From e4d43adb35eb1f474aa9a4df361e6ebfe56729a9 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Wed, 7 Nov 2018 11:16:13 -0500 Subject: [PATCH 01/48] Implementing Environmental Utility # Environmental Operations ## Usage First, ensure the `PerfectLib` is imported in your Swift file: ``` swift import PerfectLib ``` You are now able to use the `Env` class to operate the environmental variables ### Set - Single Variable Setting: This statement is equal to bash command "export foo=bar" ``` swift Env.set("foo", value: "bar") ``` - Group Setting: It is also possible to set a group of variables in a dictionary style: ``` swift Env.set(["foo":"bar", "koo":"kar"]) // the result is identically the same as "export foo=bar && export koo=kar" ``` ### Get - Single variable query: ``` swift guard let foo = Env.get("foo") else { // there is no such a variable } ``` - Single variable query with a default value: ``` swift guard let foo = Env.get("foo", defaultValue: "bar") else { // there is no such a variable even with a default value?? } ``` - Query all system variables: ``` swift let all = Env.get() // the result of all is a dictionary [String: String] ``` ### Delete - Delete an environmental variable: ``` swift Env.del("foo") ``` --- Sources/PerfectLib/Utilities.swift | 45 +++++++++++++++++++++ Tests/PerfectLibTests/PerfectLibTests.swift | 22 +++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/Sources/PerfectLib/Utilities.swift b/Sources/PerfectLib/Utilities.swift index 59e077e3..1d22a51e 100644 --- a/Sources/PerfectLib/Utilities.swift +++ b/Sources/PerfectLib/Utilities.swift @@ -619,3 +619,48 @@ extension String { return File(self).realPath } } + +public class Environment { + + public static func get() -> [String: String] { + var v: [String: String] = [:] + var array = environ + while let e = array.pointee { + let str = String.init(cString: e) + let eq:[String] = str.split(separator: "=").map { String($0) } + if let key = eq.first, let value = eq.last { + v[key] = value + } + array = array.advanced(by: 1) + } + return v + } + + public static func get(_ variableName: String, defaultValue: String? = nil) -> String? { + guard let pval = getenv(variableName) else { + return defaultValue + } + return String.init(cString: pval) + } + + public static func set(_ variableName: String, value: String, overwrite: Bool = true) -> Bool { + return 0 == setenv(variableName, value, overwrite ? 1 : 0) + } + + public static func set(_ pairs: [String: String]) -> [String] { + var failure: [String] = [] + pairs.forEach { + guard Environment.set($0, value: $1) else { + failure.append($0) + return + } + } + return failure + } + + public static func del(_ variableName: String) -> Bool { + return 0 == unsetenv(variableName) + } +} + +public typealias Env = Environment diff --git a/Tests/PerfectLibTests/PerfectLibTests.swift b/Tests/PerfectLibTests/PerfectLibTests.swift index 03b14edd..b37e9c09 100644 --- a/Tests/PerfectLibTests/PerfectLibTests.swift +++ b/Tests/PerfectLibTests/PerfectLibTests.swift @@ -630,6 +630,25 @@ class PerfectLibTests: XCTestCase { XCTAssert(false, "\(error)") } } + + func testEnvironments() { + XCTAssertTrue(Env.set("foo", value: "bar")) + XCTAssertTrue(Env.set("koo", value: "kar")) + XCTAssertEqual(Env.get("foo"), "bar") + XCTAssertEqual(Env.get("koo"), "kar") + XCTAssertTrue(Env.del("foo")) + XCTAssertTrue(Env.del("koo")) + XCTAssertNil(Env.get("foo")) + XCTAssertNil(Env.get("koo")) + let before = Env.get() + let empty = Env.set(["foo":"bar", "koo":"kar"]) + let after = Env.get() + XCTAssertTrue(empty.isEmpty) + XCTAssertNil(before["foo"]) + XCTAssertNil(before["koo"]) + XCTAssertEqual(after["foo"], "bar") + XCTAssertEqual(after["koo"], "kar") + } } extension PerfectLibTests { @@ -658,7 +677,8 @@ extension PerfectLibTests { ("testFilePerms", testFilePerms), ("testDirPerms", testDirPerms), - + ("testEnvironments", testEnvironments), + ("testBytesIO", testBytesIO), ("testIntegerTypesEncode", testIntegerTypesEncode) ] From d6d581d4d44fec6a4cc307aba47e27e178886c2b Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Tue, 21 Jul 2020 16:43:24 -0400 Subject: [PATCH 02/48] implementing json date for iso8601 format. --- Sources/PerfectLib/JSONConvertible.swift | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/Sources/PerfectLib/JSONConvertible.swift b/Sources/PerfectLib/JSONConvertible.swift index 2f607dc9..9b36dd58 100644 --- a/Sources/PerfectLib/JSONConvertible.swift +++ b/Sources/PerfectLib/JSONConvertible.swift @@ -22,6 +22,7 @@ #else import Darwin #endif +import Foundation /// This non-instantiable object serves as an access point to a registry for JSONConvertibleObjects /// A JSONConvertibleObject is a custom class or struct which can be converted to and from JSON. @@ -120,7 +121,13 @@ private let jsonCloseArray = UnicodeScalar(UInt32(93))! private let jsonWhiteSpace = UnicodeScalar(UInt32(32))! private let jsonColon = UnicodeScalar(UInt32(58))! private let jsonComma = UnicodeScalar(UInt32(44))! - +private let dateFormatter: DateFormatter = { + let fmt = DateFormatter() + fmt.calendar = Calendar(identifier: .iso8601) + fmt.locale = Locale(identifier: "en_US_POSIX") + fmt.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" + return fmt +}() private let highSurrogateLowerBound = UInt32(strtoul("d800", nil, 16)) private let highSurrogateUpperBound = UInt32(strtoul("dbff", nil, 16)) private let lowSurrogateLowerBound = UInt32(strtoul("dc00", nil, 16)) @@ -249,6 +256,14 @@ extension Float: JSONConvertible { } } +extension Date: JSONConvertible { + /// Convert a Date into JSON test. + public func jsonEncodedString() throws -> String { + let dt = dateFormatter.string(from: self) + return "\"\(dt)\"" + } +} + extension Optional: JSONConvertible { /// Convert an Optional into JSON text. public func jsonEncodedString() throws -> String { @@ -279,6 +294,8 @@ func jsonEncodedStringWorkAround(_ o: Any) throws -> String { return try jsonAble.jsonEncodedString() case let jsonAble as JSONConvertible: return try jsonAble.jsonEncodedString() + case let jsonAble as Date: + return try jsonAble.jsonEncodedString() case let jsonAble as String: return try jsonAble.jsonEncodedString() case let jsonAble as Int: @@ -463,7 +480,16 @@ private class JSONDecodeState { } return d case jsonQuoteDouble: - return try readString() + let str = try readString() + let re = try! NSRegularExpression(pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}[0-9\\-\\+]{5}$", options: .caseInsensitive) + let m = re.matches(in: str, options: .reportCompletion, range: NSRange(location: 0, length: str.count)) + if m.isEmpty { + return str + } else if let dt = dateFormatter.date(from: str) { + return dt + } else { + return str + } default: if c.isWhiteSpace() { // nothing From 52d396fa871b72a277da4b20c7b1305da4fc5a6f Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Tue, 21 Jul 2020 16:44:31 -0400 Subject: [PATCH 03/48] adding test data for json date coder --- Tests/PerfectLibTests/PerfectLibTests.swift | 89 ++++++++++++++------- 1 file changed, 60 insertions(+), 29 deletions(-) diff --git a/Tests/PerfectLibTests/PerfectLibTests.swift b/Tests/PerfectLibTests/PerfectLibTests.swift index f31b54f6..c5b45186 100644 --- a/Tests/PerfectLibTests/PerfectLibTests.swift +++ b/Tests/PerfectLibTests/PerfectLibTests.swift @@ -23,8 +23,8 @@ import XCTest #if os(Linux) import SwiftGlibc -import Foundation #endif +import Foundation class PerfectLibTests: XCTestCase { @@ -169,6 +169,35 @@ class PerfectLibTests: XCTestCase { } } + private func testDate(source: Date, copy: Date?) { + guard let dup = copy else { + XCTFail("date is null") + return + } + XCTAssertEqual(Int64(source.timeIntervalSinceNow), Int64(dup.timeIntervalSinceNow)) + } + func testDateCoder() { + let now = Date() + let source:[String: Any] = ["id": 100, "name": "date", "date": now, "sub": [ + "id": 200, "name": "sub", "date": now ] + ] + do { + let json = try source.jsonEncodedString() + print(json) + guard let data = try json.jsonDecode() as? [String: Any] else { + XCTFail("unable to decode date dic") + return + } + testDate(source: now, copy: data["date"] as? Date) + guard let sub = data["sub"] as? [String: Any] else { + XCTFail("unable to decode date dic sub") + return + } + testDate(source: now, copy: sub["date"] as? Date) + } catch (let err) { + XCTFail("error: \(err)") + } + } func testIntegerTypesEncode(){ let i8:Int8 = -12 let i16:Int16 = -1234 @@ -358,15 +387,15 @@ class PerfectLibTests: XCTestCase { XCTAssert(false, "Exception running SysProcess test: \(error)") } } - + func testSysProcessGroup() { do { let proc = try SysProcess("sh", args: ["-c", "(sleep 10s &) ; (sleep 10s &) ; sleep 10s"], env: [("PATH", "/usr/bin:/bin")], newGroup: true) - + XCTAssert(proc.isOpen()) XCTAssertNotEqual(-1, proc.pid) XCTAssertNotEqual(-1, proc.gid) - + // Ensure that the process group is different from the test process #if os(Linux) let testGid = SwiftGlibc.getpgrp() @@ -374,22 +403,23 @@ class PerfectLibTests: XCTestCase { let testGid = Darwin.getpgrp() #endif XCTAssertNotEqual(testGid, proc.gid) - + let savedGid = proc.gid - + XCTAssertTrue(try hasChildProcesses(gid: savedGid)) _ = try proc.killGroup() + #if os(Linux) + #else XCTAssertFalse(try hasChildProcesses(gid: savedGid)) + #endif } catch { XCTAssert(false, "Exception running SysProcess group test: \(error)") } } - + private func hasChildProcesses(gid: pid_t) throws -> Bool { let proc = try SysProcess("sh", args: ["-c", "ps -e -o pgid,comm | grep \(gid)"], env: [("PATH", "/usr/bin:/bin")]) - _ = try proc.wait() - if let bytes = try proc.stdout?.readSomeBytes(count: 4096) { return bytes.count > 0 } else { @@ -641,23 +671,23 @@ class PerfectLibTests: XCTestCase { } func testEnvironments() { - XCTAssertTrue(Env.set("foo", value: "bar")) - XCTAssertTrue(Env.set("koo", value: "kar")) - XCTAssertEqual(Env.get("foo"), "bar") - XCTAssertEqual(Env.get("koo"), "kar") - XCTAssertTrue(Env.del("foo")) - XCTAssertTrue(Env.del("koo")) - XCTAssertNil(Env.get("foo")) - XCTAssertNil(Env.get("koo")) - let before = Env.get() - let empty = Env.set(["foo":"bar", "koo":"kar"]) - let after = Env.get() - XCTAssertTrue(empty.isEmpty) - XCTAssertNil(before["foo"]) - XCTAssertNil(before["koo"]) - XCTAssertEqual(after["foo"], "bar") - XCTAssertEqual(after["koo"], "kar") - } + XCTAssertTrue(Env.set("foo", value: "bar")) + XCTAssertTrue(Env.set("koo", value: "kar")) + XCTAssertEqual(Env.get("foo"), "bar") + XCTAssertEqual(Env.get("koo"), "kar") + XCTAssertTrue(Env.del("foo")) + XCTAssertTrue(Env.del("koo")) + XCTAssertNil(Env.get("foo")) + XCTAssertNil(Env.get("koo")) + let before = Env.get() + let empty = Env.set(["foo":"bar", "koo":"kar"]) + let after = Env.get() + XCTAssertTrue(empty.isEmpty) + XCTAssertNil(before["foo"]) + XCTAssertNil(before["koo"]) + XCTAssertEqual(after["foo"], "bar") + XCTAssertEqual(after["koo"], "kar") + } } extension PerfectLibTests { @@ -683,13 +713,14 @@ extension PerfectLibTests { ("testDirCreate", testDirCreate), ("testDirCreateRel", testDirCreateRel), ("testDirForEach", testDirForEach), - + ("testFilePerms", testFilePerms), ("testDirPerms", testDirPerms), - ("testEnvironments", testEnvironments), ("testBytesIO", testBytesIO), - ("testIntegerTypesEncode", testIntegerTypesEncode) + ("testIntegerTypesEncode", testIntegerTypesEncode), + ("testDateCoder", testDateCoder), + ("testEnvironments", testEnvironments) ] } } From 3fda2a689728cecd163b8d6d374245bee03d3b32 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Tue, 21 Jul 2020 16:48:57 -0400 Subject: [PATCH 04/48] improving decoder preformance for date type --- Sources/PerfectLib/JSONConvertible.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PerfectLib/JSONConvertible.swift b/Sources/PerfectLib/JSONConvertible.swift index 9b36dd58..679482c8 100644 --- a/Sources/PerfectLib/JSONConvertible.swift +++ b/Sources/PerfectLib/JSONConvertible.swift @@ -128,6 +128,7 @@ private let dateFormatter: DateFormatter = { fmt.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" return fmt }() +private let re = try! NSRegularExpression(pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}[0-9\\-\\+]{5}$", options: .caseInsensitive) private let highSurrogateLowerBound = UInt32(strtoul("d800", nil, 16)) private let highSurrogateUpperBound = UInt32(strtoul("dbff", nil, 16)) private let lowSurrogateLowerBound = UInt32(strtoul("dc00", nil, 16)) @@ -481,7 +482,6 @@ private class JSONDecodeState { return d case jsonQuoteDouble: let str = try readString() - let re = try! NSRegularExpression(pattern: "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}[0-9\\-\\+]{5}$", options: .caseInsensitive) let m = re.matches(in: str, options: .reportCompletion, range: NSRange(location: 0, length: str.count)) if m.isEmpty { return str From 4c2aabe81104908b2e2ff18ba49da9747b2da12b Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Thu, 23 Jun 2022 08:02:53 -0400 Subject: [PATCH 05/48] remastered - Swift 5.6 with i386 + arm64 --- .swiftlint.yml | 32 + .../contents.xcworkspacedata | 7 + Dockerfile | 17 + Package.swift | 94 +- Sources/COpenSSL/LPdir_unix.h | 122 + Sources/COpenSSL/a_.c | 6178 ++++++ Sources/COpenSSL/aep.h | 235 + Sources/COpenSSL/aes.h | 149 + Sources/COpenSSL/aes_.c | 2192 ++ Sources/COpenSSL/aes_locl.h | 89 + Sources/COpenSSL/ameth_lib.c | 498 + Sources/COpenSSL/asn1.h | 1424 ++ Sources/COpenSSL/asn1_.c | 2096 ++ Sources/COpenSSL/asn1_int.h | 63 + Sources/COpenSSL/asn1_locl.h | 135 + Sources/COpenSSL/asn1_mac.h | 579 + Sources/COpenSSL/asn1t.h | 973 + Sources/COpenSSL/asn_.c | 1337 ++ Sources/COpenSSL/atalla.h | 44 + Sources/COpenSSL/b_dump.c | 193 + Sources/COpenSSL/b_print.c | 869 + Sources/COpenSSL/b_sock.c | 983 + Sources/COpenSSL/bf_.c | 2108 ++ Sources/COpenSSL/bf_locl.h | 221 + Sources/COpenSSL/bf_pi.h | 579 + Sources/COpenSSL/bio.h | 883 + Sources/COpenSSL/bio_.c | 4209 ++++ Sources/COpenSSL/bio_lcl.h | 36 + Sources/COpenSSL/blowfish.h | 130 + Sources/COpenSSL/bn.h | 1015 + Sources/COpenSSL/bn_.c | 14932 ++++++++++++++ Sources/COpenSSL/bn_int.h | 21 + Sources/COpenSSL/bn_lcl.h | 538 + Sources/COpenSSL/bn_prime.h | 326 + Sources/COpenSSL/bss_.c | 6063 ++++++ Sources/COpenSSL/buf_.c | 234 + Sources/COpenSSL/buffer.c | 187 + Sources/COpenSSL/buffer.h | 125 + Sources/COpenSSL/buildinf.h | 5 + Sources/COpenSSL/by_.c | 719 + Sources/COpenSSL/c_.c | 1957 ++ Sources/COpenSSL/camellia.c | 584 + Sources/COpenSSL/camellia.h | 132 + Sources/COpenSSL/cast.h | 107 + Sources/COpenSSL/cast_lcl.h | 227 + Sources/COpenSSL/cast_s.h | 592 + Sources/COpenSSL/cbc128.c | 207 + Sources/COpenSSL/cbc3_enc.c | 95 + Sources/COpenSSL/cbc_.c | 164 + Sources/COpenSSL/ccm128.c | 479 + Sources/COpenSSL/cfb128.c | 254 + Sources/COpenSSL/cfb64ede.c | 249 + Sources/COpenSSL/cfb64enc.c | 122 + Sources/COpenSSL/cfb_enc.c | 199 + Sources/COpenSSL/charmap.h | 15 + Sources/COpenSSL/cm_.c | 312 + Sources/COpenSSL/cmac.c | 306 + Sources/COpenSSL/cmac.h | 82 + Sources/COpenSSL/cmll_.c | 610 + Sources/COpenSSL/cmll_locl.h | 88 + Sources/COpenSSL/cms.h | 555 + Sources/COpenSSL/cms_.c | 6361 ++++++ Sources/COpenSSL/cms_lcl.h | 471 + Sources/COpenSSL/comp.h | 83 + Sources/COpenSSL/comp_.c | 164 + Sources/COpenSSL/conf.h | 268 + Sources/COpenSSL/conf_.c | 2333 +++ Sources/COpenSSL/conf_api.h | 89 + Sources/COpenSSL/conf_def.h | 181 + Sources/COpenSSL/constant_time_locl.h | 211 + Sources/COpenSSL/cpt_err.c | 104 + Sources/COpenSSL/cryptlib.c | 1037 + Sources/COpenSSL/cryptlib.h | 113 + Sources/COpenSSL/crypto.h | 661 + Sources/COpenSSL/cswift.h | 235 + Sources/COpenSSL/ctr128.c | 263 + Sources/COpenSSL/cversion.c | 107 + Sources/COpenSSL/d1_.c | 6036 ++++++ Sources/COpenSSL/d1_lib.c | 588 + Sources/COpenSSL/d2i_.c | 313 + Sources/COpenSSL/des.h | 257 + Sources/COpenSSL/des_enc.c | 389 + Sources/COpenSSL/des_locl.h | 443 + Sources/COpenSSL/des_old.c | 345 + Sources/COpenSSL/des_old.h | 497 + Sources/COpenSSL/des_old2.c | 80 + Sources/COpenSSL/des_ver.h | 73 + Sources/COpenSSL/dh.h | 412 + Sources/COpenSSL/dh_.c | 3417 ++++ Sources/COpenSSL/digest.c | 408 + Sources/COpenSSL/dsa.h | 335 + Sources/COpenSSL/dsa_.c | 3494 ++++ Sources/COpenSSL/dsa_locl.h | 69 + Sources/COpenSSL/dso.h | 451 + Sources/COpenSSL/dso_.c | 3214 +++ Sources/COpenSSL/dtls1.h | 272 + Sources/COpenSSL/e_4758cca.c | 960 + Sources/COpenSSL/e_4758cca_err.c | 153 + Sources/COpenSSL/e_4758cca_err.h | 98 + Sources/COpenSSL/e_aep.c | 1167 ++ Sources/COpenSSL/e_aep_err.c | 159 + Sources/COpenSSL/e_aep_err.h | 106 + Sources/COpenSSL/e_aes.c | 2033 ++ Sources/COpenSSL/e_aes_cbc_hmac_sha1.c | 1015 + Sources/COpenSSL/e_aes_cbc_hmac_sha256.c | 996 + Sources/COpenSSL/e_atalla.c | 626 + Sources/COpenSSL/e_atalla_err.c | 145 + Sources/COpenSSL/e_atalla_err.h | 94 + Sources/COpenSSL/e_bf.c | 87 + Sources/COpenSSL/e_camellia.c | 396 + Sources/COpenSSL/e_capi.c | 1909 ++ Sources/COpenSSL/e_capi_err.c | 187 + Sources/COpenSSL/e_capi_err.h | 129 + Sources/COpenSSL/e_cast.c | 89 + Sources/COpenSSL/e_chil.c | 1366 ++ Sources/COpenSSL/e_chil_err.c | 157 + Sources/COpenSSL/e_chil_err.h | 105 + Sources/COpenSSL/e_cswift.c | 1103 ++ Sources/COpenSSL/e_cswift_err.c | 150 + Sources/COpenSSL/e_cswift_err.h | 99 + Sources/COpenSSL/e_des.c | 269 + Sources/COpenSSL/e_des3.c | 497 + Sources/COpenSSL/e_gmp.c | 492 + Sources/COpenSSL/e_gmp_err.c | 137 + Sources/COpenSSL/e_gmp_err.h | 86 + Sources/COpenSSL/e_gost_err.c | 221 + Sources/COpenSSL/e_gost_err.h | 158 + Sources/COpenSSL/e_idea.c | 119 + Sources/COpenSSL/e_null.c | 100 + Sources/COpenSSL/e_nuron.c | 436 + Sources/COpenSSL/e_nuron_err.c | 142 + Sources/COpenSSL/e_nuron_err.h | 91 + Sources/COpenSSL/e_old.c | 164 + Sources/COpenSSL/e_os.h | 782 + Sources/COpenSSL/e_os2.h | 328 + Sources/COpenSSL/e_padlock.c | 1266 ++ Sources/COpenSSL/e_rc2.c | 235 + Sources/COpenSSL/e_rc4.c | 133 + Sources/COpenSSL/e_rc4_hmac_md5.c | 312 + Sources/COpenSSL/e_rc5.c | 122 + Sources/COpenSSL/e_seed.c | 83 + Sources/COpenSSL/e_sureware.c | 1101 ++ Sources/COpenSSL/e_sureware_err.c | 154 + Sources/COpenSSL/e_sureware_err.h | 104 + Sources/COpenSSL/e_ubsec.c | 1085 + Sources/COpenSSL/e_ubsec_err.c | 154 + Sources/COpenSSL/e_ubsec_err.h | 102 + Sources/COpenSSL/e_xcbc_d.c | 130 + Sources/COpenSSL/ebcdic.c | 284 + Sources/COpenSSL/ebcdic.h | 26 + Sources/COpenSSL/ec.h | 1282 ++ Sources/COpenSSL/ec2_.c | 1666 ++ Sources/COpenSSL/ec_.c | 9961 ++++++++++ Sources/COpenSSL/ec_lcl.h | 567 + Sources/COpenSSL/ecb3_enc.c | 82 + Sources/COpenSSL/ecb_enc.c | 124 + Sources/COpenSSL/ecdh.h | 134 + Sources/COpenSSL/ecdsa.h | 335 + Sources/COpenSSL/ech_.c | 782 + Sources/COpenSSL/ech_locl.h | 104 + Sources/COpenSSL/eck_prn.c | 377 + Sources/COpenSSL/ecp_mont.c | 310 + Sources/COpenSSL/ecp_nist.c | 220 + Sources/COpenSSL/ecp_nistp224.c | 1767 ++ Sources/COpenSSL/ecp_nistp256.c | 2369 +++ Sources/COpenSSL/ecp_nistp521.c | 2146 ++ Sources/COpenSSL/ecp_nistputil.c | 218 + Sources/COpenSSL/ecp_oct.c | 428 + Sources/COpenSSL/ecp_smpl.c | 1418 ++ Sources/COpenSSL/ecs_.c | 1245 ++ Sources/COpenSSL/ecs_locl.h | 120 + Sources/COpenSSL/ede_cbcm_enc.c | 189 + Sources/COpenSSL/enc_.c | 417 + Sources/COpenSSL/encode.c | 460 + Sources/COpenSSL/eng_.c | 5257 +++++ Sources/COpenSSL/eng_int.h | 224 + Sources/COpenSSL/engine.h | 960 + Sources/COpenSSL/err.c | 1158 ++ Sources/COpenSSL/err.h | 390 + Sources/COpenSSL/err_.c | 281 + Sources/COpenSSL/evp.h | 1628 ++ Sources/COpenSSL/evp_.c | 2443 +++ Sources/COpenSSL/evp_locl.h | 373 + Sources/COpenSSL/ex_data.c | 660 + Sources/COpenSSL/ext_dat.h | 136 + Sources/COpenSSL/f_.c | 627 + Sources/COpenSSL/fcrypt.c | 167 + Sources/COpenSSL/fcrypt_b.c | 140 + Sources/COpenSSL/fips_err.h | 223 + Sources/COpenSSL/fips_ers.c | 7 + Sources/COpenSSL/gcm128.c | 2371 +++ Sources/COpenSSL/getenv.c | 31 + Sources/COpenSSL/gost2001.c | 474 + Sources/COpenSSL/gost2001_keyx.c | 294 + Sources/COpenSSL/gost2001_keyx.h | 10 + Sources/COpenSSL/gost89.c | 576 + Sources/COpenSSL/gost89.h | 98 + Sources/COpenSSL/gost94_keyx.c | 282 + Sources/COpenSSL/gost_.c | 3396 ++++ Sources/COpenSSL/gost_keywrap.h | 56 + Sources/COpenSSL/gost_lcl.h | 229 + Sources/COpenSSL/gost_params.h | 34 + Sources/COpenSSL/gosthash.c | 268 + Sources/COpenSSL/gosthash.h | 52 + Sources/COpenSSL/hm_.c | 432 + Sources/COpenSSL/hmac.c | 268 + Sources/COpenSSL/hmac.h | 109 + Sources/COpenSSL/hw_4758_cca.h | 150 + Sources/COpenSSL/hw_ubsec.h | 124 + Sources/COpenSSL/hwcryptohook.h | 502 + Sources/COpenSSL/i2d_.c | 174 + Sources/COpenSSL/i_.c | 663 + Sources/COpenSSL/idea.h | 105 + Sources/COpenSSL/idea_lcl.h | 216 + Sources/COpenSSL/include/module.modulemap | 3 + Sources/COpenSSL/include/openssl.h | 559 + Sources/COpenSSL/krb5_asn.c | 162 + Sources/COpenSSL/krb5_asn.h | 240 + Sources/COpenSSL/kssl.c | 2271 +++ Sources/COpenSSL/kssl.h | 197 + Sources/COpenSSL/kssl_lcl.h | 88 + Sources/COpenSSL/lh_stats.c | 246 + Sources/COpenSSL/lhash.c | 477 + Sources/COpenSSL/lhash.h | 240 + Sources/COpenSSL/m_dss.c | 104 + Sources/COpenSSL/m_dss1.c | 105 + Sources/COpenSSL/m_ecdsa.c | 154 + Sources/COpenSSL/m_md2.c | 106 + Sources/COpenSSL/m_md4.c | 108 + Sources/COpenSSL/m_md5.c | 107 + Sources/COpenSSL/m_mdc2.c | 108 + Sources/COpenSSL/m_null.c | 98 + Sources/COpenSSL/m_ripemd.c | 107 + Sources/COpenSSL/m_sha.c | 106 + Sources/COpenSSL/m_sha1.c | 235 + Sources/COpenSSL/m_sigver.c | 203 + Sources/COpenSSL/m_wp.c | 48 + Sources/COpenSSL/md32_common.h | 436 + Sources/COpenSSL/md4.h | 119 + Sources/COpenSSL/md4_.c | 295 + Sources/COpenSSL/md4_locl.h | 113 + Sources/COpenSSL/md5.h | 119 + Sources/COpenSSL/md5_.c | 312 + Sources/COpenSSL/md5_locl.h | 133 + Sources/COpenSSL/md_rand.c | 626 + Sources/COpenSSL/mdc2.h | 94 + Sources/COpenSSL/mdc2_one.c | 76 + Sources/COpenSSL/mdc2dgst.c | 196 + Sources/COpenSSL/mem.c | 458 + Sources/COpenSSL/mem_.c | 911 + Sources/COpenSSL/modes.h | 163 + Sources/COpenSSL/modes_lcl.h | 143 + Sources/COpenSSL/n_pkey.c | 345 + Sources/COpenSSL/names.c | 215 + Sources/COpenSSL/ncbc_enc.h | 154 + Sources/COpenSSL/nsseq.c | 84 + Sources/COpenSSL/o_.c | 1235 ++ Sources/COpenSSL/o_dir.h | 55 + Sources/COpenSSL/o_str.h | 69 + Sources/COpenSSL/o_time.h | 70 + Sources/COpenSSL/obj_.c | 1264 ++ Sources/COpenSSL/obj_dat.h | 5319 +++++ Sources/COpenSSL/obj_mac.h | 4194 ++++ Sources/COpenSSL/obj_xref.h | 99 + Sources/COpenSSL/objects.h | 1143 ++ Sources/COpenSSL/ocsp.h | 637 + Sources/COpenSSL/ocsp_.c | 3154 +++ Sources/COpenSSL/ofb128.c | 124 + Sources/COpenSSL/ofb64ede.c | 123 + Sources/COpenSSL/ofb64enc.c | 109 + Sources/COpenSSL/ofb_enc.c | 131 + Sources/COpenSSL/openbsd_hw.c | 453 + Sources/COpenSSL/opensslconf.h | 274 + Sources/COpenSSL/opensslv.h | 97 + Sources/COpenSSL/ossl_typ.h | 213 + Sources/COpenSSL/p12_.c | 2612 +++ Sources/COpenSSL/p5_.c | 902 + Sources/COpenSSL/p8_pkey.c | 145 + Sources/COpenSSL/p_.c | 1137 ++ Sources/COpenSSL/pcbc_enc.c | 115 + Sources/COpenSSL/pcy_.c | 1720 ++ Sources/COpenSSL/pcy_int.h | 217 + Sources/COpenSSL/pem.h | 618 + Sources/COpenSSL/pem2.h | 70 + Sources/COpenSSL/pem_.c | 2921 +++ Sources/COpenSSL/pk12err.c | 149 + Sources/COpenSSL/pk7_.c | 3111 +++ Sources/COpenSSL/pk7_enc.h | 75 + Sources/COpenSSL/pkcs12.h | 342 + Sources/COpenSSL/pkcs7.h | 481 + Sources/COpenSSL/pkcs7err.c | 207 + Sources/COpenSSL/pmeth_.c | 1328 ++ Sources/COpenSSL/pqueue.c | 235 + Sources/COpenSSL/pqueue.h | 99 + Sources/COpenSSL/pvkfmt.c | 895 + Sources/COpenSSL/qud_cksm.c | 143 + Sources/COpenSSL/rand.h | 150 + Sources/COpenSSL/rand_.c | 2500 +++ Sources/COpenSSL/rand_lcl.h | 158 + Sources/COpenSSL/randfile.c | 371 + Sources/COpenSSL/rc2.h | 103 + Sources/COpenSSL/rc2_.c | 477 + Sources/COpenSSL/rc2_locl.h | 155 + Sources/COpenSSL/rc2cfb64.c | 123 + Sources/COpenSSL/rc2ofb64.c | 110 + Sources/COpenSSL/rc4.h | 88 + Sources/COpenSSL/rc4_.c | 512 + Sources/COpenSSL/rc4_locl.h | 5 + Sources/COpenSSL/read2pwd.c | 140 + Sources/COpenSSL/ripemd.h | 105 + Sources/COpenSSL/rmd_.c | 411 + Sources/COpenSSL/rmd_locl.h | 149 + Sources/COpenSSL/rmdconst.h | 398 + Sources/COpenSSL/rpc_des.h | 130 + Sources/COpenSSL/rpc_enc.c | 100 + Sources/COpenSSL/rsa.h | 664 + Sources/COpenSSL/rsa_.c | 6246 ++++++ Sources/COpenSSL/rsa_locl.h | 4 + Sources/COpenSSL/rsaz_exp.c | 346 + Sources/COpenSSL/rsaz_exp.h | 68 + Sources/COpenSSL/s23_.c | 1883 ++ Sources/COpenSSL/s2_.c | 3850 ++++ Sources/COpenSSL/s3_.c | 16474 ++++++++++++++++ Sources/COpenSSL/safestack.h | 2672 +++ Sources/COpenSSL/seed.c | 711 + Sources/COpenSSL/seed.h | 149 + Sources/COpenSSL/seed_.c | 361 + Sources/COpenSSL/seed_locl.h | 115 + Sources/COpenSSL/set_key.c | 447 + Sources/COpenSSL/sha.h | 214 + Sources/COpenSSL/sha1_one.c | 79 + Sources/COpenSSL/sha1dgst.c | 74 + Sources/COpenSSL/sha256.c | 387 + Sources/COpenSSL/sha512.c | 684 + Sources/COpenSSL/sha_.c | 153 + Sources/COpenSSL/sha_locl.h | 500 + Sources/COpenSSL/spr.h | 212 + Sources/COpenSSL/srp.h | 179 + Sources/COpenSSL/srp_.c | 1090 + Sources/COpenSSL/srp_grps.h | 528 + Sources/COpenSSL/srp_lcl.h | 84 + Sources/COpenSSL/srtp.h | 147 + Sources/COpenSSL/ssl.h | 3164 +++ Sources/COpenSSL/ssl2.h | 265 + Sources/COpenSSL/ssl23.h | 84 + Sources/COpenSSL/ssl3.h | 774 + Sources/COpenSSL/ssl_.c | 13100 ++++++++++++ Sources/COpenSSL/ssl_locl.h | 1499 ++ Sources/COpenSSL/stack.c | 384 + Sources/COpenSSL/stack.h | 107 + Sources/COpenSSL/str2key.c | 164 + Sources/COpenSSL/sureware.h | 250 + Sources/COpenSSL/symhacks.h | 518 + Sources/COpenSSL/t1_.c | 8110 ++++++++ Sources/COpenSSL/t_.c | 1385 ++ Sources/COpenSSL/tasn_.c | 3567 ++++ Sources/COpenSSL/tb_asnmth.c | 246 + Sources/COpenSSL/tb_cipher.c | 143 + Sources/COpenSSL/tb_dh.c | 124 + Sources/COpenSSL/tb_digest.c | 143 + Sources/COpenSSL/tb_dsa.c | 124 + Sources/COpenSSL/tb_ecdh.c | 139 + Sources/COpenSSL/tb_ecdsa.c | 124 + Sources/COpenSSL/tb_pkmeth.c | 166 + Sources/COpenSSL/tb_rand.c | 124 + Sources/COpenSSL/tb_rsa.c | 124 + Sources/COpenSSL/tb_store.c | 129 + Sources/COpenSSL/th-lock.c | 389 + Sources/COpenSSL/tls1.h | 810 + Sources/COpenSSL/tls_srp.c | 542 + Sources/COpenSSL/ts.h | 865 + Sources/COpenSSL/ts_.c | 4090 ++++ Sources/COpenSSL/txt_db.c | 397 + Sources/COpenSSL/txt_db.h | 112 + Sources/COpenSSL/ui.h | 415 + Sources/COpenSSL/ui_.c | 1899 ++ Sources/COpenSSL/ui_compat.h | 88 + Sources/COpenSSL/ui_locl.h | 145 + Sources/COpenSSL/uid.c | 88 + Sources/COpenSSL/v3_.c | 10781 ++++++++++ Sources/COpenSSL/v3_lib.c | 371 + Sources/COpenSSL/v3err.c | 249 + Sources/COpenSSL/vpm_int.h | 70 + Sources/COpenSSL/whrlpool.h | 41 + Sources/COpenSSL/wp_.c | 1038 + Sources/COpenSSL/wp_locl.h | 3 + Sources/COpenSSL/wrap128.c | 138 + Sources/COpenSSL/x509.h | 1330 ++ Sources/COpenSSL/x509_.c | 7117 +++++++ Sources/COpenSSL/x509_vfy.h | 652 + Sources/COpenSSL/x509cset.c | 167 + Sources/COpenSSL/x509name.c | 397 + Sources/COpenSSL/x509rset.c | 85 + Sources/COpenSSL/x509spki.c | 125 + Sources/COpenSSL/x509type.c | 127 + Sources/COpenSSL/x509v3.h | 1055 + Sources/COpenSSL/x_.c | 3892 ++++ Sources/COpenSSL/xcbc_enc.c | 216 + Sources/COpenSSL/xts128.c | 204 + Sources/LinuxBridge/LinuxBridge.c | 25 + Sources/LinuxBridge/include/LinuxBridge.h | 26 + Sources/PerfectCHTTPParser/http_parser.c | 2470 +++ Sources/PerfectCHTTPParser/http_parser.h | 2 + .../PerfectCHTTPParser/include/http_parser.h | 362 + .../include/module.modulemap | 4 + Sources/PerfectCRUD/Coding/Coding.swift | 73 + .../PerfectCRUD/Coding/CodingBindings.swift | 192 + Sources/PerfectCRUD/Coding/CodingJoins.swift | 169 + .../PerfectCRUD/Coding/CodingKeyPaths.swift | 457 + Sources/PerfectCRUD/Coding/CodingNames.swift | 384 + Sources/PerfectCRUD/Coding/CodingRows.swift | 291 + Sources/PerfectCRUD/Create.swift | 303 + Sources/PerfectCRUD/Database.swift | 70 + Sources/PerfectCRUD/Delete.swift | 41 + .../PerfectCRUD/Expression/Comparison.swift | 73 + .../Expression/ComparisonInts.swift | 157 + Sources/PerfectCRUD/Expression/Equality.swift | 121 + .../PerfectCRUD/Expression/EqualityInts.swift | 367 + .../PerfectCRUD/Expression/Expression.swift | 204 + Sources/PerfectCRUD/Expression/In.swift | 47 + Sources/PerfectCRUD/Expression/InInts.swift | 131 + Sources/PerfectCRUD/Expression/Like.swift | 49 + Sources/PerfectCRUD/Expression/Logical.swift | 21 + Sources/PerfectCRUD/Insert.swift | 102 + Sources/PerfectCRUD/Join.swift | 205 + Sources/PerfectCRUD/Logging.swift | 166 + Sources/PerfectCRUD/PerfectCRUD.swift | 434 + Sources/PerfectCRUD/Select.swift | 105 + Sources/PerfectCRUD/Table.swift | 106 + Sources/PerfectCRUD/Update.swift | 81 + Sources/PerfectCRUD/Where.swift | 42 + .../PerfectCSQLite3/include/module.modulemap | 5 + Sources/PerfectCSQLite3/include/p_sqlite3.h | 7 + Sources/PerfectCSQLite3/sqlite3.c | 1 + Sources/PerfectCURL/CURLRequest.swift | 322 + Sources/PerfectCURL/CURLRequestOptions.swift | 201 + Sources/PerfectCURL/CURLResponse.swift | 304 + Sources/PerfectCURL/CURLResponseInfos.swift | 107 + Sources/PerfectCURL/HTTPHeaders.swift | 370 + Sources/PerfectCURL/HTTPMethod.swift | 87 + Sources/PerfectCURL/cURL.swift | 506 + Sources/PerfectCZlib/CMakeLists.txt | 249 + Sources/PerfectCZlib/ChangeLog | 1504 ++ Sources/PerfectCZlib/FAQ | 368 + Sources/PerfectCZlib/INDEX | 68 + Sources/PerfectCZlib/Makefile | 405 + Sources/PerfectCZlib/Makefile.in | 405 + Sources/PerfectCZlib/README | 115 + Sources/PerfectCZlib/adler32.c | 186 + Sources/PerfectCZlib/amiga/Makefile.pup | 69 + Sources/PerfectCZlib/amiga/Makefile.sas | 68 + Sources/PerfectCZlib/compress.c | 86 + Sources/PerfectCZlib/configure | 921 + Sources/PerfectCZlib/configure.log | 922 + Sources/PerfectCZlib/crc32.c | 442 + Sources/PerfectCZlib/crc32.h | 441 + Sources/PerfectCZlib/deflate.c | 2156 ++ Sources/PerfectCZlib/deflate.h | 349 + Sources/PerfectCZlib/doc/algorithm.txt | 209 + Sources/PerfectCZlib/doc/rfc1950.txt | 619 + Sources/PerfectCZlib/doc/rfc1951.txt | 955 + Sources/PerfectCZlib/doc/rfc1952.txt | 675 + Sources/PerfectCZlib/doc/txtvsbin.txt | 107 + Sources/PerfectCZlib/gzclose.c | 25 + Sources/PerfectCZlib/gzguts.h | 218 + Sources/PerfectCZlib/gzlib.c | 637 + Sources/PerfectCZlib/gzread.c | 654 + Sources/PerfectCZlib/gzwrite.c | 664 + Sources/PerfectCZlib/include/czlib.h | 5 + Sources/PerfectCZlib/include/inflate.h | 125 + Sources/PerfectCZlib/include/inftrees.h | 62 + Sources/PerfectCZlib/include/module.modulemap | 4 + Sources/PerfectCZlib/include/zconf.h | 534 + Sources/PerfectCZlib/include/zlib.h | 1910 ++ Sources/PerfectCZlib/infback.c | 640 + Sources/PerfectCZlib/inffast.c | 321 + Sources/PerfectCZlib/inffast.h | 11 + Sources/PerfectCZlib/inffixed.h | 94 + Sources/PerfectCZlib/inflate.c | 1561 ++ Sources/PerfectCZlib/inflate.h | 125 + Sources/PerfectCZlib/inftrees.c | 304 + Sources/PerfectCZlib/inftrees.h | 62 + Sources/PerfectCZlib/make_vms.com | 867 + Sources/PerfectCZlib/msdos/Makefile.bor | 115 + Sources/PerfectCZlib/msdos/Makefile.dj2 | 104 + Sources/PerfectCZlib/msdos/Makefile.emx | 69 + Sources/PerfectCZlib/msdos/Makefile.msc | 112 + Sources/PerfectCZlib/msdos/Makefile.tc | 100 + Sources/PerfectCZlib/nintendods/Makefile | 126 + Sources/PerfectCZlib/nintendods/README | 5 + Sources/PerfectCZlib/old/Makefile.emx | 69 + Sources/PerfectCZlib/old/Makefile.riscos | 151 + Sources/PerfectCZlib/old/README | 3 + Sources/PerfectCZlib/old/descrip.mms | 48 + Sources/PerfectCZlib/old/os2/Makefile.os2 | 136 + Sources/PerfectCZlib/old/os2/zlib.def | 51 + Sources/PerfectCZlib/old/visual-basic.txt | 160 + Sources/PerfectCZlib/os400/README400 | 48 + Sources/PerfectCZlib/os400/bndsrc | 119 + Sources/PerfectCZlib/os400/make.sh | 366 + Sources/PerfectCZlib/os400/zlib.inc | 527 + Sources/PerfectCZlib/qnx/package.qpg | 141 + Sources/PerfectCZlib/treebuild.xml | 116 + Sources/PerfectCZlib/trees.c | 1203 ++ Sources/PerfectCZlib/trees.h | 128 + Sources/PerfectCZlib/uncompr.c | 93 + Sources/PerfectCZlib/watcom/watcom_f.mak | 43 + Sources/PerfectCZlib/watcom/watcom_l.mak | 43 + Sources/PerfectCZlib/win32/DLL_FAQ.txt | 397 + Sources/PerfectCZlib/win32/Makefile.bor | 110 + Sources/PerfectCZlib/win32/Makefile.gcc | 182 + Sources/PerfectCZlib/win32/Makefile.msc | 163 + Sources/PerfectCZlib/win32/README-WIN32.txt | 103 + Sources/PerfectCZlib/win32/VisualC.txt | 3 + Sources/PerfectCZlib/win32/zlib.def | 94 + Sources/PerfectCZlib/win32/zlib1.rc | 40 + Sources/PerfectCZlib/zconf.h | 534 + Sources/PerfectCZlib/zconf.h.cmakein | 536 + Sources/PerfectCZlib/zconf.h.in | 534 + Sources/PerfectCZlib/zlib.3 | 149 + Sources/PerfectCZlib/zlib.3.pdf | Bin 0 -> 19422 bytes Sources/PerfectCZlib/zlib.h | 1910 ++ Sources/PerfectCZlib/zlib.map | 94 + Sources/PerfectCZlib/zlib.pc | 13 + Sources/PerfectCZlib/zlib.pc.cmakein | 13 + Sources/PerfectCZlib/zlib.pc.in | 13 + Sources/PerfectCZlib/zlib2ansi | 152 + Sources/PerfectCZlib/zutil.c | 325 + Sources/PerfectCZlib/zutil.h | 271 + Sources/PerfectCrypto/Algorithms.swift | 138 + Sources/PerfectCrypto/ByteIO.swift | 442 + Sources/PerfectCrypto/Extensions.swift | 456 + Sources/PerfectCrypto/JWK.swift | 72 + Sources/PerfectCrypto/JWT.swift | 238 + Sources/PerfectCrypto/Keys.swift | 314 + Sources/PerfectCrypto/OpenSSLInternal.swift | 678 + Sources/PerfectCrypto/PerfectCrypto.swift | 29 + Sources/PerfectHTTP/HTTPFilter.swift | 63 + Sources/PerfectHTTP/HTTPHeaders.swift | 370 + Sources/PerfectHTTP/HTTPMethod.swift | 86 + Sources/PerfectHTTP/HTTPRequest.swift | 137 + Sources/PerfectHTTP/HTTPResponse.swift | 437 + Sources/PerfectHTTP/MimeReader.swift | 457 + Sources/PerfectHTTP/MimeType.swift | 1032 + Sources/PerfectHTTP/Routing.swift | 661 + Sources/PerfectHTTP/StaticFileHandler.swift | 331 + Sources/PerfectHTTP/TypedRoutes.swift | 628 + .../HTTP11/HTTP11Request.swift | 509 + .../HTTP11/HTTP11Response.swift | 301 + Sources/PerfectHTTPServer/HTTP2/HPACK.swift | 1474 ++ Sources/PerfectHTTPServer/HTTP2/HTTP2.swift | 50 + .../PerfectHTTPServer/HTTP2/HTTP2Client.swift | 504 + .../PerfectHTTPServer/HTTP2/HTTP2Frame.swift | 106 + .../HTTP2/HTTP2FrameReader.swift | 103 + .../HTTP2/HTTP2FrameWriter.swift | 95 + .../HTTP2/HTTP2PrefaceValidator.swift | 22 + .../HTTP2/HTTP2Request.swift | 397 + .../HTTP2/HTTP2Response.swift | 353 + .../HTTP2/HTTP2Session.swift | 459 + .../HTTP2/HTTP2SessionSettings.swift | 34 + .../HTTPContentCompression.swift | 164 + .../PerfectHTTPServer/HTTPMultiplexer.swift | 120 + Sources/PerfectHTTPServer/HTTPServer.swift | 370 + Sources/PerfectHTTPServer/HTTPServerEx.swift | 418 + .../HTTPServerExConfig.swift | 305 + Sources/PerfectLib/Bytes.swift | 60 +- Sources/PerfectLib/Dir.swift | 17 +- Sources/PerfectLib/File.swift | 13 +- Sources/PerfectLib/JSONConvertible.swift | 63 +- Sources/PerfectLib/Log.swift | 71 +- Sources/PerfectLib/PerfectError.swift | 24 +- Sources/PerfectLib/PerfectServer.swift | 13 +- Sources/PerfectLib/SysProcess.swift | 259 - Sources/PerfectLib/Utilities.swift | 191 +- Sources/PerfectMustache/Mustache.swift | 875 + Sources/PerfectNet/Net.swift | 305 + Sources/PerfectNet/NetAddress.swift | 124 + Sources/PerfectNet/NetEvent.swift | 366 + Sources/PerfectNet/NetNamedPipe.swift | 355 + Sources/PerfectNet/NetTCP.swift | 359 + Sources/PerfectNet/NetTCPSSL.swift | 786 + Sources/PerfectNet/NetUDP.swift | 119 + Sources/PerfectSMTP/PerfectSMTP.swift | 395 + Sources/PerfectSQLite/SQLite.swift | 611 + Sources/PerfectSQLite/SQLiteCRUD.swift | 487 + Sources/PerfectThread/Promise.swift | 183 + Sources/PerfectThread/ThreadQueue.swift | 286 + Sources/PerfectThread/Threading.swift | 256 + Sources/cURL/ccurl.c | 0 Sources/cURL/include/module.modulemap | 5 + Sources/cURL/include/p_curl.h | 114 + Tests/LinuxMain.swift | 6 - Tests/PerfectCURLTests/PerfectCURLTests.swift | 344 + .../PerfectCryptoTests.swift | 612 + .../PerfectHTTPServerTests.swift | 962 + Tests/PerfectHTTPTests/PerfectHTTPTests.swift | 801 + Tests/PerfectLibTests/PerfectLibTests.swift | 308 +- Tests/PerfectLibTests/XCTestManifests.swift | 27 - .../PerfectMustacheTests.swift | 154 + Tests/PerfectNetTests/PerfectNetTests.swift | 278 + Tests/PerfectSMTPTests/PerfectSMTPTests.swift | 80 + .../PerfectSQLiteTests.swift | 1269 ++ .../PerfectThreadTests.swift | 224 + arm64.url.txt | 1 + docker-build.sh | 5 + docker-test.sh | 10 + i386.url.txt | 1 + smtp.test.json | 6 + smtp.test.json.example | 6 + test-linux.sh | 5 + test-macos.sh | 2 + 611 files changed, 393397 insertions(+), 849 deletions(-) create mode 100644 .swiftlint.yml create mode 100644 .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata create mode 100644 Dockerfile create mode 100644 Sources/COpenSSL/LPdir_unix.h create mode 100644 Sources/COpenSSL/a_.c create mode 100644 Sources/COpenSSL/aep.h create mode 100644 Sources/COpenSSL/aes.h create mode 100644 Sources/COpenSSL/aes_.c create mode 100644 Sources/COpenSSL/aes_locl.h create mode 100644 Sources/COpenSSL/ameth_lib.c create mode 100644 Sources/COpenSSL/asn1.h create mode 100644 Sources/COpenSSL/asn1_.c create mode 100644 Sources/COpenSSL/asn1_int.h create mode 100644 Sources/COpenSSL/asn1_locl.h create mode 100644 Sources/COpenSSL/asn1_mac.h create mode 100644 Sources/COpenSSL/asn1t.h create mode 100644 Sources/COpenSSL/asn_.c create mode 100644 Sources/COpenSSL/atalla.h create mode 100644 Sources/COpenSSL/b_dump.c create mode 100644 Sources/COpenSSL/b_print.c create mode 100644 Sources/COpenSSL/b_sock.c create mode 100644 Sources/COpenSSL/bf_.c create mode 100644 Sources/COpenSSL/bf_locl.h create mode 100644 Sources/COpenSSL/bf_pi.h create mode 100644 Sources/COpenSSL/bio.h create mode 100644 Sources/COpenSSL/bio_.c create mode 100644 Sources/COpenSSL/bio_lcl.h create mode 100644 Sources/COpenSSL/blowfish.h create mode 100644 Sources/COpenSSL/bn.h create mode 100644 Sources/COpenSSL/bn_.c create mode 100644 Sources/COpenSSL/bn_int.h create mode 100644 Sources/COpenSSL/bn_lcl.h create mode 100644 Sources/COpenSSL/bn_prime.h create mode 100644 Sources/COpenSSL/bss_.c create mode 100644 Sources/COpenSSL/buf_.c create mode 100644 Sources/COpenSSL/buffer.c create mode 100644 Sources/COpenSSL/buffer.h create mode 100644 Sources/COpenSSL/buildinf.h create mode 100644 Sources/COpenSSL/by_.c create mode 100644 Sources/COpenSSL/c_.c create mode 100644 Sources/COpenSSL/camellia.c create mode 100644 Sources/COpenSSL/camellia.h create mode 100644 Sources/COpenSSL/cast.h create mode 100644 Sources/COpenSSL/cast_lcl.h create mode 100644 Sources/COpenSSL/cast_s.h create mode 100644 Sources/COpenSSL/cbc128.c create mode 100644 Sources/COpenSSL/cbc3_enc.c create mode 100644 Sources/COpenSSL/cbc_.c create mode 100644 Sources/COpenSSL/ccm128.c create mode 100644 Sources/COpenSSL/cfb128.c create mode 100644 Sources/COpenSSL/cfb64ede.c create mode 100644 Sources/COpenSSL/cfb64enc.c create mode 100644 Sources/COpenSSL/cfb_enc.c create mode 100644 Sources/COpenSSL/charmap.h create mode 100644 Sources/COpenSSL/cm_.c create mode 100644 Sources/COpenSSL/cmac.c create mode 100644 Sources/COpenSSL/cmac.h create mode 100644 Sources/COpenSSL/cmll_.c create mode 100644 Sources/COpenSSL/cmll_locl.h create mode 100644 Sources/COpenSSL/cms.h create mode 100644 Sources/COpenSSL/cms_.c create mode 100644 Sources/COpenSSL/cms_lcl.h create mode 100644 Sources/COpenSSL/comp.h create mode 100644 Sources/COpenSSL/comp_.c create mode 100644 Sources/COpenSSL/conf.h create mode 100644 Sources/COpenSSL/conf_.c create mode 100644 Sources/COpenSSL/conf_api.h create mode 100644 Sources/COpenSSL/conf_def.h create mode 100644 Sources/COpenSSL/constant_time_locl.h create mode 100644 Sources/COpenSSL/cpt_err.c create mode 100644 Sources/COpenSSL/cryptlib.c create mode 100644 Sources/COpenSSL/cryptlib.h create mode 100644 Sources/COpenSSL/crypto.h create mode 100644 Sources/COpenSSL/cswift.h create mode 100644 Sources/COpenSSL/ctr128.c create mode 100644 Sources/COpenSSL/cversion.c create mode 100644 Sources/COpenSSL/d1_.c create mode 100644 Sources/COpenSSL/d1_lib.c create mode 100644 Sources/COpenSSL/d2i_.c create mode 100644 Sources/COpenSSL/des.h create mode 100644 Sources/COpenSSL/des_enc.c create mode 100644 Sources/COpenSSL/des_locl.h create mode 100644 Sources/COpenSSL/des_old.c create mode 100644 Sources/COpenSSL/des_old.h create mode 100644 Sources/COpenSSL/des_old2.c create mode 100644 Sources/COpenSSL/des_ver.h create mode 100644 Sources/COpenSSL/dh.h create mode 100644 Sources/COpenSSL/dh_.c create mode 100644 Sources/COpenSSL/digest.c create mode 100644 Sources/COpenSSL/dsa.h create mode 100644 Sources/COpenSSL/dsa_.c create mode 100644 Sources/COpenSSL/dsa_locl.h create mode 100644 Sources/COpenSSL/dso.h create mode 100644 Sources/COpenSSL/dso_.c create mode 100644 Sources/COpenSSL/dtls1.h create mode 100644 Sources/COpenSSL/e_4758cca.c create mode 100644 Sources/COpenSSL/e_4758cca_err.c create mode 100644 Sources/COpenSSL/e_4758cca_err.h create mode 100644 Sources/COpenSSL/e_aep.c create mode 100644 Sources/COpenSSL/e_aep_err.c create mode 100644 Sources/COpenSSL/e_aep_err.h create mode 100644 Sources/COpenSSL/e_aes.c create mode 100644 Sources/COpenSSL/e_aes_cbc_hmac_sha1.c create mode 100644 Sources/COpenSSL/e_aes_cbc_hmac_sha256.c create mode 100644 Sources/COpenSSL/e_atalla.c create mode 100644 Sources/COpenSSL/e_atalla_err.c create mode 100644 Sources/COpenSSL/e_atalla_err.h create mode 100644 Sources/COpenSSL/e_bf.c create mode 100644 Sources/COpenSSL/e_camellia.c create mode 100644 Sources/COpenSSL/e_capi.c create mode 100644 Sources/COpenSSL/e_capi_err.c create mode 100644 Sources/COpenSSL/e_capi_err.h create mode 100644 Sources/COpenSSL/e_cast.c create mode 100644 Sources/COpenSSL/e_chil.c create mode 100644 Sources/COpenSSL/e_chil_err.c create mode 100644 Sources/COpenSSL/e_chil_err.h create mode 100644 Sources/COpenSSL/e_cswift.c create mode 100644 Sources/COpenSSL/e_cswift_err.c create mode 100644 Sources/COpenSSL/e_cswift_err.h create mode 100644 Sources/COpenSSL/e_des.c create mode 100644 Sources/COpenSSL/e_des3.c create mode 100644 Sources/COpenSSL/e_gmp.c create mode 100644 Sources/COpenSSL/e_gmp_err.c create mode 100644 Sources/COpenSSL/e_gmp_err.h create mode 100644 Sources/COpenSSL/e_gost_err.c create mode 100644 Sources/COpenSSL/e_gost_err.h create mode 100644 Sources/COpenSSL/e_idea.c create mode 100644 Sources/COpenSSL/e_null.c create mode 100644 Sources/COpenSSL/e_nuron.c create mode 100644 Sources/COpenSSL/e_nuron_err.c create mode 100644 Sources/COpenSSL/e_nuron_err.h create mode 100644 Sources/COpenSSL/e_old.c create mode 100644 Sources/COpenSSL/e_os.h create mode 100644 Sources/COpenSSL/e_os2.h create mode 100644 Sources/COpenSSL/e_padlock.c create mode 100644 Sources/COpenSSL/e_rc2.c create mode 100644 Sources/COpenSSL/e_rc4.c create mode 100644 Sources/COpenSSL/e_rc4_hmac_md5.c create mode 100644 Sources/COpenSSL/e_rc5.c create mode 100644 Sources/COpenSSL/e_seed.c create mode 100644 Sources/COpenSSL/e_sureware.c create mode 100644 Sources/COpenSSL/e_sureware_err.c create mode 100644 Sources/COpenSSL/e_sureware_err.h create mode 100644 Sources/COpenSSL/e_ubsec.c create mode 100644 Sources/COpenSSL/e_ubsec_err.c create mode 100644 Sources/COpenSSL/e_ubsec_err.h create mode 100644 Sources/COpenSSL/e_xcbc_d.c create mode 100644 Sources/COpenSSL/ebcdic.c create mode 100644 Sources/COpenSSL/ebcdic.h create mode 100644 Sources/COpenSSL/ec.h create mode 100644 Sources/COpenSSL/ec2_.c create mode 100644 Sources/COpenSSL/ec_.c create mode 100644 Sources/COpenSSL/ec_lcl.h create mode 100644 Sources/COpenSSL/ecb3_enc.c create mode 100644 Sources/COpenSSL/ecb_enc.c create mode 100644 Sources/COpenSSL/ecdh.h create mode 100644 Sources/COpenSSL/ecdsa.h create mode 100644 Sources/COpenSSL/ech_.c create mode 100644 Sources/COpenSSL/ech_locl.h create mode 100644 Sources/COpenSSL/eck_prn.c create mode 100644 Sources/COpenSSL/ecp_mont.c create mode 100644 Sources/COpenSSL/ecp_nist.c create mode 100644 Sources/COpenSSL/ecp_nistp224.c create mode 100644 Sources/COpenSSL/ecp_nistp256.c create mode 100644 Sources/COpenSSL/ecp_nistp521.c create mode 100644 Sources/COpenSSL/ecp_nistputil.c create mode 100644 Sources/COpenSSL/ecp_oct.c create mode 100644 Sources/COpenSSL/ecp_smpl.c create mode 100644 Sources/COpenSSL/ecs_.c create mode 100644 Sources/COpenSSL/ecs_locl.h create mode 100644 Sources/COpenSSL/ede_cbcm_enc.c create mode 100644 Sources/COpenSSL/enc_.c create mode 100644 Sources/COpenSSL/encode.c create mode 100644 Sources/COpenSSL/eng_.c create mode 100644 Sources/COpenSSL/eng_int.h create mode 100644 Sources/COpenSSL/engine.h create mode 100644 Sources/COpenSSL/err.c create mode 100644 Sources/COpenSSL/err.h create mode 100644 Sources/COpenSSL/err_.c create mode 100644 Sources/COpenSSL/evp.h create mode 100644 Sources/COpenSSL/evp_.c create mode 100644 Sources/COpenSSL/evp_locl.h create mode 100644 Sources/COpenSSL/ex_data.c create mode 100644 Sources/COpenSSL/ext_dat.h create mode 100644 Sources/COpenSSL/f_.c create mode 100644 Sources/COpenSSL/fcrypt.c create mode 100644 Sources/COpenSSL/fcrypt_b.c create mode 100644 Sources/COpenSSL/fips_err.h create mode 100644 Sources/COpenSSL/fips_ers.c create mode 100644 Sources/COpenSSL/gcm128.c create mode 100644 Sources/COpenSSL/getenv.c create mode 100644 Sources/COpenSSL/gost2001.c create mode 100644 Sources/COpenSSL/gost2001_keyx.c create mode 100644 Sources/COpenSSL/gost2001_keyx.h create mode 100644 Sources/COpenSSL/gost89.c create mode 100644 Sources/COpenSSL/gost89.h create mode 100644 Sources/COpenSSL/gost94_keyx.c create mode 100644 Sources/COpenSSL/gost_.c create mode 100644 Sources/COpenSSL/gost_keywrap.h create mode 100644 Sources/COpenSSL/gost_lcl.h create mode 100644 Sources/COpenSSL/gost_params.h create mode 100644 Sources/COpenSSL/gosthash.c create mode 100644 Sources/COpenSSL/gosthash.h create mode 100644 Sources/COpenSSL/hm_.c create mode 100644 Sources/COpenSSL/hmac.c create mode 100644 Sources/COpenSSL/hmac.h create mode 100644 Sources/COpenSSL/hw_4758_cca.h create mode 100644 Sources/COpenSSL/hw_ubsec.h create mode 100644 Sources/COpenSSL/hwcryptohook.h create mode 100644 Sources/COpenSSL/i2d_.c create mode 100644 Sources/COpenSSL/i_.c create mode 100644 Sources/COpenSSL/idea.h create mode 100644 Sources/COpenSSL/idea_lcl.h create mode 100644 Sources/COpenSSL/include/module.modulemap create mode 100644 Sources/COpenSSL/include/openssl.h create mode 100644 Sources/COpenSSL/krb5_asn.c create mode 100644 Sources/COpenSSL/krb5_asn.h create mode 100644 Sources/COpenSSL/kssl.c create mode 100644 Sources/COpenSSL/kssl.h create mode 100644 Sources/COpenSSL/kssl_lcl.h create mode 100644 Sources/COpenSSL/lh_stats.c create mode 100644 Sources/COpenSSL/lhash.c create mode 100644 Sources/COpenSSL/lhash.h create mode 100644 Sources/COpenSSL/m_dss.c create mode 100644 Sources/COpenSSL/m_dss1.c create mode 100644 Sources/COpenSSL/m_ecdsa.c create mode 100644 Sources/COpenSSL/m_md2.c create mode 100644 Sources/COpenSSL/m_md4.c create mode 100644 Sources/COpenSSL/m_md5.c create mode 100644 Sources/COpenSSL/m_mdc2.c create mode 100644 Sources/COpenSSL/m_null.c create mode 100644 Sources/COpenSSL/m_ripemd.c create mode 100644 Sources/COpenSSL/m_sha.c create mode 100644 Sources/COpenSSL/m_sha1.c create mode 100644 Sources/COpenSSL/m_sigver.c create mode 100644 Sources/COpenSSL/m_wp.c create mode 100644 Sources/COpenSSL/md32_common.h create mode 100644 Sources/COpenSSL/md4.h create mode 100644 Sources/COpenSSL/md4_.c create mode 100644 Sources/COpenSSL/md4_locl.h create mode 100644 Sources/COpenSSL/md5.h create mode 100644 Sources/COpenSSL/md5_.c create mode 100644 Sources/COpenSSL/md5_locl.h create mode 100644 Sources/COpenSSL/md_rand.c create mode 100644 Sources/COpenSSL/mdc2.h create mode 100644 Sources/COpenSSL/mdc2_one.c create mode 100644 Sources/COpenSSL/mdc2dgst.c create mode 100644 Sources/COpenSSL/mem.c create mode 100644 Sources/COpenSSL/mem_.c create mode 100644 Sources/COpenSSL/modes.h create mode 100644 Sources/COpenSSL/modes_lcl.h create mode 100644 Sources/COpenSSL/n_pkey.c create mode 100644 Sources/COpenSSL/names.c create mode 100644 Sources/COpenSSL/ncbc_enc.h create mode 100644 Sources/COpenSSL/nsseq.c create mode 100644 Sources/COpenSSL/o_.c create mode 100644 Sources/COpenSSL/o_dir.h create mode 100644 Sources/COpenSSL/o_str.h create mode 100644 Sources/COpenSSL/o_time.h create mode 100644 Sources/COpenSSL/obj_.c create mode 100644 Sources/COpenSSL/obj_dat.h create mode 100644 Sources/COpenSSL/obj_mac.h create mode 100644 Sources/COpenSSL/obj_xref.h create mode 100644 Sources/COpenSSL/objects.h create mode 100644 Sources/COpenSSL/ocsp.h create mode 100644 Sources/COpenSSL/ocsp_.c create mode 100644 Sources/COpenSSL/ofb128.c create mode 100644 Sources/COpenSSL/ofb64ede.c create mode 100644 Sources/COpenSSL/ofb64enc.c create mode 100644 Sources/COpenSSL/ofb_enc.c create mode 100644 Sources/COpenSSL/openbsd_hw.c create mode 100644 Sources/COpenSSL/opensslconf.h create mode 100644 Sources/COpenSSL/opensslv.h create mode 100644 Sources/COpenSSL/ossl_typ.h create mode 100644 Sources/COpenSSL/p12_.c create mode 100644 Sources/COpenSSL/p5_.c create mode 100644 Sources/COpenSSL/p8_pkey.c create mode 100644 Sources/COpenSSL/p_.c create mode 100644 Sources/COpenSSL/pcbc_enc.c create mode 100644 Sources/COpenSSL/pcy_.c create mode 100644 Sources/COpenSSL/pcy_int.h create mode 100644 Sources/COpenSSL/pem.h create mode 100644 Sources/COpenSSL/pem2.h create mode 100644 Sources/COpenSSL/pem_.c create mode 100644 Sources/COpenSSL/pk12err.c create mode 100644 Sources/COpenSSL/pk7_.c create mode 100644 Sources/COpenSSL/pk7_enc.h create mode 100644 Sources/COpenSSL/pkcs12.h create mode 100644 Sources/COpenSSL/pkcs7.h create mode 100644 Sources/COpenSSL/pkcs7err.c create mode 100644 Sources/COpenSSL/pmeth_.c create mode 100644 Sources/COpenSSL/pqueue.c create mode 100644 Sources/COpenSSL/pqueue.h create mode 100644 Sources/COpenSSL/pvkfmt.c create mode 100644 Sources/COpenSSL/qud_cksm.c create mode 100644 Sources/COpenSSL/rand.h create mode 100644 Sources/COpenSSL/rand_.c create mode 100644 Sources/COpenSSL/rand_lcl.h create mode 100644 Sources/COpenSSL/randfile.c create mode 100644 Sources/COpenSSL/rc2.h create mode 100644 Sources/COpenSSL/rc2_.c create mode 100644 Sources/COpenSSL/rc2_locl.h create mode 100644 Sources/COpenSSL/rc2cfb64.c create mode 100644 Sources/COpenSSL/rc2ofb64.c create mode 100644 Sources/COpenSSL/rc4.h create mode 100644 Sources/COpenSSL/rc4_.c create mode 100644 Sources/COpenSSL/rc4_locl.h create mode 100644 Sources/COpenSSL/read2pwd.c create mode 100644 Sources/COpenSSL/ripemd.h create mode 100644 Sources/COpenSSL/rmd_.c create mode 100644 Sources/COpenSSL/rmd_locl.h create mode 100644 Sources/COpenSSL/rmdconst.h create mode 100644 Sources/COpenSSL/rpc_des.h create mode 100644 Sources/COpenSSL/rpc_enc.c create mode 100644 Sources/COpenSSL/rsa.h create mode 100644 Sources/COpenSSL/rsa_.c create mode 100644 Sources/COpenSSL/rsa_locl.h create mode 100644 Sources/COpenSSL/rsaz_exp.c create mode 100644 Sources/COpenSSL/rsaz_exp.h create mode 100644 Sources/COpenSSL/s23_.c create mode 100644 Sources/COpenSSL/s2_.c create mode 100644 Sources/COpenSSL/s3_.c create mode 100644 Sources/COpenSSL/safestack.h create mode 100644 Sources/COpenSSL/seed.c create mode 100644 Sources/COpenSSL/seed.h create mode 100644 Sources/COpenSSL/seed_.c create mode 100644 Sources/COpenSSL/seed_locl.h create mode 100644 Sources/COpenSSL/set_key.c create mode 100644 Sources/COpenSSL/sha.h create mode 100644 Sources/COpenSSL/sha1_one.c create mode 100644 Sources/COpenSSL/sha1dgst.c create mode 100644 Sources/COpenSSL/sha256.c create mode 100644 Sources/COpenSSL/sha512.c create mode 100644 Sources/COpenSSL/sha_.c create mode 100644 Sources/COpenSSL/sha_locl.h create mode 100644 Sources/COpenSSL/spr.h create mode 100644 Sources/COpenSSL/srp.h create mode 100644 Sources/COpenSSL/srp_.c create mode 100644 Sources/COpenSSL/srp_grps.h create mode 100644 Sources/COpenSSL/srp_lcl.h create mode 100644 Sources/COpenSSL/srtp.h create mode 100644 Sources/COpenSSL/ssl.h create mode 100644 Sources/COpenSSL/ssl2.h create mode 100644 Sources/COpenSSL/ssl23.h create mode 100644 Sources/COpenSSL/ssl3.h create mode 100644 Sources/COpenSSL/ssl_.c create mode 100644 Sources/COpenSSL/ssl_locl.h create mode 100644 Sources/COpenSSL/stack.c create mode 100644 Sources/COpenSSL/stack.h create mode 100644 Sources/COpenSSL/str2key.c create mode 100644 Sources/COpenSSL/sureware.h create mode 100644 Sources/COpenSSL/symhacks.h create mode 100644 Sources/COpenSSL/t1_.c create mode 100644 Sources/COpenSSL/t_.c create mode 100644 Sources/COpenSSL/tasn_.c create mode 100644 Sources/COpenSSL/tb_asnmth.c create mode 100644 Sources/COpenSSL/tb_cipher.c create mode 100644 Sources/COpenSSL/tb_dh.c create mode 100644 Sources/COpenSSL/tb_digest.c create mode 100644 Sources/COpenSSL/tb_dsa.c create mode 100644 Sources/COpenSSL/tb_ecdh.c create mode 100644 Sources/COpenSSL/tb_ecdsa.c create mode 100644 Sources/COpenSSL/tb_pkmeth.c create mode 100644 Sources/COpenSSL/tb_rand.c create mode 100644 Sources/COpenSSL/tb_rsa.c create mode 100644 Sources/COpenSSL/tb_store.c create mode 100644 Sources/COpenSSL/th-lock.c create mode 100644 Sources/COpenSSL/tls1.h create mode 100644 Sources/COpenSSL/tls_srp.c create mode 100644 Sources/COpenSSL/ts.h create mode 100644 Sources/COpenSSL/ts_.c create mode 100644 Sources/COpenSSL/txt_db.c create mode 100644 Sources/COpenSSL/txt_db.h create mode 100644 Sources/COpenSSL/ui.h create mode 100644 Sources/COpenSSL/ui_.c create mode 100644 Sources/COpenSSL/ui_compat.h create mode 100644 Sources/COpenSSL/ui_locl.h create mode 100644 Sources/COpenSSL/uid.c create mode 100644 Sources/COpenSSL/v3_.c create mode 100644 Sources/COpenSSL/v3_lib.c create mode 100644 Sources/COpenSSL/v3err.c create mode 100644 Sources/COpenSSL/vpm_int.h create mode 100644 Sources/COpenSSL/whrlpool.h create mode 100644 Sources/COpenSSL/wp_.c create mode 100644 Sources/COpenSSL/wp_locl.h create mode 100644 Sources/COpenSSL/wrap128.c create mode 100644 Sources/COpenSSL/x509.h create mode 100644 Sources/COpenSSL/x509_.c create mode 100644 Sources/COpenSSL/x509_vfy.h create mode 100644 Sources/COpenSSL/x509cset.c create mode 100644 Sources/COpenSSL/x509name.c create mode 100644 Sources/COpenSSL/x509rset.c create mode 100644 Sources/COpenSSL/x509spki.c create mode 100644 Sources/COpenSSL/x509type.c create mode 100644 Sources/COpenSSL/x509v3.h create mode 100644 Sources/COpenSSL/x_.c create mode 100644 Sources/COpenSSL/xcbc_enc.c create mode 100644 Sources/COpenSSL/xts128.c create mode 100644 Sources/LinuxBridge/LinuxBridge.c create mode 100644 Sources/LinuxBridge/include/LinuxBridge.h create mode 100755 Sources/PerfectCHTTPParser/http_parser.c create mode 100755 Sources/PerfectCHTTPParser/http_parser.h create mode 100755 Sources/PerfectCHTTPParser/include/http_parser.h create mode 100644 Sources/PerfectCHTTPParser/include/module.modulemap create mode 100644 Sources/PerfectCRUD/Coding/Coding.swift create mode 100644 Sources/PerfectCRUD/Coding/CodingBindings.swift create mode 100644 Sources/PerfectCRUD/Coding/CodingJoins.swift create mode 100644 Sources/PerfectCRUD/Coding/CodingKeyPaths.swift create mode 100644 Sources/PerfectCRUD/Coding/CodingNames.swift create mode 100644 Sources/PerfectCRUD/Coding/CodingRows.swift create mode 100644 Sources/PerfectCRUD/Create.swift create mode 100644 Sources/PerfectCRUD/Database.swift create mode 100644 Sources/PerfectCRUD/Delete.swift create mode 100644 Sources/PerfectCRUD/Expression/Comparison.swift create mode 100644 Sources/PerfectCRUD/Expression/ComparisonInts.swift create mode 100644 Sources/PerfectCRUD/Expression/Equality.swift create mode 100644 Sources/PerfectCRUD/Expression/EqualityInts.swift create mode 100644 Sources/PerfectCRUD/Expression/Expression.swift create mode 100644 Sources/PerfectCRUD/Expression/In.swift create mode 100644 Sources/PerfectCRUD/Expression/InInts.swift create mode 100644 Sources/PerfectCRUD/Expression/Like.swift create mode 100644 Sources/PerfectCRUD/Expression/Logical.swift create mode 100644 Sources/PerfectCRUD/Insert.swift create mode 100644 Sources/PerfectCRUD/Join.swift create mode 100644 Sources/PerfectCRUD/Logging.swift create mode 100644 Sources/PerfectCRUD/PerfectCRUD.swift create mode 100644 Sources/PerfectCRUD/Select.swift create mode 100644 Sources/PerfectCRUD/Table.swift create mode 100644 Sources/PerfectCRUD/Update.swift create mode 100644 Sources/PerfectCRUD/Where.swift create mode 100644 Sources/PerfectCSQLite3/include/module.modulemap create mode 100644 Sources/PerfectCSQLite3/include/p_sqlite3.h create mode 100644 Sources/PerfectCSQLite3/sqlite3.c create mode 100644 Sources/PerfectCURL/CURLRequest.swift create mode 100644 Sources/PerfectCURL/CURLRequestOptions.swift create mode 100644 Sources/PerfectCURL/CURLResponse.swift create mode 100644 Sources/PerfectCURL/CURLResponseInfos.swift create mode 100644 Sources/PerfectCURL/HTTPHeaders.swift create mode 100644 Sources/PerfectCURL/HTTPMethod.swift create mode 100644 Sources/PerfectCURL/cURL.swift create mode 100644 Sources/PerfectCZlib/CMakeLists.txt create mode 100644 Sources/PerfectCZlib/ChangeLog create mode 100644 Sources/PerfectCZlib/FAQ create mode 100644 Sources/PerfectCZlib/INDEX create mode 100644 Sources/PerfectCZlib/Makefile create mode 100644 Sources/PerfectCZlib/Makefile.in create mode 100644 Sources/PerfectCZlib/README create mode 100644 Sources/PerfectCZlib/adler32.c create mode 100644 Sources/PerfectCZlib/amiga/Makefile.pup create mode 100644 Sources/PerfectCZlib/amiga/Makefile.sas create mode 100644 Sources/PerfectCZlib/compress.c create mode 100755 Sources/PerfectCZlib/configure create mode 100644 Sources/PerfectCZlib/configure.log create mode 100644 Sources/PerfectCZlib/crc32.c create mode 100644 Sources/PerfectCZlib/crc32.h create mode 100644 Sources/PerfectCZlib/deflate.c create mode 100644 Sources/PerfectCZlib/deflate.h create mode 100644 Sources/PerfectCZlib/doc/algorithm.txt create mode 100644 Sources/PerfectCZlib/doc/rfc1950.txt create mode 100644 Sources/PerfectCZlib/doc/rfc1951.txt create mode 100644 Sources/PerfectCZlib/doc/rfc1952.txt create mode 100644 Sources/PerfectCZlib/doc/txtvsbin.txt create mode 100644 Sources/PerfectCZlib/gzclose.c create mode 100644 Sources/PerfectCZlib/gzguts.h create mode 100644 Sources/PerfectCZlib/gzlib.c create mode 100644 Sources/PerfectCZlib/gzread.c create mode 100644 Sources/PerfectCZlib/gzwrite.c create mode 100755 Sources/PerfectCZlib/include/czlib.h create mode 100644 Sources/PerfectCZlib/include/inflate.h create mode 100644 Sources/PerfectCZlib/include/inftrees.h create mode 100644 Sources/PerfectCZlib/include/module.modulemap create mode 100644 Sources/PerfectCZlib/include/zconf.h create mode 100644 Sources/PerfectCZlib/include/zlib.h create mode 100644 Sources/PerfectCZlib/infback.c create mode 100644 Sources/PerfectCZlib/inffast.c create mode 100644 Sources/PerfectCZlib/inffast.h create mode 100644 Sources/PerfectCZlib/inffixed.h create mode 100644 Sources/PerfectCZlib/inflate.c create mode 100644 Sources/PerfectCZlib/inflate.h create mode 100644 Sources/PerfectCZlib/inftrees.c create mode 100644 Sources/PerfectCZlib/inftrees.h create mode 100644 Sources/PerfectCZlib/make_vms.com create mode 100644 Sources/PerfectCZlib/msdos/Makefile.bor create mode 100644 Sources/PerfectCZlib/msdos/Makefile.dj2 create mode 100644 Sources/PerfectCZlib/msdos/Makefile.emx create mode 100644 Sources/PerfectCZlib/msdos/Makefile.msc create mode 100644 Sources/PerfectCZlib/msdos/Makefile.tc create mode 100644 Sources/PerfectCZlib/nintendods/Makefile create mode 100644 Sources/PerfectCZlib/nintendods/README create mode 100644 Sources/PerfectCZlib/old/Makefile.emx create mode 100644 Sources/PerfectCZlib/old/Makefile.riscos create mode 100644 Sources/PerfectCZlib/old/README create mode 100644 Sources/PerfectCZlib/old/descrip.mms create mode 100644 Sources/PerfectCZlib/old/os2/Makefile.os2 create mode 100644 Sources/PerfectCZlib/old/os2/zlib.def create mode 100644 Sources/PerfectCZlib/old/visual-basic.txt create mode 100644 Sources/PerfectCZlib/os400/README400 create mode 100644 Sources/PerfectCZlib/os400/bndsrc create mode 100644 Sources/PerfectCZlib/os400/make.sh create mode 100644 Sources/PerfectCZlib/os400/zlib.inc create mode 100644 Sources/PerfectCZlib/qnx/package.qpg create mode 100644 Sources/PerfectCZlib/treebuild.xml create mode 100644 Sources/PerfectCZlib/trees.c create mode 100644 Sources/PerfectCZlib/trees.h create mode 100644 Sources/PerfectCZlib/uncompr.c create mode 100644 Sources/PerfectCZlib/watcom/watcom_f.mak create mode 100644 Sources/PerfectCZlib/watcom/watcom_l.mak create mode 100644 Sources/PerfectCZlib/win32/DLL_FAQ.txt create mode 100644 Sources/PerfectCZlib/win32/Makefile.bor create mode 100644 Sources/PerfectCZlib/win32/Makefile.gcc create mode 100644 Sources/PerfectCZlib/win32/Makefile.msc create mode 100644 Sources/PerfectCZlib/win32/README-WIN32.txt create mode 100644 Sources/PerfectCZlib/win32/VisualC.txt create mode 100644 Sources/PerfectCZlib/win32/zlib.def create mode 100644 Sources/PerfectCZlib/win32/zlib1.rc create mode 100644 Sources/PerfectCZlib/zconf.h create mode 100644 Sources/PerfectCZlib/zconf.h.cmakein create mode 100644 Sources/PerfectCZlib/zconf.h.in create mode 100644 Sources/PerfectCZlib/zlib.3 create mode 100644 Sources/PerfectCZlib/zlib.3.pdf create mode 100644 Sources/PerfectCZlib/zlib.h create mode 100644 Sources/PerfectCZlib/zlib.map create mode 100644 Sources/PerfectCZlib/zlib.pc create mode 100644 Sources/PerfectCZlib/zlib.pc.cmakein create mode 100644 Sources/PerfectCZlib/zlib.pc.in create mode 100755 Sources/PerfectCZlib/zlib2ansi create mode 100644 Sources/PerfectCZlib/zutil.c create mode 100644 Sources/PerfectCZlib/zutil.h create mode 100644 Sources/PerfectCrypto/Algorithms.swift create mode 100644 Sources/PerfectCrypto/ByteIO.swift create mode 100644 Sources/PerfectCrypto/Extensions.swift create mode 100644 Sources/PerfectCrypto/JWK.swift create mode 100644 Sources/PerfectCrypto/JWT.swift create mode 100644 Sources/PerfectCrypto/Keys.swift create mode 100644 Sources/PerfectCrypto/OpenSSLInternal.swift create mode 100644 Sources/PerfectCrypto/PerfectCrypto.swift create mode 100644 Sources/PerfectHTTP/HTTPFilter.swift create mode 100644 Sources/PerfectHTTP/HTTPHeaders.swift create mode 100644 Sources/PerfectHTTP/HTTPMethod.swift create mode 100644 Sources/PerfectHTTP/HTTPRequest.swift create mode 100644 Sources/PerfectHTTP/HTTPResponse.swift create mode 100644 Sources/PerfectHTTP/MimeReader.swift create mode 100644 Sources/PerfectHTTP/MimeType.swift create mode 100644 Sources/PerfectHTTP/Routing.swift create mode 100644 Sources/PerfectHTTP/StaticFileHandler.swift create mode 100644 Sources/PerfectHTTP/TypedRoutes.swift create mode 100644 Sources/PerfectHTTPServer/HTTP11/HTTP11Request.swift create mode 100644 Sources/PerfectHTTPServer/HTTP11/HTTP11Response.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HPACK.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2Client.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2Frame.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2FrameReader.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2FrameWriter.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2PrefaceValidator.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2Request.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2Response.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2Session.swift create mode 100644 Sources/PerfectHTTPServer/HTTP2/HTTP2SessionSettings.swift create mode 100644 Sources/PerfectHTTPServer/HTTPContentCompression.swift create mode 100644 Sources/PerfectHTTPServer/HTTPMultiplexer.swift create mode 100644 Sources/PerfectHTTPServer/HTTPServer.swift create mode 100644 Sources/PerfectHTTPServer/HTTPServerEx.swift create mode 100644 Sources/PerfectHTTPServer/HTTPServerExConfig.swift delete mode 100644 Sources/PerfectLib/SysProcess.swift create mode 100644 Sources/PerfectMustache/Mustache.swift create mode 100644 Sources/PerfectNet/Net.swift create mode 100644 Sources/PerfectNet/NetAddress.swift create mode 100644 Sources/PerfectNet/NetEvent.swift create mode 100644 Sources/PerfectNet/NetNamedPipe.swift create mode 100644 Sources/PerfectNet/NetTCP.swift create mode 100644 Sources/PerfectNet/NetTCPSSL.swift create mode 100644 Sources/PerfectNet/NetUDP.swift create mode 100644 Sources/PerfectSMTP/PerfectSMTP.swift create mode 100644 Sources/PerfectSQLite/SQLite.swift create mode 100644 Sources/PerfectSQLite/SQLiteCRUD.swift create mode 100644 Sources/PerfectThread/Promise.swift create mode 100644 Sources/PerfectThread/ThreadQueue.swift create mode 100644 Sources/PerfectThread/Threading.swift create mode 100644 Sources/cURL/ccurl.c create mode 100644 Sources/cURL/include/module.modulemap create mode 100644 Sources/cURL/include/p_curl.h delete mode 100644 Tests/LinuxMain.swift create mode 100644 Tests/PerfectCURLTests/PerfectCURLTests.swift create mode 100644 Tests/PerfectCryptoTests/PerfectCryptoTests.swift create mode 100644 Tests/PerfectHTTPServerTests/PerfectHTTPServerTests.swift create mode 100644 Tests/PerfectHTTPTests/PerfectHTTPTests.swift delete mode 100644 Tests/PerfectLibTests/XCTestManifests.swift create mode 100644 Tests/PerfectMustacheTests/PerfectMustacheTests.swift create mode 100644 Tests/PerfectNetTests/PerfectNetTests.swift create mode 100644 Tests/PerfectSMTPTests/PerfectSMTPTests.swift create mode 100644 Tests/PerfectSQLiteTests/PerfectSQLiteTests.swift create mode 100644 Tests/PerfectThreadTests/PerfectThreadTests.swift create mode 100644 arm64.url.txt create mode 100755 docker-build.sh create mode 100755 docker-test.sh create mode 100644 i386.url.txt create mode 100644 smtp.test.json create mode 100644 smtp.test.json.example create mode 100755 test-linux.sh create mode 100755 test-macos.sh diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 00000000..b819d26f --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,32 @@ +cyclomatic_complexity: + - 64 # warning + - 128 # error +file_length: + - 2048 # warning + - 4096 # error +function_body_length: + - 128 # warning + - 256 # error +line_length: + - 256 # warning + - 512 # error +type_body_length: + - 512 # warning + - 1024 # error +disabled_rules: + - empty_enum_arguments + - function_parameter_count + - identifier_name + - inclusive_language + - large_tuple + - multiple_closures_with_trailing_closure + - nesting + - redundant_optional_initialization + - syntactic_sugar + - unused_optional_binding + - vertical_parameter_alignment + - void_return +excluded: + - .build/ + - Sources/PerfectHTTP/Mime*.swift + - Sources/PerfectHTTPServer/HTTP2/HPACK.swift \ No newline at end of file diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..97659eec --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM ubuntu:20.04 +RUN apt-get update -y +RUN apt-get install -y wget +WORKDIR /tmp +ARG arch +COPY ./${arch}.url.txt /tmp/url.txt +RUN rm -rf /tmp/sw* +RUN wget -O /tmp/swift.tgz $(cat /tmp/url.txt) +RUN cd /tmp && tar xf /tmp/swift.tgz && rm -rf /tmp/swift.tgz && mv $(ls|grep swift) /tmp/swift/ +RUN cd /tmp/swift/usr/ && tar cf /tmp/sw.tar * +RUN cd /usr && tar xf /tmp/sw.tar +RUN rm -rf /tmp/sw* +RUN apt-get update -y +RUN apt-get install -y build-essential clang wget +RUN apt-get install -y libcurl4-openssl-dev uuid-dev +RUN apt-get install -y libsqlite3-dev libncurses-dev +RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libxml2-dev diff --git a/Package.swift b/Package.swift index b6623ef2..892fd327 100644 --- a/Package.swift +++ b/Package.swift @@ -1,50 +1,58 @@ -// swift-tools-version:5.1 -// -// Package.swift -// PerfectLib -// -// Created by Kyle Jessup on 3/22/16. -// Copyright (C) 2016 PerfectlySoft, Inc. -// -//===----------------------------------------------------------------------===// -// -// This source file is part of the Perfect.org open source project -// -// Copyright (c) 2015 - 2016 PerfectlySoft Inc. and the Perfect project authors -// Licensed under Apache License v2.0 -// -// See http://perfect.org/licensing.html for license information -// -//===----------------------------------------------------------------------===// -// +// swift-tools-version: 5.6 +// The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription #if os(Linux) -let package = Package( - name: "PerfectLib", - products: [ - .library(name: "PerfectLib", targets: ["PerfectLib"]) - ], - dependencies: [.package(url: "https://github.com/PerfectlySoft/Perfect-LinuxBridge.git", from: "3.0.0")], - targets: [ - .target(name: "PerfectLib", dependencies: ["LinuxBridge"]), - .testTarget(name: "PerfectLibTests", dependencies: ["PerfectLib"]) - ] -) +let osdep: [Target.Dependency] = ["LinuxBridge"] +let ostag: [Target] = [.target(name: "LinuxBridge"), .target(name: "PerfectCSQLite3")] +let sqldep: [Target.Dependency] = ["PerfectCSQLite3", "PerfectCRUD"] #else +let osdep: [Target.Dependency] = [] +let ostag: [Target] = [] +let sqldep: [Target.Dependency] = ["PerfectCRUD"] +#endif let package = Package( - name: "PerfectLib", - platforms: [ - .macOS(.v10_15) - ], - products: [ - .library(name: "PerfectLib", targets: ["PerfectLib"]) - ], - dependencies: [], - targets: [ - .target(name: "PerfectLib", dependencies: []), - .testTarget(name: "PerfectLibTests", dependencies: ["PerfectLib"]) - ] + name: "PerfectLib", + products: [ + .library(name: "PerfectCRUD", targets: ["PerfectCRUD"]), + .library(name: "PerfectCrypto", targets: ["PerfectCrypto"]), + .library(name: "PerfectCURL", targets: ["PerfectCURL"]), + .library(name: "PerfectLib", targets: ["PerfectLib"]), + .library(name: "PerfectHTTP", targets: ["PerfectHTTP"]), + .library(name: "PerfectHTTPServer", targets: ["PerfectHTTPServer"]), + .library(name: "PerfectMustache", targets: ["PerfectMustache"]), + .library(name: "PerfectNet", targets: ["PerfectNet"]), + .library(name: "PerfectSMTP", targets: ["PerfectSMTP"]), + .library(name: "PerfectSQLite", targets: ["PerfectSQLite"]), + .library(name: "PerfectThread", targets: ["PerfectThread"]) + ], + dependencies: [ ], + targets: ostag + [ + .target(name: "COpenSSL"), + .target(name: "cURL"), + .target(name: "PerfectCZlib"), + .target(name: "PerfectCHTTPParser"), + .target(name: "PerfectLib", dependencies: osdep), + .target(name: "PerfectThread", dependencies: osdep), + .target(name: "PerfectCRUD"), + .target(name: "PerfectCrypto", dependencies: ["PerfectLib", "PerfectThread", "COpenSSL"]), + .target(name: "PerfectCURL", dependencies: ["cURL", "PerfectLib", "PerfectThread"]), + .target(name: "PerfectHTTP", dependencies: ["PerfectLib", "PerfectNet"]), + .target(name: "PerfectHTTPServer", dependencies: ["PerfectCHTTPParser", "PerfectNet", "PerfectHTTP", "PerfectCZlib"]), + .target(name: "PerfectMustache", dependencies: ["PerfectLib"]), + .target(name: "PerfectNet", dependencies: ["PerfectCrypto", "PerfectThread"]), + .target(name: "PerfectSMTP", dependencies: ["PerfectCURL", "PerfectCrypto", "PerfectHTTP"]), + .target(name: "PerfectSQLite", dependencies: sqldep), + .testTarget(name: "PerfectCryptoTests", dependencies: ["PerfectCrypto"]), + .testTarget(name: "PerfectCURLTests", dependencies: ["PerfectCURL"]), + .testTarget(name: "PerfectHTTPTests", dependencies: ["PerfectHTTP"]), + .testTarget(name: "PerfectHTTPServerTests", dependencies: ["PerfectHTTPServer"]), + .testTarget(name: "PerfectLibTests", dependencies: ["PerfectLib"]), + .testTarget(name: "PerfectMustacheTests", dependencies: ["PerfectMustache"]), + .testTarget(name: "PerfectNetTests", dependencies: ["PerfectNet"]), + .testTarget(name: "PerfectSMTPTests", dependencies: ["PerfectSMTP"]), + .testTarget(name: "PerfectSQLiteTests", dependencies: ["PerfectSQLite"]), + .testTarget(name: "PerfectThreadTests", dependencies: ["PerfectThread"]) + ] ) -#endif diff --git a/Sources/COpenSSL/LPdir_unix.h b/Sources/COpenSSL/LPdir_unix.h new file mode 100644 index 00000000..c97e2604 --- /dev/null +++ b/Sources/COpenSSL/LPdir_unix.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifndef LPDIR_H +# include "LPdir.h" +#endif + +/* + * The POSIXly macro for the maximum number of characters in a file path is + * NAME_MAX. However, some operating systems use PATH_MAX instead. + * Therefore, it seems natural to first check for PATH_MAX and use that, and + * if it doesn't exist, use NAME_MAX. + */ +#if defined(PATH_MAX) +# define LP_ENTRY_SIZE PATH_MAX +#elif defined(NAME_MAX) +# define LP_ENTRY_SIZE NAME_MAX +#endif + +/* + * Of course, there's the possibility that neither PATH_MAX nor NAME_MAX + * exist. It's also possible that NAME_MAX exists but is define to a very + * small value (HP-UX offers 14), so we need to check if we got a result, and + * if it meets a minimum standard, and create or change it if not. + */ +#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255 +# undef LP_ENTRY_SIZE +# define LP_ENTRY_SIZE 255 +#endif + +struct LP_dir_context_st { + DIR *dir; + char entry_name[LP_ENTRY_SIZE + 1]; +}; + +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) +{ + struct dirent *direntry = NULL; + + if (ctx == NULL || directory == NULL) { + errno = EINVAL; + return 0; + } + + errno = 0; + if (*ctx == NULL) { + *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); + if (*ctx == NULL) { + errno = ENOMEM; + return 0; + } + memset(*ctx, '\0', sizeof(LP_DIR_CTX)); + + (*ctx)->dir = opendir(directory); + if ((*ctx)->dir == NULL) { + int save_errno = errno; /* Probably not needed, but I'm paranoid */ + free(*ctx); + *ctx = NULL; + errno = save_errno; + return 0; + } + } + + direntry = readdir((*ctx)->dir); + if (direntry == NULL) { + return 0; + } + + strncpy((*ctx)->entry_name, direntry->d_name, + sizeof((*ctx)->entry_name) - 1); + (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; + return (*ctx)->entry_name; +} + +int LP_find_file_end(LP_DIR_CTX **ctx) +{ + if (ctx != NULL && *ctx != NULL) { + int ret = closedir((*ctx)->dir); + + free(*ctx); + switch (ret) { + case 0: + return 1; + case -1: + return 0; + default: + break; + } + } + errno = EINVAL; + return 0; +} diff --git a/Sources/COpenSSL/a_.c b/Sources/COpenSSL/a_.c new file mode 100644 index 00000000..82d63aa4 --- /dev/null +++ b/Sources/COpenSSL/a_.c @@ -0,0 +1,6178 @@ +/* crypto/asn1/a_bitstr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include "asn1.h" + +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) +{ + return M_ASN1_BIT_STRING_set(x, d, len); +} + +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) +{ + int ret, j, bits, len; + unsigned char *p, *d; + + if (a == NULL) + return (0); + + len = a->length; + + if (len > 0) { + if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) { + bits = (int)a->flags & 0x07; + } else { + for (; len > 0; len--) { + if (a->data[len - 1]) + break; + } + j = a->data[len - 1]; + if (j & 0x01) + bits = 0; + else if (j & 0x02) + bits = 1; + else if (j & 0x04) + bits = 2; + else if (j & 0x08) + bits = 3; + else if (j & 0x10) + bits = 4; + else if (j & 0x20) + bits = 5; + else if (j & 0x40) + bits = 6; + else if (j & 0x80) + bits = 7; + else + bits = 0; /* should not happen */ + } + } else + bits = 0; + + ret = 1 + len; + if (pp == NULL) + return (ret); + + p = *pp; + + *(p++) = (unsigned char)bits; + d = a->data; + if (len > 0) { + memcpy(p, d, len); + p += len; + p[-1] &= (0xff << bits); + } + *pp = p; + return (ret); +} + +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long len) +{ + ASN1_BIT_STRING *ret = NULL; + const unsigned char *p; + unsigned char *s; + int i; + + if (len < 1) { + i = ASN1_R_STRING_TOO_SHORT; + goto err; + } + + if (len > INT_MAX) { + i = ASN1_R_STRING_TOO_LONG; + goto err; + } + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = M_ASN1_BIT_STRING_new()) == NULL) + return (NULL); + } else + ret = (*a); + + p = *pp; + i = *(p++); + if (i > 7) { + i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT; + goto err; + } + /* + * We do this to preserve the settings. If we modify the settings, via + * the _set_bit function, we will recalculate on output + */ + ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ + ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */ + + if (len-- > 1) { /* using one because of the bits left byte */ + s = (unsigned char *)OPENSSL_malloc((int)len); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + memcpy(s, p, (int)len); + s[len - 1] &= (0xff << i); + p += len; + } else + s = NULL; + + ret->length = (int)len; + if (ret->data != NULL) + OPENSSL_free(ret->data); + ret->data = s; + ret->type = V_ASN1_BIT_STRING; + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_BIT_STRING_free(ret); + return (NULL); +} + +/* + * These next 2 functions from Goetz Babin-Ebell + */ +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) +{ + int w, v, iv; + unsigned char *c; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + iv = ~v; + if (!value) + v = 0; + + if (a == NULL) + return 0; + + a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ + + if ((a->length < (w + 1)) || (a->data == NULL)) { + if (!value) + return (1); /* Don't need to set */ + if (a->data == NULL) + c = (unsigned char *)OPENSSL_malloc(w + 1); + else + c = (unsigned char *)OPENSSL_realloc_clean(a->data, + a->length, w + 1); + if (c == NULL) { + ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE); + return 0; + } + if (w + 1 - a->length > 0) + memset(c + a->length, 0, w + 1 - a->length); + a->data = c; + a->length = w + 1; + } + a->data[w] = ((a->data[w]) & iv) | v; + while ((a->length > 0) && (a->data[a->length - 1] == 0)) + a->length--; + return (1); +} + +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n) +{ + int w, v; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) + return (0); + return ((a->data[w] & v) != 0); +} + +/* + * Checks if the given bit string contains only bits specified by + * the flags vector. Returns 0 if there is at least one bit set in 'a' + * which is not specified in 'flags', 1 otherwise. + * 'len' is the length of 'flags'. + */ +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len) +{ + int i, ok; + /* Check if there is one bit set at all. */ + if (!a || !a->data) + return 1; + + /* + * Check each byte of the internal representation of the bit string. + */ + ok = 1; + for (i = 0; i < a->length && ok; ++i) { + unsigned char mask = i < flags_len ? ~flags[i] : 0xff; + /* We are done if there is an unneeded bit set. */ + ok = (a->data[i] & mask) == 0; + } + return ok; +} +/* crypto/asn1/a_bool.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "asn1t.h" + +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp) +{ + int r; + unsigned char *p, *allocated = NULL; + + r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN); + if (pp == NULL) + return (r); + + if (*pp == NULL) { + if ((p = allocated = OPENSSL_malloc(r)) == NULL) { + ASN1err(ASN1_F_I2D_ASN1_BOOLEAN, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + p = *pp; + } + + ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL); + *p = (unsigned char)a; + + + /* + * If a new buffer was allocated, just return it back. + * If not, return the incremented buffer pointer. + */ + *pp = allocated != NULL ? allocated : p + 1; + return r; +} + +int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length) +{ + int ret = -1; + const unsigned char *p; + long len; + int inf, tag, xclass; + int i = 0; + + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + i = ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != V_ASN1_BOOLEAN) { + i = ASN1_R_EXPECTING_A_BOOLEAN; + goto err; + } + + if (len != 1) { + i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH; + goto err; + } + ret = (int)*(p++); + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_D2I_ASN1_BOOLEAN, i); + return (ret); +} +/* crypto/asn1/a_bytes.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" + +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c, + int depth); +static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a, + const unsigned char **pp, long length, + int Ptag, int Pclass, int depth, + int *perr); +/* + * type is a 'bitmap' of acceptable string types. + */ +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int type) +{ + ASN1_STRING *ret = NULL; + const unsigned char *p; + unsigned char *s; + long len; + int inf, tag, xclass; + int i = 0; + + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) + goto err; + + if (tag >= 32) { + i = ASN1_R_TAG_VALUE_TOO_HIGH; + goto err; + } + if (!(ASN1_tag2bit(tag) & type)) { + i = ASN1_R_WRONG_TYPE; + goto err; + } + + /* If a bit-string, exit early */ + if (tag == V_ASN1_BIT_STRING) + return (d2i_ASN1_BIT_STRING(a, pp, length)); + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = ASN1_STRING_new()) == NULL) + return (NULL); + } else + ret = (*a); + + if (len != 0) { + s = OPENSSL_malloc((int)len + 1); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + memcpy(s, p, (int)len); + s[len] = '\0'; + p += len; + } else + s = NULL; + + if (ret->data != NULL) + OPENSSL_free(ret->data); + ret->length = (int)len; + ret->data = s; + ret->type = tag; + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_STRING_free(ret); + return (NULL); +} + +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass) +{ + int ret, r, constructed; + unsigned char *p; + + if (a == NULL) + return (0); + + if (tag == V_ASN1_BIT_STRING) + return (i2d_ASN1_BIT_STRING(a, pp)); + + ret = a->length; + r = ASN1_object_size(0, ret, tag); + if (pp == NULL) + return (r); + p = *pp; + + if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET)) + constructed = 1; + else + constructed = 0; + ASN1_put_object(&p, constructed, ret, tag, xclass); + memcpy(p, a->data, a->length); + p += a->length; + *pp = p; + return (r); +} + +/* + * Maximum recursion depth of d2i_ASN1_bytes(): much more than should be + * encountered in pratice. + */ + +#define ASN1_BYTES_MAXDEPTH 20 + +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int Ptag, int Pclass) +{ + int err = 0; + ASN1_STRING *s = int_d2i_ASN1_bytes(a, pp, length, Ptag, Pclass, 0, &err); + if (err != 0) + ASN1err(ASN1_F_D2I_ASN1_BYTES, err); + return s; +} + +static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a, + const unsigned char **pp, long length, + int Ptag, int Pclass, + int depth, int *perr) +{ + ASN1_STRING *ret = NULL; + const unsigned char *p; + unsigned char *s; + long len; + int inf, tag, xclass; + + if (depth > ASN1_BYTES_MAXDEPTH) { + *perr = ASN1_R_NESTED_ASN1_STRING; + return NULL; + } + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = ASN1_STRING_new()) == NULL) + return (NULL); + } else + ret = (*a); + + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + *perr = ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != Ptag) { + *perr = ASN1_R_WRONG_TAG; + goto err; + } + + if (inf & V_ASN1_CONSTRUCTED) { + ASN1_const_CTX c; + + c.error = 0; + c.pp = pp; + c.p = p; + c.inf = inf; + c.slen = len; + c.tag = Ptag; + c.xclass = Pclass; + c.max = (length == 0) ? 0 : (p + length); + if (!asn1_collate_primitive(ret, &c, depth)) { + *perr = c.error; + goto err; + } else { + p = c.p; + } + } else { + if (len != 0) { + if ((ret->length < len) || (ret->data == NULL)) { + s = OPENSSL_malloc((int)len + 1); + if (s == NULL) { + *perr = ERR_R_MALLOC_FAILURE; + goto err; + } + if (ret->data != NULL) + OPENSSL_free(ret->data); + } else + s = ret->data; + memcpy(s, p, (int)len); + s[len] = '\0'; + p += len; + } else { + s = NULL; + if (ret->data != NULL) + OPENSSL_free(ret->data); + } + + ret->length = (int)len; + ret->data = s; + ret->type = Ptag; + } + + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_STRING_free(ret); + return (NULL); +} + +/* + * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them + * into the one structure that is then returned + */ +/* + * There have been a few bug fixes for this function from Paul Keogh + * , many thanks to him + */ +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c, + int depth) +{ + ASN1_STRING *os = NULL; + BUF_MEM b; + int num; + + b.length = 0; + b.max = 0; + b.data = NULL; + + if (a == NULL) { + c->error = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + num = 0; + for (;;) { + if (c->inf & 1) { + c->eos = ASN1_const_check_infinite_end(&c->p, + (long)(c->max - c->p)); + if (c->eos) + break; + } else { + if (c->slen <= 0) + break; + } + + c->q = c->p; + if (int_d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass, + depth + 1, &c->error) == NULL) { + goto err; + } + + if (!BUF_MEM_grow_clean(&b, num + os->length)) { + c->error = ERR_R_BUF_LIB; + goto err; + } + memcpy(&(b.data[num]), os->data, os->length); + if (!(c->inf & 1)) + c->slen -= (c->p - c->q); + num += os->length; + } + + if (!asn1_const_Finish(c)) + goto err; + + a->length = num; + if (a->data != NULL) + OPENSSL_free(a->data); + a->data = (unsigned char *)b.data; + if (os != NULL) + ASN1_STRING_free(os); + return (1); + err: + if (os != NULL) + ASN1_STRING_free(os); + if (b.data != NULL) + OPENSSL_free(b.data); + return (0); +} +/* crypto/asn1/a_d2i_fp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +#include "buffer.h" +#include "asn1_mac.h" + +static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); + +#ifndef NO_OLD_ASN1 +# ifndef OPENSSL_NO_FP_API + +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x) +{ + BIO *b; + void *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB); + return (NULL); + } + BIO_set_fp(b, in, BIO_NOCLOSE); + ret = ASN1_d2i_bio(xnew, d2i, b, x); + BIO_free(b); + return (ret); +} +# endif + +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x) +{ + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; + + len = asn1_d2i_read_bio(in, &b); + if (len < 0) + goto err; + + p = (unsigned char *)b->data; + ret = d2i(x, &p, len); + err: + if (b != NULL) + BUF_MEM_free(b); + return (ret); +} + +#endif + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) +{ + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; + + len = asn1_d2i_read_bio(in, &b); + if (len < 0) + goto err; + + p = (const unsigned char *)b->data; + ret = ASN1_item_d2i(x, &p, len, it); + err: + if (b != NULL) + BUF_MEM_free(b); + return (ret); +} + +#ifndef OPENSSL_NO_FP_API +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) +{ + BIO *b; + char *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB); + return (NULL); + } + BIO_set_fp(b, in, BIO_NOCLOSE); + ret = ASN1_item_d2i_bio(it, b, x); + BIO_free(b); + return (ret); +} +#endif + +#define HEADER_SIZE 8 +#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) +static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) +{ + BUF_MEM *b; + unsigned char *p; + int i; + ASN1_const_CTX c; + size_t want = HEADER_SIZE; + int eos = 0; + size_t off = 0; + size_t len = 0; + + b = BUF_MEM_new(); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + return -1; + } + + ERR_clear_error(); + for (;;) { + if (want >= (len - off)) { + want -= (len - off); + + if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + i = BIO_read(in, &(b->data[len]), want); + if ((i < 0) && ((len - off) == 0)) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + if (i > 0) { + if (len + i < len) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + goto err; + } + len += i; + } + } + /* else data already loaded */ + + p = (unsigned char *)&(b->data[off]); + c.p = p; + c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass), + len - off); + if (c.inf & 0x80) { + unsigned long e; + + e = ERR_GET_REASON(ERR_peek_error()); + if (e != ASN1_R_TOO_LONG) + goto err; + else + ERR_clear_error(); /* clear error */ + } + i = c.p - p; /* header length */ + off += i; /* end of data */ + + if (c.inf & 1) { + /* no data body so go round again */ + eos++; + if (eos < 0) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG); + goto err; + } + want = HEADER_SIZE; + } else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) { + /* eos value, so go back and read another header */ + eos--; + if (eos <= 0) + break; + else + want = HEADER_SIZE; + } else { + /* suck in c.slen bytes of data */ + want = c.slen; + if (want > (len - off)) { + size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; + + want -= (len - off); + if (want > INT_MAX /* BIO_read takes an int length */ || + len + want < len) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + goto err; + } + while (want > 0) { + /* + * Read content in chunks of increasing size + * so we can return an error for EOF without + * having to allocate the entire content length + * in one go. + */ + size_t chunk = want > chunk_max ? chunk_max : want; + + if (!BUF_MEM_grow_clean(b, len + chunk)) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + want -= chunk; + while (chunk > 0) { + i = BIO_read(in, &(b->data[len]), chunk); + if (i <= 0) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, + ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + /* + * This can't overflow because |len+want| didn't + * overflow. + */ + len += i; + chunk -= i; + } + if (chunk_max < INT_MAX/2) + chunk_max *= 2; + } + } + if (off + c.slen < off) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + goto err; + } + off += c.slen; + if (eos <= 0) { + break; + } else + want = HEADER_SIZE; + } + } + + if (off > INT_MAX) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + goto err; + } + + *pb = b; + return off; + err: + if (b != NULL) + BUF_MEM_free(b); + return -1; +} +/* crypto/asn1/a_digest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +// #include "cryptlib.h" + +#ifndef NO_SYS_TYPES_H +# include +#endif + +#include "err.h" +#include "evp.h" +// #include "buffer.h" +#include "x509.h" + +#ifndef NO_ASN1_OLD + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len) +{ + int i; + unsigned char *str, *p; + + i = i2d(data, NULL); + if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { + ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE); + return (0); + } + p = str; + i2d(data, &p); + + if (!EVP_Digest(str, i, md, len, type, NULL)) { + OPENSSL_free(str); + return 0; + } + OPENSSL_free(str); + return (1); +} + +#endif + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, + unsigned char *md, unsigned int *len) +{ + int i; + unsigned char *str = NULL; + + i = ASN1_item_i2d(asn, &str, it); + if (!str) + return (0); + + if (!EVP_Digest(str, i, md, len, type, NULL)) { + OPENSSL_free(str); + return 0; + } + OPENSSL_free(str); + return (1); +} +/* crypto/asn1/a_dup.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" + +#ifndef NO_OLD_ASN1 + +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) +{ + unsigned char *b, *p; + const unsigned char *p2; + int i; + char *ret; + + if (x == NULL) + return (NULL); + + i = i2d(x, NULL); + b = OPENSSL_malloc(i + 10); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + i = i2d(x, &p); + p2 = b; + ret = d2i(NULL, &p2, i); + OPENSSL_free(b); + return (ret); +} + +#endif + +/* + * ASN1_ITEM version of dup: this follows the model above except we don't + * need to allocate the buffer. At some point this could be rewritten to + * directly dup the underlying structure instead of doing and encode and + * decode. + */ + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x) +{ + unsigned char *b = NULL; + const unsigned char *p; + long i; + void *ret; + + if (x == NULL) + return (NULL); + + i = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + ret = ASN1_item_d2i(NULL, &p, i, it); + OPENSSL_free(b); + return (ret); +} +/* crypto/asn1/a_enum.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +#include "bn.h" + +/* + * Code for ENUMERATED type: identical to INTEGER apart from a different tag. + * for comments on encoding see a_int.c + */ + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) +{ + int j, k; + unsigned int i; + unsigned char buf[sizeof(long) + 1]; + long d; + + a->type = V_ASN1_ENUMERATED; + if (a->length < (int)(sizeof(long) + 1)) { + if (a->data != NULL) + OPENSSL_free(a->data); + if ((a->data = + (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL) + memset((char *)a->data, 0, sizeof(long) + 1); + } + if (a->data == NULL) { + ASN1err(ASN1_F_ASN1_ENUMERATED_SET, ERR_R_MALLOC_FAILURE); + return (0); + } + d = v; + if (d < 0) { + d = -d; + a->type = V_ASN1_NEG_ENUMERATED; + } + + for (i = 0; i < sizeof(long); i++) { + if (d == 0) + break; + buf[i] = (int)d & 0xff; + d >>= 8; + } + j = 0; + for (k = i - 1; k >= 0; k--) + a->data[j++] = buf[k]; + a->length = j; + return (1); +} + +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a) +{ + int neg = 0, i; + long r = 0; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_ENUMERATED) + neg = 1; + else if (i != V_ASN1_ENUMERATED) + return -1; + + if (a->length > (int)sizeof(long)) { + /* hmm... a bit ugly */ + return (0xffffffffL); + } + if (a->data == NULL) + return 0; + + for (i = 0; i < a->length; i++) { + r <<= 8; + r |= (unsigned char)a->data[i]; + } + if (neg) + r = -r; + return (r); +} + +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai) +{ + ASN1_ENUMERATED *ret; + int len, j; + + if (ai == NULL) + ret = M_ASN1_ENUMERATED_new(); + else + ret = ai; + if (ret == NULL) { + ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (BN_is_negative(bn)) + ret->type = V_ASN1_NEG_ENUMERATED; + else + ret->type = V_ASN1_ENUMERATED; + j = BN_num_bits(bn); + len = ((j == 0) ? 0 : ((j / 8) + 1)); + if (ret->length < len + 4) { + unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); + if (!new_data) { + ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); + goto err; + } + ret->data = new_data; + } + + ret->length = BN_bn2bin(bn, ret->data); + return (ret); + err: + if (ret != ai) + M_ASN1_ENUMERATED_free(ret); + return (NULL); +} + +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn) +{ + BIGNUM *ret; + + if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) + ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN, ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_ENUMERATED) + BN_set_negative(ret, 1); + return (ret); +} +/* crypto/asn1/a_gentm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME + */ + +#include +#include +// #include "cryptlib.h" +#include "o_time.h" +// #include "asn1.h" +#include "asn1_locl.h" + +#if 0 + +int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp) +{ +# ifdef CHARSET_EBCDIC + /* KLUDGE! We convert to ascii before writing DER */ + int len; + char tmp[24]; + ASN1_STRING tmpstr = *(ASN1_STRING *)a; + + len = tmpstr.length; + ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof(tmp)) ? sizeof(tmp) : len); + tmpstr.data = tmp; + + a = (ASN1_GENERALIZEDTIME *)&tmpstr; +# endif + return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, + V_ASN1_GENERALIZEDTIME, V_ASN1_UNIVERSAL)); +} + +ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a, + unsigned char **pp, + long length) +{ + ASN1_GENERALIZEDTIME *ret = NULL; + + ret = + (ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length, + V_ASN1_GENERALIZEDTIME, + V_ASN1_UNIVERSAL); + if (ret == NULL) { + ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ERR_R_NESTED_ASN1_ERROR); + return (NULL); + } +# ifdef CHARSET_EBCDIC + ascii2ebcdic(ret->data, ret->data, ret->length); +# endif + if (!ASN1_GENERALIZEDTIME_check(ret)) { + ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ASN1_R_INVALID_TIME_FORMAT); + goto err; + } + + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_GENERALIZEDTIME_free(ret); + return (NULL); +} + +#endif + +int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) +{ + static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 }; + static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 }; + char *a; + int n, i, l, o; + + if (d->type != V_ASN1_GENERALIZEDTIME) + return (0); + l = d->length; + a = (char *)d->data; + o = 0; + /* + * GENERALIZEDTIME is similar to UTCTIME except the year is represented + * as YYYY. This stuff treats everything as a two digit field so make + * first two fields 00 to 99 + */ + if (l < 13) + goto err; + for (i = 0; i < 7; i++) { + if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { + i++; + if (tm) + tm->tm_sec = 0; + break; + } + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + if (++o > l) + goto err; + + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if (++o > l) + goto err; + + if ((n < min[i]) || (n > max[i])) + goto err; + if (tm) { + switch (i) { + case 0: + tm->tm_year = n * 100 - 1900; + break; + case 1: + tm->tm_year += n; + break; + case 2: + tm->tm_mon = n - 1; + break; + case 3: + tm->tm_mday = n; + break; + case 4: + tm->tm_hour = n; + break; + case 5: + tm->tm_min = n; + break; + case 6: + tm->tm_sec = n; + break; + } + } + } + /* + * Optional fractional seconds: decimal point followed by one or more + * digits. + */ + if (a[o] == '.') { + if (++o > l) + goto err; + i = o; + while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) + o++; + /* Must have at least one digit after decimal point */ + if (i == o) + goto err; + } + + if (a[o] == 'Z') + o++; + else if ((a[o] == '+') || (a[o] == '-')) { + int offsign = a[o] == '-' ? 1 : -1, offset = 0; + o++; + if (o + 4 > l) + goto err; + for (i = 7; i < 9; i++) { + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + o++; + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if ((n < min[i]) || (n > max[i])) + goto err; + if (tm) { + if (i == 7) + offset = n * 3600; + else if (i == 8) + offset += n * 60; + } + o++; + } + if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) + return 0; + } else if (a[o]) { + /* Missing time zone information. */ + goto err; + } + return (o == l); + err: + return (0); +} + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) +{ + return asn1_generalizedtime_to_tm(NULL, d); +} + +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) +{ + ASN1_GENERALIZEDTIME t; + + t.type = V_ASN1_GENERALIZEDTIME; + t.length = strlen(str); + t.data = (unsigned char *)str; + if (ASN1_GENERALIZEDTIME_check(&t)) { + if (s != NULL) { + if (!ASN1_STRING_set((ASN1_STRING *)s, + (unsigned char *)str, t.length)) + return 0; + s->type = V_ASN1_GENERALIZEDTIME; + } + return (1); + } else + return (0); +} + +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t) +{ + return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); +} + +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec) +{ + char *p; + struct tm *ts; + struct tm data; + size_t len = 20; + + if (s == NULL) + s = M_ASN1_GENERALIZEDTIME_new(); + if (s == NULL) + return (NULL); + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) + return (NULL); + + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } + + p = (char *)s->data; + if ((p == NULL) || ((size_t)s->length < len)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE); + return (NULL); + } + if (s->data != NULL) + OPENSSL_free(s->data); + s->data = (unsigned char *)p; + } + + BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900, + ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, + ts->tm_sec); + s->length = strlen(p); + s->type = V_ASN1_GENERALIZEDTIME; +#ifdef CHARSET_EBCDIC_not + ebcdic2ascii(s->data, s->data, s->length); +#endif + return (s); +} +/* crypto/asn1/a_i2d_fp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "asn1.h" + +#ifndef NO_OLD_ASN1 + +# ifndef OPENSSL_NO_FP_API +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, out, BIO_NOCLOSE); + ret = ASN1_i2d_bio(i2d, b, x); + BIO_free(b); + return (ret); +} +# endif + +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) +{ + char *b; + unsigned char *p; + int i, j = 0, n, ret = 1; + + n = i2d(x, NULL); + if (n <= 0) + return 0; + + b = (char *)OPENSSL_malloc(n); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE); + return (0); + } + + p = (unsigned char *)b; + i2d(x, &p); + + for (;;) { + i = BIO_write(out, &(b[j]), n); + if (i == n) + break; + if (i <= 0) { + ret = 0; + break; + } + j += i; + n -= i; + } + OPENSSL_free(b); + return (ret); +} + +#endif + +#ifndef OPENSSL_NO_FP_API +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, out, BIO_NOCLOSE); + ret = ASN1_item_i2d_bio(it, b, x); + BIO_free(b); + return (ret); +} +#endif + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) +{ + unsigned char *b = NULL; + int i, j = 0, n, ret = 1; + + n = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE); + return (0); + } + + for (;;) { + i = BIO_write(out, &(b[j]), n); + if (i == n) + break; + if (i <= 0) { + ret = 0; + break; + } + j += i; + n -= i; + } + OPENSSL_free(b); + return (ret); +} +/* crypto/asn1/a_int.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "bn.h" + +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) +{ + return M_ASN1_INTEGER_dup(x); +} + +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) +{ + int neg, ret; + /* Compare signs */ + neg = x->type & V_ASN1_NEG; + if (neg != (y->type & V_ASN1_NEG)) { + if (neg) + return -1; + else + return 1; + } + + ret = ASN1_STRING_cmp(x, y); + + if (neg) + return -ret; + else + return ret; +} + +/*- + * This converts an ASN1 INTEGER into its content encoding. + * The internal representation is an ASN1_STRING whose data is a big endian + * representation of the value, ignoring the sign. The sign is determined by + * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. + * + * Positive integers are no problem: they are almost the same as the DER + * encoding, except if the first byte is >= 0x80 we need to add a zero pad. + * + * Negative integers are a bit trickier... + * The DER representation of negative integers is in 2s complement form. + * The internal form is converted by complementing each octet and finally + * adding one to the result. This can be done less messily with a little trick. + * If the internal form has trailing zeroes then they will become FF by the + * complement and 0 by the add one (due to carry) so just copy as many trailing + * zeros to the destination as there are in the source. The carry will add one + * to the last none zero octet: so complement this octet and add one and finally + * complement any left over until you get to the start of the string. + * + * Padding is a little trickier too. If the first bytes is > 0x80 then we pad + * with 0xff. However if the first byte is 0x80 and one of the following bytes + * is non-zero we pad with 0xff. The reason for this distinction is that 0x80 + * followed by optional zeros isn't padded. + */ + +int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) +{ + int pad = 0, ret, i, neg; + unsigned char *p, *n, pb = 0; + + if (a == NULL) + return (0); + neg = a->type & V_ASN1_NEG; + if (a->length == 0) + ret = 1; + else { + ret = a->length; + i = a->data[0]; + if (ret == 1 && i == 0) + neg = 0; + if (!neg && (i > 127)) { + pad = 1; + pb = 0; + } else if (neg) { + if (i > 128) { + pad = 1; + pb = 0xFF; + } else if (i == 128) { + /* + * Special case: if any other bytes non zero we pad: + * otherwise we don't. + */ + for (i = 1; i < a->length; i++) + if (a->data[i]) { + pad = 1; + pb = 0xFF; + break; + } + } + } + ret += pad; + } + if (pp == NULL) + return (ret); + p = *pp; + + if (pad) + *(p++) = pb; + if (a->length == 0) + *(p++) = 0; + else if (!neg) + memcpy(p, a->data, (unsigned int)a->length); + else { + /* Begin at the end of the encoding */ + n = a->data + a->length - 1; + p += a->length - 1; + i = a->length; + /* Copy zeros to destination as long as source is zero */ + while (!*n && i > 1) { + *(p--) = 0; + n--; + i--; + } + /* Complement and increment next octet */ + *(p--) = ((*(n--)) ^ 0xff) + 1; + i--; + /* Complement any octets left */ + for (; i > 0; i--) + *(p--) = *(n--) ^ 0xff; + } + + *pp += ret; + return (ret); +} + +/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ + +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long len) +{ + ASN1_INTEGER *ret = NULL; + const unsigned char *p, *pend; + unsigned char *to, *s; + int i; + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = M_ASN1_INTEGER_new()) == NULL) + return (NULL); + ret->type = V_ASN1_INTEGER; + } else + ret = (*a); + + p = *pp; + pend = p + len; + + /* + * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies + * a missing NULL parameter. + */ + s = (unsigned char *)OPENSSL_malloc((int)len + 1); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + to = s; + if (!len) { + /* + * Strictly speaking this is an illegal INTEGER but we tolerate it. + */ + ret->type = V_ASN1_INTEGER; + } else if (*p & 0x80) { /* a negative number */ + ret->type = V_ASN1_NEG_INTEGER; + if ((*p == 0xff) && (len != 1)) { + p++; + len--; + } + i = len; + p += i - 1; + to += i - 1; + while ((!*p) && i) { + *(to--) = 0; + i--; + p--; + } + /* + * Special case: if all zeros then the number will be of the form FF + * followed by n zero bytes: this corresponds to 1 followed by n zero + * bytes. We've already written n zeros so we just append an extra + * one and set the first byte to a 1. This is treated separately + * because it is the only case where the number of bytes is larger + * than len. + */ + if (!i) { + *s = 1; + s[len] = 0; + len++; + } else { + *(to--) = (*(p--) ^ 0xff) + 1; + i--; + for (; i > 0; i--) + *(to--) = *(p--) ^ 0xff; + } + } else { + ret->type = V_ASN1_INTEGER; + if ((*p == 0) && (len != 1)) { + p++; + len--; + } + memcpy(s, p, (int)len); + } + + if (ret->data != NULL) + OPENSSL_free(ret->data); + ret->data = s; + ret->length = (int)len; + if (a != NULL) + (*a) = ret; + *pp = pend; + return (ret); + err: + ASN1err(ASN1_F_C2I_ASN1_INTEGER, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_INTEGER_free(ret); + return (NULL); +} + +/* + * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1 + * integers: some broken software can encode a positive INTEGER with its MSB + * set as negative (it doesn't add a padding zero). + */ + +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length) +{ + ASN1_INTEGER *ret = NULL; + const unsigned char *p; + unsigned char *s; + long len; + int inf, tag, xclass; + int i; + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = M_ASN1_INTEGER_new()) == NULL) + return (NULL); + ret->type = V_ASN1_INTEGER; + } else + ret = (*a); + + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + i = ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != V_ASN1_INTEGER) { + i = ASN1_R_EXPECTING_AN_INTEGER; + goto err; + } + + /* + * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies + * a missing NULL parameter. + */ + s = (unsigned char *)OPENSSL_malloc((int)len + 1); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + ret->type = V_ASN1_INTEGER; + if (len) { + if ((*p == 0) && (len != 1)) { + p++; + len--; + } + memcpy(s, p, (int)len); + p += len; + } + + if (ret->data != NULL) + OPENSSL_free(ret->data); + ret->data = s; + ret->length = (int)len; + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_INTEGER_free(ret); + return (NULL); +} + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) +{ + int j, k; + unsigned int i; + unsigned char buf[sizeof(long) + 1]; + long d; + + a->type = V_ASN1_INTEGER; + if (a->length < (int)(sizeof(long) + 1)) { + if (a->data != NULL) + OPENSSL_free(a->data); + if ((a->data = + (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL) + memset((char *)a->data, 0, sizeof(long) + 1); + } + if (a->data == NULL) { + ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE); + return (0); + } + d = v; + if (d < 0) { + d = -d; + a->type = V_ASN1_NEG_INTEGER; + } + + for (i = 0; i < sizeof(long); i++) { + if (d == 0) + break; + buf[i] = (int)d & 0xff; + d >>= 8; + } + j = 0; + for (k = i - 1; k >= 0; k--) + a->data[j++] = buf[k]; + a->length = j; + return (1); +} + +long ASN1_INTEGER_get(const ASN1_INTEGER *a) +{ + int neg = 0, i; + long r = 0; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_INTEGER) + neg = 1; + else if (i != V_ASN1_INTEGER) + return -1; + + if (a->length > (int)sizeof(long)) { + /* hmm... a bit ugly, return all ones */ + return -1; + } + if (a->data == NULL) + return 0; + + for (i = 0; i < a->length; i++) { + r <<= 8; + r |= (unsigned char)a->data[i]; + } + if (neg) + r = -r; + return (r); +} + +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) +{ + ASN1_INTEGER *ret; + int len, j; + + if (ai == NULL) + ret = M_ASN1_INTEGER_new(); + else + ret = ai; + if (ret == NULL) { + ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (BN_is_negative(bn) && !BN_is_zero(bn)) + ret->type = V_ASN1_NEG_INTEGER; + else + ret->type = V_ASN1_INTEGER; + j = BN_num_bits(bn); + len = ((j == 0) ? 0 : ((j / 8) + 1)); + if (ret->length < len + 4) { + unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); + if (!new_data) { + ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + goto err; + } + ret->data = new_data; + } + ret->length = BN_bn2bin(bn, ret->data); + /* Correct zero case */ + if (!ret->length) { + ret->data[0] = 0; + ret->length = 1; + } + return (ret); + err: + if (ret != ai) + M_ASN1_INTEGER_free(ret); + return (NULL); +} + +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) +{ + BIGNUM *ret; + + if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) + ASN1err(ASN1_F_ASN1_INTEGER_TO_BN, ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_INTEGER) + BN_set_negative(ret, 1); + return (ret); +} + +IMPLEMENT_STACK_OF(ASN1_INTEGER) + +IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER) +/* a_mbstr.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "asn1.h" + +static int traverse_string(const unsigned char *p, int len, int inform, + int (*rfunc) (unsigned long value, void *in), + void *arg); +static int in_utf8(unsigned long value, void *arg); +static int out_utf8(unsigned long value, void *arg); +static int type_str(unsigned long value, void *arg); +static int cpy_asc(unsigned long value, void *arg); +static int cpy_bmp(unsigned long value, void *arg); +static int cpy_univ(unsigned long value, void *arg); +static int cpy_utf8(unsigned long value, void *arg); +static int is_printable(unsigned long value); + +/* + * These functions take a string in UTF8, ASCII or multibyte form and a mask + * of permissible ASN1 string types. It then works out the minimal type + * (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and + * creates a string of the correct type with the supplied data. Yes this is + * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum + * size limits too. + */ + +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask) +{ + return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0); +} + +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize) +{ + int str_type; + int ret; + char free_out; + int outform, outlen = 0; + ASN1_STRING *dest; + unsigned char *p; + int nchar; + char strbuf[32]; + int (*cpyfunc) (unsigned long, void *) = NULL; + if (len == -1) + len = strlen((const char *)in); + if (!mask) + mask = DIRSTRING_TYPE; + + /* First do a string check and work out the number of characters */ + switch (inform) { + + case MBSTRING_BMP: + if (len & 1) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, + ASN1_R_INVALID_BMPSTRING_LENGTH); + return -1; + } + nchar = len >> 1; + break; + + case MBSTRING_UNIV: + if (len & 3) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, + ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); + return -1; + } + nchar = len >> 2; + break; + + case MBSTRING_UTF8: + nchar = 0; + /* This counts the characters and does utf8 syntax checking */ + ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar); + if (ret < 0) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING); + return -1; + } + break; + + case MBSTRING_ASC: + nchar = len; + break; + + default: + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + + if ((minsize > 0) && (nchar < minsize)) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT); + BIO_snprintf(strbuf, sizeof(strbuf), "%ld", minsize); + ERR_add_error_data(2, "minsize=", strbuf); + return -1; + } + + if ((maxsize > 0) && (nchar > maxsize)) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG); + BIO_snprintf(strbuf, sizeof(strbuf), "%ld", maxsize); + ERR_add_error_data(2, "maxsize=", strbuf); + return -1; + } + + /* Now work out minimal type (if any) */ + if (traverse_string(in, len, inform, type_str, &mask) < 0) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS); + return -1; + } + + /* Now work out output format and string type */ + outform = MBSTRING_ASC; + if (mask & B_ASN1_PRINTABLESTRING) + str_type = V_ASN1_PRINTABLESTRING; + else if (mask & B_ASN1_IA5STRING) + str_type = V_ASN1_IA5STRING; + else if (mask & B_ASN1_T61STRING) + str_type = V_ASN1_T61STRING; + else if (mask & B_ASN1_BMPSTRING) { + str_type = V_ASN1_BMPSTRING; + outform = MBSTRING_BMP; + } else if (mask & B_ASN1_UNIVERSALSTRING) { + str_type = V_ASN1_UNIVERSALSTRING; + outform = MBSTRING_UNIV; + } else { + str_type = V_ASN1_UTF8STRING; + outform = MBSTRING_UTF8; + } + if (!out) + return str_type; + if (*out) { + free_out = 0; + dest = *out; + if (dest->data) { + dest->length = 0; + OPENSSL_free(dest->data); + dest->data = NULL; + } + dest->type = str_type; + } else { + free_out = 1; + dest = ASN1_STRING_type_new(str_type); + if (!dest) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + return -1; + } + *out = dest; + } + /* If both the same type just copy across */ + if (inform == outform) { + if (!ASN1_STRING_set(dest, in, len)) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + return -1; + } + return str_type; + } + + /* Work out how much space the destination will need */ + switch (outform) { + case MBSTRING_ASC: + outlen = nchar; + cpyfunc = cpy_asc; + break; + + case MBSTRING_BMP: + outlen = nchar << 1; + cpyfunc = cpy_bmp; + break; + + case MBSTRING_UNIV: + outlen = nchar << 2; + cpyfunc = cpy_univ; + break; + + case MBSTRING_UTF8: + outlen = 0; + traverse_string(in, len, inform, out_utf8, &outlen); + cpyfunc = cpy_utf8; + break; + } + if (!(p = OPENSSL_malloc(outlen + 1))) { + if (free_out) + ASN1_STRING_free(dest); + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + return -1; + } + dest->length = outlen; + dest->data = p; + p[outlen] = 0; + traverse_string(in, len, inform, cpyfunc, &p); + return str_type; +} + +/* + * This function traverses a string and passes the value of each character to + * an optional function along with a void * argument. + */ + +static int traverse_string(const unsigned char *p, int len, int inform, + int (*rfunc) (unsigned long value, void *in), + void *arg) +{ + unsigned long value; + int ret; + while (len) { + if (inform == MBSTRING_ASC) { + value = *p++; + len--; + } else if (inform == MBSTRING_BMP) { + value = *p++ << 8; + value |= *p++; + len -= 2; + } else if (inform == MBSTRING_UNIV) { + value = ((unsigned long)*p++) << 24; + value |= ((unsigned long)*p++) << 16; + value |= *p++ << 8; + value |= *p++; + len -= 4; + } else { + ret = UTF8_getc(p, len, &value); + if (ret < 0) + return -1; + len -= ret; + p += ret; + } + if (rfunc) { + ret = rfunc(value, arg); + if (ret <= 0) + return ret; + } + } + return 1; +} + +/* Various utility functions for traverse_string */ + +/* Just count number of characters */ + +static int in_utf8(unsigned long value, void *arg) +{ + int *nchar; + nchar = arg; + (*nchar)++; + return 1; +} + +/* Determine size of output as a UTF8 String */ + +static int out_utf8(unsigned long value, void *arg) +{ + int *outlen; + outlen = arg; + *outlen += UTF8_putc(NULL, -1, value); + return 1; +} + +/* + * Determine the "type" of a string: check each character against a supplied + * "mask". + */ + +static int type_str(unsigned long value, void *arg) +{ + unsigned long types; + types = *((unsigned long *)arg); + if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value)) + types &= ~B_ASN1_PRINTABLESTRING; + if ((types & B_ASN1_IA5STRING) && (value > 127)) + types &= ~B_ASN1_IA5STRING; + if ((types & B_ASN1_T61STRING) && (value > 0xff)) + types &= ~B_ASN1_T61STRING; + if ((types & B_ASN1_BMPSTRING) && (value > 0xffff)) + types &= ~B_ASN1_BMPSTRING; + if (!types) + return -1; + *((unsigned long *)arg) = types; + return 1; +} + +/* Copy one byte per character ASCII like strings */ + +static int cpy_asc(unsigned long value, void *arg) +{ + unsigned char **p, *q; + p = arg; + q = *p; + *q = (unsigned char)value; + (*p)++; + return 1; +} + +/* Copy two byte per character BMPStrings */ + +static int cpy_bmp(unsigned long value, void *arg) +{ + unsigned char **p, *q; + p = arg; + q = *p; + *q++ = (unsigned char)((value >> 8) & 0xff); + *q = (unsigned char)(value & 0xff); + *p += 2; + return 1; +} + +/* Copy four byte per character UniversalStrings */ + +static int cpy_univ(unsigned long value, void *arg) +{ + unsigned char **p, *q; + p = arg; + q = *p; + *q++ = (unsigned char)((value >> 24) & 0xff); + *q++ = (unsigned char)((value >> 16) & 0xff); + *q++ = (unsigned char)((value >> 8) & 0xff); + *q = (unsigned char)(value & 0xff); + *p += 4; + return 1; +} + +/* Copy to a UTF8String */ + +static int cpy_utf8(unsigned long value, void *arg) +{ + unsigned char **p; + int ret; + p = arg; + /* We already know there is enough room so pass 0xff as the length */ + ret = UTF8_putc(*p, 0xff, value); + *p += ret; + return 1; +} + +/* Return 1 if the character is permitted in a PrintableString */ +static int is_printable(unsigned long value) +{ + int ch; + if (value > 0x7f) + return 0; + ch = (int)value; + /* + * Note: we can't use 'isalnum' because certain accented characters may + * count as alphanumeric in some environments. + */ +#ifndef CHARSET_EBCDIC + if ((ch >= 'a') && (ch <= 'z')) + return 1; + if ((ch >= 'A') && (ch <= 'Z')) + return 1; + if ((ch >= '0') && (ch <= '9')) + return 1; + if ((ch == ' ') || strchr("'()+,-./:=?", ch)) + return 1; +#else /* CHARSET_EBCDIC */ + if ((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) + return 1; + if ((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) + return 1; + if ((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) + return 1; + if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) + return 1; +#endif /* CHARSET_EBCDIC */ + return 0; +} +/* crypto/asn1/a_object.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "asn1.h" +#include "objects.h" +// #include "bn.h" + +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) +{ + unsigned char *p, *allocated = NULL; + int objsize; + + if ((a == NULL) || (a->data == NULL)) + return (0); + + objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT); + if (pp == NULL || objsize == -1) + return objsize; + + if (*pp == NULL) { + if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) { + ASN1err(ASN1_F_I2D_ASN1_OBJECT, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + p = *pp; + } + + ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); + memcpy(p, a->data, a->length); + + /* + * If a new buffer was allocated, just return it back. + * If not, return the incremented buffer pointer. + */ + *pp = allocated != NULL ? allocated : p + a->length; + return objsize; +} + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) +{ + int i, first, len = 0, c, use_bn; + char ftmp[24], *tmp = ftmp; + int tmpsize = sizeof(ftmp); + const char *p; + unsigned long l; + BIGNUM *bl = NULL; + + if (num == 0) + return (0); + else if (num == -1) + num = strlen(buf); + + p = buf; + c = *(p++); + num--; + if ((c >= '0') && (c <= '2')) { + first = c - '0'; + } else { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE); + goto err; + } + + if (num <= 0) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER); + goto err; + } + c = *(p++); + num--; + for (;;) { + if (num <= 0) + break; + if ((c != '.') && (c != ' ')) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR); + goto err; + } + l = 0; + use_bn = 0; + for (;;) { + if (num <= 0) + break; + num--; + c = *(p++); + if ((c == ' ') || (c == '.')) + break; + if ((c < '0') || (c > '9')) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT); + goto err; + } + if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) { + use_bn = 1; + if (!bl) + bl = BN_new(); + if (!bl || !BN_set_word(bl, l)) + goto err; + } + if (use_bn) { + if (!BN_mul_word(bl, 10L) + || !BN_add_word(bl, c - '0')) + goto err; + } else + l = l * 10L + (long)(c - '0'); + } + if (len == 0) { + if ((first < 2) && (l >= 40)) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, + ASN1_R_SECOND_NUMBER_TOO_LARGE); + goto err; + } + if (use_bn) { + if (!BN_add_word(bl, first * 40)) + goto err; + } else + l += (long)first *40; + } + i = 0; + if (use_bn) { + int blsize; + blsize = BN_num_bits(bl); + blsize = (blsize + 6) / 7; + if (blsize > tmpsize) { + if (tmp != ftmp) + OPENSSL_free(tmp); + tmpsize = blsize + 32; + tmp = OPENSSL_malloc(tmpsize); + if (!tmp) + goto err; + } + while (blsize--) { + BN_ULONG t = BN_div_word(bl, 0x80L); + if (t == (BN_ULONG)-1) + goto err; + tmp[i++] = (unsigned char)t; + } + } else { + + for (;;) { + tmp[i++] = (unsigned char)l & 0x7f; + l >>= 7L; + if (l == 0L) + break; + } + + } + if (out != NULL) { + if (len + i > olen) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL); + goto err; + } + while (--i > 0) + out[len++] = tmp[i] | 0x80; + out[len++] = tmp[0]; + } else + len += i; + } + if (tmp != ftmp) + OPENSSL_free(tmp); + if (bl) + BN_free(bl); + return (len); + err: + if (tmp != ftmp) + OPENSSL_free(tmp); + if (bl) + BN_free(bl); + return (0); +} + +int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a) +{ + return OBJ_obj2txt(buf, buf_len, a, 0); +} + +int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) +{ + char buf[80], *p = buf; + int i; + + if ((a == NULL) || (a->data == NULL)) + return (BIO_write(bp, "NULL", 4)); + i = i2t_ASN1_OBJECT(buf, sizeof(buf), a); + if (i > (int)(sizeof(buf) - 1)) { + p = OPENSSL_malloc(i + 1); + if (!p) + return -1; + i2t_ASN1_OBJECT(p, i + 1, a); + } + if (i <= 0) + return BIO_write(bp, "", 9); + BIO_write(bp, p, i); + if (p != buf) + OPENSSL_free(p); + return (i); +} + +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length) +{ + const unsigned char *p; + long len; + int tag, xclass; + int inf, i; + ASN1_OBJECT *ret = NULL; + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + i = ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != V_ASN1_OBJECT) { + i = ASN1_R_EXPECTING_AN_OBJECT; + goto err; + } + ret = c2i_ASN1_OBJECT(a, &p, len); + if (ret) + *pp = p; + return ret; + err: + ASN1err(ASN1_F_D2I_ASN1_OBJECT, i); + return (NULL); +} + +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long len) +{ + ASN1_OBJECT *ret = NULL; + const unsigned char *p; + unsigned char *data; + int i, length; + + /* + * Sanity check OID encoding. Need at least one content octet. MSB must + * be clear in the last octet. can't have leading 0x80 in subidentifiers, + * see: X.690 8.19.2 + */ + if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || + p[len - 1] & 0x80) { + ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } + /* Now 0 < len <= INT_MAX, so the cast is safe. */ + length = (int)len; + for (i = 0; i < length; i++, p++) { + if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { + ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } + } + + /* + * only the ASN1_OBJECTs from the 'table' will have values for ->sn or + * ->ln + */ + if ((a == NULL) || ((*a) == NULL) || + !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { + if ((ret = ASN1_OBJECT_new()) == NULL) + return (NULL); + } else + ret = (*a); + + p = *pp; + /* detach data from object */ + data = (unsigned char *)ret->data; + ret->data = NULL; + /* once detached we can change it */ + if ((data == NULL) || (ret->length < length)) { + ret->length = 0; + if (data != NULL) + OPENSSL_free(data); + data = (unsigned char *)OPENSSL_malloc(length); + if (data == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; + } + memcpy(data, p, length); + /* reattach data to object, after which it remains const */ + ret->data = data; + ret->length = length; + ret->sn = NULL; + ret->ln = NULL; + /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ + p += length; + + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_C2I_ASN1_OBJECT, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_OBJECT_free(ret); + return (NULL); +} + +ASN1_OBJECT *ASN1_OBJECT_new(void) +{ + ASN1_OBJECT *ret; + + ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); + if (ret == NULL) { + ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->length = 0; + ret->data = NULL; + ret->nid = 0; + ret->sn = NULL; + ret->ln = NULL; + ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; + return (ret); +} + +void ASN1_OBJECT_free(ASN1_OBJECT *a) +{ + if (a == NULL) + return; + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { +#ifndef CONST_STRICT /* disable purely for compile-time strict + * const checking. Doing this on a "real" + * compile will cause memory leaks */ + if (a->sn != NULL) + OPENSSL_free((void *)a->sn); + if (a->ln != NULL) + OPENSSL_free((void *)a->ln); +#endif + a->sn = a->ln = NULL; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { + if (a->data != NULL) + OPENSSL_free((void *)a->data); + a->data = NULL; + a->length = 0; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) + OPENSSL_free(a); +} + +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln) +{ + ASN1_OBJECT o; + + o.sn = sn; + o.ln = ln; + o.data = data; + o.nid = nid; + o.length = len; + o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA; + return (OBJ_dup(&o)); +} + +IMPLEMENT_STACK_OF(ASN1_OBJECT) + +IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT) +/* crypto/asn1/a_octet.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" + +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x) +{ + return M_ASN1_OCTET_STRING_dup(x); +} + +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b) +{ + return M_ASN1_OCTET_STRING_cmp(a, b); +} + +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, + int len) +{ + return M_ASN1_OCTET_STRING_set(x, d, len); +} +/* crypto/asn1/a_print.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" + +int ASN1_PRINTABLE_type(const unsigned char *s, int len) +{ + int c; + int ia5 = 0; + int t61 = 0; + + if (len <= 0) + len = -1; + if (s == NULL) + return (V_ASN1_PRINTABLESTRING); + + while ((*s) && (len-- != 0)) { + c = *(s++); +#ifndef CHARSET_EBCDIC + if (!(((c >= 'a') && (c <= 'z')) || + ((c >= 'A') && (c <= 'Z')) || + (c == ' ') || + ((c >= '0') && (c <= '9')) || + (c == ' ') || (c == '\'') || + (c == '(') || (c == ')') || + (c == '+') || (c == ',') || + (c == '-') || (c == '.') || + (c == '/') || (c == ':') || (c == '=') || (c == '?'))) + ia5 = 1; + if (c & 0x80) + t61 = 1; +#else + if (!isalnum(c) && (c != ' ') && strchr("'()+,-./:=?", c) == NULL) + ia5 = 1; + if (os_toascii[c] & 0x80) + t61 = 1; +#endif + } + if (t61) + return (V_ASN1_T61STRING); + if (ia5) + return (V_ASN1_IA5STRING); + return (V_ASN1_PRINTABLESTRING); +} + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s) +{ + int i; + unsigned char *p; + + if (s->type != V_ASN1_UNIVERSALSTRING) + return (0); + if ((s->length % 4) != 0) + return (0); + p = s->data; + for (i = 0; i < s->length; i += 4) { + if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0')) + break; + else + p += 4; + } + if (i < s->length) + return (0); + p = s->data; + for (i = 3; i < s->length; i += 4) { + *(p++) = s->data[i]; + } + *(p) = '\0'; + s->length /= 4; + s->type = ASN1_PRINTABLE_type(s->data, s->length); + return (1); +} +/* crypto/asn1/a_set.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "asn1_mac.h" + +#ifndef NO_ASN1_OLD + +typedef struct { + unsigned char *pbData; + int cbData; +} MYBLOB; + +/* + * SetBlobCmp This function compares two elements of SET_OF block + */ +static int SetBlobCmp(const void *elem1, const void *elem2) +{ + const MYBLOB *b1 = (const MYBLOB *)elem1; + const MYBLOB *b2 = (const MYBLOB *)elem2; + int r; + + r = memcmp(b1->pbData, b2->pbData, + b1->cbData < b2->cbData ? b1->cbData : b2->cbData); + if (r != 0) + return r; + return b1->cbData - b2->cbData; +} + +/* + * int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) + */ +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, int is_set) +{ + int ret = 0, r; + int i; + unsigned char *p; + unsigned char *pStart, *pTempMem; + MYBLOB *rgSetBlob; + int totSize; + + if (a == NULL) + return (0); + for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--) { + int tmplen = i2d(sk_OPENSSL_BLOCK_value(a, i), NULL); + if (tmplen > INT_MAX - ret) + return -1; + ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL); + } + r = ASN1_object_size(1, ret, ex_tag); + if (pp == NULL || r == -1) + return (r); + + p = *pp; + ASN1_put_object(&p, 1, ret, ex_tag, ex_class); + +/* Modified by gp@nsj.co.jp */ + /* And then again by Ben */ + /* And again by Steve */ + + if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) { + for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) + i2d(sk_OPENSSL_BLOCK_value(a, i), &p); + + *pp = p; + return (r); + } + + pStart = p; /* Catch the beg of Setblobs */ + /* In this array we will store the SET blobs */ + rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB)); + if (rgSetBlob == NULL) { + ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE); + return (0); + } + + for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) { + rgSetBlob[i].pbData = p; /* catch each set encode blob */ + i2d(sk_OPENSSL_BLOCK_value(a, i), &p); + rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this + * SetBlob */ + } + *pp = p; + totSize = p - pStart; /* This is the total size of all set blobs */ + + /* + * Now we have to sort the blobs. I am using a simple algo. *Sort ptrs + * *Copy to temp-mem *Copy from temp-mem to user-mem + */ + qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp); + if (!(pTempMem = OPENSSL_malloc(totSize))) { + ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE); + return (0); + } + +/* Copy to temp mem */ + p = pTempMem; + for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) { + memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData); + p += rgSetBlob[i].cbData; + } + +/* Copy back to user mem*/ + memcpy(pStart, pTempMem, totSize); + OPENSSL_free(pTempMem); + OPENSSL_free(rgSetBlob); + + return (r); +} + +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, + const unsigned char **pp, + long length, d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK), + int ex_tag, int ex_class) +{ + ASN1_const_CTX c; + STACK_OF(OPENSSL_BLOCK) *ret = NULL; + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) { + ASN1err(ASN1_F_D2I_ASN1_SET, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = (*a); + + c.p = *pp; + c.max = (length == 0) ? 0 : (c.p + length); + + c.inf = ASN1_get_object(&c.p, &c.slen, &c.tag, &c.xclass, c.max - c.p); + if (c.inf & 0x80) + goto err; + if (ex_class != c.xclass) { + ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_CLASS); + goto err; + } + if (ex_tag != c.tag) { + ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_TAG); + goto err; + } + if ((c.slen + c.p) > c.max) { + ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_LENGTH_ERROR); + goto err; + } + /* + * check for infinite constructed - it can be as long as the amount of + * data passed to us + */ + if (c.inf == (V_ASN1_CONSTRUCTED + 1)) + c.slen = length + *pp - c.p; + c.max = c.p + c.slen; + + while (c.p < c.max) { + char *s; + + if (M_ASN1_D2I_end_sequence()) + break; + /* + * XXX: This was called with 4 arguments, incorrectly, it seems if + * ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) + */ + if ((s = d2i(NULL, &c.p, c.slen)) == NULL) { + ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_ERROR_PARSING_SET_ELEMENT); + asn1_add_error(*pp, (int)(c.p - *pp)); + goto err; + } + if (!sk_OPENSSL_BLOCK_push(ret, s)) + goto err; + } + if (a != NULL) + (*a) = ret; + *pp = c.p; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) { + if (free_func != NULL) + sk_OPENSSL_BLOCK_pop_free(ret, free_func); + else + sk_OPENSSL_BLOCK_free(ret); + } + return (NULL); +} + +#endif +/* crypto/asn1/a_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +// #include "cryptlib.h" + +#ifndef NO_SYS_TYPES_H +# include +#endif + +// #include "bn.h" +// #include "evp.h" +// #include "x509.h" +// #include "objects.h" +// #include "buffer.h" +// #include "asn1_locl.h" + +#ifndef NO_ASN1_OLD + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, + const EVP_MD *type) +{ + EVP_MD_CTX ctx; + unsigned char *p, *buf_in = NULL, *buf_out = NULL; + int i, inl = 0, outl = 0, outll = 0; + X509_ALGOR *a; + + EVP_MD_CTX_init(&ctx); + for (i = 0; i < 2; i++) { + if (i == 0) + a = algor1; + else + a = algor2; + if (a == NULL) + continue; + if (type->pkey_type == NID_dsaWithSHA1) { + /* + * special case: RFC 2459 tells us to omit 'parameters' with + * id-dsa-with-sha1 + */ + ASN1_TYPE_free(a->parameter); + a->parameter = NULL; + } else if ((a->parameter == NULL) || + (a->parameter->type != V_ASN1_NULL)) { + ASN1_TYPE_free(a->parameter); + if ((a->parameter = ASN1_TYPE_new()) == NULL) + goto err; + a->parameter->type = V_ASN1_NULL; + } + ASN1_OBJECT_free(a->algorithm); + a->algorithm = OBJ_nid2obj(type->pkey_type); + if (a->algorithm == NULL) { + ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE); + goto err; + } + if (a->algorithm->length == 0) { + ASN1err(ASN1_F_ASN1_SIGN, + ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + goto err; + } + } + inl = i2d(data, NULL); + buf_in = (unsigned char *)OPENSSL_malloc((unsigned int)inl); + outll = outl = EVP_PKEY_size(pkey); + buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl); + if ((buf_in == NULL) || (buf_out == NULL)) { + outl = 0; + ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf_in; + + i2d(data, &p); + if (!EVP_SignInit_ex(&ctx, type, NULL) + || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl) + || !EVP_SignFinal(&ctx, (unsigned char *)buf_out, + (unsigned int *)&outl, pkey)) { + outl = 0; + ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB); + goto err; + } + if (signature->data != NULL) + OPENSSL_free(signature->data); + signature->data = buf_out; + buf_out = NULL; + signature->length = outl; + /* + * In the interests of compatibility, I'll make sure that the bit string + * has a 'not-used bits' value of 0 + */ + signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + err: + EVP_MD_CTX_cleanup(&ctx); + if (buf_in != NULL) { + OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); + OPENSSL_free(buf_in); + } + if (buf_out != NULL) { + OPENSSL_cleanse((char *)buf_out, outll); + OPENSSL_free(buf_out); + } + return (outl); +} + +#endif + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, + EVP_PKEY *pkey, const EVP_MD *type) +{ + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) { + EVP_MD_CTX_cleanup(&ctx); + return 0; + } + return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); +} + +int ASN1_item_sign_ctx(const ASN1_ITEM *it, + X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) +{ + const EVP_MD *type; + EVP_PKEY *pkey; + unsigned char *buf_in = NULL, *buf_out = NULL; + size_t inl = 0, outl = 0, outll = 0; + int signid, paramtype; + int rv; + + type = EVP_MD_CTX_md(ctx); + pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + + if (!type || !pkey) { + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + if (pkey->ameth->item_sign) { + rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); + if (rv == 1) + outl = signature->length; + /*- + * Return value meanings: + * <=0: error. + * 1: method does everything. + * 2: carry on as normal. + * 3: ASN1 method sets algorithm identifiers: just sign. + */ + if (rv <= 0) + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); + if (rv <= 1) + goto err; + } else + rv = 2; + + if (rv == 2) { + if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { + if (!pkey->ameth || + !OBJ_find_sigid_by_algs(&signid, + EVP_MD_nid(type), + pkey->ameth->pkey_id)) { + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, + ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; + } + } else + signid = type->pkey_type; + + if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) + paramtype = V_ASN1_NULL; + else + paramtype = V_ASN1_UNDEF; + + if (algor1) + X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); + if (algor2) + X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); + + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + outll = outl = EVP_PKEY_size(pkey); + buf_out = OPENSSL_malloc((unsigned int)outl); + if ((buf_in == NULL) || (buf_out == NULL)) { + outl = 0; + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestSignUpdate(ctx, buf_in, inl) + || !EVP_DigestSignFinal(ctx, buf_out, &outl)) { + outl = 0; + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); + goto err; + } + if (signature->data != NULL) + OPENSSL_free(signature->data); + signature->data = buf_out; + buf_out = NULL; + signature->length = outl; + /* + * In the interests of compatibility, I'll make sure that the bit string + * has a 'not-used bits' value of 0 + */ + signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + err: + EVP_MD_CTX_cleanup(ctx); + if (buf_in != NULL) { + OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); + OPENSSL_free(buf_in); + } + if (buf_out != NULL) { + OPENSSL_cleanse((char *)buf_out, outll); + OPENSSL_free(buf_out); + } + return (outl); +} +/* a_strex.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +#include "crypto.h" +// #include "x509.h" +// #include "asn1.h" + +#include "charmap.h" + +/* + * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name + * printing routines handling multibyte characters, RFC2253 and a host of + * other options. + */ + +#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) + +#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB) + +/* + * Three IO functions for sending data to memory, a BIO and and a FILE + * pointer. + */ +#if 0 /* never used */ +static int send_mem_chars(void *arg, const void *buf, int len) +{ + unsigned char **out = arg; + if (!out) + return 1; + memcpy(*out, buf, len); + *out += len; + return 1; +} +#endif + +static int send_bio_chars(void *arg, const void *buf, int len) +{ + if (!arg) + return 1; + if (BIO_write(arg, buf, len) != len) + return 0; + return 1; +} + +static int send_fp_chars(void *arg, const void *buf, int len) +{ + if (!arg) + return 1; + if (fwrite(buf, 1, len, arg) != (unsigned int)len) + return 0; + return 1; +} + +typedef int char_io (void *arg, const void *buf, int len); + +/* + * This function handles display of strings, one character at a time. It is + * passed an unsigned long for each character because it could come from 2 or + * even 4 byte forms. + */ + +static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, + char_io *io_ch, void *arg) +{ + unsigned char chflgs, chtmp; + char tmphex[HEX_SIZE(long) + 3]; + + if (c > 0xffffffffL) + return -1; + if (c > 0xffff) { + BIO_snprintf(tmphex, sizeof(tmphex), "\\W%08lX", c); + if (!io_ch(arg, tmphex, 10)) + return -1; + return 10; + } + if (c > 0xff) { + BIO_snprintf(tmphex, sizeof(tmphex), "\\U%04lX", c); + if (!io_ch(arg, tmphex, 6)) + return -1; + return 6; + } + chtmp = (unsigned char)c; + if (chtmp > 0x7f) + chflgs = flags & ASN1_STRFLGS_ESC_MSB; + else + chflgs = char_type[chtmp] & flags; + if (chflgs & CHARTYPE_BS_ESC) { + /* If we don't escape with quotes, signal we need quotes */ + if (chflgs & ASN1_STRFLGS_ESC_QUOTE) { + if (do_quotes) + *do_quotes = 1; + if (!io_ch(arg, &chtmp, 1)) + return -1; + return 1; + } + if (!io_ch(arg, "\\", 1)) + return -1; + if (!io_ch(arg, &chtmp, 1)) + return -1; + return 2; + } + if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)) { + BIO_snprintf(tmphex, 11, "\\%02X", chtmp); + if (!io_ch(arg, tmphex, 3)) + return -1; + return 3; + } + /* + * If we get this far and do any escaping at all must escape the escape + * character itself: backslash. + */ + if (chtmp == '\\' && flags & ESC_FLAGS) { + if (!io_ch(arg, "\\\\", 2)) + return -1; + return 2; + } + if (!io_ch(arg, &chtmp, 1)) + return -1; + return 1; +} + +#define BUF_TYPE_WIDTH_MASK 0x7 +#define BUF_TYPE_CONVUTF8 0x8 + +/* + * This function sends each character in a buffer to do_esc_char(). It + * interprets the content formats and converts to or from UTF8 as + * appropriate. + */ + +static int do_buf(unsigned char *buf, int buflen, + int type, unsigned char flags, char *quotes, char_io *io_ch, + void *arg) +{ + int i, outlen, len, charwidth; + unsigned char orflags, *p, *q; + unsigned long c; + p = buf; + q = buf + buflen; + outlen = 0; + charwidth = type & BUF_TYPE_WIDTH_MASK; + + switch (charwidth) { + case 4: + if (buflen & 3) { + ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); + return -1; + } + break; + case 2: + if (buflen & 1) { + ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_BMPSTRING_LENGTH); + return -1; + } + break; + default: + break; + } + + while (p != q) { + if (p == buf && flags & ASN1_STRFLGS_ESC_2253) + orflags = CHARTYPE_FIRST_ESC_2253; + else + orflags = 0; + + switch (charwidth) { + case 4: + c = ((unsigned long)*p++) << 24; + c |= ((unsigned long)*p++) << 16; + c |= ((unsigned long)*p++) << 8; + c |= *p++; + break; + + case 2: + c = ((unsigned long)*p++) << 8; + c |= *p++; + break; + + case 1: + c = *p++; + break; + + case 0: + i = UTF8_getc(p, buflen, &c); + if (i < 0) + return -1; /* Invalid UTF8String */ + buflen -= i; + p += i; + break; + default: + return -1; /* invalid width */ + } + if (p == q && flags & ASN1_STRFLGS_ESC_2253) + orflags = CHARTYPE_LAST_ESC_2253; + if (type & BUF_TYPE_CONVUTF8) { + unsigned char utfbuf[6]; + int utflen; + utflen = UTF8_putc(utfbuf, sizeof(utfbuf), c); + for (i = 0; i < utflen; i++) { + /* + * We don't need to worry about setting orflags correctly + * because if utflen==1 its value will be correct anyway + * otherwise each character will be > 0x7f and so the + * character will never be escaped on first and last. + */ + len = + do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), + quotes, io_ch, arg); + if (len < 0) + return -1; + outlen += len; + } + } else { + len = + do_esc_char(c, (unsigned char)(flags | orflags), quotes, + io_ch, arg); + if (len < 0) + return -1; + outlen += len; + } + } + return outlen; +} + +/* This function hex dumps a buffer of characters */ + +static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, + int buflen) +{ + static const char hexdig[] = "0123456789ABCDEF"; + unsigned char *p, *q; + char hextmp[2]; + if (arg) { + p = buf; + q = buf + buflen; + while (p != q) { + hextmp[0] = hexdig[*p >> 4]; + hextmp[1] = hexdig[*p & 0xf]; + if (!io_ch(arg, hextmp, 2)) + return -1; + p++; + } + } + return buflen << 1; +} + +/* + * "dump" a string. This is done when the type is unknown, or the flags + * request it. We can either dump the content octets or the entire DER + * encoding. This uses the RFC2253 #01234 format. + */ + +static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, + ASN1_STRING *str) +{ + /* + * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to + * readily obtained + */ + ASN1_TYPE t; + unsigned char *der_buf, *p; + int outlen, der_len; + + if (!io_ch(arg, "#", 1)) + return -1; + /* If we don't dump DER encoding just dump content octets */ + if (!(lflags & ASN1_STRFLGS_DUMP_DER)) { + outlen = do_hex_dump(io_ch, arg, str->data, str->length); + if (outlen < 0) + return -1; + return outlen + 1; + } + t.type = str->type; + t.value.ptr = (char *)str; + der_len = i2d_ASN1_TYPE(&t, NULL); + der_buf = OPENSSL_malloc(der_len); + if (!der_buf) + return -1; + p = der_buf; + i2d_ASN1_TYPE(&t, &p); + outlen = do_hex_dump(io_ch, arg, der_buf, der_len); + OPENSSL_free(der_buf); + if (outlen < 0) + return -1; + return outlen + 1; +} + +/* + * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is + * used for non string types otherwise it is the number of bytes per + * character + */ + +static const signed char tag2nbyte[] = { + -1, -1, -1, -1, -1, /* 0-4 */ + -1, -1, -1, -1, -1, /* 5-9 */ + -1, -1, 0, -1, /* 10-13 */ + -1, -1, -1, -1, /* 15-17 */ + 1, 1, 1, /* 18-20 */ + -1, 1, 1, 1, /* 21-24 */ + -1, 1, -1, /* 25-27 */ + 4, -1, 2 /* 28-30 */ +}; + +/* + * This is the main function, print out an ASN1_STRING taking note of various + * escape and display options. Returns number of characters written or -1 if + * an error occurred. + */ + +static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, + ASN1_STRING *str) +{ + int outlen, len; + int type; + char quotes; + unsigned char flags; + quotes = 0; + /* Keep a copy of escape flags */ + flags = (unsigned char)(lflags & ESC_FLAGS); + + type = str->type; + + outlen = 0; + + if (lflags & ASN1_STRFLGS_SHOW_TYPE) { + const char *tagname; + tagname = ASN1_tag2str(type); + outlen += strlen(tagname); + if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) + return -1; + outlen++; + } + + /* Decide what to do with type, either dump content or display it */ + + /* Dump everything */ + if (lflags & ASN1_STRFLGS_DUMP_ALL) + type = -1; + /* Ignore the string type */ + else if (lflags & ASN1_STRFLGS_IGNORE_TYPE) + type = 1; + else { + /* Else determine width based on type */ + if ((type > 0) && (type < 31)) + type = tag2nbyte[type]; + else + type = -1; + if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) + type = 1; + } + + if (type == -1) { + len = do_dump(lflags, io_ch, arg, str); + if (len < 0) + return -1; + outlen += len; + return outlen; + } + + if (lflags & ASN1_STRFLGS_UTF8_CONVERT) { + /* + * Note: if string is UTF8 and we want to convert to UTF8 then we + * just interpret it as 1 byte per character to avoid converting + * twice. + */ + if (!type) + type = 1; + else + type |= BUF_TYPE_CONVUTF8; + } + + len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL); + if (len < 0) + return -1; + outlen += len; + if (quotes) + outlen += 2; + if (!arg) + return outlen; + if (quotes && !io_ch(arg, "\"", 1)) + return -1; + if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0) + return -1; + if (quotes && !io_ch(arg, "\"", 1)) + return -1; + return outlen; +} + +/* Used for line indenting: print 'indent' spaces */ + +static int do_indent(char_io *io_ch, void *arg, int indent) +{ + int i; + for (i = 0; i < indent; i++) + if (!io_ch(arg, " ", 1)) + return 0; + return 1; +} + +#define FN_WIDTH_LN 25 +#define FN_WIDTH_SN 10 + +static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, + int indent, unsigned long flags) +{ + int i, prev = -1, orflags, cnt; + int fn_opt, fn_nid; + ASN1_OBJECT *fn; + ASN1_STRING *val; + X509_NAME_ENTRY *ent; + char objtmp[80]; + const char *objbuf; + int outlen, len; + char *sep_dn, *sep_mv, *sep_eq; + int sep_dn_len, sep_mv_len, sep_eq_len; + if (indent < 0) + indent = 0; + outlen = indent; + if (!do_indent(io_ch, arg, indent)) + return -1; + switch (flags & XN_FLAG_SEP_MASK) { + case XN_FLAG_SEP_MULTILINE: + sep_dn = "\n"; + sep_dn_len = 1; + sep_mv = " + "; + sep_mv_len = 3; + break; + + case XN_FLAG_SEP_COMMA_PLUS: + sep_dn = ","; + sep_dn_len = 1; + sep_mv = "+"; + sep_mv_len = 1; + indent = 0; + break; + + case XN_FLAG_SEP_CPLUS_SPC: + sep_dn = ", "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; + + case XN_FLAG_SEP_SPLUS_SPC: + sep_dn = "; "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; + + default: + return -1; + } + + if (flags & XN_FLAG_SPC_EQ) { + sep_eq = " = "; + sep_eq_len = 3; + } else { + sep_eq = "="; + sep_eq_len = 1; + } + + fn_opt = flags & XN_FLAG_FN_MASK; + + cnt = X509_NAME_entry_count(n); + for (i = 0; i < cnt; i++) { + if (flags & XN_FLAG_DN_REV) + ent = X509_NAME_get_entry(n, cnt - i - 1); + else + ent = X509_NAME_get_entry(n, i); + if (prev != -1) { + if (prev == ent->set) { + if (!io_ch(arg, sep_mv, sep_mv_len)) + return -1; + outlen += sep_mv_len; + } else { + if (!io_ch(arg, sep_dn, sep_dn_len)) + return -1; + outlen += sep_dn_len; + if (!do_indent(io_ch, arg, indent)) + return -1; + outlen += indent; + } + } + prev = ent->set; + fn = X509_NAME_ENTRY_get_object(ent); + val = X509_NAME_ENTRY_get_data(ent); + fn_nid = OBJ_obj2nid(fn); + if (fn_opt != XN_FLAG_FN_NONE) { + int objlen, fld_len; + if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) { + OBJ_obj2txt(objtmp, sizeof(objtmp), fn, 1); + fld_len = 0; /* XXX: what should this be? */ + objbuf = objtmp; + } else { + if (fn_opt == XN_FLAG_FN_SN) { + fld_len = FN_WIDTH_SN; + objbuf = OBJ_nid2sn(fn_nid); + } else if (fn_opt == XN_FLAG_FN_LN) { + fld_len = FN_WIDTH_LN; + objbuf = OBJ_nid2ln(fn_nid); + } else { + fld_len = 0; /* XXX: what should this be? */ + objbuf = ""; + } + } + objlen = strlen(objbuf); + if (!io_ch(arg, objbuf, objlen)) + return -1; + if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) { + if (!do_indent(io_ch, arg, fld_len - objlen)) + return -1; + outlen += fld_len - objlen; + } + if (!io_ch(arg, sep_eq, sep_eq_len)) + return -1; + outlen += objlen + sep_eq_len; + } + /* + * If the field name is unknown then fix up the DER dump flag. We + * might want to limit this further so it will DER dump on anything + * other than a few 'standard' fields. + */ + if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) + orflags = ASN1_STRFLGS_DUMP_ALL; + else + orflags = 0; + + len = do_print_ex(io_ch, arg, flags | orflags, val); + if (len < 0) + return -1; + outlen += len; + } + return outlen; +} + +/* Wrappers round the main functions */ + +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, + unsigned long flags) +{ + if (flags == XN_FLAG_COMPAT) + return X509_NAME_print(out, nm, indent); + return do_name_ex(send_bio_chars, out, nm, indent, flags); +} + +#ifndef OPENSSL_NO_FP_API +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, + unsigned long flags) +{ + if (flags == XN_FLAG_COMPAT) { + BIO *btmp; + int ret; + btmp = BIO_new_fp(fp, BIO_NOCLOSE); + if (!btmp) + return -1; + ret = X509_NAME_print(btmp, nm, indent); + BIO_free(btmp); + return ret; + } + return do_name_ex(send_fp_chars, fp, nm, indent, flags); +} +#endif + +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags) +{ + return do_print_ex(send_bio_chars, out, flags, str); +} + +#ifndef OPENSSL_NO_FP_API +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags) +{ + return do_print_ex(send_fp_chars, fp, flags, str); +} +#endif + +/* + * Utility function: convert any string type to UTF8, returns number of bytes + * in output string or a negative error code + */ + +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) +{ + ASN1_STRING stmp, *str = &stmp; + int mbflag, type, ret; + if (!in) + return -1; + type = in->type; + if ((type < 0) || (type > 30)) + return -1; + mbflag = tag2nbyte[type]; + if (mbflag == -1) + return -1; + mbflag |= MBSTRING_FLAG; + stmp.data = NULL; + stmp.length = 0; + stmp.flags = 0; + ret = + ASN1_mbstring_copy(&str, in->data, in->length, mbflag, + B_ASN1_UTF8STRING); + if (ret < 0) + return ret; + *out = stmp.data; + return stmp.length; +} +/* a_strnid.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "objects.h" + +static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; +static void st_free(ASN1_STRING_TABLE *tbl); +static int sk_table_cmp(const ASN1_STRING_TABLE *const *a, + const ASN1_STRING_TABLE *const *b); + +/* + * This is the global mask for the mbstring functions: this is use to mask + * out certain types (such as BMPString and UTF8String) because certain + * software (e.g. Netscape) has problems with them. + */ + +static unsigned long global_mask = B_ASN1_UTF8STRING; + +void ASN1_STRING_set_default_mask(unsigned long mask) +{ + global_mask = mask; +} + +unsigned long ASN1_STRING_get_default_mask(void) +{ + return global_mask; +} + +/*- + * This function sets the default to various "flavours" of configuration. + * based on an ASCII string. Currently this is: + * MASK:XXXX : a numerical mask value. + * nobmp : Don't use BMPStrings (just Printable, T61). + * pkix : PKIX recommendation in RFC2459. + * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004). + * default: the default value, Printable, T61, BMP. + */ + +int ASN1_STRING_set_default_mask_asc(const char *p) +{ + unsigned long mask; + char *end; + if (!strncmp(p, "MASK:", 5)) { + if (!p[5]) + return 0; + mask = strtoul(p + 5, &end, 0); + if (*end) + return 0; + } else if (!strcmp(p, "nombstr")) + mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING)); + else if (!strcmp(p, "pkix")) + mask = ~((unsigned long)B_ASN1_T61STRING); + else if (!strcmp(p, "utf8only")) + mask = B_ASN1_UTF8STRING; + else if (!strcmp(p, "default")) + mask = 0xFFFFFFFFL; + else + return 0; + ASN1_STRING_set_default_mask(mask); + return 1; +} + +/* + * The following function generates an ASN1_STRING based on limits in a + * table. Frequently the types and length of an ASN1_STRING are restricted by + * a corresponding OID. For example certificates and certificate requests. + */ + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid) +{ + ASN1_STRING_TABLE *tbl; + ASN1_STRING *str = NULL; + unsigned long mask; + int ret; + if (!out) + out = &str; + tbl = ASN1_STRING_TABLE_get(nid); + if (tbl) { + mask = tbl->mask; + if (!(tbl->flags & STABLE_NO_MASK)) + mask &= global_mask; + ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask, + tbl->minsize, tbl->maxsize); + } else + ret = + ASN1_mbstring_copy(out, in, inlen, inform, + DIRSTRING_TYPE & global_mask); + if (ret <= 0) + return NULL; + return *out; +} + +/* + * Now the tables and helper functions for the string table: + */ + +/* size limits: this stuff is taken straight from RFC3280 */ + +#define ub_name 32768 +#define ub_common_name 64 +#define ub_locality_name 128 +#define ub_state_name 128 +#define ub_organization_name 64 +#define ub_organization_unit_name 64 +#define ub_title 64 +#define ub_email_address 128 +#define ub_serial_number 64 + +/* This table must be kept in NID order */ + +static const ASN1_STRING_TABLE tbl_standard[] = { + {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, + {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, + {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, + {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0}, + {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0}, + {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, + 0}, + {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, + STABLE_NO_MASK}, + {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0}, + {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0}, + {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0}, + {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, + STABLE_NO_MASK}, + {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}, + {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, + {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK}, + {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}, + {NID_jurisdictionCountryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK} +}; + +static int sk_table_cmp(const ASN1_STRING_TABLE *const *a, + const ASN1_STRING_TABLE *const *b) +{ + return (*a)->nid - (*b)->nid; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table); + +static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b) +{ + return a->nid - b->nid; +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table); + +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) +{ + int idx; + ASN1_STRING_TABLE *ttmp; + ASN1_STRING_TABLE fnd; + fnd.nid = nid; + ttmp = OBJ_bsearch_table(&fnd, tbl_standard, + sizeof(tbl_standard) / + sizeof(ASN1_STRING_TABLE)); + if (ttmp) + return ttmp; + if (!stable) + return NULL; + idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); + if (idx < 0) + return NULL; + return sk_ASN1_STRING_TABLE_value(stable, idx); +} + +int ASN1_STRING_TABLE_add(int nid, + long minsize, long maxsize, unsigned long mask, + unsigned long flags) +{ + ASN1_STRING_TABLE *tmp; + char new_nid = 0; + flags &= ~STABLE_FLAGS_MALLOC; + if (!stable) + stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp); + if (!stable) { + ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!(tmp = ASN1_STRING_TABLE_get(nid))) { + tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)); + if (!tmp) { + ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + tmp->flags = flags | STABLE_FLAGS_MALLOC; + tmp->nid = nid; + tmp->minsize = tmp->maxsize = -1; + new_nid = 1; + } else + tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags; + if (minsize != -1) + tmp->minsize = minsize; + if (maxsize != -1) + tmp->maxsize = maxsize; + tmp->mask = mask; + if (new_nid) + sk_ASN1_STRING_TABLE_push(stable, tmp); + return 1; +} + +void ASN1_STRING_TABLE_cleanup(void) +{ + STACK_OF(ASN1_STRING_TABLE) *tmp; + tmp = stable; + if (!tmp) + return; + stable = NULL; + sk_ASN1_STRING_TABLE_pop_free(tmp, st_free); +} + +static void st_free(ASN1_STRING_TABLE *tbl) +{ + if (tbl->flags & STABLE_FLAGS_MALLOC) + OPENSSL_free(tbl); +} + + +IMPLEMENT_STACK_OF(ASN1_STRING_TABLE) + +#ifdef STRING_TABLE_TEST + +main() +{ + ASN1_STRING_TABLE *tmp; + int i, last_nid = -1; + + for (tmp = tbl_standard, i = 0; + i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) { + if (tmp->nid < last_nid) { + last_nid = 0; + break; + } + last_nid = tmp->nid; + } + + if (last_nid != 0) { + printf("Table order OK\n"); + exit(0); + } + + for (tmp = tbl_standard, i = 0; + i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) + printf("Index %d, NID %d, Name=%s\n", i, tmp->nid, + OBJ_nid2ln(tmp->nid)); + +} + +#endif +/* crypto/asn1/a_time.c */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/*- + * This is an implementation of the ASN1 Time structure which is: + * Time ::= CHOICE { + * utcTime UTCTime, + * generalTime GeneralizedTime } + * written by Steve Henson. + */ + +#include +#include +// #include "cryptlib.h" +// #include "o_time.h" +// #include "asn1t.h" +// #include "asn1_locl.h" + +IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) + +IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME) + +#if 0 +int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp) +{ +# ifdef CHARSET_EBCDIC + /* KLUDGE! We convert to ascii before writing DER */ + char tmp[24]; + ASN1_STRING tmpstr; + + if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) { + int len; + + tmpstr = *(ASN1_STRING *)a; + len = tmpstr.length; + ebcdic2ascii(tmp, tmpstr.data, + (len >= sizeof(tmp)) ? sizeof(tmp) : len); + tmpstr.data = tmp; + a = (ASN1_GENERALIZEDTIME *)&tmpstr; + } +# endif + if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) + return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, + a->type, V_ASN1_UNIVERSAL)); + ASN1err(ASN1_F_I2D_ASN1_TIME, ASN1_R_EXPECTING_A_TIME); + return -1; +} +#endif + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) +{ + return ASN1_TIME_adj(s, t, 0, 0); +} + +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec) +{ + struct tm *ts; + struct tm data; + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) { + ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME); + return NULL; + } + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } + if ((ts->tm_year >= 50) && (ts->tm_year < 150)) + return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); + return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); +} + +int ASN1_TIME_check(ASN1_TIME *t) +{ + if (t->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_check(t); + else if (t->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_check(t); + return 0; +} + +/* Convert an ASN1_TIME structure to GeneralizedTime */ +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out) +{ + ASN1_GENERALIZEDTIME *ret = NULL; + char *str; + int newlen; + + if (!ASN1_TIME_check(t)) + return NULL; + + if (!out || !*out) { + if (!(ret = ASN1_GENERALIZEDTIME_new())) + goto err; + } else { + ret = *out; + } + + /* If already GeneralizedTime just copy across */ + if (t->type == V_ASN1_GENERALIZEDTIME) { + if (!ASN1_STRING_set(ret, t->data, t->length)) + goto err; + goto done; + } + + /* grow the string */ + if (!ASN1_STRING_set(ret, NULL, t->length + 2)) + goto err; + /* ASN1_STRING_set() allocated 'len + 1' bytes. */ + newlen = t->length + 2 + 1; + str = (char *)ret->data; + /* Work out the century and prepend */ + if (t->data[0] >= '5') + BUF_strlcpy(str, "19", newlen); + else + BUF_strlcpy(str, "20", newlen); + + BUF_strlcat(str, (char *)t->data, newlen); + + done: + if (out != NULL && *out == NULL) + *out = ret; + return ret; + + err: + if (out == NULL || *out != ret) + ASN1_GENERALIZEDTIME_free(ret); + return NULL; +} + + +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) +{ + ASN1_TIME t; + + t.length = strlen(str); + t.data = (unsigned char *)str; + t.flags = 0; + + t.type = V_ASN1_UTCTIME; + + if (!ASN1_TIME_check(&t)) { + t.type = V_ASN1_GENERALIZEDTIME; + if (!ASN1_TIME_check(&t)) + return 0; + } + + if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) + return 0; + + return 1; +} + +static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t) +{ + if (t == NULL) { + time_t now_t; + time(&now_t); + if (OPENSSL_gmtime(&now_t, tm)) + return 1; + return 0; + } + + if (t->type == V_ASN1_UTCTIME) + return asn1_utctime_to_tm(tm, t); + else if (t->type == V_ASN1_GENERALIZEDTIME) + return asn1_generalizedtime_to_tm(tm, t); + + return 0; +} + +int ASN1_TIME_diff(int *pday, int *psec, + const ASN1_TIME *from, const ASN1_TIME *to) +{ + struct tm tm_from, tm_to; + if (!asn1_time_to_tm(&tm_from, from)) + return 0; + if (!asn1_time_to_tm(&tm_to, to)) + return 0; + return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to); +} +/* crypto/asn1/a_type.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "objects.h" + +int ASN1_TYPE_get(ASN1_TYPE *a) +{ + if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL)) + return (a->type); + else + return (0); +} + +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) +{ + if (a->value.ptr != NULL) { + ASN1_TYPE **tmp_a = &a; + ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL); + } + a->type = type; + if (type == V_ASN1_BOOLEAN) + a->value.boolean = value ? 0xff : 0; + else + a->value.ptr = value; +} + +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) +{ + if (!value || (type == V_ASN1_BOOLEAN)) { + void *p = (void *)value; + ASN1_TYPE_set(a, type, p); + } else if (type == V_ASN1_OBJECT) { + ASN1_OBJECT *odup; + odup = OBJ_dup(value); + if (!odup) + return 0; + ASN1_TYPE_set(a, type, odup); + } else { + ASN1_STRING *sdup; + sdup = ASN1_STRING_dup(value); + if (!sdup) + return 0; + ASN1_TYPE_set(a, type, sdup); + } + return 1; +} + +IMPLEMENT_STACK_OF(ASN1_TYPE) + +IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) + +/* Returns 0 if they are equal, != 0 otherwise. */ +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) +{ + int result = -1; + + if (!a || !b || a->type != b->type) + return -1; + + switch (a->type) { + case V_ASN1_OBJECT: + result = OBJ_cmp(a->value.object, b->value.object); + break; + case V_ASN1_BOOLEAN: + result = a->value.boolean - b->value.boolean; + break; + case V_ASN1_NULL: + result = 0; /* They do not have content. */ + break; + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + case V_ASN1_BIT_STRING: + case V_ASN1_OCTET_STRING: + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_OTHER: + default: + result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr, + (ASN1_STRING *)b->value.ptr); + break; + } + + return result; +} +/* crypto/asn1/a_utctm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "o_time.h" +// #include "asn1.h" +// #include "asn1_locl.h" + +#if 0 +int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp) +{ +# ifndef CHARSET_EBCDIC + return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, + V_ASN1_UTCTIME, V_ASN1_UNIVERSAL)); +# else + /* KLUDGE! We convert to ascii before writing DER */ + int len; + char tmp[24]; + ASN1_STRING x = *(ASN1_STRING *)a; + + len = x.length; + ebcdic2ascii(tmp, x.data, (len >= sizeof(tmp)) ? sizeof(tmp) : len); + x.data = tmp; + return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME, V_ASN1_UNIVERSAL); +# endif +} + +ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp, + long length) +{ + ASN1_UTCTIME *ret = NULL; + + ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length, + V_ASN1_UTCTIME, V_ASN1_UNIVERSAL); + if (ret == NULL) { + ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ERR_R_NESTED_ASN1_ERROR); + return (NULL); + } +# ifdef CHARSET_EBCDIC + ascii2ebcdic(ret->data, ret->data, ret->length); +# endif + if (!ASN1_UTCTIME_check(ret)) { + ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ASN1_R_INVALID_TIME_FORMAT); + goto err; + } + + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_UTCTIME_free(ret); + return (NULL); +} + +#endif + +int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) +{ + static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; + static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 }; + char *a; + int n, i, l, o; + + if (d->type != V_ASN1_UTCTIME) + return (0); + l = d->length; + a = (char *)d->data; + o = 0; + + if (l < 11) + goto err; + for (i = 0; i < 6; i++) { + if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { + i++; + if (tm) + tm->tm_sec = 0; + break; + } + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + if (++o > l) + goto err; + + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if (++o > l) + goto err; + + if ((n < min[i]) || (n > max[i])) + goto err; + if (tm) { + switch (i) { + case 0: + tm->tm_year = n < 50 ? n + 100 : n; + break; + case 1: + tm->tm_mon = n - 1; + break; + case 2: + tm->tm_mday = n; + break; + case 3: + tm->tm_hour = n; + break; + case 4: + tm->tm_min = n; + break; + case 5: + tm->tm_sec = n; + break; + } + } + } + if (a[o] == 'Z') + o++; + else if ((a[o] == '+') || (a[o] == '-')) { + int offsign = a[o] == '-' ? 1 : -1, offset = 0; + o++; + if (o + 4 > l) + goto err; + for (i = 6; i < 8; i++) { + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + o++; + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if ((n < min[i]) || (n > max[i])) + goto err; + if (tm) { + if (i == 6) + offset = n * 3600; + else if (i == 7) + offset += n * 60; + } + o++; + } + if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) + return 0; + } + return o == l; + err: + return 0; +} + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) +{ + return asn1_utctime_to_tm(NULL, d); +} + +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) +{ + ASN1_UTCTIME t; + + t.type = V_ASN1_UTCTIME; + t.length = strlen(str); + t.data = (unsigned char *)str; + if (ASN1_UTCTIME_check(&t)) { + if (s != NULL) { + if (!ASN1_STRING_set((ASN1_STRING *)s, + (unsigned char *)str, t.length)) + return 0; + s->type = V_ASN1_UTCTIME; + } + return (1); + } else + return (0); +} + +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) +{ + return ASN1_UTCTIME_adj(s, t, 0, 0); +} + +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec) +{ + char *p; + struct tm *ts; + struct tm data; + size_t len = 20; + int free_s = 0; + + if (s == NULL) { + free_s = 1; + s = M_ASN1_UTCTIME_new(); + } + if (s == NULL) + goto err; + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) + goto err; + + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + goto err; + } + + if ((ts->tm_year < 50) || (ts->tm_year >= 150)) + goto err; + + p = (char *)s->data; + if ((p == NULL) || ((size_t)s->length < len)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE); + goto err; + } + if (s->data != NULL) + OPENSSL_free(s->data); + s->data = (unsigned char *)p; + } + + BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100, + ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, + ts->tm_sec); + s->length = strlen(p); + s->type = V_ASN1_UTCTIME; +#ifdef CHARSET_EBCDIC_not + ebcdic2ascii(s->data, s->data, s->length); +#endif + return (s); + err: + if (free_s && s) + M_ASN1_UTCTIME_free(s); + return NULL; +} + +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) +{ + struct tm stm, ttm; + int day, sec; + + if (!asn1_utctime_to_tm(&stm, s)) + return -2; + + if (!OPENSSL_gmtime(&t, &ttm)) + return -2; + + if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm)) + return -2; + + if (day > 0) + return 1; + if (day < 0) + return -1; + if (sec > 0) + return 1; + if (sec < 0) + return -1; + return 0; +} + +#if 0 +time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s) +{ + struct tm tm; + int offset; + + memset(&tm, '\0', sizeof(tm)); + +# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0') + tm.tm_year = g2(s->data); + if (tm.tm_year < 50) + tm.tm_year += 100; + tm.tm_mon = g2(s->data + 2) - 1; + tm.tm_mday = g2(s->data + 4); + tm.tm_hour = g2(s->data + 6); + tm.tm_min = g2(s->data + 8); + tm.tm_sec = g2(s->data + 10); + if (s->data[12] == 'Z') + offset = 0; + else { + offset = g2(s->data + 13) * 60 + g2(s->data + 15); + if (s->data[12] == '-') + offset = -offset; + } +# undef g2 + + /* + * FIXME: mktime assumes the current timezone + * instead of UTC, and unless we rewrite OpenSSL + * in Lisp we cannot locally change the timezone + * without possibly interfering with other parts + * of the program. timegm, which uses UTC, is + * non-standard. + * Also time_t is inappropriate for general + * UTC times because it may a 32 bit type. + */ + return mktime(&tm) - offset * 60; +} +#endif +/* crypto/asn1/a_utf8.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" + +/* UTF8 utilities */ + +/*- + * This parses a UTF8 string one character at a time. It is passed a pointer + * to the string and the length of the string. It sets 'value' to the value of + * the current character. It returns the number of characters read or a + * negative error code: + * -1 = string too short + * -2 = illegal character + * -3 = subsequent characters not of the form 10xxxxxx + * -4 = character encoded incorrectly (not minimal length). + */ + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val) +{ + const unsigned char *p; + unsigned long value; + int ret; + if (len <= 0) + return 0; + p = str; + + /* Check syntax and work out the encoded value (if correct) */ + if ((*p & 0x80) == 0) { + value = *p++ & 0x7f; + ret = 1; + } else if ((*p & 0xe0) == 0xc0) { + if (len < 2) + return -1; + if ((p[1] & 0xc0) != 0x80) + return -3; + value = (*p++ & 0x1f) << 6; + value |= *p++ & 0x3f; + if (value < 0x80) + return -4; + ret = 2; + } else if ((*p & 0xf0) == 0xe0) { + if (len < 3) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80)) + return -3; + value = (*p++ & 0xf) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x800) + return -4; + ret = 3; + } else if ((*p & 0xf8) == 0xf0) { + if (len < 4) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80)) + return -3; + value = ((unsigned long)(*p++ & 0x7)) << 18; + value |= (*p++ & 0x3f) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x10000) + return -4; + ret = 4; + } else if ((*p & 0xfc) == 0xf8) { + if (len < 5) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80) + || ((p[4] & 0xc0) != 0x80)) + return -3; + value = ((unsigned long)(*p++ & 0x3)) << 24; + value |= ((unsigned long)(*p++ & 0x3f)) << 18; + value |= ((unsigned long)(*p++ & 0x3f)) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x200000) + return -4; + ret = 5; + } else if ((*p & 0xfe) == 0xfc) { + if (len < 6) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80) + || ((p[4] & 0xc0) != 0x80) + || ((p[5] & 0xc0) != 0x80)) + return -3; + value = ((unsigned long)(*p++ & 0x1)) << 30; + value |= ((unsigned long)(*p++ & 0x3f)) << 24; + value |= ((unsigned long)(*p++ & 0x3f)) << 18; + value |= ((unsigned long)(*p++ & 0x3f)) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x4000000) + return -4; + ret = 6; + } else + return -2; + *val = value; + return ret; +} + +/* + * This takes a character 'value' and writes the UTF8 encoded value in 'str' + * where 'str' is a buffer containing 'len' characters. Returns the number of + * characters written or -1 if 'len' is too small. 'str' can be set to NULL + * in which case it just returns the number of characters. It will need at + * most 6 characters. + */ + +int UTF8_putc(unsigned char *str, int len, unsigned long value) +{ + if (!str) + len = 6; /* Maximum we will need */ + else if (len <= 0) + return -1; + if (value < 0x80) { + if (str) + *str = (unsigned char)value; + return 1; + } + if (value < 0x800) { + if (len < 2) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 2; + } + if (value < 0x10000) { + if (len < 3) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 3; + } + if (value < 0x200000) { + if (len < 4) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 4; + } + if (value < 0x4000000) { + if (len < 5) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8); + *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 5; + } + if (len < 6) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc); + *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 6; +} +/* crypto/asn1/a_verify.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +// #include "cryptlib.h" +// #include "asn1_locl.h" + +#ifndef NO_SYS_TYPES_H +# include +#endif + +// #include "bn.h" +// #include "x509.h" +// #include "objects.h" +// #include "buffer.h" +// #include "evp.h" + +#ifndef NO_ASN1_OLD + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey) +{ + EVP_MD_CTX ctx; + const EVP_MD *type; + unsigned char *p, *buf_in = NULL; + int ret = -1, i, inl; + + EVP_MD_CTX_init(&ctx); + i = OBJ_obj2nid(a->algorithm); + type = EVP_get_digestbyname(OBJ_nid2sn(i)); + if (type == NULL) { + ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + goto err; + } + + if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { + ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + goto err; + } + + inl = i2d(data, NULL); + buf_in = OPENSSL_malloc((unsigned int)inl); + if (buf_in == NULL) { + ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf_in; + + i2d(data, &p); + if (!EVP_VerifyInit_ex(&ctx, type, NULL) + || !EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl)) { + ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + + OPENSSL_cleanse(buf_in, (unsigned int)inl); + OPENSSL_free(buf_in); + + if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data, + (unsigned int)signature->length, pkey) <= 0) { + ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + /* + * we don't need to zero the 'ctx' because we just checked public + * information + */ + /* memset(&ctx,0,sizeof(ctx)); */ + ret = 1; + err: + EVP_MD_CTX_cleanup(&ctx); + return (ret); +} + +#endif + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) +{ + EVP_MD_CTX ctx; + unsigned char *buf_in = NULL; + int ret = -1, inl; + + int mdnid, pknid; + + if (!pkey) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + return -1; + } + + EVP_MD_CTX_init(&ctx); + + /* Convert signature OID into digest and public key OIDs */ + if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + goto err; + } + if (mdnid == NID_undef) { + if (!pkey->ameth || !pkey->ameth->item_verify) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, + ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + goto err; + } + ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey); + /* + * Return value of 2 means carry on, anything else means we exit + * straight away: either a fatal error of the underlying verification + * routine handles all verification. + */ + if (ret != 2) + goto err; + ret = -1; + } else { + const EVP_MD *type; + type = EVP_get_digestbynid(mdnid); + if (type == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, + ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + goto err; + } + + /* Check public key OID matches public key type */ + if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE); + goto err; + } + + if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + + if (buf_in == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + + OPENSSL_cleanse(buf_in, (unsigned int)inl); + OPENSSL_free(buf_in); + + if (EVP_DigestVerifyFinal(&ctx, signature->data, + (size_t)signature->length) <= 0) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + /* + * we don't need to zero the 'ctx' because we just checked public + * information + */ + /* memset(&ctx,0,sizeof(ctx)); */ + ret = 1; + err: + EVP_MD_CTX_cleanup(&ctx); + return (ret); +} diff --git a/Sources/COpenSSL/aep.h b/Sources/COpenSSL/aep.h new file mode 100644 index 00000000..04ab87eb --- /dev/null +++ b/Sources/COpenSSL/aep.h @@ -0,0 +1,235 @@ +/* + * This header declares the necessary definitions for using the + * exponentiation acceleration capabilities, and rnd number generation of the + * AEP card. + */ + +/* + * + * Some AEP defines + * + */ + +/* + * Successful return value + */ +#define AEP_R_OK 0x00000000 + +/* + * Miscelleanous unsuccessful return value + */ +#define AEP_R_GENERAL_ERROR 0x10000001 + +/* + * Insufficient host memory + */ +#define AEP_R_HOST_MEMORY 0x10000002 + +#define AEP_R_FUNCTION_FAILED 0x10000006 + +/* + * Invalid arguments in function call + */ +#define AEP_R_ARGUMENTS_BAD 0x10020000 + +#define AEP_R_NO_TARGET_RESOURCES 0x10030000 + +/* + * Error occuring on socket operation + */ +#define AEP_R_SOCKERROR 0x10000010 + +/* + * Socket has been closed from the other end + */ +#define AEP_R_SOCKEOF 0x10000011 + +/* + * Invalid handles + */ +#define AEP_R_CONNECTION_HANDLE_INVALID 0x100000B3 + +#define AEP_R_TRANSACTION_HANDLE_INVALID 0x10040000 + +/* + * Transaction has not yet returned from accelerator + */ +#define AEP_R_TRANSACTION_NOT_READY 0x00010000 + +/* + * There is already a thread waiting on this transaction + */ +#define AEP_R_TRANSACTION_CLAIMED 0x10050000 + +/* + * The transaction timed out + */ +#define AEP_R_TIMED_OUT 0x10060000 + +#define AEP_R_FXN_NOT_IMPLEMENTED 0x10070000 + +#define AEP_R_TARGET_ERROR 0x10080000 + +/* + * Error in the AEP daemon process + */ +#define AEP_R_DAEMON_ERROR 0x10090000 + +/* + * Invalid ctx id + */ +#define AEP_R_INVALID_CTX_ID 0x10009000 + +#define AEP_R_NO_KEY_MANAGER 0x1000a000 + +/* + * Error obtaining a mutex + */ +#define AEP_R_MUTEX_BAD 0x000001A0 + +/* + * Fxn call before AEP_Initialise ot after AEP_Finialise + */ +#define AEP_R_AEPAPI_NOT_INITIALIZED 0x10000190 + +/* + * AEP_Initialise has already been called + */ +#define AEP_R_AEPAPI_ALREADY_INITIALIZED 0x10000191 + +/* + * Maximum number of connections to daemon reached + */ +#define AEP_R_NO_MORE_CONNECTION_HNDLS 0x10000200 + +/* + * + * Some AEP Type definitions + * + */ + +/* an unsigned 8-bit value */ +typedef unsigned char AEP_U8; + +/* an unsigned 8-bit character */ +typedef char AEP_CHAR; + +/* a BYTE-sized Boolean flag */ +typedef AEP_U8 AEP_BBOOL; + +/* + * Unsigned value, at least 16 bits long + */ +typedef unsigned short AEP_U16; + +/* an unsigned value, at least 32 bits long */ +#ifdef SIXTY_FOUR_BIT_LONG +typedef unsigned int AEP_U32; +#else +typedef unsigned long AEP_U32; +#endif + +#ifdef SIXTY_FOUR_BIT_LONG +typedef unsigned long AEP_U64; +#else +typedef struct { + unsigned long l1, l2; +} AEP_U64; +#endif + +/* at least 32 bits; each bit is a Boolean flag */ +typedef AEP_U32 AEP_FLAGS; + +typedef AEP_U8 *AEP_U8_PTR; +typedef AEP_CHAR *AEP_CHAR_PTR; +typedef AEP_U32 *AEP_U32_PTR; +typedef AEP_U64 *AEP_U64_PTR; +typedef void *AEP_VOID_PTR; + +/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */ +typedef AEP_VOID_PTR *AEP_VOID_PTR_PTR; + +/* + * Used to identify an AEP connection handle + */ +typedef AEP_U32 AEP_CONNECTION_HNDL; + +/* + * Pointer to an AEP connection handle + */ +typedef AEP_CONNECTION_HNDL *AEP_CONNECTION_HNDL_PTR; + +/* + * Used by an application (in conjunction with the apps process id) to + * identify an individual transaction + */ +typedef AEP_U32 AEP_TRANSACTION_ID; + +/* + * Pointer to an applications transaction identifier + */ +typedef AEP_TRANSACTION_ID *AEP_TRANSACTION_ID_PTR; + +/* + * Return value type + */ +typedef AEP_U32 AEP_RV; + +#define MAX_PROCESS_CONNECTIONS 256 + +#define RAND_BLK_SIZE 1024 + +typedef enum { + NotConnected = 0, + Connected = 1, + InUse = 2 +} AEP_CONNECTION_STATE; + +typedef struct AEP_CONNECTION_ENTRY { + AEP_CONNECTION_STATE conn_state; + AEP_CONNECTION_HNDL conn_hndl; +} AEP_CONNECTION_ENTRY; + +typedef AEP_RV t_AEP_OpenConnection(AEP_CONNECTION_HNDL_PTR phConnection); +typedef AEP_RV t_AEP_CloseConnection(AEP_CONNECTION_HNDL hConnection); + +typedef AEP_RV t_AEP_ModExp(AEP_CONNECTION_HNDL hConnection, + AEP_VOID_PTR pA, AEP_VOID_PTR pP, + AEP_VOID_PTR pN, + AEP_VOID_PTR pResult, + AEP_TRANSACTION_ID *pidTransID); + +typedef AEP_RV t_AEP_ModExpCrt(AEP_CONNECTION_HNDL hConnection, + AEP_VOID_PTR pA, AEP_VOID_PTR pP, + AEP_VOID_PTR pQ, + AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1, + AEP_VOID_PTR pIqmp, + AEP_VOID_PTR pResult, + AEP_TRANSACTION_ID *pidTransID); + +#ifdef AEPRAND +typedef AEP_RV t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection, + AEP_U32 Len, + AEP_U32 Type, + AEP_VOID_PTR pResult, + AEP_TRANSACTION_ID *pidTransID); +#endif + +typedef AEP_RV t_AEP_Initialize(AEP_VOID_PTR pInitArgs); +typedef AEP_RV t_AEP_Finalize(void); +typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc) + (AEP_VOID_PTR ArbBigNum, + AEP_U32 *BigNumSize), + AEP_RV (*MakeAEPBigNumFunc) (AEP_VOID_PTR + ArbBigNum, + AEP_U32 + BigNumSize, + unsigned char + *AEP_BigNum), + AEP_RV (*ConverAEPBigNumFunc) (void + *ArbBigNum, + AEP_U32 + BigNumSize, + unsigned + char + *AEP_BigNum)); diff --git a/Sources/COpenSSL/aes.h b/Sources/COpenSSL/aes.h new file mode 100644 index 00000000..f7bcedc8 --- /dev/null +++ b/Sources/COpenSSL/aes.h @@ -0,0 +1,149 @@ +/* crypto/aes/aes.h */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_AES_H +# define HEADER_AES_H + +# include "opensslconf.h" + +# ifdef OPENSSL_NO_AES +# error AES is disabled. +# endif + +# include + +# define AES_ENCRYPT 1 +# define AES_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ +# define AES_MAXNR 14 +# define AES_BLOCK_SIZE 16 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ +struct aes_key_st { +# ifdef AES_LONG + unsigned long rd_key[4 * (AES_MAXNR + 1)]; +# else + unsigned int rd_key[4 * (AES_MAXNR + 1)]; +# endif + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +const char *AES_options(void); + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num); +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], + unsigned int *num); +/* NB: the IV is _two_ blocks long */ +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +/* NB: the IV is _four_ blocks long */ +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + const AES_KEY *key2, const unsigned char *ivec, + const int enc); + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); + + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_AES_H */ diff --git a/Sources/COpenSSL/aes_.c b/Sources/COpenSSL/aes_.c new file mode 100644 index 00000000..bd0850f7 --- /dev/null +++ b/Sources/COpenSSL/aes_.c @@ -0,0 +1,2192 @@ +/* crypto/aes/aes_cbc.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "aes.h" +#include "modes.h" + +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec, const int enc) +{ + + if (enc) + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, + (block128_f) AES_encrypt); + else + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, + (block128_f) AES_decrypt); +} +/* crypto/aes/aes_cfb.c */ +/* ==================================================================== + * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "aes.h" +// #include "modes.h" + +/* + * The input and output encrypted as though 128bit cfb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ + +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) AES_encrypt); +} + +/* N.B. This expects the input to be packed, MS bit first */ +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) AES_encrypt); +} + +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) AES_encrypt); +} +/* crypto/aes/aes_core.c */ +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Note: rewritten a little bit to provide error control and an OpenSSL- + compatible API */ + +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#include +// #include "aes.h" +#include "aes_locl.h" + +#ifndef AES_ASM +/*- +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01]; +*/ + +static const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +static const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +static const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +static const u32 Te3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; + +static const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +static const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +static const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +static const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +static const u8 Td4[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; +static const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/** + * Expand the cipher key into the encryption key schedule. + */ +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + + u32 *rk; + int i = 0; + u32 temp; + + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + + rk = key->rd_key; + + if (bits==128) + key->rounds = 10; + else if (bits==192) + key->rounds = 12; + else + key->rounds = 14; + + rk[0] = GETU32(userKey ); + rk[1] = GETU32(userKey + 4); + rk[2] = GETU32(userKey + 8); + rk[3] = GETU32(userKey + 12); + if (bits == 128) { + while (1) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 0; + } + rk += 4; + } + } + rk[4] = GETU32(userKey + 16); + rk[5] = GETU32(userKey + 20); + if (bits == 192) { + while (1) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 0; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(userKey + 24); + rk[7] = GETU32(userKey + 28); + if (bits == 256) { + while (1) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 0; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te2[(temp >> 24) ] & 0xff000000) ^ + (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(temp ) & 0xff] & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + */ +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + + u32 *rk; + int i, j, status; + u32 temp; + + /* first, start with an encryption schedule */ + status = private_AES_set_encrypt_key(userKey, bits, key); + if (status < 0) + return status; + + rk = key->rd_key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < (key->rounds); i++) { + rk += 4; + rk[0] = + Td0[Te1[(rk[0] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[0] ) & 0xff] & 0xff]; + rk[1] = + Td0[Te1[(rk[1] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[1] ) & 0xff] & 0xff]; + rk[2] = + Td0[Te1[(rk[2] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[2] ) & 0xff] & 0xff]; + rk[3] = + Td0[Te1[(rk[3] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[3] ) & 0xff] & 0xff]; + } + return 0; +} + +/* + * Encrypt a single block + * in and out can overlap + */ +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) { + + const u32 *rk; + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + assert(in && out && key); + rk = key->rd_key; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(in ) ^ rk[0]; + s1 = GETU32(in + 4) ^ rk[1]; + s2 = GETU32(in + 8) ^ rk[2]; + s3 = GETU32(in + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; + if (key->rounds > 10) { + /* round 10: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; + if (key->rounds > 12) { + /* round 12: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; + } + } + rk += key->rounds << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = key->rounds >> 1; + for (;;) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[4]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[5]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[6]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0[(t0 >> 24) ] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3 ) & 0xff] ^ + rk[0]; + s1 = + Te0[(t1 >> 24) ] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0 ) & 0xff] ^ + rk[1]; + s2 = + Te0[(t2 >> 24) ] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1 ) & 0xff] ^ + rk[2]; + s3 = + Te0[(t3 >> 24) ] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te2[(t0 >> 24) ] & 0xff000000) ^ + (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(out , s0); + s1 = + (Te2[(t1 >> 24) ] & 0xff000000) ^ + (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(out + 4, s1); + s2 = + (Te2[(t2 >> 24) ] & 0xff000000) ^ + (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(out + 8, s2); + s3 = + (Te2[(t3 >> 24) ] & 0xff000000) ^ + (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32(out + 12, s3); +} + +/* + * Decrypt a single block + * in and out can overlap + */ +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) +{ + + const u32 *rk; + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + assert(in && out && key); + rk = key->rd_key; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(in ) ^ rk[0]; + s1 = GETU32(in + 4) ^ rk[1]; + s2 = GETU32(in + 8) ^ rk[2]; + s3 = GETU32(in + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; + if (key->rounds > 10) { + /* round 10: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; + if (key->rounds > 12) { + /* round 12: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; + } + } + rk += key->rounds << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = key->rounds >> 1; + for (;;) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[4]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[5]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[6]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Td0[(t0 >> 24) ] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1 ) & 0xff] ^ + rk[0]; + s1 = + Td0[(t1 >> 24) ] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2 ) & 0xff] ^ + rk[1]; + s2 = + Td0[(t2 >> 24) ] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3 ) & 0xff] ^ + rk[2]; + s3 = + Td0[(t3 >> 24) ] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + ((u32)Td4[(t0 >> 24) ] << 24) ^ + ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t2 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t1 ) & 0xff]) ^ + rk[0]; + PUTU32(out , s0); + s1 = + ((u32)Td4[(t1 >> 24) ] << 24) ^ + ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t3 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t2 ) & 0xff]) ^ + rk[1]; + PUTU32(out + 4, s1); + s2 = + ((u32)Td4[(t2 >> 24) ] << 24) ^ + ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t0 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t3 ) & 0xff]) ^ + rk[2]; + PUTU32(out + 8, s2); + s3 = + ((u32)Td4[(t3 >> 24) ] << 24) ^ + ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t1 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t0 ) & 0xff]) ^ + rk[3]; + PUTU32(out + 12, s3); +} + +#else /* AES_ASM */ + +static const u8 Te4[256] = { + 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, + 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, + 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, + 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, + 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, + 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U, + 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, + 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, + 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, + 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U, + 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, + 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, + 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, + 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U, + 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, + 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, + 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, + 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U, + 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, + 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, + 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, + 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U, + 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, + 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, + 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, + 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, + 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, + 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU, + 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, + 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, + 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, + 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U +}; +static const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/** + * Expand the cipher key into the encryption key schedule. + */ +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + u32 *rk; + int i = 0; + u32 temp; + + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + + rk = key->rd_key; + + if (bits==128) + key->rounds = 10; + else if (bits==192) + key->rounds = 12; + else + key->rounds = 14; + + rk[0] = GETU32(userKey ); + rk[1] = GETU32(userKey + 4); + rk[2] = GETU32(userKey + 8); + rk[3] = GETU32(userKey + 12); + if (bits == 128) { + while (1) { + temp = rk[3]; + rk[4] = rk[0] ^ + ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 0; + } + rk += 4; + } + } + rk[4] = GETU32(userKey + 16); + rk[5] = GETU32(userKey + 20); + if (bits == 192) { + while (1) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 0; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(userKey + 24); + rk[7] = GETU32(userKey + 28); + if (bits == 256) { + while (1) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 0; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + ((u32)Te4[(temp >> 24) ] << 24) ^ + ((u32)Te4[(temp >> 16) & 0xff] << 16) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 8) ^ + ((u32)Te4[(temp ) & 0xff]); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + */ +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + + u32 *rk; + int i, j, status; + u32 temp; + + /* first, start with an encryption schedule */ + status = private_AES_set_encrypt_key(userKey, bits, key); + if (status < 0) + return status; + + rk = key->rd_key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < (key->rounds); i++) { + rk += 4; + for (j = 0; j < 4; j++) { + u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; + + tp1 = rk[j]; + m = tp1 & 0x80808080; + tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp2 & 0x80808080; + tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp4 & 0x80808080; + tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + tp9 = tp8 ^ tp1; + tpb = tp9 ^ tp2; + tpd = tp9 ^ tp4; + tpe = tp8 ^ tp4 ^ tp2; +#if defined(ROTATE) + rk[j] = tpe ^ ROTATE(tpd,16) ^ + ROTATE(tp9,24) ^ ROTATE(tpb,8); +#else + rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ + (tp9 >> 8) ^ (tp9 << 24) ^ + (tpb >> 24) ^ (tpb << 8); +#endif + } + } + return 0; +} + +#endif /* AES_ASM */ +/* crypto/aes/aes_ctr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "aes.h" +// #include "modes.h" + +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], + unsigned int *num) +{ + CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, + (block128_f) AES_encrypt); +} +/* crypto/aes/aes_ecb.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +// #include "aes.h" +// #include "aes_locl.h" + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc) +{ + + assert(in && out && key); + assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); + + if (AES_ENCRYPT == enc) + AES_encrypt(in, out, key); + else + AES_decrypt(in, out, key); +} +/* crypto/aes/aes_ige.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "cryptlib.h" + +// #include "aes.h" +// #include "aes_locl.h" + +#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) +typedef struct { + unsigned long data[N_WORDS]; +} aes_block_t; + +/* XXX: probably some better way to do this */ +#if defined(__i386__) || defined(__x86_64__) +# define UNALIGNED_MEMOPS_ARE_FAST 1 +#else +# define UNALIGNED_MEMOPS_ARE_FAST 0 +#endif + +#if UNALIGNED_MEMOPS_ARE_FAST +# define load_block(d, s) (d) = *(const aes_block_t *)(s) +# define store_block(d, s) *(aes_block_t *)(d) = (s) +#else +# define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) +# define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) +#endif + +/* N.B. The IV for this mode is _twice_ the block size */ + +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc) +{ + size_t n; + size_t len = length; + + OPENSSL_assert(in && out && key && ivec); + OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); + OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); + + len = length / AES_BLOCK_SIZE; + + if (AES_ENCRYPT == enc) { + if (in != out && + (UNALIGNED_MEMOPS_ARE_FAST + || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == + 0)) { + aes_block_t *ivp = (aes_block_t *) ivec; + aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); + + while (len) { + aes_block_t *inp = (aes_block_t *) in; + aes_block_t *outp = (aes_block_t *) out; + + for (n = 0; n < N_WORDS; ++n) + outp->data[n] = inp->data[n] ^ ivp->data[n]; + AES_encrypt((unsigned char *)outp->data, + (unsigned char *)outp->data, key); + for (n = 0; n < N_WORDS; ++n) + outp->data[n] ^= iv2p->data[n]; + ivp = outp; + iv2p = inp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, ivp->data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); + } else { + aes_block_t tmp, tmp2; + aes_block_t iv; + aes_block_t iv2; + + load_block(iv, ivec); + load_block(iv2, ivec + AES_BLOCK_SIZE); + + while (len) { + load_block(tmp, in); + for (n = 0; n < N_WORDS; ++n) + tmp2.data[n] = tmp.data[n] ^ iv.data[n]; + AES_encrypt((unsigned char *)tmp2.data, + (unsigned char *)tmp2.data, key); + for (n = 0; n < N_WORDS; ++n) + tmp2.data[n] ^= iv2.data[n]; + store_block(out, tmp2); + iv = tmp2; + iv2 = tmp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, iv.data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); + } + } else { + if (in != out && + (UNALIGNED_MEMOPS_ARE_FAST + || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == + 0)) { + aes_block_t *ivp = (aes_block_t *) ivec; + aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); + + while (len) { + aes_block_t tmp; + aes_block_t *inp = (aes_block_t *) in; + aes_block_t *outp = (aes_block_t *) out; + + for (n = 0; n < N_WORDS; ++n) + tmp.data[n] = inp->data[n] ^ iv2p->data[n]; + AES_decrypt((unsigned char *)tmp.data, + (unsigned char *)outp->data, key); + for (n = 0; n < N_WORDS; ++n) + outp->data[n] ^= ivp->data[n]; + ivp = inp; + iv2p = outp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, ivp->data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); + } else { + aes_block_t tmp, tmp2; + aes_block_t iv; + aes_block_t iv2; + + load_block(iv, ivec); + load_block(iv2, ivec + AES_BLOCK_SIZE); + + while (len) { + load_block(tmp, in); + tmp2 = tmp; + for (n = 0; n < N_WORDS; ++n) + tmp.data[n] ^= iv2.data[n]; + AES_decrypt((unsigned char *)tmp.data, + (unsigned char *)tmp.data, key); + for (n = 0; n < N_WORDS; ++n) + tmp.data[n] ^= iv.data[n]; + store_block(out, tmp); + iv = tmp2; + iv2 = tmp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, iv.data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); + } + } +} + +/* + * Note that its effectively impossible to do biIGE in anything other + * than a single pass, so no provision is made for chaining. + */ + +/* N.B. The IV for this mode is _four times_ the block size */ + +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + const AES_KEY *key2, const unsigned char *ivec, + const int enc) +{ + size_t n; + size_t len = length; + unsigned char tmp[AES_BLOCK_SIZE]; + unsigned char tmp2[AES_BLOCK_SIZE]; + unsigned char tmp3[AES_BLOCK_SIZE]; + unsigned char prev[AES_BLOCK_SIZE]; + const unsigned char *iv; + const unsigned char *iv2; + + OPENSSL_assert(in && out && key && ivec); + OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); + OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); + + if (AES_ENCRYPT == enc) { + /* + * XXX: Do a separate case for when in != out (strictly should check + * for overlap, too) + */ + + /* First the forward pass */ + iv = ivec; + iv2 = ivec + AES_BLOCK_SIZE; + while (len >= AES_BLOCK_SIZE) { + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] = in[n] ^ iv[n]; + AES_encrypt(out, out, key); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv2[n]; + iv = out; + memcpy(prev, in, AES_BLOCK_SIZE); + iv2 = prev; + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + + /* And now backwards */ + iv = ivec + AES_BLOCK_SIZE * 2; + iv2 = ivec + AES_BLOCK_SIZE * 3; + len = length; + while (len >= AES_BLOCK_SIZE) { + out -= AES_BLOCK_SIZE; + /* + * XXX: reduce copies by alternating between buffers + */ + memcpy(tmp, out, AES_BLOCK_SIZE); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv[n]; + /* + * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); + */ + AES_encrypt(out, out, key); + /* + * hexdump(stdout,"enc", out, AES_BLOCK_SIZE); + */ + /* + * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); + */ + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv2[n]; + /* + * hexdump(stdout,"out", out, AES_BLOCK_SIZE); + */ + iv = out; + memcpy(prev, tmp, AES_BLOCK_SIZE); + iv2 = prev; + len -= AES_BLOCK_SIZE; + } + } else { + /* First backwards */ + iv = ivec + AES_BLOCK_SIZE * 2; + iv2 = ivec + AES_BLOCK_SIZE * 3; + in += length; + out += length; + while (len >= AES_BLOCK_SIZE) { + in -= AES_BLOCK_SIZE; + out -= AES_BLOCK_SIZE; + memcpy(tmp, in, AES_BLOCK_SIZE); + memcpy(tmp2, in, AES_BLOCK_SIZE); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + tmp[n] ^= iv2[n]; + AES_decrypt(tmp, out, key); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv[n]; + memcpy(tmp3, tmp2, AES_BLOCK_SIZE); + iv = tmp3; + iv2 = out; + len -= AES_BLOCK_SIZE; + } + + /* And now forwards */ + iv = ivec; + iv2 = ivec + AES_BLOCK_SIZE; + len = length; + while (len >= AES_BLOCK_SIZE) { + memcpy(tmp, out, AES_BLOCK_SIZE); + memcpy(tmp2, out, AES_BLOCK_SIZE); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + tmp[n] ^= iv2[n]; + AES_decrypt(tmp, out, key); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv[n]; + memcpy(tmp3, tmp2, AES_BLOCK_SIZE); + iv = tmp3; + iv2 = out; + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + } +} +/* crypto/aes/aes_misc.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "opensslv.h" +#include "crypto.h" +// #include "aes.h" +// #include "aes_locl.h" + +const char AES_version[] = "AES" OPENSSL_VERSION_PTEXT; + +const char *AES_options(void) +{ +#ifdef FULL_UNROLL + return "aes(full)"; +#else + return "aes(partial)"; +#endif +} + +/* FIPS wrapper functions to block low level AES calls in FIPS mode */ + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ +#ifdef OPENSSL_FIPS + fips_cipher_abort(AES); +#endif + return private_AES_set_encrypt_key(userKey, bits, key); +} + +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ +#ifdef OPENSSL_FIPS + fips_cipher_abort(AES); +#endif + return private_AES_set_decrypt_key(userKey, bits, key); +} +/* crypto/aes/aes_ofb.c */ +/* ==================================================================== + * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "aes.h" +// #include "modes.h" + +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num) +{ + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, + (block128_f) AES_encrypt); +} +/* crypto/aes/aes_wrap.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "aes.h" +// #include "modes.h" + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen) +{ + return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f) AES_encrypt); +} + +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen) +{ + return CRYPTO_128_unwrap(key, iv, out, in, inlen, + (block128_f) AES_decrypt); +} diff --git a/Sources/COpenSSL/aes_locl.h b/Sources/COpenSSL/aes_locl.h new file mode 100644 index 00000000..b0b62611 --- /dev/null +++ b/Sources/COpenSSL/aes_locl.h @@ -0,0 +1,89 @@ +/* crypto/aes/aes.h */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_AES_LOCL_H +# define HEADER_AES_LOCL_H + +# include "e_os2.h" + +# ifdef OPENSSL_NO_AES +# error AES is disabled. +# endif + +# include +# include +# include + +# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +# define GETU32(p) SWAP(*((u32 *)(p))) +# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } +# else +# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) +# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } +# endif + +# ifdef AES_LONG +typedef unsigned long u32; +# else +typedef unsigned int u32; +# endif +typedef unsigned short u16; +typedef unsigned char u8; + +# define MAXKC (256/32) +# define MAXKB (256/8) +# define MAXNR 14 + +/* This controls loop-unrolling in aes_core.c */ +# undef FULL_UNROLL + +#endif /* !HEADER_AES_LOCL_H */ diff --git a/Sources/COpenSSL/ameth_lib.c b/Sources/COpenSSL/ameth_lib.c new file mode 100644 index 00000000..be73058e --- /dev/null +++ b/Sources/COpenSSL/ameth_lib.c @@ -0,0 +1,498 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "asn1t.h" +#include "x509.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +#include "asn1_locl.h" + +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; + +/* Keep this sorted in type order !! */ +static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { +#ifndef OPENSSL_NO_RSA + &rsa_asn1_meths[0], + &rsa_asn1_meths[1], +#endif +#ifndef OPENSSL_NO_DH + &dh_asn1_meth, +#endif +#ifndef OPENSSL_NO_DSA + &dsa_asn1_meths[0], + &dsa_asn1_meths[1], + &dsa_asn1_meths[2], + &dsa_asn1_meths[3], + &dsa_asn1_meths[4], +#endif +#ifndef OPENSSL_NO_EC + &eckey_asn1_meth, +#endif + &hmac_asn1_meth, +#ifndef OPENSSL_NO_CMAC + &cmac_asn1_meth, +#endif +#ifndef OPENSSL_NO_DH + &dhx_asn1_meth +#endif +}; + +typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); +DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD) +static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL; + +#ifdef TEST +void main() +{ + int i; + for (i = 0; + i < sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); i++) + fprintf(stderr, "Number %d id=%d (%s)\n", i, + standard_methods[i]->pkey_id, + OBJ_nid2sn(standard_methods[i]->pkey_id)); +} +#endif + +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, + const EVP_PKEY_ASN1_METHOD *, ameth); + +static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a, + const EVP_PKEY_ASN1_METHOD *const *b) +{ + return ((*a)->pkey_id - (*b)->pkey_id); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, + const EVP_PKEY_ASN1_METHOD *, ameth); + +int EVP_PKEY_asn1_get_count(void) +{ + int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); + if (app_methods) + num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods); + return num; +} + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) +{ + int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); + if (idx < 0) + return NULL; + if (idx < num) + return standard_methods[idx]; + idx -= num; + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); +} + +static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type) +{ + EVP_PKEY_ASN1_METHOD tmp; + const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret; + tmp.pkey_id = type; + if (app_methods) { + int idx; + idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp); + if (idx >= 0) + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); + } + ret = OBJ_bsearch_ameth(&t, standard_methods, sizeof(standard_methods) + / sizeof(EVP_PKEY_ASN1_METHOD *)); + if (!ret || !*ret) + return NULL; + return *ret; +} + +/* + * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also + * search through engines and set *pe to a functional reference to the engine + * implementing 'type' or NULL if no engine implements it. + */ + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type) +{ + const EVP_PKEY_ASN1_METHOD *t; + + for (;;) { + t = pkey_asn1_find(type); + if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS)) + break; + type = t->pkey_base_id; + } + if (pe) { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e; + /* type will contain the final unaliased type */ + e = ENGINE_get_pkey_asn1_meth_engine(type); + if (e) { + *pe = e; + return ENGINE_get_pkey_asn1_meth(e, type); + } +#endif + *pe = NULL; + } + return t; +} + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len) +{ + int i; + const EVP_PKEY_ASN1_METHOD *ameth; + if (len == -1) + len = strlen(str); + if (pe) { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e; + ameth = ENGINE_pkey_asn1_find_str(&e, str, len); + if (ameth) { + /* + * Convert structural into functional reference + */ + if (!ENGINE_init(e)) + ameth = NULL; + ENGINE_free(e); + *pe = e; + return ameth; + } +#endif + *pe = NULL; + } + for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { + ameth = EVP_PKEY_asn1_get0(i); + if (ameth->pkey_flags & ASN1_PKEY_ALIAS) + continue; + if (((int)strlen(ameth->pem_str) == len) && + !strncasecmp(ameth->pem_str, str, len)) + return ameth; + } + return NULL; +} + +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) +{ + if (app_methods == NULL) { + app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp); + if (!app_methods) + return 0; + } + if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth)) + return 0; + sk_EVP_PKEY_ASN1_METHOD_sort(app_methods); + return 1; +} + +int EVP_PKEY_asn1_add_alias(int to, int from) +{ + EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); + if (!ameth) + return 0; + ameth->pkey_base_id = to; + if (!EVP_PKEY_asn1_add0(ameth)) { + EVP_PKEY_asn1_free(ameth); + return 0; + } + return 1; +} + +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, + int *ppkey_flags, const char **pinfo, + const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth) +{ + if (!ameth) + return 0; + if (ppkey_id) + *ppkey_id = ameth->pkey_id; + if (ppkey_base_id) + *ppkey_base_id = ameth->pkey_base_id; + if (ppkey_flags) + *ppkey_flags = ameth->pkey_flags; + if (pinfo) + *pinfo = ameth->info; + if (ppem_str) + *ppem_str = ameth->pem_str; + return 1; +} + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey) +{ + return pkey->ameth; +} + +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, const char *info) +{ + EVP_PKEY_ASN1_METHOD *ameth; + ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD)); + if (!ameth) + return NULL; + + memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD)); + + ameth->pkey_id = id; + ameth->pkey_base_id = id; + ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC; + + if (info) { + ameth->info = BUF_strdup(info); + if (!ameth->info) + goto err; + } else + ameth->info = NULL; + + /* + * One of the following must be true: + * + * pem_str == NULL AND ASN1_PKEY_ALIAS is set + * pem_str != NULL AND ASN1_PKEY_ALIAS is clear + * + * Anything else is an error and may lead to a corrupt ASN1 method table + */ + if (!((pem_str == NULL && (flags & ASN1_PKEY_ALIAS) != 0) + || (pem_str != NULL && (flags & ASN1_PKEY_ALIAS) == 0))) + goto err; + + if (pem_str) { + ameth->pem_str = BUF_strdup(pem_str); + if (!ameth->pem_str) + goto err; + } else + ameth->pem_str = NULL; + + ameth->pub_decode = 0; + ameth->pub_encode = 0; + ameth->pub_cmp = 0; + ameth->pub_print = 0; + + ameth->priv_decode = 0; + ameth->priv_encode = 0; + ameth->priv_print = 0; + + ameth->old_priv_encode = 0; + ameth->old_priv_decode = 0; + + ameth->item_verify = 0; + ameth->item_sign = 0; + + ameth->pkey_size = 0; + ameth->pkey_bits = 0; + + ameth->param_decode = 0; + ameth->param_encode = 0; + ameth->param_missing = 0; + ameth->param_copy = 0; + ameth->param_cmp = 0; + ameth->param_print = 0; + + ameth->pkey_free = 0; + ameth->pkey_ctrl = 0; + + return ameth; + + err: + + EVP_PKEY_asn1_free(ameth); + return NULL; + +} + +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src) +{ + + dst->pub_decode = src->pub_decode; + dst->pub_encode = src->pub_encode; + dst->pub_cmp = src->pub_cmp; + dst->pub_print = src->pub_print; + + dst->priv_decode = src->priv_decode; + dst->priv_encode = src->priv_encode; + dst->priv_print = src->priv_print; + + dst->old_priv_encode = src->old_priv_encode; + dst->old_priv_decode = src->old_priv_decode; + + dst->pkey_size = src->pkey_size; + dst->pkey_bits = src->pkey_bits; + + dst->param_decode = src->param_decode; + dst->param_encode = src->param_encode; + dst->param_missing = src->param_missing; + dst->param_copy = src->param_copy; + dst->param_cmp = src->param_cmp; + dst->param_print = src->param_print; + + dst->pkey_free = src->pkey_free; + dst->pkey_ctrl = src->pkey_ctrl; + + dst->item_sign = src->item_sign; + dst->item_verify = src->item_verify; + +} + +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) +{ + if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) { + if (ameth->pem_str) + OPENSSL_free(ameth->pem_str); + if (ameth->info) + OPENSSL_free(ameth->info); + OPENSSL_free(ameth); + } +} + +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode) (EVP_PKEY *pk, + X509_PUBKEY *pub), + int (*pub_encode) (X509_PUBKEY *pub, + const EVP_PKEY *pk), + int (*pub_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*pub_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + int (*pkey_size) (const EVP_PKEY *pk), + int (*pkey_bits) (const EVP_PKEY *pk)) +{ + ameth->pub_decode = pub_decode; + ameth->pub_encode = pub_encode; + ameth->pub_cmp = pub_cmp; + ameth->pub_print = pub_print; + ameth->pkey_size = pkey_size; + ameth->pkey_bits = pkey_bits; +} + +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode) (EVP_PKEY *pk, + PKCS8_PRIV_KEY_INFO + *p8inf), + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, + const EVP_PKEY *pk), + int (*priv_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)) +{ + ameth->priv_decode = priv_decode; + ameth->priv_encode = priv_encode; + ameth->priv_print = priv_print; +} + +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, + int derlen), + int (*param_encode) (const EVP_PKEY *pkey, + unsigned char **pder), + int (*param_missing) (const EVP_PKEY *pk), + int (*param_copy) (EVP_PKEY *to, + const EVP_PKEY *from), + int (*param_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*param_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx)) +{ + ameth->param_decode = param_decode; + ameth->param_encode = param_encode; + ameth->param_missing = param_missing; + ameth->param_copy = param_copy; + ameth->param_cmp = param_cmp; + ameth->param_print = param_print; +} + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free) (EVP_PKEY *pkey)) +{ + ameth->pkey_free = pkey_free; +} + +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, + long arg1, void *arg2)) +{ + ameth->pkey_ctrl = pkey_ctrl; +} + +void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, + int (*item_verify) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *a, + ASN1_BIT_STRING *sig, + EVP_PKEY *pkey), + int (*item_sign) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *alg1, + X509_ALGOR *alg2, + ASN1_BIT_STRING *sig)) +{ + ameth->item_sign = item_sign; + ameth->item_verify = item_verify; +} diff --git a/Sources/COpenSSL/asn1.h b/Sources/COpenSSL/asn1.h new file mode 100644 index 00000000..e41f9870 --- /dev/null +++ b/Sources/COpenSSL/asn1.h @@ -0,0 +1,1424 @@ +/* crypto/asn1/asn1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_H +# define HEADER_ASN1_H + +# include +# include "e_os2.h" +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# include "stack.h" +# include "safestack.h" + +# include "symhacks.h" + +# include "ossl_typ.h" +# ifndef OPENSSL_NO_DEPRECATED +# include "bn.h" +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define V_ASN1_UNIVERSAL 0x00 +# define V_ASN1_APPLICATION 0x40 +# define V_ASN1_CONTEXT_SPECIFIC 0x80 +# define V_ASN1_PRIVATE 0xc0 + +# define V_ASN1_CONSTRUCTED 0x20 +# define V_ASN1_PRIMITIVE_TAG 0x1f +# define V_ASN1_PRIMATIVE_TAG 0x1f + +# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */ +# define V_ASN1_OTHER -3/* used in ASN1_TYPE */ +# define V_ASN1_ANY -4/* used in ASN1 template code */ + +# define V_ASN1_NEG 0x100/* negative flag */ + +# define V_ASN1_UNDEF -1 +# define V_ASN1_EOC 0 +# define V_ASN1_BOOLEAN 1 /**/ +# define V_ASN1_INTEGER 2 +# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +# define V_ASN1_BIT_STRING 3 +# define V_ASN1_OCTET_STRING 4 +# define V_ASN1_NULL 5 +# define V_ASN1_OBJECT 6 +# define V_ASN1_OBJECT_DESCRIPTOR 7 +# define V_ASN1_EXTERNAL 8 +# define V_ASN1_REAL 9 +# define V_ASN1_ENUMERATED 10 +# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) +# define V_ASN1_UTF8STRING 12 +# define V_ASN1_SEQUENCE 16 +# define V_ASN1_SET 17 +# define V_ASN1_NUMERICSTRING 18 /**/ +# define V_ASN1_PRINTABLESTRING 19 +# define V_ASN1_T61STRING 20 +# define V_ASN1_TELETEXSTRING 20/* alias */ +# define V_ASN1_VIDEOTEXSTRING 21 /**/ +# define V_ASN1_IA5STRING 22 +# define V_ASN1_UTCTIME 23 +# define V_ASN1_GENERALIZEDTIME 24 /**/ +# define V_ASN1_GRAPHICSTRING 25 /**/ +# define V_ASN1_ISO64STRING 26 /**/ +# define V_ASN1_VISIBLESTRING 26/* alias */ +# define V_ASN1_GENERALSTRING 27 /**/ +# define V_ASN1_UNIVERSALSTRING 28 /**/ +# define V_ASN1_BMPSTRING 30 +/* For use with d2i_ASN1_type_bytes() */ +# define B_ASN1_NUMERICSTRING 0x0001 +# define B_ASN1_PRINTABLESTRING 0x0002 +# define B_ASN1_T61STRING 0x0004 +# define B_ASN1_TELETEXSTRING 0x0004 +# define B_ASN1_VIDEOTEXSTRING 0x0008 +# define B_ASN1_IA5STRING 0x0010 +# define B_ASN1_GRAPHICSTRING 0x0020 +# define B_ASN1_ISO64STRING 0x0040 +# define B_ASN1_VISIBLESTRING 0x0040 +# define B_ASN1_GENERALSTRING 0x0080 +# define B_ASN1_UNIVERSALSTRING 0x0100 +# define B_ASN1_OCTET_STRING 0x0200 +# define B_ASN1_BIT_STRING 0x0400 +# define B_ASN1_BMPSTRING 0x0800 +# define B_ASN1_UNKNOWN 0x1000 +# define B_ASN1_UTF8STRING 0x2000 +# define B_ASN1_UTCTIME 0x4000 +# define B_ASN1_GENERALIZEDTIME 0x8000 +# define B_ASN1_SEQUENCE 0x10000 +/* For use with ASN1_mbstring_copy() */ +# define MBSTRING_FLAG 0x1000 +# define MBSTRING_UTF8 (MBSTRING_FLAG) +# define MBSTRING_ASC (MBSTRING_FLAG|1) +# define MBSTRING_BMP (MBSTRING_FLAG|2) +# define MBSTRING_UNIV (MBSTRING_FLAG|4) +# define SMIME_OLDMIME 0x400 +# define SMIME_CRLFEOL 0x800 +# define SMIME_STREAM 0x1000 + struct X509_algor_st; +DECLARE_STACK_OF(X509_ALGOR) + +# define DECLARE_ASN1_SET_OF(type)/* filled in by mkstack.pl */ +# define IMPLEMENT_ASN1_SET_OF(type)/* nothing, no longer needed */ + +/* + * We MUST make sure that, except for constness, asn1_ctx_st and + * asn1_const_ctx are exactly the same. Fortunately, as soon as the old ASN1 + * parsing macros are gone, we can throw this away as well... + */ +typedef struct asn1_ctx_st { + unsigned char *p; /* work char pointer */ + int eos; /* end of sequence read for indefinite + * encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + unsigned char *max; /* largest value of p allowed */ + unsigned char *q; /* temporary variable */ + unsigned char **pp; /* variable */ + int line; /* used in error processing */ +} ASN1_CTX; + +typedef struct asn1_const_ctx_st { + const unsigned char *p; /* work char pointer */ + int eos; /* end of sequence read for indefinite + * encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + const unsigned char *max; /* largest value of p allowed */ + const unsigned char *q; /* temporary variable */ + const unsigned char **pp; /* variable */ + int line; /* used in error processing */ +} ASN1_const_CTX; + +/* + * These are used internally in the ASN1_OBJECT to keep track of whether the + * names and data need to be free()ed + */ +# define ASN1_OBJECT_FLAG_DYNAMIC 0x01/* internal use */ +# define ASN1_OBJECT_FLAG_CRITICAL 0x02/* critical x509v3 object id */ +# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */ +# define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08/* internal use */ +struct asn1_object_st { + const char *sn, *ln; + int nid; + int length; + const unsigned char *data; /* data remains const after init */ + int flags; /* Should we free this one */ +}; + +# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +/* + * This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should be + * inserted in the memory buffer + */ +# define ASN1_STRING_FLAG_NDEF 0x010 + +/* + * This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been accessed. + * The flag will be reset when content has been written to it. + */ + +# define ASN1_STRING_FLAG_CONT 0x020 +/* + * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +# define ASN1_STRING_FLAG_MSTRING 0x040 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + long flags; +}; + +/* + * ASN1_ENCODING structure: this is used to save the received encoding of an + * ASN1 type. This is useful to get round problems with invalid encodings + * which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +# define ASN1_LONG_UNDEF 0x7fffffffL + +# define STABLE_FLAGS_MALLOC 0x01 +# define STABLE_NO_MASK 0x02 +# define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DECLARE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +# define ub_name 32768 +# define ub_common_name 64 +# define ub_locality_name 128 +# define ub_state_name 128 +# define ub_organization_name 64 +# define ub_organization_unit_name 64 +# define ub_title 64 +# define ub_email_address 128 + +/* + * Declarations for template structures: for full definitions see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +# define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +# define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +# define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +# define I2D_OF(type) int (*)(type *,unsigned char **) +# define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +# define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +# define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +# define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/*- + * The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +# define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +# define DECLARE_ASN1_ITEM(name) \ + OPENSSL_EXTERN const ASN1_ITEM name##_it; + +# else + +/* + * Platforms that can't easily handle shared global variables are declared as + * functions returning ASN1_ITEM pointers. + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr()) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (iptr##_it) + +# define ASN1_ITEM_rptr(ref) (ref##_it()) + +# define DECLARE_ASN1_ITEM(name) \ + const ASN1_ITEM * name##_it(void); + +# endif + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* + * These determine which characters to escape: RFC2253 special characters, + * control characters and MSB set characters + */ + +# define ASN1_STRFLGS_ESC_2253 1 +# define ASN1_STRFLGS_ESC_CTRL 2 +# define ASN1_STRFLGS_ESC_MSB 4 + +/* + * This flag determines how we do escaping: normally RC2253 backslash only, + * set this to use backslash and quote. + */ + +# define ASN1_STRFLGS_ESC_QUOTE 8 + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +# define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +# define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +# define CHARTYPE_LAST_ESC_2253 0x40 + +/* + * NB the internal flags are safely reused below by flags handled at the top + * level. + */ + +/* + * If this is set we convert all character strings to UTF8 first + */ + +# define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* + * If this is set we don't attempt to interpret content: just assume all + * strings are 1 byte per character. This will produce some pretty odd + * looking output! + */ + +# define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +# define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* + * This determines which strings to display and which to 'dump' (hex dump of + * content octets or DER encoding). We can only dump non character strings or + * everything. If we don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to the usual escaping + * options. + */ + +# define ASN1_STRFLGS_DUMP_ALL 0x80 +# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* + * These determine what 'dumping' does, we can dump the content octets or the + * DER encoding: both use the RFC2253 #XXXXX notation. + */ + +# define ASN1_STRFLGS_DUMP_DER 0x200 + +/* + * All the string flags consistent with RFC2253, escaping control characters + * isn't essential in RFC2253 but it is advisable anyway. + */ + +# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DECLARE_STACK_OF(ASN1_INTEGER) +DECLARE_ASN1_SET_OF(ASN1_INTEGER) + +DECLARE_STACK_OF(ASN1_GENERALSTRING) + +typedef struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING *asn1_string; + ASN1_OBJECT *object; + ASN1_INTEGER *integer; + ASN1_ENUMERATED *enumerated; + ASN1_BIT_STRING *bit_string; + ASN1_OCTET_STRING *octet_string; + ASN1_PRINTABLESTRING *printablestring; + ASN1_T61STRING *t61string; + ASN1_IA5STRING *ia5string; + ASN1_GENERALSTRING *generalstring; + ASN1_BMPSTRING *bmpstring; + ASN1_UNIVERSALSTRING *universalstring; + ASN1_UTCTIME *utctime; + ASN1_GENERALIZEDTIME *generalizedtime; + ASN1_VISIBLESTRING *visiblestring; + ASN1_UTF8STRING *utf8string; + /* + * set and sequence are left complete and still contain the set or + * sequence bytes + */ + ASN1_STRING *set; + ASN1_STRING *sequence; + ASN1_VALUE *asn1_value; + } value; +} ASN1_TYPE; + +DECLARE_STACK_OF(ASN1_TYPE) +DECLARE_ASN1_SET_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +typedef struct NETSCAPE_X509_st { + ASN1_OCTET_STRING *header; + X509 *cert; +} NETSCAPE_X509; + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +# define M_ASN1_STRING_length(x) ((x)->length) +# define M_ASN1_STRING_length_set(x, n) ((x)->length = (n)) +# define M_ASN1_STRING_type(x) ((x)->type) +# define M_ASN1_STRING_data(x) ((x)->data) + +/* Macros for string operations */ +# define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\ + ASN1_STRING_type_new(V_ASN1_BIT_STRING) +# define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +# define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) + +# define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\ + ASN1_STRING_type_new(V_ASN1_INTEGER) +# define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +# define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\ + ASN1_STRING_type_new(V_ASN1_ENUMERATED) +# define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +# define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\ + ASN1_STRING_type_new(V_ASN1_OCTET_STRING) +# define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +# define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) +# define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b) +# define M_i2d_ASN1_OCTET_STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\ + V_ASN1_UNIVERSAL) + +# define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +# define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +# define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +# define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +# define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING) +# define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_PRINTABLE(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_PRINTABLE) + +# define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +# define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_DIRECTORYSTRING(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DIRECTORYSTRING) + +# define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +# define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_DISPLAYTEXT(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DISPLAYTEXT) + +# define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +# define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_PRINTABLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \ + (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING) + +# define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\ + ASN1_STRING_type_new(V_ASN1_T61STRING) +# define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_T61STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_T61STRING(a,pp,l) \ + (ASN1_T61STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING) + +# define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\ + ASN1_STRING_type_new(V_ASN1_IA5STRING) +# define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_IA5STRING_dup(a) \ + (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_i2d_ASN1_IA5STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_IA5STRING(a,pp,l) \ + (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\ + B_ASN1_IA5STRING) + +# define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +# define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +# define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\ + ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME) +# define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\ + (const ASN1_STRING *)a) + +# define M_ASN1_TIME_new() (ASN1_TIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +# define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_TIME_dup(a) (ASN1_TIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +# define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_GENERALSTRING) +# define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_GENERALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_GENERALSTRING(a,pp,l) \ + (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING) + +# define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING) +# define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \ + (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING) + +# define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\ + ASN1_STRING_type_new(V_ASN1_BMPSTRING) +# define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_BMPSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_BMPSTRING(a,pp,l) \ + (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING) + +# define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +# define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_VISIBLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \ + (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING) + +# define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\ + ASN1_STRING_type_new(V_ASN1_UTF8STRING) +# define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_UTF8STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_UTF8STRING(a,pp,l) \ + (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING) + + /* for the is_set parameter to i2d_ASN1_SET */ +# define IS_SEQUENCE 0 +# define IS_SET 1 + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +ASN1_OBJECT *ASN1_OBJECT_new(void); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp); +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DECLARE_STACK_OF(ASN1_OBJECT) +DECLARE_ASN1_SET_OF(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +void ASN1_STRING_clear_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING *ASN1_STRING_type_new(int type); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* + * Since this is used to store all sorts of things, via macros, for now, + * make its data void * + */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(ASN1_STRING *x); +unsigned char *ASN1_STRING_data(ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp); +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long length); +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len); + +# ifndef OPENSSL_NO_BIO +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +# endif +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, + BIT_STRING_BITNAME *tbl); + +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp); +int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); +# if 0 +time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s); +# endif + +int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); +int ASN1_TIME_diff(int *pday, int *psec, + const ASN1_TIME *from, const ASN1_TIME *to); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val); +int UTF8_putc(unsigned char *str, int len, unsigned long value); + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_TIME_check(ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME + **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, + const unsigned char **pp, + long length, d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK), + int ex_tag, int ex_class); + +# ifndef OPENSSL_NO_BIO +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type); +# endif +int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass); +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int Ptag, int Pclass); +unsigned long ASN1_tag2bit(int tag); +/* type is one or more of the B_ASN1_ values. */ +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int type); + +/* PARSING */ +int asn1_Finish(ASN1_CTX *c); +int asn1_const_Finish(ASN1_const_CTX *c); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p, long len); +int ASN1_const_check_infinite_end(const unsigned char **p, long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, + int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +# define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +/* ASN1 alloc/free macros for when a type is only used internally */ + +# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +# define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +# ifndef OPENSSL_NO_FP_API +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); + +# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); + +# define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); +# endif + +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); + +# ifndef OPENSSL_NO_BIO +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); + +# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); + +# define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump); +# endif +const char *ASN1_tag2str(int tag); + +/* Used to load and write netscape format cert */ + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509) + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK)); +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, + unsigned char **buf, int *len); +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, + ASN1_OCTET_STRING **oct); + +# define ASN1_pack_string_of(type,obj,i2d,oct) \ + (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \ + CHECKED_I2D_OF(type, i2d), \ + oct)) + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); + +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +void ERR_load_ASN1_strings(void); + +/* Error codes for the ASN1 functions. */ + +/* Function codes. */ +# define ASN1_F_A2D_ASN1_OBJECT 100 +# define ASN1_F_A2I_ASN1_ENUMERATED 101 +# define ASN1_F_A2I_ASN1_INTEGER 102 +# define ASN1_F_A2I_ASN1_STRING 103 +# define ASN1_F_APPEND_EXP 176 +# define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +# define ASN1_F_ASN1_CB 177 +# define ASN1_F_ASN1_CHECK_TLEN 104 +# define ASN1_F_ASN1_COLLATE_PRIMITIVE 105 +# define ASN1_F_ASN1_COLLECT 106 +# define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +# define ASN1_F_ASN1_D2I_FP 109 +# define ASN1_F_ASN1_D2I_READ_BIO 107 +# define ASN1_F_ASN1_DIGEST 184 +# define ASN1_F_ASN1_DO_ADB 110 +# define ASN1_F_ASN1_DUP 111 +# define ASN1_F_ASN1_ENUMERATED_SET 112 +# define ASN1_F_ASN1_ENUMERATED_TO_BN 113 +# define ASN1_F_ASN1_EX_C2I 204 +# define ASN1_F_ASN1_FIND_END 190 +# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +# define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 +# define ASN1_F_ASN1_GENERATE_V3 178 +# define ASN1_F_ASN1_GET_OBJECT 114 +# define ASN1_F_ASN1_HEADER_NEW 115 +# define ASN1_F_ASN1_I2D_BIO 116 +# define ASN1_F_ASN1_I2D_FP 117 +# define ASN1_F_ASN1_INTEGER_SET 118 +# define ASN1_F_ASN1_INTEGER_TO_BN 119 +# define ASN1_F_ASN1_ITEM_D2I_FP 206 +# define ASN1_F_ASN1_ITEM_DUP 191 +# define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 +# define ASN1_F_ASN1_ITEM_EX_D2I 120 +# define ASN1_F_ASN1_ITEM_I2D_BIO 192 +# define ASN1_F_ASN1_ITEM_I2D_FP 193 +# define ASN1_F_ASN1_ITEM_PACK 198 +# define ASN1_F_ASN1_ITEM_SIGN 195 +# define ASN1_F_ASN1_ITEM_SIGN_CTX 220 +# define ASN1_F_ASN1_ITEM_UNPACK 199 +# define ASN1_F_ASN1_ITEM_VERIFY 197 +# define ASN1_F_ASN1_MBSTRING_NCOPY 122 +# define ASN1_F_ASN1_OBJECT_NEW 123 +# define ASN1_F_ASN1_OUTPUT_DATA 214 +# define ASN1_F_ASN1_PACK_STRING 124 +# define ASN1_F_ASN1_PCTX_NEW 205 +# define ASN1_F_ASN1_PKCS5_PBE_SET 125 +# define ASN1_F_ASN1_SEQ_PACK 126 +# define ASN1_F_ASN1_SEQ_UNPACK 127 +# define ASN1_F_ASN1_SIGN 128 +# define ASN1_F_ASN1_STR2TYPE 179 +# define ASN1_F_ASN1_STRING_SET 186 +# define ASN1_F_ASN1_STRING_TABLE_ADD 129 +# define ASN1_F_ASN1_STRING_TYPE_NEW 130 +# define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +# define ASN1_F_ASN1_TEMPLATE_NEW 133 +# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +# define ASN1_F_ASN1_TIME_ADJ 217 +# define ASN1_F_ASN1_TIME_SET 175 +# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +# define ASN1_F_ASN1_UNPACK_STRING 136 +# define ASN1_F_ASN1_UTCTIME_ADJ 218 +# define ASN1_F_ASN1_UTCTIME_SET 187 +# define ASN1_F_ASN1_VERIFY 137 +# define ASN1_F_B64_READ_ASN1 209 +# define ASN1_F_B64_WRITE_ASN1 210 +# define ASN1_F_BIO_NEW_NDEF 208 +# define ASN1_F_BITSTR_CB 180 +# define ASN1_F_BN_TO_ASN1_ENUMERATED 138 +# define ASN1_F_BN_TO_ASN1_INTEGER 139 +# define ASN1_F_C2I_ASN1_BIT_STRING 189 +# define ASN1_F_C2I_ASN1_INTEGER 194 +# define ASN1_F_C2I_ASN1_OBJECT 196 +# define ASN1_F_COLLECT_DATA 140 +# define ASN1_F_D2I_ASN1_BIT_STRING 141 +# define ASN1_F_D2I_ASN1_BOOLEAN 142 +# define ASN1_F_D2I_ASN1_BYTES 143 +# define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144 +# define ASN1_F_D2I_ASN1_HEADER 145 +# define ASN1_F_D2I_ASN1_INTEGER 146 +# define ASN1_F_D2I_ASN1_OBJECT 147 +# define ASN1_F_D2I_ASN1_SET 148 +# define ASN1_F_D2I_ASN1_TYPE_BYTES 149 +# define ASN1_F_D2I_ASN1_UINTEGER 150 +# define ASN1_F_D2I_ASN1_UTCTIME 151 +# define ASN1_F_D2I_AUTOPRIVATEKEY 207 +# define ASN1_F_D2I_NETSCAPE_RSA 152 +# define ASN1_F_D2I_NETSCAPE_RSA_2 153 +# define ASN1_F_D2I_PRIVATEKEY 154 +# define ASN1_F_D2I_PUBLICKEY 155 +# define ASN1_F_D2I_RSA_NET 200 +# define ASN1_F_D2I_RSA_NET_2 201 +# define ASN1_F_D2I_X509 156 +# define ASN1_F_D2I_X509_CINF 157 +# define ASN1_F_D2I_X509_PKEY 159 +# define ASN1_F_DO_BUF 221 +# define ASN1_F_I2D_ASN1_BIO_STREAM 211 +# define ASN1_F_I2D_ASN1_BOOLEAN 223 +# define ASN1_F_I2D_ASN1_OBJECT 222 +# define ASN1_F_I2D_ASN1_SET 188 +# define ASN1_F_I2D_ASN1_TIME 160 +# define ASN1_F_I2D_DSA_PUBKEY 161 +# define ASN1_F_I2D_EC_PUBKEY 181 +# define ASN1_F_I2D_PRIVATEKEY 163 +# define ASN1_F_I2D_PUBLICKEY 164 +# define ASN1_F_I2D_RSA_NET 162 +# define ASN1_F_I2D_RSA_PUBKEY 165 +# define ASN1_F_LONG_C2I 166 +# define ASN1_F_OID_MODULE_INIT 174 +# define ASN1_F_PARSE_TAGGING 182 +# define ASN1_F_PKCS5_PBE2_SET_IV 167 +# define ASN1_F_PKCS5_PBE_SET 202 +# define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +# define ASN1_F_PKCS5_PBKDF2_SET 219 +# define ASN1_F_SMIME_READ_ASN1 212 +# define ASN1_F_SMIME_TEXT 213 +# define ASN1_F_X509_CINF_NEW 168 +# define ASN1_F_X509_CRL_ADD0_REVOKED 169 +# define ASN1_F_X509_INFO_NEW 170 +# define ASN1_F_X509_NAME_ENCODE 203 +# define ASN1_F_X509_NAME_EX_D2I 158 +# define ASN1_F_X509_NAME_EX_NEW 171 +# define ASN1_F_X509_NEW 172 +# define ASN1_F_X509_PKEY_NEW 173 + +/* Reason codes. */ +# define ASN1_R_ADDING_OBJECT 171 +# define ASN1_R_ASN1_PARSE_ERROR 203 +# define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +# define ASN1_R_AUX_ERROR 100 +# define ASN1_R_BAD_CLASS 101 +# define ASN1_R_BAD_OBJECT_HEADER 102 +# define ASN1_R_BAD_PASSWORD_READ 103 +# define ASN1_R_BAD_TAG 104 +# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +# define ASN1_R_BN_LIB 105 +# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +# define ASN1_R_BUFFER_TOO_SMALL 107 +# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +# define ASN1_R_CONTEXT_NOT_INITIALISED 217 +# define ASN1_R_DATA_IS_WRONG 109 +# define ASN1_R_DECODE_ERROR 110 +# define ASN1_R_DECODING_ERROR 111 +# define ASN1_R_DEPTH_EXCEEDED 174 +# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +# define ASN1_R_ENCODE_ERROR 112 +# define ASN1_R_ERROR_GETTING_TIME 173 +# define ASN1_R_ERROR_LOADING_SECTION 172 +# define ASN1_R_ERROR_PARSING_SET_ELEMENT 113 +# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +# define ASN1_R_EXPECTING_AN_INTEGER 115 +# define ASN1_R_EXPECTING_AN_OBJECT 116 +# define ASN1_R_EXPECTING_A_BOOLEAN 117 +# define ASN1_R_EXPECTING_A_TIME 118 +# define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +# define ASN1_R_FIELD_MISSING 121 +# define ASN1_R_FIRST_NUM_TOO_LARGE 122 +# define ASN1_R_HEADER_TOO_LONG 123 +# define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +# define ASN1_R_ILLEGAL_BOOLEAN 176 +# define ASN1_R_ILLEGAL_CHARACTERS 124 +# define ASN1_R_ILLEGAL_FORMAT 177 +# define ASN1_R_ILLEGAL_HEX 178 +# define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +# define ASN1_R_ILLEGAL_INTEGER 180 +# define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +# define ASN1_R_ILLEGAL_NULL 125 +# define ASN1_R_ILLEGAL_NULL_VALUE 182 +# define ASN1_R_ILLEGAL_OBJECT 183 +# define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +# define ASN1_R_ILLEGAL_TAGGED_ANY 127 +# define ASN1_R_ILLEGAL_TIME_VALUE 184 +# define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 +# define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +# define ASN1_R_INVALID_DIGIT 130 +# define ASN1_R_INVALID_MIME_TYPE 205 +# define ASN1_R_INVALID_MODIFIER 186 +# define ASN1_R_INVALID_NUMBER 187 +# define ASN1_R_INVALID_OBJECT_ENCODING 216 +# define ASN1_R_INVALID_SEPARATOR 131 +# define ASN1_R_INVALID_TIME_FORMAT 132 +# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +# define ASN1_R_INVALID_UTF8STRING 134 +# define ASN1_R_IV_TOO_LARGE 135 +# define ASN1_R_LENGTH_ERROR 136 +# define ASN1_R_LIST_ERROR 188 +# define ASN1_R_MIME_NO_CONTENT_TYPE 206 +# define ASN1_R_MIME_PARSE_ERROR 207 +# define ASN1_R_MIME_SIG_PARSE_ERROR 208 +# define ASN1_R_MISSING_EOC 137 +# define ASN1_R_MISSING_SECOND_NUMBER 138 +# define ASN1_R_MISSING_VALUE 189 +# define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +# define ASN1_R_MSTRING_WRONG_TAG 140 +# define ASN1_R_NESTED_ASN1_STRING 197 +# define ASN1_R_NESTED_TOO_DEEP 219 +# define ASN1_R_NON_HEX_CHARACTERS 141 +# define ASN1_R_NOT_ASCII_FORMAT 190 +# define ASN1_R_NOT_ENOUGH_DATA 142 +# define ASN1_R_NO_CONTENT_TYPE 209 +# define ASN1_R_NO_DEFAULT_DIGEST 201 +# define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +# define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +# define ASN1_R_NO_MULTIPART_BOUNDARY 211 +# define ASN1_R_NO_SIG_CONTENT_TYPE 212 +# define ASN1_R_NULL_IS_WRONG_LENGTH 144 +# define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +# define ASN1_R_ODD_NUMBER_OF_CHARS 145 +# define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146 +# define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +# define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +# define ASN1_R_SHORT_LINE 150 +# define ASN1_R_SIG_INVALID_MIME_TYPE 213 +# define ASN1_R_STREAMING_NOT_SUPPORTED 202 +# define ASN1_R_STRING_TOO_LONG 151 +# define ASN1_R_STRING_TOO_SHORT 152 +# define ASN1_R_TAG_VALUE_TOO_HIGH 153 +# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +# define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +# define ASN1_R_TOO_LONG 155 +# define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +# define ASN1_R_TYPE_NOT_PRIMITIVE 218 +# define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 +# define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 +# define ASN1_R_UNEXPECTED_EOC 159 +# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +# define ASN1_R_UNKNOWN_FORMAT 160 +# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +# define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +# define ASN1_R_UNKNOWN_TAG 194 +# define ASN1_R_UNKOWN_FORMAT 195 +# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +# define ASN1_R_UNSUPPORTED_CIPHER 165 +# define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 +# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +# define ASN1_R_UNSUPPORTED_TYPE 196 +# define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +# define ASN1_R_WRONG_TAG 168 +# define ASN1_R_WRONG_TYPE 169 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Sources/COpenSSL/asn1_.c b/Sources/COpenSSL/asn1_.c new file mode 100644 index 00000000..36299ec2 --- /dev/null +++ b/Sources/COpenSSL/asn1_.c @@ -0,0 +1,2096 @@ +/* crypto/asn1/asn1_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "asn1.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason) + +static ERR_STRING_DATA ASN1_str_functs[] = { + {ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"}, + {ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"}, + {ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"}, + {ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"}, + {ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"}, + {ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"}, + {ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"}, + {ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"}, + {ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"}, + {ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"}, + {ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"}, + {ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"}, + {ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"}, + {ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"}, + {ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"}, + {ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"}, + {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"}, + {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"}, + {ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"}, + {ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"}, + {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"}, + {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"}, + {ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"}, + {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"}, + {ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"}, + {ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"}, + {ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"}, + {ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"}, + {ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"}, + {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"}, + {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"}, + {ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"}, + {ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"}, + {ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"}, + {ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"}, + {ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"}, + {ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"}, + {ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"}, + {ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"}, + {ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"}, + {ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"}, + {ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"}, + {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"}, + {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"}, + {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"}, + {ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"}, + {ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"}, + {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), + "ASN1_TYPE_get_int_octetstring"}, + {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"}, + {ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"}, + {ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"}, + {ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"}, + {ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"}, + {ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"}, + {ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"}, + {ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"}, + {ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"}, + {ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"}, + {ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"}, + {ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"}, + {ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"}, + {ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"}, + {ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"}, + {ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"}, + {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"}, + {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"}, + {ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"}, + {ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"}, + {ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"}, + {ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"}, + {ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"}, + {ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"}, + {ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"}, + {ERR_FUNC(ASN1_F_DO_BUF), "DO_BUF"}, + {ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"}, + {ERR_FUNC(ASN1_F_I2D_ASN1_BOOLEAN), "i2d_ASN1_BOOLEAN"}, + {ERR_FUNC(ASN1_F_I2D_ASN1_OBJECT), "i2d_ASN1_OBJECT"}, + {ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"}, + {ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"}, + {ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"}, + {ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"}, + {ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"}, + {ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"}, + {ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"}, + {ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"}, + {ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"}, + {ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"}, + {ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"}, + {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"}, + {ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"}, + {ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"}, + {ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"}, + {ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"}, + {ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"}, + {ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"}, + {ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"}, + {ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"}, + {ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"}, + {ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"}, + {ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"}, + {ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"}, + {ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"}, + {0, NULL} +}; + +static ERR_STRING_DATA ASN1_str_reasons[] = { + {ERR_REASON(ASN1_R_ADDING_OBJECT), "adding object"}, + {ERR_REASON(ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"}, + {ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR), "asn1 sig parse error"}, + {ERR_REASON(ASN1_R_AUX_ERROR), "aux error"}, + {ERR_REASON(ASN1_R_BAD_CLASS), "bad class"}, + {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"}, + {ERR_REASON(ASN1_R_BAD_PASSWORD_READ), "bad password read"}, + {ERR_REASON(ASN1_R_BAD_TAG), "bad tag"}, + {ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), + "bmpstring is wrong length"}, + {ERR_REASON(ASN1_R_BN_LIB), "bn lib"}, + {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"}, + {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), + "cipher has no object identifier"}, + {ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"}, + {ERR_REASON(ASN1_R_DATA_IS_WRONG), "data is wrong"}, + {ERR_REASON(ASN1_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(ASN1_R_DECODING_ERROR), "decoding error"}, + {ERR_REASON(ASN1_R_DEPTH_EXCEEDED), "depth exceeded"}, + {ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED), + "digest and key type not supported"}, + {ERR_REASON(ASN1_R_ENCODE_ERROR), "encode error"}, + {ERR_REASON(ASN1_R_ERROR_GETTING_TIME), "error getting time"}, + {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"}, + {ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT), + "error parsing set element"}, + {ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS), + "error setting cipher params"}, + {ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER), "expecting an integer"}, + {ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT), "expecting an object"}, + {ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN), "expecting a boolean"}, + {ERR_REASON(ASN1_R_EXPECTING_A_TIME), "expecting a time"}, + {ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"}, + {ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED), + "explicit tag not constructed"}, + {ERR_REASON(ASN1_R_FIELD_MISSING), "field missing"}, + {ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE), "first num too large"}, + {ERR_REASON(ASN1_R_HEADER_TOO_LONG), "header too long"}, + {ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"}, + {ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean"}, + {ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS), "illegal characters"}, + {ERR_REASON(ASN1_R_ILLEGAL_FORMAT), "illegal format"}, + {ERR_REASON(ASN1_R_ILLEGAL_HEX), "illegal hex"}, + {ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG), "illegal implicit tag"}, + {ERR_REASON(ASN1_R_ILLEGAL_INTEGER), "illegal integer"}, + {ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"}, + {ERR_REASON(ASN1_R_ILLEGAL_NULL), "illegal null"}, + {ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE), "illegal null value"}, + {ERR_REASON(ASN1_R_ILLEGAL_OBJECT), "illegal object"}, + {ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY), "illegal optional any"}, + {ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE), + "illegal options on item template"}, + {ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY), "illegal tagged any"}, + {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE), "illegal time value"}, + {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"}, + {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG), + "integer too large for long"}, + {ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT), + "invalid bit string bits left"}, + {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"}, + {ERR_REASON(ASN1_R_INVALID_DIGIT), "invalid digit"}, + {ERR_REASON(ASN1_R_INVALID_MIME_TYPE), "invalid mime type"}, + {ERR_REASON(ASN1_R_INVALID_MODIFIER), "invalid modifier"}, + {ERR_REASON(ASN1_R_INVALID_NUMBER), "invalid number"}, + {ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"}, + {ERR_REASON(ASN1_R_INVALID_SEPARATOR), "invalid separator"}, + {ERR_REASON(ASN1_R_INVALID_TIME_FORMAT), "invalid time format"}, + {ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH), + "invalid universalstring length"}, + {ERR_REASON(ASN1_R_INVALID_UTF8STRING), "invalid utf8string"}, + {ERR_REASON(ASN1_R_IV_TOO_LARGE), "iv too large"}, + {ERR_REASON(ASN1_R_LENGTH_ERROR), "length error"}, + {ERR_REASON(ASN1_R_LIST_ERROR), "list error"}, + {ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE), "mime no content type"}, + {ERR_REASON(ASN1_R_MIME_PARSE_ERROR), "mime parse error"}, + {ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"}, + {ERR_REASON(ASN1_R_MISSING_EOC), "missing eoc"}, + {ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"}, + {ERR_REASON(ASN1_R_MISSING_VALUE), "missing value"}, + {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"}, + {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"}, + {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"}, + {ERR_REASON(ASN1_R_NESTED_TOO_DEEP), "nested too deep"}, + {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"}, + {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"}, + {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"}, + {ERR_REASON(ASN1_R_NO_CONTENT_TYPE), "no content type"}, + {ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"}, + {ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE), + "no multipart body failure"}, + {ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"}, + {ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE), "no sig content type"}, + {ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH), "null is wrong length"}, + {ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"}, + {ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS), "odd number of chars"}, + {ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING), + "private key header missing"}, + {ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"}, + {ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"}, + {ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"}, + {ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG), + "sequence or set needs config"}, + {ERR_REASON(ASN1_R_SHORT_LINE), "short line"}, + {ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"}, + {ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"}, + {ERR_REASON(ASN1_R_STRING_TOO_LONG), "string too long"}, + {ERR_REASON(ASN1_R_STRING_TOO_SHORT), "string too short"}, + {ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH), "tag value too high"}, + {ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), + "the asn1 object identifier is not known for this md"}, + {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"}, + {ERR_REASON(ASN1_R_TOO_LONG), "too long"}, + {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED), "type not constructed"}, + {ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE), "type not primitive"}, + {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY), "unable to decode rsa key"}, + {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY), + "unable to decode rsa private key"}, + {ERR_REASON(ASN1_R_UNEXPECTED_EOC), "unexpected eoc"}, + {ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), + "universalstring is wrong length"}, + {ERR_REASON(ASN1_R_UNKNOWN_FORMAT), "unknown format"}, + {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), + "unknown message digest algorithm"}, + {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE), "unknown object type"}, + {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"}, + {ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM), + "unknown signature algorithm"}, + {ERR_REASON(ASN1_R_UNKNOWN_TAG), "unknown tag"}, + {ERR_REASON(ASN1_R_UNKOWN_FORMAT), "unknown format"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE), + "unsupported any defined by type"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM), + "unsupported encryption algorithm"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE), + "unsupported public key type"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_TYPE), "unsupported type"}, + {ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"}, + {ERR_REASON(ASN1_R_WRONG_TAG), "wrong tag"}, + {ERR_REASON(ASN1_R_WRONG_TYPE), "wrong type"}, + {0, NULL} +}; + +#endif + +void ERR_load_ASN1_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) { + ERR_load_strings(0, ASN1_str_functs); + ERR_load_strings(0, ASN1_str_reasons); + } +#endif +} +/* asn1_gen.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +// #include "asn1.h" +#include "x509v3.h" + +#define ASN1_GEN_FLAG 0x10000 +#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) +#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) +#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) +#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) +#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) +#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) +#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) +#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) + +#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} + +#define ASN1_FLAG_EXP_MAX 20 +/* Maximum number of nested sequences */ +#define ASN1_GEN_SEQ_MAX_DEPTH 50 + +/* Input formats */ + +/* ASCII: default */ +#define ASN1_GEN_FORMAT_ASCII 1 +/* UTF8 */ +#define ASN1_GEN_FORMAT_UTF8 2 +/* Hex */ +#define ASN1_GEN_FORMAT_HEX 3 +/* List of bits */ +#define ASN1_GEN_FORMAT_BITLIST 4 + +struct tag_name_st { + const char *strnam; + int len; + int tag; +}; + +typedef struct { + int exp_tag; + int exp_class; + int exp_constructed; + int exp_pad; + long exp_len; +} tag_exp_type; + +typedef struct { + int imp_tag; + int imp_class; + int utype; + int format; + const char *str; + tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; + int exp_count; +} tag_exp_arg; + +static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, + int *perr); +static int bitstr_cb(const char *elem, int len, void *bitstr); +static int asn1_cb(const char *elem, int len, void *bitstr); +static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, + int exp_constructed, int exp_pad, int imp_ok); +static int parse_tagging(const char *vstart, int vlen, int *ptag, + int *pclass); +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, + int depth, int *perr); +static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); +static int asn1_str2tag(const char *tagstr, int len); + +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) +{ + X509V3_CTX cnf; + + if (!nconf) + return ASN1_generate_v3(str, NULL); + + X509V3_set_nconf(&cnf, nconf); + return ASN1_generate_v3(str, &cnf); +} + +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) +{ + int err = 0; + ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); + if (err) + ASN1err(ASN1_F_ASN1_GENERATE_V3, err); + return ret; +} + +static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, + int *perr) +{ + ASN1_TYPE *ret; + tag_exp_arg asn1_tags; + tag_exp_type *etmp; + + int i, len; + + unsigned char *orig_der = NULL, *new_der = NULL; + const unsigned char *cpy_start; + unsigned char *p; + const unsigned char *cp; + int cpy_len; + long hdr_len; + int hdr_constructed = 0, hdr_tag, hdr_class; + int r; + + asn1_tags.imp_tag = -1; + asn1_tags.imp_class = -1; + asn1_tags.format = ASN1_GEN_FORMAT_ASCII; + asn1_tags.exp_count = 0; + if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { + *perr = ASN1_R_UNKNOWN_TAG; + return NULL; + } + + if ((asn1_tags.utype == V_ASN1_SEQUENCE) + || (asn1_tags.utype == V_ASN1_SET)) { + if (!cnf) { + *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; + return NULL; + } + if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { + *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; + return NULL; + } + ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); + } else + ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); + + if (!ret) + return NULL; + + /* If no tagging return base type */ + if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) + return ret; + + /* Generate the encoding */ + cpy_len = i2d_ASN1_TYPE(ret, &orig_der); + ASN1_TYPE_free(ret); + ret = NULL; + /* Set point to start copying for modified encoding */ + cpy_start = orig_der; + + /* Do we need IMPLICIT tagging? */ + if (asn1_tags.imp_tag != -1) { + /* If IMPLICIT we will replace the underlying tag */ + /* Skip existing tag+len */ + r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, + cpy_len); + if (r & 0x80) + goto err; + /* Update copy length */ + cpy_len -= cpy_start - orig_der; + /* + * For IMPLICIT tagging the length should match the original length + * and constructed flag should be consistent. + */ + if (r & 0x1) { + /* Indefinite length constructed */ + hdr_constructed = 2; + hdr_len = 0; + } else + /* Just retain constructed flag */ + hdr_constructed = r & V_ASN1_CONSTRUCTED; + /* + * Work out new length with IMPLICIT tag: ignore constructed because + * it will mess up if indefinite length + */ + len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); + } else + len = cpy_len; + + /* Work out length in any EXPLICIT, starting from end */ + + for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; + i < asn1_tags.exp_count; i++, etmp--) { + /* Content length: number of content octets + any padding */ + len += etmp->exp_pad; + etmp->exp_len = len; + /* Total object length: length including new header */ + len = ASN1_object_size(0, len, etmp->exp_tag); + } + + /* Allocate buffer for new encoding */ + + new_der = OPENSSL_malloc(len); + if (!new_der) + goto err; + + /* Generate tagged encoding */ + + p = new_der; + + /* Output explicit tags first */ + + for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; + i++, etmp++) { + ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, + etmp->exp_tag, etmp->exp_class); + if (etmp->exp_pad) + *p++ = 0; + } + + /* If IMPLICIT, output tag */ + + if (asn1_tags.imp_tag != -1) { + if (asn1_tags.imp_class == V_ASN1_UNIVERSAL + && (asn1_tags.imp_tag == V_ASN1_SEQUENCE + || asn1_tags.imp_tag == V_ASN1_SET)) + hdr_constructed = V_ASN1_CONSTRUCTED; + ASN1_put_object(&p, hdr_constructed, hdr_len, + asn1_tags.imp_tag, asn1_tags.imp_class); + } + + /* Copy across original encoding */ + memcpy(p, cpy_start, cpy_len); + + cp = new_der; + + /* Obtain new ASN1_TYPE structure */ + ret = d2i_ASN1_TYPE(NULL, &cp, len); + + err: + if (orig_der) + OPENSSL_free(orig_der); + if (new_der) + OPENSSL_free(new_der); + + return ret; + +} + +static int asn1_cb(const char *elem, int len, void *bitstr) +{ + tag_exp_arg *arg = bitstr; + int i; + int utype; + int vlen = 0; + const char *p, *vstart = NULL; + + int tmp_tag, tmp_class; + + if (elem == NULL) + return -1; + + for (i = 0, p = elem; i < len; p++, i++) { + /* Look for the ':' in name value pairs */ + if (*p == ':') { + vstart = p + 1; + vlen = len - (vstart - elem); + len = p - elem; + break; + } + } + + utype = asn1_str2tag(elem, len); + + if (utype == -1) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); + ERR_add_error_data(2, "tag=", elem); + return -1; + } + + /* If this is not a modifier mark end of string and exit */ + if (!(utype & ASN1_GEN_FLAG)) { + arg->utype = utype; + arg->str = vstart; + /* If no value and not end of string, error */ + if (!vstart && elem[len]) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); + return -1; + } + return 0; + } + + switch (utype) { + + case ASN1_GEN_FLAG_IMP: + /* Check for illegal multiple IMPLICIT tagging */ + if (arg->imp_tag != -1) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); + return -1; + } + if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) + return -1; + break; + + case ASN1_GEN_FLAG_EXP: + + if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) + return -1; + if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) + return -1; + break; + + case ASN1_GEN_FLAG_SEQWRAP: + if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_SETWRAP: + if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_BITWRAP: + if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_OCTWRAP: + if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_FORMAT: + if (!vstart) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + if (!strncmp(vstart, "ASCII", 5)) + arg->format = ASN1_GEN_FORMAT_ASCII; + else if (!strncmp(vstart, "UTF8", 4)) + arg->format = ASN1_GEN_FORMAT_UTF8; + else if (!strncmp(vstart, "HEX", 3)) + arg->format = ASN1_GEN_FORMAT_HEX; + else if (!strncmp(vstart, "BITLIST", 7)) + arg->format = ASN1_GEN_FORMAT_BITLIST; + else { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); + return -1; + } + break; + + } + + return 1; + +} + +static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) +{ + char erch[2]; + long tag_num; + char *eptr; + if (!vstart) + return 0; + tag_num = strtoul(vstart, &eptr, 10); + /* Check we haven't gone past max length: should be impossible */ + if (eptr && *eptr && (eptr > vstart + vlen)) + return 0; + if (tag_num < 0) { + ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); + return 0; + } + *ptag = tag_num; + /* If we have non numeric characters, parse them */ + if (eptr) + vlen -= eptr - vstart; + else + vlen = 0; + if (vlen) { + switch (*eptr) { + + case 'U': + *pclass = V_ASN1_UNIVERSAL; + break; + + case 'A': + *pclass = V_ASN1_APPLICATION; + break; + + case 'P': + *pclass = V_ASN1_PRIVATE; + break; + + case 'C': + *pclass = V_ASN1_CONTEXT_SPECIFIC; + break; + + default: + erch[0] = *eptr; + erch[1] = 0; + ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); + ERR_add_error_data(2, "Char=", erch); + return 0; + break; + + } + } else + *pclass = V_ASN1_CONTEXT_SPECIFIC; + + return 1; + +} + +/* Handle multiple types: SET and SEQUENCE */ + +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, + int depth, int *perr) +{ + ASN1_TYPE *ret = NULL; + STACK_OF(ASN1_TYPE) *sk = NULL; + STACK_OF(CONF_VALUE) *sect = NULL; + unsigned char *der = NULL; + int derlen; + int i; + sk = sk_ASN1_TYPE_new_null(); + if (!sk) + goto bad; + if (section) { + if (!cnf) + goto bad; + sect = X509V3_get_section(cnf, (char *)section); + if (!sect) + goto bad; + for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { + ASN1_TYPE *typ = + generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, + depth + 1, perr); + if (!typ) + goto bad; + if (!sk_ASN1_TYPE_push(sk, typ)) + goto bad; + } + } + + /* + * Now we has a STACK of the components, convert to the correct form + */ + + if (utype == V_ASN1_SET) + derlen = i2d_ASN1_SET_ANY(sk, &der); + else + derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); + + if (derlen < 0) + goto bad; + + if (!(ret = ASN1_TYPE_new())) + goto bad; + + if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) + goto bad; + + ret->type = utype; + + ret->value.asn1_string->data = der; + ret->value.asn1_string->length = derlen; + + der = NULL; + + bad: + + if (der) + OPENSSL_free(der); + + if (sk) + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + if (sect) + X509V3_section_free(cnf, sect); + + return ret; +} + +static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, + int exp_constructed, int exp_pad, int imp_ok) +{ + tag_exp_type *exp_tmp; + /* Can only have IMPLICIT if permitted */ + if ((arg->imp_tag != -1) && !imp_ok) { + ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); + return 0; + } + + if (arg->exp_count == ASN1_FLAG_EXP_MAX) { + ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); + return 0; + } + + exp_tmp = &arg->exp_list[arg->exp_count++]; + + /* + * If IMPLICIT set tag to implicit value then reset implicit tag since it + * has been used. + */ + if (arg->imp_tag != -1) { + exp_tmp->exp_tag = arg->imp_tag; + exp_tmp->exp_class = arg->imp_class; + arg->imp_tag = -1; + arg->imp_class = -1; + } else { + exp_tmp->exp_tag = exp_tag; + exp_tmp->exp_class = exp_class; + } + exp_tmp->exp_constructed = exp_constructed; + exp_tmp->exp_pad = exp_pad; + + return 1; +} + +static int asn1_str2tag(const char *tagstr, int len) +{ + unsigned int i; + static const struct tag_name_st *tntmp, tnst[] = { + ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), + ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), + ASN1_GEN_STR("NULL", V_ASN1_NULL), + ASN1_GEN_STR("INT", V_ASN1_INTEGER), + ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), + ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), + ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), + ASN1_GEN_STR("OID", V_ASN1_OBJECT), + ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), + ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), + ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), + ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), + ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), + ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), + ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), + ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), + ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), + ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), + ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), + ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), + ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), + ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), + ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), + ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), + ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), + ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), + ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), + ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), + ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), + ASN1_GEN_STR("T61", V_ASN1_T61STRING), + ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), + ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), + ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), + ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), + ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), + ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), + + /* Special cases */ + ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), + ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), + ASN1_GEN_STR("SET", V_ASN1_SET), + /* type modifiers */ + /* Explicit tag */ + ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), + ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), + /* Implicit tag */ + ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), + ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), + /* OCTET STRING wrapper */ + ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), + /* SEQUENCE wrapper */ + ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), + /* SET wrapper */ + ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), + /* BIT STRING wrapper */ + ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), + ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), + ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), + }; + + if (len == -1) + len = strlen(tagstr); + + tntmp = tnst; + for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { + if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) + return tntmp->tag; + } + + return -1; +} + +static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) +{ + ASN1_TYPE *atmp = NULL; + + CONF_VALUE vtmp; + + unsigned char *rdata; + long rdlen; + + int no_unused = 1; + + if (!(atmp = ASN1_TYPE_new())) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!str) + str = ""; + + switch (utype) { + + case V_ASN1_NULL: + if (str && *str) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); + goto bad_form; + } + break; + + case V_ASN1_BOOLEAN: + if (format != ASN1_GEN_FORMAT_ASCII) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); + goto bad_form; + } + vtmp.name = NULL; + vtmp.section = NULL; + vtmp.value = (char *)str; + if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); + goto bad_str; + } + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + if (format != ASN1_GEN_FORMAT_ASCII) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); + goto bad_str; + } + break; + + case V_ASN1_OBJECT: + if (format != ASN1_GEN_FORMAT_ASCII) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); + goto bad_str; + } + break; + + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + if (format != ASN1_GEN_FORMAT_ASCII) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + atmp->value.asn1_string->type = utype; + if (!ASN1_TIME_check(atmp->value.asn1_string)) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); + goto bad_str; + } + + break; + + case V_ASN1_BMPSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_IA5STRING: + case V_ASN1_T61STRING: + case V_ASN1_UTF8STRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_NUMERICSTRING: + + if (format == ASN1_GEN_FORMAT_ASCII) + format = MBSTRING_ASC; + else if (format == ASN1_GEN_FORMAT_UTF8) + format = MBSTRING_UTF8; + else { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); + goto bad_form; + } + + if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, + -1, format, ASN1_tag2bit(utype)) <= 0) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + + break; + + case V_ASN1_BIT_STRING: + + case V_ASN1_OCTET_STRING: + + if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + goto bad_form; + } + + if (format == ASN1_GEN_FORMAT_HEX) { + + if (!(rdata = string_to_hex((char *)str, &rdlen))) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); + goto bad_str; + } + + atmp->value.asn1_string->data = rdata; + atmp->value.asn1_string->length = rdlen; + atmp->value.asn1_string->type = utype; + + } else if (format == ASN1_GEN_FORMAT_ASCII) + ASN1_STRING_set(atmp->value.asn1_string, str, -1); + else if ((format == ASN1_GEN_FORMAT_BITLIST) + && (utype == V_ASN1_BIT_STRING)) { + if (!CONF_parse_list + (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); + goto bad_str; + } + no_unused = 0; + + } else { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); + goto bad_form; + } + + if ((utype == V_ASN1_BIT_STRING) && no_unused) { + atmp->value.asn1_string->flags + &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; + } + + break; + + default: + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); + goto bad_str; + break; + } + + atmp->type = utype; + return atmp; + + bad_str: + ERR_add_error_data(2, "string=", str); + bad_form: + + ASN1_TYPE_free(atmp); + return NULL; + +} + +static int bitstr_cb(const char *elem, int len, void *bitstr) +{ + long bitnum; + char *eptr; + if (!elem) + return 0; + bitnum = strtoul(elem, &eptr, 10); + if (eptr && *eptr && (eptr != elem + len)) + return 0; + if (bitnum < 0) { + ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); + return 0; + } + if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { + ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} +/* crypto/asn1/asn1_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "asn1.h" +#include "asn1_mac.h" + +static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, + long max); +static void asn1_put_length(unsigned char **pp, int length); +const char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT; + +static int _asn1_check_infinite_end(const unsigned char **p, long len) +{ + /* + * If there is 0 or 1 byte left, the length check should pick things up + */ + if (len <= 0) + return (1); + else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) { + (*p) += 2; + return (1); + } + return (0); +} + +int ASN1_check_infinite_end(unsigned char **p, long len) +{ + return _asn1_check_infinite_end((const unsigned char **)p, len); +} + +int ASN1_const_check_infinite_end(const unsigned char **p, long len) +{ + return _asn1_check_infinite_end(p, len); +} + +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax) +{ + int i, ret; + long l; + const unsigned char *p = *pp; + int tag, xclass, inf; + long max = omax; + + if (!max) + goto err; + ret = (*p & V_ASN1_CONSTRUCTED); + xclass = (*p & V_ASN1_PRIVATE); + i = *p & V_ASN1_PRIMITIVE_TAG; + if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */ + p++; + if (--max == 0) + goto err; + l = 0; + while (*p & 0x80) { + l <<= 7L; + l |= *(p++) & 0x7f; + if (--max == 0) + goto err; + if (l > (INT_MAX >> 7L)) + goto err; + } + l <<= 7L; + l |= *(p++) & 0x7f; + tag = (int)l; + if (--max == 0) + goto err; + } else { + tag = i; + p++; + if (--max == 0) + goto err; + } + *ptag = tag; + *pclass = xclass; + if (!asn1_get_length(&p, &inf, plength, max)) + goto err; + + if (inf && !(ret & V_ASN1_CONSTRUCTED)) + goto err; + +#if 0 + fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n", + (int)p, *plength, omax, (int)*pp, (int)(p + *plength), + (int)(omax + *pp)); + +#endif + if (*plength > (omax - (p - *pp))) { + ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG); + /* + * Set this so that even if things are not long enough the values are + * set correctly + */ + ret |= 0x80; + } + *pp = p; + return (ret | inf); + err: + ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG); + return (0x80); +} + +static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, + long max) +{ + const unsigned char *p = *pp; + unsigned long ret = 0; + unsigned long i; + + if (max-- < 1) + return 0; + if (*p == 0x80) { + *inf = 1; + ret = 0; + p++; + } else { + *inf = 0; + i = *p & 0x7f; + if (*(p++) & 0x80) { + if (i > sizeof(ret) || max < (long)i) + return 0; + while (i-- > 0) { + ret <<= 8L; + ret |= *(p++); + } + } else + ret = i; + } + if (ret > LONG_MAX) + return 0; + *pp = p; + *rl = (long)ret; + return 1; +} + +/* + * class 0 is constructed constructed == 2 for indefinite length constructed + */ +void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, + int xclass) +{ + unsigned char *p = *pp; + int i, ttag; + + i = (constructed) ? V_ASN1_CONSTRUCTED : 0; + i |= (xclass & V_ASN1_PRIVATE); + if (tag < 31) + *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); + else { + *(p++) = i | V_ASN1_PRIMITIVE_TAG; + for (i = 0, ttag = tag; ttag > 0; i++) + ttag >>= 7; + ttag = i; + while (i-- > 0) { + p[i] = tag & 0x7f; + if (i != (ttag - 1)) + p[i] |= 0x80; + tag >>= 7; + } + p += ttag; + } + if (constructed == 2) + *(p++) = 0x80; + else + asn1_put_length(&p, length); + *pp = p; +} + +int ASN1_put_eoc(unsigned char **pp) +{ + unsigned char *p = *pp; + *p++ = 0; + *p++ = 0; + *pp = p; + return 2; +} + +static void asn1_put_length(unsigned char **pp, int length) +{ + unsigned char *p = *pp; + int i, l; + if (length <= 127) + *(p++) = (unsigned char)length; + else { + l = length; + for (i = 0; l > 0; i++) + l >>= 8; + *(p++) = i | 0x80; + l = i; + while (i-- > 0) { + p[i] = length & 0xff; + length >>= 8; + } + p += l; + } + *pp = p; +} + +int ASN1_object_size(int constructed, int length, int tag) +{ + int ret = 1; + if (length < 0) + return -1; + if (tag >= 31) { + while (tag > 0) { + tag >>= 7; + ret++; + } + } + if (constructed == 2) { + ret += 3; + } else { + ret++; + if (length > 127) { + int tmplen = length; + while (tmplen > 0) { + tmplen >>= 8; + ret++; + } + } + } + if (ret >= INT_MAX - length) + return -1; + return ret + length; +} + +static int _asn1_Finish(ASN1_const_CTX *c) +{ + if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) { + if (!ASN1_const_check_infinite_end(&c->p, c->slen)) { + c->error = ERR_R_MISSING_ASN1_EOS; + return (0); + } + } + if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) { + c->error = ERR_R_ASN1_LENGTH_MISMATCH; + return (0); + } + return (1); +} + +int asn1_Finish(ASN1_CTX *c) +{ + return _asn1_Finish((ASN1_const_CTX *)c); +} + +int asn1_const_Finish(ASN1_const_CTX *c) +{ + return _asn1_Finish(c); +} + +int asn1_GetSequence(ASN1_const_CTX *c, long *length) +{ + const unsigned char *q; + + q = c->p; + c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass), + *length); + if (c->inf & 0x80) { + c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL; + return (0); + } + if (c->tag != V_ASN1_SEQUENCE) { + c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE; + return (0); + } + (*length) -= (c->p - q); + if (c->max && (*length < 0)) { + c->error = ERR_R_ASN1_LENGTH_MISMATCH; + return (0); + } + if (c->inf == (1 | V_ASN1_CONSTRUCTED)) + c->slen = *length; + c->eos = 0; + return (1); +} + +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) +{ + if (str == NULL) + return 0; + dst->type = str->type; + if (!ASN1_STRING_set(dst, str->data, str->length)) + return 0; + dst->flags = str->flags; + return 1; +} + +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) +{ + ASN1_STRING *ret; + if (!str) + return NULL; + ret = ASN1_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_STRING_copy(ret, str)) { + ASN1_STRING_free(ret); + return NULL; + } + return ret; +} + +int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) +{ + unsigned char *c; + const char *data = _data; + + if (len < 0) { + if (data == NULL) + return (0); + else + len = strlen(data); + } + if ((str->length <= len) || (str->data == NULL)) { + c = str->data; + if (c == NULL) + str->data = OPENSSL_malloc(len + 1); + else + str->data = OPENSSL_realloc(c, len + 1); + + if (str->data == NULL) { + ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE); + str->data = c; + return (0); + } + } + str->length = len; + if (data != NULL) { + memcpy(str->data, data, len); + /* an allowance for strings :-) */ + str->data[len] = '\0'; + } + return (1); +} + +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) +{ + if (str->data) + OPENSSL_free(str->data); + str->data = data; + str->length = len; +} + +ASN1_STRING *ASN1_STRING_new(void) +{ + return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); +} + +ASN1_STRING *ASN1_STRING_type_new(int type) +{ + ASN1_STRING *ret; + + ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); + if (ret == NULL) { + ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->length = 0; + ret->type = type; + ret->data = NULL; + ret->flags = 0; + return (ret); +} + +void ASN1_STRING_free(ASN1_STRING *a) +{ + if (a == NULL) + return; + if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) + OPENSSL_free(a->data); + OPENSSL_free(a); +} + +void ASN1_STRING_clear_free(ASN1_STRING *a) +{ + if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) + OPENSSL_cleanse(a->data, a->length); + ASN1_STRING_free(a); +} + +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int i; + + i = (a->length - b->length); + if (i == 0) { + i = memcmp(a->data, b->data, a->length); + if (i == 0) + return (a->type - b->type); + else + return (i); + } else + return (i); +} + +void asn1_add_error(const unsigned char *address, int offset) +{ + char buf1[DECIMAL_SIZE(address) + 1], buf2[DECIMAL_SIZE(offset) + 1]; + + BIO_snprintf(buf1, sizeof(buf1), "%lu", (unsigned long)address); + BIO_snprintf(buf2, sizeof(buf2), "%d", offset); + ERR_add_error_data(4, "address=", buf1, " offset=", buf2); +} + +int ASN1_STRING_length(const ASN1_STRING *x) +{ + return M_ASN1_STRING_length(x); +} + +void ASN1_STRING_length_set(ASN1_STRING *x, int len) +{ + M_ASN1_STRING_length_set(x, len); + return; +} + +int ASN1_STRING_type(ASN1_STRING *x) +{ + return M_ASN1_STRING_type(x); +} + +unsigned char *ASN1_STRING_data(ASN1_STRING *x) +{ + return M_ASN1_STRING_data(x); +} +/* crypto/asn1/asn1_par.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "buffer.h" +#include "objects.h" +// #include "asn1.h" + +#ifndef ASN1_PARSE_MAXDEPTH +#define ASN1_PARSE_MAXDEPTH 128 +#endif + +static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, + int indent); +static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, + int offset, int depth, int indent, int dump); +static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, + int indent) +{ + static const char fmt[] = "%-18s"; + char str[128]; + const char *p; + + if (constructed & V_ASN1_CONSTRUCTED) + p = "cons: "; + else + p = "prim: "; + if (BIO_write(bp, p, 6) < 6) + goto err; + BIO_indent(bp, indent, 128); + + p = str; + if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) + BIO_snprintf(str, sizeof(str), "priv [ %d ] ", tag); + else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) + BIO_snprintf(str, sizeof(str), "cont [ %d ]", tag); + else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) + BIO_snprintf(str, sizeof(str), "appl [ %d ]", tag); + else if (tag > 30) + BIO_snprintf(str, sizeof(str), "", tag); + else + p = ASN1_tag2str(tag); + + if (BIO_printf(bp, fmt, p) <= 0) + goto err; + return (1); + err: + return (0); +} + +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent) +{ + return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0)); +} + +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump) +{ + return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump)); +} + +static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, + int offset, int depth, int indent, int dump) +{ + const unsigned char *p, *ep, *tot, *op, *opp; + long len; + int tag, xclass, ret = 0; + int nl, hl, j, r; + ASN1_OBJECT *o = NULL; + ASN1_OCTET_STRING *os = NULL; + /* ASN1_BMPSTRING *bmp=NULL; */ + int dump_indent; + +#if 0 + dump_indent = indent; +#else + dump_indent = 6; /* Because we know BIO_dump_indent() */ +#endif + + if (depth > ASN1_PARSE_MAXDEPTH) { + BIO_puts(bp, "BAD RECURSION DEPTH\n"); + return 0; + } + + p = *pp; + tot = p + length; + op = p - 1; + while ((p < tot) && (op < p)) { + op = p; + j = ASN1_get_object(&p, &len, &tag, &xclass, length); +#ifdef LINT + j = j; +#endif + if (j & 0x80) { + if (BIO_write(bp, "Error in encoding\n", 18) <= 0) + goto end; + ret = 0; + goto end; + } + hl = (p - op); + length -= hl; + /* + * if j == 0x21 it is a constructed indefinite length object + */ + if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp)) + <= 0) + goto end; + + if (j != (V_ASN1_CONSTRUCTED | 1)) { + if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ", + depth, (long)hl, len) <= 0) + goto end; + } else { + if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0) + goto end; + } + if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0)) + goto end; + if (j & V_ASN1_CONSTRUCTED) { + const unsigned char *sp; + + ep = p + len; + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + if (len > length) { + BIO_printf(bp, "length is greater than %ld\n", length); + ret = 0; + goto end; + } + if ((j == 0x21) && (len == 0)) { + sp = p; + for (;;) { + r = asn1_parse2(bp, &p, (long)(tot - p), + offset + (p - *pp), depth + 1, + indent, dump); + if (r == 0) { + ret = 0; + goto end; + } + if ((r == 2) || (p >= tot)) { + len = p - sp; + break; + } + } + } else { + long tmp = len; + + while (p < ep) { + sp = p; + r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1, + indent, dump); + if (r == 0) { + ret = 0; + goto end; + } + tmp -= p - sp; + } + } + } else if (xclass != 0) { + p += len; + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + } else { + nl = 0; + if ((tag == V_ASN1_PRINTABLESTRING) || + (tag == V_ASN1_T61STRING) || + (tag == V_ASN1_IA5STRING) || + (tag == V_ASN1_VISIBLESTRING) || + (tag == V_ASN1_NUMERICSTRING) || + (tag == V_ASN1_UTF8STRING) || + (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + if ((len > 0) && BIO_write(bp, (const char *)p, (int)len) + != (int)len) + goto end; + } else if (tag == V_ASN1_OBJECT) { + opp = op; + if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + i2a_ASN1_OBJECT(bp, o); + } else { + if (BIO_write(bp, ":BAD OBJECT", 11) <= 0) + goto end; + } + } else if (tag == V_ASN1_BOOLEAN) { + int ii; + + opp = op; + ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl); + if (ii < 0) { + if (BIO_write(bp, "Bad boolean\n", 12) <= 0) + goto end; + } + BIO_printf(bp, ":%d", ii); + } else if (tag == V_ASN1_BMPSTRING) { + /* do the BMP thang */ + } else if (tag == V_ASN1_OCTET_STRING) { + int i, printable = 1; + + opp = op; + os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl); + if (os != NULL && os->length > 0) { + opp = os->data; + /* + * testing whether the octet string is printable + */ + for (i = 0; i < os->length; i++) { + if (((opp[i] < ' ') && + (opp[i] != '\n') && + (opp[i] != '\r') && + (opp[i] != '\t')) || (opp[i] > '~')) { + printable = 0; + break; + } + } + if (printable) + /* printable string */ + { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + if (BIO_write(bp, (const char *)opp, os->length) <= 0) + goto end; + } else if (!dump) + /* + * not printable => print octet string as hex dump + */ + { + if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0) + goto end; + for (i = 0; i < os->length; i++) { + if (BIO_printf(bp, "%02X", opp[i]) <= 0) + goto end; + } + } else + /* print the normal dump */ + { + if (!nl) { + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + } + if (BIO_dump_indent(bp, + (const char *)opp, + ((dump == -1 || dump > + os-> + length) ? os->length : dump), + dump_indent) <= 0) + goto end; + nl = 1; + } + } + if (os != NULL) { + M_ASN1_OCTET_STRING_free(os); + os = NULL; + } + } else if (tag == V_ASN1_INTEGER) { + ASN1_INTEGER *bs; + int i; + + opp = op; + bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl); + if (bs != NULL) { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + if (bs->type == V_ASN1_NEG_INTEGER) + if (BIO_write(bp, "-", 1) <= 0) + goto end; + for (i = 0; i < bs->length; i++) { + if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) + goto end; + } + if (bs->length == 0) { + if (BIO_write(bp, "00", 2) <= 0) + goto end; + } + } else { + if (BIO_write(bp, "BAD INTEGER", 11) <= 0) + goto end; + } + M_ASN1_INTEGER_free(bs); + } else if (tag == V_ASN1_ENUMERATED) { + ASN1_ENUMERATED *bs; + int i; + + opp = op; + bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl); + if (bs != NULL) { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + if (bs->type == V_ASN1_NEG_ENUMERATED) + if (BIO_write(bp, "-", 1) <= 0) + goto end; + for (i = 0; i < bs->length; i++) { + if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) + goto end; + } + if (bs->length == 0) { + if (BIO_write(bp, "00", 2) <= 0) + goto end; + } + } else { + if (BIO_write(bp, "BAD ENUMERATED", 14) <= 0) + goto end; + } + M_ASN1_ENUMERATED_free(bs); + } else if (len > 0 && dump) { + if (!nl) { + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + } + if (BIO_dump_indent(bp, (const char *)p, + ((dump == -1 || dump > len) ? len : dump), + dump_indent) <= 0) + goto end; + nl = 1; + } + + if (!nl) { + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + } + p += len; + if ((tag == V_ASN1_EOC) && (xclass == 0)) { + ret = 2; /* End of sequence */ + goto end; + } + } + length -= len; + } + ret = 1; + end: + if (o != NULL) + ASN1_OBJECT_free(o); + if (os != NULL) + M_ASN1_OCTET_STRING_free(os); + *pp = p; + return (ret); +} + +const char *ASN1_tag2str(int tag) +{ + static const char *const tag2str[] = { + /* 0-4 */ + "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", + /* 5-9 */ + "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", + /* 10-13 */ + "ENUMERATED", "", "UTF8STRING", "", + /* 15-17 */ + "", "", "SEQUENCE", "SET", + /* 18-20 */ + "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", + /* 21-24 */ + "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", + /* 25-27 */ + "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", + /* 28-30 */ + "UNIVERSALSTRING", "", "BMPSTRING" + }; + + if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED)) + tag &= ~0x100; + + if (tag < 0 || tag > 30) + return "(unknown)"; + return tag2str[tag]; +} diff --git a/Sources/COpenSSL/asn1_int.h b/Sources/COpenSSL/asn1_int.h new file mode 100644 index 00000000..c9fd8b12 --- /dev/null +++ b/Sources/COpenSSL/asn1_int.h @@ -0,0 +1,63 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Internal ASN1 template structures and functions: not for application use */ + +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); diff --git a/Sources/COpenSSL/asn1_locl.h b/Sources/COpenSSL/asn1_locl.h new file mode 100644 index 00000000..4c004fab --- /dev/null +++ b/Sources/COpenSSL/asn1_locl.h @@ -0,0 +1,135 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Internal ASN1 structures and functions: not for application use */ + +int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d); +int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d); + +/* ASN1 print context structure */ + +struct asn1_pctx_st { + unsigned long flags; + unsigned long nm_flags; + unsigned long cert_flags; + unsigned long oid_flags; + unsigned long str_flags; +} /* ASN1_PCTX */ ; + +/* ASN1 public key method structure */ + +struct evp_pkey_asn1_method_st { + int pkey_id; + int pkey_base_id; + unsigned long pkey_flags; + char *pem_str; + char *info; + int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub); + int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk); + int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); + int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*priv_decode) (EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf); + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); + int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*pkey_size) (const EVP_PKEY *pk); + int (*pkey_bits) (const EVP_PKEY *pk); + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, int derlen); + int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder); + int (*param_missing) (const EVP_PKEY *pk); + int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from); + int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); + int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*sig_print) (BIO *out, + const X509_ALGOR *sigalg, const ASN1_STRING *sig, + int indent, ASN1_PCTX *pctx); + void (*pkey_free) (EVP_PKEY *pkey); + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2); + /* Legacy functions for old PEM */ + int (*old_priv_decode) (EVP_PKEY *pkey, + const unsigned char **pder, int derlen); + int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder); + /* Custom ASN1 signature verification */ + int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); + int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, + ASN1_BIT_STRING *sig); +} /* EVP_PKEY_ASN1_METHOD */ ; + +/* + * Method to handle CRL access. In general a CRL could be very large (several + * Mb) and can consume large amounts of resources if stored in memory by + * multiple processes. This method allows general CRL operations to be + * redirected to more efficient callbacks: for example a CRL entry database. + */ + +#define X509_CRL_METHOD_DYNAMIC 1 + +struct x509_crl_method_st { + int flags; + int (*crl_init) (X509_CRL *crl); + int (*crl_free) (X509_CRL *crl); + int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer); + int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); +}; diff --git a/Sources/COpenSSL/asn1_mac.h b/Sources/COpenSSL/asn1_mac.h new file mode 100644 index 00000000..972aac3a --- /dev/null +++ b/Sources/COpenSSL/asn1_mac.h @@ -0,0 +1,579 @@ +/* crypto/asn1/asn1_mac.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_MAC_H +# define HEADER_ASN1_MAC_H + +# include "asn1.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef ASN1_MAC_ERR_LIB +# define ASN1_MAC_ERR_LIB ERR_LIB_ASN1 +# endif + +# define ASN1_MAC_H_err(f,r,line) \ + ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line)) + +# define M_ASN1_D2I_vars(a,type,func) \ + ASN1_const_CTX c; \ + type ret=NULL; \ + \ + c.pp=(const unsigned char **)pp; \ + c.q= *(const unsigned char **)pp; \ + c.error=ERR_R_NESTED_ASN1_ERROR; \ + if ((a == NULL) || ((*a) == NULL)) \ + { if ((ret=(type)func()) == NULL) \ + { c.line=__LINE__; goto err; } } \ + else ret=(*a); + +# define M_ASN1_D2I_Init() \ + c.p= *(const unsigned char **)pp; \ + c.max=(length == 0)?0:(c.p+length); + +# define M_ASN1_D2I_Finish_2(a) \ + if (!asn1_const_Finish(&c)) \ + { c.line=__LINE__; goto err; } \ + *(const unsigned char **)pp=c.p; \ + if (a != NULL) (*a)=ret; \ + return(ret); + +# define M_ASN1_D2I_Finish(a,func,e) \ + M_ASN1_D2I_Finish_2(a); \ +err:\ + ASN1_MAC_H_err((e),c.error,c.line); \ + asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \ + if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ + return(NULL) + +# define M_ASN1_D2I_start_sequence() \ + if (!asn1_GetSequence(&c,&length)) \ + { c.line=__LINE__; goto err; } +/* Begin reading ASN1 without a surrounding sequence */ +# define M_ASN1_D2I_begin() \ + c.slen = length; + +/* End reading ASN1 with no check on length */ +# define M_ASN1_D2I_Finish_nolen(a, func, e) \ + *pp=c.p; \ + if (a != NULL) (*a)=ret; \ + return(ret); \ +err:\ + ASN1_MAC_H_err((e),c.error,c.line); \ + asn1_add_error(*pp,(int)(c.q- *pp)); \ + if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ + return(NULL) + +# define M_ASN1_D2I_end_sequence() \ + (((c.inf&1) == 0)?(c.slen <= 0): \ + (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen))) + +/* Don't use this with d2i_ASN1_BOOLEAN() */ +# define M_ASN1_D2I_get(b, func) \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +/* Don't use this with d2i_ASN1_BOOLEAN() */ +# define M_ASN1_D2I_get_x(type,b,func) \ + c.q=c.p; \ + if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +/* use this instead () */ +# define M_ASN1_D2I_get_int(b,func) \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) < 0) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get(b,func); \ + } + +# define M_ASN1_D2I_get_int_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get_int(b,func); \ + } + +# define M_ASN1_D2I_get_imp(b,func, type) \ + M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \ + c.slen-=(c.p-c.q);\ + M_ASN1_next_prev=_tmp; + +# define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \ + (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \ + { \ + unsigned char _tmp = M_ASN1_next; \ + M_ASN1_D2I_get_imp(b,func, type);\ + } + +# define M_ASN1_D2I_get_set(r,func,free_func) \ + M_ASN1_D2I_get_imp_set(r,func,free_func, \ + V_ASN1_SET,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_set_type(type,r,func,free_func) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \ + V_ASN1_SET,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_set_opt(r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ + { M_ASN1_D2I_get_set(r,func,free_func); } + +# define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ + { M_ASN1_D2I_get_set_type(type,r,func,free_func); } + +# define M_ASN1_I2D_len_SET_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_len_SET(a,f); + +# define M_ASN1_I2D_put_SET_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SET(a,f); + +# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE(a,f); + +# define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE_type(type,a,f); + +# define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \ + if ((c.slen != 0) && \ + (M_ASN1_next == \ + (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ + { \ + M_ASN1_D2I_get_imp_set(b,func,free_func,\ + tag,V_ASN1_CONTEXT_SPECIFIC); \ + } + +# define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \ + if ((c.slen != 0) && \ + (M_ASN1_next == \ + (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ + { \ + M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\ + tag,V_ASN1_CONTEXT_SPECIFIC); \ + } + +# define M_ASN1_D2I_get_seq(r,func,free_func) \ + M_ASN1_D2I_get_imp_set(r,func,free_func,\ + V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ + V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) + +# define M_ASN1_D2I_get_seq_opt(r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ + { M_ASN1_D2I_get_seq(r,func,free_func); } + +# define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ + { M_ASN1_D2I_get_seq_type(type,r,func,free_func); } + +# define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \ + M_ASN1_D2I_get_imp_set(r,func,free_func,\ + x,V_ASN1_CONTEXT_SPECIFIC); + +# define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ + x,V_ASN1_CONTEXT_SPECIFIC); + +# define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\ + (void (*)())free_func,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\ + free_func,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_set_strings(r,func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_EXP_opt(r,func,tag) \ + if ((c.slen != 0L) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (func(&(r),&c.p,Tlen) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +# define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \ + if ((c.slen != 0) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \ + (void (*)())free_func, \ + b,V_ASN1_UNIVERSAL) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +# define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \ + if ((c.slen != 0) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \ + free_func,b,V_ASN1_UNIVERSAL) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +/* New macros */ +# define M_ASN1_New_Malloc(ret,type) \ + if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \ + { c.line=__LINE__; goto err2; } + +# define M_ASN1_New(arg,func) \ + if (((arg)=func()) == NULL) return(NULL) + +# define M_ASN1_New_Error(a) \ +/*- err: ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \ + return(NULL);*/ \ + err2: ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \ + return(NULL) + +/* + * BIG UGLY WARNING! This is so damn ugly I wanna puke. Unfortunately, some + * macros that use ASN1_const_CTX still insist on writing in the input + * stream. ARGH! ARGH! ARGH! Let's get rid of this macro package. Please? -- + * Richard Levitte + */ +# define M_ASN1_next (*((unsigned char *)(c.p))) +# define M_ASN1_next_prev (*((unsigned char *)(c.q))) + +/*************************************************/ + +# define M_ASN1_I2D_vars(a) int r=0,ret=0; \ + unsigned char *p; \ + if (a == NULL) return(0) + +/* Length Macros */ +# define M_ASN1_I2D_len(a,f) ret+=f(a,NULL) +# define M_ASN1_I2D_len_IMP_opt(a,f) if (a != NULL) M_ASN1_I2D_len(a,f) + +# define M_ASN1_I2D_len_SET(a,f) \ + ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); + +# define M_ASN1_I2D_len_SET_type(type,a,f) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \ + V_ASN1_UNIVERSAL,IS_SET); + +# define M_ASN1_I2D_len_SEQUENCE(a,f) \ + ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \ + V_ASN1_UNIVERSAL,IS_SEQUENCE) + +# define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_len_SEQUENCE(a,f); + +# define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + M_ASN1_I2D_len_SEQUENCE_type(type,a,f); + +# define M_ASN1_I2D_len_IMP_SET(a,f,x) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \ + if (a != NULL)\ + { \ + v=f(a,NULL); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0))\ + { \ + v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0))\ + { \ + v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_##type##_num(a) != 0))\ + { \ + v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \ + V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +/* Put Macros */ +# define M_ASN1_I2D_put(a,f) f(a,&p) + +# define M_ASN1_I2D_put_IMP_opt(a,f,t) \ + if (a != NULL) \ + { \ + unsigned char *q=p; \ + f(a,&p); \ + *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\ + } + +# define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\ + V_ASN1_UNIVERSAL,IS_SET) +# define M_ASN1_I2D_put_SET_type(type,a,f) \ + i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET) +# define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ + V_ASN1_CONTEXT_SPECIFIC,IS_SET) +# define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \ + i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET) +# define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ + V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\ + V_ASN1_UNIVERSAL,IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \ + i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE(a,f); + +# define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); } + +# define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); } + +# define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); } + +# define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); } + +# define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \ + if (a != NULL) \ + { \ + ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \ + f(a,&p); \ + } + +# define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ + } + +# define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \ + } + +# define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + } + +# define M_ASN1_I2D_seq_total() \ + r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \ + if (pp == NULL) return(r); \ + p= *pp; \ + ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) + +# define M_ASN1_I2D_INF_seq_start(tag,ctx) \ + *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \ + *(p++)=0x80 + +# define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00 + +# define M_ASN1_I2D_finish() *pp=p; \ + return(r); + +int asn1_GetSequence(ASN1_const_CTX *c, long *length); +void asn1_add_error(const unsigned char *address, int offset); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/asn1t.h b/Sources/COpenSSL/asn1t.h new file mode 100644 index 00000000..ea951808 --- /dev/null +++ b/Sources/COpenSSL/asn1t.h @@ -0,0 +1,973 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ASN1T_H +# define HEADER_ASN1T_H + +# include +# include "e_os2.h" +# include "asn1.h" + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + OPENSSL_GLOBAL const ASN1_ITEM itname##_it = { + +# define ASN1_ITEM_end(itname) \ + }; + +# else + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr())) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM * itname##_it(void) \ + { \ + static const ASN1_ITEM local_it = { + +# define ASN1_ITEM_end(itname) \ + }; \ + return &local_it; \ + } + +# endif + +/* Macros to aid ASN1 template writing */ + +# define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +# define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + +/* This is a ASN1 type which just embeds a template */ + +/*- + * This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +# define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +# define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +# define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_ref(tname, cb, lck) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) + +# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/*- + * This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +# define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +# define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +# define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* used when the structure is combined with the parent */ + +# define ASN1_EX_COMBINE(flags, tag, type) { \ + (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +# define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) + +# define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# else +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } +# endif +/* Plain simple type */ +# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) + +/* OPTIONAL simple type */ +# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) + +/* IMPLICIT tagged OPTIONAL simple type */ +# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* Same as above but EXPLICIT */ + +# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* SEQUENCE OF type */ +# define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +# define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +# define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +# define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +# define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +# define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +# define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + +# else + +# define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ITEM *name##_adb(void) \ + { \ + static const ASN1_ADB internal_adb = \ + {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + }; \ + return (const ASN1_ITEM *) &internal_adb; \ + } \ + void dummy_function(void) + +# endif + +# define ADB_ENTRY(val, template) {val, template} + +# define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +/* + * This is the ASN1 template structure that defines a wrapper round the + * actual type. It determines the actual position of the field in the value + * structure, various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { + unsigned long flags; /* Various flags */ + long tag; /* tag, not used if no tagging */ + unsigned long offset; /* Offset of this field in structure */ +# ifndef NO_ASN1_FIELD_NAMES + const char *field_name; /* Field name */ +# endif + ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +# define ASN1_TEMPLATE_item(t) (t->item_ptr) +# define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +# define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +# define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* + * Special case: this refers to a SET OF that will be sorted into DER order + * when encoded *and* the corresponding STACK will be modified to match the + * new order. + */ +# define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +# define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* + * These flags mean the tag should be taken from the tag field. If EXPLICIT + * then the underlying type is used for the inner tag. + */ + +/* IMPLICIT tagging */ +# define ASN1_TFLG_IMPTAG (0x1 << 3) + +/* EXPLICIT tagging, inner tag from underlying type */ +# define ASN1_TFLG_EXPTAG (0x2 << 3) + +# define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +# define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT + +/* context specific EXPLICIT */ +# define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT + +/* + * If tagging is in force these determine the type of tag to use. Otherwise + * the tag is determined by the underlying type. These values reflect the + * actual octet format. + */ + +/* Universal tag */ +# define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +# define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +# define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +# define ASN1_TFLG_PRIVATE (0x3<<6) + +# define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* + * These are for ANY DEFINED BY type. In this case the 'item' field points to + * an ASN1_ADB structure which contains a table of values to decode the + * relevant type + */ + +# define ASN1_TFLG_ADB_MASK (0x3<<8) + +# define ASN1_TFLG_ADB_OID (0x1<<8) + +# define ASN1_TFLG_ADB_INT (0x1<<9) + +/* + * This flag means a parent structure is passed instead of the field: this is + * useful is a SEQUENCE is being combined with a CHOICE for example. Since + * this means the structure and item name will differ we need to use the + * ASN1_CHOICE_END_name() macro for example. + */ + +# define ASN1_TFLG_COMBINE (0x1<<10) + +/* + * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes + * indefinite length constructed encoding to be used if required. + */ + +# define ASN1_TFLG_NDEF (0x1<<11) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { + char itype; /* The item type, primitive, SEQUENCE, CHOICE + * or extern */ + long utype; /* underlying type */ + const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains + * the contents */ + long tcount; /* Number of templates if SEQUENCE or CHOICE */ + const void *funcs; /* functions that handle this type */ + long size; /* Structure size (usually) */ +# ifndef NO_ASN1_FIELD_NAMES + const char *sname; /* Structure name */ +# endif +}; + +/*- + * These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * For COMPAT types the funcs field gives a + * set of functions that handle this type, this + * supports the old d2i, i2d convention. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +# define ASN1_ITYPE_PRIMITIVE 0x0 + +# define ASN1_ITYPE_SEQUENCE 0x1 + +# define ASN1_ITYPE_CHOICE 0x2 + +# define ASN1_ITYPE_COMPAT 0x3 + +# define ASN1_ITYPE_EXTERN 0x4 + +# define ASN1_ITYPE_MSTRING 0x5 + +# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* + * Cache for ASN1 tag and length, so we don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st { + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ + +typedef ASN1_VALUE *ASN1_new_func(void); +typedef void ASN1_free_func(ASN1_VALUE *a); +typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in, + long length); +typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in); + +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, + int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, + int len, int utype, char *free_cont, + const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, + const ASN1_ITEM *it, int indent, + const ASN1_PCTX *pctx); + +typedef struct ASN1_COMPAT_FUNCS_st { + ASN1_new_func *asn1_new; + ASN1_free_func *asn1_free; + ASN1_d2i_func *asn1_d2i; + ASN1_i2d_func *asn1_i2d; +} ASN1_COMPAT_FUNCS; + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* + * This is the ASN1_AUX structure: it handles various miscellaneous + * requirements. For example the use of reference counts and an informational + * callback. The "informational callback" is called at various points during + * the ASN1 encoding and decoding. It can be used to provide minor + * customisation of the structures used. This is most useful where the + * supplied routines *almost* do the right thing but need some extra help at + * a few points. If the callback returns zero then it is assumed a fatal + * error has occurred and the main operation should be abandoned. If major + * changes in the default behaviour are required then an external type is + * more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +# define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +# define ASN1_AFLG_ENCODING 2 +/* The Sequence length is invalid */ +# define ASN1_AFLG_BROKEN 4 + +/* operation values for asn1_cb */ + +# define ASN1_OP_NEW_PRE 0 +# define ASN1_OP_NEW_POST 1 +# define ASN1_OP_FREE_PRE 2 +# define ASN1_OP_FREE_POST 3 +# define ASN1_OP_D2I_PRE 4 +# define ASN1_OP_D2I_POST 5 +# define ASN1_OP_I2D_PRE 6 +# define ASN1_OP_I2D_POST 7 +# define ASN1_OP_PRINT_PRE 8 +# define ASN1_OP_PRINT_POST 9 +# define ASN1_OP_STREAM_PRE 10 +# define ASN1_OP_STREAM_POST 11 +# define ASN1_OP_DETACHED_PRE 12 +# define ASN1_OP_DETACHED_POST 13 + +/* Macro to implement a primitive type */ +# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +# define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement an ASN1_ITEM in terms of old style funcs */ + +# define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE) + +# define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \ + static const ASN1_COMPAT_FUNCS sname##_ff = { \ + (ASN1_new_func *)sname##_new, \ + (ASN1_free_func *)sname##_free, \ + (ASN1_d2i_func *)d2i_##sname, \ + (ASN1_i2d_func *)i2d_##sname, \ + }; \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_COMPAT, \ + tag, \ + NULL, \ + 0, \ + &sname##_ff, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +/* + * This includes evil casts to remove const: they will go away when full ASN1 + * constification is done. + */ +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) +DECLARE_ASN1_ITEM(CBIGNUM) +DECLARE_ASN1_ITEM(BIGNUM) +DECLARE_ASN1_ITEM(LONG) +DECLARE_ASN1_ITEM(ZLONG) + +DECLARE_STACK_OF(ASN1_VALUE) + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); + +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_TEMPLATE *tt); +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt); +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it); +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it); + +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, + const ASN1_ITEM *it); + +ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); + +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + int nullerr); + +int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); + +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, + const ASN1_ITEM *it); +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/asn_.c b/Sources/COpenSSL/asn_.c new file mode 100644 index 00000000..d0d0e941 --- /dev/null +++ b/Sources/COpenSSL/asn_.c @@ -0,0 +1,1337 @@ +/* asn_mime.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include "cryptlib.h" +#include "rand.h" +#include "x509.h" +#include "asn1.h" +#include "asn1t.h" +#include "asn1_locl.h" + +/* + * Generalised MIME like utilities for streaming ASN1. Although many have a + * PKCS7/CMS like flavour others are more general purpose. + */ + +/* + * MIME format structures Note that all are translated to lower case apart + * from parameter values. Quotes are stripped off + */ + +typedef struct { + char *param_name; /* Param name e.g. "micalg" */ + char *param_value; /* Param value e.g. "sha1" */ +} MIME_PARAM; + +DECLARE_STACK_OF(MIME_PARAM) +IMPLEMENT_STACK_OF(MIME_PARAM) + +typedef struct { + char *name; /* Name of line e.g. "content-type" */ + char *value; /* Value of line e.g. "text/plain" */ + STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */ +} MIME_HEADER; + +DECLARE_STACK_OF(MIME_HEADER) +IMPLEMENT_STACK_OF(MIME_HEADER) + +static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, + const ASN1_ITEM *it); +static char *strip_ends(char *name); +static char *strip_start(char *name); +static char *strip_end(char *name); +static MIME_HEADER *mime_hdr_new(char *name, char *value); +static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value); +static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio); +static int mime_hdr_cmp(const MIME_HEADER *const *a, + const MIME_HEADER *const *b); +static int mime_param_cmp(const MIME_PARAM *const *a, + const MIME_PARAM *const *b); +static void mime_param_free(MIME_PARAM *param); +static int mime_bound_check(char *line, int linelen, char *bound, int blen); +static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret); +static int strip_eol(char *linebuf, int *plen); +static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name); +static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); +static void mime_hdr_free(MIME_HEADER *hdr); + +#define MAX_SMLEN 1024 +#define mime_debug(x) /* x */ + +/* Output an ASN1 structure in BER format streaming if necessary */ + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it) +{ + /* If streaming create stream BIO and copy all content through it */ + if (flags & SMIME_STREAM) { + BIO *bio, *tbio; + bio = BIO_new_NDEF(out, val, it); + if (!bio) { + ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE); + return 0; + } + SMIME_crlf_copy(in, bio, flags); + (void)BIO_flush(bio); + /* Free up successive BIOs until we hit the old output BIO */ + do { + tbio = BIO_pop(bio); + BIO_free(bio); + bio = tbio; + } while (bio != out); + } + /* + * else just write out ASN1 structure which will have all content stored + * internally + */ + else + ASN1_item_i2d_bio(it, out, val); + return 1; +} + +/* Base 64 read and write of ASN1 structure */ + +static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it) +{ + BIO *b64; + int r; + b64 = BIO_new(BIO_f_base64()); + if (!b64) { + ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + /* + * prepend the b64 BIO so all data is base64 encoded. + */ + out = BIO_push(b64, out); + r = i2d_ASN1_bio_stream(out, val, in, flags, it); + (void)BIO_flush(out); + BIO_pop(out); + BIO_free(b64); + return r; +} + +/* Streaming ASN1 PEM write */ + +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it) +{ + int r; + BIO_printf(out, "-----BEGIN %s-----\n", hdr); + r = B64_write_ASN1(out, val, in, flags, it); + BIO_printf(out, "-----END %s-----\n", hdr); + return r; +} + +static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) +{ + BIO *b64; + ASN1_VALUE *val; + if (!(b64 = BIO_new(BIO_f_base64()))) { + ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + bio = BIO_push(b64, bio); + val = ASN1_item_d2i_bio(it, bio, NULL); + if (!val) + ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR); + (void)BIO_flush(bio); + bio = BIO_pop(bio); + BIO_free(b64); + return val; +} + +/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */ + +static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) +{ + const EVP_MD *md; + int i, have_unknown = 0, write_comma, ret = 0, md_nid; + have_unknown = 0; + write_comma = 0; + for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) { + if (write_comma) + BIO_write(out, ",", 1); + write_comma = 1; + md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); + md = EVP_get_digestbynid(md_nid); + if (md && md->md_ctrl) { + int rv; + char *micstr; + rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr); + if (rv > 0) { + BIO_puts(out, micstr); + OPENSSL_free(micstr); + continue; + } + if (rv != -2) + goto err; + } + switch (md_nid) { + case NID_sha1: + BIO_puts(out, "sha1"); + break; + + case NID_md5: + BIO_puts(out, "md5"); + break; + + case NID_sha256: + BIO_puts(out, "sha-256"); + break; + + case NID_sha384: + BIO_puts(out, "sha-384"); + break; + + case NID_sha512: + BIO_puts(out, "sha-512"); + break; + + case NID_id_GostR3411_94: + BIO_puts(out, "gostr3411-94"); + goto err; + break; + + default: + if (have_unknown) + write_comma = 0; + else { + BIO_puts(out, "unknown"); + have_unknown = 1; + } + break; + + } + } + + ret = 1; + err: + + return ret; + +} + +/* SMIME sender */ + +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it) +{ + char bound[33], c; + int i; + const char *mime_prefix, *mime_eol, *cname = "smime.p7m"; + const char *msg_type = NULL; + if (flags & SMIME_OLDMIME) + mime_prefix = "application/x-pkcs7-"; + else + mime_prefix = "application/pkcs7-"; + + if (flags & SMIME_CRLFEOL) + mime_eol = "\r\n"; + else + mime_eol = "\n"; + if ((flags & SMIME_DETACHED) && data) { + /* We want multipart/signed */ + /* Generate a random boundary */ + if (RAND_bytes((unsigned char *)bound, 32) <= 0) + return 0; + for (i = 0; i < 32; i++) { + c = bound[i] & 0xf; + if (c < 10) + c += '0'; + else + c += 'A' - 10; + bound[i] = c; + } + bound[32] = 0; + BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); + BIO_printf(bio, "Content-Type: multipart/signed;"); + BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix); + BIO_puts(bio, " micalg=\""); + asn1_write_micalg(bio, mdalgs); + BIO_printf(bio, "\"; boundary=\"----%s\"%s%s", + bound, mime_eol, mime_eol); + BIO_printf(bio, "This is an S/MIME signed message%s%s", + mime_eol, mime_eol); + /* Now write out the first part */ + BIO_printf(bio, "------%s%s", bound, mime_eol); + if (!asn1_output_data(bio, data, val, flags, it)) + return 0; + BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); + + /* Headers for signature */ + + BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix); + BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol); + BIO_printf(bio, "Content-Transfer-Encoding: base64%s", mime_eol); + BIO_printf(bio, "Content-Disposition: attachment;"); + BIO_printf(bio, " filename=\"smime.p7s\"%s%s", mime_eol, mime_eol); + B64_write_ASN1(bio, val, NULL, 0, it); + BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound, + mime_eol, mime_eol); + return 1; + } + + /* Determine smime-type header */ + + if (ctype_nid == NID_pkcs7_enveloped) + msg_type = "enveloped-data"; + else if (ctype_nid == NID_pkcs7_signed) { + if (econt_nid == NID_id_smime_ct_receipt) + msg_type = "signed-receipt"; + else if (sk_X509_ALGOR_num(mdalgs) >= 0) + msg_type = "signed-data"; + else + msg_type = "certs-only"; + } else if (ctype_nid == NID_id_smime_ct_compressedData) { + msg_type = "compressed-data"; + cname = "smime.p7z"; + } + /* MIME headers */ + BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); + BIO_printf(bio, "Content-Disposition: attachment;"); + BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol); + BIO_printf(bio, "Content-Type: %smime;", mime_prefix); + if (msg_type) + BIO_printf(bio, " smime-type=%s;", msg_type); + BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol); + BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s", + mime_eol, mime_eol); + if (!B64_write_ASN1(bio, val, data, flags, it)) + return 0; + BIO_printf(bio, "%s", mime_eol); + return 1; +} + +/* Handle output of ASN1 data */ + +static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, + const ASN1_ITEM *it) +{ + BIO *tmpbio; + const ASN1_AUX *aux = it->funcs; + ASN1_STREAM_ARG sarg; + int rv = 1; + + /* + * If data is not deteched or resigning then the output BIO is already + * set up to finalise when it is written through. + */ + if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) { + SMIME_crlf_copy(data, out, flags); + return 1; + } + + if (!aux || !aux->asn1_cb) { + ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED); + return 0; + } + + sarg.out = out; + sarg.ndef_bio = NULL; + sarg.boundary = NULL; + + /* Let ASN1 code prepend any needed BIOs */ + + if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0) + return 0; + + /* Copy data across, passing through filter BIOs for processing */ + SMIME_crlf_copy(data, sarg.ndef_bio, flags); + + /* Finalize structure */ + if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0) + rv = 0; + + /* Now remove any digests prepended to the BIO */ + + while (sarg.ndef_bio != out) { + tmpbio = BIO_pop(sarg.ndef_bio); + BIO_free(sarg.ndef_bio); + sarg.ndef_bio = tmpbio; + } + + return rv; + +} + +/* + * SMIME reader: handle multipart/signed and opaque signing. in multipart + * case the content is placed in a memory BIO pointed to by "bcont". In + * opaque this is set to NULL + */ + +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) +{ + BIO *asnin; + STACK_OF(MIME_HEADER) *headers = NULL; + STACK_OF(BIO) *parts = NULL; + MIME_HEADER *hdr; + MIME_PARAM *prm; + ASN1_VALUE *val; + int ret; + + if (bcont) + *bcont = NULL; + + if (!(headers = mime_parse_hdr(bio))) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR); + return NULL; + } + + if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE); + return NULL; + } + + /* Handle multipart/signed */ + + if (!strcmp(hdr->value, "multipart/signed")) { + /* Split into two parts */ + prm = mime_param_find(hdr, "boundary"); + if (!prm || !prm->param_value) { + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY); + return NULL; + } + ret = multi_split(bio, prm->param_value, &parts); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + if (!ret || (sk_BIO_num(parts) != 2)) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + + /* Parse the signature piece */ + asnin = sk_BIO_value(parts, 1); + + if (!(headers = mime_parse_hdr(asnin))) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + + /* Get content type */ + + if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + + if (strcmp(hdr->value, "application/x-pkcs7-signature") && + strcmp(hdr->value, "application/pkcs7-signature")) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE); + ERR_add_error_data(2, "type: ", hdr->value); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + /* Read in ASN1 */ + if (!(val = b64_read_asn1(asnin, it))) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + + if (bcont) { + *bcont = sk_BIO_value(parts, 0); + BIO_free(asnin); + sk_BIO_free(parts); + } else + sk_BIO_pop_free(parts, BIO_vfree); + return val; + } + + /* OK, if not multipart/signed try opaque signature */ + + if (strcmp(hdr->value, "application/x-pkcs7-mime") && + strcmp(hdr->value, "application/pkcs7-mime")) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE); + ERR_add_error_data(2, "type: ", hdr->value); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + return NULL; + } + + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + + if (!(val = b64_read_asn1(bio, it))) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR); + return NULL; + } + return val; + +} + +/* Copy text from one BIO to another making the output CRLF at EOL */ +int SMIME_crlf_copy(BIO *in, BIO *out, int flags) +{ + BIO *bf; + char eol; + int len; + char linebuf[MAX_SMLEN]; + /* + * Buffer output so we don't write one line at a time. This is useful + * when streaming as we don't end up with one OCTET STRING per line. + */ + bf = BIO_new(BIO_f_buffer()); + if (!bf) + return 0; + out = BIO_push(bf, out); + if (flags & SMIME_BINARY) { + while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0) + BIO_write(out, linebuf, len); + } else { + if (flags & SMIME_TEXT) + BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); + while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) { + eol = strip_eol(linebuf, &len); + if (len) + BIO_write(out, linebuf, len); + if (eol) + BIO_write(out, "\r\n", 2); + } + } + (void)BIO_flush(out); + BIO_pop(out); + BIO_free(bf); + return 1; +} + +/* Strip off headers if they are text/plain */ +int SMIME_text(BIO *in, BIO *out) +{ + char iobuf[4096]; + int len; + STACK_OF(MIME_HEADER) *headers; + MIME_HEADER *hdr; + + if (!(headers = mime_parse_hdr(in))) { + ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR); + return 0; + } + if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { + ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + return 0; + } + if (strcmp(hdr->value, "text/plain")) { + ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE); + ERR_add_error_data(2, "type: ", hdr->value); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + return 0; + } + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) + BIO_write(out, iobuf, len); + if (len < 0) + return 0; + return 1; +} + +/* + * Split a multipart/XXX message body into component parts: result is + * canonical parts in a STACK of bios + */ + +static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret) +{ + char linebuf[MAX_SMLEN]; + int len, blen; + int eol = 0, next_eol = 0; + BIO *bpart = NULL; + STACK_OF(BIO) *parts; + char state, part, first; + + blen = strlen(bound); + part = 0; + state = 0; + first = 1; + parts = sk_BIO_new_null(); + *ret = parts; + while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { + state = mime_bound_check(linebuf, len, bound, blen); + if (state == 1) { + first = 1; + part++; + } else if (state == 2) { + sk_BIO_push(parts, bpart); + return 1; + } else if (part) { + /* Strip CR+LF from linebuf */ + next_eol = strip_eol(linebuf, &len); + if (first) { + first = 0; + if (bpart) + sk_BIO_push(parts, bpart); + bpart = BIO_new(BIO_s_mem()); + if (bpart == NULL) + return 1; + BIO_set_mem_eof_return(bpart, 0); + } else if (eol) + BIO_write(bpart, "\r\n", 2); + eol = next_eol; + if (len) + BIO_write(bpart, linebuf, len); + } + } + return 0; +} + +/* This is the big one: parse MIME header lines up to message body */ + +#define MIME_INVALID 0 +#define MIME_START 1 +#define MIME_TYPE 2 +#define MIME_NAME 3 +#define MIME_VALUE 4 +#define MIME_QUOTE 5 +#define MIME_COMMENT 6 + +static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio) +{ + char *p, *q, c; + char *ntmp; + char linebuf[MAX_SMLEN]; + MIME_HEADER *mhdr = NULL; + STACK_OF(MIME_HEADER) *headers; + int len, state, save_state = 0; + + headers = sk_MIME_HEADER_new(mime_hdr_cmp); + if (!headers) + return NULL; + while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { + /* If whitespace at line start then continuation line */ + if (mhdr && isspace((unsigned char)linebuf[0])) + state = MIME_NAME; + else + state = MIME_START; + ntmp = NULL; + /* Go through all characters */ + for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); + p++) { + + /* + * State machine to handle MIME headers if this looks horrible + * that's because it *is* + */ + + switch (state) { + case MIME_START: + if (c == ':') { + state = MIME_TYPE; + *p = 0; + ntmp = strip_ends(q); + q = p + 1; + } + break; + + case MIME_TYPE: + if (c == ';') { + mime_debug("Found End Value\n"); + *p = 0; + mhdr = mime_hdr_new(ntmp, strip_ends(q)); + sk_MIME_HEADER_push(headers, mhdr); + ntmp = NULL; + q = p + 1; + state = MIME_NAME; + } else if (c == '(') { + save_state = state; + state = MIME_COMMENT; + } + break; + + case MIME_COMMENT: + if (c == ')') { + state = save_state; + } + break; + + case MIME_NAME: + if (c == '=') { + state = MIME_VALUE; + *p = 0; + ntmp = strip_ends(q); + q = p + 1; + } + break; + + case MIME_VALUE: + if (c == ';') { + state = MIME_NAME; + *p = 0; + mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); + ntmp = NULL; + q = p + 1; + } else if (c == '"') { + mime_debug("Found Quote\n"); + state = MIME_QUOTE; + } else if (c == '(') { + save_state = state; + state = MIME_COMMENT; + } + break; + + case MIME_QUOTE: + if (c == '"') { + mime_debug("Found Match Quote\n"); + state = MIME_VALUE; + } + break; + } + } + + if (state == MIME_TYPE) { + mhdr = mime_hdr_new(ntmp, strip_ends(q)); + sk_MIME_HEADER_push(headers, mhdr); + } else if (state == MIME_VALUE) + mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); + if (p == linebuf) + break; /* Blank line means end of headers */ + } + + return headers; + +} + +static char *strip_ends(char *name) +{ + return strip_end(strip_start(name)); +} + +/* Strip a parameter of whitespace from start of param */ +static char *strip_start(char *name) +{ + char *p, c; + /* Look for first non white space or quote */ + for (p = name; (c = *p); p++) { + if (c == '"') { + /* Next char is start of string if non null */ + if (p[1]) + return p + 1; + /* Else null string */ + return NULL; + } + if (!isspace((unsigned char)c)) + return p; + } + return NULL; +} + +/* As above but strip from end of string : maybe should handle brackets? */ +static char *strip_end(char *name) +{ + char *p, c; + if (!name) + return NULL; + /* Look for first non white space or quote */ + for (p = name + strlen(name) - 1; p >= name; p--) { + c = *p; + if (c == '"') { + if (p - 1 == name) + return NULL; + *p = 0; + return name; + } + if (isspace((unsigned char)c)) + *p = 0; + else + return name; + } + return NULL; +} + +static MIME_HEADER *mime_hdr_new(char *name, char *value) +{ + MIME_HEADER *mhdr; + char *tmpname, *tmpval, *p; + int c; + if (name) { + if (!(tmpname = BUF_strdup(name))) + return NULL; + for (p = tmpname; *p; p++) { + c = (unsigned char)*p; + if (isupper(c)) { + c = tolower(c); + *p = c; + } + } + } else + tmpname = NULL; + if (value) { + if (!(tmpval = BUF_strdup(value))) + return NULL; + for (p = tmpval; *p; p++) { + c = (unsigned char)*p; + if (isupper(c)) { + c = tolower(c); + *p = c; + } + } + } else + tmpval = NULL; + mhdr = (MIME_HEADER *)OPENSSL_malloc(sizeof(MIME_HEADER)); + if (!mhdr) + return NULL; + mhdr->name = tmpname; + mhdr->value = tmpval; + if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) + return NULL; + return mhdr; +} + +static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value) +{ + char *tmpname, *tmpval, *p; + int c; + MIME_PARAM *mparam; + if (name) { + tmpname = BUF_strdup(name); + if (!tmpname) + return 0; + for (p = tmpname; *p; p++) { + c = (unsigned char)*p; + if (isupper(c)) { + c = tolower(c); + *p = c; + } + } + } else + tmpname = NULL; + if (value) { + tmpval = BUF_strdup(value); + if (!tmpval) + return 0; + } else + tmpval = NULL; + /* Parameter values are case sensitive so leave as is */ + mparam = (MIME_PARAM *)OPENSSL_malloc(sizeof(MIME_PARAM)); + if (!mparam) + return 0; + mparam->param_name = tmpname; + mparam->param_value = tmpval; + sk_MIME_PARAM_push(mhdr->params, mparam); + return 1; +} + +static int mime_hdr_cmp(const MIME_HEADER *const *a, + const MIME_HEADER *const *b) +{ + if (!(*a)->name || !(*b)->name) + return ! !(*a)->name - ! !(*b)->name; + + return (strcmp((*a)->name, (*b)->name)); +} + +static int mime_param_cmp(const MIME_PARAM *const *a, + const MIME_PARAM *const *b) +{ + if (!(*a)->param_name || !(*b)->param_name) + return ! !(*a)->param_name - ! !(*b)->param_name; + return (strcmp((*a)->param_name, (*b)->param_name)); +} + +/* Find a header with a given name (if possible) */ + +static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name) +{ + MIME_HEADER htmp; + int idx; + htmp.name = name; + idx = sk_MIME_HEADER_find(hdrs, &htmp); + if (idx < 0) + return NULL; + return sk_MIME_HEADER_value(hdrs, idx); +} + +static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name) +{ + MIME_PARAM param; + int idx; + param.param_name = name; + idx = sk_MIME_PARAM_find(hdr->params, ¶m); + if (idx < 0) + return NULL; + return sk_MIME_PARAM_value(hdr->params, idx); +} + +static void mime_hdr_free(MIME_HEADER *hdr) +{ + if (hdr->name) + OPENSSL_free(hdr->name); + if (hdr->value) + OPENSSL_free(hdr->value); + if (hdr->params) + sk_MIME_PARAM_pop_free(hdr->params, mime_param_free); + OPENSSL_free(hdr); +} + +static void mime_param_free(MIME_PARAM *param) +{ + if (param->param_name) + OPENSSL_free(param->param_name); + if (param->param_value) + OPENSSL_free(param->param_value); + OPENSSL_free(param); +} + +/*- + * Check for a multipart boundary. Returns: + * 0 : no boundary + * 1 : part boundary + * 2 : final boundary + */ +static int mime_bound_check(char *line, int linelen, char *bound, int blen) +{ + if (linelen == -1) + linelen = strlen(line); + if (blen == -1) + blen = strlen(bound); + /* Quickly eliminate if line length too short */ + if (blen + 2 > linelen) + return 0; + /* Check for part boundary */ + if (!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) { + if (!strncmp(line + blen + 2, "--", 2)) + return 2; + else + return 1; + } + return 0; +} + +static int strip_eol(char *linebuf, int *plen) +{ + int len = *plen; + char *p, c; + int is_eol = 0; + p = linebuf + len - 1; + for (p = linebuf + len - 1; len > 0; len--, p--) { + c = *p; + if (c == '\n') + is_eol = 1; + else if (c != '\r') + break; + } + *plen = len; + return is_eol; +} +/* asn_moid.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "crypto.h" +// #include "cryptlib.h" +#include "conf.h" +#include "dso.h" +// #include "x509.h" + +/* Simple ASN1 OID module: add all objects in a given section */ + +static int do_create(char *value, char *name); + +static int oid_module_init(CONF_IMODULE *md, const CONF *cnf) +{ + int i; + const char *oid_section; + STACK_OF(CONF_VALUE) *sktmp; + CONF_VALUE *oval; + oid_section = CONF_imodule_get_value(md); + if (!(sktmp = NCONF_get_section(cnf, oid_section))) { + ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION); + return 0; + } + for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { + oval = sk_CONF_VALUE_value(sktmp, i); + if (!do_create(oval->value, oval->name)) { + ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT); + return 0; + } + } + return 1; +} + +static void oid_module_finish(CONF_IMODULE *md) +{ + OBJ_cleanup(); +} + +void ASN1_add_oid_module(void) +{ + CONF_module_add("oid_section", oid_module_init, oid_module_finish); +} + +/*- + * Create an OID based on a name value pair. Accept two formats. + * shortname = 1.2.3.4 + * shortname = some long name, 1.2.3.4 + */ + +static int do_create(char *value, char *name) +{ + int nid; + ASN1_OBJECT *oid; + char *ln, *ostr, *p, *lntmp; + p = strrchr(value, ','); + if (!p) { + ln = name; + ostr = value; + } else { + ln = NULL; + ostr = p + 1; + if (!*ostr) + return 0; + while (isspace((unsigned char)*ostr)) + ostr++; + } + + nid = OBJ_create(ostr, name, ln); + + if (nid == NID_undef) + return 0; + + if (p) { + ln = value; + while (isspace((unsigned char)*ln)) + ln++; + p--; + while (isspace((unsigned char)*p)) { + if (p == ln) + return 0; + p--; + } + p++; + lntmp = OPENSSL_malloc((p - ln) + 1); + if (lntmp == NULL) + return 0; + memcpy(lntmp, ln, p - ln); + lntmp[p - ln] = 0; + oid = OBJ_nid2obj(nid); + oid->ln = lntmp; + } + + return 1; +} +/* asn_pack.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" + +#ifndef NO_ASN1_OLD + +/* ASN1 packing and unpacking functions */ + +/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */ + +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK)) +{ + STACK_OF(OPENSSL_BLOCK) *sk; + const unsigned char *pbuf; + pbuf = buf; + if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func, + V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL))) + ASN1err(ASN1_F_ASN1_SEQ_UNPACK, ASN1_R_DECODE_ERROR); + return sk; +} + +/* + * Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a + * OPENSSL_malloc'ed buffer + */ + +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, + unsigned char **buf, int *len) +{ + int safelen; + unsigned char *safe, *p; + if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE, + V_ASN1_UNIVERSAL, IS_SEQUENCE))) { + ASN1err(ASN1_F_ASN1_SEQ_PACK, ASN1_R_ENCODE_ERROR); + return NULL; + } + if (!(safe = OPENSSL_malloc(safelen))) { + ASN1err(ASN1_F_ASN1_SEQ_PACK, ERR_R_MALLOC_FAILURE); + return NULL; + } + p = safe; + i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, + IS_SEQUENCE); + if (len) + *len = safelen; + if (buf) + *buf = safe; + return safe; +} + +/* Extract an ASN1 object from an ASN1_STRING */ + +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i) +{ + const unsigned char *p; + char *ret; + + p = oct->data; + if (!(ret = d2i(NULL, &p, oct->length))) + ASN1err(ASN1_F_ASN1_UNPACK_STRING, ASN1_R_DECODE_ERROR); + return ret; +} + +/* Pack an ASN1 object into an ASN1_STRING */ + +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct) +{ + unsigned char *p; + ASN1_STRING *octmp; + + if (!oct || !*oct) { + if (!(octmp = ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (oct) + *oct = octmp; + } else + octmp = *oct; + + if (!(octmp->length = i2d(obj, NULL))) { + ASN1err(ASN1_F_ASN1_PACK_STRING, ASN1_R_ENCODE_ERROR); + goto err; + } + if (!(p = OPENSSL_malloc(octmp->length))) { + ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE); + goto err; + } + octmp->data = p; + i2d(obj, &p); + return octmp; + err: + if (!oct || !*oct) { + ASN1_STRING_free(octmp); + if (oct) + *oct = NULL; + } + return NULL; +} + +#endif + +/* ASN1_ITEM versions of the above */ + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) +{ + ASN1_STRING *octmp; + + if (!oct || !*oct) { + if (!(octmp = ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (oct) + *oct = octmp; + } else + octmp = *oct; + + if (octmp->data) { + OPENSSL_free(octmp->data); + octmp->data = NULL; + } + + if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) { + ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR); + return NULL; + } + if (!octmp->data) { + ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); + return NULL; + } + return octmp; +} + +/* Extract an ASN1 object from an ASN1_STRING */ + +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it) +{ + const unsigned char *p; + void *ret; + + p = oct->data; + if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it))) + ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR); + return ret; +} diff --git a/Sources/COpenSSL/atalla.h b/Sources/COpenSSL/atalla.h new file mode 100644 index 00000000..60e7eda5 --- /dev/null +++ b/Sources/COpenSSL/atalla.h @@ -0,0 +1,44 @@ +/* + * This header declares the necessary definitions for using the + * exponentiation acceleration capabilities of Atalla cards. The only + * cryptographic operation is performed by "ASI_RSAPrivateKeyOpFn" and this + * takes a structure that defines an "RSA private key". However, it is really + * only performing a regular mod_exp using the supplied modulus and exponent + * - no CRT form is being used. Hence, it is a generic mod_exp function in + * disguise, and we use it as such. Thanks to the people at Atalla for + * letting me know these definitions are fine and that they can be reproduced + * here. Geoff. + */ + +typedef struct ItemStr { + unsigned char *data; + int len; +} Item; + +typedef struct RSAPrivateKeyStr { + void *reserved; + Item version; + Item modulus; + Item publicExponent; + Item privateExponent; + Item prime[2]; + Item exponent[2]; + Item coefficient; +} RSAPrivateKey; + +/* + * Predeclare the function pointer types that we dynamically load from the + * DSO. These use the same names and form that Ben's original support code + * had (in crypto/bn/bn_exp.c) unless of course I've inadvertently changed + * the style somewhere along the way! + */ + +typedef int tfnASI_GetPerformanceStatistics(int reset_flag, + unsigned int *ret_buf); + +typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf); + +typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey, + unsigned char *output, + unsigned char *input, + unsigned int modulus_len); diff --git a/Sources/COpenSSL/b_dump.c b/Sources/COpenSSL/b_dump.c new file mode 100644 index 00000000..fcfd6995 --- /dev/null +++ b/Sources/COpenSSL/b_dump.c @@ -0,0 +1,193 @@ +/* crypto/bio/b_dump.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * Stolen from tjh's ssl/ssl_trc.c stuff. + */ + +#include +#include "cryptlib.h" +#include "bio_lcl.h" + +#define DUMP_WIDTH 16 +#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4)) + +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len) +{ + return BIO_dump_indent_cb(cb, u, s, len, 0); +} + +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent) +{ + int ret = 0; + char buf[288 + 1], tmp[20], str[128 + 1]; + int i, j, rows; + unsigned char ch; + int dump_width; + + if (indent < 0) + indent = 0; + if (indent) { + if (indent > 128) + indent = 128; + memset(str, ' ', indent); + } + str[indent] = '\0'; + + dump_width = DUMP_WIDTH_LESS_INDENT(indent); + rows = (len / dump_width); + if ((rows * dump_width) < len) + rows++; + for (i = 0; i < rows; i++) { + BUF_strlcpy(buf, str, sizeof(buf)); + BIO_snprintf(tmp, sizeof(tmp), "%04x - ", i * dump_width); + BUF_strlcat(buf, tmp, sizeof(buf)); + for (j = 0; j < dump_width; j++) { + if (((i * dump_width) + j) >= len) { + BUF_strlcat(buf, " ", sizeof(buf)); + } else { + ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; + BIO_snprintf(tmp, sizeof(tmp), "%02x%c", ch, + j == 7 ? '-' : ' '); + BUF_strlcat(buf, tmp, sizeof(buf)); + } + } + BUF_strlcat(buf, " ", sizeof(buf)); + for (j = 0; j < dump_width; j++) { + if (((i * dump_width) + j) >= len) + break; + ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; +#ifndef CHARSET_EBCDIC + BIO_snprintf(tmp, sizeof(tmp), "%c", + ((ch >= ' ') && (ch <= '~')) ? ch : '.'); +#else + BIO_snprintf(tmp, sizeof(tmp), "%c", + ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) + ? os_toebcdic[ch] + : '.'); +#endif + BUF_strlcat(buf, tmp, sizeof(buf)); + } + BUF_strlcat(buf, "\n", sizeof(buf)); + /* + * if this is the last call then update the ddt_dump thing so that we + * will move the selection point in the debug window + */ + ret += cb((void *)buf, strlen(buf), u); + } + return ret; +} + +#ifndef OPENSSL_NO_FP_API +static int write_fp(const void *data, size_t len, void *fp) +{ + return UP_fwrite(data, len, 1, fp); +} + +int BIO_dump_fp(FILE *fp, const char *s, int len) +{ + return BIO_dump_cb(write_fp, fp, s, len); +} + +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent) +{ + return BIO_dump_indent_cb(write_fp, fp, s, len, indent); +} +#endif + +static int write_bio(const void *data, size_t len, void *bp) +{ + return BIO_write((BIO *)bp, (const char *)data, len); +} + +int BIO_dump(BIO *bp, const char *s, int len) +{ + return BIO_dump_cb(write_bio, bp, s, len); +} + +int BIO_dump_indent(BIO *bp, const char *s, int len, int indent) +{ + return BIO_dump_indent_cb(write_bio, bp, s, len, indent); +} + +int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, + int datalen) +{ + int i, j = 0; + + if (datalen < 1) + return 1; + + for (i = 0; i < datalen - 1; i++) { + if (i && !j) + BIO_printf(out, "%*s", indent, ""); + + BIO_printf(out, "%02X:", data[i]); + + j = (j + 1) % width; + if (!j) + BIO_printf(out, "\n"); + } + + if (i && !j) + BIO_printf(out, "%*s", indent, ""); + BIO_printf(out, "%02X", data[datalen - 1]); + return 1; +} diff --git a/Sources/COpenSSL/b_print.c b/Sources/COpenSSL/b_print.c new file mode 100644 index 00000000..a2ebe2b5 --- /dev/null +++ b/Sources/COpenSSL/b_print.c @@ -0,0 +1,869 @@ +/* crypto/bio/b_print.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* disable assert() unless BIO_DEBUG has been defined */ +#ifndef BIO_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +/* + * Stolen from tjh's ssl/ssl_trc.c stuff. + */ + +#include +#include +#include +#include +#include +#include "cryptlib.h" +#ifndef NO_SYS_TYPES_H +# include +#endif +#include "bn.h" /* To get BN_LLONG properly defined */ +#include "bio.h" + +#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT) +# ifndef HAVE_LONG_LONG +# define HAVE_LONG_LONG 1 +# endif +#endif + +/***************************************************************************/ + +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions. + */ + +/*- + * This code contains numerious changes and enhancements which were + * made by lots of contributors over the last years to Patrick Powell's + * original code: + * + * o Patrick Powell (1995) + * o Brandon Long (1996, for Mutt) + * o Thomas Roessler (1998, for Mutt) + * o Michael Elkins (1998, for Mutt) + * o Andrew Tridgell (1998, for Samba) + * o Luke Mewburn (1999, for LukemFTP) + * o Ralf S. Engelschall (1999, for Pth) + * o ... (for OpenSSL) + */ + +#ifdef HAVE_LONG_DOUBLE +# define LDOUBLE long double +#else +# define LDOUBLE double +#endif + +#ifdef HAVE_LONG_LONG +# if defined(_WIN32) && !defined(__GNUC__) +# define LLONG __int64 +# else +# define LLONG long long +# endif +#else +# define LLONG long +#endif + +static int fmtstr(char **, char **, size_t *, size_t *, + const char *, int, int, int); +static int fmtint(char **, char **, size_t *, size_t *, + LLONG, int, int, int, int); +static int fmtfp(char **, char **, size_t *, size_t *, + LDOUBLE, int, int, int); +static int doapr_outch(char **, char **, size_t *, size_t *, int); +static int _dopr(char **sbuffer, char **buffer, + size_t *maxlen, size_t *retlen, int *truncated, + const char *format, va_list args); + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* conversion flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LLONG 4 + +/* some handy macros */ +#define char_to_int(p) (p - '0') +#define OSSL_MAX(p,q) ((p >= q) ? p : q) + +static int +_dopr(char **sbuffer, + char **buffer, + size_t *maxlen, + size_t *retlen, int *truncated, const char *format, va_list args) +{ + char ch; + LLONG value; + LDOUBLE fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + flags = currlen = cflags = min = 0; + max = -1; + ch = *format++; + + while (state != DP_S_DONE) { + if (ch == '\0' || (buffer == NULL && currlen >= *maxlen)) + state = DP_S_DONE; + + switch (state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) + return 0; + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10 * min + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg(args, int); + ch = *format++; + state = DP_S_DOT; + } else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10 * max + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg(args, int); + ch = *format++; + state = DP_S_MOD; + } else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + if (*format == 'l') { + cflags = DP_C_LLONG; + format++; + } else + cflags = DP_C_LONG; + ch = *format++; + break; + case 'q': + cflags = DP_C_LLONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + switch (cflags) { + case DP_C_SHORT: + value = (short int)va_arg(args, int); + break; + case DP_C_LONG: + value = va_arg(args, long int); + break; + case DP_C_LLONG: + value = va_arg(args, LLONG); + break; + default: + value = va_arg(args, int); + break; + } + if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min, + max, flags)) + return 0; + break; + case 'X': + flags |= DP_F_UP; + /* FALLTHROUGH */ + case 'x': + case 'o': + case 'u': + flags |= DP_F_UNSIGNED; + switch (cflags) { + case DP_C_SHORT: + value = (unsigned short int)va_arg(args, unsigned int); + break; + case DP_C_LONG: + value = (LLONG) va_arg(args, unsigned long int); + break; + case DP_C_LLONG: + value = va_arg(args, unsigned LLONG); + break; + default: + value = (LLONG) va_arg(args, unsigned int); + break; + } + if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, + ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), + min, max, flags)) + return 0; + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max, + flags)) + return 0; + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + break; + case 'c': + if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, + va_arg(args, int))) + return 0; + break; + case 's': + strvalue = va_arg(args, char *); + if (max < 0) { + if (buffer) + max = INT_MAX; + else + max = *maxlen; + } + if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, + flags, min, max)) + return 0; + break; + case 'p': + value = (long)va_arg(args, void *); + if (!fmtint(sbuffer, buffer, &currlen, maxlen, + value, 16, min, max, flags | DP_F_NUM)) + return 0; + break; + case 'n': /* XXX */ + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg(args, short int *); + *num = (short int)currlen; + } else if (cflags == DP_C_LONG) { /* XXX */ + long int *num; + num = va_arg(args, long int *); + *num = (long int)currlen; + } else if (cflags == DP_C_LLONG) { /* XXX */ + LLONG *num; + num = va_arg(args, LLONG *); + *num = (LLONG) currlen; + } else { + int *num; + num = va_arg(args, int *); + *num = currlen; + } + break; + case '%': + if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) + return 0; + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + break; + } + } + /* + * We have to truncate if there is no dynamic buffer and we have filled the + * static buffer. + */ + if (buffer == NULL) { + *truncated = (currlen > *maxlen - 1); + if (*truncated) + currlen = *maxlen - 1; + } + if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0')) + return 0; + *retlen = currlen - 1; + return 1; +} + +static int +fmtstr(char **sbuffer, + char **buffer, + size_t *currlen, + size_t *maxlen, const char *value, int flags, int min, int max) +{ + int padlen; + size_t strln; + int cnt = 0; + + if (value == 0) + value = ""; + + strln = strlen(value); + if (strln > INT_MAX) + strln = INT_MAX; + + padlen = min - strln; + if (min < 0 || padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; + + while ((padlen > 0) && (cnt < max)) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++)) + return 0; + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + ++padlen; + ++cnt; + } + return 1; +} + +static int +fmtint(char **sbuffer, + char **buffer, + size_t *currlen, + size_t *maxlen, LLONG value, int base, int min, int max, int flags) +{ + int signvalue = 0; + const char *prefix = ""; + unsigned LLONG uvalue; + char convert[DECIMAL_SIZE(value) + 3]; + int place = 0; + int spadlen = 0; + int zpadlen = 0; + int caps = 0; + + if (max < 0) + max = 0; + uvalue = value; + if (!(flags & DP_F_UNSIGNED)) { + if (value < 0) { + signvalue = '-'; + uvalue = 0 - (unsigned LLONG)value; + } else if (flags & DP_F_PLUS) + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + if (flags & DP_F_NUM) { + if (base == 8) + prefix = "0"; + if (base == 16) + prefix = "0x"; + } + if (flags & DP_F_UP) + caps = 1; + do { + convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned)base]; + uvalue = (uvalue / (unsigned)base); + } while (uvalue && (place < (int)sizeof(convert))); + if (place == sizeof(convert)) + place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = + min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix); + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = OSSL_MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; + + /* spaces */ + while (spadlen > 0) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + --spadlen; + } + + /* sign */ + if (signvalue) + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) + return 0; + + /* prefix */ + while (*prefix) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix)) + return 0; + prefix++; + } + + /* zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) + return 0; + --zpadlen; + } + } + /* digits */ + while (place > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place])) + return 0; + } + + /* left justified spaces */ + while (spadlen < 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + ++spadlen; + } + return 1; +} + +static LDOUBLE abs_val(LDOUBLE value) +{ + LDOUBLE result = value; + if (value < 0) + result = -value; + return result; +} + +static LDOUBLE pow_10(int in_exp) +{ + LDOUBLE result = 1; + while (in_exp) { + result *= 10; + in_exp--; + } + return result; +} + +static long roundv(LDOUBLE value) +{ + long intpart; + intpart = (long)value; + value = value - intpart; + if (value >= 0.5) + intpart++; + return intpart; +} + +static int +fmtfp(char **sbuffer, + char **buffer, + size_t *currlen, + size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags) +{ + int signvalue = 0; + LDOUBLE ufvalue; + char iconvert[20]; + char fconvert[20]; + int iplace = 0; + int fplace = 0; + int padlen = 0; + int zpadlen = 0; + long intpart; + long fracpart; + long max10; + + if (max < 0) + max = 6; + ufvalue = abs_val(fvalue); + if (fvalue < 0) + signvalue = '-'; + else if (flags & DP_F_PLUS) + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + + intpart = (long)ufvalue; + + /* + * sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* + * we "cheat" by converting the fractional part to integer by multiplying + * by a factor of 10 + */ + max10 = roundv(pow_10(max)); + fracpart = roundv(pow_10(max) * (ufvalue - intpart)); + + if (fracpart >= max10) { + intpart++; + fracpart -= max10; + } + + /* convert integer part */ + do { + iconvert[iplace++] = "0123456789"[intpart % 10]; + intpart = (intpart / 10); + } while (intpart && (iplace < (int)sizeof(iconvert))); + if (iplace == sizeof(iconvert)) + iplace--; + iconvert[iplace] = 0; + + /* convert fractional part */ + do { + fconvert[fplace++] = "0123456789"[fracpart % 10]; + fracpart = (fracpart / 10); + } while (fplace < max); + if (fplace == sizeof(fconvert)) + fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) + return 0; + --padlen; + signvalue = 0; + } + while (padlen > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) + return 0; + --padlen; + } + } + while (padlen > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + --padlen; + } + if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) + return 0; + + while (iplace > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace])) + return 0; + } + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0 || (flags & DP_F_NUM)) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.')) + return 0; + + while (fplace > 0) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, + fconvert[--fplace])) + return 0; + } + } + while (zpadlen > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) + return 0; + --zpadlen; + } + + while (padlen < 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + ++padlen; + } + return 1; +} + +#define BUFFER_INC 1024 + +static int +doapr_outch(char **sbuffer, + char **buffer, size_t *currlen, size_t *maxlen, int c) +{ + /* If we haven't at least one buffer, someone has doe a big booboo */ + assert(*sbuffer != NULL || buffer != NULL); + + /* |currlen| must always be <= |*maxlen| */ + assert(*currlen <= *maxlen); + + if (buffer && *currlen == *maxlen) { + if (*maxlen > INT_MAX - BUFFER_INC) + return 0; + + *maxlen += BUFFER_INC; + if (*buffer == NULL) { + *buffer = OPENSSL_malloc(*maxlen); + if (*buffer == NULL) + return 0; + if (*currlen > 0) { + assert(*sbuffer != NULL); + memcpy(*buffer, *sbuffer, *currlen); + } + *sbuffer = NULL; + } else { + char *tmpbuf; + tmpbuf = OPENSSL_realloc(*buffer, *maxlen); + if (tmpbuf == NULL) + return 0; + *buffer = tmpbuf; + } + } + + if (*currlen < *maxlen) { + if (*sbuffer) + (*sbuffer)[(*currlen)++] = (char)c; + else + (*buffer)[(*currlen)++] = (char)c; + } + + return 1; +} + +/***************************************************************************/ + +int BIO_printf(BIO *bio, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + + ret = BIO_vprintf(bio, format, args); + + va_end(args); + return (ret); +} + +int BIO_vprintf(BIO *bio, const char *format, va_list args) +{ + int ret; + size_t retlen; + char hugebuf[1024 * 2]; /* Was previously 10k, which is unreasonable + * in small-stack environments, like threads + * or DOS programs. */ + char *hugebufp = hugebuf; + size_t hugebufsize = sizeof(hugebuf); + char *dynbuf = NULL; + int ignored; + + dynbuf = NULL; + CRYPTO_push_info("doapr()"); + if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, + args)) { + OPENSSL_free(dynbuf); + return -1; + } + if (dynbuf) { + ret = BIO_write(bio, dynbuf, (int)retlen); + OPENSSL_free(dynbuf); + } else { + ret = BIO_write(bio, hugebuf, (int)retlen); + } + CRYPTO_pop_info(); + return (ret); +} + +/* + * As snprintf is not available everywhere, we provide our own + * implementation. This function has nothing to do with BIOs, but it's + * closely related to BIO_printf, and we need *some* name prefix ... (XXX the + * function should be renamed, but to what?) + */ +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + + ret = BIO_vsnprintf(buf, n, format, args); + + va_end(args); + return (ret); +} + +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +{ + size_t retlen; + int truncated; + + if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args)) + return -1; + + if (truncated) + /* + * In case of truncation, return -1 like traditional snprintf. + * (Current drafts for ISO/IEC 9899 say snprintf should return the + * number of characters that would have been written, had the buffer + * been large enough.) + */ + return -1; + else + return (retlen <= INT_MAX) ? (int)retlen : -1; +} diff --git a/Sources/COpenSSL/b_sock.c b/Sources/COpenSSL/b_sock.c new file mode 100644 index 00000000..84cb83b6 --- /dev/null +++ b/Sources/COpenSSL/b_sock.c @@ -0,0 +1,983 @@ +/* crypto/bio/b_sock.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define _DEFAULT_SOURCE +#define _BSD_SOURCE + +#include +#include +#include +#define USE_SOCKETS +#include "cryptlib.h" +#include "bio.h" +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK) +# include +# if defined(NETWARE_CLIB) +# include +NETDB_DEFINE_CONTEXT +# endif +#endif +#ifndef OPENSSL_NO_SOCK +# include "dso.h" +# define SOCKET_PROTOCOL IPPROTO_TCP +# ifdef SO_MAXCONN +# define MAX_LISTEN SO_MAXCONN +# elif defined(SOMAXCONN) +# define MAX_LISTEN SOMAXCONN +# else +# define MAX_LISTEN 32 +# endif +# if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) +static int wsa_init_done = 0; +# endif + +# if defined(__GLIBC__) +# define HAVE_GETHOSTBYNAME_R +# define GETHOSTNAME_R_BUF (2 * 1024) +# endif + +/* + * WSAAPI specifier is required to make indirect calls to run-time + * linked WinSock 2 functions used in this module, to be specific + * [get|free]addrinfo and getnameinfo. This is because WinSock uses + * uses non-C calling convention, __stdcall vs. __cdecl, on x86 + * Windows. On non-WinSock platforms WSAAPI needs to be void. + */ +# ifndef WSAAPI +# define WSAAPI +# endif + +# if 0 +static unsigned long BIO_ghbn_hits = 0L; +static unsigned long BIO_ghbn_miss = 0L; + +# define GHBN_NUM 4 +static struct ghbn_cache_st { + char name[129]; + struct hostent *ent; + unsigned long order; +} ghbn_cache[GHBN_NUM]; +# endif + +static int get_ip(const char *str, unsigned char *ip); +# if 0 +static void ghbn_free(struct hostent *a); +static struct hostent *ghbn_dup(struct hostent *a); +# endif +int BIO_get_host_ip(const char *str, unsigned char *ip) +{ + int i; + int err = 1; + int locked = 0; + struct hostent *he = NULL; +# ifdef HAVE_GETHOSTBYNAME_R + char buf[GETHOSTNAME_R_BUF]; + struct hostent hostent; + int h_errnop; +# endif + + i = get_ip(str, ip); + if (i < 0) { + BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS); + goto err; + } + + /* + * At this point, we have something that is most probably correct in some + * way, so let's init the socket. + */ + if (BIO_sock_init() != 1) + return 0; /* don't generate another error code here */ + + /* + * If the string actually contained an IP address, we need not do + * anything more + */ + if (i > 0) + return (1); + + /* if gethostbyname_r is supported, use it. */ +# ifdef HAVE_GETHOSTBYNAME_R + memset(&hostent, 0x00, sizeof(hostent)); + /* gethostbyname_r() sets |he| to NULL on error, we check it further down */ + gethostbyname_r(str, &hostent, buf, sizeof(buf), &he, &h_errnop); +# else + /* do a gethostbyname */ + CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); + locked = 1; + he = BIO_gethostbyname(str); +# endif + + if (he == NULL) { + BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP); + goto err; + } + + /* cast to short because of win16 winsock definition */ + if ((short)he->h_addrtype != AF_INET) { + BIOerr(BIO_F_BIO_GET_HOST_IP, + BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); + goto err; + } + for (i = 0; i < 4; i++) + ip[i] = he->h_addr_list[0][i]; + err = 0; + + err: + if (locked) + CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); + if (err) { + ERR_add_error_data(2, "host=", str); + return 0; + } else + return 1; +} + +int BIO_get_port(const char *str, unsigned short *port_ptr) +{ + int i; + struct servent *s; + + if (str == NULL) { + BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); + return (0); + } + i = atoi(str); + if (i != 0) + *port_ptr = (unsigned short)i; + else { + CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); + /* + * Note: under VMS with SOCKETSHR, it seems like the first parameter + * is 'char *', instead of 'const char *' + */ +# ifndef CONST_STRICT + s = getservbyname((char *)str, "tcp"); +# else + s = getservbyname(str, "tcp"); +# endif + if (s != NULL) + *port_ptr = ntohs((unsigned short)s->s_port); + CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); + if (s == NULL) { + if (strcmp(str, "http") == 0) + *port_ptr = 80; + else if (strcmp(str, "telnet") == 0) + *port_ptr = 23; + else if (strcmp(str, "socks") == 0) + *port_ptr = 1080; + else if (strcmp(str, "https") == 0) + *port_ptr = 443; + else if (strcmp(str, "ssl") == 0) + *port_ptr = 443; + else if (strcmp(str, "ftp") == 0) + *port_ptr = 21; + else if (strcmp(str, "gopher") == 0) + *port_ptr = 70; +# if 0 + else if (strcmp(str, "wais") == 0) + *port_ptr = 21; +# endif + else { + SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error()); + ERR_add_error_data(3, "service='", str, "'"); + return (0); + } + } + } + return (1); +} + +int BIO_sock_error(int sock) +{ + int j, i; + union { + size_t s; + int i; + } size; + +# if defined(OPENSSL_SYS_BEOS_R5) + return 0; +# endif + + /* heuristic way to adapt for platforms that expect 64-bit optlen */ + size.s = 0, size.i = sizeof(j); + /* + * Note: under Windows the third parameter is of type (char *) whereas + * under other systems it is (void *) if you don't have a cast it will + * choke the compiler: if you do have a cast then you can either go for + * (char *) or (void *). + */ + i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size); + if (i < 0) + return (1); + else + return (j); +} + +# if 0 +long BIO_ghbn_ctrl(int cmd, int iarg, char *parg) +{ + int i; + char **p; + + switch (cmd) { + case BIO_GHBN_CTRL_HITS: + return (BIO_ghbn_hits); + /* break; */ + case BIO_GHBN_CTRL_MISSES: + return (BIO_ghbn_miss); + /* break; */ + case BIO_GHBN_CTRL_CACHE_SIZE: + return (GHBN_NUM); + /* break; */ + case BIO_GHBN_CTRL_GET_ENTRY: + if ((iarg >= 0) && (iarg < GHBN_NUM) && (ghbn_cache[iarg].order > 0)) { + p = (char **)parg; + if (p == NULL) + return (0); + *p = ghbn_cache[iarg].name; + ghbn_cache[iarg].name[128] = '\0'; + return (1); + } + return (0); + /* break; */ + case BIO_GHBN_CTRL_FLUSH: + for (i = 0; i < GHBN_NUM; i++) + ghbn_cache[i].order = 0; + break; + default: + return (0); + } + return (1); +} +# endif + +# if 0 +static struct hostent *ghbn_dup(struct hostent *a) +{ + struct hostent *ret; + int i, j; + + MemCheck_off(); + ret = (struct hostent *)OPENSSL_malloc(sizeof(struct hostent)); + if (ret == NULL) + return (NULL); + memset(ret, 0, sizeof(struct hostent)); + + for (i = 0; a->h_aliases[i] != NULL; i++) ; + i++; + ret->h_aliases = (char **)OPENSSL_malloc(i * sizeof(char *)); + if (ret->h_aliases == NULL) + goto err; + memset(ret->h_aliases, 0, i * sizeof(char *)); + + for (i = 0; a->h_addr_list[i] != NULL; i++) ; + i++; + ret->h_addr_list = (char **)OPENSSL_malloc(i * sizeof(char *)); + if (ret->h_addr_list == NULL) + goto err; + memset(ret->h_addr_list, 0, i * sizeof(char *)); + + j = strlen(a->h_name) + 1; + if ((ret->h_name = OPENSSL_malloc(j)) == NULL) + goto err; + memcpy((char *)ret->h_name, a->h_name, j); + for (i = 0; a->h_aliases[i] != NULL; i++) { + j = strlen(a->h_aliases[i]) + 1; + if ((ret->h_aliases[i] = OPENSSL_malloc(j)) == NULL) + goto err; + memcpy(ret->h_aliases[i], a->h_aliases[i], j); + } + ret->h_length = a->h_length; + ret->h_addrtype = a->h_addrtype; + for (i = 0; a->h_addr_list[i] != NULL; i++) { + if ((ret->h_addr_list[i] = OPENSSL_malloc(a->h_length)) == NULL) + goto err; + memcpy(ret->h_addr_list[i], a->h_addr_list[i], a->h_length); + } + if (0) { + err: + if (ret != NULL) + ghbn_free(ret); + ret = NULL; + } + MemCheck_on(); + return (ret); +} + +static void ghbn_free(struct hostent *a) +{ + int i; + + if (a == NULL) + return; + + if (a->h_aliases != NULL) { + for (i = 0; a->h_aliases[i] != NULL; i++) + OPENSSL_free(a->h_aliases[i]); + OPENSSL_free(a->h_aliases); + } + if (a->h_addr_list != NULL) { + for (i = 0; a->h_addr_list[i] != NULL; i++) + OPENSSL_free(a->h_addr_list[i]); + OPENSSL_free(a->h_addr_list); + } + if (a->h_name != NULL) + OPENSSL_free(a->h_name); + OPENSSL_free(a); +} + +# endif + +struct hostent *BIO_gethostbyname(const char *name) +{ +# if 1 + /* + * Caching gethostbyname() results forever is wrong, so we have to let + * the true gethostbyname() worry about this + */ +# if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__)) + return gethostbyname((char *)name); +# else + return gethostbyname(name); +# endif +# else + struct hostent *ret; + int i, lowi = 0, j; + unsigned long low = (unsigned long)-1; + +# if 0 + /* + * It doesn't make sense to use locking here: The function interface is + * not thread-safe, because threads can never be sure when some other + * thread destroys the data they were given a pointer to. + */ + CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); +# endif + j = strlen(name); + if (j < 128) { + for (i = 0; i < GHBN_NUM; i++) { + if (low > ghbn_cache[i].order) { + low = ghbn_cache[i].order; + lowi = i; + } + if (ghbn_cache[i].order > 0) { + if (strncmp(name, ghbn_cache[i].name, 128) == 0) + break; + } + } + } else + i = GHBN_NUM; + + if (i == GHBN_NUM) { /* no hit */ + BIO_ghbn_miss++; + /* + * Note: under VMS with SOCKETSHR, it seems like the first parameter + * is 'char *', instead of 'const char *' + */ +# ifndef CONST_STRICT + ret = gethostbyname((char *)name); +# else + ret = gethostbyname(name); +# endif + + if (ret == NULL) + goto end; + if (j > 128) { /* too big to cache */ +# if 0 + /* + * If we were trying to make this function thread-safe (which is + * bound to fail), we'd have to give up in this case (or allocate + * more memory). + */ + ret = NULL; +# endif + goto end; + } + + /* else add to cache */ + if (ghbn_cache[lowi].ent != NULL) + ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */ + ghbn_cache[lowi].name[0] = '\0'; + + if ((ret = ghbn_cache[lowi].ent = ghbn_dup(ret)) == NULL) { + BIOerr(BIO_F_BIO_GETHOSTBYNAME, ERR_R_MALLOC_FAILURE); + goto end; + } + strncpy(ghbn_cache[lowi].name, name, 128); + ghbn_cache[lowi].order = BIO_ghbn_miss + BIO_ghbn_hits; + } else { + BIO_ghbn_hits++; + ret = ghbn_cache[i].ent; + ghbn_cache[i].order = BIO_ghbn_miss + BIO_ghbn_hits; + } + end: +# if 0 + CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); +# endif + return (ret); +# endif +} + +int BIO_sock_init(void) +{ +# ifdef OPENSSL_SYS_WINDOWS + static struct WSAData wsa_state; + + if (!wsa_init_done) { + int err; + + wsa_init_done = 1; + memset(&wsa_state, 0, sizeof(wsa_state)); + /* + * Not making wsa_state available to the rest of the code is formally + * wrong. But the structures we use are [beleived to be] invariable + * among Winsock DLLs, while API availability is [expected to be] + * probed at run-time with DSO_global_lookup. + */ + if (WSAStartup(0x0202, &wsa_state) != 0) { + err = WSAGetLastError(); + SYSerr(SYS_F_WSASTARTUP, err); + BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); + return (-1); + } + } +# endif /* OPENSSL_SYS_WINDOWS */ +# ifdef WATT32 + extern int _watt_do_exit; + _watt_do_exit = 0; /* don't make sock_init() call exit() */ + if (sock_init()) + return (-1); +# endif + +# if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) + WORD wVerReq; + WSADATA wsaData; + int err; + + if (!wsa_init_done) { + wsa_init_done = 1; + wVerReq = MAKEWORD(2, 0); + err = WSAStartup(wVerReq, &wsaData); + if (err != 0) { + SYSerr(SYS_F_WSASTARTUP, err); + BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); + return (-1); + } + } +# endif + + return (1); +} + +void BIO_sock_cleanup(void) +{ +# ifdef OPENSSL_SYS_WINDOWS + if (wsa_init_done) { + wsa_init_done = 0; +# if 0 /* this call is claimed to be non-present in + * Winsock2 */ + WSACancelBlockingCall(); +# endif + WSACleanup(); + } +# elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) + if (wsa_init_done) { + wsa_init_done = 0; + WSACleanup(); + } +# endif +} + +# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000 + +int BIO_socket_ioctl(int fd, long type, void *arg) +{ + int i; + +# ifdef __DJGPP__ + i = ioctlsocket(fd, type, (char *)arg); +# else +# if defined(OPENSSL_SYS_VMS) + /*- + * 2011-02-18 SMS. + * VMS ioctl() can't tolerate a 64-bit "void *arg", but we + * observe that all the consumers pass in an "unsigned long *", + * so we arrange a local copy with a short pointer, and use + * that, instead. + */ +# if __INITIAL_POINTER_SIZE == 64 +# define ARG arg_32p +# pragma pointer_size save +# pragma pointer_size 32 + unsigned long arg_32; + unsigned long *arg_32p; +# pragma pointer_size restore + arg_32p = &arg_32; + arg_32 = *((unsigned long *)arg); +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define ARG arg +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ +# else /* defined(OPENSSL_SYS_VMS) */ +# define ARG arg +# endif /* defined(OPENSSL_SYS_VMS) [else] */ + + i = ioctlsocket(fd, type, ARG); +# endif /* __DJGPP__ */ + if (i < 0) + SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error()); + return (i); +} +# endif /* __VMS_VER */ + +/* + * The reason I have implemented this instead of using sscanf is because + * Visual C 1.52c gives an unresolved external when linking a DLL :-( + */ +static int get_ip(const char *str, unsigned char ip[4]) +{ + unsigned int tmp[4]; + int num = 0, c, ok = 0; + + tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; + + for (;;) { + c = *(str++); + if ((c >= '0') && (c <= '9')) { + ok = 1; + tmp[num] = tmp[num] * 10 + c - '0'; + if (tmp[num] > 255) + return (0); + } else if (c == '.') { + if (!ok) + return (-1); + if (num == 3) + return (0); + num++; + ok = 0; + } else if (c == '\0' && (num == 3) && ok) + break; + else + return (0); + } + ip[0] = tmp[0]; + ip[1] = tmp[1]; + ip[2] = tmp[2]; + ip[3] = tmp[3]; + return (1); +} + +int BIO_get_accept_socket(char *host, int bind_mode) +{ + int ret = 0; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } server, client; + int s = INVALID_SOCKET, cs, addrlen; + unsigned char ip[4]; + unsigned short port; + char *str = NULL, *e; + char *h, *p; + unsigned long l; + int err_num; + + if (BIO_sock_init() != 1) + return (INVALID_SOCKET); + + if ((str = BUF_strdup(host)) == NULL) + return (INVALID_SOCKET); + + h = p = NULL; + h = str; + for (e = str; *e; e++) { + if (*e == ':') { + p = e; + } else if (*e == '/') { + *e = '\0'; + break; + } + } + if (p) + *p++ = '\0'; /* points at last ':', '::port' is special + * [see below] */ + else + p = h, h = NULL; + +# ifdef EAI_FAMILY + do { + static union { + void *p; + int (WSAAPI *f) (const char *, const char *, + const struct addrinfo *, struct addrinfo **); + } p_getaddrinfo = { + NULL + }; + static union { + void *p; + void (WSAAPI *f) (struct addrinfo *); + } p_freeaddrinfo = { + NULL + }; + struct addrinfo *res, hint; + + if (p_getaddrinfo.p == NULL) { + if ((p_getaddrinfo.p = DSO_global_lookup("getaddrinfo")) == NULL + || (p_freeaddrinfo.p = + DSO_global_lookup("freeaddrinfo")) == NULL) + p_getaddrinfo.p = (void *)-1; + } + if (p_getaddrinfo.p == (void *)-1) + break; + + /* + * '::port' enforces IPv6 wildcard listener. Some OSes, e.g. Solaris, + * default to IPv6 without any hint. Also note that commonly IPv6 + * wildchard socket can service IPv4 connections just as well... + */ + memset(&hint, 0, sizeof(hint)); + hint.ai_flags = AI_PASSIVE; + if (h) { + if (strchr(h, ':')) { + if (h[1] == '\0') + h = NULL; +# if OPENSSL_USE_IPV6 + hint.ai_family = AF_INET6; +# else + h = NULL; +# endif + } else if (h[0] == '*' && h[1] == '\0') { + hint.ai_family = AF_INET; + h = NULL; + } + } + + if ((*p_getaddrinfo.f) (h, p, &hint, &res)) + break; + + addrlen = res->ai_addrlen <= sizeof(server) ? + res->ai_addrlen : sizeof(server); + memcpy(&server, res->ai_addr, addrlen); + + (*p_freeaddrinfo.f) (res); + goto again; + } while (0); +# endif + + if (!BIO_get_port(p, &port)) + goto err; + + memset((char *)&server, 0, sizeof(server)); + server.sa_in.sin_family = AF_INET; + server.sa_in.sin_port = htons(port); + addrlen = sizeof(server.sa_in); + + if (h == NULL || strcmp(h, "*") == 0) + server.sa_in.sin_addr.s_addr = INADDR_ANY; + else { + if (!BIO_get_host_ip(h, &(ip[0]))) + goto err; + l = (unsigned long) + ((unsigned long)ip[0] << 24L) | + ((unsigned long)ip[1] << 16L) | + ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]); + server.sa_in.sin_addr.s_addr = htonl(l); + } + + again: + s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL); + if (s == INVALID_SOCKET) { + SYSerr(SYS_F_SOCKET, get_last_socket_error()); + ERR_add_error_data(3, "port='", host, "'"); + BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET); + goto err; + } +# ifdef SO_REUSEADDR + if (bind_mode == BIO_BIND_REUSEADDR) { + int i = 1; + + ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)); + bind_mode = BIO_BIND_NORMAL; + } +# endif + if (bind(s, &server.sa, addrlen) == -1) { +# ifdef SO_REUSEADDR + err_num = get_last_socket_error(); + if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && +# ifdef OPENSSL_SYS_WINDOWS + /* + * Some versions of Windows define EADDRINUSE to a dummy value. + */ + (err_num == WSAEADDRINUSE)) +# else + (err_num == EADDRINUSE)) +# endif + { + client = server; + if (h == NULL || strcmp(h, "*") == 0) { +# if OPENSSL_USE_IPV6 + if (client.sa.sa_family == AF_INET6) { + memset(&client.sa_in6.sin6_addr, 0, + sizeof(client.sa_in6.sin6_addr)); + client.sa_in6.sin6_addr.s6_addr[15] = 1; + } else +# endif + if (client.sa.sa_family == AF_INET) { + client.sa_in.sin_addr.s_addr = htonl(0x7F000001); + } else + goto err; + } + cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL); + if (cs != INVALID_SOCKET) { + int ii; + ii = connect(cs, &client.sa, addrlen); + closesocket(cs); + if (ii == INVALID_SOCKET) { + bind_mode = BIO_BIND_REUSEADDR; + closesocket(s); + goto again; + } + /* else error */ + } + /* else error */ + } +# endif + SYSerr(SYS_F_BIND, err_num); + ERR_add_error_data(3, "port='", host, "'"); + BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET); + goto err; + } + if (listen(s, MAX_LISTEN) == -1) { + SYSerr(SYS_F_BIND, get_last_socket_error()); + ERR_add_error_data(3, "port='", host, "'"); + BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET); + goto err; + } + ret = 1; + err: + if (str != NULL) + OPENSSL_free(str); + if ((ret == 0) && (s != INVALID_SOCKET)) { + closesocket(s); + s = INVALID_SOCKET; + } + return (s); +} + +int BIO_accept(int sock, char **addr) +{ + int ret = INVALID_SOCKET; + unsigned long l; + unsigned short port; + char *p; + + struct { + /* + * As for following union. Trouble is that there are platforms + * that have socklen_t and there are platforms that don't, on + * some platforms socklen_t is int and on some size_t. So what + * one can do? One can cook #ifdef spaghetti, which is nothing + * but masochistic. Or one can do union between int and size_t. + * One naturally does it primarily for 64-bit platforms where + * sizeof(int) != sizeof(size_t). But would it work? Note that + * if size_t member is initialized to 0, then later int member + * assignment naturally does the job on little-endian platforms + * regardless accept's expectations! What about big-endians? + * If accept expects int*, then it works, and if size_t*, then + * length value would appear as unreasonably large. But this + * won't prevent it from filling in the address structure. The + * trouble of course would be if accept returns more data than + * actual buffer can accomodate and overwrite stack... That's + * where early OPENSSL_assert comes into picture. Besides, the + * only 64-bit big-endian platform found so far that expects + * size_t* is HP-UX, where stack grows towards higher address. + * + */ + union { + size_t s; + int i; + } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } from; + } sa; + + sa.len.s = 0; + sa.len.i = sizeof(sa.from); + memset(&sa.from, 0, sizeof(sa.from)); + ret = accept(sock, &sa.from.sa, (void *)&sa.len); + if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { + OPENSSL_assert(sa.len.s <= sizeof(sa.from)); + sa.len.i = (int)sa.len.s; + /* use sa.len.i from this point */ + } + if (ret == INVALID_SOCKET) { + if (BIO_sock_should_retry(ret)) + return -2; + SYSerr(SYS_F_ACCEPT, get_last_socket_error()); + BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR); + goto end; + } + + if (addr == NULL) + goto end; + +# ifdef EAI_FAMILY + do { + char h[NI_MAXHOST], s[NI_MAXSERV]; + size_t nl; + static union { + void *p; + int (WSAAPI *f) (const struct sockaddr *, size_t /* socklen_t */ , + char *, size_t, char *, size_t, int); + } p_getnameinfo = { + NULL + }; + /* + * 2nd argument to getnameinfo is specified to be socklen_t. + * Unfortunately there is a number of environments where socklen_t is + * not defined. As it's passed by value, it's safe to pass it as + * size_t... + */ + + if (p_getnameinfo.p == NULL) { + if ((p_getnameinfo.p = DSO_global_lookup("getnameinfo")) == NULL) + p_getnameinfo.p = (void *)-1; + } + if (p_getnameinfo.p == (void *)-1) + break; + + if ((*p_getnameinfo.f) (&sa.from.sa, sa.len.i, h, sizeof(h), s, + sizeof(s), NI_NUMERICHOST | NI_NUMERICSERV)) + break; + nl = strlen(h) + strlen(s) + 2; + p = *addr; + if (p) { + *p = '\0'; + p = OPENSSL_realloc(p, nl); + } else { + p = OPENSSL_malloc(nl); + } + if (p == NULL) { + BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); + goto end; + } + *addr = p; + BIO_snprintf(*addr, nl, "%s:%s", h, s); + goto end; + } while (0); +# endif + if (sa.from.sa.sa_family != AF_INET) + goto end; + l = ntohl(sa.from.sa_in.sin_addr.s_addr); + port = ntohs(sa.from.sa_in.sin_port); + if (*addr == NULL) { + if ((p = OPENSSL_malloc(24)) == NULL) { + BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); + goto end; + } + *addr = p; + } + BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d", + (unsigned char)(l >> 24L) & 0xff, + (unsigned char)(l >> 16L) & 0xff, + (unsigned char)(l >> 8L) & 0xff, + (unsigned char)(l) & 0xff, port); + end: + return (ret); +} + +int BIO_set_tcp_ndelay(int s, int on) +{ + int ret = 0; +# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP)) + int opt; + +# ifdef SOL_TCP + opt = SOL_TCP; +# else +# ifdef IPPROTO_TCP + opt = IPPROTO_TCP; +# endif +# endif + + ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on)); +# endif + return (ret == 0); +} + +int BIO_socket_nbio(int s, int mode) +{ + int ret = -1; + int l; + + l = mode; +# ifdef FIONBIO + ret = BIO_socket_ioctl(s, FIONBIO, &l); +# endif + return (ret == 0); +} +#endif diff --git a/Sources/COpenSSL/bf_.c b/Sources/COpenSSL/bf_.c new file mode 100644 index 00000000..0833fede --- /dev/null +++ b/Sources/COpenSSL/bf_.c @@ -0,0 +1,2108 @@ +/* crypto/bio/bf_buff.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include "bio.h" + +static int buffer_write(BIO *h, const char *buf, int num); +static int buffer_read(BIO *h, char *buf, int size); +static int buffer_puts(BIO *h, const char *str); +static int buffer_gets(BIO *h, char *str, int size); +static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int buffer_new(BIO *h); +static int buffer_free(BIO *data); +static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +#define DEFAULT_BUFFER_SIZE 4096 + +static BIO_METHOD methods_buffer = { + BIO_TYPE_BUFFER, + "buffer", + buffer_write, + buffer_read, + buffer_puts, + buffer_gets, + buffer_ctrl, + buffer_new, + buffer_free, + buffer_callback_ctrl, +}; + +BIO_METHOD *BIO_f_buffer(void) +{ + return (&methods_buffer); +} + +static int buffer_new(BIO *bi) +{ + BIO_F_BUFFER_CTX *ctx; + + ctx = (BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX)); + if (ctx == NULL) + return (0); + ctx->ibuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE); + if (ctx->ibuf == NULL) { + OPENSSL_free(ctx); + return (0); + } + ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE); + if (ctx->obuf == NULL) { + OPENSSL_free(ctx->ibuf); + OPENSSL_free(ctx); + return (0); + } + ctx->ibuf_size = DEFAULT_BUFFER_SIZE; + ctx->obuf_size = DEFAULT_BUFFER_SIZE; + ctx->ibuf_len = 0; + ctx->ibuf_off = 0; + ctx->obuf_len = 0; + ctx->obuf_off = 0; + + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int buffer_free(BIO *a) +{ + BIO_F_BUFFER_CTX *b; + + if (a == NULL) + return (0); + b = (BIO_F_BUFFER_CTX *)a->ptr; + if (b->ibuf != NULL) + OPENSSL_free(b->ibuf); + if (b->obuf != NULL) + OPENSSL_free(b->obuf); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int buffer_read(BIO *b, char *out, int outl) +{ + int i, num = 0; + BIO_F_BUFFER_CTX *ctx; + + if (out == NULL) + return (0); + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + num = 0; + BIO_clear_retry_flags(b); + + start: + i = ctx->ibuf_len; + /* If there is stuff left over, grab it */ + if (i != 0) { + if (i > outl) + i = outl; + memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i); + ctx->ibuf_off += i; + ctx->ibuf_len -= i; + num += i; + if (outl == i) + return (num); + outl -= i; + out += i; + } + + /* + * We may have done a partial read. try to do more. We have nothing in + * the buffer. If we get an error and have read some data, just return it + * and let them retry to get the error again. copy direct to parent + * address space + */ + if (outl > ctx->ibuf_size) { + for (;;) { + i = BIO_read(b->next_bio, out, outl); + if (i <= 0) { + BIO_copy_next_retry(b); + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + num += i; + if (outl == i) + return (num); + out += i; + outl -= i; + } + } + /* else */ + + /* we are going to be doing some buffering */ + i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size); + if (i <= 0) { + BIO_copy_next_retry(b); + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + ctx->ibuf_off = 0; + ctx->ibuf_len = i; + + /* Lets re-read using ourselves :-) */ + goto start; +} + +static int buffer_write(BIO *b, const char *in, int inl) +{ + int i, num = 0; + BIO_F_BUFFER_CTX *ctx; + + if ((in == NULL) || (inl <= 0)) + return (0); + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + BIO_clear_retry_flags(b); + start: + i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off); + /* add to buffer and return */ + if (i >= inl) { + memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl); + ctx->obuf_len += inl; + return (num + inl); + } + /* else */ + /* stuff already in buffer, so add to it first, then flush */ + if (ctx->obuf_len != 0) { + if (i > 0) { /* lets fill it up if we can */ + memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i); + in += i; + inl -= i; + num += i; + ctx->obuf_len += i; + } + /* we now have a full buffer needing flushing */ + for (;;) { + i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]), + ctx->obuf_len); + if (i <= 0) { + BIO_copy_next_retry(b); + + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + ctx->obuf_off += i; + ctx->obuf_len -= i; + if (ctx->obuf_len == 0) + break; + } + } + /* + * we only get here if the buffer has been flushed and we still have + * stuff to write + */ + ctx->obuf_off = 0; + + /* we now have inl bytes to write */ + while (inl >= ctx->obuf_size) { + i = BIO_write(b->next_bio, in, inl); + if (i <= 0) { + BIO_copy_next_retry(b); + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + num += i; + in += i; + inl -= i; + if (inl == 0) + return (num); + } + + /* + * copy the rest into the buffer since we have only a small amount left + */ + goto start; +} + +static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + BIO_F_BUFFER_CTX *ctx; + long ret = 1; + char *p1, *p2; + int r, i, *ip; + int ibs, obs; + + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->ibuf_off = 0; + ctx->ibuf_len = 0; + ctx->obuf_off = 0; + ctx->obuf_len = 0; + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_INFO: + ret = (long)ctx->obuf_len; + break; + case BIO_C_GET_BUFF_NUM_LINES: + ret = 0; + p1 = ctx->ibuf; + for (i = 0; i < ctx->ibuf_len; i++) { + if (p1[ctx->ibuf_off + i] == '\n') + ret++; + } + break; + case BIO_CTRL_WPENDING: + ret = (long)ctx->obuf_len; + if (ret == 0) { + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + break; + case BIO_CTRL_PENDING: + ret = (long)ctx->ibuf_len; + if (ret == 0) { + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + break; + case BIO_C_SET_BUFF_READ_DATA: + if (num > ctx->ibuf_size) { + p1 = OPENSSL_malloc((int)num); + if (p1 == NULL) + goto malloc_error; + if (ctx->ibuf != NULL) + OPENSSL_free(ctx->ibuf); + ctx->ibuf = p1; + } + ctx->ibuf_off = 0; + ctx->ibuf_len = (int)num; + memcpy(ctx->ibuf, ptr, (int)num); + ret = 1; + break; + case BIO_C_SET_BUFF_SIZE: + if (ptr != NULL) { + ip = (int *)ptr; + if (*ip == 0) { + ibs = (int)num; + obs = ctx->obuf_size; + } else { /* if (*ip == 1) */ + + ibs = ctx->ibuf_size; + obs = (int)num; + } + } else { + ibs = (int)num; + obs = (int)num; + } + p1 = ctx->ibuf; + p2 = ctx->obuf; + if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) { + p1 = (char *)OPENSSL_malloc((int)num); + if (p1 == NULL) + goto malloc_error; + } + if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) { + p2 = (char *)OPENSSL_malloc((int)num); + if (p2 == NULL) { + if (p1 != ctx->ibuf) + OPENSSL_free(p1); + goto malloc_error; + } + } + if (ctx->ibuf != p1) { + OPENSSL_free(ctx->ibuf); + ctx->ibuf = p1; + ctx->ibuf_off = 0; + ctx->ibuf_len = 0; + ctx->ibuf_size = ibs; + } + if (ctx->obuf != p2) { + OPENSSL_free(ctx->obuf); + ctx->obuf = p2; + ctx->obuf_off = 0; + ctx->obuf_len = 0; + ctx->obuf_size = obs; + } + break; + case BIO_C_DO_STATE_MACHINE: + if (b->next_bio == NULL) + return (0); + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_FLUSH: + if (b->next_bio == NULL) + return (0); + if (ctx->obuf_len <= 0) { + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + + for (;;) { + BIO_clear_retry_flags(b); + if (ctx->obuf_len > 0) { + r = BIO_write(b->next_bio, + &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len); +#if 0 + fprintf(stderr, "FLUSH [%3d] %3d -> %3d\n", ctx->obuf_off, + ctx->obuf_len, r); +#endif + BIO_copy_next_retry(b); + if (r <= 0) + return ((long)r); + ctx->obuf_off += r; + ctx->obuf_len -= r; + } else { + ctx->obuf_len = 0; + ctx->obuf_off = 0; + ret = 1; + break; + } + } + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) || + !BIO_set_write_buffer_size(dbio, ctx->obuf_size)) + ret = 0; + break; + default: + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); + malloc_error: + BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE); + return (0); +} + +static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int buffer_gets(BIO *b, char *buf, int size) +{ + BIO_F_BUFFER_CTX *ctx; + int num = 0, i, flag; + char *p; + + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + size--; /* reserve space for a '\0' */ + BIO_clear_retry_flags(b); + + for (;;) { + if (ctx->ibuf_len > 0) { + p = &(ctx->ibuf[ctx->ibuf_off]); + flag = 0; + for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) { + *(buf++) = p[i]; + if (p[i] == '\n') { + flag = 1; + i++; + break; + } + } + num += i; + size -= i; + ctx->ibuf_len -= i; + ctx->ibuf_off += i; + if (flag || size == 0) { + *buf = '\0'; + return (num); + } + } else { /* read another chunk */ + + i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size); + if (i <= 0) { + BIO_copy_next_retry(b); + *buf = '\0'; + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + ctx->ibuf_len = i; + ctx->ibuf_off = 0; + } + } +} + +static int buffer_puts(BIO *b, const char *str) +{ + return (buffer_write(b, str, strlen(str))); +} +/* crypto/bf/bf_cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "blowfish.h" +#include "bf_locl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num, int encrypt) +{ + register BF_LONG v0, v1, t; + register int n = *num; + register long l = length; + BF_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + BF_encrypt((BF_LONG *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + BF_encrypt((BF_LONG *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} +/* crypto/bf/bf_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "blowfish.h" +// #include "bf_locl.h" +#include "opensslv.h" + +/* + * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From + * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE + * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) + */ + +const char BF_version[] = "Blowfish" OPENSSL_VERSION_PTEXT; + +const char *BF_options(void) +{ +#ifdef BF_PTR + return ("blowfish(ptr)"); +#elif defined(BF_PTR2) + return ("blowfish(ptr2)"); +#else + return ("blowfish(idx)"); +#endif +} + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int encrypt) +{ + BF_LONG l, d[2]; + + n2l(in, l); + d[0] = l; + n2l(in, l); + d[1] = l; + if (encrypt) + BF_encrypt(d, key); + else + BF_decrypt(d, key); + l = d[0]; + l2n(l, out); + l = d[1]; + l2n(l, out); + l = d[0] = d[1] = 0; +} +/* crypto/bf/bf_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "blowfish.h" +// #include "bf_locl.h" + +/* + * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From + * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE + * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) + */ + +#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20) +# error If you set BF_ROUNDS to some value other than 16 or 20, you will have \ +to modify the code. +#endif + +void BF_encrypt(BF_LONG *data, const BF_KEY *key) +{ +#ifndef BF_PTR2 + register BF_LONG l, r; + register const BF_LONG *p, *s; + + p = key->P; + s = &(key->S[0]); + l = data[0]; + r = data[1]; + + l ^= p[0]; + BF_ENC(r, l, s, p[1]); + BF_ENC(l, r, s, p[2]); + BF_ENC(r, l, s, p[3]); + BF_ENC(l, r, s, p[4]); + BF_ENC(r, l, s, p[5]); + BF_ENC(l, r, s, p[6]); + BF_ENC(r, l, s, p[7]); + BF_ENC(l, r, s, p[8]); + BF_ENC(r, l, s, p[9]); + BF_ENC(l, r, s, p[10]); + BF_ENC(r, l, s, p[11]); + BF_ENC(l, r, s, p[12]); + BF_ENC(r, l, s, p[13]); + BF_ENC(l, r, s, p[14]); + BF_ENC(r, l, s, p[15]); + BF_ENC(l, r, s, p[16]); +# if BF_ROUNDS == 20 + BF_ENC(r, l, s, p[17]); + BF_ENC(l, r, s, p[18]); + BF_ENC(r, l, s, p[19]); + BF_ENC(l, r, s, p[20]); +# endif + r ^= p[BF_ROUNDS + 1]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +#else + register BF_LONG l, r, t, *k; + + l = data[0]; + r = data[1]; + k = (BF_LONG *)key; + + l ^= k[0]; + BF_ENC(r, l, k, 1); + BF_ENC(l, r, k, 2); + BF_ENC(r, l, k, 3); + BF_ENC(l, r, k, 4); + BF_ENC(r, l, k, 5); + BF_ENC(l, r, k, 6); + BF_ENC(r, l, k, 7); + BF_ENC(l, r, k, 8); + BF_ENC(r, l, k, 9); + BF_ENC(l, r, k, 10); + BF_ENC(r, l, k, 11); + BF_ENC(l, r, k, 12); + BF_ENC(r, l, k, 13); + BF_ENC(l, r, k, 14); + BF_ENC(r, l, k, 15); + BF_ENC(l, r, k, 16); +# if BF_ROUNDS == 20 + BF_ENC(r, l, k, 17); + BF_ENC(l, r, k, 18); + BF_ENC(r, l, k, 19); + BF_ENC(l, r, k, 20); +# endif + r ^= k[BF_ROUNDS + 1]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +#endif +} + +#ifndef BF_DEFAULT_OPTIONS + +void BF_decrypt(BF_LONG *data, const BF_KEY *key) +{ +# ifndef BF_PTR2 + register BF_LONG l, r; + register const BF_LONG *p, *s; + + p = key->P; + s = &(key->S[0]); + l = data[0]; + r = data[1]; + + l ^= p[BF_ROUNDS + 1]; +# if BF_ROUNDS == 20 + BF_ENC(r, l, s, p[20]); + BF_ENC(l, r, s, p[19]); + BF_ENC(r, l, s, p[18]); + BF_ENC(l, r, s, p[17]); +# endif + BF_ENC(r, l, s, p[16]); + BF_ENC(l, r, s, p[15]); + BF_ENC(r, l, s, p[14]); + BF_ENC(l, r, s, p[13]); + BF_ENC(r, l, s, p[12]); + BF_ENC(l, r, s, p[11]); + BF_ENC(r, l, s, p[10]); + BF_ENC(l, r, s, p[9]); + BF_ENC(r, l, s, p[8]); + BF_ENC(l, r, s, p[7]); + BF_ENC(r, l, s, p[6]); + BF_ENC(l, r, s, p[5]); + BF_ENC(r, l, s, p[4]); + BF_ENC(l, r, s, p[3]); + BF_ENC(r, l, s, p[2]); + BF_ENC(l, r, s, p[1]); + r ^= p[0]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +# else + register BF_LONG l, r, t, *k; + + l = data[0]; + r = data[1]; + k = (BF_LONG *)key; + + l ^= k[BF_ROUNDS + 1]; +# if BF_ROUNDS == 20 + BF_ENC(r, l, k, 20); + BF_ENC(l, r, k, 19); + BF_ENC(r, l, k, 18); + BF_ENC(l, r, k, 17); +# endif + BF_ENC(r, l, k, 16); + BF_ENC(l, r, k, 15); + BF_ENC(r, l, k, 14); + BF_ENC(l, r, k, 13); + BF_ENC(r, l, k, 12); + BF_ENC(l, r, k, 11); + BF_ENC(r, l, k, 10); + BF_ENC(l, r, k, 9); + BF_ENC(r, l, k, 8); + BF_ENC(l, r, k, 7); + BF_ENC(r, l, k, 6); + BF_ENC(l, r, k, 5); + BF_ENC(r, l, k, 4); + BF_ENC(l, r, k, 3); + BF_ENC(r, l, k, 2); + BF_ENC(l, r, k, 1); + r ^= k[0]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +# endif +} + +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int encrypt) +{ + register BF_LONG tin0, tin1; + register BF_LONG tout0, tout1, xor0, xor1; + register long l = length; + BF_LONG tin[2]; + + if (encrypt) { + n2l(ivec, tout0); + n2l(ivec, tout1); + ivec -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + BF_encrypt(tin, schedule); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + BF_encrypt(tin, schedule); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + l2n(tout0, ivec); + l2n(tout1, ivec); + } else { + n2l(ivec, xor0); + n2l(ivec, xor1); + ivec -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + BF_decrypt(tin, schedule); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + BF_decrypt(tin, schedule); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, ivec); + l2n(xor1, ivec); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +#endif +/* crypto/bio/bf_buff.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "bio.h" +#include "evp.h" + +static int linebuffer_write(BIO *h, const char *buf, int num); +static int linebuffer_read(BIO *h, char *buf, int size); +static int linebuffer_puts(BIO *h, const char *str); +static int linebuffer_gets(BIO *h, char *str, int size); +static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int linebuffer_new(BIO *h); +static int linebuffer_free(BIO *data); +static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +/* A 10k maximum should be enough for most purposes */ +#define DEFAULT_LINEBUFFER_SIZE 1024*10 + +/* #define DEBUG */ + +static BIO_METHOD methods_linebuffer = { + BIO_TYPE_LINEBUFFER, + "linebuffer", + linebuffer_write, + linebuffer_read, + linebuffer_puts, + linebuffer_gets, + linebuffer_ctrl, + linebuffer_new, + linebuffer_free, + linebuffer_callback_ctrl, +}; + +BIO_METHOD *BIO_f_linebuffer(void) +{ + return (&methods_linebuffer); +} + +typedef struct bio_linebuffer_ctx_struct { + char *obuf; /* the output char array */ + int obuf_size; /* how big is the output buffer */ + int obuf_len; /* how many bytes are in it */ +} BIO_LINEBUFFER_CTX; + +static int linebuffer_new(BIO *bi) +{ + BIO_LINEBUFFER_CTX *ctx; + + ctx = (BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX)); + if (ctx == NULL) + return (0); + ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE); + if (ctx->obuf == NULL) { + OPENSSL_free(ctx); + return (0); + } + ctx->obuf_size = DEFAULT_LINEBUFFER_SIZE; + ctx->obuf_len = 0; + + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int linebuffer_free(BIO *a) +{ + BIO_LINEBUFFER_CTX *b; + + if (a == NULL) + return (0); + b = (BIO_LINEBUFFER_CTX *)a->ptr; + if (b->obuf != NULL) + OPENSSL_free(b->obuf); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int linebuffer_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out == NULL) + return (0); + if (b->next_bio == NULL) + return (0); + ret = BIO_read(b->next_bio, out, outl); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int linebuffer_write(BIO *b, const char *in, int inl) +{ + int i, num = 0, foundnl; + BIO_LINEBUFFER_CTX *ctx; + + if ((in == NULL) || (inl <= 0)) + return (0); + ctx = (BIO_LINEBUFFER_CTX *)b->ptr; + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + BIO_clear_retry_flags(b); + + do { + const char *p; + + for (p = in; p < in + inl && *p != '\n'; p++) ; + if (*p == '\n') { + p++; + foundnl = 1; + } else + foundnl = 0; + + /* + * If a NL was found and we already have text in the save buffer, + * concatenate them and write + */ + while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len) + && ctx->obuf_len > 0) { + int orig_olen = ctx->obuf_len; + + i = ctx->obuf_size - ctx->obuf_len; + if (p - in > 0) { + if (i >= p - in) { + memcpy(&(ctx->obuf[ctx->obuf_len]), in, p - in); + ctx->obuf_len += p - in; + inl -= p - in; + num += p - in; + in = p; + } else { + memcpy(&(ctx->obuf[ctx->obuf_len]), in, i); + ctx->obuf_len += i; + inl -= i; + in += i; + num += i; + } + } +#if 0 + BIO_write(b->next_bio, "<*<", 3); +#endif + i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len); + if (i <= 0) { + ctx->obuf_len = orig_olen; + BIO_copy_next_retry(b); + +#if 0 + BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } +#if 0 + BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < ctx->obuf_len) + memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i); + ctx->obuf_len -= i; + } + + /* + * Now that the save buffer is emptied, let's write the input buffer + * if a NL was found and there is anything to write. + */ + if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) { +#if 0 + BIO_write(b->next_bio, "<*<", 3); +#endif + i = BIO_write(b->next_bio, in, p - in); + if (i <= 0) { + BIO_copy_next_retry(b); +#if 0 + BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } +#if 0 + BIO_write(b->next_bio, ">*>", 3); +#endif + num += i; + in += i; + inl -= i; + } + } + while (foundnl && inl > 0); + /* + * We've written as much as we can. The rest of the input buffer, if + * any, is text that doesn't and with a NL and therefore needs to be + * saved for the next trip. + */ + if (inl > 0) { + memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl); + ctx->obuf_len += inl; + num += inl; + } + return num; +} + +static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + BIO_LINEBUFFER_CTX *ctx; + long ret = 1; + char *p; + int r; + int obs; + + ctx = (BIO_LINEBUFFER_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->obuf_len = 0; + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_INFO: + ret = (long)ctx->obuf_len; + break; + case BIO_CTRL_WPENDING: + ret = (long)ctx->obuf_len; + if (ret == 0) { + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + break; + case BIO_C_SET_BUFF_SIZE: + obs = (int)num; + p = ctx->obuf; + if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) { + p = (char *)OPENSSL_malloc((int)num); + if (p == NULL) + goto malloc_error; + } + if (ctx->obuf != p) { + if (ctx->obuf_len > obs) { + ctx->obuf_len = obs; + } + memcpy(p, ctx->obuf, ctx->obuf_len); + OPENSSL_free(ctx->obuf); + ctx->obuf = p; + ctx->obuf_size = obs; + } + break; + case BIO_C_DO_STATE_MACHINE: + if (b->next_bio == NULL) + return (0); + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_FLUSH: + if (b->next_bio == NULL) + return (0); + if (ctx->obuf_len <= 0) { + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + + for (;;) { + BIO_clear_retry_flags(b); + if (ctx->obuf_len > 0) { + r = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len); +#if 0 + fprintf(stderr, "FLUSH %3d -> %3d\n", ctx->obuf_len, r); +#endif + BIO_copy_next_retry(b); + if (r <= 0) + return ((long)r); + if (r < ctx->obuf_len) + memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r); + ctx->obuf_len -= r; + } else { + ctx->obuf_len = 0; + ret = 1; + break; + } + } + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size)) + ret = 0; + break; + default: + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); + malloc_error: + BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE); + return (0); +} + +static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int linebuffer_gets(BIO *b, char *buf, int size) +{ + if (b->next_bio == NULL) + return (0); + return (BIO_gets(b->next_bio, buf, size)); +} + +static int linebuffer_puts(BIO *b, const char *str) +{ + return (linebuffer_write(b, str, strlen(str))); +} +/* crypto/bio/bf_nbio.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +#include "rand.h" +// #include "bio.h" + +/* + * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest + */ + +static int nbiof_write(BIO *h, const char *buf, int num); +static int nbiof_read(BIO *h, char *buf, int size); +static int nbiof_puts(BIO *h, const char *str); +static int nbiof_gets(BIO *h, char *str, int size); +static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int nbiof_new(BIO *h); +static int nbiof_free(BIO *data); +static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +typedef struct nbio_test_st { + /* only set if we sent a 'should retry' error */ + int lrn; + int lwn; +} NBIO_TEST; + +static BIO_METHOD methods_nbiof = { + BIO_TYPE_NBIO_TEST, + "non-blocking IO test filter", + nbiof_write, + nbiof_read, + nbiof_puts, + nbiof_gets, + nbiof_ctrl, + nbiof_new, + nbiof_free, + nbiof_callback_ctrl, +}; + +BIO_METHOD *BIO_f_nbio_test(void) +{ + return (&methods_nbiof); +} + +static int nbiof_new(BIO *bi) +{ + NBIO_TEST *nt; + + if (!(nt = (NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST)))) + return (0); + nt->lrn = -1; + nt->lwn = -1; + bi->ptr = (char *)nt; + bi->init = 1; + bi->flags = 0; + return (1); +} + +static int nbiof_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->ptr != NULL) + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int nbiof_read(BIO *b, char *out, int outl) +{ + int ret = 0; +#if 1 + int num; + unsigned char n; +#endif + + if (out == NULL) + return (0); + if (b->next_bio == NULL) + return (0); + + BIO_clear_retry_flags(b); +#if 1 + if (RAND_bytes(&n, 1) <= 0) + return -1; + num = (n & 0x07); + + if (outl > num) + outl = num; + + if (num == 0) { + ret = -1; + BIO_set_retry_read(b); + } else +#endif + { + ret = BIO_read(b->next_bio, out, outl); + if (ret < 0) + BIO_copy_next_retry(b); + } + return (ret); +} + +static int nbiof_write(BIO *b, const char *in, int inl) +{ + NBIO_TEST *nt; + int ret = 0; + int num; + unsigned char n; + + if ((in == NULL) || (inl <= 0)) + return (0); + if (b->next_bio == NULL) + return (0); + nt = (NBIO_TEST *)b->ptr; + + BIO_clear_retry_flags(b); + +#if 1 + if (nt->lwn > 0) { + num = nt->lwn; + nt->lwn = 0; + } else { + if (RAND_bytes(&n, 1) <= 0) + return -1; + num = (n & 7); + } + + if (inl > num) + inl = num; + + if (num == 0) { + ret = -1; + BIO_set_retry_write(b); + } else +#endif + { + ret = BIO_write(b->next_bio, in, inl); + if (ret < 0) { + BIO_copy_next_retry(b); + nt->lwn = inl; + } + } + return (ret); +} + +static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_DUP: + ret = 0L; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int nbiof_gets(BIO *bp, char *buf, int size) +{ + if (bp->next_bio == NULL) + return (0); + return (BIO_gets(bp->next_bio, buf, size)); +} + +static int nbiof_puts(BIO *bp, const char *str) +{ + if (bp->next_bio == NULL) + return (0); + return (BIO_puts(bp->next_bio, str)); +} +/* crypto/bio/bf_null.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "bio.h" + +/* + * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest + */ + +static int nullf_write(BIO *h, const char *buf, int num); +static int nullf_read(BIO *h, char *buf, int size); +static int nullf_puts(BIO *h, const char *str); +static int nullf_gets(BIO *h, char *str, int size); +static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int nullf_new(BIO *h); +static int nullf_free(BIO *data); +static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +static BIO_METHOD methods_nullf = { + BIO_TYPE_NULL_FILTER, + "NULL filter", + nullf_write, + nullf_read, + nullf_puts, + nullf_gets, + nullf_ctrl, + nullf_new, + nullf_free, + nullf_callback_ctrl, +}; + +BIO_METHOD *BIO_f_null(void) +{ + return (&methods_nullf); +} + +static int nullf_new(BIO *bi) +{ + bi->init = 1; + bi->ptr = NULL; + bi->flags = 0; + return (1); +} + +static int nullf_free(BIO *a) +{ + if (a == NULL) + return (0); + /*- + a->ptr=NULL; + a->init=0; + a->flags=0; + */ + return (1); +} + +static int nullf_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out == NULL) + return (0); + if (b->next_bio == NULL) + return (0); + ret = BIO_read(b->next_bio, out, outl); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int nullf_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + + if ((in == NULL) || (inl <= 0)) + return (0); + if (b->next_bio == NULL) + return (0); + ret = BIO_write(b->next_bio, in, inl); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_DUP: + ret = 0L; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + return (ret); +} + +static long nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int nullf_gets(BIO *bp, char *buf, int size) +{ + if (bp->next_bio == NULL) + return (0); + return (BIO_gets(bp->next_bio, buf, size)); +} + +static int nullf_puts(BIO *bp, const char *str) +{ + if (bp->next_bio == NULL) + return (0); + return (BIO_puts(bp->next_bio, str)); +} +/* crypto/bf/bf_ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "blowfish.h" +// #include "bf_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num) +{ + register BF_LONG v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + BF_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + n2l(iv, v0); + n2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2n(v0, dp); + l2n(v1, dp); + while (l--) { + if (n == 0) { + BF_encrypt((BF_LONG *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2n(t, dp); + t = ti[1]; + l2n(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2n(v0, iv); + l2n(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} +/* crypto/bf/bf_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "crypto.h" +// #include "blowfish.h" +// #include "bf_locl.h" +#include "bf_pi.h" + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(BLOWFISH); + private_BF_set_key(key, len, data); +} + +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data) +#endif +{ + int i; + BF_LONG *p, ri, in[2]; + const unsigned char *d, *end; + + memcpy(key, &bf_init, sizeof(BF_KEY)); + p = key->P; + + if (len > ((BF_ROUNDS + 2) * 4)) + len = (BF_ROUNDS + 2) * 4; + + d = data; + end = &(data[len]); + for (i = 0; i < (BF_ROUNDS + 2); i++) { + ri = *(d++); + if (d >= end) + d = data; + + ri <<= 8; + ri |= *(d++); + if (d >= end) + d = data; + + ri <<= 8; + ri |= *(d++); + if (d >= end) + d = data; + + ri <<= 8; + ri |= *(d++); + if (d >= end) + d = data; + + p[i] ^= ri; + } + + in[0] = 0L; + in[1] = 0L; + for (i = 0; i < (BF_ROUNDS + 2); i += 2) { + BF_encrypt(in, key); + p[i] = in[0]; + p[i + 1] = in[1]; + } + + p = key->S; + for (i = 0; i < 4 * 256; i += 2) { + BF_encrypt(in, key); + p[i] = in[0]; + p[i + 1] = in[1]; + } +} diff --git a/Sources/COpenSSL/bf_locl.h b/Sources/COpenSSL/bf_locl.h new file mode 100644 index 00000000..9b0ec73a --- /dev/null +++ b/Sources/COpenSSL/bf_locl.h @@ -0,0 +1,221 @@ +/* crypto/bf/bf_locl.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BF_LOCL_H +# define HEADER_BF_LOCL_H +# include "opensslconf.h"/* BF_PTR, BF_PTR2 */ + +# undef c2l +# define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +# undef c2ln +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +# undef l2c +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +# undef l2cn +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +# define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +# define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +# undef n2l +# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +# undef l2n +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* + * This is actually a big endian algorithm, the most significant byte is used + * to lookup array 0 + */ + +# if defined(BF_PTR2) + +/* + * This is basically a special Intel version. Point is that Intel + * doesn't have many registers, but offers a reach choice of addressing + * modes. So we spare some registers by directly traversing BF_KEY + * structure and hiring the most decorated addressing mode. The code + * generated by EGCS is *perfectly* competitive with assembler + * implementation! + */ +# define BF_ENC(LL,R,KEY,Pi) (\ + LL^=KEY[Pi], \ + t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \ + t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \ + LL^=t \ + ) + +# elif defined(BF_PTR) + +# ifndef BF_LONG_LOG2 +# define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */ +# endif +# define BF_M (0xFF<>BF_i)&BF_M gets folded into a single instruction, namely + * rlwinm. So let'em double-check if their compiler does it. + */ + +# define BF_ENC(LL,R,S,P) ( \ + LL^=P, \ + LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \ + *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \ + *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \ + *(BF_LONG *)((unsigned char *)&(S[768])+((R<>24)&0xff)] + \ + S[0x0100+((int)(R>>16)&0xff)])^ \ + S[0x0200+((int)(R>> 8)&0xff)])+ \ + S[0x0300+((int)(R )&0xff)])&0xffffffffL \ + ) +# endif + +#endif diff --git a/Sources/COpenSSL/bf_pi.h b/Sources/COpenSSL/bf_pi.h new file mode 100644 index 00000000..46a26739 --- /dev/null +++ b/Sources/COpenSSL/bf_pi.h @@ -0,0 +1,579 @@ +/* crypto/bf/bf_pi.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +static const BF_KEY bf_init = { + { + 0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L, + 0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L, + 0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL, + 0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L, + 0x9216d5d9L, 0x8979fb1b}, { + 0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, + 0xd01adfb7L, + 0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, + 0xf12c7f99L, + 0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, + 0x858efc16L, + 0x636920d8L, 0x71574e69L, 0xa458fea3L, + 0xf4933d7eL, + 0x0d95748fL, 0x728eb658L, 0x718bcd58L, + 0x82154aeeL, + 0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, + 0x2af26013L, + 0xc5d1b023L, 0x286085f0L, 0xca417918L, + 0xb8db38efL, + 0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, + 0xb01e8a3eL, + 0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, + 0x55605c60L, + 0xe65525f3L, 0xaa55ab94L, 0x57489862L, + 0x63e81440L, + 0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, + 0x1141e8ceL, + 0xa15486afL, 0x7c72e993L, 0xb3ee1411L, + 0x636fbc2aL, + 0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, + 0x9b87931eL, + 0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, + 0x28958677L, + 0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, + 0x66282193L, + 0x61d809ccL, 0xfb21a991L, 0x487cac60L, + 0x5dec8032L, + 0xef845d5dL, 0xe98575b1L, 0xdc262302L, + 0xeb651b88L, + 0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, + 0x83f44239L, + 0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, + 0x9e1f9b5eL, + 0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, + 0xabd388f0L, + 0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, + 0xab5133a3L, + 0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, + 0x7efb2a98L, + 0xa1f1651dL, 0x39af0176L, 0x66ca593eL, + 0x82430e88L, + 0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, + 0x3b8b5ebeL, + 0xe06f75d8L, 0x85c12073L, 0x401a449fL, + 0x56c16aa6L, + 0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, + 0x429b023dL, + 0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, + 0x49f1c09bL, + 0x075372c9L, 0x80991b7bL, 0x25d479d8L, + 0xf6e8def7L, + 0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, + 0x04c006baL, + 0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, + 0x196a2463L, + 0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, + 0x3b52ec6fL, + 0x6dfc511fL, 0x9b30952cL, 0xcc814544L, + 0xaf5ebd09L, + 0xbee3d004L, 0xde334afdL, 0x660f2807L, + 0x192e4bb3L, + 0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, + 0xb9d3fbdbL, + 0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, + 0x402c7279L, + 0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, + 0xdb3222f8L, + 0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, + 0xad0552abL, + 0x323db5faL, 0xfd238760L, 0x53317b48L, + 0x3e00df82L, + 0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, + 0xdf1769dbL, + 0xd542a8f6L, 0x287effc3L, 0xac6732c6L, + 0x8c4f5573L, + 0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, + 0xb8f011a0L, + 0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, + 0x2dd1d35bL, + 0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, + 0x4bfb9790L, + 0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, + 0xcee4c6e8L, + 0xef20cadaL, 0x36774c01L, 0xd07e9efeL, + 0x2bf11fb4L, + 0x95dbda4dL, 0xae909198L, 0xeaad8e71L, + 0x6b93d5a0L, + 0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, + 0x8e7594b7L, + 0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, + 0x900df01cL, + 0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, + 0xb3a8c1adL, + 0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, + 0x8b021fa1L, + 0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, + 0xce89e299L, + 0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, + 0xd2ada8d9L, + 0x165fa266L, 0x80957705L, 0x93cc7314L, + 0x211a1477L, + 0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, + 0xfb9d35cfL, + 0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, + 0xae1e7e49L, + 0x00250e2dL, 0x2071b35eL, 0x226800bbL, + 0x57b8e0afL, + 0x2464369bL, 0xf009b91eL, 0x5563911dL, + 0x59dfa6aaL, + 0x78c14389L, 0xd95a537fL, 0x207d5ba2L, + 0x02e5b9c5L, + 0x83260376L, 0x6295cfa9L, 0x11c81968L, + 0x4e734a41L, + 0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, + 0x9a532915L, + 0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, + 0x81e67400L, + 0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, + 0x2a0dd915L, + 0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, + 0xc5855664L, + 0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, + 0x6e85076aL, + 0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, + 0xc4192623L, + 0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, + 0x8fedb266L, + 0xecaa8c71L, 0x699a17ffL, 0x5664526cL, + 0xc2b19ee1L, + 0x193602a5L, 0x75094c29L, 0xa0591340L, + 0xe4183a3eL, + 0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, + 0x99f73fd6L, + 0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, + 0xf0255dc1L, + 0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, + 0x021ecc5eL, + 0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, + 0x6b6a70a1L, + 0x687f3584L, 0x52a0e286L, 0xb79c5305L, + 0xaa500737L, + 0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, + 0x5716f2b8L, + 0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, + 0x0200b3ffL, + 0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, + 0xdc0921bdL, + 0xd19113f9L, 0x7ca92ff6L, 0x94324773L, + 0x22f54701L, + 0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, + 0x9af3dda7L, + 0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, + 0xa4751e41L, + 0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, + 0x183eb331L, + 0x4e548b38L, 0x4f6db908L, 0x6f420d03L, + 0xf60a04bfL, + 0x2cb81290L, 0x24977c79L, 0x5679b072L, + 0xbcaf89afL, + 0xde9a771fL, 0xd9930810L, 0xb38bae12L, + 0xdccf3f2eL, + 0x5512721fL, 0x2e6b7124L, 0x501adde6L, + 0x9f84cd87L, + 0x7a584718L, 0x7408da17L, 0xbc9f9abcL, + 0xe94b7d8cL, + 0xec7aec3aL, 0xdb851dfaL, 0x63094366L, + 0xc464c3d2L, + 0xef1c1847L, 0x3215d908L, 0xdd433b37L, + 0x24c2ba16L, + 0x12a14d43L, 0x2a65c451L, 0x50940002L, + 0x133ae4ddL, + 0x71dff89eL, 0x10314e55L, 0x81ac77d6L, + 0x5f11199bL, + 0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, + 0x5924a509L, + 0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, + 0x1e153c6eL, + 0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, + 0x5a3e2ab3L, + 0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, + 0x99e71d0fL, + 0x803e89d6L, 0x5266c825L, 0x2e4cc978L, + 0x9c10b36aL, + 0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, + 0x1e0a2df4L, + 0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, + 0x19c27960L, + 0x5223a708L, 0xf71312b6L, 0xebadfe6eL, + 0xeac31f66L, + 0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, + 0x018cff28L, + 0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, + 0x68ab9802L, + 0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, + 0x5b6e2f84L, + 0x1521b628L, 0x29076170L, 0xecdd4775L, + 0x619f1510L, + 0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, + 0xaa0363cfL, + 0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, + 0xcbaade14L, + 0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, + 0xb2f3846eL, + 0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, + 0x655abb50L, + 0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, + 0xc021b8f7L, + 0x9b540b19L, 0x875fa099L, 0x95f7997eL, + 0x623d7da8L, + 0xf837889aL, 0x97e32d77L, 0x11ed935fL, + 0x16681281L, + 0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, + 0x7858ba99L, + 0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, + 0x1ac24696L, + 0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, + 0x6dbc3128L, + 0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, + 0xee7c3c73L, + 0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, + 0x203e13e0L, + 0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, + 0xfacb4fd0L, + 0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, + 0x41cd2105L, + 0xd81e799eL, 0x86854dc7L, 0xe44b476aL, + 0x3d816250L, + 0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, + 0xc1c7b6a3L, + 0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, + 0x5692b285L, + 0x095bbf00L, 0xad19489dL, 0x1462b174L, + 0x23820e00L, + 0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, + 0x233f7061L, + 0x3372f092L, 0x8d937e41L, 0xd65fecf1L, + 0x6c223bdbL, + 0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, + 0xce77326eL, + 0xa6078084L, 0x19f8509eL, 0xe8efd855L, + 0x61d99735L, + 0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, + 0x800bcadcL, + 0x9e447a2eL, 0xc3453484L, 0xfdd56705L, + 0x0e1e9ec9L, + 0xdb73dbd3L, 0x105588cdL, 0x675fda79L, + 0xe3674340L, + 0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, + 0xf16dff20L, + 0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, + 0xdb83adf7L, + 0xe93d5a68L, 0x948140f7L, 0xf64c261cL, + 0x94692934L, + 0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, + 0xd4a20068L, + 0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, + 0x500061afL, + 0x1e39f62eL, 0x97244546L, 0x14214f74L, + 0xbf8b8840L, + 0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, + 0x66a02f45L, + 0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, + 0x31cb8504L, + 0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, + 0xabca0a9aL, + 0x28507825L, 0x530429f4L, 0x0a2c86daL, + 0xe9b66dfbL, + 0x68dc1462L, 0xd7486900L, 0x680ec0a4L, + 0x27a18deeL, + 0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, + 0x7af4d6b6L, + 0xaace1e7cL, 0xd3375fecL, 0xce78a399L, + 0x406b2a42L, + 0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, + 0x3b124e8bL, + 0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, + 0xeae397b2L, + 0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, + 0xca7820fbL, + 0xfb0af54eL, 0xd8feb397L, 0x454056acL, + 0xba489527L, + 0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, + 0xd096954bL, + 0x55a867bcL, 0xa1159a58L, 0xcca92963L, + 0x99e1db33L, + 0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, + 0x9029317cL, + 0xfdf8e802L, 0x04272f70L, 0x80bb155cL, + 0x05282ce3L, + 0x95c11548L, 0xe4c66d22L, 0x48c1133fL, + 0xc70f86dcL, + 0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, + 0x5d886e17L, + 0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, + 0x41113564L, + 0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, + 0x1f636c1bL, + 0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, + 0xcad18115L, + 0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, + 0xeebeb922L, + 0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, + 0x2da2f728L, + 0xd0127845L, 0x95b794fdL, 0x647d0862L, + 0xe7ccf5f0L, + 0x5449a36fL, 0x877d48faL, 0xc39dfd27L, + 0xf33e8d1eL, + 0x0a476341L, 0x992eff74L, 0x3a6f6eabL, + 0xf4f8fd37L, + 0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, + 0xdb6e6b0dL, + 0xc67b5510L, 0x6d672c37L, 0x2765d43bL, + 0xdcd0e804L, + 0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, + 0x690fed0bL, + 0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, + 0xd9155ea3L, + 0xbb132f88L, 0x515bad24L, 0x7b9479bfL, + 0x763bd6ebL, + 0x37392eb3L, 0xcc115979L, 0x8026e297L, + 0xf42e312dL, + 0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, + 0x782ef11cL, + 0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, + 0x4bfb6350L, + 0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, + 0xe2e1c3c9L, + 0x44421659L, 0x0a121386L, 0xd90cec6eL, + 0xd5abea2aL, + 0x64af674eL, 0xda86a85fL, 0xbebfe988L, + 0x64e4c3feL, + 0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, + 0x6003604dL, + 0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, + 0xd736fcccL, + 0x83426b33L, 0xf01eab71L, 0xb0804187L, + 0x3c005e5fL, + 0x77a057beL, 0xbde8ae24L, 0x55464299L, + 0xbf582e61L, + 0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, + 0x8789bdc2L, + 0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, + 0x46fcd9b9L, + 0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, + 0x915f95e2L, + 0x466e598eL, 0x20b45770L, 0x8cd55591L, + 0xc902de4cL, + 0xb90bace1L, 0xbb8205d0L, 0x11a86248L, + 0x7574a99eL, + 0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, + 0xc4324633L, + 0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, + 0x1d6efe10L, + 0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, + 0x2868f169L, + 0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, + 0x4fcd7f52L, + 0x50115e01L, 0xa70683faL, 0xa002b5c4L, + 0x0de6d027L, + 0x9af88c27L, 0x773f8641L, 0xc3604c06L, + 0x61a806b5L, + 0xf0177a28L, 0xc0f586e0L, 0x006058aaL, + 0x30dc7d62L, + 0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, + 0xc2c21634L, + 0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, + 0xce591d76L, + 0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, + 0x7c927c24L, + 0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, + 0xd39eb8fcL, + 0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, + 0x4dad0fc4L, + 0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, + 0x6c51133cL, + 0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, + 0xddc6c837L, + 0xd79a3234L, 0x92638212L, 0x670efa8eL, + 0x406000e0L, + 0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, + 0x5ac52d1bL, + 0x5cb0679eL, 0x4fa33742L, 0xd3822740L, + 0x99bc9bbeL, + 0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, + 0xc700c47bL, + 0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, + 0x6a366eb4L, + 0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, + 0x6549c2c8L, + 0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, + 0x4cd04dc6L, + 0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, + 0xbe5ee304L, + 0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, + 0x9a86ee22L, + 0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, + 0x9cf2d0a4L, + 0x83c061baL, 0x9be96a4dL, 0x8fe51550L, + 0xba645bd6L, + 0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, + 0xef5562e9L, + 0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, + 0x77fa0a59L, + 0x80e4a915L, 0x87b08601L, 0x9b09e6adL, + 0x3b3ee593L, + 0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, + 0x022b8b51L, + 0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, + 0x7c7d2d28L, + 0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, + 0x5a88f54cL, + 0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, + 0xed93fa9bL, + 0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, + 0x79132e28L, + 0x785f0191L, 0xed756055L, 0xf7960e44L, + 0xe3d35e8cL, + 0x15056dd4L, 0x88f46dbaL, 0x03a16125L, + 0x0564f0bdL, + 0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, + 0xa93a072aL, + 0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, + 0x26dcf319L, + 0x7533d928L, 0xb155fdf5L, 0x03563482L, + 0x8aba3cbbL, + 0x28517711L, 0xc20ad9f8L, 0xabcc5167L, + 0xccad925fL, + 0x4de81751L, 0x3830dc8eL, 0x379d5862L, + 0x9320f991L, + 0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, + 0x774fbe32L, + 0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, + 0x6413e680L, + 0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, + 0x09072166L, + 0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, + 0x1c20c8aeL, + 0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, + 0x6bb4e3bbL, + 0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, + 0xbcb4cdd5L, + 0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, + 0xbf3c6f47L, + 0xd29be463L, 0x542f5d9eL, 0xaec2771bL, + 0xf64e6370L, + 0x740e0d8dL, 0xe75b1357L, 0xf8721671L, + 0xaf537d5dL, + 0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, + 0x0115af84L, + 0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, + 0xce6ea048L, + 0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, + 0x277227f8L, + 0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, + 0x344525bdL, + 0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, + 0xa01fbac9L, + 0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, + 0xa1e8aac7L, + 0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, + 0xd50ada38L, + 0x0339c32aL, 0xc6913667L, 0x8df9317cL, + 0xe0b12b4fL, + 0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, + 0x27d9459cL, + 0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, + 0x9b941525L, + 0xfae59361L, 0xceb69cebL, 0xc2a86459L, + 0x12baa8d1L, + 0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, + 0xcb03a442L, + 0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, + 0x3278e964L, + 0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, + 0x8971f21eL, + 0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, + 0xc37632d8L, + 0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, + 0x0fe3f11dL, + 0xe54cda54L, 0x1edad891L, 0xce6279cfL, + 0xcd3e7e6fL, + 0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, + 0xf6fb2299L, + 0xf523f357L, 0xa6327623L, 0x93a83531L, + 0x56cccd02L, + 0xacf08162L, 0x5a75ebb5L, 0x6e163697L, + 0x88d273ccL, + 0xde966292L, 0x81b949d0L, 0x4c50901bL, + 0x71c65614L, + 0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, + 0xc3f27b9aL, + 0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, + 0x35bdd2f6L, + 0x71126905L, 0xb2040222L, 0xb6cbcf7cL, + 0xcd769c2bL, + 0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, + 0x2547adf0L, + 0xba38209cL, 0xf746ce76L, 0x77afa1c5L, + 0x20756060L, + 0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, + 0x4cf9aa7eL, + 0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, + 0xd6ebe1f9L, + 0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, + 0xc208e69fL, + 0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, + 0x3ac372e6L, + } +}; diff --git a/Sources/COpenSSL/bio.h b/Sources/COpenSSL/bio.h new file mode 100644 index 00000000..df11a58a --- /dev/null +++ b/Sources/COpenSSL/bio.h @@ -0,0 +1,883 @@ +/* crypto/bio/bio.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BIO_H +# define HEADER_BIO_H + +# include "e_os2.h" + +# ifndef OPENSSL_NO_FP_API +# include +# endif +# include + +# include "crypto.h" + +# ifndef OPENSSL_NO_SCTP +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* These are the 'types' of BIOs */ +# define BIO_TYPE_NONE 0 +# define BIO_TYPE_MEM (1|0x0400) +# define BIO_TYPE_FILE (2|0x0400) + +# define BIO_TYPE_FD (4|0x0400|0x0100) +# define BIO_TYPE_SOCKET (5|0x0400|0x0100) +# define BIO_TYPE_NULL (6|0x0400) +# define BIO_TYPE_SSL (7|0x0200) +# define BIO_TYPE_MD (8|0x0200)/* passive filter */ +# define BIO_TYPE_BUFFER (9|0x0200)/* filter */ +# define BIO_TYPE_CIPHER (10|0x0200)/* filter */ +# define BIO_TYPE_BASE64 (11|0x0200)/* filter */ +# define BIO_TYPE_CONNECT (12|0x0400|0x0100)/* socket - connect */ +# define BIO_TYPE_ACCEPT (13|0x0400|0x0100)/* socket for accept */ +# define BIO_TYPE_PROXY_CLIENT (14|0x0200)/* client proxy BIO */ +# define BIO_TYPE_PROXY_SERVER (15|0x0200)/* server proxy BIO */ +# define BIO_TYPE_NBIO_TEST (16|0x0200)/* server proxy BIO */ +# define BIO_TYPE_NULL_FILTER (17|0x0200) +# define BIO_TYPE_BER (18|0x0200)/* BER -> bin filter */ +# define BIO_TYPE_BIO (19|0x0400)/* (half a) BIO pair */ +# define BIO_TYPE_LINEBUFFER (20|0x0200)/* filter */ +# define BIO_TYPE_DGRAM (21|0x0400|0x0100) +# ifndef OPENSSL_NO_SCTP +# define BIO_TYPE_DGRAM_SCTP (24|0x0400|0x0100) +# endif +# define BIO_TYPE_ASN1 (22|0x0200)/* filter */ +# define BIO_TYPE_COMP (23|0x0200)/* filter */ + +# define BIO_TYPE_DESCRIPTOR 0x0100/* socket, fd, connect or accept */ +# define BIO_TYPE_FILTER 0x0200 +# define BIO_TYPE_SOURCE_SINK 0x0400 + +/* + * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); + */ +# define BIO_NOCLOSE 0x00 +# define BIO_CLOSE 0x01 + +/* + * These are used in the following macros and are passed to BIO_ctrl() + */ +# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */ +# define BIO_CTRL_EOF 2/* opt - are we at the eof */ +# define BIO_CTRL_INFO 3/* opt - extra tit-bits */ +# define BIO_CTRL_SET 4/* man - set the 'IO' type */ +# define BIO_CTRL_GET 5/* man - get the 'IO' type */ +# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */ +# define BIO_CTRL_POP 7/* opt - internal, used to signify change */ +# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */ +# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */ +# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */ +# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */ +# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */ +# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */ +/* callback is int cb(BIO *bio,state,ret); */ +# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */ +# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */ + +# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */ + +/* dgram BIO stuff */ +# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */ +# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected + * socket to be passed in */ +# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */ +# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */ + +# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */ +/* #endif */ + +# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */ +# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */ +# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU. + * want to use this if asking + * the kernel fails */ + +# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was + * exceed in the previous write + * operation */ + +# define BIO_CTRL_DGRAM_GET_PEER 46 +# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */ + +# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout + * to adjust socket timeouts */ +# define BIO_CTRL_DGRAM_SET_DONT_FRAG 48 + +# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49 + +# ifndef OPENSSL_NO_SCTP +/* SCTP stuff */ +# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 +# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51 +# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52 +# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53 +# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60 +# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61 +# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62 +# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63 +# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64 +# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65 +# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70 +# endif + +/* modifiers */ +# define BIO_FP_READ 0x02 +# define BIO_FP_WRITE 0x04 +# define BIO_FP_APPEND 0x08 +# define BIO_FP_TEXT 0x10 + +# define BIO_FLAGS_READ 0x01 +# define BIO_FLAGS_WRITE 0x02 +# define BIO_FLAGS_IO_SPECIAL 0x04 +# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +# define BIO_FLAGS_SHOULD_RETRY 0x08 +# ifndef BIO_FLAGS_UPLINK +/* + * "UPLINK" flag denotes file descriptors provided by application. It + * defaults to 0, as most platforms don't require UPLINK interface. + */ +# define BIO_FLAGS_UPLINK 0 +# endif + +/* Used in BIO_gethostbyname() */ +# define BIO_GHBN_CTRL_HITS 1 +# define BIO_GHBN_CTRL_MISSES 2 +# define BIO_GHBN_CTRL_CACHE_SIZE 3 +# define BIO_GHBN_CTRL_GET_ENTRY 4 +# define BIO_GHBN_CTRL_FLUSH 5 + +/* Mostly used in the SSL BIO */ +/*- + * Not used anymore + * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10 + * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20 + * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40 + */ + +# define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* + * This is used with memory BIOs: it means we shouldn't free up or change the + * data in any way. + */ +# define BIO_FLAGS_MEM_RDONLY 0x200 + +typedef struct bio_st BIO; + +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +# define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +# define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* + * The next three are used in conjunction with the BIO_should_io_special() + * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int + * *reason); will walk the BIO stack and return the 'reason' for the special + * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return + * the code. + */ +/* + * Returned from the SSL bio when the certificate retrieval code had an error + */ +# define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +# define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +# define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 + +/* + * The callback is called before and after the underling operation, The + * BIO_CB_RETURN flag indicates if it is after the call + */ +# define BIO_CB_RETURN 0x80 +# define BIO_CB_return(a) ((a)|BIO_CB_RETURN) +# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +# define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *, + int, long, long); +void BIO_set_callback(BIO *b, + long (*callback) (struct bio_st *, int, const char *, + int, long, long)); +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +const char *BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef void bio_info_cb (struct bio_st *, int, const char *, int, long, + long); + +typedef struct bio_method_st { + int type; + const char *name; + int (*bwrite) (BIO *, const char *, int); + int (*bread) (BIO *, char *, int); + int (*bputs) (BIO *, const char *); + int (*bgets) (BIO *, char *, int); + long (*ctrl) (BIO *, int, long, void *); + int (*create) (BIO *); + int (*destroy) (BIO *); + long (*callback_ctrl) (BIO *, int, bio_info_cb *); +} BIO_METHOD; + +struct bio_st { + BIO_METHOD *method; + /* bio, mode, argp, argi, argl, ret */ + long (*callback) (struct bio_st *, int, const char *, int, long, long); + char *cb_arg; /* first argument for the callback */ + int init; + int shutdown; + int flags; /* extra storage */ + int retry_reason; + int num; + void *ptr; + struct bio_st *next_bio; /* used by filter BIOs */ + struct bio_st *prev_bio; /* used by filter BIOs */ + int references; + unsigned long num_read; + unsigned long num_write; + CRYPTO_EX_DATA ex_data; +}; + +DECLARE_STACK_OF(BIO) + +typedef struct bio_f_buffer_ctx_struct { + /*- + * Buffers are setup like this: + * + * <---------------------- size -----------------------> + * +---------------------------------------------------+ + * | consumed | remaining | free space | + * +---------------------------------------------------+ + * <-- off --><------- len -------> + */ + /*- BIO *bio; *//* + * this is now in the BIO struct + */ + int ibuf_size; /* how big is the input buffer */ + int obuf_size; /* how big is the output buffer */ + char *ibuf; /* the char array */ + int ibuf_len; /* how many bytes are in it */ + int ibuf_off; /* write/read offset */ + char *obuf; /* the char array */ + int obuf_len; /* how many bytes are in it */ + int obuf_off; /* write/read offset */ +} BIO_F_BUFFER_CTX; + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +# ifndef OPENSSL_NO_SCTP +/* SCTP parameter structs */ +struct bio_dgram_sctp_sndinfo { + uint16_t snd_sid; + uint16_t snd_flags; + uint32_t snd_ppid; + uint32_t snd_context; +}; + +struct bio_dgram_sctp_rcvinfo { + uint16_t rcv_sid; + uint16_t rcv_ssn; + uint16_t rcv_flags; + uint32_t rcv_ppid; + uint32_t rcv_tsn; + uint32_t rcv_cumtsn; + uint32_t rcv_context; +}; + +struct bio_dgram_sctp_prinfo { + uint16_t pr_policy; + uint32_t pr_value; +}; +# endif + +/* connect BIO stuff */ +# define BIO_CONN_S_BEFORE 1 +# define BIO_CONN_S_GET_IP 2 +# define BIO_CONN_S_GET_PORT 3 +# define BIO_CONN_S_CREATE_SOCKET 4 +# define BIO_CONN_S_CONNECT 5 +# define BIO_CONN_S_OK 6 +# define BIO_CONN_S_BLOCKED_CONNECT 7 +# define BIO_CONN_S_NBIO 8 +/* + * #define BIO_CONN_get_param_hostname BIO_ctrl + */ + +# define BIO_C_SET_CONNECT 100 +# define BIO_C_DO_STATE_MACHINE 101 +# define BIO_C_SET_NBIO 102 +# define BIO_C_SET_PROXY_PARAM 103 +# define BIO_C_SET_FD 104 +# define BIO_C_GET_FD 105 +# define BIO_C_SET_FILE_PTR 106 +# define BIO_C_GET_FILE_PTR 107 +# define BIO_C_SET_FILENAME 108 +# define BIO_C_SET_SSL 109 +# define BIO_C_GET_SSL 110 +# define BIO_C_SET_MD 111 +# define BIO_C_GET_MD 112 +# define BIO_C_GET_CIPHER_STATUS 113 +# define BIO_C_SET_BUF_MEM 114 +# define BIO_C_GET_BUF_MEM_PTR 115 +# define BIO_C_GET_BUFF_NUM_LINES 116 +# define BIO_C_SET_BUFF_SIZE 117 +# define BIO_C_SET_ACCEPT 118 +# define BIO_C_SSL_MODE 119 +# define BIO_C_GET_MD_CTX 120 +# define BIO_C_GET_PROXY_PARAM 121 +# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */ +# define BIO_C_GET_CONNECT 123 +# define BIO_C_GET_ACCEPT 124 +# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +# define BIO_C_FILE_SEEK 128 +# define BIO_C_GET_CIPHER_CTX 129 +# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input + * value */ +# define BIO_C_SET_BIND_MODE 131 +# define BIO_C_GET_BIND_MODE 132 +# define BIO_C_FILE_TELL 133 +# define BIO_C_GET_SOCKS 134 +# define BIO_C_SET_SOCKS 135 + +# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +# define BIO_C_GET_WRITE_BUF_SIZE 137 +# define BIO_C_MAKE_BIO_PAIR 138 +# define BIO_C_DESTROY_BIO_PAIR 139 +# define BIO_C_GET_WRITE_GUARANTEE 140 +# define BIO_C_GET_READ_REQUEST 141 +# define BIO_C_SHUTDOWN_WR 142 +# define BIO_C_NREAD0 143 +# define BIO_C_NREAD 144 +# define BIO_C_NWRITE0 145 +# define BIO_C_NWRITE 146 +# define BIO_C_RESET_READ_REQUEST 147 +# define BIO_C_SET_MD_CTX 148 + +# define BIO_C_SET_PREFIX 149 +# define BIO_C_GET_PREFIX 150 +# define BIO_C_SET_SUFFIX 151 +# define BIO_C_GET_SUFFIX 152 + +# define BIO_C_SET_EX_ARG 153 +# define BIO_C_GET_EX_ARG 154 + +# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +# define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +/* BIO_s_connect() and BIO_s_socks4a_connect() */ +# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) +# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port) +# define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip) +# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) +# define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) +# define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) +# define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) +# define BIO_get_conn_int_port(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) + +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +/* BIO_s_accept() */ +# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) +# define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL) +# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) + +# define BIO_BIND_NORMAL 0 +# define BIO_BIND_REUSEADDR_IF_UNUSED 1 +# define BIO_BIND_REUSEADDR 2 +# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +# define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +/* BIO_s_accept() and BIO_s_connect() */ +# define BIO_do_connect(b) BIO_do_handshake(b) +# define BIO_do_accept(b) BIO_do_handshake(b) +# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_proxy_client() */ +# define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url)) +# define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p)) +/* BIO_set_nbio(b,n) */ +# define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s)) +/* BIO *BIO_get_filter_bio(BIO *bio); */ +# define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)())) +# define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk) +# define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool) + +# define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp) +# define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p)) +# define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url)) +# define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL) + +/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */ +# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) + +/* BIO_s_file() */ +# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp) +# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp) + +/* BIO_s_fd() and BIO_s_file() */ +# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* + * name is cast to lose const, but might be better to route through a + * function so we can do it safely + */ +# ifdef CONST_STRICT +/* + * If you are wondering why this isn't defined, its because CONST_STRICT is + * purely a compile-time kludge to allow const to be checked. + */ +int BIO_read_filename(BIO *b, const char *name); +# else +# define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)name) +# endif +# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +# define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +# define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* + * WARNING WARNING, this ups the reference count on the read bio of the SSL + * structure. This is because the ssl read BIO is now pointed to by the + * next_bio field in the bio. So when you free the BIO, make sure you are + * doing a BIO_free_all() to catch the underlying BIO. + */ +# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl) +# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) +# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +# define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL) +# define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL) +# define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL) + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */ + +# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) +# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm) +# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp) +# define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) + +/* For BIO_s_bio() */ +# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +# define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer) +# define BIO_ctrl_set_connected(b, state, peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer) +# define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +# define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +# define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) +# define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) +# define BIO_dgram_get_mtu_overhead(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) + +/* These two aren't currently implemented */ +/* int BIO_get_ex_num(BIO *bio); */ +/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */ +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(BIO *bio, int idx); +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +unsigned long BIO_number_read(BIO *bio); +unsigned long BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + +# ifndef OPENSSL_NO_FP_API +BIO_METHOD *BIO_s_file(void); +BIO *BIO_new_file(const char *filename, const char *mode); +BIO *BIO_new_fp(FILE *stream, int close_flag); +# define BIO_s_file_internal BIO_s_file +# endif +BIO *BIO_new(BIO_METHOD *type); +int BIO_set(BIO *a, BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_vfree(BIO *a); +int BIO_read(BIO *b, void *data, int len); +int BIO_gets(BIO *bp, char *buf, int size); +int BIO_write(BIO *b, const void *data, int len); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, + void (*fp) (struct bio_st *, int, const char *, int, + long, long)); +char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO *BIO_push(BIO *b, BIO *append); +BIO *BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO *BIO_find_type(BIO *b, int bio_type); +BIO *BIO_next(BIO *b); +BIO *BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +BIO *BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +BIO_METHOD *BIO_s_mem(void); +BIO *BIO_new_mem_buf(const void *buf, int len); +BIO_METHOD *BIO_s_socket(void); +BIO_METHOD *BIO_s_connect(void); +BIO_METHOD *BIO_s_accept(void); +BIO_METHOD *BIO_s_fd(void); +# ifndef OPENSSL_SYS_OS2 +BIO_METHOD *BIO_s_log(void); +# endif +BIO_METHOD *BIO_s_bio(void); +BIO_METHOD *BIO_s_null(void); +BIO_METHOD *BIO_f_null(void); +BIO_METHOD *BIO_f_buffer(void); +# ifdef OPENSSL_SYS_VMS +BIO_METHOD *BIO_f_linebuffer(void); +# endif +BIO_METHOD *BIO_f_nbio_test(void); +# ifndef OPENSSL_NO_DGRAM +BIO_METHOD *BIO_s_datagram(void); +# ifndef OPENSSL_NO_SCTP +BIO_METHOD *BIO_s_datagram_sctp(void); +# endif +# endif + +/* BIO_METHOD *BIO_f_ber(void); */ + +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +int BIO_dgram_non_fatal_error(int error); + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len); +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b, const char *bytes, int len); +int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); +# ifndef OPENSSL_NO_FP_API +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +# endif +int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, + int datalen); + +struct hostent *BIO_gethostbyname(const char *name); +/*- + * We might want a thread-safe interface too: + * struct hostent *BIO_gethostbyname_r(const char *name, + * struct hostent *result, void *buffer, size_t buflen); + * or something similar (caller allocates a struct hostent, + * pointed to by "result", and additional buffer space for the various + * substructures; if the buffer does not suffice, NULL is returned + * and an appropriate error code is set). + */ +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_get_port(const char *str, unsigned short *port_ptr); +int BIO_get_host_ip(const char *str, unsigned char *ip); +int BIO_get_accept_socket(char *host_port, int mode); +int BIO_accept(int sock, char **ip_port); +int BIO_sock_init(void); +void BIO_sock_cleanup(void); +int BIO_set_tcp_ndelay(int sock, int turn_on); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_dgram(int fd, int close_flag); +# ifndef OPENSSL_NO_SCTP +BIO *BIO_new_dgram_sctp(int fd, int close_flag); +int BIO_dgram_is_sctp(BIO *bio); +int BIO_dgram_sctp_notification_cb(BIO *b, + void (*handle_notifications) (BIO *bio, + void + *context, + void *buf), + void *context); +int BIO_dgram_sctp_wait_for_dry(BIO *b); +int BIO_dgram_sctp_msg_waiting(BIO *b); +# endif +BIO *BIO_new_fd(int fd, int close_flag); +BIO *BIO_new_connect(const char *host_port); +BIO *BIO_new_accept(const char *host_port); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* + * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default + * value. + */ + +void BIO_copy_next_retry(BIO *b); + +/* + * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); + */ + +# ifdef __GNUC__ +# define __bio_h__attr__ __attribute__ +# else +# define __bio_h__attr__(x) +# endif +int BIO_printf(BIO *bio, const char *format, ...) +__bio_h__attr__((__format__(__printf__, 2, 3))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) +__bio_h__attr__((__format__(__printf__, 2, 0))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +__bio_h__attr__((__format__(__printf__, 3, 4))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +__bio_h__attr__((__format__(__printf__, 3, 0))); +# undef __bio_h__attr__ + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BIO_strings(void); + +/* Error codes for the BIO functions. */ + +/* Function codes. */ +# define BIO_F_ACPT_STATE 100 +# define BIO_F_BIO_ACCEPT 101 +# define BIO_F_BIO_BER_GET_HEADER 102 +# define BIO_F_BIO_CALLBACK_CTRL 131 +# define BIO_F_BIO_CTRL 103 +# define BIO_F_BIO_GETHOSTBYNAME 120 +# define BIO_F_BIO_GETS 104 +# define BIO_F_BIO_GET_ACCEPT_SOCKET 105 +# define BIO_F_BIO_GET_HOST_IP 106 +# define BIO_F_BIO_GET_PORT 107 +# define BIO_F_BIO_MAKE_PAIR 121 +# define BIO_F_BIO_NEW 108 +# define BIO_F_BIO_NEW_FILE 109 +# define BIO_F_BIO_NEW_MEM_BUF 126 +# define BIO_F_BIO_NREAD 123 +# define BIO_F_BIO_NREAD0 124 +# define BIO_F_BIO_NWRITE 125 +# define BIO_F_BIO_NWRITE0 122 +# define BIO_F_BIO_PUTS 110 +# define BIO_F_BIO_READ 111 +# define BIO_F_BIO_SOCK_INIT 112 +# define BIO_F_BIO_WRITE 113 +# define BIO_F_BUFFER_CTRL 114 +# define BIO_F_CONN_CTRL 127 +# define BIO_F_CONN_STATE 115 +# define BIO_F_DGRAM_SCTP_READ 132 +# define BIO_F_DGRAM_SCTP_WRITE 133 +# define BIO_F_FILE_CTRL 116 +# define BIO_F_FILE_READ 130 +# define BIO_F_LINEBUFFER_CTRL 129 +# define BIO_F_MEM_READ 128 +# define BIO_F_MEM_WRITE 117 +# define BIO_F_SSL_NEW 118 +# define BIO_F_WSASTARTUP 119 + +/* Reason codes. */ +# define BIO_R_ACCEPT_ERROR 100 +# define BIO_R_BAD_FOPEN_MODE 101 +# define BIO_R_BAD_HOSTNAME_LOOKUP 102 +# define BIO_R_BROKEN_PIPE 124 +# define BIO_R_CONNECT_ERROR 103 +# define BIO_R_EOF_ON_MEMORY_BIO 127 +# define BIO_R_ERROR_SETTING_NBIO 104 +# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105 +# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106 +# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +# define BIO_R_INVALID_ARGUMENT 125 +# define BIO_R_INVALID_IP_ADDRESS 108 +# define BIO_R_IN_USE 123 +# define BIO_R_KEEPALIVE 109 +# define BIO_R_NBIO_CONNECT_ERROR 110 +# define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 +# define BIO_R_NO_HOSTNAME_SPECIFIED 112 +# define BIO_R_NO_PORT_DEFINED 113 +# define BIO_R_NO_PORT_SPECIFIED 114 +# define BIO_R_NO_SUCH_FILE 128 +# define BIO_R_NULL_PARAMETER 115 +# define BIO_R_TAG_MISMATCH 116 +# define BIO_R_UNABLE_TO_BIND_SOCKET 117 +# define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +# define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +# define BIO_R_UNINITIALIZED 120 +# define BIO_R_UNSUPPORTED_METHOD 121 +# define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +# define BIO_R_WSASTARTUP 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/bio_.c b/Sources/COpenSSL/bio_.c new file mode 100644 index 00000000..fe3bc19e --- /dev/null +++ b/Sources/COpenSSL/bio_.c @@ -0,0 +1,4209 @@ +/* bio_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Experimental ASN1 BIO. When written through the data is converted to an + * ASN1 string type: default is OCTET STRING. Additional functions can be + * provided to add prefix and suffix data. + */ + +#include +#include "bio.h" +#include "asn1.h" + +/* Must be large enough for biggest tag+length */ +#define DEFAULT_ASN1_BUF_SIZE 20 + +typedef enum { + ASN1_STATE_START, + ASN1_STATE_PRE_COPY, + ASN1_STATE_HEADER, + ASN1_STATE_HEADER_COPY, + ASN1_STATE_DATA_COPY, + ASN1_STATE_POST_COPY, + ASN1_STATE_DONE +} asn1_bio_state_t; + +typedef struct BIO_ASN1_EX_FUNCS_st { + asn1_ps_func *ex_func; + asn1_ps_func *ex_free_func; +} BIO_ASN1_EX_FUNCS; + +typedef struct BIO_ASN1_BUF_CTX_t { + /* Internal state */ + asn1_bio_state_t state; + /* Internal buffer */ + unsigned char *buf; + /* Size of buffer */ + int bufsize; + /* Current position in buffer */ + int bufpos; + /* Current buffer length */ + int buflen; + /* Amount of data to copy */ + int copylen; + /* Class and tag to use */ + int asn1_class, asn1_tag; + asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free; + /* Extra buffer for prefix and suffix data */ + unsigned char *ex_buf; + int ex_len; + int ex_pos; + void *ex_arg; +} BIO_ASN1_BUF_CTX; + +static int asn1_bio_write(BIO *h, const char *buf, int num); +static int asn1_bio_read(BIO *h, char *buf, int size); +static int asn1_bio_puts(BIO *h, const char *str); +static int asn1_bio_gets(BIO *h, char *str, int size); +static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int asn1_bio_new(BIO *h); +static int asn1_bio_free(BIO *data); +static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size); +static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *cleanup, asn1_bio_state_t next); +static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *setup, + asn1_bio_state_t ex_state, + asn1_bio_state_t other_state); + +static BIO_METHOD methods_asn1 = { + BIO_TYPE_ASN1, + "asn1", + asn1_bio_write, + asn1_bio_read, + asn1_bio_puts, + asn1_bio_gets, + asn1_bio_ctrl, + asn1_bio_new, + asn1_bio_free, + asn1_bio_callback_ctrl, +}; + +BIO_METHOD *BIO_f_asn1(void) +{ + return (&methods_asn1); +} + +static int asn1_bio_new(BIO *b) +{ + BIO_ASN1_BUF_CTX *ctx; + ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX)); + if (!ctx) + return 0; + if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) { + OPENSSL_free(ctx); + return 0; + } + b->init = 1; + b->ptr = (char *)ctx; + b->flags = 0; + return 1; +} + +static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) +{ + ctx->buf = OPENSSL_malloc(size); + if (!ctx->buf) + return 0; + ctx->bufsize = size; + ctx->bufpos = 0; + ctx->buflen = 0; + ctx->copylen = 0; + ctx->asn1_class = V_ASN1_UNIVERSAL; + ctx->asn1_tag = V_ASN1_OCTET_STRING; + ctx->ex_buf = NULL; + ctx->ex_len = 0; + ctx->ex_pos = 0; + ctx->state = ASN1_STATE_START; + ctx->prefix = ctx->prefix_free = ctx->suffix = ctx->suffix_free = NULL; + ctx->ex_arg = NULL; + return 1; +} + +static int asn1_bio_free(BIO *b) +{ + BIO_ASN1_BUF_CTX *ctx; + ctx = (BIO_ASN1_BUF_CTX *)b->ptr; + if (ctx == NULL) + return 0; + if (ctx->buf) + OPENSSL_free(ctx->buf); + OPENSSL_free(ctx); + b->init = 0; + b->ptr = NULL; + b->flags = 0; + return 1; +} + +static int asn1_bio_write(BIO *b, const char *in, int inl) +{ + BIO_ASN1_BUF_CTX *ctx; + int wrmax, wrlen, ret; + unsigned char *p; + if (!in || (inl < 0) || (b->next_bio == NULL)) + return 0; + ctx = (BIO_ASN1_BUF_CTX *)b->ptr; + if (ctx == NULL) + return 0; + + wrlen = 0; + ret = -1; + + for (;;) { + switch (ctx->state) { + + /* Setup prefix data, call it */ + case ASN1_STATE_START: + if (!asn1_bio_setup_ex(b, ctx, ctx->prefix, + ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER)) + return 0; + break; + + /* Copy any pre data first */ + case ASN1_STATE_PRE_COPY: + + ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free, + ASN1_STATE_HEADER); + + if (ret <= 0) + goto done; + + break; + + case ASN1_STATE_HEADER: + ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl; + OPENSSL_assert(ctx->buflen <= ctx->bufsize); + p = ctx->buf; + ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class); + ctx->copylen = inl; + ctx->state = ASN1_STATE_HEADER_COPY; + + break; + + case ASN1_STATE_HEADER_COPY: + ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen); + if (ret <= 0) + goto done; + + ctx->buflen -= ret; + if (ctx->buflen) + ctx->bufpos += ret; + else { + ctx->bufpos = 0; + ctx->state = ASN1_STATE_DATA_COPY; + } + + break; + + case ASN1_STATE_DATA_COPY: + + if (inl > ctx->copylen) + wrmax = ctx->copylen; + else + wrmax = inl; + ret = BIO_write(b->next_bio, in, wrmax); + if (ret <= 0) + break; + wrlen += ret; + ctx->copylen -= ret; + in += ret; + inl -= ret; + + if (ctx->copylen == 0) + ctx->state = ASN1_STATE_HEADER; + + if (inl == 0) + goto done; + + break; + + default: + BIO_clear_retry_flags(b); + return 0; + + } + + } + + done: + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + + return (wrlen > 0) ? wrlen : ret; + +} + +static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *cleanup, asn1_bio_state_t next) +{ + int ret; + if (ctx->ex_len <= 0) + return 1; + for (;;) { + ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len); + if (ret <= 0) + break; + ctx->ex_len -= ret; + if (ctx->ex_len > 0) + ctx->ex_pos += ret; + else { + if (cleanup) + cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); + ctx->state = next; + ctx->ex_pos = 0; + break; + } + } + return ret; +} + +static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *setup, + asn1_bio_state_t ex_state, + asn1_bio_state_t other_state) +{ + if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) { + BIO_clear_retry_flags(b); + return 0; + } + if (ctx->ex_len > 0) + ctx->state = ex_state; + else + ctx->state = other_state; + return 1; +} + +static int asn1_bio_read(BIO *b, char *in, int inl) +{ + if (!b->next_bio) + return 0; + return BIO_read(b->next_bio, in, inl); +} + +static int asn1_bio_puts(BIO *b, const char *str) +{ + return asn1_bio_write(b, str, strlen(str)); +} + +static int asn1_bio_gets(BIO *b, char *str, int size) +{ + if (!b->next_bio) + return 0; + return BIO_gets(b->next_bio, str, size); +} + +static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + if (b->next_bio == NULL) + return (0); + return BIO_callback_ctrl(b->next_bio, cmd, fp); +} + +static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2) +{ + BIO_ASN1_BUF_CTX *ctx; + BIO_ASN1_EX_FUNCS *ex_func; + long ret = 1; + ctx = (BIO_ASN1_BUF_CTX *)b->ptr; + if (ctx == NULL) + return 0; + switch (cmd) { + + case BIO_C_SET_PREFIX: + ex_func = arg2; + ctx->prefix = ex_func->ex_func; + ctx->prefix_free = ex_func->ex_free_func; + break; + + case BIO_C_GET_PREFIX: + ex_func = arg2; + ex_func->ex_func = ctx->prefix; + ex_func->ex_free_func = ctx->prefix_free; + break; + + case BIO_C_SET_SUFFIX: + ex_func = arg2; + ctx->suffix = ex_func->ex_func; + ctx->suffix_free = ex_func->ex_free_func; + break; + + case BIO_C_GET_SUFFIX: + ex_func = arg2; + ex_func->ex_func = ctx->suffix; + ex_func->ex_free_func = ctx->suffix_free; + break; + + case BIO_C_SET_EX_ARG: + ctx->ex_arg = arg2; + break; + + case BIO_C_GET_EX_ARG: + *(void **)arg2 = ctx->ex_arg; + break; + + case BIO_CTRL_FLUSH: + if (!b->next_bio) + return 0; + + /* Call post function if possible */ + if (ctx->state == ASN1_STATE_HEADER) { + if (!asn1_bio_setup_ex(b, ctx, ctx->suffix, + ASN1_STATE_POST_COPY, ASN1_STATE_DONE)) + return 0; + } + + if (ctx->state == ASN1_STATE_POST_COPY) { + ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free, + ASN1_STATE_DONE); + if (ret <= 0) + return ret; + } + + if (ctx->state == ASN1_STATE_DONE) + return BIO_ctrl(b->next_bio, cmd, arg1, arg2); + else { + BIO_clear_retry_flags(b); + return 0; + } + break; + + default: + if (!b->next_bio) + return 0; + return BIO_ctrl(b->next_bio, cmd, arg1, arg2); + + } + + return ret; +} + +static int asn1_bio_set_ex(BIO *b, int cmd, + asn1_ps_func *ex_func, asn1_ps_func *ex_free_func) +{ + BIO_ASN1_EX_FUNCS extmp; + extmp.ex_func = ex_func; + extmp.ex_free_func = ex_free_func; + return BIO_ctrl(b, cmd, 0, &extmp); +} + +static int asn1_bio_get_ex(BIO *b, int cmd, + asn1_ps_func **ex_func, + asn1_ps_func **ex_free_func) +{ + BIO_ASN1_EX_FUNCS extmp; + int ret; + ret = BIO_ctrl(b, cmd, 0, &extmp); + if (ret > 0) { + *ex_func = extmp.ex_func; + *ex_free_func = extmp.ex_free_func; + } + return ret; +} + +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free) +{ + return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free); +} + +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free) +{ + return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free); +} + +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free) +{ + return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free); +} + +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free) +{ + return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free); +} +/* crypto/evp/bio_b64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include "buffer.h" +#include "evp.h" + +static int b64_write(BIO *h, const char *buf, int num); +static int b64_read(BIO *h, char *buf, int size); +static int b64_puts(BIO *h, const char *str); +/* + * static int b64_gets(BIO *h, char *str, int size); + */ +static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int b64_new(BIO *h); +static int b64_free(BIO *data); +static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +#define B64_BLOCK_SIZE 1024 +#define B64_BLOCK_SIZE2 768 +#define B64_NONE 0 +#define B64_ENCODE 1 +#define B64_DECODE 2 + +typedef struct b64_struct { + /* + * BIO *bio; moved to the BIO structure + */ + int buf_len; + int buf_off; + int tmp_len; /* used to find the start when decoding */ + int tmp_nl; /* If true, scan until '\n' */ + int encode; + int start; /* have we started decoding yet? */ + int cont; /* <= 0 when finished */ + EVP_ENCODE_CTX base64; + char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10]; + char tmp[B64_BLOCK_SIZE]; +} BIO_B64_CTX; + +static BIO_METHOD methods_b64 = { + BIO_TYPE_BASE64, "base64 encoding", + b64_write, + b64_read, + b64_puts, + NULL, /* b64_gets, */ + b64_ctrl, + b64_new, + b64_free, + b64_callback_ctrl, +}; + +BIO_METHOD *BIO_f_base64(void) +{ + return (&methods_b64); +} + +static int b64_new(BIO *bi) +{ + BIO_B64_CTX *ctx; + + ctx = (BIO_B64_CTX *)OPENSSL_malloc(sizeof(BIO_B64_CTX)); + if (ctx == NULL) + return (0); + + ctx->buf_len = 0; + ctx->tmp_len = 0; + ctx->tmp_nl = 0; + ctx->buf_off = 0; + ctx->cont = 1; + ctx->start = 1; + ctx->encode = 0; + + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + bi->num = 0; + return (1); +} + +static int b64_free(BIO *a) +{ + if (a == NULL) + return (0); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int b64_read(BIO *b, char *out, int outl) +{ + int ret = 0, i, ii, j, k, x, n, num, ret_code = 0; + BIO_B64_CTX *ctx; + unsigned char *p, *q; + + if (out == NULL) + return (0); + ctx = (BIO_B64_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + BIO_clear_retry_flags(b); + + if (ctx->encode != B64_DECODE) { + ctx->encode = B64_DECODE; + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->tmp_len = 0; + EVP_DecodeInit(&(ctx->base64)); + } + + /* First check if there are bytes decoded/encoded */ + if (ctx->buf_len > 0) { + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + i = ctx->buf_len - ctx->buf_off; + if (i > outl) + i = outl; + OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf)); + memcpy(out, &(ctx->buf[ctx->buf_off]), i); + ret = i; + out += i; + outl -= i; + ctx->buf_off += i; + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + } + + /* + * At this point, we have room of outl bytes and an empty buffer, so we + * should read in some more. + */ + + ret_code = 0; + while (outl > 0) { + if (ctx->cont <= 0) + break; + + i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]), + B64_BLOCK_SIZE - ctx->tmp_len); + + if (i <= 0) { + ret_code = i; + + /* Should we continue next time we are called? */ + if (!BIO_should_retry(b->next_bio)) { + ctx->cont = i; + /* If buffer empty break */ + if (ctx->tmp_len == 0) + break; + /* Fall through and process what we have */ + else + i = 0; + } + /* else we retry and add more data to buffer */ + else + break; + } + i += ctx->tmp_len; + ctx->tmp_len = i; + + /* + * We need to scan, a line at a time until we have a valid line if we + * are starting. + */ + if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) { + /* ctx->start=1; */ + ctx->tmp_len = 0; + } else if (ctx->start) { + q = p = (unsigned char *)ctx->tmp; + num = 0; + for (j = 0; j < i; j++) { + if (*(q++) != '\n') + continue; + + /* + * due to a previous very long line, we need to keep on + * scanning for a '\n' before we even start looking for + * base64 encoded stuff. + */ + if (ctx->tmp_nl) { + p = q; + ctx->tmp_nl = 0; + continue; + } + + k = EVP_DecodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, + &num, p, q - p); + if ((k <= 0) && (num == 0) && (ctx->start)) + EVP_DecodeInit(&ctx->base64); + else { + if (p != (unsigned char *) + &(ctx->tmp[0])) { + i -= (p - (unsigned char *) + &(ctx->tmp[0])); + for (x = 0; x < i; x++) + ctx->tmp[x] = p[x]; + } + EVP_DecodeInit(&ctx->base64); + ctx->start = 0; + break; + } + p = q; + } + + /* we fell off the end without starting */ + if ((j == i) && (num == 0)) { + /* + * Is this is one long chunk?, if so, keep on reading until a + * new line. + */ + if (p == (unsigned char *)&(ctx->tmp[0])) { + /* Check buffer full */ + if (i == B64_BLOCK_SIZE) { + ctx->tmp_nl = 1; + ctx->tmp_len = 0; + } + } else if (p != q) { /* finished on a '\n' */ + n = q - p; + for (ii = 0; ii < n; ii++) + ctx->tmp[ii] = p[ii]; + ctx->tmp_len = n; + } + /* else finished on a '\n' */ + continue; + } else { + ctx->tmp_len = 0; + } + } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) { + /* + * If buffer isn't full and we can retry then restart to read in + * more data. + */ + continue; + } + + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + int z, jj; + +#if 0 + jj = (i >> 2) << 2; +#else + jj = i & ~3; /* process per 4 */ +#endif + z = EVP_DecodeBlock((unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, jj); + if (jj > 2) { + if (ctx->tmp[jj - 1] == '=') { + z--; + if (ctx->tmp[jj - 2] == '=') + z--; + } + } + /* + * z is now number of output bytes and jj is the number consumed + */ + if (jj != i) { + memmove(ctx->tmp, &ctx->tmp[jj], i - jj); + ctx->tmp_len = i - jj; + } + ctx->buf_len = 0; + if (z > 0) { + ctx->buf_len = z; + } + i = z; + } else { + i = EVP_DecodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)ctx->tmp, i); + ctx->tmp_len = 0; + } + /* + * If eof or an error was signalled, then the condition + * 'ctx->cont <= 0' will prevent b64_read() from reading + * more data on subsequent calls. This assignment was + * deleted accidentally in commit 5562cfaca4f3. + */ + ctx->cont = i; + + ctx->buf_off = 0; + if (i < 0) { + ret_code = 0; + ctx->buf_len = 0; + break; + } + + if (ctx->buf_len <= outl) + i = ctx->buf_len; + else + i = outl; + + memcpy(out, ctx->buf, i); + ret += i; + ctx->buf_off = i; + if (ctx->buf_off == ctx->buf_len) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + outl -= i; + out += i; + } + /* BIO_clear_retry_flags(b); */ + BIO_copy_next_retry(b); + return ((ret == 0) ? ret_code : ret); +} + +static int b64_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + int n; + int i; + BIO_B64_CTX *ctx; + + ctx = (BIO_B64_CTX *)b->ptr; + BIO_clear_retry_flags(b); + + if (ctx->encode != B64_ENCODE) { + ctx->encode = B64_ENCODE; + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->tmp_len = 0; + EVP_EncodeInit(&(ctx->base64)); + } + + OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + n = ctx->buf_len - ctx->buf_off; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (i); + } + OPENSSL_assert(i <= n); + ctx->buf_off += i; + OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + n -= i; + } + /* at this point all pending data has been written */ + ctx->buf_off = 0; + ctx->buf_len = 0; + + if ((in == NULL) || (inl <= 0)) + return (0); + + while (inl > 0) { + n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl; + + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + if (ctx->tmp_len > 0) { + OPENSSL_assert(ctx->tmp_len <= 3); + n = 3 - ctx->tmp_len; + /* + * There's a theoretical possibility for this + */ + if (n > inl) + n = inl; + memcpy(&(ctx->tmp[ctx->tmp_len]), in, n); + ctx->tmp_len += n; + ret += n; + if (ctx->tmp_len < 3) + break; + ctx->buf_len = + EVP_EncodeBlock((unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, ctx->tmp_len); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + /* + * Since we're now done using the temporary buffer, the + * length should be 0'd + */ + ctx->tmp_len = 0; + } else { + if (n < 3) { + memcpy(ctx->tmp, in, n); + ctx->tmp_len = n; + ret += n; + break; + } + n -= n % 3; + ctx->buf_len = + EVP_EncodeBlock((unsigned char *)ctx->buf, + (const unsigned char *)in, n); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret += n; + } + } else { + EVP_EncodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)in, n); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret += n; + } + inl -= n; + in += n; + + ctx->buf_off = 0; + n = ctx->buf_len; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return ((ret == 0) ? i : ret); + } + OPENSSL_assert(i <= n); + n -= i; + ctx->buf_off += i; + OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + } + ctx->buf_len = 0; + ctx->buf_off = 0; + } + return (ret); +} + +static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_B64_CTX *ctx; + long ret = 1; + int i; + + ctx = (BIO_B64_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->cont = 1; + ctx->start = 1; + ctx->encode = B64_NONE; + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_WPENDING: /* More to write in buffer */ + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret = ctx->buf_len - ctx->buf_off; + if ((ret == 0) && (ctx->encode != B64_NONE) + && (ctx->base64.num != 0)) + ret = 1; + else if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: /* More to read in buffer */ + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_FLUSH: + /* do a final write */ + again: + while (ctx->buf_len != ctx->buf_off) { + i = b64_write(b, NULL, 0); + if (i < 0) + return i; + } + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + if (ctx->tmp_len != 0) { + ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, + ctx->tmp_len); + ctx->buf_off = 0; + ctx->tmp_len = 0; + goto again; + } + } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) { + ctx->buf_off = 0; + EVP_EncodeFinal(&(ctx->base64), + (unsigned char *)ctx->buf, &(ctx->buf_len)); + /* push out the bytes */ + goto again; + } + /* Finally flush the underlying BIO */ + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_DUP: + break; + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_SET: + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int b64_puts(BIO *b, const char *str) +{ + return b64_write(b, str, strlen(str)); +} +/* crypto/bio/bio_cb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +// #include "cryptlib.h" +// #include "bio.h" +#include "err.h" + +long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp, + int argi, long argl, long ret) +{ + BIO *b; + MS_STATIC char buf[256]; + char *p; + long r = 1; + int len; + size_t p_maxlen; + + if (BIO_CB_RETURN & cmd) + r = ret; + + len = BIO_snprintf(buf,sizeof(buf),"BIO[%p]: ",(void *)bio); + + /* Ignore errors and continue printing the other information. */ + if (len < 0) + len = 0; + p = buf + len; + p_maxlen = sizeof(buf) - len; + + switch (cmd) { + case BIO_CB_FREE: + BIO_snprintf(p, p_maxlen, "Free - %s\n", bio->method->name); + break; + case BIO_CB_READ: + if (bio->method->type & BIO_TYPE_DESCRIPTOR) + BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s fd=%d\n", + bio->num, (unsigned long)argi, + bio->method->name, bio->num); + else + BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s\n", + bio->num, (unsigned long)argi, bio->method->name); + break; + case BIO_CB_WRITE: + if (bio->method->type & BIO_TYPE_DESCRIPTOR) + BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s fd=%d\n", + bio->num, (unsigned long)argi, + bio->method->name, bio->num); + else + BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s\n", + bio->num, (unsigned long)argi, bio->method->name); + break; + case BIO_CB_PUTS: + BIO_snprintf(p, p_maxlen, "puts() - %s\n", bio->method->name); + break; + case BIO_CB_GETS: + BIO_snprintf(p, p_maxlen, "gets(%lu) - %s\n", (unsigned long)argi, + bio->method->name); + break; + case BIO_CB_CTRL: + BIO_snprintf(p, p_maxlen, "ctrl(%lu) - %s\n", (unsigned long)argi, + bio->method->name); + break; + case BIO_CB_RETURN | BIO_CB_READ: + BIO_snprintf(p, p_maxlen, "read return %ld\n", ret); + break; + case BIO_CB_RETURN | BIO_CB_WRITE: + BIO_snprintf(p, p_maxlen, "write return %ld\n", ret); + break; + case BIO_CB_RETURN | BIO_CB_GETS: + BIO_snprintf(p, p_maxlen, "gets return %ld\n", ret); + break; + case BIO_CB_RETURN | BIO_CB_PUTS: + BIO_snprintf(p, p_maxlen, "puts return %ld\n", ret); + break; + case BIO_CB_RETURN | BIO_CB_CTRL: + BIO_snprintf(p, p_maxlen, "ctrl return %ld\n", ret); + break; + default: + BIO_snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd); + break; + } + + b = (BIO *)bio->cb_arg; + if (b != NULL) + BIO_write(b, buf, strlen(buf)); +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) + else + fputs(buf, stderr); +#endif + return (r); +} +/* crypto/evp/bio_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "evp.h" + +static int enc_write(BIO *h, const char *buf, int num); +static int enc_read(BIO *h, char *buf, int size); +/* + * static int enc_puts(BIO *h, const char *str); + */ +/* + * static int enc_gets(BIO *h, char *str, int size); + */ +static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int enc_new(BIO *h); +static int enc_free(BIO *data); +static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps); +#define ENC_BLOCK_SIZE (1024*4) +#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2) + +typedef struct enc_struct { + int buf_len; + int buf_off; + int cont; /* <= 0 when finished */ + int finished; + int ok; /* bad decrypt */ + EVP_CIPHER_CTX cipher; + /* + * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return + * up to a block more data than is presented to it + */ + char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2]; +} BIO_ENC_CTX; + +static BIO_METHOD methods_enc = { + BIO_TYPE_CIPHER, "cipher", + enc_write, + enc_read, + NULL, /* enc_puts, */ + NULL, /* enc_gets, */ + enc_ctrl, + enc_new, + enc_free, + enc_callback_ctrl, +}; + +BIO_METHOD *BIO_f_cipher(void) +{ + return (&methods_enc); +} + +static int enc_new(BIO *bi) +{ + BIO_ENC_CTX *ctx; + + ctx = (BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX)); + if (ctx == NULL) + return (0); + EVP_CIPHER_CTX_init(&ctx->cipher); + + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->cont = 1; + ctx->finished = 0; + ctx->ok = 1; + + bi->init = 0; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int enc_free(BIO *a) +{ + BIO_ENC_CTX *b; + + if (a == NULL) + return (0); + b = (BIO_ENC_CTX *)a->ptr; + EVP_CIPHER_CTX_cleanup(&(b->cipher)); + OPENSSL_cleanse(a->ptr, sizeof(BIO_ENC_CTX)); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int enc_read(BIO *b, char *out, int outl) +{ + int ret = 0, i; + BIO_ENC_CTX *ctx; + + if (out == NULL) + return (0); + ctx = (BIO_ENC_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + /* First check if there are bytes decoded/encoded */ + if (ctx->buf_len > 0) { + i = ctx->buf_len - ctx->buf_off; + if (i > outl) + i = outl; + memcpy(out, &(ctx->buf[ctx->buf_off]), i); + ret = i; + out += i; + outl -= i; + ctx->buf_off += i; + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + } + + /* + * At this point, we have room of outl bytes and an empty buffer, so we + * should read in some more. + */ + + while (outl > 0) { + if (ctx->cont <= 0) + break; + + /* + * read in at IV offset, read the EVP_Cipher documentation about why + */ + i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE); + + if (i <= 0) { + /* Should be continue next time we are called? */ + if (!BIO_should_retry(b->next_bio)) { + ctx->cont = i; + i = EVP_CipherFinal_ex(&(ctx->cipher), + (unsigned char *)ctx->buf, + &(ctx->buf_len)); + ctx->ok = i; + ctx->buf_off = 0; + } else { + ret = (ret == 0) ? i : ret; + break; + } + } else { + if (!EVP_CipherUpdate(&ctx->cipher, + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)&(ctx->buf[BUF_OFFSET]), + i)) { + BIO_clear_retry_flags(b); + ctx->ok = 0; + return 0; + } + ctx->cont = 1; + /* + * Note: it is possible for EVP_CipherUpdate to decrypt zero + * bytes because this is or looks like the final block: if this + * happens we should retry and either read more data or decrypt + * the final block + */ + if (ctx->buf_len == 0) + continue; + } + + if (ctx->buf_len <= outl) + i = ctx->buf_len; + else + i = outl; + if (i <= 0) + break; + memcpy(out, ctx->buf, i); + ret += i; + ctx->buf_off = i; + outl -= i; + out += i; + } + + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return ((ret == 0) ? ctx->cont : ret); +} + +static int enc_write(BIO *b, const char *in, int inl) +{ + int ret = 0, n, i; + BIO_ENC_CTX *ctx; + + ctx = (BIO_ENC_CTX *)b->ptr; + ret = inl; + + BIO_clear_retry_flags(b); + n = ctx->buf_len - ctx->buf_off; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (i); + } + ctx->buf_off += i; + n -= i; + } + /* at this point all pending data has been written */ + + if ((in == NULL) || (inl <= 0)) + return (0); + + ctx->buf_off = 0; + while (inl > 0) { + n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl; + if (!EVP_CipherUpdate(&ctx->cipher, + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)in, n)) { + BIO_clear_retry_flags(b); + ctx->ok = 0; + return 0; + } + inl -= n; + in += n; + + ctx->buf_off = 0; + n = ctx->buf_len; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (ret == inl) ? i : ret - inl; + } + n -= i; + ctx->buf_off += i; + } + ctx->buf_len = 0; + ctx->buf_off = 0; + } + BIO_copy_next_retry(b); + return (ret); +} + +static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + BIO_ENC_CTX *ctx, *dctx; + long ret = 1; + int i; + EVP_CIPHER_CTX **c_ctx; + + ctx = (BIO_ENC_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->ok = 1; + ctx->finished = 0; + EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL, + ctx->cipher.encrypt); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_WPENDING: + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: /* More to read in buffer */ + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_FLUSH: + /* do a final write */ + again: + while (ctx->buf_len != ctx->buf_off) { + i = enc_write(b, NULL, 0); + if (i < 0) + return i; + } + + if (!ctx->finished) { + ctx->finished = 1; + ctx->buf_off = 0; + ret = EVP_CipherFinal_ex(&(ctx->cipher), + (unsigned char *)ctx->buf, + &(ctx->buf_len)); + ctx->ok = (int)ret; + if (ret <= 0) + break; + + /* push out the bytes */ + goto again; + } + + /* Finally flush the underlying BIO */ + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_C_GET_CIPHER_STATUS: + ret = (long)ctx->ok; + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_C_GET_CIPHER_CTX: + c_ctx = (EVP_CIPHER_CTX **)ptr; + (*c_ctx) = &(ctx->cipher); + b->init = 1; + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + dctx = (BIO_ENC_CTX *)dbio->ptr; + EVP_CIPHER_CTX_init(&dctx->cipher); + ret = EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher); + if (ret) + dbio->init = 1; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +/*- +void BIO_set_cipher_ctx(b,c) +BIO *b; +EVP_CIPHER_ctx *c; + { + if (b == NULL) return; + + if ((b->callback != NULL) && + (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0)) + return; + + b->init=1; + ctx=(BIO_ENC_CTX *)b->ptr; + memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX)); + + if (b->callback != NULL) + b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L); + } +*/ + +void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int e) +{ + BIO_ENC_CTX *ctx; + + if (b == NULL) + return; + + if ((b->callback != NULL) && + (b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <= + 0)) + return; + + b->init = 1; + ctx = (BIO_ENC_CTX *)b->ptr; + EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e); + + if (b->callback != NULL) + b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L); +} +/* crypto/bio/bio_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +// #include "err.h" +// #include "bio.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason) + +static ERR_STRING_DATA BIO_str_functs[] = { + {ERR_FUNC(BIO_F_ACPT_STATE), "ACPT_STATE"}, + {ERR_FUNC(BIO_F_BIO_ACCEPT), "BIO_accept"}, + {ERR_FUNC(BIO_F_BIO_BER_GET_HEADER), "BIO_BER_GET_HEADER"}, + {ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL), "BIO_callback_ctrl"}, + {ERR_FUNC(BIO_F_BIO_CTRL), "BIO_ctrl"}, + {ERR_FUNC(BIO_F_BIO_GETHOSTBYNAME), "BIO_gethostbyname"}, + {ERR_FUNC(BIO_F_BIO_GETS), "BIO_gets"}, + {ERR_FUNC(BIO_F_BIO_GET_ACCEPT_SOCKET), "BIO_get_accept_socket"}, + {ERR_FUNC(BIO_F_BIO_GET_HOST_IP), "BIO_get_host_ip"}, + {ERR_FUNC(BIO_F_BIO_GET_PORT), "BIO_get_port"}, + {ERR_FUNC(BIO_F_BIO_MAKE_PAIR), "BIO_MAKE_PAIR"}, + {ERR_FUNC(BIO_F_BIO_NEW), "BIO_new"}, + {ERR_FUNC(BIO_F_BIO_NEW_FILE), "BIO_new_file"}, + {ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF), "BIO_new_mem_buf"}, + {ERR_FUNC(BIO_F_BIO_NREAD), "BIO_nread"}, + {ERR_FUNC(BIO_F_BIO_NREAD0), "BIO_nread0"}, + {ERR_FUNC(BIO_F_BIO_NWRITE), "BIO_nwrite"}, + {ERR_FUNC(BIO_F_BIO_NWRITE0), "BIO_nwrite0"}, + {ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"}, + {ERR_FUNC(BIO_F_BIO_READ), "BIO_read"}, + {ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"}, + {ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"}, + {ERR_FUNC(BIO_F_BUFFER_CTRL), "BUFFER_CTRL"}, + {ERR_FUNC(BIO_F_CONN_CTRL), "CONN_CTRL"}, + {ERR_FUNC(BIO_F_CONN_STATE), "CONN_STATE"}, + {ERR_FUNC(BIO_F_DGRAM_SCTP_READ), "DGRAM_SCTP_READ"}, + {ERR_FUNC(BIO_F_DGRAM_SCTP_WRITE), "DGRAM_SCTP_WRITE"}, + {ERR_FUNC(BIO_F_FILE_CTRL), "FILE_CTRL"}, + {ERR_FUNC(BIO_F_FILE_READ), "FILE_READ"}, + {ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "LINEBUFFER_CTRL"}, + {ERR_FUNC(BIO_F_MEM_READ), "MEM_READ"}, + {ERR_FUNC(BIO_F_MEM_WRITE), "MEM_WRITE"}, + {ERR_FUNC(BIO_F_SSL_NEW), "SSL_new"}, + {ERR_FUNC(BIO_F_WSASTARTUP), "WSASTARTUP"}, + {0, NULL} +}; + +static ERR_STRING_DATA BIO_str_reasons[] = { + {ERR_REASON(BIO_R_ACCEPT_ERROR), "accept error"}, + {ERR_REASON(BIO_R_BAD_FOPEN_MODE), "bad fopen mode"}, + {ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP), "bad hostname lookup"}, + {ERR_REASON(BIO_R_BROKEN_PIPE), "broken pipe"}, + {ERR_REASON(BIO_R_CONNECT_ERROR), "connect error"}, + {ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO), "EOF on memory BIO"}, + {ERR_REASON(BIO_R_ERROR_SETTING_NBIO), "error setting nbio"}, + {ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET), + "error setting nbio on accepted socket"}, + {ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET), + "error setting nbio on accept socket"}, + {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), + "gethostbyname addr is not af inet"}, + {ERR_REASON(BIO_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_REASON(BIO_R_INVALID_IP_ADDRESS), "invalid ip address"}, + {ERR_REASON(BIO_R_IN_USE), "in use"}, + {ERR_REASON(BIO_R_KEEPALIVE), "keepalive"}, + {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"}, + {ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED), "no accept port specified"}, + {ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED), "no hostname specified"}, + {ERR_REASON(BIO_R_NO_PORT_DEFINED), "no port defined"}, + {ERR_REASON(BIO_R_NO_PORT_SPECIFIED), "no port specified"}, + {ERR_REASON(BIO_R_NO_SUCH_FILE), "no such file"}, + {ERR_REASON(BIO_R_NULL_PARAMETER), "null parameter"}, + {ERR_REASON(BIO_R_TAG_MISMATCH), "tag mismatch"}, + {ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"}, + {ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"}, + {ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"}, + {ERR_REASON(BIO_R_UNINITIALIZED), "uninitialized"}, + {ERR_REASON(BIO_R_UNSUPPORTED_METHOD), "unsupported method"}, + {ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"}, + {ERR_REASON(BIO_R_WSASTARTUP), "WSAStartup"}, + {0, NULL} +}; + +#endif + +void ERR_load_BIO_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) { + ERR_load_strings(0, BIO_str_functs); + ERR_load_strings(0, BIO_str_reasons); + } +#endif +} +/* crypto/bio/bio_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "crypto.h" +// #include "cryptlib.h" +// #include "bio.h" +#include "stack.h" + +BIO *BIO_new(BIO_METHOD *method) +{ + BIO *ret = NULL; + + ret = (BIO *)OPENSSL_malloc(sizeof(BIO)); + if (ret == NULL) { + BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + if (!BIO_set(ret, method)) { + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +int BIO_set(BIO *bio, BIO_METHOD *method) +{ + bio->method = method; + bio->callback = NULL; + bio->cb_arg = NULL; + bio->init = 0; + bio->shutdown = 1; + bio->flags = 0; + bio->retry_reason = 0; + bio->num = 0; + bio->ptr = NULL; + bio->prev_bio = NULL; + bio->next_bio = NULL; + bio->references = 1; + bio->num_read = 0L; + bio->num_write = 0L; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); + if (method->create != NULL) + if (!method->create(bio)) { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); + return (0); + } + return (1); +} + +int BIO_free(BIO *a) +{ + int i; + + if (a == NULL) + return (0); + + i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO); +#ifdef REF_PRINT + REF_PRINT("BIO", a); +#endif + if (i > 0) + return (1); +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "BIO_free, bad reference count\n"); + abort(); + } +#endif + if ((a->callback != NULL) && + ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0)) + return (i); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); + + if ((a->method != NULL) && (a->method->destroy != NULL)) + a->method->destroy(a); + OPENSSL_free(a); + return (1); +} + +void BIO_vfree(BIO *a) +{ + BIO_free(a); +} + +void BIO_clear_flags(BIO *b, int flags) +{ + b->flags &= ~flags; +} + +int BIO_test_flags(const BIO *b, int flags) +{ + return (b->flags & flags); +} + +void BIO_set_flags(BIO *b, int flags) +{ + b->flags |= flags; +} + +long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *, + int, long, long) { + return b->callback; +} + +void BIO_set_callback(BIO *b, + long (*cb) (struct bio_st *, int, const char *, int, + long, long)) +{ + b->callback = cb; +} + +void BIO_set_callback_arg(BIO *b, char *arg) +{ + b->cb_arg = arg; +} + +char *BIO_get_callback_arg(const BIO *b) +{ + return b->cb_arg; +} + +const char *BIO_method_name(const BIO *b) +{ + return b->method->name; +} + +int BIO_method_type(const BIO *b) +{ + return b->method->type; +} + +int BIO_read(BIO *b, void *out, int outl) +{ + int i; + long (*cb) (BIO *, int, const char *, int, long, long); + + if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { + BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + if ((cb != NULL) && + ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0)) + return (i); + + if (!b->init) { + BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED); + return (-2); + } + + i = b->method->bread(b, out, outl); + + if (i > 0) + b->num_read += (unsigned long)i; + + if (cb != NULL) + i = (int)cb(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0L, (long)i); + return (i); +} + +int BIO_write(BIO *b, const void *in, int inl) +{ + int i; + long (*cb) (BIO *, int, const char *, int, long, long); + + if (b == NULL) + return (0); + + cb = b->callback; + if ((b->method == NULL) || (b->method->bwrite == NULL)) { + BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + if ((cb != NULL) && + ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0)) + return (i); + + if (!b->init) { + BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED); + return (-2); + } + + i = b->method->bwrite(b, in, inl); + + if (i > 0) + b->num_write += (unsigned long)i; + + if (cb != NULL) + i = (int)cb(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0L, (long)i); + return (i); +} + +int BIO_puts(BIO *b, const char *in) +{ + int i; + long (*cb) (BIO *, int, const char *, int, long, long); + + if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) { + BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + + if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0)) + return (i); + + if (!b->init) { + BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED); + return (-2); + } + + i = b->method->bputs(b, in); + + if (i > 0) + b->num_write += (unsigned long)i; + + if (cb != NULL) + i = (int)cb(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0L, (long)i); + return (i); +} + +int BIO_gets(BIO *b, char *in, int inl) +{ + int i; + long (*cb) (BIO *, int, const char *, int, long, long); + + if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { + BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + + if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0)) + return (i); + + if (!b->init) { + BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED); + return (-2); + } + + i = b->method->bgets(b, in, inl); + + if (cb != NULL) + i = (int)cb(b, BIO_CB_GETS | BIO_CB_RETURN, in, inl, 0L, (long)i); + return (i); +} + +int BIO_indent(BIO *b, int indent, int max) +{ + if (indent < 0) + indent = 0; + if (indent > max) + indent = max; + while (indent--) + if (BIO_puts(b, " ") != 1) + return 0; + return 1; +} + +long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) +{ + int i; + + i = iarg; + return (BIO_ctrl(b, cmd, larg, (char *)&i)); +} + +char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) +{ + char *p = NULL; + + if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0) + return (NULL); + else + return (p); +} + +long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) +{ + long ret; + long (*cb) (BIO *, int, const char *, int, long, long); + + if (b == NULL) + return (0); + + if ((b->method == NULL) || (b->method->ctrl == NULL)) { + BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + + if ((cb != NULL) && + ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0)) + return (ret); + + ret = b->method->ctrl(b, cmd, larg, parg); + + if (cb != NULL) + ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret); + return (ret); +} + +long BIO_callback_ctrl(BIO *b, int cmd, + void (*fp) (struct bio_st *, int, const char *, int, + long, long)) +{ + long ret; + long (*cb) (BIO *, int, const char *, int, long, long); + + if (b == NULL) + return (0); + + if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) { + BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + + if ((cb != NULL) && + ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0)) + return (ret); + + ret = b->method->callback_ctrl(b, cmd, fp); + + if (cb != NULL) + ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret); + return (ret); +} + +/* + * It is unfortunate to duplicate in functions what the BIO_(w)pending macros + * do; but those macros have inappropriate return type, and for interfacing + * from other programming languages, C macros aren't much of a help anyway. + */ +size_t BIO_ctrl_pending(BIO *bio) +{ + return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); +} + +size_t BIO_ctrl_wpending(BIO *bio) +{ + return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); +} + +/* put the 'bio' on the end of b's list of operators */ +BIO *BIO_push(BIO *b, BIO *bio) +{ + BIO *lb; + + if (b == NULL) + return (bio); + lb = b; + while (lb->next_bio != NULL) + lb = lb->next_bio; + lb->next_bio = bio; + if (bio != NULL) + bio->prev_bio = lb; + /* called to do internal processing */ + BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb); + return (b); +} + +/* Remove the first and return the rest */ +BIO *BIO_pop(BIO *b) +{ + BIO *ret; + + if (b == NULL) + return (NULL); + ret = b->next_bio; + + BIO_ctrl(b, BIO_CTRL_POP, 0, b); + + if (b->prev_bio != NULL) + b->prev_bio->next_bio = b->next_bio; + if (b->next_bio != NULL) + b->next_bio->prev_bio = b->prev_bio; + + b->next_bio = NULL; + b->prev_bio = NULL; + return (ret); +} + +BIO *BIO_get_retry_BIO(BIO *bio, int *reason) +{ + BIO *b, *last; + + b = last = bio; + for (;;) { + if (!BIO_should_retry(b)) + break; + last = b; + b = b->next_bio; + if (b == NULL) + break; + } + if (reason != NULL) + *reason = last->retry_reason; + return (last); +} + +int BIO_get_retry_reason(BIO *bio) +{ + return (bio->retry_reason); +} + +BIO *BIO_find_type(BIO *bio, int type) +{ + int mt, mask; + + if (!bio) + return NULL; + mask = type & 0xff; + do { + if (bio->method != NULL) { + mt = bio->method->type; + + if (!mask) { + if (mt & type) + return (bio); + } else if (mt == type) + return (bio); + } + bio = bio->next_bio; + } while (bio != NULL); + return (NULL); +} + +BIO *BIO_next(BIO *b) +{ + if (!b) + return NULL; + return b->next_bio; +} + +void BIO_free_all(BIO *bio) +{ + BIO *b; + int ref; + + while (bio != NULL) { + b = bio; + ref = b->references; + bio = bio->next_bio; + BIO_free(b); + /* Since ref count > 1, don't free anyone else. */ + if (ref > 1) + break; + } +} + +BIO *BIO_dup_chain(BIO *in) +{ + BIO *ret = NULL, *eoc = NULL, *bio, *new_bio; + + for (bio = in; bio != NULL; bio = bio->next_bio) { + if ((new_bio = BIO_new(bio->method)) == NULL) + goto err; + new_bio->callback = bio->callback; + new_bio->cb_arg = bio->cb_arg; + new_bio->init = bio->init; + new_bio->shutdown = bio->shutdown; + new_bio->flags = bio->flags; + + /* This will let SSL_s_sock() work with stdin/stdout */ + new_bio->num = bio->num; + + if (!BIO_dup_state(bio, (char *)new_bio)) { + BIO_free(new_bio); + goto err; + } + + /* copy app data */ + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data, + &bio->ex_data)) { + BIO_free(new_bio); + goto err; + } + + if (ret == NULL) { + eoc = new_bio; + ret = eoc; + } else { + BIO_push(eoc, new_bio); + eoc = new_bio; + } + } + return (ret); + err: + BIO_free_all(ret); + + return (NULL); +} + +void BIO_copy_next_retry(BIO *b) +{ + BIO_set_flags(b, BIO_get_retry_flags(b->next_bio)); + b->retry_reason = b->next_bio->retry_reason; +} + +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp, + new_func, dup_func, free_func); +} + +int BIO_set_ex_data(BIO *bio, int idx, void *data) +{ + return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data)); +} + +void *BIO_get_ex_data(BIO *bio, int idx) +{ + return (CRYPTO_get_ex_data(&(bio->ex_data), idx)); +} + +unsigned long BIO_number_read(BIO *bio) +{ + if (bio) + return bio->num_read; + return 0; +} + +unsigned long BIO_number_written(BIO *bio) +{ + if (bio) + return bio->num_write; + return 0; +} + +IMPLEMENT_STACK_OF(BIO) +/* crypto/evp/bio_md.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "evp.h" + +/* + * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest + */ + +static int md_write(BIO *h, char const *buf, int num); +static int md_read(BIO *h, char *buf, int size); +/* + * static int md_puts(BIO *h, const char *str); + */ +static int md_gets(BIO *h, char *str, int size); +static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int md_new(BIO *h); +static int md_free(BIO *data); +static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +static BIO_METHOD methods_md = { + BIO_TYPE_MD, "message digest", + md_write, + md_read, + NULL, /* md_puts, */ + md_gets, + md_ctrl, + md_new, + md_free, + md_callback_ctrl, +}; + +BIO_METHOD *BIO_f_md(void) +{ + return (&methods_md); +} + +static int md_new(BIO *bi) +{ + EVP_MD_CTX *ctx; + + ctx = EVP_MD_CTX_create(); + if (ctx == NULL) + return (0); + + bi->init = 0; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int md_free(BIO *a) +{ + if (a == NULL) + return (0); + EVP_MD_CTX_destroy(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int md_read(BIO *b, char *out, int outl) +{ + int ret = 0; + EVP_MD_CTX *ctx; + + if (out == NULL) + return (0); + ctx = b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + ret = BIO_read(b->next_bio, out, outl); + if (b->init) { + if (ret > 0) { + if (EVP_DigestUpdate(ctx, (unsigned char *)out, + (unsigned int)ret) <= 0) + return (-1); + } + } + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int md_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + EVP_MD_CTX *ctx; + + if ((in == NULL) || (inl <= 0)) + return (0); + ctx = b->ptr; + + if ((ctx != NULL) && (b->next_bio != NULL)) + ret = BIO_write(b->next_bio, in, inl); + if (b->init) { + if (ret > 0) { + if (!EVP_DigestUpdate(ctx, (const unsigned char *)in, + (unsigned int)ret)) { + BIO_clear_retry_flags(b); + return 0; + } + } + } + if (b->next_bio != NULL) { + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + } + return (ret); +} + +static long md_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + EVP_MD_CTX *ctx, *dctx, **pctx; + const EVP_MD **ppmd; + EVP_MD *md; + long ret = 1; + BIO *dbio; + + ctx = b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (b->init) + ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL); + else + ret = 0; + if (ret > 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_C_GET_MD: + if (b->init) { + ppmd = ptr; + *ppmd = ctx->digest; + } else + ret = 0; + break; + case BIO_C_GET_MD_CTX: + pctx = ptr; + *pctx = ctx; + b->init = 1; + break; + case BIO_C_SET_MD_CTX: + if (b->init) + b->ptr = ptr; + else + ret = 0; + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_C_SET_MD: + md = ptr; + ret = EVP_DigestInit_ex(ctx, md, NULL); + if (ret > 0) + b->init = 1; + break; + case BIO_CTRL_DUP: + dbio = ptr; + dctx = dbio->ptr; + if (!EVP_MD_CTX_copy_ex(dctx, ctx)) + return 0; + b->init = 1; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int md_gets(BIO *bp, char *buf, int size) +{ + EVP_MD_CTX *ctx; + unsigned int ret; + + ctx = bp->ptr; + if (size < ctx->digest->md_size) + return (0); + if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0) + return -1; + + return ((int)ret); +} + +/*- +static int md_puts(bp,str) +BIO *bp; +char *str; + { + return(-1); + } +*/ +/* bio_ndef.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "asn1.h" +#include "asn1t.h" +// #include "bio.h" +// #include "err.h" + +#include + +/* Experimental NDEF ASN1 BIO support routines */ + +/* + * The usage is quite simple, initialize an ASN1 structure, get a BIO from it + * then any data written through the BIO will end up translated to + * approptiate format on the fly. The data is streamed out and does *not* + * need to be all held in memory at once. When the BIO is flushed the output + * is finalized and any signatures etc written out. The BIO is a 'proper' + * BIO and can handle non blocking I/O correctly. The usage is simple. The + * implementation is *not*... + */ + +/* BIO support data stored in the ASN1 BIO ex_arg */ + +typedef struct ndef_aux_st { + /* ASN1 structure this BIO refers to */ + ASN1_VALUE *val; + const ASN1_ITEM *it; + /* Top of the BIO chain */ + BIO *ndef_bio; + /* Output BIO */ + BIO *out; + /* Boundary where content is inserted */ + unsigned char **boundary; + /* DER buffer start */ + unsigned char *derbuf; +} NDEF_SUPPORT; + +static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg); +static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg); +static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg); +static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) +{ + NDEF_SUPPORT *ndef_aux = NULL; + BIO *asn_bio = NULL; + const ASN1_AUX *aux = it->funcs; + ASN1_STREAM_ARG sarg; + + if (!aux || !aux->asn1_cb) { + ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED); + return NULL; + } + ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT)); + asn_bio = BIO_new(BIO_f_asn1()); + + /* ASN1 bio needs to be next to output BIO */ + + out = BIO_push(asn_bio, out); + + if (!ndef_aux || !asn_bio || !out) + goto err; + + BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free); + BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free); + + /* + * Now let callback prepend any digest, cipher etc BIOs ASN1 structure + * needs. + */ + + sarg.out = out; + sarg.ndef_bio = NULL; + sarg.boundary = NULL; + + if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) + goto err; + + ndef_aux->val = val; + ndef_aux->it = it; + ndef_aux->ndef_bio = sarg.ndef_bio; + ndef_aux->boundary = sarg.boundary; + ndef_aux->out = out; + ndef_aux->derbuf = NULL; + + BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux); + + return sarg.ndef_bio; + + err: + if (asn_bio) + BIO_free(asn_bio); + if (ndef_aux) + OPENSSL_free(ndef_aux); + return NULL; +} + +static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) +{ + NDEF_SUPPORT *ndef_aux; + unsigned char *p; + int derlen; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + p = OPENSSL_malloc(derlen); + if (!p) + return 0; + + ndef_aux->derbuf = p; + *pbuf = p; + derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + + if (!*ndef_aux->boundary) + return 0; + + *plen = *ndef_aux->boundary - *pbuf; + + return 1; +} + +static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg) +{ + NDEF_SUPPORT *ndef_aux; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + if (ndef_aux->derbuf) + OPENSSL_free(ndef_aux->derbuf); + + ndef_aux->derbuf = NULL; + *pbuf = NULL; + *plen = 0; + return 1; +} + +static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg) +{ + NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg; + if (!ndef_prefix_free(b, pbuf, plen, parg)) + return 0; + OPENSSL_free(*pndef_aux); + *pndef_aux = NULL; + return 1; +} + +static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) +{ + NDEF_SUPPORT *ndef_aux; + unsigned char *p; + int derlen; + const ASN1_AUX *aux; + ASN1_STREAM_ARG sarg; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + aux = ndef_aux->it->funcs; + + /* Finalize structures */ + sarg.ndef_bio = ndef_aux->ndef_bio; + sarg.out = ndef_aux->out; + sarg.boundary = ndef_aux->boundary; + if (aux->asn1_cb(ASN1_OP_STREAM_POST, + &ndef_aux->val, ndef_aux->it, &sarg) <= 0) + return 0; + + derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + p = OPENSSL_malloc(derlen); + if (!p) + return 0; + + ndef_aux->derbuf = p; + *pbuf = p; + derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + + if (!*ndef_aux->boundary) + return 0; + *pbuf = *ndef_aux->boundary; + *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf); + + return 1; +} +/* crypto/evp/bio_ok.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + From: Arne Ansper + + Why BIO_f_reliable? + + I wrote function which took BIO* as argument, read data from it + and processed it. Then I wanted to store the input file in + encrypted form. OK I pushed BIO_f_cipher to the BIO stack + and everything was OK. BUT if user types wrong password + BIO_f_cipher outputs only garbage and my function crashes. Yes + I can and I should fix my function, but BIO_f_cipher is + easy way to add encryption support to many existing applications + and it's hard to debug and fix them all. + + So I wanted another BIO which would catch the incorrect passwords and + file damages which cause garbage on BIO_f_cipher's output. + + The easy way is to push the BIO_f_md and save the checksum at + the end of the file. However there are several problems with this + approach: + + 1) you must somehow separate checksum from actual data. + 2) you need lot's of memory when reading the file, because you + must read to the end of the file and verify the checksum before + letting the application to read the data. + + BIO_f_reliable tries to solve both problems, so that you can + read and write arbitrary long streams using only fixed amount + of memory. + + BIO_f_reliable splits data stream into blocks. Each block is prefixed + with it's length and suffixed with it's digest. So you need only + several Kbytes of memory to buffer single block before verifying + it's digest. + + BIO_f_reliable goes further and adds several important capabilities: + + 1) the digest of the block is computed over the whole stream + -- so nobody can rearrange the blocks or remove or replace them. + + 2) to detect invalid passwords right at the start BIO_f_reliable + adds special prefix to the stream. In order to avoid known plain-text + attacks this prefix is generated as follows: + + *) digest is initialized with random seed instead of + standardized one. + *) same seed is written to output + *) well-known text is then hashed and the output + of the digest is also written to output. + + reader can now read the seed from stream, hash the same string + and then compare the digest output. + + Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I + initially wrote and tested this code on x86 machine and wrote the + digests out in machine-dependent order :( There are people using + this code and I cannot change this easily without making existing + data files unreadable. + +*/ + +#include +#include +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "bio.h" +// #include "evp.h" +#include "rand.h" + +static int ok_write(BIO *h, const char *buf, int num); +static int ok_read(BIO *h, char *buf, int size); +static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int ok_new(BIO *h); +static int ok_free(BIO *data); +static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +static int sig_out(BIO *b); +static int sig_in(BIO *b); +static int block_out(BIO *b); +static int block_in(BIO *b); +#define OK_BLOCK_SIZE (1024*4) +#define OK_BLOCK_BLOCK 4 +#define IOBS (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE) +#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back." + +typedef struct ok_struct { + size_t buf_len; + size_t buf_off; + size_t buf_len_save; + size_t buf_off_save; + int cont; /* <= 0 when finished */ + int finished; + EVP_MD_CTX md; + int blockout; /* output block is ready */ + int sigio; /* must process signature */ + unsigned char buf[IOBS]; +} BIO_OK_CTX; + +static BIO_METHOD methods_ok = { + BIO_TYPE_CIPHER, "reliable", + ok_write, + ok_read, + NULL, /* ok_puts, */ + NULL, /* ok_gets, */ + ok_ctrl, + ok_new, + ok_free, + ok_callback_ctrl, +}; + +BIO_METHOD *BIO_f_reliable(void) +{ + return (&methods_ok); +} + +static int ok_new(BIO *bi) +{ + BIO_OK_CTX *ctx; + + ctx = (BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX)); + if (ctx == NULL) + return (0); + + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->buf_len_save = 0; + ctx->buf_off_save = 0; + ctx->cont = 1; + ctx->finished = 0; + ctx->blockout = 0; + ctx->sigio = 1; + + EVP_MD_CTX_init(&ctx->md); + + bi->init = 0; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int ok_free(BIO *a) +{ + if (a == NULL) + return (0); + EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md); + OPENSSL_cleanse(a->ptr, sizeof(BIO_OK_CTX)); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int ok_read(BIO *b, char *out, int outl) +{ + int ret = 0, i, n; + BIO_OK_CTX *ctx; + + if (out == NULL) + return (0); + ctx = (BIO_OK_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) + return (0); + + while (outl > 0) { + + /* copy clean bytes to output buffer */ + if (ctx->blockout) { + i = ctx->buf_len - ctx->buf_off; + if (i > outl) + i = outl; + memcpy(out, &(ctx->buf[ctx->buf_off]), i); + ret += i; + out += i; + outl -= i; + ctx->buf_off += i; + + /* all clean bytes are out */ + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_off = 0; + + /* + * copy start of the next block into proper place + */ + if (ctx->buf_len_save - ctx->buf_off_save > 0) { + ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save; + memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]), + ctx->buf_len); + } else { + ctx->buf_len = 0; + } + ctx->blockout = 0; + } + } + + /* output buffer full -- cancel */ + if (outl == 0) + break; + + /* no clean bytes in buffer -- fill it */ + n = IOBS - ctx->buf_len; + i = BIO_read(b->next_bio, &(ctx->buf[ctx->buf_len]), n); + + if (i <= 0) + break; /* nothing new */ + + ctx->buf_len += i; + + /* no signature yet -- check if we got one */ + if (ctx->sigio == 1) { + if (!sig_in(b)) { + BIO_clear_retry_flags(b); + return 0; + } + } + + /* signature ok -- check if we got block */ + if (ctx->sigio == 0) { + if (!block_in(b)) { + BIO_clear_retry_flags(b); + return 0; + } + } + + /* invalid block -- cancel */ + if (ctx->cont <= 0) + break; + + } + + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int ok_write(BIO *b, const char *in, int inl) +{ + int ret = 0, n, i; + BIO_OK_CTX *ctx; + + if (inl <= 0) + return inl; + + ctx = (BIO_OK_CTX *)b->ptr; + ret = inl; + + if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) + return (0); + + if (ctx->sigio && !sig_out(b)) + return 0; + + do { + BIO_clear_retry_flags(b); + n = ctx->buf_len - ctx->buf_off; + while (ctx->blockout && n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + if (!BIO_should_retry(b)) + ctx->cont = 0; + return (i); + } + ctx->buf_off += i; + n -= i; + } + + /* at this point all pending data has been written */ + ctx->blockout = 0; + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_len = OK_BLOCK_BLOCK; + ctx->buf_off = 0; + } + + if ((in == NULL) || (inl <= 0)) + return (0); + + n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ? + (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl; + + memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])), + (unsigned char *)in, n); + ctx->buf_len += n; + inl -= n; + in += n; + + if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) { + if (!block_out(b)) { + BIO_clear_retry_flags(b); + return 0; + } + } + } while (inl > 0); + + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_OK_CTX *ctx; + EVP_MD *md; + const EVP_MD **ppmd; + long ret = 1; + int i; + + ctx = b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->buf_len_save = 0; + ctx->buf_off_save = 0; + ctx->cont = 1; + ctx->finished = 0; + ctx->blockout = 0; + ctx->sigio = 1; + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: /* More to read in buffer */ + case BIO_CTRL_WPENDING: /* More to read in buffer */ + ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_FLUSH: + /* do a final write */ + if (ctx->blockout == 0) + if (!block_out(b)) + return 0; + + while (ctx->blockout) { + i = ok_write(b, NULL, 0); + if (i < 0) { + ret = i; + break; + } + } + + ctx->finished = 1; + ctx->buf_off = ctx->buf_len = 0; + ctx->cont = (int)ret; + + /* Finally flush the underlying BIO */ + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_INFO: + ret = (long)ctx->cont; + break; + case BIO_C_SET_MD: + md = ptr; + if (!EVP_DigestInit_ex(&ctx->md, md, NULL)) + return 0; + b->init = 1; + break; + case BIO_C_GET_MD: + if (b->init) { + ppmd = ptr; + *ppmd = ctx->md.digest; + } else + ret = 0; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static void longswap(void *_ptr, size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + + if (is_endian.little) { + size_t i; + unsigned char *p = _ptr, c; + + for (i = 0; i < len; i += 4) { + c = p[0], p[0] = p[3], p[3] = c; + c = p[1], p[1] = p[2], p[2] = c; + } + } +} + +static int sig_out(BIO *b) +{ + BIO_OK_CTX *ctx; + EVP_MD_CTX *md; + + ctx = b->ptr; + md = &ctx->md; + + if (ctx->buf_len + 2 * md->digest->md_size > OK_BLOCK_SIZE) + return 1; + + if (!EVP_DigestInit_ex(md, md->digest, NULL)) + goto berr; + /* + * FIXME: there's absolutely no guarantee this makes any sense at all, + * particularly now EVP_MD_CTX has been restructured. + */ + if (RAND_bytes(md->md_data, md->digest->md_size) <= 0) + goto berr; + memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size); + longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size); + ctx->buf_len += md->digest->md_size; + + if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) + goto berr; + if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) + goto berr; + ctx->buf_len += md->digest->md_size; + ctx->blockout = 1; + ctx->sigio = 0; + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; +} + +static int sig_in(BIO *b) +{ + BIO_OK_CTX *ctx; + EVP_MD_CTX *md; + unsigned char tmp[EVP_MAX_MD_SIZE]; + int ret = 0; + + ctx = b->ptr; + md = &ctx->md; + + if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md->digest->md_size) + return 1; + + if (!EVP_DigestInit_ex(md, md->digest, NULL)) + goto berr; + memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size); + longswap(md->md_data, md->digest->md_size); + ctx->buf_off += md->digest->md_size; + + if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) + goto berr; + if (!EVP_DigestFinal_ex(md, tmp, NULL)) + goto berr; + ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0; + ctx->buf_off += md->digest->md_size; + if (ret == 1) { + ctx->sigio = 0; + if (ctx->buf_len != ctx->buf_off) { + memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), + ctx->buf_len - ctx->buf_off); + } + ctx->buf_len -= ctx->buf_off; + ctx->buf_off = 0; + } else { + ctx->cont = 0; + } + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; +} + +static int block_out(BIO *b) +{ + BIO_OK_CTX *ctx; + EVP_MD_CTX *md; + unsigned long tl; + + ctx = b->ptr; + md = &ctx->md; + + tl = ctx->buf_len - OK_BLOCK_BLOCK; + ctx->buf[0] = (unsigned char)(tl >> 24); + ctx->buf[1] = (unsigned char)(tl >> 16); + ctx->buf[2] = (unsigned char)(tl >> 8); + ctx->buf[3] = (unsigned char)(tl); + if (!EVP_DigestUpdate(md, + (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl)) + goto berr; + if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) + goto berr; + ctx->buf_len += md->digest->md_size; + ctx->blockout = 1; + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; +} + +static int block_in(BIO *b) +{ + BIO_OK_CTX *ctx; + EVP_MD_CTX *md; + unsigned long tl = 0; + unsigned char tmp[EVP_MAX_MD_SIZE]; + + ctx = b->ptr; + md = &ctx->md; + + assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */ + tl = ctx->buf[0]; + tl <<= 8; + tl |= ctx->buf[1]; + tl <<= 8; + tl |= ctx->buf[2]; + tl <<= 8; + tl |= ctx->buf[3]; + + if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md->digest->md_size) + return 1; + + if (!EVP_DigestUpdate(md, + (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl)) + goto berr; + if (!EVP_DigestFinal_ex(md, tmp, NULL)) + goto berr; + if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == + 0) { + /* there might be parts from next block lurking around ! */ + ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md->digest->md_size; + ctx->buf_len_save = ctx->buf_len; + ctx->buf_off = OK_BLOCK_BLOCK; + ctx->buf_len = tl + OK_BLOCK_BLOCK; + ctx->blockout = 1; + } else { + ctx->cont = 0; + } + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; +} +/* bio_pk7.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "asn1.h" +#include "pkcs7.h" +// #include "bio.h" + +#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS) +# include +#endif +#include + +/* Streaming encode support for PKCS#7 */ + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7) +{ + return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7)); +} +/* ssl/bio_ssl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +// #include "crypto.h" +// #include "bio.h" +// #include "err.h" +#include "ssl.h" + +static int ssl_write(BIO *h, const char *buf, int num); +static int ssl_read(BIO *h, char *buf, int size); +static int ssl_puts(BIO *h, const char *str); +static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int ssl_new(BIO *h); +static int ssl_free(BIO *data); +static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +typedef struct bio_ssl_st { + SSL *ssl; /* The ssl handle :-) */ + /* re-negotiate every time the total number of bytes is this size */ + int num_renegotiates; + unsigned long renegotiate_count; + unsigned long byte_count; + unsigned long renegotiate_timeout; + unsigned long last_time; +} BIO_SSL; + +static BIO_METHOD methods_sslp = { + BIO_TYPE_SSL, "ssl", + ssl_write, + ssl_read, + ssl_puts, + NULL, /* ssl_gets, */ + ssl_ctrl, + ssl_new, + ssl_free, + ssl_callback_ctrl, +}; + +BIO_METHOD *BIO_f_ssl(void) +{ + return (&methods_sslp); +} + +static int ssl_new(BIO *bi) +{ + BIO_SSL *bs; + + bs = (BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL)); + if (bs == NULL) { + BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE); + return (0); + } + memset(bs, 0, sizeof(BIO_SSL)); + bi->init = 0; + bi->ptr = (char *)bs; + bi->flags = 0; + return (1); +} + +static int ssl_free(BIO *a) +{ + BIO_SSL *bs; + + if (a == NULL) + return (0); + bs = (BIO_SSL *)a->ptr; + if (bs->ssl != NULL) + SSL_shutdown(bs->ssl); + if (a->shutdown) { + if (a->init && (bs->ssl != NULL)) + SSL_free(bs->ssl); + a->init = 0; + a->flags = 0; + } + if (a->ptr != NULL) + OPENSSL_free(a->ptr); + return (1); +} + +static int ssl_read(BIO *b, char *out, int outl) +{ + int ret = 1; + BIO_SSL *sb; + SSL *ssl; + int retry_reason = 0; + int r = 0; + + if (out == NULL) + return (0); + sb = (BIO_SSL *)b->ptr; + ssl = sb->ssl; + + BIO_clear_retry_flags(b); + +#if 0 + if (!SSL_is_init_finished(ssl)) { +/* ret=SSL_do_handshake(ssl); */ + if (ret > 0) { + + outflags = (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); + ret = -1; + goto end; + } + } +#endif +/* if (ret > 0) */ + ret = SSL_read(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + if (sb->renegotiate_count > 0) { + sb->byte_count += ret; + if (sb->byte_count > sb->renegotiate_count) { + sb->byte_count = 0; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + r = 1; + } + } + if ((sb->renegotiate_timeout > 0) && (!r)) { + unsigned long tm; + + tm = (unsigned long)time(NULL); + if (tm > sb->last_time + sb->renegotiate_timeout) { + sb->last_time = tm; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + + break; + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(b); + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(b); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_ACCEPT; + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; + break; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + case SSL_ERROR_ZERO_RETURN: + default: + break; + } + + b->retry_reason = retry_reason; + return (ret); +} + +static int ssl_write(BIO *b, const char *out, int outl) +{ + int ret, r = 0; + int retry_reason = 0; + SSL *ssl; + BIO_SSL *bs; + + if (out == NULL) + return (0); + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + + BIO_clear_retry_flags(b); + + /* + * ret=SSL_do_handshake(ssl); if (ret > 0) + */ + ret = SSL_write(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + if (bs->renegotiate_count > 0) { + bs->byte_count += ret; + if (bs->byte_count > bs->renegotiate_count) { + bs->byte_count = 0; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + r = 1; + } + } + if ((bs->renegotiate_timeout > 0) && (!r)) { + unsigned long tm; + + tm = (unsigned long)time(NULL); + if (tm > bs->last_time + bs->renegotiate_timeout) { + bs->last_time = tm; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(b); + break; + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(b); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + default: + break; + } + + b->retry_reason = retry_reason; + return (ret); +} + +static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + SSL **sslp, *ssl; + BIO_SSL *bs; + BIO *dbio, *bio; + long ret = 1; + + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) + return (0); + switch (cmd) { + case BIO_CTRL_RESET: + SSL_shutdown(ssl); + + if (ssl->handshake_func == ssl->method->ssl_connect) + SSL_set_connect_state(ssl); + else if (ssl->handshake_func == ssl->method->ssl_accept) + SSL_set_accept_state(ssl); + + SSL_clear(ssl); + + if (b->next_bio != NULL) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + else if (ssl->rbio != NULL) + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + else + ret = 1; + break; + case BIO_CTRL_INFO: + ret = 0; + break; + case BIO_C_SSL_MODE: + if (num) /* client mode */ + SSL_set_connect_state(ssl); + else + SSL_set_accept_state(ssl); + break; + case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: + ret = bs->renegotiate_timeout; + if (num < 60) + num = 5; + bs->renegotiate_timeout = (unsigned long)num; + bs->last_time = (unsigned long)time(NULL); + break; + case BIO_C_SET_SSL_RENEGOTIATE_BYTES: + ret = bs->renegotiate_count; + if ((long)num >= 512) + bs->renegotiate_count = (unsigned long)num; + break; + case BIO_C_GET_SSL_NUM_RENEGOTIATES: + ret = bs->num_renegotiates; + break; + case BIO_C_SET_SSL: + if (ssl != NULL) { + ssl_free(b); + if (!ssl_new(b)) + return 0; + } + b->shutdown = (int)num; + ssl = (SSL *)ptr; + ((BIO_SSL *)b->ptr)->ssl = ssl; + bio = SSL_get_rbio(ssl); + if (bio != NULL) { + if (b->next_bio != NULL) + BIO_push(bio, b->next_bio); + b->next_bio = bio; + CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); + } + b->init = 1; + break; + case BIO_C_GET_SSL: + if (ptr != NULL) { + sslp = (SSL **)ptr; + *sslp = ssl; + } else + ret = 0; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_WPENDING: + ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: + ret = SSL_pending(ssl); + if (ret == 0) + ret = BIO_pending(ssl->rbio); + break; + case BIO_CTRL_FLUSH: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_PUSH: + if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) { + SSL_set_bio(ssl, b->next_bio, b->next_bio); + CRYPTO_add(&b->next_bio->references, 1, CRYPTO_LOCK_BIO); + } + break; + case BIO_CTRL_POP: + /* Only detach if we are the BIO explicitly being popped */ + if (b == ptr) { + /* + * Shouldn't happen in practice because the rbio and wbio are the + * same when pushed. + */ + if (ssl->rbio != ssl->wbio) + BIO_free_all(ssl->wbio); + if (b->next_bio != NULL) + CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO); + ssl->wbio = NULL; + ssl->rbio = NULL; + } + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + + b->retry_reason = 0; + ret = (int)SSL_do_handshake(ssl); + + switch (SSL_get_error(ssl, (int)ret)) { + case SSL_ERROR_WANT_READ: + BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY); + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY); + b->retry_reason = b->next_bio->retry_reason; + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + b->retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + default: + break; + } + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + if (((BIO_SSL *)dbio->ptr)->ssl != NULL) + SSL_free(((BIO_SSL *)dbio->ptr)->ssl); + ((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl); + ((BIO_SSL *)dbio->ptr)->renegotiate_count = + ((BIO_SSL *)b->ptr)->renegotiate_count; + ((BIO_SSL *)dbio->ptr)->byte_count = ((BIO_SSL *)b->ptr)->byte_count; + ((BIO_SSL *)dbio->ptr)->renegotiate_timeout = + ((BIO_SSL *)b->ptr)->renegotiate_timeout; + ((BIO_SSL *)dbio->ptr)->last_time = ((BIO_SSL *)b->ptr)->last_time; + ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL); + break; + case BIO_C_GET_FD: + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + break; + case BIO_CTRL_SET_CALLBACK: + { +#if 0 /* FIXME: Should this be used? -- Richard + * Levitte */ + SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ret = -1; +#else + ret = 0; +#endif + } + break; + case BIO_CTRL_GET_CALLBACK: + { + void (**fptr) (const SSL *xssl, int type, int val); + + fptr = (void (**)(const SSL *xssl, int type, int val))ptr; + *fptr = SSL_get_info_callback(ssl); + } + break; + default: + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + break; + } + return (ret); +} + +static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + SSL *ssl; + BIO_SSL *bs; + long ret = 1; + + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + { + /* + * FIXME: setting this via a completely different prototype seems + * like a crap idea + */ + SSL_set_info_callback(ssl, (void (*)(const SSL *, int, int))fp); + } + break; + default: + ret = BIO_callback_ctrl(ssl->rbio, cmd, fp); + break; + } + return (ret); +} + +static int ssl_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = BIO_write(bp, str, n); + return (ret); +} + +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) +{ +#ifndef OPENSSL_NO_SOCK + BIO *ret = NULL, *buf = NULL, *ssl = NULL; + + if ((buf = BIO_new(BIO_f_buffer())) == NULL) + return (NULL); + if ((ssl = BIO_new_ssl_connect(ctx)) == NULL) + goto err; + if ((ret = BIO_push(buf, ssl)) == NULL) + goto err; + return (ret); + err: + if (buf != NULL) + BIO_free(buf); + if (ssl != NULL) + BIO_free(ssl); +#endif + return (NULL); +} + +BIO *BIO_new_ssl_connect(SSL_CTX *ctx) +{ +#ifndef OPENSSL_NO_SOCK + BIO *ret = NULL, *con = NULL, *ssl = NULL; + + if ((con = BIO_new(BIO_s_connect())) == NULL) + return (NULL); + if ((ssl = BIO_new_ssl(ctx, 1)) == NULL) + goto err; + if ((ret = BIO_push(ssl, con)) == NULL) + goto err; + return (ret); + err: + if (con != NULL) + BIO_free(con); +#endif + return (NULL); +} + +BIO *BIO_new_ssl(SSL_CTX *ctx, int client) +{ + BIO *ret; + SSL *ssl; + + if ((ret = BIO_new(BIO_f_ssl())) == NULL) + return (NULL); + if ((ssl = SSL_new(ctx)) == NULL) { + BIO_free(ret); + return (NULL); + } + if (client) + SSL_set_connect_state(ssl); + else + SSL_set_accept_state(ssl); + + BIO_set_ssl(ret, ssl, BIO_CLOSE); + return (ret); +} + +int BIO_ssl_copy_session_id(BIO *t, BIO *f) +{ + t = BIO_find_type(t, BIO_TYPE_SSL); + f = BIO_find_type(f, BIO_TYPE_SSL); + if ((t == NULL) || (f == NULL)) + return (0); + if ((((BIO_SSL *)t->ptr)->ssl == NULL) || + (((BIO_SSL *)f->ptr)->ssl == NULL)) + return (0); + SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl, ((BIO_SSL *)f->ptr)->ssl); + return (1); +} + +void BIO_ssl_shutdown(BIO *b) +{ + SSL *s; + + while (b != NULL) { + if (b->method->type == BIO_TYPE_SSL) { + s = ((BIO_SSL *)b->ptr)->ssl; + SSL_shutdown(s); + break; + } + b = b->next_bio; + } +} diff --git a/Sources/COpenSSL/bio_lcl.h b/Sources/COpenSSL/bio_lcl.h new file mode 100644 index 00000000..1d26fe3e --- /dev/null +++ b/Sources/COpenSSL/bio_lcl.h @@ -0,0 +1,36 @@ +#include "bio.h" + +#if BIO_FLAGS_UPLINK==0 +/* Shortcut UPLINK calls on most platforms... */ +# define UP_stdin stdin +# define UP_stdout stdout +# define UP_stderr stderr +# define UP_fprintf fprintf +# define UP_fgets fgets +# define UP_fread fread +# define UP_fwrite fwrite +# undef UP_fsetmod +# define UP_feof feof +# define UP_fclose fclose + +# define UP_fopen fopen +# define UP_fseek fseek +# define UP_ftell ftell +# define UP_fflush fflush +# define UP_ferror ferror +# ifdef _WIN32 +# define UP_fileno _fileno +# define UP_open _open +# define UP_read _read +# define UP_write _write +# define UP_lseek _lseek +# define UP_close _close +# else +# define UP_fileno fileno +# define UP_open open +# define UP_read read +# define UP_write write +# define UP_lseek lseek +# define UP_close close +# endif +#endif diff --git a/Sources/COpenSSL/blowfish.h b/Sources/COpenSSL/blowfish.h new file mode 100644 index 00000000..984e8dbb --- /dev/null +++ b/Sources/COpenSSL/blowfish.h @@ -0,0 +1,130 @@ +/* crypto/bf/blowfish.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BLOWFISH_H +# define HEADER_BLOWFISH_H + +# include "e_os2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_BF +# error BF is disabled. +# endif + +# define BF_ENCRYPT 1 +# define BF_DECRYPT 0 + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! BF_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define BF_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define BF_LONG unsigned long +# define BF_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define BF_LONG unsigned int +# endif + +# define BF_ROUNDS 16 +# define BF_BLOCK 8 + +typedef struct bf_key_st { + BF_LONG P[BF_ROUNDS + 2]; + BF_LONG S[4 * 256]; +} BF_KEY; + +# ifdef OPENSSL_FIPS +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data); +# endif +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data, const BF_KEY *key); +void BF_decrypt(BF_LONG *data, const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num); +const char *BF_options(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/bn.h b/Sources/COpenSSL/bn.h new file mode 100644 index 00000000..d6024069 --- /dev/null +++ b/Sources/COpenSSL/bn.h @@ -0,0 +1,1015 @@ +/* crypto/bn/bn.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_BN_H +# define HEADER_BN_H + +# include +# include "e_os2.h" +# ifndef OPENSSL_NO_FP_API +# include /* FILE */ +# endif +# include "ossl_typ.h" +# include "crypto.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These preprocessor symbols control various aspects of the bignum headers + * and library code. They're not defined by any "normal" configuration, as + * they are intended for development and testing purposes. NB: defining all + * three can be useful for debugging application code as well as openssl + * itself. BN_DEBUG - turn on various debugging alterations to the bignum + * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up + * mismanagement of bignum internals. You must also define BN_DEBUG. + */ +/* #define BN_DEBUG */ +/* #define BN_DEBUG_RAND */ + +# ifndef OPENSSL_SMALL_FOOTPRINT +# define BN_MUL_COMBA +# define BN_SQR_COMBA +# define BN_RECURSION +# endif + +/* + * This next option uses the C libraries (2 word)/(1 word) function. If it is + * not defined, I use my C version (which is slower). The reason for this + * flag is that when the particular C compiler library routine is used, and + * the library is linked with a different compiler, the library is missing. + * This mostly happens when the library is built with gcc and then linked + * using normal cc. This would be a common occurrence because gcc normally + * produces code that is 2 times faster than system compilers for the big + * number stuff. For machines with only one compiler (or shared libraries), + * this should be on. Again this in only really a problem on machines using + * "long long's", are 32bit, and are not using my assembler code. + */ +# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \ + defined(OPENSSL_SYS_WIN32) || defined(linux) +# ifndef BN_DIV2W +# define BN_DIV2W +# endif +# endif + +/* + * assuming long is 64bit - this is the DEC Alpha unsigned long long is only + * 64 bits :-(, don't define BN_LLONG for the DEC Alpha + */ +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_ULLONG unsigned long long +# define BN_ULONG unsigned long +# define BN_LONG long +# define BN_BITS 128 +# define BN_BYTES 8 +# define BN_BITS2 64 +# define BN_BITS4 32 +# define BN_MASK // (0xffffffffffffffffffffffffffffffffLL) +# define BN_MASK2 (0xffffffffffffffffL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000L) +# define BN_MASK2h1 (0xffffffff80000000L) +# define BN_TBIT (0x8000000000000000L) +# define BN_DEC_CONV (10000000000000000000UL) +# define BN_DEC_FMT1 "%lu" +# define BN_DEC_FMT2 "%019lu" +# define BN_DEC_NUM 19 +# define BN_HEX_FMT1 "%lX" +# define BN_HEX_FMT2 "%016lX" +# endif + +/* + * This is where the long long data type is 64 bits, but long is 32. For + * machines where there are 64bit registers, this is the mode to use. IRIX, + * on R4000 and above should use this mode, along with the relevant assembler + * code :-). Do NOT define BN_LLONG. + */ +# ifdef SIXTY_FOUR_BIT +# undef BN_LLONG +# undef BN_ULLONG +# define BN_ULONG unsigned long long +# define BN_LONG long long +# define BN_BITS 128 +# define BN_BYTES 8 +# define BN_BITS2 64 +# define BN_BITS4 32 +# define BN_MASK2 (0xffffffffffffffffLL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000LL) +# define BN_MASK2h1 (0xffffffff80000000LL) +# define BN_TBIT (0x8000000000000000LL) +# define BN_DEC_CONV (10000000000000000000ULL) +# define BN_DEC_FMT1 "%llu" +# define BN_DEC_FMT2 "%019llu" +# define BN_DEC_NUM 19 +# define BN_HEX_FMT1 "%llX" +# define BN_HEX_FMT2 "%016llX" +# endif + +# ifdef THIRTY_TWO_BIT +# ifdef BN_LLONG +# if defined(_WIN32) && !defined(__GNUC__) +# define BN_ULLONG unsigned __int64 +# define BN_MASK // (0xffffffffffffffffI64) +# else +# define BN_ULLONG unsigned long long +# define BN_MASK // (0xffffffffffffffffLL) +# endif +# endif +# define BN_ULONG unsigned int +# define BN_LONG int +# define BN_BITS 64 +# define BN_BYTES 4 +# define BN_BITS2 32 +# define BN_BITS4 16 +# define BN_MASK2 (0xffffffffL) +# define BN_MASK2l (0xffff) +# define BN_MASK2h1 (0xffff8000L) +# define BN_MASK2h (0xffff0000L) +# define BN_TBIT (0x80000000L) +# define BN_DEC_CONV (1000000000L) +# define BN_DEC_FMT1 "%u" +# define BN_DEC_FMT2 "%09u" +# define BN_DEC_NUM 9 +# define BN_HEX_FMT1 "%X" +# define BN_HEX_FMT2 "%08X" +# endif + +# define BN_DEFAULT_BITS 1280 + +# define BN_FLG_MALLOCED 0x01 +# define BN_FLG_STATIC_DATA 0x02 + +/* + * avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ +# define BN_FLG_CONSTTIME 0x04 + +# ifdef OPENSSL_NO_DEPRECATED +/* deprecated name for the flag */ +# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME +/* + * avoid leaking exponent information through timings + * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) + */ +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# define BN_FLG_FREE 0x8000 + /* used for debuging */ +# endif +# define BN_set_flags(b,n) ((b)->flags|=(n)) +# define BN_get_flags(b,n) ((b)->flags&(n)) + +/* + * get a clone of a BIGNUM with changed flags, for *temporary* use only (the + * two BIGNUMs cannot not be used in parallel!) + */ +# define BN_with_flags(dest,b,n) ((dest)->d=(b)->d, \ + (dest)->top=(b)->top, \ + (dest)->dmax=(b)->dmax, \ + (dest)->neg=(b)->neg, \ + (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \ + | ((b)->flags & ~BN_FLG_MALLOCED) \ + | BN_FLG_STATIC_DATA \ + | (n))) + +/* Already declared in ossl_typ.h */ +# if 0 +typedef struct bignum_st BIGNUM; +/* Used for temp variables (declaration hidden in bn_lcl.h) */ +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; +# endif + +struct bignum_st { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit + * chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int dmax; /* Size of the d array. */ + int neg; /* one if the number is negative */ + int flags; +}; + +/* Used for montgomery multiplication */ +struct bn_mont_ctx_st { + int ri; /* number of bits in R */ + BIGNUM RR; /* used to convert to montgomery form */ + BIGNUM N; /* The modulus */ + BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only + * stored for bignum algorithm) */ + BN_ULONG n0[2]; /* least significant word(s) of Ni; (type + * changed with 0.9.9, was "BN_ULONG n0;" + * before) */ + int flags; +}; + +/* + * Used for reciprocal division/mod functions It cannot be shared between + * threads + */ +struct bn_recp_ctx_st { + BIGNUM N; /* the divisor */ + BIGNUM Nr; /* the reciprocal */ + int num_bits; + int shift; + int flags; +}; + +/* Used for slow "generation" functions. */ +struct bn_gencb_st { + unsigned int ver; /* To handle binary (in)compatibility */ + void *arg; /* callback-specific data */ + union { + /* if(ver==1) - handles old style callbacks */ + void (*cb_1) (int, int, void *); + /* if(ver==2) - new callback style */ + int (*cb_2) (int, int, BN_GENCB *); + } cb; +}; +/* Wrapper function to make using BN_GENCB easier, */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); +/* Macro to populate a BN_GENCB structure with an "old"-style callback */ +# define BN_GENCB_set_old(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 1; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_1 = (callback); } +/* Macro to populate a BN_GENCB structure with a "new"-style callback */ +# define BN_GENCB_set(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 2; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_2 = (callback); } + +# define BN_prime_checks 0 /* default: select number of iterations based + * on the size of the number */ + +/* + * BN_prime_checks_for_size() returns the number of Miller-Rabin iterations + * that will be done for checking that a random number is probably prime. The + * error rate for accepting a composite number as prime depends on the size of + * the prime |b|. The error rates used are for calculating an RSA key with 2 primes, + * and so the level is what you would expect for a key of double the size of the + * prime. + * + * This table is generated using the algorithm of FIPS PUB 186-4 + * Digital Signature Standard (DSS), section F.1, page 117. + * (https://dx.doi.org/10.6028/NIST.FIPS.186-4) + * + * The following magma script was used to generate the output: + * securitybits:=125; + * k:=1024; + * for t:=1 to 65 do + * for M:=3 to Floor(2*Sqrt(k-1)-1) do + * S:=0; + * // Sum over m + * for m:=3 to M do + * s:=0; + * // Sum over j + * for j:=2 to m do + * s+:=(RealField(32)!2)^-(j+(k-1)/j); + * end for; + * S+:=2^(m-(m-1)*t)*s; + * end for; + * A:=2^(k-2-M*t); + * B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S; + * pkt:=2.00743*Log(2)*k*2^-k*(A+B); + * seclevel:=Floor(-Log(2,pkt)); + * if seclevel ge securitybits then + * printf "k: %5o, security: %o bits (t: %o, M: %o)\n",k,seclevel,t,M; + * break; + * end if; + * end for; + * if seclevel ge securitybits then break; end if; + * end for; + * + * It can be run online at: + * http://magma.maths.usyd.edu.au/calc + * + * And will output: + * k: 1024, security: 129 bits (t: 6, M: 23) + * + * k is the number of bits of the prime, securitybits is the level we want to + * reach. + * + * prime length | RSA key size | # MR tests | security level + * -------------+--------------|------------+--------------- + * (b) >= 6394 | >= 12788 | 3 | 256 bit + * (b) >= 3747 | >= 7494 | 3 | 192 bit + * (b) >= 1345 | >= 2690 | 4 | 128 bit + * (b) >= 1080 | >= 2160 | 5 | 128 bit + * (b) >= 852 | >= 1704 | 5 | 112 bit + * (b) >= 476 | >= 952 | 5 | 80 bit + * (b) >= 400 | >= 800 | 6 | 80 bit + * (b) >= 347 | >= 694 | 7 | 80 bit + * (b) >= 308 | >= 616 | 8 | 80 bit + * (b) >= 55 | >= 110 | 27 | 64 bit + * (b) >= 6 | >= 12 | 34 | 64 bit + */ + +# define BN_prime_checks_for_size(b) ((b) >= 3747 ? 3 : \ + (b) >= 1345 ? 4 : \ + (b) >= 476 ? 5 : \ + (b) >= 400 ? 6 : \ + (b) >= 347 ? 7 : \ + (b) >= 308 ? 8 : \ + (b) >= 55 ? 27 : \ + /* b >= 6 */ 34) + +# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */ +# define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \ + (((w) == 0) && ((a)->top == 0))) +# define BN_is_zero(a) ((a)->top == 0) +# define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg) +# define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg)) +# define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) + +# define BN_one(a) (BN_set_word((a),1)) +# define BN_zero_ex(a) \ + do { \ + BIGNUM *_tmp_bn = (a); \ + _tmp_bn->top = 0; \ + _tmp_bn->neg = 0; \ + } while(0) +# ifdef OPENSSL_NO_DEPRECATED +# define BN_zero(a) BN_zero_ex(a) +# else +# define BN_zero(a) (BN_set_word((a),0)) +# endif + +const BIGNUM *BN_value_one(void); +char *BN_options(void); +BN_CTX *BN_CTX_new(void); +# ifndef OPENSSL_NO_DEPRECATED +void BN_CTX_init(BN_CTX *c); +# endif +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG); +BIGNUM *BN_new(void); +void BN_init(BIGNUM *); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +void BN_set_negative(BIGNUM *b, int n); +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param a pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +# define BN_is_negative(a) ((a)->neg != 0) + +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a, int n); +# ifndef OPENSSL_NO_FP_API +int BN_print_fp(FILE *fp, const BIGNUM *a); +# endif +# ifdef HEADER_BIO_H +int BN_print(BIO *fp, const BIGNUM *a); +# else +int BN_print(void *fp, const BIGNUM *a); +# endif +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char *BN_bn2hex(const BIGNUM *a); +char *BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns + * -2 for + * error */ +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); + +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + +/* Deprecated versions */ +# ifndef OPENSSL_NO_DEPRECATED +BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + void (*callback) (int, int, void *), void *cb_arg); +int BN_is_prime(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg); +int BN_is_prime_fasttest(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), BN_CTX *ctx, + void *cb_arg, int do_trial_division); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* Newer versions */ +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1, + BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, + BN_CTX *ctx, BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void); +void BN_MONT_CTX_init(BN_MONT_CTX *ctx); +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +# define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ + (r),(a),&((mont)->RR),(mont),(ctx)) +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, + BN_MONT_CTX *mont, BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* BN_BLINDING flags */ +# define BN_BLINDING_NO_UPDATE 0x00000001 +# define BN_BLINDING_NO_RECREATE 0x00000002 + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, + BN_CTX *); +# ifndef OPENSSL_NO_DEPRECATED +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); +void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); +# endif +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx); + +# ifndef OPENSSL_NO_DEPRECATED +void BN_set_params(int mul, int high, int low, int mont); +int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ +# endif + +void BN_RECP_CTX_init(BN_RECP_CTX *recp); +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M + +/* + * Functions for arithmetic over binary polynomials represented by BIGNUMs. + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is + * ignored. Note that input arguments are not const so that their bit arrays + * can be expanded to the appropriate size if needed. + */ + +/* + * r = a + b + */ +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) +/* + * r=a mod p + */ +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +# define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) +/*- + * Some functions allow for representation of the irreducible polynomials + * as an unsigned int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ +/* r = a mod p */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], + BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); + +# endif + +/* + * faster mod functions for the 'NIST primes' 0 <= a < p^2 + */ +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +const BIGNUM *BN_get0_nist_prime_192(void); +const BIGNUM *BN_get0_nist_prime_224(void); +const BIGNUM *BN_get0_nist_prime_256(void); +const BIGNUM *BN_get0_nist_prime_384(void); +const BIGNUM *BN_get0_nist_prime_521(void); + +/* library internal functions */ + +# define bn_expand(a,bits) \ + ( \ + bits > (INT_MAX - BN_BITS2 + 1) ? \ + NULL \ + : \ + (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \ + (a) \ + : \ + bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \ + ) + +# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) +BIGNUM *bn_expand2(BIGNUM *a, int words); +# ifndef OPENSSL_NO_DEPRECATED +BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */ +# endif + +/*- + * Bignum consistency macros + * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from + * bignum data after direct manipulations on the data. There is also an + * "internal" macro, bn_check_top(), for verifying that there are no leading + * zeroes. Unfortunately, some auditing is required due to the fact that + * bn_fix_top() has become an overabused duct-tape because bignum data is + * occasionally passed around in an inconsistent state. So the following + * changes have been made to sort this out; + * - bn_fix_top()s implementation has been moved to bn_correct_top() + * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and + * bn_check_top() is as before. + * - if BN_DEBUG *is* defined; + * - bn_check_top() tries to pollute unused words even if the bignum 'top' is + * consistent. (ed: only if BN_DEBUG_RAND is defined) + * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything. + * The idea is to have debug builds flag up inconsistent bignums when they + * occur. If that occurs in a bn_fix_top(), we examine the code in question; if + * the use of bn_fix_top() was appropriate (ie. it follows directly after code + * that manipulates the bignum) it is converted to bn_correct_top(), and if it + * was not appropriate, we convert it permanently to bn_check_top() and track + * down the cause of the bug. Eventually, no internal code should be using the + * bn_fix_top() macro. External applications and libraries should try this with + * their own code too, both in terms of building against the openssl headers + * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it + * defined. This not only improves external code, it provides more test + * coverage for openssl's own code. + */ + +# ifdef BN_DEBUG + +/* We only need assert() when debugging */ +# include + +/* + * The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with + * bn_correct_top, in other words such vectors are permitted to have zeros + * in most significant limbs. Such vectors are used internally to achieve + * execution time invariance for critical operations with private keys. + * It's BN_DEBUG-only flag, because user application is not supposed to + * observe it anyway. Moreover, optimizing compiler would actually remove + * all operations manipulating the bit in question in non-BN_DEBUG build. + */ +# define BN_FLG_FIXED_TOP 0x10000 +# ifdef BN_DEBUG_RAND +/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */ +# ifndef RAND_pseudo_bytes +int RAND_pseudo_bytes(unsigned char *buf, int num); +# define BN_DEBUG_TRIX +# endif +# define bn_pollute(a) \ + do { \ + const BIGNUM *_bnum1 = (a); \ + if(_bnum1->top < _bnum1->dmax) { \ + unsigned char _tmp_char; \ + /* We cast away const without the compiler knowing, any \ + * *genuinely* constant variables that aren't mutable \ + * wouldn't be constructed with top!=dmax. */ \ + BN_ULONG *_not_const; \ + memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \ + /* Debug only - safe to ignore error return */ \ + RAND_pseudo_bytes(&_tmp_char, 1); \ + memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \ + (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \ + } \ + } while(0) +# ifdef BN_DEBUG_TRIX +# undef RAND_pseudo_bytes +# endif +# else +# define bn_pollute(a) +# endif +# define bn_check_top(a) \ + do { \ + const BIGNUM *_bnum2 = (a); \ + if (_bnum2 != NULL) { \ + int _top = _bnum2->top; \ + assert((_top == 0) || \ + (_bnum2->flags & BN_FLG_FIXED_TOP) || \ + (_bnum2->d[_top - 1] != 0)); \ + bn_pollute(_bnum2); \ + } \ + } while(0) + +# define bn_fix_top(a) bn_check_top(a) + +# define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +# define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \ + /* avoid unused variable warning with NDEBUG */ \ + (void)(_bnum2); \ + } while(0) + +# else /* !BN_DEBUG */ + +# define BN_FLG_FIXED_TOP 0 +# define bn_pollute(a) +# define bn_check_top(a) +# define bn_fix_top(a) bn_correct_top(a) +# define bn_check_size(bn, bits) +# define bn_wcheck_size(bn, words) + +# endif + +# define bn_correct_top(a) \ + { \ + BN_ULONG *ftl; \ + int tmp_top = (a)->top; \ + if (tmp_top > 0) \ + { \ + for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \ + if (*(ftl--)) break; \ + (a)->top = tmp_top; \ + } \ + if ((a)->top == 0) \ + (a)->neg = 0; \ + bn_pollute(a); \ + } + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w); +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int num); +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int num); + +/* Primes from RFC 2409 */ +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn); + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BN_strings(void); + +/* Error codes for the BN functions. */ + +/* Function codes. */ +# define BN_F_BNRAND 127 +# define BN_F_BN_BLINDING_CONVERT_EX 100 +# define BN_F_BN_BLINDING_CREATE_PARAM 128 +# define BN_F_BN_BLINDING_INVERT_EX 101 +# define BN_F_BN_BLINDING_NEW 102 +# define BN_F_BN_BLINDING_UPDATE 103 +# define BN_F_BN_BN2DEC 104 +# define BN_F_BN_BN2HEX 105 +# define BN_F_BN_CTX_GET 116 +# define BN_F_BN_CTX_NEW 106 +# define BN_F_BN_CTX_START 129 +# define BN_F_BN_DIV 107 +# define BN_F_BN_DIV_NO_BRANCH 138 +# define BN_F_BN_DIV_RECP 130 +# define BN_F_BN_EXP 123 +# define BN_F_BN_EXPAND2 108 +# define BN_F_BN_EXPAND_INTERNAL 120 +# define BN_F_BN_GF2M_MOD 131 +# define BN_F_BN_GF2M_MOD_EXP 132 +# define BN_F_BN_GF2M_MOD_MUL 133 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +# define BN_F_BN_GF2M_MOD_SQR 136 +# define BN_F_BN_GF2M_MOD_SQRT 137 +# define BN_F_BN_LSHIFT 145 +# define BN_F_BN_MOD_EXP2_MONT 118 +# define BN_F_BN_MOD_EXP_MONT 109 +# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +# define BN_F_BN_MOD_EXP_MONT_WORD 117 +# define BN_F_BN_MOD_EXP_RECP 125 +# define BN_F_BN_MOD_EXP_SIMPLE 126 +# define BN_F_BN_MOD_INVERSE 110 +# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +# define BN_F_BN_MOD_LSHIFT_QUICK 119 +# define BN_F_BN_MOD_MUL_RECIPROCAL 111 +# define BN_F_BN_MOD_SQRT 121 +# define BN_F_BN_MPI2BN 112 +# define BN_F_BN_NEW 113 +# define BN_F_BN_RAND 114 +# define BN_F_BN_RAND_RANGE 122 +# define BN_F_BN_RSHIFT 146 +# define BN_F_BN_USUB 115 + +/* Reason codes. */ +# define BN_R_ARG2_LT_ARG3 100 +# define BN_R_BAD_RECIPROCAL 101 +# define BN_R_BIGNUM_TOO_LONG 114 +# define BN_R_BITS_TOO_SMALL 118 +# define BN_R_CALLED_WITH_EVEN_MODULUS 102 +# define BN_R_DIV_BY_ZERO 103 +# define BN_R_ENCODING_ERROR 104 +# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +# define BN_R_INPUT_NOT_REDUCED 110 +# define BN_R_INVALID_LENGTH 106 +# define BN_R_INVALID_RANGE 115 +# define BN_R_INVALID_SHIFT 119 +# define BN_R_NOT_A_SQUARE 111 +# define BN_R_NOT_INITIALIZED 107 +# define BN_R_NO_INVERSE 108 +# define BN_R_NO_SOLUTION 116 +# define BN_R_P_IS_NOT_PRIME 112 +# define BN_R_TOO_MANY_ITERATIONS 113 +# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/bn_.c b/Sources/COpenSSL/bn_.c new file mode 100644 index 00000000..a7d8db1b --- /dev/null +++ b/Sources/COpenSSL/bn_.c @@ -0,0 +1,14932 @@ +/* crypto/bn/bn_add.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +/* r can == a or b */ +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + const BIGNUM *tmp; + int a_neg = a->neg, ret; + + bn_check_top(a); + bn_check_top(b); + + /*- + * a + b a+b + * a + -b a-b + * -a + b b-a + * -a + -b -(a+b) + */ + if (a_neg ^ b->neg) { + /* only one is negative */ + if (a_neg) { + tmp = a; + a = b; + b = tmp; + } + + /* we are now a - b */ + + if (BN_ucmp(a, b) < 0) { + if (!BN_usub(r, b, a)) + return (0); + r->neg = 1; + } else { + if (!BN_usub(r, a, b)) + return (0); + r->neg = 0; + } + return (1); + } + + ret = BN_uadd(r, a, b); + r->neg = a_neg; + bn_check_top(r); + return ret; +} + +/* unsigned add of b to a */ +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int max, min, dif; + BN_ULONG *ap, *bp, *rp, carry, t1, t2; + const BIGNUM *tmp; + + bn_check_top(a); + bn_check_top(b); + + if (a->top < b->top) { + tmp = a; + a = b; + b = tmp; + } + max = a->top; + min = b->top; + dif = max - min; + + if (bn_wexpand(r, max + 1) == NULL) + return 0; + + r->top = max; + + ap = a->d; + bp = b->d; + rp = r->d; + + carry = bn_add_words(rp, ap, bp, min); + rp += min; + ap += min; + bp += min; + + if (carry) { + while (dif) { + dif--; + t1 = *(ap++); + t2 = (t1 + 1) & BN_MASK2; + *(rp++) = t2; + if (t2) { + carry = 0; + break; + } + } + if (carry) { + /* carry != 0 => dif == 0 */ + *rp = 1; + r->top++; + } + } + if (dif && rp != ap) + while (dif--) + /* copy remaining words if ap != rp */ + *(rp++) = *(ap++); + r->neg = 0; + bn_check_top(r); + return 1; +} + +/* unsigned subtraction of b from a, a must be larger than b. */ +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int max, min, dif; + register BN_ULONG t1, t2, *ap, *bp, *rp; + int i, carry; +#if defined(IRIX_CC_BUG) && !defined(LINT) + int dummy; +#endif + + bn_check_top(a); + bn_check_top(b); + + max = a->top; + min = b->top; + dif = max - min; + + if (dif < 0) { /* hmm... should not be happening */ + BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3); + return (0); + } + + if (bn_wexpand(r, max) == NULL) + return (0); + + ap = a->d; + bp = b->d; + rp = r->d; + +#if 1 + carry = 0; + for (i = min; i != 0; i--) { + t1 = *(ap++); + t2 = *(bp++); + if (carry) { + carry = (t1 <= t2); + t1 = (t1 - t2 - 1) & BN_MASK2; + } else { + carry = (t1 < t2); + t1 = (t1 - t2) & BN_MASK2; + } +# if defined(IRIX_CC_BUG) && !defined(LINT) + dummy = t1; +# endif + *(rp++) = t1 & BN_MASK2; + } +#else + carry = bn_sub_words(rp, ap, bp, min); + ap += min; + bp += min; + rp += min; +#endif + if (carry) { /* subtracted */ + if (!dif) + /* error: a < b */ + return 0; + while (dif) { + dif--; + t1 = *(ap++); + t2 = (t1 - 1) & BN_MASK2; + *(rp++) = t2; + if (t1) + break; + } + } +#if 0 + memcpy(rp, ap, sizeof(*rp) * (max - i)); +#else + if (rp != ap) { + for (;;) { + if (!dif--) + break; + rp[0] = ap[0]; + if (!dif--) + break; + rp[1] = ap[1]; + if (!dif--) + break; + rp[2] = ap[2]; + if (!dif--) + break; + rp[3] = ap[3]; + rp += 4; + ap += 4; + } + } +#endif + + r->top = max; + r->neg = 0; + bn_correct_top(r); + return (1); +} + +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int max; + int add = 0, neg = 0; + const BIGNUM *tmp; + + bn_check_top(a); + bn_check_top(b); + + /*- + * a - b a-b + * a - -b a+b + * -a - b -(a+b) + * -a - -b b-a + */ + if (a->neg) { + if (b->neg) { + tmp = a; + a = b; + b = tmp; + } else { + add = 1; + neg = 1; + } + } else { + if (b->neg) { + add = 1; + neg = 0; + } + } + + if (add) { + if (!BN_uadd(r, a, b)) + return (0); + r->neg = neg; + return (1); + } + + /* We are actually doing a - b :-) */ + + max = (a->top > b->top) ? a->top : b->top; + if (bn_wexpand(r, max) == NULL) + return (0); + if (BN_ucmp(a, b) < 0) { + if (!BN_usub(r, b, a)) + return (0); + r->neg = 1; + } else { + if (!BN_usub(r, a, b)) + return (0); + r->neg = 0; + } + bn_check_top(r); + return (1); +} +/* crypto/bn/bn_asm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef BN_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +#if defined(BN_LLONG) || defined(BN_UMULT_HIGH) + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w) +{ + BN_ULONG c1 = 0; + + assert(num >= 0); + if (num <= 0) + return (c1); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul_add(rp[0], ap[0], w, c1); + mul_add(rp[1], ap[1], w, c1); + mul_add(rp[2], ap[2], w, c1); + mul_add(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } +# endif + while (num) { + mul_add(rp[0], ap[0], w, c1); + ap++; + rp++; + num--; + } + + return (c1); +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) +{ + BN_ULONG c1 = 0; + + assert(num >= 0); + if (num <= 0) + return (c1); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul(rp[0], ap[0], w, c1); + mul(rp[1], ap[1], w, c1); + mul(rp[2], ap[2], w, c1); + mul(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } +# endif + while (num) { + mul(rp[0], ap[0], w, c1); + ap++; + rp++; + num--; + } + return (c1); +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) +{ + assert(n >= 0); + if (n <= 0) + return; + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + sqr(r[0], r[1], a[0]); + sqr(r[2], r[3], a[1]); + sqr(r[4], r[5], a[2]); + sqr(r[6], r[7], a[3]); + a += 4; + r += 8; + n -= 4; + } +# endif + while (n) { + sqr(r[0], r[1], a[0]); + a++; + r += 2; + n--; + } +} + +#else /* !(defined(BN_LLONG) || + * defined(BN_UMULT_HIGH)) */ + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w) +{ + BN_ULONG c = 0; + BN_ULONG bl, bh; + + assert(num >= 0); + if (num <= 0) + return ((BN_ULONG)0); + + bl = LBITS(w); + bh = HBITS(w); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul_add(rp[0], ap[0], bl, bh, c); + mul_add(rp[1], ap[1], bl, bh, c); + mul_add(rp[2], ap[2], bl, bh, c); + mul_add(rp[3], ap[3], bl, bh, c); + ap += 4; + rp += 4; + num -= 4; + } +# endif + while (num) { + mul_add(rp[0], ap[0], bl, bh, c); + ap++; + rp++; + num--; + } + return (c); +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) +{ + BN_ULONG carry = 0; + BN_ULONG bl, bh; + + assert(num >= 0); + if (num <= 0) + return ((BN_ULONG)0); + + bl = LBITS(w); + bh = HBITS(w); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul(rp[0], ap[0], bl, bh, carry); + mul(rp[1], ap[1], bl, bh, carry); + mul(rp[2], ap[2], bl, bh, carry); + mul(rp[3], ap[3], bl, bh, carry); + ap += 4; + rp += 4; + num -= 4; + } +# endif + while (num) { + mul(rp[0], ap[0], bl, bh, carry); + ap++; + rp++; + num--; + } + return (carry); +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) +{ + assert(n >= 0); + if (n <= 0) + return; + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + sqr64(r[0], r[1], a[0]); + sqr64(r[2], r[3], a[1]); + sqr64(r[4], r[5], a[2]); + sqr64(r[6], r[7], a[3]); + a += 4; + r += 8; + n -= 4; + } +# endif + while (n) { + sqr64(r[0], r[1], a[0]); + a++; + r += 2; + n--; + } +} + +#endif /* !(defined(BN_LLONG) || + * defined(BN_UMULT_HIGH)) */ + +#if defined(BN_LLONG) && defined(BN_DIV2W) + +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ + return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d)); +} + +#else + +/* Divide h,l by d and return the result. */ +/* I need to test this some more :-( */ +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ + BN_ULONG dh, dl, q, ret = 0, th, tl, t; + int i, count = 2; + + if (d == 0) + return (BN_MASK2); + + i = BN_num_bits_word(d); + assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i)); + + i = BN_BITS2 - i; + if (h >= d) + h -= d; + + if (i) { + d <<= i; + h = (h << i) | (l >> (BN_BITS2 - i)); + l <<= i; + } + dh = (d & BN_MASK2h) >> BN_BITS4; + dl = (d & BN_MASK2l); + for (;;) { + if ((h >> BN_BITS4) == dh) + q = BN_MASK2l; + else + q = h / dh; + + th = q * dh; + tl = dl * q; + for (;;) { + t = h - th; + if ((t & BN_MASK2h) || + ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) + break; + q--; + th -= dh; + tl -= dl; + } + t = (tl >> BN_BITS4); + tl = (tl << BN_BITS4) & BN_MASK2h; + th += t; + + if (l < tl) + th++; + l -= tl; + if (h < th) { + h += d; + q--; + } + h -= th; + + if (--count == 0) + break; + + ret = q << BN_BITS4; + h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2; + l = (l & BN_MASK2l) << BN_BITS4; + } + ret |= q; + return (ret); +} +#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */ + +#ifdef BN_LLONG +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n) +{ + BN_ULLONG ll = 0; + + assert(n >= 0); + if (n <= 0) + return ((BN_ULONG)0); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + ll += (BN_ULLONG) a[0] + b[0]; + r[0] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + ll += (BN_ULLONG) a[1] + b[1]; + r[1] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + ll += (BN_ULLONG) a[2] + b[2]; + r[2] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + ll += (BN_ULLONG) a[3] + b[3]; + r[3] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + a += 4; + b += 4; + r += 4; + n -= 4; + } +# endif + while (n) { + ll += (BN_ULLONG) a[0] + b[0]; + r[0] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + a++; + b++; + r++; + n--; + } + return ((BN_ULONG)ll); +} +#else /* !BN_LLONG */ +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n) +{ + BN_ULONG c, l, t; + + assert(n >= 0); + if (n <= 0) + return ((BN_ULONG)0); + + c = 0; +# ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + t = a[0]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[0]) & BN_MASK2; + c += (l < t); + r[0] = l; + t = a[1]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[1]) & BN_MASK2; + c += (l < t); + r[1] = l; + t = a[2]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[2]) & BN_MASK2; + c += (l < t); + r[2] = l; + t = a[3]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[3]) & BN_MASK2; + c += (l < t); + r[3] = l; + a += 4; + b += 4; + r += 4; + n -= 4; + } +# endif + while (n) { + t = a[0]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[0]) & BN_MASK2; + c += (l < t); + r[0] = l; + a++; + b++; + r++; + n--; + } + return ((BN_ULONG)c); +} +#endif /* !BN_LLONG */ + +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n) +{ + BN_ULONG t1, t2; + int c = 0; + + assert(n >= 0); + if (n <= 0) + return ((BN_ULONG)0); + +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + t1 = a[0]; + t2 = b[0]; + r[0] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + t1 = a[1]; + t2 = b[1]; + r[1] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + t1 = a[2]; + t2 = b[2]; + r[2] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + t1 = a[3]; + t2 = b[3]; + r[3] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + a += 4; + b += 4; + r += 4; + n -= 4; + } +#endif + while (n) { + t1 = a[0]; + t2 = b[0]; + r[0] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + a++; + b++; + r++; + n--; + } + return (c); +} + +#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT) + +# undef bn_mul_comba8 +# undef bn_mul_comba4 +# undef bn_sqr_comba8 +# undef bn_sqr_comba4 + +/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */ +/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */ +/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ +/* + * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number + * c=(c2,c1,c0) + */ + +# ifdef BN_LLONG +/* + * Keep in mind that additions to multiplication result can not + * overflow, because its high half cannot be all-ones. + */ +# define mul_add_c(a,b,c0,c1,c2) do { \ + BN_ULONG hi; \ + BN_ULLONG t = (BN_ULLONG)(a)*(b); \ + t += c0; /* no carry */ \ + c0 = (BN_ULONG)Lw(t); \ + hi = (BN_ULONG)Hw(t); \ + c1 = (c1+hi)&BN_MASK2; if (c1 +/* + * This is essentially reference implementation, which may or may not + * result in performance improvement. E.g. on IA-32 this routine was + * observed to give 40% faster rsa1024 private key operations and 10% + * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only + * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a + * reference implementation, one to be used as starting point for + * platform-specific assembler. Mentioned numbers apply to compiler + * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and + * can vary not only from platform to platform, but even for compiler + * versions. Assembler vs. assembler improvement coefficients can + * [and are known to] differ and are to be documented elsewhere. + */ +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0p, int num) +{ + BN_ULONG c0, c1, ml, *tp, n0; +# ifdef mul64 + BN_ULONG mh; +# endif + volatile BN_ULONG *vp; + int i = 0, j; + +# if 0 /* template for platform-specific + * implementation */ + if (ap == bp) + return bn_sqr_mont(rp, ap, np, n0p, num); +# endif + vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); + + n0 = *n0p; + + c0 = 0; + ml = bp[0]; +# ifdef mul64 + mh = HBITS(ml); + ml = LBITS(ml); + for (j = 0; j < num; ++j) + mul(tp[j], ap[j], ml, mh, c0); +# else + for (j = 0; j < num; ++j) + mul(tp[j], ap[j], ml, c0); +# endif + + tp[num] = c0; + tp[num + 1] = 0; + goto enter; + + for (i = 0; i < num; i++) { + c0 = 0; + ml = bp[i]; +# ifdef mul64 + mh = HBITS(ml); + ml = LBITS(ml); + for (j = 0; j < num; ++j) + mul_add(tp[j], ap[j], ml, mh, c0); +# else + for (j = 0; j < num; ++j) + mul_add(tp[j], ap[j], ml, c0); +# endif + c1 = (tp[num] + c0) & BN_MASK2; + tp[num] = c1; + tp[num + 1] = (c1 < c0 ? 1 : 0); + enter: + c1 = tp[0]; + ml = (c1 * n0) & BN_MASK2; + c0 = 0; +# ifdef mul64 + mh = HBITS(ml); + ml = LBITS(ml); + mul_add(c1, np[0], ml, mh, c0); +# else + mul_add(c1, ml, np[0], c0); +# endif + for (j = 1; j < num; j++) { + c1 = tp[j]; +# ifdef mul64 + mul_add(c1, np[j], ml, mh, c0); +# else + mul_add(c1, ml, np[j], c0); +# endif + tp[j - 1] = c1 & BN_MASK2; + } + c1 = (tp[num] + c0) & BN_MASK2; + tp[num - 1] = c1; + tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0); + } + + if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { + c0 = bn_sub_words(rp, tp, np, num); + if (tp[num] != 0 || c0 == 0) { + for (i = 0; i < num + 2; i++) + vp[i] = 0; + return 1; + } + } + for (i = 0; i < num; i++) + rp[i] = tp[i], vp[i] = 0; + vp[num] = 0; + vp[num + 1] = 0; + return 1; +} +# else +/* + * Return value of 0 indicates that multiplication/convolution was not + * performed to signal the caller to fall down to alternative/original + * code-path. + */ +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + return 0; +} +# endif /* OPENSSL_BN_ASM_MONT */ +# endif + +#else /* !BN_MUL_COMBA */ + +/* hmm... is it faster just to do a multiply? */ +# undef bn_sqr_comba4 +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) +{ + BN_ULONG t[8]; + bn_sqr_normal(r, a, 4, t); +} + +# undef bn_sqr_comba8 +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) +{ + BN_ULONG t[16]; + bn_sqr_normal(r, a, 8, t); +} + +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +{ + r[4] = bn_mul_words(&(r[0]), a, 4, b[0]); + r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]); + r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]); + r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]); +} + +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +{ + r[8] = bn_mul_words(&(r[0]), a, 8, b[0]); + r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]); + r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]); + r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]); + r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]); + r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]); + r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]); + r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]); +} + +# ifdef OPENSSL_NO_ASM +# ifdef OPENSSL_BN_ASM_MONT +# include +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0p, int num) +{ + BN_ULONG c0, c1, *tp, n0 = *n0p; + volatile BN_ULONG *vp; + int i = 0, j; + + vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); + + for (i = 0; i <= num; i++) + tp[i] = 0; + + for (i = 0; i < num; i++) { + c0 = bn_mul_add_words(tp, ap, num, bp[i]); + c1 = (tp[num] + c0) & BN_MASK2; + tp[num] = c1; + tp[num + 1] = (c1 < c0 ? 1 : 0); + + c0 = bn_mul_add_words(tp, np, num, tp[0] * n0); + c1 = (tp[num] + c0) & BN_MASK2; + tp[num] = c1; + tp[num + 1] += (c1 < c0 ? 1 : 0); + for (j = 0; j <= num; j++) + tp[j] = tp[j + 1]; + } + + if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { + c0 = bn_sub_words(rp, tp, np, num); + if (tp[num] != 0 || c0 == 0) { + for (i = 0; i < num + 2; i++) + vp[i] = 0; + return 1; + } + } + for (i = 0; i < num; i++) + rp[i] = tp[i], vp[i] = 0; + vp[num] = 0; + vp[num + 1] = 0; + return 1; +} +# else +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + return 0; +} +# endif /* OPENSSL_BN_ASM_MONT */ +# endif + +#endif /* !BN_MUL_COMBA */ +/* crypto/bn/bn_blind.c */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +#define BN_BLINDING_COUNTER 32 + +struct bn_blinding_st { + BIGNUM *A; + BIGNUM *Ai; + BIGNUM *e; + BIGNUM *mod; /* just a reference */ +#ifndef OPENSSL_NO_DEPRECATED + unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; used + * only by crypto/rsa/rsa_eay.c, rsa_lib.c */ +#endif + CRYPTO_THREADID tid; + int counter; + unsigned long flags; + BN_MONT_CTX *m_ctx; + int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +}; + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) +{ + BN_BLINDING *ret = NULL; + + bn_check_top(mod); + + if ((ret = (BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL) { + BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + memset(ret, 0, sizeof(BN_BLINDING)); + if (A != NULL) { + if ((ret->A = BN_dup(A)) == NULL) + goto err; + } + if (Ai != NULL) { + if ((ret->Ai = BN_dup(Ai)) == NULL) + goto err; + } + + /* save a copy of mod in the BN_BLINDING structure */ + if ((ret->mod = BN_dup(mod)) == NULL) + goto err; + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(ret->mod, BN_FLG_CONSTTIME); + + /* + * Set the counter to the special value -1 to indicate that this is + * never-used fresh blinding that does not need updating before first + * use. + */ + ret->counter = -1; + CRYPTO_THREADID_current(&ret->tid); + return (ret); + err: + if (ret != NULL) + BN_BLINDING_free(ret); + return (NULL); +} + +void BN_BLINDING_free(BN_BLINDING *r) +{ + if (r == NULL) + return; + + if (r->A != NULL) + BN_free(r->A); + if (r->Ai != NULL) + BN_free(r->Ai); + if (r->e != NULL) + BN_free(r->e); + if (r->mod != NULL) + BN_free(r->mod); + OPENSSL_free(r); +} + +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) +{ + int ret = 0; + + if ((b->A == NULL) || (b->Ai == NULL)) { + BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED); + goto err; + } + + if (b->counter == -1) + b->counter = 0; + + if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL && + !(b->flags & BN_BLINDING_NO_RECREATE)) { + /* re-create blinding parameters */ + if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) + goto err; + } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) { + if (b->m_ctx != NULL) { + if (!bn_mul_mont_fixed_top(b->Ai, b->Ai, b->Ai, b->m_ctx, ctx) + || !bn_mul_mont_fixed_top(b->A, b->A, b->A, b->m_ctx, ctx)) + goto err; + } else { + if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx) + || !BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) + goto err; + } + } + + ret = 1; + err: + if (b->counter == BN_BLINDING_COUNTER) + b->counter = 0; + return (ret); +} + +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) +{ + return BN_BLINDING_convert_ex(n, NULL, b, ctx); +} + +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) +{ + int ret = 1; + + bn_check_top(n); + + if ((b->A == NULL) || (b->Ai == NULL)) { + BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED); + return (0); + } + + if (b->counter == -1) + /* Fresh blinding, doesn't need updating. */ + b->counter = 0; + else if (!BN_BLINDING_update(b, ctx)) + return (0); + + if (r != NULL && (BN_copy(r, b->Ai) == NULL)) + return 0; + + if (b->m_ctx != NULL) + ret = BN_mod_mul_montgomery(n, n, b->A, b->m_ctx, ctx); + else + ret = BN_mod_mul(n, n, b->A, b->mod, ctx); + + return ret; +} + +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) +{ + return BN_BLINDING_invert_ex(n, NULL, b, ctx); +} + +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, + BN_CTX *ctx) +{ + int ret; + + bn_check_top(n); + + if (r == NULL && (r = b->Ai) == NULL) { + BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); + return 0; + } + + if (b->m_ctx != NULL) { + /* ensure that BN_mod_mul_montgomery takes pre-defined path */ + if (n->dmax >= r->top) { + size_t i, rtop = r->top, ntop = n->top; + BN_ULONG mask; + + for (i = 0; i < rtop; i++) { + mask = (BN_ULONG)0 - ((i - ntop) >> (8 * sizeof(i) - 1)); + n->d[i] &= mask; + } + mask = (BN_ULONG)0 - ((rtop - ntop) >> (8 * sizeof(ntop) - 1)); + /* always true, if (rtop >= ntop) n->top = r->top; */ + n->top = (int)(rtop & ~mask) | (ntop & mask); + n->flags |= (BN_FLG_FIXED_TOP & ~mask); + } + ret = BN_mod_mul_montgomery(n, n, r, b->m_ctx, ctx); + } else { + ret = BN_mod_mul(n, n, r, b->mod, ctx); + } + + bn_check_top(n); + return (ret); +} + +#ifndef OPENSSL_NO_DEPRECATED +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b) +{ + return b->thread_id; +} + +void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) +{ + b->thread_id = n; +} +#endif + +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b) +{ + return &b->tid; +} + +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) +{ + return b->flags; +} + +void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) +{ + b->flags = flags; +} + +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx) +{ + int retry_counter = 32; + BN_BLINDING *ret = NULL; + + if (b == NULL) + ret = BN_BLINDING_new(NULL, NULL, m); + else + ret = b; + + if (ret == NULL) + goto err; + + if (ret->A == NULL && (ret->A = BN_new()) == NULL) + goto err; + if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) + goto err; + + if (e != NULL) { + if (ret->e != NULL) + BN_free(ret->e); + ret->e = BN_dup(e); + } + if (ret->e == NULL) + goto err; + + if (bn_mod_exp != NULL) + ret->bn_mod_exp = bn_mod_exp; + if (m_ctx != NULL) + ret->m_ctx = m_ctx; + + do { + if (!BN_rand_range(ret->A, ret->mod)) + goto err; + if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) { + /* + * this should almost never happen for good RSA keys + */ + unsigned long error = ERR_peek_last_error(); + if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) { + if (retry_counter-- == 0) { + BNerr(BN_F_BN_BLINDING_CREATE_PARAM, + BN_R_TOO_MANY_ITERATIONS); + goto err; + } + ERR_clear_error(); + } else + goto err; + } else + break; + } while (1); + + if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { + if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) + goto err; + } else { + if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) + goto err; + } + + if (ret->m_ctx != NULL) { + if (!bn_to_mont_fixed_top(ret->Ai, ret->Ai, ret->m_ctx, ctx) + || !bn_to_mont_fixed_top(ret->A, ret->A, ret->m_ctx, ctx)) + goto err; + } + + return ret; + err: + if (b == NULL && ret != NULL) { + BN_BLINDING_free(ret); + ret = NULL; + } + + return ret; +} +/* crypto/bn/knownprimes.c */ +/* Insert boilerplate */ + +#include "bn.h" + +/*- + * "First Oakley Default Group" from RFC2409, section 6.1. + * + * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } + * + * RFC2409 specifies a generator of 2. + * RFC2412 specifies a generator of of 22. + */ + +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn) +{ + static const unsigned char RFC2409_PRIME_768[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn); +} + +/*- + * "Second Oakley Default Group" from RFC2409, section 6.2. + * + * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. + * + * RFC2409 specifies a generator of 2. + * RFC2412 specifies a generator of 22. + */ + +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn) +{ + static const unsigned char RFC2409_PRIME_1024[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn); +} + +/*- + * "1536-bit MODP Group" from RFC3526, Section 2. + * + * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } + * + * RFC3526 specifies a generator of 2. + * RFC2312 specifies a generator of 22. + */ + +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_1536[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn); +} + +/*- + * "2048-bit MODP Group" from RFC3526, Section 3. + * + * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_2048[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn); +} + +/*- + * "3072-bit MODP Group" from RFC3526, Section 4. + * + * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_3072[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn); +} + +/*- + * "4096-bit MODP Group" from RFC3526, Section 5. + * + * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_4096[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn); +} + +/*- + * "6144-bit MODP Group" from RFC3526, Section 6. + * + * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_6144[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, + 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, + 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, + 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, + 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, + 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, + 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, + 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, + 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, + 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, + 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, + 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, + 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, + 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, + 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, + 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, + 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, + 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, + 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, + 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, + 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, + 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, + 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, + 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, + 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, + 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, + 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, + 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn); +} + +/*- + * "8192-bit MODP Group" from RFC3526, Section 7. + * + * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_8192[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, + 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, + 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, + 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, + 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, + 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, + 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, + 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, + 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, + 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, + 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, + 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, + 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, + 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, + 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, + 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, + 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, + 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, + 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, + 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, + 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, + 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, + 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, + 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, + 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, + 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, + 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, + 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59, + 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4, + 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, + 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA, + 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, + 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, + 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66, + 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68, + 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, + 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D, + 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, + 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, + 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7, + 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B, + 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, + 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8, + 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, + 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, + 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D, + 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36, + 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, + 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D, + 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, + 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, + 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68, + 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92, + 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, + 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B, + 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, + 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, + 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF, + 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71, + 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn); +} +/* crypto/bn/bn_ctx.c */ +/* Written by Ulf Moeller for the OpenSSL project. */ +/* ==================================================================== + * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG) +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#include +#include + +// #include "cryptlib.h" +// #include "bn_lcl.h" + +/*- + * TODO list + * + * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and + * check they can be safely removed. + * - Check +1 and other ugliness in BN_from_montgomery() + * + * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an + * appropriate 'block' size that will be honoured by bn_expand_internal() to + * prevent piddly little reallocations. OTOH, profiling bignum expansions in + * BN_CTX doesn't show this to be a big issue. + */ + +/* How many bignums are in each "pool item"; */ +#define BN_CTX_POOL_SIZE 16 +/* The stack frame info is resizing, set a first-time expansion size; */ +#define BN_CTX_START_FRAMES 32 + +/***********/ +/* BN_POOL */ +/***********/ + +/* A bundle of bignums that can be linked with other bundles */ +typedef struct bignum_pool_item { + /* The bignum values */ + BIGNUM vals[BN_CTX_POOL_SIZE]; + /* Linked-list admin */ + struct bignum_pool_item *prev, *next; +} BN_POOL_ITEM; +/* A linked-list of bignums grouped in bundles */ +typedef struct bignum_pool { + /* Linked-list admin */ + BN_POOL_ITEM *head, *current, *tail; + /* Stack depth and allocation size */ + unsigned used, size; +} BN_POOL; +static void BN_POOL_init(BN_POOL *); +static void BN_POOL_finish(BN_POOL *); +#ifndef OPENSSL_NO_DEPRECATED +static void BN_POOL_reset(BN_POOL *); +#endif +static BIGNUM *BN_POOL_get(BN_POOL *); +static void BN_POOL_release(BN_POOL *, unsigned int); + +/************/ +/* BN_STACK */ +/************/ + +/* A wrapper to manage the "stack frames" */ +typedef struct bignum_ctx_stack { + /* Array of indexes into the bignum stack */ + unsigned int *indexes; + /* Number of stack frames, and the size of the allocated array */ + unsigned int depth, size; +} BN_STACK; +static void BN_STACK_init(BN_STACK *); +static void BN_STACK_finish(BN_STACK *); +#ifndef OPENSSL_NO_DEPRECATED +static void BN_STACK_reset(BN_STACK *); +#endif +static int BN_STACK_push(BN_STACK *, unsigned int); +static unsigned int BN_STACK_pop(BN_STACK *); + +/**********/ +/* BN_CTX */ +/**********/ + +/* The opaque BN_CTX type */ +struct bignum_ctx { + /* The bignum bundles */ + BN_POOL pool; + /* The "stack frames", if you will */ + BN_STACK stack; + /* The number of bignums currently assigned */ + unsigned int used; + /* Depth of stack overflow */ + int err_stack; + /* Block "gets" until an "end" (compatibility behaviour) */ + int too_many; +}; + +/* Enable this to find BN_CTX bugs */ +#ifdef BN_CTX_DEBUG +static const char *ctxdbg_cur = NULL; +static void ctxdbg(BN_CTX *ctx) +{ + unsigned int bnidx = 0, fpidx = 0; + BN_POOL_ITEM *item = ctx->pool.head; + BN_STACK *stack = &ctx->stack; + fprintf(stderr, "(%16p): ", ctx); + while (bnidx < ctx->used) { + fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); + if (!(bnidx % BN_CTX_POOL_SIZE)) + item = item->next; + } + fprintf(stderr, "\n"); + bnidx = 0; + fprintf(stderr, " : "); + while (fpidx < stack->depth) { + while (bnidx++ < stack->indexes[fpidx]) + fprintf(stderr, " "); + fprintf(stderr, "^^^ "); + bnidx++; + fpidx++; + } + fprintf(stderr, "\n"); +} + +# define CTXDBG_ENTRY(str, ctx) do { \ + ctxdbg_cur = (str); \ + fprintf(stderr,"Starting %s\n", ctxdbg_cur); \ + ctxdbg(ctx); \ + } while(0) +# define CTXDBG_EXIT(ctx) do { \ + fprintf(stderr,"Ending %s\n", ctxdbg_cur); \ + ctxdbg(ctx); \ + } while(0) +# define CTXDBG_RET(ctx,ret) +#else +# define CTXDBG_ENTRY(str, ctx) +# define CTXDBG_EXIT(ctx) +# define CTXDBG_RET(ctx,ret) +#endif + +/* + * This function is an evil legacy and should not be used. This + * implementation is WYSIWYG, though I've done my best. + */ +#ifndef OPENSSL_NO_DEPRECATED +void BN_CTX_init(BN_CTX *ctx) +{ + /* + * Assume the caller obtained the context via BN_CTX_new() and so is + * trying to reset it for use. Nothing else makes sense, least of all + * binary compatibility from a time when they could declare a static + * variable. + */ + BN_POOL_reset(&ctx->pool); + BN_STACK_reset(&ctx->stack); + ctx->used = 0; + ctx->err_stack = 0; + ctx->too_many = 0; +} +#endif + +BN_CTX *BN_CTX_new(void) +{ + BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX)); + if (!ret) { + BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Initialise the structure */ + BN_POOL_init(&ret->pool); + BN_STACK_init(&ret->stack); + ret->used = 0; + ret->err_stack = 0; + ret->too_many = 0; + return ret; +} + +void BN_CTX_free(BN_CTX *ctx) +{ + if (ctx == NULL) + return; +#ifdef BN_CTX_DEBUG + { + BN_POOL_ITEM *pool = ctx->pool.head; + fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n", + ctx->stack.size, ctx->pool.size); + fprintf(stderr, "dmaxs: "); + while (pool) { + unsigned loop = 0; + while (loop < BN_CTX_POOL_SIZE) + fprintf(stderr, "%02x ", pool->vals[loop++].dmax); + pool = pool->next; + } + fprintf(stderr, "\n"); + } +#endif + BN_STACK_finish(&ctx->stack); + BN_POOL_finish(&ctx->pool); + OPENSSL_free(ctx); +} + +void BN_CTX_start(BN_CTX *ctx) +{ + CTXDBG_ENTRY("BN_CTX_start", ctx); + /* If we're already overflowing ... */ + if (ctx->err_stack || ctx->too_many) + ctx->err_stack++; + /* (Try to) get a new frame pointer */ + else if (!BN_STACK_push(&ctx->stack, ctx->used)) { + BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + ctx->err_stack++; + } + CTXDBG_EXIT(ctx); +} + +void BN_CTX_end(BN_CTX *ctx) +{ + CTXDBG_ENTRY("BN_CTX_end", ctx); + if (ctx->err_stack) + ctx->err_stack--; + else { + unsigned int fp = BN_STACK_pop(&ctx->stack); + /* Does this stack frame have anything to release? */ + if (fp < ctx->used) + BN_POOL_release(&ctx->pool, ctx->used - fp); + ctx->used = fp; + /* Unjam "too_many" in case "get" had failed */ + ctx->too_many = 0; + } + CTXDBG_EXIT(ctx); +} + +BIGNUM *BN_CTX_get(BN_CTX *ctx) +{ + BIGNUM *ret; + CTXDBG_ENTRY("BN_CTX_get", ctx); + if (ctx->err_stack || ctx->too_many) + return NULL; + if ((ret = BN_POOL_get(&ctx->pool)) == NULL) { + /* + * Setting too_many prevents repeated "get" attempts from cluttering + * the error stack. + */ + ctx->too_many = 1; + BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + return NULL; + } + /* OK, make sure the returned bignum is "zero" */ + BN_zero(ret); + ctx->used++; + CTXDBG_RET(ctx, ret); + return ret; +} + +/************/ +/* BN_STACK */ +/************/ + +static void BN_STACK_init(BN_STACK *st) +{ + st->indexes = NULL; + st->depth = st->size = 0; +} + +static void BN_STACK_finish(BN_STACK *st) +{ + if (st->size) + OPENSSL_free(st->indexes); +} + +#ifndef OPENSSL_NO_DEPRECATED +static void BN_STACK_reset(BN_STACK *st) +{ + st->depth = 0; +} +#endif + +static int BN_STACK_push(BN_STACK *st, unsigned int idx) +{ + if (st->depth == st->size) + /* Need to expand */ + { + unsigned int newsize = (st->size ? + (st->size * 3 / 2) : BN_CTX_START_FRAMES); + unsigned int *newitems = OPENSSL_malloc(newsize * + sizeof(unsigned int)); + if (!newitems) + return 0; + if (st->depth) + memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int)); + if (st->size) + OPENSSL_free(st->indexes); + st->indexes = newitems; + st->size = newsize; + } + st->indexes[(st->depth)++] = idx; + return 1; +} + +static unsigned int BN_STACK_pop(BN_STACK *st) +{ + return st->indexes[--(st->depth)]; +} + +/***********/ +/* BN_POOL */ +/***********/ + +static void BN_POOL_init(BN_POOL *p) +{ + p->head = p->current = p->tail = NULL; + p->used = p->size = 0; +} + +static void BN_POOL_finish(BN_POOL *p) +{ + while (p->head) { + unsigned int loop = 0; + BIGNUM *bn = p->head->vals; + while (loop++ < BN_CTX_POOL_SIZE) { + if (bn->d) + BN_clear_free(bn); + bn++; + } + p->current = p->head->next; + OPENSSL_free(p->head); + p->head = p->current; + } +} + +#ifndef OPENSSL_NO_DEPRECATED +static void BN_POOL_reset(BN_POOL *p) +{ + BN_POOL_ITEM *item = p->head; + while (item) { + unsigned int loop = 0; + BIGNUM *bn = item->vals; + while (loop++ < BN_CTX_POOL_SIZE) { + if (bn->d) + BN_clear(bn); + bn++; + } + item = item->next; + } + p->current = p->head; + p->used = 0; +} +#endif + +static BIGNUM *BN_POOL_get(BN_POOL *p) +{ + if (p->used == p->size) { + BIGNUM *bn; + unsigned int loop = 0; + BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM)); + if (!item) + return NULL; + /* Initialise the structure */ + bn = item->vals; + while (loop++ < BN_CTX_POOL_SIZE) + BN_init(bn++); + item->prev = p->tail; + item->next = NULL; + /* Link it in */ + if (!p->head) + p->head = p->current = p->tail = item; + else { + p->tail->next = item; + p->tail = item; + p->current = item; + } + p->size += BN_CTX_POOL_SIZE; + p->used++; + /* Return the first bignum from the new pool */ + return item->vals; + } + if (!p->used) + p->current = p->head; + else if ((p->used % BN_CTX_POOL_SIZE) == 0) + p->current = p->current->next; + return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE); +} + +static void BN_POOL_release(BN_POOL *p, unsigned int num) +{ + unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE; + p->used -= num; + while (num--) { + bn_check_top(p->current->vals + offset); + if (!offset) { + offset = BN_CTX_POOL_SIZE - 1; + p->current = p->current->prev; + } else + offset--; + } +} +/* crypto/bn/bn_depr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Support for deprecated functions goes here - static linkage will only + * slurp this code if applications are using them directly. + */ + +#include +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" +#include "rand.h" + +static void *dummy = &dummy; + +#ifndef OPENSSL_NO_DEPRECATED +BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + void (*callback) (int, int, void *), void *cb_arg) +{ + BN_GENCB cb; + BIGNUM *rnd = NULL; + int found = 0; + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (ret == NULL) { + if ((rnd = BN_new()) == NULL) + goto err; + } else + rnd = ret; + if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb)) + goto err; + + /* we have a prime :-) */ + found = 1; + err: + if (!found && (ret == NULL) && (rnd != NULL)) + BN_free(rnd); + return (found ? rnd : NULL); +} + +int BN_is_prime(const BIGNUM *a, int checks, + void (*callback) (int, int, void *), BN_CTX *ctx_passed, + void *cb_arg) +{ + BN_GENCB cb; + BN_GENCB_set_old(&cb, callback, cb_arg); + return BN_is_prime_ex(a, checks, ctx_passed, &cb); +} + +int BN_is_prime_fasttest(const BIGNUM *a, int checks, + void (*callback) (int, int, void *), + BN_CTX *ctx_passed, void *cb_arg, + int do_trial_division) +{ + BN_GENCB cb; + BN_GENCB_set_old(&cb, callback, cb_arg); + return BN_is_prime_fasttest_ex(a, checks, ctx_passed, + do_trial_division, &cb); +} +#endif +/* crypto/bn/bn_div.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "bn.h" +// #include "cryptlib.h" +// #include "bn_lcl.h" + +/* The old slow way */ +#if 0 +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx) +{ + int i, nm, nd; + int ret = 0; + BIGNUM *D; + + bn_check_top(m); + bn_check_top(d); + if (BN_is_zero(d)) { + BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); + return (0); + } + + if (BN_ucmp(m, d) < 0) { + if (rem != NULL) { + if (BN_copy(rem, m) == NULL) + return (0); + } + if (dv != NULL) + BN_zero(dv); + return (1); + } + + BN_CTX_start(ctx); + D = BN_CTX_get(ctx); + if (dv == NULL) + dv = BN_CTX_get(ctx); + if (rem == NULL) + rem = BN_CTX_get(ctx); + if (D == NULL || dv == NULL || rem == NULL) + goto end; + + nd = BN_num_bits(d); + nm = BN_num_bits(m); + if (BN_copy(D, d) == NULL) + goto end; + if (BN_copy(rem, m) == NULL) + goto end; + + /* + * The next 2 are needed so we can do a dv->d[0]|=1 later since + * BN_lshift1 will only work once there is a value :-) + */ + BN_zero(dv); + if (bn_wexpand(dv, 1) == NULL) + goto end; + dv->top = 1; + + if (!BN_lshift(D, D, nm - nd)) + goto end; + for (i = nm - nd; i >= 0; i--) { + if (!BN_lshift1(dv, dv)) + goto end; + if (BN_ucmp(rem, D) >= 0) { + dv->d[0] |= 1; + if (!BN_usub(rem, rem, D)) + goto end; + } +/* CAN IMPROVE (and have now :=) */ + if (!BN_rshift1(D, D)) + goto end; + } + rem->neg = BN_is_zero(rem) ? 0 : m->neg; + dv->neg = m->neg ^ d->neg; + ret = 1; + end: + BN_CTX_end(ctx); + return (ret); +} + +#else + +# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \ + && !defined(PEDANTIC) && !defined(BN_DIV3W) +# if defined(__GNUC__) && __GNUC__>=2 +# if defined(__i386) || defined (__i386__) + /*- + * There were two reasons for implementing this template: + * - GNU C generates a call to a function (__udivdi3 to be exact) + * in reply to ((((BN_ULLONG)n0)< + */ +# undef bn_div_words +# define bn_div_words(n0,n1,d0) \ + ({ asm volatile ( \ + "divl %4" \ + : "=a"(q), "=d"(rem) \ + : "a"(n1), "d"(n0), "r"(d0) \ + : "cc"); \ + q; \ + }) +# define REMAINDER_IS_ALREADY_CALCULATED +# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG) + /* + * Same story here, but it's 128-bit by 64-bit division. Wow! + * + */ +# undef bn_div_words +# define bn_div_words(n0,n1,d0) \ + ({ asm volatile ( \ + "divq %4" \ + : "=a"(q), "=d"(rem) \ + : "a"(n1), "d"(n0), "r"(d0) \ + : "cc"); \ + q; \ + }) +# define REMAINDER_IS_ALREADY_CALCULATED +# endif /* __ */ +# endif /* __GNUC__ */ +# endif /* OPENSSL_NO_ASM */ + +/*- + * BN_div computes dv := num / divisor, rounding towards + * zero, and sets up rm such that dv*divisor + rm = num holds. + * Thus: + * dv->neg == num->neg ^ divisor->neg (unless the result is zero) + * rm->neg == num->neg (unless the remainder is zero) + * If 'dv' or 'rm' is NULL, the respective value is not returned. + */ +int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, + BN_CTX *ctx) +{ + int norm_shift, i, loop; + BIGNUM *tmp, wnum, *snum, *sdiv, *res; + BN_ULONG *resp, *wnump; + BN_ULONG d0, d1; + int num_n, div_n; + int no_branch = 0; + + /* + * Invalid zero-padding would have particularly bad consequences so don't + * just rely on bn_check_top() here (bn_check_top() works only for + * BN_DEBUG builds) + */ + if ((num->top > 0 && num->d[num->top - 1] == 0) || + (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) { + BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED); + return 0; + } + + bn_check_top(num); + bn_check_top(divisor); + + if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) + || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) { + no_branch = 1; + } + + bn_check_top(dv); + bn_check_top(rm); + /*- bn_check_top(num); *//* + * 'num' has been checked already + */ + /*- bn_check_top(divisor); *//* + * 'divisor' has been checked already + */ + + if (BN_is_zero(divisor)) { + BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); + return (0); + } + + if (!no_branch && BN_ucmp(num, divisor) < 0) { + if (rm != NULL) { + if (BN_copy(rm, num) == NULL) + return (0); + } + if (dv != NULL) + BN_zero(dv); + return (1); + } + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + snum = BN_CTX_get(ctx); + sdiv = BN_CTX_get(ctx); + if (dv == NULL) + res = BN_CTX_get(ctx); + else + res = dv; + if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL) + goto err; + + /* First we normalise the numbers */ + norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2); + if (!(BN_lshift(sdiv, divisor, norm_shift))) + goto err; + sdiv->neg = 0; + norm_shift += BN_BITS2; + if (!(BN_lshift(snum, num, norm_shift))) + goto err; + snum->neg = 0; + + if (no_branch) { + /* + * Since we don't know whether snum is larger than sdiv, we pad snum + * with enough zeroes without changing its value. + */ + if (snum->top <= sdiv->top + 1) { + if (bn_wexpand(snum, sdiv->top + 2) == NULL) + goto err; + for (i = snum->top; i < sdiv->top + 2; i++) + snum->d[i] = 0; + snum->top = sdiv->top + 2; + } else { + if (bn_wexpand(snum, snum->top + 1) == NULL) + goto err; + snum->d[snum->top] = 0; + snum->top++; + } + } + + div_n = sdiv->top; + num_n = snum->top; + loop = num_n - div_n; + /* + * Lets setup a 'window' into snum This is the part that corresponds to + * the current 'area' being divided + */ + wnum.neg = 0; + wnum.d = &(snum->d[loop]); + wnum.top = div_n; + wnum.flags = BN_FLG_STATIC_DATA; + /* + * only needed when BN_ucmp messes up the values between top and max + */ + wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */ + + /* Get the top 2 words of sdiv */ + /* div_n=sdiv->top; */ + d0 = sdiv->d[div_n - 1]; + d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2]; + + /* pointer to the 'top' of snum */ + wnump = &(snum->d[num_n - 1]); + + /* Setup to 'res' */ + res->neg = (num->neg ^ divisor->neg); + if (!bn_wexpand(res, (loop + 1))) + goto err; + res->top = loop - no_branch; + resp = &(res->d[loop - 1]); + + /* space for temp */ + if (!bn_wexpand(tmp, (div_n + 1))) + goto err; + + if (!no_branch) { + if (BN_ucmp(&wnum, sdiv) >= 0) { + /* + * If BN_DEBUG_RAND is defined BN_ucmp changes (via bn_pollute) + * the const bignum arguments => clean the values between top and + * max again + */ + bn_clear_top2max(&wnum); + bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n); + *resp = 1; + } else + res->top--; + } + + /* + * if res->top == 0 then clear the neg value otherwise decrease the resp + * pointer + */ + if (res->top == 0) + res->neg = 0; + else + resp--; + + for (i = 0; i < loop - 1; i++, wnump--, resp--) { + BN_ULONG q, l0; + /* + * the first part of the loop uses the top two words of snum and sdiv + * to calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv + */ +# if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM) + BN_ULONG bn_div_3_words(BN_ULONG *, BN_ULONG, BN_ULONG); + q = bn_div_3_words(wnump, d1, d0); +# else + BN_ULONG n0, n1, rem = 0; + + n0 = wnump[0]; + n1 = wnump[-1]; + if (n0 == d0) + q = BN_MASK2; + else { /* n0 < d0 */ + +# ifdef BN_LLONG + BN_ULLONG t2; + +# if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words) + q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0); +# else + q = bn_div_words(n0, n1, d0); +# ifdef BN_DEBUG_LEVITTE + fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ +X) -> 0x%08X\n", n0, n1, d0, q); +# endif +# endif + +# ifndef REMAINDER_IS_ALREADY_CALCULATED + /* + * rem doesn't have to be BN_ULLONG. The least we + * know it's less that d0, isn't it? + */ + rem = (n1 - q * d0) & BN_MASK2; +# endif + t2 = (BN_ULLONG) d1 *q; + + for (;;) { + if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | wnump[-2])) + break; + q--; + rem += d0; + if (rem < d0) + break; /* don't let rem overflow */ + t2 -= d1; + } +# else /* !BN_LLONG */ + BN_ULONG t2l, t2h; + + q = bn_div_words(n0, n1, d0); +# ifdef BN_DEBUG_LEVITTE + fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ +X) -> 0x%08X\n", n0, n1, d0, q); +# endif +# ifndef REMAINDER_IS_ALREADY_CALCULATED + rem = (n1 - q * d0) & BN_MASK2; +# endif + +# if defined(BN_UMULT_LOHI) + BN_UMULT_LOHI(t2l, t2h, d1, q); +# elif defined(BN_UMULT_HIGH) + t2l = d1 * q; + t2h = BN_UMULT_HIGH(d1, q); +# else + { + BN_ULONG ql, qh; + t2l = LBITS(d1); + t2h = HBITS(d1); + ql = LBITS(q); + qh = HBITS(q); + mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */ + } +# endif + + for (;;) { + if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) + break; + q--; + rem += d0; + if (rem < d0) + break; /* don't let rem overflow */ + if (t2l < d1) + t2h--; + t2l -= d1; + } +# endif /* !BN_LLONG */ + } +# endif /* !BN_DIV3W */ + + l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q); + tmp->d[div_n] = l0; + wnum.d--; + /* + * ingore top values of the bignums just sub the two BN_ULONG arrays + * with bn_sub_words + */ + if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) { + /* + * Note: As we have considered only the leading two BN_ULONGs in + * the calculation of q, sdiv * q might be greater than wnum (but + * then (q-1) * sdiv is less or equal than wnum) + */ + q--; + if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n)) + /* + * we can't have an overflow here (assuming that q != 0, but + * if q == 0 then tmp is zero anyway) + */ + (*wnump)++; + } + /* store part of the result */ + *resp = q; + } + bn_correct_top(snum); + if (rm != NULL) { + /* + * Keep a copy of the neg flag in num because if rm==num BN_rshift() + * will overwrite it. + */ + int neg = num->neg; + BN_rshift(rm, snum, norm_shift); + if (!BN_is_zero(rm)) + rm->neg = neg; + bn_check_top(rm); + } + if (no_branch) + bn_correct_top(res); + BN_CTX_end(ctx); + return (1); + err: + bn_check_top(rm); + BN_CTX_end(ctx); + return (0); +} +#endif +/* crypto/bn/bn_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "bn.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason) + +static ERR_STRING_DATA BN_str_functs[] = { + {ERR_FUNC(BN_F_BNRAND), "BNRAND"}, + {ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX), "BN_BLINDING_convert_ex"}, + {ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM), "BN_BLINDING_create_param"}, + {ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX), "BN_BLINDING_invert_ex"}, + {ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"}, + {ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"}, + {ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"}, + {ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"}, + {ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"}, + {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"}, + {ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"}, + {ERR_FUNC(BN_F_BN_DIV), "BN_div"}, + {ERR_FUNC(BN_F_BN_DIV_NO_BRANCH), "BN_div_no_branch"}, + {ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"}, + {ERR_FUNC(BN_F_BN_EXP), "BN_exp"}, + {ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"}, + {ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD), "BN_GF2m_mod_solve_quad"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"}, + {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"}, + {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD), "BN_mod_exp_mont_word"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"}, + {ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"}, + {ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"}, + {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"}, + {ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"}, + {ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"}, + {ERR_FUNC(BN_F_BN_MPI2BN), "BN_mpi2bn"}, + {ERR_FUNC(BN_F_BN_NEW), "BN_new"}, + {ERR_FUNC(BN_F_BN_RAND), "BN_rand"}, + {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"}, + {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"}, + {ERR_FUNC(BN_F_BN_USUB), "BN_usub"}, + {0, NULL} +}; + +static ERR_STRING_DATA BN_str_reasons[] = { + {ERR_REASON(BN_R_ARG2_LT_ARG3), "arg2 lt arg3"}, + {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"}, + {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"}, + {ERR_REASON(BN_R_BITS_TOO_SMALL), "bits too small"}, + {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"}, + {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"}, + {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"}, + {ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA), + "expand on static bignum data"}, + {ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"}, + {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"}, + {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"}, + {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"}, + {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"}, + {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"}, + {ERR_REASON(BN_R_NO_INVERSE), "no inverse"}, + {ERR_REASON(BN_R_NO_SOLUTION), "no solution"}, + {ERR_REASON(BN_R_P_IS_NOT_PRIME), "p is not prime"}, + {ERR_REASON(BN_R_TOO_MANY_ITERATIONS), "too many iterations"}, + {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES), + "too many temporary variables"}, + {0, NULL} +}; + +#endif + +void ERR_load_BN_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(BN_str_functs[0].error) == NULL) { + ERR_load_strings(0, BN_str_functs); + ERR_load_strings(0, BN_str_reasons); + } +#endif +} +/* crypto/bn/bn_exp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +#include "constant_time_locl.h" +// #include "bn_lcl.h" + +#include +#ifdef _WIN32 +# include +# ifndef alloca +# define alloca _alloca +# endif +#elif defined(__GNUC__) +# ifndef alloca +# define alloca(s) __builtin_alloca((s)) +# endif +#elif defined(__sun) +# include +#endif + +#include "rsaz_exp.h" + +#undef SPARC_T4_MONT +#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc)) +# include "sparc_arch.h" +extern unsigned int OPENSSL_sparcv9cap_P[]; +# define SPARC_T4_MONT +#endif + +/* maximum precomputation table size for *variable* sliding windows */ +#define TABLE_SIZE 32 + +/* this one works - simple but works */ +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + int i, bits, ret = 0; + BIGNUM *v, *rr; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + BN_CTX_start(ctx); + if ((r == a) || (r == p)) + rr = BN_CTX_get(ctx); + else + rr = r; + v = BN_CTX_get(ctx); + if (rr == NULL || v == NULL) + goto err; + + if (BN_copy(v, a) == NULL) + goto err; + bits = BN_num_bits(p); + + if (BN_is_odd(p)) { + if (BN_copy(rr, a) == NULL) + goto err; + } else { + if (!BN_one(rr)) + goto err; + } + + for (i = 1; i < bits; i++) { + if (!BN_sqr(v, v, ctx)) + goto err; + if (BN_is_bit_set(p, i)) { + if (!BN_mul(rr, rr, v, ctx)) + goto err; + } + } + if (r != rr && BN_copy(r, rr) == NULL) + goto err; + + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(r); + return (ret); +} + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) +{ + int ret; + + bn_check_top(a); + bn_check_top(p); + bn_check_top(m); + + /*- + * For even modulus m = 2^k*m_odd, it might make sense to compute + * a^p mod m_odd and a^p mod 2^k separately (with Montgomery + * exponentiation for the odd part), using appropriate exponent + * reductions, and combine the results using the CRT. + * + * For now, we use Montgomery only if the modulus is odd; otherwise, + * exponentiation using the reciprocal-based quick remaindering + * algorithm is used. + * + * (Timing obtained with expspeed.c [computations a^p mod m + * where a, p, m are of the same length: 256, 512, 1024, 2048, + * 4096, 8192 bits], compared to the running time of the + * standard algorithm: + * + * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration] + * 55 .. 77 % [UltraSparc processor, but + * debug-solaris-sparcv8-gcc conf.] + * + * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration] + * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc] + * + * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont + * at 2048 and more bits, but at 512 and 1024 bits, it was + * slower even than the standard algorithm! + * + * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations] + * should be obtained when the new Montgomery reduction code + * has been integrated into OpenSSL.) + */ + +#define MONT_MUL_MOD +#define MONT_EXP_WORD +#define RECP_MUL_MOD + +#ifdef MONT_MUL_MOD + /* + * I have finally been able to take out this pre-condition of the top bit + * being set. It was caused by an error in BN_div with negatives. There + * was also another problem when for a^b%m a >= m. eay 07-May-97 + */ + /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */ + + if (BN_is_odd(m)) { +# ifdef MONT_EXP_WORD + if (a->top == 1 && !a->neg + && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(a, BN_FLG_CONSTTIME) == 0) + && (BN_get_flags(m, BN_FLG_CONSTTIME) == 0)) { + BN_ULONG A = a->d[0]; + ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL); + } else +# endif + ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL); + } else +#endif +#ifdef RECP_MUL_MOD + { + ret = BN_mod_exp_recp(r, a, p, m, ctx); + } +#else + { + ret = BN_mod_exp_simple(r, a, p, m, ctx); + } +#endif + + bn_check_top(r); + return (ret); +} + +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *aa; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + BN_RECP_CTX recp; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1, or x**0 mod -1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(r); + } else { + ret = BN_one(r); + } + return ret; + } + + BN_CTX_start(ctx); + aa = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!aa || !val[0]) + goto err; + + BN_RECP_CTX_init(&recp); + if (m->neg) { + /* ignore sign of 'm' */ + if (!BN_copy(aa, m)) + goto err; + aa->neg = 0; + if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0) + goto err; + } else { + if (BN_RECP_CTX_set(&recp, m, ctx) <= 0) + goto err; + } + + if (!BN_nnmod(val[0], a, m, ctx)) + goto err; /* 1 */ + if (BN_is_zero(val[0])) { + BN_zero(r); + ret = 1; + goto err; + } + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + + if (!BN_one(r)) + goto err; + + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) + if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) + goto err; + if (wstart == 0) + break; + wstart--; + continue; + } + /* + * We now have wstart on a 'set' bit, we now need to work out how bit + * a window to do. To do this we need to scan forward until the last + * set bit before the end of the window + */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + ret = 1; + err: + BN_CTX_end(ctx); + BN_RECP_CTX_free(&recp); + bn_check_top(r); + return (ret); +} + +int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *d, *r; + const BIGNUM *aa; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + BN_MONT_CTX *mont = NULL; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { + return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); + } + + bn_check_top(a); + bn_check_top(p); + bn_check_top(m); + + if (!BN_is_odd(m)) { + BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1, or x**0 mod -1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(rr); + } else { + ret = BN_one(rr); + } + return ret; + } + + BN_CTX_start(ctx); + d = BN_CTX_get(ctx); + r = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!d || !r || !val[0]) + goto err; + + /* + * If this is not done, things will break in the montgomery part + */ + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + if (a->neg || BN_ucmp(a, m) >= 0) { + if (!BN_nnmod(val[0], a, m, ctx)) + goto err; + aa = val[0]; + } else + aa = a; + if (BN_is_zero(aa)) { + BN_zero(rr); + ret = 1; + goto err; + } + if (!bn_to_mont_fixed_top(val[0], aa, mont, ctx)) + goto err; /* 1 */ + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!bn_mul_mont_fixed_top(d, val[0], val[0], mont, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !bn_mul_mont_fixed_top(val[i], val[i - 1], d, mont, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + +#if 1 /* by Shay Gueron's suggestion */ + j = m->top; /* borrow j */ + if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) { + if (bn_wexpand(r, j) == NULL) + goto err; + /* 2^(top*BN_BITS2) - m */ + r->d[0] = (0 - m->d[0]) & BN_MASK2; + for (i = 1; i < j; i++) + r->d[i] = (~m->d[i]) & BN_MASK2; + r->top = j; + r->flags |= BN_FLG_FIXED_TOP; + } else +#endif + if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx)) + goto err; + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) { + if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx)) + goto err; + } + if (wstart == 0) + break; + wstart--; + continue; + } + /* + * We now have wstart on a 'set' bit, we now need to work out how bit + * a window to do. To do this we need to scan forward until the last + * set bit before the end of the window + */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!bn_mul_mont_fixed_top(r, r, val[wvalue >> 1], mont, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + /* + * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery + * removes padding [if any] and makes return value suitable for public + * API consumer. + */ +#if defined(SPARC_T4_MONT) + if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) { + j = mont->N.top; /* borrow j */ + val[0]->d[0] = 1; /* borrow val[0] */ + for (i = 1; i < j; i++) + val[0]->d[i] = 0; + val[0]->top = j; + if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx)) + goto err; + } else +#endif + if (!BN_from_montgomery(rr, r, mont, ctx)) + goto err; + ret = 1; + err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + bn_check_top(rr); + return (ret); +} + +#if defined(SPARC_T4_MONT) +static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos) +{ + BN_ULONG ret = 0; + int wordpos; + + wordpos = bitpos / BN_BITS2; + bitpos %= BN_BITS2; + if (wordpos >= 0 && wordpos < a->top) { + ret = a->d[wordpos] & BN_MASK2; + if (bitpos) { + ret >>= bitpos; + if (++wordpos < a->top) + ret |= a->d[wordpos] << (BN_BITS2 - bitpos); + } + } + + return ret & BN_MASK2; +} +#endif + +/* + * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific + * layout so that accessing any of these table values shows the same access + * pattern as far as cache lines are concerned. The following functions are + * used to transfer a BIGNUM from/to that table. + */ + +static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, + unsigned char *buf, int idx, + int window) +{ + int i, j; + int width = 1 << window; + BN_ULONG *table = (BN_ULONG *)buf; + + if (top > b->top) + top = b->top; /* this works because 'buf' is explicitly + * zeroed */ + for (i = 0, j = idx; i < top; i++, j += width) { + table[j] = b->d[i]; + } + + return 1; +} + +static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, + unsigned char *buf, int idx, + int window) +{ + int i, j; + int width = 1 << window; + volatile BN_ULONG *table = (volatile BN_ULONG *)buf; + + if (bn_wexpand(b, top) == NULL) + return 0; + + if (window <= 3) { + for (i = 0; i < top; i++, table += width) { + BN_ULONG acc = 0; + + for (j = 0; j < width; j++) { + acc |= table[j] & + ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); + } + + b->d[i] = acc; + } + } else { + int xstride = 1 << (window - 2); + BN_ULONG y0, y1, y2, y3; + + i = idx >> (window - 2); /* equivalent of idx / xstride */ + idx &= xstride - 1; /* equivalent of idx % xstride */ + + y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1); + y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1); + y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1); + y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1); + + for (i = 0; i < top; i++, table += width) { + BN_ULONG acc = 0; + + for (j = 0; j < xstride; j++) { + acc |= ( (table[j + 0 * xstride] & y0) | + (table[j + 1 * xstride] & y1) | + (table[j + 2 * xstride] & y2) | + (table[j + 3 * xstride] & y3) ) + & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); + } + + b->d[i] = acc; + } + } + + b->top = top; + b->flags |= BN_FLG_FIXED_TOP; + return 1; +} + +/* + * Given a pointer value, compute the next address that is a cache line + * multiple. + */ +#define MOD_EXP_CTIME_ALIGN(x_) \ + ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK)))) + +/* + * This variant of BN_mod_exp_mont() uses fixed windows and the special + * precomputation memory layout to limit data-dependency to a minimum to + * protect secret exponents (cf. the hyper-threading timing attacks pointed + * out by Colin Percival, + * http://www.daemonology.net/hyperthreading-considered-harmful/) + */ +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont) +{ + int i, bits, ret = 0, window, wvalue; + int top; + BN_MONT_CTX *mont = NULL; + + int numPowers; + unsigned char *powerbufFree = NULL; + int powerbufLen = 0; + unsigned char *powerbuf = NULL; + BIGNUM tmp, am; +#if defined(SPARC_T4_MONT) + unsigned int t4 = 0; +#endif + + bn_check_top(a); + bn_check_top(p); + bn_check_top(m); + + if (!BN_is_odd(m)) { + BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + + top = m->top; + + /* + * Use all bits stored in |p|, rather than |BN_num_bits|, so we do not leak + * whether the top bits are zero. + */ + bits = p->top * BN_BITS2; + if (bits == 0) { + /* x**0 mod 1, or x**0 mod -1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(rr); + } else { + ret = BN_one(rr); + } + return ret; + } + + BN_CTX_start(ctx); + + /* + * Allocate a montgomery context if it was not supplied by the caller. If + * this is not done, things will break in the montgomery part. + */ + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + +#ifdef RSAZ_ENABLED + /* + * If the size of the operands allow it, perform the optimized + * RSAZ exponentiation. For further information see + * crypto/bn/rsaz_exp.c and accompanying assembly modules. + */ + if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024) + && rsaz_avx2_eligible()) { + if (NULL == bn_wexpand(rr, 16)) + goto err; + RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d, + mont->n0[0]); + rr->top = 16; + rr->neg = 0; + bn_correct_top(rr); + ret = 1; + goto err; + } else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) { + if (NULL == bn_wexpand(rr, 8)) + goto err; + RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d); + rr->top = 8; + rr->neg = 0; + bn_correct_top(rr); + ret = 1; + goto err; + } +#endif + + /* Get the window size to use with size of p. */ + window = BN_window_bits_for_ctime_exponent_size(bits); +#if defined(SPARC_T4_MONT) + if (window >= 5 && (top & 15) == 0 && top <= 64 && + (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) == + (CFR_MONTMUL | CFR_MONTSQR) && (t4 = OPENSSL_sparcv9cap_P[0])) + window = 5; + else +#endif +#if defined(OPENSSL_BN_ASM_MONT5) + if (window >= 5) { + window = 5; /* ~5% improvement for RSA2048 sign, and even + * for RSA4096 */ + /* reserve space for mont->N.d[] copy */ + powerbufLen += top * sizeof(mont->N.d[0]); + } +#endif + (void)0; + + /* + * Allocate a buffer large enough to hold all of the pre-computed powers + * of am, am itself and tmp. + */ + numPowers = 1 << window; + powerbufLen += sizeof(m->d[0]) * (top * numPowers + + ((2 * top) > + numPowers ? (2 * top) : numPowers)); +#ifdef alloca + if (powerbufLen < 3072) + powerbufFree = + alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); + else +#endif + if ((powerbufFree = + (unsigned char *)OPENSSL_malloc(powerbufLen + + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) + == NULL) + goto err; + + powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree); + memset(powerbuf, 0, powerbufLen); + +#ifdef alloca + if (powerbufLen < 3072) + powerbufFree = NULL; +#endif + + /* lay down tmp and am right after powers table */ + tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers); + am.d = tmp.d + top; + tmp.top = am.top = 0; + tmp.dmax = am.dmax = top; + tmp.neg = am.neg = 0; + tmp.flags = am.flags = BN_FLG_STATIC_DATA; + + /* prepare a^0 in Montgomery domain */ +#if 1 /* by Shay Gueron's suggestion */ + if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) { + /* 2^(top*BN_BITS2) - m */ + tmp.d[0] = (0 - m->d[0]) & BN_MASK2; + for (i = 1; i < top; i++) + tmp.d[i] = (~m->d[i]) & BN_MASK2; + tmp.top = top; + } else +#endif + if (!bn_to_mont_fixed_top(&tmp, BN_value_one(), mont, ctx)) + goto err; + + /* prepare a^1 in Montgomery domain */ + if (a->neg || BN_ucmp(a, m) >= 0) { + if (!BN_mod(&am, a, m, ctx)) + goto err; + if (!bn_to_mont_fixed_top(&am, &am, mont, ctx)) + goto err; + } else if (!bn_to_mont_fixed_top(&am, a, mont, ctx)) + goto err; + +#if defined(SPARC_T4_MONT) + if (t4) { + typedef int (*bn_pwr5_mont_f) (BN_ULONG *tp, const BN_ULONG *np, + const BN_ULONG *n0, const void *table, + int power, int bits); + int bn_pwr5_mont_t4_8(BN_ULONG *tp, const BN_ULONG *np, + const BN_ULONG *n0, const void *table, + int power, int bits); + int bn_pwr5_mont_t4_16(BN_ULONG *tp, const BN_ULONG *np, + const BN_ULONG *n0, const void *table, + int power, int bits); + int bn_pwr5_mont_t4_24(BN_ULONG *tp, const BN_ULONG *np, + const BN_ULONG *n0, const void *table, + int power, int bits); + int bn_pwr5_mont_t4_32(BN_ULONG *tp, const BN_ULONG *np, + const BN_ULONG *n0, const void *table, + int power, int bits); + static const bn_pwr5_mont_f pwr5_funcs[4] = { + bn_pwr5_mont_t4_8, bn_pwr5_mont_t4_16, + bn_pwr5_mont_t4_24, bn_pwr5_mont_t4_32 + }; + bn_pwr5_mont_f pwr5_worker = pwr5_funcs[top / 16 - 1]; + + typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap, + const void *bp, const BN_ULONG *np, + const BN_ULONG *n0); + int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, const void *bp, + const BN_ULONG *np, const BN_ULONG *n0); + int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap, + const void *bp, const BN_ULONG *np, + const BN_ULONG *n0); + int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap, + const void *bp, const BN_ULONG *np, + const BN_ULONG *n0); + int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap, + const void *bp, const BN_ULONG *np, + const BN_ULONG *n0); + static const bn_mul_mont_f mul_funcs[4] = { + bn_mul_mont_t4_8, bn_mul_mont_t4_16, + bn_mul_mont_t4_24, bn_mul_mont_t4_32 + }; + bn_mul_mont_f mul_worker = mul_funcs[top / 16 - 1]; + + void bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap, + const void *bp, const BN_ULONG *np, + const BN_ULONG *n0, int num); + void bn_mul_mont_t4(BN_ULONG *rp, const BN_ULONG *ap, + const void *bp, const BN_ULONG *np, + const BN_ULONG *n0, int num); + void bn_mul_mont_gather5_t4(BN_ULONG *rp, const BN_ULONG *ap, + const void *table, const BN_ULONG *np, + const BN_ULONG *n0, int num, int power); + void bn_flip_n_scatter5_t4(const BN_ULONG *inp, size_t num, + void *table, size_t power); + void bn_gather5_t4(BN_ULONG *out, size_t num, + void *table, size_t power); + void bn_flip_t4(BN_ULONG *dst, BN_ULONG *src, size_t num); + + BN_ULONG *np = mont->N.d, *n0 = mont->n0; + int stride = 5 * (6 - (top / 16 - 1)); /* multiple of 5, but less + * than 32 */ + + /* + * BN_to_montgomery can contaminate words above .top [in + * BN_DEBUG[_DEBUG] build]... + */ + for (i = am.top; i < top; i++) + am.d[i] = 0; + for (i = tmp.top; i < top; i++) + tmp.d[i] = 0; + + bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 0); + bn_flip_n_scatter5_t4(am.d, top, powerbuf, 1); + if (!(*mul_worker) (tmp.d, am.d, am.d, np, n0) && + !(*mul_worker) (tmp.d, am.d, am.d, np, n0)) + bn_mul_mont_vis3(tmp.d, am.d, am.d, np, n0, top); + bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 2); + + for (i = 3; i < 32; i++) { + /* Calculate a^i = a^(i-1) * a */ + if (!(*mul_worker) (tmp.d, tmp.d, am.d, np, n0) && + !(*mul_worker) (tmp.d, tmp.d, am.d, np, n0)) + bn_mul_mont_vis3(tmp.d, tmp.d, am.d, np, n0, top); + bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, i); + } + + /* switch to 64-bit domain */ + np = alloca(top * sizeof(BN_ULONG)); + top /= 2; + bn_flip_t4(np, mont->N.d, top); + + bits--; + for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + bn_gather5_t4(tmp.d, top, powerbuf, wvalue); + + /* + * Scan the exponent one window at a time starting from the most + * significant bits. + */ + while (bits >= 0) { + if (bits < stride) + stride = bits + 1; + bits -= stride; + wvalue = bn_get_bits(p, bits + 1); + + if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride)) + continue; + /* retry once and fall back */ + if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride)) + continue; + + bits += stride - 5; + wvalue >>= stride - 5; + wvalue &= 31; + bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_gather5_t4(tmp.d, tmp.d, powerbuf, np, n0, top, + wvalue); + } + + bn_flip_t4(tmp.d, tmp.d, top); + top *= 2; + /* back to 32-bit domain */ + tmp.top = top; + bn_correct_top(&tmp); + OPENSSL_cleanse(np, top * sizeof(BN_ULONG)); + } else +#endif +#if defined(OPENSSL_BN_ASM_MONT5) + if (window == 5 && top > 1) { + /* + * This optimization uses ideas from http://eprint.iacr.org/2011/239, + * specifically optimization of cache-timing attack countermeasures + * and pre-computation optimization. + */ + + /* + * Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as + * 512-bit RSA is hardly relevant, we omit it to spare size... + */ + void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, + const void *table, const BN_ULONG *np, + const BN_ULONG *n0, int num, int power); + void bn_scatter5(const BN_ULONG *inp, size_t num, + void *table, size_t power); + void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power); + void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, + const void *table, const BN_ULONG *np, + const BN_ULONG *n0, int num, int power); + int bn_get_bits5(const BN_ULONG *ap, int off); + int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *not_used, const BN_ULONG *np, + const BN_ULONG *n0, int num); + + BN_ULONG *n0 = mont->n0, *np; + + /* + * BN_to_montgomery can contaminate words above .top [in + * BN_DEBUG[_DEBUG] build]... + */ + for (i = am.top; i < top; i++) + am.d[i] = 0; + for (i = tmp.top; i < top; i++) + tmp.d[i] = 0; + + /* + * copy mont->N.d[] to improve cache locality + */ + for (np = am.d + top, i = 0; i < top; i++) + np[i] = mont->N.d[i]; + + bn_scatter5(tmp.d, top, powerbuf, 0); + bn_scatter5(am.d, am.top, powerbuf, 1); + bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2); + +# if 0 + for (i = 3; i < 32; i++) { + /* Calculate a^i = a^(i-1) * a */ + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + } +# else + /* same as above, but uses squaring for 1/2 of operations */ + for (i = 4; i < 32; i *= 2) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, i); + } + for (i = 3; i < 8; i += 2) { + int j; + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + for (j = 2 * i; j < 32; j *= 2) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, j); + } + } + for (; i < 16; i += 2) { + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2 * i); + } + for (; i < 32; i += 2) { + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + } +# endif + bits--; + for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + bn_gather5(tmp.d, top, powerbuf, wvalue); + + /* + * Scan the exponent one window at a time starting from the most + * significant bits. + */ + if (top & 7) + while (bits >= 0) { + for (wvalue = 0, i = 0; i < 5; i++, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, + wvalue); + } else { + while (bits >= 0) { + wvalue = bn_get_bits5(p->d, bits - 4); + bits -= 5; + bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); + } + } + + ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top); + tmp.top = top; + bn_correct_top(&tmp); + if (ret) { + if (!BN_copy(rr, &tmp)) + ret = 0; + goto err; /* non-zero ret means it's not error */ + } + } else +#endif + { + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window)) + goto err; + + /* + * If the window size is greater than 1, then calculate + * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) (even + * powers could instead be computed as (a^(i/2))^2 to use the slight + * performance advantage of sqr over mul). + */ + if (window > 1) { + if (!bn_mul_mont_fixed_top(&tmp, &am, &am, mont, ctx)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, + window)) + goto err; + for (i = 3; i < numPowers; i++) { + /* Calculate a^i = a^(i-1) * a */ + if (!bn_mul_mont_fixed_top(&tmp, &am, &tmp, mont, ctx)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i, + window)) + goto err; + } + } + + bits--; + for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue, + window)) + goto err; + + /* + * Scan the exponent one window at a time starting from the most + * significant bits. + */ + while (bits >= 0) { + wvalue = 0; /* The 'value' of the window */ + + /* Scan the window, squaring the result as we go */ + for (i = 0; i < window; i++, bits--) { + if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx)) + goto err; + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + + /* + * Fetch the appropriate pre-computed value from the pre-buf + */ + if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, + window)) + goto err; + + /* Multiply the result into the intermediate result */ + if (!bn_mul_mont_fixed_top(&tmp, &tmp, &am, mont, ctx)) + goto err; + } + } + + /* + * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery + * removes padding [if any] and makes return value suitable for public + * API consumer. + */ +#if defined(SPARC_T4_MONT) + if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) { + am.d[0] = 1; /* borrow am */ + for (i = 1; i < top; i++) + am.d[i] = 0; + if (!BN_mod_mul_montgomery(rr, &tmp, &am, mont, ctx)) + goto err; + } else +#endif + if (!BN_from_montgomery(rr, &tmp, mont, ctx)) + goto err; + ret = 1; + err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + if (powerbuf != NULL) { + OPENSSL_cleanse(powerbuf, powerbufLen); + if (powerbufFree) + OPENSSL_free(powerbufFree); + } + BN_CTX_end(ctx); + return (ret); +} + +int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + BN_MONT_CTX *mont = NULL; + int b, bits, ret = 0; + int r_is_one; + BN_ULONG w, next_w; + BIGNUM *d, *r, *t; + BIGNUM *swap_tmp; +#define BN_MOD_MUL_WORD(r, w, m) \ + (BN_mul_word(r, (w)) && \ + (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \ + (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1)))) + /* + * BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is + * probably more overhead than always using BN_mod (which uses BN_copy if + * a similar test returns true). + */ + /* + * We can use BN_mod and do not need BN_nnmod because our accumulator is + * never negative (the result of BN_mod does not depend on the sign of + * the modulus). + */ +#define BN_TO_MONTGOMERY_WORD(r, w, mont) \ + (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + bn_check_top(p); + bn_check_top(m); + + if (!BN_is_odd(m)) { + BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + if (m->top == 1) + a %= m->d[0]; /* make sure that 'a' is reduced */ + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1, or x**0 mod -1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(rr); + } else { + ret = BN_one(rr); + } + return ret; + } + if (a == 0) { + BN_zero(rr); + ret = 1; + return ret; + } + + BN_CTX_start(ctx); + d = BN_CTX_get(ctx); + r = BN_CTX_get(ctx); + t = BN_CTX_get(ctx); + if (d == NULL || r == NULL || t == NULL) + goto err; + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + r_is_one = 1; /* except for Montgomery factor */ + + /* bits-1 >= 0 */ + + /* The result is accumulated in the product r*w. */ + w = a; /* bit 'bits-1' of 'p' is always set */ + for (b = bits - 2; b >= 0; b--) { + /* First, square r*w. */ + next_w = w * w; + if ((next_w / w) != w) { /* overflow */ + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + next_w = 1; + } + w = next_w; + if (!r_is_one) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + + /* Second, multiply r*w by 'a' if exponent bit is set. */ + if (BN_is_bit_set(p, b)) { + next_w = w * a; + if ((next_w / a) != w) { /* overflow */ + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + next_w = a; + } + w = next_w; + } + } + + /* Finally, set r:=r*w. */ + if (w != 1) { + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + } + + if (r_is_one) { /* can happen only if a == 1 */ + if (!BN_one(rr)) + goto err; + } else { + if (!BN_from_montgomery(rr, r, mont, ctx)) + goto err; + } + ret = 1; + err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + bn_check_top(rr); + return (ret); +} + +/* The old fallback, simple version :-) */ +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *d; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 + || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1, or x**0 mod -1 is still zero. */ + if (BN_abs_is_word(m, 1)) { + ret = 1; + BN_zero(r); + } else { + ret = BN_one(r); + } + return ret; + } + + BN_CTX_start(ctx); + d = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!d || !val[0]) + goto err; + + if (!BN_nnmod(val[0], a, m, ctx)) + goto err; /* 1 */ + if (BN_is_zero(val[0])) { + BN_zero(r); + ret = 1; + goto err; + } + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul(d, val[0], val[0], m, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul(val[i], val[i - 1], d, m, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + + if (!BN_one(r)) + goto err; + + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) + if (!BN_mod_mul(r, r, r, m, ctx)) + goto err; + if (wstart == 0) + break; + wstart--; + continue; + } + /* + * We now have wstart on a 'set' bit, we now need to work out how bit + * a window to do. To do this we need to scan forward until the last + * set bit before the end of the window + */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!BN_mod_mul(r, r, r, m, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(r); + return (ret); +} +/* crypto/bn/bn_exp2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +#define TABLE_SIZE 32 + +int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + int i, j, bits, b, bits1, bits2, ret = + 0, wpos1, wpos2, window1, window2, wvalue1, wvalue2; + int r_is_one = 1; + BIGNUM *d, *r; + const BIGNUM *a_mod_m; + /* Tables of variables obtained from 'ctx' */ + BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE]; + BN_MONT_CTX *mont = NULL; + + bn_check_top(a1); + bn_check_top(p1); + bn_check_top(a2); + bn_check_top(p2); + bn_check_top(m); + + if (!(m->d[0] & 1)) { + BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + bits1 = BN_num_bits(p1); + bits2 = BN_num_bits(p2); + if ((bits1 == 0) && (bits2 == 0)) { + ret = BN_one(rr); + return ret; + } + + bits = (bits1 > bits2) ? bits1 : bits2; + + BN_CTX_start(ctx); + d = BN_CTX_get(ctx); + r = BN_CTX_get(ctx); + val1[0] = BN_CTX_get(ctx); + val2[0] = BN_CTX_get(ctx); + if (!d || !r || !val1[0] || !val2[0]) + goto err; + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + window1 = BN_window_bits_for_exponent_size(bits1); + window2 = BN_window_bits_for_exponent_size(bits2); + + /* + * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1) + */ + if (a1->neg || BN_ucmp(a1, m) >= 0) { + if (!BN_mod(val1[0], a1, m, ctx)) + goto err; + a_mod_m = val1[0]; + } else + a_mod_m = a1; + if (BN_is_zero(a_mod_m)) { + BN_zero(rr); + ret = 1; + goto err; + } + + if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx)) + goto err; + if (window1 > 1) { + if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx)) + goto err; + + j = 1 << (window1 - 1); + for (i = 1; i < j; i++) { + if (((val1[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx)) + goto err; + } + } + + /* + * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1) + */ + if (a2->neg || BN_ucmp(a2, m) >= 0) { + if (!BN_mod(val2[0], a2, m, ctx)) + goto err; + a_mod_m = val2[0]; + } else + a_mod_m = a2; + if (BN_is_zero(a_mod_m)) { + BN_zero(rr); + ret = 1; + goto err; + } + if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx)) + goto err; + if (window2 > 1) { + if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx)) + goto err; + + j = 1 << (window2 - 1); + for (i = 1; i < j; i++) { + if (((val2[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx)) + goto err; + } + } + + /* Now compute the power product, using independent windows. */ + r_is_one = 1; + wvalue1 = 0; /* The 'value' of the first window */ + wvalue2 = 0; /* The 'value' of the second window */ + wpos1 = 0; /* If wvalue1 > 0, the bottom bit of the + * first window */ + wpos2 = 0; /* If wvalue2 > 0, the bottom bit of the + * second window */ + + if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) + goto err; + for (b = bits - 1; b >= 0; b--) { + if (!r_is_one) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + + if (!wvalue1) + if (BN_is_bit_set(p1, b)) { + /* + * consider bits b-window1+1 .. b for this window + */ + i = b - window1 + 1; + while (!BN_is_bit_set(p1, i)) /* works for i<0 */ + i++; + wpos1 = i; + wvalue1 = 1; + for (i = b - 1; i >= wpos1; i--) { + wvalue1 <<= 1; + if (BN_is_bit_set(p1, i)) + wvalue1++; + } + } + + if (!wvalue2) + if (BN_is_bit_set(p2, b)) { + /* + * consider bits b-window2+1 .. b for this window + */ + i = b - window2 + 1; + while (!BN_is_bit_set(p2, i)) + i++; + wpos2 = i; + wvalue2 = 1; + for (i = b - 1; i >= wpos2; i--) { + wvalue2 <<= 1; + if (BN_is_bit_set(p2, i)) + wvalue2++; + } + } + + if (wvalue1 && b == wpos1) { + /* wvalue1 is odd and < 2^window1 */ + if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx)) + goto err; + wvalue1 = 0; + r_is_one = 0; + } + + if (wvalue2 && b == wpos2) { + /* wvalue2 is odd and < 2^window2 */ + if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx)) + goto err; + wvalue2 = 0; + r_is_one = 0; + } + } + if (!BN_from_montgomery(rr, r, mont, ctx)) + goto err; + ret = 1; + err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + bn_check_top(rr); + return (ret); +} +/* crypto/bn/bn_gcd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "bn_lcl.h" + +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); + +int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) +{ + BIGNUM *a, *b, *t; + int ret = 0; + + bn_check_top(in_a); + bn_check_top(in_b); + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + if (a == NULL || b == NULL) + goto err; + + if (BN_copy(a, in_a) == NULL) + goto err; + if (BN_copy(b, in_b) == NULL) + goto err; + a->neg = 0; + b->neg = 0; + + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + t = euclid(a, b); + if (t == NULL) + goto err; + + if (BN_copy(r, t) == NULL) + goto err; + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(r); + return (ret); +} + +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b) +{ + BIGNUM *t; + int shifts = 0; + + bn_check_top(a); + bn_check_top(b); + + /* 0 <= b <= a */ + while (!BN_is_zero(b)) { + /* 0 < b <= a */ + + if (BN_is_odd(a)) { + if (BN_is_odd(b)) { + if (!BN_sub(a, a, b)) + goto err; + if (!BN_rshift1(a, a)) + goto err; + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + } else { /* a odd - b even */ + + if (!BN_rshift1(b, b)) + goto err; + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + } + } else { /* a is even */ + + if (BN_is_odd(b)) { + if (!BN_rshift1(a, a)) + goto err; + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + } else { /* a even - b even */ + + if (!BN_rshift1(a, a)) + goto err; + if (!BN_rshift1(b, b)) + goto err; + shifts++; + } + } + /* 0 <= b <= a */ + } + + if (shifts) { + if (!BN_lshift(a, a, shifts)) + goto err; + } + bn_check_top(a); + return (a); + err: + return (NULL); +} + +/* solves ax == 1 (mod n) */ +static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx); + +BIGNUM *BN_mod_inverse(BIGNUM *in, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) +{ + BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; + BIGNUM *ret = NULL; + int sign; + + if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) + || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) { + return BN_mod_inverse_no_branch(in, a, n, ctx); + } + + bn_check_top(a); + bn_check_top(n); + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + D = BN_CTX_get(ctx); + M = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + T = BN_CTX_get(ctx); + if (T == NULL) + goto err; + + if (in == NULL) + R = BN_new(); + else + R = in; + if (R == NULL) + goto err; + + BN_one(X); + BN_zero(Y); + if (BN_copy(B, a) == NULL) + goto err; + if (BN_copy(A, n) == NULL) + goto err; + A->neg = 0; + if (B->neg || (BN_ucmp(B, A) >= 0)) { + if (!BN_nnmod(B, B, A, ctx)) + goto err; + } + sign = -1; + /*- + * From B = a mod |n|, A = |n| it follows that + * + * 0 <= B < A, + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + */ + + if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { + /* + * Binary inversion algorithm; requires odd modulus. This is faster + * than the general algorithm if the modulus is sufficiently small + * (about 400 .. 500 bits on 32-bit sytems, but much more on 64-bit + * systems) + */ + int shift; + + while (!BN_is_zero(B)) { + /*- + * 0 < B < |n|, + * 0 < A <= |n|, + * (1) -sign*X*a == B (mod |n|), + * (2) sign*Y*a == A (mod |n|) + */ + + /* + * Now divide B by the maximum possible power of two in the + * integers, and divide X by the same value mod |n|. When we're + * done, (1) still holds. + */ + shift = 0; + while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */ + shift++; + + if (BN_is_odd(X)) { + if (!BN_uadd(X, X, n)) + goto err; + } + /* + * now X is even, so we can easily divide it by two + */ + if (!BN_rshift1(X, X)) + goto err; + } + if (shift > 0) { + if (!BN_rshift(B, B, shift)) + goto err; + } + + /* + * Same for A and Y. Afterwards, (2) still holds. + */ + shift = 0; + while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */ + shift++; + + if (BN_is_odd(Y)) { + if (!BN_uadd(Y, Y, n)) + goto err; + } + /* now Y is even */ + if (!BN_rshift1(Y, Y)) + goto err; + } + if (shift > 0) { + if (!BN_rshift(A, A, shift)) + goto err; + } + + /*- + * We still have (1) and (2). + * Both A and B are odd. + * The following computations ensure that + * + * 0 <= B < |n|, + * 0 < A < |n|, + * (1) -sign*X*a == B (mod |n|), + * (2) sign*Y*a == A (mod |n|), + * + * and that either A or B is even in the next iteration. + */ + if (BN_ucmp(B, A) >= 0) { + /* -sign*(X + Y)*a == B - A (mod |n|) */ + if (!BN_uadd(X, X, Y)) + goto err; + /* + * NB: we could use BN_mod_add_quick(X, X, Y, n), but that + * actually makes the algorithm slower + */ + if (!BN_usub(B, B, A)) + goto err; + } else { + /* sign*(X + Y)*a == A - B (mod |n|) */ + if (!BN_uadd(Y, Y, X)) + goto err; + /* + * as above, BN_mod_add_quick(Y, Y, X, n) would slow things + * down + */ + if (!BN_usub(A, A, B)) + goto err; + } + } + } else { + /* general inversion algorithm */ + + while (!BN_is_zero(B)) { + BIGNUM *tmp; + + /*- + * 0 < B < A, + * (*) -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|) + */ + + /* (D, M) := (A/B, A%B) ... */ + if (BN_num_bits(A) == BN_num_bits(B)) { + if (!BN_one(D)) + goto err; + if (!BN_sub(M, A, B)) + goto err; + } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { + /* A/B is 1, 2, or 3 */ + if (!BN_lshift1(T, B)) + goto err; + if (BN_ucmp(A, T) < 0) { + /* A < 2*B, so D=1 */ + if (!BN_one(D)) + goto err; + if (!BN_sub(M, A, B)) + goto err; + } else { + /* A >= 2*B, so D=2 or D=3 */ + if (!BN_sub(M, A, T)) + goto err; + if (!BN_add(D, T, B)) + goto err; /* use D (:= 3*B) as temp */ + if (BN_ucmp(A, D) < 0) { + /* A < 3*B, so D=2 */ + if (!BN_set_word(D, 2)) + goto err; + /* + * M (= A - 2*B) already has the correct value + */ + } else { + /* only D=3 remains */ + if (!BN_set_word(D, 3)) + goto err; + /* + * currently M = A - 2*B, but we need M = A - 3*B + */ + if (!BN_sub(M, M, B)) + goto err; + } + } + } else { + if (!BN_div(D, M, A, B, ctx)) + goto err; + } + + /*- + * Now + * A = D*B + M; + * thus we have + * (**) sign*Y*a == D*B + M (mod |n|). + */ + + tmp = A; /* keep the BIGNUM object, the value does not + * matter */ + + /* (A, B) := (B, A mod B) ... */ + A = B; + B = M; + /* ... so we have 0 <= B < A again */ + + /*- + * Since the former M is now B and the former B is now A, + * (**) translates into + * sign*Y*a == D*A + B (mod |n|), + * i.e. + * sign*Y*a - D*A == B (mod |n|). + * Similarly, (*) translates into + * -sign*X*a == A (mod |n|). + * + * Thus, + * sign*Y*a + D*sign*X*a == B (mod |n|), + * i.e. + * sign*(Y + D*X)*a == B (mod |n|). + * + * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + * Note that X and Y stay non-negative all the time. + */ + + /* + * most of the time D is very small, so we can optimize tmp := + * D*X+Y + */ + if (BN_is_one(D)) { + if (!BN_add(tmp, X, Y)) + goto err; + } else { + if (BN_is_word(D, 2)) { + if (!BN_lshift1(tmp, X)) + goto err; + } else if (BN_is_word(D, 4)) { + if (!BN_lshift(tmp, X, 2)) + goto err; + } else if (D->top == 1) { + if (!BN_copy(tmp, X)) + goto err; + if (!BN_mul_word(tmp, D->d[0])) + goto err; + } else { + if (!BN_mul(tmp, D, X, ctx)) + goto err; + } + if (!BN_add(tmp, tmp, Y)) + goto err; + } + + M = Y; /* keep the BIGNUM object, the value does not + * matter */ + Y = X; + X = tmp; + sign = -sign; + } + } + + /*- + * The while loop (Euclid's algorithm) ends when + * A == gcd(a,n); + * we have + * sign*Y*a == A (mod |n|), + * where Y is non-negative. + */ + + if (sign < 0) { + if (!BN_sub(Y, n, Y)) + goto err; + } + /* Now Y*a == A (mod |n|). */ + + if (BN_is_one(A)) { + /* Y*a == 1 (mod |n|) */ + if (!Y->neg && BN_ucmp(Y, n) < 0) { + if (!BN_copy(R, Y)) + goto err; + } else { + if (!BN_nnmod(R, Y, n, ctx)) + goto err; + } + } else { + BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE); + goto err; + } + ret = R; + err: + if ((ret == NULL) && (in == NULL)) + BN_free(R); + BN_CTX_end(ctx); + bn_check_top(ret); + return (ret); +} + +/* + * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does + * not contain branches that may leak sensitive information. + */ +static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx) +{ + BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; + BIGNUM local_A, local_B; + BIGNUM *pA, *pB; + BIGNUM *ret = NULL; + int sign; + + bn_check_top(a); + bn_check_top(n); + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + D = BN_CTX_get(ctx); + M = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + T = BN_CTX_get(ctx); + if (T == NULL) + goto err; + + if (in == NULL) + R = BN_new(); + else + R = in; + if (R == NULL) + goto err; + + BN_one(X); + BN_zero(Y); + if (BN_copy(B, a) == NULL) + goto err; + if (BN_copy(A, n) == NULL) + goto err; + A->neg = 0; + + if (B->neg || (BN_ucmp(B, A) >= 0)) { + /* + * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pB = &local_B; + local_B.flags = 0; + BN_with_flags(pB, B, BN_FLG_CONSTTIME); + if (!BN_nnmod(B, pB, A, ctx)) + goto err; + } + sign = -1; + /*- + * From B = a mod |n|, A = |n| it follows that + * + * 0 <= B < A, + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + */ + + while (!BN_is_zero(B)) { + BIGNUM *tmp; + + /*- + * 0 < B < A, + * (*) -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|) + */ + + /* + * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pA = &local_A; + local_A.flags = 0; + BN_with_flags(pA, A, BN_FLG_CONSTTIME); + + /* (D, M) := (A/B, A%B) ... */ + if (!BN_div(D, M, pA, B, ctx)) + goto err; + + /*- + * Now + * A = D*B + M; + * thus we have + * (**) sign*Y*a == D*B + M (mod |n|). + */ + + tmp = A; /* keep the BIGNUM object, the value does not + * matter */ + + /* (A, B) := (B, A mod B) ... */ + A = B; + B = M; + /* ... so we have 0 <= B < A again */ + + /*- + * Since the former M is now B and the former B is now A, + * (**) translates into + * sign*Y*a == D*A + B (mod |n|), + * i.e. + * sign*Y*a - D*A == B (mod |n|). + * Similarly, (*) translates into + * -sign*X*a == A (mod |n|). + * + * Thus, + * sign*Y*a + D*sign*X*a == B (mod |n|), + * i.e. + * sign*(Y + D*X)*a == B (mod |n|). + * + * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + * Note that X and Y stay non-negative all the time. + */ + + if (!BN_mul(tmp, D, X, ctx)) + goto err; + if (!BN_add(tmp, tmp, Y)) + goto err; + + M = Y; /* keep the BIGNUM object, the value does not + * matter */ + Y = X; + X = tmp; + sign = -sign; + } + + /*- + * The while loop (Euclid's algorithm) ends when + * A == gcd(a,n); + * we have + * sign*Y*a == A (mod |n|), + * where Y is non-negative. + */ + + if (sign < 0) { + if (!BN_sub(Y, n, Y)) + goto err; + } + /* Now Y*a == A (mod |n|). */ + + if (BN_is_one(A)) { + /* Y*a == 1 (mod |n|) */ + if (!Y->neg && BN_ucmp(Y, n) < 0) { + if (!BN_copy(R, Y)) + goto err; + } else { + if (!BN_nnmod(R, Y, n, ctx)) + goto err; + } + } else { + BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE); + goto err; + } + ret = R; + err: + if ((ret == NULL) && (in == NULL)) + BN_free(R); + BN_CTX_end(ctx); + bn_check_top(ret); + return (ret); +} +/* crypto/bn/bn_gf2m.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * In addition, Sun covenants to all licensees who provide a reciprocal + * covenant with respect to their own patents if any, not to sue under + * current and future patent claims necessarily infringed by the making, + * using, practicing, selling, offering for sale and/or otherwise + * disposing of the ECC Code as delivered hereunder (or portions thereof), + * provided that such covenant shall not apply: + * 1) for code that a licensee deletes from the ECC Code; + * 2) separates from the ECC Code; or + * 3) for infringements caused by: + * i) the modification of the ECC Code or + * ii) the combination of the ECC Code with other software or + * devices where such combination causes the infringement. + * + * The software is originally written by Sheueling Chang Shantz and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +/* + * NOTE: This file is licensed pursuant to the OpenSSL license below and may + * be modified; but after modifications, the above covenant may no longer + * apply! In such cases, the corresponding paragraph ["In addition, Sun + * covenants ... causes the infringement."] and this note can be edited out; + * but please keep the Sun copyright notice and attribution. + */ + +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +#ifndef OPENSSL_NO_EC2M + +/* + * Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should + * fail. + */ +# define MAX_ITERATIONS 50 + +# define SQR_nibble(w) ((((w) & 8) << 3) \ + | (((w) & 4) << 2) \ + | (((w) & 2) << 1) \ + | ((w) & 1)) + + +/* Platform-specific macros to accelerate squaring. */ +# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) +# define SQR1(w) \ + SQR_nibble((w) >> 60) << 56 | SQR_nibble((w) >> 56) << 48 | \ + SQR_nibble((w) >> 52) << 40 | SQR_nibble((w) >> 48) << 32 | \ + SQR_nibble((w) >> 44) << 24 | SQR_nibble((w) >> 40) << 16 | \ + SQR_nibble((w) >> 36) << 8 | SQR_nibble((w) >> 32) +# define SQR0(w) \ + SQR_nibble((w) >> 28) << 56 | SQR_nibble((w) >> 24) << 48 | \ + SQR_nibble((w) >> 20) << 40 | SQR_nibble((w) >> 16) << 32 | \ + SQR_nibble((w) >> 12) << 24 | SQR_nibble((w) >> 8) << 16 | \ + SQR_nibble((w) >> 4) << 8 | SQR_nibble((w) ) +# endif +# ifdef THIRTY_TWO_BIT +# define SQR1(w) \ + SQR_nibble((w) >> 28) << 24 | SQR_nibble((w) >> 24) << 16 | \ + SQR_nibble((w) >> 20) << 8 | SQR_nibble((w) >> 16) +# define SQR0(w) \ + SQR_nibble((w) >> 12) << 24 | SQR_nibble((w) >> 8) << 16 | \ + SQR_nibble((w) >> 4) << 8 | SQR_nibble((w) ) +# endif + +# if !defined(OPENSSL_BN_ASM_GF2m) +/* + * Product of two polynomials a, b each with degree < BN_BITS2 - 1, result is + * a polynomial r with degree < 2 * BN_BITS - 1 The caller MUST ensure that + * the variables have the right amount of space allocated. + */ +# ifdef THIRTY_TWO_BIT +static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, + const BN_ULONG b) +{ + register BN_ULONG h, l, s; + BN_ULONG tab[8], top2b = a >> 30; + register BN_ULONG a1, a2, a4; + + a1 = a & (0x3FFFFFFF); + a2 = a1 << 1; + a4 = a2 << 1; + + tab[0] = 0; + tab[1] = a1; + tab[2] = a2; + tab[3] = a1 ^ a2; + tab[4] = a4; + tab[5] = a1 ^ a4; + tab[6] = a2 ^ a4; + tab[7] = a1 ^ a2 ^ a4; + + s = tab[b & 0x7]; + l = s; + s = tab[b >> 3 & 0x7]; + l ^= s << 3; + h = s >> 29; + s = tab[b >> 6 & 0x7]; + l ^= s << 6; + h ^= s >> 26; + s = tab[b >> 9 & 0x7]; + l ^= s << 9; + h ^= s >> 23; + s = tab[b >> 12 & 0x7]; + l ^= s << 12; + h ^= s >> 20; + s = tab[b >> 15 & 0x7]; + l ^= s << 15; + h ^= s >> 17; + s = tab[b >> 18 & 0x7]; + l ^= s << 18; + h ^= s >> 14; + s = tab[b >> 21 & 0x7]; + l ^= s << 21; + h ^= s >> 11; + s = tab[b >> 24 & 0x7]; + l ^= s << 24; + h ^= s >> 8; + s = tab[b >> 27 & 0x7]; + l ^= s << 27; + h ^= s >> 5; + s = tab[b >> 30]; + l ^= s << 30; + h ^= s >> 2; + + /* compensate for the top two bits of a */ + + if (top2b & 01) { + l ^= b << 30; + h ^= b >> 2; + } + if (top2b & 02) { + l ^= b << 31; + h ^= b >> 1; + } + + *r1 = h; + *r0 = l; +} +# endif +# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) +static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, + const BN_ULONG b) +{ + register BN_ULONG h, l, s; + BN_ULONG tab[16], top3b = a >> 61; + register BN_ULONG a1, a2, a4, a8; + + a1 = a & (0x1FFFFFFFFFFFFFFFULL); + a2 = a1 << 1; + a4 = a2 << 1; + a8 = a4 << 1; + + tab[0] = 0; + tab[1] = a1; + tab[2] = a2; + tab[3] = a1 ^ a2; + tab[4] = a4; + tab[5] = a1 ^ a4; + tab[6] = a2 ^ a4; + tab[7] = a1 ^ a2 ^ a4; + tab[8] = a8; + tab[9] = a1 ^ a8; + tab[10] = a2 ^ a8; + tab[11] = a1 ^ a2 ^ a8; + tab[12] = a4 ^ a8; + tab[13] = a1 ^ a4 ^ a8; + tab[14] = a2 ^ a4 ^ a8; + tab[15] = a1 ^ a2 ^ a4 ^ a8; + + s = tab[b & 0xF]; + l = s; + s = tab[b >> 4 & 0xF]; + l ^= s << 4; + h = s >> 60; + s = tab[b >> 8 & 0xF]; + l ^= s << 8; + h ^= s >> 56; + s = tab[b >> 12 & 0xF]; + l ^= s << 12; + h ^= s >> 52; + s = tab[b >> 16 & 0xF]; + l ^= s << 16; + h ^= s >> 48; + s = tab[b >> 20 & 0xF]; + l ^= s << 20; + h ^= s >> 44; + s = tab[b >> 24 & 0xF]; + l ^= s << 24; + h ^= s >> 40; + s = tab[b >> 28 & 0xF]; + l ^= s << 28; + h ^= s >> 36; + s = tab[b >> 32 & 0xF]; + l ^= s << 32; + h ^= s >> 32; + s = tab[b >> 36 & 0xF]; + l ^= s << 36; + h ^= s >> 28; + s = tab[b >> 40 & 0xF]; + l ^= s << 40; + h ^= s >> 24; + s = tab[b >> 44 & 0xF]; + l ^= s << 44; + h ^= s >> 20; + s = tab[b >> 48 & 0xF]; + l ^= s << 48; + h ^= s >> 16; + s = tab[b >> 52 & 0xF]; + l ^= s << 52; + h ^= s >> 12; + s = tab[b >> 56 & 0xF]; + l ^= s << 56; + h ^= s >> 8; + s = tab[b >> 60]; + l ^= s << 60; + h ^= s >> 4; + + /* compensate for the top three bits of a */ + + if (top3b & 01) { + l ^= b << 61; + h ^= b >> 3; + } + if (top3b & 02) { + l ^= b << 62; + h ^= b >> 2; + } + if (top3b & 04) { + l ^= b << 63; + h ^= b >> 1; + } + + *r1 = h; + *r0 = l; +} +# endif + +/* + * Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1, + * result is a polynomial r with degree < 4 * BN_BITS2 - 1 The caller MUST + * ensure that the variables have the right amount of space allocated. + */ +static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, + const BN_ULONG b1, const BN_ULONG b0) +{ + BN_ULONG m1, m0; + /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */ + bn_GF2m_mul_1x1(r + 3, r + 2, a1, b1); + bn_GF2m_mul_1x1(r + 1, r, a0, b0); + bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1); + /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */ + r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ + r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ +} +# else +void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, + BN_ULONG b0); +# endif + +/* + * Add polynomials a and b and store result in r; r could be a or b, a and b + * could be equal; r is the bitwise XOR of a and b. + */ +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int i; + const BIGNUM *at, *bt; + + bn_check_top(a); + bn_check_top(b); + + if (a->top < b->top) { + at = b; + bt = a; + } else { + at = a; + bt = b; + } + + if (bn_wexpand(r, at->top) == NULL) + return 0; + + for (i = 0; i < bt->top; i++) { + r->d[i] = at->d[i] ^ bt->d[i]; + } + for (; i < at->top; i++) { + r->d[i] = at->d[i]; + } + + r->top = at->top; + bn_correct_top(r); + + return 1; +} + +/*- + * Some functions allow for representation of the irreducible polynomials + * as an int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ + +/* Performs modular reduction of a and store result in r. r could be a. */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]) +{ + int j, k; + int n, dN, d0, d1; + BN_ULONG zz, *z; + + bn_check_top(a); + + if (!p[0]) { + /* reduction mod 1 => return 0 */ + BN_zero(r); + return 1; + } + + /* + * Since the algorithm does reduction in the r value, if a != r, copy the + * contents of a into r so we can do reduction in r. + */ + if (a != r) { + if (!bn_wexpand(r, a->top)) + return 0; + for (j = 0; j < a->top; j++) { + r->d[j] = a->d[j]; + } + r->top = a->top; + } + z = r->d; + + /* start reduction */ + dN = p[0] / BN_BITS2; + for (j = r->top - 1; j > dN;) { + zz = z[j]; + if (z[j] == 0) { + j--; + continue; + } + z[j] = 0; + + for (k = 1; p[k] != 0; k++) { + /* reducing component t^p[k] */ + n = p[0] - p[k]; + d0 = n % BN_BITS2; + d1 = BN_BITS2 - d0; + n /= BN_BITS2; + z[j - n] ^= (zz >> d0); + if (d0) + z[j - n - 1] ^= (zz << d1); + } + + /* reducing component t^0 */ + n = dN; + d0 = p[0] % BN_BITS2; + d1 = BN_BITS2 - d0; + z[j - n] ^= (zz >> d0); + if (d0) + z[j - n - 1] ^= (zz << d1); + } + + /* final round of reduction */ + while (j == dN) { + + d0 = p[0] % BN_BITS2; + zz = z[dN] >> d0; + if (zz == 0) + break; + d1 = BN_BITS2 - d0; + + /* clear up the top d1 bits */ + if (d0) + z[dN] = (z[dN] << d1) >> d1; + else + z[dN] = 0; + z[0] ^= zz; /* reduction t^0 component */ + + for (k = 1; p[k] != 0; k++) { + BN_ULONG tmp_ulong; + + /* reducing component t^p[k] */ + n = p[k] / BN_BITS2; + d0 = p[k] % BN_BITS2; + d1 = BN_BITS2 - d0; + z[n] ^= (zz << d0); + if (d0 && (tmp_ulong = zz >> d1)) + z[n + 1] ^= tmp_ulong; + } + + } + + bn_correct_top(r); + return 1; +} + +/* + * Performs modular reduction of a by p and store result in r. r could be a. + * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper + * function is only provided for convenience; for best performance, use the + * BN_GF2m_mod_arr function. + */ +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) +{ + int ret = 0; + int arr[6]; + bn_check_top(a); + bn_check_top(p); + ret = BN_GF2m_poly2arr(p, arr, sizeof(arr) / sizeof(arr[0])); + if (!ret || ret > (int)(sizeof(arr) / sizeof(arr[0]))) { + BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH); + return 0; + } + ret = BN_GF2m_mod_arr(r, a, arr); + bn_check_top(r); + return ret; +} + +/* + * Compute the product of two polynomials a and b, reduce modulo p, and store + * the result in r. r could be a or b; a could be b. + */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx) +{ + int zlen, i, j, k, ret = 0; + BIGNUM *s; + BN_ULONG x1, x0, y1, y0, zz[4]; + + bn_check_top(a); + bn_check_top(b); + + if (a == b) { + return BN_GF2m_mod_sqr_arr(r, a, p, ctx); + } + + BN_CTX_start(ctx); + if ((s = BN_CTX_get(ctx)) == NULL) + goto err; + + zlen = a->top + b->top + 4; + if (!bn_wexpand(s, zlen)) + goto err; + s->top = zlen; + + for (i = 0; i < zlen; i++) + s->d[i] = 0; + + for (j = 0; j < b->top; j += 2) { + y0 = b->d[j]; + y1 = ((j + 1) == b->top) ? 0 : b->d[j + 1]; + for (i = 0; i < a->top; i += 2) { + x0 = a->d[i]; + x1 = ((i + 1) == a->top) ? 0 : a->d[i + 1]; + bn_GF2m_mul_2x2(zz, x1, x0, y1, y0); + for (k = 0; k < 4; k++) + s->d[i + j + k] ^= zz[k]; + } + } + + bn_correct_top(s); + if (BN_GF2m_mod_arr(r, s, p)) + ret = 1; + bn_check_top(r); + + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Compute the product of two polynomials a and b, reduce modulo p, and store + * the result in r. r could be a or b; a could equal b. This function calls + * down to the BN_GF2m_mod_mul_arr implementation; this wrapper function is + * only provided for convenience; for best performance, use the + * BN_GF2m_mod_mul_arr function. + */ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + bn_check_top(a); + bn_check_top(b); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* Square a, reduce the result mod p, and store it in a. r could be a. */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *s; + + bn_check_top(a); + BN_CTX_start(ctx); + if ((s = BN_CTX_get(ctx)) == NULL) + goto err; + if (!bn_wexpand(s, 2 * a->top)) + goto err; + + for (i = a->top - 1; i >= 0; i--) { + s->d[2 * i + 1] = SQR1(a->d[i]); + s->d[2 * i] = SQR0(a->d[i]); + } + + s->top = 2 * a->top; + bn_correct_top(s); + if (!BN_GF2m_mod_arr(r, s, p)) + goto err; + bn_check_top(r); + ret = 1; + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Square a, reduce the result mod p, and store it in a. r could be a. This + * function calls down to the BN_GF2m_mod_sqr_arr implementation; this + * wrapper function is only provided for convenience; for best performance, + * use the BN_GF2m_mod_sqr_arr function. + */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + + bn_check_top(a); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* + * Invert a, reduce modulo p, and store the result in r. r could be a. Uses + * Modified Almost Inverse Algorithm (Algorithm 10) from Hankerson, D., + * Hernandez, J.L., and Menezes, A. "Software Implementation of Elliptic + * Curve Cryptography Over Binary Fields". + */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp; + int ret = 0; + + bn_check_top(a); + bn_check_top(p); + + BN_CTX_start(ctx); + + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((u = BN_CTX_get(ctx)) == NULL) + goto err; + if ((v = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_GF2m_mod(u, a, p)) + goto err; + if (BN_is_zero(u)) + goto err; + + if (!BN_copy(v, p)) + goto err; +# if 0 + if (!BN_one(b)) + goto err; + + while (1) { + while (!BN_is_odd(u)) { + if (BN_is_zero(u)) + goto err; + if (!BN_rshift1(u, u)) + goto err; + if (BN_is_odd(b)) { + if (!BN_GF2m_add(b, b, p)) + goto err; + } + if (!BN_rshift1(b, b)) + goto err; + } + + if (BN_abs_is_word(u, 1)) + break; + + if (BN_num_bits(u) < BN_num_bits(v)) { + tmp = u; + u = v; + v = tmp; + tmp = b; + b = c; + c = tmp; + } + + if (!BN_GF2m_add(u, u, v)) + goto err; + if (!BN_GF2m_add(b, b, c)) + goto err; + } +# else + { + int i; + int ubits = BN_num_bits(u); + int vbits = BN_num_bits(v); /* v is copy of p */ + int top = p->top; + BN_ULONG *udp, *bdp, *vdp, *cdp; + + if (!bn_wexpand(u, top)) + goto err; + udp = u->d; + for (i = u->top; i < top; i++) + udp[i] = 0; + u->top = top; + if (!bn_wexpand(b, top)) + goto err; + bdp = b->d; + bdp[0] = 1; + for (i = 1; i < top; i++) + bdp[i] = 0; + b->top = top; + if (!bn_wexpand(c, top)) + goto err; + cdp = c->d; + for (i = 0; i < top; i++) + cdp[i] = 0; + c->top = top; + vdp = v->d; /* It pays off to "cache" *->d pointers, + * because it allows optimizer to be more + * aggressive. But we don't have to "cache" + * p->d, because *p is declared 'const'... */ + while (1) { + while (ubits && !(udp[0] & 1)) { + BN_ULONG u0, u1, b0, b1, mask; + + u0 = udp[0]; + b0 = bdp[0]; + mask = (BN_ULONG)0 - (b0 & 1); + b0 ^= p->d[0] & mask; + for (i = 0; i < top - 1; i++) { + u1 = udp[i + 1]; + udp[i] = ((u0 >> 1) | (u1 << (BN_BITS2 - 1))) & BN_MASK2; + u0 = u1; + b1 = bdp[i + 1] ^ (p->d[i + 1] & mask); + bdp[i] = ((b0 >> 1) | (b1 << (BN_BITS2 - 1))) & BN_MASK2; + b0 = b1; + } + udp[i] = u0 >> 1; + bdp[i] = b0 >> 1; + ubits--; + } + + if (ubits <= BN_BITS2) { + if (udp[0] == 0) /* poly was reducible */ + goto err; + if (udp[0] == 1) + break; + } + + if (ubits < vbits) { + i = ubits; + ubits = vbits; + vbits = i; + tmp = u; + u = v; + v = tmp; + tmp = b; + b = c; + c = tmp; + udp = vdp; + vdp = v->d; + bdp = cdp; + cdp = c->d; + } + for (i = 0; i < top; i++) { + udp[i] ^= vdp[i]; + bdp[i] ^= cdp[i]; + } + if (ubits == vbits) { + BN_ULONG ul; + int utop = (ubits - 1) / BN_BITS2; + + while ((ul = udp[utop]) == 0 && utop) + utop--; + ubits = utop * BN_BITS2 + BN_num_bits_word(ul); + } + } + bn_correct_top(b); + } +# endif + + if (!BN_copy(r, b)) + goto err; + bn_check_top(r); + ret = 1; + + err: +# ifdef BN_DEBUG /* BN_CTX_end would complain about the + * expanded form */ + bn_correct_top(c); + bn_correct_top(u); + bn_correct_top(v); +# endif + BN_CTX_end(ctx); + return ret; +} + +/* + * Invert xx, reduce modulo p, and store the result in r. r could be xx. + * This function calls down to the BN_GF2m_mod_inv implementation; this + * wrapper function is only provided for convenience; for best performance, + * use the BN_GF2m_mod_inv function. + */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], + BN_CTX *ctx) +{ + BIGNUM *field; + int ret = 0; + + bn_check_top(xx); + BN_CTX_start(ctx); + if ((field = BN_CTX_get(ctx)) == NULL) + goto err; + if (!BN_GF2m_arr2poly(p, field)) + goto err; + + ret = BN_GF2m_mod_inv(r, xx, field, ctx); + bn_check_top(r); + + err: + BN_CTX_end(ctx); + return ret; +} + +# ifndef OPENSSL_SUN_GF2M_DIV +/* + * Divide y by x, reduce modulo p, and store the result in r. r could be x + * or y, x could equal y. + */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, + const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *xinv = NULL; + int ret = 0; + + bn_check_top(y); + bn_check_top(x); + bn_check_top(p); + + BN_CTX_start(ctx); + xinv = BN_CTX_get(ctx); + if (xinv == NULL) + goto err; + + if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) + goto err; + if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) + goto err; + bn_check_top(r); + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} +# else +/* + * Divide y by x, reduce modulo p, and store the result in r. r could be x + * or y, x could equal y. Uses algorithm Modular_Division_GF(2^m) from + * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to the + * Great Divide". + */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, + const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *a, *b, *u, *v; + int ret = 0; + + bn_check_top(y); + bn_check_top(x); + bn_check_top(p); + + BN_CTX_start(ctx); + + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + u = BN_CTX_get(ctx); + v = BN_CTX_get(ctx); + if (v == NULL) + goto err; + + /* reduce x and y mod p */ + if (!BN_GF2m_mod(u, y, p)) + goto err; + if (!BN_GF2m_mod(a, x, p)) + goto err; + if (!BN_copy(b, p)) + goto err; + + while (!BN_is_odd(a)) { + if (!BN_rshift1(a, a)) + goto err; + if (BN_is_odd(u)) + if (!BN_GF2m_add(u, u, p)) + goto err; + if (!BN_rshift1(u, u)) + goto err; + } + + do { + if (BN_GF2m_cmp(b, a) > 0) { + if (!BN_GF2m_add(b, b, a)) + goto err; + if (!BN_GF2m_add(v, v, u)) + goto err; + do { + if (!BN_rshift1(b, b)) + goto err; + if (BN_is_odd(v)) + if (!BN_GF2m_add(v, v, p)) + goto err; + if (!BN_rshift1(v, v)) + goto err; + } while (!BN_is_odd(b)); + } else if (BN_abs_is_word(a, 1)) + break; + else { + if (!BN_GF2m_add(a, a, b)) + goto err; + if (!BN_GF2m_add(u, u, v)) + goto err; + do { + if (!BN_rshift1(a, a)) + goto err; + if (BN_is_odd(u)) + if (!BN_GF2m_add(u, u, p)) + goto err; + if (!BN_rshift1(u, u)) + goto err; + } while (!BN_is_odd(a)); + } + } while (1); + + if (!BN_copy(r, u)) + goto err; + bn_check_top(r); + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} +# endif + +/* + * Divide yy by xx, reduce modulo p, and store the result in r. r could be xx + * * or yy, xx could equal yy. This function calls down to the + * BN_GF2m_mod_div implementation; this wrapper function is only provided for + * convenience; for best performance, use the BN_GF2m_mod_div function. + */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, + const int p[], BN_CTX *ctx) +{ + BIGNUM *field; + int ret = 0; + + bn_check_top(yy); + bn_check_top(xx); + + BN_CTX_start(ctx); + if ((field = BN_CTX_get(ctx)) == NULL) + goto err; + if (!BN_GF2m_arr2poly(p, field)) + goto err; + + ret = BN_GF2m_mod_div(r, yy, xx, field, ctx); + bn_check_top(r); + + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Compute the bth power of a, reduce modulo p, and store the result in r. r + * could be a. Uses simple square-and-multiply algorithm A.5.1 from IEEE + * P1363. + */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx) +{ + int ret = 0, i, n; + BIGNUM *u; + + bn_check_top(a); + bn_check_top(b); + + if (BN_is_zero(b)) + return (BN_one(r)); + + if (BN_abs_is_word(b, 1)) + return (BN_copy(r, a) != NULL); + + BN_CTX_start(ctx); + if ((u = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_GF2m_mod_arr(u, a, p)) + goto err; + + n = BN_num_bits(b) - 1; + for (i = n - 1; i >= 0; i--) { + if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx)) + goto err; + if (BN_is_bit_set(b, i)) { + if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx)) + goto err; + } + } + if (!BN_copy(r, u)) + goto err; + bn_check_top(r); + ret = 1; + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Compute the bth power of a, reduce modulo p, and store the result in r. r + * could be a. This function calls down to the BN_GF2m_mod_exp_arr + * implementation; this wrapper function is only provided for convenience; + * for best performance, use the BN_GF2m_mod_exp_arr function. + */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + bn_check_top(a); + bn_check_top(b); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* + * Compute the square root of a, reduce modulo p, and store the result in r. + * r could be a. Uses exponentiation as in algorithm A.4.1 from IEEE P1363. + */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *u; + + bn_check_top(a); + + if (!p[0]) { + /* reduction mod 1 => return 0 */ + BN_zero(r); + return 1; + } + + BN_CTX_start(ctx); + if ((u = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_set_bit(u, p[0] - 1)) + goto err; + ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx); + bn_check_top(r); + + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Compute the square root of a, reduce modulo p, and store the result in r. + * r could be a. This function calls down to the BN_GF2m_mod_sqrt_arr + * implementation; this wrapper function is only provided for convenience; + * for best performance, use the BN_GF2m_mod_sqrt_arr function. + */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + bn_check_top(a); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* + * Find r such that r^2 + r = a mod p. r could be a. If no r exists returns + * 0. Uses algorithms A.4.7 and A.4.6 from IEEE P1363. + */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], + BN_CTX *ctx) +{ + int ret = 0, count = 0, j; + BIGNUM *a, *z, *rho, *w, *w2, *tmp; + + bn_check_top(a_); + + if (!p[0]) { + /* reduction mod 1 => return 0 */ + BN_zero(r); + return 1; + } + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + z = BN_CTX_get(ctx); + w = BN_CTX_get(ctx); + if (w == NULL) + goto err; + + if (!BN_GF2m_mod_arr(a, a_, p)) + goto err; + + if (BN_is_zero(a)) { + BN_zero(r); + ret = 1; + goto err; + } + + if (p[0] & 0x1) { /* m is odd */ + /* compute half-trace of a */ + if (!BN_copy(z, a)) + goto err; + for (j = 1; j <= (p[0] - 1) / 2; j++) { + if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) + goto err; + if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) + goto err; + if (!BN_GF2m_add(z, z, a)) + goto err; + } + + } else { /* m is even */ + + rho = BN_CTX_get(ctx); + w2 = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + do { + if (!BN_rand(rho, p[0], 0, 0)) + goto err; + if (!BN_GF2m_mod_arr(rho, rho, p)) + goto err; + BN_zero(z); + if (!BN_copy(w, rho)) + goto err; + for (j = 1; j <= p[0] - 1; j++) { + if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) + goto err; + if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx)) + goto err; + if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx)) + goto err; + if (!BN_GF2m_add(z, z, tmp)) + goto err; + if (!BN_GF2m_add(w, w2, rho)) + goto err; + } + count++; + } while (BN_is_zero(w) && (count < MAX_ITERATIONS)); + if (BN_is_zero(w)) { + BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_TOO_MANY_ITERATIONS); + goto err; + } + } + + if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) + goto err; + if (!BN_GF2m_add(w, z, w)) + goto err; + if (BN_GF2m_cmp(w, a)) { + BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION); + goto err; + } + + if (!BN_copy(r, z)) + goto err; + bn_check_top(r); + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Find r such that r^2 + r = a mod p. r could be a. If no r exists returns + * 0. This function calls down to the BN_GF2m_mod_solve_quad_arr + * implementation; this wrapper function is only provided for convenience; + * for best performance, use the BN_GF2m_mod_solve_quad_arr function. + */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + bn_check_top(a); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* + * Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i * + * x^i) into an array of integers corresponding to the bits with non-zero + * coefficient. Array is terminated with -1. Up to max elements of the array + * will be filled. Return value is total number of array elements that would + * be filled if array was large enough. + */ +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max) +{ + int i, j, k = 0; + BN_ULONG mask; + + if (BN_is_zero(a)) + return 0; + + for (i = a->top - 1; i >= 0; i--) { + if (!a->d[i]) + /* skip word if a->d[i] == 0 */ + continue; + mask = BN_TBIT; + for (j = BN_BITS2 - 1; j >= 0; j--) { + if (a->d[i] & mask) { + if (k < max) + p[k] = BN_BITS2 * i + j; + k++; + } + mask >>= 1; + } + } + + if (k < max) { + p[k] = -1; + k++; + } + + return k; +} + +/* + * Convert the coefficient array representation of a polynomial to a + * bit-string. The array must be terminated by -1. + */ +int BN_GF2m_arr2poly(const int p[], BIGNUM *a) +{ + int i; + + bn_check_top(a); + BN_zero(a); + for (i = 0; p[i] != -1; i++) { + if (BN_set_bit(a, p[i]) == 0) + return 0; + } + bn_check_top(a); + + return 1; +} + +#endif +/* crypto/bn/bn_kron.c */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "bn_lcl.h" + +/* least significant word */ +#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0]) + +/* Returns -2 for errors because both -1 and 0 are valid results. */ +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + int i; + int ret = -2; /* avoid 'uninitialized' warning */ + int err = 0; + BIGNUM *A, *B, *tmp; + /*- + * In 'tab', only odd-indexed entries are relevant: + * For any odd BIGNUM n, + * tab[BN_lsw(n) & 7] + * is $(-1)^{(n^2-1)/8}$ (using TeX notation). + * Note that the sign of n does not matter. + */ + static const int tab[8] = { 0, 1, 0, -1, 0, -1, 0, 1 }; + + bn_check_top(a); + bn_check_top(b); + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + if (B == NULL) + goto end; + + err = !BN_copy(A, a); + if (err) + goto end; + err = !BN_copy(B, b); + if (err) + goto end; + + /* + * Kronecker symbol, imlemented according to Henri Cohen, + * "A Course in Computational Algebraic Number Theory" + * (algorithm 1.4.10). + */ + + /* Cohen's step 1: */ + + if (BN_is_zero(B)) { + ret = BN_abs_is_word(A, 1); + goto end; + } + + /* Cohen's step 2: */ + + if (!BN_is_odd(A) && !BN_is_odd(B)) { + ret = 0; + goto end; + } + + /* now B is non-zero */ + i = 0; + while (!BN_is_bit_set(B, i)) + i++; + err = !BN_rshift(B, B, i); + if (err) + goto end; + if (i & 1) { + /* i is odd */ + /* (thus B was even, thus A must be odd!) */ + + /* set 'ret' to $(-1)^{(A^2-1)/8}$ */ + ret = tab[BN_lsw(A) & 7]; + } else { + /* i is even */ + ret = 1; + } + + if (B->neg) { + B->neg = 0; + if (A->neg) + ret = -ret; + } + + /* + * now B is positive and odd, so what remains to be done is to compute + * the Jacobi symbol (A/B) and multiply it by 'ret' + */ + + while (1) { + /* Cohen's step 3: */ + + /* B is positive and odd */ + + if (BN_is_zero(A)) { + ret = BN_is_one(B) ? ret : 0; + goto end; + } + + /* now A is non-zero */ + i = 0; + while (!BN_is_bit_set(A, i)) + i++; + err = !BN_rshift(A, A, i); + if (err) + goto end; + if (i & 1) { + /* i is odd */ + /* multiply 'ret' by $(-1)^{(B^2-1)/8}$ */ + ret = ret * tab[BN_lsw(B) & 7]; + } + + /* Cohen's step 4: */ + /* multiply 'ret' by $(-1)^{(A-1)(B-1)/4}$ */ + if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2) + ret = -ret; + + /* (A, B) := (B mod |A|, |A|) */ + err = !BN_nnmod(B, B, A, ctx); + if (err) + goto end; + tmp = A; + A = B; + B = tmp; + tmp->neg = 0; + } + end: + BN_CTX_end(ctx); + if (err) + return -2; + else + return ret; +} +/* crypto/bn/bn_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef BN_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT; + +/* This stuff appears to be completely unused, so is deprecated */ +#ifndef OPENSSL_NO_DEPRECATED +/*- + * For a 32 bit machine + * 2 - 4 == 128 + * 3 - 8 == 256 + * 4 - 16 == 512 + * 5 - 32 == 1024 + * 6 - 64 == 2048 + * 7 - 128 == 4096 + * 8 - 256 == 8192 + */ +static int bn_limit_bits = 0; +static int bn_limit_num = 8; /* (1<= 0) { + if (mult > (int)(sizeof(int) * 8) - 1) + mult = sizeof(int) * 8 - 1; + bn_limit_bits = mult; + bn_limit_num = 1 << mult; + } + if (high >= 0) { + if (high > (int)(sizeof(int) * 8) - 1) + high = sizeof(int) * 8 - 1; + bn_limit_bits_high = high; + bn_limit_num_high = 1 << high; + } + if (low >= 0) { + if (low > (int)(sizeof(int) * 8) - 1) + low = sizeof(int) * 8 - 1; + bn_limit_bits_low = low; + bn_limit_num_low = 1 << low; + } + if (mont >= 0) { + if (mont > (int)(sizeof(int) * 8) - 1) + mont = sizeof(int) * 8 - 1; + bn_limit_bits_mont = mont; + bn_limit_num_mont = 1 << mont; + } +} + +int BN_get_params(int which) +{ + if (which == 0) + return (bn_limit_bits); + else if (which == 1) + return (bn_limit_bits_high); + else if (which == 2) + return (bn_limit_bits_low); + else if (which == 3) + return (bn_limit_bits_mont); + else + return (0); +} +#endif + +const BIGNUM *BN_value_one(void) +{ + static const BN_ULONG data_one = 1L; + static const BIGNUM const_one = + { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA }; + + return (&const_one); +} + +int BN_num_bits_word(BN_ULONG l) +{ + BN_ULONG x, mask; + int bits = (l != 0); + +#if BN_BITS2 > 32 + x = l >> 32; + mask = (0 - x) & BN_MASK2; + mask = (0 - (mask >> (BN_BITS2 - 1))); + bits += 32 & mask; + l ^= (x ^ l) & mask; +#endif + + x = l >> 16; + mask = (0 - x) & BN_MASK2; + mask = (0 - (mask >> (BN_BITS2 - 1))); + bits += 16 & mask; + l ^= (x ^ l) & mask; + + x = l >> 8; + mask = (0 - x) & BN_MASK2; + mask = (0 - (mask >> (BN_BITS2 - 1))); + bits += 8 & mask; + l ^= (x ^ l) & mask; + + x = l >> 4; + mask = (0 - x) & BN_MASK2; + mask = (0 - (mask >> (BN_BITS2 - 1))); + bits += 4 & mask; + l ^= (x ^ l) & mask; + + x = l >> 2; + mask = (0 - x) & BN_MASK2; + mask = (0 - (mask >> (BN_BITS2 - 1))); + bits += 2 & mask; + l ^= (x ^ l) & mask; + + x = l >> 1; + mask = (0 - x) & BN_MASK2; + mask = (0 - (mask >> (BN_BITS2 - 1))); + bits += 1 & mask; + + return bits; +} + +int BN_num_bits(const BIGNUM *a) +{ + int i = a->top - 1; + bn_check_top(a); + + if (BN_is_zero(a)) + return 0; + return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); +} + +void BN_clear_free(BIGNUM *a) +{ + int i; + + if (a == NULL) + return; + bn_check_top(a); + if (a->d != NULL) { + OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0])); + if (!(BN_get_flags(a, BN_FLG_STATIC_DATA))) + OPENSSL_free(a->d); + } + i = BN_get_flags(a, BN_FLG_MALLOCED); + OPENSSL_cleanse(a, sizeof(BIGNUM)); + if (i) + OPENSSL_free(a); +} + +void BN_free(BIGNUM *a) +{ + if (a == NULL) + return; + bn_check_top(a); + if ((a->d != NULL) && !(BN_get_flags(a, BN_FLG_STATIC_DATA))) + OPENSSL_free(a->d); + if (a->flags & BN_FLG_MALLOCED) + OPENSSL_free(a); + else { +#ifndef OPENSSL_NO_DEPRECATED + a->flags |= BN_FLG_FREE; +#endif + a->d = NULL; + } +} + +void BN_init(BIGNUM *a) +{ + memset(a, 0, sizeof(BIGNUM)); + bn_check_top(a); +} + +BIGNUM *BN_new(void) +{ + BIGNUM *ret; + + if ((ret = (BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL) { + BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->flags = BN_FLG_MALLOCED; + ret->top = 0; + ret->neg = 0; + ret->dmax = 0; + ret->d = NULL; + bn_check_top(ret); + return (ret); +} + +/* This is used both by bn_expand2() and bn_dup_expand() */ +/* The caller MUST check that words > b->dmax before calling this */ +static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) +{ + BN_ULONG *A, *a = NULL; + const BN_ULONG *B; + int i; + + if (words > (INT_MAX / (4 * BN_BITS2))) { + BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG); + return NULL; + } + if (BN_get_flags(b, BN_FLG_STATIC_DATA)) { + BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); + return (NULL); + } + a = A = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words); + if (A == NULL) { + BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE); + return (NULL); + } +#ifdef PURIFY + /* + * Valgrind complains in BN_consttime_swap because we process the whole + * array even if it's not initialised yet. This doesn't matter in that + * function - what's important is constant time operation (we're not + * actually going to use the data) + */ + memset(a, 0, sizeof(BN_ULONG) * words); +#endif + +#if 1 + B = b->d; + /* Check if the previous number needs to be copied */ + if (B != NULL) { + for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { + /* + * The fact that the loop is unrolled + * 4-wise is a tribute to Intel. It's + * the one that doesn't have enough + * registers to accomodate more data. + * I'd unroll it 8-wise otherwise:-) + * + * + */ + BN_ULONG a0, a1, a2, a3; + a0 = B[0]; + a1 = B[1]; + a2 = B[2]; + a3 = B[3]; + A[0] = a0; + A[1] = a1; + A[2] = a2; + A[3] = a3; + } + /* + * workaround for ultrix cc: without 'case 0', the optimizer does + * the switch table by doing a=top&3; a--; goto jump_table[a]; + * which fails for top== 0 + */ + switch (b->top & 3) { + case 3: + A[2] = B[2]; + case 2: + A[1] = B[1]; + case 1: + A[0] = B[0]; + case 0: + ; + } + } +#else + memset(A, 0, sizeof(BN_ULONG) * words); + memcpy(A, b->d, sizeof(b->d[0]) * b->top); +#endif + + return (a); +} + +/* + * This is an internal function that can be used instead of bn_expand2() when + * there is a need to copy BIGNUMs instead of only expanding the data part, + * while still expanding them. Especially useful when needing to expand + * BIGNUMs that are declared 'const' and should therefore not be changed. The + * reason to use this instead of a BN_dup() followed by a bn_expand2() is + * memory allocation overhead. A BN_dup() followed by a bn_expand2() will + * allocate new memory for the BIGNUM data twice, and free it once, while + * bn_dup_expand() makes sure allocation is made only once. + */ + +#ifndef OPENSSL_NO_DEPRECATED +BIGNUM *bn_dup_expand(const BIGNUM *b, int words) +{ + BIGNUM *r = NULL; + + bn_check_top(b); + + /* + * This function does not work if words <= b->dmax && top < words because + * BN_dup() does not preserve 'dmax'! (But bn_dup_expand() is not used + * anywhere yet.) + */ + + if (words > b->dmax) { + BN_ULONG *a = bn_expand_internal(b, words); + + if (a) { + r = BN_new(); + if (r) { + r->top = b->top; + r->dmax = words; + r->neg = b->neg; + r->d = a; + } else { + /* r == NULL, BN_new failure */ + OPENSSL_free(a); + } + } + /* + * If a == NULL, there was an error in allocation in + * bn_expand_internal(), and NULL should be returned + */ + } else { + r = BN_dup(b); + } + + bn_check_top(r); + return r; +} +#endif + +/* + * This is an internal function that should not be used in applications. It + * ensures that 'b' has enough room for a 'words' word number and initialises + * any unused part of b->d with leading zeros. It is mostly used by the + * various BIGNUM routines. If there is an error, NULL is returned. If not, + * 'b' is returned. + */ + +BIGNUM *bn_expand2(BIGNUM *b, int words) +{ + if (words > b->dmax) { + BN_ULONG *a = bn_expand_internal(b, words); + if (!a) + return NULL; + if (b->d) + OPENSSL_free(b->d); + b->d = a; + b->dmax = words; + } + +/* None of this should be necessary because of what b->top means! */ +#if 0 + /* + * NB: bn_wexpand() calls this only if the BIGNUM really has to grow + */ + if (b->top < b->dmax) { + int i; + BN_ULONG *A = &(b->d[b->top]); + for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) { + A[0] = 0; + A[1] = 0; + A[2] = 0; + A[3] = 0; + A[4] = 0; + A[5] = 0; + A[6] = 0; + A[7] = 0; + } + for (i = (b->dmax - b->top) & 7; i > 0; i--, A++) + A[0] = 0; + assert(A == &(b->d[b->dmax])); + } +#endif + return b; +} + +BIGNUM *BN_dup(const BIGNUM *a) +{ + BIGNUM *t; + + if (a == NULL) + return NULL; + bn_check_top(a); + + t = BN_new(); + if (t == NULL) + return NULL; + if (!BN_copy(t, a)) { + BN_free(t); + return NULL; + } + bn_check_top(t); + return t; +} + +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) +{ + int i; + BN_ULONG *A; + const BN_ULONG *B; + + bn_check_top(b); + + if (a == b) + return (a); + if (bn_wexpand(a, b->top) == NULL) + return (NULL); + +#if 1 + A = a->d; + B = b->d; + for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { + BN_ULONG a0, a1, a2, a3; + a0 = B[0]; + a1 = B[1]; + a2 = B[2]; + a3 = B[3]; + A[0] = a0; + A[1] = a1; + A[2] = a2; + A[3] = a3; + } + /* ultrix cc workaround, see comments in bn_expand_internal */ + switch (b->top & 3) { + case 3: + A[2] = B[2]; + case 2: + A[1] = B[1]; + case 1: + A[0] = B[0]; + case 0:; + } +#else + memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); +#endif + + a->neg = b->neg; + a->top = b->top; + a->flags |= b->flags & BN_FLG_FIXED_TOP; + bn_check_top(a); + return (a); +} + +#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \ + | BN_FLG_CONSTTIME \ + | BN_FLG_FIXED_TOP)) +#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED)) + +void BN_swap(BIGNUM *a, BIGNUM *b) +{ + int flags_old_a, flags_old_b; + BN_ULONG *tmp_d; + int tmp_top, tmp_dmax, tmp_neg; + + bn_check_top(a); + bn_check_top(b); + + flags_old_a = a->flags; + flags_old_b = b->flags; + + tmp_d = a->d; + tmp_top = a->top; + tmp_dmax = a->dmax; + tmp_neg = a->neg; + + a->d = b->d; + a->top = b->top; + a->dmax = b->dmax; + a->neg = b->neg; + + b->d = tmp_d; + b->top = tmp_top; + b->dmax = tmp_dmax; + b->neg = tmp_neg; + + a->flags = FLAGS_STRUCT(flags_old_a) | FLAGS_DATA(flags_old_b); + b->flags = FLAGS_STRUCT(flags_old_b) | FLAGS_DATA(flags_old_a); + bn_check_top(a); + bn_check_top(b); +} + +void BN_clear(BIGNUM *a) +{ + bn_check_top(a); + if (a->d != NULL) + OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0])); + a->top = 0; + a->neg = 0; + a->flags &= ~BN_FLG_FIXED_TOP; +} + +BN_ULONG BN_get_word(const BIGNUM *a) +{ + if (a->top > 1) + return BN_MASK2; + else if (a->top == 1) + return a->d[0]; + /* a->top == 0 */ + return 0; +} + +int BN_set_word(BIGNUM *a, BN_ULONG w) +{ + bn_check_top(a); + if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL) + return (0); + a->neg = 0; + a->d[0] = w; + a->top = (w ? 1 : 0); + a->flags &= ~BN_FLG_FIXED_TOP; + bn_check_top(a); + return (1); +} + +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + unsigned int i, m; + unsigned int n; + BN_ULONG l; + BIGNUM *bn = NULL; + + if (ret == NULL) + ret = bn = BN_new(); + if (ret == NULL) + return (NULL); + bn_check_top(ret); + l = 0; + n = len; + if (n == 0) { + ret->top = 0; + return (ret); + } + i = ((n - 1) / BN_BYTES) + 1; + m = ((n - 1) % (BN_BYTES)); + if (bn_wexpand(ret, (int)i) == NULL) { + if (bn) + BN_free(bn); + return NULL; + } + ret->top = i; + ret->neg = 0; + while (n--) { + l = (l << 8L) | *(s++); + if (m-- == 0) { + ret->d[--i] = l; + l = 0; + m = BN_BYTES - 1; + } + } + /* + * need to call this due to clear byte at top if avoiding having the top + * bit set (-ve number) + */ + bn_correct_top(ret); + return (ret); +} + +/* ignore negative */ +static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) +{ + int n; + size_t i, lasti, j, atop, mask; + BN_ULONG l; + + /* + * In case |a| is fixed-top, BN_num_bytes can return bogus length, + * but it's assumed that fixed-top inputs ought to be "nominated" + * even for padded output, so it works out... + */ + n = BN_num_bytes(a); + if (tolen == -1) { + tolen = n; + } else if (tolen < n) { /* uncommon/unlike case */ + BIGNUM temp = *a; + + bn_correct_top(&temp); + n = BN_num_bytes(&temp); + if (tolen < n) + return -1; + } + + /* Swipe through whole available data and don't give away padded zero. */ + atop = a->dmax * BN_BYTES; + if (atop == 0) { + OPENSSL_cleanse(to, tolen); + return tolen; + } + + lasti = atop - 1; + atop = a->top * BN_BYTES; + for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) { + l = a->d[i / BN_BYTES]; + mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); + *--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); + i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ + } + + return tolen; +} + +int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) +{ + if (tolen < 0) + return -1; + return bn2binpad(a, to, tolen); +} + +int BN_bn2bin(const BIGNUM *a, unsigned char *to) +{ + int n, i; + BN_ULONG l; + + bn_check_top(a); + n = i = BN_num_bytes(a); + while (i--) { + l = a->d[i / BN_BYTES]; + *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; + } + return (n); +} + +int BN_ucmp(const BIGNUM *a, const BIGNUM *b) +{ + int i; + BN_ULONG t1, t2, *ap, *bp; + + bn_check_top(a); + bn_check_top(b); + + i = a->top - b->top; + if (i != 0) + return (i); + ap = a->d; + bp = b->d; + for (i = a->top - 1; i >= 0; i--) { + t1 = ap[i]; + t2 = bp[i]; + if (t1 != t2) + return ((t1 > t2) ? 1 : -1); + } + return (0); +} + +int BN_cmp(const BIGNUM *a, const BIGNUM *b) +{ + int i; + int gt, lt; + BN_ULONG t1, t2; + + if ((a == NULL) || (b == NULL)) { + if (a != NULL) + return (-1); + else if (b != NULL) + return (1); + else + return (0); + } + + bn_check_top(a); + bn_check_top(b); + + if (a->neg != b->neg) { + if (a->neg) + return (-1); + else + return (1); + } + if (a->neg == 0) { + gt = 1; + lt = -1; + } else { + gt = -1; + lt = 1; + } + + if (a->top > b->top) + return (gt); + if (a->top < b->top) + return (lt); + for (i = a->top - 1; i >= 0; i--) { + t1 = a->d[i]; + t2 = b->d[i]; + if (t1 > t2) + return (gt); + if (t1 < t2) + return (lt); + } + return (0); +} + +int BN_set_bit(BIGNUM *a, int n) +{ + int i, j, k; + + if (n < 0) + return 0; + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) { + if (bn_wexpand(a, i + 1) == NULL) + return (0); + for (k = a->top; k < i + 1; k++) + a->d[k] = 0; + a->top = i + 1; + a->flags &= ~BN_FLG_FIXED_TOP; + } + + a->d[i] |= (((BN_ULONG)1) << j); + bn_check_top(a); + return (1); +} + +int BN_clear_bit(BIGNUM *a, int n) +{ + int i, j; + + bn_check_top(a); + if (n < 0) + return 0; + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) + return (0); + + a->d[i] &= (~(((BN_ULONG)1) << j)); + bn_correct_top(a); + return (1); +} + +int BN_is_bit_set(const BIGNUM *a, int n) +{ + int i, j; + + bn_check_top(a); + if (n < 0) + return 0; + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) + return 0; + return (int)(((a->d[i]) >> j) & ((BN_ULONG)1)); +} + +int BN_mask_bits(BIGNUM *a, int n) +{ + int b, w; + + bn_check_top(a); + if (n < 0) + return 0; + + w = n / BN_BITS2; + b = n % BN_BITS2; + if (w >= a->top) + return 0; + if (b == 0) + a->top = w; + else { + a->top = w + 1; + a->d[w] &= ~(BN_MASK2 << b); + } + bn_correct_top(a); + return (1); +} + +void BN_set_negative(BIGNUM *a, int b) +{ + if (b && !BN_is_zero(a)) + a->neg = 1; + else + a->neg = 0; +} + +int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) +{ + int i; + BN_ULONG aa, bb; + + aa = a[n - 1]; + bb = b[n - 1]; + if (aa != bb) + return ((aa > bb) ? 1 : -1); + for (i = n - 2; i >= 0; i--) { + aa = a[i]; + bb = b[i]; + if (aa != bb) + return ((aa > bb) ? 1 : -1); + } + return (0); +} + +/* + * Here follows a specialised variants of bn_cmp_words(). It has the + * property of performing the operation on arrays of different sizes. The + * sizes of those arrays is expressed through cl, which is the common length + * ( basicall, min(len(a),len(b)) ), and dl, which is the delta between the + * two lengths, calculated as len(a)-len(b). All lengths are the number of + * BN_ULONGs... + */ + +int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl) +{ + int n, i; + n = cl - 1; + + if (dl < 0) { + for (i = dl; i < 0; i++) { + if (b[n - i] != 0) + return -1; /* a < b */ + } + } + if (dl > 0) { + for (i = dl; i > 0; i--) { + if (a[n + i] != 0) + return 1; /* a > b */ + } + } + return bn_cmp_words(a, b, cl); +} + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. + * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, + * and that no more than nwords are used by either a or b. + * a and b cannot be the same number + */ +void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) +{ + BN_ULONG t; + int i; + + bn_wcheck_size(a, nwords); + bn_wcheck_size(b, nwords); + + assert(a != b); + assert((condition & (condition - 1)) == 0); + assert(sizeof(BN_ULONG) >= sizeof(int)); + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + t = (a->top ^ b->top) & condition; + a->top ^= t; + b->top ^= t; + + t = (a->neg ^ b->neg) & condition; + a->neg ^= t; + b->neg ^= t; + + /*- + * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention + * is actually to treat it as it's read-only data, and some (if not most) + * of it does reside in read-only segment. In other words observation of + * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal + * condition. It would either cause SEGV or effectively cause data + * corruption. + * + * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be + * preserved. + * + * BN_FLG_SECURE: must be preserved, because it determines how x->d was + * allocated and hence how to free it. + * + * BN_FLG_CONSTTIME: sufficient to mask and swap + * + * BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on + * the data, so the d array may be padded with additional 0 values (i.e. + * top could be greater than the minimal value that it could be). We should + * be swapping it + */ + +#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP) + + t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition; + a->flags ^= t; + b->flags ^= t; + +#define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ + a->d[ind] ^= t; \ + b->d[ind] ^= t; \ + } while (0) + + switch (nwords) { + default: + for (i = 10; i < nwords; i++) + BN_CONSTTIME_SWAP(i); + /* Fallthrough */ + case 10: + BN_CONSTTIME_SWAP(9); /* Fallthrough */ + case 9: + BN_CONSTTIME_SWAP(8); /* Fallthrough */ + case 8: + BN_CONSTTIME_SWAP(7); /* Fallthrough */ + case 7: + BN_CONSTTIME_SWAP(6); /* Fallthrough */ + case 6: + BN_CONSTTIME_SWAP(5); /* Fallthrough */ + case 5: + BN_CONSTTIME_SWAP(4); /* Fallthrough */ + case 4: + BN_CONSTTIME_SWAP(3); /* Fallthrough */ + case 3: + BN_CONSTTIME_SWAP(2); /* Fallthrough */ + case 2: + BN_CONSTTIME_SWAP(1); /* Fallthrough */ + case 1: + BN_CONSTTIME_SWAP(0); + } +#undef BN_CONSTTIME_SWAP +} +/* crypto/bn/bn_mod.c */ +/* + * Includes code written by Lenka Fibikova + * for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "cryptlib.h" +// #include "bn_lcl.h" + +#if 0 /* now just a #define */ +int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) +{ + return (BN_div(NULL, rem, m, d, ctx)); + /* note that rem->neg == m->neg (unless the remainder is zero) */ +} +#endif + +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) +{ + /* + * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d| + * always holds) + */ + + if (!(BN_mod(r, m, d, ctx))) + return 0; + if (!r->neg) + return 1; + /* now -|d| < r < 0, so we have to set r := r + |d| */ + return (d->neg ? BN_sub : BN_add) (r, r, d); +} + +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + if (!BN_add(r, a, b)) + return 0; + return BN_nnmod(r, r, m, ctx); +} + +/* + * BN_mod_add variant that may be used if both a and b are non-negative and + * less than m. The original algorithm was + * + * if (!BN_uadd(r, a, b)) + * return 0; + * if (BN_ucmp(r, m) >= 0) + * return BN_usub(r, r, m); + * + * which is replaced with addition, subtracting modulus, and conditional + * move depending on whether or not subtraction borrowed. + */ +int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) +{ + size_t i, ai, bi, mtop = m->top; + BN_ULONG storage[1024 / BN_BITS2]; + BN_ULONG carry, temp, mask, *rp, *tp = storage; + const BN_ULONG *ap, *bp; + + if (bn_wexpand(r, m->top) == NULL) + return 0; + + if (mtop > sizeof(storage) / sizeof(storage[0]) + && (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL) + return 0; + + ap = a->d != NULL ? a->d : tp; + bp = b->d != NULL ? b->d : tp; + + for (i = 0, ai = 0, bi = 0, carry = 0; i < mtop;) { + mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); + temp = ((ap[ai] & mask) + carry) & BN_MASK2; + carry = (temp < carry); + + mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); + tp[i] = ((bp[bi] & mask) + temp) & BN_MASK2; + carry += (tp[i] < temp); + + i++; + ai += (i - a->dmax) >> (8 * sizeof(i) - 1); + bi += (i - b->dmax) >> (8 * sizeof(i) - 1); + } + rp = r->d; + carry -= bn_sub_words(rp, tp, m->d, mtop); + for (i = 0; i < mtop; i++) { + rp[i] = (carry & tp[i]) | (~carry & rp[i]); + ((volatile BN_ULONG *)tp)[i] = 0; + } + r->top = mtop; + r->flags |= BN_FLG_FIXED_TOP; + r->neg = 0; + + if (tp != storage) + OPENSSL_free(tp); + + return 1; +} + +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) +{ + int ret = bn_mod_add_fixed_top(r, a, b, m); + + if (ret) + bn_correct_top(r); + + return ret; +} + +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + if (!BN_sub(r, a, b)) + return 0; + return BN_nnmod(r, r, m, ctx); +} + +/* + * BN_mod_sub variant that may be used if both a and b are non-negative, + * a is less than m, while b is of same bit width as m. It's implemented + * as subtraction followed by two conditional additions. + * + * 0 <= a < m + * 0 <= b < 2^w < 2*m + * + * after subtraction + * + * -2*m < r = a - b < m + * + * Thus it takes up to two conditional additions to make |r| positive. + */ +int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) +{ + size_t i, ai, bi, mtop = m->top; + BN_ULONG borrow, carry, ta, tb, mask, *rp; + const BN_ULONG *ap, *bp; + + if (bn_wexpand(r, m->top) == NULL) + return 0; + + rp = r->d; + ap = a->d != NULL ? a->d : rp; + bp = b->d != NULL ? b->d : rp; + + for (i = 0, ai = 0, bi = 0, borrow = 0; i < mtop;) { + mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); + ta = ap[ai] & mask; + + mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); + tb = bp[bi] & mask; + rp[i] = ta - tb - borrow; + if (ta != tb) + borrow = (ta < tb); + + i++; + ai += (i - a->dmax) >> (8 * sizeof(i) - 1); + bi += (i - b->dmax) >> (8 * sizeof(i) - 1); + } + ap = m->d; + for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { + ta = ((ap[i] & mask) + carry) & BN_MASK2; + carry = (ta < carry); + rp[i] = (rp[i] + ta) & BN_MASK2; + carry += (rp[i] < ta); + } + borrow -= carry; + for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { + ta = ((ap[i] & mask) + carry) & BN_MASK2; + carry = (ta < carry); + rp[i] = (rp[i] + ta) & BN_MASK2; + carry += (rp[i] < ta); + } + + r->top = mtop; + r->flags |= BN_FLG_FIXED_TOP; + r->neg = 0; + + return 1; +} + +/* + * BN_mod_sub variant that may be used if both a and b are non-negative and + * less than m + */ +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) +{ + if (!BN_sub(r, a, b)) + return 0; + if (r->neg) + return BN_add(r, r, m); + return 1; +} + +/* slow but works */ +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + BIGNUM *t; + int ret = 0; + + bn_check_top(a); + bn_check_top(b); + bn_check_top(m); + + BN_CTX_start(ctx); + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + if (a == b) { + if (!BN_sqr(t, a, ctx)) + goto err; + } else { + if (!BN_mul(t, a, b, ctx)) + goto err; + } + if (!BN_nnmod(r, t, m, ctx)) + goto err; + bn_check_top(r); + ret = 1; + err: + BN_CTX_end(ctx); + return (ret); +} + +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + if (!BN_sqr(r, a, ctx)) + return 0; + /* r->neg == 0, thus we don't need BN_nnmod */ + return BN_mod(r, r, m, ctx); +} + +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + if (!BN_lshift1(r, a)) + return 0; + bn_check_top(r); + return BN_nnmod(r, r, m, ctx); +} + +/* + * BN_mod_lshift1 variant that may be used if a is non-negative and less than + * m + */ +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) +{ + if (!BN_lshift1(r, a)) + return 0; + bn_check_top(r); + if (BN_cmp(r, m) >= 0) + return BN_sub(r, r, m); + return 1; +} + +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx) +{ + BIGNUM *abs_m = NULL; + int ret; + + if (!BN_nnmod(r, a, m, ctx)) + return 0; + + if (m->neg) { + abs_m = BN_dup(m); + if (abs_m == NULL) + return 0; + abs_m->neg = 0; + } + + ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m)); + bn_check_top(r); + + if (abs_m) + BN_free(abs_m); + return ret; +} + +/* + * BN_mod_lshift variant that may be used if a is non-negative and less than + * m + */ +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) +{ + if (r != a) { + if (BN_copy(r, a) == NULL) + return 0; + } + + while (n > 0) { + int max_shift; + + /* 0 < r < m */ + max_shift = BN_num_bits(m) - BN_num_bits(r); + /* max_shift >= 0 */ + + if (max_shift < 0) { + BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + if (max_shift > n) + max_shift = n; + + if (max_shift) { + if (!BN_lshift(r, r, max_shift)) + return 0; + n -= max_shift; + } else { + if (!BN_lshift1(r, r)) + return 0; + --n; + } + + /* BN_num_bits(r) <= BN_num_bits(m) */ + + if (BN_cmp(r, m) >= 0) { + if (!BN_sub(r, r, m)) + return 0; + } + } + bn_check_top(r); + + return 1; +} +/* crypto/bn/bn_mont.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Details about Montgomery multiplication algorithms can be found at + * http://security.ece.orst.edu/publications.html, e.g. + * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and + * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf + */ + +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +#define MONT_WORD /* use the faster word-based algorithm */ + +#ifdef MONT_WORD +static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); +#endif + +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx) +{ + int ret = bn_mul_mont_fixed_top(r, a, b, mont, ctx); + + bn_correct_top(r); + bn_check_top(r); + + return ret; +} + +int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx) +{ + BIGNUM *tmp; + int ret = 0; +#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) + int num = mont->N.top; + + if (num > 1 && a->top == num && b->top == num) { + if (bn_wexpand(r, num) == NULL) + return (0); + if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { + r->neg = a->neg ^ b->neg; + r->top = num; + r->flags |= BN_FLG_FIXED_TOP; + return 1; + } + } +#endif + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + bn_check_top(tmp); + if (a == b) { + if (!bn_sqr_fixed_top(tmp, a, ctx)) + goto err; + } else { + if (!bn_mul_fixed_top(tmp, a, b, ctx)) + goto err; + } + /* reduce from aRR to aR */ +#ifdef MONT_WORD + if (!bn_from_montgomery_word(r, tmp, mont)) + goto err; +#else + if (!BN_from_montgomery(r, tmp, mont, ctx)) + goto err; +#endif + ret = 1; + err: + BN_CTX_end(ctx); + return (ret); +} + +#ifdef MONT_WORD +static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) +{ + BIGNUM *n; + BN_ULONG *ap, *np, *rp, n0, v, carry; + int nl, max, i; + unsigned int rtop; + + n = &(mont->N); + nl = n->top; + if (nl == 0) { + ret->top = 0; + return (1); + } + + max = (2 * nl); /* carry is stored separately */ + if (bn_wexpand(r, max) == NULL) + return (0); + + r->neg ^= n->neg; + np = n->d; + rp = r->d; + + /* clear the top words of T */ + for (rtop = r->top, i = 0; i < max; i++) { + v = (BN_ULONG)0 - ((i - rtop) >> (8 * sizeof(rtop) - 1)); + rp[i] &= v; + } + + r->top = max; + r->flags |= BN_FLG_FIXED_TOP; + n0 = mont->n0[0]; + + /* + * Add multiples of |n| to |r| until R = 2^(nl * BN_BITS2) divides it. On + * input, we had |r| < |n| * R, so now |r| < 2 * |n| * R. Note that |r| + * includes |carry| which is stored separately. + */ + for (carry = 0, i = 0; i < nl; i++, rp++) { + v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2); + v = (v + carry + rp[nl]) & BN_MASK2; + carry |= (v != rp[nl]); + carry &= (v <= rp[nl]); + rp[nl] = v; + } + + if (bn_wexpand(ret, nl) == NULL) + return (0); + ret->top = nl; + ret->flags |= BN_FLG_FIXED_TOP; + ret->neg = r->neg; + + rp = ret->d; + + /* + * Shift |nl| words to divide by R. We have |ap| < 2 * |n|. Note that |ap| + * includes |carry| which is stored separately. + */ + ap = &(r->d[nl]); + + carry -= bn_sub_words(rp, ap, np, nl); + /* + * |carry| is -1 if |ap| - |np| underflowed or zero if it did not. Note + * |carry| cannot be 1. That would imply the subtraction did not fit in + * |nl| words, and we know at most one subtraction is needed. + */ + for (i = 0; i < nl; i++) { + rp[i] = (carry & ap[i]) | (~carry & rp[i]); + ap[i] = 0; + } + + return (1); +} +#endif /* MONT_WORD */ + +int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) +{ + int retn; + + retn = bn_from_mont_fixed_top(ret, a, mont, ctx); + bn_correct_top(ret); + bn_check_top(ret); + + return retn; +} + +int bn_from_mont_fixed_top(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) +{ + int retn = 0; +#ifdef MONT_WORD + BIGNUM *t; + + BN_CTX_start(ctx); + if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) { + retn = bn_from_montgomery_word(ret, t, mont); + } + BN_CTX_end(ctx); +#else /* !MONT_WORD */ + BIGNUM *t1, *t2; + + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t1 == NULL || t2 == NULL) + goto err; + + if (!BN_copy(t1, a)) + goto err; + BN_mask_bits(t1, mont->ri); + + if (!BN_mul(t2, t1, &mont->Ni, ctx)) + goto err; + BN_mask_bits(t2, mont->ri); + + if (!BN_mul(t1, t2, &mont->N, ctx)) + goto err; + if (!BN_add(t2, a, t1)) + goto err; + if (!BN_rshift(ret, t2, mont->ri)) + goto err; + + if (BN_ucmp(ret, &(mont->N)) >= 0) { + if (!BN_usub(ret, ret, &(mont->N))) + goto err; + } + retn = 1; + bn_check_top(ret); + err: + BN_CTX_end(ctx); +#endif /* MONT_WORD */ + return (retn); +} + +int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) +{ + return bn_mul_mont_fixed_top(r, a, &(mont->RR), mont, ctx); +} + +BN_MONT_CTX *BN_MONT_CTX_new(void) +{ + BN_MONT_CTX *ret; + + if ((ret = (BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL) + return (NULL); + + BN_MONT_CTX_init(ret); + ret->flags = BN_FLG_MALLOCED; + return (ret); +} + +void BN_MONT_CTX_init(BN_MONT_CTX *ctx) +{ + ctx->ri = 0; + BN_init(&(ctx->RR)); + BN_init(&(ctx->N)); + BN_init(&(ctx->Ni)); + ctx->n0[0] = ctx->n0[1] = 0; + ctx->flags = 0; +} + +void BN_MONT_CTX_free(BN_MONT_CTX *mont) +{ + if (mont == NULL) + return; + + BN_clear_free(&(mont->RR)); + BN_clear_free(&(mont->N)); + BN_clear_free(&(mont->Ni)); + if (mont->flags & BN_FLG_MALLOCED) + OPENSSL_free(mont); +} + +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *Ri, *R; + + if (BN_is_zero(mod)) + return 0; + + BN_CTX_start(ctx); + if ((Ri = BN_CTX_get(ctx)) == NULL) + goto err; + R = &(mont->RR); /* grab RR as a temp */ + if (!BN_copy(&(mont->N), mod)) + goto err; /* Set N */ + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(&(mont->N), BN_FLG_CONSTTIME); + mont->N.neg = 0; + +#ifdef MONT_WORD + { + BIGNUM tmod; + BN_ULONG buf[2]; + + BN_init(&tmod); + tmod.d = buf; + tmod.dmax = 2; + tmod.neg = 0; + + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(&tmod, BN_FLG_CONSTTIME); + + mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; + +# if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) + /* + * Only certain BN_BITS2<=32 platforms actually make use of n0[1], + * and we could use the #else case (with a shorter R value) for the + * others. However, currently only the assembler files do know which + * is which. + */ + + BN_zero(R); + if (!(BN_set_bit(R, 2 * BN_BITS2))) + goto err; + + tmod.top = 0; + if ((buf[0] = mod->d[0])) + tmod.top = 1; + if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) + tmod.top = 2; + + if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) + goto err; + if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) + goto err; /* R*Ri */ + if (!BN_is_zero(Ri)) { + if (!BN_sub_word(Ri, 1)) + goto err; + } else { /* if N mod word size == 1 */ + + if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) + goto err; + /* Ri-- (mod double word size) */ + Ri->neg = 0; + Ri->d[0] = BN_MASK2; + Ri->d[1] = BN_MASK2; + Ri->top = 2; + } + if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) + goto err; + /* + * Ni = (R*Ri-1)/N, keep only couple of least significant words: + */ + mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; + mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; +# else + BN_zero(R); + if (!(BN_set_bit(R, BN_BITS2))) + goto err; /* R */ + + buf[0] = mod->d[0]; /* tmod = N mod word size */ + buf[1] = 0; + tmod.top = buf[0] != 0 ? 1 : 0; + /* Ri = R^-1 mod N */ + if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) + goto err; + if (!BN_lshift(Ri, Ri, BN_BITS2)) + goto err; /* R*Ri */ + if (!BN_is_zero(Ri)) { + if (!BN_sub_word(Ri, 1)) + goto err; + } else { /* if N mod word size == 1 */ + + if (!BN_set_word(Ri, BN_MASK2)) + goto err; /* Ri-- (mod word size) */ + } + if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) + goto err; + /* + * Ni = (R*Ri-1)/N, keep only least significant word: + */ + mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; + mont->n0[1] = 0; +# endif + } +#else /* !MONT_WORD */ + { /* bignum version */ + mont->ri = BN_num_bits(&mont->N); + BN_zero(R); + if (!BN_set_bit(R, mont->ri)) + goto err; /* R = 2^ri */ + /* Ri = R^-1 mod N */ + if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL) + goto err; + if (!BN_lshift(Ri, Ri, mont->ri)) + goto err; /* R*Ri */ + if (!BN_sub_word(Ri, 1)) + goto err; + /* + * Ni = (R*Ri-1) / N + */ + if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx)) + goto err; + } +#endif + + /* setup RR for conversions */ + BN_zero(&(mont->RR)); + if (!BN_set_bit(&(mont->RR), mont->ri * 2)) + goto err; + if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) + goto err; + + for (i = mont->RR.top, ret = mont->N.top; i < ret; i++) + mont->RR.d[i] = 0; + mont->RR.top = ret; + mont->RR.flags |= BN_FLG_FIXED_TOP; + + ret = 1; + err: + BN_CTX_end(ctx); + return ret; +} + +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) +{ + if (to == from) + return (to); + + if (!BN_copy(&(to->RR), &(from->RR))) + return NULL; + if (!BN_copy(&(to->N), &(from->N))) + return NULL; + if (!BN_copy(&(to->Ni), &(from->Ni))) + return NULL; + to->ri = from->ri; + to->n0[0] = from->n0[0]; + to->n0[1] = from->n0[1]; + return (to); +} + +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx) +{ + BN_MONT_CTX *ret; + + CRYPTO_r_lock(lock); + ret = *pmont; + CRYPTO_r_unlock(lock); + if (ret) + return ret; + + /* + * We don't want to serialise globally while doing our lazy-init math in + * BN_MONT_CTX_set. That punishes threads that are doing independent + * things. Instead, punish the case where more than one thread tries to + * lazy-init the same 'pmont', by having each do the lazy-init math work + * independently and only use the one from the thread that wins the race + * (the losers throw away the work they've done). + */ + ret = BN_MONT_CTX_new(); + if (!ret) + return NULL; + if (!BN_MONT_CTX_set(ret, mod, ctx)) { + BN_MONT_CTX_free(ret); + return NULL; + } + + /* The locked compare-and-set, after the local work is done. */ + CRYPTO_w_lock(lock); + if (*pmont) { + BN_MONT_CTX_free(ret); + ret = *pmont; + } else + *pmont = ret; + CRYPTO_w_unlock(lock); + return ret; +} +/* crypto/bn/bn_mpi.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +int BN_bn2mpi(const BIGNUM *a, unsigned char *d) +{ + int bits; + int num = 0; + int ext = 0; + long l; + + bits = BN_num_bits(a); + num = (bits + 7) / 8; + if (bits > 0) { + ext = ((bits & 0x07) == 0); + } + if (d == NULL) + return (num + 4 + ext); + + l = num + ext; + d[0] = (unsigned char)(l >> 24) & 0xff; + d[1] = (unsigned char)(l >> 16) & 0xff; + d[2] = (unsigned char)(l >> 8) & 0xff; + d[3] = (unsigned char)(l) & 0xff; + if (ext) + d[4] = 0; + num = BN_bn2bin(a, &(d[4 + ext])); + if (a->neg) + d[4] |= 0x80; + return (num + 4 + ext); +} + +BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a) +{ + long len; + int neg = 0; + + if (n < 4) { + BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH); + return (NULL); + } + len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int) + d[3]; + if ((len + 4) != n) { + BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR); + return (NULL); + } + + if (a == NULL) + a = BN_new(); + if (a == NULL) + return (NULL); + + if (len == 0) { + a->neg = 0; + a->top = 0; + return (a); + } + d += 4; + if ((*d) & 0x80) + neg = 1; + if (BN_bin2bn(d, (int)len, a) == NULL) + return (NULL); + a->neg = neg; + if (neg) { + BN_clear_bit(a, BN_num_bits(a) - 1); + } + bn_check_top(a); + return (a); +} +/* crypto/bn/bn_mul.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef BN_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS) +/* + * Here follows specialised variants of bn_add_words() and bn_sub_words(). + * They have the property performing operations on arrays of different sizes. + * The sizes of those arrays is expressed through cl, which is the common + * length ( basicall, min(len(a),len(b)) ), and dl, which is the delta + * between the two lengths, calculated as len(a)-len(b). All lengths are the + * number of BN_ULONGs... For the operations that require a result array as + * parameter, it must have the length cl+abs(dl). These functions should + * probably end up in bn_asm.c as soon as there are assembler counterparts + * for the systems that use assembler files. + */ + +BN_ULONG bn_sub_part_words(BN_ULONG *r, + const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl) +{ + BN_ULONG c, t; + + assert(cl >= 0); + c = bn_sub_words(r, a, b, cl); + + if (dl == 0) + return c; + + r += cl; + a += cl; + b += cl; + + if (dl < 0) { +# ifdef BN_COUNT + fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, + dl, c); +# endif + for (;;) { + t = b[0]; + r[0] = (0 - t - c) & BN_MASK2; + if (t != 0) + c = 1; + if (++dl >= 0) + break; + + t = b[1]; + r[1] = (0 - t - c) & BN_MASK2; + if (t != 0) + c = 1; + if (++dl >= 0) + break; + + t = b[2]; + r[2] = (0 - t - c) & BN_MASK2; + if (t != 0) + c = 1; + if (++dl >= 0) + break; + + t = b[3]; + r[3] = (0 - t - c) & BN_MASK2; + if (t != 0) + c = 1; + if (++dl >= 0) + break; + + b += 4; + r += 4; + } + } else { + int save_dl = dl; +# ifdef BN_COUNT + fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, + dl, c); +# endif + while (c) { + t = a[0]; + r[0] = (t - c) & BN_MASK2; + if (t != 0) + c = 0; + if (--dl <= 0) + break; + + t = a[1]; + r[1] = (t - c) & BN_MASK2; + if (t != 0) + c = 0; + if (--dl <= 0) + break; + + t = a[2]; + r[2] = (t - c) & BN_MASK2; + if (t != 0) + c = 0; + if (--dl <= 0) + break; + + t = a[3]; + r[3] = (t - c) & BN_MASK2; + if (t != 0) + c = 0; + if (--dl <= 0) + break; + + save_dl = dl; + a += 4; + r += 4; + } + if (dl > 0) { +# ifdef BN_COUNT + fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c == 0)\n", + cl, dl); +# endif + if (save_dl > dl) { + switch (save_dl - dl) { + case 1: + r[1] = a[1]; + if (--dl <= 0) + break; + case 2: + r[2] = a[2]; + if (--dl <= 0) + break; + case 3: + r[3] = a[3]; + if (--dl <= 0) + break; + } + a += 4; + r += 4; + } + } + if (dl > 0) { +# ifdef BN_COUNT + fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, copy)\n", + cl, dl); +# endif + for (;;) { + r[0] = a[0]; + if (--dl <= 0) + break; + r[1] = a[1]; + if (--dl <= 0) + break; + r[2] = a[2]; + if (--dl <= 0) + break; + r[3] = a[3]; + if (--dl <= 0) + break; + + a += 4; + r += 4; + } + } + } + return c; +} +#endif + +BN_ULONG bn_add_part_words(BN_ULONG *r, + const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl) +{ + BN_ULONG c, l, t; + + assert(cl >= 0); + c = bn_add_words(r, a, b, cl); + + if (dl == 0) + return c; + + r += cl; + a += cl; + b += cl; + + if (dl < 0) { + int save_dl = dl; +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, + dl, c); +#endif + while (c) { + l = (c + b[0]) & BN_MASK2; + c = (l < c); + r[0] = l; + if (++dl >= 0) + break; + + l = (c + b[1]) & BN_MASK2; + c = (l < c); + r[1] = l; + if (++dl >= 0) + break; + + l = (c + b[2]) & BN_MASK2; + c = (l < c); + r[2] = l; + if (++dl >= 0) + break; + + l = (c + b[3]) & BN_MASK2; + c = (l < c); + r[3] = l; + if (++dl >= 0) + break; + + save_dl = dl; + b += 4; + r += 4; + } + if (dl < 0) { +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c == 0)\n", + cl, dl); +#endif + if (save_dl < dl) { + switch (dl - save_dl) { + case 1: + r[1] = b[1]; + if (++dl >= 0) + break; + case 2: + r[2] = b[2]; + if (++dl >= 0) + break; + case 3: + r[3] = b[3]; + if (++dl >= 0) + break; + } + b += 4; + r += 4; + } + } + if (dl < 0) { +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, copy)\n", + cl, dl); +#endif + for (;;) { + r[0] = b[0]; + if (++dl >= 0) + break; + r[1] = b[1]; + if (++dl >= 0) + break; + r[2] = b[2]; + if (++dl >= 0) + break; + r[3] = b[3]; + if (++dl >= 0) + break; + + b += 4; + r += 4; + } + } + } else { + int save_dl = dl; +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl > 0)\n", cl, dl); +#endif + while (c) { + t = (a[0] + c) & BN_MASK2; + c = (t < c); + r[0] = t; + if (--dl <= 0) + break; + + t = (a[1] + c) & BN_MASK2; + c = (t < c); + r[1] = t; + if (--dl <= 0) + break; + + t = (a[2] + c) & BN_MASK2; + c = (t < c); + r[2] = t; + if (--dl <= 0) + break; + + t = (a[3] + c) & BN_MASK2; + c = (t < c); + r[3] = t; + if (--dl <= 0) + break; + + save_dl = dl; + a += 4; + r += 4; + } +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, + dl); +#endif + if (dl > 0) { + if (save_dl > dl) { + switch (save_dl - dl) { + case 1: + r[1] = a[1]; + if (--dl <= 0) + break; + case 2: + r[2] = a[2]; + if (--dl <= 0) + break; + case 3: + r[3] = a[3]; + if (--dl <= 0) + break; + } + a += 4; + r += 4; + } + } + if (dl > 0) { +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, copy)\n", + cl, dl); +#endif + for (;;) { + r[0] = a[0]; + if (--dl <= 0) + break; + r[1] = a[1]; + if (--dl <= 0) + break; + r[2] = a[2]; + if (--dl <= 0) + break; + r[3] = a[3]; + if (--dl <= 0) + break; + + a += 4; + r += 4; + } + } + } + return c; +} + +#ifdef BN_RECURSION +/* + * Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of + * Computer Programming, Vol. 2) + */ + +/*- + * r is 2*n2 words in size, + * a and b are both n2 words in size. + * n2 must be a power of 2. + * We multiply and return the result. + * t must be 2*n2 words in size + * We calculate + * a[0]*b[0] + * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) + * a[1]*b[1] + */ +/* dnX may not be positive, but n2/2+dnX has to be */ +void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + int dna, int dnb, BN_ULONG *t) +{ + int n = n2 / 2, c1, c2; + int tna = n + dna, tnb = n + dnb; + unsigned int neg, zero; + BN_ULONG ln, lo, *p; + +# ifdef BN_COUNT + fprintf(stderr, " bn_mul_recursive %d%+d * %d%+d\n", n2, dna, n2, dnb); +# endif +# ifdef BN_MUL_COMBA +# if 0 + if (n2 == 4) { + bn_mul_comba4(r, a, b); + return; + } +# endif + /* + * Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete + * [steve] + */ + if (n2 == 8 && dna == 0 && dnb == 0) { + bn_mul_comba8(r, a, b); + return; + } +# endif /* BN_MUL_COMBA */ + /* Else do normal multiply */ + if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) { + bn_mul_normal(r, a, n2 + dna, b, n2 + dnb); + if ((dna + dnb) < 0) + memset(&r[2 * n2 + dna + dnb], 0, + sizeof(BN_ULONG) * -(dna + dnb)); + return; + } + /* r=(a[0]-a[1])*(b[1]-b[0]) */ + c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna); + c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n); + zero = neg = 0; + switch (c1 * 3 + c2) { + case -4: + bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ + bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ + break; + case -3: + zero = 1; + break; + case -2: + bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ + bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */ + neg = 1; + break; + case -1: + case 0: + case 1: + zero = 1; + break; + case 2: + bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */ + bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ + neg = 1; + break; + case 3: + zero = 1; + break; + case 4: + bn_sub_part_words(t, a, &(a[n]), tna, n - tna); + bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); + break; + } + +# ifdef BN_MUL_COMBA + if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take + * extra args to do this well */ + if (!zero) + bn_mul_comba4(&(t[n2]), t, &(t[n])); + else + memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG)); + + bn_mul_comba4(r, a, b); + bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n])); + } else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could + * take extra args to do + * this well */ + if (!zero) + bn_mul_comba8(&(t[n2]), t, &(t[n])); + else + memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG)); + + bn_mul_comba8(r, a, b); + bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n])); + } else +# endif /* BN_MUL_COMBA */ + { + p = &(t[n2 * 2]); + if (!zero) + bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p); + else + memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG)); + bn_mul_recursive(r, a, b, n, 0, 0, p); + bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p); + } + + /*- + * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + */ + + c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); + + if (neg) { /* if t[32] is negative */ + c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); + } else { + /* Might have a carry */ + c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2)); + } + + /*- + * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + * c1 holds the carry bits + */ + c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); + if (c1) { + p = &(r[n + n2]); + lo = *p; + ln = (lo + c1) & BN_MASK2; + *p = ln; + + /* + * The overflow will stop before we over write words we should not + * overwrite + */ + if (ln < (BN_ULONG)c1) { + do { + p++; + lo = *p; + ln = (lo + 1) & BN_MASK2; + *p = ln; + } while (ln == 0); + } + } +} + +/* + * n+tn is the word length t needs to be n*4 is size, as does r + */ +/* tnX may not be negative but less than n */ +void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, + int tna, int tnb, BN_ULONG *t) +{ + int i, j, n2 = n * 2; + int c1, c2, neg; + BN_ULONG ln, lo, *p; + +# ifdef BN_COUNT + fprintf(stderr, " bn_mul_part_recursive (%d%+d) * (%d%+d)\n", + n, tna, n, tnb); +# endif + if (n < 8) { + bn_mul_normal(r, a, n + tna, b, n + tnb); + return; + } + + /* r=(a[0]-a[1])*(b[1]-b[0]) */ + c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna); + c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n); + neg = 0; + switch (c1 * 3 + c2) { + case -4: + bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ + bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ + break; + case -3: + /* break; */ + case -2: + bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ + bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */ + neg = 1; + break; + case -1: + case 0: + case 1: + /* break; */ + case 2: + bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */ + bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ + neg = 1; + break; + case 3: + /* break; */ + case 4: + bn_sub_part_words(t, a, &(a[n]), tna, n - tna); + bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); + break; + } + /* + * The zero case isn't yet implemented here. The speedup would probably + * be negligible. + */ +# if 0 + if (n == 4) { + bn_mul_comba4(&(t[n2]), t, &(t[n])); + bn_mul_comba4(r, a, b); + bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn); + memset(&(r[n2 + tn * 2]), 0, sizeof(BN_ULONG) * (n2 - tn * 2)); + } else +# endif + if (n == 8) { + bn_mul_comba8(&(t[n2]), t, &(t[n])); + bn_mul_comba8(r, a, b); + bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb); + memset(&(r[n2 + tna + tnb]), 0, sizeof(BN_ULONG) * (n2 - tna - tnb)); + } else { + p = &(t[n2 * 2]); + bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p); + bn_mul_recursive(r, a, b, n, 0, 0, p); + i = n / 2; + /* + * If there is only a bottom half to the number, just do it + */ + if (tna > tnb) + j = tna - i; + else + j = tnb - i; + if (j == 0) { + bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), + i, tna - i, tnb - i, p); + memset(&(r[n2 + i * 2]), 0, sizeof(BN_ULONG) * (n2 - i * 2)); + } else if (j > 0) { /* eg, n == 16, i == 8 and tn == 11 */ + bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]), + i, tna - i, tnb - i, p); + memset(&(r[n2 + tna + tnb]), 0, + sizeof(BN_ULONG) * (n2 - tna - tnb)); + } else { /* (j < 0) eg, n == 16, i == 8 and tn == 5 */ + + memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2); + if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL + && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) { + bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb); + } else { + for (;;) { + i /= 2; + /* + * these simplified conditions work exclusively because + * difference between tna and tnb is 1 or 0 + */ + if (i < tna || i < tnb) { + bn_mul_part_recursive(&(r[n2]), + &(a[n]), &(b[n]), + i, tna - i, tnb - i, p); + break; + } else if (i == tna || i == tnb) { + bn_mul_recursive(&(r[n2]), + &(a[n]), &(b[n]), + i, tna - i, tnb - i, p); + break; + } + } + } + } + } + + /*- + * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + */ + + c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); + + if (neg) { /* if t[32] is negative */ + c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); + } else { + /* Might have a carry */ + c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2)); + } + + /*- + * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + * c1 holds the carry bits + */ + c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); + if (c1) { + p = &(r[n + n2]); + lo = *p; + ln = (lo + c1) & BN_MASK2; + *p = ln; + + /* + * The overflow will stop before we over write words we should not + * overwrite + */ + if (ln < (BN_ULONG)c1) { + do { + p++; + lo = *p; + ln = (lo + 1) & BN_MASK2; + *p = ln; + } while (ln == 0); + } + } +} + +/*- + * a and b must be the same size, which is n2. + * r needs to be n2 words and t needs to be n2*2 + */ +void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + BN_ULONG *t) +{ + int n = n2 / 2; + +# ifdef BN_COUNT + fprintf(stderr, " bn_mul_low_recursive %d * %d\n", n2, n2); +# endif + + bn_mul_recursive(r, a, b, n, 0, 0, &(t[0])); + if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) { + bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2])); + bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); + bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2])); + bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); + } else { + bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n); + bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n); + bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); + bn_add_words(&(r[n]), &(r[n]), &(t[n]), n); + } +} + +/*- + * a and b must be the same size, which is n2. + * r needs to be n2 words and t needs to be n2*2 + * l is the low words of the output. + * t needs to be n2*3 + */ +void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, + BN_ULONG *t) +{ + int i, n; + int c1, c2; + int neg, oneg, zero; + BN_ULONG ll, lc, *lp, *mp; + +# ifdef BN_COUNT + fprintf(stderr, " bn_mul_high %d * %d\n", n2, n2); +# endif + n = n2 / 2; + + /* Calculate (al-ah)*(bh-bl) */ + neg = zero = 0; + c1 = bn_cmp_words(&(a[0]), &(a[n]), n); + c2 = bn_cmp_words(&(b[n]), &(b[0]), n); + switch (c1 * 3 + c2) { + case -4: + bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n); + bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n); + break; + case -3: + zero = 1; + break; + case -2: + bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n); + bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n); + neg = 1; + break; + case -1: + case 0: + case 1: + zero = 1; + break; + case 2: + bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n); + bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n); + neg = 1; + break; + case 3: + zero = 1; + break; + case 4: + bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n); + bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n); + break; + } + + oneg = neg; + /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */ + /* r[10] = (a[1]*b[1]) */ +# ifdef BN_MUL_COMBA + if (n == 8) { + bn_mul_comba8(&(t[0]), &(r[0]), &(r[n])); + bn_mul_comba8(r, &(a[n]), &(b[n])); + } else +# endif + { + bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2])); + bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2])); + } + + /*- + * s0 == low(al*bl) + * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl) + * We know s0 and s1 so the only unknown is high(al*bl) + * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl)) + * high(al*bl) == s1 - (r[0]+l[0]+t[0]) + */ + if (l != NULL) { + lp = &(t[n2 + n]); + c1 = (int)(bn_add_words(lp, &(r[0]), &(l[0]), n)); + } else { + c1 = 0; + lp = &(r[0]); + } + + if (neg) + neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n)); + else { + bn_add_words(&(t[n2]), lp, &(t[0]), n); + neg = 0; + } + + if (l != NULL) { + bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n); + } else { + lp = &(t[n2 + n]); + mp = &(t[n2]); + for (i = 0; i < n; i++) + lp[i] = ((~mp[i]) + 1) & BN_MASK2; + } + + /*- + * s[0] = low(al*bl) + * t[3] = high(al*bl) + * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign + * r[10] = (a[1]*b[1]) + */ + /*- + * R[10] = al*bl + * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0]) + * R[32] = ah*bh + */ + /*- + * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow) + * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow) + * R[3]=r[1]+(carry/borrow) + */ + if (l != NULL) { + lp = &(t[n2]); + c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n)); + } else { + lp = &(t[n2 + n]); + c1 = 0; + } + c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n)); + if (oneg) + c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n)); + else + c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n)); + + c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n)); + c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n)); + if (oneg) + c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n)); + else + c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n)); + + if (c1 != 0) { /* Add starting at r[0], could be +ve or -ve */ + i = 0; + if (c1 > 0) { + lc = c1; + do { + ll = (r[i] + lc) & BN_MASK2; + r[i++] = ll; + lc = (lc > ll); + } while (lc); + } else { + lc = -c1; + do { + ll = r[i]; + r[i++] = (ll - lc) & BN_MASK2; + lc = (lc > ll); + } while (lc); + } + } + if (c2 != 0) { /* Add starting at r[1] */ + i = n; + if (c2 > 0) { + lc = c2; + do { + ll = (r[i] + lc) & BN_MASK2; + r[i++] = ll; + lc = (lc > ll); + } while (lc); + } else { + lc = -c2; + do { + ll = r[i]; + r[i++] = (ll - lc) & BN_MASK2; + lc = (lc > ll); + } while (lc); + } + } +} +#endif /* BN_RECURSION */ + +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + int ret = bn_mul_fixed_top(r, a, b, ctx); + + bn_correct_top(r); + bn_check_top(r); + + return ret; +} + +int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + int top, al, bl; + BIGNUM *rr; +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) + int i; +#endif +#ifdef BN_RECURSION + BIGNUM *t = NULL; + int j = 0, k; +#endif + +#ifdef BN_COUNT + fprintf(stderr, "BN_mul %d * %d\n", a->top, b->top); +#endif + + bn_check_top(a); + bn_check_top(b); + bn_check_top(r); + + al = a->top; + bl = b->top; + + if ((al == 0) || (bl == 0)) { + BN_zero(r); + return (1); + } + top = al + bl; + + BN_CTX_start(ctx); + if ((r == a) || (r == b)) { + if ((rr = BN_CTX_get(ctx)) == NULL) + goto err; + } else + rr = r; + rr->neg = a->neg ^ b->neg; + +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) + i = al - bl; +#endif +#ifdef BN_MUL_COMBA + if (i == 0) { +# if 0 + if (al == 4) { + if (bn_wexpand(rr, 8) == NULL) + goto err; + rr->top = 8; + bn_mul_comba4(rr->d, a->d, b->d); + goto end; + } +# endif + if (al == 8) { + if (bn_wexpand(rr, 16) == NULL) + goto err; + rr->top = 16; + bn_mul_comba8(rr->d, a->d, b->d); + goto end; + } + } +#endif /* BN_MUL_COMBA */ +#ifdef BN_RECURSION + if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) { + if (i >= -1 && i <= 1) { + /* + * Find out the power of two lower or equal to the longest of the + * two numbers + */ + if (i >= 0) { + j = BN_num_bits_word((BN_ULONG)al); + } + if (i == -1) { + j = BN_num_bits_word((BN_ULONG)bl); + } + j = 1 << (j - 1); + assert(j <= al || j <= bl); + k = j + j; + t = BN_CTX_get(ctx); + if (t == NULL) + goto err; + if (al > j || bl > j) { + if (bn_wexpand(t, k * 4) == NULL) + goto err; + if (bn_wexpand(rr, k * 4) == NULL) + goto err; + bn_mul_part_recursive(rr->d, a->d, b->d, + j, al - j, bl - j, t->d); + } else { /* al <= j || bl <= j */ + + if (bn_wexpand(t, k * 2) == NULL) + goto err; + if (bn_wexpand(rr, k * 2) == NULL) + goto err; + bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); + } + rr->top = top; + goto end; + } + } +#endif /* BN_RECURSION */ + if (bn_wexpand(rr, top) == NULL) + goto err; + rr->top = top; + bn_mul_normal(rr->d, a->d, al, b->d, bl); + +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) + end: +#endif + rr->flags |= BN_FLG_FIXED_TOP; + if (r != rr && BN_copy(r, rr) == NULL) + goto err; + + ret = 1; + err: + bn_check_top(r); + BN_CTX_end(ctx); + return (ret); +} + +void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) +{ + BN_ULONG *rr; + +#ifdef BN_COUNT + fprintf(stderr, " bn_mul_normal %d * %d\n", na, nb); +#endif + + if (na < nb) { + int itmp; + BN_ULONG *ltmp; + + itmp = na; + na = nb; + nb = itmp; + ltmp = a; + a = b; + b = ltmp; + + } + rr = &(r[na]); + if (nb <= 0) { + (void)bn_mul_words(r, a, na, 0); + return; + } else + rr[0] = bn_mul_words(r, a, na, b[0]); + + for (;;) { + if (--nb <= 0) + return; + rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]); + if (--nb <= 0) + return; + rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]); + if (--nb <= 0) + return; + rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]); + if (--nb <= 0) + return; + rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]); + rr += 4; + r += 4; + b += 4; + } +} + +void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +{ +#ifdef BN_COUNT + fprintf(stderr, " bn_mul_low_normal %d * %d\n", n, n); +#endif + bn_mul_words(r, a, n, b[0]); + + for (;;) { + if (--n <= 0) + return; + bn_mul_add_words(&(r[1]), a, n, b[1]); + if (--n <= 0) + return; + bn_mul_add_words(&(r[2]), a, n, b[2]); + if (--n <= 0) + return; + bn_mul_add_words(&(r[3]), a, n, b[3]); + if (--n <= 0) + return; + bn_mul_add_words(&(r[4]), a, n, b[4]); + r += 4; + b += 4; + } +} +/* crypto/bn/bn_nist.c */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "bn_lcl.h" +// #include "cryptlib.h" + +#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 +#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 +#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 +#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2 +#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2 + +/* pre-computed tables are "carry-less" values of modulus*(i+1) */ +#if BN_BITS2 == 64 +static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { + {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL}, + {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL}, + {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL} +}; + +static const BN_ULONG _nist_p_192_sqr[] = { + 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL, + 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL +}; + +static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { + {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL, + 0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL}, + {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is + * "carry-full" */ +}; + +static const BN_ULONG _nist_p_224_sqr[] = { + 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL, + 0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL, + 0xFFFFFFFFFFFFFFFFULL +}; + +static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { + {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFF00000001ULL}, + {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFE00000002ULL}, + {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFD00000003ULL}, + {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFC00000004ULL}, + {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFB00000005ULL}, +}; + +static const BN_ULONG _nist_p_256_sqr[] = { + 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL, + 0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL, + 0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL +}; + +static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { + {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, + {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, + {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, + {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, + {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, +}; + +static const BN_ULONG _nist_p_384_sqr[] = { + 0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL, + 0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL, + 0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL +}; + +static const BN_ULONG _nist_p_521[] = + { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0x00000000000001FFULL +}; + +static const BN_ULONG _nist_p_521_sqr[] = { + 0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, + 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, + 0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL +}; +#elif BN_BITS2 == 32 +static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { + {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +}; + +static const BN_ULONG _nist_p_192_sqr[] = { + 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000, + 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { + {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +}; + +static const BN_ULONG _nist_p_224_sqr[] = { + 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF +}; + +static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { + {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF}, + {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, + 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE}, + {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, + 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD}, + {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, + 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC}, + {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, + 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB}, +}; + +static const BN_ULONG _nist_p_256_sqr[] = { + 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, + 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, + 0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE +}; + +static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { + {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, +}; + +static const BN_ULONG _nist_p_384_sqr[] = { + 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE, + 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +static const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x000001FF +}; + +static const BN_ULONG _nist_p_521_sqr[] = { + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF +}; +#else +# error "unsupported BN_BITS2" +#endif + +static const BIGNUM _bignum_nist_p_192 = { + (BN_ULONG *)_nist_p_192[0], + BN_NIST_192_TOP, + BN_NIST_192_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_nist_p_224 = { + (BN_ULONG *)_nist_p_224[0], + BN_NIST_224_TOP, + BN_NIST_224_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_nist_p_256 = { + (BN_ULONG *)_nist_p_256[0], + BN_NIST_256_TOP, + BN_NIST_256_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_nist_p_384 = { + (BN_ULONG *)_nist_p_384[0], + BN_NIST_384_TOP, + BN_NIST_384_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_nist_p_521 = { + (BN_ULONG *)_nist_p_521, + BN_NIST_521_TOP, + BN_NIST_521_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +const BIGNUM *BN_get0_nist_prime_192(void) +{ + return &_bignum_nist_p_192; +} + +const BIGNUM *BN_get0_nist_prime_224(void) +{ + return &_bignum_nist_p_224; +} + +const BIGNUM *BN_get0_nist_prime_256(void) +{ + return &_bignum_nist_p_256; +} + +const BIGNUM *BN_get0_nist_prime_384(void) +{ + return &_bignum_nist_p_384; +} + +const BIGNUM *BN_get0_nist_prime_521(void) +{ + return &_bignum_nist_p_521; +} + +static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max) +{ + int i; + +#ifdef BN_DEBUG + OPENSSL_assert(top <= max); +#endif + for (i = 0; i < top; i++) + dst[i] = src[i]; + for (; i < max; i++) + dst[i] = 0; +} + +static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top) +{ + int i; + + for (i = 0; i < top; i++) + dst[i] = src[i]; +} + +#if BN_BITS2 == 64 +# define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; +# define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0; +/* + * two following macros are implemented under assumption that they + * are called in a sequence with *ascending* n, i.e. as they are... + */ +# define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\ + :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l))) +# define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0)); +# define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n) +# if defined(L_ENDIAN) +# if defined(__arch64__) +# define NIST_INT64 long +# else +# define NIST_INT64 long long +# endif +# endif +#else +# define bn_cp_64(to, n, from, m) \ + { \ + bn_cp_32(to, (n)*2, from, (m)*2); \ + bn_cp_32(to, (n)*2+1, from, (m)*2+1); \ + } +# define bn_64_set_0(to, n) \ + { \ + bn_32_set_0(to, (n)*2); \ + bn_32_set_0(to, (n)*2+1); \ + } +# define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; +# define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0; +# if defined(_WIN32) && !defined(__GNUC__) +# define NIST_INT64 __int64 +# elif defined(BN_LLONG) +# define NIST_INT64 long long +# endif +#endif /* BN_BITS2 != 64 */ + +#define nist_set_192(to, from, a1, a2, a3) \ + { \ + bn_cp_64(to, 0, from, (a3) - 3) \ + bn_cp_64(to, 1, from, (a2) - 3) \ + bn_cp_64(to, 2, from, (a1) - 3) \ + } + +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int top = a->top, i; + int carry; + register BN_ULONG *r_d, *a_d = a->d; + union { + BN_ULONG bn[BN_NIST_192_TOP]; + unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) / + sizeof(unsigned int)]; + } buf; + BN_ULONG c_d[BN_NIST_192_TOP], *res; + PTR_SIZE_INT mask; + static const BIGNUM _bignum_nist_p_192_sqr = { + (BN_ULONG *)_nist_p_192_sqr, + sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]), + sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_192; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_192_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_192_TOP); + } else + r_d = a_d; + + nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, + BN_NIST_192_TOP); + +#if defined(NIST_INT64) + { + NIST_INT64 acc; /* accumulator */ + unsigned int *rp = (unsigned int *)r_d; + const unsigned int *bp = (const unsigned int *)buf.ui; + + acc = rp[0]; + acc += bp[3 * 2 - 6]; + acc += bp[5 * 2 - 6]; + rp[0] = (unsigned int)acc; + acc >>= 32; + + acc += rp[1]; + acc += bp[3 * 2 - 5]; + acc += bp[5 * 2 - 5]; + rp[1] = (unsigned int)acc; + acc >>= 32; + + acc += rp[2]; + acc += bp[3 * 2 - 6]; + acc += bp[4 * 2 - 6]; + acc += bp[5 * 2 - 6]; + rp[2] = (unsigned int)acc; + acc >>= 32; + + acc += rp[3]; + acc += bp[3 * 2 - 5]; + acc += bp[4 * 2 - 5]; + acc += bp[5 * 2 - 5]; + rp[3] = (unsigned int)acc; + acc >>= 32; + + acc += rp[4]; + acc += bp[4 * 2 - 6]; + acc += bp[5 * 2 - 6]; + rp[4] = (unsigned int)acc; + acc >>= 32; + + acc += rp[5]; + acc += bp[4 * 2 - 5]; + acc += bp[5 * 2 - 5]; + rp[5] = (unsigned int)acc; + + carry = (int)(acc >> 32); + } +#else + { + BN_ULONG t_d[BN_NIST_192_TOP]; + + nist_set_192(t_d, buf.bn, 0, 3, 3); + carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); + nist_set_192(t_d, buf.bn, 4, 4, 0); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); + nist_set_192(t_d, buf.bn, 5, 5, 5) + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); + } +#endif + if (carry > 0) + carry = + (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1], + BN_NIST_192_TOP); + else + carry = 1; + + /* + * we need 'if (carry==0 || result>=modulus) result-=modulus;' + * as comparison implies subtraction, we can write + * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;' + * this is what happens below, but without explicit if:-) a. + */ + mask = + 0 - (PTR_SIZE_INT) bn_sub_words(c_d, r_d, _nist_p_192[0], + BN_NIST_192_TOP); + mask &= 0 - (PTR_SIZE_INT) carry; + res = c_d; + res = (BN_ULONG *) + (((PTR_SIZE_INT) res & ~mask) | ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_192_TOP); + r->top = BN_NIST_192_TOP; + bn_correct_top(r); + + return 1; +} + +typedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *, + const BN_ULONG *, int); + +#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \ + { \ + bn_cp_32(to, 0, from, (a7) - 7) \ + bn_cp_32(to, 1, from, (a6) - 7) \ + bn_cp_32(to, 2, from, (a5) - 7) \ + bn_cp_32(to, 3, from, (a4) - 7) \ + bn_cp_32(to, 4, from, (a3) - 7) \ + bn_cp_32(to, 5, from, (a2) - 7) \ + bn_cp_32(to, 6, from, (a1) - 7) \ + } + +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int top = a->top, i; + int carry; + BN_ULONG *r_d, *a_d = a->d; + union { + BN_ULONG bn[BN_NIST_224_TOP]; + unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) / + sizeof(unsigned int)]; + } buf; + BN_ULONG c_d[BN_NIST_224_TOP], *res; + PTR_SIZE_INT mask; + union { + bn_addsub_f f; + PTR_SIZE_INT p; + } u; + static const BIGNUM _bignum_nist_p_224_sqr = { + (BN_ULONG *)_nist_p_224_sqr, + sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]), + sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_224; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_224_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_224_TOP); + } else + r_d = a_d; + +#if BN_BITS2==64 + /* copy upper 256 bits of 448 bit number ... */ + nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1), + top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP); + /* ... and right shift by 32 to obtain upper 224 bits */ + nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8); + /* truncate lower part to 224 bits too */ + r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l; +#else + nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, + BN_NIST_224_TOP); +#endif + +#if defined(NIST_INT64) && BN_BITS2!=64 + { + NIST_INT64 acc; /* accumulator */ + unsigned int *rp = (unsigned int *)r_d; + const unsigned int *bp = (const unsigned int *)buf.ui; + + acc = rp[0]; + acc -= bp[7 - 7]; + acc -= bp[11 - 7]; + rp[0] = (unsigned int)acc; + acc >>= 32; + + acc += rp[1]; + acc -= bp[8 - 7]; + acc -= bp[12 - 7]; + rp[1] = (unsigned int)acc; + acc >>= 32; + + acc += rp[2]; + acc -= bp[9 - 7]; + acc -= bp[13 - 7]; + rp[2] = (unsigned int)acc; + acc >>= 32; + + acc += rp[3]; + acc += bp[7 - 7]; + acc += bp[11 - 7]; + acc -= bp[10 - 7]; + rp[3] = (unsigned int)acc; + acc >>= 32; + + acc += rp[4]; + acc += bp[8 - 7]; + acc += bp[12 - 7]; + acc -= bp[11 - 7]; + rp[4] = (unsigned int)acc; + acc >>= 32; + + acc += rp[5]; + acc += bp[9 - 7]; + acc += bp[13 - 7]; + acc -= bp[12 - 7]; + rp[5] = (unsigned int)acc; + acc >>= 32; + + acc += rp[6]; + acc += bp[10 - 7]; + acc -= bp[13 - 7]; + rp[6] = (unsigned int)acc; + + carry = (int)(acc >> 32); +# if BN_BITS2==64 + rp[7] = carry; +# endif + } +#else + { + BN_ULONG t_d[BN_NIST_224_TOP]; + + nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0); + carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); + nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); + nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); + nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); + +# if BN_BITS2==64 + carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32); +# endif + } +#endif + u.f = bn_sub_words; + if (carry > 0) { + carry = + (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1], + BN_NIST_224_TOP); +#if BN_BITS2==64 + carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1; +#endif + } else if (carry < 0) { + /* + * it's a bit more comlicated logic in this case. if bn_add_words + * yields no carry, then result has to be adjusted by unconditionally + * *adding* the modulus. but if it does, then result has to be + * compared to the modulus and conditionally adjusted by + * *subtracting* the latter. + */ + carry = + (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1], + BN_NIST_224_TOP); + mask = 0 - (PTR_SIZE_INT) carry; + u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | + ((PTR_SIZE_INT) bn_add_words & ~mask); + } else + carry = 1; + + /* otherwise it's effectively same as in BN_nist_mod_192... */ + mask = + 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP); + mask &= 0 - (PTR_SIZE_INT) carry; + res = c_d; + res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | + ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_224_TOP); + r->top = BN_NIST_224_TOP; + bn_correct_top(r); + + return 1; +} + +#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \ + { \ + bn_cp_32(to, 0, from, (a8) - 8) \ + bn_cp_32(to, 1, from, (a7) - 8) \ + bn_cp_32(to, 2, from, (a6) - 8) \ + bn_cp_32(to, 3, from, (a5) - 8) \ + bn_cp_32(to, 4, from, (a4) - 8) \ + bn_cp_32(to, 5, from, (a3) - 8) \ + bn_cp_32(to, 6, from, (a2) - 8) \ + bn_cp_32(to, 7, from, (a1) - 8) \ + } + +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int i, top = a->top; + int carry = 0; + register BN_ULONG *a_d = a->d, *r_d; + union { + BN_ULONG bn[BN_NIST_256_TOP]; + unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) / + sizeof(unsigned int)]; + } buf; + BN_ULONG c_d[BN_NIST_256_TOP], *res; + PTR_SIZE_INT mask; + union { + bn_addsub_f f; + PTR_SIZE_INT p; + } u; + static const BIGNUM _bignum_nist_p_256_sqr = { + (BN_ULONG *)_nist_p_256_sqr, + sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]), + sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_256; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_256_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_256_TOP); + } else + r_d = a_d; + + nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, + BN_NIST_256_TOP); + +#if defined(NIST_INT64) + { + NIST_INT64 acc; /* accumulator */ + unsigned int *rp = (unsigned int *)r_d; + const unsigned int *bp = (const unsigned int *)buf.ui; + + acc = rp[0]; + acc += bp[8 - 8]; + acc += bp[9 - 8]; + acc -= bp[11 - 8]; + acc -= bp[12 - 8]; + acc -= bp[13 - 8]; + acc -= bp[14 - 8]; + rp[0] = (unsigned int)acc; + acc >>= 32; + + acc += rp[1]; + acc += bp[9 - 8]; + acc += bp[10 - 8]; + acc -= bp[12 - 8]; + acc -= bp[13 - 8]; + acc -= bp[14 - 8]; + acc -= bp[15 - 8]; + rp[1] = (unsigned int)acc; + acc >>= 32; + + acc += rp[2]; + acc += bp[10 - 8]; + acc += bp[11 - 8]; + acc -= bp[13 - 8]; + acc -= bp[14 - 8]; + acc -= bp[15 - 8]; + rp[2] = (unsigned int)acc; + acc >>= 32; + + acc += rp[3]; + acc += bp[11 - 8]; + acc += bp[11 - 8]; + acc += bp[12 - 8]; + acc += bp[12 - 8]; + acc += bp[13 - 8]; + acc -= bp[15 - 8]; + acc -= bp[8 - 8]; + acc -= bp[9 - 8]; + rp[3] = (unsigned int)acc; + acc >>= 32; + + acc += rp[4]; + acc += bp[12 - 8]; + acc += bp[12 - 8]; + acc += bp[13 - 8]; + acc += bp[13 - 8]; + acc += bp[14 - 8]; + acc -= bp[9 - 8]; + acc -= bp[10 - 8]; + rp[4] = (unsigned int)acc; + acc >>= 32; + + acc += rp[5]; + acc += bp[13 - 8]; + acc += bp[13 - 8]; + acc += bp[14 - 8]; + acc += bp[14 - 8]; + acc += bp[15 - 8]; + acc -= bp[10 - 8]; + acc -= bp[11 - 8]; + rp[5] = (unsigned int)acc; + acc >>= 32; + + acc += rp[6]; + acc += bp[14 - 8]; + acc += bp[14 - 8]; + acc += bp[15 - 8]; + acc += bp[15 - 8]; + acc += bp[14 - 8]; + acc += bp[13 - 8]; + acc -= bp[8 - 8]; + acc -= bp[9 - 8]; + rp[6] = (unsigned int)acc; + acc >>= 32; + + acc += rp[7]; + acc += bp[15 - 8]; + acc += bp[15 - 8]; + acc += bp[15 - 8]; + acc += bp[8 - 8]; + acc -= bp[10 - 8]; + acc -= bp[11 - 8]; + acc -= bp[12 - 8]; + acc -= bp[13 - 8]; + rp[7] = (unsigned int)acc; + + carry = (int)(acc >> 32); + } +#else + { + BN_ULONG t_d[BN_NIST_256_TOP]; + + /* + * S1 + */ + nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0); + /* + * S2 + */ + nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0); + carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP); + /* left shift */ + { + register BN_ULONG *ap, t, c; + ap = t_d; + c = 0; + for (i = BN_NIST_256_TOP; i != 0; --i) { + t = *ap; + *(ap++) = ((t << 1) | c) & BN_MASK2; + c = (t & BN_TBIT) ? 1 : 0; + } + carry <<= 1; + carry |= c; + } + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * S3 + */ + nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * S4 + */ + nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * D1 + */ + nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * D2 + */ + nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * D3 + */ + nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * D4 + */ + nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); + + } +#endif + /* see BN_nist_mod_224 for explanation */ + u.f = bn_sub_words; + if (carry > 0) + carry = + (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1], + BN_NIST_256_TOP); + else if (carry < 0) { + carry = + (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1], + BN_NIST_256_TOP); + mask = 0 - (PTR_SIZE_INT) carry; + u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | + ((PTR_SIZE_INT) bn_add_words & ~mask); + } else + carry = 1; + + mask = + 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP); + mask &= 0 - (PTR_SIZE_INT) carry; + res = c_d; + res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | + ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_256_TOP); + r->top = BN_NIST_256_TOP; + bn_correct_top(r); + + return 1; +} + +#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \ + { \ + bn_cp_32(to, 0, from, (a12) - 12) \ + bn_cp_32(to, 1, from, (a11) - 12) \ + bn_cp_32(to, 2, from, (a10) - 12) \ + bn_cp_32(to, 3, from, (a9) - 12) \ + bn_cp_32(to, 4, from, (a8) - 12) \ + bn_cp_32(to, 5, from, (a7) - 12) \ + bn_cp_32(to, 6, from, (a6) - 12) \ + bn_cp_32(to, 7, from, (a5) - 12) \ + bn_cp_32(to, 8, from, (a4) - 12) \ + bn_cp_32(to, 9, from, (a3) - 12) \ + bn_cp_32(to, 10, from, (a2) - 12) \ + bn_cp_32(to, 11, from, (a1) - 12) \ + } + +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int i, top = a->top; + int carry = 0; + register BN_ULONG *r_d, *a_d = a->d; + union { + BN_ULONG bn[BN_NIST_384_TOP]; + unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) / + sizeof(unsigned int)]; + } buf; + BN_ULONG c_d[BN_NIST_384_TOP], *res; + PTR_SIZE_INT mask; + union { + bn_addsub_f f; + PTR_SIZE_INT p; + } u; + static const BIGNUM _bignum_nist_p_384_sqr = { + (BN_ULONG *)_nist_p_384_sqr, + sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]), + sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_384; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_384_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_384_TOP); + } else + r_d = a_d; + + nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, + BN_NIST_384_TOP); + +#if defined(NIST_INT64) + { + NIST_INT64 acc; /* accumulator */ + unsigned int *rp = (unsigned int *)r_d; + const unsigned int *bp = (const unsigned int *)buf.ui; + + acc = rp[0]; + acc += bp[12 - 12]; + acc += bp[21 - 12]; + acc += bp[20 - 12]; + acc -= bp[23 - 12]; + rp[0] = (unsigned int)acc; + acc >>= 32; + + acc += rp[1]; + acc += bp[13 - 12]; + acc += bp[22 - 12]; + acc += bp[23 - 12]; + acc -= bp[12 - 12]; + acc -= bp[20 - 12]; + rp[1] = (unsigned int)acc; + acc >>= 32; + + acc += rp[2]; + acc += bp[14 - 12]; + acc += bp[23 - 12]; + acc -= bp[13 - 12]; + acc -= bp[21 - 12]; + rp[2] = (unsigned int)acc; + acc >>= 32; + + acc += rp[3]; + acc += bp[15 - 12]; + acc += bp[12 - 12]; + acc += bp[20 - 12]; + acc += bp[21 - 12]; + acc -= bp[14 - 12]; + acc -= bp[22 - 12]; + acc -= bp[23 - 12]; + rp[3] = (unsigned int)acc; + acc >>= 32; + + acc += rp[4]; + acc += bp[21 - 12]; + acc += bp[21 - 12]; + acc += bp[16 - 12]; + acc += bp[13 - 12]; + acc += bp[12 - 12]; + acc += bp[20 - 12]; + acc += bp[22 - 12]; + acc -= bp[15 - 12]; + acc -= bp[23 - 12]; + acc -= bp[23 - 12]; + rp[4] = (unsigned int)acc; + acc >>= 32; + + acc += rp[5]; + acc += bp[22 - 12]; + acc += bp[22 - 12]; + acc += bp[17 - 12]; + acc += bp[14 - 12]; + acc += bp[13 - 12]; + acc += bp[21 - 12]; + acc += bp[23 - 12]; + acc -= bp[16 - 12]; + rp[5] = (unsigned int)acc; + acc >>= 32; + + acc += rp[6]; + acc += bp[23 - 12]; + acc += bp[23 - 12]; + acc += bp[18 - 12]; + acc += bp[15 - 12]; + acc += bp[14 - 12]; + acc += bp[22 - 12]; + acc -= bp[17 - 12]; + rp[6] = (unsigned int)acc; + acc >>= 32; + + acc += rp[7]; + acc += bp[19 - 12]; + acc += bp[16 - 12]; + acc += bp[15 - 12]; + acc += bp[23 - 12]; + acc -= bp[18 - 12]; + rp[7] = (unsigned int)acc; + acc >>= 32; + + acc += rp[8]; + acc += bp[20 - 12]; + acc += bp[17 - 12]; + acc += bp[16 - 12]; + acc -= bp[19 - 12]; + rp[8] = (unsigned int)acc; + acc >>= 32; + + acc += rp[9]; + acc += bp[21 - 12]; + acc += bp[18 - 12]; + acc += bp[17 - 12]; + acc -= bp[20 - 12]; + rp[9] = (unsigned int)acc; + acc >>= 32; + + acc += rp[10]; + acc += bp[22 - 12]; + acc += bp[19 - 12]; + acc += bp[18 - 12]; + acc -= bp[21 - 12]; + rp[10] = (unsigned int)acc; + acc >>= 32; + + acc += rp[11]; + acc += bp[23 - 12]; + acc += bp[20 - 12]; + acc += bp[19 - 12]; + acc -= bp[22 - 12]; + rp[11] = (unsigned int)acc; + + carry = (int)(acc >> 32); + } +#else + { + BN_ULONG t_d[BN_NIST_384_TOP]; + + /* + * S1 + */ + nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4); + /* left shift */ + { + register BN_ULONG *ap, t, c; + ap = t_d; + c = 0; + for (i = 3; i != 0; --i) { + t = *ap; + *(ap++) = ((t << 1) | c) & BN_MASK2; + c = (t & BN_TBIT) ? 1 : 0; + } + *ap = c; + } + carry = + (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2), + t_d, BN_NIST_256_TOP); + /* + * S2 + */ + carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP); + /* + * S3 + */ + nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, + 21); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * S4 + */ + nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23, + 0); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * S5 + */ + nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * S6 + */ + nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * D1 + */ + nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, + 23); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * D2 + */ + nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * D3 + */ + nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); + + } +#endif + /* see BN_nist_mod_224 for explanation */ + u.f = bn_sub_words; + if (carry > 0) + carry = + (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1], + BN_NIST_384_TOP); + else if (carry < 0) { + carry = + (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1], + BN_NIST_384_TOP); + mask = 0 - (PTR_SIZE_INT) carry; + u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | + ((PTR_SIZE_INT) bn_add_words & ~mask); + } else + carry = 1; + + mask = + 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP); + mask &= 0 - (PTR_SIZE_INT) carry; + res = c_d; + res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | + ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_384_TOP); + r->top = BN_NIST_384_TOP; + bn_correct_top(r); + + return 1; +} + +#define BN_NIST_521_RSHIFT (521%BN_BITS2) +#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT) +#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT) + +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int top = a->top, i; + BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res; + PTR_SIZE_INT mask; + static const BIGNUM _bignum_nist_p_521_sqr = { + (BN_ULONG *)_nist_p_521_sqr, + sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]), + sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_521; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_521_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_521_TOP); + } else + r_d = a_d; + + /* upper 521 bits, copy ... */ + nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1), + top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP); + /* ... and right shift */ + for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) { + t_d[i] = (val >> BN_NIST_521_RSHIFT | + (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2; + val = tmp; + } + t_d[i] = val >> BN_NIST_521_RSHIFT; + /* lower 521 bits */ + r_d[i] &= BN_NIST_521_TOP_MASK; + + bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP); + mask = + 0 - (PTR_SIZE_INT) bn_sub_words(t_d, r_d, _nist_p_521, + BN_NIST_521_TOP); + res = t_d; + res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | + ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_521_TOP); + r->top = BN_NIST_521_TOP; + bn_correct_top(r); + + return 1; +} +/* crypto/bn/bn_prime.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" +// #include "rand.h" + +/* + * NB: these functions have been "upgraded", the deprecated versions (which + * are compatibility wrappers using these functions) are in bn_depr.c. - + * Geoff + */ + +/* + * The quick sieve algorithm approach to weeding out primes is Philip + * Zimmermann's, as implemented in PGP. I have had a read of his comments + * and implemented my own version. + */ +#include "bn_prime.h" + +static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, + const BIGNUM *a1_odd, int k, BN_CTX *ctx, + BN_MONT_CTX *mont); +static int probable_prime(BIGNUM *rnd, int bits); +static int probable_prime_dh(BIGNUM *rnd, int bits, + const BIGNUM *add, const BIGNUM *rem, + BN_CTX *ctx); +static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add, + const BIGNUM *rem, BN_CTX *ctx); + +int BN_GENCB_call(BN_GENCB *cb, int a, int b) +{ + /* No callback means continue */ + if (!cb) + return 1; + switch (cb->ver) { + case 1: + /* Deprecated-style callbacks */ + if (!cb->cb.cb_1) + return 1; + cb->cb.cb_1(a, b, cb->arg); + return 1; + case 2: + /* New-style callbacks */ + return cb->cb.cb_2(a, b, cb); + default: + break; + } + /* Unrecognised callback type */ + return 0; +} + +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) +{ + BIGNUM *t; + int found = 0; + int i, j, c1 = 0; + BN_CTX *ctx; + int checks = BN_prime_checks_for_size(bits); + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (!t) + goto err; + loop: + /* make a random number and set the top and bottom bits */ + if (add == NULL) { + if (!probable_prime(ret, bits)) + goto err; + } else { + if (safe) { + if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) + goto err; + } else { + if (!probable_prime_dh(ret, bits, add, rem, ctx)) + goto err; + } + } + /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ + if (!BN_GENCB_call(cb, 0, c1++)) + /* aborted */ + goto err; + + if (!safe) { + i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); + if (i == -1) + goto err; + if (i == 0) + goto loop; + } else { + /* + * for "safe prime" generation, check that (p-1)/2 is prime. Since a + * prime is odd, We just need to divide by 2 + */ + if (!BN_rshift1(t, ret)) + goto err; + + for (i = 0; i < checks; i++) { + j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb); + if (j == -1) + goto err; + if (j == 0) + goto loop; + + j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb); + if (j == -1) + goto err; + if (j == 0) + goto loop; + + if (!BN_GENCB_call(cb, 2, c1 - 1)) + goto err; + /* We have a safe prime test pass */ + } + } + /* we have a prime :-) */ + found = 1; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + bn_check_top(ret); + return found; +} + +int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, + BN_GENCB *cb) +{ + return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb); +} + +int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, + int do_trial_division, BN_GENCB *cb) +{ + int i, j, ret = -1; + int k; + BN_CTX *ctx = NULL; + BIGNUM *A1, *A1_odd, *check; /* taken from ctx */ + BN_MONT_CTX *mont = NULL; + + if (BN_cmp(a, BN_value_one()) <= 0) + return 0; + + if (checks == BN_prime_checks) + checks = BN_prime_checks_for_size(BN_num_bits(a)); + + /* first look for small factors */ + if (!BN_is_odd(a)) + /* a is even => a is prime if and only if a == 2 */ + return BN_is_word(a, 2); + if (do_trial_division) { + for (i = 1; i < NUMPRIMES; i++) + if (BN_mod_word(a, primes[i]) == 0) + return 0; + if (!BN_GENCB_call(cb, 1, -1)) + goto err; + } + + if (ctx_passed != NULL) + ctx = ctx_passed; + else if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + + A1 = BN_CTX_get(ctx); + A1_odd = BN_CTX_get(ctx); + check = BN_CTX_get(ctx); + if (check == NULL) + goto err; + + /* compute A1 := a - 1 */ + if (!BN_copy(A1, a)) + goto err; + if (!BN_sub_word(A1, 1)) + goto err; + if (BN_is_zero(A1)) { + ret = 0; + goto err; + } + + /* write A1 as A1_odd * 2^k */ + k = 1; + while (!BN_is_bit_set(A1, k)) + k++; + if (!BN_rshift(A1_odd, A1, k)) + goto err; + + /* Montgomery setup for computations mod a */ + mont = BN_MONT_CTX_new(); + if (mont == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, a, ctx)) + goto err; + + for (i = 0; i < checks; i++) { + if (!BN_pseudo_rand_range(check, A1)) + goto err; + if (!BN_add_word(check, 1)) + goto err; + /* now 1 <= check < a */ + + j = witness(check, a, A1, A1_odd, k, ctx, mont); + if (j == -1) + goto err; + if (j) { + ret = 0; + goto err; + } + if (!BN_GENCB_call(cb, 1, i)) + goto err; + } + ret = 1; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + if (ctx_passed == NULL) + BN_CTX_free(ctx); + } + if (mont != NULL) + BN_MONT_CTX_free(mont); + + return (ret); +} + +static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, + const BIGNUM *a1_odd, int k, BN_CTX *ctx, + BN_MONT_CTX *mont) +{ + if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */ + return -1; + if (BN_is_one(w)) + return 0; /* probably prime */ + if (BN_cmp(w, a1) == 0) + return 0; /* w == -1 (mod a), 'a' is probably prime */ + while (--k) { + if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */ + return -1; + if (BN_is_one(w)) + return 1; /* 'a' is composite, otherwise a previous 'w' + * would have been == -1 (mod 'a') */ + if (BN_cmp(w, a1) == 0) + return 0; /* w == -1 (mod a), 'a' is probably prime */ + } + /* + * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and + * it is neither -1 nor +1 -- so 'a' cannot be prime + */ + bn_check_top(w); + return 1; +} + +static int probable_prime(BIGNUM *rnd, int bits) +{ + int i; + prime_t mods[NUMPRIMES]; + BN_ULONG delta, maxdelta; + + again: + if (!BN_rand(rnd, bits, 1, 1)) + return (0); + /* we now have a random number 'rand' to test. */ + for (i = 1; i < NUMPRIMES; i++) + mods[i] = (prime_t) BN_mod_word(rnd, (BN_ULONG)primes[i]); + maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; + delta = 0; + loop:for (i = 1; i < NUMPRIMES; i++) { + /* + * check that rnd is not a prime and also that gcd(rnd-1,primes) == 1 + * (except for 2) + */ + if (((mods[i] + delta) % primes[i]) <= 1) { + delta += 2; + if (delta > maxdelta) + goto again; + goto loop; + } + } + if (!BN_add_word(rnd, delta)) + return (0); + bn_check_top(rnd); + return (1); +} + +static int probable_prime_dh(BIGNUM *rnd, int bits, + const BIGNUM *add, const BIGNUM *rem, + BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *t1; + + BN_CTX_start(ctx); + if ((t1 = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_rand(rnd, bits, 0, 1)) + goto err; + + /* we need ((rnd-rem) % add) == 0 */ + + if (!BN_mod(t1, rnd, add, ctx)) + goto err; + if (!BN_sub(rnd, rnd, t1)) + goto err; + if (rem == NULL) { + if (!BN_add_word(rnd, 1)) + goto err; + } else { + if (!BN_add(rnd, rnd, rem)) + goto err; + } + + /* we now have a random number 'rand' to test. */ + + loop:for (i = 1; i < NUMPRIMES; i++) { + /* check that rnd is a prime */ + if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { + if (!BN_add(rnd, rnd, add)) + goto err; + goto loop; + } + } + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(rnd); + return (ret); +} + +static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, + const BIGNUM *rem, BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *t1, *qadd, *q; + + bits--; + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + qadd = BN_CTX_get(ctx); + if (qadd == NULL) + goto err; + + if (!BN_rshift1(qadd, padd)) + goto err; + + if (!BN_rand(q, bits, 0, 1)) + goto err; + + /* we need ((rnd-rem) % add) == 0 */ + if (!BN_mod(t1, q, qadd, ctx)) + goto err; + if (!BN_sub(q, q, t1)) + goto err; + if (rem == NULL) { + if (!BN_add_word(q, 1)) + goto err; + } else { + if (!BN_rshift1(t1, rem)) + goto err; + if (!BN_add(q, q, t1)) + goto err; + } + + /* we now have a random number 'rand' to test. */ + if (!BN_lshift1(p, q)) + goto err; + if (!BN_add_word(p, 1)) + goto err; + + loop:for (i = 1; i < NUMPRIMES; i++) { + /* check that p and q are prime */ + /* + * check that for p and q gcd(p-1,primes) == 1 (except for 2) + */ + if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) || + (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) { + if (!BN_add(p, p, padd)) + goto err; + if (!BN_add(q, q, qadd)) + goto err; + goto loop; + } + } + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(p); + return (ret); +} +/* crypto/bn/bn_print.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +// #include "cryptlib.h" +#include "buffer.h" +// #include "bn_lcl.h" + +static const char Hex[] = "0123456789ABCDEF"; + +/* Must 'OPENSSL_free' the returned data */ +char *BN_bn2hex(const BIGNUM *a) +{ + int i, j, v, z = 0; + char *buf; + char *p; + + if (BN_is_zero(a)) + return OPENSSL_strdup("0"); + buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); + if (buf == NULL) { + BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf; + if (a->neg) + *(p++) = '-'; + for (i = a->top - 1; i >= 0; i--) { + for (j = BN_BITS2 - 8; j >= 0; j -= 8) { + /* strip leading zeros */ + v = ((int)(a->d[i] >> (long)j)) & 0xff; + if (z || (v != 0)) { + *(p++) = Hex[v >> 4]; + *(p++) = Hex[v & 0x0f]; + z = 1; + } + } + } + *p = '\0'; + err: + return (buf); +} + +/* Must 'OPENSSL_free' the returned data */ +char *BN_bn2dec(const BIGNUM *a) +{ + int i = 0, num, ok = 0; + char *buf = NULL; + char *p; + BIGNUM *t = NULL; + BN_ULONG *bn_data = NULL, *lp; + int bn_data_num; + + /*- + * get an upper bound for the length of the decimal integer + * num <= (BN_num_bits(a) + 1) * log(2) + * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error) + * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1 + */ + i = BN_num_bits(a) * 3; + num = (i / 10 + i / 1000 + 1) + 1; + bn_data_num = num / BN_DEC_NUM + 1; + bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); + buf = OPENSSL_malloc(num + 3); + if ((buf == NULL) || (bn_data == NULL)) { + BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((t = BN_dup(a)) == NULL) + goto err; + +#define BUF_REMAIN (num+3 - (size_t)(p - buf)) + p = buf; + lp = bn_data; + if (BN_is_zero(t)) { + *(p++) = '0'; + *(p++) = '\0'; + } else { + if (BN_is_negative(t)) + *p++ = '-'; + + while (!BN_is_zero(t)) { + if (lp - bn_data >= bn_data_num) + goto err; + *lp = BN_div_word(t, BN_DEC_CONV); + if (*lp == (BN_ULONG)-1) + goto err; + lp++; + } + lp--; + /* + * We now have a series of blocks, BN_DEC_NUM chars in length, where + * the last one needs truncation. The blocks need to be reversed in + * order. + */ + BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp); + while (*p) + p++; + while (lp != bn_data) { + lp--; + BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp); + while (*p) + p++; + } + } + ok = 1; + err: + if (bn_data != NULL) + OPENSSL_free(bn_data); + if (t != NULL) + BN_free(t); + if (!ok && buf) { + OPENSSL_free(buf); + buf = NULL; + } + + return (buf); +} + +int BN_hex2bn(BIGNUM **bn, const char *a) +{ + BIGNUM *ret = NULL; + BN_ULONG l = 0; + int neg = 0, h, m, i, j, k, c; + int num; + + if ((a == NULL) || (*a == '\0')) + return (0); + + if (*a == '-') { + neg = 1; + a++; + } + + for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++) + continue; + + if (i > INT_MAX/4) + goto err; + + num = i + neg; + if (bn == NULL) + return (num); + + /* a is the start of the hex digits, and it is 'i' long */ + if (*bn == NULL) { + if ((ret = BN_new()) == NULL) + return (0); + } else { + ret = *bn; + BN_zero(ret); + } + + /* i is the number of hex digits */ + if (bn_expand(ret, i * 4) == NULL) + goto err; + + j = i; /* least significant 'hex' */ + m = 0; + h = 0; + while (j > 0) { + m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j; + l = 0; + for (;;) { + c = a[j - m]; + if ((c >= '0') && (c <= '9')) + k = c - '0'; + else if ((c >= 'a') && (c <= 'f')) + k = c - 'a' + 10; + else if ((c >= 'A') && (c <= 'F')) + k = c - 'A' + 10; + else + k = 0; /* paranoia */ + l = (l << 4) | k; + + if (--m <= 0) { + ret->d[h++] = l; + break; + } + } + j -= (BN_BYTES * 2); + } + ret->top = h; + bn_correct_top(ret); + + *bn = ret; + bn_check_top(ret); + /* Don't set the negative flag if it's zero. */ + if (ret->top != 0) + ret->neg = neg; + return (num); + err: + if (*bn == NULL) + BN_free(ret); + return (0); +} + +int BN_dec2bn(BIGNUM **bn, const char *a) +{ + BIGNUM *ret = NULL; + BN_ULONG l = 0; + int neg = 0, i, j; + int num; + + if ((a == NULL) || (*a == '\0')) + return (0); + if (*a == '-') { + neg = 1; + a++; + } + + for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++) + continue; + + if (i > INT_MAX/4) + goto err; + + num = i + neg; + if (bn == NULL) + return (num); + + /* + * a is the start of the digits, and it is 'i' long. We chop it into + * BN_DEC_NUM digits at a time + */ + if (*bn == NULL) { + if ((ret = BN_new()) == NULL) + return (0); + } else { + ret = *bn; + BN_zero(ret); + } + + /* i is the number of digits, a bit of an over expand */ + if (bn_expand(ret, i * 4) == NULL) + goto err; + + j = BN_DEC_NUM - (i % BN_DEC_NUM); + if (j == BN_DEC_NUM) + j = 0; + l = 0; + while (--i >= 0) { + l *= 10; + l += *a - '0'; + a++; + if (++j == BN_DEC_NUM) { + BN_mul_word(ret, BN_DEC_CONV); + BN_add_word(ret, l); + l = 0; + j = 0; + } + } + + bn_correct_top(ret); + *bn = ret; + bn_check_top(ret); + /* Don't set the negative flag if it's zero. */ + if (ret->top != 0) + ret->neg = neg; + return (num); + err: + if (*bn == NULL) + BN_free(ret); + return (0); +} + +int BN_asc2bn(BIGNUM **bn, const char *a) +{ + const char *p = a; + + if (*p == '-') + p++; + + if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) { + if (!BN_hex2bn(bn, p + 2)) + return 0; + } else { + if (!BN_dec2bn(bn, p)) + return 0; + } + /* Don't set the negative flag if it's zero. */ + if (*a == '-' && (*bn)->top != 0) + (*bn)->neg = 1; + return 1; +} + +#ifndef OPENSSL_NO_BIO +# ifndef OPENSSL_NO_FP_API +int BN_print_fp(FILE *fp, const BIGNUM *a) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) + return (0); + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = BN_print(b, a); + BIO_free(b); + return (ret); +} +# endif + +int BN_print(BIO *bp, const BIGNUM *a) +{ + int i, j, v, z = 0; + int ret = 0; + + if ((a->neg) && (BIO_write(bp, "-", 1) != 1)) + goto end; + if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1)) + goto end; + for (i = a->top - 1; i >= 0; i--) { + for (j = BN_BITS2 - 4; j >= 0; j -= 4) { + /* strip leading zeros */ + v = ((int)(a->d[i] >> (long)j)) & 0x0f; + if (z || (v != 0)) { + if (BIO_write(bp, &(Hex[v]), 1) != 1) + goto end; + z = 1; + } + } + } + ret = 1; + end: + return (ret); +} +#endif + +char *BN_options(void) +{ + static int init = 0; + static char data[16]; + + if (!init) { + init++; +#ifdef BN_LLONG + BIO_snprintf(data, sizeof(data), "bn(%d,%d)", + (int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8); +#else + BIO_snprintf(data, sizeof(data), "bn(%d,%d)", + (int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8); +#endif + } + return (data); +} +/* crypto/bn/bn_rand.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" +// #include "rand.h" + +static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) +{ + unsigned char *buf = NULL; + int ret = 0, bit, bytes, mask; + time_t tim; + + if (bits == 0) { + if (top != -1 || bottom != 0) + goto toosmall; + BN_zero(rnd); + return 1; + } + if (bits < 0 || (bits == 1 && top > 0)) + goto toosmall; + + bytes = (bits + 7) / 8; + bit = (bits - 1) % 8; + mask = 0xff << (bit + 1); + + buf = (unsigned char *)OPENSSL_malloc(bytes); + if (buf == NULL) { + BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* make a random number and set the top and bottom bits */ + time(&tim); + RAND_add(&tim, sizeof(tim), 0.0); + + /* We ignore the value of pseudorand and always call RAND_bytes */ + if (RAND_bytes(buf, bytes) <= 0) + goto err; + +#if 1 + if (pseudorand == 2) { + /* + * generate patterns that are more likely to trigger BN library bugs + */ + int i; + unsigned char c; + + for (i = 0; i < bytes; i++) { + if (RAND_pseudo_bytes(&c, 1) < 0) + goto err; + if (c >= 128 && i > 0) + buf[i] = buf[i - 1]; + else if (c < 42) + buf[i] = 0; + else if (c < 84) + buf[i] = 255; + } + } +#endif + + if (top >= 0) { + if (top) { + if (bit == 0) { + buf[0] = 1; + buf[1] |= 0x80; + } else { + buf[0] |= (3 << (bit - 1)); + } + } else { + buf[0] |= (1 << bit); + } + } + buf[0] &= ~mask; + if (bottom) /* set bottom bit if requested */ + buf[bytes - 1] |= 1; + if (!BN_bin2bn(buf, bytes, rnd)) + goto err; + ret = 1; + err: + if (buf != NULL) { + OPENSSL_cleanse(buf, bytes); + OPENSSL_free(buf); + } + bn_check_top(rnd); + return (ret); + +toosmall: + BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL); + return 0; +} + +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(0, rnd, bits, top, bottom); +} + +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(1, rnd, bits, top, bottom); +} + +#if 1 +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(2, rnd, bits, top, bottom); +} +#endif + +/* random number r: 0 <= r < range */ +static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range) +{ + int (*bn_rand) (BIGNUM *, int, int, int) = + pseudo ? BN_pseudo_rand : BN_rand; + int n; + int count = 100; + + if (range->neg || BN_is_zero(range)) { + BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE); + return 0; + } + + n = BN_num_bits(range); /* n > 0 */ + + /* BN_is_bit_set(range, n - 1) always holds */ + + if (n == 1) + BN_zero(r); + else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { + /* + * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer + * than range + */ + do { + if (!bn_rand(r, n + 1, -1, 0)) + return 0; + /* + * If r < 3*range, use r := r MOD range (which is either r, r - + * range, or r - 2*range). Otherwise, iterate once more. Since + * 3*range = 11..._2, each iteration succeeds with probability >= + * .75. + */ + if (BN_cmp(r, range) >= 0) { + if (!BN_sub(r, r, range)) + return 0; + if (BN_cmp(r, range) >= 0) + if (!BN_sub(r, r, range)) + return 0; + } + + if (!--count) { + BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS); + return 0; + } + + } + while (BN_cmp(r, range) >= 0); + } else { + do { + /* range = 11..._2 or range = 101..._2 */ + if (!bn_rand(r, n, -1, 0)) + return 0; + + if (!--count) { + BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS); + return 0; + } + } + while (BN_cmp(r, range) >= 0); + } + + bn_check_top(r); + return 1; +} + +int BN_rand_range(BIGNUM *r, const BIGNUM *range) +{ + return bn_rand_range(0, r, range); +} + +int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) +{ + return bn_rand_range(1, r, range); +} +/* crypto/bn/bn_recp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +void BN_RECP_CTX_init(BN_RECP_CTX *recp) +{ + BN_init(&(recp->N)); + BN_init(&(recp->Nr)); + recp->num_bits = 0; + recp->shift = 0; + recp->flags = 0; +} + +BN_RECP_CTX *BN_RECP_CTX_new(void) +{ + BN_RECP_CTX *ret; + + if ((ret = (BN_RECP_CTX *)OPENSSL_malloc(sizeof(BN_RECP_CTX))) == NULL) + return (NULL); + + BN_RECP_CTX_init(ret); + ret->flags = BN_FLG_MALLOCED; + return (ret); +} + +void BN_RECP_CTX_free(BN_RECP_CTX *recp) +{ + if (recp == NULL) + return; + + BN_free(&(recp->N)); + BN_free(&(recp->Nr)); + if (recp->flags & BN_FLG_MALLOCED) + OPENSSL_free(recp); +} + +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) +{ + if (!BN_copy(&(recp->N), d)) + return 0; + BN_zero(&(recp->Nr)); + recp->num_bits = BN_num_bits(d); + recp->shift = 0; + return (1); +} + +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *a; + const BIGNUM *ca; + + BN_CTX_start(ctx); + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if (y != NULL) { + if (x == y) { + if (!BN_sqr(a, x, ctx)) + goto err; + } else { + if (!BN_mul(a, x, y, ctx)) + goto err; + } + ca = a; + } else + ca = x; /* Just do the mod */ + + ret = BN_div_recp(NULL, r, ca, recp, ctx); + err: + BN_CTX_end(ctx); + bn_check_top(r); + return (ret); +} + +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx) +{ + int i, j, ret = 0; + BIGNUM *a, *b, *d, *r; + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + if (dv != NULL) + d = dv; + else + d = BN_CTX_get(ctx); + if (rem != NULL) + r = rem; + else + r = BN_CTX_get(ctx); + if (a == NULL || b == NULL || d == NULL || r == NULL) + goto err; + + if (BN_ucmp(m, &(recp->N)) < 0) { + BN_zero(d); + if (!BN_copy(r, m)) { + BN_CTX_end(ctx); + return 0; + } + BN_CTX_end(ctx); + return (1); + } + + /* + * We want the remainder Given input of ABCDEF / ab we need multiply + * ABCDEF by 3 digests of the reciprocal of ab + */ + + /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */ + i = BN_num_bits(m); + j = recp->num_bits << 1; + if (j > i) + i = j; + + /* Nr := round(2^i / N) */ + if (i != recp->shift) + recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx); + /* BN_reciprocal could have returned -1 for an error */ + if (recp->shift == -1) + goto err; + + /*- + * d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))| + * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))| + * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)| + * = |m/N| + */ + if (!BN_rshift(a, m, recp->num_bits)) + goto err; + if (!BN_mul(b, a, &(recp->Nr), ctx)) + goto err; + if (!BN_rshift(d, b, i - recp->num_bits)) + goto err; + d->neg = 0; + + if (!BN_mul(b, &(recp->N), d, ctx)) + goto err; + if (!BN_usub(r, m, b)) + goto err; + r->neg = 0; + +#if 1 + j = 0; + while (BN_ucmp(r, &(recp->N)) >= 0) { + if (j++ > 2) { + BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL); + goto err; + } + if (!BN_usub(r, r, &(recp->N))) + goto err; + if (!BN_add_word(d, 1)) + goto err; + } +#endif + + r->neg = BN_is_zero(r) ? 0 : m->neg; + d->neg = m->neg ^ recp->N.neg; + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(dv); + bn_check_top(rem); + return (ret); +} + +/* + * len is the expected size of the result We actually calculate with an extra + * word of precision, so we can do faster division if the remainder is not + * required. + */ +/* r := 2^len / m */ +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) +{ + int ret = -1; + BIGNUM *t; + + BN_CTX_start(ctx); + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_set_bit(t, len)) + goto err; + + if (!BN_div(r, NULL, t, m, ctx)) + goto err; + + ret = len; + err: + bn_check_top(r); + BN_CTX_end(ctx); + return (ret); +} +/* crypto/bn/bn_shift.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +int BN_lshift1(BIGNUM *r, const BIGNUM *a) +{ + register BN_ULONG *ap, *rp, t, c; + int i; + + bn_check_top(r); + bn_check_top(a); + + if (r != a) { + r->neg = a->neg; + if (bn_wexpand(r, a->top + 1) == NULL) + return (0); + r->top = a->top; + } else { + if (bn_wexpand(r, a->top + 1) == NULL) + return (0); + } + ap = a->d; + rp = r->d; + c = 0; + for (i = 0; i < a->top; i++) { + t = *(ap++); + *(rp++) = ((t << 1) | c) & BN_MASK2; + c = (t & BN_TBIT) ? 1 : 0; + } + if (c) { + *rp = 1; + r->top++; + } + bn_check_top(r); + return (1); +} + +int BN_rshift1(BIGNUM *r, const BIGNUM *a) +{ + BN_ULONG *ap, *rp, t, c; + int i, j; + + bn_check_top(r); + bn_check_top(a); + + if (BN_is_zero(a)) { + BN_zero(r); + return (1); + } + i = a->top; + ap = a->d; + j = i - (ap[i - 1] == 1); + if (a != r) { + if (bn_wexpand(r, j) == NULL) + return (0); + r->neg = a->neg; + } + rp = r->d; + t = ap[--i]; + c = (t & 1) ? BN_TBIT : 0; + if (t >>= 1) + rp[i] = t; + while (i > 0) { + t = ap[--i]; + rp[i] = ((t >> 1) & BN_MASK2) | c; + c = (t & 1) ? BN_TBIT : 0; + } + r->top = j; + bn_check_top(r); + return (1); +} + +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) +{ + int i, nw, lb, rb; + BN_ULONG *t, *f; + BN_ULONG l; + + bn_check_top(r); + bn_check_top(a); + + if (n < 0) { + BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT); + return 0; + } + + r->neg = a->neg; + nw = n / BN_BITS2; + if (bn_wexpand(r, a->top + nw + 1) == NULL) + return (0); + lb = n % BN_BITS2; + rb = BN_BITS2 - lb; + f = a->d; + t = r->d; + t[a->top + nw] = 0; + if (lb == 0) + for (i = a->top - 1; i >= 0; i--) + t[nw + i] = f[i]; + else + for (i = a->top - 1; i >= 0; i--) { + l = f[i]; + t[nw + i + 1] |= (l >> rb) & BN_MASK2; + t[nw + i] = (l << lb) & BN_MASK2; + } + memset(t, 0, nw * sizeof(t[0])); + /* + * for (i=0; itop = a->top + nw + 1; + bn_correct_top(r); + bn_check_top(r); + return (1); +} + +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) +{ + int i, j, nw, lb, rb; + BN_ULONG *t, *f; + BN_ULONG l, tmp; + + bn_check_top(r); + bn_check_top(a); + + if (n < 0) { + BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT); + return 0; + } + + nw = n / BN_BITS2; + rb = n % BN_BITS2; + lb = BN_BITS2 - rb; + if (nw >= a->top || a->top == 0) { + BN_zero(r); + return (1); + } + i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2; + if (r != a) { + r->neg = a->neg; + if (bn_wexpand(r, i) == NULL) + return (0); + } else { + if (n == 0) + return 1; /* or the copying loop will go berserk */ + } + + f = &(a->d[nw]); + t = r->d; + j = a->top - nw; + r->top = i; + + if (rb == 0) { + for (i = j; i != 0; i--) + *(t++) = *(f++); + } else { + l = *(f++); + for (i = j - 1; i != 0; i--) { + tmp = (l >> rb) & BN_MASK2; + l = *(f++); + *(t++) = (tmp | (l << lb)) & BN_MASK2; + } + if ((l = (l >> rb) & BN_MASK2)) + *(t) = l; + } + bn_check_top(r); + return (1); +} +/* crypto/bn/bn_sqr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +/* r must not be a */ +/* + * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 + */ +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) +{ + int ret = bn_sqr_fixed_top(r, a, ctx); + + bn_correct_top(r); + bn_check_top(r); + + return ret; +} + +int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) +{ + int max, al; + int ret = 0; + BIGNUM *tmp, *rr; + +#ifdef BN_COUNT + fprintf(stderr, "BN_sqr %d * %d\n", a->top, a->top); +#endif + bn_check_top(a); + + al = a->top; + if (al <= 0) { + r->top = 0; + r->neg = 0; + return 1; + } + + BN_CTX_start(ctx); + rr = (a != r) ? r : BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (!rr || !tmp) + goto err; + + max = 2 * al; /* Non-zero (from above) */ + if (bn_wexpand(rr, max) == NULL) + goto err; + + if (al == 4) { +#ifndef BN_SQR_COMBA + BN_ULONG t[8]; + bn_sqr_normal(rr->d, a->d, 4, t); +#else + bn_sqr_comba4(rr->d, a->d); +#endif + } else if (al == 8) { +#ifndef BN_SQR_COMBA + BN_ULONG t[16]; + bn_sqr_normal(rr->d, a->d, 8, t); +#else + bn_sqr_comba8(rr->d, a->d); +#endif + } else { +#if defined(BN_RECURSION) + if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) { + BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2]; + bn_sqr_normal(rr->d, a->d, al, t); + } else { + int j, k; + + j = BN_num_bits_word((BN_ULONG)al); + j = 1 << (j - 1); + k = j + j; + if (al == j) { + if (bn_wexpand(tmp, k * 2) == NULL) + goto err; + bn_sqr_recursive(rr->d, a->d, al, tmp->d); + } else { + if (bn_wexpand(tmp, max) == NULL) + goto err; + bn_sqr_normal(rr->d, a->d, al, tmp->d); + } + } +#else + if (bn_wexpand(tmp, max) == NULL) + goto err; + bn_sqr_normal(rr->d, a->d, al, tmp->d); +#endif + } + + rr->neg = 0; + rr->top = max; + rr->flags |= BN_FLG_FIXED_TOP; + if (r != rr && BN_copy(r, rr) == NULL) + goto err; + + ret = 1; + err: + bn_check_top(rr); + bn_check_top(tmp); + BN_CTX_end(ctx); + return (ret); +} + +/* tmp must have 2*n words */ +void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp) +{ + int i, j, max; + const BN_ULONG *ap; + BN_ULONG *rp; + + max = n * 2; + ap = a; + rp = r; + rp[0] = rp[max - 1] = 0; + rp++; + j = n; + + if (--j > 0) { + ap++; + rp[j] = bn_mul_words(rp, ap, j, ap[-1]); + rp += 2; + } + + for (i = n - 2; i > 0; i--) { + j--; + ap++; + rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]); + rp += 2; + } + + bn_add_words(r, r, r, max); + + /* There will not be a carry */ + + bn_sqr_words(tmp, a, n); + + bn_add_words(r, r, tmp, max); +} + +#ifdef BN_RECURSION +/*- + * r is 2*n words in size, + * a and b are both n words in size. (There's not actually a 'b' here ...) + * n must be a power of 2. + * We multiply and return the result. + * t must be 2*n words in size + * We calculate + * a[0]*b[0] + * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) + * a[1]*b[1] + */ +void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t) +{ + int n = n2 / 2; + int zero, c1; + BN_ULONG ln, lo, *p; + +# ifdef BN_COUNT + fprintf(stderr, " bn_sqr_recursive %d * %d\n", n2, n2); +# endif + if (n2 == 4) { +# ifndef BN_SQR_COMBA + bn_sqr_normal(r, a, 4, t); +# else + bn_sqr_comba4(r, a); +# endif + return; + } else if (n2 == 8) { +# ifndef BN_SQR_COMBA + bn_sqr_normal(r, a, 8, t); +# else + bn_sqr_comba8(r, a); +# endif + return; + } + if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) { + bn_sqr_normal(r, a, n2, t); + return; + } + /* r=(a[0]-a[1])*(a[1]-a[0]) */ + c1 = bn_cmp_words(a, &(a[n]), n); + zero = 0; + if (c1 > 0) + bn_sub_words(t, a, &(a[n]), n); + else if (c1 < 0) + bn_sub_words(t, &(a[n]), a, n); + else + zero = 1; + + /* The result will always be negative unless it is zero */ + p = &(t[n2 * 2]); + + if (!zero) + bn_sqr_recursive(&(t[n2]), t, n, p); + else + memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG)); + bn_sqr_recursive(r, a, n, p); + bn_sqr_recursive(&(r[n2]), &(a[n]), n, p); + + /*- + * t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + */ + + c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); + + /* t[32] is negative */ + c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); + + /*- + * t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1]) + * r[10] holds (a[0]*a[0]) + * r[32] holds (a[1]*a[1]) + * c1 holds the carry bits + */ + c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); + if (c1) { + p = &(r[n + n2]); + lo = *p; + ln = (lo + c1) & BN_MASK2; + *p = ln; + + /* + * The overflow will stop before we over write words we should not + * overwrite + */ + if (ln < (BN_ULONG)c1) { + do { + p++; + lo = *p; + ln = (lo + 1) & BN_MASK2; + *p = ln; + } while (ln == 0); + } + } +} +#endif +/* crypto/bn/bn_sqrt.c */ +/* + * Written by Lenka Fibikova and Bodo + * Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "bn_lcl.h" + +BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +/* + * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks + * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number + * Theory", algorithm 1.5.1). 'p' must be prime! + */ +{ + BIGNUM *ret = in; + int err = 1; + int r; + BIGNUM *A, *b, *q, *t, *x, *y; + int e, i, j; + + if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { + if (BN_abs_is_word(p, 2)) { + if (ret == NULL) + ret = BN_new(); + if (ret == NULL) + goto end; + if (!BN_set_word(ret, BN_is_bit_set(a, 0))) { + if (ret != in) + BN_free(ret); + return NULL; + } + bn_check_top(ret); + return ret; + } + + BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + return (NULL); + } + + if (BN_is_zero(a) || BN_is_one(a)) { + if (ret == NULL) + ret = BN_new(); + if (ret == NULL) + goto end; + if (!BN_set_word(ret, BN_is_one(a))) { + if (ret != in) + BN_free(ret); + return NULL; + } + bn_check_top(ret); + return ret; + } + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + t = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto end; + + if (ret == NULL) + ret = BN_new(); + if (ret == NULL) + goto end; + + /* A = a mod p */ + if (!BN_nnmod(A, a, p, ctx)) + goto end; + + /* now write |p| - 1 as 2^e*q where q is odd */ + e = 1; + while (!BN_is_bit_set(p, e)) + e++; + /* we'll set q later (if needed) */ + + if (e == 1) { + /*- + * The easy case: (|p|-1)/2 is odd, so 2 has an inverse + * modulo (|p|-1)/2, and square roots can be computed + * directly by modular exponentiation. + * We have + * 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2), + * so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1. + */ + if (!BN_rshift(q, p, 2)) + goto end; + q->neg = 0; + if (!BN_add_word(q, 1)) + goto end; + if (!BN_mod_exp(ret, A, q, p, ctx)) + goto end; + err = 0; + goto vrfy; + } + + if (e == 2) { + /*- + * |p| == 5 (mod 8) + * + * In this case 2 is always a non-square since + * Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime. + * So if a really is a square, then 2*a is a non-square. + * Thus for + * b := (2*a)^((|p|-5)/8), + * i := (2*a)*b^2 + * we have + * i^2 = (2*a)^((1 + (|p|-5)/4)*2) + * = (2*a)^((p-1)/2) + * = -1; + * so if we set + * x := a*b*(i-1), + * then + * x^2 = a^2 * b^2 * (i^2 - 2*i + 1) + * = a^2 * b^2 * (-2*i) + * = a*(-i)*(2*a*b^2) + * = a*(-i)*i + * = a. + * + * (This is due to A.O.L. Atkin, + * , + * November 1992.) + */ + + /* t := 2*a */ + if (!BN_mod_lshift1_quick(t, A, p)) + goto end; + + /* b := (2*a)^((|p|-5)/8) */ + if (!BN_rshift(q, p, 3)) + goto end; + q->neg = 0; + if (!BN_mod_exp(b, t, q, p, ctx)) + goto end; + + /* y := b^2 */ + if (!BN_mod_sqr(y, b, p, ctx)) + goto end; + + /* t := (2*a)*b^2 - 1 */ + if (!BN_mod_mul(t, t, y, p, ctx)) + goto end; + if (!BN_sub_word(t, 1)) + goto end; + + /* x = a*b*t */ + if (!BN_mod_mul(x, A, b, p, ctx)) + goto end; + if (!BN_mod_mul(x, x, t, p, ctx)) + goto end; + + if (!BN_copy(ret, x)) + goto end; + err = 0; + goto vrfy; + } + + /* + * e > 2, so we really have to use the Tonelli/Shanks algorithm. First, + * find some y that is not a square. + */ + if (!BN_copy(q, p)) + goto end; /* use 'q' as temp */ + q->neg = 0; + i = 2; + do { + /* + * For efficiency, try small numbers first; if this fails, try random + * numbers. + */ + if (i < 22) { + if (!BN_set_word(y, i)) + goto end; + } else { + if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) + goto end; + if (BN_ucmp(y, p) >= 0) { + if (!(p->neg ? BN_add : BN_sub) (y, y, p)) + goto end; + } + /* now 0 <= y < |p| */ + if (BN_is_zero(y)) + if (!BN_set_word(y, i)) + goto end; + } + + r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */ + if (r < -1) + goto end; + if (r == 0) { + /* m divides p */ + BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + goto end; + } + } + while (r == 1 && ++i < 82); + + if (r != -1) { + /* + * Many rounds and still no non-square -- this is more likely a bug + * than just bad luck. Even if p is not prime, we should have found + * some y such that r == -1. + */ + BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS); + goto end; + } + + /* Here's our actual 'q': */ + if (!BN_rshift(q, q, e)) + goto end; + + /* + * Now that we have some non-square, we can find an element of order 2^e + * by computing its q'th power. + */ + if (!BN_mod_exp(y, y, q, p, ctx)) + goto end; + if (BN_is_one(y)) { + BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + goto end; + } + + /*- + * Now we know that (if p is indeed prime) there is an integer + * k, 0 <= k < 2^e, such that + * + * a^q * y^k == 1 (mod p). + * + * As a^q is a square and y is not, k must be even. + * q+1 is even, too, so there is an element + * + * X := a^((q+1)/2) * y^(k/2), + * + * and it satisfies + * + * X^2 = a^q * a * y^k + * = a, + * + * so it is the square root that we are looking for. + */ + + /* t := (q-1)/2 (note that q is odd) */ + if (!BN_rshift1(t, q)) + goto end; + + /* x := a^((q-1)/2) */ + if (BN_is_zero(t)) { /* special case: p = 2^e + 1 */ + if (!BN_nnmod(t, A, p, ctx)) + goto end; + if (BN_is_zero(t)) { + /* special case: a == 0 (mod p) */ + BN_zero(ret); + err = 0; + goto end; + } else if (!BN_one(x)) + goto end; + } else { + if (!BN_mod_exp(x, A, t, p, ctx)) + goto end; + if (BN_is_zero(x)) { + /* special case: a == 0 (mod p) */ + BN_zero(ret); + err = 0; + goto end; + } + } + + /* b := a*x^2 (= a^q) */ + if (!BN_mod_sqr(b, x, p, ctx)) + goto end; + if (!BN_mod_mul(b, b, A, p, ctx)) + goto end; + + /* x := a*x (= a^((q+1)/2)) */ + if (!BN_mod_mul(x, x, A, p, ctx)) + goto end; + + while (1) { + /*- + * Now b is a^q * y^k for some even k (0 <= k < 2^E + * where E refers to the original value of e, which we + * don't keep in a variable), and x is a^((q+1)/2) * y^(k/2). + * + * We have a*b = x^2, + * y^2^(e-1) = -1, + * b^2^(e-1) = 1. + */ + + if (BN_is_one(b)) { + if (!BN_copy(ret, x)) + goto end; + err = 0; + goto vrfy; + } + + /* find smallest i such that b^(2^i) = 1 */ + i = 1; + if (!BN_mod_sqr(t, b, p, ctx)) + goto end; + while (!BN_is_one(t)) { + i++; + if (i == e) { + BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); + goto end; + } + if (!BN_mod_mul(t, t, t, p, ctx)) + goto end; + } + + /* t := y^2^(e - i - 1) */ + if (!BN_copy(t, y)) + goto end; + for (j = e - i - 1; j > 0; j--) { + if (!BN_mod_sqr(t, t, p, ctx)) + goto end; + } + if (!BN_mod_mul(y, t, t, p, ctx)) + goto end; + if (!BN_mod_mul(x, x, t, p, ctx)) + goto end; + if (!BN_mod_mul(b, b, y, p, ctx)) + goto end; + e = i; + } + + vrfy: + if (!err) { + /* + * verify the result -- the input might have been not a square (test + * added in 0.9.8) + */ + + if (!BN_mod_sqr(x, ret, p, ctx)) + err = 1; + + if (!err && 0 != BN_cmp(x, A)) { + BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); + err = 1; + } + } + + end: + if (err) { + if (ret != NULL && ret != in) { + BN_clear_free(ret); + } + ret = NULL; + } + BN_CTX_end(ctx); + bn_check_top(ret); + return ret; +} +/* crypto/bn/bn_word.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn_lcl.h" + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) +{ +#ifndef BN_LLONG + BN_ULONG ret = 0; +#else + BN_ULLONG ret = 0; +#endif + int i; + + if (w == 0) + return (BN_ULONG)-1; + +#ifndef BN_LLONG + /* + * If |w| is too long and we don't have BN_ULLONG then we need to fall + * back to using BN_div_word + */ + if (w > ((BN_ULONG)1 << BN_BITS4)) { + BIGNUM *tmp = BN_dup(a); + if (tmp == NULL) + return (BN_ULONG)-1; + + ret = BN_div_word(tmp, w); + BN_free(tmp); + + return ret; + } +#endif + + bn_check_top(a); + w &= BN_MASK2; + for (i = a->top - 1; i >= 0; i--) { +#ifndef BN_LLONG + /* + * We can assume here that | w <= ((BN_ULONG)1 << BN_BITS4) | and so + * | ret < ((BN_ULONG)1 << BN_BITS4) | and therefore the shifts here are + * safe and will not overflow + */ + ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w; + ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w; +#else + ret = (BN_ULLONG) (((ret << (BN_ULLONG) BN_BITS2) | a->d[i]) % + (BN_ULLONG) w); +#endif + } + return ((BN_ULONG)ret); +} + +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG ret = 0; + int i, j; + + bn_check_top(a); + w &= BN_MASK2; + + if (!w) + /* actually this an error (division by zero) */ + return (BN_ULONG)-1; + if (a->top == 0) + return 0; + + /* normalize input (so bn_div_words doesn't complain) */ + j = BN_BITS2 - BN_num_bits_word(w); + w <<= j; + if (!BN_lshift(a, a, j)) + return (BN_ULONG)-1; + + for (i = a->top - 1; i >= 0; i--) { + BN_ULONG l, d; + + l = a->d[i]; + d = bn_div_words(ret, l, w); + ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2; + a->d[i] = d; + } + if ((a->top > 0) && (a->d[a->top - 1] == 0)) + a->top--; + ret >>= j; + bn_check_top(a); + return (ret); +} + +int BN_add_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG l; + int i; + + bn_check_top(a); + w &= BN_MASK2; + + /* degenerate case: w is zero */ + if (!w) + return 1; + /* degenerate case: a is zero */ + if (BN_is_zero(a)) + return BN_set_word(a, w); + /* handle 'a' when negative */ + if (a->neg) { + a->neg = 0; + i = BN_sub_word(a, w); + if (!BN_is_zero(a)) + a->neg = !(a->neg); + return (i); + } + for (i = 0; w != 0 && i < a->top; i++) { + a->d[i] = l = (a->d[i] + w) & BN_MASK2; + w = (w > l) ? 1 : 0; + } + if (w && i == a->top) { + if (bn_wexpand(a, a->top + 1) == NULL) + return 0; + a->top++; + a->d[i] = w; + } + bn_check_top(a); + return (1); +} + +int BN_sub_word(BIGNUM *a, BN_ULONG w) +{ + int i; + + bn_check_top(a); + w &= BN_MASK2; + + /* degenerate case: w is zero */ + if (!w) + return 1; + /* degenerate case: a is zero */ + if (BN_is_zero(a)) { + i = BN_set_word(a, w); + if (i != 0) + BN_set_negative(a, 1); + return i; + } + /* handle 'a' when negative */ + if (a->neg) { + a->neg = 0; + i = BN_add_word(a, w); + a->neg = 1; + return (i); + } + + if ((a->top == 1) && (a->d[0] < w)) { + a->d[0] = w - a->d[0]; + a->neg = 1; + return (1); + } + i = 0; + for (;;) { + if (a->d[i] >= w) { + a->d[i] -= w; + break; + } else { + a->d[i] = (a->d[i] - w) & BN_MASK2; + i++; + w = 1; + } + } + if ((a->d[i] == 0) && (i == (a->top - 1))) + a->top--; + bn_check_top(a); + return (1); +} + +int BN_mul_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG ll; + + bn_check_top(a); + w &= BN_MASK2; + if (a->top) { + if (w == 0) + BN_zero(a); + else { + ll = bn_mul_words(a->d, a->d, a->top, w); + if (ll) { + if (bn_wexpand(a, a->top + 1) == NULL) + return (0); + a->d[a->top++] = ll; + } + } + } + bn_check_top(a); + return (1); +} +/* bn_x931p.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "bn.h" + +/* X9.31 routines for prime derivation */ + +/* + * X9.31 prime derivation. This is used to generate the primes pi (p1, p2, + * q1, q2) from a parameter Xpi by checking successive odd integers. + */ + +static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, + BN_GENCB *cb) +{ + int i = 0; + if (!BN_copy(pi, Xpi)) + return 0; + if (!BN_is_odd(pi) && !BN_add_word(pi, 1)) + return 0; + for (;;) { + i++; + BN_GENCB_call(cb, 0, i); + /* NB 27 MR is specificed in X9.31 */ + if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb)) + break; + if (!BN_add_word(pi, 2)) + return 0; + } + BN_GENCB_call(cb, 2, i); + return 1; +} + +/* + * This is the main X9.31 prime derivation function. From parameters Xp1, Xp2 + * and Xp derive the prime p. If the parameters p1 or p2 are not NULL they + * will be returned too: this is needed for testing. + */ + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb) +{ + int ret = 0; + + BIGNUM *t, *p1p2, *pm1; + + /* Only even e supported */ + if (!BN_is_odd(e)) + return 0; + + BN_CTX_start(ctx); + if (!p1) + p1 = BN_CTX_get(ctx); + + if (!p2) + p2 = BN_CTX_get(ctx); + + t = BN_CTX_get(ctx); + + p1p2 = BN_CTX_get(ctx); + + pm1 = BN_CTX_get(ctx); + + if (!bn_x931_derive_pi(p1, Xp1, ctx, cb)) + goto err; + + if (!bn_x931_derive_pi(p2, Xp2, ctx, cb)) + goto err; + + if (!BN_mul(p1p2, p1, p2, ctx)) + goto err; + + /* First set p to value of Rp */ + + if (!BN_mod_inverse(p, p2, p1, ctx)) + goto err; + + if (!BN_mul(p, p, p2, ctx)) + goto err; + + if (!BN_mod_inverse(t, p1, p2, ctx)) + goto err; + + if (!BN_mul(t, t, p1, ctx)) + goto err; + + if (!BN_sub(p, p, t)) + goto err; + + if (p->neg && !BN_add(p, p, p1p2)) + goto err; + + /* p now equals Rp */ + + if (!BN_mod_sub(p, p, Xp, p1p2, ctx)) + goto err; + + if (!BN_add(p, p, Xp)) + goto err; + + /* p now equals Yp0 */ + + for (;;) { + int i = 1; + BN_GENCB_call(cb, 0, i++); + if (!BN_copy(pm1, p)) + goto err; + if (!BN_sub_word(pm1, 1)) + goto err; + if (!BN_gcd(t, pm1, e, ctx)) + goto err; + if (BN_is_one(t) + /* + * X9.31 specifies 8 MR and 1 Lucas test or any prime test + * offering similar or better guarantees 50 MR is considerably + * better. + */ + && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb)) + break; + if (!BN_add(p, p, p1p2)) + goto err; + } + + BN_GENCB_call(cb, 3, 0); + + ret = 1; + + err: + + BN_CTX_end(ctx); + + return ret; +} + +/* + * Generate pair of paramters Xp, Xq for X9.31 prime generation. Note: nbits + * paramter is sum of number of bits in both. + */ + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) +{ + BIGNUM *t; + int i; + /* + * Number of bits for each prime is of the form 512+128s for s = 0, 1, + * ... + */ + if ((nbits < 1024) || (nbits & 0xff)) + return 0; + nbits >>= 1; + /* + * The random value Xp must be between sqrt(2) * 2^(nbits-1) and 2^nbits + * - 1. By setting the top two bits we ensure that the lower bound is + * exceeded. + */ + if (!BN_rand(Xp, nbits, 1, 0)) + goto err; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == NULL) + goto err; + + for (i = 0; i < 1000; i++) { + if (!BN_rand(Xq, nbits, 1, 0)) + goto err; + + /* Check that |Xp - Xq| > 2^(nbits - 100) */ + if (!BN_sub(t, Xp, Xq)) + goto err; + if (BN_num_bits(t) > (nbits - 100)) + break; + } + + BN_CTX_end(ctx); + + if (i < 1000) + return 1; + + return 0; + + err: + BN_CTX_end(ctx); + return 0; +} + +/* + * Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 and + * Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL the + * relevant parameter will be stored in it. Due to the fact that |Xp - Xq| > + * 2^(nbits - 100) must be satisfied Xp and Xq are generated using the + * previous function and supplied as input. + */ + +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + BIGNUM *Xp1, BIGNUM *Xp2, + const BIGNUM *Xp, + const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb) +{ + int ret = 0; + + BN_CTX_start(ctx); + if (Xp1 == NULL) + Xp1 = BN_CTX_get(ctx); + if (Xp2 == NULL) + Xp2 = BN_CTX_get(ctx); + if (Xp1 == NULL || Xp2 == NULL) + goto error; + + if (!BN_rand(Xp1, 101, 0, 0)) + goto error; + if (!BN_rand(Xp2, 101, 0, 0)) + goto error; + if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb)) + goto error; + + ret = 1; + + error: + BN_CTX_end(ctx); + + return ret; + +} diff --git a/Sources/COpenSSL/bn_int.h b/Sources/COpenSSL/bn_int.h new file mode 100644 index 00000000..a552cc20 --- /dev/null +++ b/Sources/COpenSSL/bn_int.h @@ -0,0 +1,21 @@ +/* + * Some BIGNUM functions assume most significant limb to be non-zero, which + * is customarily arranged by bn_correct_top. Output from below functions + * is not processed with bn_correct_top, and for this reason it may not be + * returned out of public API. It may only be passed internally into other + * functions known to support non-minimal or zero-padded BIGNUMs. + */ +int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx); +int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); + +int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); diff --git a/Sources/COpenSSL/bn_lcl.h b/Sources/COpenSSL/bn_lcl.h new file mode 100644 index 00000000..86f86e3a --- /dev/null +++ b/Sources/COpenSSL/bn_lcl.h @@ -0,0 +1,538 @@ +/* crypto/bn/bn_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_BN_LCL_H +# define HEADER_BN_LCL_H + +# include "bn.h" +# include "bn_int.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions + * + * + * For window size 'w' (w >= 2) and a random 'b' bits exponent, + * the number of multiplications is a constant plus on average + * + * 2^(w-1) + (b-w)/(w+1); + * + * here 2^(w-1) is for precomputing the table (we actually need + * entries only for windows that have the lowest bit set), and + * (b-w)/(w+1) is an approximation for the expected number of + * w-bit windows, not counting the first one. + * + * Thus we should use + * + * w >= 6 if b > 671 + * w = 5 if 671 > b > 239 + * w = 4 if 239 > b > 79 + * w = 3 if 79 > b > 23 + * w <= 2 if 23 > b + * + * (with draws in between). Very small exponents are often selected + * with low Hamming weight, so we use w = 1 for b <= 23. + */ +# if 1 +# define BN_window_bits_for_exponent_size(b) \ + ((b) > 671 ? 6 : \ + (b) > 239 ? 5 : \ + (b) > 79 ? 4 : \ + (b) > 23 ? 3 : 1) +# else +/* + * Old SSLeay/OpenSSL table. Maximum window size was 5, so this table differs + * for b==1024; but it coincides for other interesting values (b==160, + * b==512). + */ +# define BN_window_bits_for_exponent_size(b) \ + ((b) > 255 ? 5 : \ + (b) > 127 ? 4 : \ + (b) > 17 ? 3 : 1) +# endif + +/* + * BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache + * line width of the target processor is at least the following value. + */ +# define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH ( 64 ) +# define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1) + +/* + * Window sizes optimized for fixed window size modular exponentiation + * algorithm (BN_mod_exp_mont_consttime). To achieve the security goals of + * BN_mode_exp_mont_consttime, the maximum size of the window must not exceed + * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). Window size thresholds are + * defined for cache line sizes of 32 and 64, cache line sizes where + * log_2(32)=5 and log_2(64)=6 respectively. A window size of 7 should only be + * used on processors that have a 128 byte or greater cache line size. + */ +# if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64 + +# define BN_window_bits_for_ctime_exponent_size(b) \ + ((b) > 937 ? 6 : \ + (b) > 306 ? 5 : \ + (b) > 89 ? 4 : \ + (b) > 22 ? 3 : 1) +# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6) + +# elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32 + +# define BN_window_bits_for_ctime_exponent_size(b) \ + ((b) > 306 ? 5 : \ + (b) > 89 ? 4 : \ + (b) > 22 ? 3 : 1) +# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5) + +# endif + +/* Pentium pro 16,16,16,32,64 */ +/* Alpha 16,16,16,16.64 */ +# define BN_MULL_SIZE_NORMAL (16)/* 32 */ +# define BN_MUL_RECURSIVE_SIZE_NORMAL (16)/* 32 less than */ +# define BN_SQR_RECURSIVE_SIZE_NORMAL (16)/* 32 */ +# define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32)/* 32 */ +# define BN_MONT_CTX_SET_SIZE_WORD (64)/* 32 */ + +/* + * 2011-02-22 SMS. In various places, a size_t variable or a type cast to + * size_t was used to perform integer-only operations on pointers. This + * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t + * is still only 32 bits. What's needed in these cases is an integer type + * with the same size as a pointer, which size_t is not certain to be. The + * only fix here is VMS-specific. + */ +# if defined(OPENSSL_SYS_VMS) +# if __INITIAL_POINTER_SIZE == 64 +# define PTR_SIZE_INT long long +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define PTR_SIZE_INT int +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ +# elif !defined(PTR_SIZE_INT) /* defined(OPENSSL_SYS_VMS) */ +# define PTR_SIZE_INT size_t +# endif /* defined(OPENSSL_SYS_VMS) [else] */ + +# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) +/* + * BN_UMULT_HIGH section. + * + * No, I'm not trying to overwhelm you when stating that the + * product of N-bit numbers is 2*N bits wide:-) No, I don't expect + * you to be impressed when I say that if the compiler doesn't + * support 2*N integer type, then you have to replace every N*N + * multiplication with 4 (N/2)*(N/2) accompanied by some shifts + * and additions which unavoidably results in severe performance + * penalties. Of course provided that the hardware is capable of + * producing 2*N result... That's when you normally start + * considering assembler implementation. However! It should be + * pointed out that some CPUs (most notably Alpha, PowerPC and + * upcoming IA-64 family:-) provide *separate* instruction + * calculating the upper half of the product placing the result + * into a general purpose register. Now *if* the compiler supports + * inline assembler, then it's not impossible to implement the + * "bignum" routines (and have the compiler optimize 'em) + * exhibiting "native" performance in C. That's what BN_UMULT_HIGH + * macro is about:-) + * + * + */ +# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT)) +# if defined(__DECC) +# include +# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b)) +# elif defined(__GNUC__) && __GNUC__>=2 +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret; \ + asm ("umulh %1,%2,%0" \ + : "=r"(ret) \ + : "r"(a), "r"(b)); \ + ret; }) +# endif /* compiler */ +# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG) +# if defined(__GNUC__) && __GNUC__>=2 +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret; \ + asm ("mulhdu %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a), "r"(b)); \ + ret; }) +# endif /* compiler */ +# elif (defined(__x86_64) || defined(__x86_64__)) && \ + (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT)) +# if defined(__GNUC__) && __GNUC__>=2 +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret,discard; \ + asm ("mulq %3" \ + : "=a"(discard),"=d"(ret) \ + : "a"(a), "g"(b) \ + : "cc"); \ + ret; }) +# define BN_UMULT_LOHI(low,high,a,b) \ + asm ("mulq %3" \ + : "=a"(low),"=d"(high) \ + : "a"(a),"g"(b) \ + : "cc"); +# endif +# elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT) +# if defined(_MSC_VER) && _MSC_VER>=1400 +unsigned __int64 __umulh(unsigned __int64 a, unsigned __int64 b); +unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b, + unsigned __int64 *h); +# pragma intrinsic(__umulh,_umul128) +# define BN_UMULT_HIGH(a,b) __umulh((a),(b)) +# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high))) +# endif +# elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)) +# if defined(__GNUC__) && __GNUC__>=2 +# if __GNUC__>4 || (__GNUC__>=4 && __GNUC_MINOR__>=4) + /* "h" constraint is no more since 4.4 */ +# define BN_UMULT_HIGH(a,b) (((__uint128_t)(a)*(b))>>64) +# define BN_UMULT_LOHI(low,high,a,b) ({ \ + __uint128_t ret=(__uint128_t)(a)*(b); \ + (high)=ret>>64; (low)=ret; }) +# else +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret; \ + asm ("dmultu %1,%2" \ + : "=h"(ret) \ + : "r"(a), "r"(b) : "l"); \ + ret; }) +# define BN_UMULT_LOHI(low,high,a,b)\ + asm ("dmultu %2,%3" \ + : "=l"(low),"=h"(high) \ + : "r"(a), "r"(b)); +# endif +# endif +# elif defined(__aarch64__) && defined(SIXTY_FOUR_BIT_LONG) +# if defined(__GNUC__) && __GNUC__>=2 +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret; \ + asm ("umulh %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a), "r"(b)); \ + ret; }) +# endif +# endif /* cpu */ +# endif /* OPENSSL_NO_ASM */ + +/************************************************************* + * Using the long long type + */ +# define Lw(t) (((BN_ULONG)(t))&BN_MASK2) +# define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) + +# ifdef BN_DEBUG_RAND +# define bn_clear_top2max(a) \ + { \ + int ind = (a)->dmax - (a)->top; \ + BN_ULONG *ftl = &(a)->d[(a)->top-1]; \ + for (; ind != 0; ind--) \ + *(++ftl) = 0x0; \ + } +# else +# define bn_clear_top2max(a) +# endif + +# ifdef BN_LLONG +# define mul_add(r,a,w,c) { \ + BN_ULLONG t; \ + t=(BN_ULLONG)w * (a) + (r) + (c); \ + (r)= Lw(t); \ + (c)= Hw(t); \ + } + +# define mul(r,a,w,c) { \ + BN_ULLONG t; \ + t=(BN_ULLONG)w * (a) + (c); \ + (r)= Lw(t); \ + (c)= Hw(t); \ + } + +# define sqr(r0,r1,a) { \ + BN_ULLONG t; \ + t=(BN_ULLONG)(a)*(a); \ + (r0)=Lw(t); \ + (r1)=Hw(t); \ + } + +# elif defined(BN_UMULT_LOHI) +# define mul_add(r,a,w,c) { \ + BN_ULONG high,low,ret,tmp=(a); \ + ret = (r); \ + BN_UMULT_LOHI(low,high,w,tmp); \ + ret += (c); \ + (c) = (ret<(c))?1:0; \ + (c) += high; \ + ret += low; \ + (c) += (ret>BN_BITS4)&BN_MASK2l) +# define L2HBITS(a) (((a)<>BN_BITS2)&BN_MASKl) +# define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<>(BN_BITS4-1); \ + m =(m&BN_MASK2l)<<(BN_BITS4+1); \ + l=(l+m)&BN_MASK2; if (l < m) h++; \ + (lo)=l; \ + (ho)=h; \ + } + +# define mul_add(r,a,bl,bh,c) { \ + BN_ULONG l,h; \ + \ + h= (a); \ + l=LBITS(h); \ + h=HBITS(h); \ + mul64(l,h,(bl),(bh)); \ + \ + /* non-multiply part */ \ + l=(l+(c))&BN_MASK2; if (l < (c)) h++; \ + (c)=(r); \ + l=(l+(c))&BN_MASK2; if (l < (c)) h++; \ + (c)=h&BN_MASK2; \ + (r)=l; \ + } + +# define mul(r,a,bl,bh,c) { \ + BN_ULONG l,h; \ + \ + h= (a); \ + l=LBITS(h); \ + h=HBITS(h); \ + mul64(l,h,(bl),(bh)); \ + \ + /* non-multiply part */ \ + l+=(c); if ((l&BN_MASK2) < (c)) h++; \ + (c)=h&BN_MASK2; \ + (r)=l&BN_MASK2; \ + } +# endif /* !BN_LLONG */ + +# if defined(OPENSSL_DOING_MAKEDEPEND) && defined(OPENSSL_FIPS) +# undef bn_div_words +# endif + +void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb); +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); +void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp); +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a); +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a); +int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n); +int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl); +void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + int dna, int dnb, BN_ULONG *t); +void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, + int n, int tna, int tnb, BN_ULONG *t); +void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t); +void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n); +void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + BN_ULONG *t); +void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, + BN_ULONG *t); +BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl); +BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl); +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/bn_prime.h b/Sources/COpenSSL/bn_prime.h new file mode 100644 index 00000000..489af8b4 --- /dev/null +++ b/Sources/COpenSSL/bn_prime.h @@ -0,0 +1,326 @@ +/* Auto generated by bn_prime.pl */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef EIGHT_BIT +# define NUMPRIMES 2048 +typedef unsigned short prime_t; +#else +# define NUMPRIMES 54 +typedef unsigned char prime_t; +#endif +static const prime_t primes[NUMPRIMES] = { + 2, 3, 5, 7, 11, 13, 17, 19, + 23, 29, 31, 37, 41, 43, 47, 53, + 59, 61, 67, 71, 73, 79, 83, 89, + 97, 101, 103, 107, 109, 113, 127, 131, + 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, +#ifndef EIGHT_BIT + 257, 263, + 269, 271, 277, 281, 283, 293, 307, 311, + 313, 317, 331, 337, 347, 349, 353, 359, + 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, + 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, + 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, + 727, 733, 739, 743, 751, 757, 761, 769, + 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, + 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, + 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, + 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, + 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, + 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, + 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, + 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, + 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, + 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, + 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, + 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, + 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, + 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, + 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, + 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, + 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, + 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, + 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, + 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, + 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, + 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, + 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, + 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, + 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, + 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, + 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, + 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, + 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, + 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, + 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, + 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, + 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, + 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, + 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, + 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, + 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, + 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, + 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, + 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, + 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, + 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, + 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, + 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, + 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, + 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, + 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, + 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, + 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, + 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, + 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, + 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, + 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, + 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, + 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, + 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, + 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, + 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, + 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, + 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, + 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, + 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, + 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, + 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, + 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, + 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, + 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, + 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, + 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, + 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, + 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, + 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, + 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, + 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, + 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, + 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, + 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, + 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, + 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, + 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, + 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, + 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, + 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, + 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, + 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, + 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, + 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, + 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, + 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, + 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, + 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, + 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, + 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, + 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, + 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, + 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, + 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, + 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, + 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, + 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, + 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, + 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, + 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, + 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, + 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, + 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, + 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, + 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, + 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, + 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, + 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, + 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, + 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, + 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, + 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, + 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, + 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, + 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, + 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, + 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, + 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, + 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, + 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, + 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, + 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, + 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, + 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, + 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, + 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, + 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, + 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, + 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, + 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, + 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, + 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, + 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, + 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, + 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, + 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, + 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, + 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, + 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, + 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, + 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, + 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, + 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, + 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, + 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, + 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, + 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, + 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, + 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, + 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, + 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, + 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, + 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, + 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, + 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, + 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, + 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, + 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, + 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, + 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, + 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, + 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, + 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, + 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, + 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, + 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, + 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, + 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, + 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, + 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, + 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, + 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, + 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, + 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, + 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, + 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, + 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, + 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, + 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, + 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, + 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, + 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, + 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, + 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, + 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, + 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, + 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, + 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, + 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, + 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, + 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, + 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, + 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, + 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, + 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, + 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, + 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, + 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, + 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, + 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, + 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, + 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, + 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, + 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, + 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, + 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, + 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, + 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, + 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, + 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, + 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, + 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, + 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, + 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, + 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, + 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, + 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, + 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, + 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, + 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, + 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, + 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, + 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, + 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, + 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, + 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, + 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, + 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, + 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, + 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, + 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, + 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, + 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, +#endif +}; diff --git a/Sources/COpenSSL/bss_.c b/Sources/COpenSSL/bss_.c new file mode 100644 index 00000000..b5a671d6 --- /dev/null +++ b/Sources/COpenSSL/bss_.c @@ -0,0 +1,6063 @@ +/* crypto/bio/bss_acpt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +#include "cryptlib.h" +#include "bio.h" + +#ifndef OPENSSL_NO_SOCK + +# ifdef OPENSSL_SYS_WIN16 +# define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ +# else +# define SOCKET_PROTOCOL IPPROTO_TCP +# endif + +# if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ +# undef FIONBIO +# endif + +typedef struct bio_accept_st { + int state; + char *param_addr; + int accept_sock; + int accept_nbio; + char *addr; + int nbio; + /* + * If 0, it means normal, if 1, do a connect on bind failure, and if + * there is no-one listening, bind with SO_REUSEADDR. If 2, always use + * SO_REUSEADDR. + */ + int bind_mode; + BIO *bio_chain; +} BIO_ACCEPT; + +static int acpt_write(BIO *h, const char *buf, int num); +static int acpt_read(BIO *h, char *buf, int size); +static int acpt_puts(BIO *h, const char *str); +static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int acpt_new(BIO *h); +static int acpt_free(BIO *data); +static int acpt_state(BIO *b, BIO_ACCEPT *c); +static void acpt_close_socket(BIO *data); +static BIO_ACCEPT *BIO_ACCEPT_new(void); +static void BIO_ACCEPT_free(BIO_ACCEPT *a); + +# define ACPT_S_BEFORE 1 +# define ACPT_S_GET_ACCEPT_SOCKET 2 +# define ACPT_S_OK 3 + +static BIO_METHOD methods_acceptp = { + BIO_TYPE_ACCEPT, + "socket accept", + acpt_write, + acpt_read, + acpt_puts, + NULL, /* connect_gets, */ + acpt_ctrl, + acpt_new, + acpt_free, + NULL, +}; + +BIO_METHOD *BIO_s_accept(void) +{ + return (&methods_acceptp); +} + +static int acpt_new(BIO *bi) +{ + BIO_ACCEPT *ba; + + bi->init = 0; + bi->num = INVALID_SOCKET; + bi->flags = 0; + if ((ba = BIO_ACCEPT_new()) == NULL) + return (0); + bi->ptr = (char *)ba; + ba->state = ACPT_S_BEFORE; + bi->shutdown = 1; + return (1); +} + +static BIO_ACCEPT *BIO_ACCEPT_new(void) +{ + BIO_ACCEPT *ret; + + if ((ret = (BIO_ACCEPT *)OPENSSL_malloc(sizeof(BIO_ACCEPT))) == NULL) + return (NULL); + + memset(ret, 0, sizeof(BIO_ACCEPT)); + ret->accept_sock = INVALID_SOCKET; + ret->bind_mode = BIO_BIND_NORMAL; + return (ret); +} + +static void BIO_ACCEPT_free(BIO_ACCEPT *a) +{ + if (a == NULL) + return; + + if (a->param_addr != NULL) + OPENSSL_free(a->param_addr); + if (a->addr != NULL) + OPENSSL_free(a->addr); + if (a->bio_chain != NULL) + BIO_free(a->bio_chain); + OPENSSL_free(a); +} + +static void acpt_close_socket(BIO *bio) +{ + BIO_ACCEPT *c; + + c = (BIO_ACCEPT *)bio->ptr; + if (c->accept_sock != INVALID_SOCKET) { + shutdown(c->accept_sock, 2); + closesocket(c->accept_sock); + c->accept_sock = INVALID_SOCKET; + bio->num = INVALID_SOCKET; + } +} + +static int acpt_free(BIO *a) +{ + BIO_ACCEPT *data; + + if (a == NULL) + return (0); + data = (BIO_ACCEPT *)a->ptr; + + if (a->shutdown) { + acpt_close_socket(a); + BIO_ACCEPT_free(data); + a->ptr = NULL; + a->flags = 0; + a->init = 0; + } + return (1); +} + +static int acpt_state(BIO *b, BIO_ACCEPT *c) +{ + BIO *bio = NULL, *dbio; + int s = -1; + int i; + + again: + switch (c->state) { + case ACPT_S_BEFORE: + if (c->param_addr == NULL) { + BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED); + return (-1); + } + s = BIO_get_accept_socket(c->param_addr, c->bind_mode); + if (s == INVALID_SOCKET) + return (-1); + + if (c->accept_nbio) { + if (!BIO_socket_nbio(s, 1)) { + closesocket(s); + BIOerr(BIO_F_ACPT_STATE, + BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET); + return (-1); + } + } + c->accept_sock = s; + b->num = s; + c->state = ACPT_S_GET_ACCEPT_SOCKET; + return (1); + /* break; */ + case ACPT_S_GET_ACCEPT_SOCKET: + if (b->next_bio != NULL) { + c->state = ACPT_S_OK; + goto again; + } + BIO_clear_retry_flags(b); + b->retry_reason = 0; + i = BIO_accept(c->accept_sock, &(c->addr)); + + /* -2 return means we should retry */ + if (i == -2) { + BIO_set_retry_special(b); + b->retry_reason = BIO_RR_ACCEPT; + return -1; + } + + if (i < 0) + return (i); + + bio = BIO_new_socket(i, BIO_CLOSE); + if (bio == NULL) + goto err; + + BIO_set_callback(bio, BIO_get_callback(b)); + BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); + + if (c->nbio) { + if (!BIO_socket_nbio(i, 1)) { + BIOerr(BIO_F_ACPT_STATE, + BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET); + goto err; + } + } + + /* + * If the accept BIO has an bio_chain, we dup it and put the new + * socket at the end. + */ + if (c->bio_chain != NULL) { + if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL) + goto err; + if (!BIO_push(dbio, bio)) + goto err; + bio = dbio; + } + if (BIO_push(b, bio) == NULL) + goto err; + + c->state = ACPT_S_OK; + return (1); + err: + if (bio != NULL) + BIO_free(bio); + else if (s >= 0) + closesocket(s); + return (0); + /* break; */ + case ACPT_S_OK: + if (b->next_bio == NULL) { + c->state = ACPT_S_GET_ACCEPT_SOCKET; + goto again; + } + return (1); + /* break; */ + default: + return (0); + /* break; */ + } + +} + +static int acpt_read(BIO *b, char *out, int outl) +{ + int ret = 0; + BIO_ACCEPT *data; + + BIO_clear_retry_flags(b); + data = (BIO_ACCEPT *)b->ptr; + + while (b->next_bio == NULL) { + ret = acpt_state(b, data); + if (ret <= 0) + return (ret); + } + + ret = BIO_read(b->next_bio, out, outl); + BIO_copy_next_retry(b); + return (ret); +} + +static int acpt_write(BIO *b, const char *in, int inl) +{ + int ret; + BIO_ACCEPT *data; + + BIO_clear_retry_flags(b); + data = (BIO_ACCEPT *)b->ptr; + + while (b->next_bio == NULL) { + ret = acpt_state(b, data); + if (ret <= 0) + return (ret); + } + + ret = BIO_write(b->next_bio, in, inl); + BIO_copy_next_retry(b); + return (ret); +} + +static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + int *ip; + long ret = 1; + BIO_ACCEPT *data; + char **pp; + + data = (BIO_ACCEPT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = ACPT_S_BEFORE; + acpt_close_socket(b); + b->flags = 0; + break; + case BIO_C_DO_STATE_MACHINE: + /* use this one to start the connection */ + ret = (long)acpt_state(b, data); + break; + case BIO_C_SET_ACCEPT: + if (ptr != NULL) { + if (num == 0) { + b->init = 1; + if (data->param_addr != NULL) + OPENSSL_free(data->param_addr); + data->param_addr = BUF_strdup(ptr); + } else if (num == 1) { + data->accept_nbio = (ptr != NULL); + } else if (num == 2) { + if (data->bio_chain != NULL) + BIO_free(data->bio_chain); + data->bio_chain = (BIO *)ptr; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_SET_FD: + b->init = 1; + b->num = *((int *)ptr); + data->accept_sock = b->num; + data->state = ACPT_S_GET_ACCEPT_SOCKET; + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = data->accept_sock; + ret = data->accept_sock; + } else + ret = -1; + break; + case BIO_C_GET_ACCEPT: + if (b->init) { + if (ptr != NULL) { + pp = (char **)ptr; + *pp = data->param_addr; + } else + ret = -1; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + break; + case BIO_C_SET_BIND_MODE: + data->bind_mode = (int)num; + break; + case BIO_C_GET_BIND_MODE: + ret = (long)data->bind_mode; + break; + case BIO_CTRL_DUP: +/*- dbio=(BIO *)ptr; + if (data->param_port) EAY EAY + BIO_set_port(dbio,data->param_port); + if (data->param_hostname) + BIO_set_hostname(dbio,data->param_hostname); + BIO_set_nbio(dbio,data->nbio); */ + break; + + default: + ret = 0; + break; + } + return (ret); +} + +static int acpt_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = acpt_write(bp, str, n); + return (ret); +} + +BIO *BIO_new_accept(const char *str) +{ + BIO *ret; + + ret = BIO_new(BIO_s_accept()); + if (ret == NULL) + return (NULL); + if (BIO_set_accept_port(ret, str)) + return (ret); + else { + BIO_free(ret); + return (NULL); + } +} + +#endif +/* crypto/bio/bss_bio.c */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Special method for a BIO where the other endpoint is also a BIO of this + * kind, handled by the same thread (i.e. the "peer" is actually ourselves, + * wearing a different hat). Such "BIO pairs" are mainly for using the SSL + * library with I/O interfaces for which no specific BIO method is available. + * See ssl/ssltest.c for some hints on how this can be used. + */ + +/* BIO_DEBUG implies BIO_PAIR_DEBUG */ +#ifdef BIO_DEBUG +# ifndef BIO_PAIR_DEBUG +# define BIO_PAIR_DEBUG +# endif +#endif + +/* disable assert() unless BIO_PAIR_DEBUG has been defined */ +#ifndef BIO_PAIR_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#include +#include +#include +#include + +// #include "bio.h" +#include "err.h" +#include "crypto.h" + +#include "e_os.h" + +/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */ +#if defined(OPENSSL_SYS_VXWORKS) +# undef SSIZE_MAX +#endif +#ifndef SSIZE_MAX +# define SSIZE_MAX INT_MAX +#endif + +static int bio_new(BIO *bio); +static int bio_free(BIO *bio); +static int bio_read(BIO *bio, char *buf, int size); +static int bio_write(BIO *bio, const char *buf, int num); +static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); +static int bio_puts(BIO *bio, const char *str); + +static int bio_make_pair(BIO *bio1, BIO *bio2); +static void bio_destroy_pair(BIO *bio); + +static BIO_METHOD methods_biop = { + BIO_TYPE_BIO, + "BIO pair", + bio_write, + bio_read, + bio_puts, + NULL /* no bio_gets */ , + bio_ctrl, + bio_new, + bio_free, + NULL /* no bio_callback_ctrl */ +}; + +BIO_METHOD *BIO_s_bio(void) +{ + return &methods_biop; +} + +struct bio_bio_st { + BIO *peer; /* NULL if buf == NULL. If peer != NULL, then + * peer->ptr is also a bio_bio_st, and its + * "peer" member points back to us. peer != + * NULL iff init != 0 in the BIO. */ + /* This is for what we write (i.e. reading uses peer's struct): */ + int closed; /* valid iff peer != NULL */ + size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ + size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ + size_t size; + char *buf; /* "size" elements (if != NULL) */ + size_t request; /* valid iff peer != NULL; 0 if len != 0, + * otherwise set by peer to number of bytes + * it (unsuccessfully) tried to read, never + * more than buffer space (size-len) + * warrants. */ +}; + +static int bio_new(BIO *bio) +{ + struct bio_bio_st *b; + + b = OPENSSL_malloc(sizeof(*b)); + if (b == NULL) + return 0; + + b->peer = NULL; + b->closed = 0; + b->len = 0; + b->offset = 0; + /* enough for one TLS record (just a default) */ + b->size = 17 * 1024; + b->buf = NULL; + b->request = 0; + + bio->ptr = b; + return 1; +} + +static int bio_free(BIO *bio) +{ + struct bio_bio_st *b; + + if (bio == NULL) + return 0; + b = bio->ptr; + + assert(b != NULL); + + if (b->peer) + bio_destroy_pair(bio); + + if (b->buf != NULL) { + OPENSSL_free(b->buf); + } + + OPENSSL_free(b); + + return 1; +} + +static int bio_read(BIO *bio, char *buf, int size_) +{ + size_t size = size_; + size_t rest; + struct bio_bio_st *b, *peer_b; + + BIO_clear_retry_flags(bio); + + if (!bio->init) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + peer_b = b->peer->ptr; + assert(peer_b != NULL); + assert(peer_b->buf != NULL); + + peer_b->request = 0; /* will be set in "retry_read" situation */ + + if (buf == NULL || size == 0) + return 0; + + if (peer_b->len == 0) { + if (peer_b->closed) + return 0; /* writer has closed, and no data is left */ + else { + BIO_set_retry_read(bio); /* buffer is empty */ + if (size <= peer_b->size) + peer_b->request = size; + else + /* + * don't ask for more than the peer can deliver in one write + */ + peer_b->request = peer_b->size; + return -1; + } + } + + /* we can read */ + if (peer_b->len < size) + size = peer_b->len; + + /* now read "size" bytes */ + + rest = size; + + assert(rest > 0); + do { /* one or two iterations */ + size_t chunk; + + assert(rest <= peer_b->len); + if (peer_b->offset + rest <= peer_b->size) + chunk = rest; + else + /* wrap around ring buffer */ + chunk = peer_b->size - peer_b->offset; + assert(peer_b->offset + chunk <= peer_b->size); + + memcpy(buf, peer_b->buf + peer_b->offset, chunk); + + peer_b->len -= chunk; + if (peer_b->len) { + peer_b->offset += chunk; + assert(peer_b->offset <= peer_b->size); + if (peer_b->offset == peer_b->size) + peer_b->offset = 0; + buf += chunk; + } else { + /* buffer now empty, no need to advance "buf" */ + assert(chunk == rest); + peer_b->offset = 0; + } + rest -= chunk; + } + while (rest); + + return size; +} + +/*- + * non-copying interface: provide pointer to available data in buffer + * bio_nread0: return number of available bytes + * bio_nread: also advance index + * (example usage: bio_nread0(), read from buffer, bio_nread() + * or just bio_nread(), read from buffer) + */ +/* + * WARNING: The non-copying interface is largely untested as of yet and may + * contain bugs. + */ +static ossl_ssize_t bio_nread0(BIO *bio, char **buf) +{ + struct bio_bio_st *b, *peer_b; + ossl_ssize_t num; + + BIO_clear_retry_flags(bio); + + if (!bio->init) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + peer_b = b->peer->ptr; + assert(peer_b != NULL); + assert(peer_b->buf != NULL); + + peer_b->request = 0; + + if (peer_b->len == 0) { + char dummy; + + /* avoid code duplication -- nothing available for reading */ + return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ + } + + num = peer_b->len; + if (peer_b->size < peer_b->offset + num) + /* no ring buffer wrap-around for non-copying interface */ + num = peer_b->size - peer_b->offset; + assert(num > 0); + + if (buf != NULL) + *buf = peer_b->buf + peer_b->offset; + return num; +} + +static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) +{ + struct bio_bio_st *b, *peer_b; + ossl_ssize_t num, available; + + if (num_ > SSIZE_MAX) + num = SSIZE_MAX; + else + num = (ossl_ssize_t) num_; + + available = bio_nread0(bio, buf); + if (num > available) + num = available; + if (num <= 0) + return num; + + b = bio->ptr; + peer_b = b->peer->ptr; + + peer_b->len -= num; + if (peer_b->len) { + peer_b->offset += num; + assert(peer_b->offset <= peer_b->size); + if (peer_b->offset == peer_b->size) + peer_b->offset = 0; + } else + peer_b->offset = 0; + + return num; +} + +static int bio_write(BIO *bio, const char *buf, int num_) +{ + size_t num = num_; + size_t rest; + struct bio_bio_st *b; + + BIO_clear_retry_flags(bio); + + if (!bio->init || buf == NULL || num == 0) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + assert(b->buf != NULL); + + b->request = 0; + if (b->closed) { + /* we already closed */ + BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); + return -1; + } + + assert(b->len <= b->size); + + if (b->len == b->size) { + BIO_set_retry_write(bio); /* buffer is full */ + return -1; + } + + /* we can write */ + if (num > b->size - b->len) + num = b->size - b->len; + + /* now write "num" bytes */ + + rest = num; + + assert(rest > 0); + do { /* one or two iterations */ + size_t write_offset; + size_t chunk; + + assert(b->len + rest <= b->size); + + write_offset = b->offset + b->len; + if (write_offset >= b->size) + write_offset -= b->size; + /* b->buf[write_offset] is the first byte we can write to. */ + + if (write_offset + rest <= b->size) + chunk = rest; + else + /* wrap around ring buffer */ + chunk = b->size - write_offset; + + memcpy(b->buf + write_offset, buf, chunk); + + b->len += chunk; + + assert(b->len <= b->size); + + rest -= chunk; + buf += chunk; + } + while (rest); + + return num; +} + +/*- + * non-copying interface: provide pointer to region to write to + * bio_nwrite0: check how much space is available + * bio_nwrite: also increase length + * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() + * or just bio_nwrite(), write to buffer) + */ +static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) +{ + struct bio_bio_st *b; + size_t num; + size_t write_offset; + + BIO_clear_retry_flags(bio); + + if (!bio->init) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + assert(b->buf != NULL); + + b->request = 0; + if (b->closed) { + BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); + return -1; + } + + assert(b->len <= b->size); + + if (b->len == b->size) { + BIO_set_retry_write(bio); + return -1; + } + + num = b->size - b->len; + write_offset = b->offset + b->len; + if (write_offset >= b->size) + write_offset -= b->size; + if (write_offset + num > b->size) + /* + * no ring buffer wrap-around for non-copying interface (to fulfil + * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have + * to be called twice) + */ + num = b->size - write_offset; + + if (buf != NULL) + *buf = b->buf + write_offset; + assert(write_offset + num <= b->size); + + return num; +} + +static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) +{ + struct bio_bio_st *b; + ossl_ssize_t num, space; + + if (num_ > SSIZE_MAX) + num = SSIZE_MAX; + else + num = (ossl_ssize_t) num_; + + space = bio_nwrite0(bio, buf); + if (num > space) + num = space; + if (num <= 0) + return num; + b = bio->ptr; + assert(b != NULL); + b->len += num; + assert(b->len <= b->size); + + return num; +} + +static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret; + struct bio_bio_st *b = bio->ptr; + + assert(b != NULL); + + switch (cmd) { + /* specific CTRL codes */ + + case BIO_C_SET_WRITE_BUF_SIZE: + if (b->peer) { + BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); + ret = 0; + } else if (num == 0) { + BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); + ret = 0; + } else { + size_t new_size = num; + + if (b->size != new_size) { + if (b->buf) { + OPENSSL_free(b->buf); + b->buf = NULL; + } + b->size = new_size; + } + ret = 1; + } + break; + + case BIO_C_GET_WRITE_BUF_SIZE: + ret = (long)b->size; + break; + + case BIO_C_MAKE_BIO_PAIR: + { + BIO *other_bio = ptr; + + if (bio_make_pair(bio, other_bio)) + ret = 1; + else + ret = 0; + } + break; + + case BIO_C_DESTROY_BIO_PAIR: + /* + * Affects both BIOs in the pair -- call just once! Or let + * BIO_free(bio1); BIO_free(bio2); do the job. + */ + bio_destroy_pair(bio); + ret = 1; + break; + + case BIO_C_GET_WRITE_GUARANTEE: + /* + * How many bytes can the caller feed to the next write without + * having to keep any? + */ + if (b->peer == NULL || b->closed) + ret = 0; + else + ret = (long)b->size - b->len; + break; + + case BIO_C_GET_READ_REQUEST: + /* + * If the peer unsuccessfully tried to read, how many bytes were + * requested? (As with BIO_CTRL_PENDING, that number can usually be + * treated as boolean.) + */ + ret = (long)b->request; + break; + + case BIO_C_RESET_READ_REQUEST: + /* + * Reset request. (Can be useful after read attempts at the other + * side that are meant to be non-blocking, e.g. when probing SSL_read + * to see if any data is available.) + */ + b->request = 0; + ret = 1; + break; + + case BIO_C_SHUTDOWN_WR: + /* similar to shutdown(..., SHUT_WR) */ + b->closed = 1; + ret = 1; + break; + + case BIO_C_NREAD0: + /* prepare for non-copying read */ + ret = (long)bio_nread0(bio, ptr); + break; + + case BIO_C_NREAD: + /* non-copying read */ + ret = (long)bio_nread(bio, ptr, (size_t)num); + break; + + case BIO_C_NWRITE0: + /* prepare for non-copying write */ + ret = (long)bio_nwrite0(bio, ptr); + break; + + case BIO_C_NWRITE: + /* non-copying write */ + ret = (long)bio_nwrite(bio, ptr, (size_t)num); + break; + + /* standard CTRL codes follow */ + + case BIO_CTRL_RESET: + if (b->buf != NULL) { + b->len = 0; + b->offset = 0; + } + ret = 0; + break; + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + ret = 1; + break; + + case BIO_CTRL_PENDING: + if (b->peer != NULL) { + struct bio_bio_st *peer_b = b->peer->ptr; + + ret = (long)peer_b->len; + } else + ret = 0; + break; + + case BIO_CTRL_WPENDING: + if (b->buf != NULL) + ret = (long)b->len; + else + ret = 0; + break; + + case BIO_CTRL_DUP: + /* See BIO_dup_chain for circumstances we have to expect. */ + { + BIO *other_bio = ptr; + struct bio_bio_st *other_b; + + assert(other_bio != NULL); + other_b = other_bio->ptr; + assert(other_b != NULL); + + assert(other_b->buf == NULL); /* other_bio is always fresh */ + + other_b->size = b->size; + } + + ret = 1; + break; + + case BIO_CTRL_FLUSH: + ret = 1; + break; + + case BIO_CTRL_EOF: + if (b->peer != NULL) { + struct bio_bio_st *peer_b = b->peer->ptr; + + if (peer_b->len == 0 && peer_b->closed) + ret = 1; + else + ret = 0; + } else { + ret = 1; + } + break; + + default: + ret = 0; + } + return ret; +} + +static int bio_puts(BIO *bio, const char *str) +{ + return bio_write(bio, str, strlen(str)); +} + +static int bio_make_pair(BIO *bio1, BIO *bio2) +{ + struct bio_bio_st *b1, *b2; + + assert(bio1 != NULL); + assert(bio2 != NULL); + + b1 = bio1->ptr; + b2 = bio2->ptr; + + if (b1->peer != NULL || b2->peer != NULL) { + BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); + return 0; + } + + if (b1->buf == NULL) { + b1->buf = OPENSSL_malloc(b1->size); + if (b1->buf == NULL) { + BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); + return 0; + } + b1->len = 0; + b1->offset = 0; + } + + if (b2->buf == NULL) { + b2->buf = OPENSSL_malloc(b2->size); + if (b2->buf == NULL) { + BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); + return 0; + } + b2->len = 0; + b2->offset = 0; + } + + b1->peer = bio2; + b1->closed = 0; + b1->request = 0; + b2->peer = bio1; + b2->closed = 0; + b2->request = 0; + + bio1->init = 1; + bio2->init = 1; + + return 1; +} + +static void bio_destroy_pair(BIO *bio) +{ + struct bio_bio_st *b = bio->ptr; + + if (b != NULL) { + BIO *peer_bio = b->peer; + + if (peer_bio != NULL) { + struct bio_bio_st *peer_b = peer_bio->ptr; + + assert(peer_b != NULL); + assert(peer_b->peer == bio); + + peer_b->peer = NULL; + peer_bio->init = 0; + assert(peer_b->buf != NULL); + peer_b->len = 0; + peer_b->offset = 0; + + b->peer = NULL; + bio->init = 0; + assert(b->buf != NULL); + b->len = 0; + b->offset = 0; + } + } +} + +/* Exported convenience functions */ +int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, + BIO **bio2_p, size_t writebuf2) +{ + BIO *bio1 = NULL, *bio2 = NULL; + long r; + int ret = 0; + + bio1 = BIO_new(BIO_s_bio()); + if (bio1 == NULL) + goto err; + bio2 = BIO_new(BIO_s_bio()); + if (bio2 == NULL) + goto err; + + if (writebuf1) { + r = BIO_set_write_buf_size(bio1, writebuf1); + if (!r) + goto err; + } + if (writebuf2) { + r = BIO_set_write_buf_size(bio2, writebuf2); + if (!r) + goto err; + } + + r = BIO_make_bio_pair(bio1, bio2); + if (!r) + goto err; + ret = 1; + + err: + if (ret == 0) { + if (bio1) { + BIO_free(bio1); + bio1 = NULL; + } + if (bio2) { + BIO_free(bio2); + bio2 = NULL; + } + } + + *bio1_p = bio1; + *bio2_p = bio2; + return ret; +} + +size_t BIO_ctrl_get_write_guarantee(BIO *bio) +{ + return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); +} + +size_t BIO_ctrl_get_read_request(BIO *bio) +{ + return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); +} + +int BIO_ctrl_reset_read_request(BIO *bio) +{ + return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); +} + +/* + * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now + * (conceivably some other BIOs could allow non-copying reads and writes + * too.) + */ +int BIO_nread0(BIO *bio, char **buf) +{ + long ret; + + if (!bio->init) { + BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); + return -2; + } + + ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); + if (ret > INT_MAX) + return INT_MAX; + else + return (int)ret; +} + +int BIO_nread(BIO *bio, char **buf, int num) +{ + int ret; + + if (!bio->init) { + BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); + return -2; + } + + ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf); + if (ret > 0) + bio->num_read += ret; + return ret; +} + +int BIO_nwrite0(BIO *bio, char **buf) +{ + long ret; + + if (!bio->init) { + BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); + return -2; + } + + ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); + if (ret > INT_MAX) + return INT_MAX; + else + return (int)ret; +} + +int BIO_nwrite(BIO *bio, char **buf, int num) +{ + int ret; + + if (!bio->init) { + BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); + return -2; + } + + ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); + if (ret > 0) + bio->num_write += ret; + return ret; +} +/* crypto/bio/bss_conn.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +// #include "cryptlib.h" +// #include "bio.h" + +#ifndef OPENSSL_NO_SOCK + +# ifdef OPENSSL_SYS_WIN16 +# define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ +# else +# define SOCKET_PROTOCOL IPPROTO_TCP +# endif + +# if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ +# undef FIONBIO +# endif + +typedef struct bio_connect_st { + int state; + char *param_hostname; + char *param_port; + int nbio; + unsigned char ip[4]; + unsigned short port; + struct sockaddr_in them; + /* + * int socket; this will be kept in bio->num so that it is compatible + * with the bss_sock bio + */ + /* + * called when the connection is initially made callback(BIO,state,ret); + * The callback should return 'ret'. state is for compatibility with the + * ssl info_callback + */ + int (*info_callback) (const BIO *bio, int state, int ret); +} BIO_CONNECT; + +static int conn_write(BIO *h, const char *buf, int num); +static int conn_read(BIO *h, char *buf, int size); +static int conn_puts(BIO *h, const char *str); +static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int conn_new(BIO *h); +static int conn_free(BIO *data); +static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *); + +static int conn_state(BIO *b, BIO_CONNECT *c); +static void conn_close_socket(BIO *data); +BIO_CONNECT *BIO_CONNECT_new(void); +void BIO_CONNECT_free(BIO_CONNECT *a); + +static BIO_METHOD methods_connectp = { + BIO_TYPE_CONNECT, + "socket connect", + conn_write, + conn_read, + conn_puts, + NULL, /* connect_gets, */ + conn_ctrl, + conn_new, + conn_free, + conn_callback_ctrl, +}; + +static int conn_state(BIO *b, BIO_CONNECT *c) +{ + int ret = -1, i; + unsigned long l; + char *p, *q; + int (*cb) (const BIO *, int, int) = NULL; + + if (c->info_callback != NULL) + cb = c->info_callback; + + for (;;) { + switch (c->state) { + case BIO_CONN_S_BEFORE: + p = c->param_hostname; + if (p == NULL) { + BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_SPECIFIED); + goto exit_loop; + } + for (; *p != '\0'; p++) { + if ((*p == ':') || (*p == '/')) + break; + } + + i = *p; + if ((i == ':') || (i == '/')) { + + *(p++) = '\0'; + if (i == ':') { + for (q = p; *q; q++) + if (*q == '/') { + *q = '\0'; + break; + } + if (c->param_port != NULL) + OPENSSL_free(c->param_port); + c->param_port = BUF_strdup(p); + } + } + + if (c->param_port == NULL) { + BIOerr(BIO_F_CONN_STATE, BIO_R_NO_PORT_SPECIFIED); + ERR_add_error_data(2, "host=", c->param_hostname); + goto exit_loop; + } + c->state = BIO_CONN_S_GET_IP; + break; + + case BIO_CONN_S_GET_IP: + if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0) + goto exit_loop; + c->state = BIO_CONN_S_GET_PORT; + break; + + case BIO_CONN_S_GET_PORT: + if (c->param_port == NULL) { + /* abort(); */ + goto exit_loop; + } else if (BIO_get_port(c->param_port, &c->port) <= 0) + goto exit_loop; + c->state = BIO_CONN_S_CREATE_SOCKET; + break; + + case BIO_CONN_S_CREATE_SOCKET: + /* now setup address */ + memset((char *)&c->them, 0, sizeof(c->them)); + c->them.sin_family = AF_INET; + c->them.sin_port = htons((unsigned short)c->port); + l = (unsigned long) + ((unsigned long)c->ip[0] << 24L) | + ((unsigned long)c->ip[1] << 16L) | + ((unsigned long)c->ip[2] << 8L) | ((unsigned long)c->ip[3]); + c->them.sin_addr.s_addr = htonl(l); + c->state = BIO_CONN_S_CREATE_SOCKET; + + ret = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL); + if (ret == INVALID_SOCKET) { + SYSerr(SYS_F_SOCKET, get_last_socket_error()); + ERR_add_error_data(4, "host=", c->param_hostname, + ":", c->param_port); + BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); + goto exit_loop; + } + b->num = ret; + c->state = BIO_CONN_S_NBIO; + break; + + case BIO_CONN_S_NBIO: + if (c->nbio) { + if (!BIO_socket_nbio(b->num, 1)) { + BIOerr(BIO_F_CONN_STATE, BIO_R_ERROR_SETTING_NBIO); + ERR_add_error_data(4, "host=", + c->param_hostname, ":", c->param_port); + goto exit_loop; + } + } + c->state = BIO_CONN_S_CONNECT; + +# if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) + i = 1; + i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, + sizeof(i)); + if (i < 0) { + SYSerr(SYS_F_SOCKET, get_last_socket_error()); + ERR_add_error_data(4, "host=", c->param_hostname, + ":", c->param_port); + BIOerr(BIO_F_CONN_STATE, BIO_R_KEEPALIVE); + goto exit_loop; + } +# endif + break; + + case BIO_CONN_S_CONNECT: + BIO_clear_retry_flags(b); + ret = connect(b->num, + (struct sockaddr *)&c->them, sizeof(c->them)); + b->retry_reason = 0; + if (ret < 0) { + if (BIO_sock_should_retry(ret)) { + BIO_set_retry_special(b); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + b->retry_reason = BIO_RR_CONNECT; + } else { + SYSerr(SYS_F_CONNECT, get_last_socket_error()); + ERR_add_error_data(4, "host=", + c->param_hostname, ":", c->param_port); + BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR); + } + goto exit_loop; + } else + c->state = BIO_CONN_S_OK; + break; + + case BIO_CONN_S_BLOCKED_CONNECT: + i = BIO_sock_error(b->num); + if (i) { + BIO_clear_retry_flags(b); + SYSerr(SYS_F_CONNECT, i); + ERR_add_error_data(4, "host=", + c->param_hostname, ":", c->param_port); + BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR); + ret = 0; + goto exit_loop; + } else + c->state = BIO_CONN_S_OK; + break; + + case BIO_CONN_S_OK: + ret = 1; + goto exit_loop; + default: + /* abort(); */ + goto exit_loop; + } + + if (cb != NULL) { + if (!(ret = cb((BIO *)b, c->state, ret))) + goto end; + } + } + + /* Loop does not exit */ + exit_loop: + if (cb != NULL) + ret = cb((BIO *)b, c->state, ret); + end: + return (ret); +} + +BIO_CONNECT *BIO_CONNECT_new(void) +{ + BIO_CONNECT *ret; + + if ((ret = (BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL) + return (NULL); + ret->state = BIO_CONN_S_BEFORE; + ret->param_hostname = NULL; + ret->param_port = NULL; + ret->info_callback = NULL; + ret->nbio = 0; + ret->ip[0] = 0; + ret->ip[1] = 0; + ret->ip[2] = 0; + ret->ip[3] = 0; + ret->port = 0; + memset((char *)&ret->them, 0, sizeof(ret->them)); + return (ret); +} + +void BIO_CONNECT_free(BIO_CONNECT *a) +{ + if (a == NULL) + return; + + if (a->param_hostname != NULL) + OPENSSL_free(a->param_hostname); + if (a->param_port != NULL) + OPENSSL_free(a->param_port); + OPENSSL_free(a); +} + +BIO_METHOD *BIO_s_connect(void) +{ + return (&methods_connectp); +} + +static int conn_new(BIO *bi) +{ + bi->init = 0; + bi->num = INVALID_SOCKET; + bi->flags = 0; + if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL) + return (0); + else + return (1); +} + +static void conn_close_socket(BIO *bio) +{ + BIO_CONNECT *c; + + c = (BIO_CONNECT *)bio->ptr; + if (bio->num != INVALID_SOCKET) { + /* Only do a shutdown if things were established */ + if (c->state == BIO_CONN_S_OK) + shutdown(bio->num, 2); + closesocket(bio->num); + bio->num = INVALID_SOCKET; + } +} + +static int conn_free(BIO *a) +{ + BIO_CONNECT *data; + + if (a == NULL) + return (0); + data = (BIO_CONNECT *)a->ptr; + + if (a->shutdown) { + conn_close_socket(a); + BIO_CONNECT_free(data); + a->ptr = NULL; + a->flags = 0; + a->init = 0; + } + return (1); +} + +static int conn_read(BIO *b, char *out, int outl) +{ + int ret = 0; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(b, data); + if (ret <= 0) + return (ret); + } + + if (out != NULL) { + clear_socket_error(); + ret = readsocket(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int conn_write(BIO *b, const char *in, int inl) +{ + int ret; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(b, data); + if (ret <= 0) + return (ret); + } + + clear_socket_error(); + ret = writesocket(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + int *ip; + const char **pptr = NULL; + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = BIO_CONN_S_BEFORE; + conn_close_socket(b); + b->flags = 0; + break; + case BIO_C_DO_STATE_MACHINE: + /* use this one to start the connection */ + if (data->state != BIO_CONN_S_OK) + ret = (long)conn_state(b, data); + else + ret = 1; + break; + case BIO_C_GET_CONNECT: + if (ptr != NULL) { + pptr = (const char **)ptr; + } + + if (b->init) { + if (pptr != NULL) { + ret = 1; + if (num == 0) { + *pptr = data->param_hostname; + } else if (num == 1) { + *pptr = data->param_port; + } else if (num == 2) { + *pptr = (char *)&(data->ip[0]); + } else { + ret = 0; + } + } + if (num == 3) { + ret = data->port; + } + } else { + if (pptr != NULL) + *pptr = "not initialized"; + ret = 0; + } + break; + case BIO_C_SET_CONNECT: + if (ptr != NULL) { + b->init = 1; + if (num == 0) { + if (data->param_hostname != NULL) + OPENSSL_free(data->param_hostname); + data->param_hostname = BUF_strdup(ptr); + } else if (num == 1) { + if (data->param_port != NULL) + OPENSSL_free(data->param_port); + data->param_port = BUF_strdup(ptr); + } else if (num == 2) { + char buf[16]; + unsigned char *p = ptr; + + BIO_snprintf(buf, sizeof(buf), "%d.%d.%d.%d", + p[0], p[1], p[2], p[3]); + if (data->param_hostname != NULL) + OPENSSL_free(data->param_hostname); + data->param_hostname = BUF_strdup(buf); + memcpy(&(data->ip[0]), ptr, 4); + } else if (num == 3) { + char buf[DECIMAL_SIZE(int) + 1]; + + BIO_snprintf(buf, sizeof(buf), "%d", *(int *)ptr); + if (data->param_port != NULL) + OPENSSL_free(data->param_port); + data->param_port = BUF_strdup(buf); + data->port = *(int *)ptr; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + break; + case BIO_CTRL_DUP: + { + dbio = (BIO *)ptr; + if (data->param_port) + BIO_set_conn_port(dbio, data->param_port); + if (data->param_hostname) + BIO_set_conn_hostname(dbio, data->param_hostname); + BIO_set_nbio(dbio, data->nbio); + /* + * FIXME: the cast of the function seems unlikely to be a good + * idea + */ + (void)BIO_set_info_callback(dbio, + (bio_info_cb *)data->info_callback); + } + break; + case BIO_CTRL_SET_CALLBACK: + { +# if 0 /* FIXME: Should this be used? -- Richard + * Levitte */ + BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ret = -1; +# else + ret = 0; +# endif + } + break; + case BIO_CTRL_GET_CALLBACK: + { + int (**fptr) (const BIO *bio, int state, int xret); + + fptr = (int (**)(const BIO *bio, int state, int xret))ptr; + *fptr = data->info_callback; + } + break; + default: + ret = 0; + break; + } + return (ret); +} + +static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + { + data->info_callback = + (int (*)(const struct bio_st *, int, int))fp; + } + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int conn_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = conn_write(bp, str, n); + return (ret); +} + +BIO *BIO_new_connect(const char *str) +{ + BIO *ret; + + ret = BIO_new(BIO_s_connect()); + if (ret == NULL) + return (NULL); + if (BIO_set_conn_hostname(ret, str)) + return (ret); + else { + BIO_free(ret); + return (NULL); + } +} + +#endif +/* crypto/bio/bio_dgram.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#define USE_SOCKETS +// #include "cryptlib.h" + +// #include "bio.h" +#ifndef OPENSSL_NO_DGRAM + +# if defined(OPENSSL_SYS_VMS) +# include +# endif + +# ifndef OPENSSL_NO_SCTP +# include +# include +# define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00 +# define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0 +# endif + +# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU) +# define IP_MTU 14 /* linux is lame */ +# endif + +# if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6) +# define IPPROTO_IPV6 41 /* windows is lame */ +# endif + +# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED) +/* Standard definition causes type-punning problems. */ +# undef IN6_IS_ADDR_V4MAPPED +# define s6_addr32 __u6_addr.__u6_addr32 +# define IN6_IS_ADDR_V4MAPPED(a) \ + (((a)->s6_addr32[0] == 0) && \ + ((a)->s6_addr32[1] == 0) && \ + ((a)->s6_addr32[2] == htonl(0x0000ffff))) +# endif + +# ifdef WATT32 +# define sock_write SockWrite /* Watt-32 uses same names */ +# define sock_read SockRead +# define sock_puts SockPuts +# endif + +static int dgram_write(BIO *h, const char *buf, int num); +static int dgram_read(BIO *h, char *buf, int size); +static int dgram_puts(BIO *h, const char *str); +static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int dgram_new(BIO *h); +static int dgram_free(BIO *data); +static int dgram_clear(BIO *bio); + +# ifndef OPENSSL_NO_SCTP +static int dgram_sctp_write(BIO *h, const char *buf, int num); +static int dgram_sctp_read(BIO *h, char *buf, int size); +static int dgram_sctp_puts(BIO *h, const char *str); +static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int dgram_sctp_new(BIO *h); +static int dgram_sctp_free(BIO *data); +# ifdef SCTP_AUTHENTICATION_EVENT +static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification + *snp); +# endif +# endif + +static int BIO_dgram_should_retry(int s); + +static void get_current_time(struct timeval *t); + +static BIO_METHOD methods_dgramp = { + BIO_TYPE_DGRAM, + "datagram socket", + dgram_write, + dgram_read, + dgram_puts, + NULL, /* dgram_gets, */ + dgram_ctrl, + dgram_new, + dgram_free, + NULL, +}; + +# ifndef OPENSSL_NO_SCTP +static BIO_METHOD methods_dgramp_sctp = { + BIO_TYPE_DGRAM_SCTP, + "datagram sctp socket", + dgram_sctp_write, + dgram_sctp_read, + dgram_sctp_puts, + NULL, /* dgram_gets, */ + dgram_sctp_ctrl, + dgram_sctp_new, + dgram_sctp_free, + NULL, +}; +# endif + +typedef struct bio_dgram_data_st { + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } peer; + unsigned int connected; + unsigned int _errno; + unsigned int mtu; + struct timeval next_timeout; + struct timeval socket_timeout; +} bio_dgram_data; + +# ifndef OPENSSL_NO_SCTP +typedef struct bio_dgram_sctp_save_message_st { + BIO *bio; + char *data; + int length; +} bio_dgram_sctp_save_message; + +typedef struct bio_dgram_sctp_data_st { + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } peer; + unsigned int connected; + unsigned int _errno; + unsigned int mtu; + struct bio_dgram_sctp_sndinfo sndinfo; + struct bio_dgram_sctp_rcvinfo rcvinfo; + struct bio_dgram_sctp_prinfo prinfo; + void (*handle_notifications) (BIO *bio, void *context, void *buf); + void *notification_context; + int in_handshake; + int ccs_rcvd; + int ccs_sent; + int save_shutdown; + int peer_auth_tested; + bio_dgram_sctp_save_message saved_message; +} bio_dgram_sctp_data; +# endif + +BIO_METHOD *BIO_s_datagram(void) +{ + return (&methods_dgramp); +} + +BIO *BIO_new_dgram(int fd, int close_flag) +{ + BIO *ret; + + ret = BIO_new(BIO_s_datagram()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} + +static int dgram_new(BIO *bi) +{ + bio_dgram_data *data = NULL; + + bi->init = 0; + bi->num = 0; + data = OPENSSL_malloc(sizeof(bio_dgram_data)); + if (data == NULL) + return 0; + memset(data, 0x00, sizeof(bio_dgram_data)); + bi->ptr = data; + + bi->flags = 0; + return (1); +} + +static int dgram_free(BIO *a) +{ + bio_dgram_data *data; + + if (a == NULL) + return (0); + if (!dgram_clear(a)) + return 0; + + data = (bio_dgram_data *)a->ptr; + if (data != NULL) + OPENSSL_free(data); + + return (1); +} + +static int dgram_clear(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + SHUTDOWN2(a->num); + } + a->init = 0; + a->flags = 0; + } + return (1); +} + +static void dgram_adjust_rcv_timeout(BIO *b) +{ +# if defined(SO_RCVTIMEO) + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + union { + size_t s; + int i; + } sz = { + 0 + }; + + /* Is a timer active? */ + if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { + struct timeval timenow, timeleft; + + /* Read current socket timeout */ +# ifdef OPENSSL_SYS_WINDOWS + int timeout; + + sz.i = sizeof(timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, &sz.i) < 0) { + perror("getsockopt"); + } else { + data->socket_timeout.tv_sec = timeout / 1000; + data->socket_timeout.tv_usec = (timeout % 1000) * 1000; + } +# else + sz.i = sizeof(data->socket_timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + &(data->socket_timeout), (void *)&sz) < 0) { + perror("getsockopt"); + } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) + OPENSSL_assert(sz.s <= sizeof(data->socket_timeout)); +# endif + + /* Get current time */ + get_current_time(&timenow); + + /* Calculate time left until timer expires */ + memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); + if (timeleft.tv_usec < timenow.tv_usec) { + timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec; + timeleft.tv_sec--; + } else { + timeleft.tv_usec -= timenow.tv_usec; + } + if (timeleft.tv_sec < timenow.tv_sec) { + timeleft.tv_sec = 0; + timeleft.tv_usec = 1; + } else { + timeleft.tv_sec -= timenow.tv_sec; + } + + /* + * Adjust socket timeout if next handhake message timer will expire + * earlier. + */ + if ((data->socket_timeout.tv_sec == 0 + && data->socket_timeout.tv_usec == 0) + || (data->socket_timeout.tv_sec > timeleft.tv_sec) + || (data->socket_timeout.tv_sec == timeleft.tv_sec + && data->socket_timeout.tv_usec >= timeleft.tv_usec)) { +# ifdef OPENSSL_SYS_WINDOWS + timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) { + perror("setsockopt"); + } +# else + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + } +# endif + } + } +# endif +} + +static void dgram_reset_rcv_timeout(BIO *b) +{ +# if defined(SO_RCVTIMEO) + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + + /* Is a timer active? */ + if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { +# ifdef OPENSSL_SYS_WINDOWS + int timeout = data->socket_timeout.tv_sec * 1000 + + data->socket_timeout.tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) { + perror("setsockopt"); + } +# else + if (setsockopt + (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + } +# endif + } +# endif +} + +static int dgram_read(BIO *b, char *out, int outl) +{ + int ret = 0; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + + struct { + /* + * See commentary in b_sock.c. + */ + union { + size_t s; + int i; + } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } peer; + } sa; + + sa.len.s = 0; + sa.len.i = sizeof(sa.peer); + + if (out != NULL) { + clear_socket_error(); + memset(&sa.peer, 0x00, sizeof(sa.peer)); + dgram_adjust_rcv_timeout(b); + ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, (void *)&sa.len); + if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { + OPENSSL_assert(sa.len.s <= sizeof(sa.peer)); + sa.len.i = (int)sa.len.s; + } + + if (!data->connected && ret >= 0) + BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); + + BIO_clear_retry_flags(b); + if (ret < 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_read(b); + data->_errno = get_last_socket_error(); + } + } + + dgram_reset_rcv_timeout(b); + } + return (ret); +} + +static int dgram_write(BIO *b, const char *in, int inl) +{ + int ret; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + clear_socket_error(); + + if (data->connected) + ret = writesocket(b->num, in, inl); + else { + int peerlen = sizeof(data->peer); + + if (data->peer.sa.sa_family == AF_INET) + peerlen = sizeof(data->peer.sa_in); +# if OPENSSL_USE_IPV6 + else if (data->peer.sa.sa_family == AF_INET6) + peerlen = sizeof(data->peer.sa_in6); +# endif +# if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) + ret = sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); +# else + ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); +# endif + } + + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_write(b); + data->_errno = get_last_socket_error(); + +# if 0 /* higher layers are responsible for querying + * MTU, if necessary */ + if (data->_errno == EMSGSIZE) + /* retrieve the new MTU */ + BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); +# endif + } + } + return (ret); +} + +static long dgram_get_mtu_overhead(bio_dgram_data *data) +{ + long ret; + + switch (data->peer.sa.sa_family) { + case AF_INET: + /* + * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP + */ + ret = 28; + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: +# ifdef IN6_IS_ADDR_V4MAPPED + if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) + /* + * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP + */ + ret = 28; + else +# endif + /* + * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP + */ + ret = 48; + break; +# endif + default: + /* We don't know. Go with the historical default */ + ret = 28; + break; + } + return ret; +} + +static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + struct sockaddr *to = NULL; + bio_dgram_data *data = NULL; + int sockopt_val = 0; +# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU)) + socklen_t sockopt_len; /* assume that system supporting IP_MTU is + * modern enough to define socklen_t */ + socklen_t addr_len; + union { + struct sockaddr sa; + struct sockaddr_in s4; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 s6; +# endif + } addr; +# endif + + data = (bio_dgram_data *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + ret = 0; + break; + case BIO_CTRL_INFO: + ret = 0; + break; + case BIO_C_SET_FD: + dgram_clear(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + case BIO_CTRL_DGRAM_CONNECT: + to = (struct sockaddr *)ptr; +# if 0 + if (connect(b->num, to, sizeof(struct sockaddr)) < 0) { + perror("connect"); + ret = 0; + } else { +# endif + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; +# endif + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } +# if 0 + } +# endif + break; + /* (Linux)kernel sets DF bit on outgoing IP packets */ + case BIO_CTRL_DGRAM_MTU_DISCOVER: +# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) + addr_len = (socklen_t) sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) { + ret = 0; + break; + } + switch (addr.sa.sa_family) { + case AF_INET: + sockopt_val = IP_PMTUDISC_DO; + if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val))) < 0) + perror("setsockopt"); + break; +# if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) + case AF_INET6: + sockopt_val = IPV6_PMTUDISC_DO; + if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val))) < 0) + perror("setsockopt"); + break; +# endif + default: + ret = -1; + break; + } + ret = -1; +# else + break; +# endif + case BIO_CTRL_DGRAM_QUERY_MTU: +# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU) + addr_len = (socklen_t) sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) { + ret = 0; + break; + } + sockopt_len = sizeof(sockopt_val); + switch (addr.sa.sa_family) { + case AF_INET: + if ((ret = + getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, + &sockopt_len)) < 0 || sockopt_val < 0) { + ret = 0; + } else { + /* + * we assume that the transport protocol is UDP and no IP + * options are used. + */ + data->mtu = sockopt_val - 8 - 20; + ret = data->mtu; + } + break; +# if OPENSSL_USE_IPV6 && defined(IPV6_MTU) + case AF_INET6: + if ((ret = + getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, + (void *)&sockopt_val, &sockopt_len)) < 0 + || sockopt_val < 0) { + ret = 0; + } else { + /* + * we assume that the transport protocol is UDP and no IPV6 + * options are used. + */ + data->mtu = sockopt_val - 8 - 40; + ret = data->mtu; + } + break; +# endif + default: + ret = 0; + break; + } +# else + ret = 0; +# endif + break; + case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: + ret = -dgram_get_mtu_overhead(data); + switch (data->peer.sa.sa_family) { + case AF_INET: + ret += 576; + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: +# ifdef IN6_IS_ADDR_V4MAPPED + if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) + ret += 576; + else +# endif + ret += 1280; + break; +# endif + default: + ret += 576; + break; + } + break; + case BIO_CTRL_DGRAM_GET_MTU: + return data->mtu; + break; + case BIO_CTRL_DGRAM_SET_MTU: + data->mtu = num; + ret = num; + break; + case BIO_CTRL_DGRAM_SET_CONNECTED: + to = (struct sockaddr *)ptr; + + if (to != NULL) { + data->connected = 1; + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; +# endif + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } + } else { + data->connected = 0; + memset(&(data->peer), 0x00, sizeof(data->peer)); + } + break; + case BIO_CTRL_DGRAM_GET_PEER: + switch (data->peer.sa.sa_family) { + case AF_INET: + ret = sizeof(data->peer.sa_in); + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: + ret = sizeof(data->peer.sa_in6); + break; +# endif + default: + ret = sizeof(data->peer.sa); + break; + } + if (num == 0 || num > ret) + num = ret; + memcpy(ptr, &data->peer, (ret = num)); + break; + case BIO_CTRL_DGRAM_SET_PEER: + to = (struct sockaddr *)ptr; + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; +# endif + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } + break; + case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: + memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); + break; +# if defined(SO_RCVTIMEO) + case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: +# ifdef OPENSSL_SYS_WINDOWS + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) { + perror("setsockopt"); + ret = -1; + } + } +# else + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + ret = -1; + } +# endif + break; + case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: + { + union { + size_t s; + int i; + } sz = { + 0 + }; +# ifdef OPENSSL_SYS_WINDOWS + int timeout; + struct timeval *tv = (struct timeval *)ptr; + + sz.i = sizeof(timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, &sz.i) < 0) { + perror("getsockopt"); + ret = -1; + } else { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } +# else + sz.i = sizeof(struct timeval); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + ptr, (void *)&sz) < 0) { + perror("getsockopt"); + ret = -1; + } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { + OPENSSL_assert(sz.s <= sizeof(struct timeval)); + ret = (int)sz.s; + } else + ret = sz.i; +# endif + } + break; +# endif +# if defined(SO_SNDTIMEO) + case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: +# ifdef OPENSSL_SYS_WINDOWS + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) { + perror("setsockopt"); + ret = -1; + } + } +# else + if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + ret = -1; + } +# endif + break; + case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: + { + union { + size_t s; + int i; + } sz = { + 0 + }; +# ifdef OPENSSL_SYS_WINDOWS + int timeout; + struct timeval *tv = (struct timeval *)ptr; + + sz.i = sizeof(timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void *)&timeout, &sz.i) < 0) { + perror("getsockopt"); + ret = -1; + } else { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } +# else + sz.i = sizeof(struct timeval); + if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + ptr, (void *)&sz) < 0) { + perror("getsockopt"); + ret = -1; + } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { + OPENSSL_assert(sz.s <= sizeof(struct timeval)); + ret = (int)sz.s; + } else + ret = sz.i; +# endif + } + break; +# endif + case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: + /* fall-through */ + case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: +# ifdef OPENSSL_SYS_WINDOWS + if (data->_errno == WSAETIMEDOUT) +# else + if (data->_errno == EAGAIN) +# endif + { + ret = 1; + data->_errno = 0; + } else + ret = 0; + break; +# ifdef EMSGSIZE + case BIO_CTRL_DGRAM_MTU_EXCEEDED: + if (data->_errno == EMSGSIZE) { + ret = 1; + data->_errno = 0; + } else + ret = 0; + break; +# endif + case BIO_CTRL_DGRAM_SET_DONT_FRAG: + sockopt_val = num ? 1 : 0; + + switch (data->peer.sa.sa_family) { + case AF_INET: +# if defined(IP_DONTFRAG) + if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG, + &sockopt_val, sizeof(sockopt_val))) < 0) { + perror("setsockopt"); + ret = -1; + } +# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE) + if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT), + (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val))) < 0) { + perror("setsockopt"); + ret = -1; + } +# elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT) + if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT, + (const char *)&sockopt_val, + sizeof(sockopt_val))) < 0) { + perror("setsockopt"); + ret = -1; + } +# else + ret = -1; +# endif + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: +# if defined(IPV6_DONTFRAG) + if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG, + (const void *)&sockopt_val, + sizeof(sockopt_val))) < 0) { + perror("setsockopt"); + ret = -1; + } +# elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER) + if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT), + (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val))) < 0) { + perror("setsockopt"); + ret = -1; + } +# else + ret = -1; +# endif + break; +# endif + default: + ret = -1; + break; + } + break; + case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: + ret = dgram_get_mtu_overhead(data); + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int dgram_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = dgram_write(bp, str, n); + return (ret); +} + +# ifndef OPENSSL_NO_SCTP +BIO_METHOD *BIO_s_datagram_sctp(void) +{ + return (&methods_dgramp_sctp); +} + +BIO *BIO_new_dgram_sctp(int fd, int close_flag) +{ + BIO *bio; + int ret, optval = 20000; + int auth_data = 0, auth_forward = 0; + unsigned char *p; + struct sctp_authchunk auth; + struct sctp_authchunks *authchunks; + socklen_t sockopt_len; +# ifdef SCTP_AUTHENTICATION_EVENT +# ifdef SCTP_EVENT + struct sctp_event event; +# else + struct sctp_event_subscribe event; +# endif +# endif + + bio = BIO_new(BIO_s_datagram_sctp()); + if (bio == NULL) + return (NULL); + BIO_set_fd(bio, fd, close_flag); + + /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */ + auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE; + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, + sizeof(struct sctp_authchunk)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } + auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE; + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, + sizeof(struct sctp_authchunk)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } + + /* + * Test if activation was successful. When using accept(), SCTP-AUTH has + * to be activated for the listening socket already, otherwise the + * connected socket won't use it. + */ + sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); + authchunks = OPENSSL_malloc(sockopt_len); + if (!authchunks) { + BIO_vfree(bio); + return (NULL); + } + memset(authchunks, 0, sizeof(sockopt_len)); + ret = + getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, + &sockopt_len); + + if (ret < 0) { + OPENSSL_free(authchunks); + BIO_vfree(bio); + return (NULL); + } + + for (p = (unsigned char *)authchunks->gauth_chunks; + p < (unsigned char *)authchunks + sockopt_len; + p += sizeof(uint8_t)) { + if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) + auth_data = 1; + if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) + auth_forward = 1; + } + + OPENSSL_free(authchunks); + + OPENSSL_assert(auth_data); + OPENSSL_assert(auth_forward); + +# ifdef SCTP_AUTHENTICATION_EVENT +# ifdef SCTP_EVENT + memset(&event, 0, sizeof(struct sctp_event)); + event.se_assoc_id = 0; + event.se_type = SCTP_AUTHENTICATION_EVENT; + event.se_on = 1; + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, + sizeof(struct sctp_event)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } +# else + sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe); + ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } + + event.sctp_authentication_event = 1; + + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } +# endif +# endif + + /* + * Disable partial delivery by setting the min size larger than the max + * record size of 2^14 + 2048 + 13 + */ + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, + sizeof(optval)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } + + return (bio); +} + +int BIO_dgram_is_sctp(BIO *bio) +{ + return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP); +} + +static int dgram_sctp_new(BIO *bi) +{ + bio_dgram_sctp_data *data = NULL; + + bi->init = 0; + bi->num = 0; + data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data)); + if (data == NULL) + return 0; + memset(data, 0x00, sizeof(bio_dgram_sctp_data)); +# ifdef SCTP_PR_SCTP_NONE + data->prinfo.pr_policy = SCTP_PR_SCTP_NONE; +# endif + bi->ptr = data; + + bi->flags = 0; + return (1); +} + +static int dgram_sctp_free(BIO *a) +{ + bio_dgram_sctp_data *data; + + if (a == NULL) + return (0); + if (!dgram_clear(a)) + return 0; + + data = (bio_dgram_sctp_data *) a->ptr; + if (data != NULL) { + if (data->saved_message.data != NULL) + OPENSSL_free(data->saved_message.data); + OPENSSL_free(data); + } + + return (1); +} + +# ifdef SCTP_AUTHENTICATION_EVENT +void dgram_sctp_handle_auth_free_key_event(BIO *b, + union sctp_notification *snp) +{ + int ret; + struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event; + + if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) { + struct sctp_authkeyid authkeyid; + + /* delete key */ + authkeyid.scact_keynumber = authkeyevent->auth_keynumber; + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, + &authkeyid, sizeof(struct sctp_authkeyid)); + } +} +# endif + +static int dgram_sctp_read(BIO *b, char *out, int outl) +{ + int ret = 0, n = 0, i, optval; + socklen_t optlen; + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + union sctp_notification *snp; + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsg; + char cmsgbuf[512]; + + if (out != NULL) { + clear_socket_error(); + + do { + memset(&data->rcvinfo, 0x00, + sizeof(struct bio_dgram_sctp_rcvinfo)); + iov.iov_base = out; + iov.iov_len = outl; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = 512; + msg.msg_flags = 0; + n = recvmsg(b->num, &msg, 0); + + if (n <= 0) { + if (n < 0) + ret = n; + break; + } + + if (msg.msg_controllen > 0) { + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != IPPROTO_SCTP) + continue; +# ifdef SCTP_RCVINFO + if (cmsg->cmsg_type == SCTP_RCVINFO) { + struct sctp_rcvinfo *rcvinfo; + + rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg); + data->rcvinfo.rcv_sid = rcvinfo->rcv_sid; + data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn; + data->rcvinfo.rcv_flags = rcvinfo->rcv_flags; + data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid; + data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn; + data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn; + data->rcvinfo.rcv_context = rcvinfo->rcv_context; + } +# endif +# ifdef SCTP_SNDRCV + if (cmsg->cmsg_type == SCTP_SNDRCV) { + struct sctp_sndrcvinfo *sndrcvinfo; + + sndrcvinfo = + (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream; + data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn; + data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags; + data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid; + data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn; + data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn; + data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context; + } +# endif + } + } + + if (msg.msg_flags & MSG_NOTIFICATION) { + snp = (union sctp_notification *)out; + if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { +# ifdef SCTP_EVENT + struct sctp_event event; +# else + struct sctp_event_subscribe event; + socklen_t eventsize; +# endif + /* + * If a message has been delayed until the socket is dry, + * it can be sent now. + */ + if (data->saved_message.length > 0) { + dgram_sctp_write(data->saved_message.bio, + data->saved_message.data, + data->saved_message.length); + OPENSSL_free(data->saved_message.data); + data->saved_message.data = NULL; + data->saved_message.length = 0; + } + + /* disable sender dry event */ +# ifdef SCTP_EVENT + memset(&event, 0, sizeof(struct sctp_event)); + event.se_assoc_id = 0; + event.se_type = SCTP_SENDER_DRY_EVENT; + event.se_on = 0; + i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, + sizeof(struct sctp_event)); + if (i < 0) { + ret = i; + break; + } +# else + eventsize = sizeof(struct sctp_event_subscribe); + i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + &eventsize); + if (i < 0) { + ret = i; + break; + } + + event.sctp_sender_dry_event = 0; + + i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)); + if (i < 0) { + ret = i; + break; + } +# endif + } +# ifdef SCTP_AUTHENTICATION_EVENT + if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) + dgram_sctp_handle_auth_free_key_event(b, snp); +# endif + + if (data->handle_notifications != NULL) + data->handle_notifications(b, data->notification_context, + (void *)out); + + memset(out, 0, outl); + } else + ret += n; + } + while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) + && (ret < outl)); + + if (ret > 0 && !(msg.msg_flags & MSG_EOR)) { + /* Partial message read, this should never happen! */ + + /* + * The buffer was too small, this means the peer sent a message + * that was larger than allowed. + */ + if (ret == outl) + return -1; + + /* + * Test if socket buffer can handle max record size (2^14 + 2048 + * + 13) + */ + optlen = (socklen_t) sizeof(int); + ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen); + if (ret >= 0) + OPENSSL_assert(optval >= 18445); + + /* + * Test if SCTP doesn't partially deliver below max record size + * (2^14 + 2048 + 13) + */ + optlen = (socklen_t) sizeof(int); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, + &optval, &optlen); + if (ret >= 0) + OPENSSL_assert(optval >= 18445); + + /* + * Partially delivered notification??? Probably a bug.... + */ + OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION)); + + /* + * Everything seems ok till now, so it's most likely a message + * dropped by PR-SCTP. + */ + memset(out, 0, outl); + BIO_set_retry_read(b); + return -1; + } + + BIO_clear_retry_flags(b); + if (ret < 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_read(b); + data->_errno = get_last_socket_error(); + } + } + + /* Test if peer uses SCTP-AUTH before continuing */ + if (!data->peer_auth_tested) { + int ii, auth_data = 0, auth_forward = 0; + unsigned char *p; + struct sctp_authchunks *authchunks; + + optlen = + (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); + authchunks = OPENSSL_malloc(optlen); + if (!authchunks) { + BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE); + return -1; + } + memset(authchunks, 0, sizeof(optlen)); + ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, + authchunks, &optlen); + + if (ii >= 0) + for (p = (unsigned char *)authchunks->gauth_chunks; + p < (unsigned char *)authchunks + optlen; + p += sizeof(uint8_t)) { + if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) + auth_data = 1; + if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) + auth_forward = 1; + } + + OPENSSL_free(authchunks); + + if (!auth_data || !auth_forward) { + BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR); + return -1; + } + + data->peer_auth_tested = 1; + } + } + return (ret); +} + +static int dgram_sctp_write(BIO *b, const char *in, int inl) +{ + int ret; + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo); + struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo); + struct bio_dgram_sctp_sndinfo handshake_sinfo; + struct iovec iov[1]; + struct msghdr msg; + struct cmsghdr *cmsg; +# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) + char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + + CMSG_SPACE(sizeof(struct sctp_prinfo))]; + struct sctp_sndinfo *sndinfo; + struct sctp_prinfo *prinfo; +# else + char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct sctp_sndrcvinfo *sndrcvinfo; +# endif + + clear_socket_error(); + + /* + * If we're send anything else than application data, disable all user + * parameters and flags. + */ + if (in[0] != 23) { + memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo)); +# ifdef SCTP_SACK_IMMEDIATELY + handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY; +# endif + sinfo = &handshake_sinfo; + } + + /* + * If we have to send a shutdown alert message and the socket is not dry + * yet, we have to save it and send it as soon as the socket gets dry. + */ + if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) { + char *tmp; + data->saved_message.bio = b; + if (!(tmp = OPENSSL_malloc(inl))) { + BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE); + return -1; + } + if (data->saved_message.data) + OPENSSL_free(data->saved_message.data); + data->saved_message.data = tmp; + memcpy(data->saved_message.data, in, inl); + data->saved_message.length = inl; + return inl; + } + + iov[0].iov_base = (char *)in; + iov[0].iov_len = inl; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = (caddr_t) cmsgbuf; + msg.msg_controllen = 0; + msg.msg_flags = 0; +# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) + cmsg = (struct cmsghdr *)cmsgbuf; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); + sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg); + memset(sndinfo, 0, sizeof(struct sctp_sndinfo)); + sndinfo->snd_sid = sinfo->snd_sid; + sndinfo->snd_flags = sinfo->snd_flags; + sndinfo->snd_ppid = sinfo->snd_ppid; + sndinfo->snd_context = sinfo->snd_context; + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); + + cmsg = + (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))]; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_PRINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); + prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg); + memset(prinfo, 0, sizeof(struct sctp_prinfo)); + prinfo->pr_policy = pinfo->pr_policy; + prinfo->pr_value = pinfo->pr_value; + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); +# else + cmsg = (struct cmsghdr *)cmsgbuf; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + sndrcvinfo->sinfo_stream = sinfo->snd_sid; + sndrcvinfo->sinfo_flags = sinfo->snd_flags; +# ifdef __FreeBSD__ + sndrcvinfo->sinfo_flags |= pinfo->pr_policy; +# endif + sndrcvinfo->sinfo_ppid = sinfo->snd_ppid; + sndrcvinfo->sinfo_context = sinfo->snd_context; + sndrcvinfo->sinfo_timetolive = pinfo->pr_value; + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); +# endif + + ret = sendmsg(b->num, &msg, 0); + + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_write(b); + data->_errno = get_last_socket_error(); + } + } + return (ret); +} + +static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + bio_dgram_sctp_data *data = NULL; + socklen_t sockopt_len = 0; + struct sctp_authkeyid authkeyid; + struct sctp_authkey *authkey = NULL; + + data = (bio_dgram_sctp_data *) b->ptr; + + switch (cmd) { + case BIO_CTRL_DGRAM_QUERY_MTU: + /* + * Set to maximum (2^14) and ignore user input to enable transport + * protocol fragmentation. Returns always 2^14. + */ + data->mtu = 16384; + ret = data->mtu; + break; + case BIO_CTRL_DGRAM_SET_MTU: + /* + * Set to maximum (2^14) and ignore input to enable transport + * protocol fragmentation. Returns always 2^14. + */ + data->mtu = 16384; + ret = data->mtu; + break; + case BIO_CTRL_DGRAM_SET_CONNECTED: + case BIO_CTRL_DGRAM_CONNECT: + /* Returns always -1. */ + ret = -1; + break; + case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: + /* + * SCTP doesn't need the DTLS timer Returns always 1. + */ + break; + case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: + /* + * We allow transport protocol fragmentation so this is irrelevant + */ + ret = 0; + break; + case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE: + if (num > 0) + data->in_handshake = 1; + else + data->in_handshake = 0; + + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, + &data->in_handshake, sizeof(int)); + break; + case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY: + /* + * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise. + */ + + /* Get active key */ + sockopt_len = sizeof(struct sctp_authkeyid); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, + &sockopt_len); + if (ret < 0) + break; + + /* Add new key */ + sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t); + authkey = OPENSSL_malloc(sockopt_len); + if (authkey == NULL) { + ret = -1; + break; + } + memset(authkey, 0x00, sockopt_len); + authkey->sca_keynumber = authkeyid.scact_keynumber + 1; +# ifndef __FreeBSD__ + /* + * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3 + * and higher work without it. + */ + authkey->sca_keylength = 64; +# endif + memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t)); + + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, + sockopt_len); + OPENSSL_free(authkey); + authkey = NULL; + if (ret < 0) + break; + + /* Reset active key */ + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, + &authkeyid, sizeof(struct sctp_authkeyid)); + if (ret < 0) + break; + + break; + case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY: + /* Returns 0 on success, -1 otherwise. */ + + /* Get active key */ + sockopt_len = sizeof(struct sctp_authkeyid); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, + &sockopt_len); + if (ret < 0) + break; + + /* Set active key */ + authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1; + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, + &authkeyid, sizeof(struct sctp_authkeyid)); + if (ret < 0) + break; + + /* + * CCS has been sent, so remember that and fall through to check if + * we need to deactivate an old key + */ + data->ccs_sent = 1; + + case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD: + /* Returns 0 on success, -1 otherwise. */ + + /* + * Has this command really been called or is this just a + * fall-through? + */ + if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD) + data->ccs_rcvd = 1; + + /* + * CSS has been both, received and sent, so deactivate an old key + */ + if (data->ccs_rcvd == 1 && data->ccs_sent == 1) { + /* Get active key */ + sockopt_len = sizeof(struct sctp_authkeyid); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, + &authkeyid, &sockopt_len); + if (ret < 0) + break; + + /* + * Deactivate key or delete second last key if + * SCTP_AUTHENTICATION_EVENT is not available. + */ + authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; +# ifdef SCTP_AUTH_DEACTIVATE_KEY + sockopt_len = sizeof(struct sctp_authkeyid); + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY, + &authkeyid, sockopt_len); + if (ret < 0) + break; +# endif +# ifndef SCTP_AUTHENTICATION_EVENT + if (authkeyid.scact_keynumber > 0) { + authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, + &authkeyid, sizeof(struct sctp_authkeyid)); + if (ret < 0) + break; + } +# endif + + data->ccs_rcvd = 0; + data->ccs_sent = 0; + } + break; + case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo)) + num = sizeof(struct bio_dgram_sctp_sndinfo); + + memcpy(ptr, &(data->sndinfo), num); + ret = num; + break; + case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo)) + num = sizeof(struct bio_dgram_sctp_sndinfo); + + memcpy(&(data->sndinfo), ptr, num); + break; + case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo)) + num = sizeof(struct bio_dgram_sctp_rcvinfo); + + memcpy(ptr, &data->rcvinfo, num); + + ret = num; + break; + case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo)) + num = sizeof(struct bio_dgram_sctp_rcvinfo); + + memcpy(&(data->rcvinfo), ptr, num); + break; + case BIO_CTRL_DGRAM_SCTP_GET_PRINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_prinfo)) + num = sizeof(struct bio_dgram_sctp_prinfo); + + memcpy(ptr, &(data->prinfo), num); + ret = num; + break; + case BIO_CTRL_DGRAM_SCTP_SET_PRINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_prinfo)) + num = sizeof(struct bio_dgram_sctp_prinfo); + + memcpy(&(data->prinfo), ptr, num); + break; + case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN: + /* Returns always 1. */ + if (num > 0) + data->save_shutdown = 1; + else + data->save_shutdown = 0; + break; + + default: + /* + * Pass to default ctrl function to process SCTP unspecific commands + */ + ret = dgram_ctrl(b, cmd, num, ptr); + break; + } + return (ret); +} + +int BIO_dgram_sctp_notification_cb(BIO *b, + void (*handle_notifications) (BIO *bio, + void + *context, + void *buf), + void *context) +{ + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + + if (handle_notifications != NULL) { + data->handle_notifications = handle_notifications; + data->notification_context = context; + } else + return -1; + + return 0; +} + +int BIO_dgram_sctp_wait_for_dry(BIO *b) +{ + int is_dry = 0; + int n, sockflags, ret; + union sctp_notification snp; + struct msghdr msg; + struct iovec iov; +# ifdef SCTP_EVENT + struct sctp_event event; +# else + struct sctp_event_subscribe event; + socklen_t eventsize; +# endif + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + + /* set sender dry event */ +# ifdef SCTP_EVENT + memset(&event, 0, sizeof(struct sctp_event)); + event.se_assoc_id = 0; + event.se_type = SCTP_SENDER_DRY_EVENT; + event.se_on = 1; + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, + sizeof(struct sctp_event)); +# else + eventsize = sizeof(struct sctp_event_subscribe); + ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); + if (ret < 0) + return -1; + + event.sctp_sender_dry_event = 1; + + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)); +# endif + if (ret < 0) + return -1; + + /* peek for notification */ + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + n = recvmsg(b->num, &msg, MSG_PEEK); + if (n <= 0) { + if ((n < 0) && (get_last_socket_error() != EAGAIN) + && (get_last_socket_error() != EWOULDBLOCK)) + return -1; + else + return 0; + } + + /* if we find a notification, process it and try again if necessary */ + while (msg.msg_flags & MSG_NOTIFICATION) { + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + n = recvmsg(b->num, &msg, 0); + if (n <= 0) { + if ((n < 0) && (get_last_socket_error() != EAGAIN) + && (get_last_socket_error() != EWOULDBLOCK)) + return -1; + else + return is_dry; + } + + if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { + is_dry = 1; + + /* disable sender dry event */ +# ifdef SCTP_EVENT + memset(&event, 0, sizeof(struct sctp_event)); + event.se_assoc_id = 0; + event.se_type = SCTP_SENDER_DRY_EVENT; + event.se_on = 0; + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, + sizeof(struct sctp_event)); +# else + eventsize = (socklen_t) sizeof(struct sctp_event_subscribe); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + &eventsize); + if (ret < 0) + return -1; + + event.sctp_sender_dry_event = 0; + + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)); +# endif + if (ret < 0) + return -1; + } +# ifdef SCTP_AUTHENTICATION_EVENT + if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) + dgram_sctp_handle_auth_free_key_event(b, &snp); +# endif + + if (data->handle_notifications != NULL) + data->handle_notifications(b, data->notification_context, + (void *)&snp); + + /* found notification, peek again */ + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + /* if we have seen the dry already, don't wait */ + if (is_dry) { + sockflags = fcntl(b->num, F_GETFL, 0); + fcntl(b->num, F_SETFL, O_NONBLOCK); + } + + n = recvmsg(b->num, &msg, MSG_PEEK); + + if (is_dry) { + fcntl(b->num, F_SETFL, sockflags); + } + + if (n <= 0) { + if ((n < 0) && (get_last_socket_error() != EAGAIN) + && (get_last_socket_error() != EWOULDBLOCK)) + return -1; + else + return is_dry; + } + } + + /* read anything else */ + return is_dry; +} + +int BIO_dgram_sctp_msg_waiting(BIO *b) +{ + int n, sockflags; + union sctp_notification snp; + struct msghdr msg; + struct iovec iov; + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + + /* Check if there are any messages waiting to be read */ + do { + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + sockflags = fcntl(b->num, F_GETFL, 0); + fcntl(b->num, F_SETFL, O_NONBLOCK); + n = recvmsg(b->num, &msg, MSG_PEEK); + fcntl(b->num, F_SETFL, sockflags); + + /* if notification, process and try again */ + if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) { +# ifdef SCTP_AUTHENTICATION_EVENT + if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) + dgram_sctp_handle_auth_free_key_event(b, &snp); +# endif + + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + n = recvmsg(b->num, &msg, 0); + + if (data->handle_notifications != NULL) + data->handle_notifications(b, data->notification_context, + (void *)&snp); + } + + } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)); + + /* Return 1 if there is a message to be read, return 0 otherwise. */ + if (n > 0) + return 1; + else + return 0; +} + +static int dgram_sctp_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = dgram_sctp_write(bp, str, n); + return (ret); +} +# endif + +static int BIO_dgram_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = get_last_socket_error(); + +# if defined(OPENSSL_SYS_WINDOWS) + /* + * If the socket return value (i) is -1 and err is unexpectedly 0 at + * this point, the error code was overwritten by another system call + * before this error handling is called. + */ +# endif + + return (BIO_dgram_non_fatal_error(err)); + } + return (0); +} + +int BIO_dgram_non_fatal_error(int err) +{ + switch (err) { +# if defined(OPENSSL_SYS_WINDOWS) +# if defined(WSAEWOULDBLOCK) + case WSAEWOULDBLOCK: +# endif + +# if 0 /* This appears to always be an error */ +# if defined(WSAENOTCONN) + case WSAENOTCONN: +# endif +# endif +# endif + +# ifdef EWOULDBLOCK +# ifdef WSAEWOULDBLOCK +# if WSAEWOULDBLOCK != EWOULDBLOCK + case EWOULDBLOCK: +# endif +# else + case EWOULDBLOCK: +# endif +# endif + +# ifdef EINTR + case EINTR: +# endif + +# ifdef EAGAIN +# if EWOULDBLOCK != EAGAIN + case EAGAIN: +# endif +# endif + +# ifdef EPROTO + case EPROTO: +# endif + +# ifdef EINPROGRESS + case EINPROGRESS: +# endif + +# ifdef EALREADY + case EALREADY: +# endif + + return (1); + /* break; */ + default: + break; + } + return (0); +} + +static void get_current_time(struct timeval *t) +{ +# if defined(_WIN32) + SYSTEMTIME st; + union { + unsigned __int64 ul; + FILETIME ft; + } now; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &now.ft); +# ifdef __MINGW32__ + now.ul -= 116444736000000000ULL; +# else + now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ +# endif + t->tv_sec = (long)(now.ul / 10000000); + t->tv_usec = ((int)(now.ul % 10000000)) / 10; +# elif defined(OPENSSL_SYS_VMS) + struct timeb tb; + ftime(&tb); + t->tv_sec = (long)tb.time; + t->tv_usec = (long)tb.millitm * 1000; +# else + gettimeofday(t, NULL); +# endif +} + +#endif +/* crypto/bio/bss_fd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +// #include "cryptlib.h" + +#if defined(OPENSSL_NO_POSIX_IO) +/* + * Dummy placeholder for BIO_s_fd... + */ +BIO *BIO_new_fd(int fd, int close_flag) +{ + return NULL; +} + +int BIO_fd_non_fatal_error(int err) +{ + return 0; +} + +int BIO_fd_should_retry(int i) +{ + return 0; +} + +BIO_METHOD *BIO_s_fd(void) +{ + return NULL; +} +#else +/* + * As for unconditional usage of "UPLINK" interface in this module. + * Trouble is that unlike Unix file descriptors [which are indexes + * in kernel-side per-process table], corresponding descriptors on + * platforms which require "UPLINK" interface seem to be indexes + * in a user-land, non-global table. Well, in fact they are indexes + * in stdio _iob[], and recall that _iob[] was the very reason why + * "UPLINK" interface was introduced in first place. But one way on + * another. Neither libcrypto or libssl use this BIO meaning that + * file descriptors can only be provided by application. Therefore + * "UPLINK" calls are due... + */ +# include "bio_lcl.h" + +static int fd_write(BIO *h, const char *buf, int num); +static int fd_read(BIO *h, char *buf, int size); +static int fd_puts(BIO *h, const char *str); +static int fd_gets(BIO *h, char *buf, int size); +static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int fd_new(BIO *h); +static int fd_free(BIO *data); +int BIO_fd_should_retry(int s); + +static BIO_METHOD methods_fdp = { + BIO_TYPE_FD, "file descriptor", + fd_write, + fd_read, + fd_puts, + fd_gets, + fd_ctrl, + fd_new, + fd_free, + NULL, +}; + +BIO_METHOD *BIO_s_fd(void) +{ + return (&methods_fdp); +} + +BIO *BIO_new_fd(int fd, int close_flag) +{ + BIO *ret; + ret = BIO_new(BIO_s_fd()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} + +static int fd_new(BIO *bi) +{ + bi->init = 0; + bi->num = -1; + bi->ptr = NULL; + bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */ + return (1); +} + +static int fd_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + UP_close(a->num); + } + a->init = 0; + a->flags = BIO_FLAGS_UPLINK; + } + return (1); +} + +static int fd_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out != NULL) { + clear_sys_error(); + ret = UP_read(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_fd_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int fd_write(BIO *b, const char *in, int inl) +{ + int ret; + clear_sys_error(); + ret = UP_write(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_fd_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + case BIO_C_FILE_SEEK: + ret = (long)UP_lseek(b->num, num, 0); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = (long)UP_lseek(b->num, 0, 1); + break; + case BIO_C_SET_FD: + fd_free(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int fd_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = fd_write(bp, str, n); + return (ret); +} + +static int fd_gets(BIO *bp, char *buf, int size) +{ + int ret = 0; + char *ptr = buf; + char *end = buf + size - 1; + + while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n')) + ptr++; + + ptr[0] = '\0'; + + if (buf[0] != '\0') + ret = strlen(buf); + return (ret); +} + +int BIO_fd_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = get_last_sys_error(); + +# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps + * not? Ben 4/1/99 */ + if ((i == -1) && (err == 0)) + return (1); +# endif + + return (BIO_fd_non_fatal_error(err)); + } + return (0); +} + +int BIO_fd_non_fatal_error(int err) +{ + switch (err) { + +# ifdef EWOULDBLOCK +# ifdef WSAEWOULDBLOCK +# if WSAEWOULDBLOCK != EWOULDBLOCK + case EWOULDBLOCK: +# endif +# else + case EWOULDBLOCK: +# endif +# endif + +# if defined(ENOTCONN) + case ENOTCONN: +# endif + +# ifdef EINTR + case EINTR: +# endif + +# ifdef EAGAIN +# if EWOULDBLOCK != EAGAIN + case EAGAIN: +# endif +# endif + +# ifdef EPROTO + case EPROTO: +# endif + +# ifdef EINPROGRESS + case EINPROGRESS: +# endif + +# ifdef EALREADY + case EALREADY: +# endif + return (1); + /* break; */ + default: + break; + } + return (0); +} +#endif +/* crypto/bio/bss_file.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout + * with binary data (e.g. asn1parse -inform DER < xxx) under + * Windows + */ + +#ifndef HEADER_BSS_FILE_C +# define HEADER_BSS_FILE_C + +# if defined(__linux) || defined(__sun) || defined(__hpux) +/* + * Following definition aliases fopen to fopen64 on above mentioned + * platforms. This makes it possible to open and sequentially access files + * larger than 2GB from 32-bit application. It does not allow to traverse + * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit + * platform permits that, not with fseek/ftell. Not to mention that breaking + * 2GB limit for seeking would require surgery to *our* API. But sequential + * access suffices for practical cases when you can run into large files, + * such as fingerprinting, so we can let API alone. For reference, the list + * of 32-bit platforms which allow for sequential access of large files + * without extra "magic" comprise *BSD, Darwin, IRIX... + */ +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# endif + +# include +# include +# include "cryptlib.h" +# include "bio_lcl.h" +# include "err.h" + +# if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) +# include +# endif + +# if !defined(OPENSSL_NO_STDIO) + +static int MS_CALLBACK file_write(BIO *h, const char *buf, int num); +static int MS_CALLBACK file_read(BIO *h, char *buf, int size); +static int MS_CALLBACK file_puts(BIO *h, const char *str); +static int MS_CALLBACK file_gets(BIO *h, char *str, int size); +static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int MS_CALLBACK file_new(BIO *h); +static int MS_CALLBACK file_free(BIO *data); +static BIO_METHOD methods_filep = { + BIO_TYPE_FILE, + "FILE pointer", + file_write, + file_read, + file_puts, + file_gets, + file_ctrl, + file_new, + file_free, + NULL, +}; + +static FILE *file_fopen(const char *filename, const char *mode) +{ + FILE *file = NULL; + +# if defined(_WIN32) && defined(CP_UTF8) + int sz, len_0 = (int)strlen(filename) + 1; + DWORD flags; + + /* + * Basically there are three cases to cover: a) filename is + * pure ASCII string; b) actual UTF-8 encoded string and + * c) locale-ized string, i.e. one containing 8-bit + * characters that are meaningful in current system locale. + * If filename is pure ASCII or real UTF-8 encoded string, + * MultiByteToWideChar succeeds and _wfopen works. If + * filename is locale-ized string, chances are that + * MultiByteToWideChar fails reporting + * ERROR_NO_UNICODE_TRANSLATION, in which case we fall + * back to fopen... + */ + if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS), + filename, len_0, NULL, 0)) > 0 || + (GetLastError() == ERROR_INVALID_FLAGS && + (sz = MultiByteToWideChar(CP_UTF8, (flags = 0), + filename, len_0, NULL, 0)) > 0) + ) { + WCHAR wmode[8]; + WCHAR *wfilename = _alloca(sz * sizeof(WCHAR)); + + if (MultiByteToWideChar(CP_UTF8, flags, + filename, len_0, wfilename, sz) && + MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1, + wmode, sizeof(wmode) / sizeof(wmode[0])) && + (file = _wfopen(wfilename, wmode)) == NULL && + (errno == ENOENT || errno == EBADF) + ) { + /* + * UTF-8 decode succeeded, but no file, filename + * could still have been locale-ized... + */ + file = fopen(filename, mode); + } + } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + file = fopen(filename, mode); + } +# else + file = fopen(filename, mode); +# endif + return (file); +} + +BIO *BIO_new_file(const char *filename, const char *mode) +{ + BIO *ret; + FILE *file = file_fopen(filename, mode); + + if (file == NULL) { + SYSerr(SYS_F_FOPEN, get_last_sys_error()); + ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); + if (errno == ENOENT +# ifdef ENXIO + || errno == ENXIO +# endif + ) + BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); + else + BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB); + return (NULL); + } + if ((ret = BIO_new(BIO_s_file())) == NULL) { + fclose(file); + return (NULL); + } + + BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage + * UPLINK */ + BIO_set_fp(ret, file, BIO_CLOSE); + return (ret); +} + +BIO *BIO_new_fp(FILE *stream, int close_flag) +{ + BIO *ret; + + if ((ret = BIO_new(BIO_s_file())) == NULL) + return (NULL); + + BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for + * documentation puposes */ + BIO_set_fp(ret, stream, close_flag); + return (ret); +} + +BIO_METHOD *BIO_s_file(void) +{ + return (&methods_filep); +} + +static int MS_CALLBACK file_new(BIO *bi) +{ + bi->init = 0; + bi->num = 0; + bi->ptr = NULL; + bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */ + return (1); +} + +static int MS_CALLBACK file_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if ((a->init) && (a->ptr != NULL)) { + if (a->flags & BIO_FLAGS_UPLINK) + UP_fclose(a->ptr); + else + fclose(a->ptr); + a->ptr = NULL; + a->flags = BIO_FLAGS_UPLINK; + } + a->init = 0; + } + return (1); +} + +static int MS_CALLBACK file_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (b->init && (out != NULL)) { + if (b->flags & BIO_FLAGS_UPLINK) + ret = UP_fread(out, 1, (int)outl, b->ptr); + else + ret = fread(out, 1, (int)outl, (FILE *)b->ptr); + if (ret == 0 + && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) : + ferror((FILE *)b->ptr)) { + SYSerr(SYS_F_FREAD, get_last_sys_error()); + BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); + ret = -1; + } + } + return (ret); +} + +static int MS_CALLBACK file_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + + if (b->init && (in != NULL)) { + if (b->flags & BIO_FLAGS_UPLINK) + ret = UP_fwrite(in, (int)inl, 1, b->ptr); + else + ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr); + if (ret) + ret = inl; + /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */ + /* + * according to Tim Hudson , the commented out + * version above can cause 'inl' write calls under some stupid stdio + * implementations (VMS) + */ + } + return (ret); +} + +static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + FILE *fp = (FILE *)b->ptr; + FILE **fpp; + char p[4]; + int st; + + switch (cmd) { + case BIO_C_FILE_SEEK: + case BIO_CTRL_RESET: + if (b->flags & BIO_FLAGS_UPLINK) + ret = (long)UP_fseek(b->ptr, num, 0); + else + ret = (long)fseek(fp, num, 0); + break; + case BIO_CTRL_EOF: + if (b->flags & BIO_FLAGS_UPLINK) + ret = (long)UP_feof(fp); + else + ret = (long)feof(fp); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + if (b->flags & BIO_FLAGS_UPLINK) + ret = UP_ftell(b->ptr); + else + ret = ftell(fp); + break; + case BIO_C_SET_FILE_PTR: + file_free(b); + b->shutdown = (int)num & BIO_CLOSE; + b->ptr = ptr; + b->init = 1; +# if BIO_FLAGS_UPLINK!=0 +# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) +# define _IOB_ENTRIES 20 +# endif + /* Safety net to catch purely internal BIO_set_fp calls */ +# if defined(_MSC_VER) && _MSC_VER>=1900 + if (ptr == stdin || ptr == stdout || ptr == stderr) + BIO_clear_flags(b, BIO_FLAGS_UPLINK); +# elif defined(_IOB_ENTRIES) + if ((size_t)ptr >= (size_t)stdin && + (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) + BIO_clear_flags(b, BIO_FLAGS_UPLINK); +# endif +# endif +# ifdef UP_fsetmod + if (b->flags & BIO_FLAGS_UPLINK) + UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); + else +# endif + { +# if defined(OPENSSL_SYS_WINDOWS) + int fd = _fileno((FILE *)ptr); + if (num & BIO_FP_TEXT) + _setmode(fd, _O_TEXT); + else + _setmode(fd, _O_BINARY); +# elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) + int fd = fileno((FILE *)ptr); + /* Under CLib there are differences in file modes */ + if (num & BIO_FP_TEXT) + setmode(fd, O_TEXT); + else + setmode(fd, O_BINARY); +# elif defined(OPENSSL_SYS_MSDOS) + int fd = fileno((FILE *)ptr); + /* Set correct text/binary mode */ + if (num & BIO_FP_TEXT) + _setmode(fd, _O_TEXT); + /* Dangerous to set stdin/stdout to raw (unless redirected) */ + else { + if (fd == STDIN_FILENO || fd == STDOUT_FILENO) { + if (isatty(fd) <= 0) + _setmode(fd, _O_BINARY); + } else + _setmode(fd, _O_BINARY); + } +# elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) + int fd = fileno((FILE *)ptr); + if (num & BIO_FP_TEXT) + setmode(fd, O_TEXT); + else + setmode(fd, O_BINARY); +# endif + } + break; + case BIO_C_SET_FILENAME: + file_free(b); + b->shutdown = (int)num & BIO_CLOSE; + if (num & BIO_FP_APPEND) { + if (num & BIO_FP_READ) + BUF_strlcpy(p, "a+", sizeof(p)); + else + BUF_strlcpy(p, "a", sizeof(p)); + } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) + BUF_strlcpy(p, "r+", sizeof(p)); + else if (num & BIO_FP_WRITE) + BUF_strlcpy(p, "w", sizeof(p)); + else if (num & BIO_FP_READ) + BUF_strlcpy(p, "r", sizeof(p)); + else { + BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE); + ret = 0; + break; + } +# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) + if (!(num & BIO_FP_TEXT)) + strcat(p, "b"); + else + strcat(p, "t"); +# endif +# if defined(OPENSSL_SYS_NETWARE) + if (!(num & BIO_FP_TEXT)) + strcat(p, "b"); + else + strcat(p, "t"); +# endif + fp = file_fopen(ptr, p); + if (fp == NULL) { + SYSerr(SYS_F_FOPEN, get_last_sys_error()); + ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); + BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); + ret = 0; + break; + } + b->ptr = fp; + b->init = 1; + BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage + * UPLINK */ + break; + case BIO_C_GET_FILE_PTR: + /* the ptr parameter is actually a FILE ** in this case. */ + if (ptr != NULL) { + fpp = (FILE **)ptr; + *fpp = (FILE *)b->ptr; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_FLUSH: + st = b->flags & BIO_FLAGS_UPLINK + ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr); + if (st == EOF) { + SYSerr(SYS_F_FFLUSH, get_last_sys_error()); + ERR_add_error_data(1, "fflush()"); + BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); + ret = 0; + } + break; + case BIO_CTRL_DUP: + ret = 1; + break; + + case BIO_CTRL_WPENDING: + case BIO_CTRL_PENDING: + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + default: + ret = 0; + break; + } + return (ret); +} + +static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) +{ + int ret = 0; + + buf[0] = '\0'; + if (bp->flags & BIO_FLAGS_UPLINK) { + if (!UP_fgets(buf, size, bp->ptr)) + goto err; + } else { + if (!fgets(buf, size, (FILE *)bp->ptr)) + goto err; + } + if (buf[0] != '\0') + ret = strlen(buf); + err: + return (ret); +} + +static int MS_CALLBACK file_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = file_write(bp, str, n); + return (ret); +} + +# endif /* OPENSSL_NO_STDIO */ + +#endif /* HEADER_BSS_FILE_C */ +/* crypto/bio/bss_log.c */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Why BIO_s_log? + * + * BIO_s_log is useful for system daemons (or services under NT). It is + * one-way BIO, it sends all stuff to syslogd (on system that commonly use + * that), or event log (on NT), or OPCOM (on OpenVMS). + * + */ + +#include +#include + +// #include "cryptlib.h" + +#if defined(OPENSSL_SYS_WINCE) +#elif defined(OPENSSL_SYS_WIN32) +#elif defined(OPENSSL_SYS_VMS) +# include +# include +# include +# include +/* Some compiler options may mask the declaration of "_malloc32". */ +# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 +void *_malloc32(__size_t); +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ +# endif /* __INITIAL_POINTER_SIZE && defined + * _ANSI_C_SOURCE */ +#elif defined(__ultrix) +# include +#elif defined(OPENSSL_SYS_NETWARE) +# define NO_SYSLOG +#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) +# include +#endif + +#include "buffer.h" +// #include "err.h" + +#ifndef NO_SYSLOG + +# if defined(OPENSSL_SYS_WIN32) +# define LOG_EMERG 0 +# define LOG_ALERT 1 +# define LOG_CRIT 2 +# define LOG_ERR 3 +# define LOG_WARNING 4 +# define LOG_NOTICE 5 +# define LOG_INFO 6 +# define LOG_DEBUG 7 + +# define LOG_DAEMON (3<<3) +# elif defined(OPENSSL_SYS_VMS) +/* On VMS, we don't really care about these, but we need them to compile */ +# define LOG_EMERG 0 +# define LOG_ALERT 1 +# define LOG_CRIT 2 +# define LOG_ERR 3 +# define LOG_WARNING 4 +# define LOG_NOTICE 5 +# define LOG_INFO 6 +# define LOG_DEBUG 7 + +# define LOG_DAEMON OPC$M_NM_NTWORK +# endif + +static int MS_CALLBACK slg_write(BIO *h, const char *buf, int num); +static int MS_CALLBACK slg_puts(BIO *h, const char *str); +static long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int MS_CALLBACK slg_new(BIO *h); +static int MS_CALLBACK slg_free(BIO *data); +static void xopenlog(BIO *bp, char *name, int level); +static void xsyslog(BIO *bp, int priority, const char *string); +static void xcloselog(BIO *bp); + +static BIO_METHOD methods_slg = { + BIO_TYPE_MEM, "syslog", + slg_write, + NULL, + slg_puts, + NULL, + slg_ctrl, + slg_new, + slg_free, + NULL, +}; + +BIO_METHOD *BIO_s_log(void) +{ + return (&methods_slg); +} + +static int MS_CALLBACK slg_new(BIO *bi) +{ + bi->init = 1; + bi->num = 0; + bi->ptr = NULL; + xopenlog(bi, "application", LOG_DAEMON); + return (1); +} + +static int MS_CALLBACK slg_free(BIO *a) +{ + if (a == NULL) + return (0); + xcloselog(a); + return (1); +} + +static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) +{ + int ret = inl; + char *buf; + char *pp; + int priority, i; + static const struct { + int strl; + char str[10]; + int log_level; + } mapping[] = { + { + 6, "PANIC ", LOG_EMERG + }, + { + 6, "EMERG ", LOG_EMERG + }, + { + 4, "EMR ", LOG_EMERG + }, + { + 6, "ALERT ", LOG_ALERT + }, + { + 4, "ALR ", LOG_ALERT + }, + { + 5, "CRIT ", LOG_CRIT + }, + { + 4, "CRI ", LOG_CRIT + }, + { + 6, "ERROR ", LOG_ERR + }, + { + 4, "ERR ", LOG_ERR + }, + { + 8, "WARNING ", LOG_WARNING + }, + { + 5, "WARN ", LOG_WARNING + }, + { + 4, "WAR ", LOG_WARNING + }, + { + 7, "NOTICE ", LOG_NOTICE + }, + { + 5, "NOTE ", LOG_NOTICE + }, + { + 4, "NOT ", LOG_NOTICE + }, + { + 5, "INFO ", LOG_INFO + }, + { + 4, "INF ", LOG_INFO + }, + { + 6, "DEBUG ", LOG_DEBUG + }, + { + 4, "DBG ", LOG_DEBUG + }, + { + 0, "", LOG_ERR + } + /* The default */ + }; + + if ((buf = (char *)OPENSSL_malloc(inl + 1)) == NULL) { + return (0); + } + memcpy(buf, in, inl); + buf[inl] = '\0'; + + i = 0; + while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0) + i++; + priority = mapping[i].log_level; + pp = buf + mapping[i].strl; + + xsyslog(b, priority, pp); + + OPENSSL_free(buf); + return (ret); +} + +static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + switch (cmd) { + case BIO_CTRL_SET: + xcloselog(b); + xopenlog(b, ptr, num); + break; + default: + break; + } + return (0); +} + +static int MS_CALLBACK slg_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = slg_write(bp, str, n); + return (ret); +} + +# if defined(OPENSSL_SYS_WIN32) + +static void xopenlog(BIO *bp, char *name, int level) +{ + if (check_winnt()) + bp->ptr = RegisterEventSourceA(NULL, name); + else + bp->ptr = NULL; +} + +static void xsyslog(BIO *bp, int priority, const char *string) +{ + LPCSTR lpszStrings[2]; + WORD evtype = EVENTLOG_ERROR_TYPE; + char pidbuf[DECIMAL_SIZE(DWORD) + 4]; + + if (bp->ptr == NULL) + return; + + switch (priority) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + evtype = EVENTLOG_ERROR_TYPE; + break; + case LOG_WARNING: + evtype = EVENTLOG_WARNING_TYPE; + break; + case LOG_NOTICE: + case LOG_INFO: + case LOG_DEBUG: + evtype = EVENTLOG_INFORMATION_TYPE; + break; + default: + /* + * Should never happen, but set it + * as error anyway. + */ + evtype = EVENTLOG_ERROR_TYPE; + break; + } + + sprintf(pidbuf, "[%u] ", GetCurrentProcessId()); + lpszStrings[0] = pidbuf; + lpszStrings[1] = string; + + ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL); +} + +static void xcloselog(BIO *bp) +{ + if (bp->ptr) + DeregisterEventSource((HANDLE) (bp->ptr)); + bp->ptr = NULL; +} + +# elif defined(OPENSSL_SYS_VMS) + +static int VMS_OPC_target = LOG_DAEMON; + +static void xopenlog(BIO *bp, char *name, int level) +{ + VMS_OPC_target = level; +} + +static void xsyslog(BIO *bp, int priority, const char *string) +{ + struct dsc$descriptor_s opc_dsc; + +/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */ +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 +# define OPCDEF_TYPE __char_ptr32 +# define OPCDEF_MALLOC _malloc32 +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define OPCDEF_TYPE char * +# define OPCDEF_MALLOC OPENSSL_malloc +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + struct opcdef *opcdef_p; + +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ + + char buf[10240]; + unsigned int len; + struct dsc$descriptor_s buf_dsc; + $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); + char *priority_tag; + + switch (priority) { + case LOG_EMERG: + priority_tag = "Emergency"; + break; + case LOG_ALERT: + priority_tag = "Alert"; + break; + case LOG_CRIT: + priority_tag = "Critical"; + break; + case LOG_ERR: + priority_tag = "Error"; + break; + case LOG_WARNING: + priority_tag = "Warning"; + break; + case LOG_NOTICE: + priority_tag = "Notice"; + break; + case LOG_INFO: + priority_tag = "Info"; + break; + case LOG_DEBUG: + priority_tag = "DEBUG"; + break; + } + + buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + buf_dsc.dsc$b_class = DSC$K_CLASS_S; + buf_dsc.dsc$a_pointer = buf; + buf_dsc.dsc$w_length = sizeof(buf) - 1; + + lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); + + /* We know there's an 8-byte header. That's documented. */ + opcdef_p = OPCDEF_MALLOC(8 + len); + opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; + memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); + opcdef_p->opc$l_ms_rqstid = 0; + memcpy(&opcdef_p->opc$l_ms_text, buf, len); + + opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + opc_dsc.dsc$b_class = DSC$K_CLASS_S; + opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p; + opc_dsc.dsc$w_length = len + 8; + + sys$sndopr(opc_dsc, 0); + + OPENSSL_free(opcdef_p); +} + +static void xcloselog(BIO *bp) +{ +} + +# else /* Unix/Watt32 */ + +static void xopenlog(BIO *bp, char *name, int level) +{ +# ifdef WATT32 /* djgpp/DOS */ + openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level); +# else + openlog(name, LOG_PID | LOG_CONS, level); +# endif +} + +static void xsyslog(BIO *bp, int priority, const char *string) +{ + syslog(priority, "%s", string); +} + +static void xcloselog(BIO *bp) +{ + closelog(); +} + +# endif /* Unix */ + +#endif /* NO_SYSLOG */ +/* crypto/bio/bss_mem.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "bio.h" + +static int mem_write(BIO *h, const char *buf, int num); +static int mem_read(BIO *h, char *buf, int size); +static int mem_puts(BIO *h, const char *str); +static int mem_gets(BIO *h, char *str, int size); +static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int mem_new(BIO *h); +static int mem_free(BIO *data); +static BIO_METHOD mem_method = { + BIO_TYPE_MEM, + "memory buffer", + mem_write, + mem_read, + mem_puts, + mem_gets, + mem_ctrl, + mem_new, + mem_free, + NULL, +}; + +/* + * bio->num is used to hold the value to return on 'empty', if it is 0, + * should_retry is not set + */ + +BIO_METHOD *BIO_s_mem(void) +{ + return (&mem_method); +} + + +BIO *BIO_new_mem_buf(const void *buf, int len) +{ + BIO *ret; + BUF_MEM *b; + size_t sz; + + if (!buf) { + BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER); + return NULL; + } + sz = (len < 0) ? strlen(buf) : (size_t)len; + if (!(ret = BIO_new(BIO_s_mem()))) + return NULL; + b = (BUF_MEM *)ret->ptr; + /* Cast away const and trust in the MEM_RDONLY flag. */ + b->data = (void *)buf; + b->length = sz; + b->max = sz; + ret->flags |= BIO_FLAGS_MEM_RDONLY; + /* Since this is static data retrying wont help */ + ret->num = 0; + return ret; +} + +static int mem_new(BIO *bi) +{ + BUF_MEM *b; + + if ((b = BUF_MEM_new()) == NULL) + return (0); + bi->shutdown = 1; + bi->init = 1; + bi->num = -1; + bi->ptr = (char *)b; + return (1); +} + +static int mem_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if ((a->init) && (a->ptr != NULL)) { + BUF_MEM *b; + b = (BUF_MEM *)a->ptr; + if (a->flags & BIO_FLAGS_MEM_RDONLY) + b->data = NULL; + BUF_MEM_free(b); + a->ptr = NULL; + } + } + return (1); +} + +static int mem_read(BIO *b, char *out, int outl) +{ + int ret = -1; + BUF_MEM *bm; + + bm = (BUF_MEM *)b->ptr; + BIO_clear_retry_flags(b); + ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl; + if ((out != NULL) && (ret > 0)) { + memcpy(out, bm->data, ret); + bm->length -= ret; + if (b->flags & BIO_FLAGS_MEM_RDONLY) + bm->data += ret; + else { + memmove(&(bm->data[0]), &(bm->data[ret]), bm->length); + } + } else if (bm->length == 0) { + ret = b->num; + if (ret != 0) + BIO_set_retry_read(b); + } + return (ret); +} + +static int mem_write(BIO *b, const char *in, int inl) +{ + int ret = -1; + int blen; + BUF_MEM *bm; + + bm = (BUF_MEM *)b->ptr; + if (in == NULL) { + BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER); + goto end; + } + + if (b->flags & BIO_FLAGS_MEM_RDONLY) { + BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO); + goto end; + } + + BIO_clear_retry_flags(b); + if (inl == 0) + return 0; + blen = bm->length; + if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl)) + goto end; + memcpy(&(bm->data[blen]), in, inl); + ret = inl; + end: + return (ret); +} + +static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + char **pptr; + + BUF_MEM *bm = (BUF_MEM *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (bm->data != NULL) { + /* For read only case reset to the start again */ + if (b->flags & BIO_FLAGS_MEM_RDONLY) { + bm->data -= bm->max - bm->length; + bm->length = bm->max; + } else { + memset(bm->data, 0, bm->max); + bm->length = 0; + } + } + break; + case BIO_CTRL_EOF: + ret = (long)(bm->length == 0); + break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + b->num = (int)num; + break; + case BIO_CTRL_INFO: + ret = (long)bm->length; + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)&(bm->data[0]); + } + break; + case BIO_C_SET_BUF_MEM: + mem_free(b); + b->shutdown = (int)num; + b->ptr = ptr; + break; + case BIO_C_GET_BUF_MEM_PTR: + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)bm; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + + case BIO_CTRL_WPENDING: + ret = 0L; + break; + case BIO_CTRL_PENDING: + ret = (long)bm->length; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + default: + ret = 0; + break; + } + return (ret); +} + +static int mem_gets(BIO *bp, char *buf, int size) +{ + int i, j; + int ret = -1; + char *p; + BUF_MEM *bm = (BUF_MEM *)bp->ptr; + + BIO_clear_retry_flags(bp); + j = bm->length; + if ((size - 1) < j) + j = size - 1; + if (j <= 0) { + *buf = '\0'; + return 0; + } + p = bm->data; + for (i = 0; i < j; i++) { + if (p[i] == '\n') { + i++; + break; + } + } + + /* + * i is now the max num of bytes to copy, either j or up to + * and including the first newline + */ + + i = mem_read(bp, buf, i); + if (i > 0) + buf[i] = '\0'; + ret = i; + return (ret); +} + +static int mem_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = mem_write(bp, str, n); + /* memory semantics is that it will always work */ + return (ret); +} +/* crypto/bio/bss_null.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "bio.h" + +static int null_write(BIO *h, const char *buf, int num); +static int null_read(BIO *h, char *buf, int size); +static int null_puts(BIO *h, const char *str); +static int null_gets(BIO *h, char *str, int size); +static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int null_new(BIO *h); +static int null_free(BIO *data); +static BIO_METHOD null_method = { + BIO_TYPE_NULL, + "NULL", + null_write, + null_read, + null_puts, + null_gets, + null_ctrl, + null_new, + null_free, + NULL, +}; + +BIO_METHOD *BIO_s_null(void) +{ + return (&null_method); +} + +static int null_new(BIO *bi) +{ + bi->init = 1; + bi->num = 0; + bi->ptr = (NULL); + return (1); +} + +static int null_free(BIO *a) +{ + if (a == NULL) + return (0); + return (1); +} + +static int null_read(BIO *b, char *out, int outl) +{ + return (0); +} + +static int null_write(BIO *b, const char *in, int inl) +{ + return (inl); +} + +static long null_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + + switch (cmd) { + case BIO_CTRL_RESET: + case BIO_CTRL_EOF: + case BIO_CTRL_SET: + case BIO_CTRL_SET_CLOSE: + case BIO_CTRL_FLUSH: + case BIO_CTRL_DUP: + ret = 1; + break; + case BIO_CTRL_GET_CLOSE: + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + default: + ret = 0; + break; + } + return (ret); +} + +static int null_gets(BIO *bp, char *buf, int size) +{ + return (0); +} + +static int null_puts(BIO *bp, const char *str) +{ + if (str == NULL) + return (0); + return (strlen(str)); +} +/* crypto/bio/bss_sock.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +// #include "cryptlib.h" + +#ifndef OPENSSL_NO_SOCK + +# include "bio.h" + +# ifdef WATT32 +# define sock_write SockWrite /* Watt-32 uses same names */ +# define sock_read SockRead +# define sock_puts SockPuts +# endif + +static int sock_write(BIO *h, const char *buf, int num); +static int sock_read(BIO *h, char *buf, int size); +static int sock_puts(BIO *h, const char *str); +static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int sock_new(BIO *h); +static int sock_free(BIO *data); +int BIO_sock_should_retry(int s); + +static BIO_METHOD methods_sockp = { + BIO_TYPE_SOCKET, + "socket", + sock_write, + sock_read, + sock_puts, + NULL, /* sock_gets, */ + sock_ctrl, + sock_new, + sock_free, + NULL, +}; + +BIO_METHOD *BIO_s_socket(void) +{ + return (&methods_sockp); +} + +BIO *BIO_new_socket(int fd, int close_flag) +{ + BIO *ret; + + ret = BIO_new(BIO_s_socket()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} + +static int sock_new(BIO *bi) +{ + bi->init = 0; + bi->num = 0; + bi->ptr = NULL; + bi->flags = 0; + return (1); +} + +static int sock_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + SHUTDOWN2(a->num); + } + a->init = 0; + a->flags = 0; + } + return (1); +} + +static int sock_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out != NULL) { + clear_socket_error(); + ret = readsocket(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int sock_write(BIO *b, const char *in, int inl) +{ + int ret; + + clear_socket_error(); + ret = writesocket(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + + switch (cmd) { + case BIO_C_SET_FD: + sock_free(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int sock_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = sock_write(bp, str, n); + return (ret); +} + +int BIO_sock_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = get_last_socket_error(); + +# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps + * not? Ben 4/1/99 */ + if ((i == -1) && (err == 0)) + return (1); +# endif + + return (BIO_sock_non_fatal_error(err)); + } + return (0); +} + +int BIO_sock_non_fatal_error(int err) +{ + switch (err) { +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) +# if defined(WSAEWOULDBLOCK) + case WSAEWOULDBLOCK: +# endif + +# if 0 /* This appears to always be an error */ +# if defined(WSAENOTCONN) + case WSAENOTCONN: +# endif +# endif +# endif + +# ifdef EWOULDBLOCK +# ifdef WSAEWOULDBLOCK +# if WSAEWOULDBLOCK != EWOULDBLOCK + case EWOULDBLOCK: +# endif +# else + case EWOULDBLOCK: +# endif +# endif + +# if defined(ENOTCONN) + case ENOTCONN: +# endif + +# ifdef EINTR + case EINTR: +# endif + +# ifdef EAGAIN +# if EWOULDBLOCK != EAGAIN + case EAGAIN: +# endif +# endif + +# ifdef EPROTO + case EPROTO: +# endif + +# ifdef EINPROGRESS + case EINPROGRESS: +# endif + +# ifdef EALREADY + case EALREADY: +# endif + return (1); + /* break; */ + default: + break; + } + return (0); +} + +#endif /* #ifndef OPENSSL_NO_SOCK */ diff --git a/Sources/COpenSSL/buf_.c b/Sources/COpenSSL/buf_.c new file mode 100644 index 00000000..a2889b81 --- /dev/null +++ b/Sources/COpenSSL/buf_.c @@ -0,0 +1,234 @@ +/* crypto/buffer/buf_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "buffer.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason) + +static ERR_STRING_DATA BUF_str_functs[] = { + {ERR_FUNC(BUF_F_BUF_MEMDUP), "BUF_memdup"}, + {ERR_FUNC(BUF_F_BUF_MEM_GROW), "BUF_MEM_grow"}, + {ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN), "BUF_MEM_grow_clean"}, + {ERR_FUNC(BUF_F_BUF_MEM_NEW), "BUF_MEM_new"}, + {ERR_FUNC(BUF_F_BUF_STRDUP), "BUF_strdup"}, + {ERR_FUNC(BUF_F_BUF_STRNDUP), "BUF_strndup"}, + {0, NULL} +}; + +static ERR_STRING_DATA BUF_str_reasons[] = { + {0, NULL} +}; + +#endif + +void ERR_load_BUF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) { + ERR_load_strings(0, BUF_str_functs); + ERR_load_strings(0, BUF_str_reasons); + } +#endif +} +/* crypto/buffer/buffer.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +// #include "buffer.h" + +size_t BUF_strnlen(const char *str, size_t maxlen) +{ + const char *p; + + for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ; + + return p - str; +} + +char *BUF_strdup(const char *str) +{ + if (str == NULL) + return NULL; + return BUF_strndup(str, strlen(str)); +} + +char *BUF_strndup(const char *str, size_t siz) +{ + char *ret; + + if (str == NULL) + return NULL; + + siz = BUF_strnlen(str, siz); + + if (siz >= INT_MAX) + return NULL; + + ret = OPENSSL_malloc(siz + 1); + if (ret == NULL) { + BUFerr(BUF_F_BUF_STRNDUP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + memcpy(ret, str, siz); + ret[siz] = '\0'; + + return (ret); +} + +void *BUF_memdup(const void *data, size_t siz) +{ + void *ret; + + if (data == NULL || siz >= INT_MAX) + return NULL; + + ret = OPENSSL_malloc(siz); + if (ret == NULL) { + BUFerr(BUF_F_BUF_MEMDUP, ERR_R_MALLOC_FAILURE); + return NULL; + } + return memcpy(ret, data, siz); +} + +size_t BUF_strlcpy(char *dst, const char *src, size_t size) +{ + size_t l = 0; + for (; size > 1 && *src; size--) { + *dst++ = *src++; + l++; + } + if (size) + *dst = '\0'; + return l + strlen(src); +} + +size_t BUF_strlcat(char *dst, const char *src, size_t size) +{ + size_t l = 0; + for (; size > 0 && *dst; size--, dst++) + l++; + return l + BUF_strlcpy(dst, src, size); +} diff --git a/Sources/COpenSSL/buffer.c b/Sources/COpenSSL/buffer.c new file mode 100644 index 00000000..82f462e8 --- /dev/null +++ b/Sources/COpenSSL/buffer.c @@ -0,0 +1,187 @@ +/* crypto/buffer/buffer.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "buffer.h" + +/* + * LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That + * function is applied in several functions in this file and this limit + * ensures that the result fits in an int. + */ +#define LIMIT_BEFORE_EXPANSION 0x5ffffffc + +BUF_MEM *BUF_MEM_new(void) +{ + BUF_MEM *ret; + + ret = OPENSSL_malloc(sizeof(BUF_MEM)); + if (ret == NULL) { + BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->length = 0; + ret->max = 0; + ret->data = NULL; + return (ret); +} + +void BUF_MEM_free(BUF_MEM *a) +{ + if (a == NULL) + return; + + if (a->data != NULL) { + OPENSSL_cleanse(a->data, a->max); + OPENSSL_free(a->data); + } + OPENSSL_free(a); +} + +int BUF_MEM_grow(BUF_MEM *str, size_t len) +{ + char *ret; + size_t n; + + if (str->length >= len) { + str->length = len; + return (len); + } + if (str->max >= len) { + memset(&str->data[str->length], 0, len - str->length); + str->length = len; + return (len); + } + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ + if (len > LIMIT_BEFORE_EXPANSION) { + BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE); + return 0; + } + n = (len + 3) / 3 * 4; + if (str->data == NULL) + ret = OPENSSL_malloc(n); + else + ret = OPENSSL_realloc(str->data, n); + if (ret == NULL) { + BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE); + len = 0; + } else { + str->data = ret; + str->max = n; + memset(&str->data[str->length], 0, len - str->length); + str->length = len; + } + return (len); +} + +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len) +{ + char *ret; + size_t n; + + if (str->length >= len) { + memset(&str->data[len], 0, str->length - len); + str->length = len; + return (len); + } + if (str->max >= len) { + memset(&str->data[str->length], 0, len - str->length); + str->length = len; + return (len); + } + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ + if (len > LIMIT_BEFORE_EXPANSION) { + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); + return 0; + } + n = (len + 3) / 3 * 4; + if (str->data == NULL) + ret = OPENSSL_malloc(n); + else + ret = OPENSSL_realloc_clean(str->data, str->max, n); + if (ret == NULL) { + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); + len = 0; + } else { + str->data = ret; + str->max = n; + memset(&str->data[str->length], 0, len - str->length); + str->length = len; + } + return (len); +} + +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t size) +{ + size_t i; + if (in) { + out += size - 1; + for (i = 0; i < size; i++) + *out-- = *in++; + } else { + unsigned char *q; + char c; + q = out + size - 1; + for (i = 0; i < size / 2; i++) { + c = *q; + *q-- = *out; + *out++ = c; + } + } +} diff --git a/Sources/COpenSSL/buffer.h b/Sources/COpenSSL/buffer.h new file mode 100644 index 00000000..546c9ec8 --- /dev/null +++ b/Sources/COpenSSL/buffer.h @@ -0,0 +1,125 @@ +/* crypto/buffer/buffer.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BUFFER_H +# define HEADER_BUFFER_H + +# include "ossl_typ.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# if !defined(NO_SYS_TYPES_H) +# include +# endif + +/* Already declared in ossl_typ.h */ +/* typedef struct buf_mem_st BUF_MEM; */ + +struct buf_mem_st { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ +}; + +BUF_MEM *BUF_MEM_new(void); +void BUF_MEM_free(BUF_MEM *a); +int BUF_MEM_grow(BUF_MEM *str, size_t len); +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); +size_t BUF_strnlen(const char *str, size_t maxlen); +char *BUF_strdup(const char *str); + +/* + * Like strndup, but in addition, explicitly guarantees to never read past the + * first |siz| bytes of |str|. + */ +char *BUF_strndup(const char *str, size_t siz); + +void *BUF_memdup(const void *data, size_t siz); +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); + +/* safe string functions */ +size_t BUF_strlcpy(char *dst, const char *src, size_t siz); +size_t BUF_strlcat(char *dst, const char *src, size_t siz); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BUF_strings(void); + +/* Error codes for the BUF functions. */ + +/* Function codes. */ +# define BUF_F_BUF_MEMDUP 103 +# define BUF_F_BUF_MEM_GROW 100 +# define BUF_F_BUF_MEM_GROW_CLEAN 105 +# define BUF_F_BUF_MEM_NEW 101 +# define BUF_F_BUF_STRDUP 102 +# define BUF_F_BUF_STRNDUP 104 + +/* Reason codes. */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/buildinf.h b/Sources/COpenSSL/buildinf.h new file mode 100644 index 00000000..2e287c42 --- /dev/null +++ b/Sources/COpenSSL/buildinf.h @@ -0,0 +1,5 @@ +#ifndef MK1MF_BUILD +# define CFLAGS "-DB_ENDIAN" +# define PLATFORM "macos" +# define DATE "Sun Feb 27 19:44:16 MET 2000" +#endif diff --git a/Sources/COpenSSL/by_.c b/Sources/COpenSSL/by_.c new file mode 100644 index 00000000..ff48e154 --- /dev/null +++ b/Sources/COpenSSL/by_.c @@ -0,0 +1,719 @@ +/* crypto/x509/by_dir.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "cryptlib.h" + +#ifndef NO_SYS_TYPES_H +# include +#endif +#ifndef OPENSSL_NO_POSIX_IO +# include +#endif + +#include "lhash.h" +#include "x509.h" + +typedef struct lookup_dir_hashes_st { + unsigned long hash; + int suffix; +} BY_DIR_HASH; + +typedef struct lookup_dir_entry_st { + char *dir; + int dir_type; + STACK_OF(BY_DIR_HASH) *hashes; +} BY_DIR_ENTRY; + +typedef struct lookup_dir_st { + BUF_MEM *buffer; + STACK_OF(BY_DIR_ENTRY) *dirs; +} BY_DIR; + +DECLARE_STACK_OF(BY_DIR_HASH) +DECLARE_STACK_OF(BY_DIR_ENTRY) + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret); +static int new_dir(X509_LOOKUP *lu); +static void free_dir(X509_LOOKUP *lu); +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret); +X509_LOOKUP_METHOD x509_dir_lookup = { + "Load certs from files in a directory", + new_dir, /* new */ + free_dir, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + dir_ctrl, /* ctrl */ + get_cert_by_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) +{ + return (&x509_dir_lookup); +} + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **retp) +{ + int ret = 0; + BY_DIR *ld; + char *dir = NULL; + + ld = (BY_DIR *)ctx->method_data; + + switch (cmd) { + case X509_L_ADD_DIR: + if (argl == X509_FILETYPE_DEFAULT) { + dir = (char *)ossl_safe_getenv(X509_get_default_cert_dir_env()); + if (dir) + ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); + else + ret = add_cert_dir(ld, X509_get_default_cert_dir(), + X509_FILETYPE_PEM); + if (!ret) { + X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR); + } + } else + ret = add_cert_dir(ld, argp, (int)argl); + break; + } + return (ret); +} + +static int new_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) + return (0); + if ((a->buffer = BUF_MEM_new()) == NULL) { + OPENSSL_free(a); + return (0); + } + a->dirs = NULL; + lu->method_data = (char *)a; + return (1); +} + +static void by_dir_hash_free(BY_DIR_HASH *hash) +{ + OPENSSL_free(hash); +} + +static int by_dir_hash_cmp(const BY_DIR_HASH *const *a, + const BY_DIR_HASH *const *b) +{ + if ((*a)->hash > (*b)->hash) + return 1; + if ((*a)->hash < (*b)->hash) + return -1; + return 0; +} + +static void by_dir_entry_free(BY_DIR_ENTRY *ent) +{ + if (ent->dir) + OPENSSL_free(ent->dir); + if (ent->hashes) + sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); + OPENSSL_free(ent); +} + +static void free_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + a = (BY_DIR *)lu->method_data; + if (a->dirs != NULL) + sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); + if (a->buffer != NULL) + BUF_MEM_free(a->buffer); + OPENSSL_free(a); +} + +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) +{ + int j, len; + const char *s, *ss, *p; + + if (dir == NULL || !*dir) { + X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY); + return 0; + } + + s = dir; + p = s; + do { + if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) { + BY_DIR_ENTRY *ent; + ss = s; + s = p + 1; + len = (int)(p - ss); + if (len == 0) + continue; + for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); + if (strlen(ent->dir) == (size_t)len && + strncmp(ent->dir, ss, (unsigned int)len) == 0) + break; + } + if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) + continue; + if (ctx->dirs == NULL) { + ctx->dirs = sk_BY_DIR_ENTRY_new_null(); + if (!ctx->dirs) { + X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY)); + if (!ent) + return 0; + ent->dir_type = type; + ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); + ent->dir = OPENSSL_malloc((unsigned int)len + 1); + if (!ent->dir || !ent->hashes) { + by_dir_entry_free(ent); + return 0; + } + strncpy(ent->dir, ss, (unsigned int)len); + ent->dir[len] = '\0'; + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + by_dir_entry_free(ent); + return 0; + } + } + } while (*p++ != '\0'); + return 1; +} + +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + BY_DIR *ctx; + union { + struct { + X509 st_x509; + X509_CINF st_x509_cinf; + } x509; + struct { + X509_CRL st_crl; + X509_CRL_INFO st_crl_info; + } crl; + } data; + int ok = 0; + int i, j, k; + unsigned long h; + BUF_MEM *b = NULL; + X509_OBJECT stmp, *tmp; + const char *postfix = ""; + + if (name == NULL) + return (0); + + stmp.type = type; + if (type == X509_LU_X509) { + data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; + data.x509.st_x509_cinf.subject = name; + stmp.data.x509 = &data.x509.st_x509; + postfix = ""; + } else if (type == X509_LU_CRL) { + data.crl.st_crl.crl = &data.crl.st_crl_info; + data.crl.st_crl_info.issuer = name; + stmp.data.crl = &data.crl.st_crl; + postfix = "r"; + } else { + X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b = BUF_MEM_new()) == NULL) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB); + goto finish; + } + + ctx = (BY_DIR *)xl->method_data; + + h = X509_NAME_hash(name); + for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { + BY_DIR_ENTRY *ent; + int idx; + BY_DIR_HASH htmp, *hent; + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); + j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; + if (!BUF_MEM_grow(b, j)) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + goto finish; + } + if (type == X509_LU_CRL && ent->hashes) { + htmp.hash = h; + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } else { + hent = NULL; + k = 0; + } + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + } else { + k = 0; + hent = NULL; + } + for (;;) { + char c = '/'; +#ifdef OPENSSL_SYS_VMS + c = ent->dir[strlen(ent->dir) - 1]; + if (c != ':' && c != '>' && c != ']') { + /* + * If no separator is present, we assume the directory + * specifier is a logical name, and add a colon. We really + * should use better VMS routines for merging things like + * this, but this will do for now... -- Richard Levitte + */ + c = ':'; + } else { + c = '\0'; + } +#endif + if (c == '\0') { + /* + * This is special. When c == '\0', no directory separator + * should be added. + */ + BIO_snprintf(b->data, b->max, + "%s%08lx.%s%d", ent->dir, h, postfix, k); + } else { + BIO_snprintf(b->data, b->max, + "%s%c%08lx.%s%d", ent->dir, c, h, postfix, k); + } +#ifndef OPENSSL_NO_POSIX_IO +# ifdef _WIN32 +# define stat _stat +# endif + { + struct stat st; + if (stat(b->data, &st) < 0) + break; + } +#endif + /* found one. */ + if (type == X509_LU_X509) { + if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0) + break; + } else if (type == X509_LU_CRL) { + if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) + break; + } + /* else case will caught higher up */ + k++; + } + + /* + * we have added it to the cache so now pull it out again + */ + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp); + if (j != -1) + tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); + else + tmp = NULL; + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + /* If a CRL, update the last file suffix added for this */ + + if (type == X509_LU_CRL) { + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + /* + * Look for entry again in case another thread added an entry + * first. + */ + if (!hent) { + htmp.hash = h; + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + } + if (!hent) { + hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); + if (hent == NULL) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + goto finish; + } + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + OPENSSL_free(hent); + ok = 0; + goto finish; + } + } else if (hent->suffix < k) + hent->suffix = k; + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + } + + if (tmp != NULL) { + ok = 1; + ret->type = tmp->type; + memcpy(&ret->data, &tmp->data, sizeof(ret->data)); + /* + * If we were going to up the reference count, we would need to + * do it on a perl 'type' basis + */ + /*- CRYPTO_add(&tmp->data.x509->references,1, + CRYPTO_LOCK_X509);*/ + goto finish; + } + } + finish: + if (b != NULL) + BUF_MEM_free(b); + return (ok); +} +/* crypto/x509/by_file.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +// #include "cryptlib.h" +// #include "lhash.h" +#include "buffer.h" +// #include "x509.h" +#include "pem.h" + +#ifndef OPENSSL_NO_STDIO + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +X509_LOOKUP_METHOD x509_file_lookup = { + "Load file into cache", + NULL, /* new */ + NULL, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + by_file_ctrl, /* ctrl */ + NULL, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + +X509_LOOKUP_METHOD *X509_LOOKUP_file(void) +{ + return (&x509_file_lookup); +} + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, + long argl, char **ret) +{ + int ok = 0; + const char *file; + + switch (cmd) { + case X509_L_FILE_LOAD: + if (argl == X509_FILETYPE_DEFAULT) { + file = ossl_safe_getenv(X509_get_default_cert_file_env()); + + if (file) + ok = (X509_load_cert_crl_file(ctx, file, + X509_FILETYPE_PEM) != 0); + + else + ok = (X509_load_cert_crl_file + (ctx, X509_get_default_cert_file(), + X509_FILETYPE_PEM) != 0); + + if (!ok) { + X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); + } + } else { + if (argl == X509_FILETYPE_PEM) + ok = (X509_load_cert_crl_file(ctx, argp, + X509_FILETYPE_PEM) != 0); + else + ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); + } + break; + } + return (ok); +} + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509 *x = NULL; + + if (file == NULL) + return (1); + in = BIO_new(BIO_s_file_internal()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); + if (x == NULL) { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) { + ERR_clear_error(); + break; + } else { + X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); + goto err; + } + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_bio(in, NULL); + if (x == NULL) { + X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); + goto err; + } + err: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} + +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509_CRL *x = NULL; + + if (file == NULL) + return (1); + in = BIO_new(BIO_s_file_internal()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_CRL(in, NULL, NULL, ""); + if (x == NULL) { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) { + ERR_clear_error(); + break; + } else { + X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB); + goto err; + } + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_CRL_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_CRL_bio(in, NULL); + if (x == NULL) { + X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); + goto err; + } + err: + if (x != NULL) + X509_CRL_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} + +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + STACK_OF(X509_INFO) *inf; + X509_INFO *itmp; + BIO *in; + int i, count = 0; + if (type != X509_FILETYPE_PEM) + return X509_load_cert_file(ctx, file, type); + in = BIO_new_file(file, "r"); + if (!in) { + X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); + BIO_free(in); + if (!inf) { + X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); + return 0; + } + for (i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if (itmp->x509) { + X509_STORE_add_cert(ctx->store_ctx, itmp->x509); + count++; + } + if (itmp->crl) { + X509_STORE_add_crl(ctx->store_ctx, itmp->crl); + count++; + } + } + sk_X509_INFO_pop_free(inf, X509_INFO_free); + return count; +} + +#endif /* OPENSSL_NO_STDIO */ diff --git a/Sources/COpenSSL/c_.c b/Sources/COpenSSL/c_.c new file mode 100644 index 00000000..3b72d6da --- /dev/null +++ b/Sources/COpenSSL/c_.c @@ -0,0 +1,1957 @@ +/* crypto/evp/c_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +#if 0 +# undef OpenSSL_add_all_algorithms + +void OpenSSL_add_all_algorithms(void) +{ + OPENSSL_add_all_algorithms_noconf(); +} +#endif + +void OPENSSL_add_all_algorithms_noconf(void) +{ + /* + * For the moment OPENSSL_cpuid_setup does something + * only on IA-32, but we reserve the option for all + * platforms... + */ + OPENSSL_cpuid_setup(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); +} +/* crypto/evp/c_allc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +#include "pkcs12.h" +#include "objects.h" + +void OpenSSL_add_all_ciphers(void) +{ + +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cfb()); + EVP_add_cipher(EVP_des_cfb1()); + EVP_add_cipher(EVP_des_cfb8()); + EVP_add_cipher(EVP_des_ede_cfb()); + EVP_add_cipher(EVP_des_ede3_cfb()); + EVP_add_cipher(EVP_des_ede3_cfb1()); + EVP_add_cipher(EVP_des_ede3_cfb8()); + + EVP_add_cipher(EVP_des_ofb()); + EVP_add_cipher(EVP_des_ede_ofb()); + EVP_add_cipher(EVP_des_ede3_ofb()); + + EVP_add_cipher(EVP_desx_cbc()); + EVP_add_cipher_alias(SN_desx_cbc, "DESX"); + EVP_add_cipher_alias(SN_desx_cbc, "desx"); + + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher_alias(SN_des_cbc, "DES"); + EVP_add_cipher_alias(SN_des_cbc, "des"); + EVP_add_cipher(EVP_des_ede_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); + EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3"); + EVP_add_cipher_alias(SN_des_ede3_cbc, "des3"); + + EVP_add_cipher(EVP_des_ecb()); + EVP_add_cipher(EVP_des_ede()); + EVP_add_cipher(EVP_des_ede3()); + EVP_add_cipher(EVP_des_ede3_wrap()); +#endif + +#ifndef OPENSSL_NO_RC4 + EVP_add_cipher(EVP_rc4()); + EVP_add_cipher(EVP_rc4_40()); +# ifndef OPENSSL_NO_MD5 + EVP_add_cipher(EVP_rc4_hmac_md5()); +# endif +#endif + +#ifndef OPENSSL_NO_IDEA + EVP_add_cipher(EVP_idea_ecb()); + EVP_add_cipher(EVP_idea_cfb()); + EVP_add_cipher(EVP_idea_ofb()); + EVP_add_cipher(EVP_idea_cbc()); + EVP_add_cipher_alias(SN_idea_cbc, "IDEA"); + EVP_add_cipher_alias(SN_idea_cbc, "idea"); +#endif + +#ifndef OPENSSL_NO_SEED + EVP_add_cipher(EVP_seed_ecb()); + EVP_add_cipher(EVP_seed_cfb()); + EVP_add_cipher(EVP_seed_ofb()); + EVP_add_cipher(EVP_seed_cbc()); + EVP_add_cipher_alias(SN_seed_cbc, "SEED"); + EVP_add_cipher_alias(SN_seed_cbc, "seed"); +#endif + +#ifndef OPENSSL_NO_RC2 + EVP_add_cipher(EVP_rc2_ecb()); + EVP_add_cipher(EVP_rc2_cfb()); + EVP_add_cipher(EVP_rc2_ofb()); + EVP_add_cipher(EVP_rc2_cbc()); + EVP_add_cipher(EVP_rc2_40_cbc()); + EVP_add_cipher(EVP_rc2_64_cbc()); + EVP_add_cipher_alias(SN_rc2_cbc, "RC2"); + EVP_add_cipher_alias(SN_rc2_cbc, "rc2"); +#endif + +#ifndef OPENSSL_NO_BF + EVP_add_cipher(EVP_bf_ecb()); + EVP_add_cipher(EVP_bf_cfb()); + EVP_add_cipher(EVP_bf_ofb()); + EVP_add_cipher(EVP_bf_cbc()); + EVP_add_cipher_alias(SN_bf_cbc, "BF"); + EVP_add_cipher_alias(SN_bf_cbc, "bf"); + EVP_add_cipher_alias(SN_bf_cbc, "blowfish"); +#endif + +#ifndef OPENSSL_NO_CAST + EVP_add_cipher(EVP_cast5_ecb()); + EVP_add_cipher(EVP_cast5_cfb()); + EVP_add_cipher(EVP_cast5_ofb()); + EVP_add_cipher(EVP_cast5_cbc()); + EVP_add_cipher_alias(SN_cast5_cbc, "CAST"); + EVP_add_cipher_alias(SN_cast5_cbc, "cast"); + EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc"); + EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc"); +#endif + +#ifndef OPENSSL_NO_RC5 + EVP_add_cipher(EVP_rc5_32_12_16_ecb()); + EVP_add_cipher(EVP_rc5_32_12_16_cfb()); + EVP_add_cipher(EVP_rc5_32_12_16_ofb()); + EVP_add_cipher(EVP_rc5_32_12_16_cbc()); + EVP_add_cipher_alias(SN_rc5_cbc, "rc5"); + EVP_add_cipher_alias(SN_rc5_cbc, "RC5"); +#endif + +#ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_ecb()); + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_128_cfb()); + EVP_add_cipher(EVP_aes_128_cfb1()); + EVP_add_cipher(EVP_aes_128_cfb8()); + EVP_add_cipher(EVP_aes_128_ofb()); + EVP_add_cipher(EVP_aes_128_ctr()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_128_xts()); + EVP_add_cipher(EVP_aes_128_ccm()); + EVP_add_cipher(EVP_aes_128_wrap()); + EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); + EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); + EVP_add_cipher(EVP_aes_192_ecb()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_192_cfb()); + EVP_add_cipher(EVP_aes_192_cfb1()); + EVP_add_cipher(EVP_aes_192_cfb8()); + EVP_add_cipher(EVP_aes_192_ofb()); + EVP_add_cipher(EVP_aes_192_ctr()); + EVP_add_cipher(EVP_aes_192_gcm()); + EVP_add_cipher(EVP_aes_192_ccm()); + EVP_add_cipher(EVP_aes_192_wrap()); + EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); + EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); + EVP_add_cipher(EVP_aes_256_ecb()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_256_cfb()); + EVP_add_cipher(EVP_aes_256_cfb1()); + EVP_add_cipher(EVP_aes_256_cfb8()); + EVP_add_cipher(EVP_aes_256_ofb()); + EVP_add_cipher(EVP_aes_256_ctr()); + EVP_add_cipher(EVP_aes_256_gcm()); + EVP_add_cipher(EVP_aes_256_xts()); + EVP_add_cipher(EVP_aes_256_ccm()); + EVP_add_cipher(EVP_aes_256_wrap()); + EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); + EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); +# endif +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); +# endif +#endif + +#ifndef OPENSSL_NO_CAMELLIA + EVP_add_cipher(EVP_camellia_128_ecb()); + EVP_add_cipher(EVP_camellia_128_cbc()); + EVP_add_cipher(EVP_camellia_128_cfb()); + EVP_add_cipher(EVP_camellia_128_cfb1()); + EVP_add_cipher(EVP_camellia_128_cfb8()); + EVP_add_cipher(EVP_camellia_128_ofb()); + EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128"); + EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128"); + EVP_add_cipher(EVP_camellia_192_ecb()); + EVP_add_cipher(EVP_camellia_192_cbc()); + EVP_add_cipher(EVP_camellia_192_cfb()); + EVP_add_cipher(EVP_camellia_192_cfb1()); + EVP_add_cipher(EVP_camellia_192_cfb8()); + EVP_add_cipher(EVP_camellia_192_ofb()); + EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192"); + EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192"); + EVP_add_cipher(EVP_camellia_256_ecb()); + EVP_add_cipher(EVP_camellia_256_cbc()); + EVP_add_cipher(EVP_camellia_256_cfb()); + EVP_add_cipher(EVP_camellia_256_cfb1()); + EVP_add_cipher(EVP_camellia_256_cfb8()); + EVP_add_cipher(EVP_camellia_256_ofb()); + EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256"); + EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256"); +#endif +} +/* crypto/evp/c_alld.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "pkcs12.h" +// #include "objects.h" + +void OpenSSL_add_all_digests(void) +{ +#ifndef OPENSSL_NO_MD4 + EVP_add_digest(EVP_md4()); +#endif +#ifndef OPENSSL_NO_MD5 + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); +#endif +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0) + EVP_add_digest(EVP_sha()); +# ifndef OPENSSL_NO_DSA + EVP_add_digest(EVP_dss()); +# endif +#endif +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_digest(EVP_sha1()); + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); +# ifndef OPENSSL_NO_DSA + EVP_add_digest(EVP_dss1()); + EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); +# endif +# ifndef OPENSSL_NO_ECDSA + EVP_add_digest(EVP_ecdsa()); +# endif +#endif +#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES) + EVP_add_digest(EVP_mdc2()); +#endif +#ifndef OPENSSL_NO_RIPEMD + EVP_add_digest(EVP_ripemd160()); + EVP_add_digest_alias(SN_ripemd160, "ripemd"); + EVP_add_digest_alias(SN_ripemd160, "rmd160"); +#endif +#ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +#endif +#ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +#endif +#ifndef OPENSSL_NO_WHIRLPOOL + EVP_add_digest(EVP_whirlpool()); +#endif +} +/* crypto/cast/c_cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "cast.h" +#include "cast_lcl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num, int enc) +{ + register CAST_LONG v0, v1, t; + register int n = *num; + register long l = length; + CAST_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = ivec; + if (enc) { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + CAST_encrypt((CAST_LONG *)ti, schedule); + iv = ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + CAST_encrypt((CAST_LONG *)ti, schedule); + iv = ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} +/* crypto/cast/c_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "cast.h" +// #include "cast_lcl.h" +#include "opensslv.h" + +const char CAST_version[] = "CAST" OPENSSL_VERSION_PTEXT; + +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *ks, int enc) +{ + CAST_LONG l, d[2]; + + n2l(in, l); + d[0] = l; + n2l(in, l); + d[1] = l; + if (enc) + CAST_encrypt(d, ks); + else + CAST_decrypt(d, ks); + l = d[0]; + l2n(l, out); + l = d[1]; + l2n(l, out); + l = d[0] = d[1] = 0; +} +/* crypto/cast/c_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "cast.h" +// #include "cast_lcl.h" + +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key) +{ + register CAST_LONG l, r, t; + const register CAST_LONG *k; + + k = &(key->data[0]); + l = data[0]; + r = data[1]; + + E_CAST(0, k, l, r, +, ^, -); + E_CAST(1, k, r, l, ^, -, +); + E_CAST(2, k, l, r, -, +, ^); + E_CAST(3, k, r, l, +, ^, -); + E_CAST(4, k, l, r, ^, -, +); + E_CAST(5, k, r, l, -, +, ^); + E_CAST(6, k, l, r, +, ^, -); + E_CAST(7, k, r, l, ^, -, +); + E_CAST(8, k, l, r, -, +, ^); + E_CAST(9, k, r, l, +, ^, -); + E_CAST(10, k, l, r, ^, -, +); + E_CAST(11, k, r, l, -, +, ^); + if (!key->short_key) { + E_CAST(12, k, l, r, +, ^, -); + E_CAST(13, k, r, l, ^, -, +); + E_CAST(14, k, l, r, -, +, ^); + E_CAST(15, k, r, l, +, ^, -); + } + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +} + +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key) +{ + register CAST_LONG l, r, t; + const register CAST_LONG *k; + + k = &(key->data[0]); + l = data[0]; + r = data[1]; + + if (!key->short_key) { + E_CAST(15, k, l, r, +, ^, -); + E_CAST(14, k, r, l, -, +, ^); + E_CAST(13, k, l, r, ^, -, +); + E_CAST(12, k, r, l, +, ^, -); + } + E_CAST(11, k, l, r, -, +, ^); + E_CAST(10, k, r, l, ^, -, +); + E_CAST(9, k, l, r, +, ^, -); + E_CAST(8, k, r, l, -, +, ^); + E_CAST(7, k, l, r, ^, -, +); + E_CAST(6, k, r, l, +, ^, -); + E_CAST(5, k, l, r, -, +, ^); + E_CAST(4, k, r, l, ^, -, +); + E_CAST(3, k, l, r, +, ^, -); + E_CAST(2, k, r, l, -, +, ^); + E_CAST(1, k, l, r, ^, -, +); + E_CAST(0, k, r, l, +, ^, -); + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +} + +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *ks, unsigned char *iv, + int enc) +{ + register CAST_LONG tin0, tin1; + register CAST_LONG tout0, tout1, xor0, xor1; + register long l = length; + CAST_LONG tin[2]; + + if (enc) { + n2l(iv, tout0); + n2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + CAST_encrypt(tin, ks); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + CAST_encrypt(tin, ks); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + l2n(tout0, iv); + l2n(tout1, iv); + } else { + n2l(iv, xor0); + n2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + CAST_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + CAST_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, iv); + l2n(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} +/* crypto/cast/c_ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "cast.h" +// #include "cast_lcl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num) +{ + register CAST_LONG v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + CAST_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = ivec; + n2l(iv, v0); + n2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2n(v0, dp); + l2n(v1, dp); + while (l--) { + if (n == 0) { + CAST_encrypt((CAST_LONG *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2n(t, dp); + t = ti[1]; + l2n(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = ivec; + l2n(v0, iv); + l2n(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} +#include +#include +#include +// #include "objects.h" +#include "comp.h" + +static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); +static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); + +static COMP_METHOD rle_method = { + NID_rle_compression, + LN_rle_compression, + NULL, + NULL, + rle_compress_block, + rle_expand_block, + NULL, + NULL, +}; + +COMP_METHOD *COMP_rle(void) +{ + return (&rle_method); +} + +static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + if (ilen == 0) + return 0; + + if (olen <= ilen) + return -1; + + *(out++) = 0; + memcpy(out, in, ilen); + return (ilen + 1); +} + +static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + int i; + + if (ilen == 0) + return 0; + + if (olen < (ilen - 1)) + return -1; + + i = *(in++); + if (i != 0) + return -1; + + memcpy(out, in, ilen - 1); + return (ilen - 1); +} +/* crypto/cast/c_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "crypto.h" +// #include "cast.h" +// #include "cast_lcl.h" +#include "cast_s.h" + +#define CAST_exp(l,A,a,n) \ + A[n/4]=l; \ + a[n+3]=(l )&0xff; \ + a[n+2]=(l>> 8)&0xff; \ + a[n+1]=(l>>16)&0xff; \ + a[n+0]=(l>>24)&0xff; + +#define S4 CAST_S_table4 +#define S5 CAST_S_table5 +#define S6 CAST_S_table6 +#define S7 CAST_S_table7 +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(CAST); + private_CAST_set_key(key, len, data); +} + +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) +#endif +{ + CAST_LONG x[16]; + CAST_LONG z[16]; + CAST_LONG k[32]; + CAST_LONG X[4], Z[4]; + CAST_LONG l, *K; + int i; + + for (i = 0; i < 16; i++) + x[i] = 0; + if (len > 16) + len = 16; + for (i = 0; i < len; i++) + x[i] = data[i]; + if (len <= 10) + key->short_key = 1; + else + key->short_key = 0; + + K = &k[0]; + X[0] = ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]) & 0xffffffffL; + X[1] = ((x[4] << 24) | (x[5] << 16) | (x[6] << 8) | x[7]) & 0xffffffffL; + X[2] = ((x[8] << 24) | (x[9] << 16) | (x[10] << 8) | x[11]) & 0xffffffffL; + X[3] = + ((x[12] << 24) | (x[13] << 16) | (x[14] << 8) | x[15]) & 0xffffffffL; + + for (;;) { + l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; + CAST_exp(l, Z, z, 0); + l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; + CAST_exp(l, Z, z, 4); + l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; + CAST_exp(l, Z, z, 8); + l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; + CAST_exp(l, Z, z, 12); + + K[0] = S4[z[8]] ^ S5[z[9]] ^ S6[z[7]] ^ S7[z[6]] ^ S4[z[2]]; + K[1] = S4[z[10]] ^ S5[z[11]] ^ S6[z[5]] ^ S7[z[4]] ^ S5[z[6]]; + K[2] = S4[z[12]] ^ S5[z[13]] ^ S6[z[3]] ^ S7[z[2]] ^ S6[z[9]]; + K[3] = S4[z[14]] ^ S5[z[15]] ^ S6[z[1]] ^ S7[z[0]] ^ S7[z[12]]; + + l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; + CAST_exp(l, X, x, 0); + l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; + CAST_exp(l, X, x, 4); + l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; + CAST_exp(l, X, x, 8); + l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; + CAST_exp(l, X, x, 12); + + K[4] = S4[x[3]] ^ S5[x[2]] ^ S6[x[12]] ^ S7[x[13]] ^ S4[x[8]]; + K[5] = S4[x[1]] ^ S5[x[0]] ^ S6[x[14]] ^ S7[x[15]] ^ S5[x[13]]; + K[6] = S4[x[7]] ^ S5[x[6]] ^ S6[x[8]] ^ S7[x[9]] ^ S6[x[3]]; + K[7] = S4[x[5]] ^ S5[x[4]] ^ S6[x[10]] ^ S7[x[11]] ^ S7[x[7]]; + + l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; + CAST_exp(l, Z, z, 0); + l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; + CAST_exp(l, Z, z, 4); + l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; + CAST_exp(l, Z, z, 8); + l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; + CAST_exp(l, Z, z, 12); + + K[8] = S4[z[3]] ^ S5[z[2]] ^ S6[z[12]] ^ S7[z[13]] ^ S4[z[9]]; + K[9] = S4[z[1]] ^ S5[z[0]] ^ S6[z[14]] ^ S7[z[15]] ^ S5[z[12]]; + K[10] = S4[z[7]] ^ S5[z[6]] ^ S6[z[8]] ^ S7[z[9]] ^ S6[z[2]]; + K[11] = S4[z[5]] ^ S5[z[4]] ^ S6[z[10]] ^ S7[z[11]] ^ S7[z[6]]; + + l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; + CAST_exp(l, X, x, 0); + l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; + CAST_exp(l, X, x, 4); + l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; + CAST_exp(l, X, x, 8); + l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; + CAST_exp(l, X, x, 12); + + K[12] = S4[x[8]] ^ S5[x[9]] ^ S6[x[7]] ^ S7[x[6]] ^ S4[x[3]]; + K[13] = S4[x[10]] ^ S5[x[11]] ^ S6[x[5]] ^ S7[x[4]] ^ S5[x[7]]; + K[14] = S4[x[12]] ^ S5[x[13]] ^ S6[x[3]] ^ S7[x[2]] ^ S6[x[8]]; + K[15] = S4[x[14]] ^ S5[x[15]] ^ S6[x[1]] ^ S7[x[0]] ^ S7[x[13]]; + if (K != k) + break; + K += 16; + } + + for (i = 0; i < 16; i++) { + key->data[i * 2] = k[i]; + key->data[i * 2 + 1] = ((k[i + 16]) + 16) & 0x1f; + } +} +#include +#include +#include +// #include "objects.h" +// #include "comp.h" +#include "err.h" + +COMP_METHOD *COMP_zlib(void); + +static COMP_METHOD zlib_method_nozlib = { + NID_undef, + "(undef)", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +#ifndef ZLIB +# undef ZLIB_SHARED +#else + +# include + +static int zlib_stateful_init(COMP_CTX *ctx); +static void zlib_stateful_finish(COMP_CTX *ctx); +static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); +static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); + +/* memory allocations functions for zlib intialization */ +static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size) +{ + void *p; + + p = OPENSSL_malloc(no * size); + if (p) + memset(p, 0, no * size); + return p; +} + +static void zlib_zfree(void *opaque, void *address) +{ + OPENSSL_free(address); +} + +# if 0 +static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); +static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); + +static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source, + uLong sourceLen); + +static COMP_METHOD zlib_stateless_method = { + NID_zlib_compression, + LN_zlib_compression, + NULL, + NULL, + zlib_compress_block, + zlib_expand_block, + NULL, + NULL, +}; +# endif + +static COMP_METHOD zlib_stateful_method = { + NID_zlib_compression, + LN_zlib_compression, + zlib_stateful_init, + zlib_stateful_finish, + zlib_stateful_compress_block, + zlib_stateful_expand_block, + NULL, + NULL, +}; + +/* + * When OpenSSL is built on Windows, we do not want to require that + * the ZLIB.DLL be available in order for the OpenSSL DLLs to + * work. Therefore, all ZLIB routines are loaded at run time + * and we do not link to a .LIB file when ZLIB_SHARED is set. + */ +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# include +# endif /* !(OPENSSL_SYS_WINDOWS || + * OPENSSL_SYS_WIN32) */ + +# ifdef ZLIB_SHARED +# include "dso.h" + +/* Function pointers */ +typedef int (*compress_ft) (Bytef *dest, uLongf * destLen, + const Bytef *source, uLong sourceLen); +typedef int (*inflateEnd_ft) (z_streamp strm); +typedef int (*inflate_ft) (z_streamp strm, int flush); +typedef int (*inflateInit__ft) (z_streamp strm, + const char *version, int stream_size); +typedef int (*deflateEnd_ft) (z_streamp strm); +typedef int (*deflate_ft) (z_streamp strm, int flush); +typedef int (*deflateInit__ft) (z_streamp strm, int level, + const char *version, int stream_size); +typedef const char *(*zError__ft) (int err); +static compress_ft p_compress = NULL; +static inflateEnd_ft p_inflateEnd = NULL; +static inflate_ft p_inflate = NULL; +static inflateInit__ft p_inflateInit_ = NULL; +static deflateEnd_ft p_deflateEnd = NULL; +static deflate_ft p_deflate = NULL; +static deflateInit__ft p_deflateInit_ = NULL; +static zError__ft p_zError = NULL; + +static int zlib_loaded = 0; /* only attempt to init func pts once */ +static DSO *zlib_dso = NULL; + +# define compress p_compress +# define inflateEnd p_inflateEnd +# define inflate p_inflate +# define inflateInit_ p_inflateInit_ +# define deflateEnd p_deflateEnd +# define deflate p_deflate +# define deflateInit_ p_deflateInit_ +# define zError p_zError +# endif /* ZLIB_SHARED */ + +struct zlib_state { + z_stream istream; + z_stream ostream; +}; + +static int zlib_stateful_ex_idx = -1; + +static int zlib_stateful_init(COMP_CTX *ctx) +{ + int err; + struct zlib_state *state = + (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state)); + + if (state == NULL) + goto err; + + state->istream.zalloc = zlib_zalloc; + state->istream.zfree = zlib_zfree; + state->istream.opaque = Z_NULL; + state->istream.next_in = Z_NULL; + state->istream.next_out = Z_NULL; + state->istream.avail_in = 0; + state->istream.avail_out = 0; + err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream)); + if (err != Z_OK) + goto err; + + state->ostream.zalloc = zlib_zalloc; + state->ostream.zfree = zlib_zfree; + state->ostream.opaque = Z_NULL; + state->ostream.next_in = Z_NULL; + state->ostream.next_out = Z_NULL; + state->ostream.avail_in = 0; + state->ostream.avail_out = 0; + err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION, + ZLIB_VERSION, sizeof(z_stream)); + if (err != Z_OK) + goto err; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data); + CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state); + return 1; + err: + if (state) + OPENSSL_free(state); + return 0; +} + +static void zlib_stateful_finish(COMP_CTX *ctx) +{ + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); + inflateEnd(&state->istream); + deflateEnd(&state->ostream); + OPENSSL_free(state); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data); +} + +static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + int err = Z_OK; + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); + + if (state == NULL) + return -1; + + state->ostream.next_in = in; + state->ostream.avail_in = ilen; + state->ostream.next_out = out; + state->ostream.avail_out = olen; + if (ilen > 0) + err = deflate(&state->ostream, Z_SYNC_FLUSH); + if (err != Z_OK) + return -1; +# ifdef DEBUG_ZLIB + fprintf(stderr, "compress(%4d)->%4d %s\n", + ilen, olen - state->ostream.avail_out, + (ilen != olen - state->ostream.avail_out) ? "zlib" : "clear"); +# endif + return olen - state->ostream.avail_out; +} + +static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + int err = Z_OK; + + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); + + if (state == NULL) + return 0; + + state->istream.next_in = in; + state->istream.avail_in = ilen; + state->istream.next_out = out; + state->istream.avail_out = olen; + if (ilen > 0) + err = inflate(&state->istream, Z_SYNC_FLUSH); + if (err != Z_OK) + return -1; +# ifdef DEBUG_ZLIB + fprintf(stderr, "expand(%4d)->%4d %s\n", + ilen, olen - state->istream.avail_out, + (ilen != olen - state->istream.avail_out) ? "zlib" : "clear"); +# endif + return olen - state->istream.avail_out; +} + +# if 0 +static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + unsigned long l; + int i; + int clear = 1; + + if (ilen > 128) { + out[0] = 1; + l = olen - 1; + i = compress(&(out[1]), &l, in, (unsigned long)ilen); + if (i != Z_OK) + return (-1); + if (ilen > l) { + clear = 0; + l++; + } + } + if (clear) { + out[0] = 0; + memcpy(&(out[1]), in, ilen); + l = ilen + 1; + } +# ifdef DEBUG_ZLIB + fprintf(stderr, "compress(%4d)->%4d %s\n", + ilen, (int)l, (clear) ? "clear" : "zlib"); +# endif + return ((int)l); +} + +static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + unsigned long l; + int i; + + if (in[0]) { + l = olen; + i = zz_uncompress(out, &l, &(in[1]), (unsigned long)ilen - 1); + if (i != Z_OK) + return (-1); + } else { + memcpy(out, &(in[1]), ilen - 1); + l = ilen - 1; + } +# ifdef DEBUG_ZLIB + fprintf(stderr, "expand (%4d)->%4d %s\n", + ilen, (int)l, in[0] ? "zlib" : "clear"); +# endif + return ((int)l); +} + +static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source, + uLong sourceLen) +{ + z_stream stream; + int err; + + stream.next_in = (Bytef *)source; + stream.avail_in = (uInt) sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong) stream.avail_in != sourceLen) + return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt) * destLen; + if ((uLong) stream.avail_out != *destLen) + return Z_BUF_ERROR; + + stream.zalloc = (alloc_func) 0; + stream.zfree = (free_func) 0; + + err = inflateInit_(&stream, ZLIB_VERSION, sizeof(z_stream)); + if (err != Z_OK) + return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} +# endif + +#endif + +COMP_METHOD *COMP_zlib(void) +{ + COMP_METHOD *meth = &zlib_method_nozlib; + +#ifdef ZLIB_SHARED + if (!zlib_loaded) { +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) + zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0); +# else + zlib_dso = DSO_load(NULL, "z", NULL, 0); +# endif + if (zlib_dso != NULL) { + p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); + p_inflateEnd + = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd"); + p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate"); + p_inflateInit_ + = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); + p_deflateEnd + = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd"); + p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate"); + p_deflateInit_ + = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_"); + p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError"); + + if (p_compress && p_inflateEnd && p_inflate + && p_inflateInit_ && p_deflateEnd + && p_deflate && p_deflateInit_ && p_zError) + zlib_loaded++; + } + } +#endif +#ifdef ZLIB_SHARED + if (zlib_loaded) +#endif +#if defined(ZLIB) || defined(ZLIB_SHARED) + { + /* + * init zlib_stateful_ex_idx here so that in a multi-process + * application it's enough to intialize openssl before forking (idx + * will be inherited in all the children) + */ + if (zlib_stateful_ex_idx == -1) { + CRYPTO_w_lock(CRYPTO_LOCK_COMP); + if (zlib_stateful_ex_idx == -1) + zlib_stateful_ex_idx = + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP, + 0, NULL, NULL, NULL, NULL); + CRYPTO_w_unlock(CRYPTO_LOCK_COMP); + if (zlib_stateful_ex_idx == -1) + goto err; + } + + meth = &zlib_stateful_method; + } + err: +#endif + + return (meth); +} + +void COMP_zlib_cleanup(void) +{ +#ifdef ZLIB_SHARED + if (zlib_dso != NULL) + DSO_free(zlib_dso); + zlib_dso = NULL; +#endif +} + +#ifdef ZLIB + +/* Zlib based compression/decompression filter BIO */ + +typedef struct { + unsigned char *ibuf; /* Input buffer */ + int ibufsize; /* Buffer size */ + z_stream zin; /* Input decompress context */ + unsigned char *obuf; /* Output buffer */ + int obufsize; /* Output buffer size */ + unsigned char *optr; /* Position in output buffer */ + int ocount; /* Amount of data in output buffer */ + int odone; /* deflate EOF */ + int comp_level; /* Compression level to use */ + z_stream zout; /* Output compression context */ +} BIO_ZLIB_CTX; + +# define ZLIB_DEFAULT_BUFSIZE 1024 + +static int bio_zlib_new(BIO *bi); +static int bio_zlib_free(BIO *bi); +static int bio_zlib_read(BIO *b, char *out, int outl); +static int bio_zlib_write(BIO *b, const char *in, int inl); +static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr); +static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp); + +static BIO_METHOD bio_meth_zlib = { + BIO_TYPE_COMP, + "zlib", + bio_zlib_write, + bio_zlib_read, + NULL, + NULL, + bio_zlib_ctrl, + bio_zlib_new, + bio_zlib_free, + bio_zlib_callback_ctrl +}; + +BIO_METHOD *BIO_f_zlib(void) +{ + return &bio_meth_zlib; +} + +static int bio_zlib_new(BIO *bi) +{ + BIO_ZLIB_CTX *ctx; +# ifdef ZLIB_SHARED + (void)COMP_zlib(); + if (!zlib_loaded) { + COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); + return 0; + } +# endif + ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX)); + if (!ctx) { + COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->ibuf = NULL; + ctx->obuf = NULL; + ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; + ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; + ctx->zin.zalloc = Z_NULL; + ctx->zin.zfree = Z_NULL; + ctx->zin.next_in = NULL; + ctx->zin.avail_in = 0; + ctx->zin.next_out = NULL; + ctx->zin.avail_out = 0; + ctx->zout.zalloc = Z_NULL; + ctx->zout.zfree = Z_NULL; + ctx->zout.next_in = NULL; + ctx->zout.avail_in = 0; + ctx->zout.next_out = NULL; + ctx->zout.avail_out = 0; + ctx->odone = 0; + ctx->comp_level = Z_DEFAULT_COMPRESSION; + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + return 1; +} + +static int bio_zlib_free(BIO *bi) +{ + BIO_ZLIB_CTX *ctx; + if (!bi) + return 0; + ctx = (BIO_ZLIB_CTX *) bi->ptr; + if (ctx->ibuf) { + /* Destroy decompress context */ + inflateEnd(&ctx->zin); + OPENSSL_free(ctx->ibuf); + } + if (ctx->obuf) { + /* Destroy compress context */ + deflateEnd(&ctx->zout); + OPENSSL_free(ctx->obuf); + } + OPENSSL_free(ctx); + bi->ptr = NULL; + bi->init = 0; + bi->flags = 0; + return 1; +} + +static int bio_zlib_read(BIO *b, char *out, int outl) +{ + BIO_ZLIB_CTX *ctx; + int ret; + z_stream *zin; + if (!out || !outl) + return 0; + ctx = (BIO_ZLIB_CTX *) b->ptr; + zin = &ctx->zin; + BIO_clear_retry_flags(b); + if (!ctx->ibuf) { + ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); + if (!ctx->ibuf) { + COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); + return 0; + } + inflateInit(zin); + zin->next_in = ctx->ibuf; + zin->avail_in = 0; + } + + /* Copy output data directly to supplied buffer */ + zin->next_out = (unsigned char *)out; + zin->avail_out = (unsigned int)outl; + for (;;) { + /* Decompress while data available */ + while (zin->avail_in) { + ret = inflate(zin, 0); + if ((ret != Z_OK) && (ret != Z_STREAM_END)) { + COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR); + ERR_add_error_data(2, "zlib error:", zError(ret)); + return 0; + } + /* If EOF or we've read everything then return */ + if ((ret == Z_STREAM_END) || !zin->avail_out) + return outl - zin->avail_out; + } + + /* + * No data in input buffer try to read some in, if an error then + * return the total data read. + */ + ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize); + if (ret <= 0) { + /* Total data read */ + int tot = outl - zin->avail_out; + BIO_copy_next_retry(b); + if (ret < 0) + return (tot > 0) ? tot : ret; + return tot; + } + zin->avail_in = ret; + zin->next_in = ctx->ibuf; + } +} + +static int bio_zlib_write(BIO *b, const char *in, int inl) +{ + BIO_ZLIB_CTX *ctx; + int ret; + z_stream *zout; + if (!in || !inl) + return 0; + ctx = (BIO_ZLIB_CTX *) b->ptr; + if (ctx->odone) + return 0; + zout = &ctx->zout; + BIO_clear_retry_flags(b); + if (!ctx->obuf) { + ctx->obuf = OPENSSL_malloc(ctx->obufsize); + /* Need error here */ + if (!ctx->obuf) { + COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->optr = ctx->obuf; + ctx->ocount = 0; + deflateInit(zout, ctx->comp_level); + zout->next_out = ctx->obuf; + zout->avail_out = ctx->obufsize; + } + /* Obtain input data directly from supplied buffer */ + zout->next_in = (void *)in; + zout->avail_in = inl; + for (;;) { + /* If data in output buffer write it first */ + while (ctx->ocount) { + ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); + if (ret <= 0) { + /* Total data written */ + int tot = inl - zout->avail_in; + BIO_copy_next_retry(b); + if (ret < 0) + return (tot > 0) ? tot : ret; + return tot; + } + ctx->optr += ret; + ctx->ocount -= ret; + } + + /* Have we consumed all supplied data? */ + if (!zout->avail_in) + return inl; + + /* Compress some more */ + + /* Reset buffer */ + ctx->optr = ctx->obuf; + zout->next_out = ctx->obuf; + zout->avail_out = ctx->obufsize; + /* Compress some more */ + ret = deflate(zout, 0); + if (ret != Z_OK) { + COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR); + ERR_add_error_data(2, "zlib error:", zError(ret)); + return 0; + } + ctx->ocount = ctx->obufsize - zout->avail_out; + } +} + +static int bio_zlib_flush(BIO *b) +{ + BIO_ZLIB_CTX *ctx; + int ret; + z_stream *zout; + ctx = (BIO_ZLIB_CTX *) b->ptr; + /* If no data written or already flush show success */ + if (!ctx->obuf || (ctx->odone && !ctx->ocount)) + return 1; + zout = &ctx->zout; + BIO_clear_retry_flags(b); + /* No more input data */ + zout->next_in = NULL; + zout->avail_in = 0; + for (;;) { + /* If data in output buffer write it first */ + while (ctx->ocount) { + ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); + if (ret <= 0) { + BIO_copy_next_retry(b); + return ret; + } + ctx->optr += ret; + ctx->ocount -= ret; + } + if (ctx->odone) + return 1; + + /* Compress some more */ + + /* Reset buffer */ + ctx->optr = ctx->obuf; + zout->next_out = ctx->obuf; + zout->avail_out = ctx->obufsize; + /* Compress some more */ + ret = deflate(zout, Z_FINISH); + if (ret == Z_STREAM_END) + ctx->odone = 1; + else if (ret != Z_OK) { + COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR); + ERR_add_error_data(2, "zlib error:", zError(ret)); + return 0; + } + ctx->ocount = ctx->obufsize - zout->avail_out; + } +} + +static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_ZLIB_CTX *ctx; + int ret, *ip; + int ibs, obs; + if (!b->next_bio) + return 0; + ctx = (BIO_ZLIB_CTX *) b->ptr; + switch (cmd) { + + case BIO_CTRL_RESET: + ctx->ocount = 0; + ctx->odone = 0; + ret = 1; + break; + + case BIO_CTRL_FLUSH: + ret = bio_zlib_flush(b); + if (ret > 0) + ret = BIO_flush(b->next_bio); + break; + + case BIO_C_SET_BUFF_SIZE: + ibs = -1; + obs = -1; + if (ptr != NULL) { + ip = ptr; + if (*ip == 0) + ibs = (int)num; + else + obs = (int)num; + } else { + ibs = (int)num; + obs = ibs; + } + + if (ibs != -1) { + if (ctx->ibuf) { + OPENSSL_free(ctx->ibuf); + ctx->ibuf = NULL; + } + ctx->ibufsize = ibs; + } + + if (obs != -1) { + if (ctx->obuf) { + OPENSSL_free(ctx->obuf); + ctx->obuf = NULL; + } + ctx->obufsize = obs; + } + ret = 1; + break; + + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + + } + + return ret; +} + +static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + if (!b->next_bio) + return 0; + return BIO_callback_ctrl(b->next_bio, cmd, fp); +} + +#endif diff --git a/Sources/COpenSSL/camellia.c b/Sources/COpenSSL/camellia.c new file mode 100644 index 00000000..719fa61c --- /dev/null +++ b/Sources/COpenSSL/camellia.c @@ -0,0 +1,584 @@ +/* crypto/camellia/camellia.c */ +/* ==================================================================== + * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . + * ALL RIGHTS RESERVED. + * + * Intellectual Property information for Camellia: + * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html + * + * News Release for Announcement of Camellia open source: + * http://www.ntt.co.jp/news/news06e/0604/060413a.html + * + * The Camellia Code included herein is developed by + * NTT (Nippon Telegraph and Telephone Corporation), and is contributed + * to the OpenSSL project. + * + * The Camellia Code is licensed pursuant to the OpenSSL open source + * license provided below. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +/* + * Algorithm Specification + * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html + */ + +/* + * This release balances code size and performance. In particular key + * schedule setup is fully unrolled, because doing so *significantly* + * reduces amount of instructions per setup round and code increase is + * justifiable. In block functions on the other hand only inner loops + * are unrolled, as full unroll gives only nominal performance boost, + * while code size grows 4 or 7 times. Also, unlike previous versions + * this one "encourages" compiler to keep intermediate variables in + * registers, which should give better "all round" results, in other + * words reasonable performance even with not so modern compilers. + */ + +#include "camellia.h" +#include "cmll_locl.h" +#include +#include + +/* 32-bit rotations */ +#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define RightRotate(x, s) _lrotr(x, s) +# define LeftRotate(x, s) _lrotl(x, s) +# if _MSC_VER >= 1400 +# define SWAP(x) _byteswap_ulong(x) +# else +# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +# endif +# define GETU32(p) SWAP(*((u32 *)(p))) +# define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v))) +# elif defined(__GNUC__) && __GNUC__>=2 +# if defined(__i386) || defined(__x86_64) +# define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) +# define LeftRotate(x,s) ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) +# if defined(B_ENDIAN) /* stratus.com does it */ +# define GETU32(p) (*(u32 *)(p)) +# define PUTU32(p,v) (*(u32 *)(p)=(v)) +# else +# define GETU32(p) ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; }) +# define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; }) +# endif +# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ + defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) +# define LeftRotate(x,s) ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; }) +# define RightRotate(x,s) LeftRotate(x,(32-s)) +# elif defined(__s390x__) +# define LeftRotate(x,s) ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; }) +# define RightRotate(x,s) LeftRotate(x,(32-s)) +# define GETU32(p) (*(u32 *)(p)) +# define PUTU32(p,v) (*(u32 *)(p)=(v)) +# endif +# endif +#endif + +#if !defined(RightRotate) && !defined(LeftRotate) +# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) ) +# define LeftRotate(x, s) ( ((x) << (s)) + ((x) >> (32 - s)) ) +#endif + +#if !defined(GETU32) && !defined(PUTU32) +# define GETU32(p) (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] << 8) ^ ((u32)(p)[3])) +# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >> 8), (p)[3] = (u8)(v)) +#endif + +/* S-box data */ +#define SBOX1_1110 Camellia_SBOX[0] +#define SBOX4_4404 Camellia_SBOX[1] +#define SBOX2_0222 Camellia_SBOX[2] +#define SBOX3_3033 Camellia_SBOX[3] +static const u32 Camellia_SBOX[][256] = { + {0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, + 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, + 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, + 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, + 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, + 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, + 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, + 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, + 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, + 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, + 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, + 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, + 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, + 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, + 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, + 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, + 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, + 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, + 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, + 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, + 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, + 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, + 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, + 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, + 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, + 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, + 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, + 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, + 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, + 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, + 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, + 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, + 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, + 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, + 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, + 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, + 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, + 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, + 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, + 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, + 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, + 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, + 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00}, + {0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, + 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, + 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, + 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, + 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, + 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, + 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, + 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, + 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, + 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, + 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, + 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, + 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, + 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, + 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, + 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, + 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, + 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, + 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, + 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, + 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, + 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, + 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, + 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, + 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, + 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, + 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, + 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, + 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, + 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, + 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, + 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, + 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, + 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, + 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, + 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, + 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, + 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, + 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, + 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, + 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, + 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, + 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e}, + {0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, + 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, + 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, + 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, + 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, + 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, + 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, + 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, + 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, + 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, + 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, + 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, + 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, + 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, + 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, + 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, + 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, + 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, + 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, + 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, + 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, + 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, + 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, + 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, + 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, + 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, + 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, + 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, + 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, + 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, + 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, + 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, + 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, + 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, + 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, + 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, + 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, + 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, + 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, + 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, + 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, + 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, + 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d}, + {0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, + 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, + 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, + 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, + 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, + 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, + 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, + 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, + 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, + 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, + 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, + 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, + 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, + 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, + 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, + 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, + 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, + 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, + 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, + 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, + 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, + 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, + 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, + 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, + 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, + 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, + 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, + 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, + 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, + 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, + 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, + 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, + 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, + 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, + 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, + 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, + 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, + 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, + 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, + 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, + 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, + 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, + 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f} +}; + +/* Key generation constants */ +static const u32 SIGMA[] = { + 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, + 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd +}; + +/* The phi algorithm given in C.2.7 of the Camellia spec document. */ +/* + * This version does not attempt to minimize amount of temporary + * variables, but instead explicitly exposes algorithm's parallelism. + * It is therefore most appropriate for platforms with not less than + * ~16 registers. For platforms with less registers [well, x86 to be + * specific] assembler version should be/is provided anyway... + */ +#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\ + register u32 _t0,_t1,_t2,_t3;\ +\ + _t0 = _s0 ^ (_key)[0];\ + _t3 = SBOX4_4404[_t0&0xff];\ + _t1 = _s1 ^ (_key)[1];\ + _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\ + _t2 = SBOX1_1110[_t1&0xff];\ + _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\ + _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\ + _t3 ^= SBOX1_1110[(_t0 >> 24)];\ + _t2 ^= _t3;\ + _t3 = RightRotate(_t3,8);\ + _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\ + _s3 ^= _t3;\ + _t2 ^= SBOX2_0222[(_t1 >> 24)];\ + _s2 ^= _t2; \ + _s3 ^= _t2;\ +} while(0) + +/* + * Note that n has to be less than 32. Rotations for larger amount + * of bits are achieved by "rotating" order of s-elements and + * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32). + */ +#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\ + u32 _t0=_s0>>(32-_n);\ + _s0 = (_s0<<_n) | (_s1>>(32-_n));\ + _s1 = (_s1<<_n) | (_s2>>(32-_n));\ + _s2 = (_s2<<_n) | (_s3>>(32-_n));\ + _s3 = (_s3<<_n) | _t0;\ +} while (0) + +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k) +{ + register u32 s0, s1, s2, s3; + + k[0] = s0 = GETU32(rawKey); + k[1] = s1 = GETU32(rawKey + 4); + k[2] = s2 = GETU32(rawKey + 8); + k[3] = s3 = GETU32(rawKey + 12); + + if (keyBitLength != 128) { + k[8] = s0 = GETU32(rawKey + 16); + k[9] = s1 = GETU32(rawKey + 20); + if (keyBitLength == 192) { + k[10] = s2 = ~s0; + k[11] = s3 = ~s1; + } else { + k[10] = s2 = GETU32(rawKey + 24); + k[11] = s3 = GETU32(rawKey + 28); + } + s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; + } + + /* Use the Feistel routine to scramble the key material */ + Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0); + Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2); + + s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; + Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4); + Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6); + + /* Fill the keyTable. Requires many block rotations. */ + if (keyBitLength == 128) { + k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 30 */ + k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 45 */ + k[24] = s0, k[25] = s1; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 60 */ + k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; + RotLeft128(s1, s2, s3, s0, 2); /* KA <<< 94 */ + k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KA <<<111 */ + k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; + + s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3]; + RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 15 */ + k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KL <<< 45 */ + k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 60 */ + k[26] = s2, k[27] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 77 */ + k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 94 */ + k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<<111 */ + k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3; + + return 3; /* grand rounds */ + } else { + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + s0 ^= k[8], s1 ^= k[9], s2 ^= k[10], s3 ^= k[11]; + Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8)); + Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10)); + + k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 30 */ + k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 60 */ + k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3; + RotLeft128(s1, s2, s3, s0, 19); /* KB <<<111 */ + k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0; + + s0 = k[8], s1 = k[9], s2 = k[10], s3 = k[11]; + RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 15 */ + k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 30 */ + k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KR <<< 60 */ + k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; + RotLeft128(s1, s2, s3, s0, 2); /* KR <<< 94 */ + k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0; + + s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15]; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KA <<< 45 */ + k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; + /* KA <<< 77 */ + k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KA <<< 94 */ + k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0; + + s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3]; + RotLeft128(s1, s2, s3, s0, 13); /* KL <<< 45 */ + k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0; + RotLeft128(s1, s2, s3, s0, 15); /* KL <<< 60 */ + k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KL <<< 77 */ + k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0; + RotLeft128(s2, s3, s0, s1, 2); /* KL <<<111 */ + k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1; + + return 4; /* grand rounds */ + } + /* + * It is possible to perform certain precalculations, which + * would spare few cycles in block procedure. It's not done, + * because it upsets the performance balance between key + * setup and block procedures, negatively affecting overall + * throughput in applications operating on short messages + * and volatile keys. + */ +} + +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, + u8 ciphertext[]) +{ + register u32 s0, s1, s2, s3; + const u32 *k = keyTable, *kend = keyTable + grandRounds * 16; + + s0 = GETU32(plaintext) ^ k[0]; + s1 = GETU32(plaintext + 4) ^ k[1]; + s2 = GETU32(plaintext + 8) ^ k[2]; + s3 = GETU32(plaintext + 12) ^ k[3]; + k += 4; + + while (1) { + /* Camellia makes 6 Feistel rounds */ + Camellia_Feistel(s0, s1, s2, s3, k + 0); + Camellia_Feistel(s2, s3, s0, s1, k + 2); + Camellia_Feistel(s0, s1, s2, s3, k + 4); + Camellia_Feistel(s2, s3, s0, s1, k + 6); + Camellia_Feistel(s0, s1, s2, s3, k + 8); + Camellia_Feistel(s2, s3, s0, s1, k + 10); + k += 12; + + if (k == kend) + break; + + /* + * This is the same function as the diffusion function D of the + * accompanying documentation. See section 3.2 for properties of the + * FLlayer function. + */ + s1 ^= LeftRotate(s0 & k[0], 1); + s2 ^= s3 | k[3]; + s0 ^= s1 | k[1]; + s3 ^= LeftRotate(s2 & k[2], 1); + k += 4; + } + + s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; + + PUTU32(ciphertext, s2); + PUTU32(ciphertext + 4, s3); + PUTU32(ciphertext + 8, s0); + PUTU32(ciphertext + 12, s1); +} + +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) +{ + Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, + plaintext, keyTable, ciphertext); +} + +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, + u8 plaintext[]) +{ + u32 s0, s1, s2, s3; + const u32 *k = keyTable + grandRounds * 16, *kend = keyTable + 4; + + s0 = GETU32(ciphertext) ^ k[0]; + s1 = GETU32(ciphertext + 4) ^ k[1]; + s2 = GETU32(ciphertext + 8) ^ k[2]; + s3 = GETU32(ciphertext + 12) ^ k[3]; + + while (1) { + /* Camellia makes 6 Feistel rounds */ + k -= 12; + Camellia_Feistel(s0, s1, s2, s3, k + 10); + Camellia_Feistel(s2, s3, s0, s1, k + 8); + Camellia_Feistel(s0, s1, s2, s3, k + 6); + Camellia_Feistel(s2, s3, s0, s1, k + 4); + Camellia_Feistel(s0, s1, s2, s3, k + 2); + Camellia_Feistel(s2, s3, s0, s1, k + 0); + + if (k == kend) + break; + + /* + * This is the same function as the diffusion function D of the + * accompanying documentation. See section 3.2 for properties of the + * FLlayer function. + */ + k -= 4; + s1 ^= LeftRotate(s0 & k[2], 1); + s2 ^= s3 | k[1]; + s0 ^= s1 | k[3]; + s3 ^= LeftRotate(s2 & k[0], 1); + } + + k -= 4; + s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; + + PUTU32(plaintext, s2); + PUTU32(plaintext + 4, s3); + PUTU32(plaintext + 8, s0); + PUTU32(plaintext + 12, s1); +} + +void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) +{ + Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, + plaintext, keyTable, ciphertext); +} diff --git a/Sources/COpenSSL/camellia.h b/Sources/COpenSSL/camellia.h new file mode 100644 index 00000000..d13dda99 --- /dev/null +++ b/Sources/COpenSSL/camellia.h @@ -0,0 +1,132 @@ +/* crypto/camellia/camellia.h */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_CAMELLIA_H +# define HEADER_CAMELLIA_H + +# include "opensslconf.h" + +# ifdef OPENSSL_NO_CAMELLIA +# error CAMELLIA is disabled. +# endif + +# include + +# define CAMELLIA_ENCRYPT 1 +# define CAMELLIA_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ + +# define CAMELLIA_BLOCK_SIZE 16 +# define CAMELLIA_TABLE_BYTE_LEN 272 +# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match + * with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +# ifdef OPENSSL_FIPS +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); +# endif +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_Camellia_H */ diff --git a/Sources/COpenSSL/cast.h b/Sources/COpenSSL/cast.h new file mode 100644 index 00000000..c3da7ae8 --- /dev/null +++ b/Sources/COpenSSL/cast.h @@ -0,0 +1,107 @@ +/* crypto/cast/cast.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CAST_H +# define HEADER_CAST_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include "opensslconf.h" + +# ifdef OPENSSL_NO_CAST +# error CAST is disabled. +# endif + +# define CAST_ENCRYPT 1 +# define CAST_DECRYPT 0 + +# define CAST_LONG unsigned int + +# define CAST_BLOCK 8 +# define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ +} CAST_KEY; + +# ifdef OPENSSL_FIPS +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +# endif +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *key, int enc); +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *ks, unsigned char *iv, + int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/cast_lcl.h b/Sources/COpenSSL/cast_lcl.h new file mode 100644 index 00000000..b0f08294 --- /dev/null +++ b/Sources/COpenSSL/cast_lcl.h @@ -0,0 +1,227 @@ +/* crypto/cast/cast_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "e_os.h" + +#ifdef OPENSSL_SYS_WIN32 +# include +#endif + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER) +# define ROTL(a,n) (_lrotl(a,n)) +#elif defined(PEDANTIC) +# define ROTL(a,n) ((((a)<<(n))&0xffffffffL)|((a)>>((32-(n))&31))) +#else +# define ROTL(a,n) ((((a)<<(n))&0xffffffffL)|((a)>>(32-(n)))) +#endif + +#define C_M 0x3fc +#define C_0 22L +#define C_1 14L +#define C_2 6L +#define C_3 2L /* left shift */ + +/* The rotate has an extra 16 added to it to help the x86 asm */ +#if defined(CAST_PTR) +# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + int i; \ + t=(key[n*2] OP1 R)&0xffffffffL; \ + i=key[n*2+1]; \ + t=ROTL(t,i); \ + L^= (((((*(CAST_LONG *)((unsigned char *) \ + CAST_S_table0+((t>>C_2)&C_M)) OP2 \ + *(CAST_LONG *)((unsigned char *) \ + CAST_S_table1+((t<>C_0)&C_M)))&0xffffffffL) OP1 \ + *(CAST_LONG *)((unsigned char *) \ + CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \ + } +#elif defined(CAST_PTR2) +# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + int i; \ + CAST_LONG u,v,w; \ + w=(key[n*2] OP1 R)&0xffffffffL; \ + i=key[n*2+1]; \ + w=ROTL(w,i); \ + u=w>>C_2; \ + v=w<>C_0; \ + t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\ + v=w>>C_1; \ + u&=C_M; \ + v&=C_M; \ + t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\ + t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\ + L^=(t&0xffffffff); \ + } +#else +# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + CAST_LONG a,b,c,d; \ + t=(key[n*2] OP1 R)&0xffffffff; \ + t=ROTL(t,(key[n*2+1])); \ + a=CAST_S_table0[(t>> 8)&0xff]; \ + b=CAST_S_table1[(t )&0xff]; \ + c=CAST_S_table2[(t>>24)&0xff]; \ + d=CAST_S_table3[(t>>16)&0xff]; \ + L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \ + } +#endif + +extern const CAST_LONG CAST_S_table0[256]; +extern const CAST_LONG CAST_S_table1[256]; +extern const CAST_LONG CAST_S_table2[256]; +extern const CAST_LONG CAST_S_table3[256]; +extern const CAST_LONG CAST_S_table4[256]; +extern const CAST_LONG CAST_S_table5[256]; +extern const CAST_LONG CAST_S_table6[256]; +extern const CAST_LONG CAST_S_table7[256]; diff --git a/Sources/COpenSSL/cast_s.h b/Sources/COpenSSL/cast_s.h new file mode 100644 index 00000000..380dc81a --- /dev/null +++ b/Sources/COpenSSL/cast_s.h @@ -0,0 +1,592 @@ +/* crypto/cast/cast_s.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +OPENSSL_GLOBAL const CAST_LONG CAST_S_table0[256] = { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, + 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, + 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, + 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, + 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, + 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, + 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, + 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, + 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, + 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, + 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, + 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, + 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, + 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, + 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, + 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, + 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, + 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, + 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, + 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, + 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, + 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, + 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, + 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, + 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, + 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, + 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, + 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, + 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, + 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, + 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, + 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, + 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table1[256] = { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, + 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, + 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, + 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, + 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, + 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, + 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, + 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, + 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, + 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, + 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, + 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, + 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, + 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, + 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, + 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, + 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, + 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, + 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, + 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, + 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, + 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, + 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, + 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, + 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, + 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, + 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, + 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, + 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, + 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, + 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, + 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, + 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table2[256] = { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, + 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, + 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, + 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, + 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, + 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, + 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, + 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, + 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, + 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, + 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, + 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, + 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, + 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, + 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, + 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, + 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, + 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, + 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, + 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, + 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, + 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, + 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, + 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, + 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, + 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, + 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, + 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, + 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, + 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, + 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, + 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, + 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table3[256] = { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, + 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, + 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, + 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, + 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, + 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, + 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, + 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, + 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, + 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, + 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, + 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, + 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, + 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, + 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, + 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, + 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, + 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, + 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, + 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, + 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, + 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, + 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, + 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, + 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, + 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, + 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, + 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, + 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, + 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, + 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, + 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, + 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table4[256] = { + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, + 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, + 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, + 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, + 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, + 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, + 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, + 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, + 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, + 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, + 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, + 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, + 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, + 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, + 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, + 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, + 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, + 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, + 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, + 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, + 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, + 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, + 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, + 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, + 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, + 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, + 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, + 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, + 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, + 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, + 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, + 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, + 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table5[256] = { + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, + 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, + 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, + 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, + 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, + 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, + 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, + 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, + 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, + 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, + 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, + 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, + 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, + 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, + 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, + 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, + 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, + 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, + 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, + 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, + 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, + 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, + 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, + 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, + 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, + 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, + 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, + 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, + 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, + 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, + 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, + 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, + 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table6[256] = { + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, + 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, + 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, + 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, + 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, + 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, + 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, + 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, + 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, + 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, + 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, + 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, + 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, + 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, + 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, + 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, + 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, + 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, + 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, + 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, + 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, + 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, + 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, + 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, + 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, + 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, + 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, + 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, + 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, + 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, + 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, + 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, + 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table7[256] = { + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, + 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, + 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, + 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, + 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, + 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, + 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, + 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, + 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, + 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, + 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, + 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, + 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, + 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, + 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, + 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, + 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, + 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, + 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, + 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, + 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, + 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, + 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, + 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, + 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, + 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, + 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, + 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, + 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, + 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, + 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, + 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, + 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e, +}; diff --git a/Sources/COpenSSL/cbc128.c b/Sources/COpenSSL/cbc128.c new file mode 100644 index 00000000..31c76a36 --- /dev/null +++ b/Sources/COpenSSL/cbc128.c @@ -0,0 +1,207 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "crypto.h" +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC) +# define STRICT_ALIGNMENT 0 +#endif + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block) +{ + size_t n; + const unsigned char *iv = ivec; + + assert(in && out && key && ivec); + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (STRICT_ALIGNMENT && + ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { + while (len >= 16) { + for (n = 0; n < 16; ++n) + out[n] = in[n] ^ iv[n]; + (*block) (out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } else { + while (len >= 16) { + for (n = 0; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(iv + n); + (*block) (out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } +#endif + while (len) { + for (n = 0; n < 16 && n < len; ++n) + out[n] = in[n] ^ iv[n]; + for (; n < 16; ++n) + out[n] = iv[n]; + (*block) (out, out, key); + iv = out; + if (len <= 16) + break; + len -= 16; + in += 16; + out += 16; + } + memcpy(ivec, iv, 16); +} + +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block) +{ + size_t n; + union { + size_t t[16 / sizeof(size_t)]; + unsigned char c[16]; + } tmp; + + assert(in && out && key && ivec); + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (in != out) { + const unsigned char *iv = ivec; + + if (STRICT_ALIGNMENT && + ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { + while (len >= 16) { + (*block) (in, out, key); + for (n = 0; n < 16; ++n) + out[n] ^= iv[n]; + iv = in; + len -= 16; + in += 16; + out += 16; + } + } else if (16 % sizeof(size_t) == 0) { /* always true */ + while (len >= 16) { + size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv; + + (*block) (in, out, key); + for (n = 0; n < 16 / sizeof(size_t); n++) + out_t[n] ^= iv_t[n]; + iv = in; + len -= 16; + in += 16; + out += 16; + } + } + memcpy(ivec, iv, 16); + } else { + if (STRICT_ALIGNMENT && + ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { + unsigned char c; + while (len >= 16) { + (*block) (in, tmp.c, key); + for (n = 0; n < 16; ++n) { + c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + len -= 16; + in += 16; + out += 16; + } + } else if (16 % sizeof(size_t) == 0) { /* always true */ + while (len >= 16) { + size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec; + const size_t *in_t = (const size_t *)in; + + (*block) (in, tmp.c, key); + for (n = 0; n < 16 / sizeof(size_t); n++) { + c = in_t[n]; + out_t[n] = tmp.t[n] ^ ivec_t[n]; + ivec_t[n] = c; + } + len -= 16; + in += 16; + out += 16; + } + } + } +#endif + while (len) { + unsigned char c; + (*block) (in, tmp.c, key); + for (n = 0; n < 16 && n < len; ++n) { + c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + if (len <= 16) { + for (; n < 16; ++n) + ivec[n] = in[n]; + break; + } + len -= 16; + in += 16; + out += 16; + } +} diff --git a/Sources/COpenSSL/cbc3_enc.c b/Sources/COpenSSL/cbc3_enc.c new file mode 100644 index 00000000..249518a6 --- /dev/null +++ b/Sources/COpenSSL/cbc3_enc.c @@ -0,0 +1,95 @@ +/* crypto/des/cbc3_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* HAS BUGS! DON'T USE - this is only present for use in des.c */ +void DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length, + DES_key_schedule ks1, DES_key_schedule ks2, + DES_cblock *iv1, DES_cblock *iv2, int enc) +{ + int off = ((int)length - 1) / 8; + long l8 = ((length + 7) / 8) * 8; + DES_cblock niv1, niv2; + + if (enc == DES_ENCRYPT) { + DES_cbc_encrypt((unsigned char *)input, + (unsigned char *)output, length, &ks1, iv1, enc); + if (length >= sizeof(DES_cblock)) + memcpy(niv1, output[off], sizeof(DES_cblock)); + DES_cbc_encrypt((unsigned char *)output, + (unsigned char *)output, l8, &ks2, iv1, !enc); + DES_cbc_encrypt((unsigned char *)output, + (unsigned char *)output, l8, &ks1, iv2, enc); + if (length >= sizeof(DES_cblock)) + memcpy(niv2, output[off], sizeof(DES_cblock)); + } else { + if (length >= sizeof(DES_cblock)) + memcpy(niv2, input[off], sizeof(DES_cblock)); + DES_cbc_encrypt((unsigned char *)input, + (unsigned char *)output, l8, &ks1, iv2, enc); + DES_cbc_encrypt((unsigned char *)output, + (unsigned char *)output, l8, &ks2, iv1, !enc); + if (length >= sizeof(DES_cblock)) + memcpy(niv1, output[off], sizeof(DES_cblock)); + DES_cbc_encrypt((unsigned char *)output, + (unsigned char *)output, length, &ks1, iv1, enc); + } + memcpy(*iv1, niv1, sizeof(DES_cblock)); + memcpy(*iv2, niv2, sizeof(DES_cblock)); +} diff --git a/Sources/COpenSSL/cbc_.c b/Sources/COpenSSL/cbc_.c new file mode 100644 index 00000000..5ef2e8f6 --- /dev/null +++ b/Sources/COpenSSL/cbc_.c @@ -0,0 +1,164 @@ +/* crypto/des/cbc_cksm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec) +{ + register DES_LONG tout0, tout1, tin0, tin1; + register long l = length; + DES_LONG tin[2]; + unsigned char *out = &(*output)[0]; + const unsigned char *iv = &(*ivec)[0]; + + c2l(iv, tout0); + c2l(iv, tout1); + for (; l > 0; l -= 8) { + if (l >= 8) { + c2l(in, tin0); + c2l(in, tin1); + } else + c2ln(in, tin0, tin1, l); + + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); + /* fix 15/10/91 eay - thanks to keithr@sco.COM */ + tout0 = tin[0]; + tout1 = tin[1]; + } + if (out != NULL) { + l2c(tout0, out); + l2c(tout1, out); + } + tout0 = tin0 = tin1 = tin[0] = tin[1] = 0; + /* + * Transform the data in tout1 so that it will match the return value + * that the MIT Kerberos mit_des_cbc_cksum API returns. + */ + tout1 = ((tout1 >> 24L) & 0x000000FF) + | ((tout1 >> 8L) & 0x0000FF00) + | ((tout1 << 8L) & 0x00FF0000) + | ((tout1 << 24L) & 0xFF000000); + return (tout1); +} +/* crypto/des/cbc_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define CBC_ENC_C__DONT_UPDATE_IV + +#include "ncbc_enc.h" /* des_cbc_encrypt */ diff --git a/Sources/COpenSSL/ccm128.c b/Sources/COpenSSL/ccm128.c new file mode 100644 index 00000000..1a1ad54b --- /dev/null +++ b/Sources/COpenSSL/ccm128.c @@ -0,0 +1,479 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "crypto.h" +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * First you setup M and L parameters and pass the key schedule. This is + * called once per session setup... + */ +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, + block128_f block) +{ + memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c)); + ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3; + ctx->blocks = 0; + ctx->block = block; + ctx->key = key; +} + +/* !!! Following interfaces are to be called *once* per packet !!! */ + +/* Then you setup per-message nonce and pass the length of the message */ +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, + const unsigned char *nonce, size_t nlen, size_t mlen) +{ + unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */ + + if (nlen < (14 - L)) + return -1; /* nonce is too short */ + + if (sizeof(mlen) == 8 && L >= 3) { + ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8))); + ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8))); + ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8))); + ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8))); + } else + ctx->nonce.u[1] = 0; + + ctx->nonce.c[12] = (u8)(mlen >> 24); + ctx->nonce.c[13] = (u8)(mlen >> 16); + ctx->nonce.c[14] = (u8)(mlen >> 8); + ctx->nonce.c[15] = (u8)mlen; + + ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ + memcpy(&ctx->nonce.c[1], nonce, 14 - L); + + return 0; +} + +/* Then you pass additional authentication data, this is optional */ +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, + const unsigned char *aad, size_t alen) +{ + unsigned int i; + block128_f block = ctx->block; + + if (alen == 0) + return; + + ctx->nonce.c[0] |= 0x40; /* set Adata flag */ + (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++; + + if (alen < (0x10000 - 0x100)) { + ctx->cmac.c[0] ^= (u8)(alen >> 8); + ctx->cmac.c[1] ^= (u8)alen; + i = 2; + } else if (sizeof(alen) == 8 + && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) { + ctx->cmac.c[0] ^= 0xFF; + ctx->cmac.c[1] ^= 0xFF; + ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8))); + ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8))); + ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8))); + ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8))); + ctx->cmac.c[6] ^= (u8)(alen >> 24); + ctx->cmac.c[7] ^= (u8)(alen >> 16); + ctx->cmac.c[8] ^= (u8)(alen >> 8); + ctx->cmac.c[9] ^= (u8)alen; + i = 10; + } else { + ctx->cmac.c[0] ^= 0xFF; + ctx->cmac.c[1] ^= 0xFE; + ctx->cmac.c[2] ^= (u8)(alen >> 24); + ctx->cmac.c[3] ^= (u8)(alen >> 16); + ctx->cmac.c[4] ^= (u8)(alen >> 8); + ctx->cmac.c[5] ^= (u8)alen; + i = 6; + } + + do { + for (; i < 16 && alen; ++i, ++aad, --alen) + ctx->cmac.c[i] ^= *aad; + (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++; + i = 0; + } while (alen); +} + +/* Finally you encrypt or decrypt the message */ + +/* + * counter part of nonce may not be larger than L*8 bits, L is not larger + * than 8, therefore 64-bit counter... + */ +static void ctr64_inc(unsigned char *counter) +{ + unsigned int n = 8; + u8 c; + + counter += 8; + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++; + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; /* length mismatch */ + + ctx->blocks += ((len + 15) >> 3) | 1; + if (ctx->blocks > (U64(1) << 61)) + return -2; /* too much data */ + + while (len >= 16) { +#if defined(STRICT_ALIGNMENT) + union { + u64 u[2]; + u8 c[16]; + } temp; + + memcpy(temp.c, inp, 16); + ctx->cmac.u[0] ^= temp.u[0]; + ctx->cmac.u[1] ^= temp.u[1]; +#else + ctx->cmac.u[0] ^= ((u64 *)inp)[0]; + ctx->cmac.u[1] ^= ((u64 *)inp)[1]; +#endif + (*block) (ctx->cmac.c, ctx->cmac.c, key); + (*block) (ctx->nonce.c, scratch.c, key); + ctr64_inc(ctx->nonce.c); +#if defined(STRICT_ALIGNMENT) + temp.u[0] ^= scratch.u[0]; + temp.u[1] ^= scratch.u[1]; + memcpy(out, temp.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]; + ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]; +#endif + inp += 16; + out += 16; + len -= 16; + } + + if (len) { + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= inp[i]; + (*block) (ctx->cmac.c, ctx->cmac.c, key); + (*block) (ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + out[i] = scratch.c[i] ^ inp[i]; + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block) (ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} + +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block) (ctx->nonce.c, ctx->cmac.c, key); + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; + + while (len >= 16) { +#if defined(STRICT_ALIGNMENT) + union { + u64 u[2]; + u8 c[16]; + } temp; +#endif + (*block) (ctx->nonce.c, scratch.c, key); + ctr64_inc(ctx->nonce.c); +#if defined(STRICT_ALIGNMENT) + memcpy(temp.c, inp, 16); + ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); + ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); + memcpy(out, scratch.c, 16); +#else + ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]); + ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]); +#endif + (*block) (ctx->cmac.c, ctx->cmac.c, key); + + inp += 16; + out += 16; + len -= 16; + } + + if (len) { + (*block) (ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); + (*block) (ctx->cmac.c, ctx->cmac.c, key); + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block) (ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} + +static void ctr64_add(unsigned char *counter, size_t inc) +{ + size_t n = 8, val = 0; + + counter += 8; + do { + --n; + val += counter[n] + (inc & 0xff); + counter[n] = (unsigned char)val; + val >>= 8; /* carry bit */ + inc >>= 8; + } while (n && (inc || val)); +} + +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len, ccm128_f stream) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++; + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; /* length mismatch */ + + ctx->blocks += ((len + 15) >> 3) | 1; + if (ctx->blocks > (U64(1) << 61)) + return -2; /* too much data */ + + if ((n = len / 16)) { + (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c); + n *= 16; + inp += n; + out += n; + len -= n; + if (len) + ctr64_add(ctx->nonce.c, n / 16); + } + + if (len) { + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= inp[i]; + (*block) (ctx->cmac.c, ctx->cmac.c, key); + (*block) (ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + out[i] = scratch.c[i] ^ inp[i]; + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block) (ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} + +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len, ccm128_f stream) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block) (ctx->nonce.c, ctx->cmac.c, key); + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; + + if ((n = len / 16)) { + (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c); + n *= 16; + inp += n; + out += n; + len -= n; + if (len) + ctr64_add(ctx->nonce.c, n / 16); + } + + if (len) { + (*block) (ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); + (*block) (ctx->cmac.c, ctx->cmac.c, key); + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block) (ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} + +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len) +{ + unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */ + + M *= 2; + M += 2; + if (len < M) + return 0; + memcpy(tag, ctx->cmac.c, M); + return M; +} diff --git a/Sources/COpenSSL/cfb128.c b/Sources/COpenSSL/cfb128.c new file mode 100644 index 00000000..b55c3576 --- /dev/null +++ b/Sources/COpenSSL/cfb128.c @@ -0,0 +1,254 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "crypto.h" +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * The input and output encrypted as though 128bit cfb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + unsigned int n; + size_t l = 0; + + assert(in && out && key && ivec && num); + + n = *num; + + if (enc) { +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + while (n && len) { + *(out++) = ivec[n] ^= *(in++); + --len; + n = (n + 1) % 16; + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out | (size_t)ivec) % + sizeof(size_t) != 0) + break; +# endif + while (len >= 16) { + (*block) (ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + *(size_t *)(out + n) = + *(size_t *)(ivec + n) ^= *(size_t *)(in + n); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block) (ivec, ivec, key); + while (len--) { + out[n] = ivec[n] ^= in[n]; + ++n; + } + } + *num = n; + return; + } while (0); + } + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block) (ivec, ivec, key); + } + out[l] = ivec[n] ^= in[l]; + ++l; + n = (n + 1) % 16; + } + *num = n; + } else { +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + while (n && len) { + unsigned char c; + *(out++) = ivec[n] ^ (c = *(in++)); + ivec[n] = c; + --len; + n = (n + 1) % 16; + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out | (size_t)ivec) % + sizeof(size_t) != 0) + break; +# endif + while (len >= 16) { + (*block) (ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t t = *(size_t *)(in + n); + *(size_t *)(out + n) = *(size_t *)(ivec + n) ^ t; + *(size_t *)(ivec + n) = t; + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block) (ivec, ivec, key); + while (len--) { + unsigned char c; + out[n] = ivec[n] ^ (c = in[n]); + ivec[n] = c; + ++n; + } + } + *num = n; + return; + } while (0); + } + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + unsigned char c; + if (n == 0) { + (*block) (ivec, ivec, key); + } + out[l] = ivec[n] ^ (c = in[l]); + ivec[n] = c; + ++l; + n = (n + 1) % 16; + } + *num = n; + } +} + +/* + * This expects a single block of size nbits for both in and out. Note that + * it corrupts any extra bits in the last byte of out + */ +static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out, + int nbits, const void *key, + unsigned char ivec[16], int enc, + block128_f block) +{ + int n, rem, num; + unsigned char ovec[16 * 2 + 1]; /* +1 because we dererefence (but don't + * use) one byte off the end */ + + if (nbits <= 0 || nbits > 128) + return; + + /* fill in the first half of the new IV with the current IV */ + memcpy(ovec, ivec, 16); + /* construct the new IV */ + (*block) (ivec, ivec, key); + num = (nbits + 7) / 8; + if (enc) /* encrypt the input */ + for (n = 0; n < num; ++n) + out[n] = (ovec[16 + n] = in[n] ^ ivec[n]); + else /* decrypt the input */ + for (n = 0; n < num; ++n) + out[n] = (ovec[16 + n] = in[n]) ^ ivec[n]; + /* shift ovec left... */ + rem = nbits % 8; + num = nbits / 8; + if (rem == 0) + memcpy(ivec, ovec + num, 16); + else + for (n = 0; n < 16; ++n) + ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem); + + /* it is not necessary to cleanse ovec, since the IV is not secret */ +} + +/* N.B. This expects the input to be packed, MS bit first */ +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + size_t n; + unsigned char c[1], d[1]; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for (n = 0; n < bits; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + cfbr_encrypt_block(c, d, 1, key, ivec, enc, block); + out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) | + ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } +} + +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + size_t n; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for (n = 0; n < length; ++n) + cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block); +} diff --git a/Sources/COpenSSL/cfb64ede.c b/Sources/COpenSSL/cfb64ede.c new file mode 100644 index 00000000..5d709c12 --- /dev/null +++ b/Sources/COpenSSL/cfb64ede.c @@ -0,0 +1,249 @@ +/* crypto/des/cfb64ede.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" +#include "e_os.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc) +{ + register DES_LONG v0, v1; + register long l = length; + register int n = *num; + DES_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = &(*ivec)[0]; + if (enc) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + c2l(iv, v1); + + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + v0 = ti[0]; + v1 = ti[1]; + + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + iv = &(*ivec)[0]; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + c2l(iv, v1); + + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + v0 = ti[0]; + v1 = ti[1]; + + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + iv = &(*ivec)[0]; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = c = cc = 0; + *num = n; +} + +#ifdef undef /* MACRO */ +void DES_ede2_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, DES_key_schedule ks1, + DES_key_schedule ks2, DES_cblock (*ivec), + int *num, int enc) +{ + DES_ede3_cfb64_encrypt(in, out, length, ks1, ks2, ks1, ivec, num, enc); +} +#endif + +/* + * This is compatible with the single key CFB-r for DES, even thought that's + * not what EVP needs. + */ + +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc) +{ + register DES_LONG d0, d1, v0, v1; + register unsigned long l = length, n = ((unsigned int)numbits + 7) / 8; + register int num = numbits, i; + DES_LONG ti[2]; + unsigned char *iv; + unsigned char ovec[16]; + + if (num > 64) + return; + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + if (enc) { + while (l >= n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + c2ln(in, d0, d1, n); + in += n; + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + /* + * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under + * gcc :-( + */ + if (num == 32) { + v0 = v1; + v1 = d0; + } else if (num == 64) { + v0 = d0; + v1 = d1; + } else { + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); + /* shift ovec left most of the bits... */ + memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0)); + /* now the remaining bits */ + if (num % 8 != 0) + for (i = 0; i < 8; ++i) { + ovec[i] <<= num % 8; + ovec[i] |= ovec[i + 1] >> (8 - num % 8); + } + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); + } + } + } else { + while (l >= n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + c2ln(in, d0, d1, n); + in += n; + /* + * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under + * gcc :-( + */ + if (num == 32) { + v0 = v1; + v1 = d0; + } else if (num == 64) { + v0 = d0; + v1 = d1; + } else { + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); + /* shift ovec left most of the bits... */ + memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0)); + /* now the remaining bits */ + if (num % 8 != 0) + for (i = 0; i < 8; ++i) { + ovec[i] <<= num % 8; + ovec[i] |= ovec[i + 1] >> (8 - num % 8); + } + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); + } + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; +} diff --git a/Sources/COpenSSL/cfb64enc.c b/Sources/COpenSSL/cfb64enc.c new file mode 100644 index 00000000..7346774e --- /dev/null +++ b/Sources/COpenSSL/cfb64enc.c @@ -0,0 +1,122 @@ +/* crypto/des/cfb64enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc) +{ + register DES_LONG v0, v1; + register long l = length; + register int n = *num; + DES_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = &(*ivec)[0]; + if (enc) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + DES_encrypt1(ti, schedule, DES_ENCRYPT); + iv = &(*ivec)[0]; + v0 = ti[0]; + l2c(v0, iv); + v0 = ti[1]; + l2c(v0, iv); + iv = &(*ivec)[0]; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + DES_encrypt1(ti, schedule, DES_ENCRYPT); + iv = &(*ivec)[0]; + v0 = ti[0]; + l2c(v0, iv); + v0 = ti[1]; + l2c(v0, iv); + iv = &(*ivec)[0]; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = c = cc = 0; + *num = n; +} diff --git a/Sources/COpenSSL/cfb_enc.c b/Sources/COpenSSL/cfb_enc.c new file mode 100644 index 00000000..bd0e2997 --- /dev/null +++ b/Sources/COpenSSL/cfb_enc.c @@ -0,0 +1,199 @@ +/* crypto/des/cfb_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "e_os.h" +#include "des_locl.h" +#include + +/* + * The input and output are loaded in multiples of 8 bits. What this means is + * that if you hame numbits=12 and length=2 the first 12 bits will be + * retrieved from the first byte and half the second. The second 12 bits + * will come from the 3rd and half the 4th byte. + */ +/* + * Until Aug 1 2003 this function did not correctly implement CFB-r, so it + * will not be compatible with any encryption prior to that date. Ben. + */ +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc) +{ + register DES_LONG d0, d1, v0, v1; + register unsigned long l = length; + register int num = numbits / 8, n = (numbits + 7) / 8, i, rem = + numbits % 8; + DES_LONG ti[2]; + unsigned char *iv; +#ifndef L_ENDIAN + unsigned char ovec[16]; +#else + unsigned int sh[4]; + unsigned char *ovec = (unsigned char *)sh; + + /* I kind of count that compiler optimizes away this assertioni, */ + assert(sizeof(sh[0]) == 4); /* as this holds true for all, */ + /* but 16-bit platforms... */ + +#endif + + if (numbits <= 0 || numbits > 64) + return; + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + if (enc) { + while (l >= (unsigned long)n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + c2ln(in, d0, d1, n); + in += n; + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + /* + * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under + * gcc :-( + */ + if (numbits == 32) { + v0 = v1; + v1 = d0; + } else if (numbits == 64) { + v0 = d0; + v1 = d1; + } else { +#ifndef L_ENDIAN + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); +#else + sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; +#endif + if (rem == 0) + memmove(ovec, ovec + num, 8); + else + for (i = 0; i < 8; ++i) + ovec[i] = ovec[i + num] << rem | + ovec[i + num + 1] >> (8 - rem); +#ifdef L_ENDIAN + v0 = sh[0], v1 = sh[1]; +#else + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); +#endif + } + } + } else { + while (l >= (unsigned long)n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + c2ln(in, d0, d1, n); + in += n; + /* + * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under + * gcc :-( + */ + if (numbits == 32) { + v0 = v1; + v1 = d0; + } else if (numbits == 64) { + v0 = d0; + v1 = d1; + } else { +#ifndef L_ENDIAN + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); +#else + sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; +#endif + if (rem == 0) + memmove(ovec, ovec + num, 8); + else + for (i = 0; i < 8; ++i) + ovec[i] = ovec[i + num] << rem | + ovec[i + num + 1] >> (8 - rem); +#ifdef L_ENDIAN + v0 = sh[0], v1 = sh[1]; +#else + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); +#endif + } + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; +} diff --git a/Sources/COpenSSL/charmap.h b/Sources/COpenSSL/charmap.h new file mode 100644 index 00000000..3305ad14 --- /dev/null +++ b/Sources/COpenSSL/charmap.h @@ -0,0 +1,15 @@ +/* + * Auto generated with chartype.pl script. Mask of various character + * properties + */ + +static const unsigned char char_type[] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2 +}; diff --git a/Sources/COpenSSL/cm_.c b/Sources/COpenSSL/cm_.c new file mode 100644 index 00000000..53393010 --- /dev/null +++ b/Sources/COpenSSL/cm_.c @@ -0,0 +1,312 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2010. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "cmac.h" +#include "asn1_locl.h" + +/* + * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output + * length and to free up a CMAC key. + */ + +static int cmac_size(const EVP_PKEY *pkey) +{ + return EVP_MAX_BLOCK_LENGTH; +} + +static void cmac_key_free(EVP_PKEY *pkey) +{ + CMAC_CTX *cmctx = (CMAC_CTX *)pkey->pkey.ptr; + if (cmctx) + CMAC_CTX_free(cmctx); +} + +const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { + EVP_PKEY_CMAC, + EVP_PKEY_CMAC, + 0, + + "CMAC", + "OpenSSL CMAC method", + + 0, 0, 0, 0, + + 0, 0, 0, + + cmac_size, + 0, + 0, 0, 0, 0, 0, 0, 0, + + cmac_key_free, + 0, + 0, 0 +}; +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2010. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +// #include "cryptlib.h" +#include "x509.h" +#include "x509v3.h" +// #include "evp.h" +// #include "cmac.h" +#include "evp_locl.h" + +/* The context structure and "key" is simply a CMAC_CTX */ + +static int pkey_cmac_init(EVP_PKEY_CTX *ctx) +{ + ctx->data = CMAC_CTX_new(); + if (!ctx->data) + return 0; + ctx->keygen_info_count = 0; + return 1; +} + +static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + if (!pkey_cmac_init(dst)) + return 0; + if (!CMAC_CTX_copy(dst->data, src->data)) + return 0; + return 1; +} + +static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) +{ + CMAC_CTX_free(ctx->data); +} + +static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + CMAC_CTX *cmkey = CMAC_CTX_new(); + CMAC_CTX *cmctx = ctx->data; + if (!cmkey) + return 0; + if (!CMAC_CTX_copy(cmkey, cmctx)) { + CMAC_CTX_free(cmkey); + return 0; + } + EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); + + return 1; +} + +static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + if (!CMAC_Update(ctx->pctx->data, data, count)) + return 0; + return 1; +} + +static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); + mctx->update = int_update; + return 1; +} + +static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) +{ + return CMAC_Final(ctx->data, sig, siglen); +} + +static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + CMAC_CTX *cmctx = ctx->data; + switch (type) { + + case EVP_PKEY_CTRL_SET_MAC_KEY: + if (!p2 || p1 < 0) + return 0; + if (!CMAC_Init(cmctx, p2, p1, NULL, NULL)) + return 0; + break; + + case EVP_PKEY_CTRL_CIPHER: + if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine)) + return 0; + break; + + case EVP_PKEY_CTRL_MD: + if (ctx->pkey && !CMAC_CTX_copy(ctx->data, + (CMAC_CTX *)ctx->pkey->pkey.ptr)) + return 0; + if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL)) + return 0; + break; + + default: + return -2; + + } + return 1; +} + +static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!value) { + return 0; + } + if (!strcmp(type, "key")) { + void *p = (void *)value; + return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, strlen(p), p); + } + if (!strcmp(type, "cipher")) { + const EVP_CIPHER *c; + c = EVP_get_cipherbyname(value); + if (!c) + return 0; + return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c); + } + if (!strcmp(type, "hexkey")) { + unsigned char *key; + int r; + long keylen; + key = string_to_hex(value, &keylen); + if (!key) + return 0; + r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); + OPENSSL_free(key); + return r; + } + return -2; +} + +const EVP_PKEY_METHOD cmac_pkey_meth = { + EVP_PKEY_CMAC, + EVP_PKEY_FLAG_SIGCTX_CUSTOM, + pkey_cmac_init, + pkey_cmac_copy, + pkey_cmac_cleanup, + + 0, 0, + + 0, + pkey_cmac_keygen, + + 0, 0, + + 0, 0, + + 0, 0, + + cmac_signctx_init, + cmac_signctx, + + 0, 0, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_cmac_ctrl, + pkey_cmac_ctrl_str +}; diff --git a/Sources/COpenSSL/cmac.c b/Sources/COpenSSL/cmac.c new file mode 100644 index 00000000..9ae59c9b --- /dev/null +++ b/Sources/COpenSSL/cmac.c @@ -0,0 +1,306 @@ +/* crypto/cmac/cmac.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include "cryptlib.h" +#include "cmac.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +struct CMAC_CTX_st { + /* Cipher context to use */ + EVP_CIPHER_CTX cctx; + /* Keys k1 and k2 */ + unsigned char k1[EVP_MAX_BLOCK_LENGTH]; + unsigned char k2[EVP_MAX_BLOCK_LENGTH]; + /* Temporary block */ + unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; + /* Last (possibly partial) block */ + unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; + /* Number of bytes in last block: -1 means context not initialised */ + int nlast_block; +}; + +/* Make temporary keys K1 and K2 */ + +static void make_kn(unsigned char *k1, unsigned char *l, int bl) +{ + int i; + /* Shift block to left, including carry */ + for (i = 0; i < bl; i++) { + k1[i] = l[i] << 1; + if (i < bl - 1 && l[i + 1] & 0x80) + k1[i] |= 1; + } + /* If MSB set fixup with R */ + if (l[0] & 0x80) + k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; +} + +CMAC_CTX *CMAC_CTX_new(void) +{ + CMAC_CTX *ctx; + ctx = OPENSSL_malloc(sizeof(CMAC_CTX)); + if (!ctx) + return NULL; + EVP_CIPHER_CTX_init(&ctx->cctx); + ctx->nlast_block = -1; + return ctx; +} + +void CMAC_CTX_cleanup(CMAC_CTX *ctx) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->cctx.engine) { + FIPS_cmac_ctx_cleanup(ctx); + return; + } +#endif + EVP_CIPHER_CTX_cleanup(&ctx->cctx); + OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); + OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); + OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH); + OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH); + ctx->nlast_block = -1; +} + +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) +{ + return &ctx->cctx; +} + +void CMAC_CTX_free(CMAC_CTX *ctx) +{ + if (!ctx) + return; + CMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) +{ + int bl; + if (in->nlast_block == -1) + return 0; + if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx)) + return 0; + bl = EVP_CIPHER_CTX_block_size(&in->cctx); + memcpy(out->k1, in->k1, bl); + memcpy(out->k2, in->k2, bl); + memcpy(out->tbl, in->tbl, bl); + memcpy(out->last_block, in->last_block, bl); + out->nlast_block = in->nlast_block; + return 1; +} + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl) +{ + static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) { + /* If we have an ENGINE need to allow non FIPS */ + if ((impl || ctx->cctx.engine) + && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { + EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS); + return 0; + } + + /* Switch to FIPS cipher implementation if possible */ + if (cipher != NULL) { + const EVP_CIPHER *fcipher; + fcipher = FIPS_get_cipherbynid(EVP_CIPHER_nid(cipher)); + if (fcipher != NULL) + cipher = fcipher; + } + /* + * Other algorithm blocking will be done in FIPS_cmac_init, via + * FIPS_cipherinit(). + */ + if (!impl && !ctx->cctx.engine) + return FIPS_cmac_init(ctx, key, keylen, cipher, NULL); + } +#endif + /* All zeros means restart */ + if (!key && !cipher && !impl && keylen == 0) { + /* Not initialised */ + if (ctx->nlast_block == -1) + return 0; + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) + return 0; + memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx)); + ctx->nlast_block = 0; + return 1; + } + /* Initialiase context */ + if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) + return 0; + /* Non-NULL key means initialisation complete */ + if (key) { + int bl; + if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) + return 0; + if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) + return 0; + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) + return 0; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) + return 0; + make_kn(ctx->k1, ctx->tbl, bl); + make_kn(ctx->k2, ctx->k1, bl); + OPENSSL_cleanse(ctx->tbl, bl); + /* Reset context again ready for first data block */ + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) + return 0; + /* Zero tbl so resume works */ + memset(ctx->tbl, 0, bl); + ctx->nlast_block = 0; + } + return 1; +} + +int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) +{ + const unsigned char *data = in; + size_t bl; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->cctx.engine) + return FIPS_cmac_update(ctx, in, dlen); +#endif + if (ctx->nlast_block == -1) + return 0; + if (dlen == 0) + return 1; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + /* Copy into partial block if we need to */ + if (ctx->nlast_block > 0) { + size_t nleft; + nleft = bl - ctx->nlast_block; + if (dlen < nleft) + nleft = dlen; + memcpy(ctx->last_block + ctx->nlast_block, data, nleft); + dlen -= nleft; + ctx->nlast_block += nleft; + /* If no more to process return */ + if (dlen == 0) + return 1; + data += nleft; + /* Else not final block so encrypt it */ + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl)) + return 0; + } + /* Encrypt all but one of the complete blocks left */ + while (dlen > bl) { + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl)) + return 0; + dlen -= bl; + data += bl; + } + /* Copy any data left to last block buffer */ + memcpy(ctx->last_block, data, dlen); + ctx->nlast_block = dlen; + return 1; + +} + +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) +{ + int i, bl, lb; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->cctx.engine) + return FIPS_cmac_final(ctx, out, poutlen); +#endif + if (ctx->nlast_block == -1) + return 0; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + *poutlen = (size_t)bl; + if (!out) + return 1; + lb = ctx->nlast_block; + /* Is last block complete? */ + if (lb == bl) { + for (i = 0; i < bl; i++) + out[i] = ctx->last_block[i] ^ ctx->k1[i]; + } else { + ctx->last_block[lb] = 0x80; + if (bl - lb > 1) + memset(ctx->last_block + lb + 1, 0, bl - lb - 1); + for (i = 0; i < bl; i++) + out[i] = ctx->last_block[i] ^ ctx->k2[i]; + } + if (!EVP_Cipher(&ctx->cctx, out, out, bl)) { + OPENSSL_cleanse(out, bl); + return 0; + } + return 1; +} + +int CMAC_resume(CMAC_CTX *ctx) +{ + if (ctx->nlast_block == -1) + return 0; + /* + * The buffer "tbl" containes the last fully encrypted block which is the + * last IV (or all zeroes if no last encrypted block). The last block has + * not been modified since CMAC_final(). So reinitliasing using the last + * decrypted block will allow CMAC to continue after calling + * CMAC_Final(). + */ + return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl); +} diff --git a/Sources/COpenSSL/cmac.h b/Sources/COpenSSL/cmac.h new file mode 100644 index 00000000..74b74bea --- /dev/null +++ b/Sources/COpenSSL/cmac.h @@ -0,0 +1,82 @@ +/* crypto/cmac/cmac.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMAC_H +# define HEADER_CMAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include "evp.h" + +/* Opaque */ +typedef struct CMAC_CTX_st CMAC_CTX; + +CMAC_CTX *CMAC_CTX_new(void); +void CMAC_CTX_cleanup(CMAC_CTX *ctx); +void CMAC_CTX_free(CMAC_CTX *ctx); +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl); +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); +int CMAC_resume(CMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/cmll_.c b/Sources/COpenSSL/cmll_.c new file mode 100644 index 00000000..1479c311 --- /dev/null +++ b/Sources/COpenSSL/cmll_.c @@ -0,0 +1,610 @@ +/* crypto/camellia/camellia_cbc.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "camellia.h" +#include "modes.h" + +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc) +{ + + if (enc) + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, + (block128_f) Camellia_encrypt); + else + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, + (block128_f) Camellia_decrypt); +} +/* crypto/camellia/camellia_cfb.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "camellia.h" +// #include "modes.h" + +/* + * The input and output encrypted as though 128bit cfb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ + +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) Camellia_encrypt); +} + +/* N.B. This expects the input to be packed, MS bit first */ +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) Camellia_encrypt); +} + +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) Camellia_encrypt); +} +/* crypto/camellia/camellia_ctr.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "camellia.h" +// #include "modes.h" + +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num) +{ + + CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, + (block128_f) Camellia_encrypt); +} +/* crypto/camellia/camellia_ecb.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef CAMELLIA_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +// #include "camellia.h" +#include "cmll_locl.h" + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc) +{ + + assert(in && out && key); + assert((CAMELLIA_ENCRYPT == enc) || (CAMELLIA_DECRYPT == enc)); + + if (CAMELLIA_ENCRYPT == enc) + Camellia_encrypt(in, out, key); + else + Camellia_decrypt(in, out, key); +} +/* crypto/camellia/camellia_misc.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "opensslv.h" +#include "crypto.h" +// #include "camellia.h" +// #include "cmll_locl.h" + +const char CAMELLIA_version[] = "CAMELLIA" OPENSSL_VERSION_PTEXT; + +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key) +{ + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + key->grand_rounds = Camellia_Ekeygen(bits, userKey, key->u.rd_key); + return 0; +} + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key) +{ + Camellia_EncryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out); +} + +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key) +{ + Camellia_DecryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out); +} +/* crypto/camellia/camellia_ofb.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "camellia.h" +// #include "modes.h" + +/* + * The input and output encrypted as though 128bit ofb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num) +{ + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, + (block128_f) Camellia_encrypt); +} +/* crypto/camellia/cmll_utl.c */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "opensslv.h" +// #include "crypto.h" +// #include "camellia.h" +// #include "cmll_locl.h" + +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key) +{ +#ifdef OPENSSL_FIPS + fips_cipher_abort(Camellia); +#endif + return private_Camellia_set_key(userKey, bits, key); +} diff --git a/Sources/COpenSSL/cmll_locl.h b/Sources/COpenSSL/cmll_locl.h new file mode 100644 index 00000000..2bd79b8c --- /dev/null +++ b/Sources/COpenSSL/cmll_locl.h @@ -0,0 +1,88 @@ +/* crypto/camellia/camellia_locl.h */ +/* ==================================================================== + * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . + * ALL RIGHTS RESERVED. + * + * Intellectual Property information for Camellia: + * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html + * + * News Release for Announcement of Camellia open source: + * http://www.ntt.co.jp/news/news06e/0604/060413a.html + * + * The Camellia Code included herein is developed by + * NTT (Nippon Telegraph and Telephone Corporation), and is contributed + * to the OpenSSL project. + * + * The Camellia Code is licensed pursuant to the OpenSSL open source + * license provided below. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CAMELLIA_LOCL_H +# define HEADER_CAMELLIA_LOCL_H + +typedef unsigned int u32; +typedef unsigned char u8; + +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, + KEY_TABLE_TYPE keyTable); +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, + u8 ciphertext[]); +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, + u8 plaintext[]); +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); +void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]); +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); +#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ diff --git a/Sources/COpenSSL/cms.h b/Sources/COpenSSL/cms.h new file mode 100644 index 00000000..a098795c --- /dev/null +++ b/Sources/COpenSSL/cms.h @@ -0,0 +1,555 @@ +/* crypto/cms/cms.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMS_H +# define HEADER_CMS_H + +# include "x509.h" + +# ifdef OPENSSL_NO_CMS +# error CMS is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; + +DECLARE_STACK_OF(CMS_SignerInfo) +DECLARE_STACK_OF(GENERAL_NAMES) +DECLARE_STACK_OF(CMS_RecipientEncryptedKey) +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_NONE -1 +# define CMS_RECIPINFO_TRANS 0 +# define CMS_RECIPINFO_AGREE 1 +# define CMS_RECIPINFO_KEK 2 +# define CMS_RECIPINFO_PASS 3 +# define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +# define CMS_TEXT 0x1 +# define CMS_NOCERTS 0x2 +# define CMS_NO_CONTENT_VERIFY 0x4 +# define CMS_NO_ATTR_VERIFY 0x8 +# define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +# define CMS_NOINTERN 0x10 +# define CMS_NO_SIGNER_CERT_VERIFY 0x20 +# define CMS_NOVERIFY 0x20 +# define CMS_DETACHED 0x40 +# define CMS_BINARY 0x80 +# define CMS_NOATTR 0x100 +# define CMS_NOSMIMECAP 0x200 +# define CMS_NOOLDMIMETYPE 0x400 +# define CMS_CRLFEOL 0x800 +# define CMS_STREAM 0x1000 +# define CMS_NOCRL 0x2000 +# define CMS_PARTIAL 0x4000 +# define CMS_REUSE_DIGEST 0x8000 +# define CMS_USE_KEYID 0x10000 +# define CMS_DEBUG_DECRYPT 0x20000 +# define CMS_KEY_PARAM 0x40000 + +const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +# ifdef HEADER_PEM_H +DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) +# endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, + unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, + ossl_ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); +int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags); +EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si); +EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig); +ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +# ifdef HEADER_X509V3_H + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, + STACK_OF(GENERAL_NAMES) + *receiptList, STACK_OF(GENERAL_NAMES) + *receiptsTo); +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); +# endif +int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm); +STACK_OF(CMS_RecipientEncryptedKey) +*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri); + +int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, + X509_ALGOR **pubalg, + ASN1_BIT_STRING **pubkey, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert); + +int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, + ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, + X509 *cert); +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); +EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); +int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, + CMS_RecipientEncryptedKey *rek); + +int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CMS_strings(void); + +/* Error codes for the CMS functions. */ + +/* Function codes. */ +# define CMS_F_CHECK_CONTENT 99 +# define CMS_F_CMS_ADD0_CERT 164 +# define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 +# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 +# define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 +# define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 +# define CMS_F_CMS_ADD1_SIGNER 102 +# define CMS_F_CMS_ADD1_SIGNINGTIME 103 +# define CMS_F_CMS_COMPRESS 104 +# define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 +# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 +# define CMS_F_CMS_COPY_CONTENT 107 +# define CMS_F_CMS_COPY_MESSAGEDIGEST 108 +# define CMS_F_CMS_DATA 109 +# define CMS_F_CMS_DATAFINAL 110 +# define CMS_F_CMS_DATAINIT 111 +# define CMS_F_CMS_DECRYPT 112 +# define CMS_F_CMS_DECRYPT_SET1_KEY 113 +# define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 +# define CMS_F_CMS_DECRYPT_SET1_PKEY 114 +# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 +# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 +# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +# define CMS_F_CMS_DIGEST_VERIFY 118 +# define CMS_F_CMS_ENCODE_RECEIPT 161 +# define CMS_F_CMS_ENCRYPT 119 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 +# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 +# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 +# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 +# define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 +# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 +# define CMS_F_CMS_ENVELOPED_DATA_INIT 126 +# define CMS_F_CMS_ENV_ASN1_CTRL 171 +# define CMS_F_CMS_FINAL 127 +# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 +# define CMS_F_CMS_GET0_CONTENT 129 +# define CMS_F_CMS_GET0_ECONTENT_TYPE 130 +# define CMS_F_CMS_GET0_ENVELOPED 131 +# define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 +# define CMS_F_CMS_GET0_SIGNED 133 +# define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 +# define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 +# define CMS_F_CMS_RECEIPT_VERIFY 160 +# define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 +# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT 169 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT 178 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG 175 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID 173 +# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS 172 +# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP 174 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 +# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 +# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 +# define CMS_F_CMS_SD_ASN1_CTRL 170 +# define CMS_F_CMS_SET1_IAS 176 +# define CMS_F_CMS_SET1_KEYID 177 +# define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 +# define CMS_F_CMS_SET_DETACHED 147 +# define CMS_F_CMS_SIGN 148 +# define CMS_F_CMS_SIGNED_DATA_INIT 149 +# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 +# define CMS_F_CMS_SIGNERINFO_SIGN 151 +# define CMS_F_CMS_SIGNERINFO_VERIFY 152 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 +# define CMS_F_CMS_SIGN_RECEIPT 163 +# define CMS_F_CMS_STREAM 155 +# define CMS_F_CMS_UNCOMPRESS 156 +# define CMS_F_CMS_VERIFY 157 + +/* Reason codes. */ +# define CMS_R_ADD_SIGNER_ERROR 99 +# define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 +# define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 +# define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +# define CMS_R_CIPHER_INITIALISATION_ERROR 101 +# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 +# define CMS_R_CMS_DATAFINAL_ERROR 103 +# define CMS_R_CMS_LIB 104 +# define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 +# define CMS_R_CONTENT_NOT_FOUND 105 +# define CMS_R_CONTENT_TYPE_MISMATCH 171 +# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 +# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 +# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 +# define CMS_R_CONTENT_VERIFY_ERROR 109 +# define CMS_R_CTRL_ERROR 110 +# define CMS_R_CTRL_FAILURE 111 +# define CMS_R_DECRYPT_ERROR 112 +# define CMS_R_DIGEST_ERROR 161 +# define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 +# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 +# define CMS_R_ERROR_SETTING_KEY 115 +# define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 +# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 +# define CMS_R_INVALID_KEY_LENGTH 118 +# define CMS_R_MD_BIO_INIT_ERROR 119 +# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 +# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 +# define CMS_R_MSGSIGDIGEST_ERROR 172 +# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 +# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 +# define CMS_R_NEED_ONE_SIGNER 164 +# define CMS_R_NOT_A_SIGNED_RECEIPT 165 +# define CMS_R_NOT_ENCRYPTED_DATA 122 +# define CMS_R_NOT_KEK 123 +# define CMS_R_NOT_KEY_AGREEMENT 181 +# define CMS_R_NOT_KEY_TRANSPORT 124 +# define CMS_R_NOT_PWRI 177 +# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 +# define CMS_R_NO_CIPHER 126 +# define CMS_R_NO_CONTENT 127 +# define CMS_R_NO_CONTENT_TYPE 173 +# define CMS_R_NO_DEFAULT_DIGEST 128 +# define CMS_R_NO_DIGEST_SET 129 +# define CMS_R_NO_KEY 130 +# define CMS_R_NO_KEY_OR_CERT 174 +# define CMS_R_NO_MATCHING_DIGEST 131 +# define CMS_R_NO_MATCHING_RECIPIENT 132 +# define CMS_R_NO_MATCHING_SIGNATURE 166 +# define CMS_R_NO_MSGSIGDIGEST 167 +# define CMS_R_NO_PASSWORD 178 +# define CMS_R_NO_PRIVATE_KEY 133 +# define CMS_R_NO_PUBLIC_KEY 134 +# define CMS_R_NO_RECEIPT_REQUEST 168 +# define CMS_R_NO_SIGNERS 135 +# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 +# define CMS_R_RECEIPT_DECODE_ERROR 169 +# define CMS_R_RECIPIENT_ERROR 137 +# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 +# define CMS_R_SIGNFINAL_ERROR 139 +# define CMS_R_SMIME_TEXT_ERROR 140 +# define CMS_R_STORE_INIT_ERROR 141 +# define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 +# define CMS_R_TYPE_NOT_DATA 143 +# define CMS_R_TYPE_NOT_DIGESTED_DATA 144 +# define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 +# define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 +# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 +# define CMS_R_UNKNOWN_CIPHER 148 +# define CMS_R_UNKNOWN_DIGEST_ALGORIHM 149 +# define CMS_R_UNKNOWN_ID 150 +# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +# define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +# define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 +# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 +# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE 155 +# define CMS_R_UNSUPPORTED_TYPE 156 +# define CMS_R_UNWRAP_ERROR 157 +# define CMS_R_UNWRAP_FAILURE 180 +# define CMS_R_VERIFICATION_FAILURE 158 +# define CMS_R_WRAP_ERROR 159 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/cms_.c b/Sources/COpenSSL/cms_.c new file mode 100644 index 00000000..afbec0a0 --- /dev/null +++ b/Sources/COpenSSL/cms_.c @@ -0,0 +1,6361 @@ +/* crypto/cms/cms_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "asn1t.h" +#include "pem.h" +#include "x509v3.h" +#include "cms.h" +#include "cms_lcl.h" + + +ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = { + ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME), + ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER) +} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber) + +ASN1_SEQUENCE(CMS_OtherCertificateFormat) = { + ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT), + ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY) +} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat) + +ASN1_CHOICE(CMS_CertificateChoices) = { + ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509), + ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0), + ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1), + ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2), + ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3) +} ASN1_CHOICE_END(CMS_CertificateChoices) + +ASN1_CHOICE(CMS_SignerIdentifier) = { + ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), + ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0) +} ASN1_CHOICE_END(CMS_SignerIdentifier) + +ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = { + ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT), + ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0) +} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo) + +/* Minor tweak to operation: free up signer key, cert */ +static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + CMS_SignerInfo *si = (CMS_SignerInfo *)*pval; + if (si->pkey) + EVP_PKEY_free(si->pkey); + if (si->signer) + X509_free(si->signer); + if (si->pctx) + EVP_MD_CTX_cleanup(&si->mctx); + } + return 1; +} + +ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = { + ASN1_SIMPLE(CMS_SignerInfo, version, LONG), + ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier), + ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR), + ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0), + ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1) +} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo) + +ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = { + ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT), + ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY) +} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat) + +ASN1_CHOICE(CMS_RevocationInfoChoice) = { + ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL), + ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1) +} ASN1_CHOICE_END(CMS_RevocationInfoChoice) + +ASN1_NDEF_SEQUENCE(CMS_SignedData) = { + ASN1_SIMPLE(CMS_SignedData, version, LONG), + ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR), + ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0), + ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1), + ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo) +} ASN1_NDEF_SEQUENCE_END(CMS_SignedData) + +ASN1_SEQUENCE(CMS_OriginatorInfo) = { + ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0), + ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1) +} ASN1_SEQUENCE_END(CMS_OriginatorInfo) + +ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { + ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT), + ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR), + ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0) +} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo) + +ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = { + ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG), + ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier), + ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo) + +ASN1_SEQUENCE(CMS_OtherKeyAttribute) = { + ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT), + ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY) +} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute) + +ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = { + ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING), + ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME), + ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute) +} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier) + +ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = { + ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), + ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0) +} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier) + +static int cms_rek_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + CMS_RecipientEncryptedKey *rek = (CMS_RecipientEncryptedKey *)*pval; + if (operation == ASN1_OP_FREE_POST) { + if (rek->pkey) + EVP_PKEY_free(rek->pkey); + } + return 1; +} + +ASN1_SEQUENCE_cb(CMS_RecipientEncryptedKey, cms_rek_cb) = { + ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier), + ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END_cb(CMS_RecipientEncryptedKey, CMS_RecipientEncryptedKey) + +ASN1_SEQUENCE(CMS_OriginatorPublicKey) = { + ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey) + +ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = { + ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), + ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0), + ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1) +} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey) + +static int cms_kari_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + CMS_KeyAgreeRecipientInfo *kari = (CMS_KeyAgreeRecipientInfo *)*pval; + if (operation == ASN1_OP_NEW_POST) { + EVP_CIPHER_CTX_init(&kari->ctx); + EVP_CIPHER_CTX_set_flags(&kari->ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + kari->pctx = NULL; + } else if (operation == ASN1_OP_FREE_POST) { + if (kari->pctx) + EVP_PKEY_CTX_free(kari->pctx); + EVP_CIPHER_CTX_cleanup(&kari->ctx); + } + return 1; +} + +ASN1_SEQUENCE_cb(CMS_KeyAgreeRecipientInfo, cms_kari_cb) = { + ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG), + ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0), + ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1), + ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), + ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey) +} ASN1_SEQUENCE_END_cb(CMS_KeyAgreeRecipientInfo, CMS_KeyAgreeRecipientInfo) + +ASN1_SEQUENCE(CMS_KEKIdentifier) = { + ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING), + ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME), + ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute) +} ASN1_SEQUENCE_END(CMS_KEKIdentifier) + +ASN1_SEQUENCE(CMS_KEKRecipientInfo) = { + ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG), + ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier), + ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo) + +ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = { + ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG), + ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0), + ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo) + +ASN1_SEQUENCE(CMS_OtherRecipientInfo) = { + ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT), + ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY) +} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo) + +/* Free up RecipientInfo additional data */ +static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_PRE) { + CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval; + if (ri->type == CMS_RECIPINFO_TRANS) { + CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + if (ktri->pkey) + EVP_PKEY_free(ktri->pkey); + if (ktri->recip) + X509_free(ktri->recip); + if (ktri->pctx) + EVP_PKEY_CTX_free(ktri->pctx); + } else if (ri->type == CMS_RECIPINFO_KEK) { + CMS_KEKRecipientInfo *kekri = ri->d.kekri; + if (kekri->key) { + OPENSSL_cleanse(kekri->key, kekri->keylen); + OPENSSL_free(kekri->key); + } + } else if (ri->type == CMS_RECIPINFO_PASS) { + CMS_PasswordRecipientInfo *pwri = ri->d.pwri; + if (pwri->pass) { + OPENSSL_cleanse(pwri->pass, pwri->passlen); + OPENSSL_free(pwri->pass); + } + } + } + return 1; +} + +ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = { + ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo), + ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1), + ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2), + ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3), + ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4) +} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type) + +ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = { + ASN1_SIMPLE(CMS_EnvelopedData, version, LONG), + ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0), + ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo), + ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1) +} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData) + +ASN1_NDEF_SEQUENCE(CMS_DigestedData) = { + ASN1_SIMPLE(CMS_DigestedData, version, LONG), + ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo), + ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING) +} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData) + +ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = { + ASN1_SIMPLE(CMS_EncryptedData, version, LONG), + ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1) +} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData) + +ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = { + ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG), + ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0), + ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo), + ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR), + ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1), + ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2), + ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3) +} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData) + +ASN1_NDEF_SEQUENCE(CMS_CompressedData) = { + ASN1_SIMPLE(CMS_CompressedData, version, LONG), + ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo), +} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData) + +/* This is the ANY DEFINED BY table for the top level ContentInfo structure */ + +ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0); + +ASN1_ADB(CMS_ContentInfo) = { + ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)), + ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)), + ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)), + ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)), + ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)), + ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)), + ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), +} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); + +/* CMS streaming support */ +static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + ASN1_STREAM_ARG *sarg = exarg; + CMS_ContentInfo *cms = NULL; + if (pval) + cms = (CMS_ContentInfo *)*pval; + else + return 1; + switch (operation) { + + case ASN1_OP_STREAM_PRE: + if (CMS_stream(&sarg->boundary, cms) <= 0) + return 0; + case ASN1_OP_DETACHED_PRE: + sarg->ndef_bio = CMS_dataInit(cms, sarg->out); + if (!sarg->ndef_bio) + return 0; + break; + + case ASN1_OP_STREAM_POST: + case ASN1_OP_DETACHED_POST: + if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0) + return 0; + break; + + } + return 1; +} + +ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = { + ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT), + ASN1_ADB_OBJECT(CMS_ContentInfo) +} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo) + +/* Specials for signed attributes */ + +/* + * When signing attributes we want to reorder them to match the sorted + * encoding. + */ + +ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign) + +/* + * When verifying attributes we need to use the received order. So we use + * SEQUENCE OF and tag it to SET OF + */ + +ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, + V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify) + + + +ASN1_CHOICE(CMS_ReceiptsFrom) = { + ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0), + ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1) +} ASN1_CHOICE_END(CMS_ReceiptsFrom) + +ASN1_SEQUENCE(CMS_ReceiptRequest) = { + ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING), + ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom), + ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES) +} ASN1_SEQUENCE_END(CMS_ReceiptRequest) + +ASN1_SEQUENCE(CMS_Receipt) = { + ASN1_SIMPLE(CMS_Receipt, version, LONG), + ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT), + ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING), + ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_Receipt) + +/* + * Utilities to encode the CMS_SharedInfo structure used during key + * derivation. + */ + +typedef struct { + X509_ALGOR *keyInfo; + ASN1_OCTET_STRING *entityUInfo; + ASN1_OCTET_STRING *suppPubInfo; +} CMS_SharedInfo; + +ASN1_SEQUENCE(CMS_SharedInfo) = { + ASN1_SIMPLE(CMS_SharedInfo, keyInfo, X509_ALGOR), + ASN1_EXP_OPT(CMS_SharedInfo, entityUInfo, ASN1_OCTET_STRING, 0), + ASN1_EXP_OPT(CMS_SharedInfo, suppPubInfo, ASN1_OCTET_STRING, 2), +} ASN1_SEQUENCE_END(CMS_SharedInfo) + +int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, + ASN1_OCTET_STRING *ukm, int keylen) +{ + union { + CMS_SharedInfo *pecsi; + ASN1_VALUE *a; + } intsi = { + NULL + }; + + ASN1_OCTET_STRING oklen; + unsigned char kl[4]; + CMS_SharedInfo ecsi; + + keylen <<= 3; + kl[0] = (keylen >> 24) & 0xff; + kl[1] = (keylen >> 16) & 0xff; + kl[2] = (keylen >> 8) & 0xff; + kl[3] = keylen & 0xff; + oklen.length = 4; + oklen.data = kl; + oklen.type = V_ASN1_OCTET_STRING; + oklen.flags = 0; + ecsi.keyInfo = kekalg; + ecsi.entityUInfo = ukm; + ecsi.suppPubInfo = &oklen; + intsi.pecsi = &ecsi; + return ASN1_item_i2d(intsi.a, pder, ASN1_ITEM_rptr(CMS_SharedInfo)); +} +/* crypto/cms/cms_att.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "asn1t.h" +// #include "pem.h" +// #include "x509v3.h" +#include "err.h" +// #include "cms.h" +// #include "cms_lcl.h" + +/* CMS SignedData Attribute utilities */ + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si) +{ + return X509at_get_attr_count(si->signedAttrs); +} + +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos); +} + +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos); +} + +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc) +{ + return X509at_get_attr(si->signedAttrs, loc); +} + +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc) +{ + return X509at_delete_attr(si->signedAttrs, loc); +} + +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&si->signedAttrs, attr)) + return 1; + return 0; +} + +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len)) + return 1; + return 0; +} + +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, const void *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len)) + return 1; + return 0; +} + +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len)) + return 1; + return 0; +} + +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type) +{ + return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type); +} + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si) +{ + return X509at_get_attr_count(si->unsignedAttrs); +} + +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos) +{ + return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos); +} + +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos); +} + +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc) +{ + return X509at_get_attr(si->unsignedAttrs, loc); +} + +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc) +{ + return X509at_delete_attr(si->unsignedAttrs, loc); +} + +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&si->unsignedAttrs, attr)) + return 1; + return 0; +} + +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len)) + return 1; + return 0; +} + +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len)) + return 1; + return 0; +} + +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname, + type, bytes, len)) + return 1; + return 0; +} + +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type) +{ + return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type); +} + +/* Specific attribute cases */ +/* crypto/cms/cms_cd.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +// #include "asn1t.h" +// #include "pem.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +#include "bio.h" +#ifndef OPENSSL_NO_COMP +# include "comp.h" +#endif +// #include "cms_lcl.h" + +DECLARE_ASN1_ITEM(CMS_CompressedData) + +#ifdef ZLIB + +/* CMS CompressedData Utilities */ + +CMS_ContentInfo *cms_CompressedData_create(int comp_nid) +{ + CMS_ContentInfo *cms; + CMS_CompressedData *cd; + /* + * Will need something cleverer if there is ever more than one + * compression algorithm or parameters have some meaning... + */ + if (comp_nid != NID_zlib_compression) { + CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE, + CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return NULL; + } + cms = CMS_ContentInfo_new(); + if (!cms) + return NULL; + + cd = M_ASN1_new_of(CMS_CompressedData); + + if (!cd) + goto err; + + cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData); + cms->d.compressedData = cd; + + cd->version = 0; + + X509_ALGOR_set0(cd->compressionAlgorithm, + OBJ_nid2obj(NID_zlib_compression), V_ASN1_UNDEF, NULL); + + cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); + + return cms; + + err: + + if (cms) + CMS_ContentInfo_free(cms); + + return NULL; +} + +BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_CompressedData *cd; + ASN1_OBJECT *compoid; + if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) { + CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, + CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA); + return NULL; + } + cd = cms->d.compressedData; + X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm); + if (OBJ_obj2nid(compoid) != NID_zlib_compression) { + CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, + CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return NULL; + } + return BIO_new(BIO_f_zlib()); +} + +#endif +/* crypto/cms/cms_dd.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "pem.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +// #include "cms_lcl.h" + +DECLARE_ASN1_ITEM(CMS_DigestedData) + +/* CMS DigestedData Utilities */ + +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md) +{ + CMS_ContentInfo *cms; + CMS_DigestedData *dd; + cms = CMS_ContentInfo_new(); + if (!cms) + return NULL; + + dd = M_ASN1_new_of(CMS_DigestedData); + + if (!dd) + goto err; + + cms->contentType = OBJ_nid2obj(NID_pkcs7_digest); + cms->d.digestedData = dd; + + dd->version = 0; + dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); + + cms_DigestAlgorithm_set(dd->digestAlgorithm, md); + + return cms; + + err: + + if (cms) + CMS_ContentInfo_free(cms); + + return NULL; +} + +BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_DigestedData *dd; + dd = cms->d.digestedData; + return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm); +} + +int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify) +{ + EVP_MD_CTX mctx; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + int r = 0; + CMS_DigestedData *dd; + EVP_MD_CTX_init(&mctx); + + dd = cms->d.digestedData; + + if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm)) + goto err; + + if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0) + goto err; + + if (verify) { + if (mdlen != (unsigned int)dd->digest->length) { + CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, + CMS_R_MESSAGEDIGEST_WRONG_LENGTH); + goto err; + } + + if (memcmp(md, dd->digest->data, mdlen)) + CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, + CMS_R_VERIFICATION_FAILURE); + else + r = 1; + } else { + if (!ASN1_STRING_set(dd->digest, md, mdlen)) + goto err; + r = 1; + } + + err: + EVP_MD_CTX_cleanup(&mctx); + + return r; + +} +/* crypto/cms/cms_enc.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "pem.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +#include "rand.h" +// #include "cms_lcl.h" + +/* CMS EncryptedData Utilities */ + +DECLARE_ASN1_ITEM(CMS_EncryptedData) + +/* Return BIO based on EncryptedContentInfo and key */ + +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) +{ + BIO *b; + EVP_CIPHER_CTX *ctx; + const EVP_CIPHER *ciph; + X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; + unsigned char *tkey = NULL; + size_t tkeylen = 0; + + int ok = 0; + + int enc, keep_key = 0; + + enc = ec->cipher ? 1 : 0; + + b = BIO_new(BIO_f_cipher()); + if (!b) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + BIO_get_cipher_ctx(b, &ctx); + + if (enc) { + ciph = ec->cipher; + /* + * If not keeping key set cipher to NULL so subsequent calls decrypt. + */ + if (ec->key) + ec->cipher = NULL; + } else { + ciph = EVP_get_cipherbyobj(calg->algorithm); + + if (!ciph) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); + goto err; + } + } + + if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_INITIALISATION_ERROR); + goto err; + } + + if (enc) { + int ivlen; + calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); + /* Generate a random IV if we need one */ + ivlen = EVP_CIPHER_CTX_iv_length(ctx); + if (ivlen > 0) { + if (RAND_bytes(iv, ivlen) <= 0) + goto err; + piv = iv; + } + } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + tkeylen = EVP_CIPHER_CTX_key_length(ctx); + /* Generate random session key */ + if (!enc || !ec->key) { + tkey = OPENSSL_malloc(tkeylen); + if (!tkey) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) + goto err; + } + + if (!ec->key) { + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + if (enc) + keep_key = 1; + else + ERR_clear_error(); + + } + + if (ec->keylen != tkeylen) { + /* If necessary set key length */ + if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { + /* + * Only reveal failure if debugging so we don't leak information + * which may be useful in MMA. + */ + if (enc || ec->debug) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_INVALID_KEY_LENGTH); + goto err; + } else { + /* Use random key */ + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + ERR_clear_error(); + } + } + } + + if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_INITIALISATION_ERROR); + goto err; + } + if (enc) { + calg->parameter = ASN1_TYPE_new(); + if (calg->parameter == NULL) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + /* If parameter type not set omit parameter */ + if (calg->parameter->type == V_ASN1_UNDEF) { + ASN1_TYPE_free(calg->parameter); + calg->parameter = NULL; + } + } + ok = 1; + + err: + if (ec->key && (!keep_key || !ok)) { + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + ec->key = NULL; + } + if (tkey) { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + } + if (ok) + return b; + BIO_free(b); + return NULL; +} + +int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen) +{ + ec->cipher = cipher; + if (key) { + ec->key = OPENSSL_malloc(keylen); + if (!ec->key) + return 0; + memcpy(ec->key, key, keylen); + } + ec->keylen = keylen; + if (cipher) + ec->contentType = OBJ_nid2obj(NID_pkcs7_data); + return 1; +} + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen) +{ + CMS_EncryptedContentInfo *ec; + if (!key || !keylen) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY); + return 0; + } + if (ciph) { + cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData); + if (!cms->d.encryptedData) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE); + return 0; + } + cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); + cms->d.encryptedData->version = 0; + } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA); + return 0; + } + ec = cms->d.encryptedData->encryptedContentInfo; + return cms_EncryptedContent_init(ec, ciph, key, keylen); +} + +BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedData *enc = cms->d.encryptedData; + if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) + enc->version = 2; + return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); +} +/* crypto/cms/cms_env.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "pem.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +// #include "rand.h" +#include "aes.h" +// #include "cms_lcl.h" +#include "asn1_locl.h" + +/* CMS EnvelopedData Utilities */ + +DECLARE_ASN1_ITEM(CMS_EnvelopedData) +DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) +DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) +DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) + +DECLARE_STACK_OF(CMS_RecipientInfo) + +CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) +{ + if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { + CMSerr(CMS_F_CMS_GET0_ENVELOPED, + CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); + return NULL; + } + return cms->d.envelopedData; +} + +static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) +{ + if (cms->d.other == NULL) { + cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); + if (!cms->d.envelopedData) { + CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE); + return NULL; + } + cms->d.envelopedData->version = 0; + cms->d.envelopedData->encryptedContentInfo->contentType = + OBJ_nid2obj(NID_pkcs7_data); + ASN1_OBJECT_free(cms->contentType); + cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); + return cms->d.envelopedData; + } + return cms_get0_enveloped(cms); +} + +int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) +{ + EVP_PKEY *pkey; + int i; + if (ri->type == CMS_RECIPINFO_TRANS) + pkey = ri->d.ktri->pkey; + else if (ri->type == CMS_RECIPINFO_AGREE) { + EVP_PKEY_CTX *pctx = ri->d.kari->pctx; + if (!pctx) + return 0; + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!pkey) + return 0; + } else + return 0; + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return 1; + i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); + if (i == -2) { + CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; + } + if (i <= 0) { + CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE); + return 0; + } + return 1; +} + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) +{ + CMS_EnvelopedData *env; + env = cms_get0_enveloped(cms); + if (!env) + return NULL; + return env->recipientInfos; +} + +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) +{ + return ri->type; +} + +EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri) +{ + if (ri->type == CMS_RECIPINFO_TRANS) + return ri->d.ktri->pctx; + else if (ri->type == CMS_RECIPINFO_AGREE) + return ri->d.kari->pctx; + return NULL; +} + +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) +{ + CMS_ContentInfo *cms; + CMS_EnvelopedData *env; + cms = CMS_ContentInfo_new(); + if (!cms) + goto merr; + env = cms_enveloped_data_init(cms); + if (!env) + goto merr; + if (!cms_EncryptedContent_init(env->encryptedContentInfo, + cipher, NULL, 0)) + goto merr; + return cms; + merr: + if (cms) + CMS_ContentInfo_free(cms); + CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); + return NULL; +} + +/* Key Transport Recipient Info (KTRI) routines */ + +/* Initialise a ktri based on passed certificate and key */ + +static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, + EVP_PKEY *pk, unsigned int flags) +{ + CMS_KeyTransRecipientInfo *ktri; + int idtype; + + ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); + if (!ri->d.ktri) + return 0; + ri->type = CMS_RECIPINFO_TRANS; + + ktri = ri->d.ktri; + + if (flags & CMS_USE_KEYID) { + ktri->version = 2; + idtype = CMS_RECIPINFO_KEYIDENTIFIER; + } else { + ktri->version = 0; + idtype = CMS_RECIPINFO_ISSUER_SERIAL; + } + + /* + * Not a typo: RecipientIdentifier and SignerIdentifier are the same + * structure. + */ + + if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) + return 0; + + CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); + CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); + ktri->pkey = pk; + ktri->recip = recip; + + if (flags & CMS_KEY_PARAM) { + ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (!ktri->pctx) + return 0; + if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) + return 0; + } else if (!cms_env_asn1_ctrl(ri, 0)) + return 0; + return 1; +} + +/* + * Add a recipient certificate using appropriate type of RecipientInfo + */ + +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + EVP_PKEY *pk = NULL; + env = cms_get0_enveloped(cms); + if (!env) + goto err; + + /* Initialize recipient info */ + ri = M_ASN1_new_of(CMS_RecipientInfo); + if (!ri) + goto merr; + + pk = X509_get_pubkey(recip); + if (!pk) { + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY); + goto err; + } + + switch (cms_pkey_get_ri_type(pk)) { + + case CMS_RECIPINFO_TRANS: + if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags)) + goto err; + break; + + case CMS_RECIPINFO_AGREE: + if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) + goto err; + break; + + default: + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + + } + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + EVP_PKEY_free(pk); + + return ri; + + merr: + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); + err: + if (ri) + M_ASN1_free_of(ri, CMS_RecipientInfo); + if (pk) + EVP_PKEY_free(pk); + return NULL; + +} + +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg) +{ + CMS_KeyTransRecipientInfo *ktri; + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, + CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + + ktri = ri->d.ktri; + + if (pk) + *pk = ktri->pkey; + if (recip) + *recip = ktri->recip; + if (palg) + *palg = ktri->keyEncryptionAlgorithm; + return 1; +} + +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno) +{ + CMS_KeyTransRecipientInfo *ktri; + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, + CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + ktri = ri->d.ktri; + + return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno); +} + +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) +{ + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, + CMS_R_NOT_KEY_TRANSPORT); + return -2; + } + return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); +} + +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) +{ + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + ri->d.ktri->pkey = pkey; + return 1; +} + +/* Encrypt content key in key transport recipient info */ + +static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_KeyTransRecipientInfo *ktri; + CMS_EncryptedContentInfo *ec; + EVP_PKEY_CTX *pctx; + unsigned char *ek = NULL; + size_t eklen; + + int ret = 0; + + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + ktri = ri->d.ktri; + ec = cms->d.envelopedData->encryptedContentInfo; + + pctx = ktri->pctx; + + if (pctx) { + if (!cms_env_asn1_ctrl(ri, 0)) + goto err; + } else { + pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + goto err; + } + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) + goto err; + + ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); + ek = NULL; + + ret = 1; + + err: + if (pctx) { + EVP_PKEY_CTX_free(pctx); + ktri->pctx = NULL; + } + if (ek) + OPENSSL_free(ek); + return ret; + +} + +/* Decrypt content key from KTRI */ + +static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + EVP_PKEY *pkey = ktri->pkey; + unsigned char *ek = NULL; + size_t eklen; + int ret = 0; + CMS_EncryptedContentInfo *ec; + ec = cms->d.envelopedData->encryptedContentInfo; + + if (ktri->pkey == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY); + return 0; + } + + ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!ktri->pctx) + return 0; + + if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) + goto err; + + if (!cms_env_asn1_ctrl(ri, 1)) + goto err; + + if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, + ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, + ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); + goto err; + } + + ret = 1; + + if (ec->key) { + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + } + + ec->key = ek; + ec->keylen = eklen; + + err: + if (ktri->pctx) { + EVP_PKEY_CTX_free(ktri->pctx); + ktri->pctx = NULL; + } + if (!ret && ek) + OPENSSL_free(ek); + + return ret; +} + +/* Key Encrypted Key (KEK) RecipientInfo routines */ + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen) +{ + ASN1_OCTET_STRING tmp_os; + CMS_KEKRecipientInfo *kekri; + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK); + return -2; + } + kekri = ri->d.kekri; + tmp_os.type = V_ASN1_OCTET_STRING; + tmp_os.flags = 0; + tmp_os.data = (unsigned char *)id; + tmp_os.length = (int)idlen; + return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); +} + +/* For now hard code AES key wrap info */ + +static size_t aes_wrap_keylen(int nid) +{ + switch (nid) { + case NID_id_aes128_wrap: + return 16; + + case NID_id_aes192_wrap: + return 24; + + case NID_id_aes256_wrap: + return 32; + + default: + return 0; + } +} + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + CMS_KEKRecipientInfo *kekri; + env = cms_get0_enveloped(cms); + if (!env) + goto err; + + if (nid == NID_undef) { + switch (keylen) { + case 16: + nid = NID_id_aes128_wrap; + break; + + case 24: + nid = NID_id_aes192_wrap; + break; + + case 32: + nid = NID_id_aes256_wrap; + break; + + default: + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); + goto err; + } + + } else { + + size_t exp_keylen = aes_wrap_keylen(nid); + + if (!exp_keylen) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, + CMS_R_UNSUPPORTED_KEK_ALGORITHM); + goto err; + } + + if (keylen != exp_keylen) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); + goto err; + } + + } + + /* Initialize recipient info */ + ri = M_ASN1_new_of(CMS_RecipientInfo); + if (!ri) + goto merr; + + ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); + if (!ri->d.kekri) + goto merr; + ri->type = CMS_RECIPINFO_KEK; + + kekri = ri->d.kekri; + + if (otherTypeId) { + kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); + if (kekri->kekid->other == NULL) + goto merr; + } + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + /* After this point no calls can fail */ + + kekri->version = 4; + + kekri->key = key; + kekri->keylen = keylen; + + ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); + + kekri->kekid->date = date; + + if (kekri->kekid->other) { + kekri->kekid->other->keyAttrId = otherTypeId; + kekri->kekid->other->keyAttr = otherType; + } + + X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, + OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); + + return ri; + + merr: + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE); + err: + if (ri) + M_ASN1_free_of(ri, CMS_RecipientInfo); + return NULL; + +} + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype) +{ + CMS_KEKIdentifier *rkid; + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK); + return 0; + } + rkid = ri->d.kekri->kekid; + if (palg) + *palg = ri->d.kekri->keyEncryptionAlgorithm; + if (pid) + *pid = rkid->keyIdentifier; + if (pdate) + *pdate = rkid->date; + if (potherid) { + if (rkid->other) + *potherid = rkid->other->keyAttrId; + else + *potherid = NULL; + } + if (pothertype) { + if (rkid->other) + *pothertype = rkid->other->keyAttr; + else + *pothertype = NULL; + } + return 1; +} + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen) +{ + CMS_KEKRecipientInfo *kekri; + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK); + return 0; + } + + kekri = ri->d.kekri; + kekri->key = key; + kekri->keylen = keylen; + return 1; +} + +/* Encrypt content key in KEK recipient info */ + +static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_EncryptedContentInfo *ec; + CMS_KEKRecipientInfo *kekri; + AES_KEY actx; + unsigned char *wkey = NULL; + int wkeylen; + int r = 0; + + ec = cms->d.envelopedData->encryptedContentInfo; + + kekri = ri->d.kekri; + + if (!kekri->key) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); + return 0; + } + + if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, + CMS_R_ERROR_SETTING_KEY); + goto err; + } + + wkey = OPENSSL_malloc(ec->keylen + 8); + + if (!wkey) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); + + if (wkeylen <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); + goto err; + } + + ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); + + r = 1; + + err: + + if (!r && wkey) + OPENSSL_free(wkey); + OPENSSL_cleanse(&actx, sizeof(actx)); + + return r; + +} + +/* Decrypt content key in KEK recipient info */ + +static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_EncryptedContentInfo *ec; + CMS_KEKRecipientInfo *kekri; + AES_KEY actx; + unsigned char *ukey = NULL; + int ukeylen; + int r = 0, wrap_nid; + + ec = cms->d.envelopedData->encryptedContentInfo; + + kekri = ri->d.kekri; + + if (!kekri->key) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); + return 0; + } + + wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); + if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, + CMS_R_INVALID_KEY_LENGTH); + return 0; + } + + /* If encrypted key length is invalid don't bother */ + + if (kekri->encryptedKey->length < 16) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, + CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); + goto err; + } + + if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, + CMS_R_ERROR_SETTING_KEY); + goto err; + } + + ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); + + if (!ukey) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + ukeylen = AES_unwrap_key(&actx, NULL, ukey, + kekri->encryptedKey->data, + kekri->encryptedKey->length); + + if (ukeylen <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR); + goto err; + } + + ec->key = ukey; + ec->keylen = ukeylen; + + r = 1; + + err: + + if (!r && ukey) + OPENSSL_free(ukey); + OPENSSL_cleanse(&actx, sizeof(actx)); + + return r; + +} + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + switch (ri->type) { + case CMS_RECIPINFO_TRANS: + return cms_RecipientInfo_ktri_decrypt(cms, ri); + + case CMS_RECIPINFO_KEK: + return cms_RecipientInfo_kekri_decrypt(cms, ri); + + case CMS_RECIPINFO_PASS: + return cms_RecipientInfo_pwri_crypt(cms, ri, 0); + + default: + CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, + CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); + return 0; + } +} + +int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + switch (ri->type) { + case CMS_RECIPINFO_TRANS: + return cms_RecipientInfo_ktri_encrypt(cms, ri); + + case CMS_RECIPINFO_AGREE: + return cms_RecipientInfo_kari_encrypt(cms, ri); + + case CMS_RECIPINFO_KEK: + return cms_RecipientInfo_kekri_encrypt(cms, ri); + break; + + case CMS_RECIPINFO_PASS: + return cms_RecipientInfo_pwri_crypt(cms, ri, 1); + break; + + default: + CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT, + CMS_R_UNSUPPORTED_RECIPIENT_TYPE); + return 0; + } +} + +/* Check structures and fixup version numbers (if necessary) */ + +static void cms_env_set_originfo_version(CMS_EnvelopedData *env) +{ + CMS_OriginatorInfo *org = env->originatorInfo; + int i; + if (org == NULL) + return; + for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) { + CMS_CertificateChoices *cch; + cch = sk_CMS_CertificateChoices_value(org->certificates, i); + if (cch->type == CMS_CERTCHOICE_OTHER) { + env->version = 4; + return; + } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { + if (env->version < 3) + env->version = 3; + } + } + + for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) { + CMS_RevocationInfoChoice *rch; + rch = sk_CMS_RevocationInfoChoice_value(org->crls, i); + if (rch->type == CMS_REVCHOICE_OTHER) { + env->version = 4; + return; + } + } +} + +static void cms_env_set_version(CMS_EnvelopedData *env) +{ + int i; + CMS_RecipientInfo *ri; + + /* + * Can't set version higher than 4 so if 4 or more already nothing to do. + */ + if (env->version >= 4) + return; + + cms_env_set_originfo_version(env); + + if (env->version >= 3) + return; + + for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) { + ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i); + if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) { + env->version = 3; + return; + } else if (ri->type != CMS_RECIPINFO_TRANS + || ri->d.ktri->version != 0) { + env->version = 2; + } + } + if (env->version == 2) + return; + if (env->originatorInfo || env->unprotectedAttrs) + env->version = 2; + env->version = 0; +} + +BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedContentInfo *ec; + STACK_OF(CMS_RecipientInfo) *rinfos; + CMS_RecipientInfo *ri; + int i, ok = 0; + BIO *ret; + + /* Get BIO first to set up key */ + + ec = cms->d.envelopedData->encryptedContentInfo; + ret = cms_EncryptedContent_init_bio(ec); + + /* If error or no cipher end of processing */ + + if (!ret || !ec->cipher) + return ret; + + /* Now encrypt content key according to each RecipientInfo type */ + + rinfos = cms->d.envelopedData->recipientInfos; + + for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { + ri = sk_CMS_RecipientInfo_value(rinfos, i); + if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { + CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, + CMS_R_ERROR_SETTING_RECIPIENTINFO); + goto err; + } + } + cms_env_set_version(cms->d.envelopedData); + + ok = 1; + + err: + ec->cipher = NULL; + if (ec->key) { + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + ec->key = NULL; + ec->keylen = 0; + } + if (ok) + return ret; + BIO_free(ret); + return NULL; + +} + +/* + * Get RecipientInfo type (if any) supported by a key (public or private). To + * retain compatibility with previous behaviour if the ctrl value isn't + * supported we assume key transport. + */ +int cms_pkey_get_ri_type(EVP_PKEY *pk) +{ + if (pk->ameth && pk->ameth->pkey_ctrl) { + int i, r; + i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r); + if (i > 0) + return r; + } + return CMS_RECIPINFO_TRANS; +} +/* crypto/cms/cms_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +// #include "err.h" +// #include "cms.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason) + +static ERR_STRING_DATA CMS_str_functs[] = { + {ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"}, + {ERR_FUNC(CMS_F_CMS_ADD0_CERT), "CMS_add0_cert"}, + {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"}, + {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD), + "CMS_add0_recipient_password"}, + {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"}, + {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"}, + {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"}, + {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"}, + {ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"}, + {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "cms_CompressedData_create"}, + {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO), + "cms_CompressedData_init_bio"}, + {ERR_FUNC(CMS_F_CMS_COPY_CONTENT), "CMS_COPY_CONTENT"}, + {ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST), "CMS_COPY_MESSAGEDIGEST"}, + {ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"}, + {ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"}, + {ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"}, + {ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"}, + {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"}, + {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD), "CMS_decrypt_set1_password"}, + {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"}, + {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX), + "cms_DigestAlgorithm_find_ctx"}, + {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO), + "cms_DigestAlgorithm_init_bio"}, + {ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "cms_DigestedData_do_final"}, + {ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"}, + {ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT), "cms_encode_Receipt"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO), + "cms_EncryptedContent_init_bio"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT), "CMS_EncryptedData_encrypt"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY), + "CMS_EncryptedData_set1_key"}, + {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"}, + {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO), + "cms_EnvelopedData_init_bio"}, + {ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"}, + {ERR_FUNC(CMS_F_CMS_ENV_ASN1_CTRL), "cms_env_asn1_ctrl"}, + {ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"}, + {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), + "CMS_GET0_CERTIFICATE_CHOICES"}, + {ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"}, + {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "CMS_GET0_ECONTENT_TYPE"}, + {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "cms_get0_enveloped"}, + {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES), + "CMS_GET0_REVOCATION_CHOICES"}, + {ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"}, + {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "cms_msgSigDigest_add1"}, + {ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0), + "CMS_ReceiptRequest_create0"}, + {ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY), "cms_Receipt_verify"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_ENCRYPT), "CMS_RecipientInfo_encrypt"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT), + "cms_RecipientInfo_kari_encrypt"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG), + "CMS_RecipientInfo_kari_get0_alg"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID), + "CMS_RecipientInfo_kari_get0_orig_id"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS), + "CMS_RecipientInfo_kari_get0_reks"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP), + "CMS_RecipientInfo_kari_orig_id_cmp"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT), + "CMS_RECIPIENTINFO_KEKRI_DECRYPT"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT), + "CMS_RECIPIENTINFO_KEKRI_ENCRYPT"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID), + "CMS_RecipientInfo_kekri_get0_id"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP), + "CMS_RecipientInfo_kekri_id_cmp"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), + "CMS_RecipientInfo_ktri_cert_cmp"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT), + "CMS_RECIPIENTINFO_KTRI_DECRYPT"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT), + "CMS_RECIPIENTINFO_KTRI_ENCRYPT"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS), + "CMS_RecipientInfo_ktri_get0_algs"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID), + "CMS_RecipientInfo_ktri_get0_signer_id"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT), + "cms_RecipientInfo_pwri_crypt"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY), + "CMS_RecipientInfo_set0_key"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD), + "CMS_RecipientInfo_set0_password"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY), + "CMS_RecipientInfo_set0_pkey"}, + {ERR_FUNC(CMS_F_CMS_SD_ASN1_CTRL), "CMS_SD_ASN1_CTRL"}, + {ERR_FUNC(CMS_F_CMS_SET1_IAS), "cms_set1_ias"}, + {ERR_FUNC(CMS_F_CMS_SET1_KEYID), "cms_set1_keyid"}, + {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"}, + {ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"}, + {ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"}, + {ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT), "CMS_SIGNED_DATA_INIT"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN), + "CMS_SIGNERINFO_CONTENT_SIGN"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN), "CMS_SignerInfo_sign"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY), "CMS_SignerInfo_verify"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), + "CMS_SIGNERINFO_VERIFY_CERT"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), + "CMS_SignerInfo_verify_content"}, + {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"}, + {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"}, + {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"}, + {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"}, + {0, NULL} +}; + +static ERR_STRING_DATA CMS_str_reasons[] = { + {ERR_REASON(CMS_R_ADD_SIGNER_ERROR), "add signer error"}, + {ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT), + "certificate already present"}, + {ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID), "certificate has no keyid"}, + {ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR), + "cipher initialisation error"}, + {ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR), + "cipher parameter initialisation error"}, + {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR), "cms datafinal error"}, + {ERR_REASON(CMS_R_CMS_LIB), "cms lib"}, + {ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH), + "contentidentifier mismatch"}, + {ERR_REASON(CMS_R_CONTENT_NOT_FOUND), "content not found"}, + {ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH), "content type mismatch"}, + {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA), + "content type not compressed data"}, + {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA), + "content type not enveloped data"}, + {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA), + "content type not signed data"}, + {ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR), "content verify error"}, + {ERR_REASON(CMS_R_CTRL_ERROR), "ctrl error"}, + {ERR_REASON(CMS_R_CTRL_FAILURE), "ctrl failure"}, + {ERR_REASON(CMS_R_DECRYPT_ERROR), "decrypt error"}, + {ERR_REASON(CMS_R_DIGEST_ERROR), "digest error"}, + {ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY), "error getting public key"}, + {ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE), + "error reading messagedigest attribute"}, + {ERR_REASON(CMS_R_ERROR_SETTING_KEY), "error setting key"}, + {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO), + "error setting recipientinfo"}, + {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH), + "invalid encrypted key length"}, + {ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER), + "invalid key encryption parameter"}, + {ERR_REASON(CMS_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR), "md bio init error"}, + {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH), + "messagedigest attribute wrong length"}, + {ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH), + "messagedigest wrong length"}, + {ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"}, + {ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE), + "msgsigdigest verification failure"}, + {ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH), + "msgsigdigest wrong length"}, + {ERR_REASON(CMS_R_NEED_ONE_SIGNER), "need one signer"}, + {ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT), "not a signed receipt"}, + {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"}, + {ERR_REASON(CMS_R_NOT_KEK), "not kek"}, + {ERR_REASON(CMS_R_NOT_KEY_AGREEMENT), "not key agreement"}, + {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT), "not key transport"}, + {ERR_REASON(CMS_R_NOT_PWRI), "not pwri"}, + {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), + "not supported for this key type"}, + {ERR_REASON(CMS_R_NO_CIPHER), "no cipher"}, + {ERR_REASON(CMS_R_NO_CONTENT), "no content"}, + {ERR_REASON(CMS_R_NO_CONTENT_TYPE), "no content type"}, + {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_REASON(CMS_R_NO_DIGEST_SET), "no digest set"}, + {ERR_REASON(CMS_R_NO_KEY), "no key"}, + {ERR_REASON(CMS_R_NO_KEY_OR_CERT), "no key or cert"}, + {ERR_REASON(CMS_R_NO_MATCHING_DIGEST), "no matching digest"}, + {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT), "no matching recipient"}, + {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE), "no matching signature"}, + {ERR_REASON(CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"}, + {ERR_REASON(CMS_R_NO_PASSWORD), "no password"}, + {ERR_REASON(CMS_R_NO_PRIVATE_KEY), "no private key"}, + {ERR_REASON(CMS_R_NO_PUBLIC_KEY), "no public key"}, + {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST), "no receipt request"}, + {ERR_REASON(CMS_R_NO_SIGNERS), "no signers"}, + {ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR), "receipt decode error"}, + {ERR_REASON(CMS_R_RECIPIENT_ERROR), "recipient error"}, + {ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND), + "signer certificate not found"}, + {ERR_REASON(CMS_R_SIGNFINAL_ERROR), "signfinal error"}, + {ERR_REASON(CMS_R_SMIME_TEXT_ERROR), "smime text error"}, + {ERR_REASON(CMS_R_STORE_INIT_ERROR), "store init error"}, + {ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA), "type not compressed data"}, + {ERR_REASON(CMS_R_TYPE_NOT_DATA), "type not data"}, + {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA), "type not digested data"}, + {ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA), "type not encrypted data"}, + {ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA), "type not enveloped data"}, + {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT), + "unable to finalize context"}, + {ERR_REASON(CMS_R_UNKNOWN_CIPHER), "unknown cipher"}, + {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM), "unknown digest algorihm"}, + {ERR_REASON(CMS_R_UNKNOWN_ID), "unknown id"}, + {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM), + "unsupported compression algorithm"}, + {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"}, + {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM), + "unsupported kek algorithm"}, + {ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM), + "unsupported key encryption algorithm"}, + {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE), + "unsupported recipient type"}, + {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE), + "unsupported recpientinfo type"}, + {ERR_REASON(CMS_R_UNSUPPORTED_TYPE), "unsupported type"}, + {ERR_REASON(CMS_R_UNWRAP_ERROR), "unwrap error"}, + {ERR_REASON(CMS_R_UNWRAP_FAILURE), "unwrap failure"}, + {ERR_REASON(CMS_R_VERIFICATION_FAILURE), "verification failure"}, + {ERR_REASON(CMS_R_WRAP_ERROR), "wrap error"}, + {0, NULL} +}; + +#endif + +void ERR_load_CMS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) { + ERR_load_strings(0, CMS_str_functs); + ERR_load_strings(0, CMS_str_reasons); + } +#endif +} +/* crypto/cms/cms_ess.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "pem.h" +// #include "rand.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +// #include "cms_lcl.h" + +DECLARE_ASN1_ITEM(CMS_ReceiptRequest) +DECLARE_ASN1_ITEM(CMS_Receipt) + +IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) + +/* ESS services: for now just Signed Receipt related */ + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) +{ + ASN1_STRING *str; + CMS_ReceiptRequest *rr = NULL; + if (prr) + *prr = NULL; + str = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj + (NID_id_smime_aa_receiptRequest), -3, + V_ASN1_SEQUENCE); + if (!str) + return 0; + + rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); + if (!rr) + return -1; + if (prr) + *prr = rr; + else + CMS_ReceiptRequest_free(rr); + return 1; +} + +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, + STACK_OF(GENERAL_NAMES) + *receiptList, STACK_OF(GENERAL_NAMES) + *receiptsTo) +{ + CMS_ReceiptRequest *rr = NULL; + + rr = CMS_ReceiptRequest_new(); + if (!rr) + goto merr; + if (id) + ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); + else { + if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) + goto merr; + if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0) + goto err; + } + + sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); + rr->receiptsTo = receiptsTo; + + if (receiptList) { + rr->receiptsFrom->type = 1; + rr->receiptsFrom->d.receiptList = receiptList; + } else { + rr->receiptsFrom->type = 0; + rr->receiptsFrom->d.allOrFirstTier = allorfirst; + } + + return rr; + + merr: + CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE); + + err: + if (rr) + CMS_ReceiptRequest_free(rr); + + return NULL; + +} + +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) +{ + unsigned char *rrder = NULL; + int rrderlen, r = 0; + + rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder); + if (rrderlen < 0) + goto merr; + + if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest, + V_ASN1_SEQUENCE, rrder, rrderlen)) + goto merr; + + r = 1; + + merr: + if (!r) + CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE); + + if (rrder) + OPENSSL_free(rrder); + + return r; + +} + +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto) +{ + if (pcid) + *pcid = rr->signedContentIdentifier; + if (rr->receiptsFrom->type == 0) { + if (pallorfirst) + *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; + if (plist) + *plist = NULL; + } else { + if (pallorfirst) + *pallorfirst = -1; + if (plist) + *plist = rr->receiptsFrom->d.receiptList; + } + if (prto) + *prto = rr->receiptsTo; +} + +/* Digest a SignerInfo structure for msgSigDigest attribute processing */ + +static int cms_msgSigDigest(CMS_SignerInfo *si, + unsigned char *dig, unsigned int *diglen) +{ + const EVP_MD *md; + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) + return 0; + if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, + si->signedAttrs, dig, diglen)) + return 0; + return 1; +} + +/* Add a msgSigDigest attribute to a SignerInfo */ + +int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) +{ + unsigned char dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + if (!cms_msgSigDigest(src, dig, &diglen)) { + CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); + return 0; + } + if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, + V_ASN1_OCTET_STRING, dig, diglen)) { + CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +/* Verify signed receipt after it has already passed normal CMS verify */ + +int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) +{ + int r = 0, i; + CMS_ReceiptRequest *rr = NULL; + CMS_Receipt *rct = NULL; + STACK_OF(CMS_SignerInfo) *sis, *osis; + CMS_SignerInfo *si, *osi = NULL; + ASN1_OCTET_STRING *msig, **pcont; + ASN1_OBJECT *octype; + unsigned char dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + /* Get SignerInfos, also checks SignedData content type */ + osis = CMS_get0_SignerInfos(req_cms); + sis = CMS_get0_SignerInfos(cms); + if (!osis || !sis) + goto err; + + if (sk_CMS_SignerInfo_num(sis) != 1) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER); + goto err; + } + + /* Check receipt content type */ + if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT); + goto err; + } + + /* Extract and decode receipt content */ + pcont = CMS_get0_content(cms); + if (!pcont || !*pcont) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT); + goto err; + } + + rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt)); + + if (!rct) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR); + goto err; + } + + /* Locate original request */ + + for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) { + osi = sk_CMS_SignerInfo_value(osis, i); + if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue)) + break; + } + + if (i == sk_CMS_SignerInfo_num(osis)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE); + goto err; + } + + si = sk_CMS_SignerInfo_value(sis, 0); + + /* Get msgSigDigest value and compare */ + + msig = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj + (NID_id_smime_aa_msgSigDigest), -3, + V_ASN1_OCTET_STRING); + + if (!msig) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST); + goto err; + } + + if (!cms_msgSigDigest(osi, dig, &diglen)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR); + goto err; + } + + if (diglen != (unsigned int)msig->length) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH); + goto err; + } + + if (memcmp(dig, msig->data, diglen)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, + CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); + goto err; + } + + /* Compare content types */ + + octype = CMS_signed_get0_data_by_OBJ(osi, + OBJ_nid2obj(NID_pkcs9_contentType), + -3, V_ASN1_OBJECT); + if (!octype) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE); + goto err; + } + + /* Compare details in receipt request */ + + if (OBJ_cmp(octype, rct->contentType)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH); + goto err; + } + + /* Get original receipt request details */ + + if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); + goto err; + } + + if (ASN1_STRING_cmp(rr->signedContentIdentifier, + rct->signedContentIdentifier)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH); + goto err; + } + + r = 1; + + err: + if (rr) + CMS_ReceiptRequest_free(rr); + if (rct) + M_ASN1_free_of(rct, CMS_Receipt); + + return r; + +} + +/* + * Encode a Receipt into an OCTET STRING read for including into content of a + * SignedData ContentInfo. + */ + +ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) +{ + CMS_Receipt rct; + CMS_ReceiptRequest *rr = NULL; + ASN1_OBJECT *ctype; + ASN1_OCTET_STRING *os = NULL; + + /* Get original receipt request */ + + /* Get original receipt request details */ + + if (CMS_get1_ReceiptRequest(si, &rr) <= 0) { + CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); + goto err; + } + + /* Get original content type */ + + ctype = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj(NID_pkcs9_contentType), + -3, V_ASN1_OBJECT); + if (!ctype) { + CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE); + goto err; + } + + rct.version = 1; + rct.contentType = ctype; + rct.signedContentIdentifier = rr->signedContentIdentifier; + rct.originatorSignatureValue = si->signature; + + os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL); + + err: + if (rr) + CMS_ReceiptRequest_free(rr); + + return os; + +} +/* crypto/cms/cms_io.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "asn1t.h" +#include "x509.h" +// #include "err.h" +// #include "pem.h" +// #include "cms.h" +// #include "cms_lcl.h" + +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); + if (!pos) + return 0; + if (!*pos) + *pos = ASN1_OCTET_STRING_new(); + if (*pos) { + (*pos)->flags |= ASN1_STRING_FLAG_NDEF; + (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; + *boundary = &(*pos)->data; + return 1; + } + CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE); + return 0; +} + +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); +} + +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); +} + +IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) +{ + return BIO_new_NDEF(out, (ASN1_VALUE *)cms, + ASN1_ITEM_rptr(CMS_ContentInfo)); +} + +/* CMS wrappers round generalised stream and MIME routines */ + +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) +{ + return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags, + ASN1_ITEM_rptr(CMS_ContentInfo)); +} + +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags) +{ + return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags, + "CMS", ASN1_ITEM_rptr(CMS_ContentInfo)); +} + +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) +{ + STACK_OF(X509_ALGOR) *mdalgs; + int ctype_nid = OBJ_obj2nid(cms->contentType); + int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms)); + if (ctype_nid == NID_pkcs7_signed) + mdalgs = cms->d.signedData->digestAlgorithms; + else + mdalgs = NULL; + + return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, + ctype_nid, econt_nid, mdalgs, + ASN1_ITEM_rptr(CMS_ContentInfo)); +} + +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont) +{ + return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, + ASN1_ITEM_rptr + (CMS_ContentInfo)); +} +/* crypto/cms/cms_kari.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "pem.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +// #include "rand.h" +// #include "aes.h" +// #include "cms_lcl.h" +// #include "asn1_locl.h" + +DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo) +DECLARE_ASN1_ITEM(CMS_RecipientEncryptedKey) +DECLARE_ASN1_ITEM(CMS_OriginatorPublicKey) +DECLARE_ASN1_ITEM(CMS_RecipientKeyIdentifier) + +/* Key Agreement Recipient Info (KARI) routines */ + +int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pukm) +{ + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG, + CMS_R_NOT_KEY_AGREEMENT); + return 0; + } + if (palg) + *palg = ri->d.kari->keyEncryptionAlgorithm; + if (pukm) + *pukm = ri->d.kari->ukm; + return 1; +} + +/* Retrieve recipient encrypted keys from a kari */ + +STACK_OF(CMS_RecipientEncryptedKey) +*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri) +{ + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS, + CMS_R_NOT_KEY_AGREEMENT); + return NULL; + } + return ri->d.kari->recipientEncryptedKeys; +} + +int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, + X509_ALGOR **pubalg, + ASN1_BIT_STRING **pubkey, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno) +{ + CMS_OriginatorIdentifierOrKey *oik; + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, + CMS_R_NOT_KEY_AGREEMENT); + return 0; + } + oik = ri->d.kari->originator; + if (issuer) + *issuer = NULL; + if (sno) + *sno = NULL; + if (keyid) + *keyid = NULL; + if (pubalg) + *pubalg = NULL; + if (pubkey) + *pubkey = NULL; + if (oik->type == CMS_OIK_ISSUER_SERIAL) { + if (issuer) + *issuer = oik->d.issuerAndSerialNumber->issuer; + if (sno) + *sno = oik->d.issuerAndSerialNumber->serialNumber; + } else if (oik->type == CMS_OIK_KEYIDENTIFIER) { + if (keyid) + *keyid = oik->d.subjectKeyIdentifier; + } else if (oik->type == CMS_OIK_PUBKEY) { + if (pubalg) + *pubalg = oik->d.originatorKey->algorithm; + if (pubkey) + *pubkey = oik->d.originatorKey->publicKey; + } else + return 0; + return 1; +} + +int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) +{ + CMS_OriginatorIdentifierOrKey *oik; + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, + CMS_R_NOT_KEY_AGREEMENT); + return -2; + } + oik = ri->d.kari->originator; + if (oik->type == CMS_OIK_ISSUER_SERIAL) + return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); + else if (oik->type == CMS_OIK_KEYIDENTIFIER) + return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); + return -1; +} + +int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, + ASN1_OCTET_STRING **keyid, + ASN1_GENERALIZEDTIME **tm, + CMS_OtherKeyAttribute **other, + X509_NAME **issuer, ASN1_INTEGER **sno) +{ + CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; + if (rid->type == CMS_REK_ISSUER_SERIAL) { + if (issuer) + *issuer = rid->d.issuerAndSerialNumber->issuer; + if (sno) + *sno = rid->d.issuerAndSerialNumber->serialNumber; + if (keyid) + *keyid = NULL; + if (tm) + *tm = NULL; + if (other) + *other = NULL; + } else if (rid->type == CMS_REK_KEYIDENTIFIER) { + if (keyid) + *keyid = rid->d.rKeyId->subjectKeyIdentifier; + if (tm) + *tm = rid->d.rKeyId->date; + if (other) + *other = rid->d.rKeyId->other; + if (issuer) + *issuer = NULL; + if (sno) + *sno = NULL; + } else + return 0; + return 1; +} + +int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, + X509 *cert) +{ + CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; + if (rid->type == CMS_REK_ISSUER_SERIAL) + return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); + else if (rid->type == CMS_REK_KEYIDENTIFIER) + return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert); + else + return -1; +} + +int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) +{ + EVP_PKEY_CTX *pctx; + CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; + if (kari->pctx) { + EVP_PKEY_CTX_free(kari->pctx); + kari->pctx = NULL; + } + if (!pk) + return 1; + pctx = EVP_PKEY_CTX_new(pk, NULL); + if (!pctx || !EVP_PKEY_derive_init(pctx)) + goto err; + kari->pctx = pctx; + return 1; + err: + if (pctx) + EVP_PKEY_CTX_free(pctx); + return 0; +} + +EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) +{ + if (ri->type == CMS_RECIPINFO_AGREE) + return &ri->d.kari->ctx; + return NULL; +} + +/* + * Derive KEK and decrypt/encrypt with it to produce either the original CEK + * or the encrypted CEK. + */ + +static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, + const unsigned char *in, size_t inlen, + CMS_KeyAgreeRecipientInfo *kari, int enc) +{ + /* Key encryption key */ + unsigned char kek[EVP_MAX_KEY_LENGTH]; + size_t keklen; + int rv = 0; + unsigned char *out = NULL; + int outlen; + keklen = EVP_CIPHER_CTX_key_length(&kari->ctx); + if (keklen > EVP_MAX_KEY_LENGTH) + return 0; + /* Derive KEK */ + if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0) + goto err; + /* Set KEK in context */ + if (!EVP_CipherInit_ex(&kari->ctx, NULL, NULL, kek, NULL, enc)) + goto err; + /* obtain output length of ciphered key */ + if (!EVP_CipherUpdate(&kari->ctx, NULL, &outlen, in, inlen)) + goto err; + out = OPENSSL_malloc(outlen); + if (!out) + goto err; + if (!EVP_CipherUpdate(&kari->ctx, out, &outlen, in, inlen)) + goto err; + *pout = out; + *poutlen = (size_t)outlen; + rv = 1; + + err: + OPENSSL_cleanse(kek, keklen); + if (!rv && out) + OPENSSL_free(out); + EVP_CIPHER_CTX_cleanup(&kari->ctx); + EVP_PKEY_CTX_free(kari->pctx); + kari->pctx = NULL; + return rv; +} + +int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri, + CMS_RecipientEncryptedKey *rek) +{ + int rv = 0; + unsigned char *enckey = NULL, *cek = NULL; + size_t enckeylen; + size_t ceklen; + CMS_EncryptedContentInfo *ec; + enckeylen = rek->encryptedKey->length; + enckey = rek->encryptedKey->data; + /* Setup all parameters to derive KEK */ + if (!cms_env_asn1_ctrl(ri, 1)) + goto err; + /* Attempt to decrypt CEK */ + if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) + goto err; + ec = cms->d.envelopedData->encryptedContentInfo; + if (ec->key) { + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + } + ec->key = cek; + ec->keylen = ceklen; + cek = NULL; + rv = 1; + err: + if (cek) + OPENSSL_free(cek); + return rv; +} + +/* Create ephemeral key and initialise context based on it */ +static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, + EVP_PKEY *pk) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *ekey = NULL; + int rv = 0; + pctx = EVP_PKEY_CTX_new(pk, NULL); + if (!pctx) + goto err; + if (EVP_PKEY_keygen_init(pctx) <= 0) + goto err; + if (EVP_PKEY_keygen(pctx, &ekey) <= 0) + goto err; + EVP_PKEY_CTX_free(pctx); + pctx = EVP_PKEY_CTX_new(ekey, NULL); + if (!pctx) + goto err; + if (EVP_PKEY_derive_init(pctx) <= 0) + goto err; + kari->pctx = pctx; + rv = 1; + err: + if (!rv && pctx) + EVP_PKEY_CTX_free(pctx); + if (ekey) + EVP_PKEY_free(ekey); + return rv; +} + +/* Initialise a ktri based on passed certificate and key */ + +int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, + EVP_PKEY *pk, unsigned int flags) +{ + CMS_KeyAgreeRecipientInfo *kari; + CMS_RecipientEncryptedKey *rek = NULL; + + ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo); + if (!ri->d.kari) + return 0; + ri->type = CMS_RECIPINFO_AGREE; + + kari = ri->d.kari; + kari->version = 3; + + rek = M_ASN1_new_of(CMS_RecipientEncryptedKey); + if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) { + M_ASN1_free_of(rek, CMS_RecipientEncryptedKey); + return 0; + } + + if (flags & CMS_USE_KEYID) { + rek->rid->type = CMS_REK_KEYIDENTIFIER; + rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier); + if (rek->rid->d.rKeyId == NULL) + return 0; + if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) + return 0; + } else { + rek->rid->type = CMS_REK_ISSUER_SERIAL; + if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) + return 0; + } + + /* Create ephemeral key */ + if (!cms_kari_create_ephemeral_key(kari, pk)) + return 0; + + CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); + rek->pkey = pk; + return 1; +} + +static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, + const EVP_CIPHER *cipher) +{ + EVP_CIPHER_CTX *ctx = &kari->ctx; + const EVP_CIPHER *kekcipher; + int keylen = EVP_CIPHER_key_length(cipher); + /* If a suitable wrap algorithm is already set nothing to do */ + kekcipher = EVP_CIPHER_CTX_cipher(ctx); + + if (kekcipher) { + if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE) + return 0; + return 1; + } + /* + * Pick a cipher based on content encryption cipher. If it is DES3 use + * DES3 wrap otherwise use AES wrap similar to key size. + */ +#ifndef OPENSSL_NO_DES + if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) + kekcipher = EVP_des_ede3_wrap(); + else +#endif + if (keylen <= 16) + kekcipher = EVP_aes_128_wrap(); + else if (keylen <= 24) + kekcipher = EVP_aes_192_wrap(); + else + kekcipher = EVP_aes_256_wrap(); + return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); +} + +/* Encrypt content key in key agreement recipient info */ + +int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_KeyAgreeRecipientInfo *kari; + CMS_EncryptedContentInfo *ec; + CMS_RecipientEncryptedKey *rek; + STACK_OF(CMS_RecipientEncryptedKey) *reks; + int i; + + if (ri->type != CMS_RECIPINFO_AGREE) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT); + return 0; + } + kari = ri->d.kari; + reks = kari->recipientEncryptedKeys; + ec = cms->d.envelopedData->encryptedContentInfo; + /* Initialise wrap algorithm parameters */ + if (!cms_wrap_init(kari, ec->cipher)) + return 0; + /* + * If no orignator key set up initialise for ephemeral key the public key + * ASN1 structure will set the actual public key value. + */ + if (kari->originator->type == -1) { + CMS_OriginatorIdentifierOrKey *oik = kari->originator; + oik->type = CMS_OIK_PUBKEY; + oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey); + if (!oik->d.originatorKey) + return 0; + } + /* Initialise KDF algorithm */ + if (!cms_env_asn1_ctrl(ri, 0)) + return 0; + /* For each rek, derive KEK, encrypt CEK */ + for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { + unsigned char *enckey; + size_t enckeylen; + rek = sk_CMS_RecipientEncryptedKey_value(reks, i); + if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0) + return 0; + if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen, + kari, 1)) + return 0; + ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen); + } + + return 1; + +} +/* crypto/cms/cms_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "asn1t.h" +// #include "x509v3.h" +// #include "err.h" +// #include "pem.h" +// #include "bio.h" +#include "asn1.h" +// #include "cms.h" +// #include "cms_lcl.h" + +IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo) +IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +DECLARE_ASN1_ITEM(CMS_CertificateChoices) +DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) +DECLARE_STACK_OF(CMS_CertificateChoices) +DECLARE_STACK_OF(CMS_RevocationInfoChoice) + +const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms) +{ + return cms->contentType; +} + +CMS_ContentInfo *cms_Data_create(void) +{ + CMS_ContentInfo *cms; + cms = CMS_ContentInfo_new(); + if (cms) { + cms->contentType = OBJ_nid2obj(NID_pkcs7_data); + /* Never detached */ + CMS_set_detached(cms, 0); + } + return cms; +} + +BIO *cms_content_bio(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + if (!pos) + return NULL; + /* If content detached data goes nowhere: create NULL BIO */ + if (!*pos) + return BIO_new(BIO_s_null()); + /* + * If content not detached and created return memory BIO + */ + if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) + return BIO_new(BIO_s_mem()); + /* Else content was read in: return read only BIO for it */ + return BIO_new_mem_buf((*pos)->data, (*pos)->length); +} + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) +{ + BIO *cmsbio, *cont; + if (icont) + cont = icont; + else + cont = cms_content_bio(cms); + if (!cont) { + CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT); + return NULL; + } + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_data: + return cont; + + case NID_pkcs7_signed: + cmsbio = cms_SignedData_init_bio(cms); + break; + + case NID_pkcs7_digest: + cmsbio = cms_DigestedData_init_bio(cms); + break; +#ifdef ZLIB + case NID_id_smime_ct_compressedData: + cmsbio = cms_CompressedData_init_bio(cms); + break; +#endif + + case NID_pkcs7_encrypted: + cmsbio = cms_EncryptedData_init_bio(cms); + break; + + case NID_pkcs7_enveloped: + cmsbio = cms_EnvelopedData_init_bio(cms); + break; + + default: + CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); + return NULL; + } + + if (cmsbio) + return BIO_push(cmsbio, cont); + + if (!icont) + BIO_free(cont); + return NULL; + +} + +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) +{ + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + if (!pos) + return 0; + /* If ebmedded content find memory BIO and set content */ + if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { + BIO *mbio; + unsigned char *cont; + long contlen; + mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); + if (!mbio) { + CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); + return 0; + } + contlen = BIO_get_mem_data(mbio, &cont); + /* Set bio as read only so its content can't be clobbered */ + BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); + BIO_set_mem_eof_return(mbio, 0); + ASN1_STRING_set0(*pos, cont, contlen); + (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; + } + + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_data: + case NID_pkcs7_enveloped: + case NID_pkcs7_encrypted: + case NID_id_smime_ct_compressedData: + /* Nothing to do */ + return 1; + + case NID_pkcs7_signed: + return cms_SignedData_final(cms, cmsbio); + + case NID_pkcs7_digest: + return cms_DigestedData_do_final(cms, cmsbio, 0); + + default: + CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); + return 0; + } +} + +/* + * Return an OCTET STRING pointer to content. This allows it to be accessed + * or set later. + */ + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_data: + return &cms->d.data; + + case NID_pkcs7_signed: + return &cms->d.signedData->encapContentInfo->eContent; + + case NID_pkcs7_enveloped: + return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; + + case NID_pkcs7_digest: + return &cms->d.digestedData->encapContentInfo->eContent; + + case NID_pkcs7_encrypted: + return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; + + case NID_id_smime_ct_authData: + return &cms->d.authenticatedData->encapContentInfo->eContent; + + case NID_id_smime_ct_compressedData: + return &cms->d.compressedData->encapContentInfo->eContent; + + default: + if (cms->d.other->type == V_ASN1_OCTET_STRING) + return &cms->d.other->value.octet_string; + CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + + } +} + +/* + * Return an ASN1_OBJECT pointer to content type. This allows it to be + * accessed or set later. + */ + +static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_signed: + return &cms->d.signedData->encapContentInfo->eContentType; + + case NID_pkcs7_enveloped: + return &cms->d.envelopedData->encryptedContentInfo->contentType; + + case NID_pkcs7_digest: + return &cms->d.digestedData->encapContentInfo->eContentType; + + case NID_pkcs7_encrypted: + return &cms->d.encryptedData->encryptedContentInfo->contentType; + + case NID_id_smime_ct_authData: + return &cms->d.authenticatedData->encapContentInfo->eContentType; + + case NID_id_smime_ct_compressedData: + return &cms->d.compressedData->encapContentInfo->eContentType; + + default: + CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + + } +} + +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms) +{ + ASN1_OBJECT **petype; + petype = cms_get0_econtent_type(cms); + if (petype) + return *petype; + return NULL; +} + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) +{ + ASN1_OBJECT **petype, *etype; + petype = cms_get0_econtent_type(cms); + if (!petype) + return 0; + if (!oid) + return 1; + etype = OBJ_dup(oid); + if (!etype) + return 0; + ASN1_OBJECT_free(*petype); + *petype = etype; + return 1; +} + +int CMS_is_detached(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); + if (!pos) + return -1; + if (*pos) + return 0; + return 1; +} + +int CMS_set_detached(CMS_ContentInfo *cms, int detached) +{ + ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); + if (!pos) + return 0; + if (detached) { + if (*pos) { + ASN1_OCTET_STRING_free(*pos); + *pos = NULL; + } + return 1; + } + if (!*pos) + *pos = ASN1_OCTET_STRING_new(); + if (*pos) { + /* + * NB: special flag to show content is created and not read in. + */ + (*pos)->flags |= ASN1_STRING_FLAG_CONT; + return 1; + } + CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE); + return 0; +} + +/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ + +void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) +{ + int param_type; + + if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) + param_type = V_ASN1_UNDEF; + else + param_type = V_ASN1_NULL; + + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); + +} + +/* Create a digest BIO from an X509_ALGOR structure */ + +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) +{ + BIO *mdbio = NULL; + ASN1_OBJECT *digestoid; + const EVP_MD *digest; + X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); + digest = EVP_get_digestbyobj(digestoid); + if (!digest) { + CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, + CMS_R_UNKNOWN_DIGEST_ALGORIHM); + goto err; + } + mdbio = BIO_new(BIO_f_md()); + if (!mdbio || !BIO_set_md(mdbio, digest)) { + CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR); + goto err; + } + return mdbio; + err: + if (mdbio) + BIO_free(mdbio); + return NULL; +} + +/* Locate a message digest content from a BIO chain based on SignerInfo */ + +int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, + X509_ALGOR *mdalg) +{ + int nid; + ASN1_OBJECT *mdoid; + X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); + nid = OBJ_obj2nid(mdoid); + /* Look for digest type to match signature */ + for (;;) { + EVP_MD_CTX *mtmp; + chain = BIO_find_type(chain, BIO_TYPE_MD); + if (chain == NULL) { + CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, + CMS_R_NO_MATCHING_DIGEST); + return 0; + } + BIO_get_md_ctx(chain, &mtmp); + if (EVP_MD_CTX_type(mtmp) == nid + /* + * Workaround for broken implementations that use signature + * algorithm OID instead of digest. + */ + || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) + return EVP_MD_CTX_copy_ex(mctx, mtmp); + chain = BIO_next(chain); + } +} + +static STACK_OF(CMS_CertificateChoices) +**cms_get0_certificate_choices(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_signed: + return &cms->d.signedData->certificates; + + case NID_pkcs7_enveloped: + if (cms->d.envelopedData->originatorInfo == NULL) + return NULL; + return &cms->d.envelopedData->originatorInfo->certificates; + + default: + CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, + CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + + } +} + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) +{ + STACK_OF(CMS_CertificateChoices) **pcerts; + CMS_CertificateChoices *cch; + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return NULL; + if (!*pcerts) + *pcerts = sk_CMS_CertificateChoices_new_null(); + if (!*pcerts) + return NULL; + cch = M_ASN1_new_of(CMS_CertificateChoices); + if (!cch) + return NULL; + if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) { + M_ASN1_free_of(cch, CMS_CertificateChoices); + return NULL; + } + return cch; +} + +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) +{ + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) **pcerts; + int i; + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return 0; + for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { + cch = sk_CMS_CertificateChoices_value(*pcerts, i); + if (cch->type == CMS_CERTCHOICE_CERT) { + if (!X509_cmp(cch->d.certificate, cert)) { + CMSerr(CMS_F_CMS_ADD0_CERT, + CMS_R_CERTIFICATE_ALREADY_PRESENT); + return 0; + } + } + } + cch = CMS_add0_CertificateChoices(cms); + if (!cch) + return 0; + cch->type = CMS_CERTCHOICE_CERT; + cch->d.certificate = cert; + return 1; +} + +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) +{ + int r; + r = CMS_add0_cert(cms, cert); + if (r > 0) + CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); + return r; +} + +static STACK_OF(CMS_RevocationInfoChoice) +**cms_get0_revocation_choices(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_signed: + return &cms->d.signedData->crls; + + case NID_pkcs7_enveloped: + if (cms->d.envelopedData->originatorInfo == NULL) + return NULL; + return &cms->d.envelopedData->originatorInfo->crls; + + default: + CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, + CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + + } +} + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) +{ + STACK_OF(CMS_RevocationInfoChoice) **pcrls; + CMS_RevocationInfoChoice *rch; + pcrls = cms_get0_revocation_choices(cms); + if (!pcrls) + return NULL; + if (!*pcrls) + *pcrls = sk_CMS_RevocationInfoChoice_new_null(); + if (!*pcrls) + return NULL; + rch = M_ASN1_new_of(CMS_RevocationInfoChoice); + if (!rch) + return NULL; + if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { + M_ASN1_free_of(rch, CMS_RevocationInfoChoice); + return NULL; + } + return rch; +} + +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) +{ + CMS_RevocationInfoChoice *rch; + rch = CMS_add0_RevocationInfoChoice(cms); + if (!rch) + return 0; + rch->type = CMS_REVCHOICE_CRL; + rch->d.crl = crl; + return 1; +} + +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) +{ + int r; + r = CMS_add0_crl(cms, crl); + if (r > 0) + CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); + return r; +} + +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) +{ + STACK_OF(X509) *certs = NULL; + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) **pcerts; + int i; + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return NULL; + for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { + cch = sk_CMS_CertificateChoices_value(*pcerts, i); + if (cch->type == 0) { + if (!certs) { + certs = sk_X509_new_null(); + if (!certs) + return NULL; + } + if (!sk_X509_push(certs, cch->d.certificate)) { + sk_X509_pop_free(certs, X509_free); + return NULL; + } + CRYPTO_add(&cch->d.certificate->references, 1, CRYPTO_LOCK_X509); + } + } + return certs; + +} + +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) +{ + STACK_OF(X509_CRL) *crls = NULL; + STACK_OF(CMS_RevocationInfoChoice) **pcrls; + CMS_RevocationInfoChoice *rch; + int i; + pcrls = cms_get0_revocation_choices(cms); + if (!pcrls) + return NULL; + for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { + rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); + if (rch->type == 0) { + if (!crls) { + crls = sk_X509_CRL_new_null(); + if (!crls) + return NULL; + } + if (!sk_X509_CRL_push(crls, rch->d.crl)) { + sk_X509_CRL_pop_free(crls, X509_CRL_free); + return NULL; + } + CRYPTO_add(&rch->d.crl->references, 1, CRYPTO_LOCK_X509_CRL); + } + } + return crls; +} + +int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) +{ + int ret; + ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert)); + if (ret) + return ret; + return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert)); +} + +int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) +{ + X509_check_purpose(cert, -1, -1); + if (!cert->skid) + return -1; + return ASN1_OCTET_STRING_cmp(keyid, cert->skid); +} + +int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) +{ + CMS_IssuerAndSerialNumber *ias; + ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber); + if (!ias) + goto err; + if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) + goto err; + if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert))) + goto err; + if (*pias) + M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber); + *pias = ias; + return 1; + err: + if (ias) + M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber); + CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE); + return 0; +} + +int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) +{ + ASN1_OCTET_STRING *keyid = NULL; + X509_check_purpose(cert, -1, -1); + if (!cert->skid) { + CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID); + return 0; + } + keyid = ASN1_STRING_dup(cert->skid); + if (!keyid) { + CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE); + return 0; + } + if (*pkeyid) + ASN1_OCTET_STRING_free(*pkeyid); + *pkeyid = keyid; + return 1; +} +/* crypto/cms/cms_pwri.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2009 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "pem.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +// #include "rand.h" +// #include "aes.h" +// #include "cms_lcl.h" +// #include "asn1_locl.h" + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, ossl_ssize_t passlen) +{ + CMS_PasswordRecipientInfo *pwri; + if (ri->type != CMS_RECIPINFO_PASS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); + return 0; + } + + pwri = ri->d.pwri; + pwri->pass = pass; + if (pass && passlen < 0) + passlen = strlen((char *)pass); + pwri->passlen = passlen; + return 1; +} + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + CMS_PasswordRecipientInfo *pwri; + EVP_CIPHER_CTX ctx; + X509_ALGOR *encalg = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + int ivlen; + + env = cms_get0_enveloped(cms); + if (!env) + return NULL; + + if (wrap_nid <= 0) + wrap_nid = NID_id_alg_PWRI_KEK; + + if (pbe_nid <= 0) + pbe_nid = NID_id_pbkdf2; + + /* Get from enveloped data */ + if (kekciph == NULL) + kekciph = env->encryptedContentInfo->cipher; + + if (kekciph == NULL) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); + return NULL; + } + if (wrap_nid != NID_id_alg_PWRI_KEK) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, + CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); + return NULL; + } + + /* Setup algorithm identifier for cipher */ + encalg = X509_ALGOR_new(); + if (encalg == NULL) { + goto merr; + } + EVP_CIPHER_CTX_init(&ctx); + + if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); + goto err; + } + + ivlen = EVP_CIPHER_CTX_iv_length(&ctx); + + if (ivlen > 0) { + if (RAND_bytes(iv, ivlen) <= 0) + goto err; + if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); + goto err; + } + encalg->parameter = ASN1_TYPE_new(); + if (!encalg->parameter) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + } + + encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx)); + + EVP_CIPHER_CTX_cleanup(&ctx); + + /* Initialize recipient info */ + ri = M_ASN1_new_of(CMS_RecipientInfo); + if (!ri) + goto merr; + + ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo); + if (!ri->d.pwri) + goto merr; + ri->type = CMS_RECIPINFO_PASS; + + pwri = ri->d.pwri; + /* Since this is overwritten, free up empty structure already there */ + X509_ALGOR_free(pwri->keyEncryptionAlgorithm); + pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); + if (!pwri->keyEncryptionAlgorithm) + goto merr; + pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); + pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); + if (!pwri->keyEncryptionAlgorithm->parameter) + goto merr; + + if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), + &pwri->keyEncryptionAlgorithm->parameter-> + value.sequence)) + goto merr; + pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; + + X509_ALGOR_free(encalg); + encalg = NULL; + + /* Setup PBE algorithm */ + + pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); + + if (!pwri->keyDerivationAlgorithm) + goto err; + + CMS_RecipientInfo_set0_password(ri, pass, passlen); + pwri->version = 0; + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + return ri; + + merr: + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ri) + M_ASN1_free_of(ri, CMS_RecipientInfo); + if (encalg) + X509_ALGOR_free(encalg); + return NULL; + +} + +/* + * This is an implementation of the key wrapping mechanism in RFC3211, at + * some point this should go into EVP. + */ + +static int kek_unwrap_key(unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen, + EVP_CIPHER_CTX *ctx) +{ + size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); + unsigned char *tmp; + int outl, rv = 0; + if (inlen < 2 * blocklen) { + /* too small */ + return 0; + } + if (inlen % blocklen) { + /* Invalid size */ + return 0; + } + tmp = OPENSSL_malloc(inlen); + if (!tmp) + return 0; + /* setup IV by decrypting last two blocks */ + EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, + in + inlen - 2 * blocklen, blocklen * 2); + /* + * Do a decrypt of last decrypted block to set IV to correct value output + * it to start of buffer so we don't corrupt decrypted block this works + * because buffer is at least two block lengths long. + */ + EVP_DecryptUpdate(ctx, tmp, &outl, tmp + inlen - blocklen, blocklen); + /* Can now decrypt first n - 1 blocks */ + EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen); + + /* Reset IV to original value */ + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); + /* Decrypt again */ + EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen); + /* Check check bytes */ + if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) { + /* Check byte failure */ + goto err; + } + if (inlen < (size_t)(tmp[0] - 4)) { + /* Invalid length value */ + goto err; + } + *outlen = (size_t)tmp[0]; + memcpy(out, tmp + 4, *outlen); + rv = 1; + err: + OPENSSL_cleanse(tmp, inlen); + OPENSSL_free(tmp); + return rv; + +} + +static int kek_wrap_key(unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen, + EVP_CIPHER_CTX *ctx) +{ + size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); + size_t olen; + int dummy; + /* + * First decide length of output buffer: need header and round up to + * multiple of block length. + */ + olen = (inlen + 4 + blocklen - 1) / blocklen; + olen *= blocklen; + if (olen < 2 * blocklen) { + /* Key too small */ + return 0; + } + if (inlen > 0xFF) { + /* Key too large */ + return 0; + } + if (out) { + /* Set header */ + out[0] = (unsigned char)inlen; + out[1] = in[0] ^ 0xFF; + out[2] = in[1] ^ 0xFF; + out[3] = in[2] ^ 0xFF; + memcpy(out + 4, in, inlen); + /* Add random padding to end */ + if (olen > inlen + 4 + && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) + return 0; + /* Encrypt twice */ + EVP_EncryptUpdate(ctx, out, &dummy, out, olen); + EVP_EncryptUpdate(ctx, out, &dummy, out, olen); + } + + *outlen = olen; + + return 1; +} + +/* Encrypt/Decrypt content key in PWRI recipient info */ + +int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + int en_de) +{ + CMS_EncryptedContentInfo *ec; + CMS_PasswordRecipientInfo *pwri; + const unsigned char *p = NULL; + int plen; + int r = 0; + X509_ALGOR *algtmp, *kekalg = NULL; + EVP_CIPHER_CTX kekctx; + const EVP_CIPHER *kekcipher; + unsigned char *key = NULL; + size_t keylen; + + ec = cms->d.envelopedData->encryptedContentInfo; + + pwri = ri->d.pwri; + EVP_CIPHER_CTX_init(&kekctx); + + if (!pwri->pass) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); + return 0; + } + algtmp = pwri->keyEncryptionAlgorithm; + + if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, + CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); + return 0; + } + + if (algtmp->parameter->type == V_ASN1_SEQUENCE) { + p = algtmp->parameter->value.sequence->data; + plen = algtmp->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + } + if (kekalg == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, + CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); + return 0; + } + + kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + + if (!kekcipher) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); + goto err; + } + + /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ + if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de)) + goto err; + EVP_CIPHER_CTX_set_padding(&kekctx, 0); + if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + + algtmp = pwri->keyDerivationAlgorithm; + + /* Finish password based key derivation to setup key in "ctx" */ + + if (EVP_PBE_CipherInit(algtmp->algorithm, + (char *)pwri->pass, pwri->passlen, + algtmp->parameter, &kekctx, en_de) < 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); + goto err; + } + + /* Finally wrap/unwrap the key */ + + if (en_de) { + + if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx)) + goto err; + + key = OPENSSL_malloc(keylen); + + if (!key) + goto err; + + if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx)) + goto err; + pwri->encryptedKey->data = key; + pwri->encryptedKey->length = keylen; + } else { + key = OPENSSL_malloc(pwri->encryptedKey->length); + + if (!key) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!kek_unwrap_key(key, &keylen, + pwri->encryptedKey->data, + pwri->encryptedKey->length, &kekctx)) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); + goto err; + } + + ec->key = key; + ec->keylen = keylen; + + } + + r = 1; + + err: + + EVP_CIPHER_CTX_cleanup(&kekctx); + + if (!r && key) + OPENSSL_free(key); + X509_ALGOR_free(kekalg); + + return r; + +} +/* crypto/cms/cms_sd.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "pem.h" +// #include "x509.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +// #include "cms_lcl.h" +// #include "asn1_locl.h" + +/* CMS SignedData Utilities */ + +DECLARE_ASN1_ITEM(CMS_SignedData) + +static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms) +{ + if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { + CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); + return NULL; + } + return cms->d.signedData; +} + +static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) +{ + if (cms->d.other == NULL) { + cms->d.signedData = M_ASN1_new_of(CMS_SignedData); + if (!cms->d.signedData) { + CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); + return NULL; + } + cms->d.signedData->version = 1; + cms->d.signedData->encapContentInfo->eContentType = + OBJ_nid2obj(NID_pkcs7_data); + cms->d.signedData->encapContentInfo->partial = 1; + ASN1_OBJECT_free(cms->contentType); + cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); + return cms->d.signedData; + } + return cms_get0_signed(cms); +} + +/* Just initialize SignedData e.g. for certs only structure */ + +int CMS_SignedData_init(CMS_ContentInfo *cms) +{ + if (cms_signed_data_init(cms)) + return 1; + else + return 0; +} + +/* Check structures and fixup version numbers (if necessary) */ + +static void cms_sd_set_version(CMS_SignedData *sd) +{ + int i; + CMS_CertificateChoices *cch; + CMS_RevocationInfoChoice *rch; + CMS_SignerInfo *si; + + for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) { + cch = sk_CMS_CertificateChoices_value(sd->certificates, i); + if (cch->type == CMS_CERTCHOICE_OTHER) { + if (sd->version < 5) + sd->version = 5; + } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { + if (sd->version < 4) + sd->version = 4; + } else if (cch->type == CMS_CERTCHOICE_V1ACERT) { + if (sd->version < 3) + sd->version = 3; + } + } + + for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) { + rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); + if (rch->type == CMS_REVCHOICE_OTHER) { + if (sd->version < 5) + sd->version = 5; + } + } + + if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) + && (sd->version < 3)) + sd->version = 3; + + for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { + si = sk_CMS_SignerInfo_value(sd->signerInfos, i); + if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { + if (si->version < 3) + si->version = 3; + if (sd->version < 3) + sd->version = 3; + } else if (si->version < 1) + si->version = 1; + } + + if (sd->version < 1) + sd->version = 1; + +} + +/* Copy an existing messageDigest value */ + +static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) +{ + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *sitmp; + int i; + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + ASN1_OCTET_STRING *messageDigest; + sitmp = sk_CMS_SignerInfo_value(sinfos, i); + if (sitmp == si) + continue; + if (CMS_signed_get_attr_count(sitmp) < 0) + continue; + if (OBJ_cmp(si->digestAlgorithm->algorithm, + sitmp->digestAlgorithm->algorithm)) + continue; + messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, + OBJ_nid2obj + (NID_pkcs9_messageDigest), + -3, V_ASN1_OCTET_STRING); + if (!messageDigest) { + CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, + CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); + return 0; + } + + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, + messageDigest, -1)) + return 1; + else + return 0; + } + CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST); + return 0; +} + +int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) +{ + switch (type) { + case CMS_SIGNERINFO_ISSUER_SERIAL: + if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert)) + return 0; + break; + + case CMS_SIGNERINFO_KEYIDENTIFIER: + if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert)) + return 0; + break; + + default: + CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); + return 0; + } + + sid->type = type; + + return 1; +} + +int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno) +{ + if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { + if (issuer) + *issuer = sid->d.issuerAndSerialNumber->issuer; + if (sno) + *sno = sid->d.issuerAndSerialNumber->serialNumber; + } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { + if (keyid) + *keyid = sid->d.subjectKeyIdentifier; + } else + return 0; + return 1; +} + +int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) +{ + if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) + return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert); + else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) + return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert); + else + return -1; +} + +static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd) +{ + EVP_PKEY *pkey = si->pkey; + int i; + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return 1; + i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si); + if (i == -2) { + CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; + } + if (i <= 0) { + CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE); + return 0; + } + return 1; +} + +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags) +{ + CMS_SignedData *sd; + CMS_SignerInfo *si = NULL; + X509_ALGOR *alg; + int i, type; + if (!X509_check_private_key(signer, pk)) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, + CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return NULL; + } + sd = cms_signed_data_init(cms); + if (!sd) + goto err; + si = M_ASN1_new_of(CMS_SignerInfo); + if (!si) + goto merr; + X509_check_purpose(signer, -1, -1); + + CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); + CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); + + si->pkey = pk; + si->signer = signer; + EVP_MD_CTX_init(&si->mctx); + si->pctx = NULL; + + if (flags & CMS_USE_KEYID) { + si->version = 3; + if (sd->version < 3) + sd->version = 3; + type = CMS_SIGNERINFO_KEYIDENTIFIER; + } else { + type = CMS_SIGNERINFO_ISSUER_SERIAL; + si->version = 1; + } + + if (!cms_set1_SignerIdentifier(si->sid, signer, type)) + goto err; + + if (md == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) + goto err; + md = EVP_get_digestbynid(def_nid); + if (md == NULL) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); + goto err; + } + } + + if (!md) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); + goto err; + } + + cms_DigestAlgorithm_set(si->digestAlgorithm, md); + + /* See if digest is present in digestAlgorithms */ + for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { + ASN1_OBJECT *aoid; + alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); + X509_ALGOR_get0(&aoid, NULL, NULL, alg); + if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) + break; + } + + if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { + alg = X509_ALGOR_new(); + if (!alg) + goto merr; + cms_DigestAlgorithm_set(alg, md); + if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { + X509_ALGOR_free(alg); + goto merr; + } + } + + if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) + goto err; + if (!(flags & CMS_NOATTR)) { + /* + * Initialialize signed attributes strutucture so other attributes + * such as signing time etc are added later even if we add none here. + */ + if (!si->signedAttrs) { + si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); + if (!si->signedAttrs) + goto merr; + } + + if (!(flags & CMS_NOSMIMECAP)) { + STACK_OF(X509_ALGOR) *smcap = NULL; + i = CMS_add_standard_smimecap(&smcap); + if (i) + i = CMS_add_smimecap(si, smcap); + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + if (!i) + goto merr; + } + if (flags & CMS_REUSE_DIGEST) { + if (!cms_copy_messageDigest(cms, si)) + goto err; + if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && + !CMS_SignerInfo_sign(si)) + goto err; + } + } + + if (!(flags & CMS_NOCERTS)) { + /* NB ignore -1 return for duplicate cert */ + if (!CMS_add1_cert(cms, signer)) + goto merr; + } + + if (flags & CMS_KEY_PARAM) { + if (flags & CMS_NOATTR) { + si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); + if (!si->pctx) + goto err; + if (EVP_PKEY_sign_init(si->pctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) + goto err; + } else if (EVP_DigestSignInit(&si->mctx, &si->pctx, md, NULL, pk) <= + 0) + goto err; + } + + if (!sd->signerInfos) + sd->signerInfos = sk_CMS_SignerInfo_new_null(); + if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) + goto merr; + + return si; + + merr: + CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); + err: + if (si) + M_ASN1_free_of(si, CMS_SignerInfo); + return NULL; + +} + +static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) +{ + ASN1_TIME *tt; + int r = 0; + if (t) + tt = t; + else + tt = X509_gmtime_adj(NULL, 0); + + if (!tt) + goto merr; + + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, + tt->type, tt, -1) <= 0) + goto merr; + + r = 1; + + merr: + + if (!t) + ASN1_TIME_free(tt); + + if (!r) + CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE); + + return r; + +} + +EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si) +{ + return si->pctx; +} + +EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si) +{ + return &si->mctx; +} + +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) +{ + CMS_SignedData *sd; + sd = cms_get0_signed(cms); + if (!sd) + return NULL; + return sd->signerInfos; +} + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) +{ + STACK_OF(X509) *signers = NULL; + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *si; + int i; + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (si->signer) { + if (!signers) { + signers = sk_X509_new_null(); + if (!signers) + return NULL; + } + if (!sk_X509_push(signers, si->signer)) { + sk_X509_free(signers); + return NULL; + } + } + } + return signers; +} + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) +{ + if (signer) { + CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); + if (si->pkey) + EVP_PKEY_free(si->pkey); + si->pkey = X509_get_pubkey(signer); + } + if (si->signer) + X509_free(si->signer); + si->signer = signer; +} + +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno) +{ + return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); +} + +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) +{ + return cms_SignerIdentifier_cert_cmp(si->sid, cert); +} + +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, + unsigned int flags) +{ + CMS_SignedData *sd; + CMS_SignerInfo *si; + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) *certs; + X509 *x; + int i, j; + int ret = 0; + sd = cms_get0_signed(cms); + if (!sd) + return -1; + certs = sd->certificates; + for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { + si = sk_CMS_SignerInfo_value(sd->signerInfos, i); + if (si->signer) + continue; + + for (j = 0; j < sk_X509_num(scerts); j++) { + x = sk_X509_value(scerts, j); + if (CMS_SignerInfo_cert_cmp(si, x) == 0) { + CMS_SignerInfo_set1_signer_cert(si, x); + ret++; + break; + } + } + + if (si->signer || (flags & CMS_NOINTERN)) + continue; + + for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { + cch = sk_CMS_CertificateChoices_value(certs, j); + if (cch->type != 0) + continue; + x = cch->d.certificate; + if (CMS_SignerInfo_cert_cmp(si, x) == 0) { + CMS_SignerInfo_set1_signer_cert(si, x); + ret++; + break; + } + } + } + return ret; +} + +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig) +{ + if (pk) + *pk = si->pkey; + if (signer) + *signer = si->signer; + if (pdig) + *pdig = si->digestAlgorithm; + if (psig) + *psig = si->signatureAlgorithm; +} + +ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si) +{ + return si->signature; +} + +static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, + CMS_SignerInfo *si, BIO *chain) +{ + EVP_MD_CTX mctx; + int r = 0; + EVP_PKEY_CTX *pctx = NULL; + EVP_MD_CTX_init(&mctx); + + if (!si->pkey) { + CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); + return 0; + } + + if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) + goto err; + /* Set SignerInfo algortihm details if we used custom parametsr */ + if (si->pctx && !cms_sd_asn1_ctrl(si, 0)) + goto err; + + /* + * If any signed attributes calculate and add messageDigest attribute + */ + + if (CMS_signed_get_attr_count(si) >= 0) { + ASN1_OBJECT *ctype = + cms->d.signedData->encapContentInfo->eContentType; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + if (!EVP_DigestFinal_ex(&mctx, md, &mdlen)) + goto err; + if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, md, mdlen)) + goto err; + /* Copy content type across */ + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, ctype, -1) <= 0) + goto err; + if (!CMS_SignerInfo_sign(si)) + goto err; + } else if (si->pctx) { + unsigned char *sig; + size_t siglen; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + pctx = si->pctx; + if (!EVP_DigestFinal_ex(&mctx, md, &mdlen)) + goto err; + siglen = EVP_PKEY_size(si->pkey); + sig = OPENSSL_malloc(siglen); + if (!sig) { + CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) + goto err; + ASN1_STRING_set0(si->signature, sig, siglen); + } else { + unsigned char *sig; + unsigned int siglen; + sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); + if (!sig) { + CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) { + CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR); + OPENSSL_free(sig); + goto err; + } + ASN1_STRING_set0(si->signature, sig, siglen); + } + + r = 1; + + err: + EVP_MD_CTX_cleanup(&mctx); + if (pctx) + EVP_PKEY_CTX_free(pctx); + return r; + +} + +int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) +{ + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *si; + int i; + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (!cms_SignerInfo_content_sign(cms, si, chain)) + return 0; + } + cms->d.signedData->encapContentInfo->partial = 0; + return 1; +} + +int CMS_SignerInfo_sign(CMS_SignerInfo *si) +{ + EVP_MD_CTX *mctx = &si->mctx; + EVP_PKEY_CTX *pctx; + unsigned char *abuf = NULL; + int alen; + size_t siglen; + const EVP_MD *md = NULL; + + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) + return 0; + + if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { + if (!cms_add1_signingTime(si, NULL)) + goto err; + } + + if (si->pctx) + pctx = si->pctx; + else { + EVP_MD_CTX_init(mctx); + if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) + goto err; + } + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { + CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); + goto err; + } + + alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, + ASN1_ITEM_rptr(CMS_Attributes_Sign)); + if (!abuf) + goto err; + if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0) + goto err; + if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0) + goto err; + OPENSSL_free(abuf); + abuf = OPENSSL_malloc(siglen); + if (!abuf) + goto err; + if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { + CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); + goto err; + } + + EVP_MD_CTX_cleanup(mctx); + + ASN1_STRING_set0(si->signature, abuf, siglen); + + return 1; + + err: + if (abuf) + OPENSSL_free(abuf); + EVP_MD_CTX_cleanup(mctx); + return 0; + +} + +int CMS_SignerInfo_verify(CMS_SignerInfo *si) +{ + EVP_MD_CTX *mctx = &si->mctx; + unsigned char *abuf = NULL; + int alen, r = -1; + const EVP_MD *md = NULL; + + if (!si->pkey) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); + return -1; + } + + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) + return -1; + EVP_MD_CTX_init(mctx); + if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0) + goto err; + + if (!cms_sd_asn1_ctrl(si, 1)) + goto err; + + alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, + ASN1_ITEM_rptr(CMS_Attributes_Verify)); + if (!abuf) + goto err; + r = EVP_DigestVerifyUpdate(mctx, abuf, alen); + OPENSSL_free(abuf); + if (r <= 0) { + r = -1; + goto err; + } + r = EVP_DigestVerifyFinal(mctx, + si->signature->data, si->signature->length); + if (r <= 0) + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); + err: + EVP_MD_CTX_cleanup(mctx); + return r; +} + +/* Create a chain of digest BIOs from a CMS ContentInfo */ + +BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) +{ + int i; + CMS_SignedData *sd; + BIO *chain = NULL; + sd = cms_get0_signed(cms); + if (!sd) + return NULL; + if (cms->d.signedData->encapContentInfo->partial) + cms_sd_set_version(sd); + for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { + X509_ALGOR *digestAlgorithm; + BIO *mdbio; + digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); + mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); + if (!mdbio) + goto err; + if (chain) + BIO_push(chain, mdbio); + else + chain = mdbio; + } + return chain; + err: + if (chain) + BIO_free_all(chain); + return NULL; +} + +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) +{ + ASN1_OCTET_STRING *os = NULL; + EVP_MD_CTX mctx; + EVP_PKEY_CTX *pkctx = NULL; + int r = -1; + unsigned char mval[EVP_MAX_MD_SIZE]; + unsigned int mlen; + EVP_MD_CTX_init(&mctx); + /* If we have any signed attributes look for messageDigest value */ + if (CMS_signed_get_attr_count(si) >= 0) { + os = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj(NID_pkcs9_messageDigest), + -3, V_ASN1_OCTET_STRING); + if (!os) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); + goto err; + } + } + + if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) + goto err; + + if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_UNABLE_TO_FINALIZE_CONTEXT); + goto err; + } + + /* If messageDigest found compare it */ + + if (os) { + if (mlen != (unsigned int)os->length) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); + goto err; + } + + if (memcmp(mval, os->data, mlen)) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_VERIFICATION_FAILURE); + r = 0; + } else + r = 1; + } else { + const EVP_MD *md = EVP_MD_CTX_md(&mctx); + pkctx = EVP_PKEY_CTX_new(si->pkey, NULL); + if (pkctx == NULL) + goto err; + if (EVP_PKEY_verify_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0) + goto err; + si->pctx = pkctx; + if (!cms_sd_asn1_ctrl(si, 1)) + goto err; + r = EVP_PKEY_verify(pkctx, si->signature->data, + si->signature->length, mval, mlen); + if (r <= 0) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_VERIFICATION_FAILURE); + r = 0; + } + } + + err: + if (pkctx) + EVP_PKEY_CTX_free(pkctx); + EVP_MD_CTX_cleanup(&mctx); + return r; + +} + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) +{ + unsigned char *smder = NULL; + int smderlen, r; + smderlen = i2d_X509_ALGORS(algs, &smder); + if (smderlen <= 0) + return 0; + r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, + V_ASN1_SEQUENCE, smder, smderlen); + OPENSSL_free(smder); + return r; +} + +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize) +{ + X509_ALGOR *alg; + ASN1_INTEGER *key = NULL; + if (keysize > 0) { + key = ASN1_INTEGER_new(); + if (!key || !ASN1_INTEGER_set(key, keysize)) + return 0; + } + alg = X509_ALGOR_new(); + if (!alg) { + if (key) + ASN1_INTEGER_free(key); + return 0; + } + + X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), + key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); + if (!*algs) + *algs = sk_X509_ALGOR_new_null(); + if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) { + X509_ALGOR_free(alg); + return 0; + } + return 1; +} + +/* Check to see if a cipher exists and if so add S/MIME capabilities */ + +static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) +{ + if (EVP_get_cipherbynid(nid)) + return CMS_add_simple_smimecap(sk, nid, arg); + return 1; +} + +static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) +{ + if (EVP_get_digestbynid(nid)) + return CMS_add_simple_smimecap(sk, nid, arg); + return 1; +} + +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) +{ + if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) + || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) + || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) + || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) + || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) + || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) + || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) + || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) + || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) + || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) + return 0; + return 1; +} +/* crypto/cms/cms_smime.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" +// #include "x509v3.h" +// #include "err.h" +// #include "cms.h" +// #include "cms_lcl.h" +// #include "asn1_locl.h" + +static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) +{ + unsigned char buf[4096]; + int r = 0, i; + BIO *tmpout = NULL; + + if (out == NULL) + tmpout = BIO_new(BIO_s_null()); + else if (flags & CMS_TEXT) { + tmpout = BIO_new(BIO_s_mem()); + BIO_set_mem_eof_return(tmpout, 0); + } else + tmpout = out; + + if (!tmpout) { + CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Read all content through chain to process digest, decrypt etc */ + for (;;) { + i = BIO_read(in, buf, sizeof(buf)); + if (i <= 0) { + if (BIO_method_type(in) == BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(in)) + goto err; + } + if (i < 0) + goto err; + break; + } + + if (tmpout && (BIO_write(tmpout, buf, i) != i)) + goto err; + } + + if (flags & CMS_TEXT) { + if (!SMIME_text(tmpout, out)) { + CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR); + goto err; + } + } + + r = 1; + + err: + if (tmpout && (tmpout != out)) + BIO_free(tmpout); + return r; + +} + +static int check_content(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + if (!pos || !*pos) { + CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); + return 0; + } + return 1; +} + +static void do_free_upto(BIO *f, BIO *upto) +{ + if (upto) { + BIO *tbio; + do { + tbio = BIO_pop(f); + BIO_free(f); + f = tbio; + } + while (f && f != upto); + } else + BIO_free_all(f); +} + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) +{ + BIO *cont; + int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { + CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); + return 0; + } + cont = CMS_dataInit(cms, NULL); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + BIO_free_all(cont); + return r; +} + +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) +{ + CMS_ContentInfo *cms; + cms = cms_Data_create(); + if (!cms) + return NULL; + + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + + return NULL; +} + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags) +{ + BIO *cont; + int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { + CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); + return 0; + } + + if (!dcont && !check_content(cms)) + return 0; + + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + if (r) + r = cms_DigestedData_do_final(cms, cont, 1); + do_free_upto(cont, dcont); + return r; +} + +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags) +{ + CMS_ContentInfo *cms; + if (!md) + md = EVP_sha1(); + cms = cms_DigestedData_create(md); + if (!cms) + return NULL; + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + return NULL; +} + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags) +{ + BIO *cont; + int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, + CMS_R_TYPE_NOT_ENCRYPTED_DATA); + return 0; + } + + if (!dcont && !check_content(cms)) + return 0; + + if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) + return 0; + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + do_free_upto(cont, dcont); + return r; +} + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags) +{ + CMS_ContentInfo *cms; + if (!cipher) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); + return NULL; + } + cms = CMS_ContentInfo_new(); + if (!cms) + return NULL; + if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) + return NULL; + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) + || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + return NULL; +} + +static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, + X509_STORE *store, + STACK_OF(X509) *certs, + STACK_OF(X509_CRL) *crls, + unsigned int flags) +{ + X509_STORE_CTX ctx; + X509 *signer; + int i, j, r = 0; + CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); + if (!X509_STORE_CTX_init(&ctx, store, signer, certs)) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR); + goto err; + } + X509_STORE_CTX_set_default(&ctx, "smime_sign"); + if (crls) + X509_STORE_CTX_set0_crls(&ctx, crls); + + i = X509_verify_cert(&ctx); + if (i <= 0) { + j = X509_STORE_CTX_get_error(&ctx); + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, + CMS_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(j)); + goto err; + } + r = 1; + err: + X509_STORE_CTX_cleanup(&ctx); + return r; + +} + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags) +{ + CMS_SignerInfo *si; + STACK_OF(CMS_SignerInfo) *sinfos; + STACK_OF(X509) *cms_certs = NULL; + STACK_OF(X509_CRL) *crls = NULL; + X509 *signer; + int i, scount = 0, ret = 0; + BIO *cmsbio = NULL, *tmpin = NULL; + + if (!dcont && !check_content(cms)) + return 0; + + /* Attempt to find all signer certificates */ + + sinfos = CMS_get0_SignerInfos(cms); + + if (sk_CMS_SignerInfo_num(sinfos) <= 0) { + CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS); + goto err; + } + + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); + if (signer) + scount++; + } + + if (scount != sk_CMS_SignerInfo_num(sinfos)) + scount += CMS_set1_signers_certs(cms, certs, flags); + + if (scount != sk_CMS_SignerInfo_num(sinfos)) { + CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); + goto err; + } + + /* Attempt to verify all signers certs */ + + if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { + cms_certs = CMS_get1_certs(cms); + if (!(flags & CMS_NOCRL)) + crls = CMS_get1_crls(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (!cms_signerinfo_verify_cert(si, store, + cms_certs, crls, flags)) + goto err; + } + } + + /* Attempt to verify all SignerInfo signed attribute signatures */ + + if (!(flags & CMS_NO_ATTR_VERIFY)) { + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (CMS_signed_get_attr_count(si) < 0) + continue; + if (CMS_SignerInfo_verify(si) <= 0) + goto err; + } + } + + /* + * Performance optimization: if the content is a memory BIO then store + * its contents in a temporary read only memory BIO. This avoids + * potentially large numbers of slow copies of data which will occur when + * reading from a read write memory BIO when signatures are calculated. + */ + + if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { + char *ptr; + long len; + len = BIO_get_mem_data(dcont, &ptr); + tmpin = BIO_new_mem_buf(ptr, len); + if (tmpin == NULL) { + CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); + goto err2; + } + } else + tmpin = dcont; + + cmsbio = CMS_dataInit(cms, tmpin); + if (!cmsbio) + goto err; + + if (!cms_copy_content(out, cmsbio, flags)) + goto err; + + if (!(flags & CMS_NO_CONTENT_VERIFY)) { + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { + CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR); + goto err; + } + } + } + + ret = 1; + + err: + + if (dcont && (tmpin == dcont)) + do_free_upto(cmsbio, dcont); + else + BIO_free_all(cmsbio); + + err2: + if (cms_certs) + sk_X509_pop_free(cms_certs, X509_free); + if (crls) + sk_X509_CRL_pop_free(crls, X509_CRL_free); + + return ret; +} + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags) +{ + int r; + flags &= ~(CMS_DETACHED | CMS_TEXT); + r = CMS_verify(rcms, certs, store, NULL, NULL, flags); + if (r <= 0) + return r; + return cms_Receipt_verify(rcms, ocms); +} + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags) +{ + CMS_ContentInfo *cms; + int i; + + cms = CMS_ContentInfo_new(); + if (!cms || !CMS_SignedData_init(cms)) + goto merr; + + if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { + CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); + goto err; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *x = sk_X509_value(certs, i); + if (!CMS_add1_cert(cms, x)) + goto merr; + } + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) + || CMS_final(cms, data, NULL, flags)) + return cms; + else + goto err; + + merr: + CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); + + err: + if (cms) + CMS_ContentInfo_free(cms); + return NULL; +} + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags) +{ + CMS_SignerInfo *rct_si; + CMS_ContentInfo *cms = NULL; + ASN1_OCTET_STRING **pos, *os; + BIO *rct_cont = NULL; + int r = 0; + + flags &= ~(CMS_STREAM | CMS_TEXT); + /* Not really detached but avoids content being allocated */ + flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED; + if (!pkey || !signcert) { + CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT); + return NULL; + } + + /* Initialize signed data */ + + cms = CMS_sign(NULL, NULL, certs, NULL, flags); + if (!cms) + goto err; + + /* Set inner content type to signed receipt */ + if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) + goto err; + + rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); + if (!rct_si) { + CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR); + goto err; + } + + os = cms_encode_Receipt(si); + + if (!os) + goto err; + + /* Set content to digest */ + rct_cont = BIO_new_mem_buf(os->data, os->length); + if (!rct_cont) + goto err; + + /* Add msgSigDigest attribute */ + + if (!cms_msgSigDigest_add1(rct_si, si)) + goto err; + + /* Finalize structure */ + if (!CMS_final(cms, rct_cont, NULL, flags)) + goto err; + + /* Set embedded content */ + pos = CMS_get0_content(cms); + *pos = os; + + r = 1; + + err: + if (rct_cont) + BIO_free(rct_cont); + if (r) + return cms; + CMS_ContentInfo_free(cms); + return NULL; + +} + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, + const EVP_CIPHER *cipher, unsigned int flags) +{ + CMS_ContentInfo *cms; + int i; + X509 *recip; + cms = CMS_EnvelopedData_create(cipher); + if (!cms) + goto merr; + for (i = 0; i < sk_X509_num(certs); i++) { + recip = sk_X509_value(certs, i); + if (!CMS_add1_recipient_cert(cms, recip, flags)) { + CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); + goto err; + } + } + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) + || CMS_final(cms, data, NULL, flags)) + return cms; + else + goto err; + + merr: + CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); + err: + if (cms) + CMS_ContentInfo_free(cms); + return NULL; +} + +static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + EVP_PKEY *pk, X509 *cert) +{ + int i; + STACK_OF(CMS_RecipientEncryptedKey) *reks; + CMS_RecipientEncryptedKey *rek; + reks = CMS_RecipientInfo_kari_get0_reks(ri); + if (!cert) + return 0; + for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { + int rv; + rek = sk_CMS_RecipientEncryptedKey_value(reks, i); + if (CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) + continue; + CMS_RecipientInfo_kari_set0_pkey(ri, pk); + rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); + CMS_RecipientInfo_kari_set0_pkey(ri, NULL); + if (rv > 0) + return 1; + return -1; + } + return 0; +} + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r, ri_type; + int debug = 0, match_ri = 0; + ris = CMS_get0_RecipientInfos(cms); + if (ris) + debug = cms->d.envelopedData->encryptedContentInfo->debug; + ri_type = cms_pkey_get_ri_type(pk); + if (ri_type == CMS_RECIPINFO_NONE) { + CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + return 0; + } + + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != ri_type) + continue; + match_ri = 1; + if (ri_type == CMS_RECIPINFO_AGREE) { + r = cms_kari_set1_pkey(cms, ri, pk, cert); + if (r > 0) + return 1; + if (r < 0) + return 0; + } + /* + * If we have a cert try matching RecipientInfo otherwise try them + * all. + */ + else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { + CMS_RecipientInfo_set0_pkey(ri, pk); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_pkey(ri, NULL); + if (cert) { + /* + * If not debugging clear any error and return success to + * avoid leaking of information useful to MMA + */ + if (!debug) { + ERR_clear_error(); + return 1; + } + if (r > 0) + return 1; + CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR); + return 0; + } + /* + * If no cert and not debugging don't leave loop after first + * successful decrypt. Always attempt to decrypt all recipients + * to avoid leaking timing of a successful decrypt. + */ + else if (r > 0 && debug) + return 1; + } + } + /* If no cert and not debugging always return success */ + if (match_ri && !cert && !debug) { + ERR_clear_error(); + return 1; + } + + CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); + return 0; + +} + +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; + ris = CMS_get0_RecipientInfos(cms); + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) + continue; + + /* + * If we have an id try matching RecipientInfo otherwise try them + * all. + */ + if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { + CMS_RecipientInfo_set0_key(ri, key, keylen); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_key(ri, NULL, 0); + if (r > 0) + return 1; + if (id) { + CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR); + return 0; + } + ERR_clear_error(); + } + } + + CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT); + return 0; + +} + +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; + ris = CMS_get0_RecipientInfos(cms); + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) + continue; + CMS_RecipientInfo_set0_password(ri, pass, passlen); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_password(ri, NULL, 0); + if (r > 0) + return 1; + } + + CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT); + return 0; + +} + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags) +{ + int r; + BIO *cont; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { + CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); + return 0; + } + if (!dcont && !check_content(cms)) + return 0; + if (flags & CMS_DEBUG_DECRYPT) + cms->d.envelopedData->encryptedContentInfo->debug = 1; + else + cms->d.envelopedData->encryptedContentInfo->debug = 0; + if (!pk && !cert && !dcont && !out) + return 1; + if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) + return 0; + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + do_free_upto(cont, dcont); + return r; +} + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) +{ + BIO *cmsbio; + int ret = 0; + if (!(cmsbio = CMS_dataInit(cms, dcont))) { + CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB); + return 0; + } + + SMIME_crlf_copy(data, cmsbio, flags); + + (void)BIO_flush(cmsbio); + + if (!CMS_dataFinal(cms, cmsbio)) { + CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR); + goto err; + } + + ret = 1; + + err: + do_free_upto(cmsbio, dcont); + + return ret; + +} + +#ifdef ZLIB + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags) +{ + BIO *cont; + int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { + CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA); + return 0; + } + + if (!dcont && !check_content(cms)) + return 0; + + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + do_free_upto(cont, dcont); + return r; +} + +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) +{ + CMS_ContentInfo *cms; + if (comp_nid <= 0) + comp_nid = NID_zlib_compression; + cms = cms_CompressedData_create(comp_nid); + if (!cms) + return NULL; + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + return NULL; +} + +#else + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags) +{ + CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return 0; +} + +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) +{ + CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return NULL; +} + +#endif diff --git a/Sources/COpenSSL/cms_lcl.h b/Sources/COpenSSL/cms_lcl.h new file mode 100644 index 00000000..537ec685 --- /dev/null +++ b/Sources/COpenSSL/cms_lcl.h @@ -0,0 +1,471 @@ +/* crypto/cms/cms_lcl.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMS_LCL_H +# define HEADER_CMS_LCL_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include "x509.h" + +/* + * Cryptographic message syntax (CMS) structures: taken from RFC3852 + */ + +/* Forward references */ + +typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber; +typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo; +typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier; +typedef struct CMS_SignedData_st CMS_SignedData; +typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat; +typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo; +typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo; +typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; +typedef struct CMS_DigestedData_st CMS_DigestedData; +typedef struct CMS_EncryptedData_st CMS_EncryptedData; +typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData; +typedef struct CMS_CompressedData_st CMS_CompressedData; +typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat; +typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo; +typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey; +typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey; +typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo; +typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier; +typedef struct CMS_KeyAgreeRecipientIdentifier_st + CMS_KeyAgreeRecipientIdentifier; +typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier; +typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo; +typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo; +typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo; +typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom; + +struct CMS_ContentInfo_st { + ASN1_OBJECT *contentType; + union { + ASN1_OCTET_STRING *data; + CMS_SignedData *signedData; + CMS_EnvelopedData *envelopedData; + CMS_DigestedData *digestedData; + CMS_EncryptedData *encryptedData; + CMS_AuthenticatedData *authenticatedData; + CMS_CompressedData *compressedData; + ASN1_TYPE *other; + /* Other types ... */ + void *otherData; + } d; +}; + +struct CMS_SignedData_st { + long version; + STACK_OF(X509_ALGOR) *digestAlgorithms; + CMS_EncapsulatedContentInfo *encapContentInfo; + STACK_OF(CMS_CertificateChoices) *certificates; + STACK_OF(CMS_RevocationInfoChoice) *crls; + STACK_OF(CMS_SignerInfo) *signerInfos; +}; + +struct CMS_EncapsulatedContentInfo_st { + ASN1_OBJECT *eContentType; + ASN1_OCTET_STRING *eContent; + /* Set to 1 if incomplete structure only part set up */ + int partial; +}; + +struct CMS_SignerInfo_st { + long version; + CMS_SignerIdentifier *sid; + X509_ALGOR *digestAlgorithm; + STACK_OF(X509_ATTRIBUTE) *signedAttrs; + X509_ALGOR *signatureAlgorithm; + ASN1_OCTET_STRING *signature; + STACK_OF(X509_ATTRIBUTE) *unsignedAttrs; + /* Signing certificate and key */ + X509 *signer; + EVP_PKEY *pkey; + /* Digest and public key context for alternative parameters */ + EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; +}; + +struct CMS_SignerIdentifier_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + ASN1_OCTET_STRING *subjectKeyIdentifier; + } d; +}; + +struct CMS_EnvelopedData_st { + long version; + CMS_OriginatorInfo *originatorInfo; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + CMS_EncryptedContentInfo *encryptedContentInfo; + STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; +}; + +struct CMS_OriginatorInfo_st { + STACK_OF(CMS_CertificateChoices) *certificates; + STACK_OF(CMS_RevocationInfoChoice) *crls; +}; + +struct CMS_EncryptedContentInfo_st { + ASN1_OBJECT *contentType; + X509_ALGOR *contentEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedContent; + /* Content encryption algorithm and key */ + const EVP_CIPHER *cipher; + unsigned char *key; + size_t keylen; + /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ + int debug; +}; + +struct CMS_RecipientInfo_st { + int type; + union { + CMS_KeyTransRecipientInfo *ktri; + CMS_KeyAgreeRecipientInfo *kari; + CMS_KEKRecipientInfo *kekri; + CMS_PasswordRecipientInfo *pwri; + CMS_OtherRecipientInfo *ori; + } d; +}; + +typedef CMS_SignerIdentifier CMS_RecipientIdentifier; + +struct CMS_KeyTransRecipientInfo_st { + long version; + CMS_RecipientIdentifier *rid; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Recipient Key and cert */ + X509 *recip; + EVP_PKEY *pkey; + /* Public key context for this operation */ + EVP_PKEY_CTX *pctx; +}; + +struct CMS_KeyAgreeRecipientInfo_st { + long version; + CMS_OriginatorIdentifierOrKey *originator; + ASN1_OCTET_STRING *ukm; + X509_ALGOR *keyEncryptionAlgorithm; + STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys; + /* Public key context associated with current operation */ + EVP_PKEY_CTX *pctx; + /* Cipher context for CEK wrapping */ + EVP_CIPHER_CTX ctx; +}; + +struct CMS_OriginatorIdentifierOrKey_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + ASN1_OCTET_STRING *subjectKeyIdentifier; + CMS_OriginatorPublicKey *originatorKey; + } d; +}; + +struct CMS_OriginatorPublicKey_st { + X509_ALGOR *algorithm; + ASN1_BIT_STRING *publicKey; +}; + +struct CMS_RecipientEncryptedKey_st { + CMS_KeyAgreeRecipientIdentifier *rid; + ASN1_OCTET_STRING *encryptedKey; + /* Public key associated with this recipient */ + EVP_PKEY *pkey; +}; + +struct CMS_KeyAgreeRecipientIdentifier_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + CMS_RecipientKeyIdentifier *rKeyId; + } d; +}; + +struct CMS_RecipientKeyIdentifier_st { + ASN1_OCTET_STRING *subjectKeyIdentifier; + ASN1_GENERALIZEDTIME *date; + CMS_OtherKeyAttribute *other; +}; + +struct CMS_KEKRecipientInfo_st { + long version; + CMS_KEKIdentifier *kekid; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Extra info: symmetric key to use */ + unsigned char *key; + size_t keylen; +}; + +struct CMS_KEKIdentifier_st { + ASN1_OCTET_STRING *keyIdentifier; + ASN1_GENERALIZEDTIME *date; + CMS_OtherKeyAttribute *other; +}; + +struct CMS_PasswordRecipientInfo_st { + long version; + X509_ALGOR *keyDerivationAlgorithm; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Extra info: password to use */ + unsigned char *pass; + size_t passlen; +}; + +struct CMS_OtherRecipientInfo_st { + ASN1_OBJECT *oriType; + ASN1_TYPE *oriValue; +}; + +struct CMS_DigestedData_st { + long version; + X509_ALGOR *digestAlgorithm; + CMS_EncapsulatedContentInfo *encapContentInfo; + ASN1_OCTET_STRING *digest; +}; + +struct CMS_EncryptedData_st { + long version; + CMS_EncryptedContentInfo *encryptedContentInfo; + STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; +}; + +struct CMS_AuthenticatedData_st { + long version; + CMS_OriginatorInfo *originatorInfo; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + X509_ALGOR *macAlgorithm; + X509_ALGOR *digestAlgorithm; + CMS_EncapsulatedContentInfo *encapContentInfo; + STACK_OF(X509_ATTRIBUTE) *authAttrs; + ASN1_OCTET_STRING *mac; + STACK_OF(X509_ATTRIBUTE) *unauthAttrs; +}; + +struct CMS_CompressedData_st { + long version; + X509_ALGOR *compressionAlgorithm; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + CMS_EncapsulatedContentInfo *encapContentInfo; +}; + +struct CMS_RevocationInfoChoice_st { + int type; + union { + X509_CRL *crl; + CMS_OtherRevocationInfoFormat *other; + } d; +}; + +# define CMS_REVCHOICE_CRL 0 +# define CMS_REVCHOICE_OTHER 1 + +struct CMS_OtherRevocationInfoFormat_st { + ASN1_OBJECT *otherRevInfoFormat; + ASN1_TYPE *otherRevInfo; +}; + +struct CMS_CertificateChoices { + int type; + union { + X509 *certificate; + ASN1_STRING *extendedCertificate; /* Obsolete */ + ASN1_STRING *v1AttrCert; /* Left encoded for now */ + ASN1_STRING *v2AttrCert; /* Left encoded for now */ + CMS_OtherCertificateFormat *other; + } d; +}; + +# define CMS_CERTCHOICE_CERT 0 +# define CMS_CERTCHOICE_EXCERT 1 +# define CMS_CERTCHOICE_V1ACERT 2 +# define CMS_CERTCHOICE_V2ACERT 3 +# define CMS_CERTCHOICE_OTHER 4 + +struct CMS_OtherCertificateFormat_st { + ASN1_OBJECT *otherCertFormat; + ASN1_TYPE *otherCert; +}; + +/* + * This is also defined in pkcs7.h but we duplicate it to allow the CMS code + * to be independent of PKCS#7 + */ + +struct CMS_IssuerAndSerialNumber_st { + X509_NAME *issuer; + ASN1_INTEGER *serialNumber; +}; + +struct CMS_OtherKeyAttribute_st { + ASN1_OBJECT *keyAttrId; + ASN1_TYPE *keyAttr; +}; + +/* ESS structures */ + +# ifdef HEADER_X509V3_H + +struct CMS_ReceiptRequest_st { + ASN1_OCTET_STRING *signedContentIdentifier; + CMS_ReceiptsFrom *receiptsFrom; + STACK_OF(GENERAL_NAMES) *receiptsTo; +}; + +struct CMS_ReceiptsFrom_st { + int type; + union { + long allOrFirstTier; + STACK_OF(GENERAL_NAMES) *receiptList; + } d; +}; +# endif + +struct CMS_Receipt_st { + long version; + ASN1_OBJECT *contentType; + ASN1_OCTET_STRING *signedContentIdentifier; + ASN1_OCTET_STRING *originatorSignatureValue; +}; + +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_ITEM(CMS_SignerInfo) +DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) +DECLARE_ASN1_ITEM(CMS_Attributes_Sign) +DECLARE_ASN1_ITEM(CMS_Attributes_Verify) +DECLARE_ASN1_ITEM(CMS_RecipientInfo) +DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo) +DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber) + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_ISSUER_SERIAL 0 +# define CMS_RECIPINFO_KEYIDENTIFIER 1 + +# define CMS_REK_ISSUER_SERIAL 0 +# define CMS_REK_KEYIDENTIFIER 1 + +# define CMS_OIK_ISSUER_SERIAL 0 +# define CMS_OIK_KEYIDENTIFIER 1 +# define CMS_OIK_PUBKEY 2 + +BIO *cms_content_bio(CMS_ContentInfo *cms); + +CMS_ContentInfo *cms_Data_create(void); + +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md); +BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms); +int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify); + +BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms); +int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); +int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, + int type); +int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); +int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert); + +CMS_ContentInfo *cms_CompressedData_create(int comp_nid); +BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms); + +void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md); +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm); +int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, + X509_ALGOR *mdalg); + +int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert); +int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert); +int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert); +int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert); + +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec); +BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms); +int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen); + +int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms); +int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); +ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); + +BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); +CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); +int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd); +int cms_pkey_get_ri_type(EVP_PKEY *pk); +/* KARI routines */ +int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, + EVP_PKEY *pk, unsigned int flags); +int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri); + +/* PWRI routines */ +int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + int en_de); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/comp.h b/Sources/COpenSSL/comp.h new file mode 100644 index 00000000..f8af56a9 --- /dev/null +++ b/Sources/COpenSSL/comp.h @@ -0,0 +1,83 @@ + +#ifndef HEADER_COMP_H +# define HEADER_COMP_H + +# include "crypto.h" + +# ifdef OPENSSL_NO_COMP +# error COMP is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct comp_ctx_st COMP_CTX; + +struct comp_method_st { + int type; /* NID for compression library */ + const char *name; /* A text string to identify the library */ + int (*init) (COMP_CTX *ctx); + void (*finish) (COMP_CTX *ctx); + int (*compress) (COMP_CTX *ctx, + unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + int (*expand) (COMP_CTX *ctx, + unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + /* + * The following two do NOTHING, but are kept for backward compatibility + */ + long (*ctrl) (void); + long (*callback_ctrl) (void); +}; + +struct comp_ctx_st { + COMP_METHOD *meth; + unsigned long compress_in; + unsigned long compress_out; + unsigned long expand_in; + unsigned long expand_out; + CRYPTO_EX_DATA ex_data; +}; + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); +void COMP_CTX_free(COMP_CTX *ctx); +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +COMP_METHOD *COMP_rle(void); +COMP_METHOD *COMP_zlib(void); +void COMP_zlib_cleanup(void); + +# ifdef HEADER_BIO_H +# ifdef ZLIB +BIO_METHOD *BIO_f_zlib(void); +# endif +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_COMP_strings(void); + +/* Error codes for the COMP functions. */ + +/* Function codes. */ +# define COMP_F_BIO_ZLIB_FLUSH 99 +# define COMP_F_BIO_ZLIB_NEW 100 +# define COMP_F_BIO_ZLIB_READ 101 +# define COMP_F_BIO_ZLIB_WRITE 102 + +/* Reason codes. */ +# define COMP_R_ZLIB_DEFLATE_ERROR 99 +# define COMP_R_ZLIB_INFLATE_ERROR 100 +# define COMP_R_ZLIB_NOT_SUPPORTED 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/comp_.c b/Sources/COpenSSL/comp_.c new file mode 100644 index 00000000..ee710ecb --- /dev/null +++ b/Sources/COpenSSL/comp_.c @@ -0,0 +1,164 @@ +/* crypto/comp/comp_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "comp.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason) + +static ERR_STRING_DATA COMP_str_functs[] = { + {ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH), "BIO_ZLIB_FLUSH"}, + {ERR_FUNC(COMP_F_BIO_ZLIB_NEW), "BIO_ZLIB_NEW"}, + {ERR_FUNC(COMP_F_BIO_ZLIB_READ), "BIO_ZLIB_READ"}, + {ERR_FUNC(COMP_F_BIO_ZLIB_WRITE), "BIO_ZLIB_WRITE"}, + {0, NULL} +}; + +static ERR_STRING_DATA COMP_str_reasons[] = { + {ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR), "zlib deflate error"}, + {ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR), "zlib inflate error"}, + {ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED), "zlib not supported"}, + {0, NULL} +}; + +#endif + +void ERR_load_COMP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) { + ERR_load_strings(0, COMP_str_functs); + ERR_load_strings(0, COMP_str_reasons); + } +#endif +} +#include +#include +#include +#include "objects.h" +// #include "comp.h" + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth) +{ + COMP_CTX *ret; + + if ((ret = (COMP_CTX *)OPENSSL_malloc(sizeof(COMP_CTX))) == NULL) { + /* ZZZZZZZZZZZZZZZZ */ + return (NULL); + } + memset(ret, 0, sizeof(COMP_CTX)); + ret->meth = meth; + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +void COMP_CTX_free(COMP_CTX *ctx) +{ + if (ctx == NULL) + return; + + if (ctx->meth->finish != NULL) + ctx->meth->finish(ctx); + + OPENSSL_free(ctx); +} + +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen) +{ + int ret; + if (ctx->meth->compress == NULL) { + /* ZZZZZZZZZZZZZZZZZ */ + return (-1); + } + ret = ctx->meth->compress(ctx, out, olen, in, ilen); + if (ret > 0) { + ctx->compress_in += ilen; + ctx->compress_out += ret; + } + return (ret); +} + +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen) +{ + int ret; + + if (ctx->meth->expand == NULL) { + /* ZZZZZZZZZZZZZZZZZ */ + return (-1); + } + ret = ctx->meth->expand(ctx, out, olen, in, ilen); + if (ret > 0) { + ctx->expand_in += ilen; + ctx->expand_out += ret; + } + return (ret); +} diff --git a/Sources/COpenSSL/conf.h b/Sources/COpenSSL/conf.h new file mode 100644 index 00000000..a7ded85c --- /dev/null +++ b/Sources/COpenSSL/conf.h @@ -0,0 +1,268 @@ +/* crypto/conf/conf.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_H +# define HEADER_CONF_H + +# include "bio.h" +# include "lhash.h" +# include "stack.h" +# include "safestack.h" +# include "e_os2.h" + +# include "ossl_typ.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +DECLARE_STACK_OF(CONF_VALUE) +DECLARE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create) (CONF_METHOD *meth); + int (*init) (CONF *conf); + int (*destroy) (CONF *conf); + int (*destroy_data) (CONF *conf); + int (*load_bio) (CONF *conf, BIO *bp, long *eline); + int (*dump) (const CONF *conf, BIO *bp); + int (*is_number) (const CONF *conf, char c); + int (*to_int) (const CONF *conf, char c); + int (*load) (CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DECLARE_STACK_OF(CONF_MODULE) +DECLARE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func (CONF_IMODULE *md); + +# define CONF_MFLAGS_IGNORE_ERRORS 0x1 +# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +# define CONF_MFLAGS_SILENT 0x4 +# define CONF_MFLAGS_NO_DSO 0x8 +# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +# define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +# ifndef OPENSSL_NO_FP_API +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +# endif +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +void OPENSSL_config(const char *config_name); +void OPENSSL_no_config(void); + +/* + * New conf code. The semantics are different from the functions above. If + * that wasn't the case, the above functions would have been replaced + */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; +}; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +# if 0 /* Just to give you an idea of what I have in + * mind */ +CONF_METHOD *NCONF_XML(void); +# endif +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +# ifndef OPENSSL_NO_FP_API +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +# endif +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +int NCONF_dump_fp(const CONF *conf, FILE *out); +int NCONF_dump_bio(const CONF *conf, BIO *out); + +# if 0 /* The following function has no error + * checking, and should therefore be avoided */ +long NCONF_get_number(CONF *conf, char *group, char *name); +# else +# define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) +# endif + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +void CONF_modules_free(void); +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg); + +void OPENSSL_load_builtin_modules(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CONF_strings(void); + +/* Error codes for the CONF functions. */ + +/* Function codes. */ +# define CONF_F_CONF_DUMP_FP 104 +# define CONF_F_CONF_LOAD 100 +# define CONF_F_CONF_LOAD_BIO 102 +# define CONF_F_CONF_LOAD_FP 103 +# define CONF_F_CONF_MODULES_LOAD 116 +# define CONF_F_CONF_PARSE_LIST 119 +# define CONF_F_DEF_LOAD 120 +# define CONF_F_DEF_LOAD_BIO 121 +# define CONF_F_MODULE_INIT 115 +# define CONF_F_MODULE_LOAD_DSO 117 +# define CONF_F_MODULE_RUN 118 +# define CONF_F_NCONF_DUMP_BIO 105 +# define CONF_F_NCONF_DUMP_FP 106 +# define CONF_F_NCONF_GET_NUMBER 107 +# define CONF_F_NCONF_GET_NUMBER_E 112 +# define CONF_F_NCONF_GET_SECTION 108 +# define CONF_F_NCONF_GET_STRING 109 +# define CONF_F_NCONF_LOAD 113 +# define CONF_F_NCONF_LOAD_BIO 110 +# define CONF_F_NCONF_LOAD_FP 114 +# define CONF_F_NCONF_NEW 111 +# define CONF_F_STR_COPY 101 + +/* Reason codes. */ +# define CONF_R_ERROR_LOADING_DSO 110 +# define CONF_R_LIST_CANNOT_BE_NULL 115 +# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +# define CONF_R_MISSING_EQUAL_SIGN 101 +# define CONF_R_MISSING_FINISH_FUNCTION 111 +# define CONF_R_MISSING_INIT_FUNCTION 112 +# define CONF_R_MODULE_INITIALIZATION_ERROR 109 +# define CONF_R_NO_CLOSE_BRACE 102 +# define CONF_R_NO_CONF 105 +# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +# define CONF_R_NO_SECTION 107 +# define CONF_R_NO_SUCH_FILE 114 +# define CONF_R_NO_VALUE 108 +# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +# define CONF_R_UNKNOWN_MODULE_NAME 113 +# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 +# define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/conf_.c b/Sources/COpenSSL/conf_.c new file mode 100644 index 00000000..ab0d3893 --- /dev/null +++ b/Sources/COpenSSL/conf_.c @@ -0,0 +1,2333 @@ +/* conf_api.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Part of the code in here was originally in conf.c, which is now removed */ + +#ifndef CONF_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +#include +#include "cryptlib.h" +#include "conf.h" +#include "conf_api.h" +#include "e_os.h" + +static void value_free_hash_doall_arg(CONF_VALUE *a, + LHASH_OF(CONF_VALUE) *conf); +static void value_free_stack_doall(CONF_VALUE *a); +static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE, + LHASH_OF(CONF_VALUE)) +static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE) + +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) +{ + CONF_VALUE *v, vv; + + if ((conf == NULL) || (section == NULL)) + return (NULL); + vv.name = NULL; + vv.section = (char *)section; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + return (v); +} + +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section) +{ + CONF_VALUE *v; + + v = _CONF_get_section(conf, section); + if (v != NULL) + return ((STACK_OF(CONF_VALUE) *)v->value); + else + return (NULL); +} + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) +{ + CONF_VALUE *v = NULL; + STACK_OF(CONF_VALUE) *ts; + + ts = (STACK_OF(CONF_VALUE) *)section->value; + + value->section = section->section; + if (!sk_CONF_VALUE_push(ts, value)) { + return 0; + } + + v = lh_CONF_VALUE_insert(conf->data, value); + if (v != NULL) { + (void)sk_CONF_VALUE_delete_ptr(ts, v); + OPENSSL_free(v->name); + OPENSSL_free(v->value); + OPENSSL_free(v); + } + return 1; +} + +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name) +{ + CONF_VALUE *v, vv; + char *p; + + if (name == NULL) + return (NULL); + if (conf != NULL) { + if (section != NULL) { + vv.name = (char *)name; + vv.section = (char *)section; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + if (v != NULL) + return (v->value); + if (strcmp(section, "ENV") == 0) { + p = ossl_safe_getenv(name); + if (p != NULL) + return (p); + } + } + vv.section = "default"; + vv.name = (char *)name; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + if (v != NULL) + return (v->value); + else + return (NULL); + } else + return (ossl_safe_getenv(name)); +} + +#if 0 /* There's no way to provide error checking + * with this function, so force implementors + * of the higher levels to get a string and + * read the number themselves. */ +long _CONF_get_number(CONF *conf, char *section, char *name) +{ + char *str; + long ret = 0; + + str = _CONF_get_string(conf, section, name); + if (str == NULL) + return (0); + for (;;) { + if (conf->meth->is_number(conf, *str)) + ret = ret * 10 + conf->meth->to_int(conf, *str); + else + return (ret); + str++; + } +} +#endif + +static unsigned long conf_value_hash(const CONF_VALUE *v) +{ + return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); +} + +static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) + +static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) +{ + int i; + + if (a->section != b->section) { + i = strcmp(a->section, b->section); + if (i) + return (i); + } + + if ((a->name != NULL) && (b->name != NULL)) { + i = strcmp(a->name, b->name); + return (i); + } else if (a->name == b->name) + return (0); + else + return ((a->name == NULL) ? -1 : 1); +} + +static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) + +int _CONF_new_data(CONF *conf) +{ + if (conf == NULL) { + return 0; + } + if (conf->data == NULL) + if ((conf->data = lh_CONF_VALUE_new()) == NULL) { + return 0; + } + return 1; +} + +void _CONF_free_data(CONF *conf) +{ + if (conf == NULL || conf->data == NULL) + return; + + lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make * sure the + * 'OPENSSL_free()' works as * + * expected */ + lh_CONF_VALUE_doall_arg(conf->data, + LHASH_DOALL_ARG_FN(value_free_hash), + LHASH_OF(CONF_VALUE), conf->data); + + /* + * We now have only 'section' entries in the hash table. Due to problems + * with + */ + + lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); + lh_CONF_VALUE_free(conf->data); +} + +static void value_free_hash_doall_arg(CONF_VALUE *a, + LHASH_OF(CONF_VALUE) *conf) +{ + if (a->name != NULL) + (void)lh_CONF_VALUE_delete(conf, a); +} + +static void value_free_stack_doall(CONF_VALUE *a) +{ + CONF_VALUE *vv; + STACK_OF(CONF_VALUE) *sk; + int i; + + if (a->name != NULL) + return; + + sk = (STACK_OF(CONF_VALUE) *)a->value; + for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { + vv = sk_CONF_VALUE_value(sk, i); + OPENSSL_free(vv->value); + OPENSSL_free(vv->name); + OPENSSL_free(vv); + } + if (sk != NULL) + sk_CONF_VALUE_free(sk); + OPENSSL_free(a->section); + OPENSSL_free(a); +} + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) +{ + STACK_OF(CONF_VALUE) *sk = NULL; + int ok = 0, i; + CONF_VALUE *v = NULL, *vv; + + if ((sk = sk_CONF_VALUE_new_null()) == NULL) + goto err; + if ((v = OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) + goto err; + i = strlen(section) + 1; + if ((v->section = OPENSSL_malloc(i)) == NULL) + goto err; + + memcpy(v->section, section, i); + v->name = NULL; + v->value = (char *)sk; + + vv = lh_CONF_VALUE_insert(conf->data, v); + OPENSSL_assert(vv == NULL); + if (lh_CONF_VALUE_error(conf->data) > 0) + goto err; + ok = 1; + err: + if (!ok) { + if (sk != NULL) + sk_CONF_VALUE_free(sk); + if (v != NULL) + OPENSSL_free(v); + v = NULL; + } + return (v); +} + +IMPLEMENT_STACK_OF(CONF_VALUE) +/* crypto/conf/conf.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Part of the code in here was originally in conf.c, which is now removed */ + +#include +#include +// #include "cryptlib.h" +#include "stack.h" +#include "lhash.h" +// #include "conf.h" +// #include "conf_api.h" +#include "conf_def.h" +#include "buffer.h" +#include "err.h" + +/* + * The maximum length we can grow a value to after variable expansion. 64k + * should be more than enough for all reasonable uses. + */ +#define MAX_CONF_VALUE_LENGTH 65536 + +static char *eat_ws(CONF *conf, char *p); +static char *eat_alpha_numeric(CONF *conf, char *p); +static void clear_comments(CONF *conf, char *p); +static int str_copy(CONF *conf, char *section, char **to, char *from); +static char *scan_quote(CONF *conf, char *p); +static char *scan_dquote(CONF *conf, char *p); +#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) + +static CONF *def_create(CONF_METHOD *meth); +static int def_init_default(CONF *conf); +static int def_init_WIN32(CONF *conf); +static int def_destroy(CONF *conf); +static int def_destroy_data(CONF *conf); +static int def_load(CONF *conf, const char *name, long *eline); +static int def_load_bio(CONF *conf, BIO *bp, long *eline); +static int def_dump(const CONF *conf, BIO *bp); +static int def_is_number(const CONF *conf, char c); +static int def_to_int(const CONF *conf, char c); + +const char CONF_def_version[] = "CONF_def" OPENSSL_VERSION_PTEXT; + +static CONF_METHOD default_method = { + "OpenSSL default", + def_create, + def_init_default, + def_destroy, + def_destroy_data, + def_load_bio, + def_dump, + def_is_number, + def_to_int, + def_load +}; + +static CONF_METHOD WIN32_method = { + "WIN32", + def_create, + def_init_WIN32, + def_destroy, + def_destroy_data, + def_load_bio, + def_dump, + def_is_number, + def_to_int, + def_load +}; + +CONF_METHOD *NCONF_default() +{ + return &default_method; +} + +CONF_METHOD *NCONF_WIN32() +{ + return &WIN32_method; +} + +static CONF *def_create(CONF_METHOD *meth) +{ + CONF *ret; + + ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); + if (ret) + if (meth->init(ret) == 0) { + OPENSSL_free(ret); + ret = NULL; + } + return ret; +} + +static int def_init_default(CONF *conf) +{ + if (conf == NULL) + return 0; + + conf->meth = &default_method; + conf->meth_data = CONF_type_default; + conf->data = NULL; + + return 1; +} + +static int def_init_WIN32(CONF *conf) +{ + if (conf == NULL) + return 0; + + conf->meth = &WIN32_method; + conf->meth_data = (void *)CONF_type_win32; + conf->data = NULL; + + return 1; +} + +static int def_destroy(CONF *conf) +{ + if (def_destroy_data(conf)) { + OPENSSL_free(conf); + return 1; + } + return 0; +} + +static int def_destroy_data(CONF *conf) +{ + if (conf == NULL) + return 0; + _CONF_free_data(conf); + return 1; +} + +static int def_load(CONF *conf, const char *name, long *line) +{ + int ret; + BIO *in = NULL; + +#ifdef OPENSSL_SYS_VMS + in = BIO_new_file(name, "r"); +#else + in = BIO_new_file(name, "rb"); +#endif + if (in == NULL) { + if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) + CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE); + else + CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB); + return 0; + } + + ret = def_load_bio(conf, in, line); + BIO_free(in); + + return ret; +} + +static int def_load_bio(CONF *conf, BIO *in, long *line) +{ +/* The macro BUFSIZE conflicts with a system macro in VxWorks */ +#define CONFBUFSIZE 512 + int bufnum = 0, i, ii; + BUF_MEM *buff = NULL; + char *s, *p, *end; + int again; + long eline = 0; + char btmp[DECIMAL_SIZE(eline) + 1]; + CONF_VALUE *v = NULL, *tv; + CONF_VALUE *sv = NULL; + char *section = NULL, *buf; + char *start, *psection, *pname; + void *h = (void *)(conf->data); + + if ((buff = BUF_MEM_new()) == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); + goto err; + } + + section = BUF_strdup("default"); + if (section == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (_CONF_new_data(conf) == 0) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + + sv = _CONF_new_section(conf, section); + if (sv == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + + bufnum = 0; + again = 0; + for (;;) { + if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); + goto err; + } + p = &(buff->data[bufnum]); + *p = '\0'; + BIO_gets(in, p, CONFBUFSIZE - 1); + p[CONFBUFSIZE - 1] = '\0'; + ii = i = strlen(p); + if (i == 0 && !again) + break; + again = 0; + while (i > 0) { + if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) + break; + else + i--; + } + /* + * we removed some trailing stuff so there is a new line on the end. + */ + if (ii && i == ii) + again = 1; /* long line */ + else { + p[i] = '\0'; + eline++; /* another input line */ + } + + /* we now have a line with trailing \r\n removed */ + + /* i is the number of bytes */ + bufnum += i; + + v = NULL; + /* check for line continuation */ + if (bufnum >= 1) { + /* + * If we have bytes and the last char '\\' and second last char + * is not '\\' + */ + p = &(buff->data[bufnum - 1]); + if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { + bufnum--; + again = 1; + } + } + if (again) + continue; + bufnum = 0; + buf = buff->data; + + clear_comments(conf, buf); + s = eat_ws(conf, buf); + if (IS_EOF(conf, *s)) + continue; /* blank line */ + if (*s == '[') { + char *ss; + + s++; + start = eat_ws(conf, s); + ss = start; + again: + end = eat_alpha_numeric(conf, ss); + p = eat_ws(conf, end); + if (*p != ']') { + if (*p != '\0' && ss != p) { + ss = p; + goto again; + } + CONFerr(CONF_F_DEF_LOAD_BIO, + CONF_R_MISSING_CLOSE_SQUARE_BRACKET); + goto err; + } + *end = '\0'; + if (!str_copy(conf, NULL, §ion, start)) + goto err; + if ((sv = _CONF_get_section(conf, section)) == NULL) + sv = _CONF_new_section(conf, section); + if (sv == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, + CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + continue; + } else { + pname = s; + psection = NULL; + end = eat_alpha_numeric(conf, s); + if ((end[0] == ':') && (end[1] == ':')) { + *end = '\0'; + end += 2; + psection = pname; + pname = end; + end = eat_alpha_numeric(conf, end); + } + p = eat_ws(conf, end); + if (*p != '=') { + CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); + goto err; + } + *end = '\0'; + p++; + start = eat_ws(conf, p); + while (!IS_EOF(conf, *p)) + p++; + p--; + while ((p != start) && (IS_WS(conf, *p))) + p--; + p++; + *p = '\0'; + + if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + if (psection == NULL) + psection = section; + v->name = (char *)OPENSSL_malloc(strlen(pname) + 1); + v->value = NULL; + if (v->name == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + BUF_strlcpy(v->name, pname, strlen(pname) + 1); + if (!str_copy(conf, psection, &(v->value), start)) + goto err; + + if (strcmp(psection, section) != 0) { + if ((tv = _CONF_get_section(conf, psection)) + == NULL) + tv = _CONF_new_section(conf, psection); + if (tv == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, + CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + } else + tv = sv; +#if 1 + if (_CONF_add_string(conf, tv, v) == 0) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } +#else + v->section = tv->section; + if (!sk_CONF_VALUE_push(ts, v)) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + vv = (CONF_VALUE *)lh_insert(conf->data, v); + if (vv != NULL) { + sk_CONF_VALUE_delete_ptr(ts, vv); + OPENSSL_free(vv->name); + OPENSSL_free(vv->value); + OPENSSL_free(vv); + } +#endif + v = NULL; + } + } + if (buff != NULL) + BUF_MEM_free(buff); + if (section != NULL) + OPENSSL_free(section); + return (1); + err: + if (buff != NULL) + BUF_MEM_free(buff); + if (section != NULL) + OPENSSL_free(section); + if (line != NULL) + *line = eline; + BIO_snprintf(btmp, sizeof(btmp), "%ld", eline); + ERR_add_error_data(2, "line ", btmp); + if ((h != conf->data) && (conf->data != NULL)) { + CONF_free(conf->data); + conf->data = NULL; + } + if (v != NULL) { + if (v->name != NULL) + OPENSSL_free(v->name); + if (v->value != NULL) + OPENSSL_free(v->value); + if (v != NULL) + OPENSSL_free(v); + } + return (0); +} + +static void clear_comments(CONF *conf, char *p) +{ + for (;;) { + if (IS_FCOMMENT(conf, *p)) { + *p = '\0'; + return; + } + if (!IS_WS(conf, *p)) { + break; + } + p++; + } + + for (;;) { + if (IS_COMMENT(conf, *p)) { + *p = '\0'; + return; + } + if (IS_DQUOTE(conf, *p)) { + p = scan_dquote(conf, p); + continue; + } + if (IS_QUOTE(conf, *p)) { + p = scan_quote(conf, p); + continue; + } + if (IS_ESC(conf, *p)) { + p = scan_esc(conf, p); + continue; + } + if (IS_EOF(conf, *p)) + return; + else + p++; + } +} + +static int str_copy(CONF *conf, char *section, char **pto, char *from) +{ + int q, r, rr = 0, to = 0, len = 0; + char *s, *e, *rp, *p, *rrp, *np, *cp, v; + BUF_MEM *buf; + + if ((buf = BUF_MEM_new()) == NULL) + return (0); + + len = strlen(from) + 1; + if (!BUF_MEM_grow(buf, len)) + goto err; + + for (;;) { + if (IS_QUOTE(conf, *from)) { + q = *from; + from++; + while (!IS_EOF(conf, *from) && (*from != q)) { + if (IS_ESC(conf, *from)) { + from++; + if (IS_EOF(conf, *from)) + break; + } + buf->data[to++] = *(from++); + } + if (*from == q) + from++; + } else if (IS_DQUOTE(conf, *from)) { + q = *from; + from++; + while (!IS_EOF(conf, *from)) { + if (*from == q) { + if (*(from + 1) == q) { + from++; + } else { + break; + } + } + buf->data[to++] = *(from++); + } + if (*from == q) + from++; + } else if (IS_ESC(conf, *from)) { + from++; + v = *(from++); + if (IS_EOF(conf, v)) + break; + else if (v == 'r') + v = '\r'; + else if (v == 'n') + v = '\n'; + else if (v == 'b') + v = '\b'; + else if (v == 't') + v = '\t'; + buf->data[to++] = v; + } else if (IS_EOF(conf, *from)) + break; + else if (*from == '$') { + size_t newsize; + + /* try to expand it */ + rrp = NULL; + s = &(from[1]); + if (*s == '{') + q = '}'; + else if (*s == '(') + q = ')'; + else + q = 0; + + if (q) + s++; + cp = section; + e = np = s; + while (IS_ALPHA_NUMERIC(conf, *e)) + e++; + if ((e[0] == ':') && (e[1] == ':')) { + cp = np; + rrp = e; + rr = *e; + *rrp = '\0'; + e += 2; + np = e; + while (IS_ALPHA_NUMERIC(conf, *e)) + e++; + } + r = *e; + *e = '\0'; + rp = e; + if (q) { + if (r != q) { + CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE); + goto err; + } + e++; + } + /*- + * So at this point we have + * np which is the start of the name string which is + * '\0' terminated. + * cp which is the start of the section string which is + * '\0' terminated. + * e is the 'next point after'. + * r and rr are the chars replaced by the '\0' + * rp and rrp is where 'r' and 'rr' came from. + */ + p = _CONF_get_string(conf, cp, np); + if (rrp != NULL) + *rrp = rr; + *rp = r; + if (p == NULL) { + CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE); + goto err; + } + newsize = strlen(p) + buf->length - (e - from); + if (newsize > MAX_CONF_VALUE_LENGTH) { + CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG); + goto err; + } + if (!BUF_MEM_grow_clean(buf, newsize)) { + CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE); + goto err; + } + while (*p) + buf->data[to++] = *(p++); + + /* + * Since we change the pointer 'from', we also have to change the + * perceived length of the string it points at. /RL + */ + len -= e - from; + from = e; + + /* + * In case there were no braces or parenthesis around the + * variable reference, we have to put back the character that was + * replaced with a '\0'. /RL + */ + *rp = r; + } else + buf->data[to++] = *(from++); + } + buf->data[to] = '\0'; + if (*pto != NULL) + OPENSSL_free(*pto); + *pto = buf->data; + OPENSSL_free(buf); + return (1); + err: + if (buf != NULL) + BUF_MEM_free(buf); + return (0); +} + +static char *eat_ws(CONF *conf, char *p) +{ + while (IS_WS(conf, *p) && (!IS_EOF(conf, *p))) + p++; + return (p); +} + +static char *eat_alpha_numeric(CONF *conf, char *p) +{ + for (;;) { + if (IS_ESC(conf, *p)) { + p = scan_esc(conf, p); + continue; + } + if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) + return (p); + p++; + } +} + +static char *scan_quote(CONF *conf, char *p) +{ + int q = *p; + + p++; + while (!(IS_EOF(conf, *p)) && (*p != q)) { + if (IS_ESC(conf, *p)) { + p++; + if (IS_EOF(conf, *p)) + return (p); + } + p++; + } + if (*p == q) + p++; + return (p); +} + +static char *scan_dquote(CONF *conf, char *p) +{ + int q = *p; + + p++; + while (!(IS_EOF(conf, *p))) { + if (*p == q) { + if (*(p + 1) == q) { + p++; + } else { + break; + } + } + p++; + } + if (*p == q) + p++; + return (p); +} + +static void dump_value_doall_arg(CONF_VALUE *a, BIO *out) +{ + if (a->name) + BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); + else + BIO_printf(out, "[[%s]]\n", a->section); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO) + +static int def_dump(const CONF *conf, BIO *out) +{ + lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), + BIO, out); + return 1; +} + +static int def_is_number(const CONF *conf, char c) +{ + return IS_NUMBER(conf, c); +} + +static int def_to_int(const CONF *conf, char c) +{ + return c - '0'; +} +/* crypto/conf/conf_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +// #include "err.h" +// #include "conf.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason) + +static ERR_STRING_DATA CONF_str_functs[] = { + {ERR_FUNC(CONF_F_CONF_DUMP_FP), "CONF_dump_fp"}, + {ERR_FUNC(CONF_F_CONF_LOAD), "CONF_load"}, + {ERR_FUNC(CONF_F_CONF_LOAD_BIO), "CONF_load_bio"}, + {ERR_FUNC(CONF_F_CONF_LOAD_FP), "CONF_load_fp"}, + {ERR_FUNC(CONF_F_CONF_MODULES_LOAD), "CONF_modules_load"}, + {ERR_FUNC(CONF_F_CONF_PARSE_LIST), "CONF_parse_list"}, + {ERR_FUNC(CONF_F_DEF_LOAD), "DEF_LOAD"}, + {ERR_FUNC(CONF_F_DEF_LOAD_BIO), "DEF_LOAD_BIO"}, + {ERR_FUNC(CONF_F_MODULE_INIT), "MODULE_INIT"}, + {ERR_FUNC(CONF_F_MODULE_LOAD_DSO), "MODULE_LOAD_DSO"}, + {ERR_FUNC(CONF_F_MODULE_RUN), "MODULE_RUN"}, + {ERR_FUNC(CONF_F_NCONF_DUMP_BIO), "NCONF_dump_bio"}, + {ERR_FUNC(CONF_F_NCONF_DUMP_FP), "NCONF_dump_fp"}, + {ERR_FUNC(CONF_F_NCONF_GET_NUMBER), "NCONF_get_number"}, + {ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E), "NCONF_get_number_e"}, + {ERR_FUNC(CONF_F_NCONF_GET_SECTION), "NCONF_get_section"}, + {ERR_FUNC(CONF_F_NCONF_GET_STRING), "NCONF_get_string"}, + {ERR_FUNC(CONF_F_NCONF_LOAD), "NCONF_load"}, + {ERR_FUNC(CONF_F_NCONF_LOAD_BIO), "NCONF_load_bio"}, + {ERR_FUNC(CONF_F_NCONF_LOAD_FP), "NCONF_load_fp"}, + {ERR_FUNC(CONF_F_NCONF_NEW), "NCONF_new"}, + {ERR_FUNC(CONF_F_STR_COPY), "STR_COPY"}, + {0, NULL} +}; + +static ERR_STRING_DATA CONF_str_reasons[] = { + {ERR_REASON(CONF_R_ERROR_LOADING_DSO), "error loading dso"}, + {ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL), "list cannot be null"}, + {ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET), + "missing close square bracket"}, + {ERR_REASON(CONF_R_MISSING_EQUAL_SIGN), "missing equal sign"}, + {ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION), "missing finish function"}, + {ERR_REASON(CONF_R_MISSING_INIT_FUNCTION), "missing init function"}, + {ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR), + "module initialization error"}, + {ERR_REASON(CONF_R_NO_CLOSE_BRACE), "no close brace"}, + {ERR_REASON(CONF_R_NO_CONF), "no conf"}, + {ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE), + "no conf or environment variable"}, + {ERR_REASON(CONF_R_NO_SECTION), "no section"}, + {ERR_REASON(CONF_R_NO_SUCH_FILE), "no such file"}, + {ERR_REASON(CONF_R_NO_VALUE), "no value"}, + {ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION), + "unable to create new section"}, + {ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"}, + {ERR_REASON(CONF_R_VARIABLE_EXPANSION_TOO_LONG), + "variable expansion too long"}, + {ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"}, + {0, NULL} +}; + +#endif + +void ERR_load_CONF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) { + ERR_load_strings(0, CONF_str_functs); + ERR_load_strings(0, CONF_str_reasons); + } +#endif +} +/* conf_lib.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "crypto.h" +// #include "err.h" +// #include "conf.h" +// #include "conf_api.h" +// #include "lhash.h" + +const char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT; + +static CONF_METHOD *default_CONF_method = NULL; + +/* Init a 'CONF' structure from an old LHASH */ + +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) +{ + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + + default_CONF_method->init(conf); + conf->data = hash; +} + +/* + * The following section contains the "CONF classic" functions, rewritten in + * terms of the new CONF interface. + */ + +int CONF_set_default_method(CONF_METHOD *meth) +{ + default_CONF_method = meth; + return 1; +} + +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline) +{ + LHASH_OF(CONF_VALUE) *ltmp; + BIO *in = NULL; + +#ifdef OPENSSL_SYS_VMS + in = BIO_new_file(file, "r"); +#else + in = BIO_new_file(file, "rb"); +#endif + if (in == NULL) { + CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); + return NULL; + } + + ltmp = CONF_load_bio(conf, in, eline); + BIO_free(in); + + return ltmp; +} + +#ifndef OPENSSL_NO_FP_API +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline) +{ + BIO *btmp; + LHASH_OF(CONF_VALUE) *ltmp; + if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { + CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); + return NULL; + } + ltmp = CONF_load_bio(conf, btmp, eline); + BIO_free(btmp); + return ltmp; +} +#endif + +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline) +{ + CONF ctmp; + int ret; + + CONF_set_nconf(&ctmp, conf); + + ret = NCONF_load_bio(&ctmp, bp, eline); + if (ret) + return ctmp.data; + return NULL; +} + +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section) +{ + if (conf == NULL) { + return NULL; + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return NCONF_get_section(&ctmp, section); + } +} + +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name) +{ + if (conf == NULL) { + return NCONF_get_string(NULL, group, name); + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return NCONF_get_string(&ctmp, group, name); + } +} + +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name) +{ + int status; + long result = 0; + + if (conf == NULL) { + status = NCONF_get_number_e(NULL, group, name, &result); + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + status = NCONF_get_number_e(&ctmp, group, name, &result); + } + + if (status == 0) { + /* This function does not believe in errors... */ + ERR_clear_error(); + } + return result; +} + +void CONF_free(LHASH_OF(CONF_VALUE) *conf) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + NCONF_free_data(&ctmp); +} + +#ifndef OPENSSL_NO_FP_API +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) +{ + BIO *btmp; + int ret; + + if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { + CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); + return 0; + } + ret = CONF_dump_bio(conf, btmp); + BIO_free(btmp); + return ret; +} +#endif + +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return NCONF_dump_bio(&ctmp, out); +} + +/* + * The following section contains the "New CONF" functions. They are + * completely centralised around a new CONF structure that may contain + * basically anything, but at least a method pointer and a table of data. + * These functions are also written in terms of the bridge functions used by + * the "CONF classic" functions, for consistency. + */ + +CONF *NCONF_new(CONF_METHOD *meth) +{ + CONF *ret; + + if (meth == NULL) + meth = NCONF_default(); + + ret = meth->create(meth); + if (ret == NULL) { + CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + return ret; +} + +void NCONF_free(CONF *conf) +{ + if (conf == NULL) + return; + conf->meth->destroy(conf); +} + +void NCONF_free_data(CONF *conf) +{ + if (conf == NULL) + return; + conf->meth->destroy_data(conf); +} + +int NCONF_load(CONF *conf, const char *file, long *eline) +{ + if (conf == NULL) { + CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); + return 0; + } + + return conf->meth->load(conf, file, eline); +} + +#ifndef OPENSSL_NO_FP_API +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) +{ + BIO *btmp; + int ret; + if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { + CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); + return 0; + } + ret = NCONF_load_bio(conf, btmp, eline); + BIO_free(btmp); + return ret; +} +#endif + +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) +{ + if (conf == NULL) { + CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); + return 0; + } + + return conf->meth->load_bio(conf, bp, eline); +} + +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) +{ + if (conf == NULL) { + CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); + return NULL; + } + + if (section == NULL) { + CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); + return NULL; + } + + return _CONF_get_section_values(conf, section); +} + +char *NCONF_get_string(const CONF *conf, const char *group, const char *name) +{ + char *s = _CONF_get_string(conf, group, name); + + /* + * Since we may get a value from an environment variable even if conf is + * NULL, let's check the value first + */ + if (s) + return s; + + if (conf == NULL) { + CONFerr(CONF_F_NCONF_GET_STRING, + CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); + return NULL; + } + CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); + ERR_add_error_data(4, "group=", group, " name=", name); + return NULL; +} + +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result) +{ + char *str; + + if (result == NULL) { + CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + str = NCONF_get_string(conf, group, name); + + if (str == NULL) + return 0; + + for (*result = 0; conf->meth->is_number(conf, *str);) { + *result = (*result) * 10 + conf->meth->to_int(conf, *str); + str++; + } + + return 1; +} + +#ifndef OPENSSL_NO_FP_API +int NCONF_dump_fp(const CONF *conf, FILE *out) +{ + BIO *btmp; + int ret; + if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { + CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); + return 0; + } + ret = NCONF_dump_bio(conf, btmp); + BIO_free(btmp); + return ret; +} +#endif + +int NCONF_dump_bio(const CONF *conf, BIO *out) +{ + if (conf == NULL) { + CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); + return 0; + } + + return conf->meth->dump(conf, out); +} + +/* This function should be avoided */ +#if 0 +long NCONF_get_number(CONF *conf, char *group, char *name) +{ + int status; + long ret = 0; + + status = NCONF_get_number_e(conf, group, name, &ret); + if (status == 0) { + /* This function does not believe in errors... */ + ERR_get_error(); + } + return ret; +} +#endif +/* conf_mall.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "crypto.h" +// #include "cryptlib.h" +// #include "conf.h" +#include "dso.h" +#include "x509.h" +#include "asn1.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +/* Load all OpenSSL builtin modules */ + +void OPENSSL_load_builtin_modules(void) +{ + /* Add builtin modules here */ + ASN1_add_oid_module(); +#ifndef OPENSSL_NO_ENGINE + ENGINE_add_conf_module(); +#endif + EVP_add_alg_module(); +} +/* conf_mod.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "crypto.h" +// #include "cryptlib.h" +// #include "conf.h" +// #include "dso.h" +// #include "x509.h" + +#define DSO_mod_init_name "OPENSSL_init" +#define DSO_mod_finish_name "OPENSSL_finish" + +/* + * This structure contains a data about supported modules. entries in this + * table correspond to either dynamic or static modules. + */ + +struct conf_module_st { + /* DSO of this module or NULL if static */ + DSO *dso; + /* Name of the module */ + char *name; + /* Init function */ + conf_init_func *init; + /* Finish function */ + conf_finish_func *finish; + /* Number of successfully initialized modules */ + int links; + void *usr_data; +}; + +/* + * This structure contains information about modules that have been + * successfully initialized. There may be more than one entry for a given + * module. + */ + +struct conf_imodule_st { + CONF_MODULE *pmod; + char *name; + char *value; + unsigned long flags; + void *usr_data; +}; + +static STACK_OF(CONF_MODULE) *supported_modules = NULL; +static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; + +static void module_free(CONF_MODULE *md); +static void module_finish(CONF_IMODULE *imod); +static int module_run(const CONF *cnf, char *name, char *value, + unsigned long flags); +static CONF_MODULE *module_add(DSO *dso, const char *name, + conf_init_func *ifunc, + conf_finish_func *ffunc); +static CONF_MODULE *module_find(char *name); +static int module_init(CONF_MODULE *pmod, char *name, char *value, + const CONF *cnf); +static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value, + unsigned long flags); + +/* Main function: load modules from a CONF structure */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags) +{ + STACK_OF(CONF_VALUE) *values; + CONF_VALUE *vl; + char *vsection = NULL; + + int ret, i; + + if (!cnf) + return 1; + + if (appname) + vsection = NCONF_get_string(cnf, NULL, appname); + + if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION))) + vsection = NCONF_get_string(cnf, NULL, "openssl_conf"); + + if (!vsection) { + ERR_clear_error(); + return 1; + } + + values = NCONF_get_section(cnf, vsection); + + if (!values) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + vl = sk_CONF_VALUE_value(values, i); + ret = module_run(cnf, vl->name, vl->value, flags); + if (ret <= 0) + if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) + return ret; + } + + return 1; + +} + +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags) +{ + char *file = NULL; + CONF *conf = NULL; + int ret = 0; + conf = NCONF_new(NULL); + if (!conf) + goto err; + + if (filename == NULL) { + file = CONF_get1_default_config_file(); + if (!file) + goto err; + } else + file = (char *)filename; + + if (NCONF_load(conf, file, NULL) <= 0) { + if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) && + (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) { + ERR_clear_error(); + ret = 1; + } + goto err; + } + + ret = CONF_modules_load(conf, appname, flags); + + err: + if (filename == NULL) + OPENSSL_free(file); + NCONF_free(conf); + + return ret; +} + +static int module_run(const CONF *cnf, char *name, char *value, + unsigned long flags) +{ + CONF_MODULE *md; + int ret; + + md = module_find(name); + + /* Module not found: try to load DSO */ + if (!md && !(flags & CONF_MFLAGS_NO_DSO)) + md = module_load_dso(cnf, name, value, flags); + + if (!md) { + if (!(flags & CONF_MFLAGS_SILENT)) { + CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME); + ERR_add_error_data(2, "module=", name); + } + return -1; + } + + ret = module_init(md, name, value, cnf); + + if (ret <= 0) { + if (!(flags & CONF_MFLAGS_SILENT)) { + char rcode[DECIMAL_SIZE(ret) + 1]; + CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR); + BIO_snprintf(rcode, sizeof(rcode), "%-8d", ret); + ERR_add_error_data(6, "module=", name, ", value=", value, + ", retcode=", rcode); + } + } + + return ret; +} + +/* Load a module from a DSO */ +static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value, + unsigned long flags) +{ + DSO *dso = NULL; + conf_init_func *ifunc; + conf_finish_func *ffunc; + char *path = NULL; + int errcode = 0; + CONF_MODULE *md; + /* Look for alternative path in module section */ + path = NCONF_get_string(cnf, value, "path"); + if (!path) { + ERR_clear_error(); + path = name; + } + dso = DSO_load(NULL, path, NULL, 0); + if (!dso) { + errcode = CONF_R_ERROR_LOADING_DSO; + goto err; + } + ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name); + if (!ifunc) { + errcode = CONF_R_MISSING_INIT_FUNCTION; + goto err; + } + ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name); + /* All OK, add module */ + md = module_add(dso, name, ifunc, ffunc); + + if (!md) + goto err; + + return md; + + err: + if (dso) + DSO_free(dso); + CONFerr(CONF_F_MODULE_LOAD_DSO, errcode); + ERR_add_error_data(4, "module=", name, ", path=", path); + return NULL; +} + +/* add module to list */ +static CONF_MODULE *module_add(DSO *dso, const char *name, + conf_init_func *ifunc, conf_finish_func *ffunc) +{ + CONF_MODULE *tmod = NULL; + if (supported_modules == NULL) + supported_modules = sk_CONF_MODULE_new_null(); + if (supported_modules == NULL) + return NULL; + tmod = OPENSSL_malloc(sizeof(CONF_MODULE)); + if (tmod == NULL) + return NULL; + + tmod->dso = dso; + tmod->name = BUF_strdup(name); + if (tmod->name == NULL) { + OPENSSL_free(tmod); + return NULL; + } + tmod->init = ifunc; + tmod->finish = ffunc; + tmod->links = 0; + + if (!sk_CONF_MODULE_push(supported_modules, tmod)) { + OPENSSL_free(tmod); + return NULL; + } + + return tmod; +} + +/* + * Find a module from the list. We allow module names of the form + * modname.XXXX to just search for modname to allow the same module to be + * initialized more than once. + */ + +static CONF_MODULE *module_find(char *name) +{ + CONF_MODULE *tmod; + int i, nchar; + char *p; + p = strrchr(name, '.'); + + if (p) + nchar = p - name; + else + nchar = strlen(name); + + for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) { + tmod = sk_CONF_MODULE_value(supported_modules, i); + if (!strncmp(tmod->name, name, nchar)) + return tmod; + } + + return NULL; + +} + +/* initialize a module */ +static int module_init(CONF_MODULE *pmod, char *name, char *value, + const CONF *cnf) +{ + int ret = 1; + int init_called = 0; + CONF_IMODULE *imod = NULL; + + /* Otherwise add initialized module to list */ + imod = OPENSSL_malloc(sizeof(CONF_IMODULE)); + if (!imod) + goto err; + + imod->pmod = pmod; + imod->name = BUF_strdup(name); + imod->value = BUF_strdup(value); + imod->usr_data = NULL; + + if (!imod->name || !imod->value) + goto memerr; + + /* Try to initialize module */ + if (pmod->init) { + ret = pmod->init(imod, cnf); + init_called = 1; + /* Error occurred, exit */ + if (ret <= 0) + goto err; + } + + if (initialized_modules == NULL) { + initialized_modules = sk_CONF_IMODULE_new_null(); + if (!initialized_modules) { + CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (!sk_CONF_IMODULE_push(initialized_modules, imod)) { + CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); + goto err; + } + + pmod->links++; + + return ret; + + err: + + /* We've started the module so we'd better finish it */ + if (pmod->finish && init_called) + pmod->finish(imod); + + memerr: + if (imod) { + if (imod->name) + OPENSSL_free(imod->name); + if (imod->value) + OPENSSL_free(imod->value); + OPENSSL_free(imod); + } + + return -1; + +} + +/* + * Unload any dynamic modules that have a link count of zero: i.e. have no + * active initialized modules. If 'all' is set then all modules are unloaded + * including static ones. + */ + +void CONF_modules_unload(int all) +{ + int i; + CONF_MODULE *md; + CONF_modules_finish(); + /* unload modules in reverse order */ + for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) { + md = sk_CONF_MODULE_value(supported_modules, i); + /* If static or in use and 'all' not set ignore it */ + if (((md->links > 0) || !md->dso) && !all) + continue; + /* Since we're working in reverse this is OK */ + (void)sk_CONF_MODULE_delete(supported_modules, i); + module_free(md); + } + if (sk_CONF_MODULE_num(supported_modules) == 0) { + sk_CONF_MODULE_free(supported_modules); + supported_modules = NULL; + } +} + +/* unload a single module */ +static void module_free(CONF_MODULE *md) +{ + if (md->dso) + DSO_free(md->dso); + OPENSSL_free(md->name); + OPENSSL_free(md); +} + +/* finish and free up all modules instances */ + +void CONF_modules_finish(void) +{ + CONF_IMODULE *imod; + while (sk_CONF_IMODULE_num(initialized_modules) > 0) { + imod = sk_CONF_IMODULE_pop(initialized_modules); + module_finish(imod); + } + sk_CONF_IMODULE_free(initialized_modules); + initialized_modules = NULL; +} + +/* finish a module instance */ + +static void module_finish(CONF_IMODULE *imod) +{ + if (imod->pmod->finish) + imod->pmod->finish(imod); + imod->pmod->links--; + OPENSSL_free(imod->name); + OPENSSL_free(imod->value); + OPENSSL_free(imod); +} + +/* Add a static module to OpenSSL */ + +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc) +{ + if (module_add(NULL, name, ifunc, ffunc)) + return 1; + else + return 0; +} + +void CONF_modules_free(void) +{ + CONF_modules_finish(); + CONF_modules_unload(1); +} + +/* Utility functions */ + +const char *CONF_imodule_get_name(const CONF_IMODULE *md) +{ + return md->name; +} + +const char *CONF_imodule_get_value(const CONF_IMODULE *md) +{ + return md->value; +} + +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md) +{ + return md->usr_data; +} + +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data) +{ + md->usr_data = usr_data; +} + +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md) +{ + return md->pmod; +} + +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md) +{ + return md->flags; +} + +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags) +{ + md->flags = flags; +} + +void *CONF_module_get_usr_data(CONF_MODULE *pmod) +{ + return pmod->usr_data; +} + +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data) +{ + pmod->usr_data = usr_data; +} + +/* Return default config file name */ + +char *CONF_get1_default_config_file(void) +{ + char *file; + int len; + + file = ossl_safe_getenv("OPENSSL_CONF"); + if (file) + return BUF_strdup(file); + + len = strlen(X509_get_default_cert_area()); +#ifndef OPENSSL_SYS_VMS + len++; +#endif + len += strlen(OPENSSL_CONF); + + file = OPENSSL_malloc(len + 1); + + if (!file) + return NULL; + BUF_strlcpy(file, X509_get_default_cert_area(), len + 1); +#ifndef OPENSSL_SYS_VMS + BUF_strlcat(file, "/", len + 1); +#endif + BUF_strlcat(file, OPENSSL_CONF, len + 1); + + return file; +} + +/* + * This function takes a list separated by 'sep' and calls the callback + * function giving the start and length of each member optionally stripping + * leading and trailing whitespace. This can be used to parse comma separated + * lists for example. + */ + +int CONF_parse_list(const char *list_, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg) +{ + int ret; + const char *lstart, *tmpend, *p; + + if (list_ == NULL) { + CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL); + return 0; + } + + lstart = list_; + for (;;) { + if (nospc) { + while (*lstart && isspace((unsigned char)*lstart)) + lstart++; + } + p = strchr(lstart, sep); + if (p == lstart || !*lstart) + ret = list_cb(NULL, 0, arg); + else { + if (p) + tmpend = p - 1; + else + tmpend = lstart + strlen(lstart) - 1; + if (nospc) { + while (isspace((unsigned char)*tmpend)) + tmpend--; + } + ret = list_cb(lstart, tmpend - lstart + 1, arg); + } + if (ret <= 0) + return ret; + if (p == NULL) + return 1; + lstart = p + 1; + } +} +/* conf_sap.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "crypto.h" +// #include "cryptlib.h" +// #include "conf.h" +// #include "dso.h" +// #include "x509.h" +// #include "asn1.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +/* + * This is the automatic configuration loader: it is called automatically by + * OpenSSL when any of a number of standard initialisation functions are + * called, unless this is overridden by calling OPENSSL_no_config() + */ + +static int openssl_configured = 0; + +void OPENSSL_config(const char *config_name) +{ + if (openssl_configured) + return; + + OPENSSL_load_builtin_modules(); +#ifndef OPENSSL_NO_ENGINE + /* Need to load ENGINEs */ + ENGINE_load_builtin_engines(); +#endif + ERR_clear_error(); + CONF_modules_load_file(NULL, config_name, + CONF_MFLAGS_DEFAULT_SECTION | + CONF_MFLAGS_IGNORE_MISSING_FILE); + openssl_configured = 1; +} + +void OPENSSL_no_config() +{ + openssl_configured = 1; +} diff --git a/Sources/COpenSSL/conf_api.h b/Sources/COpenSSL/conf_api.h new file mode 100644 index 00000000..66a0eeac --- /dev/null +++ b/Sources/COpenSSL/conf_api.h @@ -0,0 +1,89 @@ +/* conf_api.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_API_H +# define HEADER_CONF_API_H + +# include "lhash.h" +# include "conf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name); +long _CONF_get_number(const CONF *conf, const char *section, + const char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/conf_def.h b/Sources/COpenSSL/conf_def.h new file mode 100644 index 00000000..48b34421 --- /dev/null +++ b/Sources/COpenSSL/conf_def.h @@ -0,0 +1,181 @@ +/* crypto/conf/conf_def.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * THIS FILE WAS AUTOMAGICALLY GENERATED! Please modify and use keysets.pl to + * regenerate it. + */ + +#define CONF_NUMBER 1 +#define CONF_UPPER 2 +#define CONF_LOWER 4 +#define CONF_UNDER 256 +#define CONF_PUNCTUATION 512 +#define CONF_WS 16 +#define CONF_ESC 32 +#define CONF_QUOTE 64 +#define CONF_DQUOTE 1024 +#define CONF_COMMENT 128 +#define CONF_FCOMMENT 2048 +#define CONF_EOF 8 +#define CONF_HIGHBIT 4096 +#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) +#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) +#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \ + CONF_PUNCTUATION) + +#define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) +#ifndef CHARSET_EBCDIC +# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) +# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) +# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) +# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) +# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) +# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) +# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) +# define IS_ALPHA_NUMERIC_PUNCT(c,a) \ + (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) +# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) +# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) + +#else /*CHARSET_EBCDIC*/ + +# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT) +# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT) +# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF) +# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC) +# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER) +# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS) +# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC) +# define IS_ALPHA_NUMERIC_PUNCT(c,a) \ + (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE) +# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE) +# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT) +#endif /*CHARSET_EBCDIC*/ + +static unsigned short CONF_type_default[256] = { + 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040, + 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, + 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100, + 0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, +}; + +static unsigned short CONF_type_win32[256] = { + 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000, + 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200, + 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100, + 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, +}; diff --git a/Sources/COpenSSL/constant_time_locl.h b/Sources/COpenSSL/constant_time_locl.h new file mode 100644 index 00000000..c786aea9 --- /dev/null +++ b/Sources/COpenSSL/constant_time_locl.h @@ -0,0 +1,211 @@ +/* crypto/constant_time_locl.h */ +/*- + * Utilities for constant-time cryptography. + * + * Author: Emilia Kasper (emilia@openssl.org) + * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley + * (Google). + * ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONSTANT_TIME_LOCL_H +# define HEADER_CONSTANT_TIME_LOCL_H + +# include "e_os.h" /* For 'inline' */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * The boolean methods return a bitmask of all ones (0xff...f) for true + * and 0 for false. This is useful for choosing a value based on the result + * of a conditional in constant time. For example, + * + * if (a < b) { + * c = a; + * } else { + * c = b; + * } + * + * can be written as + * + * unsigned int lt = constant_time_lt(a, b); + * c = constant_time_select(lt, a, b); + */ + +/* + * Returns the given value with the MSB copied to all the other + * bits. Uses the fact that arithmetic shift shifts-in the sign bit. + * However, this is not ensured by the C standard so you may need to + * replace this with something else on odd CPUs. + */ +static inline unsigned int constant_time_msb(unsigned int a); + +/* + * Returns 0xff..f if a < b and 0 otherwise. + */ +static inline unsigned int constant_time_lt(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_lt_8(unsigned int a, + unsigned int b); + +/* + * Returns 0xff..f if a >= b and 0 otherwise. + */ +static inline unsigned int constant_time_ge(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_ge_8(unsigned int a, + unsigned int b); + +/* + * Returns 0xff..f if a == 0 and 0 otherwise. + */ +static inline unsigned int constant_time_is_zero(unsigned int a); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_is_zero_8(unsigned int a); + +/* + * Returns 0xff..f if a == b and 0 otherwise. + */ +static inline unsigned int constant_time_eq(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_eq_8(unsigned int a, + unsigned int b); +/* Signed integers. */ +static inline unsigned int constant_time_eq_int(int a, int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_eq_int_8(int a, int b); + +/*- + * Returns (mask & a) | (~mask & b). + * + * When |mask| is all 1s or all 0s (as returned by the methods above), + * the select methods return either |a| (if |mask| is nonzero) or |b| + * (if |mask| is zero). + */ +static inline unsigned int constant_time_select(unsigned int mask, + unsigned int a, + unsigned int b); +/* Convenience method for unsigned chars. */ +static inline unsigned char constant_time_select_8(unsigned char mask, + unsigned char a, + unsigned char b); +/* Convenience method for signed integers. */ +static inline int constant_time_select_int(unsigned int mask, int a, int b); + +static inline unsigned int constant_time_msb(unsigned int a) +{ + return 0 - (a >> (sizeof(a) * 8 - 1)); +} + +static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) +{ + return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); +} + +static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_lt(a, b)); +} + +static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) +{ + return ~constant_time_lt(a, b); +} + +static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_ge(a, b)); +} + +static inline unsigned int constant_time_is_zero(unsigned int a) +{ + return constant_time_msb(~a & (a - 1)); +} + +static inline unsigned char constant_time_is_zero_8(unsigned int a) +{ + return (unsigned char)(constant_time_is_zero(a)); +} + +static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) +{ + return constant_time_is_zero(a ^ b); +} + +static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_eq(a, b)); +} + +static inline unsigned int constant_time_eq_int(int a, int b) +{ + return constant_time_eq((unsigned)(a), (unsigned)(b)); +} + +static inline unsigned char constant_time_eq_int_8(int a, int b) +{ + return constant_time_eq_8((unsigned)(a), (unsigned)(b)); +} + +static inline unsigned int constant_time_select(unsigned int mask, + unsigned int a, + unsigned int b) +{ + return (mask & a) | (~mask & b); +} + +static inline unsigned char constant_time_select_8(unsigned char mask, + unsigned char a, + unsigned char b) +{ + return (unsigned char)(constant_time_select(mask, a, b)); +} + +static inline int constant_time_select_int(unsigned int mask, int a, int b) +{ + return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); +} + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_CONSTANT_TIME_LOCL_H */ diff --git a/Sources/COpenSSL/cpt_err.c b/Sources/COpenSSL/cpt_err.c new file mode 100644 index 00000000..71d6385a --- /dev/null +++ b/Sources/COpenSSL/cpt_err.c @@ -0,0 +1,104 @@ +/* crypto/cpt_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "crypto.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason) + +static ERR_STRING_DATA CRYPTO_str_functs[] = { + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX), "CRYPTO_get_ex_new_index"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID), "CRYPTO_get_new_dynlockid"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_LOCKID), "CRYPTO_get_new_lockid"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA), "CRYPTO_set_ex_data"}, + {ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX), "DEF_ADD_INDEX"}, + {ERR_FUNC(CRYPTO_F_DEF_GET_CLASS), "DEF_GET_CLASS"}, + {ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"}, + {ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA), "INT_DUP_EX_DATA"}, + {ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA), "INT_FREE_EX_DATA"}, + {ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA), "INT_NEW_EX_DATA"}, + {0, NULL} +}; + +static ERR_STRING_DATA CRYPTO_str_reasons[] = { + {ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK), + "no dynlock create callback"}, + {0, NULL} +}; + +#endif + +void ERR_load_CRYPTO_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) { + ERR_load_strings(0, CRYPTO_str_functs); + ERR_load_strings(0, CRYPTO_str_reasons); + } +#endif +} diff --git a/Sources/COpenSSL/cryptlib.c b/Sources/COpenSSL/cryptlib.c new file mode 100644 index 00000000..e85e1ba0 --- /dev/null +++ b/Sources/COpenSSL/cryptlib.c @@ -0,0 +1,1037 @@ +/* crypto/cryptlib.c */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include "cryptlib.h" +#include "safestack.h" + +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) +static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */ +#endif + +DECLARE_STACK_OF(CRYPTO_dynlock) + +/* real #defines in crypto.h, keep these upto date */ +static const char *const lock_names[CRYPTO_NUM_LOCKS] = { + "<>", + "err", + "ex_data", + "x509", + "x509_info", + "x509_pkey", + "x509_crl", + "x509_req", + "dsa", + "rsa", + "evp_pkey", + "x509_store", + "ssl_ctx", + "ssl_cert", + "ssl_session", + "ssl_sess_cert", + "ssl", + "ssl_method", + "rand", + "rand2", + "debug_malloc", + "BIO", + "gethostbyname", + "getservbyname", + "readdir", + "RSA_blinding", + "dh", + "debug_malloc2", + "dso", + "dynlock", + "engine", + "ui", + "ecdsa", + "ec", + "ecdh", + "bn", + "ec_pre_comp", + "store", + "comp", + "fips", + "fips2", +#if CRYPTO_NUM_LOCKS != 41 +# error "Inconsistency between crypto.h and cryptlib.c" +#endif +}; + +/* + * This is for applications to allocate new type names in the non-dynamic + * array of lock names. These are numbered with positive numbers. + */ +static STACK_OF(OPENSSL_STRING) *app_locks = NULL; + +/* + * For applications that want a more dynamic way of handling threads, the + * following stack is used. These are externally numbered with negative + * numbers. + */ +static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL; + +static void (MS_FAR *locking_callback) (int mode, int type, + const char *file, int line) = 0; +static int (MS_FAR *add_lock_callback) (int *pointer, int amount, + int type, const char *file, + int line) = 0; +#ifndef OPENSSL_NO_DEPRECATED +static unsigned long (MS_FAR *id_callback) (void) = 0; +#endif +static void (MS_FAR *threadid_callback) (CRYPTO_THREADID *) = 0; +static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) + (const char *file, int line) = 0; +static void (MS_FAR *dynlock_lock_callback) (int mode, + struct CRYPTO_dynlock_value *l, + const char *file, int line) = 0; +static void (MS_FAR *dynlock_destroy_callback) (struct CRYPTO_dynlock_value + *l, const char *file, + int line) = 0; + +int CRYPTO_get_new_lockid(char *name) +{ + char *str; + int i; + +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) + /* + * A hack to make Visual C++ 5.0 work correctly when linking as a DLL + * using /MT. Without this, the application cannot use any floating point + * printf's. It also seems to be needed for Visual C 1.5 (win16) + */ + SSLeay_MSVC5_hack = (double)name[0] * (double)name[1]; +#endif + + if ((app_locks == NULL) + && ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + if ((str = BUF_strdup(name)) == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + i = sk_OPENSSL_STRING_push(app_locks, str); + if (!i) + OPENSSL_free(str); + else + i += CRYPTO_NUM_LOCKS; /* gap of one :-) */ + return (i); +} + +int CRYPTO_num_locks(void) +{ + return CRYPTO_NUM_LOCKS; +} + +int CRYPTO_get_new_dynlockid(void) +{ + int i = 0; + CRYPTO_dynlock *pointer = NULL; + + if (dynlock_create_callback == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, + CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); + return (0); + } + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + if ((dyn_locks == NULL) + && ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) { + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + pointer = (CRYPTO_dynlock *) OPENSSL_malloc(sizeof(CRYPTO_dynlock)); + if (pointer == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + pointer->references = 1; + pointer->data = dynlock_create_callback(__FILE__, __LINE__); + if (pointer->data == NULL) { + OPENSSL_free(pointer); + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + /* First, try to find an existing empty slot */ + i = sk_CRYPTO_dynlock_find(dyn_locks, NULL); + /* If there was none, push, thereby creating a new one */ + if (i == -1) + /* + * Since sk_push() returns the number of items on the stack, not the + * location of the pushed item, we need to transform the returned + * number into a position, by decreasing it. + */ + i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1; + else + /* + * If we found a place with a NULL pointer, put our pointer in it. + */ + (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer); + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (i == -1) { + dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); + OPENSSL_free(pointer); + } else + i += 1; /* to avoid 0 */ + return -i; +} + +void CRYPTO_destroy_dynlockid(int i) +{ + CRYPTO_dynlock *pointer = NULL; + if (i) + i = -i - 1; + if (dynlock_destroy_callback == NULL) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + + if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) { + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + return; + } + pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); + if (pointer != NULL) { + --pointer->references; +#ifdef REF_CHECK + if (pointer->references < 0) { + fprintf(stderr, + "CRYPTO_destroy_dynlockid, bad reference count\n"); + abort(); + } else +#endif + if (pointer->references <= 0) { + (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); + } else + pointer = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (pointer) { + dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); + OPENSSL_free(pointer); + } +} + +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) +{ + CRYPTO_dynlock *pointer = NULL; + if (i) + i = -i - 1; + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + + if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) + pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); + if (pointer) + pointer->references++; + + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (pointer) + return pointer->data; + return NULL; +} + +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) + (const char *file, int line) { + return (dynlock_create_callback); +} + +void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode, + struct CRYPTO_dynlock_value + *l, const char *file, + int line) { + return (dynlock_lock_callback); +} + +void (*CRYPTO_get_dynlock_destroy_callback(void)) + (struct CRYPTO_dynlock_value *l, const char *file, int line) { + return (dynlock_destroy_callback); +} + +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) + (const char *file, int line)) +{ + dynlock_create_callback = func; +} + +void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode, + struct + CRYPTO_dynlock_value *l, + const char *file, + int line)) +{ + dynlock_lock_callback = func; +} + +void CRYPTO_set_dynlock_destroy_callback(void (*func) + (struct CRYPTO_dynlock_value *l, + const char *file, int line)) +{ + dynlock_destroy_callback = func; +} + +void (*CRYPTO_get_locking_callback(void)) (int mode, int type, + const char *file, int line) { + return (locking_callback); +} + +int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type, + const char *file, int line) { + return (add_lock_callback); +} + +void CRYPTO_set_locking_callback(void (*func) (int mode, int type, + const char *file, int line)) +{ + /* + * Calling this here ensures initialisation before any threads are + * started. + */ + OPENSSL_init(); + locking_callback = func; +} + +void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type, + const char *file, int line)) +{ + add_lock_callback = func; +} + +/* + * the memset() here and in set_pointer() seem overkill, but for the sake of + * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause + * two "equal" THREADID structs to not be memcmp()-identical. + */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) +{ + memset(id, 0, sizeof(*id)); + id->val = val; +} + +static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 }; + +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) +{ + unsigned char *dest = (void *)&id->val; + unsigned int accum = 0; + unsigned char dnum = sizeof(id->val); + + memset(id, 0, sizeof(*id)); + id->ptr = ptr; + if (sizeof(id->val) >= sizeof(id->ptr)) { + /* + * 'ptr' can be embedded in 'val' without loss of uniqueness + */ + id->val = (unsigned long)id->ptr; + return; + } + /* + * hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a + * linear function over the bytes in 'ptr', the co-efficients of which + * are a sequence of low-primes (hash_coeffs is an 8-element cycle) - the + * starting prime for the sequence varies for each byte of 'val' (unique + * polynomials unless pointers are >64-bit). For added spice, the totals + * accumulate rather than restarting from zero, and the index of the + * 'val' byte is added each time (position dependence). If I was a + * black-belt, I'd scan big-endian pointers in reverse to give low-order + * bits more play, but this isn't crypto and I'd prefer nobody mistake it + * as such. Plus I'm lazy. + */ + while (dnum--) { + const unsigned char *src = (void *)&id->ptr; + unsigned char snum = sizeof(id->ptr); + while (snum--) + accum += *(src++) * hash_coeffs[(snum + dnum) & 7]; + accum += dnum; + *(dest++) = accum & 255; + } +} + +#ifdef OPENSSL_FIPS +extern int FIPS_crypto_threadid_set_callback(void (*func) (CRYPTO_THREADID *)); +#endif + +int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *)) +{ + if (threadid_callback) + return 0; + threadid_callback = func; +#ifdef OPENSSL_FIPS + FIPS_crypto_threadid_set_callback(func); +#endif + return 1; +} + +void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *) { + return threadid_callback; +} + +void CRYPTO_THREADID_current(CRYPTO_THREADID *id) +{ + if (threadid_callback) { + threadid_callback(id); + return; + } +#ifndef OPENSSL_NO_DEPRECATED + /* If the deprecated callback was set, fall back to that */ + if (id_callback) { + CRYPTO_THREADID_set_numeric(id, id_callback()); + return; + } +#endif + /* Else pick a backup */ +#ifdef OPENSSL_SYS_WIN16 + CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask()); +#elif defined(OPENSSL_SYS_WIN32) + CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId()); +#elif defined(OPENSSL_SYS_BEOS) + CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL)); +#else + /* For everything else, default to using the address of 'errno' */ + CRYPTO_THREADID_set_pointer(id, (void *)&errno); +#endif +} + +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b) +{ + return memcmp(a, b, sizeof(*a)); +} + +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src) +{ + memcpy(dest, src, sizeof(*src)); +} + +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) +{ + return id->val; +} + +#ifndef OPENSSL_NO_DEPRECATED +unsigned long (*CRYPTO_get_id_callback(void)) (void) { + return (id_callback); +} + +void CRYPTO_set_id_callback(unsigned long (*func) (void)) +{ + id_callback = func; +} + +unsigned long CRYPTO_thread_id(void) +{ + unsigned long ret = 0; + + if (id_callback == NULL) { +# ifdef OPENSSL_SYS_WIN16 + ret = (unsigned long)GetCurrentTask(); +# elif defined(OPENSSL_SYS_WIN32) + ret = (unsigned long)GetCurrentThreadId(); +# elif defined(GETPID_IS_MEANINGLESS) + ret = 1L; +# elif defined(OPENSSL_SYS_BEOS) + ret = (unsigned long)find_thread(NULL); +# else + ret = (unsigned long)getpid(); +# endif + } else + ret = id_callback(); + return (ret); +} +#endif + +void CRYPTO_lock(int mode, int type, const char *file, int line) +{ +#ifdef LOCK_DEBUG + { + CRYPTO_THREADID id; + char *rw_text, *operation_text; + + if (mode & CRYPTO_LOCK) + operation_text = "lock "; + else if (mode & CRYPTO_UNLOCK) + operation_text = "unlock"; + else + operation_text = "ERROR "; + + if (mode & CRYPTO_READ) + rw_text = "r"; + else if (mode & CRYPTO_WRITE) + rw_text = "w"; + else + rw_text = "ERROR"; + + CRYPTO_THREADID_current(&id); + fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n", + CRYPTO_THREADID_hash(&id), rw_text, operation_text, + CRYPTO_get_lock_name(type), file, line); + } +#endif + if (type < 0) { + if (dynlock_lock_callback != NULL) { + struct CRYPTO_dynlock_value *pointer + = CRYPTO_get_dynlock_value(type); + + OPENSSL_assert(pointer != NULL); + + dynlock_lock_callback(mode, pointer, file, line); + + CRYPTO_destroy_dynlockid(type); + } + } else if (locking_callback != NULL) + locking_callback(mode, type, file, line); +} + +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line) +{ + int ret = 0; + + if (add_lock_callback != NULL) { +#ifdef LOCK_DEBUG + int before = *pointer; +#endif + + ret = add_lock_callback(pointer, amount, type, file, line); +#ifdef LOCK_DEBUG + { + CRYPTO_THREADID id; + CRYPTO_THREADID_current(&id); + fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", + CRYPTO_THREADID_hash(&id), before, amount, ret, + CRYPTO_get_lock_name(type), file, line); + } +#endif + } else { + CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line); + + ret = *pointer + amount; +#ifdef LOCK_DEBUG + { + CRYPTO_THREADID id; + CRYPTO_THREADID_current(&id); + fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", + CRYPTO_THREADID_hash(&id), + *pointer, amount, ret, + CRYPTO_get_lock_name(type), file, line); + } +#endif + *pointer = ret; + CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line); + } + return (ret); +} + +const char *CRYPTO_get_lock_name(int type) +{ + if (type < 0) + return ("dynamic"); + else if (type < CRYPTO_NUM_LOCKS) + return (lock_names[type]); + else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks)) + return ("ERROR"); + else + return (sk_OPENSSL_STRING_value(app_locks, type - CRYPTO_NUM_LOCKS)); +} + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__INTEL__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) + +extern unsigned int OPENSSL_ia32cap_P[4]; +unsigned long *OPENSSL_ia32cap_loc(void) +{ + if (sizeof(long) == 4) + /* + * If 32-bit application pulls address of OPENSSL_ia32cap_P[0] + * clear second element to maintain the illusion that vector + * is 32-bit. + */ + OPENSSL_ia32cap_P[1] = 0; + + OPENSSL_ia32cap_P[2] = 0; + + return (unsigned long *)OPENSSL_ia32cap_P; +} + +# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) +# define OPENSSL_CPUID_SETUP +# if defined(_WIN32) +typedef unsigned __int64 IA32CAP; +# else +typedef unsigned long long IA32CAP; +# endif +void OPENSSL_cpuid_setup(void) +{ + static int trigger = 0; + IA32CAP OPENSSL_ia32_cpuid(unsigned int *); + IA32CAP vec; + char *env; + + if (trigger) + return; + + trigger = 1; + if ((env = getenv("OPENSSL_ia32cap"))) { + int off = (env[0] == '~') ? 1 : 0; +# if defined(_WIN32) + if (!sscanf(env + off, "%I64i", &vec)) + vec = strtoul(env + off, NULL, 0); +# else + if (!sscanf(env + off, "%lli", (long long *)&vec)) + vec = strtoul(env + off, NULL, 0); +# endif + if (off) + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec; + else if (env[0] == ':') + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); + + OPENSSL_ia32cap_P[2] = 0; + if ((env = strchr(env, ':'))) { + unsigned int vecx; + env++; + off = (env[0] == '~') ? 1 : 0; + vecx = strtoul(env + off, NULL, 0); + if (off) + OPENSSL_ia32cap_P[2] &= ~vecx; + else + OPENSSL_ia32cap_P[2] = vecx; + } + } else + vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); + + /* + * |(1<<10) sets a reserved bit to signal that variable + * was initialized already... This is to avoid interference + * with cpuid snippets in ELF .init segment. + */ + OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10); + OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32); +} +# else +unsigned int OPENSSL_ia32cap_P[4]; +# endif + +#else +unsigned long *OPENSSL_ia32cap_loc(void) +{ + return NULL; +} +#endif +int OPENSSL_NONPIC_relocated = 0; +#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) +void OPENSSL_cpuid_setup(void) +{ +} +#endif + +#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) +# ifdef __CYGWIN__ +/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ +# include +/* + * this has side-effect of _WIN32 getting defined, which otherwise is + * mutually exclusive with __CYGWIN__... + */ +# endif + +/* + * All we really need to do is remove the 'error' state when a thread + * detaches + */ + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + OPENSSL_cpuid_setup(); +# if defined(_WIN32_WINNT) + { + IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL; + IMAGE_NT_HEADERS *nt_headers; + + if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) { + nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header + + dos_header->e_lfanew); + if (nt_headers->Signature == IMAGE_NT_SIGNATURE && + hinstDLL != + (HINSTANCE) (nt_headers->OptionalHeader.ImageBase)) + OPENSSL_NONPIC_relocated = 1; + } + } +# endif + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + break; + } + return (TRUE); +} +#endif + +#if defined(_WIN32) && !defined(__CYGWIN__) +# include +# include +# ifdef __WATCOMC__ +# if defined(_UNICODE) || defined(__UNICODE__) +# define _vsntprintf _vsnwprintf +# else +# define _vsntprintf _vsnprintf +# endif +# endif +# ifdef _MSC_VER +# define alloca _alloca +# endif + +# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 +int OPENSSL_isservice(void) +{ + HWINSTA h; + DWORD len; + WCHAR *name; + static union { + void *p; + int (*f) (void); + } _OPENSSL_isservice = { + NULL + }; + + if (_OPENSSL_isservice.p == NULL) { + HANDLE h = GetModuleHandle(NULL); + if (h != NULL) + _OPENSSL_isservice.p = GetProcAddress(h, "_OPENSSL_isservice"); + if (_OPENSSL_isservice.p == NULL) + _OPENSSL_isservice.p = (void *)-1; + } + + if (_OPENSSL_isservice.p != (void *)-1) + return (*_OPENSSL_isservice.f) (); + + h = GetProcessWindowStation(); + if (h == NULL) + return -1; + + if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) || + GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return -1; + + if (len > 512) + return -1; /* paranoia */ + len++, len &= ~1; /* paranoia */ + name = (WCHAR *)alloca(len + sizeof(WCHAR)); + if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len)) + return -1; + + len++, len &= ~1; /* paranoia */ + name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */ +# if 1 + /* + * This doesn't cover "interactive" services [working with real + * WinSta0's] nor programs started non-interactively by Task Scheduler + * [those are working with SAWinSta]. + */ + if (wcsstr(name, L"Service-0x")) + return 1; +# else + /* This covers all non-interactive programs such as services. */ + if (!wcsstr(name, L"WinSta0")) + return 1; +# endif + else + return 0; +} +# else +int OPENSSL_isservice(void) +{ + return 0; +} +# endif + +void OPENSSL_showfatal(const char *fmta, ...) +{ + va_list ap; + TCHAR buf[256]; + const TCHAR *fmt; +# ifdef STD_ERROR_HANDLE /* what a dirty trick! */ + HANDLE h; + + if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL && + GetFileType(h) != FILE_TYPE_UNKNOWN) { + /* must be console application */ + int len; + DWORD out; + + va_start(ap, fmta); + len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap); + WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL); + va_end(ap); + return; + } +# endif + + if (sizeof(TCHAR) == sizeof(char)) + fmt = (const TCHAR *)fmta; + else + do { + int keepgoing; + size_t len_0 = strlen(fmta) + 1, i; + WCHAR *fmtw; + + fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR)); + if (fmtw == NULL) { + fmt = (const TCHAR *)L"no stack?"; + break; + } +# ifndef OPENSSL_NO_MULTIBYTE + if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0)) +# endif + for (i = 0; i < len_0; i++) + fmtw[i] = (WCHAR)fmta[i]; + + for (i = 0; i < len_0; i++) { + if (fmtw[i] == L'%') + do { + keepgoing = 0; + switch (fmtw[i + 1]) { + case L'0': + case L'1': + case L'2': + case L'3': + case L'4': + case L'5': + case L'6': + case L'7': + case L'8': + case L'9': + case L'.': + case L'*': + case L'-': + i++; + keepgoing = 1; + break; + case L's': + fmtw[i + 1] = L'S'; + break; + case L'S': + fmtw[i + 1] = L's'; + break; + case L'c': + fmtw[i + 1] = L'C'; + break; + case L'C': + fmtw[i + 1] = L'c'; + break; + } + } while (keepgoing); + } + fmt = (const TCHAR *)fmtw; + } while (0); + + va_start(ap, fmta); + _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap); + buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0'); + va_end(ap); + +# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 + /* this -------------v--- guards NT-specific calls */ + if (check_winnt() && OPENSSL_isservice() > 0) { + HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL")); + + if (hEventLog != NULL) { + const TCHAR *pmsg = buf; + + if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL, + 1, 0, &pmsg, NULL)) { +#if defined(DEBUG) + /* + * We are in a situation where we tried to report a critical + * error and this failed for some reason. As a last resort, + * in debug builds, send output to the debugger or any other + * tool like DebugView which can monitor the output. + */ + OutputDebugString(pmsg); +#endif + } + + (void)DeregisterEventSource(hEventLog); + } + } else +# endif + MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR); +} +#else +void OPENSSL_showfatal(const char *fmta, ...) +{ + va_list ap; + + va_start(ap, fmta); + vfprintf(stderr, fmta, ap); + va_end(ap); +} + +int OPENSSL_isservice(void) +{ + return 0; +} +#endif + +void OpenSSLDie(const char *file, int line, const char *assertion) +{ + OPENSSL_showfatal + ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line, + assertion); +#if !defined(_WIN32) || defined(__CYGWIN__) + abort(); +#else + /* + * Win32 abort() customarily shows a dialog, but we just did that... + */ +# if !defined(_WIN32_WCE) + raise(SIGABRT); +# endif + _exit(3); +#endif +} + +void *OPENSSL_stderr(void) +{ + return stderr; +} + +int CRYPTO_memcmp(const volatile void *in_a, const volatile void *in_b, size_t len) +{ + size_t i; + const volatile unsigned char *a = in_a; + const volatile unsigned char *b = in_b; + unsigned char x = 0; + + for (i = 0; i < len; i++) + x |= a[i] ^ b[i]; + + return x; +} diff --git a/Sources/COpenSSL/cryptlib.h b/Sources/COpenSSL/cryptlib.h new file mode 100644 index 00000000..ee9e58c3 --- /dev/null +++ b/Sources/COpenSSL/cryptlib.h @@ -0,0 +1,113 @@ +/* crypto/cryptlib.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CRYPTLIB_H +# define HEADER_CRYPTLIB_H + +# include +# include + +# include "e_os.h" + +# ifdef OPENSSL_USE_APPLINK +# define BIO_FLAGS_UPLINK 0x8000 +# include "ms/uplink.h" +# endif + +# include "crypto.h" +# include "buffer.h" +# include "bio.h" +# include "err.h" +# include "opensslconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_SYS_VMS +# define X509_CERT_AREA OPENSSLDIR +# define X509_CERT_DIR OPENSSLDIR "/certs" +# define X509_CERT_FILE OPENSSLDIR "/cert.pem" +# define X509_PRIVATE_DIR OPENSSLDIR "/private" +# else +# define X509_CERT_AREA "SSLROOT:[000000]" +# define X509_CERT_DIR "SSLCERTS:" +# define X509_CERT_FILE "SSLCERTS:cert.pem" +# define X509_PRIVATE_DIR "SSLPRIVATE:" +# endif + +# define X509_CERT_DIR_EVP "SSL_CERT_DIR" +# define X509_CERT_FILE_EVP "SSL_CERT_FILE" + +/* size of string representations */ +# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) +# define HEX_SIZE(type) (sizeof(type)*2) + +void OPENSSL_cpuid_setup(void); +extern unsigned int OPENSSL_ia32cap_P[]; +void OPENSSL_showfatal(const char *fmta, ...); +void *OPENSSL_stderr(void); +extern int OPENSSL_NONPIC_relocated; + +char *ossl_safe_getenv(const char *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/crypto.h b/Sources/COpenSSL/crypto.h new file mode 100644 index 00000000..e962ec3b --- /dev/null +++ b/Sources/COpenSSL/crypto.h @@ -0,0 +1,661 @@ +/* crypto/crypto.h */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_CRYPTO_H +# define HEADER_CRYPTO_H + +# include + +# include "e_os2.h" + +# ifndef OPENSSL_NO_FP_API +# include +# endif + +# include "stack.h" +# include "safestack.h" +# include "opensslv.h" +# include "ossl_typ.h" + +# ifdef CHARSET_EBCDIC +# include "ebcdic.h" +# endif + +/* + * Resolve problems on some operating systems with symbol names that clash + * one way or another + */ +# include "symhacks.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Backward compatibility to SSLeay */ +/* + * This is more to be used to check the correct DLL is being used in the MS + * world. + */ +# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +# define SSLEAY_VERSION 0 +/* #define SSLEAY_OPTIONS 1 no longer supported */ +# define SSLEAY_CFLAGS 2 +# define SSLEAY_BUILT_ON 3 +# define SSLEAY_PLATFORM 4 +# define SSLEAY_DIR 5 + +/* Already declared in ossl_typ.h */ +# if 0 +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Called when a new object is created */ +typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +/* Called when an object is free()ed */ +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +/* Called when we need to dup an object */ +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); +# endif + +/* A generic structure to pass assorted data in a expandable way */ +typedef struct openssl_item_st { + int code; + void *value; /* Not used for flag attributes */ + size_t value_size; /* Max size of value for output, length for + * input */ + size_t *value_length; /* Returned length of value for output */ +} OPENSSL_ITEM; + +/* + * When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock + * names in cryptlib.c + */ + +# define CRYPTO_LOCK_ERR 1 +# define CRYPTO_LOCK_EX_DATA 2 +# define CRYPTO_LOCK_X509 3 +# define CRYPTO_LOCK_X509_INFO 4 +# define CRYPTO_LOCK_X509_PKEY 5 +# define CRYPTO_LOCK_X509_CRL 6 +# define CRYPTO_LOCK_X509_REQ 7 +# define CRYPTO_LOCK_DSA 8 +# define CRYPTO_LOCK_RSA 9 +# define CRYPTO_LOCK_EVP_PKEY 10 +# define CRYPTO_LOCK_X509_STORE 11 +# define CRYPTO_LOCK_SSL_CTX 12 +# define CRYPTO_LOCK_SSL_CERT 13 +# define CRYPTO_LOCK_SSL_SESSION 14 +# define CRYPTO_LOCK_SSL_SESS_CERT 15 +# define CRYPTO_LOCK_SSL 16 +# define CRYPTO_LOCK_SSL_METHOD 17 +# define CRYPTO_LOCK_RAND 18 +# define CRYPTO_LOCK_RAND2 19 +# define CRYPTO_LOCK_MALLOC 20 +# define CRYPTO_LOCK_BIO 21 +# define CRYPTO_LOCK_GETHOSTBYNAME 22 +# define CRYPTO_LOCK_GETSERVBYNAME 23 +# define CRYPTO_LOCK_READDIR 24 +# define CRYPTO_LOCK_RSA_BLINDING 25 +# define CRYPTO_LOCK_DH 26 +# define CRYPTO_LOCK_MALLOC2 27 +# define CRYPTO_LOCK_DSO 28 +# define CRYPTO_LOCK_DYNLOCK 29 +# define CRYPTO_LOCK_ENGINE 30 +# define CRYPTO_LOCK_UI 31 +# define CRYPTO_LOCK_ECDSA 32 +# define CRYPTO_LOCK_EC 33 +# define CRYPTO_LOCK_ECDH 34 +# define CRYPTO_LOCK_BN 35 +# define CRYPTO_LOCK_EC_PRE_COMP 36 +# define CRYPTO_LOCK_STORE 37 +# define CRYPTO_LOCK_COMP 38 +# define CRYPTO_LOCK_FIPS 39 +# define CRYPTO_LOCK_FIPS2 40 +# define CRYPTO_NUM_LOCKS 41 + +# define CRYPTO_LOCK 1 +# define CRYPTO_UNLOCK 2 +# define CRYPTO_READ 4 +# define CRYPTO_WRITE 8 + +# ifndef OPENSSL_NO_LOCKING +# ifndef CRYPTO_w_lock +# define CRYPTO_w_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +# define CRYPTO_w_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +# define CRYPTO_r_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) +# define CRYPTO_r_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) +# define CRYPTO_add(addr,amount,type) \ + CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) +# endif +# else +# define CRYPTO_w_lock(a) +# define CRYPTO_w_unlock(a) +# define CRYPTO_r_lock(a) +# define CRYPTO_r_unlock(a) +# define CRYPTO_add(a,b,c) ((*(a))+=(b)) +# endif + +/* + * Some applications as well as some parts of OpenSSL need to allocate and + * deallocate locks in a dynamic fashion. The following typedef makes this + * possible in a type-safe manner. + */ +/* struct CRYPTO_dynlock_value has to be defined by the application. */ +typedef struct { + int references; + struct CRYPTO_dynlock_value *data; +} CRYPTO_dynlock; + +/* + * The following can be used to detect memory leaks in the SSLeay library. It + * used, it turns on malloc checking + */ + +# define CRYPTO_MEM_CHECK_OFF 0x0/* an enume */ +# define CRYPTO_MEM_CHECK_ON 0x1/* a bit */ +# define CRYPTO_MEM_CHECK_ENABLE 0x2/* a bit */ +# define CRYPTO_MEM_CHECK_DISABLE 0x3/* an enume */ + +/* + * The following are bit values to turn on or off options connected to the + * malloc checking functionality + */ + +/* Adds time to the memory checking information */ +# define V_CRYPTO_MDEBUG_TIME 0x1/* a bit */ +/* Adds thread number to the memory checking information */ +# define V_CRYPTO_MDEBUG_THREAD 0x2/* a bit */ + +# define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD) + +/* predec of the BIO type */ +typedef struct bio_st BIO_dummy; + +struct crypto_ex_data_st { + STACK_OF(void) *sk; + /* gcc is screwing up this data structure :-( */ + int dummy; +}; +DECLARE_STACK_OF(void) + +/* + * This stuff is basically class callback functions The current classes are + * SSL_CTX, SSL, SSL_SESSION, and a few more + */ + +typedef struct crypto_ex_data_func_st { + long argl; /* Arbitary long */ + void *argp; /* Arbitary void * */ + CRYPTO_EX_new *new_func; + CRYPTO_EX_free *free_func; + CRYPTO_EX_dup *dup_func; +} CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +/* + * Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA + * entry. + */ + +# define CRYPTO_EX_INDEX_BIO 0 +# define CRYPTO_EX_INDEX_SSL 1 +# define CRYPTO_EX_INDEX_SSL_CTX 2 +# define CRYPTO_EX_INDEX_SSL_SESSION 3 +# define CRYPTO_EX_INDEX_X509_STORE 4 +# define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +# define CRYPTO_EX_INDEX_RSA 6 +# define CRYPTO_EX_INDEX_DSA 7 +# define CRYPTO_EX_INDEX_DH 8 +# define CRYPTO_EX_INDEX_ENGINE 9 +# define CRYPTO_EX_INDEX_X509 10 +# define CRYPTO_EX_INDEX_UI 11 +# define CRYPTO_EX_INDEX_ECDSA 12 +# define CRYPTO_EX_INDEX_ECDH 13 +# define CRYPTO_EX_INDEX_COMP 14 +# define CRYPTO_EX_INDEX_STORE 15 + +/* + * Dynamically assigned indexes start from this value (don't use directly, + * use via CRYPTO_ex_data_new_class). + */ +# define CRYPTO_EX_INDEX_USER 100 + +/* + * This is the default callbacks, but we can have others as well: this is + * needed in Win32 where the application malloc and the library malloc may + * not be the same. + */ +# define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\ + malloc, realloc, free) + +# if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD +# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */ +# define CRYPTO_MDEBUG +# endif +# endif + +/* + * Set standard debugging functions (not done by default unless CRYPTO_MDEBUG + * is defined) + */ +# define CRYPTO_malloc_debug_init() do {\ + CRYPTO_set_mem_debug_functions(\ + CRYPTO_dbg_malloc,\ + CRYPTO_dbg_realloc,\ + CRYPTO_dbg_free,\ + CRYPTO_dbg_set_options,\ + CRYPTO_dbg_get_options);\ + } while(0) + +int CRYPTO_mem_ctrl(int mode); +int CRYPTO_is_mem_check_on(void); + +/* for applications */ +# define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) +# define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) + +/* for library-internal use */ +# define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) +# define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) +# define is_MemCheck_on() CRYPTO_is_mem_check_on() + +# define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) +# define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) +# define OPENSSL_realloc(addr,num) \ + CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) +# define OPENSSL_realloc_clean(addr,old_num,num) \ + CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__) +# define OPENSSL_remalloc(addr,num) \ + CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__) +# define OPENSSL_freeFunc CRYPTO_free +# define OPENSSL_free(addr) CRYPTO_free(addr) + +# define OPENSSL_malloc_locked(num) \ + CRYPTO_malloc_locked((int)num,__FILE__,__LINE__) +# define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) + +const char *SSLeay_version(int type); +unsigned long SSLeay(void); + +int OPENSSL_issetugid(void); + +/* An opaque type representing an implementation of "ex_data" support */ +typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL; +/* Return an opaque pointer to the current "ex_data" implementation */ +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void); +/* Sets the "ex_data" implementation to be used (if it's not too late) */ +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i); +/* Get a new "ex_data" class, and return the corresponding "class_index" */ +int CRYPTO_ex_data_new_class(void); +/* Within a given class, get/register a new index */ +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* + * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a + * given class (invokes whatever per-class callbacks are applicable) + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +/* + * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular + * index (relative to the class type involved) + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); +/* + * This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. + */ +void CRYPTO_cleanup_all_ex_data(void); + +int CRYPTO_get_new_lockid(char *name); + +int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */ +void CRYPTO_lock(int mode, int type, const char *file, int line); +void CRYPTO_set_locking_callback(void (*func) (int mode, int type, + const char *file, int line)); +void (*CRYPTO_get_locking_callback(void)) (int mode, int type, + const char *file, int line); +void CRYPTO_set_add_lock_callback(int (*func) + (int *num, int mount, int type, + const char *file, int line)); +int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type, + const char *file, int line); + +/* Don't use this structure directly. */ +typedef struct crypto_threadid_st { + void *ptr; + unsigned long val; +} CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +int CRYPTO_THREADID_set_callback(void (*threadid_func) (CRYPTO_THREADID *)); +void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *); +void CRYPTO_THREADID_current(CRYPTO_THREADID *id); +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); +# ifndef OPENSSL_NO_DEPRECATED +void CRYPTO_set_id_callback(unsigned long (*func) (void)); +unsigned long (*CRYPTO_get_id_callback(void)) (void); +unsigned long CRYPTO_thread_id(void); +# endif + +const char *CRYPTO_get_lock_name(int type); +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line); + +int CRYPTO_get_new_dynlockid(void); +void CRYPTO_destroy_dynlockid(int i); +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value + *(*dyn_create_function) (const char + *file, + int line)); +void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function) + (int mode, + struct CRYPTO_dynlock_value *l, + const char *file, int line)); +void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function) + (struct CRYPTO_dynlock_value *l, + const char *file, int line)); +struct CRYPTO_dynlock_value +*(*CRYPTO_get_dynlock_create_callback(void)) (const char *file, int line); +void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode, + struct CRYPTO_dynlock_value + *l, const char *file, + int line); +void (*CRYPTO_get_dynlock_destroy_callback(void)) (struct CRYPTO_dynlock_value + *l, const char *file, + int line); + +/* + * CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- call + * the latter last if you need different functions + */ +int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), + void (*f) (void *)); +int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), + void (*free_func) (void *)); +int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, + int), void (*f) (void *)); +int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), + void (*free_func) (void *)); +int CRYPTO_set_mem_debug_functions(void (*m) + (void *, int, const char *, int, int), + void (*r) (void *, void *, int, + const char *, int, int), + void (*f) (void *, int), void (*so) (long), + long (*go) (void)); +void CRYPTO_get_mem_functions(void *(**m) (size_t), + void *(**r) (void *, size_t), + void (**f) (void *)); +void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), + void (**f) (void *)); +void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), + void *(**r) (void *, size_t, const char *, + int), void (**f) (void *)); +void CRYPTO_get_locked_mem_ex_functions(void + *(**m) (size_t, const char *, int), + void (**f) (void *)); +void CRYPTO_get_mem_debug_functions(void (**m) + (void *, int, const char *, int, int), + void (**r) (void *, void *, int, + const char *, int, int), + void (**f) (void *, int), + void (**so) (long), long (**go) (void)); + +void *CRYPTO_malloc_locked(int num, const char *file, int line); +void CRYPTO_free_locked(void *ptr); +void *CRYPTO_malloc(int num, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +void CRYPTO_free(void *ptr); +void *CRYPTO_realloc(void *addr, int num, const char *file, int line); +void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file, + int line); +void *CRYPTO_remalloc(void *addr, int num, const char *file, int line); + +void OPENSSL_cleanse(void *ptr, size_t len); + +void CRYPTO_set_mem_debug_options(long bits); +long CRYPTO_get_mem_debug_options(void); + +# define CRYPTO_push_info(info) \ + CRYPTO_push_info_(info, __FILE__, __LINE__); +int CRYPTO_push_info_(const char *info, const char *file, int line); +int CRYPTO_pop_info(void); +int CRYPTO_remove_all_info(void); + +/* + * Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro; + * used as default in CRYPTO_MDEBUG compilations): + */ +/*- + * The last argument has the following significance: + * + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, + int before_p); +void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file, + int line, int before_p); +void CRYPTO_dbg_free(void *addr, int before_p); +/*- + * Tell the debugging code about options. By default, the following values + * apply: + * + * 0: Clear all options. + * V_CRYPTO_MDEBUG_TIME (1): Set the "Show Time" option. + * V_CRYPTO_MDEBUG_THREAD (2): Set the "Show Thread Number" option. + * V_CRYPTO_MDEBUG_ALL (3): 1 + 2 + */ +void CRYPTO_dbg_set_options(long bits); +long CRYPTO_dbg_get_options(void); + +# ifndef OPENSSL_NO_FP_API +void CRYPTO_mem_leaks_fp(FILE *); +# endif +void CRYPTO_mem_leaks(struct bio_st *bio); +/* unsigned long order, char *file, int line, int num_bytes, char *addr */ +typedef void *CRYPTO_MEM_LEAK_CB (unsigned long, const char *, int, int, + void *); +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); + +/* die if we have to */ +void OpenSSLDie(const char *file, int line, const char *assertion); +# define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1)) + +unsigned long *OPENSSL_ia32cap_loc(void); +# define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) +int OPENSSL_isservice(void); + +int FIPS_mode(void); +int FIPS_mode_set(int r); + +void OPENSSL_init(void); + +# define fips_md_init(alg) fips_md_init_ctx(alg, alg) + +# ifdef OPENSSL_FIPS +# define fips_md_init_ctx(alg, cx) \ + int alg##_Init(cx##_CTX *c) \ + { \ + if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ + "Low level API call to digest " #alg " forbidden in FIPS mode!"); \ + return private_##alg##_Init(c); \ + } \ + int private_##alg##_Init(cx##_CTX *c) + +# define fips_cipher_abort(alg) \ + if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ + "Low level API call to cipher " #alg " forbidden in FIPS mode!") + +# else +# define fips_md_init_ctx(alg, cx) \ + int alg##_Init(cx##_CTX *c) +# define fips_cipher_abort(alg) while(0) +# endif + +/* + * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. + * It takes an amount of time dependent on |len|, but independent of the + * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements + * into a defined order as the return value when a != b is undefined, other + * than to be non-zero. + */ +int CRYPTO_memcmp(const volatile void *a, const volatile void *b, size_t len); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CRYPTO_strings(void); + +/* Error codes for the CRYPTO functions. */ + +/* Function codes. */ +# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +# define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID 103 +# define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101 +# define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +# define CRYPTO_F_DEF_ADD_INDEX 104 +# define CRYPTO_F_DEF_GET_CLASS 105 +# define CRYPTO_F_FIPS_MODE_SET 109 +# define CRYPTO_F_INT_DUP_EX_DATA 106 +# define CRYPTO_F_INT_FREE_EX_DATA 107 +# define CRYPTO_F_INT_NEW_EX_DATA 108 + +/* Reason codes. */ +# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 +# define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/cswift.h b/Sources/COpenSSL/cswift.h new file mode 100644 index 00000000..6dcd5fed --- /dev/null +++ b/Sources/COpenSSL/cswift.h @@ -0,0 +1,235 @@ +/* + * Attribution notice: Rainbow have generously allowed me to reproduce the + * necessary definitions here from their API. This means the support can + * build independently of whether application builders have the API or + * hardware. This will allow developers to easily produce software that has + * latent hardware support for any users that have accelertors installed, + * without the developers themselves needing anything extra. I have only + * clipped the parts from the CryptoSwift header files that are (or seem) + * relevant to the CryptoSwift support code. This is simply to keep the file + * sizes reasonable. [Geoff] + */ + +/* + * NB: These type widths do *not* seem right in general, in particular + * they're not terribly friendly to 64-bit architectures (unsigned long) will + * be 64-bit on IA-64 for a start. I'm leaving these alone as they agree with + * Rainbow's API and this will only be called into question on platforms with + * Rainbow support anyway! ;-) + */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + typedef long SW_STATUS; /* status */ + typedef unsigned char SW_BYTE; /* 8 bit byte */ + typedef unsigned short SW_U16; /* 16 bit number */ +#if defined(_IRIX) +# include + typedef __uint32_t SW_U32; +#else + typedef unsigned long SW_U32; /* 32 bit integer */ +#endif + +#if defined(OPENSSL_SYS_WIN32) + typedef struct _SW_U64 { + SW_U32 low32; + SW_U32 high32; + } SW_U64; /* 64 bit integer */ +#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC) + typedef longlong SW_U64 +#else /* Unix variants */ + typedef struct _SW_U64 { + SW_U32 low32; + SW_U32 high32; + } SW_U64; /* 64 bit integer */ +#endif + +/* status codes */ +#define SW_OK (0L) +#define SW_ERR_BASE (-10000L) +#define SW_ERR_NO_CARD (SW_ERR_BASE-1) /* The Card is not present */ +#define SW_ERR_CARD_NOT_READY (SW_ERR_BASE-2) /* The card has not powered */ + /* up yet */ +#define SW_ERR_TIME_OUT (SW_ERR_BASE-3) /* Execution of a command */ + /* time out */ +#define SW_ERR_NO_EXECUTE (SW_ERR_BASE-4) /* The Card failed to */ + /* execute the command */ +#define SW_ERR_INPUT_NULL_PTR (SW_ERR_BASE-5) /* a required pointer is */ + /* NULL */ +#define SW_ERR_INPUT_SIZE (SW_ERR_BASE-6) /* size is invalid, too */ + /* small, too large. */ +#define SW_ERR_INVALID_HANDLE (SW_ERR_BASE-7) /* Invalid SW_ACC_CONTEXT */ + /* handle */ +#define SW_ERR_PENDING (SW_ERR_BASE-8) /* A request is already out- */ + /* standing at this */ + /* context handle */ +#define SW_ERR_AVAILABLE (SW_ERR_BASE-9) /* A result is available. */ +#define SW_ERR_NO_PENDING (SW_ERR_BASE-10) /* No request is pending. */ +#define SW_ERR_NO_MEMORY (SW_ERR_BASE-11) /* Not enough memory */ +#define SW_ERR_BAD_ALGORITHM (SW_ERR_BASE-12) /* Invalid algorithm type */ + /* in SW_PARAM structure */ +#define SW_ERR_MISSING_KEY (SW_ERR_BASE-13) /* No key is associated with */ + /* context. */ + /* swAttachKeyParam() is */ + /* not called. */ +#define SW_ERR_KEY_CMD_MISMATCH \ + (SW_ERR_BASE-14) /* Cannot perform requested */ + /* SW_COMMAND_CODE since */ + /* key attached via */ + /* swAttachKeyParam() */ + /* cannot be used for this */ + /* SW_COMMAND_CODE. */ +#define SW_ERR_NOT_IMPLEMENTED \ + (SW_ERR_BASE-15) /* Not implemented */ +#define SW_ERR_BAD_COMMAND (SW_ERR_BASE-16) /* Bad command code */ +#define SW_ERR_BAD_ITEM_SIZE (SW_ERR_BASE-17) /* too small or too large in */ + /* the "initems" or */ + /* "outitems". */ +#define SW_ERR_BAD_ACCNUM (SW_ERR_BASE-18) /* Bad accelerator number */ +#define SW_ERR_SELFTEST_FAIL (SW_ERR_BASE-19) /* At least one of the self */ + /* test fail, look at the */ + /* selfTestBitmap in */ + /* SW_ACCELERATOR_INFO for */ + /* details. */ +#define SW_ERR_MISALIGN (SW_ERR_BASE-20) /* Certain alogrithms require */ + /* key materials aligned */ + /* in certain order, e.g. */ + /* 128 bit for CRT */ +#define SW_ERR_OUTPUT_NULL_PTR \ + (SW_ERR_BASE-21) /* a required pointer is */ + /* NULL */ +#define SW_ERR_OUTPUT_SIZE \ + (SW_ERR_BASE-22) /* size is invalid, too */ + /* small, too large. */ +#define SW_ERR_FIRMWARE_CHECKSUM \ + (SW_ERR_BASE-23) /* firmware checksum mismatch */ + /* download failed. */ +#define SW_ERR_UNKNOWN_FIRMWARE \ + (SW_ERR_BASE-24) /* unknown firmware error */ +#define SW_ERR_INTERRUPT (SW_ERR_BASE-25) /* request is abort when */ + /* it's waiting to be */ + /* completed. */ +#define SW_ERR_NVWRITE_FAIL (SW_ERR_BASE-26) /* error in writing to Non- */ + /* volatile memory */ +#define SW_ERR_NVWRITE_RANGE (SW_ERR_BASE-27) /* out of range error in */ + /* writing to NV memory */ +#define SW_ERR_RNG_ERROR (SW_ERR_BASE-28) /* Random Number Generation */ + /* failure */ +#define SW_ERR_DSS_FAILURE (SW_ERR_BASE-29) /* DSS Sign or Verify failure */ +#define SW_ERR_MODEXP_FAILURE (SW_ERR_BASE-30) /* Failure in various math */ + /* calculations */ +#define SW_ERR_ONBOARD_MEMORY (SW_ERR_BASE-31) /* Error in accessing on - */ + /* board memory */ +#define SW_ERR_FIRMWARE_VERSION \ + (SW_ERR_BASE-32) /* Wrong version in firmware */ + /* update */ +#define SW_ERR_ZERO_WORKING_ACCELERATOR \ + (SW_ERR_BASE-44) /* All accelerators are bad */ + + /* algorithm type */ +#define SW_ALG_CRT 1 +#define SW_ALG_EXP 2 +#define SW_ALG_DSA 3 +#define SW_ALG_NVDATA 4 + + /* command code */ +#define SW_CMD_MODEXP_CRT 1 /* perform Modular Exponentiation using */ + /* Chinese Remainder Theorem (CRT) */ +#define SW_CMD_MODEXP 2 /* perform Modular Exponentiation */ +#define SW_CMD_DSS_SIGN 3 /* perform DSS sign */ +#define SW_CMD_DSS_VERIFY 4 /* perform DSS verify */ +#define SW_CMD_RAND 5 /* perform random number generation */ +#define SW_CMD_NVREAD 6 /* perform read to nonvolatile RAM */ +#define SW_CMD_NVWRITE 7 /* perform write to nonvolatile RAM */ + + typedef SW_U32 SW_ALGTYPE; /* alogrithm type */ + typedef SW_U32 SW_STATE; /* state */ + typedef SW_U32 SW_COMMAND_CODE; /* command code */ + typedef SW_U32 SW_COMMAND_BITMAP[4]; /* bitmap */ + + typedef struct _SW_LARGENUMBER { + SW_U32 nbytes; /* number of bytes in the buffer "value" */ + SW_BYTE *value; /* the large integer as a string of */ + /* bytes in network (big endian) order */ + } SW_LARGENUMBER; + +#if defined(OPENSSL_SYS_WIN32) +# include + typedef HANDLE SW_OSHANDLE; /* handle to kernel object */ +# define SW_OS_INVALID_HANDLE INVALID_HANDLE_VALUE +# define SW_CALLCONV _stdcall +#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC) + /* async callback mechanisms */ + /* swiftCallbackLevel */ +# define SW_MAC_CALLBACK_LEVEL_NO 0 +# define SW_MAC_CALLBACK_LEVEL_HARDWARE 1/* from the hardware ISR */ +# define SW_MAC_CALLBACK_LEVEL_SECONDARY 2/* as secondary ISR */ + typedef int SW_MAC_CALLBACK_LEVEL; + typedef int SW_OSHANDLE; +# define SW_OS_INVALID_HANDLE (-1) +# define SW_CALLCONV +#else /* Unix variants */ + typedef int SW_OSHANDLE; /* handle to driver */ +# define SW_OS_INVALID_HANDLE (-1) +# define SW_CALLCONV +#endif + + typedef struct _SW_CRT { + SW_LARGENUMBER p; /* prime number p */ + SW_LARGENUMBER q; /* prime number q */ + SW_LARGENUMBER dmp1; /* exponent1 */ + SW_LARGENUMBER dmq1; /* exponent2 */ + SW_LARGENUMBER iqmp; /* CRT coefficient */ + } SW_CRT; + + typedef struct _SW_EXP { + SW_LARGENUMBER modulus; /* modulus */ + SW_LARGENUMBER exponent; /* exponent */ + } SW_EXP; + + typedef struct _SW_DSA { + SW_LARGENUMBER p; /* */ + SW_LARGENUMBER q; /* */ + SW_LARGENUMBER g; /* */ + SW_LARGENUMBER key; /* private/public key */ + } SW_DSA; + + typedef struct _SW_NVDATA { + SW_U32 accnum; /* accelerator board number */ + SW_U32 offset; /* offset in byte */ + } SW_NVDATA; + + typedef struct _SW_PARAM { + SW_ALGTYPE type; /* type of the alogrithm */ + union { + SW_CRT crt; + SW_EXP exp; + SW_DSA dsa; + SW_NVDATA nvdata; + } up; + } SW_PARAM; + + typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */ + + /* + * Now the OpenSSL bits, these function types are the for the function + * pointers that will bound into the Rainbow shared libraries. + */ + typedef SW_STATUS SW_CALLCONV t_swAcquireAccContext(SW_CONTEXT_HANDLE + *hac); + typedef SW_STATUS SW_CALLCONV t_swAttachKeyParam(SW_CONTEXT_HANDLE hac, + SW_PARAM *key_params); + typedef SW_STATUS SW_CALLCONV t_swSimpleRequest(SW_CONTEXT_HANDLE hac, + SW_COMMAND_CODE cmd, + SW_LARGENUMBER pin[], + SW_U32 pin_count, + SW_LARGENUMBER pout[], + SW_U32 pout_count); + typedef SW_STATUS SW_CALLCONV t_swReleaseAccContext(SW_CONTEXT_HANDLE + hac); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ diff --git a/Sources/COpenSSL/ctr128.c b/Sources/COpenSSL/ctr128.c new file mode 100644 index 00000000..e3d6eb43 --- /dev/null +++ b/Sources/COpenSSL/ctr128.c @@ -0,0 +1,263 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "crypto.h" +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * NOTE: the IV/counter CTR mode is big-endian. The code itself is + * endian-neutral. + */ + +/* increment counter (128-bit int) by 1 */ +static void ctr128_inc(unsigned char *counter) +{ + u32 n = 16, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (u8)c; + c >>= 8; + } while (n); +} + +#if !defined(OPENSSL_SMALL_FOOTPRINT) +static void ctr128_inc_aligned(unsigned char *counter) +{ + size_t *data, c, d, n; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) { + ctr128_inc(counter); + return; + } + + data = (size_t *)counter; + c = 1; + n = 16 / sizeof(size_t); + do { + --n; + d = data[n] += c; + /* did addition carry? */ + c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1); + } while (n); +} +#endif + +/* + * The input encrypted as though 128bit counter mode is being used. The + * extra state information to record how much of the 128bit block we have + * used is contained in *num, and the encrypted counter is kept in + * ecount_buf. Both *num and ecount_buf must be initialised with zeros + * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes + * that the counter is in the x lower bits of the IV (ivec), and that the + * application has full control over overflow and the rest of the IV. This + * implementation takes NO responsability for checking that the counter + * doesn't overflow into the rest of the IV when incremented. + */ +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], unsigned int *num, + block128_f block) +{ + unsigned int n; + size_t l = 0; + + assert(in && out && key && ecount_buf && num); + assert(*num < 16); + + n = *num; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out | (size_t)ecount_buf) + % sizeof(size_t) != 0) + break; +# endif + while (len >= 16) { + (*block) (ivec, ecount_buf, key); + ctr128_inc_aligned(ivec); + for (n = 0; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n); + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block) (ivec, ecount_buf, key); + ctr128_inc_aligned(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + *num = n; + return; + } while (0); + } + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block) (ivec, ecount_buf, key); + ctr128_inc(ivec); + } + out[l] = in[l] ^ ecount_buf[n]; + ++l; + n = (n + 1) % 16; + } + + *num = n; +} + +/* increment upper 96 bits of 128-bit counter by 1 */ +static void ctr96_inc(unsigned char *counter) +{ + u32 n = 12, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (u8)c; + c >>= 8; + } while (n); +} + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], + unsigned int *num, ctr128_f func) +{ + unsigned int n, ctr32; + + assert(in && out && key && ecount_buf && num); + assert(*num < 16); + + n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + + ctr32 = GETU32(ivec + 12); + while (len >= 16) { + size_t blocks = len / 16; + /* + * 1<<28 is just a not-so-small yet not-so-large number... + * Below condition is practically never met, but it has to + * be checked for code correctness. + */ + if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28)) + blocks = (1U << 28); + /* + * As (*func) operates on 32-bit counter, caller + * has to handle overflow. 'if' below detects the + * overflow, which is then handled by limiting the + * amount of blocks to the exact overflow point... + */ + ctr32 += (u32)blocks; + if (ctr32 < blocks) { + blocks -= ctr32; + ctr32 = 0; + } + (*func) (in, out, blocks, key, ivec); + /* (*ctr) does not update ivec, caller does: */ + PUTU32(ivec + 12, ctr32); + /* ... overflow was detected, propogate carry. */ + if (ctr32 == 0) + ctr96_inc(ivec); + blocks *= 16; + len -= blocks; + out += blocks; + in += blocks; + } + if (len) { + memset(ecount_buf, 0, 16); + (*func) (ecount_buf, ecount_buf, 1, key, ivec); + ++ctr32; + PUTU32(ivec + 12, ctr32); + if (ctr32 == 0) + ctr96_inc(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + + *num = n; +} diff --git a/Sources/COpenSSL/cversion.c b/Sources/COpenSSL/cversion.c new file mode 100644 index 00000000..bfff6995 --- /dev/null +++ b/Sources/COpenSSL/cversion.c @@ -0,0 +1,107 @@ +/* crypto/cversion.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "cryptlib.h" + +#ifndef NO_WINDOWS_BRAINDEATH +# include "buildinf.h" +#endif + +const char *SSLeay_version(int t) +{ + if (t == SSLEAY_VERSION) + return OPENSSL_VERSION_TEXT; + if (t == SSLEAY_BUILT_ON) { +#ifdef DATE +# ifdef OPENSSL_USE_BUILD_DATE + return (DATE); +# else + return ("built on: reproducible build, date unspecified"); +# endif +#else + return ("built on: date not available"); +#endif + } + if (t == SSLEAY_CFLAGS) { +#ifdef CFLAGS + return (CFLAGS); +#else + return ("compiler: information not available"); +#endif + } + if (t == SSLEAY_PLATFORM) { +#ifdef PLATFORM + return (PLATFORM); +#else + return ("platform: information not available"); +#endif + } + if (t == SSLEAY_DIR) { +#ifdef OPENSSLDIR + return "OPENSSLDIR: \"" OPENSSLDIR "\""; +#else + return "OPENSSLDIR: N/A"; +#endif + } + return ("not available"); +} + +unsigned long SSLeay(void) +{ + return (SSLEAY_VERSION_NUMBER); +} diff --git a/Sources/COpenSSL/d1_.c b/Sources/COpenSSL/d1_.c new file mode 100644 index 00000000..ba720193 --- /dev/null +++ b/Sources/COpenSSL/d1_.c @@ -0,0 +1,6036 @@ +/* ssl/d1_both.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "ssl_locl.h" +#include "buffer.h" +#include "rand.h" +#include "objects.h" +#include "evp.h" +#include "x509.h" + +#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) + +#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ + if ((end) - (start) <= 8) { \ + long ii; \ + for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ + } else { \ + long ii; \ + bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ + for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ + bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ + } } + +#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ + long ii; \ + OPENSSL_assert((msg_len) > 0); \ + is_complete = 1; \ + if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ + if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ + if (bitmask[ii] != 0xff) { is_complete = 0; break; } } + +#if 0 +# define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ + long ii; \ + printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \ + printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \ + printf("\n"); } +#endif + +static unsigned char bitmask_start_values[] = + { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 }; +static unsigned char bitmask_end_values[] = + { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; + +/* XDTLS: figure out the right values */ +static const unsigned int g_probable_mtu[] = { 1500, 512, 256 }; + +static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, + unsigned long frag_len); +static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); +static void dtls1_set_message_header_int(SSL *s, unsigned char mt, + unsigned long len, + unsigned short seq_num, + unsigned long frag_off, + unsigned long frag_len); +static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, + int *ok); + +static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len, + int reassembly) +{ + hm_fragment *frag = NULL; + unsigned char *buf = NULL; + unsigned char *bitmask = NULL; + + frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); + if (frag == NULL) + return NULL; + + if (frag_len) { + buf = (unsigned char *)OPENSSL_malloc(frag_len); + if (buf == NULL) { + OPENSSL_free(frag); + return NULL; + } + } + + /* zero length fragment gets zero frag->fragment */ + frag->fragment = buf; + + /* Initialize reassembly bitmask if necessary */ + if (reassembly) { + bitmask = + (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len)); + if (bitmask == NULL) { + if (buf != NULL) + OPENSSL_free(buf); + OPENSSL_free(frag); + return NULL; + } + memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); + } + + frag->reassembly = bitmask; + + return frag; +} + +void dtls1_hm_fragment_free(hm_fragment *frag) +{ + + if (frag->msg_header.is_ccs) { + EVP_CIPHER_CTX_free(frag->msg_header. + saved_retransmit_state.enc_write_ctx); + EVP_MD_CTX_destroy(frag->msg_header. + saved_retransmit_state.write_hash); + } + if (frag->fragment) + OPENSSL_free(frag->fragment); + if (frag->reassembly) + OPENSSL_free(frag->reassembly); + OPENSSL_free(frag); +} + +static int dtls1_query_mtu(SSL *s) +{ + if (s->d1->link_mtu) { + s->d1->mtu = + s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); + s->d1->link_mtu = 0; + } + + /* AHA! Figure out the MTU, and stick to the right size */ + if (s->d1->mtu < dtls1_min_mtu(s)) { + if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + s->d1->mtu = + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + + /* + * I've seen the kernel return bogus numbers when it doesn't know + * (initial write), so just make sure we have a reasonable number + */ + if (s->d1->mtu < dtls1_min_mtu(s)) { + /* Set to min mtu */ + s->d1->mtu = dtls1_min_mtu(s); + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, + s->d1->mtu, NULL); + } + } else + return 0; + } + return 1; +} + +/* + * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or + * SSL3_RT_CHANGE_CIPHER_SPEC) + */ +int dtls1_do_write(SSL *s, int type) +{ + int ret; + unsigned int curr_mtu; + int retry = 1; + unsigned int len, frag_off, mac_size, blocksize, used_len; + + if (!dtls1_query_mtu(s)) + return -1; + + OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something + * reasonable now */ + + if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) + OPENSSL_assert(s->init_num == + (int)s->d1->w_msg_hdr.msg_len + + DTLS1_HM_HEADER_LENGTH); + + if (s->write_hash) { + if (s->enc_write_ctx + && EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_GCM_MODE) + mac_size = 0; + else + mac_size = EVP_MD_CTX_size(s->write_hash); + } else + mac_size = 0; + + if (s->enc_write_ctx && + (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) + blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); + else + blocksize = 0; + + frag_off = 0; + s->rwstate = SSL_NOTHING; + + /* s->init_num shouldn't ever be < 0...but just in case */ + while (s->init_num > 0) { + if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) { + /* We must be writing a fragment other than the first one */ + + if (frag_off > 0) { + /* This is the first attempt at writing out this fragment */ + + if (s->init_off <= DTLS1_HM_HEADER_LENGTH) { + /* + * Each fragment that was already sent must at least have + * contained the message header plus one other byte. + * Therefore |init_off| must have progressed by at least + * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went + * wrong. + */ + return -1; + } + + /* + * Adjust |init_off| and |init_num| to allow room for a new + * message header for this fragment. + */ + s->init_off -= DTLS1_HM_HEADER_LENGTH; + s->init_num += DTLS1_HM_HEADER_LENGTH; + } else { + /* + * We must have been called again after a retry so use the + * fragment offset from our last attempt. We do not need + * to adjust |init_off| and |init_num| as above, because + * that should already have been done before the retry. + */ + frag_off = s->d1->w_msg_hdr.frag_off; + } + } + + used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH + + mac_size + blocksize; + if (s->d1->mtu > used_len) + curr_mtu = s->d1->mtu - used_len; + else + curr_mtu = 0; + + if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) { + /* + * grr.. we could get an error if MTU picked was wrong + */ + ret = BIO_flush(SSL_get_wbio(s)); + if (ret <= 0) { + s->rwstate = SSL_WRITING; + return ret; + } + used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize; + if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) { + curr_mtu = s->d1->mtu - used_len; + } else { + /* Shouldn't happen */ + return -1; + } + } + + /* + * We just checked that s->init_num > 0 so this cast should be safe + */ + if (((unsigned int)s->init_num) > curr_mtu) + len = curr_mtu; + else + len = s->init_num; + + /* Shouldn't ever happen */ + if (len > INT_MAX) + len = INT_MAX; + + /* + * XDTLS: this function is too long. split out the CCS part + */ + if (type == SSL3_RT_HANDSHAKE) { + if (len < DTLS1_HM_HEADER_LENGTH) { + /* + * len is so small that we really can't do anything sensible + * so fail + */ + return -1; + } + dtls1_fix_message_header(s, frag_off, + len - DTLS1_HM_HEADER_LENGTH); + + dtls1_write_message_header(s, + (unsigned char *)&s->init_buf-> + data[s->init_off]); + } + + ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], + len); + if (ret < 0) { + /* + * might need to update MTU here, but we don't know which + * previous packet caused the failure -- so can't really + * retransmit anything. continue as if everything is fine and + * wait for an alert to handle the retransmit + */ + if (retry && BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) { + if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + if (!dtls1_query_mtu(s)) + return -1; + /* Have one more go */ + retry = 0; + } else + return -1; + } else { + return (-1); + } + } else { + + /* + * bad if this assert fails, only part of the handshake message + * got sent. but why would this happen? + */ + OPENSSL_assert(len == (unsigned int)ret); + + if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { + /* + * should not be done for 'Hello Request's, but in that case + * we'll ignore the result anyway + */ + unsigned char *p = + (unsigned char *)&s->init_buf->data[s->init_off]; + const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + int xlen; + + if (frag_off == 0 && s->version != DTLS1_BAD_VER) { + /* + * reconstruct message header is if it is being sent in + * single fragment + */ + *p++ = msg_hdr->type; + l2n3(msg_hdr->msg_len, p); + s2n(msg_hdr->seq, p); + l2n3(0, p); + l2n3(msg_hdr->msg_len, p); + p -= DTLS1_HM_HEADER_LENGTH; + xlen = ret; + } else { + p += DTLS1_HM_HEADER_LENGTH; + xlen = ret - DTLS1_HM_HEADER_LENGTH; + } + + ssl3_finish_mac(s, p, xlen); + } + + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, type, s->init_buf->data, + (size_t)(s->init_off + s->init_num), s, + s->msg_callback_arg); + + s->init_off = 0; /* done writing this message */ + s->init_num = 0; + + return (1); + } + s->init_off += ret; + s->init_num -= ret; + ret -= DTLS1_HM_HEADER_LENGTH; + frag_off += ret; + + /* + * We save the fragment offset for the next fragment so we have it + * available in case of an IO retry. We don't know the length of the + * next fragment yet so just set that to 0 for now. It will be + * updated again later. + */ + dtls1_fix_message_header(s, frag_off, 0); + } + } + return (0); +} + +/* + * Obtain handshake message of message type 'mt' (any if mt == -1), maximum + * acceptable body length 'max'. Read an entire handshake message. Handshake + * messages arrive in fragments. + */ +long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) +{ + int i, al; + struct hm_header_st *msg_hdr; + unsigned char *p; + unsigned long msg_len; + + /* + * s3->tmp is used to store messages that are unexpected, caused by the + * absence of an optional handshake message + */ + if (s->s3->tmp.reuse_message) { + s->s3->tmp.reuse_message = 0; + if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + *ok = 1; + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + s->init_num = (int)s->s3->tmp.message_size; + return s->init_num; + } + + msg_hdr = &s->d1->r_msg_hdr; + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + + again: + i = dtls1_get_message_fragment(s, st1, stn, max, ok); + if (i == DTLS1_HM_BAD_FRAGMENT || i == DTLS1_HM_FRAGMENT_RETRY) { + /* bad fragment received */ + goto again; + } else if (i <= 0 && !*ok) { + return i; + } + + /* + * Don't change the *message* read sequence number while listening. For + * the *record* write sequence we reflect the ClientHello sequence number + * when listening. + */ + if (s->d1->listen) + memcpy(s->s3->write_sequence, s->s3->read_sequence, + sizeof(s->s3->write_sequence)); + else + s->d1->handshake_read_seq++; + + if (mt >= 0 && s->s3->tmp.message_type != mt) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + p = (unsigned char *)s->init_buf->data; + msg_len = msg_hdr->msg_len; + + /* reconstruct message header */ + *(p++) = msg_hdr->type; + l2n3(msg_len, p); + s2n(msg_hdr->seq, p); + l2n3(0, p); + l2n3(msg_len, p); + if (s->version != DTLS1_BAD_VER) { + p -= DTLS1_HM_HEADER_LENGTH; + msg_len += DTLS1_HM_HEADER_LENGTH; + } + + ssl3_finish_mac(s, p, msg_len); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + p, msg_len, s, s->msg_callback_arg); + + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + return s->init_num; + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + *ok = 0; + return -1; +} + +static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, + int max) +{ + size_t frag_off, frag_len, msg_len; + + msg_len = msg_hdr->msg_len; + frag_off = msg_hdr->frag_off; + frag_len = msg_hdr->frag_len; + + /* sanity checking */ + if ((frag_off + frag_len) > msg_len) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + if ((frag_off + frag_len) > (unsigned long)max) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */ + /* + * msg_len is limited to 2^24, but is effectively checked against max + * above + * + * Make buffer slightly larger than message length as a precaution + * against small OOB reads e.g. CVE-2016-6306 + */ + if (!BUF_MEM_grow_clean + (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH + 16)) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB); + return SSL_AD_INTERNAL_ERROR; + } + + s->s3->tmp.message_size = msg_len; + s->d1->r_msg_hdr.msg_len = msg_len; + s->s3->tmp.message_type = msg_hdr->type; + s->d1->r_msg_hdr.type = msg_hdr->type; + s->d1->r_msg_hdr.seq = msg_hdr->seq; + } else if (msg_len != s->d1->r_msg_hdr.msg_len) { + /* + * They must be playing with us! BTW, failure to enforce upper limit + * would open possibility for buffer overrun. + */ + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + return 0; /* no error */ +} + +static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) +{ + /*- + * (0) check whether the desired fragment is available + * if so: + * (1) copy over the fragment to s->init_buf->data[] + * (2) update s->init_num + */ + pitem *item; + hm_fragment *frag; + int al; + + *ok = 0; + do { + item = pqueue_peek(s->d1->buffered_messages); + if (item == NULL) + return 0; + + frag = (hm_fragment *)item->data; + + if (frag->msg_header.seq < s->d1->handshake_read_seq) { + /* This is a stale message that has been buffered so clear it */ + pqueue_pop(s->d1->buffered_messages); + dtls1_hm_fragment_free(frag); + pitem_free(item); + item = NULL; + frag = NULL; + } + } while (item == NULL); + + + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; + + if (s->d1->handshake_read_seq == frag->msg_header.seq) { + unsigned long frag_len = frag->msg_header.frag_len; + pqueue_pop(s->d1->buffered_messages); + + al = dtls1_preprocess_fragment(s, &frag->msg_header, max); + + /* al will be 0 if no alert */ + if (al == 0 && frag->msg_header.frag_len > 0) { + unsigned char *p = + (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + memcpy(&p[frag->msg_header.frag_off], frag->fragment, + frag->msg_header.frag_len); + } + + dtls1_hm_fragment_free(frag); + pitem_free(item); + + if (al == 0) { + *ok = 1; + return frag_len; + } + + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->init_num = 0; + *ok = 0; + return -1; + } else + return 0; +} + +/* + * dtls1_max_handshake_message_len returns the maximum number of bytes + * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but + * may be greater if the maximum certificate list size requires it. + */ +static unsigned long dtls1_max_handshake_message_len(const SSL *s) +{ + unsigned long max_len = + DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; + if (max_len < (unsigned long)s->max_cert_list) + return s->max_cert_list; + return max_len; +} + +static int +dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok) +{ + hm_fragment *frag = NULL; + pitem *item = NULL; + int i = -1, is_complete; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || + msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) + goto err; + + if (frag_len == 0) + return DTLS1_HM_FRAGMENT_RETRY; + + /* Try to find item in queue */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + if (item == NULL) { + frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); + if (frag == NULL) + goto err; + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + frag->msg_header.frag_len = frag->msg_header.msg_len; + frag->msg_header.frag_off = 0; + } else { + frag = (hm_fragment *)item->data; + if (frag->msg_header.msg_len != msg_hdr->msg_len) { + item = NULL; + frag = NULL; + goto err; + } + } + + /* + * If message is already reassembled, this must be a retransmit and can + * be dropped. In this case item != NULL and so frag does not need to be + * freed. + */ + if (frag->reassembly == NULL) { + unsigned char devnull[256]; + + while (frag_len) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + devnull, + frag_len > + sizeof(devnull) ? sizeof(devnull) : + frag_len, 0); + if (i <= 0) + goto err; + frag_len -= i; + } + return DTLS1_HM_FRAGMENT_RETRY; + } + + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + frag->fragment + msg_hdr->frag_off, + frag_len, 0); + if ((unsigned long)i != frag_len) + i = -1; + if (i <= 0) + goto err; + + RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, + (long)(msg_hdr->frag_off + frag_len)); + + RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, + is_complete); + + if (is_complete) { + OPENSSL_free(frag->reassembly); + frag->reassembly = NULL; + } + + if (item == NULL) { + item = pitem_new(seq64be, frag); + if (item == NULL) { + i = -1; + goto err; + } + + item = pqueue_insert(s->d1->buffered_messages, item); + /* + * pqueue_insert fails iff a duplicate item is inserted. However, + * |item| cannot be a duplicate. If it were, |pqueue_find|, above, + * would have returned it and control would never have reached this + * branch. + */ + OPENSSL_assert(item != NULL); + } + + return DTLS1_HM_FRAGMENT_RETRY; + + err: + if (frag != NULL && item == NULL) + dtls1_hm_fragment_free(frag); + *ok = 0; + return i; +} + +static int +dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr, + int *ok) +{ + int i = -1; + hm_fragment *frag = NULL; + pitem *item = NULL; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) + goto err; + + /* Try to find item in queue, to prevent duplicate entries */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + /* + * If we already have an entry and this one is a fragment, don't discard + * it and rather try to reassemble it. + */ + if (item != NULL && frag_len != msg_hdr->msg_len) + item = NULL; + + /* + * Discard the message if sequence number was already there, is too far + * in the future, already in the queue or if we received a FINISHED + * before the SERVER_HELLO, which then must be a stale retransmit. + */ + if (msg_hdr->seq <= s->d1->handshake_read_seq || + msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || + (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) + { + unsigned char devnull[256]; + + while (frag_len) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + devnull, + frag_len > + sizeof(devnull) ? sizeof(devnull) : + frag_len, 0); + if (i <= 0) + goto err; + frag_len -= i; + } + } else { + if (frag_len != msg_hdr->msg_len) + return dtls1_reassemble_fragment(s, msg_hdr, ok); + + if (frag_len > dtls1_max_handshake_message_len(s)) + goto err; + + frag = dtls1_hm_fragment_new(frag_len, 0); + if (frag == NULL) + goto err; + + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + + if (frag_len) { + /* + * read the body of the fragment (header has already been read + */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + frag->fragment, frag_len, 0); + if ((unsigned long)i != frag_len) + i = -1; + if (i <= 0) + goto err; + } + + item = pitem_new(seq64be, frag); + if (item == NULL) + goto err; + + item = pqueue_insert(s->d1->buffered_messages, item); + /* + * pqueue_insert fails iff a duplicate item is inserted. However, + * |item| cannot be a duplicate. If it were, |pqueue_find|, above, + * would have returned it. Then, either |frag_len| != + * |msg_hdr->msg_len| in which case |item| is set to NULL and it will + * have been processed with |dtls1_reassemble_fragment|, above, or + * the record will have been discarded. + */ + OPENSSL_assert(item != NULL); + } + + return DTLS1_HM_FRAGMENT_RETRY; + + err: + if (frag != NULL && item == NULL) + dtls1_hm_fragment_free(frag); + *ok = 0; + return i; +} + +static long +dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) +{ + unsigned char wire[DTLS1_HM_HEADER_LENGTH]; + unsigned long len, frag_off, frag_len; + int i, al; + struct hm_header_st msg_hdr; + + redo: + /* see if we have the required fragment already */ + if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) { + if (*ok) + s->init_num = frag_len; + return frag_len; + } + + /* read handshake message header */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire, + DTLS1_HM_HEADER_LENGTH, 0); + if (i <= 0) { /* nbio, or an error */ + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + /* Handshake fails if message header is incomplete */ + if (i != DTLS1_HM_HEADER_LENGTH) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + /* parse the message fragment header */ + dtls1_get_message_header(wire, &msg_hdr); + + len = msg_hdr.msg_len; + frag_off = msg_hdr.frag_off; + frag_len = msg_hdr.frag_len; + + /* + * We must have at least frag_len bytes left in the record to be read. + * Fragments must not span records. + */ + if (frag_len > s->s3->rrec.length) { + al = SSL3_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_BAD_LENGTH); + goto f_err; + } + + /* + * if this is a future (or stale) message it gets buffered + * (or dropped)--no further processing at this time + * While listening, we accept seq 1 (ClientHello with cookie) + * although we're still expecting seq 0 (ClientHello) + */ + if (msg_hdr.seq != s->d1->handshake_read_seq + && !(s->d1->listen && msg_hdr.seq == 1)) + return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); + + if (frag_len && frag_len < len) + return dtls1_reassemble_fragment(s, &msg_hdr, ok); + + if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && + wire[0] == SSL3_MT_HELLO_REQUEST) { + /* + * The server may always send 'Hello Request' messages -- we are + * doing a handshake anyway now, so ignore them if their format is + * correct. Does not count for 'Finished' MAC. + */ + if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + wire, DTLS1_HM_HEADER_LENGTH, s, + s->msg_callback_arg); + + s->init_num = 0; + goto redo; + } else { /* Incorrectly formated Hello request */ + + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, + SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + } + + if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max))) + goto f_err; + + if (frag_len > 0) { + unsigned char *p = + (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + &p[frag_off], frag_len, 0); + + /* + * This shouldn't ever fail due to NBIO because we already checked + * that we have enough data in the record + */ + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + } else + i = 0; + + /* + * XDTLS: an incorrectly formatted fragment should cause the handshake + * to fail + */ + if (i != (int)frag_len) { + al = SSL3_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL3_AD_ILLEGAL_PARAMETER); + goto f_err; + } + + *ok = 1; + s->state = stn; + + /* + * Note that s->init_num is *not* used as current offset in + * s->init_buf->data, but as a counter summing up fragments' lengths: as + * soon as they sum up to handshake packet length, we assume we have got + * all the fragments. + */ + s->init_num = frag_len; + return frag_len; + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->init_num = 0; + + *ok = 0; + return (-1); +} + +/*- + * for these 2 messages, we need to + * ssl->enc_read_ctx re-init + * ssl->s3->read_sequence zero + * ssl->s3->read_mac_secret re-init + * ssl->session->read_sym_enc assign + * ssl->session->read_compression assign + * ssl->session->read_hash assign + */ +int dtls1_send_change_cipher_spec(SSL *s, int a, int b) +{ + unsigned char *p; + + if (s->state == a) { + p = (unsigned char *)s->init_buf->data; + *p++ = SSL3_MT_CCS; + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->init_num = DTLS1_CCS_HEADER_LENGTH; + + if (s->version == DTLS1_BAD_VER) { + s->d1->next_handshake_write_seq++; + s2n(s->d1->handshake_write_seq, p); + s->init_num += 2; + } + + s->init_off = 0; + + dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, + s->d1->handshake_write_seq, 0, 0); + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 1); + + s->state = b; + } + + /* SSL3_ST_CW_CHANGE_B */ + return (dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); +} + +int dtls1_read_failed(SSL *s, int code) +{ + if (code > 0) { +#ifdef TLS_DEBUG + fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__); +#endif + return 1; + } + + if (!dtls1_is_timer_expired(s)) { + /* + * not a timeout, none of our business, let higher layers handle + * this. in fact it's probably an error + */ + return code; + } +#ifndef OPENSSL_NO_HEARTBEATS + /* done, no need to send a retransmit */ + if (!SSL_in_init(s) && !s->tlsext_hb_pending) +#else + /* done, no need to send a retransmit */ + if (!SSL_in_init(s)) +#endif + { + BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); + return code; + } +#if 0 /* for now, each alert contains only one + * record number */ + item = pqueue_peek(state->rcvd_records); + if (item) { + /* send an alert immediately for all the missing records */ + } else +#endif + +#if 0 /* no more alert sending, just retransmit the + * last set of messages */ + if (state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT) + ssl3_send_alert(s, SSL3_AL_WARNING, + DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); +#endif + + return dtls1_handle_timeout(s); +} + +int dtls1_get_queue_priority(unsigned short seq, int is_ccs) +{ + /* + * The index of the retransmission queue actually is the message sequence + * number, since the queue only contains messages of a single handshake. + * However, the ChangeCipherSpec has no message sequence number and so + * using only the sequence will result in the CCS and Finished having the + * same index. To prevent this, the sequence number is multiplied by 2. + * In case of a CCS 1 is subtracted. This does not only differ CSS and + * Finished, it also maintains the order of the index (important for + * priority queues) and fits in the unsigned short variable. + */ + return seq * 2 - is_ccs; +} + +int dtls1_retransmit_buffered_messages(SSL *s) +{ + pqueue sent = s->d1->sent_messages; + piterator iter; + pitem *item; + hm_fragment *frag; + int found = 0; + + iter = pqueue_iterator(sent); + + for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { + frag = (hm_fragment *)item->data; + if (dtls1_retransmit_message(s, (unsigned short) + dtls1_get_queue_priority + (frag->msg_header.seq, + frag->msg_header.is_ccs), 0, + &found) <= 0 && found) { +#ifdef TLS_DEBUG + fprintf(stderr, "dtls1_retransmit_message() failed\n"); +#endif + return -1; + } + } + + return 1; +} + +int dtls1_buffer_message(SSL *s, int is_ccs) +{ + pitem *item; + hm_fragment *frag; + unsigned char seq64be[8]; + + /* + * this function is called immediately after a message has been + * serialized + */ + OPENSSL_assert(s->init_off == 0); + + frag = dtls1_hm_fragment_new(s->init_num, 0); + if (!frag) + return 0; + + memcpy(frag->fragment, s->init_buf->data, s->init_num); + + if (is_ccs) { + /* For DTLS1_BAD_VER the header length is non-standard */ + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + ((s->version==DTLS1_BAD_VER)?3:DTLS1_CCS_HEADER_LENGTH) + == (unsigned int)s->init_num); + } else { + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); + } + + frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.seq = s->d1->w_msg_hdr.seq; + frag->msg_header.type = s->d1->w_msg_hdr.type; + frag->msg_header.frag_off = 0; + frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.is_ccs = is_ccs; + + /* save current state */ + frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx; + frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; + frag->msg_header.saved_retransmit_state.compress = s->compress; + frag->msg_header.saved_retransmit_state.session = s->session; + frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch; + + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = + (unsigned + char)(dtls1_get_queue_priority(frag->msg_header.seq, + frag->msg_header.is_ccs) >> 8); + seq64be[7] = + (unsigned + char)(dtls1_get_queue_priority(frag->msg_header.seq, + frag->msg_header.is_ccs)); + + item = pitem_new(seq64be, frag); + if (item == NULL) { + dtls1_hm_fragment_free(frag); + return 0; + } +#if 0 + fprintf(stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); + fprintf(stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); + fprintf(stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); +#endif + + pqueue_insert(s->d1->sent_messages, item); + return 1; +} + +int +dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, + int *found) +{ + int ret; + /* XDTLS: for now assuming that read/writes are blocking */ + pitem *item; + hm_fragment *frag; + unsigned long header_length; + unsigned char seq64be[8]; + struct dtls1_retransmit_state saved_state; + unsigned char save_write_sequence[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + + /*- + OPENSSL_assert(s->init_num == 0); + OPENSSL_assert(s->init_off == 0); + */ + + /* XDTLS: the requested message ought to be found, otherwise error */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(seq >> 8); + seq64be[7] = (unsigned char)seq; + + item = pqueue_find(s->d1->sent_messages, seq64be); + if (item == NULL) { +#ifdef TLS_DEBUG + fprintf(stderr, "retransmit: message %d non-existant\n", seq); +#endif + *found = 0; + return 0; + } + + *found = 1; + frag = (hm_fragment *)item->data; + + if (frag->msg_header.is_ccs) + header_length = DTLS1_CCS_HEADER_LENGTH; + else + header_length = DTLS1_HM_HEADER_LENGTH; + + memcpy(s->init_buf->data, frag->fragment, + frag->msg_header.msg_len + header_length); + s->init_num = frag->msg_header.msg_len + header_length; + + dtls1_set_message_header_int(s, frag->msg_header.type, + frag->msg_header.msg_len, + frag->msg_header.seq, 0, + frag->msg_header.frag_len); + + /* save current state */ + saved_state.enc_write_ctx = s->enc_write_ctx; + saved_state.write_hash = s->write_hash; + saved_state.compress = s->compress; + saved_state.session = s->session; + saved_state.epoch = s->d1->w_epoch; + saved_state.epoch = s->d1->w_epoch; + + s->d1->retransmitting = 1; + + /* restore state in which the message was originally sent */ + s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx; + s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; + s->compress = frag->msg_header.saved_retransmit_state.compress; + s->session = frag->msg_header.saved_retransmit_state.session; + s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch; + + if (frag->msg_header.saved_retransmit_state.epoch == + saved_state.epoch - 1) { + memcpy(save_write_sequence, s->s3->write_sequence, + sizeof(s->s3->write_sequence)); + memcpy(s->s3->write_sequence, s->d1->last_write_sequence, + sizeof(s->s3->write_sequence)); + } + + ret = dtls1_do_write(s, frag->msg_header.is_ccs ? + SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); + + /* restore current state */ + s->enc_write_ctx = saved_state.enc_write_ctx; + s->write_hash = saved_state.write_hash; + s->compress = saved_state.compress; + s->session = saved_state.session; + s->d1->w_epoch = saved_state.epoch; + + if (frag->msg_header.saved_retransmit_state.epoch == + saved_state.epoch - 1) { + memcpy(s->d1->last_write_sequence, s->s3->write_sequence, + sizeof(s->s3->write_sequence)); + memcpy(s->s3->write_sequence, save_write_sequence, + sizeof(s->s3->write_sequence)); + } + + s->d1->retransmitting = 0; + + (void)BIO_flush(SSL_get_wbio(s)); + return ret; +} + +unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, + unsigned char mt, unsigned long len, + unsigned long frag_off, + unsigned long frag_len) +{ + /* Don't change sequence numbers while listening */ + if (frag_off == 0 && !s->d1->listen) { + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->d1->next_handshake_write_seq++; + } + + dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, + frag_off, frag_len); + + return p += DTLS1_HM_HEADER_LENGTH; +} + +/* don't actually do the writing, wait till the MTU has been retrieved */ +static void +dtls1_set_message_header_int(SSL *s, unsigned char mt, + unsigned long len, unsigned short seq_num, + unsigned long frag_off, unsigned long frag_len) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->type = mt; + msg_hdr->msg_len = len; + msg_hdr->seq = seq_num; + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; +} + +static void +dtls1_fix_message_header(SSL *s, unsigned long frag_off, + unsigned long frag_len) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; +} + +static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + *p++ = msg_hdr->type; + l2n3(msg_hdr->msg_len, p); + + s2n(msg_hdr->seq, p); + l2n3(msg_hdr->frag_off, p); + l2n3(msg_hdr->frag_len, p); + + return p; +} + +unsigned int dtls1_link_min_mtu(void) +{ + return (g_probable_mtu[(sizeof(g_probable_mtu) / + sizeof(g_probable_mtu[0])) - 1]); +} + +unsigned int dtls1_min_mtu(SSL *s) +{ + return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); +} + +void +dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) +{ + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + msg_hdr->type = *(data++); + n2l3(data, msg_hdr->msg_len); + + n2s(data, msg_hdr->seq); + n2l3(data, msg_hdr->frag_off); + n2l3(data, msg_hdr->frag_len); +} + +void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) +{ + memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); + + ccs_hdr->type = *(data++); +} + +int dtls1_shutdown(SSL *s) +{ + int ret; +#ifndef OPENSSL_NO_SCTP + BIO *wbio; + + wbio = SSL_get_wbio(s); + if (wbio != NULL && BIO_dgram_is_sctp(wbio) && + !(s->shutdown & SSL_SENT_SHUTDOWN)) { + ret = BIO_dgram_sctp_wait_for_dry(wbio); + if (ret < 0) + return -1; + + if (ret == 0) + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, + NULL); + } +#endif + ret = ssl3_shutdown(s); +#ifndef OPENSSL_NO_SCTP + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL); +#endif + return ret; +} + +#ifndef OPENSSL_NO_HEARTBEATS +int dtls1_process_heartbeat(SSL *s) +{ + unsigned char *p = &s->s3->rrec.data[0], *pl; + unsigned short hbtype; + unsigned int payload; + unsigned int padding = 16; /* Use minimum padding */ + + if (s->msg_callback) + s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, + &s->s3->rrec.data[0], s->s3->rrec.length, + s, s->msg_callback_arg); + + /* Read type and payload length first */ + if (1 + 2 + 16 > s->s3->rrec.length) + return 0; /* silently discard */ + if (s->s3->rrec.length > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; /* silently discard per RFC 6520 sec. 4 */ + + hbtype = *p++; + n2s(p, payload); + if (1 + 2 + payload + 16 > s->s3->rrec.length) + return 0; /* silently discard per RFC 6520 sec. 4 */ + pl = p; + + if (hbtype == TLS1_HB_REQUEST) { + unsigned char *buffer, *bp; + unsigned int write_length = 1 /* heartbeat type */ + + 2 /* heartbeat length */ + + payload + padding; + int r; + + if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + + /* + * Allocate memory for the response, size is 1 byte message type, + * plus 2 bytes payload length, plus payload, plus padding + */ + buffer = OPENSSL_malloc(write_length); + if (buffer == NULL) + return -1; + bp = buffer; + + /* Enter response type, length and copy payload */ + *bp++ = TLS1_HB_RESPONSE; + s2n(payload, bp); + memcpy(bp, pl, payload); + bp += payload; + /* Random padding */ + if (RAND_bytes(bp, padding) <= 0) { + OPENSSL_free(buffer); + return -1; + } + + r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); + + if (r >= 0 && s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, + buffer, write_length, s, s->msg_callback_arg); + + OPENSSL_free(buffer); + + if (r < 0) + return r; + } else if (hbtype == TLS1_HB_RESPONSE) { + unsigned int seq; + + /* + * We only send sequence numbers (2 bytes unsigned int), and 16 + * random bytes, so we just try to read the sequence number + */ + n2s(pl, seq); + + if (payload == 18 && seq == s->tlsext_hb_seq) { + dtls1_stop_timer(s); + s->tlsext_hb_seq++; + s->tlsext_hb_pending = 0; + } + } + + return 0; +} + +int dtls1_heartbeat(SSL *s) +{ + unsigned char *buf, *p; + int ret = -1; + unsigned int payload = 18; /* Sequence number + random bytes */ + unsigned int padding = 16; /* Use minimum padding */ + + /* Only send if peer supports and accepts HB requests... */ + if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || + s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { + SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); + return -1; + } + + /* ...and there is none in flight yet... */ + if (s->tlsext_hb_pending) { + SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); + return -1; + } + + /* ...and no handshake in progress. */ + if (SSL_in_init(s) || s->in_handshake) { + SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); + return -1; + } + + /* + * Check if padding is too long, payload and padding must not exceed 2^14 + * - 3 = 16381 bytes in total. + */ + OPENSSL_assert(payload + padding <= 16381); + + /*- + * Create HeartBeat message, we just use a sequence number + * as payload to distuingish different messages and add + * some random stuff. + * - Message Type, 1 byte + * - Payload Length, 2 bytes (unsigned int) + * - Payload, the sequence number (2 bytes uint) + * - Payload, random bytes (16 bytes uint) + * - Padding + */ + buf = OPENSSL_malloc(1 + 2 + payload + padding); + if (buf == NULL) + goto err; + p = buf; + /* Message Type */ + *p++ = TLS1_HB_REQUEST; + /* Payload length (18 bytes here) */ + s2n(payload, p); + /* Sequence number */ + s2n(s->tlsext_hb_seq, p); + /* 16 random bytes */ + if (RAND_bytes(p, 16) <= 0) + goto err; + p += 16; + /* Random padding */ + if (RAND_bytes(p, padding) <= 0) + goto err; + + ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); + if (ret >= 0) { + if (s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, + buf, 3 + payload + padding, + s, s->msg_callback_arg); + + dtls1_start_timer(s); + s->tlsext_hb_pending = 1; + } + +err: + OPENSSL_free(buf); + + return ret; +} +#endif +/* ssl/d1_clnt.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "ssl_locl.h" +#ifndef OPENSSL_NO_KRB5 +# include "kssl_lcl.h" +#endif +// #include "buffer.h" +// #include "rand.h" +// #include "objects.h" +// #include "evp.h" +#include "md5.h" +#include "bn.h" +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +static const SSL_METHOD *dtls1_get_client_method(int ver); +static int dtls1_get_hello_verify(SSL *s); + +static const SSL_METHOD *dtls1_get_client_method(int ver) +{ + if (ver == DTLS_ANY_VERSION) + return DTLS_client_method(); + else if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER) + return DTLSv1_client_method(); + else if (ver == DTLS1_2_VERSION) + return DTLSv1_2_client_method(); + else + return NULL; +} + +IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, + DTLSv1_client_method, + ssl_undefined_function, + dtls1_connect, + dtls1_get_client_method, DTLSv1_enc_data) + +IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, + DTLSv1_2_client_method, + ssl_undefined_function, + dtls1_connect, + dtls1_get_client_method, DTLSv1_2_enc_data) + +IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, + DTLS_client_method, + ssl_undefined_function, + dtls1_connect, + dtls1_get_client_method, DTLSv1_2_enc_data) + +int dtls1_connect(SSL *s) +{ + BUF_MEM *buf = NULL; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; +#ifndef OPENSSL_NO_SCTP + unsigned char sctpauthkey[64]; + char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; +#endif + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + +#ifndef OPENSSL_NO_SCTP + /* + * Notify SCTP BIO socket to enter handshake mode and prevent stream + * identifier other than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + s->in_handshake, NULL); +#endif + +#ifndef OPENSSL_NO_HEARTBEATS + /* + * If we're awaiting a HeartbeatResponse, pretend we already got and + * don't await it anymore, because Heartbeats don't make sense during + * handshakes anyway. + */ + if (s->tlsext_hb_pending) { + dtls1_stop_timer(s); + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + s->state = SSL_ST_CONNECT; + s->ctx->stats.sess_connect_renegotiate++; + /* break */ + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE | SSL_ST_CONNECT: + case SSL_ST_OK | SSL_ST_CONNECT: + + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) && + (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) { + SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->init_buf = buf; + buf = NULL; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* setup buffing BIO */ + if (!ssl_init_wbio_buffer(s, 0)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* don't push the buffering BIO quite yet */ + + s->state = SSL3_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + /* mark client_random uninitialized */ + memset(s->s3->client_random, 0, sizeof(s->s3->client_random)); + s->d1->send_cookie = 0; + s->hit = 0; + s->d1->change_cipher_spec_ok = 0; + /* + * Should have been reset by ssl3_get_finished, too. + */ + s->s3->change_cipher_spec = 0; + break; + +#ifndef OPENSSL_NO_SCTP + case DTLS1_SCTP_ST_CR_READ_SOCK: + + if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + s->s3->in_read_app_data = 2; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + + s->state = s->s3->tmp.next_state; + break; + + case DTLS1_SCTP_ST_CW_WRITE_SOCK: + /* read app data until dry event */ + + ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); + if (ret < 0) + goto end; + + if (ret == 0) { + s->s3->in_read_app_data = 2; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + + s->state = s->d1->next_state; + break; +#endif + + case SSL3_ST_CW_CLNT_HELLO_A: + s->shutdown = 0; + + /* every DTLS ClientHello resets Finished MAC */ + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* fall thru */ + case SSL3_ST_CW_CLNT_HELLO_B: + dtls1_start_timer(s); + ret = ssl3_client_hello(s); + if (ret <= 0) + goto end; + + if (s->d1->send_cookie) { + s->state = SSL3_ST_CW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; + } else + s->state = SSL3_ST_CR_SRVR_HELLO_A; + + s->init_num = 0; + +#ifndef OPENSSL_NO_SCTP + /* Disable buffering for SCTP */ + if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) { +#endif + /* + * turn on buffering for the next lot of output + */ + if (s->bbio != s->wbio) + s->wbio = BIO_push(s->bbio, s->wbio); +#ifndef OPENSSL_NO_SCTP + } +#endif + + break; + + case SSL3_ST_CR_SRVR_HELLO_A: + case SSL3_ST_CR_SRVR_HELLO_B: + ret = ssl3_get_server_hello(s); + if (ret <= 0) + goto end; + else { + if (s->hit) { +#ifndef OPENSSL_NO_SCTP + /* + * Add new shared key for SCTP-Auth, will be ignored if + * no SCTP used. + */ + snprintf((char *)labelbuffer, + sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), + labelbuffer, + sizeof(labelbuffer), NULL, 0, + 0) <= 0) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif + + s->state = SSL3_ST_CR_FINISHED_A; + if (s->tlsext_ticket_expected) { + /* receive renewed session ticket */ + s->state = SSL3_ST_CR_SESSION_TICKET_A; + } + } else + s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; + } + s->init_num = 0; + break; + + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + + ret = dtls1_get_hello_verify(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->d1->send_cookie) /* start again, with a cookie */ + s->state = SSL3_ST_CW_CLNT_HELLO_A; + else + s->state = SSL3_ST_CR_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_A: + case SSL3_ST_CR_CERT_B: + /* Check if it is anon DH or PSK */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + ret = ssl3_get_server_certificate(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state = SSL3_ST_CR_CERT_STATUS_A; + else + s->state = SSL3_ST_CR_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_CR_KEY_EXCH_A; + } +#else + } else + skip = 1; + + s->state = SSL3_ST_CR_KEY_EXCH_A; +#endif + s->init_num = 0; + break; + + case SSL3_ST_CR_KEY_EXCH_A: + case SSL3_ST_CR_KEY_EXCH_B: + ret = ssl3_get_key_exchange(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_CERT_REQ_A; + s->init_num = 0; + + /* + * at this point we check that we have the required stuff from + * the server + */ + if (!ssl3_check_cert_and_algorithm(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + break; + + case SSL3_ST_CR_CERT_REQ_A: + case SSL3_ST_CR_CERT_REQ_B: + ret = ssl3_get_certificate_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_DONE_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_SRVR_DONE_A: + case SSL3_ST_CR_SRVR_DONE_B: + ret = ssl3_get_server_done(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->s3->tmp.cert_req) + s->s3->tmp.next_state = SSL3_ST_CW_CERT_A; + else + s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + state == SSL_ST_RENEGOTIATE) + s->state = DTLS1_SCTP_ST_CR_READ_SOCK; + else +#endif + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_CW_CERT_A: + case SSL3_ST_CW_CERT_B: + case SSL3_ST_CW_CERT_C: + case SSL3_ST_CW_CERT_D: + dtls1_start_timer(s); + ret = ssl3_send_client_certificate(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_KEY_EXCH_A: + case SSL3_ST_CW_KEY_EXCH_B: + dtls1_start_timer(s); + ret = ssl3_send_client_key_exchange(s); + if (ret <= 0) + goto end; + +#ifndef OPENSSL_NO_SCTP + /* + * Add new shared key for SCTP-Auth, will be ignored if no SCTP + * used. + */ + snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0) <= 0) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif + + /* + * EAY EAY EAY need to check for DH fix cert sent back + */ + /* + * For TLS, cert_req is set to 2, so a cert chain of nothing is + * sent, but no verify packet is sent + */ + if (s->s3->tmp.cert_req == 1) { + s->state = SSL3_ST_CW_CERT_VRFY_A; + } else { +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL3_ST_CW_CHANGE_A; + s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } else +#endif + s->state = SSL3_ST_CW_CHANGE_A; + } + + s->init_num = 0; + break; + + case SSL3_ST_CW_CERT_VRFY_A: + case SSL3_ST_CW_CERT_VRFY_B: + dtls1_start_timer(s); + ret = ssl3_send_client_verify(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL3_ST_CW_CHANGE_A; + s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } else +#endif + s->state = SSL3_ST_CW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_CW_CHANGE_B: + if (!s->hit) + dtls1_start_timer(s); + ret = dtls1_send_change_cipher_spec(s, + SSL3_ST_CW_CHANGE_A, + SSL3_ST_CW_CHANGE_B); + if (ret <= 0) + goto end; + + s->state = SSL3_ST_CW_FINISHED_A; + s->init_num = 0; + + s->session->cipher = s->s3->tmp.new_cipher; +#ifdef OPENSSL_NO_COMP + s->session->compress_meth = 0; +#else + if (s->s3->tmp.new_compression == NULL) + s->session->compress_meth = 0; + else + s->session->compress_meth = s->s3->tmp.new_compression->id; +#endif + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_CLIENT_WRITE)) + { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } +#ifndef OPENSSL_NO_SCTP + if (s->hit) { + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); + } +#endif + + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + break; + + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_CW_FINISHED_B: + if (!s->hit) + dtls1_start_timer(s); + ret = ssl3_send_finished(s, + SSL3_ST_CW_FINISHED_A, + SSL3_ST_CW_FINISHED_B, + s->method-> + ssl3_enc->client_finished_label, + s->method-> + ssl3_enc->client_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_FLUSH; + + /* clear flags */ + s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; + if (s->hit) { + s->s3->tmp.next_state = SSL_ST_OK; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = s->s3->tmp.next_state; + s->s3->tmp.next_state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } +#endif + if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { + s->state = SSL_ST_OK; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL_ST_OK; + s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } +#endif + s->s3->flags |= SSL3_FLAGS_POP_BUFFER; + s->s3->delay_buf_pop_ret = 0; + } + } else { +#ifndef OPENSSL_NO_SCTP + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); +#endif + +#ifndef OPENSSL_NO_TLSEXT + /* + * Allow NewSessionTicket if ticket expected + */ + if (s->tlsext_ticket_expected) + s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; + else +#endif + + s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; + } + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_CR_SESSION_TICKET_A: + case SSL3_ST_CR_SESSION_TICKET_B: + ret = ssl3_get_new_session_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_STATUS_A: + case SSL3_ST_CR_CERT_STATUS_B: + ret = ssl3_get_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_KEY_EXCH_A; + s->init_num = 0; + break; +#endif + + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + s->d1->change_cipher_spec_ok = 1; + ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + + if (s->hit) + s->state = SSL3_ST_CW_CHANGE_A; + else + s->state = SSL_ST_OK; + +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + state == SSL_ST_RENEGOTIATE) { + s->d1->next_state = s->state; + s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } +#endif + + s->init_num = 0; + break; + + case SSL3_ST_CW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + /* + * If the write error was fatal, stop trying + */ + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + } + + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL_ST_OK: + /* clean a few things up */ + ssl3_cleanup_key_block(s); + +#if 0 + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } +#endif + + /* + * If we are not 'joining' the last two packets, remove the + * buffering now + */ + if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) + ssl_free_wbio_buffer(s); + /* else do it later in ssl3_write */ + + s->init_num = 0; + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->handshake_func = dtls1_connect; + s->ctx->stats.sess_connect_good++; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + /* done with handshaking */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; + dtls1_clear_received_buffer(s); + goto end; + /* break; */ + + case SSL_ST_ERR: + default: + SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + /* did we do anything */ + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + end: + s->in_handshake--; + +#ifndef OPENSSL_NO_SCTP + /* + * Notify SCTP BIO socket to leave handshake mode and allow stream + * identifier other than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + s->in_handshake, NULL); +#endif + + if (buf != NULL) + BUF_MEM_free(buf); + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + return (ret); +} + +static int dtls1_get_hello_verify(SSL *s) +{ + int n, al, ok = 0; + unsigned char *data; + unsigned int cookie_len; + + s->first_packet = 1; + n = s->method->ssl_get_message(s, + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, + -1, s->max_cert_list, &ok); + s->first_packet = 0; + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { + s->d1->send_cookie = 0; + s->s3->tmp.reuse_message = 1; + return (1); + } + + data = (unsigned char *)s->init_msg; +#if 0 + if (s->method->version != DTLS_ANY_VERSION && + ((data[0] != (s->version >> 8)) || (data[1] != (s->version & 0xff)))) + { + SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY, SSL_R_WRONG_SSL_VERSION); + s->version = (s->version & 0xff00) | data[1]; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } +#endif + data += 2; + + cookie_len = *(data++); + if (cookie_len > sizeof(s->d1->cookie)) { + al = SSL_AD_ILLEGAL_PARAMETER; + goto f_err; + } + + memcpy(s->d1->cookie, data, cookie_len); + s->d1->cookie_len = cookie_len; + + s->d1->send_cookie = 1; + return 1; + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->state = SSL_ST_ERR; + return -1; +} +/* ssl/d1_meth.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "objects.h" +// #include "ssl_locl.h" + +static const SSL_METHOD *dtls1_get_method(int ver); +static const SSL_METHOD *dtls1_get_method(int ver) +{ + if (ver == DTLS_ANY_VERSION) + return DTLS_method(); + else if (ver == DTLS1_VERSION) + return DTLSv1_method(); + else if (ver == DTLS1_2_VERSION) + return DTLSv1_2_method(); + else + return NULL; +} + +IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, + DTLSv1_method, + dtls1_accept, + dtls1_connect, dtls1_get_method, DTLSv1_enc_data) + +IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, + DTLSv1_2_method, + dtls1_accept, + dtls1_connect, dtls1_get_method, DTLSv1_2_enc_data) + +IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, + DTLS_method, + dtls1_accept, + dtls1_connect, dtls1_get_method, DTLSv1_2_enc_data) +/* ssl/d1_pkt.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +// #include "ssl_locl.h" +// #include "evp.h" +// #include "buffer.h" +#include "pqueue.h" +// #include "rand.h" + +/* mod 128 saturating subtract of two 64-bit values in big-endian order */ +static int satsub64be(const unsigned char *v1, const unsigned char *v2) +{ + int ret, i; + + if (sizeof(long) == 8) + do { + const union { + long one; + char little; + } is_endian = { + 1 + }; + long l; + + if (is_endian.little) + break; + /* not reached on little-endians */ + /* + * following test is redundant, because input is always aligned, + * but I take no chances... + */ + if (((size_t)v1 | (size_t)v2) & 0x7) + break; + + l = *((long *)v1); + l -= *((long *)v2); + if (l > 128) + return 128; + else if (l < -128) + return -128; + else + return (int)l; + } while (0); + + ret = 0; + for (i=0; i<7; i++) { + if (v1[i] > v2[i]) { + /* v1 is larger... but by how much? */ + if (v1[i] != v2[i] + 1) + return 128; + while (++i <= 6) { + if (v1[i] != 0x00 || v2[i] != 0xff) + return 128; /* too much */ + } + /* We checked all the way to the penultimate byte, + * so despite higher bytes changing we actually + * know that it only changed from (e.g.) + * ... (xx) ff ff ff ?? + * to ... (xx+1) 00 00 00 ?? + * so we add a 'bias' of 256 for the carry that + * happened, and will eventually return + * 256 + v1[7] - v2[7]. */ + ret = 256; + break; + } else if (v2[i] > v1[i]) { + /* v2 is larger... but by how much? */ + if (v2[i] != v1[i] + 1) + return -128; + while (++i <= 6) { + if (v2[i] != 0x00 || v1[i] != 0xff) + return -128; /* too much */ + } + /* Similar to the case above, we know it changed + * from ... (xx) 00 00 00 ?? + * to ... (xx-1) ff ff ff ?? + * so we add a 'bias' of -256 for the borrow, + * to return -256 + v1[7] - v2[7]. */ + ret = -256; + } + } + + ret += (int)v1[7] - (int)v2[7]; + + if (ret > 128) + return 128; + else if (ret < -128) + return -128; + else + return ret; +} + +static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, + int len, int peek); +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); +static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); +static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, + unsigned int *is_next_epoch); +#if 0 +static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, + unsigned short *priority, + unsigned long *offset); +#endif +static int dtls1_buffer_record(SSL *s, record_pqueue *q, + unsigned char *priority); +static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); + +/* copy buffered record into SSL structure */ +static int dtls1_copy_record(SSL *s, pitem *item) +{ + DTLS1_RECORD_DATA *rdata; + + rdata = (DTLS1_RECORD_DATA *)item->data; + + if (s->s3->rbuf.buf != NULL) + OPENSSL_free(s->s3->rbuf.buf); + + s->packet = rdata->packet; + s->packet_length = rdata->packet_length; + memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); + + /* Set proper sequence number for mac calculation */ + memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); + + return (1); +} + +static int +dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) +{ + DTLS1_RECORD_DATA *rdata; + pitem *item; + + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; + + rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); + item = pitem_new(priority, rdata); + if (rdata == NULL || item == NULL) { + if (rdata != NULL) + OPENSSL_free(rdata); + if (item != NULL) + pitem_free(item); + + SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); + return -1; + } + + rdata->packet = s->packet; + rdata->packet_length = s->packet_length; + memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD)); + + item->data = rdata; + +#ifndef OPENSSL_NO_SCTP + /* Store bio_dgram_sctp_rcvinfo struct */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + (s->state == SSL3_ST_SR_FINISHED_A + || s->state == SSL3_ST_CR_FINISHED_A)) { + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, + sizeof(rdata->recordinfo), &rdata->recordinfo); + } +#endif + + s->packet = NULL; + s->packet_length = 0; + memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); + memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD)); + + if (!ssl3_setup_buffers(s)) { + SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); + if (rdata->rbuf.buf != NULL) + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata); + pitem_free(item); + return (-1); + } + + if (pqueue_insert(queue->q, item) == NULL) { + /* Must be a duplicate so ignore it */ + if (rdata->rbuf.buf != NULL) + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata); + pitem_free(item); + } + + return (1); +} + +static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) +{ + pitem *item; + + item = pqueue_pop(queue->q); + if (item) { + dtls1_copy_record(s, item); + + OPENSSL_free(item->data); + pitem_free(item); + + return (1); + } + + return (0); +} + +/* + * retrieve a buffered record that belongs to the new epoch, i.e., not + * processed yet + */ +#define dtls1_get_unprocessed_record(s) \ + dtls1_retrieve_buffered_record((s), \ + &((s)->d1->unprocessed_rcds)) + +/* + * retrieve a buffered record that belongs to the current epoch, ie, + * processed + */ +#define dtls1_get_processed_record(s) \ + dtls1_retrieve_buffered_record((s), \ + &((s)->d1->processed_rcds)) + +static int dtls1_process_buffered_records(SSL *s) +{ + pitem *item; + SSL3_BUFFER *rb; + SSL3_RECORD *rr; + DTLS1_BITMAP *bitmap; + unsigned int is_next_epoch; + int replayok = 1; + + item = pqueue_peek(s->d1->unprocessed_rcds.q); + if (item) { + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) + return 1; /* Nothing to do. */ + + rr = &s->s3->rrec; + rb = &s->s3->rbuf; + + if (rb->left > 0) { + /* + * We've still got data from the current packet to read. There could + * be a record from the new epoch in it - so don't overwrite it + * with the unprocessed records yet (we'll do it when we've + * finished reading the current packet). + */ + return 1; + } + + + /* Process all the records. */ + while (pqueue_peek(s->d1->unprocessed_rcds.q)) { + dtls1_get_unprocessed_record(s); + bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); + if (bitmap == NULL) { + /* + * Should not happen. This will only ever be NULL when the + * current record is from a different epoch. But that cannot + * be the case because we already checked the epoch above + */ + SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, + ERR_R_INTERNAL_ERROR); + return 0; + } +#ifndef OPENSSL_NO_SCTP + /* Only do replay check if no SCTP bio */ + if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) +#endif + { + /* + * Check whether this is a repeat, or aged record. We did this + * check once already when we first received the record - but + * we might have updated the window since then due to + * records we subsequently processed. + */ + replayok = dtls1_record_replay_check(s, bitmap); + } + + if (!replayok || !dtls1_process_record(s, bitmap)) { + /* dump this record */ + rr->length = 0; + s->packet_length = 0; + continue; + } + + if (dtls1_buffer_record(s, &(s->d1->processed_rcds), + s->s3->rrec.seq_num) < 0) + return 0; + } + } + + /* + * sync epoch numbers once all the unprocessed records have been + * processed + */ + s->d1->processed_rcds.epoch = s->d1->r_epoch; + s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; + + return 1; +} + +#if 0 + +static int dtls1_get_buffered_record(SSL *s) +{ + pitem *item; + PQ_64BIT priority = + (((PQ_64BIT) s->d1->handshake_read_seq) << 32) | + ((PQ_64BIT) s->d1->r_msg_hdr.frag_off); + + /* if we're not (re)negotiating, nothing buffered */ + if (!SSL_in_init(s)) + return 0; + + item = pqueue_peek(s->d1->rcvd_records); + if (item && item->priority == priority) { + /* + * Check if we've received the record of interest. It must be a + * handshake record, since data records as passed up without + * buffering + */ + DTLS1_RECORD_DATA *rdata; + item = pqueue_pop(s->d1->rcvd_records); + rdata = (DTLS1_RECORD_DATA *)item->data; + + if (s->s3->rbuf.buf != NULL) + OPENSSL_free(s->s3->rbuf.buf); + + s->packet = rdata->packet; + s->packet_length = rdata->packet_length; + memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); + + OPENSSL_free(item->data); + pitem_free(item); + + /* s->d1->next_expected_seq_num++; */ + return (1); + } + + return 0; +} + +#endif + +static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) +{ + int i, al; + int enc_err; + SSL_SESSION *sess; + SSL3_RECORD *rr; + unsigned int mac_size, orig_len; + unsigned char md[EVP_MAX_MD_SIZE]; + + rr = &(s->s3->rrec); + sess = s->session; + + /* + * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, + * and we have that many bytes in s->packet + */ + rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]); + + /* + * ok, we can now read from 's->packet' data into 'rr' rr->input points + * at rr->length bytes, which need to be copied into rr->data by either + * the decryption or by the decompression When the data is 'copied' into + * the rr->data buffer, rr->input will be pointed at the new buffer + */ + + /* + * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length + * bytes of encrypted compressed stuff. + */ + + /* check is not needed I believe */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + goto f_err; + } + + /* decrypt in place in 'rr->input' */ + rr->data = rr->input; + + enc_err = s->method->ssl3_enc->enc(s, 0); + /*- + * enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid + */ + if (enc_err == 0) { + /* For DTLS we simply ignore bad packets. */ + rr->length = 0; + s->packet_length = 0; + goto err; + } +#ifdef TLS_DEBUG + printf("dec %d\n", rr->length); + { + unsigned int z; + for (z = 0; z < rr->length; z++) + printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); + } + printf("\n"); +#endif + + /* r->length is now the compressed data plus mac */ + if ((sess != NULL) && + (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + + /* + * kludge: *_cbc_remove_padding passes padding length in rr->type + */ + orig_len = rr->length + ((unsigned int)rr->type >> 8); + + /* + * orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different amount + * of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size + 1)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* + * We update the length so that the TLS header bytes can be + * constructed correctly but we need to extract the MAC in + * constant time from within the record, without leaking the + * contents of the padding bytes. + */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; + } else { + /* + * In this case there's no padding, so |orig_len| equals + * |rec->length| and we checked that there's enough bytes for + * |mac_size| above. + */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + + i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); + if (i < 0 || mac == NULL + || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) + enc_err = -1; + } + + if (enc_err < 0) { + /* decryption failed, silently discard message */ + rr->length = 0; + s->packet_length = 0; + goto err; + } + + /* r->length is now just compressed */ + if (s->expand != NULL) { + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, + SSL_R_COMPRESSED_LENGTH_TOO_LONG); + goto f_err; + } + if (!ssl3_do_uncompress(s)) { + al = SSL_AD_DECOMPRESSION_FAILURE; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION); + goto f_err; + } + } + + if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + + rr->off = 0; + /*- + * So at this point the following is true + * ssl->s3->rrec.type is the type of record + * ssl->s3->rrec.length == number of bytes in record + * ssl->s3->rrec.off == offset to first valid byte + * ssl->s3->rrec.data == where to take bytes from, increment + * after use :-). + */ + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; + + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap); + + return (1); + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (0); +} + +/*- + * Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data, - data + * ssl->s3->rrec.length, - number of bytes + */ +/* used only by dtls1_read_bytes */ +int dtls1_get_record(SSL *s) +{ + int ssl_major, ssl_minor; + int i, n; + SSL3_RECORD *rr; + unsigned char *p = NULL; + unsigned short version; + DTLS1_BITMAP *bitmap; + unsigned int is_next_epoch; + + rr = &(s->s3->rrec); + + again: + /* + * The epoch may have changed. If so, process all the pending records. + * This is a non-blocking operation. + */ + if (!dtls1_process_buffered_records(s)) + return -1; + + /* if we're renegotiating, then there may be buffered records */ + if (dtls1_get_processed_record(s)) + return 1; + + /* get something from the wire */ + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { + n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); + /* read timeout is handled by dtls1_read_bytes */ + if (n <= 0) + return (n); /* error or non-blocking */ + + /* this packet contained a partial record, dump it */ + if (s->packet_length != DTLS1_RT_HEADER_LENGTH) { + s->packet_length = 0; + goto again; + } + + s->rstate = SSL_ST_READ_BODY; + + p = s->packet; + + if (s->msg_callback) + s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, + s, s->msg_callback_arg); + + /* Pull apart the header into the DTLS1_RECORD */ + rr->type = *(p++); + ssl_major = *(p++); + ssl_minor = *(p++); + version = (ssl_major << 8) | ssl_minor; + + /* sequence number is 64 bits, with top 2 bytes = epoch */ + n2s(p, rr->epoch); + + memcpy(&(s->s3->read_sequence[2]), p, 6); + p += 6; + + n2s(p, rr->length); + + /* + * Lets check the version. We tolerate alerts that don't have the exact + * version number (e.g. because of protocol version errors) + */ + if (!s->first_packet && rr->type != SSL3_RT_ALERT) { + if (version != s->version) { + /* unexpected version, silently discard */ + rr->length = 0; + s->packet_length = 0; + goto again; + } + } + + if ((version & 0xff00) != (s->version & 0xff00)) { + /* wrong version, silently discard record */ + rr->length = 0; + s->packet_length = 0; + goto again; + } + + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + /* record too long, silently discard it */ + rr->length = 0; + s->packet_length = 0; + goto again; + } + + /* now s->rstate == SSL_ST_READ_BODY */ + } + + /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ + + if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) { + /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ + i = rr->length; + n = ssl3_read_n(s, i, i, 1); + /* this packet contained a partial record, dump it */ + if (n != i) { + rr->length = 0; + s->packet_length = 0; + goto again; + } + + /* + * now n == rr->length, and s->packet_length == + * DTLS1_RT_HEADER_LENGTH + rr->length + */ + } + s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ + + /* match epochs. NULL means the packet is dropped on the floor */ + bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); + if (bitmap == NULL) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +#ifndef OPENSSL_NO_SCTP + /* Only do replay check if no SCTP bio */ + if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) { +#endif + /* + * Check whether this is a repeat, or aged record. Don't check if + * we're listening and this message is a ClientHello. They can look + * as if they're replayed, since they arrive from different + * connections and would be dropped unnecessarily. + */ + if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && + s->packet_length > DTLS1_RT_HEADER_LENGTH && + s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && + !dtls1_record_replay_check(s, bitmap)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +#ifndef OPENSSL_NO_SCTP + } +#endif + + /* just read a 0 length packet */ + if (rr->length == 0) + goto again; + + /* + * If this record is from the next epoch (either HM or ALERT), and a + * handshake is currently in progress, buffer it since it cannot be + * processed at this time. However, do not buffer anything while + * listening. + */ + if (is_next_epoch) { + if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { + if (dtls1_buffer_record + (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) + return -1; + } + rr->length = 0; + s->packet_length = 0; + goto again; + } + + if (!dtls1_process_record(s, bitmap)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } + + return (1); + +} + +/*- + * Return up to 'len' payload bytes received in 'type' records. + * 'type' is one of the following: + * + * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - 0 (during a shutdown, no data has to be returned) + * + * If we don't have stored data to work from, read a SSL/TLS record first + * (possibly multiple records if we still don't have anything to return). + * + * This function must handle any surprises the peer may have for us, such as + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really + * a surprise, but handled as if it were), or renegotiation requests. + * Also if record payloads contain fragments too small to process, we store + * them until there is enough for the respective protocol (the record protocol + * may use arbitrary fragmentation and even interleaving): + * Change cipher spec protocol + * just 1 byte needed, no need for keeping anything stored + * Alert protocol + * 2 bytes needed (AlertLevel, AlertDescription) + * Handshake protocol + * 4 bytes needed (HandshakeType, uint24 length) -- we just have + * to detect unexpected Client Hello and Hello Request messages + * here, anything else is handled by higher layers + * Application data protocol + * none of our business + */ +int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +{ + int al, i, j, ret; + unsigned int n; + SSL3_RECORD *rr; + void (*cb) (const SSL *ssl, int type2, int val) = NULL; + + if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ + if (!ssl3_setup_buffers(s)) + return (-1); + + /* XXX: check what the second '&& type' is about */ + if ((type && (type != SSL3_RT_APPLICATION_DATA) && + (type != SSL3_RT_HANDSHAKE) && type) || + (peek && (type != SSL3_RT_APPLICATION_DATA))) { + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* + * check whether there's a handshake message (client hello?) waiting + */ + if ((ret = have_handshake_fragment(s, type, buf, len, peek))) + return ret; + + /* + * Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. + */ + +#ifndef OPENSSL_NO_SCTP + /* + * Continue handshake if it had to be interrupted to read app data with + * SCTP. + */ + if ((!s->in_handshake && SSL_in_init(s)) || + (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + (s->state == DTLS1_SCTP_ST_SR_READ_SOCK + || s->state == DTLS1_SCTP_ST_CR_READ_SOCK) + && s->s3->in_read_app_data != 2)) +#else + if (!s->in_handshake && SSL_in_init(s)) +#endif + { + /* type == SSL3_RT_APPLICATION_DATA */ + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + + start: + s->rwstate = SSL_NOTHING; + + /*- + * s->s3->rrec.type - is the type of record + * s->s3->rrec.data, - data + * s->s3->rrec.off, - offset into 'data' for next read + * s->s3->rrec.length, - number of bytes. + */ + rr = &(s->s3->rrec); + + /* + * We are not handshaking and have no data yet, so process data buffered + * during the last handshake in advance, if any. + */ + if (s->state == SSL_ST_OK && rr->length == 0) { + pitem *item; + item = pqueue_pop(s->d1->buffered_app_data.q); + if (item) { +#ifndef OPENSSL_NO_SCTP + /* Restore bio_dgram_sctp_rcvinfo struct */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s))) { + DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, + sizeof(rdata->recordinfo), &rdata->recordinfo); + } +#endif + + dtls1_copy_record(s, item); + + OPENSSL_free(item->data); + pitem_free(item); + } + } + + /* Check for timeout */ + if (dtls1_handle_timeout(s) > 0) + goto start; + + /* get new packet if necessary */ + if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { + ret = dtls1_get_record(s); + if (ret <= 0) { + ret = dtls1_read_failed(s, ret); + /* anything other than a timeout is an error */ + if (ret <= 0) + return (ret); + else + goto start; + } + } + + if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) { + rr->length = 0; + goto start; + } + + /* + * Reset the count of consecutive warning alerts if we've got a non-empty + * record that isn't an alert. + */ + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + s->cert->alert_count = 0; + + /* we now have a packet which can be read and processed */ + + if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ + && (rr->type != SSL3_RT_HANDSHAKE)) { + /* + * We now have application data between CCS and Finished. Most likely + * the packets were reordered on their way, so buffer the application + * data for later processing rather than dropping the connection. + */ + if (dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num) < + 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + rr->length = 0; + goto start; + } + + /* + * If the other end has shut down, throw anything we read away (even in + * 'peek' mode) + */ + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + rr->length = 0; + s->rwstate = SSL_NOTHING; + return (0); + } + + if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or + * SSL3_RT_HANDSHAKE */ + /* + * make sure that we are not getting application data when we are + * doing a handshake for the first time + */ + if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && + (s->enc_read_ctx == NULL)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); + goto f_err; + } + + if (len <= 0) + return (len); + + if ((unsigned int)len > rr->length) + n = rr->length; + else + n = (unsigned int)len; + + memcpy(buf, &(rr->data[rr->off]), n); + if (!peek) { + rr->length -= n; + rr->off += n; + if (rr->length == 0) { + s->rstate = SSL_ST_READ_HEADER; + rr->off = 0; + } + } +#ifndef OPENSSL_NO_SCTP + /* + * We were about to renegotiate but had to read belated application + * data first, so retry. + */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + rr->type == SSL3_RT_APPLICATION_DATA && + (s->state == DTLS1_SCTP_ST_SR_READ_SOCK + || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) { + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + } + + /* + * We might had to delay a close_notify alert because of reordered + * app data. If there was an alert and there is no message to read + * anymore, finally set shutdown. + */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + s->d1->shutdown_received + && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return (0); + } +#endif + return (n); + } + + /* + * If we get here, then type != rr->type; if we have a handshake message, + * then it was unexpected (Hello Request or Client Hello). + */ + + /* + * In case of record types for which we have 'fragment' storage, fill + * that so that we can process the data at a fixed place. + */ + { + unsigned int k, dest_maxlen = 0; + unsigned char *dest = NULL; + unsigned int *dest_len = NULL; + + if (rr->type == SSL3_RT_HANDSHAKE) { + dest_maxlen = sizeof(s->d1->handshake_fragment); + dest = s->d1->handshake_fragment; + dest_len = &s->d1->handshake_fragment_len; + } else if (rr->type == SSL3_RT_ALERT) { + dest_maxlen = sizeof(s->d1->alert_fragment); + dest = s->d1->alert_fragment; + dest_len = &s->d1->alert_fragment_len; + } +#ifndef OPENSSL_NO_HEARTBEATS + else if (rr->type == TLS1_RT_HEARTBEAT) { + dtls1_process_heartbeat(s); + + /* Exit and notify application to read again */ + rr->length = 0; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + return (-1); + } +#endif + /* else it's a CCS message, or application data or wrong */ + else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) { + /* + * Application data while renegotiating is allowed. Try again + * reading. + */ + if (rr->type == SSL3_RT_APPLICATION_DATA) { + BIO *bio; + s->s3->in_read_app_data = 2; + bio = SSL_get_rbio(s); + s->rwstate = SSL_READING; + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + + /* Not certain if this is the right error handling */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + + if (dest_maxlen > 0) { + /* + * XDTLS: In a pathalogical case, the Client Hello may be + * fragmented--don't always expect dest_maxlen bytes + */ + if (rr->length < dest_maxlen) { +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + /* + * for normal alerts rr->length is 2, while + * dest_maxlen is 7 if we were to handle this + * non-existing alert... + */ + FIX ME +#endif + s->rstate = SSL_ST_READ_HEADER; + rr->length = 0; + goto start; + } + + /* now move 'n' bytes: */ + for (k = 0; k < dest_maxlen; k++) { + dest[k] = rr->data[rr->off++]; + rr->length--; + } + *dest_len = dest_maxlen; + } + } + + /*- + * s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; + * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. + * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) + */ + + /* If we are a client, check for an incoming 'Hello Request': */ + if ((!s->server) && + (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && + (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && + (s->session != NULL) && (s->session->cipher != NULL)) { + s->d1->handshake_fragment_len = 0; + + if ((s->d1->handshake_fragment[1] != 0) || + (s->d1->handshake_fragment[2] != 0) || + (s->d1->handshake_fragment[3] != 0)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); + goto f_err; + } + + /* + * no need to check sequence number on HELLO REQUEST messages + */ + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + s->d1->handshake_fragment, 4, s, + s->msg_callback_arg); + + if (SSL_is_init_finished(s) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + !s->s3->renegotiate) { + s->d1->handshake_read_seq++; + s->new_session = 1; + ssl3_renegotiate(s); + if (ssl3_renegotiate_check(s)) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* + * In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world + */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + } + } + /* + * we either finished a handshake or ignored the request, now try + * again to obtain the (application) data we were asked for + */ + goto start; + } + + /* + * If we are a server and get a client hello when renegotiation isn't + * allowed send back a no renegotiation alert and carry on. + */ + if (s->server + && SSL_is_init_finished(s) + && !s->s3->send_connection_binding + && s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH + && s->d1->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO + && s->s3->previous_client_finished_len != 0 + && (s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) == 0) { + s->d1->handshake_fragment_len = 0; + rr->length = 0; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); + goto start; + } + + + if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) { + int alert_level = s->d1->alert_fragment[0]; + int alert_descr = s->d1->alert_fragment[1]; + + s->d1->alert_fragment_len = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, + s->d1->alert_fragment, 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (alert_level << 8) | alert_descr; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (alert_level == SSL3_AL_WARNING) { + s->s3->warn_alert = alert_descr; + + s->cert->alert_count++; + if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); + goto f_err; + } + + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { +#ifndef OPENSSL_NO_SCTP + /* + * With SCTP and streams the socket may deliver app data + * after a close_notify alert. We have to check this first so + * that nothing gets discarded. + */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + s->d1->shutdown_received = 1; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + return -1; + } +#endif + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return (0); + } +#if 0 + /* XXX: this is a possible improvement in the future */ + /* now check if it's a missing record */ + if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { + unsigned short seq; + unsigned int frag_off; + unsigned char *p = &(s->d1->alert_fragment[2]); + + n2s(p, seq); + n2l3(p, frag_off); + + dtls1_retransmit_message(s, + dtls1_get_queue_priority + (frag->msg_header.seq, 0), frag_off, + &found); + if (!found && SSL_in_init(s)) { + /* + * fprintf( stderr,"in init = %d\n", SSL_in_init(s)); + */ + /* + * requested a message not yet sent, send an alert + * ourselves + */ + ssl3_send_alert(s, SSL3_AL_WARNING, + DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); + } + } +#endif + } else if (alert_level == SSL3_AL_FATAL) { + char tmp[16]; + + s->rwstate = SSL_NOTHING; + s->s3->fatal_alert = alert_descr; + SSLerr(SSL_F_DTLS1_READ_BYTES, + SSL_AD_REASON_OFFSET + alert_descr); + BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr); + ERR_add_error_data(2, "SSL alert number ", tmp); + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->session_ctx, s->session); + return (0); + } else { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); + goto f_err; + } + + goto start; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a + * shutdown */ + s->rwstate = SSL_NOTHING; + rr->length = 0; + return (0); + } + + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { + struct ccs_header_st ccs_hdr; + unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH; + + dtls1_get_ccs_header(rr->data, &ccs_hdr); + + if (s->version == DTLS1_BAD_VER) + ccs_hdr_len = 3; + + /* + * 'Change Cipher Spec' is just a single byte, so we know exactly + * what the record payload has to look like + */ + /* XDTLS: check that epoch is consistent */ + if ((rr->length != ccs_hdr_len) || + (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto f_err; + } + + rr->length = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, + rr->data, 1, s, s->msg_callback_arg); + + /* + * We can't process a CCS now, because previous handshake messages + * are still missing, so just drop it. + */ + if (!s->d1->change_cipher_spec_ok) { + goto start; + } + + s->d1->change_cipher_spec_ok = 0; + + s->s3->change_cipher_spec = 1; + if (!ssl3_do_change_cipher_spec(s)) + goto err; + + /* do this whenever CCS is processed */ + dtls1_reset_seq_numbers(s, SSL3_CC_READ); + + if (s->version == DTLS1_BAD_VER) + s->d1->handshake_read_seq++; + +#ifndef OPENSSL_NO_SCTP + /* + * Remember that a CCS has been received, so that an old key of + * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no + * SCTP is used + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); +#endif + + goto start; + } + + /* + * Unexpected handshake message (Client Hello, or protocol violation) + */ + if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && + !s->in_handshake) { + struct hm_header_st msg_hdr; + + /* this may just be a stale retransmit */ + dtls1_get_message_header(rr->data, &msg_hdr); + if (rr->epoch != s->d1->r_epoch) { + rr->length = 0; + goto start; + } + + /* + * If we are server, we may have a repeated FINISHED of the client + * here, then retransmit our CCS and FINISHED. + */ + if (msg_hdr.type == SSL3_MT_FINISHED) { + if (dtls1_check_timeout_num(s) < 0) + return -1; + + dtls1_retransmit_buffered_messages(s); + rr->length = 0; + goto start; + } + + if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { +#if 0 /* worked only because C operator preferences + * are not as expected (and because this is + * not really needed for clients except for + * detecting protocol violations): */ + s->state = SSL_ST_BEFORE | (s->server) + ? SSL_ST_ACCEPT : SSL_ST_CONNECT; +#else + s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; +#endif + s->renegotiate = 1; + s->new_session = 1; + } + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* + * In the case where we try to read application data, but we + * trigger an SSL handshake, we return -1 with the retry + * option set. Otherwise renegotiation may cause nasty + * problems in the blocking world + */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + goto start; + } + + switch (rr->type) { + default: +#ifndef OPENSSL_NO_TLS + /* TLS just ignores unknown message types */ + if (s->version == TLS1_VERSION) { + rr->length = 0; + goto start; + } +#endif + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + case SSL3_RT_CHANGE_CIPHER_SPEC: + case SSL3_RT_ALERT: + case SSL3_RT_HANDSHAKE: + /* + * we already handled all of these, with the possible exception of + * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not + * happen when type != rr->type + */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + goto f_err; + case SSL3_RT_APPLICATION_DATA: + /* + * At this point, we were expecting handshake data, but have + * application data. If the library was running inside ssl3_read() + * (i.e. in_read_app_data is set) and it makes sense to read + * application data at this point (session renegotiation not yet + * started), we will indulge it. + */ + if (s->s3->in_read_app_data && + (s->s3->total_renegotiations != 0) && + (((s->state & SSL_ST_CONNECT) && + (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->state <= SSL3_ST_CR_SRVR_HELLO_A) + ) || ((s->state & SSL_ST_ACCEPT) && + (s->state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->state >= SSL3_ST_SR_CLNT_HELLO_A) + ) + )) { + s->s3->in_read_app_data = 2; + return (-1); + } else { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + } + /* not reached */ + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (-1); +} + +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) +{ + int i; + +#ifndef OPENSSL_NO_SCTP + /* + * Check if we have to continue an interrupted handshake for reading + * belated app data with SCTP. + */ + if ((SSL_in_init(s) && !s->in_handshake) || + (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + (s->state == DTLS1_SCTP_ST_SR_READ_SOCK + || s->state == DTLS1_SCTP_ST_CR_READ_SOCK))) +#else + if (SSL_in_init(s) && !s->in_handshake) +#endif + { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG); + return -1; + } + + i = dtls1_write_bytes(s, type, buf_, len); + return i; +} + + /* + * this only happens when a client hello is received and a handshake + * is started. + */ +static int +have_handshake_fragment(SSL *s, int type, unsigned char *buf, + int len, int peek) +{ + + if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0)) + /* (partially) satisfy request from storage */ + { + unsigned char *src = s->d1->handshake_fragment; + unsigned char *dst = buf; + unsigned int k, n; + + /* peek == 0 */ + n = 0; + while ((len > 0) && (s->d1->handshake_fragment_len > 0)) { + *dst++ = *src++; + len--; + s->d1->handshake_fragment_len--; + n++; + } + /* move any remaining fragment bytes: */ + for (k = 0; k < s->d1->handshake_fragment_len; k++) + s->d1->handshake_fragment[k] = *src++; + return n; + } + + return 0; +} + +/* + * Call this to write data in records of type 'type' It will return <= 0 if + * not all data has been sent or non-blocking IO. + */ +int dtls1_write_bytes(SSL *s, int type, const void *buf, int len) +{ + int i; + + OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); + s->rwstate = SSL_NOTHING; + i = do_dtls1_write(s, type, buf, len, 0); + return i; +} + +int do_dtls1_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragment) +{ + unsigned char *p, *pseq; + int i, mac_size, clear = 0; + int prefix_len = 0; + int eivlen; + SSL3_RECORD *wr; + SSL3_BUFFER *wb; + SSL_SESSION *sess; + + /* + * first check if there is a SSL3_BUFFER still being written out. This + * will happen with non blocking IO + */ + if (s->s3->wbuf.left != 0) { + OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ + return (ssl3_write_pending(s, type, buf, len)); + } + + /* If we have an alert to send, lets send it */ + if (s->s3->alert_dispatch) { + i = s->method->ssl_dispatch_alert(s); + if (i <= 0) + return (i); + /* if it went, fall through and send more stuff */ + } + + if (len == 0 && !create_empty_fragment) + return 0; + + wr = &(s->s3->wrec); + wb = &(s->s3->wbuf); + sess = s->session; + + if ((sess == NULL) || + (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL)) + clear = 1; + + if (clear) + mac_size = 0; + else { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } + + /* DTLS implements explicit IV, so no need for empty fragments */ +#if 0 + /* + * 'create_empty_fragment' is true only when this function calls itself + */ + if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done + && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER) + { + /* + * countermeasure against known-IV weakness in CBC ciphersuites (see + * http://www.openssl.org/~bodo/tls-cbc.txt) + */ + + if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { + /* + * recursive function call with 'create_empty_fragment' set; this + * prepares and buffers the data for an empty fragment (these + * 'prefix_len' bytes are sent out later together with the actual + * payload) + */ + prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1); + if (prefix_len <= 0) + goto err; + + if (s->s3->wbuf.len < + (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) { + /* insufficient space */ + SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + s->s3->empty_fragment_done = 1; + } +#endif + p = wb->buf + prefix_len; + + /* write the header */ + + *(p++) = type & 0xff; + wr->type = type; + /* + * Special case: for hello verify request, client version 1.0 and we + * haven't decided which version to use yet send back using version 1.0 + * header: otherwise some clients will ignore it. + */ + if (s->method->version == DTLS_ANY_VERSION) { + *(p++) = DTLS1_VERSION >> 8; + *(p++) = DTLS1_VERSION & 0xff; + } else { + *(p++) = s->version >> 8; + *(p++) = s->version & 0xff; + } + + /* field where we are to write out packet epoch, seq num and len */ + pseq = p; + p += 10; + + /* Explicit IV length, block ciphers appropriate version flag */ + if (s->enc_write_ctx) { + int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); + if (mode == EVP_CIPH_CBC_MODE) { + eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); + if (eivlen <= 1) + eivlen = 0; + } + /* Need explicit part of IV for GCM mode */ + else if (mode == EVP_CIPH_GCM_MODE) + eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; + else + eivlen = 0; + } else + eivlen = 0; + + /* lets setup the record stuff. */ + wr->data = p + eivlen; /* make room for IV in case of CBC */ + wr->length = (int)len; + wr->input = (unsigned char *)buf; + + /* + * we now 'read' from wr->input, wr->length bytes into wr->data + */ + + /* first we compress */ + if (s->compress != NULL) { + if (!ssl3_do_compress(s)) { + SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_COMPRESSION_FAILURE); + goto err; + } + } else { + memcpy(wr->data, wr->input, wr->length); + wr->input = wr->data; + } + + /* + * we should still have the output to wr->data and the input from + * wr->input. Length should be wr->length. wr->data still points in the + * wb->buf + */ + + if (mac_size != 0) { + if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0) + goto err; + wr->length += mac_size; + } + + /* this is true regardless of mac size */ + wr->input = p; + wr->data = p; + + if (eivlen) + wr->length += eivlen; + + if (s->method->ssl3_enc->enc(s, 1) < 1) + goto err; + + /* record length after mac and block padding */ + /* + * if (type == SSL3_RT_APPLICATION_DATA || (type == SSL3_RT_ALERT && ! + * SSL_in_init(s))) + */ + + /* there's only one epoch between handshake and app data */ + + s2n(s->d1->w_epoch, pseq); + + /* XDTLS: ?? */ + /* + * else s2n(s->d1->handshake_epoch, pseq); + */ + + memcpy(pseq, &(s->s3->write_sequence[2]), 6); + pseq += 6; + s2n(wr->length, pseq); + + if (s->msg_callback) + s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH, + DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); + + /* + * we should now have wr->data pointing to the encrypted data, which is + * wr->length long + */ + wr->type = type; /* not needed but helps for debugging */ + wr->length += DTLS1_RT_HEADER_LENGTH; + +#if 0 /* this is now done at the message layer */ + /* buffer the record, making it easy to handle retransmits */ + if (type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC) + dtls1_buffer_record(s, wr->data, wr->length, + *((PQ_64BIT *) & (s->s3->write_sequence[0]))); +#endif + + ssl3_record_sequence_update(&(s->s3->write_sequence[0])); + + if (create_empty_fragment) { + /* + * we are in a recursive call; just return the length, don't write + * out anything here + */ + return wr->length; + } + + /* now let's set up wb */ + wb->left = prefix_len + wr->length; + wb->offset = 0; + + /* + * memorize arguments so that ssl3_write_pending can detect bad write + * retries later + */ + s->s3->wpend_tot = len; + s->s3->wpend_buf = buf; + s->s3->wpend_type = type; + s->s3->wpend_ret = len; + + /* we now just need to write the buffer */ + return ssl3_write_pending(s, type, buf, len); + err: + return -1; +} + +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) +{ + int cmp; + unsigned int shift; + const unsigned char *seq = s->s3->read_sequence; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + memcpy(s->s3->rrec.seq_num, seq, 8); + return 1; /* this record in new */ + } + shift = -cmp; + if (shift >= sizeof(bitmap->map) * 8) + return 0; /* stale, outside the window */ + else if (bitmap->map & (1UL << shift)) + return 0; /* record previously received */ + + memcpy(s->s3->rrec.seq_num, seq, 8); + return 1; +} + +static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) +{ + int cmp; + unsigned int shift; + const unsigned char *seq = s->s3->read_sequence; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + shift = cmp; + if (shift < sizeof(bitmap->map) * 8) + bitmap->map <<= shift, bitmap->map |= 1UL; + else + bitmap->map = 1UL; + memcpy(bitmap->max_seq_num, seq, 8); + } else { + shift = -cmp; + if (shift < sizeof(bitmap->map) * 8) + bitmap->map |= 1UL << shift; + } +} + +int dtls1_dispatch_alert(SSL *s) +{ + int i, j; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + unsigned char buf[DTLS1_AL_HEADER_LENGTH]; + unsigned char *ptr = &buf[0]; + + s->s3->alert_dispatch = 0; + + memset(buf, 0x00, sizeof(buf)); + *ptr++ = s->s3->send_alert[0]; + *ptr++ = s->s3->send_alert[1]; + +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { + s2n(s->d1->handshake_read_seq, ptr); +# if 0 + if (s->d1->r_msg_hdr.frag_off == 0) + /* + * waiting for a new msg + */ + else + s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */ +# endif + +# if 0 + fprintf(stderr, + "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n", + s->d1->handshake_read_seq, s->d1->r_msg_hdr.seq); +# endif + l2n3(s->d1->r_msg_hdr.frag_off, ptr); + } +#endif + + i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); + if (i <= 0) { + s->s3->alert_dispatch = 1; + /* fprintf( stderr, "not done with alert\n" ); */ + } else { + if (s->s3->send_alert[0] == SSL3_AL_FATAL +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +#endif + ) + (void)BIO_flush(s->wbio); + + if (s->msg_callback) + s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, + 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; + cb(s, SSL_CB_WRITE_ALERT, j); + } + } + return (i); +} + +static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, + unsigned int *is_next_epoch) +{ + + *is_next_epoch = 0; + + /* In current epoch, accept HM, CCS, DATA, & ALERT */ + if (rr->epoch == s->d1->r_epoch) + return &s->d1->bitmap; + + /* + * Only HM and ALERT messages can be from the next epoch and only if we + * have already processed all of the unprocessed records from the last + * epoch + */ + else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && + s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + *is_next_epoch = 1; + return &s->d1->next_bitmap; + } + + return NULL; +} + +#if 0 +static int +dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, + unsigned short *priority, unsigned long *offset) +{ + + /* alerts are passed up immediately */ + if (rr->type == SSL3_RT_APPLICATION_DATA || rr->type == SSL3_RT_ALERT) + return 0; + + /* + * Only need to buffer if a handshake is underway. (this implies that + * Hello Request and Client Hello are passed up immediately) + */ + if (SSL_in_init(s)) { + unsigned char *data = rr->data; + /* need to extract the HM/CCS sequence number here */ + if (rr->type == SSL3_RT_HANDSHAKE || + rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { + unsigned short seq_num; + struct hm_header_st msg_hdr; + struct ccs_header_st ccs_hdr; + + if (rr->type == SSL3_RT_HANDSHAKE) { + dtls1_get_message_header(data, &msg_hdr); + seq_num = msg_hdr.seq; + *offset = msg_hdr.frag_off; + } else { + dtls1_get_ccs_header(data, &ccs_hdr); + seq_num = ccs_hdr.seq; + *offset = 0; + } + + /* + * this is either a record we're waiting for, or a retransmit of + * something we happened to previously receive (higher layers + * will drop the repeat silently + */ + if (seq_num < s->d1->handshake_read_seq) + return 0; + if (rr->type == SSL3_RT_HANDSHAKE && + seq_num == s->d1->handshake_read_seq && + msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off) + return 0; + else if (seq_num == s->d1->handshake_read_seq && + (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC || + msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off)) + return 0; + else { + *priority = seq_num; + return 1; + } + } else /* unknown record type */ + return 0; + } + + return 0; +} +#endif + +void dtls1_reset_seq_numbers(SSL *s, int rw) +{ + unsigned char *seq; + unsigned int seq_bytes = sizeof(s->s3->read_sequence); + + if (rw & SSL3_CC_READ) { + seq = s->s3->read_sequence; + s->d1->r_epoch++; + memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); + memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); + + /* + * We must not use any buffered messages received from the previous + * epoch + */ + dtls1_clear_received_buffer(s); + } else { + seq = s->s3->write_sequence; + memcpy(s->d1->last_write_sequence, seq, + sizeof(s->s3->write_sequence)); + s->d1->w_epoch++; + } + + memset(seq, 0x00, seq_bytes); +} +/* ssl/t1_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. + */ + +#include +// #include "objects.h" +// #include "ssl_locl.h" +#include "srtp.h" + +#ifndef OPENSSL_NO_SRTP + +static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { + { + "SRTP_AES128_CM_SHA1_80", + SRTP_AES128_CM_SHA1_80, + }, + { + "SRTP_AES128_CM_SHA1_32", + SRTP_AES128_CM_SHA1_32, + }, +# if 0 + { + "SRTP_NULL_SHA1_80", + SRTP_NULL_SHA1_80, + }, + { + "SRTP_NULL_SHA1_32", + SRTP_NULL_SHA1_32, + }, +# endif + {0} +}; + +static int find_profile_by_name(char *profile_name, + SRTP_PROTECTION_PROFILE **pptr, unsigned len) +{ + SRTP_PROTECTION_PROFILE *p; + + p = srtp_known_profiles; + while (p->name) { + if ((len == strlen(p->name)) && !strncmp(p->name, profile_name, len)) { + *pptr = p; + return 0; + } + + p++; + } + + return 1; +} + +static int ssl_ctx_make_profiles(const char *profiles_string, + STACK_OF(SRTP_PROTECTION_PROFILE) **out) +{ + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles; + + char *col; + char *ptr = (char *)profiles_string; + + SRTP_PROTECTION_PROFILE *p; + + if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, + SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + return 1; + } + + do { + col = strchr(ptr, ':'); + + if (!find_profile_by_name(ptr, &p, + col ? col - ptr : (int)strlen(ptr))) { + if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + sk_SRTP_PROTECTION_PROFILE_free(profiles); + return 1; + } + + sk_SRTP_PROTECTION_PROFILE_push(profiles, p); + } else { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, + SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); + sk_SRTP_PROTECTION_PROFILE_free(profiles); + return 1; + } + + if (col) + ptr = col + 1; + } while (col); + + *out = profiles; + + return 0; +} + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) +{ + return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); +} + +int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) +{ + return ssl_ctx_make_profiles(profiles, &s->srtp_profiles); +} + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) +{ + if (s != NULL) { + if (s->srtp_profiles != NULL) { + return s->srtp_profiles; + } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) { + return s->ctx->srtp_profiles; + } + } + + return NULL; +} + +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) +{ + return s->srtp_profile; +} + +/* + * Note: this function returns 0 length if there are no profiles specified + */ +int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + int ct = 0; + int i; + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0; + SRTP_PROTECTION_PROFILE *prof; + + clnt = SSL_get_srtp_profiles(s); + ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */ + + if (p) { + if (ct == 0) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); + return 1; + } + + if ((2 + ct * 2 + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); + return 1; + } + + /* Add the length */ + s2n(ct * 2, p); + for (i = 0; i < ct; i++) { + prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); + s2n(prof->id, p); + } + + /* Add an empty use_mki value */ + *p++ = 0; + } + + *len = 2 + ct * 2 + 1; + + return 0; +} + +int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len, + int *al) +{ + SRTP_PROTECTION_PROFILE *sprof; + STACK_OF(SRTP_PROTECTION_PROFILE) *srvr; + int ct; + int mki_len; + int i, srtp_pref; + unsigned int id; + + /* Length value + the MKI length */ + if (len < 3) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + /* Pull off the length of the cipher suite list */ + n2s(d, ct); + len -= 2; + + /* Check that it is even */ + if (ct % 2) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + /* Check that lengths are consistent */ + if (len < (ct + 1)) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + srvr = SSL_get_srtp_profiles(s); + s->srtp_profile = NULL; + /* Search all profiles for a match initially */ + srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr); + + while (ct) { + n2s(d, id); + ct -= 2; + len -= 2; + + /* + * Only look for match in profiles of higher preference than + * current match. + * If no profiles have been have been configured then this + * does nothing. + */ + for (i = 0; i < srtp_pref; i++) { + sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i); + if (sprof->id == id) { + s->srtp_profile = sprof; + srtp_pref = i; + break; + } + } + } + + /* + * Now extract the MKI value as a sanity check, but discard it for now + */ + mki_len = *d; + d++; + len--; + + if (mki_len != len) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_MKI_VALUE); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + return 0; +} + +int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + if (p) { + if (maxlen < 5) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, + SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); + return 1; + } + + if (s->srtp_profile == 0) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, + SSL_R_USE_SRTP_NOT_NEGOTIATED); + return 1; + } + s2n(2, p); + s2n(s->srtp_profile->id, p); + *p++ = 0; + } + *len = 5; + + return 0; +} + +int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len, + int *al) +{ + unsigned id; + int i; + int ct; + + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; + SRTP_PROTECTION_PROFILE *prof; + + if (len != 5) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + n2s(d, ct); + if (ct != 2) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + n2s(d, id); + if (*d) { /* Must be no MKI, since we never offer one */ + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_MKI_VALUE); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 1; + } + + clnt = SSL_get_srtp_profiles(s); + + /* Throw an error if the server gave us an unsolicited extension */ + if (clnt == NULL) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_NO_SRTP_PROFILES); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + /* + * Check to see if the server gave us something we support (and + * presumably offered) + */ + for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { + prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); + + if (prof->id == id) { + s->srtp_profile = prof; + *al = 0; + return 0; + } + } + + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; +} + +#endif +/* ssl/d1_srvr.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "ssl_locl.h" +// #include "buffer.h" +// #include "rand.h" +// #include "objects.h" +// #include "evp.h" +// #include "x509.h" +// #include "md5.h" +// #include "bn.h" +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +static const SSL_METHOD *dtls1_get_server_method(int ver); +static int dtls1_send_hello_verify_request(SSL *s); + +static const SSL_METHOD *dtls1_get_server_method(int ver) +{ + if (ver == DTLS_ANY_VERSION) + return DTLS_server_method(); + else if (ver == DTLS1_VERSION) + return DTLSv1_server_method(); + else if (ver == DTLS1_2_VERSION) + return DTLSv1_2_server_method(); + else + return NULL; +} + +IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, + DTLSv1_server_method, + dtls1_accept, + ssl_undefined_function, + dtls1_get_server_method, DTLSv1_enc_data) + +IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, + DTLSv1_2_server_method, + dtls1_accept, + ssl_undefined_function, + dtls1_get_server_method, DTLSv1_2_enc_data) + +IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, + DTLS_server_method, + dtls1_accept, + ssl_undefined_function, + dtls1_get_server_method, DTLSv1_2_enc_data) + +int dtls1_accept(SSL *s) +{ + BUF_MEM *buf; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + unsigned long alg_k; + int ret = -1; + int new_state, state, skip = 0; + int listen; +#ifndef OPENSSL_NO_SCTP + unsigned char sctpauthkey[64]; + char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; +#endif + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + listen = s->d1->listen; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + s->d1->listen = listen; +#ifndef OPENSSL_NO_SCTP + /* + * Notify SCTP BIO socket to enter handshake mode and prevent stream + * identifier other than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + s->in_handshake, NULL); +#endif + + if (s->cert == NULL) { + SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_NO_CERTIFICATE_SET); + return (-1); + } +#ifndef OPENSSL_NO_HEARTBEATS + /* + * If we're awaiting a HeartbeatResponse, pretend we already got and + * don't await it anymore, because Heartbeats don't make sense during + * handshakes anyway. + */ + if (s->tlsext_hb_pending) { + dtls1_stop_timer(s); + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + /* s->state=SSL_ST_ACCEPT; */ + + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + case SSL_ST_OK | SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { + SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); + return -1; + } + s->type = SSL_ST_ACCEPT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + BUF_MEM_free(buf); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->init_buf = buf; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + s->init_num = 0; + s->d1->change_cipher_spec_ok = 0; + /* + * Should have been reset by ssl3_get_finished, too. + */ + s->s3->change_cipher_spec = 0; + + if (s->state != SSL_ST_RENEGOTIATE) { + /* + * Ok, we now need to push on a buffering BIO so that the + * output is sent in a way that TCP likes :-) ...but not with + * SCTP :-) + */ +#ifndef OPENSSL_NO_SCTP + if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) +#endif + if (!ssl_init_wbio_buffer(s, 1)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + s->state = SSL3_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + } else if (!s->s3->send_connection_binding && + !(s->options & + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + /* + * Server attempting to renegotiate with client that doesn't + * support secure renegotiation. + */ + SSLerr(SSL_F_DTLS1_ACCEPT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } else { + /* + * s->state == SSL_ST_RENEGOTIATE, we will just send a + * HelloRequest + */ + s->ctx->stats.sess_accept_renegotiate++; + s->state = SSL3_ST_SW_HELLO_REQ_A; + } + + break; + + case SSL3_ST_SW_HELLO_REQ_A: + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; + dtls1_clear_sent_buffer(s); + dtls1_start_timer(s); + ret = ssl3_send_hello_request(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + break; + + case SSL3_ST_SW_HELLO_REQ_C: + s->state = SSL_ST_OK; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + case SSL3_ST_SR_CLNT_HELLO_B: + case SSL3_ST_SR_CLNT_HELLO_C: + + s->shutdown = 0; + ret = ssl3_get_client_hello(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + + if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) + s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; + else + s->state = SSL3_ST_SW_SRVR_HELLO_A; + + s->init_num = 0; + + /* If we're just listening, stop here */ + if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { + ret = 2; + s->d1->listen = 0; + /* + * Set expected sequence numbers to continue the handshake. + */ + s->d1->handshake_read_seq = 2; + s->d1->handshake_write_seq = 1; + s->d1->next_handshake_write_seq = 1; + goto end; + } + + break; + + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + + ret = dtls1_send_hello_verify_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; + + /* HelloVerifyRequest resets Finished MAC */ + if (s->version != DTLS1_BAD_VER) + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + break; + +#ifndef OPENSSL_NO_SCTP + case DTLS1_SCTP_ST_SR_READ_SOCK: + + if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + s->s3->in_read_app_data = 2; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + + s->state = SSL3_ST_SR_FINISHED_A; + break; + + case DTLS1_SCTP_ST_SW_WRITE_SOCK: + ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); + if (ret < 0) + goto end; + + if (ret == 0) { + if (s->d1->next_state != SSL_ST_OK) { + s->s3->in_read_app_data = 2; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + } + + s->state = s->d1->next_state; + break; +#endif + + case SSL3_ST_SW_SRVR_HELLO_A: + case SSL3_ST_SW_SRVR_HELLO_B: + s->renegotiate = 2; + dtls1_start_timer(s); + ret = ssl3_send_server_hello(s); + if (ret <= 0) + goto end; + + if (s->hit) { +#ifndef OPENSSL_NO_SCTP + /* + * Add new shared key for SCTP-Auth, will be ignored if no + * SCTP used. + */ + snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0) <= 0) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->state = SSL3_ST_SW_CHANGE_A; +#else + s->state = SSL3_ST_SW_CHANGE_A; +#endif + } else + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_A: + case SSL3_ST_SW_CERT_B: + /* Check if it is anon DH or normal PSK */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + dtls1_start_timer(s); + ret = ssl3_send_server_certificate(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state = SSL3_ST_SW_CERT_STATUS_A; + else + s->state = SSL3_ST_SW_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_SW_KEY_EXCH_A; + } +#else + } else + skip = 1; + + s->state = SSL3_ST_SW_KEY_EXCH_A; +#endif + s->init_num = 0; + break; + + case SSL3_ST_SW_KEY_EXCH_A: + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* + * clear this, it may get reset by + * send_server_key_exchange + */ + s->s3->tmp.use_rsa_tmp = 0; + + /* + * only send if a DH key exchange or RSA but we have a sign only + * certificate + */ + if (0 + /* + * PSK: send ServerKeyExchange if PSK identity hint if + * provided + */ +#ifndef OPENSSL_NO_PSK + || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) +#endif + || (alg_k & SSL_kDHE) + || (alg_k & SSL_kEECDH) + || ((alg_k & SSL_kRSA) + && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL + || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) + && EVP_PKEY_size(s->cert->pkeys + [SSL_PKEY_RSA_ENC].privatekey) * + 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) + ) + ) + ) + ) { + dtls1_start_timer(s); + ret = ssl3_send_server_key_exchange(s); + if (ret <= 0) + goto end; + } else + skip = 1; + + s->state = SSL3_ST_SW_CERT_REQ_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_REQ_A: + case SSL3_ST_SW_CERT_REQ_B: + if ( /* don't request cert unless asked for it: */ + !(s->verify_mode & SSL_VERIFY_PEER) || + /* + * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert + * during re-negotiation: + */ + ((s->session->peer != NULL) && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || + /* + * never request cert in anonymous ciphersuites (see + * section "Certificate request" in SSL 3 drafts and in + * RFC 2246): + */ + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + /* + * ... except when the application insists on + * verification (against the specs, but s3_clnt.c accepts + * this for SSL 3) + */ + !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || + /* + * never request cert in Kerberos ciphersuites + */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) + /* + * With normal PSK Certificates and Certificate Requests + * are omitted + */ + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + /* no cert request */ + skip = 1; + s->s3->tmp.cert_request = 0; + s->state = SSL3_ST_SW_SRVR_DONE_A; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; + s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +#endif + } else { + s->s3->tmp.cert_request = 1; + dtls1_start_timer(s); + ret = ssl3_send_certificate_request(s); + if (ret <= 0) + goto end; +#ifndef NETSCAPE_HANG_BUG + s->state = SSL3_ST_SW_SRVR_DONE_A; +# ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; + s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +# endif +#else + s->state = SSL3_ST_SW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; +# ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = s->s3->tmp.next_state; + s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +# endif +#endif + s->init_num = 0; + } + break; + + case SSL3_ST_SW_SRVR_DONE_A: + case SSL3_ST_SW_SRVR_DONE_B: + dtls1_start_timer(s); + ret = ssl3_send_server_done(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + break; + + case SSL3_ST_SW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + /* + * If the write error was fatal, stop trying + */ + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + } + + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_SR_CERT_A: + case SSL3_ST_SR_CERT_B: + if (s->s3->tmp.cert_request) { + ret = ssl3_get_client_certificate(s); + if (ret <= 0) + goto end; + } + s->init_num = 0; + s->state = SSL3_ST_SR_KEY_EXCH_A; + break; + + case SSL3_ST_SR_KEY_EXCH_A: + case SSL3_ST_SR_KEY_EXCH_B: + ret = ssl3_get_client_key_exchange(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SCTP + /* + * Add new shared key for SCTP-Auth, will be ignored if no SCTP + * used. + */ + snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0) <= 0) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif + + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + if (ret == 2) { + /* + * For the ECDH ciphersuites when the client sends its ECDH + * pub key in a certificate, the CertificateVerify message is + * not sent. + */ + s->state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + } else if (SSL_USE_SIGALGS(s)) { + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + if (!s->session->peer) + break; + /* + * For sigalgs freeze the handshake buffer at this point and + * digest cached records. + */ + if (!s->s3->handshake_buffer) { + SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!ssl3_digest_cached_records(s)) { + s->state = SSL_ST_ERR; + return -1; + } + } else { + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + /* + * We need to get hashes here so if there is a client cert, + * it can be verified + */ + s->method->ssl3_enc->cert_verify_mac(s, + NID_md5, + &(s->s3-> + tmp.cert_verify_md + [0])); + s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, + &(s->s3-> + tmp.cert_verify_md + [MD5_DIGEST_LENGTH])); + } + break; + + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + ret = ssl3_get_cert_verify(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + state == SSL_ST_RENEGOTIATE) + s->state = DTLS1_SCTP_ST_SR_READ_SOCK; + else +#endif + s->state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: + /* + * Enable CCS. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. This *should* be the + * first time we have received one - but we check anyway to be + * cautious. + * s->s3->change_cipher_spec is set when a CCS is + * processed in d1_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->d1->change_cipher_spec_ok = 1; + ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->hit) + s->state = SSL_ST_OK; +#ifndef OPENSSL_NO_TLSEXT + else if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; +#endif + else + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret = ssl3_send_newsession_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret = ssl3_send_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_KEY_EXCH_A; + s->init_num = 0; + break; + +#endif + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_SW_CHANGE_B: + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + ret = dtls1_send_change_cipher_spec(s, + SSL3_ST_SW_CHANGE_A, + SSL3_ST_SW_CHANGE_B); + + if (ret <= 0) + goto end; + +#ifndef OPENSSL_NO_SCTP + if (!s->hit) { + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); + } +#endif + + s->state = SSL3_ST_SW_FINISHED_A; + s->init_num = 0; + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_SERVER_WRITE)) + { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + break; + + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_SW_FINISHED_B: + ret = ssl3_send_finished(s, + SSL3_ST_SW_FINISHED_A, + SSL3_ST_SW_FINISHED_B, + s->method-> + ssl3_enc->server_finished_label, + s->method-> + ssl3_enc->server_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + if (s->hit) { + s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; + +#ifndef OPENSSL_NO_SCTP + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); +#endif + } else { + s->s3->tmp.next_state = SSL_ST_OK; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = s->s3->tmp.next_state; + s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +#endif + } + s->init_num = 0; + break; + + case SSL_ST_OK: + /* clean a few things up */ + ssl3_cleanup_key_block(s); + +#if 0 + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; +#endif + + /* remove buffering on output */ + ssl_free_wbio_buffer(s); + + s->init_num = 0; + + if (s->renegotiate == 2) { /* skipped if we just sent a + * HelloRequest */ + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + s->handshake_func = dtls1_accept; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + } + + ret = 1; + + /* done handshaking, next message is client hello */ + s->d1->handshake_read_seq = 0; + /* next message is server hello */ + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; + dtls1_clear_received_buffer(s); + goto end; + /* break; */ + + case SSL_ST_ERR: + default: + SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + end: + /* BIO_flush(s->wbio); */ + + s->in_handshake--; +#ifndef OPENSSL_NO_SCTP + /* + * Notify SCTP BIO socket to leave handshake mode and prevent stream + * identifier other than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + s->in_handshake, NULL); +#endif + + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +int dtls1_send_hello_verify_request(SSL *s) +{ + unsigned int msg_len; + unsigned char *msg, *buf, *p; + + if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) { + buf = (unsigned char *)s->init_buf->data; + + msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); + /* Always use DTLS 1.0 version: see RFC 6347 */ + *(p++) = DTLS1_VERSION >> 8; + *(p++) = DTLS1_VERSION & 0xFF; + + if (s->ctx->app_gen_cookie_cb == NULL || + s->ctx->app_gen_cookie_cb(s, s->d1->cookie, + &(s->d1->cookie_len)) == 0) { + SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST, + ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return 0; + } + + *(p++) = (unsigned char)s->d1->cookie_len; + memcpy(p, s->d1->cookie, s->d1->cookie_len); + p += s->d1->cookie_len; + msg_len = p - msg; + + dtls1_set_message_header(s, buf, + DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, + msg_len); + + s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B; + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + } + + /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} diff --git a/Sources/COpenSSL/d1_lib.c b/Sources/COpenSSL/d1_lib.c new file mode 100644 index 00000000..ab052545 --- /dev/null +++ b/Sources/COpenSSL/d1_lib.c @@ -0,0 +1,588 @@ +/* ssl/d1_lib.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#define USE_SOCKETS +#include "objects.h" +#include "ssl_locl.h" + +#if defined(OPENSSL_SYS_VMS) +# include +#endif + +static void get_current_time(struct timeval *t); +static void dtls1_set_handshake_header(SSL *s, int type, unsigned long len); +static int dtls1_handshake_write(SSL *s); +const char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT; +int dtls1_listen(SSL *s, struct sockaddr *client); + +SSL3_ENC_METHOD DTLSv1_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV, + DTLS1_HM_HEADER_LENGTH, + dtls1_set_handshake_header, + dtls1_handshake_write +}; + +SSL3_ENC_METHOD DTLSv1_2_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS + | SSL_ENC_FLAG_SHA256_PRF | SSL_ENC_FLAG_TLS1_2_CIPHERS, + DTLS1_HM_HEADER_LENGTH, + dtls1_set_handshake_header, + dtls1_handshake_write +}; + +long dtls1_default_timeout(void) +{ + /* + * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for + * http, the cache would over fill + */ + return (60 * 60 * 2); +} + +int dtls1_new(SSL *s) +{ + DTLS1_STATE *d1; + + if (!ssl3_new(s)) + return (0); + if ((d1 = OPENSSL_malloc(sizeof(*d1))) == NULL) + return (0); + memset(d1, 0, sizeof(*d1)); + + /* d1->handshake_epoch=0; */ + + d1->unprocessed_rcds.q = pqueue_new(); + d1->processed_rcds.q = pqueue_new(); + d1->buffered_messages = pqueue_new(); + d1->sent_messages = pqueue_new(); + d1->buffered_app_data.q = pqueue_new(); + + if (s->server) { + d1->cookie_len = sizeof(s->d1->cookie); + } + + d1->link_mtu = 0; + d1->mtu = 0; + + if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q + || !d1->buffered_messages || !d1->sent_messages + || !d1->buffered_app_data.q) { + if (d1->unprocessed_rcds.q) + pqueue_free(d1->unprocessed_rcds.q); + if (d1->processed_rcds.q) + pqueue_free(d1->processed_rcds.q); + if (d1->buffered_messages) + pqueue_free(d1->buffered_messages); + if (d1->sent_messages) + pqueue_free(d1->sent_messages); + if (d1->buffered_app_data.q) + pqueue_free(d1->buffered_app_data.q); + OPENSSL_free(d1); + return (0); + } + + s->d1 = d1; + s->method->ssl_clear(s); + return (1); +} + +static void dtls1_clear_queues(SSL *s) +{ + pitem *item = NULL; + DTLS1_RECORD_DATA *rdata; + + while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } + + dtls1_clear_received_buffer(s); + dtls1_clear_sent_buffer(s); +} + +void dtls1_clear_received_buffer(SSL *s) +{ + pitem *item = NULL; + hm_fragment *frag = NULL; + + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } +} + +void dtls1_clear_sent_buffer(SSL *s) +{ + pitem *item = NULL; + hm_fragment *frag = NULL; + + while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } +} + + +void dtls1_free(SSL *s) +{ + ssl3_free(s); + + dtls1_clear_queues(s); + + pqueue_free(s->d1->unprocessed_rcds.q); + pqueue_free(s->d1->processed_rcds.q); + pqueue_free(s->d1->buffered_messages); + pqueue_free(s->d1->sent_messages); + pqueue_free(s->d1->buffered_app_data.q); + + OPENSSL_free(s->d1); + s->d1 = NULL; +} + +void dtls1_clear(SSL *s) +{ + pqueue unprocessed_rcds; + pqueue processed_rcds; + pqueue buffered_messages; + pqueue sent_messages; + pqueue buffered_app_data; + unsigned int mtu; + unsigned int link_mtu; + + if (s->d1) { + unprocessed_rcds = s->d1->unprocessed_rcds.q; + processed_rcds = s->d1->processed_rcds.q; + buffered_messages = s->d1->buffered_messages; + sent_messages = s->d1->sent_messages; + buffered_app_data = s->d1->buffered_app_data.q; + mtu = s->d1->mtu; + link_mtu = s->d1->link_mtu; + + dtls1_clear_queues(s); + + memset(s->d1, 0, sizeof(*(s->d1))); + + if (s->server) { + s->d1->cookie_len = sizeof(s->d1->cookie); + } + + if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { + s->d1->mtu = mtu; + s->d1->link_mtu = link_mtu; + } + + s->d1->unprocessed_rcds.q = unprocessed_rcds; + s->d1->processed_rcds.q = processed_rcds; + s->d1->buffered_messages = buffered_messages; + s->d1->sent_messages = sent_messages; + s->d1->buffered_app_data.q = buffered_app_data; + } + + ssl3_clear(s); + if (s->options & SSL_OP_CISCO_ANYCONNECT) + s->client_version = s->version = DTLS1_BAD_VER; + else if (s->method->version == DTLS_ANY_VERSION) + s->version = DTLS1_2_VERSION; + else + s->version = s->method->version; +} + +long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + + switch (cmd) { + case DTLS_CTRL_GET_TIMEOUT: + if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) { + ret = 1; + } + break; + case DTLS_CTRL_HANDLE_TIMEOUT: + ret = dtls1_handle_timeout(s); + break; + case DTLS_CTRL_LISTEN: + ret = dtls1_listen(s, parg); + break; + case SSL_CTRL_CHECK_PROTO_VERSION: + /* + * For library-internal use; checks that the current protocol is the + * highest enabled version (according to s->ctx->method, as version + * negotiation may have changed s->method). + */ + if (s->version == s->ctx->method->version) + return 1; + /* + * Apparently we're using a version-flexible SSL_METHOD (not at its + * highest protocol version). + */ + if (s->ctx->method->version == DTLS_method()->version) { +#if DTLS_MAX_VERSION != DTLS1_2_VERSION +# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. +#endif + if (!(s->options & SSL_OP_NO_DTLSv1_2)) + return s->version == DTLS1_2_VERSION; + if (!(s->options & SSL_OP_NO_DTLSv1)) + return s->version == DTLS1_VERSION; + } + return 0; /* Unexpected state; fail closed. */ + case DTLS_CTRL_SET_LINK_MTU: + if (larg < (long)dtls1_link_min_mtu()) + return 0; + s->d1->link_mtu = larg; + return 1; + case DTLS_CTRL_GET_LINK_MIN_MTU: + return (long)dtls1_link_min_mtu(); + case SSL_CTRL_SET_MTU: + /* + * We may not have a BIO set yet so can't call dtls1_min_mtu() + * We'll have to make do with dtls1_link_min_mtu() and max overhead + */ + if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD) + return 0; + s->d1->mtu = larg; + return larg; + default: + ret = ssl3_ctrl(s, cmd, larg, parg); + break; + } + return (ret); +} + +/* + * As it's impossible to use stream ciphers in "datagram" mode, this + * simple filter is designed to disengage them in DTLS. Unfortunately + * there is no universal way to identify stream SSL_CIPHER, so we have + * to explicitly list their SSL_* codes. Currently RC4 is the only one + * available, but if new ones emerge, they will have to be added... + */ +const SSL_CIPHER *dtls1_get_cipher(unsigned int u) +{ + const SSL_CIPHER *ciph = ssl3_get_cipher(u); + + if (ciph != NULL) { + if (ciph->algorithm_enc == SSL_RC4) + return NULL; + } + + return ciph; +} + +void dtls1_start_timer(SSL *s) +{ +#ifndef OPENSSL_NO_SCTP + /* Disable timer for SCTP */ + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); + return; + } +#endif + + /* If timer is not set, initialize duration with 1 second */ + if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { + s->d1->timeout_duration = 1; + } + + /* Set timeout to current time */ + get_current_time(&(s->d1->next_timeout)); + + /* Add duration to current time */ + s->d1->next_timeout.tv_sec += s->d1->timeout_duration; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); +} + +struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft) +{ + struct timeval timenow; + + /* If no timeout is set, just return NULL */ + if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { + return NULL; + } + + /* Get current time */ + get_current_time(&timenow); + + /* If timer already expired, set remaining time to 0 */ + if (s->d1->next_timeout.tv_sec < timenow.tv_sec || + (s->d1->next_timeout.tv_sec == timenow.tv_sec && + s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + memset(timeleft, 0, sizeof(struct timeval)); + return timeleft; + } + + /* Calculate time left until timer expires */ + memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); + timeleft->tv_sec -= timenow.tv_sec; + timeleft->tv_usec -= timenow.tv_usec; + if (timeleft->tv_usec < 0) { + timeleft->tv_sec--; + timeleft->tv_usec += 1000000; + } + + /* + * If remaining time is less than 15 ms, set it to 0 to prevent issues + * because of small devergences with socket timeouts. + */ + if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { + memset(timeleft, 0, sizeof(struct timeval)); + } + + return timeleft; +} + +int dtls1_is_timer_expired(SSL *s) +{ + struct timeval timeleft; + + /* Get time left until timeout, return false if no timer running */ + if (dtls1_get_timeout(s, &timeleft) == NULL) { + return 0; + } + + /* Return false if timer is not expired yet */ + if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { + return 0; + } + + /* Timer expired, so return true */ + return 1; +} + +void dtls1_double_timeout(SSL *s) +{ + s->d1->timeout_duration *= 2; + if (s->d1->timeout_duration > 60) + s->d1->timeout_duration = 60; + dtls1_start_timer(s); +} + +void dtls1_stop_timer(SSL *s) +{ + /* Reset everything */ + memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); + memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); + s->d1->timeout_duration = 1; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); + /* Clear retransmission buffer */ + dtls1_clear_sent_buffer(s); +} + +int dtls1_check_timeout_num(SSL *s) +{ + unsigned int mtu; + + s->d1->timeout.num_alerts++; + + /* Reduce MTU after 2 unsuccessful retransmissions */ + if (s->d1->timeout.num_alerts > 2 + && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + mtu = + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, + NULL); + if (mtu < s->d1->mtu) + s->d1->mtu = mtu; + } + + if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { + /* fail the connection, enough alerts have been sent */ + SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED); + return -1; + } + + return 0; +} + +int dtls1_handle_timeout(SSL *s) +{ + /* if no timer is expired, don't do anything */ + if (!dtls1_is_timer_expired(s)) { + return 0; + } + + dtls1_double_timeout(s); + + if (dtls1_check_timeout_num(s) < 0) + return -1; + + s->d1->timeout.read_timeouts++; + if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { + s->d1->timeout.read_timeouts = 1; + } +#ifndef OPENSSL_NO_HEARTBEATS + if (s->tlsext_hb_pending) { + s->tlsext_hb_pending = 0; + return dtls1_heartbeat(s); + } +#endif + + dtls1_start_timer(s); + return dtls1_retransmit_buffered_messages(s); +} + +static void get_current_time(struct timeval *t) +{ +#if defined(_WIN32) + SYSTEMTIME st; + union { + unsigned __int64 ul; + FILETIME ft; + } now; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &now.ft); +# ifdef __MINGW32__ + now.ul -= 116444736000000000ULL; +# else + now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ +# endif + t->tv_sec = (long)(now.ul / 10000000); + t->tv_usec = ((int)(now.ul % 10000000)) / 10; +#elif defined(OPENSSL_SYS_VMS) + struct timeb tb; + ftime(&tb); + t->tv_sec = (long)tb.time; + t->tv_usec = (long)tb.millitm * 1000; +#else + gettimeofday(t, NULL); +#endif +} + +int dtls1_listen(SSL *s, struct sockaddr *client) +{ + int ret; + + /* Ensure there is no state left over from a previous invocation */ + SSL_clear(s); + + SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); + s->d1->listen = 1; + + ret = SSL_accept(s); + if (ret <= 0) + return ret; + + (void)BIO_dgram_get_peer(SSL_get_rbio(s), client); + return 1; +} + +static void dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) +{ + unsigned char *p = (unsigned char *)s->init_buf->data; + dtls1_set_message_header(s, p, htype, len, 0, len); + s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH; + s->init_off = 0; + /* Buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); +} + +static int dtls1_handshake_write(SSL *s) +{ + return dtls1_do_write(s, SSL3_RT_HANDSHAKE); +} diff --git a/Sources/COpenSSL/d2i_.c b/Sources/COpenSSL/d2i_.c new file mode 100644 index 00000000..de45a985 --- /dev/null +++ b/Sources/COpenSSL/d2i_.c @@ -0,0 +1,313 @@ +/* crypto/asn1/d2i_pr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn.h" +#include "evp.h" +#include "objects.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +#include "x509.h" +#include "asn1.h" +#include "asn1_locl.h" + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length) +{ + EVP_PKEY *ret; + const unsigned char *p = *pp; + + if ((a == NULL) || (*a == NULL)) { + if ((ret = EVP_PKEY_new()) == NULL) { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB); + return (NULL); + } + } else { + ret = *a; +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) { + ENGINE_finish(ret->engine); + ret->engine = NULL; + } +#endif + } + + if (!EVP_PKEY_set_type(ret, type)) { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + } + + if (!ret->ameth->old_priv_decode || + !ret->ameth->old_priv_decode(ret, &p, length)) { + if (ret->ameth->priv_decode) { + EVP_PKEY *tmp; + PKCS8_PRIV_KEY_INFO *p8 = NULL; + p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); + if (!p8) + goto err; + tmp = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (tmp == NULL) + goto err; + EVP_PKEY_free(ret); + ret = tmp; + } else { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); + goto err; + } + } + *pp = p; + if (a != NULL) + (*a) = ret; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + EVP_PKEY_free(ret); + return (NULL); +} + +/* + * This works like d2i_PrivateKey() except it automatically works out the + * type + */ + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length) +{ + STACK_OF(ASN1_TYPE) *inkey; + const unsigned char *p; + int keytype; + p = *pp; + /* + * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by + * analyzing it we can determine the passed structure: this assumes the + * input is surrounded by an ASN1 SEQUENCE. + */ + inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); + p = *pp; + /* + * Since we only need to discern "traditional format" RSA and DSA keys we + * can just count the elements. + */ + if (sk_ASN1_TYPE_num(inkey) == 6) + keytype = EVP_PKEY_DSA; + else if (sk_ASN1_TYPE_num(inkey) == 4) + keytype = EVP_PKEY_EC; + else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not + * traditional format */ + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); + EVP_PKEY *ret; + + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + if (!p8) { + ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, + ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return NULL; + } + ret = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (ret == NULL) + return NULL; + *pp = p; + if (a) { + *a = ret; + } + return ret; + } else + keytype = EVP_PKEY_RSA; + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + return d2i_PrivateKey(keytype, a, pp, length); +} +/* crypto/asn1/d2i_pu.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "evp.h" +// #include "objects.h" +// #include "asn1.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_EC +# include "ec.h" +#endif + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length) +{ + EVP_PKEY *ret; + + if ((a == NULL) || (*a == NULL)) { + if ((ret = EVP_PKEY_new()) == NULL) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); + return (NULL); + } + } else + ret = *a; + + if (!EVP_PKEY_set_type(ret, type)) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); + goto err; + } + + switch (EVP_PKEY_id(ret)) { +#ifndef OPENSSL_NO_RSA + case EVP_PKEY_RSA: + /* TMP UGLY CAST */ + if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, + (const unsigned char **)pp, + length)) == NULL) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + goto err; + } + break; +#endif +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + /* TMP UGLY CAST */ + if (!d2i_DSAPublicKey(&(ret->pkey.dsa), + (const unsigned char **)pp, length)) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + goto err; + } + break; +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + if (!o2i_ECPublicKey(&(ret->pkey.ec), + (const unsigned char **)pp, length)) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + goto err; + } + break; +#endif + default: + ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + /* break; */ + } + if (a != NULL) + (*a) = ret; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + EVP_PKEY_free(ret); + return (NULL); +} diff --git a/Sources/COpenSSL/des.h b/Sources/COpenSSL/des.h new file mode 100644 index 00000000..7e91d13c --- /dev/null +++ b/Sources/COpenSSL/des.h @@ -0,0 +1,257 @@ +/* crypto/des/des.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_NEW_DES_H +# define HEADER_NEW_DES_H + +# include "e_os2.h" /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG + * (via openssl/opensslconf.h */ + +# ifdef OPENSSL_NO_DES +# error DES is disabled. +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char DES_cblock[8]; +typedef /* const */ unsigned char const_DES_cblock[8]; +/* + * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and + * const_DES_cblock * are incompatible pointer types. + */ + +typedef struct DES_ks { + union { + DES_cblock cblock; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG deslong[2]; + } ks[16]; +} DES_key_schedule; + +# ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT +# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT +# define OPENSSL_ENABLE_OLD_DES_SUPPORT +# endif +# endif + +# ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT +# include "des_old.h" +# endif + +# define DES_KEY_SZ (sizeof(DES_cblock)) +# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +# define DES_ENCRYPT 1 +# define DES_DECRYPT 0 + +# define DES_CBC_MODE 0 +# define DES_PCBC_MODE 1 + +# define DES_ecb2_encrypt(i,o,k1,k2,e) \ + DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */ +# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key) +OPENSSL_DECLARE_GLOBAL(int, DES_rw_mode); /* defaults to DES_PCBC_MODE */ +# define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode) + +const char *DES_options(void); +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc); +DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec); +/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ +void DES_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc); +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc); + +/* + * This is the DES encryption function that gets called by just about every + * other DES routine in the library. You should not use this function except + * to implement 'modes' of DES. I say this because the functions that call + * this routine do the conversion from 'char *' to long, and this needs to be + * done to make sure 'non-aligned' memory access do not occur. The + * characters are loaded 'little endian'. Data is a pointer to 2 unsigned + * long's and ks is the DES_key_schedule to use. enc, is non zero specifies + * encryption, zero if decryption. + */ +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc); + +/* + * This functions is the same as DES_encrypt1() except that the DES initial + * permutation (IP) and final permutation (FP) have been left out. As for + * DES_encrypt1(), you should not use this function. It is used by the + * routines in the library that implement triple DES. IP() DES_encrypt2() + * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1() + * DES_encrypt1() DES_encrypt1() except faster :-). + */ +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc); + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, DES_cblock *ivec, int enc); +void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec1, DES_cblock *ivec2, int enc); +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc); +void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num); +# if 0 +void DES_xwhite_in2out(const_DES_cblock *DES_key, const_DES_cblock *in_white, + DES_cblock *out_white); +# endif + +int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv); +int DES_enc_write(int fd, const void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv); +char *DES_fcrypt(const char *buf, const char *salt, char *ret); +char *DES_crypt(const char *buf, const char *salt); +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec); +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed); +int DES_random_key(DES_cblock *ret); +void DES_set_odd_parity(DES_cblock *key); +int DES_check_key_parity(const_DES_cblock *key); +int DES_is_weak_key(const_DES_cblock *key); +/* + * DES_set_key (= set_key = DES_key_sched = key_sched) calls + * DES_set_key_checked if global variable DES_check_key is set, + * DES_set_key_unchecked otherwise. + */ +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); +# ifdef OPENSSL_FIPS +void private_DES_set_key_unchecked(const_DES_cblock *key, + DES_key_schedule *schedule); +# endif +void DES_string_to_key(const char *str, DES_cblock *key); +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc); +void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num); + +int DES_read_password(DES_cblock *key, const char *prompt, int verify); +int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, + const char *prompt, int verify); + +# define DES_fixup_key_parity DES_set_odd_parity + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/des_enc.c b/Sources/COpenSSL/des_enc.c new file mode 100644 index 00000000..21bdcb30 --- /dev/null +++ b/Sources/COpenSSL/des_enc.c @@ -0,0 +1,389 @@ +/* crypto/des/des_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" +#include "spr.h" + +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) +{ + register DES_LONG l, r, t, u; +#ifdef DES_PTR + register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif +#ifndef DES_UNROLL + register int i; +#endif + register DES_LONG *s; + + r = data[0]; + l = data[1]; + + IP(r, l); + /* + * Things have been modified so that the initial rotate is done outside + * the loop. This required the DES_SPtrans values in sp.h to be rotated + * 1 bit to the right. One perl script later and things have a 5% speed + * up on a sparc2. Thanks to Richard Outerbridge + * <71755.204@CompuServe.COM> for pointing this out. + */ + /* clear the top bits on machines with 8byte longs */ + /* shift left by 2 */ + r = ROTATE(r, 29) & 0xffffffffL; + l = ROTATE(l, 29) & 0xffffffffL; + + s = ks->ks->deslong; + /* + * I don't know if it is worth the effort of loop unrolling the inner + * loop + */ + if (enc) { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#else + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#endif + } else { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 30); /* 16 */ + D_ENCRYPT(r, l, 28); /* 15 */ + D_ENCRYPT(l, r, 26); /* 14 */ + D_ENCRYPT(r, l, 24); /* 13 */ + D_ENCRYPT(l, r, 22); /* 12 */ + D_ENCRYPT(r, l, 20); /* 11 */ + D_ENCRYPT(l, r, 18); /* 10 */ + D_ENCRYPT(r, l, 16); /* 9 */ + D_ENCRYPT(l, r, 14); /* 8 */ + D_ENCRYPT(r, l, 12); /* 7 */ + D_ENCRYPT(l, r, 10); /* 6 */ + D_ENCRYPT(r, l, 8); /* 5 */ + D_ENCRYPT(l, r, 6); /* 4 */ + D_ENCRYPT(r, l, 4); /* 3 */ + D_ENCRYPT(l, r, 2); /* 2 */ + D_ENCRYPT(r, l, 0); /* 1 */ +#else + for (i = 30; i > 0; i -= 4) { + D_ENCRYPT(l, r, i - 0); /* 16 */ + D_ENCRYPT(r, l, i - 2); /* 15 */ + } +#endif + } + + /* rotate and clear the top bits on machines with 8byte longs */ + l = ROTATE(l, 3) & 0xffffffffL; + r = ROTATE(r, 3) & 0xffffffffL; + + FP(r, l); + data[0] = l; + data[1] = r; + l = r = t = u = 0; +} + +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc) +{ + register DES_LONG l, r, t, u; +#ifdef DES_PTR + register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif +#ifndef DES_UNROLL + register int i; +#endif + register DES_LONG *s; + + r = data[0]; + l = data[1]; + + /* + * Things have been modified so that the initial rotate is done outside + * the loop. This required the DES_SPtrans values in sp.h to be rotated + * 1 bit to the right. One perl script later and things have a 5% speed + * up on a sparc2. Thanks to Richard Outerbridge + * <71755.204@CompuServe.COM> for pointing this out. + */ + /* clear the top bits on machines with 8byte longs */ + r = ROTATE(r, 29) & 0xffffffffL; + l = ROTATE(l, 29) & 0xffffffffL; + + s = ks->ks->deslong; + /* + * I don't know if it is worth the effort of loop unrolling the inner + * loop + */ + if (enc) { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#else + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#endif + } else { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 30); /* 16 */ + D_ENCRYPT(r, l, 28); /* 15 */ + D_ENCRYPT(l, r, 26); /* 14 */ + D_ENCRYPT(r, l, 24); /* 13 */ + D_ENCRYPT(l, r, 22); /* 12 */ + D_ENCRYPT(r, l, 20); /* 11 */ + D_ENCRYPT(l, r, 18); /* 10 */ + D_ENCRYPT(r, l, 16); /* 9 */ + D_ENCRYPT(l, r, 14); /* 8 */ + D_ENCRYPT(r, l, 12); /* 7 */ + D_ENCRYPT(l, r, 10); /* 6 */ + D_ENCRYPT(r, l, 8); /* 5 */ + D_ENCRYPT(l, r, 6); /* 4 */ + D_ENCRYPT(r, l, 4); /* 3 */ + D_ENCRYPT(l, r, 2); /* 2 */ + D_ENCRYPT(r, l, 0); /* 1 */ +#else + for (i = 30; i > 0; i -= 4) { + D_ENCRYPT(l, r, i - 0); /* 16 */ + D_ENCRYPT(r, l, i - 2); /* 15 */ + } +#endif + } + /* rotate and clear the top bits on machines with 8byte longs */ + data[0] = ROTATE(l, 3) & 0xffffffffL; + data[1] = ROTATE(r, 3) & 0xffffffffL; + l = r = t = u = 0; +} + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3) +{ + register DES_LONG l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT); + DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT); + DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3) +{ + register DES_LONG l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT); + DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT); + DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +#ifndef DES_DEFAULT_OPTIONS + +# undef CBC_ENC_C__DONT_UPDATE_IV +# include "ncbc_enc.h" /* DES_ncbc_encrypt */ + +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc) +{ + register DES_LONG tin0, tin1; + register DES_LONG tout0, tout1, xor0, xor1; + register const unsigned char *in; + unsigned char *out; + register long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + in = input; + out = output; + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + register DES_LONG t0, t1; + + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = t0; + xor1 = t1; + } + if (l != -8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = t0; + xor1 = t1; + } + + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +#endif /* DES_DEFAULT_OPTIONS */ diff --git a/Sources/COpenSSL/des_locl.h b/Sources/COpenSSL/des_locl.h new file mode 100644 index 00000000..ae7127f5 --- /dev/null +++ b/Sources/COpenSSL/des_locl.h @@ -0,0 +1,443 @@ +/* crypto/des/des_locl.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DES_LOCL_H +# define HEADER_DES_LOCL_H + +# include "e_os2.h" + +# if defined(OPENSSL_SYS_WIN32) +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +# endif + +# include +# include + +# ifndef OPENSSL_SYS_MSDOS +# if !defined(OPENSSL_SYS_VMS) || defined(__DECC) +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +# include +# endif +# endif +# include "des.h" + +# ifdef OPENSSL_SYS_MSDOS /* Visual C++ 2.1 (Windows NT/95) */ +# include +# include +# include +# include +# endif + +# if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS) +# include +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +# define ITERATIONS 16 +# define HALF_ITERATIONS 8 + +/* used in des_read and des_write */ +# define MAXWRITE (1024*16) +# define BSIZE (MAXWRITE+4) + +# define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ + case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ + case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ + case 5: l2|=((DES_LONG)(*(--(c)))); \ + case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ + case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ + case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ + case 1: l1|=((DES_LONG)(*(--(c)))); \ + } \ + } + +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* + * replacements for htonl and ntohl since I have no idea what to do when + * faced with machines with 8 byte longs. + */ +# define HDRSIZE 4 + +# define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))) + +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* NOTE - c is not incremented as per l2c */ +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +# if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) +# define ROTATE(a,n) (_lrotr(a,n)) +# elif defined(__ICC) +# define ROTATE(a,n) (_rotr(a,n)) +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ("rorl %1,%0" \ + : "=r"(ret) \ + : "I"(n),"0"(a) \ + : "cc"); \ + ret; \ + }) +# endif +# endif +# ifndef ROTATE +# define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) +# endif + +/* + * Don't worry about the LOAD_DATA() stuff, that is used by fcrypt() to add + * it's little bit to the front + */ + +# ifdef DES_FCRYPT + +# define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ + { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } + +# define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ + t=R^(R>>16L); \ + u=t&E0; t&=E1; \ + tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ + tmp=(t<<16); t^=R^s[S+1]; t^=tmp +# else +# define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) +# define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ + u=R^s[S ]; \ + t=R^s[S+1] +# endif + +/* + * The changes to this macro may help or hinder, depending on the compiler + * and the architecture. gcc2 always seems to do well :-). Inspired by Dana + * How DO NOT use the alternative version on machines + * with 8 byte longs. It does not seem to work on the Alpha, even when + * DES_LONG is 4 bytes, probably an issue of accessing non-word aligned + * objects :-( + */ +# ifdef DES_PTR + +/* + * It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there is no reason + * to not xor all the sub items together. This potentially saves a register + * since things can be xored directly into L + */ + +# if defined(DES_RISC1) || defined(DES_RISC2) +# ifdef DES_RISC1 +# define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,u3; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u2=(int)u>>8L; \ + u1=(int)u&0xfc; \ + u2&=0xfc; \ + t=ROTATE(t,4); \ + u>>=16L; \ + LL^= *(const DES_LONG *)(des_SP +u1); \ + LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ + u3=(int)(u>>8L); \ + u1=(int)u&0xfc; \ + u3&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x400+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x600+u3); \ + u2=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u2&=0xfc; \ + t>>=16L; \ + LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ + u3=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u3&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x500+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x700+u3); } +# endif +# ifdef DES_RISC2 +# define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,s1,s2; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u2=(int)u>>8L; \ + u1=(int)u&0xfc; \ + u2&=0xfc; \ + t=ROTATE(t,4); \ + LL^= *(const DES_LONG *)(des_SP +u1); \ + LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ + s1=(int)(u>>16L); \ + s2=(int)(u>>24L); \ + s1&=0xfc; \ + s2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x400+s1); \ + LL^= *(const DES_LONG *)(des_SP+0x600+s2); \ + u2=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ + s1=(int)(t>>16L); \ + s2=(int)(t>>24L); \ + s1&=0xfc; \ + s2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x500+s1); \ + LL^= *(const DES_LONG *)(des_SP+0x700+s2); } +# endif +# else +# define D_ENCRYPT(LL,R,S) { \ + LOAD_DATA_tmp(R,S,u,t,E0,E1); \ + t=ROTATE(t,4); \ + LL^= \ + *(const DES_LONG *)(des_SP +((u )&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x100+((t )&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); } +# endif + +# else /* original version */ + +# if defined(DES_RISC1) || defined(DES_RISC2) +# ifdef DES_RISC1 +# define D_ENCRYPT(LL,R,S) {\ + unsigned int u1,u2,u3; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u>>=2L; \ + t=ROTATE(t,6); \ + u2=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u2&=0x3f; \ + u>>=16L; \ + LL^=DES_SPtrans[0][u1]; \ + LL^=DES_SPtrans[2][u2]; \ + u3=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u3&=0x3f; \ + LL^=DES_SPtrans[4][u1]; \ + LL^=DES_SPtrans[6][u3]; \ + u2=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u2&=0x3f; \ + t>>=16L; \ + LL^=DES_SPtrans[1][u1]; \ + LL^=DES_SPtrans[3][u2]; \ + u3=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u3&=0x3f; \ + LL^=DES_SPtrans[5][u1]; \ + LL^=DES_SPtrans[7][u3]; } +# endif +# ifdef DES_RISC2 +# define D_ENCRYPT(LL,R,S) {\ + unsigned int u1,u2,s1,s2; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u>>=2L; \ + t=ROTATE(t,6); \ + u2=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u2&=0x3f; \ + LL^=DES_SPtrans[0][u1]; \ + LL^=DES_SPtrans[2][u2]; \ + s1=(int)u>>16L; \ + s2=(int)u>>24L; \ + s1&=0x3f; \ + s2&=0x3f; \ + LL^=DES_SPtrans[4][s1]; \ + LL^=DES_SPtrans[6][s2]; \ + u2=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u2&=0x3f; \ + LL^=DES_SPtrans[1][u1]; \ + LL^=DES_SPtrans[3][u2]; \ + s1=(int)t>>16; \ + s2=(int)t>>24L; \ + s1&=0x3f; \ + s2&=0x3f; \ + LL^=DES_SPtrans[5][s1]; \ + LL^=DES_SPtrans[7][s2]; } +# endif + +# else + +# define D_ENCRYPT(LL,R,S) {\ + LOAD_DATA_tmp(R,S,u,t,E0,E1); \ + t=ROTATE(t,4); \ + LL^=\ + DES_SPtrans[0][(u>> 2L)&0x3f]^ \ + DES_SPtrans[2][(u>>10L)&0x3f]^ \ + DES_SPtrans[4][(u>>18L)&0x3f]^ \ + DES_SPtrans[6][(u>>26L)&0x3f]^ \ + DES_SPtrans[1][(t>> 2L)&0x3f]^ \ + DES_SPtrans[3][(t>>10L)&0x3f]^ \ + DES_SPtrans[5][(t>>18L)&0x3f]^ \ + DES_SPtrans[7][(t>>26L)&0x3f]; } +# endif +# endif + + /*- + * IP and FP + * The problem is more of a geometric problem that random bit fiddling. + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 + 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 + 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 + + 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 + 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 + 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 + 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 + + The output has been subject to swaps of the form + 0 1 -> 3 1 but the odd and even bits have been put into + 2 3 2 0 + different words. The main trick is to remember that + t=((l>>size)^r)&(mask); + r^=t; + l^=(t<>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + +# define IP(l,r) \ + { \ + register DES_LONG tt; \ + PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ + PERM_OP(l,r,tt,16,0x0000ffffL); \ + PERM_OP(r,l,tt, 2,0x33333333L); \ + PERM_OP(l,r,tt, 8,0x00ff00ffL); \ + PERM_OP(r,l,tt, 1,0x55555555L); \ + } + +# define FP(l,r) \ + { \ + register DES_LONG tt; \ + PERM_OP(l,r,tt, 1,0x55555555L); \ + PERM_OP(r,l,tt, 8,0x00ff00ffL); \ + PERM_OP(l,r,tt, 2,0x33333333L); \ + PERM_OP(r,l,tt,16,0x0000ffffL); \ + PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ + } + +extern const DES_LONG DES_SPtrans[8][64]; + +void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, + DES_LONG Eswap0, DES_LONG Eswap1); + +# ifdef OPENSSL_SMALL_FOOTPRINT +# undef DES_UNROLL +# endif +#endif diff --git a/Sources/COpenSSL/des_old.c b/Sources/COpenSSL/des_old.c new file mode 100644 index 00000000..e03aec4d --- /dev/null +++ b/Sources/COpenSSL/des_old.c @@ -0,0 +1,345 @@ +/* crypto/des/des_old.c */ + +/*- + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * The function names in here are deprecated and are only present to + * provide an interface compatible with libdes. OpenSSL now provides + * functions where "des_" has been replaced with "DES_" in the names, + * to make it possible to make incompatible changes that are needed + * for C type security and other stuff. + * + * Please consider starting to use the DES_ functions rather than the + * des_ ones. The des_ functions will dissapear completely before + * OpenSSL 1.0! + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#define OPENSSL_DES_LIBDES_COMPATIBILITY +#include "des.h" +#include "rand.h" + +const char *_ossl_old_des_options(void) +{ + return DES_options(); +} + +void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + des_key_schedule ks1, des_key_schedule ks2, + des_key_schedule ks3, int enc) +{ + DES_ecb3_encrypt((const_DES_cblock *)input, output, + (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3, enc); +} + +DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec) +{ + return DES_cbc_cksum((unsigned char *)input, output, length, + (DES_key_schedule *)schedule, ivec); +} + +void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_cbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)schedule, ivec, enc); +} + +void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_ncbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)schedule, ivec, enc); +} + +void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, + _ossl_old_des_cblock *inw, + _ossl_old_des_cblock *outw, int enc) +{ + DES_xcbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)schedule, ivec, inw, outw, + enc); +} + +void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_cfb_encrypt(in, out, numbits, length, + (DES_key_schedule *)schedule, ivec, enc); +} + +void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + des_key_schedule ks, int enc) +{ + DES_ecb_encrypt(input, output, (DES_key_schedule *)ks, enc); +} + +void _ossl_old_des_encrypt(DES_LONG *data, des_key_schedule ks, int enc) +{ + DES_encrypt1(data, (DES_key_schedule *)ks, enc); +} + +void _ossl_old_des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc) +{ + DES_encrypt2(data, (DES_key_schedule *)ks, enc); +} + +void _ossl_old_des_encrypt3(DES_LONG *data, des_key_schedule ks1, + des_key_schedule ks2, des_key_schedule ks3) +{ + DES_encrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3); +} + +void _ossl_old_des_decrypt3(DES_LONG *data, des_key_schedule ks1, + des_key_schedule ks2, des_key_schedule ks3) +{ + DES_decrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3); +} + +void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule ks1, + des_key_schedule ks2, + des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_ede3_cbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)ks1, + (DES_key_schedule *)ks2, (DES_key_schedule *)ks3, + ivec, enc); +} + +void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule ks1, + des_key_schedule ks2, + des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num, + int enc) +{ + DES_ede3_cfb64_encrypt(in, out, length, + (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3, ivec, num, enc); +} + +void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule ks1, + des_key_schedule ks2, + des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num) +{ + DES_ede3_ofb64_encrypt(in, out, length, + (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3, ivec, num); +} + +#if 0 /* broken code, preserved just in case anyone + * specifically looks for this */ +void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), + _ossl_old_des_cblock (*in_white), + _ossl_old_des_cblock (*out_white)) +{ + DES_xwhite_in2out(des_key, in_white, out_white); +} +#endif + +int _ossl_old_des_enc_read(int fd, char *buf, int len, des_key_schedule sched, + _ossl_old_des_cblock *iv) +{ + return DES_enc_read(fd, buf, len, (DES_key_schedule *)sched, iv); +} + +int _ossl_old_des_enc_write(int fd, char *buf, int len, + des_key_schedule sched, _ossl_old_des_cblock *iv) +{ + return DES_enc_write(fd, buf, len, (DES_key_schedule *)sched, iv); +} + +char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret) +{ + return DES_fcrypt(buf, salt, ret); +} + +char *_ossl_old_des_crypt(const char *buf, const char *salt) +{ + return DES_crypt(buf, salt); +} + +char *_ossl_old_crypt(const char *buf, const char *salt) +{ + return DES_crypt(buf, salt); +} + +void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec) +{ + DES_ofb_encrypt(in, out, numbits, length, (DES_key_schedule *)schedule, + ivec); +} + +void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_pcbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)schedule, ivec, enc); +} + +DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + int out_count, _ossl_old_des_cblock *seed) +{ + return DES_quad_cksum((unsigned char *)input, output, length, + out_count, seed); +} + +void _ossl_old_des_random_seed(_ossl_old_des_cblock key) +{ + RAND_seed(key, sizeof(_ossl_old_des_cblock)); +} + +void _ossl_old_des_random_key(_ossl_old_des_cblock ret) +{ + DES_random_key((DES_cblock *)ret); +} + +int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt, + int verify) +{ + return DES_read_password(key, prompt, verify); +} + +int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2, + const char *prompt, int verify) +{ + return DES_read_2passwords(key1, key2, prompt, verify); +} + +void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key) +{ + DES_set_odd_parity(key); +} + +int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key) +{ + return DES_is_weak_key(key); +} + +int _ossl_old_des_set_key(_ossl_old_des_cblock *key, + des_key_schedule schedule) +{ + return DES_set_key(key, (DES_key_schedule *)schedule); +} + +int _ossl_old_des_key_sched(_ossl_old_des_cblock *key, + des_key_schedule schedule) +{ + return DES_key_sched(key, (DES_key_schedule *)schedule); +} + +void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key) +{ + DES_string_to_key(str, key); +} + +void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2) +{ + DES_string_to_2keys(str, key1, key2); +} + +void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num, + int enc) +{ + DES_cfb64_encrypt(in, out, length, (DES_key_schedule *)schedule, + ivec, num, enc); +} + +void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num) +{ + DES_ofb64_encrypt(in, out, length, (DES_key_schedule *)schedule, + ivec, num); +} diff --git a/Sources/COpenSSL/des_old.h b/Sources/COpenSSL/des_old.h new file mode 100644 index 00000000..3a98695c --- /dev/null +++ b/Sources/COpenSSL/des_old.h @@ -0,0 +1,497 @@ +/* crypto/des/des_old.h */ + +/*- + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * The function names in here are deprecated and are only present to + * provide an interface compatible with openssl 0.9.6 and older as + * well as libdes. OpenSSL now provides functions where "des_" has + * been replaced with "DES_" in the names, to make it possible to + * make incompatible changes that are needed for C type security and + * other stuff. + * + * This include files has two compatibility modes: + * + * - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API + * that is compatible with libdes and SSLeay. + * - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an + * API that is compatible with OpenSSL 0.9.5x to 0.9.6x. + * + * Note that these modes break earlier snapshots of OpenSSL, where + * libdes compatibility was the only available mode or (later on) the + * prefered compatibility mode. However, after much consideration + * (and more or less violent discussions with external parties), it + * was concluded that OpenSSL should be compatible with earlier versions + * of itself before anything else. Also, in all honesty, libdes is + * an old beast that shouldn't really be used any more. + * + * Please consider starting to use the DES_ functions rather than the + * des_ ones. The des_ functions will disappear completely before + * OpenSSL 1.0! + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DES_H +# define HEADER_DES_H + +# include "e_os2.h" /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */ + +# ifdef OPENSSL_NO_DES +# error DES is disabled. +# endif + +# ifndef HEADER_NEW_DES_H +# error You must include des.h, not des_old.h directly. +# endif + +# ifdef _KERBEROS_DES_H +# error replaces . +# endif + +# include "symhacks.h" + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef _ +# undef _ +# endif + +typedef unsigned char _ossl_old_des_cblock[8]; +typedef struct _ossl_old_des_ks_struct { + union { + _ossl_old_des_cblock _; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG pad[2]; + } ks; +} _ossl_old_des_key_schedule[16]; + +# ifndef OPENSSL_DES_LIBDES_COMPATIBILITY +# define des_cblock DES_cblock +# define const_des_cblock const_DES_cblock +# define des_key_schedule DES_key_schedule +# define des_ecb3_encrypt(i,o,k1,k2,k3,e)\ + DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e)) +# define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\ + DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e)) +# define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\ + DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e)) +# define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\ + DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e)) +# define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\ + DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n)) +# define des_options()\ + DES_options() +# define des_cbc_cksum(i,o,l,k,iv)\ + DES_cbc_cksum((i),(o),(l),&(k),(iv)) +# define des_cbc_encrypt(i,o,l,k,iv,e)\ + DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_ncbc_encrypt(i,o,l,k,iv,e)\ + DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\ + DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e)) +# define des_cfb_encrypt(i,o,n,l,k,iv,e)\ + DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e)) +# define des_ecb_encrypt(i,o,k,e)\ + DES_ecb_encrypt((i),(o),&(k),(e)) +# define des_encrypt1(d,k,e)\ + DES_encrypt1((d),&(k),(e)) +# define des_encrypt2(d,k,e)\ + DES_encrypt2((d),&(k),(e)) +# define des_encrypt3(d,k1,k2,k3)\ + DES_encrypt3((d),&(k1),&(k2),&(k3)) +# define des_decrypt3(d,k1,k2,k3)\ + DES_decrypt3((d),&(k1),&(k2),&(k3)) +# define des_xwhite_in2out(k,i,o)\ + DES_xwhite_in2out((k),(i),(o)) +# define des_enc_read(f,b,l,k,iv)\ + DES_enc_read((f),(b),(l),&(k),(iv)) +# define des_enc_write(f,b,l,k,iv)\ + DES_enc_write((f),(b),(l),&(k),(iv)) +# define des_fcrypt(b,s,r)\ + DES_fcrypt((b),(s),(r)) +# if 0 +# define des_crypt(b,s)\ + DES_crypt((b),(s)) +# if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__) +# define crypt(b,s)\ + DES_crypt((b),(s)) +# endif +# endif +# define des_ofb_encrypt(i,o,n,l,k,iv)\ + DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv)) +# define des_pcbc_encrypt(i,o,l,k,iv,e)\ + DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_quad_cksum(i,o,l,c,s)\ + DES_quad_cksum((i),(o),(l),(c),(s)) +# define des_random_seed(k)\ + _ossl_096_des_random_seed((k)) +# define des_random_key(r)\ + DES_random_key((r)) +# define des_read_password(k,p,v) \ + DES_read_password((k),(p),(v)) +# define des_read_2passwords(k1,k2,p,v) \ + DES_read_2passwords((k1),(k2),(p),(v)) +# define des_set_odd_parity(k)\ + DES_set_odd_parity((k)) +# define des_check_key_parity(k)\ + DES_check_key_parity((k)) +# define des_is_weak_key(k)\ + DES_is_weak_key((k)) +# define des_set_key(k,ks)\ + DES_set_key((k),&(ks)) +# define des_key_sched(k,ks)\ + DES_key_sched((k),&(ks)) +# define des_set_key_checked(k,ks)\ + DES_set_key_checked((k),&(ks)) +# define des_set_key_unchecked(k,ks)\ + DES_set_key_unchecked((k),&(ks)) +# define des_string_to_key(s,k)\ + DES_string_to_key((s),(k)) +# define des_string_to_2keys(s,k1,k2)\ + DES_string_to_2keys((s),(k1),(k2)) +# define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\ + DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e)) +# define des_ofb64_encrypt(i,o,l,ks,iv,n)\ + DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n)) + +# define des_ecb2_encrypt(i,o,k1,k2,e) \ + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +# define des_check_key DES_check_key +# define des_rw_mode DES_rw_mode +# else /* libdes compatibility */ +/* + * Map all symbol names to _ossl_old_des_* form, so we avoid all clashes with + * libdes + */ +# define des_cblock _ossl_old_des_cblock +# define des_key_schedule _ossl_old_des_key_schedule +# define des_ecb3_encrypt(i,o,k1,k2,k3,e)\ + _ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e)) +# define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\ + _ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e)) +# define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\ + _ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e)) +# define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\ + _ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n)) +# define des_options()\ + _ossl_old_des_options() +# define des_cbc_cksum(i,o,l,k,iv)\ + _ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv)) +# define des_cbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_ncbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\ + _ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e)) +# define des_cfb_encrypt(i,o,n,l,k,iv,e)\ + _ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e)) +# define des_ecb_encrypt(i,o,k,e)\ + _ossl_old_des_ecb_encrypt((i),(o),(k),(e)) +# define des_encrypt(d,k,e)\ + _ossl_old_des_encrypt((d),(k),(e)) +# define des_encrypt2(d,k,e)\ + _ossl_old_des_encrypt2((d),(k),(e)) +# define des_encrypt3(d,k1,k2,k3)\ + _ossl_old_des_encrypt3((d),(k1),(k2),(k3)) +# define des_decrypt3(d,k1,k2,k3)\ + _ossl_old_des_decrypt3((d),(k1),(k2),(k3)) +# define des_xwhite_in2out(k,i,o)\ + _ossl_old_des_xwhite_in2out((k),(i),(o)) +# define des_enc_read(f,b,l,k,iv)\ + _ossl_old_des_enc_read((f),(b),(l),(k),(iv)) +# define des_enc_write(f,b,l,k,iv)\ + _ossl_old_des_enc_write((f),(b),(l),(k),(iv)) +# define des_fcrypt(b,s,r)\ + _ossl_old_des_fcrypt((b),(s),(r)) +# define des_crypt(b,s)\ + _ossl_old_des_crypt((b),(s)) +# if 0 +# define crypt(b,s)\ + _ossl_old_crypt((b),(s)) +# endif +# define des_ofb_encrypt(i,o,n,l,k,iv)\ + _ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv)) +# define des_pcbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_quad_cksum(i,o,l,c,s)\ + _ossl_old_des_quad_cksum((i),(o),(l),(c),(s)) +# define des_random_seed(k)\ + _ossl_old_des_random_seed((k)) +# define des_random_key(r)\ + _ossl_old_des_random_key((r)) +# define des_read_password(k,p,v) \ + _ossl_old_des_read_password((k),(p),(v)) +# define des_read_2passwords(k1,k2,p,v) \ + _ossl_old_des_read_2passwords((k1),(k2),(p),(v)) +# define des_set_odd_parity(k)\ + _ossl_old_des_set_odd_parity((k)) +# define des_is_weak_key(k)\ + _ossl_old_des_is_weak_key((k)) +# define des_set_key(k,ks)\ + _ossl_old_des_set_key((k),(ks)) +# define des_key_sched(k,ks)\ + _ossl_old_des_key_sched((k),(ks)) +# define des_string_to_key(s,k)\ + _ossl_old_des_string_to_key((s),(k)) +# define des_string_to_2keys(s,k1,k2)\ + _ossl_old_des_string_to_2keys((s),(k1),(k2)) +# define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\ + _ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e)) +# define des_ofb64_encrypt(i,o,l,ks,iv,n)\ + _ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n)) + +# define des_ecb2_encrypt(i,o,k1,k2,e) \ + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +# define des_check_key DES_check_key +# define des_rw_mode DES_rw_mode +# endif + +const char *_ossl_old_des_options(void); +void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, int enc); +DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec); +void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, + _ossl_old_des_cblock *inw, + _ossl_old_des_cblock *outw, int enc); +void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + _ossl_old_des_key_schedule ks, int enc); +void _ossl_old_des_encrypt(DES_LONG *data, _ossl_old_des_key_schedule ks, + int enc); +void _ossl_old_des_encrypt2(DES_LONG *data, _ossl_old_des_key_schedule ks, + int enc); +void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3); +void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3); +void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num, + int enc); +void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num); +# if 0 +void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), + _ossl_old_des_cblock (*in_white), + _ossl_old_des_cblock (*out_white)); +# endif + +int _ossl_old_des_enc_read(int fd, char *buf, int len, + _ossl_old_des_key_schedule sched, + _ossl_old_des_cblock *iv); +int _ossl_old_des_enc_write(int fd, char *buf, int len, + _ossl_old_des_key_schedule sched, + _ossl_old_des_cblock *iv); +char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret); +char *_ossl_old_des_crypt(const char *buf, const char *salt); +# if !defined(PERL5) && !defined(NeXT) +char *_ossl_old_crypt(const char *buf, const char *salt); +# endif +void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec); +void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + int out_count, _ossl_old_des_cblock *seed); +void _ossl_old_des_random_seed(_ossl_old_des_cblock key); +void _ossl_old_des_random_key(_ossl_old_des_cblock ret); +int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt, + int verify); +int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2, + const char *prompt, int verify); +void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key); +int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key); +int _ossl_old_des_set_key(_ossl_old_des_cblock *key, + _ossl_old_des_key_schedule schedule); +int _ossl_old_des_key_sched(_ossl_old_des_cblock *key, + _ossl_old_des_key_schedule schedule); +void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key); +void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2); +void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num, + int enc); +void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num); + +void _ossl_096_des_random_seed(des_cblock *key); + +/* + * The following definitions provide compatibility with the MIT Kerberos + * library. The _ossl_old_des_key_schedule structure is not binary + * compatible. + */ + +# define _KERBEROS_DES_H + +# define KRBDES_ENCRYPT DES_ENCRYPT +# define KRBDES_DECRYPT DES_DECRYPT + +# ifdef KERBEROS +# define ENCRYPT DES_ENCRYPT +# define DECRYPT DES_DECRYPT +# endif + +# ifndef NCOMPAT +# define C_Block des_cblock +# define Key_schedule des_key_schedule +# define KEY_SZ DES_KEY_SZ +# define string_to_key des_string_to_key +# define read_pw_string des_read_pw_string +# define random_key des_random_key +# define pcbc_encrypt des_pcbc_encrypt +# define set_key des_set_key +# define key_sched des_key_sched +# define ecb_encrypt des_ecb_encrypt +# define cbc_encrypt des_cbc_encrypt +# define ncbc_encrypt des_ncbc_encrypt +# define xcbc_encrypt des_xcbc_encrypt +# define cbc_cksum des_cbc_cksum +# define quad_cksum des_quad_cksum +# define check_parity des_check_key_parity +# endif + +# define des_fixup_key_parity DES_fixup_key_parity + +#ifdef __cplusplus +} +#endif + +/* for DES_read_pw_string et al */ +# include "ui_compat.h" + +#endif diff --git a/Sources/COpenSSL/des_old2.c b/Sources/COpenSSL/des_old2.c new file mode 100644 index 00000000..6f06d996 --- /dev/null +++ b/Sources/COpenSSL/des_old2.c @@ -0,0 +1,80 @@ +/* crypto/des/des_old.c */ + +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING The + * function names in here are deprecated and are only present to provide an + * interface compatible with OpenSSL 0.9.6c. OpenSSL now provides functions + * where "des_" has been replaced with "DES_" in the names, to make it + * possible to make incompatible changes that are needed for C type security + * and other stuff. Please consider starting to use the DES_ functions + * rather than the des_ ones. The des_ functions will dissapear completely + * before OpenSSL 1.0! WARNING WARNING WARNING WARNING WARNING WARNING + * WARNING WARNING + */ + +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#undef OPENSSL_DES_LIBDES_COMPATIBILITY +#include "des.h" +#include "rand.h" + +void _ossl_096_des_random_seed(DES_cblock *key) +{ + RAND_seed(key, sizeof(DES_cblock)); +} diff --git a/Sources/COpenSSL/des_ver.h b/Sources/COpenSSL/des_ver.h new file mode 100644 index 00000000..5ad82d02 --- /dev/null +++ b/Sources/COpenSSL/des_ver.h @@ -0,0 +1,73 @@ +/* crypto/des/des_ver.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "e_os2.h" + +#ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +#endif + +/* The following macros make sure the names are different from libdes names */ +#define DES_version OSSL_DES_version +#define libdes_version OSSL_libdes_version + +/* SSLeay version string */ +OPENSSL_EXTERN const char OSSL_DES_version[]; +/* old libdes version string */ +OPENSSL_EXTERN const char OSSL_libdes_version[]; diff --git a/Sources/COpenSSL/dh.h b/Sources/COpenSSL/dh.h new file mode 100644 index 00000000..d610c7b8 --- /dev/null +++ b/Sources/COpenSSL/dh.h @@ -0,0 +1,412 @@ +/* crypto/dh/dh.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DH_H +# define HEADER_DH_H + +# include "e_os2.h" + +# ifdef OPENSSL_NO_DH +# error DH is disabled. +# endif + +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# include "ossl_typ.h" +# ifndef OPENSSL_NO_DEPRECATED +# include "bn.h" +# endif + +# ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# endif + +# define DH_FLAG_CACHE_MONT_P 0x01 + +/* + * new with 0.9.7h; the built-in DH + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define DH_FLAG_NO_EXP_CONSTTIME 0x02 + +/* + * If this flag is set the DH method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its reposibility to ensure the + * result is compliant. + */ + +# define DH_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DH_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dh_st DH; */ +/* typedef struct dh_method DH_METHOD; */ + +struct dh_method { + const char *name; + /* Methods here */ + int (*generate_key) (DH *dh); + int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh); + /* Can be null */ + int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); + int (*init) (DH *dh); + int (*finish) (DH *dh); + int flags; + char *app_data; + /* If this is non-NULL, it will be used to generate parameters */ + int (*generate_params) (DH *dh, int prime_len, int generator, + BN_GENCB *cb); +}; + +struct dh_st { + /* + * This first argument is used to pick up errors when a DH is passed + * instead of a EVP_PKEY + */ + int pad; + int version; + BIGNUM *p; + BIGNUM *g; + long length; /* optional */ + BIGNUM *pub_key; /* g^x % p */ + BIGNUM *priv_key; /* x */ + int flags; + BN_MONT_CTX *method_mont_p; + /* Place holders if we want to do X9.42 DH */ + BIGNUM *q; + BIGNUM *j; + unsigned char *seed; + int seedlen; + BIGNUM *counter; + int references; + CRYPTO_EX_DATA ex_data; + const DH_METHOD *meth; + ENGINE *engine; +}; + +# define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +# define DH_GENERATOR_5 5 + +/* DH_check error codes */ +# define DH_CHECK_P_NOT_PRIME 0x01 +# define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +# define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +# define DH_NOT_SUITABLE_GENERATOR 0x08 +# define DH_CHECK_Q_NOT_PRIME 0x10 +# define DH_CHECK_INVALID_Q_VALUE 0x20 +# define DH_CHECK_INVALID_J_VALUE 0x40 + +/* DH_check_pub_key error codes */ +# define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +# define DH_CHECK_PUBKEY_TOO_LARGE 0x02 +# define DH_CHECK_PUBKEY_INVALID 0x04 + +/* + * primes p where (p-1)/2 is prime too are called "safe"; we define this for + * backward compatibility: + */ +# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +# define d2i_DHparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x)) +# define d2i_DHparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x) +# define i2d_DHparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +# define d2i_DHxparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHxparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHxparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x)) +# define d2i_DHxparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x) +# define i2d_DHxparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x) + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH *DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_size(const DH *dh); +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +DH *DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, + BN_GENCB *cb); + +int DH_check(const DH *dh, int *codes); +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh); +DH *d2i_DHparams(DH **a, const unsigned char **pp, long length); +int i2d_DHparams(const DH *a, unsigned char **pp); +DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length); +int i2d_DHxparams(const DH *a, unsigned char **pp); +# ifndef OPENSSL_NO_FP_API +int DHparams_print_fp(FILE *fp, const DH *x); +# endif +# ifndef OPENSSL_NO_BIO +int DHparams_print(BIO *bp, const DH *x); +# else +int DHparams_print(char *bp, const DH *x); +# endif + +/* RFC 5114 parameters */ +DH *DH_get_1024_160(void); +DH *DH_get_2048_224(void); +DH *DH_get_2048_256(void); + +# ifndef OPENSSL_NO_CMS +/* RFC2631 KDF */ +int DH_KDF_X9_42(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + ASN1_OBJECT *key_oid, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); +# endif + +# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) + +# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)oid) + +# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)poid) + +# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)plen) + +# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)p) + +# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)p) + +# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10) +# define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12) +# define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13) +# define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14) + +/* KDF types */ +# define EVP_PKEY_DH_KDF_NONE 1 +# define EVP_PKEY_DH_KDF_X9_42 2 + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DH_strings(void); + +/* Error codes for the DH functions. */ + +/* Function codes. */ +# define DH_F_COMPUTE_KEY 102 +# define DH_F_DHPARAMS_PRINT_FP 101 +# define DH_F_DH_BUILTIN_GENPARAMS 106 +# define DH_F_DH_CMS_DECRYPT 117 +# define DH_F_DH_CMS_SET_PEERKEY 118 +# define DH_F_DH_CMS_SET_SHARED_INFO 119 +# define DH_F_DH_COMPUTE_KEY 114 +# define DH_F_DH_GENERATE_KEY 115 +# define DH_F_DH_GENERATE_PARAMETERS_EX 116 +# define DH_F_DH_NEW_METHOD 105 +# define DH_F_DH_PARAM_DECODE 107 +# define DH_F_DH_PRIV_DECODE 110 +# define DH_F_DH_PRIV_ENCODE 111 +# define DH_F_DH_PUB_DECODE 108 +# define DH_F_DH_PUB_ENCODE 109 +# define DH_F_DO_DH_PRINT 100 +# define DH_F_GENERATE_KEY 103 +# define DH_F_GENERATE_PARAMETERS 104 +# define DH_F_PKEY_DH_DERIVE 112 +# define DH_F_PKEY_DH_KEYGEN 113 + +/* Reason codes. */ +# define DH_R_BAD_GENERATOR 101 +# define DH_R_BN_DECODE_ERROR 109 +# define DH_R_BN_ERROR 106 +# define DH_R_DECODE_ERROR 104 +# define DH_R_INVALID_PUBKEY 102 +# define DH_R_KDF_PARAMETER_ERROR 112 +# define DH_R_KEYS_NOT_SET 108 +# define DH_R_KEY_SIZE_TOO_SMALL 110 +# define DH_R_MODULUS_TOO_LARGE 103 +# define DH_R_NON_FIPS_METHOD 111 +# define DH_R_NO_PARAMETERS_SET 107 +# define DH_R_NO_PRIVATE_VALUE 100 +# define DH_R_PARAMETER_ENCODING_ERROR 105 +# define DH_R_PEER_KEY_ERROR 113 +# define DH_R_SHARED_INFO_ERROR 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/dh_.c b/Sources/COpenSSL/dh_.c new file mode 100644 index 00000000..2e9b4056 --- /dev/null +++ b/Sources/COpenSSL/dh_.c @@ -0,0 +1,3417 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "x509.h" +#include "asn1.h" +#include "dh.h" +#include "bn.h" +#include "asn1_locl.h" +#ifndef OPENSSL_NO_CMS +# include "cms.h" +#endif + +extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth; + +/* + * i2d/d2i like DH parameter functions which use the appropriate routine for + * PKCS#3 DH or X9.42 DH. + */ + +static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp, + long length) +{ + if (pkey->ameth == &dhx_asn1_meth) + return d2i_DHxparams(NULL, pp, length); + return d2i_DHparams(NULL, pp, length); +} + +static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp) +{ + if (pkey->ameth == &dhx_asn1_meth) + return i2d_DHxparams(a, pp); + return i2d_DHparams(a, pp); +} + +static void int_dh_free(EVP_PKEY *pkey) +{ + DH_free(pkey->pkey.dh); +} + +static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *public_key = NULL; + + DH *dh = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype != V_ASN1_SEQUENCE) { + DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + + if (!(dh = d2i_dhp(pkey, &pm, pmlen))) { + DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); + goto err; + } + + if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) { + DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); + goto err; + } + + /* We have parameters now set public key */ + if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { + DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR); + goto err; + } + + ASN1_INTEGER_free(public_key); + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); + return 1; + + err: + if (public_key) + ASN1_INTEGER_free(public_key); + if (dh) + DH_free(dh); + return 0; + +} + +static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + DH *dh; + int ptype; + unsigned char *penc = NULL; + int penclen; + ASN1_STRING *str; + ASN1_INTEGER *pub_key = NULL; + + dh = pkey->pkey.dh; + + str = ASN1_STRING_new(); + if (!str) { + DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + str->length = i2d_dhp(pkey, dh, &str->data); + if (str->length <= 0) { + DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + ptype = V_ASN1_SEQUENCE; + + pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); + if (!pub_key) + goto err; + + penclen = i2d_ASN1_INTEGER(pub_key, &penc); + + ASN1_INTEGER_free(pub_key); + + if (penclen <= 0) { + DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), + ptype, str, penc, penclen)) + return 1; + + err: + if (penc) + OPENSSL_free(penc); + if (str) + ASN1_STRING_free(str); + + return 0; +} + +/* + * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in that + * the AlgorithmIdentifier contains the paramaters, the private key is + * explcitly included and the pubkey must be recalculated. + */ + +static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + + DH *dh = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype != V_ASN1_SEQUENCE) + goto decerr; + + if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen))) + goto decerr; + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + if (!(dh = d2i_dhp(pkey, &pm, pmlen))) + goto decerr; + /* We have parameters now set private key */ + if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { + DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR); + goto dherr; + } + /* Calculate public key */ + if (!DH_generate_key(dh)) + goto dherr; + + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); + + ASN1_STRING_clear_free(privkey); + + return 1; + + decerr: + DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); + dherr: + DH_free(dh); + ASN1_STRING_clear_free(privkey); + return 0; +} + +static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + ASN1_STRING *params = NULL; + ASN1_INTEGER *prkey = NULL; + unsigned char *dp = NULL; + int dplen; + + params = ASN1_STRING_new(); + + if (!params) { + DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + params->length = i2d_dhp(pkey, pkey->pkey.dh, ¶ms->data); + if (params->length <= 0) { + DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + params->type = V_ASN1_SEQUENCE; + + /* Get private key into integer */ + prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL); + + if (!prkey) { + DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR); + goto err; + } + + dplen = i2d_ASN1_INTEGER(prkey, &dp); + + ASN1_STRING_clear_free(prkey); + prkey = NULL; + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) + goto err; + + return 1; + + err: + if (dp != NULL) + OPENSSL_free(dp); + if (params != NULL) + ASN1_STRING_free(params); + if (prkey != NULL) + ASN1_STRING_clear_free(prkey); + return 0; +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) +{ + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; +} + +static int dh_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + DH *dh; + if (!(dh = d2i_dhp(pkey, pder, derlen))) { + DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); + return 0; + } + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); + return 1; +} + +static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_dhp(pkey, pkey->pkey.dh, pder); +} + +static int do_dh_print(BIO *bp, const DH *x, int indent, + ASN1_PCTX *ctx, int ptype) +{ + unsigned char *m = NULL; + int reason = ERR_R_BUF_LIB, ret = 0; + size_t buf_len = 0; + + const char *ktype = NULL; + + BIGNUM *priv_key, *pub_key; + + if (ptype == 2) + priv_key = x->priv_key; + else + priv_key = NULL; + + if (ptype > 0) + pub_key = x->pub_key; + else + pub_key = NULL; + + update_buflen(x->p, &buf_len); + + if (buf_len == 0) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + update_buflen(x->g, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->j, &buf_len); + update_buflen(x->counter, &buf_len); + update_buflen(pub_key, &buf_len); + update_buflen(priv_key, &buf_len); + + if (ptype == 2) + ktype = "DH Private-Key"; + else if (ptype == 1) + ktype = "DH Public-Key"; + else + ktype = "DH Parameters"; + + m = OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + BIO_indent(bp, indent, 128); + if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) + goto err; + indent += 4; + + if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent)) + goto err; + if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent)) + goto err; + + if (!ASN1_bn_print(bp, "prime:", x->p, m, indent)) + goto err; + if (!ASN1_bn_print(bp, "generator:", x->g, m, indent)) + goto err; + if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, m, indent)) + goto err; + if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, m, indent)) + goto err; + if (x->seed) { + int i; + BIO_indent(bp, indent, 128); + BIO_puts(bp, "seed:"); + for (i = 0; i < x->seedlen; i++) { + if ((i % 15) == 0) { + if (BIO_puts(bp, "\n") <= 0 + || !BIO_indent(bp, indent + 4, 128)) + goto err; + } + if (BIO_printf(bp, "%02x%s", x->seed[i], + ((i + 1) == x->seedlen) ? "" : ":") <= 0) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + return (0); + } + if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, m, indent)) + goto err; + if (x->length != 0) { + BIO_indent(bp, indent, 128); + if (BIO_printf(bp, "recommended-private-length: %d bits\n", + (int)x->length) <= 0) + goto err; + } + + ret = 1; + if (0) { + err: + DHerr(DH_F_DO_DH_PRINT, reason); + } + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +static int int_dh_size(const EVP_PKEY *pkey) +{ + return (DH_size(pkey->pkey.dh)); +} + +static int dh_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.dh->p); +} + +static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) || + BN_cmp(a->pkey.dh->g, b->pkey.dh->g)) + return 0; + else if (a->ameth == &dhx_asn1_meth) { + if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q)) + return 0; + } + return 1; +} + +static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) +{ + BIGNUM *a; + if (src) { + a = BN_dup(src); + if (!a) + return 0; + } else + a = NULL; + if (*dst) + BN_free(*dst); + *dst = a; + return 1; +} + +static int int_dh_param_copy(DH *to, const DH *from, int is_x942) +{ + if (is_x942 == -1) + is_x942 = ! !from->q; + if (!int_dh_bn_cpy(&to->p, from->p)) + return 0; + if (!int_dh_bn_cpy(&to->g, from->g)) + return 0; + if (is_x942) { + if (!int_dh_bn_cpy(&to->q, from->q)) + return 0; + if (!int_dh_bn_cpy(&to->j, from->j)) + return 0; + if (to->seed) { + OPENSSL_free(to->seed); + to->seed = NULL; + to->seedlen = 0; + } + if (from->seed) { + to->seed = BUF_memdup(from->seed, from->seedlen); + if (!to->seed) + return 0; + to->seedlen = from->seedlen; + } + } else + to->length = from->length; + return 1; +} + +DH *DHparams_dup(DH *dh) +{ + DH *ret; + ret = DH_new(); + if (!ret) + return NULL; + if (!int_dh_param_copy(ret, dh, -1)) { + DH_free(ret); + return NULL; + } + return ret; +} + +static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + return int_dh_param_copy(to->pkey.dh, from->pkey.dh, + from->ameth == &dhx_asn1_meth); +} + +static int dh_missing_parameters(const EVP_PKEY *a) +{ + if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL) + return 1; + return 0; +} + +static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (dh_cmp_parameters(a, b) == 0) + return 0; + if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0) + return 0; + else + return 1; +} + +static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0); +} + +static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1); +} + +static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2); +} + +int DHparams_print(BIO *bp, const DH *x) +{ + return do_dh_print(bp, x, 4, NULL, 0); +} + +#ifndef OPENSSL_NO_CMS +static int dh_cms_decrypt(CMS_RecipientInfo *ri); +static int dh_cms_encrypt(CMS_RecipientInfo *ri); +#endif + +static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { +#ifndef OPENSSL_NO_CMS + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (arg1 == 1) + return dh_cms_decrypt(arg2); + else if (arg1 == 0) + return dh_cms_encrypt(arg2); + return -2; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: + *(int *)arg2 = CMS_RECIPINFO_AGREE; + return 1; +#endif + default: + return -2; + } + +} + +const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { + EVP_PKEY_DH, + EVP_PKEY_DH, + 0, + + "DH", + "OpenSSL PKCS#3 DH method", + + dh_pub_decode, + dh_pub_encode, + dh_pub_cmp, + dh_public_print, + + dh_priv_decode, + dh_priv_encode, + dh_private_print, + + int_dh_size, + dh_bits, + + dh_param_decode, + dh_param_encode, + dh_missing_parameters, + dh_copy_parameters, + dh_cmp_parameters, + dh_param_print, + 0, + + int_dh_free, + 0 +}; + +const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = { + EVP_PKEY_DHX, + EVP_PKEY_DHX, + 0, + + "X9.42 DH", + "OpenSSL X9.42 DH method", + + dh_pub_decode, + dh_pub_encode, + dh_pub_cmp, + dh_public_print, + + dh_priv_decode, + dh_priv_encode, + dh_private_print, + + int_dh_size, + dh_bits, + + dh_param_decode, + dh_param_encode, + dh_missing_parameters, + dh_copy_parameters, + dh_cmp_parameters, + dh_param_print, + 0, + + int_dh_free, + dh_pkey_ctrl +}; + +#ifndef OPENSSL_NO_CMS + +static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, + X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) +{ + ASN1_OBJECT *aoid; + int atype; + void *aval; + ASN1_INTEGER *public_key = NULL; + int rv = 0; + EVP_PKEY *pkpeer = NULL, *pk = NULL; + DH *dhpeer = NULL; + const unsigned char *p; + int plen; + + X509_ALGOR_get0(&aoid, &atype, &aval, alg); + if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) + goto err; + /* Only absent parameters allowed in RFC XXXX */ + if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) + goto err; + + pk = EVP_PKEY_CTX_get0_pkey(pctx); + if (!pk) + goto err; + if (pk->type != EVP_PKEY_DHX) + goto err; + /* Get parameters from parent key */ + dhpeer = DHparams_dup(pk->pkey.dh); + /* We have parameters now set public key */ + plen = ASN1_STRING_length(pubkey); + p = ASN1_STRING_data(pubkey); + if (!p || !plen) + goto err; + + if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, plen))) { + DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR); + goto err; + } + + /* We have parameters now set public key */ + if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { + DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR); + goto err; + } + + pkpeer = EVP_PKEY_new(); + if (!pkpeer) + goto err; + EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer); + dhpeer = NULL; + if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) + rv = 1; + err: + if (public_key) + ASN1_INTEGER_free(public_key); + if (pkpeer) + EVP_PKEY_free(pkpeer); + if (dhpeer) + DH_free(dhpeer); + return rv; +} + +static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) +{ + int rv = 0; + + X509_ALGOR *alg, *kekalg = NULL; + ASN1_OCTET_STRING *ukm; + const unsigned char *p; + unsigned char *dukm = NULL; + size_t dukmlen = 0; + int keylen, plen; + const EVP_CIPHER *kekcipher; + EVP_CIPHER_CTX *kekctx; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) + goto err; + + /* + * For DH we only have one OID permissible. If ever any more get defined + * we will need something cleverer. + */ + if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { + DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR); + goto err; + } + + if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0) + goto err; + + if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) + goto err; + + if (alg->parameter->type != V_ASN1_SEQUENCE) + goto err; + + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + if (!kekalg) + goto err; + kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); + if (!kekctx) + goto err; + kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) + goto err; + if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) + goto err; + if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) + goto err; + + keylen = EVP_CIPHER_CTX_key_length(kekctx); + if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) + goto err; + /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ + if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, + OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) + <= 0) + goto err; + + if (ukm) { + dukmlen = ASN1_STRING_length(ukm); + dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); + if (!dukm) + goto err; + } + + if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) + goto err; + dukm = NULL; + + rv = 1; + err: + if (kekalg) + X509_ALGOR_free(kekalg); + if (dukm) + OPENSSL_free(dukm); + return rv; +} + +static int dh_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (!pctx) + return 0; + /* See if we need to set peer key */ + if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { + X509_ALGOR *alg; + ASN1_BIT_STRING *pubkey; + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, + NULL, NULL, NULL)) + return 0; + if (!alg || !pubkey) + return 0; + if (!dh_cms_set_peerkey(pctx, alg, pubkey)) { + DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR); + return 0; + } + } + /* Set DH derivation parameters and initialise unwrap context */ + if (!dh_cms_set_shared_info(pctx, ri)) { + DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR); + return 0; + } + return 1; +} + +static int dh_cms_encrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + EVP_CIPHER_CTX *ctx; + int keylen; + X509_ALGOR *talg, *wrap_alg = NULL; + ASN1_OBJECT *aoid; + ASN1_BIT_STRING *pubkey; + ASN1_STRING *wrap_str; + ASN1_OCTET_STRING *ukm; + unsigned char *penc = NULL, *dukm = NULL; + int penclen; + size_t dukmlen = 0; + int rv = 0; + int kdf_type, wrap_nid; + const EVP_MD *kdf_md; + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (!pctx) + return 0; + /* Get ephemeral key */ + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, + NULL, NULL, NULL)) + goto err; + X509_ALGOR_get0(&aoid, NULL, NULL, talg); + /* Is everything uninitialised? */ + if (aoid == OBJ_nid2obj(NID_undef)) { + ASN1_INTEGER *pubk; + pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL); + if (!pubk) + goto err; + /* Set the key */ + + penclen = i2d_ASN1_INTEGER(pubk, &penc); + ASN1_INTEGER_free(pubk); + if (penclen <= 0) + goto err; + ASN1_STRING_set0(pubkey, penc, penclen); + pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), + V_ASN1_UNDEF, NULL); + } + + /* See if custom paraneters set */ + kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); + if (kdf_type <= 0) + goto err; + if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) + goto err; + + if (kdf_type == EVP_PKEY_DH_KDF_NONE) { + kdf_type = EVP_PKEY_DH_KDF_X9_42; + if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) + goto err; + } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) + /* Unknown KDF */ + goto err; + if (kdf_md == NULL) { + /* Only SHA1 supported */ + kdf_md = EVP_sha1(); + if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) + goto err; + } else if (EVP_MD_type(kdf_md) != NID_sha1) + /* Unsupported digest */ + goto err; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) + goto err; + + /* Get wrap NID */ + ctx = CMS_RecipientInfo_kari_get0_ctx(ri); + wrap_nid = EVP_CIPHER_CTX_type(ctx); + if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) + goto err; + keylen = EVP_CIPHER_CTX_key_length(ctx); + + /* Package wrap algorithm in an AlgorithmIdentifier */ + + wrap_alg = X509_ALGOR_new(); + if (!wrap_alg) + goto err; + wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); + wrap_alg->parameter = ASN1_TYPE_new(); + if (!wrap_alg->parameter) + goto err; + if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) + goto err; + if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { + ASN1_TYPE_free(wrap_alg->parameter); + wrap_alg->parameter = NULL; + } + + if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + if (ukm) { + dukmlen = ASN1_STRING_length(ukm); + dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); + if (!dukm) + goto err; + } + + if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) + goto err; + dukm = NULL; + + /* + * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter + * of another AlgorithmIdentifier. + */ + penc = NULL; + penclen = i2d_X509_ALGOR(wrap_alg, &penc); + if (!penc || !penclen) + goto err; + wrap_str = ASN1_STRING_new(); + if (!wrap_str) + goto err; + ASN1_STRING_set0(wrap_str, penc, penclen); + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), + V_ASN1_SEQUENCE, wrap_str); + + rv = 1; + + err: + if (penc) + OPENSSL_free(penc); + if (wrap_alg) + X509_ALGOR_free(wrap_alg); + return rv; +} + +#endif +/* dh_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "dh.h" +#include "objects.h" +#include "asn1t.h" + +/* Override the default free and new methods */ +static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)DH_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + DH_free((DH *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +ASN1_SEQUENCE_cb(DHparams, dh_cb) = { + ASN1_SIMPLE(DH, p, BIGNUM), + ASN1_SIMPLE(DH, g, BIGNUM), + ASN1_OPT(DH, length, ZLONG), +} ASN1_SEQUENCE_END_cb(DH, DHparams) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams) + +/* + * Internal only structures for handling X9.42 DH: this gets translated to or + * from a DH structure straight away. + */ + +typedef struct { + ASN1_BIT_STRING *seed; + BIGNUM *counter; +} int_dhvparams; + +typedef struct { + BIGNUM *p; + BIGNUM *q; + BIGNUM *g; + BIGNUM *j; + int_dhvparams *vparams; +} int_dhx942_dh; + +ASN1_SEQUENCE(DHvparams) = { + ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING), + ASN1_SIMPLE(int_dhvparams, counter, BIGNUM) +} ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams) + +ASN1_SEQUENCE(DHxparams) = { + ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM), + ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM), + ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM), + ASN1_OPT(int_dhx942_dh, j, BIGNUM), + ASN1_OPT(int_dhx942_dh, vparams, DHvparams), +} ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams) + +int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a, + const unsigned char **pp, long length); +int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp); + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx) + +/* Application leve function: read in X9.42 DH parameters into DH structure */ + +DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length) +{ + int_dhx942_dh *dhx = NULL; + DH *dh = NULL; + dh = DH_new(); + if (!dh) + return NULL; + dhx = d2i_int_dhx(NULL, pp, length); + if (!dhx) { + DH_free(dh); + return NULL; + } + + if (a) { + if (*a) + DH_free(*a); + *a = dh; + } + + dh->p = dhx->p; + dh->q = dhx->q; + dh->g = dhx->g; + dh->j = dhx->j; + + if (dhx->vparams) { + dh->seed = dhx->vparams->seed->data; + dh->seedlen = dhx->vparams->seed->length; + dh->counter = dhx->vparams->counter; + dhx->vparams->seed->data = NULL; + ASN1_BIT_STRING_free(dhx->vparams->seed); + OPENSSL_free(dhx->vparams); + dhx->vparams = NULL; + } + + OPENSSL_free(dhx); + return dh; +} + +int i2d_DHxparams(const DH *dh, unsigned char **pp) +{ + int_dhx942_dh dhx; + int_dhvparams dhv; + ASN1_BIT_STRING bs; + dhx.p = dh->p; + dhx.g = dh->g; + dhx.q = dh->q; + dhx.j = dh->j; + if (dh->counter && dh->seed && dh->seedlen > 0) { + bs.flags = ASN1_STRING_FLAG_BITS_LEFT; + bs.data = dh->seed; + bs.length = dh->seedlen; + dhv.seed = &bs; + dhv.counter = dh->counter; + dhx.vparams = &dhv; + } else + dhx.vparams = NULL; + + return i2d_int_dhx(&dhx, pp); +} +/* crypto/dh/dh_check.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "dh.h" + +/*- + * Check that p is a safe prime and + * if g is 2, 3 or 5, check that it is a suitable generator + * where + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 + * for 5, p mod 10 == 3 or 7 + * should hold. + */ + +int DH_check(const DH *dh, int *ret) +{ + int ok = 0; + BN_CTX *ctx = NULL; + BN_ULONG l; + BIGNUM *t1 = NULL, *t2 = NULL; + + *ret = 0; + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + if (t1 == NULL) + goto err; + t2 = BN_CTX_get(ctx); + if (t2 == NULL) + goto err; + + if (dh->q) { + if (BN_cmp(dh->g, BN_value_one()) <= 0) + *ret |= DH_NOT_SUITABLE_GENERATOR; + else if (BN_cmp(dh->g, dh->p) >= 0) + *ret |= DH_NOT_SUITABLE_GENERATOR; + else { + /* Check g^q == 1 mod p */ + if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx)) + goto err; + if (!BN_is_one(t1)) + *ret |= DH_NOT_SUITABLE_GENERATOR; + } + if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL)) + *ret |= DH_CHECK_Q_NOT_PRIME; + /* Check p == 1 mod q i.e. q divides p - 1 */ + if (!BN_div(t1, t2, dh->p, dh->q, ctx)) + goto err; + if (!BN_is_one(t2)) + *ret |= DH_CHECK_INVALID_Q_VALUE; + if (dh->j && BN_cmp(dh->j, t1)) + *ret |= DH_CHECK_INVALID_J_VALUE; + + } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { + l = BN_mod_word(dh->p, 24); + if (l != 11) + *ret |= DH_NOT_SUITABLE_GENERATOR; + } +#if 0 + else if (BN_is_word(dh->g, DH_GENERATOR_3)) { + l = BN_mod_word(dh->p, 12); + if (l != 5) + *ret |= DH_NOT_SUITABLE_GENERATOR; + } +#endif + else if (BN_is_word(dh->g, DH_GENERATOR_5)) { + l = BN_mod_word(dh->p, 10); + if ((l != 3) && (l != 7)) + *ret |= DH_NOT_SUITABLE_GENERATOR; + } else + *ret |= DH_UNABLE_TO_CHECK_GENERATOR; + + if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL)) + *ret |= DH_CHECK_P_NOT_PRIME; + else if (!dh->q) { + if (!BN_rshift1(t1, dh->p)) + goto err; + if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL)) + *ret |= DH_CHECK_P_NOT_SAFE_PRIME; + } + ok = 1; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return (ok); +} + +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) +{ + int ok = 0; + BIGNUM *tmp = NULL; + BN_CTX *ctx = NULL; + + *ret = 0; + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL || !BN_set_word(tmp, 1)) + goto err; + if (BN_cmp(pub_key, tmp) <= 0) + *ret |= DH_CHECK_PUBKEY_TOO_SMALL; + if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1)) + goto err; + if (BN_cmp(pub_key, tmp) >= 0) + *ret |= DH_CHECK_PUBKEY_TOO_LARGE; + + if (dh->q != NULL) { + /* Check pub_key^q == 1 mod p */ + if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) + goto err; + if (!BN_is_one(tmp)) + *ret |= DH_CHECK_PUBKEY_INVALID; + } + + ok = 1; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return (ok); +} +/* crypto/dh/dh_depr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* This file contains deprecated functions as wrappers to the new ones */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "dh.h" + +static void *dummy = &dummy; + +#ifndef OPENSSL_NO_DEPRECATED +DH *DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, void *), void *cb_arg) +{ + BN_GENCB cb; + DH *ret = NULL; + + if ((ret = DH_new()) == NULL) + return NULL; + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (DH_generate_parameters_ex(ret, prime_len, generator, &cb)) + return ret; + DH_free(ret); + return NULL; +} +#endif +/* crypto/dh/dh_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "dh.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason) + +static ERR_STRING_DATA DH_str_functs[] = { + {ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"}, + {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"}, + {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, + {ERR_FUNC(DH_F_DH_CMS_DECRYPT), "DH_CMS_DECRYPT"}, + {ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "DH_CMS_SET_PEERKEY"}, + {ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "DH_CMS_SET_SHARED_INFO"}, + {ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"}, + {ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"}, + {ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS_EX), "DH_generate_parameters_ex"}, + {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"}, + {ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"}, + {ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"}, + {ERR_FUNC(DH_F_DH_PRIV_ENCODE), "DH_PRIV_ENCODE"}, + {ERR_FUNC(DH_F_DH_PUB_DECODE), "DH_PUB_DECODE"}, + {ERR_FUNC(DH_F_DH_PUB_ENCODE), "DH_PUB_ENCODE"}, + {ERR_FUNC(DH_F_DO_DH_PRINT), "DO_DH_PRINT"}, + {ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"}, + {ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"}, + {ERR_FUNC(DH_F_PKEY_DH_DERIVE), "PKEY_DH_DERIVE"}, + {ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "PKEY_DH_KEYGEN"}, + {0, NULL} +}; + +static ERR_STRING_DATA DH_str_reasons[] = { + {ERR_REASON(DH_R_BAD_GENERATOR), "bad generator"}, + {ERR_REASON(DH_R_BN_DECODE_ERROR), "bn decode error"}, + {ERR_REASON(DH_R_BN_ERROR), "bn error"}, + {ERR_REASON(DH_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(DH_R_INVALID_PUBKEY), "invalid public key"}, + {ERR_REASON(DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, + {ERR_REASON(DH_R_KEYS_NOT_SET), "keys not set"}, + {ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL), "key size too small"}, + {ERR_REASON(DH_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_REASON(DH_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_REASON(DH_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_REASON(DH_R_NO_PRIVATE_VALUE), "no private value"}, + {ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, + {ERR_REASON(DH_R_PEER_KEY_ERROR), "peer key error"}, + {ERR_REASON(DH_R_SHARED_INFO_ERROR), "shared info error"}, + {0, NULL} +}; + +#endif + +void ERR_load_DH_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(DH_str_functs[0].error) == NULL) { + ERR_load_strings(0, DH_str_functs); + ERR_load_strings(0, DH_str_reasons); + } +#endif +} +/* crypto/dh/dh_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * NB: These functions have been upgraded - the previous prototypes are in + * dh_depr.c as wrappers to these ones. - Geoff + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "dh.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, + BN_GENCB *cb); + +int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, + BN_GENCB *cb) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ret->meth->flags & DH_FLAG_FIPS_METHOD) + && !(ret->flags & DH_FLAG_NON_FIPS_ALLOW)) { + DHerr(DH_F_DH_GENERATE_PARAMETERS_EX, DH_R_NON_FIPS_METHOD); + return 0; + } +#endif + if (ret->meth->generate_params) + return ret->meth->generate_params(ret, prime_len, generator, cb); +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_dh_generate_parameters_ex(ret, prime_len, generator, cb); +#endif + return dh_builtin_genparams(ret, prime_len, generator, cb); +} + +/*- + * We generate DH parameters as follows + * find a prime q which is prime_len/2 bits long. + * p=(2*q)+1 or (p-1)/2 = q + * For this case, g is a generator if + * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. + * Since the factors of p-1 are q and 2, we just need to check + * g^2 mod p != 1 and g^q mod p != 1. + * + * Having said all that, + * there is another special case method for the generators 2, 3 and 5. + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 <<<<< does not work for safe primes. + * for 5, p mod 10 == 3 or 7 + * + * Thanks to Phil Karn for the pointers about the + * special generators and for answering some of my questions. + * + * I've implemented the second simple method :-). + * Since DH should be using a safe prime (both p and q are prime), + * this generator function can take a very very long time to run. + */ +/* + * Actually there is no reason to insist that 'generator' be a generator. + * It's just as OK (and in some sense better) to use a generator of the + * order-q subgroup. + */ +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, + BN_GENCB *cb) +{ + BIGNUM *t1, *t2; + int g, ok = -1; + BN_CTX *ctx = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t1 == NULL || t2 == NULL) + goto err; + + /* Make sure 'ret' has the necessary elements */ + if (!ret->p && ((ret->p = BN_new()) == NULL)) + goto err; + if (!ret->g && ((ret->g = BN_new()) == NULL)) + goto err; + + if (generator <= 1) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); + goto err; + } + if (generator == DH_GENERATOR_2) { + if (!BN_set_word(t1, 24)) + goto err; + if (!BN_set_word(t2, 11)) + goto err; + g = 2; + } +#if 0 /* does not work for safe primes */ + else if (generator == DH_GENERATOR_3) { + if (!BN_set_word(t1, 12)) + goto err; + if (!BN_set_word(t2, 5)) + goto err; + g = 3; + } +#endif + else if (generator == DH_GENERATOR_5) { + if (!BN_set_word(t1, 10)) + goto err; + if (!BN_set_word(t2, 3)) + goto err; + /* + * BN_set_word(t3,7); just have to miss out on these ones :-( + */ + g = 5; + } else { + /* + * in the general case, don't worry if 'generator' is a generator or + * not: since we are using safe primes, it will generate either an + * order-q or an order-2q group, which both is OK + */ + if (!BN_set_word(t1, 2)) + goto err; + if (!BN_set_word(t2, 1)) + goto err; + g = generator; + } + + if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb)) + goto err; + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + if (!BN_set_word(ret->g, g)) + goto err; + ok = 1; + err: + if (ok == -1) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB); + ok = 0; + } + + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} +/* crypto/dh/dh_kdf.c */ +/* + * Written by Stephen Henson for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "e_os.h" + +#ifndef OPENSSL_NO_CMS +#include +// #include "dh.h" +#include "evp.h" +// #include "asn1.h" +#include "cms.h" + +/* Key derivation from X9.42/RFC2631 */ + +#define DH_KDF_MAX (1L << 30) + +/* Skip past an ASN1 structure: for OBJECT skip content octets too */ + +static int skip_asn1(unsigned char **pp, long *plen, int exptag) +{ + const unsigned char *q = *pp; + int i, tag, xclass; + long tmplen; + i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen); + if (i & 0x80) + return 0; + if (tag != exptag || xclass != V_ASN1_UNIVERSAL) + return 0; + if (tag == V_ASN1_OBJECT) + q += tmplen; + *plen -= q - *pp; + *pp = (unsigned char *)q; + return 1; +} + +/* + * Encode the DH shared info structure, return an offset to the counter value + * so we can update the structure without reencoding it. + */ + +static int dh_sharedinfo_encode(unsigned char **pder, unsigned char **pctr, + ASN1_OBJECT *key_oid, size_t outlen, + const unsigned char *ukm, size_t ukmlen) +{ + unsigned char *p; + int derlen; + long tlen; + /* "magic" value to check offset is sane */ + static unsigned char ctr[4] = { 0xF3, 0x17, 0x22, 0x53 }; + X509_ALGOR atmp; + ASN1_OCTET_STRING ctr_oct, ukm_oct, *pukm_oct; + ASN1_TYPE ctr_atype; + if (ukmlen > DH_KDF_MAX || outlen > DH_KDF_MAX) + return 0; + ctr_oct.data = ctr; + ctr_oct.length = 4; + ctr_oct.flags = 0; + ctr_oct.type = V_ASN1_OCTET_STRING; + ctr_atype.type = V_ASN1_OCTET_STRING; + ctr_atype.value.octet_string = &ctr_oct; + atmp.algorithm = key_oid; + atmp.parameter = &ctr_atype; + if (ukm) { + ukm_oct.type = V_ASN1_OCTET_STRING; + ukm_oct.flags = 0; + ukm_oct.data = (unsigned char *)ukm; + ukm_oct.length = ukmlen; + pukm_oct = &ukm_oct; + } else + pukm_oct = NULL; + derlen = CMS_SharedInfo_encode(pder, &atmp, pukm_oct, outlen); + if (derlen <= 0) + return 0; + p = *pder; + tlen = derlen; + if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)) + return 0; + if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)) + return 0; + if (!skip_asn1(&p, &tlen, V_ASN1_OBJECT)) + return 0; + if (!skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING)) + return 0; + if (CRYPTO_memcmp(p, ctr, 4)) + return 0; + *pctr = p; + return derlen; +} + +int DH_KDF_X9_42(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + ASN1_OBJECT *key_oid, + const unsigned char *ukm, size_t ukmlen, const EVP_MD *md) +{ + EVP_MD_CTX mctx; + int rv = 0; + unsigned int i; + size_t mdlen; + unsigned char *der = NULL, *ctr; + int derlen; + if (Zlen > DH_KDF_MAX) + return 0; + mdlen = EVP_MD_size(md); + EVP_MD_CTX_init(&mctx); + derlen = dh_sharedinfo_encode(&der, &ctr, key_oid, outlen, ukm, ukmlen); + if (derlen == 0) + goto err; + for (i = 1;; i++) { + unsigned char mtmp[EVP_MAX_MD_SIZE]; + EVP_DigestInit_ex(&mctx, md, NULL); + if (!EVP_DigestUpdate(&mctx, Z, Zlen)) + goto err; + ctr[3] = i & 0xFF; + ctr[2] = (i >> 8) & 0xFF; + ctr[1] = (i >> 16) & 0xFF; + ctr[0] = (i >> 24) & 0xFF; + if (!EVP_DigestUpdate(&mctx, der, derlen)) + goto err; + if (outlen >= mdlen) { + if (!EVP_DigestFinal(&mctx, out, NULL)) + goto err; + outlen -= mdlen; + if (outlen == 0) + break; + out += mdlen; + } else { + if (!EVP_DigestFinal(&mctx, mtmp, NULL)) + goto err; + memcpy(out, mtmp, outlen); + OPENSSL_cleanse(mtmp, mdlen); + break; + } + } + rv = 1; + err: + if (der) + OPENSSL_free(der); + EVP_MD_CTX_cleanup(&mctx); + return rv; +} +#endif +/* crypto/dh/dh_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +#include "rand.h" +// #include "dh.h" + +static int generate_key(DH *dh); +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +static int dh_init(DH *dh); +static int dh_finish(DH *dh); + +int DH_generate_key(DH *dh) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) + && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { + DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD); + return 0; + } +#endif + return dh->meth->generate_key(dh); +} + +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) + && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { + DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD); + return 0; + } +#endif + return dh->meth->compute_key(key, pub_key, dh); +} + +int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + int rv, pad; + rv = dh->meth->compute_key(key, pub_key, dh); + if (rv <= 0) + return rv; + pad = BN_num_bytes(dh->p) - rv; + if (pad > 0) { + memmove(key + pad, key, rv); + memset(key, 0, pad); + } + return rv + pad; +} + +static DH_METHOD dh_ossl = { + "OpenSSL DH Method", + generate_key, + compute_key, + dh_bn_mod_exp, + dh_init, + dh_finish, + 0, + NULL, + NULL +}; + +const DH_METHOD *DH_OpenSSL(void) +{ + return &dh_ossl; +} + +static int generate_key(DH *dh) +{ + int ok = 0; + int generate_new_key = 0; + unsigned l; + BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (dh->priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) + goto err; + generate_new_key = 1; + } else + priv_key = dh->priv_key; + + if (dh->pub_key == NULL) { + pub_key = BN_new(); + if (pub_key == NULL) + goto err; + } else + pub_key = dh->pub_key; + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if (!mont) + goto err; + } + + if (generate_new_key) { + if (dh->q) { + do { + if (!BN_rand_range(priv_key, dh->q)) + goto err; + } + while (BN_is_zero(priv_key) || BN_is_one(priv_key)); + } else { + /* secret exponent length */ + l = dh->length ? dh->length : BN_num_bits(dh->p) - 1; + if (!BN_rand(priv_key, l, 0, 0)) + goto err; + } + } + + { + BIGNUM local_prk; + BIGNUM *prk; + + if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_init(&local_prk); + prk = &local_prk; + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + } else + prk = priv_key; + + if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) + goto err; + } + + dh->pub_key = pub_key; + dh->priv_key = priv_key; + ok = 1; + err: + if (ok != 1) + DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB); + + if ((pub_key != NULL) && (dh->pub_key == NULL)) + BN_free(pub_key); + if ((priv_key != NULL) && (dh->priv_key == NULL)) + BN_free(priv_key); + BN_CTX_free(ctx); + return (ok); +} + +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *tmp; + int ret = -1; + int check_result; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + if (dh->priv_key == NULL) { + DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE); + goto err; + } + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { + /* XXX */ + BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); + } + if (!mont) + goto err; + } + + if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) { + DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY); + goto err; + } + + if (!dh-> + meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) { + DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + ret = BN_bn2bin(tmp, key); + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return (ret); +} + +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + /* + * If a is only one word long and constant time is false, use the faster + * exponenentiation function. + */ + if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0)) { + BN_ULONG A = a->d[0]; + return BN_mod_exp_mont_word(r, A, p, m, ctx, m_ctx); + } else + return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); +} + +static int dh_init(DH *dh) +{ + dh->flags |= DH_FLAG_CACHE_MONT_P; + return (1); +} + +static int dh_finish(DH *dh) +{ + if (dh->method_mont_p) + BN_MONT_CTX_free(dh->method_mont_p); + return (1); +} +/* crypto/dh/dh_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "dh.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +#ifdef OPENSSL_FIPS +# include +#endif + +const char DH_version[] = "Diffie-Hellman" OPENSSL_VERSION_PTEXT; + +static const DH_METHOD *default_DH_method = NULL; + +void DH_set_default_method(const DH_METHOD *meth) +{ + default_DH_method = meth; +} + +const DH_METHOD *DH_get_default_method(void) +{ + if (!default_DH_method) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_dh_openssl(); + else + return DH_OpenSSL(); +#else + default_DH_method = DH_OpenSSL(); +#endif + } + return default_DH_method; +} + +int DH_set_method(DH *dh, const DH_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const DH_METHOD *mtmp; + mtmp = dh->meth; + if (mtmp->finish) + mtmp->finish(dh); +#ifndef OPENSSL_NO_ENGINE + if (dh->engine) { + ENGINE_finish(dh->engine); + dh->engine = NULL; + } +#endif + dh->meth = meth; + if (meth->init) + meth->init(dh); + return 1; +} + +DH *DH_new(void) +{ + return DH_new_method(NULL); +} + +DH *DH_new_method(ENGINE *engine) +{ + DH *ret; + + ret = (DH *)OPENSSL_malloc(sizeof(DH)); + if (ret == NULL) { + DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->meth = DH_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine) { + if (!ENGINE_init(engine)) { + DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; + } else + ret->engine = ENGINE_get_default_DH(); + if (ret->engine) { + ret->meth = ENGINE_get_DH(ret->engine); + if (!ret->meth) { + DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->pad = 0; + ret->version = 0; + ret->p = NULL; + ret->g = NULL; + ret->length = 0; + ret->pub_key = NULL; + ret->priv_key = NULL; + ret->q = NULL; + ret->j = NULL; + ret->seed = NULL; + ret->seedlen = 0; + ret->counter = NULL; + ret->method_mont_p = NULL; + ret->references = 1; + ret->flags = ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +void DH_free(DH *r) +{ + int i; + if (r == NULL) + return; + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH); +#ifdef REF_PRINT + REF_PRINT("DH", r); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "DH_free, bad reference count\n"); + abort(); + } +#endif + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); + + if (r->p != NULL) + BN_clear_free(r->p); + if (r->g != NULL) + BN_clear_free(r->g); + if (r->q != NULL) + BN_clear_free(r->q); + if (r->j != NULL) + BN_clear_free(r->j); + if (r->seed) + OPENSSL_free(r->seed); + if (r->counter != NULL) + BN_clear_free(r->counter); + if (r->pub_key != NULL) + BN_clear_free(r->pub_key); + if (r->priv_key != NULL) + BN_clear_free(r->priv_key); + OPENSSL_free(r); +} + +int DH_up_ref(DH *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH); +#ifdef REF_PRINT + REF_PRINT("DH", r); +#endif +#ifdef REF_CHECK + if (i < 2) { + fprintf(stderr, "DH_up, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); +} + +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp, + new_func, dup_func, free_func); +} + +int DH_set_ex_data(DH *d, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&d->ex_data, idx, arg)); +} + +void *DH_get_ex_data(DH *d, int idx) +{ + return (CRYPTO_get_ex_data(&d->ex_data, idx)); +} + +int DH_size(const DH *dh) +{ + return (BN_num_bytes(dh->p)); +} +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" +// #include "evp.h" +// #include "dh.h" +// #include "bn.h" +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +// #include "objects.h" +#include "evp_locl.h" + +/* DH pkey context structure */ + +typedef struct { + /* Parameter gen parameters */ + int prime_len; + int generator; + int use_dsa; + int subprime_len; + /* message digest used for parameter generation */ + const EVP_MD *md; + int rfc5114_param; + /* Keygen callback info */ + int gentmp[2]; + /* KDF (if any) to use for DH */ + char kdf_type; + /* OID to use for KDF */ + ASN1_OBJECT *kdf_oid; + /* Message digest to use for key derivation */ + const EVP_MD *kdf_md; + /* User key material */ + unsigned char *kdf_ukm; + size_t kdf_ukmlen; + /* KDF output length */ + size_t kdf_outlen; +} DH_PKEY_CTX; + +static int pkey_dh_init(EVP_PKEY_CTX *ctx) +{ + DH_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX)); + if (!dctx) + return 0; + dctx->prime_len = 1024; + dctx->subprime_len = -1; + dctx->generator = 2; + dctx->use_dsa = 0; + dctx->md = NULL; + dctx->rfc5114_param = 0; + + dctx->kdf_type = EVP_PKEY_DH_KDF_NONE; + dctx->kdf_oid = NULL; + dctx->kdf_md = NULL; + dctx->kdf_ukm = NULL; + dctx->kdf_ukmlen = 0; + dctx->kdf_outlen = 0; + + ctx->data = dctx; + ctx->keygen_info = dctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + DH_PKEY_CTX *dctx, *sctx; + if (!pkey_dh_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->prime_len = sctx->prime_len; + dctx->subprime_len = sctx->subprime_len; + dctx->generator = sctx->generator; + dctx->use_dsa = sctx->use_dsa; + dctx->md = sctx->md; + dctx->rfc5114_param = sctx->rfc5114_param; + + dctx->kdf_type = sctx->kdf_type; + dctx->kdf_oid = OBJ_dup(sctx->kdf_oid); + if (!dctx->kdf_oid) + return 0; + dctx->kdf_md = sctx->kdf_md; + if (dctx->kdf_ukm) { + dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); + dctx->kdf_ukmlen = sctx->kdf_ukmlen; + } + dctx->kdf_outlen = sctx->kdf_outlen; + return 1; +} + +static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) +{ + DH_PKEY_CTX *dctx = ctx->data; + if (dctx) { + if (dctx->kdf_ukm) + OPENSSL_free(dctx->kdf_ukm); + if (dctx->kdf_oid) + ASN1_OBJECT_free(dctx->kdf_oid); + OPENSSL_free(dctx); + } +} + +static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + DH_PKEY_CTX *dctx = ctx->data; + switch (type) { + case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: + if (p1 < 256) + return -2; + dctx->prime_len = p1; + return 1; + + case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN: + if (dctx->use_dsa == 0) + return -2; + dctx->subprime_len = p1; + return 1; + + case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: + if (dctx->use_dsa) + return -2; + dctx->generator = p1; + return 1; + + case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE: +#ifdef OPENSSL_NO_DSA + if (p1 != 0) + return -2; +#else + if (p1 < 0 || p1 > 2) + return -2; +#endif + dctx->use_dsa = p1; + return 1; + + case EVP_PKEY_CTRL_DH_RFC5114: + if (p1 < 1 || p1 > 3) + return -2; + dctx->rfc5114_param = p1; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + /* Default behaviour is OK */ + return 1; + + case EVP_PKEY_CTRL_DH_KDF_TYPE: + if (p1 == -2) + return dctx->kdf_type; +#ifdef OPENSSL_NO_CMS + if (p1 != EVP_PKEY_DH_KDF_NONE) +#else + if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) +#endif + return -2; + dctx->kdf_type = p1; + return 1; + + case EVP_PKEY_CTRL_DH_KDF_MD: + dctx->kdf_md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_DH_KDF_MD: + *(const EVP_MD **)p2 = dctx->kdf_md; + return 1; + + case EVP_PKEY_CTRL_DH_KDF_OUTLEN: + if (p1 <= 0) + return -2; + dctx->kdf_outlen = (size_t)p1; + return 1; + + case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN: + *(int *)p2 = dctx->kdf_outlen; + return 1; + + case EVP_PKEY_CTRL_DH_KDF_UKM: + if (dctx->kdf_ukm) + OPENSSL_free(dctx->kdf_ukm); + dctx->kdf_ukm = p2; + if (p2) + dctx->kdf_ukmlen = p1; + else + dctx->kdf_ukmlen = 0; + return 1; + + case EVP_PKEY_CTRL_GET_DH_KDF_UKM: + *(unsigned char **)p2 = dctx->kdf_ukm; + return dctx->kdf_ukmlen; + + case EVP_PKEY_CTRL_DH_KDF_OID: + if (dctx->kdf_oid) + ASN1_OBJECT_free(dctx->kdf_oid); + dctx->kdf_oid = p2; + return 1; + + case EVP_PKEY_CTRL_GET_DH_KDF_OID: + *(ASN1_OBJECT **)p2 = dctx->kdf_oid; + return 1; + + default: + return -2; + + } +} + +static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!strcmp(type, "dh_paramgen_prime_len")) { + int len; + len = atoi(value); + return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); + } + if (!strcmp(type, "dh_rfc5114")) { + DH_PKEY_CTX *dctx = ctx->data; + int len; + len = atoi(value); + if (len < 0 || len > 3) + return -2; + dctx->rfc5114_param = len; + return 1; + } + if (!strcmp(type, "dh_paramgen_generator")) { + int len; + len = atoi(value); + return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len); + } + if (!strcmp(type, "dh_paramgen_subprime_len")) { + int len; + len = atoi(value); + return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len); + } + if (!strcmp(type, "dh_paramgen_type")) { + int typ; + typ = atoi(value); + return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ); + } + return -2; +} + +#ifndef OPENSSL_NO_DSA + +extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, + const unsigned char *seed_in, size_t seed_len, + unsigned char *seed_out, int *counter_ret, + unsigned long *h_ret, BN_GENCB *cb); + +extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, + const EVP_MD *evpmd, + const unsigned char *seed_in, + size_t seed_len, int idx, + unsigned char *seed_out, int *counter_ret, + unsigned long *h_ret, BN_GENCB *cb); + +static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb) +{ + DSA *ret; + int rv = 0; + int prime_len = dctx->prime_len; + int subprime_len = dctx->subprime_len; + const EVP_MD *md = dctx->md; + if (dctx->use_dsa > 2) + return NULL; + ret = DSA_new(); + if (!ret) + return NULL; + if (subprime_len == -1) { + if (prime_len >= 2048) + subprime_len = 256; + else + subprime_len = 160; + } + if (md == NULL) { + if (prime_len >= 2048) + md = EVP_sha256(); + else + md = EVP_sha1(); + } + if (dctx->use_dsa == 1) + rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md, + NULL, 0, NULL, NULL, NULL, pcb); + else if (dctx->use_dsa == 2) + rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md, + NULL, 0, -1, NULL, NULL, NULL, pcb); + if (rv <= 0) { + DSA_free(ret); + return NULL; + } + return ret; +} + +#endif + +static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DH *dh = NULL; + DH_PKEY_CTX *dctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (dctx->rfc5114_param) { + switch (dctx->rfc5114_param) { + case 1: + dh = DH_get_1024_160(); + break; + + case 2: + dh = DH_get_2048_224(); + break; + + case 3: + dh = DH_get_2048_256(); + break; + + default: + return -2; + } + EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); + return 1; + } + + if (ctx->pkey_gencb) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else + pcb = NULL; +#ifndef OPENSSL_NO_DSA + if (dctx->use_dsa) { + DSA *dsa_dh; + dsa_dh = dsa_dh_generate(dctx, pcb); + if (!dsa_dh) + return 0; + dh = DSA_dup_DH(dsa_dh); + DSA_free(dsa_dh); + if (!dh) + return 0; + EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); + return 1; + } +#endif + dh = DH_new(); + if (!dh) + return 0; + ret = DH_generate_parameters_ex(dh, + dctx->prime_len, dctx->generator, pcb); + + if (ret) + EVP_PKEY_assign_DH(pkey, dh); + else + DH_free(dh); + return ret; +} + +static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DH *dh = NULL; + if (ctx->pkey == NULL) { + DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); + return 0; + } + dh = DH_new(); + if (!dh) + return 0; + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return DH_generate_key(pkey->pkey.dh); +} + +static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + int ret; + DH *dh; + DH_PKEY_CTX *dctx = ctx->data; + BIGNUM *dhpub; + if (!ctx->pkey || !ctx->peerkey) { + DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); + return 0; + } + dh = ctx->pkey->pkey.dh; + dhpub = ctx->peerkey->pkey.dh->pub_key; + if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) { + if (key == NULL) { + *keylen = DH_size(dh); + return 1; + } + ret = DH_compute_key(key, dhpub, dh); + if (ret < 0) + return ret; + *keylen = ret; + return 1; + } +#ifndef OPENSSL_NO_CMS + else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { + unsigned char *Z = NULL; + size_t Zlen = 0; + if (!dctx->kdf_outlen || !dctx->kdf_oid) + return 0; + if (key == NULL) { + *keylen = dctx->kdf_outlen; + return 1; + } + if (*keylen != dctx->kdf_outlen) + return 0; + ret = 0; + Zlen = DH_size(dh); + Z = OPENSSL_malloc(Zlen); + if (!Z) { + goto err; + } + if (DH_compute_key_padded(Z, dhpub, dh) <= 0) + goto err; + if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid, + dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) + goto err; + *keylen = dctx->kdf_outlen; + ret = 1; + err: + if (Z) { + OPENSSL_cleanse(Z, Zlen); + OPENSSL_free(Z); + } + return ret; + } +#endif + return 0; +} + +const EVP_PKEY_METHOD dh_pkey_meth = { + EVP_PKEY_DH, + 0, + pkey_dh_init, + pkey_dh_copy, + pkey_dh_cleanup, + + 0, + pkey_dh_paramgen, + + 0, + pkey_dh_keygen, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + 0, + pkey_dh_derive, + + pkey_dh_ctrl, + pkey_dh_ctrl_str +}; + +const EVP_PKEY_METHOD dhx_pkey_meth = { + EVP_PKEY_DHX, + 0, + pkey_dh_init, + pkey_dh_copy, + pkey_dh_cleanup, + + 0, + pkey_dh_paramgen, + + 0, + pkey_dh_keygen, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + 0, + pkey_dh_derive, + + pkey_dh_ctrl, + pkey_dh_ctrl_str +}; +/* crypto/asn1/t_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "dh.h" + +#ifndef OPENSSL_NO_FP_API +int DHparams_print_fp(FILE *fp, const DH *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DHparams_print(b, x); + BIO_free(b); + return (ret); +} +#endif +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2011. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "dh.h" +// #include "bn.h" + +/* DH parameters from RFC5114 */ + +#if BN_BITS2 == 64 +static const BN_ULONG dh1024_160_p[] = { + 0xDF1FB2BC2E4A4371ULL, 0xE68CFDA76D4DA708ULL, 0x45BF37DF365C1A65ULL, + 0xA151AF5F0DC8B4BDULL, 0xFAA31A4FF55BCCC0ULL, 0x4EFFD6FAE5644738ULL, + 0x98488E9C219A7372ULL, 0xACCBDD7D90C4BD70ULL, 0x24975C3CD49B83BFULL, + 0x13ECB4AEA9061123ULL, 0x9838EF1E2EE652C0ULL, 0x6073E28675A23D18ULL, + 0x9A6A9DCA52D23B61ULL, 0x52C99FBCFB06A3C6ULL, 0xDE92DE5EAE5D54ECULL, + 0xB10B8F96A080E01DULL +}; + +static const BN_ULONG dh1024_160_g[] = { + 0x855E6EEB22B3B2E5ULL, 0x858F4DCEF97C2A24ULL, 0x2D779D5918D08BC8ULL, + 0xD662A4D18E73AFA3ULL, 0x1DBF0A0169B6A28AULL, 0xA6A24C087A091F53ULL, + 0x909D0D2263F80A76ULL, 0xD7FBD7D3B9A92EE1ULL, 0x5E91547F9E2749F4ULL, + 0x160217B4B01B886AULL, 0x777E690F5504F213ULL, 0x266FEA1E5C41564BULL, + 0xD6406CFF14266D31ULL, 0xF8104DD258AC507FULL, 0x6765A442EFB99905ULL, + 0xA4D1CBD5C3FD3412ULL +}; + +static const BN_ULONG dh1024_160_q[] = { + 0x64B7CB9D49462353ULL, 0x81A8DF278ABA4E7DULL, 0x00000000F518AA87ULL +}; + +static const BN_ULONG dh2048_224_p[] = { + 0x0AC4DFFE0C10E64FULL, 0xCF9DE5384E71B81CULL, 0x7EF363E2FFA31F71ULL, + 0xE3FB73C16B8E75B9ULL, 0xC9B53DCF4BA80A29ULL, 0x23F10B0E16E79763ULL, + 0xC52172E413042E9BULL, 0xBE60E69CC928B2B9ULL, 0x80CD86A1B9E587E8ULL, + 0x315D75E198C641A4ULL, 0xCDF93ACC44328387ULL, 0x15987D9ADC0A486DULL, + 0x7310F7121FD5A074ULL, 0x278273C7DE31EFDCULL, 0x1602E714415D9330ULL, + 0x81286130BC8985DBULL, 0xB3BF8A3170918836ULL, 0x6A00E0A0B9C49708ULL, + 0xC6BA0B2C8BBC27BEULL, 0xC9F98D11ED34DBF6ULL, 0x7AD5B7D0B6C12207ULL, + 0xD91E8FEF55B7394BULL, 0x9037C9EDEFDA4DF8ULL, 0x6D3F8152AD6AC212ULL, + 0x1DE6B85A1274A0A6ULL, 0xEB3D688A309C180EULL, 0xAF9A3C407BA1DF15ULL, + 0xE6FA141DF95A56DBULL, 0xB54B1597B61D0A75ULL, 0xA20D64E5683B9FD1ULL, + 0xD660FAA79559C51FULL, 0xAD107E1E9123A9D0ULL +}; + +static const BN_ULONG dh2048_224_g[] = { + 0x84B890D3191F2BFAULL, 0x81BC087F2A7065B3ULL, 0x19C418E1F6EC0179ULL, + 0x7B5A0F1C71CFFF4CULL, 0xEDFE72FE9B6AA4BDULL, 0x81E1BCFE94B30269ULL, + 0x566AFBB48D6C0191ULL, 0xB539CCE3409D13CDULL, 0x6AA21E7F5F2FF381ULL, + 0xD9E263E4770589EFULL, 0x10E183EDD19963DDULL, 0xB70A8137150B8EEBULL, + 0x051AE3D428C8F8ACULL, 0xBB77A86F0C1AB15BULL, 0x6E3025E316A330EFULL, + 0x19529A45D6F83456ULL, 0xF180EB34118E98D1ULL, 0xB5F6C6B250717CBEULL, + 0x09939D54DA7460CDULL, 0xE247150422EA1ED4ULL, 0xB8A762D0521BC98AULL, + 0xF4D027275AC1348BULL, 0xC17669101999024AULL, 0xBE5E9001A8D66AD7ULL, + 0xC57DB17C620A8652ULL, 0xAB739D7700C29F52ULL, 0xDD921F01A70C4AFAULL, + 0xA6824A4E10B9A6F0ULL, 0x74866A08CFE4FFE3ULL, 0x6CDEBE7B89998CAFULL, + 0x9DF30B5C8FFDAC50ULL, 0xAC4032EF4F2D9AE3ULL +}; + +static const BN_ULONG dh2048_224_q[] = { + 0xBF389A99B36371EBULL, 0x1F80535A4738CEBCULL, 0xC58D93FE99717710ULL, + 0x00000000801C0D34ULL +}; + +static const BN_ULONG dh2048_256_p[] = { + 0xDB094AE91E1A1597ULL, 0x693877FAD7EF09CAULL, 0x6116D2276E11715FULL, + 0xA4B54330C198AF12ULL, 0x75F26375D7014103ULL, 0xC3A3960A54E710C3ULL, + 0xDED4010ABD0BE621ULL, 0xC0B857F689962856ULL, 0xB3CA3F7971506026ULL, + 0x1CCACB83E6B486F6ULL, 0x67E144E514056425ULL, 0xF6A167B5A41825D9ULL, + 0x3AD8347796524D8EULL, 0xF13C6D9A51BFA4ABULL, 0x2D52526735488A0EULL, + 0xB63ACAE1CAA6B790ULL, 0x4FDB70C581B23F76ULL, 0xBC39A0BF12307F5CULL, + 0xB941F54EB1E59BB8ULL, 0x6C5BFC11D45F9088ULL, 0x22E0B1EF4275BF7BULL, + 0x91F9E6725B4758C0ULL, 0x5A8A9D306BCF67EDULL, 0x209E0C6497517ABDULL, + 0x3BF4296D830E9A7CULL, 0x16C3D91134096FAAULL, 0xFAF7DF4561B2AA30ULL, + 0xE00DF8F1D61957D4ULL, 0x5D2CEED4435E3B00ULL, 0x8CEEF608660DD0F2ULL, + 0xFFBBD19C65195999ULL, 0x87A8E61DB4B6663CULL +}; + +static const BN_ULONG dh2048_256_g[] = { + 0x664B4C0F6CC41659ULL, 0x5E2327CFEF98C582ULL, 0xD647D148D4795451ULL, + 0x2F63078490F00EF8ULL, 0x184B523D1DB246C3ULL, 0xC7891428CDC67EB6ULL, + 0x7FD028370DF92B52ULL, 0xB3353BBB64E0EC37ULL, 0xECD06E1557CD0915ULL, + 0xB7D2BBD2DF016199ULL, 0xC8484B1E052588B9ULL, 0xDB2A3B7313D3FE14ULL, + 0xD052B985D182EA0AULL, 0xA4BD1BFFE83B9C80ULL, 0xDFC967C1FB3F2E55ULL, + 0xB5045AF2767164E1ULL, 0x1D14348F6F2F9193ULL, 0x64E67982428EBC83ULL, + 0x8AC376D282D6ED38ULL, 0x777DE62AAAB8A862ULL, 0xDDF463E5E9EC144BULL, + 0x0196F931C77A57F2ULL, 0xA55AE31341000A65ULL, 0x901228F8C28CBB18ULL, + 0xBC3773BF7E8C6F62ULL, 0xBE3A6C1B0C6B47B1ULL, 0xFF4FED4AAC0BB555ULL, + 0x10DBC15077BE463FULL, 0x07F4793A1A0BA125ULL, 0x4CA7B18F21EF2054ULL, + 0x2E77506660EDBD48ULL, 0x3FB32C9B73134D0BULL +}; + +static const BN_ULONG dh2048_256_q[] = { + 0xA308B0FE64F5FBD3ULL, 0x99B1A47D1EB3750BULL, 0xB447997640129DA2ULL, + 0x8CF83642A709A097ULL +}; + +#elif BN_BITS2 == 32 + +static const BN_ULONG dh1024_160_p[] = { + 0x2E4A4371, 0xDF1FB2BC, 0x6D4DA708, 0xE68CFDA7, 0x365C1A65, 0x45BF37DF, + 0x0DC8B4BD, 0xA151AF5F, 0xF55BCCC0, 0xFAA31A4F, 0xE5644738, 0x4EFFD6FA, + 0x219A7372, 0x98488E9C, 0x90C4BD70, 0xACCBDD7D, 0xD49B83BF, 0x24975C3C, + 0xA9061123, 0x13ECB4AE, 0x2EE652C0, 0x9838EF1E, 0x75A23D18, 0x6073E286, + 0x52D23B61, 0x9A6A9DCA, 0xFB06A3C6, 0x52C99FBC, 0xAE5D54EC, 0xDE92DE5E, + 0xA080E01D, 0xB10B8F96 +}; + +static const BN_ULONG dh1024_160_g[] = { + 0x22B3B2E5, 0x855E6EEB, 0xF97C2A24, 0x858F4DCE, 0x18D08BC8, 0x2D779D59, + 0x8E73AFA3, 0xD662A4D1, 0x69B6A28A, 0x1DBF0A01, 0x7A091F53, 0xA6A24C08, + 0x63F80A76, 0x909D0D22, 0xB9A92EE1, 0xD7FBD7D3, 0x9E2749F4, 0x5E91547F, + 0xB01B886A, 0x160217B4, 0x5504F213, 0x777E690F, 0x5C41564B, 0x266FEA1E, + 0x14266D31, 0xD6406CFF, 0x58AC507F, 0xF8104DD2, 0xEFB99905, 0x6765A442, + 0xC3FD3412, 0xA4D1CBD5 +}; + +static const BN_ULONG dh1024_160_q[] = { + 0x49462353, 0x64B7CB9D, 0x8ABA4E7D, 0x81A8DF27, 0xF518AA87 +}; + +static const BN_ULONG dh2048_224_p[] = { + 0x0C10E64F, 0x0AC4DFFE, 0x4E71B81C, 0xCF9DE538, 0xFFA31F71, 0x7EF363E2, + 0x6B8E75B9, 0xE3FB73C1, 0x4BA80A29, 0xC9B53DCF, 0x16E79763, 0x23F10B0E, + 0x13042E9B, 0xC52172E4, 0xC928B2B9, 0xBE60E69C, 0xB9E587E8, 0x80CD86A1, + 0x98C641A4, 0x315D75E1, 0x44328387, 0xCDF93ACC, 0xDC0A486D, 0x15987D9A, + 0x1FD5A074, 0x7310F712, 0xDE31EFDC, 0x278273C7, 0x415D9330, 0x1602E714, + 0xBC8985DB, 0x81286130, 0x70918836, 0xB3BF8A31, 0xB9C49708, 0x6A00E0A0, + 0x8BBC27BE, 0xC6BA0B2C, 0xED34DBF6, 0xC9F98D11, 0xB6C12207, 0x7AD5B7D0, + 0x55B7394B, 0xD91E8FEF, 0xEFDA4DF8, 0x9037C9ED, 0xAD6AC212, 0x6D3F8152, + 0x1274A0A6, 0x1DE6B85A, 0x309C180E, 0xEB3D688A, 0x7BA1DF15, 0xAF9A3C40, + 0xF95A56DB, 0xE6FA141D, 0xB61D0A75, 0xB54B1597, 0x683B9FD1, 0xA20D64E5, + 0x9559C51F, 0xD660FAA7, 0x9123A9D0, 0xAD107E1E +}; + +static const BN_ULONG dh2048_224_g[] = { + 0x191F2BFA, 0x84B890D3, 0x2A7065B3, 0x81BC087F, 0xF6EC0179, 0x19C418E1, + 0x71CFFF4C, 0x7B5A0F1C, 0x9B6AA4BD, 0xEDFE72FE, 0x94B30269, 0x81E1BCFE, + 0x8D6C0191, 0x566AFBB4, 0x409D13CD, 0xB539CCE3, 0x5F2FF381, 0x6AA21E7F, + 0x770589EF, 0xD9E263E4, 0xD19963DD, 0x10E183ED, 0x150B8EEB, 0xB70A8137, + 0x28C8F8AC, 0x051AE3D4, 0x0C1AB15B, 0xBB77A86F, 0x16A330EF, 0x6E3025E3, + 0xD6F83456, 0x19529A45, 0x118E98D1, 0xF180EB34, 0x50717CBE, 0xB5F6C6B2, + 0xDA7460CD, 0x09939D54, 0x22EA1ED4, 0xE2471504, 0x521BC98A, 0xB8A762D0, + 0x5AC1348B, 0xF4D02727, 0x1999024A, 0xC1766910, 0xA8D66AD7, 0xBE5E9001, + 0x620A8652, 0xC57DB17C, 0x00C29F52, 0xAB739D77, 0xA70C4AFA, 0xDD921F01, + 0x10B9A6F0, 0xA6824A4E, 0xCFE4FFE3, 0x74866A08, 0x89998CAF, 0x6CDEBE7B, + 0x8FFDAC50, 0x9DF30B5C, 0x4F2D9AE3, 0xAC4032EF +}; + +static const BN_ULONG dh2048_224_q[] = { + 0xB36371EB, 0xBF389A99, 0x4738CEBC, 0x1F80535A, 0x99717710, 0xC58D93FE, + 0x801C0D34 +}; + +static const BN_ULONG dh2048_256_p[] = { + 0x1E1A1597, 0xDB094AE9, 0xD7EF09CA, 0x693877FA, 0x6E11715F, 0x6116D227, + 0xC198AF12, 0xA4B54330, 0xD7014103, 0x75F26375, 0x54E710C3, 0xC3A3960A, + 0xBD0BE621, 0xDED4010A, 0x89962856, 0xC0B857F6, 0x71506026, 0xB3CA3F79, + 0xE6B486F6, 0x1CCACB83, 0x14056425, 0x67E144E5, 0xA41825D9, 0xF6A167B5, + 0x96524D8E, 0x3AD83477, 0x51BFA4AB, 0xF13C6D9A, 0x35488A0E, 0x2D525267, + 0xCAA6B790, 0xB63ACAE1, 0x81B23F76, 0x4FDB70C5, 0x12307F5C, 0xBC39A0BF, + 0xB1E59BB8, 0xB941F54E, 0xD45F9088, 0x6C5BFC11, 0x4275BF7B, 0x22E0B1EF, + 0x5B4758C0, 0x91F9E672, 0x6BCF67ED, 0x5A8A9D30, 0x97517ABD, 0x209E0C64, + 0x830E9A7C, 0x3BF4296D, 0x34096FAA, 0x16C3D911, 0x61B2AA30, 0xFAF7DF45, + 0xD61957D4, 0xE00DF8F1, 0x435E3B00, 0x5D2CEED4, 0x660DD0F2, 0x8CEEF608, + 0x65195999, 0xFFBBD19C, 0xB4B6663C, 0x87A8E61D +}; + +static const BN_ULONG dh2048_256_g[] = { + 0x6CC41659, 0x664B4C0F, 0xEF98C582, 0x5E2327CF, 0xD4795451, 0xD647D148, + 0x90F00EF8, 0x2F630784, 0x1DB246C3, 0x184B523D, 0xCDC67EB6, 0xC7891428, + 0x0DF92B52, 0x7FD02837, 0x64E0EC37, 0xB3353BBB, 0x57CD0915, 0xECD06E15, + 0xDF016199, 0xB7D2BBD2, 0x052588B9, 0xC8484B1E, 0x13D3FE14, 0xDB2A3B73, + 0xD182EA0A, 0xD052B985, 0xE83B9C80, 0xA4BD1BFF, 0xFB3F2E55, 0xDFC967C1, + 0x767164E1, 0xB5045AF2, 0x6F2F9193, 0x1D14348F, 0x428EBC83, 0x64E67982, + 0x82D6ED38, 0x8AC376D2, 0xAAB8A862, 0x777DE62A, 0xE9EC144B, 0xDDF463E5, + 0xC77A57F2, 0x0196F931, 0x41000A65, 0xA55AE313, 0xC28CBB18, 0x901228F8, + 0x7E8C6F62, 0xBC3773BF, 0x0C6B47B1, 0xBE3A6C1B, 0xAC0BB555, 0xFF4FED4A, + 0x77BE463F, 0x10DBC150, 0x1A0BA125, 0x07F4793A, 0x21EF2054, 0x4CA7B18F, + 0x60EDBD48, 0x2E775066, 0x73134D0B, 0x3FB32C9B +}; + +static const BN_ULONG dh2048_256_q[] = { + 0x64F5FBD3, 0xA308B0FE, 0x1EB3750B, 0x99B1A47D, 0x40129DA2, 0xB4479976, + 0xA709A097, 0x8CF83642 +}; + +#else +# error "unsupported BN_BITS2" +#endif + +/* Macro to make a BIGNUM from static data */ + +#define make_dh_bn(x) static const BIGNUM _bignum_##x = { (BN_ULONG *) x, \ + sizeof(x)/sizeof(BN_ULONG),\ + sizeof(x)/sizeof(BN_ULONG),\ + 0, BN_FLG_STATIC_DATA } + +/* + * Macro to make a DH structure from BIGNUM data. NB: although just copying + * the BIGNUM static pointers would be more efficient we can't as they get + * wiped using BN_clear_free() when DH_free() is called. + */ + +#define make_dh(x) \ +DH * DH_get_##x(void) \ + { \ + DH *dh; \ + make_dh_bn(dh##x##_p); \ + make_dh_bn(dh##x##_q); \ + make_dh_bn(dh##x##_g); \ + dh = DH_new(); \ + if (!dh) \ + return NULL; \ + dh->p = BN_dup(&_bignum_dh##x##_p); \ + dh->g = BN_dup(&_bignum_dh##x##_g); \ + dh->q = BN_dup(&_bignum_dh##x##_q); \ + if (!dh->p || !dh->q || !dh->g) \ + { \ + DH_free(dh); \ + return NULL; \ + } \ + return dh; \ + } + +make_dh(1024_160) +make_dh(2048_224) +make_dh(2048_256) diff --git a/Sources/COpenSSL/digest.c b/Sources/COpenSSL/digest.c new file mode 100644 index 00000000..e2c7af91 --- /dev/null +++ b/Sources/COpenSSL/digest.c @@ -0,0 +1,408 @@ +/* crypto/evp/digest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "objects.h" +#include "evp.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +#ifdef OPENSSL_FIPS +# include +# include "evp_locl.h" +#endif + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx) +{ + memset(ctx, '\0', sizeof(*ctx)); +} + +EVP_MD_CTX *EVP_MD_CTX_create(void) +{ + EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); + + if (ctx) + EVP_MD_CTX_init(ctx); + + return ctx; +} + +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) +{ + EVP_MD_CTX_init(ctx); + return EVP_DigestInit_ex(ctx, type, NULL); +} + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) +{ + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); +#ifdef OPENSSL_FIPS + /* If FIPS mode switch to approved implementation if possible */ + if (FIPS_mode()) { + const EVP_MD *fipsmd; + if (type) { + fipsmd = evp_get_fips_md(type); + if (fipsmd) + type = fipsmd; + } + } +#endif +#ifndef OPENSSL_NO_ENGINE + /* + * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so + * this context may already have an ENGINE! Try to avoid releasing the + * previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unecessary. + */ + if (ctx->engine && ctx->digest && (!type || + (type + && (type->type == + ctx->digest->type)))) + goto skip_to_init; + if (type) { + /* + * Ensure an ENGINE left lying around from last time is cleared (the + * previous check attempted to avoid this if the same ENGINE and + * EVP_MD could be used). + */ + if (ctx->engine) + ENGINE_finish(ctx->engine); + if (impl) { + if (!ENGINE_init(impl)) { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } else + /* Ask if an ENGINE is reserved for this job */ + impl = ENGINE_get_digest_engine(type->type); + if (impl) { + /* There's an ENGINE for this job ... (apparently) */ + const EVP_MD *d = ENGINE_get_digest(impl, type->type); + if (!d) { + /* Same comment from evp_enc.c */ + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); + ENGINE_finish(impl); + return 0; + } + /* We'll use the ENGINE's private digest definition */ + type = d; + /* + * Store the ENGINE functional reference so we know 'type' came + * from an ENGINE and we need to release it when done. + */ + ctx->engine = impl; + } else + ctx->engine = NULL; + } else { + if (!ctx->digest) { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET); + return 0; + } + type = ctx->digest; + } +#endif + if (ctx->digest != type) { + if (ctx->digest && ctx->digest->ctx_size) { + OPENSSL_free(ctx->md_data); + ctx->md_data = NULL; + } + ctx->digest = type; + if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { + ctx->update = type->update; + ctx->md_data = OPENSSL_malloc(type->ctx_size); + if (ctx->md_data == NULL) { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE); + return 0; + } + } + } +#ifndef OPENSSL_NO_ENGINE + skip_to_init: +#endif + if (ctx->pctx) { + int r; + r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); + if (r <= 0 && (r != -2)) + return 0; + } + if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) + return 1; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) { + if (FIPS_digestinit(ctx, type)) + return 1; + OPENSSL_free(ctx->md_data); + ctx->md_data = NULL; + return 0; + } +#endif + return ctx->digest->init(ctx); +} + +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_digestupdate(ctx, data, count); +#endif + return ctx->update(ctx, data, count); +} + +/* The caller can assume that this removes any secret data from the context */ +int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) +{ + int ret; + ret = EVP_DigestFinal_ex(ctx, md, size); + EVP_MD_CTX_cleanup(ctx); + return ret; +} + +/* The caller can assume that this removes any secret data from the context */ +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) +{ + int ret; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_digestfinal(ctx, md, size); +#endif + + OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ret = ctx->digest->final(ctx, md); + if (size != NULL) + *size = ctx->digest->md_size; + if (ctx->digest->cleanup) { + ctx->digest->cleanup(ctx); + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); + } + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + return ret; +} + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) +{ + EVP_MD_CTX_init(out); + return EVP_MD_CTX_copy_ex(out, in); +} + +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) +{ + unsigned char *tmp_buf; + if ((in == NULL) || (in->digest == NULL)) { + EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a digest context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) { + EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB); + return 0; + } +#endif + + if (out->digest == in->digest) { + tmp_buf = out->md_data; + EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); + } else + tmp_buf = NULL; + EVP_MD_CTX_cleanup(out); + memcpy(out, in, sizeof(*out)); + + if (in->md_data && out->digest->ctx_size) { + if (tmp_buf) + out->md_data = tmp_buf; + else { + out->md_data = OPENSSL_malloc(out->digest->ctx_size); + if (!out->md_data) { + EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE); + return 0; + } + } + memcpy(out->md_data, in->md_data, out->digest->ctx_size); + } + + out->update = in->update; + + if (in->pctx) { + out->pctx = EVP_PKEY_CTX_dup(in->pctx); + if (!out->pctx) { + EVP_MD_CTX_cleanup(out); + return 0; + } + } + + if (out->digest->copy) + return out->digest->copy(out, in); + + return 1; +} + +int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, const EVP_MD *type, + ENGINE *impl) +{ + EVP_MD_CTX ctx; + int ret; + + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT); + ret = EVP_DigestInit_ex(&ctx, type, impl) + && EVP_DigestUpdate(&ctx, data, count) + && EVP_DigestFinal_ex(&ctx, md, size); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) +{ + if (ctx) { + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +/* This call frees resources associated with the context */ +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) +{ +#ifndef OPENSSL_FIPS + /* + * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because + * sometimes only copies of the context are ever finalised. + */ + if (ctx->digest && ctx->digest->cleanup + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) + ctx->digest->cleanup(ctx); + if (ctx->digest && ctx->digest->ctx_size && ctx->md_data + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + OPENSSL_free(ctx->md_data); + } +#endif + if (ctx->pctx) + EVP_PKEY_CTX_free(ctx->pctx); +#ifndef OPENSSL_NO_ENGINE + if (ctx->engine) + /* + * The EVP_MD we used belongs to an ENGINE, release the functional + * reference we held for this reason. + */ + ENGINE_finish(ctx->engine); +#endif +#ifdef OPENSSL_FIPS + FIPS_md_ctx_cleanup(ctx); +#endif + memset(ctx, '\0', sizeof(*ctx)); + + return 1; +} diff --git a/Sources/COpenSSL/dsa.h b/Sources/COpenSSL/dsa.h new file mode 100644 index 00000000..985c0cd9 --- /dev/null +++ b/Sources/COpenSSL/dsa.h @@ -0,0 +1,335 @@ +/* crypto/dsa/dsa.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * The DSS routines are based on patches supplied by + * Steven Schoch . He basically did the + * work and I have just tweaked them a little to fit into my + * stylistic vision for SSLeay :-) */ + +#ifndef HEADER_DSA_H +# define HEADER_DSA_H + +# include "e_os2.h" + +# ifdef OPENSSL_NO_DSA +# error DSA is disabled. +# endif + +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# include "crypto.h" +# include "ossl_typ.h" + +# ifndef OPENSSL_NO_DEPRECATED +# include "bn.h" +# ifndef OPENSSL_NO_DH +# include "dh.h" +# endif +# endif + +# ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +# endif + +# define DSA_FLAG_CACHE_MONT_P 0x01 +/* + * new with 0.9.7h; the built-in DSA implementation now uses constant time + * modular exponentiation for secret exponents by default. This flag causes + * the faster variable sliding window method to be used for all exponents. + */ +# define DSA_FLAG_NO_EXP_CONSTTIME 0x02 + +/* + * If this flag is set the DSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its reposibility to ensure the + * result is compliant. + */ + +# define DSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DSA_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dsa_st DSA; */ +/* typedef struct dsa_method DSA_METHOD; */ + +typedef struct DSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +} DSA_SIG; + +struct dsa_method { + const char *name; + DSA_SIG *(*dsa_do_sign) (const unsigned char *dgst, int dlen, DSA *dsa); + int (*dsa_sign_setup) (DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); + int (*dsa_do_verify) (const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + int (*dsa_mod_exp) (DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); + /* Can be null */ + int (*bn_mod_exp) (DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + int (*init) (DSA *dsa); + int (*finish) (DSA *dsa); + int flags; + char *app_data; + /* If this is non-NULL, it is used to generate DSA parameters */ + int (*dsa_paramgen) (DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + /* If this is non-NULL, it is used to generate DSA keys */ + int (*dsa_keygen) (DSA *dsa); +}; + +struct dsa_st { + /* + * This first variable is used to pick up errors where a DSA is passed + * instead of of a EVP_PKEY + */ + int pad; + long version; + int write_params; + BIGNUM *p; + BIGNUM *q; /* == 20 */ + BIGNUM *g; + BIGNUM *pub_key; /* y public key */ + BIGNUM *priv_key; /* x private key */ + BIGNUM *kinv; /* Signing pre-calc */ + BIGNUM *r; /* Signing pre-calc */ + int flags; + /* Normally used to cache montgomery values */ + BN_MONT_CTX *method_mont_p; + int references; + CRYPTO_EX_DATA ex_data; + const DSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; +}; + +# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) +# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) + +DSA *DSAparams_dup(DSA *x); +DSA_SIG *DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); + +DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +int DSA_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); + +DSA *DSA_new(void); +DSA *DSA_new_method(ENGINE *engine); +void DSA_free(DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); + /* next 4 return -1 on error */ +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); + +DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +DSA *DSA_generate_parameters(int bits, + unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, void + (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + +int DSA_generate_key(DSA *a); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +int i2d_DSAparams(const DSA *a, unsigned char **pp); + +# ifndef OPENSSL_NO_BIO +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +# endif +# ifndef OPENSSL_NO_FP_API +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); +# endif + +# define DSS_prime_checks 64 +/* + * Primality test according to FIPS PUB 186-4, Appendix C.3. Since we only + * have one value here we set the number of checks to 64 which is the 128 bit + * security level that is the highest level and valid for creating a 3072 bit + * DSA key. + */ +# define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +# ifndef OPENSSL_NO_DH +/* + * Convert DSA structure (key or just parameters) into DH structure (be + * careful to avoid small subgroup attacks when using this!) + */ +DH *DSA_dup_DH(const DSA *r); +# endif + +# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) + +# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSA_strings(void); + +/* Error codes for the DSA functions. */ + +/* Function codes. */ +# define DSA_F_D2I_DSA_SIG 110 +# define DSA_F_DO_DSA_PRINT 104 +# define DSA_F_DSAPARAMS_PRINT 100 +# define DSA_F_DSAPARAMS_PRINT_FP 101 +# define DSA_F_DSA_BUILTIN_PARAMGEN2 126 +# define DSA_F_DSA_DO_SIGN 112 +# define DSA_F_DSA_DO_VERIFY 113 +# define DSA_F_DSA_GENERATE_KEY 124 +# define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 +# define DSA_F_DSA_NEW_METHOD 103 +# define DSA_F_DSA_PARAM_DECODE 119 +# define DSA_F_DSA_PRINT_FP 105 +# define DSA_F_DSA_PRIV_DECODE 115 +# define DSA_F_DSA_PRIV_ENCODE 116 +# define DSA_F_DSA_PUB_DECODE 117 +# define DSA_F_DSA_PUB_ENCODE 118 +# define DSA_F_DSA_SIGN 106 +# define DSA_F_DSA_SIGN_SETUP 107 +# define DSA_F_DSA_SIG_NEW 109 +# define DSA_F_DSA_SIG_PRINT 125 +# define DSA_F_DSA_VERIFY 108 +# define DSA_F_I2D_DSA_SIG 111 +# define DSA_F_OLD_DSA_PRIV_DECODE 122 +# define DSA_F_PKEY_DSA_CTRL 120 +# define DSA_F_PKEY_DSA_CTRL_STR 127 +# define DSA_F_PKEY_DSA_KEYGEN 121 +# define DSA_F_SIG_CB 114 + +/* Reason codes. */ +# define DSA_R_BAD_Q_VALUE 102 +# define DSA_R_BN_DECODE_ERROR 108 +# define DSA_R_BN_ERROR 109 +# define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +# define DSA_R_DECODE_ERROR 104 +# define DSA_R_INVALID_DIGEST_TYPE 106 +# define DSA_R_INVALID_PARAMETERS 112 +# define DSA_R_MISSING_PARAMETERS 101 +# define DSA_R_MODULUS_TOO_LARGE 103 +# define DSA_R_NEED_NEW_SETUP_VALUES 110 +# define DSA_R_NON_FIPS_DSA_METHOD 111 +# define DSA_R_NO_PARAMETERS_SET 107 +# define DSA_R_PARAMETER_ENCODING_ERROR 105 +# define DSA_R_Q_NOT_PRIME 113 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/dsa_.c b/Sources/COpenSSL/dsa_.c new file mode 100644 index 00000000..f1d90aa9 --- /dev/null +++ b/Sources/COpenSSL/dsa_.c @@ -0,0 +1,3494 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "x509.h" +#include "asn1.h" +#include "dsa.h" +#include "bn.h" +#ifndef OPENSSL_NO_CMS +# include "cms.h" +#endif +#include "asn1_locl.h" + +static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *public_key = NULL; + + DSA *dsa = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype == V_ASN1_SEQUENCE) { + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + + if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + goto err; + } + + } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) { + if (!(dsa = DSA_new())) { + DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + goto err; + } + + if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); + goto err; + } + + ASN1_INTEGER_free(public_key); + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; + + err: + if (public_key) + ASN1_INTEGER_free(public_key); + if (dsa) + DSA_free(dsa); + return 0; + +} + +static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + DSA *dsa; + int ptype; + unsigned char *penc = NULL; + int penclen; + ASN1_STRING *str = NULL; + ASN1_OBJECT *aobj; + + dsa = pkey->pkey.dsa; + if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { + str = ASN1_STRING_new(); + if (!str) { + DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + str->length = i2d_DSAparams(dsa, &str->data); + if (str->length <= 0) { + DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + ptype = V_ASN1_SEQUENCE; + } else + ptype = V_ASN1_UNDEF; + + dsa->write_params = 0; + + penclen = i2d_DSAPublicKey(dsa, &penc); + + if (penclen <= 0) { + DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + aobj = OBJ_nid2obj(EVP_PKEY_DSA); + if (aobj == NULL) + goto err; + + if (X509_PUBKEY_set0_param(pk, aobj, ptype, str, penc, penclen)) + return 1; + + err: + if (penc) + OPENSSL_free(penc); + if (str) + ASN1_STRING_free(str); + + return 0; +} + +/* + * In PKCS#8 DSA: you just get a private key integer and parameters in the + * AlgorithmIdentifier the pubkey must be recalculated. + */ + +static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + BN_CTX *ctx = NULL; + + STACK_OF(ASN1_TYPE) *ndsa = NULL; + DSA *dsa = NULL; + + int ret = 0; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + /* Check for broken DSA PKCS#8, UGH! */ + if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { + ASN1_TYPE *t1, *t2; + if (!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) + goto decerr; + if (sk_ASN1_TYPE_num(ndsa) != 2) + goto decerr; + /*- + * Handle Two broken types: + * SEQUENCE {parameters, priv_key} + * SEQUENCE {pub_key, priv_key} + */ + + t1 = sk_ASN1_TYPE_value(ndsa, 0); + t2 = sk_ASN1_TYPE_value(ndsa, 1); + if (t1->type == V_ASN1_SEQUENCE) { + p8->broken = PKCS8_EMBEDDED_PARAM; + pval = t1->value.ptr; + } else if (ptype == V_ASN1_SEQUENCE) + p8->broken = PKCS8_NS_DB; + else + goto decerr; + + if (t2->type != V_ASN1_INTEGER) + goto decerr; + + privkey = t2->value.integer; + } else { + const unsigned char *q = p; + if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen))) + goto decerr; + if (privkey->type == V_ASN1_NEG_INTEGER) { + p8->broken = PKCS8_NEG_PRIVKEY; + ASN1_STRING_clear_free(privkey); + if (!(privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen))) + goto decerr; + } + if (ptype != V_ASN1_SEQUENCE) + goto decerr; + } + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) + goto decerr; + /* We have parameters now set private key */ + if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { + DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); + goto dsaerr; + } + /* Calculate public key */ + if (!(dsa->pub_key = BN_new())) { + DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + if (!(ctx = BN_CTX_new())) { + DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + + BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME); + if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { + DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); + goto dsaerr; + } + + EVP_PKEY_assign_DSA(pkey, dsa); + + ret = 1; + goto done; + + decerr: + DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR); + dsaerr: + DSA_free(dsa); + done: + BN_CTX_free(ctx); + if (ndsa) + sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); + else + ASN1_STRING_clear_free(privkey); + return ret; +} + +static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + ASN1_STRING *params = NULL; + ASN1_INTEGER *prkey = NULL; + unsigned char *dp = NULL; + int dplen; + + if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) { + DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS); + goto err; + } + + params = ASN1_STRING_new(); + + if (!params) { + DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); + if (params->length <= 0) { + DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + params->type = V_ASN1_SEQUENCE; + + /* Get private key into integer */ + prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); + + if (!prkey) { + DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR); + goto err; + } + + dplen = i2d_ASN1_INTEGER(prkey, &dp); + + ASN1_STRING_clear_free(prkey); + prkey = NULL; + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) + goto err; + + return 1; + + err: + if (dp != NULL) + OPENSSL_free(dp); + if (params != NULL) + ASN1_STRING_free(params); + if (prkey != NULL) + ASN1_STRING_clear_free(prkey); + return 0; +} + +static int int_dsa_size(const EVP_PKEY *pkey) +{ + return (DSA_size(pkey->pkey.dsa)); +} + +static int dsa_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.dsa->p); +} + +static int dsa_missing_parameters(const EVP_PKEY *pkey) +{ + DSA *dsa; + dsa = pkey->pkey.dsa; + if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) + return 1; + return 0; +} + +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + BIGNUM *a; + + if ((a = BN_dup(from->pkey.dsa->p)) == NULL) + return 0; + if (to->pkey.dsa->p != NULL) + BN_free(to->pkey.dsa->p); + to->pkey.dsa->p = a; + + if ((a = BN_dup(from->pkey.dsa->q)) == NULL) + return 0; + if (to->pkey.dsa->q != NULL) + BN_free(to->pkey.dsa->q); + to->pkey.dsa->q = a; + + if ((a = BN_dup(from->pkey.dsa->g)) == NULL) + return 0; + if (to->pkey.dsa->g != NULL) + BN_free(to->pkey.dsa->g); + to->pkey.dsa->g = a; + return 1; +} + +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) || + BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) || + BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g)) + return 0; + else + return 1; +} + +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0) + return 0; + else + return 1; +} + +static void int_dsa_free(EVP_PKEY *pkey) +{ + DSA_free(pkey->pkey.dsa); +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) +{ + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; +} + +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) +{ + unsigned char *m = NULL; + int ret = 0; + size_t buf_len = 0; + const char *ktype = NULL; + + const BIGNUM *priv_key, *pub_key; + + if (ptype == 2) + priv_key = x->priv_key; + else + priv_key = NULL; + + if (ptype > 0) + pub_key = x->pub_key; + else + pub_key = NULL; + + if (ptype == 2) + ktype = "Private-Key"; + else if (ptype == 1) + ktype = "Public-Key"; + else + ktype = "DSA-Parameters"; + + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->g, &buf_len); + update_buflen(priv_key, &buf_len); + update_buflen(pub_key, &buf_len); + + m = (unsigned char *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (priv_key) { + if (!BIO_indent(bp, off, 128)) + goto err; + if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) + <= 0) + goto err; + } + + if (!ASN1_bn_print(bp, "priv:", priv_key, m, off)) + goto err; + if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off)) + goto err; + if (!ASN1_bn_print(bp, "P: ", x->p, m, off)) + goto err; + if (!ASN1_bn_print(bp, "Q: ", x->q, m, off)) + goto err; + if (!ASN1_bn_print(bp, "G: ", x->g, m, off)) + goto err; + ret = 1; + err: + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +static int dsa_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + DSA *dsa; + if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) { + DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; +} + +static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_DSAparams(pkey->pkey.dsa, pder); +} + +static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); +} + +static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); +} + +static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); +} + +static int old_dsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + DSA *dsa; + if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) { + DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; +} + +static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); +} + +static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) +{ + DSA_SIG *dsa_sig; + const unsigned char *p; + if (!sig) { + if (BIO_puts(bp, "\n") <= 0) + return 0; + else + return 1; + } + p = sig->data; + dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); + if (dsa_sig) { + int rv = 0; + size_t buf_len = 0; + unsigned char *m = NULL; + update_buflen(dsa_sig->r, &buf_len); + update_buflen(dsa_sig->s, &buf_len); + m = OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BIO_write(bp, "\n", 1) != 1) + goto err; + + if (!ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent)) + goto err; + if (!ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) + goto err; + rv = 1; + err: + if (m) + OPENSSL_free(m); + DSA_SIG_free(dsa_sig); + return rv; + } + return X509_signature_dump(bp, sig, indent); +} + +static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: + *(int *)arg2 = CMS_RECIPINFO_NONE; + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha256; + return 2; + + default: + return -2; + + } + +} + +/* NB these are sorted in pkey_id order, lowest first */ + +const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = { + + { + EVP_PKEY_DSA2, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS}, + + { + EVP_PKEY_DSA1, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS}, + + { + EVP_PKEY_DSA4, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS}, + + { + EVP_PKEY_DSA3, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS}, + + { + EVP_PKEY_DSA, + EVP_PKEY_DSA, + 0, + + "DSA", + "OpenSSL DSA method", + + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, + dsa_pub_print, + + dsa_priv_decode, + dsa_priv_encode, + dsa_priv_print, + + int_dsa_size, + dsa_bits, + + dsa_param_decode, + dsa_param_encode, + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, + dsa_param_print, + dsa_sig_print, + + int_dsa_free, + dsa_pkey_ctrl, + old_dsa_priv_decode, + old_dsa_priv_encode} +}; +/* dsa_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "dsa.h" +// #include "asn1.h" +#include "asn1t.h" +#include "rand.h" + +/* Override the default new methods */ +static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + DSA_SIG *sig; + sig = OPENSSL_malloc(sizeof(DSA_SIG)); + if (!sig) { + DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE); + return 0; + } + sig->r = NULL; + sig->s = NULL; + *pval = (ASN1_VALUE *)sig; + return 2; + } + return 1; +} + +ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = { + ASN1_SIMPLE(DSA_SIG, r, CBIGNUM), + ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) +} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG) + +/* Override the default free and new methods */ +static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)DSA_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + DSA_free((DSA *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = { + ASN1_SIMPLE(DSA, version, LONG), + ASN1_SIMPLE(DSA, p, BIGNUM), + ASN1_SIMPLE(DSA, q, BIGNUM), + ASN1_SIMPLE(DSA, g, BIGNUM), + ASN1_SIMPLE(DSA, pub_key, BIGNUM), + ASN1_SIMPLE(DSA, priv_key, BIGNUM) +} ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey) + +ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = { + ASN1_SIMPLE(DSA, p, BIGNUM), + ASN1_SIMPLE(DSA, q, BIGNUM), + ASN1_SIMPLE(DSA, g, BIGNUM), +} ASN1_SEQUENCE_END_cb(DSA, DSAparams) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams) + +/* + * DSA public key is a bit trickier... its effectively a CHOICE type decided + * by a field called write_params which can either write out just the public + * key as an INTEGER or the parameters and public key in a SEQUENCE + */ + +ASN1_SEQUENCE(dsa_pub_internal) = { + ASN1_SIMPLE(DSA, pub_key, BIGNUM), + ASN1_SIMPLE(DSA, p, BIGNUM), + ASN1_SIMPLE(DSA, q, BIGNUM), + ASN1_SIMPLE(DSA, g, BIGNUM) +} ASN1_SEQUENCE_END_name(DSA, dsa_pub_internal) + +ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = { + ASN1_SIMPLE(DSA, pub_key, BIGNUM), + ASN1_EX_COMBINE(0, 0, dsa_pub_internal) +} ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) + +DSA *DSAparams_dup(DSA *dsa) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); +} + +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa) +{ + DSA_SIG *s; + RAND_seed(dgst, dlen); + s = DSA_do_sign(dgst, dlen, dsa); + if (s == NULL) { + *siglen = 0; + return (0); + } + *siglen = i2d_DSA_SIG(s, &sig); + DSA_SIG_free(s); + return (1); +} + +/* data has already been hashed (probably with SHA or SHA-1). */ +/*- + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa) +{ + DSA_SIG *s; + const unsigned char *p = sigbuf; + unsigned char *der = NULL; + int derlen = -1; + int ret = -1; + + s = DSA_SIG_new(); + if (s == NULL) + return (ret); + if (d2i_DSA_SIG(&s, &p, siglen) == NULL) + goto err; + /* Ensure signature uses DER and doesn't have trailing garbage */ + derlen = i2d_DSA_SIG(s, &der); + if (derlen != siglen || memcmp(sigbuf, der, derlen)) + goto err; + ret = DSA_do_verify(dgst, dgst_len, s, dsa); + err: + if (derlen > 0) { + OPENSSL_cleanse(der, derlen); + OPENSSL_free(der); + } + DSA_SIG_free(s); + return (ret); +} +/* crypto/dsa/dsa_depr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This file contains deprecated function(s) that are now wrappers to the new + * version(s). + */ + +#undef GENUINE_DSA + +#ifdef GENUINE_DSA +/* + * Parameter generation follows the original release of FIPS PUB 186, + * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) + */ +# define HASH EVP_sha() +#else +/* + * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, + * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB + * 180-1) + */ +# define HASH EVP_sha1() +#endif + +static void *dummy = &dummy; + +#ifndef OPENSSL_NO_SHA + +# include +# include +# include "cryptlib.h" +# include "evp.h" +# include "bn.h" +# include "dsa.h" +# include "rand.h" +# include "sha.h" + +# ifndef OPENSSL_NO_DEPRECATED +DSA *DSA_generate_parameters(int bits, + unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, + void (*callback) (int, int, void *), + void *cb_arg) +{ + BN_GENCB cb; + DSA *ret; + + if ((ret = DSA_new()) == NULL) + return NULL; + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (DSA_generate_parameters_ex(ret, bits, seed_in, seed_len, + counter_ret, h_ret, &cb)) + return ret; + DSA_free(ret); + return NULL; +} +# endif +#endif +/* crypto/dsa/dsa_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "dsa.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason) + +static ERR_STRING_DATA DSA_str_functs[] = { + {ERR_FUNC(DSA_F_D2I_DSA_SIG), "d2i_DSA_SIG"}, + {ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"}, + {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"}, + {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, + {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"}, + {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, + {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, + {ERR_FUNC(DSA_F_DSA_GENERATE_KEY), "DSA_generate_key"}, + {ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX), + "DSA_generate_parameters_ex"}, + {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"}, + {ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "DSA_PARAM_DECODE"}, + {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"}, + {ERR_FUNC(DSA_F_DSA_PRIV_DECODE), "DSA_PRIV_DECODE"}, + {ERR_FUNC(DSA_F_DSA_PRIV_ENCODE), "DSA_PRIV_ENCODE"}, + {ERR_FUNC(DSA_F_DSA_PUB_DECODE), "DSA_PUB_DECODE"}, + {ERR_FUNC(DSA_F_DSA_PUB_ENCODE), "DSA_PUB_ENCODE"}, + {ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"}, + {ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"}, + {ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"}, + {ERR_FUNC(DSA_F_DSA_SIG_PRINT), "DSA_SIG_PRINT"}, + {ERR_FUNC(DSA_F_DSA_VERIFY), "DSA_verify"}, + {ERR_FUNC(DSA_F_I2D_DSA_SIG), "i2d_DSA_SIG"}, + {ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "OLD_DSA_PRIV_DECODE"}, + {ERR_FUNC(DSA_F_PKEY_DSA_CTRL), "PKEY_DSA_CTRL"}, + {ERR_FUNC(DSA_F_PKEY_DSA_CTRL_STR), "PKEY_DSA_CTRL_STR"}, + {ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN), "PKEY_DSA_KEYGEN"}, + {ERR_FUNC(DSA_F_SIG_CB), "SIG_CB"}, + {0, NULL} +}; + +static ERR_STRING_DATA DSA_str_reasons[] = { + {ERR_REASON(DSA_R_BAD_Q_VALUE), "bad q value"}, + {ERR_REASON(DSA_R_BN_DECODE_ERROR), "bn decode error"}, + {ERR_REASON(DSA_R_BN_ERROR), "bn error"}, + {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), + "data too large for key size"}, + {ERR_REASON(DSA_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE), "invalid digest type"}, + {ERR_REASON(DSA_R_INVALID_PARAMETERS), "invalid parameters"}, + {ERR_REASON(DSA_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(DSA_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, + {ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD), "non fips dsa method"}, + {ERR_REASON(DSA_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, + {ERR_REASON(DSA_R_Q_NOT_PRIME), "q not prime"}, + {0, NULL} +}; + +#endif + +void ERR_load_DSA_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(DSA_str_functs[0].error) == NULL) { + ERR_load_strings(0, DSA_str_functs); + ERR_load_strings(0, DSA_str_reasons); + } +#endif +} +/* crypto/dsa/dsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#undef GENUINE_DSA + +#ifdef GENUINE_DSA +/* + * Parameter generation follows the original release of FIPS PUB 186, + * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) + */ +# define HASH EVP_sha() +#else +/* + * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, + * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB + * 180-1) + */ +# define HASH EVP_sha1() +#endif + +#include "opensslconf.h" /* To see if OPENSSL_NO_SHA is defined */ + +#ifndef OPENSSL_NO_SHA + +# include +# include "cryptlib.h" +# include "evp.h" +# include "bn.h" +# include "rand.h" +# include "sha.h" +# include "dsa_locl.h" + +# ifdef OPENSSL_FIPS +/* Workaround bug in prototype */ +# define fips_dsa_builtin_paramgen2 fips_dsa_paramgen_bad +# include +# endif + +int DSA_generate_parameters_ex(DSA *ret, int bits, + const unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb) +{ +# ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD); + return 0; + } +# endif + if (ret->meth->dsa_paramgen) + return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, + counter_ret, h_ret, cb); +# ifdef OPENSSL_FIPS + else if (FIPS_mode()) { + return FIPS_dsa_generate_parameters_ex(ret, bits, + seed_in, seed_len, + counter_ret, h_ret, cb); + } +# endif + else { + const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1(); + size_t qbits = EVP_MD_size(evpmd) * 8; + + return dsa_builtin_paramgen(ret, bits, qbits, evpmd, + seed_in, seed_len, NULL, counter_ret, + h_ret, cb); + } +} + +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, + size_t seed_len, unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) +{ + int ok = 0; + unsigned char seed[SHA256_DIGEST_LENGTH]; + unsigned char md[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; + BIGNUM *r0, *W, *X, *c, *test; + BIGNUM *g = NULL, *q = NULL, *p = NULL; + BN_MONT_CTX *mont = NULL; + int i, k, n = 0, m = 0, qsize = qbits >> 3; + int counter = 0; + int r = 0; + BN_CTX *ctx = NULL; + unsigned int h = 2; + + if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && + qsize != SHA256_DIGEST_LENGTH) + /* invalid q size */ + return 0; + + if (evpmd == NULL) { + if (qsize == SHA_DIGEST_LENGTH) + evpmd = EVP_sha1(); + else if (qsize == SHA224_DIGEST_LENGTH) + evpmd = EVP_sha224(); + else + evpmd = EVP_sha256(); + } else { + qsize = EVP_MD_size(evpmd); + } + + if (bits < 512) + bits = 512; + + bits = (bits + 63) / 64 * 64; + + /* + * NB: seed_len == 0 is special case: copy generated seed to seed_in if + * it is not NULL. + */ + if (seed_len && (seed_len < (size_t)qsize)) + seed_in = NULL; /* seed buffer too small -- ignore */ + if (seed_len > (size_t)qsize) + seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger + * SEED, but our internal buffers are + * restricted to 160 bits */ + if (seed_in != NULL) + memcpy(seed, seed_in, seed_len); + + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + r0 = BN_CTX_get(ctx); + g = BN_CTX_get(ctx); + W = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + c = BN_CTX_get(ctx); + p = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + + if (test == NULL) + goto err; + + if (!BN_lshift(test, BN_value_one(), bits - 1)) + goto err; + + for (;;) { + for (;;) { /* find q */ + int seed_is_random; + + /* step 1 */ + if (!BN_GENCB_call(cb, 0, m++)) + goto err; + + if (!seed_len || !seed_in) { + if (RAND_bytes(seed, qsize) <= 0) + goto err; + seed_is_random = 1; + } else { + seed_is_random = 0; + seed_len = 0; /* use random seed if 'seed_in' turns out to + * be bad */ + } + memcpy(buf, seed, qsize); + memcpy(buf2, seed, qsize); + /* precompute "SEED + 1" for step 7: */ + for (i = qsize - 1; i >= 0; i--) { + buf[i]++; + if (buf[i] != 0) + break; + } + + /* step 2 */ + if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) + goto err; + if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) + goto err; + for (i = 0; i < qsize; i++) + md[i] ^= buf2[i]; + + /* step 3 */ + md[0] |= 0x80; + md[qsize - 1] |= 0x01; + if (!BN_bin2bn(md, qsize, q)) + goto err; + + /* step 4 */ + r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, + seed_is_random, cb); + if (r > 0) + break; + if (r != 0) + goto err; + + /* do a callback call */ + /* step 5 */ + } + + if (!BN_GENCB_call(cb, 2, 0)) + goto err; + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + + /* step 6 */ + counter = 0; + /* "offset = 2" */ + + n = (bits - 1) / 160; + + for (;;) { + if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) + goto err; + + /* step 7 */ + BN_zero(W); + /* now 'buf' contains "SEED + offset - 1" */ + for (k = 0; k <= n; k++) { + /* + * obtain "SEED + offset + k" by incrementing: + */ + for (i = qsize - 1; i >= 0; i--) { + buf[i]++; + if (buf[i] != 0) + break; + } + + if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) + goto err; + + /* step 8 */ + if (!BN_bin2bn(md, qsize, r0)) + goto err; + if (!BN_lshift(r0, r0, (qsize << 3) * k)) + goto err; + if (!BN_add(W, W, r0)) + goto err; + } + + /* more of step 8 */ + if (!BN_mask_bits(W, bits - 1)) + goto err; + if (!BN_copy(X, W)) + goto err; + if (!BN_add(X, X, test)) + goto err; + + /* step 9 */ + if (!BN_lshift1(r0, q)) + goto err; + if (!BN_mod(c, X, r0, ctx)) + goto err; + if (!BN_sub(r0, c, BN_value_one())) + goto err; + if (!BN_sub(p, X, r0)) + goto err; + + /* step 10 */ + if (BN_cmp(p, test) >= 0) { + /* step 11 */ + r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); + if (r > 0) + goto end; /* found it */ + if (r != 0) + goto err; + } + + /* step 13 */ + counter++; + /* "offset = offset + n + 1" */ + + /* step 14 */ + if (counter >= 4096) + break; + } + } + end: + if (!BN_GENCB_call(cb, 2, 1)) + goto err; + + /* We now need to generate g */ + /* Set r0=(p-1)/q */ + if (!BN_sub(test, p, BN_value_one())) + goto err; + if (!BN_div(r0, NULL, test, q, ctx)) + goto err; + + if (!BN_set_word(test, h)) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) + goto err; + + for (;;) { + /* g=test^r0%p */ + if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) + goto err; + if (!BN_is_one(g)) + break; + if (!BN_add(test, test, BN_value_one())) + goto err; + h++; + } + + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + + ok = 1; + err: + if (ok) { + if (ret->p) + BN_free(ret->p); + if (ret->q) + BN_free(ret->q); + if (ret->g) + BN_free(ret->g); + ret->p = BN_dup(p); + ret->q = BN_dup(q); + ret->g = BN_dup(g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { + ok = 0; + goto err; + } + if (counter_ret != NULL) + *counter_ret = counter; + if (h_ret != NULL) + *h_ret = h; + if (seed_out) + memcpy(seed_out, seed, qsize); + } + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (mont != NULL) + BN_MONT_CTX_free(mont); + return ok; +} + +# ifdef OPENSSL_FIPS +# undef fips_dsa_builtin_paramgen2 +extern int fips_dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, + const EVP_MD *evpmd, + const unsigned char *seed_in, + size_t seed_len, int idx, + unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); +# endif + +/* + * This is a parameter generation algorithm for the DSA2 algorithm as + * described in FIPS 186-3. + */ + +int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, + const EVP_MD *evpmd, const unsigned char *seed_in, + size_t seed_len, int idx, unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb) +{ + int ok = -1; + unsigned char *seed = NULL, *seed_tmp = NULL; + unsigned char md[EVP_MAX_MD_SIZE]; + int mdsize; + BIGNUM *r0, *W, *X, *c, *test; + BIGNUM *g = NULL, *q = NULL, *p = NULL; + BN_MONT_CTX *mont = NULL; + int i, k, n = 0, m = 0, qsize = N >> 3; + int counter = 0; + int r = 0; + BN_CTX *ctx = NULL; + EVP_MD_CTX mctx; + unsigned int h = 2; + +# ifdef OPENSSL_FIPS + + if (FIPS_mode()) + return fips_dsa_builtin_paramgen2(ret, L, N, evpmd, + seed_in, seed_len, idx, + seed_out, counter_ret, h_ret, cb); +# endif + + EVP_MD_CTX_init(&mctx); + + /* make sure L > N, otherwise we'll get trapped in an infinite loop */ + if (L <= N) { + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); + goto err; + } + + if (evpmd == NULL) { + if (N == 160) + evpmd = EVP_sha1(); + else if (N == 224) + evpmd = EVP_sha224(); + else + evpmd = EVP_sha256(); + } + + mdsize = EVP_MD_size(evpmd); + /* If unverificable g generation only don't need seed */ + if (!ret->p || !ret->q || idx >= 0) { + if (seed_len == 0) + seed_len = mdsize; + + seed = OPENSSL_malloc(seed_len); + + if (seed_out) + seed_tmp = seed_out; + else + seed_tmp = OPENSSL_malloc(seed_len); + + if (!seed || !seed_tmp) + goto err; + + if (seed_in) + memcpy(seed, seed_in, seed_len); + + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + g = BN_CTX_get(ctx); + W = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + c = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + + /* if p, q already supplied generate g only */ + if (ret->p && ret->q) { + p = ret->p; + q = ret->q; + if (idx >= 0) + memcpy(seed_tmp, seed, seed_len); + goto g_only; + } else { + p = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + if (q == NULL) + goto err; + } + + if (!BN_lshift(test, BN_value_one(), L - 1)) + goto err; + for (;;) { + for (;;) { /* find q */ + unsigned char *pmd; + /* step 1 */ + if (!BN_GENCB_call(cb, 0, m++)) + goto err; + + if (!seed_in) { + if (RAND_bytes(seed, seed_len) <= 0) + goto err; + } + /* step 2 */ + if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL)) + goto err; + /* Take least significant bits of md */ + if (mdsize > qsize) + pmd = md + mdsize - qsize; + else + pmd = md; + + if (mdsize < qsize) + memset(md + mdsize, 0, qsize - mdsize); + + /* step 3 */ + pmd[0] |= 0x80; + pmd[qsize - 1] |= 0x01; + if (!BN_bin2bn(pmd, qsize, q)) + goto err; + + /* step 4 */ + r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, + seed_in ? 1 : 0, cb); + if (r > 0) + break; + if (r != 0) + goto err; + /* Provided seed didn't produce a prime: error */ + if (seed_in) { + ok = 0; + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME); + goto err; + } + + /* do a callback call */ + /* step 5 */ + } + /* Copy seed to seed_out before we mess with it */ + if (seed_out) + memcpy(seed_out, seed, seed_len); + + if (!BN_GENCB_call(cb, 2, 0)) + goto err; + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + + /* step 6 */ + counter = 0; + /* "offset = 1" */ + + n = (L - 1) / (mdsize << 3); + + for (;;) { + if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) + goto err; + + /* step 7 */ + BN_zero(W); + /* now 'buf' contains "SEED + offset - 1" */ + for (k = 0; k <= n; k++) { + /* + * obtain "SEED + offset + k" by incrementing: + */ + for (i = seed_len - 1; i >= 0; i--) { + seed[i]++; + if (seed[i] != 0) + break; + } + + if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL)) + goto err; + + /* step 8 */ + if (!BN_bin2bn(md, mdsize, r0)) + goto err; + if (!BN_lshift(r0, r0, (mdsize << 3) * k)) + goto err; + if (!BN_add(W, W, r0)) + goto err; + } + + /* more of step 8 */ + if (!BN_mask_bits(W, L - 1)) + goto err; + if (!BN_copy(X, W)) + goto err; + if (!BN_add(X, X, test)) + goto err; + + /* step 9 */ + if (!BN_lshift1(r0, q)) + goto err; + if (!BN_mod(c, X, r0, ctx)) + goto err; + if (!BN_sub(r0, c, BN_value_one())) + goto err; + if (!BN_sub(p, X, r0)) + goto err; + + /* step 10 */ + if (BN_cmp(p, test) >= 0) { + /* step 11 */ + r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); + if (r > 0) + goto end; /* found it */ + if (r != 0) + goto err; + } + + /* step 13 */ + counter++; + /* "offset = offset + n + 1" */ + + /* step 14 */ + if (counter >= (int)(4 * L)) + break; + } + if (seed_in) { + ok = 0; + DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); + goto err; + } + } + end: + if (!BN_GENCB_call(cb, 2, 1)) + goto err; + + g_only: + + /* We now need to generate g */ + /* Set r0=(p-1)/q */ + if (!BN_sub(test, p, BN_value_one())) + goto err; + if (!BN_div(r0, NULL, test, q, ctx)) + goto err; + + if (idx < 0) { + if (!BN_set_word(test, h)) + goto err; + } else + h = 1; + if (!BN_MONT_CTX_set(mont, p, ctx)) + goto err; + + for (;;) { + static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e }; + if (idx >= 0) { + md[0] = idx & 0xff; + md[1] = (h >> 8) & 0xff; + md[2] = h & 0xff; + if (!EVP_DigestInit_ex(&mctx, evpmd, NULL)) + goto err; + if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len)) + goto err; + if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen))) + goto err; + if (!EVP_DigestUpdate(&mctx, md, 3)) + goto err; + if (!EVP_DigestFinal_ex(&mctx, md, NULL)) + goto err; + if (!BN_bin2bn(md, mdsize, test)) + goto err; + } + /* g=test^r0%p */ + if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) + goto err; + if (!BN_is_one(g)) + break; + if (idx < 0 && !BN_add(test, test, BN_value_one())) + goto err; + h++; + if (idx >= 0 && h > 0xffff) + goto err; + } + + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + + ok = 1; + err: + if (ok == 1) { + if (p != ret->p) { + if (ret->p) + BN_free(ret->p); + ret->p = BN_dup(p); + } + if (q != ret->q) { + if (ret->q) + BN_free(ret->q); + ret->q = BN_dup(q); + } + if (ret->g) + BN_free(ret->g); + ret->g = BN_dup(g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { + ok = -1; + goto err; + } + if (counter_ret != NULL) + *counter_ret = counter; + if (h_ret != NULL) + *h_ret = h; + } + if (seed) + OPENSSL_free(seed); + if (seed_out != seed_tmp) + OPENSSL_free(seed_tmp); + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (mont != NULL) + BN_MONT_CTX_free(mont); + EVP_MD_CTX_cleanup(&mctx); + return ok; +} + +int dsa_paramgen_check_g(DSA *dsa) +{ + BN_CTX *ctx; + BIGNUM *tmp; + BN_MONT_CTX *mont = NULL; + int rv = -1; + ctx = BN_CTX_new(); + if (!ctx) + return -1; + BN_CTX_start(ctx); + if (BN_cmp(dsa->g, BN_value_one()) <= 0) + return 0; + if (BN_cmp(dsa->g, dsa->p) >= 0) + return 0; + tmp = BN_CTX_get(ctx); + if (!tmp) + goto err; + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, dsa->p, ctx)) + goto err; + /* Work out g^q mod p */ + if (!BN_mod_exp_mont(tmp, dsa->g, dsa->q, dsa->p, ctx, mont)) + goto err; + if (!BN_cmp(tmp, BN_value_one())) + rv = 1; + else + rv = 0; + err: + BN_CTX_end(ctx); + if (mont) + BN_MONT_CTX_free(mont); + BN_CTX_free(ctx); + return rv; + +} +#endif +/* crypto/dsa/dsa_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +#ifndef OPENSSL_NO_SHA +# include "bn.h" +# include "dsa.h" +# include "rand.h" + +# ifdef OPENSSL_FIPS +# include +# endif + +static int dsa_builtin_keygen(DSA *dsa); + +int DSA_generate_key(DSA *dsa) +{ +# ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_GENERATE_KEY, DSA_R_NON_FIPS_DSA_METHOD); + return 0; + } +# endif + if (dsa->meth->dsa_keygen) + return dsa->meth->dsa_keygen(dsa); +# ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_dsa_generate_key(dsa); +# endif + return dsa_builtin_keygen(dsa); +} + +static int dsa_builtin_keygen(DSA *dsa) +{ + int ok = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if (dsa->priv_key == NULL) { + if ((priv_key = BN_new()) == NULL) + goto err; + } else + priv_key = dsa->priv_key; + + do + if (!BN_rand_range(priv_key, dsa->q)) + goto err; + while (BN_is_zero(priv_key)) ; + + if (dsa->pub_key == NULL) { + if ((pub_key = BN_new()) == NULL) + goto err; + } else + pub_key = dsa->pub_key; + + { + BIGNUM local_prk; + BIGNUM *prk; + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_init(&local_prk); + prk = &local_prk; + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + } else + prk = priv_key; + + if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) + goto err; + } + + dsa->priv_key = priv_key; + dsa->pub_key = pub_key; + ok = 1; + + err: + if ((pub_key != NULL) && (dsa->pub_key == NULL)) + BN_free(pub_key); + if ((priv_key != NULL) && (dsa->priv_key == NULL)) + BN_free(priv_key); + if (ctx != NULL) + BN_CTX_free(ctx); + return (ok); +} +#endif +/* crypto/dsa/dsa_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "dsa.h" +// #include "asn1.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +#ifdef OPENSSL_FIPS +# include +#endif + +const char DSA_version[] = "DSA" OPENSSL_VERSION_PTEXT; + +static const DSA_METHOD *default_DSA_method = NULL; + +void DSA_set_default_method(const DSA_METHOD *meth) +{ + default_DSA_method = meth; +} + +const DSA_METHOD *DSA_get_default_method(void) +{ + if (!default_DSA_method) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_dsa_openssl(); + else + return DSA_OpenSSL(); +#else + default_DSA_method = DSA_OpenSSL(); +#endif + } + return default_DSA_method; +} + +DSA *DSA_new(void) +{ + return DSA_new_method(NULL); +} + +int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const DSA_METHOD *mtmp; + mtmp = dsa->meth; + if (mtmp->finish) + mtmp->finish(dsa); +#ifndef OPENSSL_NO_ENGINE + if (dsa->engine) { + ENGINE_finish(dsa->engine); + dsa->engine = NULL; + } +#endif + dsa->meth = meth; + if (meth->init) + meth->init(dsa); + return 1; +} + +DSA *DSA_new_method(ENGINE *engine) +{ + DSA *ret; + + ret = (DSA *)OPENSSL_malloc(sizeof(DSA)); + if (ret == NULL) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->meth = DSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine) { + if (!ENGINE_init(engine)) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; + } else + ret->engine = ENGINE_get_default_DSA(); + if (ret->engine) { + ret->meth = ENGINE_get_DSA(ret->engine); + if (!ret->meth) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->pad = 0; + ret->version = 0; + ret->write_params = 1; + ret->p = NULL; + ret->q = NULL; + ret->g = NULL; + + ret->pub_key = NULL; + ret->priv_key = NULL; + + ret->kinv = NULL; + ret->r = NULL; + ret->method_mont_p = NULL; + + ret->references = 1; + ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } + + return (ret); +} + +void DSA_free(DSA *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DSA); +#ifdef REF_PRINT + REF_PRINT("DSA", r); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "DSA_free, bad reference count\n"); + abort(); + } +#endif + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); + + if (r->p != NULL) + BN_clear_free(r->p); + if (r->q != NULL) + BN_clear_free(r->q); + if (r->g != NULL) + BN_clear_free(r->g); + if (r->pub_key != NULL) + BN_clear_free(r->pub_key); + if (r->priv_key != NULL) + BN_clear_free(r->priv_key); + if (r->kinv != NULL) + BN_clear_free(r->kinv); + if (r->r != NULL) + BN_clear_free(r->r); + OPENSSL_free(r); +} + +int DSA_up_ref(DSA *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA); +#ifdef REF_PRINT + REF_PRINT("DSA", r); +#endif +#ifdef REF_CHECK + if (i < 2) { + fprintf(stderr, "DSA_up_ref, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); +} + +int DSA_size(const DSA *r) +{ + int ret, i; + ASN1_INTEGER bs; + unsigned char buf[4]; /* 4 bytes looks really small. However, + * i2d_ASN1_INTEGER() will not look beyond + * the first byte, as long as the second + * parameter is NULL. */ + + i = BN_num_bits(r->q); + bs.length = (i + 7) / 8; + bs.data = buf; + bs.type = V_ASN1_INTEGER; + /* If the top bit is set the asn1 encoding is 1 larger. */ + buf[0] = 0xff; + + i = i2d_ASN1_INTEGER(&bs, NULL); + i += i; /* r and s */ + ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); + return (ret); +} + +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp, + new_func, dup_func, free_func); +} + +int DSA_set_ex_data(DSA *d, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&d->ex_data, idx, arg)); +} + +void *DSA_get_ex_data(DSA *d, int idx) +{ + return (CRYPTO_get_ex_data(&d->ex_data, idx)); +} + +#ifndef OPENSSL_NO_DH +DH *DSA_dup_DH(const DSA *r) +{ + /* + * DSA has p, q, g, optional pub_key, optional priv_key. DH has p, + * optional length, g, optional pub_key, optional priv_key, optional q. + */ + + DH *ret = NULL; + + if (r == NULL) + goto err; + ret = DH_new(); + if (ret == NULL) + goto err; + if (r->p != NULL) + if ((ret->p = BN_dup(r->p)) == NULL) + goto err; + if (r->q != NULL) { + ret->length = BN_num_bits(r->q); + if ((ret->q = BN_dup(r->q)) == NULL) + goto err; + } + if (r->g != NULL) + if ((ret->g = BN_dup(r->g)) == NULL) + goto err; + if (r->pub_key != NULL) + if ((ret->pub_key = BN_dup(r->pub_key)) == NULL) + goto err; + if (r->priv_key != NULL) + if ((ret->priv_key = BN_dup(r->priv_key)) == NULL) + goto err; + + return ret; + + err: + if (ret != NULL) + DH_free(ret); + return NULL; +} +#endif +/* crypto/dsa/dsa_ossl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +#include "sha.h" +// #include "dsa.h" +// #include "rand.h" +// #include "asn1.h" + +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); +static int dsa_init(DSA *dsa); +static int dsa_finish(DSA *dsa); +static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, + BN_CTX *ctx); + +static DSA_METHOD openssl_dsa_meth = { + "OpenSSL DSA method", + dsa_do_sign, + dsa_sign_setup, + dsa_do_verify, + NULL, /* dsa_mod_exp, */ + NULL, /* dsa_bn_mod_exp, */ + dsa_init, + dsa_finish, + 0, + NULL, + NULL, + NULL +}; + +/*- + * These macro wrappers replace attempts to use the dsa_mod_exp() and + * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of + * having a the macro work as an expression by bundling an "err_instr". So; + * + * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx, + * dsa->method_mont_p)) goto err; + * + * can be replaced by; + * + * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx, + * dsa->method_mont_p); + */ + +#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \ + do { \ + int _tmp_res53; \ + if ((dsa)->meth->dsa_mod_exp) \ + _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \ + (a2), (p2), (m), (ctx), (in_mont)); \ + else \ + _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \ + (m), (ctx), (in_mont)); \ + if (!_tmp_res53) err_instr; \ + } while(0) +#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \ + do { \ + int _tmp_res53; \ + if ((dsa)->meth->bn_mod_exp) \ + _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \ + (m), (ctx), (m_ctx)); \ + else \ + _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \ + if (!_tmp_res53) err_instr; \ + } while(0) + +const DSA_METHOD *DSA_OpenSSL(void) +{ + return &openssl_dsa_meth; +} + +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + BIGNUM *kinv = NULL, *r = NULL, *s = NULL; + BIGNUM *m, *blind, *blindm, *tmp; + BN_CTX *ctx = NULL; + int reason = ERR_R_BN_LIB; + DSA_SIG *ret = NULL; + int noredo = 0; + + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + reason = DSA_R_MISSING_PARAMETERS; + goto err; + } + + s = BN_new(); + if (s == NULL) + goto err; + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + m = BN_CTX_get(ctx); + blind = BN_CTX_get(ctx); + blindm = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + redo: + if ((dsa->kinv == NULL) || (dsa->r == NULL)) { + if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) + goto err; + } else { + kinv = dsa->kinv; + dsa->kinv = NULL; + r = dsa->r; + dsa->r = NULL; + noredo = 1; + } + + if (dlen > BN_num_bytes(dsa->q)) + /* + * if the digest length is greater than the size of q use the + * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3, + * 4.2 + */ + dlen = BN_num_bytes(dsa->q); + if (BN_bin2bn(dgst, dlen, m) == NULL) + goto err; + + /* + * The normal signature calculation is: + * + * s := k^-1 * (m + r * priv_key) mod q + * + * We will blind this to protect against side channel attacks + * + * s := blind^-1 * k^-1 * (blind * m + blind * r * priv_key) mod q + */ + + /* Generate a blinding value */ + do { + if (!BN_rand(blind, BN_num_bits(dsa->q) - 1, -1, 0)) + goto err; + } while (BN_is_zero(blind)); + BN_set_flags(blind, BN_FLG_CONSTTIME); + BN_set_flags(blindm, BN_FLG_CONSTTIME); + BN_set_flags(tmp, BN_FLG_CONSTTIME); + + /* tmp := blind * priv_key * r mod q */ + if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->q, ctx)) + goto err; + if (!BN_mod_mul(tmp, tmp, r, dsa->q, ctx)) + goto err; + + /* blindm := blind * m mod q */ + if (!BN_mod_mul(blindm, blind, m, dsa->q, ctx)) + goto err; + + /* s : = (blind * priv_key * r) + (blind * m) mod q */ + if (!BN_mod_add_quick(s, tmp, blindm, dsa->q)) + goto err; + + /* s := s * k^-1 mod q */ + if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) + goto err; + + /* s:= s * blind^-1 mod q */ + if (BN_mod_inverse(blind, blind, dsa->q, ctx) == NULL) + goto err; + if (!BN_mod_mul(s, s, blind, dsa->q, ctx)) + goto err; + + /* + * Redo if r or s is zero as required by FIPS 186-3: this is very + * unlikely. + */ + if (BN_is_zero(r) || BN_is_zero(s)) { + if (noredo) { + reason = DSA_R_NEED_NEW_SETUP_VALUES; + goto err; + } + goto redo; + } + ret = DSA_SIG_new(); + if (ret == NULL) + goto err; + ret->r = r; + ret->s = s; + + err: + if (ret == NULL) { + DSAerr(DSA_F_DSA_DO_SIGN, reason); + BN_free(r); + BN_free(s); + } + BN_CTX_free(ctx); + BN_clear_free(kinv); + return ret; +} + +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + BN_CTX *ctx; + BIGNUM k, kq, *K, *kinv = NULL, *r = NULL; + BIGNUM l, m; + int ret = 0; + int q_bits; + + if (!dsa->p || !dsa->q || !dsa->g) { + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); + return 0; + } + + BN_init(&k); + BN_init(&kq); + BN_init(&l); + BN_init(&m); + + if (ctx_in == NULL) { + if ((ctx = BN_CTX_new()) == NULL) + goto err; + } else + ctx = ctx_in; + + if ((r = BN_new()) == NULL) + goto err; + + /* Preallocate space */ + q_bits = BN_num_bits(dsa->q) + sizeof(dsa->q->d[0]) * 16; + if (!BN_set_bit(&k, q_bits) + || !BN_set_bit(&l, q_bits) + || !BN_set_bit(&m, q_bits)) + goto err; + + /* Get random k */ + do + if (!BN_rand_range(&k, dsa->q)) + goto err; + while (BN_is_zero(&k)); + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_set_flags(&k, BN_FLG_CONSTTIME); + BN_set_flags(&l, BN_FLG_CONSTTIME); + } + + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx)) + goto err; + } + + /* Compute r = (g^k mod p) mod q */ + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + /* + * We do not want timing information to leak the length of k, so we + * compute G^k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the modulus. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. + */ + if (!BN_add(&l, &k, dsa->q) + || !BN_add(&m, &l, dsa->q) + || !BN_copy(&kq, BN_num_bits(&l) > q_bits ? &l : &m)) + goto err; + + BN_set_flags(&kq, BN_FLG_CONSTTIME); + + K = &kq; + } else { + K = &k; + } + + DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, + dsa->method_mont_p); + if (!BN_mod(r, r, dsa->q, ctx)) + goto err; + + /* Compute part of 's = inv(k) (m + xr) mod q' */ + if ((kinv = dsa_mod_inverse_fermat(&k, dsa->q, ctx)) == NULL) + goto err; + + if (*kinvp != NULL) + BN_clear_free(*kinvp); + *kinvp = kinv; + kinv = NULL; + if (*rp != NULL) + BN_clear_free(*rp); + *rp = r; + ret = 1; + err: + if (!ret) { + DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB); + if (r != NULL) + BN_clear_free(r); + } + if (ctx_in == NULL) + BN_CTX_free(ctx); + BN_clear_free(&k); + BN_clear_free(&kq); + BN_clear_free(&l); + BN_clear_free(&m); + return ret; +} + +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa) +{ + BN_CTX *ctx; + BIGNUM u1, u2, t1; + BN_MONT_CTX *mont = NULL; + int ret = -1, i; + if (!dsa->p || !dsa->q || !dsa->g) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS); + return -1; + } + + i = BN_num_bits(dsa->q); + /* fips 186-3 allows only different sizes for q */ + if (i != 160 && i != 224 && i != 256) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE); + return -1; + } + + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE); + return -1; + } + BN_init(&u1); + BN_init(&u2); + BN_init(&t1); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, dsa->q) >= 0) { + ret = 0; + goto err; + } + if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || + BN_ucmp(sig->s, dsa->q) >= 0) { + ret = 0; + goto err; + } + + /* + * Calculate W = inv(S) mod Q save W in u2 + */ + if ((BN_mod_inverse(&u2, sig->s, dsa->q, ctx)) == NULL) + goto err; + + /* save M in u1 */ + if (dgst_len > (i >> 3)) + /* + * if the digest length is greater than the size of q use the + * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3, + * 4.2 + */ + dgst_len = (i >> 3); + if (BN_bin2bn(dgst, dgst_len, &u1) == NULL) + goto err; + + /* u1 = M * w mod q */ + if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) + goto err; + + /* u2 = r * w mod q */ + if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) + goto err; + + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx); + if (!mont) + goto err; + } + + DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, + ctx, mont); + /* BN_copy(&u1,&t1); */ + /* let u1 = u1 mod q */ + if (!BN_mod(&u1, &t1, dsa->q, ctx)) + goto err; + + /* + * V is now in u1. If the signature is correct, it will be equal to R. + */ + ret = (BN_ucmp(&u1, sig->r) == 0); + + err: + if (ret < 0) + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB); + if (ctx != NULL) + BN_CTX_free(ctx); + BN_free(&u1); + BN_free(&u2); + BN_free(&t1); + return (ret); +} + +static int dsa_init(DSA *dsa) +{ + dsa->flags |= DSA_FLAG_CACHE_MONT_P; + return (1); +} + +static int dsa_finish(DSA *dsa) +{ + if (dsa->method_mont_p) + BN_MONT_CTX_free(dsa->method_mont_p); + return (1); +} + +/* + * Compute the inverse of k modulo q. + * Since q is prime, Fermat's Little Theorem applies, which reduces this to + * mod-exp operation. Both the exponent and modulus are public information + * so a mod-exp that doesn't leak the base is sufficient. A newly allocated + * BIGNUM is returned which the caller must free. + */ +static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, + BN_CTX *ctx) +{ + BIGNUM *res = NULL; + BIGNUM *r, e; + + if ((r = BN_new()) == NULL) + return NULL; + + BN_init(&e); + + if (BN_set_word(r, 2) + && BN_sub(&e, q, r) + && BN_mod_exp_mont(r, k, &e, q, ctx, NULL)) + res = r; + else + BN_free(r); + BN_free(&e); + return res; +} +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" +#include "evp.h" +// #include "bn.h" +#include "evp_locl.h" +#include "dsa_locl.h" + +/* DSA pkey context structure */ + +typedef struct { + /* Parameter gen parameters */ + int nbits; /* size of p in bits (default: 1024) */ + int qbits; /* size of q in bits (default: 160) */ + const EVP_MD *pmd; /* MD for parameter generation */ + /* Keygen callback info */ + int gentmp[2]; + /* message digest */ + const EVP_MD *md; /* MD for the signature */ +} DSA_PKEY_CTX; + +static int pkey_dsa_init(EVP_PKEY_CTX *ctx) +{ + DSA_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX)); + if (!dctx) + return 0; + dctx->nbits = 1024; + dctx->qbits = 160; + dctx->pmd = NULL; + dctx->md = NULL; + + ctx->data = dctx; + ctx->keygen_info = dctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + DSA_PKEY_CTX *dctx, *sctx; + if (!pkey_dsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + dctx->qbits = sctx->qbits; + dctx->pmd = sctx->pmd; + dctx->md = sctx->md; + return 1; +} + +static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) +{ + DSA_PKEY_CTX *dctx = ctx->data; + if (dctx) + OPENSSL_free(dctx); +} + +static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbslen) +{ + int ret, type; + unsigned int sltmp; + DSA_PKEY_CTX *dctx = ctx->data; + DSA *dsa = ctx->pkey->pkey.dsa; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa); + + if (ret <= 0) + return ret; + *siglen = sltmp; + return 1; +} + +static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret, type; + DSA_PKEY_CTX *dctx = ctx->data; + DSA *dsa = ctx->pkey->pkey.dsa; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa); + + return ret; +} + +static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + DSA_PKEY_CTX *dctx = ctx->data; + switch (type) { + case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: + if (p1 < 256) + return -2; + dctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: + if (p1 != 160 && p1 != 224 && p1 && p1 != 256) + return -2; + dctx->qbits = p1; + return 1; + + case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256) { + DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->pmd = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_dsa && + EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { + DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = dctx->md; + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + DSAerr(DSA_F_PKEY_DSA_CTRL, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + default: + return -2; + + } +} + +static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!strcmp(type, "dsa_paramgen_bits")) { + int nbits; + nbits = atoi(value); + return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); + } + if (!strcmp(type, "dsa_paramgen_q_bits")) { + int qbits = atoi(value); + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, + NULL); + } + if (strcmp(type, "dsa_paramgen_md") == 0) { + const EVP_MD *md = EVP_get_digestbyname(value); + + if (md == NULL) { + DSAerr(DSA_F_PKEY_DSA_CTRL_STR, DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, + (void *)md); + } + return -2; +} + +static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DSA *dsa = NULL; + DSA_PKEY_CTX *dctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (ctx->pkey_gencb) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else + pcb = NULL; + dsa = DSA_new(); + if (!dsa) + return 0; + ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, + NULL, 0, NULL, NULL, NULL, pcb); + if (ret) + EVP_PKEY_assign_DSA(pkey, dsa); + else + DSA_free(dsa); + return ret; +} + +static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DSA *dsa = NULL; + if (ctx->pkey == NULL) { + DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); + return 0; + } + dsa = DSA_new(); + if (!dsa) + return 0; + EVP_PKEY_assign_DSA(pkey, dsa); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return DSA_generate_key(pkey->pkey.dsa); +} + +const EVP_PKEY_METHOD dsa_pkey_meth = { + EVP_PKEY_DSA, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_dsa_init, + pkey_dsa_copy, + pkey_dsa_cleanup, + + 0, + pkey_dsa_paramgen, + + 0, + pkey_dsa_keygen, + + 0, + pkey_dsa_sign, + + 0, + pkey_dsa_verify, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_dsa_ctrl, + pkey_dsa_ctrl_str +}; +/* crypto/dsa/dsa_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "dsa.h" + +#ifndef OPENSSL_NO_FP_API +int DSA_print_fp(FILE *fp, const DSA *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DSA_print(b, x, off); + BIO_free(b); + return (ret); +} + +int DSAparams_print_fp(FILE *fp, const DSA *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DSAparams_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int DSA_print(BIO *bp, const DSA *x, int off) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; +} + +int DSAparams_print(BIO *bp, const DSA *x) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) + return 0; + ret = EVP_PKEY_print_params(bp, pk, 4, NULL); + EVP_PKEY_free(pk); + return ret; +} +/* crypto/dsa/dsa_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +// #include "cryptlib.h" +// #include "dsa.h" +// #include "rand.h" +// #include "bn.h" + +DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD); + return NULL; + } +#endif + return dsa->meth->dsa_do_sign(dgst, dlen, dsa); +} + +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD); + return 0; + } +#endif + return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); +} + +DSA_SIG *DSA_SIG_new(void) +{ + DSA_SIG *sig; + sig = OPENSSL_malloc(sizeof(DSA_SIG)); + if (!sig) + return NULL; + sig->r = NULL; + sig->s = NULL; + return sig; +} + +void DSA_SIG_free(DSA_SIG *sig) +{ + if (sig) { + if (sig->r) + BN_free(sig->r); + if (sig->s) + BN_free(sig->s); + OPENSSL_free(sig); + } +} +/* crypto/dsa/dsa_vrf.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +// #include "cryptlib.h" +// #include "dsa.h" + +int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, + DSA *dsa) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD); + return -1; + } +#endif + return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa); +} diff --git a/Sources/COpenSSL/dsa_locl.h b/Sources/COpenSSL/dsa_locl.h new file mode 100644 index 00000000..1594ee40 --- /dev/null +++ b/Sources/COpenSSL/dsa_locl.h @@ -0,0 +1,69 @@ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "dsa.h" + +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, + size_t seed_len, unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + +int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, + const EVP_MD *evpmd, const unsigned char *seed_in, + size_t seed_len, int idx, unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + +int dsa_paramgen_check_g(DSA *dsa); diff --git a/Sources/COpenSSL/dso.h b/Sources/COpenSSL/dso.h new file mode 100644 index 00000000..5072f212 --- /dev/null +++ b/Sources/COpenSSL/dso.h @@ -0,0 +1,451 @@ +/* dso.h */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DSO_H +# define HEADER_DSO_H + +# include "crypto.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* These values are used as commands to DSO_ctrl() */ +# define DSO_CTRL_GET_FLAGS 1 +# define DSO_CTRL_SET_FLAGS 2 +# define DSO_CTRL_OR_FLAGS 3 + +/* + * By default, DSO_load() will translate the provided filename into a form + * typical for the platform (more specifically the DSO_METHOD) using the + * dso_name_converter function of the method. Eg. win32 will transform "blah" + * into "blah.dll", and dlfcn will transform it into "libblah.so". The + * behaviour can be overriden by setting the name_converter callback in the + * DSO object (using DSO_set_name_converter()). This callback could even + * utilise the DSO_METHOD's converter too if it only wants to override + * behaviour for one or two possible DSO methods. However, the following flag + * can be set in a DSO to prevent *any* native name-translation at all - eg. + * if the caller has prompted the user for a path to a driver library so the + * filename should be interpreted as-is. + */ +# define DSO_FLAG_NO_NAME_TRANSLATION 0x01 +/* + * An extra flag to give if only the extension should be added as + * translation. This is obviously only of importance on Unix and other + * operating systems where the translation also may prefix the name with + * something, like 'lib', and ignored everywhere else. This flag is also + * ignored if DSO_FLAG_NO_NAME_TRANSLATION is used at the same time. + */ +# define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY 0x02 + +/* + * The following flag controls the translation of symbol names to upper case. + * This is currently only being implemented for OpenVMS. + */ +# define DSO_FLAG_UPCASE_SYMBOL 0x10 + +/* + * This flag loads the library with public symbols. Meaning: The exported + * symbols of this library are public to all libraries loaded after this + * library. At the moment only implemented in unix. + */ +# define DSO_FLAG_GLOBAL_SYMBOLS 0x20 + +typedef void (*DSO_FUNC_TYPE) (void); + +typedef struct dso_st DSO; + +/* + * The function prototype used for method functions (or caller-provided + * callbacks) that transform filenames. They are passed a DSO structure + * pointer (or NULL if they are to be used independantly of a DSO object) and + * a filename to transform. They should either return NULL (if there is an + * error condition) or a newly allocated string containing the transformed + * form that the caller will need to free with OPENSSL_free() when done. + */ +typedef char *(*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *); +/* + * The function prototype used for method functions (or caller-provided + * callbacks) that merge two file specifications. They are passed a DSO + * structure pointer (or NULL if they are to be used independantly of a DSO + * object) and two file specifications to merge. They should either return + * NULL (if there is an error condition) or a newly allocated string + * containing the result of merging that the caller will need to free with + * OPENSSL_free() when done. Here, merging means that bits and pieces are + * taken from each of the file specifications and added together in whatever + * fashion that is sensible for the DSO method in question. The only rule + * that really applies is that if the two specification contain pieces of the + * same type, the copy from the first string takes priority. One could see + * it as the first specification is the one given by the user and the second + * being a bunch of defaults to add on if they're missing in the first. + */ +typedef char *(*DSO_MERGER_FUNC)(DSO *, const char *, const char *); + +typedef struct dso_meth_st { + const char *name; + /* + * Loads a shared library, NB: new DSO_METHODs must ensure that a + * successful load populates the loaded_filename field, and likewise a + * successful unload OPENSSL_frees and NULLs it out. + */ + int (*dso_load) (DSO *dso); + /* Unloads a shared library */ + int (*dso_unload) (DSO *dso); + /* Binds a variable */ + void *(*dso_bind_var) (DSO *dso, const char *symname); + /* + * Binds a function - assumes a return type of DSO_FUNC_TYPE. This should + * be cast to the real function prototype by the caller. Platforms that + * don't have compatible representations for different prototypes (this + * is possible within ANSI C) are highly unlikely to have shared + * libraries at all, let alone a DSO_METHOD implemented for them. + */ + DSO_FUNC_TYPE (*dso_bind_func) (DSO *dso, const char *symname); +/* I don't think this would actually be used in any circumstances. */ +# if 0 + /* Unbinds a variable */ + int (*dso_unbind_var) (DSO *dso, char *symname, void *symptr); + /* Unbinds a function */ + int (*dso_unbind_func) (DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +# endif + /* + * The generic (yuck) "ctrl()" function. NB: Negative return values + * (rather than zero) indicate errors. + */ + long (*dso_ctrl) (DSO *dso, int cmd, long larg, void *parg); + /* + * The default DSO_METHOD-specific function for converting filenames to a + * canonical native form. + */ + DSO_NAME_CONVERTER_FUNC dso_name_converter; + /* + * The default DSO_METHOD-specific function for converting filenames to a + * canonical native form. + */ + DSO_MERGER_FUNC dso_merger; + /* [De]Initialisation handlers. */ + int (*init) (DSO *dso); + int (*finish) (DSO *dso); + /* Return pathname of the module containing location */ + int (*pathbyaddr) (void *addr, char *path, int sz); + /* Perform global symbol lookup, i.e. among *all* modules */ + void *(*globallookup) (const char *symname); +} DSO_METHOD; + +/**********************************************************************/ +/* The low-level handle type used to refer to a loaded shared library */ + +struct dso_st { + DSO_METHOD *meth; + /* + * Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use + * anything but will need to cache the filename for use in the dso_bind + * handler. All in all, let each method control its own destiny. + * "Handles" and such go in a STACK. + */ + STACK_OF(void) *meth_data; + int references; + int flags; + /* + * For use by applications etc ... use this for your bits'n'pieces, don't + * touch meth_data! + */ + CRYPTO_EX_DATA ex_data; + /* + * If this callback function pointer is set to non-NULL, then it will be + * used in DSO_load() in place of meth->dso_name_converter. NB: This + * should normally set using DSO_set_name_converter(). + */ + DSO_NAME_CONVERTER_FUNC name_converter; + /* + * If this callback function pointer is set to non-NULL, then it will be + * used in DSO_load() in place of meth->dso_merger. NB: This should + * normally set using DSO_set_merger(). + */ + DSO_MERGER_FUNC merger; + /* + * This is populated with (a copy of) the platform-independant filename + * used for this DSO. + */ + char *filename; + /* + * This is populated with (a copy of) the translated filename by which + * the DSO was actually loaded. It is NULL iff the DSO is not currently + * loaded. NB: This is here because the filename translation process may + * involve a callback being invoked more than once not only to convert to + * a platform-specific form, but also to try different filenames in the + * process of trying to perform a load. As such, this variable can be + * used to indicate (a) whether this DSO structure corresponds to a + * loaded library or not, and (b) the filename with which it was actually + * loaded. + */ + char *loaded_filename; +}; + +DSO *DSO_new(void); +DSO *DSO_new_method(DSO_METHOD *method); +int DSO_free(DSO *dso); +int DSO_flags(DSO *dso); +int DSO_up_ref(DSO *dso); +long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg); + +/* + * This function sets the DSO's name_converter callback. If it is non-NULL, + * then it will be used instead of the associated DSO_METHOD's function. If + * oldcb is non-NULL then it is set to the function pointer value being + * replaced. Return value is non-zero for success. + */ +int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb, + DSO_NAME_CONVERTER_FUNC *oldcb); +/* + * These functions can be used to get/set the platform-independant filename + * used for a DSO. NB: set will fail if the DSO is already loaded. + */ +const char *DSO_get_filename(DSO *dso); +int DSO_set_filename(DSO *dso, const char *filename); +/* + * This function will invoke the DSO's name_converter callback to translate a + * filename, or if the callback isn't set it will instead use the DSO_METHOD's + * converter. If "filename" is NULL, the "filename" in the DSO itself will be + * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is + * simply duplicated. NB: This function is usually called from within a + * DSO_METHOD during the processing of a DSO_load() call, and is exposed so + * that caller-created DSO_METHODs can do the same thing. A non-NULL return + * value will need to be OPENSSL_free()'d. + */ +char *DSO_convert_filename(DSO *dso, const char *filename); +/* + * This function will invoke the DSO's merger callback to merge two file + * specifications, or if the callback isn't set it will instead use the + * DSO_METHOD's merger. A non-NULL return value will need to be + * OPENSSL_free()'d. + */ +char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2); +/* + * If the DSO is currently loaded, this returns the filename that it was + * loaded under, otherwise it returns NULL. So it is also useful as a test as + * to whether the DSO is currently loaded. NB: This will not necessarily + * return the same value as DSO_convert_filename(dso, dso->filename), because + * the DSO_METHOD's load function may have tried a variety of filenames (with + * and/or without the aid of the converters) before settling on the one it + * actually loaded. + */ +const char *DSO_get_loaded_filename(DSO *dso); + +void DSO_set_default_method(DSO_METHOD *meth); +DSO_METHOD *DSO_get_default_method(void); +DSO_METHOD *DSO_get_method(DSO *dso); +DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth); + +/* + * The all-singing all-dancing load function, you normally pass NULL for the + * first and third parameters. Use DSO_up and DSO_free for subsequent + * reference count handling. Any flags passed in will be set in the + * constructed DSO after its init() function but before the load operation. + * If 'dso' is non-NULL, 'flags' is ignored. + */ +DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags); + +/* This function binds to a variable inside a shared library. */ +void *DSO_bind_var(DSO *dso, const char *symname); + +/* This function binds to a function inside a shared library. */ +DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname); + +/* + * This method is the default, but will beg, borrow, or steal whatever method + * should be the default on any particular platform (including + * DSO_METH_null() if necessary). + */ +DSO_METHOD *DSO_METHOD_openssl(void); + +/* + * This method is defined for all platforms - if a platform has no DSO + * support then this will be the only method! + */ +DSO_METHOD *DSO_METHOD_null(void); + +/* + * If DSO_DLFCN is defined, the standard dlfcn.h-style functions (dlopen, + * dlclose, dlsym, etc) will be used and incorporated into this method. If + * not, this method will return NULL. + */ +DSO_METHOD *DSO_METHOD_dlfcn(void); + +/* + * If DSO_DL is defined, the standard dl.h-style functions (shl_load, + * shl_unload, shl_findsym, etc) will be used and incorporated into this + * method. If not, this method will return NULL. + */ +DSO_METHOD *DSO_METHOD_dl(void); + +/* If WIN32 is defined, use DLLs. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_win32(void); + +/* If VMS is defined, use shared images. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_vms(void); + +/* + * This function writes null-terminated pathname of DSO module containing + * 'addr' into 'sz' large caller-provided 'path' and returns the number of + * characters [including trailing zero] written to it. If 'sz' is 0 or + * negative, 'path' is ignored and required amount of charachers [including + * trailing zero] to accomodate pathname is returned. If 'addr' is NULL, then + * pathname of cryptolib itself is returned. Negative or zero return value + * denotes error. + */ +int DSO_pathbyaddr(void *addr, char *path, int sz); + +/* + * This function should be used with caution! It looks up symbols in *all* + * loaded modules and if module gets unloaded by somebody else attempt to + * dereference the pointer is doomed to have fatal consequences. Primary + * usage for this function is to probe *core* system functionality, e.g. + * check if getnameinfo(3) is available at run-time without bothering about + * OS-specific details such as libc.so.versioning or where does it actually + * reside: in libc itself or libsocket. + */ +void *DSO_global_lookup(const char *name); + +/* If BeOS is defined, use shared images. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_beos(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSO_strings(void); + +/* Error codes for the DSO functions. */ + +/* Function codes. */ +# define DSO_F_BEOS_BIND_FUNC 144 +# define DSO_F_BEOS_BIND_VAR 145 +# define DSO_F_BEOS_LOAD 146 +# define DSO_F_BEOS_NAME_CONVERTER 147 +# define DSO_F_BEOS_UNLOAD 148 +# define DSO_F_DLFCN_BIND_FUNC 100 +# define DSO_F_DLFCN_BIND_VAR 101 +# define DSO_F_DLFCN_LOAD 102 +# define DSO_F_DLFCN_MERGER 130 +# define DSO_F_DLFCN_NAME_CONVERTER 123 +# define DSO_F_DLFCN_UNLOAD 103 +# define DSO_F_DL_BIND_FUNC 104 +# define DSO_F_DL_BIND_VAR 105 +# define DSO_F_DL_LOAD 106 +# define DSO_F_DL_MERGER 131 +# define DSO_F_DL_NAME_CONVERTER 124 +# define DSO_F_DL_UNLOAD 107 +# define DSO_F_DSO_BIND_FUNC 108 +# define DSO_F_DSO_BIND_VAR 109 +# define DSO_F_DSO_CONVERT_FILENAME 126 +# define DSO_F_DSO_CTRL 110 +# define DSO_F_DSO_FREE 111 +# define DSO_F_DSO_GET_FILENAME 127 +# define DSO_F_DSO_GET_LOADED_FILENAME 128 +# define DSO_F_DSO_GLOBAL_LOOKUP 139 +# define DSO_F_DSO_LOAD 112 +# define DSO_F_DSO_MERGE 132 +# define DSO_F_DSO_NEW_METHOD 113 +# define DSO_F_DSO_PATHBYADDR 140 +# define DSO_F_DSO_SET_FILENAME 129 +# define DSO_F_DSO_SET_NAME_CONVERTER 122 +# define DSO_F_DSO_UP_REF 114 +# define DSO_F_GLOBAL_LOOKUP_FUNC 138 +# define DSO_F_PATHBYADDR 137 +# define DSO_F_VMS_BIND_SYM 115 +# define DSO_F_VMS_LOAD 116 +# define DSO_F_VMS_MERGER 133 +# define DSO_F_VMS_UNLOAD 117 +# define DSO_F_WIN32_BIND_FUNC 118 +# define DSO_F_WIN32_BIND_VAR 119 +# define DSO_F_WIN32_GLOBALLOOKUP 142 +# define DSO_F_WIN32_GLOBALLOOKUP_FUNC 143 +# define DSO_F_WIN32_JOINER 135 +# define DSO_F_WIN32_LOAD 120 +# define DSO_F_WIN32_MERGER 134 +# define DSO_F_WIN32_NAME_CONVERTER 125 +# define DSO_F_WIN32_PATHBYADDR 141 +# define DSO_F_WIN32_SPLITTER 136 +# define DSO_F_WIN32_UNLOAD 121 + +/* Reason codes. */ +# define DSO_R_CTRL_FAILED 100 +# define DSO_R_DSO_ALREADY_LOADED 110 +# define DSO_R_EMPTY_FILE_STRUCTURE 113 +# define DSO_R_FAILURE 114 +# define DSO_R_FILENAME_TOO_BIG 101 +# define DSO_R_FINISH_FAILED 102 +# define DSO_R_INCORRECT_FILE_SYNTAX 115 +# define DSO_R_LOAD_FAILED 103 +# define DSO_R_NAME_TRANSLATION_FAILED 109 +# define DSO_R_NO_FILENAME 111 +# define DSO_R_NO_FILE_SPECIFICATION 116 +# define DSO_R_NULL_HANDLE 104 +# define DSO_R_SET_FILENAME_FAILED 112 +# define DSO_R_STACK_ERROR 105 +# define DSO_R_SYM_FAILURE 106 +# define DSO_R_UNLOAD_FAILED 107 +# define DSO_R_UNSUPPORTED 108 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/dso_.c b/Sources/COpenSSL/dso_.c new file mode 100644 index 00000000..52445f45 --- /dev/null +++ b/Sources/COpenSSL/dso_.c @@ -0,0 +1,3214 @@ +/* dso_beos.c */ +/* + * Written by Marcin Konicki (ahwayakchih@neoni.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include "dso.h" + +#if !defined(OPENSSL_SYS_BEOS) +DSO_METHOD *DSO_METHOD_beos(void) +{ + return NULL; +} +#else + +# include + +static int beos_load(DSO *dso); +static int beos_unload(DSO *dso); +static void *beos_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname); +# if 0 +static int beos_unbind_var(DSO *dso, char *symname, void *symptr); +static int beos_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int beos_init(DSO *dso); +static int beos_finish(DSO *dso); +static long beos_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *beos_name_converter(DSO *dso, const char *filename); + +static DSO_METHOD dso_meth_beos = { + "OpenSSL 'beos' shared library method", + beos_load, + beos_unload, + beos_bind_var, + beos_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + beos_name_converter, + NULL, /* init */ + NULL /* finish */ +}; + +DSO_METHOD *DSO_METHOD_beos(void) +{ + return (&dso_meth_beos); +} + +/* + * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to + * the handle (image_id) returned from load_add_on(). + */ + +static int beos_load(DSO *dso) +{ + image_id id; + /* See applicable comments from dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + + if (filename == NULL) { + DSOerr(DSO_F_BEOS_LOAD, DSO_R_NO_FILENAME); + goto err; + } + id = load_add_on(filename); + if (id < 1) { + DSOerr(DSO_F_BEOS_LOAD, DSO_R_LOAD_FAILED); + ERR_add_error_data(3, "filename(", filename, ")"); + goto err; + } + if (!sk_push(dso->meth_data, (char *)id)) { + DSOerr(DSO_F_BEOS_LOAD, DSO_R_STACK_ERROR); + goto err; + } + /* Success */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup ! */ + if (filename != NULL) + OPENSSL_free(filename); + if (id > 0) + unload_add_on(id); + return (0); +} + +static int beos_unload(DSO *dso) +{ + image_id id; + if (dso == NULL) { + DSOerr(DSO_F_BEOS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_num(dso->meth_data) < 1) + return (1); + id = (image_id) sk_pop(dso->meth_data); + if (id < 1) { + DSOerr(DSO_F_BEOS_UNLOAD, DSO_R_NULL_HANDLE); + return (0); + } + if (unload_add_on(id) != B_OK) { + DSOerr(DSO_F_BEOS_UNLOAD, DSO_R_UNLOAD_FAILED); + /* + * We should push the value back onto the stack in case of a retry. + */ + sk_push(dso->meth_data, (char *)id); + return (0); + } + return (1); +} + +static void *beos_bind_var(DSO *dso, const char *symname) +{ + image_id id; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_BEOS_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_num(dso->meth_data) < 1) { + DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_STACK_ERROR); + return (NULL); + } + id = (image_id) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if (id < 1) { + DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_NULL_HANDLE); + return (NULL); + } + if (get_image_symbol(id, symname, B_SYMBOL_TYPE_DATA, &sym) != B_OK) { + DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_SYM_FAILURE); + ERR_add_error_data(3, "symname(", symname, ")"); + return (NULL); + } + return (sym); +} + +static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname) +{ + image_id id; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_BEOS_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_num(dso->meth_data) < 1) { + DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_STACK_ERROR); + return (NULL); + } + id = (image_id) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if (id < 1) { + DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_NULL_HANDLE); + return (NULL); + } + if (get_image_symbol(id, symname, B_SYMBOL_TYPE_TEXT, &sym) != B_OK) { + DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_add_error_data(3, "symname(", symname, ")"); + return (NULL); + } + return ((DSO_FUNC_TYPE)sym); +} + +/* This one is the same as the one in dlfcn */ +static char *beos_name_converter(DSO *dso, const char *filename) +{ + char *translated; + int len, rsize, transform; + + len = strlen(filename); + rsize = len + 1; + transform = (strstr(filename, "/") == NULL); + if (transform) { + /* We will convert this to "%s.so" or "lib%s.so" */ + rsize += 3; /* The length of ".so" */ + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + rsize += 3; /* The length of "lib" */ + } + translated = OPENSSL_malloc(rsize); + if (translated == NULL) { + DSOerr(DSO_F_BEOS_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + return (NULL); + } + if (transform) { + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + sprintf(translated, "lib%s.so", filename); + else + sprintf(translated, "%s.so", filename); + } else + sprintf(translated, "%s", filename); + return (translated); +} + +#endif +/* dso_dl.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "dso.h" + +#ifndef DSO_DL +DSO_METHOD *DSO_METHOD_dl(void) +{ + return NULL; +} +#else + +# include + +/* Part of the hack in "dl_load" ... */ +# define DSO_MAX_TRANSLATED_SIZE 256 + +static int dl_load(DSO *dso); +static int dl_unload(DSO *dso); +static void *dl_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname); +# if 0 +static int dl_unbind_var(DSO *dso, char *symname, void *symptr); +static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int dl_init(DSO *dso); +static int dl_finish(DSO *dso); +static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *dl_name_converter(DSO *dso, const char *filename); +static char *dl_merger(DSO *dso, const char *filespec1, + const char *filespec2); +static int dl_pathbyaddr(void *addr, char *path, int sz); +static void *dl_globallookup(const char *name); + +static DSO_METHOD dso_meth_dl = { + "OpenSSL 'dl' shared library method", + dl_load, + dl_unload, + dl_bind_var, + dl_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + dl_name_converter, + dl_merger, + NULL, /* init */ + NULL, /* finish */ + dl_pathbyaddr, + dl_globallookup +}; + +DSO_METHOD *DSO_METHOD_dl(void) +{ + return (&dso_meth_dl); +} + +/* + * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle + * (shl_t) returned from shl_load(). NB: I checked on HPUX11 and shl_t is + * itself a pointer type so the cast is safe. + */ + +static int dl_load(DSO *dso) +{ + shl_t ptr = NULL; + /* + * We don't do any fancy retries or anything, just take the method's (or + * DSO's if it has the callback set) best translation of the + * platform-independant filename and try once with that. + */ + char *filename = DSO_convert_filename(dso, NULL); + + if (filename == NULL) { + DSOerr(DSO_F_DL_LOAD, DSO_R_NO_FILENAME); + goto err; + } + ptr = shl_load(filename, BIND_IMMEDIATE | + (dso->flags & DSO_FLAG_NO_NAME_TRANSLATION ? 0 : + DYNAMIC_PATH), 0L); + if (ptr == NULL) { + DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED); + ERR_add_error_data(4, "filename(", filename, "): ", strerror(errno)); + goto err; + } + if (!sk_push(dso->meth_data, (char *)ptr)) { + DSOerr(DSO_F_DL_LOAD, DSO_R_STACK_ERROR); + goto err; + } + /* + * Success, stick the converted filename we've loaded under into the DSO + * (it also serves as the indicator that we are currently loaded). + */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup! */ + if (filename != NULL) + OPENSSL_free(filename); + if (ptr != NULL) + shl_unload(ptr); + return (0); +} + +static int dl_unload(DSO *dso) +{ + shl_t ptr; + if (dso == NULL) { + DSOerr(DSO_F_DL_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_num(dso->meth_data) < 1) + return (1); + /* Is this statement legal? */ + ptr = (shl_t) sk_pop(dso->meth_data); + if (ptr == NULL) { + DSOerr(DSO_F_DL_UNLOAD, DSO_R_NULL_HANDLE); + /* + * Should push the value back onto the stack in case of a retry. + */ + sk_push(dso->meth_data, (char *)ptr); + return (0); + } + shl_unload(ptr); + return (1); +} + +static void *dl_bind_var(DSO *dso, const char *symname) +{ + shl_t ptr; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DL_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_num(dso->meth_data) < 1) { + DSOerr(DSO_F_DL_BIND_VAR, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_DL_BIND_VAR, DSO_R_NULL_HANDLE); + return (NULL); + } + if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) { + DSOerr(DSO_F_DL_BIND_VAR, DSO_R_SYM_FAILURE); + ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno)); + return (NULL); + } + return (sym); +} + +static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname) +{ + shl_t ptr; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DL_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_num(dso->meth_data) < 1) { + DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_NULL_HANDLE); + return (NULL); + } + if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) { + DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno)); + return (NULL); + } + return ((DSO_FUNC_TYPE)sym); +} + +static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) +{ + char *merged; + + if (!filespec1 && !filespec2) { + DSOerr(DSO_F_DL_MERGER, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + /* + * If the first file specification is a rooted path, it rules. same goes + * if the second file specification is missing. + */ + if (!filespec2 || filespec1[0] == '/') { + merged = OPENSSL_malloc(strlen(filespec1) + 1); + if (!merged) { + DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec1); + } + /* + * If the first file specification is missing, the second one rules. + */ + else if (!filespec1) { + merged = OPENSSL_malloc(strlen(filespec2) + 1); + if (!merged) { + DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + } else + /* + * This part isn't as trivial as it looks. It assumes that the + * second file specification really is a directory, and makes no + * checks whatsoever. Therefore, the result becomes the + * concatenation of filespec2 followed by a slash followed by + * filespec1. + */ + { + int spec2len, len; + + spec2len = (filespec2 ? strlen(filespec2) : 0); + len = spec2len + (filespec1 ? strlen(filespec1) : 0); + + if (filespec2 && filespec2[spec2len - 1] == '/') { + spec2len--; + len--; + } + merged = OPENSSL_malloc(len + 2); + if (!merged) { + DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + merged[spec2len] = '/'; + strcpy(&merged[spec2len + 1], filespec1); + } + return (merged); +} + +/* + * This function is identical to the one in dso_dlfcn.c, but as it is highly + * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at + * the same time, there's no great duplicating the code. Figuring out an + * elegant way to share one copy of the code would be more difficult and + * would not leave the implementations independant. + */ +# if defined(__hpux) +static const char extension[] = ".sl"; +# else +static const char extension[] = ".so"; +# endif +static char *dl_name_converter(DSO *dso, const char *filename) +{ + char *translated; + int len, rsize, transform; + + len = strlen(filename); + rsize = len + 1; + transform = (strstr(filename, "/") == NULL); + { + /* We will convert this to "%s.s?" or "lib%s.s?" */ + rsize += strlen(extension); /* The length of ".s?" */ + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + rsize += 3; /* The length of "lib" */ + } + translated = OPENSSL_malloc(rsize); + if (translated == NULL) { + DSOerr(DSO_F_DL_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + return (NULL); + } + if (transform) { + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + sprintf(translated, "lib%s%s", filename, extension); + else + sprintf(translated, "%s%s", filename, extension); + } else + sprintf(translated, "%s", filename); + return (translated); +} + +static int dl_pathbyaddr(void *addr, char *path, int sz) +{ + struct shl_descriptor inf; + int i, len; + + if (addr == NULL) { + union { + int (*f) (void *, char *, int); + void *p; + } t = { + dl_pathbyaddr + }; + addr = t.p; + } + + for (i = -1; shl_get_r(i, &inf) == 0; i++) { + if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) || + ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) { + len = (int)strlen(inf.filename); + if (sz <= 0) + return len + 1; + if (len >= sz) + len = sz - 1; + memcpy(path, inf.filename, len); + path[len++] = 0; + return len; + } + } + + return -1; +} + +static void *dl_globallookup(const char *name) +{ + void *ret; + shl_t h = NULL; + + return shl_findsym(&h, name, TYPE_UNDEFINED, &ret) ? NULL : ret; +} +#endif /* DSO_DL */ +/* dso_dlfcn.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * We need to do this early, because stdio.h includes the header files that + * handle _GNU_SOURCE and other similar macros. Defining it later is simply + * too late, because those headers are protected from re- inclusion. + */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE /* make sure dladdr is declared */ +#endif + +#include +// #include "cryptlib.h" +// #include "dso.h" + +#ifndef DSO_DLFCN +DSO_METHOD *DSO_METHOD_dlfcn(void) +{ + return NULL; +} +#else + +# ifdef HAVE_DLFCN_H +# ifdef __osf__ +# define __EXTENSIONS__ +# endif +# include +# define HAVE_DLINFO 1 +# if defined(_AIX) || defined(__CYGWIN__) || \ + defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ + (defined(__osf__) && !defined(RTLD_NEXT)) || \ + (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \ + defined(__ANDROID__) +# undef HAVE_DLINFO +# endif +# endif + +/* Part of the hack in "dlfcn_load" ... */ +# define DSO_MAX_TRANSLATED_SIZE 256 + +static int dlfcn_load(DSO *dso); +static int dlfcn_unload(DSO *dso); +static void *dlfcn_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname); +# if 0 +static int dlfcn_unbind(DSO *dso, char *symname, void *symptr); +static int dlfcn_init(DSO *dso); +static int dlfcn_finish(DSO *dso); +static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *dlfcn_name_converter(DSO *dso, const char *filename); +static char *dlfcn_merger(DSO *dso, const char *filespec1, + const char *filespec2); +static int dlfcn_pathbyaddr(void *addr, char *path, int sz); +static void *dlfcn_globallookup(const char *name); + +static DSO_METHOD dso_meth_dlfcn = { + "OpenSSL 'dlfcn' shared library method", + dlfcn_load, + dlfcn_unload, + dlfcn_bind_var, + dlfcn_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + dlfcn_name_converter, + dlfcn_merger, + NULL, /* init */ + NULL, /* finish */ + dlfcn_pathbyaddr, + dlfcn_globallookup +}; + +DSO_METHOD *DSO_METHOD_dlfcn(void) +{ + return (&dso_meth_dlfcn); +} + +/* + * Prior to using the dlopen() function, we should decide on the flag we + * send. There's a few different ways of doing this and it's a messy + * venn-diagram to match up which platforms support what. So as we don't have + * autoconf yet, I'm implementing a hack that could be hacked further + * relatively easily to deal with cases as we find them. Initially this is to + * cope with OpenBSD. + */ +# if defined(__OpenBSD__) || defined(__NetBSD__) +# ifdef DL_LAZY +# define DLOPEN_FLAG DL_LAZY +# else +# ifdef RTLD_NOW +# define DLOPEN_FLAG RTLD_NOW +# else +# define DLOPEN_FLAG 0 +# endif +# endif +# else +# ifdef OPENSSL_SYS_SUNOS +# define DLOPEN_FLAG 1 +# else +# define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */ +# endif +# endif + +/* + * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle + * (void*) returned from dlopen(). + */ + +static int dlfcn_load(DSO *dso) +{ + void *ptr = NULL; + /* See applicable comments in dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + int flags = DLOPEN_FLAG; + + if (filename == NULL) { + DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME); + goto err; + } +# ifdef RTLD_GLOBAL + if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS) + flags |= RTLD_GLOBAL; +# endif + ptr = dlopen(filename, flags); + if (ptr == NULL) { + DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED); + ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); + goto err; + } + if (!sk_void_push(dso->meth_data, (char *)ptr)) { + DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR); + goto err; + } + /* Success */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup! */ + if (filename != NULL) + OPENSSL_free(filename); + if (ptr != NULL) + dlclose(ptr); + return (0); +} + +static int dlfcn_unload(DSO *dso) +{ + void *ptr; + if (dso == NULL) { + DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_void_num(dso->meth_data) < 1) + return (1); + ptr = sk_void_pop(dso->meth_data); + if (ptr == NULL) { + DSOerr(DSO_F_DLFCN_UNLOAD, DSO_R_NULL_HANDLE); + /* + * Should push the value back onto the stack in case of a retry. + */ + sk_void_push(dso->meth_data, ptr); + return (0); + } + /* For now I'm not aware of any errors associated with dlclose() */ + dlclose(ptr); + return (1); +} + +static void *dlfcn_bind_var(DSO *dso, const char *symname) +{ + void *ptr, *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DLFCN_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_NULL_HANDLE); + return (NULL); + } + sym = dlsym(ptr, symname); + if (sym == NULL) { + DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_SYM_FAILURE); + ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); + return (NULL); + } + return (sym); +} + +static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) +{ + void *ptr; + union { + DSO_FUNC_TYPE sym; + void *dlret; + } u; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_NULL_HANDLE); + return (NULL); + } + u.dlret = dlsym(ptr, symname); + if (u.dlret == NULL) { + DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); + return (NULL); + } + return u.sym; +} + +static char *dlfcn_merger(DSO *dso, const char *filespec1, + const char *filespec2) +{ + char *merged; + + if (!filespec1 && !filespec2) { + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + /* + * If the first file specification is a rooted path, it rules. same goes + * if the second file specification is missing. + */ + if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) { + merged = OPENSSL_malloc(strlen(filespec1) + 1); + if (!merged) { + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec1); + } + /* + * If the first file specification is missing, the second one rules. + */ + else if (!filespec1) { + merged = OPENSSL_malloc(strlen(filespec2) + 1); + if (!merged) { + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + } else { + /* + * This part isn't as trivial as it looks. It assumes that the + * second file specification really is a directory, and makes no + * checks whatsoever. Therefore, the result becomes the + * concatenation of filespec2 followed by a slash followed by + * filespec1. + */ + int spec2len, len; + + spec2len = strlen(filespec2); + len = spec2len + strlen(filespec1); + + if (spec2len && filespec2[spec2len - 1] == '/') { + spec2len--; + len--; + } + merged = OPENSSL_malloc(len + 2); + if (!merged) { + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + merged[spec2len] = '/'; + strcpy(&merged[spec2len + 1], filespec1); + } + return (merged); +} + +# ifdef OPENSSL_SYS_MACOSX +# define DSO_ext ".dylib" +# define DSO_extlen 6 +# else +# define DSO_ext ".so" +# define DSO_extlen 3 +# endif + +static char *dlfcn_name_converter(DSO *dso, const char *filename) +{ + char *translated; + int len, rsize, transform; + + len = strlen(filename); + rsize = len + 1; + transform = (strstr(filename, "/") == NULL); + if (transform) { + /* We will convert this to "%s.so" or "lib%s.so" etc */ + rsize += DSO_extlen; /* The length of ".so" */ + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + rsize += 3; /* The length of "lib" */ + } + translated = OPENSSL_malloc(rsize); + if (translated == NULL) { + DSOerr(DSO_F_DLFCN_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + return (NULL); + } + if (transform) { + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + sprintf(translated, "lib%s" DSO_ext, filename); + else + sprintf(translated, "%s" DSO_ext, filename); + } else + sprintf(translated, "%s", filename); + return (translated); +} + +# ifdef __sgi +/*- +This is a quote from IRIX manual for dladdr(3c): + + does not contain a prototype for dladdr or definition of + Dl_info. The #include in the SYNOPSIS line is traditional, + but contains no dladdr prototype and no IRIX library contains an + implementation. Write your own declaration based on the code below. + + The following code is dependent on internal interfaces that are not + part of the IRIX compatibility guarantee; however, there is no future + intention to change this interface, so on a practical level, the code + below is safe to use on IRIX. +*/ +# include +# ifndef _RLD_INTERFACE_DLFCN_H_DLADDR +# define _RLD_INTERFACE_DLFCN_H_DLADDR +typedef struct Dl_info { + const char *dli_fname; + void *dli_fbase; + const char *dli_sname; + void *dli_saddr; + int dli_version; + int dli_reserved1; + long dli_reserved[4]; +} Dl_info; +# else +typedef struct Dl_info Dl_info; +# endif +# define _RLD_DLADDR 14 + +static int dladdr(void *address, Dl_info *dl) +{ + void *v; + v = _rld_new_interface(_RLD_DLADDR, address, dl); + return (int)v; +} +# endif /* __sgi */ + +static int dlfcn_pathbyaddr(void *addr, char *path, int sz) +{ +# ifdef HAVE_DLINFO + Dl_info dli; + int len; + + if (addr == NULL) { + union { + int (*f) (void *, char *, int); + void *p; + } t = { + dlfcn_pathbyaddr + }; + addr = t.p; + } + + if (dladdr(addr, &dli)) { + len = (int)strlen(dli.dli_fname); + if (sz <= 0) + return len + 1; + if (len >= sz) + len = sz - 1; + memcpy(path, dli.dli_fname, len); + path[len++] = 0; + return len; + } + + ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror()); +# endif + return -1; +} + +static void *dlfcn_globallookup(const char *name) +{ + void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY); + + if (handle) { + ret = dlsym(handle, name); + dlclose(handle); + } + + return ret; +} +#endif /* DSO_DLFCN */ +/* crypto/dso/dso_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "dso.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason) + +static ERR_STRING_DATA DSO_str_functs[] = { + {ERR_FUNC(DSO_F_BEOS_BIND_FUNC), "BEOS_BIND_FUNC"}, + {ERR_FUNC(DSO_F_BEOS_BIND_VAR), "BEOS_BIND_VAR"}, + {ERR_FUNC(DSO_F_BEOS_LOAD), "BEOS_LOAD"}, + {ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER), "BEOS_NAME_CONVERTER"}, + {ERR_FUNC(DSO_F_BEOS_UNLOAD), "BEOS_UNLOAD"}, + {ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"}, + {ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"}, + {ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"}, + {ERR_FUNC(DSO_F_DLFCN_MERGER), "DLFCN_MERGER"}, + {ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "DLFCN_NAME_CONVERTER"}, + {ERR_FUNC(DSO_F_DLFCN_UNLOAD), "DLFCN_UNLOAD"}, + {ERR_FUNC(DSO_F_DL_BIND_FUNC), "DL_BIND_FUNC"}, + {ERR_FUNC(DSO_F_DL_BIND_VAR), "DL_BIND_VAR"}, + {ERR_FUNC(DSO_F_DL_LOAD), "DL_LOAD"}, + {ERR_FUNC(DSO_F_DL_MERGER), "DL_MERGER"}, + {ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "DL_NAME_CONVERTER"}, + {ERR_FUNC(DSO_F_DL_UNLOAD), "DL_UNLOAD"}, + {ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"}, + {ERR_FUNC(DSO_F_DSO_BIND_VAR), "DSO_bind_var"}, + {ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME), "DSO_convert_filename"}, + {ERR_FUNC(DSO_F_DSO_CTRL), "DSO_ctrl"}, + {ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"}, + {ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"}, + {ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"}, + {ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP), "DSO_global_lookup"}, + {ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"}, + {ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"}, + {ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"}, + {ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"}, + {ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"}, + {ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"}, + {ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"}, + {ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC), "GLOBAL_LOOKUP_FUNC"}, + {ERR_FUNC(DSO_F_PATHBYADDR), "PATHBYADDR"}, + {ERR_FUNC(DSO_F_VMS_BIND_SYM), "VMS_BIND_SYM"}, + {ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"}, + {ERR_FUNC(DSO_F_VMS_MERGER), "VMS_MERGER"}, + {ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"}, + {ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"}, + {ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"}, + {ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP), "WIN32_GLOBALLOOKUP"}, + {ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC), "WIN32_GLOBALLOOKUP_FUNC"}, + {ERR_FUNC(DSO_F_WIN32_JOINER), "WIN32_JOINER"}, + {ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"}, + {ERR_FUNC(DSO_F_WIN32_MERGER), "WIN32_MERGER"}, + {ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"}, + {ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "WIN32_PATHBYADDR"}, + {ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"}, + {ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"}, + {0, NULL} +}; + +static ERR_STRING_DATA DSO_str_reasons[] = { + {ERR_REASON(DSO_R_CTRL_FAILED), "control command failed"}, + {ERR_REASON(DSO_R_DSO_ALREADY_LOADED), "dso already loaded"}, + {ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE), "empty file structure"}, + {ERR_REASON(DSO_R_FAILURE), "failure"}, + {ERR_REASON(DSO_R_FILENAME_TOO_BIG), "filename too big"}, + {ERR_REASON(DSO_R_FINISH_FAILED), "cleanup method function failed"}, + {ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX), "incorrect file syntax"}, + {ERR_REASON(DSO_R_LOAD_FAILED), "could not load the shared library"}, + {ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED), "name translation failed"}, + {ERR_REASON(DSO_R_NO_FILENAME), "no filename"}, + {ERR_REASON(DSO_R_NO_FILE_SPECIFICATION), "no file specification"}, + {ERR_REASON(DSO_R_NULL_HANDLE), "a null shared library handle was used"}, + {ERR_REASON(DSO_R_SET_FILENAME_FAILED), "set filename failed"}, + {ERR_REASON(DSO_R_STACK_ERROR), "the meth_data stack is corrupt"}, + {ERR_REASON(DSO_R_SYM_FAILURE), + "could not bind to the requested symbol name"}, + {ERR_REASON(DSO_R_UNLOAD_FAILED), "could not unload the shared library"}, + {ERR_REASON(DSO_R_UNSUPPORTED), "functionality not supported"}, + {0, NULL} +}; + +#endif + +void ERR_load_DSO_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) { + ERR_load_strings(0, DSO_str_functs); + ERR_load_strings(0, DSO_str_reasons); + } +#endif +} +/* dso_lib.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "crypto.h" +// #include "cryptlib.h" +// #include "dso.h" + +static DSO_METHOD *default_DSO_meth = NULL; + +DSO *DSO_new(void) +{ + return (DSO_new_method(NULL)); +} + +void DSO_set_default_method(DSO_METHOD *meth) +{ + default_DSO_meth = meth; +} + +DSO_METHOD *DSO_get_default_method(void) +{ + return (default_DSO_meth); +} + +DSO_METHOD *DSO_get_method(DSO *dso) +{ + return (dso->meth); +} + +DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth) +{ + DSO_METHOD *mtmp; + mtmp = dso->meth; + dso->meth = meth; + return (mtmp); +} + +DSO *DSO_new_method(DSO_METHOD *meth) +{ + DSO *ret; + + if (default_DSO_meth == NULL) + /* + * We default to DSO_METH_openssl() which in turn defaults to + * stealing the "best available" method. Will fallback to + * DSO_METH_null() in the worst case. + */ + default_DSO_meth = DSO_METHOD_openssl(); + ret = (DSO *)OPENSSL_malloc(sizeof(DSO)); + if (ret == NULL) { + DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + memset(ret, 0, sizeof(DSO)); + ret->meth_data = sk_void_new_null(); + if (ret->meth_data == NULL) { + /* sk_new doesn't generate any errors so we do */ + DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return (NULL); + } + if (meth == NULL) + ret->meth = default_DSO_meth; + else + ret->meth = meth; + ret->references = 1; + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + sk_void_free(ret->meth_data); + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +int DSO_free(DSO *dso) +{ + int i; + + if (dso == NULL) { + DSOerr(DSO_F_DSO_FREE, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + + i = CRYPTO_add(&dso->references, -1, CRYPTO_LOCK_DSO); +#ifdef REF_PRINT + REF_PRINT("DSO", dso); +#endif + if (i > 0) + return (1); +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "DSO_free, bad reference count\n"); + abort(); + } +#endif + + if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) { + DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED); + return (0); + } + + if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) { + DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED); + return (0); + } + + sk_void_free(dso->meth_data); + if (dso->filename != NULL) + OPENSSL_free(dso->filename); + if (dso->loaded_filename != NULL) + OPENSSL_free(dso->loaded_filename); + + OPENSSL_free(dso); + return (1); +} + +int DSO_flags(DSO *dso) +{ + return ((dso == NULL) ? 0 : dso->flags); +} + +int DSO_up_ref(DSO *dso) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + + CRYPTO_add(&dso->references, 1, CRYPTO_LOCK_DSO); + return (1); +} + +DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) +{ + DSO *ret; + int allocated = 0; + + if (dso == NULL) { + ret = DSO_new_method(meth); + if (ret == NULL) { + DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE); + goto err; + } + allocated = 1; + /* Pass the provided flags to the new DSO object */ + if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED); + goto err; + } + } else + ret = dso; + /* Don't load if we're currently already loaded */ + if (ret->filename != NULL) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED); + goto err; + } + /* + * filename can only be NULL if we were passed a dso that already has one + * set. + */ + if (filename != NULL) + if (!DSO_set_filename(ret, filename)) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED); + goto err; + } + filename = ret->filename; + if (filename == NULL) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME); + goto err; + } + if (ret->meth->dso_load == NULL) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED); + goto err; + } + if (!ret->meth->dso_load(ret)) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED); + goto err; + } + /* Load succeeded */ + return (ret); + err: + if (allocated) + DSO_free(ret); + return (NULL); +} + +void *DSO_bind_var(DSO *dso, const char *symname) +{ + void *ret = NULL; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DSO_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (dso->meth->dso_bind_var == NULL) { + DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_UNSUPPORTED); + return (NULL); + } + if ((ret = dso->meth->dso_bind_var(dso, symname)) == NULL) { + DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_SYM_FAILURE); + return (NULL); + } + /* Success */ + return (ret); +} + +DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname) +{ + DSO_FUNC_TYPE ret = NULL; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (dso->meth->dso_bind_func == NULL) { + DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED); + return (NULL); + } + if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) { + DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE); + return (NULL); + } + /* Success */ + return (ret); +} + +/* + * I don't really like these *_ctrl functions very much to be perfectly + * honest. For one thing, I think I have to return a negative value for any + * error because possible DSO_ctrl() commands may return values such as + * "size"s that can legitimately be zero (making the standard + * "if (DSO_cmd(...))" form that works almost everywhere else fail at odd + * times. I'd prefer "output" values to be passed by reference and the return + * value as success/failure like usual ... but we conform when we must... :-) + */ +long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return (-1); + } + /* + * We should intercept certain generic commands and only pass control to + * the method-specific ctrl() function if it's something we don't handle. + */ + switch (cmd) { + case DSO_CTRL_GET_FLAGS: + return dso->flags; + case DSO_CTRL_SET_FLAGS: + dso->flags = (int)larg; + return (0); + case DSO_CTRL_OR_FLAGS: + dso->flags |= (int)larg; + return (0); + default: + break; + } + if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) { + DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED); + return (-1); + } + return (dso->meth->dso_ctrl(dso, cmd, larg, parg)); +} + +int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb, + DSO_NAME_CONVERTER_FUNC *oldcb) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_SET_NAME_CONVERTER, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (oldcb) + *oldcb = dso->name_converter; + dso->name_converter = cb; + return (1); +} + +const char *DSO_get_filename(DSO *dso) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + return (dso->filename); +} + +int DSO_set_filename(DSO *dso, const char *filename) +{ + char *copied; + + if ((dso == NULL) || (filename == NULL)) { + DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (dso->loaded_filename) { + DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED); + return (0); + } + /* We'll duplicate filename */ + copied = OPENSSL_malloc(strlen(filename) + 1); + if (copied == NULL) { + DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE); + return (0); + } + BUF_strlcpy(copied, filename, strlen(filename) + 1); + if (dso->filename) + OPENSSL_free(dso->filename); + dso->filename = copied; + return (1); +} + +char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2) +{ + char *result = NULL; + + if (dso == NULL || filespec1 == NULL) { + DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { + if (dso->merger != NULL) + result = dso->merger(dso, filespec1, filespec2); + else if (dso->meth->dso_merger != NULL) + result = dso->meth->dso_merger(dso, filespec1, filespec2); + } + return (result); +} + +char *DSO_convert_filename(DSO *dso, const char *filename) +{ + char *result = NULL; + + if (dso == NULL) { + DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (filename == NULL) + filename = dso->filename; + if (filename == NULL) { + DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME); + return (NULL); + } + if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { + if (dso->name_converter != NULL) + result = dso->name_converter(dso, filename); + else if (dso->meth->dso_name_converter != NULL) + result = dso->meth->dso_name_converter(dso, filename); + } + if (result == NULL) { + result = OPENSSL_malloc(strlen(filename) + 1); + if (result == NULL) { + DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE); + return (NULL); + } + BUF_strlcpy(result, filename, strlen(filename) + 1); + } + return (result); +} + +const char *DSO_get_loaded_filename(DSO *dso) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_GET_LOADED_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + return (dso->loaded_filename); +} + +int DSO_pathbyaddr(void *addr, char *path, int sz) +{ + DSO_METHOD *meth = default_DSO_meth; + if (meth == NULL) + meth = DSO_METHOD_openssl(); + if (meth->pathbyaddr == NULL) { + DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED); + return -1; + } + return (*meth->pathbyaddr) (addr, path, sz); +} + +void *DSO_global_lookup(const char *name) +{ + DSO_METHOD *meth = default_DSO_meth; + if (meth == NULL) + meth = DSO_METHOD_openssl(); + if (meth->globallookup == NULL) { + DSOerr(DSO_F_DSO_GLOBAL_LOOKUP, DSO_R_UNSUPPORTED); + return NULL; + } + return (*meth->globallookup) (name); +} +/* dso_null.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This "NULL" method is provided as the fallback for systems that have no + * appropriate support for "shared-libraries". + */ + +#include +// #include "cryptlib.h" +// #include "dso.h" + +static DSO_METHOD dso_meth_null = { + "NULL shared library method", + NULL, /* load */ + NULL, /* unload */ + NULL, /* bind_var */ + NULL, /* bind_func */ +/* For now, "unbind" doesn't exist */ +#if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +#endif + NULL, /* ctrl */ + NULL, /* dso_name_converter */ + NULL, /* dso_merger */ + NULL, /* init */ + NULL, /* finish */ + NULL, /* pathbyaddr */ + NULL /* globallookup */ +}; + +DSO_METHOD *DSO_METHOD_null(void) +{ + return (&dso_meth_null); +} +/* dso_openssl.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "dso.h" + +/* We just pinch the method from an appropriate "default" method. */ + +DSO_METHOD *DSO_METHOD_openssl(void) +{ +#ifdef DEF_DSO_METHOD + return (DEF_DSO_METHOD()); +#elif defined(DSO_DLFCN) + return (DSO_METHOD_dlfcn()); +#elif defined(DSO_DL) + return (DSO_METHOD_dl()); +#elif defined(DSO_WIN32) + return (DSO_METHOD_win32()); +#elif defined(DSO_VMS) + return (DSO_METHOD_vms()); +#elif defined(DSO_BEOS) + return (DSO_METHOD_beos()); +#else + return (DSO_METHOD_null()); +#endif +} +/* dso_vms.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +// #include "cryptlib.h" +// #include "dso.h" + +#ifndef OPENSSL_SYS_VMS +DSO_METHOD *DSO_METHOD_vms(void) +{ + return NULL; +} +#else + +# pragma message disable DOLLARID +# include +# include +# include +# include +# include +# include "vms_rms.h" + +/* Some compiler options may mask the declaration of "_malloc32". */ +# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 +void *_malloc32(__size_t); +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ +# endif /* __INITIAL_POINTER_SIZE && defined + * _ANSI_C_SOURCE */ + +# pragma message disable DOLLARID + +static int vms_load(DSO *dso); +static int vms_unload(DSO *dso); +static void *vms_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname); +# if 0 +static int vms_unbind_var(DSO *dso, char *symname, void *symptr); +static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int vms_init(DSO *dso); +static int vms_finish(DSO *dso); +static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *vms_name_converter(DSO *dso, const char *filename); +static char *vms_merger(DSO *dso, const char *filespec1, + const char *filespec2); + +static DSO_METHOD dso_meth_vms = { + "OpenSSL 'VMS' shared library method", + vms_load, + NULL, /* unload */ + vms_bind_var, + vms_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + vms_name_converter, + vms_merger, + NULL, /* init */ + NULL /* finish */ +}; + +/* + * On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends + * on the reference to the file name being the same for all calls regarding + * one shared image, so we'll just store it in an instance of the following + * structure and put a pointer to that instance in the meth_data stack. + */ +typedef struct dso_internal_st { + /* + * This should contain the name only, no directory, no extension, nothing + * but a name. + */ + struct dsc$descriptor_s filename_dsc; + char filename[NAMX_MAXRSS + 1]; + /* + * This contains whatever is not in filename, if needed. Normally not + * defined. + */ + struct dsc$descriptor_s imagename_dsc; + char imagename[NAMX_MAXRSS + 1]; +} DSO_VMS_INTERNAL; + +DSO_METHOD *DSO_METHOD_vms(void) +{ + return (&dso_meth_vms); +} + +static int vms_load(DSO *dso) +{ + void *ptr = NULL; + /* See applicable comments in dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + +/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */ +# if __INITIAL_POINTER_SIZE == 64 +# define DSO_MALLOC _malloc32 +# pragma pointer_size save +# pragma pointer_size 32 +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define DSO_MALLOC OPENSSL_malloc +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + DSO_VMS_INTERNAL *p = NULL; + +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ + + const char *sp1, *sp2; /* Search result */ + const char *ext = NULL; /* possible extension to add */ + + if (filename == NULL) { + DSOerr(DSO_F_VMS_LOAD, DSO_R_NO_FILENAME); + goto err; + } + + /*- + * A file specification may look like this: + * + * node::dev:[dir-spec]name.type;ver + * + * or (for compatibility with TOPS-20): + * + * node::dev:name.type;ver + * + * and the dir-spec uses '.' as separator. Also, a dir-spec + * may consist of several parts, with mixed use of [] and <>: + * + * [dir1.] + * + * We need to split the file specification into the name and + * the rest (both before and after the name itself). + */ + /* + * Start with trying to find the end of a dir-spec, and save the position + * of the byte after in sp1 + */ + sp1 = strrchr(filename, ']'); + sp2 = strrchr(filename, '>'); + if (sp1 == NULL) + sp1 = sp2; + if (sp2 != NULL && sp2 > sp1) + sp1 = sp2; + if (sp1 == NULL) + sp1 = strrchr(filename, ':'); + if (sp1 == NULL) + sp1 = filename; + else + sp1++; /* The byte after the found character */ + /* Now, let's see if there's a type, and save the position in sp2 */ + sp2 = strchr(sp1, '.'); + /* + * If there is a period and the next character is a semi-colon, + * we need to add an extension + */ + if (sp2 != NULL && sp2[1] == ';') + ext = ".EXE"; + /* + * If we found it, that's where we'll cut. Otherwise, look for a version + * number and save the position in sp2 + */ + if (sp2 == NULL) { + sp2 = strchr(sp1, ';'); + ext = ".EXE"; + } + /* + * If there was still nothing to find, set sp2 to point at the end of the + * string + */ + if (sp2 == NULL) + sp2 = sp1 + strlen(sp1); + + /* Check that we won't get buffer overflows */ + if (sp2 - sp1 > FILENAME_MAX + || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) { + DSOerr(DSO_F_VMS_LOAD, DSO_R_FILENAME_TOO_BIG); + goto err; + } + + p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL)); + if (p == NULL) { + DSOerr(DSO_F_VMS_LOAD, ERR_R_MALLOC_FAILURE); + goto err; + } + + strncpy(p->filename, sp1, sp2 - sp1); + p->filename[sp2 - sp1] = '\0'; + + strncpy(p->imagename, filename, sp1 - filename); + p->imagename[sp1 - filename] = '\0'; + if (ext) { + strcat(p->imagename, ext); + if (*sp2 == '.') + sp2++; + } + strcat(p->imagename, sp2); + + p->filename_dsc.dsc$w_length = strlen(p->filename); + p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + p->filename_dsc.dsc$b_class = DSC$K_CLASS_S; + p->filename_dsc.dsc$a_pointer = p->filename; + p->imagename_dsc.dsc$w_length = strlen(p->imagename); + p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S; + p->imagename_dsc.dsc$a_pointer = p->imagename; + + if (!sk_void_push(dso->meth_data, (char *)p)) { + DSOerr(DSO_F_VMS_LOAD, DSO_R_STACK_ERROR); + goto err; + } + + /* Success (for now, we lie. We actually do not know...) */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup! */ + if (p != NULL) + OPENSSL_free(p); + if (filename != NULL) + OPENSSL_free(filename); + return (0); +} + +/* + * Note that this doesn't actually unload the shared image, as there is no + * such thing in VMS. Next time it get loaded again, a new copy will + * actually be loaded. + */ +static int vms_unload(DSO *dso) +{ + DSO_VMS_INTERNAL *p; + if (dso == NULL) { + DSOerr(DSO_F_VMS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_void_num(dso->meth_data) < 1) + return (1); + p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data); + if (p == NULL) { + DSOerr(DSO_F_VMS_UNLOAD, DSO_R_NULL_HANDLE); + return (0); + } + /* Cleanup */ + OPENSSL_free(p); + return (1); +} + +/* + * We must do this in a separate function because of the way the exception + * handler works (it makes this function return + */ +static int do_find_symbol(DSO_VMS_INTERNAL *ptr, + struct dsc$descriptor_s *symname_dsc, void **sym, + unsigned long flags) +{ + /* + * Make sure that signals are caught and returned instead of aborting the + * program. The exception handler gets unestablished automatically on + * return from this function. + */ + lib$establish(lib$sig_to_ret); + + if (ptr->imagename_dsc.dsc$w_length) + return lib$find_image_symbol(&ptr->filename_dsc, + symname_dsc, sym, + &ptr->imagename_dsc, flags); + else + return lib$find_image_symbol(&ptr->filename_dsc, + symname_dsc, sym, 0, flags); +} + +void vms_bind_sym(DSO *dso, const char *symname, void **sym) +{ + DSO_VMS_INTERNAL *ptr; + int status; +# if 0 + int flags = (1 << 4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't + * defined in VMS older than 7.0 or so */ +# else + int flags = 0; +# endif + struct dsc$descriptor_s symname_dsc; + +/* Arrange 32-bit pointer to (copied) string storage, if needed. */ +# if __INITIAL_POINTER_SIZE == 64 +# define SYMNAME symname_32p +# pragma pointer_size save +# pragma pointer_size 32 + char *symname_32p; +# pragma pointer_size restore + char symname_32[NAMX_MAXRSS + 1]; +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define SYMNAME ((char *) symname) +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + *sym = NULL; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_VMS_BIND_SYM, ERR_R_PASSED_NULL_PARAMETER); + return; + } +# if __INITIAL_POINTER_SIZE == 64 + /* Copy the symbol name to storage with a 32-bit pointer. */ + symname_32p = symname_32; + strcpy(symname_32p, symname); +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + symname_dsc.dsc$w_length = strlen(SYMNAME); + symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + symname_dsc.dsc$b_class = DSC$K_CLASS_S; + symname_dsc.dsc$a_pointer = SYMNAME; + + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_STACK_ERROR); + return; + } + ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data, + sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_NULL_HANDLE); + return; + } + + if (dso->flags & DSO_FLAG_UPCASE_SYMBOL) + flags = 0; + + status = do_find_symbol(ptr, &symname_dsc, sym, flags); + + if (!$VMS_STATUS_SUCCESS(status)) { + unsigned short length; + char errstring[257]; + struct dsc$descriptor_s errstring_dsc; + + errstring_dsc.dsc$w_length = sizeof(errstring); + errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + errstring_dsc.dsc$b_class = DSC$K_CLASS_S; + errstring_dsc.dsc$a_pointer = errstring; + + *sym = NULL; + + status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); + + if (!$VMS_STATUS_SUCCESS(status)) + lib$signal(status); /* This is really bad. Abort! */ + else { + errstring[length] = '\0'; + + DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_SYM_FAILURE); + if (ptr->imagename_dsc.dsc$w_length) + ERR_add_error_data(9, + "Symbol ", symname, + " in ", ptr->filename, + " (", ptr->imagename, ")", + ": ", errstring); + else + ERR_add_error_data(6, + "Symbol ", symname, + " in ", ptr->filename, ": ", errstring); + } + return; + } + return; +} + +static void *vms_bind_var(DSO *dso, const char *symname) +{ + void *sym = 0; + vms_bind_sym(dso, symname, &sym); + return sym; +} + +static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname) +{ + DSO_FUNC_TYPE sym = 0; + vms_bind_sym(dso, symname, (void **)&sym); + return sym; +} + +static char *vms_merger(DSO *dso, const char *filespec1, + const char *filespec2) +{ + int status; + int filespec1len, filespec2len; + struct FAB fab; + struct NAMX_STRUCT nam; + char esa[NAMX_MAXRSS + 1]; + char *merged; + +/* Arrange 32-bit pointer to (copied) string storage, if needed. */ +# if __INITIAL_POINTER_SIZE == 64 +# define FILESPEC1 filespec1_32p; +# define FILESPEC2 filespec2_32p; +# pragma pointer_size save +# pragma pointer_size 32 + char *filespec1_32p; + char *filespec2_32p; +# pragma pointer_size restore + char filespec1_32[NAMX_MAXRSS + 1]; + char filespec2_32[NAMX_MAXRSS + 1]; +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define FILESPEC1 ((char *) filespec1) +# define FILESPEC2 ((char *) filespec2) +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + if (!filespec1) + filespec1 = ""; + if (!filespec2) + filespec2 = ""; + filespec1len = strlen(filespec1); + filespec2len = strlen(filespec2); + +# if __INITIAL_POINTER_SIZE == 64 + /* Copy the file names to storage with a 32-bit pointer. */ + filespec1_32p = filespec1_32; + filespec2_32p = filespec2_32; + strcpy(filespec1_32p, filespec1); + strcpy(filespec2_32p, filespec2); +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + fab = cc$rms_fab; + nam = CC_RMS_NAMX; + + FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNA = FILESPEC1; + FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNS = filespec1len; + FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNA = FILESPEC2; + FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNS = filespec2len; + NAMX_DNA_FNA_SET(fab) + + nam.NAMX_ESA = esa; + nam.NAMX_ESS = NAMX_MAXRSS; + nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD; + SET_NAMX_NO_SHORT_UPCASE(nam); + + fab.FAB_NAMX = &nam; + + status = sys$parse(&fab, 0, 0); + + if (!$VMS_STATUS_SUCCESS(status)) { + unsigned short length; + char errstring[257]; + struct dsc$descriptor_s errstring_dsc; + + errstring_dsc.dsc$w_length = sizeof(errstring); + errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + errstring_dsc.dsc$b_class = DSC$K_CLASS_S; + errstring_dsc.dsc$a_pointer = errstring; + + status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); + + if (!$VMS_STATUS_SUCCESS(status)) + lib$signal(status); /* This is really bad. Abort! */ + else { + errstring[length] = '\0'; + + DSOerr(DSO_F_VMS_MERGER, DSO_R_FAILURE); + ERR_add_error_data(7, + "filespec \"", filespec1, "\", ", + "defaults \"", filespec2, "\": ", errstring); + } + return (NULL); + } + + merged = OPENSSL_malloc(nam.NAMX_ESL + 1); + if (!merged) + goto malloc_err; + strncpy(merged, nam.NAMX_ESA, nam.NAMX_ESL); + merged[nam.NAMX_ESL] = '\0'; + return (merged); + malloc_err: + DSOerr(DSO_F_VMS_MERGER, ERR_R_MALLOC_FAILURE); +} + +static char *vms_name_converter(DSO *dso, const char *filename) +{ + int len = strlen(filename); + char *not_translated = OPENSSL_malloc(len + 1); + if (not_translated) + strcpy(not_translated, filename); + return (not_translated); +} + +#endif /* OPENSSL_SYS_VMS */ +/* dso_win32.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "dso.h" + +#if !defined(DSO_WIN32) +DSO_METHOD *DSO_METHOD_win32(void) +{ + return NULL; +} +#else + +# ifdef _WIN32_WCE +# if _WIN32_WCE < 300 +static FARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName) +{ + WCHAR lpProcNameW[64]; + int i; + + for (i = 0; lpProcName[i] && i < 64; i++) + lpProcNameW[i] = (WCHAR)lpProcName[i]; + if (i == 64) + return NULL; + lpProcNameW[i] = 0; + + return GetProcAddressW(hModule, lpProcNameW); +} +# endif +# undef GetProcAddress +# define GetProcAddress GetProcAddressA + +static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName) +{ + WCHAR *fnamw; + size_t len_0 = strlen(lpLibFileName) + 1, i; + +# ifdef _MSC_VER + fnamw = (WCHAR *)_alloca(len_0 * sizeof(WCHAR)); +# else + fnamw = (WCHAR *)alloca(len_0 * sizeof(WCHAR)); +# endif + if (fnamw == NULL) { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } +# if defined(_WIN32_WCE) && _WIN32_WCE>=101 + if (!MultiByteToWideChar(CP_ACP, 0, lpLibFileName, len_0, fnamw, len_0)) +# endif + for (i = 0; i < len_0; i++) + fnamw[i] = (WCHAR)lpLibFileName[i]; + + return LoadLibraryW(fnamw); +} +# endif + +/* Part of the hack in "win32_load" ... */ +# define DSO_MAX_TRANSLATED_SIZE 256 + +static int win32_load(DSO *dso); +static int win32_unload(DSO *dso); +static void *win32_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname); +# if 0 +static int win32_unbind_var(DSO *dso, char *symname, void *symptr); +static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int win32_init(DSO *dso); +static int win32_finish(DSO *dso); +static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *win32_name_converter(DSO *dso, const char *filename); +static char *win32_merger(DSO *dso, const char *filespec1, + const char *filespec2); +static int win32_pathbyaddr(void *addr, char *path, int sz); +static void *win32_globallookup(const char *name); + +static const char *openssl_strnchr(const char *string, int c, size_t len); + +static DSO_METHOD dso_meth_win32 = { + "OpenSSL 'win32' shared library method", + win32_load, + win32_unload, + win32_bind_var, + win32_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + win32_name_converter, + win32_merger, + NULL, /* init */ + NULL, /* finish */ + win32_pathbyaddr, + win32_globallookup +}; + +DSO_METHOD *DSO_METHOD_win32(void) +{ + return (&dso_meth_win32); +} + +/* + * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to + * the handle (HINSTANCE) returned from LoadLibrary(), and copied. + */ + +static int win32_load(DSO *dso) +{ + HINSTANCE h = NULL, *p = NULL; + /* See applicable comments from dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + + if (filename == NULL) { + DSOerr(DSO_F_WIN32_LOAD, DSO_R_NO_FILENAME); + goto err; + } + h = LoadLibraryA(filename); + if (h == NULL) { + DSOerr(DSO_F_WIN32_LOAD, DSO_R_LOAD_FAILED); + ERR_add_error_data(3, "filename(", filename, ")"); + goto err; + } + p = (HINSTANCE *) OPENSSL_malloc(sizeof(HINSTANCE)); + if (p == NULL) { + DSOerr(DSO_F_WIN32_LOAD, ERR_R_MALLOC_FAILURE); + goto err; + } + *p = h; + if (!sk_void_push(dso->meth_data, p)) { + DSOerr(DSO_F_WIN32_LOAD, DSO_R_STACK_ERROR); + goto err; + } + /* Success */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup ! */ + if (filename != NULL) + OPENSSL_free(filename); + if (p != NULL) + OPENSSL_free(p); + if (h != NULL) + FreeLibrary(h); + return (0); +} + +static int win32_unload(DSO *dso) +{ + HINSTANCE *p; + if (dso == NULL) { + DSOerr(DSO_F_WIN32_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_void_num(dso->meth_data) < 1) + return (1); + p = sk_void_pop(dso->meth_data); + if (p == NULL) { + DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_NULL_HANDLE); + return (0); + } + if (!FreeLibrary(*p)) { + DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_UNLOAD_FAILED); + /* + * We should push the value back onto the stack in case of a retry. + */ + sk_void_push(dso->meth_data, p); + return (0); + } + /* Cleanup */ + OPENSSL_free(p); + return (1); +} + +/* + * Using GetProcAddress for variables? TODO: Check this out in the Win32 API + * docs, there's probably a variant for variables. + */ +static void *win32_bind_var(DSO *dso, const char *symname) +{ + HINSTANCE *ptr; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_WIN32_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_NULL_HANDLE); + return (NULL); + } + sym = GetProcAddress(*ptr, symname); + if (sym == NULL) { + DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_SYM_FAILURE); + ERR_add_error_data(3, "symname(", symname, ")"); + return (NULL); + } + return (sym); +} + +static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname) +{ + HINSTANCE *ptr; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_WIN32_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_NULL_HANDLE); + return (NULL); + } + sym = GetProcAddress(*ptr, symname); + if (sym == NULL) { + DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_add_error_data(3, "symname(", symname, ")"); + return (NULL); + } + return ((DSO_FUNC_TYPE)sym); +} + +struct file_st { + const char *node; + int nodelen; + const char *device; + int devicelen; + const char *predir; + int predirlen; + const char *dir; + int dirlen; + const char *file; + int filelen; +}; + +static struct file_st *win32_splitter(DSO *dso, const char *filename, + int assume_last_is_dir) +{ + struct file_st *result = NULL; + enum { IN_NODE, IN_DEVICE, IN_FILE } position; + const char *start = filename; + char last; + + if (!filename) { + DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_NO_FILENAME); + /* + * goto err; + */ + return (NULL); + } + + result = OPENSSL_malloc(sizeof(struct file_st)); + if (result == NULL) { + DSOerr(DSO_F_WIN32_SPLITTER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + memset(result, 0, sizeof(struct file_st)); + position = IN_DEVICE; + + if ((filename[0] == '\\' && filename[1] == '\\') + || (filename[0] == '/' && filename[1] == '/')) { + position = IN_NODE; + filename += 2; + start = filename; + result->node = start; + } + + do { + last = filename[0]; + switch (last) { + case ':': + if (position != IN_DEVICE) { + DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_INCORRECT_FILE_SYNTAX); + /* + * goto err; + */ + OPENSSL_free(result); + return (NULL); + } + result->device = start; + result->devicelen = (int)(filename - start); + position = IN_FILE; + start = ++filename; + result->dir = start; + break; + case '\\': + case '/': + if (position == IN_NODE) { + result->nodelen = (int)(filename - start); + position = IN_FILE; + start = ++filename; + result->dir = start; + } else if (position == IN_DEVICE) { + position = IN_FILE; + filename++; + result->dir = start; + result->dirlen = (int)(filename - start); + start = filename; + } else { + filename++; + result->dirlen += (int)(filename - start); + start = filename; + } + break; + case '\0': + if (position == IN_NODE) { + result->nodelen = (int)(filename - start); + } else { + if (filename - start > 0) { + if (assume_last_is_dir) { + if (position == IN_DEVICE) { + result->dir = start; + result->dirlen = 0; + } + result->dirlen += (int)(filename - start); + } else { + result->file = start; + result->filelen = (int)(filename - start); + } + } + } + break; + default: + filename++; + break; + } + } + while (last); + + if (!result->nodelen) + result->node = NULL; + if (!result->devicelen) + result->device = NULL; + if (!result->dirlen) + result->dir = NULL; + if (!result->filelen) + result->file = NULL; + + return (result); +} + +static char *win32_joiner(DSO *dso, const struct file_st *file_split) +{ + int len = 0, offset = 0; + char *result = NULL; + const char *start; + + if (!file_split) { + DSOerr(DSO_F_WIN32_JOINER, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (file_split->node) { + len += 2 + file_split->nodelen; /* 2 for starting \\ */ + if (file_split->predir || file_split->dir || file_split->file) + len++; /* 1 for ending \ */ + } else if (file_split->device) { + len += file_split->devicelen + 1; /* 1 for ending : */ + } + len += file_split->predirlen; + if (file_split->predir && (file_split->dir || file_split->file)) { + len++; /* 1 for ending \ */ + } + len += file_split->dirlen; + if (file_split->dir && file_split->file) { + len++; /* 1 for ending \ */ + } + len += file_split->filelen; + + if (!len) { + DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE); + return (NULL); + } + + result = OPENSSL_malloc(len + 1); + if (!result) { + DSOerr(DSO_F_WIN32_JOINER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + if (file_split->node) { + strcpy(&result[offset], "\\\\"); + offset += 2; + strncpy(&result[offset], file_split->node, file_split->nodelen); + offset += file_split->nodelen; + if (file_split->predir || file_split->dir || file_split->file) { + result[offset] = '\\'; + offset++; + } + } else if (file_split->device) { + strncpy(&result[offset], file_split->device, file_split->devicelen); + offset += file_split->devicelen; + result[offset] = ':'; + offset++; + } + start = file_split->predir; + while (file_split->predirlen > (start - file_split->predir)) { + const char *end = openssl_strnchr(start, '/', + file_split->predirlen - (start - + file_split->predir)); + if (!end) + end = start + + file_split->predirlen - (start - file_split->predir); + strncpy(&result[offset], start, end - start); + offset += (int)(end - start); + result[offset] = '\\'; + offset++; + start = end + 1; + } +# if 0 /* Not needed, since the directory converter + * above already appeneded a backslash */ + if (file_split->predir && (file_split->dir || file_split->file)) { + result[offset] = '\\'; + offset++; + } +# endif + start = file_split->dir; + while (file_split->dirlen > (start - file_split->dir)) { + const char *end = openssl_strnchr(start, '/', + file_split->dirlen - (start - + file_split->dir)); + if (!end) + end = start + file_split->dirlen - (start - file_split->dir); + strncpy(&result[offset], start, end - start); + offset += (int)(end - start); + result[offset] = '\\'; + offset++; + start = end + 1; + } +# if 0 /* Not needed, since the directory converter + * above already appeneded a backslash */ + if (file_split->dir && file_split->file) { + result[offset] = '\\'; + offset++; + } +# endif + strncpy(&result[offset], file_split->file, file_split->filelen); + offset += file_split->filelen; + result[offset] = '\0'; + return (result); +} + +static char *win32_merger(DSO *dso, const char *filespec1, + const char *filespec2) +{ + char *merged = NULL; + struct file_st *filespec1_split = NULL; + struct file_st *filespec2_split = NULL; + + if (!filespec1 && !filespec2) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (!filespec2) { + merged = OPENSSL_malloc(strlen(filespec1) + 1); + if (!merged) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec1); + } else if (!filespec1) { + merged = OPENSSL_malloc(strlen(filespec2) + 1); + if (!merged) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + } else { + filespec1_split = win32_splitter(dso, filespec1, 0); + if (!filespec1_split) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + filespec2_split = win32_splitter(dso, filespec2, 1); + if (!filespec2_split) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); + OPENSSL_free(filespec1_split); + return (NULL); + } + + /* Fill in into filespec1_split */ + if (!filespec1_split->node && !filespec1_split->device) { + filespec1_split->node = filespec2_split->node; + filespec1_split->nodelen = filespec2_split->nodelen; + filespec1_split->device = filespec2_split->device; + filespec1_split->devicelen = filespec2_split->devicelen; + } + if (!filespec1_split->dir) { + filespec1_split->dir = filespec2_split->dir; + filespec1_split->dirlen = filespec2_split->dirlen; + } else if (filespec1_split->dir[0] != '\\' + && filespec1_split->dir[0] != '/') { + filespec1_split->predir = filespec2_split->dir; + filespec1_split->predirlen = filespec2_split->dirlen; + } + if (!filespec1_split->file) { + filespec1_split->file = filespec2_split->file; + filespec1_split->filelen = filespec2_split->filelen; + } + + merged = win32_joiner(dso, filespec1_split); + } + OPENSSL_free(filespec1_split); + OPENSSL_free(filespec2_split); + return (merged); +} + +static char *win32_name_converter(DSO *dso, const char *filename) +{ + char *translated; + int len, transform; + + len = strlen(filename); + transform = ((strstr(filename, "/") == NULL) && + (strstr(filename, "\\") == NULL) && + (strstr(filename, ":") == NULL)); + if (transform) + /* We will convert this to "%s.dll" */ + translated = OPENSSL_malloc(len + 5); + else + /* We will simply duplicate filename */ + translated = OPENSSL_malloc(len + 1); + if (translated == NULL) { + DSOerr(DSO_F_WIN32_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + return (NULL); + } + if (transform) + sprintf(translated, "%s.dll", filename); + else + sprintf(translated, "%s", filename); + return (translated); +} + +static const char *openssl_strnchr(const char *string, int c, size_t len) +{ + size_t i; + const char *p; + for (i = 0, p = string; i < len && *p; i++, p++) { + if (*p == c) + return p; + } + return NULL; +} + +# include +# ifdef _WIN32_WCE +# define DLLNAME "TOOLHELP.DLL" +# else +# ifdef MODULEENTRY32 +# undef MODULEENTRY32 /* unmask the ASCII version! */ +# endif +# define DLLNAME "KERNEL32.DLL" +# endif + +typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD); +typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE); +typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *); + +static int win32_pathbyaddr(void *addr, char *path, int sz) +{ + HMODULE dll; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + MODULEENTRY32 me32; + CREATETOOLHELP32SNAPSHOT create_snap; + CLOSETOOLHELP32SNAPSHOT close_snap; + MODULE32 module_first, module_next; + + if (addr == NULL) { + union { + int (*f) (void *, char *, int); + void *p; + } t = { + win32_pathbyaddr + }; + addr = t.p; + } + + dll = LoadLibrary(TEXT(DLLNAME)); + if (dll == NULL) { + DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); + return -1; + } + + create_snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(dll, "CreateToolhelp32Snapshot"); + if (create_snap == NULL) { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); + return -1; + } + /* We take the rest for granted... */ +# ifdef _WIN32_WCE + close_snap = (CLOSETOOLHELP32SNAPSHOT) + GetProcAddress(dll, "CloseToolhelp32Snapshot"); +# else + close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle; +# endif + module_first = (MODULE32) GetProcAddress(dll, "Module32First"); + module_next = (MODULE32) GetProcAddress(dll, "Module32Next"); + + hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0); + if (hModuleSnap == INVALID_HANDLE_VALUE) { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); + return -1; + } + + me32.dwSize = sizeof(me32); + + if (!(*module_first) (hModuleSnap, &me32)) { + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_FAILURE); + return -1; + } + + do { + if ((BYTE *) addr >= me32.modBaseAddr && + (BYTE *) addr < me32.modBaseAddr + me32.modBaseSize) { + (*close_snap) (hModuleSnap); + FreeLibrary(dll); +# ifdef _WIN32_WCE +# if _WIN32_WCE >= 101 + return WideCharToMultiByte(CP_ACP, 0, me32.szExePath, -1, + path, sz, NULL, NULL); +# else + { + int i, len = (int)wcslen(me32.szExePath); + if (sz <= 0) + return len + 1; + if (len >= sz) + len = sz - 1; + for (i = 0; i < len; i++) + path[i] = (char)me32.szExePath[i]; + path[len++] = 0; + return len; + } +# endif +# else + { + int len = (int)strlen(me32.szExePath); + if (sz <= 0) + return len + 1; + if (len >= sz) + len = sz - 1; + memcpy(path, me32.szExePath, len); + path[len++] = 0; + return len; + } +# endif + } + } while ((*module_next) (hModuleSnap, &me32)); + + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + return 0; +} + +static void *win32_globallookup(const char *name) +{ + HMODULE dll; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + MODULEENTRY32 me32; + CREATETOOLHELP32SNAPSHOT create_snap; + CLOSETOOLHELP32SNAPSHOT close_snap; + MODULE32 module_first, module_next; + FARPROC ret = NULL; + + dll = LoadLibrary(TEXT(DLLNAME)); + if (dll == NULL) { + DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); + return NULL; + } + + create_snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(dll, "CreateToolhelp32Snapshot"); + if (create_snap == NULL) { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); + return NULL; + } + /* We take the rest for granted... */ +# ifdef _WIN32_WCE + close_snap = (CLOSETOOLHELP32SNAPSHOT) + GetProcAddress(dll, "CloseToolhelp32Snapshot"); +# else + close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle; +# endif + module_first = (MODULE32) GetProcAddress(dll, "Module32First"); + module_next = (MODULE32) GetProcAddress(dll, "Module32Next"); + + hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0); + if (hModuleSnap == INVALID_HANDLE_VALUE) { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); + return NULL; + } + + me32.dwSize = sizeof(me32); + + if (!(*module_first) (hModuleSnap, &me32)) { + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + return NULL; + } + + do { + if ((ret = GetProcAddress(me32.hModule, name))) { + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + return ret; + } + } while ((*module_next) (hModuleSnap, &me32)); + + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + return NULL; +} +#endif /* DSO_WIN32 */ diff --git a/Sources/COpenSSL/dtls1.h b/Sources/COpenSSL/dtls1.h new file mode 100644 index 00000000..0af2fb5b --- /dev/null +++ b/Sources/COpenSSL/dtls1.h @@ -0,0 +1,272 @@ +/* ssl/dtls1.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DTLS1_H +# define HEADER_DTLS1_H + +# include "buffer.h" +# include "pqueue.h" +# ifdef OPENSSL_SYS_VMS +# include +# include +# endif +# ifdef OPENSSL_SYS_WIN32 +/* Needed for struct timeval */ +# include +# elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_) +# include +# else +# if defined(OPENSSL_SYS_VXWORKS) +# include +# else +# include +# endif +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define DTLS1_VERSION 0xFEFF +# define DTLS1_2_VERSION 0xFEFD +# define DTLS_MAX_VERSION DTLS1_2_VERSION +# define DTLS1_VERSION_MAJOR 0xFE + +# define DTLS1_BAD_VER 0x0100 + +/* Special value for method supporting multiple versions */ +# define DTLS_ANY_VERSION 0x1FFFF + +# if 0 +/* this alert description is not specified anywhere... */ +# define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 +# endif + +/* lengths of messages */ +# define DTLS1_COOKIE_LENGTH 256 + +# define DTLS1_RT_HEADER_LENGTH 13 + +# define DTLS1_HM_HEADER_LENGTH 12 + +# define DTLS1_HM_BAD_FRAGMENT -2 +# define DTLS1_HM_FRAGMENT_RETRY -3 + +# define DTLS1_CCS_HEADER_LENGTH 1 + +# ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +# define DTLS1_AL_HEADER_LENGTH 7 +# else +# define DTLS1_AL_HEADER_LENGTH 2 +# endif + +# ifndef OPENSSL_NO_SSL_INTERN + +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP" +# endif + +/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */ +# define DTLS1_MAX_MTU_OVERHEAD 48 + +typedef struct dtls1_bitmap_st { + unsigned long map; /* track 32 packets on 32-bit systems and 64 + * - on 64-bit systems */ + unsigned char max_seq_num[8]; /* max record number seen so far, 64-bit + * value in big-endian encoding */ +} DTLS1_BITMAP; + +struct dtls1_retransmit_state { + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +# else + char *compress; +# endif + SSL_SESSION *session; + unsigned short epoch; +}; + +struct hm_header_st { + unsigned char type; + unsigned long msg_len; + unsigned short seq; + unsigned long frag_off; + unsigned long frag_len; + unsigned int is_ccs; + struct dtls1_retransmit_state saved_retransmit_state; +}; + +struct ccs_header_st { + unsigned char type; + unsigned short seq; +}; + +struct dtls1_timeout_st { + /* Number of read timeouts so far */ + unsigned int read_timeouts; + /* Number of write timeouts so far */ + unsigned int write_timeouts; + /* Number of alerts received so far */ + unsigned int num_alerts; +}; + +typedef struct record_pqueue_st { + unsigned short epoch; + pqueue q; +} record_pqueue; + +typedef struct hm_fragment_st { + struct hm_header_st msg_header; + unsigned char *fragment; + unsigned char *reassembly; +} hm_fragment; + +typedef struct dtls1_state_st { + unsigned int send_cookie; + unsigned char cookie[DTLS1_COOKIE_LENGTH]; + unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; + unsigned int cookie_len; + /* + * The current data and handshake epoch. This is initially + * undefined, and starts at zero once the initial handshake is + * completed + */ + unsigned short r_epoch; + unsigned short w_epoch; + /* records being received in the current epoch */ + DTLS1_BITMAP bitmap; + /* renegotiation starts a new set of sequence numbers */ + DTLS1_BITMAP next_bitmap; + /* handshake message numbers */ + unsigned short handshake_write_seq; + unsigned short next_handshake_write_seq; + unsigned short handshake_read_seq; + /* save last sequence number for retransmissions */ + unsigned char last_write_sequence[8]; + /* Received handshake records (processed and unprocessed) */ + record_pqueue unprocessed_rcds; + record_pqueue processed_rcds; + /* Buffered handshake messages */ + pqueue buffered_messages; + /* Buffered (sent) handshake records */ + pqueue sent_messages; + /* + * Buffered application records. Only for records between CCS and + * Finished to prevent either protocol violation or unnecessary message + * loss. + */ + record_pqueue buffered_app_data; + /* Is set when listening for new connections with dtls1_listen() */ + unsigned int listen; + unsigned int link_mtu; /* max on-the-wire DTLS packet size */ + unsigned int mtu; /* max DTLS packet size */ + struct hm_header_st w_msg_hdr; + struct hm_header_st r_msg_hdr; + struct dtls1_timeout_st timeout; + /* + * Indicates when the last handshake msg or heartbeat sent will timeout + */ + struct timeval next_timeout; + /* Timeout duration */ + unsigned short timeout_duration; + /* + * storage for Alert/Handshake protocol data received but not yet + * processed by ssl3_read_bytes: + */ + unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; + unsigned int handshake_fragment_len; + unsigned int retransmitting; + /* + * Set when the handshake is ready to process peer's ChangeCipherSpec message. + * Cleared after the message has been processed. + */ + unsigned int change_cipher_spec_ok; +# ifndef OPENSSL_NO_SCTP + /* used when SSL_ST_XX_FLUSH is entered */ + int next_state; + int shutdown_received; +# endif +} DTLS1_STATE; + +typedef struct dtls1_record_data_st { + unsigned char *packet; + unsigned int packet_length; + SSL3_BUFFER rbuf; + SSL3_RECORD rrec; +# ifndef OPENSSL_NO_SCTP + struct bio_dgram_sctp_rcvinfo recordinfo; +# endif +} DTLS1_RECORD_DATA; + +# endif + +/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ +# define DTLS1_TMO_READ_COUNT 2 +# define DTLS1_TMO_WRITE_COUNT 2 + +# define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_4758cca.c b/Sources/COpenSSL/e_4758cca.c new file mode 100644 index 00000000..d331c134 --- /dev/null +++ b/Sources/COpenSSL/e_4758cca.c @@ -0,0 +1,960 @@ +/* Author: Maurice Gittens */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "crypto.h" +#include "dso.h" +#include "x509.h" +#include "objects.h" +#include "engine.h" +#include "rand.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#include "bn.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_4758_CCA + +# ifdef FLAT_INC +# include "hw_4758_cca.h" +# else +# include "hw_4758_cca.h" +# endif + +# include "e_4758cca_err.c" + +static int ibm_4758_cca_destroy(ENGINE *e); +static int ibm_4758_cca_init(ENGINE *e); +static int ibm_4758_cca_finish(ENGINE *e); +static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)); + +/* rsa functions */ +/* -------------*/ +# ifndef OPENSSL_NO_RSA +static int cca_rsa_pub_enc(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int cca_rsa_priv_dec(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa); +static int cca_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); + +/* utility functions */ +/* ---------------------*/ +static EVP_PKEY *ibm_4758_load_privkey(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); +static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); + +static int getModulusAndExponent(const unsigned char *token, + long *exponentLength, + unsigned char *exponent, long *modulusLength, + long *modulusFieldLength, + unsigned char *modulus); +# endif + +/* RAND number functions */ +/* ---------------------*/ +static int cca_get_random_bytes(unsigned char *, int); +static int cca_random_status(void); + +# ifndef OPENSSL_NO_RSA +static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +# endif + +/* Function pointers for CCA verbs */ +/* -------------------------------*/ +# ifndef OPENSSL_NO_RSA +static F_KEYRECORDREAD keyRecordRead; +static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate; +static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify; +static F_PUBLICKEYEXTRACT publicKeyExtract; +static F_PKAENCRYPT pkaEncrypt; +static F_PKADECRYPT pkaDecrypt; +# endif +static F_RANDOMNUMBERGENERATE randomNumberGenerate; + +/* static variables */ +/* ----------------*/ +static const char *CCA4758_LIB_NAME = NULL; +static const char *get_CCA4758_LIB_NAME(void) +{ + if (CCA4758_LIB_NAME) + return CCA4758_LIB_NAME; + return CCA_LIB_NAME; +} + +static void free_CCA4758_LIB_NAME(void) +{ + if (CCA4758_LIB_NAME) + OPENSSL_free((void *)CCA4758_LIB_NAME); + CCA4758_LIB_NAME = NULL; +} + +static long set_CCA4758_LIB_NAME(const char *name) +{ + free_CCA4758_LIB_NAME(); + return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0); +} + +# ifndef OPENSSL_NO_RSA +static const char *n_keyRecordRead = CSNDKRR; +static const char *n_digitalSignatureGenerate = CSNDDSG; +static const char *n_digitalSignatureVerify = CSNDDSV; +static const char *n_publicKeyExtract = CSNDPKX; +static const char *n_pkaEncrypt = CSNDPKE; +static const char *n_pkaDecrypt = CSNDPKD; +# endif +static const char *n_randomNumberGenerate = CSNBRNG; + +# ifndef OPENSSL_NO_RSA +static int hndidx = -1; +# endif +static DSO *dso = NULL; + +/* openssl engine initialization structures */ +/* ----------------------------------------*/ + +# define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE +static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = { + {CCA4758_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the '4758cca' shared library", + ENGINE_CMD_FLAG_STRING}, + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +static RSA_METHOD ibm_4758_cca_rsa = { + "IBM 4758 CCA RSA method", + cca_rsa_pub_enc, + NULL, + NULL, + cca_rsa_priv_dec, + NULL, /* rsa_mod_exp, */ + NULL, /* mod_exp_mont, */ + NULL, /* init */ + NULL, /* finish */ + RSA_FLAG_SIGN_VER, /* flags */ + NULL, /* app_data */ + cca_rsa_sign, /* rsa_sign */ + cca_rsa_verify, /* rsa_verify */ + NULL /* rsa_keygen */ +}; +# endif + +static RAND_METHOD ibm_4758_cca_rand = { + /* "IBM 4758 RAND method", */ + NULL, /* seed */ + cca_get_random_bytes, /* get random bytes from the card */ + NULL, /* cleanup */ + NULL, /* add */ + cca_get_random_bytes, /* pseudo rand */ + cca_random_status, /* status */ +}; + +static const char *engine_4758_cca_id = "4758cca"; +static const char *engine_4758_cca_name = + "IBM 4758 CCA hardware engine support"; +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +/* Compatibility hack, the dynamic library uses this form in the path */ +static const char *engine_4758_cca_id_alt = "4758_cca"; +# endif + +/* engine implementation */ +/* ---------------------*/ +static int bind_helper(ENGINE *e) +{ + if (!ENGINE_set_id(e, engine_4758_cca_id) || + !ENGINE_set_name(e, engine_4758_cca_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) || +# endif + !ENGINE_set_RAND(e, &ibm_4758_cca_rand) || + !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) || + !ENGINE_set_init_function(e, ibm_4758_cca_init) || + !ENGINE_set_finish_function(e, ibm_4758_cca_finish) || + !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || + !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || +# endif + !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) + return 0; + /* Ensure the error handling is set up */ + ERR_load_CCA4758_strings(); + return 1; +} + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_4758_cca(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_4758cca(void) +{ + ENGINE *e_4758 = engine_4758_cca(); + if (!e_4758) + return; + ENGINE_add(e_4758); + ENGINE_free(e_4758); + ERR_clear_error(); +} +# endif + +static int ibm_4758_cca_destroy(ENGINE *e) +{ + ERR_unload_CCA4758_strings(); + free_CCA4758_LIB_NAME(); + return 1; +} + +static int ibm_4758_cca_init(ENGINE *e) +{ + if (dso) { + CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED); + goto err; + } + + dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); + if (!dso) { + CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); + goto err; + } +# ifndef OPENSSL_NO_RSA + if (!(keyRecordRead = (F_KEYRECORDREAD) + DSO_bind_func(dso, n_keyRecordRead)) || + !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) + DSO_bind_func(dso, n_randomNumberGenerate)) || + !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) + DSO_bind_func(dso, n_digitalSignatureGenerate)) || + !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) + DSO_bind_func(dso, n_digitalSignatureVerify)) || + !(publicKeyExtract = (F_PUBLICKEYEXTRACT) + DSO_bind_func(dso, n_publicKeyExtract)) || + !(pkaEncrypt = (F_PKAENCRYPT) + DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT) + DSO_bind_func(dso, + n_pkaDecrypt))) + { + CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); + goto err; + } +# else + if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) + DSO_bind_func(dso, n_randomNumberGenerate))) { + CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); + goto err; + } +# endif + +# ifndef OPENSSL_NO_RSA + hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", + NULL, NULL, cca_ex_free); +# endif + + return 1; + err: + if (dso) + DSO_free(dso); + dso = NULL; + +# ifndef OPENSSL_NO_RSA + keyRecordRead = (F_KEYRECORDREAD) 0; + digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; + digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; + publicKeyExtract = (F_PUBLICKEYEXTRACT)0; + pkaEncrypt = (F_PKAENCRYPT) 0; + pkaDecrypt = (F_PKADECRYPT) 0; +# endif + randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; + return 0; +} + +static int ibm_4758_cca_finish(ENGINE *e) +{ + free_CCA4758_LIB_NAME(); + if (!dso) { + CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED); + return 0; + } + if (!DSO_free(dso)) { + CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE); + return 0; + } + dso = NULL; +# ifndef OPENSSL_NO_RSA + keyRecordRead = (F_KEYRECORDREAD) 0; + randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; + digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; + digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; + publicKeyExtract = (F_PUBLICKEYEXTRACT)0; + pkaEncrypt = (F_PKAENCRYPT) 0; + pkaDecrypt = (F_PKADECRYPT) 0; +# endif + randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; + return 1; +} + +static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)) +{ + int initialised = ((dso == NULL) ? 0 : 1); + switch (cmd) { + case CCA4758_CMD_SO_PATH: + if (p == NULL) { + CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (initialised) { + CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED); + return 0; + } + return set_CCA4758_LIB_NAME((const char *)p); + default: + break; + } + CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, + CCA4758_R_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +# ifndef OPENSSL_NO_RSA + +# define MAX_CCA_PKA_TOKEN_SIZE 2500 + +static EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, + void *callback_data) +{ + RSA *rtmp = NULL; + EVP_PKEY *res = NULL; + unsigned char *keyToken = NULL; + unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE]; + long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; + long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; + long returnCode; + long reasonCode; + long exitDataLength = 0; + long ruleArrayLength = 0; + unsigned char exitData[8]; + unsigned char ruleArray[8]; + unsigned char keyLabel[64]; + unsigned long keyLabelLength = strlen(key_id); + unsigned char modulus[256]; + long modulusFieldLength = sizeof(modulus); + long modulusLength = 0; + unsigned char exponent[256]; + long exponentLength = sizeof(exponent); + + if (keyLabelLength > sizeof(keyLabel)) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, + CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return NULL; + } + + memset(keyLabel, ' ', sizeof(keyLabel)); + memcpy(keyLabel, key_id, keyLabelLength); + + keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); + if (!keyToken) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + keyRecordRead(&returnCode, &reasonCode, &exitDataLength, + exitData, &ruleArrayLength, ruleArray, keyLabel, + &keyTokenLength, keyToken + sizeof(long)); + + if (returnCode) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, + CCA4758_R_FAILED_LOADING_PRIVATE_KEY); + goto err; + } + + publicKeyExtract(&returnCode, &reasonCode, &exitDataLength, + exitData, &ruleArrayLength, ruleArray, &keyTokenLength, + keyToken + sizeof(long), &pubKeyTokenLength, + pubKeyToken); + + if (returnCode) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, + CCA4758_R_FAILED_LOADING_PRIVATE_KEY); + goto err; + } + + if (!getModulusAndExponent(pubKeyToken, &exponentLength, + exponent, &modulusLength, &modulusFieldLength, + modulus)) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, + CCA4758_R_FAILED_LOADING_PRIVATE_KEY); + goto err; + } + + (*(long *)keyToken) = keyTokenLength; + rtmp = RSA_new_method(e); + if (rtmp == NULL) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); + + rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); + rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); + rtmp->flags |= RSA_FLAG_EXT_PKEY; + + res = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(res, rtmp); + + return res; + err: + if (keyToken) + OPENSSL_free(keyToken); + return NULL; +} + +static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, + void *callback_data) +{ + RSA *rtmp = NULL; + EVP_PKEY *res = NULL; + unsigned char *keyToken = NULL; + long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; + long returnCode; + long reasonCode; + long exitDataLength = 0; + long ruleArrayLength = 0; + unsigned char exitData[8]; + unsigned char ruleArray[8]; + unsigned char keyLabel[64]; + unsigned long keyLabelLength = strlen(key_id); + unsigned char modulus[512]; + long modulusFieldLength = sizeof(modulus); + long modulusLength = 0; + unsigned char exponent[512]; + long exponentLength = sizeof(exponent); + + if (keyLabelLength > sizeof(keyLabel)) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, + CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return NULL; + } + + memset(keyLabel, ' ', sizeof(keyLabel)); + memcpy(keyLabel, key_id, keyLabelLength); + + keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); + if (!keyToken) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, + &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, + keyToken + sizeof(long)); + + if (returnCode) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength, + exponent, &modulusLength, &modulusFieldLength, + modulus)) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, + CCA4758_R_FAILED_LOADING_PUBLIC_KEY); + goto err; + } + + (*(long *)keyToken) = keyTokenLength; + rtmp = RSA_new_method(e); + if (rtmp == NULL) { + CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); + rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); + rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); + rtmp->flags |= RSA_FLAG_EXT_PKEY; + res = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(res, rtmp); + + return res; + err: + if (keyToken) + OPENSSL_free(keyToken); + return NULL; +} + +static int cca_rsa_pub_enc(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + long returnCode; + long reasonCode; + long lflen = flen; + long exitDataLength = 0; + unsigned char exitData[8]; + long ruleArrayLength = 1; + unsigned char ruleArray[8] = "PKCS-1.2"; + long dataStructureLength = 0; + unsigned char dataStructure[8]; + long outputLength = RSA_size(rsa); + long keyTokenLength; + unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); + + keyTokenLength = *(long *)keyToken; + keyToken += sizeof(long); + + pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData, + &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, + &dataStructureLength, dataStructure, &keyTokenLength, + keyToken, &outputLength, to); + + if (returnCode || reasonCode) + return -(returnCode << 16 | reasonCode); + return outputLength; +} + +static int cca_rsa_priv_dec(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + long returnCode; + long reasonCode; + long lflen = flen; + long exitDataLength = 0; + unsigned char exitData[8]; + long ruleArrayLength = 1; + unsigned char ruleArray[8] = "PKCS-1.2"; + long dataStructureLength = 0; + unsigned char dataStructure[8]; + long outputLength = RSA_size(rsa); + long keyTokenLength; + unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); + + keyTokenLength = *(long *)keyToken; + keyToken += sizeof(long); + + pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData, + &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, + &dataStructureLength, dataStructure, &keyTokenLength, + keyToken, &outputLength, to); + + return (returnCode | reasonCode) ? 0 : 1; +} + +# define SSL_SIG_LEN 36 + +static int cca_rsa_verify(int type, const unsigned char *m, + unsigned int m_len, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa) +{ + long returnCode; + long reasonCode; + long lsiglen = siglen; + long exitDataLength = 0; + unsigned char exitData[8]; + long ruleArrayLength = 1; + unsigned char ruleArray[8] = "PKCS-1.1"; + long keyTokenLength; + unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); + long length = SSL_SIG_LEN; + long keyLength; + unsigned char *hashBuffer = NULL; + X509_SIG sig; + ASN1_TYPE parameter; + X509_ALGOR algorithm; + ASN1_OCTET_STRING digest; + + keyTokenLength = *(long *)keyToken; + keyToken += sizeof(long); + + if (type == NID_md5 || type == NID_sha1) { + sig.algor = &algorithm; + algorithm.algorithm = OBJ_nid2obj(type); + + if (!algorithm.algorithm) { + CCA4758err(CCA4758_F_CCA_RSA_VERIFY, + CCA4758_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + + if (!algorithm.algorithm->length) { + CCA4758err(CCA4758_F_CCA_RSA_VERIFY, + CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); + return 0; + } + + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + algorithm.parameter = ¶meter; + + sig.digest = &digest; + sig.digest->data = (unsigned char *)m; + sig.digest->length = m_len; + + length = i2d_X509_SIG(&sig, NULL); + } + + keyLength = RSA_size(rsa); + + if (length - RSA_PKCS1_PADDING > keyLength) { + CCA4758err(CCA4758_F_CCA_RSA_VERIFY, + CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return 0; + } + + switch (type) { + case NID_md5_sha1: + if (m_len != SSL_SIG_LEN) { + CCA4758err(CCA4758_F_CCA_RSA_VERIFY, + CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return 0; + } + + hashBuffer = (unsigned char *)m; + length = m_len; + break; + case NID_md5: + { + unsigned char *ptr; + ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); + if (!hashBuffer) { + CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); + return 0; + } + + i2d_X509_SIG(&sig, &ptr); + } + break; + case NID_sha1: + { + unsigned char *ptr; + ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); + if (!hashBuffer) { + CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); + return 0; + } + i2d_X509_SIG(&sig, &ptr); + } + break; + default: + return 0; + } + + digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, + exitData, &ruleArrayLength, ruleArray, + &keyTokenLength, keyToken, &length, hashBuffer, + &lsiglen, (unsigned char *)sigbuf); + + if (type == NID_sha1 || type == NID_md5) { + OPENSSL_cleanse(hashBuffer, keyLength + 1); + OPENSSL_free(hashBuffer); + } + + return ((returnCode || reasonCode) ? 0 : 1); +} + +# define SSL_SIG_LEN 36 + +static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa) +{ + long returnCode; + long reasonCode; + long exitDataLength = 0; + unsigned char exitData[8]; + long ruleArrayLength = 1; + unsigned char ruleArray[8] = "PKCS-1.1"; + long outputLength = 256; + long outputBitLength; + long keyTokenLength; + unsigned char *hashBuffer = NULL; + unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); + long length = SSL_SIG_LEN; + long keyLength; + X509_SIG sig; + ASN1_TYPE parameter; + X509_ALGOR algorithm; + ASN1_OCTET_STRING digest; + + keyTokenLength = *(long *)keyToken; + keyToken += sizeof(long); + + if (type == NID_md5 || type == NID_sha1) { + sig.algor = &algorithm; + algorithm.algorithm = OBJ_nid2obj(type); + + if (!algorithm.algorithm) { + CCA4758err(CCA4758_F_CCA_RSA_SIGN, + CCA4758_R_UNKNOWN_ALGORITHM_TYPE); + return 0; + } + + if (!algorithm.algorithm->length) { + CCA4758err(CCA4758_F_CCA_RSA_SIGN, + CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); + return 0; + } + + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + algorithm.parameter = ¶meter; + + sig.digest = &digest; + sig.digest->data = (unsigned char *)m; + sig.digest->length = m_len; + + length = i2d_X509_SIG(&sig, NULL); + } + + keyLength = RSA_size(rsa); + + if (length - RSA_PKCS1_PADDING > keyLength) { + CCA4758err(CCA4758_F_CCA_RSA_SIGN, + CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return 0; + } + + switch (type) { + case NID_md5_sha1: + if (m_len != SSL_SIG_LEN) { + CCA4758err(CCA4758_F_CCA_RSA_SIGN, + CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return 0; + } + hashBuffer = (unsigned char *)m; + length = m_len; + break; + case NID_md5: + { + unsigned char *ptr; + ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); + if (!hashBuffer) { + CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); + return 0; + } + i2d_X509_SIG(&sig, &ptr); + } + break; + case NID_sha1: + { + unsigned char *ptr; + ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); + if (!hashBuffer) { + CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); + return 0; + } + i2d_X509_SIG(&sig, &ptr); + } + break; + default: + return 0; + } + + digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, + exitData, &ruleArrayLength, ruleArray, + &keyTokenLength, keyToken, &length, hashBuffer, + &outputLength, &outputBitLength, sigret); + + if (type == NID_sha1 || type == NID_md5) { + OPENSSL_cleanse(hashBuffer, keyLength + 1); + OPENSSL_free(hashBuffer); + } + + *siglen = outputLength; + + return ((returnCode || reasonCode) ? 0 : 1); +} + +static int getModulusAndExponent(const unsigned char *token, + long *exponentLength, + unsigned char *exponent, long *modulusLength, + long *modulusFieldLength, + unsigned char *modulus) +{ + unsigned long len; + + if (*token++ != (char)0x1E) /* internal PKA token? */ + return 0; + + if (*token++) /* token version must be zero */ + return 0; + + len = *token++; + len = len << 8; + len |= (unsigned char)*token++; + + token += 4; /* skip reserved bytes */ + + if (*token++ == (char)0x04) { + if (*token++) /* token version must be zero */ + return 0; + + len = *token++; + len = len << 8; + len |= (unsigned char)*token++; + + token += 2; /* skip reserved section */ + + len = *token++; + len = len << 8; + len |= (unsigned char)*token++; + + *exponentLength = len; + + len = *token++; + len = len << 8; + len |= (unsigned char)*token++; + + *modulusLength = len; + + len = *token++; + len = len << 8; + len |= (unsigned char)*token++; + + *modulusFieldLength = len; + + memcpy(exponent, token, *exponentLength); + token += *exponentLength; + + memcpy(modulus, token, *modulusFieldLength); + return 1; + } + return 0; +} + +# endif /* OPENSSL_NO_RSA */ + +static int cca_random_status(void) +{ + return 1; +} + +static int cca_get_random_bytes(unsigned char *buf, int num) +{ + long ret_code; + long reason_code; + long exit_data_length; + unsigned char exit_data[4]; + unsigned char form[] = "RANDOM "; + unsigned char rand_buf[8]; + + while (num >= (int)sizeof(rand_buf)) { + randomNumberGenerate(&ret_code, &reason_code, &exit_data_length, + exit_data, form, rand_buf); + if (ret_code) + return 0; + num -= sizeof(rand_buf); + memcpy(buf, rand_buf, sizeof(rand_buf)); + buf += sizeof(rand_buf); + } + + if (num) { + randomNumberGenerate(&ret_code, &reason_code, NULL, NULL, + form, rand_buf); + if (ret_code) + return 0; + memcpy(buf, rand_buf, num); + } + + return 1; +} + +# ifndef OPENSSL_NO_RSA +static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, + long argl, void *argp) +{ + if (item) + OPENSSL_free(item); +} +# endif + +/* Goo to handle building as a dynamic engine */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_4758_cca_id) != 0) && + (strcmp(id, engine_4758_cca_id_alt) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ +# endif /* !OPENSSL_NO_HW_4758_CCA */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_4758cca_err.c b/Sources/COpenSSL/e_4758cca_err.c new file mode 100644 index 00000000..f9d9fe90 --- /dev/null +++ b/Sources/COpenSSL/e_4758cca_err.c @@ -0,0 +1,153 @@ +/* e_4758cca_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_4758cca_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA CCA4758_str_functs[] = { + {ERR_FUNC(CCA4758_F_CCA_RSA_SIGN), "CCA_RSA_SIGN"}, + {ERR_FUNC(CCA4758_F_CCA_RSA_VERIFY), "CCA_RSA_VERIFY"}, + {ERR_FUNC(CCA4758_F_IBM_4758_CCA_CTRL), "IBM_4758_CCA_CTRL"}, + {ERR_FUNC(CCA4758_F_IBM_4758_CCA_FINISH), "IBM_4758_CCA_FINISH"}, + {ERR_FUNC(CCA4758_F_IBM_4758_CCA_INIT), "IBM_4758_CCA_INIT"}, + {ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PRIVKEY), "IBM_4758_LOAD_PRIVKEY"}, + {ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PUBKEY), "IBM_4758_LOAD_PUBKEY"}, + {0, NULL} +}; + +static ERR_STRING_DATA CCA4758_str_reasons[] = { + {ERR_REASON(CCA4758_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD), + "asn1 oid unknown for md"}, + {ERR_REASON(CCA4758_R_COMMAND_NOT_IMPLEMENTED), + "command not implemented"}, + {ERR_REASON(CCA4758_R_DSO_FAILURE), "dso failure"}, + {ERR_REASON(CCA4758_R_FAILED_LOADING_PRIVATE_KEY), + "failed loading private key"}, + {ERR_REASON(CCA4758_R_FAILED_LOADING_PUBLIC_KEY), + "failed loading public key"}, + {ERR_REASON(CCA4758_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL), + "size too large or too small"}, + {ERR_REASON(CCA4758_R_UNIT_FAILURE), "unit failure"}, + {ERR_REASON(CCA4758_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"}, + {0, NULL} +}; + +#endif + +#ifdef CCA4758_LIB_NAME +static ERR_STRING_DATA CCA4758_lib_name[] = { + {0, CCA4758_LIB_NAME}, + {0, NULL} +}; +#endif + +static int CCA4758_lib_error_code = 0; +static int CCA4758_error_init = 1; + +static void ERR_load_CCA4758_strings(void) +{ + if (CCA4758_lib_error_code == 0) + CCA4758_lib_error_code = ERR_get_next_error_library(); + + if (CCA4758_error_init) { + CCA4758_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(CCA4758_lib_error_code, CCA4758_str_functs); + ERR_load_strings(CCA4758_lib_error_code, CCA4758_str_reasons); +#endif + +#ifdef CCA4758_LIB_NAME + CCA4758_lib_name->error = ERR_PACK(CCA4758_lib_error_code, 0, 0); + ERR_load_strings(0, CCA4758_lib_name); +#endif + } +} + +static void ERR_unload_CCA4758_strings(void) +{ + if (CCA4758_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(CCA4758_lib_error_code, CCA4758_str_functs); + ERR_unload_strings(CCA4758_lib_error_code, CCA4758_str_reasons); +#endif + +#ifdef CCA4758_LIB_NAME + ERR_unload_strings(0, CCA4758_lib_name); +#endif + CCA4758_error_init = 1; + } +} + +static void ERR_CCA4758_error(int function, int reason, char *file, int line) +{ + if (CCA4758_lib_error_code == 0) + CCA4758_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(CCA4758_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_4758cca_err.h b/Sources/COpenSSL/e_4758cca_err.h new file mode 100644 index 00000000..2f29d96f --- /dev/null +++ b/Sources/COpenSSL/e_4758cca_err.h @@ -0,0 +1,98 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_CCA4758_ERR_H +# define HEADER_CCA4758_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_CCA4758_strings(void); +static void ERR_unload_CCA4758_strings(void); +static void ERR_CCA4758_error(int function, int reason, char *file, int line); +# define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the CCA4758 functions. */ + +/* Function codes. */ +# define CCA4758_F_CCA_RSA_SIGN 105 +# define CCA4758_F_CCA_RSA_VERIFY 106 +# define CCA4758_F_IBM_4758_CCA_CTRL 100 +# define CCA4758_F_IBM_4758_CCA_FINISH 101 +# define CCA4758_F_IBM_4758_CCA_INIT 102 +# define CCA4758_F_IBM_4758_LOAD_PRIVKEY 103 +# define CCA4758_F_IBM_4758_LOAD_PUBKEY 104 + +/* Reason codes. */ +# define CCA4758_R_ALREADY_LOADED 100 +# define CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD 101 +# define CCA4758_R_COMMAND_NOT_IMPLEMENTED 102 +# define CCA4758_R_DSO_FAILURE 103 +# define CCA4758_R_FAILED_LOADING_PRIVATE_KEY 104 +# define CCA4758_R_FAILED_LOADING_PUBLIC_KEY 105 +# define CCA4758_R_NOT_LOADED 106 +# define CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107 +# define CCA4758_R_UNIT_FAILURE 108 +# define CCA4758_R_UNKNOWN_ALGORITHM_TYPE 109 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_aep.c b/Sources/COpenSSL/e_aep.c new file mode 100644 index 00000000..edf7c229 --- /dev/null +++ b/Sources/COpenSSL/e_aep.c @@ -0,0 +1,1167 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "bn.h" +#include + +#include "e_os2.h" +#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) || defined(__MINGW32__) +# include +# include +#else +# include +typedef int pid_t; +#endif + +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) +# define getpid GetThreadID +extern int GetThreadID(void); +#elif defined(_WIN32) && !defined(__WATCOMC__) +# define getpid _getpid +#endif + +#include "crypto.h" +#include "dso.h" +#include "engine.h" +#include "buffer.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_AEP +# ifdef FLAT_INC +# include "aep.h" +# else +# include "aep.h" +# endif + +# define AEP_LIB_NAME "aep engine" +# define FAIL_TO_SW 0x10101010 + +# include "e_aep_err.c" + +static int aep_init(ENGINE *e); +static int aep_finish(ENGINE *e); +static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); +static int aep_destroy(ENGINE *e); + +static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection); +static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection); +static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection); +static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use); + +/* BIGNUM stuff */ +# ifndef OPENSSL_NO_RSA +static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, + const BIGNUM *dmq1, const BIGNUM *iqmp, + BN_CTX *ctx); +# endif + +/* RSA stuff */ +# ifndef OPENSSL_NO_RSA +static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +# endif + +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +# ifndef OPENSSL_NO_RSA +static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +# endif + +/* DSA stuff */ +# ifndef OPENSSL_NO_DSA +static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont); + +static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +/* DH stuff */ +/* This function is aliased to mod_exp (with the DH and mont dropped). */ +# ifndef OPENSSL_NO_DH +static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +/* rand stuff */ +# ifdef AEPRAND +static int aep_rand(unsigned char *buf, int num); +static int aep_rand_status(void); +# endif + +/* Bignum conversion stuff */ +static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32 *BigNumSize); +static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize, + unsigned char *AEP_BigNum); +static AEP_RV ConvertAEPBigNum(void *ArbBigNum, AEP_U32 BigNumSize, + unsigned char *AEP_BigNum); + +/* The definitions for control commands specific to this engine */ +# define AEP_CMD_SO_PATH ENGINE_CMD_BASE +static const ENGINE_CMD_DEFN aep_cmd_defns[] = { + {AEP_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'aep' shared library", + ENGINE_CMD_FLAG_STRING}, + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD aep_rsa = { + "Aep RSA method", + NULL, /* rsa_pub_encrypt */ + NULL, /* rsa_pub_decrypt */ + NULL, /* rsa_priv_encrypt */ + NULL, /* rsa_priv_encrypt */ + aep_rsa_mod_exp, /* rsa_mod_exp */ + aep_mod_exp_mont, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* rsa_sign */ + NULL, /* rsa_verify */ + NULL /* rsa_keygen */ +}; +# endif + +# ifndef OPENSSL_NO_DSA +/* Our internal DSA_METHOD that we provide pointers to */ +static DSA_METHOD aep_dsa = { + "Aep DSA method", + NULL, /* dsa_do_sign */ + NULL, /* dsa_sign_setup */ + NULL, /* dsa_do_verify */ + aep_dsa_mod_exp, /* dsa_mod_exp */ + aep_mod_exp_dsa, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* dsa_paramgen */ + NULL /* dsa_keygen */ +}; +# endif + +# ifndef OPENSSL_NO_DH +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD aep_dh = { + "Aep DH method", + NULL, + NULL, + aep_mod_exp_dh, + NULL, + NULL, + 0, + NULL, + NULL +}; +# endif + +# ifdef AEPRAND +/* our internal RAND_method that we provide pointers to */ +static RAND_METHOD aep_random = { + /* + * "AEP RAND method", + */ + NULL, + aep_rand, + NULL, + NULL, + aep_rand, + aep_rand_status, +}; +# endif + +/* + * Define an array of structures to hold connections + */ +static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS]; + +/* + * Used to determine if this is a new process + */ +static pid_t recorded_pid = 0; + +# ifdef AEPRAND +static AEP_U8 rand_block[RAND_BLK_SIZE]; +static AEP_U32 rand_block_bytes = 0; +# endif + +/* Constants used when creating the ENGINE */ +static const char *engine_aep_id = "aep"; +static const char *engine_aep_name = "Aep hardware engine support"; + +static int max_key_len = 2176; + +/* + * This internal function is used by ENGINE_aep() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_aep(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif +# ifndef OPENSSL_NO_DSA + const DSA_METHOD *meth2; +# endif +# ifndef OPENSSL_NO_DH + const DH_METHOD *meth3; +# endif + + if (!ENGINE_set_id(e, engine_aep_id) || + !ENGINE_set_name(e, engine_aep_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &aep_rsa) || +# endif +# ifndef OPENSSL_NO_DSA + !ENGINE_set_DSA(e, &aep_dsa) || +# endif +# ifndef OPENSSL_NO_DH + !ENGINE_set_DH(e, &aep_dh) || +# endif +# ifdef AEPRAND + !ENGINE_set_RAND(e, &aep_random) || +# endif + !ENGINE_set_init_function(e, aep_init) || + !ENGINE_set_destroy_function(e, aep_destroy) || + !ENGINE_set_finish_function(e, aep_finish) || + !ENGINE_set_ctrl_function(e, aep_ctrl) || + !ENGINE_set_cmd_defns(e, aep_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + /* + * We know that the "PKCS1_SSLeay()" functions hook properly to the + * aep-specific mod_exp and mod_exp_crt so we use those functions. NB: We + * don't use ENGINE_openssl() or anything "more generic" because + * something like the RSAref code may not hook properly, and if you own + * one of these cards then you have the right to do RSA operations on it + * anyway! + */ + meth1 = RSA_PKCS1_SSLeay(); + aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec; +# endif + +# ifndef OPENSSL_NO_DSA + /* + * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits. + */ + meth2 = DSA_OpenSSL(); + aep_dsa.dsa_do_sign = meth2->dsa_do_sign; + aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup; + aep_dsa.dsa_do_verify = meth2->dsa_do_verify; + + aep_dsa = *DSA_get_default_method(); + aep_dsa.dsa_mod_exp = aep_dsa_mod_exp; + aep_dsa.bn_mod_exp = aep_mod_exp_dsa; +# endif + +# ifndef OPENSSL_NO_DH + /* Much the same for Diffie-Hellman */ + meth3 = DH_OpenSSL(); + aep_dh.generate_key = meth3->generate_key; + aep_dh.compute_key = meth3->compute_key; + aep_dh.bn_mod_exp = meth3->bn_mod_exp; +# endif + + /* Ensure the aep error handling is set up */ + ERR_load_AEPHK_strings(); + + return 1; +} + +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_helper(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_aep_id) != 0)) + return 0; + if (!bind_aep(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) +# else +static ENGINE *engine_aep(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_aep(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_aep(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_aep(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +/* + * This is a process-global DSO handle used for loading and unloading the Aep + * library. NB: This is only set (or unset) during an init() or finish() call + * (reference counts permitting) and they're operating with global locks, so + * this should be thread-safe implicitly. + */ +static DSO *aep_dso = NULL; + +/* + * These are the static string constants for the DSO file name and the + * function symbol names to bind to. + */ +static const char *AEP_LIBNAME = NULL; +static const char *get_AEP_LIBNAME(void) +{ + if (AEP_LIBNAME) + return AEP_LIBNAME; + return "aep"; +} + +static void free_AEP_LIBNAME(void) +{ + if (AEP_LIBNAME) + OPENSSL_free((void *)AEP_LIBNAME); + AEP_LIBNAME = NULL; +} + +static long set_AEP_LIBNAME(const char *name) +{ + free_AEP_LIBNAME(); + return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0); +} + +static const char *AEP_F1 = "AEP_ModExp"; +static const char *AEP_F2 = "AEP_ModExpCrt"; +# ifdef AEPRAND +static const char *AEP_F3 = "AEP_GenRandom"; +# endif +static const char *AEP_F4 = "AEP_Finalize"; +static const char *AEP_F5 = "AEP_Initialize"; +static const char *AEP_F6 = "AEP_OpenConnection"; +static const char *AEP_F7 = "AEP_SetBNCallBacks"; +static const char *AEP_F8 = "AEP_CloseConnection"; + +/* + * These are the function pointers that are (un)set when the library has + * successfully (un)loaded. + */ +static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL; +static t_AEP_CloseConnection *p_AEP_CloseConnection = NULL; +static t_AEP_ModExp *p_AEP_ModExp = NULL; +static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL; +# ifdef AEPRAND +static t_AEP_GenRandom *p_AEP_GenRandom = NULL; +# endif +static t_AEP_Initialize *p_AEP_Initialize = NULL; +static t_AEP_Finalize *p_AEP_Finalize = NULL; +static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL; + +/* (de)initialisation functions. */ +static int aep_init(ENGINE *e) +{ + t_AEP_ModExp *p1; + t_AEP_ModExpCrt *p2; +# ifdef AEPRAND + t_AEP_GenRandom *p3; +# endif + t_AEP_Finalize *p4; + t_AEP_Initialize *p5; + t_AEP_OpenConnection *p6; + t_AEP_SetBNCallBacks *p7; + t_AEP_CloseConnection *p8; + + int to_return = 0; + + if (aep_dso != NULL) { + AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libaep.so. */ + + aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0); + + if (aep_dso == NULL) { + AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_NOT_LOADED); + goto err; + } + + if (!(p1 = (t_AEP_ModExp *) DSO_bind_func(aep_dso, AEP_F1)) || + !(p2 = (t_AEP_ModExpCrt *) DSO_bind_func(aep_dso, AEP_F2)) || +# ifdef AEPRAND + !(p3 = (t_AEP_GenRandom *) DSO_bind_func(aep_dso, AEP_F3)) || +# endif + !(p4 = (t_AEP_Finalize *) DSO_bind_func(aep_dso, AEP_F4)) || + !(p5 = (t_AEP_Initialize *) DSO_bind_func(aep_dso, AEP_F5)) || + !(p6 = (t_AEP_OpenConnection *) DSO_bind_func(aep_dso, AEP_F6)) || + !(p7 = (t_AEP_SetBNCallBacks *) DSO_bind_func(aep_dso, AEP_F7)) || + !(p8 = (t_AEP_CloseConnection *) DSO_bind_func(aep_dso, AEP_F8))) { + AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_NOT_LOADED); + goto err; + } + + /* Copy the pointers */ + + p_AEP_ModExp = p1; + p_AEP_ModExpCrt = p2; +# ifdef AEPRAND + p_AEP_GenRandom = p3; +# endif + p_AEP_Finalize = p4; + p_AEP_Initialize = p5; + p_AEP_OpenConnection = p6; + p_AEP_SetBNCallBacks = p7; + p_AEP_CloseConnection = p8; + + to_return = 1; + + return to_return; + + err: + + if (aep_dso) + DSO_free(aep_dso); + aep_dso = NULL; + + p_AEP_OpenConnection = NULL; + p_AEP_ModExp = NULL; + p_AEP_ModExpCrt = NULL; +# ifdef AEPRAND + p_AEP_GenRandom = NULL; +# endif + p_AEP_Initialize = NULL; + p_AEP_Finalize = NULL; + p_AEP_SetBNCallBacks = NULL; + p_AEP_CloseConnection = NULL; + + return to_return; +} + +/* Destructor (complements the "ENGINE_aep()" constructor) */ +static int aep_destroy(ENGINE *e) +{ + free_AEP_LIBNAME(); + ERR_unload_AEPHK_strings(); + return 1; +} + +static int aep_finish(ENGINE *e) +{ + int to_return = 0, in_use; + AEP_RV rv; + + if (aep_dso == NULL) { + AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_NOT_LOADED); + goto err; + } + + rv = aep_close_all_connections(0, &in_use); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_CLOSE_HANDLES_FAILED); + goto err; + } + if (in_use) { + AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_CONNECTIONS_IN_USE); + goto err; + } + + rv = p_AEP_Finalize(); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_FINALIZE_FAILED); + goto err; + } + + if (!DSO_free(aep_dso)) { + AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_UNIT_FAILURE); + goto err; + } + + aep_dso = NULL; + p_AEP_CloseConnection = NULL; + p_AEP_OpenConnection = NULL; + p_AEP_ModExp = NULL; + p_AEP_ModExpCrt = NULL; +# ifdef AEPRAND + p_AEP_GenRandom = NULL; +# endif + p_AEP_Initialize = NULL; + p_AEP_Finalize = NULL; + p_AEP_SetBNCallBacks = NULL; + + to_return = 1; + err: + return to_return; +} + +static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int initialised = ((aep_dso == NULL) ? 0 : 1); + switch (cmd) { + case AEP_CMD_SO_PATH: + if (p == NULL) { + AEPHKerr(AEPHK_F_AEP_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (initialised) { + AEPHKerr(AEPHK_F_AEP_CTRL, AEPHK_R_ALREADY_LOADED); + return 0; + } + return set_AEP_LIBNAME((const char *)p); + default: + break; + } + AEPHKerr(AEPHK_F_AEP_CTRL, AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + int to_return = 0; + int r_len = 0; + AEP_CONNECTION_HNDL hConnection; + AEP_RV rv; + + r_len = BN_num_bits(m); + + /* Perform in software if modulus is too large for hardware. */ + + if (r_len > max_key_len) { + AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return BN_mod_exp(r, a, p, m, ctx); + } + + /* + * Grab a connection from the pool + */ + rv = aep_get_connection(&hConnection); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_GET_HANDLE_FAILED); + return BN_mod_exp(r, a, p, m, ctx); + } + + /* + * To the card with the mod exp + */ + rv = p_AEP_ModExp(hConnection, (void *)a, (void *)p, (void *)m, (void *)r, + NULL); + + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_MOD_EXP_FAILED); + rv = aep_close_connection(hConnection); + return BN_mod_exp(r, a, p, m, ctx); + } + + /* + * Return the connection to the pool + */ + rv = aep_return_connection(hConnection); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_RETURN_CONNECTION_FAILED); + goto err; + } + + to_return = 1; + err: + return to_return; +} + +# ifndef OPENSSL_NO_RSA +static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, + const BIGNUM *dmq1, const BIGNUM *iqmp, + BN_CTX *ctx) +{ + AEP_RV rv = AEP_R_OK; + AEP_CONNECTION_HNDL hConnection; + + /* + * Grab a connection from the pool + */ + rv = aep_get_connection(&hConnection); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_GET_HANDLE_FAILED); + return FAIL_TO_SW; + } + + /* + * To the card with the mod exp + */ + rv = p_AEP_ModExpCrt(hConnection, (void *)a, (void *)p, (void *)q, + (void *)dmp1, (void *)dmq1, (void *)iqmp, (void *)r, + NULL); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_MOD_EXP_CRT_FAILED); + rv = aep_close_connection(hConnection); + return FAIL_TO_SW; + } + + /* + * Return the connection to the pool + */ + rv = aep_return_connection(hConnection); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_RETURN_CONNECTION_FAILED); + goto err; + } + + err: + return rv; +} +# endif + +# ifdef AEPRAND +static int aep_rand(unsigned char *buf, int len) +{ + AEP_RV rv = AEP_R_OK; + AEP_CONNECTION_HNDL hConnection; + + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + + /* + * Can the request be serviced with what's already in the buffer? + */ + if (len <= rand_block_bytes) { + memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len); + rand_block_bytes -= len; + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } else + /* + * If not the get another block of random bytes + */ + { + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + rv = aep_get_connection(&hConnection); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_HANDLE_FAILED); + goto err_nounlock; + } + + if (len > RAND_BLK_SIZE) { + rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_RANDOM_FAILED); + goto err_nounlock; + } + } else { + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + + rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, + &rand_block[0], NULL); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_RANDOM_FAILED); + + goto err; + } + + rand_block_bytes = RAND_BLK_SIZE; + + memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len); + rand_block_bytes -= len; + + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + + rv = aep_return_connection(hConnection); + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_RETURN_CONNECTION_FAILED); + + goto err_nounlock; + } + } + + return 1; + err: + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + err_nounlock: + return 0; +} + +static int aep_rand_status(void) +{ + return 1; +} +# endif + +# ifndef OPENSSL_NO_RSA +static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) +{ + int to_return = 0; + AEP_RV rv = AEP_R_OK; + + if (!aep_dso) { + AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP, AEPHK_R_NOT_LOADED); + goto err; + } + + /* + * See if we have all the necessary bits for a crt + */ + if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) { + rv = aep_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, rsa->dmq1, + rsa->iqmp, ctx); + + if (rv == FAIL_TO_SW) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); + goto err; + } else if (rv != AEP_R_OK) + goto err; + } else { + if (!rsa->d || !rsa->n) { + AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP, AEPHK_R_MISSING_KEY_COMPONENTS); + goto err; + } + + rv = aep_mod_exp(r0, I, rsa->d, rsa->n, ctx); + if (rv != AEP_R_OK) + goto err; + + } + + to_return = 1; + + err: + return to_return; +} +# endif + +# ifndef OPENSSL_NO_DSA +static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + BIGNUM t; + int to_return = 0; + BN_init(&t); + + /* let rr = a1 ^ p1 mod m */ + if (!aep_mod_exp(rr, a1, p1, m, ctx)) + goto end; + /* let t = a2 ^ p2 mod m */ + if (!aep_mod_exp(&t, a2, p2, m, ctx)) + goto end; + /* let rr = rr * t mod m */ + if (!BN_mod_mul(rr, rr, &t, m, ctx)) + goto end; + to_return = 1; + end: + BN_free(&t); + return to_return; +} + +static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return aep_mod_exp(r, a, p, m, ctx); +} +# endif + +# ifndef OPENSSL_NO_RSA +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return aep_mod_exp(r, a, p, m, ctx); +} +# endif + +# ifndef OPENSSL_NO_DH +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return aep_mod_exp(r, a, p, m, ctx); +} +# endif + +static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection) +{ + int count; + AEP_RV rv = AEP_R_OK; + + /* + * Get the current process id + */ + pid_t curr_pid; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + + curr_pid = getpid(); + + /* + * Check if this is the first time this is being called from the current + * process + */ + if (recorded_pid != curr_pid) { + /* + * Remember our pid so we can check if we're in a new process + */ + recorded_pid = curr_pid; + + /* + * Call Finalize to make sure we have not inherited some data from a + * parent process + */ + p_AEP_Finalize(); + + /* + * Initialise the AEP API + */ + rv = p_AEP_Initialize(NULL); + + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_INIT_FAILURE); + recorded_pid = 0; + goto end; + } + + /* + * Set the AEP big num call back functions + */ + rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum, + &ConvertAEPBigNum); + + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, + AEPHK_R_SETBNCALLBACK_FAILURE); + recorded_pid = 0; + goto end; + } +# ifdef AEPRAND + /* + * Reset the rand byte count + */ + rand_block_bytes = 0; +# endif + + /* + * Init the structures + */ + for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { + aep_app_conn_table[count].conn_state = NotConnected; + aep_app_conn_table[count].conn_hndl = 0; + } + + /* + * Open a connection + */ + rv = p_AEP_OpenConnection(phConnection); + + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_UNIT_FAILURE); + recorded_pid = 0; + goto end; + } + + aep_app_conn_table[0].conn_state = InUse; + aep_app_conn_table[0].conn_hndl = *phConnection; + goto end; + } + /* + * Check the existing connections to see if we can find a free one + */ + for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { + if (aep_app_conn_table[count].conn_state == Connected) { + aep_app_conn_table[count].conn_state = InUse; + *phConnection = aep_app_conn_table[count].conn_hndl; + goto end; + } + } + /* + * If no connections available, we're going to have to try to open a new + * one + */ + for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { + if (aep_app_conn_table[count].conn_state == NotConnected) { + /* + * Open a connection + */ + rv = p_AEP_OpenConnection(phConnection); + + if (rv != AEP_R_OK) { + AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_UNIT_FAILURE); + goto end; + } + + aep_app_conn_table[count].conn_state = InUse; + aep_app_conn_table[count].conn_hndl = *phConnection; + goto end; + } + } + rv = AEP_R_GENERAL_ERROR; + end: + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; +} + +static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection) +{ + int count; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + + /* + * Find the connection item that matches this connection handle + */ + for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { + if (aep_app_conn_table[count].conn_hndl == hConnection) { + aep_app_conn_table[count].conn_state = Connected; + break; + } + } + + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + + return AEP_R_OK; +} + +static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection) +{ + int count; + AEP_RV rv = AEP_R_OK; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + + /* + * Find the connection item that matches this connection handle + */ + for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { + if (aep_app_conn_table[count].conn_hndl == hConnection) { + rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl); + if (rv != AEP_R_OK) + goto end; + aep_app_conn_table[count].conn_state = NotConnected; + aep_app_conn_table[count].conn_hndl = 0; + break; + } + } + + end: + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; +} + +static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use) +{ + int count; + AEP_RV rv = AEP_R_OK; + + *in_use = 0; + if (use_engine_lock) + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { + switch (aep_app_conn_table[count].conn_state) { + case Connected: + rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl); + if (rv != AEP_R_OK) + goto end; + aep_app_conn_table[count].conn_state = NotConnected; + aep_app_conn_table[count].conn_hndl = 0; + break; + case InUse: + (*in_use)++; + break; + case NotConnected: + break; + } + } + end: + if (use_engine_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return rv; +} + +/* + * BigNum call back functions, used to convert OpenSSL bignums into AEP + * bignums. Note only 32bit Openssl build support + */ + +static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32 *BigNumSize) +{ + BIGNUM *bn; + + /* + * Cast the ArbBigNum pointer to our BIGNUM struct + */ + bn = (BIGNUM *)ArbBigNum; + +# ifdef SIXTY_FOUR_BIT_LONG + *BigNumSize = bn->top << 3; +# else + /* + * Size of the bignum in bytes is equal to the bn->top (no of 32 bit + * words) multiplies by 4 + */ + *BigNumSize = bn->top << 2; +# endif + + return AEP_R_OK; +} + +static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize, + unsigned char *AEP_BigNum) +{ + BIGNUM *bn; + +# ifndef SIXTY_FOUR_BIT_LONG + unsigned char *buf; + int i; +# endif + + /* + * Cast the ArbBigNum pointer to our BIGNUM struct + */ + bn = (BIGNUM *)ArbBigNum; + +# ifdef SIXTY_FOUR_BIT_LONG + memcpy(AEP_BigNum, bn->d, BigNumSize); +# else + /* + * Must copy data into a (monotone) least significant byte first format + * performing endian conversion if necessary + */ + for (i = 0; i < bn->top; i++) { + buf = (unsigned char *)&bn->d[i]; + + *((AEP_U32 *)AEP_BigNum) = (AEP_U32) + ((unsigned)buf[1] << 8 | buf[0]) | + ((unsigned)buf[3] << 8 | buf[2]) << 16; + + AEP_BigNum += 4; + } +# endif + + return AEP_R_OK; +} + +/* + * Turn an AEP Big Num back to a user big num + */ +static AEP_RV ConvertAEPBigNum(void *ArbBigNum, AEP_U32 BigNumSize, + unsigned char *AEP_BigNum) +{ + BIGNUM *bn; +# ifndef SIXTY_FOUR_BIT_LONG + int i; +# endif + + bn = (BIGNUM *)ArbBigNum; + + /* + * Expand the result bn so that it can hold our big num. Size is in bits + */ + if (bn_expand(bn, (int)(BigNumSize << 3)) == NULL) + return AEP_R_HOST_MEMORY; + +# ifdef SIXTY_FOUR_BIT_LONG + bn->top = BigNumSize >> 3; + + if ((BigNumSize & 7) != 0) + bn->top++; + + memset(bn->d, 0, bn->top << 3); + + memcpy(bn->d, AEP_BigNum, BigNumSize); +# else + bn->top = BigNumSize >> 2; + + for (i = 0; i < bn->top; i++) { + bn->d[i] = (AEP_U32) + ((unsigned)AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 | + ((unsigned)AEP_BigNum[1] << 8 | AEP_BigNum[0]); + AEP_BigNum += 4; + } +# endif + + return AEP_R_OK; +} + +# endif /* !OPENSSL_NO_HW_AEP */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_aep_err.c b/Sources/COpenSSL/e_aep_err.c new file mode 100644 index 00000000..9023f043 --- /dev/null +++ b/Sources/COpenSSL/e_aep_err.c @@ -0,0 +1,159 @@ +/* e_aep_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_aep_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA AEPHK_str_functs[] = { + {ERR_FUNC(AEPHK_F_AEP_CTRL), "AEP_CTRL"}, + {ERR_FUNC(AEPHK_F_AEP_FINISH), "AEP_FINISH"}, + {ERR_FUNC(AEPHK_F_AEP_GET_CONNECTION), "AEP_GET_CONNECTION"}, + {ERR_FUNC(AEPHK_F_AEP_INIT), "AEP_INIT"}, + {ERR_FUNC(AEPHK_F_AEP_MOD_EXP), "AEP_MOD_EXP"}, + {ERR_FUNC(AEPHK_F_AEP_MOD_EXP_CRT), "AEP_MOD_EXP_CRT"}, + {ERR_FUNC(AEPHK_F_AEP_RAND), "AEP_RAND"}, + {ERR_FUNC(AEPHK_F_AEP_RSA_MOD_EXP), "AEP_RSA_MOD_EXP"}, + {0, NULL} +}; + +static ERR_STRING_DATA AEPHK_str_reasons[] = { + {ERR_REASON(AEPHK_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(AEPHK_R_CLOSE_HANDLES_FAILED), "close handles failed"}, + {ERR_REASON(AEPHK_R_CONNECTIONS_IN_USE), "connections in use"}, + {ERR_REASON(AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(AEPHK_R_FINALIZE_FAILED), "finalize failed"}, + {ERR_REASON(AEPHK_R_GET_HANDLE_FAILED), "get handle failed"}, + {ERR_REASON(AEPHK_R_GET_RANDOM_FAILED), "get random failed"}, + {ERR_REASON(AEPHK_R_INIT_FAILURE), "init failure"}, + {ERR_REASON(AEPHK_R_MISSING_KEY_COMPONENTS), "missing key components"}, + {ERR_REASON(AEPHK_R_MOD_EXP_CRT_FAILED), "mod exp crt failed"}, + {ERR_REASON(AEPHK_R_MOD_EXP_FAILED), "mod exp failed"}, + {ERR_REASON(AEPHK_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(AEPHK_R_OK), "ok"}, + {ERR_REASON(AEPHK_R_RETURN_CONNECTION_FAILED), + "return connection failed"}, + {ERR_REASON(AEPHK_R_SETBNCALLBACK_FAILURE), "setbncallback failure"}, + {ERR_REASON(AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL), + "size too large or too small"}, + {ERR_REASON(AEPHK_R_UNIT_FAILURE), "unit failure"}, + {0, NULL} +}; + +#endif + +#ifdef AEPHK_LIB_NAME +static ERR_STRING_DATA AEPHK_lib_name[] = { + {0, AEPHK_LIB_NAME}, + {0, NULL} +}; +#endif + +static int AEPHK_lib_error_code = 0; +static int AEPHK_error_init = 1; + +static void ERR_load_AEPHK_strings(void) +{ + if (AEPHK_lib_error_code == 0) + AEPHK_lib_error_code = ERR_get_next_error_library(); + + if (AEPHK_error_init) { + AEPHK_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(AEPHK_lib_error_code, AEPHK_str_functs); + ERR_load_strings(AEPHK_lib_error_code, AEPHK_str_reasons); +#endif + +#ifdef AEPHK_LIB_NAME + AEPHK_lib_name->error = ERR_PACK(AEPHK_lib_error_code, 0, 0); + ERR_load_strings(0, AEPHK_lib_name); +#endif + } +} + +static void ERR_unload_AEPHK_strings(void) +{ + if (AEPHK_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(AEPHK_lib_error_code, AEPHK_str_functs); + ERR_unload_strings(AEPHK_lib_error_code, AEPHK_str_reasons); +#endif + +#ifdef AEPHK_LIB_NAME + ERR_unload_strings(0, AEPHK_lib_name); +#endif + AEPHK_error_init = 1; + } +} + +static void ERR_AEPHK_error(int function, int reason, char *file, int line) +{ + if (AEPHK_lib_error_code == 0) + AEPHK_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(AEPHK_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_aep_err.h b/Sources/COpenSSL/e_aep_err.h new file mode 100644 index 00000000..2ed01147 --- /dev/null +++ b/Sources/COpenSSL/e_aep_err.h @@ -0,0 +1,106 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_AEPHK_ERR_H +# define HEADER_AEPHK_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_AEPHK_strings(void); +static void ERR_unload_AEPHK_strings(void); +static void ERR_AEPHK_error(int function, int reason, char *file, int line); +# define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the AEPHK functions. */ + +/* Function codes. */ +# define AEPHK_F_AEP_CTRL 100 +# define AEPHK_F_AEP_FINISH 101 +# define AEPHK_F_AEP_GET_CONNECTION 102 +# define AEPHK_F_AEP_INIT 103 +# define AEPHK_F_AEP_MOD_EXP 104 +# define AEPHK_F_AEP_MOD_EXP_CRT 105 +# define AEPHK_F_AEP_RAND 106 +# define AEPHK_F_AEP_RSA_MOD_EXP 107 + +/* Reason codes. */ +# define AEPHK_R_ALREADY_LOADED 100 +# define AEPHK_R_CLOSE_HANDLES_FAILED 101 +# define AEPHK_R_CONNECTIONS_IN_USE 102 +# define AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 +# define AEPHK_R_FINALIZE_FAILED 104 +# define AEPHK_R_GET_HANDLE_FAILED 105 +# define AEPHK_R_GET_RANDOM_FAILED 106 +# define AEPHK_R_INIT_FAILURE 107 +# define AEPHK_R_MISSING_KEY_COMPONENTS 108 +# define AEPHK_R_MOD_EXP_CRT_FAILED 109 +# define AEPHK_R_MOD_EXP_FAILED 110 +# define AEPHK_R_NOT_LOADED 111 +# define AEPHK_R_OK 112 +# define AEPHK_R_RETURN_CONNECTION_FAILED 113 +# define AEPHK_R_SETBNCALLBACK_FAILURE 114 +# define AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL 116 +# define AEPHK_R_UNIT_FAILURE 115 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_aes.c b/Sources/COpenSSL/e_aes.c new file mode 100644 index 00000000..4ff534b7 --- /dev/null +++ b/Sources/COpenSSL/e_aes.c @@ -0,0 +1,2033 @@ +/* ==================================================================== + * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "opensslconf.h" +#ifndef OPENSSL_NO_AES +#include "crypto.h" +# include "evp.h" +# include "err.h" +# include +# include +# include "aes.h" +# include "evp_locl.h" +# include "modes_lcl.h" +# include "rand.h" + +# undef EVP_CIPH_FLAG_FIPS +# define EVP_CIPH_FLAG_FIPS 0 + +typedef struct { + union { + double align; + AES_KEY ks; + } ks; + block128_f block; + union { + cbc128_f cbc; + ctr128_f ctr; + } stream; +} EVP_AES_KEY; + +typedef struct { + union { + double align; + AES_KEY ks; + } ks; /* AES key schedule to use */ + int key_set; /* Set if key initialised */ + int iv_set; /* Set if an iv is set */ + GCM128_CONTEXT gcm; + unsigned char *iv; /* Temporary IV store */ + int ivlen; /* IV length */ + int taglen; + int iv_gen; /* It is OK to generate IVs */ + int tls_aad_len; /* TLS AAD length */ + ctr128_f ctr; +} EVP_AES_GCM_CTX; + +typedef struct { + union { + double align; + AES_KEY ks; + } ks1, ks2; /* AES key schedules to use */ + XTS128_CONTEXT xts; + void (*stream) (const unsigned char *in, + unsigned char *out, size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +} EVP_AES_XTS_CTX; + +typedef struct { + union { + double align; + AES_KEY ks; + } ks; /* AES key schedule to use */ + int key_set; /* Set if key initialised */ + int iv_set; /* Set if an iv is set */ + int tag_set; /* Set if tag is valid */ + int len_set; /* Set if message length set */ + int L, M; /* L and M parameters from RFC3610 */ + CCM128_CONTEXT ccm; + ccm128_f str; +} EVP_AES_CCM_CTX; + +# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) + +# ifdef VPAES_ASM +int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int vpaes_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void vpaes_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void vpaes_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void vpaes_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); +# endif +# ifdef BSAES_ASM +void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[16], int enc); +void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + const unsigned char ivec[16]); +void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char iv[16]); +void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char iv[16]); +# endif +# ifdef AES_CTR_ASM +void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + const unsigned char ivec[AES_BLOCK_SIZE]); +# endif +# ifdef AES_XTS_ASM +void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +# endif + +# if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) +# include "ppc_arch.h" +# ifdef VPAES_ASM +# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC) +# endif +# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207) +# define HWAES_set_encrypt_key aes_p8_set_encrypt_key +# define HWAES_set_decrypt_key aes_p8_set_decrypt_key +# define HWAES_encrypt aes_p8_encrypt +# define HWAES_decrypt aes_p8_decrypt +# define HWAES_cbc_encrypt aes_p8_cbc_encrypt +# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks +# endif + +# if defined(AES_ASM) && !defined(I386_ONLY) && ( \ + ((defined(__i386) || defined(__i386__) || \ + defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) + +extern unsigned int OPENSSL_ia32cap_P[]; + +# ifdef VPAES_ASM +# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) +# endif +# ifdef BSAES_ASM +# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) +# endif +/* + * AES-NI section + */ +# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) + +int aesni_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int aesni_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void aesni_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void aesni_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void aesni_ecb_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, const AES_KEY *key, int enc); +void aesni_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); + +void aesni_ctr32_encrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, const unsigned char *ivec); + +void aesni_xts_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_xts_decrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_ccm64_encrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void aesni_ccm64_decrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) +size_t aesni_gcm_encrypt(const unsigned char *in, + unsigned char *out, + size_t len, + const void *key, unsigned char ivec[16], u64 *Xi); +# define AES_gcm_encrypt aesni_gcm_encrypt +size_t aesni_gcm_decrypt(const unsigned char *in, + unsigned char *out, + size_t len, + const void *key, unsigned char ivec[16], u64 *Xi); +# define AES_gcm_decrypt aesni_gcm_decrypt +void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in, + size_t len); +# define AES_GCM_ASM(gctx) (gctx->ctr==aesni_ctr32_encrypt_blocks && \ + gctx->gcm.ghash==gcm_ghash_avx) +# define AES_GCM_ASM2(gctx) (gctx->gcm.block==(block128_f)aesni_encrypt && \ + gctx->gcm.ghash==gcm_ghash_avx) +# undef AES_GCM_ASM2 /* minor size optimization */ +# endif + +static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) + && !enc) { + ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data); + dat->block = (block128_f) aesni_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) aesni_cbc_encrypt : NULL; + } else { + ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data); + dat->block = (block128_f) aesni_encrypt; + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; + else + dat->stream.cbc = NULL; + } + + if (ret < 0) { + EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, ctx->encrypt); + + return 1; +} + +static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + size_t bl = ctx->cipher->block_size; + + if (len < bl) + return 1; + + aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt); + + return 1; +} + +# define aesni_ofb_cipher aes_ofb_cipher +static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aesni_cfb_cipher aes_cfb_cipher +static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aesni_cfb8_cipher aes_cfb8_cipher +static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aesni_cfb1_cipher aes_cfb1_cipher +static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aesni_ctr_cipher aes_ctr_cipher +static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt); + gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; + /* + * If we have an iv can set it directly, otherwise use saved IV. + */ + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + /* If key set use IV, otherwise copy */ + if (gctx->key_set) + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + else + memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +# define aesni_gcm_cipher aes_gcm_cipher +static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + if (!iv && !key) + return 1; + + if (key) { + /* key_len is two AES keys */ + if (enc) { + aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) aesni_encrypt; + xctx->stream = aesni_xts_encrypt; + } else { + aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) aesni_decrypt; + xctx->stream = aesni_xts_decrypt; + } + + aesni_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2.ks); + xctx->xts.block2 = (block128_f) aesni_encrypt; + + xctx->xts.key1 = &xctx->ks1; + } + + if (iv) { + xctx->xts.key2 = &xctx->ks2; + memcpy(ctx->iv, iv, 16); + } + + return 1; +} + +# define aesni_xts_cipher aes_xts_cipher +static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) aesni_encrypt); + cctx->str = enc ? (ccm128_f) aesni_ccm64_encrypt_blocks : + (ccm128_f) aesni_ccm64_decrypt_blocks; + cctx->key_set = 1; + } + if (iv) { + memcpy(ctx->iv, iv, 15 - cctx->L); + cctx->iv_set = 1; + } + return 1; +} + +# define aesni_ccm_cipher aes_ccm_cipher +static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +static const EVP_CIPHER aesni_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aesni_init_key, \ + aesni_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL,NULL,NULL,NULL }; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize, \ + keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_init_key, \ + aes_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL,NULL,NULL,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } + +# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ +static const EVP_CIPHER aesni_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aesni_##mode##_init_key, \ + aesni_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL,NULL,aes_##mode##_ctrl,NULL }; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_##mode##_init_key, \ + aes_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL,NULL,aes_##mode##_ctrl,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } + +# elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) + +# include "sparc_arch.h" + +extern unsigned int OPENSSL_sparcv9cap_P[]; + +# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES) + +void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks); +void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks); +void aes_t4_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void aes_t4_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +/* + * Key-length specific subroutines were chosen for following reason. + * Each SPARC T4 core can execute up to 8 threads which share core's + * resources. Loading as much key material to registers allows to + * minimize references to shared memory interface, as well as amount + * of instructions in inner loops [much needed on T4]. But then having + * non-key-length specific routines would require conditional branches + * either in inner loops or on subroutines' entries. Former is hardly + * acceptable, while latter means code size increase to size occupied + * by multiple key-length specfic subroutines, so why fight? + */ +void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec); +void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + unsigned char *ivec); +void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + unsigned char *ivec); +void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + unsigned char *ivec); +void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char *ivec); +void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char *ivec); +void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char *ivec); +void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char *ivec); + +static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode, bits; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + bits = ctx->key_len * 8; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) + && !enc) { + ret = 0; + aes_t4_set_decrypt_key(key, bits, ctx->cipher_data); + dat->block = (block128_f) aes_t4_decrypt; + switch (bits) { + case 128: + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) aes128_t4_cbc_decrypt : NULL; + break; + case 192: + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) aes192_t4_cbc_decrypt : NULL; + break; + case 256: + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) aes256_t4_cbc_decrypt : NULL; + break; + default: + ret = -1; + } + } else { + ret = 0; + aes_t4_set_encrypt_key(key, bits, ctx->cipher_data); + dat->block = (block128_f) aes_t4_encrypt; + switch (bits) { + case 128: + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) aes128_t4_cbc_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) aes128_t4_ctr32_encrypt; + else + dat->stream.cbc = NULL; + break; + case 192: + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) aes192_t4_cbc_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) aes192_t4_ctr32_encrypt; + else + dat->stream.cbc = NULL; + break; + case 256: + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) aes256_t4_cbc_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) aes256_t4_ctr32_encrypt; + else + dat->stream.cbc = NULL; + break; + default: + ret = -1; + } + } + + if (ret < 0) { + EVPerr(EVP_F_AES_T4_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +# define aes_t4_cbc_cipher aes_cbc_cipher +static int aes_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aes_t4_ecb_cipher aes_ecb_cipher +static int aes_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aes_t4_ofb_cipher aes_ofb_cipher +static int aes_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aes_t4_cfb_cipher aes_cfb_cipher +static int aes_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aes_t4_cfb8_cipher aes_cfb8_cipher +static int aes_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aes_t4_cfb1_cipher aes_cfb1_cipher +static int aes_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aes_t4_ctr_cipher aes_ctr_cipher +static int aes_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aes_t4_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + int bits = ctx->key_len * 8; + aes_t4_set_encrypt_key(key, bits, &gctx->ks.ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) aes_t4_encrypt); + switch (bits) { + case 128: + gctx->ctr = (ctr128_f) aes128_t4_ctr32_encrypt; + break; + case 192: + gctx->ctr = (ctr128_f) aes192_t4_ctr32_encrypt; + break; + case 256: + gctx->ctr = (ctr128_f) aes256_t4_ctr32_encrypt; + break; + default: + return 0; + } + /* + * If we have an iv can set it directly, otherwise use saved IV. + */ + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + /* If key set use IV, otherwise copy */ + if (gctx->key_set) + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + else + memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +# define aes_t4_gcm_cipher aes_gcm_cipher +static int aes_t4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + if (!iv && !key) + return 1; + + if (key) { + int bits = ctx->key_len * 4; + xctx->stream = NULL; + /* key_len is two AES keys */ + if (enc) { + aes_t4_set_encrypt_key(key, bits, &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) aes_t4_encrypt; + switch (bits) { + case 128: + xctx->stream = aes128_t4_xts_encrypt; + break; +# if 0 /* not yet */ + case 192: + xctx->stream = aes192_t4_xts_encrypt; + break; +# endif + case 256: + xctx->stream = aes256_t4_xts_encrypt; + break; + default: + return 0; + } + } else { + aes_t4_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) aes_t4_decrypt; + switch (bits) { + case 128: + xctx->stream = aes128_t4_xts_decrypt; + break; +# if 0 /* not yet */ + case 192: + xctx->stream = aes192_t4_xts_decrypt; + break; +# endif + case 256: + xctx->stream = aes256_t4_xts_decrypt; + break; + default: + return 0; + } + } + + aes_t4_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2.ks); + xctx->xts.block2 = (block128_f) aes_t4_encrypt; + + xctx->xts.key1 = &xctx->ks1; + } + + if (iv) { + xctx->xts.key2 = &xctx->ks2; + memcpy(ctx->iv, iv, 16); + } + + return 1; +} + +# define aes_t4_xts_cipher aes_xts_cipher +static int aes_t4_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + int bits = ctx->key_len * 8; + aes_t4_set_encrypt_key(key, bits, &cctx->ks.ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) aes_t4_encrypt); +# if 0 /* not yet */ + switch (bits) { + case 128: + cctx->str = enc ? (ccm128_f) aes128_t4_ccm64_encrypt : + (ccm128_f) ae128_t4_ccm64_decrypt; + break; + case 192: + cctx->str = enc ? (ccm128_f) aes192_t4_ccm64_encrypt : + (ccm128_f) ae192_t4_ccm64_decrypt; + break; + case 256: + cctx->str = enc ? (ccm128_f) aes256_t4_ccm64_encrypt : + (ccm128_f) ae256_t4_ccm64_decrypt; + break; + default: + return 0; + } +# else + cctx->str = NULL; +# endif + cctx->key_set = 1; + } + if (iv) { + memcpy(ctx->iv, iv, 15 - cctx->L); + cctx->iv_set = 1; + } + return 1; +} + +# define aes_t4_ccm_cipher aes_ccm_cipher +static int aes_t4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +static const EVP_CIPHER aes_t4_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_t4_init_key, \ + aes_t4_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL,NULL,NULL,NULL }; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize, \ + keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_init_key, \ + aes_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL,NULL,NULL,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; } + +# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ +static const EVP_CIPHER aes_t4_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_t4_##mode##_init_key, \ + aes_t4_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL,NULL,aes_##mode##_ctrl,NULL }; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_##mode##_init_key, \ + aes_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL,NULL,aes_##mode##_ctrl,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; } + +# else + +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_init_key, \ + aes_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL,NULL,NULL,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return &aes_##keylen##_##mode; } + +# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_##mode##_init_key, \ + aes_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL,NULL,aes_##mode##_ctrl,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return &aes_##keylen##_##mode; } +# endif + +# if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__)) +# include "arm_arch.h" +# if __ARM_MAX_ARCH__>=7 +# if defined(BSAES_ASM) +# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) +# endif +# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) +# define HWAES_set_encrypt_key aes_v8_set_encrypt_key +# define HWAES_set_decrypt_key aes_v8_set_decrypt_key +# define HWAES_encrypt aes_v8_encrypt +# define HWAES_decrypt aes_v8_decrypt +# define HWAES_cbc_encrypt aes_v8_cbc_encrypt +# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks +# endif +# endif + +# if defined(HWAES_CAPABLE) +int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +void HWAES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void HWAES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + const unsigned char ivec[16]); +# endif + +# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ + BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags) + +static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) + && !enc) +# ifdef HWAES_CAPABLE + if (HWAES_CAPABLE) { + ret = HWAES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f) HWAES_decrypt; + dat->stream.cbc = NULL; +# ifdef HWAES_cbc_encrypt + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt; +# endif + } else +# endif +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) { + ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f) AES_decrypt; + dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt; + } else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f) vpaes_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) vpaes_cbc_encrypt : NULL; + } else +# endif + { + ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f) AES_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) AES_cbc_encrypt : NULL; + } else +# ifdef HWAES_CAPABLE + if (HWAES_CAPABLE) { + ret = HWAES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f) HWAES_encrypt; + dat->stream.cbc = NULL; +# ifdef HWAES_cbc_encrypt + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt; + else +# endif +# ifdef HWAES_ctr32_encrypt_blocks + if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks; + else +# endif + (void)0; /* terminate potentially open 'else' */ + } else +# endif +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) { + ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f) AES_encrypt; + dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; + } else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f) vpaes_encrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) vpaes_cbc_encrypt : NULL; + } else +# endif + { + ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f) AES_encrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) AES_cbc_encrypt : NULL; +# ifdef AES_CTR_ASM + if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) AES_ctr32_encrypt; +# endif + } + + if (ret < 0) { + EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + if (dat->stream.cbc) + (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt); + else if (ctx->encrypt) + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); + else + CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block); + + return 1; +} + +static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + size_t bl = ctx->cipher->block_size; + size_t i; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + if (len < bl) + return 1; + + for (i = 0, len -= bl; i <= len; i += bl) + (*dat->block) (in + i, out + i, &dat->ks); + + return 1; +} + +static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, dat->block); + return 1; +} + +static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; +} + +static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; +} + +static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) { + CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; + } + + while (len >= MAXBITCHUNK) { + CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + len -= MAXBITCHUNK; + out += MAXBITCHUNK; + in += MAXBITCHUNK; + } + if (len) + CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + + return 1; +} + +static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + unsigned int num = ctx->num; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + if (dat->stream.ctr) + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, + ctx->iv, ctx->buf, &num, dat->stream.ctr); + else + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, + ctx->iv, ctx->buf, &num, dat->block); + ctx->num = (size_t)num; + return 1; +} + +BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS) + BLOCK_CIPHER_generic_pack(NID_aes, 192, EVP_CIPH_FLAG_FIPS) + BLOCK_CIPHER_generic_pack(NID_aes, 256, EVP_CIPH_FLAG_FIPS) + +static int aes_gcm_cleanup(EVP_CIPHER_CTX *c) +{ + EVP_AES_GCM_CTX *gctx = c->cipher_data; + if (gctx == NULL) + return 0; + OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); + if (gctx->iv != c->iv) + OPENSSL_free(gctx->iv); + return 1; +} + +/* increment counter (64-bit int) by 1 */ +static void ctr64_inc(unsigned char *counter) +{ + int n = 8; + unsigned char c; + + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_GCM_CTX *gctx = c->cipher_data; + switch (type) { + case EVP_CTRL_INIT: + gctx->key_set = 0; + gctx->iv_set = 0; + gctx->ivlen = c->cipher->iv_len; + gctx->iv = c->iv; + gctx->taglen = -1; + gctx->iv_gen = 0; + gctx->tls_aad_len = -1; + return 1; + + case EVP_CTRL_GCM_SET_IVLEN: + if (arg <= 0) + return 0; + /* Allocate memory for IV if needed */ + if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { + if (gctx->iv != c->iv) + OPENSSL_free(gctx->iv); + gctx->iv = OPENSSL_malloc(arg); + if (!gctx->iv) + return 0; + } + gctx->ivlen = arg; + return 1; + + case EVP_CTRL_GCM_SET_TAG: + if (arg <= 0 || arg > 16 || c->encrypt) + return 0; + memcpy(c->buf, ptr, arg); + gctx->taglen = arg; + return 1; + + case EVP_CTRL_GCM_GET_TAG: + if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) + return 0; + memcpy(ptr, c->buf, arg); + return 1; + + case EVP_CTRL_GCM_SET_IV_FIXED: + /* Special case: -1 length restores whole IV */ + if (arg == -1) { + memcpy(gctx->iv, ptr, gctx->ivlen); + gctx->iv_gen = 1; + return 1; + } + /* + * Fixed field must be at least 4 bytes and invocation field at least + * 8. + */ + if ((arg < 4) || (gctx->ivlen - arg) < 8) + return 0; + if (arg) + memcpy(gctx->iv, ptr, arg); + if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) + return 0; + gctx->iv_gen = 1; + return 1; + + case EVP_CTRL_GCM_IV_GEN: + if (gctx->iv_gen == 0 || gctx->key_set == 0) + return 0; + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + if (arg <= 0 || arg > gctx->ivlen) + arg = gctx->ivlen; + memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); + /* + * Invocation field will be at least 8 bytes in size and so no need + * to check wrap around or increment more than last 8 bytes. + */ + ctr64_inc(gctx->iv + gctx->ivlen - 8); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_GCM_SET_IV_INV: + if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) + return 0; + memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_AEAD_TLS1_AAD: + /* Save the AAD for later use */ + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return 0; + memcpy(c->buf, ptr, arg); + gctx->tls_aad_len = arg; + { + unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; + /* Correct length for explicit IV */ + if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN) + return 0; + len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + /* If decrypting correct for tag too */ + if (!c->encrypt) { + if (len < EVP_GCM_TLS_TAG_LEN) + return 0; + len -= EVP_GCM_TLS_TAG_LEN; + } + c->buf[arg - 2] = len >> 8; + c->buf[arg - 1] = len & 0xff; + } + /* Extra padding: tag appended to record */ + return EVP_GCM_TLS_TAG_LEN; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_GCM_CTX *gctx_out = out->cipher_data; + if (gctx->gcm.key) { + if (gctx->gcm.key != &gctx->ks) + return 0; + gctx_out->gcm.key = &gctx_out->ks; + } + if (gctx->iv == c->iv) + gctx_out->iv = out->iv; + else { + gctx_out->iv = OPENSSL_malloc(gctx->ivlen); + if (!gctx_out->iv) + return 0; + memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); + } + return 1; + } + + default: + return -1; + + } +} + +static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + do { +# ifdef HWAES_CAPABLE + if (HWAES_CAPABLE) { + HWAES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) HWAES_encrypt); +# ifdef HWAES_ctr32_encrypt_blocks + gctx->ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks; +# else + gctx->ctr = NULL; +# endif + break; + } else +# endif +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE) { + AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) AES_encrypt); + gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; + break; + } else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + vpaes_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) vpaes_encrypt); + gctx->ctr = NULL; + break; + } else +# endif + (void)0; /* terminate potentially open 'else' */ + + AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) AES_encrypt); +# ifdef AES_CTR_ASM + gctx->ctr = (ctr128_f) AES_ctr32_encrypt; +# else + gctx->ctr = NULL; +# endif + } while (0); + + /* + * If we have an iv can set it directly, otherwise use saved IV. + */ + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + /* If key set use IV, otherwise copy */ + if (gctx->key_set) + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + else + memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +/* + * Handle TLS GCM packet format. This consists of the last portion of the IV + * followed by the payload and finally the tag. On encrypt generate IV, + * encrypt payload and write the tag. On verify retrieve IV, decrypt payload + * and verify tag. + */ + +static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + int rv = -1; + /* Encrypt/decrypt must be performed in place */ + if (out != in + || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) + return -1; + /* + * Set IV from start of buffer or generate IV and write to start of + * buffer. + */ + if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? + EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, + EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) + goto err; + /* Use saved AAD */ + if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) + goto err; + /* Fix buffer and length to point to payload */ + in += EVP_GCM_TLS_EXPLICIT_IV_LEN; + out += EVP_GCM_TLS_EXPLICIT_IV_LEN; + len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + if (ctx->encrypt) { + /* Encrypt payload */ + if (gctx->ctr) { + size_t bulk = 0; +# if defined(AES_GCM_ASM) + if (len >= 32 && AES_GCM_ASM(gctx)) { + if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0)) + return -1; + + bulk = AES_gcm_encrypt(in, out, len, + gctx->gcm.key, + gctx->gcm.Yi.c, gctx->gcm.Xi.u); + gctx->gcm.len.u[1] += bulk; + } +# endif + if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, + in + bulk, + out + bulk, + len - bulk, gctx->ctr)) + goto err; + } else { + size_t bulk = 0; +# if defined(AES_GCM_ASM2) + if (len >= 32 && AES_GCM_ASM2(gctx)) { + if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0)) + return -1; + + bulk = AES_gcm_encrypt(in, out, len, + gctx->gcm.key, + gctx->gcm.Yi.c, gctx->gcm.Xi.u); + gctx->gcm.len.u[1] += bulk; + } +# endif + if (CRYPTO_gcm128_encrypt(&gctx->gcm, + in + bulk, out + bulk, len - bulk)) + goto err; + } + out += len; + /* Finally write tag */ + CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); + rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + } else { + /* Decrypt */ + if (gctx->ctr) { + size_t bulk = 0; +# if defined(AES_GCM_ASM) + if (len >= 16 && AES_GCM_ASM(gctx)) { + if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0)) + return -1; + + bulk = AES_gcm_decrypt(in, out, len, + gctx->gcm.key, + gctx->gcm.Yi.c, gctx->gcm.Xi.u); + gctx->gcm.len.u[1] += bulk; + } +# endif + if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, + in + bulk, + out + bulk, + len - bulk, gctx->ctr)) + goto err; + } else { + size_t bulk = 0; +# if defined(AES_GCM_ASM2) + if (len >= 16 && AES_GCM_ASM2(gctx)) { + if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0)) + return -1; + + bulk = AES_gcm_decrypt(in, out, len, + gctx->gcm.key, + gctx->gcm.Yi.c, gctx->gcm.Xi.u); + gctx->gcm.len.u[1] += bulk; + } +# endif + if (CRYPTO_gcm128_decrypt(&gctx->gcm, + in + bulk, out + bulk, len - bulk)) + goto err; + } + /* Retrieve tag */ + CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); + /* If tag mismatch wipe buffer */ + if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { + OPENSSL_cleanse(out, len); + goto err; + } + rv = len; + } + + err: + gctx->iv_set = 0; + gctx->tls_aad_len = -1; + return rv; +} + +static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + /* If not set up, return error */ + if (!gctx->key_set) + return -1; + + if (gctx->tls_aad_len >= 0) + return aes_gcm_tls_cipher(ctx, out, in, len); + + if (!gctx->iv_set) + return -1; + if (in) { + if (out == NULL) { + if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) + return -1; + } else if (ctx->encrypt) { + if (gctx->ctr) { + size_t bulk = 0; +# if defined(AES_GCM_ASM) + if (len >= 32 && AES_GCM_ASM(gctx)) { + size_t res = (16 - gctx->gcm.mres) % 16; + + if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res)) + return -1; + + bulk = AES_gcm_encrypt(in + res, + out + res, len - res, + gctx->gcm.key, gctx->gcm.Yi.c, + gctx->gcm.Xi.u); + gctx->gcm.len.u[1] += bulk; + bulk += res; + } +# endif + if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, + in + bulk, + out + bulk, + len - bulk, gctx->ctr)) + return -1; + } else { + size_t bulk = 0; +# if defined(AES_GCM_ASM2) + if (len >= 32 && AES_GCM_ASM2(gctx)) { + size_t res = (16 - gctx->gcm.mres) % 16; + + if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res)) + return -1; + + bulk = AES_gcm_encrypt(in + res, + out + res, len - res, + gctx->gcm.key, gctx->gcm.Yi.c, + gctx->gcm.Xi.u); + gctx->gcm.len.u[1] += bulk; + bulk += res; + } +# endif + if (CRYPTO_gcm128_encrypt(&gctx->gcm, + in + bulk, out + bulk, len - bulk)) + return -1; + } + } else { + if (gctx->ctr) { + size_t bulk = 0; +# if defined(AES_GCM_ASM) + if (len >= 16 && AES_GCM_ASM(gctx)) { + size_t res = (16 - gctx->gcm.mres) % 16; + + if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res)) + return -1; + + bulk = AES_gcm_decrypt(in + res, + out + res, len - res, + gctx->gcm.key, + gctx->gcm.Yi.c, gctx->gcm.Xi.u); + gctx->gcm.len.u[1] += bulk; + bulk += res; + } +# endif + if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, + in + bulk, + out + bulk, + len - bulk, gctx->ctr)) + return -1; + } else { + size_t bulk = 0; +# if defined(AES_GCM_ASM2) + if (len >= 16 && AES_GCM_ASM2(gctx)) { + size_t res = (16 - gctx->gcm.mres) % 16; + + if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res)) + return -1; + + bulk = AES_gcm_decrypt(in + res, + out + res, len - res, + gctx->gcm.key, + gctx->gcm.Yi.c, gctx->gcm.Xi.u); + gctx->gcm.len.u[1] += bulk; + bulk += res; + } +# endif + if (CRYPTO_gcm128_decrypt(&gctx->gcm, + in + bulk, out + bulk, len - bulk)) + return -1; + } + } + return len; + } else { + if (!ctx->encrypt) { + if (gctx->taglen < 0) + return -1; + if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) + return -1; + gctx->iv_set = 0; + return 0; + } + CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); + gctx->taglen = 16; + /* Don't reuse the IV */ + gctx->iv_set = 0; + return 0; + } + +} + +# define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ + | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ + | EVP_CIPH_CUSTOM_COPY) + +BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM, + EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | + CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM, + EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | + CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM, + EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | + CUSTOM_FLAGS) + +static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_XTS_CTX *xctx = c->cipher_data; + if (type == EVP_CTRL_COPY) { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_XTS_CTX *xctx_out = out->cipher_data; + if (xctx->xts.key1) { + if (xctx->xts.key1 != &xctx->ks1) + return 0; + xctx_out->xts.key1 = &xctx_out->ks1; + } + if (xctx->xts.key2) { + if (xctx->xts.key2 != &xctx->ks2) + return 0; + xctx_out->xts.key2 = &xctx_out->ks2; + } + return 1; + } else if (type != EVP_CTRL_INIT) + return -1; + /* key1 and key2 are used as an indicator both key and IV are set */ + xctx->xts.key1 = NULL; + xctx->xts.key2 = NULL; + return 1; +} + +static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + if (!iv && !key) + return 1; + + if (key) + do { +# ifdef AES_XTS_ASM + xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; +# else + xctx->stream = NULL; +# endif + /* key_len is two AES keys */ +# ifdef HWAES_CAPABLE + if (HWAES_CAPABLE) { + if (enc) { + HWAES_set_encrypt_key(key, ctx->key_len * 4, + &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) HWAES_encrypt; + } else { + HWAES_set_decrypt_key(key, ctx->key_len * 4, + &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) HWAES_decrypt; + } + + HWAES_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2.ks); + xctx->xts.block2 = (block128_f) HWAES_encrypt; + + xctx->xts.key1 = &xctx->ks1; + break; + } else +# endif +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE) + xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt; + else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + if (enc) { + vpaes_set_encrypt_key(key, ctx->key_len * 4, + &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) vpaes_encrypt; + } else { + vpaes_set_decrypt_key(key, ctx->key_len * 4, + &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) vpaes_decrypt; + } + + vpaes_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2.ks); + xctx->xts.block2 = (block128_f) vpaes_encrypt; + + xctx->xts.key1 = &xctx->ks1; + break; + } else +# endif + (void)0; /* terminate potentially open 'else' */ + + if (enc) { + AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) AES_encrypt; + } else { + AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); + xctx->xts.block1 = (block128_f) AES_decrypt; + } + + AES_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2.ks); + xctx->xts.block2 = (block128_f) AES_encrypt; + + xctx->xts.key1 = &xctx->ks1; + } while (0); + + if (iv) { + xctx->xts.key2 = &xctx->ks2; + memcpy(ctx->iv, iv, 16); + } + + return 1; +} + +static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + if (!xctx->xts.key1 || !xctx->xts.key2) + return 0; + if (!out || !in || len < AES_BLOCK_SIZE) + return 0; + if (xctx->stream) + (*xctx->stream) (in, out, len, + xctx->xts.key1, xctx->xts.key2, ctx->iv); + else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, + ctx->encrypt)) + return 0; + return 1; +} + +# define aes_xts_cleanup NULL + +# define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ + | EVP_CIPH_CUSTOM_COPY) + +BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, + EVP_CIPH_FLAG_FIPS | XTS_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, + EVP_CIPH_FLAG_FIPS | XTS_FLAGS) + +static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_CCM_CTX *cctx = c->cipher_data; + switch (type) { + case EVP_CTRL_INIT: + cctx->key_set = 0; + cctx->iv_set = 0; + cctx->L = 8; + cctx->M = 12; + cctx->tag_set = 0; + cctx->len_set = 0; + return 1; + + case EVP_CTRL_CCM_SET_IVLEN: + arg = 15 - arg; + case EVP_CTRL_CCM_SET_L: + if (arg < 2 || arg > 8) + return 0; + cctx->L = arg; + return 1; + + case EVP_CTRL_CCM_SET_TAG: + if ((arg & 1) || arg < 4 || arg > 16) + return 0; + if (c->encrypt && ptr) + return 0; + if (ptr) { + cctx->tag_set = 1; + memcpy(c->buf, ptr, arg); + } + cctx->M = arg; + return 1; + + case EVP_CTRL_CCM_GET_TAG: + if (!c->encrypt || !cctx->tag_set) + return 0; + if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) + return 0; + cctx->tag_set = 0; + cctx->iv_set = 0; + cctx->len_set = 0; + return 1; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_CCM_CTX *cctx_out = out->cipher_data; + if (cctx->ccm.key) { + if (cctx->ccm.key != &cctx->ks) + return 0; + cctx_out->ccm.key = &cctx_out->ks; + } + return 1; + } + + default: + return -1; + + } +} + +static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) + do { +# ifdef HWAES_CAPABLE + if (HWAES_CAPABLE) { + HWAES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks); + + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) HWAES_encrypt); + cctx->str = NULL; + cctx->key_set = 1; + break; + } else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + vpaes_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) vpaes_encrypt); + cctx->str = NULL; + cctx->key_set = 1; + break; + } +# endif + AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) AES_encrypt); + cctx->str = NULL; + cctx->key_set = 1; + } while (0); + if (iv) { + memcpy(ctx->iv, iv, 15 - cctx->L); + cctx->iv_set = 1; + } + return 1; +} + +static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + CCM128_CONTEXT *ccm = &cctx->ccm; + /* If not set up, return error */ + if (!cctx->iv_set && !cctx->key_set) + return -1; + if (!ctx->encrypt && !cctx->tag_set) + return -1; + if (!out) { + if (!in) { + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) + return -1; + cctx->len_set = 1; + return len; + } + /* If have AAD need message length */ + if (!cctx->len_set && len) + return -1; + CRYPTO_ccm128_aad(ccm, in, len); + return len; + } + /* EVP_*Final() doesn't return any data */ + if (!in) + return 0; + /* If not set length yet do it */ + if (!cctx->len_set) { + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) + return -1; + cctx->len_set = 1; + } + if (ctx->encrypt) { + if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, + cctx->str) : + CRYPTO_ccm128_encrypt(ccm, in, out, len)) + return -1; + cctx->tag_set = 1; + return len; + } else { + int rv = -1; + if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, + cctx->str) : + !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { + unsigned char tag[16]; + if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { + if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M)) + rv = len; + } + } + if (rv == -1) + OPENSSL_cleanse(out, len); + cctx->iv_set = 0; + cctx->tag_set = 0; + cctx->len_set = 0; + return rv; + } + +} + +# define aes_ccm_cleanup NULL + +BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, + EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, + EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, + EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) +#endif +typedef struct { + union { + double align; + AES_KEY ks; + } ks; + /* Indicates if IV has been set */ + unsigned char *iv; +} EVP_AES_WRAP_CTX; + +static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_WRAP_CTX *wctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + if (ctx->encrypt) + AES_set_encrypt_key(key, ctx->key_len * 8, &wctx->ks.ks); + else + AES_set_decrypt_key(key, ctx->key_len * 8, &wctx->ks.ks); + if (!iv) + wctx->iv = NULL; + } + if (iv) { + memcpy(ctx->iv, iv, 8); + wctx->iv = ctx->iv; + } + return 1; +} + +static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inlen) +{ + EVP_AES_WRAP_CTX *wctx = ctx->cipher_data; + size_t rv; + if (!in) + return 0; + if (inlen % 8) + return -1; + if (ctx->encrypt && inlen < 8) + return -1; + if (!ctx->encrypt && inlen < 16) + return -1; + if (!out) { + if (ctx->encrypt) + return inlen + 8; + else + return inlen - 8; + } + if (ctx->encrypt) + rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen, + (block128_f) AES_encrypt); + else + rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv, out, in, inlen, + (block128_f) AES_decrypt); + return rv ? (int)rv : -1; +} + +#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \ + | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1) + +static const EVP_CIPHER aes_128_wrap = { + NID_id_aes128_wrap, + 8, 16, 8, WRAP_FLAGS, + aes_wrap_init_key, aes_wrap_cipher, + NULL, + sizeof(EVP_AES_WRAP_CTX), + NULL, NULL, NULL, NULL +}; + +const EVP_CIPHER *EVP_aes_128_wrap(void) +{ + return &aes_128_wrap; +} + +static const EVP_CIPHER aes_192_wrap = { + NID_id_aes192_wrap, + 8, 24, 8, WRAP_FLAGS, + aes_wrap_init_key, aes_wrap_cipher, + NULL, + sizeof(EVP_AES_WRAP_CTX), + NULL, NULL, NULL, NULL +}; + +const EVP_CIPHER *EVP_aes_192_wrap(void) +{ + return &aes_192_wrap; +} + +static const EVP_CIPHER aes_256_wrap = { + NID_id_aes256_wrap, + 8, 32, 8, WRAP_FLAGS, + aes_wrap_init_key, aes_wrap_cipher, + NULL, + sizeof(EVP_AES_WRAP_CTX), + NULL, NULL, NULL, NULL +}; + +const EVP_CIPHER *EVP_aes_256_wrap(void) +{ + return &aes_256_wrap; +} diff --git a/Sources/COpenSSL/e_aes_cbc_hmac_sha1.c b/Sources/COpenSSL/e_aes_cbc_hmac_sha1.c new file mode 100644 index 00000000..79ba5257 --- /dev/null +++ b/Sources/COpenSSL/e_aes_cbc_hmac_sha1.c @@ -0,0 +1,1015 @@ +/* ==================================================================== + * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "opensslconf.h" + +#include +#include + +#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1) + +# include "evp.h" +# include "objects.h" +# include "aes.h" +# include "sha.h" +# include "rand.h" +# include "modes_lcl.h" +# include "constant_time_locl.h" + +# ifndef EVP_CIPH_FLAG_AEAD_CIPHER +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +# endif + +# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1) +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0 +# endif + +# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 +# endif + +# define TLS1_1_VERSION 0x0302 + +typedef struct { + AES_KEY ks; + SHA_CTX head, tail, md; + size_t payload_length; /* AAD length in decrypt case */ + union { + unsigned int tls_ver; + unsigned char tls_aad[16]; /* 13 used */ + } aux; +} EVP_AES_HMAC_SHA1; + +# define NO_PAYLOAD_LENGTH ((size_t)-1) + +# if defined(AES_ASM) && ( \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) + +extern unsigned int OPENSSL_ia32cap_P[]; +# define AESNI_CAPABLE (1<<(57-32)) + +int aesni_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int aesni_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void aesni_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); + +void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks, + const AES_KEY *key, unsigned char iv[16], + SHA_CTX *ctx, const void *in0); + +void aesni256_cbc_sha1_dec(const void *inp, void *out, size_t blocks, + const AES_KEY *key, unsigned char iv[16], + SHA_CTX *ctx, const void *in0); + +# define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data) + +static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *inkey, + const unsigned char *iv, int enc) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + int ret; + + if (enc) + ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks); + else + ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks); + + SHA1_Init(&key->head); /* handy when benchmarking */ + key->tail = key->head; + key->md = key->head; + + key->payload_length = NO_PAYLOAD_LENGTH; + + return ret < 0 ? 0 : 1; +} + +# define STITCHED_CALL +# undef STITCHED_DECRYPT_CALL + +# if !defined(STITCHED_CALL) +# define aes_off 0 +# endif + +void sha1_block_data_order(void *c, const void *p, size_t len); + +static void sha1_update(SHA_CTX *c, const void *data, size_t len) +{ + const unsigned char *ptr = data; + size_t res; + + if ((res = c->num)) { + res = SHA_CBLOCK - res; + if (len < res) + res = len; + SHA1_Update(c, ptr, res); + ptr += res; + len -= res; + } + + res = len % SHA_CBLOCK; + len -= res; + + if (len) { + sha1_block_data_order(c, ptr, len / SHA_CBLOCK); + + ptr += len; + c->Nh += len >> 29; + c->Nl += len <<= 3; + if (c->Nl < (unsigned int)len) + c->Nh++; + } + + if (res) + SHA1_Update(c, ptr, res); +} + +# ifdef SHA1_Update +# undef SHA1_Update +# endif +# define SHA1_Update sha1_update + +# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + +typedef struct { + unsigned int A[8], B[8], C[8], D[8], E[8]; +} SHA1_MB_CTX; +typedef struct { + const unsigned char *ptr; + int blocks; +} HASH_DESC; + +void sha1_multi_block(SHA1_MB_CTX *, const HASH_DESC *, int); + +typedef struct { + const unsigned char *inp; + unsigned char *out; + int blocks; + u64 iv[2]; +} CIPH_DESC; + +void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int); + +static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key, + unsigned char *out, + const unsigned char *inp, + size_t inp_len, int n4x) +{ /* n4x is 1 or 2 */ + HASH_DESC hash_d[8], edges[8]; + CIPH_DESC ciph_d[8]; + unsigned char storage[sizeof(SHA1_MB_CTX) + 32]; + union { + u64 q[16]; + u32 d[32]; + u8 c[128]; + } blocks[8]; + SHA1_MB_CTX *ctx; + unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed = + 0; + size_t ret = 0; + u8 *IVs; +# if defined(BSWAP8) + u64 seqnum; +# endif + + /* ask for IVs in bulk */ + if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0) + return 0; + + ctx = (SHA1_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); /* align */ + + frag = (unsigned int)inp_len >> (1 + n4x); + last = (unsigned int)inp_len + frag - (frag << (1 + n4x)); + if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) { + frag++; + last -= x4 - 1; + } + + packlen = 5 + 16 + ((frag + 20 + 16) & -16); + + /* populate descriptors with pointers and IVs */ + hash_d[0].ptr = inp; + ciph_d[0].inp = inp; + /* 5+16 is place for header and explicit IV */ + ciph_d[0].out = out + 5 + 16; + memcpy(ciph_d[0].out - 16, IVs, 16); + memcpy(ciph_d[0].iv, IVs, 16); + IVs += 16; + + for (i = 1; i < x4; i++) { + ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag; + ciph_d[i].out = ciph_d[i - 1].out + packlen; + memcpy(ciph_d[i].out - 16, IVs, 16); + memcpy(ciph_d[i].iv, IVs, 16); + IVs += 16; + } + +# if defined(BSWAP8) + memcpy(blocks[0].c, key->md.data, 8); + seqnum = BSWAP8(blocks[0].q[0]); +# endif + for (i = 0; i < x4; i++) { + unsigned int len = (i == (x4 - 1) ? last : frag); +# if !defined(BSWAP8) + unsigned int carry, j; +# endif + + ctx->A[i] = key->md.h0; + ctx->B[i] = key->md.h1; + ctx->C[i] = key->md.h2; + ctx->D[i] = key->md.h3; + ctx->E[i] = key->md.h4; + + /* fix seqnum */ +# if defined(BSWAP8) + blocks[i].q[0] = BSWAP8(seqnum + i); +# else + for (carry = i, j = 8; j--;) { + blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry; + carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1); + } +# endif + blocks[i].c[8] = ((u8 *)key->md.data)[8]; + blocks[i].c[9] = ((u8 *)key->md.data)[9]; + blocks[i].c[10] = ((u8 *)key->md.data)[10]; + /* fix length */ + blocks[i].c[11] = (u8)(len >> 8); + blocks[i].c[12] = (u8)(len); + + memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13); + hash_d[i].ptr += 64 - 13; + hash_d[i].blocks = (len - (64 - 13)) / 64; + + edges[i].ptr = blocks[i].c; + edges[i].blocks = 1; + } + + /* hash 13-byte headers and first 64-13 bytes of inputs */ + sha1_multi_block(ctx, edges, n4x); + /* hash bulk inputs */ +# define MAXCHUNKSIZE 2048 +# if MAXCHUNKSIZE%64 +# error "MAXCHUNKSIZE is not divisible by 64" +# elif MAXCHUNKSIZE + /* + * goal is to minimize pressure on L1 cache by moving in shorter steps, + * so that hashed data is still in the cache by the time we encrypt it + */ + minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64; + if (minblocks > MAXCHUNKSIZE / 64) { + for (i = 0; i < x4; i++) { + edges[i].ptr = hash_d[i].ptr; + edges[i].blocks = MAXCHUNKSIZE / 64; + ciph_d[i].blocks = MAXCHUNKSIZE / 16; + } + do { + sha1_multi_block(ctx, edges, n4x); + aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); + + for (i = 0; i < x4; i++) { + edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE; + hash_d[i].blocks -= MAXCHUNKSIZE / 64; + edges[i].blocks = MAXCHUNKSIZE / 64; + ciph_d[i].inp += MAXCHUNKSIZE; + ciph_d[i].out += MAXCHUNKSIZE; + ciph_d[i].blocks = MAXCHUNKSIZE / 16; + memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16); + } + processed += MAXCHUNKSIZE; + minblocks -= MAXCHUNKSIZE / 64; + } while (minblocks > MAXCHUNKSIZE / 64); + } +# endif +# undef MAXCHUNKSIZE + sha1_multi_block(ctx, hash_d, n4x); + + memset(blocks, 0, sizeof(blocks)); + for (i = 0; i < x4; i++) { + unsigned int len = (i == (x4 - 1) ? last : frag), + off = hash_d[i].blocks * 64; + const unsigned char *ptr = hash_d[i].ptr + off; + + off = (len - processed) - (64 - 13) - off; /* remainder actually */ + memcpy(blocks[i].c, ptr, off); + blocks[i].c[off] = 0x80; + len += 64 + 13; /* 64 is HMAC header */ + len *= 8; /* convert to bits */ + if (off < (64 - 8)) { +# ifdef BSWAP4 + blocks[i].d[15] = BSWAP4(len); +# else + PUTU32(blocks[i].c + 60, len); +# endif + edges[i].blocks = 1; + } else { +# ifdef BSWAP4 + blocks[i].d[31] = BSWAP4(len); +# else + PUTU32(blocks[i].c + 124, len); +# endif + edges[i].blocks = 2; + } + edges[i].ptr = blocks[i].c; + } + + /* hash input tails and finalize */ + sha1_multi_block(ctx, edges, n4x); + + memset(blocks, 0, sizeof(blocks)); + for (i = 0; i < x4; i++) { +# ifdef BSWAP4 + blocks[i].d[0] = BSWAP4(ctx->A[i]); + ctx->A[i] = key->tail.h0; + blocks[i].d[1] = BSWAP4(ctx->B[i]); + ctx->B[i] = key->tail.h1; + blocks[i].d[2] = BSWAP4(ctx->C[i]); + ctx->C[i] = key->tail.h2; + blocks[i].d[3] = BSWAP4(ctx->D[i]); + ctx->D[i] = key->tail.h3; + blocks[i].d[4] = BSWAP4(ctx->E[i]); + ctx->E[i] = key->tail.h4; + blocks[i].c[20] = 0x80; + blocks[i].d[15] = BSWAP4((64 + 20) * 8); +# else + PUTU32(blocks[i].c + 0, ctx->A[i]); + ctx->A[i] = key->tail.h0; + PUTU32(blocks[i].c + 4, ctx->B[i]); + ctx->B[i] = key->tail.h1; + PUTU32(blocks[i].c + 8, ctx->C[i]); + ctx->C[i] = key->tail.h2; + PUTU32(blocks[i].c + 12, ctx->D[i]); + ctx->D[i] = key->tail.h3; + PUTU32(blocks[i].c + 16, ctx->E[i]); + ctx->E[i] = key->tail.h4; + blocks[i].c[20] = 0x80; + PUTU32(blocks[i].c + 60, (64 + 20) * 8); +# endif + edges[i].ptr = blocks[i].c; + edges[i].blocks = 1; + } + + /* finalize MACs */ + sha1_multi_block(ctx, edges, n4x); + + for (i = 0; i < x4; i++) { + unsigned int len = (i == (x4 - 1) ? last : frag), pad, j; + unsigned char *out0 = out; + + memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed); + ciph_d[i].inp = ciph_d[i].out; + + out += 5 + 16 + len; + + /* write MAC */ + PUTU32(out + 0, ctx->A[i]); + PUTU32(out + 4, ctx->B[i]); + PUTU32(out + 8, ctx->C[i]); + PUTU32(out + 12, ctx->D[i]); + PUTU32(out + 16, ctx->E[i]); + out += 20; + len += 20; + + /* pad */ + pad = 15 - len % 16; + for (j = 0; j <= pad; j++) + *(out++) = pad; + len += pad + 1; + + ciph_d[i].blocks = (len - processed) / 16; + len += 16; /* account for explicit iv */ + + /* arrange header */ + out0[0] = ((u8 *)key->md.data)[8]; + out0[1] = ((u8 *)key->md.data)[9]; + out0[2] = ((u8 *)key->md.data)[10]; + out0[3] = (u8)(len >> 8); + out0[4] = (u8)(len); + + ret += len + 5; + inp += frag; + } + + aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); + + OPENSSL_cleanse(blocks, sizeof(blocks)); + OPENSSL_cleanse(ctx, sizeof(*ctx)); + + return ret; +} +# endif + +static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + unsigned int l; + size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and + * later */ + sha_off = 0; +# if defined(STITCHED_CALL) + size_t aes_off = 0, blocks; + + sha_off = SHA_CBLOCK - key->md.num; +# endif + + key->payload_length = NO_PAYLOAD_LENGTH; + + if (len % AES_BLOCK_SIZE) + return 0; + + if (ctx->encrypt) { + if (plen == NO_PAYLOAD_LENGTH) + plen = len; + else if (len != + ((plen + SHA_DIGEST_LENGTH + + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)) + return 0; + else if (key->aux.tls_ver >= TLS1_1_VERSION) + iv = AES_BLOCK_SIZE; + +# if defined(STITCHED_CALL) + if (plen > (sha_off + iv) + && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) { + SHA1_Update(&key->md, in + iv, sha_off); + + aesni_cbc_sha1_enc(in, out, blocks, &key->ks, + ctx->iv, &key->md, in + iv + sha_off); + blocks *= SHA_CBLOCK; + aes_off += blocks; + sha_off += blocks; + key->md.Nh += blocks >> 29; + key->md.Nl += blocks <<= 3; + if (key->md.Nl < (unsigned int)blocks) + key->md.Nh++; + } else { + sha_off = 0; + } +# endif + sha_off += iv; + SHA1_Update(&key->md, in + sha_off, plen - sha_off); + + if (plen != len) { /* "TLS" mode of operation */ + if (in != out) + memcpy(out + aes_off, in + aes_off, plen - aes_off); + + /* calculate HMAC and append it to payload */ + SHA1_Final(out + plen, &key->md); + key->md = key->tail; + SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH); + SHA1_Final(out + plen, &key->md); + + /* pad the payload|hmac */ + plen += SHA_DIGEST_LENGTH; + for (l = len - plen - 1; plen < len; plen++) + out[plen] = l; + /* encrypt HMAC|padding at once */ + aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, + &key->ks, ctx->iv, 1); + } else { + aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, + &key->ks, ctx->iv, 1); + } + } else { + union { + unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)]; + unsigned char c[32 + SHA_DIGEST_LENGTH]; + } mac, *pmac; + + /* arrange cache line alignment */ + pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32)); + + if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ + size_t inp_len, mask, j, i; + unsigned int res, maxpad, pad, bitlen; + int ret = 1; + union { + unsigned int u[SHA_LBLOCK]; + unsigned char c[SHA_CBLOCK]; + } *data = (void *)key->md.data; +# if defined(STITCHED_DECRYPT_CALL) + unsigned char tail_iv[AES_BLOCK_SIZE]; + int stitch = 0; +# endif + + if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3]) + >= TLS1_1_VERSION) { + if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1)) + return 0; + + /* omit explicit iv */ + memcpy(ctx->iv, in, AES_BLOCK_SIZE); + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + len -= AES_BLOCK_SIZE; + } else if (len < (SHA_DIGEST_LENGTH + 1)) + return 0; + +# if defined(STITCHED_DECRYPT_CALL) + if (len >= 1024 && ctx->key_len == 32) { + /* decrypt last block */ + memcpy(tail_iv, in + len - 2 * AES_BLOCK_SIZE, + AES_BLOCK_SIZE); + aesni_cbc_encrypt(in + len - AES_BLOCK_SIZE, + out + len - AES_BLOCK_SIZE, AES_BLOCK_SIZE, + &key->ks, tail_iv, 0); + stitch = 1; + } else +# endif + /* decrypt HMAC|padding at once */ + aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); + + /* figure out payload length */ + pad = out[len - 1]; + maxpad = len - (SHA_DIGEST_LENGTH + 1); + maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); + maxpad &= 255; + + mask = constant_time_ge(maxpad, pad); + ret &= mask; + /* + * If pad is invalid then we will fail the above test but we must + * continue anyway because we are in constant time code. However, + * we'll use the maxpad value instead of the supplied pad to make + * sure we perform well defined pointer arithmetic. + */ + pad = constant_time_select(mask, pad, maxpad); + + inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); + + key->aux.tls_aad[plen - 2] = inp_len >> 8; + key->aux.tls_aad[plen - 1] = inp_len; + + /* calculate HMAC */ + key->md = key->head; + SHA1_Update(&key->md, key->aux.tls_aad, plen); + +# if defined(STITCHED_DECRYPT_CALL) + if (stitch) { + blocks = (len - (256 + 32 + SHA_CBLOCK)) / SHA_CBLOCK; + aes_off = len - AES_BLOCK_SIZE - blocks * SHA_CBLOCK; + sha_off = SHA_CBLOCK - plen; + + aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0); + + SHA1_Update(&key->md, out, sha_off); + aesni256_cbc_sha1_dec(in + aes_off, + out + aes_off, blocks, &key->ks, + ctx->iv, &key->md, out + sha_off); + + sha_off += blocks *= SHA_CBLOCK; + out += sha_off; + len -= sha_off; + inp_len -= sha_off; + + key->md.Nl += (blocks << 3); /* at most 18 bits */ + memcpy(ctx->iv, tail_iv, AES_BLOCK_SIZE); + } +# endif + +# if 1 + len -= SHA_DIGEST_LENGTH; /* amend mac */ + if (len >= (256 + SHA_CBLOCK)) { + j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK); + j += SHA_CBLOCK - key->md.num; + SHA1_Update(&key->md, out, j); + out += j; + len -= j; + inp_len -= j; + } + + /* but pretend as if we hashed padded payload */ + bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */ +# ifdef BSWAP4 + bitlen = BSWAP4(bitlen); +# else + mac.c[0] = 0; + mac.c[1] = (unsigned char)(bitlen >> 16); + mac.c[2] = (unsigned char)(bitlen >> 8); + mac.c[3] = (unsigned char)bitlen; + bitlen = mac.u[0]; +# endif + + pmac->u[0] = 0; + pmac->u[1] = 0; + pmac->u[2] = 0; + pmac->u[3] = 0; + pmac->u[4] = 0; + + for (res = key->md.num, j = 0; j < len; j++) { + size_t c = out[j]; + mask = (j - inp_len) >> (sizeof(j) * 8 - 8); + c &= mask; + c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8)); + data->c[res++] = (unsigned char)c; + + if (res != SHA_CBLOCK) + continue; + + /* j is not incremented yet */ + mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1)); + data->u[SHA_LBLOCK - 1] |= bitlen & mask; + sha1_block_data_order(&key->md, data, 1); + mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + res = 0; + } + + for (i = res; i < SHA_CBLOCK; i++, j++) + data->c[i] = 0; + + if (res > SHA_CBLOCK - 8) { + mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1)); + data->u[SHA_LBLOCK - 1] |= bitlen & mask; + sha1_block_data_order(&key->md, data, 1); + mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + + memset(data, 0, SHA_CBLOCK); + j += 64; + } + data->u[SHA_LBLOCK - 1] = bitlen; + sha1_block_data_order(&key->md, data, 1); + mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + +# ifdef BSWAP4 + pmac->u[0] = BSWAP4(pmac->u[0]); + pmac->u[1] = BSWAP4(pmac->u[1]); + pmac->u[2] = BSWAP4(pmac->u[2]); + pmac->u[3] = BSWAP4(pmac->u[3]); + pmac->u[4] = BSWAP4(pmac->u[4]); +# else + for (i = 0; i < 5; i++) { + res = pmac->u[i]; + pmac->c[4 * i + 0] = (unsigned char)(res >> 24); + pmac->c[4 * i + 1] = (unsigned char)(res >> 16); + pmac->c[4 * i + 2] = (unsigned char)(res >> 8); + pmac->c[4 * i + 3] = (unsigned char)res; + } +# endif + len += SHA_DIGEST_LENGTH; +# else + SHA1_Update(&key->md, out, inp_len); + res = key->md.num; + SHA1_Final(pmac->c, &key->md); + + { + unsigned int inp_blocks, pad_blocks; + + /* but pretend as if we hashed padded payload */ + inp_blocks = + 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); + res += (unsigned int)(len - inp_len); + pad_blocks = res / SHA_CBLOCK; + res %= SHA_CBLOCK; + pad_blocks += + 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); + for (; inp_blocks < pad_blocks; inp_blocks++) + sha1_block_data_order(&key->md, data, 1); + } +# endif + key->md = key->tail; + SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH); + SHA1_Final(pmac->c, &key->md); + + /* verify HMAC */ + out += inp_len; + len -= inp_len; +# if 1 + { + unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH; + size_t off = out - p; + unsigned int c, cmask; + + maxpad += SHA_DIGEST_LENGTH; + for (res = 0, i = 0, j = 0; j < maxpad; j++) { + c = p[j]; + cmask = + ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) * + 8 - 1); + res |= (c ^ pad) & ~cmask; /* ... and padding */ + cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1); + res |= (c ^ pmac->c[i]) & cmask; + i += 1 & cmask; + } + maxpad -= SHA_DIGEST_LENGTH; + + res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); + ret &= (int)~res; + } +# else + for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++) + res |= out[i] ^ pmac->c[i]; + res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); + ret &= (int)~res; + + /* verify padding */ + pad = (pad & ~res) | (maxpad & res); + out = out + len - 1 - pad; + for (res = 0, i = 0; i < pad; i++) + res |= out[i] ^ pad; + + res = (0 - res) >> (sizeof(res) * 8 - 1); + ret &= (int)~res; +# endif + return ret; + } else { +# if defined(STITCHED_DECRYPT_CALL) + if (len >= 1024 && ctx->key_len == 32) { + if (sha_off %= SHA_CBLOCK) + blocks = (len - 3 * SHA_CBLOCK) / SHA_CBLOCK; + else + blocks = (len - 2 * SHA_CBLOCK) / SHA_CBLOCK; + aes_off = len - blocks * SHA_CBLOCK; + + aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0); + SHA1_Update(&key->md, out, sha_off); + aesni256_cbc_sha1_dec(in + aes_off, + out + aes_off, blocks, &key->ks, + ctx->iv, &key->md, out + sha_off); + + sha_off += blocks *= SHA_CBLOCK; + out += sha_off; + len -= sha_off; + + key->md.Nh += blocks >> 29; + key->md.Nl += blocks <<= 3; + if (key->md.Nl < (unsigned int)blocks) + key->md.Nh++; + } else +# endif + /* decrypt HMAC|padding at once */ + aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); + + SHA1_Update(&key->md, out, len); + } + } + + return 1; +} + +static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, + void *ptr) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + + switch (type) { + case EVP_CTRL_AEAD_SET_MAC_KEY: + { + unsigned int i; + unsigned char hmac_key[64]; + + memset(hmac_key, 0, sizeof(hmac_key)); + + if (arg > (int)sizeof(hmac_key)) { + SHA1_Init(&key->head); + SHA1_Update(&key->head, ptr, arg); + SHA1_Final(hmac_key, &key->head); + } else { + memcpy(hmac_key, ptr, arg); + } + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36; /* ipad */ + SHA1_Init(&key->head); + SHA1_Update(&key->head, hmac_key, sizeof(hmac_key)); + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ + SHA1_Init(&key->tail); + SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key)); + + OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); + + return 1; + } + case EVP_CTRL_AEAD_TLS1_AAD: + { + unsigned char *p = ptr; + unsigned int len; + + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return -1; + + len = p[arg - 2] << 8 | p[arg - 1]; + + if (ctx->encrypt) { + key->payload_length = len; + if ((key->aux.tls_ver = + p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { + if (len < AES_BLOCK_SIZE) + return 0; + len -= AES_BLOCK_SIZE; + p[arg - 2] = len >> 8; + p[arg - 1] = len; + } + key->md = key->head; + SHA1_Update(&key->md, p, arg); + + return (int)(((len + SHA_DIGEST_LENGTH + + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) + - len); + } else { + memcpy(key->aux.tls_aad, ptr, arg); + key->payload_length = arg; + + return SHA_DIGEST_LENGTH; + } + } +# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: + return (int)(5 + 16 + ((arg + 20 + 16) & -16)); + case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: + { + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = + (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; + unsigned int n4x = 1, x4; + unsigned int frag, last, packlen, inp_len; + + if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) + return -1; + + inp_len = param->inp[11] << 8 | param->inp[12]; + + if (ctx->encrypt) { + if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION) + return -1; + + if (inp_len) { + if (inp_len < 4096) + return 0; /* too short */ + + if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5)) + n4x = 2; /* AVX2 */ + } else if ((n4x = param->interleave / 4) && n4x <= 2) + inp_len = param->len; + else + return -1; + + key->md = key->head; + SHA1_Update(&key->md, param->inp, 13); + + x4 = 4 * n4x; + n4x += 1; + + frag = inp_len >> n4x; + last = inp_len + frag - (frag << n4x); + if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) { + frag++; + last -= x4 - 1; + } + + packlen = 5 + 16 + ((frag + 20 + 16) & -16); + packlen = (packlen << n4x) - packlen; + packlen += 5 + 16 + ((last + 20 + 16) & -16); + + param->interleave = x4; + + return (int)packlen; + } else + return -1; /* not yet */ + } + case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: + { + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = + (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; + + return (int)tls1_1_multi_block_encrypt(key, param->out, + param->inp, param->len, + param->interleave / 4); + } + case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT: +# endif + default: + return -1; + } +} + +static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = { +# ifdef NID_aes_128_cbc_hmac_sha1 + NID_aes_128_cbc_hmac_sha1, +# else + NID_undef, +# endif + 16, 16, 16, + EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | + EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, + aesni_cbc_hmac_sha1_init_key, + aesni_cbc_hmac_sha1_cipher, + NULL, + sizeof(EVP_AES_HMAC_SHA1), + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, + aesni_cbc_hmac_sha1_ctrl, + NULL +}; + +static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = { +# ifdef NID_aes_256_cbc_hmac_sha1 + NID_aes_256_cbc_hmac_sha1, +# else + NID_undef, +# endif + 16, 32, 16, + EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | + EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, + aesni_cbc_hmac_sha1_init_key, + aesni_cbc_hmac_sha1_cipher, + NULL, + sizeof(EVP_AES_HMAC_SHA1), + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, + aesni_cbc_hmac_sha1_ctrl, + NULL +}; + +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) +{ + return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? + &aesni_128_cbc_hmac_sha1_cipher : NULL); +} + +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) +{ + return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? + &aesni_256_cbc_hmac_sha1_cipher : NULL); +} +# else +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) +{ + return NULL; +} + +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) +{ + return NULL; +} +# endif +#endif diff --git a/Sources/COpenSSL/e_aes_cbc_hmac_sha256.c b/Sources/COpenSSL/e_aes_cbc_hmac_sha256.c new file mode 100644 index 00000000..33614040 --- /dev/null +++ b/Sources/COpenSSL/e_aes_cbc_hmac_sha256.c @@ -0,0 +1,996 @@ +/* ==================================================================== + * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "opensslconf.h" + +#include +#include + +#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA256) + +# include "evp.h" +# include "objects.h" +# include "aes.h" +# include "sha.h" +# include "rand.h" +# include "modes_lcl.h" +# include "constant_time_locl.h" + +# ifndef EVP_CIPH_FLAG_AEAD_CIPHER +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +# endif + +# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1) +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0 +# endif + +# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 +# endif + +# define TLS1_1_VERSION 0x0302 + +typedef struct { + AES_KEY ks; + SHA256_CTX head, tail, md; + size_t payload_length; /* AAD length in decrypt case */ + union { + unsigned int tls_ver; + unsigned char tls_aad[16]; /* 13 used */ + } aux; +} EVP_AES_HMAC_SHA256; + +# define NO_PAYLOAD_LENGTH ((size_t)-1) + +# if defined(AES_ASM) && ( \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) + +extern unsigned int OPENSSL_ia32cap_P[]; +# define AESNI_CAPABLE (1<<(57-32)) + +int aesni_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int aesni_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void aesni_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); + +int aesni_cbc_sha256_enc(const void *inp, void *out, size_t blocks, + const AES_KEY *key, unsigned char iv[16], + SHA256_CTX *ctx, const void *in0); + +# define data(ctx) ((EVP_AES_HMAC_SHA256 *)(ctx)->cipher_data) + +static int aesni_cbc_hmac_sha256_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *inkey, + const unsigned char *iv, int enc) +{ + EVP_AES_HMAC_SHA256 *key = data(ctx); + int ret; + + if (enc) + memset(&key->ks, 0, sizeof(key->ks.rd_key)), + ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks); + else + ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks); + + SHA256_Init(&key->head); /* handy when benchmarking */ + key->tail = key->head; + key->md = key->head; + + key->payload_length = NO_PAYLOAD_LENGTH; + + return ret < 0 ? 0 : 1; +} + +# define STITCHED_CALL + +# if !defined(STITCHED_CALL) +# define aes_off 0 +# endif + +void sha256_block_data_order(void *c, const void *p, size_t len); + +static void sha256_update(SHA256_CTX *c, const void *data, size_t len) +{ + const unsigned char *ptr = data; + size_t res; + + if ((res = c->num)) { + res = SHA256_CBLOCK - res; + if (len < res) + res = len; + SHA256_Update(c, ptr, res); + ptr += res; + len -= res; + } + + res = len % SHA256_CBLOCK; + len -= res; + + if (len) { + sha256_block_data_order(c, ptr, len / SHA256_CBLOCK); + + ptr += len; + c->Nh += len >> 29; + c->Nl += len <<= 3; + if (c->Nl < (unsigned int)len) + c->Nh++; + } + + if (res) + SHA256_Update(c, ptr, res); +} + +# ifdef SHA256_Update +# undef SHA256_Update +# endif +# define SHA256_Update sha256_update + +# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + +typedef struct { + unsigned int A[8], B[8], C[8], D[8], E[8], F[8], G[8], H[8]; +} SHA256_MB_CTX; +typedef struct { + const unsigned char *ptr; + int blocks; +} HASH_DESC; + +void sha256_multi_block(SHA256_MB_CTX *, const HASH_DESC *, int); + +typedef struct { + const unsigned char *inp; + unsigned char *out; + int blocks; + u64 iv[2]; +} CIPH_DESC; + +void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int); + +static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA256 *key, + unsigned char *out, + const unsigned char *inp, + size_t inp_len, int n4x) +{ /* n4x is 1 or 2 */ + HASH_DESC hash_d[8], edges[8]; + CIPH_DESC ciph_d[8]; + unsigned char storage[sizeof(SHA256_MB_CTX) + 32]; + union { + u64 q[16]; + u32 d[32]; + u8 c[128]; + } blocks[8]; + SHA256_MB_CTX *ctx; + unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed = + 0; + size_t ret = 0; + u8 *IVs; +# if defined(BSWAP8) + u64 seqnum; +# endif + + /* ask for IVs in bulk */ + if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0) + return 0; + + /* align */ + ctx = (SHA256_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); + + frag = (unsigned int)inp_len >> (1 + n4x); + last = (unsigned int)inp_len + frag - (frag << (1 + n4x)); + if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) { + frag++; + last -= x4 - 1; + } + + packlen = 5 + 16 + ((frag + 32 + 16) & -16); + + /* populate descriptors with pointers and IVs */ + hash_d[0].ptr = inp; + ciph_d[0].inp = inp; + /* 5+16 is place for header and explicit IV */ + ciph_d[0].out = out + 5 + 16; + memcpy(ciph_d[0].out - 16, IVs, 16); + memcpy(ciph_d[0].iv, IVs, 16); + IVs += 16; + + for (i = 1; i < x4; i++) { + ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag; + ciph_d[i].out = ciph_d[i - 1].out + packlen; + memcpy(ciph_d[i].out - 16, IVs, 16); + memcpy(ciph_d[i].iv, IVs, 16); + IVs += 16; + } + +# if defined(BSWAP8) + memcpy(blocks[0].c, key->md.data, 8); + seqnum = BSWAP8(blocks[0].q[0]); +# endif + for (i = 0; i < x4; i++) { + unsigned int len = (i == (x4 - 1) ? last : frag); +# if !defined(BSWAP8) + unsigned int carry, j; +# endif + + ctx->A[i] = key->md.h[0]; + ctx->B[i] = key->md.h[1]; + ctx->C[i] = key->md.h[2]; + ctx->D[i] = key->md.h[3]; + ctx->E[i] = key->md.h[4]; + ctx->F[i] = key->md.h[5]; + ctx->G[i] = key->md.h[6]; + ctx->H[i] = key->md.h[7]; + + /* fix seqnum */ +# if defined(BSWAP8) + blocks[i].q[0] = BSWAP8(seqnum + i); +# else + for (carry = i, j = 8; j--;) { + blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry; + carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1); + } +# endif + blocks[i].c[8] = ((u8 *)key->md.data)[8]; + blocks[i].c[9] = ((u8 *)key->md.data)[9]; + blocks[i].c[10] = ((u8 *)key->md.data)[10]; + /* fix length */ + blocks[i].c[11] = (u8)(len >> 8); + blocks[i].c[12] = (u8)(len); + + memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13); + hash_d[i].ptr += 64 - 13; + hash_d[i].blocks = (len - (64 - 13)) / 64; + + edges[i].ptr = blocks[i].c; + edges[i].blocks = 1; + } + + /* hash 13-byte headers and first 64-13 bytes of inputs */ + sha256_multi_block(ctx, edges, n4x); + /* hash bulk inputs */ +# define MAXCHUNKSIZE 2048 +# if MAXCHUNKSIZE%64 +# error "MAXCHUNKSIZE is not divisible by 64" +# elif MAXCHUNKSIZE + /* + * goal is to minimize pressure on L1 cache by moving in shorter steps, + * so that hashed data is still in the cache by the time we encrypt it + */ + minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64; + if (minblocks > MAXCHUNKSIZE / 64) { + for (i = 0; i < x4; i++) { + edges[i].ptr = hash_d[i].ptr; + edges[i].blocks = MAXCHUNKSIZE / 64; + ciph_d[i].blocks = MAXCHUNKSIZE / 16; + } + do { + sha256_multi_block(ctx, edges, n4x); + aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); + + for (i = 0; i < x4; i++) { + edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE; + hash_d[i].blocks -= MAXCHUNKSIZE / 64; + edges[i].blocks = MAXCHUNKSIZE / 64; + ciph_d[i].inp += MAXCHUNKSIZE; + ciph_d[i].out += MAXCHUNKSIZE; + ciph_d[i].blocks = MAXCHUNKSIZE / 16; + memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16); + } + processed += MAXCHUNKSIZE; + minblocks -= MAXCHUNKSIZE / 64; + } while (minblocks > MAXCHUNKSIZE / 64); + } +# endif +# undef MAXCHUNKSIZE + sha256_multi_block(ctx, hash_d, n4x); + + memset(blocks, 0, sizeof(blocks)); + for (i = 0; i < x4; i++) { + unsigned int len = (i == (x4 - 1) ? last : frag), + off = hash_d[i].blocks * 64; + const unsigned char *ptr = hash_d[i].ptr + off; + + off = (len - processed) - (64 - 13) - off; /* remainder actually */ + memcpy(blocks[i].c, ptr, off); + blocks[i].c[off] = 0x80; + len += 64 + 13; /* 64 is HMAC header */ + len *= 8; /* convert to bits */ + if (off < (64 - 8)) { +# ifdef BSWAP4 + blocks[i].d[15] = BSWAP4(len); +# else + PUTU32(blocks[i].c + 60, len); +# endif + edges[i].blocks = 1; + } else { +# ifdef BSWAP4 + blocks[i].d[31] = BSWAP4(len); +# else + PUTU32(blocks[i].c + 124, len); +# endif + edges[i].blocks = 2; + } + edges[i].ptr = blocks[i].c; + } + + /* hash input tails and finalize */ + sha256_multi_block(ctx, edges, n4x); + + memset(blocks, 0, sizeof(blocks)); + for (i = 0; i < x4; i++) { +# ifdef BSWAP4 + blocks[i].d[0] = BSWAP4(ctx->A[i]); + ctx->A[i] = key->tail.h[0]; + blocks[i].d[1] = BSWAP4(ctx->B[i]); + ctx->B[i] = key->tail.h[1]; + blocks[i].d[2] = BSWAP4(ctx->C[i]); + ctx->C[i] = key->tail.h[2]; + blocks[i].d[3] = BSWAP4(ctx->D[i]); + ctx->D[i] = key->tail.h[3]; + blocks[i].d[4] = BSWAP4(ctx->E[i]); + ctx->E[i] = key->tail.h[4]; + blocks[i].d[5] = BSWAP4(ctx->F[i]); + ctx->F[i] = key->tail.h[5]; + blocks[i].d[6] = BSWAP4(ctx->G[i]); + ctx->G[i] = key->tail.h[6]; + blocks[i].d[7] = BSWAP4(ctx->H[i]); + ctx->H[i] = key->tail.h[7]; + blocks[i].c[32] = 0x80; + blocks[i].d[15] = BSWAP4((64 + 32) * 8); +# else + PUTU32(blocks[i].c + 0, ctx->A[i]); + ctx->A[i] = key->tail.h[0]; + PUTU32(blocks[i].c + 4, ctx->B[i]); + ctx->B[i] = key->tail.h[1]; + PUTU32(blocks[i].c + 8, ctx->C[i]); + ctx->C[i] = key->tail.h[2]; + PUTU32(blocks[i].c + 12, ctx->D[i]); + ctx->D[i] = key->tail.h[3]; + PUTU32(blocks[i].c + 16, ctx->E[i]); + ctx->E[i] = key->tail.h[4]; + PUTU32(blocks[i].c + 20, ctx->F[i]); + ctx->F[i] = key->tail.h[5]; + PUTU32(blocks[i].c + 24, ctx->G[i]); + ctx->G[i] = key->tail.h[6]; + PUTU32(blocks[i].c + 28, ctx->H[i]); + ctx->H[i] = key->tail.h[7]; + blocks[i].c[32] = 0x80; + PUTU32(blocks[i].c + 60, (64 + 32) * 8); +# endif + edges[i].ptr = blocks[i].c; + edges[i].blocks = 1; + } + + /* finalize MACs */ + sha256_multi_block(ctx, edges, n4x); + + for (i = 0; i < x4; i++) { + unsigned int len = (i == (x4 - 1) ? last : frag), pad, j; + unsigned char *out0 = out; + + memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed); + ciph_d[i].inp = ciph_d[i].out; + + out += 5 + 16 + len; + + /* write MAC */ + PUTU32(out + 0, ctx->A[i]); + PUTU32(out + 4, ctx->B[i]); + PUTU32(out + 8, ctx->C[i]); + PUTU32(out + 12, ctx->D[i]); + PUTU32(out + 16, ctx->E[i]); + PUTU32(out + 20, ctx->F[i]); + PUTU32(out + 24, ctx->G[i]); + PUTU32(out + 28, ctx->H[i]); + out += 32; + len += 32; + + /* pad */ + pad = 15 - len % 16; + for (j = 0; j <= pad; j++) + *(out++) = pad; + len += pad + 1; + + ciph_d[i].blocks = (len - processed) / 16; + len += 16; /* account for explicit iv */ + + /* arrange header */ + out0[0] = ((u8 *)key->md.data)[8]; + out0[1] = ((u8 *)key->md.data)[9]; + out0[2] = ((u8 *)key->md.data)[10]; + out0[3] = (u8)(len >> 8); + out0[4] = (u8)(len); + + ret += len + 5; + inp += frag; + } + + aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); + + OPENSSL_cleanse(blocks, sizeof(blocks)); + OPENSSL_cleanse(ctx, sizeof(*ctx)); + + return ret; +} +# endif + +static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_HMAC_SHA256 *key = data(ctx); + unsigned int l; + size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and + * later */ + sha_off = 0; +# if defined(STITCHED_CALL) + size_t aes_off = 0, blocks; + + sha_off = SHA256_CBLOCK - key->md.num; +# endif + + key->payload_length = NO_PAYLOAD_LENGTH; + + if (len % AES_BLOCK_SIZE) + return 0; + + if (ctx->encrypt) { + if (plen == NO_PAYLOAD_LENGTH) + plen = len; + else if (len != + ((plen + SHA256_DIGEST_LENGTH + + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)) + return 0; + else if (key->aux.tls_ver >= TLS1_1_VERSION) + iv = AES_BLOCK_SIZE; + +# if defined(STITCHED_CALL) + /* + * Assembly stitch handles AVX-capable processors, but its + * performance is not optimal on AMD Jaguar, ~40% worse, for + * unknown reasons. Incidentally processor in question supports + * AVX, but not AMD-specific XOP extension, which can be used + * to identify it and avoid stitch invocation. So that after we + * establish that current CPU supports AVX, we even see if it's + * either even XOP-capable Bulldozer-based or GenuineIntel one. + * But SHAEXT-capable go ahead... + */ + if (((OPENSSL_ia32cap_P[2] & (1 << 29)) || /* SHAEXT? */ + ((OPENSSL_ia32cap_P[1] & (1 << (60 - 32))) && /* AVX? */ + ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */ + | (OPENSSL_ia32cap_P[0] & (1 << 30))))) && /* "Intel CPU"? */ + plen > (sha_off + iv) && + (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) { + SHA256_Update(&key->md, in + iv, sha_off); + + (void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks, + ctx->iv, &key->md, in + iv + sha_off); + blocks *= SHA256_CBLOCK; + aes_off += blocks; + sha_off += blocks; + key->md.Nh += blocks >> 29; + key->md.Nl += blocks <<= 3; + if (key->md.Nl < (unsigned int)blocks) + key->md.Nh++; + } else { + sha_off = 0; + } +# endif + sha_off += iv; + SHA256_Update(&key->md, in + sha_off, plen - sha_off); + + if (plen != len) { /* "TLS" mode of operation */ + if (in != out) + memcpy(out + aes_off, in + aes_off, plen - aes_off); + + /* calculate HMAC and append it to payload */ + SHA256_Final(out + plen, &key->md); + key->md = key->tail; + SHA256_Update(&key->md, out + plen, SHA256_DIGEST_LENGTH); + SHA256_Final(out + plen, &key->md); + + /* pad the payload|hmac */ + plen += SHA256_DIGEST_LENGTH; + for (l = len - plen - 1; plen < len; plen++) + out[plen] = l; + /* encrypt HMAC|padding at once */ + aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, + &key->ks, ctx->iv, 1); + } else { + aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, + &key->ks, ctx->iv, 1); + } + } else { + union { + unsigned int u[SHA256_DIGEST_LENGTH / sizeof(unsigned int)]; + unsigned char c[64 + SHA256_DIGEST_LENGTH]; + } mac, *pmac; + + /* arrange cache line alignment */ + pmac = (void *)(((size_t)mac.c + 63) & ((size_t)0 - 64)); + + /* decrypt HMAC|padding at once */ + aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); + + if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ + size_t inp_len, mask, j, i; + unsigned int res, maxpad, pad, bitlen; + int ret = 1; + union { + unsigned int u[SHA_LBLOCK]; + unsigned char c[SHA256_CBLOCK]; + } *data = (void *)key->md.data; + + if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3]) + >= TLS1_1_VERSION) + iv = AES_BLOCK_SIZE; + + if (len < (iv + SHA256_DIGEST_LENGTH + 1)) + return 0; + + /* omit explicit iv */ + out += iv; + len -= iv; + + /* figure out payload length */ + pad = out[len - 1]; + maxpad = len - (SHA256_DIGEST_LENGTH + 1); + maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); + maxpad &= 255; + + mask = constant_time_ge(maxpad, pad); + ret &= mask; + /* + * If pad is invalid then we will fail the above test but we must + * continue anyway because we are in constant time code. However, + * we'll use the maxpad value instead of the supplied pad to make + * sure we perform well defined pointer arithmetic. + */ + pad = constant_time_select(mask, pad, maxpad); + + inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1); + + key->aux.tls_aad[plen - 2] = inp_len >> 8; + key->aux.tls_aad[plen - 1] = inp_len; + + /* calculate HMAC */ + key->md = key->head; + SHA256_Update(&key->md, key->aux.tls_aad, plen); + +# if 1 + len -= SHA256_DIGEST_LENGTH; /* amend mac */ + if (len >= (256 + SHA256_CBLOCK)) { + j = (len - (256 + SHA256_CBLOCK)) & (0 - SHA256_CBLOCK); + j += SHA256_CBLOCK - key->md.num; + SHA256_Update(&key->md, out, j); + out += j; + len -= j; + inp_len -= j; + } + + /* but pretend as if we hashed padded payload */ + bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */ +# ifdef BSWAP4 + bitlen = BSWAP4(bitlen); +# else + mac.c[0] = 0; + mac.c[1] = (unsigned char)(bitlen >> 16); + mac.c[2] = (unsigned char)(bitlen >> 8); + mac.c[3] = (unsigned char)bitlen; + bitlen = mac.u[0]; +# endif + + pmac->u[0] = 0; + pmac->u[1] = 0; + pmac->u[2] = 0; + pmac->u[3] = 0; + pmac->u[4] = 0; + pmac->u[5] = 0; + pmac->u[6] = 0; + pmac->u[7] = 0; + + for (res = key->md.num, j = 0; j < len; j++) { + size_t c = out[j]; + mask = (j - inp_len) >> (sizeof(j) * 8 - 8); + c &= mask; + c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8)); + data->c[res++] = (unsigned char)c; + + if (res != SHA256_CBLOCK) + continue; + + /* j is not incremented yet */ + mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1)); + data->u[SHA_LBLOCK - 1] |= bitlen & mask; + sha256_block_data_order(&key->md, data, 1); + mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h[0] & mask; + pmac->u[1] |= key->md.h[1] & mask; + pmac->u[2] |= key->md.h[2] & mask; + pmac->u[3] |= key->md.h[3] & mask; + pmac->u[4] |= key->md.h[4] & mask; + pmac->u[5] |= key->md.h[5] & mask; + pmac->u[6] |= key->md.h[6] & mask; + pmac->u[7] |= key->md.h[7] & mask; + res = 0; + } + + for (i = res; i < SHA256_CBLOCK; i++, j++) + data->c[i] = 0; + + if (res > SHA256_CBLOCK - 8) { + mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1)); + data->u[SHA_LBLOCK - 1] |= bitlen & mask; + sha256_block_data_order(&key->md, data, 1); + mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h[0] & mask; + pmac->u[1] |= key->md.h[1] & mask; + pmac->u[2] |= key->md.h[2] & mask; + pmac->u[3] |= key->md.h[3] & mask; + pmac->u[4] |= key->md.h[4] & mask; + pmac->u[5] |= key->md.h[5] & mask; + pmac->u[6] |= key->md.h[6] & mask; + pmac->u[7] |= key->md.h[7] & mask; + + memset(data, 0, SHA256_CBLOCK); + j += 64; + } + data->u[SHA_LBLOCK - 1] = bitlen; + sha256_block_data_order(&key->md, data, 1); + mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h[0] & mask; + pmac->u[1] |= key->md.h[1] & mask; + pmac->u[2] |= key->md.h[2] & mask; + pmac->u[3] |= key->md.h[3] & mask; + pmac->u[4] |= key->md.h[4] & mask; + pmac->u[5] |= key->md.h[5] & mask; + pmac->u[6] |= key->md.h[6] & mask; + pmac->u[7] |= key->md.h[7] & mask; + +# ifdef BSWAP4 + pmac->u[0] = BSWAP4(pmac->u[0]); + pmac->u[1] = BSWAP4(pmac->u[1]); + pmac->u[2] = BSWAP4(pmac->u[2]); + pmac->u[3] = BSWAP4(pmac->u[3]); + pmac->u[4] = BSWAP4(pmac->u[4]); + pmac->u[5] = BSWAP4(pmac->u[5]); + pmac->u[6] = BSWAP4(pmac->u[6]); + pmac->u[7] = BSWAP4(pmac->u[7]); +# else + for (i = 0; i < 8; i++) { + res = pmac->u[i]; + pmac->c[4 * i + 0] = (unsigned char)(res >> 24); + pmac->c[4 * i + 1] = (unsigned char)(res >> 16); + pmac->c[4 * i + 2] = (unsigned char)(res >> 8); + pmac->c[4 * i + 3] = (unsigned char)res; + } +# endif + len += SHA256_DIGEST_LENGTH; +# else + SHA256_Update(&key->md, out, inp_len); + res = key->md.num; + SHA256_Final(pmac->c, &key->md); + + { + unsigned int inp_blocks, pad_blocks; + + /* but pretend as if we hashed padded payload */ + inp_blocks = + 1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); + res += (unsigned int)(len - inp_len); + pad_blocks = res / SHA256_CBLOCK; + res %= SHA256_CBLOCK; + pad_blocks += + 1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); + for (; inp_blocks < pad_blocks; inp_blocks++) + sha1_block_data_order(&key->md, data, 1); + } +# endif + key->md = key->tail; + SHA256_Update(&key->md, pmac->c, SHA256_DIGEST_LENGTH); + SHA256_Final(pmac->c, &key->md); + + /* verify HMAC */ + out += inp_len; + len -= inp_len; +# if 1 + { + unsigned char *p = + out + len - 1 - maxpad - SHA256_DIGEST_LENGTH; + size_t off = out - p; + unsigned int c, cmask; + + maxpad += SHA256_DIGEST_LENGTH; + for (res = 0, i = 0, j = 0; j < maxpad; j++) { + c = p[j]; + cmask = + ((int)(j - off - SHA256_DIGEST_LENGTH)) >> + (sizeof(int) * 8 - 1); + res |= (c ^ pad) & ~cmask; /* ... and padding */ + cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1); + res |= (c ^ pmac->c[i]) & cmask; + i += 1 & cmask; + } + maxpad -= SHA256_DIGEST_LENGTH; + + res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); + ret &= (int)~res; + } +# else + for (res = 0, i = 0; i < SHA256_DIGEST_LENGTH; i++) + res |= out[i] ^ pmac->c[i]; + res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); + ret &= (int)~res; + + /* verify padding */ + pad = (pad & ~res) | (maxpad & res); + out = out + len - 1 - pad; + for (res = 0, i = 0; i < pad; i++) + res |= out[i] ^ pad; + + res = (0 - res) >> (sizeof(res) * 8 - 1); + ret &= (int)~res; +# endif + return ret; + } else { + SHA256_Update(&key->md, out, len); + } + } + + return 1; +} + +static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, + void *ptr) +{ + EVP_AES_HMAC_SHA256 *key = data(ctx); + + switch (type) { + case EVP_CTRL_AEAD_SET_MAC_KEY: + { + unsigned int i; + unsigned char hmac_key[64]; + + memset(hmac_key, 0, sizeof(hmac_key)); + + if (arg > (int)sizeof(hmac_key)) { + SHA256_Init(&key->head); + SHA256_Update(&key->head, ptr, arg); + SHA256_Final(hmac_key, &key->head); + } else { + memcpy(hmac_key, ptr, arg); + } + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36; /* ipad */ + SHA256_Init(&key->head); + SHA256_Update(&key->head, hmac_key, sizeof(hmac_key)); + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ + SHA256_Init(&key->tail); + SHA256_Update(&key->tail, hmac_key, sizeof(hmac_key)); + + OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); + + return 1; + } + case EVP_CTRL_AEAD_TLS1_AAD: + { + unsigned char *p = ptr; + unsigned int len; + + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return -1; + + len = p[arg - 2] << 8 | p[arg - 1]; + + if (ctx->encrypt) { + key->payload_length = len; + if ((key->aux.tls_ver = + p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { + if (len < AES_BLOCK_SIZE) + return 0; + len -= AES_BLOCK_SIZE; + p[arg - 2] = len >> 8; + p[arg - 1] = len; + } + key->md = key->head; + SHA256_Update(&key->md, p, arg); + + return (int)(((len + SHA256_DIGEST_LENGTH + + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) + - len); + } else { + memcpy(key->aux.tls_aad, ptr, arg); + key->payload_length = arg; + + return SHA256_DIGEST_LENGTH; + } + } +# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: + return (int)(5 + 16 + ((arg + 32 + 16) & -16)); + case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: + { + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = + (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; + unsigned int n4x = 1, x4; + unsigned int frag, last, packlen, inp_len; + + if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) + return -1; + + inp_len = param->inp[11] << 8 | param->inp[12]; + + if (ctx->encrypt) { + if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION) + return -1; + + if (inp_len) { + if (inp_len < 4096) + return 0; /* too short */ + + if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5)) + n4x = 2; /* AVX2 */ + } else if ((n4x = param->interleave / 4) && n4x <= 2) + inp_len = param->len; + else + return -1; + + key->md = key->head; + SHA256_Update(&key->md, param->inp, 13); + + x4 = 4 * n4x; + n4x += 1; + + frag = inp_len >> n4x; + last = inp_len + frag - (frag << n4x); + if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) { + frag++; + last -= x4 - 1; + } + + packlen = 5 + 16 + ((frag + 32 + 16) & -16); + packlen = (packlen << n4x) - packlen; + packlen += 5 + 16 + ((last + 32 + 16) & -16); + + param->interleave = x4; + + return (int)packlen; + } else + return -1; /* not yet */ + } + case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: + { + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = + (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; + + return (int)tls1_1_multi_block_encrypt(key, param->out, + param->inp, param->len, + param->interleave / 4); + } + case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT: +# endif + default: + return -1; + } +} + +static EVP_CIPHER aesni_128_cbc_hmac_sha256_cipher = { +# ifdef NID_aes_128_cbc_hmac_sha256 + NID_aes_128_cbc_hmac_sha256, +# else + NID_undef, +# endif + 16, 16, 16, + EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | + EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, + aesni_cbc_hmac_sha256_init_key, + aesni_cbc_hmac_sha256_cipher, + NULL, + sizeof(EVP_AES_HMAC_SHA256), + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, + aesni_cbc_hmac_sha256_ctrl, + NULL +}; + +static EVP_CIPHER aesni_256_cbc_hmac_sha256_cipher = { +# ifdef NID_aes_256_cbc_hmac_sha256 + NID_aes_256_cbc_hmac_sha256, +# else + NID_undef, +# endif + 16, 32, 16, + EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | + EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, + aesni_cbc_hmac_sha256_init_key, + aesni_cbc_hmac_sha256_cipher, + NULL, + sizeof(EVP_AES_HMAC_SHA256), + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, + aesni_cbc_hmac_sha256_ctrl, + NULL +}; + +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void) +{ + return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) && + aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ? + &aesni_128_cbc_hmac_sha256_cipher : NULL); +} + +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void) +{ + return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) && + aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ? + &aesni_256_cbc_hmac_sha256_cipher : NULL); +} +# else +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void) +{ + return NULL; +} + +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void) +{ + return NULL; +} +# endif +#endif diff --git a/Sources/COpenSSL/e_atalla.c b/Sources/COpenSSL/e_atalla.c new file mode 100644 index 00000000..0774c84f --- /dev/null +++ b/Sources/COpenSSL/e_atalla.c @@ -0,0 +1,626 @@ +/* crypto/engine/hw_atalla.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "crypto.h" +#include "buffer.h" +#include "dso.h" +#include "engine.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#include "bn.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_ATALLA + +# ifdef FLAT_INC +# include "atalla.h" +# else +# include "atalla.h" +# endif + +# define ATALLA_LIB_NAME "atalla engine" +# include "e_atalla_err.c" + +static int atalla_destroy(ENGINE *e); +static int atalla_init(ENGINE *e); +static int atalla_finish(ENGINE *e); +static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* BIGNUM stuff */ +static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +# ifndef OPENSSL_NO_RSA +/* RSA stuff */ +static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +# ifndef OPENSSL_NO_DSA +/* DSA stuff */ +static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont); +static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +# ifndef OPENSSL_NO_DH +/* DH stuff */ +/* This function is alised to mod_exp (with the DH and mont dropped). */ +static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +/* The definitions for control commands specific to this engine */ +# define ATALLA_CMD_SO_PATH ENGINE_CMD_BASE +static const ENGINE_CMD_DEFN atalla_cmd_defns[] = { + {ATALLA_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'atasi' shared library", + ENGINE_CMD_FLAG_STRING}, + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD atalla_rsa = { + "Atalla RSA method", + NULL, + NULL, + NULL, + NULL, + atalla_rsa_mod_exp, + atalla_mod_exp_mont, + NULL, + NULL, + 0, + NULL, + NULL, + NULL, + NULL +}; +# endif + +# ifndef OPENSSL_NO_DSA +/* Our internal DSA_METHOD that we provide pointers to */ +static DSA_METHOD atalla_dsa = { + "Atalla DSA method", + NULL, /* dsa_do_sign */ + NULL, /* dsa_sign_setup */ + NULL, /* dsa_do_verify */ + atalla_dsa_mod_exp, /* dsa_mod_exp */ + atalla_mod_exp_dsa, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* dsa_paramgen */ + NULL /* dsa_keygen */ +}; +# endif + +# ifndef OPENSSL_NO_DH +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD atalla_dh = { + "Atalla DH method", + NULL, + NULL, + atalla_mod_exp_dh, + NULL, + NULL, + 0, + NULL, + NULL +}; +# endif + +/* Constants used when creating the ENGINE */ +static const char *engine_atalla_id = "atalla"; +static const char *engine_atalla_name = "Atalla hardware engine support"; + +/* + * This internal function is used by ENGINE_atalla() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif +# ifndef OPENSSL_NO_DSA + const DSA_METHOD *meth2; +# endif +# ifndef OPENSSL_NO_DH + const DH_METHOD *meth3; +# endif + if (!ENGINE_set_id(e, engine_atalla_id) || + !ENGINE_set_name(e, engine_atalla_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &atalla_rsa) || +# endif +# ifndef OPENSSL_NO_DSA + !ENGINE_set_DSA(e, &atalla_dsa) || +# endif +# ifndef OPENSSL_NO_DH + !ENGINE_set_DH(e, &atalla_dh) || +# endif + !ENGINE_set_destroy_function(e, atalla_destroy) || + !ENGINE_set_init_function(e, atalla_init) || + !ENGINE_set_finish_function(e, atalla_finish) || + !ENGINE_set_ctrl_function(e, atalla_ctrl) || + !ENGINE_set_cmd_defns(e, atalla_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + /* + * We know that the "PKCS1_SSLeay()" functions hook properly to the + * atalla-specific mod_exp and mod_exp_crt so we use those functions. NB: + * We don't use ENGINE_openssl() or anything "more generic" because + * something like the RSAref code may not hook properly, and if you own + * one of these cards then you have the right to do RSA operations on it + * anyway! + */ + meth1 = RSA_PKCS1_SSLeay(); + atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec; +# endif + +# ifndef OPENSSL_NO_DSA + /* + * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits. + */ + meth2 = DSA_OpenSSL(); + atalla_dsa.dsa_do_sign = meth2->dsa_do_sign; + atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup; + atalla_dsa.dsa_do_verify = meth2->dsa_do_verify; +# endif + +# ifndef OPENSSL_NO_DH + /* Much the same for Diffie-Hellman */ + meth3 = DH_OpenSSL(); + atalla_dh.generate_key = meth3->generate_key; + atalla_dh.compute_key = meth3->compute_key; +# endif + + /* Ensure the atalla error handling is set up */ + ERR_load_ATALLA_strings(); + return 1; +} + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_atalla(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_atalla(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_atalla(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +/* + * This is a process-global DSO handle used for loading and unloading the + * Atalla library. NB: This is only set (or unset) during an init() or + * finish() call (reference counts permitting) and they're operating with + * global locks, so this should be thread-safe implicitly. + */ +static DSO *atalla_dso = NULL; + +/* + * These are the function pointers that are (un)set when the library has + * successfully (un)loaded. + */ +static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL; +static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL; +static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = + NULL; + +/* + * These are the static string constants for the DSO file name and the + * function symbol names to bind to. Regrettably, the DSO name on *nix + * appears to be "atasi.so" rather than something more consistent like + * "libatasi.so". At the time of writing, I'm not sure what the file name on + * win32 is but clearly native name translation is not possible (eg + * libatasi.so on *nix, and atasi.dll on win32). For the purposes of testing, + * I have created a symbollic link called "libatasi.so" so that we can use + * native name-translation - a better solution will be needed. + */ +static const char *ATALLA_LIBNAME = NULL; +static const char *get_ATALLA_LIBNAME(void) +{ + if (ATALLA_LIBNAME) + return ATALLA_LIBNAME; + return "atasi"; +} + +static void free_ATALLA_LIBNAME(void) +{ + if (ATALLA_LIBNAME) + OPENSSL_free((void *)ATALLA_LIBNAME); + ATALLA_LIBNAME = NULL; +} + +static long set_ATALLA_LIBNAME(const char *name) +{ + free_ATALLA_LIBNAME(); + return (((ATALLA_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); +} + +static const char *ATALLA_F1 = "ASI_GetHardwareConfig"; +static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn"; +static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics"; + +/* Destructor (complements the "ENGINE_atalla()" constructor) */ +static int atalla_destroy(ENGINE *e) +{ + free_ATALLA_LIBNAME(); + /* + * Unload the atalla error strings so any error state including our + * functs or reasons won't lead to a segfault (they simply get displayed + * without corresponding string data because none will be found). + */ + ERR_unload_ATALLA_strings(); + return 1; +} + +/* (de)initialisation functions. */ +static int atalla_init(ENGINE *e) +{ + tfnASI_GetHardwareConfig *p1; + tfnASI_RSAPrivateKeyOpFn *p2; + tfnASI_GetPerformanceStatistics *p3; + /* + * Not sure of the origin of this magic value, but Ben's code had it and + * it seemed to have been working for a few people. :-) + */ + unsigned int config_buf[1024]; + + if (atalla_dso != NULL) { + ATALLAerr(ATALLA_F_ATALLA_INIT, ATALLA_R_ALREADY_LOADED); + goto err; + } + /* + * Attempt to load libatasi.so/atasi.dll/whatever. Needs to be changed + * unfortunately because the Atalla drivers don't have standard library + * names that can be platform-translated well. + */ + /* + * TODO: Work out how to actually map to the names the Atalla drivers + * really use - for now a symbollic link needs to be created on the host + * system from libatasi.so to atasi.so on unix variants. + */ + atalla_dso = DSO_load(NULL, get_ATALLA_LIBNAME(), NULL, 0); + if (atalla_dso == NULL) { + ATALLAerr(ATALLA_F_ATALLA_INIT, ATALLA_R_NOT_LOADED); + goto err; + } + if (! + (p1 = + (tfnASI_GetHardwareConfig *) DSO_bind_func(atalla_dso, ATALLA_F1)) +|| !(p2 = (tfnASI_RSAPrivateKeyOpFn *) DSO_bind_func(atalla_dso, ATALLA_F2)) +|| !(p3 = + (tfnASI_GetPerformanceStatistics *) DSO_bind_func(atalla_dso, + ATALLA_F3))) { + ATALLAerr(ATALLA_F_ATALLA_INIT, ATALLA_R_NOT_LOADED); + goto err; + } + /* Copy the pointers */ + p_Atalla_GetHardwareConfig = p1; + p_Atalla_RSAPrivateKeyOpFn = p2; + p_Atalla_GetPerformanceStatistics = p3; + /* + * Perform a basic test to see if there's actually any unit running. + */ + if (p1(0L, config_buf) != 0) { + ATALLAerr(ATALLA_F_ATALLA_INIT, ATALLA_R_UNIT_FAILURE); + goto err; + } + /* Everything's fine. */ + return 1; + err: + if (atalla_dso) + DSO_free(atalla_dso); + atalla_dso = NULL; + p_Atalla_GetHardwareConfig = NULL; + p_Atalla_RSAPrivateKeyOpFn = NULL; + p_Atalla_GetPerformanceStatistics = NULL; + return 0; +} + +static int atalla_finish(ENGINE *e) +{ + free_ATALLA_LIBNAME(); + if (atalla_dso == NULL) { + ATALLAerr(ATALLA_F_ATALLA_FINISH, ATALLA_R_NOT_LOADED); + return 0; + } + if (!DSO_free(atalla_dso)) { + ATALLAerr(ATALLA_F_ATALLA_FINISH, ATALLA_R_UNIT_FAILURE); + return 0; + } + atalla_dso = NULL; + p_Atalla_GetHardwareConfig = NULL; + p_Atalla_RSAPrivateKeyOpFn = NULL; + p_Atalla_GetPerformanceStatistics = NULL; + return 1; +} + +static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int initialised = ((atalla_dso == NULL) ? 0 : 1); + switch (cmd) { + case ATALLA_CMD_SO_PATH: + if (p == NULL) { + ATALLAerr(ATALLA_F_ATALLA_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (initialised) { + ATALLAerr(ATALLA_F_ATALLA_CTRL, ATALLA_R_ALREADY_LOADED); + return 0; + } + return set_ATALLA_LIBNAME((const char *)p); + default: + break; + } + ATALLAerr(ATALLA_F_ATALLA_CTRL, ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + /* + * I need somewhere to store temporary serialised values for use with the + * Atalla API calls. A neat cheat - I'll use BIGNUMs from the BN_CTX but + * access their arrays directly as byte arrays . This way I don't + * have to clean anything up. + */ + BIGNUM *modulus; + BIGNUM *exponent; + BIGNUM *argument; + BIGNUM *result; + RSAPrivateKey keydata; + int to_return, numbytes; + + modulus = exponent = argument = result = NULL; + to_return = 0; /* expect failure */ + + if (!atalla_dso) { + ATALLAerr(ATALLA_F_ATALLA_MOD_EXP, ATALLA_R_NOT_LOADED); + goto err; + } + /* Prepare the params */ + BN_CTX_start(ctx); + modulus = BN_CTX_get(ctx); + exponent = BN_CTX_get(ctx); + argument = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if (!result) { + ATALLAerr(ATALLA_F_ATALLA_MOD_EXP, ATALLA_R_BN_CTX_FULL); + goto err; + } + if (!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) || + !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top)) { + ATALLAerr(ATALLA_F_ATALLA_MOD_EXP, ATALLA_R_BN_EXPAND_FAIL); + goto err; + } + /* Prepare the key-data */ + memset(&keydata, 0, sizeof(keydata)); + numbytes = BN_num_bytes(m); + memset(exponent->d, 0, numbytes); + memset(modulus->d, 0, numbytes); + BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p)); + BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m)); + keydata.privateExponent.data = (unsigned char *)exponent->d; + keydata.privateExponent.len = numbytes; + keydata.modulus.data = (unsigned char *)modulus->d; + keydata.modulus.len = numbytes; + /* Prepare the argument */ + memset(argument->d, 0, numbytes); + memset(result->d, 0, numbytes); + BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a)); + /* Perform the operation */ + if (p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d, + (unsigned char *)argument->d, + keydata.modulus.len) != 0) { + ATALLAerr(ATALLA_F_ATALLA_MOD_EXP, ATALLA_R_REQUEST_FAILED); + goto err; + } + /* Convert the response */ + BN_bin2bn((unsigned char *)result->d, numbytes, r); + to_return = 1; + err: + BN_CTX_end(ctx); + return to_return; +} + +# ifndef OPENSSL_NO_RSA +static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + int to_return = 0; + + if (!atalla_dso) { + ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP, ATALLA_R_NOT_LOADED); + goto err; + } + if (!rsa->d || !rsa->n) { + ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP, + ATALLA_R_MISSING_KEY_COMPONENTS); + goto err; + } + to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx); + err: + return to_return; +} +# endif + +# ifndef OPENSSL_NO_DSA +/* + * This code was liberated and adapted from the commented-out code in + * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration (it + * doesn't have a CRT form for RSA), this function means that an Atalla + * system running with a DSA server certificate can handshake around 5 or 6 + * times faster/more than an equivalent system running with RSA. Just check + * out the "signs" statistics from the RSA and DSA parts of "openssl speed + * -engine atalla dsa1024 rsa1024". + */ +static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + BIGNUM t; + int to_return = 0; + + BN_init(&t); + /* let rr = a1 ^ p1 mod m */ + if (!atalla_mod_exp(rr, a1, p1, m, ctx)) + goto end; + /* let t = a2 ^ p2 mod m */ + if (!atalla_mod_exp(&t, a2, p2, m, ctx)) + goto end; + /* let rr = rr * t mod m */ + if (!BN_mod_mul(rr, rr, &t, m, ctx)) + goto end; + to_return = 1; + end: + BN_free(&t); + return to_return; +} + +static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return atalla_mod_exp(r, a, p, m, ctx); +} +# endif + +# ifndef OPENSSL_NO_RSA +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return atalla_mod_exp(r, a, p, m, ctx); +} +# endif + +# ifndef OPENSSL_NO_DH +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return atalla_mod_exp(r, a, p, m, ctx); +} +# endif + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_atalla_id) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ +# endif /* !OPENSSL_NO_HW_ATALLA */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_atalla_err.c b/Sources/COpenSSL/e_atalla_err.c new file mode 100644 index 00000000..de8cfce7 --- /dev/null +++ b/Sources/COpenSSL/e_atalla_err.c @@ -0,0 +1,145 @@ +/* e_atalla_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_atalla_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA ATALLA_str_functs[] = { + {ERR_FUNC(ATALLA_F_ATALLA_CTRL), "ATALLA_CTRL"}, + {ERR_FUNC(ATALLA_F_ATALLA_FINISH), "ATALLA_FINISH"}, + {ERR_FUNC(ATALLA_F_ATALLA_INIT), "ATALLA_INIT"}, + {ERR_FUNC(ATALLA_F_ATALLA_MOD_EXP), "ATALLA_MOD_EXP"}, + {ERR_FUNC(ATALLA_F_ATALLA_RSA_MOD_EXP), "ATALLA_RSA_MOD_EXP"}, + {0, NULL} +}; + +static ERR_STRING_DATA ATALLA_str_reasons[] = { + {ERR_REASON(ATALLA_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(ATALLA_R_BN_CTX_FULL), "bn ctx full"}, + {ERR_REASON(ATALLA_R_BN_EXPAND_FAIL), "bn expand fail"}, + {ERR_REASON(ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(ATALLA_R_MISSING_KEY_COMPONENTS), "missing key components"}, + {ERR_REASON(ATALLA_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(ATALLA_R_REQUEST_FAILED), "request failed"}, + {ERR_REASON(ATALLA_R_UNIT_FAILURE), "unit failure"}, + {0, NULL} +}; + +#endif + +#ifdef ATALLA_LIB_NAME +static ERR_STRING_DATA ATALLA_lib_name[] = { + {0, ATALLA_LIB_NAME}, + {0, NULL} +}; +#endif + +static int ATALLA_lib_error_code = 0; +static int ATALLA_error_init = 1; + +static void ERR_load_ATALLA_strings(void) +{ + if (ATALLA_lib_error_code == 0) + ATALLA_lib_error_code = ERR_get_next_error_library(); + + if (ATALLA_error_init) { + ATALLA_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(ATALLA_lib_error_code, ATALLA_str_functs); + ERR_load_strings(ATALLA_lib_error_code, ATALLA_str_reasons); +#endif + +#ifdef ATALLA_LIB_NAME + ATALLA_lib_name->error = ERR_PACK(ATALLA_lib_error_code, 0, 0); + ERR_load_strings(0, ATALLA_lib_name); +#endif + } +} + +static void ERR_unload_ATALLA_strings(void) +{ + if (ATALLA_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(ATALLA_lib_error_code, ATALLA_str_functs); + ERR_unload_strings(ATALLA_lib_error_code, ATALLA_str_reasons); +#endif + +#ifdef ATALLA_LIB_NAME + ERR_unload_strings(0, ATALLA_lib_name); +#endif + ATALLA_error_init = 1; + } +} + +static void ERR_ATALLA_error(int function, int reason, char *file, int line) +{ + if (ATALLA_lib_error_code == 0) + ATALLA_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(ATALLA_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_atalla_err.h b/Sources/COpenSSL/e_atalla_err.h new file mode 100644 index 00000000..7b71eff4 --- /dev/null +++ b/Sources/COpenSSL/e_atalla_err.h @@ -0,0 +1,94 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ATALLA_ERR_H +# define HEADER_ATALLA_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_ATALLA_strings(void); +static void ERR_unload_ATALLA_strings(void); +static void ERR_ATALLA_error(int function, int reason, char *file, int line); +# define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the ATALLA functions. */ + +/* Function codes. */ +# define ATALLA_F_ATALLA_CTRL 100 +# define ATALLA_F_ATALLA_FINISH 101 +# define ATALLA_F_ATALLA_INIT 102 +# define ATALLA_F_ATALLA_MOD_EXP 103 +# define ATALLA_F_ATALLA_RSA_MOD_EXP 104 + +/* Reason codes. */ +# define ATALLA_R_ALREADY_LOADED 100 +# define ATALLA_R_BN_CTX_FULL 101 +# define ATALLA_R_BN_EXPAND_FAIL 102 +# define ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 +# define ATALLA_R_MISSING_KEY_COMPONENTS 104 +# define ATALLA_R_NOT_LOADED 105 +# define ATALLA_R_REQUEST_FAILED 106 +# define ATALLA_R_UNIT_FAILURE 107 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_bf.c b/Sources/COpenSSL/e_bf.c new file mode 100644 index 00000000..2117651f --- /dev/null +++ b/Sources/COpenSSL/e_bf.c @@ -0,0 +1,87 @@ +/* crypto/evp/e_bf.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_BF +# include "evp.h" +# include "evp_locl.h" +# include "objects.h" +# include "blowfish.h" + +static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +typedef struct { + BF_KEY ks; +} EVP_BF_KEY; + +# define data(ctx) EVP_C_DATA(EVP_BF_KEY,ctx) + +IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64, + EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +#endif diff --git a/Sources/COpenSSL/e_camellia.c b/Sources/COpenSSL/e_camellia.c new file mode 100644 index 00000000..d896f7a1 --- /dev/null +++ b/Sources/COpenSSL/e_camellia.c @@ -0,0 +1,396 @@ +/* crypto/evp/e_camellia.c */ +/* ==================================================================== + * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "opensslconf.h" +#ifndef OPENSSL_NO_CAMELLIA +# include "evp.h" +# include "err.h" +# include +# include +# include "camellia.h" +# include "evp_locl.h" +# include "modes_lcl.h" + +static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +/* Camellia subkey Structure */ +typedef struct { + CAMELLIA_KEY ks; + block128_f block; + union { + cbc128_f cbc; + ctr128_f ctr; + } stream; +} EVP_CAMELLIA_KEY; + +# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) + +/* Attribute operation for Camellia */ +# define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx) + +# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) +/* ---------^^^ this is not a typo, just a way to detect that + * assembler support was in general requested... */ +# include "sparc_arch.h" + +extern unsigned int OPENSSL_sparcv9cap_P[]; + +# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA) + +void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks); +void cmll_t4_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void cmll_t4_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const CAMELLIA_KEY *key, + unsigned char *ivec); +void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const CAMELLIA_KEY *key, + unsigned char *ivec); + +static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode, bits; + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + bits = ctx->key_len * 8; + + cmll_t4_set_key(key, bits, &dat->ks); + + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) + && !enc) { + ret = 0; + dat->block = (block128_f) cmll_t4_decrypt; + switch (bits) { + case 128: + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) cmll128_t4_cbc_decrypt : NULL; + break; + case 192: + case 256: + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) cmll256_t4_cbc_decrypt : NULL; + break; + default: + ret = -1; + } + } else { + ret = 0; + dat->block = (block128_f) cmll_t4_encrypt; + switch (bits) { + case 128: + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt; + else + dat->stream.cbc = NULL; + break; + case 192: + case 256: + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt; + else + dat->stream.cbc = NULL; + break; + default: + ret = -1; + } + } + + if (ret < 0) { + EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +# define cmll_t4_cbc_cipher camellia_cbc_cipher +static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define cmll_t4_ecb_cipher camellia_ecb_cipher +static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define cmll_t4_ofb_cipher camellia_ofb_cipher +static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define cmll_t4_cfb_cipher camellia_cfb_cipher +static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define cmll_t4_cfb8_cipher camellia_cfb8_cipher +static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define cmll_t4_cfb1_cipher camellia_cfb1_cipher +static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define cmll_t4_ctr_cipher camellia_ctr_cipher +static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + cmll_t4_init_key, \ + cmll_t4_##mode##_cipher, \ + NULL, \ + sizeof(EVP_CAMELLIA_KEY), \ + NULL,NULL,NULL,NULL }; \ +static const EVP_CIPHER camellia_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize, \ + keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + camellia_init_key, \ + camellia_##mode##_cipher, \ + NULL, \ + sizeof(EVP_CAMELLIA_KEY), \ + NULL,NULL,NULL,NULL }; \ +const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \ +{ return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; } + +# else + +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +static const EVP_CIPHER camellia_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + camellia_init_key, \ + camellia_##mode##_cipher, \ + NULL, \ + sizeof(EVP_CAMELLIA_KEY), \ + NULL,NULL,NULL,NULL }; \ +const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \ +{ return &camellia_##keylen##_##mode; } + +# endif + +# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ + BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) +# if 0 /* not yet, missing NID */ +BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags) +# endif +/* The subkey for Camellia is generated. */ +static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode; + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + ret = Camellia_set_key(key, ctx->key_len * 8, &dat->ks); + if (ret < 0) { + EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED); + return 0; + } + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) + && !enc) { + dat->block = (block128_f) Camellia_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) Camellia_cbc_encrypt : NULL; + } else { + dat->block = (block128_f) Camellia_encrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) Camellia_cbc_encrypt : NULL; + } + + return 1; +} + +static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + if (dat->stream.cbc) + (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt); + else if (ctx->encrypt) + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); + else + CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block); + + return 1; +} + +static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + size_t bl = ctx->cipher->block_size; + size_t i; + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + if (len < bl) + return 1; + + for (i = 0, len -= bl; i <= len; i += bl) + (*dat->block) (in + i, out + i, &dat->ks); + + return 1; +} + +static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, dat->block); + return 1; +} + +static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; +} + +static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; +} + +static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) { + CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; + } + + while (len >= MAXBITCHUNK) { + CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + len -= MAXBITCHUNK; + out += MAXBITCHUNK; + in += MAXBITCHUNK; + } + if (len) + CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + + return 1; +} + +# if 0 /* not yet, missing NID */ +static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + unsigned int num = ctx->num; + EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; + + if (dat->stream.ctr) + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, + ctx->iv, ctx->buf, &num, dat->stream.ctr); + else + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, + ctx->iv, ctx->buf, &num, dat->block); + ctx->num = (size_t)num; + return 1; +} +# endif + +BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0) + BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0) + BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0) +#else + +# ifdef PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/Sources/COpenSSL/e_capi.c b/Sources/COpenSSL/e_capi.c new file mode 100644 index 00000000..c02bd6b0 --- /dev/null +++ b/Sources/COpenSSL/e_capi.c @@ -0,0 +1,1909 @@ +/* engines/e_capi.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include + +#include "crypto.h" + +#ifdef OPENSSL_SYS_WIN32 +# ifndef OPENSSL_NO_CAPIENG + +# include "buffer.h" +# include "bn.h" +# include "rsa.h" + +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +# endif + +# include +# include +# include +# ifndef alloca +# define alloca _alloca +# endif + +/* + * This module uses several "new" interfaces, among which is + * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is + * one of possible values you can pass to function in question. By + * checking if it's defined we can see if wincrypt.h and accompanying + * crypt32.lib are in shape. The native MingW32 headers up to and + * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the + * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG, + * so we check for these too and avoid compiling. + * Yes, it's rather "weak" test and if compilation fails, + * then re-configure with -DOPENSSL_NO_CAPIENG. + */ +# if defined(CERT_KEY_PROV_INFO_PROP_ID) && \ + defined(CERT_STORE_PROV_SYSTEM_A) && \ + defined(CERT_STORE_READONLY_FLAG) +# define __COMPILE_CAPIENG +# endif /* CERT_KEY_PROV_INFO_PROP_ID */ +# endif /* OPENSSL_NO_CAPIENG */ +#endif /* OPENSSL_SYS_WIN32 */ + +#ifdef __COMPILE_CAPIENG + +# undef X509_EXTENSIONS +# undef X509_CERT_PAIR + +/* Definitions which may be missing from earlier version of headers */ +# ifndef CERT_STORE_OPEN_EXISTING_FLAG +# define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 +# endif + +# ifndef CERT_STORE_CREATE_NEW_FLAG +# define CERT_STORE_CREATE_NEW_FLAG 0x00002000 +# endif + +# ifndef CERT_SYSTEM_STORE_CURRENT_USER +# define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000 +# endif + +# ifndef ALG_SID_SHA_256 +# define ALG_SID_SHA_256 12 +# endif +# ifndef ALG_SID_SHA_384 +# define ALG_SID_SHA_384 13 +# endif +# ifndef ALG_SID_SHA_512 +# define ALG_SID_SHA_512 14 +# endif + +# ifndef CALG_SHA_256 +# define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256) +# endif +# ifndef CALG_SHA_384 +# define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384) +# endif +# ifndef CALG_SHA_512 +# define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512) +# endif + +# include "engine.h" +# include "pem.h" +# include "x509v3.h" + +# include "e_capi_err.h" +# include "e_capi_err.c" + +static const char *engine_capi_id = "capi"; +static const char *engine_capi_name = "CryptoAPI ENGINE"; + +typedef struct CAPI_CTX_st CAPI_CTX; +typedef struct CAPI_KEY_st CAPI_KEY; + +static void capi_addlasterror(void); +static void capi_adderror(DWORD err); + +static void CAPI_trace(CAPI_CTX * ctx, char *format, ...); + +static int capi_list_providers(CAPI_CTX * ctx, BIO *out); +static int capi_list_containers(CAPI_CTX * ctx, BIO *out); +int capi_list_certs(CAPI_CTX * ctx, BIO *out, char *storename); +void capi_free_key(CAPI_KEY * key); + +static PCCERT_CONTEXT capi_find_cert(CAPI_CTX * ctx, const char *id, + HCERTSTORE hstore); + +CAPI_KEY *capi_find_key(CAPI_CTX * ctx, const char *id); + +static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +static int capi_rsa_sign(int dtype, const unsigned char *m, + unsigned int m_len, unsigned char *sigret, + unsigned int *siglen, const RSA *rsa); +static int capi_rsa_priv_enc(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int capi_rsa_priv_dec(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int capi_rsa_free(RSA *rsa); + +static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, + DSA *dsa); +static int capi_dsa_free(DSA *dsa); + +static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **pkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, + void *callback_data); + +static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); +# ifdef OPENSSL_CAPIENG_DIALOG +static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); +# endif + +typedef PCCERT_CONTEXT(WINAPI *CERTDLG) (HCERTSTORE, HWND, LPCWSTR, + LPCWSTR, DWORD, DWORD, void *); +typedef HWND(WINAPI *GETCONSWIN) (void); + +/* + * This structure contains CAPI ENGINE specific data: it contains various + * global options and affects how other functions behave. + */ + +# define CAPI_DBG_TRACE 2 +# define CAPI_DBG_ERROR 1 + +struct CAPI_CTX_st { + int debug_level; + char *debug_file; + /* Parameters to use for container lookup */ + DWORD keytype; + LPSTR cspname; + DWORD csptype; + /* Certificate store name to use */ + LPSTR storename; + LPSTR ssl_client_store; + /* System store flags */ + DWORD store_flags; +/* Lookup string meanings in load_private_key */ +/* Substring of subject: uses "storename" */ +# define CAPI_LU_SUBSTR 1 +/* Friendly name: uses storename */ +# define CAPI_LU_FNAME 2 +/* Container name: uses cspname, keytype */ +# define CAPI_LU_CONTNAME 3 + int lookup_method; +/* Info to dump with dumpcerts option */ +/* Issuer and serial name strings */ +# define CAPI_DMP_SUMMARY 0x1 +/* Friendly name */ +# define CAPI_DMP_FNAME 0x2 +/* Full X509_print dump */ +# define CAPI_DMP_FULL 0x4 +/* Dump PEM format certificate */ +# define CAPI_DMP_PEM 0x8 +/* Dump pseudo key (if possible) */ +# define CAPI_DMP_PSKEY 0x10 +/* Dump key info (if possible) */ +# define CAPI_DMP_PKEYINFO 0x20 + DWORD dump_flags; + int (*client_cert_select) (ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); + CERTDLG certselectdlg; + GETCONSWIN getconswindow; +}; + +static CAPI_CTX *capi_ctx_new(); +static void capi_ctx_free(CAPI_CTX * ctx); +static int capi_ctx_set_provname(CAPI_CTX * ctx, LPSTR pname, DWORD type, + int check); +static int capi_ctx_set_provname_idx(CAPI_CTX * ctx, int idx); + +# define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE +# define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1) +# define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2) +# define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3) +# define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4) +# define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5) +# define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6) +# define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7) +# define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8) +# define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9) +# define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10) +# define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11) +# define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12) +# define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13) + +static const ENGINE_CMD_DEFN capi_cmd_defns[] = { + {CAPI_CMD_LIST_CERTS, + "list_certs", + "List all certificates in store", + ENGINE_CMD_FLAG_NO_INPUT}, + {CAPI_CMD_LOOKUP_CERT, + "lookup_cert", + "Lookup and output certificates", + ENGINE_CMD_FLAG_STRING}, + {CAPI_CMD_DEBUG_LEVEL, + "debug_level", + "debug level (1=errors, 2=trace)", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_DEBUG_FILE, + "debug_file", + "debugging filename)", + ENGINE_CMD_FLAG_STRING}, + {CAPI_CMD_KEYTYPE, + "key_type", + "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_LIST_CSPS, + "list_csps", + "List all CSPs", + ENGINE_CMD_FLAG_NO_INPUT}, + {CAPI_CMD_SET_CSP_IDX, + "csp_idx", + "Set CSP by index", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_SET_CSP_NAME, + "csp_name", + "Set CSP name, (default CSP used if not specified)", + ENGINE_CMD_FLAG_STRING}, + {CAPI_CMD_SET_CSP_TYPE, + "csp_type", + "Set CSP type, (default RSA_PROV_FULL)", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_LIST_CONTAINERS, + "list_containers", + "list container names", + ENGINE_CMD_FLAG_NO_INPUT}, + {CAPI_CMD_LIST_OPTIONS, + "list_options", + "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, " + "32=private key info)", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_LOOKUP_METHOD, + "lookup_method", + "Set key lookup method (1=substring, 2=friendlyname, 3=container name)", + ENGINE_CMD_FLAG_NUMERIC}, + {CAPI_CMD_STORE_NAME, + "store_name", + "certificate store name, default \"MY\"", + ENGINE_CMD_FLAG_STRING}, + {CAPI_CMD_STORE_FLAGS, + "store_flags", + "Certificate store flags: 1 = system store", + ENGINE_CMD_FLAG_NUMERIC}, + + {0, NULL, NULL, 0} +}; + +static int capi_idx = -1; +static int rsa_capi_idx = -1; +static int dsa_capi_idx = -1; +static int cert_capi_idx = -1; + +static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int ret = 1; + CAPI_CTX *ctx; + BIO *out; + if (capi_idx == -1) { + CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED); + return 0; + } + ctx = ENGINE_get_ex_data(e, capi_idx); + out = BIO_new_fp(stdout, BIO_NOCLOSE); + switch (cmd) { + case CAPI_CMD_LIST_CSPS: + ret = capi_list_providers(ctx, out); + break; + + case CAPI_CMD_LIST_CERTS: + ret = capi_list_certs(ctx, out, NULL); + break; + + case CAPI_CMD_LOOKUP_CERT: + ret = capi_list_certs(ctx, out, p); + break; + + case CAPI_CMD_LIST_CONTAINERS: + ret = capi_list_containers(ctx, out); + break; + + case CAPI_CMD_STORE_NAME: + if (ctx->storename) + OPENSSL_free(ctx->storename); + ctx->storename = BUF_strdup(p); + CAPI_trace(ctx, "Setting store name to %s\n", p); + break; + + case CAPI_CMD_STORE_FLAGS: + if (i & 1) { + ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE; + ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER; + } else { + ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER; + ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE; + } + CAPI_trace(ctx, "Setting flags to %d\n", i); + break; + + case CAPI_CMD_DEBUG_LEVEL: + ctx->debug_level = (int)i; + CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level); + break; + + case CAPI_CMD_DEBUG_FILE: + ctx->debug_file = BUF_strdup(p); + CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file); + break; + + case CAPI_CMD_KEYTYPE: + ctx->keytype = i; + CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype); + break; + + case CAPI_CMD_SET_CSP_IDX: + ret = capi_ctx_set_provname_idx(ctx, i); + break; + + case CAPI_CMD_LIST_OPTIONS: + ctx->dump_flags = i; + break; + + case CAPI_CMD_LOOKUP_METHOD: + if (i < 1 || i > 3) { + CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD); + return 0; + } + ctx->lookup_method = i; + break; + + case CAPI_CMD_SET_CSP_NAME: + ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1); + break; + + case CAPI_CMD_SET_CSP_TYPE: + ctx->csptype = i; + break; + + default: + CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND); + ret = 0; + } + + BIO_free(out); + return ret; + +} + +static RSA_METHOD capi_rsa_method = { + "CryptoAPI RSA method", + 0, /* pub_enc */ + 0, /* pub_dec */ + capi_rsa_priv_enc, /* priv_enc */ + capi_rsa_priv_dec, /* priv_dec */ + 0, /* rsa_mod_exp */ + 0, /* bn_mod_exp */ + 0, /* init */ + capi_rsa_free, /* finish */ + RSA_FLAG_SIGN_VER, /* flags */ + NULL, /* app_data */ + capi_rsa_sign, /* rsa_sign */ + 0 /* rsa_verify */ +}; + +static DSA_METHOD capi_dsa_method = { + "CryptoAPI DSA method", + capi_dsa_do_sign, /* dsa_do_sign */ + 0, /* dsa_sign_setup */ + 0, /* dsa_do_verify */ + 0, /* dsa_mod_exp */ + 0, /* bn_mod_exp */ + 0, /* init */ + capi_dsa_free, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + 0, /* dsa_paramgen */ + 0 /* dsa_keygen */ +}; + +static int capi_init(ENGINE *e) +{ + CAPI_CTX *ctx; + const RSA_METHOD *ossl_rsa_meth; + const DSA_METHOD *ossl_dsa_meth; + + if (capi_idx < 0) { + capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0); + if (capi_idx < 0) + goto memerr; + + cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0); + + /* Setup RSA_METHOD */ + rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0); + ossl_rsa_meth = RSA_PKCS1_SSLeay(); + capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc; + capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec; + capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp; + capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp; + + /* Setup DSA Method */ + dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0); + ossl_dsa_meth = DSA_OpenSSL(); + capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify; + capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp; + capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp; + } + + ctx = capi_ctx_new(); + if (!ctx) + goto memerr; + + ENGINE_set_ex_data(e, capi_idx, ctx); + +# ifdef OPENSSL_CAPIENG_DIALOG + { + HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL")); + HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL")); + if (cryptui) + ctx->certselectdlg = + (CERTDLG) GetProcAddress(cryptui, + "CryptUIDlgSelectCertificateFromStore"); + if (kernel) + ctx->getconswindow = + (GETCONSWIN) GetProcAddress(kernel, "GetConsoleWindow"); + if (cryptui && !OPENSSL_isservice()) + ctx->client_cert_select = cert_select_dialog; + } +# endif + + return 1; + + memerr: + CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE); + return 0; + + return 1; +} + +static int capi_destroy(ENGINE *e) +{ + ERR_unload_CAPI_strings(); + return 1; +} + +static int capi_finish(ENGINE *e) +{ + CAPI_CTX *ctx; + ctx = ENGINE_get_ex_data(e, capi_idx); + capi_ctx_free(ctx); + ENGINE_set_ex_data(e, capi_idx, NULL); + return 1; +} + +/* + * CryptoAPI key application data. This contains a handle to the private key + * container (for sign operations) and a handle to the key (for decrypt + * operations). + */ + +struct CAPI_KEY_st { + /* Associated certificate context (if any) */ + PCCERT_CONTEXT pcert; + HCRYPTPROV hprov; + HCRYPTKEY key; + DWORD keyspec; +}; + +static int bind_capi(ENGINE *e) +{ + if (!ENGINE_set_id(e, engine_capi_id) + || !ENGINE_set_name(e, engine_capi_name) + || !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) + || !ENGINE_set_init_function(e, capi_init) + || !ENGINE_set_finish_function(e, capi_finish) + || !ENGINE_set_destroy_function(e, capi_destroy) + || !ENGINE_set_RSA(e, &capi_rsa_method) + || !ENGINE_set_DSA(e, &capi_dsa_method) + || !ENGINE_set_load_privkey_function(e, capi_load_privkey) + || !ENGINE_set_load_ssl_client_cert_function(e, + capi_load_ssl_client_cert) + || !ENGINE_set_cmd_defns(e, capi_cmd_defns) + || !ENGINE_set_ctrl_function(e, capi_ctrl)) + return 0; + ERR_load_CAPI_strings(); + + return 1; + +} + +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_helper(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_capi_id) != 0)) + return 0; + if (!bind_capi(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) +# else +static ENGINE *engine_capi(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_capi(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_capi(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_capi(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen) +{ + int i; + /* + * Reverse buffer in place: since this is a keyblob structure that will + * be freed up after conversion anyway it doesn't matter if we change + * it. + */ + for (i = 0; i < binlen / 2; i++) { + unsigned char c; + c = bin[i]; + bin[i] = bin[binlen - i - 1]; + bin[binlen - i - 1] = c; + } + + if (!BN_bin2bn(bin, binlen, bn)) + return 0; + return 1; +} + +/* Given a CAPI_KEY get an EVP_PKEY structure */ + +static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY * key) +{ + unsigned char *pubkey = NULL; + DWORD len; + BLOBHEADER *bh; + RSA *rkey = NULL; + DSA *dkey = NULL; + EVP_PKEY *ret = NULL; + if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) { + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); + capi_addlasterror(); + return NULL; + } + + pubkey = OPENSSL_malloc(len); + + if (!pubkey) + goto memerr; + + if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) { + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR); + capi_addlasterror(); + goto err; + } + + bh = (BLOBHEADER *) pubkey; + if (bh->bType != PUBLICKEYBLOB) { + CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); + goto err; + } + if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) { + RSAPUBKEY *rp; + DWORD rsa_modlen; + unsigned char *rsa_modulus; + rp = (RSAPUBKEY *) (bh + 1); + if (rp->magic != 0x31415352) { + char magstr[10]; + BIO_snprintf(magstr, 10, "%lx", rp->magic); + CAPIerr(CAPI_F_CAPI_GET_PKEY, + CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); + ERR_add_error_data(2, "magic=0x", magstr); + goto err; + } + rsa_modulus = (unsigned char *)(rp + 1); + rkey = RSA_new_method(eng); + if (!rkey) + goto memerr; + + rkey->e = BN_new(); + rkey->n = BN_new(); + + if (!rkey->e || !rkey->n) + goto memerr; + + if (!BN_set_word(rkey->e, rp->pubexp)) + goto memerr; + + rsa_modlen = rp->bitlen / 8; + if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen)) + goto memerr; + + RSA_set_ex_data(rkey, rsa_capi_idx, key); + + if (!(ret = EVP_PKEY_new())) + goto memerr; + + EVP_PKEY_assign_RSA(ret, rkey); + rkey = NULL; + + } else if (bh->aiKeyAlg == CALG_DSS_SIGN) { + DSSPUBKEY *dp; + DWORD dsa_plen; + unsigned char *btmp; + dp = (DSSPUBKEY *) (bh + 1); + if (dp->magic != 0x31535344) { + char magstr[10]; + BIO_snprintf(magstr, 10, "%lx", dp->magic); + CAPIerr(CAPI_F_CAPI_GET_PKEY, + CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); + ERR_add_error_data(2, "magic=0x", magstr); + goto err; + } + dsa_plen = dp->bitlen / 8; + btmp = (unsigned char *)(dp + 1); + dkey = DSA_new_method(eng); + if (!dkey) + goto memerr; + dkey->p = BN_new(); + dkey->q = BN_new(); + dkey->g = BN_new(); + dkey->pub_key = BN_new(); + if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key) + goto memerr; + if (!lend_tobn(dkey->p, btmp, dsa_plen)) + goto memerr; + btmp += dsa_plen; + if (!lend_tobn(dkey->q, btmp, 20)) + goto memerr; + btmp += 20; + if (!lend_tobn(dkey->g, btmp, dsa_plen)) + goto memerr; + btmp += dsa_plen; + if (!lend_tobn(dkey->pub_key, btmp, dsa_plen)) + goto memerr; + btmp += dsa_plen; + + DSA_set_ex_data(dkey, dsa_capi_idx, key); + + if (!(ret = EVP_PKEY_new())) + goto memerr; + + EVP_PKEY_assign_DSA(ret, dkey); + dkey = NULL; + } else { + char algstr[10]; + BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg); + CAPIerr(CAPI_F_CAPI_GET_PKEY, + CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); + ERR_add_error_data(2, "aiKeyAlg=0x", algstr); + goto err; + } + + err: + if (pubkey) + OPENSSL_free(pubkey); + if (!ret) { + if (rkey) + RSA_free(rkey); + if (dkey) + DSA_free(dkey); + } + + return ret; + + memerr: + CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE); + goto err; + +} + +static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + CAPI_CTX *ctx; + CAPI_KEY *key; + EVP_PKEY *ret; + ctx = ENGINE_get_ex_data(eng, capi_idx); + + if (!ctx) { + CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); + return NULL; + } + + key = capi_find_key(ctx, key_id); + + if (!key) + return NULL; + + ret = capi_get_pkey(eng, key); + + if (!ret) + capi_free_key(key); + return ret; + +} + +/* CryptoAPI RSA operations */ + +int capi_rsa_priv_enc(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED); + return -1; +} + +int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, const RSA *rsa) +{ + ALG_ID alg; + HCRYPTHASH hash; + DWORD slen; + unsigned int i; + int ret = -1; + CAPI_KEY *capi_key; + CAPI_CTX *ctx; + + ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); + + CAPI_trace(ctx, "Called CAPI_rsa_sign()\n"); + + capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); + if (!capi_key) { + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY); + return -1; + } +/* Convert the signature type to a CryptoAPI algorithm ID */ + switch (dtype) { + case NID_sha256: + alg = CALG_SHA_256; + break; + + case NID_sha384: + alg = CALG_SHA_384; + break; + + case NID_sha512: + alg = CALG_SHA_512; + break; + + case NID_sha1: + alg = CALG_SHA1; + break; + + case NID_md5: + alg = CALG_MD5; + break; + + case NID_md5_sha1: + alg = CALG_SSL3_SHAMD5; + break; + default: + { + char algstr[10]; + BIO_snprintf(algstr, 10, "%lx", dtype); + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID); + ERR_add_error_data(2, "NID=0x", algstr); + return -1; + } + } + +/* Create the hash object */ + if (!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash)) { + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); + capi_addlasterror(); + return -1; + } +/* Set the hash value to the value passed */ + + if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0)) { + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE); + capi_addlasterror(); + goto err; + } + +/* Finally sign it */ + slen = RSA_size(rsa); + if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) { + CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH); + capi_addlasterror(); + goto err; + } else { + ret = 1; + /* Inplace byte reversal of signature */ + for (i = 0; i < slen / 2; i++) { + unsigned char c; + c = sigret[i]; + sigret[i] = sigret[slen - i - 1]; + sigret[slen - i - 1] = c; + } + *siglen = slen; + } + + /* Now cleanup */ + + err: + CryptDestroyHash(hash); + + return ret; +} + +int capi_rsa_priv_dec(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + int i; + unsigned char *tmpbuf; + CAPI_KEY *capi_key; + CAPI_CTX *ctx; + DWORD flags = 0; + + ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); + + CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n"); + + capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); + if (!capi_key) { + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY); + return -1; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + /* Nothing to do */ + break; +#ifdef CRYPT_DECRYPT_RSA_NO_PADDING_CHECK + case RSA_NO_PADDING: + flags = CRYPT_DECRYPT_RSA_NO_PADDING_CHECK; + break; +#endif + default: + { + char errstr[10]; + BIO_snprintf(errstr, 10, "%d", padding); + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING); + ERR_add_error_data(2, "padding=", errstr); + return -1; + } + } + + /* Create temp reverse order version of input */ + if (!(tmpbuf = OPENSSL_malloc(flen))) { + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE); + return -1; + } + for (i = 0; i < flen; i++) + tmpbuf[flen - i - 1] = from[i]; + + /* Finally decrypt it */ + if (!CryptDecrypt(capi_key->key, 0, TRUE, flags, tmpbuf, &flen)) { + CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR); + capi_addlasterror(); + OPENSSL_cleanse(tmpbuf, flen); + OPENSSL_free(tmpbuf); + return -1; + } else { + memcpy(to, tmpbuf, flen); + } + + OPENSSL_cleanse(tmpbuf, flen); + OPENSSL_free(tmpbuf); + + return flen; +} + +static int capi_rsa_free(RSA *rsa) +{ + CAPI_KEY *capi_key; + capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); + capi_free_key(capi_key); + RSA_set_ex_data(rsa, rsa_capi_idx, 0); + return 1; +} + +/* CryptoAPI DSA operations */ + +static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, + DSA *dsa) +{ + HCRYPTHASH hash; + DWORD slen; + DSA_SIG *ret = NULL; + CAPI_KEY *capi_key; + CAPI_CTX *ctx; + unsigned char csigbuf[40]; + + ctx = ENGINE_get_ex_data(dsa->engine, capi_idx); + + CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n"); + + capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); + + if (!capi_key) { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY); + return NULL; + } + + if (dlen != 20) { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH); + return NULL; + } + + /* Create the hash object */ + if (!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash)) { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); + capi_addlasterror(); + return NULL; + } + + /* Set the hash value to the value passed */ + if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0)) { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE); + capi_addlasterror(); + goto err; + } + + /* Finally sign it */ + slen = sizeof(csigbuf); + if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) { + CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH); + capi_addlasterror(); + goto err; + } else { + ret = DSA_SIG_new(); + if (!ret) + goto err; + ret->r = BN_new(); + ret->s = BN_new(); + if (!ret->r || !ret->s) + goto err; + if (!lend_tobn(ret->r, csigbuf, 20) + || !lend_tobn(ret->s, csigbuf + 20, 20)) { + DSA_SIG_free(ret); + ret = NULL; + goto err; + } + } + + /* Now cleanup */ + + err: + OPENSSL_cleanse(csigbuf, 40); + CryptDestroyHash(hash); + return ret; +} + +static int capi_dsa_free(DSA *dsa) +{ + CAPI_KEY *capi_key; + capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); + capi_free_key(capi_key); + DSA_set_ex_data(dsa, dsa_capi_idx, 0); + return 1; +} + +static void capi_vtrace(CAPI_CTX * ctx, int level, char *format, + va_list argptr) +{ + BIO *out; + + if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file)) + return; + out = BIO_new_file(ctx->debug_file, "a+"); + BIO_vprintf(out, format, argptr); + BIO_free(out); +} + +static void CAPI_trace(CAPI_CTX * ctx, char *format, ...) +{ + va_list args; + va_start(args, format); + capi_vtrace(ctx, CAPI_DBG_TRACE, format, args); + va_end(args); +} + +static void capi_addlasterror(void) +{ + capi_adderror(GetLastError()); +} + +static void capi_adderror(DWORD err) +{ + char errstr[10]; + BIO_snprintf(errstr, 10, "%lX", err); + ERR_add_error_data(2, "Error code= 0x", errstr); +} + +static char *wide_to_asc(LPCWSTR wstr) +{ + char *str; + int len_0, sz; + + if (!wstr) + return NULL; + len_0 = (int)wcslen(wstr) + 1; /* WideCharToMultiByte expects int */ + sz = WideCharToMultiByte(CP_ACP, 0, wstr, len_0, NULL, 0, NULL, NULL); + if (!sz) { + CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); + return NULL; + } + str = OPENSSL_malloc(sz); + if (!str) { + CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!WideCharToMultiByte(CP_ACP, 0, wstr, len_0, str, sz, NULL, NULL)) { + OPENSSL_free(str); + CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); + return NULL; + } + return str; +} + +static int capi_get_provname(CAPI_CTX * ctx, LPSTR * pname, DWORD * ptype, + DWORD idx) +{ + DWORD len, err; + LPTSTR name; + CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx); + if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len)) { + err = GetLastError(); + if (err == ERROR_NO_MORE_ITEMS) + return 2; + CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); + capi_adderror(err); + return 0; + } + if (sizeof(TCHAR) != sizeof(char)) + name = alloca(len); + else + name = OPENSSL_malloc(len); + if (name == NULL) { + CAPIerr(CAPI_F_CAPI_GET_PROVNAME, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len)) { + err = GetLastError(); + if (err == ERROR_NO_MORE_ITEMS) + return 2; + CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); + capi_adderror(err); + return 0; + } + if (sizeof(TCHAR) != sizeof(char)) + *pname = wide_to_asc((WCHAR *)name); + else + *pname = (char *)name; + CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", *pname, + *ptype); + + return 1; +} + +static int capi_list_providers(CAPI_CTX * ctx, BIO *out) +{ + DWORD idx, ptype; + int ret; + LPSTR provname = NULL; + CAPI_trace(ctx, "capi_list_providers\n"); + BIO_printf(out, "Available CSPs:\n"); + for (idx = 0;; idx++) { + ret = capi_get_provname(ctx, &provname, &ptype, idx); + if (ret == 2) + break; + if (ret == 0) + break; + BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype); + OPENSSL_free(provname); + } + return 1; +} + +static int capi_list_containers(CAPI_CTX * ctx, BIO *out) +{ + int ret = 1; + HCRYPTPROV hprov; + DWORD err, idx, flags, buflen = 0, clen; + LPSTR cname; + LPTSTR cspname = NULL; + + CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, + ctx->csptype); + if (ctx->cspname && sizeof(TCHAR) != sizeof(char)) { + if ((clen = + MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, NULL, 0))) { + cspname = alloca(clen * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, (WCHAR *)cspname, + clen); + } + if (!cspname) { + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); + capi_addlasterror(); + return 0; + } + } else + cspname = (TCHAR *)ctx->cspname; + if (!CryptAcquireContext + (&hprov, NULL, cspname, ctx->csptype, CRYPT_VERIFYCONTEXT)) { + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, + CAPI_R_CRYPTACQUIRECONTEXT_ERROR); + capi_addlasterror(); + return 0; + } + if (!CryptGetProvParam + (hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST)) { + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); + capi_addlasterror(); + CryptReleaseContext(hprov, 0); + return 0; + } + CAPI_trace(ctx, "Got max container len %d\n", buflen); + if (buflen == 0) + buflen = 1024; + cname = OPENSSL_malloc(buflen); + if (!cname) { + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (idx = 0;; idx++) { + clen = buflen; + cname[0] = 0; + + if (idx == 0) + flags = CRYPT_FIRST; + else + flags = 0; + if (!CryptGetProvParam + (hprov, PP_ENUMCONTAINERS, (BYTE *) cname, &clen, flags)) { + err = GetLastError(); + if (err == ERROR_NO_MORE_ITEMS) + goto done; + CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); + capi_adderror(err); + goto err; + } + CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", + cname, clen, idx, flags); + if (!cname[0] && (clen == buflen)) { + CAPI_trace(ctx, "Enumerate bug: using workaround\n"); + goto done; + } + BIO_printf(out, "%d. %s\n", idx, cname); + } + err: + + ret = 0; + + done: + if (cname) + OPENSSL_free(cname); + CryptReleaseContext(hprov, 0); + + return ret; +} + +CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX * ctx, PCCERT_CONTEXT cert) +{ + DWORD len; + CRYPT_KEY_PROV_INFO *pinfo; + + if (!CertGetCertificateContextProperty + (cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) + return NULL; + pinfo = OPENSSL_malloc(len); + if (!pinfo) { + CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!CertGetCertificateContextProperty + (cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) { + CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, + CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO); + capi_addlasterror(); + OPENSSL_free(pinfo); + return NULL; + } + return pinfo; +} + +static void capi_dump_prov_info(CAPI_CTX * ctx, BIO *out, + CRYPT_KEY_PROV_INFO * pinfo) +{ + char *provname = NULL, *contname = NULL; + if (!pinfo) { + BIO_printf(out, " No Private Key\n"); + return; + } + provname = wide_to_asc(pinfo->pwszProvName); + contname = wide_to_asc(pinfo->pwszContainerName); + if (!provname || !contname) + goto err; + + BIO_printf(out, " Private Key Info:\n"); + BIO_printf(out, " Provider Name: %s, Provider Type %d\n", provname, + pinfo->dwProvType); + BIO_printf(out, " Container Name: %s, Key Type %d\n", contname, + pinfo->dwKeySpec); + err: + if (provname) + OPENSSL_free(provname); + if (contname) + OPENSSL_free(contname); +} + +char *capi_cert_get_fname(CAPI_CTX * ctx, PCCERT_CONTEXT cert) +{ + LPWSTR wfname; + DWORD dlen; + + CAPI_trace(ctx, "capi_cert_get_fname\n"); + if (!CertGetCertificateContextProperty + (cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen)) + return NULL; + wfname = OPENSSL_malloc(dlen); + if (wfname == NULL) { + CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (CertGetCertificateContextProperty + (cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen)) { + char *fname = wide_to_asc(wfname); + OPENSSL_free(wfname); + return fname; + } + CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME); + capi_addlasterror(); + + OPENSSL_free(wfname); + return NULL; +} + +void capi_dump_cert(CAPI_CTX * ctx, BIO *out, PCCERT_CONTEXT cert) +{ + X509 *x; + unsigned char *p; + unsigned long flags = ctx->dump_flags; + if (flags & CAPI_DMP_FNAME) { + char *fname; + fname = capi_cert_get_fname(ctx, cert); + if (fname) { + BIO_printf(out, " Friendly Name \"%s\"\n", fname); + OPENSSL_free(fname); + } else + BIO_printf(out, " \n"); + } + + p = cert->pbCertEncoded; + x = d2i_X509(NULL, &p, cert->cbCertEncoded); + if (!x) + BIO_printf(out, " \n"); + if (flags & CAPI_DMP_SUMMARY) { + BIO_printf(out, " Subject: "); + X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); + BIO_printf(out, "\n Issuer: "); + X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); + BIO_printf(out, "\n"); + } + if (flags & CAPI_DMP_FULL) + X509_print_ex(out, x, XN_FLAG_ONELINE, 0); + + if (flags & CAPI_DMP_PKEYINFO) { + CRYPT_KEY_PROV_INFO *pinfo; + pinfo = capi_get_prov_info(ctx, cert); + capi_dump_prov_info(ctx, out, pinfo); + if (pinfo) + OPENSSL_free(pinfo); + } + + if (flags & CAPI_DMP_PEM) + PEM_write_bio_X509(out, x); + X509_free(x); +} + +HCERTSTORE capi_open_store(CAPI_CTX * ctx, char *storename) +{ + HCERTSTORE hstore; + + if (!storename) + storename = ctx->storename; + if (!storename) + storename = "MY"; + CAPI_trace(ctx, "Opening certificate store %s\n", storename); + + hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, + ctx->store_flags, storename); + if (!hstore) { + CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE); + capi_addlasterror(); + } + return hstore; +} + +int capi_list_certs(CAPI_CTX * ctx, BIO *out, char *id) +{ + char *storename; + int idx; + int ret = 1; + HCERTSTORE hstore; + PCCERT_CONTEXT cert = NULL; + + storename = ctx->storename; + if (!storename) + storename = "MY"; + CAPI_trace(ctx, "Listing certs for store %s\n", storename); + + hstore = capi_open_store(ctx, storename); + if (!hstore) + return 0; + if (id) { + cert = capi_find_cert(ctx, id, hstore); + if (!cert) { + ret = 0; + goto err; + } + capi_dump_cert(ctx, out, cert); + CertFreeCertificateContext(cert); + } else { + for (idx = 0;; idx++) { + cert = CertEnumCertificatesInStore(hstore, cert); + if (!cert) + break; + BIO_printf(out, "Certificate %d\n", idx); + capi_dump_cert(ctx, out, cert); + } + } + err: + CertCloseStore(hstore, 0); + return ret; +} + +static PCCERT_CONTEXT capi_find_cert(CAPI_CTX * ctx, const char *id, + HCERTSTORE hstore) +{ + PCCERT_CONTEXT cert = NULL; + char *fname = NULL; + int match; + switch (ctx->lookup_method) { + case CAPI_LU_SUBSTR: + return CertFindCertificateInStore(hstore, + X509_ASN_ENCODING, 0, + CERT_FIND_SUBJECT_STR_A, id, NULL); + case CAPI_LU_FNAME: + for (;;) { + cert = CertEnumCertificatesInStore(hstore, cert); + if (!cert) + return NULL; + fname = capi_cert_get_fname(ctx, cert); + if (fname) { + if (strcmp(fname, id)) + match = 0; + else + match = 1; + OPENSSL_free(fname); + if (match) + return cert; + } + } + default: + return NULL; + } +} + +static CAPI_KEY *capi_get_key(CAPI_CTX * ctx, const TCHAR *contname, + TCHAR *provname, DWORD ptype, DWORD keyspec) +{ + CAPI_KEY *key; + DWORD dwFlags = 0; + key = OPENSSL_malloc(sizeof(CAPI_KEY)); + if (key == NULL) { + CAPIerr(CAPI_F_CAPI_GET_KEY, ERR_R_MALLOC_FAILURE); + capi_addlasterror(); + goto err; + } + if (sizeof(TCHAR) == sizeof(char)) + CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", + contname, provname, ptype); + else if (ctx && ctx->debug_level >= CAPI_DBG_TRACE && ctx->debug_file) { + /* above 'if' is optimization to minimize malloc-ations */ + char *_contname = wide_to_asc((WCHAR *)contname); + char *_provname = wide_to_asc((WCHAR *)provname); + + CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", + _contname, _provname, ptype); + if (_provname) + OPENSSL_free(_provname); + if (_contname) + OPENSSL_free(_contname); + } + if (ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE) + dwFlags = CRYPT_MACHINE_KEYSET; + if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) { + CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); + capi_addlasterror(); + goto err; + } + if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) { + CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR); + capi_addlasterror(); + CryptReleaseContext(key->hprov, 0); + goto err; + } + key->keyspec = keyspec; + key->pcert = NULL; + return key; + + err: + OPENSSL_free(key); + return NULL; +} + +static CAPI_KEY *capi_get_cert_key(CAPI_CTX * ctx, PCCERT_CONTEXT cert) +{ + CAPI_KEY *key = NULL; + CRYPT_KEY_PROV_INFO *pinfo = NULL; + char *provname = NULL, *contname = NULL; + pinfo = capi_get_prov_info(ctx, cert); + if (!pinfo) + goto err; + if (sizeof(TCHAR) != sizeof(char)) + key = capi_get_key(ctx, (TCHAR *)pinfo->pwszContainerName, + (TCHAR *)pinfo->pwszProvName, + pinfo->dwProvType, pinfo->dwKeySpec); + else { + provname = wide_to_asc(pinfo->pwszProvName); + contname = wide_to_asc(pinfo->pwszContainerName); + if (!provname || !contname) + goto err; + key = capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname, + pinfo->dwProvType, pinfo->dwKeySpec); + } + + err: + if (pinfo) + OPENSSL_free(pinfo); + if (provname) + OPENSSL_free(provname); + if (contname) + OPENSSL_free(contname); + return key; +} + +CAPI_KEY *capi_find_key(CAPI_CTX * ctx, const char *id) +{ + PCCERT_CONTEXT cert; + HCERTSTORE hstore; + CAPI_KEY *key = NULL; + switch (ctx->lookup_method) { + case CAPI_LU_SUBSTR: + case CAPI_LU_FNAME: + hstore = capi_open_store(ctx, NULL); + if (!hstore) + return NULL; + cert = capi_find_cert(ctx, id, hstore); + if (cert) { + key = capi_get_cert_key(ctx, cert); + CertFreeCertificateContext(cert); + } + CertCloseStore(hstore, 0); + break; + + case CAPI_LU_CONTNAME: + if (sizeof(TCHAR) != sizeof(char)) { + WCHAR *contname, *provname; + DWORD len; + + if ((len = MultiByteToWideChar(CP_ACP, 0, id, -1, NULL, 0)) && + (contname = alloca(len * sizeof(WCHAR)), + MultiByteToWideChar(CP_ACP, 0, id, -1, contname, len)) && + (len = + MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, NULL, 0)) + && (provname = + alloca(len * sizeof(WCHAR)), MultiByteToWideChar(CP_ACP, + 0, + ctx->cspname, + -1, + provname, + len))) + key = + capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname, + ctx->csptype, ctx->keytype); + } else + key = capi_get_key(ctx, (TCHAR *)id, + (TCHAR *)ctx->cspname, + ctx->csptype, ctx->keytype); + break; + } + + return key; +} + +void capi_free_key(CAPI_KEY * key) +{ + if (!key) + return; + CryptDestroyKey(key->key); + CryptReleaseContext(key->hprov, 0); + if (key->pcert) + CertFreeCertificateContext(key->pcert); + OPENSSL_free(key); +} + +/* Initialize a CAPI_CTX structure */ + +static CAPI_CTX *capi_ctx_new() +{ + CAPI_CTX *ctx; + ctx = OPENSSL_malloc(sizeof(CAPI_CTX)); + if (!ctx) { + CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ctx->cspname = NULL; + ctx->csptype = PROV_RSA_FULL; + ctx->dump_flags = CAPI_DMP_SUMMARY | CAPI_DMP_FNAME; + ctx->keytype = AT_KEYEXCHANGE; + ctx->storename = NULL; + ctx->ssl_client_store = NULL; + ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG | + CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER; + ctx->lookup_method = CAPI_LU_SUBSTR; + ctx->debug_level = 0; + ctx->debug_file = NULL; + ctx->client_cert_select = cert_select_simple; + return ctx; +} + +static void capi_ctx_free(CAPI_CTX * ctx) +{ + CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx); + if (!ctx) + return; + if (ctx->cspname) + OPENSSL_free(ctx->cspname); + if (ctx->debug_file) + OPENSSL_free(ctx->debug_file); + if (ctx->storename) + OPENSSL_free(ctx->storename); + if (ctx->ssl_client_store) + OPENSSL_free(ctx->ssl_client_store); + OPENSSL_free(ctx); +} + +static int capi_ctx_set_provname(CAPI_CTX * ctx, LPSTR pname, DWORD type, + int check) +{ + CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type); + if (check) { + HCRYPTPROV hprov; + LPTSTR name = NULL; + + if (sizeof(TCHAR) != sizeof(char)) { + DWORD len; + if ((len = MultiByteToWideChar(CP_ACP, 0, pname, -1, NULL, 0))) { + name = alloca(len * sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, pname, -1, (WCHAR *)name, len); + } + } else + name = (TCHAR *)pname; + + if (!name || !CryptAcquireContext(&hprov, NULL, name, type, + CRYPT_VERIFYCONTEXT)) { + CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, + CAPI_R_CRYPTACQUIRECONTEXT_ERROR); + capi_addlasterror(); + return 0; + } + CryptReleaseContext(hprov, 0); + } + if (ctx->cspname) + OPENSSL_free(ctx->cspname); + ctx->cspname = BUF_strdup(pname); + ctx->csptype = type; + return 1; +} + +static int capi_ctx_set_provname_idx(CAPI_CTX * ctx, int idx) +{ + LPSTR pname; + DWORD type; + int res; + if (capi_get_provname(ctx, &pname, &type, idx) != 1) + return 0; + res = capi_ctx_set_provname(ctx, pname, type, 0); + OPENSSL_free(pname); + return res; +} + +static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) +{ + int i; + X509_NAME *nm; + /* Special case: empty list: match anything */ + if (sk_X509_NAME_num(ca_dn) <= 0) + return 1; + for (i = 0; i < sk_X509_NAME_num(ca_dn); i++) { + nm = sk_X509_NAME_value(ca_dn, i); + if (!X509_NAME_cmp(nm, X509_get_issuer_name(x))) + return 1; + } + return 0; +} + +static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **pkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, + void *callback_data) +{ + STACK_OF(X509) *certs = NULL; + X509 *x; + char *storename; + const char *p; + int i, client_cert_idx; + HCERTSTORE hstore; + PCCERT_CONTEXT cert = NULL, excert = NULL; + CAPI_CTX *ctx; + CAPI_KEY *key; + ctx = ENGINE_get_ex_data(e, capi_idx); + + *pcert = NULL; + *pkey = NULL; + + storename = ctx->ssl_client_store; + if (!storename) + storename = "MY"; + + hstore = capi_open_store(ctx, storename); + if (!hstore) + return 0; + /* Enumerate all certificates collect any matches */ + for (i = 0;; i++) { + cert = CertEnumCertificatesInStore(hstore, cert); + if (!cert) + break; + p = cert->pbCertEncoded; + x = d2i_X509(NULL, &p, cert->cbCertEncoded); + if (!x) { + CAPI_trace(ctx, "Can't Parse Certificate %d\n", i); + continue; + } + if (cert_issuer_match(ca_dn, x) + && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0)) { + key = capi_get_cert_key(ctx, cert); + if (!key) { + X509_free(x); + continue; + } + /* + * Match found: attach extra data to it so we can retrieve the + * key later. + */ + excert = CertDuplicateCertificateContext(cert); + key->pcert = excert; + X509_set_ex_data(x, cert_capi_idx, key); + + if (!certs) + certs = sk_X509_new_null(); + + sk_X509_push(certs, x); + } else + X509_free(x); + + } + + if (cert) + CertFreeCertificateContext(cert); + if (hstore) + CertCloseStore(hstore, 0); + + if (!certs) + return 0; + + /* Select the appropriate certificate */ + + client_cert_idx = ctx->client_cert_select(e, ssl, certs); + + /* Set the selected certificate and free the rest */ + + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + if (i == client_cert_idx) + *pcert = x; + else { + key = X509_get_ex_data(x, cert_capi_idx); + capi_free_key(key); + X509_free(x); + } + } + + sk_X509_free(certs); + + if (!*pcert) + return 0; + + /* Setup key for selected certificate */ + + key = X509_get_ex_data(*pcert, cert_capi_idx); + *pkey = capi_get_pkey(e, key); + X509_set_ex_data(*pcert, cert_capi_idx, NULL); + + return 1; + +} + +/* Simple client cert selection function: always select first */ + +static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) +{ + return 0; +} + +# ifdef OPENSSL_CAPIENG_DIALOG + +/* + * More complex cert selection function, using standard function + * CryptUIDlgSelectCertificateFromStore() to produce a dialog box. + */ + +/* + * Definitions which are in cryptuiapi.h but this is not present in older + * versions of headers. + */ + +# ifndef CRYPTUI_SELECT_LOCATION_COLUMN +# define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010 +# define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004 +# endif + +# define dlg_title L"OpenSSL Application SSL Client Certificate Selection" +# define dlg_prompt L"Select a certificate to use for authentication" +# define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \ + |CRYPTUI_SELECT_INTENDEDUSE_COLUMN + +static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) +{ + X509 *x; + HCERTSTORE dstore; + PCCERT_CONTEXT cert; + CAPI_CTX *ctx; + CAPI_KEY *key; + HWND hwnd; + int i, idx = -1; + if (sk_X509_num(certs) == 1) + return 0; + ctx = ENGINE_get_ex_data(e, capi_idx); + /* Create an in memory store of certificates */ + dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, + CERT_STORE_CREATE_NEW_FLAG, NULL); + if (!dstore) { + CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE); + capi_addlasterror(); + goto err; + } + /* Add all certificates to store */ + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + key = X509_get_ex_data(x, cert_capi_idx); + + if (!CertAddCertificateContextToStore(dstore, key->pcert, + CERT_STORE_ADD_NEW, NULL)) { + CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT); + capi_addlasterror(); + goto err; + } + + } + hwnd = GetForegroundWindow(); + if (!hwnd) + hwnd = GetActiveWindow(); + if (!hwnd && ctx->getconswindow) + hwnd = ctx->getconswindow(); + /* Call dialog to select one */ + cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt, + dlg_columns, 0, NULL); + + /* Find matching cert from list */ + if (cert) { + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + key = X509_get_ex_data(x, cert_capi_idx); + if (CertCompareCertificate + (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->pCertInfo, + key->pcert->pCertInfo)) { + idx = i; + break; + } + } + } + + err: + if (dstore) + CertCloseStore(dstore, 0); + return idx; + +} +# endif + +#else /* !__COMPILE_CAPIENG */ +# include "engine.h" +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +OPENSSL_EXPORT + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); +OPENSSL_EXPORT + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) +{ + return 0; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() +# else +void ENGINE_load_capi(void) +{ +} +# endif +#endif diff --git a/Sources/COpenSSL/e_capi_err.c b/Sources/COpenSSL/e_capi_err.c new file mode 100644 index 00000000..8eb2089a --- /dev/null +++ b/Sources/COpenSSL/e_capi_err.c @@ -0,0 +1,187 @@ +/* e_capi_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_capi_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA CAPI_str_functs[] = { + {ERR_FUNC(CAPI_F_CAPI_CERT_GET_FNAME), "CAPI_CERT_GET_FNAME"}, + {ERR_FUNC(CAPI_F_CAPI_CTRL), "CAPI_CTRL"}, + {ERR_FUNC(CAPI_F_CAPI_CTX_NEW), "CAPI_CTX_NEW"}, + {ERR_FUNC(CAPI_F_CAPI_CTX_SET_PROVNAME), "CAPI_CTX_SET_PROVNAME"}, + {ERR_FUNC(CAPI_F_CAPI_DSA_DO_SIGN), "CAPI_DSA_DO_SIGN"}, + {ERR_FUNC(CAPI_F_CAPI_GET_KEY), "CAPI_GET_KEY"}, + {ERR_FUNC(CAPI_F_CAPI_GET_PKEY), "CAPI_GET_PKEY"}, + {ERR_FUNC(CAPI_F_CAPI_GET_PROVNAME), "CAPI_GET_PROVNAME"}, + {ERR_FUNC(CAPI_F_CAPI_GET_PROV_INFO), "CAPI_GET_PROV_INFO"}, + {ERR_FUNC(CAPI_F_CAPI_INIT), "CAPI_INIT"}, + {ERR_FUNC(CAPI_F_CAPI_LIST_CONTAINERS), "CAPI_LIST_CONTAINERS"}, + {ERR_FUNC(CAPI_F_CAPI_LOAD_PRIVKEY), "CAPI_LOAD_PRIVKEY"}, + {ERR_FUNC(CAPI_F_CAPI_OPEN_STORE), "CAPI_OPEN_STORE"}, + {ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_DEC), "CAPI_RSA_PRIV_DEC"}, + {ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_ENC), "CAPI_RSA_PRIV_ENC"}, + {ERR_FUNC(CAPI_F_CAPI_RSA_SIGN), "CAPI_RSA_SIGN"}, + {ERR_FUNC(CAPI_F_CERT_SELECT_DIALOG), "CERT_SELECT_DIALOG"}, + {ERR_FUNC(CAPI_F_CLIENT_CERT_SELECT), "CLIENT_CERT_SELECT"}, + {ERR_FUNC(CAPI_F_WIDE_TO_ASC), "WIDE_TO_ASC"}, + {0, NULL} +}; + +static ERR_STRING_DATA CAPI_str_reasons[] = { + {ERR_REASON(CAPI_R_CANT_CREATE_HASH_OBJECT), "cant create hash object"}, + {ERR_REASON(CAPI_R_CANT_FIND_CAPI_CONTEXT), "cant find capi context"}, + {ERR_REASON(CAPI_R_CANT_GET_KEY), "cant get key"}, + {ERR_REASON(CAPI_R_CANT_SET_HASH_VALUE), "cant set hash value"}, + {ERR_REASON(CAPI_R_CRYPTACQUIRECONTEXT_ERROR), + "cryptacquirecontext error"}, + {ERR_REASON(CAPI_R_CRYPTENUMPROVIDERS_ERROR), "cryptenumproviders error"}, + {ERR_REASON(CAPI_R_DECRYPT_ERROR), "decrypt error"}, + {ERR_REASON(CAPI_R_ENGINE_NOT_INITIALIZED), "engine not initialized"}, + {ERR_REASON(CAPI_R_ENUMCONTAINERS_ERROR), "enumcontainers error"}, + {ERR_REASON(CAPI_R_ERROR_ADDING_CERT), "error adding cert"}, + {ERR_REASON(CAPI_R_ERROR_CREATING_STORE), "error creating store"}, + {ERR_REASON(CAPI_R_ERROR_GETTING_FRIENDLY_NAME), + "error getting friendly name"}, + {ERR_REASON(CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO), + "error getting key provider info"}, + {ERR_REASON(CAPI_R_ERROR_OPENING_STORE), "error opening store"}, + {ERR_REASON(CAPI_R_ERROR_SIGNING_HASH), "error signing hash"}, + {ERR_REASON(CAPI_R_FUNCTION_NOT_SUPPORTED), "function not supported"}, + {ERR_REASON(CAPI_R_GETUSERKEY_ERROR), "getuserkey error"}, + {ERR_REASON(CAPI_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, + {ERR_REASON(CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER), + "invalid dsa public key blob magic number"}, + {ERR_REASON(CAPI_R_INVALID_LOOKUP_METHOD), "invalid lookup method"}, + {ERR_REASON(CAPI_R_INVALID_PUBLIC_KEY_BLOB), "invalid public key blob"}, + {ERR_REASON(CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER), + "invalid rsa public key blob magic number"}, + {ERR_REASON(CAPI_R_PUBKEY_EXPORT_ERROR), "pubkey export error"}, + {ERR_REASON(CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR), + "pubkey export length error"}, + {ERR_REASON(CAPI_R_UNKNOWN_COMMAND), "unknown command"}, + {ERR_REASON(CAPI_R_UNSUPPORTED_ALGORITHM_NID), + "unsupported algorithm nid"}, + {ERR_REASON(CAPI_R_UNSUPPORTED_PADDING), "unsupported padding"}, + {ERR_REASON(CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM), + "unsupported public key algorithm"}, + {ERR_REASON(CAPI_R_WIN32_ERROR), "win32 error"}, + {0, NULL} +}; + +#endif + +#ifdef CAPI_LIB_NAME +static ERR_STRING_DATA CAPI_lib_name[] = { + {0, CAPI_LIB_NAME}, + {0, NULL} +}; +#endif + +static int CAPI_lib_error_code = 0; +static int CAPI_error_init = 1; + +static void ERR_load_CAPI_strings(void) +{ + if (CAPI_lib_error_code == 0) + CAPI_lib_error_code = ERR_get_next_error_library(); + + if (CAPI_error_init) { + CAPI_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(CAPI_lib_error_code, CAPI_str_functs); + ERR_load_strings(CAPI_lib_error_code, CAPI_str_reasons); +#endif + +#ifdef CAPI_LIB_NAME + CAPI_lib_name->error = ERR_PACK(CAPI_lib_error_code, 0, 0); + ERR_load_strings(0, CAPI_lib_name); +#endif + } +} + +static void ERR_unload_CAPI_strings(void) +{ + if (CAPI_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(CAPI_lib_error_code, CAPI_str_functs); + ERR_unload_strings(CAPI_lib_error_code, CAPI_str_reasons); +#endif + +#ifdef CAPI_LIB_NAME + ERR_unload_strings(0, CAPI_lib_name); +#endif + CAPI_error_init = 1; + } +} + +static void ERR_CAPI_error(int function, int reason, char *file, int line) +{ + if (CAPI_lib_error_code == 0) + CAPI_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(CAPI_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_capi_err.h b/Sources/COpenSSL/e_capi_err.h new file mode 100644 index 00000000..b5d06dce --- /dev/null +++ b/Sources/COpenSSL/e_capi_err.h @@ -0,0 +1,129 @@ +/* ==================================================================== + * Copyright (c) 2001-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_CAPI_ERR_H +# define HEADER_CAPI_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_CAPI_strings(void); +static void ERR_unload_CAPI_strings(void); +static void ERR_CAPI_error(int function, int reason, char *file, int line); +# define CAPIerr(f,r) ERR_CAPI_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the CAPI functions. */ + +/* Function codes. */ +# define CAPI_F_CAPI_CERT_GET_FNAME 99 +# define CAPI_F_CAPI_CTRL 100 +# define CAPI_F_CAPI_CTX_NEW 101 +# define CAPI_F_CAPI_CTX_SET_PROVNAME 102 +# define CAPI_F_CAPI_DSA_DO_SIGN 114 +# define CAPI_F_CAPI_GET_KEY 103 +# define CAPI_F_CAPI_GET_PKEY 115 +# define CAPI_F_CAPI_GET_PROVNAME 104 +# define CAPI_F_CAPI_GET_PROV_INFO 105 +# define CAPI_F_CAPI_INIT 106 +# define CAPI_F_CAPI_LIST_CONTAINERS 107 +# define CAPI_F_CAPI_LOAD_PRIVKEY 108 +# define CAPI_F_CAPI_OPEN_STORE 109 +# define CAPI_F_CAPI_RSA_PRIV_DEC 110 +# define CAPI_F_CAPI_RSA_PRIV_ENC 111 +# define CAPI_F_CAPI_RSA_SIGN 112 +# define CAPI_F_CERT_SELECT_DIALOG 117 +# define CAPI_F_CLIENT_CERT_SELECT 116 +# define CAPI_F_WIDE_TO_ASC 113 + +/* Reason codes. */ +# define CAPI_R_CANT_CREATE_HASH_OBJECT 99 +# define CAPI_R_CANT_FIND_CAPI_CONTEXT 100 +# define CAPI_R_CANT_GET_KEY 101 +# define CAPI_R_CANT_SET_HASH_VALUE 102 +# define CAPI_R_CRYPTACQUIRECONTEXT_ERROR 103 +# define CAPI_R_CRYPTENUMPROVIDERS_ERROR 104 +# define CAPI_R_DECRYPT_ERROR 105 +# define CAPI_R_ENGINE_NOT_INITIALIZED 106 +# define CAPI_R_ENUMCONTAINERS_ERROR 107 +# define CAPI_R_ERROR_ADDING_CERT 125 +# define CAPI_R_ERROR_CREATING_STORE 126 +# define CAPI_R_ERROR_GETTING_FRIENDLY_NAME 108 +# define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO 109 +# define CAPI_R_ERROR_OPENING_STORE 110 +# define CAPI_R_ERROR_SIGNING_HASH 111 +# define CAPI_R_FUNCTION_NOT_SUPPORTED 112 +# define CAPI_R_GETUSERKEY_ERROR 113 +# define CAPI_R_INVALID_DIGEST_LENGTH 124 +# define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 122 +# define CAPI_R_INVALID_LOOKUP_METHOD 114 +# define CAPI_R_INVALID_PUBLIC_KEY_BLOB 115 +# define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 123 +# define CAPI_R_PUBKEY_EXPORT_ERROR 116 +# define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR 117 +# define CAPI_R_UNKNOWN_COMMAND 118 +# define CAPI_R_UNSUPPORTED_ALGORITHM_NID 119 +# define CAPI_R_UNSUPPORTED_PADDING 120 +# define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM 121 +# define CAPI_R_WIN32_ERROR 127 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_cast.c b/Sources/COpenSSL/e_cast.c new file mode 100644 index 00000000..c777c36e --- /dev/null +++ b/Sources/COpenSSL/e_cast.c @@ -0,0 +1,89 @@ +/* crypto/evp/e_cast.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_CAST +# include "evp.h" +# include "objects.h" +# include "evp_locl.h" +# include "cast.h" + +static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +typedef struct { + CAST_KEY ks; +} EVP_CAST_KEY; + +# define data(ctx) EVP_C_DATA(EVP_CAST_KEY,ctx) + +IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY, + NID_cast5, 8, CAST_KEY_LENGTH, 8, 64, + EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +#endif diff --git a/Sources/COpenSSL/e_chil.c b/Sources/COpenSSL/e_chil.c new file mode 100644 index 00000000..3abc504d --- /dev/null +++ b/Sources/COpenSSL/e_chil.c @@ -0,0 +1,1366 @@ +/* crypto/engine/e_chil.c */ +/* + * Written by Richard Levitte (richard@levitte.org), Geoff Thorpe + * (geoff@geoffthorpe.net) and Dr Stephen N Henson (steve@openssl.org) for + * the OpenSSL project 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "crypto.h" +#include "pem.h" +#include "dso.h" +#include "engine.h" +#include "ui.h" +#include "rand.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#include "bn.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_CHIL + +/*- + * Attribution notice: nCipher have said several times that it's OK for + * us to implement a general interface to their boxes, and recently declared + * their HWCryptoHook to be public, and therefore available for us to use. + * Thanks, nCipher. + * + * The hwcryptohook.h included here is from May 2000. + * [Richard Levitte] + */ +# ifdef FLAT_INC +# include "hwcryptohook.h" +# else +# include "hwcryptohook.h" +# endif + +# define HWCRHK_LIB_NAME "CHIL engine" +# include "e_chil_err.c" + +static int hwcrhk_destroy(ENGINE *e); +static int hwcrhk_init(ENGINE *e); +static int hwcrhk_finish(ENGINE *e); +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* Functions to handle mutexes */ +static int hwcrhk_mutex_init(HWCryptoHook_Mutex *, + HWCryptoHook_CallerContext *); +static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *); +static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex *); +static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *); + +/* BIGNUM stuff */ +static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +# ifndef OPENSSL_NO_RSA +/* RSA stuff */ +static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int hwcrhk_rsa_finish(RSA *rsa); +# endif + +# ifndef OPENSSL_NO_DH +/* DH stuff */ +/* This function is alised to mod_exp (with the DH and mont dropped). */ +static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +/* RAND stuff */ +static int hwcrhk_rand_bytes(unsigned char *buf, int num); +static int hwcrhk_rand_status(void); + +/* KM stuff */ +static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data); +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data); + +/* Interaction stuff */ +static int hwcrhk_insert_card(const char *prompt_info, + const char *wrong_info, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx); +static int hwcrhk_get_pass(const char *prompt_info, + int *len_io, char *buf, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx); +static void hwcrhk_log_message(void *logstr, const char *message); + +/* The definitions for control commands specific to this engine */ +# define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE +# define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1) +# define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2) +# define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3) +# define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4) +static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = { + {HWCRHK_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'hwcrhk' shared library", + ENGINE_CMD_FLAG_STRING}, + {HWCRHK_CMD_FORK_CHECK, + "FORK_CHECK", + "Turns fork() checking on (non-zero) or off (zero)", + ENGINE_CMD_FLAG_NUMERIC}, + {HWCRHK_CMD_THREAD_LOCKING, + "THREAD_LOCKING", + "Turns thread-safe locking on (zero) or off (non-zero)", + ENGINE_CMD_FLAG_NUMERIC}, + {HWCRHK_CMD_SET_USER_INTERFACE, + "SET_USER_INTERFACE", + "Set the global user interface (internal)", + ENGINE_CMD_FLAG_INTERNAL}, + {HWCRHK_CMD_SET_CALLBACK_DATA, + "SET_CALLBACK_DATA", + "Set the global user interface extra data (internal)", + ENGINE_CMD_FLAG_INTERNAL}, + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD hwcrhk_rsa = { + "CHIL RSA method", + NULL, + NULL, + NULL, + NULL, + hwcrhk_rsa_mod_exp, + hwcrhk_mod_exp_mont, + NULL, + hwcrhk_rsa_finish, + 0, + NULL, + NULL, + NULL, + NULL +}; +# endif + +# ifndef OPENSSL_NO_DH +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD hwcrhk_dh = { + "CHIL DH method", + NULL, + NULL, + hwcrhk_mod_exp_dh, + NULL, + NULL, + 0, + NULL, + NULL +}; +# endif + +static RAND_METHOD hwcrhk_rand = { + /* "CHIL RAND method", */ + NULL, + hwcrhk_rand_bytes, + NULL, + NULL, + hwcrhk_rand_bytes, + hwcrhk_rand_status, +}; + +/* Constants used when creating the ENGINE */ +static const char *engine_hwcrhk_id = "chil"; +static const char *engine_hwcrhk_name = "CHIL hardware engine support"; +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +/* Compatibility hack, the dynamic library uses this form in the path */ +static const char *engine_hwcrhk_id_alt = "ncipher"; +# endif + +/* Internal stuff for HWCryptoHook */ + +/* Some structures needed for proper use of thread locks */ +/* + * hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue + * into HWCryptoHook_Mutex + */ +struct HWCryptoHook_MutexValue { + int lockid; +}; + +/* + * hwcryptohook.h has some typedefs that turn struct + * HWCryptoHook_PassphraseContextValue into HWCryptoHook_PassphraseContext + */ +struct HWCryptoHook_PassphraseContextValue { + UI_METHOD *ui_method; + void *callback_data; +}; + +/* + * hwcryptohook.h has some typedefs that turn struct + * HWCryptoHook_CallerContextValue into HWCryptoHook_CallerContext + */ +struct HWCryptoHook_CallerContextValue { + pem_password_cb *password_callback; /* Deprecated! Only present for + * backward compatibility! */ + UI_METHOD *ui_method; + void *callback_data; +}; + +/* + * The MPI structure in HWCryptoHook is pretty compatible with OpenSSL + * BIGNUM's, so lets define a couple of conversion macros + */ +# define BN2MPI(mp, bn) \ + {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} +# define MPI2BN(bn, mp) \ + {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} + +static BIO *logstream = NULL; +static int disable_mutex_callbacks = 0; + +/* + * One might wonder why these are needed, since one can pass down at least a + * UI_METHOD and a pointer to callback data to the key-loading functions. The + * thing is that the ModExp and RSAImmed functions can load keys as well, if + * the data they get is in a special, nCipher-defined format (hint: if you + * look at the private exponent of the RSA data as a string, you'll see this + * string: "nCipher KM tool key id", followed by some bytes, followed a key + * identity string, followed by more bytes. This happens when you use + * "embed" keys instead of "hwcrhk" keys). Unfortunately, those functions do + * not take any passphrase or caller context, and our functions can't really + * take any callback data either. Still, the "insert_card" and + * "get_passphrase" callbacks may be called down the line, and will need to + * know what user interface callbacks to call, and having callback data from + * the application may be a nice thing as well, so we need to keep track of + * that globally. + */ +static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL }; + +/* Stuff to pass to the HWCryptoHook library */ +static HWCryptoHook_InitInfo hwcrhk_globals = { + HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */ + &logstream, /* logstream */ + sizeof(BN_ULONG), /* limbsize */ + 0, /* mslimb first: false for BNs */ + -1, /* msbyte first: use native */ + 0, /* Max mutexes, 0 = no small limit */ + 0, /* Max simultaneous, 0 = default */ + + /* + * The next few are mutex stuff: we write wrapper functions around the OS + * mutex functions. We initialise them to 0 here, and change that to + * actual function pointers in hwcrhk_init() if dynamic locks are + * supported (that is, if the application programmer has made sure of + * setting up callbacks bafore starting this engine) *and* if + * disable_mutex_callbacks hasn't been set by a call to + * ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). + */ + sizeof(HWCryptoHook_Mutex), + 0, + 0, + 0, + 0, + + /* + * The next few are condvar stuff: we write wrapper functions round the + * OS functions. Currently not implemented and not and absolute + * necessity even in threaded programs, therefore 0'ed. Will hopefully + * be implemented some day, since it enhances the efficiency of + * HWCryptoHook. + */ + 0, /* sizeof(HWCryptoHook_CondVar), */ + 0, /* hwcrhk_cv_init, */ + 0, /* hwcrhk_cv_wait, */ + 0, /* hwcrhk_cv_signal, */ + 0, /* hwcrhk_cv_broadcast, */ + 0, /* hwcrhk_cv_destroy, */ + + hwcrhk_get_pass, /* pass phrase */ + hwcrhk_insert_card, /* insert a card */ + hwcrhk_log_message /* Log message */ +}; + +/* Now, to our own code */ + +/* + * This internal function is used by ENGINE_chil() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif +# ifndef OPENSSL_NO_DH + const DH_METHOD *meth2; +# endif + if (!ENGINE_set_id(e, engine_hwcrhk_id) || + !ENGINE_set_name(e, engine_hwcrhk_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &hwcrhk_rsa) || +# endif +# ifndef OPENSSL_NO_DH + !ENGINE_set_DH(e, &hwcrhk_dh) || +# endif + !ENGINE_set_RAND(e, &hwcrhk_rand) || + !ENGINE_set_destroy_function(e, hwcrhk_destroy) || + !ENGINE_set_init_function(e, hwcrhk_init) || + !ENGINE_set_finish_function(e, hwcrhk_finish) || + !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) || + !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) || + !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) || + !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + /* + * We know that the "PKCS1_SSLeay()" functions hook properly to the + * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: + * We don't use ENGINE_openssl() or anything "more generic" because + * something like the RSAref code may not hook properly, and if you own + * one of these cards then you have the right to do RSA operations on it + * anyway! + */ + meth1 = RSA_PKCS1_SSLeay(); + hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; +# endif + +# ifndef OPENSSL_NO_DH + /* Much the same for Diffie-Hellman */ + meth2 = DH_OpenSSL(); + hwcrhk_dh.generate_key = meth2->generate_key; + hwcrhk_dh.compute_key = meth2->compute_key; +# endif + + /* Ensure the hwcrhk error handling is set up */ + ERR_load_HWCRHK_strings(); + return 1; +} + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_chil(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_chil(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_chil(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +/* + * This is a process-global DSO handle used for loading and unloading the + * HWCryptoHook library. NB: This is only set (or unset) during an init() or + * finish() call (reference counts permitting) and they're operating with + * global locks, so this should be thread-safe implicitly. + */ +static DSO *hwcrhk_dso = NULL; +static HWCryptoHook_ContextHandle hwcrhk_context = 0; +# ifndef OPENSSL_NO_RSA +/* Index for KM handle. Not really used yet. */ +static int hndidx_rsa = -1; +# endif + +/* + * These are the function pointers that are (un)set when the library has + * successfully (un)loaded. + */ +static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; +static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; +static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; +# ifndef OPENSSL_NO_RSA +static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; +# endif +static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; +# ifndef OPENSSL_NO_RSA +static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; +static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; +static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; +# endif +static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; + +/* Used in the DSO operations. */ +static const char *HWCRHK_LIBNAME = NULL; +static void free_HWCRHK_LIBNAME(void) +{ + if (HWCRHK_LIBNAME) + OPENSSL_free((void *)HWCRHK_LIBNAME); + HWCRHK_LIBNAME = NULL; +} + +static const char *get_HWCRHK_LIBNAME(void) +{ + if (HWCRHK_LIBNAME) + return HWCRHK_LIBNAME; + return "nfhwcrhk"; +} + +static long set_HWCRHK_LIBNAME(const char *name) +{ + free_HWCRHK_LIBNAME(); + return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); +} + +static const char *n_hwcrhk_Init = "HWCryptoHook_Init"; +static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish"; +static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp"; +# ifndef OPENSSL_NO_RSA +static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; +# endif +static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; +# ifndef OPENSSL_NO_RSA +static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; +static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; +static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; +# endif +static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; + +/* + * HWCryptoHook library functions and mechanics - these are used by the + * higher-level functions further down. NB: As and where there's no error + * checking, take a look lower down where these functions are called, the + * checking and error handling is probably down there. + */ + +/* utility function to obtain a context */ +static int get_context(HWCryptoHook_ContextHandle * hac, + HWCryptoHook_CallerContext * cac) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + + *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, cac); + if (!*hac) + return 0; + return 1; +} + +/* similarly to release one. */ +static void release_context(HWCryptoHook_ContextHandle hac) +{ + p_hwcrhk_Finish(hac); +} + +/* Destructor (complements the "ENGINE_chil()" constructor) */ +static int hwcrhk_destroy(ENGINE *e) +{ + free_HWCRHK_LIBNAME(); + ERR_unload_HWCRHK_strings(); + return 1; +} + +/* (de)initialisation functions. */ +static int hwcrhk_init(ENGINE *e) +{ + HWCryptoHook_Init_t *p1; + HWCryptoHook_Finish_t *p2; + HWCryptoHook_ModExp_t *p3; +# ifndef OPENSSL_NO_RSA + HWCryptoHook_RSA_t *p4; + HWCryptoHook_RSALoadKey_t *p5; + HWCryptoHook_RSAGetPublicKey_t *p6; + HWCryptoHook_RSAUnloadKey_t *p7; +# endif + HWCryptoHook_RandomBytes_t *p8; + HWCryptoHook_ModExpCRT_t *p9; + + if (hwcrhk_dso != NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ + hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0); + if (hwcrhk_dso == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE); + goto err; + } + if (!(p1 = (HWCryptoHook_Init_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) || + !(p2 = (HWCryptoHook_Finish_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) || + !(p3 = (HWCryptoHook_ModExp_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) || +# ifndef OPENSSL_NO_RSA + !(p4 = (HWCryptoHook_RSA_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) || + !(p5 = (HWCryptoHook_RSALoadKey_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) || + !(p6 = (HWCryptoHook_RSAGetPublicKey_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) || + !(p7 = (HWCryptoHook_RSAUnloadKey_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) || +# endif + !(p8 = (HWCryptoHook_RandomBytes_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) || + !(p9 = (HWCryptoHook_ModExpCRT_t *) + DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) { + HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE); + goto err; + } + /* Copy the pointers */ + p_hwcrhk_Init = p1; + p_hwcrhk_Finish = p2; + p_hwcrhk_ModExp = p3; +# ifndef OPENSSL_NO_RSA + p_hwcrhk_RSA = p4; + p_hwcrhk_RSALoadKey = p5; + p_hwcrhk_RSAGetPublicKey = p6; + p_hwcrhk_RSAUnloadKey = p7; +# endif + p_hwcrhk_RandomBytes = p8; + p_hwcrhk_ModExpCRT = p9; + + /* + * Check if the application decided to support dynamic locks, and if it + * does, use them. + */ + if (disable_mutex_callbacks == 0) { + if (CRYPTO_get_dynlock_create_callback() != NULL && + CRYPTO_get_dynlock_lock_callback() != NULL && + CRYPTO_get_dynlock_destroy_callback() != NULL) { + hwcrhk_globals.mutex_init = hwcrhk_mutex_init; + hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock; + hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; + hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; + } + } + + /* + * Try and get a context - if not, we may have a DSO but no accelerator! + */ + if (!get_context(&hwcrhk_context, &password_context)) { + HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_UNIT_FAILURE); + goto err; + } + /* Everything's fine. */ +# ifndef OPENSSL_NO_RSA + if (hndidx_rsa == -1) + hndidx_rsa = RSA_get_ex_new_index(0, + "nFast HWCryptoHook RSA key handle", + NULL, NULL, NULL); +# endif + return 1; + err: + if (hwcrhk_dso) + DSO_free(hwcrhk_dso); + hwcrhk_dso = NULL; + p_hwcrhk_Init = NULL; + p_hwcrhk_Finish = NULL; + p_hwcrhk_ModExp = NULL; +# ifndef OPENSSL_NO_RSA + p_hwcrhk_RSA = NULL; + p_hwcrhk_RSALoadKey = NULL; + p_hwcrhk_RSAGetPublicKey = NULL; + p_hwcrhk_RSAUnloadKey = NULL; +# endif + p_hwcrhk_ModExpCRT = NULL; + p_hwcrhk_RandomBytes = NULL; + return 0; +} + +static int hwcrhk_finish(ENGINE *e) +{ + int to_return = 1; + free_HWCRHK_LIBNAME(); + if (hwcrhk_dso == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_NOT_LOADED); + to_return = 0; + goto err; + } + release_context(hwcrhk_context); + if (!DSO_free(hwcrhk_dso)) { + HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_DSO_FAILURE); + to_return = 0; + goto err; + } + err: + if (logstream) + BIO_free(logstream); + hwcrhk_dso = NULL; + p_hwcrhk_Init = NULL; + p_hwcrhk_Finish = NULL; + p_hwcrhk_ModExp = NULL; +# ifndef OPENSSL_NO_RSA + p_hwcrhk_RSA = NULL; + p_hwcrhk_RSALoadKey = NULL; + p_hwcrhk_RSAGetPublicKey = NULL; + p_hwcrhk_RSAUnloadKey = NULL; +# endif + p_hwcrhk_ModExpCRT = NULL; + p_hwcrhk_RandomBytes = NULL; + return to_return; +} + +static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int to_return = 1; + + switch (cmd) { + case HWCRHK_CMD_SO_PATH: + if (hwcrhk_dso) { + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_ALREADY_LOADED); + return 0; + } + if (p == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return set_HWCRHK_LIBNAME((const char *)p); + case ENGINE_CTRL_SET_LOGSTREAM: + { + BIO *bio = (BIO *)p; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (logstream) { + BIO_free(logstream); + logstream = NULL; + } + if (CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO) > 1) + logstream = bio; + else + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_BIO_WAS_FREED); + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + case ENGINE_CTRL_SET_PASSWORD_CALLBACK: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + password_context.password_callback = (pem_password_cb *)f; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + case ENGINE_CTRL_SET_USER_INTERFACE: + case HWCRHK_CMD_SET_USER_INTERFACE: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + password_context.ui_method = (UI_METHOD *)p; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + case ENGINE_CTRL_SET_CALLBACK_DATA: + case HWCRHK_CMD_SET_CALLBACK_DATA: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + password_context.callback_data = p; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + /* + * this enables or disables the "SimpleForkCheck" flag used in the + * initialisation structure. + */ + case ENGINE_CTRL_CHIL_SET_FORKCHECK: + case HWCRHK_CMD_FORK_CHECK: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (i) + hwcrhk_globals.flags |= HWCryptoHook_InitFlags_SimpleForkCheck; + else + hwcrhk_globals.flags &= ~HWCryptoHook_InitFlags_SimpleForkCheck; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + /* + * This will prevent the initialisation function from "installing" + * the mutex-handling callbacks, even if they are available from + * within the library (or were provided to the library from the + * calling application). This is to remove any baggage for + * applications not using multithreading. + */ + case ENGINE_CTRL_CHIL_NO_LOCKING: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + disable_mutex_callbacks = 1; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + case HWCRHK_CMD_THREAD_LOCKING: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + disable_mutex_callbacks = ((i == 0) ? 0 : 1); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + + /* The command isn't understood by this engine */ + default: + HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, + HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); + to_return = 0; + break; + } + + return to_return; +} + +static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data) +{ +# ifndef OPENSSL_NO_RSA + RSA *rtmp = NULL; +# endif + EVP_PKEY *res = NULL; +# ifndef OPENSSL_NO_RSA + HWCryptoHook_MPI e, n; + HWCryptoHook_RSAKeyHandle *hptr; +# endif +# if !defined(OPENSSL_NO_RSA) + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + HWCryptoHook_PassphraseContext ppctx; +# endif + +# if !defined(OPENSSL_NO_RSA) + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); +# endif + + if (!hwcrhk_context) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NOT_INITIALISED); + goto err; + } +# ifndef OPENSSL_NO_RSA + hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); + if (!hptr) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + ppctx.ui_method = ui_method; + ppctx.callback_data = callback_data; + if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, &rmsg, &ppctx)) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); + ERR_add_error_data(1, rmsg.buf); + goto err; + } + if (!*hptr) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NO_KEY); + goto err; + } +# endif +# ifndef OPENSSL_NO_RSA + rtmp = RSA_new_method(eng); + if (rtmp == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr); + rtmp->e = BN_new(); + rtmp->n = BN_new(); + if (rtmp->e == NULL || rtmp->n == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + rtmp->flags |= RSA_FLAG_EXT_PKEY; + MPI2BN(rtmp->e, e); + MPI2BN(rtmp->n, n); + if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) + != HWCRYPTOHOOK_ERROR_MPISIZE) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); + ERR_add_error_data(1, rmsg.buf); + goto err; + } + + if (bn_expand2(rtmp->e, e.size / sizeof(BN_ULONG)) == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (bn_expand2(rtmp->n, n.size / sizeof(BN_ULONG)) == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + MPI2BN(rtmp->e, e); + MPI2BN(rtmp->n, n); + + if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); + ERR_add_error_data(1, rmsg.buf); + goto err; + } + rtmp->e->top = e.size / sizeof(BN_ULONG); + bn_fix_top(rtmp->e); + rtmp->n->top = n.size / sizeof(BN_ULONG); + bn_fix_top(rtmp->n); + + res = EVP_PKEY_new(); + if (res == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); + goto err; + } + EVP_PKEY_assign_RSA(res, rtmp); +# endif + + if (!res) + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, + HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED); + + return res; + err: +# ifndef OPENSSL_NO_RSA + if (rtmp) + RSA_free(rtmp); +# endif + return NULL; +} + +static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + EVP_PKEY *res = NULL; + +# ifndef OPENSSL_NO_RSA + res = hwcrhk_load_privkey(eng, key_id, ui_method, callback_data); +# endif + + if (res) + switch (res->type) { +# ifndef OPENSSL_NO_RSA + case EVP_PKEY_RSA: + { + RSA *rsa = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); + rsa = res->pkey.rsa; + res->pkey.rsa = RSA_new(); + res->pkey.rsa->n = rsa->n; + res->pkey.rsa->e = rsa->e; + rsa->n = NULL; + rsa->e = NULL; + CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + RSA_free(rsa); + } + break; +# endif + default: + HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, + HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); + goto err; + } + + return res; + err: + if (res) + EVP_PKEY_free(res); + return NULL; +} + +/* A little mod_exp */ +static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + /* + * Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, we use them + * directly, plus a little macro magic. We only thing we need to make + * sure of is that enough space is allocated. + */ + HWCryptoHook_MPI m_a, m_p, m_n, m_r; + int to_return, ret; + + to_return = 0; /* expect failure */ + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + + if (!hwcrhk_context) { + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_NOT_INITIALISED); + goto err; + } + /* Prepare the params */ + if (bn_expand2(r, m->top) == NULL) { /* Check for error !! */ + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, ERR_R_MALLOC_FAILURE); + goto err; + } + BN2MPI(m_a, a); + BN2MPI(m_p, p); + BN2MPI(m_n, m); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) { + /* + * FIXME: When this error is returned, HWCryptoHook is telling us + * that falling back to software computation might be a good thing. + */ + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FALLBACK); + } else { + HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FAILED); + } + ERR_add_error_data(1, rmsg.buf); + goto err; + } + + to_return = 1; + err: + return to_return; +} + +# ifndef OPENSSL_NO_RSA +static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + HWCryptoHook_RSAKeyHandle *hptr; + int to_return = 0, ret; + + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + + if (!hwcrhk_context) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_NOT_INITIALISED); + goto err; + } + + /* + * This provides support for nForce keys. Since that's opaque data all + * we do is provide a handle to the proper key and let HWCryptoHook take + * care of the rest. + */ + if ((hptr = + (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa)) + != NULL) { + HWCryptoHook_MPI m_a, m_r; + + if (!rsa->n) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_MISSING_KEY_COMPONENTS); + goto err; + } + + /* Prepare the params */ + if (bn_expand2(r, rsa->n->top) == NULL) { /* Check for error !! */ + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, ERR_R_MALLOC_FAILURE); + goto err; + } + BN2MPI(m_a, I); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) { + /* + * FIXME: When this error is returned, HWCryptoHook is telling us + * that falling back to software computation might be a good + * thing. + */ + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FALLBACK); + } else { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FAILED); + } + ERR_add_error_data(1, rmsg.buf); + goto err; + } + } else { + HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r; + + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_MISSING_KEY_COMPONENTS); + goto err; + } + + /* Prepare the params */ + if (bn_expand2(r, rsa->n->top) == NULL) { /* Check for error !! */ + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, ERR_R_MALLOC_FAILURE); + goto err; + } + BN2MPI(m_a, I); + BN2MPI(m_p, rsa->p); + BN2MPI(m_q, rsa->q); + BN2MPI(m_dmp1, rsa->dmp1); + BN2MPI(m_dmq1, rsa->dmq1); + BN2MPI(m_iqmp, rsa->iqmp); + MPI2BN(r, m_r); + + /* Perform the operation */ + ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q, + m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg); + + /* Convert the response */ + r->top = m_r.size / sizeof(BN_ULONG); + bn_fix_top(r); + + if (ret < 0) { + /* + * FIXME: When this error is returned, HWCryptoHook is telling us + * that falling back to software computation might be a good + * thing. + */ + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FALLBACK); + } else { + HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, + HWCRHK_R_REQUEST_FAILED); + } + ERR_add_error_data(1, rmsg.buf); + goto err; + } + } + /* + * If we're here, we must be here with some semblance of success :-) + */ + to_return = 1; + err: + return to_return; +} +# endif + +# ifndef OPENSSL_NO_RSA +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return hwcrhk_mod_exp(r, a, p, m, ctx); +} + +static int hwcrhk_rsa_finish(RSA *rsa) +{ + HWCryptoHook_RSAKeyHandle *hptr; + + hptr = RSA_get_ex_data(rsa, hndidx_rsa); + if (hptr) { + p_hwcrhk_RSAUnloadKey(*hptr, NULL); + OPENSSL_free(hptr); + RSA_set_ex_data(rsa, hndidx_rsa, NULL); + } + return 1; +} + +# endif + +# ifndef OPENSSL_NO_DH +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return hwcrhk_mod_exp(r, a, p, m, ctx); +} +# endif + +/* Random bytes are good */ +static int hwcrhk_rand_bytes(unsigned char *buf, int num) +{ + char tempbuf[1024]; + HWCryptoHook_ErrMsgBuf rmsg; + int to_return = 0; /* assume failure */ + int ret; + + rmsg.buf = tempbuf; + rmsg.size = sizeof(tempbuf); + + if (!hwcrhk_context) { + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_NOT_INITIALISED); + goto err; + } + + ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg); + if (ret < 0) { + /* + * FIXME: When this error is returned, HWCryptoHook is telling us + * that falling back to software computation might be a good thing. + */ + if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FALLBACK); + } else { + HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FAILED); + } + ERR_add_error_data(1, rmsg.buf); + goto err; + } + to_return = 1; + err: + return to_return; +} + +static int hwcrhk_rand_status(void) +{ + return 1; +} + +/* + * Mutex calls: since the HWCryptoHook model closely follows the POSIX model + * these just wrap the POSIX functions and add some logging. + */ + +static int hwcrhk_mutex_init(HWCryptoHook_Mutex * mt, + HWCryptoHook_CallerContext * cactx) +{ + mt->lockid = CRYPTO_get_new_dynlockid(); + if (mt->lockid == 0) + return 1; /* failure */ + return 0; /* success */ +} + +static int hwcrhk_mutex_lock(HWCryptoHook_Mutex * mt) +{ + CRYPTO_w_lock(mt->lockid); + return 0; +} + +static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) +{ + CRYPTO_w_unlock(mt->lockid); +} + +static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex * mt) +{ + CRYPTO_destroy_dynlockid(mt->lockid); +} + +static int hwcrhk_get_pass(const char *prompt_info, + int *len_io, char *buf, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx) +{ + pem_password_cb *callback = NULL; + void *callback_data = NULL; + UI_METHOD *ui_method = NULL; + /* + * Despite what the documentation says prompt_info can be an empty + * string. + */ + if (prompt_info && !*prompt_info) + prompt_info = NULL; + + if (cactx) { + if (cactx->ui_method) + ui_method = cactx->ui_method; + if (cactx->password_callback) + callback = cactx->password_callback; + if (cactx->callback_data) + callback_data = cactx->callback_data; + } + if (ppctx) { + if (ppctx->ui_method) { + ui_method = ppctx->ui_method; + callback = NULL; + } + if (ppctx->callback_data) + callback_data = ppctx->callback_data; + } + if (callback == NULL && ui_method == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS, HWCRHK_R_NO_CALLBACK); + return -1; + } + + if (ui_method) { + UI *ui = UI_new_method(ui_method); + if (ui) { + int ok; + char *prompt = UI_construct_prompt(ui, + "pass phrase", prompt_info); + + ok = UI_add_input_string(ui, prompt, + UI_INPUT_FLAG_DEFAULT_PWD, + buf, 0, (*len_io) - 1); + UI_add_user_data(ui, callback_data); + UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); + + if (ok >= 0) + do { + ok = UI_process(ui); + } + while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); + + if (ok >= 0) + *len_io = strlen(buf); + + UI_free(ui); + OPENSSL_free(prompt); + } + } else { + *len_io = callback(buf, *len_io, 0, callback_data); + } + if (!*len_io) + return -1; + return 0; +} + +static int hwcrhk_insert_card(const char *prompt_info, + const char *wrong_info, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx) +{ + int ok = -1; + UI *ui; + void *callback_data = NULL; + UI_METHOD *ui_method = NULL; + + if (cactx) { + if (cactx->ui_method) + ui_method = cactx->ui_method; + if (cactx->callback_data) + callback_data = cactx->callback_data; + } + if (ppctx) { + if (ppctx->ui_method) + ui_method = ppctx->ui_method; + if (ppctx->callback_data) + callback_data = ppctx->callback_data; + } + if (ui_method == NULL) { + HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD, HWCRHK_R_NO_CALLBACK); + return -1; + } + + ui = UI_new_method(ui_method); + + if (ui) { + char answer = '\0'; + char buf[BUFSIZ]; + /* + * Despite what the documentation says wrong_info can be an empty + * string. + */ + if (wrong_info && *wrong_info) + BIO_snprintf(buf, sizeof(buf) - 1, + "Current card: \"%s\"\n", wrong_info); + else + buf[0] = 0; + ok = UI_dup_info_string(ui, buf); + if (ok >= 0 && prompt_info) { + BIO_snprintf(buf, sizeof(buf) - 1, + "Insert card \"%s\"", prompt_info); + ok = UI_dup_input_boolean(ui, buf, + "\n then hit or C to cancel\n", + "\r\n", "Cc", UI_INPUT_FLAG_ECHO, + &answer); + } + UI_add_user_data(ui, callback_data); + + if (ok >= 0) + ok = UI_process(ui); + UI_free(ui); + + if (ok == -2 || (ok >= 0 && answer == 'C')) + ok = 1; + else if (ok < 0) + ok = -1; + else + ok = 0; + } + return ok; +} + +static void hwcrhk_log_message(void *logstr, const char *message) +{ + BIO *lstream = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_BIO); + if (logstr) + lstream = *(BIO **)logstr; + if (lstream) { + BIO_printf(lstream, "%s\n", message); + } + CRYPTO_w_unlock(CRYPTO_LOCK_BIO); +} + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_hwcrhk_id) != 0) && + (strcmp(id, engine_hwcrhk_id_alt) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ +# endif /* !OPENSSL_NO_HW_CHIL */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_chil_err.c b/Sources/COpenSSL/e_chil_err.c new file mode 100644 index 00000000..f341cc3c --- /dev/null +++ b/Sources/COpenSSL/e_chil_err.c @@ -0,0 +1,157 @@ +/* e_chil_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_chil_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA HWCRHK_str_functs[] = { + {ERR_FUNC(HWCRHK_F_HWCRHK_CTRL), "HWCRHK_CTRL"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_FINISH), "HWCRHK_FINISH"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_GET_PASS), "HWCRHK_GET_PASS"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_INIT), "HWCRHK_INIT"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_INSERT_CARD), "HWCRHK_INSERT_CARD"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PRIVKEY), "HWCRHK_LOAD_PRIVKEY"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PUBKEY), "HWCRHK_LOAD_PUBKEY"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_MOD_EXP), "HWCRHK_MOD_EXP"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_RAND_BYTES), "HWCRHK_RAND_BYTES"}, + {ERR_FUNC(HWCRHK_F_HWCRHK_RSA_MOD_EXP), "HWCRHK_RSA_MOD_EXP"}, + {0, NULL} +}; + +static ERR_STRING_DATA HWCRHK_str_reasons[] = { + {ERR_REASON(HWCRHK_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(HWCRHK_R_BIO_WAS_FREED), "bio was freed"}, + {ERR_REASON(HWCRHK_R_CHIL_ERROR), "chil error"}, + {ERR_REASON(HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(HWCRHK_R_DSO_FAILURE), "dso failure"}, + {ERR_REASON(HWCRHK_R_MISSING_KEY_COMPONENTS), "missing key components"}, + {ERR_REASON(HWCRHK_R_NOT_INITIALISED), "not initialised"}, + {ERR_REASON(HWCRHK_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(HWCRHK_R_NO_CALLBACK), "no callback"}, + {ERR_REASON(HWCRHK_R_NO_KEY), "no key"}, + {ERR_REASON(HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED), + "private key algorithms disabled"}, + {ERR_REASON(HWCRHK_R_REQUEST_FAILED), "request failed"}, + {ERR_REASON(HWCRHK_R_REQUEST_FALLBACK), "request fallback"}, + {ERR_REASON(HWCRHK_R_UNIT_FAILURE), "unit failure"}, + {0, NULL} +}; + +#endif + +#ifdef HWCRHK_LIB_NAME +static ERR_STRING_DATA HWCRHK_lib_name[] = { + {0, HWCRHK_LIB_NAME}, + {0, NULL} +}; +#endif + +static int HWCRHK_lib_error_code = 0; +static int HWCRHK_error_init = 1; + +static void ERR_load_HWCRHK_strings(void) +{ + if (HWCRHK_lib_error_code == 0) + HWCRHK_lib_error_code = ERR_get_next_error_library(); + + if (HWCRHK_error_init) { + HWCRHK_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(HWCRHK_lib_error_code, HWCRHK_str_functs); + ERR_load_strings(HWCRHK_lib_error_code, HWCRHK_str_reasons); +#endif + +#ifdef HWCRHK_LIB_NAME + HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code, 0, 0); + ERR_load_strings(0, HWCRHK_lib_name); +#endif + } +} + +static void ERR_unload_HWCRHK_strings(void) +{ + if (HWCRHK_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(HWCRHK_lib_error_code, HWCRHK_str_functs); + ERR_unload_strings(HWCRHK_lib_error_code, HWCRHK_str_reasons); +#endif + +#ifdef HWCRHK_LIB_NAME + ERR_unload_strings(0, HWCRHK_lib_name); +#endif + HWCRHK_error_init = 1; + } +} + +static void ERR_HWCRHK_error(int function, int reason, char *file, int line) +{ + if (HWCRHK_lib_error_code == 0) + HWCRHK_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(HWCRHK_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_chil_err.h b/Sources/COpenSSL/e_chil_err.h new file mode 100644 index 00000000..d86a4ce9 --- /dev/null +++ b/Sources/COpenSSL/e_chil_err.h @@ -0,0 +1,105 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_HWCRHK_ERR_H +# define HEADER_HWCRHK_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_HWCRHK_strings(void); +static void ERR_unload_HWCRHK_strings(void); +static void ERR_HWCRHK_error(int function, int reason, char *file, int line); +# define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the HWCRHK functions. */ + +/* Function codes. */ +# define HWCRHK_F_HWCRHK_CTRL 100 +# define HWCRHK_F_HWCRHK_FINISH 101 +# define HWCRHK_F_HWCRHK_GET_PASS 102 +# define HWCRHK_F_HWCRHK_INIT 103 +# define HWCRHK_F_HWCRHK_INSERT_CARD 104 +# define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 105 +# define HWCRHK_F_HWCRHK_LOAD_PUBKEY 106 +# define HWCRHK_F_HWCRHK_MOD_EXP 107 +# define HWCRHK_F_HWCRHK_RAND_BYTES 108 +# define HWCRHK_F_HWCRHK_RSA_MOD_EXP 109 + +/* Reason codes. */ +# define HWCRHK_R_ALREADY_LOADED 100 +# define HWCRHK_R_BIO_WAS_FREED 101 +# define HWCRHK_R_CHIL_ERROR 102 +# define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 +# define HWCRHK_R_DSO_FAILURE 104 +# define HWCRHK_R_MISSING_KEY_COMPONENTS 105 +# define HWCRHK_R_NOT_INITIALISED 106 +# define HWCRHK_R_NOT_LOADED 107 +# define HWCRHK_R_NO_CALLBACK 108 +# define HWCRHK_R_NO_KEY 109 +# define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 110 +# define HWCRHK_R_REQUEST_FAILED 111 +# define HWCRHK_R_REQUEST_FALLBACK 112 +# define HWCRHK_R_UNIT_FAILURE 113 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_cswift.c b/Sources/COpenSSL/e_cswift.c new file mode 100644 index 00000000..f0fcbc7e --- /dev/null +++ b/Sources/COpenSSL/e_cswift.c @@ -0,0 +1,1103 @@ +/* crypto/engine/hw_cswift.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "crypto.h" +#include "buffer.h" +#include "dso.h" +#include "engine.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#include "rand.h" +#include "bn.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_CSWIFT + +/* + * Attribution notice: Rainbow have generously allowed me to reproduce the + * necessary definitions here from their API. This means the support can + * build independently of whether application builders have the API or + * hardware. This will allow developers to easily produce software that has + * latent hardware support for any users that have accelerators installed, + * without the developers themselves needing anything extra. I have only + * clipped the parts from the CryptoSwift header files that are (or seem) + * relevant to the CryptoSwift support code. This is simply to keep the file + * sizes reasonable. [Geoff] + */ +# ifdef FLAT_INC +# include "cswift.h" +# else +# include "cswift.h" +# endif + +# define CSWIFT_LIB_NAME "cswift engine" +# include "e_cswift_err.c" + +# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) + +static int cswift_destroy(ENGINE *e); +static int cswift_init(ENGINE *e); +static int cswift_finish(ENGINE *e); +static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); +# ifndef OPENSSL_NO_RSA +static int cswift_bn_32copy(SW_LARGENUMBER *out, const BIGNUM *in); +# endif + +/* BIGNUM stuff */ +static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +# ifndef OPENSSL_NO_RSA +static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, + const BIGNUM *dmq1, const BIGNUM *iqmp, + BN_CTX *ctx); +# endif + +# ifndef OPENSSL_NO_RSA +/* RSA stuff */ +static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +# ifndef OPENSSL_NO_DSA +/* DSA stuff */ +static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, + DSA *dsa); +static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); +# endif + +# ifndef OPENSSL_NO_DH +/* DH stuff */ +/* This function is alised to mod_exp (with the DH and mont dropped). */ +static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif + +/* RAND stuff */ +static int cswift_rand_bytes(unsigned char *buf, int num); +static int cswift_rand_status(void); + +/* The definitions for control commands specific to this engine */ +# define CSWIFT_CMD_SO_PATH ENGINE_CMD_BASE +static const ENGINE_CMD_DEFN cswift_cmd_defns[] = { + {CSWIFT_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'cswift' shared library", + ENGINE_CMD_FLAG_STRING}, + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD cswift_rsa = { + "CryptoSwift RSA method", + NULL, + NULL, + NULL, + NULL, + cswift_rsa_mod_exp, + cswift_mod_exp_mont, + NULL, + NULL, + 0, + NULL, + NULL, + NULL, + NULL +}; +# endif + +# ifndef OPENSSL_NO_DSA +/* Our internal DSA_METHOD that we provide pointers to */ +static DSA_METHOD cswift_dsa = { + "CryptoSwift DSA method", + cswift_dsa_sign, + NULL, /* dsa_sign_setup */ + cswift_dsa_verify, + NULL, /* dsa_mod_exp */ + NULL, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* dsa_paramgen */ + NULL /* dsa_keygen */ +}; +# endif + +# ifndef OPENSSL_NO_DH +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD cswift_dh = { + "CryptoSwift DH method", + NULL, + NULL, + cswift_mod_exp_dh, + NULL, + NULL, + 0, + NULL, + NULL +}; +# endif + +static RAND_METHOD cswift_random = { + /* "CryptoSwift RAND method", */ + NULL, + cswift_rand_bytes, + NULL, + NULL, + cswift_rand_bytes, + cswift_rand_status, +}; + +/* Constants used when creating the ENGINE */ +static const char *engine_cswift_id = "cswift"; +static const char *engine_cswift_name = "CryptoSwift hardware engine support"; + +/* + * This internal function is used by ENGINE_cswift() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif +# ifndef OPENSSL_NO_DH + const DH_METHOD *meth2; +# endif + if (!ENGINE_set_id(e, engine_cswift_id) || + !ENGINE_set_name(e, engine_cswift_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &cswift_rsa) || +# endif +# ifndef OPENSSL_NO_DSA + !ENGINE_set_DSA(e, &cswift_dsa) || +# endif +# ifndef OPENSSL_NO_DH + !ENGINE_set_DH(e, &cswift_dh) || +# endif + !ENGINE_set_RAND(e, &cswift_random) || + !ENGINE_set_destroy_function(e, cswift_destroy) || + !ENGINE_set_init_function(e, cswift_init) || + !ENGINE_set_finish_function(e, cswift_finish) || + !ENGINE_set_ctrl_function(e, cswift_ctrl) || + !ENGINE_set_cmd_defns(e, cswift_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + /* + * We know that the "PKCS1_SSLeay()" functions hook properly to the + * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: + * We don't use ENGINE_openssl() or anything "more generic" because + * something like the RSAref code may not hook properly, and if you own + * one of these cards then you have the right to do RSA operations on it + * anyway! + */ + meth1 = RSA_PKCS1_SSLeay(); + cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec; +# endif + +# ifndef OPENSSL_NO_DH + /* Much the same for Diffie-Hellman */ + meth2 = DH_OpenSSL(); + cswift_dh.generate_key = meth2->generate_key; + cswift_dh.compute_key = meth2->compute_key; +# endif + + /* Ensure the cswift error handling is set up */ + ERR_load_CSWIFT_strings(); + return 1; +} + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_cswift(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_cswift(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_cswift(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +/* + * This is a process-global DSO handle used for loading and unloading the + * CryptoSwift library. NB: This is only set (or unset) during an init() or + * finish() call (reference counts permitting) and they're operating with + * global locks, so this should be thread-safe implicitly. + */ +static DSO *cswift_dso = NULL; + +/* + * These are the function pointers that are (un)set when the library has + * successfully (un)loaded. + */ +t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL; +t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL; +t_swSimpleRequest *p_CSwift_SimpleRequest = NULL; +t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL; + +/* Used in the DSO operations. */ +static const char *CSWIFT_LIBNAME = NULL; +static const char *get_CSWIFT_LIBNAME(void) +{ + if (CSWIFT_LIBNAME) + return CSWIFT_LIBNAME; + return "swift"; +} + +static void free_CSWIFT_LIBNAME(void) +{ + if (CSWIFT_LIBNAME) + OPENSSL_free((void *)CSWIFT_LIBNAME); + CSWIFT_LIBNAME = NULL; +} + +static long set_CSWIFT_LIBNAME(const char *name) +{ + free_CSWIFT_LIBNAME(); + return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); +} + +static const char *CSWIFT_F1 = "swAcquireAccContext"; +static const char *CSWIFT_F2 = "swAttachKeyParam"; +static const char *CSWIFT_F3 = "swSimpleRequest"; +static const char *CSWIFT_F4 = "swReleaseAccContext"; + +/* + * CryptoSwift library functions and mechanics - these are used by the + * higher-level functions further down. NB: As and where there's no error + * checking, take a look lower down where these functions are called, the + * checking and error handling is probably down there. + */ + +/* utility function to obtain a context */ +static int get_context(SW_CONTEXT_HANDLE *hac) +{ + SW_STATUS status; + + status = p_CSwift_AcquireAccContext(hac); + if (status != SW_OK) + return 0; + return 1; +} + +/* similarly to release one. */ +static void release_context(SW_CONTEXT_HANDLE hac) +{ + p_CSwift_ReleaseAccContext(hac); +} + +/* Destructor (complements the "ENGINE_cswift()" constructor) */ +static int cswift_destroy(ENGINE *e) +{ + free_CSWIFT_LIBNAME(); + ERR_unload_CSWIFT_strings(); + return 1; +} + +/* (de)initialisation functions. */ +static int cswift_init(ENGINE *e) +{ + SW_CONTEXT_HANDLE hac; + t_swAcquireAccContext *p1; + t_swAttachKeyParam *p2; + t_swSimpleRequest *p3; + t_swReleaseAccContext *p4; + + if (cswift_dso != NULL) { + CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libswift.so/swift.dll/whatever. */ + cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0); + if (cswift_dso == NULL) { + CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_NOT_LOADED); + goto err; + } + if (!(p1 = (t_swAcquireAccContext *) + DSO_bind_func(cswift_dso, CSWIFT_F1)) || + !(p2 = (t_swAttachKeyParam *) + DSO_bind_func(cswift_dso, CSWIFT_F2)) || + !(p3 = (t_swSimpleRequest *) + DSO_bind_func(cswift_dso, CSWIFT_F3)) || + !(p4 = (t_swReleaseAccContext *) + DSO_bind_func(cswift_dso, CSWIFT_F4))) { + CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_NOT_LOADED); + goto err; + } + /* Copy the pointers */ + p_CSwift_AcquireAccContext = p1; + p_CSwift_AttachKeyParam = p2; + p_CSwift_SimpleRequest = p3; + p_CSwift_ReleaseAccContext = p4; + /* + * Try and get a context - if not, we may have a DSO but no accelerator! + */ + if (!get_context(&hac)) { + CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_UNIT_FAILURE); + goto err; + } + release_context(hac); + /* Everything's fine. */ + return 1; + err: + if (cswift_dso) { + DSO_free(cswift_dso); + cswift_dso = NULL; + } + p_CSwift_AcquireAccContext = NULL; + p_CSwift_AttachKeyParam = NULL; + p_CSwift_SimpleRequest = NULL; + p_CSwift_ReleaseAccContext = NULL; + return 0; +} + +static int cswift_finish(ENGINE *e) +{ + free_CSWIFT_LIBNAME(); + if (cswift_dso == NULL) { + CSWIFTerr(CSWIFT_F_CSWIFT_FINISH, CSWIFT_R_NOT_LOADED); + return 0; + } + if (!DSO_free(cswift_dso)) { + CSWIFTerr(CSWIFT_F_CSWIFT_FINISH, CSWIFT_R_UNIT_FAILURE); + return 0; + } + cswift_dso = NULL; + p_CSwift_AcquireAccContext = NULL; + p_CSwift_AttachKeyParam = NULL; + p_CSwift_SimpleRequest = NULL; + p_CSwift_ReleaseAccContext = NULL; + return 1; +} + +static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int initialised = ((cswift_dso == NULL) ? 0 : 1); + switch (cmd) { + case CSWIFT_CMD_SO_PATH: + if (p == NULL) { + CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (initialised) { + CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_ALREADY_LOADED); + return 0; + } + return set_CSWIFT_LIBNAME((const char *)p); + default: + break; + } + CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +/* Un petit mod_exp */ +static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + /* + * I need somewhere to store temporary serialised values for use with the + * CryptoSwift API calls. A neat cheat - I'll use BIGNUMs from the BN_CTX + * but access their arrays directly as byte arrays . This way I + * don't have to clean anything up. + */ + BIGNUM *modulus; + BIGNUM *exponent; + BIGNUM *argument; + BIGNUM *result; + SW_STATUS sw_status; + SW_LARGENUMBER arg, res; + SW_PARAM sw_param; + SW_CONTEXT_HANDLE hac; + int to_return, acquired; + + modulus = exponent = argument = result = NULL; + to_return = 0; /* expect failure */ + acquired = 0; + + if (!get_context(&hac)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_UNIT_FAILURE); + goto err; + } + acquired = 1; + /* Prepare the params */ + BN_CTX_start(ctx); + modulus = BN_CTX_get(ctx); + exponent = BN_CTX_get(ctx); + argument = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if (!result) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BN_CTX_FULL); + goto err; + } + if (!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) || + !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + sw_param.type = SW_ALG_EXP; + sw_param.up.exp.modulus.nbytes = BN_bn2bin(m, + (unsigned char *)modulus->d); + sw_param.up.exp.modulus.value = (unsigned char *)modulus->d; + sw_param.up.exp.exponent.nbytes = BN_bn2bin(p, + (unsigned char *)exponent->d); + sw_param.up.exp.exponent.value = (unsigned char *)exponent->d; + /* Attach the key params */ + sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); + switch (sw_status) { + case SW_OK: + break; + case SW_ERR_INPUT_SIZE: + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BAD_KEY_SIZE); + goto err; + default: + { + char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + } + goto err; + } + /* Prepare the argument and response */ + arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); + arg.value = (unsigned char *)argument->d; + res.nbytes = BN_num_bytes(m); + memset(result->d, 0, res.nbytes); + res.value = (unsigned char *)result->d; + /* Perform the operation */ + if ((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1, + &res, 1)) != SW_OK) { + char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + goto err; + } + /* Convert the response */ + BN_bin2bn((unsigned char *)result->d, res.nbytes, r); + to_return = 1; + err: + if (acquired) + release_context(hac); + BN_CTX_end(ctx); + return to_return; +} + +# ifndef OPENSSL_NO_RSA +int cswift_bn_32copy(SW_LARGENUMBER *out, const BIGNUM *in) +{ + int mod; + int numbytes = BN_num_bytes(in); + + mod = 0; + while (((out->nbytes = (numbytes + mod)) % 32)) { + mod++; + } + out->value = (unsigned char *)OPENSSL_malloc(out->nbytes); + if (!out->value) { + return 0; + } + BN_bn2bin(in, &out->value[mod]); + if (mod) + memset(out->value, 0, mod); + + return 1; +} +# endif + +# ifndef OPENSSL_NO_RSA +/* Un petit mod_exp chinois */ +static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dmp1, + const BIGNUM *dmq1, const BIGNUM *iqmp, + BN_CTX *ctx) +{ + SW_STATUS sw_status; + SW_LARGENUMBER arg, res; + SW_PARAM sw_param; + SW_CONTEXT_HANDLE hac; + BIGNUM *result = NULL; + BIGNUM *argument = NULL; + int to_return = 0; /* expect failure */ + int acquired = 0; + + sw_param.up.crt.p.value = NULL; + sw_param.up.crt.q.value = NULL; + sw_param.up.crt.dmp1.value = NULL; + sw_param.up.crt.dmq1.value = NULL; + sw_param.up.crt.iqmp.value = NULL; + + if (!get_context(&hac)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_UNIT_FAILURE); + goto err; + } + acquired = 1; + + /* Prepare the params */ + argument = BN_new(); + result = BN_new(); + if (!result || !argument) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_CTX_FULL); + goto err; + } + + sw_param.type = SW_ALG_CRT; + /************************************************************************/ + /* + * 04/02/2003 + */ + /* + * Modified by Frederic Giudicelli (deny-all.com) to overcome the + */ + /* + * limitation of cswift with values not a multiple of 32 + */ + /************************************************************************/ + if (!cswift_bn_32copy(&sw_param.up.crt.p, p)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + if (!cswift_bn_32copy(&sw_param.up.crt.q, q)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + if (!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + if (!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + if (!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + if (!bn_wexpand(argument, a->top) || !bn_wexpand(result, p->top + q->top)) { + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + + /* Attach the key params */ + sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); + switch (sw_status) { + case SW_OK: + break; + case SW_ERR_INPUT_SIZE: + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BAD_KEY_SIZE); + goto err; + default: + { + char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + } + goto err; + } + /* Prepare the argument and response */ + arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); + arg.value = (unsigned char *)argument->d; + res.nbytes = 2 * BN_num_bytes(p); + memset(result->d, 0, res.nbytes); + res.value = (unsigned char *)result->d; + /* Perform the operation */ + if ((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1, + &res, 1)) != SW_OK) { + char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; + CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + goto err; + } + /* Convert the response */ + BN_bin2bn((unsigned char *)result->d, res.nbytes, r); + to_return = 1; + err: + if (sw_param.up.crt.p.value) + OPENSSL_free(sw_param.up.crt.p.value); + if (sw_param.up.crt.q.value) + OPENSSL_free(sw_param.up.crt.q.value); + if (sw_param.up.crt.dmp1.value) + OPENSSL_free(sw_param.up.crt.dmp1.value); + if (sw_param.up.crt.dmq1.value) + OPENSSL_free(sw_param.up.crt.dmq1.value); + if (sw_param.up.crt.iqmp.value) + OPENSSL_free(sw_param.up.crt.iqmp.value); + if (result) + BN_free(result); + if (argument) + BN_free(argument); + if (acquired) + release_context(hac); + return to_return; +} +# endif + +# ifndef OPENSSL_NO_RSA +static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + int to_return = 0; + const RSA_METHOD *def_rsa_method; + + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { + CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP, + CSWIFT_R_MISSING_KEY_COMPONENTS); + goto err; + } + + /* Try the limits of RSA (2048 bits) */ + if (BN_num_bytes(rsa->p) > 128 || + BN_num_bytes(rsa->q) > 128 || + BN_num_bytes(rsa->dmp1) > 128 || + BN_num_bytes(rsa->dmq1) > 128 || BN_num_bytes(rsa->iqmp) > 128) { +# ifdef RSA_NULL + def_rsa_method = RSA_null_method(); +# else +# if 0 + def_rsa_method = RSA_PKCS1_RSAref(); +# else + def_rsa_method = RSA_PKCS1_SSLeay(); +# endif +# endif + if (def_rsa_method) + return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx); + } + + to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, + rsa->dmq1, rsa->iqmp, ctx); + err: + return to_return; +} + +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + const RSA_METHOD *def_rsa_method; + + /* Try the limits of RSA (2048 bits) */ + if (BN_num_bytes(r) > 256 || + BN_num_bytes(a) > 256 || BN_num_bytes(m) > 256) { +# ifdef RSA_NULL + def_rsa_method = RSA_null_method(); +# else +# if 0 + def_rsa_method = RSA_PKCS1_RSAref(); +# else + def_rsa_method = RSA_PKCS1_SSLeay(); +# endif +# endif + if (def_rsa_method) + return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx); + } + + return cswift_mod_exp(r, a, p, m, ctx); +} +# endif /* OPENSSL_NO_RSA */ + +# ifndef OPENSSL_NO_DSA +static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + SW_CONTEXT_HANDLE hac; + SW_PARAM sw_param; + SW_STATUS sw_status; + SW_LARGENUMBER arg, res; + BN_CTX *ctx; + BIGNUM *dsa_p = NULL; + BIGNUM *dsa_q = NULL; + BIGNUM *dsa_g = NULL; + BIGNUM *dsa_key = NULL; + BIGNUM *result = NULL; + DSA_SIG *to_return = NULL; + int acquired = 0; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + if (!get_context(&hac)) { + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_UNIT_FAILURE); + goto err; + } + acquired = 1; + /* Prepare the params */ + BN_CTX_start(ctx); + dsa_p = BN_CTX_get(ctx); + dsa_q = BN_CTX_get(ctx); + dsa_g = BN_CTX_get(ctx); + dsa_key = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if (!result) { + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BN_CTX_FULL); + goto err; + } + if (!bn_wexpand(dsa_p, dsa->p->top) || + !bn_wexpand(dsa_q, dsa->q->top) || + !bn_wexpand(dsa_g, dsa->g->top) || + !bn_wexpand(dsa_key, dsa->priv_key->top) || + !bn_wexpand(result, dsa->p->top)) { + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + sw_param.type = SW_ALG_DSA; + sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, (unsigned char *)dsa_p->d); + sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; + sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, (unsigned char *)dsa_q->d); + sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; + sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, (unsigned char *)dsa_g->d); + sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; + sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key, + (unsigned char *)dsa_key->d); + sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; + /* Attach the key params */ + sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); + switch (sw_status) { + case SW_OK: + break; + case SW_ERR_INPUT_SIZE: + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BAD_KEY_SIZE); + goto err; + default: + { + char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + } + goto err; + } + /* Prepare the argument and response */ + arg.nbytes = dlen; + arg.value = (unsigned char *)dgst; + res.nbytes = BN_num_bytes(dsa->p); + memset(result->d, 0, res.nbytes); + res.value = (unsigned char *)result->d; + /* Perform the operation */ + sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1, + &res, 1); + if (sw_status != SW_OK) { + char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + goto err; + } + /* Convert the response */ + if ((to_return = DSA_SIG_new()) == NULL) + goto err; + to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL); + to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL); + + err: + if (acquired) + release_context(hac); + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return to_return; +} + +static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa) +{ + SW_CONTEXT_HANDLE hac; + SW_PARAM sw_param; + SW_STATUS sw_status; + SW_LARGENUMBER arg[2], res; + unsigned long sig_result; + BN_CTX *ctx; + BIGNUM *dsa_p = NULL; + BIGNUM *dsa_q = NULL; + BIGNUM *dsa_g = NULL; + BIGNUM *dsa_key = NULL; + BIGNUM *argument = NULL; + int to_return = -1; + int acquired = 0; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + if (!get_context(&hac)) { + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_UNIT_FAILURE); + goto err; + } + acquired = 1; + /* Prepare the params */ + BN_CTX_start(ctx); + dsa_p = BN_CTX_get(ctx); + dsa_q = BN_CTX_get(ctx); + dsa_g = BN_CTX_get(ctx); + dsa_key = BN_CTX_get(ctx); + argument = BN_CTX_get(ctx); + if (!argument) { + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BN_CTX_FULL); + goto err; + } + if (!bn_wexpand(dsa_p, dsa->p->top) || + !bn_wexpand(dsa_q, dsa->q->top) || + !bn_wexpand(dsa_g, dsa->g->top) || + !bn_wexpand(dsa_key, dsa->pub_key->top) || + !bn_wexpand(argument, 40)) { + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BN_EXPAND_FAIL); + goto err; + } + sw_param.type = SW_ALG_DSA; + sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, (unsigned char *)dsa_p->d); + sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; + sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, (unsigned char *)dsa_q->d); + sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; + sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, (unsigned char *)dsa_g->d); + sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; + sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key, + (unsigned char *)dsa_key->d); + sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; + /* Attach the key params */ + sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); + switch (sw_status) { + case SW_OK: + break; + case SW_ERR_INPUT_SIZE: + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BAD_KEY_SIZE); + goto err; + default: + { + char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + } + goto err; + } + /* Prepare the argument and response */ + arg[0].nbytes = dgst_len; + arg[0].value = (unsigned char *)dgst; + arg[1].nbytes = 40; + arg[1].value = (unsigned char *)argument->d; + memset(arg[1].value, 0, 40); + BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r)); + BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s)); + res.nbytes = 4; /* unsigned long */ + res.value = (unsigned char *)(&sig_result); + /* Perform the operation */ + sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2, + &res, 1); + if (sw_status != SW_OK) { + char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; + CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", sw_status); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + goto err; + } + /* Convert the response */ + to_return = ((sig_result == 0) ? 0 : 1); + + err: + if (acquired) + release_context(hac); + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return to_return; +} +# endif + +# ifndef OPENSSL_NO_DH +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return cswift_mod_exp(r, a, p, m, ctx); +} +# endif + +/* Random bytes are good */ +static int cswift_rand_bytes(unsigned char *buf, int num) +{ + SW_CONTEXT_HANDLE hac; + SW_STATUS swrc; + SW_LARGENUMBER largenum; + int acquired = 0; + int to_return = 0; /* assume failure */ + unsigned char buf32[1024]; + + if (!get_context(&hac)) { + CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE); + goto err; + } + acquired = 1; + + /************************************************************************/ + /* + * 04/02/2003 + */ + /* + * Modified by Frederic Giudicelli (deny-all.com) to overcome the + */ + /* + * limitation of cswift with values not a multiple of 32 + */ + /************************************************************************/ + + while (num >= (int)sizeof(buf32)) { + largenum.value = buf; + largenum.nbytes = sizeof(buf32); + /*- + * tell CryptoSwift how many bytes we want and where we want it. + * Note: - CryptoSwift cannot do more than 4096 bytes at a time. + * - CryptoSwift can only do multiple of 32-bits. + */ + swrc = + p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1); + if (swrc != SW_OK) { + char tmpbuf[20]; + CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", swrc); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + goto err; + } + buf += sizeof(buf32); + num -= sizeof(buf32); + } + if (num) { + largenum.nbytes = sizeof(buf32); + largenum.value = buf32; + swrc = + p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1); + if (swrc != SW_OK) { + char tmpbuf[20]; + CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED); + sprintf(tmpbuf, "%ld", swrc); + ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); + goto err; + } + memcpy(buf, largenum.value, num); + } + + to_return = 1; /* success */ + err: + if (acquired) + release_context(hac); + + return to_return; +} + +static int cswift_rand_status(void) +{ + return 1; +} + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_cswift_id) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ +# endif /* !OPENSSL_NO_HW_CSWIFT */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_cswift_err.c b/Sources/COpenSSL/e_cswift_err.c new file mode 100644 index 00000000..73baaf89 --- /dev/null +++ b/Sources/COpenSSL/e_cswift_err.c @@ -0,0 +1,150 @@ +/* e_cswift_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_cswift_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA CSWIFT_str_functs[] = { + {ERR_FUNC(CSWIFT_F_CSWIFT_CTRL), "CSWIFT_CTRL"}, + {ERR_FUNC(CSWIFT_F_CSWIFT_DSA_SIGN), "CSWIFT_DSA_SIGN"}, + {ERR_FUNC(CSWIFT_F_CSWIFT_DSA_VERIFY), "CSWIFT_DSA_VERIFY"}, + {ERR_FUNC(CSWIFT_F_CSWIFT_FINISH), "CSWIFT_FINISH"}, + {ERR_FUNC(CSWIFT_F_CSWIFT_INIT), "CSWIFT_INIT"}, + {ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP), "CSWIFT_MOD_EXP"}, + {ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP_CRT), "CSWIFT_MOD_EXP_CRT"}, + {ERR_FUNC(CSWIFT_F_CSWIFT_RAND_BYTES), "CSWIFT_RAND_BYTES"}, + {ERR_FUNC(CSWIFT_F_CSWIFT_RSA_MOD_EXP), "CSWIFT_RSA_MOD_EXP"}, + {0, NULL} +}; + +static ERR_STRING_DATA CSWIFT_str_reasons[] = { + {ERR_REASON(CSWIFT_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(CSWIFT_R_BAD_KEY_SIZE), "bad key size"}, + {ERR_REASON(CSWIFT_R_BN_CTX_FULL), "bn ctx full"}, + {ERR_REASON(CSWIFT_R_BN_EXPAND_FAIL), "bn expand fail"}, + {ERR_REASON(CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(CSWIFT_R_MISSING_KEY_COMPONENTS), "missing key components"}, + {ERR_REASON(CSWIFT_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(CSWIFT_R_REQUEST_FAILED), "request failed"}, + {ERR_REASON(CSWIFT_R_UNIT_FAILURE), "unit failure"}, + {0, NULL} +}; + +#endif + +#ifdef CSWIFT_LIB_NAME +static ERR_STRING_DATA CSWIFT_lib_name[] = { + {0, CSWIFT_LIB_NAME}, + {0, NULL} +}; +#endif + +static int CSWIFT_lib_error_code = 0; +static int CSWIFT_error_init = 1; + +static void ERR_load_CSWIFT_strings(void) +{ + if (CSWIFT_lib_error_code == 0) + CSWIFT_lib_error_code = ERR_get_next_error_library(); + + if (CSWIFT_error_init) { + CSWIFT_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(CSWIFT_lib_error_code, CSWIFT_str_functs); + ERR_load_strings(CSWIFT_lib_error_code, CSWIFT_str_reasons); +#endif + +#ifdef CSWIFT_LIB_NAME + CSWIFT_lib_name->error = ERR_PACK(CSWIFT_lib_error_code, 0, 0); + ERR_load_strings(0, CSWIFT_lib_name); +#endif + } +} + +static void ERR_unload_CSWIFT_strings(void) +{ + if (CSWIFT_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(CSWIFT_lib_error_code, CSWIFT_str_functs); + ERR_unload_strings(CSWIFT_lib_error_code, CSWIFT_str_reasons); +#endif + +#ifdef CSWIFT_LIB_NAME + ERR_unload_strings(0, CSWIFT_lib_name); +#endif + CSWIFT_error_init = 1; + } +} + +static void ERR_CSWIFT_error(int function, int reason, char *file, int line) +{ + if (CSWIFT_lib_error_code == 0) + CSWIFT_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(CSWIFT_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_cswift_err.h b/Sources/COpenSSL/e_cswift_err.h new file mode 100644 index 00000000..fde3a827 --- /dev/null +++ b/Sources/COpenSSL/e_cswift_err.h @@ -0,0 +1,99 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_CSWIFT_ERR_H +# define HEADER_CSWIFT_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_CSWIFT_strings(void); +static void ERR_unload_CSWIFT_strings(void); +static void ERR_CSWIFT_error(int function, int reason, char *file, int line); +# define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the CSWIFT functions. */ + +/* Function codes. */ +# define CSWIFT_F_CSWIFT_CTRL 100 +# define CSWIFT_F_CSWIFT_DSA_SIGN 101 +# define CSWIFT_F_CSWIFT_DSA_VERIFY 102 +# define CSWIFT_F_CSWIFT_FINISH 103 +# define CSWIFT_F_CSWIFT_INIT 104 +# define CSWIFT_F_CSWIFT_MOD_EXP 105 +# define CSWIFT_F_CSWIFT_MOD_EXP_CRT 106 +# define CSWIFT_F_CSWIFT_RAND_BYTES 108 +# define CSWIFT_F_CSWIFT_RSA_MOD_EXP 107 + +/* Reason codes. */ +# define CSWIFT_R_ALREADY_LOADED 100 +# define CSWIFT_R_BAD_KEY_SIZE 101 +# define CSWIFT_R_BN_CTX_FULL 102 +# define CSWIFT_R_BN_EXPAND_FAIL 103 +# define CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED 104 +# define CSWIFT_R_MISSING_KEY_COMPONENTS 105 +# define CSWIFT_R_NOT_LOADED 106 +# define CSWIFT_R_REQUEST_FAILED 107 +# define CSWIFT_R_UNIT_FAILURE 108 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_des.c b/Sources/COpenSSL/e_des.c new file mode 100644 index 00000000..4bb830dd --- /dev/null +++ b/Sources/COpenSSL/e_des.c @@ -0,0 +1,269 @@ +/* crypto/evp/e_des.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_DES +# include "evp.h" +# include "objects.h" +# include "evp_locl.h" +# include "des.h" +# include "rand.h" + +typedef struct { + union { + double align; + DES_key_schedule ks; + } ks; + union { + void (*cbc) (const void *, void *, size_t, + const DES_key_schedule *, unsigned char *); + } stream; +} EVP_DES_KEY; + +# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) +/* ----------^^^ this is not a typo, just a way to detect that + * assembler support was in general requested... */ +# include "sparc_arch.h" + +extern unsigned int OPENSSL_sparcv9cap_P[]; + +# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) + +void des_t4_key_expand(const void *key, DES_key_schedule *ks); +void des_t4_cbc_encrypt(const void *inp, void *out, size_t len, + const DES_key_schedule *ks, unsigned char iv[8]); +void des_t4_cbc_decrypt(const void *inp, void *out, size_t len, + const DES_key_schedule *ks, unsigned char iv[8]); +# endif + +static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +/* + * Because of various casts and different names can't use + * IMPLEMENT_BLOCK_CIPHER + */ + +static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + BLOCK_CIPHER_ecb_loop() + DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), + ctx->cipher_data, ctx->encrypt); + return 1; +} + +static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num); + return 1; +} + +static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; + + if (dat->stream.cbc != NULL) { + (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, ctx->iv); + return 1; + } + while (inl >= EVP_MAXCHUNK) { + DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + return 1; +} + +/* + * Although we have a CFB-r implementation for DES, it doesn't pack the right + * way, so wrap it here + */ +static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t n, chunk = EVP_MAXCHUNK / 8; + unsigned char c[1], d[1]; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + for (n = 0; n < chunk * 8; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + out[n / 8] = + (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | + ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +BLOCK_CIPHER_defs(des, EVP_DES_KEY, NID_des, 8, 8, 8, 64, + EVP_CIPH_RAND_KEY, des_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) + + BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 1, + EVP_CIPH_RAND_KEY, des_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) + + BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 8, + EVP_CIPH_RAND_KEY, des_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) + +static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; + + dat->stream.cbc = NULL; +# if defined(SPARC_DES_CAPABLE) + if (SPARC_DES_CAPABLE) { + int mode = ctx->cipher->flags & EVP_CIPH_MODE; + + if (mode == EVP_CIPH_CBC_MODE) { + des_t4_key_expand(key, &dat->ks.ks); + dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt; + return 1; + } + } +# endif +# ifdef EVP_CHECK_DES_KEY + if (DES_set_key_checked(deskey, dat->ks.ks) != 0) + return 0; +# else + DES_set_key_unchecked(deskey, ctx->cipher_data); +# endif + return 1; +} + +static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + + switch (type) { + case EVP_CTRL_RAND_KEY: + if (RAND_bytes(ptr, 8) <= 0) + return 0; + DES_set_odd_parity((DES_cblock *)ptr); + return 1; + + default: + return -1; + } +} + +#endif diff --git a/Sources/COpenSSL/e_des3.c b/Sources/COpenSSL/e_des3.c new file mode 100644 index 00000000..bd30bac1 --- /dev/null +++ b/Sources/COpenSSL/e_des3.c @@ -0,0 +1,497 @@ +/* crypto/evp/e_des3.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_DES +# include "evp.h" +# include "objects.h" +# include "evp_locl.h" +# include "des.h" +# include "rand.h" + +/* Block use of implementations in FIPS mode */ +# undef EVP_CIPH_FLAG_FIPS +# define EVP_CIPH_FLAG_FIPS 0 + +typedef struct { + union { + double align; + DES_key_schedule ks[3]; + } ks; + union { + void (*cbc) (const void *, void *, size_t, + const DES_key_schedule *, unsigned char *); + } stream; +} DES_EDE_KEY; +# define ks1 ks.ks[0] +# define ks2 ks.ks[1] +# define ks3 ks.ks[2] + +# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) +/* ---------^^^ this is not a typo, just a way to detect that + * assembler support was in general requested... */ +# include "sparc_arch.h" + +extern unsigned int OPENSSL_sparcv9cap_P[]; + +# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) + +void des_t4_key_expand(const void *key, DES_key_schedule *ks); +void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len, + const DES_key_schedule ks[3], unsigned char iv[8]); +void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len, + const DES_key_schedule ks[3], unsigned char iv[8]); +# endif + +static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +# define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data) + +/* + * Because of various casts and different args can't use + * IMPLEMENT_BLOCK_CIPHER + */ + +static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + BLOCK_CIPHER_ecb_loop() + DES_ecb3_encrypt((const_DES_cblock *)(in + i), + (DES_cblock *)(out + i), + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, ctx->encrypt); + return 1; +} + +static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ede3_ofb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &ctx->num); + + return 1; +} + +static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + DES_EDE_KEY *dat = data(ctx); + +# ifdef KSSL_DEBUG + { + int i; + fprintf(stderr, "des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx, + ctx->buf_len); + fprintf(stderr, "\t iv= "); + for (i = 0; i < 8; i++) + fprintf(stderr, "%02X", ctx->iv[i]); + fprintf(stderr, "\n"); + } +# endif /* KSSL_DEBUG */ + if (dat->stream.cbc) { + (*dat->stream.cbc) (in, out, inl, dat->ks.ks, ctx->iv); + return 1; + } + + while (inl >= EVP_MAXCHUNK) { + DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, + &dat->ks1, &dat->ks2, &dat->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cbc_encrypt(in, out, (long)inl, + &dat->ks1, &dat->ks2, &dat->ks3, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &ctx->num, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cfb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &ctx->num, ctx->encrypt); + return 1; +} + +/* + * Although we have a CFB-r implementation for 3-DES, it doesn't pack the + * right way, so wrap it here + */ +static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t n; + unsigned char c[1], d[1]; + + if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) + inl *= 8; + for (n = 0; n < inl; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + DES_ede3_cfb_encrypt(c, d, 1, 1, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + ctx->encrypt); + out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) + | ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } + + return 1; +} + +static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cfb_encrypt(in, out, 8, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + ctx->encrypt); + return 1; +} + +BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, + EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede_init_key, NULL, NULL, NULL, des3_ctrl) +# define des_ede3_cfb64_cipher des_ede_cfb64_cipher +# define des_ede3_ofb_cipher des_ede_ofb_cipher +# define des_ede3_cbc_cipher des_ede_cbc_cipher +# define des_ede3_ecb_cipher des_ede_ecb_cipher + BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, + EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | + EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, NULL, + des3_ctrl) + + BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1, + EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | + EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, + NULL, des3_ctrl) + + BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8, + EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | + EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, + NULL, des3_ctrl) + +static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + DES_EDE_KEY *dat = data(ctx); + + dat->stream.cbc = NULL; +# if defined(SPARC_DES_CAPABLE) + if (SPARC_DES_CAPABLE) { + int mode = ctx->cipher->flags & EVP_CIPH_MODE; + + if (mode == EVP_CIPH_CBC_MODE) { + des_t4_key_expand(&deskey[0], &dat->ks1); + des_t4_key_expand(&deskey[1], &dat->ks2); + memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1)); + dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt : + des_t4_ede3_cbc_decrypt; + return 1; + } + } +# endif +# ifdef EVP_CHECK_DES_KEY + if (DES_set_key_checked(&deskey[0], &dat->ks1) + || DES_set_key_checked(&deskey[1], &dat->ks2)) + return 0; +# else + DES_set_key_unchecked(&deskey[0], &dat->ks1); + DES_set_key_unchecked(&deskey[1], &dat->ks2); +# endif + memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1)); + return 1; +} + +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + DES_EDE_KEY *dat = data(ctx); + +# ifdef KSSL_DEBUG + { + int i; + fprintf(stderr, "des_ede3_init_key(ctx=%p)\n", ctx); + fprintf(stderr, "\tKEY= "); + for (i = 0; i < 24; i++) + fprintf(stderr, "%02X", key[i]); + fprintf(stderr, "\n"); + if (iv) { + fprintf(stderr, "\t IV= "); + for (i = 0; i < 8; i++) + fprintf(stderr, "%02X", iv[i]); + fprintf(stderr, "\n"); + } + } +# endif /* KSSL_DEBUG */ + + dat->stream.cbc = NULL; +# if defined(SPARC_DES_CAPABLE) + if (SPARC_DES_CAPABLE) { + int mode = ctx->cipher->flags & EVP_CIPH_MODE; + + if (mode == EVP_CIPH_CBC_MODE) { + des_t4_key_expand(&deskey[0], &dat->ks1); + des_t4_key_expand(&deskey[1], &dat->ks2); + des_t4_key_expand(&deskey[2], &dat->ks3); + dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt : + des_t4_ede3_cbc_decrypt; + return 1; + } + } +# endif +# ifdef EVP_CHECK_DES_KEY + if (DES_set_key_checked(&deskey[0], &dat->ks1) + || DES_set_key_checked(&deskey[1], &dat->ks2) + || DES_set_key_checked(&deskey[2], &dat->ks3)) + return 0; +# else + DES_set_key_unchecked(&deskey[0], &dat->ks1); + DES_set_key_unchecked(&deskey[1], &dat->ks2); + DES_set_key_unchecked(&deskey[2], &dat->ks3); +# endif + return 1; +} + +static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + + DES_cblock *deskey = ptr; + + switch (type) { + case EVP_CTRL_RAND_KEY: + if (RAND_bytes(ptr, c->key_len) <= 0) + return 0; + DES_set_odd_parity(deskey); + if (c->key_len >= 16) + DES_set_odd_parity(deskey + 1); + if (c->key_len >= 24) + DES_set_odd_parity(deskey + 2); + return 1; + + default: + return -1; + } +} + +const EVP_CIPHER *EVP_des_ede(void) +{ + return &des_ede_ecb; +} + +const EVP_CIPHER *EVP_des_ede3(void) +{ + return &des_ede3_ecb; +} + +# ifndef OPENSSL_NO_SHA + +# include "sha.h" + +static const unsigned char wrap_iv[8] = + { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 }; + +static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH]; + int rv = -1; + if (inl < 24) + return -1; + if (out == NULL) + return inl - 16; + memcpy(ctx->iv, wrap_iv, 8); + /* Decrypt first block which will end up as icv */ + des_ede_cbc_cipher(ctx, icv, in, 8); + /* Decrypt central blocks */ + /* + * If decrypting in place move whole output along a block so the next + * des_ede_cbc_cipher is in place. + */ + if (out == in) { + memmove(out, out + 8, inl - 8); + in -= 8; + } + des_ede_cbc_cipher(ctx, out, in + 8, inl - 16); + /* Decrypt final block which will be IV */ + des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8); + /* Reverse order of everything */ + BUF_reverse(icv, NULL, 8); + BUF_reverse(out, NULL, inl - 16); + BUF_reverse(ctx->iv, iv, 8); + /* Decrypt again using new IV */ + des_ede_cbc_cipher(ctx, out, out, inl - 16); + des_ede_cbc_cipher(ctx, icv, icv, 8); + /* Work out SHA1 hash of first portion */ + SHA1(out, inl - 16, sha1tmp); + + if (!CRYPTO_memcmp(sha1tmp, icv, 8)) + rv = inl - 16; + OPENSSL_cleanse(icv, 8); + OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); + OPENSSL_cleanse(iv, 8); + OPENSSL_cleanse(ctx->iv, 8); + if (rv == -1) + OPENSSL_cleanse(out, inl - 16); + + return rv; +} + +static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + unsigned char sha1tmp[SHA_DIGEST_LENGTH]; + if (out == NULL) + return inl + 16; + /* Copy input to output buffer + 8 so we have space for IV */ + memmove(out + 8, in, inl); + /* Work out ICV */ + SHA1(in, inl, sha1tmp); + memcpy(out + inl + 8, sha1tmp, 8); + OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); + /* Generate random IV */ + if (RAND_bytes(ctx->iv, 8) <= 0) + return -1; + memcpy(out, ctx->iv, 8); + /* Encrypt everything after IV in place */ + des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8); + BUF_reverse(out, NULL, inl + 16); + memcpy(ctx->iv, wrap_iv, 8); + des_ede_cbc_cipher(ctx, out, out, inl + 16); + return inl + 16; +} + +static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + /* + * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK + * is more than will ever be needed. Also input length must be a multiple + * of 8 bits. + */ + if (inl >= EVP_MAXCHUNK || inl % 8) + return -1; + if (ctx->encrypt) + return des_ede3_wrap(ctx, out, in, inl); + else + return des_ede3_unwrap(ctx, out, in, inl); +} + +static const EVP_CIPHER des3_wrap = { + NID_id_smime_alg_CMS3DESwrap, + 8, 24, 0, + EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER + | EVP_CIPH_FLAG_DEFAULT_ASN1, + des_ede3_init_key, des_ede3_wrap_cipher, + NULL, + sizeof(DES_EDE_KEY), + NULL, NULL, NULL, NULL +}; + +const EVP_CIPHER *EVP_des_ede3_wrap(void) +{ + return &des3_wrap; +} + +# endif +#endif diff --git a/Sources/COpenSSL/e_gmp.c b/Sources/COpenSSL/e_gmp.c new file mode 100644 index 00000000..5720d41c --- /dev/null +++ b/Sources/COpenSSL/e_gmp.c @@ -0,0 +1,492 @@ +/* crypto/engine/e_gmp.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This engine is not (currently) compiled in by default. Do enable it, + * reconfigure OpenSSL with "enable-gmp -lgmp". The GMP libraries and headers + * must reside in one of the paths searched by the compiler/linker, otherwise + * paths must be specified - eg. try configuring with "enable-gmp + * -I -L -lgmp". YMMV. + */ + +/*- + * As for what this does - it's a largely unoptimised implementation of an + * ENGINE that uses the GMP library to perform RSA private key operations. To + * obtain more information about what "unoptimised" means, see my original mail + * on the subject (though ignore the build instructions which have since + * changed); + * + * http://www.mail-archive.com/openssl-dev@openssl.org/msg12227.html + * + * On my athlon system at least, it appears the builtin OpenSSL code is now + * slightly faster, which is to say that the RSA-related MPI performance + * between OpenSSL's BIGNUM and GMP's mpz implementations is probably pretty + * balanced for this chip, and so the performance degradation in this ENGINE by + * having to convert to/from GMP formats (and not being able to cache + * montgomery forms) is probably the difference. However, if some unconfirmed + * reports from users is anything to go by, the situation on some other + * chipsets might be a good deal more favourable to the GMP version (eg. PPC). + * Feedback welcome. */ + +#include +#include +#include "crypto.h" +#include "buffer.h" +#include "engine.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#include "bn.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_GMP + +# include + +# define E_GMP_LIB_NAME "gmp engine" +# include "e_gmp_err.c" + +static int e_gmp_destroy(ENGINE *e); +static int e_gmp_init(ENGINE *e); +static int e_gmp_finish(ENGINE *e); +static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +# ifndef OPENSSL_NO_RSA +/* RSA stuff */ +static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +static int e_gmp_rsa_finish(RSA *r); +# endif + +/* The definitions for control commands specific to this engine */ +/* #define E_GMP_CMD_SO_PATH ENGINE_CMD_BASE */ +static const ENGINE_CMD_DEFN e_gmp_cmd_defns[] = { +# if 0 + {E_GMP_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'e_gmp' shared library", + ENGINE_CMD_FLAG_STRING}, +# endif + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD e_gmp_rsa = { + "GMP RSA method", + NULL, + NULL, + NULL, + NULL, + e_gmp_rsa_mod_exp, + NULL, + NULL, + e_gmp_rsa_finish, + /* + * These flags initialise montgomery crud that GMP ignores, however it + * makes sure the public key ops (which are done in openssl) don't seem + * *slower* than usual :-) + */ + RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE, + NULL, + NULL, + NULL +}; +# endif + +/* Constants used when creating the ENGINE */ +static const char *engine_e_gmp_id = "gmp"; +static const char *engine_e_gmp_name = "GMP engine support"; + +/* + * This internal function is used by ENGINE_gmp() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif + if (!ENGINE_set_id(e, engine_e_gmp_id) || + !ENGINE_set_name(e, engine_e_gmp_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &e_gmp_rsa) || +# endif + !ENGINE_set_destroy_function(e, e_gmp_destroy) || + !ENGINE_set_init_function(e, e_gmp_init) || + !ENGINE_set_finish_function(e, e_gmp_finish) || + !ENGINE_set_ctrl_function(e, e_gmp_ctrl) || + !ENGINE_set_cmd_defns(e, e_gmp_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + meth1 = RSA_PKCS1_SSLeay(); + e_gmp_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + e_gmp_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + e_gmp_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + e_gmp_rsa.rsa_priv_dec = meth1->rsa_priv_dec; + e_gmp_rsa.bn_mod_exp = meth1->bn_mod_exp; +# endif + + /* Ensure the e_gmp error handling is set up */ + ERR_load_GMP_strings(); + return 1; +} + +static ENGINE *engine_gmp(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_gmp(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_gmp(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} + +# ifndef OPENSSL_NO_RSA +/* Used to attach our own key-data to an RSA structure */ +static int hndidx_rsa = -1; +# endif + +static int e_gmp_destroy(ENGINE *e) +{ + ERR_unload_GMP_strings(); + return 1; +} + +/* (de)initialisation functions. */ +static int e_gmp_init(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + if (hndidx_rsa == -1) + hndidx_rsa = RSA_get_ex_new_index(0, + "GMP-based RSA key handle", + NULL, NULL, NULL); +# endif + if (hndidx_rsa == -1) + return 0; + return 1; +} + +static int e_gmp_finish(ENGINE *e) +{ + return 1; +} + +static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int to_return = 1; + + switch (cmd) { +# if 0 + case E_GMP_CMD_SO_PATH: + /* ... */ +# endif + /* The command isn't understood by this engine */ + default: + GMPerr(GMP_F_E_GMP_CTRL, GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED); + to_return = 0; + break; + } + + return to_return; +} + +/* + * Most often limb sizes will be the same. If not, we use hex conversion + * which is neat, but extremely inefficient. + */ +static int bn2gmp(const BIGNUM *bn, mpz_t g) +{ + bn_check_top(bn); + if (((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && + (BN_BITS2 == GMP_NUMB_BITS)) { + /* The common case */ + if (!_mpz_realloc(g, bn->top)) + return 0; + memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0])); + g->_mp_size = bn->top; + if (bn->neg) + g->_mp_size = -g->_mp_size; + return 1; + } else { + int toret; + char *tmpchar = BN_bn2hex(bn); + if (!tmpchar) + return 0; + toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0); + OPENSSL_free(tmpchar); + return toret; + } +} + +static int gmp2bn(mpz_t g, BIGNUM *bn) +{ + if (((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && + (BN_BITS2 == GMP_NUMB_BITS)) { + /* The common case */ + int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size; + BN_zero(bn); + if (bn_expand2(bn, s) == NULL) + return 0; + bn->top = s; + memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0])); + bn_correct_top(bn); + bn->neg = g->_mp_size >= 0 ? 0 : 1; + return 1; + } else { + int toret; + char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10); + if (!tmpchar) + return 0; + mpz_get_str(tmpchar, 16, g); + toret = BN_hex2bn(&bn, tmpchar); + OPENSSL_free(tmpchar); + return toret; + } +} + +# ifndef OPENSSL_NO_RSA +typedef struct st_e_gmp_rsa_ctx { + int public_only; + mpz_t n; + mpz_t d; + mpz_t e; + mpz_t p; + mpz_t q; + mpz_t dmp1; + mpz_t dmq1; + mpz_t iqmp; + mpz_t r0, r1, I0, m1; +} E_GMP_RSA_CTX; + +static E_GMP_RSA_CTX *e_gmp_get_rsa(RSA *rsa) +{ + E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa); + if (hptr) + return hptr; + hptr = OPENSSL_malloc(sizeof(E_GMP_RSA_CTX)); + if (!hptr) + return NULL; + /* + * These inits could probably be replaced by more intelligent mpz_init2() + * versions, to reduce malloc-thrashing. + */ + mpz_init(hptr->n); + mpz_init(hptr->d); + mpz_init(hptr->e); + mpz_init(hptr->p); + mpz_init(hptr->q); + mpz_init(hptr->dmp1); + mpz_init(hptr->dmq1); + mpz_init(hptr->iqmp); + mpz_init(hptr->r0); + mpz_init(hptr->r1); + mpz_init(hptr->I0); + mpz_init(hptr->m1); + if (!bn2gmp(rsa->n, hptr->n) || !bn2gmp(rsa->e, hptr->e)) + goto err; + if (!rsa->p || !rsa->q || !rsa->d || !rsa->dmp1 || !rsa->dmq1 + || !rsa->iqmp) { + hptr->public_only = 1; + return hptr; + } + if (!bn2gmp(rsa->d, hptr->d) || !bn2gmp(rsa->p, hptr->p) || + !bn2gmp(rsa->q, hptr->q) || !bn2gmp(rsa->dmp1, hptr->dmp1) || + !bn2gmp(rsa->dmq1, hptr->dmq1) || !bn2gmp(rsa->iqmp, hptr->iqmp)) + goto err; + hptr->public_only = 0; + RSA_set_ex_data(rsa, hndidx_rsa, hptr); + return hptr; + err: + mpz_clear(hptr->n); + mpz_clear(hptr->d); + mpz_clear(hptr->e); + mpz_clear(hptr->p); + mpz_clear(hptr->q); + mpz_clear(hptr->dmp1); + mpz_clear(hptr->dmq1); + mpz_clear(hptr->iqmp); + mpz_clear(hptr->r0); + mpz_clear(hptr->r1); + mpz_clear(hptr->I0); + mpz_clear(hptr->m1); + OPENSSL_free(hptr); + return NULL; +} + +static int e_gmp_rsa_finish(RSA *rsa) +{ + E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa); + if (!hptr) + return 0; + mpz_clear(hptr->n); + mpz_clear(hptr->d); + mpz_clear(hptr->e); + mpz_clear(hptr->p); + mpz_clear(hptr->q); + mpz_clear(hptr->dmp1); + mpz_clear(hptr->dmq1); + mpz_clear(hptr->iqmp); + mpz_clear(hptr->r0); + mpz_clear(hptr->r1); + mpz_clear(hptr->I0); + mpz_clear(hptr->m1); + OPENSSL_free(hptr); + RSA_set_ex_data(rsa, hndidx_rsa, NULL); + return 1; +} + +static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + E_GMP_RSA_CTX *hptr; + int to_return = 0; + + hptr = e_gmp_get_rsa(rsa); + if (!hptr) { + GMPerr(GMP_F_E_GMP_RSA_MOD_EXP, GMP_R_KEY_CONTEXT_ERROR); + return 0; + } + if (hptr->public_only) { + GMPerr(GMP_F_E_GMP_RSA_MOD_EXP, GMP_R_MISSING_KEY_COMPONENTS); + return 0; + } + + /* ugh!!! */ + if (!bn2gmp(I, hptr->I0)) + return 0; + + /* + * This is basically the CRT logic in crypto/rsa/rsa_eay.c reworded into + * GMP-speak. It may be that GMP's API facilitates cleaner formulations + * of this stuff, eg. better handling of negatives, or functions that + * combine operations. + */ + + mpz_mod(hptr->r1, hptr->I0, hptr->q); + mpz_powm(hptr->m1, hptr->r1, hptr->dmq1, hptr->q); + + mpz_mod(hptr->r1, hptr->I0, hptr->p); + mpz_powm(hptr->r0, hptr->r1, hptr->dmp1, hptr->p); + + mpz_sub(hptr->r0, hptr->r0, hptr->m1); + + if (mpz_sgn(hptr->r0) < 0) + mpz_add(hptr->r0, hptr->r0, hptr->p); + mpz_mul(hptr->r1, hptr->r0, hptr->iqmp); + mpz_mod(hptr->r0, hptr->r1, hptr->p); + + if (mpz_sgn(hptr->r0) < 0) + mpz_add(hptr->r0, hptr->r0, hptr->p); + mpz_mul(hptr->r1, hptr->r0, hptr->q); + mpz_add(hptr->r0, hptr->r1, hptr->m1); + + /* ugh!!! */ + if (gmp2bn(hptr->r0, r)) + to_return = 1; + + return 1; +} +# endif + +# endif /* !OPENSSL_NO_GMP */ + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +IMPLEMENT_DYNAMIC_CHECK_FN() +# ifndef OPENSSL_NO_GMP +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_e_gmp_id) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +# else +OPENSSL_EXPORT + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); +OPENSSL_EXPORT + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) +{ + return 0; +} +# endif +# endif /* !OPENSSL_NO_DYNAMIC_ENGINE */ + +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_gmp_err.c b/Sources/COpenSSL/e_gmp_err.c new file mode 100644 index 00000000..02f9f1d7 --- /dev/null +++ b/Sources/COpenSSL/e_gmp_err.c @@ -0,0 +1,137 @@ +/* e_gmp_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_gmp_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA GMP_str_functs[] = { + {ERR_FUNC(GMP_F_E_GMP_CTRL), "E_GMP_CTRL"}, + {ERR_FUNC(GMP_F_E_GMP_RSA_MOD_EXP), "E_GMP_RSA_MOD_EXP"}, + {0, NULL} +}; + +static ERR_STRING_DATA GMP_str_reasons[] = { + {ERR_REASON(GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(GMP_R_KEY_CONTEXT_ERROR), "key context error"}, + {ERR_REASON(GMP_R_MISSING_KEY_COMPONENTS), "missing key components"}, + {0, NULL} +}; + +#endif + +#ifdef GMP_LIB_NAME +static ERR_STRING_DATA GMP_lib_name[] = { + {0, GMP_LIB_NAME}, + {0, NULL} +}; +#endif + +static int GMP_lib_error_code = 0; +static int GMP_error_init = 1; + +static void ERR_load_GMP_strings(void) +{ + if (GMP_lib_error_code == 0) + GMP_lib_error_code = ERR_get_next_error_library(); + + if (GMP_error_init) { + GMP_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(GMP_lib_error_code, GMP_str_functs); + ERR_load_strings(GMP_lib_error_code, GMP_str_reasons); +#endif + +#ifdef GMP_LIB_NAME + GMP_lib_name->error = ERR_PACK(GMP_lib_error_code, 0, 0); + ERR_load_strings(0, GMP_lib_name); +#endif + } +} + +static void ERR_unload_GMP_strings(void) +{ + if (GMP_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(GMP_lib_error_code, GMP_str_functs); + ERR_unload_strings(GMP_lib_error_code, GMP_str_reasons); +#endif + +#ifdef GMP_LIB_NAME + ERR_unload_strings(0, GMP_lib_name); +#endif + GMP_error_init = 1; + } +} + +static void ERR_GMP_error(int function, int reason, char *file, int line) +{ + if (GMP_lib_error_code == 0) + GMP_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(GMP_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_gmp_err.h b/Sources/COpenSSL/e_gmp_err.h new file mode 100644 index 00000000..637abbc9 --- /dev/null +++ b/Sources/COpenSSL/e_gmp_err.h @@ -0,0 +1,86 @@ +/* ==================================================================== + * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_GMP_ERR_H +# define HEADER_GMP_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_GMP_strings(void); +static void ERR_unload_GMP_strings(void); +static void ERR_GMP_error(int function, int reason, char *file, int line); +# define GMPerr(f,r) ERR_GMP_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the GMP functions. */ + +/* Function codes. */ +# define GMP_F_E_GMP_CTRL 100 +# define GMP_F_E_GMP_RSA_MOD_EXP 101 + +/* Reason codes. */ +# define GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED 100 +# define GMP_R_KEY_CONTEXT_ERROR 101 +# define GMP_R_MISSING_KEY_COMPONENTS 102 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_gost_err.c b/Sources/COpenSSL/e_gost_err.c new file mode 100644 index 00000000..b2abfec7 --- /dev/null +++ b/Sources/COpenSSL/e_gost_err.c @@ -0,0 +1,221 @@ +/* e_gost_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_gost_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA GOST_str_functs[] = { + {ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"}, + {ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"}, + {ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"}, + {ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_PARAMS"}, + {ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "GET_ENCRYPTION_PARAMS"}, + {ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"}, + {ERR_FUNC(GOST_F_GOST2001_DO_SIGN), "GOST2001_DO_SIGN"}, + {ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"}, + {ERR_FUNC(GOST_F_GOST2001_KEYGEN), "GOST2001_KEYGEN"}, + {ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS), + "GOST89_GET_ASN1_PARAMETERS"}, + {ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS), + "GOST89_SET_ASN1_PARAMETERS"}, + {ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC), "GOST94_COMPUTE_PUBLIC"}, + {ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "GOST_CIPHER_CTL"}, + {ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"}, + {ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"}, + {ERR_FUNC(GOST_F_GOST_IMIT_CTRL), "GOST_IMIT_CTRL"}, + {ERR_FUNC(GOST_F_GOST_IMIT_FINAL), "GOST_IMIT_FINAL"}, + {ERR_FUNC(GOST_F_GOST_IMIT_UPDATE), "GOST_IMIT_UPDATE"}, + {ERR_FUNC(GOST_F_GOST_SIGN_KEYGEN), "GOST_SIGN_KEYGEN"}, + {ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"}, + {ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"}, + {ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT), "PKEY_GOST01CP_DECRYPT"}, + {ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "PKEY_GOST01CP_ENCRYPT"}, + {ERR_FUNC(GOST_F_PKEY_GOST01CP_KEYGEN), "PKEY_GOST01CP_KEYGEN"}, + {ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN), "PKEY_GOST01_PARAMGEN"}, + {ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE), "PKEY_GOST2001_DERIVE"}, + {ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT), "PKEY_GOST94CP_DECRYPT"}, + {ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT), "PKEY_GOST94CP_ENCRYPT"}, + {ERR_FUNC(GOST_F_PKEY_GOST94CP_KEYGEN), "PKEY_GOST94CP_KEYGEN"}, + {ERR_FUNC(GOST_F_PKEY_GOST94_PARAMGEN), "PKEY_GOST94_PARAMGEN"}, + {ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"}, + {ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR), "PKEY_GOST_CTRL01_STR"}, + {ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR), "PKEY_GOST_CTRL94_STR"}, + {ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL), "PKEY_GOST_MAC_CTRL"}, + {ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR), "PKEY_GOST_MAC_CTRL_STR"}, + {ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN), "PKEY_GOST_MAC_KEYGEN"}, + {ERR_FUNC(GOST_F_PRINT_GOST_01), "PRINT_GOST_01"}, + {ERR_FUNC(GOST_F_PRIV_DECODE_GOST), "PRIV_DECODE_GOST"}, + {ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"}, + {ERR_FUNC(GOST_F_PUB_DECODE_GOST94), "PUB_DECODE_GOST94"}, + {ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"}, + {ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"}, + {ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"}, + {0, NULL} +}; + +static ERR_STRING_DATA GOST_str_reasons[] = { + {ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT), + "bad key parameters format"}, + {ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT), + "bad pkey parameters format"}, + {ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY), + "cannot pack ephemeral key"}, + {ERR_REASON(GOST_R_CTRL_CALL_FAILED), "ctrl call failed"}, + {ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY), + "error computing shared key"}, + {ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO), + "error packing key transport info"}, + {ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO), + "error parsing key transport info"}, + {ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS), "incompatible algorithms"}, + {ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY), "incompatible peer key"}, + {ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS), "invalid cipher params"}, + {ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID), "invalid cipher param oid"}, + {ERR_REASON(GOST_R_INVALID_DIGEST_TYPE), "invalid digest type"}, + {ERR_REASON(GOST_R_INVALID_GOST94_PARMSET), "invalid gost94 parmset"}, + {ERR_REASON(GOST_R_INVALID_IV_LENGTH), "invalid iv length"}, + {ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH), "invalid mac key length"}, + {ERR_REASON(GOST_R_INVALID_PARAMSET), "invalid paramset"}, + {ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED), "key is not initalized"}, + {ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED), "key is not initialized"}, + {ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING), "key parameters missing"}, + {ERR_REASON(GOST_R_MAC_KEY_NOT_SET), "mac key not set"}, + {ERR_REASON(GOST_R_MALLOC_FAILURE), "malloc failure"}, + {ERR_REASON(GOST_R_NO_MEMORY), "no memory"}, + {ERR_REASON(GOST_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_REASON(GOST_R_NO_PEER_KEY), "no peer key"}, + {ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR), + "no private part of non ephemeral keypair"}, + {ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED), "public key undefined"}, + {ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR), "random generator error"}, + {ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE), "random generator failure"}, + {ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED), + "random number generator failed"}, + {ERR_REASON(GOST_R_SIGNATURE_MISMATCH), "signature mismatch"}, + {ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q), + "signature parts greater than q"}, + {ERR_REASON(GOST_R_UKM_NOT_SET), "ukm not set"}, + {ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND), + "unsupported cipher ctl command"}, + {ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET), + "unsupported parameter set"}, + {0, NULL} +}; + +#endif + +#ifdef GOST_LIB_NAME +static ERR_STRING_DATA GOST_lib_name[] = { + {0, GOST_LIB_NAME}, + {0, NULL} +}; +#endif + +static int GOST_lib_error_code = 0; +static int GOST_error_init = 1; + +void ERR_load_GOST_strings(void) +{ + if (GOST_lib_error_code == 0) + GOST_lib_error_code = ERR_get_next_error_library(); + + if (GOST_error_init) { + GOST_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(GOST_lib_error_code, GOST_str_functs); + ERR_load_strings(GOST_lib_error_code, GOST_str_reasons); +#endif + +#ifdef GOST_LIB_NAME + GOST_lib_name->error = ERR_PACK(GOST_lib_error_code, 0, 0); + ERR_load_strings(0, GOST_lib_name); +#endif + } +} + +void ERR_unload_GOST_strings(void) +{ + if (GOST_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(GOST_lib_error_code, GOST_str_functs); + ERR_unload_strings(GOST_lib_error_code, GOST_str_reasons); +#endif + +#ifdef GOST_LIB_NAME + ERR_unload_strings(0, GOST_lib_name); +#endif + GOST_error_init = 1; + } +} + +void ERR_GOST_error(int function, int reason, char *file, int line) +{ + if (GOST_lib_error_code == 0) + GOST_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(GOST_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_gost_err.h b/Sources/COpenSSL/e_gost_err.h new file mode 100644 index 00000000..a2018ec4 --- /dev/null +++ b/Sources/COpenSSL/e_gost_err.h @@ -0,0 +1,158 @@ +/* ==================================================================== + * Copyright (c) 2001-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_GOST_ERR_H +# define HEADER_GOST_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_GOST_strings(void); +void ERR_unload_GOST_strings(void); +void ERR_GOST_error(int function, int reason, char *file, int line); +# define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the GOST functions. */ + +/* Function codes. */ +# define GOST_F_DECODE_GOST_ALGOR_PARAMS 99 +# define GOST_F_ENCODE_GOST_ALGOR_PARAMS 100 +# define GOST_F_FILL_GOST2001_PARAMS 101 +# define GOST_F_FILL_GOST94_PARAMS 102 +# define GOST_F_GET_ENCRYPTION_PARAMS 103 +# define GOST_F_GOST2001_COMPUTE_PUBLIC 104 +# define GOST_F_GOST2001_DO_SIGN 105 +# define GOST_F_GOST2001_DO_VERIFY 106 +# define GOST_F_GOST2001_KEYGEN 107 +# define GOST_F_GOST89_GET_ASN1_PARAMETERS 108 +# define GOST_F_GOST89_SET_ASN1_PARAMETERS 109 +# define GOST_F_GOST94_COMPUTE_PUBLIC 110 +# define GOST_F_GOST_CIPHER_CTL 111 +# define GOST_F_GOST_DO_SIGN 112 +# define GOST_F_GOST_DO_VERIFY 113 +# define GOST_F_GOST_IMIT_CTRL 114 +# define GOST_F_GOST_IMIT_FINAL 140 +# define GOST_F_GOST_IMIT_UPDATE 115 +# define GOST_F_GOST_SIGN_KEYGEN 142 +# define GOST_F_PARAM_COPY_GOST01 116 +# define GOST_F_PARAM_COPY_GOST94 117 +# define GOST_F_PKEY_GOST01CP_DECRYPT 118 +# define GOST_F_PKEY_GOST01CP_ENCRYPT 119 +# define GOST_F_PKEY_GOST01CP_KEYGEN 120 +# define GOST_F_PKEY_GOST01_PARAMGEN 138 +# define GOST_F_PKEY_GOST2001_DERIVE 121 +# define GOST_F_PKEY_GOST94CP_DECRYPT 122 +# define GOST_F_PKEY_GOST94CP_ENCRYPT 123 +# define GOST_F_PKEY_GOST94CP_KEYGEN 124 +# define GOST_F_PKEY_GOST94_PARAMGEN 139 +# define GOST_F_PKEY_GOST_CTRL 125 +# define GOST_F_PKEY_GOST_CTRL01_STR 126 +# define GOST_F_PKEY_GOST_CTRL94_STR 127 +# define GOST_F_PKEY_GOST_MAC_CTRL 128 +# define GOST_F_PKEY_GOST_MAC_CTRL_STR 129 +# define GOST_F_PKEY_GOST_MAC_KEYGEN 130 +# define GOST_F_PRINT_GOST_01 131 +# define GOST_F_PRIV_DECODE_GOST 132 +# define GOST_F_PUB_DECODE_GOST01 133 +# define GOST_F_PUB_DECODE_GOST94 134 +# define GOST_F_PUB_ENCODE_GOST01 135 +# define GOST_F_UNPACK_CC_SIGNATURE 136 +# define GOST_F_UNPACK_CP_SIGNATURE 137 + +/* Reason codes. */ +# define GOST_R_BAD_KEY_PARAMETERS_FORMAT 99 +# define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 100 +# define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 101 +# define GOST_R_CTRL_CALL_FAILED 132 +# define GOST_R_ERROR_COMPUTING_SHARED_KEY 102 +# define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO 103 +# define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 104 +# define GOST_R_INCOMPATIBLE_ALGORITHMS 105 +# define GOST_R_INCOMPATIBLE_PEER_KEY 131 +# define GOST_R_INVALID_CIPHER_PARAMS 106 +# define GOST_R_INVALID_CIPHER_PARAM_OID 107 +# define GOST_R_INVALID_DIGEST_TYPE 108 +# define GOST_R_INVALID_GOST94_PARMSET 109 +# define GOST_R_INVALID_IV_LENGTH 110 +# define GOST_R_INVALID_MAC_KEY_LENGTH 111 +# define GOST_R_INVALID_PARAMSET 112 +# define GOST_R_KEY_IS_NOT_INITALIZED 113 +# define GOST_R_KEY_IS_NOT_INITIALIZED 114 +# define GOST_R_KEY_PARAMETERS_MISSING 115 +# define GOST_R_MAC_KEY_NOT_SET 116 +# define GOST_R_MALLOC_FAILURE 117 +# define GOST_R_NO_MEMORY 118 +# define GOST_R_NO_PARAMETERS_SET 119 +# define GOST_R_NO_PEER_KEY 120 +# define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 121 +# define GOST_R_PUBLIC_KEY_UNDEFINED 122 +# define GOST_R_RANDOM_GENERATOR_ERROR 123 +# define GOST_R_RANDOM_GENERATOR_FAILURE 124 +# define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 125 +# define GOST_R_SIGNATURE_MISMATCH 126 +# define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 127 +# define GOST_R_UKM_NOT_SET 128 +# define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND 129 +# define GOST_R_UNSUPPORTED_PARAMETER_SET 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_idea.c b/Sources/COpenSSL/e_idea.c new file mode 100644 index 00000000..bd01a781 --- /dev/null +++ b/Sources/COpenSSL/e_idea.c @@ -0,0 +1,119 @@ +/* crypto/evp/e_idea.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_IDEA +# include "evp.h" +# include "objects.h" +# include "evp_locl.h" +# include "idea.h" + +static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +/* + * NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a + * special case + */ + +static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + BLOCK_CIPHER_ecb_loop() + idea_ecb_encrypt(in + i, out + i, ctx->cipher_data); + return 1; +} + +/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */ + +typedef struct { + IDEA_KEY_SCHEDULE ks; +} EVP_IDEA_KEY; + +BLOCK_CIPHER_func_cbc(idea, idea, EVP_IDEA_KEY, ks) + BLOCK_CIPHER_func_ofb(idea, idea, 64, EVP_IDEA_KEY, ks) + BLOCK_CIPHER_func_cfb(idea, idea, 64, EVP_IDEA_KEY, ks) + + BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64, + 0, idea_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + if (!enc) { + if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) + enc = 1; + else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) + enc = 1; + } + if (enc) + idea_set_encrypt_key(key, ctx->cipher_data); + else { + IDEA_KEY_SCHEDULE tmp; + + idea_set_encrypt_key(key, &tmp); + idea_set_decrypt_key(&tmp, ctx->cipher_data); + OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE)); + } + return 1; +} + +#endif diff --git a/Sources/COpenSSL/e_null.c b/Sources/COpenSSL/e_null.c new file mode 100644 index 00000000..33320a6d --- /dev/null +++ b/Sources/COpenSSL/e_null.c @@ -0,0 +1,100 @@ +/* crypto/evp/e_null.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "objects.h" + +static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +static const EVP_CIPHER n_cipher = { + NID_undef, + 1, 0, 0, + 0, + null_init_key, + null_cipher, + NULL, + 0, + NULL, + NULL, + NULL, + NULL +}; + +const EVP_CIPHER *EVP_enc_null(void) +{ + return (&n_cipher); +} + +static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + /* memset(&(ctx->c),0,sizeof(ctx->c)); */ + return 1; +} + +static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + if (in != out) + memcpy((char *)out, (const char *)in, inl); + return 1; +} diff --git a/Sources/COpenSSL/e_nuron.c b/Sources/COpenSSL/e_nuron.c new file mode 100644 index 00000000..1c943521 --- /dev/null +++ b/Sources/COpenSSL/e_nuron.c @@ -0,0 +1,436 @@ +/* crypto/engine/hw_nuron.c */ +/* + * Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff + * Thorpe's Atalla implementation. + */ +/* ==================================================================== + * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "crypto.h" +#include "buffer.h" +#include "dso.h" +#include "engine.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#include "bn.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_NURON + +# define NURON_LIB_NAME "nuron engine" +# include "e_nuron_err.c" + +static const char *NURON_LIBNAME = NULL; +static const char *get_NURON_LIBNAME(void) +{ + if (NURON_LIBNAME) + return NURON_LIBNAME; + return "nuronssl"; +} + +static void free_NURON_LIBNAME(void) +{ + if (NURON_LIBNAME) + OPENSSL_free((void *)NURON_LIBNAME); + NURON_LIBNAME = NULL; +} + +static long set_NURON_LIBNAME(const char *name) +{ + free_NURON_LIBNAME(); + return (((NURON_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); +} + +static const char *NURON_F1 = "nuron_mod_exp"; + +/* The definitions for control commands specific to this engine */ +# define NURON_CMD_SO_PATH ENGINE_CMD_BASE +static const ENGINE_CMD_DEFN nuron_cmd_defns[] = { + {NURON_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'nuronssl' shared library", + ENGINE_CMD_FLAG_STRING}, + {0, NULL, NULL, 0} +}; + +typedef int tfnModExp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m); +static tfnModExp *pfnModExp = NULL; + +static DSO *pvDSOHandle = NULL; + +static int nuron_destroy(ENGINE *e) +{ + free_NURON_LIBNAME(); + ERR_unload_NURON_strings(); + return 1; +} + +static int nuron_init(ENGINE *e) +{ + if (pvDSOHandle != NULL) { + NURONerr(NURON_F_NURON_INIT, NURON_R_ALREADY_LOADED); + return 0; + } + + pvDSOHandle = DSO_load(NULL, get_NURON_LIBNAME(), NULL, + DSO_FLAG_NAME_TRANSLATION_EXT_ONLY); + if (!pvDSOHandle) { + NURONerr(NURON_F_NURON_INIT, NURON_R_DSO_NOT_FOUND); + return 0; + } + + pfnModExp = (tfnModExp *) DSO_bind_func(pvDSOHandle, NURON_F1); + if (!pfnModExp) { + NURONerr(NURON_F_NURON_INIT, NURON_R_DSO_FUNCTION_NOT_FOUND); + return 0; + } + + return 1; +} + +static int nuron_finish(ENGINE *e) +{ + free_NURON_LIBNAME(); + if (pvDSOHandle == NULL) { + NURONerr(NURON_F_NURON_FINISH, NURON_R_NOT_LOADED); + return 0; + } + if (!DSO_free(pvDSOHandle)) { + NURONerr(NURON_F_NURON_FINISH, NURON_R_DSO_FAILURE); + return 0; + } + pvDSOHandle = NULL; + pfnModExp = NULL; + return 1; +} + +static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int initialised = ((pvDSOHandle == NULL) ? 0 : 1); + switch (cmd) { + case NURON_CMD_SO_PATH: + if (p == NULL) { + NURONerr(NURON_F_NURON_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (initialised) { + NURONerr(NURON_F_NURON_CTRL, NURON_R_ALREADY_LOADED); + return 0; + } + return set_NURON_LIBNAME((const char *)p); + default: + break; + } + NURONerr(NURON_F_NURON_CTRL, NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +static int nuron_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + if (!pvDSOHandle) { + NURONerr(NURON_F_NURON_MOD_EXP, NURON_R_NOT_LOADED); + return 0; + } + return pfnModExp(r, a, p, m); +} + +# ifndef OPENSSL_NO_RSA +static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + return nuron_mod_exp(r0, I, rsa->d, rsa->n, ctx); +} +# endif + +# ifndef OPENSSL_NO_DSA +/* + * This code was liberated and adapted from the commented-out code in + * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration (it + * doesn't have a CRT form for RSA), this function means that an Atalla + * system running with a DSA server certificate can handshake around 5 or 6 + * times faster/more than an equivalent system running with RSA. Just check + * out the "signs" statistics from the RSA and DSA parts of "openssl speed + * -engine atalla dsa1024 rsa1024". + */ +static int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + BIGNUM t; + int to_return = 0; + + BN_init(&t); + /* let rr = a1 ^ p1 mod m */ + if (!nuron_mod_exp(rr, a1, p1, m, ctx)) + goto end; + /* let t = a2 ^ p2 mod m */ + if (!nuron_mod_exp(&t, a2, p2, m, ctx)) + goto end; + /* let rr = rr * t mod m */ + if (!BN_mod_mul(rr, rr, &t, m, ctx)) + goto end; + to_return = 1; + end: + BN_free(&t); + return to_return; +} + +static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return nuron_mod_exp(r, a, p, m, ctx); +} +# endif + +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +# ifndef OPENSSL_NO_RSA +static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return nuron_mod_exp(r, a, p, m, ctx); +} +# endif + +# ifndef OPENSSL_NO_DH +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return nuron_mod_exp(r, a, p, m, ctx); +} +# endif + +# ifndef OPENSSL_NO_RSA +static RSA_METHOD nuron_rsa = { + "Nuron RSA method", + NULL, + NULL, + NULL, + NULL, + nuron_rsa_mod_exp, + nuron_mod_exp_mont, + NULL, + NULL, + 0, + NULL, + NULL, + NULL, + NULL +}; +# endif + +# ifndef OPENSSL_NO_DSA +static DSA_METHOD nuron_dsa = { + "Nuron DSA method", + NULL, /* dsa_do_sign */ + NULL, /* dsa_sign_setup */ + NULL, /* dsa_do_verify */ + nuron_dsa_mod_exp, /* dsa_mod_exp */ + nuron_mod_exp_dsa, /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* dsa_paramgen */ + NULL /* dsa_keygen */ +}; +# endif + +# ifndef OPENSSL_NO_DH +static DH_METHOD nuron_dh = { + "Nuron DH method", + NULL, + NULL, + nuron_mod_exp_dh, + NULL, + NULL, + 0, + NULL, + NULL +}; +# endif + +/* Constants used when creating the ENGINE */ +static const char *engine_nuron_id = "nuron"; +static const char *engine_nuron_name = "Nuron hardware engine support"; + +/* + * This internal function is used by ENGINE_nuron() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif +# ifndef OPENSSL_NO_DSA + const DSA_METHOD *meth2; +# endif +# ifndef OPENSSL_NO_DH + const DH_METHOD *meth3; +# endif + if (!ENGINE_set_id(e, engine_nuron_id) || + !ENGINE_set_name(e, engine_nuron_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &nuron_rsa) || +# endif +# ifndef OPENSSL_NO_DSA + !ENGINE_set_DSA(e, &nuron_dsa) || +# endif +# ifndef OPENSSL_NO_DH + !ENGINE_set_DH(e, &nuron_dh) || +# endif + !ENGINE_set_destroy_function(e, nuron_destroy) || + !ENGINE_set_init_function(e, nuron_init) || + !ENGINE_set_finish_function(e, nuron_finish) || + !ENGINE_set_ctrl_function(e, nuron_ctrl) || + !ENGINE_set_cmd_defns(e, nuron_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + /* + * We know that the "PKCS1_SSLeay()" functions hook properly to the + * nuron-specific mod_exp and mod_exp_crt so we use those functions. NB: + * We don't use ENGINE_openssl() or anything "more generic" because + * something like the RSAref code may not hook properly, and if you own + * one of these cards then you have the right to do RSA operations on it + * anyway! + */ + meth1 = RSA_PKCS1_SSLeay(); + nuron_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + nuron_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + nuron_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + nuron_rsa.rsa_priv_dec = meth1->rsa_priv_dec; +# endif + +# ifndef OPENSSL_NO_DSA + /* + * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits. + */ + meth2 = DSA_OpenSSL(); + nuron_dsa.dsa_do_sign = meth2->dsa_do_sign; + nuron_dsa.dsa_sign_setup = meth2->dsa_sign_setup; + nuron_dsa.dsa_do_verify = meth2->dsa_do_verify; +# endif + +# ifndef OPENSSL_NO_DH + /* Much the same for Diffie-Hellman */ + meth3 = DH_OpenSSL(); + nuron_dh.generate_key = meth3->generate_key; + nuron_dh.compute_key = meth3->compute_key; +# endif + + /* Ensure the nuron error handling is set up */ + ERR_load_NURON_strings(); + return 1; +} + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_nuron(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_nuron(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_nuron(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_nuron_id) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ +# endif /* !OPENSSL_NO_HW_NURON */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_nuron_err.c b/Sources/COpenSSL/e_nuron_err.c new file mode 100644 index 00000000..649525cc --- /dev/null +++ b/Sources/COpenSSL/e_nuron_err.c @@ -0,0 +1,142 @@ +/* e_nuron_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_nuron_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA NURON_str_functs[] = { + {ERR_FUNC(NURON_F_NURON_CTRL), "NURON_CTRL"}, + {ERR_FUNC(NURON_F_NURON_FINISH), "NURON_FINISH"}, + {ERR_FUNC(NURON_F_NURON_INIT), "NURON_INIT"}, + {ERR_FUNC(NURON_F_NURON_MOD_EXP), "NURON_MOD_EXP"}, + {0, NULL} +}; + +static ERR_STRING_DATA NURON_str_reasons[] = { + {ERR_REASON(NURON_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(NURON_R_DSO_FAILURE), "dso failure"}, + {ERR_REASON(NURON_R_DSO_FUNCTION_NOT_FOUND), "dso function not found"}, + {ERR_REASON(NURON_R_DSO_NOT_FOUND), "dso not found"}, + {ERR_REASON(NURON_R_NOT_LOADED), "not loaded"}, + {0, NULL} +}; + +#endif + +#ifdef NURON_LIB_NAME +static ERR_STRING_DATA NURON_lib_name[] = { + {0, NURON_LIB_NAME}, + {0, NULL} +}; +#endif + +static int NURON_lib_error_code = 0; +static int NURON_error_init = 1; + +static void ERR_load_NURON_strings(void) +{ + if (NURON_lib_error_code == 0) + NURON_lib_error_code = ERR_get_next_error_library(); + + if (NURON_error_init) { + NURON_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(NURON_lib_error_code, NURON_str_functs); + ERR_load_strings(NURON_lib_error_code, NURON_str_reasons); +#endif + +#ifdef NURON_LIB_NAME + NURON_lib_name->error = ERR_PACK(NURON_lib_error_code, 0, 0); + ERR_load_strings(0, NURON_lib_name); +#endif + } +} + +static void ERR_unload_NURON_strings(void) +{ + if (NURON_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(NURON_lib_error_code, NURON_str_functs); + ERR_unload_strings(NURON_lib_error_code, NURON_str_reasons); +#endif + +#ifdef NURON_LIB_NAME + ERR_unload_strings(0, NURON_lib_name); +#endif + NURON_error_init = 1; + } +} + +static void ERR_NURON_error(int function, int reason, char *file, int line) +{ + if (NURON_lib_error_code == 0) + NURON_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(NURON_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_nuron_err.h b/Sources/COpenSSL/e_nuron_err.h new file mode 100644 index 00000000..aa7849c6 --- /dev/null +++ b/Sources/COpenSSL/e_nuron_err.h @@ -0,0 +1,91 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_NURON_ERR_H +# define HEADER_NURON_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_NURON_strings(void); +static void ERR_unload_NURON_strings(void); +static void ERR_NURON_error(int function, int reason, char *file, int line); +# define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the NURON functions. */ + +/* Function codes. */ +# define NURON_F_NURON_CTRL 100 +# define NURON_F_NURON_FINISH 101 +# define NURON_F_NURON_INIT 102 +# define NURON_F_NURON_MOD_EXP 103 + +/* Reason codes. */ +# define NURON_R_ALREADY_LOADED 100 +# define NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED 101 +# define NURON_R_DSO_FAILURE 102 +# define NURON_R_DSO_FUNCTION_NOT_FOUND 103 +# define NURON_R_DSO_NOT_FOUND 104 +# define NURON_R_NOT_LOADED 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_old.c b/Sources/COpenSSL/e_old.c new file mode 100644 index 00000000..93e5a4c3 --- /dev/null +++ b/Sources/COpenSSL/e_old.c @@ -0,0 +1,164 @@ +/* crypto/evp/e_old.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef OPENSSL_NO_DEPRECATED +static void *dummy = &dummy; +#else + +# include "evp.h" + +/* + * Define some deprecated functions, so older programs don't crash and burn + * too quickly. On Windows and VMS, these will never be used, since + * functions and variables in shared libraries are selected by entry point + * location, not by name. + */ + +# ifndef OPENSSL_NO_BF +# undef EVP_bf_cfb +const EVP_CIPHER *EVP_bf_cfb(void); +const EVP_CIPHER *EVP_bf_cfb(void) +{ + return EVP_bf_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_DES +# undef EVP_des_cfb +const EVP_CIPHER *EVP_des_cfb(void); +const EVP_CIPHER *EVP_des_cfb(void) +{ + return EVP_des_cfb64(); +} + +# undef EVP_des_ede3_cfb +const EVP_CIPHER *EVP_des_ede3_cfb(void); +const EVP_CIPHER *EVP_des_ede3_cfb(void) +{ + return EVP_des_ede3_cfb64(); +} + +# undef EVP_des_ede_cfb +const EVP_CIPHER *EVP_des_ede_cfb(void); +const EVP_CIPHER *EVP_des_ede_cfb(void) +{ + return EVP_des_ede_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_IDEA +# undef EVP_idea_cfb +const EVP_CIPHER *EVP_idea_cfb(void); +const EVP_CIPHER *EVP_idea_cfb(void) +{ + return EVP_idea_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_RC2 +# undef EVP_rc2_cfb +const EVP_CIPHER *EVP_rc2_cfb(void); +const EVP_CIPHER *EVP_rc2_cfb(void) +{ + return EVP_rc2_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_CAST +# undef EVP_cast5_cfb +const EVP_CIPHER *EVP_cast5_cfb(void); +const EVP_CIPHER *EVP_cast5_cfb(void) +{ + return EVP_cast5_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_RC5 +# undef EVP_rc5_32_12_16_cfb +const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) +{ + return EVP_rc5_32_12_16_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_AES +# undef EVP_aes_128_cfb +const EVP_CIPHER *EVP_aes_128_cfb(void); +const EVP_CIPHER *EVP_aes_128_cfb(void) +{ + return EVP_aes_128_cfb128(); +} + +# undef EVP_aes_192_cfb +const EVP_CIPHER *EVP_aes_192_cfb(void); +const EVP_CIPHER *EVP_aes_192_cfb(void) +{ + return EVP_aes_192_cfb128(); +} + +# undef EVP_aes_256_cfb +const EVP_CIPHER *EVP_aes_256_cfb(void); +const EVP_CIPHER *EVP_aes_256_cfb(void) +{ + return EVP_aes_256_cfb128(); +} +# endif + +#endif diff --git a/Sources/COpenSSL/e_os.h b/Sources/COpenSSL/e_os.h new file mode 100644 index 00000000..ffc7772f --- /dev/null +++ b/Sources/COpenSSL/e_os.h @@ -0,0 +1,782 @@ +/* e_os.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_E_OS_H +# define HEADER_E_OS_H + +# include "opensslconf.h" + +# include "e_os2.h" +/* + * contains what we can justify to make visible to the + * outside; this file e_os.h is not part of the exported interface. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to checking reference counts, most while doing perl5 stuff :-) */ +# ifdef REF_PRINT +# undef REF_PRINT +# define REF_PRINT(a,b) fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a) +# endif + +# ifndef DEVRANDOM +/* + * set this to a comma-separated list of 'random' device files to try out. My + * default, we will try to read at least one of these files + */ +# define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom" +# endif +# ifndef DEVRANDOM_EGD +/* + * set this to a comma-seperated list of 'egd' sockets to try out. These + * sockets will be tried in the order listed in case accessing the device + * files listed in DEVRANDOM did not return enough entropy. + */ +# define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy" +# endif + +# if defined(OPENSSL_SYS_VXWORKS) +# define NO_SYS_PARAM_H +# define NO_CHMOD +# define NO_SYSLOG +# endif + +# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) +# if macintosh==1 +# ifndef MAC_OS_GUSI_SOURCE +# define MAC_OS_pre_X +# define NO_SYS_TYPES_H +# endif +# define NO_SYS_PARAM_H +# define NO_CHMOD +# define NO_SYSLOG +# undef DEVRANDOM +# define GETPID_IS_MEANINGLESS +# endif +# endif + +/******************************************************************** + The Microsoft section + ********************************************************************/ +/* + * The following is used because of the small stack in some Microsoft + * operating systems + */ +# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32) +# define MS_STATIC static +# else +# define MS_STATIC +# endif + +# if defined(OPENSSL_SYS_WIN32) && !defined(WIN32) +# define WIN32 +# endif +# if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +# endif +# if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS) +# define MSDOS +# endif + +# if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS) +# define GETPID_IS_MEANINGLESS +# endif + +# ifdef WIN32 +# define get_last_sys_error() GetLastError() +# define clear_sys_error() SetLastError(0) +# if !defined(WINNT) +# define WIN_CONSOLE_BUG +# endif +# else +# define get_last_sys_error() errno +# define clear_sys_error() errno=0 +# endif + +# if defined(WINDOWS) +# define get_last_socket_error() WSAGetLastError() +# define clear_socket_error() WSASetLastError(0) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# elif defined(__DJGPP__) +# define WATT32 +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define closesocket(s) close_s(s) +# define readsocket(s,b,n) read_s(s,b,n) +# define writesocket(s,b,n) send(s,b,n,0) +# elif defined(MAC_OS_pre_X) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define closesocket(s) MacSocket_close(s) +# define readsocket(s,b,n) MacSocket_recv((s),(b),(n),true) +# define writesocket(s,b,n) MacSocket_send((s),(b),(n)) +# elif defined(OPENSSL_SYS_VMS) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# define closesocket(s) close(s) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# elif defined(OPENSSL_SYS_VXWORKS) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define ioctlsocket(a,b,c) ioctl((a),(b),(int)(c)) +# define closesocket(s) close(s) +# define readsocket(s,b,n) read((s),(b),(n)) +# define writesocket(s,b,n) write((s),(char *)(b),(n)) +# elif defined(OPENSSL_SYS_BEOS_R5) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define FIONBIO SO_NONBLOCK +# define ioctlsocket(a,b,c) setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c))) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# elif defined(OPENSSL_SYS_NETWARE) +# if defined(NETWARE_BSDSOCK) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define closesocket(s) close(s) +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# if defined(NETWARE_LIBC) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# else +# define readsocket(s,b,n) recv((s),(char*)(b),(n),0) +# define writesocket(s,b,n) send((s),(char*)(b),(n),0) +# endif +# else +# define get_last_socket_error() WSAGetLastError() +# define clear_socket_error() WSASetLastError(0) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# endif +# else +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# define closesocket(s) close(s) +# define readsocket(s,b,n) read((s),(b),(n)) +# define writesocket(s,b,n) write((s),(b),(n)) +# endif + +# ifdef WIN16 /* never the case */ +# define MS_CALLBACK _far _loadds +# define MS_FAR _far +# else +# define MS_CALLBACK +# define MS_FAR +# endif + +# ifdef OPENSSL_NO_STDIO +# undef OPENSSL_NO_FP_API +# define OPENSSL_NO_FP_API +# endif + +# if (defined(WINDOWS) || defined(MSDOS)) + +# ifdef __DJGPP__ +# include +# include +# include +# include +# include +# define _setmode setmode +# define _O_TEXT O_TEXT +# define _O_BINARY O_BINARY +# undef DEVRANDOM +# define DEVRANDOM "/dev/urandom\x24" +# endif /* __DJGPP__ */ + +# ifndef S_IFDIR +# define S_IFDIR _S_IFDIR +# endif + +# ifndef S_IFMT +# define S_IFMT _S_IFMT +# endif + +# if !defined(WINNT) && !defined(__DJGPP__) +# define NO_SYSLOG +# endif +# define NO_DIRENT + +# ifdef WINDOWS +# if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT) + /* + * Defining _WIN32_WINNT here in e_os.h implies certain "discipline." + * Most notably we ought to check for availability of each specific + * routine with GetProcAddress() and/or guard NT-specific calls with + * GetVersion() < 0x80000000. One can argue that in latter "or" case + * we ought to /DELAYLOAD some .DLLs in order to protect ourselves + * against run-time link errors. This doesn't seem to be necessary, + * because it turned out that already Windows 95, first non-NT Win32 + * implementation, is equipped with at least NT 3.51 stubs, dummy + * routines with same name, but which do nothing. Meaning that it's + * apparently sufficient to guard "vanilla" NT calls with GetVersion + * alone, while NT 4.0 and above interfaces ought to be linked with + * GetProcAddress at run-time. + */ +# define _WIN32_WINNT 0x0400 +# endif +# if !defined(OPENSSL_NO_SOCK) && (defined(_WIN32_WINNT) || defined(_WIN32_WCE)) + /* + * Just like defining _WIN32_WINNT including winsock2.h implies + * certain "discipline" for maintaining [broad] binary compatibility. + * As long as structures are invariant among Winsock versions, + * it's sufficient to check for specific Winsock2 API availability + * at run-time [DSO_global_lookup is recommended]... + */ +# include +# include + /* yes, they have to be #included prior to */ +# endif +# include +# include +# include +# include +# if defined(_WIN32_WCE) && !defined(EACCES) +# define EACCES 13 +# endif +# include +# ifdef _WIN64 +# define strlen(s) _strlen31(s) +/* cut strings to 2GB */ +static __inline unsigned int _strlen31(const char *str) +{ + unsigned int len = 0; + while (*str && len < 0x80000000U) + str++, len++; + return len & 0x7FFFFFFF; +} +# endif +# include +# if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace) + /* compensate for bug in VC6 ctype.h */ +# undef isspace +# undef isdigit +# undef isalnum +# undef isupper +# undef isxdigit +# endif +# if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(_DLL) && defined(stdin) +# if _MSC_VER>=1300 && _MSC_VER<1600 +# undef stdin +# undef stdout +# undef stderr +FILE *__iob_func(); +# define stdin (&__iob_func()[0]) +# define stdout (&__iob_func()[1]) +# define stderr (&__iob_func()[2]) +# elif _MSC_VER<1300 && defined(I_CAN_LIVE_WITH_LNK4049) +# undef stdin +# undef stdout +# undef stderr + /* + * pre-1300 has __p__iob(), but it's available only in msvcrt.lib, + * or in other words with /MD. Declaring implicit import, i.e. with + * _imp_ prefix, works correctly with all compiler options, but + * without /MD results in LINK warning LNK4049: 'locally defined + * symbol "__iob" imported'. + */ +extern FILE *_imp___iob; +# define stdin (&_imp___iob[0]) +# define stdout (&_imp___iob[1]) +# define stderr (&_imp___iob[2]) +# endif +# endif +# endif +# include +# include + +# ifdef OPENSSL_SYS_WINCE +# define OPENSSL_NO_POSIX_IO +# endif + +# if defined (__BORLANDC__) +# define _setmode setmode +# define _O_TEXT O_TEXT +# define _O_BINARY O_BINARY +# define _int64 __int64 +# define _kbhit kbhit +# endif + +# define EXIT(n) exit(n) +# define LIST_SEPARATOR_CHAR ';' +# ifndef X_OK +# define X_OK 0 +# endif +# ifndef W_OK +# define W_OK 2 +# endif +# ifndef R_OK +# define R_OK 4 +# endif +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define NUL_DEV "nul" +# define RFILE ".rnd" +# ifdef OPENSSL_SYS_WINCE +# define DEFAULT_HOME "" +# else +# define DEFAULT_HOME "C:" +# endif + +/* Avoid Visual Studio 13 GetVersion deprecated problems */ +# if defined(_MSC_VER) && _MSC_VER>=1800 +# define check_winnt() (1) +# define check_win_minplat(x) (1) +# else +# define check_winnt() (GetVersion() < 0x80000000) +# define check_win_minplat(x) (LOBYTE(LOWORD(GetVersion())) >= (x)) +# endif + +# else /* The non-microsoft world */ + +# ifdef OPENSSL_SYS_VMS +# define VMS 1 + /* + * some programs don't include stdlib, so exit() and others give implicit + * function warnings + */ +# include +# if defined(__DECC) +# include +# else +# include +# endif +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define RFILE ".rnd" +# define LIST_SEPARATOR_CHAR ',' +# define NUL_DEV "NLA0:" + /* We don't have any well-defined random devices on VMS, yet... */ +# undef DEVRANDOM + /*- + We need to do this since VMS has the following coding on status codes: + + Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ... + The important thing to know is that odd numbers are considered + good, while even ones are considered errors. + Bits 3-15: actual status number + Bits 16-27: facility number. 0 is considered "unknown" + Bits 28-31: control bits. If bit 28 is set, the shell won't try to + output the message (which, for random codes, just looks ugly) + + So, what we do here is to change 0 to 1 to get the default success status, + and everything else is shifted up to fit into the status number field, and + the status is tagged as an error, which I believe is what is wanted here. + -- Richard Levitte + */ +# define EXIT(n) do { int __VMS_EXIT = n; \ + if (__VMS_EXIT == 0) \ + __VMS_EXIT = 1; \ + else \ + __VMS_EXIT = (n << 3) | 2; \ + __VMS_EXIT |= 0x10000000; \ + exit(__VMS_EXIT); } while(0) +# define NO_SYS_PARAM_H + +# elif defined(OPENSSL_SYS_NETWARE) +# include +# include +# define NO_SYS_TYPES_H +# undef DEVRANDOM +# ifdef NETWARE_CLIB +# define getpid GetThreadID +extern int GetThreadID(void); +/* # include */ +extern int kbhit(void); +# else +# include +# endif +# define NO_SYSLOG +# define _setmode setmode +# define _kbhit kbhit +# define _O_TEXT O_TEXT +# define _O_BINARY O_BINARY +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define RFILE ".rnd" +# define LIST_SEPARATOR_CHAR ';' +# define EXIT(n) { if (n) printf("ERROR: %d\n", (int)n); exit(n); } + +# else + /* !defined VMS */ +# ifdef OPENSSL_SYS_MPE +# define NO_SYS_PARAM_H +# endif +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +# ifndef NO_SYS_TYPES_H +# include +# endif +# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) +# define pid_t int /* pid_t is missing on NEXTSTEP/OPENSTEP + * (unless when compiling with + * -D_POSIX_SOURCE, which doesn't work for + * us) */ +# endif +# ifdef OPENSSL_SYS_NEWS4 /* setvbuf is missing on mips-sony-bsd */ +# define setvbuf(a, b, c, d) setbuffer((a), (b), (d)) +typedef unsigned long clock_t; +# endif +# ifdef OPENSSL_SYS_WIN32_CYGWIN +# include +# include +# endif + +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define RFILE ".rnd" +# define LIST_SEPARATOR_CHAR ':' +# define NUL_DEV "/dev/null" +# define EXIT(n) exit(n) +# endif + +# define SSLeay_getpid() getpid() + +# endif + +/*************/ + +# if defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_DGRAM) +# define OPENSSL_NO_DGRAM +# endif + +# ifdef USE_SOCKETS +# if defined(WINDOWS) || defined(MSDOS) + /* windows world */ + +# ifdef OPENSSL_NO_SOCK +# define SSLeay_Write(a,b,c) (-1) +# define SSLeay_Read(a,b,c) (-1) +# define SHUTDOWN(fd) close(fd) +# define SHUTDOWN2(fd) close(fd) +# elif !defined(__DJGPP__) +# if defined(_WIN32_WCE) && _WIN32_WCE<410 +# define getservbyname _masked_declaration_getservbyname +# endif +# if !defined(IPPROTO_IP) + /* winsock[2].h was included already? */ +# include +# endif +# ifdef getservbyname +# undef getservbyname + /* this is used to be wcecompat/include/winsock_extras.h */ +struct servent *PASCAL getservbyname(const char *, const char *); +# endif + +# ifdef _WIN64 +/* + * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because + * the value constitutes an index in per-process table of limited size + * and not a real pointer. + */ +# define socket(d,t,p) ((int)socket(d,t,p)) +# define accept(s,f,l) ((int)accept(s,f,l)) +# endif +# define SSLeay_Write(a,b,c) send((a),(b),(c),0) +# define SSLeay_Read(a,b,c) recv((a),(b),(c),0) +# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); } +# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); } +# else +# define SSLeay_Write(a,b,c) write_s(a,b,c,0) +# define SSLeay_Read(a,b,c) read_s(a,b,c) +# define SHUTDOWN(fd) close_s(fd) +# define SHUTDOWN2(fd) close_s(fd) +# endif + +# elif defined(MAC_OS_pre_X) + +# include "MacSocket.h" +# define SSLeay_Write(a,b,c) MacSocket_send((a),(b),(c)) +# define SSLeay_Read(a,b,c) MacSocket_recv((a),(b),(c),true) +# define SHUTDOWN(fd) MacSocket_close(fd) +# define SHUTDOWN2(fd) MacSocket_close(fd) + +# elif defined(OPENSSL_SYS_NETWARE) + /* + * NetWare uses the WinSock2 interfaces by default, but can be + * configured for BSD + */ +# if defined(NETWARE_BSDSOCK) +# include +# include +# include +# if defined(NETWARE_CLIB) +# include +# else +# include +# endif +# define INVALID_SOCKET (int)(~0) +# else +# include +# endif +# define SSLeay_Write(a,b,c) send((a),(b),(c),0) +# define SSLeay_Read(a,b,c) recv((a),(b),(c),0) +# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); } +# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); } + +# else + +# ifndef NO_SYS_PARAM_H +# include +# endif +# ifdef OPENSSL_SYS_VXWORKS +# include +# elif !defined(OPENSSL_SYS_MPE) +# include /* Needed under linux for FD_XXX */ +# endif + +# include +# if defined(OPENSSL_SYS_VMS_NODECC) +# include +# include +# include +# else +# include +# ifdef FILIO_H +# include /* Added for FIONBIO under unixware */ +# endif +# include +# if !defined(OPENSSL_SYS_BEOS_R5) +# include +# endif +# endif + +# if defined(NeXT) || defined(_NEXT_SOURCE) +# include +# include +# endif + +# ifdef OPENSSL_SYS_AIX +# include +# endif + +# ifdef __QNX__ +# include +# endif + +# if defined(__sun) || defined(sun) +# include +# else +# ifndef VMS +# include +# else + /* ioctl is only in VMS > 7.0 and when socketshr is not used */ +# if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000) +# include +# endif +# endif +# endif + +# ifdef VMS +# include +# if defined(TCPIP_TYPE_SOCKETSHR) +# include +# endif +# endif + +# define SSLeay_Read(a,b,c) read((a),(b),(c)) +# define SSLeay_Write(a,b,c) write((a),(b),(c)) +# define SHUTDOWN(fd) { shutdown((fd),0); closesocket((fd)); } +# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket((fd)); } +# ifndef INVALID_SOCKET +# define INVALID_SOCKET (-1) +# endif /* INVALID_SOCKET */ +# endif + +/* + * Some IPv6 implementations are broken, disable them in known bad versions. + */ +# if !defined(OPENSSL_USE_IPV6) +# if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB) +# define OPENSSL_USE_IPV6 1 +# else +# define OPENSSL_USE_IPV6 0 +# endif +# endif + +# endif + +# if (defined(__sun) || defined(sun)) && !defined(__svr4__) && !defined(__SVR4) + /* include headers first, so our defines don't break it */ +# include +# include + /* bcopy can handle overlapping moves according to SunOS 4.1.4 manpage */ +# define memmove(s1,s2,n) bcopy((s2),(s1),(n)) +# define strtoul(s,e,b) ((unsigned long int)strtol((s),(e),(b))) +extern char *sys_errlist[]; +extern int sys_nerr; +# define strerror(errnum) \ + (((errnum)<0 || (errnum)>=sys_nerr) ? NULL : sys_errlist[errnum]) + /* Being signed SunOS 4.x memcpy breaks ASN1_OBJECT table lookup */ +# include "crypto/o_str.h" +# define memcmp OPENSSL_memcmp +# endif + +# ifndef OPENSSL_EXIT +# if defined(MONOLITH) && !defined(OPENSSL_C) +# define OPENSSL_EXIT(n) return(n) +# else +# define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0) +# endif +# endif + +/***********************************************/ + +# define DG_GCC_BUG /* gcc < 2.6.3 on DGUX */ + +# ifdef sgi +# define IRIX_CC_BUG /* all version of IRIX I've tested (4.* 5.*) */ +# endif +# ifdef OPENSSL_SYS_SNI +# define IRIX_CC_BUG /* CDS++ up to V2.0Bsomething suffered from + * the same bug. */ +# endif + +# if defined(OPENSSL_SYS_WINDOWS) +# define strcasecmp _stricmp +# define strncasecmp _strnicmp +# elif defined(OPENSSL_SYS_VMS) +/* VMS below version 7.0 doesn't have strcasecmp() */ +# include "o_str.h" +# define strcasecmp OPENSSL_strcasecmp +# define strncasecmp OPENSSL_strncasecmp +# define OPENSSL_IMPLEMENTS_strncasecmp +# elif defined(OPENSSL_SYS_OS2) && defined(__EMX__) +# define strcasecmp stricmp +# define strncasecmp strnicmp +# elif defined(OPENSSL_SYS_NETWARE) +# include +# if defined(NETWARE_CLIB) +# define strcasecmp stricmp +# define strncasecmp strnicmp +# endif /* NETWARE_CLIB */ +# endif + +# if defined(OPENSSL_SYS_OS2) && defined(__EMX__) +# include +# include +# define NO_SYSLOG +# endif + +/* vxworks */ +# if defined(OPENSSL_SYS_VXWORKS) +# include +# include +# include + +# define TTY_STRUCT int + +# define sleep(a) taskDelay((a) * sysClkRateGet()) + +# include +# include +# include + +# define getpid taskIdSelf + +/* + * NOTE: these are implemented by helpers in database app! if the database is + * not linked, we need to implement them elswhere + */ +struct hostent *gethostbyname(const char *name); +struct hostent *gethostbyaddr(const char *addr, int length, int type); +struct servent *getservbyname(const char *name, const char *proto); + +# endif +/* end vxworks */ + +/* beos */ +# if defined(OPENSSL_SYS_BEOS_R5) +# define SO_ERROR 0 +# define NO_SYS_UN +# define IPPROTO_IP 0 +# include +# endif + +# if !defined(inline) && !defined(__cplusplus) +# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L + /* do nothing, inline works */ +# elif defined(__GNUC__) && __GNUC__>=2 +# define inline __inline__ +# elif defined(_MSC_VER) + /* + * Visual Studio: inline is available in C++ only, however + * __inline is available for C, see + * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx + */ +# define inline __inline +# else +# define inline +# endif +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/e_os2.h b/Sources/COpenSSL/e_os2.h new file mode 100644 index 00000000..c5b50c92 --- /dev/null +++ b/Sources/COpenSSL/e_os2.h @@ -0,0 +1,328 @@ +/* e_os2.h */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "opensslconf.h" + +#ifndef HEADER_E_OS2_H +# define HEADER_E_OS2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * Detect operating systems. This probably needs completing. + * The result is that at least one OPENSSL_SYS_os macro should be defined. + * However, if none is defined, Unix is assumed. + **/ + +# define OPENSSL_SYS_UNIX + +/* ---------------------- Macintosh, before MacOS X ----------------------- */ +# if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_MACINTOSH_CLASSIC +# endif + +/* ---------------------- NetWare ----------------------------------------- */ +# if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_NETWARE +# endif + +/* --------------------- Microsoft operating systems ---------------------- */ + +/* + * Note that MSDOS actually denotes 32-bit environments running on top of + * MS-DOS, such as DJGPP one. + */ +# if defined(OPENSSL_SYSNAME_MSDOS) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_MSDOS +# endif + +/* + * For 32 bit environment, there seems to be the CygWin environment and then + * all the others that try to do the same thing Microsoft does... + */ +# if defined(OPENSSL_SYSNAME_UWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_UWIN +# else +# if defined(__CYGWIN__) || defined(OPENSSL_SYSNAME_CYGWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_CYGWIN +# else +# if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32 +# endif +# if defined(_WIN64) || defined(OPENSSL_SYSNAME_WIN64) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN64) +# define OPENSSL_SYS_WIN64 +# endif +# endif +# if defined(OPENSSL_SYSNAME_WINNT) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINNT +# endif +# if defined(OPENSSL_SYSNAME_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINCE +# endif +# endif +# endif + +/* Anything that tries to look like Microsoft is "Windows" */ +# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +# endif + +/* + * DLL settings. This part is a bit tough, because it's up to the + * application implementor how he or she will link the application, so it + * requires some macro to be used. + */ +# ifdef OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_OPT_WINDLL +# if defined(_WINDLL) /* This is used when building OpenSSL to + * indicate that DLL linkage should be used */ +# define OPENSSL_OPT_WINDLL +# endif +# endif +# endif + +/* ------------------------------- OpenVMS -------------------------------- */ +# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_VMS +# if defined(__DECC) +# define OPENSSL_SYS_VMS_DECC +# elif defined(__DECCXX) +# define OPENSSL_SYS_VMS_DECC +# define OPENSSL_SYS_VMS_DECCXX +# else +# define OPENSSL_SYS_VMS_NODECC +# endif +# endif + +/* -------------------------------- OS/2 ---------------------------------- */ +# if defined(__EMX__) || defined(__OS2__) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_OS2 +# endif + +/* -------------------------------- Unix ---------------------------------- */ +# ifdef OPENSSL_SYS_UNIX +# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX) +# define OPENSSL_SYS_LINUX +# endif +# ifdef OPENSSL_SYSNAME_MPE +# define OPENSSL_SYS_MPE +# endif +# ifdef OPENSSL_SYSNAME_SNI +# define OPENSSL_SYS_SNI +# endif +# ifdef OPENSSL_SYSNAME_ULTRASPARC +# define OPENSSL_SYS_ULTRASPARC +# endif +# ifdef OPENSSL_SYSNAME_NEWS4 +# define OPENSSL_SYS_NEWS4 +# endif +# ifdef OPENSSL_SYSNAME_MACOSX +# define OPENSSL_SYS_MACOSX +# endif +# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY +# define OPENSSL_SYS_MACOSX_RHAPSODY +# define OPENSSL_SYS_MACOSX +# endif +# ifdef OPENSSL_SYSNAME_SUNOS +# define OPENSSL_SYS_SUNOS +# endif +# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY) +# define OPENSSL_SYS_CRAY +# endif +# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX) +# define OPENSSL_SYS_AIX +# endif +# endif + +/* -------------------------------- VOS ----------------------------------- */ +# if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS) +# define OPENSSL_SYS_VOS +# ifdef __HPPA__ +# define OPENSSL_SYS_VOS_HPPA +# endif +# ifdef __IA32__ +# define OPENSSL_SYS_VOS_IA32 +# endif +# endif + +/* ------------------------------ VxWorks --------------------------------- */ +# ifdef OPENSSL_SYSNAME_VXWORKS +# define OPENSSL_SYS_VXWORKS +# endif + +/* -------------------------------- BeOS ---------------------------------- */ +# if defined(__BEOS__) +# define OPENSSL_SYS_BEOS +# include +# if defined(BONE_VERSION) +# define OPENSSL_SYS_BEOS_BONE +# else +# define OPENSSL_SYS_BEOS_R5 +# endif +# endif + +/** + * That's it for OS-specific stuff + *****************************************************************************/ + +/* Specials for I/O an exit */ +# ifdef OPENSSL_SYS_MSDOS +# define OPENSSL_UNISTD_IO +# define OPENSSL_DECLARE_EXIT extern void exit(int); +# else +# define OPENSSL_UNISTD_IO OPENSSL_UNISTD +# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */ +# endif + +/*- + * Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare + * certain global symbols that, with some compilers under VMS, have to be + * defined and declared explicitely with globaldef and globalref. + * Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare + * DLL exports and imports for compilers under Win32. These are a little + * more complicated to use. Basically, for any library that exports some + * global variables, the following code must be present in the header file + * that declares them, before OPENSSL_EXTERN is used: + * + * #ifdef SOME_BUILD_FLAG_MACRO + * # undef OPENSSL_EXTERN + * # define OPENSSL_EXTERN OPENSSL_EXPORT + * #endif + * + * The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL + * have some generally sensible values, and for OPENSSL_EXTERN to have the + * value OPENSSL_IMPORT. + */ + +# if defined(OPENSSL_SYS_VMS_NODECC) +# define OPENSSL_EXPORT globalref +# define OPENSSL_IMPORT globalref +# define OPENSSL_GLOBAL globaldef +# elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL) +# define OPENSSL_EXPORT extern __declspec(dllexport) +# define OPENSSL_IMPORT extern __declspec(dllimport) +# define OPENSSL_GLOBAL +# else +# define OPENSSL_EXPORT extern +# define OPENSSL_IMPORT extern +# define OPENSSL_GLOBAL +# endif +# define OPENSSL_EXTERN OPENSSL_IMPORT + +/*- + * Macros to allow global variables to be reached through function calls when + * required (if a shared library version requires it, for example. + * The way it's done allows definitions like this: + * + * // in foobar.c + * OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) + * // in foobar.h + * OPENSSL_DECLARE_GLOBAL(int,foobar); + * #define foobar OPENSSL_GLOBAL_REF(foobar) + */ +# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ + type *_shadow_##name(void) \ + { static type _hide_##name=value; return &_hide_##name; } +# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) +# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) +# else +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value; +# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name +# define OPENSSL_GLOBAL_REF(name) _shadow_##name +# endif + +# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE) +# define ossl_ssize_t long +# endif + +# ifdef OPENSSL_SYS_MSDOS +# define ossl_ssize_t long +# endif + +# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS) +# define ssize_t int +# endif + +# if defined(__ultrix) && !defined(ssize_t) +# define ossl_ssize_t int +# endif + +# ifndef ossl_ssize_t +# define ossl_ssize_t ssize_t +# endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_padlock.c b/Sources/COpenSSL/e_padlock.c new file mode 100644 index 00000000..fbc3f1c4 --- /dev/null +++ b/Sources/COpenSSL/e_padlock.c @@ -0,0 +1,1266 @@ +/*- + * Support for VIA PadLock Advanced Cryptography Engine (ACE) + * Written by Michal Ludvig + * http://www.logix.cz/michal + * + * Big thanks to Andy Polyakov for a help with optimization, + * assembler fixes, port to MS Windows and a lot of other + * valuable work on this engine! + */ + +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "opensslconf.h" +#include "crypto.h" +#include "dso.h" +#include "engine.h" +#include "evp.h" +#ifndef OPENSSL_NO_AES +# include "aes.h" +#endif +#include "rand.h" +#include "err.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_PADLOCK + +/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */ +# if (OPENSSL_VERSION_NUMBER >= 0x00908000L) +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define DYNAMIC_ENGINE +# endif +# elif (OPENSSL_VERSION_NUMBER >= 0x00907000L) +# ifdef ENGINE_DYNAMIC_SUPPORT +# define DYNAMIC_ENGINE +# endif +# else +# error "Only OpenSSL >= 0.9.7 is supported" +# endif + +/* + * VIA PadLock AES is available *ONLY* on some x86 CPUs. Not only that it + * doesn't exist elsewhere, but it even can't be compiled on other platforms! + * + * In addition, because of the heavy use of inline assembler, compiler choice + * is limited to GCC and Microsoft C. + */ +# undef COMPILE_HW_PADLOCK +# if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM) +# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \ + (defined(_MSC_VER) && defined(_M_IX86)) +# define COMPILE_HW_PADLOCK +# endif +# endif + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE +# ifdef COMPILE_HW_PADLOCK +static ENGINE *ENGINE_padlock(void); +# endif + +void ENGINE_load_padlock(void) +{ +/* On non-x86 CPUs it just returns. */ +# ifdef COMPILE_HW_PADLOCK + ENGINE *toadd = ENGINE_padlock(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +# endif +} + +# endif + +# ifdef COMPILE_HW_PADLOCK +/* + * We do these includes here to avoid header problems on platforms that do + * not have the VIA padlock anyway... + */ +# include +# ifdef _WIN32 +# include +# ifndef alloca +# define alloca _alloca +# endif +# elif defined(__GNUC__) +# ifndef alloca +# define alloca(s) __builtin_alloca(s) +# endif +# endif + +/* Function for ENGINE detection and control */ +static int padlock_available(void); +static int padlock_init(ENGINE *e); + +/* RNG Stuff */ +static RAND_METHOD padlock_rand; + +/* Cipher Stuff */ +# ifndef OPENSSL_NO_AES +static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); +# endif + +/* Engine names */ +static const char *padlock_id = "padlock"; +static char padlock_name[100]; + +/* Available features */ +static int padlock_use_ace = 0; /* Advanced Cryptography Engine */ +static int padlock_use_rng = 0; /* Random Number Generator */ +# ifndef OPENSSL_NO_AES +static int padlock_aes_align_required = 1; +# endif + +/* ===== Engine "management" functions ===== */ + +/* Prepare the ENGINE structure for registration */ +static int padlock_bind_helper(ENGINE *e) +{ + /* Check available features */ + padlock_available(); + +# if 1 /* disable RNG for now, see commentary in + * vicinity of RNG code */ + padlock_use_rng = 0; +# endif + + /* Generate a nice engine name with available features */ + BIO_snprintf(padlock_name, sizeof(padlock_name), + "VIA PadLock (%s, %s)", + padlock_use_rng ? "RNG" : "no-RNG", + padlock_use_ace ? "ACE" : "no-ACE"); + + /* Register everything or return with an error */ + if (!ENGINE_set_id(e, padlock_id) || + !ENGINE_set_name(e, padlock_name) || + !ENGINE_set_init_function(e, padlock_init) || +# ifndef OPENSSL_NO_AES + (padlock_use_ace && !ENGINE_set_ciphers(e, padlock_ciphers)) || +# endif + (padlock_use_rng && !ENGINE_set_RAND(e, &padlock_rand))) { + return 0; + } + + /* Everything looks good */ + return 1; +} + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE + +/* Constructor */ +static ENGINE *ENGINE_padlock(void) +{ + ENGINE *eng = ENGINE_new(); + + if (!eng) { + return NULL; + } + + if (!padlock_bind_helper(eng)) { + ENGINE_free(eng); + return NULL; + } + + return eng; +} + +# endif + +/* Check availability of the engine */ +static int padlock_init(ENGINE *e) +{ + return (padlock_use_rng || padlock_use_ace); +} + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +# ifdef DYNAMIC_ENGINE +static int padlock_bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, padlock_id) != 0)) { + return 0; + } + + if (!padlock_bind_helper(e)) { + return 0; + } + + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(padlock_bind_fn) +# endif /* DYNAMIC_ENGINE */ +/* ===== Here comes the "real" engine ===== */ +# ifndef OPENSSL_NO_AES +/* Some AES-related constants */ +# define AES_BLOCK_SIZE 16 +# define AES_KEY_SIZE_128 16 +# define AES_KEY_SIZE_192 24 +# define AES_KEY_SIZE_256 32 + /* + * Here we store the status information relevant to the current context. + */ + /* + * BIG FAT WARNING: Inline assembler in PADLOCK_XCRYPT_ASM() depends on + * the order of items in this structure. Don't blindly modify, reorder, + * etc! + */ +struct padlock_cipher_data { + unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */ + union { + unsigned int pad[4]; + struct { + int rounds:4; + int dgst:1; /* n/a in C3 */ + int align:1; /* n/a in C3 */ + int ciphr:1; /* n/a in C3 */ + unsigned int keygen:1; + int interm:1; + unsigned int encdec:1; + int ksize:2; + } b; + } cword; /* Control word */ + AES_KEY ks; /* Encryption key */ +}; + +/* + * Essentially this variable belongs in thread local storage. + * Having this variable global on the other hand can only cause + * few bogus key reloads [if any at all on single-CPU system], + * so we accept the penatly... + */ +static volatile struct padlock_cipher_data *padlock_saved_context; +# endif + +/*- + * ======================================================= + * Inline assembler section(s). + * ======================================================= + * Order of arguments is chosen to facilitate Windows port + * using __fastcall calling convention. If you wish to add + * more routines, keep in mind that first __fastcall + * argument is passed in %ecx and second - in %edx. + * ======================================================= + */ +# if defined(__GNUC__) && __GNUC__>=2 +/* + * As for excessive "push %ebx"/"pop %ebx" found all over. + * When generating position-independent code GCC won't let + * us use "b" in assembler templates nor even respect "ebx" + * in "clobber description." Therefore the trouble... + */ + +/* + * Helper function - check if a CPUID instruction is available on this CPU + */ +static int padlock_insn_cpuid_available(void) +{ + int result = -1; + + /* + * We're checking if the bit #21 of EFLAGS can be toggled. If yes = + * CPUID is available. + */ + asm volatile ("pushf\n" + "popl %%eax\n" + "xorl $0x200000, %%eax\n" + "movl %%eax, %%ecx\n" + "andl $0x200000, %%ecx\n" + "pushl %%eax\n" + "popf\n" + "pushf\n" + "popl %%eax\n" + "andl $0x200000, %%eax\n" + "xorl %%eax, %%ecx\n" + "movl %%ecx, %0\n":"=r" (result)::"eax", "ecx"); + + return (result == 0); +} + +/* + * Load supported features of the CPU to see if the PadLock is available. + */ +static int padlock_available(void) +{ + char vendor_string[16]; + unsigned int eax, edx; + + /* First check if the CPUID instruction is available at all... */ + if (!padlock_insn_cpuid_available()) + return 0; + + /* Are we running on the Centaur (VIA) CPU? */ + eax = 0x00000000; + vendor_string[12] = 0; + asm volatile ("pushl %%ebx\n" + "cpuid\n" + "movl %%ebx,(%%edi)\n" + "movl %%edx,4(%%edi)\n" + "movl %%ecx,8(%%edi)\n" + "popl %%ebx":"+a" (eax):"D"(vendor_string):"ecx", "edx"); + if (strcmp(vendor_string, "CentaurHauls") != 0) + return 0; + + /* Check for Centaur Extended Feature Flags presence */ + eax = 0xC0000000; + asm volatile ("pushl %%ebx; cpuid; popl %%ebx":"+a" (eax)::"ecx", "edx"); + if (eax < 0xC0000001) + return 0; + + /* Read the Centaur Extended Feature Flags */ + eax = 0xC0000001; + asm volatile ("pushl %%ebx; cpuid; popl %%ebx":"+a" (eax), + "=d"(edx)::"ecx"); + + /* Fill up some flags */ + padlock_use_ace = ((edx & (0x3 << 6)) == (0x3 << 6)); + padlock_use_rng = ((edx & (0x3 << 2)) == (0x3 << 2)); + + return padlock_use_ace + padlock_use_rng; +} + +# ifndef OPENSSL_NO_AES +# ifndef AES_ASM +/* Our own htonl()/ntohl() */ +static inline void padlock_bswapl(AES_KEY *ks) +{ + size_t i = sizeof(ks->rd_key) / sizeof(ks->rd_key[0]); + unsigned int *key = ks->rd_key; + + while (i--) { + asm volatile ("bswapl %0":"+r" (*key)); + key++; + } +} +# endif +# endif + +/* + * Force key reload from memory to the CPU microcode. Loading EFLAGS from the + * stack clears EFLAGS[30] which does the trick. + */ +static inline void padlock_reload_key(void) +{ + asm volatile ("pushfl; popfl"); +} + +# ifndef OPENSSL_NO_AES +/* + * This is heuristic key context tracing. At first one + * believes that one should use atomic swap instructions, + * but it's not actually necessary. Point is that if + * padlock_saved_context was changed by another thread + * after we've read it and before we compare it with cdata, + * our key *shall* be reloaded upon thread context switch + * and we are therefore set in either case... + */ +static inline void padlock_verify_context(struct padlock_cipher_data *cdata) +{ + asm volatile ("pushfl\n" + " btl $30,(%%esp)\n" + " jnc 1f\n" + " cmpl %2,%1\n" + " je 1f\n" + " popfl\n" + " subl $4,%%esp\n" + "1: addl $4,%%esp\n" + " movl %2,%0":"+m" (padlock_saved_context) + :"r"(padlock_saved_context), "r"(cdata):"cc"); +} + +/* Template for padlock_xcrypt_* modes */ +/* + * BIG FAT WARNING: The offsets used with 'leal' instructions describe items + * of the 'padlock_cipher_data' structure. + */ +# define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \ +static inline void *name(size_t cnt, \ + struct padlock_cipher_data *cdata, \ + void *out, const void *inp) \ +{ void *iv; \ + asm volatile ( "pushl %%ebx\n" \ + " leal 16(%0),%%edx\n" \ + " leal 32(%0),%%ebx\n" \ + rep_xcrypt "\n" \ + " popl %%ebx" \ + : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \ + : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \ + : "edx", "cc", "memory"); \ + return iv; \ +} + +/* Generate all functions with appropriate opcodes */ +/* rep xcryptecb */ +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") +/* rep xcryptcbc */ + PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") +/* rep xcryptcfb */ + PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") +/* rep xcryptofb */ + PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") +# endif +/* The RNG call itself */ +static inline unsigned int padlock_xstore(void *addr, unsigned int edx_in) +{ + unsigned int eax_out; + + asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */ + :"=a" (eax_out), "=m"(*(unsigned *)addr) + :"D"(addr), "d"(edx_in) + ); + + return eax_out; +} + +/* + * Why not inline 'rep movsd'? I failed to find information on what value in + * Direction Flag one can expect and consequently have to apply + * "better-safe-than-sorry" approach and assume "undefined." I could + * explicitly clear it and restore the original value upon return from + * padlock_aes_cipher, but it's presumably too much trouble for too little + * gain... In case you wonder 'rep xcrypt*' instructions above are *not* + * affected by the Direction Flag and pointers advance toward larger + * addresses unconditionally. + */ +static inline unsigned char *padlock_memcpy(void *dst, const void *src, + size_t n) +{ + long *d = dst; + const long *s = src; + + n /= sizeof(*d); + do { + *d++ = *s++; + } while (--n); + + return dst; +} + +# elif defined(_MSC_VER) +/* + * Unlike GCC these are real functions. In order to minimize impact + * on performance we adhere to __fastcall calling convention in + * order to get two first arguments passed through %ecx and %edx. + * Which kind of suits very well, as instructions in question use + * both %ecx and %edx as input:-) + */ +# define REP_XCRYPT(code) \ + _asm _emit 0xf3 \ + _asm _emit 0x0f _asm _emit 0xa7 \ + _asm _emit code + +/* + * BIG FAT WARNING: The offsets used with 'lea' instructions describe items + * of the 'padlock_cipher_data' structure. + */ +# define PADLOCK_XCRYPT_ASM(name,code) \ +static void * __fastcall \ + name (size_t cnt, void *cdata, \ + void *outp, const void *inp) \ +{ _asm mov eax,edx \ + _asm lea edx,[eax+16] \ + _asm lea ebx,[eax+32] \ + _asm mov edi,outp \ + _asm mov esi,inp \ + REP_XCRYPT(code) \ +} + +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8) +PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0) +PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0) +PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8) + +static int __fastcall padlock_xstore(void *outp, unsigned int code) +{ + _asm mov edi,ecx + _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0 +} + +static void __fastcall padlock_reload_key(void) +{ + _asm pushfd + _asm popfd +} + +static void __fastcall padlock_verify_context(void *cdata) +{ + _asm { + pushfd + bt DWORD PTR[esp],30 + jnc skip + cmp ecx,padlock_saved_context + je skip + popfd + sub esp,4 + skip: add esp,4 + mov padlock_saved_context,ecx + } +} + +static int +padlock_available(void) +{ + _asm { + pushfd + pop eax + mov ecx,eax + xor eax,1<<21 + push eax + popfd + pushfd + pop eax + xor eax,ecx + bt eax,21 + jnc noluck + mov eax,0 + cpuid + xor eax,eax + cmp ebx,'tneC' + jne noluck + cmp edx,'Hrua' + jne noluck + cmp ecx,'slua' + jne noluck + mov eax,0xC0000000 + cpuid + mov edx,eax + xor eax,eax + cmp edx,0xC0000001 + jb noluck + mov eax,0xC0000001 + cpuid + xor eax,eax + bt edx,6 + jnc skip_a + bt edx,7 + jnc skip_a + mov padlock_use_ace,1 + inc eax + skip_a: bt edx,2 + jnc skip_r + bt edx,3 + jnc skip_r + mov padlock_use_rng,1 + inc eax + skip_r: + noluck: + } +} + +static void __fastcall padlock_bswapl(void *key) +{ + _asm { + pushfd + cld + mov esi,ecx + mov edi,ecx + mov ecx,60 + up: lodsd + bswap eax + stosd + loop up + popfd + } +} + +/* + * MS actually specifies status of Direction Flag and compiler even manages + * to compile following as 'rep movsd' all by itself... + */ +# define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U)) +# endif +/* ===== AES encryption/decryption ===== */ +# ifndef OPENSSL_NO_AES +# if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb) +# define NID_aes_128_cfb NID_aes_128_cfb128 +# endif +# if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb) +# define NID_aes_128_ofb NID_aes_128_ofb128 +# endif +# if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb) +# define NID_aes_192_cfb NID_aes_192_cfb128 +# endif +# if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb) +# define NID_aes_192_ofb NID_aes_192_ofb128 +# endif +# if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb) +# define NID_aes_256_cfb NID_aes_256_cfb128 +# endif +# if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb) +# define NID_aes_256_ofb NID_aes_256_ofb128 +# endif +/* + * List of supported ciphers. + */ static int padlock_cipher_nids[] = { + NID_aes_128_ecb, + NID_aes_128_cbc, + NID_aes_128_cfb, + NID_aes_128_ofb, + + NID_aes_192_ecb, + NID_aes_192_cbc, + NID_aes_192_cfb, + NID_aes_192_ofb, + + NID_aes_256_ecb, + NID_aes_256_cbc, + NID_aes_256_cfb, + NID_aes_256_ofb, +}; + +static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids) / + sizeof(padlock_cipher_nids[0])); + +/* Function prototypes ... */ +static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t nbytes); + +# define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \ + ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) ) +# define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\ + NEAREST_ALIGNED(ctx->cipher_data)) + +# define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE +# define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE +# define EVP_CIPHER_block_size_OFB 1 +# define EVP_CIPHER_block_size_CFB 1 + +/* + * Declaring so many ciphers by hand would be a pain. Instead introduce a bit + * of preprocessor magic :-) + */ +# define DECLARE_AES_EVP(ksize,lmode,umode) \ +static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \ + NID_aes_##ksize##_##lmode, \ + EVP_CIPHER_block_size_##umode, \ + AES_KEY_SIZE_##ksize, \ + AES_BLOCK_SIZE, \ + 0 | EVP_CIPH_##umode##_MODE, \ + padlock_aes_init_key, \ + padlock_aes_cipher, \ + NULL, \ + sizeof(struct padlock_cipher_data) + 16, \ + EVP_CIPHER_set_asn1_iv, \ + EVP_CIPHER_get_asn1_iv, \ + NULL, \ + NULL \ +} + +DECLARE_AES_EVP(128, ecb, ECB); +DECLARE_AES_EVP(128, cbc, CBC); +DECLARE_AES_EVP(128, cfb, CFB); +DECLARE_AES_EVP(128, ofb, OFB); + +DECLARE_AES_EVP(192, ecb, ECB); +DECLARE_AES_EVP(192, cbc, CBC); +DECLARE_AES_EVP(192, cfb, CFB); +DECLARE_AES_EVP(192, ofb, OFB); + +DECLARE_AES_EVP(256, ecb, ECB); +DECLARE_AES_EVP(256, cbc, CBC); +DECLARE_AES_EVP(256, cfb, CFB); +DECLARE_AES_EVP(256, ofb, OFB); + +static int +padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, + int nid) +{ + /* No specific cipher => return a list of supported nids ... */ + if (!cipher) { + *nids = padlock_cipher_nids; + return padlock_cipher_nids_num; + } + + /* ... or the requested "cipher" otherwise */ + switch (nid) { + case NID_aes_128_ecb: + *cipher = &padlock_aes_128_ecb; + break; + case NID_aes_128_cbc: + *cipher = &padlock_aes_128_cbc; + break; + case NID_aes_128_cfb: + *cipher = &padlock_aes_128_cfb; + break; + case NID_aes_128_ofb: + *cipher = &padlock_aes_128_ofb; + break; + + case NID_aes_192_ecb: + *cipher = &padlock_aes_192_ecb; + break; + case NID_aes_192_cbc: + *cipher = &padlock_aes_192_cbc; + break; + case NID_aes_192_cfb: + *cipher = &padlock_aes_192_cfb; + break; + case NID_aes_192_ofb: + *cipher = &padlock_aes_192_ofb; + break; + + case NID_aes_256_ecb: + *cipher = &padlock_aes_256_ecb; + break; + case NID_aes_256_cbc: + *cipher = &padlock_aes_256_cbc; + break; + case NID_aes_256_cfb: + *cipher = &padlock_aes_256_cfb; + break; + case NID_aes_256_ofb: + *cipher = &padlock_aes_256_ofb; + break; + + default: + /* Sorry, we don't support this NID */ + *cipher = NULL; + return 0; + } + + return 1; +} + +/* Prepare the encryption key for PadLock usage */ +static int +padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + struct padlock_cipher_data *cdata; + int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8; + + if (key == NULL) + return 0; /* ERROR */ + + cdata = ALIGNED_CIPHER_DATA(ctx); + memset(cdata, 0, sizeof(struct padlock_cipher_data)); + + /* Prepare Control word. */ + if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) + cdata->cword.b.encdec = 0; + else + cdata->cword.b.encdec = (ctx->encrypt == 0); + cdata->cword.b.rounds = 10 + (key_len - 128) / 32; + cdata->cword.b.ksize = (key_len - 128) / 64; + + switch (key_len) { + case 128: + /* + * PadLock can generate an extended key for AES128 in hardware + */ + memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128); + cdata->cword.b.keygen = 0; + break; + + case 192: + case 256: + /* + * Generate an extended AES key in software. Needed for AES192/AES256 + */ + /* + * Well, the above applies to Stepping 8 CPUs and is listed as + * hardware errata. They most likely will fix it at some point and + * then a check for stepping would be due here. + */ + if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE || + EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE || enc) + AES_set_encrypt_key(key, key_len, &cdata->ks); + else + AES_set_decrypt_key(key, key_len, &cdata->ks); +# ifndef AES_ASM + /* + * OpenSSL C functions use byte-swapped extended key. + */ + padlock_bswapl(&cdata->ks); +# endif + cdata->cword.b.keygen = 1; + break; + + default: + /* ERROR */ + return 0; + } + + /* + * This is done to cover for cases when user reuses the + * context for new key. The catch is that if we don't do + * this, padlock_eas_cipher might proceed with old key... + */ + padlock_reload_key(); + + return 1; +} + +/*- + * Simplified version of padlock_aes_cipher() used when + * 1) both input and output buffers are at aligned addresses. + * or when + * 2) running on a newer CPU that doesn't require aligned buffers. + */ +static int +padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, + const unsigned char *in_arg, size_t nbytes) +{ + struct padlock_cipher_data *cdata; + void *iv; + + cdata = ALIGNED_CIPHER_DATA(ctx); + padlock_verify_context(cdata); + + switch (EVP_CIPHER_CTX_mode(ctx)) { + case EVP_CIPH_ECB_MODE: + padlock_xcrypt_ecb(nbytes / AES_BLOCK_SIZE, cdata, out_arg, in_arg); + break; + + case EVP_CIPH_CBC_MODE: + memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); + iv = padlock_xcrypt_cbc(nbytes / AES_BLOCK_SIZE, cdata, out_arg, + in_arg); + memcpy(ctx->iv, iv, AES_BLOCK_SIZE); + break; + + case EVP_CIPH_CFB_MODE: + memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); + iv = padlock_xcrypt_cfb(nbytes / AES_BLOCK_SIZE, cdata, out_arg, + in_arg); + memcpy(ctx->iv, iv, AES_BLOCK_SIZE); + break; + + case EVP_CIPH_OFB_MODE: + memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); + padlock_xcrypt_ofb(nbytes / AES_BLOCK_SIZE, cdata, out_arg, in_arg); + memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE); + break; + + default: + return 0; + } + + memset(cdata->iv, 0, AES_BLOCK_SIZE); + + return 1; +} + +# ifndef PADLOCK_CHUNK +# define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */ +# endif +# if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1) +# error "insane PADLOCK_CHUNK..." +# endif + +/* + * Re-align the arguments to 16-Bytes boundaries and run the encryption + * function itself. This function is not AES-specific. + */ +static int +padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, + const unsigned char *in_arg, size_t nbytes) +{ + struct padlock_cipher_data *cdata; + const void *inp; + unsigned char *out; + void *iv; + int inp_misaligned, out_misaligned, realign_in_loop; + size_t chunk, allocated = 0; + + /* + * ctx->num is maintained in byte-oriented modes, such as CFB and OFB... + */ + if ((chunk = ctx->num)) { /* borrow chunk variable */ + unsigned char *ivp = ctx->iv; + + switch (EVP_CIPHER_CTX_mode(ctx)) { + case EVP_CIPH_CFB_MODE: + if (chunk >= AES_BLOCK_SIZE) + return 0; /* bogus value */ + + if (ctx->encrypt) + while (chunk < AES_BLOCK_SIZE && nbytes != 0) { + ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk]; + chunk++, nbytes--; + } else + while (chunk < AES_BLOCK_SIZE && nbytes != 0) { + unsigned char c = *(in_arg++); + *(out_arg++) = c ^ ivp[chunk]; + ivp[chunk++] = c, nbytes--; + } + + ctx->num = chunk % AES_BLOCK_SIZE; + break; + case EVP_CIPH_OFB_MODE: + if (chunk >= AES_BLOCK_SIZE) + return 0; /* bogus value */ + + while (chunk < AES_BLOCK_SIZE && nbytes != 0) { + *(out_arg++) = *(in_arg++) ^ ivp[chunk]; + chunk++, nbytes--; + } + + ctx->num = chunk % AES_BLOCK_SIZE; + break; + } + } + + if (nbytes == 0) + return 1; +# if 0 + if (nbytes % AES_BLOCK_SIZE) + return 0; /* are we expected to do tail processing? */ +# else + /* + * nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC modes and + * arbitrary value in byte-oriented modes, such as CFB and OFB... + */ +# endif + + /* + * VIA promises CPUs that won't require alignment in the future. For now + * padlock_aes_align_required is initialized to 1 and the condition is + * never met... + */ + /* + * C7 core is capable to manage unaligned input in non-ECB[!] mode, but + * performance penalties appear to be approximately same as for software + * alignment below or ~3x. They promise to improve it in the future, but + * for now we can just as well pretend that it can only handle aligned + * input... + */ + if (!padlock_aes_align_required && (nbytes % AES_BLOCK_SIZE) == 0) + return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); + + inp_misaligned = (((size_t)in_arg) & 0x0F); + out_misaligned = (((size_t)out_arg) & 0x0F); + + /* + * Note that even if output is aligned and input not, I still prefer to + * loop instead of copy the whole input and then encrypt in one stroke. + * This is done in order to improve L1 cache utilization... + */ + realign_in_loop = out_misaligned | inp_misaligned; + + if (!realign_in_loop && (nbytes % AES_BLOCK_SIZE) == 0) + return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); + + /* this takes one "if" out of the loops */ + chunk = nbytes; + chunk %= PADLOCK_CHUNK; + if (chunk == 0) + chunk = PADLOCK_CHUNK; + + if (out_misaligned) { + /* optmize for small input */ + allocated = (chunk < nbytes ? PADLOCK_CHUNK : nbytes); + out = alloca(0x10 + allocated); + out = NEAREST_ALIGNED(out); + } else + out = out_arg; + + cdata = ALIGNED_CIPHER_DATA(ctx); + padlock_verify_context(cdata); + + switch (EVP_CIPHER_CTX_mode(ctx)) { + case EVP_CIPH_ECB_MODE: + do { + if (inp_misaligned) + inp = padlock_memcpy(out, in_arg, chunk); + else + inp = in_arg; + in_arg += chunk; + + padlock_xcrypt_ecb(chunk / AES_BLOCK_SIZE, cdata, out, inp); + + if (out_misaligned) + out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; + else + out = out_arg += chunk; + + nbytes -= chunk; + chunk = PADLOCK_CHUNK; + } while (nbytes); + break; + + case EVP_CIPH_CBC_MODE: + memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); + goto cbc_shortcut; + do { + if (iv != cdata->iv) + memcpy(cdata->iv, iv, AES_BLOCK_SIZE); + chunk = PADLOCK_CHUNK; + cbc_shortcut: /* optimize for small input */ + if (inp_misaligned) + inp = padlock_memcpy(out, in_arg, chunk); + else + inp = in_arg; + in_arg += chunk; + + iv = padlock_xcrypt_cbc(chunk / AES_BLOCK_SIZE, cdata, out, inp); + + if (out_misaligned) + out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; + else + out = out_arg += chunk; + + } while (nbytes -= chunk); + memcpy(ctx->iv, iv, AES_BLOCK_SIZE); + break; + + case EVP_CIPH_CFB_MODE: + memcpy(iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE); + chunk &= ~(AES_BLOCK_SIZE - 1); + if (chunk) + goto cfb_shortcut; + else + goto cfb_skiploop; + do { + if (iv != cdata->iv) + memcpy(cdata->iv, iv, AES_BLOCK_SIZE); + chunk = PADLOCK_CHUNK; + cfb_shortcut: /* optimize for small input */ + if (inp_misaligned) + inp = padlock_memcpy(out, in_arg, chunk); + else + inp = in_arg; + in_arg += chunk; + + iv = padlock_xcrypt_cfb(chunk / AES_BLOCK_SIZE, cdata, out, inp); + + if (out_misaligned) + out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; + else + out = out_arg += chunk; + + nbytes -= chunk; + } while (nbytes >= AES_BLOCK_SIZE); + + cfb_skiploop: + if (nbytes) { + unsigned char *ivp = cdata->iv; + + if (iv != ivp) { + memcpy(ivp, iv, AES_BLOCK_SIZE); + iv = ivp; + } + ctx->num = nbytes; + if (cdata->cword.b.encdec) { + cdata->cword.b.encdec = 0; + padlock_reload_key(); + padlock_xcrypt_ecb(1, cdata, ivp, ivp); + cdata->cword.b.encdec = 1; + padlock_reload_key(); + while (nbytes) { + unsigned char c = *(in_arg++); + *(out_arg++) = c ^ *ivp; + *(ivp++) = c, nbytes--; + } + } else { + padlock_reload_key(); + padlock_xcrypt_ecb(1, cdata, ivp, ivp); + padlock_reload_key(); + while (nbytes) { + *ivp = *(out_arg++) = *(in_arg++) ^ *ivp; + ivp++, nbytes--; + } + } + } + + memcpy(ctx->iv, iv, AES_BLOCK_SIZE); + break; + + case EVP_CIPH_OFB_MODE: + memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); + chunk &= ~(AES_BLOCK_SIZE - 1); + if (chunk) + do { + if (inp_misaligned) + inp = padlock_memcpy(out, in_arg, chunk); + else + inp = in_arg; + in_arg += chunk; + + padlock_xcrypt_ofb(chunk / AES_BLOCK_SIZE, cdata, out, inp); + + if (out_misaligned) + out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; + else + out = out_arg += chunk; + + nbytes -= chunk; + chunk = PADLOCK_CHUNK; + } while (nbytes >= AES_BLOCK_SIZE); + + if (nbytes) { + unsigned char *ivp = cdata->iv; + + ctx->num = nbytes; + padlock_reload_key(); /* empirically found */ + padlock_xcrypt_ecb(1, cdata, ivp, ivp); + padlock_reload_key(); /* empirically found */ + while (nbytes) { + *(out_arg++) = *(in_arg++) ^ *ivp; + ivp++, nbytes--; + } + } + + memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE); + break; + + default: + return 0; + } + + /* Clean the realign buffer if it was used */ + if (out_misaligned) { + volatile unsigned long *p = (void *)out; + size_t n = allocated / sizeof(*p); + while (n--) + *p++ = 0; + } + + memset(cdata->iv, 0, AES_BLOCK_SIZE); + + return 1; +} + +# endif /* OPENSSL_NO_AES */ + +/* ===== Random Number Generator ===== */ +/* + * This code is not engaged. The reason is that it does not comply + * with recommendations for VIA RNG usage for secure applications + * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it + * provide meaningful error control... + */ +/* + * Wrapper that provides an interface between the API and the raw PadLock + * RNG + */ +static int padlock_rand_bytes(unsigned char *output, int count) +{ + unsigned int eax, buf; + + while (count >= 8) { + eax = padlock_xstore(output, 0); + if (!(eax & (1 << 6))) + return 0; /* RNG disabled */ + /* this ---vv--- covers DC bias, Raw Bits and String Filter */ + if (eax & (0x1F << 10)) + return 0; + if ((eax & 0x1F) == 0) + continue; /* no data, retry... */ + if ((eax & 0x1F) != 8) + return 0; /* fatal failure... */ + output += 8; + count -= 8; + } + while (count > 0) { + eax = padlock_xstore(&buf, 3); + if (!(eax & (1 << 6))) + return 0; /* RNG disabled */ + /* this ---vv--- covers DC bias, Raw Bits and String Filter */ + if (eax & (0x1F << 10)) + return 0; + if ((eax & 0x1F) == 0) + continue; /* no data, retry... */ + if ((eax & 0x1F) != 1) + return 0; /* fatal failure... */ + *output++ = (unsigned char)buf; + count--; + } + *(volatile unsigned int *)&buf = 0; + + return 1; +} + +/* Dummy but necessary function */ +static int padlock_rand_status(void) +{ + return 1; +} + +/* Prepare structure for registration */ +static RAND_METHOD padlock_rand = { + NULL, /* seed */ + padlock_rand_bytes, /* bytes */ + NULL, /* cleanup */ + NULL, /* add */ + padlock_rand_bytes, /* pseudorand */ + padlock_rand_status, /* rand status */ +}; + +# else /* !COMPILE_HW_PADLOCK */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +OPENSSL_EXPORT + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); +OPENSSL_EXPORT + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) +{ + return 0; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() +# endif +# endif /* COMPILE_HW_PADLOCK */ +# endif /* !OPENSSL_NO_HW_PADLOCK */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_rc2.c b/Sources/COpenSSL/e_rc2.c new file mode 100644 index 00000000..9e033597 --- /dev/null +++ b/Sources/COpenSSL/e_rc2.c @@ -0,0 +1,235 @@ +/* crypto/evp/e_rc2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RC2 + +# include "evp.h" +# include "objects.h" +# include "evp_locl.h" +# include "rc2.h" + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); +static int rc2_magic_to_meth(int i); +static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +typedef struct { + int key_bits; /* effective key bits */ + RC2_KEY ks; /* key schedule */ +} EVP_RC2_KEY; + +# define data(ctx) ((EVP_RC2_KEY *)(ctx)->cipher_data) + +IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2, + 8, + RC2_KEY_LENGTH, 8, 64, + EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, NULL, + rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, + rc2_ctrl) +# define RC2_40_MAGIC 0xa0 +# define RC2_64_MAGIC 0x78 +# define RC2_128_MAGIC 0x3a +static const EVP_CIPHER r2_64_cbc_cipher = { + NID_rc2_64_cbc, + 8, 8 /* 64 bit */ , 8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, + rc2_cbc_cipher, + NULL, + sizeof(EVP_RC2_KEY), + rc2_set_asn1_type_and_iv, + rc2_get_asn1_type_and_iv, + rc2_ctrl, + NULL +}; + +static const EVP_CIPHER r2_40_cbc_cipher = { + NID_rc2_40_cbc, + 8, 5 /* 40 bit */ , 8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, + rc2_cbc_cipher, + NULL, + sizeof(EVP_RC2_KEY), + rc2_set_asn1_type_and_iv, + rc2_get_asn1_type_and_iv, + rc2_ctrl, + NULL +}; + +const EVP_CIPHER *EVP_rc2_64_cbc(void) +{ + return (&r2_64_cbc_cipher); +} + +const EVP_CIPHER *EVP_rc2_40_cbc(void) +{ + return (&r2_40_cbc_cipher); +} + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), + key, data(ctx)->key_bits); + return 1; +} + +static int rc2_meth_to_magic(EVP_CIPHER_CTX *e) +{ + int i; + + EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i); + if (i == 128) + return (RC2_128_MAGIC); + else if (i == 64) + return (RC2_64_MAGIC); + else if (i == 40) + return (RC2_40_MAGIC); + else + return (0); +} + +static int rc2_magic_to_meth(int i) +{ + if (i == RC2_128_MAGIC) + return 128; + else if (i == RC2_64_MAGIC) + return 64; + else if (i == RC2_40_MAGIC) + return 40; + else { + EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE); + return (0); + } +} + +static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + long num = 0; + int i = 0; + int key_bits; + unsigned int l; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (type != NULL) { + l = EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(l <= sizeof(iv)); + i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l); + if (i != (int)l) + return (-1); + key_bits = rc2_magic_to_meth((int)num); + if (!key_bits) + return (-1); + if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) + return -1; + EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); + EVP_CIPHER_CTX_set_key_length(c, key_bits / 8); + } + return (i); +} + +static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + long num; + int i = 0, j; + + if (type != NULL) { + num = rc2_meth_to_magic(c); + j = EVP_CIPHER_CTX_iv_length(c); + i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); + } + return (i); +} + +static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + switch (type) { + case EVP_CTRL_INIT: + data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8; + return 1; + + case EVP_CTRL_GET_RC2_KEY_BITS: + *(int *)ptr = data(c)->key_bits; + return 1; + + case EVP_CTRL_SET_RC2_KEY_BITS: + if (arg > 0) { + data(c)->key_bits = arg; + return 1; + } + return 0; +# ifdef PBE_PRF_TEST + case EVP_CTRL_PBE_PRF_NID: + *(int *)ptr = NID_hmacWithMD5; + return 1; +# endif + + default: + return -1; + } +} + +#endif diff --git a/Sources/COpenSSL/e_rc4.c b/Sources/COpenSSL/e_rc4.c new file mode 100644 index 00000000..dee323d2 --- /dev/null +++ b/Sources/COpenSSL/e_rc4.c @@ -0,0 +1,133 @@ +/* crypto/evp/e_rc4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RC4 + +# include "evp.h" +# include "evp_locl.h" +# include "objects.h" +# include "rc4.h" + +/* FIXME: surely this is available elsewhere? */ +# define EVP_RC4_KEY_SIZE 16 + +typedef struct { + RC4_KEY ks; /* working key */ +} EVP_RC4_KEY; + +# define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data) + +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +static const EVP_CIPHER r4_cipher = { + NID_rc4, + 1, EVP_RC4_KEY_SIZE, 0, + EVP_CIPH_VARIABLE_LENGTH, + rc4_init_key, + rc4_cipher, + NULL, + sizeof(EVP_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +static const EVP_CIPHER r4_40_cipher = { + NID_rc4_40, + 1, 5 /* 40 bit */ , 0, + EVP_CIPH_VARIABLE_LENGTH, + rc4_init_key, + rc4_cipher, + NULL, + sizeof(EVP_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +const EVP_CIPHER *EVP_rc4(void) +{ + return (&r4_cipher); +} + +const EVP_CIPHER *EVP_rc4_40(void) +{ + return (&r4_40_cipher); +} + +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + RC4(&data(ctx)->ks, inl, in, out); + return 1; +} +#endif diff --git a/Sources/COpenSSL/e_rc4_hmac_md5.c b/Sources/COpenSSL/e_rc4_hmac_md5.c new file mode 100644 index 00000000..d517c122 --- /dev/null +++ b/Sources/COpenSSL/e_rc4_hmac_md5.c @@ -0,0 +1,312 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "opensslconf.h" + +#include +#include + +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5) + +# include "crypto.h" +# include "evp.h" +# include "objects.h" +# include "rc4.h" +# include "md5.h" + +# ifndef EVP_CIPH_FLAG_AEAD_CIPHER +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +# endif + +/* FIXME: surely this is available elsewhere? */ +# define EVP_RC4_KEY_SIZE 16 + +typedef struct { + RC4_KEY ks; + MD5_CTX head, tail, md; + size_t payload_length; +} EVP_RC4_HMAC_MD5; + +# define NO_PAYLOAD_LENGTH ((size_t)-1) + +void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out, + MD5_CTX *ctx, const void *inp, size_t blocks); + +# define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data) + +static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *inkey, + const unsigned char *iv, int enc) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); + + RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey); + + MD5_Init(&key->head); /* handy when benchmarking */ + key->tail = key->head; + key->md = key->head; + + key->payload_length = NO_PAYLOAD_LENGTH; + + return 1; +} + +# if defined(RC4_ASM) && defined(MD5_ASM) && ( \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) && \ + !(defined(__APPLE__) && defined(__MACH__)) +# define STITCHED_CALL +# endif + +# if !defined(STITCHED_CALL) +# define rc4_off 0 +# define md5_off 0 +# endif + +static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); +# if defined(STITCHED_CALL) + size_t rc4_off = 32 - 1 - (key->ks.x & (32 - 1)), /* 32 is $MOD from + * rc4_md5-x86_64.pl */ + md5_off = MD5_CBLOCK - key->md.num, blocks; + unsigned int l; + extern unsigned int OPENSSL_ia32cap_P[]; +# endif + size_t plen = key->payload_length; + + if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH)) + return 0; + + if (ctx->encrypt) { + if (plen == NO_PAYLOAD_LENGTH) + plen = len; +# if defined(STITCHED_CALL) + /* cipher has to "fall behind" */ + if (rc4_off > md5_off) + md5_off += MD5_CBLOCK; + + if (plen > md5_off && (blocks = (plen - md5_off) / MD5_CBLOCK) && + (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) { + MD5_Update(&key->md, in, md5_off); + RC4(&key->ks, rc4_off, in, out); + + rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off, + &key->md, in + md5_off, blocks); + blocks *= MD5_CBLOCK; + rc4_off += blocks; + md5_off += blocks; + key->md.Nh += blocks >> 29; + key->md.Nl += blocks <<= 3; + if (key->md.Nl < (unsigned int)blocks) + key->md.Nh++; + } else { + rc4_off = 0; + md5_off = 0; + } +# endif + MD5_Update(&key->md, in + md5_off, plen - md5_off); + + if (plen != len) { /* "TLS" mode of operation */ + if (in != out) + memcpy(out + rc4_off, in + rc4_off, plen - rc4_off); + + /* calculate HMAC and append it to payload */ + MD5_Final(out + plen, &key->md); + key->md = key->tail; + MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH); + MD5_Final(out + plen, &key->md); + /* encrypt HMAC at once */ + RC4(&key->ks, len - rc4_off, out + rc4_off, out + rc4_off); + } else { + RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off); + } + } else { + unsigned char mac[MD5_DIGEST_LENGTH]; +# if defined(STITCHED_CALL) + /* digest has to "fall behind" */ + if (md5_off > rc4_off) + rc4_off += 2 * MD5_CBLOCK; + else + rc4_off += MD5_CBLOCK; + + if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) && + (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) { + RC4(&key->ks, rc4_off, in, out); + MD5_Update(&key->md, out, md5_off); + + rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off, + &key->md, out + md5_off, blocks); + blocks *= MD5_CBLOCK; + rc4_off += blocks; + md5_off += blocks; + l = (key->md.Nl + (blocks << 3)) & 0xffffffffU; + if (l < key->md.Nl) + key->md.Nh++; + key->md.Nl = l; + key->md.Nh += blocks >> 29; + } else { + md5_off = 0; + rc4_off = 0; + } +# endif + /* decrypt HMAC at once */ + RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off); + if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ + MD5_Update(&key->md, out + md5_off, plen - md5_off); + + /* calculate HMAC and verify it */ + MD5_Final(mac, &key->md); + key->md = key->tail; + MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH); + MD5_Final(mac, &key->md); + + if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH)) + return 0; + } else { + MD5_Update(&key->md, out + md5_off, len - md5_off); + } + } + + key->payload_length = NO_PAYLOAD_LENGTH; + + return 1; +} + +static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, + void *ptr) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); + + switch (type) { + case EVP_CTRL_AEAD_SET_MAC_KEY: + { + unsigned int i; + unsigned char hmac_key[64]; + + memset(hmac_key, 0, sizeof(hmac_key)); + + if (arg > (int)sizeof(hmac_key)) { + MD5_Init(&key->head); + MD5_Update(&key->head, ptr, arg); + MD5_Final(hmac_key, &key->head); + } else { + memcpy(hmac_key, ptr, arg); + } + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36; /* ipad */ + MD5_Init(&key->head); + MD5_Update(&key->head, hmac_key, sizeof(hmac_key)); + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ + MD5_Init(&key->tail); + MD5_Update(&key->tail, hmac_key, sizeof(hmac_key)); + + OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); + + return 1; + } + case EVP_CTRL_AEAD_TLS1_AAD: + { + unsigned char *p = ptr; + unsigned int len; + + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return -1; + + len = p[arg - 2] << 8 | p[arg - 1]; + + if (!ctx->encrypt) { + if (len < MD5_DIGEST_LENGTH) + return -1; + len -= MD5_DIGEST_LENGTH; + p[arg - 2] = len >> 8; + p[arg - 1] = len; + } + key->payload_length = len; + key->md = key->head; + MD5_Update(&key->md, p, arg); + + return MD5_DIGEST_LENGTH; + } + default: + return -1; + } +} + +static EVP_CIPHER r4_hmac_md5_cipher = { +# ifdef NID_rc4_hmac_md5 + NID_rc4_hmac_md5, +# else + NID_undef, +# endif + 1, EVP_RC4_KEY_SIZE, 0, + EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH | + EVP_CIPH_FLAG_AEAD_CIPHER, + rc4_hmac_md5_init_key, + rc4_hmac_md5_cipher, + NULL, + sizeof(EVP_RC4_HMAC_MD5), + NULL, + NULL, + rc4_hmac_md5_ctrl, + NULL +}; + +const EVP_CIPHER *EVP_rc4_hmac_md5(void) +{ + return (&r4_hmac_md5_cipher); +} +#endif diff --git a/Sources/COpenSSL/e_rc5.c b/Sources/COpenSSL/e_rc5.c new file mode 100644 index 00000000..c108774d --- /dev/null +++ b/Sources/COpenSSL/e_rc5.c @@ -0,0 +1,122 @@ +/* crypto/evp/e_rc5.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RC5 + +# include "evp.h" +# include "objects.h" +# include "evp_locl.h" +# include + +static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +typedef struct { + int rounds; /* number of rounds */ + RC5_32_KEY ks; /* key schedule */ +} EVP_RC5_KEY; + +# define data(ctx) EVP_C_DATA(EVP_RC5_KEY,ctx) + +IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5, + 8, RC5_32_KEY_LENGTH, 8, 64, + EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + r_32_12_16_init_key, NULL, NULL, NULL, rc5_ctrl) + +static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + switch (type) { + case EVP_CTRL_INIT: + data(c)->rounds = RC5_12_ROUNDS; + return 1; + + case EVP_CTRL_GET_RC5_ROUNDS: + *(int *)ptr = data(c)->rounds; + return 1; + + case EVP_CTRL_SET_RC5_ROUNDS: + switch (arg) { + case RC5_8_ROUNDS: + case RC5_12_ROUNDS: + case RC5_16_ROUNDS: + data(c)->rounds = arg; + return 1; + + default: + EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS); + return 0; + } + + default: + return -1; + } +} + +static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), + key, data(ctx)->rounds); + return 1; +} + +#endif diff --git a/Sources/COpenSSL/e_seed.c b/Sources/COpenSSL/e_seed.c new file mode 100644 index 00000000..74867e45 --- /dev/null +++ b/Sources/COpenSSL/e_seed.c @@ -0,0 +1,83 @@ +/* crypto/evp/e_seed.c */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "opensslconf.h" +#ifndef OPENSSL_NO_SEED +# include "evp.h" +# include "err.h" +# include +# include +# include "seed.h" +# include "evp_locl.h" + +static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +typedef struct { + SEED_KEY_SCHEDULE ks; +} EVP_SEED_KEY; + +IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed, + 16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1, + seed_init_key, 0, 0, 0, 0) + +static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + SEED_set_key(key, ctx->cipher_data); + return 1; +} + +#endif diff --git a/Sources/COpenSSL/e_sureware.c b/Sources/COpenSSL/e_sureware.c new file mode 100644 index 00000000..f32c6aa1 --- /dev/null +++ b/Sources/COpenSSL/e_sureware.c @@ -0,0 +1,1101 @@ +/*- +* Written by Corinne Dive-Reclus(cdive@baltimore.com) +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. All advertising materials mentioning features or use of this +* software must display the following acknowledgment: +* "This product includes software developed by the OpenSSL Project +* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" +* +* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +* endorse or promote products derived from this software without +* prior written permission. For written permission, please contact +* licensing@OpenSSL.org. +* +* 5. Products derived from this software may not be called "OpenSSL" +* nor may "OpenSSL" appear in their names without prior written +* permission of the OpenSSL Project. +* +* 6. Redistributions of any form whatsoever must retain the following +* acknowledgment: +* "This product includes software developed by the OpenSSL Project +* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" +* +* Written by Corinne Dive-Reclus(cdive@baltimore.com) +* +* Copyright@2001 Baltimore Technologies Ltd. +* All right Reserved. +* * +* THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND * +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * +* ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE * +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * +* SUCH DAMAGE. * +====================================================================*/ + +#include +#include +#include "crypto.h" +#include "pem.h" +#include "dso.h" +#include "engine.h" +#include "rand.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#include "bn.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_SUREWARE + +# ifdef FLAT_INC +# include "sureware.h" +# else +# include "sureware.h" +# endif + +# define SUREWARE_LIB_NAME "sureware engine" +# include "e_sureware_err.c" + +static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)); +static int surewarehk_destroy(ENGINE *e); +static int surewarehk_init(ENGINE *e); +static int surewarehk_finish(ENGINE *e); +static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +/* RSA stuff */ +# ifndef OPENSSL_NO_RSA +static int surewarehk_rsa_priv_dec(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int surewarehk_rsa_sign(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +# endif + +/* RAND stuff */ +static int surewarehk_rand_bytes(unsigned char *buf, int num); +static void surewarehk_rand_seed(const void *buf, int num); +static void surewarehk_rand_add(const void *buf, int num, double entropy); + +/* KM stuff */ +static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, + void *callback_data); +static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, + void *callback_data); +static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +# if 0 +static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +# endif + +# ifndef OPENSSL_NO_RSA +/* This function is aliased to mod_exp (with the mont stuff dropped). */ +static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return surewarehk_modexp(r, a, p, m, ctx); +} + +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD surewarehk_rsa = { + "SureWare RSA method", + NULL, /* pub_enc */ + NULL, /* pub_dec */ + surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc */ + surewarehk_rsa_priv_dec, /* priv_dec */ + NULL, /* mod_exp */ + surewarehk_mod_exp_mont, /* mod_exp_mongomery */ + NULL, /* init */ + NULL, /* finish */ + 0, /* RSA flag */ + NULL, + NULL, /* OpenSSL sign */ + NULL, /* OpenSSL verify */ + NULL /* keygen */ +}; +# endif + +# ifndef OPENSSL_NO_DH +/* Our internal DH_METHOD that we provide pointers to */ +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return surewarehk_modexp(r, a, p, m, ctx); +} + +static DH_METHOD surewarehk_dh = { + "SureWare DH method", + NULL, /* gen_key */ + NULL, /* agree, */ + surewarehk_modexp_dh, /* dh mod exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, + NULL +}; +# endif + +static RAND_METHOD surewarehk_rand = { + /* "SureWare RAND method", */ + surewarehk_rand_seed, + surewarehk_rand_bytes, + NULL, /* cleanup */ + surewarehk_rand_add, + surewarehk_rand_bytes, + NULL, /* rand_status */ +}; + +# ifndef OPENSSL_NO_DSA +/* DSA stuff */ +static DSA_SIG *surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, + DSA *dsa); +static int surewarehk_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, + BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont) +{ + BIGNUM t; + int to_return = 0; + BN_init(&t); + /* let rr = a1 ^ p1 mod m */ + if (!surewarehk_modexp(rr, a1, p1, m, ctx)) + goto end; + /* let t = a2 ^ p2 mod m */ + if (!surewarehk_modexp(&t, a2, p2, m, ctx)) + goto end; + /* let rr = rr * t mod m */ + if (!BN_mod_mul(rr, rr, &t, m, ctx)) + goto end; + to_return = 1; + end: + BN_free(&t); + return to_return; +} + +static DSA_METHOD surewarehk_dsa = { + "SureWare DSA method", + surewarehk_dsa_do_sign, + NULL, /* sign setup */ + NULL, /* verify, */ + surewarehk_dsa_mod_exp, /* mod exp */ + NULL, /* bn mod exp */ + NULL, /* init */ + NULL, /* finish */ + 0, + NULL, + NULL, + NULL +}; +# endif + +static const char *engine_sureware_id = "sureware"; +static const char *engine_sureware_name = "SureWare hardware engine support"; + +/* Now, to our own code */ + +/* + * As this is only ever called once, there's no need for locking (indeed - + * the lock will already be held by our caller!!!) + */ +static int bind_sureware(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif +# ifndef OPENSSL_NO_DSA + const DSA_METHOD *meth2; +# endif +# ifndef OPENSSL_NO_DH + const DH_METHOD *meth3; +# endif + + if (!ENGINE_set_id(e, engine_sureware_id) || + !ENGINE_set_name(e, engine_sureware_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &surewarehk_rsa) || +# endif +# ifndef OPENSSL_NO_DSA + !ENGINE_set_DSA(e, &surewarehk_dsa) || +# endif +# ifndef OPENSSL_NO_DH + !ENGINE_set_DH(e, &surewarehk_dh) || +# endif + !ENGINE_set_RAND(e, &surewarehk_rand) || + !ENGINE_set_destroy_function(e, surewarehk_destroy) || + !ENGINE_set_init_function(e, surewarehk_init) || + !ENGINE_set_finish_function(e, surewarehk_finish) || + !ENGINE_set_ctrl_function(e, surewarehk_ctrl) || + !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) || + !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey)) + return 0; + +# ifndef OPENSSL_NO_RSA + /* + * We know that the "PKCS1_SSLeay()" functions hook properly to the + * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: + * We don't use ENGINE_openssl() or anything "more generic" because + * something like the RSAref code may not hook properly, and if you own + * one of these cards then you have the right to do RSA operations on it + * anyway! + */ + meth1 = RSA_PKCS1_SSLeay(); + if (meth1) { + surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + } +# endif + +# ifndef OPENSSL_NO_DSA + /* + * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits. + */ + meth2 = DSA_OpenSSL(); + if (meth2) { + surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify; + } +# endif + +# ifndef OPENSSL_NO_DH + /* Much the same for Diffie-Hellman */ + meth3 = DH_OpenSSL(); + if (meth3) { + surewarehk_dh.generate_key = meth3->generate_key; + surewarehk_dh.compute_key = meth3->compute_key; + } +# endif + + /* Ensure the sureware error handling is set up */ + ERR_load_SUREWARE_strings(); + return 1; +} + +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_helper(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_sureware_id) != 0)) + return 0; + if (!bind_sureware(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) +# else +static ENGINE *engine_sureware(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_sureware(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_sureware(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_sureware(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +/* + * This is a process-global DSO handle used for loading and unloading the + * SureWareHook library. NB: This is only set (or unset) during an init() or + * finish() call (reference counts permitting) and they're operating with + * global locks, so this should be thread-safe implicitly. + */ +static DSO *surewarehk_dso = NULL; +# ifndef OPENSSL_NO_RSA +/* Index for KM handle. Not really used yet. */ +static int rsaHndidx = -1; +# endif +# ifndef OPENSSL_NO_DSA +/* Index for KM handle. Not really used yet. */ +static int dsaHndidx = -1; +# endif + +/* + * These are the function pointers that are (un)set when the library has + * successfully (un)loaded. + */ +static SureWareHook_Init_t *p_surewarehk_Init = NULL; +static SureWareHook_Finish_t *p_surewarehk_Finish = NULL; +static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL; +static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL; +static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL; +static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL; +static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL; +static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL; +static SureWareHook_Free_t *p_surewarehk_Free = NULL; +static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec = NULL; +static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign = NULL; +static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign = NULL; +static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp = NULL; + +/* Used in the DSO operations. */ +static const char *surewarehk_LIBNAME = "SureWareHook"; +static const char *n_surewarehk_Init = "SureWareHook_Init"; +static const char *n_surewarehk_Finish = "SureWareHook_Finish"; +static const char *n_surewarehk_Rand_Bytes = "SureWareHook_Rand_Bytes"; +static const char *n_surewarehk_Rand_Seed = "SureWareHook_Rand_Seed"; +static const char *n_surewarehk_Load_Privkey = "SureWareHook_Load_Privkey"; +static const char *n_surewarehk_Info_Pubkey = "SureWareHook_Info_Pubkey"; +static const char *n_surewarehk_Load_Rsa_Pubkey = + "SureWareHook_Load_Rsa_Pubkey"; +static const char *n_surewarehk_Load_Dsa_Pubkey = + "SureWareHook_Load_Dsa_Pubkey"; +static const char *n_surewarehk_Free = "SureWareHook_Free"; +static const char *n_surewarehk_Rsa_Priv_Dec = "SureWareHook_Rsa_Priv_Dec"; +static const char *n_surewarehk_Rsa_Sign = "SureWareHook_Rsa_Sign"; +static const char *n_surewarehk_Dsa_Sign = "SureWareHook_Dsa_Sign"; +static const char *n_surewarehk_Mod_Exp = "SureWareHook_Mod_Exp"; +static BIO *logstream = NULL; + +/* + * SureWareHook library functions and mechanics - these are used by the + * higher-level functions further down. NB: As and where there's no error + * checking, take a look lower down where these functions are called, the + * checking and error handling is probably down there. + */ +static int threadsafe = 1; +static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)) +{ + int to_return = 1; + + switch (cmd) { + case ENGINE_CTRL_SET_LOGSTREAM: + { + BIO *bio = (BIO *)p; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (logstream) { + BIO_free(logstream); + logstream = NULL; + } + if (CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO) > 1) + logstream = bio; + else + SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL, + SUREWARE_R_BIO_WAS_FREED); + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + /* + * This will prevent the initialisation function from "installing" + * the mutex-handling callbacks, even if they are available from + * within the library (or were provided to the library from the + * calling application). This is to remove any baggage for + * applications not using multithreading. + */ + case ENGINE_CTRL_CHIL_NO_LOCKING: + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + threadsafe = 0; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + break; + + /* The command isn't understood by this engine */ + default: + SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL, + ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + to_return = 0; + break; + } + + return to_return; +} + +/* Destructor (complements the "ENGINE_surewarehk()" constructor) */ +static int surewarehk_destroy(ENGINE *e) +{ + ERR_unload_SUREWARE_strings(); + return 1; +} + +/* (de)initialisation functions. */ +static int surewarehk_init(ENGINE *e) +{ + char msg[64] = "ENGINE_init"; + SureWareHook_Init_t *p1 = NULL; + SureWareHook_Finish_t *p2 = NULL; + SureWareHook_Rand_Bytes_t *p3 = NULL; + SureWareHook_Rand_Seed_t *p4 = NULL; + SureWareHook_Load_Privkey_t *p5 = NULL; + SureWareHook_Load_Rsa_Pubkey_t *p6 = NULL; + SureWareHook_Free_t *p7 = NULL; + SureWareHook_Rsa_Priv_Dec_t *p8 = NULL; + SureWareHook_Rsa_Sign_t *p9 = NULL; + SureWareHook_Dsa_Sign_t *p12 = NULL; + SureWareHook_Info_Pubkey_t *p13 = NULL; + SureWareHook_Load_Dsa_Pubkey_t *p14 = NULL; + SureWareHook_Mod_Exp_t *p15 = NULL; + + if (surewarehk_dso != NULL) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_ALREADY_LOADED); + goto err; + } + /* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */ + surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0); + if (surewarehk_dso == NULL) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_DSO_FAILURE); + goto err; + } + if (! + (p1 = + (SureWareHook_Init_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Init)) +|| !(p2 = + (SureWareHook_Finish_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Finish)) +|| !(p3 = + (SureWareHook_Rand_Bytes_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Rand_Bytes)) +|| !(p4 = + (SureWareHook_Rand_Seed_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Rand_Seed)) +|| !(p5 = + (SureWareHook_Load_Privkey_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Load_Privkey)) +|| !(p6 = + (SureWareHook_Load_Rsa_Pubkey_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Load_Rsa_Pubkey)) +|| !(p7 = + (SureWareHook_Free_t *) DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) +|| !(p8 = + (SureWareHook_Rsa_Priv_Dec_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Rsa_Priv_Dec)) +|| !(p9 = + (SureWareHook_Rsa_Sign_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Rsa_Sign)) +|| !(p12 = + (SureWareHook_Dsa_Sign_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Dsa_Sign)) +|| !(p13 = + (SureWareHook_Info_Pubkey_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Info_Pubkey)) +|| !(p14 = + (SureWareHook_Load_Dsa_Pubkey_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Load_Dsa_Pubkey)) +|| !(p15 = + (SureWareHook_Mod_Exp_t *) DSO_bind_func(surewarehk_dso, + n_surewarehk_Mod_Exp))) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_DSO_FAILURE); + goto err; + } + /* Copy the pointers */ + p_surewarehk_Init = p1; + p_surewarehk_Finish = p2; + p_surewarehk_Rand_Bytes = p3; + p_surewarehk_Rand_Seed = p4; + p_surewarehk_Load_Privkey = p5; + p_surewarehk_Load_Rsa_Pubkey = p6; + p_surewarehk_Free = p7; + p_surewarehk_Rsa_Priv_Dec = p8; + p_surewarehk_Rsa_Sign = p9; + p_surewarehk_Dsa_Sign = p12; + p_surewarehk_Info_Pubkey = p13; + p_surewarehk_Load_Dsa_Pubkey = p14; + p_surewarehk_Mod_Exp = p15; + /* Contact the hardware and initialises it. */ + if (p_surewarehk_Init(msg, threadsafe) == SUREWAREHOOK_ERROR_UNIT_FAILURE) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, SUREWARE_R_UNIT_FAILURE); + goto err; + } + if (p_surewarehk_Init(msg, threadsafe) == SUREWAREHOOK_ERROR_UNIT_FAILURE) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, SUREWARE_R_UNIT_FAILURE); + goto err; + } + /* + * try to load the default private key, if failed does not return a + * failure but wait for an explicit ENGINE_load_privakey + */ + surewarehk_load_privkey(e, NULL, NULL, NULL); + + /* Everything's fine. */ +# ifndef OPENSSL_NO_RSA + if (rsaHndidx == -1) + rsaHndidx = RSA_get_ex_new_index(0, + "SureWareHook RSA key handle", + NULL, NULL, surewarehk_ex_free); +# endif +# ifndef OPENSSL_NO_DSA + if (dsaHndidx == -1) + dsaHndidx = DSA_get_ex_new_index(0, + "SureWareHook DSA key handle", + NULL, NULL, surewarehk_ex_free); +# endif + + return 1; + err: + if (surewarehk_dso) + DSO_free(surewarehk_dso); + surewarehk_dso = NULL; + p_surewarehk_Init = NULL; + p_surewarehk_Finish = NULL; + p_surewarehk_Rand_Bytes = NULL; + p_surewarehk_Rand_Seed = NULL; + p_surewarehk_Load_Privkey = NULL; + p_surewarehk_Load_Rsa_Pubkey = NULL; + p_surewarehk_Free = NULL; + p_surewarehk_Rsa_Priv_Dec = NULL; + p_surewarehk_Rsa_Sign = NULL; + p_surewarehk_Dsa_Sign = NULL; + p_surewarehk_Info_Pubkey = NULL; + p_surewarehk_Load_Dsa_Pubkey = NULL; + p_surewarehk_Mod_Exp = NULL; + return 0; +} + +static int surewarehk_finish(ENGINE *e) +{ + int to_return = 1; + if (surewarehk_dso == NULL) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH, ENGINE_R_NOT_LOADED); + to_return = 0; + goto err; + } + p_surewarehk_Finish(); + if (!DSO_free(surewarehk_dso)) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH, ENGINE_R_DSO_FAILURE); + to_return = 0; + goto err; + } + err: + if (logstream) + BIO_free(logstream); + surewarehk_dso = NULL; + p_surewarehk_Init = NULL; + p_surewarehk_Finish = NULL; + p_surewarehk_Rand_Bytes = NULL; + p_surewarehk_Rand_Seed = NULL; + p_surewarehk_Load_Privkey = NULL; + p_surewarehk_Load_Rsa_Pubkey = NULL; + p_surewarehk_Free = NULL; + p_surewarehk_Rsa_Priv_Dec = NULL; + p_surewarehk_Rsa_Sign = NULL; + p_surewarehk_Dsa_Sign = NULL; + p_surewarehk_Info_Pubkey = NULL; + p_surewarehk_Load_Dsa_Pubkey = NULL; + p_surewarehk_Mod_Exp = NULL; + return to_return; +} + +static void surewarehk_error_handling(char *const msg, int func, int ret) +{ + switch (ret) { + case SUREWAREHOOK_ERROR_UNIT_FAILURE: + ENGINEerr(func, SUREWARE_R_UNIT_FAILURE); + break; + case SUREWAREHOOK_ERROR_FALLBACK: + ENGINEerr(func, SUREWARE_R_REQUEST_FALLBACK); + break; + case SUREWAREHOOK_ERROR_DATA_SIZE: + ENGINEerr(func, SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + break; + case SUREWAREHOOK_ERROR_INVALID_PAD: + ENGINEerr(func, SUREWARE_R_PADDING_CHECK_FAILED); + break; + default: + ENGINEerr(func, SUREWARE_R_REQUEST_FAILED); + break; + case 1: /* nothing */ + msg[0] = '\0'; + } + if (*msg) { + ERR_add_error_data(1, msg); + if (logstream) { + CRYPTO_w_lock(CRYPTO_LOCK_BIO); + BIO_write(logstream, msg, strlen(msg)); + CRYPTO_w_unlock(CRYPTO_LOCK_BIO); + } + } +} + +static int surewarehk_rand_bytes(unsigned char *buf, int num) +{ + int ret = 0; + char msg[64] = "ENGINE_rand_bytes"; + if (!p_surewarehk_Rand_Bytes) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES, + ENGINE_R_NOT_INITIALISED); + } else { + ret = p_surewarehk_Rand_Bytes(msg, buf, num); + surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RAND_BYTES, ret); + } + return ret == 1 ? 1 : 0; +} + +static void surewarehk_rand_seed(const void *buf, int num) +{ + int ret = 0; + char msg[64] = "ENGINE_rand_seed"; + if (!p_surewarehk_Rand_Seed) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED, + ENGINE_R_NOT_INITIALISED); + } else { + ret = p_surewarehk_Rand_Seed(msg, buf, num); + surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RAND_SEED, ret); + } +} + +static void surewarehk_rand_add(const void *buf, int num, double entropy) +{ + surewarehk_rand_seed(buf, num); +} + +static EVP_PKEY *sureware_load_public(ENGINE *e, const char *key_id, + char *hptr, unsigned long el, + char keytype) +{ + EVP_PKEY *res = NULL; +# ifndef OPENSSL_NO_RSA + RSA *rsatmp = NULL; +# endif +# ifndef OPENSSL_NO_DSA + DSA *dsatmp = NULL; +# endif + char msg[64] = "sureware_load_public"; + int ret = 0; + if (!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey) { + SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC, + ENGINE_R_NOT_INITIALISED); + goto err; + } + switch (keytype) { +# ifndef OPENSSL_NO_RSA + case 1: + /*RSA*/ + /* set private external reference */ + rsatmp = RSA_new_method(e); + RSA_set_ex_data(rsatmp, rsaHndidx, hptr); + rsatmp->flags |= RSA_FLAG_EXT_PKEY; + + /* set public big nums */ + rsatmp->e = BN_new(); + rsatmp->n = BN_new(); + if(!rsatmp->e || !rsatmp->n) + goto err; + bn_expand2(rsatmp->e, el / sizeof(BN_ULONG)); + bn_expand2(rsatmp->n, el / sizeof(BN_ULONG)); + if (rsatmp->e->dmax != (int)(el / sizeof(BN_ULONG)) || + rsatmp->n->dmax != (int)(el / sizeof(BN_ULONG))) + goto err; + ret = p_surewarehk_Load_Rsa_Pubkey(msg, key_id, el, + (unsigned long *)rsatmp->n->d, + (unsigned long *)rsatmp->e->d); + surewarehk_error_handling(msg, SUREWARE_F_SUREWARE_LOAD_PUBLIC, ret); + if (ret != 1) { + SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC, + ENGINE_R_FAILED_LOADING_PUBLIC_KEY); + goto err; + } + /* normalise pub e and pub n */ + rsatmp->e->top = el / sizeof(BN_ULONG); + bn_fix_top(rsatmp->e); + rsatmp->n->top = el / sizeof(BN_ULONG); + bn_fix_top(rsatmp->n); + /* create an EVP object: engine + rsa key */ + res = EVP_PKEY_new(); + EVP_PKEY_assign_RSA(res, rsatmp); + break; +# endif + +# ifndef OPENSSL_NO_DSA + case 2: + /*DSA*/ + /* set private/public external reference */ + dsatmp = DSA_new_method(e); + DSA_set_ex_data(dsatmp, dsaHndidx, hptr); + /* + * dsatmp->flags |= DSA_FLAG_EXT_PKEY; + */ + + /* set public key */ + dsatmp->pub_key = BN_new(); + dsatmp->p = BN_new(); + dsatmp->q = BN_new(); + dsatmp->g = BN_new(); + if(!dsatmp->pub_key || !dsatmp->p || !dsatmp->q || !dsatmp->g) + goto err; + bn_expand2(dsatmp->pub_key, el / sizeof(BN_ULONG)); + bn_expand2(dsatmp->p, el / sizeof(BN_ULONG)); + bn_expand2(dsatmp->q, 20 / sizeof(BN_ULONG)); + bn_expand2(dsatmp->g, el / sizeof(BN_ULONG)); + if (dsatmp->pub_key->dmax != (int)(el / sizeof(BN_ULONG)) + || dsatmp->p->dmax != (int)(el / sizeof(BN_ULONG)) + || dsatmp->q->dmax != 20 / sizeof(BN_ULONG) + || dsatmp->g->dmax != (int)(el / sizeof(BN_ULONG))) + goto err; + + ret = p_surewarehk_Load_Dsa_Pubkey(msg, key_id, el, + (unsigned long *)dsatmp-> + pub_key->d, + (unsigned long *)dsatmp->p->d, + (unsigned long *)dsatmp->q->d, + (unsigned long *)dsatmp->g->d); + surewarehk_error_handling(msg, SUREWARE_F_SUREWARE_LOAD_PUBLIC, ret); + if (ret != 1) { + SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC, + ENGINE_R_FAILED_LOADING_PUBLIC_KEY); + goto err; + } + /* set parameters */ + /* normalise pubkey and parameters in case of */ + dsatmp->pub_key->top = el / sizeof(BN_ULONG); + bn_fix_top(dsatmp->pub_key); + dsatmp->p->top = el / sizeof(BN_ULONG); + bn_fix_top(dsatmp->p); + dsatmp->q->top = 20 / sizeof(BN_ULONG); + bn_fix_top(dsatmp->q); + dsatmp->g->top = el / sizeof(BN_ULONG); + bn_fix_top(dsatmp->g); + + /* create an EVP object: engine + rsa key */ + res = EVP_PKEY_new(); + EVP_PKEY_assign_DSA(res, dsatmp); + break; +# endif + + default: + SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC, + ENGINE_R_FAILED_LOADING_PRIVATE_KEY); + goto err; + } + return res; + err: +# ifndef OPENSSL_NO_RSA + if (rsatmp) + RSA_free(rsatmp); +# endif +# ifndef OPENSSL_NO_DSA + if (dsatmp) + DSA_free(dsatmp); +# endif + return NULL; +} + +static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, + void *callback_data) +{ + EVP_PKEY *res = NULL; + int ret = 0; + unsigned long el = 0; + char *hptr = NULL; + char keytype = 0; + char msg[64] = "ENGINE_load_privkey"; + + if (!p_surewarehk_Load_Privkey) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY, + ENGINE_R_NOT_INITIALISED); + } else { + ret = p_surewarehk_Load_Privkey(msg, key_id, &hptr, &el, &keytype); + if (ret != 1) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY, + ENGINE_R_FAILED_LOADING_PRIVATE_KEY); + ERR_add_error_data(1, msg); + } else + res = sureware_load_public(e, key_id, hptr, el, keytype); + } + return res; +} + +static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, + void *callback_data) +{ + EVP_PKEY *res = NULL; + int ret = 0; + unsigned long el = 0; + char *hptr = NULL; + char keytype = 0; + char msg[64] = "ENGINE_load_pubkey"; + + if (!p_surewarehk_Info_Pubkey) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY, + ENGINE_R_NOT_INITIALISED); + } else { + /* call once to identify if DSA or RSA */ + ret = p_surewarehk_Info_Pubkey(msg, key_id, &el, &keytype); + if (ret != 1) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY, + ENGINE_R_FAILED_LOADING_PUBLIC_KEY); + ERR_add_error_data(1, msg); + } else + res = sureware_load_public(e, key_id, hptr, el, keytype); + } + return res; +} + +/* + * This cleans up an RSA/DSA KM key(do not destroy the key into the hardware) + * , called when ex_data is freed + */ +static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp) +{ + if (!p_surewarehk_Free) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE, ENGINE_R_NOT_INITIALISED); + } else + p_surewarehk_Free((char *)item, 0); +} + +# if 0 +/* not currently used (bug?) */ +/* + * This cleans up an DH KM key (destroys the key into hardware), called when + * ex_data is freed + */ +static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp) +{ + if (!p_surewarehk_Free) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_DH_EX_FREE, + ENGINE_R_NOT_INITIALISED); + } else + p_surewarehk_Free((char *)item, 1); +} +# endif + +/* + * return number of decrypted bytes + */ +# ifndef OPENSSL_NO_RSA +static int surewarehk_rsa_priv_dec(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + int ret = 0, tlen; + char *buf = NULL, *hptr = NULL; + char msg[64] = "ENGINE_rsa_priv_dec"; + if (!p_surewarehk_Rsa_Priv_Dec) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, + ENGINE_R_NOT_INITIALISED); + } + /* extract ref to private key */ + else if (!(hptr = RSA_get_ex_data(rsa, rsaHndidx))) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, + SUREWARE_R_MISSING_KEY_COMPONENTS); + goto err; + } + /* analyse what padding we can do into the hardware */ + if (padding == RSA_PKCS1_PADDING) { + /* do it one shot */ + ret = + p_surewarehk_Rsa_Priv_Dec(msg, flen, (unsigned char *)from, &tlen, + to, hptr, SUREWARE_PKCS1_PAD); + surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, + ret); + if (ret != 1) + goto err; + ret = tlen; + } else { /* do with no padding into hardware */ + + ret = + p_surewarehk_Rsa_Priv_Dec(msg, flen, (unsigned char *)from, &tlen, + to, hptr, SUREWARE_NO_PAD); + surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, + ret); + if (ret != 1) + goto err; + /* intermediate buffer for padding */ + if ((buf = OPENSSL_malloc(tlen)) == NULL) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, + ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(buf, to, tlen); /* transfert to into buf */ + switch (padding) { /* check padding in software */ +# ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + ret = + RSA_padding_check_PKCS1_OAEP(to, tlen, (unsigned char *)buf, + tlen, tlen, NULL, 0); + break; +# endif + case RSA_SSLV23_PADDING: + ret = + RSA_padding_check_SSLv23(to, tlen, (unsigned char *)buf, flen, + tlen); + break; + case RSA_NO_PADDING: + ret = + RSA_padding_check_none(to, tlen, (unsigned char *)buf, flen, + tlen); + break; + default: + SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, + SUREWARE_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (ret < 0) + SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, + SUREWARE_R_PADDING_CHECK_FAILED); + } + err: + if (buf) { + OPENSSL_cleanse(buf, tlen); + OPENSSL_free(buf); + } + return ret; +} + +/* + * Does what OpenSSL rsa_priv_enc does. + */ +static int surewarehk_rsa_sign(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + int ret = 0, tlen; + char *hptr = NULL; + char msg[64] = "ENGINE_rsa_sign"; + if (!p_surewarehk_Rsa_Sign) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN, ENGINE_R_NOT_INITIALISED); + } + /* extract ref to private key */ + else if (!(hptr = RSA_get_ex_data(rsa, rsaHndidx))) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN, + SUREWARE_R_MISSING_KEY_COMPONENTS); + } else { + switch (padding) { + case RSA_PKCS1_PADDING: /* do it in one shot */ + ret = + p_surewarehk_Rsa_Sign(msg, flen, (unsigned char *)from, &tlen, + to, hptr, SUREWARE_PKCS1_PAD); + surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_SIGN, + ret); + break; + case RSA_NO_PADDING: + default: + SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN, + SUREWARE_R_UNKNOWN_PADDING_TYPE); + } + } + return ret == 1 ? tlen : ret; +} + +# endif + +# ifndef OPENSSL_NO_DSA +/* DSA sign and verify */ +static DSA_SIG *surewarehk_dsa_do_sign(const unsigned char *from, int flen, + DSA *dsa) +{ + int ret = 0; + char *hptr = NULL; + DSA_SIG *psign = NULL; + char msg[64] = "ENGINE_dsa_do_sign"; + if (!p_surewarehk_Dsa_Sign) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN, + ENGINE_R_NOT_INITIALISED); + goto err; + } + /* extract ref to private key */ + else if (!(hptr = DSA_get_ex_data(dsa, dsaHndidx))) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN, + SUREWARE_R_MISSING_KEY_COMPONENTS); + goto err; + } else { + if ((psign = DSA_SIG_new()) == NULL) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN, + ERR_R_MALLOC_FAILURE); + goto err; + } + psign->r = BN_new(); + psign->s = BN_new(); + if(!psign->r || !psign->s) + goto err; + bn_expand2(psign->r, 20 / sizeof(BN_ULONG)); + bn_expand2(psign->s, 20 / sizeof(BN_ULONG)); + if (psign->r->dmax != 20 / sizeof(BN_ULONG) || + psign->s->dmax != 20 / sizeof(BN_ULONG)) + goto err; + ret = p_surewarehk_Dsa_Sign(msg, flen, from, + (unsigned long *)psign->r->d, + (unsigned long *)psign->s->d, hptr); + surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_DSA_DO_SIGN, + ret); + } + psign->r->top = 20 / sizeof(BN_ULONG); + bn_fix_top(psign->r); + psign->s->top = 20 / sizeof(BN_ULONG); + bn_fix_top(psign->s); + + err: + if (psign) { + DSA_SIG_free(psign); + psign = NULL; + } + return psign; +} +# endif + +static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + int ret = 0; + char msg[64] = "ENGINE_modexp"; + if (!p_surewarehk_Mod_Exp) { + SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP, ENGINE_R_NOT_INITIALISED); + } else if (r) { + bn_expand2(r, m->top); + if (r->dmax == m->top) { + /* do it */ + ret = p_surewarehk_Mod_Exp(msg, + m->top * sizeof(BN_ULONG), + (unsigned long *)m->d, + p->top * sizeof(BN_ULONG), + (unsigned long *)p->d, + a->top * sizeof(BN_ULONG), + (unsigned long *)a->d, + (unsigned long *)r->d); + surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_MODEXP, ret); + if (ret == 1) { + /* normalise result */ + r->top = m->top; + bn_fix_top(r); + } + } + } + return ret; +} +# endif /* !OPENSSL_NO_HW_SureWare */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_sureware_err.c b/Sources/COpenSSL/e_sureware_err.c new file mode 100644 index 00000000..7551f181 --- /dev/null +++ b/Sources/COpenSSL/e_sureware_err.c @@ -0,0 +1,154 @@ +/* e_sureware_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_sureware_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA SUREWARE_str_functs[] = { + {ERR_FUNC(SUREWARE_F_SUREWAREHK_CTRL), "SUREWAREHK_CTRL"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_DH_EX_FREE), "SUREWAREHK_DH_EX_FREE"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN), "SUREWAREHK_DSA_DO_SIGN"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_EX_FREE), "SUREWAREHK_EX_FREE"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_FINISH), "SUREWAREHK_FINISH"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_INIT), "SUREWAREHK_INIT"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY), "SUREWAREHK_LOAD_PRIVKEY"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY), "SUREWAREHK_LOAD_PUBKEY"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_MODEXP), "SUREWAREHK_MODEXP"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_BYTES), "SUREWAREHK_RAND_BYTES"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_SEED), "SUREWAREHK_RAND_SEED"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC), "SUREWAREHK_RSA_PRIV_DEC"}, + {ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_SIGN), "SUREWAREHK_RSA_SIGN"}, + {ERR_FUNC(SUREWARE_F_SUREWARE_LOAD_PUBLIC), "SUREWARE_LOAD_PUBLIC"}, + {0, NULL} +}; + +static ERR_STRING_DATA SUREWARE_str_reasons[] = { + {ERR_REASON(SUREWARE_R_BIO_WAS_FREED), "bio was freed"}, + {ERR_REASON(SUREWARE_R_MISSING_KEY_COMPONENTS), "missing key components"}, + {ERR_REASON(SUREWARE_R_PADDING_CHECK_FAILED), "padding check failed"}, + {ERR_REASON(SUREWARE_R_REQUEST_FAILED), "request failed"}, + {ERR_REASON(SUREWARE_R_REQUEST_FALLBACK), "request fallback"}, + {ERR_REASON(SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL), + "size too large or too small"}, + {ERR_REASON(SUREWARE_R_UNIT_FAILURE), "unit failure"}, + {ERR_REASON(SUREWARE_R_UNKNOWN_PADDING_TYPE), "unknown padding type"}, + {0, NULL} +}; + +#endif + +#ifdef SUREWARE_LIB_NAME +static ERR_STRING_DATA SUREWARE_lib_name[] = { + {0, SUREWARE_LIB_NAME}, + {0, NULL} +}; +#endif + +static int SUREWARE_lib_error_code = 0; +static int SUREWARE_error_init = 1; + +static void ERR_load_SUREWARE_strings(void) +{ + if (SUREWARE_lib_error_code == 0) + SUREWARE_lib_error_code = ERR_get_next_error_library(); + + if (SUREWARE_error_init) { + SUREWARE_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(SUREWARE_lib_error_code, SUREWARE_str_functs); + ERR_load_strings(SUREWARE_lib_error_code, SUREWARE_str_reasons); +#endif + +#ifdef SUREWARE_LIB_NAME + SUREWARE_lib_name->error = ERR_PACK(SUREWARE_lib_error_code, 0, 0); + ERR_load_strings(0, SUREWARE_lib_name); +#endif + } +} + +static void ERR_unload_SUREWARE_strings(void) +{ + if (SUREWARE_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(SUREWARE_lib_error_code, SUREWARE_str_functs); + ERR_unload_strings(SUREWARE_lib_error_code, SUREWARE_str_reasons); +#endif + +#ifdef SUREWARE_LIB_NAME + ERR_unload_strings(0, SUREWARE_lib_name); +#endif + SUREWARE_error_init = 1; + } +} + +static void ERR_SUREWARE_error(int function, int reason, char *file, int line) +{ + if (SUREWARE_lib_error_code == 0) + SUREWARE_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(SUREWARE_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_sureware_err.h b/Sources/COpenSSL/e_sureware_err.h new file mode 100644 index 00000000..bef86239 --- /dev/null +++ b/Sources/COpenSSL/e_sureware_err.h @@ -0,0 +1,104 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SUREWARE_ERR_H +# define HEADER_SUREWARE_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_SUREWARE_strings(void); +static void ERR_unload_SUREWARE_strings(void); +static void ERR_SUREWARE_error(int function, int reason, char *file, + int line); +# define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the SUREWARE functions. */ + +/* Function codes. */ +# define SUREWARE_F_SUREWAREHK_CTRL 100 +# define SUREWARE_F_SUREWAREHK_DH_EX_FREE 112 +# define SUREWARE_F_SUREWAREHK_DSA_DO_SIGN 101 +# define SUREWARE_F_SUREWAREHK_EX_FREE 102 +# define SUREWARE_F_SUREWAREHK_FINISH 103 +# define SUREWARE_F_SUREWAREHK_INIT 104 +# define SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY 105 +# define SUREWARE_F_SUREWAREHK_LOAD_PUBKEY 113 +# define SUREWARE_F_SUREWAREHK_MODEXP 107 +# define SUREWARE_F_SUREWAREHK_RAND_BYTES 108 +# define SUREWARE_F_SUREWAREHK_RAND_SEED 109 +# define SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC 110 +# define SUREWARE_F_SUREWAREHK_RSA_SIGN 111 +# define SUREWARE_F_SUREWARE_LOAD_PUBLIC 106 + +/* Reason codes. */ +# define SUREWARE_R_BIO_WAS_FREED 100 +# define SUREWARE_R_MISSING_KEY_COMPONENTS 105 +# define SUREWARE_R_PADDING_CHECK_FAILED 106 +# define SUREWARE_R_REQUEST_FAILED 101 +# define SUREWARE_R_REQUEST_FALLBACK 102 +# define SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 103 +# define SUREWARE_R_UNIT_FAILURE 104 +# define SUREWARE_R_UNKNOWN_PADDING_TYPE 107 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_ubsec.c b/Sources/COpenSSL/e_ubsec.c new file mode 100644 index 00000000..e00ea4bd --- /dev/null +++ b/Sources/COpenSSL/e_ubsec.c @@ -0,0 +1,1085 @@ +/* crypto/engine/hw_ubsec.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. Cloned shamelessly by Joe Tardo. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "crypto.h" +#include "buffer.h" +#include "dso.h" +#include "engine.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#include "bn.h" + +#ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_UBSEC + +# ifdef FLAT_INC +# include "hw_ubsec.h" +# else +# include "hw_ubsec.h" +# endif + +# define UBSEC_LIB_NAME "ubsec engine" +# include "e_ubsec_err.c" + +# define FAIL_TO_SOFTWARE -15 + +static int ubsec_destroy(ENGINE *e); +static int ubsec_init(ENGINE *e); +static int ubsec_finish(ENGINE *e); +static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); +static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +# ifndef OPENSSL_NO_RSA +static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dp, + const BIGNUM *dq, const BIGNUM *qinv, + BN_CTX *ctx); +static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif +# ifndef OPENSSL_NO_DSA +# ifdef NOT_USED +static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont); +static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +# endif +static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, + DSA *dsa); +static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); +# endif +# ifndef OPENSSL_NO_DH +static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, + DH *dh); +static int ubsec_dh_generate_key(DH *dh); +# endif + +# ifdef NOT_USED +static int ubsec_rand_bytes(unsigned char *buf, int num); +static int ubsec_rand_status(void); +# endif + +# define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE +static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = { + {UBSEC_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the 'ubsec' shared library", + ENGINE_CMD_FLAG_STRING}, + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD ubsec_rsa = { + "UBSEC RSA method", + NULL, + NULL, + NULL, + NULL, + ubsec_rsa_mod_exp, + ubsec_mod_exp_mont, + NULL, + NULL, + 0, + NULL, + NULL, + NULL, + NULL +}; +# endif + +# ifndef OPENSSL_NO_DSA +/* Our internal DSA_METHOD that we provide pointers to */ +static DSA_METHOD ubsec_dsa = { + "UBSEC DSA method", + ubsec_dsa_do_sign, /* dsa_do_sign */ + NULL, /* dsa_sign_setup */ + ubsec_dsa_verify, /* dsa_do_verify */ + NULL, /* ubsec_dsa_mod_exp *//* dsa_mod_exp */ + NULL, /* ubsec_mod_exp_dsa *//* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* dsa_paramgen */ + NULL /* dsa_keygen */ +}; +# endif + +# ifndef OPENSSL_NO_DH +/* Our internal DH_METHOD that we provide pointers to */ +static DH_METHOD ubsec_dh = { + "UBSEC DH method", + ubsec_dh_generate_key, + ubsec_dh_compute_key, + ubsec_mod_exp_dh, + NULL, + NULL, + 0, + NULL, + NULL +}; +# endif + +/* Constants used when creating the ENGINE */ +static const char *engine_ubsec_id = "ubsec"; +static const char *engine_ubsec_name = "UBSEC hardware engine support"; + +/* + * This internal function is used by ENGINE_ubsec() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif +# ifndef OPENSSL_NO_DH +# ifndef HAVE_UBSEC_DH + const DH_METHOD *meth3; +# endif /* HAVE_UBSEC_DH */ +# endif + if (!ENGINE_set_id(e, engine_ubsec_id) || + !ENGINE_set_name(e, engine_ubsec_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &ubsec_rsa) || +# endif +# ifndef OPENSSL_NO_DSA + !ENGINE_set_DSA(e, &ubsec_dsa) || +# endif +# ifndef OPENSSL_NO_DH + !ENGINE_set_DH(e, &ubsec_dh) || +# endif + !ENGINE_set_destroy_function(e, ubsec_destroy) || + !ENGINE_set_init_function(e, ubsec_init) || + !ENGINE_set_finish_function(e, ubsec_finish) || + !ENGINE_set_ctrl_function(e, ubsec_ctrl) || + !ENGINE_set_cmd_defns(e, ubsec_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + /* + * We know that the "PKCS1_SSLeay()" functions hook properly to the + * Broadcom-specific mod_exp and mod_exp_crt so we use those functions. + * NB: We don't use ENGINE_openssl() or anything "more generic" because + * something like the RSAref code may not hook properly, and if you own + * one of these cards then you have the right to do RSA operations on it + * anyway! + */ + meth1 = RSA_PKCS1_SSLeay(); + ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec; +# endif + +# ifndef OPENSSL_NO_DH +# ifndef HAVE_UBSEC_DH + /* Much the same for Diffie-Hellman */ + meth3 = DH_OpenSSL(); + ubsec_dh.generate_key = meth3->generate_key; + ubsec_dh.compute_key = meth3->compute_key; +# endif /* HAVE_UBSEC_DH */ +# endif + + /* Ensure the ubsec error handling is set up */ + ERR_load_UBSEC_strings(); + return 1; +} + +# ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_ubsec(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_ubsec(void) +{ + /* Copied from eng_[openssl|dyn].c */ + ENGINE *toadd = engine_ubsec(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +# endif + +/* + * This is a process-global DSO handle used for loading and unloading the + * UBSEC library. NB: This is only set (or unset) during an init() or + * finish() call (reference counts permitting) and they're operating with + * global locks, so this should be thread-safe implicitly. + */ + +static DSO *ubsec_dso = NULL; + +/* + * These are the function pointers that are (un)set when the library has + * successfully (un)loaded. + */ + +static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL; +static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL; +static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL; +static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL; +# ifndef OPENSSL_NO_DH +static t_UBSEC_diffie_hellman_generate_ioctl + * p_UBSEC_diffie_hellman_generate_ioctl = NULL; +static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl + = NULL; +# endif +# ifndef OPENSSL_NO_RSA +static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL; +static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; +# endif +# ifndef OPENSSL_NO_DSA +static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL; +static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL; +# endif +static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL; +static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL; +static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL; + +static int max_key_len = 1024; /* ??? */ + +/* + * These are the static string constants for the DSO file name and the function + * symbol names to bind to. + */ + +static const char *UBSEC_LIBNAME = NULL; +static const char *get_UBSEC_LIBNAME(void) +{ + if (UBSEC_LIBNAME) + return UBSEC_LIBNAME; + return "ubsec"; +} + +static void free_UBSEC_LIBNAME(void) +{ + if (UBSEC_LIBNAME) + OPENSSL_free((void *)UBSEC_LIBNAME); + UBSEC_LIBNAME = NULL; +} + +static long set_UBSEC_LIBNAME(const char *name) +{ + free_UBSEC_LIBNAME(); + return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); +} + +static const char *UBSEC_F1 = "ubsec_bytes_to_bits"; +static const char *UBSEC_F2 = "ubsec_bits_to_bytes"; +static const char *UBSEC_F3 = "ubsec_open"; +static const char *UBSEC_F4 = "ubsec_close"; +# ifndef OPENSSL_NO_DH +static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl"; +static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl"; +# endif +/* #ifndef OPENSSL_NO_RSA */ +static const char *UBSEC_F7 = "rsa_mod_exp_ioctl"; +static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl"; +/* #endif */ +# ifndef OPENSSL_NO_DSA +static const char *UBSEC_F9 = "dsa_sign_ioctl"; +static const char *UBSEC_F10 = "dsa_verify_ioctl"; +# endif +static const char *UBSEC_F11 = "math_accelerate_ioctl"; +static const char *UBSEC_F12 = "rng_ioctl"; +static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl"; + +/* Destructor (complements the "ENGINE_ubsec()" constructor) */ +static int ubsec_destroy(ENGINE *e) +{ + free_UBSEC_LIBNAME(); + ERR_unload_UBSEC_strings(); + return 1; +} + +/* (de)initialisation functions. */ +static int ubsec_init(ENGINE *e) +{ + t_UBSEC_ubsec_bytes_to_bits *p1; + t_UBSEC_ubsec_bits_to_bytes *p2; + t_UBSEC_ubsec_open *p3; + t_UBSEC_ubsec_close *p4; +# ifndef OPENSSL_NO_DH + t_UBSEC_diffie_hellman_generate_ioctl *p5; + t_UBSEC_diffie_hellman_agree_ioctl *p6; +# endif +/* #ifndef OPENSSL_NO_RSA */ + t_UBSEC_rsa_mod_exp_ioctl *p7; + t_UBSEC_rsa_mod_exp_crt_ioctl *p8; +/* #endif */ +# ifndef OPENSSL_NO_DSA + t_UBSEC_dsa_sign_ioctl *p9; + t_UBSEC_dsa_verify_ioctl *p10; +# endif + t_UBSEC_math_accelerate_ioctl *p11; + t_UBSEC_rng_ioctl *p12; + t_UBSEC_max_key_len_ioctl *p13; + int fd = 0; + + if (ubsec_dso != NULL) { + UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED); + goto err; + } + /* + * Attempt to load libubsec.so/ubsec.dll/whatever. + */ + ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0); + if (ubsec_dso == NULL) { + UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); + goto err; + } + + if (!(p1 = (t_UBSEC_ubsec_bytes_to_bits *) + DSO_bind_func(ubsec_dso, UBSEC_F1)) + || !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) + DSO_bind_func(ubsec_dso, UBSEC_F2)) + || !(p3 = (t_UBSEC_ubsec_open *) + DSO_bind_func(ubsec_dso, UBSEC_F3)) + || !(p4 = (t_UBSEC_ubsec_close *) + DSO_bind_func(ubsec_dso, UBSEC_F4)) +# ifndef OPENSSL_NO_DH + || !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F5)) + || !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F6)) +# endif +/* #ifndef OPENSSL_NO_RSA */ + || !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F7)) + || !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F8)) +/* #endif */ +# ifndef OPENSSL_NO_DSA + || !(p9 = (t_UBSEC_dsa_sign_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F9)) + || !(p10 = (t_UBSEC_dsa_verify_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F10)) +# endif + || !(p11 = (t_UBSEC_math_accelerate_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F11)) + || !(p12 = (t_UBSEC_rng_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F12)) + || !(p13 = (t_UBSEC_max_key_len_ioctl *) + DSO_bind_func(ubsec_dso, UBSEC_F13))) { + UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); + goto err; + } + + /* Copy the pointers */ + p_UBSEC_ubsec_bytes_to_bits = p1; + p_UBSEC_ubsec_bits_to_bytes = p2; + p_UBSEC_ubsec_open = p3; + p_UBSEC_ubsec_close = p4; +# ifndef OPENSSL_NO_DH + p_UBSEC_diffie_hellman_generate_ioctl = p5; + p_UBSEC_diffie_hellman_agree_ioctl = p6; +# endif +# ifndef OPENSSL_NO_RSA + p_UBSEC_rsa_mod_exp_ioctl = p7; + p_UBSEC_rsa_mod_exp_crt_ioctl = p8; +# endif +# ifndef OPENSSL_NO_DSA + p_UBSEC_dsa_sign_ioctl = p9; + p_UBSEC_dsa_verify_ioctl = p10; +# endif + p_UBSEC_math_accelerate_ioctl = p11; + p_UBSEC_rng_ioctl = p12; + p_UBSEC_max_key_len_ioctl = p13; + + /* Perform an open to see if there's actually any unit running. */ + if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) + && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0)) { + p_UBSEC_ubsec_close(fd); + return 1; + } else { + UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); + } + + err: + if (ubsec_dso) + DSO_free(ubsec_dso); + ubsec_dso = NULL; + p_UBSEC_ubsec_bytes_to_bits = NULL; + p_UBSEC_ubsec_bits_to_bytes = NULL; + p_UBSEC_ubsec_open = NULL; + p_UBSEC_ubsec_close = NULL; +# ifndef OPENSSL_NO_DH + p_UBSEC_diffie_hellman_generate_ioctl = NULL; + p_UBSEC_diffie_hellman_agree_ioctl = NULL; +# endif +# ifndef OPENSSL_NO_RSA + p_UBSEC_rsa_mod_exp_ioctl = NULL; + p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; +# endif +# ifndef OPENSSL_NO_DSA + p_UBSEC_dsa_sign_ioctl = NULL; + p_UBSEC_dsa_verify_ioctl = NULL; +# endif + p_UBSEC_math_accelerate_ioctl = NULL; + p_UBSEC_rng_ioctl = NULL; + p_UBSEC_max_key_len_ioctl = NULL; + + return 0; +} + +static int ubsec_finish(ENGINE *e) +{ + free_UBSEC_LIBNAME(); + if (ubsec_dso == NULL) { + UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED); + return 0; + } + if (!DSO_free(ubsec_dso)) { + UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE); + return 0; + } + ubsec_dso = NULL; + p_UBSEC_ubsec_bytes_to_bits = NULL; + p_UBSEC_ubsec_bits_to_bytes = NULL; + p_UBSEC_ubsec_open = NULL; + p_UBSEC_ubsec_close = NULL; +# ifndef OPENSSL_NO_DH + p_UBSEC_diffie_hellman_generate_ioctl = NULL; + p_UBSEC_diffie_hellman_agree_ioctl = NULL; +# endif +# ifndef OPENSSL_NO_RSA + p_UBSEC_rsa_mod_exp_ioctl = NULL; + p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; +# endif +# ifndef OPENSSL_NO_DSA + p_UBSEC_dsa_sign_ioctl = NULL; + p_UBSEC_dsa_verify_ioctl = NULL; +# endif + p_UBSEC_math_accelerate_ioctl = NULL; + p_UBSEC_rng_ioctl = NULL; + p_UBSEC_max_key_len_ioctl = NULL; + return 1; +} + +static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int initialised = ((ubsec_dso == NULL) ? 0 : 1); + switch (cmd) { + case UBSEC_CMD_SO_PATH: + if (p == NULL) { + UBSECerr(UBSEC_F_UBSEC_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (initialised) { + UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_ALREADY_LOADED); + return 0; + } + return set_UBSEC_LIBNAME((const char *)p); + default: + break; + } + UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + int y_len = 0; + int fd; + + if (ubsec_dso == NULL) { + UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED); + return 0; + } + + /* Check if hardware can't handle this argument. */ + y_len = BN_num_bits(m); + if (y_len > max_key_len) { + UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return BN_mod_exp(r, a, p, m, ctx); + } + + if (!bn_wexpand(r, m->top)) { + UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL); + return 0; + } + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { + fd = 0; + UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE); + return BN_mod_exp(r, a, p, m, ctx); + } + + if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a), + (unsigned char *)m->d, BN_num_bits(m), + (unsigned char *)p->d, BN_num_bits(p), + (unsigned char *)r->d, &y_len) != 0) { + UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + return BN_mod_exp(r, a, p, m, ctx); + } + + p_UBSEC_ubsec_close(fd); + + r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2; + return 1; +} + +# ifndef OPENSSL_NO_RSA +static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + int to_return = 0; + + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { + UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS); + goto err; + } + + to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, + rsa->dmq1, rsa->iqmp, ctx); + if (to_return == FAIL_TO_SOFTWARE) { + /* + * Do in software as hardware failed. + */ + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); + } + err: + return to_return; +} + +static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *q, const BIGNUM *dp, + const BIGNUM *dq, const BIGNUM *qinv, + BN_CTX *ctx) +{ + int y_len, fd; + + y_len = BN_num_bits(p) + BN_num_bits(q); + + /* Check if hardware can't handle this argument. */ + if (y_len > max_key_len) { + UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, + UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + return FAIL_TO_SOFTWARE; + } + + if (!bn_wexpand(r, p->top + q->top + 1)) { + UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL); + return 0; + } + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { + fd = 0; + UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE); + return FAIL_TO_SOFTWARE; + } + + if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd, + (unsigned char *)a->d, BN_num_bits(a), + (unsigned char *)qinv->d, + BN_num_bits(qinv), + (unsigned char *)dp->d, BN_num_bits(dp), + (unsigned char *)p->d, BN_num_bits(p), + (unsigned char *)dq->d, BN_num_bits(dq), + (unsigned char *)q->d, BN_num_bits(q), + (unsigned char *)r->d, &y_len) != 0) { + UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + return FAIL_TO_SOFTWARE; + } + + p_UBSEC_ubsec_close(fd); + + r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1) / BN_BITS2; + return 1; +} +# endif + +# ifndef OPENSSL_NO_DSA +# ifdef NOT_USED +static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, + BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + BIGNUM t; + int to_return = 0; + + BN_init(&t); + /* let rr = a1 ^ p1 mod m */ + if (!ubsec_mod_exp(rr, a1, p1, m, ctx)) + goto end; + /* let t = a2 ^ p2 mod m */ + if (!ubsec_mod_exp(&t, a2, p2, m, ctx)) + goto end; + /* let rr = rr * t mod m */ + if (!BN_mod_mul(rr, rr, &t, m, ctx)) + goto end; + to_return = 1; + end: + BN_free(&t); + return to_return; +} + +static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return ubsec_mod_exp(r, a, p, m, ctx); +} +# endif +# endif + +# ifndef OPENSSL_NO_RSA + +/* + * This function is aliased to mod_exp (with the mont stuff dropped). + */ +static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + int ret = 0; + + /* Do in software if the key is too large for the hardware. */ + if (BN_num_bits(m) > max_key_len) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + ret = (*meth->bn_mod_exp) (r, a, p, m, ctx, m_ctx); + } else { + ret = ubsec_mod_exp(r, a, p, m, ctx); + } + + return ret; +} +# endif + +# ifndef OPENSSL_NO_DH +/* This function is aliased to mod_exp (with the dh and mont dropped). */ +static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return ubsec_mod_exp(r, a, p, m, ctx); +} +# endif + +# ifndef OPENSSL_NO_DSA +static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, + DSA *dsa) +{ + DSA_SIG *to_return = NULL; + int s_len = 160, r_len = 160, d_len, fd; + BIGNUM m, *r = NULL, *s = NULL; + + BN_init(&m); + + s = BN_new(); + r = BN_new(); + if ((s == NULL) || (r == NULL)) + goto err; + + d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen); + + if (!bn_wexpand(r, (160 + BN_BITS2 - 1) / BN_BITS2) || + (!bn_wexpand(s, (160 + BN_BITS2 - 1) / BN_BITS2))) { + UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); + goto err; + } + + if (BN_bin2bn(dgst, dlen, &m) == NULL) { + UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); + goto err; + } + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { + const DSA_METHOD *meth; + fd = 0; + UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE); + meth = DSA_OpenSSL(); + to_return = meth->dsa_do_sign(dgst, dlen, dsa); + goto err; + } + + if (p_UBSEC_dsa_sign_ioctl(fd, + /* compute hash before signing */ + 0, (unsigned char *)dgst, d_len, NULL, + /* compute random value */ + 0, + (unsigned char *)dsa->p->d, + BN_num_bits(dsa->p), + (unsigned char *)dsa->q->d, + BN_num_bits(dsa->q), + (unsigned char *)dsa->g->d, + BN_num_bits(dsa->g), + (unsigned char *)dsa->priv_key->d, + BN_num_bits(dsa->priv_key), + (unsigned char *)r->d, &r_len, + (unsigned char *)s->d, &s_len) != 0) { + const DSA_METHOD *meth; + + UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + meth = DSA_OpenSSL(); + to_return = meth->dsa_do_sign(dgst, dlen, dsa); + + goto err; + } + + p_UBSEC_ubsec_close(fd); + + r->top = (160 + BN_BITS2 - 1) / BN_BITS2; + s->top = (160 + BN_BITS2 - 1) / BN_BITS2; + + to_return = DSA_SIG_new(); + if (to_return == NULL) { + UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); + goto err; + } + + to_return->r = r; + to_return->s = s; + + err: + if (!to_return) { + if (r) + BN_free(r); + if (s) + BN_free(s); + } + BN_clear_free(&m); + return to_return; +} + +static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa) +{ + int v_len, d_len; + int to_return = 0; + int fd; + BIGNUM v, *pv = &v; + + BN_init(&v); + + if (!bn_wexpand(pv, dsa->p->top)) { + UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL); + goto err; + } + + v_len = BN_num_bits(dsa->p); + + d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len); + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { + const DSA_METHOD *meth; + fd = 0; + UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE); + meth = DSA_OpenSSL(); + to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); + goto err; + } + + if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */ + (unsigned char *)dgst, d_len, + (unsigned char *)dsa->p->d, + BN_num_bits(dsa->p), + (unsigned char *)dsa->q->d, + BN_num_bits(dsa->q), + (unsigned char *)dsa->g->d, + BN_num_bits(dsa->g), + (unsigned char *)dsa->pub_key->d, + BN_num_bits(dsa->pub_key), + (unsigned char *)sig->r->d, + BN_num_bits(sig->r), + (unsigned char *)sig->s->d, + BN_num_bits(sig->s), (unsigned char *)v.d, + &v_len) != 0) { + const DSA_METHOD *meth; + UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + meth = DSA_OpenSSL(); + to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); + + goto err; + } + + p_UBSEC_ubsec_close(fd); + + to_return = 1; + err: + BN_clear_free(&v); + return to_return; +} +# endif + +# ifndef OPENSSL_NO_DH +static int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, + DH *dh) +{ + int ret = -1, k_len, fd; + + k_len = BN_num_bits(dh->p); + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { + const DH_METHOD *meth; + UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE); + meth = DH_OpenSSL(); + ret = meth->compute_key(key, pub_key, dh); + goto err; + } + + if (p_UBSEC_diffie_hellman_agree_ioctl(fd, + (unsigned char *)dh->priv_key->d, + BN_num_bits(dh->priv_key), + (unsigned char *)pub_key->d, + BN_num_bits(pub_key), + (unsigned char *)dh->p->d, + BN_num_bits(dh->p), key, + &k_len) != 0) { + /* Hardware's a no go, failover to software */ + const DH_METHOD *meth; + UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + meth = DH_OpenSSL(); + ret = meth->compute_key(key, pub_key, dh); + + goto err; + } + + p_UBSEC_ubsec_close(fd); + + ret = p_UBSEC_ubsec_bits_to_bytes(k_len); + err: + return ret; +} + +static int ubsec_dh_generate_key(DH *dh) +{ + int ret = 0, random_bits = 0, pub_key_len = 0, priv_key_len = 0, fd; + BIGNUM *pub_key = NULL; + BIGNUM *priv_key = NULL; + + /* + * How many bits should Random x be? dh_key.c + * sets the range from 0 to num_bits(modulus) ??? + */ + + if (dh->priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) + goto err; + priv_key_len = BN_num_bits(dh->p); + if (bn_wexpand(priv_key, dh->p->top) == NULL) + goto err; + do + if (!BN_rand_range(priv_key, dh->p)) + goto err; + while (BN_is_zero(priv_key)) ; + random_bits = BN_num_bits(priv_key); + } else { + priv_key = dh->priv_key; + } + + if (dh->pub_key == NULL) { + pub_key = BN_new(); + if (pub_key == NULL) + goto err; + pub_key_len = BN_num_bits(dh->p); + if (bn_wexpand(pub_key, dh->p->top) == NULL) + goto err; + } else { + pub_key = dh->pub_key; + } + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { + const DH_METHOD *meth; + UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE); + meth = DH_OpenSSL(); + ret = meth->generate_key(dh); + goto err; + } + + if (p_UBSEC_diffie_hellman_generate_ioctl(fd, + (unsigned char *)priv_key->d, + &priv_key_len, + (unsigned char *)pub_key->d, + &pub_key_len, + (unsigned char *)dh->g->d, + BN_num_bits(dh->g), + (unsigned char *)dh->p->d, + BN_num_bits(dh->p), 0, 0, + random_bits) != 0) { + /* Hardware's a no go, failover to software */ + const DH_METHOD *meth; + + UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + meth = DH_OpenSSL(); + ret = meth->generate_key(dh); + + goto err; + } + + p_UBSEC_ubsec_close(fd); + + dh->pub_key = pub_key; + dh->pub_key->top = (pub_key_len + BN_BITS2 - 1) / BN_BITS2; + dh->priv_key = priv_key; + dh->priv_key->top = (priv_key_len + BN_BITS2 - 1) / BN_BITS2; + + ret = 1; + err: + return ret; +} +# endif + +# ifdef NOT_USED +static int ubsec_rand_bytes(unsigned char *buf, int num) +{ + int ret = 0, fd; + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { + const RAND_METHOD *meth; + UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE); + num = p_UBSEC_ubsec_bits_to_bytes(num); + meth = RAND_SSLeay(); + meth->seed(buf, num); + ret = meth->bytes(buf, num); + goto err; + } + + num *= 8; /* bytes to bits */ + + if (p_UBSEC_rng_ioctl(fd, UBSEC_RNG_DIRECT, buf, &num) != 0) { + /* Hardware's a no go, failover to software */ + const RAND_METHOD *meth; + + UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + num = p_UBSEC_ubsec_bits_to_bytes(num); + meth = RAND_SSLeay(); + meth->seed(buf, num); + ret = meth->bytes(buf, num); + + goto err; + } + + p_UBSEC_ubsec_close(fd); + + ret = 1; + err: + return (ret); +} + +static int ubsec_rand_status(void) +{ + return 0; +} +# endif + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +# ifndef OPENSSL_NO_DYNAMIC_ENGINE +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_ubsec_id) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ +# endif /* !OPENSSL_NO_HW_UBSEC */ +#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_ubsec_err.c b/Sources/COpenSSL/e_ubsec_err.c new file mode 100644 index 00000000..948b87f7 --- /dev/null +++ b/Sources/COpenSSL/e_ubsec_err.c @@ -0,0 +1,154 @@ +/* e_ubsec_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "e_ubsec_err.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(0,func,0) +# define ERR_REASON(reason) ERR_PACK(0,0,reason) + +static ERR_STRING_DATA UBSEC_str_functs[] = { + {ERR_FUNC(UBSEC_F_UBSEC_CTRL), "UBSEC_CTRL"}, + {ERR_FUNC(UBSEC_F_UBSEC_DH_COMPUTE_KEY), "UBSEC_DH_COMPUTE_KEY"}, + {ERR_FUNC(UBSEC_F_UBSEC_DH_GENERATE_KEY), "UBSEC_DH_GENERATE_KEY"}, + {ERR_FUNC(UBSEC_F_UBSEC_DSA_DO_SIGN), "UBSEC_DSA_DO_SIGN"}, + {ERR_FUNC(UBSEC_F_UBSEC_DSA_VERIFY), "UBSEC_DSA_VERIFY"}, + {ERR_FUNC(UBSEC_F_UBSEC_FINISH), "UBSEC_FINISH"}, + {ERR_FUNC(UBSEC_F_UBSEC_INIT), "UBSEC_INIT"}, + {ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP), "UBSEC_MOD_EXP"}, + {ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP_CRT), "UBSEC_MOD_EXP_CRT"}, + {ERR_FUNC(UBSEC_F_UBSEC_RAND_BYTES), "UBSEC_RAND_BYTES"}, + {ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP), "UBSEC_RSA_MOD_EXP"}, + {ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT), "UBSEC_RSA_MOD_EXP_CRT"}, + {0, NULL} +}; + +static ERR_STRING_DATA UBSEC_str_reasons[] = { + {ERR_REASON(UBSEC_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(UBSEC_R_BN_EXPAND_FAIL), "bn expand fail"}, + {ERR_REASON(UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(UBSEC_R_DSO_FAILURE), "dso failure"}, + {ERR_REASON(UBSEC_R_MISSING_KEY_COMPONENTS), "missing key components"}, + {ERR_REASON(UBSEC_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(UBSEC_R_REQUEST_FAILED), "request failed"}, + {ERR_REASON(UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL), + "size too large or too small"}, + {ERR_REASON(UBSEC_R_UNIT_FAILURE), "unit failure"}, + {0, NULL} +}; + +#endif + +#ifdef UBSEC_LIB_NAME +static ERR_STRING_DATA UBSEC_lib_name[] = { + {0, UBSEC_LIB_NAME}, + {0, NULL} +}; +#endif + +static int UBSEC_lib_error_code = 0; +static int UBSEC_error_init = 1; + +static void ERR_load_UBSEC_strings(void) +{ + if (UBSEC_lib_error_code == 0) + UBSEC_lib_error_code = ERR_get_next_error_library(); + + if (UBSEC_error_init) { + UBSEC_error_init = 0; +#ifndef OPENSSL_NO_ERR + ERR_load_strings(UBSEC_lib_error_code, UBSEC_str_functs); + ERR_load_strings(UBSEC_lib_error_code, UBSEC_str_reasons); +#endif + +#ifdef UBSEC_LIB_NAME + UBSEC_lib_name->error = ERR_PACK(UBSEC_lib_error_code, 0, 0); + ERR_load_strings(0, UBSEC_lib_name); +#endif + } +} + +static void ERR_unload_UBSEC_strings(void) +{ + if (UBSEC_error_init == 0) { +#ifndef OPENSSL_NO_ERR + ERR_unload_strings(UBSEC_lib_error_code, UBSEC_str_functs); + ERR_unload_strings(UBSEC_lib_error_code, UBSEC_str_reasons); +#endif + +#ifdef UBSEC_LIB_NAME + ERR_unload_strings(0, UBSEC_lib_name); +#endif + UBSEC_error_init = 1; + } +} + +static void ERR_UBSEC_error(int function, int reason, char *file, int line) +{ + if (UBSEC_lib_error_code == 0) + UBSEC_lib_error_code = ERR_get_next_error_library(); + ERR_PUT_error(UBSEC_lib_error_code, function, reason, file, line); +} diff --git a/Sources/COpenSSL/e_ubsec_err.h b/Sources/COpenSSL/e_ubsec_err.h new file mode 100644 index 00000000..c8aec7c3 --- /dev/null +++ b/Sources/COpenSSL/e_ubsec_err.h @@ -0,0 +1,102 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UBSEC_ERR_H +# define HEADER_UBSEC_ERR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +static void ERR_load_UBSEC_strings(void); +static void ERR_unload_UBSEC_strings(void); +static void ERR_UBSEC_error(int function, int reason, char *file, int line); +# define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__) + +/* Error codes for the UBSEC functions. */ + +/* Function codes. */ +# define UBSEC_F_UBSEC_CTRL 100 +# define UBSEC_F_UBSEC_DH_COMPUTE_KEY 101 +# define UBSEC_F_UBSEC_DH_GENERATE_KEY 111 +# define UBSEC_F_UBSEC_DSA_DO_SIGN 102 +# define UBSEC_F_UBSEC_DSA_VERIFY 103 +# define UBSEC_F_UBSEC_FINISH 104 +# define UBSEC_F_UBSEC_INIT 105 +# define UBSEC_F_UBSEC_MOD_EXP 106 +# define UBSEC_F_UBSEC_MOD_EXP_CRT 110 +# define UBSEC_F_UBSEC_RAND_BYTES 107 +# define UBSEC_F_UBSEC_RSA_MOD_EXP 108 +# define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT 109 + +/* Reason codes. */ +# define UBSEC_R_ALREADY_LOADED 100 +# define UBSEC_R_BN_EXPAND_FAIL 101 +# define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED 102 +# define UBSEC_R_DSO_FAILURE 103 +# define UBSEC_R_MISSING_KEY_COMPONENTS 104 +# define UBSEC_R_NOT_LOADED 105 +# define UBSEC_R_REQUEST_FAILED 106 +# define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107 +# define UBSEC_R_UNIT_FAILURE 108 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/e_xcbc_d.c b/Sources/COpenSSL/e_xcbc_d.c new file mode 100644 index 00000000..61bb071a --- /dev/null +++ b/Sources/COpenSSL/e_xcbc_d.c @@ -0,0 +1,130 @@ +/* crypto/evp/e_xcbc_d.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_DES + +# include "evp.h" +# include "objects.h" +# include "evp_locl.h" +# include "des.h" + +static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + +typedef struct { + DES_key_schedule ks; /* key schedule */ + DES_cblock inw; + DES_cblock outw; +} DESX_CBC_KEY; + +# define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data) + +static const EVP_CIPHER d_xcbc_cipher = { + NID_desx_cbc, + 8, 24, 8, + EVP_CIPH_CBC_MODE, + desx_cbc_init_key, + desx_cbc_cipher, + NULL, + sizeof(DESX_CBC_KEY), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL, + NULL +}; + +const EVP_CIPHER *EVP_desx_cbc(void) +{ + return (&d_xcbc_cipher); +} + +static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + + DES_set_key_unchecked(deskey, &data(ctx)->ks); + memcpy(&data(ctx)->inw[0], &key[8], 8); + memcpy(&data(ctx)->outw[0], &key[16], 8); + + return 1; +} + +static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks, + (DES_cblock *)&(ctx->iv[0]), + &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks, + (DES_cblock *)&(ctx->iv[0]), + &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt); + return 1; +} +#endif diff --git a/Sources/COpenSSL/ebcdic.c b/Sources/COpenSSL/ebcdic.c new file mode 100644 index 00000000..ce7ab64e --- /dev/null +++ b/Sources/COpenSSL/ebcdic.c @@ -0,0 +1,284 @@ +/* crypto/ebcdic.c */ + +#ifndef CHARSET_EBCDIC + +# include "e_os2.h" +# if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) || defined(__clang__) +static void *dummy = &dummy; +# endif + +#else /* CHARSET_EBCDIC */ + +# include "ebcdic.h" +/*- + * Initial Port for Apache-1.3 by + * Adapted for OpenSSL-0.9.4 by + */ + +# ifdef _OSD_POSIX +/* + * "BS2000 OSD" is a POSIX subsystem on a main frame. It is made by Siemens + * AG, Germany, for their BS2000 mainframe machines. Within the POSIX + * subsystem, the same character set was chosen as in "native BS2000", namely + * EBCDIC. (EDF04) + * + * The name "ASCII" in these routines is misleading: actually, conversion is + * not between EBCDIC and ASCII, but EBCDIC(EDF04) and ISO-8859.1; that means + * that (western european) national characters are preserved. + * + * This table is identical to the one used by rsh/rcp/ftp and other POSIX + * tools. + */ + +/* Here's the bijective ebcdic-to-ascii table: */ +const unsigned char os_toascii[256] = { + /* + * 00 + */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, + 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + /* + * 10 + */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, + 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + /* + * 20 + */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */ + /* + * 30 + */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, + 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */ + /* + * 40 + */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, + 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+| */ + /* + * 50 + */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, + 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /* &.........!$*);. */ + /* + * 60 + */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, + 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/ + /* + * 70 + */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, + 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* ..........:#@'=" */ + /* + * 80 + */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */ + /* + * 90 + */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */ + /* + * a0 + */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /* ..stuvwxyz...... */ + /* + * b0 + */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, + 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /* ...........[\].. */ + /* + * c0 + */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* .ABCDEFGHI...... */ + /* + * d0 + */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /* .JKLMNOPQR...... */ + /* + * e0 + */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* ..STUVWXYZ...... */ + /* + * f0 + */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /* 0123456789.{.}.~ */ +}; + +/* The ascii-to-ebcdic table: */ +const unsigned char os_toebcdic[256] = { + /* + * 00 + */ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, + 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + /* + * 10 + */ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, + 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + /* + * 20 + */ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, + 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */ + /* + * 30 + */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */ + /* + * 40 + */ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */ + /* + * 50 + */ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, + 0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d, /* PQRSTUVWXYZ[\]^_ */ + /* + * 60 + */ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */ + /* + * 70 + */ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, + 0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07, /* pqrstuvwxyz{|}~. */ + /* + * 80 + */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */ + /* + * 90 + */ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, + 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f, /* ................ */ + /* + * a0 + */ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5, + 0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1, /* ................ */ + /* + * b0 + */ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, + 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */ + /* + * c0 + */ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */ + /* + * d0 + */ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, + 0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59, /* ................ */ + /* + * e0 + */ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */ + /* + * f0 + */ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, + 0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */ +}; + +# else /*_OSD_POSIX*/ + +/* + * This code does basic character mapping for IBM's TPF and OS/390 operating + * systems. It is a modified version of the BS2000 table. + * + * Bijective EBCDIC (character set IBM-1047) to US-ASCII table: This table is + * bijective - there are no ambigous or duplicate characters. + */ +const unsigned char os_toascii[256] = { + 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */ + 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */ + 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */ + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */ + 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */ + 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */ + 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */ + 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */ + 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */ + 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */ + 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */ + 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */ + 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */ + 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */ + 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */ + 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */ + 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */ + 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */ + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */ + 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */ + 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */ + 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */ + 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */ + 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */ + 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */ + 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */ + 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */ + 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */ +}; + +/* + * The US-ASCII to EBCDIC (character set IBM-1047) table: This table is + * bijective (no ambiguous or duplicate characters) + */ +const unsigned char os_toebcdic[256] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f: */ + 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f: */ + 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f: */ + 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f: */ + 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */ + 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f: */ + 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */ + 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f: */ + 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */ + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f: */ + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */ + 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f: */ + 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f: */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */ + 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f: */ + 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */ + 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af: */ + 0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */ + 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf: */ + 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */ + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf: */ + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */ + 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df: */ + 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */ + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef: */ + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */ + 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff: */ + 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */ +}; +# endif/*_OSD_POSIX*/ + +/* + * Translate a memory block from EBCDIC (host charset) to ASCII (net charset) + * dest and srce may be identical, or separate memory blocks, but should not + * overlap. These functions intentionally have an interface compatible to + * memcpy(3). + */ + +void *ebcdic2ascii(void *dest, const void *srce, size_t count) +{ + unsigned char *udest = dest; + const unsigned char *usrce = srce; + + while (count-- != 0) { + *udest++ = os_toascii[*usrce++]; + } + + return dest; +} + +void *ascii2ebcdic(void *dest, const void *srce, size_t count) +{ + unsigned char *udest = dest; + const unsigned char *usrce = srce; + + while (count-- != 0) { + *udest++ = os_toebcdic[*usrce++]; + } + + return dest; +} + +#endif diff --git a/Sources/COpenSSL/ebcdic.h b/Sources/COpenSSL/ebcdic.h new file mode 100644 index 00000000..4cbdfeb7 --- /dev/null +++ b/Sources/COpenSSL/ebcdic.h @@ -0,0 +1,26 @@ +/* crypto/ebcdic.h */ + +#ifndef HEADER_EBCDIC_H +# define HEADER_EBCDIC_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid name clashes with other applications */ +# define os_toascii _openssl_os_toascii +# define os_toebcdic _openssl_os_toebcdic +# define ebcdic2ascii _openssl_ebcdic2ascii +# define ascii2ebcdic _openssl_ascii2ebcdic + +extern const unsigned char os_toascii[256]; +extern const unsigned char os_toebcdic[256]; +void *ebcdic2ascii(void *dest, const void *srce, size_t count); +void *ascii2ebcdic(void *dest, const void *srce, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ec.h b/Sources/COpenSSL/ec.h new file mode 100644 index 00000000..e490c7aa --- /dev/null +++ b/Sources/COpenSSL/ec.h @@ -0,0 +1,1282 @@ +/* crypto/ec/ec.h */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/** + * \file crypto/ec/ec.h Include file for the OpenSSL EC functions + * \author Originally written by Bodo Moeller for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_EC_H +# define HEADER_EC_H + +# include "opensslconf.h" + +# ifdef OPENSSL_NO_EC +# error EC is disabled. +# endif + +# include "asn1.h" +# include "symhacks.h" +# ifndef OPENSSL_NO_DEPRECATED +# include "bn.h" +# endif + +# ifdef __cplusplus +extern "C" { +# elif defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif + +# ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +# endif + +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x04 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + +typedef struct ec_method_st EC_METHOD; + +typedef struct ec_group_st + /*- + EC_METHOD *meth; + -- field definition + -- curve coefficients + -- optional generator with associated information (order, cofactor) + -- optional extra data (precomputed table for fast computation of multiples of generator) + -- ASN1 stuff + */ + EC_GROUP; + +typedef struct ec_point_st EC_POINT; + +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nist_method(void); + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/** Returns 64-bit optimized methods for nistp224 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp224_method(void); + +/** Returns 64-bit optimized methods for nistp256 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp256_method(void); + +/** Returns 64-bit optimized methods for nistp521 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp521_method(void); +# endif + +# ifndef OPENSSL_NO_EC2M +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object + */ +const EC_METHOD *EC_GF2m_simple_method(void); + +# endif + +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ + +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); + +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); + +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); + +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and it's order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Returns the montgomery data for order(Generator) + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). +*/ +BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM with the prime number + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM for the prime number + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M +/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM for the polynomial defining the underlying field + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx); +# endif +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); + +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); + +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if both groups are equal and 1 otherwise + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +/* + * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after + * choosing an appropriate EC_METHOD + */ + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# endif +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +/* + * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all + * available curves or zero if a error occurred. In case r ist not zero + * nitems EC_builtin_curve structures are filled with the data of the first + * nitems internal groups + */ +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + +const char *EC_curve_nid2nist(int nid); +int EC_curve_nist2nid(const char *name); + +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); + +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *ctx); + +/** Sets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + int y_bit, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Sets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + int y_bit, BN_CTX *ctx); +# endif +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +/* other interfaces to point2oct/oct2point: */ +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if point if on the curve and 0 otherwise + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 0 if both points are equal and a value != 0 otherwise + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx); + +/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number futher summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + size_t num, const EC_POINT *p[], const BIGNUM *m[], + BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ + +/* + * EC_GROUP_get_basis_type() returns the NID of the basis type used to + * represent the field elements + */ +int EC_GROUP_get_basis_type(const EC_GROUP *); +# ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, + unsigned int *k2, unsigned int *k3); +# endif + +# define OPENSSL_EC_NAMED_CURVE 0x001 + +typedef struct ecpk_parameters_st ECPKPARAMETERS; + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +# ifndef OPENSSL_NO_BIO +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +# endif +# ifndef OPENSSL_NO_FP_API +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); +# endif + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + +typedef struct ec_key_st EC_KEY; + +/* some values for the encoding_flag */ +# define EC_PKEY_NO_PARAMETERS 0x001 +# define EC_PKEY_NO_PUBKEY 0x002 + +/* some values for the flags field */ +# define EC_FLAG_NON_FIPS_ALLOW 0x1 +# define EC_FLAG_FIPS_CHECKED 0x2 + +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new(void); + +int EC_KEY_get_flags(const EC_KEY *key); + +void EC_KEY_set_flags(EC_KEY *key, int flags); + +void EC_KEY_clear_flags(EC_KEY *key, int flags); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new_by_curve_name(int nid); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); +/* functions to set/get method specific data */ +void *EC_KEY_get_key_method_data(EC_KEY *key, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +/** Sets the key method data of an EC_KEY object, if none has yet been set. + * \param key EC_KEY object + * \param data opaque data to install. + * \param dup_func a function that duplicates |data|. + * \param free_func a function that frees |data|. + * \param clear_free_func a function that wipes and frees |data|. + * \return the previously set data pointer, or NULL if |data| was inserted. + */ +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +/* wrapper functions for the underlying EC_GROUP object */ +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + +/** Sets a public key from affine coordindates performing + * neccessary NIST PKV tests. + * \param key the EC_KEY object + * \param x public key x coordinate + * \param y public key y coordinate + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y); + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec paramters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(EC_KEY *key, unsigned char **out); + +# ifndef OPENSSL_NO_BIO +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + +# endif +# ifndef OPENSSL_NO_FP_API +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +# endif + +# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) + +# ifndef __cplusplus +# if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +# endif + +# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + +# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL) + +# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL) + +# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL) + +# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL) + +# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, (void *)plen) + +# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)p) + +# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ + EVP_PKEY_OP_DERIVE, \ + EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)p) + +# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5) +# define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) +# define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) +/* KDF types */ +# define EVP_PKEY_ECDH_KDF_NONE 1 +# define EVP_PKEY_ECDH_KDF_X9_62 2 + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EC_strings(void); + +/* Error codes for the EC functions. */ + +/* Function codes. */ +# define EC_F_BN_TO_FELEM 224 +# define EC_F_COMPUTE_WNAF 143 +# define EC_F_D2I_ECPARAMETERS 144 +# define EC_F_D2I_ECPKPARAMETERS 145 +# define EC_F_D2I_ECPRIVATEKEY 146 +# define EC_F_DO_EC_KEY_PRINT 221 +# define EC_F_ECDH_CMS_DECRYPT 238 +# define EC_F_ECDH_CMS_SET_SHARED_INFO 239 +# define EC_F_ECKEY_PARAM2TYPE 223 +# define EC_F_ECKEY_PARAM_DECODE 212 +# define EC_F_ECKEY_PRIV_DECODE 213 +# define EC_F_ECKEY_PRIV_ENCODE 214 +# define EC_F_ECKEY_PUB_DECODE 215 +# define EC_F_ECKEY_PUB_ENCODE 216 +# define EC_F_ECKEY_TYPE2PARAM 220 +# define EC_F_ECPARAMETERS_PRINT 147 +# define EC_F_ECPARAMETERS_PRINT_FP 148 +# define EC_F_ECPKPARAMETERS_PRINT 149 +# define EC_F_ECPKPARAMETERS_PRINT_FP 150 +# define EC_F_ECP_NISTZ256_GET_AFFINE 240 +# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE 243 +# define EC_F_ECP_NISTZ256_POINTS_MUL 241 +# define EC_F_ECP_NISTZ256_PRE_COMP_NEW 244 +# define EC_F_ECP_NISTZ256_SET_WORDS 245 +# define EC_F_ECP_NISTZ256_WINDOWED_MUL 242 +# define EC_F_ECP_NIST_MOD_192 203 +# define EC_F_ECP_NIST_MOD_224 204 +# define EC_F_ECP_NIST_MOD_256 205 +# define EC_F_ECP_NIST_MOD_521 206 +# define EC_F_EC_ASN1_GROUP2CURVE 153 +# define EC_F_EC_ASN1_GROUP2FIELDID 154 +# define EC_F_EC_ASN1_GROUP2PARAMETERS 155 +# define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156 +# define EC_F_EC_ASN1_PARAMETERS2GROUP 157 +# define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158 +# define EC_F_EC_EX_DATA_SET_DATA 211 +# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +# define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +# define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +# define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +# define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +# define EC_F_EC_GFP_MONT_FIELD_MUL 131 +# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +# define EC_F_EC_GFP_MONT_FIELD_SQR 132 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135 +# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 +# define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 +# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 +# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 +# define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 +# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 +# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 +# define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 +# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 +# define EC_F_EC_GFP_NIST_FIELD_MUL 200 +# define EC_F_EC_GFP_NIST_FIELD_SQR 201 +# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 +# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +# define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +# define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 +# define EC_F_EC_GROUP_CHECK 170 +# define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +# define EC_F_EC_GROUP_COPY 106 +# define EC_F_EC_GROUP_GET0_GENERATOR 139 +# define EC_F_EC_GROUP_GET_COFACTOR 140 +# define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +# define EC_F_EC_GROUP_GET_CURVE_GFP 130 +# define EC_F_EC_GROUP_GET_DEGREE 173 +# define EC_F_EC_GROUP_GET_ORDER 141 +# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +# define EC_F_EC_GROUP_NEW 108 +# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +# define EC_F_EC_GROUP_NEW_FROM_DATA 175 +# define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 +# define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +# define EC_F_EC_GROUP_SET_CURVE_GFP 109 +# define EC_F_EC_GROUP_SET_EXTRA_DATA 110 +# define EC_F_EC_GROUP_SET_GENERATOR 111 +# define EC_F_EC_KEY_CHECK_KEY 177 +# define EC_F_EC_KEY_COPY 178 +# define EC_F_EC_KEY_GENERATE_KEY 179 +# define EC_F_EC_KEY_NEW 182 +# define EC_F_EC_KEY_PRINT 180 +# define EC_F_EC_KEY_PRINT_FP 181 +# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 +# define EC_F_EC_POINTS_MAKE_AFFINE 136 +# define EC_F_EC_POINT_ADD 112 +# define EC_F_EC_POINT_CMP 113 +# define EC_F_EC_POINT_COPY 114 +# define EC_F_EC_POINT_DBL 115 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +# define EC_F_EC_POINT_INVERT 210 +# define EC_F_EC_POINT_IS_AT_INFINITY 118 +# define EC_F_EC_POINT_IS_ON_CURVE 119 +# define EC_F_EC_POINT_MAKE_AFFINE 120 +# define EC_F_EC_POINT_MUL 184 +# define EC_F_EC_POINT_NEW 121 +# define EC_F_EC_POINT_OCT2POINT 122 +# define EC_F_EC_POINT_POINT2OCT 123 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +# define EC_F_EC_POINT_SET_TO_INFINITY 127 +# define EC_F_EC_PRE_COMP_DUP 207 +# define EC_F_EC_PRE_COMP_NEW 196 +# define EC_F_EC_WNAF_MUL 187 +# define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +# define EC_F_I2D_ECPARAMETERS 190 +# define EC_F_I2D_ECPKPARAMETERS 191 +# define EC_F_I2D_ECPRIVATEKEY 192 +# define EC_F_I2O_ECPUBLICKEY 151 +# define EC_F_NISTP224_PRE_COMP_NEW 227 +# define EC_F_NISTP256_PRE_COMP_NEW 236 +# define EC_F_NISTP521_PRE_COMP_NEW 237 +# define EC_F_O2I_ECPUBLICKEY 152 +# define EC_F_OLD_EC_PRIV_DECODE 222 +# define EC_F_PKEY_EC_CTRL 197 +# define EC_F_PKEY_EC_CTRL_STR 198 +# define EC_F_PKEY_EC_DERIVE 217 +# define EC_F_PKEY_EC_KEYGEN 199 +# define EC_F_PKEY_EC_PARAMGEN 219 +# define EC_F_PKEY_EC_SIGN 218 + +/* Reason codes. */ +# define EC_R_ASN1_ERROR 115 +# define EC_R_ASN1_UNKNOWN_FIELD 116 +# define EC_R_BIGNUM_OUT_OF_RANGE 144 +# define EC_R_BUFFER_TOO_SMALL 100 +# define EC_R_COORDINATES_OUT_OF_RANGE 146 +# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +# define EC_R_DECODE_ERROR 142 +# define EC_R_DISCRIMINANT_IS_ZERO 118 +# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +# define EC_R_FIELD_TOO_LARGE 143 +# define EC_R_GF2M_NOT_SUPPORTED 147 +# define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +# define EC_R_INCOMPATIBLE_OBJECTS 101 +# define EC_R_INVALID_ARGUMENT 112 +# define EC_R_INVALID_COMPRESSED_POINT 110 +# define EC_R_INVALID_COMPRESSION_BIT 109 +# define EC_R_INVALID_CURVE 141 +# define EC_R_INVALID_DIGEST 151 +# define EC_R_INVALID_DIGEST_TYPE 138 +# define EC_R_INVALID_ENCODING 102 +# define EC_R_INVALID_FIELD 103 +# define EC_R_INVALID_FORM 104 +# define EC_R_INVALID_GROUP_ORDER 122 +# define EC_R_INVALID_PENTANOMIAL_BASIS 132 +# define EC_R_INVALID_PRIVATE_KEY 123 +# define EC_R_INVALID_TRINOMIAL_BASIS 137 +# define EC_R_KDF_PARAMETER_ERROR 148 +# define EC_R_KEYS_NOT_SET 140 +# define EC_R_MISSING_PARAMETERS 124 +# define EC_R_MISSING_PRIVATE_KEY 125 +# define EC_R_NOT_A_NIST_PRIME 135 +# define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136 +# define EC_R_NOT_IMPLEMENTED 126 +# define EC_R_NOT_INITIALIZED 111 +# define EC_R_NO_FIELD_MOD 133 +# define EC_R_NO_PARAMETERS_SET 139 +# define EC_R_PASSED_NULL_PARAMETER 134 +# define EC_R_PEER_KEY_ERROR 149 +# define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +# define EC_R_POINT_AT_INFINITY 106 +# define EC_R_POINT_IS_NOT_ON_CURVE 107 +# define EC_R_SHARED_INFO_ERROR 150 +# define EC_R_SLOT_FULL 108 +# define EC_R_UNDEFINED_GENERATOR 113 +# define EC_R_UNDEFINED_ORDER 128 +# define EC_R_UNKNOWN_GROUP 129 +# define EC_R_UNKNOWN_ORDER 114 +# define EC_R_UNSUPPORTED_FIELD 131 +# define EC_R_WRONG_CURVE_PARAMETERS 145 +# define EC_R_WRONG_ORDER 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ec2_.c b/Sources/COpenSSL/ec2_.c new file mode 100644 index 00000000..b289761b --- /dev/null +++ b/Sources/COpenSSL/ec2_.c @@ -0,0 +1,1666 @@ +/* crypto/ec/ec2_mult.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The software is originally written by Sheueling Chang Shantz and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "err.h" + +#include "ec_lcl.h" + +#ifndef OPENSSL_NO_EC2M + +/*- + * Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective + * coordinates. + * Uses algorithm Mdouble in appendix of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + * modified to not require precomputation of c=b^{2^{m-1}}. + */ +static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, + BN_CTX *ctx) +{ + BIGNUM *t1; + int ret = 0; + + /* Since Mdouble is static we can guarantee that ctx != NULL. */ + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + if (t1 == NULL) + goto err; + + if (!group->meth->field_sqr(group, x, x, ctx)) + goto err; + if (!group->meth->field_sqr(group, t1, z, ctx)) + goto err; + if (!group->meth->field_mul(group, z, x, t1, ctx)) + goto err; + if (!group->meth->field_sqr(group, x, x, ctx)) + goto err; + if (!group->meth->field_sqr(group, t1, t1, ctx)) + goto err; + if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) + goto err; + if (!BN_GF2m_add(x, x, t1)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +/*- + * Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery + * projective coordinates. + * Uses algorithm Madd in appendix of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + */ +static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, + BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2, + BN_CTX *ctx) +{ + BIGNUM *t1, *t2; + int ret = 0; + + /* Since Madd is static we can guarantee that ctx != NULL. */ + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t2 == NULL) + goto err; + + if (!BN_copy(t1, x)) + goto err; + if (!group->meth->field_mul(group, x1, x1, z2, ctx)) + goto err; + if (!group->meth->field_mul(group, z1, z1, x2, ctx)) + goto err; + if (!group->meth->field_mul(group, t2, x1, z1, ctx)) + goto err; + if (!BN_GF2m_add(z1, z1, x1)) + goto err; + if (!group->meth->field_sqr(group, z1, z1, ctx)) + goto err; + if (!group->meth->field_mul(group, x1, z1, t1, ctx)) + goto err; + if (!BN_GF2m_add(x1, x1, t2)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +/*- + * Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) + * using Montgomery point multiplication algorithm Mxy() in appendix of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + * Returns: + * 0 on error + * 1 if return value should be the point at infinity + * 2 otherwise + */ +static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, + BIGNUM *x1, BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, + BN_CTX *ctx) +{ + BIGNUM *t3, *t4, *t5; + int ret = 0; + + if (BN_is_zero(z1)) { + BN_zero(x2); + BN_zero(z2); + return 1; + } + + if (BN_is_zero(z2)) { + if (!BN_copy(x2, x)) + return 0; + if (!BN_GF2m_add(z2, x, y)) + return 0; + return 2; + } + + /* Since Mxy is static we can guarantee that ctx != NULL. */ + BN_CTX_start(ctx); + t3 = BN_CTX_get(ctx); + t4 = BN_CTX_get(ctx); + t5 = BN_CTX_get(ctx); + if (t5 == NULL) + goto err; + + if (!BN_one(t5)) + goto err; + + if (!group->meth->field_mul(group, t3, z1, z2, ctx)) + goto err; + + if (!group->meth->field_mul(group, z1, z1, x, ctx)) + goto err; + if (!BN_GF2m_add(z1, z1, x1)) + goto err; + if (!group->meth->field_mul(group, z2, z2, x, ctx)) + goto err; + if (!group->meth->field_mul(group, x1, z2, x1, ctx)) + goto err; + if (!BN_GF2m_add(z2, z2, x2)) + goto err; + + if (!group->meth->field_mul(group, z2, z2, z1, ctx)) + goto err; + if (!group->meth->field_sqr(group, t4, x, ctx)) + goto err; + if (!BN_GF2m_add(t4, t4, y)) + goto err; + if (!group->meth->field_mul(group, t4, t4, t3, ctx)) + goto err; + if (!BN_GF2m_add(t4, t4, z2)) + goto err; + + if (!group->meth->field_mul(group, t3, t3, x, ctx)) + goto err; + if (!group->meth->field_div(group, t3, t5, t3, ctx)) + goto err; + if (!group->meth->field_mul(group, t4, t3, t4, ctx)) + goto err; + if (!group->meth->field_mul(group, x2, x1, t3, ctx)) + goto err; + if (!BN_GF2m_add(z2, x2, x)) + goto err; + + if (!group->meth->field_mul(group, z2, z2, t4, ctx)) + goto err; + if (!BN_GF2m_add(z2, z2, y)) + goto err; + + ret = 2; + + err: + BN_CTX_end(ctx); + return ret; +} + +/*- + * Computes scalar*point and stores the result in r. + * point can not equal r. + * Uses a modified algorithm 2P of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + * + * To protect against side-channel attack the function uses constant time swap, + * avoiding conditional branches. + */ +static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, + EC_POINT *r, + const BIGNUM *scalar, + const EC_POINT *point, + BN_CTX *ctx) +{ + BIGNUM *x1, *x2, *z1, *z2; + int ret = 0, i, group_top; + BN_ULONG mask, word; + + if (r == point) { + ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT); + return 0; + } + + /* if result should be point at infinity */ + if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) || + EC_POINT_is_at_infinity(group, point)) { + return EC_POINT_set_to_infinity(group, r); + } + + /* only support affine coordinates */ + if (!point->Z_is_one) + return 0; + + /* + * Since point_multiply is static we can guarantee that ctx != NULL. + */ + BN_CTX_start(ctx); + x1 = BN_CTX_get(ctx); + z1 = BN_CTX_get(ctx); + if (z1 == NULL) + goto err; + + x2 = &r->X; + z2 = &r->Y; + + group_top = group->field.top; + if (bn_wexpand(x1, group_top) == NULL + || bn_wexpand(z1, group_top) == NULL + || bn_wexpand(x2, group_top) == NULL + || bn_wexpand(z2, group_top) == NULL) + goto err; + + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) + goto err; /* x1 = x */ + if (!BN_one(z1)) + goto err; /* z1 = 1 */ + if (!group->meth->field_sqr(group, z2, x1, ctx)) + goto err; /* z2 = x1^2 = x^2 */ + if (!group->meth->field_sqr(group, x2, z2, ctx)) + goto err; + if (!BN_GF2m_add(x2, x2, &group->b)) + goto err; /* x2 = x^4 + b */ + + /* find top most bit and go one past it */ + i = scalar->top - 1; + mask = BN_TBIT; + word = scalar->d[i]; + while (!(word & mask)) + mask >>= 1; + mask >>= 1; + /* if top most bit was at word break, go to next word */ + if (!mask) { + i--; + mask = BN_TBIT; + } + + for (; i >= 0; i--) { + word = scalar->d[i]; + while (mask) { + BN_consttime_swap(word & mask, x1, x2, group_top); + BN_consttime_swap(word & mask, z1, z2, group_top); + if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) + goto err; + if (!gf2m_Mdouble(group, x1, z1, ctx)) + goto err; + BN_consttime_swap(word & mask, x1, x2, group_top); + BN_consttime_swap(word & mask, z1, z2, group_top); + mask >>= 1; + } + mask = BN_TBIT; + } + + /* convert out of "projective" coordinates */ + i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx); + if (i == 0) + goto err; + else if (i == 1) { + if (!EC_POINT_set_to_infinity(group, r)) + goto err; + } else { + if (!BN_one(&r->Z)) + goto err; + r->Z_is_one = 1; + } + + /* GF(2^m) field elements should always have BIGNUM::neg = 0 */ + BN_set_negative(&r->X, 0); + BN_set_negative(&r->Y, 0); + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +/*- + * Computes the sum + * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1] + * gracefully ignoring NULL scalar values. + */ +int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + int ret = 0; + size_t i; + EC_POINT *p = NULL; + EC_POINT *acc = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + /* + * This implementation is more efficient than the wNAF implementation for + * 2 or fewer points. Use the ec_wNAF_mul implementation for 3 or more + * points, or if we can perform a fast multiplication based on + * precomputation. + */ + if ((scalar && (num > 1)) || (num > 2) + || (num == 0 && EC_GROUP_have_precompute_mult(group))) { + ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + goto err; + } + + if ((p = EC_POINT_new(group)) == NULL) + goto err; + if ((acc = EC_POINT_new(group)) == NULL) + goto err; + + if (!EC_POINT_set_to_infinity(group, acc)) + goto err; + + if (scalar) { + if (!ec_GF2m_montgomery_point_multiply + (group, p, scalar, group->generator, ctx)) + goto err; + if (BN_is_negative(scalar)) + if (!group->meth->invert(group, p, ctx)) + goto err; + if (!group->meth->add(group, acc, acc, p, ctx)) + goto err; + } + + for (i = 0; i < num; i++) { + if (!ec_GF2m_montgomery_point_multiply + (group, p, scalars[i], points[i], ctx)) + goto err; + if (BN_is_negative(scalars[i])) + if (!group->meth->invert(group, p, ctx)) + goto err; + if (!group->meth->add(group, acc, acc, p, ctx)) + goto err; + } + + if (!EC_POINT_copy(r, acc)) + goto err; + + ret = 1; + + err: + if (p) + EC_POINT_free(p); + if (acc) + EC_POINT_free(acc); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Precomputation for point multiplication: fall back to wNAF methods because + * ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate + */ + +int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + return ec_wNAF_precompute_mult(group, ctx); +} + +int ec_GF2m_have_precompute_mult(const EC_GROUP *group) +{ + return ec_wNAF_have_precompute_mult(group); +} + +#endif +/* crypto/ec/ec2_oct.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The software is originally written by Sheueling Chang Shantz and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "err.h" + +// #include "ec_lcl.h" + +#ifndef OPENSSL_NO_EC2M + +/*- + * Calculates and sets the affine coordinates of an EC_POINT from the given + * compressed coordinates. Uses algorithm 2.3.4 of SEC 1. + * Note that the simple implementation only uses affine coordinates. + * + * The method is from the following publication: + * + * Harper, Menezes, Vanstone: + * "Public-Key Cryptosystems with Very Small Key Lengths", + * EUROCRYPT '92, Springer-Verlag LNCS 658, + * published February 1993 + * + * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe + * the same method, but claim no priority date earlier than July 29, 1994 + * (and additionally fail to cite the EUROCRYPT '92 publication as prior art). + */ +int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x_, int y_bit, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *tmp, *x, *y, *z; + int ret = 0, z0; + + /* clear error queue */ + ERR_clear_error(); + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + y_bit = (y_bit != 0) ? 1 : 0; + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + z = BN_CTX_get(ctx); + if (z == NULL) + goto err; + + if (!BN_GF2m_mod_arr(x, x_, group->poly)) + goto err; + if (BN_is_zero(x)) { + if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) + goto err; + } else { + if (!group->meth->field_sqr(group, tmp, x, ctx)) + goto err; + if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) + goto err; + if (!BN_GF2m_add(tmp, &group->a, tmp)) + goto err; + if (!BN_GF2m_add(tmp, x, tmp)) + goto err; + if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) { + unsigned long err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_BN + && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) { + ERR_clear_error(); + ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, + EC_R_INVALID_COMPRESSED_POINT); + } else + ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, + ERR_R_BN_LIB); + goto err; + } + z0 = (BN_is_odd(z)) ? 1 : 0; + if (!group->meth->field_mul(group, y, x, z, ctx)) + goto err; + if (z0 != y_bit) { + if (!BN_GF2m_add(y, y, x)) + goto err; + } + } + + if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Converts an EC_POINT to an octet string. If buf is NULL, the encoded + * length will be returned. If the length len of buf is smaller than required + * an error will be returned. + */ +size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx) +{ + size_t ret; + BN_CTX *new_ctx = NULL; + int used_ctx = 0; + BIGNUM *x, *y, *yxi; + size_t field_len, i, skip; + + if ((form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); + goto err; + } + + if (EC_POINT_is_at_infinity(group, point)) { + /* encodes to a single 0 octet */ + if (buf != NULL) { + if (len < 1) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + return 0; + } + buf[0] = 0; + } + return 1; + } + + /* ret := required output buffer length */ + field_len = (EC_GROUP_get_degree(group) + 7) / 8; + ret = + (form == + POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + /* if 'buf' is NULL, just return required length */ + if (buf != NULL) { + if (len < ret) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + used_ctx = 1; + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + yxi = BN_CTX_get(ctx); + if (yxi == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) + goto err; + + buf[0] = form; + if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) { + if (!group->meth->field_div(group, yxi, y, x, ctx)) + goto err; + if (BN_is_odd(yxi)) + buf[0]++; + } + + i = 1; + + skip = field_len - BN_num_bytes(x); + if (skip > field_len) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(x, buf + i); + i += skip; + if (i != 1 + field_len) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (form == POINT_CONVERSION_UNCOMPRESSED + || form == POINT_CONVERSION_HYBRID) { + skip = field_len - BN_num_bytes(y); + if (skip > field_len) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(y, buf + i); + i += skip; + } + + if (i != ret) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (used_ctx) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; + + err: + if (used_ctx) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return 0; +} + +/* + * Converts an octet string representation to an EC_POINT. Note that the + * simple implementation only uses affine coordinates. + */ +int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, + BN_CTX *ctx) +{ + point_conversion_form_t form; + int y_bit; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y, *yxi; + size_t field_len, enc_len; + int ret = 0; + + if (len == 0) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); + return 0; + } + form = buf[0]; + y_bit = form & 1; + form = form & ~1U; + if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + if (form == 0) { + if (len != 1) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + return EC_POINT_set_to_infinity(group, point); + } + + field_len = (EC_GROUP_get_degree(group) + 7) / 8; + enc_len = + (form == + POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + if (len != enc_len) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + yxi = BN_CTX_get(ctx); + if (yxi == NULL) + goto err; + + if (!BN_bin2bn(buf + 1, field_len, x)) + goto err; + if (BN_ucmp(x, &group->field) >= 0) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + + if (form == POINT_CONVERSION_COMPRESSED) { + if (!EC_POINT_set_compressed_coordinates_GF2m + (group, point, x, y_bit, ctx)) + goto err; + } else { + if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) + goto err; + if (BN_ucmp(y, &group->field) >= 0) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + if (form == POINT_CONVERSION_HYBRID) { + if (!group->meth->field_div(group, yxi, y, x, ctx)) + goto err; + if (y_bit != BN_is_odd(yxi)) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + } + + if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) + goto err; + } + + /* test required by X9.62 */ + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} +#endif +/* crypto/ec/ec2_smpl.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The software is originally written by Sheueling Chang Shantz and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "err.h" + +// #include "ec_lcl.h" + +#ifndef OPENSSL_NO_EC2M + +# ifdef OPENSSL_FIPS +# include +# endif + +const EC_METHOD *EC_GF2m_simple_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_characteristic_two_field, + ec_GF2m_simple_group_init, + ec_GF2m_simple_group_finish, + ec_GF2m_simple_group_clear_finish, + ec_GF2m_simple_group_copy, + ec_GF2m_simple_group_set_curve, + ec_GF2m_simple_group_get_curve, + ec_GF2m_simple_group_get_degree, + ec_GF2m_simple_group_check_discriminant, + ec_GF2m_simple_point_init, + ec_GF2m_simple_point_finish, + ec_GF2m_simple_point_clear_finish, + ec_GF2m_simple_point_copy, + ec_GF2m_simple_point_set_to_infinity, + 0 /* set_Jprojective_coordinates_GFp */ , + 0 /* get_Jprojective_coordinates_GFp */ , + ec_GF2m_simple_point_set_affine_coordinates, + ec_GF2m_simple_point_get_affine_coordinates, + 0, 0, 0, + ec_GF2m_simple_add, + ec_GF2m_simple_dbl, + ec_GF2m_simple_invert, + ec_GF2m_simple_is_at_infinity, + ec_GF2m_simple_is_on_curve, + ec_GF2m_simple_cmp, + ec_GF2m_simple_make_affine, + ec_GF2m_simple_points_make_affine, + + /* + * the following three method functions are defined in ec2_mult.c + */ + ec_GF2m_simple_mul, + ec_GF2m_precompute_mult, + ec_GF2m_have_precompute_mult, + + ec_GF2m_simple_field_mul, + ec_GF2m_simple_field_sqr, + ec_GF2m_simple_field_div, + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + +# ifdef OPENSSL_FIPS + if (FIPS_mode()) + return fips_ec_gf2m_simple_method(); +# endif + + return &ret; +} + +/* + * Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members + * are handled by EC_GROUP_new. + */ +int ec_GF2m_simple_group_init(EC_GROUP *group) +{ + BN_init(&group->field); + BN_init(&group->a); + BN_init(&group->b); + return 1; +} + +/* + * Free a GF(2^m)-based EC_GROUP structure. Note that all other members are + * handled by EC_GROUP_free. + */ +void ec_GF2m_simple_group_finish(EC_GROUP *group) +{ + BN_free(&group->field); + BN_free(&group->a); + BN_free(&group->b); +} + +/* + * Clear and free a GF(2^m)-based EC_GROUP structure. Note that all other + * members are handled by EC_GROUP_clear_free. + */ +void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) +{ + BN_clear_free(&group->field); + BN_clear_free(&group->a); + BN_clear_free(&group->b); + group->poly[0] = 0; + group->poly[1] = 0; + group->poly[2] = 0; + group->poly[3] = 0; + group->poly[4] = 0; + group->poly[5] = -1; +} + +/* + * Copy a GF(2^m)-based EC_GROUP structure. Note that all other members are + * handled by EC_GROUP_copy. + */ +int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + int i; + if (!BN_copy(&dest->field, &src->field)) + return 0; + if (!BN_copy(&dest->a, &src->a)) + return 0; + if (!BN_copy(&dest->b, &src->b)) + return 0; + dest->poly[0] = src->poly[0]; + dest->poly[1] = src->poly[1]; + dest->poly[2] = src->poly[2]; + dest->poly[3] = src->poly[3]; + dest->poly[4] = src->poly[4]; + dest->poly[5] = src->poly[5]; + if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) + == NULL) + return 0; + if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) + == NULL) + return 0; + for (i = dest->a.top; i < dest->a.dmax; i++) + dest->a.d[i] = 0; + for (i = dest->b.top; i < dest->b.dmax; i++) + dest->b.d[i] = 0; + return 1; +} + +/* Set the curve parameters of an EC_GROUP structure. */ +int ec_GF2m_simple_group_set_curve(EC_GROUP *group, + const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0, i; + + /* group->field */ + if (!BN_copy(&group->field, p)) + goto err; + i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1; + if ((i != 5) && (i != 3)) { + ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); + goto err; + } + + /* group->a */ + if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) + goto err; + if (bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) + == NULL) + goto err; + for (i = group->a.top; i < group->a.dmax; i++) + group->a.d[i] = 0; + + /* group->b */ + if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) + goto err; + if (bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) + == NULL) + goto err; + for (i = group->b.top; i < group->b.dmax; i++) + group->b.d[i] = 0; + + ret = 1; + err: + return ret; +} + +/* + * Get the curve parameters of an EC_GROUP structure. If p, a, or b are NULL + * then there values will not be set but the method will return with success. + */ +int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + + if (p != NULL) { + if (!BN_copy(p, &group->field)) + return 0; + } + + if (a != NULL) { + if (!BN_copy(a, &group->a)) + goto err; + } + + if (b != NULL) { + if (!BN_copy(b, &group->b)) + goto err; + } + + ret = 1; + + err: + return ret; +} + +/* + * Gets the degree of the field. For a curve over GF(2^m) this is the value + * m. + */ +int ec_GF2m_simple_group_get_degree(const EC_GROUP *group) +{ + return BN_num_bits(&group->field) - 1; +} + +/* + * Checks the discriminant of the curve. y^2 + x*y = x^3 + a*x^2 + b is an + * elliptic curve <=> b != 0 (mod p) + */ +int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, + BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *b; + BN_CTX *new_ctx = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, + ERR_R_MALLOC_FAILURE); + goto err; + } + } + BN_CTX_start(ctx); + b = BN_CTX_get(ctx); + if (b == NULL) + goto err; + + if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) + goto err; + + /* + * check the discriminant: y^2 + x*y = x^3 + a*x^2 + b is an elliptic + * curve <=> b != 0 (mod p) + */ + if (BN_is_zero(b)) + goto err; + + ret = 1; + + err: + if (ctx != NULL) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* Initializes an EC_POINT. */ +int ec_GF2m_simple_point_init(EC_POINT *point) +{ + BN_init(&point->X); + BN_init(&point->Y); + BN_init(&point->Z); + return 1; +} + +/* Frees an EC_POINT. */ +void ec_GF2m_simple_point_finish(EC_POINT *point) +{ + BN_free(&point->X); + BN_free(&point->Y); + BN_free(&point->Z); +} + +/* Clears and frees an EC_POINT. */ +void ec_GF2m_simple_point_clear_finish(EC_POINT *point) +{ + BN_clear_free(&point->X); + BN_clear_free(&point->Y); + BN_clear_free(&point->Z); + point->Z_is_one = 0; +} + +/* + * Copy the contents of one EC_POINT into another. Assumes dest is + * initialized. + */ +int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) +{ + if (!BN_copy(&dest->X, &src->X)) + return 0; + if (!BN_copy(&dest->Y, &src->Y)) + return 0; + if (!BN_copy(&dest->Z, &src->Z)) + return 0; + dest->Z_is_one = src->Z_is_one; + + return 1; +} + +/* + * Set an EC_POINT to the point at infinity. A point at infinity is + * represented by having Z=0. + */ +int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, + EC_POINT *point) +{ + point->Z_is_one = 0; + BN_zero(&point->Z); + return 1; +} + +/* + * Set the coordinates of an EC_POINT using affine coordinates. Note that + * the simple implementation only uses affine coordinates. + */ +int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + int ret = 0; + if (x == NULL || y == NULL) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!BN_copy(&point->X, x)) + goto err; + BN_set_negative(&point->X, 0); + if (!BN_copy(&point->Y, y)) + goto err; + BN_set_negative(&point->Y, 0); + if (!BN_copy(&point->Z, BN_value_one())) + goto err; + BN_set_negative(&point->Z, 0); + point->Z_is_one = 1; + ret = 1; + + err: + return ret; +} + +/* + * Gets the affine coordinates of an EC_POINT. Note that the simple + * implementation only uses affine coordinates. + */ +int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + int ret = 0; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + + if (BN_cmp(&point->Z, BN_value_one())) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (x != NULL) { + if (!BN_copy(x, &point->X)) + goto err; + BN_set_negative(x, 0); + } + if (y != NULL) { + if (!BN_copy(y, &point->Y)) + goto err; + BN_set_negative(y, 0); + } + ret = 1; + + err: + return ret; +} + +/* + * Computes a + b and stores the result in r. r could be a or b, a could be + * b. Uses algorithm A.10.2 of IEEE P1363. + */ +int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; + int ret = 0; + + if (EC_POINT_is_at_infinity(group, a)) { + if (!EC_POINT_copy(r, b)) + return 0; + return 1; + } + + if (EC_POINT_is_at_infinity(group, b)) { + if (!EC_POINT_copy(r, a)) + return 0; + return 1; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x0 = BN_CTX_get(ctx); + y0 = BN_CTX_get(ctx); + x1 = BN_CTX_get(ctx); + y1 = BN_CTX_get(ctx); + x2 = BN_CTX_get(ctx); + y2 = BN_CTX_get(ctx); + s = BN_CTX_get(ctx); + t = BN_CTX_get(ctx); + if (t == NULL) + goto err; + + if (a->Z_is_one) { + if (!BN_copy(x0, &a->X)) + goto err; + if (!BN_copy(y0, &a->Y)) + goto err; + } else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) + goto err; + } + if (b->Z_is_one) { + if (!BN_copy(x1, &b->X)) + goto err; + if (!BN_copy(y1, &b->Y)) + goto err; + } else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) + goto err; + } + + if (BN_GF2m_cmp(x0, x1)) { + if (!BN_GF2m_add(t, x0, x1)) + goto err; + if (!BN_GF2m_add(s, y0, y1)) + goto err; + if (!group->meth->field_div(group, s, s, t, ctx)) + goto err; + if (!group->meth->field_sqr(group, x2, s, ctx)) + goto err; + if (!BN_GF2m_add(x2, x2, &group->a)) + goto err; + if (!BN_GF2m_add(x2, x2, s)) + goto err; + if (!BN_GF2m_add(x2, x2, t)) + goto err; + } else { + if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) { + if (!EC_POINT_set_to_infinity(group, r)) + goto err; + ret = 1; + goto err; + } + if (!group->meth->field_div(group, s, y1, x1, ctx)) + goto err; + if (!BN_GF2m_add(s, s, x1)) + goto err; + + if (!group->meth->field_sqr(group, x2, s, ctx)) + goto err; + if (!BN_GF2m_add(x2, x2, s)) + goto err; + if (!BN_GF2m_add(x2, x2, &group->a)) + goto err; + } + + if (!BN_GF2m_add(y2, x1, x2)) + goto err; + if (!group->meth->field_mul(group, y2, y2, s, ctx)) + goto err; + if (!BN_GF2m_add(y2, y2, x2)) + goto err; + if (!BN_GF2m_add(y2, y2, y1)) + goto err; + + if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Computes 2 * a and stores the result in r. r could be a. Uses algorithm + * A.10.2 of IEEE P1363. + */ +int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx) +{ + return ec_GF2m_simple_add(group, r, a, a, ctx); +} + +int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +{ + if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) + /* point is its own inverse */ + return 1; + + if (!EC_POINT_make_affine(group, point, ctx)) + return 0; + return BN_GF2m_add(&point->Y, &point->X, &point->Y); +} + +/* Indicates whether the given point is the point at infinity. */ +int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, + const EC_POINT *point) +{ + return BN_is_zero(&point->Z); +} + +/*- + * Determines whether the given EC_POINT is an actual point on the curve defined + * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation: + * y^2 + x*y = x^3 + a*x^2 + b. + */ +int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) +{ + int ret = -1; + BN_CTX *new_ctx = NULL; + BIGNUM *lh, *y2; + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + + if (EC_POINT_is_at_infinity(group, point)) + return 1; + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + + /* only support affine coordinates */ + if (!point->Z_is_one) + return -1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return -1; + } + + BN_CTX_start(ctx); + y2 = BN_CTX_get(ctx); + lh = BN_CTX_get(ctx); + if (lh == NULL) + goto err; + + /*- + * We have a curve defined by a Weierstrass equation + * y^2 + x*y = x^3 + a*x^2 + b. + * <=> x^3 + a*x^2 + x*y + b + y^2 = 0 + * <=> ((x + a) * x + y ) * x + b + y^2 = 0 + */ + if (!BN_GF2m_add(lh, &point->X, &group->a)) + goto err; + if (!field_mul(group, lh, lh, &point->X, ctx)) + goto err; + if (!BN_GF2m_add(lh, lh, &point->Y)) + goto err; + if (!field_mul(group, lh, lh, &point->X, ctx)) + goto err; + if (!BN_GF2m_add(lh, lh, &group->b)) + goto err; + if (!field_sqr(group, y2, &point->Y, ctx)) + goto err; + if (!BN_GF2m_add(lh, lh, y2)) + goto err; + ret = BN_is_zero(lh); + err: + if (ctx) + BN_CTX_end(ctx); + if (new_ctx) + BN_CTX_free(new_ctx); + return ret; +} + +/*- + * Indicates whether two points are equal. + * Return values: + * -1 error + * 0 equal (in affine coordinates) + * 1 not equal + */ +int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + BIGNUM *aX, *aY, *bX, *bY; + BN_CTX *new_ctx = NULL; + int ret = -1; + + if (EC_POINT_is_at_infinity(group, a)) { + return EC_POINT_is_at_infinity(group, b) ? 0 : 1; + } + + if (EC_POINT_is_at_infinity(group, b)) + return 1; + + if (a->Z_is_one && b->Z_is_one) { + return ((BN_cmp(&a->X, &b->X) == 0) + && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return -1; + } + + BN_CTX_start(ctx); + aX = BN_CTX_get(ctx); + aY = BN_CTX_get(ctx); + bX = BN_CTX_get(ctx); + bY = BN_CTX_get(ctx); + if (bY == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) + goto err; + if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) + goto err; + ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1; + + err: + if (ctx) + BN_CTX_end(ctx); + if (new_ctx) + BN_CTX_free(new_ctx); + return ret; +} + +/* Forces the given EC_POINT to internally use affine coordinates. */ +int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + int ret = 0; + + if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) + return 1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) + goto err; + if (!BN_copy(&point->X, x)) + goto err; + if (!BN_copy(&point->Y, y)) + goto err; + if (!BN_one(&point->Z)) + goto err; + point->Z_is_one = 1; + + ret = 1; + + err: + if (ctx) + BN_CTX_end(ctx); + if (new_ctx) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Forces each of the EC_POINTs in the given array to use affine coordinates. + */ +int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx) +{ + size_t i; + + for (i = 0; i < num; i++) { + if (!group->meth->make_affine(group, points[i], ctx)) + return 0; + } + + return 1; +} + +/* Wrapper to simple binary polynomial field multiplication implementation. */ +int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx); +} + +/* Wrapper to simple binary polynomial field squaring implementation. */ +int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) +{ + return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx); +} + +/* Wrapper to simple binary polynomial field division implementation. */ +int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + return BN_GF2m_mod_div(r, a, b, &group->field, ctx); +} + +#endif diff --git a/Sources/COpenSSL/ec_.c b/Sources/COpenSSL/ec_.c new file mode 100644 index 00000000..f1e6243f --- /dev/null +++ b/Sources/COpenSSL/ec_.c @@ -0,0 +1,9961 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "x509.h" +#include "ec.h" +#include "bn.h" +#ifndef OPENSSL_NO_CMS +# include "cms.h" +#endif +#include "asn1t.h" +#include "asn1_locl.h" +#include "ec_lcl.h" + +#ifndef OPENSSL_NO_CMS +static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); +static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); +#endif + +static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) +{ + const EC_GROUP *group; + int nid; + if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { + ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); + return 0; + } + if (EC_GROUP_get_asn1_flag(group) + && (nid = EC_GROUP_get_curve_name(group))) + /* we have a 'named curve' => just set the OID */ + { + *ppval = OBJ_nid2obj(nid); + *pptype = V_ASN1_OBJECT; + } else { /* explicit parameters */ + + ASN1_STRING *pstr = NULL; + pstr = ASN1_STRING_new(); + if (!pstr) + return 0; + pstr->length = i2d_ECParameters(ec_key, &pstr->data); + if (pstr->length <= 0) { + ASN1_STRING_free(pstr); + ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); + return 0; + } + *ppval = pstr; + *pptype = V_ASN1_SEQUENCE; + } + return 1; +} + +static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + EC_KEY *ec_key = pkey->pkey.ec; + void *pval = NULL; + int ptype; + unsigned char *penc = NULL, *p; + int penclen; + + if (!eckey_param2type(&ptype, &pval, ec_key)) { + ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); + return 0; + } + penclen = i2o_ECPublicKey(ec_key, NULL); + if (penclen <= 0) + goto err; + penc = OPENSSL_malloc(penclen); + if (!penc) + goto err; + p = penc; + penclen = i2o_ECPublicKey(ec_key, &p); + if (penclen <= 0) + goto err; + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), + ptype, pval, penc, penclen)) + return 1; + err: + if (ptype == V_ASN1_OBJECT) + ASN1_OBJECT_free(pval); + else + ASN1_STRING_free(pval); + if (penc) + OPENSSL_free(penc); + return 0; +} + +static EC_KEY *eckey_type2param(int ptype, void *pval) +{ + EC_KEY *eckey = NULL; + EC_GROUP *group = NULL; + + if (ptype == V_ASN1_SEQUENCE) { + const ASN1_STRING *pstr = pval; + const unsigned char *pm = pstr->data; + int pmlen = pstr->length; + + if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) { + ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); + goto ecerr; + } + } else if (ptype == V_ASN1_OBJECT) { + const ASN1_OBJECT *poid = pval; + + /* + * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID + */ + if ((eckey = EC_KEY_new()) == NULL) { + ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); + goto ecerr; + } + group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); + if (group == NULL) + goto ecerr; + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(eckey, group) == 0) + goto ecerr; + EC_GROUP_free(group); + } else { + ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); + goto ecerr; + } + + return eckey; + + ecerr: + EC_KEY_free(eckey); + EC_GROUP_free(group); + return NULL; +} + +static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p = NULL; + void *pval; + int ptype, pklen; + EC_KEY *eckey = NULL; + X509_ALGOR *palg; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + eckey = eckey_type2param(ptype, pval); + + if (!eckey) { + ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); + return 0; + } + + /* We have parameters now set public key */ + if (!o2i_ECPublicKey(&eckey, &p, pklen)) { + ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); + goto ecerr; + } + + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; + + ecerr: + if (eckey) + EC_KEY_free(eckey); + return 0; +} + +static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + int r; + const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); + const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), + *pb = EC_KEY_get0_public_key(b->pkey.ec); + if (group == NULL || pa == NULL || pb == NULL) + return -2; + r = EC_POINT_cmp(group, pa, pb, NULL); + if (r == 0) + return 1; + if (r == 1) + return 0; + return -2; +} + +static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p = NULL; + void *pval; + int ptype, pklen; + EC_KEY *eckey = NULL; + X509_ALGOR *palg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + eckey = eckey_type2param(ptype, pval); + + if (!eckey) + goto ecliberr; + + /* We have parameters now set private key */ + if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { + ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); + goto ecerr; + } + + /* calculate public key (if necessary) */ + if (EC_KEY_get0_public_key(eckey) == NULL) { + const BIGNUM *priv_key; + const EC_GROUP *group; + EC_POINT *pub_key; + /* + * the public key was not included in the SEC1 private key => + * calculate the public key + */ + group = EC_KEY_get0_group(eckey); + pub_key = EC_POINT_new(group); + if (pub_key == NULL) { + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { + EC_POINT_free(pub_key); + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + priv_key = EC_KEY_get0_private_key(eckey); + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { + EC_POINT_free(pub_key); + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + if (EC_KEY_set_public_key(eckey, pub_key) == 0) { + EC_POINT_free(pub_key); + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + EC_POINT_free(pub_key); + } + + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; + + ecliberr: + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + ecerr: + if (eckey) + EC_KEY_free(eckey); + return 0; +} + +static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + EC_KEY ec_key = *(pkey->pkey.ec); + unsigned char *ep, *p; + int eplen, ptype; + void *pval; + unsigned int old_flags; + + if (!eckey_param2type(&ptype, &pval, &ec_key)) { + ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); + return 0; + } + + /* set the private key */ + + /* + * do not include the parameters in the SEC1 private key see PKCS#11 + * 12.11 + */ + old_flags = EC_KEY_get_enc_flags(&ec_key); + EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS); + + eplen = i2d_ECPrivateKey(&ec_key, NULL); + if (!eplen) { + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); + return 0; + } + ep = (unsigned char *)OPENSSL_malloc(eplen); + if (!ep) { + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + return 0; + } + p = ep; + if (!i2d_ECPrivateKey(&ec_key, &p)) { + OPENSSL_free(ep); + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); + return 0; + } + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, + ptype, pval, ep, eplen)) { + OPENSSL_free(ep); + return 0; + } + + return 1; +} + +static int int_ec_size(const EVP_PKEY *pkey) +{ + return ECDSA_size(pkey->pkey.ec); +} + +static int ec_bits(const EVP_PKEY *pkey) +{ + BIGNUM *order = BN_new(); + const EC_GROUP *group; + int ret; + + if (!order) { + ERR_clear_error(); + return 0; + } + group = EC_KEY_get0_group(pkey->pkey.ec); + if (!EC_GROUP_get_order(group, order, NULL)) { + ERR_clear_error(); + return 0; + } + + ret = BN_num_bits(order); + BN_free(order); + return ret; +} + +static int ec_missing_parameters(const EVP_PKEY *pkey) +{ + if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL) + return 1; + return 0; +} + +static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); + if (group == NULL) + return 0; + if (EC_KEY_set_group(to->pkey.ec, group) == 0) + return 0; + EC_GROUP_free(group); + return 1; +} + +static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), + *group_b = EC_KEY_get0_group(b->pkey.ec); + if (group_a == NULL || group_b == NULL) + return -2; + if (EC_GROUP_cmp(group_a, group_b, NULL)) + return 0; + else + return 1; +} + +static void int_ec_free(EVP_PKEY *pkey) +{ + EC_KEY_free(pkey->pkey.ec); +} + +static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) +{ + unsigned char *buffer = NULL; + const char *ecstr; + size_t buf_len = 0, i; + int ret = 0, reason = ERR_R_BIO_LIB; + BIGNUM *pub_key = NULL, *order = NULL; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + const BIGNUM *priv_key; + + if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (ktype > 0) { + public_key = EC_KEY_get0_public_key(x); + if (public_key != NULL) { + if ((pub_key = EC_POINT_point2bn(group, public_key, + EC_KEY_get_conv_form(x), NULL, + ctx)) == NULL) { + reason = ERR_R_EC_LIB; + goto err; + } + buf_len = (size_t)BN_num_bytes(pub_key); + } + } + + if (ktype == 2) { + priv_key = EC_KEY_get0_private_key(x); + if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) + buf_len = i; + } else + priv_key = NULL; + + if (ktype > 0) { + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + } + if (ktype == 2) + ecstr = "Private-Key"; + else if (ktype == 1) + ecstr = "Public-Key"; + else + ecstr = "ECDSA-Parameters"; + + if (!BIO_indent(bp, off, 128)) + goto err; + if ((order = BN_new()) == NULL) + goto err; + if (!EC_GROUP_get_order(group, order, NULL)) + goto err; + if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) + goto err; + + if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, + buffer, off)) + goto err; + if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, + buffer, off)) + goto err; + if (!ECPKParameters_print(bp, group, off)) + goto err; + ret = 1; + err: + if (!ret) + ECerr(EC_F_DO_EC_KEY_PRINT, reason); + if (pub_key) + BN_free(pub_key); + if (order) + BN_free(order); + if (ctx) + BN_CTX_free(ctx); + if (buffer != NULL) + OPENSSL_free(buffer); + return (ret); +} + +static int eckey_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + EC_KEY *eckey; + if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { + ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; +} + +static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_ECParameters(pkey->pkey.ec, pder); +} + +static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); +} + +static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); +} + +static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); +} + +static int old_ec_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + EC_KEY *ec; + if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { + ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, ec); + return 1; +} + +static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_ECPrivateKey(pkey->pkey.ec, pder); +} + +static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (arg1 == 1) + return ecdh_cms_decrypt(arg2); + else if (arg1 == 0) + return ecdh_cms_encrypt(arg2); + return -2; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: + *(int *)arg2 = CMS_RECIPINFO_AGREE; + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha256; + return 2; + + default: + return -2; + + } + +} + +const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { + EVP_PKEY_EC, + EVP_PKEY_EC, + 0, + "EC", + "OpenSSL EC algorithm", + + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, + eckey_pub_print, + + eckey_priv_decode, + eckey_priv_encode, + eckey_priv_print, + + int_ec_size, + ec_bits, + + eckey_param_decode, + eckey_param_encode, + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, + eckey_param_print, + 0, + + int_ec_free, + ec_pkey_ctrl, + old_ec_priv_decode, + old_ec_priv_encode +}; + +#ifndef OPENSSL_NO_CMS + +static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, + X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) +{ + ASN1_OBJECT *aoid; + int atype; + void *aval; + int rv = 0; + EVP_PKEY *pkpeer = NULL; + EC_KEY *ecpeer = NULL; + const unsigned char *p; + int plen; + X509_ALGOR_get0(&aoid, &atype, &aval, alg); + if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) + goto err; + /* If absent parameters get group from main key */ + if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { + const EC_GROUP *grp; + EVP_PKEY *pk; + pk = EVP_PKEY_CTX_get0_pkey(pctx); + if (!pk) + goto err; + grp = EC_KEY_get0_group(pk->pkey.ec); + ecpeer = EC_KEY_new(); + if (!ecpeer) + goto err; + if (!EC_KEY_set_group(ecpeer, grp)) + goto err; + } else { + ecpeer = eckey_type2param(atype, aval); + if (!ecpeer) + goto err; + } + /* We have parameters now set public key */ + plen = ASN1_STRING_length(pubkey); + p = ASN1_STRING_data(pubkey); + if (!p || !plen) + goto err; + if (!o2i_ECPublicKey(&ecpeer, &p, plen)) + goto err; + pkpeer = EVP_PKEY_new(); + if (!pkpeer) + goto err; + EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer); + if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) + rv = 1; + err: + if (ecpeer) + EC_KEY_free(ecpeer); + if (pkpeer) + EVP_PKEY_free(pkpeer); + return rv; +} + +/* Set KDF parameters based on KDF NID */ +static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) +{ + int kdf_nid, kdfmd_nid, cofactor; + const EVP_MD *kdf_md; + if (eckdf_nid == NID_undef) + return 0; + + /* Lookup KDF type, cofactor mode and digest */ + if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid)) + return 0; + + if (kdf_nid == NID_dh_std_kdf) + cofactor = 0; + else if (kdf_nid == NID_dh_cofactor_kdf) + cofactor = 1; + else + return 0; + + if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) + return 0; + + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0) + return 0; + + kdf_md = EVP_get_digestbynid(kdfmd_nid); + if (!kdf_md) + return 0; + + if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) + return 0; + return 1; +} + +static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) +{ + int rv = 0; + + X509_ALGOR *alg, *kekalg = NULL; + ASN1_OCTET_STRING *ukm; + const unsigned char *p; + unsigned char *der = NULL; + int plen, keylen; + const EVP_CIPHER *kekcipher; + EVP_CIPHER_CTX *kekctx; + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) + return 0; + + if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { + ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR); + return 0; + } + + if (alg->parameter->type != V_ASN1_SEQUENCE) + return 0; + + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + if (!kekalg) + goto err; + kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); + if (!kekctx) + goto err; + kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) + goto err; + if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) + goto err; + if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) + goto err; + + keylen = EVP_CIPHER_CTX_key_length(kekctx); + if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); + + if (!plen) + goto err; + + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) + goto err; + der = NULL; + + rv = 1; + err: + if (kekalg) + X509_ALGOR_free(kekalg); + if (der) + OPENSSL_free(der); + return rv; +} + +static int ecdh_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (!pctx) + return 0; + /* See if we need to set peer key */ + if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { + X509_ALGOR *alg; + ASN1_BIT_STRING *pubkey; + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, + NULL, NULL, NULL)) + return 0; + if (!alg || !pubkey) + return 0; + if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { + ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR); + return 0; + } + } + /* Set ECDH derivation parameters and initialise unwrap context */ + if (!ecdh_cms_set_shared_info(pctx, ri)) { + ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR); + return 0; + } + return 1; +} + +static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pctx; + EVP_PKEY *pkey; + EVP_CIPHER_CTX *ctx; + int keylen; + X509_ALGOR *talg, *wrap_alg = NULL; + ASN1_OBJECT *aoid; + ASN1_BIT_STRING *pubkey; + ASN1_STRING *wrap_str; + ASN1_OCTET_STRING *ukm; + unsigned char *penc = NULL; + int penclen; + int rv = 0; + int ecdh_nid, kdf_type, kdf_nid, wrap_nid; + const EVP_MD *kdf_md; + pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (!pctx) + return 0; + /* Get ephemeral key */ + pkey = EVP_PKEY_CTX_get0_pkey(pctx); + if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, + NULL, NULL, NULL)) + goto err; + X509_ALGOR_get0(&aoid, NULL, NULL, talg); + /* Is everything uninitialised? */ + if (aoid == OBJ_nid2obj(NID_undef)) { + + EC_KEY *eckey = pkey->pkey.ec; + /* Set the key */ + unsigned char *p; + + penclen = i2o_ECPublicKey(eckey, NULL); + if (penclen <= 0) + goto err; + penc = OPENSSL_malloc(penclen); + if (!penc) + goto err; + p = penc; + penclen = i2o_ECPublicKey(eckey, &p); + if (penclen <= 0) + goto err; + ASN1_STRING_set0(pubkey, penc, penclen); + pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), + V_ASN1_UNDEF, NULL); + } + + /* See if custom paraneters set */ + kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); + if (kdf_type <= 0) + goto err; + if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md)) + goto err; + ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); + if (ecdh_nid < 0) + goto err; + else if (ecdh_nid == 0) + ecdh_nid = NID_dh_std_kdf; + else if (ecdh_nid == 1) + ecdh_nid = NID_dh_cofactor_kdf; + + if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { + kdf_type = EVP_PKEY_ECDH_KDF_X9_62; + if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) + goto err; + } else + /* Uknown KDF */ + goto err; + if (kdf_md == NULL) { + /* Fixme later for better MD */ + kdf_md = EVP_sha1(); + if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) + goto err; + } + + if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) + goto err; + + /* Lookup NID for KDF+cofactor+digest */ + + if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid)) + goto err; + /* Get wrap NID */ + ctx = CMS_RecipientInfo_kari_get0_ctx(ri); + wrap_nid = EVP_CIPHER_CTX_type(ctx); + keylen = EVP_CIPHER_CTX_key_length(ctx); + + /* Package wrap algorithm in an AlgorithmIdentifier */ + + wrap_alg = X509_ALGOR_new(); + if (!wrap_alg) + goto err; + wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); + wrap_alg->parameter = ASN1_TYPE_new(); + if (!wrap_alg->parameter) + goto err; + if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) + goto err; + if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { + ASN1_TYPE_free(wrap_alg->parameter); + wrap_alg->parameter = NULL; + } + + if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) + goto err; + + penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); + + if (!penclen) + goto err; + + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) + goto err; + penc = NULL; + + /* + * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter + * of another AlgorithmIdentifier. + */ + penclen = i2d_X509_ALGOR(wrap_alg, &penc); + if (!penc || !penclen) + goto err; + wrap_str = ASN1_STRING_new(); + if (!wrap_str) + goto err; + ASN1_STRING_set0(wrap_str, penc, penclen); + penc = NULL; + X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); + + rv = 1; + + err: + if (penc) + OPENSSL_free(penc); + if (wrap_alg) + X509_ALGOR_free(wrap_alg); + return rv; +} + +#endif +/* crypto/ec/ec_asn1.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "ec_lcl.h" +#include "err.h" +// #include "asn1t.h" +#include "objects.h" + +#define OSSL_NELEM(x) (sizeof(x)/sizeof(x[0])) + +int EC_GROUP_get_basis_type(const EC_GROUP *group) +{ + int i; + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_characteristic_two_field) + /* everything else is currently not supported */ + return 0; + + /* Find the last non-zero element of group->poly[] */ + for (i = 0; + i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; + i++) + continue; + + if (i == 4) + return NID_X9_62_ppBasis; + else if (i == 2) + return NID_X9_62_tpBasis; + else + /* everything else is currently not supported */ + return 0; +} + +#ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) +{ + if (group == NULL) + return 0; + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_characteristic_two_field + || !((group->poly[0] != 0) && (group->poly[1] != 0) + && (group->poly[2] == 0))) { + ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (k) + *k = group->poly[1]; + + return 1; +} + +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, + unsigned int *k2, unsigned int *k3) +{ + if (group == NULL) + return 0; + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_characteristic_two_field + || !((group->poly[0] != 0) && (group->poly[1] != 0) + && (group->poly[2] != 0) && (group->poly[3] != 0) + && (group->poly[4] == 0))) { + ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (k1) + *k1 = group->poly[3]; + if (k2) + *k2 = group->poly[2]; + if (k3) + *k3 = group->poly[1]; + + return 1; +} +#endif + +/* some structures needed for the asn1 encoding */ +typedef struct x9_62_pentanomial_st { + long k1; + long k2; + long k3; +} X9_62_PENTANOMIAL; + +typedef struct x9_62_characteristic_two_st { + long m; + ASN1_OBJECT *type; + union { + char *ptr; + /* NID_X9_62_onBasis */ + ASN1_NULL *onBasis; + /* NID_X9_62_tpBasis */ + ASN1_INTEGER *tpBasis; + /* NID_X9_62_ppBasis */ + X9_62_PENTANOMIAL *ppBasis; + /* anything else */ + ASN1_TYPE *other; + } p; +} X9_62_CHARACTERISTIC_TWO; + +typedef struct x9_62_fieldid_st { + ASN1_OBJECT *fieldType; + union { + char *ptr; + /* NID_X9_62_prime_field */ + ASN1_INTEGER *prime; + /* NID_X9_62_characteristic_two_field */ + X9_62_CHARACTERISTIC_TWO *char_two; + /* anything else */ + ASN1_TYPE *other; + } p; +} X9_62_FIELDID; + +typedef struct x9_62_curve_st { + ASN1_OCTET_STRING *a; + ASN1_OCTET_STRING *b; + ASN1_BIT_STRING *seed; +} X9_62_CURVE; + +typedef struct ec_parameters_st { + long version; + X9_62_FIELDID *fieldID; + X9_62_CURVE *curve; + ASN1_OCTET_STRING *base; + ASN1_INTEGER *order; + ASN1_INTEGER *cofactor; +} ECPARAMETERS; + +struct ecpk_parameters_st { + int type; + union { + ASN1_OBJECT *named_curve; + ECPARAMETERS *parameters; + ASN1_NULL *implicitlyCA; + } value; +} /* ECPKPARAMETERS */ ; + +/* SEC1 ECPrivateKey */ +typedef struct ec_privatekey_st { + long version; + ASN1_OCTET_STRING *privateKey; + ECPKPARAMETERS *parameters; + ASN1_BIT_STRING *publicKey; +} EC_PRIVATEKEY; + +/* the OpenSSL ASN.1 definitions */ +ASN1_SEQUENCE(X9_62_PENTANOMIAL) = { + ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG), + ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG), + ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG) +} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL) + +DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) + +ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY); + +ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = { + ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), + ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), + ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL)) +} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL); + +ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = { + ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG), + ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO) +} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO) + +DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) + +ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); + +ASN1_ADB(X9_62_FIELDID) = { + ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), + ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO)) +} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); + +ASN1_SEQUENCE(X9_62_FIELDID) = { + ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), + ASN1_ADB_OBJECT(X9_62_FIELDID) +} ASN1_SEQUENCE_END(X9_62_FIELDID) + +ASN1_SEQUENCE(X9_62_CURVE) = { + ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), + ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), + ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(X9_62_CURVE) + +ASN1_SEQUENCE(ECPARAMETERS) = { + ASN1_SIMPLE(ECPARAMETERS, version, LONG), + ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), + ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), + ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), + ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), + ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) +} ASN1_SEQUENCE_END(ECPARAMETERS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) + +ASN1_CHOICE(ECPKPARAMETERS) = { + ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), + ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), + ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) +} ASN1_CHOICE_END(ECPKPARAMETERS) + +DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS) +IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS) + +ASN1_SEQUENCE(EC_PRIVATEKEY) = { + ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), + ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), + ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), + ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) +} ASN1_SEQUENCE_END(EC_PRIVATEKEY) + +DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY) +IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) + +/* some declarations of internal function */ + +/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ +static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); +/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ +static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); +/* + * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS + * object + */ +static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); +/* + * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP + * object + */ +static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, + ECPARAMETERS *); +/* + * ec_asn1_pkparameters2group() creates a EC_GROUP object from a + * ECPKPARAMETERS object + */ +static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); +/* + * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a + * EC_GROUP object + */ +static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, + ECPKPARAMETERS *); + +/* the function definitions */ + +static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) +{ + int ok = 0, nid; + BIGNUM *tmp = NULL; + + if (group == NULL || field == NULL) + return 0; + + /* clear the old values (if necessary) */ + if (field->fieldType != NULL) + ASN1_OBJECT_free(field->fieldType); + if (field->p.other != NULL) + ASN1_TYPE_free(field->p.other); + + nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + /* set OID for the field */ + if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); + goto err; + } + + if (nid == NID_X9_62_prime_field) { + if ((tmp = BN_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + /* the parameters are specified by the prime number p */ + if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); + goto err; + } + /* set the prime number */ + field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); + if (field->p.prime == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); + goto err; + } + } else /* nid == NID_X9_62_characteristic_two_field */ +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED); + goto err; + } +#else + { + int field_type; + X9_62_CHARACTERISTIC_TWO *char_two; + + field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); + char_two = field->p.char_two; + + if (char_two == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + + char_two->m = (long)EC_GROUP_get_degree(group); + + field_type = EC_GROUP_get_basis_type(group); + + if (field_type == 0) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); + goto err; + } + /* set base type OID */ + if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); + goto err; + } + + if (field_type == NID_X9_62_tpBasis) { + unsigned int k; + + if (!EC_GROUP_get_trinomial_basis(group, &k)) + goto err; + + char_two->p.tpBasis = ASN1_INTEGER_new(); + if (!char_two->p.tpBasis) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); + goto err; + } + } else if (field_type == NID_X9_62_ppBasis) { + unsigned int k1, k2, k3; + + if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) + goto err; + + char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); + if (!char_two->p.ppBasis) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* set k? values */ + char_two->p.ppBasis->k1 = (long)k1; + char_two->p.ppBasis->k2 = (long)k2; + char_two->p.ppBasis->k3 = (long)k3; + } else { /* field_type == NID_X9_62_onBasis */ + + /* for ONB the parameters are (asn1) NULL */ + char_two->p.onBasis = ASN1_NULL_new(); + if (!char_two->p.onBasis) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + } + } +#endif + + ok = 1; + + err:if (tmp) + BN_free(tmp); + return (ok); +} + +static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) +{ + int ok = 0, nid; + BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; + unsigned char *buffer_1 = NULL, *buffer_2 = NULL, + *a_buf = NULL, *b_buf = NULL; + size_t len_1, len_2; + unsigned char char_zero = 0; + + if (!group || !curve || !curve->a || !curve->b) + return 0; + + if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + + nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + + /* get a and b */ + if (nid == NID_X9_62_prime_field) { + if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* nid == NID_X9_62_characteristic_two_field */ + + if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); + goto err; + } + } +#endif + len_1 = (size_t)BN_num_bytes(tmp_1); + len_2 = (size_t)BN_num_bytes(tmp_2); + + if (len_1 == 0) { + /* len_1 == 0 => a == 0 */ + a_buf = &char_zero; + len_1 = 1; + } else { + if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); + goto err; + } + a_buf = buffer_1; + } + + if (len_2 == 0) { + /* len_2 == 0 => b == 0 */ + b_buf = &char_zero; + len_2 = 1; + } else { + if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); + goto err; + } + b_buf = buffer_2; + } + + /* set a and b */ + if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) || + !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); + goto err; + } + + /* set the seed (optional) */ + if (group->seed) { + if (!curve->seed) + if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (!ASN1_BIT_STRING_set(curve->seed, group->seed, + (int)group->seed_len)) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); + goto err; + } + } else { + if (curve->seed) { + ASN1_BIT_STRING_free(curve->seed); + curve->seed = NULL; + } + } + + ok = 1; + + err:if (buffer_1) + OPENSSL_free(buffer_1); + if (buffer_2) + OPENSSL_free(buffer_2); + if (tmp_1) + BN_free(tmp_1); + if (tmp_2) + BN_free(tmp_2); + return (ok); +} + +static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, + ECPARAMETERS *param) +{ + int ok = 0; + size_t len = 0; + ECPARAMETERS *ret = NULL; + BIGNUM *tmp = NULL; + unsigned char *buffer = NULL; + const EC_POINT *point = NULL; + point_conversion_form_t form; + + if ((tmp = BN_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (param == NULL) { + if ((ret = ECPARAMETERS_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = param; + + /* set the version (always one) */ + ret->version = (long)0x1; + + /* set the fieldID */ + if (!ec_asn1_group2fieldid(group, ret->fieldID)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + + /* set the curve */ + if (!ec_asn1_group2curve(group, ret->curve)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + + /* set the base point */ + if ((point = EC_GROUP_get0_generator(group)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR); + goto err; + } + + form = EC_GROUP_get_point_conversion_form(group); + + len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); + if (len == 0) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + if ((buffer = OPENSSL_malloc(len)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); + goto err; + } + + /* set the order */ + if (!EC_GROUP_get_order(group, tmp, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); + if (ret->order == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); + goto err; + } + + /* set the cofactor (optional) */ + if (EC_GROUP_get_cofactor(group, tmp, NULL)) { + ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); + if (ret->cofactor == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); + goto err; + } + } + + ok = 1; + + err:if (!ok) { + if (ret && !param) + ECPARAMETERS_free(ret); + ret = NULL; + } + if (tmp) + BN_free(tmp); + if (buffer) + OPENSSL_free(buffer); + return (ret); +} + +ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, + ECPKPARAMETERS *params) +{ + int ok = 1, tmp; + ECPKPARAMETERS *ret = params; + + if (ret == NULL) { + if ((ret = ECPKPARAMETERS_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE); + return NULL; + } + } else { + if (ret->type == 0 && ret->value.named_curve) + ASN1_OBJECT_free(ret->value.named_curve); + else if (ret->type == 1 && ret->value.parameters) + ECPARAMETERS_free(ret->value.parameters); + } + + if (EC_GROUP_get_asn1_flag(group)) { + /* + * use the asn1 OID to describe the the elliptic curve parameters + */ + tmp = EC_GROUP_get_curve_name(group); + if (tmp) { + ret->type = 0; + if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) + ok = 0; + } else + /* we don't kmow the nid => ERROR */ + ok = 0; + } else { + /* use the ECPARAMETERS structure */ + ret->type = 1; + if ((ret->value.parameters = + ec_asn1_group2parameters(group, NULL)) == NULL) + ok = 0; + } + + if (!ok) { + ECPKPARAMETERS_free(ret); + return NULL; + } + return ret; +} + +static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) +{ + int ok = 0, tmp; + EC_GROUP *ret = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL; + EC_POINT *point = NULL; + long field_bits; + + if (!params->fieldID || !params->fieldID->fieldType || + !params->fieldID->p.ptr) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + /* now extract the curve parameters a and b */ + if (!params->curve || !params->curve->a || + !params->curve->a->data || !params->curve->b || + !params->curve->b->data) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); + if (a == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); + goto err; + } + b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); + if (b == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); + goto err; + } + + /* get the field parameters */ + tmp = OBJ_obj2nid(params->fieldID->fieldType); + if (tmp == NID_X9_62_characteristic_two_field) +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED); + goto err; + } +#else + { + X9_62_CHARACTERISTIC_TWO *char_two; + + char_two = params->fieldID->p.char_two; + + field_bits = char_two->m; + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); + goto err; + } + + if ((p = BN_new()) == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* get the base type */ + tmp = OBJ_obj2nid(char_two->type); + + if (tmp == NID_X9_62_tpBasis) { + long tmp_long; + + if (!char_two->p.tpBasis) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); + + if (!(char_two->m > tmp_long && tmp_long > 0)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, + EC_R_INVALID_TRINOMIAL_BASIS); + goto err; + } + + /* create the polynomial */ + if (!BN_set_bit(p, (int)char_two->m)) + goto err; + if (!BN_set_bit(p, (int)tmp_long)) + goto err; + if (!BN_set_bit(p, 0)) + goto err; + } else if (tmp == NID_X9_62_ppBasis) { + X9_62_PENTANOMIAL *penta; + + penta = char_two->p.ppBasis; + if (!penta) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + if (! + (char_two->m > penta->k3 && penta->k3 > penta->k2 + && penta->k2 > penta->k1 && penta->k1 > 0)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, + EC_R_INVALID_PENTANOMIAL_BASIS); + goto err; + } + + /* create the polynomial */ + if (!BN_set_bit(p, (int)char_two->m)) + goto err; + if (!BN_set_bit(p, (int)penta->k1)) + goto err; + if (!BN_set_bit(p, (int)penta->k2)) + goto err; + if (!BN_set_bit(p, (int)penta->k3)) + goto err; + if (!BN_set_bit(p, 0)) + goto err; + } else if (tmp == NID_X9_62_onBasis) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED); + goto err; + } else { /* error */ + + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + /* create the EC_GROUP structure */ + ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); + } +#endif + else if (tmp == NID_X9_62_prime_field) { + /* we have a curve over a prime field */ + /* extract the prime number */ + if (!params->fieldID->p.prime) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); + if (p == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); + goto err; + } + + if (BN_is_negative(p) || BN_is_zero(p)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); + goto err; + } + + field_bits = BN_num_bits(p); + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); + goto err; + } + + /* create the EC_GROUP structure */ + ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); + } else { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); + goto err; + } + + if (ret == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); + goto err; + } + + /* extract seed (optional) */ + if (params->curve->seed != NULL) { + if (ret->seed != NULL) + OPENSSL_free(ret->seed); + if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(ret->seed, params->curve->seed->data, + params->curve->seed->length); + ret->seed_len = params->curve->seed->length; + } + + if (!params->order || !params->base || !params->base->data) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + if ((point = EC_POINT_new(ret)) == NULL) + goto err; + + /* set the point conversion form */ + EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) + (params->base->data[0] & ~0x01)); + + /* extract the ec point */ + if (!EC_POINT_oct2point(ret, point, params->base->data, + params->base->length, NULL)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); + goto err; + } + + /* extract the order */ + if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); + goto err; + } + if (BN_is_negative(a) || BN_is_zero(a)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); + goto err; + } + if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */ + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + /* extract the cofactor (optional) */ + if (params->cofactor == NULL) { + if (b) { + BN_free(b); + b = NULL; + } + } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); + goto err; + } + /* set the generator, order and cofactor (if present) */ + if (!EC_GROUP_set_generator(ret, point, a, b)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); + goto err; + } + + ok = 1; + + err:if (!ok) { + if (ret) + EC_GROUP_clear_free(ret); + ret = NULL; + } + + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (point) + EC_POINT_free(point); + return (ret); +} + +EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) +{ + EC_GROUP *ret = NULL; + int tmp = 0; + + if (params == NULL) { + ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS); + return NULL; + } + + if (params->type == 0) { /* the curve is given by an OID */ + tmp = OBJ_obj2nid(params->value.named_curve); + if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { + ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, + EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); + return NULL; + } + EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); + } else if (params->type == 1) { /* the parameters are given by a + * ECPARAMETERS structure */ + ret = ec_asn1_parameters2group(params->value.parameters); + if (!ret) { + ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB); + return NULL; + } + EC_GROUP_set_asn1_flag(ret, 0x0); + } else if (params->type == 2) { /* implicitlyCA */ + return NULL; + } else { + ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR); + return NULL; + } + + return ret; +} + +/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) +{ + EC_GROUP *group = NULL; + ECPKPARAMETERS *params = NULL; + const unsigned char *p = *in; + + if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) { + ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); + ECPKPARAMETERS_free(params); + return NULL; + } + + if ((group = ec_asn1_pkparameters2group(params)) == NULL) { + ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); + ECPKPARAMETERS_free(params); + return NULL; + } + + if (a && *a) + EC_GROUP_clear_free(*a); + if (a) + *a = group; + + ECPKPARAMETERS_free(params); + *in = p; + return (group); +} + +int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) +{ + int ret = 0; + ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); + if (tmp == NULL) { + ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); + return 0; + } + if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { + ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); + ECPKPARAMETERS_free(tmp); + return 0; + } + ECPKPARAMETERS_free(tmp); + return (ret); +} + +/* some EC_KEY functions */ + +EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) +{ + int ok = 0; + EC_KEY *ret = NULL; + EC_PRIVATEKEY *priv_key = NULL; + const unsigned char *p = *in; + + if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + return NULL; + } + + if (a == NULL || *a == NULL) { + if ((ret = EC_KEY_new()) == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = *a; + + if (priv_key->parameters) { + if (ret->group) + EC_GROUP_clear_free(ret->group); + ret->group = ec_asn1_pkparameters2group(priv_key->parameters); + } + + if (ret->group == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + + ret->version = priv_key->version; + + if (priv_key->privateKey) { + ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey), + M_ASN1_STRING_length(priv_key->privateKey), + ret->priv_key); + if (ret->priv_key == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB); + goto err; + } + } else { + ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY); + goto err; + } + + if (ret->pub_key) + EC_POINT_clear_free(ret->pub_key); + ret->pub_key = EC_POINT_new(ret->group); + if (ret->pub_key == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + + if (priv_key->publicKey) { + const unsigned char *pub_oct; + int pub_oct_len; + + pub_oct = M_ASN1_STRING_data(priv_key->publicKey); + pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); + /* + * The first byte - point conversion form - must be present. + */ + if (pub_oct_len <= 0) { + ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); + goto err; + } + /* Save the point conversion form. */ + ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); + if (!EC_POINT_oct2point(ret->group, ret->pub_key, + pub_oct, (size_t)(pub_oct_len), NULL)) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + } else { + if (!EC_POINT_mul + (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + /* Remember the original private-key-only encoding. */ + ret->enc_flag |= EC_PKEY_NO_PUBKEY; + } + + if (a) + *a = ret; + *in = p; + ok = 1; + err: + if (!ok) { + if (ret && (a == NULL || *a != ret)) + EC_KEY_free(ret); + ret = NULL; + } + + if (priv_key) + EC_PRIVATEKEY_free(priv_key); + + return (ret); +} + +int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) +{ + int ret = 0, ok = 0; + unsigned char *buffer = NULL; + size_t buf_len = 0, tmp_len, bn_len; + EC_PRIVATEKEY *priv_key = NULL; + + if (a == NULL || a->group == NULL || a->priv_key == NULL || + (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + priv_key->version = a->version; + + bn_len = (size_t)BN_num_bytes(a->priv_key); + + /* Octetstring may need leading zeros if BN is to short */ + + buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8; + + if (bn_len > buf_len) { + ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + buffer = OPENSSL_malloc(buf_len); + if (buffer == NULL) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); + goto err; + } + + if (buf_len - bn_len > 0) { + memset(buffer, 0, buf_len - bn_len); + } + + if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); + goto err; + } + + if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { + if ((priv_key->parameters = + ec_asn1_group2pkparameters(a->group, + priv_key->parameters)) == NULL) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + } + + if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { + priv_key->publicKey = M_ASN1_BIT_STRING_new(); + if (priv_key->publicKey == NULL) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + tmp_len = EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, NULL, 0, NULL); + + if (tmp_len > buf_len) { + unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); + if (!tmp_buffer) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + buffer = tmp_buffer; + buf_len = tmp_len; + } + + if (!EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, buffer, buf_len, NULL)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + + priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); + goto err; + } + } + + if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + ok = 1; + err: + if (buffer) + OPENSSL_free(buffer); + if (priv_key) + EC_PRIVATEKEY_free(priv_key); + return (ok ? ret : 0); +} + +int i2d_ECParameters(EC_KEY *a, unsigned char **out) +{ + if (a == NULL) { + ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return i2d_ECPKParameters(a->group, out); +} + +EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) +{ + EC_KEY *ret; + + if (in == NULL || *in == NULL) { + ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (a == NULL || *a == NULL) { + if ((ret = EC_KEY_new()) == NULL) { + ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); + return NULL; + } + } else + ret = *a; + + if (!d2i_ECPKParameters(&ret->group, in, len)) { + ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); + if (a == NULL || *a != ret) + EC_KEY_free(ret); + return NULL; + } + + if (a) + *a = ret; + + return ret; +} + +EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) +{ + EC_KEY *ret = NULL; + + if (a == NULL || (*a) == NULL || (*a)->group == NULL) { + /* + * sorry, but a EC_GROUP-structur is necessary to set the public key + */ + ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ret = *a; + if (ret->pub_key == NULL && + (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { + ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { + ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); + return 0; + } + /* save the point conversion form */ + ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01); + *in += len; + return ret; +} + +int i2o_ECPublicKey(EC_KEY *a, unsigned char **out) +{ + size_t buf_len = 0; + int new_buffer = 0; + + if (a == NULL) { + ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + buf_len = EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, NULL, 0, NULL); + + if (out == NULL || buf_len == 0) + /* out == NULL => just return the length of the octet string */ + return buf_len; + + if (*out == NULL) { + if ((*out = OPENSSL_malloc(buf_len)) == NULL) { + ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + new_buffer = 1; + } + if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, + *out, buf_len, NULL)) { + ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); + if (new_buffer) { + OPENSSL_free(*out); + *out = NULL; + } + return 0; + } + if (!new_buffer) + *out += buf_len; + return buf_len; +} +/* crypto/ec/ec_check.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ec_lcl.h" +// #include "err.h" + +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *order; + BN_CTX *new_ctx = NULL; + EC_POINT *point = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE); + goto err; + } + } + BN_CTX_start(ctx); + if ((order = BN_CTX_get(ctx)) == NULL) + goto err; + + /* check the discriminant */ + if (!EC_GROUP_check_discriminant(group, ctx)) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO); + goto err; + } + + /* check the generator */ + if (group->generator == NULL) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR); + goto err; + } + if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + /* check the order of the generator */ + if ((point = EC_POINT_new(group)) == NULL) + goto err; + if (!EC_GROUP_get_order(group, order, ctx)) + goto err; + if (BN_is_zero(order)) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER); + goto err; + } + + if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) + goto err; + if (!EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + ret = 1; + + err: + if (ctx != NULL) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (point) + EC_POINT_free(point); + return ret; +} +/* crypto/ec/ec_curve.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +// #include "ec_lcl.h" +// #include "err.h" +// #include "obj_mac.h" +#include "opensslconf.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +typedef struct { + int field_type, /* either NID_X9_62_prime_field or + * NID_X9_62_characteristic_two_field */ + seed_len, param_len; + unsigned int cofactor; /* promoted to BN_ULONG */ +} EC_CURVE_DATA; + +/* the nist prime curves */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_NIST_PRIME_192 = { + { + NID_X9_62_prime_field, 20, 24, 1 + }, + { + /* seed */ + 0x30, 0x45, 0xAE, 0x6F, 0xC8, 0x42, 0x2F, 0x64, 0xED, 0x57, 0x95, 0x28, + 0xD3, 0x81, 0x20, 0xEA, 0xE1, 0x21, 0x96, 0xD5, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB, + 0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1, + /* x */ + 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB, + 0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12, + /* y */ + 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed, + 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 28 * 6]; +} _EC_NIST_PRIME_224 = { + { + NID_X9_62_prime_field, 20, 28, 1 + }, + { + /* seed */ + 0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45, 0xB5, 0x9F, + 0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, + /* b */ + 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, + 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, + 0x23, 0x55, 0xFF, 0xB4, + /* x */ + 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, + 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, + 0x11, 0x5C, 0x1D, 0x21, + /* y */ + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, + 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, + 0x85, 0x00, 0x7e, 0x34, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, + 0x5C, 0x5C, 0x2A, 0x3D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 48 * 6]; +} _EC_NIST_PRIME_384 = { + { + NID_X9_62_prime_field, 20, 48, 1 + }, + { + /* seed */ + 0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, 0x89, 0x6A, + 0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF, + /* x */ + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, + /* y */ + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, + 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, + 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, + 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 66 * 6]; +} _EC_NIST_PRIME_521 = { + { + NID_X9_62_prime_field, 20, 66, 1 + }, + { + /* seed */ + 0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, 0x67, 0x17, + 0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA, + /* p */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, + 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, + 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, + 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00, + /* x */ + 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, + /* y */ + 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, + 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, + 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, + 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, + 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, + 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, + /* order */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, + 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, + 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 + } +}; + +/* the x9.62 prime curves (minus the nist prime curves) */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_PRIME_192V2 = { + { + NID_X9_62_prime_field, 20, 24, 1 + }, + { + /* seed */ + 0x31, 0xA9, 0x2E, 0xE2, 0x02, 0x9F, 0xD1, 0x0D, 0x90, 0x1B, 0x11, 0x3E, + 0x99, 0x07, 0x10, 0xF0, 0xD2, 0x1A, 0xC6, 0xB6, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0xCC, 0x22, 0xD6, 0xDF, 0xB9, 0x5C, 0x6B, 0x25, 0xE4, 0x9C, 0x0D, 0x63, + 0x64, 0xA4, 0xE5, 0x98, 0x0C, 0x39, 0x3A, 0xA2, 0x16, 0x68, 0xD9, 0x53, + /* x */ + 0xEE, 0xA2, 0xBA, 0xE7, 0xE1, 0x49, 0x78, 0x42, 0xF2, 0xDE, 0x77, 0x69, + 0xCF, 0xE9, 0xC9, 0x89, 0xC0, 0x72, 0xAD, 0x69, 0x6F, 0x48, 0x03, 0x4A, + /* y */ + 0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b, 0xb8, 0x2a, + 0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9, 0x70, 0xb2, 0xde, 0x15, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x5F, 0xB1, 0xA7, 0x24, 0xDC, 0x80, 0x41, 0x86, 0x48, 0xD8, 0xDD, 0x31 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_PRIME_192V3 = { + { + NID_X9_62_prime_field, 20, 24, 1 + }, + { + /* seed */ + 0xC4, 0x69, 0x68, 0x44, 0x35, 0xDE, 0xB3, 0x78, 0xC4, 0xB6, 0x5C, 0xA9, + 0x59, 0x1E, 0x2A, 0x57, 0x63, 0x05, 0x9A, 0x2E, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x22, 0x12, 0x3D, 0xC2, 0x39, 0x5A, 0x05, 0xCA, 0xA7, 0x42, 0x3D, 0xAE, + 0xCC, 0xC9, 0x47, 0x60, 0xA7, 0xD4, 0x62, 0x25, 0x6B, 0xD5, 0x69, 0x16, + /* x */ + 0x7D, 0x29, 0x77, 0x81, 0x00, 0xC6, 0x5A, 0x1D, 0xA1, 0x78, 0x37, 0x16, + 0x58, 0x8D, 0xCE, 0x2B, 0x8B, 0x4A, 0xEE, 0x8E, 0x22, 0x8F, 0x18, 0x96, + /* y */ + 0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49, 0xdc, 0xb6, + 0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76, 0x48, 0xa9, 0x43, 0xb0, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7A, 0x62, 0xD0, 0x31, 0xC8, 0x3F, 0x42, 0x94, 0xF6, 0x40, 0xEC, 0x13 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_PRIME_239V1 = { + { + NID_X9_62_prime_field, 20, 30, 1 + }, + { + /* seed */ + 0xE4, 0x3B, 0xB4, 0x60, 0xF0, 0xB8, 0x0C, 0xC0, 0xC0, 0xB0, 0x75, 0x79, + 0x8E, 0x94, 0x80, 0x60, 0xF8, 0x32, 0x1B, 0x7D, + /* p */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x6B, 0x01, 0x6C, 0x3B, 0xDC, 0xF1, 0x89, 0x41, 0xD0, 0xD6, 0x54, 0x92, + 0x14, 0x75, 0xCA, 0x71, 0xA9, 0xDB, 0x2F, 0xB2, 0x7D, 0x1D, 0x37, 0x79, + 0x61, 0x85, 0xC2, 0x94, 0x2C, 0x0A, + /* x */ + 0x0F, 0xFA, 0x96, 0x3C, 0xDC, 0xA8, 0x81, 0x6C, 0xCC, 0x33, 0xB8, 0x64, + 0x2B, 0xED, 0xF9, 0x05, 0xC3, 0xD3, 0x58, 0x57, 0x3D, 0x3F, 0x27, 0xFB, + 0xBD, 0x3B, 0x3C, 0xB9, 0xAA, 0xAF, + /* y */ + 0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40, 0x54, 0xca, + 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18, 0xce, 0x22, 0x6b, 0x39, + 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae, + /* order */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0x9E, 0x5E, 0x9A, 0x9F, 0x5D, 0x90, 0x71, 0xFB, 0xD1, + 0x52, 0x26, 0x88, 0x90, 0x9D, 0x0B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_PRIME_239V2 = { + { + NID_X9_62_prime_field, 20, 30, 1 + }, + { + /* seed */ + 0xE8, 0xB4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xCA, 0x3B, 0x80, 0x99, + 0x98, 0x2B, 0xE0, 0x9F, 0xCB, 0x9A, 0xE6, 0x16, + /* p */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x61, 0x7F, 0xAB, 0x68, 0x32, 0x57, 0x6C, 0xBB, 0xFE, 0xD5, 0x0D, 0x99, + 0xF0, 0x24, 0x9C, 0x3F, 0xEE, 0x58, 0xB9, 0x4B, 0xA0, 0x03, 0x8C, 0x7A, + 0xE8, 0x4C, 0x8C, 0x83, 0x2F, 0x2C, + /* x */ + 0x38, 0xAF, 0x09, 0xD9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xC9, 0x21, 0xBB, + 0x5E, 0x9E, 0x26, 0x29, 0x6A, 0x3C, 0xDC, 0xF2, 0xF3, 0x57, 0x57, 0xA0, + 0xEA, 0xFD, 0x87, 0xB8, 0x30, 0xE7, + /* y */ + 0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d, 0xa0, 0xfc, + 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55, 0xde, 0x6e, 0xf4, 0x60, + 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba, + /* order */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0xCF, 0xA7, 0xE8, 0x59, 0x43, 0x77, 0xD4, 0x14, 0xC0, + 0x38, 0x21, 0xBC, 0x58, 0x20, 0x63 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_PRIME_239V3 = { + { + NID_X9_62_prime_field, 20, 30, 1 + }, + { + /* seed */ + 0x7D, 0x73, 0x74, 0x16, 0x8F, 0xFE, 0x34, 0x71, 0xB6, 0x0A, 0x85, 0x76, + 0x86, 0xA1, 0x94, 0x75, 0xD3, 0xBF, 0xA2, 0xFF, + /* p */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x25, 0x57, 0x05, 0xFA, 0x2A, 0x30, 0x66, 0x54, 0xB1, 0xF4, 0xCB, 0x03, + 0xD6, 0xA7, 0x50, 0xA3, 0x0C, 0x25, 0x01, 0x02, 0xD4, 0x98, 0x87, 0x17, + 0xD9, 0xBA, 0x15, 0xAB, 0x6D, 0x3E, + /* x */ + 0x67, 0x68, 0xAE, 0x8E, 0x18, 0xBB, 0x92, 0xCF, 0xCF, 0x00, 0x5C, 0x94, + 0x9A, 0xA2, 0xC6, 0xD9, 0x48, 0x53, 0xD0, 0xE6, 0x60, 0xBB, 0xF8, 0x54, + 0xB1, 0xC9, 0x50, 0x5F, 0xE9, 0x5A, + /* y */ + 0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d, 0x55, 0x2b, + 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b, 0x6e, 0x81, 0x84, 0x99, + 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3, + /* order */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0x97, 0x5D, 0xEB, 0x41, 0xB3, 0xA6, 0x05, 0x7C, 0x3C, + 0x43, 0x21, 0x46, 0x52, 0x65, 0x51 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 32 * 6]; +} _EC_X9_62_PRIME_256V1 = { + { + NID_X9_62_prime_field, 20, 32, 1 + }, + { + /* seed */ + 0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, 0x78, 0xE1, + 0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B, + /* x */ + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, + /* y */ + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, + 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 + } +}; + +/* the secg prime curves (minus the nist and x9.62 prime curves) */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 14 * 6]; +} _EC_SECG_PRIME_112R1 = { + { + NID_X9_62_prime_field, 20, 14, 1 + }, + { + /* seed */ + 0x00, 0xF5, 0x0B, 0x02, 0x8E, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, + 0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3F, 0xB1, + /* p */ + 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, + 0x20, 0x8B, + /* a */ + 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, + 0x20, 0x88, + /* b */ + 0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, 0x11, 0x70, + 0x2B, 0x22, + /* x */ + 0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, 0xF9, 0xC2, + 0xF0, 0x98, + /* y */ + 0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e, 0x0f, 0xf7, + 0x75, 0x00, + /* order */ + 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, 0xAC, 0x65, + 0x61, 0xC5 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 14 * 6]; +} _EC_SECG_PRIME_112R2 = { + { + NID_X9_62_prime_field, 20, 14, 4 + }, + { + /* seed */ + 0x00, 0x27, 0x57, 0xA1, 0x11, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, + 0x51, 0x75, 0x53, 0x16, 0xC0, 0x5E, 0x0B, 0xD4, + /* p */ + 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, + 0x20, 0x8B, + /* a */ + 0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, 0x5C, 0x0E, + 0xF0, 0x2C, + /* b */ + 0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, 0x4C, 0x85, + 0xD7, 0x09, + /* x */ + 0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, 0xD0, 0x92, + 0x86, 0x43, + /* y */ + 0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3, 0x6e, 0x95, + 0x6e, 0x97, + /* order */ + 0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, 0x05, 0x20, + 0xD0, 0x4B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 16 * 6]; +} _EC_SECG_PRIME_128R1 = { + { + NID_X9_62_prime_field, 20, 16, 1 + }, + { + /* seed */ + 0x00, 0x0E, 0x0D, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, + 0x0C, 0xC0, 0x3A, 0x44, 0x73, 0xD0, 0x36, 0x79, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, 0x99, 0x3C, + 0x2C, 0xEE, 0x5E, 0xD3, + /* x */ + 0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, 0x60, 0x7C, + 0xA5, 0x2C, 0x5B, 0x86, + /* y */ + 0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d, 0xa2, 0x92, + 0xdd, 0xed, 0x7a, 0x83, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, 0x0D, 0x1B, + 0x90, 0x38, 0xA1, 0x15 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 16 * 6]; +} _EC_SECG_PRIME_128R2 = { + { + NID_X9_62_prime_field, 20, 16, 4 + }, + { + /* seed */ + 0x00, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x12, 0xD8, + 0xF0, 0x34, 0x31, 0xFC, 0xE6, 0x3B, 0x88, 0xF4, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, 0xCC, 0x9B, + 0xBF, 0xF9, 0xAE, 0xE1, + /* b */ + 0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, 0x65, 0x58, + 0xBB, 0x6D, 0x8A, 0x5D, + /* x */ + 0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, 0x32, 0xA7, + 0xCD, 0xEB, 0xC1, 0x40, + /* y */ + 0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06, 0xfe, 0x80, + 0x5f, 0xc3, 0x4b, 0x44, + /* order */ + 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, 0x24, 0x72, + 0x06, 0x13, 0xB5, 0xA3 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_SECG_PRIME_160K1 = { + { + NID_X9_62_prime_field, 0, 21, 1 + }, + { + /* no seed */ + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + /* x */ + 0x00, 0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, 0x01, 0x9E, + 0x76, 0x30, 0x36, 0xF4, 0xF5, 0xDD, 0x4D, 0x7E, 0xBB, + /* y */ + 0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b, 0xc2, 0x82, + 0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f, 0xee, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, + 0xFA, 0x16, 0xDF, 0xAB, 0x9A, 0xCA, 0x16, 0xB6, 0xB3 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_SECG_PRIME_160R1 = { + { + NID_X9_62_prime_field, 20, 21, 1 + }, + { + /* seed */ + 0x10, 0x53, 0xCD, 0xE4, 0x2C, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x53, 0x3B, 0xF3, 0xF8, 0x33, 0x45, + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, + /* a */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFC, + /* b */ + 0x00, 0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, 0xAC, 0xF8, + 0x9F, 0x81, 0xD4, 0xD4, 0xAD, 0xC5, 0x65, 0xFA, 0x45, + /* x */ + 0x00, 0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, 0x64, 0x69, + 0x89, 0x68, 0xC3, 0x8B, 0xB9, 0x13, 0xCB, 0xFC, 0x82, + /* y */ + 0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59, 0xdc, 0xc9, + 0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb, 0x32, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4, + 0xC8, 0xF9, 0x27, 0xAE, 0xD3, 0xCA, 0x75, 0x22, 0x57 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_SECG_PRIME_160R2 = { + { + NID_X9_62_prime_field, 20, 21, 1 + }, + { + /* seed */ + 0xB9, 0x9B, 0x99, 0xB0, 0x99, 0xB3, 0x23, 0xE0, 0x27, 0x09, 0xA4, 0xD6, + 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51, + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73, + /* a */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x70, + /* b */ + 0x00, 0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, 0x57, 0x27, + 0x49, 0x04, 0x66, 0x4D, 0x5A, 0xF5, 0x03, 0x88, 0xBA, + /* x */ + 0x00, 0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, 0x4F, 0xF1, + 0x1B, 0x30, 0xF7, 0x19, 0x9D, 0x31, 0x44, 0xCE, 0x6D, + /* y */ + 0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0, 0x71, 0xfa, + 0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f, 0x2e, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, + 0x1E, 0xE7, 0x86, 0xA8, 0x18, 0xF3, 0xA1, 0xA1, 0x6B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 24 * 6]; +} _EC_SECG_PRIME_192K1 = { + { + NID_X9_62_prime_field, 0, 24, 1 + }, + { + /* no seed */ + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEE, 0x37, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + /* x */ + 0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, 0x7D, 0x02, + 0x80, 0xB7, 0xF4, 0x34, 0x1D, 0xA5, 0xD1, 0xB1, 0xEA, 0xE0, 0x6C, 0x7D, + /* y */ + 0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41, 0x63, 0xd0, + 0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88, 0xd9, 0x5e, 0x2f, 0x9d, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x26, 0xF2, 0xFC, 0x17, 0x0F, 0x69, 0x46, 0x6A, 0x74, 0xDE, 0xFD, 0x8D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 29 * 6]; +} _EC_SECG_PRIME_224K1 = { + { + NID_X9_62_prime_field, 0, 29, 1 + }, + { + /* no seed */ + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFF, 0xFF, 0xE5, 0x6D, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, + /* x */ + 0x00, 0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, 0xFC, 0x28, + 0xA1, 0x69, 0xA4, 0x67, 0xE9, 0xE4, 0x70, 0x75, 0xA9, 0x0F, 0x7E, 0x65, + 0x0E, 0xB6, 0xB7, 0xA4, 0x5C, + /* y */ + 0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82, 0xca, 0xfb, + 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd, 0x59, 0xe2, 0xca, 0x4b, + 0xdb, 0x55, 0x6d, 0x61, 0xa5, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xDC, 0xE8, 0xD2, 0xEC, 0x61, 0x84, 0xCA, 0xF0, 0xA9, + 0x71, 0x76, 0x9F, 0xB1, 0xF7 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 32 * 6]; +} _EC_SECG_PRIME_256K1 = { + { + NID_X9_62_prime_field, 0, 32, 1 + }, + { + /* no seed */ + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + /* x */ + 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, + 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, + 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, + /* y */ + 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, + 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, + 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, + 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 + } +}; + +/* some wap/wtls curves */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 15 * 6]; +} _EC_WTLS_8 = { + { + NID_X9_62_prime_field, 0, 15, 1 + }, + { + /* no seed */ + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFD, 0xE7, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, + /* x */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, + /* y */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEC, 0xEA, 0x55, 0x1A, + 0xD8, 0x37, 0xE9 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_WTLS_9 = { + { + NID_X9_62_prime_field, 0, 21, 1 + }, + { + /* no seed */ + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x8F, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + /* x */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* y */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCD, + 0xC9, 0x8A, 0xE0, 0xE2, 0xDE, 0x57, 0x4A, 0xBF, 0x33 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 28 * 6]; +} _EC_WTLS_12 = { + { + NID_X9_62_prime_field, 0, 28, 1 + }, + { + /* no seed */ + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, + /* b */ + 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, + 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, + 0x23, 0x55, 0xFF, 0xB4, + /* x */ + 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, + 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, + 0x11, 0x5C, 0x1D, 0x21, + /* y */ + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, + 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, + 0x85, 0x00, 0x7e, 0x34, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, + 0x5C, 0x5C, 0x2A, 0x3D + } +}; + +#ifndef OPENSSL_NO_EC2M + +/* characteristic two curves */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 15 * 6]; +} _EC_SECG_CHAR2_113R1 = { + { + NID_X9_62_characteristic_two_field, 20, 15, 2 + }, + { + /* seed */ + 0x10, 0xE7, 0x23, 0xAB, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, + 0x17, 0x56, 0xFE, 0xBF, 0x8F, 0xCB, 0x49, 0xA9, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x01, + /* a */ + 0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64, 0x9C, 0xE8, + 0x58, 0x20, 0xF7, + /* b */ + 0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18, 0x8B, 0xE0, + 0xE9, 0xC7, 0x23, + /* x */ + 0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07, 0xD7, 0x35, + 0x62, 0xC1, 0x0F, + /* y */ + 0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1, 0x31, 0x5E, + 0xD3, 0x18, 0x86, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC, 0xEC, 0x8A, + 0x39, 0xE5, 0x6F + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 15 * 6]; +} _EC_SECG_CHAR2_113R2 = { + { + NID_X9_62_characteristic_two_field, 20, 15, 2 + }, + { + /* seed */ + 0x10, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6, + 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x5D, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x01, + /* a */ + 0x00, 0x68, 0x99, 0x18, 0xDB, 0xEC, 0x7E, 0x5A, 0x0D, 0xD6, 0xDF, 0xC0, + 0xAA, 0x55, 0xC7, + /* b */ + 0x00, 0x95, 0xE9, 0xA9, 0xEC, 0x9B, 0x29, 0x7B, 0xD4, 0xBF, 0x36, 0xE0, + 0x59, 0x18, 0x4F, + /* x */ + 0x01, 0xA5, 0x7A, 0x6A, 0x7B, 0x26, 0xCA, 0x5E, 0xF5, 0x2F, 0xCD, 0xB8, + 0x16, 0x47, 0x97, + /* y */ + 0x00, 0xB3, 0xAD, 0xC9, 0x4E, 0xD1, 0xFE, 0x67, 0x4C, 0x06, 0xE6, 0x95, + 0xBA, 0xBA, 0x1D, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x78, 0x9B, 0x24, + 0x96, 0xAF, 0x93 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 17 * 6]; +} _EC_SECG_CHAR2_131R1 = { + { + NID_X9_62_characteristic_two_field, 20, 17, 2 + }, + { + /* seed */ + 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x98, 0x5B, 0xD3, + 0xAD, 0xBA, 0xDA, 0x21, 0xB4, 0x3A, 0x97, 0xE2, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x0D, + /* a */ + 0x07, 0xA1, 0x1B, 0x09, 0xA7, 0x6B, 0x56, 0x21, 0x44, 0x41, 0x8F, 0xF3, + 0xFF, 0x8C, 0x25, 0x70, 0xB8, + /* b */ + 0x02, 0x17, 0xC0, 0x56, 0x10, 0x88, 0x4B, 0x63, 0xB9, 0xC6, 0xC7, 0x29, + 0x16, 0x78, 0xF9, 0xD3, 0x41, + /* x */ + 0x00, 0x81, 0xBA, 0xF9, 0x1F, 0xDF, 0x98, 0x33, 0xC4, 0x0F, 0x9C, 0x18, + 0x13, 0x43, 0x63, 0x83, 0x99, + /* y */ + 0x07, 0x8C, 0x6E, 0x7E, 0xA3, 0x8C, 0x00, 0x1F, 0x73, 0xC8, 0x13, 0x4B, + 0x1B, 0x4E, 0xF9, 0xE1, 0x50, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x23, 0x95, + 0x3A, 0x94, 0x64, 0xB5, 0x4D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 17 * 6]; +} _EC_SECG_CHAR2_131R2 = { + { + NID_X9_62_characteristic_two_field, 20, 17, 2 + }, + { + /* seed */ + 0x98, 0x5B, 0xD3, 0xAD, 0xBA, 0xD4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x5A, 0x21, 0xB4, 0x3A, 0x97, 0xE3, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x0D, + /* a */ + 0x03, 0xE5, 0xA8, 0x89, 0x19, 0xD7, 0xCA, 0xFC, 0xBF, 0x41, 0x5F, 0x07, + 0xC2, 0x17, 0x65, 0x73, 0xB2, + /* b */ + 0x04, 0xB8, 0x26, 0x6A, 0x46, 0xC5, 0x56, 0x57, 0xAC, 0x73, 0x4C, 0xE3, + 0x8F, 0x01, 0x8F, 0x21, 0x92, + /* x */ + 0x03, 0x56, 0xDC, 0xD8, 0xF2, 0xF9, 0x50, 0x31, 0xAD, 0x65, 0x2D, 0x23, + 0x95, 0x1B, 0xB3, 0x66, 0xA8, + /* y */ + 0x06, 0x48, 0xF0, 0x6D, 0x86, 0x79, 0x40, 0xA5, 0x36, 0x6D, 0x9E, 0x26, + 0x5D, 0xE9, 0xEB, 0x24, 0x0F, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, 0x54, 0xA2, + 0x33, 0x04, 0x9B, 0xA9, 0x8F + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_NIST_CHAR2_163K = { + { + NID_X9_62_characteristic_two_field, 0, 21, 2 + }, + { + /* no seed */ + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA, 0x07, 0xD7, + 0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE, 0xE8, + /* y */ + 0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38, 0xFF, 0x58, 0x32, 0x1F, 0x2E, + 0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3, 0xD9, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + 0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5, 0xEF + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_SECG_CHAR2_163R1 = { + { + NID_X9_62_characteristic_two_field, 0, 21, 2 + }, + { + /* no seed */ +# if 0 + /* + * The algorithm used to derive the curve parameters from the seed + * used here is slightly different than the algorithm described in + * X9.62 . + */ + 0x24, 0xB7, 0xB1, 0x37, 0xC8, 0xA1, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, + 0x61, 0x51, 0x75, 0x6F, 0xD0, 0xDA, 0x2E, 0x5C, +# endif + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, + /* a */ + 0x07, 0xB6, 0x88, 0x2C, 0xAA, 0xEF, 0xA8, 0x4F, 0x95, 0x54, 0xFF, 0x84, + 0x28, 0xBD, 0x88, 0xE2, 0x46, 0xD2, 0x78, 0x2A, 0xE2, + /* b */ + 0x07, 0x13, 0x61, 0x2D, 0xCD, 0xDC, 0xB4, 0x0A, 0xAB, 0x94, 0x6B, 0xDA, + 0x29, 0xCA, 0x91, 0xF7, 0x3A, 0xF9, 0x58, 0xAF, 0xD9, + /* x */ + 0x03, 0x69, 0x97, 0x96, 0x97, 0xAB, 0x43, 0x89, 0x77, 0x89, 0x56, 0x67, + 0x89, 0x56, 0x7F, 0x78, 0x7A, 0x78, 0x76, 0xA6, 0x54, + /* y */ + 0x00, 0x43, 0x5E, 0xDB, 0x42, 0xEF, 0xAF, 0xB2, 0x98, 0x9D, 0x51, 0xFE, + 0xFC, 0xE3, 0xC8, 0x09, 0x88, 0xF4, 0x1F, 0xF8, 0x83, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, + 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27, 0x9B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_NIST_CHAR2_163B = { + { + NID_X9_62_characteristic_two_field, 0, 21, 2 + }, + { + /* no seed */ +# if 0 + /* + * The seed here was used to created the curve parameters in normal + * basis representation (and not the polynomial representation used + * here) + */ + 0x85, 0xE2, 0x5B, 0xFE, 0x5C, 0x86, 0x22, 0x6C, 0xDB, 0x12, 0x01, 0x6F, + 0x75, 0x53, 0xF9, 0xD0, 0xE6, 0x93, 0xA2, 0x68, +# endif + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x02, 0x0A, 0x60, 0x19, 0x07, 0xB8, 0xC9, 0x53, 0xCA, 0x14, 0x81, 0xEB, + 0x10, 0x51, 0x2F, 0x78, 0x74, 0x4A, 0x32, 0x05, 0xFD, + /* x */ + 0x03, 0xF0, 0xEB, 0xA1, 0x62, 0x86, 0xA2, 0xD5, 0x7E, 0xA0, 0x99, 0x11, + 0x68, 0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E, 0x36, + /* y */ + 0x00, 0xD5, 0x1F, 0xBC, 0x6C, 0x71, 0xA0, 0x09, 0x4F, 0xA2, 0xCD, 0xD5, + 0x45, 0xB1, 0x1C, 0x5C, 0x0C, 0x79, 0x73, 0x24, 0xF1, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, + 0xFE, 0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C, 0x33 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 25 * 6]; +} _EC_SECG_CHAR2_193R1 = { + { + NID_X9_62_characteristic_two_field, 20, 25, 2 + }, + { + /* seed */ + 0x10, 0x3F, 0xAE, 0xC7, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, + 0x75, 0x77, 0x7F, 0xC5, 0xB1, 0x91, 0xEF, 0x30, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, + /* a */ + 0x00, 0x17, 0x85, 0x8F, 0xEB, 0x7A, 0x98, 0x97, 0x51, 0x69, 0xE1, 0x71, + 0xF7, 0x7B, 0x40, 0x87, 0xDE, 0x09, 0x8A, 0xC8, 0xA9, 0x11, 0xDF, 0x7B, + 0x01, + /* b */ + 0x00, 0xFD, 0xFB, 0x49, 0xBF, 0xE6, 0xC3, 0xA8, 0x9F, 0xAC, 0xAD, 0xAA, + 0x7A, 0x1E, 0x5B, 0xBC, 0x7C, 0xC1, 0xC2, 0xE5, 0xD8, 0x31, 0x47, 0x88, + 0x14, + /* x */ + 0x01, 0xF4, 0x81, 0xBC, 0x5F, 0x0F, 0xF8, 0x4A, 0x74, 0xAD, 0x6C, 0xDF, + 0x6F, 0xDE, 0xF4, 0xBF, 0x61, 0x79, 0x62, 0x53, 0x72, 0xD8, 0xC0, 0xC5, + 0xE1, + /* y */ + 0x00, 0x25, 0xE3, 0x99, 0xF2, 0x90, 0x37, 0x12, 0xCC, 0xF3, 0xEA, 0x9E, + 0x3A, 0x1A, 0xD1, 0x7F, 0xB0, 0xB3, 0x20, 0x1B, 0x6A, 0xF7, 0xCE, 0x1B, + 0x05, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC7, 0xF3, 0x4A, 0x77, 0x8F, 0x44, 0x3A, 0xCC, 0x92, 0x0E, 0xBA, + 0x49 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 25 * 6]; +} _EC_SECG_CHAR2_193R2 = { + { + NID_X9_62_characteristic_two_field, 20, 25, 2 + }, + { + /* seed */ + 0x10, 0xB7, 0xB4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51, + 0x37, 0xC8, 0xA1, 0x6F, 0xD0, 0xDA, 0x22, 0x11, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, + /* a */ + 0x01, 0x63, 0xF3, 0x5A, 0x51, 0x37, 0xC2, 0xCE, 0x3E, 0xA6, 0xED, 0x86, + 0x67, 0x19, 0x0B, 0x0B, 0xC4, 0x3E, 0xCD, 0x69, 0x97, 0x77, 0x02, 0x70, + 0x9B, + /* b */ + 0x00, 0xC9, 0xBB, 0x9E, 0x89, 0x27, 0xD4, 0xD6, 0x4C, 0x37, 0x7E, 0x2A, + 0xB2, 0x85, 0x6A, 0x5B, 0x16, 0xE3, 0xEF, 0xB7, 0xF6, 0x1D, 0x43, 0x16, + 0xAE, + /* x */ + 0x00, 0xD9, 0xB6, 0x7D, 0x19, 0x2E, 0x03, 0x67, 0xC8, 0x03, 0xF3, 0x9E, + 0x1A, 0x7E, 0x82, 0xCA, 0x14, 0xA6, 0x51, 0x35, 0x0A, 0xAE, 0x61, 0x7E, + 0x8F, + /* y */ + 0x01, 0xCE, 0x94, 0x33, 0x56, 0x07, 0xC3, 0x04, 0xAC, 0x29, 0xE7, 0xDE, + 0xFB, 0xD9, 0xCA, 0x01, 0xF5, 0x96, 0xF9, 0x27, 0x22, 0x4C, 0xDE, 0xCF, + 0x6C, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x5A, 0xAB, 0x56, 0x1B, 0x00, 0x54, 0x13, 0xCC, 0xD4, 0xEE, 0x99, + 0xD5 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 30 * 6]; +} _EC_NIST_CHAR2_233K = { + { + NID_X9_62_characteristic_two_field, 0, 30, 4 + }, + { + /* no seed */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2, + 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C, + 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26, + /* y */ + 0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A, + 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0, + 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3, + /* order */ + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB, + 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_NIST_CHAR2_233B = { + { + NID_X9_62_characteristic_two_field, 20, 30, 2 + }, + { + /* seed */ + 0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1, 0x4B, 0x34, + 0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C, 0x09, 0x23, + 0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9, 0xCE, 0x42, 0x81, 0xFE, + 0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD, + /* x */ + 0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21, 0x39, 0xF1, + 0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F, 0x8B, 0x36, 0xF8, 0xF8, + 0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B, + /* y */ + 0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78, 0xE5, 0x85, + 0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67, 0xA7, 0xCA, 0x36, 0x71, + 0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F, 0x8A, 0x69, 0x22, 0x03, + 0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 30 * 6]; +} _EC_SECG_CHAR2_239K1 = { + { + NID_X9_62_characteristic_two_field, 0, 30, 4 + }, + { + /* no seed */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09, 0x88, 0xA6, + 0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C, 0xC2, 0xCC, 0x7B, 0x2A, + 0x65, 0x55, 0x19, 0x30, 0x35, 0xDC, + /* y */ + 0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01, 0x1C, 0x10, + 0x30, 0x89, 0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75, 0xFC, 0x31, 0x2A, 0x5D, + 0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA, + /* order */ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C, 0xB6, 0xE9, 0x1F, 0x1C, + 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 36 * 6]; +} _EC_NIST_CHAR2_283K = { + { + NID_X9_62_characteristic_two_field, 0, 36, 4 + }, + { + /* no seed */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x05, 0x03, 0x21, 0x3F, 0x78, 0xCA, 0x44, 0x88, 0x3F, 0x1A, 0x3B, 0x81, + 0x62, 0xF1, 0x88, 0xE5, 0x53, 0xCD, 0x26, 0x5F, 0x23, 0xC1, 0x56, 0x7A, + 0x16, 0x87, 0x69, 0x13, 0xB0, 0xC2, 0xAC, 0x24, 0x58, 0x49, 0x28, 0x36, + /* y */ + 0x01, 0xCC, 0xDA, 0x38, 0x0F, 0x1C, 0x9E, 0x31, 0x8D, 0x90, 0xF9, 0x5D, + 0x07, 0xE5, 0x42, 0x6F, 0xE8, 0x7E, 0x45, 0xC0, 0xE8, 0x18, 0x46, 0x98, + 0xE4, 0x59, 0x62, 0x36, 0x4E, 0x34, 0x11, 0x61, 0x77, 0xDD, 0x22, 0x59, + /* order */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xAE, 0x2E, 0xD0, 0x75, 0x77, + 0x26, 0x5D, 0xFF, 0x7F, 0x94, 0x45, 0x1E, 0x06, 0x1E, 0x16, 0x3C, 0x61 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 36 * 6]; +} _EC_NIST_CHAR2_283B = { + { + NID_X9_62_characteristic_two_field, 20, 36, 2 + }, + { + /* no seed */ + 0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, 0xD5, 0xB6, + 0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A, + 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2, + 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5, + /* x */ + 0x05, 0xF9, 0x39, 0x25, 0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93, 0x4F, 0x8C, + 0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8, 0x55, 0x7E, 0xAC, 0x9C, + 0x80, 0xE2, 0xE1, 0x98, 0xF8, 0xCD, 0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53, + /* y */ + 0x03, 0x67, 0x68, 0x54, 0xFE, 0x24, 0x14, 0x1C, 0xB9, 0x8F, 0xE6, 0xD4, + 0xB2, 0x0D, 0x02, 0xB4, 0x51, 0x6F, 0xF7, 0x02, 0x35, 0x0E, 0xDD, 0xB0, + 0x82, 0x67, 0x79, 0xC8, 0x13, 0xF0, 0xDF, 0x45, 0xBE, 0x81, 0x12, 0xF4, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90, 0x39, 0x96, 0x60, 0xFC, + 0x93, 0x8A, 0x90, 0x16, 0x5B, 0x04, 0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 52 * 6]; +} _EC_NIST_CHAR2_409K = { + { + NID_X9_62_characteristic_two_field, 0, 52, 4 + }, + { + /* no seed */ + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x00, 0x60, 0xF0, 0x5F, 0x65, 0x8F, 0x49, 0xC1, 0xAD, 0x3A, 0xB1, 0x89, + 0x0F, 0x71, 0x84, 0x21, 0x0E, 0xFD, 0x09, 0x87, 0xE3, 0x07, 0xC8, 0x4C, + 0x27, 0xAC, 0xCF, 0xB8, 0xF9, 0xF6, 0x7C, 0xC2, 0xC4, 0x60, 0x18, 0x9E, + 0xB5, 0xAA, 0xAA, 0x62, 0xEE, 0x22, 0x2E, 0xB1, 0xB3, 0x55, 0x40, 0xCF, + 0xE9, 0x02, 0x37, 0x46, + /* y */ + 0x01, 0xE3, 0x69, 0x05, 0x0B, 0x7C, 0x4E, 0x42, 0xAC, 0xBA, 0x1D, 0xAC, + 0xBF, 0x04, 0x29, 0x9C, 0x34, 0x60, 0x78, 0x2F, 0x91, 0x8E, 0xA4, 0x27, + 0xE6, 0x32, 0x51, 0x65, 0xE9, 0xEA, 0x10, 0xE3, 0xDA, 0x5F, 0x6C, 0x42, + 0xE9, 0xC5, 0x52, 0x15, 0xAA, 0x9C, 0xA2, 0x7A, 0x58, 0x63, 0xEC, 0x48, + 0xD8, 0xE0, 0x28, 0x6B, + /* order */ + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x5F, 0x83, 0xB2, 0xD4, 0xEA, 0x20, 0x40, 0x0E, 0xC4, + 0x55, 0x7D, 0x5E, 0xD3, 0xE3, 0xE7, 0xCA, 0x5B, 0x4B, 0x5C, 0x83, 0xB8, + 0xE0, 0x1E, 0x5F, 0xCF + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 52 * 6]; +} _EC_NIST_CHAR2_409B = { + { + NID_X9_62_characteristic_two_field, 20, 52, 2 + }, + { + /* seed */ + 0x40, 0x99, 0xB5, 0xA4, 0x57, 0xF9, 0xD6, 0x9F, 0x79, 0x21, 0x3D, 0x09, + 0x4C, 0x4B, 0xCD, 0x4D, 0x42, 0x62, 0x21, 0x0B, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x00, 0x21, 0xA5, 0xC2, 0xC8, 0xEE, 0x9F, 0xEB, 0x5C, 0x4B, 0x9A, 0x75, + 0x3B, 0x7B, 0x47, 0x6B, 0x7F, 0xD6, 0x42, 0x2E, 0xF1, 0xF3, 0xDD, 0x67, + 0x47, 0x61, 0xFA, 0x99, 0xD6, 0xAC, 0x27, 0xC8, 0xA9, 0xA1, 0x97, 0xB2, + 0x72, 0x82, 0x2F, 0x6C, 0xD5, 0x7A, 0x55, 0xAA, 0x4F, 0x50, 0xAE, 0x31, + 0x7B, 0x13, 0x54, 0x5F, + /* x */ + 0x01, 0x5D, 0x48, 0x60, 0xD0, 0x88, 0xDD, 0xB3, 0x49, 0x6B, 0x0C, 0x60, + 0x64, 0x75, 0x62, 0x60, 0x44, 0x1C, 0xDE, 0x4A, 0xF1, 0x77, 0x1D, 0x4D, + 0xB0, 0x1F, 0xFE, 0x5B, 0x34, 0xE5, 0x97, 0x03, 0xDC, 0x25, 0x5A, 0x86, + 0x8A, 0x11, 0x80, 0x51, 0x56, 0x03, 0xAE, 0xAB, 0x60, 0x79, 0x4E, 0x54, + 0xBB, 0x79, 0x96, 0xA7, + /* y */ + 0x00, 0x61, 0xB1, 0xCF, 0xAB, 0x6B, 0xE5, 0xF3, 0x2B, 0xBF, 0xA7, 0x83, + 0x24, 0xED, 0x10, 0x6A, 0x76, 0x36, 0xB9, 0xC5, 0xA7, 0xBD, 0x19, 0x8D, + 0x01, 0x58, 0xAA, 0x4F, 0x54, 0x88, 0xD0, 0x8F, 0x38, 0x51, 0x4F, 0x1F, + 0xDF, 0x4B, 0x4F, 0x40, 0xD2, 0x18, 0x1B, 0x36, 0x81, 0xC3, 0x64, 0xBA, + 0x02, 0x73, 0xC7, 0x06, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xE2, 0xAA, 0xD6, 0xA6, 0x12, 0xF3, 0x33, 0x07, 0xBE, + 0x5F, 0xA4, 0x7C, 0x3C, 0x9E, 0x05, 0x2F, 0x83, 0x81, 0x64, 0xCD, 0x37, + 0xD9, 0xA2, 0x11, 0x73 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 72 * 6]; +} _EC_NIST_CHAR2_571K = { + { + NID_X9_62_characteristic_two_field, 0, 72, 4 + }, + { + /* no seed */ + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x02, 0x6E, 0xB7, 0xA8, 0x59, 0x92, 0x3F, 0xBC, 0x82, 0x18, 0x96, 0x31, + 0xF8, 0x10, 0x3F, 0xE4, 0xAC, 0x9C, 0xA2, 0x97, 0x00, 0x12, 0xD5, 0xD4, + 0x60, 0x24, 0x80, 0x48, 0x01, 0x84, 0x1C, 0xA4, 0x43, 0x70, 0x95, 0x84, + 0x93, 0xB2, 0x05, 0xE6, 0x47, 0xDA, 0x30, 0x4D, 0xB4, 0xCE, 0xB0, 0x8C, + 0xBB, 0xD1, 0xBA, 0x39, 0x49, 0x47, 0x76, 0xFB, 0x98, 0x8B, 0x47, 0x17, + 0x4D, 0xCA, 0x88, 0xC7, 0xE2, 0x94, 0x52, 0x83, 0xA0, 0x1C, 0x89, 0x72, + /* y */ + 0x03, 0x49, 0xDC, 0x80, 0x7F, 0x4F, 0xBF, 0x37, 0x4F, 0x4A, 0xEA, 0xDE, + 0x3B, 0xCA, 0x95, 0x31, 0x4D, 0xD5, 0x8C, 0xEC, 0x9F, 0x30, 0x7A, 0x54, + 0xFF, 0xC6, 0x1E, 0xFC, 0x00, 0x6D, 0x8A, 0x2C, 0x9D, 0x49, 0x79, 0xC0, + 0xAC, 0x44, 0xAE, 0xA7, 0x4F, 0xBE, 0xBB, 0xB9, 0xF7, 0x72, 0xAE, 0xDC, + 0xB6, 0x20, 0xB0, 0x1A, 0x7B, 0xA7, 0xAF, 0x1B, 0x32, 0x04, 0x30, 0xC8, + 0x59, 0x19, 0x84, 0xF6, 0x01, 0xCD, 0x4C, 0x14, 0x3E, 0xF1, 0xC7, 0xA3, + /* order */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x18, 0x50, 0xE1, 0xF1, 0x9A, 0x63, 0xE4, 0xB3, 0x91, 0xA8, 0xDB, + 0x91, 0x7F, 0x41, 0x38, 0xB6, 0x30, 0xD8, 0x4B, 0xE5, 0xD6, 0x39, 0x38, + 0x1E, 0x91, 0xDE, 0xB4, 0x5C, 0xFE, 0x77, 0x8F, 0x63, 0x7C, 0x10, 0x01 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 72 * 6]; +} _EC_NIST_CHAR2_571B = { + { + NID_X9_62_characteristic_two_field, 20, 72, 2 + }, + { + /* seed */ + 0x2A, 0xA0, 0x58, 0xF7, 0x3A, 0x0E, 0x33, 0xAB, 0x48, 0x6B, 0x0F, 0x61, + 0x04, 0x10, 0xC5, 0x3A, 0x7F, 0x13, 0x23, 0x10, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x02, 0xF4, 0x0E, 0x7E, 0x22, 0x21, 0xF2, 0x95, 0xDE, 0x29, 0x71, 0x17, + 0xB7, 0xF3, 0xD6, 0x2F, 0x5C, 0x6A, 0x97, 0xFF, 0xCB, 0x8C, 0xEF, 0xF1, + 0xCD, 0x6B, 0xA8, 0xCE, 0x4A, 0x9A, 0x18, 0xAD, 0x84, 0xFF, 0xAB, 0xBD, + 0x8E, 0xFA, 0x59, 0x33, 0x2B, 0xE7, 0xAD, 0x67, 0x56, 0xA6, 0x6E, 0x29, + 0x4A, 0xFD, 0x18, 0x5A, 0x78, 0xFF, 0x12, 0xAA, 0x52, 0x0E, 0x4D, 0xE7, + 0x39, 0xBA, 0xCA, 0x0C, 0x7F, 0xFE, 0xFF, 0x7F, 0x29, 0x55, 0x72, 0x7A, + /* x */ + 0x03, 0x03, 0x00, 0x1D, 0x34, 0xB8, 0x56, 0x29, 0x6C, 0x16, 0xC0, 0xD4, + 0x0D, 0x3C, 0xD7, 0x75, 0x0A, 0x93, 0xD1, 0xD2, 0x95, 0x5F, 0xA8, 0x0A, + 0xA5, 0xF4, 0x0F, 0xC8, 0xDB, 0x7B, 0x2A, 0xBD, 0xBD, 0xE5, 0x39, 0x50, + 0xF4, 0xC0, 0xD2, 0x93, 0xCD, 0xD7, 0x11, 0xA3, 0x5B, 0x67, 0xFB, 0x14, + 0x99, 0xAE, 0x60, 0x03, 0x86, 0x14, 0xF1, 0x39, 0x4A, 0xBF, 0xA3, 0xB4, + 0xC8, 0x50, 0xD9, 0x27, 0xE1, 0xE7, 0x76, 0x9C, 0x8E, 0xEC, 0x2D, 0x19, + /* y */ + 0x03, 0x7B, 0xF2, 0x73, 0x42, 0xDA, 0x63, 0x9B, 0x6D, 0xCC, 0xFF, 0xFE, + 0xB7, 0x3D, 0x69, 0xD7, 0x8C, 0x6C, 0x27, 0xA6, 0x00, 0x9C, 0xBB, 0xCA, + 0x19, 0x80, 0xF8, 0x53, 0x39, 0x21, 0xE8, 0xA6, 0x84, 0x42, 0x3E, 0x43, + 0xBA, 0xB0, 0x8A, 0x57, 0x62, 0x91, 0xAF, 0x8F, 0x46, 0x1B, 0xB2, 0xA8, + 0xB3, 0x53, 0x1D, 0x2F, 0x04, 0x85, 0xC1, 0x9B, 0x16, 0xE2, 0xF1, 0x51, + 0x6E, 0x23, 0xDD, 0x3C, 0x1A, 0x48, 0x27, 0xAF, 0x1B, 0x8A, 0xC1, 0x5B, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE6, 0x61, 0xCE, 0x18, 0xFF, 0x55, 0x98, 0x73, 0x08, 0x05, 0x9B, 0x18, + 0x68, 0x23, 0x85, 0x1E, 0xC7, 0xDD, 0x9C, 0xA1, 0x16, 0x1D, 0xE9, 0x3D, + 0x51, 0x74, 0xD6, 0x6E, 0x83, 0x82, 0xE9, 0xBB, 0x2F, 0xE8, 0x4E, 0x47 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_X9_62_CHAR2_163V1 = { + { + NID_X9_62_characteristic_two_field, 20, 21, 2 + }, + { + /* seed */ + 0xD2, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6, + 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x54, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, + /* a */ + 0x07, 0x25, 0x46, 0xB5, 0x43, 0x52, 0x34, 0xA4, 0x22, 0xE0, 0x78, 0x96, + 0x75, 0xF4, 0x32, 0xC8, 0x94, 0x35, 0xDE, 0x52, 0x42, + /* b */ + 0x00, 0xC9, 0x51, 0x7D, 0x06, 0xD5, 0x24, 0x0D, 0x3C, 0xFF, 0x38, 0xC7, + 0x4B, 0x20, 0xB6, 0xCD, 0x4D, 0x6F, 0x9D, 0xD4, 0xD9, + /* x */ + 0x07, 0xAF, 0x69, 0x98, 0x95, 0x46, 0x10, 0x3D, 0x79, 0x32, 0x9F, 0xCC, + 0x3D, 0x74, 0x88, 0x0F, 0x33, 0xBB, 0xE8, 0x03, 0xCB, + /* y */ + 0x01, 0xEC, 0x23, 0x21, 0x1B, 0x59, 0x66, 0xAD, 0xEA, 0x1D, 0x3F, 0x87, + 0xF7, 0xEA, 0x58, 0x48, 0xAE, 0xF0, 0xB7, 0xCA, 0x9F, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE6, + 0x0F, 0xC8, 0x82, 0x1C, 0xC7, 0x4D, 0xAE, 0xAF, 0xC1 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_X9_62_CHAR2_163V2 = { + { + NID_X9_62_characteristic_two_field, 20, 21, 2 + }, + { + /* seed */ + 0x53, 0x81, 0x4C, 0x05, 0x0D, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x58, 0x0C, 0xA4, 0xE2, 0x9F, 0xFD, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, + /* a */ + 0x01, 0x08, 0xB3, 0x9E, 0x77, 0xC4, 0xB1, 0x08, 0xBE, 0xD9, 0x81, 0xED, + 0x0E, 0x89, 0x0E, 0x11, 0x7C, 0x51, 0x1C, 0xF0, 0x72, + /* b */ + 0x06, 0x67, 0xAC, 0xEB, 0x38, 0xAF, 0x4E, 0x48, 0x8C, 0x40, 0x74, 0x33, + 0xFF, 0xAE, 0x4F, 0x1C, 0x81, 0x16, 0x38, 0xDF, 0x20, + /* x */ + 0x00, 0x24, 0x26, 0x6E, 0x4E, 0xB5, 0x10, 0x6D, 0x0A, 0x96, 0x4D, 0x92, + 0xC4, 0x86, 0x0E, 0x26, 0x71, 0xDB, 0x9B, 0x6C, 0xC5, + /* y */ + 0x07, 0x9F, 0x68, 0x4D, 0xDF, 0x66, 0x84, 0xC5, 0xCD, 0x25, 0x8B, 0x38, + 0x90, 0x02, 0x1B, 0x23, 0x86, 0xDF, 0xD1, 0x9F, 0xC5, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF6, + 0x4D, 0xE1, 0x15, 0x1A, 0xDB, 0xB7, 0x8F, 0x10, 0xA7 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_X9_62_CHAR2_163V3 = { + { + NID_X9_62_characteristic_two_field, 20, 21, 2 + }, + { + /* seed */ + 0x50, 0xCB, 0xF1, 0xD9, 0x5C, 0xA9, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, + 0x61, 0x51, 0x75, 0xF1, 0x6A, 0x36, 0xA3, 0xB8, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, + /* a */ + 0x07, 0xA5, 0x26, 0xC6, 0x3D, 0x3E, 0x25, 0xA2, 0x56, 0xA0, 0x07, 0x69, + 0x9F, 0x54, 0x47, 0xE3, 0x2A, 0xE4, 0x56, 0xB5, 0x0E, + /* b */ + 0x03, 0xF7, 0x06, 0x17, 0x98, 0xEB, 0x99, 0xE2, 0x38, 0xFD, 0x6F, 0x1B, + 0xF9, 0x5B, 0x48, 0xFE, 0xEB, 0x48, 0x54, 0x25, 0x2B, + /* x */ + 0x02, 0xF9, 0xF8, 0x7B, 0x7C, 0x57, 0x4D, 0x0B, 0xDE, 0xCF, 0x8A, 0x22, + 0xE6, 0x52, 0x47, 0x75, 0xF9, 0x8C, 0xDE, 0xBD, 0xCB, + /* y */ + 0x05, 0xB9, 0x35, 0x59, 0x0C, 0x15, 0x5E, 0x17, 0xEA, 0x48, 0xEB, 0x3F, + 0xF3, 0x71, 0x8B, 0x89, 0x3D, 0xF5, 0x9A, 0x05, 0xD0, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1A, + 0xEE, 0x14, 0x0F, 0x11, 0x0A, 0xFF, 0x96, 0x13, 0x09 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 23 * 6]; +} _EC_X9_62_CHAR2_176V1 = { + { + NID_X9_62_characteristic_two_field, 0, 23, 0xFF6E + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, + /* a */ + 0x00, 0xE4, 0xE6, 0xDB, 0x29, 0x95, 0x06, 0x5C, 0x40, 0x7D, 0x9D, 0x39, + 0xB8, 0xD0, 0x96, 0x7B, 0x96, 0x70, 0x4B, 0xA8, 0xE9, 0xC9, 0x0B, + /* b */ + 0x00, 0x5D, 0xDA, 0x47, 0x0A, 0xBE, 0x64, 0x14, 0xDE, 0x8E, 0xC1, 0x33, + 0xAE, 0x28, 0xE9, 0xBB, 0xD7, 0xFC, 0xEC, 0x0A, 0xE0, 0xFF, 0xF2, + /* x */ + 0x00, 0x8D, 0x16, 0xC2, 0x86, 0x67, 0x98, 0xB6, 0x00, 0xF9, 0xF0, 0x8B, + 0xB4, 0xA8, 0xE8, 0x60, 0xF3, 0x29, 0x8C, 0xE0, 0x4A, 0x57, 0x98, + /* y */ + 0x00, 0x6F, 0xA4, 0x53, 0x9C, 0x2D, 0xAD, 0xDD, 0xD6, 0xBA, 0xB5, 0x16, + 0x7D, 0x61, 0xB4, 0x36, 0xE1, 0xD9, 0x2B, 0xB1, 0x6A, 0x56, 0x2C, + /* order */ + 0x00, 0x00, 0x01, 0x00, 0x92, 0x53, 0x73, 0x97, 0xEC, 0xA4, 0xF6, 0x14, + 0x57, 0x99, 0xD6, 0x2B, 0x0A, 0x19, 0xCE, 0x06, 0xFE, 0x26, 0xAD + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_CHAR2_191V1 = { + { + NID_X9_62_characteristic_two_field, 20, 24, 2 + }, + { + /* seed */ + 0x4E, 0x13, 0xCA, 0x54, 0x27, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x55, 0x2F, 0x27, 0x9A, 0x8C, 0x84, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + /* a */ + 0x28, 0x66, 0x53, 0x7B, 0x67, 0x67, 0x52, 0x63, 0x6A, 0x68, 0xF5, 0x65, + 0x54, 0xE1, 0x26, 0x40, 0x27, 0x6B, 0x64, 0x9E, 0xF7, 0x52, 0x62, 0x67, + /* b */ + 0x2E, 0x45, 0xEF, 0x57, 0x1F, 0x00, 0x78, 0x6F, 0x67, 0xB0, 0x08, 0x1B, + 0x94, 0x95, 0xA3, 0xD9, 0x54, 0x62, 0xF5, 0xDE, 0x0A, 0xA1, 0x85, 0xEC, + /* x */ + 0x36, 0xB3, 0xDA, 0xF8, 0xA2, 0x32, 0x06, 0xF9, 0xC4, 0xF2, 0x99, 0xD7, + 0xB2, 0x1A, 0x9C, 0x36, 0x91, 0x37, 0xF2, 0xC8, 0x4A, 0xE1, 0xAA, 0x0D, + /* y */ + 0x76, 0x5B, 0xE7, 0x34, 0x33, 0xB3, 0xF9, 0x5E, 0x33, 0x29, 0x32, 0xE7, + 0x0E, 0xA2, 0x45, 0xCA, 0x24, 0x18, 0xEA, 0x0E, 0xF9, 0x80, 0x18, 0xFB, + /* order */ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0xA2, 0x0E, 0x90, 0xC3, 0x90, 0x67, 0xC8, 0x93, 0xBB, 0xB9, 0xA5 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_CHAR2_191V2 = { + { + NID_X9_62_characteristic_two_field, 20, 24, 4 + }, + { + /* seed */ + 0x08, 0x71, 0xEF, 0x2F, 0xEF, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x58, 0xBE, 0xE0, 0xD9, 0x5C, 0x15, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + /* a */ + 0x40, 0x10, 0x28, 0x77, 0x4D, 0x77, 0x77, 0xC7, 0xB7, 0x66, 0x6D, 0x13, + 0x66, 0xEA, 0x43, 0x20, 0x71, 0x27, 0x4F, 0x89, 0xFF, 0x01, 0xE7, 0x18, + /* b */ + 0x06, 0x20, 0x04, 0x8D, 0x28, 0xBC, 0xBD, 0x03, 0xB6, 0x24, 0x9C, 0x99, + 0x18, 0x2B, 0x7C, 0x8C, 0xD1, 0x97, 0x00, 0xC3, 0x62, 0xC4, 0x6A, 0x01, + /* x */ + 0x38, 0x09, 0xB2, 0xB7, 0xCC, 0x1B, 0x28, 0xCC, 0x5A, 0x87, 0x92, 0x6A, + 0xAD, 0x83, 0xFD, 0x28, 0x78, 0x9E, 0x81, 0xE2, 0xC9, 0xE3, 0xBF, 0x10, + /* y */ + 0x17, 0x43, 0x43, 0x86, 0x62, 0x6D, 0x14, 0xF3, 0xDB, 0xF0, 0x17, 0x60, + 0xD9, 0x21, 0x3A, 0x3E, 0x1C, 0xF3, 0x7A, 0xEC, 0x43, 0x7D, 0x66, 0x8A, + /* order */ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x50, 0x8C, 0xB8, 0x9F, 0x65, 0x28, 0x24, 0xE0, 0x6B, 0x81, 0x73 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_CHAR2_191V3 = { + { + NID_X9_62_characteristic_two_field, 20, 24, 6 + }, + { + /* seed */ + 0xE0, 0x53, 0x51, 0x2D, 0xC6, 0x84, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x50, 0x67, 0xAE, 0x78, 0x6D, 0x1F, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + /* a */ + 0x6C, 0x01, 0x07, 0x47, 0x56, 0x09, 0x91, 0x22, 0x22, 0x10, 0x56, 0x91, + 0x1C, 0x77, 0xD7, 0x7E, 0x77, 0xA7, 0x77, 0xE7, 0xE7, 0xE7, 0x7F, 0xCB, + /* b */ + 0x71, 0xFE, 0x1A, 0xF9, 0x26, 0xCF, 0x84, 0x79, 0x89, 0xEF, 0xEF, 0x8D, + 0xB4, 0x59, 0xF6, 0x63, 0x94, 0xD9, 0x0F, 0x32, 0xAD, 0x3F, 0x15, 0xE8, + /* x */ + 0x37, 0x5D, 0x4C, 0xE2, 0x4F, 0xDE, 0x43, 0x44, 0x89, 0xDE, 0x87, 0x46, + 0xE7, 0x17, 0x86, 0x01, 0x50, 0x09, 0xE6, 0x6E, 0x38, 0xA9, 0x26, 0xDD, + /* y */ + 0x54, 0x5A, 0x39, 0x17, 0x61, 0x96, 0x57, 0x5D, 0x98, 0x59, 0x99, 0x36, + 0x6E, 0x6A, 0xD3, 0x4C, 0xE0, 0xA7, 0x7C, 0xD7, 0x12, 0x7B, 0x06, 0xBE, + /* order */ + 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x61, 0x0C, 0x0B, 0x19, 0x68, 0x12, 0xBF, 0xB6, 0x28, 0x8A, 0x3E, 0xA3 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 27 * 6]; +} _EC_X9_62_CHAR2_208W1 = { + { + NID_X9_62_characteristic_two_field, 0, 27, 0xFE48 + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + /* b */ + 0x00, 0xC8, 0x61, 0x9E, 0xD4, 0x5A, 0x62, 0xE6, 0x21, 0x2E, 0x11, 0x60, + 0x34, 0x9E, 0x2B, 0xFA, 0x84, 0x44, 0x39, 0xFA, 0xFC, 0x2A, 0x3F, 0xD1, + 0x63, 0x8F, 0x9E, + /* x */ + 0x00, 0x89, 0xFD, 0xFB, 0xE4, 0xAB, 0xE1, 0x93, 0xDF, 0x95, 0x59, 0xEC, + 0xF0, 0x7A, 0xC0, 0xCE, 0x78, 0x55, 0x4E, 0x27, 0x84, 0xEB, 0x8C, 0x1E, + 0xD1, 0xA5, 0x7A, + /* y */ + 0x00, 0x0F, 0x55, 0xB5, 0x1A, 0x06, 0xE7, 0x8E, 0x9A, 0xC3, 0x8A, 0x03, + 0x5F, 0xF5, 0x20, 0xD8, 0xB0, 0x17, 0x81, 0xBE, 0xB1, 0xA6, 0xBB, 0x08, + 0x61, 0x7D, 0xE3, + /* order */ + 0x00, 0x00, 0x01, 0x01, 0xBA, 0xF9, 0x5C, 0x97, 0x23, 0xC5, 0x7B, 0x6C, + 0x21, 0xDA, 0x2E, 0xFF, 0x2D, 0x5E, 0xD5, 0x88, 0xBD, 0xD5, 0x71, 0x7E, + 0x21, 0x2F, 0x9D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_CHAR2_239V1 = { + { + NID_X9_62_characteristic_two_field, 20, 30, 4 + }, + { + /* seed */ + 0xD3, 0x4B, 0x9A, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, + 0xCA, 0x71, 0xB9, 0x20, 0xBF, 0xEF, 0xB0, 0x5D, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x32, 0x01, 0x08, 0x57, 0x07, 0x7C, 0x54, 0x31, 0x12, 0x3A, 0x46, 0xB8, + 0x08, 0x90, 0x67, 0x56, 0xF5, 0x43, 0x42, 0x3E, 0x8D, 0x27, 0x87, 0x75, + 0x78, 0x12, 0x57, 0x78, 0xAC, 0x76, + /* b */ + 0x79, 0x04, 0x08, 0xF2, 0xEE, 0xDA, 0xF3, 0x92, 0xB0, 0x12, 0xED, 0xEF, + 0xB3, 0x39, 0x2F, 0x30, 0xF4, 0x32, 0x7C, 0x0C, 0xA3, 0xF3, 0x1F, 0xC3, + 0x83, 0xC4, 0x22, 0xAA, 0x8C, 0x16, + /* x */ + 0x57, 0x92, 0x70, 0x98, 0xFA, 0x93, 0x2E, 0x7C, 0x0A, 0x96, 0xD3, 0xFD, + 0x5B, 0x70, 0x6E, 0xF7, 0xE5, 0xF5, 0xC1, 0x56, 0xE1, 0x6B, 0x7E, 0x7C, + 0x86, 0x03, 0x85, 0x52, 0xE9, 0x1D, + /* y */ + 0x61, 0xD8, 0xEE, 0x50, 0x77, 0xC3, 0x3F, 0xEC, 0xF6, 0xF1, 0xA1, 0x6B, + 0x26, 0x8D, 0xE4, 0x69, 0xC3, 0xC7, 0x74, 0x4E, 0xA9, 0xA9, 0x71, 0x64, + 0x9F, 0xC7, 0xA9, 0x61, 0x63, 0x05, + /* order */ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x42, 0xFF, 0xE1, 0x49, 0x2A, 0x49, 0x93, + 0xF1, 0xCA, 0xD6, 0x66, 0xE4, 0x47 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_CHAR2_239V2 = { + { + NID_X9_62_characteristic_two_field, 20, 30, 6 + }, + { + /* seed */ + 0x2A, 0xA6, 0x98, 0x2F, 0xDF, 0xA4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x5D, 0x26, 0x67, 0x27, 0x27, 0x7D, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x42, 0x30, 0x01, 0x77, 0x57, 0xA7, 0x67, 0xFA, 0xE4, 0x23, 0x98, 0x56, + 0x9B, 0x74, 0x63, 0x25, 0xD4, 0x53, 0x13, 0xAF, 0x07, 0x66, 0x26, 0x64, + 0x79, 0xB7, 0x56, 0x54, 0xE6, 0x5F, + /* b */ + 0x50, 0x37, 0xEA, 0x65, 0x41, 0x96, 0xCF, 0xF0, 0xCD, 0x82, 0xB2, 0xC1, + 0x4A, 0x2F, 0xCF, 0x2E, 0x3F, 0xF8, 0x77, 0x52, 0x85, 0xB5, 0x45, 0x72, + 0x2F, 0x03, 0xEA, 0xCD, 0xB7, 0x4B, + /* x */ + 0x28, 0xF9, 0xD0, 0x4E, 0x90, 0x00, 0x69, 0xC8, 0xDC, 0x47, 0xA0, 0x85, + 0x34, 0xFE, 0x76, 0xD2, 0xB9, 0x00, 0xB7, 0xD7, 0xEF, 0x31, 0xF5, 0x70, + 0x9F, 0x20, 0x0C, 0x4C, 0xA2, 0x05, + /* y */ + 0x56, 0x67, 0x33, 0x4C, 0x45, 0xAF, 0xF3, 0xB5, 0xA0, 0x3B, 0xAD, 0x9D, + 0xD7, 0x5E, 0x2C, 0x71, 0xA9, 0x93, 0x62, 0x56, 0x7D, 0x54, 0x53, 0xF7, + 0xFA, 0x6E, 0x22, 0x7E, 0xC8, 0x33, + /* order */ + 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x3C, 0x6F, 0x28, 0x85, 0x25, 0x9C, 0x31, 0xE3, 0xFC, + 0xDF, 0x15, 0x46, 0x24, 0x52, 0x2D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_CHAR2_239V3 = { + { + NID_X9_62_characteristic_two_field, 20, 30, 0xA + }, + { + /* seed */ + 0x9E, 0x07, 0x6F, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, + 0xE1, 0x1E, 0x9F, 0xDD, 0x77, 0xF9, 0x20, 0x41, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x01, 0x23, 0x87, 0x74, 0x66, 0x6A, 0x67, 0x76, 0x6D, 0x66, 0x76, 0xF7, + 0x78, 0xE6, 0x76, 0xB6, 0x69, 0x99, 0x17, 0x66, 0x66, 0xE6, 0x87, 0x66, + 0x6D, 0x87, 0x66, 0xC6, 0x6A, 0x9F, + /* b */ + 0x6A, 0x94, 0x19, 0x77, 0xBA, 0x9F, 0x6A, 0x43, 0x51, 0x99, 0xAC, 0xFC, + 0x51, 0x06, 0x7E, 0xD5, 0x87, 0xF5, 0x19, 0xC5, 0xEC, 0xB5, 0x41, 0xB8, + 0xE4, 0x41, 0x11, 0xDE, 0x1D, 0x40, + /* x */ + 0x70, 0xF6, 0xE9, 0xD0, 0x4D, 0x28, 0x9C, 0x4E, 0x89, 0x91, 0x3C, 0xE3, + 0x53, 0x0B, 0xFD, 0xE9, 0x03, 0x97, 0x7D, 0x42, 0xB1, 0x46, 0xD5, 0x39, + 0xBF, 0x1B, 0xDE, 0x4E, 0x9C, 0x92, + /* y */ + 0x2E, 0x5A, 0x0E, 0xAF, 0x6E, 0x5E, 0x13, 0x05, 0xB9, 0x00, 0x4D, 0xCE, + 0x5C, 0x0E, 0xD7, 0xFE, 0x59, 0xA3, 0x56, 0x08, 0xF3, 0x38, 0x37, 0xC8, + 0x16, 0xD8, 0x0B, 0x79, 0xF4, 0x61, + /* order */ + 0x0C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xAC, 0x49, 0x12, 0xD2, 0xD9, 0xDF, 0x90, 0x3E, 0xF9, + 0x88, 0x8B, 0x8A, 0x0E, 0x4C, 0xFF + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 35 * 6]; +} _EC_X9_62_CHAR2_272W1 = { + { + NID_X9_62_characteristic_two_field, 0, 35, 0xFF06 + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, + /* a */ + 0x00, 0x91, 0xA0, 0x91, 0xF0, 0x3B, 0x5F, 0xBA, 0x4A, 0xB2, 0xCC, 0xF4, + 0x9C, 0x4E, 0xDD, 0x22, 0x0F, 0xB0, 0x28, 0x71, 0x2D, 0x42, 0xBE, 0x75, + 0x2B, 0x2C, 0x40, 0x09, 0x4D, 0xBA, 0xCD, 0xB5, 0x86, 0xFB, 0x20, + /* b */ + 0x00, 0x71, 0x67, 0xEF, 0xC9, 0x2B, 0xB2, 0xE3, 0xCE, 0x7C, 0x8A, 0xAA, + 0xFF, 0x34, 0xE1, 0x2A, 0x9C, 0x55, 0x70, 0x03, 0xD7, 0xC7, 0x3A, 0x6F, + 0xAF, 0x00, 0x3F, 0x99, 0xF6, 0xCC, 0x84, 0x82, 0xE5, 0x40, 0xF7, + /* x */ + 0x00, 0x61, 0x08, 0xBA, 0xBB, 0x2C, 0xEE, 0xBC, 0xF7, 0x87, 0x05, 0x8A, + 0x05, 0x6C, 0xBE, 0x0C, 0xFE, 0x62, 0x2D, 0x77, 0x23, 0xA2, 0x89, 0xE0, + 0x8A, 0x07, 0xAE, 0x13, 0xEF, 0x0D, 0x10, 0xD1, 0x71, 0xDD, 0x8D, + /* y */ + 0x00, 0x10, 0xC7, 0x69, 0x57, 0x16, 0x85, 0x1E, 0xEF, 0x6B, 0xA7, 0xF6, + 0x87, 0x2E, 0x61, 0x42, 0xFB, 0xD2, 0x41, 0xB8, 0x30, 0xFF, 0x5E, 0xFC, + 0xAC, 0xEC, 0xCA, 0xB0, 0x5E, 0x02, 0x00, 0x5D, 0xDE, 0x9D, 0x23, + /* order */ + 0x00, 0x00, 0x01, 0x00, 0xFA, 0xF5, 0x13, 0x54, 0xE0, 0xE3, 0x9E, 0x48, + 0x92, 0xDF, 0x6E, 0x31, 0x9C, 0x72, 0xC8, 0x16, 0x16, 0x03, 0xFA, 0x45, + 0xAA, 0x7B, 0x99, 0x8A, 0x16, 0x7B, 0x8F, 0x1E, 0x62, 0x95, 0x21 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 39 * 6]; +} _EC_X9_62_CHAR2_304W1 = { + { + NID_X9_62_characteristic_two_field, 0, 39, 0xFE2E + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x07, + /* a */ + 0x00, 0xFD, 0x0D, 0x69, 0x31, 0x49, 0xA1, 0x18, 0xF6, 0x51, 0xE6, 0xDC, + 0xE6, 0x80, 0x20, 0x85, 0x37, 0x7E, 0x5F, 0x88, 0x2D, 0x1B, 0x51, 0x0B, + 0x44, 0x16, 0x00, 0x74, 0xC1, 0x28, 0x80, 0x78, 0x36, 0x5A, 0x03, 0x96, + 0xC8, 0xE6, 0x81, + /* b */ + 0x00, 0xBD, 0xDB, 0x97, 0xE5, 0x55, 0xA5, 0x0A, 0x90, 0x8E, 0x43, 0xB0, + 0x1C, 0x79, 0x8E, 0xA5, 0xDA, 0xA6, 0x78, 0x8F, 0x1E, 0xA2, 0x79, 0x4E, + 0xFC, 0xF5, 0x71, 0x66, 0xB8, 0xC1, 0x40, 0x39, 0x60, 0x1E, 0x55, 0x82, + 0x73, 0x40, 0xBE, + /* x */ + 0x00, 0x19, 0x7B, 0x07, 0x84, 0x5E, 0x9B, 0xE2, 0xD9, 0x6A, 0xDB, 0x0F, + 0x5F, 0x3C, 0x7F, 0x2C, 0xFF, 0xBD, 0x7A, 0x3E, 0xB8, 0xB6, 0xFE, 0xC3, + 0x5C, 0x7F, 0xD6, 0x7F, 0x26, 0xDD, 0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74, + 0x0A, 0x26, 0x14, + /* y */ + 0x00, 0xE1, 0x9F, 0xBE, 0xB7, 0x6E, 0x0D, 0xA1, 0x71, 0x51, 0x7E, 0xCF, + 0x40, 0x1B, 0x50, 0x28, 0x9B, 0xF0, 0x14, 0x10, 0x32, 0x88, 0x52, 0x7A, + 0x9B, 0x41, 0x6A, 0x10, 0x5E, 0x80, 0x26, 0x0B, 0x54, 0x9F, 0xDC, 0x1B, + 0x92, 0xC0, 0x3B, + /* order */ + 0x00, 0x00, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01, + 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01, 0x02, 0x2D, 0x5C, + 0x91, 0xDD, 0x17, 0x3F, 0x8F, 0xB5, 0x61, 0xDA, 0x68, 0x99, 0x16, 0x44, + 0x43, 0x05, 0x1D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 45 * 6]; +} _EC_X9_62_CHAR2_359V1 = { + { + NID_X9_62_characteristic_two_field, 20, 45, 0x4C + }, + { + /* seed */ + 0x2B, 0x35, 0x49, 0x20, 0xB7, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x58, 0x5B, 0xA1, 0x33, 0x2D, 0xC6, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x56, 0x67, 0x67, 0x6A, 0x65, 0x4B, 0x20, 0x75, 0x4F, 0x35, 0x6E, 0xA9, + 0x20, 0x17, 0xD9, 0x46, 0x56, 0x7C, 0x46, 0x67, 0x55, 0x56, 0xF1, 0x95, + 0x56, 0xA0, 0x46, 0x16, 0xB5, 0x67, 0xD2, 0x23, 0xA5, 0xE0, 0x56, 0x56, + 0xFB, 0x54, 0x90, 0x16, 0xA9, 0x66, 0x56, 0xA5, 0x57, + /* b */ + 0x24, 0x72, 0xE2, 0xD0, 0x19, 0x7C, 0x49, 0x36, 0x3F, 0x1F, 0xE7, 0xF5, + 0xB6, 0xDB, 0x07, 0x5D, 0x52, 0xB6, 0x94, 0x7D, 0x13, 0x5D, 0x8C, 0xA4, + 0x45, 0x80, 0x5D, 0x39, 0xBC, 0x34, 0x56, 0x26, 0x08, 0x96, 0x87, 0x74, + 0x2B, 0x63, 0x29, 0xE7, 0x06, 0x80, 0x23, 0x19, 0x88, + /* x */ + 0x3C, 0x25, 0x8E, 0xF3, 0x04, 0x77, 0x67, 0xE7, 0xED, 0xE0, 0xF1, 0xFD, + 0xAA, 0x79, 0xDA, 0xEE, 0x38, 0x41, 0x36, 0x6A, 0x13, 0x2E, 0x16, 0x3A, + 0xCE, 0xD4, 0xED, 0x24, 0x01, 0xDF, 0x9C, 0x6B, 0xDC, 0xDE, 0x98, 0xE8, + 0xE7, 0x07, 0xC0, 0x7A, 0x22, 0x39, 0xB1, 0xB0, 0x97, + /* y */ + 0x53, 0xD7, 0xE0, 0x85, 0x29, 0x54, 0x70, 0x48, 0x12, 0x1E, 0x9C, 0x95, + 0xF3, 0x79, 0x1D, 0xD8, 0x04, 0x96, 0x39, 0x48, 0xF3, 0x4F, 0xAE, 0x7B, + 0xF4, 0x4E, 0xA8, 0x23, 0x65, 0xDC, 0x78, 0x68, 0xFE, 0x57, 0xE4, 0xAE, + 0x2D, 0xE2, 0x11, 0x30, 0x5A, 0x40, 0x71, 0x04, 0xBD, + /* order */ + 0x01, 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28, + 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28, 0x6B, 0xC9, 0xFB, + 0x8F, 0x6B, 0x85, 0xC5, 0x56, 0x89, 0x2C, 0x20, 0xA7, 0xEB, 0x96, 0x4F, + 0xE7, 0x71, 0x9E, 0x74, 0xF4, 0x90, 0x75, 0x8D, 0x3B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 47 * 6]; +} _EC_X9_62_CHAR2_368W1 = { + { + NID_X9_62_characteristic_two_field, 0, 47, 0xFF70 + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + /* a */ + 0x00, 0xE0, 0xD2, 0xEE, 0x25, 0x09, 0x52, 0x06, 0xF5, 0xE2, 0xA4, 0xF9, + 0xED, 0x22, 0x9F, 0x1F, 0x25, 0x6E, 0x79, 0xA0, 0xE2, 0xB4, 0x55, 0x97, + 0x0D, 0x8D, 0x0D, 0x86, 0x5B, 0xD9, 0x47, 0x78, 0xC5, 0x76, 0xD6, 0x2F, + 0x0A, 0xB7, 0x51, 0x9C, 0xCD, 0x2A, 0x1A, 0x90, 0x6A, 0xE3, 0x0D, + /* b */ + 0x00, 0xFC, 0x12, 0x17, 0xD4, 0x32, 0x0A, 0x90, 0x45, 0x2C, 0x76, 0x0A, + 0x58, 0xED, 0xCD, 0x30, 0xC8, 0xDD, 0x06, 0x9B, 0x3C, 0x34, 0x45, 0x38, + 0x37, 0xA3, 0x4E, 0xD5, 0x0C, 0xB5, 0x49, 0x17, 0xE1, 0xC2, 0x11, 0x2D, + 0x84, 0xD1, 0x64, 0xF4, 0x44, 0xF8, 0xF7, 0x47, 0x86, 0x04, 0x6A, + /* x */ + 0x00, 0x10, 0x85, 0xE2, 0x75, 0x53, 0x81, 0xDC, 0xCC, 0xE3, 0xC1, 0x55, + 0x7A, 0xFA, 0x10, 0xC2, 0xF0, 0xC0, 0xC2, 0x82, 0x56, 0x46, 0xC5, 0xB3, + 0x4A, 0x39, 0x4C, 0xBC, 0xFA, 0x8B, 0xC1, 0x6B, 0x22, 0xE7, 0xE7, 0x89, + 0xE9, 0x27, 0xBE, 0x21, 0x6F, 0x02, 0xE1, 0xFB, 0x13, 0x6A, 0x5F, + /* y */ + 0x00, 0x7B, 0x3E, 0xB1, 0xBD, 0xDC, 0xBA, 0x62, 0xD5, 0xD8, 0xB2, 0x05, + 0x9B, 0x52, 0x57, 0x97, 0xFC, 0x73, 0x82, 0x2C, 0x59, 0x05, 0x9C, 0x62, + 0x3A, 0x45, 0xFF, 0x38, 0x43, 0xCE, 0xE8, 0xF8, 0x7C, 0xD1, 0x85, 0x5A, + 0xDA, 0xA8, 0x1E, 0x2A, 0x07, 0x50, 0xB8, 0x0F, 0xDA, 0x23, 0x10, + /* order */ + 0x00, 0x00, 0x01, 0x00, 0x90, 0x51, 0x2D, 0xA9, 0xAF, 0x72, 0xB0, 0x83, + 0x49, 0xD9, 0x8A, 0x5D, 0xD4, 0xC7, 0xB0, 0x53, 0x2E, 0xCA, 0x51, 0xCE, + 0x03, 0xE2, 0xD1, 0x0F, 0x3B, 0x7A, 0xC5, 0x79, 0xBD, 0x87, 0xE9, 0x09, + 0xAE, 0x40, 0xA6, 0xF1, 0x31, 0xE9, 0xCF, 0xCE, 0x5B, 0xD9, 0x67 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 54 * 6]; +} _EC_X9_62_CHAR2_431R1 = { + { + NID_X9_62_characteristic_two_field, 0, 54, 0x2760 + }, + { + /* no seed */ + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x1A, 0x82, 0x7E, 0xF0, 0x0D, 0xD6, 0xFC, 0x0E, 0x23, 0x4C, 0xAF, 0x04, + 0x6C, 0x6A, 0x5D, 0x8A, 0x85, 0x39, 0x5B, 0x23, 0x6C, 0xC4, 0xAD, 0x2C, + 0xF3, 0x2A, 0x0C, 0xAD, 0xBD, 0xC9, 0xDD, 0xF6, 0x20, 0xB0, 0xEB, 0x99, + 0x06, 0xD0, 0x95, 0x7F, 0x6C, 0x6F, 0xEA, 0xCD, 0x61, 0x54, 0x68, 0xDF, + 0x10, 0x4D, 0xE2, 0x96, 0xCD, 0x8F, + /* b */ + 0x10, 0xD9, 0xB4, 0xA3, 0xD9, 0x04, 0x7D, 0x8B, 0x15, 0x43, 0x59, 0xAB, + 0xFB, 0x1B, 0x7F, 0x54, 0x85, 0xB0, 0x4C, 0xEB, 0x86, 0x82, 0x37, 0xDD, + 0xC9, 0xDE, 0xDA, 0x98, 0x2A, 0x67, 0x9A, 0x5A, 0x91, 0x9B, 0x62, 0x6D, + 0x4E, 0x50, 0xA8, 0xDD, 0x73, 0x1B, 0x10, 0x7A, 0x99, 0x62, 0x38, 0x1F, + 0xB5, 0xD8, 0x07, 0xBF, 0x26, 0x18, + /* x */ + 0x12, 0x0F, 0xC0, 0x5D, 0x3C, 0x67, 0xA9, 0x9D, 0xE1, 0x61, 0xD2, 0xF4, + 0x09, 0x26, 0x22, 0xFE, 0xCA, 0x70, 0x1B, 0xE4, 0xF5, 0x0F, 0x47, 0x58, + 0x71, 0x4E, 0x8A, 0x87, 0xBB, 0xF2, 0xA6, 0x58, 0xEF, 0x8C, 0x21, 0xE7, + 0xC5, 0xEF, 0xE9, 0x65, 0x36, 0x1F, 0x6C, 0x29, 0x99, 0xC0, 0xC2, 0x47, + 0xB0, 0xDB, 0xD7, 0x0C, 0xE6, 0xB7, + /* y */ + 0x20, 0xD0, 0xAF, 0x89, 0x03, 0xA9, 0x6F, 0x8D, 0x5F, 0xA2, 0xC2, 0x55, + 0x74, 0x5D, 0x3C, 0x45, 0x1B, 0x30, 0x2C, 0x93, 0x46, 0xD9, 0xB7, 0xE4, + 0x85, 0xE7, 0xBC, 0xE4, 0x1F, 0x6B, 0x59, 0x1F, 0x3E, 0x8F, 0x6A, 0xDD, + 0xCB, 0xB0, 0xBC, 0x4C, 0x2F, 0x94, 0x7A, 0x7D, 0xE1, 0xA8, 0x9B, 0x62, + 0x5D, 0x6A, 0x59, 0x8B, 0x37, 0x60, + /* order */ + 0x00, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, + 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, + 0x34, 0x03, 0x40, 0x34, 0x03, 0x23, 0xC3, 0x13, 0xFA, 0xB5, 0x05, 0x89, + 0x70, 0x3B, 0x5E, 0xC6, 0x8D, 0x35, 0x87, 0xFE, 0xC6, 0x0D, 0x16, 0x1C, + 0xC1, 0x49, 0xC1, 0xAD, 0x4A, 0x91 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 15 * 6]; +} _EC_WTLS_1 = { + { + NID_X9_62_characteristic_two_field, 0, 15, 2 + }, + { + /* no seed */ + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, + /* x */ + 0x01, 0x66, 0x79, 0x79, 0xA4, 0x0B, 0xA4, 0x97, 0xE5, 0xD5, 0xC2, 0x70, + 0x78, 0x06, 0x17, + /* y */ + 0x00, 0xF4, 0x4B, 0x4A, 0xF1, 0xEC, 0xC2, 0x63, 0x0E, 0x08, 0x78, 0x5C, + 0xEB, 0xCC, 0x15, + /* order */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBF, 0x91, 0xAF, + 0x6D, 0xEA, 0x73 + } +}; + +/* IPSec curves */ +/* + * NOTE: The of curves over a extension field of non prime degree is not + * recommended (Weil-descent). As the group order is not a prime this curve + * is not suitable for ECDSA. + */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 20 * 6]; +} _EC_IPSEC_155_ID3 = { + { + NID_X9_62_characteristic_two_field, 0, 20, 3 + }, + { + /* no seed */ + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f, + /* x */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + /* y */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8, + /* order */ + 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xC7, 0xF3, + 0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C + } +}; + +/* + * NOTE: The of curves over a extension field of non prime degree is not + * recommended (Weil-descent). As the group order is not a prime this curve + * is not suitable for ECDSA. + */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 24 * 6]; +} _EC_IPSEC_185_ID4 = { + { + NID_X9_62_characteristic_two_field, 0, 24, 2 + }, + { + /* no seed */ + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xe9, + /* x */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + /* y */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + /* order */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E + } +}; + +#endif + +/* + * These curves were added by Annie Yousar + * For the definition of RFC 5639 curves see + * http://www.ietf.org/rfc/rfc5639.txt These curves are generated verifiable + * at random, nevertheless the seed is omitted as parameter because the + * generation mechanism is different from those defined in ANSI X9.62. + */ + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 20 * 6]; +} _EC_brainpoolP160r1 = { + { + NID_X9_62_prime_field, 0, 20, 1 + }, + { + /* no seed */ + /* p */ + 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, + 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F, + /* a */ + 0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE, 0x61, 0xBA, + 0xDA, 0x74, 0x5D, 0x97, 0xE8, 0xF7, 0xC3, 0x00, + /* b */ + 0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F, 0xAA, 0x2D, + 0xBD, 0xEC, 0x95, 0xC8, 0xD8, 0x67, 0x5E, 0x58, + /* x */ + 0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93, 0x8C, 0x46, + 0x31, 0xEB, 0x5A, 0xF7, 0xBD, 0xBC, 0xDB, 0xC3, + /* y */ + 0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9, 0x47, 0x41, + 0x66, 0x9C, 0x97, 0x63, 0x16, 0xDA, 0x63, 0x21, + /* order */ + 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91, + 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 20 * 6]; +} _EC_brainpoolP160t1 = { + { + NID_X9_62_prime_field, 0, 20, 1 + }, + { + /* no seed */ + /* p */ + 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, + 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F, + /* a */ + 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, + 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0C, + /* b */ + 0x7A, 0x55, 0x6B, 0x6D, 0xAE, 0x53, 0x5B, 0x7B, 0x51, 0xED, 0x2C, 0x4D, + 0x7D, 0xAA, 0x7A, 0x0B, 0x5C, 0x55, 0xF3, 0x80, + /* x */ + 0xB1, 0x99, 0xB1, 0x3B, 0x9B, 0x34, 0xEF, 0xC1, 0x39, 0x7E, 0x64, 0xBA, + 0xEB, 0x05, 0xAC, 0xC2, 0x65, 0xFF, 0x23, 0x78, + /* y */ + 0xAD, 0xD6, 0x71, 0x8B, 0x7C, 0x7C, 0x19, 0x61, 0xF0, 0x99, 0x1B, 0x84, + 0x24, 0x43, 0x77, 0x21, 0x52, 0xC9, 0xE0, 0xAD, + /* order */ + 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91, + 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 24 * 6]; +} _EC_brainpoolP192r1 = { + { + NID_X9_62_prime_field, 0, 24, 1 + }, + { + /* no seed */ + /* p */ + 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, + 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97, + /* a */ + 0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39, 0xC0, 0x31, + 0xFE, 0x86, 0x85, 0xC1, 0xCA, 0xE0, 0x40, 0xE5, 0xC6, 0x9A, 0x28, 0xEF, + /* b */ + 0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72, 0x1D, 0x04, + 0x4F, 0x44, 0x96, 0xBC, 0xCA, 0x7E, 0xF4, 0x14, 0x6F, 0xBF, 0x25, 0xC9, + /* x */ + 0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0, 0x33, 0xC5, + 0x6C, 0xB0, 0xF0, 0x90, 0x0A, 0x2F, 0x5C, 0x48, 0x53, 0x37, 0x5F, 0xD6, + /* y */ + 0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F, 0x48, 0x28, + 0xC1, 0x49, 0x00, 0x02, 0xE6, 0x77, 0x3F, 0xA2, 0xFA, 0x29, 0x9B, 0x8F, + /* order */ + 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F, + 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 24 * 6]; +} _EC_brainpoolP192t1 = { + { + NID_X9_62_prime_field, 0, 24, 1 + }, + { + /* no seed */ + /* p */ + 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, + 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97, + /* a */ + 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, + 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x94, + /* b */ + 0x13, 0xD5, 0x6F, 0xFA, 0xEC, 0x78, 0x68, 0x1E, 0x68, 0xF9, 0xDE, 0xB4, + 0x3B, 0x35, 0xBE, 0xC2, 0xFB, 0x68, 0x54, 0x2E, 0x27, 0x89, 0x7B, 0x79, + /* x */ + 0x3A, 0xE9, 0xE5, 0x8C, 0x82, 0xF6, 0x3C, 0x30, 0x28, 0x2E, 0x1F, 0xE7, + 0xBB, 0xF4, 0x3F, 0xA7, 0x2C, 0x44, 0x6A, 0xF6, 0xF4, 0x61, 0x81, 0x29, + /* y */ + 0x09, 0x7E, 0x2C, 0x56, 0x67, 0xC2, 0x22, 0x3A, 0x90, 0x2A, 0xB5, 0xCA, + 0x44, 0x9D, 0x00, 0x84, 0xB7, 0xE5, 0xB3, 0xDE, 0x7C, 0xCC, 0x01, 0xC9, + /* order */ + 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F, + 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 28 * 6]; +} _EC_brainpoolP224r1 = { + { + NID_X9_62_prime_field, 0, 28, 1 + }, + { + /* no seed */ + /* p */ + 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, + 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, + 0x7E, 0xC8, 0xC0, 0xFF, + /* a */ + 0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98, 0x03, 0xA6, + 0xC1, 0x53, 0x0B, 0x51, 0x4E, 0x18, 0x2A, 0xD8, 0xB0, 0x04, 0x2A, 0x59, + 0xCA, 0xD2, 0x9F, 0x43, + /* b */ + 0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07, 0x13, 0xB1, + 0xA9, 0x23, 0x69, 0xE3, 0x3E, 0x21, 0x35, 0xD2, 0x66, 0xDB, 0xB3, 0x72, + 0x38, 0x6C, 0x40, 0x0B, + /* x */ + 0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08, 0x23, 0xB2, + 0xA8, 0x7D, 0xC6, 0x8C, 0x9E, 0x4C, 0xE3, 0x17, 0x4C, 0x1E, 0x6E, 0xFD, + 0xEE, 0x12, 0xC0, 0x7D, + /* y */ + 0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6, 0xB8, 0x9E, + 0x4E, 0xCD, 0xAC, 0x24, 0x35, 0x4B, 0x9E, 0x99, 0xCA, 0xA3, 0xF6, 0xD3, + 0x76, 0x14, 0x02, 0xCD, + /* order */ + 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, + 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3, + 0xA5, 0xA7, 0x93, 0x9F + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 28 * 6]; +} _EC_brainpoolP224t1 = { + { + NID_X9_62_prime_field, 0, 28, 1 + }, + { + /* no seed */ + /* p */ + 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, + 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, + 0x7E, 0xC8, 0xC0, 0xFF, + /* a */ + 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, + 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, + 0x7E, 0xC8, 0xC0, 0xFC, + /* b */ + 0x4B, 0x33, 0x7D, 0x93, 0x41, 0x04, 0xCD, 0x7B, 0xEF, 0x27, 0x1B, 0xF6, + 0x0C, 0xED, 0x1E, 0xD2, 0x0D, 0xA1, 0x4C, 0x08, 0xB3, 0xBB, 0x64, 0xF1, + 0x8A, 0x60, 0x88, 0x8D, + /* x */ + 0x6A, 0xB1, 0xE3, 0x44, 0xCE, 0x25, 0xFF, 0x38, 0x96, 0x42, 0x4E, 0x7F, + 0xFE, 0x14, 0x76, 0x2E, 0xCB, 0x49, 0xF8, 0x92, 0x8A, 0xC0, 0xC7, 0x60, + 0x29, 0xB4, 0xD5, 0x80, + /* y */ + 0x03, 0x74, 0xE9, 0xF5, 0x14, 0x3E, 0x56, 0x8C, 0xD2, 0x3F, 0x3F, 0x4D, + 0x7C, 0x0D, 0x4B, 0x1E, 0x41, 0xC8, 0xCC, 0x0D, 0x1C, 0x6A, 0xBD, 0x5F, + 0x1A, 0x46, 0xDB, 0x4C, + /* order */ + 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, + 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3, + 0xA5, 0xA7, 0x93, 0x9F + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 32 * 6]; +} _EC_brainpoolP256r1 = { + { + NID_X9_62_prime_field, 0, 32, 1 + }, + { + /* no seed */ + /* p */ + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, + 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, + 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77, + /* a */ + 0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, 0x75, 0x30, + 0x41, 0x7A, 0xFF, 0xE7, 0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C, + 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9, + /* b */ + 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9, + 0xBB, 0xD7, 0x7C, 0xBF, 0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE, + 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6, + /* x */ + 0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, 0x48, 0x2F, + 0xFC, 0x81, 0xB7, 0xAF, 0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2, + 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62, + /* y */ + 0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, 0x46, 0x1A, + 0x14, 0x61, 0x1D, 0xC9, 0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54, + 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97, + /* order */ + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, + 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, + 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 32 * 6]; +} _EC_brainpoolP256t1 = { + { + NID_X9_62_prime_field, 0, 32, 1 + }, + { + /* no seed */ + /* p */ + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, + 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, + 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77, + /* a */ + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, + 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, + 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x74, + /* b */ + 0x66, 0x2C, 0x61, 0xC4, 0x30, 0xD8, 0x4E, 0xA4, 0xFE, 0x66, 0xA7, 0x73, + 0x3D, 0x0B, 0x76, 0xB7, 0xBF, 0x93, 0xEB, 0xC4, 0xAF, 0x2F, 0x49, 0x25, + 0x6A, 0xE5, 0x81, 0x01, 0xFE, 0xE9, 0x2B, 0x04, + /* x */ + 0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7, 0x73, 0x22, 0x13, 0xB2, + 0x3A, 0x65, 0x61, 0x49, 0xAF, 0xA1, 0x42, 0xC4, 0x7A, 0xAF, 0xBC, 0x2B, + 0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13, 0x05, 0xF4, + /* y */ + 0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D, 0x7F, 0x7B, 0x22, 0xE1, + 0x46, 0x44, 0x41, 0x7E, 0x69, 0xBC, 0xB6, 0xDE, 0x39, 0xD0, 0x27, 0x00, + 0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25, 0xC9, 0xBE, + /* order */ + 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, + 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, + 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 40 * 6]; +} _EC_brainpoolP320r1 = { + { + NID_X9_62_prime_field, 0, 40, 1 + }, + { + /* no seed */ + /* p */ + 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, + 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, + 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, + 0xF1, 0xB3, 0x2E, 0x27, + /* a */ + 0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC, 0xEB, 0xD4, + 0x6D, 0x3F, 0x3B, 0xB8, 0xA2, 0xA7, 0x35, 0x13, 0xF5, 0xEB, 0x79, 0xDA, + 0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF, 0xA9, 0xF4, 0x92, 0xF3, 0x75, 0xA9, + 0x7D, 0x86, 0x0E, 0xB4, + /* b */ + 0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD, 0x19, 0x86, + 0x40, 0x68, 0x8A, 0x6F, 0xE1, 0x3F, 0x41, 0x34, 0x95, 0x54, 0xB4, 0x9A, + 0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45, 0x39, 0x81, 0x6F, 0x5E, 0xB4, 0xAC, + 0x8F, 0xB1, 0xF1, 0xA6, + /* x */ + 0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89, 0xBC, 0xC4, + 0x8E, 0xE5, 0xBF, 0xE6, 0xF2, 0x01, 0x37, 0xD1, 0x0A, 0x08, 0x7E, 0xB6, + 0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5, 0x99, 0xC7, 0x10, 0xAF, 0x8D, 0x0D, + 0x39, 0xE2, 0x06, 0x11, + /* y */ + 0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40, 0x93, 0x24, + 0x7F, 0x77, 0x27, 0x5E, 0x07, 0x43, 0xFF, 0xED, 0x11, 0x71, 0x82, 0xEA, + 0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC, 0x6A, 0xC7, 0xD3, 0x52, 0x45, 0xD1, + 0x69, 0x2E, 0x8E, 0xE1, + /* order */ + 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, + 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3, + 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, + 0x44, 0xC5, 0x93, 0x11 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 40 * 6]; +} _EC_brainpoolP320t1 = { + { + NID_X9_62_prime_field, 0, 40, 1 + }, + { + /* no seed */ + /* p */ + 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, + 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, + 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, + 0xF1, 0xB3, 0x2E, 0x27, + /* a */ + 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, + 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, + 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, + 0xF1, 0xB3, 0x2E, 0x24, + /* b */ + 0xA7, 0xF5, 0x61, 0xE0, 0x38, 0xEB, 0x1E, 0xD5, 0x60, 0xB3, 0xD1, 0x47, + 0xDB, 0x78, 0x20, 0x13, 0x06, 0x4C, 0x19, 0xF2, 0x7E, 0xD2, 0x7C, 0x67, + 0x80, 0xAA, 0xF7, 0x7F, 0xB8, 0xA5, 0x47, 0xCE, 0xB5, 0xB4, 0xFE, 0xF4, + 0x22, 0x34, 0x03, 0x53, + /* x */ + 0x92, 0x5B, 0xE9, 0xFB, 0x01, 0xAF, 0xC6, 0xFB, 0x4D, 0x3E, 0x7D, 0x49, + 0x90, 0x01, 0x0F, 0x81, 0x34, 0x08, 0xAB, 0x10, 0x6C, 0x4F, 0x09, 0xCB, + 0x7E, 0xE0, 0x78, 0x68, 0xCC, 0x13, 0x6F, 0xFF, 0x33, 0x57, 0xF6, 0x24, + 0xA2, 0x1B, 0xED, 0x52, + /* y */ + 0x63, 0xBA, 0x3A, 0x7A, 0x27, 0x48, 0x3E, 0xBF, 0x66, 0x71, 0xDB, 0xEF, + 0x7A, 0xBB, 0x30, 0xEB, 0xEE, 0x08, 0x4E, 0x58, 0xA0, 0xB0, 0x77, 0xAD, + 0x42, 0xA5, 0xA0, 0x98, 0x9D, 0x1E, 0xE7, 0x1B, 0x1B, 0x9B, 0xC0, 0x45, + 0x5F, 0xB0, 0xD2, 0xC3, + /* order */ + 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, + 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3, + 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, + 0x44, 0xC5, 0x93, 0x11 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 48 * 6]; +} _EC_brainpoolP384r1 = { + { + NID_X9_62_prime_field, 0, 48, 1 + }, + { + /* no seed */ + /* p */ + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, + 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, + 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, + 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53, + /* a */ + 0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, 0x08, 0x0A, + 0xCE, 0x05, 0xAF, 0xA0, 0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87, + 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F, 0x8A, 0xA5, 0x81, 0x4A, + 0x50, 0x3A, 0xD4, 0xEB, 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, + /* b */ + 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, 0xB5, 0x54, + 0x16, 0xF0, 0x44, 0x7C, 0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6, + 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5, 0x7C, 0xB4, 0x39, 0x02, + 0x95, 0xDB, 0xC9, 0x94, 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11, + /* x */ + 0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, 0x3A, 0x81, + 0xB7, 0xC1, 0x3F, 0x6B, 0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3, + 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8, 0xE8, 0x26, 0xE0, 0x34, + 0x36, 0xD6, 0x46, 0xAA, 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E, + /* y */ + 0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, 0xEB, 0x8E, + 0x95, 0xCF, 0xD5, 0x52, 0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64, + 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28, 0x0E, 0x46, 0x46, 0x21, + 0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15, + /* order */ + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, + 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, + 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, + 0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 48 * 6]; +} _EC_brainpoolP384t1 = { + { + NID_X9_62_prime_field, 0, 48, 1 + }, + { + /* no seed */ + /* p */ + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, + 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, + 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, + 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53, + /* a */ + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, + 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, + 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, + 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x50, + /* b */ + 0x7F, 0x51, 0x9E, 0xAD, 0xA7, 0xBD, 0xA8, 0x1B, 0xD8, 0x26, 0xDB, 0xA6, + 0x47, 0x91, 0x0F, 0x8C, 0x4B, 0x93, 0x46, 0xED, 0x8C, 0xCD, 0xC6, 0x4E, + 0x4B, 0x1A, 0xBD, 0x11, 0x75, 0x6D, 0xCE, 0x1D, 0x20, 0x74, 0xAA, 0x26, + 0x3B, 0x88, 0x80, 0x5C, 0xED, 0x70, 0x35, 0x5A, 0x33, 0xB4, 0x71, 0xEE, + /* x */ + 0x18, 0xDE, 0x98, 0xB0, 0x2D, 0xB9, 0xA3, 0x06, 0xF2, 0xAF, 0xCD, 0x72, + 0x35, 0xF7, 0x2A, 0x81, 0x9B, 0x80, 0xAB, 0x12, 0xEB, 0xD6, 0x53, 0x17, + 0x24, 0x76, 0xFE, 0xCD, 0x46, 0x2A, 0xAB, 0xFF, 0xC4, 0xFF, 0x19, 0x1B, + 0x94, 0x6A, 0x5F, 0x54, 0xD8, 0xD0, 0xAA, 0x2F, 0x41, 0x88, 0x08, 0xCC, + /* y */ + 0x25, 0xAB, 0x05, 0x69, 0x62, 0xD3, 0x06, 0x51, 0xA1, 0x14, 0xAF, 0xD2, + 0x75, 0x5A, 0xD3, 0x36, 0x74, 0x7F, 0x93, 0x47, 0x5B, 0x7A, 0x1F, 0xCA, + 0x3B, 0x88, 0xF2, 0xB6, 0xA2, 0x08, 0xCC, 0xFE, 0x46, 0x94, 0x08, 0x58, + 0x4D, 0xC2, 0xB2, 0x91, 0x26, 0x75, 0xBF, 0x5B, 0x9E, 0x58, 0x29, 0x28, + /* order */ + 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, + 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, + 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, + 0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 64 * 6]; +} _EC_brainpoolP512r1 = { + { + NID_X9_62_prime_field, 0, 64, 1 + }, + { + /* no seed */ + /* p */ + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, + 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, + 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, + 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, + 0x58, 0x3A, 0x48, 0xF3, + /* a */ + 0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, 0x71, 0x45, + 0xAC, 0x23, 0x4C, 0xC5, 0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10, + 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, + 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, + 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, + 0x77, 0xFC, 0x94, 0xCA, + /* b */ + 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, + 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, + 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, + 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67, + 0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63, + 0x80, 0x16, 0xF7, 0x23, + /* x */ + 0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, 0x32, 0x2E, + 0x9C, 0x4C, 0x6A, 0x93, 0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1, + 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E, 0xFF, 0x3B, 0x1F, 0x78, + 0xE2, 0xD0, 0xD4, 0x8D, 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F, + 0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09, + 0xBC, 0xB9, 0xF8, 0x22, + /* y */ + 0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, 0xBF, 0xA9, + 0xCF, 0x78, 0x22, 0xFD, 0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A, + 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11, 0xB2, 0xDC, 0xDE, 0x49, + 0x4A, 0x5F, 0x48, 0x5E, 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE, + 0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F, + 0x3A, 0xD8, 0x08, 0x92, + /* order */ + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, + 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, + 0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, + 0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82, + 0x9C, 0xA9, 0x00, 0x69 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 64 * 6]; +} _EC_brainpoolP512t1 = { + { + NID_X9_62_prime_field, 0, 64, 1 + }, + { + /* no seed */ + /* p */ + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, + 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, + 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, + 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, + 0x58, 0x3A, 0x48, 0xF3, + /* a */ + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, + 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, + 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, + 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, + 0x58, 0x3A, 0x48, 0xF0, + /* b */ + 0x7C, 0xBB, 0xBC, 0xF9, 0x44, 0x1C, 0xFA, 0xB7, 0x6E, 0x18, 0x90, 0xE4, + 0x68, 0x84, 0xEA, 0xE3, 0x21, 0xF7, 0x0C, 0x0B, 0xCB, 0x49, 0x81, 0x52, + 0x78, 0x97, 0x50, 0x4B, 0xEC, 0x3E, 0x36, 0xA6, 0x2B, 0xCD, 0xFA, 0x23, + 0x04, 0x97, 0x65, 0x40, 0xF6, 0x45, 0x00, 0x85, 0xF2, 0xDA, 0xE1, 0x45, + 0xC2, 0x25, 0x53, 0xB4, 0x65, 0x76, 0x36, 0x89, 0x18, 0x0E, 0xA2, 0x57, + 0x18, 0x67, 0x42, 0x3E, + /* x */ + 0x64, 0x0E, 0xCE, 0x5C, 0x12, 0x78, 0x87, 0x17, 0xB9, 0xC1, 0xBA, 0x06, + 0xCB, 0xC2, 0xA6, 0xFE, 0xBA, 0x85, 0x84, 0x24, 0x58, 0xC5, 0x6D, 0xDE, + 0x9D, 0xB1, 0x75, 0x8D, 0x39, 0xC0, 0x31, 0x3D, 0x82, 0xBA, 0x51, 0x73, + 0x5C, 0xDB, 0x3E, 0xA4, 0x99, 0xAA, 0x77, 0xA7, 0xD6, 0x94, 0x3A, 0x64, + 0xF7, 0xA3, 0xF2, 0x5F, 0xE2, 0x6F, 0x06, 0xB5, 0x1B, 0xAA, 0x26, 0x96, + 0xFA, 0x90, 0x35, 0xDA, + /* y */ + 0x5B, 0x53, 0x4B, 0xD5, 0x95, 0xF5, 0xAF, 0x0F, 0xA2, 0xC8, 0x92, 0x37, + 0x6C, 0x84, 0xAC, 0xE1, 0xBB, 0x4E, 0x30, 0x19, 0xB7, 0x16, 0x34, 0xC0, + 0x11, 0x31, 0x15, 0x9C, 0xAE, 0x03, 0xCE, 0xE9, 0xD9, 0x93, 0x21, 0x84, + 0xBE, 0xEF, 0x21, 0x6B, 0xD7, 0x1D, 0xF2, 0xDA, 0xDF, 0x86, 0xA6, 0x27, + 0x30, 0x6E, 0xCF, 0xF9, 0x6D, 0xBB, 0x8B, 0xAC, 0xE1, 0x98, 0xB6, 0x1E, + 0x00, 0xF8, 0xB3, 0x32, + /* order */ + 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, + 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, + 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, + 0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, + 0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82, + 0x9C, 0xA9, 0x00, 0x69 + } +}; + +typedef struct _ec_list_element_st { + int nid; + const EC_CURVE_DATA *data; + const EC_METHOD *(*meth) (void); + const char *comment; +} ec_list_element; + +static const ec_list_element curve_list[] = { + /* prime field curves */ + /* secg curves */ + {NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, + "SECG/WTLS curve over a 112 bit prime field"}, + {NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, + "SECG curve over a 112 bit prime field"}, + {NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, + "SECG curve over a 128 bit prime field"}, + {NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, + "SECG curve over a 128 bit prime field"}, + {NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, + "SECG curve over a 160 bit prime field"}, + {NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, + "SECG curve over a 160 bit prime field"}, + {NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, + "SECG/WTLS curve over a 160 bit prime field"}, + /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ + {NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, + "SECG curve over a 192 bit prime field"}, + {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, + "SECG curve over a 224 bit prime field"}, +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, + "NIST/SECG curve over a 224 bit prime field"}, +#else + {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, + "NIST/SECG curve over a 224 bit prime field"}, +#endif + {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, + "SECG curve over a 256 bit prime field"}, + /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ + {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, + "NIST/SECG curve over a 384 bit prime field"}, +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, + "NIST/SECG curve over a 521 bit prime field"}, +#else + {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, + "NIST/SECG curve over a 521 bit prime field"}, +#endif + /* X9.62 curves */ + {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, + "NIST/X9.62/SECG curve over a 192 bit prime field"}, + {NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, + "X9.62 curve over a 192 bit prime field"}, + {NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, + "X9.62 curve over a 192 bit prime field"}, + {NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, + "X9.62 curve over a 239 bit prime field"}, + {NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, + "X9.62 curve over a 239 bit prime field"}, + {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, + "X9.62 curve over a 239 bit prime field"}, + {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, +#if defined(ECP_NISTZ256_ASM) + EC_GFp_nistz256_method, +#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) + EC_GFp_nistp256_method, +#else + 0, +#endif + "X9.62/SECG curve over a 256 bit prime field"}, +#ifndef OPENSSL_NO_EC2M + /* characteristic two field curves */ + /* NIST/SECG curves */ + {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, + "SECG curve over a 113 bit binary field"}, + {NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, + "SECG curve over a 113 bit binary field"}, + {NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, + "SECG/WTLS curve over a 131 bit binary field"}, + {NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, + "SECG curve over a 131 bit binary field"}, + {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, + "NIST/SECG/WTLS curve over a 163 bit binary field"}, + {NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, + "SECG curve over a 163 bit binary field"}, + {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, + "NIST/SECG curve over a 163 bit binary field"}, + {NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, + "SECG curve over a 193 bit binary field"}, + {NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, + "SECG curve over a 193 bit binary field"}, + {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, + "SECG curve over a 239 bit binary field"}, + {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, + "NIST/SECG curve over a 283 bit binary field"}, + {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, + "NIST/SECG curve over a 283 bit binary field"}, + {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, + "NIST/SECG curve over a 409 bit binary field"}, + {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, + "NIST/SECG curve over a 409 bit binary field"}, + {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, + "NIST/SECG curve over a 571 bit binary field"}, + {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, + "NIST/SECG curve over a 571 bit binary field"}, + /* X9.62 curves */ + {NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, + "X9.62 curve over a 163 bit binary field"}, + {NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, + "X9.62 curve over a 163 bit binary field"}, + {NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, + "X9.62 curve over a 163 bit binary field"}, + {NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, + "X9.62 curve over a 176 bit binary field"}, + {NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, + "X9.62 curve over a 191 bit binary field"}, + {NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, + "X9.62 curve over a 191 bit binary field"}, + {NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, + "X9.62 curve over a 191 bit binary field"}, + {NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, + "X9.62 curve over a 208 bit binary field"}, + {NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, + "X9.62 curve over a 239 bit binary field"}, + {NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, + "X9.62 curve over a 239 bit binary field"}, + {NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, + "X9.62 curve over a 239 bit binary field"}, + {NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, + "X9.62 curve over a 272 bit binary field"}, + {NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, + "X9.62 curve over a 304 bit binary field"}, + {NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, + "X9.62 curve over a 359 bit binary field"}, + {NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, + "X9.62 curve over a 368 bit binary field"}, + {NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, + "X9.62 curve over a 431 bit binary field"}, + /* + * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves + * from X9.62] + */ + {NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, + "WTLS curve over a 113 bit binary field"}, + {NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, + "NIST/SECG/WTLS curve over a 163 bit binary field"}, + {NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, + "SECG curve over a 113 bit binary field"}, + {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, + "X9.62 curve over a 163 bit binary field"}, +#endif + {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, + "SECG/WTLS curve over a 112 bit prime field"}, + {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, + "SECG/WTLS curve over a 160 bit prime field"}, + {NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, + "WTLS curve over a 112 bit prime field"}, + {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, + "WTLS curve over a 160 bit prime field"}, +#ifndef OPENSSL_NO_EC2M + {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, +#endif + {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, + "WTLS curvs over a 224 bit prime field"}, +#ifndef OPENSSL_NO_EC2M + /* IPSec curves */ + {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, + "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" + "\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, + {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, + "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" + "\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, +#endif + /* brainpool curves */ + {NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0, + "RFC 5639 curve over a 160 bit prime field"}, + {NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0, + "RFC 5639 curve over a 160 bit prime field"}, + {NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0, + "RFC 5639 curve over a 192 bit prime field"}, + {NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0, + "RFC 5639 curve over a 192 bit prime field"}, + {NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0, + "RFC 5639 curve over a 224 bit prime field"}, + {NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0, + "RFC 5639 curve over a 224 bit prime field"}, + {NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0, + "RFC 5639 curve over a 256 bit prime field"}, + {NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0, + "RFC 5639 curve over a 256 bit prime field"}, + {NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0, + "RFC 5639 curve over a 320 bit prime field"}, + {NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0, + "RFC 5639 curve over a 320 bit prime field"}, + {NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0, + "RFC 5639 curve over a 384 bit prime field"}, + {NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0, + "RFC 5639 curve over a 384 bit prime field"}, + {NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0, + "RFC 5639 curve over a 512 bit prime field"}, + {NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0, + "RFC 5639 curve over a 512 bit prime field"}, +}; + +#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element)) + +static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) +{ + EC_GROUP *group = NULL; + EC_POINT *P = NULL; + BN_CTX *ctx = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = + NULL; + int ok = 0; + int seed_len, param_len; + const EC_METHOD *meth; + const EC_CURVE_DATA *data; + const unsigned char *params; + + if ((ctx = BN_CTX_new()) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); + goto err; + } + + data = curve.data; + seed_len = data->seed_len; + param_len = data->param_len; + params = (const unsigned char *)(data + 1); /* skip header */ + params += seed_len; /* skip seed */ + + if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) + || !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) + || !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + + if (curve.meth != 0) { + meth = curve.meth(); + if (((group = EC_GROUP_new(meth)) == NULL) || + (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } else if (data->field_type == NID_X9_62_prime_field) { + if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* field_type == + * NID_X9_62_characteristic_two_field */ + + if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } +#endif + + if ((P = EC_POINT_new(group)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + + if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) + || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) + || !BN_set_word(x, (BN_ULONG)data->cofactor)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + if (!EC_GROUP_set_generator(group, P, order, x)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + if (seed_len) { + if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } + ok = 1; + err: + if (!ok) { + EC_GROUP_free(group); + group = NULL; + } + if (P) + EC_POINT_free(P); + if (ctx) + BN_CTX_free(ctx); + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (order) + BN_free(order); + if (x) + BN_free(x); + if (y) + BN_free(y); + return group; +} + +EC_GROUP *EC_GROUP_new_by_curve_name(int nid) +{ + size_t i; + EC_GROUP *ret = NULL; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ec_group_new_by_curve_name(nid); +#endif + if (nid <= 0) + return NULL; + + for (i = 0; i < curve_list_length; i++) + if (curve_list[i].nid == nid) { + ret = ec_group_new_from_data(curve_list[i]); + break; + } + + if (ret == NULL) { + ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP); + return NULL; + } + + EC_GROUP_set_curve_name(ret, nid); + + return ret; +} + +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) +{ + size_t i, min; + + if (r == NULL || nitems == 0) + return curve_list_length; + + min = nitems < curve_list_length ? nitems : curve_list_length; + + for (i = 0; i < min; i++) { + r[i].nid = curve_list[i].nid; + r[i].comment = curve_list[i].comment; + } + + return curve_list_length; +} + +/* Functions to translate between common NIST curve names and NIDs */ + +typedef struct { + const char *name; /* NIST Name of curve */ + int nid; /* Curve NID */ +} EC_NIST_NAME; + +static EC_NIST_NAME nist_curves[] = { + {"B-163", NID_sect163r2}, + {"B-233", NID_sect233r1}, + {"B-283", NID_sect283r1}, + {"B-409", NID_sect409r1}, + {"B-571", NID_sect571r1}, + {"K-163", NID_sect163k1}, + {"K-233", NID_sect233k1}, + {"K-283", NID_sect283k1}, + {"K-409", NID_sect409k1}, + {"K-571", NID_sect571k1}, + {"P-192", NID_X9_62_prime192v1}, + {"P-224", NID_secp224r1}, + {"P-256", NID_X9_62_prime256v1}, + {"P-384", NID_secp384r1}, + {"P-521", NID_secp521r1} +}; + +const char *EC_curve_nid2nist(int nid) +{ + size_t i; + for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) { + if (nist_curves[i].nid == nid) + return nist_curves[i].name; + } + return NULL; +} + +int EC_curve_nist2nid(const char *name) +{ + size_t i; + for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) { + if (!strcmp(nist_curves[i].name, name)) + return nist_curves[i].nid; + } + return NID_undef; +} +/* crypto/ec/ec_cvt.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +// #include "err.h" +// #include "ec_lcl.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + const EC_METHOD *meth; + EC_GROUP *ret; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ec_group_new_curve_gfp(p, a, b, ctx); +#endif +#if defined(OPENSSL_BN_ASM_MONT) + /* + * This might appear controversial, but the fact is that generic + * prime method was observed to deliver better performance even + * for NIST primes on a range of platforms, e.g.: 60%-15% + * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25% + * in 32-bit build and 35%--12% in 64-bit build on Core2... + * Coefficients are relative to optimized bn_nist.c for most + * intensive ECDSA verify and ECDH operations for 192- and 521- + * bit keys respectively. Choice of these boundary values is + * arguable, because the dependency of improvement coefficient + * from key length is not a "monotone" curve. For example while + * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's + * generally faster, sometimes "respectfully" faster, sometimes + * "tolerably" slower... What effectively happens is that loop + * with bn_mul_add_words is put against bn_mul_mont, and the + * latter "wins" on short vectors. Correct solution should be + * implementing dedicated NxN multiplication subroutines for + * small N. But till it materializes, let's stick to generic + * prime method... + * + */ + meth = EC_GFp_mont_method(); +#else + meth = EC_GFp_nist_method(); +#endif + + ret = EC_GROUP_new(meth); + if (ret == NULL) + return NULL; + + if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { + unsigned long err; + + err = ERR_peek_last_error(); + + if (!(ERR_GET_LIB(err) == ERR_LIB_EC && + ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) || + (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) { + /* real error */ + + EC_GROUP_clear_free(ret); + return NULL; + } + + /* + * not an actual error, we just cannot use EC_GFp_nist_method + */ + + ERR_clear_error(); + + EC_GROUP_clear_free(ret); + meth = EC_GFp_mont_method(); + + ret = EC_GROUP_new(meth); + if (ret == NULL) + return NULL; + + if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { + EC_GROUP_clear_free(ret); + return NULL; + } + } + + return ret; +} + +#ifndef OPENSSL_NO_EC2M +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + const EC_METHOD *meth; + EC_GROUP *ret; + +# ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ec_group_new_curve_gf2m(p, a, b, ctx); +# endif + meth = EC_GF2m_simple_method(); + + ret = EC_GROUP_new(meth); + if (ret == NULL) + return NULL; + + if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) { + EC_GROUP_clear_free(ret); + return NULL; + } + + return ret; +} +#endif +/* crypto/ec/ec_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +// #include "err.h" +// #include "ec.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason) + +static ERR_STRING_DATA EC_str_functs[] = { + {ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"}, + {ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"}, + {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"}, + {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"}, + {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"}, + {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"}, + {ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ECDH_CMS_DECRYPT"}, + {ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ECDH_CMS_SET_SHARED_INFO"}, + {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"}, + {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"}, + {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"}, + {ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"}, + {ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"}, + {ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"}, + {ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"}, + {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"}, + {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"}, + {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"}, + {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"}, + {ERR_FUNC(EC_F_ECP_NISTZ256_GET_AFFINE), "ecp_nistz256_get_affine"}, + {ERR_FUNC(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE), + "ecp_nistz256_mult_precompute"}, + {ERR_FUNC(EC_F_ECP_NISTZ256_POINTS_MUL), "ecp_nistz256_points_mul"}, + {ERR_FUNC(EC_F_ECP_NISTZ256_PRE_COMP_NEW), "ecp_nistz256_pre_comp_new"}, + {ERR_FUNC(EC_F_ECP_NISTZ256_SET_WORDS), "ecp_nistz256_set_words"}, + {ERR_FUNC(EC_F_ECP_NISTZ256_WINDOWED_MUL), "ecp_nistz256_windowed_mul"}, + {ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"}, + {ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"}, + {ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"}, + {ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"}, + {ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"}, + {ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"}, + {ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"}, + {ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"}, + {ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"}, + {ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"}, + {ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"}, + {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), + "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), + "ec_GF2m_simple_group_check_discriminant"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), + "ec_GF2m_simple_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), + "ec_GF2m_simple_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), + "ec_GF2m_simple_point_set_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), + "ec_GF2m_simple_set_compressed_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), + "ec_GFp_mont_field_set_to_one"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), + "ec_GFp_mont_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), + "EC_GFP_MONT_GROUP_SET_CURVE_GFP"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE), + "ec_GFp_nistp224_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES), + "ec_GFp_nistp224_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE), + "ec_GFp_nistp256_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES), + "ec_GFp_nistp256_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE), + "ec_GFp_nistp521_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES), + "ec_GFp_nistp521_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"}, + {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"}, + {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), + "ec_GFp_nist_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), + "ec_GFp_simple_group_check_discriminant"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), + "ec_GFp_simple_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), + "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), + "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), + "ec_GFp_simple_points_make_affine"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), + "ec_GFp_simple_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), + "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), + "ec_GFp_simple_point_set_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), + "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), + "ec_GFp_simple_set_compressed_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), + "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"}, + {ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"}, + {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), + "EC_GROUP_check_discriminant"}, + {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"}, + {ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), + "EC_GROUP_get_pentanomial_basis"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), + "EC_GROUP_get_trinomial_basis"}, + {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"}, + {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"}, + {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"}, + {ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"}, + {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"}, + {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"}, + {ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"}, + {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"}, + {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"}, + {ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"}, + {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"}, + {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"}, + {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"}, + {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"}, + {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES), + "EC_KEY_set_public_key_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"}, + {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, + {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, + {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"}, + {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"}, + {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), + "EC_POINT_get_affine_coordinates_GF2m"}, + {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), + "EC_POINT_get_affine_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), + "EC_POINT_get_Jprojective_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"}, + {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"}, + {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"}, + {ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"}, + {ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"}, + {ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"}, + {ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"}, + {ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"}, + {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), + "EC_POINT_set_affine_coordinates_GF2m"}, + {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), + "EC_POINT_set_affine_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), + "EC_POINT_set_compressed_coordinates_GF2m"}, + {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), + "EC_POINT_set_compressed_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), + "EC_POINT_set_Jprojective_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"}, + {ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"}, + {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"}, + {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"}, + {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"}, + {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"}, + {ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"}, + {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"}, + {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"}, + {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"}, + {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"}, + {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"}, + {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"}, + {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"}, + {ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"}, + {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"}, + {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"}, + {ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"}, + {ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"}, + {ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"}, + {0, NULL} +}; + +static ERR_STRING_DATA EC_str_reasons[] = { + {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"}, + {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"}, + {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"}, + {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"}, + {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE), + "d2i ecpkparameters failure"}, + {ERR_REASON(EC_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"}, + {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), + "ec group new by name failure"}, + {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"}, + {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"}, + {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), + "group2pkparameters failure"}, + {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE), + "i2d ecpkparameters failure"}, + {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"}, + {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"}, + {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"}, + {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"}, + {ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"}, + {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"}, + {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"}, + {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"}, + {ERR_REASON(EC_R_INVALID_FORM), "invalid form"}, + {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"}, + {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, + {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, + {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, + {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, + {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"}, + {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"}, + {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"}, + {ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME), + "not a supported NIST prime"}, + {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"}, + {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"}, + {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"}, + {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"}, + {ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"}, + {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), + "pkparameters2group failure"}, + {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"}, + {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"}, + {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"}, + {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, + {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, + {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, + {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, + {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, + {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, + {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"}, + {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"}, + {0, NULL} +}; + +#endif + +void ERR_load_EC_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(EC_str_functs[0].error) == NULL) { + ERR_load_strings(0, EC_str_functs); + ERR_load_strings(0, EC_str_reasons); + } +#endif +} +/* crypto/ec/ec_key.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions originally developed by SUN MICROSYSTEMS, INC., and + * contributed to the OpenSSL project. + */ + +#include +// #include "ec_lcl.h" +// #include "err.h" +#ifdef OPENSSL_FIPS +# include +#endif + +EC_KEY *EC_KEY_new(void) +{ + EC_KEY *ret; + + ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); + if (ret == NULL) { + ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->version = 1; + ret->flags = 0; + ret->group = NULL; + ret->pub_key = NULL; + ret->priv_key = NULL; + ret->enc_flag = 0; + ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; + ret->references = 1; + ret->method_data = NULL; + return (ret); +} + +EC_KEY *EC_KEY_new_by_curve_name(int nid) +{ + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) + return NULL; + ret->group = EC_GROUP_new_by_curve_name(nid); + if (ret->group == NULL) { + EC_KEY_free(ret); + return NULL; + } + return ret; +} + +void EC_KEY_free(EC_KEY *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); +#ifdef REF_PRINT + REF_PRINT("EC_KEY", r); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "EC_KEY_free, bad reference count\n"); + abort(); + } +#endif + + if (r->group != NULL) + EC_GROUP_free(r->group); + if (r->pub_key != NULL) + EC_POINT_free(r->pub_key); + if (r->priv_key != NULL) + BN_clear_free(r->priv_key); + + EC_EX_DATA_free_all_data(&r->method_data); + + OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); + + OPENSSL_free(r); +} + +EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) +{ + EC_EXTRA_DATA *d; + + if (dest == NULL || src == NULL) { + ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + /* copy the parameters */ + if (src->group) { + const EC_METHOD *meth = EC_GROUP_method_of(src->group); + /* clear the old group */ + if (dest->group) + EC_GROUP_free(dest->group); + dest->group = EC_GROUP_new(meth); + if (dest->group == NULL) + return NULL; + if (!EC_GROUP_copy(dest->group, src->group)) + return NULL; + } + /* copy the public key */ + if (src->pub_key && src->group) { + if (dest->pub_key) + EC_POINT_free(dest->pub_key); + dest->pub_key = EC_POINT_new(src->group); + if (dest->pub_key == NULL) + return NULL; + if (!EC_POINT_copy(dest->pub_key, src->pub_key)) + return NULL; + } + /* copy the private key */ + if (src->priv_key) { + if (dest->priv_key == NULL) { + dest->priv_key = BN_new(); + if (dest->priv_key == NULL) + return NULL; + } + if (!BN_copy(dest->priv_key, src->priv_key)) + return NULL; + } + /* copy method/extra data */ + EC_EX_DATA_free_all_data(&dest->method_data); + + for (d = src->method_data; d != NULL; d = d->next) { + void *t = d->dup_func(d->data); + + if (t == NULL) + return 0; + if (!EC_EX_DATA_set_data + (&dest->method_data, t, d->dup_func, d->free_func, + d->clear_free_func)) + return 0; + } + + /* copy the rest */ + dest->enc_flag = src->enc_flag; + dest->conv_form = src->conv_form; + dest->version = src->version; + dest->flags = src->flags; + + return dest; +} + +EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) +{ + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) + return NULL; + if (EC_KEY_copy(ret, ec_key) == NULL) { + EC_KEY_free(ret); + return NULL; + } + return ret; +} + +int EC_KEY_up_ref(EC_KEY *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); +#ifdef REF_PRINT + REF_PRINT("EC_KEY", r); +#endif +#ifdef REF_CHECK + if (i < 2) { + fprintf(stderr, "EC_KEY_up, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); +} + +int EC_KEY_generate_key(EC_KEY *eckey) +{ + int ok = 0; + BN_CTX *ctx = NULL; + BIGNUM *priv_key = NULL, *order = NULL; + EC_POINT *pub_key = NULL; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ec_key_generate_key(eckey); +#endif + + if (!eckey || !eckey->group) { + ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((order = BN_new()) == NULL) + goto err; + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if (eckey->priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) + goto err; + } else + priv_key = eckey->priv_key; + + if (!EC_GROUP_get_order(eckey->group, order, ctx)) + goto err; + + do + if (!BN_rand_range(priv_key, order)) + goto err; + while (BN_is_zero(priv_key)) ; + + if (eckey->pub_key == NULL) { + pub_key = EC_POINT_new(eckey->group); + if (pub_key == NULL) + goto err; + } else + pub_key = eckey->pub_key; + + if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) + goto err; + + eckey->priv_key = priv_key; + eckey->pub_key = pub_key; + + ok = 1; + + err: + if (order) + BN_free(order); + if (pub_key != NULL && eckey->pub_key == NULL) + EC_POINT_free(pub_key); + if (priv_key != NULL && eckey->priv_key == NULL) + BN_free(priv_key); + if (ctx != NULL) + BN_CTX_free(ctx); + return (ok); +} + +int EC_KEY_check_key(const EC_KEY *eckey) +{ + int ok = 0; + BN_CTX *ctx = NULL; + const BIGNUM *order = NULL; + EC_POINT *point = NULL; + + if (!eckey || !eckey->group || !eckey->pub_key) { + ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); + goto err; + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + if ((point = EC_POINT_new(eckey->group)) == NULL) + goto err; + + /* testing whether the pub_key is on the elliptic curve */ + if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + /* testing whether pub_key * order is the point at infinity */ + order = &eckey->group->order; + if (BN_is_zero(order)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); + goto err; + } + if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); + goto err; + } + if (!EC_POINT_is_at_infinity(eckey->group, point)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); + goto err; + } + /* + * in case the priv_key is present : check if generator * priv_key == + * pub_key + */ + if (eckey->priv_key) { + if (BN_cmp(eckey->priv_key, order) >= 0) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); + goto err; + } + if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, + NULL, NULL, ctx)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); + goto err; + } + } + ok = 1; + err: + if (ctx != NULL) + BN_CTX_free(ctx); + if (point != NULL) + EC_POINT_free(point); + return (ok); +} + +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y) +{ + BN_CTX *ctx = NULL; + BIGNUM *tx, *ty; + EC_POINT *point = NULL; + int ok = 0; +#ifndef OPENSSL_NO_EC2M + int tmp_nid, is_char_two = 0; +#endif + + if (!key || !key->group || !x || !y) { + ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + BN_CTX_start(ctx); + point = EC_POINT_new(key->group); + + if (!point) + goto err; + + tx = BN_CTX_get(ctx); + ty = BN_CTX_get(ctx); + if (ty == NULL) + goto err; + +#ifndef OPENSSL_NO_EC2M + tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group)); + + if (tmp_nid == NID_X9_62_characteristic_two_field) + is_char_two = 1; + + if (is_char_two) { + if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point, + x, y, ctx)) + goto err; + if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point, + tx, ty, ctx)) + goto err; + } else +#endif + { + if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, + x, y, ctx)) + goto err; + if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, + tx, ty, ctx)) + goto err; + } + /* + * Check if retrieved coordinates match originals: if not values are out + * of range. + */ + if (BN_cmp(x, tx) || BN_cmp(y, ty)) { + ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, + EC_R_COORDINATES_OUT_OF_RANGE); + goto err; + } + + if (!EC_KEY_set_public_key(key, point)) + goto err; + + if (EC_KEY_check_key(key) == 0) + goto err; + + ok = 1; + + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(point); + return ok; + +} + +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) +{ + return key->group; +} + +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) +{ + if (key->group != NULL) + EC_GROUP_free(key->group); + key->group = EC_GROUP_dup(group); + return (key->group == NULL) ? 0 : 1; +} + +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) +{ + return key->priv_key; +} + +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) +{ + if (key->priv_key) + BN_clear_free(key->priv_key); + key->priv_key = BN_dup(priv_key); + return (key->priv_key == NULL) ? 0 : 1; +} + +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) +{ + return key->pub_key; +} + +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) +{ + if (key->pub_key != NULL) + EC_POINT_free(key->pub_key); + key->pub_key = EC_POINT_dup(pub_key, key->group); + return (key->pub_key == NULL) ? 0 : 1; +} + +unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) +{ + return key->enc_flag; +} + +void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) +{ + key->enc_flag = flags; +} + +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) +{ + return key->conv_form; +} + +void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) +{ + key->conv_form = cform; + if (key->group != NULL) + EC_GROUP_set_point_conversion_form(key->group, cform); +} + +void *EC_KEY_get_key_method_data(EC_KEY *key, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + void *ret; + + CRYPTO_r_lock(CRYPTO_LOCK_EC); + ret = + EC_EX_DATA_get_data(key->method_data, dup_func, free_func, + clear_free_func); + CRYPTO_r_unlock(CRYPTO_LOCK_EC); + + return ret; +} + +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + EC_EXTRA_DATA *ex_data; + + CRYPTO_w_lock(CRYPTO_LOCK_EC); + ex_data = + EC_EX_DATA_get_data(key->method_data, dup_func, free_func, + clear_free_func); + if (ex_data == NULL) + EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, + clear_free_func); + CRYPTO_w_unlock(CRYPTO_LOCK_EC); + + return ex_data; +} + +void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) +{ + if (key->group != NULL) + EC_GROUP_set_asn1_flag(key->group, flag); +} + +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) +{ + if (key->group == NULL) + return 0; + return EC_GROUP_precompute_mult(key->group, ctx); +} + +int EC_KEY_get_flags(const EC_KEY *key) +{ + return key->flags; +} + +void EC_KEY_set_flags(EC_KEY *key, int flags) +{ + key->flags |= flags; +} + +void EC_KEY_clear_flags(EC_KEY *key, int flags) +{ + key->flags &= ~flags; +} +/* crypto/ec/ec_lib.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Binary polynomial ECC support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +// #include "err.h" +#include "opensslv.h" + +// #include "ec_lcl.h" + +const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; + +/* local function prototypes */ + +static int ec_precompute_mont_data(EC_GROUP *group); + +/* functions for EC_GROUP objects */ + +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) +{ + EC_GROUP *ret; + + if (meth == NULL) { + ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL); + return NULL; + } + if (meth->group_init == 0) { + ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(*ret)); + if (ret == NULL) { + ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = meth; + + ret->extra_data = NULL; + ret->mont_data = NULL; + + ret->generator = NULL; + BN_init(&ret->order); + BN_init(&ret->cofactor); + + ret->curve_name = 0; + ret->asn1_flag = ~EC_GROUP_ASN1_FLAG_MASK; + ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; + + ret->seed = NULL; + ret->seed_len = 0; + + if (!meth->group_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +void EC_GROUP_free(EC_GROUP *group) +{ + if (!group) + return; + + if (group->meth->group_finish != 0) + group->meth->group_finish(group); + + EC_EX_DATA_free_all_data(&group->extra_data); + + if (EC_GROUP_VERSION(group) && group->mont_data) + BN_MONT_CTX_free(group->mont_data); + + if (group->generator != NULL) + EC_POINT_free(group->generator); + BN_free(&group->order); + BN_free(&group->cofactor); + + if (group->seed) + OPENSSL_free(group->seed); + + OPENSSL_free(group); +} + +void EC_GROUP_clear_free(EC_GROUP *group) +{ + if (!group) + return; + + if (group->meth->group_clear_finish != 0) + group->meth->group_clear_finish(group); + else if (group->meth->group_finish != 0) + group->meth->group_finish(group); + + EC_EX_DATA_clear_free_all_data(&group->extra_data); + + if (EC_GROUP_VERSION(group) && group->mont_data) + BN_MONT_CTX_free(group->mont_data); + + if (group->generator != NULL) + EC_POINT_clear_free(group->generator); + BN_clear_free(&group->order); + BN_clear_free(&group->cofactor); + + if (group->seed) { + OPENSSL_cleanse(group->seed, group->seed_len); + OPENSSL_free(group->seed); + } + + OPENSSL_cleanse(group, sizeof(*group)); + OPENSSL_free(group); +} + +int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + EC_EXTRA_DATA *d; + + if (dest->meth->group_copy == 0) { + ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (dest->meth != src->meth) { + ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) + return 1; + + EC_EX_DATA_free_all_data(&dest->extra_data); + + for (d = src->extra_data; d != NULL; d = d->next) { + void *t = d->dup_func(d->data); + + if (t == NULL) + return 0; + if (!EC_EX_DATA_set_data + (&dest->extra_data, t, d->dup_func, d->free_func, + d->clear_free_func)) + return 0; + } + + if (EC_GROUP_VERSION(src) && src->mont_data != NULL) { + if (dest->mont_data == NULL) { + dest->mont_data = BN_MONT_CTX_new(); + if (dest->mont_data == NULL) + return 0; + } + if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) + return 0; + } else { + /* src->generator == NULL */ + if (EC_GROUP_VERSION(dest) && dest->mont_data != NULL) { + BN_MONT_CTX_free(dest->mont_data); + dest->mont_data = NULL; + } + } + + if (src->generator != NULL) { + if (dest->generator == NULL) { + dest->generator = EC_POINT_new(dest); + if (dest->generator == NULL) + return 0; + } + if (!EC_POINT_copy(dest->generator, src->generator)) + return 0; + } else { + /* src->generator == NULL */ + if (dest->generator != NULL) { + EC_POINT_clear_free(dest->generator); + dest->generator = NULL; + } + } + + if (!BN_copy(&dest->order, &src->order)) + return 0; + if (!BN_copy(&dest->cofactor, &src->cofactor)) + return 0; + + dest->curve_name = src->curve_name; + dest->asn1_flag = src->asn1_flag; + dest->asn1_form = src->asn1_form; + + if (src->seed) { + if (dest->seed) + OPENSSL_free(dest->seed); + dest->seed = OPENSSL_malloc(src->seed_len); + if (dest->seed == NULL) + return 0; + if (!memcpy(dest->seed, src->seed, src->seed_len)) + return 0; + dest->seed_len = src->seed_len; + } else { + if (dest->seed) + OPENSSL_free(dest->seed); + dest->seed = NULL; + dest->seed_len = 0; + } + + return dest->meth->group_copy(dest, src); +} + +EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) +{ + EC_GROUP *t = NULL; + int ok = 0; + + if (a == NULL) + return NULL; + + if ((t = EC_GROUP_new(a->meth)) == NULL) + return (NULL); + if (!EC_GROUP_copy(t, a)) + goto err; + + ok = 1; + + err: + if (!ok) { + if (t) + EC_GROUP_free(t); + return NULL; + } else + return t; +} + +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) +{ + return group->meth; +} + +int EC_METHOD_get_field_type(const EC_METHOD *meth) +{ + return meth->field_type; +} + +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor) +{ + if (generator == NULL) { + ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (group->generator == NULL) { + group->generator = EC_POINT_new(group); + if (group->generator == NULL) + return 0; + } + if (!EC_POINT_copy(group->generator, generator)) + return 0; + + if (order != NULL) { + if (!BN_copy(&group->order, order)) + return 0; + } else + BN_zero(&group->order); + + if (cofactor != NULL) { + if (!BN_copy(&group->cofactor, cofactor)) + return 0; + } else + BN_zero(&group->cofactor); + + /*- + * Access to the `mont_data` field of an EC_GROUP struct should always be + * guarded by an EC_GROUP_VERSION(group) check to avoid OOB accesses, as the + * group might come from the FIPS module, which does not define the + * `mont_data` field inside the EC_GROUP structure. + */ + if (EC_GROUP_VERSION(group)) { + /*- + * Some groups have an order with + * factors of two, which makes the Montgomery setup fail. + * |group->mont_data| will be NULL in this case. + */ + if (BN_is_odd(&group->order)) + return ec_precompute_mont_data(group); + + BN_MONT_CTX_free(group->mont_data); + group->mont_data = NULL; + } + + return 1; +} + +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) +{ + return group->generator; +} + +BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) +{ + return EC_GROUP_VERSION(group) ? group->mont_data : NULL; +} + +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) +{ + if (!BN_copy(order, &group->order)) + return 0; + + return !BN_is_zero(order); +} + +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx) +{ + if (!BN_copy(cofactor, &group->cofactor)) + return 0; + + return !BN_is_zero(&group->cofactor); +} + +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid) +{ + group->curve_name = nid; +} + +int EC_GROUP_get_curve_name(const EC_GROUP *group) +{ + return group->curve_name; +} + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) +{ + group->asn1_flag &= ~EC_GROUP_ASN1_FLAG_MASK; + group->asn1_flag |= flag & EC_GROUP_ASN1_FLAG_MASK; +} + +int EC_GROUP_get_asn1_flag(const EC_GROUP *group) +{ + return group->asn1_flag & EC_GROUP_ASN1_FLAG_MASK; +} + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form) +{ + group->asn1_form = form; +} + +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP + *group) +{ + return group->asn1_form; +} + +size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) +{ + if (group->seed) { + OPENSSL_free(group->seed); + group->seed = NULL; + group->seed_len = 0; + } + + if (!len || !p) + return 1; + + if ((group->seed = OPENSSL_malloc(len)) == NULL) + return 0; + memcpy(group->seed, p, len); + group->seed_len = len; + + return len; +} + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group) +{ + return group->seed; +} + +size_t EC_GROUP_get_seed_len(const EC_GROUP *group) +{ + return group->seed_len; +} + +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + if (group->meth->group_set_curve == 0) { + ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_set_curve(group, p, a, b, ctx); +} + +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) +{ + if (group->meth->group_get_curve == 0) { + ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_get_curve(group, p, a, b, ctx); +} + +#ifndef OPENSSL_NO_EC2M +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + if (group->meth->group_set_curve == 0) { + ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_set_curve(group, p, a, b, ctx); +} + +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) +{ + if (group->meth->group_get_curve == 0) { + ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_get_curve(group, p, a, b, ctx); +} +#endif + +int EC_GROUP_get_degree(const EC_GROUP *group) +{ + if (group->meth->group_get_degree == 0) { + ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_get_degree(group); +} + +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) +{ + if (group->meth->group_check_discriminant == 0) { + ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_check_discriminant(group, ctx); +} + +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) +{ + int r = 0; + BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; + BN_CTX *ctx_new = NULL; + + /* compare the field types */ + if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != + EC_METHOD_get_field_type(EC_GROUP_method_of(b))) + return 1; + /* compare the curve name (if present in both) */ + if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && + EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) + return 1; + + if (!ctx) + ctx_new = ctx = BN_CTX_new(); + if (!ctx) + return -1; + + BN_CTX_start(ctx); + a1 = BN_CTX_get(ctx); + a2 = BN_CTX_get(ctx); + a3 = BN_CTX_get(ctx); + b1 = BN_CTX_get(ctx); + b2 = BN_CTX_get(ctx); + b3 = BN_CTX_get(ctx); + if (!b3) { + BN_CTX_end(ctx); + if (ctx_new) + BN_CTX_free(ctx); + return -1; + } + + /* + * XXX This approach assumes that the external representation of curves + * over the same field type is the same. + */ + if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || + !b->meth->group_get_curve(b, b1, b2, b3, ctx)) + r = 1; + + if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) + r = 1; + + /* XXX EC_POINT_cmp() assumes that the methods are equal */ + if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), + EC_GROUP_get0_generator(b), ctx)) + r = 1; + + if (!r) { + /* compare the order and cofactor */ + if (!EC_GROUP_get_order(a, a1, ctx) || + !EC_GROUP_get_order(b, b1, ctx) || + !EC_GROUP_get_cofactor(a, a2, ctx) || + !EC_GROUP_get_cofactor(b, b2, ctx)) { + BN_CTX_end(ctx); + if (ctx_new) + BN_CTX_free(ctx); + return -1; + } + if (BN_cmp(a1, b1) || BN_cmp(a2, b2)) + r = 1; + } + + BN_CTX_end(ctx); + if (ctx_new) + BN_CTX_free(ctx); + + return r; +} + +/* this has 'package' visibility */ +int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + EC_EXTRA_DATA *d; + + if (ex_data == NULL) + return 0; + + for (d = *ex_data; d != NULL; d = d->next) { + if (d->dup_func == dup_func && d->free_func == free_func + && d->clear_free_func == clear_free_func) { + ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL); + return 0; + } + } + + if (data == NULL) + /* no explicit entry needed */ + return 1; + + d = OPENSSL_malloc(sizeof(*d)); + if (d == NULL) + return 0; + + d->data = data; + d->dup_func = dup_func; + d->free_func = free_func; + d->clear_free_func = clear_free_func; + + d->next = *ex_data; + *ex_data = d; + + return 1; +} + +/* this has 'package' visibility */ +void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + const EC_EXTRA_DATA *d; + + for (d = ex_data; d != NULL; d = d->next) { + if (d->dup_func == dup_func && d->free_func == free_func + && d->clear_free_func == clear_free_func) + return d->data; + } + + return NULL; +} + +/* this has 'package' visibility */ +void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + EC_EXTRA_DATA **p; + + if (ex_data == NULL) + return; + + for (p = ex_data; *p != NULL; p = &((*p)->next)) { + if ((*p)->dup_func == dup_func && (*p)->free_func == free_func + && (*p)->clear_free_func == clear_free_func) { + EC_EXTRA_DATA *next = (*p)->next; + + (*p)->free_func((*p)->data); + OPENSSL_free(*p); + + *p = next; + return; + } + } +} + +/* this has 'package' visibility */ +void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + EC_EXTRA_DATA **p; + + if (ex_data == NULL) + return; + + for (p = ex_data; *p != NULL; p = &((*p)->next)) { + if ((*p)->dup_func == dup_func && (*p)->free_func == free_func + && (*p)->clear_free_func == clear_free_func) { + EC_EXTRA_DATA *next = (*p)->next; + + (*p)->clear_free_func((*p)->data); + OPENSSL_free(*p); + + *p = next; + return; + } + } +} + +/* this has 'package' visibility */ +void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data) +{ + EC_EXTRA_DATA *d; + + if (ex_data == NULL) + return; + + d = *ex_data; + while (d) { + EC_EXTRA_DATA *next = d->next; + + d->free_func(d->data); + OPENSSL_free(d); + + d = next; + } + *ex_data = NULL; +} + +/* this has 'package' visibility */ +void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data) +{ + EC_EXTRA_DATA *d; + + if (ex_data == NULL) + return; + + d = *ex_data; + while (d) { + EC_EXTRA_DATA *next = d->next; + + d->clear_free_func(d->data); + OPENSSL_free(d); + + d = next; + } + *ex_data = NULL; +} + +/* functions for EC_POINT objects */ + +EC_POINT *EC_POINT_new(const EC_GROUP *group) +{ + EC_POINT *ret; + + if (group == NULL) { + ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (group->meth->point_init == 0) { + ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(*ret)); + if (ret == NULL) { + ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = group->meth; + + if (!ret->meth->point_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +void EC_POINT_free(EC_POINT *point) +{ + if (!point) + return; + + if (point->meth->point_finish != 0) + point->meth->point_finish(point); + OPENSSL_free(point); +} + +void EC_POINT_clear_free(EC_POINT *point) +{ + if (!point) + return; + + if (point->meth->point_clear_finish != 0) + point->meth->point_clear_finish(point); + else if (point->meth->point_finish != 0) + point->meth->point_finish(point); + OPENSSL_cleanse(point, sizeof(*point)); + OPENSSL_free(point); +} + +int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) +{ + if (dest->meth->point_copy == 0) { + ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (dest->meth != src->meth) { + ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) + return 1; + return dest->meth->point_copy(dest, src); +} + +EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) +{ + EC_POINT *t; + int r; + + if (a == NULL) + return NULL; + + t = EC_POINT_new(group); + if (t == NULL) + return (NULL); + r = EC_POINT_copy(t, a); + if (!r) { + EC_POINT_free(t); + return NULL; + } else + return t; +} + +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) +{ + return point->meth; +} + +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) +{ + if (group->meth->point_set_to_infinity == 0) { + ECerr(EC_F_EC_POINT_SET_TO_INFINITY, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_to_infinity(group, point); +} + +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx) +{ + if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { + ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, + y, z, ctx); +} + +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *ctx) +{ + if (group->meth->point_get_Jprojective_coordinates_GFp == 0) { + ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, + y, z, ctx); +} + +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + if (group->meth->point_set_affine_coordinates == 0) { + ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); +} + +#ifndef OPENSSL_NO_EC2M +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + if (group->meth->point_set_affine_coordinates == 0) { + ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); +} +#endif + +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx) +{ + if (group->meth->point_get_affine_coordinates == 0) { + ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); +} + +#ifndef OPENSSL_NO_EC2M +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx) +{ + if (group->meth->point_get_affine_coordinates == 0) { + ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); +} +#endif + +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + if (group->meth->add == 0) { + ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if ((group->meth != r->meth) || (r->meth != a->meth) + || (a->meth != b->meth)) { + ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->add(group, r, a, b, ctx); +} + +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx) +{ + if (group->meth->dbl == 0) { + ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if ((group->meth != r->meth) || (r->meth != a->meth)) { + ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->dbl(group, r, a, ctx); +} + +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) +{ + if (group->meth->invert == 0) { + ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != a->meth) { + ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->invert(group, a, ctx); +} + +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) +{ + if (group->meth->is_at_infinity == 0) { + ECerr(EC_F_EC_POINT_IS_AT_INFINITY, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->is_at_infinity(group, point); +} + +/* + * Check whether an EC_POINT is on the curve or not. Note that the return + * value for this function should NOT be treated as a boolean. Return values: + * 1: The point is on the curve + * 0: The point is not on the curve + * -1: An error occurred + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) +{ + if (group->meth->is_on_curve == 0) { + ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->is_on_curve(group, point, ctx); +} + +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx) +{ + if (group->meth->point_cmp == 0) { + ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + if ((group->meth != a->meth) || (a->meth != b->meth)) { + ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); + return -1; + } + return group->meth->point_cmp(group, a, b, ctx); +} + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +{ + if (group->meth->make_affine == 0) { + ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->make_affine(group, point, ctx); +} + +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx) +{ + size_t i; + + if (group->meth->points_make_affine == 0) { + ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + for (i = 0; i < num; i++) { + if (group->meth != points[i]->meth) { + ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + } + return group->meth->points_make_affine(group, num, points, ctx); +} + +/* + * Functions for point multiplication. If group->meth->mul is 0, we use the + * wNAF-based implementations in ec_mult.c; otherwise we dispatch through + * methods. + */ + +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + if (group->meth->mul == 0) + /* use default */ + return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + + return group->meth->mul(group, r, scalar, num, points, scalars, ctx); +} + +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) +{ + /* just a convenient interface to EC_POINTs_mul() */ + + const EC_POINT *points[1]; + const BIGNUM *scalars[1]; + + points[0] = point; + scalars[0] = p_scalar; + + return EC_POINTs_mul(group, r, g_scalar, + (point != NULL + && p_scalar != NULL), points, scalars, ctx); +} + +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + if (group->meth->mul == 0) + /* use default */ + return ec_wNAF_precompute_mult(group, ctx); + + if (group->meth->precompute_mult != 0) + return group->meth->precompute_mult(group, ctx); + else + return 1; /* nothing to do, so report success */ +} + +int EC_GROUP_have_precompute_mult(const EC_GROUP *group) +{ + if (group->meth->mul == 0) + /* use default */ + return ec_wNAF_have_precompute_mult(group); + + if (group->meth->have_precompute_mult != 0) + return group->meth->have_precompute_mult(group); + else + return 0; /* cannot tell whether precomputation has + * been performed */ +} + +/*- + * ec_precompute_mont_data sets |group->mont_data| from |group->order| and + * returns one on success. On error it returns zero. + * + * Note: this function must be called only after verifying that + * EC_GROUP_VERSION(group) returns true. + * The reason for this is that access to the `mont_data` field of an EC_GROUP + * struct should always be guarded by an EC_GROUP_VERSION(group) check to avoid + * OOB accesses, as the group might come from the FIPS module, which does not + * define the `mont_data` field inside the EC_GROUP structure. + */ +static +int ec_precompute_mont_data(EC_GROUP *group) +{ + BN_CTX *ctx = BN_CTX_new(); + int ret = 0; + + if (group->mont_data) { + BN_MONT_CTX_free(group->mont_data); + group->mont_data = NULL; + } + + if (ctx == NULL) + goto err; + + group->mont_data = BN_MONT_CTX_new(); + if (!group->mont_data) + goto err; + + if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) { + BN_MONT_CTX_free(group->mont_data); + group->mont_data = NULL; + goto err; + } + + ret = 1; + + err: + + if (ctx) + BN_CTX_free(ctx); + return ret; +} +/* crypto/ec/ec_mult.c */ +/* + * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +// #include "err.h" + +// #include "ec_lcl.h" + +/* + * This file implements the wNAF-based interleaving multi-exponentiation method + * Formerly at: + * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp + * You might now find it here: + * http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13 + * http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf + * For multiplication with precomputation, we use wNAF splitting, formerly at: + * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp + */ + +/* structure for precomputed multiples of the generator */ +typedef struct ec_pre_comp_st { + const EC_GROUP *group; /* parent EC_GROUP object */ + size_t blocksize; /* block size for wNAF splitting */ + size_t numblocks; /* max. number of blocks for which we have + * precomputation */ + size_t w; /* window size */ + EC_POINT **points; /* array with pre-calculated multiples of + * generator: 'num' pointers to EC_POINT + * objects followed by a NULL */ + size_t num; /* numblocks * 2^(w-1) */ + int references; +} EC_PRE_COMP; + +/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */ +static void *ec_pre_comp_dup(void *); +static void ec_pre_comp_free(void *); +static void ec_pre_comp_clear_free(void *); + +static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) +{ + EC_PRE_COMP *ret = NULL; + + if (!group) + return NULL; + + ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP)); + if (!ret) { + ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + return ret; + } + ret->group = group; + ret->blocksize = 8; /* default */ + ret->numblocks = 0; + ret->w = 4; /* default */ + ret->points = NULL; + ret->num = 0; + ret->references = 1; + return ret; +} + +static void *ec_pre_comp_dup(void *src_) +{ + EC_PRE_COMP *src = src_; + + /* no need to actually copy, these objects never change! */ + + CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + + return src_; +} + +static void ec_pre_comp_free(void *pre_) +{ + int i; + EC_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + if (pre->points) { + EC_POINT **p; + + for (p = pre->points; *p != NULL; p++) + EC_POINT_free(*p); + OPENSSL_free(pre->points); + } + OPENSSL_free(pre); +} + +static void ec_pre_comp_clear_free(void *pre_) +{ + int i; + EC_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + if (pre->points) { + EC_POINT **p; + + for (p = pre->points; *p != NULL; p++) { + EC_POINT_clear_free(*p); + OPENSSL_cleanse(p, sizeof(*p)); + } + OPENSSL_free(pre->points); + } + OPENSSL_cleanse(pre, sizeof(*pre)); + OPENSSL_free(pre); +} + +/*- + * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. + * This is an array r[] of values that are either zero or odd with an + * absolute value less than 2^w satisfying + * scalar = \sum_j r[j]*2^j + * where at most one of any w+1 consecutive digits is non-zero + * with the exception that the most significant digit may be only + * w-1 zeros away from that next non-zero digit. + */ +static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) +{ + int window_val; + int ok = 0; + signed char *r = NULL; + int sign = 1; + int bit, next_bit, mask; + size_t len = 0, j; + + if (BN_is_zero(scalar)) { + r = OPENSSL_malloc(1); + if (!r) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); + goto err; + } + r[0] = 0; + *ret_len = 1; + return r; + } + + if (w <= 0 || w > 7) { /* 'signed char' can represent integers with + * absolute values less than 2^7 */ + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + bit = 1 << w; /* at most 128 */ + next_bit = bit << 1; /* at most 256 */ + mask = next_bit - 1; /* at most 255 */ + + if (BN_is_negative(scalar)) { + sign = -1; + } + + if (scalar->d == NULL || scalar->top == 0) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + + len = BN_num_bits(scalar); + r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer + * than binary representation (*ret_len will + * be set to the actual length, i.e. at most + * BN_num_bits(scalar) + 1) */ + if (r == NULL) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); + goto err; + } + window_val = scalar->d[0] & mask; + j = 0; + while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len, + * window_val will not + * increase */ + int digit = 0; + + /* 0 <= window_val <= 2^(w+1) */ + + if (window_val & 1) { + /* 0 < window_val < 2^(w+1) */ + + if (window_val & bit) { + digit = window_val - next_bit; /* -2^w < digit < 0 */ + +#if 1 /* modified wNAF */ + if (j + w + 1 >= len) { + /* + * special case for generating modified wNAFs: no new + * bits will be added into window_val, so using a + * positive digit here will decrease the total length of + * the representation + */ + + digit = window_val & (mask >> 1); /* 0 < digit < 2^w */ + } +#endif + } else { + digit = window_val; /* 0 < digit < 2^w */ + } + + if (digit <= -bit || digit >= bit || !(digit & 1)) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + + window_val -= digit; + + /* + * now window_val is 0 or 2^(w+1) in standard wNAF generation; + * for modified window NAFs, it may also be 2^w + */ + if (window_val != 0 && window_val != next_bit + && window_val != bit) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + r[j++] = sign * digit; + + window_val >>= 1; + window_val += bit * BN_is_bit_set(scalar, j + w); + + if (window_val > next_bit) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (j > len + 1) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + len = j; + ok = 1; + + err: + if (!ok) { + OPENSSL_free(r); + r = NULL; + } + if (ok) + *ret_len = len; + return r; +} + +#define EC_POINT_BN_set_flags(P, flags) do { \ + BN_set_flags(&(P)->X, (flags)); \ + BN_set_flags(&(P)->Y, (flags)); \ + BN_set_flags(&(P)->Z, (flags)); \ +} while(0) + +/*- + * This functions computes (in constant time) a point multiplication over the + * EC group. + * + * At a high level, it is Montgomery ladder with conditional swaps. + * + * It performs either a fixed scalar point multiplication + * (scalar * generator) + * when point is NULL, or a generic scalar point multiplication + * (scalar * point) + * when point is not NULL. + * + * scalar should be in the range [0,n) otherwise all constant time bets are off. + * + * NB: This says nothing about EC_POINT_add and EC_POINT_dbl, + * which of course are not constant time themselves. + * + * The product is stored in r. + * + * Returns 1 on success, 0 otherwise. + */ +static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, const EC_POINT *point, + BN_CTX *ctx) +{ + int i, cardinality_bits, group_top, kbit, pbit, Z_is_one; + EC_POINT *s = NULL; + BIGNUM *k = NULL; + BIGNUM *lambda = NULL; + BIGNUM *cardinality = NULL; + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + + BN_CTX_start(ctx); + + s = EC_POINT_new(group); + if (s == NULL) + goto err; + + if (point == NULL) { + if (!EC_POINT_copy(s, group->generator)) + goto err; + } else { + if (!EC_POINT_copy(s, point)) + goto err; + } + + EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME); + + cardinality = BN_CTX_get(ctx); + lambda = BN_CTX_get(ctx); + k = BN_CTX_get(ctx); + if (k == NULL || !BN_mul(cardinality, &group->order, &group->cofactor, ctx)) + goto err; + + /* + * Group cardinalities are often on a word boundary. + * So when we pad the scalar, some timing diff might + * pop if it needs to be expanded due to carries. + * So expand ahead of time. + */ + cardinality_bits = BN_num_bits(cardinality); + group_top = cardinality->top; + if ((bn_wexpand(k, group_top + 2) == NULL) + || (bn_wexpand(lambda, group_top + 2) == NULL)) + goto err; + + if (!BN_copy(k, scalar)) + goto err; + + BN_set_flags(k, BN_FLG_CONSTTIME); + + if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) { + /*- + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(k, k, cardinality, ctx)) + goto err; + } + + if (!BN_add(lambda, k, cardinality)) + goto err; + BN_set_flags(lambda, BN_FLG_CONSTTIME); + if (!BN_add(k, lambda, cardinality)) + goto err; + /* + * lambda := scalar + cardinality + * k := scalar + 2*cardinality + */ + kbit = BN_is_bit_set(lambda, cardinality_bits); + BN_consttime_swap(kbit, k, lambda, group_top + 2); + + group_top = group->field.top; + if ((bn_wexpand(&s->X, group_top) == NULL) + || (bn_wexpand(&s->Y, group_top) == NULL) + || (bn_wexpand(&s->Z, group_top) == NULL) + || (bn_wexpand(&r->X, group_top) == NULL) + || (bn_wexpand(&r->Y, group_top) == NULL) + || (bn_wexpand(&r->Z, group_top) == NULL)) + goto err; + + /* top bit is a 1, in a fixed pos */ + if (!EC_POINT_copy(r, s)) + goto err; + + EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME); + + if (!EC_POINT_dbl(group, s, s, ctx)) + goto err; + + pbit = 0; + +#define EC_POINT_CSWAP(c, a, b, w, t) do { \ + BN_consttime_swap(c, &(a)->X, &(b)->X, w); \ + BN_consttime_swap(c, &(a)->Y, &(b)->Y, w); \ + BN_consttime_swap(c, &(a)->Z, &(b)->Z, w); \ + t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ + (a)->Z_is_one ^= (t); \ + (b)->Z_is_one ^= (t); \ +} while(0) + + /*- + * The ladder step, with branches, is + * + * k[i] == 0: S = add(R, S), R = dbl(R) + * k[i] == 1: R = add(S, R), S = dbl(S) + * + * Swapping R, S conditionally on k[i] leaves you with state + * + * k[i] == 0: T, U = R, S + * k[i] == 1: T, U = S, R + * + * Then perform the ECC ops. + * + * U = add(T, U) + * T = dbl(T) + * + * Which leaves you with state + * + * k[i] == 0: U = add(R, S), T = dbl(R) + * k[i] == 1: U = add(S, R), T = dbl(S) + * + * Swapping T, U conditionally on k[i] leaves you with state + * + * k[i] == 0: R, S = T, U + * k[i] == 1: R, S = U, T + * + * Which leaves you with state + * + * k[i] == 0: S = add(R, S), R = dbl(R) + * k[i] == 1: R = add(S, R), S = dbl(S) + * + * So we get the same logic, but instead of a branch it's a + * conditional swap, followed by ECC ops, then another conditional swap. + * + * Optimization: The end of iteration i and start of i-1 looks like + * + * ... + * CSWAP(k[i], R, S) + * ECC + * CSWAP(k[i], R, S) + * (next iteration) + * CSWAP(k[i-1], R, S) + * ECC + * CSWAP(k[i-1], R, S) + * ... + * + * So instead of two contiguous swaps, you can merge the condition + * bits and do a single swap. + * + * k[i] k[i-1] Outcome + * 0 0 No Swap + * 0 1 Swap + * 1 0 Swap + * 1 1 No Swap + * + * This is XOR. pbit tracks the previous bit of k. + */ + + for (i = cardinality_bits - 1; i >= 0; i--) { + kbit = BN_is_bit_set(k, i) ^ pbit; + EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one); + if (!EC_POINT_add(group, s, r, s, ctx)) + goto err; + if (!EC_POINT_dbl(group, r, r, ctx)) + goto err; + /* + * pbit logic merges this cswap with that of the + * next iteration + */ + pbit ^= kbit; + } + /* one final cswap to move the right value into r */ + EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one); +#undef EC_POINT_CSWAP + + ret = 1; + + err: + EC_POINT_free(s); + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + + return ret; +} + +#undef EC_POINT_BN_set_flags + +/* + * TODO: table should be optimised for the wNAF-based implementation, + * sometimes smaller windows will give better performance (thus the + * boundaries should be increased) + */ +#define EC_window_bits_for_scalar_size(b) \ + ((size_t) \ + ((b) >= 2000 ? 6 : \ + (b) >= 800 ? 5 : \ + (b) >= 300 ? 4 : \ + (b) >= 70 ? 3 : \ + (b) >= 20 ? 2 : \ + 1)) + +/*- + * Compute + * \sum scalars[i]*points[i], + * also including + * scalar*generator + * in the addition if scalar != NULL + */ +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + const EC_POINT *generator = NULL; + EC_POINT *tmp = NULL; + size_t totalnum; + size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ + size_t pre_points_per_block = 0; + size_t i, j; + int k; + int r_is_inverted = 0; + int r_is_at_infinity = 1; + size_t *wsize = NULL; /* individual window sizes */ + signed char **wNAF = NULL; /* individual wNAFs */ + size_t *wNAF_len = NULL; + size_t max_len = 0; + size_t num_val; + EC_POINT **val = NULL; /* precomputation */ + EC_POINT **v; + EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or + * 'pre_comp->points' */ + const EC_PRE_COMP *pre_comp = NULL; + int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be + * treated like other scalars, i.e. + * precomputation is not available */ + int ret = 0; + + if (group->meth != r->meth) { + ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + if ((scalar == NULL) && (num == 0)) { + return EC_POINT_set_to_infinity(group, r); + } + + if (!BN_is_zero(&group->order) && !BN_is_zero(&group->cofactor)) { + /*- + * Handle the common cases where the scalar is secret, enforcing a constant + * time scalar multiplication algorithm. + */ + if ((scalar != NULL) && (num == 0)) { + /*- + * In this case we want to compute scalar * GeneratorPoint: this + * codepath is reached most prominently by (ephemeral) key generation + * of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH + * keygen/first half), where the scalar is always secret. This is why + * we ignore if BN_FLG_CONSTTIME is actually set and we always call the + * constant time version. + */ + return ec_mul_consttime(group, r, scalar, NULL, ctx); + } + if ((scalar == NULL) && (num == 1)) { + /*- + * In this case we want to compute scalar * GenericPoint: this codepath + * is reached most prominently by the second half of ECDH, where the + * secret scalar is multiplied by the peer's public point. To protect + * the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and + * we always call the constant time version. + */ + return ec_mul_consttime(group, r, scalars[0], points[0], ctx); + } + } + + for (i = 0; i < num; i++) { + if (group->meth != points[i]->meth) { + ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + } + + if (scalar != NULL) { + generator = EC_GROUP_get0_generator(group); + if (generator == NULL) { + ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR); + goto err; + } + + /* look if we can use precomputed multiples of generator */ + + pre_comp = + EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, + ec_pre_comp_free, ec_pre_comp_clear_free); + + if (pre_comp && pre_comp->numblocks + && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == + 0)) { + blocksize = pre_comp->blocksize; + + /* + * determine maximum number of blocks that wNAF splitting may + * yield (NB: maximum wNAF length is bit length plus one) + */ + numblocks = (BN_num_bits(scalar) / blocksize) + 1; + + /* + * we cannot use more blocks than we have precomputation for + */ + if (numblocks > pre_comp->numblocks) + numblocks = pre_comp->numblocks; + + pre_points_per_block = (size_t)1 << (pre_comp->w - 1); + + /* check that pre_comp looks sane */ + if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + /* can't use precomputation */ + pre_comp = NULL; + numblocks = 1; + num_scalar = 1; /* treat 'scalar' like 'num'-th element of + * 'scalars' */ + } + } + + totalnum = num + numblocks; + + wsize = OPENSSL_malloc(totalnum * sizeof(wsize[0])); + wNAF_len = OPENSSL_malloc(totalnum * sizeof(wNAF_len[0])); + /* include space for pivot */ + wNAF = OPENSSL_malloc((totalnum + 1) * sizeof(wNAF[0])); + val_sub = OPENSSL_malloc(totalnum * sizeof(val_sub[0])); + + /* Ensure wNAF is initialised in case we end up going to err */ + if (wNAF) + wNAF[0] = NULL; /* preliminary pivot */ + + if (!wsize || !wNAF_len || !wNAF || !val_sub) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * num_val will be the total number of temporarily precomputed points + */ + num_val = 0; + + for (i = 0; i < num + num_scalar; i++) { + size_t bits; + + bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); + wsize[i] = EC_window_bits_for_scalar_size(bits); + num_val += (size_t)1 << (wsize[i] - 1); + wNAF[i + 1] = NULL; /* make sure we always have a pivot */ + wNAF[i] = + compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], + &wNAF_len[i]); + if (wNAF[i] == NULL) + goto err; + if (wNAF_len[i] > max_len) + max_len = wNAF_len[i]; + } + + if (numblocks) { + /* we go here iff scalar != NULL */ + + if (pre_comp == NULL) { + if (num_scalar != 1) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + /* we have already generated a wNAF for 'scalar' */ + } else { + signed char *tmp_wNAF = NULL; + size_t tmp_len = 0; + + if (num_scalar != 0) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* + * use the window size for which we have precomputation + */ + wsize[num] = pre_comp->w; + tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len); + if (!tmp_wNAF) + goto err; + + if (tmp_len <= max_len) { + /* + * One of the other wNAFs is at least as long as the wNAF + * belonging to the generator, so wNAF splitting will not buy + * us anything. + */ + + numblocks = 1; + totalnum = num + 1; /* don't use wNAF splitting */ + wNAF[num] = tmp_wNAF; + wNAF[num + 1] = NULL; + wNAF_len[num] = tmp_len; + if (tmp_len > max_len) + max_len = tmp_len; + /* + * pre_comp->points starts with the points that we need here: + */ + val_sub[num] = pre_comp->points; + } else { + /* + * don't include tmp_wNAF directly into wNAF array - use wNAF + * splitting and include the blocks + */ + + signed char *pp; + EC_POINT **tmp_points; + + if (tmp_len < numblocks * blocksize) { + /* + * possibly we can do with fewer blocks than estimated + */ + numblocks = (tmp_len + blocksize - 1) / blocksize; + if (numblocks > pre_comp->numblocks) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + totalnum = num + numblocks; + } + + /* split wNAF in 'numblocks' parts */ + pp = tmp_wNAF; + tmp_points = pre_comp->points; + + for (i = num; i < totalnum; i++) { + if (i < totalnum - 1) { + wNAF_len[i] = blocksize; + if (tmp_len < blocksize) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + tmp_len -= blocksize; + } else + /* + * last block gets whatever is left (this could be + * more or less than 'blocksize'!) + */ + wNAF_len[i] = tmp_len; + + wNAF[i + 1] = NULL; + wNAF[i] = OPENSSL_malloc(wNAF_len[i]); + if (wNAF[i] == NULL) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + OPENSSL_free(tmp_wNAF); + goto err; + } + memcpy(wNAF[i], pp, wNAF_len[i]); + if (wNAF_len[i] > max_len) + max_len = wNAF_len[i]; + + if (*tmp_points == NULL) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + OPENSSL_free(tmp_wNAF); + goto err; + } + val_sub[i] = tmp_points; + tmp_points += pre_points_per_block; + pp += blocksize; + } + OPENSSL_free(tmp_wNAF); + } + } + } + + /* + * All points we precompute now go into a single array 'val'. + * 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a + * subarray of 'pre_comp->points' if we already have precomputation. + */ + val = OPENSSL_malloc((num_val + 1) * sizeof(val[0])); + if (val == NULL) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + val[num_val] = NULL; /* pivot element */ + + /* allocate points for precomputation */ + v = val; + for (i = 0; i < num + num_scalar; i++) { + val_sub[i] = v; + for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) { + *v = EC_POINT_new(group); + if (*v == NULL) + goto err; + v++; + } + } + if (!(v == val + num_val)) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!(tmp = EC_POINT_new(group))) + goto err; + + /*- + * prepare precomputed values: + * val_sub[i][0] := points[i] + * val_sub[i][1] := 3 * points[i] + * val_sub[i][2] := 5 * points[i] + * ... + */ + for (i = 0; i < num + num_scalar; i++) { + if (i < num) { + if (!EC_POINT_copy(val_sub[i][0], points[i])) + goto err; + } else { + if (!EC_POINT_copy(val_sub[i][0], generator)) + goto err; + } + + if (wsize[i] > 1) { + if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) + goto err; + for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) { + if (!EC_POINT_add + (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) + goto err; + } + } + } + +#if 1 /* optional; EC_window_bits_for_scalar_size + * assumes we do this step */ + if (!EC_POINTs_make_affine(group, num_val, val, ctx)) + goto err; +#endif + + r_is_at_infinity = 1; + + for (k = max_len - 1; k >= 0; k--) { + if (!r_is_at_infinity) { + if (!EC_POINT_dbl(group, r, r, ctx)) + goto err; + } + + for (i = 0; i < totalnum; i++) { + if (wNAF_len[i] > (size_t)k) { + int digit = wNAF[i][k]; + int is_neg; + + if (digit) { + is_neg = digit < 0; + + if (is_neg) + digit = -digit; + + if (is_neg != r_is_inverted) { + if (!r_is_at_infinity) { + if (!EC_POINT_invert(group, r, ctx)) + goto err; + } + r_is_inverted = !r_is_inverted; + } + + /* digit > 0 */ + + if (r_is_at_infinity) { + if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) + goto err; + r_is_at_infinity = 0; + } else { + if (!EC_POINT_add + (group, r, r, val_sub[i][digit >> 1], ctx)) + goto err; + } + } + } + } + } + + if (r_is_at_infinity) { + if (!EC_POINT_set_to_infinity(group, r)) + goto err; + } else { + if (r_is_inverted) + if (!EC_POINT_invert(group, r, ctx)) + goto err; + } + + ret = 1; + + err: + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (tmp != NULL) + EC_POINT_free(tmp); + if (wsize != NULL) + OPENSSL_free(wsize); + if (wNAF_len != NULL) + OPENSSL_free(wNAF_len); + if (wNAF != NULL) { + signed char **w; + + for (w = wNAF; *w != NULL; w++) + OPENSSL_free(*w); + + OPENSSL_free(wNAF); + } + if (val != NULL) { + for (v = val; *v != NULL; v++) + EC_POINT_clear_free(*v); + + OPENSSL_free(val); + } + if (val_sub != NULL) { + OPENSSL_free(val_sub); + } + return ret; +} + +/*- + * ec_wNAF_precompute_mult() + * creates an EC_PRE_COMP object with preprecomputed multiples of the generator + * for use with wNAF splitting as implemented in ec_wNAF_mul(). + * + * 'pre_comp->points' is an array of multiples of the generator + * of the following form: + * points[0] = generator; + * points[1] = 3 * generator; + * ... + * points[2^(w-1)-1] = (2^(w-1)-1) * generator; + * points[2^(w-1)] = 2^blocksize * generator; + * points[2^(w-1)+1] = 3 * 2^blocksize * generator; + * ... + * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator + * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator + * ... + * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator + * points[2^(w-1)*numblocks] = NULL + */ +int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + const EC_POINT *generator; + EC_POINT *tmp_point = NULL, *base = NULL, **var; + BN_CTX *new_ctx = NULL; + BIGNUM *order; + size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; + EC_POINT **points = NULL; + EC_PRE_COMP *pre_comp; + int ret = 0; + + /* if there is an old EC_PRE_COMP object, throw it away */ + EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, + ec_pre_comp_free, ec_pre_comp_clear_free); + + if ((pre_comp = ec_pre_comp_new(group)) == NULL) + return 0; + + generator = EC_GROUP_get0_generator(group); + if (generator == NULL) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + } + + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + if (order == NULL) + goto err; + + if (!EC_GROUP_get_order(group, order, ctx)) + goto err; + if (BN_is_zero(order)) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); + goto err; + } + + bits = BN_num_bits(order); + /* + * The following parameters mean we precompute (approximately) one point + * per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other + * bit lengths, other parameter combinations might provide better + * efficiency. + */ + blocksize = 8; + w = 4; + if (EC_window_bits_for_scalar_size(bits) > w) { + /* let's not make the window too small ... */ + w = EC_window_bits_for_scalar_size(bits); + } + + numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks + * to use for wNAF + * splitting */ + + pre_points_per_block = (size_t)1 << (w - 1); + num = pre_points_per_block * numblocks; /* number of points to compute + * and store */ + + points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1)); + if (!points) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + goto err; + } + + var = points; + var[num] = NULL; /* pivot */ + for (i = 0; i < num; i++) { + if ((var[i] = EC_POINT_new(group)) == NULL) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_POINT_copy(base, generator)) + goto err; + + /* do the precomputation */ + for (i = 0; i < numblocks; i++) { + size_t j; + + if (!EC_POINT_dbl(group, tmp_point, base, ctx)) + goto err; + + if (!EC_POINT_copy(*var++, base)) + goto err; + + for (j = 1; j < pre_points_per_block; j++, var++) { + /* + * calculate odd multiples of the current base point + */ + if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) + goto err; + } + + if (i < numblocks - 1) { + /* + * get the next base (multiply current one by 2^blocksize) + */ + size_t k; + + if (blocksize <= 2) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!EC_POINT_dbl(group, base, tmp_point, ctx)) + goto err; + for (k = 2; k < blocksize; k++) { + if (!EC_POINT_dbl(group, base, base, ctx)) + goto err; + } + } + } + + if (!EC_POINTs_make_affine(group, num, points, ctx)) + goto err; + + pre_comp->group = group; + pre_comp->blocksize = blocksize; + pre_comp->numblocks = numblocks; + pre_comp->w = w; + pre_comp->points = points; + points = NULL; + pre_comp->num = num; + + if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp, + ec_pre_comp_dup, ec_pre_comp_free, + ec_pre_comp_clear_free)) + goto err; + pre_comp = NULL; + + ret = 1; + err: + if (ctx != NULL) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (pre_comp) + ec_pre_comp_free(pre_comp); + if (points) { + EC_POINT **p; + + for (p = points; *p != NULL; p++) + EC_POINT_free(*p); + OPENSSL_free(points); + } + if (tmp_point) + EC_POINT_free(tmp_point); + if (base) + EC_POINT_free(base); + return ret; +} + +int ec_wNAF_have_precompute_mult(const EC_GROUP *group) +{ + if (EC_EX_DATA_get_data + (group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, + ec_pre_comp_clear_free) != NULL) + return 1; + else + return 0; +} +/* crypto/ec/ec_lib.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Binary polynomial ECC support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +// #include "err.h" +// #include "opensslv.h" + +// #include "ec_lcl.h" + +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + int y_bit, BN_CTX *ctx) +{ + if (group->meth->point_set_compressed_coordinates == 0 + && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { + if (group->meth->field_type == NID_X9_62_prime_field) + return ec_GFp_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); + else +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, + EC_R_GF2M_NOT_SUPPORTED); + return 0; + } +#else + return ec_GF2m_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); +#endif + } + return group->meth->point_set_compressed_coordinates(group, point, x, + y_bit, ctx); +} + +#ifndef OPENSSL_NO_EC2M +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + int y_bit, BN_CTX *ctx) +{ + if (group->meth->point_set_compressed_coordinates == 0 + && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { + if (group->meth->field_type == NID_X9_62_prime_field) + return ec_GFp_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); + else + return ec_GF2m_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); + } + return group->meth->point_set_compressed_coordinates(group, point, x, + y_bit, ctx); +} +#endif + +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, unsigned char *buf, + size_t len, BN_CTX *ctx) +{ + if (group->meth->point2oct == 0 + && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { + ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { + if (group->meth->field_type == NID_X9_62_prime_field) + return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); + else +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED); + return 0; + } +#else + return ec_GF2m_simple_point2oct(group, point, + form, buf, len, ctx); +#endif + } + + return group->meth->point2oct(group, point, form, buf, len, ctx); +} + +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, BN_CTX *ctx) +{ + if (group->meth->oct2point == 0 + && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { + ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { + if (group->meth->field_type == NID_X9_62_prime_field) + return ec_GFp_simple_oct2point(group, point, buf, len, ctx); + else +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED); + return 0; + } +#else + return ec_GF2m_simple_oct2point(group, point, buf, len, ctx); +#endif + } + return group->meth->oct2point(group, point, buf, len, ctx); +} +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" +// #include "ec.h" +// #include "ec_lcl.h" +#include "ecdsa.h" +#include "evp.h" +#include "evp_locl.h" + +/* EC pkey context structure */ + +typedef struct { + /* Key and paramgen group */ + EC_GROUP *gen_group; + /* message digest */ + const EVP_MD *md; + /* Duplicate key if custom cofactor needed */ + EC_KEY *co_key; + /* Cofactor mode */ + signed char cofactor_mode; + /* KDF (if any) to use for ECDH */ + char kdf_type; + /* Message digest to use for key derivation */ + const EVP_MD *kdf_md; + /* User key material */ + unsigned char *kdf_ukm; + size_t kdf_ukmlen; + /* KDF output length */ + size_t kdf_outlen; +} EC_PKEY_CTX; + +static int pkey_ec_init(EVP_PKEY_CTX *ctx) +{ + EC_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); + if (!dctx) + return 0; + dctx->gen_group = NULL; + dctx->md = NULL; + + dctx->cofactor_mode = -1; + dctx->co_key = NULL; + dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE; + dctx->kdf_md = NULL; + dctx->kdf_outlen = 0; + dctx->kdf_ukm = NULL; + dctx->kdf_ukmlen = 0; + + ctx->data = dctx; + + return 1; +} + +static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + EC_PKEY_CTX *dctx, *sctx; + if (!pkey_ec_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + if (sctx->gen_group) { + dctx->gen_group = EC_GROUP_dup(sctx->gen_group); + if (!dctx->gen_group) + return 0; + } + dctx->md = sctx->md; + + if (sctx->co_key) { + dctx->co_key = EC_KEY_dup(sctx->co_key); + if (!dctx->co_key) + return 0; + } + dctx->kdf_type = sctx->kdf_type; + dctx->kdf_md = sctx->kdf_md; + dctx->kdf_outlen = sctx->kdf_outlen; + if (sctx->kdf_ukm) { + dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); + if (!dctx->kdf_ukm) + return 0; + } else + dctx->kdf_ukm = NULL; + dctx->kdf_ukmlen = sctx->kdf_ukmlen; + return 1; +} + +static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) +{ + EC_PKEY_CTX *dctx = ctx->data; + if (dctx) { + if (dctx->gen_group) + EC_GROUP_free(dctx->gen_group); + if (dctx->co_key) + EC_KEY_free(dctx->co_key); + if (dctx->kdf_ukm) + OPENSSL_free(dctx->kdf_ukm); + OPENSSL_free(dctx); + } +} + +static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret, type; + unsigned int sltmp; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (!sig) { + *siglen = ECDSA_size(ec); + return 1; + } else if (*siglen < (size_t)ECDSA_size(ec)) { + ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); + + if (ret <= 0) + return ret; + *siglen = (size_t)sltmp; + return 1; +} + +static int pkey_ec_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret, type; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); + + return ret; +} + +#ifndef OPENSSL_NO_ECDH +static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + int ret; + size_t outlen; + const EC_POINT *pubkey = NULL; + EC_KEY *eckey; + EC_PKEY_CTX *dctx = ctx->data; + if (!ctx->pkey || !ctx->peerkey) { + ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET); + return 0; + } + + eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec; + + if (!key) { + const EC_GROUP *group; + group = EC_KEY_get0_group(eckey); + *keylen = (EC_GROUP_get_degree(group) + 7) / 8; + return 1; + } + pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + + /* + * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not + * an error, the result is truncated. + */ + + outlen = *keylen; + + ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); + if (ret <= 0) + return 0; + *keylen = ret; + return 1; +} + +static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, + unsigned char *key, size_t *keylen) +{ + EC_PKEY_CTX *dctx = ctx->data; + unsigned char *ktmp = NULL; + size_t ktmplen; + int rv = 0; + if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE) + return pkey_ec_derive(ctx, key, keylen); + if (!key) { + *keylen = dctx->kdf_outlen; + return 1; + } + if (*keylen != dctx->kdf_outlen) + return 0; + if (!pkey_ec_derive(ctx, NULL, &ktmplen)) + return 0; + ktmp = OPENSSL_malloc(ktmplen); + if (!ktmp) + return 0; + if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) + goto err; + /* Do KDF stuff */ + if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen, + dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) + goto err; + rv = 1; + + err: + if (ktmp) { + OPENSSL_cleanse(ktmp, ktmplen); + OPENSSL_free(ktmp); + } + return rv; +} +#endif + +static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + EC_PKEY_CTX *dctx = ctx->data; + EC_GROUP *group; + switch (type) { + case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: + group = EC_GROUP_new_by_curve_name(p1); + if (group == NULL) { + ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); + return 0; + } + if (dctx->gen_group) + EC_GROUP_free(dctx->gen_group); + dctx->gen_group = group; + return 1; + + case EVP_PKEY_CTRL_EC_PARAM_ENC: + if (!dctx->gen_group) { + ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET); + return 0; + } + EC_GROUP_set_asn1_flag(dctx->gen_group, p1); + return 1; + +#ifndef OPENSSL_NO_ECDH + case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: + if (p1 == -2) { + if (dctx->cofactor_mode != -1) + return dctx->cofactor_mode; + else { + EC_KEY *ec_key = ctx->pkey->pkey.ec; + return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : + 0; + } + } else if (p1 < -1 || p1 > 1) + return -2; + dctx->cofactor_mode = p1; + if (p1 != -1) { + EC_KEY *ec_key = ctx->pkey->pkey.ec; + if (!ec_key->group) + return -2; + /* If cofactor is 1 cofactor mode does nothing */ + if (BN_is_one(&ec_key->group->cofactor)) + return 1; + if (!dctx->co_key) { + dctx->co_key = EC_KEY_dup(ec_key); + if (!dctx->co_key) + return 0; + } + if (p1) + EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); + else + EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); + } else if (dctx->co_key) { + EC_KEY_free(dctx->co_key); + dctx->co_key = NULL; + } + return 1; +#endif + + case EVP_PKEY_CTRL_EC_KDF_TYPE: + if (p1 == -2) + return dctx->kdf_type; + if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62) + return -2; + dctx->kdf_type = p1; + return 1; + + case EVP_PKEY_CTRL_EC_KDF_MD: + dctx->kdf_md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_EC_KDF_MD: + *(const EVP_MD **)p2 = dctx->kdf_md; + return 1; + + case EVP_PKEY_CTRL_EC_KDF_OUTLEN: + if (p1 <= 0) + return -2; + dctx->kdf_outlen = (size_t)p1; + return 1; + + case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: + *(int *)p2 = dctx->kdf_outlen; + return 1; + + case EVP_PKEY_CTRL_EC_KDF_UKM: + if (dctx->kdf_ukm) + OPENSSL_free(dctx->kdf_ukm); + dctx->kdf_ukm = p2; + if (p2) + dctx->kdf_ukmlen = p1; + else + dctx->kdf_ukmlen = 0; + return 1; + + case EVP_PKEY_CTRL_GET_EC_KDF_UKM: + *(unsigned char **)p2 = dctx->kdf_ukm; + return dctx->kdf_ukmlen; + + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { + ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = dctx->md; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + /* Default behaviour is OK */ + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; + + default: + return -2; + + } +} + +static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!strcmp(type, "ec_paramgen_curve")) { + int nid; + nid = EC_curve_nist2nid(value); + if (nid == NID_undef) + nid = OBJ_sn2nid(value); + if (nid == NID_undef) + nid = OBJ_ln2nid(value); + if (nid == NID_undef) { + ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); + return 0; + } + return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); + } else if (!strcmp(type, "ec_param_enc")) { + int param_enc; + if (!strcmp(value, "explicit")) + param_enc = 0; + else if (!strcmp(value, "named_curve")) + param_enc = OPENSSL_EC_NAMED_CURVE; + else + return -2; + return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); + } else if (!strcmp(type, "ecdh_kdf_md")) { + const EVP_MD *md; + if (!(md = EVP_get_digestbyname(value))) { + ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md); + } else if (!strcmp(type, "ecdh_cofactor_mode")) { + int co_mode; + co_mode = atoi(value); + return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode); + } + + return -2; +} + +static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + EC_KEY *ec = NULL; + EC_PKEY_CTX *dctx = ctx->data; + int ret = 0; + if (dctx->gen_group == NULL) { + ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); + return 0; + } + ec = EC_KEY_new(); + if (!ec) + return 0; + ret = EC_KEY_set_group(ec, dctx->gen_group); + if (ret) + EVP_PKEY_assign_EC_KEY(pkey, ec); + else + EC_KEY_free(ec); + return ret; +} + +static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + EC_KEY *ec = NULL; + EC_PKEY_CTX *dctx = ctx->data; + if (ctx->pkey == NULL && dctx->gen_group == NULL) { + ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); + return 0; + } + ec = EC_KEY_new(); + if (!ec) + return 0; + EVP_PKEY_assign_EC_KEY(pkey, ec); + if (ctx->pkey) { + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + } else { + if (!EC_KEY_set_group(ec, dctx->gen_group)) + return 0; + } + return EC_KEY_generate_key(pkey->pkey.ec); +} + +const EVP_PKEY_METHOD ec_pkey_meth = { + EVP_PKEY_EC, + 0, + pkey_ec_init, + pkey_ec_copy, + pkey_ec_cleanup, + + 0, + pkey_ec_paramgen, + + 0, + pkey_ec_keygen, + + 0, + pkey_ec_sign, + + 0, + pkey_ec_verify, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + 0, +#ifndef OPENSSL_NO_ECDH + pkey_ec_kdf_derive, +#else + 0, +#endif + + pkey_ec_ctrl, + pkey_ec_ctrl_str +}; +/* crypto/ec/ec_print.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "crypto.h" +// #include "ec_lcl.h" + +BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + BIGNUM *ret, BN_CTX *ctx) +{ + size_t buf_len = 0; + unsigned char *buf; + + buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (buf_len == 0) + return NULL; + + if ((buf = OPENSSL_malloc(buf_len)) == NULL) + return NULL; + + if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { + OPENSSL_free(buf); + return NULL; + } + + ret = BN_bin2bn(buf, buf_len, ret); + + OPENSSL_free(buf); + + return ret; +} + +EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, + const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx) +{ + size_t buf_len = 0; + unsigned char *buf; + EC_POINT *ret; + + if ((buf_len = BN_num_bytes(bn)) == 0) + return NULL; + buf = OPENSSL_malloc(buf_len); + if (buf == NULL) + return NULL; + + if (!BN_bn2bin(bn, buf)) { + OPENSSL_free(buf); + return NULL; + } + + if (point == NULL) { + if ((ret = EC_POINT_new(group)) == NULL) { + OPENSSL_free(buf); + return NULL; + } + } else + ret = point; + + if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) { + if (point == NULL) + EC_POINT_clear_free(ret); + OPENSSL_free(buf); + return NULL; + } + + OPENSSL_free(buf); + return ret; +} + +static const char *HEX_DIGITS = "0123456789ABCDEF"; + +/* the return value must be freed (using OPENSSL_free()) */ +char *EC_POINT_point2hex(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, BN_CTX *ctx) +{ + char *ret, *p; + size_t buf_len = 0, i; + unsigned char *buf, *pbuf; + + buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (buf_len == 0) + return NULL; + + if ((buf = OPENSSL_malloc(buf_len)) == NULL) + return NULL; + + if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { + OPENSSL_free(buf); + return NULL; + } + + ret = (char *)OPENSSL_malloc(buf_len * 2 + 2); + if (ret == NULL) { + OPENSSL_free(buf); + return NULL; + } + p = ret; + pbuf = buf; + for (i = buf_len; i > 0; i--) { + int v = (int)*(pbuf++); + *(p++) = HEX_DIGITS[v >> 4]; + *(p++) = HEX_DIGITS[v & 0x0F]; + } + *p = '\0'; + + OPENSSL_free(buf); + + return ret; +} + +EC_POINT *EC_POINT_hex2point(const EC_GROUP *group, + const char *buf, EC_POINT *point, BN_CTX *ctx) +{ + EC_POINT *ret = NULL; + BIGNUM *tmp_bn = NULL; + + if (!BN_hex2bn(&tmp_bn, buf)) + return NULL; + + ret = EC_POINT_bn2point(group, tmp_bn, point, ctx); + + BN_clear_free(tmp_bn); + + return ret; +} diff --git a/Sources/COpenSSL/ec_lcl.h b/Sources/COpenSSL/ec_lcl.h new file mode 100644 index 00000000..bda6e9f2 --- /dev/null +++ b/Sources/COpenSSL/ec_lcl.h @@ -0,0 +1,567 @@ +/* crypto/ec/ec_lcl.h */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include + +#include "obj_mac.h" +#include "ec.h" +#include "bn.h" + +#if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +#endif + +/* Use default functions for poin2oct, oct2point and compressed coordinates */ +#define EC_FLAGS_DEFAULT_OCT 0x1 + +/* + * Structure details are not part of the exported interface, so all this may + * change in future versions. + */ + +struct ec_method_st { + /* Various method flags */ + int flags; + /* used by EC_METHOD_get_field_type: */ + int field_type; /* a NID */ + /* + * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, + * EC_GROUP_copy: + */ + int (*group_init) (EC_GROUP *); + void (*group_finish) (EC_GROUP *); + void (*group_clear_finish) (EC_GROUP *); + int (*group_copy) (EC_GROUP *, const EC_GROUP *); + /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */ + /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */ + int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, + BN_CTX *); + /* used by EC_GROUP_get_degree: */ + int (*group_get_degree) (const EC_GROUP *); + /* used by EC_GROUP_check: */ + int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *); + /* + * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, + * EC_POINT_copy: + */ + int (*point_init) (EC_POINT *); + void (*point_finish) (EC_POINT *); + void (*point_clear_finish) (EC_POINT *); + int (*point_copy) (EC_POINT *, const EC_POINT *); + /*- + * used by EC_POINT_set_to_infinity, + * EC_POINT_set_Jprojective_coordinates_GFp, + * EC_POINT_get_Jprojective_coordinates_GFp, + * EC_POINT_set_affine_coordinates_GFp, ..._GF2m, + * EC_POINT_get_affine_coordinates_GFp, ..._GF2m, + * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m: + */ + int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *); + int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *, + EC_POINT *, const BIGNUM *x, + const BIGNUM *y, + const BIGNUM *z, BN_CTX *); + int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *); + int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *); + int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *, + BIGNUM *x, BIGNUM *y, BN_CTX *); + int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, + BN_CTX *); + /* used by EC_POINT_point2oct, EC_POINT_oct2point: */ + size_t (*point2oct) (const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, unsigned char *buf, + size_t len, BN_CTX *); + int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf, + size_t len, BN_CTX *); + /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */ + int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); + int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); + int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *); + /* + * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: + */ + int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *); + int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *); + int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, + BN_CTX *); + /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */ + int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *); + int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[], + BN_CTX *); + /* + * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, + * EC_POINT_have_precompute_mult (default implementations are used if the + * 'mul' pointer is 0): + */ + int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); + int (*precompute_mult) (EC_GROUP *group, BN_CTX *); + int (*have_precompute_mult) (const EC_GROUP *group); + /* internal functions */ + /* + * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and + * 'dbl' so that the same implementations of point operations can be used + * with different optimized implementations of expensive field + * operations: + */ + int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); + int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + /* e.g. to Montgomery */ + int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + /* e.g. from Montgomery */ + int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *); +} /* EC_METHOD */ ; + +typedef struct ec_extra_data_st { + struct ec_extra_data_st *next; + void *data; + void *(*dup_func) (void *); + void (*free_func) (void *); + void (*clear_free_func) (void *); +} EC_EXTRA_DATA; /* used in EC_GROUP */ + +struct ec_group_st { + const EC_METHOD *meth; + EC_POINT *generator; /* optional */ + BIGNUM order, cofactor; + int curve_name; /* optional NID for named curve */ + int asn1_flag; /* flag to control the asn1 encoding */ + /* + * Kludge: upper bit of ans1_flag is used to denote structure + * version. If set, then last field is present. This is done + * for interoperation with FIPS code. + */ +#define EC_GROUP_ASN1_FLAG_MASK 0x7fffffff +#define EC_GROUP_VERSION(p) (p->asn1_flag&~EC_GROUP_ASN1_FLAG_MASK) + point_conversion_form_t asn1_form; + unsigned char *seed; /* optional seed for parameters (appears in + * ASN1) */ + size_t seed_len; + EC_EXTRA_DATA *extra_data; /* linked list */ + /* + * The following members are handled by the method functions, even if + * they appear generic + */ + /* + * Field specification. For curves over GF(p), this is the modulus; for + * curves over GF(2^m), this is the irreducible polynomial defining the + * field. + */ + BIGNUM field; + /* + * Field specification for curves over GF(2^m). The irreducible f(t) is + * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m = + * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with + * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero + * terms. + */ + int poly[6]; + /* + * Curve coefficients. (Here the assumption is that BIGNUMs can be used + * or abused for all kinds of fields, not just GF(p).) For characteristic + * > 3, the curve is defined by a Weierstrass equation of the form y^2 = + * x^3 + a*x + b. For characteristic 2, the curve is defined by an + * equation of the form y^2 + x*y = x^3 + a*x^2 + b. + */ + BIGNUM a, b; + /* enable optimized point arithmetics for special case */ + int a_is_minus3; + /* method-specific (e.g., Montgomery structure) */ + void *field_data1; + /* method-specific */ + void *field_data2; + /* method-specific */ + int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *); + BN_MONT_CTX *mont_data; /* data for ECDSA inverse */ +} /* EC_GROUP */ ; + +struct ec_key_st { + int version; + EC_GROUP *group; + EC_POINT *pub_key; + BIGNUM *priv_key; + unsigned int enc_flag; + point_conversion_form_t conv_form; + int references; + int flags; + EC_EXTRA_DATA *method_data; +} /* EC_KEY */ ; + +/* + * Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs + * only (with visibility limited to 'package' level for now). We use the + * function pointers as index for retrieval; this obviates global + * ex_data-style index tables. + */ +int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *, void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +void EC_EX_DATA_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **); +void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **); + +struct ec_point_st { + const EC_METHOD *meth; + /* + * All members except 'meth' are handled by the method functions, even if + * they appear generic + */ + BIGNUM X; + BIGNUM Y; + BIGNUM Z; /* Jacobian projective coordinates: (X, Y, Z) + * represents (X/Z^2, Y/Z^3) if Z != 0 */ + int Z_is_one; /* enable optimized point arithmetics for + * special case */ +} /* EC_POINT */ ; + +/* + * method functions in ec_mult.c (ec_lib.c uses these as defaults if + * group->method->mul is 0) + */ +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *); +int ec_wNAF_have_precompute_mult(const EC_GROUP *group); + +/* method functions in ecp_smpl.c */ +int ec_GFp_simple_group_init(EC_GROUP *); +void ec_GFp_simple_group_finish(EC_GROUP *); +void ec_GFp_simple_group_clear_finish(EC_GROUP *); +int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); +int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, BN_CTX *); +int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *); +int ec_GFp_simple_group_get_degree(const EC_GROUP *); +int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); +int ec_GFp_simple_point_init(EC_POINT *); +void ec_GFp_simple_point_finish(EC_POINT *); +void ec_GFp_simple_point_clear_finish(EC_POINT *); +int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); +int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, + EC_POINT *, const BIGNUM *x, + const BIGNUM *y, + const BIGNUM *z, BN_CTX *); +int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *); +int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *); +int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BN_CTX *); +int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, + BN_CTX *); +size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *); +int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, + const unsigned char *buf, size_t len, BN_CTX *); +int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); +int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + BN_CTX *); +int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); +int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, + BN_CTX *); +int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, + EC_POINT *[], BN_CTX *); +int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + +/* method functions in ecp_mont.c */ +int ec_GFp_mont_group_init(EC_GROUP *); +int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +void ec_GFp_mont_group_finish(EC_GROUP *); +void ec_GFp_mont_group_clear_finish(EC_GROUP *); +int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *); +int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); + +/* method functions in ecp_nist.c */ +int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); +int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + +/* method functions in ec2_smpl.c */ +int ec_GF2m_simple_group_init(EC_GROUP *); +void ec_GF2m_simple_group_finish(EC_GROUP *); +void ec_GF2m_simple_group_clear_finish(EC_GROUP *); +int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *); +int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *); +int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *); +int ec_GF2m_simple_group_get_degree(const EC_GROUP *); +int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); +int ec_GF2m_simple_point_init(EC_POINT *); +void ec_GF2m_simple_point_finish(EC_POINT *); +void ec_GF2m_simple_point_clear_finish(EC_POINT *); +int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *); +int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); +int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *); +int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BN_CTX *); +int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, + BN_CTX *); +size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *); +int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *, + const unsigned char *buf, size_t len, BN_CTX *); +int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); +int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + BN_CTX *); +int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); +int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, + BN_CTX *); +int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, + EC_POINT *[], BN_CTX *); +int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + +/* method functions in ec2_mult.c */ +int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ec_GF2m_have_precompute_mult(const EC_GROUP *group); + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/* method functions in ecp_nistp224.c */ +int ec_GFp_nistp224_group_init(EC_GROUP *group); +int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group); + +/* method functions in ecp_nistp256.c */ +int ec_GFp_nistp256_group_init(EC_GROUP *group); +int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group); + +/* method functions in ecp_nistp521.c */ +int ec_GFp_nistp521_group_init(EC_GROUP *group); +int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group); + +/* utility functions in ecp_nistputil.c */ +void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, + size_t felem_size, + void *tmp_felems, + void (*felem_one) (void *out), + int (*felem_is_zero) (const void + *in), + void (*felem_assign) (void *out, + const void + *in), + void (*felem_square) (void *out, + const void + *in), + void (*felem_mul) (void *out, + const void + *in1, + const void + *in2), + void (*felem_inv) (void *out, + const void + *in), + void (*felem_contract) (void + *out, + const + void + *in)); +void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, + unsigned char *digit, unsigned char in); +#endif + +#ifdef ECP_NISTZ256_ASM +/** Returns GFp methods using montgomery multiplication, with x86-64 optimized + * P256. See http://eprint.iacr.org/2013/816. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistz256_method(void); +#endif + +#ifdef OPENSSL_FIPS +EC_GROUP *FIPS_ec_group_new_curve_gfp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +EC_GROUP *FIPS_ec_group_new_curve_gf2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +EC_GROUP *FIPS_ec_group_new_by_curve_name(int nid); +#endif diff --git a/Sources/COpenSSL/ecb3_enc.c b/Sources/COpenSSL/ecb3_enc.c new file mode 100644 index 00000000..c49fbd41 --- /dev/null +++ b/Sources/COpenSSL/ecb3_enc.c @@ -0,0 +1,82 @@ +/* crypto/des/ecb3_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc) +{ + register DES_LONG l0, l1; + DES_LONG ll[2]; + const unsigned char *in = &(*input)[0]; + unsigned char *out = &(*output)[0]; + + c2l(in, l0); + c2l(in, l1); + ll[0] = l0; + ll[1] = l1; + if (enc) + DES_encrypt3(ll, ks1, ks2, ks3); + else + DES_decrypt3(ll, ks1, ks2, ks3); + l0 = ll[0]; + l1 = ll[1]; + l2c(l0, out); + l2c(l1, out); +} diff --git a/Sources/COpenSSL/ecb_enc.c b/Sources/COpenSSL/ecb_enc.c new file mode 100644 index 00000000..1f3627b0 --- /dev/null +++ b/Sources/COpenSSL/ecb_enc.c @@ -0,0 +1,124 @@ +/* crypto/des/ecb_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" +#include "des_ver.h" +#include "opensslv.h" +#include "bio.h" + +OPENSSL_GLOBAL const char libdes_version[] = "libdes" OPENSSL_VERSION_PTEXT; +OPENSSL_GLOBAL const char DES_version[] = "DES" OPENSSL_VERSION_PTEXT; + +const char *DES_options(void) +{ + static int init = 1; + static char buf[32]; + + if (init) { + const char *ptr, *unroll, *risc, *size; + +#ifdef DES_PTR + ptr = "ptr"; +#else + ptr = "idx"; +#endif +#if defined(DES_RISC1) || defined(DES_RISC2) +# ifdef DES_RISC1 + risc = "risc1"; +# endif +# ifdef DES_RISC2 + risc = "risc2"; +# endif +#else + risc = "cisc"; +#endif +#ifdef DES_UNROLL + unroll = "16"; +#else + unroll = "2"; +#endif + if (sizeof(DES_LONG) != sizeof(long)) + size = "int"; + else + size = "long"; + BIO_snprintf(buf, sizeof(buf), "des(%s,%s,%s,%s)", ptr, risc, unroll, + size); + init = 0; + } + return (buf); +} + +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc) +{ + register DES_LONG l; + DES_LONG ll[2]; + const unsigned char *in = &(*input)[0]; + unsigned char *out = &(*output)[0]; + + c2l(in, l); + ll[0] = l; + c2l(in, l); + ll[1] = l; + DES_encrypt1(ll, ks, enc); + l = ll[0]; + l2c(l, out); + l = ll[1]; + l2c(l, out); + l = ll[0] = ll[1] = 0; +} diff --git a/Sources/COpenSSL/ecdh.h b/Sources/COpenSSL/ecdh.h new file mode 100644 index 00000000..85e20860 --- /dev/null +++ b/Sources/COpenSSL/ecdh.h @@ -0,0 +1,134 @@ +/* crypto/ecdh/ecdh.h */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDH_H +# define HEADER_ECDH_H + +# include "opensslconf.h" + +# ifdef OPENSSL_NO_ECDH +# error ECDH is disabled. +# endif + +# include "ec.h" +# include "ossl_typ.h" +# ifndef OPENSSL_NO_DEPRECATED +# include "bn.h" +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define EC_FLAG_COFACTOR_ECDH 0x1000 + +const ECDH_METHOD *ECDH_OpenSSL(void); + +void ECDH_set_default_method(const ECDH_METHOD *); +const ECDH_METHOD *ECDH_get_default_method(void); +int ECDH_set_method(EC_KEY *, const ECDH_METHOD *); + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)); + +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDH_get_ex_data(EC_KEY *d, int idx); + +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDH_strings(void); + +/* Error codes for the ECDH functions. */ + +/* Function codes. */ +# define ECDH_F_ECDH_CHECK 102 +# define ECDH_F_ECDH_COMPUTE_KEY 100 +# define ECDH_F_ECDH_DATA_NEW_METHOD 101 + +/* Reason codes. */ +# define ECDH_R_KDF_FAILED 102 +# define ECDH_R_NON_FIPS_METHOD 103 +# define ECDH_R_NO_PRIVATE_VALUE 100 +# define ECDH_R_POINT_ARITHMETIC_FAILURE 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ecdsa.h b/Sources/COpenSSL/ecdsa.h new file mode 100644 index 00000000..3814095c --- /dev/null +++ b/Sources/COpenSSL/ecdsa.h @@ -0,0 +1,335 @@ +/* crypto/ecdsa/ecdsa.h */ +/** + * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions + * \author Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDSA_H +# define HEADER_ECDSA_H + +# include "opensslconf.h" + +# ifdef OPENSSL_NO_ECDSA +# error ECDSA is disabled. +# endif + +# include "ec.h" +# include "ossl_typ.h" +# ifndef OPENSSL_NO_DEPRECATED +# include "bn.h" +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ECDSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +} ECDSA_SIG; + +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *sig); + +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or 0 + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); + +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, + EC_KEY *eckey); + +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +const ECDSA_METHOD *ECDSA_OpenSSL(void); + +/** Sets the default ECDSA method + * \param meth new default ECDSA_METHOD + */ +void ECDSA_set_default_method(const ECDSA_METHOD *meth); + +/** Returns the default ECDSA method + * \return pointer to ECDSA_METHOD structure containing the default method + */ +const ECDSA_METHOD *ECDSA_get_default_method(void); + +/** Sets method to be used for the ECDSA operations + * \param eckey EC_KEY object + * \param meth new method + * \return 1 on success and 0 otherwise + */ +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); + +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/* the standard ex_data functions */ +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDSA_get_ex_data(EC_KEY *d, int idx); + +/** Allocates and initialize a ECDSA_METHOD structure + * \param ecdsa_method pointer to ECDSA_METHOD to copy. (May be NULL) + * \return pointer to a ECDSA_METHOD structure or NULL if an error occurred + */ + +ECDSA_METHOD *ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_method); + +/** frees a ECDSA_METHOD structure + * \param ecdsa_method pointer to the ECDSA_METHOD structure + */ +void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method); + +/** Sets application specific data in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param app application specific data to set + */ + +void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app); + +/** Returns application specific data from a ECDSA_METHOD structure + * \param ecdsa_method pointer to ECDSA_METHOD structure + * \return pointer to application specific data. + */ + +void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method); + +/** Set the ECDSA_do_sign function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_do_sign a funtion of type ECDSA_do_sign + */ + +void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method, + ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char + *dgst, int dgst_len, + const BIGNUM *inv, + const BIGNUM *rp, + EC_KEY *eckey)); + +/** Set the ECDSA_sign_setup function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_sign_setup a funtion of type ECDSA_sign_setup + */ + +void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_sign_setup) (EC_KEY *eckey, + BN_CTX *ctx, + BIGNUM **kinv, + BIGNUM **r)); + +/** Set the ECDSA_do_verify function in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param ecdsa_do_verify a funtion of type ECDSA_do_verify + */ + +void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_do_verify) (const unsigned char + *dgst, int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)); + +void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags); + +/** Set the flags field in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param flags flags value to set + */ + +void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name); + +/** Set the name field in the ECDSA_METHOD + * \param ecdsa_method pointer to existing ECDSA_METHOD + * \param name name to set + */ + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDSA_strings(void); + +/* Error codes for the ECDSA functions. */ + +/* Function codes. */ +# define ECDSA_F_ECDSA_CHECK 104 +# define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 +# define ECDSA_F_ECDSA_DO_SIGN 101 +# define ECDSA_F_ECDSA_DO_VERIFY 102 +# define ECDSA_F_ECDSA_METHOD_NEW 105 +# define ECDSA_F_ECDSA_SIGN_SETUP 103 + +/* Reason codes. */ +# define ECDSA_R_BAD_SIGNATURE 100 +# define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101 +# define ECDSA_R_ERR_EC_LIB 102 +# define ECDSA_R_MISSING_PARAMETERS 103 +# define ECDSA_R_NEED_NEW_SETUP_VALUES 106 +# define ECDSA_R_NON_FIPS_METHOD 107 +# define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +# define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ech_.c b/Sources/COpenSSL/ech_.c new file mode 100644 index 00000000..88894864 --- /dev/null +++ b/Sources/COpenSSL/ech_.c @@ -0,0 +1,782 @@ +/* crypto/ecdh/ech_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "ecdh.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason) + +static ERR_STRING_DATA ECDH_str_functs[] = { + {ERR_FUNC(ECDH_F_ECDH_CHECK), "ECDH_CHECK"}, + {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, + {ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"}, + {0, NULL} +}; + +static ERR_STRING_DATA ECDH_str_reasons[] = { + {ERR_REASON(ECDH_R_KDF_FAILED), "KDF failed"}, + {ERR_REASON(ECDH_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_REASON(ECDH_R_NO_PRIVATE_VALUE), "no private value"}, + {ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"}, + {0, NULL} +}; + +#endif + +void ERR_load_ECDH_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL) { + ERR_load_strings(0, ECDH_str_functs); + ERR_load_strings(0, ECDH_str_reasons); + } +#endif +} +/* crypto/ecdh/ec_kdf.c */ +/* + * Written by Stephen Henson for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#define OPENSSL_FIPSAPI + +#include +// #include "ecdh.h" +#include "evp.h" + +/* Key derivation function from X9.62/SECG */ +/* Way more than we will ever need */ +#define ECDH_KDF_MAX (1 << 30) + +int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, + const unsigned char *Z, size_t Zlen, + const unsigned char *sinfo, size_t sinfolen, + const EVP_MD *md) +{ + EVP_MD_CTX mctx; + int rv = 0; + unsigned int i; + size_t mdlen; + unsigned char ctr[4]; + if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX + || Zlen > ECDH_KDF_MAX) + return 0; + mdlen = EVP_MD_size(md); + EVP_MD_CTX_init(&mctx); + for (i = 1;; i++) { + unsigned char mtmp[EVP_MAX_MD_SIZE]; + EVP_DigestInit_ex(&mctx, md, NULL); + ctr[3] = i & 0xFF; + ctr[2] = (i >> 8) & 0xFF; + ctr[1] = (i >> 16) & 0xFF; + ctr[0] = (i >> 24) & 0xFF; + if (!EVP_DigestUpdate(&mctx, Z, Zlen)) + goto err; + if (!EVP_DigestUpdate(&mctx, ctr, sizeof(ctr))) + goto err; + if (!EVP_DigestUpdate(&mctx, sinfo, sinfolen)) + goto err; + if (outlen >= mdlen) { + if (!EVP_DigestFinal(&mctx, out, NULL)) + goto err; + outlen -= mdlen; + if (outlen == 0) + break; + out += mdlen; + } else { + if (!EVP_DigestFinal(&mctx, mtmp, NULL)) + goto err; + memcpy(out, mtmp, outlen); + OPENSSL_cleanse(mtmp, mdlen); + break; + } + } + rv = 1; + err: + EVP_MD_CTX_cleanup(&mctx); + return rv; +} +/* crypto/ecdh/ecdh_key.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ech_locl.h" + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *eckey, + void *(*KDF) (const void *in, size_t inlen, void *out, + size_t *outlen)) +{ + ECDH_DATA *ecdh = ecdh_check(eckey); + if (ecdh == NULL) + return 0; + return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF); +} +/* crypto/ecdh/ech_lib.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ech_locl.h" +#include +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +// #include "err.h" +#ifdef OPENSSL_FIPS +# include +#endif + +const char ECDH_version[] = "ECDH" OPENSSL_VERSION_PTEXT; + +static const ECDH_METHOD *default_ECDH_method = NULL; + +static void *ecdh_data_new(void); +static void *ecdh_data_dup(void *); +static void ecdh_data_free(void *); + +void ECDH_set_default_method(const ECDH_METHOD *meth) +{ + default_ECDH_method = meth; +} + +const ECDH_METHOD *ECDH_get_default_method(void) +{ + if (!default_ECDH_method) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ecdh_openssl(); + else + return ECDH_OpenSSL(); +#else + default_ECDH_method = ECDH_OpenSSL(); +#endif + } + return default_ECDH_method; +} + +int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth) +{ + ECDH_DATA *ecdh; + + ecdh = ecdh_check(eckey); + + if (ecdh == NULL) + return 0; + +#if 0 + mtmp = ecdh->meth; + if (mtmp->finish) + mtmp->finish(eckey); +#endif +#ifndef OPENSSL_NO_ENGINE + if (ecdh->engine) { + ENGINE_finish(ecdh->engine); + ecdh->engine = NULL; + } +#endif + ecdh->meth = meth; +#if 0 + if (meth->init) + meth->init(eckey); +#endif + return 1; +} + +static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine) +{ + ECDH_DATA *ret; + + ret = (ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA)); + if (ret == NULL) { + ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->init = NULL; + + ret->meth = ECDH_get_default_method(); + ret->engine = engine; +#ifndef OPENSSL_NO_ENGINE + if (!ret->engine) + ret->engine = ENGINE_get_default_ECDH(); + if (ret->engine) { + ret->meth = ENGINE_get_ECDH(ret->engine); + if (!ret->meth) { + ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->flags = ret->meth->flags; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); +#if 0 + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } +#endif + return (ret); +} + +static void *ecdh_data_new(void) +{ + return (void *)ECDH_DATA_new_method(NULL); +} + +static void *ecdh_data_dup(void *data) +{ + ECDH_DATA *r = (ECDH_DATA *)data; + + /* XXX: dummy operation */ + if (r == NULL) + return NULL; + + return (void *)ecdh_data_new(); +} + +void ecdh_data_free(void *data) +{ + ECDH_DATA *r = (ECDH_DATA *)data; + +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data); + + OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA)); + + OPENSSL_free(r); +} + +ECDH_DATA *ecdh_check(EC_KEY *key) +{ + ECDH_DATA *ecdh_data; + + void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup, + ecdh_data_free, ecdh_data_free); + if (data == NULL) { + ecdh_data = (ECDH_DATA *)ecdh_data_new(); + if (ecdh_data == NULL) + return NULL; + data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data, + ecdh_data_dup, ecdh_data_free, + ecdh_data_free); + if (data != NULL) { + /* + * Another thread raced us to install the key_method data and + * won. + */ + ecdh_data_free(ecdh_data); + ecdh_data = (ECDH_DATA *)data; + } else if (EC_KEY_get_key_method_data(key, ecdh_data_dup, + ecdh_data_free, + ecdh_data_free) != ecdh_data) { + /* Or an out of memory error in EC_KEY_insert_key_method_data. */ + ecdh_data_free(ecdh_data); + return NULL; + } + } else { + ecdh_data = (ECDH_DATA *)data; + } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD) + && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { + ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD); + return NULL; + } +#endif + + return ecdh_data; +} + +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp, + new_func, dup_func, free_func); +} + +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg) +{ + ECDH_DATA *ecdh; + ecdh = ecdh_check(d); + if (ecdh == NULL) + return 0; + return (CRYPTO_set_ex_data(&ecdh->ex_data, idx, arg)); +} + +void *ECDH_get_ex_data(EC_KEY *d, int idx) +{ + ECDH_DATA *ecdh; + ecdh = ecdh_check(d); + if (ecdh == NULL) + return NULL; + return (CRYPTO_get_ex_data(&ecdh->ex_data, idx)); +} +/* crypto/ecdh/ech_ossl.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "cryptlib.h" + +// #include "ech_locl.h" +// #include "err.h" +#include "sha.h" +#include "obj_mac.h" +#include "bn.h" + +static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key, + EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)); + +static ECDH_METHOD openssl_ecdh_meth = { + "OpenSSL ECDH method", + ecdh_compute_key, +#if 0 + NULL, /* init */ + NULL, /* finish */ +#endif + 0, /* flags */ + NULL /* app_data */ +}; + +const ECDH_METHOD *ECDH_OpenSSL(void) +{ + return &openssl_ecdh_meth; +} + +/*- + * This implementation is based on the following primitives in the IEEE 1363 standard: + * - ECKAS-DH1 + * - ECSVDP-DH + * Finally an optional KDF is applied. + */ +static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)) +{ + BN_CTX *ctx; + EC_POINT *tmp = NULL; + BIGNUM *x = NULL, *y = NULL; + const BIGNUM *priv_key; + const EC_GROUP *group; + int ret = -1; + size_t buflen, len; + unsigned char *buf = NULL; + + if (outlen > INT_MAX) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); /* sort of, + * anyway */ + return -1; + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + + priv_key = EC_KEY_get0_private_key(ecdh); + if (priv_key == NULL) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_NO_PRIVATE_VALUE); + goto err; + } + + group = EC_KEY_get0_group(ecdh); + + if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) { + if (!EC_GROUP_get_cofactor(group, x, ctx) || + !BN_mul(x, x, priv_key, ctx)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + priv_key = x; + } + + if ((tmp = EC_POINT_new(group)) == NULL) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == + NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + } +#endif + + buflen = (EC_GROUP_get_degree(group) + 7) / 8; + len = BN_num_bytes(x); + if (len > buflen) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); + goto err; + } + if ((buf = OPENSSL_malloc(buflen)) == NULL) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + memset(buf, 0, buflen - len); + if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + if (KDF != 0) { + if (KDF(buf, buflen, out, &outlen) == NULL) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KDF_FAILED); + goto err; + } + ret = outlen; + } else { + /* no KDF, just copy as much as we can */ + if (outlen > buflen) + outlen = buflen; + memcpy(out, buf, outlen); + ret = outlen; + } + + err: + if (tmp) + EC_POINT_free(tmp); + if (ctx) + BN_CTX_end(ctx); + if (ctx) + BN_CTX_free(ctx); + if (buf) { + OPENSSL_cleanse(buf, buflen); + OPENSSL_free(buf); + } + return (ret); +} diff --git a/Sources/COpenSSL/ech_locl.h b/Sources/COpenSSL/ech_locl.h new file mode 100644 index 00000000..68349f8c --- /dev/null +++ b/Sources/COpenSSL/ech_locl.h @@ -0,0 +1,104 @@ +/* crypto/ecdh/ech_locl.h */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ECH_LOCL_H +# define HEADER_ECH_LOCL_H + +# include "ecdh.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ecdh_method { + const char *name; + int (*compute_key) (void *key, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, void *(*KDF) (const void *in, + size_t inlen, void *out, + size_t *outlen)); +# if 0 + int (*init) (EC_KEY *eckey); + int (*finish) (EC_KEY *eckey); +# endif + int flags; + char *app_data; +}; + +/* + * If this flag is set the ECDH method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define ECDH_FLAG_FIPS_METHOD 0x1 + +typedef struct ecdh_data_st { + /* EC_KEY_METH_DATA part */ + int (*init) (EC_KEY *); + /* method specific part */ + ENGINE *engine; + int flags; + const ECDH_METHOD *meth; + CRYPTO_EX_DATA ex_data; +} ECDH_DATA; + +ECDH_DATA *ecdh_check(EC_KEY *); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_ECH_LOCL_H */ diff --git a/Sources/COpenSSL/eck_prn.c b/Sources/COpenSSL/eck_prn.c new file mode 100644 index 00000000..958b965a --- /dev/null +++ b/Sources/COpenSSL/eck_prn.c @@ -0,0 +1,377 @@ +/* crypto/ec/eck_prn.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions originally developed by SUN MICROSYSTEMS, INC., and + * contributed to the OpenSSL project. + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "ec.h" +#include "bn.h" + +#ifndef OPENSSL_NO_FP_API +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECPKParameters_print(b, x, off); + BIO_free(b); + return (ret); +} + +int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = EC_KEY_print(b, x, off); + BIO_free(b); + return (ret); +} + +int ECParameters_print_fp(FILE *fp, const EC_KEY *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECParameters_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; +} + +int ECParameters_print(BIO *bp, const EC_KEY *x) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) + return 0; + ret = EVP_PKEY_print_params(bp, pk, 4, NULL); + EVP_PKEY_free(pk); + return ret; +} + +static int print_bin(BIO *fp, const char *str, const unsigned char *num, + size_t len, int off); + +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) +{ + unsigned char *buffer = NULL; + size_t buf_len = 0, i; + int ret = 0, reason = ERR_R_BIO_LIB; + BN_CTX *ctx = NULL; + const EC_POINT *point = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, + *order = NULL, *cofactor = NULL; + const unsigned char *seed; + size_t seed_len = 0; + + static const char *gen_compressed = "Generator (compressed):"; + static const char *gen_uncompressed = "Generator (uncompressed):"; + static const char *gen_hybrid = "Generator (hybrid):"; + + if (!x) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (EC_GROUP_get_asn1_flag(x)) { + /* the curve parameter are given by an asn1 OID */ + int nid; + const char *nname; + + if (!BIO_indent(bp, off, 128)) + goto err; + + nid = EC_GROUP_get_curve_name(x); + if (nid == 0) + goto err; + + if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) + goto err; + if (BIO_printf(bp, "\n") <= 0) + goto err; + nname = EC_curve_nid2nist(nid); + if (nname) { + if (!BIO_indent(bp, off, 128)) + goto err; + if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0) + goto err; + } + } else { + /* explicit parameters */ + int is_char_two = 0; + point_conversion_form_t form; + int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); + + if (tmp_nid == NID_X9_62_characteristic_two_field) + is_char_two = 1; + + if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || + (b = BN_new()) == NULL || (order = BN_new()) == NULL || + (cofactor = BN_new()) == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } +#ifndef OPENSSL_NO_EC2M + if (is_char_two) { + if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) { + reason = ERR_R_EC_LIB; + goto err; + } + } else /* prime field */ +#endif + { + if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) { + reason = ERR_R_EC_LIB; + goto err; + } + } + + if ((point = EC_GROUP_get0_generator(x)) == NULL) { + reason = ERR_R_EC_LIB; + goto err; + } + if (!EC_GROUP_get_order(x, order, NULL) || + !EC_GROUP_get_cofactor(x, cofactor, NULL)) { + reason = ERR_R_EC_LIB; + goto err; + } + + form = EC_GROUP_get_point_conversion_form(x); + + if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) { + reason = ERR_R_EC_LIB; + goto err; + } + + buf_len = (size_t)BN_num_bytes(p); + if (buf_len < (i = (size_t)BN_num_bytes(a))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(b))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(gen))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(order))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) + buf_len = i; + + if ((seed = EC_GROUP_get0_seed(x)) != NULL) + seed_len = EC_GROUP_get_seed_len(x); + + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (!BIO_indent(bp, off, 128)) + goto err; + + /* print the 'short name' of the field type */ + if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) + <= 0) + goto err; + + if (is_char_two) { + /* print the 'short name' of the base type OID */ + int basis_type = EC_GROUP_get_basis_type(x); + if (basis_type == 0) + goto err; + + if (!BIO_indent(bp, off, 128)) + goto err; + + if (BIO_printf(bp, "Basis Type: %s\n", + OBJ_nid2sn(basis_type)) <= 0) + goto err; + + /* print the polynomial */ + if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, + off)) + goto err; + } else { + if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off)) + goto err; + } + if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) + goto err; + if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) + goto err; + if (form == POINT_CONVERSION_COMPRESSED) { + if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, + buffer, off)) + goto err; + } else if (form == POINT_CONVERSION_UNCOMPRESSED) { + if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, + buffer, off)) + goto err; + } else { /* form == POINT_CONVERSION_HYBRID */ + + if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, + buffer, off)) + goto err; + } + if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, + buffer, off)) + goto err; + if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, + buffer, off)) + goto err; + if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) + goto err; + } + ret = 1; + err: + if (!ret) + ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (gen) + BN_free(gen); + if (order) + BN_free(order); + if (cofactor) + BN_free(cofactor); + if (ctx) + BN_CTX_free(ctx); + if (buffer != NULL) + OPENSSL_free(buffer); + return (ret); +} + +static int print_bin(BIO *fp, const char *name, const unsigned char *buf, + size_t len, int off) +{ + size_t i; + char str[128 + 1 + 4]; + + if (buf == NULL) + return 1; + if (off > 0) { + if (off > 128) + off = 128; + memset(str, ' ', off); + if (BIO_write(fp, str, off) <= 0) + return 0; + } else { + off = 0; + } + + if (BIO_printf(fp, "%s", name) <= 0) + return 0; + + for (i = 0; i < len; i++) { + if ((i % 15) == 0) { + str[0] = '\n'; + memset(&(str[1]), ' ', off + 4); + if (BIO_write(fp, str, off + 1 + 4) <= 0) + return 0; + } + if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= + 0) + return 0; + } + if (BIO_write(fp, "\n", 1) <= 0) + return 0; + + return 1; +} diff --git a/Sources/COpenSSL/ecp_mont.c b/Sources/COpenSSL/ecp_mont.c new file mode 100644 index 00000000..19922347 --- /dev/null +++ b/Sources/COpenSSL/ecp_mont.c @@ -0,0 +1,310 @@ +/* crypto/ec/ecp_mont.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include "err.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +#include "ec_lcl.h" + +const EC_METHOD *EC_GFp_mont_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_mont_group_init, + ec_GFp_mont_group_finish, + ec_GFp_mont_group_clear_finish, + ec_GFp_mont_group_copy, + ec_GFp_mont_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_simple_point_get_affine_coordinates, + 0, 0, 0, + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + 0 /* mul */ , + 0 /* precompute_mult */ , + 0 /* have_precompute_mult */ , + ec_GFp_mont_field_mul, + ec_GFp_mont_field_sqr, + 0 /* field_div */ , + ec_GFp_mont_field_encode, + ec_GFp_mont_field_decode, + ec_GFp_mont_field_set_to_one + }; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return fips_ec_gfp_mont_method(); +#endif + + return &ret; +} + +int ec_GFp_mont_group_init(EC_GROUP *group) +{ + int ok; + + ok = ec_GFp_simple_group_init(group); + group->field_data1 = NULL; + group->field_data2 = NULL; + return ok; +} + +void ec_GFp_mont_group_finish(EC_GROUP *group) +{ + if (group->field_data1 != NULL) { + BN_MONT_CTX_free(group->field_data1); + group->field_data1 = NULL; + } + if (group->field_data2 != NULL) { + BN_free(group->field_data2); + group->field_data2 = NULL; + } + ec_GFp_simple_group_finish(group); +} + +void ec_GFp_mont_group_clear_finish(EC_GROUP *group) +{ + if (group->field_data1 != NULL) { + BN_MONT_CTX_free(group->field_data1); + group->field_data1 = NULL; + } + if (group->field_data2 != NULL) { + BN_clear_free(group->field_data2); + group->field_data2 = NULL; + } + ec_GFp_simple_group_clear_finish(group); +} + +int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + if (dest->field_data1 != NULL) { + BN_MONT_CTX_free(dest->field_data1); + dest->field_data1 = NULL; + } + if (dest->field_data2 != NULL) { + BN_clear_free(dest->field_data2); + dest->field_data2 = NULL; + } + + if (!ec_GFp_simple_group_copy(dest, src)) + return 0; + + if (src->field_data1 != NULL) { + dest->field_data1 = BN_MONT_CTX_new(); + if (dest->field_data1 == NULL) + return 0; + if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) + goto err; + } + if (src->field_data2 != NULL) { + dest->field_data2 = BN_dup(src->field_data2); + if (dest->field_data2 == NULL) + goto err; + } + + return 1; + + err: + if (dest->field_data1 != NULL) { + BN_MONT_CTX_free(dest->field_data1); + dest->field_data1 = NULL; + } + return 0; +} + +int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *one = NULL; + int ret = 0; + + if (group->field_data1 != NULL) { + BN_MONT_CTX_free(group->field_data1); + group->field_data1 = NULL; + } + if (group->field_data2 != NULL) { + BN_free(group->field_data2); + group->field_data2 = NULL; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + mont = BN_MONT_CTX_new(); + if (mont == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) { + ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB); + goto err; + } + one = BN_new(); + if (one == NULL) + goto err; + if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) + goto err; + + group->field_data1 = mont; + mont = NULL; + group->field_data2 = one; + one = NULL; + + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + + if (!ret) { + BN_MONT_CTX_free(group->field_data1); + group->field_data1 = NULL; + BN_free(group->field_data2); + group->field_data2 = NULL; + } + + err: + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (mont != NULL) + BN_MONT_CTX_free(mont); + if (one != NULL) + BN_free(one); + return ret; +} + +int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + if (group->field_data1 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx); +} + +int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + if (group->field_data1 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx); +} + +int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) +{ + if (group->field_data1 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx); +} + +int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) +{ + if (group->field_data1 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_from_montgomery(r, a, group->field_data1, ctx); +} + +int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, + BN_CTX *ctx) +{ + if (group->field_data2 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED); + return 0; + } + + if (!BN_copy(r, group->field_data2)) + return 0; + return 1; +} diff --git a/Sources/COpenSSL/ecp_nist.c b/Sources/COpenSSL/ecp_nist.c new file mode 100644 index 00000000..d174eac4 --- /dev/null +++ b/Sources/COpenSSL/ecp_nist.c @@ -0,0 +1,220 @@ +/* crypto/ec/ecp_nist.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +#include "err.h" +#include "obj_mac.h" +#include "ec_lcl.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +const EC_METHOD *EC_GFp_nist_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_simple_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_nist_group_copy, + ec_GFp_nist_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_simple_point_get_affine_coordinates, + 0, 0, 0, + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + 0 /* mul */ , + 0 /* precompute_mult */ , + 0 /* have_precompute_mult */ , + ec_GFp_nist_field_mul, + ec_GFp_nist_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return fips_ec_gfp_nist_method(); +#endif + + return &ret; +} + +int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + dest->field_mod_func = src->field_mod_func; + + return ec_GFp_simple_group_copy(dest, src); +} + +int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *tmp_bn; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + + BN_CTX_start(ctx); + if ((tmp_bn = BN_CTX_get(ctx)) == NULL) + goto err; + + if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) + group->field_mod_func = BN_nist_mod_192; + else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) + group->field_mod_func = BN_nist_mod_224; + else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0) + group->field_mod_func = BN_nist_mod_256; + else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0) + group->field_mod_func = BN_nist_mod_384; + else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0) + group->field_mod_func = BN_nist_mod_521; + else { + ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME); + goto err; + } + + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *ctx_new = NULL; + + if (!group || !r || !a || !b) { + ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if (!ctx) + if ((ctx_new = ctx = BN_CTX_new()) == NULL) + goto err; + + if (!BN_mul(r, a, b, ctx)) + goto err; + if (!group->field_mod_func(r, r, &group->field, ctx)) + goto err; + + ret = 1; + err: + if (ctx_new) + BN_CTX_free(ctx_new); + return ret; +} + +int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *ctx_new = NULL; + + if (!group || !r || !a) { + ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER); + goto err; + } + if (!ctx) + if ((ctx_new = ctx = BN_CTX_new()) == NULL) + goto err; + + if (!BN_sqr(r, a, ctx)) + goto err; + if (!group->field_mod_func(r, r, &group->field, ctx)) + goto err; + + ret = 1; + err: + if (ctx_new) + BN_CTX_free(ctx_new); + return ret; +} diff --git a/Sources/COpenSSL/ecp_nistp224.c b/Sources/COpenSSL/ecp_nistp224.c new file mode 100644 index 00000000..ea89e552 --- /dev/null +++ b/Sources/COpenSSL/ecp_nistp224.c @@ -0,0 +1,1767 @@ +/* crypto/ec/ecp_nistp224.c */ +/* + * Written by Emilia Kasper (Google) for the OpenSSL project. + */ +/* Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication + * + * Inspired by Daniel J. Bernstein's public domain nistp224 implementation + * and Adam Langley's public domain 64-bit C implementation of curve25519 + */ + +#include "opensslconf.h" +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif + +# include +# include "err.h" +# include "ec_lcl.h" + +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + /* even with gcc, the typedef won't work for 32-bit platforms */ +typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit + * platforms */ +# else +# error "Need GCC 3.1 or later to define type uint128_t" +# endif + +typedef uint8_t u8; +typedef uint64_t u64; + +/******************************************************************************/ +/*- + * INTERNAL REPRESENTATION OF FIELD ELEMENTS + * + * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3 + * using 64-bit coefficients called 'limbs', + * and sometimes (for multiplication results) as + * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6 + * using 128-bit coefficients called 'widelimbs'. + * A 4-limb representation is an 'felem'; + * a 7-widelimb representation is a 'widefelem'. + * Even within felems, bits of adjacent limbs overlap, and we don't always + * reduce the representations: we ensure that inputs to each felem + * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60, + * and fit into a 128-bit word without overflow. The coefficients are then + * again partially reduced to obtain an felem satisfying a_i < 2^57. + * We only reduce to the unique minimal representation at the end of the + * computation. + */ + +typedef uint64_t limb; +typedef uint128_t widelimb; + +typedef limb felem[4]; +typedef widelimb widefelem[7]; + +/* + * Field element represented as a byte arrary. 28*8 = 224 bits is also the + * group order size for the elliptic curve, and we also use this type for + * scalars for point multiplication. + */ +typedef u8 felem_bytearray[28]; + +static const felem_bytearray nistp224_curve_params[5] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}, + {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */ + 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, + 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4}, + {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */ + 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, + 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21}, + {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */ + 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, + 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34} +}; + +/*- + * Precomputed multiples of the standard generator + * Points are given in coordinates (X, Y, Z) where Z normally is 1 + * (0 for the point at infinity). + * For each field element, slice a_0 is word 0, etc. + * + * The table has 2 * 16 elements, starting with the following: + * index | bits | point + * ------+---------+------------------------------ + * 0 | 0 0 0 0 | 0G + * 1 | 0 0 0 1 | 1G + * 2 | 0 0 1 0 | 2^56G + * 3 | 0 0 1 1 | (2^56 + 1)G + * 4 | 0 1 0 0 | 2^112G + * 5 | 0 1 0 1 | (2^112 + 1)G + * 6 | 0 1 1 0 | (2^112 + 2^56)G + * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G + * 8 | 1 0 0 0 | 2^168G + * 9 | 1 0 0 1 | (2^168 + 1)G + * 10 | 1 0 1 0 | (2^168 + 2^56)G + * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G + * 12 | 1 1 0 0 | (2^168 + 2^112)G + * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G + * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G + * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G + * followed by a copy of this with each element multiplied by 2^28. + * + * The reason for this is so that we can clock bits into four different + * locations when doing simple scalar multiplies against the base point, + * and then another four locations using the second 16 elements. + */ +static const felem gmul[2][16][3] = { {{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}, + {{0x3280d6115c1d21, 0xc1d356c2112234, + 0x7f321390b94a03, 0xb70e0cbd6bb4bf}, + {0xd5819985007e34, 0x75a05a07476444, + 0xfb4c22dfe6cd43, 0xbd376388b5f723}, + {1, 0, 0, 0}}, + {{0xfd9675666ebbe9, 0xbca7664d40ce5e, + 0x2242df8d8a2a43, 0x1f49bbb0f99bc5}, + {0x29e0b892dc9c43, 0xece8608436e662, + 0xdc858f185310d0, 0x9812dd4eb8d321}, + {1, 0, 0, 0}}, + {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, + 0x16e9a3bbce8a3f, 0xeedcccd8c2a748}, + {0xf19f90ed50266d, 0xabf2b4bf65f9df, + 0x313865468fafec, 0x5cb379ba910a17}, + {1, 0, 0, 0}}, + {{0x0641966cab26e3, 0x91fb2991fab0a0, + 0xefec27a4e13a0b, 0x0499aa8a5f8ebe}, + {0x7510407766af5d, 0x84d929610d5450, + 0x81d77aae82f706, 0x6916f6d4338c5b}, + {1, 0, 0, 0}}, + {{0xea95ac3b1f15c6, 0x086000905e82d4, + 0xdd323ae4d1c8b1, 0x932b56be7685a3}, + {0x9ef93dea25dbbf, 0x41665960f390f0, + 0xfdec76dbe2a8a7, 0x523e80f019062a}, + {1, 0, 0, 0}}, + {{0x822fdd26732c73, 0xa01c83531b5d0f, + 0x363f37347c1ba4, 0xc391b45c84725c}, + {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, + 0xc393da7e222a7f, 0x1efb7890ede244}, + {1, 0, 0, 0}}, + {{0x4c9e90ca217da1, 0xd11beca79159bb, + 0xff8d33c2c98b7c, 0x2610b39409f849}, + {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, + 0x966c079b753c89, 0xfe67e4e820b112}, + {1, 0, 0, 0}}, + {{0xe28cae2df5312d, 0xc71b61d16f5c6e, + 0x79b7619a3e7c4c, 0x05c73240899b47}, + {0x9f7f6382c73e3a, 0x18615165c56bda, + 0x641fab2116fd56, 0x72855882b08394}, + {1, 0, 0, 0}}, + {{0x0469182f161c09, 0x74a98ca8d00fb5, + 0xb89da93489a3e0, 0x41c98768fb0c1d}, + {0xe5ea05fb32da81, 0x3dce9ffbca6855, + 0x1cfe2d3fbf59e6, 0x0e5e03408738a7}, + {1, 0, 0, 0}}, + {{0xdab22b2333e87f, 0x4430137a5dd2f6, + 0xe03ab9f738beb8, 0xcb0c5d0dc34f24}, + {0x764a7df0c8fda5, 0x185ba5c3fa2044, + 0x9281d688bcbe50, 0xc40331df893881}, + {1, 0, 0, 0}}, + {{0xb89530796f0f60, 0xade92bd26909a3, + 0x1a0c83fb4884da, 0x1765bf22a5a984}, + {0x772a9ee75db09e, 0x23bc6c67cec16f, + 0x4c1edba8b14e2f, 0xe2a215d9611369}, + {1, 0, 0, 0}}, + {{0x571e509fb5efb3, 0xade88696410552, + 0xc8ae85fada74fe, 0x6c7e4be83bbde3}, + {0xff9f51160f4652, 0xb47ce2495a6539, + 0xa2946c53b582f4, 0x286d2db3ee9a60}, + {1, 0, 0, 0}}, + {{0x40bbd5081a44af, 0x0995183b13926c, + 0xbcefba6f47f6d0, 0x215619e9cc0057}, + {0x8bc94d3b0df45e, 0xf11c54a3694f6f, + 0x8631b93cdfe8b5, 0xe7e3f4b0982db9}, + {1, 0, 0, 0}}, + {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, + 0x1c29819435d2c6, 0xc813132f4c07e9}, + {0x2891425503b11f, 0x08781030579fea, + 0xf5426ba5cc9674, 0x1e28ebf18562bc}, + {1, 0, 0, 0}}, + {{0x9f31997cc864eb, 0x06cd91d28b5e4c, + 0xff17036691a973, 0xf1aef351497c58}, + {0xdd1f2d600564ff, 0xdead073b1402db, + 0x74a684435bd693, 0xeea7471f962558}, + {1, 0, 0, 0}}}, +{{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}, + {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31}, + {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d}, + {1, 0, 0, 0}}, + {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3}, + {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a}, + {1, 0, 0, 0}}, + {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33}, + {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100}, + {1, 0, 0, 0}}, + {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5}, + {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea}, + {1, 0, 0, 0}}, + {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be}, + {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51}, + {1, 0, 0, 0}}, + {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1}, + {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb}, + {1, 0, 0, 0}}, + {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233}, + {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def}, + {1, 0, 0, 0}}, + {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae}, + {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45}, + {1, 0, 0, 0}}, + {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e}, + {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb}, + {1, 0, 0, 0}}, + {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de}, + {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3}, + {1, 0, 0, 0}}, + {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05}, + {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58}, + {1, 0, 0, 0}}, + {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb}, + {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0}, + {1, 0, 0, 0}}, + {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9}, + {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea}, + {1, 0, 0, 0}}, + {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba}, + {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405}, + {1, 0, 0, 0}}, + {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e}, + {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e}, + {1, 0, 0, 0}}} +}; + +/* Precomputation for the group generator. */ +typedef struct { + felem g_pre_comp[2][16][3]; + int references; +} NISTP224_PRE_COMP; + +const EC_METHOD *EC_GFp_nistp224_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_nistp224_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_nist_group_copy, + ec_GFp_nistp224_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_nistp224_point_get_affine_coordinates, + 0 /* point_set_compressed_coordinates */ , + 0 /* point2oct */ , + 0 /* oct2point */ , + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + ec_GFp_nistp224_points_mul, + ec_GFp_nistp224_precompute_mult, + ec_GFp_nistp224_have_precompute_mult, + ec_GFp_nist_field_mul, + ec_GFp_nist_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + + return &ret; +} + +/* + * Helper functions to convert field elements to/from internal representation + */ +static void bin28_to_felem(felem out, const u8 in[28]) +{ + out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff; + out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff; + out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff; + out[3] = (*((const uint64_t *)(in+20))) >> 8; +} + +static void felem_to_bin28(u8 out[28], const felem in) +{ + unsigned i; + for (i = 0; i < 7; ++i) { + out[i] = in[0] >> (8 * i); + out[i + 7] = in[1] >> (8 * i); + out[i + 14] = in[2] >> (8 * i); + out[i + 21] = in[3] >> (8 * i); + } +} + +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ +static void flip_endian(u8 *out, const u8 *in, unsigned len) +{ + unsigned i; + for (i = 0; i < len; ++i) + out[i] = in[len - 1 - i]; +} + +/* From OpenSSL BIGNUM to internal representation */ +static int BN_to_felem(felem out, const BIGNUM *bn) +{ + felem_bytearray b_in; + felem_bytearray b_out; + unsigned num_bytes; + + /* BN_bn2bin eats leading zeroes */ + memset(b_out, 0, sizeof(b_out)); + num_bytes = BN_num_bytes(bn); + if (num_bytes > sizeof(b_out)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + if (BN_is_negative(bn)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + num_bytes = BN_bn2bin(bn, b_in); + flip_endian(b_out, b_in, num_bytes); + bin28_to_felem(out, b_out); + return 1; +} + +/* From internal representation to OpenSSL BIGNUM */ +static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) +{ + felem_bytearray b_in, b_out; + felem_to_bin28(b_in, in); + flip_endian(b_out, b_in, sizeof(b_out)); + return BN_bin2bn(b_out, sizeof(b_out), out); +} + +/******************************************************************************/ +/*- + * FIELD OPERATIONS + * + * Field operations, using the internal representation of field elements. + * NB! These operations are specific to our point multiplication and cannot be + * expected to be correct in general - e.g., multiplication with a large scalar + * will cause an overflow. + * + */ + +static void felem_one(felem out) +{ + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; +} + +static void felem_assign(felem out, const felem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +/* Sum two field elements: out += in */ +static void felem_sum(felem out, const felem in) +{ + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +/* Get negative value: out = -in */ +/* Assumes in[i] < 2^57 */ +static void felem_neg(felem out, const felem in) +{ + static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2); + static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2); + static const limb two58m42m2 = (((limb) 1) << 58) - + (((limb) 1) << 42) - (((limb) 1) << 2); + + /* Set to 0 mod 2^224-2^96+1 to ensure out > in */ + out[0] = two58p2 - in[0]; + out[1] = two58m42m2 - in[1]; + out[2] = two58m2 - in[2]; + out[3] = two58m2 - in[3]; +} + +/* Subtract field elements: out -= in */ +/* Assumes in[i] < 2^57 */ +static void felem_diff(felem out, const felem in) +{ + static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2); + static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2); + static const limb two58m42m2 = (((limb) 1) << 58) - + (((limb) 1) << 42) - (((limb) 1) << 2); + + /* Add 0 mod 2^224-2^96+1 to ensure out > in */ + out[0] += two58p2; + out[1] += two58m42m2; + out[2] += two58m2; + out[3] += two58m2; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +/* Subtract in unreduced 128-bit mode: out -= in */ +/* Assumes in[i] < 2^119 */ +static void widefelem_diff(widefelem out, const widefelem in) +{ + static const widelimb two120 = ((widelimb) 1) << 120; + static const widelimb two120m64 = (((widelimb) 1) << 120) - + (((widelimb) 1) << 64); + static const widelimb two120m104m64 = (((widelimb) 1) << 120) - + (((widelimb) 1) << 104) - (((widelimb) 1) << 64); + + /* Add 0 mod 2^224-2^96+1 to ensure out > in */ + out[0] += two120; + out[1] += two120m64; + out[2] += two120m64; + out[3] += two120; + out[4] += two120m104m64; + out[5] += two120m64; + out[6] += two120m64; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; + out[4] -= in[4]; + out[5] -= in[5]; + out[6] -= in[6]; +} + +/* Subtract in mixed mode: out128 -= in64 */ +/* in[i] < 2^63 */ +static void felem_diff_128_64(widefelem out, const felem in) +{ + static const widelimb two64p8 = (((widelimb) 1) << 64) + + (((widelimb) 1) << 8); + static const widelimb two64m8 = (((widelimb) 1) << 64) - + (((widelimb) 1) << 8); + static const widelimb two64m48m8 = (((widelimb) 1) << 64) - + (((widelimb) 1) << 48) - (((widelimb) 1) << 8); + + /* Add 0 mod 2^224-2^96+1 to ensure out > in */ + out[0] += two64p8; + out[1] += two64m48m8; + out[2] += two64m8; + out[3] += two64m8; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +/* + * Multiply a field element by a scalar: out = out * scalar The scalars we + * actually use are small, so results fit without overflow + */ +static void felem_scalar(felem out, const limb scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; +} + +/* + * Multiply an unreduced field element by a scalar: out = out * scalar The + * scalars we actually use are small, so results fit without overflow + */ +static void widefelem_scalar(widefelem out, const widelimb scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; +} + +/* Square a field element: out = in^2 */ +static void felem_square(widefelem out, const felem in) +{ + limb tmp0, tmp1, tmp2; + tmp0 = 2 * in[0]; + tmp1 = 2 * in[1]; + tmp2 = 2 * in[2]; + out[0] = ((widelimb) in[0]) * in[0]; + out[1] = ((widelimb) in[0]) * tmp1; + out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1]; + out[3] = ((widelimb) in[3]) * tmp0 + ((widelimb) in[1]) * tmp2; + out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2]; + out[5] = ((widelimb) in[3]) * tmp2; + out[6] = ((widelimb) in[3]) * in[3]; +} + +/* Multiply two field elements: out = in1 * in2 */ +static void felem_mul(widefelem out, const felem in1, const felem in2) +{ + out[0] = ((widelimb) in1[0]) * in2[0]; + out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0]; + out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] + + ((widelimb) in1[2]) * in2[0]; + out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] + + ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0]; + out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] + + ((widelimb) in1[3]) * in2[1]; + out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2]; + out[6] = ((widelimb) in1[3]) * in2[3]; +} + +/*- + * Reduce seven 128-bit coefficients to four 64-bit coefficients. + * Requires in[i] < 2^126, + * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */ +static void felem_reduce(felem out, const widefelem in) +{ + static const widelimb two127p15 = (((widelimb) 1) << 127) + + (((widelimb) 1) << 15); + static const widelimb two127m71 = (((widelimb) 1) << 127) - + (((widelimb) 1) << 71); + static const widelimb two127m71m55 = (((widelimb) 1) << 127) - + (((widelimb) 1) << 71) - (((widelimb) 1) << 55); + widelimb output[5]; + + /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */ + output[0] = in[0] + two127p15; + output[1] = in[1] + two127m71m55; + output[2] = in[2] + two127m71; + output[3] = in[3]; + output[4] = in[4]; + + /* Eliminate in[4], in[5], in[6] */ + output[4] += in[6] >> 16; + output[3] += (in[6] & 0xffff) << 40; + output[2] -= in[6]; + + output[3] += in[5] >> 16; + output[2] += (in[5] & 0xffff) << 40; + output[1] -= in[5]; + + output[2] += output[4] >> 16; + output[1] += (output[4] & 0xffff) << 40; + output[0] -= output[4]; + + /* Carry 2 -> 3 -> 4 */ + output[3] += output[2] >> 56; + output[2] &= 0x00ffffffffffffff; + + output[4] = output[3] >> 56; + output[3] &= 0x00ffffffffffffff; + + /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */ + + /* Eliminate output[4] */ + output[2] += output[4] >> 16; + /* output[2] < 2^56 + 2^56 = 2^57 */ + output[1] += (output[4] & 0xffff) << 40; + output[0] -= output[4]; + + /* Carry 0 -> 1 -> 2 -> 3 */ + output[1] += output[0] >> 56; + out[0] = output[0] & 0x00ffffffffffffff; + + output[2] += output[1] >> 56; + /* output[2] < 2^57 + 2^72 */ + out[1] = output[1] & 0x00ffffffffffffff; + output[3] += output[2] >> 56; + /* output[3] <= 2^56 + 2^16 */ + out[2] = output[2] & 0x00ffffffffffffff; + + /*- + * out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, + * out[3] <= 2^56 + 2^16 (due to final carry), + * so out < 2*p + */ + out[3] = output[3]; +} + +static void felem_square_reduce(felem out, const felem in) +{ + widefelem tmp; + felem_square(tmp, in); + felem_reduce(out, tmp); +} + +static void felem_mul_reduce(felem out, const felem in1, const felem in2) +{ + widefelem tmp; + felem_mul(tmp, in1, in2); + felem_reduce(out, tmp); +} + +/* + * Reduce to unique minimal representation. Requires 0 <= in < 2*p (always + * call felem_reduce first) + */ +static void felem_contract(felem out, const felem in) +{ + static const int64_t two56 = ((limb) 1) << 56; + /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */ + /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */ + int64_t tmp[4], a; + tmp[0] = in[0]; + tmp[1] = in[1]; + tmp[2] = in[2]; + tmp[3] = in[3]; + /* Case 1: a = 1 iff in >= 2^224 */ + a = (in[3] >> 56); + tmp[0] -= a; + tmp[1] += a << 40; + tmp[3] &= 0x00ffffffffffffff; + /* + * Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 + * and the lower part is non-zero + */ + a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) | + (((int64_t) (in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63); + a &= 0x00ffffffffffffff; + /* turn a into an all-one mask (if a = 0) or an all-zero mask */ + a = (a - 1) >> 63; + /* subtract 2^224 - 2^96 + 1 if a is all-one */ + tmp[3] &= a ^ 0xffffffffffffffff; + tmp[2] &= a ^ 0xffffffffffffffff; + tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff; + tmp[0] -= 1 & a; + + /* + * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be + * non-zero, so we only need one step + */ + a = tmp[0] >> 63; + tmp[0] += two56 & a; + tmp[1] -= 1 & a; + + /* carry 1 -> 2 -> 3 */ + tmp[2] += tmp[1] >> 56; + tmp[1] &= 0x00ffffffffffffff; + + tmp[3] += tmp[2] >> 56; + tmp[2] &= 0x00ffffffffffffff; + + /* Now 0 <= out < p */ + out[0] = tmp[0]; + out[1] = tmp[1]; + out[2] = tmp[2]; + out[3] = tmp[3]; +} + +/* + * Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field + * elements are reduced to in < 2^225, so we only need to check three cases: + * 0, 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2 + */ +static limb felem_is_zero(const felem in) +{ + limb zero, two224m96p1, two225m97p2; + + zero = in[0] | in[1] | in[2] | in[3]; + zero = (((int64_t) (zero) - 1) >> 63) & 1; + two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) + | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff); + two224m96p1 = (((int64_t) (two224m96p1) - 1) >> 63) & 1; + two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) + | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff); + two225m97p2 = (((int64_t) (two225m97p2) - 1) >> 63) & 1; + return (zero | two224m96p1 | two225m97p2); +} + +static int felem_is_zero_int(const void *in) +{ + return (int)(felem_is_zero(in) & ((limb) 1)); +} + +/* Invert a field element */ +/* Computation chain copied from djb's code */ +static void felem_inv(felem out, const felem in) +{ + felem ftmp, ftmp2, ftmp3, ftmp4; + widefelem tmp; + unsigned i; + + felem_square(tmp, in); + felem_reduce(ftmp, tmp); /* 2 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^2 - 1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 2 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp2, tmp); /* 2^4 - 2 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^5 - 4 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^6 - 8 */ + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(ftmp, tmp); /* 2^6 - 1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp2, tmp); /* 2^7 - 2 */ + for (i = 0; i < 5; ++i) { /* 2^12 - 2^6 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(ftmp2, tmp); /* 2^12 - 1 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^13 - 2 */ + for (i = 0; i < 11; ++i) { /* 2^24 - 2^12 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^24 - 1 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^25 - 2 */ + for (i = 0; i < 23; ++i) { /* 2^48 - 2^24 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^48 - 1 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp4, tmp); /* 2^49 - 2 */ + for (i = 0; i < 47; ++i) { /* 2^96 - 2^48 */ + felem_square(tmp, ftmp4); + felem_reduce(ftmp4, tmp); + } + felem_mul(tmp, ftmp3, ftmp4); + felem_reduce(ftmp3, tmp); /* 2^96 - 1 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp4, tmp); /* 2^97 - 2 */ + for (i = 0; i < 23; ++i) { /* 2^120 - 2^24 */ + felem_square(tmp, ftmp4); + felem_reduce(ftmp4, tmp); + } + felem_mul(tmp, ftmp2, ftmp4); + felem_reduce(ftmp2, tmp); /* 2^120 - 1 */ + for (i = 0; i < 6; ++i) { /* 2^126 - 2^6 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(ftmp, tmp); /* 2^126 - 1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^127 - 2 */ + felem_mul(tmp, ftmp, in); + felem_reduce(ftmp, tmp); /* 2^127 - 1 */ + for (i = 0; i < 97; ++i) { /* 2^224 - 2^97 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } + felem_mul(tmp, ftmp, ftmp3); + felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */ +} + +/* + * Copy in constant time: if icopy == 1, copy in to out, if icopy == 0, copy + * out to itself. + */ +static void copy_conditional(felem out, const felem in, limb icopy) +{ + unsigned i; + /* + * icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one + */ + const limb copy = -icopy; + for (i = 0; i < 4; ++i) { + const limb tmp = copy & (in[i] ^ out[i]); + out[i] ^= tmp; + } +} + +/******************************************************************************/ +/*- + * ELLIPTIC CURVE POINT OPERATIONS + * + * Points are represented in Jacobian projective coordinates: + * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3), + * or to the point at infinity if Z == 0. + * + */ + +/*- + * Double an elliptic curve point: + * (X', Y', Z') = 2 * (X, Y, Z), where + * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2 + * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2 + * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed, + * while x_out == y_in is not (maybe this works, but it's not tested). + */ +static void +point_double(felem x_out, felem y_out, felem z_out, + const felem x_in, const felem y_in, const felem z_in) +{ + widefelem tmp, tmp2; + felem delta, gamma, beta, alpha, ftmp, ftmp2; + + felem_assign(ftmp, x_in); + felem_assign(ftmp2, x_in); + + /* delta = z^2 */ + felem_square(tmp, z_in); + felem_reduce(delta, tmp); + + /* gamma = y^2 */ + felem_square(tmp, y_in); + felem_reduce(gamma, tmp); + + /* beta = x*gamma */ + felem_mul(tmp, x_in, gamma); + felem_reduce(beta, tmp); + + /* alpha = 3*(x-delta)*(x+delta) */ + felem_diff(ftmp, delta); + /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */ + felem_sum(ftmp2, delta); + /* ftmp2[i] < 2^57 + 2^57 = 2^58 */ + felem_scalar(ftmp2, 3); + /* ftmp2[i] < 3 * 2^58 < 2^60 */ + felem_mul(tmp, ftmp, ftmp2); + /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */ + felem_reduce(alpha, tmp); + + /* x' = alpha^2 - 8*beta */ + felem_square(tmp, alpha); + /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ + felem_assign(ftmp, beta); + felem_scalar(ftmp, 8); + /* ftmp[i] < 8 * 2^57 = 2^60 */ + felem_diff_128_64(tmp, ftmp); + /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ + felem_reduce(x_out, tmp); + + /* z' = (y + z)^2 - gamma - delta */ + felem_sum(delta, gamma); + /* delta[i] < 2^57 + 2^57 = 2^58 */ + felem_assign(ftmp, y_in); + felem_sum(ftmp, z_in); + /* ftmp[i] < 2^57 + 2^57 = 2^58 */ + felem_square(tmp, ftmp); + /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */ + felem_diff_128_64(tmp, delta); + /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */ + felem_reduce(z_out, tmp); + + /* y' = alpha*(4*beta - x') - 8*gamma^2 */ + felem_scalar(beta, 4); + /* beta[i] < 4 * 2^57 = 2^59 */ + felem_diff(beta, x_out); + /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */ + felem_mul(tmp, alpha, beta); + /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */ + felem_square(tmp2, gamma); + /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */ + widefelem_scalar(tmp2, 8); + /* tmp2[i] < 8 * 2^116 = 2^119 */ + widefelem_diff(tmp, tmp2); + /* tmp[i] < 2^119 + 2^120 < 2^121 */ + felem_reduce(y_out, tmp); +} + +/*- + * Add two elliptic curve points: + * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where + * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 - + * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 + * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) - + * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3 + * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2) + * + * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0. + */ + +/* + * This function is not entirely constant-time: it includes a branch for + * checking whether the two input points are equal, (while not equal to the + * point at infinity). This case never happens during single point + * multiplication, so there is no timing leak for ECDH or ECDSA signing. + */ +static void point_add(felem x3, felem y3, felem z3, + const felem x1, const felem y1, const felem z1, + const int mixed, const felem x2, const felem y2, + const felem z2) +{ + felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out; + widefelem tmp, tmp2; + limb z1_is_zero, z2_is_zero, x_equal, y_equal; + + if (!mixed) { + /* ftmp2 = z2^2 */ + felem_square(tmp, z2); + felem_reduce(ftmp2, tmp); + + /* ftmp4 = z2^3 */ + felem_mul(tmp, ftmp2, z2); + felem_reduce(ftmp4, tmp); + + /* ftmp4 = z2^3*y1 */ + felem_mul(tmp2, ftmp4, y1); + felem_reduce(ftmp4, tmp2); + + /* ftmp2 = z2^2*x1 */ + felem_mul(tmp2, ftmp2, x1); + felem_reduce(ftmp2, tmp2); + } else { + /* + * We'll assume z2 = 1 (special case z2 = 0 is handled later) + */ + + /* ftmp4 = z2^3*y1 */ + felem_assign(ftmp4, y1); + + /* ftmp2 = z2^2*x1 */ + felem_assign(ftmp2, x1); + } + + /* ftmp = z1^2 */ + felem_square(tmp, z1); + felem_reduce(ftmp, tmp); + + /* ftmp3 = z1^3 */ + felem_mul(tmp, ftmp, z1); + felem_reduce(ftmp3, tmp); + + /* tmp = z1^3*y2 */ + felem_mul(tmp, ftmp3, y2); + /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ + + /* ftmp3 = z1^3*y2 - z2^3*y1 */ + felem_diff_128_64(tmp, ftmp4); + /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ + felem_reduce(ftmp3, tmp); + + /* tmp = z1^2*x2 */ + felem_mul(tmp, ftmp, x2); + /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ + + /* ftmp = z1^2*x2 - z2^2*x1 */ + felem_diff_128_64(tmp, ftmp2); + /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ + felem_reduce(ftmp, tmp); + + /* + * the formulae are incorrect if the points are equal so we check for + * this and do doubling if this happens + */ + x_equal = felem_is_zero(ftmp); + y_equal = felem_is_zero(ftmp3); + z1_is_zero = felem_is_zero(z1); + z2_is_zero = felem_is_zero(z2); + /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */ + if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + /* ftmp5 = z1*z2 */ + if (!mixed) { + felem_mul(tmp, z1, z2); + felem_reduce(ftmp5, tmp); + } else { + /* special case z2 = 0 is handled later */ + felem_assign(ftmp5, z1); + } + + /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */ + felem_mul(tmp, ftmp, ftmp5); + felem_reduce(z_out, tmp); + + /* ftmp = (z1^2*x2 - z2^2*x1)^2 */ + felem_assign(ftmp5, ftmp); + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + + /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */ + felem_mul(tmp, ftmp, ftmp5); + felem_reduce(ftmp5, tmp); + + /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */ + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(ftmp2, tmp); + + /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */ + felem_mul(tmp, ftmp4, ftmp5); + /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ + + /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */ + felem_square(tmp2, ftmp3); + /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */ + + /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */ + felem_diff_128_64(tmp2, ftmp5); + /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */ + + /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */ + felem_assign(ftmp5, ftmp2); + felem_scalar(ftmp5, 2); + /* ftmp5[i] < 2 * 2^57 = 2^58 */ + + /*- + * x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 - + * 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 + */ + felem_diff_128_64(tmp2, ftmp5); + /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */ + felem_reduce(x_out, tmp2); + + /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */ + felem_diff(ftmp2, x_out); + /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */ + + /* + * tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) + */ + felem_mul(tmp2, ftmp3, ftmp2); + /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */ + + /*- + * y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) - + * z2^3*y1*(z1^2*x2 - z2^2*x1)^3 + */ + widefelem_diff(tmp2, tmp); + /* tmp2[i] < 2^118 + 2^120 < 2^121 */ + felem_reduce(y_out, tmp2); + + /* + * the result (x_out, y_out, z_out) is incorrect if one of the inputs is + * the point at infinity, so we need to check for this separately + */ + + /* + * if point 1 is at infinity, copy point 2 to output, and vice versa + */ + copy_conditional(x_out, x2, z1_is_zero); + copy_conditional(x_out, x1, z2_is_zero); + copy_conditional(y_out, y2, z1_is_zero); + copy_conditional(y_out, y1, z2_is_zero); + copy_conditional(z_out, z2, z1_is_zero); + copy_conditional(z_out, z1, z2_is_zero); + felem_assign(x3, x_out); + felem_assign(y3, y_out); + felem_assign(z3, z_out); +} + +/* + * select_point selects the |idx|th point from a precomputation table and + * copies it to out. + * The pre_comp array argument should be size of |size| argument + */ +static void select_point(const u64 idx, unsigned int size, + const felem pre_comp[][3], felem out[3]) +{ + unsigned i, j; + limb *outlimbs = &out[0][0]; + memset(outlimbs, 0, 3 * sizeof(felem)); + + for (i = 0; i < size; i++) { + const limb *inlimbs = &pre_comp[i][0][0]; + u64 mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (j = 0; j < 4 * 3; j++) + outlimbs[j] |= inlimbs[j] & mask; + } +} + +/* get_bit returns the |i|th bit in |in| */ +static char get_bit(const felem_bytearray in, unsigned i) +{ + if (i >= 224) + return 0; + return (in[i >> 3] >> (i & 7)) & 1; +} + +/* + * Interleaved point multiplication using precomputed point multiples: The + * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars + * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the + * generator, using certain (large) precomputed multiples in g_pre_comp. + * Output point (X, Y, Z) is stored in x_out, y_out, z_out + */ +static void batch_mul(felem x_out, felem y_out, felem z_out, + const felem_bytearray scalars[], + const unsigned num_points, const u8 *g_scalar, + const int mixed, const felem pre_comp[][17][3], + const felem g_pre_comp[2][16][3]) +{ + int i, skip; + unsigned num; + unsigned gen_mul = (g_scalar != NULL); + felem nq[3], tmp[4]; + u64 bits; + u8 sign, digit; + + /* set nq to the point at infinity */ + memset(nq, 0, 3 * sizeof(felem)); + + /* + * Loop over all scalars msb-to-lsb, interleaving additions of multiples + * of the generator (two in each of the last 28 rounds) and additions of + * other points multiples (every 5th round). + */ + skip = 1; /* save two point operations in the first + * round */ + for (i = (num_points ? 220 : 27); i >= 0; --i) { + /* double */ + if (!skip) + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + + /* add multiples of the generator */ + if (gen_mul && (i <= 27)) { + /* first, look 28 bits upwards */ + bits = get_bit(g_scalar, i + 196) << 3; + bits |= get_bit(g_scalar, i + 140) << 2; + bits |= get_bit(g_scalar, i + 84) << 1; + bits |= get_bit(g_scalar, i + 28); + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp[1], tmp); + + if (!skip) { + /* value 1 below is argument for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + + /* second, look at the current position */ + bits = get_bit(g_scalar, i + 168) << 3; + bits |= get_bit(g_scalar, i + 112) << 2; + bits |= get_bit(g_scalar, i + 56) << 1; + bits |= get_bit(g_scalar, i); + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp[0], tmp); + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], + 1 /* mixed */ , tmp[0], tmp[1], tmp[2]); + } + + /* do other additions every 5 doublings */ + if (num_points && (i % 5 == 0)) { + /* loop over all scalars */ + for (num = 0; num < num_points; ++num) { + bits = get_bit(scalars[num], i + 4) << 5; + bits |= get_bit(scalars[num], i + 3) << 4; + bits |= get_bit(scalars[num], i + 2) << 3; + bits |= get_bit(scalars[num], i + 1) << 2; + bits |= get_bit(scalars[num], i) << 1; + bits |= get_bit(scalars[num], i - 1); + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + /* select the point to add or subtract */ + select_point(digit, 17, pre_comp[num], tmp); + felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative + * point */ + copy_conditional(tmp[1], tmp[3], sign); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], + mixed, tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + } + } + } + felem_assign(x_out, nq[0]); + felem_assign(y_out, nq[1]); + felem_assign(z_out, nq[2]); +} + +/******************************************************************************/ +/* + * FUNCTIONS TO MANAGE PRECOMPUTATION + */ + +static NISTP224_PRE_COMP *nistp224_pre_comp_new() +{ + NISTP224_PRE_COMP *ret = NULL; + ret = (NISTP224_PRE_COMP *) OPENSSL_malloc(sizeof(*ret)); + if (!ret) { + ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + return ret; + } + memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); + ret->references = 1; + return ret; +} + +static void *nistp224_pre_comp_dup(void *src_) +{ + NISTP224_PRE_COMP *src = src_; + + /* no need to actually copy, these objects never change! */ + CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + + return src_; +} + +static void nistp224_pre_comp_free(void *pre_) +{ + int i; + NISTP224_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_free(pre); +} + +static void nistp224_pre_comp_clear_free(void *pre_) +{ + int i; + NISTP224_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_cleanse(pre, sizeof(*pre)); + OPENSSL_free(pre); +} + +/******************************************************************************/ +/* + * OPENSSL EC_METHOD FUNCTIONS + */ + +int ec_GFp_nistp224_group_init(EC_GROUP *group) +{ + int ret; + ret = ec_GFp_simple_group_init(group); + group->a_is_minus3 = 1; + return ret; +} + +int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *curve_p, *curve_a, *curve_b; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((curve_p = BN_CTX_get(ctx)) == NULL) || + ((curve_a = BN_CTX_get(ctx)) == NULL) || + ((curve_b = BN_CTX_get(ctx)) == NULL)) + goto err; + BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p); + BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a); + BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b); + if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { + ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, + EC_R_WRONG_CURVE_PARAMETERS); + goto err; + } + group->field_mod_func = BN_nist_mod_224; + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = + * (X/Z^2, Y/Z^3) + */ +int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + felem z1, z2, x_in, y_in, x_out, y_out; + widefelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || + (!BN_to_felem(z1, &point->Z))) + return 0; + felem_inv(z2, z1); + felem_square(tmp, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, x_in, z1); + felem_reduce(x_in, tmp); + felem_contract(x_out, x_in); + if (x != NULL) { + if (!felem_to_BN(x, x_out)) { + ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + felem_mul(tmp, z1, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, y_in, z1); + felem_reduce(y_in, tmp); + felem_contract(y_out, y_in); + if (y != NULL) { + if (!felem_to_BN(y, y_out)) { + ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + return 1; +} + +static void make_points_affine(size_t num, felem points[ /* num */ ][3], + felem tmp_felems[ /* num+1 */ ]) +{ + /* + * Runs in constant time, unless an input is the point at infinity (which + * normally shouldn't happen). + */ + ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(felem), + tmp_felems, + (void (*)(void *))felem_one, + felem_is_zero_int, + (void (*)(void *, const void *)) + felem_assign, + (void (*)(void *, const void *)) + felem_square_reduce, (void (*) + (void *, + const void + *, + const void + *)) + felem_mul_reduce, + (void (*)(void *, const void *)) + felem_inv, + (void (*)(void *, const void *)) + felem_contract); +} + +/* + * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL + * values Result is stored in r (r can equal one of the inputs). + */ +int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + int ret = 0; + int j; + unsigned i; + int mixed = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y, *z, *tmp_scalar; + felem_bytearray g_secret; + felem_bytearray *secrets = NULL; + felem(*pre_comp)[17][3] = NULL; + felem *tmp_felems = NULL; + felem_bytearray tmp; + unsigned num_bytes; + int have_pre_comp = 0; + size_t num_points = num; + felem x_in, y_in, z_in, x_out, y_out, z_out; + NISTP224_PRE_COMP *pre = NULL; + const felem(*g_pre_comp)[16][3] = NULL; + EC_POINT *generator = NULL; + const EC_POINT *p = NULL; + const BIGNUM *p_scalar = NULL; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || + ((y = BN_CTX_get(ctx)) == NULL) || + ((z = BN_CTX_get(ctx)) == NULL) || + ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) + goto err; + + if (scalar != NULL) { + pre = EC_EX_DATA_get_data(group->extra_data, + nistp224_pre_comp_dup, + nistp224_pre_comp_free, + nistp224_pre_comp_clear_free); + if (pre) + /* we have precomputation, try to use it */ + g_pre_comp = (const felem(*)[16][3])pre->g_pre_comp; + else + /* try to use the standard precomputation */ + g_pre_comp = &gmul[0]; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + /* get the generator from precomputation */ + if (!felem_to_BN(x, g_pre_comp[0][1][0]) || + !felem_to_BN(y, g_pre_comp[0][1][1]) || + !felem_to_BN(z, g_pre_comp[0][1][2])) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_Jprojective_coordinates_GFp(group, + generator, x, y, z, + ctx)) + goto err; + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) + /* precomputation matches generator */ + have_pre_comp = 1; + else + /* + * we don't have valid precomputation: treat the generator as a + * random point + */ + num_points = num_points + 1; + } + + if (num_points > 0) { + if (num_points >= 3) { + /* + * unless we precompute multiples for just one or two points, + * converting those into affine form is time well spent + */ + mixed = 1; + } + secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); + pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem)); + if (mixed) + tmp_felems = + OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem)); + if ((secrets == NULL) || (pre_comp == NULL) + || (mixed && (tmp_felems == NULL))) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * we treat NULL scalars as 0, and NULL points as points at infinity, + * i.e., they contribute nothing to the linear combination + */ + memset(secrets, 0, num_points * sizeof(felem_bytearray)); + memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem)); + for (i = 0; i < num_points; ++i) { + if (i == num) + /* the generator */ + { + p = EC_GROUP_get0_generator(group); + p_scalar = scalar; + } else + /* the i^th point */ + { + p = points[i]; + p_scalar = scalars[i]; + } + if ((p_scalar != NULL) && (p != NULL)) { + /* reduce scalar to 0 <= scalar < 2^224 */ + if ((BN_num_bits(p_scalar) > 224) + || (BN_is_negative(p_scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(p_scalar, tmp); + flip_endian(secrets[i], tmp, num_bytes); + /* precompute multiples */ + if ((!BN_to_felem(x_out, &p->X)) || + (!BN_to_felem(y_out, &p->Y)) || + (!BN_to_felem(z_out, &p->Z))) + goto err; + felem_assign(pre_comp[i][1][0], x_out); + felem_assign(pre_comp[i][1][1], y_out); + felem_assign(pre_comp[i][1][2], z_out); + for (j = 2; j <= 16; ++j) { + if (j & 1) { + point_add(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][1][0], + pre_comp[i][1][1], pre_comp[i][1][2], 0, + pre_comp[i][j - 1][0], + pre_comp[i][j - 1][1], + pre_comp[i][j - 1][2]); + } else { + point_double(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][j / 2][0], + pre_comp[i][j / 2][1], + pre_comp[i][j / 2][2]); + } + } + } + } + if (mixed) + make_points_affine(num_points * 17, pre_comp[0], tmp_felems); + } + + /* the scalar for the generator */ + if ((scalar != NULL) && (have_pre_comp)) { + memset(g_secret, 0, sizeof(g_secret)); + /* reduce scalar to 0 <= scalar < 2^224 */ + if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(scalar, tmp); + flip_endian(g_secret, tmp, num_bytes); + /* do the multiplication with generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + g_secret, + mixed, (const felem(*)[17][3])pre_comp, g_pre_comp); + } else + /* do the multiplication without generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); + /* reduce the output to its unique minimal representation */ + felem_contract(x_in, x_out); + felem_contract(y_in, y_out); + felem_contract(z_in, z_out); + if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || + (!felem_to_BN(z, z_in))) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (secrets != NULL) + OPENSSL_free(secrets); + if (pre_comp != NULL) + OPENSSL_free(pre_comp); + if (tmp_felems != NULL) + OPENSSL_free(tmp_felems); + return ret; +} + +int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + NISTP224_PRE_COMP *pre = NULL; + int i, j; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + EC_POINT *generator = NULL; + felem tmp_felems[32]; + + /* throw away old precomputation */ + EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup, + nistp224_pre_comp_free, + nistp224_pre_comp_clear_free); + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) + goto err; + /* get the generator */ + if (group->generator == NULL) + goto err; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + BN_bin2bn(nistp224_curve_params[3], sizeof(felem_bytearray), x); + BN_bin2bn(nistp224_curve_params[4], sizeof(felem_bytearray), y); + if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) + goto err; + if ((pre = nistp224_pre_comp_new()) == NULL) + goto err; + /* + * if the generator is the standard one, use built-in precomputation + */ + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { + memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); + goto done; + } + if ((!BN_to_felem(pre->g_pre_comp[0][1][0], &group->generator->X)) || + (!BN_to_felem(pre->g_pre_comp[0][1][1], &group->generator->Y)) || + (!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z))) + goto err; + /* + * compute 2^56*G, 2^112*G, 2^168*G for the first table, 2^28*G, 2^84*G, + * 2^140*G, 2^196*G for the second one + */ + for (i = 1; i <= 8; i <<= 1) { + point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0], + pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]); + for (j = 0; j < 27; ++j) { + point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2], pre->g_pre_comp[1][i][0], + pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]); + } + if (i == 8) + break; + point_double(pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2], pre->g_pre_comp[1][i][0], + pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]); + for (j = 0; j < 27; ++j) { + point_double(pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2], + pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2]); + } + } + for (i = 0; i < 2; i++) { + /* g_pre_comp[i][0] is the point at infinity */ + memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0])); + /* the remaining multiples */ + /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */ + point_add(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], + pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0], + pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2], + 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */ + point_add(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], + pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0], + pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], + 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */ + point_add(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], + pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0], + pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], + 0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], + pre->g_pre_comp[i][4][2]); + /* + * 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G + */ + point_add(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], + pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0], + pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2], + 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + for (j = 1; j < 8; ++j) { + /* odd multiples: add G resp. 2^28*G */ + point_add(pre->g_pre_comp[i][2 * j + 1][0], + pre->g_pre_comp[i][2 * j + 1][1], + pre->g_pre_comp[i][2 * j + 1][2], + pre->g_pre_comp[i][2 * j][0], + pre->g_pre_comp[i][2 * j][1], + pre->g_pre_comp[i][2 * j][2], 0, + pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1], + pre->g_pre_comp[i][1][2]); + } + } + make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems); + + done: + if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup, + nistp224_pre_comp_free, + nistp224_pre_comp_clear_free)) + goto err; + ret = 1; + pre = NULL; + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (pre) + nistp224_pre_comp_free(pre); + return ret; +} + +int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group) +{ + if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup, + nistp224_pre_comp_free, + nistp224_pre_comp_clear_free) + != NULL) + return 1; + else + return 0; +} + +#else +static void *dummy = &dummy; +#endif diff --git a/Sources/COpenSSL/ecp_nistp256.c b/Sources/COpenSSL/ecp_nistp256.c new file mode 100644 index 00000000..bacb006a --- /dev/null +++ b/Sources/COpenSSL/ecp_nistp256.c @@ -0,0 +1,2369 @@ +/* crypto/ec/ecp_nistp256.c */ +/* + * Written by Adam Langley (Google) for the OpenSSL project + */ +/* Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication + * + * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c. + * Otherwise based on Emilia's P224 work, which was inspired by my curve25519 + * work which got its smarts from Daniel J. Bernstein's work on the same. + */ + +#include "opensslconf.h" +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif + +# include +# include "err.h" +# include "ec_lcl.h" + +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + /* even with gcc, the typedef won't work for 32-bit platforms */ +typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit + * platforms */ +typedef __int128_t int128_t; +# else +# error "Need GCC 3.1 or later to define type uint128_t" +# endif + +typedef uint8_t u8; +typedef uint32_t u32; +typedef uint64_t u64; + +/* + * The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We + * can serialise an element of this field into 32 bytes. We call this an + * felem_bytearray. + */ + +typedef u8 felem_bytearray[32]; + +/* + * These are the parameters of P256, taken from FIPS 186-3, page 86. These + * values are big-endian. + */ +static const felem_bytearray nistp256_curve_params[5] = { + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */ + {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, + 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, + 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, + 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b}, + {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */ + 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, + 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, + 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96}, + {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */ + 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, + 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5} +}; + +/*- + * The representation of field elements. + * ------------------------------------ + * + * We represent field elements with either four 128-bit values, eight 128-bit + * values, or four 64-bit values. The field element represented is: + * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p) + * or: + * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p) + * + * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits + * apart, but are 128-bits wide, the most significant bits of each limb overlap + * with the least significant bits of the next. + * + * A field element with four limbs is an 'felem'. One with eight limbs is a + * 'longfelem' + * + * A field element with four, 64-bit values is called a 'smallfelem'. Small + * values are used as intermediate values before multiplication. + */ + +# define NLIMBS 4 + +typedef uint128_t limb; +typedef limb felem[NLIMBS]; +typedef limb longfelem[NLIMBS * 2]; +typedef u64 smallfelem[NLIMBS]; + +/* This is the value of the prime as four 64-bit words, little-endian. */ +static const u64 kPrime[4] = + { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul }; +static const u64 bottom63bits = 0x7ffffffffffffffful; + +/* + * bin32_to_felem takes a little-endian byte array and converts it into felem + * form. This assumes that the CPU is little-endian. + */ +static void bin32_to_felem(felem out, const u8 in[32]) +{ + out[0] = *((u64 *)&in[0]); + out[1] = *((u64 *)&in[8]); + out[2] = *((u64 *)&in[16]); + out[3] = *((u64 *)&in[24]); +} + +/* + * smallfelem_to_bin32 takes a smallfelem and serialises into a little + * endian, 32 byte array. This assumes that the CPU is little-endian. + */ +static void smallfelem_to_bin32(u8 out[32], const smallfelem in) +{ + *((u64 *)&out[0]) = in[0]; + *((u64 *)&out[8]) = in[1]; + *((u64 *)&out[16]) = in[2]; + *((u64 *)&out[24]) = in[3]; +} + +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ +static void flip_endian(u8 *out, const u8 *in, unsigned len) +{ + unsigned i; + for (i = 0; i < len; ++i) + out[i] = in[len - 1 - i]; +} + +/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ +static int BN_to_felem(felem out, const BIGNUM *bn) +{ + felem_bytearray b_in; + felem_bytearray b_out; + unsigned num_bytes; + + /* BN_bn2bin eats leading zeroes */ + memset(b_out, 0, sizeof(b_out)); + num_bytes = BN_num_bytes(bn); + if (num_bytes > sizeof(b_out)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + if (BN_is_negative(bn)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + num_bytes = BN_bn2bin(bn, b_in); + flip_endian(b_out, b_in, num_bytes); + bin32_to_felem(out, b_out); + return 1; +} + +/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ +static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in) +{ + felem_bytearray b_in, b_out; + smallfelem_to_bin32(b_in, in); + flip_endian(b_out, b_in, sizeof(b_out)); + return BN_bin2bn(b_out, sizeof(b_out), out); +} + +/*- + * Field operations + * ---------------- + */ + +static void smallfelem_one(smallfelem out) +{ + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; +} + +static void smallfelem_assign(smallfelem out, const smallfelem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +static void felem_assign(felem out, const felem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +/* felem_sum sets out = out + in. */ +static void felem_sum(felem out, const felem in) +{ + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +/* felem_small_sum sets out = out + in. */ +static void felem_small_sum(felem out, const smallfelem in) +{ + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +/* felem_scalar sets out = out * scalar */ +static void felem_scalar(felem out, const u64 scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; +} + +/* longfelem_scalar sets out = out * scalar */ +static void longfelem_scalar(longfelem out, const u64 scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; + out[7] *= scalar; +} + +# define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9) +# define two105 (((limb)1) << 105) +# define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9) + +/* zero105 is 0 mod p */ +static const felem zero105 = + { two105m41m9, two105, two105m41p9, two105m41p9 }; + +/*- + * smallfelem_neg sets |out| to |-small| + * On exit: + * out[i] < out[i] + 2^105 + */ +static void smallfelem_neg(felem out, const smallfelem small) +{ + /* In order to prevent underflow, we subtract from 0 mod p. */ + out[0] = zero105[0] - small[0]; + out[1] = zero105[1] - small[1]; + out[2] = zero105[2] - small[2]; + out[3] = zero105[3] - small[3]; +} + +/*- + * felem_diff subtracts |in| from |out| + * On entry: + * in[i] < 2^104 + * On exit: + * out[i] < out[i] + 2^105 + */ +static void felem_diff(felem out, const felem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + out[0] += zero105[0]; + out[1] += zero105[1]; + out[2] += zero105[2]; + out[3] += zero105[3]; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +# define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11) +# define two107 (((limb)1) << 107) +# define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11) + +/* zero107 is 0 mod p */ +static const felem zero107 = + { two107m43m11, two107, two107m43p11, two107m43p11 }; + +/*- + * An alternative felem_diff for larger inputs |in| + * felem_diff_zero107 subtracts |in| from |out| + * On entry: + * in[i] < 2^106 + * On exit: + * out[i] < out[i] + 2^107 + */ +static void felem_diff_zero107(felem out, const felem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + out[0] += zero107[0]; + out[1] += zero107[1]; + out[2] += zero107[2]; + out[3] += zero107[3]; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +/*- + * longfelem_diff subtracts |in| from |out| + * On entry: + * in[i] < 7*2^67 + * On exit: + * out[i] < out[i] + 2^70 + 2^40 + */ +static void longfelem_diff(longfelem out, const longfelem in) +{ + static const limb two70m8p6 = + (((limb) 1) << 70) - (((limb) 1) << 8) + (((limb) 1) << 6); + static const limb two70p40 = (((limb) 1) << 70) + (((limb) 1) << 40); + static const limb two70 = (((limb) 1) << 70); + static const limb two70m40m38p6 = + (((limb) 1) << 70) - (((limb) 1) << 40) - (((limb) 1) << 38) + + (((limb) 1) << 6); + static const limb two70m6 = (((limb) 1) << 70) - (((limb) 1) << 6); + + /* add 0 mod p to avoid underflow */ + out[0] += two70m8p6; + out[1] += two70p40; + out[2] += two70; + out[3] += two70m40m38p6; + out[4] += two70m6; + out[5] += two70m6; + out[6] += two70m6; + out[7] += two70m6; + + /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */ + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; + out[4] -= in[4]; + out[5] -= in[5]; + out[6] -= in[6]; + out[7] -= in[7]; +} + +# define two64m0 (((limb)1) << 64) - 1 +# define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1 +# define two64m46 (((limb)1) << 64) - (((limb)1) << 46) +# define two64m32 (((limb)1) << 64) - (((limb)1) << 32) + +/* zero110 is 0 mod p */ +static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 }; + +/*- + * felem_shrink converts an felem into a smallfelem. The result isn't quite + * minimal as the value may be greater than p. + * + * On entry: + * in[i] < 2^109 + * On exit: + * out[i] < 2^64 + */ +static void felem_shrink(smallfelem out, const felem in) +{ + felem tmp; + u64 a, b, mask; + u64 high, low; + static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */ + + /* Carry 2->3 */ + tmp[3] = zero110[3] + in[3] + ((u64)(in[2] >> 64)); + /* tmp[3] < 2^110 */ + + tmp[2] = zero110[2] + (u64)in[2]; + tmp[0] = zero110[0] + in[0]; + tmp[1] = zero110[1] + in[1]; + /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */ + + /* + * We perform two partial reductions where we eliminate the high-word of + * tmp[3]. We don't update the other words till the end. + */ + a = tmp[3] >> 64; /* a < 2^46 */ + tmp[3] = (u64)tmp[3]; + tmp[3] -= a; + tmp[3] += ((limb) a) << 32; + /* tmp[3] < 2^79 */ + + b = a; + a = tmp[3] >> 64; /* a < 2^15 */ + b += a; /* b < 2^46 + 2^15 < 2^47 */ + tmp[3] = (u64)tmp[3]; + tmp[3] -= a; + tmp[3] += ((limb) a) << 32; + /* tmp[3] < 2^64 + 2^47 */ + + /* + * This adjusts the other two words to complete the two partial + * reductions. + */ + tmp[0] += b; + tmp[1] -= (((limb) b) << 32); + + /* + * In order to make space in tmp[3] for the carry from 2 -> 3, we + * conditionally subtract kPrime if tmp[3] is large enough. + */ + high = (u64)(tmp[3] >> 64); + /* As tmp[3] < 2^65, high is either 1 or 0 */ + high = 0 - high; + /*- + * high is: + * all ones if the high word of tmp[3] is 1 + * all zeros if the high word of tmp[3] if 0 + */ + low = (u64)tmp[3]; + mask = 0 - (low >> 63); + /*- + * mask is: + * all ones if the MSB of low is 1 + * all zeros if the MSB of low if 0 + */ + low &= bottom63bits; + low -= kPrime3Test; + /* if low was greater than kPrime3Test then the MSB is zero */ + low = ~low; + low = 0 - (low >> 63); + /*- + * low is: + * all ones if low was > kPrime3Test + * all zeros if low was <= kPrime3Test + */ + mask = (mask & low) | high; + tmp[0] -= mask & kPrime[0]; + tmp[1] -= mask & kPrime[1]; + /* kPrime[2] is zero, so omitted */ + tmp[3] -= mask & kPrime[3]; + /* tmp[3] < 2**64 - 2**32 + 1 */ + + tmp[1] += ((u64)(tmp[0] >> 64)); + tmp[0] = (u64)tmp[0]; + tmp[2] += ((u64)(tmp[1] >> 64)); + tmp[1] = (u64)tmp[1]; + tmp[3] += ((u64)(tmp[2] >> 64)); + tmp[2] = (u64)tmp[2]; + /* tmp[i] < 2^64 */ + + out[0] = tmp[0]; + out[1] = tmp[1]; + out[2] = tmp[2]; + out[3] = tmp[3]; +} + +/* smallfelem_expand converts a smallfelem to an felem */ +static void smallfelem_expand(felem out, const smallfelem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +/*- + * smallfelem_square sets |out| = |small|^2 + * On entry: + * small[i] < 2^64 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void smallfelem_square(longfelem out, const smallfelem small) +{ + limb a; + u64 high, low; + + a = ((uint128_t) small[0]) * small[0]; + low = a; + high = a >> 64; + out[0] = low; + out[1] = high; + + a = ((uint128_t) small[0]) * small[1]; + low = a; + high = a >> 64; + out[1] += low; + out[1] += low; + out[2] = high; + + a = ((uint128_t) small[0]) * small[2]; + low = a; + high = a >> 64; + out[2] += low; + out[2] *= 2; + out[3] = high; + + a = ((uint128_t) small[0]) * small[3]; + low = a; + high = a >> 64; + out[3] += low; + out[4] = high; + + a = ((uint128_t) small[1]) * small[2]; + low = a; + high = a >> 64; + out[3] += low; + out[3] *= 2; + out[4] += high; + + a = ((uint128_t) small[1]) * small[1]; + low = a; + high = a >> 64; + out[2] += low; + out[3] += high; + + a = ((uint128_t) small[1]) * small[3]; + low = a; + high = a >> 64; + out[4] += low; + out[4] *= 2; + out[5] = high; + + a = ((uint128_t) small[2]) * small[3]; + low = a; + high = a >> 64; + out[5] += low; + out[5] *= 2; + out[6] = high; + out[6] += high; + + a = ((uint128_t) small[2]) * small[2]; + low = a; + high = a >> 64; + out[4] += low; + out[5] += high; + + a = ((uint128_t) small[3]) * small[3]; + low = a; + high = a >> 64; + out[6] += low; + out[7] = high; +} + +/*- + * felem_square sets |out| = |in|^2 + * On entry: + * in[i] < 2^109 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void felem_square(longfelem out, const felem in) +{ + u64 small[4]; + felem_shrink(small, in); + smallfelem_square(out, small); +} + +/*- + * smallfelem_mul sets |out| = |small1| * |small2| + * On entry: + * small1[i] < 2^64 + * small2[i] < 2^64 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void smallfelem_mul(longfelem out, const smallfelem small1, + const smallfelem small2) +{ + limb a; + u64 high, low; + + a = ((uint128_t) small1[0]) * small2[0]; + low = a; + high = a >> 64; + out[0] = low; + out[1] = high; + + a = ((uint128_t) small1[0]) * small2[1]; + low = a; + high = a >> 64; + out[1] += low; + out[2] = high; + + a = ((uint128_t) small1[1]) * small2[0]; + low = a; + high = a >> 64; + out[1] += low; + out[2] += high; + + a = ((uint128_t) small1[0]) * small2[2]; + low = a; + high = a >> 64; + out[2] += low; + out[3] = high; + + a = ((uint128_t) small1[1]) * small2[1]; + low = a; + high = a >> 64; + out[2] += low; + out[3] += high; + + a = ((uint128_t) small1[2]) * small2[0]; + low = a; + high = a >> 64; + out[2] += low; + out[3] += high; + + a = ((uint128_t) small1[0]) * small2[3]; + low = a; + high = a >> 64; + out[3] += low; + out[4] = high; + + a = ((uint128_t) small1[1]) * small2[2]; + low = a; + high = a >> 64; + out[3] += low; + out[4] += high; + + a = ((uint128_t) small1[2]) * small2[1]; + low = a; + high = a >> 64; + out[3] += low; + out[4] += high; + + a = ((uint128_t) small1[3]) * small2[0]; + low = a; + high = a >> 64; + out[3] += low; + out[4] += high; + + a = ((uint128_t) small1[1]) * small2[3]; + low = a; + high = a >> 64; + out[4] += low; + out[5] = high; + + a = ((uint128_t) small1[2]) * small2[2]; + low = a; + high = a >> 64; + out[4] += low; + out[5] += high; + + a = ((uint128_t) small1[3]) * small2[1]; + low = a; + high = a >> 64; + out[4] += low; + out[5] += high; + + a = ((uint128_t) small1[2]) * small2[3]; + low = a; + high = a >> 64; + out[5] += low; + out[6] = high; + + a = ((uint128_t) small1[3]) * small2[2]; + low = a; + high = a >> 64; + out[5] += low; + out[6] += high; + + a = ((uint128_t) small1[3]) * small2[3]; + low = a; + high = a >> 64; + out[6] += low; + out[7] = high; +} + +/*- + * felem_mul sets |out| = |in1| * |in2| + * On entry: + * in1[i] < 2^109 + * in2[i] < 2^109 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void felem_mul(longfelem out, const felem in1, const felem in2) +{ + smallfelem small1, small2; + felem_shrink(small1, in1); + felem_shrink(small2, in2); + smallfelem_mul(out, small1, small2); +} + +/*- + * felem_small_mul sets |out| = |small1| * |in2| + * On entry: + * small1[i] < 2^64 + * in2[i] < 2^109 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void felem_small_mul(longfelem out, const smallfelem small1, + const felem in2) +{ + smallfelem small2; + felem_shrink(small2, in2); + smallfelem_mul(out, small1, small2); +} + +# define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4) +# define two100 (((limb)1) << 100) +# define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4) +/* zero100 is 0 mod p */ +static const felem zero100 = + { two100m36m4, two100, two100m36p4, two100m36p4 }; + +/*- + * Internal function for the different flavours of felem_reduce. + * felem_reduce_ reduces the higher coefficients in[4]-in[7]. + * On entry: + * out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7] + * out[1] >= in[7] + 2^32*in[4] + * out[2] >= in[5] + 2^32*in[5] + * out[3] >= in[4] + 2^32*in[5] + 2^32*in[6] + * On exit: + * out[0] <= out[0] + in[4] + 2^32*in[5] + * out[1] <= out[1] + in[5] + 2^33*in[6] + * out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7] + * out[3] <= out[3] + 2^32*in[4] + 3*in[7] + */ +static void felem_reduce_(felem out, const longfelem in) +{ + int128_t c; + /* combine common terms from below */ + c = in[4] + (in[5] << 32); + out[0] += c; + out[3] -= c; + + c = in[5] - in[7]; + out[1] += c; + out[2] -= c; + + /* the remaining terms */ + /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */ + out[1] -= (in[4] << 32); + out[3] += (in[4] << 32); + + /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */ + out[2] -= (in[5] << 32); + + /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */ + out[0] -= in[6]; + out[0] -= (in[6] << 32); + out[1] += (in[6] << 33); + out[2] += (in[6] * 2); + out[3] -= (in[6] << 32); + + /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */ + out[0] -= in[7]; + out[0] -= (in[7] << 32); + out[2] += (in[7] << 33); + out[3] += (in[7] * 3); +} + +/*- + * felem_reduce converts a longfelem into an felem. + * To be called directly after felem_square or felem_mul. + * On entry: + * in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64 + * in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64 + * On exit: + * out[i] < 2^101 + */ +static void felem_reduce(felem out, const longfelem in) +{ + out[0] = zero100[0] + in[0]; + out[1] = zero100[1] + in[1]; + out[2] = zero100[2] + in[2]; + out[3] = zero100[3] + in[3]; + + felem_reduce_(out, in); + + /*- + * out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0 + * out[1] > 2^100 - 2^64 - 7*2^96 > 0 + * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0 + * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0 + * + * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101 + * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101 + * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101 + * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101 + */ +} + +/*- + * felem_reduce_zero105 converts a larger longfelem into an felem. + * On entry: + * in[0] < 2^71 + * On exit: + * out[i] < 2^106 + */ +static void felem_reduce_zero105(felem out, const longfelem in) +{ + out[0] = zero105[0] + in[0]; + out[1] = zero105[1] + in[1]; + out[2] = zero105[2] + in[2]; + out[3] = zero105[3] + in[3]; + + felem_reduce_(out, in); + + /*- + * out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0 + * out[1] > 2^105 - 2^71 - 2^103 > 0 + * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0 + * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0 + * + * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106 + * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106 + * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106 + * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106 + */ +} + +/* + * subtract_u64 sets *result = *result - v and *carry to one if the + * subtraction underflowed. + */ +static void subtract_u64(u64 *result, u64 *carry, u64 v) +{ + uint128_t r = *result; + r -= v; + *carry = (r >> 64) & 1; + *result = (u64)r; +} + +/* + * felem_contract converts |in| to its unique, minimal representation. On + * entry: in[i] < 2^109 + */ +static void felem_contract(smallfelem out, const felem in) +{ + unsigned i; + u64 all_equal_so_far = 0, result = 0, carry; + + felem_shrink(out, in); + /* small is minimal except that the value might be > p */ + + all_equal_so_far--; + /* + * We are doing a constant time test if out >= kPrime. We need to compare + * each u64, from most-significant to least significant. For each one, if + * all words so far have been equal (m is all ones) then a non-equal + * result is the answer. Otherwise we continue. + */ + for (i = 3; i < 4; i--) { + u64 equal; + uint128_t a = ((uint128_t) kPrime[i]) - out[i]; + /* + * if out[i] > kPrime[i] then a will underflow and the high 64-bits + * will all be set. + */ + result |= all_equal_so_far & ((u64)(a >> 64)); + + /* + * if kPrime[i] == out[i] then |equal| will be all zeros and the + * decrement will make it all ones. + */ + equal = kPrime[i] ^ out[i]; + equal--; + equal &= equal << 32; + equal &= equal << 16; + equal &= equal << 8; + equal &= equal << 4; + equal &= equal << 2; + equal &= equal << 1; + equal = 0 - (equal >> 63); + + all_equal_so_far &= equal; + } + + /* + * if all_equal_so_far is still all ones then the two values are equal + * and so out >= kPrime is true. + */ + result |= all_equal_so_far; + + /* if out >= kPrime then we subtract kPrime. */ + subtract_u64(&out[0], &carry, result & kPrime[0]); + subtract_u64(&out[1], &carry, carry); + subtract_u64(&out[2], &carry, carry); + subtract_u64(&out[3], &carry, carry); + + subtract_u64(&out[1], &carry, result & kPrime[1]); + subtract_u64(&out[2], &carry, carry); + subtract_u64(&out[3], &carry, carry); + + subtract_u64(&out[2], &carry, result & kPrime[2]); + subtract_u64(&out[3], &carry, carry); + + subtract_u64(&out[3], &carry, result & kPrime[3]); +} + +static void smallfelem_square_contract(smallfelem out, const smallfelem in) +{ + longfelem longtmp; + felem tmp; + + smallfelem_square(longtmp, in); + felem_reduce(tmp, longtmp); + felem_contract(out, tmp); +} + +static void smallfelem_mul_contract(smallfelem out, const smallfelem in1, + const smallfelem in2) +{ + longfelem longtmp; + felem tmp; + + smallfelem_mul(longtmp, in1, in2); + felem_reduce(tmp, longtmp); + felem_contract(out, tmp); +} + +/*- + * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0 + * otherwise. + * On entry: + * small[i] < 2^64 + */ +static limb smallfelem_is_zero(const smallfelem small) +{ + limb result; + u64 is_p; + + u64 is_zero = small[0] | small[1] | small[2] | small[3]; + is_zero--; + is_zero &= is_zero << 32; + is_zero &= is_zero << 16; + is_zero &= is_zero << 8; + is_zero &= is_zero << 4; + is_zero &= is_zero << 2; + is_zero &= is_zero << 1; + is_zero = 0 - (is_zero >> 63); + + is_p = (small[0] ^ kPrime[0]) | + (small[1] ^ kPrime[1]) | + (small[2] ^ kPrime[2]) | (small[3] ^ kPrime[3]); + is_p--; + is_p &= is_p << 32; + is_p &= is_p << 16; + is_p &= is_p << 8; + is_p &= is_p << 4; + is_p &= is_p << 2; + is_p &= is_p << 1; + is_p = 0 - (is_p >> 63); + + is_zero |= is_p; + + result = is_zero; + result |= ((limb) is_zero) << 64; + return result; +} + +static int smallfelem_is_zero_int(const void *small) +{ + return (int)(smallfelem_is_zero(small) & ((limb) 1)); +} + +/*- + * felem_inv calculates |out| = |in|^{-1} + * + * Based on Fermat's Little Theorem: + * a^p = a (mod p) + * a^{p-1} = 1 (mod p) + * a^{p-2} = a^{-1} (mod p) + */ +static void felem_inv(felem out, const felem in) +{ + felem ftmp, ftmp2; + /* each e_I will hold |in|^{2^I - 1} */ + felem e2, e4, e8, e16, e32, e64; + longfelem tmp; + unsigned i; + + felem_square(tmp, in); + felem_reduce(ftmp, tmp); /* 2^1 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */ + felem_assign(e2, ftmp); + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^4 - 2^2 */ + felem_mul(tmp, ftmp, e2); + felem_reduce(ftmp, tmp); /* 2^4 - 2^0 */ + felem_assign(e4, ftmp); + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^5 - 2^1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^6 - 2^2 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^7 - 2^3 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^8 - 2^4 */ + felem_mul(tmp, ftmp, e4); + felem_reduce(ftmp, tmp); /* 2^8 - 2^0 */ + felem_assign(e8, ftmp); + for (i = 0; i < 8; i++) { + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } /* 2^16 - 2^8 */ + felem_mul(tmp, ftmp, e8); + felem_reduce(ftmp, tmp); /* 2^16 - 2^0 */ + felem_assign(e16, ftmp); + for (i = 0; i < 16; i++) { + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } /* 2^32 - 2^16 */ + felem_mul(tmp, ftmp, e16); + felem_reduce(ftmp, tmp); /* 2^32 - 2^0 */ + felem_assign(e32, ftmp); + for (i = 0; i < 32; i++) { + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } /* 2^64 - 2^32 */ + felem_assign(e64, ftmp); + felem_mul(tmp, ftmp, in); + felem_reduce(ftmp, tmp); /* 2^64 - 2^32 + 2^0 */ + for (i = 0; i < 192; i++) { + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } /* 2^256 - 2^224 + 2^192 */ + + felem_mul(tmp, e64, e32); + felem_reduce(ftmp2, tmp); /* 2^64 - 2^0 */ + for (i = 0; i < 16; i++) { + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } /* 2^80 - 2^16 */ + felem_mul(tmp, ftmp2, e16); + felem_reduce(ftmp2, tmp); /* 2^80 - 2^0 */ + for (i = 0; i < 8; i++) { + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } /* 2^88 - 2^8 */ + felem_mul(tmp, ftmp2, e8); + felem_reduce(ftmp2, tmp); /* 2^88 - 2^0 */ + for (i = 0; i < 4; i++) { + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } /* 2^92 - 2^4 */ + felem_mul(tmp, ftmp2, e4); + felem_reduce(ftmp2, tmp); /* 2^92 - 2^0 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^93 - 2^1 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^94 - 2^2 */ + felem_mul(tmp, ftmp2, e2); + felem_reduce(ftmp2, tmp); /* 2^94 - 2^0 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^95 - 2^1 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^96 - 2^2 */ + felem_mul(tmp, ftmp2, in); + felem_reduce(ftmp2, tmp); /* 2^96 - 3 */ + + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */ +} + +static void smallfelem_inv_contract(smallfelem out, const smallfelem in) +{ + felem tmp; + + smallfelem_expand(tmp, in); + felem_inv(tmp, tmp); + felem_contract(out, tmp); +} + +/*- + * Group operations + * ---------------- + * + * Building on top of the field operations we have the operations on the + * elliptic curve group itself. Points on the curve are represented in Jacobian + * coordinates + */ + +/*- + * point_double calculates 2*(x_in, y_in, z_in) + * + * The method is taken from: + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + * + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. + * while x_out == y_in is not (maybe this works, but it's not tested). + */ +static void +point_double(felem x_out, felem y_out, felem z_out, + const felem x_in, const felem y_in, const felem z_in) +{ + longfelem tmp, tmp2; + felem delta, gamma, beta, alpha, ftmp, ftmp2; + smallfelem small1, small2; + + felem_assign(ftmp, x_in); + /* ftmp[i] < 2^106 */ + felem_assign(ftmp2, x_in); + /* ftmp2[i] < 2^106 */ + + /* delta = z^2 */ + felem_square(tmp, z_in); + felem_reduce(delta, tmp); + /* delta[i] < 2^101 */ + + /* gamma = y^2 */ + felem_square(tmp, y_in); + felem_reduce(gamma, tmp); + /* gamma[i] < 2^101 */ + felem_shrink(small1, gamma); + + /* beta = x*gamma */ + felem_small_mul(tmp, small1, x_in); + felem_reduce(beta, tmp); + /* beta[i] < 2^101 */ + + /* alpha = 3*(x-delta)*(x+delta) */ + felem_diff(ftmp, delta); + /* ftmp[i] < 2^105 + 2^106 < 2^107 */ + felem_sum(ftmp2, delta); + /* ftmp2[i] < 2^105 + 2^106 < 2^107 */ + felem_scalar(ftmp2, 3); + /* ftmp2[i] < 3 * 2^107 < 2^109 */ + felem_mul(tmp, ftmp, ftmp2); + felem_reduce(alpha, tmp); + /* alpha[i] < 2^101 */ + felem_shrink(small2, alpha); + + /* x' = alpha^2 - 8*beta */ + smallfelem_square(tmp, small2); + felem_reduce(x_out, tmp); + felem_assign(ftmp, beta); + felem_scalar(ftmp, 8); + /* ftmp[i] < 8 * 2^101 = 2^104 */ + felem_diff(x_out, ftmp); + /* x_out[i] < 2^105 + 2^101 < 2^106 */ + + /* z' = (y + z)^2 - gamma - delta */ + felem_sum(delta, gamma); + /* delta[i] < 2^101 + 2^101 = 2^102 */ + felem_assign(ftmp, y_in); + felem_sum(ftmp, z_in); + /* ftmp[i] < 2^106 + 2^106 = 2^107 */ + felem_square(tmp, ftmp); + felem_reduce(z_out, tmp); + felem_diff(z_out, delta); + /* z_out[i] < 2^105 + 2^101 < 2^106 */ + + /* y' = alpha*(4*beta - x') - 8*gamma^2 */ + felem_scalar(beta, 4); + /* beta[i] < 4 * 2^101 = 2^103 */ + felem_diff_zero107(beta, x_out); + /* beta[i] < 2^107 + 2^103 < 2^108 */ + felem_small_mul(tmp, small2, beta); + /* tmp[i] < 7 * 2^64 < 2^67 */ + smallfelem_square(tmp2, small1); + /* tmp2[i] < 7 * 2^64 */ + longfelem_scalar(tmp2, 8); + /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */ + longfelem_diff(tmp, tmp2); + /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */ + felem_reduce_zero105(y_out, tmp); + /* y_out[i] < 2^106 */ +} + +/* + * point_double_small is the same as point_double, except that it operates on + * smallfelems + */ +static void +point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out, + const smallfelem x_in, const smallfelem y_in, + const smallfelem z_in) +{ + felem felem_x_out, felem_y_out, felem_z_out; + felem felem_x_in, felem_y_in, felem_z_in; + + smallfelem_expand(felem_x_in, x_in); + smallfelem_expand(felem_y_in, y_in); + smallfelem_expand(felem_z_in, z_in); + point_double(felem_x_out, felem_y_out, felem_z_out, + felem_x_in, felem_y_in, felem_z_in); + felem_shrink(x_out, felem_x_out); + felem_shrink(y_out, felem_y_out); + felem_shrink(z_out, felem_z_out); +} + +/* copy_conditional copies in to out iff mask is all ones. */ +static void copy_conditional(felem out, const felem in, limb mask) +{ + unsigned i; + for (i = 0; i < NLIMBS; ++i) { + const limb tmp = mask & (in[i] ^ out[i]); + out[i] ^= tmp; + } +} + +/* copy_small_conditional copies in to out iff mask is all ones. */ +static void copy_small_conditional(felem out, const smallfelem in, limb mask) +{ + unsigned i; + const u64 mask64 = mask; + for (i = 0; i < NLIMBS; ++i) { + out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask); + } +} + +/*- + * point_add calcuates (x1, y1, z1) + (x2, y2, z2) + * + * The method is taken from: + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, + * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). + * + * This function includes a branch for checking whether the two input points + * are equal, (while not equal to the point at infinity). This case never + * happens during single point multiplication, so there is no timing leak for + * ECDH or ECDSA signing. + */ +static void point_add(felem x3, felem y3, felem z3, + const felem x1, const felem y1, const felem z1, + const int mixed, const smallfelem x2, + const smallfelem y2, const smallfelem z2) +{ + felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out; + longfelem tmp, tmp2; + smallfelem small1, small2, small3, small4, small5; + limb x_equal, y_equal, z1_is_zero, z2_is_zero; + + felem_shrink(small3, z1); + + z1_is_zero = smallfelem_is_zero(small3); + z2_is_zero = smallfelem_is_zero(z2); + + /* ftmp = z1z1 = z1**2 */ + smallfelem_square(tmp, small3); + felem_reduce(ftmp, tmp); + /* ftmp[i] < 2^101 */ + felem_shrink(small1, ftmp); + + if (!mixed) { + /* ftmp2 = z2z2 = z2**2 */ + smallfelem_square(tmp, z2); + felem_reduce(ftmp2, tmp); + /* ftmp2[i] < 2^101 */ + felem_shrink(small2, ftmp2); + + felem_shrink(small5, x1); + + /* u1 = ftmp3 = x1*z2z2 */ + smallfelem_mul(tmp, small5, small2); + felem_reduce(ftmp3, tmp); + /* ftmp3[i] < 2^101 */ + + /* ftmp5 = z1 + z2 */ + felem_assign(ftmp5, z1); + felem_small_sum(ftmp5, z2); + /* ftmp5[i] < 2^107 */ + + /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */ + felem_square(tmp, ftmp5); + felem_reduce(ftmp5, tmp); + /* ftmp2 = z2z2 + z1z1 */ + felem_sum(ftmp2, ftmp); + /* ftmp2[i] < 2^101 + 2^101 = 2^102 */ + felem_diff(ftmp5, ftmp2); + /* ftmp5[i] < 2^105 + 2^101 < 2^106 */ + + /* ftmp2 = z2 * z2z2 */ + smallfelem_mul(tmp, small2, z2); + felem_reduce(ftmp2, tmp); + + /* s1 = ftmp2 = y1 * z2**3 */ + felem_mul(tmp, y1, ftmp2); + felem_reduce(ftmp6, tmp); + /* ftmp6[i] < 2^101 */ + } else { + /* + * We'll assume z2 = 1 (special case z2 = 0 is handled later) + */ + + /* u1 = ftmp3 = x1*z2z2 */ + felem_assign(ftmp3, x1); + /* ftmp3[i] < 2^106 */ + + /* ftmp5 = 2z1z2 */ + felem_assign(ftmp5, z1); + felem_scalar(ftmp5, 2); + /* ftmp5[i] < 2*2^106 = 2^107 */ + + /* s1 = ftmp2 = y1 * z2**3 */ + felem_assign(ftmp6, y1); + /* ftmp6[i] < 2^106 */ + } + + /* u2 = x2*z1z1 */ + smallfelem_mul(tmp, x2, small1); + felem_reduce(ftmp4, tmp); + + /* h = ftmp4 = u2 - u1 */ + felem_diff_zero107(ftmp4, ftmp3); + /* ftmp4[i] < 2^107 + 2^101 < 2^108 */ + felem_shrink(small4, ftmp4); + + x_equal = smallfelem_is_zero(small4); + + /* z_out = ftmp5 * h */ + felem_small_mul(tmp, small4, ftmp5); + felem_reduce(z_out, tmp); + /* z_out[i] < 2^101 */ + + /* ftmp = z1 * z1z1 */ + smallfelem_mul(tmp, small1, small3); + felem_reduce(ftmp, tmp); + + /* s2 = tmp = y2 * z1**3 */ + felem_small_mul(tmp, y2, ftmp); + felem_reduce(ftmp5, tmp); + + /* r = ftmp5 = (s2 - s1)*2 */ + felem_diff_zero107(ftmp5, ftmp6); + /* ftmp5[i] < 2^107 + 2^107 = 2^108 */ + felem_scalar(ftmp5, 2); + /* ftmp5[i] < 2^109 */ + felem_shrink(small1, ftmp5); + y_equal = smallfelem_is_zero(small1); + + if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + /* I = ftmp = (2h)**2 */ + felem_assign(ftmp, ftmp4); + felem_scalar(ftmp, 2); + /* ftmp[i] < 2*2^108 = 2^109 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + + /* J = ftmp2 = h * I */ + felem_mul(tmp, ftmp4, ftmp); + felem_reduce(ftmp2, tmp); + + /* V = ftmp4 = U1 * I */ + felem_mul(tmp, ftmp3, ftmp); + felem_reduce(ftmp4, tmp); + + /* x_out = r**2 - J - 2V */ + smallfelem_square(tmp, small1); + felem_reduce(x_out, tmp); + felem_assign(ftmp3, ftmp4); + felem_scalar(ftmp4, 2); + felem_sum(ftmp4, ftmp2); + /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */ + felem_diff(x_out, ftmp4); + /* x_out[i] < 2^105 + 2^101 */ + + /* y_out = r(V-x_out) - 2 * s1 * J */ + felem_diff_zero107(ftmp3, x_out); + /* ftmp3[i] < 2^107 + 2^101 < 2^108 */ + felem_small_mul(tmp, small1, ftmp3); + felem_mul(tmp2, ftmp6, ftmp2); + longfelem_scalar(tmp2, 2); + /* tmp2[i] < 2*2^67 = 2^68 */ + longfelem_diff(tmp, tmp2); + /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */ + felem_reduce_zero105(y_out, tmp); + /* y_out[i] < 2^106 */ + + copy_small_conditional(x_out, x2, z1_is_zero); + copy_conditional(x_out, x1, z2_is_zero); + copy_small_conditional(y_out, y2, z1_is_zero); + copy_conditional(y_out, y1, z2_is_zero); + copy_small_conditional(z_out, z2, z1_is_zero); + copy_conditional(z_out, z1, z2_is_zero); + felem_assign(x3, x_out); + felem_assign(y3, y_out); + felem_assign(z3, z_out); +} + +/* + * point_add_small is the same as point_add, except that it operates on + * smallfelems + */ +static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3, + smallfelem x1, smallfelem y1, smallfelem z1, + smallfelem x2, smallfelem y2, smallfelem z2) +{ + felem felem_x3, felem_y3, felem_z3; + felem felem_x1, felem_y1, felem_z1; + smallfelem_expand(felem_x1, x1); + smallfelem_expand(felem_y1, y1); + smallfelem_expand(felem_z1, z1); + point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0, + x2, y2, z2); + felem_shrink(x3, felem_x3); + felem_shrink(y3, felem_y3); + felem_shrink(z3, felem_z3); +} + +/*- + * Base point pre computation + * -------------------------- + * + * Two different sorts of precomputed tables are used in the following code. + * Each contain various points on the curve, where each point is three field + * elements (x, y, z). + * + * For the base point table, z is usually 1 (0 for the point at infinity). + * This table has 2 * 16 elements, starting with the following: + * index | bits | point + * ------+---------+------------------------------ + * 0 | 0 0 0 0 | 0G + * 1 | 0 0 0 1 | 1G + * 2 | 0 0 1 0 | 2^64G + * 3 | 0 0 1 1 | (2^64 + 1)G + * 4 | 0 1 0 0 | 2^128G + * 5 | 0 1 0 1 | (2^128 + 1)G + * 6 | 0 1 1 0 | (2^128 + 2^64)G + * 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G + * 8 | 1 0 0 0 | 2^192G + * 9 | 1 0 0 1 | (2^192 + 1)G + * 10 | 1 0 1 0 | (2^192 + 2^64)G + * 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G + * 12 | 1 1 0 0 | (2^192 + 2^128)G + * 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G + * 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G + * 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G + * followed by a copy of this with each element multiplied by 2^32. + * + * The reason for this is so that we can clock bits into four different + * locations when doing simple scalar multiplies against the base point, + * and then another four locations using the second 16 elements. + * + * Tables for other points have table[i] = iG for i in 0 .. 16. */ + +/* gmul is the table of precomputed base points */ +static const smallfelem gmul[2][16][3] = { + {{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}, + {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, + 0x6b17d1f2e12c4247}, + {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16, + 0x4fe342e2fe1a7f9b}, + {1, 0, 0, 0}}, + {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de, + 0x0fa822bc2811aaa5}, + {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b, + 0xbff44ae8f5dba80d}, + {1, 0, 0, 0}}, + {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789, + 0x300a4bbc89d6726f}, + {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f, + 0x72aac7e0d09b4644}, + {1, 0, 0, 0}}, + {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e, + 0x447d739beedb5e67}, + {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7, + 0x2d4825ab834131ee}, + {1, 0, 0, 0}}, + {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60, + 0xef9519328a9c72ff}, + {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c, + 0x611e9fc37dbb2c9b}, + {1, 0, 0, 0}}, + {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf, + 0x550663797b51f5d8}, + {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5, + 0x157164848aecb851}, + {1, 0, 0, 0}}, + {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391, + 0xeb5d7745b21141ea}, + {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee, + 0xeafd72ebdbecc17b}, + {1, 0, 0, 0}}, + {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5, + 0xa6d39677a7849276}, + {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf, + 0x674f84749b0b8816}, + {1, 0, 0, 0}}, + {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb, + 0x4e769e7672c9ddad}, + {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281, + 0x42b99082de830663}, + {1, 0, 0, 0}}, + {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478, + 0x78878ef61c6ce04d}, + {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def, + 0xb6cb3f5d7b72c321}, + {1, 0, 0, 0}}, + {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae, + 0x0c88bc4d716b1287}, + {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa, + 0xdd5ddea3f3901dc6}, + {1, 0, 0, 0}}, + {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3, + 0x68f344af6b317466}, + {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3, + 0x31b9c405f8540a20}, + {1, 0, 0, 0}}, + {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0, + 0x4052bf4b6f461db9}, + {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8, + 0xfecf4d5190b0fc61}, + {1, 0, 0, 0}}, + {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a, + 0x1eddbae2c802e41a}, + {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0, + 0x43104d86560ebcfc}, + {1, 0, 0, 0}}, + {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a, + 0xb48e26b484f7a21c}, + {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668, + 0xfac015404d4d3dab}, + {1, 0, 0, 0}}}, + {{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}, + {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da, + 0x7fe36b40af22af89}, + {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1, + 0xe697d45825b63624}, + {1, 0, 0, 0}}, + {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902, + 0x4a5b506612a677a6}, + {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40, + 0xeb13461ceac089f1}, + {1, 0, 0, 0}}, + {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857, + 0x0781b8291c6a220a}, + {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434, + 0x690cde8df0151593}, + {1, 0, 0, 0}}, + {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326, + 0x8a535f566ec73617}, + {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf, + 0x0455c08468b08bd7}, + {1, 0, 0, 0}}, + {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279, + 0x06bada7ab77f8276}, + {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70, + 0x5b476dfd0e6cb18a}, + {1, 0, 0, 0}}, + {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8, + 0x3e29864e8a2ec908}, + {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed, + 0x239b90ea3dc31e7e}, + {1, 0, 0, 0}}, + {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4, + 0x820f4dd949f72ff7}, + {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3, + 0x140406ec783a05ec}, + {1, 0, 0, 0}}, + {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe, + 0x68f6b8542783dfee}, + {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028, + 0xcbe1feba92e40ce6}, + {1, 0, 0, 0}}, + {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927, + 0xd0b2f94d2f420109}, + {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a, + 0x971459828b0719e5}, + {1, 0, 0, 0}}, + {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687, + 0x961610004a866aba}, + {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c, + 0x7acb9fadcee75e44}, + {1, 0, 0, 0}}, + {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea, + 0x24eb9acca333bf5b}, + {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d, + 0x69f891c5acd079cc}, + {1, 0, 0, 0}}, + {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514, + 0xe51f547c5972a107}, + {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06, + 0x1c309a2b25bb1387}, + {1, 0, 0, 0}}, + {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828, + 0x20b87b8aa2c4e503}, + {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044, + 0xf5c6fa49919776be}, + {1, 0, 0, 0}}, + {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56, + 0x1ed7d1b9332010b9}, + {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24, + 0x3a2b03f03217257a}, + {1, 0, 0, 0}}, + {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b, + 0x15fee545c78dd9f6}, + {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, + 0x4ab5b6b2b8753f81}, + {1, 0, 0, 0}}} +}; + +/* + * select_point selects the |idx|th point from a precomputation table and + * copies it to out. + */ +static void select_point(const u64 idx, unsigned int size, + const smallfelem pre_comp[16][3], smallfelem out[3]) +{ + unsigned i, j; + u64 *outlimbs = &out[0][0]; + memset(outlimbs, 0, 3 * sizeof(smallfelem)); + + for (i = 0; i < size; i++) { + const u64 *inlimbs = (u64 *)&pre_comp[i][0][0]; + u64 mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (j = 0; j < NLIMBS * 3; j++) + outlimbs[j] |= inlimbs[j] & mask; + } +} + +/* get_bit returns the |i|th bit in |in| */ +static char get_bit(const felem_bytearray in, int i) +{ + if ((i < 0) || (i >= 256)) + return 0; + return (in[i >> 3] >> (i & 7)) & 1; +} + +/* + * Interleaved point multiplication using precomputed point multiples: The + * small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[], the scalars + * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the + * generator, using certain (large) precomputed multiples in g_pre_comp. + * Output point (X, Y, Z) is stored in x_out, y_out, z_out + */ +static void batch_mul(felem x_out, felem y_out, felem z_out, + const felem_bytearray scalars[], + const unsigned num_points, const u8 *g_scalar, + const int mixed, const smallfelem pre_comp[][17][3], + const smallfelem g_pre_comp[2][16][3]) +{ + int i, skip; + unsigned num, gen_mul = (g_scalar != NULL); + felem nq[3], ftmp; + smallfelem tmp[3]; + u64 bits; + u8 sign, digit; + + /* set nq to the point at infinity */ + memset(nq, 0, 3 * sizeof(felem)); + + /* + * Loop over all scalars msb-to-lsb, interleaving additions of multiples + * of the generator (two in each of the last 32 rounds) and additions of + * other points multiples (every 5th round). + */ + skip = 1; /* save two point operations in the first + * round */ + for (i = (num_points ? 255 : 31); i >= 0; --i) { + /* double */ + if (!skip) + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + + /* add multiples of the generator */ + if (gen_mul && (i <= 31)) { + /* first, look 32 bits upwards */ + bits = get_bit(g_scalar, i + 224) << 3; + bits |= get_bit(g_scalar, i + 160) << 2; + bits |= get_bit(g_scalar, i + 96) << 1; + bits |= get_bit(g_scalar, i + 32); + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp[1], tmp); + + if (!skip) { + /* Arg 1 below is for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); + } else { + smallfelem_expand(nq[0], tmp[0]); + smallfelem_expand(nq[1], tmp[1]); + smallfelem_expand(nq[2], tmp[2]); + skip = 0; + } + + /* second, look at the current position */ + bits = get_bit(g_scalar, i + 192) << 3; + bits |= get_bit(g_scalar, i + 128) << 2; + bits |= get_bit(g_scalar, i + 64) << 1; + bits |= get_bit(g_scalar, i); + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp[0], tmp); + /* Arg 1 below is for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); + } + + /* do other additions every 5 doublings */ + if (num_points && (i % 5 == 0)) { + /* loop over all scalars */ + for (num = 0; num < num_points; ++num) { + bits = get_bit(scalars[num], i + 4) << 5; + bits |= get_bit(scalars[num], i + 3) << 4; + bits |= get_bit(scalars[num], i + 2) << 3; + bits |= get_bit(scalars[num], i + 1) << 2; + bits |= get_bit(scalars[num], i) << 1; + bits |= get_bit(scalars[num], i - 1); + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + /* + * select the point to add or subtract, in constant time + */ + select_point(digit, 17, pre_comp[num], tmp); + smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative + * point */ + copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1)); + felem_contract(tmp[1], ftmp); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], + mixed, tmp[0], tmp[1], tmp[2]); + } else { + smallfelem_expand(nq[0], tmp[0]); + smallfelem_expand(nq[1], tmp[1]); + smallfelem_expand(nq[2], tmp[2]); + skip = 0; + } + } + } + } + felem_assign(x_out, nq[0]); + felem_assign(y_out, nq[1]); + felem_assign(z_out, nq[2]); +} + +/* Precomputation for the group generator. */ +typedef struct { + smallfelem g_pre_comp[2][16][3]; + int references; +} NISTP256_PRE_COMP; + +const EC_METHOD *EC_GFp_nistp256_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_nistp256_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_nist_group_copy, + ec_GFp_nistp256_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_nistp256_point_get_affine_coordinates, + 0 /* point_set_compressed_coordinates */ , + 0 /* point2oct */ , + 0 /* oct2point */ , + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + ec_GFp_nistp256_points_mul, + ec_GFp_nistp256_precompute_mult, + ec_GFp_nistp256_have_precompute_mult, + ec_GFp_nist_field_mul, + ec_GFp_nist_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + + return &ret; +} + +/******************************************************************************/ +/* + * FUNCTIONS TO MANAGE PRECOMPUTATION + */ + +static NISTP256_PRE_COMP *nistp256_pre_comp_new() +{ + NISTP256_PRE_COMP *ret = NULL; + ret = (NISTP256_PRE_COMP *) OPENSSL_malloc(sizeof(*ret)); + if (!ret) { + ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + return ret; + } + memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); + ret->references = 1; + return ret; +} + +static void *nistp256_pre_comp_dup(void *src_) +{ + NISTP256_PRE_COMP *src = src_; + + /* no need to actually copy, these objects never change! */ + CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + + return src_; +} + +static void nistp256_pre_comp_free(void *pre_) +{ + int i; + NISTP256_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_free(pre); +} + +static void nistp256_pre_comp_clear_free(void *pre_) +{ + int i; + NISTP256_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_cleanse(pre, sizeof(*pre)); + OPENSSL_free(pre); +} + +/******************************************************************************/ +/* + * OPENSSL EC_METHOD FUNCTIONS + */ + +int ec_GFp_nistp256_group_init(EC_GROUP *group) +{ + int ret; + ret = ec_GFp_simple_group_init(group); + group->a_is_minus3 = 1; + return ret; +} + +int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *curve_p, *curve_a, *curve_b; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((curve_p = BN_CTX_get(ctx)) == NULL) || + ((curve_a = BN_CTX_get(ctx)) == NULL) || + ((curve_b = BN_CTX_get(ctx)) == NULL)) + goto err; + BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p); + BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a); + BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b); + if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { + ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, + EC_R_WRONG_CURVE_PARAMETERS); + goto err; + } + group->field_mod_func = BN_nist_mod_256; + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = + * (X/Z^2, Y/Z^3) + */ +int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + felem z1, z2, x_in, y_in; + smallfelem x_out, y_out; + longfelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || + (!BN_to_felem(z1, &point->Z))) + return 0; + felem_inv(z2, z1); + felem_square(tmp, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, x_in, z1); + felem_reduce(x_in, tmp); + felem_contract(x_out, x_in); + if (x != NULL) { + if (!smallfelem_to_BN(x, x_out)) { + ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + felem_mul(tmp, z1, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, y_in, z1); + felem_reduce(y_in, tmp); + felem_contract(y_out, y_in); + if (y != NULL) { + if (!smallfelem_to_BN(y, y_out)) { + ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + return 1; +} + +/* points below is of size |num|, and tmp_smallfelems is of size |num+1| */ +static void make_points_affine(size_t num, smallfelem points[][3], + smallfelem tmp_smallfelems[]) +{ + /* + * Runs in constant time, unless an input is the point at infinity (which + * normally shouldn't happen). + */ + ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(smallfelem), + tmp_smallfelems, + (void (*)(void *))smallfelem_one, + smallfelem_is_zero_int, + (void (*)(void *, const void *)) + smallfelem_assign, + (void (*)(void *, const void *)) + smallfelem_square_contract, + (void (*) + (void *, const void *, + const void *)) + smallfelem_mul_contract, + (void (*)(void *, const void *)) + smallfelem_inv_contract, + /* nothing to contract */ + (void (*)(void *, const void *)) + smallfelem_assign); +} + +/* + * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL + * values Result is stored in r (r can equal one of the inputs). + */ +int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + int ret = 0; + int j; + int mixed = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y, *z, *tmp_scalar; + felem_bytearray g_secret; + felem_bytearray *secrets = NULL; + smallfelem(*pre_comp)[17][3] = NULL; + smallfelem *tmp_smallfelems = NULL; + felem_bytearray tmp; + unsigned i, num_bytes; + int have_pre_comp = 0; + size_t num_points = num; + smallfelem x_in, y_in, z_in; + felem x_out, y_out, z_out; + NISTP256_PRE_COMP *pre = NULL; + const smallfelem(*g_pre_comp)[16][3] = NULL; + EC_POINT *generator = NULL; + const EC_POINT *p = NULL; + const BIGNUM *p_scalar = NULL; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || + ((y = BN_CTX_get(ctx)) == NULL) || + ((z = BN_CTX_get(ctx)) == NULL) || + ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) + goto err; + + if (scalar != NULL) { + pre = EC_EX_DATA_get_data(group->extra_data, + nistp256_pre_comp_dup, + nistp256_pre_comp_free, + nistp256_pre_comp_clear_free); + if (pre) + /* we have precomputation, try to use it */ + g_pre_comp = (const smallfelem(*)[16][3])pre->g_pre_comp; + else + /* try to use the standard precomputation */ + g_pre_comp = &gmul[0]; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + /* get the generator from precomputation */ + if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) || + !smallfelem_to_BN(y, g_pre_comp[0][1][1]) || + !smallfelem_to_BN(z, g_pre_comp[0][1][2])) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_Jprojective_coordinates_GFp(group, + generator, x, y, z, + ctx)) + goto err; + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) + /* precomputation matches generator */ + have_pre_comp = 1; + else + /* + * we don't have valid precomputation: treat the generator as a + * random point + */ + num_points++; + } + if (num_points > 0) { + if (num_points >= 3) { + /* + * unless we precompute multiples for just one or two points, + * converting those into affine form is time well spent + */ + mixed = 1; + } + secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); + pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem)); + if (mixed) + tmp_smallfelems = + OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem)); + if ((secrets == NULL) || (pre_comp == NULL) + || (mixed && (tmp_smallfelems == NULL))) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * we treat NULL scalars as 0, and NULL points as points at infinity, + * i.e., they contribute nothing to the linear combination + */ + memset(secrets, 0, num_points * sizeof(felem_bytearray)); + memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem)); + for (i = 0; i < num_points; ++i) { + if (i == num) + /* + * we didn't have a valid precomputation, so we pick the + * generator + */ + { + p = EC_GROUP_get0_generator(group); + p_scalar = scalar; + } else + /* the i^th point */ + { + p = points[i]; + p_scalar = scalars[i]; + } + if ((p_scalar != NULL) && (p != NULL)) { + /* reduce scalar to 0 <= scalar < 2^256 */ + if ((BN_num_bits(p_scalar) > 256) + || (BN_is_negative(p_scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(p_scalar, tmp); + flip_endian(secrets[i], tmp, num_bytes); + /* precompute multiples */ + if ((!BN_to_felem(x_out, &p->X)) || + (!BN_to_felem(y_out, &p->Y)) || + (!BN_to_felem(z_out, &p->Z))) + goto err; + felem_shrink(pre_comp[i][1][0], x_out); + felem_shrink(pre_comp[i][1][1], y_out); + felem_shrink(pre_comp[i][1][2], z_out); + for (j = 2; j <= 16; ++j) { + if (j & 1) { + point_add_small(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][1][0], + pre_comp[i][1][1], pre_comp[i][1][2], + pre_comp[i][j - 1][0], + pre_comp[i][j - 1][1], + pre_comp[i][j - 1][2]); + } else { + point_double_small(pre_comp[i][j][0], + pre_comp[i][j][1], + pre_comp[i][j][2], + pre_comp[i][j / 2][0], + pre_comp[i][j / 2][1], + pre_comp[i][j / 2][2]); + } + } + } + } + if (mixed) + make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems); + } + + /* the scalar for the generator */ + if ((scalar != NULL) && (have_pre_comp)) { + memset(g_secret, 0, sizeof(g_secret)); + /* reduce scalar to 0 <= scalar < 2^256 */ + if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(scalar, tmp); + flip_endian(g_secret, tmp, num_bytes); + /* do the multiplication with generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + g_secret, + mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp); + } else + /* do the multiplication without generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL); + /* reduce the output to its unique minimal representation */ + felem_contract(x_in, x_out); + felem_contract(y_in, y_out); + felem_contract(z_in, z_out); + if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) || + (!smallfelem_to_BN(z, z_in))) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (secrets != NULL) + OPENSSL_free(secrets); + if (pre_comp != NULL) + OPENSSL_free(pre_comp); + if (tmp_smallfelems != NULL) + OPENSSL_free(tmp_smallfelems); + return ret; +} + +int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + NISTP256_PRE_COMP *pre = NULL; + int i, j; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + EC_POINT *generator = NULL; + smallfelem tmp_smallfelems[32]; + felem x_tmp, y_tmp, z_tmp; + + /* throw away old precomputation */ + EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup, + nistp256_pre_comp_free, + nistp256_pre_comp_clear_free); + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) + goto err; + /* get the generator */ + if (group->generator == NULL) + goto err; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + BN_bin2bn(nistp256_curve_params[3], sizeof(felem_bytearray), x); + BN_bin2bn(nistp256_curve_params[4], sizeof(felem_bytearray), y); + if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) + goto err; + if ((pre = nistp256_pre_comp_new()) == NULL) + goto err; + /* + * if the generator is the standard one, use built-in precomputation + */ + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { + memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); + goto done; + } + if ((!BN_to_felem(x_tmp, &group->generator->X)) || + (!BN_to_felem(y_tmp, &group->generator->Y)) || + (!BN_to_felem(z_tmp, &group->generator->Z))) + goto err; + felem_shrink(pre->g_pre_comp[0][1][0], x_tmp); + felem_shrink(pre->g_pre_comp[0][1][1], y_tmp); + felem_shrink(pre->g_pre_comp[0][1][2], z_tmp); + /* + * compute 2^64*G, 2^128*G, 2^192*G for the first table, 2^32*G, 2^96*G, + * 2^160*G, 2^224*G for the second one + */ + for (i = 1; i <= 8; i <<= 1) { + point_double_small(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0], + pre->g_pre_comp[0][i][1], + pre->g_pre_comp[0][i][2]); + for (j = 0; j < 31; ++j) { + point_double_small(pre->g_pre_comp[1][i][0], + pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2], + pre->g_pre_comp[1][i][0], + pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2]); + } + if (i == 8) + break; + point_double_small(pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2], + pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2]); + for (j = 0; j < 31; ++j) { + point_double_small(pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2], + pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2]); + } + } + for (i = 0; i < 2; i++) { + /* g_pre_comp[i][0] is the point at infinity */ + memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0])); + /* the remaining multiples */ + /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */ + point_add_small(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], + pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0], + pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2], + pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */ + point_add_small(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], + pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0], + pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], + pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */ + point_add_small(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], + pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0], + pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], + pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], + pre->g_pre_comp[i][4][2]); + /* + * 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G + */ + point_add_small(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], + pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0], + pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2], + pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + for (j = 1; j < 8; ++j) { + /* odd multiples: add G resp. 2^32*G */ + point_add_small(pre->g_pre_comp[i][2 * j + 1][0], + pre->g_pre_comp[i][2 * j + 1][1], + pre->g_pre_comp[i][2 * j + 1][2], + pre->g_pre_comp[i][2 * j][0], + pre->g_pre_comp[i][2 * j][1], + pre->g_pre_comp[i][2 * j][2], + pre->g_pre_comp[i][1][0], + pre->g_pre_comp[i][1][1], + pre->g_pre_comp[i][1][2]); + } + } + make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems); + + done: + if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup, + nistp256_pre_comp_free, + nistp256_pre_comp_clear_free)) + goto err; + ret = 1; + pre = NULL; + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (pre) + nistp256_pre_comp_free(pre); + return ret; +} + +int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group) +{ + if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup, + nistp256_pre_comp_free, + nistp256_pre_comp_clear_free) + != NULL) + return 1; + else + return 0; +} +#else +static void *dummy = &dummy; +#endif diff --git a/Sources/COpenSSL/ecp_nistp521.c b/Sources/COpenSSL/ecp_nistp521.c new file mode 100644 index 00000000..27cab28b --- /dev/null +++ b/Sources/COpenSSL/ecp_nistp521.c @@ -0,0 +1,2146 @@ +/* crypto/ec/ecp_nistp521.c */ +/* + * Written by Adam Langley (Google) for the OpenSSL project + */ +/* Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication + * + * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c. + * Otherwise based on Emilia's P224 work, which was inspired by my curve25519 + * work which got its smarts from Daniel J. Bernstein's work on the same. + */ + +#include "opensslconf.h" +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif + +# include +# include "err.h" +# include "ec_lcl.h" + +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + /* even with gcc, the typedef won't work for 32-bit platforms */ +typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit + * platforms */ +# else +# error "Need GCC 3.1 or later to define type uint128_t" +# endif + +typedef uint8_t u8; +typedef uint64_t u64; + +/* + * The underlying field. P521 operates over GF(2^521-1). We can serialise an + * element of this field into 66 bytes where the most significant byte + * contains only a single bit. We call this an felem_bytearray. + */ + +typedef u8 felem_bytearray[66]; + +/* + * These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5. + * These values are big-endian. + */ +static const felem_bytearray nistp521_curve_params[5] = { + {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff}, + {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfc}, + {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */ + 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, + 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, + 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, + 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, + 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, + 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, + 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, + 0x3f, 0x00}, + {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */ + 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, + 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, + 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, + 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, + 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, + 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, + 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, + 0xbd, 0x66}, + {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */ + 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, + 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, + 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, + 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, + 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, + 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, + 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, + 0x66, 0x50} +}; + +/*- + * The representation of field elements. + * ------------------------------------ + * + * We represent field elements with nine values. These values are either 64 or + * 128 bits and the field element represented is: + * v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464 (mod p) + * Each of the nine values is called a 'limb'. Since the limbs are spaced only + * 58 bits apart, but are greater than 58 bits in length, the most significant + * bits of each limb overlap with the least significant bits of the next. + * + * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a + * 'largefelem' */ + +# define NLIMBS 9 + +typedef uint64_t limb; +typedef limb felem[NLIMBS]; +typedef uint128_t largefelem[NLIMBS]; + +static const limb bottom57bits = 0x1ffffffffffffff; +static const limb bottom58bits = 0x3ffffffffffffff; + +/* + * bin66_to_felem takes a little-endian byte array and converts it into felem + * form. This assumes that the CPU is little-endian. + */ +static void bin66_to_felem(felem out, const u8 in[66]) +{ + out[0] = (*((limb *) & in[0])) & bottom58bits; + out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits; + out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits; + out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits; + out[4] = (*((limb *) & in[29])) & bottom58bits; + out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits; + out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits; + out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits; + out[8] = (*((limb *) & in[58])) & bottom57bits; +} + +/* + * felem_to_bin66 takes an felem and serialises into a little endian, 66 byte + * array. This assumes that the CPU is little-endian. + */ +static void felem_to_bin66(u8 out[66], const felem in) +{ + memset(out, 0, 66); + (*((limb *) & out[0])) = in[0]; + (*((limb *) & out[7])) |= in[1] << 2; + (*((limb *) & out[14])) |= in[2] << 4; + (*((limb *) & out[21])) |= in[3] << 6; + (*((limb *) & out[29])) = in[4]; + (*((limb *) & out[36])) |= in[5] << 2; + (*((limb *) & out[43])) |= in[6] << 4; + (*((limb *) & out[50])) |= in[7] << 6; + (*((limb *) & out[58])) = in[8]; +} + +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ +static void flip_endian(u8 *out, const u8 *in, unsigned len) +{ + unsigned i; + for (i = 0; i < len; ++i) + out[i] = in[len - 1 - i]; +} + +/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ +static int BN_to_felem(felem out, const BIGNUM *bn) +{ + felem_bytearray b_in; + felem_bytearray b_out; + unsigned num_bytes; + + /* BN_bn2bin eats leading zeroes */ + memset(b_out, 0, sizeof(b_out)); + num_bytes = BN_num_bytes(bn); + if (num_bytes > sizeof(b_out)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + if (BN_is_negative(bn)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + num_bytes = BN_bn2bin(bn, b_in); + flip_endian(b_out, b_in, num_bytes); + bin66_to_felem(out, b_out); + return 1; +} + +/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ +static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) +{ + felem_bytearray b_in, b_out; + felem_to_bin66(b_in, in); + flip_endian(b_out, b_in, sizeof(b_out)); + return BN_bin2bn(b_out, sizeof(b_out), out); +} + +/*- + * Field operations + * ---------------- + */ + +static void felem_one(felem out) +{ + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; +} + +static void felem_assign(felem out, const felem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + out[4] = in[4]; + out[5] = in[5]; + out[6] = in[6]; + out[7] = in[7]; + out[8] = in[8]; +} + +/* felem_sum64 sets out = out + in. */ +static void felem_sum64(felem out, const felem in) +{ + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; + out[4] += in[4]; + out[5] += in[5]; + out[6] += in[6]; + out[7] += in[7]; + out[8] += in[8]; +} + +/* felem_scalar sets out = in * scalar */ +static void felem_scalar(felem out, const felem in, limb scalar) +{ + out[0] = in[0] * scalar; + out[1] = in[1] * scalar; + out[2] = in[2] * scalar; + out[3] = in[3] * scalar; + out[4] = in[4] * scalar; + out[5] = in[5] * scalar; + out[6] = in[6] * scalar; + out[7] = in[7] * scalar; + out[8] = in[8] * scalar; +} + +/* felem_scalar64 sets out = out * scalar */ +static void felem_scalar64(felem out, limb scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; + out[7] *= scalar; + out[8] *= scalar; +} + +/* felem_scalar128 sets out = out * scalar */ +static void felem_scalar128(largefelem out, limb scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; + out[7] *= scalar; + out[8] *= scalar; +} + +/*- + * felem_neg sets |out| to |-in| + * On entry: + * in[i] < 2^59 + 2^14 + * On exit: + * out[i] < 2^62 + */ +static void felem_neg(felem out, const felem in) +{ + /* In order to prevent underflow, we subtract from 0 mod p. */ + static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5); + static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4); + + out[0] = two62m3 - in[0]; + out[1] = two62m2 - in[1]; + out[2] = two62m2 - in[2]; + out[3] = two62m2 - in[3]; + out[4] = two62m2 - in[4]; + out[5] = two62m2 - in[5]; + out[6] = two62m2 - in[6]; + out[7] = two62m2 - in[7]; + out[8] = two62m2 - in[8]; +} + +/*- + * felem_diff64 subtracts |in| from |out| + * On entry: + * in[i] < 2^59 + 2^14 + * On exit: + * out[i] < out[i] + 2^62 + */ +static void felem_diff64(felem out, const felem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5); + static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4); + + out[0] += two62m3 - in[0]; + out[1] += two62m2 - in[1]; + out[2] += two62m2 - in[2]; + out[3] += two62m2 - in[3]; + out[4] += two62m2 - in[4]; + out[5] += two62m2 - in[5]; + out[6] += two62m2 - in[6]; + out[7] += two62m2 - in[7]; + out[8] += two62m2 - in[8]; +} + +/*- + * felem_diff_128_64 subtracts |in| from |out| + * On entry: + * in[i] < 2^62 + 2^17 + * On exit: + * out[i] < out[i] + 2^63 + */ +static void felem_diff_128_64(largefelem out, const felem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5); + static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4); + + out[0] += two63m6 - in[0]; + out[1] += two63m5 - in[1]; + out[2] += two63m5 - in[2]; + out[3] += two63m5 - in[3]; + out[4] += two63m5 - in[4]; + out[5] += two63m5 - in[5]; + out[6] += two63m5 - in[6]; + out[7] += two63m5 - in[7]; + out[8] += two63m5 - in[8]; +} + +/*- + * felem_diff_128_64 subtracts |in| from |out| + * On entry: + * in[i] < 2^126 + * On exit: + * out[i] < out[i] + 2^127 - 2^69 + */ +static void felem_diff128(largefelem out, const largefelem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + static const uint128_t two127m70 = + (((uint128_t) 1) << 127) - (((uint128_t) 1) << 70); + static const uint128_t two127m69 = + (((uint128_t) 1) << 127) - (((uint128_t) 1) << 69); + + out[0] += (two127m70 - in[0]); + out[1] += (two127m69 - in[1]); + out[2] += (two127m69 - in[2]); + out[3] += (two127m69 - in[3]); + out[4] += (two127m69 - in[4]); + out[5] += (two127m69 - in[5]); + out[6] += (two127m69 - in[6]); + out[7] += (two127m69 - in[7]); + out[8] += (two127m69 - in[8]); +} + +/*- + * felem_square sets |out| = |in|^2 + * On entry: + * in[i] < 2^62 + * On exit: + * out[i] < 17 * max(in[i]) * max(in[i]) + */ +static void felem_square(largefelem out, const felem in) +{ + felem inx2, inx4; + felem_scalar(inx2, in, 2); + felem_scalar(inx4, in, 4); + + /*- + * We have many cases were we want to do + * in[x] * in[y] + + * in[y] * in[x] + * This is obviously just + * 2 * in[x] * in[y] + * However, rather than do the doubling on the 128 bit result, we + * double one of the inputs to the multiplication by reading from + * |inx2| + */ + + out[0] = ((uint128_t) in[0]) * in[0]; + out[1] = ((uint128_t) in[0]) * inx2[1]; + out[2] = ((uint128_t) in[0]) * inx2[2] + ((uint128_t) in[1]) * in[1]; + out[3] = ((uint128_t) in[0]) * inx2[3] + ((uint128_t) in[1]) * inx2[2]; + out[4] = ((uint128_t) in[0]) * inx2[4] + + ((uint128_t) in[1]) * inx2[3] + ((uint128_t) in[2]) * in[2]; + out[5] = ((uint128_t) in[0]) * inx2[5] + + ((uint128_t) in[1]) * inx2[4] + ((uint128_t) in[2]) * inx2[3]; + out[6] = ((uint128_t) in[0]) * inx2[6] + + ((uint128_t) in[1]) * inx2[5] + + ((uint128_t) in[2]) * inx2[4] + ((uint128_t) in[3]) * in[3]; + out[7] = ((uint128_t) in[0]) * inx2[7] + + ((uint128_t) in[1]) * inx2[6] + + ((uint128_t) in[2]) * inx2[5] + ((uint128_t) in[3]) * inx2[4]; + out[8] = ((uint128_t) in[0]) * inx2[8] + + ((uint128_t) in[1]) * inx2[7] + + ((uint128_t) in[2]) * inx2[6] + + ((uint128_t) in[3]) * inx2[5] + ((uint128_t) in[4]) * in[4]; + + /* + * The remaining limbs fall above 2^521, with the first falling at 2^522. + * They correspond to locations one bit up from the limbs produced above + * so we would have to multiply by two to align them. Again, rather than + * operate on the 128-bit result, we double one of the inputs to the + * multiplication. If we want to double for both this reason, and the + * reason above, then we end up multiplying by four. + */ + + /* 9 */ + out[0] += ((uint128_t) in[1]) * inx4[8] + + ((uint128_t) in[2]) * inx4[7] + + ((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[4]) * inx4[5]; + + /* 10 */ + out[1] += ((uint128_t) in[2]) * inx4[8] + + ((uint128_t) in[3]) * inx4[7] + + ((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[5]) * inx2[5]; + + /* 11 */ + out[2] += ((uint128_t) in[3]) * inx4[8] + + ((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[5]) * inx4[6]; + + /* 12 */ + out[3] += ((uint128_t) in[4]) * inx4[8] + + ((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[6]) * inx2[6]; + + /* 13 */ + out[4] += ((uint128_t) in[5]) * inx4[8] + ((uint128_t) in[6]) * inx4[7]; + + /* 14 */ + out[5] += ((uint128_t) in[6]) * inx4[8] + ((uint128_t) in[7]) * inx2[7]; + + /* 15 */ + out[6] += ((uint128_t) in[7]) * inx4[8]; + + /* 16 */ + out[7] += ((uint128_t) in[8]) * inx2[8]; +} + +/*- + * felem_mul sets |out| = |in1| * |in2| + * On entry: + * in1[i] < 2^64 + * in2[i] < 2^63 + * On exit: + * out[i] < 17 * max(in1[i]) * max(in2[i]) + */ +static void felem_mul(largefelem out, const felem in1, const felem in2) +{ + felem in2x2; + felem_scalar(in2x2, in2, 2); + + out[0] = ((uint128_t) in1[0]) * in2[0]; + + out[1] = ((uint128_t) in1[0]) * in2[1] + ((uint128_t) in1[1]) * in2[0]; + + out[2] = ((uint128_t) in1[0]) * in2[2] + + ((uint128_t) in1[1]) * in2[1] + ((uint128_t) in1[2]) * in2[0]; + + out[3] = ((uint128_t) in1[0]) * in2[3] + + ((uint128_t) in1[1]) * in2[2] + + ((uint128_t) in1[2]) * in2[1] + ((uint128_t) in1[3]) * in2[0]; + + out[4] = ((uint128_t) in1[0]) * in2[4] + + ((uint128_t) in1[1]) * in2[3] + + ((uint128_t) in1[2]) * in2[2] + + ((uint128_t) in1[3]) * in2[1] + ((uint128_t) in1[4]) * in2[0]; + + out[5] = ((uint128_t) in1[0]) * in2[5] + + ((uint128_t) in1[1]) * in2[4] + + ((uint128_t) in1[2]) * in2[3] + + ((uint128_t) in1[3]) * in2[2] + + ((uint128_t) in1[4]) * in2[1] + ((uint128_t) in1[5]) * in2[0]; + + out[6] = ((uint128_t) in1[0]) * in2[6] + + ((uint128_t) in1[1]) * in2[5] + + ((uint128_t) in1[2]) * in2[4] + + ((uint128_t) in1[3]) * in2[3] + + ((uint128_t) in1[4]) * in2[2] + + ((uint128_t) in1[5]) * in2[1] + ((uint128_t) in1[6]) * in2[0]; + + out[7] = ((uint128_t) in1[0]) * in2[7] + + ((uint128_t) in1[1]) * in2[6] + + ((uint128_t) in1[2]) * in2[5] + + ((uint128_t) in1[3]) * in2[4] + + ((uint128_t) in1[4]) * in2[3] + + ((uint128_t) in1[5]) * in2[2] + + ((uint128_t) in1[6]) * in2[1] + ((uint128_t) in1[7]) * in2[0]; + + out[8] = ((uint128_t) in1[0]) * in2[8] + + ((uint128_t) in1[1]) * in2[7] + + ((uint128_t) in1[2]) * in2[6] + + ((uint128_t) in1[3]) * in2[5] + + ((uint128_t) in1[4]) * in2[4] + + ((uint128_t) in1[5]) * in2[3] + + ((uint128_t) in1[6]) * in2[2] + + ((uint128_t) in1[7]) * in2[1] + ((uint128_t) in1[8]) * in2[0]; + + /* See comment in felem_square about the use of in2x2 here */ + + out[0] += ((uint128_t) in1[1]) * in2x2[8] + + ((uint128_t) in1[2]) * in2x2[7] + + ((uint128_t) in1[3]) * in2x2[6] + + ((uint128_t) in1[4]) * in2x2[5] + + ((uint128_t) in1[5]) * in2x2[4] + + ((uint128_t) in1[6]) * in2x2[3] + + ((uint128_t) in1[7]) * in2x2[2] + ((uint128_t) in1[8]) * in2x2[1]; + + out[1] += ((uint128_t) in1[2]) * in2x2[8] + + ((uint128_t) in1[3]) * in2x2[7] + + ((uint128_t) in1[4]) * in2x2[6] + + ((uint128_t) in1[5]) * in2x2[5] + + ((uint128_t) in1[6]) * in2x2[4] + + ((uint128_t) in1[7]) * in2x2[3] + ((uint128_t) in1[8]) * in2x2[2]; + + out[2] += ((uint128_t) in1[3]) * in2x2[8] + + ((uint128_t) in1[4]) * in2x2[7] + + ((uint128_t) in1[5]) * in2x2[6] + + ((uint128_t) in1[6]) * in2x2[5] + + ((uint128_t) in1[7]) * in2x2[4] + ((uint128_t) in1[8]) * in2x2[3]; + + out[3] += ((uint128_t) in1[4]) * in2x2[8] + + ((uint128_t) in1[5]) * in2x2[7] + + ((uint128_t) in1[6]) * in2x2[6] + + ((uint128_t) in1[7]) * in2x2[5] + ((uint128_t) in1[8]) * in2x2[4]; + + out[4] += ((uint128_t) in1[5]) * in2x2[8] + + ((uint128_t) in1[6]) * in2x2[7] + + ((uint128_t) in1[7]) * in2x2[6] + ((uint128_t) in1[8]) * in2x2[5]; + + out[5] += ((uint128_t) in1[6]) * in2x2[8] + + ((uint128_t) in1[7]) * in2x2[7] + ((uint128_t) in1[8]) * in2x2[6]; + + out[6] += ((uint128_t) in1[7]) * in2x2[8] + + ((uint128_t) in1[8]) * in2x2[7]; + + out[7] += ((uint128_t) in1[8]) * in2x2[8]; +} + +static const limb bottom52bits = 0xfffffffffffff; + +/*- + * felem_reduce converts a largefelem to an felem. + * On entry: + * in[i] < 2^128 + * On exit: + * out[i] < 2^59 + 2^14 + */ +static void felem_reduce(felem out, const largefelem in) +{ + u64 overflow1, overflow2; + + out[0] = ((limb) in[0]) & bottom58bits; + out[1] = ((limb) in[1]) & bottom58bits; + out[2] = ((limb) in[2]) & bottom58bits; + out[3] = ((limb) in[3]) & bottom58bits; + out[4] = ((limb) in[4]) & bottom58bits; + out[5] = ((limb) in[5]) & bottom58bits; + out[6] = ((limb) in[6]) & bottom58bits; + out[7] = ((limb) in[7]) & bottom58bits; + out[8] = ((limb) in[8]) & bottom58bits; + + /* out[i] < 2^58 */ + + out[1] += ((limb) in[0]) >> 58; + out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6; + /*- + * out[1] < 2^58 + 2^6 + 2^58 + * = 2^59 + 2^6 + */ + out[2] += ((limb) (in[0] >> 64)) >> 52; + + out[2] += ((limb) in[1]) >> 58; + out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6; + out[3] += ((limb) (in[1] >> 64)) >> 52; + + out[3] += ((limb) in[2]) >> 58; + out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6; + out[4] += ((limb) (in[2] >> 64)) >> 52; + + out[4] += ((limb) in[3]) >> 58; + out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6; + out[5] += ((limb) (in[3] >> 64)) >> 52; + + out[5] += ((limb) in[4]) >> 58; + out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6; + out[6] += ((limb) (in[4] >> 64)) >> 52; + + out[6] += ((limb) in[5]) >> 58; + out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6; + out[7] += ((limb) (in[5] >> 64)) >> 52; + + out[7] += ((limb) in[6]) >> 58; + out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6; + out[8] += ((limb) (in[6] >> 64)) >> 52; + + out[8] += ((limb) in[7]) >> 58; + out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6; + /*- + * out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12 + * < 2^59 + 2^13 + */ + overflow1 = ((limb) (in[7] >> 64)) >> 52; + + overflow1 += ((limb) in[8]) >> 58; + overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6; + overflow2 = ((limb) (in[8] >> 64)) >> 52; + + overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */ + overflow2 <<= 1; /* overflow2 < 2^13 */ + + out[0] += overflow1; /* out[0] < 2^60 */ + out[1] += overflow2; /* out[1] < 2^59 + 2^6 + 2^13 */ + + out[1] += out[0] >> 58; + out[0] &= bottom58bits; + /*- + * out[0] < 2^58 + * out[1] < 2^59 + 2^6 + 2^13 + 2^2 + * < 2^59 + 2^14 + */ +} + +static void felem_square_reduce(felem out, const felem in) +{ + largefelem tmp; + felem_square(tmp, in); + felem_reduce(out, tmp); +} + +static void felem_mul_reduce(felem out, const felem in1, const felem in2) +{ + largefelem tmp; + felem_mul(tmp, in1, in2); + felem_reduce(out, tmp); +} + +/*- + * felem_inv calculates |out| = |in|^{-1} + * + * Based on Fermat's Little Theorem: + * a^p = a (mod p) + * a^{p-1} = 1 (mod p) + * a^{p-2} = a^{-1} (mod p) + */ +static void felem_inv(felem out, const felem in) +{ + felem ftmp, ftmp2, ftmp3, ftmp4; + largefelem tmp; + unsigned i; + + felem_square(tmp, in); + felem_reduce(ftmp, tmp); /* 2^1 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */ + felem_assign(ftmp2, ftmp); + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 2^0 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^4 - 2^1 */ + + felem_square(tmp, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^3 - 2^1 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^4 - 2^2 */ + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^4 - 2^0 */ + + felem_assign(ftmp2, ftmp3); + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^5 - 2^1 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^6 - 2^2 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^7 - 2^3 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^8 - 2^4 */ + felem_assign(ftmp4, ftmp3); + felem_mul(tmp, ftmp3, ftmp); + felem_reduce(ftmp4, tmp); /* 2^8 - 2^1 */ + felem_square(tmp, ftmp4); + felem_reduce(ftmp4, tmp); /* 2^9 - 2^2 */ + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^8 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 8; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^16 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 16; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^32 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 32; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^64 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 64; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^128 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 128; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^256 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 256; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^512 - 2^0 */ + + for (i = 0; i < 9; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */ + } + felem_mul(tmp, ftmp3, ftmp4); + felem_reduce(ftmp3, tmp); /* 2^512 - 2^2 */ + felem_mul(tmp, ftmp3, in); + felem_reduce(out, tmp); /* 2^512 - 3 */ +} + +/* This is 2^521-1, expressed as an felem */ +static const felem kPrime = { + 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff, + 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff, + 0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff +}; + +/*- + * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0 + * otherwise. + * On entry: + * in[i] < 2^59 + 2^14 + */ +static limb felem_is_zero(const felem in) +{ + felem ftmp; + limb is_zero, is_p; + felem_assign(ftmp, in); + + ftmp[0] += ftmp[8] >> 57; + ftmp[8] &= bottom57bits; + /* ftmp[8] < 2^57 */ + ftmp[1] += ftmp[0] >> 58; + ftmp[0] &= bottom58bits; + ftmp[2] += ftmp[1] >> 58; + ftmp[1] &= bottom58bits; + ftmp[3] += ftmp[2] >> 58; + ftmp[2] &= bottom58bits; + ftmp[4] += ftmp[3] >> 58; + ftmp[3] &= bottom58bits; + ftmp[5] += ftmp[4] >> 58; + ftmp[4] &= bottom58bits; + ftmp[6] += ftmp[5] >> 58; + ftmp[5] &= bottom58bits; + ftmp[7] += ftmp[6] >> 58; + ftmp[6] &= bottom58bits; + ftmp[8] += ftmp[7] >> 58; + ftmp[7] &= bottom58bits; + /* ftmp[8] < 2^57 + 4 */ + + /* + * The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is greater + * than our bound for ftmp[8]. Therefore we only have to check if the + * zero is zero or 2^521-1. + */ + + is_zero = 0; + is_zero |= ftmp[0]; + is_zero |= ftmp[1]; + is_zero |= ftmp[2]; + is_zero |= ftmp[3]; + is_zero |= ftmp[4]; + is_zero |= ftmp[5]; + is_zero |= ftmp[6]; + is_zero |= ftmp[7]; + is_zero |= ftmp[8]; + + is_zero--; + /* + * We know that ftmp[i] < 2^63, therefore the only way that the top bit + * can be set is if is_zero was 0 before the decrement. + */ + is_zero = 0 - (is_zero >> 63); + + is_p = ftmp[0] ^ kPrime[0]; + is_p |= ftmp[1] ^ kPrime[1]; + is_p |= ftmp[2] ^ kPrime[2]; + is_p |= ftmp[3] ^ kPrime[3]; + is_p |= ftmp[4] ^ kPrime[4]; + is_p |= ftmp[5] ^ kPrime[5]; + is_p |= ftmp[6] ^ kPrime[6]; + is_p |= ftmp[7] ^ kPrime[7]; + is_p |= ftmp[8] ^ kPrime[8]; + + is_p--; + is_p = 0 - (is_p >> 63); + + is_zero |= is_p; + return is_zero; +} + +static int felem_is_zero_int(const void *in) +{ + return (int)(felem_is_zero(in) & ((limb) 1)); +} + +/*- + * felem_contract converts |in| to its unique, minimal representation. + * On entry: + * in[i] < 2^59 + 2^14 + */ +static void felem_contract(felem out, const felem in) +{ + limb is_p, is_greater, sign; + static const limb two58 = ((limb) 1) << 58; + + felem_assign(out, in); + + out[0] += out[8] >> 57; + out[8] &= bottom57bits; + /* out[8] < 2^57 */ + out[1] += out[0] >> 58; + out[0] &= bottom58bits; + out[2] += out[1] >> 58; + out[1] &= bottom58bits; + out[3] += out[2] >> 58; + out[2] &= bottom58bits; + out[4] += out[3] >> 58; + out[3] &= bottom58bits; + out[5] += out[4] >> 58; + out[4] &= bottom58bits; + out[6] += out[5] >> 58; + out[5] &= bottom58bits; + out[7] += out[6] >> 58; + out[6] &= bottom58bits; + out[8] += out[7] >> 58; + out[7] &= bottom58bits; + /* out[8] < 2^57 + 4 */ + + /* + * If the value is greater than 2^521-1 then we have to subtract 2^521-1 + * out. See the comments in felem_is_zero regarding why we don't test for + * other multiples of the prime. + */ + + /* + * First, if |out| is equal to 2^521-1, we subtract it out to get zero. + */ + + is_p = out[0] ^ kPrime[0]; + is_p |= out[1] ^ kPrime[1]; + is_p |= out[2] ^ kPrime[2]; + is_p |= out[3] ^ kPrime[3]; + is_p |= out[4] ^ kPrime[4]; + is_p |= out[5] ^ kPrime[5]; + is_p |= out[6] ^ kPrime[6]; + is_p |= out[7] ^ kPrime[7]; + is_p |= out[8] ^ kPrime[8]; + + is_p--; + is_p &= is_p << 32; + is_p &= is_p << 16; + is_p &= is_p << 8; + is_p &= is_p << 4; + is_p &= is_p << 2; + is_p &= is_p << 1; + is_p = 0 - (is_p >> 63); + is_p = ~is_p; + + /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */ + + out[0] &= is_p; + out[1] &= is_p; + out[2] &= is_p; + out[3] &= is_p; + out[4] &= is_p; + out[5] &= is_p; + out[6] &= is_p; + out[7] &= is_p; + out[8] &= is_p; + + /* + * In order to test that |out| >= 2^521-1 we need only test if out[8] >> + * 57 is greater than zero as (2^521-1) + x >= 2^522 + */ + is_greater = out[8] >> 57; + is_greater |= is_greater << 32; + is_greater |= is_greater << 16; + is_greater |= is_greater << 8; + is_greater |= is_greater << 4; + is_greater |= is_greater << 2; + is_greater |= is_greater << 1; + is_greater = 0 - (is_greater >> 63); + + out[0] -= kPrime[0] & is_greater; + out[1] -= kPrime[1] & is_greater; + out[2] -= kPrime[2] & is_greater; + out[3] -= kPrime[3] & is_greater; + out[4] -= kPrime[4] & is_greater; + out[5] -= kPrime[5] & is_greater; + out[6] -= kPrime[6] & is_greater; + out[7] -= kPrime[7] & is_greater; + out[8] -= kPrime[8] & is_greater; + + /* Eliminate negative coefficients */ + sign = -(out[0] >> 63); + out[0] += (two58 & sign); + out[1] -= (1 & sign); + sign = -(out[1] >> 63); + out[1] += (two58 & sign); + out[2] -= (1 & sign); + sign = -(out[2] >> 63); + out[2] += (two58 & sign); + out[3] -= (1 & sign); + sign = -(out[3] >> 63); + out[3] += (two58 & sign); + out[4] -= (1 & sign); + sign = -(out[4] >> 63); + out[4] += (two58 & sign); + out[5] -= (1 & sign); + sign = -(out[0] >> 63); + out[5] += (two58 & sign); + out[6] -= (1 & sign); + sign = -(out[6] >> 63); + out[6] += (two58 & sign); + out[7] -= (1 & sign); + sign = -(out[7] >> 63); + out[7] += (two58 & sign); + out[8] -= (1 & sign); + sign = -(out[5] >> 63); + out[5] += (two58 & sign); + out[6] -= (1 & sign); + sign = -(out[6] >> 63); + out[6] += (two58 & sign); + out[7] -= (1 & sign); + sign = -(out[7] >> 63); + out[7] += (two58 & sign); + out[8] -= (1 & sign); +} + +/*- + * Group operations + * ---------------- + * + * Building on top of the field operations we have the operations on the + * elliptic curve group itself. Points on the curve are represented in Jacobian + * coordinates */ + +/*- + * point_double calcuates 2*(x_in, y_in, z_in) + * + * The method is taken from: + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + * + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. + * while x_out == y_in is not (maybe this works, but it's not tested). */ +static void +point_double(felem x_out, felem y_out, felem z_out, + const felem x_in, const felem y_in, const felem z_in) +{ + largefelem tmp, tmp2; + felem delta, gamma, beta, alpha, ftmp, ftmp2; + + felem_assign(ftmp, x_in); + felem_assign(ftmp2, x_in); + + /* delta = z^2 */ + felem_square(tmp, z_in); + felem_reduce(delta, tmp); /* delta[i] < 2^59 + 2^14 */ + + /* gamma = y^2 */ + felem_square(tmp, y_in); + felem_reduce(gamma, tmp); /* gamma[i] < 2^59 + 2^14 */ + + /* beta = x*gamma */ + felem_mul(tmp, x_in, gamma); + felem_reduce(beta, tmp); /* beta[i] < 2^59 + 2^14 */ + + /* alpha = 3*(x-delta)*(x+delta) */ + felem_diff64(ftmp, delta); + /* ftmp[i] < 2^61 */ + felem_sum64(ftmp2, delta); + /* ftmp2[i] < 2^60 + 2^15 */ + felem_scalar64(ftmp2, 3); + /* ftmp2[i] < 3*2^60 + 3*2^15 */ + felem_mul(tmp, ftmp, ftmp2); + /*- + * tmp[i] < 17(3*2^121 + 3*2^76) + * = 61*2^121 + 61*2^76 + * < 64*2^121 + 64*2^76 + * = 2^127 + 2^82 + * < 2^128 + */ + felem_reduce(alpha, tmp); + + /* x' = alpha^2 - 8*beta */ + felem_square(tmp, alpha); + /* + * tmp[i] < 17*2^120 < 2^125 + */ + felem_assign(ftmp, beta); + felem_scalar64(ftmp, 8); + /* ftmp[i] < 2^62 + 2^17 */ + felem_diff_128_64(tmp, ftmp); + /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */ + felem_reduce(x_out, tmp); + + /* z' = (y + z)^2 - gamma - delta */ + felem_sum64(delta, gamma); + /* delta[i] < 2^60 + 2^15 */ + felem_assign(ftmp, y_in); + felem_sum64(ftmp, z_in); + /* ftmp[i] < 2^60 + 2^15 */ + felem_square(tmp, ftmp); + /* + * tmp[i] < 17(2^122) < 2^127 + */ + felem_diff_128_64(tmp, delta); + /* tmp[i] < 2^127 + 2^63 */ + felem_reduce(z_out, tmp); + + /* y' = alpha*(4*beta - x') - 8*gamma^2 */ + felem_scalar64(beta, 4); + /* beta[i] < 2^61 + 2^16 */ + felem_diff64(beta, x_out); + /* beta[i] < 2^61 + 2^60 + 2^16 */ + felem_mul(tmp, alpha, beta); + /*- + * tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16)) + * = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30) + * = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30) + * < 2^128 + */ + felem_square(tmp2, gamma); + /*- + * tmp2[i] < 17*(2^59 + 2^14)^2 + * = 17*(2^118 + 2^74 + 2^28) + */ + felem_scalar128(tmp2, 8); + /*- + * tmp2[i] < 8*17*(2^118 + 2^74 + 2^28) + * = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31 + * < 2^126 + */ + felem_diff128(tmp, tmp2); + /*- + * tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30) + * = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 + + * 2^74 + 2^69 + 2^34 + 2^30 + * < 2^128 + */ + felem_reduce(y_out, tmp); +} + +/* copy_conditional copies in to out iff mask is all ones. */ +static void copy_conditional(felem out, const felem in, limb mask) +{ + unsigned i; + for (i = 0; i < NLIMBS; ++i) { + const limb tmp = mask & (in[i] ^ out[i]); + out[i] ^= tmp; + } +} + +/*- + * point_add calcuates (x1, y1, z1) + (x2, y2, z2) + * + * The method is taken from + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, + * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). + * + * This function includes a branch for checking whether the two input points + * are equal (while not equal to the point at infinity). This case never + * happens during single point multiplication, so there is no timing leak for + * ECDH or ECDSA signing. */ +static void point_add(felem x3, felem y3, felem z3, + const felem x1, const felem y1, const felem z1, + const int mixed, const felem x2, const felem y2, + const felem z2) +{ + felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out; + largefelem tmp, tmp2; + limb x_equal, y_equal, z1_is_zero, z2_is_zero; + + z1_is_zero = felem_is_zero(z1); + z2_is_zero = felem_is_zero(z2); + + /* ftmp = z1z1 = z1**2 */ + felem_square(tmp, z1); + felem_reduce(ftmp, tmp); + + if (!mixed) { + /* ftmp2 = z2z2 = z2**2 */ + felem_square(tmp, z2); + felem_reduce(ftmp2, tmp); + + /* u1 = ftmp3 = x1*z2z2 */ + felem_mul(tmp, x1, ftmp2); + felem_reduce(ftmp3, tmp); + + /* ftmp5 = z1 + z2 */ + felem_assign(ftmp5, z1); + felem_sum64(ftmp5, z2); + /* ftmp5[i] < 2^61 */ + + /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */ + felem_square(tmp, ftmp5); + /* tmp[i] < 17*2^122 */ + felem_diff_128_64(tmp, ftmp); + /* tmp[i] < 17*2^122 + 2^63 */ + felem_diff_128_64(tmp, ftmp2); + /* tmp[i] < 17*2^122 + 2^64 */ + felem_reduce(ftmp5, tmp); + + /* ftmp2 = z2 * z2z2 */ + felem_mul(tmp, ftmp2, z2); + felem_reduce(ftmp2, tmp); + + /* s1 = ftmp6 = y1 * z2**3 */ + felem_mul(tmp, y1, ftmp2); + felem_reduce(ftmp6, tmp); + } else { + /* + * We'll assume z2 = 1 (special case z2 = 0 is handled later) + */ + + /* u1 = ftmp3 = x1*z2z2 */ + felem_assign(ftmp3, x1); + + /* ftmp5 = 2*z1z2 */ + felem_scalar(ftmp5, z1, 2); + + /* s1 = ftmp6 = y1 * z2**3 */ + felem_assign(ftmp6, y1); + } + + /* u2 = x2*z1z1 */ + felem_mul(tmp, x2, ftmp); + /* tmp[i] < 17*2^120 */ + + /* h = ftmp4 = u2 - u1 */ + felem_diff_128_64(tmp, ftmp3); + /* tmp[i] < 17*2^120 + 2^63 */ + felem_reduce(ftmp4, tmp); + + x_equal = felem_is_zero(ftmp4); + + /* z_out = ftmp5 * h */ + felem_mul(tmp, ftmp5, ftmp4); + felem_reduce(z_out, tmp); + + /* ftmp = z1 * z1z1 */ + felem_mul(tmp, ftmp, z1); + felem_reduce(ftmp, tmp); + + /* s2 = tmp = y2 * z1**3 */ + felem_mul(tmp, y2, ftmp); + /* tmp[i] < 17*2^120 */ + + /* r = ftmp5 = (s2 - s1)*2 */ + felem_diff_128_64(tmp, ftmp6); + /* tmp[i] < 17*2^120 + 2^63 */ + felem_reduce(ftmp5, tmp); + y_equal = felem_is_zero(ftmp5); + felem_scalar64(ftmp5, 2); + /* ftmp5[i] < 2^61 */ + + if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + /* I = ftmp = (2h)**2 */ + felem_assign(ftmp, ftmp4); + felem_scalar64(ftmp, 2); + /* ftmp[i] < 2^61 */ + felem_square(tmp, ftmp); + /* tmp[i] < 17*2^122 */ + felem_reduce(ftmp, tmp); + + /* J = ftmp2 = h * I */ + felem_mul(tmp, ftmp4, ftmp); + felem_reduce(ftmp2, tmp); + + /* V = ftmp4 = U1 * I */ + felem_mul(tmp, ftmp3, ftmp); + felem_reduce(ftmp4, tmp); + + /* x_out = r**2 - J - 2V */ + felem_square(tmp, ftmp5); + /* tmp[i] < 17*2^122 */ + felem_diff_128_64(tmp, ftmp2); + /* tmp[i] < 17*2^122 + 2^63 */ + felem_assign(ftmp3, ftmp4); + felem_scalar64(ftmp4, 2); + /* ftmp4[i] < 2^61 */ + felem_diff_128_64(tmp, ftmp4); + /* tmp[i] < 17*2^122 + 2^64 */ + felem_reduce(x_out, tmp); + + /* y_out = r(V-x_out) - 2 * s1 * J */ + felem_diff64(ftmp3, x_out); + /* + * ftmp3[i] < 2^60 + 2^60 = 2^61 + */ + felem_mul(tmp, ftmp5, ftmp3); + /* tmp[i] < 17*2^122 */ + felem_mul(tmp2, ftmp6, ftmp2); + /* tmp2[i] < 17*2^120 */ + felem_scalar128(tmp2, 2); + /* tmp2[i] < 17*2^121 */ + felem_diff128(tmp, tmp2); + /*- + * tmp[i] < 2^127 - 2^69 + 17*2^122 + * = 2^126 - 2^122 - 2^6 - 2^2 - 1 + * < 2^127 + */ + felem_reduce(y_out, tmp); + + copy_conditional(x_out, x2, z1_is_zero); + copy_conditional(x_out, x1, z2_is_zero); + copy_conditional(y_out, y2, z1_is_zero); + copy_conditional(y_out, y1, z2_is_zero); + copy_conditional(z_out, z2, z1_is_zero); + copy_conditional(z_out, z1, z2_is_zero); + felem_assign(x3, x_out); + felem_assign(y3, y_out); + felem_assign(z3, z_out); +} + +/*- + * Base point pre computation + * -------------------------- + * + * Two different sorts of precomputed tables are used in the following code. + * Each contain various points on the curve, where each point is three field + * elements (x, y, z). + * + * For the base point table, z is usually 1 (0 for the point at infinity). + * This table has 16 elements: + * index | bits | point + * ------+---------+------------------------------ + * 0 | 0 0 0 0 | 0G + * 1 | 0 0 0 1 | 1G + * 2 | 0 0 1 0 | 2^130G + * 3 | 0 0 1 1 | (2^130 + 1)G + * 4 | 0 1 0 0 | 2^260G + * 5 | 0 1 0 1 | (2^260 + 1)G + * 6 | 0 1 1 0 | (2^260 + 2^130)G + * 7 | 0 1 1 1 | (2^260 + 2^130 + 1)G + * 8 | 1 0 0 0 | 2^390G + * 9 | 1 0 0 1 | (2^390 + 1)G + * 10 | 1 0 1 0 | (2^390 + 2^130)G + * 11 | 1 0 1 1 | (2^390 + 2^130 + 1)G + * 12 | 1 1 0 0 | (2^390 + 2^260)G + * 13 | 1 1 0 1 | (2^390 + 2^260 + 1)G + * 14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G + * 15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G + * + * The reason for this is so that we can clock bits into four different + * locations when doing simple scalar multiplies against the base point. + * + * Tables for other points have table[i] = iG for i in 0 .. 16. */ + +/* gmul is the table of precomputed base points */ +static const felem gmul[16][3] = { {{0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334, + 0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8, + 0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404}, + {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353, + 0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45, + 0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad, + 0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e, + 0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5}, + {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58, + 0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c, + 0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873, + 0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c, + 0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9}, + {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52, + 0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e, + 0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2, + 0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561, + 0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065}, + {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a, + 0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e, + 0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6, + 0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51, + 0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe}, + {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d, + 0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c, + 0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27, + 0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f, + 0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256}, + {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa, + 0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2, + 0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890, + 0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74, + 0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23}, + {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516, + 0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1, + 0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce, + 0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7, + 0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5}, + {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318, + 0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83, + 0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae, + 0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef, + 0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203}, + {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447, + 0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283, + 0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5, + 0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c, + 0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a}, + {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df, + 0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645, + 0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292, + 0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422, + 0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b}, + {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30, + 0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb, + 0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767, + 0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3, + 0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf}, + {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2, + 0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692, + 0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3, + 0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade, + 0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684}, + {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8, + 0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a, + 0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608, + 0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610, + 0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d}, + {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006, + 0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86, + 0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c, + 0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9, + 0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f}, + {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7, + 0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c, + 0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}} +}; + +/* + * select_point selects the |idx|th point from a precomputation table and + * copies it to out. + */ + /* pre_comp below is of the size provided in |size| */ +static void select_point(const limb idx, unsigned int size, + const felem pre_comp[][3], felem out[3]) +{ + unsigned i, j; + limb *outlimbs = &out[0][0]; + memset(outlimbs, 0, 3 * sizeof(felem)); + + for (i = 0; i < size; i++) { + const limb *inlimbs = &pre_comp[i][0][0]; + limb mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (j = 0; j < NLIMBS * 3; j++) + outlimbs[j] |= inlimbs[j] & mask; + } +} + +/* get_bit returns the |i|th bit in |in| */ +static char get_bit(const felem_bytearray in, int i) +{ + if (i < 0) + return 0; + return (in[i >> 3] >> (i & 7)) & 1; +} + +/* + * Interleaved point multiplication using precomputed point multiples: The + * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars + * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the + * generator, using certain (large) precomputed multiples in g_pre_comp. + * Output point (X, Y, Z) is stored in x_out, y_out, z_out + */ +static void batch_mul(felem x_out, felem y_out, felem z_out, + const felem_bytearray scalars[], + const unsigned num_points, const u8 *g_scalar, + const int mixed, const felem pre_comp[][17][3], + const felem g_pre_comp[16][3]) +{ + int i, skip; + unsigned num, gen_mul = (g_scalar != NULL); + felem nq[3], tmp[4]; + limb bits; + u8 sign, digit; + + /* set nq to the point at infinity */ + memset(nq, 0, 3 * sizeof(felem)); + + /* + * Loop over all scalars msb-to-lsb, interleaving additions of multiples + * of the generator (last quarter of rounds) and additions of other + * points multiples (every 5th round). + */ + skip = 1; /* save two point operations in the first + * round */ + for (i = (num_points ? 520 : 130); i >= 0; --i) { + /* double */ + if (!skip) + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + + /* add multiples of the generator */ + if (gen_mul && (i <= 130)) { + bits = get_bit(g_scalar, i + 390) << 3; + if (i < 130) { + bits |= get_bit(g_scalar, i + 260) << 2; + bits |= get_bit(g_scalar, i + 130) << 1; + bits |= get_bit(g_scalar, i); + } + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp, tmp); + if (!skip) { + /* The 1 argument below is for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + } + + /* do other additions every 5 doublings */ + if (num_points && (i % 5 == 0)) { + /* loop over all scalars */ + for (num = 0; num < num_points; ++num) { + bits = get_bit(scalars[num], i + 4) << 5; + bits |= get_bit(scalars[num], i + 3) << 4; + bits |= get_bit(scalars[num], i + 2) << 3; + bits |= get_bit(scalars[num], i + 1) << 2; + bits |= get_bit(scalars[num], i) << 1; + bits |= get_bit(scalars[num], i - 1); + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + /* + * select the point to add or subtract, in constant time + */ + select_point(digit, 17, pre_comp[num], tmp); + felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative + * point */ + copy_conditional(tmp[1], tmp[3], (-(limb) sign)); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], + mixed, tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + } + } + } + felem_assign(x_out, nq[0]); + felem_assign(y_out, nq[1]); + felem_assign(z_out, nq[2]); +} + +/* Precomputation for the group generator. */ +typedef struct { + felem g_pre_comp[16][3]; + int references; +} NISTP521_PRE_COMP; + +const EC_METHOD *EC_GFp_nistp521_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_nistp521_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_nist_group_copy, + ec_GFp_nistp521_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_nistp521_point_get_affine_coordinates, + 0 /* point_set_compressed_coordinates */ , + 0 /* point2oct */ , + 0 /* oct2point */ , + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + ec_GFp_nistp521_points_mul, + ec_GFp_nistp521_precompute_mult, + ec_GFp_nistp521_have_precompute_mult, + ec_GFp_nist_field_mul, + ec_GFp_nist_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + + return &ret; +} + +/******************************************************************************/ +/* + * FUNCTIONS TO MANAGE PRECOMPUTATION + */ + +static NISTP521_PRE_COMP *nistp521_pre_comp_new() +{ + NISTP521_PRE_COMP *ret = NULL; + ret = (NISTP521_PRE_COMP *) OPENSSL_malloc(sizeof(NISTP521_PRE_COMP)); + if (!ret) { + ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + return ret; + } + memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); + ret->references = 1; + return ret; +} + +static void *nistp521_pre_comp_dup(void *src_) +{ + NISTP521_PRE_COMP *src = src_; + + /* no need to actually copy, these objects never change! */ + CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + + return src_; +} + +static void nistp521_pre_comp_free(void *pre_) +{ + int i; + NISTP521_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_free(pre); +} + +static void nistp521_pre_comp_clear_free(void *pre_) +{ + int i; + NISTP521_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_cleanse(pre, sizeof(*pre)); + OPENSSL_free(pre); +} + +/******************************************************************************/ +/* + * OPENSSL EC_METHOD FUNCTIONS + */ + +int ec_GFp_nistp521_group_init(EC_GROUP *group) +{ + int ret; + ret = ec_GFp_simple_group_init(group); + group->a_is_minus3 = 1; + return ret; +} + +int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *curve_p, *curve_a, *curve_b; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((curve_p = BN_CTX_get(ctx)) == NULL) || + ((curve_a = BN_CTX_get(ctx)) == NULL) || + ((curve_b = BN_CTX_get(ctx)) == NULL)) + goto err; + BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p); + BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a); + BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b); + if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { + ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, + EC_R_WRONG_CURVE_PARAMETERS); + goto err; + } + group->field_mod_func = BN_nist_mod_521; + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = + * (X/Z^2, Y/Z^3) + */ +int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + felem z1, z2, x_in, y_in, x_out, y_out; + largefelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || + (!BN_to_felem(z1, &point->Z))) + return 0; + felem_inv(z2, z1); + felem_square(tmp, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, x_in, z1); + felem_reduce(x_in, tmp); + felem_contract(x_out, x_in); + if (x != NULL) { + if (!felem_to_BN(x, x_out)) { + ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + felem_mul(tmp, z1, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, y_in, z1); + felem_reduce(y_in, tmp); + felem_contract(y_out, y_in); + if (y != NULL) { + if (!felem_to_BN(y, y_out)) { + ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + return 1; +} + +/* points below is of size |num|, and tmp_felems is of size |num+1/ */ +static void make_points_affine(size_t num, felem points[][3], + felem tmp_felems[]) +{ + /* + * Runs in constant time, unless an input is the point at infinity (which + * normally shouldn't happen). + */ + ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(felem), + tmp_felems, + (void (*)(void *))felem_one, + felem_is_zero_int, + (void (*)(void *, const void *)) + felem_assign, + (void (*)(void *, const void *)) + felem_square_reduce, (void (*) + (void *, + const void + *, + const void + *)) + felem_mul_reduce, + (void (*)(void *, const void *)) + felem_inv, + (void (*)(void *, const void *)) + felem_contract); +} + +/* + * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL + * values Result is stored in r (r can equal one of the inputs). + */ +int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + int ret = 0; + int j; + int mixed = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y, *z, *tmp_scalar; + felem_bytearray g_secret; + felem_bytearray *secrets = NULL; + felem(*pre_comp)[17][3] = NULL; + felem *tmp_felems = NULL; + felem_bytearray tmp; + unsigned i, num_bytes; + int have_pre_comp = 0; + size_t num_points = num; + felem x_in, y_in, z_in, x_out, y_out, z_out; + NISTP521_PRE_COMP *pre = NULL; + felem(*g_pre_comp)[3] = NULL; + EC_POINT *generator = NULL; + const EC_POINT *p = NULL; + const BIGNUM *p_scalar = NULL; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || + ((y = BN_CTX_get(ctx)) == NULL) || + ((z = BN_CTX_get(ctx)) == NULL) || + ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) + goto err; + + if (scalar != NULL) { + pre = EC_EX_DATA_get_data(group->extra_data, + nistp521_pre_comp_dup, + nistp521_pre_comp_free, + nistp521_pre_comp_clear_free); + if (pre) + /* we have precomputation, try to use it */ + g_pre_comp = &pre->g_pre_comp[0]; + else + /* try to use the standard precomputation */ + g_pre_comp = (felem(*)[3]) gmul; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + /* get the generator from precomputation */ + if (!felem_to_BN(x, g_pre_comp[1][0]) || + !felem_to_BN(y, g_pre_comp[1][1]) || + !felem_to_BN(z, g_pre_comp[1][2])) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_Jprojective_coordinates_GFp(group, + generator, x, y, z, + ctx)) + goto err; + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) + /* precomputation matches generator */ + have_pre_comp = 1; + else + /* + * we don't have valid precomputation: treat the generator as a + * random point + */ + num_points++; + } + + if (num_points > 0) { + if (num_points >= 2) { + /* + * unless we precompute multiples for just one point, converting + * those into affine form is time well spent + */ + mixed = 1; + } + secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); + pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem)); + if (mixed) + tmp_felems = + OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem)); + if ((secrets == NULL) || (pre_comp == NULL) + || (mixed && (tmp_felems == NULL))) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * we treat NULL scalars as 0, and NULL points as points at infinity, + * i.e., they contribute nothing to the linear combination + */ + memset(secrets, 0, num_points * sizeof(felem_bytearray)); + memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem)); + for (i = 0; i < num_points; ++i) { + if (i == num) + /* + * we didn't have a valid precomputation, so we pick the + * generator + */ + { + p = EC_GROUP_get0_generator(group); + p_scalar = scalar; + } else + /* the i^th point */ + { + p = points[i]; + p_scalar = scalars[i]; + } + if ((p_scalar != NULL) && (p != NULL)) { + /* reduce scalar to 0 <= scalar < 2^521 */ + if ((BN_num_bits(p_scalar) > 521) + || (BN_is_negative(p_scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(p_scalar, tmp); + flip_endian(secrets[i], tmp, num_bytes); + /* precompute multiples */ + if ((!BN_to_felem(x_out, &p->X)) || + (!BN_to_felem(y_out, &p->Y)) || + (!BN_to_felem(z_out, &p->Z))) + goto err; + memcpy(pre_comp[i][1][0], x_out, sizeof(felem)); + memcpy(pre_comp[i][1][1], y_out, sizeof(felem)); + memcpy(pre_comp[i][1][2], z_out, sizeof(felem)); + for (j = 2; j <= 16; ++j) { + if (j & 1) { + point_add(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][1][0], + pre_comp[i][1][1], pre_comp[i][1][2], 0, + pre_comp[i][j - 1][0], + pre_comp[i][j - 1][1], + pre_comp[i][j - 1][2]); + } else { + point_double(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][j / 2][0], + pre_comp[i][j / 2][1], + pre_comp[i][j / 2][2]); + } + } + } + } + if (mixed) + make_points_affine(num_points * 17, pre_comp[0], tmp_felems); + } + + /* the scalar for the generator */ + if ((scalar != NULL) && (have_pre_comp)) { + memset(g_secret, 0, sizeof(g_secret)); + /* reduce scalar to 0 <= scalar < 2^521 */ + if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(scalar, tmp); + flip_endian(g_secret, tmp, num_bytes); + /* do the multiplication with generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + g_secret, + mixed, (const felem(*)[17][3])pre_comp, + (const felem(*)[3])g_pre_comp); + } else + /* do the multiplication without generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); + /* reduce the output to its unique minimal representation */ + felem_contract(x_in, x_out); + felem_contract(y_in, y_out); + felem_contract(z_in, z_out); + if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || + (!felem_to_BN(z, z_in))) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (secrets != NULL) + OPENSSL_free(secrets); + if (pre_comp != NULL) + OPENSSL_free(pre_comp); + if (tmp_felems != NULL) + OPENSSL_free(tmp_felems); + return ret; +} + +int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + NISTP521_PRE_COMP *pre = NULL; + int i, j; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + EC_POINT *generator = NULL; + felem tmp_felems[16]; + + /* throw away old precomputation */ + EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup, + nistp521_pre_comp_free, + nistp521_pre_comp_clear_free); + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) + goto err; + /* get the generator */ + if (group->generator == NULL) + goto err; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + BN_bin2bn(nistp521_curve_params[3], sizeof(felem_bytearray), x); + BN_bin2bn(nistp521_curve_params[4], sizeof(felem_bytearray), y); + if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) + goto err; + if ((pre = nistp521_pre_comp_new()) == NULL) + goto err; + /* + * if the generator is the standard one, use built-in precomputation + */ + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { + memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); + goto done; + } + if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) || + (!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) || + (!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z))) + goto err; + /* compute 2^130*G, 2^260*G, 2^390*G */ + for (i = 1; i <= 4; i <<= 1) { + point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], + pre->g_pre_comp[2 * i][2], pre->g_pre_comp[i][0], + pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]); + for (j = 0; j < 129; ++j) { + point_double(pre->g_pre_comp[2 * i][0], + pre->g_pre_comp[2 * i][1], + pre->g_pre_comp[2 * i][2], + pre->g_pre_comp[2 * i][0], + pre->g_pre_comp[2 * i][1], + pre->g_pre_comp[2 * i][2]); + } + } + /* g_pre_comp[0] is the point at infinity */ + memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0])); + /* the remaining multiples */ + /* 2^130*G + 2^260*G */ + point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1], + pre->g_pre_comp[6][2], pre->g_pre_comp[4][0], + pre->g_pre_comp[4][1], pre->g_pre_comp[4][2], + 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], + pre->g_pre_comp[2][2]); + /* 2^130*G + 2^390*G */ + point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1], + pre->g_pre_comp[10][2], pre->g_pre_comp[8][0], + pre->g_pre_comp[8][1], pre->g_pre_comp[8][2], + 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], + pre->g_pre_comp[2][2]); + /* 2^260*G + 2^390*G */ + point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1], + pre->g_pre_comp[12][2], pre->g_pre_comp[8][0], + pre->g_pre_comp[8][1], pre->g_pre_comp[8][2], + 0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1], + pre->g_pre_comp[4][2]); + /* 2^130*G + 2^260*G + 2^390*G */ + point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1], + pre->g_pre_comp[14][2], pre->g_pre_comp[12][0], + pre->g_pre_comp[12][1], pre->g_pre_comp[12][2], + 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], + pre->g_pre_comp[2][2]); + for (i = 1; i < 8; ++i) { + /* odd multiples: add G */ + point_add(pre->g_pre_comp[2 * i + 1][0], + pre->g_pre_comp[2 * i + 1][1], + pre->g_pre_comp[2 * i + 1][2], pre->g_pre_comp[2 * i][0], + pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], 0, + pre->g_pre_comp[1][0], pre->g_pre_comp[1][1], + pre->g_pre_comp[1][2]); + } + make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems); + + done: + if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup, + nistp521_pre_comp_free, + nistp521_pre_comp_clear_free)) + goto err; + ret = 1; + pre = NULL; + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (pre) + nistp521_pre_comp_free(pre); + return ret; +} + +int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group) +{ + if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup, + nistp521_pre_comp_free, + nistp521_pre_comp_clear_free) + != NULL) + return 1; + else + return 0; +} + +#else +static void *dummy = &dummy; +#endif diff --git a/Sources/COpenSSL/ecp_nistputil.c b/Sources/COpenSSL/ecp_nistputil.c new file mode 100644 index 00000000..41ea2858 --- /dev/null +++ b/Sources/COpenSSL/ecp_nistputil.c @@ -0,0 +1,218 @@ +/* crypto/ec/ecp_nistputil.c */ +/* + * Written by Bodo Moeller for the OpenSSL project. + */ +/* Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "opensslconf.h" +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + +/* + * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c. + */ + +# include +# include "ec_lcl.h" + +/* + * Convert an array of points into affine coordinates. (If the point at + * infinity is found (Z = 0), it remains unchanged.) This function is + * essentially an equivalent to EC_POINTs_make_affine(), but works with the + * internal representation of points as used by ecp_nistp###.c rather than + * with (BIGNUM-based) EC_POINT data structures. point_array is the + * input/output buffer ('num' points in projective form, i.e. three + * coordinates each), based on an internal representation of field elements + * of size 'felem_size'. tmp_felems needs to point to a temporary array of + * 'num'+1 field elements for storage of intermediate values. + */ +void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, + size_t felem_size, + void *tmp_felems, + void (*felem_one) (void *out), + int (*felem_is_zero) (const void + *in), + void (*felem_assign) (void *out, + const void + *in), + void (*felem_square) (void *out, + const void + *in), + void (*felem_mul) (void *out, + const void + *in1, + const void + *in2), + void (*felem_inv) (void *out, + const void + *in), + void (*felem_contract) (void + *out, + const + void + *in)) +{ + int i = 0; + +# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size]) +# define X(I) (&((char *)point_array)[3*(I) * felem_size]) +# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size]) +# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size]) + + if (!felem_is_zero(Z(0))) + felem_assign(tmp_felem(0), Z(0)); + else + felem_one(tmp_felem(0)); + for (i = 1; i < (int)num; i++) { + if (!felem_is_zero(Z(i))) + felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i)); + else + felem_assign(tmp_felem(i), tmp_felem(i - 1)); + } + /* + * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any + * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1 + */ + + felem_inv(tmp_felem(num - 1), tmp_felem(num - 1)); + for (i = num - 1; i >= 0; i--) { + if (i > 0) + /* + * tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i) + * is the inverse of the product of Z(0) .. Z(i) + */ + /* 1/Z(i) */ + felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i)); + else + felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */ + + if (!felem_is_zero(Z(i))) { + if (i > 0) + /* + * For next iteration, replace tmp_felem(i-1) by its inverse + */ + felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i)); + + /* + * Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) + */ + felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */ + felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */ + felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */ + felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */ + felem_contract(X(i), X(i)); + felem_contract(Y(i), Y(i)); + felem_one(Z(i)); + } else { + if (i > 0) + /* + * For next iteration, replace tmp_felem(i-1) by its inverse + */ + felem_assign(tmp_felem(i - 1), tmp_felem(i)); + } + } +} + +/*- + * This function looks at 5+1 scalar bits (5 current, 1 adjacent less + * significant bit), and recodes them into a signed digit for use in fast point + * multiplication: the use of signed rather than unsigned digits means that + * fewer points need to be precomputed, given that point inversion is easy + * (a precomputed point dP makes -dP available as well). + * + * BACKGROUND: + * + * Signed digits for multiplication were introduced by Booth ("A signed binary + * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV, + * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers. + * Booth's original encoding did not generally improve the density of nonzero + * digits over the binary representation, and was merely meant to simplify the + * handling of signed factors given in two's complement; but it has since been + * shown to be the basis of various signed-digit representations that do have + * further advantages, including the wNAF, using the following general approach: + * + * (1) Given a binary representation + * + * b_k ... b_2 b_1 b_0, + * + * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1 + * by using bit-wise subtraction as follows: + * + * b_k b_(k-1) ... b_2 b_1 b_0 + * - b_k ... b_3 b_2 b_1 b_0 + * ------------------------------------- + * s_k b_(k-1) ... s_3 s_2 s_1 s_0 + * + * A left-shift followed by subtraction of the original value yields a new + * representation of the same value, using signed bits s_i = b_(i+1) - b_i. + * This representation from Booth's paper has since appeared in the + * literature under a variety of different names including "reversed binary + * form", "alternating greedy expansion", "mutual opposite form", and + * "sign-alternating {+-1}-representation". + * + * An interesting property is that among the nonzero bits, values 1 and -1 + * strictly alternate. + * + * (2) Various window schemes can be applied to the Booth representation of + * integers: for example, right-to-left sliding windows yield the wNAF + * (a signed-digit encoding independently discovered by various researchers + * in the 1990s), and left-to-right sliding windows yield a left-to-right + * equivalent of the wNAF (independently discovered by various researchers + * around 2004). + * + * To prevent leaking information through side channels in point multiplication, + * we need to recode the given integer into a regular pattern: sliding windows + * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few + * decades older: we'll be using the so-called "modified Booth encoding" due to + * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49 + * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five + * signed bits into a signed digit: + * + * s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j) + * + * The sign-alternating property implies that the resulting digit values are + * integers from -16 to 16. + * + * Of course, we don't actually need to compute the signed digits s_i as an + * intermediate step (that's just a nice way to see how this scheme relates + * to the wNAF): a direct computation obtains the recoded digit from the + * six bits b_(4j + 4) ... b_(4j - 1). + * + * This function takes those five bits as an integer (0 .. 63), writing the + * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute + * value, in the range 0 .. 8). Note that this integer essentially provides the + * input bits "shifted to the left" by one position: for example, the input to + * compute the least significant recoded digit, given that there's no bit b_-1, + * has to be b_4 b_3 b_2 b_1 b_0 0. + * + */ +void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, + unsigned char *digit, unsigned char in) +{ + unsigned char s, d; + + s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as + * 6-bit value */ + d = (1 << 6) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + *sign = s & 1; + *digit = d; +} +#else +static void *dummy = &dummy; +#endif diff --git a/Sources/COpenSSL/ecp_oct.c b/Sources/COpenSSL/ecp_oct.c new file mode 100644 index 00000000..f08d0d45 --- /dev/null +++ b/Sources/COpenSSL/ecp_oct.c @@ -0,0 +1,428 @@ +/* crypto/ec/ecp_oct.c */ +/* + * Includes code written by Lenka Fibikova + * for the OpenSSL project. Includes code written by Bodo Moeller for the + * OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include "err.h" +#include "symhacks.h" + +#include "ec_lcl.h" + +int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x_, int y_bit, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *tmp1, *tmp2, *x, *y; + int ret = 0; + + /* clear error queue */ + ERR_clear_error(); + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + y_bit = (y_bit != 0); + + BN_CTX_start(ctx); + tmp1 = BN_CTX_get(ctx); + tmp2 = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + /*- + * Recover y. We have a Weierstrass equation + * y^2 = x^3 + a*x + b, + * so y is one of the square roots of x^3 + a*x + b. + */ + + /* tmp1 := x^3 */ + if (!BN_nnmod(x, x_, &group->field, ctx)) + goto err; + if (group->meth->field_decode == 0) { + /* field_{sqr,mul} work on standard representation */ + if (!group->meth->field_sqr(group, tmp2, x_, ctx)) + goto err; + if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) + goto err; + } else { + if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) + goto err; + if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) + goto err; + } + + /* tmp1 := tmp1 + a*x */ + if (group->a_is_minus3) { + if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) + goto err; + if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) + goto err; + if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } else { + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) + goto err; + if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) + goto err; + } else { + /* field_mul works on standard representation */ + if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) + goto err; + } + + if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } + + /* tmp1 := tmp1 + b */ + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) + goto err; + if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } else { + if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) + goto err; + } + + if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { + unsigned long err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_BN + && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { + ERR_clear_error(); + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + EC_R_INVALID_COMPRESSED_POINT); + } else + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + ERR_R_BN_LIB); + goto err; + } + + if (y_bit != BN_is_odd(y)) { + if (BN_is_zero(y)) { + int kron; + + kron = BN_kronecker(x, &group->field, ctx); + if (kron == -2) + goto err; + + if (kron == 1) + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + EC_R_INVALID_COMPRESSION_BIT); + else + /* + * BN_mod_sqrt() should have cought this error (not a square) + */ + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + EC_R_INVALID_COMPRESSED_POINT); + goto err; + } + if (!BN_usub(y, &group->field, y)) + goto err; + } + if (y_bit != BN_is_odd(y)) { + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx) +{ + size_t ret; + BN_CTX *new_ctx = NULL; + int used_ctx = 0; + BIGNUM *x, *y; + size_t field_len, i, skip; + + if ((form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); + goto err; + } + + if (EC_POINT_is_at_infinity(group, point)) { + /* encodes to a single 0 octet */ + if (buf != NULL) { + if (len < 1) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + return 0; + } + buf[0] = 0; + } + return 1; + } + + /* ret := required output buffer length */ + field_len = BN_num_bytes(&group->field); + ret = + (form == + POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + /* if 'buf' is NULL, just return required length */ + if (buf != NULL) { + if (len < ret) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + used_ctx = 1; + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + + if ((form == POINT_CONVERSION_COMPRESSED + || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) + buf[0] = form + 1; + else + buf[0] = form; + + i = 1; + + skip = field_len - BN_num_bytes(x); + if (skip > field_len) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(x, buf + i); + i += skip; + if (i != 1 + field_len) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (form == POINT_CONVERSION_UNCOMPRESSED + || form == POINT_CONVERSION_HYBRID) { + skip = field_len - BN_num_bytes(y); + if (skip > field_len) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(y, buf + i); + i += skip; + } + + if (i != ret) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (used_ctx) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; + + err: + if (used_ctx) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return 0; +} + +int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, BN_CTX *ctx) +{ + point_conversion_form_t form; + int y_bit; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + size_t field_len, enc_len; + int ret = 0; + + if (len == 0) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); + return 0; + } + form = buf[0]; + y_bit = form & 1; + form = form & ~1U; + if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + if (form == 0) { + if (len != 1) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + return EC_POINT_set_to_infinity(group, point); + } + + field_len = BN_num_bytes(&group->field); + enc_len = + (form == + POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + if (len != enc_len) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!BN_bin2bn(buf + 1, field_len, x)) + goto err; + if (BN_ucmp(x, &group->field) >= 0) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + + if (form == POINT_CONVERSION_COMPRESSED) { + if (!EC_POINT_set_compressed_coordinates_GFp + (group, point, x, y_bit, ctx)) + goto err; + } else { + if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) + goto err; + if (BN_ucmp(y, &group->field) >= 0) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + if (form == POINT_CONVERSION_HYBRID) { + if (y_bit != BN_is_odd(y)) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + } + + /* test required by X9.62 */ + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} diff --git a/Sources/COpenSSL/ecp_smpl.c b/Sources/COpenSSL/ecp_smpl.c new file mode 100644 index 00000000..2b9a7054 --- /dev/null +++ b/Sources/COpenSSL/ecp_smpl.c @@ -0,0 +1,1418 @@ +/* crypto/ec/ecp_smpl.c */ +/* + * Includes code written by Lenka Fibikova + * for the OpenSSL project. Includes code written by Bodo Moeller for the + * OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include "err.h" +#include "symhacks.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +#include "ec_lcl.h" + +const EC_METHOD *EC_GFp_simple_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_simple_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_simple_group_copy, + ec_GFp_simple_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_simple_point_get_affine_coordinates, + 0, 0, 0, + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + 0 /* mul */ , + 0 /* precompute_mult */ , + 0 /* have_precompute_mult */ , + ec_GFp_simple_field_mul, + ec_GFp_simple_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return fips_ec_gfp_simple_method(); +#endif + + return &ret; +} + +/* + * Most method functions in this file are designed to work with + * non-trivial representations of field elements if necessary + * (see ecp_mont.c): while standard modular addition and subtraction + * are used, the field_mul and field_sqr methods will be used for + * multiplication, and field_encode and field_decode (if defined) + * will be used for converting between representations. + * + * Functions ec_GFp_simple_points_make_affine() and + * ec_GFp_simple_point_get_affine_coordinates() specifically assume + * that if a non-trivial representation is used, it is a Montgomery + * representation (i.e. 'encoding' means multiplying by some factor R). + */ + +int ec_GFp_simple_group_init(EC_GROUP *group) +{ + BN_init(&group->field); + BN_init(&group->a); + BN_init(&group->b); + group->a_is_minus3 = 0; + return 1; +} + +void ec_GFp_simple_group_finish(EC_GROUP *group) +{ + BN_free(&group->field); + BN_free(&group->a); + BN_free(&group->b); +} + +void ec_GFp_simple_group_clear_finish(EC_GROUP *group) +{ + BN_clear_free(&group->field); + BN_clear_free(&group->a); + BN_clear_free(&group->b); +} + +int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + if (!BN_copy(&dest->field, &src->field)) + return 0; + if (!BN_copy(&dest->a, &src->a)) + return 0; + if (!BN_copy(&dest->b, &src->b)) + return 0; + + dest->a_is_minus3 = src->a_is_minus3; + + return 1; +} + +int ec_GFp_simple_group_set_curve(EC_GROUP *group, + const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *tmp_a; + + /* p must be a prime > 3 */ + if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { + ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD); + return 0; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + tmp_a = BN_CTX_get(ctx); + if (tmp_a == NULL) + goto err; + + /* group->field */ + if (!BN_copy(&group->field, p)) + goto err; + BN_set_negative(&group->field, 0); + + /* group->a */ + if (!BN_nnmod(tmp_a, a, p, ctx)) + goto err; + if (group->meth->field_encode) { + if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) + goto err; + } else if (!BN_copy(&group->a, tmp_a)) + goto err; + + /* group->b */ + if (!BN_nnmod(&group->b, b, p, ctx)) + goto err; + if (group->meth->field_encode) + if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) + goto err; + + /* group->a_is_minus3 */ + if (!BN_add_word(tmp_a, 3)) + goto err; + group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field)); + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + + if (p != NULL) { + if (!BN_copy(p, &group->field)) + return 0; + } + + if (a != NULL || b != NULL) { + if (group->meth->field_decode) { + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + if (a != NULL) { + if (!group->meth->field_decode(group, a, &group->a, ctx)) + goto err; + } + if (b != NULL) { + if (!group->meth->field_decode(group, b, &group->b, ctx)) + goto err; + } + } else { + if (a != NULL) { + if (!BN_copy(a, &group->a)) + goto err; + } + if (b != NULL) { + if (!BN_copy(b, &group->b)) + goto err; + } + } + } + + ret = 1; + + err: + if (new_ctx) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_group_get_degree(const EC_GROUP *group) +{ + return BN_num_bits(&group->field); +} + +int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *a, *b, *order, *tmp_1, *tmp_2; + const BIGNUM *p = &group->field; + BN_CTX *new_ctx = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, + ERR_R_MALLOC_FAILURE); + goto err; + } + } + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + tmp_1 = BN_CTX_get(ctx); + tmp_2 = BN_CTX_get(ctx); + order = BN_CTX_get(ctx); + if (order == NULL) + goto err; + + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, a, &group->a, ctx)) + goto err; + if (!group->meth->field_decode(group, b, &group->b, ctx)) + goto err; + } else { + if (!BN_copy(a, &group->a)) + goto err; + if (!BN_copy(b, &group->b)) + goto err; + } + + /*- + * check the discriminant: + * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p) + * 0 =< a, b < p + */ + if (BN_is_zero(a)) { + if (BN_is_zero(b)) + goto err; + } else if (!BN_is_zero(b)) { + if (!BN_mod_sqr(tmp_1, a, p, ctx)) + goto err; + if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) + goto err; + if (!BN_lshift(tmp_1, tmp_2, 2)) + goto err; + /* tmp_1 = 4*a^3 */ + + if (!BN_mod_sqr(tmp_2, b, p, ctx)) + goto err; + if (!BN_mul_word(tmp_2, 27)) + goto err; + /* tmp_2 = 27*b^2 */ + + if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) + goto err; + if (BN_is_zero(a)) + goto err; + } + ret = 1; + + err: + if (ctx != NULL) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_point_init(EC_POINT *point) +{ + BN_init(&point->X); + BN_init(&point->Y); + BN_init(&point->Z); + point->Z_is_one = 0; + + return 1; +} + +void ec_GFp_simple_point_finish(EC_POINT *point) +{ + BN_free(&point->X); + BN_free(&point->Y); + BN_free(&point->Z); +} + +void ec_GFp_simple_point_clear_finish(EC_POINT *point) +{ + BN_clear_free(&point->X); + BN_clear_free(&point->Y); + BN_clear_free(&point->Z); + point->Z_is_one = 0; +} + +int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) +{ + if (!BN_copy(&dest->X, &src->X)) + return 0; + if (!BN_copy(&dest->Y, &src->Y)) + return 0; + if (!BN_copy(&dest->Z, &src->Z)) + return 0; + dest->Z_is_one = src->Z_is_one; + + return 1; +} + +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, + EC_POINT *point) +{ + point->Z_is_one = 0; + BN_zero(&point->Z); + return 1; +} + +int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, + const BIGNUM *z, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + if (x != NULL) { + if (!BN_nnmod(&point->X, x, &group->field, ctx)) + goto err; + if (group->meth->field_encode) { + if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) + goto err; + } + } + + if (y != NULL) { + if (!BN_nnmod(&point->Y, y, &group->field, ctx)) + goto err; + if (group->meth->field_encode) { + if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) + goto err; + } + } + + if (z != NULL) { + int Z_is_one; + + if (!BN_nnmod(&point->Z, z, &group->field, ctx)) + goto err; + Z_is_one = BN_is_one(&point->Z); + if (group->meth->field_encode) { + if (Z_is_one && (group->meth->field_set_to_one != 0)) { + if (!group->meth->field_set_to_one(group, &point->Z, ctx)) + goto err; + } else { + if (!group-> + meth->field_encode(group, &point->Z, &point->Z, ctx)) + goto err; + } + } + point->Z_is_one = Z_is_one; + } + + ret = 1; + + err: + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BIGNUM *z, BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (group->meth->field_decode != 0) { + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + if (x != NULL) { + if (!group->meth->field_decode(group, x, &point->X, ctx)) + goto err; + } + if (y != NULL) { + if (!group->meth->field_decode(group, y, &point->Y, ctx)) + goto err; + } + if (z != NULL) { + if (!group->meth->field_decode(group, z, &point->Z, ctx)) + goto err; + } + } else { + if (x != NULL) { + if (!BN_copy(x, &point->X)) + goto err; + } + if (y != NULL) { + if (!BN_copy(y, &point->Y)) + goto err; + } + if (z != NULL) { + if (!BN_copy(z, &point->Z)) + goto err; + } + } + + ret = 1; + + err: + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + if (x == NULL || y == NULL) { + /* + * unlike for projective coordinates, we do not tolerate this + */ + ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, + BN_value_one(), ctx); +} + +int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *Z, *Z_1, *Z_2, *Z_3; + const BIGNUM *Z_; + int ret = 0; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + Z = BN_CTX_get(ctx); + Z_1 = BN_CTX_get(ctx); + Z_2 = BN_CTX_get(ctx); + Z_3 = BN_CTX_get(ctx); + if (Z_3 == NULL) + goto err; + + /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */ + + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, Z, &point->Z, ctx)) + goto err; + Z_ = Z; + } else { + Z_ = &point->Z; + } + + if (BN_is_one(Z_)) { + if (group->meth->field_decode) { + if (x != NULL) { + if (!group->meth->field_decode(group, x, &point->X, ctx)) + goto err; + } + if (y != NULL) { + if (!group->meth->field_decode(group, y, &point->Y, ctx)) + goto err; + } + } else { + if (x != NULL) { + if (!BN_copy(x, &point->X)) + goto err; + } + if (y != NULL) { + if (!BN_copy(y, &point->Y)) + goto err; + } + } + } else { + if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + goto err; + } + + if (group->meth->field_encode == 0) { + /* field_sqr works on standard representation */ + if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) + goto err; + } else { + if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) + goto err; + } + + if (x != NULL) { + /* + * in the Montgomery case, field_mul will cancel out Montgomery + * factor in X: + */ + if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) + goto err; + } + + if (y != NULL) { + if (group->meth->field_encode == 0) { + /* + * field_mul works on standard representation + */ + if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) + goto err; + } else { + if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) + goto err; + } + + /* + * in the Montgomery case, field_mul will cancel out Montgomery + * factor in Y: + */ + if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) + goto err; + } + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + const BIGNUM *p; + BN_CTX *new_ctx = NULL; + BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; + int ret = 0; + + if (a == b) + return EC_POINT_dbl(group, r, a, ctx); + if (EC_POINT_is_at_infinity(group, a)) + return EC_POINT_copy(r, b); + if (EC_POINT_is_at_infinity(group, b)) + return EC_POINT_copy(r, a); + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + n0 = BN_CTX_get(ctx); + n1 = BN_CTX_get(ctx); + n2 = BN_CTX_get(ctx); + n3 = BN_CTX_get(ctx); + n4 = BN_CTX_get(ctx); + n5 = BN_CTX_get(ctx); + n6 = BN_CTX_get(ctx); + if (n6 == NULL) + goto end; + + /* + * Note that in this function we must not read components of 'a' or 'b' + * once we have written the corresponding components of 'r'. ('r' might + * be one of 'a' or 'b'.) + */ + + /* n1, n2 */ + if (b->Z_is_one) { + if (!BN_copy(n1, &a->X)) + goto end; + if (!BN_copy(n2, &a->Y)) + goto end; + /* n1 = X_a */ + /* n2 = Y_a */ + } else { + if (!field_sqr(group, n0, &b->Z, ctx)) + goto end; + if (!field_mul(group, n1, &a->X, n0, ctx)) + goto end; + /* n1 = X_a * Z_b^2 */ + + if (!field_mul(group, n0, n0, &b->Z, ctx)) + goto end; + if (!field_mul(group, n2, &a->Y, n0, ctx)) + goto end; + /* n2 = Y_a * Z_b^3 */ + } + + /* n3, n4 */ + if (a->Z_is_one) { + if (!BN_copy(n3, &b->X)) + goto end; + if (!BN_copy(n4, &b->Y)) + goto end; + /* n3 = X_b */ + /* n4 = Y_b */ + } else { + if (!field_sqr(group, n0, &a->Z, ctx)) + goto end; + if (!field_mul(group, n3, &b->X, n0, ctx)) + goto end; + /* n3 = X_b * Z_a^2 */ + + if (!field_mul(group, n0, n0, &a->Z, ctx)) + goto end; + if (!field_mul(group, n4, &b->Y, n0, ctx)) + goto end; + /* n4 = Y_b * Z_a^3 */ + } + + /* n5, n6 */ + if (!BN_mod_sub_quick(n5, n1, n3, p)) + goto end; + if (!BN_mod_sub_quick(n6, n2, n4, p)) + goto end; + /* n5 = n1 - n3 */ + /* n6 = n2 - n4 */ + + if (BN_is_zero(n5)) { + if (BN_is_zero(n6)) { + /* a is the same point as b */ + BN_CTX_end(ctx); + ret = EC_POINT_dbl(group, r, a, ctx); + ctx = NULL; + goto end; + } else { + /* a is the inverse of b */ + BN_zero(&r->Z); + r->Z_is_one = 0; + ret = 1; + goto end; + } + } + + /* 'n7', 'n8' */ + if (!BN_mod_add_quick(n1, n1, n3, p)) + goto end; + if (!BN_mod_add_quick(n2, n2, n4, p)) + goto end; + /* 'n7' = n1 + n3 */ + /* 'n8' = n2 + n4 */ + + /* Z_r */ + if (a->Z_is_one && b->Z_is_one) { + if (!BN_copy(&r->Z, n5)) + goto end; + } else { + if (a->Z_is_one) { + if (!BN_copy(n0, &b->Z)) + goto end; + } else if (b->Z_is_one) { + if (!BN_copy(n0, &a->Z)) + goto end; + } else { + if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) + goto end; + } + if (!field_mul(group, &r->Z, n0, n5, ctx)) + goto end; + } + r->Z_is_one = 0; + /* Z_r = Z_a * Z_b * n5 */ + + /* X_r */ + if (!field_sqr(group, n0, n6, ctx)) + goto end; + if (!field_sqr(group, n4, n5, ctx)) + goto end; + if (!field_mul(group, n3, n1, n4, ctx)) + goto end; + if (!BN_mod_sub_quick(&r->X, n0, n3, p)) + goto end; + /* X_r = n6^2 - n5^2 * 'n7' */ + + /* 'n9' */ + if (!BN_mod_lshift1_quick(n0, &r->X, p)) + goto end; + if (!BN_mod_sub_quick(n0, n3, n0, p)) + goto end; + /* n9 = n5^2 * 'n7' - 2 * X_r */ + + /* Y_r */ + if (!field_mul(group, n0, n0, n6, ctx)) + goto end; + if (!field_mul(group, n5, n4, n5, ctx)) + goto end; /* now n5 is n5^3 */ + if (!field_mul(group, n1, n2, n5, ctx)) + goto end; + if (!BN_mod_sub_quick(n0, n0, n1, p)) + goto end; + if (BN_is_odd(n0)) + if (!BN_add(n0, n0, p)) + goto end; + /* now 0 <= n0 < 2*p, and n0 is even */ + if (!BN_rshift1(&r->Y, n0)) + goto end; + /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ + + ret = 1; + + end: + if (ctx) /* otherwise we already called BN_CTX_end */ + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + const BIGNUM *p; + BN_CTX *new_ctx = NULL; + BIGNUM *n0, *n1, *n2, *n3; + int ret = 0; + + if (EC_POINT_is_at_infinity(group, a)) { + BN_zero(&r->Z); + r->Z_is_one = 0; + return 1; + } + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + n0 = BN_CTX_get(ctx); + n1 = BN_CTX_get(ctx); + n2 = BN_CTX_get(ctx); + n3 = BN_CTX_get(ctx); + if (n3 == NULL) + goto err; + + /* + * Note that in this function we must not read components of 'a' once we + * have written the corresponding components of 'r'. ('r' might the same + * as 'a'.) + */ + + /* n1 */ + if (a->Z_is_one) { + if (!field_sqr(group, n0, &a->X, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n1, n0, p)) + goto err; + if (!BN_mod_add_quick(n0, n0, n1, p)) + goto err; + if (!BN_mod_add_quick(n1, n0, &group->a, p)) + goto err; + /* n1 = 3 * X_a^2 + a_curve */ + } else if (group->a_is_minus3) { + if (!field_sqr(group, n1, &a->Z, ctx)) + goto err; + if (!BN_mod_add_quick(n0, &a->X, n1, p)) + goto err; + if (!BN_mod_sub_quick(n2, &a->X, n1, p)) + goto err; + if (!field_mul(group, n1, n0, n2, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n0, n1, p)) + goto err; + if (!BN_mod_add_quick(n1, n0, n1, p)) + goto err; + /*- + * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) + * = 3 * X_a^2 - 3 * Z_a^4 + */ + } else { + if (!field_sqr(group, n0, &a->X, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n1, n0, p)) + goto err; + if (!BN_mod_add_quick(n0, n0, n1, p)) + goto err; + if (!field_sqr(group, n1, &a->Z, ctx)) + goto err; + if (!field_sqr(group, n1, n1, ctx)) + goto err; + if (!field_mul(group, n1, n1, &group->a, ctx)) + goto err; + if (!BN_mod_add_quick(n1, n1, n0, p)) + goto err; + /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */ + } + + /* Z_r */ + if (a->Z_is_one) { + if (!BN_copy(n0, &a->Y)) + goto err; + } else { + if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) + goto err; + } + if (!BN_mod_lshift1_quick(&r->Z, n0, p)) + goto err; + r->Z_is_one = 0; + /* Z_r = 2 * Y_a * Z_a */ + + /* n2 */ + if (!field_sqr(group, n3, &a->Y, ctx)) + goto err; + if (!field_mul(group, n2, &a->X, n3, ctx)) + goto err; + if (!BN_mod_lshift_quick(n2, n2, 2, p)) + goto err; + /* n2 = 4 * X_a * Y_a^2 */ + + /* X_r */ + if (!BN_mod_lshift1_quick(n0, n2, p)) + goto err; + if (!field_sqr(group, &r->X, n1, ctx)) + goto err; + if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) + goto err; + /* X_r = n1^2 - 2 * n2 */ + + /* n3 */ + if (!field_sqr(group, n0, n3, ctx)) + goto err; + if (!BN_mod_lshift_quick(n3, n0, 3, p)) + goto err; + /* n3 = 8 * Y_a^4 */ + + /* Y_r */ + if (!BN_mod_sub_quick(n0, n2, &r->X, p)) + goto err; + if (!field_mul(group, n0, n1, n0, ctx)) + goto err; + if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) + goto err; + /* Y_r = n1 * (n2 - X_r) - n3 */ + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +{ + if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) + /* point is its own inverse */ + return 1; + + return BN_usub(&point->Y, &group->field, &point->Y); +} + +int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) +{ + return BN_is_zero(&point->Z); +} + +int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + const BIGNUM *p; + BN_CTX *new_ctx = NULL; + BIGNUM *rh, *tmp, *Z4, *Z6; + int ret = -1; + + if (EC_POINT_is_at_infinity(group, point)) + return 1; + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return -1; + } + + BN_CTX_start(ctx); + rh = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + Z4 = BN_CTX_get(ctx); + Z6 = BN_CTX_get(ctx); + if (Z6 == NULL) + goto err; + + /*- + * We have a curve defined by a Weierstrass equation + * y^2 = x^3 + a*x + b. + * The point to consider is given in Jacobian projective coordinates + * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). + * Substituting this and multiplying by Z^6 transforms the above equation into + * Y^2 = X^3 + a*X*Z^4 + b*Z^6. + * To test this, we add up the right-hand side in 'rh'. + */ + + /* rh := X^2 */ + if (!field_sqr(group, rh, &point->X, ctx)) + goto err; + + if (!point->Z_is_one) { + if (!field_sqr(group, tmp, &point->Z, ctx)) + goto err; + if (!field_sqr(group, Z4, tmp, ctx)) + goto err; + if (!field_mul(group, Z6, Z4, tmp, ctx)) + goto err; + + /* rh := (rh + a*Z^4)*X */ + if (group->a_is_minus3) { + if (!BN_mod_lshift1_quick(tmp, Z4, p)) + goto err; + if (!BN_mod_add_quick(tmp, tmp, Z4, p)) + goto err; + if (!BN_mod_sub_quick(rh, rh, tmp, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + } else { + if (!field_mul(group, tmp, Z4, &group->a, ctx)) + goto err; + if (!BN_mod_add_quick(rh, rh, tmp, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + } + + /* rh := rh + b*Z^6 */ + if (!field_mul(group, tmp, &group->b, Z6, ctx)) + goto err; + if (!BN_mod_add_quick(rh, rh, tmp, p)) + goto err; + } else { + /* point->Z_is_one */ + + /* rh := (rh + a)*X */ + if (!BN_mod_add_quick(rh, rh, &group->a, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + /* rh := rh + b */ + if (!BN_mod_add_quick(rh, rh, &group->b, p)) + goto err; + } + + /* 'lh' := Y^2 */ + if (!field_sqr(group, tmp, &point->Y, ctx)) + goto err; + + ret = (0 == BN_ucmp(tmp, rh)); + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + /*- + * return values: + * -1 error + * 0 equal (in affine coordinates) + * 1 not equal + */ + + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + BN_CTX *new_ctx = NULL; + BIGNUM *tmp1, *tmp2, *Za23, *Zb23; + const BIGNUM *tmp1_, *tmp2_; + int ret = -1; + + if (EC_POINT_is_at_infinity(group, a)) { + return EC_POINT_is_at_infinity(group, b) ? 0 : 1; + } + + if (EC_POINT_is_at_infinity(group, b)) + return 1; + + if (a->Z_is_one && b->Z_is_one) { + return ((BN_cmp(&a->X, &b->X) == 0) + && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; + } + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return -1; + } + + BN_CTX_start(ctx); + tmp1 = BN_CTX_get(ctx); + tmp2 = BN_CTX_get(ctx); + Za23 = BN_CTX_get(ctx); + Zb23 = BN_CTX_get(ctx); + if (Zb23 == NULL) + goto end; + + /*- + * We have to decide whether + * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), + * or equivalently, whether + * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). + */ + + if (!b->Z_is_one) { + if (!field_sqr(group, Zb23, &b->Z, ctx)) + goto end; + if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) + goto end; + tmp1_ = tmp1; + } else + tmp1_ = &a->X; + if (!a->Z_is_one) { + if (!field_sqr(group, Za23, &a->Z, ctx)) + goto end; + if (!field_mul(group, tmp2, &b->X, Za23, ctx)) + goto end; + tmp2_ = tmp2; + } else + tmp2_ = &b->X; + + /* compare X_a*Z_b^2 with X_b*Z_a^2 */ + if (BN_cmp(tmp1_, tmp2_) != 0) { + ret = 1; /* points differ */ + goto end; + } + + if (!b->Z_is_one) { + if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) + goto end; + if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) + goto end; + /* tmp1_ = tmp1 */ + } else + tmp1_ = &a->Y; + if (!a->Z_is_one) { + if (!field_mul(group, Za23, Za23, &a->Z, ctx)) + goto end; + if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) + goto end; + /* tmp2_ = tmp2 */ + } else + tmp2_ = &b->Y; + + /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ + if (BN_cmp(tmp1_, tmp2_) != 0) { + ret = 1; /* points differ */ + goto end; + } + + /* points are equal */ + ret = 0; + + end: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + int ret = 0; + + if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) + return 1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + if (!point->Z_is_one) { + ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *tmp, *tmp_Z; + BIGNUM **prod_Z = NULL; + size_t i; + int ret = 0; + + if (num == 0) + return 1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + tmp_Z = BN_CTX_get(ctx); + if (tmp == NULL || tmp_Z == NULL) + goto err; + + prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0])); + if (prod_Z == NULL) + goto err; + for (i = 0; i < num; i++) { + prod_Z[i] = BN_new(); + if (prod_Z[i] == NULL) + goto err; + } + + /* + * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z, + * skipping any zero-valued inputs (pretend that they're 1). + */ + + if (!BN_is_zero(&points[0]->Z)) { + if (!BN_copy(prod_Z[0], &points[0]->Z)) + goto err; + } else { + if (group->meth->field_set_to_one != 0) { + if (!group->meth->field_set_to_one(group, prod_Z[0], ctx)) + goto err; + } else { + if (!BN_one(prod_Z[0])) + goto err; + } + } + + for (i = 1; i < num; i++) { + if (!BN_is_zero(&points[i]->Z)) { + if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1], + &points[i]->Z, ctx)) + goto err; + } else { + if (!BN_copy(prod_Z[i], prod_Z[i - 1])) + goto err; + } + } + + /* + * Now use a single explicit inversion to replace every non-zero + * points[i]->Z by its inverse. + */ + + if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) { + ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); + goto err; + } + if (group->meth->field_encode != 0) { + /* + * In the Montgomery case, we just turned R*H (representing H) into + * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to + * multiply by the Montgomery factor twice. + */ + if (!group->meth->field_encode(group, tmp, tmp, ctx)) + goto err; + if (!group->meth->field_encode(group, tmp, tmp, ctx)) + goto err; + } + + for (i = num - 1; i > 0; --i) { + /* + * Loop invariant: tmp is the product of the inverses of points[0]->Z + * .. points[i]->Z (zero-valued inputs skipped). + */ + if (!BN_is_zero(&points[i]->Z)) { + /* + * Set tmp_Z to the inverse of points[i]->Z (as product of Z + * inverses 0 .. i, Z values 0 .. i - 1). + */ + if (!group-> + meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx)) + goto err; + /* + * Update tmp to satisfy the loop invariant for i - 1. + */ + if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx)) + goto err; + /* Replace points[i]->Z by its inverse. */ + if (!BN_copy(&points[i]->Z, tmp_Z)) + goto err; + } + } + + if (!BN_is_zero(&points[0]->Z)) { + /* Replace points[0]->Z by its inverse. */ + if (!BN_copy(&points[0]->Z, tmp)) + goto err; + } + + /* Finally, fix up the X and Y coordinates for all points. */ + + for (i = 0; i < num; i++) { + EC_POINT *p = points[i]; + + if (!BN_is_zero(&p->Z)) { + /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ + + if (!group->meth->field_sqr(group, tmp, &p->Z, ctx)) + goto err; + if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx)) + goto err; + + if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx)) + goto err; + if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) + goto err; + + if (group->meth->field_set_to_one != 0) { + if (!group->meth->field_set_to_one(group, &p->Z, ctx)) + goto err; + } else { + if (!BN_one(&p->Z)) + goto err; + } + p->Z_is_one = 1; + } + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (prod_Z != NULL) { + for (i = 0; i < num; i++) { + if (prod_Z[i] == NULL) + break; + BN_clear_free(prod_Z[i]); + } + OPENSSL_free(prod_Z); + } + return ret; +} + +int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + return BN_mod_mul(r, a, b, &group->field, ctx); +} + +int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + return BN_mod_sqr(r, a, &group->field, ctx); +} diff --git a/Sources/COpenSSL/ecs_.c b/Sources/COpenSSL/ecs_.c new file mode 100644 index 00000000..5ea16937 --- /dev/null +++ b/Sources/COpenSSL/ecs_.c @@ -0,0 +1,1245 @@ +/* crypto/ecdsa/ecs_asn1.c */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#include "err.h" +#include "asn1t.h" + +ASN1_SEQUENCE(ECDSA_SIG) = { + ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), + ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) +} ASN1_SEQUENCE_END(ECDSA_SIG) + +DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG) +IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG) +/* crypto/ecdsa/ecs_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +// #include "err.h" +#include "ecdsa.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason) + +static ERR_STRING_DATA ECDSA_str_functs[] = { + {ERR_FUNC(ECDSA_F_ECDSA_CHECK), "ECDSA_CHECK"}, + {ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"}, + {ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"}, + {ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"}, + {ERR_FUNC(ECDSA_F_ECDSA_METHOD_NEW), "ECDSA_METHOD_new"}, + {ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"}, + {0, NULL} +}; + +static ERR_STRING_DATA ECDSA_str_reasons[] = { + {ERR_REASON(ECDSA_R_BAD_SIGNATURE), "bad signature"}, + {ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), + "data too large for key size"}, + {ERR_REASON(ECDSA_R_ERR_EC_LIB), "err ec lib"}, + {ERR_REASON(ECDSA_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, + {ERR_REASON(ECDSA_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED), + "random number generation failed"}, + {ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED), "signature malloc failed"}, + {0, NULL} +}; + +#endif + +void ERR_load_ECDSA_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL) { + ERR_load_strings(0, ECDSA_str_functs); + ERR_load_strings(0, ECDSA_str_reasons); + } +#endif +} +/* crypto/ecdsa/ecs_lib.c */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "ecs_locl.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +// #include "err.h" +#include "bn.h" +#ifdef OPENSSL_FIPS +# include +#endif + +const char ECDSA_version[] = "ECDSA" OPENSSL_VERSION_PTEXT; + +static const ECDSA_METHOD *default_ECDSA_method = NULL; + +static void *ecdsa_data_new(void); +static void *ecdsa_data_dup(void *); +static void ecdsa_data_free(void *); + +void ECDSA_set_default_method(const ECDSA_METHOD *meth) +{ + default_ECDSA_method = meth; +} + +const ECDSA_METHOD *ECDSA_get_default_method(void) +{ + if (!default_ECDSA_method) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ecdsa_openssl(); + else + return ECDSA_OpenSSL(); +#else + default_ECDSA_method = ECDSA_OpenSSL(); +#endif + } + return default_ECDSA_method; +} + +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth) +{ + ECDSA_DATA *ecdsa; + + ecdsa = ecdsa_check(eckey); + + if (ecdsa == NULL) + return 0; + +#ifndef OPENSSL_NO_ENGINE + if (ecdsa->engine) { + ENGINE_finish(ecdsa->engine); + ecdsa->engine = NULL; + } +#endif + ecdsa->meth = meth; + + return 1; +} + +static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine) +{ + ECDSA_DATA *ret; + + ret = (ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA)); + if (ret == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->init = NULL; + + ret->meth = ECDSA_get_default_method(); + ret->engine = engine; +#ifndef OPENSSL_NO_ENGINE + if (!ret->engine) + ret->engine = ENGINE_get_default_ECDSA(); + if (ret->engine) { + ret->meth = ENGINE_get_ECDSA(ret->engine); + if (!ret->meth) { + ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->flags = ret->meth->flags; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); +#if 0 + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } +#endif + return (ret); +} + +static void *ecdsa_data_new(void) +{ + return (void *)ECDSA_DATA_new_method(NULL); +} + +static void *ecdsa_data_dup(void *data) +{ + ECDSA_DATA *r = (ECDSA_DATA *)data; + + /* XXX: dummy operation */ + if (r == NULL) + return NULL; + + return ecdsa_data_new(); +} + +static void ecdsa_data_free(void *data) +{ + ECDSA_DATA *r = (ECDSA_DATA *)data; + +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data); + + OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA)); + + OPENSSL_free(r); +} + +ECDSA_DATA *ecdsa_check(EC_KEY *key) +{ + ECDSA_DATA *ecdsa_data; + + void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup, + ecdsa_data_free, ecdsa_data_free); + if (data == NULL) { + ecdsa_data = (ECDSA_DATA *)ecdsa_data_new(); + if (ecdsa_data == NULL) + return NULL; + data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data, + ecdsa_data_dup, ecdsa_data_free, + ecdsa_data_free); + if (data != NULL) { + /* + * Another thread raced us to install the key_method data and + * won. + */ + ecdsa_data_free(ecdsa_data); + ecdsa_data = (ECDSA_DATA *)data; + } else if (EC_KEY_get_key_method_data(key, ecdsa_data_dup, + ecdsa_data_free, + ecdsa_data_free) != ecdsa_data) { + /* Or an out of memory error in EC_KEY_insert_key_method_data. */ + ecdsa_data_free(ecdsa_data); + return NULL; + } + } else { + ecdsa_data = (ECDSA_DATA *)data; + } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD) + && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { + ECDSAerr(ECDSA_F_ECDSA_CHECK, ECDSA_R_NON_FIPS_METHOD); + return NULL; + } +#endif + + return ecdsa_data; +} + +int ECDSA_size(const EC_KEY *r) +{ + int ret, i; + ASN1_INTEGER bs; + BIGNUM *order = NULL; + unsigned char buf[4]; + const EC_GROUP *group; + + if (r == NULL) + return 0; + group = EC_KEY_get0_group(r); + if (group == NULL) + return 0; + + if ((order = BN_new()) == NULL) + return 0; + if (!EC_GROUP_get_order(group, order, NULL)) { + BN_clear_free(order); + return 0; + } + i = BN_num_bits(order); + bs.length = (i + 7) / 8; + bs.data = buf; + bs.type = V_ASN1_INTEGER; + /* If the top bit is set the asn1 encoding is 1 larger. */ + buf[0] = 0xff; + + i = i2d_ASN1_INTEGER(&bs, NULL); + i += i; /* r and s */ + ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); + BN_clear_free(order); + return (ret); +} + +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp, + new_func, dup_func, free_func); +} + +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg) +{ + ECDSA_DATA *ecdsa; + ecdsa = ecdsa_check(d); + if (ecdsa == NULL) + return 0; + return (CRYPTO_set_ex_data(&ecdsa->ex_data, idx, arg)); +} + +void *ECDSA_get_ex_data(EC_KEY *d, int idx) +{ + ECDSA_DATA *ecdsa; + ecdsa = ecdsa_check(d); + if (ecdsa == NULL) + return NULL; + return (CRYPTO_get_ex_data(&ecdsa->ex_data, idx)); +} + +ECDSA_METHOD *ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_meth) +{ + ECDSA_METHOD *ret; + + ret = OPENSSL_malloc(sizeof(ECDSA_METHOD)); + if (ret == NULL) { + ECDSAerr(ECDSA_F_ECDSA_METHOD_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ecdsa_meth) + *ret = *ecdsa_meth; + else { + ret->ecdsa_sign_setup = 0; + ret->ecdsa_do_sign = 0; + ret->ecdsa_do_verify = 0; + ret->name = NULL; + ret->flags = 0; + } + ret->flags |= ECDSA_METHOD_FLAG_ALLOCATED; + return ret; +} + +void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method, + ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char + *dgst, int dgst_len, + const BIGNUM *inv, + const BIGNUM *rp, + EC_KEY *eckey)) +{ + ecdsa_method->ecdsa_do_sign = ecdsa_do_sign; +} + +void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_sign_setup) (EC_KEY *eckey, + BN_CTX *ctx, + BIGNUM **kinv, + BIGNUM **r)) +{ + ecdsa_method->ecdsa_sign_setup = ecdsa_sign_setup; +} + +void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method, + int (*ecdsa_do_verify) (const unsigned char + *dgst, int dgst_len, + const ECDSA_SIG *sig, + EC_KEY *eckey)) +{ + ecdsa_method->ecdsa_do_verify = ecdsa_do_verify; +} + +void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags) +{ + ecdsa_method->flags = flags | ECDSA_METHOD_FLAG_ALLOCATED; +} + +void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name) +{ + ecdsa_method->name = name; +} + +void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method) +{ + if (ecdsa_method->flags & ECDSA_METHOD_FLAG_ALLOCATED) + OPENSSL_free(ecdsa_method); +} + +void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app) +{ + ecdsa_method->app_data = app; +} + +void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method) +{ + return ecdsa_method->app_data; +} +/* crypto/ecdsa/ecs_ossl.c */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ecs_locl.h" +// #include "err.h" +#include "obj_mac.h" +// #include "bn.h" +#include "bn_int.h" + +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, + const BIGNUM *, const BIGNUM *, + EC_KEY *eckey); +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +static ECDSA_METHOD openssl_ecdsa_meth = { + "OpenSSL ECDSA method", + ecdsa_do_sign, + ecdsa_sign_setup, + ecdsa_do_verify, +#if 0 + NULL, /* init */ + NULL, /* finish */ +#endif + 0, /* flags */ + NULL /* app_data */ +}; + +const ECDSA_METHOD *ECDSA_OpenSSL(void) +{ + return &openssl_ecdsa_meth; +} + +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + BN_CTX *ctx = NULL; + BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; + EC_POINT *tmp_point = NULL; + const EC_GROUP *group; + int ret = 0; + int order_bits; + + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx_in == NULL) { + if ((ctx = BN_CTX_new()) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); + return 0; + } + } else + ctx = ctx_in; + + k = BN_new(); /* this value is later returned in *kinvp */ + r = BN_new(); /* this value is later returned in *rp */ + order = BN_new(); + X = BN_new(); + if (!k || !r || !order || !X) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((tmp_point = EC_POINT_new(group)) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + if (!EC_GROUP_get_order(group, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + + /* Preallocate space */ + order_bits = BN_num_bits(order); + if (!BN_set_bit(k, order_bits) + || !BN_set_bit(r, order_bits) + || !BN_set_bit(X, order_bits)) + goto err; + + do { + /* get random k */ + do + if (!BN_rand_range(k, order)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, + ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); + goto err; + } + while (BN_is_zero(k)) ; + + /* + * We do not want timing information to leak the length of k, so we + * compute G*k using an equivalent scalar of fixed bit-length. + * + * We unconditionally perform both of these additions to prevent a + * small timing information leakage. We then choose the sum that is + * one bit longer than the order. This guarantees the code + * path used in the constant time implementations elsewhere. + * + * TODO: revisit the BN_copy aiming for a memory access agnostic + * conditional copy. + */ + if (!BN_add(r, k, order) + || !BN_add(X, r, order) + || !BN_copy(k, BN_num_bits(r) > order_bits ? r : X)) + goto err; + + /* compute r the x-coordinate of generator * k */ + if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == + NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp + (group, tmp_point, X, NULL, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* NID_X9_62_characteristic_two_field */ + + if (!EC_POINT_get_affine_coordinates_GF2m(group, + tmp_point, X, NULL, + ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + } +#endif + if (!BN_nnmod(r, X, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + } + while (BN_is_zero(r)); + + /* compute the inverse of k */ + if (EC_GROUP_get_mont_data(group) != NULL) { + /* + * We want inverse in constant time, therefore we utilize the fact + * order must be prime and use Fermats Little Theorem instead. + */ + if (!BN_set_word(X, 2)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_sub(X, order, X, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + BN_set_flags(X, BN_FLG_CONSTTIME); + if (!BN_mod_exp_mont_consttime + (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + } else { + if (!BN_mod_inverse(k, k, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + } + + /* clear old values if necessary */ + if (*rp != NULL) + BN_clear_free(*rp); + if (*kinvp != NULL) + BN_clear_free(*kinvp); + /* save the pre-computed values */ + *rp = r; + *kinvp = k; + ret = 1; + err: + if (!ret) { + if (k != NULL) + BN_clear_free(k); + if (r != NULL) + BN_clear_free(r); + } + if (ctx_in == NULL) + BN_CTX_free(ctx); + if (order != NULL) + BN_free(order); + if (tmp_point != NULL) + EC_POINT_free(tmp_point); + if (X) + BN_clear_free(X); + return (ret); +} + +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey) +{ + int ok = 0, i; + BIGNUM *kinv = NULL, *s, *m = NULL, *order = NULL; + const BIGNUM *ckinv; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + ECDSA_SIG *ret; + ECDSA_DATA *ecdsa; + const BIGNUM *priv_key; + BN_MONT_CTX *mont_data; + + ecdsa = ecdsa_check(eckey); + group = EC_KEY_get0_group(eckey); + priv_key = EC_KEY_get0_private_key(eckey); + + if (group == NULL || priv_key == NULL || ecdsa == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ret = ECDSA_SIG_new(); + if (!ret) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + return NULL; + } + s = ret->s; + + if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || + (m = BN_new()) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_GROUP_get_order(group, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); + goto err; + } + mont_data = EC_GROUP_get_mont_data(group); + + i = BN_num_bits(order); + /* + * Need to truncate digest if it is too long: first truncate whole bytes. + */ + if (8 * dgst_len > i) + dgst_len = (i + 7) / 8; + if (!BN_bin2bn(dgst, dgst_len, m)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + /* If still too long truncate remaining bits with a shift */ + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + do { + if (in_kinv == NULL || in_r == NULL) { + if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_ECDSA_LIB); + goto err; + } + ckinv = kinv; + } else { + ckinv = in_kinv; + if (BN_copy(ret->r, in_r) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + /* + * With only one multiplicant being in Montgomery domain + * multiplication yields real result without post-conversion. + * Also note that all operations but last are performed with + * zero-padded vectors. Last operation, BN_mod_mul_montgomery + * below, returns user-visible value with removed zero padding. + */ + if (!bn_to_mont_fixed_top(s, ret->r, mont_data, ctx) + || !bn_mul_mont_fixed_top(s, s, priv_key, mont_data, ctx)) { + goto err; + } + if (!bn_mod_add_fixed_top(s, s, m, order)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + /* + * |s| can still be larger than modulus, because |m| can be. In + * such case we count on Montgomery reduction to tie it up. + */ + if (!bn_to_mont_fixed_top(s, s, mont_data, ctx) + || !BN_mod_mul_montgomery(s, s, ckinv, mont_data, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (BN_is_zero(s)) { + /* + * if kinv and r have been supplied by the caller don't to + * generate new kinv and r values + */ + if (in_kinv != NULL && in_r != NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, + ECDSA_R_NEED_NEW_SETUP_VALUES); + goto err; + } + } else + /* s != 0 => we have a valid signature */ + break; + } + while (1); + + ok = 1; + err: + if (!ok) { + ECDSA_SIG_free(ret); + ret = NULL; + } + if (ctx) + BN_CTX_free(ctx); + if (m) + BN_clear_free(m); + if (order) + BN_free(order); + if (kinv) + BN_clear_free(kinv); + return ret; +} + +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + int ret = -1, i; + BN_CTX *ctx; + BIGNUM *order, *u1, *u2, *m, *X; + EC_POINT *point = NULL; + const EC_GROUP *group; + const EC_POINT *pub_key; + + /* check input values */ + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || + (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); + return -1; + } + + ctx = BN_CTX_new(); + if (!ctx) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); + return -1; + } + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + u1 = BN_CTX_get(ctx); + u2 = BN_CTX_get(ctx); + m = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + if (!X) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + + if (!EC_GROUP_get_order(group, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || + BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); + ret = 0; /* signature is invalid */ + goto err; + } + /* calculate tmp1 = inv(S) mod order */ + if (!BN_mod_inverse(u2, sig->s, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* digest -> m */ + i = BN_num_bits(order); + /* + * Need to truncate digest if it is too long: first truncate whole bytes. + */ + if (8 * dgst_len > i) + dgst_len = (i + 7) / 8; + if (!BN_bin2bn(dgst, dgst_len, m)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* If still too long truncate remaining bits with a shift */ + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* u1 = m * tmp mod order */ + if (!BN_mod_mul(u1, m, u2, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* u2 = r * w mod q */ + if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + + if ((point = EC_POINT_new(group)) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == + NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* NID_X9_62_characteristic_two_field */ + + if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + } +#endif + if (!BN_nnmod(u1, X, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* if the signature is correct u1 is equal to sig->r */ + ret = (BN_ucmp(u1, sig->r) == 0); + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (point) + EC_POINT_free(point); + return ret; +} +/* crypto/ecdsa/ecdsa_sign.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ecs_locl.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +#include "rand.h" + +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) +{ + return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey); +} + +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, + const BIGNUM *kinv, const BIGNUM *rp, + EC_KEY *eckey) +{ + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return NULL; + return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey); +} + +int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char + *sig, unsigned int *siglen, EC_KEY *eckey) +{ + return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey); +} + +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char + *sig, unsigned int *siglen, const BIGNUM *kinv, + const BIGNUM *r, EC_KEY *eckey) +{ + ECDSA_SIG *s; + RAND_seed(dgst, dlen); + s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); + if (s == NULL) { + *siglen = 0; + return 0; + } + *siglen = i2d_ECDSA_SIG(s, &sig); + ECDSA_SIG_free(s); + return 1; +} + +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return 0; + return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); +} +/* crypto/ecdsa/ecdsa_vrf.c */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ecs_locl.h" +#include +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +/*- + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return 0; + return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey); +} + +/*- + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) +{ + ECDSA_SIG *s; + const unsigned char *p = sigbuf; + unsigned char *der = NULL; + int derlen = -1; + int ret = -1; + + s = ECDSA_SIG_new(); + if (s == NULL) + return (ret); + if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) + goto err; + /* Ensure signature uses DER and doesn't have trailing garbage */ + derlen = i2d_ECDSA_SIG(s, &der); + if (derlen != sig_len || memcmp(sigbuf, der, derlen)) + goto err; + ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); + err: + if (derlen > 0) { + OPENSSL_cleanse(der, derlen); + OPENSSL_free(der); + } + ECDSA_SIG_free(s); + return (ret); +} diff --git a/Sources/COpenSSL/ecs_locl.h b/Sources/COpenSSL/ecs_locl.h new file mode 100644 index 00000000..08f7c56e --- /dev/null +++ b/Sources/COpenSSL/ecs_locl.h @@ -0,0 +1,120 @@ +/* crypto/ecdsa/ecs_locl.h */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ECS_LOCL_H +# define HEADER_ECS_LOCL_H + +# include "ecdsa.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ecdsa_method { + const char *name; + ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char *dgst, int dgst_len, + const BIGNUM *inv, const BIGNUM *rp, + EC_KEY *eckey); + int (*ecdsa_sign_setup) (EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **r); + int (*ecdsa_do_verify) (const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); +# if 0 + int (*init) (EC_KEY *eckey); + int (*finish) (EC_KEY *eckey); +# endif + int flags; + void *app_data; +}; + +/* The ECDSA_METHOD was allocated and can be freed */ + +# define ECDSA_METHOD_FLAG_ALLOCATED 0x2 + +/* + * If this flag is set the ECDSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define ECDSA_FLAG_FIPS_METHOD 0x1 + +typedef struct ecdsa_data_st { + /* EC_KEY_METH_DATA part */ + int (*init) (EC_KEY *); + /* method (ECDSA) specific part */ + ENGINE *engine; + int flags; + const ECDSA_METHOD *meth; + CRYPTO_EX_DATA ex_data; +} ECDSA_DATA; + +/** ecdsa_check + * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure + * and if not it removes the old meth_data and creates a ECDSA_DATA structure. + * \param eckey pointer to a EC_KEY object + * \return pointer to a ECDSA_DATA structure + */ +ECDSA_DATA *ecdsa_check(EC_KEY *eckey); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_ECS_LOCL_H */ diff --git a/Sources/COpenSSL/ede_cbcm_enc.c b/Sources/COpenSSL/ede_cbcm_enc.c new file mode 100644 index 00000000..72ef639b --- /dev/null +++ b/Sources/COpenSSL/ede_cbcm_enc.c @@ -0,0 +1,189 @@ +/* ede_cbcm_enc.c */ +/* + * Written by Ben Laurie for the OpenSSL project 13 Feb + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * + * This is an implementation of Triple DES Cipher Block Chaining with Output + * Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom). + * + * Note that there is a known attack on this by Biham and Knudsen but it + * takes a lot of work: + * + * http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz + * + */ + +#include "opensslconf.h" /* To see if OPENSSL_NO_DESCBCM is defined */ + +#ifndef OPENSSL_NO_DESCBCM +# include "des_locl.h" + +void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec1, DES_cblock *ivec2, int enc) +{ + register DES_LONG tin0, tin1; + register DES_LONG tout0, tout1, xor0, xor1, m0, m1; + register long l = length; + DES_LONG tin[2]; + unsigned char *iv1, *iv2; + + iv1 = &(*ivec1)[0]; + iv2 = &(*ivec2)[0]; + + if (enc) { + c2l(iv1, m0); + c2l(iv1, m1); + c2l(iv2, tout0); + c2l(iv2, tout1); + for (l -= 8; l >= -7; l -= 8) { + tin[0] = m0; + tin[1] = m1; + DES_encrypt1(tin, ks3, 1); + m0 = tin[0]; + m1 = tin[1]; + + if (l < 0) { + c2ln(in, tin0, tin1, l + 8); + } else { + c2l(in, tin0); + c2l(in, tin1); + } + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt1(tin, ks1, 1); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks2, 0); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks1, 1); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv1 = &(*ivec1)[0]; + l2c(m0, iv1); + l2c(m1, iv1); + + iv2 = &(*ivec2)[0]; + l2c(tout0, iv2); + l2c(tout1, iv2); + } else { + register DES_LONG t0, t1; + + c2l(iv1, m0); + c2l(iv1, m1); + c2l(iv2, xor0); + c2l(iv2, xor1); + for (l -= 8; l >= -7; l -= 8) { + tin[0] = m0; + tin[1] = m1; + DES_encrypt1(tin, ks3, 1); + m0 = tin[0]; + m1 = tin[1]; + + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt1(tin, ks1, 0); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks2, 1); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks1, 0); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + if (l < 0) { + l2cn(tout0, tout1, out, l + 8); + } else { + l2c(tout0, out); + l2c(tout1, out); + } + xor0 = t0; + xor1 = t1; + } + + iv1 = &(*ivec1)[0]; + l2c(m0, iv1); + l2c(m1, iv1); + + iv2 = &(*ivec2)[0]; + l2c(xor0, iv2); + l2c(xor1, iv2); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} +#endif diff --git a/Sources/COpenSSL/enc_.c b/Sources/COpenSSL/enc_.c new file mode 100644 index 00000000..6b1abee1 --- /dev/null +++ b/Sources/COpenSSL/enc_.c @@ -0,0 +1,417 @@ +/* crypto/des/enc_read.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include "des_locl.h" + +/* This has some uglies in it but it works - even over sockets. */ +/* + * extern int errno; + */ +OPENSSL_IMPLEMENT_GLOBAL(int, DES_rw_mode, DES_PCBC_MODE) + +/*- + * WARNINGS: + * + * - The data format used by DES_enc_write() and DES_enc_read() + * has a cryptographic weakness: When asked to write more + * than MAXWRITE bytes, DES_enc_write will split the data + * into several chunks that are all encrypted + * using the same IV. So don't use these functions unless you + * are sure you know what you do (in which case you might + * not want to use them anyway). + * + * - This code cannot handle non-blocking sockets. + * + * - This function uses an internal state and thus cannot be + * used on multiple files. + */ +int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv) +{ +#if defined(OPENSSL_NO_POSIX_IO) + return (0); +#else + /* data to be unencrypted */ + int net_num = 0; + static unsigned char *net = NULL; + /* + * extra unencrypted data for when a block of 100 comes in but is + * des_read one byte at a time. + */ + static unsigned char *unnet = NULL; + static int unnet_start = 0; + static int unnet_left = 0; + static unsigned char *tmpbuf = NULL; + int i; + long num = 0, rnum; + unsigned char *p; + + if (tmpbuf == NULL) { + tmpbuf = OPENSSL_malloc(BSIZE); + if (tmpbuf == NULL) + return (-1); + } + if (net == NULL) { + net = OPENSSL_malloc(BSIZE); + if (net == NULL) + return (-1); + } + if (unnet == NULL) { + unnet = OPENSSL_malloc(BSIZE); + if (unnet == NULL) + return (-1); + } + /* left over data from last decrypt */ + if (unnet_left != 0) { + if (unnet_left < len) { + /* + * we still still need more data but will return with the number + * of bytes we have - should always check the return value + */ + memcpy(buf, &(unnet[unnet_start]), unnet_left); + /* + * eay 26/08/92 I had the next 2 lines reversed :-( + */ + i = unnet_left; + unnet_start = unnet_left = 0; + } else { + memcpy(buf, &(unnet[unnet_start]), len); + unnet_start += len; + unnet_left -= len; + i = len; + } + return (i); + } + + /* We need to get more data. */ + if (len > MAXWRITE) + len = MAXWRITE; + + /* first - get the length */ + while (net_num < HDRSIZE) { +# ifndef OPENSSL_SYS_WIN32 + i = read(fd, (void *)&(net[net_num]), HDRSIZE - net_num); +# else + i = _read(fd, (void *)&(net[net_num]), HDRSIZE - net_num); +# endif +# ifdef EINTR + if ((i == -1) && (errno == EINTR)) + continue; +# endif + if (i <= 0) + return (0); + net_num += i; + } + + /* we now have at net_num bytes in net */ + p = net; + /* num=0; */ + n2l(p, num); + /* + * num should be rounded up to the next group of eight we make sure that + * we have read a multiple of 8 bytes from the net. + */ + if ((num > MAXWRITE) || (num < 0)) /* error */ + return (-1); + rnum = (num < 8) ? 8 : ((num + 7) / 8 * 8); + + net_num = 0; + while (net_num < rnum) { +# ifndef OPENSSL_SYS_WIN32 + i = read(fd, (void *)&(net[net_num]), rnum - net_num); +# else + i = _read(fd, (void *)&(net[net_num]), rnum - net_num); +# endif +# ifdef EINTR + if ((i == -1) && (errno == EINTR)) + continue; +# endif + if (i <= 0) + return (0); + net_num += i; + } + + /* Check if there will be data left over. */ + if (len < num) { + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, unnet, num, sched, iv, DES_DECRYPT); + else + DES_cbc_encrypt(net, unnet, num, sched, iv, DES_DECRYPT); + memcpy(buf, unnet, len); + unnet_start = len; + unnet_left = num - len; + + /* + * The following line is done because we return num as the number of + * bytes read. + */ + num = len; + } else { + /*- + * >output is a multiple of 8 byes, if len < rnum + * >we must be careful. The user must be aware that this + * >routine will write more bytes than he asked for. + * >The length of the buffer must be correct. + * FIXED - Should be ok now 18-9-90 - eay */ + if (len < rnum) { + + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, tmpbuf, num, sched, iv, DES_DECRYPT); + else + DES_cbc_encrypt(net, tmpbuf, num, sched, iv, DES_DECRYPT); + + /* + * eay 26/08/92 fix a bug that returned more bytes than you asked + * for (returned len bytes :-( + */ + memcpy(buf, tmpbuf, num); + } else { + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, buf, num, sched, iv, DES_DECRYPT); + else + DES_cbc_encrypt(net, buf, num, sched, iv, DES_DECRYPT); + } + } + return num; +#endif /* OPENSSL_NO_POSIX_IO */ +} +/* crypto/des/enc_writ.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +// #include "cryptlib.h" +// #include "des_locl.h" +#include "rand.h" + +/*- + * WARNINGS: + * + * - The data format used by DES_enc_write() and DES_enc_read() + * has a cryptographic weakness: When asked to write more + * than MAXWRITE bytes, DES_enc_write will split the data + * into several chunks that are all encrypted + * using the same IV. So don't use these functions unless you + * are sure you know what you do (in which case you might + * not want to use them anyway). + * + * - This code cannot handle non-blocking sockets. + */ + +int DES_enc_write(int fd, const void *_buf, int len, + DES_key_schedule *sched, DES_cblock *iv) +{ +#if defined(OPENSSL_NO_POSIX_IO) + return (-1); +#else +# ifdef _LIBC + extern unsigned long time(); + extern int write(); +# endif + const unsigned char *buf = _buf; + long rnum; + int i, j, k, outnum; + static unsigned char *outbuf = NULL; + unsigned char shortbuf[8]; + unsigned char *p; + const unsigned char *cp; + static int start = 1; + + if (len < 0) + return -1; + + if (outbuf == NULL) { + outbuf = OPENSSL_malloc(BSIZE + HDRSIZE); + if (outbuf == NULL) + return (-1); + } + /* + * If we are sending less than 8 bytes, the same char will look the same + * if we don't pad it out with random bytes + */ + if (start) { + start = 0; + } + + /* lets recurse if we want to send the data in small chunks */ + if (len > MAXWRITE) { + j = 0; + for (i = 0; i < len; i += k) { + k = DES_enc_write(fd, &(buf[i]), + ((len - i) > MAXWRITE) ? MAXWRITE : (len - i), + sched, iv); + if (k < 0) + return (k); + else + j += k; + } + return (j); + } + + /* write length first */ + p = outbuf; + l2n(len, p); + + /* pad short strings */ + if (len < 8) { + cp = shortbuf; + memcpy(shortbuf, buf, len); + if (RAND_bytes(shortbuf + len, 8 - len) <= 0) { + return -1; + } + rnum = 8; + } else { + cp = buf; + rnum = ((len + 7) / 8 * 8); /* round up to nearest eight */ + } + + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched, + iv, DES_ENCRYPT); + else + DES_cbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched, + iv, DES_ENCRYPT); + + /* output */ + outnum = rnum + HDRSIZE; + + for (j = 0; j < outnum; j += i) { + /* + * eay 26/08/92 I was not doing writing from where we got up to. + */ +# ifndef _WIN32 + i = write(fd, (void *)&(outbuf[j]), outnum - j); +# else + i = _write(fd, (void *)&(outbuf[j]), outnum - j); +# endif + if (i == -1) { +# ifdef EINTR + if (errno == EINTR) + i = 0; + else +# endif + /* + * This is really a bad error - very bad It will stuff-up + * both ends. + */ + return (-1); + } + } + + return (len); +#endif /* OPENSSL_NO_POSIX_IO */ +} diff --git a/Sources/COpenSSL/encode.c b/Sources/COpenSSL/encode.c new file mode 100644 index 00000000..06ecf637 --- /dev/null +++ b/Sources/COpenSSL/encode.c @@ -0,0 +1,460 @@ +/* crypto/evp/encode.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include "evp.h" + +static unsigned char conv_ascii2bin(unsigned char a); +#ifndef CHARSET_EBCDIC +# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) +#else +/* + * We assume that PEM encoded files are EBCDIC files (i.e., printable text + * files). Convert them here while decoding. When encoding, output is EBCDIC + * (text) format again. (No need for conversion in the conv_bin2ascii macro, + * as the underlying textstring data_bin2ascii[] is already EBCDIC) + */ +# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) +#endif + +/*- + * 64 char lines + * pad input with 0 + * left over chars are set to = + * 1 byte => xx== + * 2 bytes => xxx= + * 3 bytes => xxxx + */ +#define BIN_PER_LINE (64/4*3) +#define CHUNKS_PER_LINE (64/4) +#define CHAR_PER_LINE (64+1) + +static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\ +abcdefghijklmnopqrstuvwxyz0123456789+/"; + +/*- + * 0xF0 is a EOLN + * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). + * 0xF2 is EOF + * 0xE0 is ignore at start of line. + * 0xFF is error + */ + +#define B64_EOLN 0xF0 +#define B64_CR 0xF1 +#define B64_EOF 0xF2 +#define B64_WS 0xE0 +#define B64_ERROR 0xFF +#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) +#define B64_BASE64(a) !B64_NOT_BASE64(a) + +static const unsigned char data_ascii2bin[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +#ifndef CHARSET_EBCDIC +static unsigned char conv_ascii2bin(unsigned char a) +{ + if (a & 0x80) + return B64_ERROR; + return data_ascii2bin[a]; +} +#else +static unsigned char conv_ascii2bin(unsigned char a) +{ + a = os_toascii[a]; + if (a & 0x80) + return B64_ERROR; + return data_ascii2bin[a]; +} +#endif + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) +{ + ctx->length = 48; + ctx->num = 0; + ctx->line_num = 0; +} + +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int i, j; + size_t total = 0; + + *outl = 0; + if (inl <= 0) + return; + OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); + if (ctx->length - ctx->num > inl) { + memcpy(&(ctx->enc_data[ctx->num]), in, inl); + ctx->num += inl; + return; + } + if (ctx->num != 0) { + i = ctx->length - ctx->num; + memcpy(&(ctx->enc_data[ctx->num]), in, i); + in += i; + inl -= i; + j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length); + ctx->num = 0; + out += j; + *(out++) = '\n'; + *out = '\0'; + total = j + 1; + } + while (inl >= ctx->length && total <= INT_MAX) { + j = EVP_EncodeBlock(out, in, ctx->length); + in += ctx->length; + inl -= ctx->length; + out += j; + *(out++) = '\n'; + *out = '\0'; + total += j + 1; + } + if (total > INT_MAX) { + /* Too much output data! */ + *outl = 0; + return; + } + if (inl != 0) + memcpy(&(ctx->enc_data[0]), in, inl); + ctx->num = inl; + *outl = total; +} + +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) +{ + unsigned int ret = 0; + + if (ctx->num != 0) { + ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num); + out[ret++] = '\n'; + out[ret] = '\0'; + ctx->num = 0; + } + *outl = ret; +} + +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen) +{ + int i, ret = 0; + unsigned long l; + + for (i = dlen; i > 0; i -= 3) { + if (i >= 3) { + l = (((unsigned long)f[0]) << 16L) | + (((unsigned long)f[1]) << 8L) | f[2]; + *(t++) = conv_bin2ascii(l >> 18L); + *(t++) = conv_bin2ascii(l >> 12L); + *(t++) = conv_bin2ascii(l >> 6L); + *(t++) = conv_bin2ascii(l); + } else { + l = ((unsigned long)f[0]) << 16L; + if (i == 2) + l |= ((unsigned long)f[1] << 8L); + + *(t++) = conv_bin2ascii(l >> 18L); + *(t++) = conv_bin2ascii(l >> 12L); + *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L); + *(t++) = '='; + } + ret += 4; + f += 3; + } + + *t = '\0'; + return (ret); +} + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) +{ + /* Only ctx->num is used during decoding. */ + ctx->num = 0; + ctx->length = 0; + ctx->line_num = 0; + ctx->expect_nl = 0; +} + +/*- + * -1 for error + * 0 for last line + * 1 for full line + * + * Note: even though EVP_DecodeUpdate attempts to detect and report end of + * content, the context doesn't currently remember it and will accept more data + * in the next call. Therefore, the caller is responsible for checking and + * rejecting a 0 return value in the middle of content. + * + * Note: even though EVP_DecodeUpdate has historically tried to detect end of + * content based on line length, this has never worked properly. Therefore, + * we now return 0 when one of the following is true: + * - Padding or B64_EOF was detected and the last block is complete. + * - Input has zero-length. + * -1 is returned if: + * - Invalid characters are detected. + * - There is extra trailing padding, or data after padding. + * - B64_EOF is detected after an incomplete base64 block. + */ +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len; + unsigned char *d; + + n = ctx->num; + d = ctx->enc_data; + + if (n > 0 && d[n - 1] == '=') { + eof++; + if (n > 1 && d[n - 2] == '=') + eof++; + } + + /* Legacy behaviour: an empty input chunk signals end of input. */ + if (inl == 0) { + rv = 0; + goto end; + } + + for (i = 0; i < inl; i++) { + tmp = *(in++); + v = conv_ascii2bin(tmp); + if (v == B64_ERROR) { + rv = -1; + goto end; + } + + if (tmp == '=') { + eof++; + } else if (eof > 0 && B64_BASE64(v)) { + /* More data after padding. */ + rv = -1; + goto end; + } + + if (eof > 2) { + rv = -1; + goto end; + } + + if (v == B64_EOF) { + seof = 1; + goto tail; + } + + /* Only save valid base64 characters. */ + if (B64_BASE64(v)) { + if (n >= 64) { + /* + * We increment n once per loop, and empty the buffer as soon as + * we reach 64 characters, so this can only happen if someone's + * manually messed with the ctx. Refuse to write any more data. + */ + rv = -1; + goto end; + } + OPENSSL_assert(n < (int)sizeof(ctx->enc_data)); + d[n++] = tmp; + } + + if (n == 64) { + decoded_len = EVP_DecodeBlock(out, d, n); + n = 0; + if (decoded_len < 0 || eof > decoded_len) { + rv = -1; + goto end; + } + ret += decoded_len - eof; + out += decoded_len - eof; + } + } + + /* + * Legacy behaviour: if the current line is a full base64-block (i.e., has + * 0 mod 4 base64 characters), it is processed immediately. We keep this + * behaviour as applications may not be calling EVP_DecodeFinal properly. + */ +tail: + if (n > 0) { + if ((n & 3) == 0) { + decoded_len = EVP_DecodeBlock(out, d, n); + n = 0; + if (decoded_len < 0 || eof > decoded_len) { + rv = -1; + goto end; + } + ret += (decoded_len - eof); + } else if (seof) { + /* EOF in the middle of a base64 block. */ + rv = -1; + goto end; + } + } + + rv = seof || (n == 0 && eof) ? 0 : 1; +end: + /* Legacy behaviour. This should probably rather be zeroed on error. */ + *outl = ret; + ctx->num = n; + return (rv); +} + +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n) +{ + int i, ret = 0, a, b, c, d; + unsigned long l; + + /* trim white space from the start of the line. */ + while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) { + f++; + n--; + } + + /* + * strip off stuff at the end of the line ascii2bin values B64_WS, + * B64_EOLN, B64_EOLN and B64_EOF + */ + while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1])))) + n--; + + if (n % 4 != 0) + return (-1); + + for (i = 0; i < n; i += 4) { + a = conv_ascii2bin(*(f++)); + b = conv_ascii2bin(*(f++)); + c = conv_ascii2bin(*(f++)); + d = conv_ascii2bin(*(f++)); + if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) + return (-1); + l = ((((unsigned long)a) << 18L) | + (((unsigned long)b) << 12L) | + (((unsigned long)c) << 6L) | (((unsigned long)d))); + *(t++) = (unsigned char)(l >> 16L) & 0xff; + *(t++) = (unsigned char)(l >> 8L) & 0xff; + *(t++) = (unsigned char)(l) & 0xff; + ret += 3; + } + return (ret); +} + +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + + *outl = 0; + if (ctx->num != 0) { + i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num); + if (i < 0) + return (-1); + ctx->num = 0; + *outl = i; + return (1); + } else + return (1); +} + +#ifdef undef +int EVP_DecodeValid(unsigned char *buf, int len) +{ + int i, num = 0, bad = 0; + + if (len == 0) + return (-1); + while (conv_ascii2bin(*buf) == B64_WS) { + buf++; + len--; + if (len == 0) + return (-1); + } + + for (i = len; i >= 4; i -= 4) { + if ((conv_ascii2bin(buf[0]) >= 0x40) || + (conv_ascii2bin(buf[1]) >= 0x40) || + (conv_ascii2bin(buf[2]) >= 0x40) || + (conv_ascii2bin(buf[3]) >= 0x40)) + return (-1); + buf += 4; + num += 1 + (buf[2] != '=') + (buf[3] != '='); + } + if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN)) + return (num); + if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) && + (conv_ascii2bin(buf[0]) == B64_EOLN)) + return (num); + return (1); +} +#endif diff --git a/Sources/COpenSSL/eng_.c b/Sources/COpenSSL/eng_.c new file mode 100644 index 00000000..8e2c7aba --- /dev/null +++ b/Sources/COpenSSL/eng_.c @@ -0,0 +1,5257 @@ +/* crypto/engine/eng_all.c */ +/* + * Written by Richard Levitte for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "eng_int.h" + +void ENGINE_load_builtin_engines(void) +{ + /* Some ENGINEs need this */ + OPENSSL_cpuid_setup(); +#if 0 + /* + * There's no longer any need for an "openssl" ENGINE unless, one day, it + * is the *only* way for standard builtin implementations to be be + * accessed (ie. it would be possible to statically link binaries with + * *no* builtin implementations). + */ + ENGINE_load_openssl(); +#endif +#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) + ENGINE_load_cryptodev(); +#endif +#ifndef OPENSSL_NO_RDRAND + ENGINE_load_rdrand(); +#endif + ENGINE_load_dynamic(); +#ifndef OPENSSL_NO_STATIC_ENGINE +# ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_4758_CCA + ENGINE_load_4758cca(); +# endif +# ifndef OPENSSL_NO_HW_AEP + ENGINE_load_aep(); +# endif +# ifndef OPENSSL_NO_HW_ATALLA + ENGINE_load_atalla(); +# endif +# ifndef OPENSSL_NO_HW_CSWIFT + ENGINE_load_cswift(); +# endif +# ifndef OPENSSL_NO_HW_NCIPHER + ENGINE_load_chil(); +# endif +# ifndef OPENSSL_NO_HW_NURON + ENGINE_load_nuron(); +# endif +# ifndef OPENSSL_NO_HW_SUREWARE + ENGINE_load_sureware(); +# endif +# ifndef OPENSSL_NO_HW_UBSEC + ENGINE_load_ubsec(); +# endif +# ifndef OPENSSL_NO_HW_PADLOCK + ENGINE_load_padlock(); +# endif +# endif +# ifndef OPENSSL_NO_GOST + ENGINE_load_gost(); +# endif +# ifndef OPENSSL_NO_GMP + ENGINE_load_gmp(); +# endif +# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) + ENGINE_load_capi(); +# endif +#endif + ENGINE_register_all_complete(); +} + +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) +void ENGINE_setup_bsd_cryptodev(void) +{ + static int bsd_cryptodev_default_loaded = 0; + if (!bsd_cryptodev_default_loaded) { + ENGINE_load_cryptodev(); + ENGINE_register_all_complete(); + } + bsd_cryptodev_default_loaded = 1; +} +#endif +/* eng_cnf.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "eng_int.h" +#include "conf.h" + +/* #define ENGINE_CONF_DEBUG */ + +/* ENGINE config module */ + +static char *skip_dot(char *name) +{ + char *p; + p = strchr(name, '.'); + if (p) + return p + 1; + return name; +} + +static STACK_OF(ENGINE) *initialized_engines = NULL; + +static int int_engine_init(ENGINE *e) +{ + if (!ENGINE_init(e)) + return 0; + if (!initialized_engines) + initialized_engines = sk_ENGINE_new_null(); + if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) { + ENGINE_finish(e); + return 0; + } + return 1; +} + +static int int_engine_configure(char *name, char *value, const CONF *cnf) +{ + int i; + int ret = 0; + long do_init = -1; + STACK_OF(CONF_VALUE) *ecmds; + CONF_VALUE *ecmd = NULL; + char *ctrlname, *ctrlvalue; + ENGINE *e = NULL; + int soft = 0; + + name = skip_dot(name); +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "Configuring engine %s\n", name); +#endif + /* Value is a section containing ENGINE commands */ + ecmds = NCONF_get_section(cnf, value); + + if (!ecmds) { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, + ENGINE_R_ENGINE_SECTION_ERROR); + return 0; + } + + for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) { + ecmd = sk_CONF_VALUE_value(ecmds, i); + ctrlname = skip_dot(ecmd->name); + ctrlvalue = ecmd->value; +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, + ctrlvalue); +#endif + + /* First handle some special pseudo ctrls */ + + /* Override engine name to use */ + if (!strcmp(ctrlname, "engine_id")) + name = ctrlvalue; + else if (!strcmp(ctrlname, "soft_load")) + soft = 1; + /* Load a dynamic ENGINE */ + else if (!strcmp(ctrlname, "dynamic_path")) { + e = ENGINE_by_id("dynamic"); + if (!e) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0)) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0)) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) + goto err; + } + /* ... add other pseudos here ... */ + else { + /* + * At this point we need an ENGINE structural reference if we + * don't already have one. + */ + if (!e) { + e = ENGINE_by_id(name); + if (!e && soft) { + ERR_clear_error(); + return 1; + } + if (!e) + goto err; + } + /* + * Allow "EMPTY" to mean no value: this allows a valid "value" to + * be passed to ctrls of type NO_INPUT + */ + if (!strcmp(ctrlvalue, "EMPTY")) + ctrlvalue = NULL; + if (!strcmp(ctrlname, "init")) { + if (!NCONF_get_number_e(cnf, value, "init", &do_init)) + goto err; + if (do_init == 1) { + if (!int_engine_init(e)) + goto err; + } else if (do_init != 0) { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, + ENGINE_R_INVALID_INIT_VALUE); + goto err; + } + } else if (!strcmp(ctrlname, "default_algorithms")) { + if (!ENGINE_set_default_string(e, ctrlvalue)) + goto err; + } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0)) + goto err; + } + + } + if (e && (do_init == -1) && !int_engine_init(e)) { + ecmd = NULL; + goto err; + } + ret = 1; + err: + if (ret != 1) { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, + ENGINE_R_ENGINE_CONFIGURATION_ERROR); + if (ecmd) + ERR_add_error_data(6, "section=", ecmd->section, + ", name=", ecmd->name, + ", value=", ecmd->value); + } + if (e) + ENGINE_free(e); + return ret; +} + +static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) +{ + STACK_OF(CONF_VALUE) *elist; + CONF_VALUE *cval; + int i; +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "Called engine module: name %s, value %s\n", + CONF_imodule_get_name(md), CONF_imodule_get_value(md)); +#endif + /* Value is a section containing ENGINEs to configure */ + elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); + + if (!elist) { + ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, + ENGINE_R_ENGINES_SECTION_ERROR); + return 0; + } + + for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { + cval = sk_CONF_VALUE_value(elist, i); + if (!int_engine_configure(cval->name, cval->value, cnf)) + return 0; + } + + return 1; +} + +static void int_engine_module_finish(CONF_IMODULE *md) +{ + ENGINE *e; + while ((e = sk_ENGINE_pop(initialized_engines))) + ENGINE_finish(e); + sk_ENGINE_free(initialized_engines); + initialized_engines = NULL; +} + +void ENGINE_add_conf_module(void) +{ + CONF_module_add("engines", + int_engine_module_init, int_engine_module_finish); +} +/* + * Copyright (c) 2002 Bob Beck + * Copyright (c) 2002 Theo de Raadt + * Copyright (c) 2002 Markus Friedl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include "objects.h" +#include "engine.h" +#include "evp.h" +#include "bn.h" + +#if (defined(__unix__) || defined(unix)) && !defined(USG) && \ + (defined(OpenBSD) || defined(__FreeBSD__)) +# include +# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) +# define HAVE_CRYPTODEV +# endif +# if (OpenBSD >= 200110) +# define HAVE_SYSLOG_R +# endif +#endif + +#ifndef HAVE_CRYPTODEV + +void ENGINE_load_cryptodev(void) +{ + /* This is a NOP on platforms without /dev/crypto */ + return; +} + +#else + +# include +# include +# include "dh.h" +# include "dsa.h" +# include "err.h" +# include "rsa.h" +# include +# include +# include +# include +# include +# include +# include +# include +# include + +struct dev_crypto_state { + struct session_op d_sess; + int d_fd; +# ifdef USE_CRYPTODEV_DIGESTS + char dummy_mac_key[HASH_MAX_LEN]; + unsigned char digest_res[HASH_MAX_LEN]; + char *mac_data; + int mac_len; +# endif +}; + +static u_int32_t cryptodev_asymfeat = 0; + +static int get_asym_dev_crypto(void); +static int open_dev_crypto(void); +static int get_dev_crypto(void); +static int get_cryptodev_ciphers(const int **cnids); +# ifdef USE_CRYPTODEV_DIGESTS +static int get_cryptodev_digests(const int **cnids); +# endif +static int cryptodev_usable_ciphers(const int **nids); +static int cryptodev_usable_digests(const int **nids); +static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); +static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); +static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid); +static int bn2crparam(const BIGNUM *a, struct crparam *crp); +static int crparam2bn(struct crparam *crp, BIGNUM *a); +static void zapparams(struct crypt_kop *kop); +static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, + int slen, BIGNUM *s); + +static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, + BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, + BIGNUM *p, BN_CTX *ctx, + BN_MONT_CTX *mont); +static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, + DSA *dsa); +static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); +static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, + DH *dh); +static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)); +void ENGINE_load_cryptodev(void); + +static const ENGINE_CMD_DEFN cryptodev_defns[] = { + {0, NULL, NULL, 0} +}; + +static struct { + int id; + int nid; + int ivmax; + int keylen; +} ciphers[] = { + { + CRYPTO_ARC4, NID_rc4, 0, 16, + }, + { + CRYPTO_DES_CBC, NID_des_cbc, 8, 8, + }, + { + CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, + }, + { + CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, + }, + { + CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, + }, + { + CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, + }, +# ifdef CRYPTO_AES_CTR + { + CRYPTO_AES_CTR, NID_aes_128_ctr, 14, 16, + }, + { + CRYPTO_AES_CTR, NID_aes_192_ctr, 14, 24, + }, + { + CRYPTO_AES_CTR, NID_aes_256_ctr, 14, 32, + }, +# endif + { + CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, + }, + { + CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, + }, + { + CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, + }, + { + 0, NID_undef, 0, 0, + }, +}; + +# ifdef USE_CRYPTODEV_DIGESTS +static struct { + int id; + int nid; + int keylen; +} digests[] = { + { + CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16 + }, + { + CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20 + }, + { + CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16 + /* ? */ + }, + { + CRYPTO_MD5_KPDK, NID_undef, 0 + }, + { + CRYPTO_SHA1_KPDK, NID_undef, 0 + }, + { + CRYPTO_MD5, NID_md5, 16 + }, + { + CRYPTO_SHA1, NID_sha1, 20 + }, + { + 0, NID_undef, 0 + }, +}; +# endif + +/* + * Return a fd if /dev/crypto seems usable, 0 otherwise. + */ +static int open_dev_crypto(void) +{ + static int fd = -1; + + if (fd == -1) { + if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) + return (-1); + /* close on exec */ + if (fcntl(fd, F_SETFD, 1) == -1) { + close(fd); + fd = -1; + return (-1); + } + } + return (fd); +} + +static int get_dev_crypto(void) +{ + int fd, retfd; + + if ((fd = open_dev_crypto()) == -1) + return (-1); +# ifndef CRIOGET_NOT_NEEDED + if (ioctl(fd, CRIOGET, &retfd) == -1) + return (-1); + + /* close on exec */ + if (fcntl(retfd, F_SETFD, 1) == -1) { + close(retfd); + return (-1); + } +# else + retfd = fd; +# endif + return (retfd); +} + +static void put_dev_crypto(int fd) +{ +# ifndef CRIOGET_NOT_NEEDED + close(fd); +# endif +} + +/* Caching version for asym operations */ +static int get_asym_dev_crypto(void) +{ + static int fd = -1; + + if (fd == -1) + fd = get_dev_crypto(); + return fd; +} + +/* + * Find out what ciphers /dev/crypto will let us have a session for. + * XXX note, that some of these openssl doesn't deal with yet! + * returning them here is harmless, as long as we return NULL + * when asked for a handler in the cryptodev_engine_ciphers routine + */ +static int get_cryptodev_ciphers(const int **cnids) +{ + static int nids[CRYPTO_ALGORITHM_MAX]; + struct session_op sess; + int fd, i, count = 0; + + if ((fd = get_dev_crypto()) < 0) { + *cnids = NULL; + return (0); + } + memset(&sess, 0, sizeof(sess)); + sess.key = (caddr_t) "123456789abcdefghijklmno"; + + for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { + if (ciphers[i].nid == NID_undef) + continue; + sess.cipher = ciphers[i].id; + sess.keylen = ciphers[i].keylen; + sess.mac = 0; + if (ioctl(fd, CIOCGSESSION, &sess) != -1 && + ioctl(fd, CIOCFSESSION, &sess.ses) != -1) + nids[count++] = ciphers[i].nid; + } + put_dev_crypto(fd); + + if (count > 0) + *cnids = nids; + else + *cnids = NULL; + return (count); +} + +# ifdef USE_CRYPTODEV_DIGESTS +/* + * Find out what digests /dev/crypto will let us have a session for. + * XXX note, that some of these openssl doesn't deal with yet! + * returning them here is harmless, as long as we return NULL + * when asked for a handler in the cryptodev_engine_digests routine + */ +static int get_cryptodev_digests(const int **cnids) +{ + static int nids[CRYPTO_ALGORITHM_MAX]; + struct session_op sess; + int fd, i, count = 0; + + if ((fd = get_dev_crypto()) < 0) { + *cnids = NULL; + return (0); + } + memset(&sess, 0, sizeof(sess)); + sess.mackey = (caddr_t) "123456789abcdefghijklmno"; + for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { + if (digests[i].nid == NID_undef) + continue; + sess.mac = digests[i].id; + sess.mackeylen = digests[i].keylen; + sess.cipher = 0; + if (ioctl(fd, CIOCGSESSION, &sess) != -1 && + ioctl(fd, CIOCFSESSION, &sess.ses) != -1) + nids[count++] = digests[i].nid; + } + put_dev_crypto(fd); + + if (count > 0) + *cnids = nids; + else + *cnids = NULL; + return (count); +} +# endif /* 0 */ + +/* + * Find the useable ciphers|digests from dev/crypto - this is the first + * thing called by the engine init crud which determines what it + * can use for ciphers from this engine. We want to return + * only what we can do, anythine else is handled by software. + * + * If we can't initialize the device to do anything useful for + * any reason, we want to return a NULL array, and 0 length, + * which forces everything to be done is software. By putting + * the initalization of the device in here, we ensure we can + * use this engine as the default, and if for whatever reason + * /dev/crypto won't do what we want it will just be done in + * software + * + * This can (should) be greatly expanded to perhaps take into + * account speed of the device, and what we want to do. + * (although the disabling of particular alg's could be controlled + * by the device driver with sysctl's.) - this is where we + * want most of the decisions made about what we actually want + * to use from /dev/crypto. + */ +static int cryptodev_usable_ciphers(const int **nids) +{ + return (get_cryptodev_ciphers(nids)); +} + +static int cryptodev_usable_digests(const int **nids) +{ +# ifdef USE_CRYPTODEV_DIGESTS + return (get_cryptodev_digests(nids)); +# else + /* + * XXXX just disable all digests for now, because it sucks. + * we need a better way to decide this - i.e. I may not + * want digests on slow cards like hifn on fast machines, + * but might want them on slow or loaded machines, etc. + * will also want them when using crypto cards that don't + * suck moose gonads - would be nice to be able to decide something + * as reasonable default without having hackery that's card dependent. + * of course, the default should probably be just do everything, + * with perhaps a sysctl to turn algoritms off (or have them off + * by default) on cards that generally suck like the hifn. + */ + *nids = NULL; + return (0); +# endif +} + +static int +cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->cipher_data; + struct session_op *sess = &state->d_sess; + const void *iiv; + unsigned char save_iv[EVP_MAX_IV_LENGTH]; + + if (state->d_fd < 0) + return (0); + if (!inl) + return (1); + if ((inl % ctx->cipher->block_size) != 0) + return (0); + + memset(&cryp, 0, sizeof(cryp)); + + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = inl; + cryp.src = (caddr_t) in; + cryp.dst = (caddr_t) out; + cryp.mac = 0; + + cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; + + if (ctx->cipher->iv_len) { + cryp.iv = (caddr_t) ctx->iv; + if (!ctx->encrypt) { + iiv = in + inl - ctx->cipher->iv_len; + memcpy(save_iv, iiv, ctx->cipher->iv_len); + } + } else + cryp.iv = NULL; + + if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { + /* + * XXX need better errror handling this can fail for a number of + * different reasons. + */ + return (0); + } + + if (ctx->cipher->iv_len) { + if (ctx->encrypt) + iiv = out + inl - ctx->cipher->iv_len; + else + iiv = save_iv; + memcpy(ctx->iv, iiv, ctx->cipher->iv_len); + } + return (1); +} + +static int +cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + struct dev_crypto_state *state = ctx->cipher_data; + struct session_op *sess = &state->d_sess; + int cipher = -1, i; + + for (i = 0; ciphers[i].id; i++) + if (ctx->cipher->nid == ciphers[i].nid && + ctx->cipher->iv_len <= ciphers[i].ivmax && + ctx->key_len == ciphers[i].keylen) { + cipher = ciphers[i].id; + break; + } + + if (!ciphers[i].id) { + state->d_fd = -1; + return (0); + } + + memset(sess, 0, sizeof(struct session_op)); + + if ((state->d_fd = get_dev_crypto()) < 0) + return (0); + + sess->key = (caddr_t) key; + sess->keylen = ctx->key_len; + sess->cipher = cipher; + + if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { + put_dev_crypto(state->d_fd); + state->d_fd = -1; + return (0); + } + return (1); +} + +/* + * free anything we allocated earlier when initting a + * session, and close the session. + */ +static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx) +{ + int ret = 0; + struct dev_crypto_state *state = ctx->cipher_data; + struct session_op *sess = &state->d_sess; + + if (state->d_fd < 0) + return (0); + + /* + * XXX if this ioctl fails, someting's wrong. the invoker may have called + * us with a bogus ctx, or we could have a device that for whatever + * reason just doesn't want to play ball - it's not clear what's right + * here - should this be an error? should it just increase a counter, + * hmm. For right now, we return 0 - I don't believe that to be "right". + * we could call the gorpy openssl lib error handlers that print messages + * to users of the library. hmm.. + */ + + if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { + ret = 0; + } else { + ret = 1; + } + put_dev_crypto(state->d_fd); + state->d_fd = -1; + + return (ret); +} + +/* + * libcrypto EVP stuff - this is how we get wired to EVP so the engine + * gets called when libcrypto requests a cipher NID. + */ + +/* RC4 */ +const EVP_CIPHER cryptodev_rc4 = { + NID_rc4, + 1, 16, 0, + EVP_CIPH_VARIABLE_LENGTH, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + NULL, + NULL, + NULL +}; + +/* DES CBC EVP */ +const EVP_CIPHER cryptodev_des_cbc = { + NID_des_cbc, + 8, 8, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +/* 3DES CBC EVP */ +const EVP_CIPHER cryptodev_3des_cbc = { + NID_des_ede3_cbc, + 8, 24, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_bf_cbc = { + NID_bf_cbc, + 8, 16, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_cast_cbc = { + NID_cast5_cbc, + 8, 16, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_cbc = { + NID_aes_128_cbc, + 16, 16, 16, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_192_cbc = { + NID_aes_192_cbc, + 16, 24, 16, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_256_cbc = { + NID_aes_256_cbc, + 16, 32, 16, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +# ifdef CRYPTO_AES_CTR +const EVP_CIPHER cryptodev_aes_ctr = { + NID_aes_128_ctr, + 16, 16, 14, + EVP_CIPH_CTR_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_ctr_192 = { + NID_aes_192_ctr, + 16, 24, 14, + EVP_CIPH_CTR_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_ctr_256 = { + NID_aes_256_ctr, + 16, 32, 14, + EVP_CIPH_CTR_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; +# endif +/* + * Registered by the ENGINE when used to find out how to deal with + * a particular NID in the ENGINE. this says what we'll do at the + * top level - note, that list is restricted by what we answer with + */ +static int +cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) +{ + if (!cipher) + return (cryptodev_usable_ciphers(nids)); + + switch (nid) { + case NID_rc4: + *cipher = &cryptodev_rc4; + break; + case NID_des_ede3_cbc: + *cipher = &cryptodev_3des_cbc; + break; + case NID_des_cbc: + *cipher = &cryptodev_des_cbc; + break; + case NID_bf_cbc: + *cipher = &cryptodev_bf_cbc; + break; + case NID_cast5_cbc: + *cipher = &cryptodev_cast_cbc; + break; + case NID_aes_128_cbc: + *cipher = &cryptodev_aes_cbc; + break; + case NID_aes_192_cbc: + *cipher = &cryptodev_aes_192_cbc; + break; + case NID_aes_256_cbc: + *cipher = &cryptodev_aes_256_cbc; + break; +# ifdef CRYPTO_AES_CTR + case NID_aes_128_ctr: + *cipher = &cryptodev_aes_ctr; + break; + case NID_aes_192_ctr: + *cipher = &cryptodev_aes_ctr_192; + break; + case NID_aes_256_ctr: + *cipher = &cryptodev_aes_ctr_256; + break; +# endif + default: + *cipher = NULL; + break; + } + return (*cipher != NULL); +} + +# ifdef USE_CRYPTODEV_DIGESTS + +/* convert digest type to cryptodev */ +static int digest_nid_to_cryptodev(int nid) +{ + int i; + + for (i = 0; digests[i].id; i++) + if (digests[i].nid == nid) + return (digests[i].id); + return (0); +} + +static int digest_key_length(int nid) +{ + int i; + + for (i = 0; digests[i].id; i++) + if (digests[i].nid == nid) + return digests[i].keylen; + return (0); +} + +static int cryptodev_digest_init(EVP_MD_CTX *ctx) +{ + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + int digest; + + if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef) { + printf("cryptodev_digest_init: Can't get digest \n"); + return (0); + } + + memset(state, 0, sizeof(struct dev_crypto_state)); + + if ((state->d_fd = get_dev_crypto()) < 0) { + printf("cryptodev_digest_init: Can't get Dev \n"); + return (0); + } + + sess->mackey = state->dummy_mac_key; + sess->mackeylen = digest_key_length(ctx->digest->type); + sess->mac = digest; + + if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { + put_dev_crypto(state->d_fd); + state->d_fd = -1; + printf("cryptodev_digest_init: Open session failed\n"); + return (0); + } + + return (1); +} + +static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, + size_t count) +{ + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + if (!data || state->d_fd < 0) { + printf("cryptodev_digest_update: illegal inputs \n"); + return (0); + } + + if (!count) { + return (0); + } + + if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { + /* if application doesn't support one buffer */ + char *mac_data = + OPENSSL_realloc(state->mac_data, state->mac_len + count); + + if (mac_data == NULL) { + printf("cryptodev_digest_update: realloc failed\n"); + return (0); + } + + state->mac_data = mac_data; + memcpy(state->mac_data + state->mac_len, data, count); + state->mac_len += count; + + return (1); + } + + memset(&cryp, 0, sizeof(cryp)); + + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = count; + cryp.src = (caddr_t) data; + cryp.dst = NULL; + cryp.mac = (caddr_t) state->digest_res; + if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { + printf("cryptodev_digest_update: digest failed\n"); + return (0); + } + return (1); +} + +static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + int ret = 1; + + if (!md || state->d_fd < 0) { + printf("cryptodev_digest_final: illegal input\n"); + return (0); + } + + if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { + /* if application doesn't support one buffer */ + memset(&cryp, 0, sizeof(cryp)); + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = state->mac_len; + cryp.src = state->mac_data; + cryp.dst = NULL; + cryp.mac = (caddr_t) md; + if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { + printf("cryptodev_digest_final: digest failed\n"); + return (0); + } + + return 1; + } + + memcpy(md, state->digest_res, ctx->digest->md_size); + + return (ret); +} + +static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) +{ + int ret = 1; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + if (state == NULL) + return 0; + + if (state->d_fd < 0) { + printf("cryptodev_digest_cleanup: illegal input\n"); + return (0); + } + + if (state->mac_data) { + OPENSSL_free(state->mac_data); + state->mac_data = NULL; + state->mac_len = 0; + } + + if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { + printf("cryptodev_digest_cleanup: failed to close session\n"); + ret = 0; + } else { + ret = 1; + } + put_dev_crypto(state->d_fd); + state->d_fd = -1; + + return (ret); +} + +static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +{ + struct dev_crypto_state *fstate = from->md_data; + struct dev_crypto_state *dstate = to->md_data; + struct session_op *sess; + int digest; + + if (dstate == NULL || fstate == NULL) + return 1; + + memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); + + sess = &dstate->d_sess; + + digest = digest_nid_to_cryptodev(to->digest->type); + + sess->mackey = dstate->dummy_mac_key; + sess->mackeylen = digest_key_length(to->digest->type); + sess->mac = digest; + + dstate->d_fd = get_dev_crypto(); + + if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) { + put_dev_crypto(dstate->d_fd); + dstate->d_fd = -1; + printf("cryptodev_digest_init: Open session failed\n"); + return (0); + } + + dstate->mac_len = fstate->mac_len; + if (fstate->mac_len != 0) { + if (fstate->mac_data != NULL) { + dstate->mac_data = OPENSSL_malloc(fstate->mac_len); + if (dstate->mac_data == NULL) { + printf("cryptodev_digest_init: malloc failed\n"); + return 0; + } + memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); + } + } + + return 1; +} + +const EVP_MD cryptodev_sha1 = { + NID_sha1, + NID_undef, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_ONESHOT, + cryptodev_digest_init, + cryptodev_digest_update, + cryptodev_digest_final, + cryptodev_digest_copy, + cryptodev_digest_cleanup, + EVP_PKEY_NULL_method, + SHA_CBLOCK, + sizeof(struct dev_crypto_state), +}; + +const EVP_MD cryptodev_md5 = { + NID_md5, + NID_undef, + 16 /* MD5_DIGEST_LENGTH */ , + EVP_MD_FLAG_ONESHOT, + cryptodev_digest_init, + cryptodev_digest_update, + cryptodev_digest_final, + cryptodev_digest_copy, + cryptodev_digest_cleanup, + EVP_PKEY_NULL_method, + 64 /* MD5_CBLOCK */ , + sizeof(struct dev_crypto_state), +}; + +# endif /* USE_CRYPTODEV_DIGESTS */ + +static int +cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) +{ + if (!digest) + return (cryptodev_usable_digests(nids)); + + switch (nid) { +# ifdef USE_CRYPTODEV_DIGESTS + case NID_md5: + *digest = &cryptodev_md5; + break; + case NID_sha1: + *digest = &cryptodev_sha1; + break; + default: +# endif /* USE_CRYPTODEV_DIGESTS */ + *digest = NULL; + break; + } + return (*digest != NULL); +} + +/* + * Convert a BIGNUM to the representation that /dev/crypto needs. + * Upon completion of use, the caller is responsible for freeing + * crp->crp_p. + */ +static int bn2crparam(const BIGNUM *a, struct crparam *crp) +{ + int i, j, k; + ssize_t bytes, bits; + u_char *b; + + crp->crp_p = NULL; + crp->crp_nbits = 0; + + bits = BN_num_bits(a); + bytes = (bits + 7) / 8; + + b = malloc(bytes); + if (b == NULL) + return (1); + memset(b, 0, bytes); + + crp->crp_p = (caddr_t) b; + crp->crp_nbits = bits; + + for (i = 0, j = 0; i < a->top; i++) { + for (k = 0; k < BN_BITS2 / 8; k++) { + if ((j + k) >= bytes) + return (0); + b[j + k] = a->d[i] >> (k * 8); + } + j += BN_BITS2 / 8; + } + return (0); +} + +/* Convert a /dev/crypto parameter to a BIGNUM */ +static int crparam2bn(struct crparam *crp, BIGNUM *a) +{ + u_int8_t *pd; + int i, bytes; + + bytes = (crp->crp_nbits + 7) / 8; + + if (bytes == 0) + return (-1); + + if ((pd = (u_int8_t *) malloc(bytes)) == NULL) + return (-1); + + for (i = 0; i < bytes; i++) + pd[i] = ((char *)crp->crp_p)[bytes - i - 1]; + + BN_bin2bn(pd, bytes, a); + free(pd); + + return (0); +} + +static void zapparams(struct crypt_kop *kop) +{ + int i; + + for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { + OPENSSL_free(kop->crk_param[i].crp_p); + kop->crk_param[i].crp_p = NULL; + kop->crk_param[i].crp_nbits = 0; + } +} + +static int +cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, + BIGNUM *s) +{ + int fd, ret = -1; + + if ((fd = get_asym_dev_crypto()) < 0) + return ret; + + if (r) { + kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_malloc(rlen); + if (kop->crk_param[kop->crk_iparams].crp_p == NULL) + return ret; + memset(kop->crk_param[kop->crk_iparams].crp_p, 0, (size_t)rlen); + kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; + kop->crk_oparams++; + } + if (s) { + kop->crk_param[kop->crk_iparams + 1].crp_p = OPENSSL_malloc(slen); + /* No need to free the kop->crk_iparams parameter if it was allocated, + * callers of this routine have to free allocated parameters through + * zapparams both in case of success and failure + */ + if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL) + return ret; + memset(kop->crk_param[kop->crk_iparams + 1].crp_p, 0, (size_t)slen); + kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8; + kop->crk_oparams++; + } + + if (ioctl(fd, CIOCKEY, kop) == 0) { + if (r) + crparam2bn(&kop->crk_param[kop->crk_iparams], r); + if (s) + crparam2bn(&kop->crk_param[kop->crk_iparams + 1], s); + ret = 0; + } + + return ret; +} + +static int +cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + struct crypt_kop kop; + int ret = 1; + + /* + * Currently, we know we can do mod exp iff we can do any asymmetric + * operations at all. + */ + if (cryptodev_asymfeat == 0) { + ret = BN_mod_exp(r, a, p, m, ctx); + return (ret); + } + + memset(&kop, 0, sizeof(kop)); + kop.crk_op = CRK_MOD_EXP; + + /* inputs: a^p % m */ + if (bn2crparam(a, &kop.crk_param[0])) + goto err; + if (bn2crparam(p, &kop.crk_param[1])) + goto err; + if (bn2crparam(m, &kop.crk_param[2])) + goto err; + kop.crk_iparams = 3; + + if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF asym process failed, Running in software\n"); + ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); + + } else if (ECANCELED == kop.crk_status) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF hardware operation cancelled. Running in Software\n"); + ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); + } + /* else cryptodev operation worked ok ==> ret = 1 */ + + err: + zapparams(&kop); + return (ret); +} + +static int +cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + int r; + ctx = BN_CTX_new(); + r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); + BN_CTX_free(ctx); + return (r); +} + +static int +cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) +{ + struct crypt_kop kop; + int ret = 1; + + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { + /* XXX 0 means failure?? */ + return (0); + } + + memset(&kop, 0, sizeof(kop)); + kop.crk_op = CRK_MOD_EXP_CRT; + /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ + if (bn2crparam(rsa->p, &kop.crk_param[0])) + goto err; + if (bn2crparam(rsa->q, &kop.crk_param[1])) + goto err; + if (bn2crparam(I, &kop.crk_param[2])) + goto err; + if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) + goto err; + if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) + goto err; + if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) + goto err; + kop.crk_iparams = 6; + + if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF asym process failed, running in Software\n"); + ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); + + } else if (ECANCELED == kop.crk_status) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF hardware operation cancelled. Running in Software\n"); + ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); + } + /* else cryptodev operation worked ok ==> ret = 1 */ + + err: + zapparams(&kop); + return (ret); +} + +static RSA_METHOD cryptodev_rsa = { + "cryptodev RSA method", + NULL, /* rsa_pub_enc */ + NULL, /* rsa_pub_dec */ + NULL, /* rsa_priv_enc */ + NULL, /* rsa_priv_dec */ + NULL, + NULL, + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* rsa_sign */ + NULL /* rsa_verify */ +}; + +static int +cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); +} + +static int +cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, + BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, + BN_CTX *ctx, BN_MONT_CTX *mont) +{ + BIGNUM t2; + int ret = 0; + + BN_init(&t2); + + /* v = ( g^u1 * y^u2 mod p ) mod q */ + /* let t1 = g ^ u1 mod p */ + ret = 0; + + if (!dsa->meth->bn_mod_exp(dsa, t1, dsa->g, u1, dsa->p, ctx, mont)) + goto err; + + /* let t2 = y ^ u2 mod p */ + if (!dsa->meth->bn_mod_exp(dsa, &t2, dsa->pub_key, u2, dsa->p, ctx, mont)) + goto err; + /* let u1 = t1 * t2 mod p */ + if (!BN_mod_mul(u1, t1, &t2, dsa->p, ctx)) + goto err; + + BN_copy(t1, u1); + + ret = 1; + err: + BN_free(&t2); + return (ret); +} + +static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, + DSA *dsa) +{ + struct crypt_kop kop; + BIGNUM *r = NULL, *s = NULL; + DSA_SIG *dsaret = NULL; + + if ((r = BN_new()) == NULL) + goto err; + if ((s = BN_new()) == NULL) { + BN_free(r); + goto err; + } + + memset(&kop, 0, sizeof(kop)); + kop.crk_op = CRK_DSA_SIGN; + + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ + kop.crk_param[0].crp_p = (caddr_t) dgst; + kop.crk_param[0].crp_nbits = dlen * 8; + if (bn2crparam(dsa->p, &kop.crk_param[1])) + goto err; + if (bn2crparam(dsa->q, &kop.crk_param[2])) + goto err; + if (bn2crparam(dsa->g, &kop.crk_param[3])) + goto err; + if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) + goto err; + kop.crk_iparams = 5; + + if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, + BN_num_bytes(dsa->q), s) == 0) { + dsaret = DSA_SIG_new(); + if (dsaret == NULL) + goto err; + dsaret->r = r; + dsaret->s = s; + r = s = NULL; + } else { + const DSA_METHOD *meth = DSA_OpenSSL(); + dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa); + } + err: + BN_free(r); + BN_free(s); + kop.crk_param[0].crp_p = NULL; + zapparams(&kop); + return (dsaret); +} + +static int +cryptodev_dsa_verify(const unsigned char *dgst, int dlen, + DSA_SIG *sig, DSA *dsa) +{ + struct crypt_kop kop; + int dsaret = 1; + + memset(&kop, 0, sizeof(kop)); + kop.crk_op = CRK_DSA_VERIFY; + + /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ + kop.crk_param[0].crp_p = (caddr_t) dgst; + kop.crk_param[0].crp_nbits = dlen * 8; + if (bn2crparam(dsa->p, &kop.crk_param[1])) + goto err; + if (bn2crparam(dsa->q, &kop.crk_param[2])) + goto err; + if (bn2crparam(dsa->g, &kop.crk_param[3])) + goto err; + if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) + goto err; + if (bn2crparam(sig->r, &kop.crk_param[5])) + goto err; + if (bn2crparam(sig->s, &kop.crk_param[6])) + goto err; + kop.crk_iparams = 7; + + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { + /* + * OCF success value is 0, if not zero, change dsaret to fail + */ + if (0 != kop.crk_status) + dsaret = 0; + } else { + const DSA_METHOD *meth = DSA_OpenSSL(); + + dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa); + } + err: + kop.crk_param[0].crp_p = NULL; + zapparams(&kop); + return (dsaret); +} + +static DSA_METHOD cryptodev_dsa = { + "cryptodev DSA method", + NULL, + NULL, /* dsa_sign_setup */ + NULL, + NULL, /* dsa_mod_exp */ + NULL, + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL /* app_data */ +}; + +static int +cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); +} + +static int +cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + struct crypt_kop kop; + int dhret = 1; + int fd, keylen; + + if ((fd = get_asym_dev_crypto()) < 0) { + const DH_METHOD *meth = DH_OpenSSL(); + + return ((meth->compute_key) (key, pub_key, dh)); + } + + keylen = BN_num_bits(dh->p); + + memset(&kop, 0, sizeof(kop)); + kop.crk_op = CRK_DH_COMPUTE_KEY; + + /* inputs: dh->priv_key pub_key dh->p key */ + if (bn2crparam(dh->priv_key, &kop.crk_param[0])) + goto err; + if (bn2crparam(pub_key, &kop.crk_param[1])) + goto err; + if (bn2crparam(dh->p, &kop.crk_param[2])) + goto err; + kop.crk_iparams = 3; + + kop.crk_param[3].crp_p = (caddr_t) key; + kop.crk_param[3].crp_nbits = keylen * 8; + kop.crk_oparams = 1; + + if (ioctl(fd, CIOCKEY, &kop) == -1) { + const DH_METHOD *meth = DH_OpenSSL(); + + dhret = (meth->compute_key) (key, pub_key, dh); + } + err: + kop.crk_param[3].crp_p = NULL; + zapparams(&kop); + return (dhret); +} + +static DH_METHOD cryptodev_dh = { + "cryptodev DH method", + NULL, /* cryptodev_dh_generate_key */ + NULL, + NULL, + NULL, + NULL, + 0, /* flags */ + NULL /* app_data */ +}; + +/* + * ctrl right now is just a wrapper that doesn't do much + * but I expect we'll want some options soon. + */ +static int +cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ +# ifdef HAVE_SYSLOG_R + struct syslog_data sd = SYSLOG_DATA_INIT; +# endif + + switch (cmd) { + default: +# ifdef HAVE_SYSLOG_R + syslog_r(LOG_ERR, &sd, "cryptodev_ctrl: unknown command %d", cmd); +# else + syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd); +# endif + break; + } + return (1); +} + +void ENGINE_load_cryptodev(void) +{ + ENGINE *engine = ENGINE_new(); + int fd; + + if (engine == NULL) + return; + if ((fd = get_dev_crypto()) < 0) { + ENGINE_free(engine); + return; + } + + /* + * find out what asymmetric crypto algorithms we support + */ + if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { + put_dev_crypto(fd); + ENGINE_free(engine); + return; + } + put_dev_crypto(fd); + + if (!ENGINE_set_id(engine, "cryptodev") || + !ENGINE_set_name(engine, "BSD cryptodev engine") || + !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || + !ENGINE_set_digests(engine, cryptodev_engine_digests) || + !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || + !ENGINE_set_cmd_defns(engine, cryptodev_defns)) { + ENGINE_free(engine); + return; + } + + if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { + const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); + + cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; + cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; + cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; + cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; + cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; + cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; + if (cryptodev_asymfeat & CRF_MOD_EXP) { + cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; + if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) + cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_mod_exp; + else + cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_nocrt_mod_exp; + } + } + + if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { + const DSA_METHOD *meth = DSA_OpenSSL(); + + memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); + if (cryptodev_asymfeat & CRF_DSA_SIGN) + cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; + if (cryptodev_asymfeat & CRF_MOD_EXP) { + cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; + cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; + } + if (cryptodev_asymfeat & CRF_DSA_VERIFY) + cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; + } + + if (ENGINE_set_DH(engine, &cryptodev_dh)) { + const DH_METHOD *dh_meth = DH_OpenSSL(); + + cryptodev_dh.generate_key = dh_meth->generate_key; + cryptodev_dh.compute_key = dh_meth->compute_key; + cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; + if (cryptodev_asymfeat & CRF_MOD_EXP) { + cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) + cryptodev_dh.compute_key = cryptodev_dh_compute_key; + } + } + + ENGINE_add(engine); + ENGINE_free(engine); + ERR_clear_error(); +} + +#endif /* HAVE_CRYPTODEV */ +/* crypto/engine/eng_ctrl.c */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "eng_int.h" + +/* + * When querying a ENGINE-specific control command's 'description', this + * string is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. + */ +static const char *int_no_description = ""; + +/* + * These internal functions handle 'CMD'-related control commands when the + * ENGINE in question has asked us to take care of it (ie. the ENGINE did not + * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. + */ + +static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn) +{ + if ((defn->cmd_num == 0) || (defn->cmd_name == NULL)) + return 1; + return 0; +} + +static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s) +{ + int idx = 0; + while (!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0)) { + idx++; + defn++; + } + if (int_ctrl_cmd_is_null(defn)) + /* The given name wasn't found */ + return -1; + return idx; +} + +static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num) +{ + int idx = 0; + /* + * NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So + * our searches don't need to take any longer than necessary. + */ + while (!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) { + idx++; + defn++; + } + if (defn->cmd_num == num) + return idx; + /* The given cmd_num wasn't found */ + return -1; +} + +static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)) +{ + int idx; + char *s = (char *)p; + /* Take care of the easy one first (eg. it requires no searches) */ + if (cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) { + if ((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns)) + return 0; + return e->cmd_defns->cmd_num; + } + /* One or two commands require that "p" be a valid string buffer */ + if ((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) || + (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) || + (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) { + if (s == NULL) { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + } + /* Now handle cmd_name -> cmd_num conversion */ + if (cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) { + if ((e->cmd_defns == NULL) + || ((idx = int_ctrl_cmd_by_name(e->cmd_defns, s)) < 0)) { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NAME); + return -1; + } + return e->cmd_defns[idx].cmd_num; + } + /* + * For the rest of the commands, the 'long' argument must specify a valie + * command number - so we need to conduct a search. + */ + if ((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns, + (unsigned int) + i)) < 0)) { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NUMBER); + return -1; + } + /* Now the logic splits depending on command type */ + switch (cmd) { + case ENGINE_CTRL_GET_NEXT_CMD_TYPE: + idx++; + if (int_ctrl_cmd_is_null(e->cmd_defns + idx)) + /* end-of-list */ + return 0; + else + return e->cmd_defns[idx].cmd_num; + case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: + return strlen(e->cmd_defns[idx].cmd_name); + case ENGINE_CTRL_GET_NAME_FROM_CMD: + return BIO_snprintf(s, strlen(e->cmd_defns[idx].cmd_name) + 1, + "%s", e->cmd_defns[idx].cmd_name); + case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: + if (e->cmd_defns[idx].cmd_desc) + return strlen(e->cmd_defns[idx].cmd_desc); + return strlen(int_no_description); + case ENGINE_CTRL_GET_DESC_FROM_CMD: + if (e->cmd_defns[idx].cmd_desc) + return BIO_snprintf(s, + strlen(e->cmd_defns[idx].cmd_desc) + 1, + "%s", e->cmd_defns[idx].cmd_desc); + return BIO_snprintf(s, strlen(int_no_description) + 1, "%s", + int_no_description); + case ENGINE_CTRL_GET_CMD_FLAGS: + return e->cmd_defns[idx].cmd_flags; + } + /* Shouldn't really be here ... */ + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INTERNAL_LIST_ERROR); + return -1; +} + +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int ctrl_exists, ref_exists; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ref_exists = ((e->struct_ref > 0) ? 1 : 0); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); + if (!ref_exists) { + ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_REFERENCE); + return 0; + } + /* + * Intercept any "root-level" commands before trying to hand them on to + * ctrl() handlers. + */ + switch (cmd) { + case ENGINE_CTRL_HAS_CTRL_FUNCTION: + return ctrl_exists; + case ENGINE_CTRL_GET_FIRST_CMD_TYPE: + case ENGINE_CTRL_GET_NEXT_CMD_TYPE: + case ENGINE_CTRL_GET_CMD_FROM_NAME: + case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: + case ENGINE_CTRL_GET_NAME_FROM_CMD: + case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: + case ENGINE_CTRL_GET_DESC_FROM_CMD: + case ENGINE_CTRL_GET_CMD_FLAGS: + if (ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL)) + return int_ctrl_helper(e, cmd, i, p, f); + if (!ctrl_exists) { + ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION); + /* + * For these cmd-related functions, failure is indicated by a -1 + * return value (because 0 is used as a valid return in some + * places). + */ + return -1; + } + default: + break; + } + /* Anything else requires a ctrl() handler to exist. */ + if (!ctrl_exists) { + ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION); + return 0; + } + return e->ctrl(e, cmd, i, p, f); +} + +int ENGINE_cmd_is_executable(ENGINE *e, int cmd) +{ + int flags; + if ((flags = + ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) { + ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, + ENGINE_R_INVALID_CMD_NUMBER); + return 0; + } + if (!(flags & ENGINE_CMD_FLAG_NO_INPUT) && + !(flags & ENGINE_CMD_FLAG_NUMERIC) && + !(flags & ENGINE_CMD_FLAG_STRING)) + return 0; + return 1; +} + +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f) (void), int cmd_optional) +{ + int num; + + if ((e == NULL) || (cmd_name == NULL)) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, + ENGINE_CTRL_GET_CMD_FROM_NAME, + 0, (void *)cmd_name, + NULL)) <= 0)) { + /* + * If the command didn't *have* to be supported, we fake success. + * This allows certain settings to be specified for multiple ENGINEs + * and only require a change of ENGINE id (without having to + * selectively apply settings). Eg. changing from a hardware device + * back to the regular software ENGINE without editing the config + * file, etc. + */ + if (cmd_optional) { + ERR_clear_error(); + return 1; + } + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ENGINE_R_INVALID_CMD_NAME); + return 0; + } + /* + * Force the result of the control command to 0 or 1, for the reasons + * mentioned before. + */ + if (ENGINE_ctrl(e, num, i, p, f) > 0) + return 1; + return 0; +} + +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional) +{ + int num, flags; + long l; + char *ptr; + if ((e == NULL) || (cmd_name == NULL)) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, + ENGINE_CTRL_GET_CMD_FROM_NAME, + 0, (void *)cmd_name, + NULL)) <= 0)) { + /* + * If the command didn't *have* to be supported, we fake success. + * This allows certain settings to be specified for multiple ENGINEs + * and only require a change of ENGINE id (without having to + * selectively apply settings). Eg. changing from a hardware device + * back to the regular software ENGINE without editing the config + * file, etc. + */ + if (cmd_optional) { + ERR_clear_error(); + return 1; + } + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ENGINE_R_INVALID_CMD_NAME); + return 0; + } + if (!ENGINE_cmd_is_executable(e, num)) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_CMD_NOT_EXECUTABLE); + return 0; + } + if ((flags = + ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0) { + /* + * Shouldn't happen, given that ENGINE_cmd_is_executable() returned + * success. + */ + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + /* + * If the command takes no input, there must be no input. And vice versa. + */ + if (flags & ENGINE_CMD_FLAG_NO_INPUT) { + if (arg != NULL) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_COMMAND_TAKES_NO_INPUT); + return 0; + } + /* + * We deliberately force the result of ENGINE_ctrl() to 0 or 1 rather + * than returning it as "return data". This is to ensure usage of + * these commands is consistent across applications and that certain + * applications don't understand it one way, and others another. + */ + if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0) + return 1; + return 0; + } + /* So, we require input */ + if (arg == NULL) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_COMMAND_TAKES_INPUT); + return 0; + } + /* If it takes string input, that's easy */ + if (flags & ENGINE_CMD_FLAG_STRING) { + /* Same explanation as above */ + if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0) + return 1; + return 0; + } + /* + * If it doesn't take numeric either, then it is unsupported for use in a + * config-setting situation, which is what this function is for. This + * should never happen though, because ENGINE_cmd_is_executable() was + * used. + */ + if (!(flags & ENGINE_CMD_FLAG_NUMERIC)) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + l = strtol(arg, &ptr, 10); + if ((arg == ptr) || (*ptr != '\0')) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); + return 0; + } + /* + * Force the result of the control command to 0 or 1, for the reasons + * mentioned before. + */ + if (ENGINE_ctrl(e, num, l, NULL, NULL) > 0) + return 1; + return 0; +} +/* crypto/engine/eng_dyn.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "eng_int.h" +#include "dso.h" + +/* + * Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE + * loader should implement the hook-up functions with the following + * prototypes. + */ + +/* Our ENGINE handlers */ +static int dynamic_init(ENGINE *e); +static int dynamic_finish(ENGINE *e); +static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)); +/* Predeclare our context type */ +typedef struct st_dynamic_data_ctx dynamic_data_ctx; +/* The implementation for the important control command */ +static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx); + +#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE +#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) +#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) +#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) +#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4) +#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5) +#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6) + +/* The constants used when creating the ENGINE */ +static const char *engine_dynamic_id = "dynamic"; +static const char *engine_dynamic_name = "Dynamic engine loading support"; +static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = { + {DYNAMIC_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the new ENGINE shared library", + ENGINE_CMD_FLAG_STRING}, + {DYNAMIC_CMD_NO_VCHECK, + "NO_VCHECK", + "Specifies to continue even if version checking fails (boolean)", + ENGINE_CMD_FLAG_NUMERIC}, + {DYNAMIC_CMD_ID, + "ID", + "Specifies an ENGINE id name for loading", + ENGINE_CMD_FLAG_STRING}, + {DYNAMIC_CMD_LIST_ADD, + "LIST_ADD", + "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", + ENGINE_CMD_FLAG_NUMERIC}, + {DYNAMIC_CMD_DIR_LOAD, + "DIR_LOAD", + "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)", + ENGINE_CMD_FLAG_NUMERIC}, + {DYNAMIC_CMD_DIR_ADD, + "DIR_ADD", + "Adds a directory from which ENGINEs can be loaded", + ENGINE_CMD_FLAG_STRING}, + {DYNAMIC_CMD_LOAD, + "LOAD", + "Load up the ENGINE specified by other settings", + ENGINE_CMD_FLAG_NO_INPUT}, + {0, NULL, NULL, 0} +}; + +/* + * Loading code stores state inside the ENGINE structure via the "ex_data" + * element. We load all our state into a single structure and use that as a + * single context in the "ex_data" stack. + */ +struct st_dynamic_data_ctx { + /* The DSO object we load that supplies the ENGINE code */ + DSO *dynamic_dso; + /* + * The function pointer to the version checking shared library function + */ + dynamic_v_check_fn v_check; + /* + * The function pointer to the engine-binding shared library function + */ + dynamic_bind_engine bind_engine; + /* The default name/path for loading the shared library */ + const char *DYNAMIC_LIBNAME; + /* Whether to continue loading on a version check failure */ + int no_vcheck; + /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */ + const char *engine_id; + /* + * If non-zero, a successfully loaded ENGINE should be added to the + * internal ENGINE list. If 2, the add must succeed or the entire load + * should fail. + */ + int list_add_value; + /* The symbol name for the version checking function */ + const char *DYNAMIC_F1; + /* The symbol name for the "initialise ENGINE structure" function */ + const char *DYNAMIC_F2; + /* + * Whether to never use 'dirs', use 'dirs' as a fallback, or only use + * 'dirs' for loading. Default is to use 'dirs' as a fallback. + */ + int dir_load; + /* A stack of directories from which ENGINEs could be loaded */ + STACK_OF(OPENSSL_STRING) *dirs; +}; + +/* + * This is the "ex_data" index we obtain and reserve for use with our context + * structure. + */ +static int dynamic_ex_data_idx = -1; + +static void int_free_str(char *s) +{ + OPENSSL_free(s); +} + +/* + * Because our ex_data element may or may not get allocated depending on + * whether a "first-use" occurs before the ENGINE is freed, we have a memory + * leak problem to solve. We can't declare a "new" handler for the ex_data as + * we don't want a dynamic_data_ctx in *all* ENGINE structures of all types + * (this is a bug in the design of CRYPTO_EX_DATA). As such, we just declare + * a "free" handler and that will get called if an ENGINE is being destroyed + * and there was an ex_data element corresponding to our context type. + */ +static void dynamic_data_ctx_free_func(void *parent, void *ptr, + CRYPTO_EX_DATA *ad, int idx, long argl, + void *argp) +{ + if (ptr) { + dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr; + if (ctx->dynamic_dso) + DSO_free(ctx->dynamic_dso); + if (ctx->DYNAMIC_LIBNAME) + OPENSSL_free((void *)ctx->DYNAMIC_LIBNAME); + if (ctx->engine_id) + OPENSSL_free((void *)ctx->engine_id); + if (ctx->dirs) + sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str); + OPENSSL_free(ctx); + } +} + +/* + * Construct the per-ENGINE context. We create it blindly and then use a lock + * to check for a race - if so, all but one of the threads "racing" will have + * wasted their time. The alternative involves creating everything inside the + * lock which is far worse. + */ +static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) +{ + dynamic_data_ctx *c; + c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); + if (!c) { + ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); + return 0; + } + memset(c, 0, sizeof(dynamic_data_ctx)); + c->dynamic_dso = NULL; + c->v_check = NULL; + c->bind_engine = NULL; + c->DYNAMIC_LIBNAME = NULL; + c->no_vcheck = 0; + c->engine_id = NULL; + c->list_add_value = 0; + c->DYNAMIC_F1 = "v_check"; + c->DYNAMIC_F2 = "bind_engine"; + c->dir_load = 1; + c->dirs = sk_OPENSSL_STRING_new_null(); + if (!c->dirs) { + ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); + OPENSSL_free(c); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, + dynamic_ex_data_idx)) + == NULL) { + /* Good, we're the first */ + ENGINE_set_ex_data(e, dynamic_ex_data_idx, c); + *ctx = c; + c = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* + * If we lost the race to set the context, c is non-NULL and *ctx is the + * context of the thread that won. + */ + if (c) { + sk_OPENSSL_STRING_free(c->dirs); + OPENSSL_free(c); + } + return 1; +} + +/* + * This function retrieves the context structure from an ENGINE's "ex_data", + * or if it doesn't exist yet, sets it up. + */ +static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e) +{ + dynamic_data_ctx *ctx; + if (dynamic_ex_data_idx < 0) { + /* + * Create and register the ENGINE ex_data, and associate our "free" + * function with it to ensure any allocated contexts get freed when + * an ENGINE goes underground. + */ + int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, + dynamic_data_ctx_free_func); + if (new_idx == -1) { + ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX, ENGINE_R_NO_INDEX); + return NULL; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + /* Avoid a race by checking again inside this lock */ + if (dynamic_ex_data_idx < 0) { + /* Good, someone didn't beat us to it */ + dynamic_ex_data_idx = new_idx; + new_idx = -1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* + * In theory we could "give back" the index here if (new_idx>-1), but + * it's not possible and wouldn't gain us much if it were. + */ + } + ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx); + /* Check if the context needs to be created */ + if ((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx)) + /* "set_data" will set errors if necessary */ + return NULL; + return ctx; +} + +static ENGINE *engine_dynamic(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!ENGINE_set_id(ret, engine_dynamic_id) || + !ENGINE_set_name(ret, engine_dynamic_name) || + !ENGINE_set_init_function(ret, dynamic_init) || + !ENGINE_set_finish_function(ret, dynamic_finish) || + !ENGINE_set_ctrl_function(ret, dynamic_ctrl) || + !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) || + !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_dynamic(void) +{ + ENGINE *toadd = engine_dynamic(); + if (!toadd) + return; + ENGINE_add(toadd); + /* + * If the "add" worked, it gets a structural reference. So either way, we + * release our just-created reference. + */ + ENGINE_free(toadd); + /* + * If the "add" didn't work, it was probably a conflict because it was + * already added (eg. someone calling ENGINE_load_blah then calling + * ENGINE_load_builtin_engines() perhaps). + */ + ERR_clear_error(); +} + +static int dynamic_init(ENGINE *e) +{ + /* + * We always return failure - the "dyanamic" engine itself can't be used + * for anything. + */ + return 0; +} + +static int dynamic_finish(ENGINE *e) +{ + /* + * This should never be called on account of "dynamic_init" always + * failing. + */ + return 0; +} + +static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); + int initialised; + + if (!ctx) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_NOT_LOADED); + return 0; + } + initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1); + /* All our control commands require the ENGINE to be uninitialised */ + if (initialised) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_ALREADY_LOADED); + return 0; + } + switch (cmd) { + case DYNAMIC_CMD_SO_PATH: + /* a NULL 'p' or a string of zero-length is the same thing */ + if (p && (strlen((const char *)p) < 1)) + p = NULL; + if (ctx->DYNAMIC_LIBNAME) + OPENSSL_free((void *)ctx->DYNAMIC_LIBNAME); + if (p) + ctx->DYNAMIC_LIBNAME = BUF_strdup(p); + else + ctx->DYNAMIC_LIBNAME = NULL; + return (ctx->DYNAMIC_LIBNAME ? 1 : 0); + case DYNAMIC_CMD_NO_VCHECK: + ctx->no_vcheck = ((i == 0) ? 0 : 1); + return 1; + case DYNAMIC_CMD_ID: + /* a NULL 'p' or a string of zero-length is the same thing */ + if (p && (strlen((const char *)p) < 1)) + p = NULL; + if (ctx->engine_id) + OPENSSL_free((void *)ctx->engine_id); + if (p) + ctx->engine_id = BUF_strdup(p); + else + ctx->engine_id = NULL; + return (ctx->engine_id ? 1 : 0); + case DYNAMIC_CMD_LIST_ADD: + if ((i < 0) || (i > 2)) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + return 0; + } + ctx->list_add_value = (int)i; + return 1; + case DYNAMIC_CMD_LOAD: + return dynamic_load(e, ctx); + case DYNAMIC_CMD_DIR_LOAD: + if ((i < 0) || (i > 2)) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + return 0; + } + ctx->dir_load = (int)i; + return 1; + case DYNAMIC_CMD_DIR_ADD: + /* a NULL 'p' or a string of zero-length is the same thing */ + if (!p || (strlen((const char *)p) < 1)) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + return 0; + } + { + char *tmp_str = BUF_strdup(p); + if (!tmp_str) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE); + return 0; + } + sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1); + } + return 1; + default: + break; + } + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +static int int_load(dynamic_data_ctx *ctx) +{ + int num, loop; + /* Unless told not to, try a direct load */ + if ((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso, + ctx->DYNAMIC_LIBNAME, NULL, + 0)) != NULL) + return 1; + /* If we're not allowed to use 'dirs' or we have none, fail */ + if (!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1) + return 0; + for (loop = 0; loop < num; loop++) { + const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop); + char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s); + if (!merge) + return 0; + if (DSO_load(ctx->dynamic_dso, merge, NULL, 0)) { + /* Found what we're looking for */ + OPENSSL_free(merge); + return 1; + } + OPENSSL_free(merge); + } + return 0; +} + +static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) +{ + ENGINE cpy; + dynamic_fns fns; + + if (!ctx->dynamic_dso) + ctx->dynamic_dso = DSO_new(); + if (!ctx->DYNAMIC_LIBNAME) { + if (!ctx->engine_id) + return 0; + ctx->DYNAMIC_LIBNAME = + DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id); + } + if (!int_load(ctx)) { + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_NOT_FOUND); + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + return 0; + } + /* We have to find a bind function otherwise it'll always end badly */ + if (! + (ctx->bind_engine = + (dynamic_bind_engine) DSO_bind_func(ctx->dynamic_dso, + ctx->DYNAMIC_F2))) { + ctx->bind_engine = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_FAILURE); + return 0; + } + /* Do we perform version checking? */ + if (!ctx->no_vcheck) { + unsigned long vcheck_res = 0; + /* + * Now we try to find a version checking function and decide how to + * cope with failure if/when it fails. + */ + ctx->v_check = + (dynamic_v_check_fn) DSO_bind_func(ctx->dynamic_dso, + ctx->DYNAMIC_F1); + if (ctx->v_check) + vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION); + /* + * We fail if the version checker veto'd the load *or* if it is + * deferring to us (by returning its version) and we think it is too + * old. + */ + if (vcheck_res < OSSL_DYNAMIC_OLDEST) { + /* Fail */ + ctx->bind_engine = NULL; + ctx->v_check = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, + ENGINE_R_VERSION_INCOMPATIBILITY); + return 0; + } + } + /* + * First binary copy the ENGINE structure so that we can roll back if the + * hand-over fails + */ + memcpy(&cpy, e, sizeof(ENGINE)); + /* + * Provide the ERR, "ex_data", memory, and locking callbacks so the + * loaded library uses our state rather than its own. FIXME: As noted in + * engine.h, much of this would be simplified if each area of code + * provided its own "summary" structure of all related callbacks. It + * would also increase opaqueness. + */ + fns.static_state = ENGINE_get_static_state(); + fns.err_fns = ERR_get_implementation(); + fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); + CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, + &fns.mem_fns.realloc_cb, &fns.mem_fns.free_cb); + fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback(); + fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback(); + fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback(); + fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback(); + fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback(); + /* + * Now that we've loaded the dynamic engine, make sure no "dynamic" + * ENGINE elements will show through. + */ + engine_set_all_null(e); + + /* Try to bind the ENGINE onto our own ENGINE structure */ + if (!ctx->bind_engine(e, ctx->engine_id, &fns)) { + ctx->bind_engine = NULL; + ctx->v_check = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED); + /* Copy the original ENGINE structure back */ + memcpy(e, &cpy, sizeof(ENGINE)); + return 0; + } + /* Do we try to add this ENGINE to the internal list too? */ + if (ctx->list_add_value > 0) { + if (!ENGINE_add(e)) { + /* Do we tolerate this or fail? */ + if (ctx->list_add_value > 1) { + /* + * Fail - NB: By this time, it's too late to rollback, and + * trying to do so allows the bind_engine() code to have + * created leaks. We just have to fail where we are, after + * the ENGINE has changed. + */ + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, + ENGINE_R_CONFLICTING_ENGINE_ID); + return 0; + } + /* Tolerate */ + ERR_clear_error(); + } + } + return 1; +} +/* crypto/engine/eng_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "engine.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason) + +static ERR_STRING_DATA ENGINE_str_functs[] = { + {ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"}, + {ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"}, + {ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"}, + {ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "DYNAMIC_SET_DATA_CTX"}, + {ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"}, + {ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"}, + {ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"}, + {ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"}, + {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"}, + {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"}, + {ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"}, + {ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL), "ENGINE_FREE_UTIL"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), + "ENGINE_get_pkey_asn1_meth"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"}, + {ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"}, + {ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"}, + {ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"}, + {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"}, + {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"}, + {ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT), + "ENGINE_load_ssl_client_cert"}, + {ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"}, + {ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"}, + {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), + "ENGINE_set_default_string"}, + {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE), "ENGINE_SET_DEFAULT_TYPE"}, + {ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"}, + {ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"}, + {ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"}, + {ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"}, + {ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "ENGINE_UNLOCKED_FINISH"}, + {ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"}, + {ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"}, + {ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"}, + {ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "INT_ENGINE_MODULE_INIT"}, + {ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"}, + {0, NULL} +}; + +static ERR_STRING_DATA ENGINE_str_reasons[] = { + {ERR_REASON(ENGINE_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER), + "argument is not a number"}, + {ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE), "cmd not executable"}, + {ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT), "command takes input"}, + {ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT), "command takes no input"}, + {ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID), "conflicting engine id"}, + {ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED), "dh not implemented"}, + {ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED), "dsa not implemented"}, + {ERR_REASON(ENGINE_R_DSO_FAILURE), "DSO failure"}, + {ERR_REASON(ENGINE_R_DSO_NOT_FOUND), "dso not found"}, + {ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR), "engines section error"}, + {ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR), + "engine configuration error"}, + {ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST), "engine is not in the list"}, + {ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR), "engine section error"}, + {ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY), + "failed loading private key"}, + {ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY), + "failed loading public key"}, + {ERR_REASON(ENGINE_R_FINISH_FAILED), "finish failed"}, + {ERR_REASON(ENGINE_R_GET_HANDLE_FAILED), + "could not obtain hardware handle"}, + {ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING), "'id' or 'name' missing"}, + {ERR_REASON(ENGINE_R_INIT_FAILED), "init failed"}, + {ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR), "internal list error"}, + {ERR_REASON(ENGINE_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_REASON(ENGINE_R_INVALID_CMD_NAME), "invalid cmd name"}, + {ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER), "invalid cmd number"}, + {ERR_REASON(ENGINE_R_INVALID_INIT_VALUE), "invalid init value"}, + {ERR_REASON(ENGINE_R_INVALID_STRING), "invalid string"}, + {ERR_REASON(ENGINE_R_NOT_INITIALISED), "not initialised"}, + {ERR_REASON(ENGINE_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION), "no control function"}, + {ERR_REASON(ENGINE_R_NO_INDEX), "no index"}, + {ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION), "no load function"}, + {ERR_REASON(ENGINE_R_NO_REFERENCE), "no reference"}, + {ERR_REASON(ENGINE_R_NO_SUCH_ENGINE), "no such engine"}, + {ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION), "no unload function"}, + {ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS), "provide parameters"}, + {ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED), "rsa not implemented"}, + {ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER), "unimplemented cipher"}, + {ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST), "unimplemented digest"}, + {ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD), + "unimplemented public key method"}, + {ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY), "version incompatibility"}, + {0, NULL} +}; + +#endif + +void ERR_load_ENGINE_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) { + ERR_load_strings(0, ENGINE_str_functs); + ERR_load_strings(0, ENGINE_str_reasons); + } +#endif +} +/* crypto/engine/eng_fat.c */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +// #include "eng_int.h" +// #include "conf.h" + +int ENGINE_set_default(ENGINE *e, unsigned int flags) +{ + if ((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e)) + return 0; + if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) + return 0; +#ifndef OPENSSL_NO_RSA + if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e)) + return 0; +#endif +#ifndef OPENSSL_NO_DSA + if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e)) + return 0; +#endif +#ifndef OPENSSL_NO_DH + if ((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e)) + return 0; +#endif +#ifndef OPENSSL_NO_ECDH + if ((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e)) + return 0; +#endif +#ifndef OPENSSL_NO_ECDSA + if ((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e)) + return 0; +#endif + if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) + return 0; + if ((flags & ENGINE_METHOD_PKEY_METHS) + && !ENGINE_set_default_pkey_meths(e)) + return 0; + if ((flags & ENGINE_METHOD_PKEY_ASN1_METHS) + && !ENGINE_set_default_pkey_asn1_meths(e)) + return 0; + return 1; +} + +/* Set default algorithms using a string */ + +static int int_def_cb(const char *alg, int len, void *arg) +{ + unsigned int *pflags = arg; + if (alg == NULL) + return 0; + if (!strncmp(alg, "ALL", len)) + *pflags |= ENGINE_METHOD_ALL; + else if (!strncmp(alg, "RSA", len)) + *pflags |= ENGINE_METHOD_RSA; + else if (!strncmp(alg, "DSA", len)) + *pflags |= ENGINE_METHOD_DSA; + else if (!strncmp(alg, "ECDH", len)) + *pflags |= ENGINE_METHOD_ECDH; + else if (!strncmp(alg, "ECDSA", len)) + *pflags |= ENGINE_METHOD_ECDSA; + else if (!strncmp(alg, "DH", len)) + *pflags |= ENGINE_METHOD_DH; + else if (!strncmp(alg, "RAND", len)) + *pflags |= ENGINE_METHOD_RAND; + else if (!strncmp(alg, "CIPHERS", len)) + *pflags |= ENGINE_METHOD_CIPHERS; + else if (!strncmp(alg, "DIGESTS", len)) + *pflags |= ENGINE_METHOD_DIGESTS; + else if (!strncmp(alg, "PKEY", len)) + *pflags |= ENGINE_METHOD_PKEY_METHS | ENGINE_METHOD_PKEY_ASN1_METHS; + else if (!strncmp(alg, "PKEY_CRYPTO", len)) + *pflags |= ENGINE_METHOD_PKEY_METHS; + else if (!strncmp(alg, "PKEY_ASN1", len)) + *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS; + else + return 0; + return 1; +} + +int ENGINE_set_default_string(ENGINE *e, const char *def_list) +{ + unsigned int flags = 0; + if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags)) { + ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING, + ENGINE_R_INVALID_STRING); + ERR_add_error_data(2, "str=", def_list); + return 0; + } + return ENGINE_set_default(e, flags); +} + +int ENGINE_register_complete(ENGINE *e) +{ + ENGINE_register_ciphers(e); + ENGINE_register_digests(e); +#ifndef OPENSSL_NO_RSA + ENGINE_register_RSA(e); +#endif +#ifndef OPENSSL_NO_DSA + ENGINE_register_DSA(e); +#endif +#ifndef OPENSSL_NO_DH + ENGINE_register_DH(e); +#endif +#ifndef OPENSSL_NO_ECDH + ENGINE_register_ECDH(e); +#endif +#ifndef OPENSSL_NO_ECDSA + ENGINE_register_ECDSA(e); +#endif + ENGINE_register_RAND(e); + ENGINE_register_pkey_meths(e); + ENGINE_register_pkey_asn1_meths(e); + return 1; +} + +int ENGINE_register_all_complete(void) +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL)) + ENGINE_register_complete(e); + return 1; +} +/* crypto/engine/eng_init.c */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "eng_int.h" + +/* + * Initialise a engine type for use (or up its functional reference count if + * it's already in use). This version is only used internally. + */ +int engine_unlocked_init(ENGINE *e) +{ + int to_return = 1; + + if ((e->funct_ref == 0) && e->init) + /* + * This is the first functional reference and the engine requires + * initialisation so we do it now. + */ + to_return = e->init(e); + if (to_return) { + /* + * OK, we return a functional reference which is also a structural + * reference. + */ + e->struct_ref++; + e->funct_ref++; + engine_ref_debug(e, 0, 1) + engine_ref_debug(e, 1, 1) + } + return to_return; +} + +/* + * Free a functional reference to a engine type. This version is only used + * internally. + */ +int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers) +{ + int to_return = 1; + + /* + * Reduce the functional reference count here so if it's the terminating + * case, we can release the lock safely and call the finish() handler + * without risk of a race. We get a race if we leave the count until + * after and something else is calling "finish" at the same time - + * there's a chance that both threads will together take the count from 2 + * to 0 without either calling finish(). + */ + e->funct_ref--; + engine_ref_debug(e, 1, -1); + if ((e->funct_ref == 0) && e->finish) { + if (unlock_for_handlers) + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + to_return = e->finish(e); + if (unlock_for_handlers) + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (!to_return) + return 0; + } +#ifdef REF_CHECK + if (e->funct_ref < 0) { + fprintf(stderr, "ENGINE_finish, bad functional reference count\n"); + abort(); + } +#endif + /* Release the structural reference too */ + if (!engine_free_util(e, 0)) { + ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH, ENGINE_R_FINISH_FAILED); + return 0; + } + return to_return; +} + +/* The API (locked) version of "init" */ +int ENGINE_init(ENGINE *e) +{ + int ret; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = engine_unlocked_init(e); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; +} + +/* The API (locked) version of "finish" */ +int ENGINE_finish(ENGINE *e) +{ + int to_return = 1; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_FINISH, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + to_return = engine_unlocked_finish(e, 1); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!to_return) { + ENGINEerr(ENGINE_F_ENGINE_FINISH, ENGINE_R_FINISH_FAILED); + return 0; + } + return to_return; +} +/* crypto/engine/eng_lib.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "eng_int.h" +#include "rand.h" + +/* The "new"/"free" stuff first */ + +ENGINE *ENGINE_new(void) +{ + ENGINE *ret; + + ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE)); + if (ret == NULL) { + ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ret, 0, sizeof(ENGINE)); + ret->struct_ref = 1; + engine_ref_debug(ret, 0, 1) + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data); + return ret; +} + +/* + * Placed here (close proximity to ENGINE_new) so that modifications to the + * elements of the ENGINE structure are more likely to be caught and changed + * here. + */ +void engine_set_all_null(ENGINE *e) +{ + e->id = NULL; + e->name = NULL; + e->rsa_meth = NULL; + e->dsa_meth = NULL; + e->dh_meth = NULL; + e->rand_meth = NULL; + e->store_meth = NULL; + e->ciphers = NULL; + e->digests = NULL; + e->destroy = NULL; + e->init = NULL; + e->finish = NULL; + e->ctrl = NULL; + e->load_privkey = NULL; + e->load_pubkey = NULL; + e->cmd_defns = NULL; + e->flags = 0; +} + +int engine_free_util(ENGINE *e, int locked) +{ + int i; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (locked) + i = CRYPTO_add(&e->struct_ref, -1, CRYPTO_LOCK_ENGINE); + else + i = --e->struct_ref; + engine_ref_debug(e, 0, -1) + if (i > 0) + return 1; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "ENGINE_free, bad structural reference count\n"); + abort(); + } +#endif + /* Free up any dynamically allocated public key methods */ + engine_pkey_meths_free(e); + engine_pkey_asn1_meths_free(e); + /* + * Give the ENGINE a chance to do any structural cleanup corresponding to + * allocation it did in its constructor (eg. unload error strings) + */ + if (e->destroy) + e->destroy(e); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data); + OPENSSL_free(e); + return 1; +} + +int ENGINE_free(ENGINE *e) +{ + return engine_free_util(e, 1); +} + +/* Cleanup stuff */ + +/* + * ENGINE_cleanup() is coded such that anything that does work that will need + * cleanup can register a "cleanup" callback here. That way we don't get + * linker bloat by referring to all *possible* cleanups, but any linker bloat + * into code "X" will cause X's cleanup function to end up here. + */ +static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL; +static int int_cleanup_check(int create) +{ + if (cleanup_stack) + return 1; + if (!create) + return 0; + cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null(); + return (cleanup_stack ? 1 : 0); +} + +static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb) +{ + ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(ENGINE_CLEANUP_ITEM)); + if (!item) + return NULL; + item->cb = cb; + return item; +} + +void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb) +{ + ENGINE_CLEANUP_ITEM *item; + if (!int_cleanup_check(1)) + return; + item = int_cleanup_item(cb); + if (item) + sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0); +} + +void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb) +{ + ENGINE_CLEANUP_ITEM *item; + if (!int_cleanup_check(1)) + return; + item = int_cleanup_item(cb); + if (item != NULL) { + if (sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item) <= 0) + OPENSSL_free(item); + } +} + +/* The API function that performs all cleanup */ +static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item) +{ + (*(item->cb)) (); + OPENSSL_free(item); +} + +void ENGINE_cleanup(void) +{ + if (int_cleanup_check(0)) { + sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack, + engine_cleanup_cb_free); + cleanup_stack = NULL; + } + /* + * FIXME: This should be handled (somehow) through RAND, eg. by it + * registering a cleanup callback. + */ + RAND_set_rand_method(NULL); +} + +/* Now the "ex_data" support */ + +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp, + new_func, dup_func, free_func); +} + +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&e->ex_data, idx, arg)); +} + +void *ENGINE_get_ex_data(const ENGINE *e, int idx) +{ + return (CRYPTO_get_ex_data(&e->ex_data, idx)); +} + +/* + * Functions to get/set an ENGINE's elements - mainly to avoid exposing the + * ENGINE structure itself. + */ + +int ENGINE_set_id(ENGINE *e, const char *id) +{ + if (id == NULL) { + ENGINEerr(ENGINE_F_ENGINE_SET_ID, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + e->id = id; + return 1; +} + +int ENGINE_set_name(ENGINE *e, const char *name) +{ + if (name == NULL) { + ENGINEerr(ENGINE_F_ENGINE_SET_NAME, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + e->name = name; + return 1; +} + +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f) +{ + e->destroy = destroy_f; + return 1; +} + +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f) +{ + e->init = init_f; + return 1; +} + +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f) +{ + e->finish = finish_f; + return 1; +} + +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f) +{ + e->ctrl = ctrl_f; + return 1; +} + +int ENGINE_set_flags(ENGINE *e, int flags) +{ + e->flags = flags; + return 1; +} + +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns) +{ + e->cmd_defns = defns; + return 1; +} + +const char *ENGINE_get_id(const ENGINE *e) +{ + return e->id; +} + +const char *ENGINE_get_name(const ENGINE *e) +{ + return e->name; +} + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e) +{ + return e->destroy; +} + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e) +{ + return e->init; +} + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e) +{ + return e->finish; +} + +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e) +{ + return e->ctrl; +} + +int ENGINE_get_flags(const ENGINE *e) +{ + return e->flags; +} + +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e) +{ + return e->cmd_defns; +} + +/* + * eng_lib.o is pretty much linked into anything that touches ENGINE already, + * so put the "static_state" hack here. + */ + +static int internal_static_hack = 0; + +void *ENGINE_get_static_state(void) +{ + return &internal_static_hack; +} +/* crypto/engine/eng_list.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +// #include "cryptlib.h" +// #include "eng_int.h" + +/* + * The linked-list of pointers to engine types. engine_list_head incorporates + * an implicit structural reference but engine_list_tail does not - the + * latter is a computational niceity and only points to something that is + * already pointed to by its predecessor in the list (or engine_list_head + * itself). In the same way, the use of the "prev" pointer in each ENGINE is + * to save excessive list iteration, it doesn't correspond to an extra + * structural reference. Hence, engine_list_head, and each non-null "next" + * pointer account for the list itself assuming exactly 1 structural + * reference on each list member. + */ +static ENGINE *engine_list_head = NULL; +static ENGINE *engine_list_tail = NULL; + +/* + * This cleanup function is only needed internally. If it should be called, + * we register it with the "ENGINE_cleanup()" stack to be called during + * cleanup. + */ + +static void engine_list_cleanup(void) +{ + ENGINE *iterator = engine_list_head; + + while (iterator != NULL) { + ENGINE_remove(iterator); + iterator = engine_list_head; + } + return; +} + +/* + * These static functions starting with a lower case "engine_" always take + * place when CRYPTO_LOCK_ENGINE has been locked up. + */ +static int engine_list_add(ENGINE *e) +{ + int conflict = 0; + ENGINE *iterator = NULL; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + iterator = engine_list_head; + while (iterator && !conflict) { + conflict = (strcmp(iterator->id, e->id) == 0); + iterator = iterator->next; + } + if (conflict) { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_CONFLICTING_ENGINE_ID); + return 0; + } + if (engine_list_head == NULL) { + /* We are adding to an empty list. */ + if (engine_list_tail) { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + engine_list_head = e; + e->prev = NULL; + /* + * The first time the list allocates, we should register the cleanup. + */ + engine_cleanup_add_last(engine_list_cleanup); + } else { + /* We are adding to the tail of an existing list. */ + if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + engine_list_tail->next = e; + e->prev = engine_list_tail; + } + /* + * Having the engine in the list assumes a structural reference. + */ + e->struct_ref++; + engine_ref_debug(e, 0, 1) + /* However it came to be, e is the last item in the list. */ + engine_list_tail = e; + e->next = NULL; + return 1; +} + +static int engine_list_remove(ENGINE *e) +{ + ENGINE *iterator; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + /* We need to check that e is in our linked list! */ + iterator = engine_list_head; + while (iterator && (iterator != e)) + iterator = iterator->next; + if (iterator == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, + ENGINE_R_ENGINE_IS_NOT_IN_LIST); + return 0; + } + /* un-link e from the chain. */ + if (e->next) + e->next->prev = e->prev; + if (e->prev) + e->prev->next = e->next; + /* Correct our head/tail if necessary. */ + if (engine_list_head == e) + engine_list_head = e->next; + if (engine_list_tail == e) + engine_list_tail = e->prev; + engine_free_util(e, 0); + return 1; +} + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void) +{ + ENGINE *ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = engine_list_head; + if (ret) { + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; +} + +ENGINE *ENGINE_get_last(void) +{ + ENGINE *ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = engine_list_tail; + if (ret) { + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; +} + +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e) +{ + ENGINE *ret = NULL; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = e->next; + if (ret) { + /* Return a valid structural refernce to the next ENGINE */ + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* Release the structural reference to the previous ENGINE */ + ENGINE_free(e); + return ret; +} + +ENGINE *ENGINE_get_prev(ENGINE *e) +{ + ENGINE *ret = NULL; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_GET_PREV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = e->prev; + if (ret) { + /* Return a valid structural reference to the next ENGINE */ + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* Release the structural reference to the previous ENGINE */ + ENGINE_free(e); + return ret; +} + +/* Add another "ENGINE" type into the list. */ +int ENGINE_add(ENGINE *e) +{ + int to_return = 1; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_ADD, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((e->id == NULL) || (e->name == NULL)) { + ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_ID_OR_NAME_MISSING); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (!engine_list_add(e)) { + ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + to_return = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return to_return; +} + +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e) +{ + int to_return = 1; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_REMOVE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (!engine_list_remove(e)) { + ENGINEerr(ENGINE_F_ENGINE_REMOVE, ENGINE_R_INTERNAL_LIST_ERROR); + to_return = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return to_return; +} + +static void engine_cpy(ENGINE *dest, const ENGINE *src) +{ + dest->id = src->id; + dest->name = src->name; +#ifndef OPENSSL_NO_RSA + dest->rsa_meth = src->rsa_meth; +#endif +#ifndef OPENSSL_NO_DSA + dest->dsa_meth = src->dsa_meth; +#endif +#ifndef OPENSSL_NO_DH + dest->dh_meth = src->dh_meth; +#endif +#ifndef OPENSSL_NO_ECDH + dest->ecdh_meth = src->ecdh_meth; +#endif +#ifndef OPENSSL_NO_ECDSA + dest->ecdsa_meth = src->ecdsa_meth; +#endif + dest->rand_meth = src->rand_meth; + dest->store_meth = src->store_meth; + dest->ciphers = src->ciphers; + dest->digests = src->digests; + dest->pkey_meths = src->pkey_meths; + dest->destroy = src->destroy; + dest->init = src->init; + dest->finish = src->finish; + dest->ctrl = src->ctrl; + dest->load_privkey = src->load_privkey; + dest->load_pubkey = src->load_pubkey; + dest->cmd_defns = src->cmd_defns; + dest->flags = src->flags; +} + +ENGINE *ENGINE_by_id(const char *id) +{ + ENGINE *iterator; + char *load_dir = NULL; + if (id == NULL) { + ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + iterator = engine_list_head; + while (iterator && (strcmp(id, iterator->id) != 0)) + iterator = iterator->next; + if (iterator) { + /* + * We need to return a structural reference. If this is an ENGINE + * type that returns copies, make a duplicate - otherwise increment + * the existing ENGINE's reference count. + */ + if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) { + ENGINE *cp = ENGINE_new(); + if (!cp) + iterator = NULL; + else { + engine_cpy(cp, iterator); + iterator = cp; + } + } else { + iterator->struct_ref++; + engine_ref_debug(iterator, 0, 1) + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); +#if 0 + if (iterator == NULL) { + ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE); + ERR_add_error_data(2, "id=", id); + } + return iterator; +#else + /* EEK! Experimental code starts */ + if (iterator) + return iterator; + /* + * Prevent infinite recusrion if we're looking for the dynamic engine. + */ + if (strcmp(id, "dynamic")) { +# ifdef OPENSSL_SYS_VMS + if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == 0) + load_dir = "SSLROOT:[ENGINES]"; +# else + if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == 0) + load_dir = ENGINESDIR; +# endif + iterator = ENGINE_by_id("dynamic"); + if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) || + !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) || + !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD", + load_dir, 0) || + !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) || + !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0)) + goto notfound; + return iterator; + } + notfound: + ENGINE_free(iterator); + ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE); + ERR_add_error_data(2, "id=", id); + return NULL; + /* EEK! Experimental code ends */ +#endif +} + +int ENGINE_up_ref(ENGINE *e) +{ + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_add(&e->struct_ref, 1, CRYPTO_LOCK_ENGINE); + return 1; +} +/* crypto/engine/eng_openssl.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include "crypto.h" +// #include "cryptlib.h" +// #include "engine.h" +// #include "dso.h" +#include "pem.h" +// #include "evp.h" +// #include "rand.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +/* + * This testing gunk is implemented (and explained) lower down. It also + * assumes the application explicitly calls "ENGINE_load_openssl()" because + * this is no longer automatic in ENGINE_load_builtin_engines(). + */ +#define TEST_ENG_OPENSSL_RC4 +#define TEST_ENG_OPENSSL_PKEY +/* #define TEST_ENG_OPENSSL_RC4_OTHERS */ +#define TEST_ENG_OPENSSL_RC4_P_INIT +/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */ +#define TEST_ENG_OPENSSL_SHA +/* #define TEST_ENG_OPENSSL_SHA_OTHERS */ +/* #define TEST_ENG_OPENSSL_SHA_P_INIT */ +/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */ +/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */ + +/* Now check what of those algorithms are actually enabled */ +#ifdef OPENSSL_NO_RC4 +# undef TEST_ENG_OPENSSL_RC4 +# undef TEST_ENG_OPENSSL_RC4_OTHERS +# undef TEST_ENG_OPENSSL_RC4_P_INIT +# undef TEST_ENG_OPENSSL_RC4_P_CIPHER +#endif +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1) +# undef TEST_ENG_OPENSSL_SHA +# undef TEST_ENG_OPENSSL_SHA_OTHERS +# undef TEST_ENG_OPENSSL_SHA_P_INIT +# undef TEST_ENG_OPENSSL_SHA_P_UPDATE +# undef TEST_ENG_OPENSSL_SHA_P_FINAL +#endif + +#ifdef TEST_ENG_OPENSSL_RC4 +static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); +#endif +#ifdef TEST_ENG_OPENSSL_SHA +static int openssl_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid); +#endif + +#ifdef TEST_ENG_OPENSSL_PKEY +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data); +#endif + +/* The constants used when creating the ENGINE */ +static const char *engine_openssl_id = "openssl"; +static const char *engine_openssl_name = "Software engine support"; + +/* + * This internal function is used by ENGINE_openssl() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ + if (!ENGINE_set_id(e, engine_openssl_id) + || !ENGINE_set_name(e, engine_openssl_name) +#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS +# ifndef OPENSSL_NO_RSA + || !ENGINE_set_RSA(e, RSA_get_default_method()) +# endif +# ifndef OPENSSL_NO_DSA + || !ENGINE_set_DSA(e, DSA_get_default_method()) +# endif +# ifndef OPENSSL_NO_ECDH + || !ENGINE_set_ECDH(e, ECDH_OpenSSL()) +# endif +# ifndef OPENSSL_NO_ECDSA + || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL()) +# endif +# ifndef OPENSSL_NO_DH + || !ENGINE_set_DH(e, DH_get_default_method()) +# endif + || !ENGINE_set_RAND(e, RAND_SSLeay()) +# ifdef TEST_ENG_OPENSSL_RC4 + || !ENGINE_set_ciphers(e, openssl_ciphers) +# endif +# ifdef TEST_ENG_OPENSSL_SHA + || !ENGINE_set_digests(e, openssl_digests) +# endif +#endif +#ifdef TEST_ENG_OPENSSL_PKEY + || !ENGINE_set_load_privkey_function(e, openssl_load_privkey) +#endif + ) + return 0; + /* + * If we add errors to this ENGINE, ensure the error handling is setup + * here + */ + /* openssl_load_error_strings(); */ + return 1; +} + +static ENGINE *engine_openssl(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_openssl(void) +{ + ENGINE *toadd = engine_openssl(); + if (!toadd) + return; + ENGINE_add(toadd); + /* + * If the "add" worked, it gets a structural reference. So either way, we + * release our just-created reference. + */ + ENGINE_free(toadd); + ERR_clear_error(); +} + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +#ifdef ENGINE_DYNAMIC_SUPPORT +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_openssl_id) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +#endif /* ENGINE_DYNAMIC_SUPPORT */ +#ifdef TEST_ENG_OPENSSL_RC4 +/*- + * This section of code compiles an "alternative implementation" of two modes of + * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4" + * should under normal circumstances go via this support rather than the default + * EVP support. There are other symbols to tweak the testing; + * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time + * we're asked for a cipher we don't support (should not happen). + * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time + * the "init_key" handler is called. + * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler. + */ +# include "rc4.h" +# define TEST_RC4_KEY_SIZE 16 +static int test_cipher_nids[] = { NID_rc4, NID_rc4_40 }; + +static int test_cipher_nids_number = 2; +typedef struct { + unsigned char key[TEST_RC4_KEY_SIZE]; + RC4_KEY ks; +} TEST_RC4_KEY; +# define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data) +static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ +# ifdef TEST_ENG_OPENSSL_RC4_P_INIT + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n"); +# endif + memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx)); + RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), + test(ctx)->key); + return 1; +} + +static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ +# ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n"); +# endif + RC4(&test(ctx)->ks, inl, in, out); + return 1; +} + +static const EVP_CIPHER test_r4_cipher = { + NID_rc4, + 1, TEST_RC4_KEY_SIZE, 0, + EVP_CIPH_VARIABLE_LENGTH, + test_rc4_init_key, + test_rc4_cipher, + NULL, + sizeof(TEST_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +static const EVP_CIPHER test_r4_40_cipher = { + NID_rc4_40, + 1, 5 /* 40 bit */ , 0, + EVP_CIPH_VARIABLE_LENGTH, + test_rc4_init_key, + test_rc4_cipher, + NULL, + sizeof(TEST_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) +{ + if (!cipher) { + /* We are returning a list of supported nids */ + *nids = test_cipher_nids; + return test_cipher_nids_number; + } + /* We are being asked for a specific cipher */ + if (nid == NID_rc4) + *cipher = &test_r4_cipher; + else if (nid == NID_rc4_40) + *cipher = &test_r4_40_cipher; + else { +# ifdef TEST_ENG_OPENSSL_RC4_OTHERS + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for " + "nid %d\n", nid); +# endif + *cipher = NULL; + return 0; + } + return 1; +} +#endif + +#ifdef TEST_ENG_OPENSSL_SHA +/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */ +# include "sha.h" +static int test_digest_nids[] = { NID_sha1 }; + +static int test_digest_nids_number = 1; +static int test_sha1_init(EVP_MD_CTX *ctx) +{ +# ifdef TEST_ENG_OPENSSL_SHA_P_INIT + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n"); +# endif + return SHA1_Init(ctx->md_data); +} + +static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ +# ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n"); +# endif + return SHA1_Update(ctx->md_data, data, count); +} + +static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) +{ +# ifdef TEST_ENG_OPENSSL_SHA_P_FINAL + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n"); +# endif + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD test_sha_md = { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, + 0, + test_sha1_init, + test_sha1_update, + test_sha1_final, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +static int openssl_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) +{ + if (!digest) { + /* We are returning a list of supported nids */ + *nids = test_digest_nids; + return test_digest_nids_number; + } + /* We are being asked for a specific digest */ + if (nid == NID_sha1) + *digest = &test_sha_md; + else { +# ifdef TEST_ENG_OPENSSL_SHA_OTHERS + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for " + "nid %d\n", nid); +# endif + *digest = NULL; + return 0; + } + return 1; +} +#endif + +#ifdef TEST_ENG_OPENSSL_PKEY +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data) +{ + BIO *in; + EVP_PKEY *key; + fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", + key_id); + in = BIO_new_file(key_id, "r"); + if (!in) + return NULL; + key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL); + BIO_free(in); + return key; +} +#endif +/* crypto/engine/eng_pkey.c */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "eng_int.h" + +/* Basic get/set stuff */ + +int ENGINE_set_load_privkey_function(ENGINE *e, + ENGINE_LOAD_KEY_PTR loadpriv_f) +{ + e->load_privkey = loadpriv_f; + return 1; +} + +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f) +{ + e->load_pubkey = loadpub_f; + return 1; +} + +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR + loadssl_f) +{ + e->load_ssl_client_cert = loadssl_f; + return 1; +} + +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e) +{ + return e->load_privkey; +} + +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e) +{ + return e->load_pubkey; +} + +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE + *e) +{ + return e->load_ssl_client_cert; +} + +/* API functions to load public/private keys */ + +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + EVP_PKEY *pkey; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (e->funct_ref == 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_privkey) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + pkey = e->load_privkey(e, key_id, ui_method, callback_data); + if (!pkey) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ENGINE_R_FAILED_LOADING_PRIVATE_KEY); + return 0; + } + return pkey; +} + +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + EVP_PKEY *pkey; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (e->funct_ref == 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_pubkey) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + pkey = e->load_pubkey(e, key_id, ui_method, callback_data); + if (!pkey) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, + ENGINE_R_FAILED_LOADING_PUBLIC_KEY); + return 0; + } + return pkey; +} + +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **ppkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data) +{ + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (e->funct_ref == 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_ssl_client_cert) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother, + ui_method, callback_data); +} +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "opensslconf.h" + +#include +#include +// #include "engine.h" +// #include "rand.h" +// #include "err.h" + +#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ) + +size_t OPENSSL_ia32_rdrand(void); + +static int get_random_bytes(unsigned char *buf, int num) +{ + size_t rnd; + + while (num >= (int)sizeof(size_t)) { + if ((rnd = OPENSSL_ia32_rdrand()) == 0) + return 0; + + *((size_t *)buf) = rnd; + buf += sizeof(size_t); + num -= sizeof(size_t); + } + if (num) { + if ((rnd = OPENSSL_ia32_rdrand()) == 0) + return 0; + + memcpy(buf, &rnd, num); + } + + return 1; +} + +static int random_status(void) +{ + return 1; +} + +static RAND_METHOD rdrand_meth = { + NULL, /* seed */ + get_random_bytes, + NULL, /* cleanup */ + NULL, /* add */ + get_random_bytes, + random_status, +}; + +static int rdrand_init(ENGINE *e) +{ + return 1; +} + +static const char *engine_e_rdrand_id = "rdrand"; +static const char *engine_e_rdrand_name = "Intel RDRAND engine"; + +static int bind_helper(ENGINE *e) +{ + if (!ENGINE_set_id(e, engine_e_rdrand_id) || + !ENGINE_set_name(e, engine_e_rdrand_name) || + !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) || + !ENGINE_set_init_function(e, rdrand_init) || + !ENGINE_set_RAND(e, &rdrand_meth)) + return 0; + + return 1; +} + +static ENGINE *ENGINE_rdrand(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_rdrand(void) +{ + extern unsigned int OPENSSL_ia32cap_P[]; + + if (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) { + ENGINE *toadd = ENGINE_rdrand(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); + } +} +#else +void ENGINE_load_rdrand(void) +{ +} +#endif +/* ==================================================================== + * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "evp.h" +#include "lhash.h" +// #include "eng_int.h" + +/* The type of the items in the table */ +typedef struct st_engine_pile { + /* The 'nid' of this algorithm/mode */ + int nid; + /* ENGINEs that implement this algorithm/mode. */ + STACK_OF(ENGINE) *sk; + /* The default ENGINE to perform this algorithm/mode. */ + ENGINE *funct; + /* + * Zero if 'sk' is newer than the cached 'funct', non-zero otherwise + */ + int uptodate; +} ENGINE_PILE; + +DECLARE_LHASH_OF(ENGINE_PILE); + +/* The type exposed in eng_int.h */ +struct st_engine_table { + LHASH_OF(ENGINE_PILE) piles; +}; /* ENGINE_TABLE */ + +typedef struct st_engine_pile_doall { + engine_table_doall_cb *cb; + void *arg; +} ENGINE_PILE_DOALL; + +/* Global flags (ENGINE_TABLE_FLAG_***). */ +static unsigned int table_flags = 0; + +/* API function manipulating 'table_flags' */ +unsigned int ENGINE_get_table_flags(void) +{ + return table_flags; +} + +void ENGINE_set_table_flags(unsigned int flags) +{ + table_flags = flags; +} + +/* Internal functions for the "piles" hash table */ +static unsigned long engine_pile_hash(const ENGINE_PILE *c) +{ + return c->nid; +} + +static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) +{ + return a->nid - b->nid; +} + +static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE) +static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE) + +static int int_table_check(ENGINE_TABLE **t, int create) +{ + LHASH_OF(ENGINE_PILE) *lh; + + if (*t) + return 1; + if (!create) + return 0; + if ((lh = lh_ENGINE_PILE_new()) == NULL) + return 0; + *t = (ENGINE_TABLE *)lh; + return 1; +} + +/* + * Privately exposed (via eng_int.h) functions for adding and/or removing + * ENGINEs from the implementation table + */ +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, + ENGINE *e, const int *nids, int num_nids, + int setdefault) +{ + int ret = 0, added = 0; + ENGINE_PILE tmplate, *fnd; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (!(*table)) + added = 1; + if (!int_table_check(table, 1)) + goto end; + if (added) + /* The cleanup callback needs to be added */ + engine_cleanup_add_first(cleanup); + while (num_nids--) { + tmplate.nid = *nids; + fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); + if (!fnd) { + fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); + if (!fnd) + goto end; + fnd->uptodate = 1; + fnd->nid = *nids; + fnd->sk = sk_ENGINE_new_null(); + if (!fnd->sk) { + OPENSSL_free(fnd); + goto end; + } + fnd->funct = NULL; + (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd); + if (lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate) != fnd) { + sk_ENGINE_free(fnd->sk); + OPENSSL_free(fnd); + goto end; + } + } + /* A registration shouldn't add duplciate entries */ + (void)sk_ENGINE_delete_ptr(fnd->sk, e); + /* + * if 'setdefault', this ENGINE goes to the head of the list + */ + if (!sk_ENGINE_push(fnd->sk, e)) + goto end; + /* "touch" this ENGINE_PILE */ + fnd->uptodate = 0; + if (setdefault) { + if (!engine_unlocked_init(e)) { + ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, + ENGINE_R_INIT_FAILED); + goto end; + } + if (fnd->funct) + engine_unlocked_finish(fnd->funct, 0); + fnd->funct = e; + fnd->uptodate = 1; + } + nids++; + } + ret = 1; + end: + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; +} + +static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e) +{ + int n; + /* Iterate the 'c->sk' stack removing any occurance of 'e' */ + while ((n = sk_ENGINE_find(pile->sk, e)) >= 0) { + (void)sk_ENGINE_delete(pile->sk, n); + pile->uptodate = 0; + } + if (pile->funct == e) { + engine_unlocked_finish(e, 0); + pile->funct = NULL; + } +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE) + +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) +{ + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (int_table_check(table, 0)) + lh_ENGINE_PILE_doall_arg(&(*table)->piles, + LHASH_DOALL_ARG_FN(int_unregister_cb), + ENGINE, e); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); +} + +static void int_cleanup_cb_doall(ENGINE_PILE *p) +{ + sk_ENGINE_free(p->sk); + if (p->funct) + engine_unlocked_finish(p->funct, 0); + OPENSSL_free(p); +} + +static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE) + +void engine_table_cleanup(ENGINE_TABLE **table) +{ + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (*table) { + lh_ENGINE_PILE_doall(&(*table)->piles, + LHASH_DOALL_FN(int_cleanup_cb)); + lh_ENGINE_PILE_free(&(*table)->piles); + *table = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); +} + +/* return a functional reference for a given 'nid' */ +#ifndef ENGINE_TABLE_DEBUG +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) +#else +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, + int l) +#endif +{ + ENGINE *ret = NULL; + ENGINE_PILE tmplate, *fnd = NULL; + int initres, loop = 0; + + if (!(*table)) { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing " + "registered!\n", f, l, nid); +#endif + return NULL; + } + ERR_set_mark(); + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + /* + * Check again inside the lock otherwise we could race against cleanup + * operations. But don't worry about a fprintf(stderr). + */ + if (!int_table_check(table, 0)) + goto end; + tmplate.nid = nid; + fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); + if (!fnd) + goto end; + if (fnd->funct && engine_unlocked_init(fnd->funct)) { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " + "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); +#endif + ret = fnd->funct; + goto end; + } + if (fnd->uptodate) { + ret = fnd->funct; + goto end; + } + trynext: + ret = sk_ENGINE_value(fnd->sk, loop++); + if (!ret) { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " + "registered implementations would initialise\n", f, l, nid); +#endif + goto end; + } + /* Try to initialise the ENGINE? */ + if ((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) + initres = engine_unlocked_init(ret); + else + initres = 0; + if (initres) { + /* Update 'funct' */ + if ((fnd->funct != ret) && engine_unlocked_init(ret)) { + /* If there was a previous default we release it. */ + if (fnd->funct) + engine_unlocked_finish(fnd->funct, 0); + fnd->funct = ret; +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " + "setting default to '%s'\n", f, l, nid, ret->id); +#endif + } +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " + "newly initialised '%s'\n", f, l, nid, ret->id); +#endif + goto end; + } + goto trynext; + end: + /* + * If it failed, it is unlikely to succeed again until some future + * registrations have taken place. In all cases, we cache. + */ + if (fnd) + fnd->uptodate = 1; +#ifdef ENGINE_TABLE_DEBUG + if (ret) + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " + "ENGINE '%s'\n", f, l, nid, ret->id); + else + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " + "'no matching ENGINE'\n", f, l, nid); +#endif + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* + * Whatever happened, any failed init()s are not failures in this + * context, so clear our error state. + */ + ERR_pop_to_mark(); + return ret; +} + +/* Table enumeration */ + +static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall) +{ + dall->cb(pile->nid, pile->sk, pile->funct, dall->arg); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE, ENGINE_PILE_DOALL) + +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, + void *arg) +{ + ENGINE_PILE_DOALL dall; + dall.cb = cb; + dall.arg = arg; + if (table) + lh_ENGINE_PILE_doall_arg(&table->piles, + LHASH_DOALL_ARG_FN(int_cb), + ENGINE_PILE_DOALL, &dall); +} diff --git a/Sources/COpenSSL/eng_int.h b/Sources/COpenSSL/eng_int.h new file mode 100644 index 00000000..a47cff19 --- /dev/null +++ b/Sources/COpenSSL/eng_int.h @@ -0,0 +1,224 @@ +/* crypto/engine/eng_int.h */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_ENGINE_INT_H +# define HEADER_ENGINE_INT_H + +# include "cryptlib.h" +/* Take public definitions from engine.h */ +# include "engine.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * If we compile with this symbol defined, then both reference counts in the + * ENGINE structure will be monitored with a line of output on stderr for + * each change. This prints the engine's pointer address (truncated to + * unsigned int), "struct" or "funct" to indicate the reference type, the + * before and after reference count, and the file:line-number pair. The + * "engine_ref_debug" statements must come *after* the change. + */ +# ifdef ENGINE_REF_COUNT_DEBUG + +# define engine_ref_debug(e, isfunct, diff) \ + fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \ + (unsigned int)(e), (isfunct ? "funct" : "struct"), \ + ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \ + ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ + (__FILE__), (__LINE__)); + +# else + +# define engine_ref_debug(e, isfunct, diff) + +# endif + +/* + * Any code that will need cleanup operations should use these functions to + * register callbacks. ENGINE_cleanup() will call all registered callbacks in + * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be + * held (in "write" mode). + */ +typedef void (ENGINE_CLEANUP_CB) (void); +typedef struct st_engine_cleanup_item { + ENGINE_CLEANUP_CB *cb; +} ENGINE_CLEANUP_ITEM; +DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM) +void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb); +void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb); + +/* We need stacks of ENGINEs for use in eng_table.c */ +DECLARE_STACK_OF(ENGINE) + +/* + * If this symbol is defined then engine_table_select(), the function that is + * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults + * and functional references (etc), will display debugging summaries to + * stderr. + */ +/* #define ENGINE_TABLE_DEBUG */ + +/* + * This represents an implementation table. Dependent code should instantiate + * it as a (ENGINE_TABLE *) pointer value set initially to NULL. + */ +typedef struct st_engine_table ENGINE_TABLE; +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, + ENGINE *e, const int *nids, int num_nids, + int setdefault); +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e); +void engine_table_cleanup(ENGINE_TABLE **table); +# ifndef ENGINE_TABLE_DEBUG +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); +# else +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, + int l); +# define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) +# endif +typedef void (engine_table_doall_cb) (int nid, STACK_OF(ENGINE) *sk, + ENGINE *def, void *arg); +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, + void *arg); + +/* + * Internal versions of API functions that have control over locking. These + * are used between C files when functionality needs to be shared but the + * caller may already be controlling of the CRYPTO_LOCK_ENGINE lock. + */ +int engine_unlocked_init(ENGINE *e); +int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers); +int engine_free_util(ENGINE *e, int locked); + +/* + * This function will reset all "set"able values in an ENGINE to NULL. This + * won't touch reference counts or ex_data, but is equivalent to calling all + * the ENGINE_set_***() functions with a NULL value. + */ +void engine_set_all_null(ENGINE *e); + +/* + * NB: Bitwise OR-able values for the "flags" variable in ENGINE are now + * exposed in engine.h. + */ + +/* Free up dynamically allocated public key methods associated with ENGINE */ + +void engine_pkey_meths_free(ENGINE *e); +void engine_pkey_asn1_meths_free(ENGINE *e); + +/* + * This is a structure for storing implementations of various crypto + * algorithms and functions. + */ +struct engine_st { + const char *id; + const char *name; + const RSA_METHOD *rsa_meth; + const DSA_METHOD *dsa_meth; + const DH_METHOD *dh_meth; + const ECDH_METHOD *ecdh_meth; + const ECDSA_METHOD *ecdsa_meth; + const RAND_METHOD *rand_meth; + const STORE_METHOD *store_meth; + /* Cipher handling is via this callback */ + ENGINE_CIPHERS_PTR ciphers; + /* Digest handling is via this callback */ + ENGINE_DIGESTS_PTR digests; + /* Public key handling via this callback */ + ENGINE_PKEY_METHS_PTR pkey_meths; + /* ASN1 public key handling via this callback */ + ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths; + ENGINE_GEN_INT_FUNC_PTR destroy; + ENGINE_GEN_INT_FUNC_PTR init; + ENGINE_GEN_INT_FUNC_PTR finish; + ENGINE_CTRL_FUNC_PTR ctrl; + ENGINE_LOAD_KEY_PTR load_privkey; + ENGINE_LOAD_KEY_PTR load_pubkey; + ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert; + const ENGINE_CMD_DEFN *cmd_defns; + int flags; + /* reference count on the structure itself */ + int struct_ref; + /* + * reference count on usability of the engine type. NB: This controls the + * loading and initialisation of any functionlity required by this + * engine, whereas the previous count is simply to cope with + * (de)allocation of this structure. Hence, running_ref <= struct_ref at + * all times. + */ + int funct_ref; + /* A place to store per-ENGINE data */ + CRYPTO_EX_DATA ex_data; + /* Used to maintain the linked-list of engines. */ + struct engine_st *prev; + struct engine_st *next; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_ENGINE_INT_H */ diff --git a/Sources/COpenSSL/engine.h b/Sources/COpenSSL/engine.h new file mode 100644 index 00000000..873464a0 --- /dev/null +++ b/Sources/COpenSSL/engine.h @@ -0,0 +1,960 @@ +/* openssl/engine.h */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_ENGINE_H +# define HEADER_ENGINE_H + +# include "opensslconf.h" + +# ifdef OPENSSL_NO_ENGINE +# error ENGINE is disabled. +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# include "bn.h" +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif +# ifndef OPENSSL_NO_DSA +# include "dsa.h" +# endif +# ifndef OPENSSL_NO_DH +# include "dh.h" +# endif +# ifndef OPENSSL_NO_ECDH +# include "ecdh.h" +# endif +# ifndef OPENSSL_NO_ECDSA +# include "ecdsa.h" +# endif +# include "rand.h" +# include "ui.h" +# include "err.h" +# endif + +# include "ossl_typ.h" +# include "symhacks.h" + +# include "x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These flags are used to control combinations of algorithm (methods) by + * bitwise "OR"ing. + */ +# define ENGINE_METHOD_RSA (unsigned int)0x0001 +# define ENGINE_METHOD_DSA (unsigned int)0x0002 +# define ENGINE_METHOD_DH (unsigned int)0x0004 +# define ENGINE_METHOD_RAND (unsigned int)0x0008 +# define ENGINE_METHOD_ECDH (unsigned int)0x0010 +# define ENGINE_METHOD_ECDSA (unsigned int)0x0020 +# define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +# define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 +# define ENGINE_METHOD_STORE (unsigned int)0x0100 +# define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +# define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 +/* Obvious all-or-nothing cases. */ +# define ENGINE_METHOD_ALL (unsigned int)0xFFFF +# define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* + * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be + * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. + */ +# define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* Not used */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ + +/* + * This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles + * these control commands on behalf of the ENGINE using their "cmd_defns" + * data. + */ +# define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* + * This flag is for ENGINEs who return new duplicate structures when found + * via "ENGINE_by_id()". When an ENGINE must store state (eg. if + * ENGINE_ctrl() commands are called in sequence as part of some stateful + * process like key-generation setup and execution), it can set this flag - + * then each attempt to obtain the ENGINE will result in it being copied into + * a new structure. Normally, ENGINEs don't declare this flag so + * ENGINE_by_id() just increments the existing ENGINE's structural reference + * count. + */ +# define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* + * This flag if for an ENGINE that does not want its methods registered as + * part of ENGINE_register_all_complete() for example if the methods are not + * usable as default methods. + */ + +# define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 + +/* + * ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input + * each command expects. Currently only numeric and string input is + * supported. If a control command supports none of the _NUMERIC, _STRING, or + * _NO_INPUT options, then it is regarded as an "internal" control command - + * and not for use in config setting situations. As such, they're not + * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() + * access. Changes to this list of 'command types' should be reflected + * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). + */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +# define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* + * accepts string input (cast from 'void*' to 'const char *', 4th parameter + * to ENGINE_ctrl) + */ +# define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* + * Indicates that the control command takes *no* input. Ie. the control + * command is unparameterised. + */ +# define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* + * Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. + */ +# define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* + * NB: These 3 control commands are deprecated and should not be used. + * ENGINEs relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate + * the same functionality to their own ENGINE-specific control functions that + * can be "discovered" by calling applications. The fact these control + * commands wouldn't be "executable" (ie. usable by text-based config) + * doesn't change the fact that application code can find and use them + * without requiring per-ENGINE hacking. + */ + +/* + * These flags are used to tell the ctrl function what should be done. All + * command numbers are shared between all engines, even if some don't make + * sense to some engines. In such a case, they do nothing but return the + * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. + */ +# define ENGINE_CTRL_SET_LOGSTREAM 1 +# define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +# define ENGINE_CTRL_HUP 3/* Close and reinitialise + * any handles/connections + * etc. */ +# define ENGINE_CTRL_SET_USER_INTERFACE 4/* Alternative to callback */ +# define ENGINE_CTRL_SET_CALLBACK_DATA 5/* User-specific data, used + * when calling the password + * callback and the user + * interface */ +# define ENGINE_CTRL_LOAD_CONFIGURATION 6/* Load a configuration, + * given a string that + * represents a file name + * or so */ +# define ENGINE_CTRL_LOAD_SECTION 7/* Load data from a given + * section in the already + * loaded configuration */ + +/* + * These control commands allow an application to deal with an arbitrary + * engine in a dynamic way. Warn: Negative return values indicate errors FOR + * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other + * commands, including ENGINE-specific command types, return zero for an + * error. An ENGINE can choose to implement these ctrl functions, and can + * internally manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise + * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the + * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's + * ctrl() handler need only implement its own commands - the above "meta" + * commands will be taken care of. + */ + +/* + * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", + * then all the remaining control commands will return failure, so it is + * worth checking this first if the caller is trying to "discover" the + * engine's capabilities and doesn't want errors generated unnecessarily. + */ +# define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* + * Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. + */ +# define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* + * The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. + */ +# define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* + * The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. + */ +# define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* + * The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the + * NAME_LEN case, the return value is the length of the command name (not + * counting a trailing EOL). In the NAME case, the 'void*' argument must be a + * string buffer large enough, and it will be populated with the name of the + * command (WITH a trailing EOL). + */ +# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +# define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +# define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* + * With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. + */ +# define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* + * ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). + */ +# define ENGINE_CMD_BASE 200 + +/* + * NB: These 2 nCipher "chil" control commands are deprecated, and their + * functionality is now available through ENGINE-specific control commands + * (exposed through the above-mentioned 'CMD'-handling). Code using these 2 + * commands should be migrated to the more general command handling before + * these are removed. + */ + +/* Flags specific to the nCipher "chil" engine */ +# define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 + /* + * Depending on the value of the (long)i argument, this sets or + * unsets the SimpleForkCheck flag in the CHIL API to enable or + * disable checking and workarounds for applications that fork(). + */ +# define ENGINE_CTRL_CHIL_NO_LOCKING 101 + /* + * This prevents the initialisation function from providing mutex + * callbacks to the nCipher library. + */ + +/* + * If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on + * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN + * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl() + * handler that supports the stated commands (ie. the "cmd_num" entries as + * described by the array). NB: The array must be ordered in increasing order + * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element + * has cmd_num set to zero and/or cmd_name set to NULL. + */ +typedef struct ENGINE_CMD_DEFN_st { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ +} ENGINE_CMD_DEFN; + +/* Generic function pointer */ +typedef int (*ENGINE_GEN_FUNC_PTR) (void); +/* Generic function pointer taking no arguments */ +typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, + void (*f) (void)); +/* Generic load_key function pointer */ +typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, + X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, + void *callback_data); +/*- + * These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* + * Returns to a pointer to the array of supported cipher 'nid's. If the + * second parameter is non-NULL it is set to the size of the returned array. + */ +typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **, + const int **, int); +typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **, + int); +typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **, + const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **, + const int **, int); +/* + * STRUCTURE functions ... all of these functions deal with pointers to + * ENGINE structures where the pointers have a "structural reference". This + * means that their reference is to allowed access to the structure but it + * does not imply that the structure is functional. To simply increment or + * decrement the structural reference count, use ENGINE_by_id and + * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next + * as it will automatically decrement the structural reference count of the + * "current" ENGINE and increment the structural reference count of the + * ENGINE it returns (unless it is NULL). + */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); +/* Add all the built-in engines. */ +void ENGINE_load_openssl(void); +void ENGINE_load_dynamic(void); +# ifndef OPENSSL_NO_STATIC_ENGINE +void ENGINE_load_4758cca(void); +void ENGINE_load_aep(void); +void ENGINE_load_atalla(void); +void ENGINE_load_chil(void); +void ENGINE_load_cswift(void); +void ENGINE_load_nuron(void); +void ENGINE_load_sureware(void); +void ENGINE_load_ubsec(void); +void ENGINE_load_padlock(void); +void ENGINE_load_capi(void); +# ifndef OPENSSL_NO_GMP +void ENGINE_load_gmp(void); +# endif +# ifndef OPENSSL_NO_GOST +void ENGINE_load_gost(void); +# endif +# endif +void ENGINE_load_cryptodev(void); +void ENGINE_load_rdrand(void); +void ENGINE_load_builtin_engines(void); + +/* + * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. + */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); + +/*- Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required, so + * ENGINE_cleanup() will reverse any "register" operations. + */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_ECDH(ENGINE *e); +void ENGINE_unregister_ECDH(ENGINE *e); +void ENGINE_register_all_ECDH(void); + +int ENGINE_register_ECDSA(ENGINE *e); +void ENGINE_unregister_ECDSA(ENGINE *e); +void ENGINE_register_all_ECDSA(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_STORE(ENGINE *e); +void ENGINE_unregister_STORE(ENGINE *e); +void ENGINE_register_all_STORE(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + +/* + * These functions register all support from the above categories. Note, use + * of these functions can result in static linkage of code your application + * may not need. If you only need a subset of functionality, consider using + * more selective initialisation. + */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* + * Send parametrised control commands to the engine. The possibilities to + * send down an integer, a pointer to data or a function pointer are + * provided. Any of the parameters may or may not be NULL, depending on the + * command number. In actuality, this function only requires a structural + * (rather than functional) reference to an engine, but many control commands + * may require the engine be functional. The caller should be aware of trying + * commands that require an operational ENGINE, and only use functional + * references in such situations. + */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* + * This function tests if an ENGINE-specific command is usable as a + * "setting". Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). + */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* + * This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional + * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation + * on how to use the cmd_name and cmd_optional. + */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f) (void), int cmd_optional); + +/* + * This function passes a command-name and argument to an ENGINE. The + * cmd_name is converted to a command number and the control command is + * called using 'arg' as an argument (unless the ENGINE doesn't support such + * a command, in which case no control command is called). The command is + * checked for input flags, and if necessary the argument will be converted + * to a numeric value. If cmd_optional is non-zero, then if the ENGINE + * doesn't support the given cmd_name the return value will be success + * anyway. This function is intended for applications to use so that users + * (or config files) can supply engine-specific config data to the ENGINE at + * run-time to control behaviour of specific engines. As such, it shouldn't + * be used for calling ENGINE_ctrl() functions that return data, deal with + * binary data, or that are otherwise supposed to be used directly through + * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl() + * operation in this function will be lost - the return value is interpreted + * as failure if the return value is zero, success otherwise, and this + * function returns a boolean value as a result. In other words, vendors of + * 'ENGINE'-enabled devices should write ENGINE implementations with + * parameterisations that work in this scheme, so that compliant ENGINE-based + * applications can work consistently with the same configuration for the + * same ENGINE-enabled devices, across applications. + */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* + * These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an + * ENGINE structure with personalised implementations of things prior to + * using it directly or adding it to the builtin ENGINE list in OpenSSL. + * These are also here so that the ENGINE structure doesn't have to be + * exposed and break binary compatibility! + */ +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth); +int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, + ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR + loadssl_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions allow control over any per-structure ENGINE data. */ +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); + +/* + * This function cleans up anything that needs it. Eg. the ENGINE_add() + * function automatically ensures the list cleanup function is registered to + * be called from ENGINE_cleanup(). Similarly, all ENGINE_register_*** + * functions ensure ENGINE_cleanup() will clean up after them. + */ +void ENGINE_cleanup(void); + +/* + * These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! + */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e); +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE + *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, + int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, + int len); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); + +/* + * FUNCTIONAL functions. These functions deal with ENGINE structures that + * have (or will) be initialised for use. Broadly speaking, the structural + * functions are useful for iterating the list of available engine types, + * creating new engine types, and other "list" operations. These functions + * actually deal with ENGINEs that are to be used. As such these functions + * can fail (if applicable) when particular engines are unavailable - eg. if + * a hardware accelerator is not attached or not functioning correctly. Each + * ENGINE has 2 reference counts; structural and functional. Every time a + * functional reference is obtained or released, a corresponding structural + * reference is automatically obtained or released too. + */ + +/* + * Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently operational + * and cannot initialise. + */ +int ENGINE_init(ENGINE *e); +/* + * Free a functional reference to a engine type. This does not require a + * corresponding call to ENGINE_free as it also releases a structural + * reference. + */ +int ENGINE_finish(ENGINE *e); + +/* + * The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. + */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **ppkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); + +/* + * This returns a pointer for the current ENGINE structure that is (by + * default) performing any RSA operations. The value returned is an + * incremented reference, so it should be free'd (ENGINE_finish) before it is + * discarded. + */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_ECDH(void); +ENGINE *ENGINE_get_default_ECDSA(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +/* + * These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". + */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); + +/* + * This sets a new default ENGINE structure for performing RSA operations. If + * the result is non-zero (success) then the ENGINE structure will have had + * its reference count up'd so the caller should still free their own + * reference 'e'. + */ +int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *def_list); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_ECDH(ENGINE *e); +int ENGINE_set_default_ECDSA(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); + +/* + * The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. + */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +void ENGINE_add_conf_module(void); + +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +# define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000 +/* + * Binary versions older than this are too old for us (whether we're a loader + * or a loadee) + */ +# define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000 + +/* + * When compiling an ENGINE entirely as an external shared library, loadable + * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' + * structure type provides the calling application's (or library's) error + * functionality and memory management function pointers to the loaded + * library. These should be used/set in the loaded library code so that the + * loading application's 'state' will be used/changed in all operations. The + * 'static_state' pointer allows the loaded library to know if it shares the + * same static data as the calling application (or library), and thus whether + * these callbacks need to be set or not. + */ +typedef void *(*dyn_MEM_malloc_cb) (size_t); +typedef void *(*dyn_MEM_realloc_cb) (void *, size_t); +typedef void (*dyn_MEM_free_cb) (void *); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_cb malloc_cb; + dyn_MEM_realloc_cb realloc_cb; + dyn_MEM_free_cb free_cb; +} dynamic_MEM_fns; +/* + * FIXME: Perhaps the memory and locking code (crypto.h) should declare and + * use these types so we (and any other dependant code) can simplify a bit?? + */ +typedef void (*dyn_lock_locking_cb) (int, int, const char *, int); +typedef int (*dyn_lock_add_lock_cb) (int *, int, int, const char *, int); +typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb) (const char *, + int); +typedef void (*dyn_dynlock_lock_cb) (int, struct CRYPTO_dynlock_value *, + const char *, int); +typedef void (*dyn_dynlock_destroy_cb) (struct CRYPTO_dynlock_value *, + const char *, int); +typedef struct st_dynamic_LOCK_fns { + dyn_lock_locking_cb lock_locking_cb; + dyn_lock_add_lock_cb lock_add_lock_cb; + dyn_dynlock_create_cb dynlock_create_cb; + dyn_dynlock_lock_cb dynlock_lock_cb; + dyn_dynlock_destroy_cb dynlock_destroy_cb; +} dynamic_LOCK_fns; +/* The top-level structure */ +typedef struct st_dynamic_fns { + void *static_state; + const ERR_FNS *err_fns; + const CRYPTO_EX_DATA_IMPL *ex_data_fns; + dynamic_MEM_fns mem_fns; + dynamic_LOCK_fns lock_fns; +} dynamic_fns; + +/* + * The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading + * code. If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's + * version is unsatisfactory and could veto the load. The function is + * expected to be implemented with the symbol name "v_check", and a default + * implementation can be fully instantiated with + * IMPLEMENT_DYNAMIC_CHECK_FN(). + */ +typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version); +# define IMPLEMENT_DYNAMIC_CHECK_FN() \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v); \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \ + if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* + * This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load + * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto + * the structure, and (c) the shared library will be unloaded. So + * implementations should do their own internal cleanup in failure + * circumstances otherwise they could leak. The 'id' parameter, if non-NULL, + * represents the ENGINE id that the loader is looking for. If this is NULL, + * the shared library can choose to return failure or to initialise a + * 'default' ENGINE. If non-NULL, the shared library must initialise only an + * ENGINE matching the passed 'id'. The function is expected to be + * implemented with the symbol name "bind_engine". A standard implementation + * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter + * 'fn' is a callback function that populates the ENGINE structure and + * returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); + */ +typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, + const dynamic_fns *fns); +# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ + if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ + fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ + return 0; \ + CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \ + CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \ + CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \ + CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \ + CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \ + if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ + return 0; \ + if(!ERR_set_implementation(fns->err_fns)) return 0; \ + skip_cbs: \ + if(!fn(e,id)) return 0; \ + return 1; } + +/* + * If the loading application (or library) and the loaded ENGINE library + * share the same static data (eg. they're both dynamically linked to the + * same libcrypto.so) we need a way to avoid trying to set system callbacks - + * this would fail, and for the same reason that it's unnecessary to try. If + * the loaded ENGINE has (or gets from through the loader) its own copy of + * the libcrypto static data, we will need to set the callbacks. The easiest + * way to detect this is to have a function that returns a pointer to some + * static data and let the loading application and loaded ENGINE compare + * their respective values. + */ +void *ENGINE_get_static_state(void); + +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) +void ENGINE_setup_bsd_cryptodev(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ENGINE_strings(void); + +/* Error codes for the ENGINE functions. */ + +/* Function codes. */ +# define ENGINE_F_DYNAMIC_CTRL 180 +# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +# define ENGINE_F_DYNAMIC_LOAD 182 +# define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 +# define ENGINE_F_ENGINE_ADD 105 +# define ENGINE_F_ENGINE_BY_ID 106 +# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 +# define ENGINE_F_ENGINE_CTRL 142 +# define ENGINE_F_ENGINE_CTRL_CMD 178 +# define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 +# define ENGINE_F_ENGINE_FINISH 107 +# define ENGINE_F_ENGINE_FREE_UTIL 108 +# define ENGINE_F_ENGINE_GET_CIPHER 185 +# define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 +# define ENGINE_F_ENGINE_GET_DIGEST 186 +# define ENGINE_F_ENGINE_GET_NEXT 115 +# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +# define ENGINE_F_ENGINE_GET_PKEY_METH 192 +# define ENGINE_F_ENGINE_GET_PREV 116 +# define ENGINE_F_ENGINE_INIT 119 +# define ENGINE_F_ENGINE_LIST_ADD 120 +# define ENGINE_F_ENGINE_LIST_REMOVE 121 +# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 +# define ENGINE_F_ENGINE_NEW 122 +# define ENGINE_F_ENGINE_REMOVE 123 +# define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 +# define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 +# define ENGINE_F_ENGINE_SET_ID 129 +# define ENGINE_F_ENGINE_SET_NAME 130 +# define ENGINE_F_ENGINE_TABLE_REGISTER 184 +# define ENGINE_F_ENGINE_UNLOAD_KEY 152 +# define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 +# define ENGINE_F_ENGINE_UP_REF 190 +# define ENGINE_F_INT_CTRL_HELPER 172 +# define ENGINE_F_INT_ENGINE_CONFIGURE 188 +# define ENGINE_F_INT_ENGINE_MODULE_INIT 187 +# define ENGINE_F_LOG_MESSAGE 141 + +/* Reason codes. */ +# define ENGINE_R_ALREADY_LOADED 100 +# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +# define ENGINE_R_CMD_NOT_EXECUTABLE 134 +# define ENGINE_R_COMMAND_TAKES_INPUT 135 +# define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 +# define ENGINE_R_CONFLICTING_ENGINE_ID 103 +# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +# define ENGINE_R_DH_NOT_IMPLEMENTED 139 +# define ENGINE_R_DSA_NOT_IMPLEMENTED 140 +# define ENGINE_R_DSO_FAILURE 104 +# define ENGINE_R_DSO_NOT_FOUND 132 +# define ENGINE_R_ENGINES_SECTION_ERROR 148 +# define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 +# define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +# define ENGINE_R_ENGINE_SECTION_ERROR 149 +# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +# define ENGINE_R_FINISH_FAILED 106 +# define ENGINE_R_GET_HANDLE_FAILED 107 +# define ENGINE_R_ID_OR_NAME_MISSING 108 +# define ENGINE_R_INIT_FAILED 109 +# define ENGINE_R_INTERNAL_LIST_ERROR 110 +# define ENGINE_R_INVALID_ARGUMENT 143 +# define ENGINE_R_INVALID_CMD_NAME 137 +# define ENGINE_R_INVALID_CMD_NUMBER 138 +# define ENGINE_R_INVALID_INIT_VALUE 151 +# define ENGINE_R_INVALID_STRING 150 +# define ENGINE_R_NOT_INITIALISED 117 +# define ENGINE_R_NOT_LOADED 112 +# define ENGINE_R_NO_CONTROL_FUNCTION 120 +# define ENGINE_R_NO_INDEX 144 +# define ENGINE_R_NO_LOAD_FUNCTION 125 +# define ENGINE_R_NO_REFERENCE 130 +# define ENGINE_R_NO_SUCH_ENGINE 116 +# define ENGINE_R_NO_UNLOAD_FUNCTION 126 +# define ENGINE_R_PROVIDE_PARAMETERS 113 +# define ENGINE_R_RSA_NOT_IMPLEMENTED 141 +# define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +# define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 +# define ENGINE_R_VERSION_INCOMPATIBILITY 145 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/err.c b/Sources/COpenSSL/err.c new file mode 100644 index 00000000..90254493 --- /dev/null +++ b/Sources/COpenSSL/err.c @@ -0,0 +1,1158 @@ +/* crypto/err/err.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include "lhash.h" +#include "crypto.h" +#include "buffer.h" +#include "bio.h" +#include "err.h" + +DECLARE_LHASH_OF(ERR_STRING_DATA); +DECLARE_LHASH_OF(ERR_STATE); + +static void err_load_strings(int lib, ERR_STRING_DATA *str); + +static void ERR_STATE_free(ERR_STATE *s); +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA ERR_str_libraries[] = { + {ERR_PACK(ERR_LIB_NONE, 0, 0), "unknown library"}, + {ERR_PACK(ERR_LIB_SYS, 0, 0), "system library"}, + {ERR_PACK(ERR_LIB_BN, 0, 0), "bignum routines"}, + {ERR_PACK(ERR_LIB_RSA, 0, 0), "rsa routines"}, + {ERR_PACK(ERR_LIB_DH, 0, 0), "Diffie-Hellman routines"}, + {ERR_PACK(ERR_LIB_EVP, 0, 0), "digital envelope routines"}, + {ERR_PACK(ERR_LIB_BUF, 0, 0), "memory buffer routines"}, + {ERR_PACK(ERR_LIB_OBJ, 0, 0), "object identifier routines"}, + {ERR_PACK(ERR_LIB_PEM, 0, 0), "PEM routines"}, + {ERR_PACK(ERR_LIB_DSA, 0, 0), "dsa routines"}, + {ERR_PACK(ERR_LIB_X509, 0, 0), "x509 certificate routines"}, + {ERR_PACK(ERR_LIB_ASN1, 0, 0), "asn1 encoding routines"}, + {ERR_PACK(ERR_LIB_CONF, 0, 0), "configuration file routines"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, 0), "common libcrypto routines"}, + {ERR_PACK(ERR_LIB_EC, 0, 0), "elliptic curve routines"}, + {ERR_PACK(ERR_LIB_SSL, 0, 0), "SSL routines"}, + {ERR_PACK(ERR_LIB_BIO, 0, 0), "BIO routines"}, + {ERR_PACK(ERR_LIB_PKCS7, 0, 0), "PKCS7 routines"}, + {ERR_PACK(ERR_LIB_X509V3, 0, 0), "X509 V3 routines"}, + {ERR_PACK(ERR_LIB_PKCS12, 0, 0), "PKCS12 routines"}, + {ERR_PACK(ERR_LIB_RAND, 0, 0), "random number generator"}, + {ERR_PACK(ERR_LIB_DSO, 0, 0), "DSO support routines"}, + {ERR_PACK(ERR_LIB_TS, 0, 0), "time stamp routines"}, + {ERR_PACK(ERR_LIB_ENGINE, 0, 0), "engine routines"}, + {ERR_PACK(ERR_LIB_OCSP, 0, 0), "OCSP routines"}, + {ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"}, + {ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"}, + {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"}, + {0, NULL}, +}; + +static ERR_STRING_DATA ERR_str_functs[] = { + {ERR_PACK(0, SYS_F_FOPEN, 0), "fopen"}, + {ERR_PACK(0, SYS_F_CONNECT, 0), "connect"}, + {ERR_PACK(0, SYS_F_GETSERVBYNAME, 0), "getservbyname"}, + {ERR_PACK(0, SYS_F_SOCKET, 0), "socket"}, + {ERR_PACK(0, SYS_F_IOCTLSOCKET, 0), "ioctlsocket"}, + {ERR_PACK(0, SYS_F_BIND, 0), "bind"}, + {ERR_PACK(0, SYS_F_LISTEN, 0), "listen"}, + {ERR_PACK(0, SYS_F_ACCEPT, 0), "accept"}, +# ifdef OPENSSL_SYS_WINDOWS + {ERR_PACK(0, SYS_F_WSASTARTUP, 0), "WSAstartup"}, +# endif + {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"}, + {ERR_PACK(0, SYS_F_FREAD, 0), "fread"}, + {ERR_PACK(0, SYS_F_FFLUSH, 0), "fflush"}, + {0, NULL}, +}; + +static ERR_STRING_DATA ERR_str_reasons[] = { + {ERR_R_SYS_LIB, "system lib"}, + {ERR_R_BN_LIB, "BN lib"}, + {ERR_R_RSA_LIB, "RSA lib"}, + {ERR_R_DH_LIB, "DH lib"}, + {ERR_R_EVP_LIB, "EVP lib"}, + {ERR_R_BUF_LIB, "BUF lib"}, + {ERR_R_OBJ_LIB, "OBJ lib"}, + {ERR_R_PEM_LIB, "PEM lib"}, + {ERR_R_DSA_LIB, "DSA lib"}, + {ERR_R_X509_LIB, "X509 lib"}, + {ERR_R_ASN1_LIB, "ASN1 lib"}, + {ERR_R_CONF_LIB, "CONF lib"}, + {ERR_R_CRYPTO_LIB, "CRYPTO lib"}, + {ERR_R_EC_LIB, "EC lib"}, + {ERR_R_SSL_LIB, "SSL lib"}, + {ERR_R_BIO_LIB, "BIO lib"}, + {ERR_R_PKCS7_LIB, "PKCS7 lib"}, + {ERR_R_X509V3_LIB, "X509V3 lib"}, + {ERR_R_PKCS12_LIB, "PKCS12 lib"}, + {ERR_R_RAND_LIB, "RAND lib"}, + {ERR_R_DSO_LIB, "DSO lib"}, + {ERR_R_ENGINE_LIB, "ENGINE lib"}, + {ERR_R_OCSP_LIB, "OCSP lib"}, + {ERR_R_TS_LIB, "TS lib"}, + + {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"}, + {ERR_R_BAD_ASN1_OBJECT_HEADER, "bad asn1 object header"}, + {ERR_R_BAD_GET_ASN1_OBJECT_CALL, "bad get asn1 object call"}, + {ERR_R_EXPECTING_AN_ASN1_SEQUENCE, "expecting an asn1 sequence"}, + {ERR_R_ASN1_LENGTH_MISMATCH, "asn1 length mismatch"}, + {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"}, + + {ERR_R_FATAL, "fatal"}, + {ERR_R_MALLOC_FAILURE, "malloc failure"}, + {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, + "called a function you should not call"}, + {ERR_R_PASSED_NULL_PARAMETER, "passed a null parameter"}, + {ERR_R_INTERNAL_ERROR, "internal error"}, + {ERR_R_DISABLED, "called a function that was disabled at compile-time"}, + + {0, NULL}, +}; +#endif + +/* Define the predeclared (but externally opaque) "ERR_FNS" type */ +struct st_ERR_FNS { + /* Works on the "error_hash" string table */ + LHASH_OF(ERR_STRING_DATA) *(*cb_err_get) (int create); + void (*cb_err_del) (void); + ERR_STRING_DATA *(*cb_err_get_item) (const ERR_STRING_DATA *); + ERR_STRING_DATA *(*cb_err_set_item) (ERR_STRING_DATA *); + ERR_STRING_DATA *(*cb_err_del_item) (ERR_STRING_DATA *); + /* Works on the "thread_hash" error-state table */ + LHASH_OF(ERR_STATE) *(*cb_thread_get) (int create); + void (*cb_thread_release) (LHASH_OF(ERR_STATE) **hash); + ERR_STATE *(*cb_thread_get_item) (const ERR_STATE *); + ERR_STATE *(*cb_thread_set_item) (ERR_STATE *); + void (*cb_thread_del_item) (const ERR_STATE *); + /* Returns the next available error "library" numbers */ + int (*cb_get_next_lib) (void); +}; + +/* Predeclarations of the "err_defaults" functions */ +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create); +static void int_err_del(void); +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); +static LHASH_OF(ERR_STATE) *int_thread_get(int create); +static void int_thread_release(LHASH_OF(ERR_STATE) **hash); +static ERR_STATE *int_thread_get_item(const ERR_STATE *); +static ERR_STATE *int_thread_set_item(ERR_STATE *); +static void int_thread_del_item(const ERR_STATE *); +static int int_err_get_next_lib(void); +/* The static ERR_FNS table using these defaults functions */ +static const ERR_FNS err_defaults = { + int_err_get, + int_err_del, + int_err_get_item, + int_err_set_item, + int_err_del_item, + int_thread_get, + int_thread_release, + int_thread_get_item, + int_thread_set_item, + int_thread_del_item, + int_err_get_next_lib +}; + +/* The replacable table of ERR_FNS functions we use at run-time */ +static const ERR_FNS *err_fns = NULL; + +/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */ +#define ERRFN(a) err_fns->cb_##a + +/* + * The internal state used by "err_defaults" - as such, the setting, reading, + * creating, and deleting of this data should only be permitted via the + * "err_defaults" functions. This way, a linked module can completely defer + * all ERR state operation (together with requisite locking) to the + * implementations and state in the loading application. + */ +static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; +static LHASH_OF(ERR_STATE) *int_thread_hash = NULL; +static int int_thread_hash_references = 0; +static int int_err_library_number = ERR_LIB_USER; + +/* + * Internal function that checks whether "err_fns" is set and if not, sets it + * to the defaults. + */ +static void err_fns_check(void) +{ + if (err_fns) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!err_fns) + err_fns = &err_defaults; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} + +/* API functions to get or set the underlying ERR functions. */ + +const ERR_FNS *ERR_get_implementation(void) +{ + err_fns_check(); + return err_fns; +} + +int ERR_set_implementation(const ERR_FNS *fns) +{ + int ret = 0; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + /* + * It's too late if 'err_fns' is non-NULL. BTW: not much point setting an + * error is there?! + */ + if (!err_fns) { + err_fns = fns; + ret = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return ret; +} + +/* + * These are the callbacks provided to "lh_new()" when creating the LHASH + * tables internal to the "err_defaults" implementation. + */ + +static unsigned long get_error_values(int inc, int top, const char **file, + int *line, const char **data, + int *flags); + +/* The internal functions used in the "err_defaults" implementation */ + +static unsigned long err_string_data_hash(const ERR_STRING_DATA *a) +{ + unsigned long ret, l; + + l = a->error; + ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l); + return (ret ^ ret % 19 * 13); +} + +static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA) + +static int err_string_data_cmp(const ERR_STRING_DATA *a, + const ERR_STRING_DATA *b) +{ + return (int)(a->error - b->error); +} + +static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA) + +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create) +{ + LHASH_OF(ERR_STRING_DATA) *ret = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!int_error_hash && create) { + CRYPTO_push_info("int_err_get (err.c)"); + int_error_hash = lh_ERR_STRING_DATA_new(); + CRYPTO_pop_info(); + } + if (int_error_hash) + ret = int_error_hash; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; +} + +static void int_err_del(void) +{ + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (int_error_hash) { + lh_ERR_STRING_DATA_free(int_error_hash); + int_error_hash = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} + +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get) (0); + if (!hash) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_retrieve(hash, d); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get) (1); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_insert(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get) (0); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_delete(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static unsigned long err_state_hash(const ERR_STATE *a) +{ + return CRYPTO_THREADID_hash(&a->tid) * 13; +} + +static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE) + +static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b) +{ + return CRYPTO_THREADID_cmp(&a->tid, &b->tid); +} + +static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE) + +static LHASH_OF(ERR_STATE) *int_thread_get(int create) +{ + LHASH_OF(ERR_STATE) *ret = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!int_thread_hash && create) { + CRYPTO_push_info("int_thread_get (err.c)"); + int_thread_hash = lh_ERR_STATE_new(); + CRYPTO_pop_info(); + } + if (int_thread_hash) { + int_thread_hash_references++; + ret = int_thread_hash; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return ret; +} + +static void int_thread_release(LHASH_OF(ERR_STATE) **hash) +{ + int i; + + if (hash == NULL || *hash == NULL) + return; + + i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR); + +#ifdef REF_PRINT + fprintf(stderr, "%4d:%s\n", int_thread_hash_references, "ERR"); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "int_thread_release, bad reference count\n"); + abort(); /* ok */ + } +#endif + *hash = NULL; +} + +static ERR_STATE *int_thread_get_item(const ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get) (0); + if (!hash) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_retrieve(hash, d); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release) (&hash); + return p; +} + +static ERR_STATE *int_thread_set_item(ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get) (1); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_insert(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release) (&hash); + return p; +} + +static void int_thread_del_item(const ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get) (0); + if (!hash) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_delete(hash, d); + /* make sure we don't leak memory */ + if (int_thread_hash_references == 1 + && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) { + lh_ERR_STATE_free(int_thread_hash); + int_thread_hash = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release) (&hash); + if (p) + ERR_STATE_free(p); +} + +static int int_err_get_next_lib(void) +{ + int ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + ret = int_err_library_number++; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; +} + +#ifndef OPENSSL_NO_ERR +# define NUM_SYS_STR_REASONS 127 +# define LEN_SYS_STR_REASON 32 + +static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; +/* + * SYS_str_reasons is filled with copies of strerror() results at + * initialization. 'errno' values up to 127 should cover all usual errors, + * others will be displayed numerically by ERR_error_string. It is crucial + * that we have something for each reason code that occurs in + * ERR_str_reasons, or bogus reason strings will be returned for SYSerr(), + * which always gets an errno value and never one of those 'standard' reason + * codes. + */ + +static void build_SYS_str_reasons(void) +{ + /* OPENSSL_malloc cannot be used here, use static storage instead */ + static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON]; + int i; + static int init = 1; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + if (!init) { + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + return; + } + + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!init) { + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return; + } + + for (i = 1; i <= NUM_SYS_STR_REASONS; i++) { + ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; + + str->error = (unsigned long)i; + if (str->string == NULL) { + char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]); + char *src = strerror(i); + if (src != NULL) { + strncpy(*dest, src, sizeof(*dest)); + (*dest)[sizeof(*dest) - 1] = '\0'; + str->string = *dest; + } + } + if (str->string == NULL) + str->string = "unknown"; + } + + /* + * Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, as + * required by ERR_load_strings. + */ + + init = 0; + + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} +#endif + +#define err_clear_data(p,i) \ + do { \ + if (((p)->err_data[i] != NULL) && \ + (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \ + { \ + OPENSSL_free((p)->err_data[i]); \ + (p)->err_data[i]=NULL; \ + } \ + (p)->err_data_flags[i]=0; \ + } while(0) + +#define err_clear(p,i) \ + do { \ + (p)->err_flags[i]=0; \ + (p)->err_buffer[i]=0; \ + err_clear_data(p,i); \ + (p)->err_file[i]=NULL; \ + (p)->err_line[i]= -1; \ + } while(0) + +static void ERR_STATE_free(ERR_STATE *s) +{ + int i; + + if (s == NULL) + return; + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear_data(s, i); + } + OPENSSL_free(s); +} + +void ERR_load_ERR_strings(void) +{ + err_fns_check(); +#ifndef OPENSSL_NO_ERR + err_load_strings(0, ERR_str_libraries); + err_load_strings(0, ERR_str_reasons); + err_load_strings(ERR_LIB_SYS, ERR_str_functs); + build_SYS_str_reasons(); + err_load_strings(ERR_LIB_SYS, SYS_str_reasons); +#endif +} + +static void err_load_strings(int lib, ERR_STRING_DATA *str) +{ + while (str->error) { + if (lib) + str->error |= ERR_PACK(lib, 0, 0); + ERRFN(err_set_item) (str); + str++; + } +} + +void ERR_load_strings(int lib, ERR_STRING_DATA *str) +{ + ERR_load_ERR_strings(); + err_load_strings(lib, str); +} + +void ERR_unload_strings(int lib, ERR_STRING_DATA *str) +{ + while (str->error) { + if (lib) + str->error |= ERR_PACK(lib, 0, 0); + ERRFN(err_del_item) (str); + str++; + } +} + +void ERR_free_strings(void) +{ + err_fns_check(); + ERRFN(err_del) (); +} + +/********************************************************/ + +void ERR_put_error(int lib, int func, int reason, const char *file, int line) +{ + ERR_STATE *es; + +#ifdef _OSD_POSIX + /* + * In the BS2000-OSD POSIX subsystem, the compiler generates path names + * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to + * something sensible. @@@ We shouldn't modify a const string, though. + */ + if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) { + char *end; + + /* Skip the "*POSIX(" prefix */ + file += sizeof("*POSIX(") - 1; + end = &file[strlen(file) - 1]; + if (*end == ')') + *end = '\0'; + /* Optional: use the basename of the path only. */ + if ((end = strrchr(file, '/')) != NULL) + file = &end[1]; + } +#endif + es = ERR_get_state(); + if (es == NULL) + return; + + es->top = (es->top + 1) % ERR_NUM_ERRORS; + if (es->top == es->bottom) + es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; + es->err_flags[es->top] = 0; + es->err_buffer[es->top] = ERR_PACK(lib, func, reason); + es->err_file[es->top] = file; + es->err_line[es->top] = line; + err_clear_data(es, es->top); +} + +void ERR_clear_error(void) +{ + int i; + ERR_STATE *es; + + es = ERR_get_state(); + if (es == NULL) + return; + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(es, i); + } + es->top = es->bottom = 0; +} + +unsigned long ERR_get_error(void) +{ + return (get_error_values(1, 0, NULL, NULL, NULL, NULL)); +} + +unsigned long ERR_get_error_line(const char **file, int *line) +{ + return (get_error_values(1, 0, file, line, NULL, NULL)); +} + +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(1, 0, file, line, data, flags)); +} + +unsigned long ERR_peek_error(void) +{ + return (get_error_values(0, 0, NULL, NULL, NULL, NULL)); +} + +unsigned long ERR_peek_error_line(const char **file, int *line) +{ + return (get_error_values(0, 0, file, line, NULL, NULL)); +} + +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(0, 0, file, line, data, flags)); +} + +unsigned long ERR_peek_last_error(void) +{ + return (get_error_values(0, 1, NULL, NULL, NULL, NULL)); +} + +unsigned long ERR_peek_last_error_line(const char **file, int *line) +{ + return (get_error_values(0, 1, file, line, NULL, NULL)); +} + +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(0, 1, file, line, data, flags)); +} + +static unsigned long get_error_values(int inc, int top, const char **file, + int *line, const char **data, + int *flags) +{ + int i = 0; + ERR_STATE *es; + unsigned long ret; + + es = ERR_get_state(); + if (es == NULL) + return 0; + + if (inc && top) { + if (file) + *file = ""; + if (line) + *line = 0; + if (data) + *data = ""; + if (flags) + *flags = 0; + + return ERR_R_INTERNAL_ERROR; + } + + if (es->bottom == es->top) + return 0; + if (top) + i = es->top; /* last error */ + else + i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ + + ret = es->err_buffer[i]; + if (inc) { + es->bottom = i; + es->err_buffer[i] = 0; + } + + if ((file != NULL) && (line != NULL)) { + if (es->err_file[i] == NULL) { + *file = "NA"; + if (line != NULL) + *line = 0; + } else { + *file = es->err_file[i]; + if (line != NULL) + *line = es->err_line[i]; + } + } + + if (data == NULL) { + if (inc) { + err_clear_data(es, i); + } + } else { + if (es->err_data[i] == NULL) { + *data = ""; + if (flags != NULL) + *flags = 0; + } else { + *data = es->err_data[i]; + if (flags != NULL) + *flags = es->err_data_flags[i]; + } + } + return ret; +} + +void ERR_error_string_n(unsigned long e, char *buf, size_t len) +{ + char lsbuf[64], fsbuf[64], rsbuf[64]; + const char *ls, *fs, *rs; + unsigned long l, f, r; + + if (len == 0) + return; + + l = ERR_GET_LIB(e); + f = ERR_GET_FUNC(e); + r = ERR_GET_REASON(e); + + ls = ERR_lib_error_string(e); + fs = ERR_func_error_string(e); + rs = ERR_reason_error_string(e); + + if (ls == NULL) + BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); + if (fs == NULL) + BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); + if (rs == NULL) + BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); + + BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls ? ls : lsbuf, + fs ? fs : fsbuf, rs ? rs : rsbuf); + if (strlen(buf) == len - 1) { + /* + * output may be truncated; make sure we always have 5 + * colon-separated fields, i.e. 4 colons ... + */ +#define NUM_COLONS 4 + if (len > NUM_COLONS) { /* ... if possible */ + int i; + char *s = buf; + + for (i = 0; i < NUM_COLONS; i++) { + char *colon = strchr(s, ':'); + if (colon == NULL || colon > &buf[len - 1] - NUM_COLONS + i) { + /* + * set colon no. i at last possible position (buf[len-1] + * is the terminating 0) + */ + colon = &buf[len - 1] - NUM_COLONS + i; + *colon = ':'; + } + s = colon + 1; + } + } + } +} + +/* BAD for multi-threading: uses a local buffer if ret == NULL */ +/* + * ERR_error_string_n should be used instead for ret != NULL as + * ERR_error_string cannot know how large the buffer is + */ +char *ERR_error_string(unsigned long e, char *ret) +{ + static char buf[256]; + + if (ret == NULL) + ret = buf; + ERR_error_string_n(e, ret, 256); + + return ret; +} + +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void) +{ + err_fns_check(); + return ERRFN(err_get) (0); +} + +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void) +{ + err_fns_check(); + return ERRFN(thread_get) (0); +} + +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash) +{ + err_fns_check(); + ERRFN(thread_release) (hash); +} + +const char *ERR_lib_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p; + unsigned long l; + + err_fns_check(); + l = ERR_GET_LIB(e); + d.error = ERR_PACK(l, 0, 0); + p = ERRFN(err_get_item) (&d); + return ((p == NULL) ? NULL : p->string); +} + +const char *ERR_func_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p; + unsigned long l, f; + + err_fns_check(); + l = ERR_GET_LIB(e); + f = ERR_GET_FUNC(e); + d.error = ERR_PACK(l, f, 0); + p = ERRFN(err_get_item) (&d); + return ((p == NULL) ? NULL : p->string); +} + +const char *ERR_reason_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p = NULL; + unsigned long l, r; + + err_fns_check(); + l = ERR_GET_LIB(e); + r = ERR_GET_REASON(e); + d.error = ERR_PACK(l, 0, r); + p = ERRFN(err_get_item) (&d); + if (!p) { + d.error = ERR_PACK(0, 0, r); + p = ERRFN(err_get_item) (&d); + } + return ((p == NULL) ? NULL : p->string); +} + +void ERR_remove_thread_state(const CRYPTO_THREADID *id) +{ + ERR_STATE tmp; + + if (id) + CRYPTO_THREADID_cpy(&tmp.tid, id); + else + CRYPTO_THREADID_current(&tmp.tid); + err_fns_check(); + /* + * thread_del_item automatically destroys the LHASH if the number of + * items reaches zero. + */ + ERRFN(thread_del_item) (&tmp); +} + +#ifndef OPENSSL_NO_DEPRECATED +void ERR_remove_state(unsigned long pid) +{ + ERR_remove_thread_state(NULL); +} +#endif + +ERR_STATE *ERR_get_state(void) +{ + ERR_STATE *ret, tmp, *tmpp = NULL; + int i; + CRYPTO_THREADID tid; + + err_fns_check(); + CRYPTO_THREADID_current(&tid); + CRYPTO_THREADID_cpy(&tmp.tid, &tid); + ret = ERRFN(thread_get_item) (&tmp); + + /* ret == the error state, if NULL, make a new one */ + if (ret == NULL) { + ret = (ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); + if (ret == NULL) + return NULL; + CRYPTO_THREADID_cpy(&ret->tid, &tid); + ret->top = 0; + ret->bottom = 0; + for (i = 0; i < ERR_NUM_ERRORS; i++) { + ret->err_data[i] = NULL; + ret->err_data_flags[i] = 0; + } + tmpp = ERRFN(thread_set_item) (ret); + /* To check if insertion failed, do a get. */ + if (ERRFN(thread_get_item) (ret) != ret) { + ERR_STATE_free(ret); /* could not insert it */ + return NULL; + } + /* + * If a race occured in this function and we came second, tmpp is the + * first one that we just replaced. + */ + if (tmpp) + ERR_STATE_free(tmpp); + } + return ret; +} + +int ERR_get_next_error_library(void) +{ + err_fns_check(); + return ERRFN(get_next_lib) (); +} + +void ERR_set_error_data(char *data, int flags) +{ + ERR_STATE *es; + int i; + + es = ERR_get_state(); + if (es == NULL) + return; + + i = es->top; + + err_clear_data(es, i); + es->err_data[i] = data; + es->err_data_flags[i] = flags; +} + +void ERR_add_error_data(int num, ...) +{ + va_list args; + va_start(args, num); + ERR_add_error_vdata(num, args); + va_end(args); +} + +void ERR_add_error_vdata(int num, va_list args) +{ + int i, n, s; + char *str, *p, *a; + + s = 80; + str = OPENSSL_malloc(s + 1); + if (str == NULL) + return; + str[0] = '\0'; + + n = 0; + for (i = 0; i < num; i++) { + a = va_arg(args, char *); + /* ignore NULLs, thanks to Bob Beck */ + if (a != NULL) { + n += strlen(a); + if (n > s) { + s = n + 20; + p = OPENSSL_realloc(str, s + 1); + if (p == NULL) { + OPENSSL_free(str); + return; + } else + str = p; + } + BUF_strlcat(str, a, (size_t)s + 1); + } + } + ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING); +} + +int ERR_set_mark(void) +{ + ERR_STATE *es; + + es = ERR_get_state(); + if (es == NULL) + return 0; + + if (es->bottom == es->top) + return 0; + es->err_flags[es->top] |= ERR_FLAG_MARK; + return 1; +} + +int ERR_pop_to_mark(void) +{ + ERR_STATE *es; + + es = ERR_get_state(); + if (es == NULL) + return 0; + + while (es->bottom != es->top + && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { + err_clear(es, es->top); + es->top -= 1; + if (es->top == -1) + es->top = ERR_NUM_ERRORS - 1; + } + + if (es->bottom == es->top) + return 0; + es->err_flags[es->top] &= ~ERR_FLAG_MARK; + return 1; +} diff --git a/Sources/COpenSSL/err.h b/Sources/COpenSSL/err.h new file mode 100644 index 00000000..250af838 --- /dev/null +++ b/Sources/COpenSSL/err.h @@ -0,0 +1,390 @@ +/* crypto/err/err.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ERR_H +# define HEADER_ERR_H + +# include "e_os2.h" + +# ifndef OPENSSL_NO_FP_API +# include +# include +# endif + +# include "ossl_typ.h" +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# ifndef OPENSSL_NO_LHASH +# include "lhash.h" +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_NO_ERR +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +# else +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +# endif + +# include + +# define ERR_TXT_MALLOCED 0x01 +# define ERR_TXT_STRING 0x02 + +# define ERR_FLAG_MARK 0x01 + +# define ERR_NUM_ERRORS 16 +typedef struct err_state_st { + CRYPTO_THREADID tid; + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top, bottom; +} ERR_STATE; + +/* library */ +# define ERR_LIB_NONE 1 +# define ERR_LIB_SYS 2 +# define ERR_LIB_BN 3 +# define ERR_LIB_RSA 4 +# define ERR_LIB_DH 5 +# define ERR_LIB_EVP 6 +# define ERR_LIB_BUF 7 +# define ERR_LIB_OBJ 8 +# define ERR_LIB_PEM 9 +# define ERR_LIB_DSA 10 +# define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +# define ERR_LIB_ASN1 13 +# define ERR_LIB_CONF 14 +# define ERR_LIB_CRYPTO 15 +# define ERR_LIB_EC 16 +# define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +# define ERR_LIB_BIO 32 +# define ERR_LIB_PKCS7 33 +# define ERR_LIB_X509V3 34 +# define ERR_LIB_PKCS12 35 +# define ERR_LIB_RAND 36 +# define ERR_LIB_DSO 37 +# define ERR_LIB_ENGINE 38 +# define ERR_LIB_OCSP 39 +# define ERR_LIB_UI 40 +# define ERR_LIB_COMP 41 +# define ERR_LIB_ECDSA 42 +# define ERR_LIB_ECDH 43 +# define ERR_LIB_STORE 44 +# define ERR_LIB_FIPS 45 +# define ERR_LIB_CMS 46 +# define ERR_LIB_TS 47 +# define ERR_LIB_HMAC 48 +# define ERR_LIB_JPAKE 49 + +# define ERR_LIB_USER 128 + +# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__) +# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__) +# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__) +# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__) +# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__) +# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__) +# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__) +# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__) +# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__) +# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__) +# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__) +# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__) +# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__) +# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__) +# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__) +# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__) +# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__) +# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__) +# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__) +# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__) +# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__) +# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__) +# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__) +# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__) +# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__) +# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) +# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) +# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) +# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) +# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) +# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) +# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) +# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) + +/* + * Borland C seems too stupid to be able to shift and do longs in the + * pre-processor :-( + */ +# define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)*0x1000000)| \ + ((((unsigned long)f)&0xfffL)*0x1000)| \ + ((((unsigned long)r)&0xfffL))) +# define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL) +# define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL) +# define ERR_GET_REASON(l) (int)((l)&0xfffL) +# define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL) + +/* OS functions */ +# define SYS_F_FOPEN 1 +# define SYS_F_CONNECT 2 +# define SYS_F_GETSERVBYNAME 3 +# define SYS_F_SOCKET 4 +# define SYS_F_IOCTLSOCKET 5 +# define SYS_F_BIND 6 +# define SYS_F_LISTEN 7 +# define SYS_F_ACCEPT 8 +# define SYS_F_WSASTARTUP 9/* Winsock stuff */ +# define SYS_F_OPENDIR 10 +# define SYS_F_FREAD 11 +# define SYS_F_FFLUSH 18 + +/* reasons */ +# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ +# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */ +# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */ +# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */ +# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */ +# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */ +# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */ +# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */ +# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */ +# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */ +# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */ +# define ERR_R_CONF_LIB ERR_LIB_CONF/* 14 */ +# define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO/* 15 */ +# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */ +# define ERR_R_SSL_LIB ERR_LIB_SSL/* 20 */ +# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */ +# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */ +# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */ +# define ERR_R_PKCS12_LIB ERR_LIB_PKCS12/* 35 */ +# define ERR_R_RAND_LIB ERR_LIB_RAND/* 36 */ +# define ERR_R_DSO_LIB ERR_LIB_DSO/* 37 */ +# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ +# define ERR_R_OCSP_LIB ERR_LIB_OCSP/* 39 */ +# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ +# define ERR_R_COMP_LIB ERR_LIB_COMP/* 41 */ +# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ +# define ERR_R_ECDH_LIB ERR_LIB_ECDH/* 43 */ +# define ERR_R_STORE_LIB ERR_LIB_STORE/* 44 */ +# define ERR_R_TS_LIB ERR_LIB_TS/* 45 */ + +# define ERR_R_NESTED_ASN1_ERROR 58 +# define ERR_R_BAD_ASN1_OBJECT_HEADER 59 +# define ERR_R_BAD_GET_ASN1_OBJECT_CALL 60 +# define ERR_R_EXPECTING_AN_ASN1_SEQUENCE 61 +# define ERR_R_ASN1_LENGTH_MISMATCH 62 +# define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +# define ERR_R_FATAL 64 +# define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +# define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +# define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +# define ERR_R_DISABLED (5|ERR_R_FATAL) + +/* + * 99 is the maximum possible ERR_R_... code, higher values are reserved for + * the individual libraries + */ + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +void ERR_put_error(int lib, int func, int reason, const char *file, int line); +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags); +void ERR_clear_error(void); +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_FP_API +void ERR_print_errors_fp(FILE *fp); +# endif +# ifndef OPENSSL_NO_BIO +void ERR_print_errors(BIO *bp); +# endif +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +void ERR_load_strings(int lib, ERR_STRING_DATA str[]); +void ERR_unload_strings(int lib, ERR_STRING_DATA str[]); +void ERR_load_ERR_strings(void); +void ERR_load_crypto_strings(void); +void ERR_free_strings(void); + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid); +# ifndef OPENSSL_NO_DEPRECATED +void ERR_remove_state(unsigned long pid); /* if zero we look it up */ +# endif +ERR_STATE *ERR_get_state(void); + +# ifndef OPENSSL_NO_LHASH +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void); +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void); +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash); +# endif + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); + +/* Already defined in ossl_typ.h */ +/* typedef struct st_ERR_FNS ERR_FNS; */ +/* + * An application can use this function and provide the return value to + * loaded modules that should use the application's ERR state/functionality + */ +const ERR_FNS *ERR_get_implementation(void); +/* + * A loaded module should call this function prior to any ERR operations + * using the application's "ERR_FNS". + */ +int ERR_set_implementation(const ERR_FNS *fns); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/err_.c b/Sources/COpenSSL/err_.c new file mode 100644 index 00000000..9c981be7 --- /dev/null +++ b/Sources/COpenSSL/err_.c @@ -0,0 +1,281 @@ +/* crypto/err/err_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "asn1.h" +#include "bn.h" +#ifndef OPENSSL_NO_EC +# include "ec.h" +#endif +#include "buffer.h" +#include "bio.h" +#ifndef OPENSSL_NO_COMP +# include "comp.h" +#endif +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_ECDSA +# include "ecdsa.h" +#endif +#ifndef OPENSSL_NO_ECDH +# include "ecdh.h" +#endif +#include "evp.h" +#include "objects.h" +#include "pem2.h" +#include "x509.h" +#include "x509v3.h" +#include "conf.h" +#include "pkcs12.h" +#include "rand.h" +#include "dso.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +#include "ui.h" +#include "ocsp.h" +#include "err.h" +#ifdef OPENSSL_FIPS +# include +#endif +#include "ts.h" +#ifndef OPENSSL_NO_CMS +# include "cms.h" +#endif +#ifndef OPENSSL_NO_JPAKE +# include +#endif + +void ERR_load_crypto_strings(void) +{ +#ifndef OPENSSL_NO_ERR + ERR_load_ERR_strings(); /* include error strings for SYSerr */ + ERR_load_BN_strings(); +# ifndef OPENSSL_NO_RSA + ERR_load_RSA_strings(); +# endif +# ifndef OPENSSL_NO_DH + ERR_load_DH_strings(); +# endif + ERR_load_EVP_strings(); + ERR_load_BUF_strings(); + ERR_load_OBJ_strings(); + ERR_load_PEM_strings(); +# ifndef OPENSSL_NO_DSA + ERR_load_DSA_strings(); +# endif + ERR_load_X509_strings(); + ERR_load_ASN1_strings(); + ERR_load_CONF_strings(); + ERR_load_CRYPTO_strings(); +# ifndef OPENSSL_NO_COMP + ERR_load_COMP_strings(); +# endif +# ifndef OPENSSL_NO_EC + ERR_load_EC_strings(); +# endif +# ifndef OPENSSL_NO_ECDSA + ERR_load_ECDSA_strings(); +# endif +# ifndef OPENSSL_NO_ECDH + ERR_load_ECDH_strings(); +# endif + /* skip ERR_load_SSL_strings() because it is not in this library */ + ERR_load_BIO_strings(); + ERR_load_PKCS7_strings(); + ERR_load_X509V3_strings(); + ERR_load_PKCS12_strings(); + ERR_load_RAND_strings(); + ERR_load_DSO_strings(); + ERR_load_TS_strings(); +# ifndef OPENSSL_NO_ENGINE + ERR_load_ENGINE_strings(); +# endif + ERR_load_OCSP_strings(); + ERR_load_UI_strings(); +# ifdef OPENSSL_FIPS + ERR_load_FIPS_strings(); +# endif +# ifndef OPENSSL_NO_CMS + ERR_load_CMS_strings(); +# endif +# ifndef OPENSSL_NO_JPAKE + ERR_load_JPAKE_strings(); +# endif +#endif +} +/* crypto/err/err_prn.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "lhash.h" +#include "crypto.h" +// #include "buffer.h" +// #include "err.h" + +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u) +{ + unsigned long l; + char buf[256]; + char buf2[4096]; + const char *file, *data; + int line, flags; + unsigned long es; + CRYPTO_THREADID cur; + + CRYPTO_THREADID_current(&cur); + es = CRYPTO_THREADID_hash(&cur); + while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { + ERR_error_string_n(l, buf, sizeof(buf)); + BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, buf, + file, line, (flags & ERR_TXT_STRING) ? data : ""); + if (cb(buf2, strlen(buf2), u) <= 0) + break; /* abort outputting the error report */ + } +} + +#ifndef OPENSSL_NO_FP_API +static int print_fp(const char *str, size_t len, void *fp) +{ + BIO bio; + + BIO_set(&bio, BIO_s_file()); + BIO_set_fp(&bio, fp, BIO_NOCLOSE); + + return BIO_printf(&bio, "%s", str); +} + +void ERR_print_errors_fp(FILE *fp) +{ + ERR_print_errors_cb(print_fp, fp); +} +#endif + +static int print_bio(const char *str, size_t len, void *bp) +{ + return BIO_write((BIO *)bp, str, len); +} + +void ERR_print_errors(BIO *bp) +{ + ERR_print_errors_cb(print_bio, bp); +} diff --git a/Sources/COpenSSL/evp.h b/Sources/COpenSSL/evp.h new file mode 100644 index 00000000..0646db43 --- /dev/null +++ b/Sources/COpenSSL/evp.h @@ -0,0 +1,1628 @@ +/* crypto/evp/evp.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ENVELOPE_H +# define HEADER_ENVELOPE_H + +# ifdef OPENSSL_ALGORITHM_DEFINES +# include "opensslconf.h" +# else +# define OPENSSL_ALGORITHM_DEFINES +# include "opensslconf.h" +# undef OPENSSL_ALGORITHM_DEFINES +# endif + +# include "ossl_typ.h" + +# include "symhacks.h" + +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif + +/*- +#define EVP_RC2_KEY_SIZE 16 +#define EVP_RC4_KEY_SIZE 16 +#define EVP_BLOWFISH_KEY_SIZE 16 +#define EVP_CAST5_KEY_SIZE 16 +#define EVP_RC5_32_12_16_KEY_SIZE 16 +*/ +# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ +# define EVP_MAX_KEY_LENGTH 64 +# define EVP_MAX_IV_LENGTH 16 +# define EVP_MAX_BLOCK_LENGTH 32 + +# define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +# define PKCS5_DEFAULT_ITER 2048 + +# include "objects.h" + +# define EVP_PK_RSA 0x0001 +# define EVP_PK_DSA 0x0002 +# define EVP_PK_DH 0x0004 +# define EVP_PK_EC 0x0008 +# define EVP_PKT_SIGN 0x0010 +# define EVP_PKT_ENC 0x0020 +# define EVP_PKT_EXCH 0x0040 +# define EVP_PKS_RSA 0x0100 +# define EVP_PKS_DSA 0x0200 +# define EVP_PKS_EC 0x0400 + +# define EVP_PKEY_NONE NID_undef +# define EVP_PKEY_RSA NID_rsaEncryption +# define EVP_PKEY_RSA2 NID_rsa +# define EVP_PKEY_DSA NID_dsa +# define EVP_PKEY_DSA1 NID_dsa_2 +# define EVP_PKEY_DSA2 NID_dsaWithSHA +# define EVP_PKEY_DSA3 NID_dsaWithSHA1 +# define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +# define EVP_PKEY_DH NID_dhKeyAgreement +# define EVP_PKEY_DHX NID_dhpublicnumber +# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +# define EVP_PKEY_HMAC NID_hmac +# define EVP_PKEY_CMAC NID_cmac + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Type needs to be a bit field Sub-type needs to be for variations on the + * method, as in, can it do arbitrary encryption.... + */ +struct evp_pkey_st { + int type; + int save_type; + int references; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; + union { + char *ptr; +# ifndef OPENSSL_NO_RSA + struct rsa_st *rsa; /* RSA */ +# endif +# ifndef OPENSSL_NO_DSA + struct dsa_st *dsa; /* DSA */ +# endif +# ifndef OPENSSL_NO_DH + struct dh_st *dh; /* DH */ +# endif +# ifndef OPENSSL_NO_EC + struct ec_key_st *ec; /* ECC */ +# endif + } pkey; + int save_parameters; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} /* EVP_PKEY */ ; + +# define EVP_PKEY_MO_SIGN 0x0001 +# define EVP_PKEY_MO_VERIFY 0x0002 +# define EVP_PKEY_MO_ENCRYPT 0x0004 +# define EVP_PKEY_MO_DECRYPT 0x0008 + +# ifndef EVP_MD +struct env_md_st { + int type; + int pkey_type; + int md_size; + unsigned long flags; + int (*init) (EVP_MD_CTX *ctx); + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); + int (*final) (EVP_MD_CTX *ctx, unsigned char *md); + int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from); + int (*cleanup) (EVP_MD_CTX *ctx); + /* FIXME: prototype these some day */ + int (*sign) (int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, void *key); + int (*verify) (int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, + void *key); + int required_pkey_type[5]; /* EVP_PKEY_xxx */ + int block_size; + int ctx_size; /* how big does the ctx->md_data need to be */ + /* control function */ + int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2); +} /* EVP_MD */ ; + +typedef int evp_sign_method(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigret, + unsigned int *siglen, void *key); +typedef int evp_verify_method(int type, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, void *key); + +/* digest can only handle a single block */ +# define EVP_MD_FLAG_ONESHOT 0x0001 + +/* + * digest is a "clone" digest used + * which is a copy of an existing + * one for a specific public key type. + * EVP_dss1() etc + */ +# define EVP_MD_FLAG_PKEY_DIGEST 0x0002 + +/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */ + +# define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004 + +/* DigestAlgorithmIdentifier flags... */ + +# define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +# define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +# define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +# define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +/* Note if suitable for use in FIPS mode */ +# define EVP_MD_FLAG_FIPS 0x0400 + +/* Digest ctrls */ + +# define EVP_MD_CTRL_DIGALGID 0x1 +# define EVP_MD_CTRL_MICALG 0x2 + +/* Minimum Algorithm specific ctrl value */ + +# define EVP_MD_CTRL_ALG_CTRL 0x1000 + +# define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_DSA_method (evp_sign_method *)DSA_sign, \ + (evp_verify_method *)DSA_verify, \ + {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \ + EVP_PKEY_DSA4,0} +# else +# define EVP_PKEY_DSA_method EVP_PKEY_NULL_method +# endif + +# ifndef OPENSSL_NO_ECDSA +# define EVP_PKEY_ECDSA_method (evp_sign_method *)ECDSA_sign, \ + (evp_verify_method *)ECDSA_verify, \ + {EVP_PKEY_EC,0,0,0} +# else +# define EVP_PKEY_ECDSA_method EVP_PKEY_NULL_method +# endif + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_RSA_method (evp_sign_method *)RSA_sign, \ + (evp_verify_method *)RSA_verify, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \ + (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \ + (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +# else +# define EVP_PKEY_RSA_method EVP_PKEY_NULL_method +# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method +# endif + +# endif /* !EVP_MD */ + +struct env_md_ctx_st { + const EVP_MD *digest; + ENGINE *engine; /* functional reference if 'digest' is + * ENGINE-provided */ + unsigned long flags; + void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); +} /* EVP_MD_CTX */ ; + +/* values for EVP_MD_CTX flags */ + +# define EVP_MD_CTX_FLAG_ONESHOT 0x0001/* digest update will be + * called once only */ +# define EVP_MD_CTX_FLAG_CLEANED 0x0002/* context has already been + * cleaned */ +# define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data + * in EVP_MD_CTX_cleanup */ +/* + * FIPS and pad options are ignored in 1.0.0, definitions are here so we + * don't accidentally reuse the values for other purposes. + */ + +# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS + * digest in FIPS mode */ + +/* + * The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +# define EVP_MD_CTX_FLAG_PAD_MASK 0xF0/* RSA mode to use */ +# define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */ +# define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */ +# define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */ + +# define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */ + +struct evp_cipher_st { + int nid; + int block_size; + /* Default value for variable length ciphers */ + int key_len; + int iv_len; + /* Various flags */ + unsigned long flags; + /* init key */ + int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + /* encrypt/decrypt data */ + int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + /* cleanup ctx */ + int (*cleanup) (EVP_CIPHER_CTX *); + /* how big ctx->cipher_data needs to be */ + int ctx_size; + /* Populate a ASN1_TYPE with parameters */ + int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); + /* Get parameters from a ASN1_TYPE */ + int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); + /* Miscellaneous operations */ + int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); + /* Application data */ + void *app_data; +} /* EVP_CIPHER */ ; + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +# define EVP_CIPH_STREAM_CIPHER 0x0 +# define EVP_CIPH_ECB_MODE 0x1 +# define EVP_CIPH_CBC_MODE 0x2 +# define EVP_CIPH_CFB_MODE 0x3 +# define EVP_CIPH_OFB_MODE 0x4 +# define EVP_CIPH_CTR_MODE 0x5 +# define EVP_CIPH_GCM_MODE 0x6 +# define EVP_CIPH_CCM_MODE 0x7 +# define EVP_CIPH_XTS_MODE 0x10001 +# define EVP_CIPH_WRAP_MODE 0x10002 +# define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +# define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +# define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +# define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +# define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +# define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +# define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +# define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +# define EVP_CIPH_CUSTOM_COPY 0x400 +/* Allow use default ASN1 get/set iv */ +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +# define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +/* + * Cipher handles any and all padding logic as well as finalisation. + */ +# define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000 + +/* + * Cipher context flag to indicate we can handle wrap mode: if allowed in + * older applications it could overflow buffers. + */ + +# define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1 + +/* ctrl() values */ + +# define EVP_CTRL_INIT 0x0 +# define EVP_CTRL_SET_KEY_LENGTH 0x1 +# define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +# define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +# define EVP_CTRL_GET_RC5_ROUNDS 0x4 +# define EVP_CTRL_SET_RC5_ROUNDS 0x5 +# define EVP_CTRL_RAND_KEY 0x6 +# define EVP_CTRL_PBE_PRF_NID 0x7 +# define EVP_CTRL_COPY 0x8 +# define EVP_CTRL_GCM_SET_IVLEN 0x9 +# define EVP_CTRL_GCM_GET_TAG 0x10 +# define EVP_CTRL_GCM_SET_TAG 0x11 +# define EVP_CTRL_GCM_SET_IV_FIXED 0x12 +# define EVP_CTRL_GCM_IV_GEN 0x13 +# define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN +# define EVP_CTRL_CCM_GET_TAG EVP_CTRL_GCM_GET_TAG +# define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG +# define EVP_CTRL_CCM_SET_L 0x14 +# define EVP_CTRL_CCM_SET_MSGLEN 0x15 +/* + * AEAD cipher deduces payload length and returns number of bytes required to + * store MAC and eventual padding. Subsequent call to EVP_Cipher even + * appends/verifies MAC. + */ +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +/* Set the GCM invocation field, decrypt only */ +# define EVP_CTRL_GCM_SET_IV_INV 0x18 + +# define EVP_CTRL_TLS1_1_MULTIBLOCK_AAD 0x19 +# define EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT 0x1a +# define EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT 0x1b +# define EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE 0x1c + +/* RFC 5246 defines additional data to be 13 bytes in length */ +# define EVP_AEAD_TLS1_AAD_LEN 13 + +typedef struct { + unsigned char *out; + const unsigned char *inp; + size_t len; + unsigned int interleave; +} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM; + +/* GCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_GCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +/* Length of tag for TLS */ +# define EVP_GCM_TLS_TAG_LEN 16 + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + +struct evp_cipher_ctx_st { + const EVP_CIPHER *cipher; + ENGINE *engine; /* functional reference if 'cipher' is + * ENGINE-provided */ + int encrypt; /* encrypt or decrypt */ + int buf_len; /* number we have left */ + unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ + unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */ + int num; /* used by cfb/ofb/ctr mode */ + void *app_data; /* application stuff */ + int key_len; /* May change for variable length cipher */ + unsigned long flags; /* Various flags */ + void *cipher_data; /* per EVP data */ + int final_used; + int block_mask; + unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ +} /* EVP_CIPHER_CTX */ ; + +typedef struct evp_Encode_Ctx_st { + /* number saved in a partial encode/decode */ + int num; + /* + * The length is either the output line length (in input bytes) or the + * shortest input line length that is ok. Once decoding begins, the + * length is adjusted up each time a longer line is decoded + */ + int length; + /* data to encode */ + unsigned char enc_data[80]; + /* number read on current line */ + int line_num; + int expect_nl; +} EVP_ENCODE_CTX; + +/* Password based encryption function */ +typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +# endif + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +# endif + +# ifndef OPENSSL_NO_DH +# define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +# endif + +# ifndef OPENSSL_NO_EC +# define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +# endif + +/* Add some extra combinations */ +# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +# define EVP_MD_nid(e) EVP_MD_type(e) +# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +# define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +# define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); +# define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) + +# define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) +# define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) + +# define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_SignInit(a,b) EVP_DigestInit(a,b) +# define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +# define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +# define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +# define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +# ifdef CONST_STRICT +void BIO_set_md(BIO *, const EVP_MD *md); +# else +# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md) +# endif +# define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp) +# define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp) +# define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp) +# define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp) + +int EVP_Cipher(EVP_CIPHER_CTX *c, + unsigned char *out, const unsigned char *in, unsigned int inl); + +# define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +# define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx); +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_create(void); +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); +int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, const EVP_MD *type, + ENGINE *impl); + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); + +int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); +int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, + const char *prompt, int verify); +void EVP_set_pw_prompt(const char *prompt); +char *EVP_get_pw_prompt(void); + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, + int datal, int count, unsigned char *key, + unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv); +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv); +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + int enc); +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv, int enc); +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, + unsigned char *sigret, size_t *siglen); + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, + const unsigned char *sig, size_t siglen); + +int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, + EVP_PKEY *priv); +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk); +int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned + char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +# ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_md(void); +BIO_METHOD *BIO_f_base64(void); +BIO_METHOD *BIO_f_cipher(void); +BIO_METHOD *BIO_f_reliable(void); +void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int enc); +# endif + +const EVP_MD *EVP_md_null(void); +# ifndef OPENSSL_NO_MD2 +const EVP_MD *EVP_md2(void); +# endif +# ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +# endif +# ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +# endif +# ifndef OPENSSL_NO_SHA +const EVP_MD *EVP_sha(void); +const EVP_MD *EVP_sha1(void); +const EVP_MD *EVP_dss(void); +const EVP_MD *EVP_dss1(void); +const EVP_MD *EVP_ecdsa(void); +# endif +# ifndef OPENSSL_NO_SHA256 +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +# endif +# ifndef OPENSSL_NO_SHA512 +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +# endif +# ifndef OPENSSL_NO_MDC2 +const EVP_MD *EVP_mdc2(void); +# endif +# ifndef OPENSSL_NO_RIPEMD +const EVP_MD *EVP_ripemd160(void); +# endif +# ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +# endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +# ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +# if 0 +const EVP_CIPHER *EVP_des_ede_cfb1(void); +const EVP_CIPHER *EVP_des_ede_cfb8(void); +# endif +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +const EVP_CIPHER *EVP_des_ede3_wrap(void); +/* + * This should now be supported through the dev_crypto ENGINE. But also, why + * are rc4 and md5 declarations made here inside a "NO_DES" precompiler + * branch? + */ +# if 0 +# ifdef OPENSSL_OPENBSD_DEV_CRYPTO +const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void); +const EVP_CIPHER *EVP_dev_crypto_rc4(void); +const EVP_MD *EVP_dev_crypto_md5(void); +# endif +# endif +# endif +# ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +# ifndef OPENSSL_NO_MD5 +const EVP_CIPHER *EVP_rc4_hmac_md5(void); +# endif +# endif +# ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +# endif +# ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +# endif +# ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +# endif +# ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +# endif +# ifndef OPENSSL_NO_RC5 +const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void); +const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void); +# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64 +const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void); +# endif +# ifndef OPENSSL_NO_AES +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +const EVP_CIPHER *EVP_aes_128_ctr(void); +const EVP_CIPHER *EVP_aes_128_ccm(void); +const EVP_CIPHER *EVP_aes_128_gcm(void); +const EVP_CIPHER *EVP_aes_128_xts(void); +const EVP_CIPHER *EVP_aes_128_wrap(void); +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +const EVP_CIPHER *EVP_aes_192_ctr(void); +const EVP_CIPHER *EVP_aes_192_ccm(void); +const EVP_CIPHER *EVP_aes_192_gcm(void); +const EVP_CIPHER *EVP_aes_192_wrap(void); +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +const EVP_CIPHER *EVP_aes_256_ctr(void); +const EVP_CIPHER *EVP_aes_256_ccm(void); +const EVP_CIPHER *EVP_aes_256_gcm(void); +const EVP_CIPHER *EVP_aes_256_xts(void); +const EVP_CIPHER *EVP_aes_256_wrap(void); +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +# endif +# ifndef OPENSSL_NO_SHA256 +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void); +# endif +# endif +# ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +# endif + +# ifndef OPENSSL_NO_SEED +const EVP_CIPHER *EVP_seed_ecb(void); +const EVP_CIPHER *EVP_seed_cbc(void); +const EVP_CIPHER *EVP_seed_cfb128(void); +# define EVP_seed_cfb EVP_seed_cfb128 +const EVP_CIPHER *EVP_seed_ofb(void); +# endif + +void OPENSSL_add_all_algorithms_noconf(void); +void OPENSSL_add_all_algorithms_conf(void); + +# ifdef OPENSSL_LOAD_CONF +# define OpenSSL_add_all_algorithms() \ + OPENSSL_add_all_algorithms_conf() +# else +# define OpenSSL_add_all_algorithms() \ + OPENSSL_add_all_algorithms_noconf() +# endif + +void OpenSSL_add_all_ciphers(void); +void OpenSSL_add_all_digests(void); +# define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms() +# define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers() +# define SSLeay_add_all_digests() OpenSSL_add_all_digests() + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); +void EVP_cleanup(void); + +void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn) + (const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_MD_do_all_sorted(void (*fn) + (const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, + const unsigned char *enc_key, int enc_key_len, + EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, + const unsigned char *key, int key_len, + EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(EVP_PKEY *pkey); +int EVP_PKEY_size(EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +void *EVP_PKEY_get0(EVP_PKEY *pkey); + +# ifndef OPENSSL_NO_RSA +struct rsa_st; +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DSA +struct dsa_st; +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DH +struct dh_st; +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_EC +struct ec_key_st; +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +# endif + +EVP_PKEY *EVP_PKEY_new(void); +void EVP_PKEY_free(EVP_PKEY *pkey); + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +# define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +# define EVP_PBE_TYPE_PRF 0x1 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, + int md_nid, EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); + +# define ASN1_PKEY_ALIAS 0x1 +# define ASN1_PKEY_DYNAMIC 0x2 +# define ASN1_PKEY_SIGPARAM_NULL 0x4 + +# define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +# define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +# define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +# define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 +# define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, + int *ppkey_flags, const char **pinfo, + const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, + const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode) (EVP_PKEY *pk, + X509_PUBKEY *pub), + int (*pub_encode) (X509_PUBKEY *pub, + const EVP_PKEY *pk), + int (*pub_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*pub_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + int (*pkey_size) (const EVP_PKEY *pk), + int (*pkey_bits) (const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode) (EVP_PKEY *pk, + PKCS8_PRIV_KEY_INFO + *p8inf), + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, + const EVP_PKEY *pk), + int (*priv_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, + int derlen), + int (*param_encode) (const EVP_PKEY *pkey, + unsigned char **pder), + int (*param_missing) (const EVP_PKEY *pk), + int (*param_copy) (EVP_PKEY *to, + const EVP_PKEY *from), + int (*param_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*param_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free) (EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, + long arg1, void *arg2)); +void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, + int (*item_verify) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *a, + ASN1_BIT_STRING *sig, + EVP_PKEY *pkey), + int (*item_sign) (EVP_MD_CTX *ctx, + const ASN1_ITEM *it, + void *asn, + X509_ALGOR *alg1, + X509_ALGOR *alg2, + ASN1_BIT_STRING *sig)); + +# define EVP_PKEY_OP_UNDEFINED 0 +# define EVP_PKEY_OP_PARAMGEN (1<<1) +# define EVP_PKEY_OP_KEYGEN (1<<2) +# define EVP_PKEY_OP_SIGN (1<<3) +# define EVP_PKEY_OP_VERIFY (1<<4) +# define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +# define EVP_PKEY_OP_SIGNCTX (1<<6) +# define EVP_PKEY_OP_VERIFYCTX (1<<7) +# define EVP_PKEY_OP_ENCRYPT (1<<8) +# define EVP_PKEY_OP_DECRYPT (1<<9) +# define EVP_PKEY_OP_DERIVE (1<<10) + +# define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +# define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +# define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) + +# define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +# define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_GET_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTRL_MD 1 +# define EVP_PKEY_CTRL_PEER_KEY 2 + +# define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +# define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +# define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +# define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +# define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +# define EVP_PKEY_CTRL_SET_IV 8 + +# define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +# define EVP_PKEY_CTRL_CMS_DECRYPT 10 +# define EVP_PKEY_CTRL_CMS_SIGN 11 + +# define EVP_PKEY_CTRL_CIPHER 12 + +# define EVP_PKEY_CTRL_GET_MD 13 + +# define EVP_PKEY_ALG_CTRL 0x1000 + +# define EVP_PKEY_FLAG_AUTOARGLEN 2 +/* + * Method handles all operations: don't assume any digest related defaults. + */ +# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + const unsigned char *key, int keylen); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb (EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_add_alg_module(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +void ERR_load_EVP_strings(void); + +/* Error codes for the EVP functions. */ + +/* Function codes. */ +# define EVP_F_AESNI_INIT_KEY 165 +# define EVP_F_AESNI_XTS_CIPHER 176 +# define EVP_F_AES_INIT_KEY 133 +# define EVP_F_AES_T4_INIT_KEY 178 +# define EVP_F_AES_XTS 172 +# define EVP_F_AES_XTS_CIPHER 175 +# define EVP_F_ALG_MODULE_INIT 177 +# define EVP_F_CAMELLIA_INIT_KEY 159 +# define EVP_F_CMAC_INIT 173 +# define EVP_F_CMLL_T4_INIT_KEY 179 +# define EVP_F_D2I_PKEY 100 +# define EVP_F_DO_SIGVER_INIT 161 +# define EVP_F_DSAPKEY2PKCS8 134 +# define EVP_F_DSA_PKEY2PKCS8 135 +# define EVP_F_ECDSA_PKEY2PKCS8 129 +# define EVP_F_ECKEY_PKEY2PKCS8 132 +# define EVP_F_EVP_CIPHERINIT_EX 123 +# define EVP_F_EVP_CIPHER_CTX_COPY 163 +# define EVP_F_EVP_CIPHER_CTX_CTRL 124 +# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +# define EVP_F_EVP_DECRYPTFINAL_EX 101 +# define EVP_F_EVP_DIGESTINIT_EX 128 +# define EVP_F_EVP_ENCRYPTFINAL_EX 127 +# define EVP_F_EVP_MD_CTX_COPY_EX 110 +# define EVP_F_EVP_MD_SIZE 162 +# define EVP_F_EVP_OPENINIT 102 +# define EVP_F_EVP_PBE_ALG_ADD 115 +# define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +# define EVP_F_EVP_PBE_CIPHERINIT 116 +# define EVP_F_EVP_PKCS82PKEY 111 +# define EVP_F_EVP_PKCS82PKEY_BROKEN 136 +# define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 +# define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +# define EVP_F_EVP_PKEY_CTX_CTRL 137 +# define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +# define EVP_F_EVP_PKEY_CTX_DUP 156 +# define EVP_F_EVP_PKEY_DECRYPT 104 +# define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +# define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +# define EVP_F_EVP_PKEY_DERIVE 153 +# define EVP_F_EVP_PKEY_DERIVE_INIT 154 +# define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +# define EVP_F_EVP_PKEY_ENCRYPT 105 +# define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +# define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +# define EVP_F_EVP_PKEY_GET1_DH 119 +# define EVP_F_EVP_PKEY_GET1_DSA 120 +# define EVP_F_EVP_PKEY_GET1_ECDSA 130 +# define EVP_F_EVP_PKEY_GET1_EC_KEY 131 +# define EVP_F_EVP_PKEY_GET1_RSA 121 +# define EVP_F_EVP_PKEY_KEYGEN 146 +# define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +# define EVP_F_EVP_PKEY_NEW 106 +# define EVP_F_EVP_PKEY_PARAMGEN 148 +# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +# define EVP_F_EVP_PKEY_SIGN 140 +# define EVP_F_EVP_PKEY_SIGN_INIT 141 +# define EVP_F_EVP_PKEY_VERIFY 142 +# define EVP_F_EVP_PKEY_VERIFY_INIT 143 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +# define EVP_F_EVP_RIJNDAEL 126 +# define EVP_F_EVP_SIGNFINAL 107 +# define EVP_F_EVP_VERIFYFINAL 108 +# define EVP_F_FIPS_CIPHERINIT 166 +# define EVP_F_FIPS_CIPHER_CTX_COPY 170 +# define EVP_F_FIPS_CIPHER_CTX_CTRL 167 +# define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171 +# define EVP_F_FIPS_DIGESTINIT 168 +# define EVP_F_FIPS_MD_CTX_COPY 169 +# define EVP_F_HMAC_INIT_EX 174 +# define EVP_F_INT_CTX_NEW 157 +# define EVP_F_PKCS5_PBE_KEYIVGEN 117 +# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +# define EVP_F_PKCS8_SET_BROKEN 112 +# define EVP_F_PKEY_SET_TYPE 158 +# define EVP_F_RC2_MAGIC_TO_METH 109 +# define EVP_F_RC5_CTRL 125 + +/* Reason codes. */ +# define EVP_R_AES_IV_SETUP_FAILED 162 +# define EVP_R_AES_KEY_SETUP_FAILED 143 +# define EVP_R_ASN1_LIB 140 +# define EVP_R_BAD_BLOCK_LENGTH 136 +# define EVP_R_BAD_DECRYPT 100 +# define EVP_R_BAD_KEY_LENGTH 137 +# define EVP_R_BN_DECODE_ERROR 112 +# define EVP_R_BN_PUBKEY_ERROR 113 +# define EVP_R_BUFFER_TOO_SMALL 155 +# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +# define EVP_R_CIPHER_PARAMETER_ERROR 122 +# define EVP_R_COMMAND_NOT_SUPPORTED 147 +# define EVP_R_CTRL_NOT_IMPLEMENTED 132 +# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +# define EVP_R_DECODE_ERROR 114 +# define EVP_R_DIFFERENT_KEY_TYPES 101 +# define EVP_R_DIFFERENT_PARAMETERS 153 +# define EVP_R_DISABLED_FOR_FIPS 163 +# define EVP_R_ENCODE_ERROR 115 +# define EVP_R_ERROR_LOADING_SECTION 165 +# define EVP_R_ERROR_SETTING_FIPS_MODE 166 +# define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 +# define EVP_R_EXPECTING_AN_RSA_KEY 127 +# define EVP_R_EXPECTING_A_DH_KEY 128 +# define EVP_R_EXPECTING_A_DSA_KEY 129 +# define EVP_R_EXPECTING_A_ECDSA_KEY 141 +# define EVP_R_EXPECTING_A_EC_KEY 142 +# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +# define EVP_R_INITIALIZATION_ERROR 134 +# define EVP_R_INPUT_NOT_INITIALIZED 111 +# define EVP_R_INVALID_DIGEST 152 +# define EVP_R_INVALID_FIPS_MODE 168 +# define EVP_R_INVALID_KEY 171 +# define EVP_R_INVALID_KEY_LENGTH 130 +# define EVP_R_INVALID_OPERATION 148 +# define EVP_R_IV_TOO_LARGE 102 +# define EVP_R_KEYGEN_FAILURE 120 +# define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +# define EVP_R_METHOD_NOT_SUPPORTED 144 +# define EVP_R_MISSING_PARAMETERS 103 +# define EVP_R_NO_CIPHER_SET 131 +# define EVP_R_NO_DEFAULT_DIGEST 158 +# define EVP_R_NO_DIGEST_SET 139 +# define EVP_R_NO_DSA_PARAMETERS 116 +# define EVP_R_NO_KEY_SET 154 +# define EVP_R_NO_OPERATION_SET 149 +# define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 +# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 +# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +# define EVP_R_OPERATON_NOT_INITIALIZED 151 +# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 +# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +# define EVP_R_PUBLIC_KEY_NOT_RSA 106 +# define EVP_R_TOO_LARGE 164 +# define EVP_R_UNKNOWN_CIPHER 160 +# define EVP_R_UNKNOWN_DIGEST 161 +# define EVP_R_UNKNOWN_OPTION 169 +# define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +# define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 +# define EVP_R_UNSUPPORTED_ALGORITHM 156 +# define EVP_R_UNSUPPORTED_CIPHER 107 +# define EVP_R_UNSUPPORTED_KEYLENGTH 123 +# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +# define EVP_R_UNSUPPORTED_KEY_SIZE 108 +# define EVP_R_UNSUPPORTED_PRF 125 +# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +# define EVP_R_UNSUPPORTED_SALT_TYPE 126 +# define EVP_R_WRAP_MODE_NOT_ALLOWED 170 +# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +# define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Sources/COpenSSL/evp_.c b/Sources/COpenSSL/evp_.c new file mode 100644 index 00000000..6d2babb4 --- /dev/null +++ b/Sources/COpenSSL/evp_.c @@ -0,0 +1,2443 @@ +/* evp_acnf.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "evp.h" +#include "conf.h" + +/* + * Load all algorithms and configure OpenSSL. This function is called + * automatically when OPENSSL_LOAD_CONF is set. + */ + +void OPENSSL_add_all_algorithms_conf(void) +{ + OPENSSL_add_all_algorithms_noconf(); + OPENSSL_config(NULL); +} +/* crypto/asn1/evp_asn1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "asn1.h" +#include "asn1_mac.h" + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) +{ + ASN1_STRING *os; + + if ((os = M_ASN1_OCTET_STRING_new()) == NULL) + return (0); + if (!M_ASN1_OCTET_STRING_set(os, data, len)) { + M_ASN1_OCTET_STRING_free(os); + return 0; + } + ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os); + return (1); +} + +/* int max_len: for returned value */ +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len) +{ + int ret, num; + unsigned char *p; + + if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) { + ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG); + return (-1); + } + p = M_ASN1_STRING_data(a->value.octet_string); + ret = M_ASN1_STRING_length(a->value.octet_string); + if (ret < max_len) + num = ret; + else + num = max_len; + memcpy(data, p, num); + return (ret); +} + +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, + int len) +{ + int n, size; + ASN1_OCTET_STRING os, *osp; + ASN1_INTEGER in; + unsigned char *p; + unsigned char buf[32]; /* when they have 256bit longs, I'll be in + * trouble */ + in.data = buf; + in.length = 32; + os.data = data; + os.type = V_ASN1_OCTET_STRING; + os.length = len; + ASN1_INTEGER_set(&in, num); + n = i2d_ASN1_INTEGER(&in, NULL); + n += M_i2d_ASN1_OCTET_STRING(&os, NULL); + + size = ASN1_object_size(1, n, V_ASN1_SEQUENCE); + + if ((osp = ASN1_STRING_new()) == NULL) + return (0); + /* Grow the 'string' */ + if (!ASN1_STRING_set(osp, NULL, size)) { + ASN1_STRING_free(osp); + return (0); + } + + M_ASN1_STRING_length_set(osp, size); + p = M_ASN1_STRING_data(osp); + + ASN1_put_object(&p, 1, n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); + i2d_ASN1_INTEGER(&in, &p); + M_i2d_ASN1_OCTET_STRING(&os, &p); + + ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp); + return (1); +} + +/* + * we return the actual length..., num may be missing, in which case, set it + * to zero + */ +/* int max_len: for returned value */ +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, + unsigned char *data, int max_len) +{ + int ret = -1, n; + ASN1_INTEGER *ai = NULL; + ASN1_OCTET_STRING *os = NULL; + const unsigned char *p; + long length; + ASN1_const_CTX c; + + if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) { + goto err; + } + p = M_ASN1_STRING_data(a->value.sequence); + length = M_ASN1_STRING_length(a->value.sequence); + + c.pp = &p; + c.p = p; + c.max = p + length; + c.error = ASN1_R_DATA_IS_WRONG; + + M_ASN1_D2I_start_sequence(); + c.q = c.p; + if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL) + goto err; + c.slen -= (c.p - c.q); + c.q = c.p; + if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL) + goto err; + c.slen -= (c.p - c.q); + if (!M_ASN1_D2I_end_sequence()) + goto err; + + if (num != NULL) + *num = ASN1_INTEGER_get(ai); + + ret = M_ASN1_STRING_length(os); + if (max_len > ret) + n = ret; + else + n = max_len; + + if (data != NULL) + memcpy(data, M_ASN1_STRING_data(os), n); + if (0) { + err: + ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG); + } + if (os != NULL) + M_ASN1_OCTET_STRING_free(os); + if (ai != NULL) + M_ASN1_INTEGER_free(ai); + return (ret); +} +/* evp_cnf.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "crypto.h" +// #include "cryptlib.h" +// #include "conf.h" +#include "dso.h" +#include "x509.h" +#include "x509v3.h" +#ifdef OPENSSL_FIPS +# include +#endif + +/* Algorithm configuration module. */ + +static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) +{ + int i; + const char *oid_section; + STACK_OF(CONF_VALUE) *sktmp; + CONF_VALUE *oval; + oid_section = CONF_imodule_get_value(md); + if (!(sktmp = NCONF_get_section(cnf, oid_section))) { + EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION); + return 0; + } + for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { + oval = sk_CONF_VALUE_value(sktmp, i); + if (!strcmp(oval->name, "fips_mode")) { + int m; + if (!X509V3_get_value_bool(oval, &m)) { + EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE); + return 0; + } + if (m > 0) { +#ifdef OPENSSL_FIPS + if (!FIPS_mode() && !FIPS_mode_set(1)) { + EVPerr(EVP_F_ALG_MODULE_INIT, + EVP_R_ERROR_SETTING_FIPS_MODE); + return 0; + } +#else + EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED); + return 0; +#endif + } + } else { + EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION); + ERR_add_error_data(4, "name=", oval->name, + ", value=", oval->value); + } + + } + return 1; +} + +void EVP_add_alg_module(void) +{ + CONF_module_add("alg_section", alg_module_init, 0); +} +/* crypto/evp/evp_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +#include "err.h" +#include "rand.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +#ifdef OPENSSL_FIPS +# include +#endif +#include "evp_locl.h" + +#ifdef OPENSSL_FIPS +# define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl) +#else +# define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl) +#endif + +const char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT; + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) +{ + memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); + /* ctx->cipher=NULL; */ +} + +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) +{ + EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); + if (ctx) + EVP_CIPHER_CTX_init(ctx); + return ctx; +} + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc) +{ + if (cipher) + EVP_CIPHER_CTX_init(ctx); + return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); +} + +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv, int enc) +{ + if (enc == -1) + enc = ctx->encrypt; + else { + if (enc) + enc = 1; + ctx->encrypt = enc; + } +#ifndef OPENSSL_NO_ENGINE + /* + * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so + * this context may already have an ENGINE! Try to avoid releasing the + * previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unecessary. + */ + if (ctx->engine && ctx->cipher && (!cipher || + (cipher + && (cipher->nid == + ctx->cipher->nid)))) + goto skip_to_init; +#endif + if (cipher) { + /* + * Ensure a context left lying around from last time is cleared (the + * previous check attempted to avoid this if the same ENGINE and + * EVP_CIPHER could be used). + */ + if (ctx->cipher) { + unsigned long flags = ctx->flags; + EVP_CIPHER_CTX_cleanup(ctx); + /* Restore encrypt and flags */ + ctx->encrypt = enc; + ctx->flags = flags; + } +#ifndef OPENSSL_NO_ENGINE + if (impl) { + if (!ENGINE_init(impl)) { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } else + /* Ask if an ENGINE is reserved for this job */ + impl = ENGINE_get_cipher_engine(cipher->nid); + if (impl) { + /* There's an ENGINE for this job ... (apparently) */ + const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid); + if (!c) { + /* + * One positive side-effect of US's export control history, + * is that we should at least be able to avoid using US + * mispellings of "initialisation"? + */ + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + /* We'll use the ENGINE's private cipher definition */ + cipher = c; + /* + * Store the ENGINE functional reference so we know 'cipher' came + * from an ENGINE and we need to release it when done. + */ + ctx->engine = impl; + } else + ctx->engine = NULL; +#endif + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) { + const EVP_CIPHER *fcipher = NULL; + if (cipher) + fcipher = evp_get_fips_cipher(cipher); + if (fcipher) + cipher = fcipher; + return FIPS_cipherinit(ctx, cipher, key, iv, enc); + } +#endif + ctx->cipher = cipher; + if (ctx->cipher->ctx_size) { + ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); + if (!ctx->cipher_data) { + ctx->cipher = NULL; + EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + ctx->cipher_data = NULL; + } + ctx->key_len = cipher->key_len; + /* Preserve wrap enable flag, zero everything else */ + ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; + if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + ctx->cipher = NULL; + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } + } else if (!ctx->cipher) { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + skip_to_init: +#endif +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_cipherinit(ctx, cipher, key, iv, enc); +#endif + /* we assume block size is a power of 2 in *cryptUpdate */ + OPENSSL_assert(ctx->cipher->block_size == 1 + || ctx->cipher->block_size == 8 + || ctx->cipher->block_size == 16); + + if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW) + && EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_WRAP_MODE_NOT_ALLOWED); + return 0; + } + + if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { + switch (EVP_CIPHER_CTX_mode(ctx)) { + + case EVP_CIPH_STREAM_CIPHER: + case EVP_CIPH_ECB_MODE: + break; + + case EVP_CIPH_CFB_MODE: + case EVP_CIPH_OFB_MODE: + + ctx->num = 0; + /* fall-through */ + + case EVP_CIPH_CBC_MODE: + + OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= + (int)sizeof(ctx->iv)); + if (iv) + memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + case EVP_CIPH_CTR_MODE: + ctx->num = 0; + /* Don't reuse IV for CTR mode */ + if (iv) + memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + default: + return 0; + break; + } + } + + if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { + if (!ctx->cipher->init(ctx, key, iv, enc)) + return 0; + } + ctx->buf_len = 0; + ctx->final_used = 0; + ctx->block_mask = ctx->cipher->block_size - 1; + return 1; +} + +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + if (ctx->encrypt) + return EVP_EncryptUpdate(ctx, out, outl, in, inl); + else + return EVP_DecryptUpdate(ctx, out, outl, in, inl); +} + +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + if (ctx->encrypt) + return EVP_EncryptFinal_ex(ctx, out, outl); + else + return EVP_DecryptFinal_ex(ctx, out, outl); +} + +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + if (ctx->encrypt) + return EVP_EncryptFinal(ctx, out, outl); + else + return EVP_DecryptFinal(ctx, out, outl); +} + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv) +{ + return EVP_CipherInit(ctx, cipher, key, iv, 1); +} + +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv) +{ + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); +} + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv) +{ + return EVP_CipherInit(ctx, cipher, key, iv, 0); +} + +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv) +{ + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); +} + +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int i, j, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = M_do_cipher(ctx, out, in, inl); + if (i < 0) + return 0; + else + *outl = i; + return 1; + } + + if (inl <= 0) { + *outl = 0; + return inl == 0; + } + + if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) { + if (M_do_cipher(ctx, out, in, inl)) { + *outl = inl; + return 1; + } else { + *outl = 0; + return 0; + } + } + i = ctx->buf_len; + bl = ctx->cipher->block_size; + OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); + if (i != 0) { + if (bl - i > inl) { + memcpy(&(ctx->buf[i]), in, inl); + ctx->buf_len += inl; + *outl = 0; + return 1; + } else { + j = bl - i; + memcpy(&(ctx->buf[i]), in, j); + if (!M_do_cipher(ctx, out, ctx->buf, bl)) + return 0; + inl -= j; + in += j; + out += bl; + *outl = bl; + } + } else + *outl = 0; + i = inl & (bl - 1); + inl -= i; + if (inl > 0) { + if (!M_do_cipher(ctx, out, in, inl)) + return 0; + *outl += inl; + } + + if (i != 0) + memcpy(ctx->buf, &(in[inl]), i); + ctx->buf_len = i; + return 1; +} + +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int ret; + ret = EVP_EncryptFinal_ex(ctx, out, outl); + return ret; +} + +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int n, ret; + unsigned int i, b, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + ret = M_do_cipher(ctx, out, NULL, 0); + if (ret < 0) + return 0; + else + *outl = ret; + return 1; + } + + b = ctx->cipher->block_size; + OPENSSL_assert(b <= sizeof(ctx->buf)); + if (b == 1) { + *outl = 0; + return 1; + } + bl = ctx->buf_len; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (bl) { + EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, + EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *outl = 0; + return 1; + } + + n = b - bl; + for (i = bl; i < b; i++) + ctx->buf[i] = n; + ret = M_do_cipher(ctx, out, ctx->buf, b); + + if (ret) + *outl = b; + + return ret; +} + +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int fix_len; + unsigned int b; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + fix_len = M_do_cipher(ctx, out, in, inl); + if (fix_len < 0) { + *outl = 0; + return 0; + } else + *outl = fix_len; + return 1; + } + + if (inl <= 0) { + *outl = 0; + return inl == 0; + } + + if (ctx->flags & EVP_CIPH_NO_PADDING) + return EVP_EncryptUpdate(ctx, out, outl, in, inl); + + b = ctx->cipher->block_size; + OPENSSL_assert(b <= sizeof(ctx->final)); + + if (ctx->final_used) { + memcpy(out, ctx->final, b); + out += b; + fix_len = 1; + } else + fix_len = 0; + + if (!EVP_EncryptUpdate(ctx, out, outl, in, inl)) + return 0; + + /* + * if we have 'decrypted' a multiple of block size, make sure we have a + * copy of this last block + */ + if (b > 1 && !ctx->buf_len) { + *outl -= b; + ctx->final_used = 1; + memcpy(ctx->final, &out[*outl], b); + } else + ctx->final_used = 0; + + if (fix_len) + *outl += b; + + return 1; +} + +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int ret; + ret = EVP_DecryptFinal_ex(ctx, out, outl); + return ret; +} + +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i, n; + unsigned int b; + *outl = 0; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = M_do_cipher(ctx, out, NULL, 0); + if (i < 0) + return 0; + else + *outl = i; + return 1; + } + + b = ctx->cipher->block_size; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (ctx->buf_len) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, + EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *outl = 0; + return 1; + } + if (b > 1) { + if (ctx->buf_len || !ctx->final_used) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH); + return (0); + } + OPENSSL_assert(b <= sizeof(ctx->final)); + + /* + * The following assumes that the ciphertext has been authenticated. + * Otherwise it provides a padding oracle. + */ + n = ctx->final[b - 1]; + if (n == 0 || n > (int)b) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); + return (0); + } + for (i = 0; i < n; i++) { + if (ctx->final[--b] != n) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); + return (0); + } + } + n = ctx->cipher->block_size - n; + for (i = 0; i < n; i++) + out[i] = ctx->final[i]; + *outl = n; + } else + *outl = 0; + return (1); +} + +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + if (ctx) { + EVP_CIPHER_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) +{ +#ifndef OPENSSL_FIPS + if (c->cipher != NULL) { + if (c->cipher->cleanup && !c->cipher->cleanup(c)) + return 0; + /* Cleanse cipher context data */ + if (c->cipher_data) + OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); + } + if (c->cipher_data) + OPENSSL_free(c->cipher_data); +#endif +#ifndef OPENSSL_NO_ENGINE + if (c->engine) + /* + * The EVP_CIPHER we used belongs to an ENGINE, release the + * functional reference we held for this reason. + */ + ENGINE_finish(c->engine); +#endif +#ifdef OPENSSL_FIPS + FIPS_cipher_ctx_cleanup(c); +#endif + memset(c, 0, sizeof(EVP_CIPHER_CTX)); + return 1; +} + +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) +{ + if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) + return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); + if (c->key_len == keylen) + return 1; + if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { + c->key_len = keylen; + return 1; + } + EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH); + return 0; +} + +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) +{ + if (pad) + ctx->flags &= ~EVP_CIPH_NO_PADDING; + else + ctx->flags |= EVP_CIPH_NO_PADDING; + return 1; +} + +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + int ret; + if (!ctx->cipher) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); + return 0; + } + + if (!ctx->cipher->ctrl) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->cipher->ctrl(ctx, type, arg, ptr); + if (ret == -1) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, + EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); + return 0; + } + return ret; +} + +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) +{ + if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) + return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); + if (RAND_bytes(key, ctx->key_len) <= 0) + return 0; + return 1; +} + +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) +{ + if ((in == NULL) || (in->cipher == NULL)) { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a cipher context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_ENGINE_LIB); + return 0; + } +#endif + + EVP_CIPHER_CTX_cleanup(out); + memcpy(out, in, sizeof(*out)); + + if (in->cipher_data && in->cipher->ctx_size) { + out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); + if (!out->cipher_data) { + out->cipher = NULL; + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); + } + + if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) + if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) { + out->cipher = NULL; + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INITIALIZATION_ERROR); + return 0; + } + return 1; +} +/* crypto/evp/evp_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +// #include "err.h" +// #include "evp.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason) + +static ERR_STRING_DATA EVP_str_functs[] = { + {ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"}, + {ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"}, + {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"}, + {ERR_FUNC(EVP_F_AES_T4_INIT_KEY), "AES_T4_INIT_KEY"}, + {ERR_FUNC(EVP_F_AES_XTS), "AES_XTS"}, + {ERR_FUNC(EVP_F_AES_XTS_CIPHER), "AES_XTS_CIPHER"}, + {ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"}, + {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"}, + {ERR_FUNC(EVP_F_CMAC_INIT), "CMAC_INIT"}, + {ERR_FUNC(EVP_F_CMLL_T4_INIT_KEY), "CMLL_T4_INIT_KEY"}, + {ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"}, + {ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"}, + {ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"}, + {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"}, + {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"}, + {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"}, + {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, + {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"}, + {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"}, + {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), + "EVP_CIPHER_CTX_set_key_length"}, + {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, + {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, + {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, + {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, + {ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"}, + {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"}, + {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"}, + {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"}, + {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"}, + {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"}, + {ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"}, + {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"}, + {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"}, + {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"}, + {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"}, + {ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"}, + {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"}, + {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH), "EVP_PKEY_get1_DH"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA), "EVP_PKEY_get1_DSA"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"}, + {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"}, + {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"}, + {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"}, + {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"}, + {ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"}, + {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"}, + {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT), + "EVP_PKEY_verify_recover_init"}, + {ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"}, + {ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"}, + {ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"}, + {ERR_FUNC(EVP_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"}, + {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY), "FIPS_CIPHER_CTX_COPY"}, + {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"}, + {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH), + "FIPS_CIPHER_CTX_SET_KEY_LENGTH"}, + {ERR_FUNC(EVP_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"}, + {ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY), "FIPS_MD_CTX_COPY"}, + {ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"}, + {ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"}, + {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"}, + {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"}, + {ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_KEYIVGEN"}, + {ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"}, + {ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"}, + {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"}, + {ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"}, + {0, NULL} +}; + +static ERR_STRING_DATA EVP_str_reasons[] = { + {ERR_REASON(EVP_R_AES_IV_SETUP_FAILED), "aes iv setup failed"}, + {ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"}, + {ERR_REASON(EVP_R_ASN1_LIB), "asn1 lib"}, + {ERR_REASON(EVP_R_BAD_BLOCK_LENGTH), "bad block length"}, + {ERR_REASON(EVP_R_BAD_DECRYPT), "bad decrypt"}, + {ERR_REASON(EVP_R_BAD_KEY_LENGTH), "bad key length"}, + {ERR_REASON(EVP_R_BN_DECODE_ERROR), "bn decode error"}, + {ERR_REASON(EVP_R_BN_PUBKEY_ERROR), "bn pubkey error"}, + {ERR_REASON(EVP_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED), + "camellia key setup failed"}, + {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"}, + {ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED), "command not supported"}, + {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED), "ctrl not implemented"}, + {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED), + "ctrl operation not implemented"}, + {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), + "data not multiple of block length"}, + {ERR_REASON(EVP_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES), "different key types"}, + {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS), "different parameters"}, + {ERR_REASON(EVP_R_DISABLED_FOR_FIPS), "disabled for fips"}, + {ERR_REASON(EVP_R_ENCODE_ERROR), "encode error"}, + {ERR_REASON(EVP_R_ERROR_LOADING_SECTION), "error loading section"}, + {ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"}, + {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR), "evp pbe cipherinit error"}, + {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY), "expecting an rsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"}, + {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY), "expecting a ecdsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"}, + {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_REASON(EVP_R_INITIALIZATION_ERROR), "initialization error"}, + {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"}, + {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"}, + {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"}, + {ERR_REASON(EVP_R_INVALID_KEY), "invalid key"}, + {ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"}, + {ERR_REASON(EVP_R_IV_TOO_LARGE), "iv too large"}, + {ERR_REASON(EVP_R_KEYGEN_FAILURE), "keygen failure"}, + {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"}, + {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED), "method not supported"}, + {ERR_REASON(EVP_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(EVP_R_NO_CIPHER_SET), "no cipher set"}, + {ERR_REASON(EVP_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_REASON(EVP_R_NO_DIGEST_SET), "no digest set"}, + {ERR_REASON(EVP_R_NO_DSA_PARAMETERS), "no dsa parameters"}, + {ERR_REASON(EVP_R_NO_KEY_SET), "no key set"}, + {ERR_REASON(EVP_R_NO_OPERATION_SET), "no operation set"}, + {ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED), + "no sign function configured"}, + {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED), + "no verify function configured"}, + {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), + "operation not supported for this keytype"}, + {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, + {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), + "pkcs8 unknown broken type"}, + {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"}, + {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"}, + {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, + {ERR_REASON(EVP_R_TOO_LARGE), "too large"}, + {ERR_REASON(EVP_R_UNKNOWN_CIPHER), "unknown cipher"}, + {ERR_REASON(EVP_R_UNKNOWN_DIGEST), "unknown digest"}, + {ERR_REASON(EVP_R_UNKNOWN_OPTION), "unknown option"}, + {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM), "unknown pbe algorithm"}, + {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS), + "unsuported number of rounds"}, + {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, + {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH), "unsupported keylength"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION), + "unsupported key derivation function"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"}, + {ERR_REASON(EVP_R_UNSUPPORTED_PRF), "unsupported prf"}, + {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM), + "unsupported private key algorithm"}, + {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE), "unsupported salt type"}, + {ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"}, + {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"}, + {ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"}, + {0, NULL} +}; + +#endif + +void ERR_load_EVP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) { + ERR_load_strings(0, EVP_str_functs); + ERR_load_strings(0, EVP_str_reasons); + } +#endif +} +/* crypto/evp/evp_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "x509.h" +#include "objects.h" +// #include "evp.h" +#include "ui.h" + +/* should be init to zeros. */ +static char prompt_string[80]; + +void EVP_set_pw_prompt(const char *prompt) +{ + if (prompt == NULL) + prompt_string[0] = '\0'; + else { + strncpy(prompt_string, prompt, 79); + prompt_string[79] = '\0'; + } +} + +char *EVP_get_pw_prompt(void) +{ + if (prompt_string[0] == '\0') + return (NULL); + else + return (prompt_string); +} + +/* + * For historical reasons, the standard function for reading passwords is in + * the DES library -- if someone ever wants to disable DES, this function + * will fail + */ +int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) +{ + return EVP_read_pw_string_min(buf, 0, len, prompt, verify); +} + +int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, + int verify) +{ + int ret = -1; + char buff[BUFSIZ]; + UI *ui; + + if ((prompt == NULL) && (prompt_string[0] != '\0')) + prompt = prompt_string; + ui = UI_new(); + if (ui == NULL) + return ret; + if (UI_add_input_string(ui, prompt, 0, buf, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0 + || (verify + && UI_add_verify_string(ui, prompt, 0, buff, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len, + buf) < 0)) + goto end; + ret = UI_process(ui); + OPENSSL_cleanse(buff, BUFSIZ); + end: + UI_free(ui); + return ret; +} + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, + int datal, int count, unsigned char *key, + unsigned char *iv) +{ + EVP_MD_CTX c; + unsigned char md_buf[EVP_MAX_MD_SIZE]; + int niv, nkey, addmd = 0; + unsigned int mds = 0, i; + int rv = 0; + nkey = type->key_len; + niv = type->iv_len; + OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); + OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); + + if (data == NULL) + return (nkey); + + EVP_MD_CTX_init(&c); + for (;;) { + if (!EVP_DigestInit_ex(&c, md, NULL)) + goto err; + if (addmd++) + if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) + goto err; + if (!EVP_DigestUpdate(&c, data, datal)) + goto err; + if (salt != NULL) + if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN)) + goto err; + if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) + goto err; + + for (i = 1; i < (unsigned int)count; i++) { + if (!EVP_DigestInit_ex(&c, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) + goto err; + if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) + goto err; + } + i = 0; + if (nkey) { + for (;;) { + if (nkey == 0) + break; + if (i == mds) + break; + if (key != NULL) + *(key++) = md_buf[i]; + nkey--; + i++; + } + } + if (niv && (i != mds)) { + for (;;) { + if (niv == 0) + break; + if (i == mds) + break; + if (iv != NULL) + *(iv++) = md_buf[i]; + niv--; + i++; + } + } + if ((nkey == 0) && (niv == 0)) + break; + } + rv = type->key_len; + err: + EVP_MD_CTX_cleanup(&c); + OPENSSL_cleanse(md_buf, sizeof(md_buf)); + return rv; +} +/* crypto/evp/evp_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "objects.h" +#ifdef OPENSSL_FIPS +# include +# include "evp_locl.h" +#endif + +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int ret; + + if (c->cipher->set_asn1_parameters != NULL) + ret = c->cipher->set_asn1_parameters(c, type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { + switch (EVP_CIPHER_CTX_mode(c)) { + case EVP_CIPH_WRAP_MODE: + if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap) + ASN1_TYPE_set(type, V_ASN1_NULL, NULL); + ret = 1; + break; + + case EVP_CIPH_GCM_MODE: + case EVP_CIPH_CCM_MODE: + case EVP_CIPH_XTS_MODE: + ret = -1; + break; + + default: + ret = EVP_CIPHER_set_asn1_iv(c, type); + } + } else + ret = -1; + return (ret); +} + +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int ret; + + if (c->cipher->get_asn1_parameters != NULL) + ret = c->cipher->get_asn1_parameters(c, type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { + switch (EVP_CIPHER_CTX_mode(c)) { + + case EVP_CIPH_WRAP_MODE: + ret = 1; + break; + + case EVP_CIPH_GCM_MODE: + case EVP_CIPH_CCM_MODE: + case EVP_CIPH_XTS_MODE: + ret = -1; + break; + + default: + ret = EVP_CIPHER_get_asn1_iv(c, type); + break; + } + } else + ret = -1; + return (ret); +} + +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int l; + + if (type != NULL) { + l = EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(l <= sizeof(c->iv)); + i = ASN1_TYPE_get_octetstring(type, c->oiv, l); + if (i != (int)l) + return (-1); + else if (i > 0) + memcpy(c->iv, c->oiv, l); + } + return (i); +} + +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int j; + + if (type != NULL) { + j = EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(j <= sizeof(c->iv)); + i = ASN1_TYPE_set_octetstring(type, c->oiv, j); + } + return (i); +} + +/* Convert the various cipher NIDs and dummies to a proper OID NID */ +int EVP_CIPHER_type(const EVP_CIPHER *ctx) +{ + int nid; + ASN1_OBJECT *otmp; + nid = EVP_CIPHER_nid(ctx); + + switch (nid) { + + case NID_rc2_cbc: + case NID_rc2_64_cbc: + case NID_rc2_40_cbc: + + return NID_rc2_cbc; + + case NID_rc4: + case NID_rc4_40: + + return NID_rc4; + + case NID_aes_128_cfb128: + case NID_aes_128_cfb8: + case NID_aes_128_cfb1: + + return NID_aes_128_cfb128; + + case NID_aes_192_cfb128: + case NID_aes_192_cfb8: + case NID_aes_192_cfb1: + + return NID_aes_192_cfb128; + + case NID_aes_256_cfb128: + case NID_aes_256_cfb8: + case NID_aes_256_cfb1: + + return NID_aes_256_cfb128; + + case NID_des_cfb64: + case NID_des_cfb8: + case NID_des_cfb1: + + return NID_des_cfb64; + + case NID_des_ede3_cfb64: + case NID_des_ede3_cfb8: + case NID_des_ede3_cfb1: + + return NID_des_cfb64; + + default: + /* Check it has an OID and it is valid */ + otmp = OBJ_nid2obj(nid); + if (!otmp || !otmp->data) + nid = NID_undef; + ASN1_OBJECT_free(otmp); + return nid; + } +} + +int EVP_CIPHER_block_size(const EVP_CIPHER *e) +{ + return e->block_size; +} + +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->block_size; +} + +int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + return ctx->cipher->do_cipher(ctx, out, in, inl); +} + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher; +} + +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) +{ +#ifdef OPENSSL_FIPS + const EVP_CIPHER *fcipher; + fcipher = evp_get_fips_cipher(cipher); + if (fcipher && fcipher->flags & EVP_CIPH_FLAG_FIPS) + return cipher->flags | EVP_CIPH_FLAG_FIPS; +#endif + return cipher->flags; +} + +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) +{ +#ifdef OPENSSL_FIPS + return EVP_CIPHER_flags(ctx->cipher); +#else + return ctx->cipher->flags; +#endif +} + +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) +{ + return ctx->app_data; +} + +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) +{ + ctx->app_data = data; +} + +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) +{ + return cipher->iv_len; +} + +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->iv_len; +} + +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) +{ + return cipher->key_len; +} + +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) +{ + return ctx->key_len; +} + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher) +{ + return cipher->nid; +} + +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->nid; +} + +int EVP_MD_block_size(const EVP_MD *md) +{ + return md->block_size; +} + +int EVP_MD_type(const EVP_MD *md) +{ + return md->type; +} + +int EVP_MD_pkey_type(const EVP_MD *md) +{ + return md->pkey_type; +} + +int EVP_MD_size(const EVP_MD *md) +{ + if (!md) { + EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); + return -1; + } + return md->md_size; +} + +#ifdef OPENSSL_FIPS + +const EVP_MD *evp_get_fips_md(const EVP_MD *md) +{ + int nid = EVP_MD_type(md); + if (nid == NID_dsa) + return FIPS_evp_dss1(); + else if (nid == NID_dsaWithSHA) + return FIPS_evp_dss(); + else if (nid == NID_ecdsa_with_SHA1) + return FIPS_evp_ecdsa(); + else + return FIPS_get_digestbynid(nid); +} + +const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher) +{ + int nid = cipher->nid; + if (nid == NID_undef) + return FIPS_evp_enc_null(); + else + return FIPS_get_cipherbynid(nid); +} + +#endif + +unsigned long EVP_MD_flags(const EVP_MD *md) +{ +#ifdef OPENSSL_FIPS + const EVP_MD *fmd; + fmd = evp_get_fips_md(md); + if (fmd && fmd->flags & EVP_MD_FLAG_FIPS) + return md->flags | EVP_MD_FLAG_FIPS; +#endif + return md->flags; +} + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) +{ + if (!ctx) + return NULL; + return ctx->digest; +} + +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) +{ + ctx->flags &= ~flags; +} + +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) +{ + return (ctx->flags & flags); +} + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) +{ + ctx->flags &= ~flags; +} + +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) +{ + return (ctx->flags & flags); +} +/* evp_pbe.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +#include "pkcs12.h" +// #include "x509.h" +// #include "evp_locl.h" + +/* Password based encryption (PBE) functions */ + +DECLARE_STACK_OF(EVP_PBE_CTL) +static STACK_OF(EVP_PBE_CTL) *pbe_algs; + +/* Setup a cipher context from a PBE algorithm */ + +typedef struct { + int pbe_type; + int pbe_nid; + int cipher_nid; + int md_nid; + EVP_PBE_KEYGEN *keygen; +} EVP_PBE_CTL; + +static const EVP_PBE_CTL builtin_pbe[] = { + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, + NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, + NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, + NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + +#ifndef OPENSSL_NO_HMAC + {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, +#endif + + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, + NID_rc4, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, + NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, + NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, + NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, + NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + +#ifndef OPENSSL_NO_HMAC + {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen}, +#endif + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, + NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, + NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, + NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, + {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, +}; + +#ifdef TEST +int main(int argc, char **argv) +{ + int i, nid_md, nid_cipher; + EVP_PBE_CTL *tpbe, *tpbe2; + /* + * OpenSSL_add_all_algorithms(); + */ + + for (i = 0; i < sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL); i++) { + tpbe = builtin_pbe + i; + fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid, + OBJ_nid2sn(tpbe->pbe_nid)); + if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid, + &nid_cipher, &nid_md, 0)) + fprintf(stderr, "Found %s %s\n", + OBJ_nid2sn(nid_cipher), OBJ_nid2sn(nid_md)); + else + fprintf(stderr, "Find ERROR!!\n"); + } + + return 0; +} +#endif + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) +{ + const EVP_CIPHER *cipher; + const EVP_MD *md; + int cipher_nid, md_nid; + EVP_PBE_KEYGEN *keygen; + + if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), + &cipher_nid, &md_nid, &keygen)) { + char obj_tmp[80]; + EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM); + if (!pbe_obj) + BUF_strlcpy(obj_tmp, "NULL", sizeof(obj_tmp)); + else + i2t_ASN1_OBJECT(obj_tmp, sizeof(obj_tmp), pbe_obj); + ERR_add_error_data(2, "TYPE=", obj_tmp); + return 0; + } + + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + + if (cipher_nid == -1) + cipher = NULL; + else { + cipher = EVP_get_cipherbynid(cipher_nid); + if (!cipher) { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER); + return 0; + } + } + + if (md_nid == -1) + md = NULL; + else { + md = EVP_get_digestbynid(md_nid); + if (!md) { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST); + return 0; + } + } + + if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE); + return 0; + } + return 1; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); + +static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2) +{ + int ret = pbe1->pbe_type - pbe2->pbe_type; + if (ret) + return ret; + else + return pbe1->pbe_nid - pbe2->pbe_nid; +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); + +static int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b) +{ + int ret = (*a)->pbe_type - (*b)->pbe_type; + if (ret) + return ret; + else + return (*a)->pbe_nid - (*b)->pbe_nid; +} + +/* Add a PBE algorithm */ + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, + int md_nid, EVP_PBE_KEYGEN *keygen) +{ + EVP_PBE_CTL *pbe_tmp; + + if (pbe_algs == NULL) { + pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); + if (pbe_algs == NULL) + goto err; + } + + if ((pbe_tmp = OPENSSL_malloc(sizeof(*pbe_tmp))) == NULL) + goto err; + + pbe_tmp->pbe_type = pbe_type; + pbe_tmp->pbe_nid = pbe_nid; + pbe_tmp->cipher_nid = cipher_nid; + pbe_tmp->md_nid = md_nid; + pbe_tmp->keygen = keygen; + + sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp); + return 1; + + err: + EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE); + return 0; +} + +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen) +{ + int cipher_nid, md_nid; + if (cipher) + cipher_nid = EVP_CIPHER_nid(cipher); + else + cipher_nid = -1; + if (md) + md_nid = EVP_MD_type(md); + else + md_nid = -1; + + return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid, + cipher_nid, md_nid, keygen); +} + +int EVP_PBE_find(int type, int pbe_nid, + int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) +{ + EVP_PBE_CTL *pbetmp = NULL, pbelu; + int i; + if (pbe_nid == NID_undef) + return 0; + + pbelu.pbe_type = type; + pbelu.pbe_nid = pbe_nid; + + if (pbe_algs) { + i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); + if (i != -1) + pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i); + } + if (pbetmp == NULL) { + pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, + sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL)); + } + if (pbetmp == NULL) + return 0; + if (pcnid) + *pcnid = pbetmp->cipher_nid; + if (pmnid) + *pmnid = pbetmp->md_nid; + if (pkeygen) + *pkeygen = pbetmp->keygen; + return 1; +} + +static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe) +{ + OPENSSL_freeFunc(pbe); +} + +void EVP_PBE_cleanup(void) +{ + sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl); + pbe_algs = NULL; +} +/* evp_pkey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "x509.h" +// #include "rand.h" +#include "asn1_locl.h" + +/* Extract a private key from a PKCS8 structure */ + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) +{ + EVP_PKEY *pkey = NULL; + ASN1_OBJECT *algoid; + char obj_tmp[80]; + + if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) + return NULL; + + if (!(pkey = EVP_PKEY_new())) { + EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + i2t_ASN1_OBJECT(obj_tmp, 80, algoid); + ERR_add_error_data(2, "TYPE=", obj_tmp); + goto error; + } + + if (pkey->ameth->priv_decode) { + if (!pkey->ameth->priv_decode(pkey, p8)) { + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR); + goto error; + } + } else { + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED); + goto error; + } + + return pkey; + + error: + EVP_PKEY_free(pkey); + return NULL; +} + +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) +{ + return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK); +} + +/* Turn a private key into a PKCS8 structure */ + +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) +{ + PKCS8_PRIV_KEY_INFO *p8; + + if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE); + return NULL; + } + p8->broken = broken; + + if (pkey->ameth) { + if (pkey->ameth->priv_encode) { + if (!pkey->ameth->priv_encode(p8, pkey)) { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, + EVP_R_PRIVATE_KEY_ENCODE_ERROR); + goto error; + } + } else { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_METHOD_NOT_SUPPORTED); + goto error; + } + } else { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, + EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + goto error; + } + RAND_add(p8->pkey->value.octet_string->data, + p8->pkey->value.octet_string->length, 0.0); + return p8; + error: + PKCS8_PRIV_KEY_INFO_free(p8); + return NULL; +} + +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) +{ + switch (broken) { + + case PKCS8_OK: + p8->broken = PKCS8_OK; + return p8; + break; + + case PKCS8_NO_OCTET: + p8->broken = PKCS8_NO_OCTET; + p8->pkey->type = V_ASN1_SEQUENCE; + return p8; + break; + + default: + EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE); + return NULL; + } +} + +/* EVP_PKEY attribute functions */ + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key) +{ + return X509at_get_attr_count(key->attributes); +} + +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(key->attributes, nid, lastpos); +} + +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos); +} + +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc) +{ + return X509at_get_attr(key->attributes, loc); +} + +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc) +{ + return X509at_delete_attr(key->attributes, loc); +} + +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&key->attributes, attr)) + return 1; + return 0; +} + +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len)) + return 1; + return 0; +} + +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len)) + return 1; + return 0; +} + +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len)) + return 1; + return 0; +} diff --git a/Sources/COpenSSL/evp_locl.h b/Sources/COpenSSL/evp_locl.h new file mode 100644 index 00000000..bee7f6d1 --- /dev/null +++ b/Sources/COpenSSL/evp_locl.h @@ -0,0 +1,373 @@ +/* evp_locl.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Macros to code block cipher wrappers */ + +/* Wrapper functions for each cipher mode */ + +#define BLOCK_CIPHER_ecb_loop() \ + size_t i, bl; \ + bl = ctx->cipher->block_size;\ + if(inl < bl) return 1;\ + inl -= bl; \ + for(i=0; i <= inl; i+=bl) + +#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \ +static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ +{\ + BLOCK_CIPHER_ecb_loop() \ + cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\ + return 1;\ +} + +#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2)) + +#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \ +static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ +{\ + while(inl>=EVP_MAXCHUNK)\ + {\ + cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ + inl-=EVP_MAXCHUNK;\ + in +=EVP_MAXCHUNK;\ + out+=EVP_MAXCHUNK;\ + }\ + if (inl)\ + cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ + return 1;\ +} + +#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \ +static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ +{\ + while(inl>=EVP_MAXCHUNK) \ + {\ + cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ + inl-=EVP_MAXCHUNK;\ + in +=EVP_MAXCHUNK;\ + out+=EVP_MAXCHUNK;\ + }\ + if (inl)\ + cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ + return 1;\ +} + +#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ +static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ +{\ + size_t chunk=EVP_MAXCHUNK;\ + if (cbits==1) chunk>>=3;\ + if (inl=chunk)\ + {\ + cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?chunk*8:chunk), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ + inl-=chunk;\ + in +=chunk;\ + out+=chunk;\ + if(inlc))+\ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ + set_asn1, get_asn1,\ + ctrl, \ + NULL \ +};\ +const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\ +static const EVP_CIPHER cname##_cfb = {\ + nid##_cfb64, 1, key_len, iv_len, \ + flags | EVP_CIPH_CFB_MODE,\ + init_key,\ + cname##_cfb_cipher,\ + cleanup,\ + sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ + set_asn1, get_asn1,\ + ctrl,\ + NULL \ +};\ +const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\ +static const EVP_CIPHER cname##_ofb = {\ + nid##_ofb64, 1, key_len, iv_len, \ + flags | EVP_CIPH_OFB_MODE,\ + init_key,\ + cname##_ofb_cipher,\ + cleanup,\ + sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ + set_asn1, get_asn1,\ + ctrl,\ + NULL \ +};\ +const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\ +static const EVP_CIPHER cname##_ecb = {\ + nid##_ecb, block_size, key_len, iv_len, \ + flags | EVP_CIPH_ECB_MODE,\ + init_key,\ + cname##_ecb_cipher,\ + cleanup,\ + sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ + set_asn1, get_asn1,\ + ctrl,\ + NULL \ +};\ +const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } +*/ + +#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \ + block_size, key_len, iv_len, cbits, \ + flags, init_key, \ + cleanup, set_asn1, get_asn1, ctrl) \ + BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \ + BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \ + cbits, flags, init_key, cleanup, set_asn1, \ + get_asn1, ctrl) + +#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data) + +#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \ + BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ + BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ + NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ + 0, cipher##_init_key, NULL, \ + EVP_CIPHER_set_asn1_iv, \ + EVP_CIPHER_get_asn1_iv, \ + NULL) + +struct evp_pkey_ctx_st { + /* Method associated with this operation */ + const EVP_PKEY_METHOD *pmeth; + /* Engine that implements this method or NULL if builtin */ + ENGINE *engine; + /* Key: may be NULL */ + EVP_PKEY *pkey; + /* Peer key for key agreement, may be NULL */ + EVP_PKEY *peerkey; + /* Actual operation */ + int operation; + /* Algorithm specific data */ + void *data; + /* Application specific data */ + void *app_data; + /* Keygen callback */ + EVP_PKEY_gen_cb *pkey_gencb; + /* implementation specific keygen data */ + int *keygen_info; + int keygen_info_count; +} /* EVP_PKEY_CTX */ ; + +#define EVP_PKEY_FLAG_DYNAMIC 1 + +struct evp_pkey_method_st { + int pkey_id; + int flags; + int (*init) (EVP_PKEY_CTX *ctx); + int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup) (EVP_PKEY_CTX *ctx); + int (*paramgen_init) (EVP_PKEY_CTX *ctx); + int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + int (*keygen_init) (EVP_PKEY_CTX *ctx); + int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + int (*sign_init) (EVP_PKEY_CTX *ctx); + int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + int (*verify_init) (EVP_PKEY_CTX *ctx); + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + int (*verify_recover_init) (EVP_PKEY_CTX *ctx); + int (*verify_recover) (EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx); + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx); + int (*encrypt_init) (EVP_PKEY_CTX *ctx); + int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + int (*decrypt_init) (EVP_PKEY_CTX *ctx); + int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + int (*derive_init) (EVP_PKEY_CTX *ctx); + int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); + int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); +} /* EVP_PKEY_METHOD */ ; + +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); + +int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, + int en_de); + +const EVP_MD *evp_get_fips_md(const EVP_MD *md); +const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher); + +#ifdef OPENSSL_FIPS + +# ifdef OPENSSL_DOING_MAKEDEPEND +# undef SHA1_Init +# undef SHA1_Update +# undef SHA224_Init +# undef SHA256_Init +# undef SHA384_Init +# undef SHA512_Init +# undef DES_set_key_unchecked +# endif + +# define RIPEMD160_Init private_RIPEMD160_Init +# define WHIRLPOOL_Init private_WHIRLPOOL_Init +# define MD5_Init private_MD5_Init +# define MD4_Init private_MD4_Init +# define MD2_Init private_MD2_Init +# define MDC2_Init private_MDC2_Init +# define SHA_Init private_SHA_Init +# define SHA1_Init private_SHA1_Init +# define SHA224_Init private_SHA224_Init +# define SHA256_Init private_SHA256_Init +# define SHA384_Init private_SHA384_Init +# define SHA512_Init private_SHA512_Init + +# define BF_set_key private_BF_set_key +# define CAST_set_key private_CAST_set_key +# define idea_set_encrypt_key private_idea_set_encrypt_key +# define SEED_set_key private_SEED_set_key +# define RC2_set_key private_RC2_set_key +# define RC4_set_key private_RC4_set_key +# define DES_set_key_unchecked private_DES_set_key_unchecked +# define Camellia_set_key private_Camellia_set_key + +#endif diff --git a/Sources/COpenSSL/ex_data.c b/Sources/COpenSSL/ex_data.c new file mode 100644 index 00000000..e52a5065 --- /dev/null +++ b/Sources/COpenSSL/ex_data.c @@ -0,0 +1,660 @@ +/* crypto/ex_data.c */ + +/* + * Overhaul notes; + * + * This code is now *mostly* thread-safe. It is now easier to understand in what + * ways it is safe and in what ways it is not, which is an improvement. Firstly, + * all per-class stacks and index-counters for ex_data are stored in the same + * global LHASH table (keyed by class). This hash table uses locking for all + * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be + * called when no other threads can possibly race against it (even if it was + * locked, the race would mean it's possible the hash table might have been + * recreated after the cleanup). As classes can only be added to the hash table, + * and within each class, the stack of methods can only be incremented, the + * locking mechanics are simpler than they would otherwise be. For example, the + * new/dup/free ex_data functions will lock the hash table, copy the method + * pointers it needs from the relevant class, then unlock the hash table before + * actually applying those method pointers to the task of the new/dup/free + * operations. As they can't be removed from the method-stack, only + * supplemented, there's no race conditions associated with using them outside + * the lock. The get/set_ex_data functions are not locked because they do not + * involve this global state at all - they operate directly with a previously + * obtained per-class method index and a particular "ex_data" variable. These + * variables are usually instantiated per-context (eg. each RSA structure has + * one) so locking on read/write access to that variable can be locked locally + * if required (eg. using the "RSA" lock to synchronise access to a + * per-RSA-structure ex_data variable if required). + * [Geoff] + */ + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "lhash.h" + +/* What an "implementation of ex_data functionality" looks like */ +struct st_CRYPTO_EX_DATA_IMPL { + /*********************/ + /* GLOBAL OPERATIONS */ + /* Return a new class index */ + int (*cb_new_class) (void); + /* Cleanup all state used by the implementation */ + void (*cb_cleanup) (void); + /************************/ + /* PER-CLASS OPERATIONS */ + /* Get a new method index within a class */ + int (*cb_get_new_index) (int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + /* Initialise a new CRYPTO_EX_DATA of a given class */ + int (*cb_new_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad); + /* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */ + int (*cb_dup_ex_data) (int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); + /* Cleanup a CRYPTO_EX_DATA of a given class */ + void (*cb_free_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad); +}; + +/* The implementation we use at run-time */ +static const CRYPTO_EX_DATA_IMPL *impl = NULL; + +/* + * To call "impl" functions, use this macro rather than referring to 'impl' + * directly, eg. EX_IMPL(get_new_index)(...); + */ +#define EX_IMPL(a) impl->cb_##a + +/* Predeclare the "default" ex_data implementation */ +static int int_new_class(void); +static void int_cleanup(void); +static int int_get_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +static CRYPTO_EX_DATA_IMPL impl_default = { + int_new_class, + int_cleanup, + int_get_new_index, + int_new_ex_data, + int_dup_ex_data, + int_free_ex_data +}; + +/* + * Internal function that checks whether "impl" is set and if not, sets it to + * the default. + */ +static void impl_check(void) +{ + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + if (!impl) + impl = &impl_default; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); +} + +/* + * A macro wrapper for impl_check that first uses a non-locked test before + * invoking the function (which checks again inside a lock). + */ +#define IMPL_CHECK if(!impl) impl_check(); + +/* API functions to get/set the "ex_data" implementation */ +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void) +{ + IMPL_CHECK return impl; +} + +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i) +{ + int toret = 0; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + if (!impl) { + impl = i; + toret = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +/****************************************************************************/ +/* + * Interal (default) implementation of "ex_data" support. API functions are + * further down. + */ + +/* + * The type that represents what each "class" used to implement locally. A + * STACK of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is + * the global value representing the class that is used to distinguish these + * items. + */ +typedef struct st_ex_class_item { + int class_index; + STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth; + int meth_num; +} EX_CLASS_ITEM; + +/* When assigning new class indexes, this is our counter */ +static int ex_class = CRYPTO_EX_INDEX_USER; + +/* The global hash table of EX_CLASS_ITEM items */ +DECLARE_LHASH_OF(EX_CLASS_ITEM); +static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL; + +/* The callbacks required in the "ex_data" hash table */ +static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a) +{ + return a->class_index; +} + +static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM) + +static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b) +{ + return a->class_index - b->class_index; +} + +static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM) + +/* + * Internal functions used by the "impl_default" implementation to access the + * state + */ +static int ex_data_check(void) +{ + int toret = 1; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + if (!ex_data && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL) + toret = 0; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +/* + * This macros helps reduce the locking from repeated checks because the + * ex_data_check() function checks ex_data again inside a lock. + */ +#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail} + +/* This "inner" callback is used by the callback function that follows it */ +static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs) +{ + OPENSSL_free(funcs); +} + +/* + * This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from + * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't + * do any locking. + */ +static void def_cleanup_cb(void *a_void) +{ + EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void; + sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb); + OPENSSL_free(item); +} + +/* + * Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to + * a given class. Handles locking. + */ +static EX_CLASS_ITEM *def_get_class(int class_index) +{ + EX_CLASS_ITEM d, *p, *gen; + EX_DATA_CHECK(return NULL;) + d.class_index = class_index; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); + if (!p) { + gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM)); + if (gen) { + gen->class_index = class_index; + gen->meth_num = 0; + gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); + if (!gen->meth) + OPENSSL_free(gen); + else { + /* + * Because we're inside the ex_data lock, the return value + * from the insert will be NULL + */ + (void)lh_EX_CLASS_ITEM_insert(ex_data, gen); + p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); + if (p != gen) { + sk_CRYPTO_EX_DATA_FUNCS_free(gen->meth); + OPENSSL_free(gen); + } + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + if (!p) + CRYPTOerr(CRYPTO_F_DEF_GET_CLASS, ERR_R_MALLOC_FAILURE); + return p; +} + +/* + * Add a new method to the given EX_CLASS_ITEM and return the corresponding + * index (or -1 for error). Handles locking. + */ +static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + int toret = -1; + CRYPTO_EX_DATA_FUNCS *a = + (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); + if (!a) { + CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE); + return -1; + } + a->argl = argl; + a->argp = argp; + a->new_func = new_func; + a->dup_func = dup_func; + a->free_func = free_func; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) { + if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) { + CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE); + OPENSSL_free(a); + goto err; + } + } + toret = item->meth_num++; + (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); + err: + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +/**************************************************************/ +/* The functions in the default CRYPTO_EX_DATA_IMPL structure */ + +static int int_new_class(void) +{ + int toret; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + toret = ex_class++; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +static void int_cleanup(void) +{ + EX_DATA_CHECK(return;) + lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb); + lh_EX_CLASS_ITEM_free(ex_data); + ex_data = NULL; + impl = NULL; +} + +static int int_get_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + EX_CLASS_ITEM *item = def_get_class(class_index); + if (!item) + return -1; + return def_add_index(item, argl, argp, new_func, dup_func, free_func); +} + +/* + * Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries + * in the lock, then using them outside the lock. NB: Thread-safety only + * applies to the global "ex_data" state (ie. class definitions), not + * thread-safe on 'ad' itself. + */ +static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + int mx, i; + void *ptr; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + EX_CLASS_ITEM *item = def_get_class(class_index); + if (!item) + /* error is already set */ + return 0; + ad->sk = NULL; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + if (mx > 0) { + storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); + } + skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + if ((mx > 0) && !storage) { + CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA, ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < mx; i++) { + if (storage[i] && storage[i]->new_func) { + ptr = CRYPTO_get_ex_data(ad, i); + storage[i]->new_func(obj, ptr, ad, i, + storage[i]->argl, storage[i]->argp); + } + } + if (storage) + OPENSSL_free(storage); + return 1; +} + +/* Same thread-safety notes as for "int_new_ex_data" */ +static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from) +{ + int mx, j, i; + void *ptr; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + EX_CLASS_ITEM *item; + if (!from->sk) + /* 'to' should be "blank" which *is* just like 'from' */ + return 1; + if ((item = def_get_class(class_index)) == NULL) + return 0; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + j = sk_void_num(from->sk); + if (j < mx) + mx = j; + if (mx > 0) { + /* + * Make sure the ex_data stack is at least |mx| elements long to avoid + * issues in the for loop that follows; so go get the |mx|'th element + * (if it does not exist CRYPTO_get_ex_data() returns NULL), and assign + * to itself. This is normally a no-op; but ensures the stack is the + * proper size + */ + if (!CRYPTO_set_ex_data(to, mx - 1, CRYPTO_get_ex_data(to, mx - 1))) + goto skip; + storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); + } + skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + if ((mx > 0) && !storage) { + CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA, ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < mx; i++) { + ptr = CRYPTO_get_ex_data(from, i); + if (storage[i] && storage[i]->dup_func) + storage[i]->dup_func(to, from, &ptr, i, + storage[i]->argl, storage[i]->argp); + CRYPTO_set_ex_data(to, i, ptr); + } + if (storage) + OPENSSL_free(storage); + return 1; +} + +/* Same thread-safety notes as for "int_new_ex_data" */ +static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + int mx, i; + EX_CLASS_ITEM *item; + void *ptr; + CRYPTO_EX_DATA_FUNCS *f; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + if (ex_data == NULL) + goto err; + if ((item = def_get_class(class_index)) == NULL) + goto err; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + if (mx > 0) { + storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); + } + skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + for (i = 0; i < mx; i++) { + if (storage != NULL) + f = storage[i]; + else { + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + f = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + } + if (f != NULL && f->free_func != NULL) { + ptr = CRYPTO_get_ex_data(ad, i); + f->free_func(obj, ptr, ad, i, f->argl, f->argp); + } + } + OPENSSL_free(storage); + err: + sk_void_free(ad->sk); + ad->sk = NULL; +} + +/********************************************************************/ +/* + * API functions that defer all "state" operations to the "ex_data" + * implementation we have set. + */ + +/* + * Obtain an index for a new class (not the same as getting a new index + * within an existing class - this is actually getting a new *class*) + */ +int CRYPTO_ex_data_new_class(void) +{ + IMPL_CHECK return EX_IMPL(new_class) (); +} + +/* + * Release all "ex_data" state to prevent memory leaks. This can't be made + * thread-safe without overhauling a lot of stuff, and shouldn't really be + * called under potential race-conditions anyway (it's for program shutdown + * after all). + */ +void CRYPTO_cleanup_all_ex_data(void) +{ + IMPL_CHECK EX_IMPL(cleanup) (); +} + +/* Inside an existing class, get/register a new index. */ +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + int ret = -1; + + IMPL_CHECK + ret = EX_IMPL(get_new_index) (class_index, + argl, argp, new_func, dup_func, + free_func); + return ret; +} + +/* + * Initialise a new CRYPTO_EX_DATA for use in a particular class - including + * calling new() callbacks for each index in the class used by this variable + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + IMPL_CHECK return EX_IMPL(new_ex_data) (class_index, obj, ad); +} + +/* + * Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks + * for each index in the class used by this variable + */ +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from) +{ + IMPL_CHECK return EX_IMPL(dup_ex_data) (class_index, to, from); +} + +/* + * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for + * each index in the class used by this variable + */ +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + IMPL_CHECK EX_IMPL(free_ex_data) (class_index, obj, ad); +} + +/* + * For a given CRYPTO_EX_DATA variable, set the value corresponding to a + * particular index in the class used by this variable + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) +{ + int i; + + if (ad->sk == NULL) { + if ((ad->sk = sk_void_new_null()) == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE); + return (0); + } + } + i = sk_void_num(ad->sk); + + while (i <= idx) { + if (!sk_void_push(ad->sk, NULL)) { + CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE); + return (0); + } + i++; + } + sk_void_set(ad->sk, idx, val); + return (1); +} + +/* + * For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a + * particular index in the class used by this variable + */ +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) +{ + if (ad->sk == NULL) + return (0); + else if (idx >= sk_void_num(ad->sk)) + return (0); + else + return (sk_void_value(ad->sk, idx)); +} + +IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS) diff --git a/Sources/COpenSSL/ext_dat.h b/Sources/COpenSSL/ext_dat.h new file mode 100644 index 00000000..c3a6fce7 --- /dev/null +++ b/Sources/COpenSSL/ext_dat.h @@ -0,0 +1,136 @@ +/* ext_dat.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* This file contains a table of "standard" extensions */ + +extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; +extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; +extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; +extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; +extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; +extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; +extern X509V3_EXT_METHOD v3_crl_hold, v3_pci; +extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; +extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; +extern X509V3_EXT_METHOD v3_addr, v3_asid; +extern X509V3_EXT_METHOD v3_ct_scts[]; + +/* + * This table will be searched using OBJ_bsearch so it *must* kept in order + * of the ext_nid values. + */ + +static const X509V3_EXT_METHOD *standard_exts[] = { + &v3_nscert, + &v3_ns_ia5_list[0], + &v3_ns_ia5_list[1], + &v3_ns_ia5_list[2], + &v3_ns_ia5_list[3], + &v3_ns_ia5_list[4], + &v3_ns_ia5_list[5], + &v3_ns_ia5_list[6], + &v3_skey_id, + &v3_key_usage, + &v3_pkey_usage_period, + &v3_alt[0], + &v3_alt[1], + &v3_bcons, + &v3_crl_num, + &v3_cpols, + &v3_akey_id, + &v3_crld, + &v3_ext_ku, + &v3_delta_crl, + &v3_crl_reason, +#ifndef OPENSSL_NO_OCSP + &v3_crl_invdate, +#endif + &v3_sxnet, + &v3_info, +#ifndef OPENSSL_NO_RFC3779 + &v3_addr, + &v3_asid, +#endif +#ifndef OPENSSL_NO_OCSP + &v3_ocsp_nonce, + &v3_ocsp_crlid, + &v3_ocsp_accresp, + &v3_ocsp_nocheck, + &v3_ocsp_acutoff, + &v3_ocsp_serviceloc, +#endif + &v3_sinfo, + &v3_policy_constraints, +#ifndef OPENSSL_NO_OCSP + &v3_crl_hold, +#endif + &v3_pci, + &v3_name_constraints, + &v3_policy_mappings, + &v3_inhibit_anyp, + &v3_idp, + &v3_alt[2], + &v3_freshest_crl, + &v3_ct_scts[0], + &v3_ct_scts[1], +}; + +/* Number of standard extensions */ + +#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) diff --git a/Sources/COpenSSL/f_.c b/Sources/COpenSSL/f_.c new file mode 100644 index 00000000..48f83c99 --- /dev/null +++ b/Sources/COpenSSL/f_.c @@ -0,0 +1,627 @@ +/* crypto/asn1/f_enum.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "buffer.h" +#include "asn1.h" + +/* Based on a_int.c: equivalent ENUMERATED functions */ + +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a) +{ + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; + + if (a == NULL) + return (0); + + if (a->length == 0) { + if (BIO_write(bp, "00", 2) != 2) + goto err; + n = 2; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) + goto err; + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) + goto err; + n += 2; + } + } + return (n); + err: + return (-1); +} + +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) +{ + int ret = 0; + int i, j, k, m, n, again, bufsize; + unsigned char *s = NULL, *sp; + unsigned char *bufp; + int num = 0, slen = 0, first = 1; + + bs->type = V_ASN1_ENUMERATED; + + bufsize = BIO_gets(bp, buf, size); + for (;;) { + if (bufsize < 1) + goto err_sl; + i = bufsize; + if (buf[i - 1] == '\n') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + if (buf[i - 1] == '\r') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + again = (buf[i - 1] == '\\'); + + for (j = 0; j < i; j++) { + if (!(((buf[j] >= '0') && (buf[j] <= '9')) || + ((buf[j] >= 'a') && (buf[j] <= 'f')) || + ((buf[j] >= 'A') && (buf[j] <= 'F')))) { + i = j; + break; + } + } + buf[i] = '\0'; + /* + * We have now cleared all the crap off the end of the line + */ + if (i < 2) + goto err_sl; + + bufp = (unsigned char *)buf; + if (first) { + first = 0; + if ((bufp[0] == '0') && (bufp[1] == '0')) { + bufp += 2; + i -= 2; + } + } + k = 0; + i -= again; + if (i % 2 != 0) { + ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS); + goto err; + } + i /= 2; + if (num + i > slen) { + if (s == NULL) + sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + + i * 2); + else + sp = (unsigned char *)OPENSSL_realloc(s, + (unsigned int)num + + i * 2); + if (sp == NULL) { + ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); + goto err; + } + s = sp; + slen = num + i * 2; + } + for (j = 0; j < i; j++, k += 2) { + for (n = 0; n < 2; n++) { + m = bufp[k + n]; + if ((m >= '0') && (m <= '9')) + m -= '0'; + else if ((m >= 'a') && (m <= 'f')) + m = m - 'a' + 10; + else if ((m >= 'A') && (m <= 'F')) + m = m - 'A' + 10; + else { + ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, + ASN1_R_NON_HEX_CHARACTERS); + goto err; + } + s[num + j] <<= 4; + s[num + j] |= m; + } + } + num += i; + if (again) + bufsize = BIO_gets(bp, buf, size); + else + break; + } + bs->length = num; + bs->data = s; + ret = 1; + err: + if (0) { + err_sl: + ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE); + } + if (ret != 1) + OPENSSL_free(s); + return (ret); +} +/* crypto/asn1/f_int.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "asn1.h" + +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a) +{ + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; + + if (a == NULL) + return (0); + + if (a->type & V_ASN1_NEG) { + if (BIO_write(bp, "-", 1) != 1) + goto err; + n = 1; + } + + if (a->length == 0) { + if (BIO_write(bp, "00", 2) != 2) + goto err; + n += 2; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) + goto err; + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) + goto err; + n += 2; + } + } + return (n); + err: + return (-1); +} + +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) +{ + int ret = 0; + int i, j, k, m, n, again, bufsize; + unsigned char *s = NULL, *sp; + unsigned char *bufp; + int num = 0, slen = 0, first = 1; + + bs->type = V_ASN1_INTEGER; + + bufsize = BIO_gets(bp, buf, size); + for (;;) { + if (bufsize < 1) + goto err_sl; + i = bufsize; + if (buf[i - 1] == '\n') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + if (buf[i - 1] == '\r') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + again = (buf[i - 1] == '\\'); + + for (j = 0; j < i; j++) { +#ifndef CHARSET_EBCDIC + if (!(((buf[j] >= '0') && (buf[j] <= '9')) || + ((buf[j] >= 'a') && (buf[j] <= 'f')) || + ((buf[j] >= 'A') && (buf[j] <= 'F')))) +#else + /* + * This #ifdef is not strictly necessary, since the characters + * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but + * not the whole alphabet). Nevertheless, isxdigit() is faster. + */ + if (!isxdigit(buf[j])) +#endif + { + i = j; + break; + } + } + buf[i] = '\0'; + /* + * We have now cleared all the crap off the end of the line + */ + if (i < 2) + goto err_sl; + + bufp = (unsigned char *)buf; + if (first) { + first = 0; + if ((bufp[0] == '0') && (bufp[1] == '0')) { + bufp += 2; + i -= 2; + } + } + k = 0; + i -= again; + if (i % 2 != 0) { + ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS); + goto err; + } + i /= 2; + if (num + i > slen) { + if (s == NULL) + sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + + i * 2); + else + sp = OPENSSL_realloc_clean(s, slen, num + i * 2); + if (sp == NULL) { + ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + goto err; + } + s = sp; + slen = num + i * 2; + } + for (j = 0; j < i; j++, k += 2) { + for (n = 0; n < 2; n++) { + m = bufp[k + n]; + if ((m >= '0') && (m <= '9')) + m -= '0'; + else if ((m >= 'a') && (m <= 'f')) + m = m - 'a' + 10; + else if ((m >= 'A') && (m <= 'F')) + m = m - 'A' + 10; + else { + ASN1err(ASN1_F_A2I_ASN1_INTEGER, + ASN1_R_NON_HEX_CHARACTERS); + goto err; + } + s[num + j] <<= 4; + s[num + j] |= m; + } + } + num += i; + if (again) + bufsize = BIO_gets(bp, buf, size); + else + break; + } + bs->length = num; + bs->data = s; + ret = 1; + err: + if (0) { + err_sl: + ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE); + } + if (ret != 1) + OPENSSL_free(s); + return (ret); +} +/* crypto/asn1/f_string.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "asn1.h" + +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type) +{ + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; + + if (a == NULL) + return (0); + + if (a->length == 0) { + if (BIO_write(bp, "0", 1) != 1) + goto err; + n = 1; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) + goto err; + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) + goto err; + n += 2; + } + } + return (n); + err: + return (-1); +} + +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) +{ + int ret = 0; + int i, j, k, m, n, again, bufsize; + unsigned char *s = NULL, *sp; + unsigned char *bufp; + int num = 0, slen = 0, first = 1; + + bufsize = BIO_gets(bp, buf, size); + for (;;) { + if (bufsize < 1) { + if (first) + break; + else + goto err_sl; + } + first = 0; + + i = bufsize; + if (buf[i - 1] == '\n') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + if (buf[i - 1] == '\r') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + again = (buf[i - 1] == '\\'); + + for (j = i - 1; j > 0; j--) { +#ifndef CHARSET_EBCDIC + if (!(((buf[j] >= '0') && (buf[j] <= '9')) || + ((buf[j] >= 'a') && (buf[j] <= 'f')) || + ((buf[j] >= 'A') && (buf[j] <= 'F')))) +#else + /* + * This #ifdef is not strictly necessary, since the characters + * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but + * not the whole alphabet). Nevertheless, isxdigit() is faster. + */ + if (!isxdigit(buf[j])) +#endif + { + i = j; + break; + } + } + buf[i] = '\0'; + /* + * We have now cleared all the crap off the end of the line + */ + if (i < 2) + goto err_sl; + + bufp = (unsigned char *)buf; + + k = 0; + i -= again; + if (i % 2 != 0) { + ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS); + goto err; + } + i /= 2; + if (num + i > slen) { + if (s == NULL) + sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + + i * 2); + else + sp = (unsigned char *)OPENSSL_realloc(s, + (unsigned int)num + + i * 2); + if (sp == NULL) { + ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE); + goto err; + } + s = sp; + slen = num + i * 2; + } + for (j = 0; j < i; j++, k += 2) { + for (n = 0; n < 2; n++) { + m = bufp[k + n]; + if ((m >= '0') && (m <= '9')) + m -= '0'; + else if ((m >= 'a') && (m <= 'f')) + m = m - 'a' + 10; + else if ((m >= 'A') && (m <= 'F')) + m = m - 'A' + 10; + else { + ASN1err(ASN1_F_A2I_ASN1_STRING, + ASN1_R_NON_HEX_CHARACTERS); + goto err; + } + s[num + j] <<= 4; + s[num + j] |= m; + } + } + num += i; + if (again) + bufsize = BIO_gets(bp, buf, size); + else + break; + } + bs->length = num; + bs->data = s; + ret = 1; + err: + if (0) { + err_sl: + ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE); + } + if (ret != 1) + OPENSSL_free(s); + return (ret); +} diff --git a/Sources/COpenSSL/fcrypt.c b/Sources/COpenSSL/fcrypt.c new file mode 100644 index 00000000..cb7c5c59 --- /dev/null +++ b/Sources/COpenSSL/fcrypt.c @@ -0,0 +1,167 @@ +/* NOCW */ +#include +#ifdef _OSD_POSIX +# ifndef CHARSET_EBCDIC +# define CHARSET_EBCDIC 1 +# endif +#endif +#ifdef CHARSET_EBCDIC +# include "ebcdic.h" +#endif + +/* + * This version of crypt has been developed from my MIT compatible DES + * library. Eric Young (eay@cryptsoft.com) + */ + +/* + * Modification by Jens Kupferschmidt (Cu) I have included directive PARA for + * shared memory computers. I have included a directive LONGCRYPT to using + * this routine to cipher passwords with more then 8 bytes like HP-UX 10.x it + * used. The MAXPLEN definition is the maximum of length of password and can + * changed. I have defined 24. + */ + +#include "des_locl.h" + +/* + * Added more values to handle illegal salt values the way normal crypt() + * implementations do. The patch was sent by Bjorn Gronvall + */ +static unsigned const char con_salt[128] = { + 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, + 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, + 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, + 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, + 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, + 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, + 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, + 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, +}; + +static unsigned const char cov_2char[64] = { + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, + 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, + 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, + 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, + 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A +}; + +char *DES_crypt(const char *buf, const char *salt) +{ + static char buff[14]; + +#ifndef CHARSET_EBCDIC + return (DES_fcrypt(buf, salt, buff)); +#else + char e_salt[2 + 1]; + char e_buf[32 + 1]; /* replace 32 by 8 ? */ + char *ret; + + /* Copy at most 2 chars of salt */ + if ((e_salt[0] = salt[0]) != '\0') + e_salt[1] = salt[1]; + + /* Copy at most 32 chars of password */ + strncpy(e_buf, buf, sizeof(e_buf)); + + /* Make sure we have a delimiter */ + e_salt[sizeof(e_salt) - 1] = e_buf[sizeof(e_buf) - 1] = '\0'; + + /* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */ + ebcdic2ascii(e_salt, e_salt, sizeof(e_salt)); + + /* Convert the cleartext password to ASCII */ + ebcdic2ascii(e_buf, e_buf, sizeof(e_buf)); + + /* Encrypt it (from/to ASCII) */ + ret = DES_fcrypt(e_buf, e_salt, buff); + + /* Convert the result back to EBCDIC */ + ascii2ebcdic(ret, ret, strlen(ret)); + + return ret; +#endif +} + +char *DES_fcrypt(const char *buf, const char *salt, char *ret) +{ + unsigned int i, j, x, y; + DES_LONG Eswap0, Eswap1; + DES_LONG out[2], ll; + DES_cblock key; + DES_key_schedule ks; + unsigned char bb[9]; + unsigned char *b = bb; + unsigned char c, u; + + /* + * eay 25/08/92 If you call crypt("pwd","*") as often happens when you + * have * as the pwd field in /etc/passwd, the function returns + * *\0XXXXXXXXX The \0 makes the string look like * so the pwd "*" would + * crypt to "*". This was found when replacing the crypt in our shared + * libraries. People found that the disabled accounts effectively had no + * passwd :-(. + */ +#ifndef CHARSET_EBCDIC + x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]); + Eswap0 = con_salt[x] << 2; + x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]); + Eswap1 = con_salt[x] << 6; +#else + x = ret[0] = ((salt[0] == '\0') ? os_toascii['A'] : salt[0]); + Eswap0 = con_salt[x] << 2; + x = ret[1] = ((salt[1] == '\0') ? os_toascii['A'] : salt[1]); + Eswap1 = con_salt[x] << 6; +#endif + + /* + * EAY r=strlen(buf); r=(r+7)/8; + */ + for (i = 0; i < 8; i++) { + c = *(buf++); + if (!c) + break; + key[i] = (c << 1); + } + for (; i < 8; i++) + key[i] = 0; + + DES_set_key_unchecked(&key, &ks); + fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1); + + ll = out[0]; + l2c(ll, b); + ll = out[1]; + l2c(ll, b); + y = 0; + u = 0x80; + bb[8] = 0; + for (i = 2; i < 13; i++) { + c = 0; + for (j = 0; j < 6; j++) { + c <<= 1; + if (bb[y] & u) + c |= 1; + u >>= 1; + if (!u) { + y++; + u = 0x80; + } + } + ret[i] = cov_2char[c]; + } + ret[13] = '\0'; + return (ret); +} diff --git a/Sources/COpenSSL/fcrypt_b.c b/Sources/COpenSSL/fcrypt_b.c new file mode 100644 index 00000000..b9e87383 --- /dev/null +++ b/Sources/COpenSSL/fcrypt_b.c @@ -0,0 +1,140 @@ +/* crypto/des/fcrypt_b.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +/* + * This version of crypt has been developed from my MIT compatible DES + * library. The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au + * Eric Young (eay@cryptsoft.com) + */ + +#define DES_FCRYPT +#include "des_locl.h" +#undef DES_FCRYPT + +#undef PERM_OP +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + +#undef HPERM_OP +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ + (a)=(a)^(t)^(t>>(16-(n))))\ + +void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0, + DES_LONG Eswap1) +{ + register DES_LONG l, r, t, u; +#ifdef DES_PTR + register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif + register DES_LONG *s; + register int j; + register DES_LONG E0, E1; + + l = 0; + r = 0; + + s = (DES_LONG *)ks; + E0 = Eswap0; + E1 = Eswap1; + + for (j = 0; j < 25; j++) { +#ifndef DES_UNROLL + register int i; + + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#else + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#endif + + t = l; + l = r; + r = t; + } + l = ROTATE(l, 3) & 0xffffffffL; + r = ROTATE(r, 3) & 0xffffffffL; + + PERM_OP(l, r, t, 1, 0x55555555L); + PERM_OP(r, l, t, 8, 0x00ff00ffL); + PERM_OP(l, r, t, 2, 0x33333333L); + PERM_OP(r, l, t, 16, 0x0000ffffL); + PERM_OP(l, r, t, 4, 0x0f0f0f0fL); + + out[0] = r; + out[1] = l; +} diff --git a/Sources/COpenSSL/fips_err.h b/Sources/COpenSSL/fips_err.h new file mode 100644 index 00000000..478cf0e2 --- /dev/null +++ b/Sources/COpenSSL/fips_err.h @@ -0,0 +1,223 @@ +/* crypto/fips_err.h */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason) + +static ERR_STRING_DATA FIPS_str_functs[] = { + {ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, + {ERR_FUNC(FIPS_F_DH_INIT), "DH_INIT"}, + {ERR_FUNC(FIPS_F_DRBG_RESEED), "DRBG_RESEED"}, + {ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"}, + {ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"}, + {ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"}, + {ERR_FUNC(FIPS_F_DSA_DO_VERIFY), "DSA_do_verify"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_DSA), "FIPS_CHECK_DSA"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_DSA_PRNG), "fips_check_dsa_prng"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_EC), "FIPS_CHECK_EC"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_EC_PRNG), "fips_check_ec_prng"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT), + "FIPS_check_incore_fingerprint"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_RSA), "fips_check_rsa"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_RSA_PRNG), "fips_check_rsa_prng"}, + {ERR_FUNC(FIPS_F_FIPS_CIPHER), "FIPS_cipher"}, + {ERR_FUNC(FIPS_F_FIPS_CIPHERINIT), "FIPS_cipherinit"}, + {ERR_FUNC(FIPS_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"}, + {ERR_FUNC(FIPS_F_FIPS_DIGESTFINAL), "FIPS_digestfinal"}, + {ERR_FUNC(FIPS_F_FIPS_DIGESTINIT), "FIPS_digestinit"}, + {ERR_FUNC(FIPS_F_FIPS_DIGESTUPDATE), "FIPS_digestupdate"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_BYTES), "FIPS_DRBG_BYTES"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_CHECK), "FIPS_DRBG_CHECK"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_CPRNG_TEST), "FIPS_DRBG_CPRNG_TEST"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_ERROR_CHECK), "FIPS_DRBG_ERROR_CHECK"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE), "FIPS_drbg_generate"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_INIT), "FIPS_drbg_init"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE), "FIPS_drbg_instantiate"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_NEW), "FIPS_drbg_new"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_RESEED), "FIPS_drbg_reseed"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_SINGLE_KAT), "FIPS_DRBG_SINGLE_KAT"}, + {ERR_FUNC(FIPS_F_FIPS_DSA_SIGN_DIGEST), "FIPS_dsa_sign_digest"}, + {ERR_FUNC(FIPS_F_FIPS_DSA_VERIFY_DIGEST), "FIPS_dsa_verify_digest"}, + {ERR_FUNC(FIPS_F_FIPS_GET_ENTROPY), "FIPS_GET_ENTROPY"}, + {ERR_FUNC(FIPS_F_FIPS_MODULE_MODE_SET), "FIPS_module_mode_set"}, + {ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST), "fips_pkey_signature_test"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_ADD), "FIPS_rand_add"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_BYTES), "FIPS_rand_bytes"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_PSEUDO_BYTES), "FIPS_rand_pseudo_bytes"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_SEED), "FIPS_rand_seed"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_SET_METHOD), "FIPS_rand_set_method"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_STATUS), "FIPS_rand_status"}, + {ERR_FUNC(FIPS_F_FIPS_RSA_SIGN_DIGEST), "FIPS_rsa_sign_digest"}, + {ERR_FUNC(FIPS_F_FIPS_RSA_VERIFY_DIGEST), "FIPS_rsa_verify_digest"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_CCM), "FIPS_selftest_aes_ccm"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_GCM), "FIPS_selftest_aes_gcm"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_XTS), "FIPS_selftest_aes_xts"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_CMAC), "FIPS_selftest_cmac"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_ECDSA), "FIPS_selftest_ecdsa"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC), "FIPS_selftest_hmac"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_X931), "FIPS_selftest_x931"}, + {ERR_FUNC(FIPS_F_FIPS_SET_PRNG_KEY), "FIPS_SET_PRNG_KEY"}, + {ERR_FUNC(FIPS_F_HASH_FINAL), "HASH_FINAL"}, + {ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, + {ERR_FUNC(FIPS_F_RSA_EAY_INIT), "RSA_EAY_INIT"}, + {ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, + {ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"}, + {ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"}, + {ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"}, + {ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX), "RSA_X931_generate_key_ex"}, + {0, NULL} +}; + +static ERR_STRING_DATA FIPS_str_reasons[] = { + {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED), + "additional input error undetected"}, + {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_TOO_LONG), + "additional input too long"}, + {ERR_REASON(FIPS_R_ALREADY_INSTANTIATED), "already instantiated"}, + {ERR_REASON(FIPS_R_AUTHENTICATION_FAILURE), "authentication failure"}, + {ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE), "contradicting evidence"}, + {ERR_REASON(FIPS_R_DRBG_NOT_INITIALISED), "drbg not initialised"}, + {ERR_REASON(FIPS_R_DRBG_STUCK), "drbg stuck"}, + {ERR_REASON(FIPS_R_ENTROPY_ERROR_UNDETECTED), "entropy error undetected"}, + {ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED), + "entropy not requested for reseed"}, + {ERR_REASON(FIPS_R_ENTROPY_SOURCE_STUCK), "entropy source stuck"}, + {ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, + {ERR_REASON(FIPS_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, + {ERR_REASON(FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT), + "error retrieving additional input"}, + {ERR_REASON(FIPS_R_ERROR_RETRIEVING_ENTROPY), "error retrieving entropy"}, + {ERR_REASON(FIPS_R_ERROR_RETRIEVING_NONCE), "error retrieving nonce"}, + {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH), + "fingerprint does not match"}, + {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED), + "fingerprint does not match nonpic relocated"}, + {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING), + "fingerprint does not match segment aliasing"}, + {ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET), "fips mode already set"}, + {ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED), "fips selftest failed"}, + {ERR_REASON(FIPS_R_FUNCTION_ERROR), "function error"}, + {ERR_REASON(FIPS_R_GENERATE_ERROR), "generate error"}, + {ERR_REASON(FIPS_R_GENERATE_ERROR_UNDETECTED), + "generate error undetected"}, + {ERR_REASON(FIPS_R_INSTANTIATE_ERROR), "instantiate error"}, + {ERR_REASON(FIPS_R_INSUFFICIENT_SECURITY_STRENGTH), + "insufficient security strength"}, + {ERR_REASON(FIPS_R_INTERNAL_ERROR), "internal error"}, + {ERR_REASON(FIPS_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(FIPS_R_INVALID_PARAMETERS), "invalid parameters"}, + {ERR_REASON(FIPS_R_IN_ERROR_STATE), "in error state"}, + {ERR_REASON(FIPS_R_KEY_TOO_SHORT), "key too short"}, + {ERR_REASON(FIPS_R_NONCE_ERROR_UNDETECTED), "nonce error undetected"}, + {ERR_REASON(FIPS_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_REASON(FIPS_R_NOPR_TEST1_FAILURE), "nopr test1 failure"}, + {ERR_REASON(FIPS_R_NOPR_TEST2_FAILURE), "nopr test2 failure"}, + {ERR_REASON(FIPS_R_NOT_INSTANTIATED), "not instantiated"}, + {ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED), "pairwise test failed"}, + {ERR_REASON(FIPS_R_PERSONALISATION_ERROR_UNDETECTED), + "personalisation error undetected"}, + {ERR_REASON(FIPS_R_PERSONALISATION_STRING_TOO_LONG), + "personalisation string too long"}, + {ERR_REASON(FIPS_R_PRNG_STRENGTH_TOO_LOW), "prng strength too low"}, + {ERR_REASON(FIPS_R_PR_TEST1_FAILURE), "pr test1 failure"}, + {ERR_REASON(FIPS_R_PR_TEST2_FAILURE), "pr test2 failure"}, + {ERR_REASON(FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED), + "request length error undetected"}, + {ERR_REASON(FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG), + "request too large for drbg"}, + {ERR_REASON(FIPS_R_RESEED_COUNTER_ERROR), "reseed counter error"}, + {ERR_REASON(FIPS_R_RESEED_ERROR), "reseed error"}, + {ERR_REASON(FIPS_R_SELFTEST_FAILED), "selftest failed"}, + {ERR_REASON(FIPS_R_SELFTEST_FAILURE), "selftest failure"}, + {ERR_REASON(FIPS_R_STRENGTH_ERROR_UNDETECTED), + "strength error undetected"}, + {ERR_REASON(FIPS_R_TEST_FAILURE), "test failure"}, + {ERR_REASON(FIPS_R_UNINSTANTIATE_ERROR), "uninstantiate error"}, + {ERR_REASON(FIPS_R_UNINSTANTIATE_ZEROISE_ERROR), + "uninstantiate zeroise error"}, + {ERR_REASON(FIPS_R_UNSUPPORTED_DRBG_TYPE), "unsupported drbg type"}, + {ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM), "unsupported platform"}, + {0, NULL} +}; + +#endif + +void ERR_load_FIPS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL) { + ERR_load_strings(0, FIPS_str_functs); + ERR_load_strings(0, FIPS_str_reasons); + } +#endif +} diff --git a/Sources/COpenSSL/fips_ers.c b/Sources/COpenSSL/fips_ers.c new file mode 100644 index 00000000..4a030805 --- /dev/null +++ b/Sources/COpenSSL/fips_ers.c @@ -0,0 +1,7 @@ +#include "opensslconf.h" + +#ifdef OPENSSL_FIPS +# include "fips_err.h" +#else +static void *dummy = &dummy; +#endif diff --git a/Sources/COpenSSL/gcm128.c b/Sources/COpenSSL/gcm128.c new file mode 100644 index 00000000..71bb8a83 --- /dev/null +++ b/Sources/COpenSSL/gcm128.c @@ -0,0 +1,2371 @@ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#define OPENSSL_FIPSAPI + +#include "crypto.h" +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#if defined(BSWAP4) && defined(STRICT_ALIGNMENT) +/* redefine, because alignment is ensured */ +# undef GETU32 +# define GETU32(p) BSWAP4(*(const u32 *)(p)) +# undef PUTU32 +# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) +#endif + +#define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16)) +#define REDUCE1BIT(V) do { \ + if (sizeof(size_t)==8) { \ + u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \ + V.lo = (V.hi<<63)|(V.lo>>1); \ + V.hi = (V.hi>>1 )^T; \ + } \ + else { \ + u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \ + V.lo = (V.hi<<63)|(V.lo>>1); \ + V.hi = (V.hi>>1 )^((u64)T<<32); \ + } \ +} while(0) + +/*- + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should + * never be set to 8. 8 is effectively reserved for testing purposes. + * TABLE_BITS>1 are lookup-table-driven implementations referred to as + * "Shoup's" in GCM specification. In other words OpenSSL does not cover + * whole spectrum of possible table driven implementations. Why? In + * non-"Shoup's" case memory access pattern is segmented in such manner, + * that it's trivial to see that cache timing information can reveal + * fair portion of intermediate hash value. Given that ciphertext is + * always available to attacker, it's possible for him to attempt to + * deduce secret parameter H and if successful, tamper with messages + * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's + * not as trivial, but there is no reason to believe that it's resistant + * to cache-timing attack. And the thing about "8-bit" implementation is + * that it consumes 16 (sixteen) times more memory, 4KB per individual + * key + 1KB shared. Well, on pros side it should be twice as fast as + * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version + * was observed to run ~75% faster, closer to 100% for commercial + * compilers... Yet "4-bit" procedure is preferred, because it's + * believed to provide better security-performance balance and adequate + * all-round performance. "All-round" refers to things like: + * + * - shorter setup time effectively improves overall timing for + * handling short messages; + * - larger table allocation can become unbearable because of VM + * subsystem penalties (for example on Windows large enough free + * results in VM working set trimming, meaning that consequent + * malloc would immediately incur working set expansion); + * - larger table has larger cache footprint, which can affect + * performance of other code paths (not necessarily even from same + * thread in Hyper-Threading world); + * + * Value of 1 is not appropriate for performance reasons. + */ +#if TABLE_BITS==8 + +static void gcm_init_8bit(u128 Htable[256], u64 H[2]) +{ + int i, j; + u128 V; + + Htable[0].hi = 0; + Htable[0].lo = 0; + V.hi = H[0]; + V.lo = H[1]; + + for (Htable[128] = V, i = 64; i > 0; i >>= 1) { + REDUCE1BIT(V); + Htable[i] = V; + } + + for (i = 2; i < 256; i <<= 1) { + u128 *Hi = Htable + i, H0 = *Hi; + for (j = 1; j < i; ++j) { + Hi[j].hi = H0.hi ^ Htable[j].hi; + Hi[j].lo = H0.lo ^ Htable[j].lo; + } + } +} + +static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) +{ + u128 Z = { 0, 0 }; + const u8 *xi = (const u8 *)Xi + 15; + size_t rem, n = *xi; + const union { + long one; + char little; + } is_endian = { + 1 + }; + static const size_t rem_8bit[256] = { + PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246), + PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E), + PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56), + PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E), + PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66), + PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E), + PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076), + PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E), + PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06), + PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E), + PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416), + PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E), + PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626), + PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E), + PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836), + PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E), + PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6), + PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE), + PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6), + PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE), + PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6), + PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE), + PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6), + PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE), + PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86), + PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E), + PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496), + PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E), + PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6), + PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE), + PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6), + PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE), + PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346), + PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E), + PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56), + PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E), + PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66), + PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E), + PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176), + PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E), + PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06), + PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E), + PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516), + PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E), + PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726), + PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E), + PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936), + PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E), + PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6), + PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE), + PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6), + PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE), + PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6), + PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE), + PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6), + PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE), + PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86), + PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E), + PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596), + PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E), + PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6), + PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE), + PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6), + PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE) + }; + + while (1) { + Z.hi ^= Htable[n].hi; + Z.lo ^= Htable[n].lo; + + if ((u8 *)Xi == xi) + break; + + n = *(--xi); + + rem = (size_t)Z.lo & 0xff; + Z.lo = (Z.hi << 56) | (Z.lo >> 8); + Z.hi = (Z.hi >> 8); + if (sizeof(size_t) == 8) + Z.hi ^= rem_8bit[rem]; + else + Z.hi ^= (u64)rem_8bit[rem] << 32; + } + + if (is_endian.little) { +# ifdef BSWAP8 + Xi[0] = BSWAP8(Z.hi); + Xi[1] = BSWAP8(Z.lo); +# else + u8 *p = (u8 *)Xi; + u32 v; + v = (u32)(Z.hi >> 32); + PUTU32(p, v); + v = (u32)(Z.hi); + PUTU32(p + 4, v); + v = (u32)(Z.lo >> 32); + PUTU32(p + 8, v); + v = (u32)(Z.lo); + PUTU32(p + 12, v); +# endif + } else { + Xi[0] = Z.hi; + Xi[1] = Z.lo; + } +} + +# define GCM_MUL(ctx,Xi) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable) + +#elif TABLE_BITS==4 + +static void gcm_init_4bit(u128 Htable[16], u64 H[2]) +{ + u128 V; +# if defined(OPENSSL_SMALL_FOOTPRINT) + int i; +# endif + + Htable[0].hi = 0; + Htable[0].lo = 0; + V.hi = H[0]; + V.lo = H[1]; + +# if defined(OPENSSL_SMALL_FOOTPRINT) + for (Htable[8] = V, i = 4; i > 0; i >>= 1) { + REDUCE1BIT(V); + Htable[i] = V; + } + + for (i = 2; i < 16; i <<= 1) { + u128 *Hi = Htable + i; + int j; + for (V = *Hi, j = 1; j < i; ++j) { + Hi[j].hi = V.hi ^ Htable[j].hi; + Hi[j].lo = V.lo ^ Htable[j].lo; + } + } +# else + Htable[8] = V; + REDUCE1BIT(V); + Htable[4] = V; + REDUCE1BIT(V); + Htable[2] = V; + REDUCE1BIT(V); + Htable[1] = V; + Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo; + V = Htable[4]; + Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo; + Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo; + Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo; + V = Htable[8]; + Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo; + Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo; + Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo; + Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo; + Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo; + Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo; + Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo; +# endif +# if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm)) + /* + * ARM assembler expects specific dword order in Htable. + */ + { + int j; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + if (is_endian.little) + for (j = 0; j < 16; ++j) { + V = Htable[j]; + Htable[j].hi = V.lo; + Htable[j].lo = V.hi; + } else + for (j = 0; j < 16; ++j) { + V = Htable[j]; + Htable[j].hi = V.lo << 32 | V.lo >> 32; + Htable[j].lo = V.hi << 32 | V.hi >> 32; + } + } +# endif +} + +# ifndef GHASH_ASM +static const size_t rem_4bit[16] = { + PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460), + PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0), + PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560), + PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) +}; + +static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) +{ + u128 Z; + int cnt = 15; + size_t rem, nlo, nhi; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + nlo = ((const u8 *)Xi)[15]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi = Htable[nlo].hi; + Z.lo = Htable[nlo].lo; + + while (1) { + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + if (sizeof(size_t) == 8) + Z.hi ^= rem_4bit[rem]; + else + Z.hi ^= (u64)rem_4bit[rem] << 32; + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) + break; + + nlo = ((const u8 *)Xi)[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + if (sizeof(size_t) == 8) + Z.hi ^= rem_4bit[rem]; + else + Z.hi ^= (u64)rem_4bit[rem] << 32; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } + + if (is_endian.little) { +# ifdef BSWAP8 + Xi[0] = BSWAP8(Z.hi); + Xi[1] = BSWAP8(Z.lo); +# else + u8 *p = (u8 *)Xi; + u32 v; + v = (u32)(Z.hi >> 32); + PUTU32(p, v); + v = (u32)(Z.hi); + PUTU32(p + 4, v); + v = (u32)(Z.lo >> 32); + PUTU32(p + 8, v); + v = (u32)(Z.lo); + PUTU32(p + 12, v); +# endif + } else { + Xi[0] = Z.hi; + Xi[1] = Z.lo; + } +} + +# if !defined(OPENSSL_SMALL_FOOTPRINT) +/* + * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for + * details... Compiler-generated code doesn't seem to give any + * performance improvement, at least not on x86[_64]. It's here + * mostly as reference and a placeholder for possible future + * non-trivial optimization[s]... + */ +static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) +{ + u128 Z; + int cnt; + size_t rem, nlo, nhi; + const union { + long one; + char little; + } is_endian = { + 1 + }; + +# if 1 + do { + cnt = 15; + nlo = ((const u8 *)Xi)[15]; + nlo ^= inp[15]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi = Htable[nlo].hi; + Z.lo = Htable[nlo].lo; + + while (1) { + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + if (sizeof(size_t) == 8) + Z.hi ^= rem_4bit[rem]; + else + Z.hi ^= (u64)rem_4bit[rem] << 32; + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) + break; + + nlo = ((const u8 *)Xi)[cnt]; + nlo ^= inp[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + if (sizeof(size_t) == 8) + Z.hi ^= rem_4bit[rem]; + else + Z.hi ^= (u64)rem_4bit[rem] << 32; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } +# else + /* + * Extra 256+16 bytes per-key plus 512 bytes shared tables + * [should] give ~50% improvement... One could have PACK()-ed + * the rem_8bit even here, but the priority is to minimize + * cache footprint... + */ + u128 Hshr4[16]; /* Htable shifted right by 4 bits */ + u8 Hshl4[16]; /* Htable shifted left by 4 bits */ + static const unsigned short rem_8bit[256] = { + 0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E, + 0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E, + 0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E, + 0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E, + 0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E, + 0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E, + 0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E, + 0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E, + 0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE, + 0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE, + 0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE, + 0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE, + 0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E, + 0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E, + 0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE, + 0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE, + 0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E, + 0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E, + 0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E, + 0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E, + 0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E, + 0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E, + 0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E, + 0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E, + 0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE, + 0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE, + 0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE, + 0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE, + 0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E, + 0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E, + 0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE, + 0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE + }; + /* + * This pre-processing phase slows down procedure by approximately + * same time as it makes each loop spin faster. In other words + * single block performance is approximately same as straightforward + * "4-bit" implementation, and then it goes only faster... + */ + for (cnt = 0; cnt < 16; ++cnt) { + Z.hi = Htable[cnt].hi; + Z.lo = Htable[cnt].lo; + Hshr4[cnt].lo = (Z.hi << 60) | (Z.lo >> 4); + Hshr4[cnt].hi = (Z.hi >> 4); + Hshl4[cnt] = (u8)(Z.lo << 4); + } + + do { + for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) { + nlo = ((const u8 *)Xi)[cnt]; + nlo ^= inp[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + + rem = (size_t)Z.lo & 0xff; + + Z.lo = (Z.hi << 56) | (Z.lo >> 8); + Z.hi = (Z.hi >> 8); + + Z.hi ^= Hshr4[nhi].hi; + Z.lo ^= Hshr4[nhi].lo; + Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48; + } + + nlo = ((const u8 *)Xi)[0]; + nlo ^= inp[0]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + + rem = (size_t)Z.lo & 0xf; + + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48; +# endif + + if (is_endian.little) { +# ifdef BSWAP8 + Xi[0] = BSWAP8(Z.hi); + Xi[1] = BSWAP8(Z.lo); +# else + u8 *p = (u8 *)Xi; + u32 v; + v = (u32)(Z.hi >> 32); + PUTU32(p, v); + v = (u32)(Z.hi); + PUTU32(p + 4, v); + v = (u32)(Z.lo >> 32); + PUTU32(p + 8, v); + v = (u32)(Z.lo); + PUTU32(p + 12, v); +# endif + } else { + Xi[0] = Z.hi; + Xi[1] = Z.lo; + } + } while (inp += 16, len -= 16); +} +# endif +# else +void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif + +# define GCM_MUL(ctx,Xi) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable) +# if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT) +# define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len) +/* + * GHASH_CHUNK is "stride parameter" missioned to mitigate cache trashing + * effect. In other words idea is to hash data while it's still in L1 cache + * after encryption pass... + */ +# define GHASH_CHUNK (3*1024) +# endif + +#else /* TABLE_BITS */ + +static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) +{ + u128 V, Z = { 0, 0 }; + long X; + int i, j; + const long *xi = (const long *)Xi; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + V.hi = H[0]; /* H is in host byte order, no byte swapping */ + V.lo = H[1]; + + for (j = 0; j < 16 / sizeof(long); ++j) { + if (is_endian.little) { + if (sizeof(long) == 8) { +# ifdef BSWAP8 + X = (long)(BSWAP8(xi[j])); +# else + const u8 *p = (const u8 *)(xi + j); + X = (long)((u64)GETU32(p) << 32 | GETU32(p + 4)); +# endif + } else { + const u8 *p = (const u8 *)(xi + j); + X = (long)GETU32(p); + } + } else + X = xi[j]; + + for (i = 0; i < 8 * sizeof(long); ++i, X <<= 1) { + u64 M = (u64)(X >> (8 * sizeof(long) - 1)); + Z.hi ^= V.hi & M; + Z.lo ^= V.lo & M; + + REDUCE1BIT(V); + } + } + + if (is_endian.little) { +# ifdef BSWAP8 + Xi[0] = BSWAP8(Z.hi); + Xi[1] = BSWAP8(Z.lo); +# else + u8 *p = (u8 *)Xi; + u32 v; + v = (u32)(Z.hi >> 32); + PUTU32(p, v); + v = (u32)(Z.hi); + PUTU32(p + 4, v); + v = (u32)(Z.lo >> 32); + PUTU32(p + 8, v); + v = (u32)(Z.lo); + PUTU32(p + 12, v); +# endif + } else { + Xi[0] = Z.hi; + Xi[1] = Z.lo; + } +} + +# define GCM_MUL(ctx,Xi) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u) + +#endif + +#if TABLE_BITS==4 && (defined(GHASH_ASM) || defined(OPENSSL_CPUID_OBJ)) +# if !defined(I386_ONLY) && \ + (defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define GHASH_ASM_X86_OR_64 +# define GCM_FUNCREF_4BIT +extern unsigned int OPENSSL_ia32cap_P[]; + +void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); + +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define gcm_init_avx gcm_init_clmul +# define gcm_gmult_avx gcm_gmult_clmul +# define gcm_ghash_avx gcm_ghash_clmul +# else +void gcm_init_avx(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_avx(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif + +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define GHASH_ASM_X86 +void gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); + +void gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif +# elif defined(__arm__) || defined(__arm) || defined(__aarch64__) +# include "arm_arch.h" +# if __ARM_MAX_ARCH__>=7 +# define GHASH_ASM_ARM +# define GCM_FUNCREF_4BIT +# define PMULL_CAPABLE (OPENSSL_armcap_P & ARMV8_PMULL) +# if defined(__arm__) || defined(__arm) +# define NEON_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) +# endif +void gcm_init_neon(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +void gcm_init_v8(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_v8(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_v8(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif +# elif defined(__sparc__) || defined(__sparc) +# include "sparc_arch.h" +# define GHASH_ASM_SPARC +# define GCM_FUNCREF_4BIT +extern unsigned int OPENSSL_sparcv9cap_P[]; +void gcm_init_vis3(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_vis3(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_vis3(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) +# include "ppc_arch.h" +# define GHASH_ASM_PPC +# define GCM_FUNCREF_4BIT +void gcm_init_p8(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_p8(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif +#endif + +#ifdef GCM_FUNCREF_4BIT +# undef GCM_MUL +# define GCM_MUL(ctx,Xi) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable) +# ifdef GHASH +# undef GHASH +# define GHASH(ctx,in,len) (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len) +# endif +#endif + +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + + memset(ctx, 0, sizeof(*ctx)); + ctx->block = block; + ctx->key = key; + + (*block) (ctx->H.c, ctx->H.c, key); + + if (is_endian.little) { + /* H is stored in host byte order */ +#ifdef BSWAP8 + ctx->H.u[0] = BSWAP8(ctx->H.u[0]); + ctx->H.u[1] = BSWAP8(ctx->H.u[1]); +#else + u8 *p = ctx->H.c; + u64 hi, lo; + hi = (u64)GETU32(p) << 32 | GETU32(p + 4); + lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); + ctx->H.u[0] = hi; + ctx->H.u[1] = lo; +#endif + } +#if TABLE_BITS==8 + gcm_init_8bit(ctx->Htable, ctx->H.u); +#elif TABLE_BITS==4 +# if defined(GHASH_ASM_X86_OR_64) +# if !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2) + if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */ + OPENSSL_ia32cap_P[1] & (1 << 1)) { /* check PCLMULQDQ bit */ + if (((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */ + gcm_init_avx(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_avx; + ctx->ghash = gcm_ghash_avx; + } else { + gcm_init_clmul(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_clmul; + ctx->ghash = gcm_ghash_clmul; + } + return; + } +# endif + gcm_init_4bit(ctx->Htable, ctx->H.u); +# if defined(GHASH_ASM_X86) /* x86 only */ +# if defined(OPENSSL_IA32_SSE2) + if (OPENSSL_ia32cap_P[0] & (1 << 25)) { /* check SSE bit */ +# else + if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */ +# endif + ctx->gmult = gcm_gmult_4bit_mmx; + ctx->ghash = gcm_ghash_4bit_mmx; + } else { + ctx->gmult = gcm_gmult_4bit_x86; + ctx->ghash = gcm_ghash_4bit_x86; + } +# else + ctx->gmult = gcm_gmult_4bit; + ctx->ghash = gcm_ghash_4bit; +# endif +# elif defined(GHASH_ASM_ARM) +# ifdef PMULL_CAPABLE + if (PMULL_CAPABLE) { + gcm_init_v8(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_v8; + ctx->ghash = gcm_ghash_v8; + } else +# endif +# ifdef NEON_CAPABLE + if (NEON_CAPABLE) { + gcm_init_neon(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_neon; + ctx->ghash = gcm_ghash_neon; + } else +# endif + { + gcm_init_4bit(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_4bit; +# if defined(GHASH) + ctx->ghash = gcm_ghash_4bit; +# else + ctx->ghash = NULL; +# endif + } +# elif defined(GHASH_ASM_SPARC) + if (OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3) { + gcm_init_vis3(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_vis3; + ctx->ghash = gcm_ghash_vis3; + } else { + gcm_init_4bit(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_4bit; + ctx->ghash = gcm_ghash_4bit; + } +# elif defined(GHASH_ASM_PPC) + if (OPENSSL_ppccap_P & PPC_CRYPTO207) { + gcm_init_p8(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_p8; + ctx->ghash = gcm_ghash_p8; + } else { + gcm_init_4bit(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_4bit; +# if defined(GHASH) + ctx->ghash = gcm_ghash_4bit; +# else + ctx->ghash = NULL; +# endif + } +# else + gcm_init_4bit(ctx->Htable, ctx->H.u); +# endif +#endif +} + +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int ctr; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +#endif + + ctx->Yi.u[0] = 0; + ctx->Yi.u[1] = 0; + ctx->Xi.u[0] = 0; + ctx->Xi.u[1] = 0; + ctx->len.u[0] = 0; /* AAD length */ + ctx->len.u[1] = 0; /* message length */ + ctx->ares = 0; + ctx->mres = 0; + + if (len == 12) { + memcpy(ctx->Yi.c, iv, 12); + ctx->Yi.c[15] = 1; + ctr = 1; + } else { + size_t i; + u64 len0 = len; + + while (len >= 16) { + for (i = 0; i < 16; ++i) + ctx->Yi.c[i] ^= iv[i]; + GCM_MUL(ctx, Yi); + iv += 16; + len -= 16; + } + if (len) { + for (i = 0; i < len; ++i) + ctx->Yi.c[i] ^= iv[i]; + GCM_MUL(ctx, Yi); + } + len0 <<= 3; + if (is_endian.little) { +#ifdef BSWAP8 + ctx->Yi.u[1] ^= BSWAP8(len0); +#else + ctx->Yi.c[8] ^= (u8)(len0 >> 56); + ctx->Yi.c[9] ^= (u8)(len0 >> 48); + ctx->Yi.c[10] ^= (u8)(len0 >> 40); + ctx->Yi.c[11] ^= (u8)(len0 >> 32); + ctx->Yi.c[12] ^= (u8)(len0 >> 24); + ctx->Yi.c[13] ^= (u8)(len0 >> 16); + ctx->Yi.c[14] ^= (u8)(len0 >> 8); + ctx->Yi.c[15] ^= (u8)(len0); +#endif + } else + ctx->Yi.u[1] ^= len0; + + GCM_MUL(ctx, Yi); + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + } + + (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; +} + +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len) +{ + size_t i; + unsigned int n; + u64 alen = ctx->len.u[0]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + if (ctx->len.u[1]) + return -2; + + alen += len; + if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len)) + return -1; + ctx->len.u[0] = alen; + + n = ctx->ares; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(aad++); + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->ares = n; + return 0; + } + } +#ifdef GHASH + if ((i = (len & (size_t)-16))) { + GHASH(ctx, aad, i); + aad += i; + len -= i; + } +#else + while (len >= 16) { + for (i = 0; i < 16; ++i) + ctx->Xi.c[i] ^= aad[i]; + GCM_MUL(ctx, Xi); + aad += 16; + len -= 16; + } +#endif + if (len) { + n = (unsigned int)len; + for (i = 0; i < len; ++i) + ctx->Xi.c[i] ^= aad[i]; + } + + ctx->ares = n; + return 0; +} + +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + block128_f block = ctx->block; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + +#if 0 + n = (unsigned int)mlen % 16; /* alternative to ctx->mres */ +#endif + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to encrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + + n = ctx->mres; +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) + break; +# endif +# if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + while (j) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + out += 16; + in += 16; + j -= 16; + } + GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); + len -= GHASH_CHUNK; + } + if ((i = (len & (size_t)-16))) { + size_t j = i; + + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + out += 16; + in += 16; + len -= 16; + } + GHASH(ctx, out - j, j); + } +# else + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +# endif + if (len) { + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; + } while (0); + } +#endif + for (i = 0; i < len; ++i) { + if (n == 0) { + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + } + ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n]; + n = (n + 1) % 16; + if (n == 0) + GCM_MUL(ctx, Xi); + } + + ctx->mres = n; + return 0; +} + +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + block128_f block = ctx->block; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to decrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + + n = ctx->mres; +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + if (n) { + while (n && len) { + u8 c = *(in++); + *(out++) = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) + break; +# endif +# if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + GHASH(ctx, in, GHASH_CHUNK); + while (j) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + out += 16; + in += 16; + j -= 16; + } + len -= GHASH_CHUNK; + } + if ((i = (len & (size_t)-16))) { + GHASH(ctx, in, i); + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + out += 16; + in += 16; + len -= 16; + } + } +# else + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) { + size_t c = in[i]; + out[i] = c ^ ctx->EKi.t[i]; + ctx->Xi.t[i] ^= c; + } + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +# endif + if (len) { + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + while (len--) { + u8 c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; + } while (0); + } +#endif + for (i = 0; i < len; ++i) { + u8 c; + if (n == 0) { + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + } + c = in[i]; + out[i] = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + n = (n + 1) % 16; + if (n == 0) + GCM_MUL(ctx, Xi); + } + + ctx->mres = n; + return 0; +} + +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to encrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + + n = ctx->mres; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) + while (len >= GHASH_CHUNK) { + (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + GHASH(ctx, out, GHASH_CHUNK); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + if ((i = (len & (size_t)-16))) { + size_t j = i / 16; + + (*stream) (in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + in += i; + len -= i; +#if defined(GHASH) + GHASH(ctx, out, i); + out += i; +#else + while (j--) { + for (i = 0; i < 16; ++i) + ctx->Xi.c[i] ^= out[i]; + GCM_MUL(ctx, Xi); + out += 16; + } +#endif + } + if (len) { + (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; +} + +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to decrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + + n = ctx->mres; + if (n) { + while (n && len) { + u8 c = *(in++); + *(out++) = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) + while (len >= GHASH_CHUNK) { + GHASH(ctx, in, GHASH_CHUNK); + (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + if ((i = (len & (size_t)-16))) { + size_t j = i / 16; + +#if defined(GHASH) + GHASH(ctx, in, i); +#else + while (j--) { + size_t k; + for (k = 0; k < 16; ++k) + ctx->Xi.c[k] ^= in[k]; + GCM_MUL(ctx, Xi); + in += 16; + } + j = i / 16; + in -= i; +#endif + (*stream) (in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + out += i; + in += i; + len -= i; + } + if (len) { + (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + while (len--) { + u8 c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; +} + +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + u64 alen = ctx->len.u[0] << 3; + u64 clen = ctx->len.u[1] << 3; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +#endif + + if (ctx->mres || ctx->ares) + GCM_MUL(ctx, Xi); + + if (is_endian.little) { +#ifdef BSWAP8 + alen = BSWAP8(alen); + clen = BSWAP8(clen); +#else + u8 *p = ctx->len.c; + + ctx->len.u[0] = alen; + ctx->len.u[1] = clen; + + alen = (u64)GETU32(p) << 32 | GETU32(p + 4); + clen = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); +#endif + } + + ctx->Xi.u[0] ^= alen; + ctx->Xi.u[1] ^= clen; + GCM_MUL(ctx, Xi); + + ctx->Xi.u[0] ^= ctx->EK0.u[0]; + ctx->Xi.u[1] ^= ctx->EK0.u[1]; + + if (tag && len <= sizeof(ctx->Xi)) + return CRYPTO_memcmp(ctx->Xi.c, tag, len); + else + return -1; +} + +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) +{ + CRYPTO_gcm128_finish(ctx, NULL, 0); + memcpy(tag, ctx->Xi.c, + len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); +} + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) +{ + GCM128_CONTEXT *ret; + + if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT)))) + CRYPTO_gcm128_init(ret, key, block); + + return ret; +} + +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx) +{ + if (ctx) { + OPENSSL_cleanse(ctx, sizeof(*ctx)); + OPENSSL_free(ctx); + } +} + +#if defined(SELFTEST) +# include +# include "aes.h" + +/* Test Case 1 */ +static const u8 K1[16], *P1 = NULL, *A1 = NULL, IV1[12], *C1 = NULL; +static const u8 T1[] = { + 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a +}; + +/* Test Case 2 */ +# define K2 K1 +# define A2 A1 +# define IV2 IV1 +static const u8 P2[16]; +static const u8 C2[] = { + 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 +}; + +static const u8 T2[] = { + 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf +}; + +/* Test Case 3 */ +# define A3 A2 +static const u8 K3[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 +}; + +static const u8 P3[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 +}; + +static const u8 IV3[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 +}; + +static const u8 C3[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 +}; + +static const u8 T3[] = { + 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 +}; + +/* Test Case 4 */ +# define K4 K3 +# define IV4 IV3 +static const u8 P4[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 +}; + +static const u8 A4[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 +}; + +static const u8 C4[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 +}; + +static const u8 T4[] = { + 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 +}; + +/* Test Case 5 */ +# define K5 K4 +# define P5 P4 +# define A5 A4 +static const u8 IV5[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad +}; + +static const u8 C5[] = { + 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98 +}; + +static const u8 T5[] = { + 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb +}; + +/* Test Case 6 */ +# define K6 K5 +# define P6 P5 +# define A6 A5 +static const u8 IV6[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b +}; + +static const u8 C6[] = { + 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5 +}; + +static const u8 T6[] = { + 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 +}; + +/* Test Case 7 */ +static const u8 K7[24], *P7 = NULL, *A7 = NULL, IV7[12], *C7 = NULL; +static const u8 T7[] = { + 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 +}; + +/* Test Case 8 */ +# define K8 K7 +# define IV8 IV7 +# define A8 A7 +static const u8 P8[16]; +static const u8 C8[] = { + 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 +}; + +static const u8 T8[] = { + 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb +}; + +/* Test Case 9 */ +# define A9 A8 +static const u8 K9[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c +}; + +static const u8 P9[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 +}; + +static const u8 IV9[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 +}; + +static const u8 C9[] = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 +}; + +static const u8 T9[] = { + 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 +}; + +/* Test Case 10 */ +# define K10 K9 +# define IV10 IV9 +static const u8 P10[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 +}; + +static const u8 A10[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 +}; + +static const u8 C10[] = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10 +}; + +static const u8 T10[] = { + 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c +}; + +/* Test Case 11 */ +# define K11 K10 +# define P11 P10 +# define A11 A10 +static const u8 IV11[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad }; + +static const u8 C11[] = { + 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7 +}; + +static const u8 T11[] = { + 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, + 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 +}; + +/* Test Case 12 */ +# define K12 K11 +# define P12 P11 +# define A12 A11 +static const u8 IV12[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b +}; + +static const u8 C12[] = { + 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b +}; + +static const u8 T12[] = { + 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, + 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 +}; + +/* Test Case 13 */ +static const u8 K13[32], *P13 = NULL, *A13 = NULL, IV13[12], *C13 = NULL; +static const u8 T13[] = { + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b +}; + +/* Test Case 14 */ +# define K14 K13 +# define A14 A13 +static const u8 P14[16], IV14[12]; +static const u8 C14[] = { + 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 +}; + +static const u8 T14[] = { + 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 +}; + +/* Test Case 15 */ +# define A15 A14 +static const u8 K15[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 +}; + +static const u8 P15[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 +}; + +static const u8 IV15[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 +}; + +static const u8 C15[] = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad +}; + +static const u8 T15[] = { + 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c +}; + +/* Test Case 16 */ +# define K16 K15 +# define IV16 IV15 +static const u8 P16[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 +}; + +static const u8 A16[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 +}; + +static const u8 C16[] = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62 +}; + +static const u8 T16[] = { + 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b +}; + +/* Test Case 17 */ +# define K17 K16 +# define P17 P16 +# define A17 A16 +static const u8 IV17[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad }; + +static const u8 C17[] = { + 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f +}; + +static const u8 T17[] = { + 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, + 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 +}; + +/* Test Case 18 */ +# define K18 K17 +# define P18 P17 +# define A18 A17 +static const u8 IV18[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b +}; + +static const u8 C18[] = { + 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f +}; + +static const u8 T18[] = { + 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, + 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a +}; + +/* Test Case 19 */ +# define K19 K1 +# define P19 P1 +# define IV19 IV1 +# define C19 C1 +static const u8 A19[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad +}; + +static const u8 T19[] = { + 0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d, + 0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92 +}; + +/* Test Case 20 */ +# define K20 K1 +# define A20 A1 +/* this results in 0xff in counter LSB */ +static const u8 IV20[64] = { 0xff, 0xff, 0xff, 0xff }; + +static const u8 P20[288]; +static const u8 C20[] = { + 0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a, + 0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14, + 0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce, + 0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f, + 0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70, + 0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18, + 0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf, + 0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49, + 0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab, + 0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c, + 0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c, + 0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29, + 0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1, + 0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76, + 0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2, + 0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce, + 0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f, + 0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86, + 0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb, + 0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18, + 0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65, + 0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42, + 0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b, + 0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06, + 0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24, + 0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c, + 0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4, + 0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64, + 0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03, + 0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6, + 0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90, + 0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74, + 0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67, + 0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46, + 0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78, + 0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c +}; + +static const u8 T20[] = { + 0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a, + 0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f +}; + +# define TEST_CASE(n) do { \ + u8 out[sizeof(P##n)]; \ + AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key); \ + CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt); \ + CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \ + memset(out,0,sizeof(out)); \ + if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \ + if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out)); \ + if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \ + (C##n && memcmp(out,C##n,sizeof(out)))) \ + ret++, printf ("encrypt test#%d failed.\n",n); \ + CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \ + memset(out,0,sizeof(out)); \ + if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \ + if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out)); \ + if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \ + (P##n && memcmp(out,P##n,sizeof(out)))) \ + ret++, printf ("decrypt test#%d failed.\n",n); \ + } while(0) + +int main() +{ + GCM128_CONTEXT ctx; + AES_KEY key; + int ret = 0; + + TEST_CASE(1); + TEST_CASE(2); + TEST_CASE(3); + TEST_CASE(4); + TEST_CASE(5); + TEST_CASE(6); + TEST_CASE(7); + TEST_CASE(8); + TEST_CASE(9); + TEST_CASE(10); + TEST_CASE(11); + TEST_CASE(12); + TEST_CASE(13); + TEST_CASE(14); + TEST_CASE(15); + TEST_CASE(16); + TEST_CASE(17); + TEST_CASE(18); + TEST_CASE(19); + TEST_CASE(20); + +# ifdef OPENSSL_CPUID_OBJ + { + size_t start, stop, gcm_t, ctr_t, OPENSSL_rdtsc(); + union { + u64 u; + u8 c[1024]; + } buf; + int i; + + AES_set_encrypt_key(K1, sizeof(K1) * 8, &key); + CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt); + CRYPTO_gcm128_setiv(&ctx, IV1, sizeof(IV1)); + + CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf)); + start = OPENSSL_rdtsc(); + CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf)); + gcm_t = OPENSSL_rdtsc() - start; + + CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf), + &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres, + (block128_f) AES_encrypt); + start = OPENSSL_rdtsc(); + CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf), + &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres, + (block128_f) AES_encrypt); + ctr_t = OPENSSL_rdtsc() - start; + + printf("%.2f-%.2f=%.2f\n", + gcm_t / (double)sizeof(buf), + ctr_t / (double)sizeof(buf), + (gcm_t - ctr_t) / (double)sizeof(buf)); +# ifdef GHASH + { + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx.ghash; + + GHASH((&ctx), buf.c, sizeof(buf)); + start = OPENSSL_rdtsc(); + for (i = 0; i < 100; ++i) + GHASH((&ctx), buf.c, sizeof(buf)); + gcm_t = OPENSSL_rdtsc() - start; + printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i); + } +# endif + } +# endif + + return ret; +} +#endif diff --git a/Sources/COpenSSL/getenv.c b/Sources/COpenSSL/getenv.c new file mode 100644 index 00000000..53f1dfd4 --- /dev/null +++ b/Sources/COpenSSL/getenv.c @@ -0,0 +1,31 @@ +/* + * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include "cryptlib.h" + +char *ossl_safe_getenv(const char *name) +{ +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +# if __GLIBC_PREREQ(2, 17) +# define SECURE_GETENV + return secure_getenv(name); +# endif +#endif + +#ifndef SECURE_GETENV + if (OPENSSL_issetugid()) + return NULL; + return getenv(name); +#endif +} diff --git a/Sources/COpenSSL/gost2001.c b/Sources/COpenSSL/gost2001.c new file mode 100644 index 00000000..08a64a08 --- /dev/null +++ b/Sources/COpenSSL/gost2001.c @@ -0,0 +1,474 @@ +/********************************************************************** + * gost2001.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST R 34.10-2001 * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include "gost_lcl.h" +#include "gost_params.h" +#include +#include "rand.h" +#include "ecdsa.h" +#include "err.h" +#include "e_gost_err.h" +#ifdef DEBUG_SIGN +extern +void dump_signature(const char *message, const unsigned char *buffer, + size_t len); +void dump_dsa_sig(const char *message, DSA_SIG *sig); +#else + +# define dump_signature(a,b,c) +# define dump_dsa_sig(a,b) +#endif + +/* + * Fills EC_KEY structure hidden in the app_data field of DSA structure + * with parameter information, extracted from parameter array in + * params.c file. + * + * Also fils DSA->q field with copy of EC_GROUP order field to make + * DSA_size function work + */ +int fill_GOST2001_params(EC_KEY *eckey, int nid) +{ + R3410_2001_params *params = R3410_2001_paramset; + EC_GROUP *grp = NULL; + BIGNUM *p = NULL, *q = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL; + EC_POINT *P = NULL; + BN_CTX *ctx = BN_CTX_new(); + int ok = 0; + + if(!ctx) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + p = BN_CTX_get(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + if(!p || !a || !b || !x || !y || !q) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE); + goto err; + } + while (params->nid != NID_undef && params->nid != nid) + params++; + if (params->nid == NID_undef) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, + GOST_R_UNSUPPORTED_PARAMETER_SET); + goto err; + } + if(!BN_hex2bn(&p, params->p) + || !BN_hex2bn(&a, params->a) + || !BN_hex2bn(&b, params->b)) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, + ERR_R_INTERNAL_ERROR); + goto err; + } + + grp = EC_GROUP_new_curve_GFp(p, a, b, ctx); + if(!grp) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE); + goto err; + } + + P = EC_POINT_new(grp); + if(!P) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE); + goto err; + } + + if(!BN_hex2bn(&x, params->x) + || !BN_hex2bn(&y, params->y) + || !EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx) + || !BN_hex2bn(&q, params->q)) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_KEYS + fprintf(stderr, "Set params index %d oid %s\nq=", + (params - R3410_2001_paramset), OBJ_nid2sn(params->nid)); + BN_print_fp(stderr, q); + fprintf(stderr, "\n"); +#endif + + if(!EC_GROUP_set_generator(grp, P, q, NULL)) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR); + goto err; + } + EC_GROUP_set_curve_name(grp, params->nid); + if(!EC_KEY_set_group(eckey, grp)) { + GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR); + goto err; + } + ok = 1; + err: + if (P) EC_POINT_free(P); + if (grp) EC_GROUP_free(grp); + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +/* + * Computes gost2001 signature as DSA_SIG structure + * + * + */ +DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) +{ + DSA_SIG *newsig = NULL, *ret = NULL; + BIGNUM *md = hashsum2bn(dgst); + BIGNUM *order = NULL; + const EC_GROUP *group; + const BIGNUM *priv_key; + BIGNUM *r = NULL, *s = NULL, *X = NULL, *tmp = NULL, *tmp2 = NULL, *k = + NULL, *e = NULL; + EC_POINT *C = NULL; + BN_CTX *ctx = BN_CTX_new(); + if(!ctx || !md) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + BN_CTX_start(ctx); + OPENSSL_assert(dlen == 32); + newsig = DSA_SIG_new(); + if (!newsig) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, GOST_R_NO_MEMORY); + goto err; + } + group = EC_KEY_get0_group(eckey); + if(!group) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + order = BN_CTX_get(ctx); + if(!order || !EC_GROUP_get_order(group, order, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + priv_key = EC_KEY_get0_private_key(eckey); + if(!priv_key) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + e = BN_CTX_get(ctx); + if(!e || !BN_mod(e, md, order, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_SIGN + fprintf(stderr, "digest as bignum="); + BN_print_fp(stderr, md); + fprintf(stderr, "\ndigest mod q="); + BN_print_fp(stderr, e); + fprintf(stderr, "\n"); +#endif + if (BN_is_zero(e)) { + BN_one(e); + } + k = BN_CTX_get(ctx); + C = EC_POINT_new(group); + if(!k || !C) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + do { + do { + if (!BN_rand_range(k, order)) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, + GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + goto err; + } + if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); + goto err; + } + if (!X) + X = BN_CTX_get(ctx); + if (!r) + r = BN_CTX_get(ctx); + if (!X || !r) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); + goto err; + } + + if(!BN_nnmod(r, X, order, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + } + while (BN_is_zero(r)); + /* s = (r*priv_key+k*e) mod order */ + if (!tmp) + tmp = BN_CTX_get(ctx); + if (!tmp2) + tmp2 = BN_CTX_get(ctx); + if (!s) + s = BN_CTX_get(ctx); + if (!tmp || !tmp2 || !s) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + if(!BN_mod_mul(tmp, priv_key, r, order, ctx) + || !BN_mod_mul(tmp2, k, e, order, ctx) + || !BN_mod_add(s, tmp, tmp2, order, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); + goto err; + } + } + while (BN_is_zero(s)); + + newsig->s = BN_dup(s); + newsig->r = BN_dup(r); + if(!newsig->s || !newsig->r) { + GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + ret = newsig; + err: + if(ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (C) EC_POINT_free(C); + if (md) BN_free(md); + if (!ret && newsig) { + DSA_SIG_free(newsig); + } + return ret; +} + +/* + * Verifies gost 2001 signature + * + */ +int gost2001_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, EC_KEY *ec) +{ + BN_CTX *ctx = BN_CTX_new(); + const EC_GROUP *group = EC_KEY_get0_group(ec); + BIGNUM *order; + BIGNUM *md = NULL, *e = NULL, *R = NULL, *v = NULL, *z1 = NULL, *z2 = + NULL; + BIGNUM *X = NULL, *tmp = NULL; + EC_POINT *C = NULL; + const EC_POINT *pub_key = NULL; + int ok = 0; + + if(!ctx || !group) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + e = BN_CTX_get(ctx); + z1 = BN_CTX_get(ctx); + z2 = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + R = BN_CTX_get(ctx); + v = BN_CTX_get(ctx); + if(!order || !e || !z1 || !z2 || !tmp || !X || !R || !v) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + + pub_key = EC_KEY_get0_public_key(ec); + if(!pub_key || !EC_GROUP_get_order(group, order, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || + (BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, + GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + goto err; + + } + md = hashsum2bn(dgst); + + if(!md || !BN_mod(e, md, order, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_SIGN + fprintf(stderr, "digest as bignum: "); + BN_print_fp(stderr, md); + fprintf(stderr, "\ndigest mod q: "); + BN_print_fp(stderr, e); +#endif + if (BN_is_zero(e) && !BN_one(e)) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + v = BN_mod_inverse(v, e, order, ctx); + if(!v + || !BN_mod_mul(z1, sig->s, v, order, ctx) + || !BN_sub(tmp, order, sig->r) + || !BN_mod_mul(z2, tmp, v, order, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_SIGN + fprintf(stderr, "\nInverted digest value: "); + BN_print_fp(stderr, v); + fprintf(stderr, "\nz1: "); + BN_print_fp(stderr, z1); + fprintf(stderr, "\nz2: "); + BN_print_fp(stderr, z2); +#endif + C = EC_POINT_new(group); + if (!C) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + if(!BN_mod(R, X, order, ctx)) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifdef DEBUG_SIGN + fprintf(stderr, "\nX="); + BN_print_fp(stderr, X); + fprintf(stderr, "\nX mod q="); + BN_print_fp(stderr, R); + fprintf(stderr, "\n"); +#endif + if (BN_cmp(R, sig->r) != 0) { + GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); + } else { + ok = 1; + } + err: + if (C) EC_POINT_free(C); + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (md) BN_free(md); + return ok; +} + +/* + * Computes GOST R 34.10-2001 public key + * + * + */ +int gost2001_compute_public(EC_KEY *ec) +{ + const EC_GROUP *group = EC_KEY_get0_group(ec); + EC_POINT *pub_key = NULL; + const BIGNUM *priv_key = NULL; + BN_CTX *ctx = NULL; + int ok = 0; + + if (!group) { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, + GOST_R_KEY_IS_NOT_INITIALIZED); + return 0; + } + ctx = BN_CTX_new(); + if(!ctx) { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); + goto err; + } + BN_CTX_start(ctx); + if (!(priv_key = EC_KEY_get0_private_key(ec))) { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); + goto err; + } + + pub_key = EC_POINT_new(group); + if(!pub_key) { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); + goto err; + } + if (!EC_KEY_set_public_key(ec, pub_key)) { + GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); + goto err; + } + ok = 256; + err: + if (pub_key) EC_POINT_free(pub_key); + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +/* + * + * Generates GOST R 34.10-2001 keypair + * + * + */ +int gost2001_keygen(EC_KEY *ec) +{ + BIGNUM *order = BN_new(), *d = BN_new(); + const EC_GROUP *group = NULL; + + if (order == NULL || d == NULL) { + GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_MALLOC_FAILURE); + BN_free(d); + BN_free(order); + return 0; + } + + group = EC_KEY_get0_group(ec); + if(!group || !EC_GROUP_get_order(group, order, NULL)) { + GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR); + BN_free(d); + BN_free(order); + return 0; + } + + do { + if (!BN_rand_range(d, order)) { + GOSTerr(GOST_F_GOST2001_KEYGEN, + GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); + BN_free(d); + BN_free(order); + return 0; + } + } + while (BN_is_zero(d)); + + if(!EC_KEY_set_private_key(ec, d)) { + GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR); + BN_free(d); + BN_free(order); + return 0; + } + BN_free(d); + BN_free(order); + return gost2001_compute_public(ec); +} diff --git a/Sources/COpenSSL/gost2001_keyx.c b/Sources/COpenSSL/gost2001_keyx.c new file mode 100644 index 00000000..1aa8331e --- /dev/null +++ b/Sources/COpenSSL/gost2001_keyx.c @@ -0,0 +1,294 @@ +/********************************************************************** + * gost_keyx.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * VK0 34.10-2001 key exchange and GOST R 34.10-2001 * + * based PKCS7/SMIME support * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include "evp.h" +#include "rand.h" +#include +#include "objects.h" +#include "gost89.h" +#include "gosthash.h" +#include "e_gost_err.h" +#include "gost_keywrap.h" +#include "gost_lcl.h" +#include "gost2001_keyx.h" + +/* Implementation of CryptoPro VKO 34.10-2001 algorithm */ +static int VKO_compute_key(unsigned char *shared_key, size_t shared_key_size, + const EC_POINT *pub_key, EC_KEY *priv_key, + const unsigned char *ukm) +{ + unsigned char ukm_be[8], databuf[64], hashbuf[64]; + BIGNUM *UKM = NULL, *p = NULL, *order = NULL, *X = NULL, *Y = NULL; + const BIGNUM *key = EC_KEY_get0_private_key(priv_key); + EC_POINT *pnt = EC_POINT_new(EC_KEY_get0_group(priv_key)); + int i; + gost_hash_ctx hash_ctx; + BN_CTX *ctx = BN_CTX_new(); + + for (i = 0; i < 8; i++) { + ukm_be[7 - i] = ukm[i]; + } + BN_CTX_start(ctx); + UKM = getbnfrombuf(ukm_be, 8); + p = BN_CTX_get(ctx); + order = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + EC_GROUP_get_order(EC_KEY_get0_group(priv_key), order, ctx); + BN_mod_mul(p, key, UKM, order, ctx); + EC_POINT_mul(EC_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx); + EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key), + pnt, X, Y, ctx); + /* + * Serialize elliptic curve point same way as we do it when saving key + */ + store_bignum(Y, databuf, 32); + store_bignum(X, databuf + 32, 32); + /* And reverse byte order of whole buffer */ + for (i = 0; i < 64; i++) { + hashbuf[63 - i] = databuf[i]; + } + init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet); + start_hash(&hash_ctx); + hash_block(&hash_ctx, hashbuf, 64); + finish_hash(&hash_ctx, shared_key); + done_gost_hash_ctx(&hash_ctx); + BN_free(UKM); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(pnt); + return 32; +} + +/* + * EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001 + * algorithm + */ +int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + /* + * Public key of peer in the ctx field peerkey Our private key in the ctx + * pkey ukm is in the algorithm specific context data + */ + EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx); + EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + + if (!data->shared_ukm) { + GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET); + return 0; + } + + if (key == NULL) { + *keylen = 32; + return 32; + } + + *keylen = + VKO_compute_key(key, 32, + EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)), + (EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm); + return 1; +} + +/* + * EVP_PKEY_METHOD callback encrypt + * Implementation of GOST2001 key transport, cryptocom variation + */ +/* + * Generates ephemeral key based on pubk algorithm computes shared key using + * VKO and returns filled up GOST_KEY_TRANSPORT structure + */ + +/* + * EVP_PKEY_METHOD callback encrypt + * Implementation of GOST2001 key transport, cryptopo variation + */ + +int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, + size_t *out_len, const unsigned char *key, + size_t key_len) +{ + GOST_KEY_TRANSPORT *gkt = NULL; + EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); + const struct gost_cipher_info *param = get_encryption_params(NULL); + unsigned char ukm[8], shared_key[32], crypted_key[44]; + int ret = 0; + int key_is_ephemeral = 1; + gost_ctx cctx; + EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); + if (data->shared_ukm) { + memcpy(ukm, data->shared_ukm, 8); + } else if (out) { + + if (RAND_bytes(ukm, 8) <= 0) { + GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, + GOST_R_RANDOM_GENERATOR_FAILURE); + return 0; + } + } + /* Check for private key in the peer_key of context */ + if (sec_key) { + key_is_ephemeral = 0; + if (!gost_get0_priv_key(sec_key)) { + GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, + GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); + goto err; + } + } else { + key_is_ephemeral = 1; + if (out) { + sec_key = EVP_PKEY_new(); + if (sec_key == NULL) + goto err; + EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), EC_KEY_new()); + EVP_PKEY_copy_parameters(sec_key, pubk); + if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) { + goto err; + } + } + } + if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) + && param == gost_cipher_list) { + param = gost_cipher_list + 1; + } + if (out) { + VKO_compute_key(shared_key, 32, + EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)), + EVP_PKEY_get0(sec_key), ukm); + gost_init(&cctx, param->sblock); + keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key); + } + gkt = GOST_KEY_TRANSPORT_new(); + if (!gkt) { + goto err; + } + if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { + goto err; + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { + goto err; + } + if (!ASN1_OCTET_STRING_set + (gkt->key_info->encrypted_key, crypted_key + 8, 32)) { + goto err; + } + if (key_is_ephemeral) { + if (!X509_PUBKEY_set + (&gkt->key_agreement_info->ephem_key, out ? sec_key : pubk)) { + GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, + GOST_R_CANNOT_PACK_EPHEMERAL_KEY); + goto err; + } + } + ASN1_OBJECT_free(gkt->key_agreement_info->cipher); + gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); + if (key_is_ephemeral && sec_key) + EVP_PKEY_free(sec_key); + if (!key_is_ephemeral) { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) + <= 0) { + GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0) + ret = 1; + GOST_KEY_TRANSPORT_free(gkt); + return ret; + err: + if (key_is_ephemeral && sec_key) + EVP_PKEY_free(sec_key); + GOST_KEY_TRANSPORT_free(gkt); + return -1; +} + +/* + * EVP_PKEY_METHOD callback decrypt + * Implementation of GOST2001 key transport, cryptopo variation + */ +int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, + size_t *key_len, const unsigned char *in, + size_t in_len) +{ + const unsigned char *p = in; + EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); + GOST_KEY_TRANSPORT *gkt = NULL; + int ret = 0; + unsigned char wrappedKey[44]; + unsigned char sharedKey[32]; + gost_ctx ctx; + const struct gost_cipher_info *param = NULL; + EVP_PKEY *eph_key = NULL, *peerkey = NULL; + + if (!key) { + *key_len = 32; + return 1; + } + gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len); + if (!gkt) { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, + GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); + return -1; + } + + /* If key transport structure contains public key, use it */ + eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); + if (eph_key) { + if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, + GOST_R_INCOMPATIBLE_PEER_KEY); + goto err; + } + } else { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) + <= 0) { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + peerkey = EVP_PKEY_CTX_get0_peerkey(pctx); + if (!peerkey) { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_NO_PEER_KEY); + goto err; + } + + param = get_encryption_params(gkt->key_agreement_info->cipher); + if (!param) { + goto err; + } + + gost_init(&ctx, param->sblock); + OPENSSL_assert(gkt->key_agreement_info->eph_iv->length == 8); + memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8); + OPENSSL_assert(gkt->key_info->encrypted_key->length == 32); + memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); + OPENSSL_assert(gkt->key_info->imit->length == 4); + memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); + VKO_compute_key(sharedKey, 32, + EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)), + EVP_PKEY_get0(priv), wrappedKey); + if (!keyUnwrapCryptoPro(&ctx, sharedKey, wrappedKey, key)) { + GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, + GOST_R_ERROR_COMPUTING_SHARED_KEY); + goto err; + } + + ret = 1; + err: + if (eph_key) + EVP_PKEY_free(eph_key); + if (gkt) + GOST_KEY_TRANSPORT_free(gkt); + return ret; +} diff --git a/Sources/COpenSSL/gost2001_keyx.h b/Sources/COpenSSL/gost2001_keyx.h new file mode 100644 index 00000000..2d29113a --- /dev/null +++ b/Sources/COpenSSL/gost2001_keyx.h @@ -0,0 +1,10 @@ +GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk, + BIGNUM *eph_key, + const unsigned char *key, + size_t keylen, + unsigned char *ukm, + size_t ukm_len); + +int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv, + GOST_KEY_TRANSPORT * gkt, + unsigned char *key_buf, int key_buf_len); diff --git a/Sources/COpenSSL/gost89.c b/Sources/COpenSSL/gost89.c new file mode 100644 index 00000000..4ff4ddd7 --- /dev/null +++ b/Sources/COpenSSL/gost89.c @@ -0,0 +1,576 @@ +/********************************************************************** + * gost89.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST 28147-89 encryption algorithm * + * No OpenSSL libraries required to compile and use * + * this code * + **********************************************************************/ +#include +#include "gost89.h" +/*- + Substitution blocks from RFC 4357 + + Note: our implementation of gost 28147-89 algorithm + uses S-box matrix rotated 90 degrees counterclockwise, relative to + examples given in RFC. + + +*/ + +/* Substitution blocks from test examples for GOST R 34.11-94*/ +gost_subst_block GostR3411_94_TestParamSet = { + {0X1, 0XF, 0XD, 0X0, 0X5, 0X7, 0XA, 0X4, 0X9, 0X2, 0X3, 0XE, 0X6, 0XB, + 0X8, 0XC} + , + {0XD, 0XB, 0X4, 0X1, 0X3, 0XF, 0X5, 0X9, 0X0, 0XA, 0XE, 0X7, 0X6, 0X8, + 0X2, 0XC} + , + {0X4, 0XB, 0XA, 0X0, 0X7, 0X2, 0X1, 0XD, 0X3, 0X6, 0X8, 0X5, 0X9, 0XC, + 0XF, 0XE} + , + {0X6, 0XC, 0X7, 0X1, 0X5, 0XF, 0XD, 0X8, 0X4, 0XA, 0X9, 0XE, 0X0, 0X3, + 0XB, 0X2} + , + {0X7, 0XD, 0XA, 0X1, 0X0, 0X8, 0X9, 0XF, 0XE, 0X4, 0X6, 0XC, 0XB, 0X2, + 0X5, 0X3} + , + {0X5, 0X8, 0X1, 0XD, 0XA, 0X3, 0X4, 0X2, 0XE, 0XF, 0XC, 0X7, 0X6, 0X0, + 0X9, 0XB} + , + {0XE, 0XB, 0X4, 0XC, 0X6, 0XD, 0XF, 0XA, 0X2, 0X3, 0X8, 0X1, 0X0, 0X7, + 0X5, 0X9} + , + {0X4, 0XA, 0X9, 0X2, 0XD, 0X8, 0X0, 0XE, 0X6, 0XB, 0X1, 0XC, 0X7, 0XF, + 0X5, 0X3} +}; + +/* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */ +gost_subst_block GostR3411_94_CryptoProParamSet = { + {0x1, 0x3, 0xA, 0x9, 0x5, 0xB, 0x4, 0xF, 0x8, 0x6, 0x7, 0xE, 0xD, 0x0, + 0x2, 0xC} + , + {0xD, 0xE, 0x4, 0x1, 0x7, 0x0, 0x5, 0xA, 0x3, 0xC, 0x8, 0xF, 0x6, 0x2, + 0x9, 0xB} + , + {0x7, 0x6, 0x2, 0x4, 0xD, 0x9, 0xF, 0x0, 0xA, 0x1, 0x5, 0xB, 0x8, 0xE, + 0xC, 0x3} + , + {0x7, 0x6, 0x4, 0xB, 0x9, 0xC, 0x2, 0xA, 0x1, 0x8, 0x0, 0xE, 0xF, 0xD, + 0x3, 0x5} + , + {0x4, 0xA, 0x7, 0xC, 0x0, 0xF, 0x2, 0x8, 0xE, 0x1, 0x6, 0x5, 0xD, 0xB, + 0x9, 0x3} + , + {0x7, 0xF, 0xC, 0xE, 0x9, 0x4, 0x1, 0x0, 0x3, 0xB, 0x5, 0x2, 0x6, 0xA, + 0x8, 0xD} + , + {0x5, 0xF, 0x4, 0x0, 0x2, 0xD, 0xB, 0x9, 0x1, 0x7, 0x6, 0x3, 0xC, 0xE, + 0xA, 0x8} + , + {0xA, 0x4, 0x5, 0x6, 0x8, 0x1, 0x3, 0x7, 0xD, 0xC, 0xE, 0x0, 0x9, 0x2, + 0xB, 0xF} +}; + +/* Test paramset from GOST 28147 */ +gost_subst_block Gost28147_TestParamSet = { + {0xC, 0x6, 0x5, 0x2, 0xB, 0x0, 0x9, 0xD, 0x3, 0xE, 0x7, 0xA, 0xF, 0x4, + 0x1, 0x8} + , + {0x9, 0xB, 0xC, 0x0, 0x3, 0x6, 0x7, 0x5, 0x4, 0x8, 0xE, 0xF, 0x1, 0xA, + 0x2, 0xD} + , + {0x8, 0xF, 0x6, 0xB, 0x1, 0x9, 0xC, 0x5, 0xD, 0x3, 0x7, 0xA, 0x0, 0xE, + 0x2, 0x4} + , + {0x3, 0xE, 0x5, 0x9, 0x6, 0x8, 0x0, 0xD, 0xA, 0xB, 0x7, 0xC, 0x2, 0x1, + 0xF, 0x4} + , + {0xE, 0x9, 0xB, 0x2, 0x5, 0xF, 0x7, 0x1, 0x0, 0xD, 0xC, 0x6, 0xA, 0x4, + 0x3, 0x8} + , + {0xD, 0x8, 0xE, 0xC, 0x7, 0x3, 0x9, 0xA, 0x1, 0x5, 0x2, 0x4, 0x6, 0xF, + 0x0, 0xB} + , + {0xC, 0x9, 0xF, 0xE, 0x8, 0x1, 0x3, 0xA, 0x2, 0x7, 0x4, 0xD, 0x6, 0x0, + 0xB, 0x5} + , + {0x4, 0x2, 0xF, 0x5, 0x9, 0x1, 0x0, 0x8, 0xE, 0x3, 0xB, 0xC, 0xD, 0x7, + 0xA, 0x6} +}; + +/* 1.2.643.2.2.31.1 */ +gost_subst_block Gost28147_CryptoProParamSetA = { + {0xB, 0xA, 0xF, 0x5, 0x0, 0xC, 0xE, 0x8, 0x6, 0x2, 0x3, 0x9, 0x1, 0x7, + 0xD, 0x4} + , + {0x1, 0xD, 0x2, 0x9, 0x7, 0xA, 0x6, 0x0, 0x8, 0xC, 0x4, 0x5, 0xF, 0x3, + 0xB, 0xE} + , + {0x3, 0xA, 0xD, 0xC, 0x1, 0x2, 0x0, 0xB, 0x7, 0x5, 0x9, 0x4, 0x8, 0xF, + 0xE, 0x6} + , + {0xB, 0x5, 0x1, 0x9, 0x8, 0xD, 0xF, 0x0, 0xE, 0x4, 0x2, 0x3, 0xC, 0x7, + 0xA, 0x6} + , + {0xE, 0x7, 0xA, 0xC, 0xD, 0x1, 0x3, 0x9, 0x0, 0x2, 0xB, 0x4, 0xF, 0x8, + 0x5, 0x6} + , + {0xE, 0x4, 0x6, 0x2, 0xB, 0x3, 0xD, 0x8, 0xC, 0xF, 0x5, 0xA, 0x0, 0x7, + 0x1, 0x9} + , + {0x3, 0x7, 0xE, 0x9, 0x8, 0xA, 0xF, 0x0, 0x5, 0x2, 0x6, 0xC, 0xB, 0x4, + 0xD, 0x1} + , + {0x9, 0x6, 0x3, 0x2, 0x8, 0xB, 0x1, 0x7, 0xA, 0x4, 0xE, 0xF, 0xC, 0x0, + 0xD, 0x5} +}; + +/* 1.2.643.2.2.31.2 */ +gost_subst_block Gost28147_CryptoProParamSetB = { + {0x0, 0x4, 0xB, 0xE, 0x8, 0x3, 0x7, 0x1, 0xA, 0x2, 0x9, 0x6, 0xF, 0xD, + 0x5, 0xC} + , + {0x5, 0x2, 0xA, 0xB, 0x9, 0x1, 0xC, 0x3, 0x7, 0x4, 0xD, 0x0, 0x6, 0xF, + 0x8, 0xE} + , + {0x8, 0x3, 0x2, 0x6, 0x4, 0xD, 0xE, 0xB, 0xC, 0x1, 0x7, 0xF, 0xA, 0x0, + 0x9, 0x5} + , + {0x2, 0x7, 0xC, 0xF, 0x9, 0x5, 0xA, 0xB, 0x1, 0x4, 0x0, 0xD, 0x6, 0x8, + 0xE, 0x3} + , + {0x7, 0x5, 0x0, 0xD, 0xB, 0x6, 0x1, 0x2, 0x3, 0xA, 0xC, 0xF, 0x4, 0xE, + 0x9, 0x8} + , + {0xE, 0xC, 0x0, 0xA, 0x9, 0x2, 0xD, 0xB, 0x7, 0x5, 0x8, 0xF, 0x3, 0x6, + 0x1, 0x4} + , + {0x0, 0x1, 0x2, 0xA, 0x4, 0xD, 0x5, 0xC, 0x9, 0x7, 0x3, 0xF, 0xB, 0x8, + 0x6, 0xE} + , + {0x8, 0x4, 0xB, 0x1, 0x3, 0x5, 0x0, 0x9, 0x2, 0xE, 0xA, 0xC, 0xD, 0x6, + 0x7, 0xF} +}; + +/* 1.2.643.2.2.31.3 */ +gost_subst_block Gost28147_CryptoProParamSetC = { + {0x7, 0x4, 0x0, 0x5, 0xA, 0x2, 0xF, 0xE, 0xC, 0x6, 0x1, 0xB, 0xD, 0x9, + 0x3, 0x8} + , + {0xA, 0x9, 0x6, 0x8, 0xD, 0xE, 0x2, 0x0, 0xF, 0x3, 0x5, 0xB, 0x4, 0x1, + 0xC, 0x7} + , + {0xC, 0x9, 0xB, 0x1, 0x8, 0xE, 0x2, 0x4, 0x7, 0x3, 0x6, 0x5, 0xA, 0x0, + 0xF, 0xD} + , + {0x8, 0xD, 0xB, 0x0, 0x4, 0x5, 0x1, 0x2, 0x9, 0x3, 0xC, 0xE, 0x6, 0xF, + 0xA, 0x7} + , + {0x3, 0x6, 0x0, 0x1, 0x5, 0xD, 0xA, 0x8, 0xB, 0x2, 0x9, 0x7, 0xE, 0xF, + 0xC, 0x4} + , + {0x8, 0x2, 0x5, 0x0, 0x4, 0x9, 0xF, 0xA, 0x3, 0x7, 0xC, 0xD, 0x6, 0xE, + 0x1, 0xB} + , + {0x0, 0x1, 0x7, 0xD, 0xB, 0x4, 0x5, 0x2, 0x8, 0xE, 0xF, 0xC, 0x9, 0xA, + 0x6, 0x3} + , + {0x1, 0xB, 0xC, 0x2, 0x9, 0xD, 0x0, 0xF, 0x4, 0x5, 0x8, 0xE, 0xA, 0x7, + 0x6, 0x3} +}; + +/* 1.2.643.2.2.31.4 */ +gost_subst_block Gost28147_CryptoProParamSetD = { + {0x1, 0xA, 0x6, 0x8, 0xF, 0xB, 0x0, 0x4, 0xC, 0x3, 0x5, 0x9, 0x7, 0xD, + 0x2, 0xE} + , + {0x3, 0x0, 0x6, 0xF, 0x1, 0xE, 0x9, 0x2, 0xD, 0x8, 0xC, 0x4, 0xB, 0xA, + 0x5, 0x7} + , + {0x8, 0x0, 0xF, 0x3, 0x2, 0x5, 0xE, 0xB, 0x1, 0xA, 0x4, 0x7, 0xC, 0x9, + 0xD, 0x6} + , + {0x0, 0xC, 0x8, 0x9, 0xD, 0x2, 0xA, 0xB, 0x7, 0x3, 0x6, 0x5, 0x4, 0xE, + 0xF, 0x1} + , + {0x1, 0x5, 0xE, 0xC, 0xA, 0x7, 0x0, 0xD, 0x6, 0x2, 0xB, 0x4, 0x9, 0x3, + 0xF, 0x8} + , + {0x1, 0xC, 0xB, 0x0, 0xF, 0xE, 0x6, 0x5, 0xA, 0xD, 0x4, 0x8, 0x9, 0x3, + 0x7, 0x2} + , + {0xB, 0x6, 0x3, 0x4, 0xC, 0xF, 0xE, 0x2, 0x7, 0xD, 0x8, 0x0, 0x5, 0xA, + 0x9, 0x1} + , + {0xF, 0xC, 0x2, 0xA, 0x6, 0x4, 0x5, 0x0, 0x7, 0x9, 0xE, 0xD, 0x1, 0xB, + 0x8, 0x3} +}; + +const byte CryptoProKeyMeshingKey[] = { + 0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23, + 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4, + 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12, + 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B +}; + +/* Initialization of gost_ctx subst blocks*/ +static void kboxinit(gost_ctx * c, const gost_subst_block * b) +{ + int i; + + for (i = 0; i < 256; i++) { + c->k87[i] = (word32) (b->k8[i >> 4] << 4 | b->k7[i & 15]) << 24; + c->k65[i] = (b->k6[i >> 4] << 4 | b->k5[i & 15]) << 16; + c->k43[i] = (b->k4[i >> 4] << 4 | b->k3[i & 15]) << 8; + c->k21[i] = b->k2[i >> 4] << 4 | b->k1[i & 15]; + + } +} + +/* Part of GOST 28147 algorithm moved into separate function */ +static word32 f(gost_ctx * c, word32 x) +{ + x = c->k87[x >> 24 & 255] | c->k65[x >> 16 & 255] | + c->k43[x >> 8 & 255] | c->k21[x & 255]; + /* Rotate left 11 bits */ + return x << 11 | x >> (32 - 11); +} + +/* Low-level encryption routine - encrypts one 64 bit block*/ +void gostcrypt(gost_ctx * c, const byte * in, byte * out) +{ + register word32 n1, n2; /* As named in the GOST */ + n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24); + n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24); + /* Instead of swapping halves, swap names each round */ + + n2 ^= f(c, n1 + c->k[0]); + n1 ^= f(c, n2 + c->k[1]); + n2 ^= f(c, n1 + c->k[2]); + n1 ^= f(c, n2 + c->k[3]); + n2 ^= f(c, n1 + c->k[4]); + n1 ^= f(c, n2 + c->k[5]); + n2 ^= f(c, n1 + c->k[6]); + n1 ^= f(c, n2 + c->k[7]); + + n2 ^= f(c, n1 + c->k[0]); + n1 ^= f(c, n2 + c->k[1]); + n2 ^= f(c, n1 + c->k[2]); + n1 ^= f(c, n2 + c->k[3]); + n2 ^= f(c, n1 + c->k[4]); + n1 ^= f(c, n2 + c->k[5]); + n2 ^= f(c, n1 + c->k[6]); + n1 ^= f(c, n2 + c->k[7]); + + n2 ^= f(c, n1 + c->k[0]); + n1 ^= f(c, n2 + c->k[1]); + n2 ^= f(c, n1 + c->k[2]); + n1 ^= f(c, n2 + c->k[3]); + n2 ^= f(c, n1 + c->k[4]); + n1 ^= f(c, n2 + c->k[5]); + n2 ^= f(c, n1 + c->k[6]); + n1 ^= f(c, n2 + c->k[7]); + + n2 ^= f(c, n1 + c->k[7]); + n1 ^= f(c, n2 + c->k[6]); + n2 ^= f(c, n1 + c->k[5]); + n1 ^= f(c, n2 + c->k[4]); + n2 ^= f(c, n1 + c->k[3]); + n1 ^= f(c, n2 + c->k[2]); + n2 ^= f(c, n1 + c->k[1]); + n1 ^= f(c, n2 + c->k[0]); + + out[0] = (byte) (n2 & 0xff); + out[1] = (byte) ((n2 >> 8) & 0xff); + out[2] = (byte) ((n2 >> 16) & 0xff); + out[3] = (byte) (n2 >> 24); + out[4] = (byte) (n1 & 0xff); + out[5] = (byte) ((n1 >> 8) & 0xff); + out[6] = (byte) ((n1 >> 16) & 0xff); + out[7] = (byte) (n1 >> 24); +} + +/* Low-level decryption routine. Decrypts one 64-bit block */ +void gostdecrypt(gost_ctx * c, const byte * in, byte * out) +{ + register word32 n1, n2; /* As named in the GOST */ + n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24); + n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24); + + n2 ^= f(c, n1 + c->k[0]); + n1 ^= f(c, n2 + c->k[1]); + n2 ^= f(c, n1 + c->k[2]); + n1 ^= f(c, n2 + c->k[3]); + n2 ^= f(c, n1 + c->k[4]); + n1 ^= f(c, n2 + c->k[5]); + n2 ^= f(c, n1 + c->k[6]); + n1 ^= f(c, n2 + c->k[7]); + + n2 ^= f(c, n1 + c->k[7]); + n1 ^= f(c, n2 + c->k[6]); + n2 ^= f(c, n1 + c->k[5]); + n1 ^= f(c, n2 + c->k[4]); + n2 ^= f(c, n1 + c->k[3]); + n1 ^= f(c, n2 + c->k[2]); + n2 ^= f(c, n1 + c->k[1]); + n1 ^= f(c, n2 + c->k[0]); + + n2 ^= f(c, n1 + c->k[7]); + n1 ^= f(c, n2 + c->k[6]); + n2 ^= f(c, n1 + c->k[5]); + n1 ^= f(c, n2 + c->k[4]); + n2 ^= f(c, n1 + c->k[3]); + n1 ^= f(c, n2 + c->k[2]); + n2 ^= f(c, n1 + c->k[1]); + n1 ^= f(c, n2 + c->k[0]); + + n2 ^= f(c, n1 + c->k[7]); + n1 ^= f(c, n2 + c->k[6]); + n2 ^= f(c, n1 + c->k[5]); + n1 ^= f(c, n2 + c->k[4]); + n2 ^= f(c, n1 + c->k[3]); + n1 ^= f(c, n2 + c->k[2]); + n2 ^= f(c, n1 + c->k[1]); + n1 ^= f(c, n2 + c->k[0]); + + out[0] = (byte) (n2 & 0xff); + out[1] = (byte) ((n2 >> 8) & 0xff); + out[2] = (byte) ((n2 >> 16) & 0xff); + out[3] = (byte) (n2 >> 24); + out[4] = (byte) (n1 & 0xff); + out[5] = (byte) ((n1 >> 8) & 0xff); + out[6] = (byte) ((n1 >> 16) & 0xff); + out[7] = (byte) (n1 >> 24); +} + +/* Encrypts several blocks in ECB mode */ +void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks) +{ + int i; + for (i = 0; i < blocks; i++) { + gostcrypt(c, clear, cipher); + clear += 8; + cipher += 8; + } +} + +/* Decrypts several blocks in ECB mode */ +void gost_dec(gost_ctx * c, const byte * cipher, byte * clear, int blocks) +{ + int i; + for (i = 0; i < blocks; i++) { + gostdecrypt(c, cipher, clear); + clear += 8; + cipher += 8; + } +} + +/* Encrypts several full blocks in CFB mode using 8byte IV */ +void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear, + byte * cipher, int blocks) +{ + byte cur_iv[8]; + byte gamma[8]; + int i, j; + const byte *in; + byte *out; + memcpy(cur_iv, iv, 8); + for (i = 0, in = clear, out = cipher; i < blocks; i++, in += 8, out += 8) { + gostcrypt(ctx, cur_iv, gamma); + for (j = 0; j < 8; j++) { + cur_iv[j] = out[j] = in[j] ^ gamma[j]; + } + } +} + +/* Decrypts several full blocks in CFB mode using 8byte IV */ +void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher, + byte * clear, int blocks) +{ + byte cur_iv[8]; + byte gamma[8]; + int i, j; + const byte *in; + byte *out; + memcpy(cur_iv, iv, 8); + for (i = 0, in = cipher, out = clear; i < blocks; i++, in += 8, out += 8) { + gostcrypt(ctx, cur_iv, gamma); + for (j = 0; j < 8; j++) { + out[j] = (cur_iv[j] = in[j]) ^ gamma[j]; + } + } +} + +/* Encrypts one block using specified key */ +void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock, + byte * outblock) +{ + gost_key(c, key); + gostcrypt(c, inblock, outblock); +} + +/* Set 256 bit key into context */ +void gost_key(gost_ctx * c, const byte * k) +{ + int i, j; + for (i = 0, j = 0; i < 8; i++, j += 4) { + c->k[i] = + k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | ((word32) k[j + 3] << + 24); + } +} + +/* Retrieve 256-bit key from context */ +void gost_get_key(gost_ctx * c, byte * k) +{ + int i, j; + for (i = 0, j = 0; i < 8; i++, j += 4) { + k[j] = (byte) (c->k[i] & 0xFF); + k[j + 1] = (byte) ((c->k[i] >> 8) & 0xFF); + k[j + 2] = (byte) ((c->k[i] >> 16) & 0xFF); + k[j + 3] = (byte) ((c->k[i] >> 24) & 0xFF); + } +} + +/* Initalize context. Provides default value for subst_block */ +void gost_init(gost_ctx * c, const gost_subst_block * b) +{ + if (!b) { + b = &GostR3411_94_TestParamSet; + } + kboxinit(c, b); +} + +/* Cleans up key from context */ +void gost_destroy(gost_ctx * c) +{ + int i; + for (i = 0; i < 8; i++) + c->k[i] = 0; +} + +/* + * Compute GOST 28147 mac block Parameters gost_ctx *c - context initalized + * with substitution blocks and key buffer - 8-byte mac state buffer block + * 8-byte block to process. + */ +void mac_block(gost_ctx * c, byte * buffer, const byte * block) +{ + register word32 n1, n2; /* As named in the GOST */ + int i; + for (i = 0; i < 8; i++) { + buffer[i] ^= block[i]; + } + n1 = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | ((word32) + buffer[3] << 24); + n2 = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | ((word32) + buffer[7] << 24); + /* Instead of swapping halves, swap names each round */ + + n2 ^= f(c, n1 + c->k[0]); + n1 ^= f(c, n2 + c->k[1]); + n2 ^= f(c, n1 + c->k[2]); + n1 ^= f(c, n2 + c->k[3]); + n2 ^= f(c, n1 + c->k[4]); + n1 ^= f(c, n2 + c->k[5]); + n2 ^= f(c, n1 + c->k[6]); + n1 ^= f(c, n2 + c->k[7]); + + n2 ^= f(c, n1 + c->k[0]); + n1 ^= f(c, n2 + c->k[1]); + n2 ^= f(c, n1 + c->k[2]); + n1 ^= f(c, n2 + c->k[3]); + n2 ^= f(c, n1 + c->k[4]); + n1 ^= f(c, n2 + c->k[5]); + n2 ^= f(c, n1 + c->k[6]); + n1 ^= f(c, n2 + c->k[7]); + + buffer[0] = (byte) (n1 & 0xff); + buffer[1] = (byte) ((n1 >> 8) & 0xff); + buffer[2] = (byte) ((n1 >> 16) & 0xff); + buffer[3] = (byte) (n1 >> 24); + buffer[4] = (byte) (n2 & 0xff); + buffer[5] = (byte) ((n2 >> 8) & 0xff); + buffer[6] = (byte) ((n2 >> 16) & 0xff); + buffer[7] = (byte) (n2 >> 24); +} + +/* Get mac with specified number of bits from MAC state buffer */ +void get_mac(byte * buffer, int nbits, byte * out) +{ + int nbytes = nbits >> 3; + int rembits = nbits & 7; + int mask = rembits ? ((1 < rembits) - 1) : 0; + int i; + for (i = 0; i < nbytes; i++) + out[i] = buffer[i]; + if (rembits) + out[i] = buffer[i] & mask; +} + +/* + * Compute mac of specified length (in bits) from data. Context should be + * initialized with key and subst blocks + */ +int gost_mac(gost_ctx * ctx, int mac_len, const unsigned char *data, + unsigned int data_len, unsigned char *mac) +{ + byte buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + byte buf2[8]; + unsigned int i; + for (i = 0; i + 8 <= data_len; i += 8) + mac_block(ctx, buffer, data + i); + if (i < data_len) { + memset(buf2, 0, 8); + memcpy(buf2, data + i, data_len - i); + mac_block(ctx, buffer, buf2); + i += 8; + } + if (i == 8) { + memset(buf2, 0, 8); + mac_block(ctx, buffer, buf2); + } + get_mac(buffer, mac_len, mac); + return 1; +} + +/* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */ +int gost_mac_iv(gost_ctx * ctx, int mac_len, const unsigned char *iv, + const unsigned char *data, unsigned int data_len, + unsigned char *mac) +{ + byte buffer[8]; + byte buf2[8]; + unsigned int i; + memcpy(buffer, iv, 8); + for (i = 0; i + 8 <= data_len; i += 8) + mac_block(ctx, buffer, data + i); + if (i < data_len) { + memset(buf2, 0, 8); + memcpy(buf2, data + i, data_len - i); + mac_block(ctx, buffer, buf2); + i += 8; + } + if (i == 8) { + memset(buf2, 0, 8); + mac_block(ctx, buffer, buf2); + } + get_mac(buffer, mac_len, mac); + return 1; +} + +/* Implements key meshing algorithm by modifing ctx and IV in place */ +void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv) +{ + unsigned char newkey[32], newiv[8]; + /* Set static keymeshing key */ + /* "Decrypt" key with keymeshing key */ + gost_dec(ctx, CryptoProKeyMeshingKey, newkey, 4); + /* set new key */ + gost_key(ctx, newkey); + /* Encrypt iv with new key */ + gostcrypt(ctx, iv, newiv); + memcpy(iv, newiv, 8); +} diff --git a/Sources/COpenSSL/gost89.h b/Sources/COpenSSL/gost89.h new file mode 100644 index 00000000..e5b877f4 --- /dev/null +++ b/Sources/COpenSSL/gost89.h @@ -0,0 +1,98 @@ +/********************************************************************** + * gost89.h * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Declarations for GOST 28147-89 encryption algorithm * + * No OpenSSL libraries required to compile and use * + * this code * + **********************************************************************/ +#ifndef GOST89_H +# define GOST89_H + +/* Typedef for unsigned 32-bit integer */ +# if __LONG_MAX__ > 2147483647L +typedef unsigned int u4; +# else +typedef unsigned long u4; +# endif +/* Typedef for unsigned 8-bit integer */ +typedef unsigned char byte; + +/* Internal representation of GOST substitution blocks */ +typedef struct { + byte k8[16]; + byte k7[16]; + byte k6[16]; + byte k5[16]; + byte k4[16]; + byte k3[16]; + byte k2[16]; + byte k1[16]; +} gost_subst_block; + +/* Cipher context includes key and preprocessed substitution block */ +typedef struct { + u4 k[8]; + /* Constant s-boxes -- set up in gost_init(). */ + u4 k87[256], k65[256], k43[256], k21[256]; +} gost_ctx; +/* + * Note: encrypt and decrypt expect full blocks--padding blocks is caller's + * responsibility. All bulk encryption is done in ECB mode by these calls. + * Other modes may be added easily enough. + */ +/* Encrypt several full blocks in ECB mode */ +void gost_enc(gost_ctx * ctx, const byte * clear, byte * cipher, int blocks); +/* Decrypt several full blocks in ECB mode */ +void gost_dec(gost_ctx * ctx, const byte * cipher, byte * clear, int blocks); +/* Encrypts several full blocks in CFB mode using 8byte IV */ +void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear, + byte * cipher, int blocks); +/* Decrypts several full blocks in CFB mode using 8byte IV */ +void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher, + byte * clear, int blocks); + +/* Encrypt one block */ +void gostcrypt(gost_ctx * c, const byte * in, byte * out); +/* Decrypt one block */ +void gostdecrypt(gost_ctx * c, const byte * in, byte * out); +/* Set key into context */ +void gost_key(gost_ctx * ctx, const byte * key); +/* Get key from context */ +void gost_get_key(gost_ctx * ctx, byte * key); +/* Set S-blocks into context */ +void gost_init(gost_ctx * ctx, const gost_subst_block * subst_block); +/* Clean up context */ +void gost_destroy(gost_ctx * ctx); +/* Intermediate function used for calculate hash */ +void gost_enc_with_key(gost_ctx *, byte * key, byte * inblock, + byte * outblock); +/* Compute MAC of given length in bits from data */ +int gost_mac(gost_ctx * ctx, int hmac_len, const unsigned char *data, + unsigned int data_len, unsigned char *hmac); +/* + * Compute MAC of given length in bits from data, using non-zero 8-byte IV + * (non-standard, for use in CryptoPro key transport only + */ +int gost_mac_iv(gost_ctx * ctx, int hmac_len, const unsigned char *iv, + const unsigned char *data, unsigned int data_len, + unsigned char *hmac); +/* Perform one step of MAC calculation like gostcrypt */ +void mac_block(gost_ctx * c, byte * buffer, const byte * block); +/* Extracts MAC value from mac state buffer */ +void get_mac(byte * buffer, int nbits, byte * out); +/* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/ +void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv); +/* Parameter sets specified in RFC 4357 */ +extern gost_subst_block GostR3411_94_TestParamSet; +extern gost_subst_block GostR3411_94_CryptoProParamSet; +extern gost_subst_block Gost28147_TestParamSet; +extern gost_subst_block Gost28147_CryptoProParamSetA; +extern gost_subst_block Gost28147_CryptoProParamSetB; +extern gost_subst_block Gost28147_CryptoProParamSetC; +extern gost_subst_block Gost28147_CryptoProParamSetD; +extern const byte CryptoProKeyMeshingKey[]; +typedef unsigned int word32; + +#endif diff --git a/Sources/COpenSSL/gost94_keyx.c b/Sources/COpenSSL/gost94_keyx.c new file mode 100644 index 00000000..94e7f45e --- /dev/null +++ b/Sources/COpenSSL/gost94_keyx.c @@ -0,0 +1,282 @@ +/********************************************************************** + * gost94_keyx.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implements generation and parsing of GOST_KEY_TRANSPORT for * + * GOST R 34.10-94 algorithms * + * * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include "dh.h" +#include "rand.h" +#include "evp.h" +#include "objects.h" + +#include "gost89.h" +#include "gosthash.h" +#include "e_gost_err.h" +#include "gost_keywrap.h" +#include "gost_lcl.h" +/* Common functions for both 94 and 2001 key exchange schemes */ +/* + * Implementation of the Diffi-Hellman key agreement scheme based on GOST-94 + * keys + */ + +/* + * Computes Diffie-Hellman key and stores it into buffer in little-endian + * byte order as expected by both versions of GOST 94 algorithm + */ +static int compute_pair_key_le(unsigned char *pair_key, BIGNUM *pub_key, + DH *dh) +{ + unsigned char be_key[128]; + int i, key_size; + key_size = DH_compute_key(be_key, pub_key, dh); + if (!key_size) + return 0; + memset(pair_key, 0, 128); + for (i = 0; i < key_size; i++) { + pair_key[i] = be_key[key_size - 1 - i]; + } + return key_size; +} + +/* + * Computes 256 bit Key exchange key as specified in RFC 4357 + */ +static int make_cp_exchange_key(BIGNUM *priv_key, EVP_PKEY *pubk, + unsigned char *shared_key) +{ + unsigned char dh_key[128]; + int ret; + gost_hash_ctx hash_ctx; + DH *dh = DH_new(); + + if (!dh) + return 0; + memset(dh_key, 0, 128); + dh->g = BN_dup(pubk->pkey.dsa->g); + dh->p = BN_dup(pubk->pkey.dsa->p); + dh->priv_key = BN_dup(priv_key); + ret = + compute_pair_key_le(dh_key, ((DSA *)(EVP_PKEY_get0(pubk)))->pub_key, + dh); + DH_free(dh); + if (!ret) + return 0; + init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet); + start_hash(&hash_ctx); + hash_block(&hash_ctx, dh_key, 128); + finish_hash(&hash_ctx, shared_key); + done_gost_hash_ctx(&hash_ctx); + return 1; +} + +/* EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-94 */ + +int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) +{ + EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx); + EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx); + *keylen = 32; + if (key == NULL) + return 1; + + return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key); +} + +/* + * EVP_PKEY_METHOD callback encrypt for GOST R 34.10-94 cryptopro + * modification + */ + +int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *key, + size_t key_len) +{ + GOST_KEY_TRANSPORT *gkt = NULL; + unsigned char shared_key[32], ukm[8], crypted_key[44]; + const struct gost_cipher_info *param = get_encryption_params(NULL); + EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx); + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + gost_ctx cctx; + int key_is_ephemeral = 1; + int tmp_outlen; + EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx); + + /* Do not use vizir cipher parameters with cryptopro */ + if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) + && param == gost_cipher_list) { + param = gost_cipher_list + 1; + } + + if (mykey) { + /* If key already set, it is not ephemeral */ + key_is_ephemeral = 0; + if (!gost_get0_priv_key(mykey)) { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); + goto err; + } + } else { + /* Otherwise generate ephemeral key */ + key_is_ephemeral = 1; + if (out) { + mykey = EVP_PKEY_new(); + if (!mykey) + goto memerr; + EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk), DSA_new()); + EVP_PKEY_copy_parameters(mykey, pubk); + if (!gost_sign_keygen(EVP_PKEY_get0(mykey))) { + goto err; + } + } + } + if (out) + make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, shared_key); + if (data->shared_ukm) { + memcpy(ukm, data->shared_ukm, 8); + } else if (out) { + if (RAND_bytes(ukm, 8) <= 0) { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_RANDOM_GENERATOR_FAILURE); + goto err; + } + } + + if (out) { + gost_init(&cctx, param->sblock); + keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key); + } + gkt = GOST_KEY_TRANSPORT_new(); + if (!gkt) { + goto memerr; + } + if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { + goto memerr; + } + if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { + goto memerr; + } + if (!ASN1_OCTET_STRING_set + (gkt->key_info->encrypted_key, crypted_key + 8, 32)) { + goto memerr; + } + if (key_is_ephemeral) { + if (!X509_PUBKEY_set + (&gkt->key_agreement_info->ephem_key, out ? mykey : pubk)) { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_CANNOT_PACK_EPHEMERAL_KEY); + goto err; + } + if (out) + EVP_PKEY_free(mykey); + } + ASN1_OBJECT_free(gkt->key_agreement_info->cipher); + gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); + tmp_outlen = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL); + if (tmp_outlen <= 0) { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, + GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO); + goto err; + } + *outlen = tmp_outlen; + if (!key_is_ephemeral) { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= + 0) { + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + GOST_KEY_TRANSPORT_free(gkt); + return 1; + memerr: + if (key_is_ephemeral) { + EVP_PKEY_free(mykey); + } + GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_MALLOC_FAILURE); + err: + GOST_KEY_TRANSPORT_free(gkt); + return -1; +} + +/* + * EVP_PLEY_METHOD callback decrypt for GOST R 34.10-94 cryptopro + * modification + */ +int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *key_len, const unsigned char *in, + size_t in_len) +{ + const unsigned char *p = in; + GOST_KEY_TRANSPORT *gkt = NULL; + unsigned char wrappedKey[44]; + unsigned char sharedKey[32]; + gost_ctx cctx; + const struct gost_cipher_info *param = NULL; + EVP_PKEY *eph_key = NULL, *peerkey = NULL; + EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(ctx); + + if (!key) { + *key_len = 32; + return 1; + } + + gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len); + if (!gkt) { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, + GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); + return 0; + } + eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); + if (eph_key) { + if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0) { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, + GOST_R_INCOMPATIBLE_PEER_KEY); + goto err; + } + } else { + /* Set control "public key from client certificate used" */ + if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= + 0) { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, GOST_R_CTRL_CALL_FAILED); + goto err; + } + } + peerkey = EVP_PKEY_CTX_get0_peerkey(ctx); + if (!peerkey) { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, GOST_R_NO_PEER_KEY); + goto err; + } + + param = get_encryption_params(gkt->key_agreement_info->cipher); + if (!param) { + goto err; + } + + gost_init(&cctx, param->sblock); + OPENSSL_assert(gkt->key_agreement_info->eph_iv->length == 8); + memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8); + OPENSSL_assert(gkt->key_info->encrypted_key->length == 32); + memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); + OPENSSL_assert(gkt->key_info->imit->length == 4); + memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); + make_cp_exchange_key(gost_get0_priv_key(priv), peerkey, sharedKey); + if (!keyUnwrapCryptoPro(&cctx, sharedKey, wrappedKey, key)) { + GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, + GOST_R_ERROR_COMPUTING_SHARED_KEY); + goto err; + } + + EVP_PKEY_free(eph_key); + GOST_KEY_TRANSPORT_free(gkt); + return 1; + err: + EVP_PKEY_free(eph_key); + GOST_KEY_TRANSPORT_free(gkt); + return -1; +} diff --git a/Sources/COpenSSL/gost_.c b/Sources/COpenSSL/gost_.c new file mode 100644 index 00000000..a1f0cbb9 --- /dev/null +++ b/Sources/COpenSSL/gost_.c @@ -0,0 +1,3396 @@ +/********************************************************************** + * gost_ameth.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of RFC 4490/4491 ASN1 method * + * for OpenSSL * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include "crypto.h" +#include "err.h" +#include "engine.h" +#include "evp.h" +#include "asn1.h" +#ifndef OPENSSL_NO_CMS +# include "cms.h" +#endif +#include "gost_params.h" +#include "gost_lcl.h" +#include "e_gost_err.h" + +int gost94_nid_by_params(DSA *p) +{ + R3410_params *gost_params; + BIGNUM *q = BN_new(); + for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) { + BN_dec2bn(&q, gost_params->q); + if (!BN_cmp(q, p->q)) { + BN_free(q); + return gost_params->nid; + } + } + BN_free(q); + return NID_undef; +} + +static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) +{ + ASN1_STRING *params = ASN1_STRING_new(); + GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); + int pkey_param_nid = NID_undef; + + if (!params || !gkp) { + GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + params = NULL; + goto err; + } + switch (EVP_PKEY_base_id(key)) { + case NID_id_GostR3410_2001: + pkey_param_nid = + EC_GROUP_get_curve_name(EC_KEY_get0_group + (EVP_PKEY_get0((EVP_PKEY *)key))); + break; + case NID_id_GostR3410_94: + pkey_param_nid = + (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); + if (pkey_param_nid == NID_undef) { + GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, + GOST_R_INVALID_GOST94_PARMSET); + ASN1_STRING_free(params); + params = NULL; + goto err; + } + break; + } + gkp->key_params = OBJ_nid2obj(pkey_param_nid); + gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); + /* + * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); + */ + params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); + if (params->length <= 0) { + GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(params); + params = NULL; + goto err; + } + params->type = V_ASN1_SEQUENCE; + err: + GOST_KEY_PARAMS_free(gkp); + return params; +} + +/* + * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting + * NID and parameters + */ +static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) +{ + ASN1_OBJECT *palg_obj = NULL; + int ptype = V_ASN1_UNDEF; + int pkey_nid = NID_undef, param_nid = NID_undef; + void *_pval; + ASN1_STRING *pval = NULL; + const unsigned char *p; + GOST_KEY_PARAMS *gkp = NULL; + + X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); + pval = _pval; + if (ptype != V_ASN1_SEQUENCE) { + GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, + GOST_R_BAD_KEY_PARAMETERS_FORMAT); + return 0; + } + p = pval->data; + pkey_nid = OBJ_obj2nid(palg_obj); + + gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length); + if (!gkp) { + GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, + GOST_R_BAD_PKEY_PARAMETERS_FORMAT); + return 0; + } + param_nid = OBJ_obj2nid(gkp->key_params); + GOST_KEY_PARAMS_free(gkp); + if(!EVP_PKEY_set_type(pkey, pkey_nid)) { + GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR); + return 0; + } + switch (pkey_nid) { + case NID_id_GostR3410_94: + { + DSA *dsa = EVP_PKEY_get0(pkey); + if (!dsa) { + dsa = DSA_new(); + if (!EVP_PKEY_assign(pkey, pkey_nid, dsa)) + return 0; + } + if (!fill_GOST94_params(dsa, param_nid)) + return 0; + break; + } + case NID_id_GostR3410_2001: + { + EC_KEY *ec = EVP_PKEY_get0(pkey); + if (!ec) { + ec = EC_KEY_new(); + if (!EVP_PKEY_assign(pkey, pkey_nid, ec)) + return 0; + } + if (!fill_GOST2001_params(ec, param_nid)) + return 0; + } + } + + return 1; +} + +static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv) +{ + switch (EVP_PKEY_base_id(pkey)) { + case NID_id_GostR3410_94: + { + DSA *dsa = EVP_PKEY_get0(pkey); + if (!dsa) { + dsa = DSA_new(); + EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa); + } + dsa->priv_key = BN_dup(priv); + if (!EVP_PKEY_missing_parameters(pkey)) + gost94_compute_public(dsa); + break; + } + case NID_id_GostR3410_2001: + { + EC_KEY *ec = EVP_PKEY_get0(pkey); + if (!ec) { + ec = EC_KEY_new(); + EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec); + } + if (!EC_KEY_set_private_key(ec, priv)) + return 0; + if (!EVP_PKEY_missing_parameters(pkey)) + gost2001_compute_public(ec); + break; + } + } + return 1; +} + +BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) +{ + switch (EVP_PKEY_base_id(pkey)) { + case NID_id_GostR3410_94: + { + DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); + if (!dsa) { + return NULL; + } + if (!dsa->priv_key) + return NULL; + return dsa->priv_key; + break; + } + case NID_id_GostR3410_2001: + { + EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); + const BIGNUM *priv; + if (!ec) { + return NULL; + } + if (!(priv = EC_KEY_get0_private_key(ec))) + return NULL; + return (BIGNUM *)priv; + break; + } + } + return NULL; +} + +static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) { + X509_ALGOR *alg1 = NULL, *alg2 = NULL; + int nid = EVP_PKEY_base_id(pkey); + PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, + NULL, &alg1, &alg2); + X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), + V_ASN1_NULL, 0); + if (nid == NID_undef) { + return (-1); + } + X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) { + X509_ALGOR *alg1 = NULL, *alg2 = NULL; + int nid = EVP_PKEY_base_id(pkey); + CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, + NULL, NULL, &alg1, &alg2); + X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), + V_ASN1_NULL, 0); + if (nid == NID_undef) { + return (-1); + } + X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); + } + return 1; +#endif + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (arg1 == 0) { + X509_ALGOR *alg; + ASN1_STRING *params = encode_gost_algor_params(pkey); + if (!params) { + return -1; + } + PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); + X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), + V_ASN1_SEQUENCE, params); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (arg1 == 0) { + X509_ALGOR *alg = NULL; + ASN1_STRING *params = encode_gost_algor_params(pkey); + if (!params) { + return -1; + } + CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, + NULL, &alg); + X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, + params); + } + return 1; +#endif + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_id_GostR3411_94; + return 2; + } + + return -2; +} + +/* --------------------- free functions * ------------------------------*/ +static void pkey_free_gost94(EVP_PKEY *key) +{ + if (key->pkey.dsa) { + DSA_free(key->pkey.dsa); + } +} + +static void pkey_free_gost01(EVP_PKEY *key) +{ + if (key->pkey.ec) { + EC_KEY_free(key->pkey.ec); + } +} + +/* ------------------ private key functions -----------------------------*/ +static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) +{ + const unsigned char *pkey_buf = NULL, *p = NULL; + int priv_len = 0; + BIGNUM *pk_num = NULL; + int ret = 0; + X509_ALGOR *palg = NULL; + ASN1_OBJECT *palg_obj = NULL; + ASN1_INTEGER *priv_key = NULL; + + if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) + return 0; + p = pkey_buf; + if (!decode_gost_algor_params(pk, palg)) { + return 0; + } + if (V_ASN1_OCTET_STRING == *p) { + /* New format - Little endian octet string */ + unsigned char rev_buf[32]; + int i; + ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); + if (!s || s->length != 32) { + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); + return 0; + } + for (i = 0; i < 32; i++) { + rev_buf[31 - i] = s->data[i]; + } + ASN1_STRING_free(s); + pk_num = getbnfrombuf(rev_buf, 32); + } else { + priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); + if (!priv_key) + return 0; + ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); + ASN1_INTEGER_free(priv_key); + if (!ret) { + GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); + return 0; + } + } + + ret = gost_set_priv_key(pk, pk_num); + BN_free(pk_num); + return ret; +} + +/* ----------------------------------------------------------------------*/ +static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) +{ + ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); + ASN1_STRING *params = encode_gost_algor_params(pk); + unsigned char *priv_buf = NULL; + int priv_len; + + ASN1_INTEGER *asn1key = NULL; + if (!params) { + return 0; + } + asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL); + priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); + ASN1_INTEGER_free(asn1key); + return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, + priv_buf, priv_len); +} + +/* --------- printing keys --------------------------------*/ +static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx, int type) +{ + int param_nid = NID_undef; + + if (type == 2) { + BIGNUM *key; + + if (!BIO_indent(out, indent, 128)) + return 0; + BIO_printf(out, "Private key: "); + key = gost_get0_priv_key(pkey); + if (!key) + BIO_printf(out, ""); + else + BN_print(out, key); + BIO_printf(out, "\n"); + } + if (type >= 1) { + BIGNUM *pubkey; + + pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; + BIO_indent(out, indent, 128); + BIO_printf(out, "Public key: "); + BN_print(out, pubkey); + BIO_printf(out, "\n"); + } + + param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); + BIO_indent(out, indent, 128); + BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); + return 1; +} + +static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + return print_gost_94(out, pkey, indent, pctx, 0); +} + +static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + return print_gost_94(out, pkey, indent, pctx, 1); +} + +static int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + return print_gost_94(out, pkey, indent, pctx, 2); +} + +static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx, int type) +{ + int param_nid = NID_undef; + if (type == 2) { + BIGNUM *key; + + if (!BIO_indent(out, indent, 128)) + return 0; + BIO_printf(out, "Private key: "); + key = gost_get0_priv_key(pkey); + if (!key) + BIO_printf(out, "= 1) { + BN_CTX *ctx = BN_CTX_new(); + BIGNUM *X, *Y; + const EC_POINT *pubkey; + const EC_GROUP *group; + + if (!ctx) { + GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE); + return 0; + } + BN_CTX_start(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + pubkey = + EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); + group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); + if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { + GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB); + BN_CTX_free(ctx); + return 0; + } + if (!BIO_indent(out, indent, 128)) + return 0; + BIO_printf(out, "Public key:\n"); + if (!BIO_indent(out, indent + 3, 128)) + return 0; + BIO_printf(out, "X:"); + BN_print(out, X); + BIO_printf(out, "\n"); + BIO_indent(out, indent + 3, 128); + BIO_printf(out, "Y:"); + BN_print(out, Y); + BIO_printf(out, "\n"); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + param_nid = + EC_GROUP_get_curve_name(EC_KEY_get0_group + (EVP_PKEY_get0((EVP_PKEY *)pkey))); + if (!BIO_indent(out, indent, 128)) + return 0; + BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); + return 1; +} + +static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + return print_gost_01(out, pkey, indent, pctx, 0); +} + +static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + return print_gost_01(out, pkey, indent, pctx, 1); +} + +static int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) +{ + return print_gost_01(out, pkey, indent, pctx, 2); +} + +/* ---------------------------------------------------------------------*/ +static int param_missing_gost94(const EVP_PKEY *pk) +{ + const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); + if (!dsa) + return 1; + if (!dsa->q) + return 1; + return 0; +} + +static int param_missing_gost01(const EVP_PKEY *pk) +{ + const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); + if (!ec) + return 1; + if (!EC_KEY_get0_group(ec)) + return 1; + return 0; +} + +static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) +{ + const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); + DSA *dto = EVP_PKEY_get0(to); + if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { + GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS); + return 0; + } + if (!dfrom) { + GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING); + return 0; + } + if (!dto) { + dto = DSA_new(); + EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto); + } +#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); + COPYBIGNUM(dto, dfrom, p) + COPYBIGNUM(dto, dfrom, q) + COPYBIGNUM(dto, dfrom, g) + + if (dto->priv_key) + gost94_compute_public(dto); + return 1; +} + +static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) +{ + EC_KEY *eto = EVP_PKEY_get0(to); + const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); + if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { + GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); + return 0; + } + if (!efrom) { + GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); + return 0; + } + if (!eto) { + eto = EC_KEY_new(); + if(!eto) { + GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE); + return 0; + } + if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) { + GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); + return 0; + } + } + if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) { + GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); + return 0; + } + if (EC_KEY_get0_private_key(eto)) { + gost2001_compute_public(eto); + } + return 1; +} + +static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) +{ + const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); + const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); + if (!BN_cmp(da->q, db->q)) + return 1; + return 0; +} + +static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (EC_GROUP_get_curve_name + (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) == + EC_GROUP_get_curve_name(EC_KEY_get0_group + (EVP_PKEY_get0((EVP_PKEY *)b)))) { + return 1; + } + return 0; + +} + +/* ---------- Public key functions * --------------------------------------*/ +static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) +{ + X509_ALGOR *palg = NULL; + const unsigned char *pubkey_buf = NULL; + unsigned char *databuf; + ASN1_OBJECT *palgobj = NULL; + int pub_len, i, j; + DSA *dsa; + ASN1_OCTET_STRING *octet = NULL; + + if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) + return 0; + EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); + if (!decode_gost_algor_params(pk, palg)) + return 0; + octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); + if (!octet) { + GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); + return 0; + } + databuf = OPENSSL_malloc(octet->length); + if (databuf == NULL) { + GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { + databuf[j] = octet->data[i]; + } + dsa = EVP_PKEY_get0(pk); + dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL); + ASN1_OCTET_STRING_free(octet); + OPENSSL_free(databuf); + return 1; + +} + +static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) +{ + ASN1_OBJECT *algobj = NULL; + ASN1_OCTET_STRING *octet = NULL; + void *pval = NULL; + unsigned char *buf = NULL, *databuf, *sptr; + int i, j, data_len, ret = 0; + + int ptype = V_ASN1_UNDEF; + DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); + algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); + if (pk->save_parameters) { + ASN1_STRING *params = encode_gost_algor_params(pk); + pval = params; + ptype = V_ASN1_SEQUENCE; + } + data_len = BN_num_bytes(dsa->pub_key); + databuf = OPENSSL_malloc(data_len); + if (databuf == NULL) + return 0; + BN_bn2bin(dsa->pub_key, databuf); + octet = ASN1_OCTET_STRING_new(); + ASN1_STRING_set(octet, NULL, data_len); + sptr = ASN1_STRING_data(octet); + for (i = 0, j = data_len - 1; i < data_len; i++, j--) { + sptr[i] = databuf[j]; + } + OPENSSL_free(databuf); + ret = i2d_ASN1_OCTET_STRING(octet, &buf); + ASN1_BIT_STRING_free(octet); + if (ret < 0) + return 0; + return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); +} + +static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) +{ + X509_ALGOR *palg = NULL; + const unsigned char *pubkey_buf = NULL; + unsigned char *databuf; + ASN1_OBJECT *palgobj = NULL; + int pub_len, i, j; + EC_POINT *pub_key; + BIGNUM *X, *Y; + ASN1_OCTET_STRING *octet = NULL; + int len; + const EC_GROUP *group; + + if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) + return 0; + EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); + if (!decode_gost_algor_params(pk, palg)) + return 0; + group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); + octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); + if (!octet) { + GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); + return 0; + } + databuf = OPENSSL_malloc(octet->length); + if (databuf == NULL) { + GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { + databuf[j] = octet->data[i]; + } + len = octet->length / 2; + ASN1_OCTET_STRING_free(octet); + + Y = getbnfrombuf(databuf, len); + X = getbnfrombuf(databuf + len, len); + OPENSSL_free(databuf); + pub_key = EC_POINT_new(group); + if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) { + GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); + EC_POINT_free(pub_key); + BN_free(X); + BN_free(Y); + return 0; + } + BN_free(X); + BN_free(Y); + if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) { + GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); + EC_POINT_free(pub_key); + return 0; + } + EC_POINT_free(pub_key); + return 1; + +} + +static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) +{ + ASN1_OBJECT *algobj = NULL; + ASN1_OCTET_STRING *octet = NULL; + void *pval = NULL; + unsigned char *buf = NULL, *databuf, *sptr; + int i, j, data_len, ret = 0; + const EC_POINT *pub_key; + BIGNUM *X, *Y, *order; + const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); + int ptype = V_ASN1_UNDEF; + + algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); + if (pk->save_parameters) { + ASN1_STRING *params = encode_gost_algor_params(pk); + pval = params; + ptype = V_ASN1_SEQUENCE; + } + order = BN_new(); + EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); + pub_key = EC_KEY_get0_public_key(ec); + if (!pub_key) { + GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); + return 0; + } + X = BN_new(); + Y = BN_new(); + if(!X || !Y) { + GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); + if(X) BN_free(X); + if(Y) BN_free(Y); + BN_free(order); + return 0; + } + if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), + pub_key, X, Y, NULL)) { + GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); + BN_free(X); + BN_free(Y); + BN_free(order); + return 0; + } + data_len = 2 * BN_num_bytes(order); + BN_free(order); + databuf = OPENSSL_malloc(data_len); + if (databuf == NULL) { + GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); + return 0; + } + memset(databuf, 0, data_len); + + store_bignum(X, databuf + data_len / 2, data_len / 2); + store_bignum(Y, databuf, data_len / 2); + + BN_free(X); + BN_free(Y); + octet = ASN1_OCTET_STRING_new(); + ASN1_STRING_set(octet, NULL, data_len); + sptr = ASN1_STRING_data(octet); + for (i = 0, j = data_len - 1; i < data_len; i++, j--) { + sptr[i] = databuf[j]; + } + OPENSSL_free(databuf); + ret = i2d_ASN1_OCTET_STRING(octet, &buf); + ASN1_BIT_STRING_free(octet); + if (ret < 0) + return 0; + return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); +} + +static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) +{ + const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); + const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); + if (da && db && da->pub_key && db->pub_key + && !BN_cmp(da->pub_key, db->pub_key)) { + return 1; + } + return 0; +} + +static int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) +{ + const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); + const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); + const EC_POINT *ka, *kb; + int ret = 0; + if (!ea || !eb) + return 0; + ka = EC_KEY_get0_public_key(ea); + kb = EC_KEY_get0_public_key(eb); + if (!ka || !kb) + return 0; + ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); + return ret; +} + +static int pkey_size_gost(const EVP_PKEY *pk) +{ + return 64; +} + +static int pkey_bits_gost(const EVP_PKEY *pk) +{ + return 256; +} + +/* ---------------------- ASN1 METHOD for GOST MAC -------------------*/ +static void mackey_free_gost(EVP_PKEY *pk) +{ + if (pk->pkey.ptr) { + OPENSSL_free(pk->pkey.ptr); + } +} + +static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_id_Gost28147_89_MAC; + return 2; + } + return -2; +} + +static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); + return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); +} + +static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + int nid = + EC_GROUP_get_curve_name(EC_KEY_get0_group + (EVP_PKEY_get0((EVP_PKEY *)pkey))); + return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); +} + +static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, + int derlen) +{ + ASN1_OBJECT *obj = NULL; + DSA *dsa = EVP_PKEY_get0(pkey); + int nid; + if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { + return 0; + } + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + if (!dsa) { + dsa = DSA_new(); + if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) + return 0; + } + if (!fill_GOST94_params(dsa, nid)) + return 0; + return 1; +} + +static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, + int derlen) +{ + ASN1_OBJECT *obj = NULL; + int nid; + EC_KEY *ec = EVP_PKEY_get0(pkey); + if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { + return 0; + } + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + if (!ec) { + ec = EC_KEY_new(); + if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) + return 0; + } + if (!fill_GOST2001_params(ec, nid)) + return 0; + return 1; +} + +/* ----------------------------------------------------------------------*/ +int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, + const char *pemstr, const char *info) +{ + *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info); + if (!*ameth) + return 0; + switch (nid) { + case NID_id_GostR3410_94: + EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94); + EVP_PKEY_asn1_set_private(*ameth, + priv_decode_gost, priv_encode_gost, + priv_print_gost94); + + EVP_PKEY_asn1_set_param(*ameth, + gost94_param_decode, gost94_param_encode, + param_missing_gost94, param_copy_gost94, + param_cmp_gost94, param_print_gost94); + EVP_PKEY_asn1_set_public(*ameth, + pub_decode_gost94, pub_encode_gost94, + pub_cmp_gost94, pub_print_gost94, + pkey_size_gost, pkey_bits_gost); + + EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); + break; + case NID_id_GostR3410_2001: + EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01); + EVP_PKEY_asn1_set_private(*ameth, + priv_decode_gost, priv_encode_gost, + priv_print_gost01); + + EVP_PKEY_asn1_set_param(*ameth, + gost2001_param_decode, gost2001_param_encode, + param_missing_gost01, param_copy_gost01, + param_cmp_gost01, param_print_gost01); + EVP_PKEY_asn1_set_public(*ameth, + pub_decode_gost01, pub_encode_gost01, + pub_cmp_gost01, pub_print_gost01, + pkey_size_gost, pkey_bits_gost); + + EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); + break; + case NID_id_Gost28147_89_MAC: + EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); + EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); + break; + } + return 1; +} +/********************************************************************** + * gost_keytrans.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * ASN1 structure definition for GOST key transport * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include "asn1t.h" +#include "x509.h" +// #include "gost_lcl.h" + +ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = { + ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO), + ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info, GOST_KEY_AGREEMENT_INFO, 0) +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_TRANSPORT) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) + +ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) = { + ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING), + ASN1_SIMPLE(GOST_KEY_INFO, imit, ASN1_OCTET_STRING) +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_INFO) + +ASN1_NDEF_SEQUENCE(GOST_KEY_AGREEMENT_INFO) = { + ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT), + ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0), + ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING) +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) + +ASN1_NDEF_SEQUENCE(GOST_KEY_PARAMS) = { + ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT), + ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT), + ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT), +} ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_PARAMS) + +ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) = { + ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING), + ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT), +} ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) + +ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) = { /* FIXME incomplete */ + ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT) +} + +ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS) +IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) +/********************************************************************** + * gost_crypt.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * OpenSSL interface to GOST 28147-89 cipher functions * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +#include "gost89.h" +#include "rand.h" +// #include "e_gost_err.h" +// #include "gost_lcl.h" + +#if !defined(CCGOST_DEBUG) && !defined(DEBUG) +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +/* Handles block of data in CFB mode */ +static int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +/* Handles block of data in CNT mode */ +static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +/* Cleanup function */ +static int gost_cipher_cleanup(EVP_CIPHER_CTX *); +/* set/get cipher parameters */ +static int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params); +static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params); +/* Control function */ +static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); + +EVP_CIPHER cipher_gost = { + NID_id_Gost28147_89, + 1, /* block_size */ + 32, /* key_size */ + 8, /* iv_len */ + EVP_CIPH_CFB_MODE | EVP_CIPH_NO_PADDING | + EVP_CIPH_CUSTOM_IV | EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, + gost_cipher_init, + gost_cipher_do_cfb, + gost_cipher_cleanup, + sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ + gost89_set_asn1_parameters, + gost89_get_asn1_parameters, + gost_cipher_ctl, + NULL, +}; + +EVP_CIPHER cipher_gost_cpacnt = { + NID_gost89_cnt, + 1, /* block_size */ + 32, /* key_size */ + 8, /* iv_len */ + EVP_CIPH_OFB_MODE | EVP_CIPH_NO_PADDING | + EVP_CIPH_CUSTOM_IV | EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, + gost_cipher_init_cpa, + gost_cipher_do_cnt, + gost_cipher_cleanup, + sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ + gost89_set_asn1_parameters, + gost89_get_asn1_parameters, + gost_cipher_ctl, + NULL, +}; + +/* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */ +/* Init functions which set specific parameters */ +static int gost_imit_init_cpa(EVP_MD_CTX *ctx); +/* process block of data */ +static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count); +/* Return computed value */ +static int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md); +/* Copies context */ +static int gost_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); +static int gost_imit_cleanup(EVP_MD_CTX *ctx); +/* Control function, knows how to set MAC key.*/ +static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr); + +EVP_MD imit_gost_cpa = { + NID_id_Gost28147_89_MAC, + NID_undef, + 4, + 0, + gost_imit_init_cpa, + gost_imit_update, + gost_imit_final, + gost_imit_copy, + gost_imit_cleanup, + NULL, + NULL, + {0, 0, 0, 0, 0}, + 8, + sizeof(struct ossl_gost_imit_ctx), + gost_imit_ctrl +}; + +/* + * Correspondence between gost parameter OIDs and substitution blocks + * NID field is filed by register_gost_NID function in engine.c + * upon engine initialization + */ + +struct gost_cipher_info gost_cipher_list[] = { + /*- NID *//* + * Subst block + *//* + * Key meshing + */ + /* + * {NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0}, + */ + {NID_id_Gost28147_89_cc, &GostR3411_94_CryptoProParamSet, 0}, + {NID_id_Gost28147_89_CryptoPro_A_ParamSet, &Gost28147_CryptoProParamSetA, + 1}, + {NID_id_Gost28147_89_CryptoPro_B_ParamSet, &Gost28147_CryptoProParamSetB, + 1}, + {NID_id_Gost28147_89_CryptoPro_C_ParamSet, &Gost28147_CryptoProParamSetC, + 1}, + {NID_id_Gost28147_89_CryptoPro_D_ParamSet, &Gost28147_CryptoProParamSetD, + 1}, + {NID_id_Gost28147_89_TestParamSet, &Gost28147_TestParamSet, 1}, + {NID_undef, NULL, 0} +}; + +/* + * get encryption parameters from crypto network settings FIXME For now we + * use environment var CRYPT_PARAMS as place to store these settings. + * Actually, it is better to use engine control command, read from + * configuration file to set them + */ +const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj) +{ + int nid; + struct gost_cipher_info *param; + if (!obj) { + const char *params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS); + if (!params || !strlen(params)) + return &gost_cipher_list[1]; + + nid = OBJ_txt2nid(params); + if (nid == NID_undef) { + GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS, + GOST_R_INVALID_CIPHER_PARAM_OID); + return NULL; + } + } else { + nid = OBJ_obj2nid(obj); + } + for (param = gost_cipher_list; param->sblock != NULL && param->nid != nid; + param++) ; + if (!param->sblock) { + GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS, GOST_R_INVALID_CIPHER_PARAMS); + return NULL; + } + return param; +} + +/* Sets cipher param from paramset NID. */ +static int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c, int nid) +{ + const struct gost_cipher_info *param; + param = + get_encryption_params((nid == NID_undef ? NULL : OBJ_nid2obj(nid))); + if (!param) + return 0; + + c->paramNID = param->nid; + c->key_meshing = param->key_meshing; + c->count = 0; + gost_init(&(c->cctx), param->sblock); + return 1; +} + +/* Initializes EVP_CIPHER_CTX by paramset NID */ +static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc, + int paramNID, int mode) +{ + struct ossl_gost_cipher_ctx *c = ctx->cipher_data; + if (ctx->app_data == NULL) { + if (!gost_cipher_set_param(c, paramNID)) + return 0; + ctx->app_data = ctx->cipher_data; + } + if (key) + gost_key(&(c->cctx), key); + if (iv) + memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + return 1; +} + +static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + struct ossl_gost_cipher_ctx *c = ctx->cipher_data; + gost_init(&(c->cctx), &Gost28147_CryptoProParamSetA); + c->key_meshing = 1; + c->count = 0; + if (key) + gost_key(&(c->cctx), key); + if (iv) + memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + return 1; +} + +/* Initializes EVP_CIPHER_CTX with default values */ +int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + return gost_cipher_init_param(ctx, key, iv, enc, NID_undef, + EVP_CIPH_CFB_MODE); +} + +/* + * Wrapper around gostcrypt function from gost89.c which perform key meshing + * when nesseccary + */ +static void gost_crypt_mesh(void *ctx, unsigned char *iv, unsigned char *buf) +{ + struct ossl_gost_cipher_ctx *c = ctx; + assert(c->count % 8 == 0 && c->count <= 1024); + if (c->key_meshing && c->count == 1024) { + cryptopro_key_meshing(&(c->cctx), iv); + } + gostcrypt(&(c->cctx), iv, buf); + c->count = c->count % 1024 + 8; +} + +static void gost_cnt_next(void *ctx, unsigned char *iv, unsigned char *buf) +{ + struct ossl_gost_cipher_ctx *c = ctx; + word32 g, go; + unsigned char buf1[8]; + assert(c->count % 8 == 0 && c->count <= 1024); + if (c->key_meshing && c->count == 1024) { + cryptopro_key_meshing(&(c->cctx), iv); + } + if (c->count == 0) { + gostcrypt(&(c->cctx), iv, buf1); + } else { + memcpy(buf1, iv, 8); + } + g = buf1[0] | (buf1[1] << 8) | (buf1[2] << 16) | ((word32) buf1[3] << 24); + g += 0x01010101; + buf1[0] = (unsigned char)(g & 0xff); + buf1[1] = (unsigned char)((g >> 8) & 0xff); + buf1[2] = (unsigned char)((g >> 16) & 0xff); + buf1[3] = (unsigned char)((g >> 24) & 0xff); + g = buf1[4] | (buf1[5] << 8) | (buf1[6] << 16) | ((word32) buf1[7] << 24); + go = g; + g += 0x01010104; + if (go > g) /* overflow */ + g++; + buf1[4] = (unsigned char)(g & 0xff); + buf1[5] = (unsigned char)((g >> 8) & 0xff); + buf1[6] = (unsigned char)((g >> 16) & 0xff); + buf1[7] = (unsigned char)((g >> 24) & 0xff); + memcpy(iv, buf1, 8); + gostcrypt(&(c->cctx), buf1, buf); + c->count = c->count % 1024 + 8; +} + +/* GOST encryption in CFB mode */ +int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + const unsigned char *in_ptr = in; + unsigned char *out_ptr = out; + size_t i = 0; + size_t j = 0; +/* process partial block if any */ + if (ctx->num) { + for (j = ctx->num, i = 0; j < 8 && i < inl; + j++, i++, in_ptr++, out_ptr++) { + if (!ctx->encrypt) + ctx->buf[j + 8] = *in_ptr; + *out_ptr = ctx->buf[j] ^ (*in_ptr); + if (ctx->encrypt) + ctx->buf[j + 8] = *out_ptr; + } + if (j == 8) { + memcpy(ctx->iv, ctx->buf + 8, 8); + ctx->num = 0; + } else { + ctx->num = j; + return 1; + } + } + + for (; i + 8 < inl; i += 8, in_ptr += 8, out_ptr += 8) { + /* + * block cipher current iv + */ + gost_crypt_mesh(ctx->cipher_data, ctx->iv, ctx->buf); + /* + * xor next block of input text with it and output it + */ + /* + * output this block + */ + if (!ctx->encrypt) + memcpy(ctx->iv, in_ptr, 8); + for (j = 0; j < 8; j++) { + out_ptr[j] = ctx->buf[j] ^ in_ptr[j]; + } + /* Encrypt */ + /* Next iv is next block of cipher text */ + if (ctx->encrypt) + memcpy(ctx->iv, out_ptr, 8); + } +/* Process rest of buffer */ + if (i < inl) { + gost_crypt_mesh(ctx->cipher_data, ctx->iv, ctx->buf); + if (!ctx->encrypt) + memcpy(ctx->buf + 8, in_ptr, inl - i); + for (j = 0; i < inl; j++, i++) { + out_ptr[j] = ctx->buf[j] ^ in_ptr[j]; + } + ctx->num = j; + if (ctx->encrypt) + memcpy(ctx->buf + 8, out_ptr, j); + } else { + ctx->num = 0; + } + return 1; +} + +static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + const unsigned char *in_ptr = in; + unsigned char *out_ptr = out; + size_t i = 0; + size_t j; +/* process partial block if any */ + if (ctx->num) { + for (j = ctx->num, i = 0; j < 8 && i < inl; + j++, i++, in_ptr++, out_ptr++) { + *out_ptr = ctx->buf[j] ^ (*in_ptr); + } + if (j == 8) { + ctx->num = 0; + } else { + ctx->num = j; + return 1; + } + } + + for (; i + 8 < inl; i += 8, in_ptr += 8, out_ptr += 8) { + /* + * block cipher current iv + */ + /* Encrypt */ + gost_cnt_next(ctx->cipher_data, ctx->iv, ctx->buf); + /* + * xor next block of input text with it and output it + */ + /* + * output this block + */ + for (j = 0; j < 8; j++) { + out_ptr[j] = ctx->buf[j] ^ in_ptr[j]; + } + } +/* Process rest of buffer */ + if (i < inl) { + gost_cnt_next(ctx->cipher_data, ctx->iv, ctx->buf); + for (j = 0; i < inl; j++, i++) { + out_ptr[j] = ctx->buf[j] ^ in_ptr[j]; + } + ctx->num = j; + } else { + ctx->num = 0; + } + return 1; +} + +/* Cleaning up of EVP_CIPHER_CTX */ +int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) +{ + gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx); + ctx->app_data = NULL; + return 1; +} + +/* Control function for gost cipher */ +int gost_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + switch (type) { + case EVP_CTRL_RAND_KEY: + { + if (RAND_bytes((unsigned char *)ptr, ctx->key_len) <= 0) { + GOSTerr(GOST_F_GOST_CIPHER_CTL, + GOST_R_RANDOM_GENERATOR_ERROR); + return -1; + } + break; + } + case EVP_CTRL_PBE_PRF_NID: + if (ptr) { + *((int *)ptr) = NID_id_HMACGostR3411_94; + return 1; + } else { + return 0; + } + + default: + GOSTerr(GOST_F_GOST_CIPHER_CTL, + GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND); + return -1; + } + return 1; +} + +/* Set cipher parameters from ASN1 structure */ +int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) +{ + int len = 0; + unsigned char *buf = NULL; + unsigned char *p = NULL; + struct ossl_gost_cipher_ctx *c = ctx->cipher_data; + GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new(); + ASN1_OCTET_STRING *os = NULL; + if (!gcp) { + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len)) { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + ASN1_OBJECT_free(gcp->enc_param_set); + gcp->enc_param_set = OBJ_nid2obj(c->paramNID); + + len = i2d_GOST_CIPHER_PARAMS(gcp, NULL); + p = buf = (unsigned char *)OPENSSL_malloc(len); + if (!buf) { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + i2d_GOST_CIPHER_PARAMS(gcp, &p); + GOST_CIPHER_PARAMS_free(gcp); + + os = ASN1_OCTET_STRING_new(); + + if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) { + OPENSSL_free(buf); + GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); + return 0; + } + OPENSSL_free(buf); + + ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os); + return 1; +} + +/* Store parameters into ASN1 structure */ +int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) +{ + int ret = -1; + int len; + GOST_CIPHER_PARAMS *gcp = NULL; + unsigned char *p; + struct ossl_gost_cipher_ctx *c = ctx->cipher_data; + if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) { + return ret; + } + + p = params->value.sequence->data; + + gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p, + params->value.sequence->length); + + len = gcp->iv->length; + if (len != ctx->cipher->iv_len) { + GOST_CIPHER_PARAMS_free(gcp); + GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS, GOST_R_INVALID_IV_LENGTH); + return -1; + } + if (!gost_cipher_set_param(c, OBJ_obj2nid(gcp->enc_param_set))) { + GOST_CIPHER_PARAMS_free(gcp); + return -1; + } + memcpy(ctx->oiv, gcp->iv->data, len); + + GOST_CIPHER_PARAMS_free(gcp); + + return 1; +} + +int gost_imit_init_cpa(EVP_MD_CTX *ctx) +{ + struct ossl_gost_imit_ctx *c = ctx->md_data; + memset(c->buffer, 0, sizeof(c->buffer)); + memset(c->partial_block, 0, sizeof(c->partial_block)); + c->count = 0; + c->bytes_left = 0; + c->key_meshing = 1; + gost_init(&(c->cctx), &Gost28147_CryptoProParamSetA); + return 1; +} + +static void mac_block_mesh(struct ossl_gost_imit_ctx *c, + const unsigned char *data) +{ + unsigned char buffer[8]; + /* + * We are using local buffer for iv because CryptoPro doesn't interpret + * internal state of MAC algorithm as iv during keymeshing (but does + * initialize internal state from iv in key transport + */ + assert(c->count % 8 == 0 && c->count <= 1024); + if (c->key_meshing && c->count == 1024) { + cryptopro_key_meshing(&(c->cctx), buffer); + } + mac_block(&(c->cctx), c->buffer, data); + c->count = c->count % 1024 + 8; +} + +int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + struct ossl_gost_imit_ctx *c = ctx->md_data; + const unsigned char *p = data; + size_t bytes = count, i; + if (!(c->key_set)) { + GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET); + return 0; + } + if (c->bytes_left) { + for (i = c->bytes_left; i < 8 && bytes > 0; bytes--, i++, p++) { + c->partial_block[i] = *p; + } + if (i == 8) { + mac_block_mesh(c, c->partial_block); + } else { + c->bytes_left = i; + return 1; + } + } + while (bytes > 8) { + mac_block_mesh(c, p); + p += 8; + bytes -= 8; + } + if (bytes > 0) { + memcpy(c->partial_block, p, bytes); + } + c->bytes_left = bytes; + return 1; +} + +int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + struct ossl_gost_imit_ctx *c = ctx->md_data; + if (!c->key_set) { + GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET); + return 0; + } + if (c->count == 0 && c->bytes_left) { + unsigned char buffer[8]; + memset(buffer, 0, 8); + gost_imit_update(ctx, buffer, 8); + } + if (c->bytes_left) { + int i; + for (i = c->bytes_left; i < 8; i++) { + c->partial_block[i] = 0; + } + mac_block_mesh(c, c->partial_block); + } + get_mac(c->buffer, 32, md); + return 1; +} + +int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) +{ + switch (type) { + case EVP_MD_CTRL_KEY_LEN: + *((unsigned int *)(ptr)) = 32; + return 1; + case EVP_MD_CTRL_SET_KEY: + { + if (arg != 32) { + GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + + gost_key(&(((struct ossl_gost_imit_ctx *)(ctx->md_data))->cctx), + ptr); + ((struct ossl_gost_imit_ctx *)(ctx->md_data))->key_set = 1; + return 1; + + } + default: + return 0; + } +} + +int gost_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +{ + memcpy(to->md_data, from->md_data, sizeof(struct ossl_gost_imit_ctx)); + return 1; +} + +/* Clean up imit ctx */ +int gost_imit_cleanup(EVP_MD_CTX *ctx) +{ + memset(ctx->md_data, 0, sizeof(struct ossl_gost_imit_ctx)); + return 1; +} +/********************************************************************** + * gost_ctl.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of control commands for GOST engine * + * OpenSSL 0.9.9 libraries required * + **********************************************************************/ +#include +#include +// #include "crypto.h" +// #include "err.h" +// #include "engine.h" +#include "buffer.h" +// #include "gost_lcl.h" + +static char *gost_params[GOST_PARAM_MAX + 1] = { NULL }; +static const char *gost_envnames[] = { "CRYPT_PARAMS" }; + +const ENGINE_CMD_DEFN gost_cmds[] = { +/*- { GOST_CTRL_RNG, + "RNG", + "Type of random number generator to use", + ENGINE_CMD_FLAG_STRING + }, + { GOST_CTRL_RNG_PARAMS, + "RNG_PARAMS", + "Parameter for random number generator", + ENGINE_CMD_FLAG_STRING + }, +*/ {GOST_CTRL_CRYPT_PARAMS, + "CRYPT_PARAMS", + "OID of default GOST 28147-89 parameters", + ENGINE_CMD_FLAG_STRING}, + {0, NULL, NULL, 0} +}; + +void gost_param_free() +{ + int i; + for (i = 0; i <= GOST_PARAM_MAX; i++) + if (gost_params[i] != NULL) { + OPENSSL_free(gost_params[i]); + gost_params[i] = NULL; + } + +} + +int gost_control_func(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int param = cmd - ENGINE_CMD_BASE; + int ret = 0; + if (param < 0 || param > GOST_PARAM_MAX) + return -1; + ret = gost_set_default_param(param, p); + return ret; +} + +const char *get_gost_engine_param(int param) +{ + char *tmp; + if (param < 0 || param > GOST_PARAM_MAX) + return NULL; + if (gost_params[param] != NULL) { + return gost_params[param]; + } + tmp = getenv(gost_envnames[param]); + if (tmp) { + if (gost_params[param]) + OPENSSL_free(gost_params[param]); + gost_params[param] = BUF_strdup(tmp); + return gost_params[param]; + } + return NULL; +} + +int gost_set_default_param(int param, const char *value) +{ + const char *tmp; + if (param < 0 || param > GOST_PARAM_MAX) + return 0; + tmp = getenv(gost_envnames[param]); + /* + * if there is value in the environment, use it, else -passed string * + */ + if (!tmp) + tmp = value; + if (gost_params[param]) + OPENSSL_free(gost_params[param]); + gost_params[param] = BUF_strdup(tmp); + + return 1; +} +/********************************************************************** + * gost_eng.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Main file of GOST engine * + * for OpenSSL * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +// #include "crypto.h" +// #include "err.h" +// #include "evp.h" +// #include "engine.h" +#include "obj_mac.h" +// #include "e_gost_err.h" +// #include "gost_lcl.h" +static const char *engine_gost_id = "gost"; +static const char *engine_gost_name = + "Reference implementation of GOST engine"; + +/* Symmetric cipher and digest function registrar */ + +static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); + +static int gost_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int ind); + +static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, + const int **nids, int nid); + +static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, + const int **nids, int nid); + +static int gost_cipher_nids[] = { NID_id_Gost28147_89, NID_gost89_cnt, 0 }; + +static int gost_digest_nids[] = + { NID_id_GostR3411_94, NID_id_Gost28147_89_MAC, 0 }; + +static int gost_pkey_meth_nids[] = { NID_id_GostR3410_94, + NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0 +}; + +static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL, + *pmeth_GostR3410_2001 = NULL, *pmeth_Gost28147_MAC = NULL; + +static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL, + *ameth_GostR3410_2001 = NULL, *ameth_Gost28147_MAC = NULL; + +static int gost_engine_init(ENGINE *e) +{ + return 1; +} + +static int gost_engine_finish(ENGINE *e) +{ + return 1; +} + +static int gost_engine_destroy(ENGINE *e) +{ + gost_param_free(); + + pmeth_GostR3410_94 = NULL; + pmeth_GostR3410_2001 = NULL; + pmeth_Gost28147_MAC = NULL; + ameth_GostR3410_94 = NULL; + ameth_GostR3410_2001 = NULL; + ameth_Gost28147_MAC = NULL; + return 1; +} + +static int bind_gost(ENGINE *e, const char *id) +{ + int ret = 0; + if (id && strcmp(id, engine_gost_id)) + return 0; + if (ameth_GostR3410_94) { + printf("GOST engine already loaded\n"); + goto end; + } + + if (!ENGINE_set_id(e, engine_gost_id)) { + printf("ENGINE_set_id failed\n"); + goto end; + } + if (!ENGINE_set_name(e, engine_gost_name)) { + printf("ENGINE_set_name failed\n"); + goto end; + } + if (!ENGINE_set_digests(e, gost_digests)) { + printf("ENGINE_set_digests failed\n"); + goto end; + } + if (!ENGINE_set_ciphers(e, gost_ciphers)) { + printf("ENGINE_set_ciphers failed\n"); + goto end; + } + if (!ENGINE_set_pkey_meths(e, gost_pkey_meths)) { + printf("ENGINE_set_pkey_meths failed\n"); + goto end; + } + if (!ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) { + printf("ENGINE_set_pkey_asn1_meths failed\n"); + goto end; + } + /* Control function and commands */ + if (!ENGINE_set_cmd_defns(e, gost_cmds)) { + fprintf(stderr, "ENGINE_set_cmd_defns failed\n"); + goto end; + } + if (!ENGINE_set_ctrl_function(e, gost_control_func)) { + fprintf(stderr, "ENGINE_set_ctrl_func failed\n"); + goto end; + } + if (!ENGINE_set_destroy_function(e, gost_engine_destroy) + || !ENGINE_set_init_function(e, gost_engine_init) + || !ENGINE_set_finish_function(e, gost_engine_finish)) { + goto end; + } + + if (!register_ameth_gost + (NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", + "GOST R 34.10-94")) + goto end; + if (!register_ameth_gost + (NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", + "GOST R 34.10-2001")) + goto end; + if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC, + "GOST-MAC", "GOST 28147-89 MAC")) + goto end; + + if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) + goto end; + if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) + goto end; + if (!register_pmeth_gost + (NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0)) + goto end; + if (!ENGINE_register_ciphers(e) + || !ENGINE_register_digests(e) + || !ENGINE_register_pkey_meths(e) + /* These two actually should go in LIST_ADD command */ + || !EVP_add_cipher(&cipher_gost) + || !EVP_add_cipher(&cipher_gost_cpacnt) + || !EVP_add_digest(&digest_gost) + || !EVP_add_digest(&imit_gost_cpa) + ) { + goto end; + } + + ERR_load_GOST_strings(); + ret = 1; + end: + return ret; +} + +static int gost_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) +{ + int ok = 1; + if (!digest) { + *nids = gost_digest_nids; + return 2; + } + /* + * printf("Digest no %d requested\n",nid); + */ + if (nid == NID_id_GostR3411_94) { + *digest = &digest_gost; + } else if (nid == NID_id_Gost28147_89_MAC) { + *digest = &imit_gost_cpa; + } else { + ok = 0; + *digest = NULL; + } + return ok; +} + +static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) +{ + int ok = 1; + if (!cipher) { + *nids = gost_cipher_nids; + return 2; /* two ciphers are supported */ + } + + if (nid == NID_id_Gost28147_89) { + *cipher = &cipher_gost; + } else if (nid == NID_gost89_cnt) { + *cipher = &cipher_gost_cpacnt; + } else { + ok = 0; + *cipher = NULL; + } + return ok; +} + +static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, + const int **nids, int nid) +{ + if (!pmeth) { + *nids = gost_pkey_meth_nids; + return 3; + } + + switch (nid) { + case NID_id_GostR3410_94: + *pmeth = pmeth_GostR3410_94; + return 1; + case NID_id_GostR3410_2001: + *pmeth = pmeth_GostR3410_2001; + return 1; + case NID_id_Gost28147_89_MAC: + *pmeth = pmeth_Gost28147_MAC; + return 1; + default:; + } + + *pmeth = NULL; + return 0; +} + +static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, + const int **nids, int nid) +{ + if (!ameth) { + *nids = gost_pkey_meth_nids; + return 3; + } + switch (nid) { + case NID_id_GostR3410_94: + *ameth = ameth_GostR3410_94; + return 1; + case NID_id_GostR3410_2001: + *ameth = ameth_GostR3410_2001; + return 1; + case NID_id_Gost28147_89_MAC: + *ameth = ameth_Gost28147_MAC; + return 1; + + default:; + } + + *ameth = NULL; + return 0; +} + +#ifdef OPENSSL_NO_DYNAMIC_ENGINE +static ENGINE *engine_gost(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_gost(ret, engine_gost_id)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_gost(void) +{ + ENGINE *toadd; + if (pmeth_GostR3410_94) + return; + toadd = engine_gost(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +} +#else +IMPLEMENT_DYNAMIC_BIND_FN(bind_gost) +IMPLEMENT_DYNAMIC_CHECK_FN() +#endif +/********************************************************************** + * keywrap.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of CryptoPro key wrap algorithm, as defined in * + * RFC 4357 p 6.3 and 6.4 * + * Doesn't need OpenSSL * + **********************************************************************/ +#include +// #include "gost89.h" +#include "gost_keywrap.h" + +/*- + * Diversifies key using random UserKey Material + * Implements RFC 4357 p 6.5 key diversification algorithm + * + * inputKey - 32byte key to be diversified + * ukm - 8byte user key material + * outputKey - 32byte buffer to store diversified key + * + */ +void keyDiversifyCryptoPro(gost_ctx * ctx, const unsigned char *inputKey, + const unsigned char *ukm, unsigned char *outputKey) +{ + + u4 k, s1, s2; + int i, j, mask; + unsigned char S[8]; + memcpy(outputKey, inputKey, 32); + for (i = 0; i < 8; i++) { + /* Make array of integers from key */ + /* Compute IV S */ + s1 = 0, s2 = 0; + for (j = 0, mask = 1; j < 8; j++, mask <<= 1) { + k = ((u4) outputKey[4 * j]) | (outputKey[4 * j + 1] << 8) | + (outputKey[4 * j + 2] << 16) | (outputKey[4 * j + 3] << 24); + if (mask & ukm[i]) { + s1 += k; + } else { + s2 += k; + } + } + S[0] = (unsigned char)(s1 & 0xff); + S[1] = (unsigned char)((s1 >> 8) & 0xff); + S[2] = (unsigned char)((s1 >> 16) & 0xff); + S[3] = (unsigned char)((s1 >> 24) & 0xff); + S[4] = (unsigned char)(s2 & 0xff); + S[5] = (unsigned char)((s2 >> 8) & 0xff); + S[6] = (unsigned char)((s2 >> 16) & 0xff); + S[7] = (unsigned char)((s2 >> 24) & 0xff); + gost_key(ctx, outputKey); + gost_enc_cfb(ctx, S, outputKey, outputKey, 4); + } +} + +/*- + * Wraps key using RFC 4357 6.3 + * ctx - gost encryption context, initialized with some S-boxes + * keyExchangeKey (KEK) 32-byte (256-bit) shared key + * ukm - 8 byte (64 bit) user key material, + * sessionKey - 32-byte (256-bit) key to be wrapped + * wrappedKey - 44-byte buffer to store wrapped key + */ + +int keyWrapCryptoPro(gost_ctx * ctx, const unsigned char *keyExchangeKey, + const unsigned char *ukm, + const unsigned char *sessionKey, + unsigned char *wrappedKey) +{ + unsigned char kek_ukm[32]; + keyDiversifyCryptoPro(ctx, keyExchangeKey, ukm, kek_ukm); + gost_key(ctx, kek_ukm); + memcpy(wrappedKey, ukm, 8); + gost_enc(ctx, sessionKey, wrappedKey + 8, 4); + gost_mac_iv(ctx, 32, ukm, sessionKey, 32, wrappedKey + 40); + return 1; +} + +/*- + * Unwraps key using RFC 4357 6.4 + * ctx - gost encryption context, initialized with some S-boxes + * keyExchangeKey 32-byte shared key + * wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM, + * 32 byte encrypted key and 4 byte MAC + * + * sessionKEy - 32byte buffer to store sessionKey in + * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match + */ + +int keyUnwrapCryptoPro(gost_ctx * ctx, const unsigned char *keyExchangeKey, + const unsigned char *wrappedKey, + unsigned char *sessionKey) +{ + unsigned char kek_ukm[32], cek_mac[4]; + keyDiversifyCryptoPro(ctx, keyExchangeKey, wrappedKey + /* First 8 bytes of wrapped Key is ukm */ + , kek_ukm); + gost_key(ctx, kek_ukm); + gost_dec(ctx, wrappedKey + 8, sessionKey, 4); + gost_mac_iv(ctx, 32, wrappedKey, sessionKey, 32, cek_mac); + if (memcmp(cek_mac, wrappedKey + 40, 4)) { + return 0; + } + return 1; +} +/********************************************************************** + * md_gost.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * OpenSSL interface to GOST R 34.11-94 hash functions * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +// #include "gost_lcl.h" +#include "gosthash.h" +// #include "e_gost_err.h" + +/* implementation of GOST 34.11 hash function See gost_md.c*/ +static int gost_digest_init(EVP_MD_CTX *ctx); +static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, + size_t count); +static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md); +static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); +static int gost_digest_cleanup(EVP_MD_CTX *ctx); + +EVP_MD digest_gost = { + NID_id_GostR3411_94, + NID_undef, + 32, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE, + gost_digest_init, + gost_digest_update, + gost_digest_final, + gost_digest_copy, + gost_digest_cleanup, + NULL, + NULL, + {NID_undef, NID_undef, 0, 0, 0}, + 32, + sizeof(struct ossl_gost_digest_ctx), + NULL +}; + +int gost_digest_init(EVP_MD_CTX *ctx) +{ + struct ossl_gost_digest_ctx *c = ctx->md_data; + memset(&(c->dctx), 0, sizeof(gost_hash_ctx)); + gost_init(&(c->cctx), &GostR3411_94_CryptoProParamSet); + c->dctx.cipher_ctx = &(c->cctx); + return 1; +} + +int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return hash_block((gost_hash_ctx *) ctx->md_data, data, count); +} + +int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return finish_hash((gost_hash_ctx *) ctx->md_data, md); + +} + +int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +{ + struct ossl_gost_digest_ctx *md_ctx = to->md_data; + if (to->md_data && from->md_data) { + memcpy(to->md_data, from->md_data, + sizeof(struct ossl_gost_digest_ctx)); + md_ctx->dctx.cipher_ctx = &(md_ctx->cctx); + } + return 1; +} + +int gost_digest_cleanup(EVP_MD_CTX *ctx) +{ + if (ctx->md_data) + memset(ctx->md_data, 0, sizeof(struct ossl_gost_digest_ctx)); + return 1; +} +/********************************************************************** + * params.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Definitions of GOST R 34.10 parameter sets, defined in RFC 4357 * + * OpenSSL 0.9.9 libraries required to compile and use * + * this code * + **********************************************************************/ +// #include "gost_params.h" +#include "objects.h" +/* Parameters of GOST 34.10 */ + +R3410_params R3410_paramset[] = { +/* Paramset A */ + {NID_id_GostR3410_94_CryptoPro_A_ParamSet, + "100997906755055304772081815535925224869" + "8410825720534578748235158755771479905292727772441528526992987964833" + "5669968284202797289605274717317548059048560713474685214192868091256" + "1502802222185647539190902656116367847270145019066794290930185446216" + "3997308722217328898303231940973554032134009725883228768509467406639" + "62", + "127021248288932417465907042777176443525" + "7876535089165358128175072657050312609850984974231883334834011809259" + "9999512098893413065920561499672425412104927434935707492031276956145" + "1689224110579311248812610229678534638401693520013288995000362260684" + "2227508135323070045173416336850045410625869714168836867788425378203" + "83", + "683631961449557007844441656118272528951" + "02170888761442055095051287550314083023"} + , + {NID_id_GostR3410_94_CryptoPro_B_ParamSet, + "429418261486158041438734477379555023926" + "7234596860714306679811299408947123142002706038521669956384871995765" + "7284814898909770759462613437669456364882730370838934791080835932647" + "9767786019153434744009610342313166725786869204821949328786333602033" + "8479709268434224762105576023501613261478065276102850944540333865234" + "1", + "139454871199115825601409655107690713107" + "0417070599280317977580014543757653577229840941243685222882398330391" + "1468164807668823692122073732267216074074777170091113455043205380464" + "7694904686120113087816240740184800477047157336662926249423571248823" + "9685422217536601433914856808405203368594584948031873412885804895251" + "63", + "79885141663410976897627118935756323747307951916507639758300472692338873533959"} + , + {NID_id_GostR3410_94_CryptoPro_C_ParamSet, + "816552717970881016017893191415300348226" + "2544051353358162468249467681876621283478212884286545844013955142622" + "2087723485023722868022275009502224827866201744494021697716482008353" + "6398202298024892620480898699335508064332313529725332208819456895108" + "5155178100221003459370588291073071186553005962149936840737128710832" + "3", + "110624679233511963040518952417017040248" + "5862954819831383774196396298584395948970608956170224210628525560327" + "8638246716655439297654402921844747893079518669992827880792192992701" + "1428546551433875806377110443534293554066712653034996277099320715774" + "3542287621283671843703709141350171945045805050291770503634517804938" + "01", + "113468861199819350564868233378875198043" + "267947776488510997961231672532899549103"} + , + {NID_id_GostR3410_94_CryptoPro_D_ParamSet, + "756976611021707301782128757801610628085" + "5283803109571158829574281419208532589041660017017859858216341400371" + "4687551412794400562878935266630754392677014598582103365983119173924" + "4732511225464712252386803315902707727668715343476086350472025298282" + "7271461690125050616858238384366331089777463541013033926723743254833" + "7", + "905457649621929965904290958774625315611" + "3056083907389766971404812524422262512556054474620855996091570786713" + "5849550236741915584185990627801066465809510095784713989819413820871" + "5964648914493053407920737078890520482730623038837767710173664838239" + "8574828787891286471201460474326612697849693665518073864436497893214" + "9", + "108988435796353506912374591498972192620" + "190487557619582334771735390599299211593"} + , + + {NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, + "1335318132727206734338595199483190012179423759678474868994823595993" + "6964252873471246159040332773182141032801252925387191478859899310331" + "0567744136196364803064721377826656898686468463277710150809401182608" + "7702016153249904683329312949209127762411378780302243557466062839716" + "59376426832674269780880061631528163475887", + "14201174159756348119636828602231808974327613839524373876287257344192" + "74593935127189736311660784676003608489466235676257952827747192122419" + "29071046134208380636394084512691828894000571524625445295769349356752" + "72895683154177544176313938445719175509684710784659566254794231229333" + "8483924514339614727760681880609734239", + "91771529896554605945588149018382750217296858393520724172743325725474" + "374979801"} + , + {NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, + "8890864727828423151699995801875757891031463338652579140051973659" + "3048131440685857067369829407947744496306656291505503608252399443" + "7900272386749145996230867832228661977543992816745254823298629859" + "8753575466286051738837854736167685769017780335804511440773337196" + "2538423532919394477873664752824509986617878992443177", + "1028946126624994859676552074360530315217970499989304888248413244" + "8474923022758470167998871003604670704877377286176171227694098633" + "1539089568784129110109512690503345393869871295783467257264868341" + "7200196629860561193666752429682367397084815179752036423595736533" + "68957392061769855284593965042530895046088067160269433", + "9109671391802626916582318050603555673628769498182593088388796888" + "5281641595199"} + , + {NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, + "4430618464297584182473135030809859326863990650118941756995270074" + "8609973181426950235239623239110557450826919295792878938752101867" + "7047181623251027516953100431855964837602657827828194249605561893" + "6965865325513137194483136247773653468410118796740709840825496997" + "9375560722345106704721086025979309968763193072908334", + "1246996366993477513607147265794064436203408861395055989217248455" + "7299870737698999651480662364723992859320868822848751165438350943" + "3276647222625940615560580450040947211826027729977563540237169063" + "0448079715771649447778447000597419032457722226253269698374446528" + "35352729304393746106576383349151001715930924115499549", + "6787876137336591234380295020065682527118129468050147943114675429" + "4748422492761"} + , + + {NID_undef, NULL, NULL, NULL} +}; + +R3410_2001_params R3410_2001_paramset[] = { + /* default_cc_sign01_param 1.2.643.2.9.1.8.1 */ + {NID_id_GostR3410_2001_ParamSet_cc, + /* A */ + "C0000000000000000000000000000000000000000000000000000000000003c4", + /* B */ + "2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c", + /* P */ + "C0000000000000000000000000000000000000000000000000000000000003C7", + /* Q */ + "5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85", + /* X */ + "2", + /* Y */ + "a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"} + , + /* 1.2.643.2.2.35.0 */ + {NID_id_GostR3410_2001_TestParamSet, + "7", + "5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E", + "8000000000000000000000000000000000000000000000000000000000000431", + "8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3", + "2", + "08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8"} + , + /* + * 1.2.643.2.2.35.1 + */ + {NID_id_GostR3410_2001_CryptoPro_A_ParamSet, + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", + "a6", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", + "1", + "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"} + , + /* + * 1.2.643.2.2.35.2 + */ + {NID_id_GostR3410_2001_CryptoPro_B_ParamSet, + "8000000000000000000000000000000000000000000000000000000000000C96", + "3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B", + "8000000000000000000000000000000000000000000000000000000000000C99", + "800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F", + "1", + "3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC"} + , + /* + * 1.2.643.2.2.35.3 + */ + {NID_id_GostR3410_2001_CryptoPro_C_ParamSet, + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598", + "805a", + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B", + "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", + "0", + "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"} + , + /* + * 1.2.643.2.2.36.0 + */ + {NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", + "a6", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", + "1", + "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"} + , + /* + * 1.2.643.2.2.36.1 + */ + {NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598", + "805a", + "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B", + "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", + "0", + "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"} + , + {0, NULL, NULL, NULL, NULL, NULL, NULL} +}; +/********************************************************************** + * gost_pmeth.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of RFC 4357 (GOST R 34.10) Publick key method * + * for OpenSSL * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +// #include "evp.h" +// #include "objects.h" +#include "ec.h" +#include "x509v3.h" /* For string_to_hex */ +#include +#include +#include +// #include "gost_params.h" +// #include "gost_lcl.h" +// #include "e_gost_err.h" +/* -----init, cleanup, copy - uniform for all algs ---------------*/ +/* Allocates new gost_pmeth_data structure and assigns it as data */ +static int pkey_gost_init(EVP_PKEY_CTX *ctx) +{ + struct gost_pmeth_data *data; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + data = OPENSSL_malloc(sizeof(struct gost_pmeth_data)); + if (!data) + return 0; + memset(data, 0, sizeof(struct gost_pmeth_data)); + if (pkey && EVP_PKEY_get0(pkey)) { + switch (EVP_PKEY_base_id(pkey)) { + case NID_id_GostR3410_94: + data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey)); + break; + case NID_id_GostR3410_2001: + data->sign_param_nid = + EC_GROUP_get_curve_name(EC_KEY_get0_group + (EVP_PKEY_get0((EVP_PKEY *)pkey))); + break; + default: + return 0; + } + } + EVP_PKEY_CTX_set_data(ctx, data); + return 1; +} + +/* Copies contents of gost_pmeth_data structure */ +static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + struct gost_pmeth_data *dst_data, *src_data; + if (!pkey_gost_init(dst)) { + return 0; + } + src_data = EVP_PKEY_CTX_get_data(src); + dst_data = EVP_PKEY_CTX_get_data(dst); + *dst_data = *src_data; + if (src_data->shared_ukm) { + dst_data->shared_ukm = NULL; + } + return 1; +} + +/* Frees up gost_pmeth_data structure */ +static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx) +{ + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + if (data->shared_ukm) + OPENSSL_free(data->shared_ukm); + OPENSSL_free(data); +} + +/* --------------------- control functions ------------------------------*/ +static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + struct gost_pmeth_data *pctx = + (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx); + switch (type) { + case EVP_PKEY_CTRL_MD: + { + if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) { + GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); + return 0; + } + pctx->md = (EVP_MD *)p2; + return 1; + } + break; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = pctx->md; + return 1; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_DIGESTINIT: +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_ENCRYPT: + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_SIGN: +#endif + return 1; + + case EVP_PKEY_CTRL_GOST_PARAMSET: + pctx->sign_param_nid = (int)p1; + return 1; + case EVP_PKEY_CTRL_SET_IV: + pctx->shared_ukm = OPENSSL_malloc((int)p1); + if (pctx->shared_ukm == NULL) + return 0; + memcpy(pctx->shared_ukm, p2, (int)p1); + return 1; + case EVP_PKEY_CTRL_PEER_KEY: + if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ + return 1; + if (p1 == 2) /* TLS: peer key used? */ + return pctx->peer_key_used; + if (p1 == 3) /* TLS: peer key used! */ + return (pctx->peer_key_used = 1); + return -2; + } + return -2; +} + +static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + int param_nid = 0; + if (!strcmp(type, param_ctrl_string)) { + if (!value) { + return 0; + } + if (strlen(value) == 1) { + switch (toupper((unsigned char)value[0])) { + case 'A': + param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; + break; + case 'B': + param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet; + break; + case 'C': + param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet; + break; + case 'D': + param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet; + break; + default: + return 0; + break; + } + } else if ((strlen(value) == 2) + && (toupper((unsigned char)value[0]) == 'X')) { + switch (toupper((unsigned char)value[1])) { + case 'A': + param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet; + break; + case 'B': + param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet; + break; + case 'C': + param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet; + break; + default: + return 0; + break; + } + } else { + R3410_params *p = R3410_paramset; + param_nid = OBJ_txt2nid(value); + if (param_nid == NID_undef) { + return 0; + } + for (; p->nid != NID_undef; p++) { + if (p->nid == param_nid) + break; + } + if (p->nid == NID_undef) { + GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR, GOST_R_INVALID_PARAMSET); + return 0; + } + } + + return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, + param_nid, NULL); + } + return -2; +} + +static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + int param_nid = 0; + if (!strcmp(type, param_ctrl_string)) { + if (!value) { + return 0; + } + if (strlen(value) == 1) { + switch (toupper((unsigned char)value[0])) { + case 'A': + param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet; + break; + case 'B': + param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet; + break; + case 'C': + param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet; + break; + case '0': + param_nid = NID_id_GostR3410_2001_TestParamSet; + break; + default: + return 0; + break; + } + } else if ((strlen(value) == 2) + && (toupper((unsigned char)value[0]) == 'X')) { + switch (toupper((unsigned char)value[1])) { + case 'A': + param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet; + break; + case 'B': + param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet; + break; + default: + return 0; + break; + } + } else { + R3410_2001_params *p = R3410_2001_paramset; + param_nid = OBJ_txt2nid(value); + if (param_nid == NID_undef) { + return 0; + } + for (; p->nid != NID_undef; p++) { + if (p->nid == param_nid) + break; + } + if (p->nid == NID_undef) { + GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR, GOST_R_INVALID_PARAMSET); + return 0; + } + } + + return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, + param_nid, NULL); + } + return -2; +} + +/* --------------------- key generation --------------------------------*/ + +static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) +{ + return 1; +} + +static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + DSA *dsa = NULL; + if (data->sign_param_nid == NID_undef) { + GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN, GOST_R_NO_PARAMETERS_SET); + return 0; + } + dsa = DSA_new(); + if (!fill_GOST94_params(dsa, data->sign_param_nid)) { + DSA_free(dsa); + return 0; + } + EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa); + return 1; +} + +static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + EC_KEY *ec = NULL; + + if (data->sign_param_nid == NID_undef) { + GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); + return 0; + } + if (!ec) + ec = EC_KEY_new(); + if (!fill_GOST2001_params(ec, data->sign_param_nid)) { + EC_KEY_free(ec); + return 0; + } + EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec); + return 1; +} + +/* Generates Gost_R3410_94_cp key */ +static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DSA *dsa; + if (!pkey_gost94_paramgen(ctx, pkey)) + return 0; + dsa = EVP_PKEY_get0(pkey); + gost_sign_keygen(dsa); + return 1; +} + +/* Generates GOST_R3410 2001 key and assigns it using specified type */ +static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + EC_KEY *ec; + if (!pkey_gost01_paramgen(ctx, pkey)) + return 0; + ec = EVP_PKEY_get0(pkey); + gost2001_keygen(ec); + return 1; +} + +/* ----------- sign callbacks --------------------------------------*/ + +static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbs_len) +{ + DSA_SIG *unpacked_sig = NULL; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!siglen) + return 0; + if (!sig) { + *siglen = 64; /* better to check size of pkey->pkey.dsa-q */ + return 1; + } + unpacked_sig = gost_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey)); + if (!unpacked_sig) { + return 0; + } + return pack_sign_cp(unpacked_sig, 32, sig, siglen); +} + +static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbs_len) +{ + DSA_SIG *unpacked_sig = NULL; + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!siglen) + return 0; + if (!sig) { + *siglen = 64; /* better to check size of curve order */ + return 1; + } + unpacked_sig = gost2001_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey)); + if (!unpacked_sig) { + return 0; + } + return pack_sign_cp(unpacked_sig, 32, sig, siglen); +} + +/* ------------------- verify callbacks ---------------------------*/ + +static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbs_len) +{ + int ok = 0; + EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); + DSA_SIG *s = unpack_cp_signature(sig, siglen); + if (!s) + return 0; + if (pub_key) + ok = gost_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key)); + DSA_SIG_free(s); + return ok; +} + +static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbs_len) +{ + int ok = 0; + EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); + DSA_SIG *s = unpack_cp_signature(sig, siglen); + if (!s) + return 0; +#ifdef DEBUG_SIGN + fprintf(stderr, "R="); + BN_print_fp(stderr, s->r); + fprintf(stderr, "\nS="); + BN_print_fp(stderr, s->s); + fprintf(stderr, "\n"); +#endif + if (pub_key) + ok = gost2001_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key)); + DSA_SIG_free(s); + return ok; +} + +/* ------------- encrypt init -------------------------------------*/ +/* Generates ephermeral key */ +static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) +{ + return 1; +} + +/* --------------- Derive init ------------------------------------*/ +static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx) +{ + return 1; +} + +/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/ +static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) +{ + struct gost_mac_pmeth_data *data; + data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data)); + if (!data) + return 0; + memset(data, 0, sizeof(struct gost_mac_pmeth_data)); + EVP_PKEY_CTX_set_data(ctx, data); + return 1; +} + +static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx) +{ + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + OPENSSL_free(data); +} + +static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + struct gost_mac_pmeth_data *dst_data, *src_data; + if (!pkey_gost_mac_init(dst)) { + return 0; + } + src_data = EVP_PKEY_CTX_get_data(src); + dst_data = EVP_PKEY_CTX_get_data(dst); + *dst_data = *src_data; + return 1; +} + +static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + struct gost_mac_pmeth_data *data = + (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx); + + switch (type) { + case EVP_PKEY_CTRL_MD: + { + if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC) { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, + GOST_R_INVALID_DIGEST_TYPE); + return 0; + } + data->md = (EVP_MD *)p2; + return 1; + } + break; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = data->md; + return 1; + + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + return 1; + case EVP_PKEY_CTRL_SET_MAC_KEY: + if (p1 != 32) { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + + memcpy(data->key, p2, 32); + data->key_set = 1; + return 1; + case EVP_PKEY_CTRL_DIGESTINIT: + { + EVP_MD_CTX *mctx = p2; + void *key; + if (!data->key_set) { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); + if (!pkey) { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, + GOST_R_MAC_KEY_NOT_SET); + return 0; + } + key = EVP_PKEY_get0(pkey); + if (!key) { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, + GOST_R_MAC_KEY_NOT_SET); + return 0; + } + } else { + key = &(data->key); + } + return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, key); + } + } + return -2; +} + +static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!strcmp(type, key_ctrl_string)) { + if (strlen(value) != 32) { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, + GOST_R_INVALID_MAC_KEY_LENGTH); + return 0; + } + return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, + 32, (char *)value); + } + if (!strcmp(type, hexkey_ctrl_string)) { + long keylen; + int ret; + unsigned char *keybuf = string_to_hex(value, &keylen); + if (!keybuf || keylen != 32) { + GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, + GOST_R_INVALID_MAC_KEY_LENGTH); + OPENSSL_free(keybuf); + return 0; + } + ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf); + OPENSSL_free(keybuf); + return ret; + + } + return -2; +} + +static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); + unsigned char *keydata; + if (!data->key_set) { + GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET); + return 0; + } + keydata = OPENSSL_malloc(32); + if (keydata == NULL) + return 0; + memcpy(keydata, data->key, 32); + EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); + return 1; +} + +static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + return 1; +} + +static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, EVP_MD_CTX *mctx) +{ + unsigned int tmpsiglen = *siglen; /* for platforms where + * sizeof(int)!=sizeof(size_t) */ + int ret; + if (!sig) { + *siglen = 4; + return 1; + } + ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen); + *siglen = tmpsiglen; + return ret; +} + +/* ----------------------------------------------------------------*/ +int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) +{ + *pmeth = EVP_PKEY_meth_new(id, flags); + if (!*pmeth) + return 0; + + switch (id) { + case NID_id_GostR3410_94: + EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ctrl94_str); + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost94cp_keygen); + EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign); + EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify); + EVP_PKEY_meth_set_encrypt(*pmeth, + pkey_gost_encrypt_init, + pkey_GOST94cp_encrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt); + EVP_PKEY_meth_set_derive(*pmeth, + pkey_gost_derive_init, pkey_gost94_derive); + EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, + pkey_gost94_paramgen); + break; + case NID_id_GostR3410_2001: + EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ctrl01_str); + EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign); + EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify); + + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen); + + EVP_PKEY_meth_set_encrypt(*pmeth, + pkey_gost_encrypt_init, + pkey_GOST01cp_encrypt); + EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt); + EVP_PKEY_meth_set_derive(*pmeth, + pkey_gost_derive_init, pkey_gost2001_derive); + EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, + pkey_gost01_paramgen); + break; + case NID_id_Gost28147_89_MAC: + EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl, + pkey_gost_mac_ctrl_str); + EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init, + pkey_gost_mac_signctx); + EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen); + EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init); + EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup); + EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy); + return 1; + default: /* Unsupported method */ + return 0; + } + EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init); + EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup); + + EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy); + /* + * FIXME derive etc... + */ + + return 1; +} +/********************************************************************** + * gost_sign.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST R 34.10-94 signature algorithm * + * for OpenSSL * + * Requires OpenSSL 0.9.9 for compilation * + **********************************************************************/ +#include +// #include "rand.h" +#include "bn.h" +#include "dsa.h" +// #include "evp.h" +// #include "err.h" + +// #include "gost_params.h" +// #include "gost_lcl.h" +// #include "e_gost_err.h" + +#ifdef DEBUG_SIGN +void dump_signature(const char *message, const unsigned char *buffer, + size_t len) +{ + size_t i; + fprintf(stderr, "signature %s Length=%d", message, len); + for (i = 0; i < len; i++) { + if (i % 16 == 0) + fputc('\n', stderr); + fprintf(stderr, " %02x", buffer[i]); + } + fprintf(stderr, "\nEnd of signature\n"); +} + +void dump_dsa_sig(const char *message, DSA_SIG *sig) +{ + fprintf(stderr, "%s\nR=", message); + BN_print_fp(stderr, sig->r); + fprintf(stderr, "\nS="); + BN_print_fp(stderr, sig->s); + fprintf(stderr, "\n"); +} + +#else + +# define dump_signature(a,b,c) +# define dump_dsa_sig(a,b) +#endif + +/* + * Computes signature and returns it as DSA_SIG structure + */ +DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + BIGNUM *k = NULL, *tmp = NULL, *tmp2 = NULL; + DSA_SIG *newsig = NULL, *ret = NULL; + BIGNUM *md = hashsum2bn(dgst); + /* check if H(M) mod q is zero */ + BN_CTX *ctx = BN_CTX_new(); + if(!ctx) { + GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + BN_CTX_start(ctx); + newsig = DSA_SIG_new(); + if (!newsig) { + GOSTerr(GOST_F_GOST_DO_SIGN, GOST_R_NO_MEMORY); + goto err; + } + tmp = BN_CTX_get(ctx); + k = BN_CTX_get(ctx); + tmp2 = BN_CTX_get(ctx); + if(!tmp || !k || !tmp2) { + GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + BN_mod(tmp, md, dsa->q, ctx); + if (BN_is_zero(tmp)) { + BN_one(md); + } + do { + do { + /* + * Generate random number k less than q + */ + BN_rand_range(k, dsa->q); + /* generate r = (a^x mod p) mod q */ + BN_mod_exp(tmp, dsa->g, k, dsa->p, ctx); + if (!(newsig->r)) { + newsig->r = BN_new(); + if(!newsig->r) { + GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + BN_mod(newsig->r, tmp, dsa->q, ctx); + } + while (BN_is_zero(newsig->r)); + /* generate s = (xr + k(Hm)) mod q */ + BN_mod_mul(tmp, dsa->priv_key, newsig->r, dsa->q, ctx); + BN_mod_mul(tmp2, k, md, dsa->q, ctx); + if (!newsig->s) { + newsig->s = BN_new(); + if(!newsig->s) { + GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + BN_mod_add(newsig->s, tmp, tmp2, dsa->q, ctx); + } + while (BN_is_zero(newsig->s)); + + ret = newsig; + err: + BN_free(md); + if(ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if(!ret && newsig) { + DSA_SIG_free(newsig); + } + return ret; +} + +/* + * Packs signature according to Cryptocom rules + * and frees up DSA_SIG structure + */ +/*- +int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen) + { + *siglen = 2*order; + memset(sig,0,*siglen); + store_bignum(s->r, sig,order); + store_bignum(s->s, sig + order,order); + dump_signature("serialized",sig,*siglen); + DSA_SIG_free(s); + return 1; + } +*/ +/* + * Packs signature according to Cryptopro rules + * and frees up DSA_SIG structure + */ +int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen) +{ + *siglen = 2 * order; + memset(sig, 0, *siglen); + store_bignum(s->s, sig, order); + store_bignum(s->r, sig + order, order); + dump_signature("serialized", sig, *siglen); + DSA_SIG_free(s); + return 1; +} + +/* + * Verifies signature passed as DSA_SIG structure + * + */ + +int gost_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa) +{ + BIGNUM *md = NULL, *tmp = NULL; + BIGNUM *q2 = NULL; + BIGNUM *u = NULL, *v = NULL, *z1 = NULL, *z2 = NULL; + BIGNUM *tmp2 = NULL, *tmp3 = NULL; + int ok = 0; + BN_CTX *ctx = BN_CTX_new(); + if(!ctx) { + GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_CTX_start(ctx); + if (BN_cmp(sig->s, dsa->q) >= 1 || BN_cmp(sig->r, dsa->q) >= 1) { + GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); + goto err; + } + md = hashsum2bn(dgst); + + tmp = BN_CTX_get(ctx); + v = BN_CTX_get(ctx); + q2 = BN_CTX_get(ctx); + z1 = BN_CTX_get(ctx); + z2 = BN_CTX_get(ctx); + tmp2 = BN_CTX_get(ctx); + tmp3 = BN_CTX_get(ctx); + u = BN_CTX_get(ctx); + if(!tmp || !v || !q2 || !z1 || !z2 || !tmp2 || !tmp3 || !u) { + GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + + BN_mod(tmp, md, dsa->q, ctx); + if (BN_is_zero(tmp)) { + BN_one(md); + } + BN_copy(q2, dsa->q); + BN_sub_word(q2, 2); + BN_mod_exp(v, md, q2, dsa->q, ctx); + BN_mod_mul(z1, sig->s, v, dsa->q, ctx); + BN_sub(tmp, dsa->q, sig->r); + BN_mod_mul(z2, tmp, v, dsa->p, ctx); + BN_mod_exp(tmp, dsa->g, z1, dsa->p, ctx); + BN_mod_exp(tmp2, dsa->pub_key, z2, dsa->p, ctx); + BN_mod_mul(tmp3, tmp, tmp2, dsa->p, ctx); + BN_mod(u, tmp3, dsa->q, ctx); + ok = (BN_cmp(u, sig->r) == 0); + + if (!ok) { + GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); + } +err: + if(md) BN_free(md); + if(ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +/* + * Computes public keys for GOST R 34.10-94 algorithm + * + */ +int gost94_compute_public(DSA *dsa) +{ + /* Now fill algorithm parameters with correct values */ + BN_CTX *ctx; + if (!dsa->g) { + GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, GOST_R_KEY_IS_NOT_INITALIZED); + return 0; + } + ctx = BN_CTX_new(); + if(!ctx) { + GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); + return 0; + } + + dsa->pub_key = BN_new(); + if(!dsa->pub_key) { + GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); + BN_CTX_free(ctx); + return 0; + } + /* Compute public key y = a^x mod p */ + BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx); + BN_CTX_free(ctx); + return 1; +} + +/* + * Fill GOST 94 params, searching them in R3410_paramset array + * by nid of paramset + * + */ +int fill_GOST94_params(DSA *dsa, int nid) +{ + R3410_params *params = R3410_paramset; + while (params->nid != NID_undef && params->nid != nid) + params++; + if (params->nid == NID_undef) { + GOSTerr(GOST_F_FILL_GOST94_PARAMS, GOST_R_UNSUPPORTED_PARAMETER_SET); + return 0; + } +#define dump_signature(a,b,c) + if (dsa->p) { + BN_free(dsa->p); + } + dsa->p = NULL; + BN_dec2bn(&(dsa->p), params->p); + if (dsa->q) { + BN_free(dsa->q); + } + dsa->q = NULL; + BN_dec2bn(&(dsa->q), params->q); + if (dsa->g) { + BN_free(dsa->g); + } + dsa->g = NULL; + BN_dec2bn(&(dsa->g), params->a); + return 1; +} + +/* + * Generate GOST R 34.10-94 keypair + * + * + */ +int gost_sign_keygen(DSA *dsa) +{ + dsa->priv_key = BN_new(); + if(!dsa->priv_key) { + GOSTerr(GOST_F_GOST_SIGN_KEYGEN, ERR_R_MALLOC_FAILURE); + return 0; + } + BN_rand_range(dsa->priv_key, dsa->q); + return gost94_compute_public(dsa); +} + +/* Unpack signature according to cryptocom rules */ +/*- +DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen) + { + DSA_SIG *s; + s = DSA_SIG_new(); + if (s == NULL) + { + GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY); + return(NULL); + } + s->r = getbnfrombuf(sig, siglen/2); + s->s = getbnfrombuf(sig + siglen/2, siglen/2); + return s; + } +*/ +/* Unpack signature according to cryptopro rules */ +DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen) +{ + DSA_SIG *s; + + s = DSA_SIG_new(); + if (s == NULL) { + GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, GOST_R_NO_MEMORY); + return NULL; + } + s->s = getbnfrombuf(sig, siglen / 2); + s->r = getbnfrombuf(sig + siglen / 2, siglen / 2); + return s; +} + +/* Convert little-endian byte array into bignum */ +BIGNUM *hashsum2bn(const unsigned char *dgst) +{ + unsigned char buf[32]; + int i; + for (i = 0; i < 32; i++) { + buf[31 - i] = dgst[i]; + } + return getbnfrombuf(buf, 32); +} + +/* Convert byte buffer to bignum, skipping leading zeros*/ +BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len) +{ + while (*buf == 0 && len > 0) { + buf++; + len--; + } + if (len) { + return BN_bin2bn(buf, len, NULL); + } else { + BIGNUM *b = BN_new(); + BN_zero(b); + return b; + } +} + +/* + * Pack bignum into byte buffer of given size, filling all leading bytes by + * zeros + */ +int store_bignum(BIGNUM *bn, unsigned char *buf, int len) +{ + int bytes = BN_num_bytes(bn); + if (bytes > len) + return 0; + memset(buf, 0, len); + BN_bn2bin(bn, buf + len - bytes); + return 1; +} diff --git a/Sources/COpenSSL/gost_keywrap.h b/Sources/COpenSSL/gost_keywrap.h new file mode 100644 index 00000000..7def4c9f --- /dev/null +++ b/Sources/COpenSSL/gost_keywrap.h @@ -0,0 +1,56 @@ +/********************************************************************** + * gost_keywrap.h * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of CryptoPro key wrap algorithm, as defined in * + * RFC 4357 p 6.3 and 6.4 * + * Doesn't need OpenSSL * + **********************************************************************/ +#ifndef GOST_KEYWRAP_H +# define GOST_KEYWRAP_H +# include +# include "gost89.h" +/*- + * Diversifies key using random UserKey Material + * Implements RFC 4357 p 6.5 key diversification algorithm + * + * inputKey - 32byte key to be diversified + * ukm - 8byte user key material + * outputKey - 32byte buffer to store diversified key + * + */ +void keyDiversifyCryptoPro(gost_ctx * ctx, + const unsigned char *inputKey, + const unsigned char *ukm, + unsigned char *outputKey); +/*- + * Wraps key using RFC 4357 6.3 + * ctx - gost encryption context, initialized with some S-boxes + * keyExchangeKey (KEK) 32-byte (256-bit) shared key + * ukm - 8 byte (64 bit) user key material, + * sessionKey - 32-byte (256-bit) key to be wrapped + * wrappedKey - 44-byte buffer to store wrapped key + */ + +int keyWrapCryptoPro(gost_ctx * ctx, + const unsigned char *keyExchangeKey, + const unsigned char *ukm, + const unsigned char *sessionKey, + unsigned char *wrappedKey); +/*- + * Unwraps key using RFC 4357 6.4 + * ctx - gost encryption context, initialized with some S-boxes + * keyExchangeKey 32-byte shared key + * wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM, + * 32 byte encrypted key and 4 byte MAC + * + * sessionKEy - 32byte buffer to store sessionKey in + * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match + */ + +int keyUnwrapCryptoPro(gost_ctx * ctx, + const unsigned char *keyExchangeKey, + const unsigned char *wrappedKey, + unsigned char *sessionKey); +#endif diff --git a/Sources/COpenSSL/gost_lcl.h b/Sources/COpenSSL/gost_lcl.h new file mode 100644 index 00000000..67a81523 --- /dev/null +++ b/Sources/COpenSSL/gost_lcl.h @@ -0,0 +1,229 @@ +#ifndef GOST_TOOLS_H +# define GOST_TOOLS_H +/********************************************************************** + * gost_lcl.h * + * Copyright (c) 2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Internal declarations used in GOST engine * + * OpenSSL 0.9.9 libraries required to compile and use * + * this code * + **********************************************************************/ +# include "bn.h" +# include "evp.h" +# include "dsa.h" +# include "asn1t.h" +# include "x509.h" +# include "engine.h" +# include "ec.h" +# include "gost89.h" +# include "gosthash.h" +/* Control commands */ +# define GOST_PARAM_CRYPT_PARAMS 0 +# define GOST_PARAM_MAX 0 +# define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS) + +extern const ENGINE_CMD_DEFN gost_cmds[]; +int gost_control_func(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); +const char *get_gost_engine_param(int param); +int gost_set_default_param(int param, const char *value); +void gost_param_free(void); + +/* method registration */ + +int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, + const char *pemstr, const char *info); +int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags); + +/* Gost-specific pmeth control-function parameters */ +/* For GOST R34.10 parameters */ +# define param_ctrl_string "paramset" +# define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1) +/* For GOST 28147 MAC */ +# define key_ctrl_string "key" +# define hexkey_ctrl_string "hexkey" +# define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3) +/* Pmeth internal representation */ +struct gost_pmeth_data { + int sign_param_nid; /* Should be set whenever parameters are + * filled */ + EVP_MD *md; + unsigned char *shared_ukm; + int peer_key_used; +}; + +struct gost_mac_pmeth_data { + int key_set; + EVP_MD *md; + unsigned char key[32]; +}; +/* GOST-specific ASN1 structures */ + +typedef struct { + ASN1_OCTET_STRING *encrypted_key; + ASN1_OCTET_STRING *imit; +} GOST_KEY_INFO; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO) + +typedef struct { + ASN1_OBJECT *cipher; + X509_PUBKEY *ephem_key; + ASN1_OCTET_STRING *eph_iv; +} GOST_KEY_AGREEMENT_INFO; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) + +typedef struct { + GOST_KEY_INFO *key_info; + GOST_KEY_AGREEMENT_INFO *key_agreement_info; +} GOST_KEY_TRANSPORT; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) + +typedef struct { /* FIXME incomplete */ + GOST_KEY_TRANSPORT *gkt; +} GOST_CLIENT_KEY_EXCHANGE_PARAMS; + +/* + * Hacks to shorten symbols to 31 characters or less, or OpenVMS. This mimics + * what's done in symhacks.h, but since this is a very local header file, I + * prefered to put this hack directly here. -- Richard Levitte + */ +# ifdef OPENSSL_SYS_VMS +# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_it +# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_it GOST_CLIENT_KEY_EXC_PARAMS_it +# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_new +# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_new GOST_CLIENT_KEY_EXC_PARAMS_new +# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_free +# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_free GOST_CLIENT_KEY_EXC_PARAMS_free +# undef d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS +# define d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS d2i_GOST_CLIENT_KEY_EXC_PARAMS +# undef i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS +# define i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS i2d_GOST_CLIENT_KEY_EXC_PARAMS +# endif /* End of hack */ +DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) +typedef struct { + ASN1_OBJECT *key_params; + ASN1_OBJECT *hash_params; + ASN1_OBJECT *cipher_params; +} GOST_KEY_PARAMS; + +DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS) + +typedef struct { + ASN1_OCTET_STRING *iv; + ASN1_OBJECT *enc_param_set; +} GOST_CIPHER_PARAMS; + +DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) +/*============== Message digest and cipher related structures ==========*/ + /* + * Structure used as EVP_MD_CTX-md_data. It allows to avoid storing + * in the md-data pointers to dynamically allocated memory. I + * cannot invent better way to avoid memory leaks, because openssl + * insist on invoking Init on Final-ed digests, and there is no + * reliable way to find out whether pointer in the passed md_data is + * valid or not. + */ +struct ossl_gost_digest_ctx { + gost_hash_ctx dctx; + gost_ctx cctx; +}; +/* EVP_MD structure for GOST R 34.11 */ +extern EVP_MD digest_gost; +/* EVP_MD structure for GOST 28147 in MAC mode */ +extern EVP_MD imit_gost_cpa; +/* Cipher context used for EVP_CIPHER operation */ +struct ossl_gost_cipher_ctx { + int paramNID; + unsigned int count; + int key_meshing; + gost_ctx cctx; +}; +/* Structure to map parameter NID to S-block */ +struct gost_cipher_info { + int nid; + gost_subst_block *sblock; + int key_meshing; +}; +/* Context for MAC */ +struct ossl_gost_imit_ctx { + gost_ctx cctx; + unsigned char buffer[8]; + unsigned char partial_block[8]; + unsigned int count; + int key_meshing; + int bytes_left; + int key_set; +}; +/* Table which maps parameter NID to S-blocks */ +extern struct gost_cipher_info gost_cipher_list[]; +/* Find encryption params from ASN1_OBJECT */ +const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj); +/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */ +extern EVP_CIPHER cipher_gost; +extern EVP_CIPHER cipher_gost_cpacnt; +# define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3) +# define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4) +/* EVP_PKEY_METHOD key encryption callbacks */ +/* From gost94_keyx.c */ +int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *key, + size_t key_len); + +int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *in, + size_t in_len); +/* From gost2001_keyx.c */ +int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *key, + size_t key_len); + +int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, + size_t *outlen, const unsigned char *in, + size_t in_len); +/* derive functions */ +/* From gost2001_keyx.c */ +int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen); +/* From gost94_keyx.c */ +int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); +/* Internal functions for signature algorithms */ +int fill_GOST94_params(DSA *dsa, int nid); +int fill_GOST2001_params(EC_KEY *eckey, int nid); +int gost_sign_keygen(DSA *dsa); +int gost2001_keygen(EC_KEY *ec); + +DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey); + +int gost_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); +int gost2001_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, EC_KEY *ec); +int gost2001_compute_public(EC_KEY *ec); +int gost94_compute_public(DSA *dsa); +/*============== miscellaneous functions============================= */ +/* from gost_sign.c */ +/* Convert GOST R 34.11 hash sum to bignum according to standard */ +BIGNUM *hashsum2bn(const unsigned char *dgst); +/* + * Store bignum in byte array of given length, prepending by zeros if + * nesseccary + */ +int store_bignum(BIGNUM *bn, unsigned char *buf, int len); +/* Read bignum, which can have few MSB all-zeros from buffer*/ +BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len); +/* Pack GOST R 34.10 signature according to CryptoPro rules */ +int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen); +/* Unpack GOST R 34.10 signature according to CryptoPro rules */ +DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen); +/* from ameth.c */ +/* Get private key as BIGNUM from both R 34.10-94 and R 34.10-2001 keys*/ +/* Returns pointer into EVP_PKEY structure */ +BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey); +/* Find NID by GOST 94 parameters */ +int gost94_nid_by_params(DSA *p); + +#endif diff --git a/Sources/COpenSSL/gost_params.h b/Sources/COpenSSL/gost_params.h new file mode 100644 index 00000000..0773cbfa --- /dev/null +++ b/Sources/COpenSSL/gost_params.h @@ -0,0 +1,34 @@ +/********************************************************************** + * gost_params.h * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Declaration of structures used to represent GOST R 34.10 * + * parameter sets, defined in RFC 4357 * + * OpenSSL 0.9.9 libraries required to compile and use * + * this code * + **********************************************************************/ +#ifndef GOST_PARAMSET_H +# define GOST_PARAMSET_H +typedef struct R3410 { + int nid; + char *a; + char *p; + char *q; +} R3410_params; + +extern R3410_params R3410_paramset[]; + +typedef struct R3410_2001 { + int nid; + char *a; + char *b; + char *p; + char *q; + char *x; + char *y; +} R3410_2001_params; + +extern R3410_2001_params R3410_2001_paramset[]; + +#endif diff --git a/Sources/COpenSSL/gosthash.c b/Sources/COpenSSL/gosthash.c new file mode 100644 index 00000000..bfc884ae --- /dev/null +++ b/Sources/COpenSSL/gosthash.c @@ -0,0 +1,268 @@ +/********************************************************************** + * gosthash.c * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Implementation of GOST R 34.11-94 hash function * + * uses on gost89.c and gost89.h Doesn't need OpenSSL * + **********************************************************************/ +#include + +#include "gost89.h" +#include "gosthash.h" + +/* + * Use OPENSSL_malloc for memory allocation if compiled with + * -DOPENSSL_BUILD, and libc malloc otherwise + */ +#ifndef MYALLOC +# ifdef OPENSSL_BUILD +# include "crypto.h" +# define MYALLOC(size) OPENSSL_malloc(size) +# define MYFREE(ptr) OPENSSL_free(ptr) +# else +# define MYALLOC(size) malloc(size) +# define MYFREE(ptr) free(ptr) +# endif +#endif +/* + * Following functions are various bit meshing routines used in GOST R + * 34.11-94 algorithms + */ +static void swap_bytes(byte * w, byte * k) +{ + int i, j; + for (i = 0; i < 4; i++) + for (j = 0; j < 8; j++) + k[i + 4 * j] = w[8 * i + j]; + +} + +/* was A_A */ +static void circle_xor8(const byte * w, byte * k) +{ + byte buf[8]; + int i; + memcpy(buf, w, 8); + memmove(k, w + 8, 24); + for (i = 0; i < 8; i++) + k[i + 24] = buf[i] ^ k[i]; +} + +/* was R_R */ +static void transform_3(byte * data) +{ + unsigned short int acc; + acc = (data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30]) | + ((data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31]) << 8); + memmove(data, data + 2, 30); + data[30] = acc & 0xff; + data[31] = acc >> 8; +} + +/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/ +static int add_blocks(int n, byte * left, const byte * right) +{ + int i; + int carry = 0; + int sum; + for (i = 0; i < n; i++) { + sum = (int)left[i] + (int)right[i] + carry; + left[i] = sum & 0xff; + carry = sum >> 8; + } + return carry; +} + +/* Xor two sequences of bytes */ +static void xor_blocks(byte * result, const byte * a, const byte * b, + size_t len) +{ + size_t i; + for (i = 0; i < len; i++) + result[i] = a[i] ^ b[i]; +} + +/* + * Calculate H(i+1) = Hash(Hi,Mi) + * Where H and M are 32 bytes long + */ +static int hash_step(gost_ctx * c, byte * H, const byte * M) +{ + byte U[32], W[32], V[32], S[32], Key[32]; + int i; + /* Compute first key */ + xor_blocks(W, H, M, 32); + swap_bytes(W, Key); + /* Encrypt first 8 bytes of H with first key */ + gost_enc_with_key(c, Key, H, S); + /* Compute second key */ + circle_xor8(H, U); + circle_xor8(M, V); + circle_xor8(V, V); + xor_blocks(W, U, V, 32); + swap_bytes(W, Key); + /* encrypt second 8 bytes of H with second key */ + gost_enc_with_key(c, Key, H + 8, S + 8); + /* compute third key */ + circle_xor8(U, U); + U[31] = ~U[31]; + U[29] = ~U[29]; + U[28] = ~U[28]; + U[24] = ~U[24]; + U[23] = ~U[23]; + U[20] = ~U[20]; + U[18] = ~U[18]; + U[17] = ~U[17]; + U[14] = ~U[14]; + U[12] = ~U[12]; + U[10] = ~U[10]; + U[8] = ~U[8]; + U[7] = ~U[7]; + U[5] = ~U[5]; + U[3] = ~U[3]; + U[1] = ~U[1]; + circle_xor8(V, V); + circle_xor8(V, V); + xor_blocks(W, U, V, 32); + swap_bytes(W, Key); + /* encrypt third 8 bytes of H with third key */ + gost_enc_with_key(c, Key, H + 16, S + 16); + /* Compute fourth key */ + circle_xor8(U, U); + circle_xor8(V, V); + circle_xor8(V, V); + xor_blocks(W, U, V, 32); + swap_bytes(W, Key); + /* Encrypt last 8 bytes with fourth key */ + gost_enc_with_key(c, Key, H + 24, S + 24); + for (i = 0; i < 12; i++) + transform_3(S); + xor_blocks(S, S, M, 32); + transform_3(S); + xor_blocks(S, S, H, 32); + for (i = 0; i < 61; i++) + transform_3(S); + memcpy(H, S, 32); + return 1; +} + +/* + * Initialize gost_hash ctx - cleans up temporary structures and set up + * substitution blocks + */ +int init_gost_hash_ctx(gost_hash_ctx * ctx, + const gost_subst_block * subst_block) +{ + memset(ctx, 0, sizeof(gost_hash_ctx)); + ctx->cipher_ctx = (gost_ctx *) MYALLOC(sizeof(gost_ctx)); + if (!ctx->cipher_ctx) { + return 0; + } + gost_init(ctx->cipher_ctx, subst_block); + return 1; +} + +/* + * Free cipher CTX if it is dynamically allocated. Do not use + * if cipher ctx is statically allocated as in OpenSSL implementation of + * GOST hash algroritm + * + */ +void done_gost_hash_ctx(gost_hash_ctx * ctx) +{ + /* + * No need to use gost_destroy, because cipher keys are not really secret + * when hashing + */ + MYFREE(ctx->cipher_ctx); +} + +/* + * reset state of hash context to begin hashing new message + */ +int start_hash(gost_hash_ctx * ctx) +{ + if (!ctx->cipher_ctx) + return 0; + memset(&(ctx->H), 0, 32); + memset(&(ctx->S), 0, 32); + ctx->len = 0L; + ctx->left = 0; + return 1; +} + +/* + * Hash block of arbitrary length + * + * + */ +int hash_block(gost_hash_ctx * ctx, const byte * block, size_t length) +{ + if (ctx->left) { + /* + * There are some bytes from previous step + */ + unsigned int add_bytes = 32 - ctx->left; + if (add_bytes > length) { + add_bytes = length; + } + memcpy(&(ctx->remainder[ctx->left]), block, add_bytes); + ctx->left += add_bytes; + if (ctx->left < 32) { + return 1; + } + block += add_bytes; + length -= add_bytes; + hash_step(ctx->cipher_ctx, ctx->H, ctx->remainder); + add_blocks(32, ctx->S, ctx->remainder); + ctx->len += 32; + ctx->left = 0; + } + while (length >= 32) { + hash_step(ctx->cipher_ctx, ctx->H, block); + + add_blocks(32, ctx->S, block); + ctx->len += 32; + block += 32; + length -= 32; + } + if (length) { + memcpy(ctx->remainder, block, ctx->left = length); + } + return 1; +} + +/* + * Compute hash value from current state of ctx + * state of hash ctx becomes invalid and cannot be used for further + * hashing. + */ +int finish_hash(gost_hash_ctx * ctx, byte * hashval) +{ + byte buf[32]; + byte H[32]; + byte S[32]; + ghosthash_len fin_len = ctx->len; + byte *bptr; + memcpy(H, ctx->H, 32); + memcpy(S, ctx->S, 32); + if (ctx->left) { + memset(buf, 0, 32); + memcpy(buf, ctx->remainder, ctx->left); + hash_step(ctx->cipher_ctx, H, buf); + add_blocks(32, S, buf); + fin_len += ctx->left; + } + memset(buf, 0, 32); + bptr = buf; + fin_len <<= 3; /* Hash length in BITS!! */ + while (fin_len > 0) { + *(bptr++) = (byte) (fin_len & 0xFF); + fin_len >>= 8; + }; + hash_step(ctx->cipher_ctx, H, buf); + hash_step(ctx->cipher_ctx, H, S); + memcpy(hashval, H, 32); + return 1; +} diff --git a/Sources/COpenSSL/gosthash.h b/Sources/COpenSSL/gosthash.h new file mode 100644 index 00000000..003e668e --- /dev/null +++ b/Sources/COpenSSL/gosthash.h @@ -0,0 +1,52 @@ +/********************************************************************** + * gosthash.h * + * Copyright (c) 2005-2006 Cryptocom LTD * + * This file is distributed under the same license as OpenSSL * + * * + * Declaration of GOST R 34.11-94 hash functions * + * uses and gost89.h Doesn't need OpenSSL * + **********************************************************************/ +#ifndef GOSTHASH_H +# define GOSTHASH_H +# include "gost89.h" +# include + +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +typedef __int64 ghosthash_len; +# elif defined(__arch64__) +typedef long ghosthash_len; +# else +typedef long long ghosthash_len; +# endif + +typedef struct gost_hash_ctx { + ghosthash_len len; + gost_ctx *cipher_ctx; + int left; + byte H[32]; + byte S[32]; + byte remainder[32]; +} gost_hash_ctx; + +/* Initalizes gost hash ctx, including creation of gost cipher ctx */ + +int init_gost_hash_ctx(gost_hash_ctx * ctx, + const gost_subst_block * subst_block); +void done_gost_hash_ctx(gost_hash_ctx * ctx); + +/* + * Cleans up all fields, except cipher ctx preparing ctx for computing of new + * hash value + */ +int start_hash(gost_hash_ctx * ctx); + +/* Hashes block of data */ +int hash_block(gost_hash_ctx * ctx, const byte * block, size_t length); + +/* + * Finalizes computation of hash and fills buffer (which should be at least + * 32 bytes long) with value of computed hash. + */ +int finish_hash(gost_hash_ctx * ctx, byte * hashval); + +#endif diff --git a/Sources/COpenSSL/hm_.c b/Sources/COpenSSL/hm_.c new file mode 100644 index 00000000..030ca777 --- /dev/null +++ b/Sources/COpenSSL/hm_.c @@ -0,0 +1,432 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "asn1_locl.h" + +#define HMAC_TEST_PRIVATE_KEY_FORMAT + +/* + * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output + * length and to free up an HMAC key. + */ + +static int hmac_size(const EVP_PKEY *pkey) +{ + return EVP_MAX_MD_SIZE; +} + +static void hmac_key_free(EVP_PKEY *pkey) +{ + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + if (os) { + if (os->data) + OPENSSL_cleanse(os->data, os->length); + ASN1_OCTET_STRING_free(os); + } +} + +static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha256; + return 1; + + default: + return -2; + } +} + +#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT +/* + * A bogus private key format for test purposes. This is simply the HMAC key + * with "HMAC PRIVATE KEY" in the headers. When enabled the genpkey utility + * can be used to "generate" HMAC keys. + */ + +static int old_hmac_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + ASN1_OCTET_STRING *os; + os = ASN1_OCTET_STRING_new(); + if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen)) + goto err; + if (!EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os)) + goto err; + return 1; + + err: + ASN1_OCTET_STRING_free(os); + return 0; +} + +static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + int inc; + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + if (pder) { + if (!*pder) { + *pder = OPENSSL_malloc(os->length); + inc = 0; + } else + inc = 1; + + memcpy(*pder, os->data, os->length); + + if (inc) + *pder += os->length; + } + + return os->length; +} + +#endif + +const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { + EVP_PKEY_HMAC, + EVP_PKEY_HMAC, + 0, + + "HMAC", + "OpenSSL HMAC method", + + 0, 0, 0, 0, + + 0, 0, 0, + + hmac_size, + 0, + 0, 0, 0, 0, 0, 0, 0, + + hmac_key_free, + hmac_pkey_ctrl, +#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT + old_hmac_decode, + old_hmac_encode +#else + 0, 0 +#endif +}; +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +#include "x509.h" +#include "x509v3.h" +// #include "evp.h" +#include "hmac.h" +#include "evp_locl.h" + +/* HMAC pkey context structure */ + +typedef struct { + const EVP_MD *md; /* MD for HMAC use */ + ASN1_OCTET_STRING ktmp; /* Temp storage for key */ + HMAC_CTX ctx; +} HMAC_PKEY_CTX; + +static int pkey_hmac_init(EVP_PKEY_CTX *ctx) +{ + HMAC_PKEY_CTX *hctx; + hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX)); + if (!hctx) + return 0; + hctx->md = NULL; + hctx->ktmp.data = NULL; + hctx->ktmp.length = 0; + hctx->ktmp.flags = 0; + hctx->ktmp.type = V_ASN1_OCTET_STRING; + HMAC_CTX_init(&hctx->ctx); + + ctx->data = hctx; + ctx->keygen_info_count = 0; + + return 1; +} + +static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + HMAC_PKEY_CTX *sctx, *dctx; + if (!pkey_hmac_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->md = sctx->md; + if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx)) + goto err; + if (sctx->ktmp.data != NULL) { + if (!ASN1_OCTET_STRING_set(&dctx->ktmp, + sctx->ktmp.data, sctx->ktmp.length)) + goto err; + } + return 1; + err: + HMAC_CTX_cleanup(&dctx->ctx); + OPENSSL_free(dctx); + return 0; +} + +static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) +{ + HMAC_PKEY_CTX *hctx = ctx->data; + HMAC_CTX_cleanup(&hctx->ctx); + if (hctx->ktmp.data) { + if (hctx->ktmp.length) + OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length); + OPENSSL_free(hctx->ktmp.data); + hctx->ktmp.data = NULL; + } + OPENSSL_free(hctx); +} + +static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + ASN1_OCTET_STRING *hkey = NULL; + HMAC_PKEY_CTX *hctx = ctx->data; + if (!hctx->ktmp.data) + return 0; + hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); + if (!hkey) + return 0; + EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); + + return 1; +} + +static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + HMAC_PKEY_CTX *hctx = ctx->pctx->data; + if (!HMAC_Update(&hctx->ctx, data, count)) + return 0; + return 1; +} + +static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + HMAC_PKEY_CTX *hctx = ctx->data; + HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT); + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); + mctx->update = int_update; + return 1; +} + +static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) +{ + unsigned int hlen; + HMAC_PKEY_CTX *hctx = ctx->data; + int l = EVP_MD_CTX_size(mctx); + + if (l < 0) + return 0; + *siglen = l; + if (!sig) + return 1; + + if (!HMAC_Final(&hctx->ctx, sig, &hlen)) + return 0; + *siglen = (size_t)hlen; + return 1; +} + +static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + HMAC_PKEY_CTX *hctx = ctx->data; + ASN1_OCTET_STRING *key; + switch (type) { + + case EVP_PKEY_CTRL_SET_MAC_KEY: + if ((!p2 && p1 > 0) || (p1 < -1)) + return 0; + if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) + return 0; + break; + + case EVP_PKEY_CTRL_MD: + hctx->md = p2; + break; + + case EVP_PKEY_CTRL_DIGESTINIT: + key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; + if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, + ctx->engine)) + return 0; + break; + + default: + return -2; + + } + return 1; +} + +static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!value) { + return 0; + } + if (!strcmp(type, "key")) { + void *p = (void *)value; + return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p); + } + if (!strcmp(type, "hexkey")) { + unsigned char *key; + int r; + long keylen; + key = string_to_hex(value, &keylen); + if (!key) + return 0; + r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); + OPENSSL_free(key); + return r; + } + return -2; +} + +const EVP_PKEY_METHOD hmac_pkey_meth = { + EVP_PKEY_HMAC, + 0, + pkey_hmac_init, + pkey_hmac_copy, + pkey_hmac_cleanup, + + 0, 0, + + 0, + pkey_hmac_keygen, + + 0, 0, + + 0, 0, + + 0, 0, + + hmac_signctx_init, + hmac_signctx, + + 0, 0, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_hmac_ctrl, + pkey_hmac_ctrl_str +}; diff --git a/Sources/COpenSSL/hmac.c b/Sources/COpenSSL/hmac.c new file mode 100644 index 00000000..8587fc62 --- /dev/null +++ b/Sources/COpenSSL/hmac.c @@ -0,0 +1,268 @@ +/* crypto/hmac/hmac.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#include +#include +#include +#include "cryptlib.h" +#include "hmac.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl) +{ + int i, j, reset = 0; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + +#ifdef OPENSSL_FIPS + /* If FIPS mode switch to approved implementation if possible */ + if (FIPS_mode()) { + const EVP_MD *fipsmd; + if (md) { + fipsmd = FIPS_get_digestbynid(EVP_MD_type(md)); + if (fipsmd) + md = fipsmd; + } + } + + if (FIPS_mode()) { + /* If we have an ENGINE need to allow non FIPS */ + if ((impl || ctx->i_ctx.engine) + && !(ctx->i_ctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { + EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS); + return 0; + } + /* + * Other algorithm blocking will be done in FIPS_cmac_init, via + * FIPS_hmac_init_ex(). + */ + if (!impl && !ctx->i_ctx.engine) + return FIPS_hmac_init_ex(ctx, key, len, md, NULL); + } +#endif + /* If we are changing MD then we must have a key */ + if (md != NULL && md != ctx->md && (key == NULL || len < 0)) + return 0; + + if (md != NULL) { + reset = 1; + ctx->md = md; + } else if (ctx->md) { + md = ctx->md; + } else { + return 0; + } + + if (key != NULL) { + reset = 1; + j = EVP_MD_block_size(md); + OPENSSL_assert(j <= (int)sizeof(ctx->key)); + if (j < len) { + if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->md_ctx, key, len)) + goto err; + if (!EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key, + &ctx->key_length)) + goto err; + } else { + if (len < 0 || len > (int)sizeof(ctx->key)) + return 0; + memcpy(ctx->key, key, len); + ctx->key_length = len; + } + if (ctx->key_length != HMAC_MAX_MD_CBLOCK) + memset(&ctx->key[ctx->key_length], 0, + HMAC_MAX_MD_CBLOCK - ctx->key_length); + } + + if (reset) { + for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) + pad[i] = 0x36 ^ ctx->key[i]; + if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) + goto err; + + for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) + pad[i] = 0x5c ^ ctx->key[i]; + if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) + goto err; + } + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) + goto err; + return 1; + err: + return 0; +} + +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) +{ + if (key && md) + HMAC_CTX_init(ctx); + return HMAC_Init_ex(ctx, key, len, md, NULL); +} + +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->i_ctx.engine) + return FIPS_hmac_update(ctx, data, len); +#endif + if (!ctx->md) + return 0; + + return EVP_DigestUpdate(&ctx->md_ctx, data, len); +} + +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) +{ + unsigned int i; + unsigned char buf[EVP_MAX_MD_SIZE]; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->i_ctx.engine) + return FIPS_hmac_final(ctx, md, len); +#endif + + if (!ctx->md) + goto err; + + if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i)) + goto err; + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx)) + goto err; + if (!EVP_DigestUpdate(&ctx->md_ctx, buf, i)) + goto err; + if (!EVP_DigestFinal_ex(&ctx->md_ctx, md, len)) + goto err; + return 1; + err: + return 0; +} + +void HMAC_CTX_init(HMAC_CTX *ctx) +{ + EVP_MD_CTX_init(&ctx->i_ctx); + EVP_MD_CTX_init(&ctx->o_ctx); + EVP_MD_CTX_init(&ctx->md_ctx); + ctx->md = NULL; +} + +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) +{ + if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx)) + goto err; + memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK); + dctx->key_length = sctx->key_length; + dctx->md = sctx->md; + return 1; + err: + return 0; +} + +void HMAC_CTX_cleanup(HMAC_CTX *ctx) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->i_ctx.engine) { + FIPS_hmac_ctx_cleanup(ctx); + return; + } +#endif + EVP_MD_CTX_cleanup(&ctx->i_ctx); + EVP_MD_CTX_cleanup(&ctx->o_ctx); + EVP_MD_CTX_cleanup(&ctx->md_ctx); + OPENSSL_cleanse(ctx, sizeof(*ctx)); +} + +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len) +{ + HMAC_CTX c; + static unsigned char m[EVP_MAX_MD_SIZE]; + + if (md == NULL) + md = m; + HMAC_CTX_init(&c); + if (!HMAC_Init(&c, key, key_len, evp_md)) + goto err; + if (!HMAC_Update(&c, d, n)) + goto err; + if (!HMAC_Final(&c, md, md_len)) + goto err; + HMAC_CTX_cleanup(&c); + return md; + err: + HMAC_CTX_cleanup(&c); + return NULL; +} + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) +{ + EVP_MD_CTX_set_flags(&ctx->i_ctx, flags); + EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); + EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); +} diff --git a/Sources/COpenSSL/hmac.h b/Sources/COpenSSL/hmac.h new file mode 100644 index 00000000..b7e0ed1c --- /dev/null +++ b/Sources/COpenSSL/hmac.h @@ -0,0 +1,109 @@ +/* crypto/hmac/hmac.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#ifndef HEADER_HMAC_H +# define HEADER_HMAC_H + +# include "opensslconf.h" + +# ifdef OPENSSL_NO_HMAC +# error HMAC is disabled. +# endif + +# include "evp.h" + +# define HMAC_MAX_MD_CBLOCK 128/* largest known is SHA512 */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[HMAC_MAX_MD_CBLOCK]; +} HMAC_CTX; + +# define HMAC_size(e) (EVP_MD_size((e)->md)) + +void HMAC_CTX_init(HMAC_CTX *ctx); +void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +/* deprecated */ +# define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) + +/* deprecated */ +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md); +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl); +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len); +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/hw_4758_cca.h b/Sources/COpenSSL/hw_4758_cca.h new file mode 100644 index 00000000..235543ad --- /dev/null +++ b/Sources/COpenSSL/hw_4758_cca.h @@ -0,0 +1,150 @@ +/**********************************************************************/ +/* */ +/* Prototypes of the CCA verbs used by the 4758 CCA openssl driver */ +/* */ +/* Maurice Gittens */ +/* */ +/**********************************************************************/ + +#ifndef __HW_4758_CCA__ +# define __HW_4758_CCA__ + +/* + * Only WIN32 support for now + */ +# if defined(WIN32) + +# define CCA_LIB_NAME "CSUNSAPI" + +# define CSNDPKX "CSNDPKX_32" +# define CSNDKRR "CSNDKRR_32" +# define CSNDPKE "CSNDPKE_32" +# define CSNDPKD "CSNDPKD_32" +# define CSNDDSV "CSNDDSV_32" +# define CSNDDSG "CSNDDSG_32" +# define CSNBRNG "CSNBRNG_32" + +# define SECURITYAPI __stdcall +# else + /* + * Fixme!! Find out the values of these constants for other platforms. + */ +# define CCA_LIB_NAME "CSUNSAPI" + +# define CSNDPKX "CSNDPKX" +# define CSNDKRR "CSNDKRR" +# define CSNDPKE "CSNDPKE" +# define CSNDPKD "CSNDPKD" +# define CSNDDSV "CSNDDSV" +# define CSNDDSG "CSNDDSG" +# define CSNBRNG "CSNBRNG" + +# define SECURITYAPI +# endif + +/* + * security API prototypes + */ + +/* PKA Key Record Read */ +typedef void (SECURITYAPI * F_KEYRECORDREAD) + (long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + long *rule_array_count, + unsigned char *rule_array, + unsigned char *key_label, long *key_token_length, unsigned char *key_token); + +/* Random Number Generate */ +typedef void (SECURITYAPI * F_RANDOMNUMBERGENERATE) + (long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + unsigned char *form, unsigned char *random_number); + +/* Digital Signature Generate */ +typedef void (SECURITYAPI * F_DIGITALSIGNATUREGENERATE) + (long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + long *rule_array_count, + unsigned char *rule_array, + long *PKA_private_key_id_length, + unsigned char *PKA_private_key_id, + long *hash_length, + unsigned char *hash, + long *signature_field_length, + long *signature_bit_length, unsigned char *signature_field); + +/* Digital Signature Verify */ +typedef void (SECURITYAPI * F_DIGITALSIGNATUREVERIFY) (long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char + *exit_data, + long *rule_array_count, + unsigned char + *rule_array, + long + *PKA_public_key_id_length, + unsigned char + *PKA_public_key_id, + long *hash_length, + unsigned char *hash, + long + *signature_field_length, + unsigned char + *signature_field); + +/* PKA Public Key Extract */ +typedef void (SECURITYAPI * F_PUBLICKEYEXTRACT) (long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + long *rule_array_count, + unsigned char *rule_array, + long + *source_key_identifier_length, + unsigned char + *source_key_identifier, + long + *target_key_token_length, + unsigned char + *target_key_token); + +/* PKA Encrypt */ +typedef void (SECURITYAPI * F_PKAENCRYPT) + (long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + long *rule_array_count, + unsigned char *rule_array, + long *key_value_length, + unsigned char *key_value, + long *data_struct_length, + unsigned char *data_struct, + long *RSA_public_key_length, + unsigned char *RSA_public_key, + long *RSA_encipher_length, unsigned char *RSA_encipher); + +/* PKA Decrypt */ +typedef void (SECURITYAPI * F_PKADECRYPT) + (long *return_code, + long *reason_code, + long *exit_data_length, + unsigned char *exit_data, + long *rule_array_count, + unsigned char *rule_array, + long *enciphered_key_length, + unsigned char *enciphered_key, + long *data_struct_length, + unsigned char *data_struct, + long *RSA_private_key_length, + unsigned char *RSA_private_key, + long *key_value_length, unsigned char *key_value); + +#endif diff --git a/Sources/COpenSSL/hw_ubsec.h b/Sources/COpenSSL/hw_ubsec.h new file mode 100644 index 00000000..a4e67fc5 --- /dev/null +++ b/Sources/COpenSSL/hw_ubsec.h @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * Copyright 2000 + * Broadcom Corporation + * 16215 Alton Parkway + * PO Box 57013 + * Irvine CA 92619-7013 + * + *****************************************************************************/ +/* + * Broadcom Corporation uBSec SDK + */ +/* + * Character device header file. + */ +/* + * Revision History: + * + * October 2000 JTT Created. + */ + +#define MAX_PUBLIC_KEY_BITS (1024) +#define MAX_PUBLIC_KEY_BYTES (1024/8) +#define SHA_BIT_SIZE (160) +#define MAX_CRYPTO_KEY_LENGTH 24 +#define MAX_MAC_KEY_LENGTH 64 +#define UBSEC_CRYPTO_DEVICE_NAME ((unsigned char *)"/dev/ubscrypt") +#define UBSEC_KEY_DEVICE_NAME ((unsigned char *)"/dev/ubskey") + +/* Math command types. */ +#define UBSEC_MATH_MODADD 0x0001 +#define UBSEC_MATH_MODSUB 0x0002 +#define UBSEC_MATH_MODMUL 0x0004 +#define UBSEC_MATH_MODEXP 0x0008 +#define UBSEC_MATH_MODREM 0x0010 +#define UBSEC_MATH_MODINV 0x0020 + +typedef long ubsec_MathCommand_t; +typedef long ubsec_RNGCommand_t; + +typedef struct ubsec_crypto_context_s { + unsigned int flags; + unsigned char crypto[MAX_CRYPTO_KEY_LENGTH]; + unsigned char auth[MAX_MAC_KEY_LENGTH]; +} ubsec_crypto_context_t, *ubsec_crypto_context_p; + +/* + * Predeclare the function pointer types that we dynamically load from the DSO. + */ + +typedef int t_UBSEC_ubsec_bytes_to_bits(unsigned char *n, int bytes); + +typedef int t_UBSEC_ubsec_bits_to_bytes(int bits); + +typedef int t_UBSEC_ubsec_open(unsigned char *device); + +typedef int t_UBSEC_ubsec_close(int fd); + +typedef int t_UBSEC_diffie_hellman_generate_ioctl(int fd, + unsigned char *x, + int *x_len, + unsigned char *y, + int *y_len, + unsigned char *g, int g_len, + unsigned char *m, int m_len, + unsigned char *userX, + int userX_len, + int random_bits); + +typedef int t_UBSEC_diffie_hellman_agree_ioctl(int fd, + unsigned char *x, int x_len, + unsigned char *y, int y_len, + unsigned char *m, int m_len, + unsigned char *k, int *k_len); + +typedef int t_UBSEC_rsa_mod_exp_ioctl(int fd, + unsigned char *x, int x_len, + unsigned char *m, int m_len, + unsigned char *e, int e_len, + unsigned char *y, int *y_len); + +typedef int t_UBSEC_rsa_mod_exp_crt_ioctl(int fd, + unsigned char *x, int x_len, + unsigned char *qinv, int qinv_len, + unsigned char *edq, int edq_len, + unsigned char *q, int q_len, + unsigned char *edp, int edp_len, + unsigned char *p, int p_len, + unsigned char *y, int *y_len); + +typedef int t_UBSEC_dsa_sign_ioctl(int fd, + int hash, unsigned char *data, + int data_len, unsigned char *rndom, + int random_len, unsigned char *p, + int p_len, unsigned char *q, int q_len, + unsigned char *g, int g_len, + unsigned char *key, int key_len, + unsigned char *r, int *r_len, + unsigned char *s, int *s_len); + +typedef int t_UBSEC_dsa_verify_ioctl(int fd, + int hash, unsigned char *data, + int data_len, unsigned char *p, + int p_len, unsigned char *q, int q_len, + unsigned char *g, int g_len, + unsigned char *key, int key_len, + unsigned char *r, int r_len, + unsigned char *s, int s_len, + unsigned char *v, int *v_len); + +typedef int t_UBSEC_math_accelerate_ioctl(int fd, ubsec_MathCommand_t command, + unsigned char *ModN, int *ModN_len, + unsigned char *ExpE, int *ExpE_len, + unsigned char *ParamA, + int *ParamA_len, + unsigned char *ParamB, + int *ParamB_len, + unsigned char *Result, + int *Result_len); + +typedef int t_UBSEC_rng_ioctl(int fd, ubsec_RNGCommand_t command, + unsigned char *Result, int *Result_len); + +typedef int t_UBSEC_max_key_len_ioctl(int fd, int *max_key_len); diff --git a/Sources/COpenSSL/hwcryptohook.h b/Sources/COpenSSL/hwcryptohook.h new file mode 100644 index 00000000..fa06396a --- /dev/null +++ b/Sources/COpenSSL/hwcryptohook.h @@ -0,0 +1,502 @@ +/*- + * ModExp / RSA (with/without KM) plugin API + * + * The application will load a dynamic library which + * exports entrypoint(s) defined in this file. + * + * This set of entrypoints provides only a multithreaded, + * synchronous-within-each-thread, facility. + * + * + * This file is Copyright 1998-2000 nCipher Corporation Limited. + * + * Redistribution and use in source and binary forms, with opr without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the copyright notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions, and the following + * disclaimer, in the documentation and/or other materials provided + * with the distribution + * + * IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR + * ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any + * damages arising directly or indirectly from this file, its use or + * this licence. Without prejudice to the generality of the + * foregoing: all liability shall be excluded for direct, indirect, + * special, incidental, consequential or other damages or any loss of + * profits, business, revenue goodwill or anticipated savings; + * liability shall be excluded even if nCipher or anyone else has been + * advised of the possibility of damage. In any event, if the + * exclusion of liability is not effective, the liability of nCipher + * or any author or distributor shall be limited to the lesser of the + * price paid and 1,000 pounds sterling. This licence only fails to + * exclude or limit liability for death or personal injury arising out + * of negligence, and only to the extent that such an exclusion or + * limitation is not effective. + * + * NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL + * AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not + * limited to, any implied warranties of merchantability, fitness for + * a particular purpose, satisfactory quality, and/or non-infringement + * of any third party rights. + * + * US Government use: This software and documentation is Commercial + * Computer Software and Computer Software Documentation, as defined in + * sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in + * Noncommercial Computer Software and Noncommercial Computer Software + * Documentation." Use, duplication or disclosure by the Government is + * subject to the terms and conditions specified here. + * + * By using or distributing this file you will be accepting these + * terms and conditions, including the limitation of liability and + * lack of warranty. If you do not wish to accept these terms and + * conditions, DO NOT USE THE FILE. + * + * + * The actual dynamically loadable plugin, and the library files for + * static linking, which are also provided in some distributions, are + * not covered by the licence described above. You should have + * received a separate licence with terms and conditions for these + * library files; if you received the library files without a licence, + * please contact nCipher. + * + * + * $Id: hwcryptohook.h,v 1.1 2002/10/11 17:10:59 levitte Exp $ + */ + +#ifndef HWCRYPTOHOOK_H +# define HWCRYPTOHOOK_H + +# include +# include + +# ifndef HWCRYPTOHOOK_DECLARE_APPTYPES +# define HWCRYPTOHOOK_DECLARE_APPTYPES 1 +# endif + +# define HWCRYPTOHOOK_ERROR_FAILED -1 +# define HWCRYPTOHOOK_ERROR_FALLBACK -2 +# define HWCRYPTOHOOK_ERROR_MPISIZE -3 + +# if HWCRYPTOHOOK_DECLARE_APPTYPES + +/*- + * These structs are defined by the application and opaque to the + * crypto plugin. The application may define these as it sees fit. + * Default declarations are provided here, but the application may + * #define HWCRYPTOHOOK_DECLARE_APPTYPES 0 + * to prevent these declarations, and instead provide its own + * declarations of these types. (Pointers to them must still be + * ordinary pointers to structs or unions, or the resulting combined + * program will have a type inconsistency.) + */ +typedef struct HWCryptoHook_MutexValue HWCryptoHook_Mutex; +typedef struct HWCryptoHook_CondVarValue HWCryptoHook_CondVar; +typedef struct HWCryptoHook_PassphraseContextValue + HWCryptoHook_PassphraseContext; +typedef struct HWCryptoHook_CallerContextValue HWCryptoHook_CallerContext; + +# endif /* HWCRYPTOHOOK_DECLARE_APPTYPES */ + +/*- + * These next two structs are opaque to the application. The crypto + * plugin will return pointers to them; the caller simply manipulates + * the pointers. + */ +typedef struct HWCryptoHook_Context *HWCryptoHook_ContextHandle; +typedef struct HWCryptoHook_RSAKey *HWCryptoHook_RSAKeyHandle; + +typedef struct { + char *buf; + size_t size; +} HWCryptoHook_ErrMsgBuf; +/*- + * Used for error reporting. When a HWCryptoHook function fails it + * will return a sentinel value (0 for pointer-valued functions, or a + * negative number, usually HWCRYPTOHOOK_ERROR_FAILED, for + * integer-valued ones). It will, if an ErrMsgBuf is passed, also put + * an error message there. + * + * size is the size of the buffer, and will not be modified. If you + * pass 0 for size you must pass 0 for buf, and nothing will be + * recorded (just as if you passed 0 for the struct pointer). + * Messages written to the buffer will always be null-terminated, even + * when truncated to fit within size bytes. + * + * The contents of the buffer are not defined if there is no error. + */ + +typedef struct HWCryptoHook_MPIStruct { + unsigned char *buf; + size_t size; +} HWCryptoHook_MPI; +/*- + * When one of these is returned, a pointer is passed to the function. + * At call, size is the space available. Afterwards it is updated to + * be set to the actual length (which may be more than the space available, + * if there was not enough room and the result was truncated). + * buf (the pointer) is not updated. + * + * size is in bytes and may be zero at call or return, but must be a + * multiple of the limb size. Zero limbs at the MS end are not + * permitted. + */ + +# define HWCryptoHook_InitFlags_FallbackModExp 0x0002UL +# define HWCryptoHook_InitFlags_FallbackRSAImmed 0x0004UL +/*- + * Enable requesting fallback to software in case of problems with the + * hardware support. This indicates to the crypto provider that the + * application is prepared to fall back to software operation if the + * ModExp* or RSAImmed* functions return HWCRYPTOHOOK_ERROR_FALLBACK. + * Without this flag those calls will never return + * HWCRYPTOHOOK_ERROR_FALLBACK. The flag will also cause the crypto + * provider to avoid repeatedly attempting to contact dead hardware + * within a short interval, if appropriate. + */ + +# define HWCryptoHook_InitFlags_SimpleForkCheck 0x0010UL +/*- + * Without _SimpleForkCheck the library is allowed to assume that the + * application will not fork and call the library in the child(ren). + * + * When it is specified, this is allowed. However, after a fork + * neither parent nor child may unload any loaded keys or call + * _Finish. Instead, they should call exit (or die with a signal) + * without calling _Finish. After all the children have died the + * parent may unload keys or call _Finish. + * + * This flag only has any effect on UN*X platforms. + */ + +typedef struct { + unsigned long flags; + void *logstream; /* usually a FILE*. See below. */ + size_t limbsize; /* bignum format - size of radix type, must + * be power of 2 */ + int mslimbfirst; /* 0 or 1 */ + int msbytefirst; /* 0 or 1; -1 = native */ + /*- + * All the callback functions should return 0 on success, or a + * nonzero integer (whose value will be visible in the error message + * put in the buffer passed to the call). + * + * If a callback is not available pass a null function pointer. + * + * The callbacks may not call down again into the crypto plugin. + */ + /*- + * For thread-safety. Set everything to 0 if you promise only to be + * singlethreaded. maxsimultaneous is the number of calls to + * ModExp[Crt]/RSAImmed{Priv,Pub}/RSA. If you don't know what to + * put there then say 0 and the hook library will use a default. + * + * maxmutexes is a small limit on the number of simultaneous mutexes + * which will be requested by the library. If there is no small + * limit, set it to 0. If the crypto plugin cannot create the + * advertised number of mutexes the calls to its functions may fail. + * If a low number of mutexes is advertised the plugin will try to + * do the best it can. Making larger numbers of mutexes available + * may improve performance and parallelism by reducing contention + * over critical sections. Unavailability of any mutexes, implying + * single-threaded operation, should be indicated by the setting + * mutex_init et al to 0. + */ + int maxmutexes; + int maxsimultaneous; + size_t mutexsize; + int (*mutex_init) (HWCryptoHook_Mutex *, + HWCryptoHook_CallerContext * cactx); + int (*mutex_acquire) (HWCryptoHook_Mutex *); + void (*mutex_release) (HWCryptoHook_Mutex *); + void (*mutex_destroy) (HWCryptoHook_Mutex *); + /*- + * For greater efficiency, can use condition vars internally for + * synchronisation. In this case maxsimultaneous is ignored, but + * the other mutex stuff must be available. In singlethreaded + * programs, set everything to 0. + */ + size_t condvarsize; + int (*condvar_init) (HWCryptoHook_CondVar *, + HWCryptoHook_CallerContext * cactx); + int (*condvar_wait) (HWCryptoHook_CondVar *, HWCryptoHook_Mutex *); + void (*condvar_signal) (HWCryptoHook_CondVar *); + void (*condvar_broadcast) (HWCryptoHook_CondVar *); + void (*condvar_destroy) (HWCryptoHook_CondVar *); + /*- + * The semantics of acquiring and releasing mutexes and broadcasting + * and waiting on condition variables are expected to be those from + * POSIX threads (pthreads). The mutexes may be (in pthread-speak) + * fast mutexes, recursive mutexes, or nonrecursive ones. + * + * The _release/_signal/_broadcast and _destroy functions must + * always succeed when given a valid argument; if they are given an + * invalid argument then the program (crypto plugin + application) + * has an internal error, and they should abort the program. + */ + int (*getpassphrase) (const char *prompt_info, + int *len_io, char *buf, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx); + /*- + * Passphrases and the prompt_info, if they contain high-bit-set + * characters, are UTF-8. The prompt_info may be a null pointer if + * no prompt information is available (it should not be an empty + * string). It will not contain text like `enter passphrase'; + * instead it might say something like `Operator Card for John + * Smith' or `SmartCard in nFast Module #1, Slot #1'. + * + * buf points to a buffer in which to return the passphrase; on + * entry *len_io is the length of the buffer. It should be updated + * by the callback. The returned passphrase should not be + * null-terminated by the callback. + */ + int (*getphystoken) (const char *prompt_info, + const char *wrong_info, + HWCryptoHook_PassphraseContext * ppctx, + HWCryptoHook_CallerContext * cactx); + /*- + * Requests that the human user physically insert a different + * smartcard, DataKey, etc. The plugin should check whether the + * currently inserted token(s) are appropriate, and if they are it + * should not make this call. + * + * prompt_info is as before. wrong_info is a description of the + * currently inserted token(s) so that the user is told what + * something is. wrong_info, like prompt_info, may be null, but + * should not be an empty string. Its contents should be + * syntactically similar to that of prompt_info. + */ + /*- + * Note that a single LoadKey operation might cause several calls to + * getpassphrase and/or requestphystoken. If requestphystoken is + * not provided (ie, a null pointer is passed) then the plugin may + * not support loading keys for which authorisation by several cards + * is required. If getpassphrase is not provided then cards with + * passphrases may not be supported. + * + * getpassphrase and getphystoken do not need to check that the + * passphrase has been entered correctly or the correct token + * inserted; the crypto plugin will do that. If this is not the + * case then the crypto plugin is responsible for calling these + * routines again as appropriate until the correct token(s) and + * passphrase(s) are supplied as required, or until any retry limits + * implemented by the crypto plugin are reached. + * + * In either case, the application must allow the user to say `no' + * or `cancel' to indicate that they do not know the passphrase or + * have the appropriate token; this should cause the callback to + * return nonzero indicating error. + */ + void (*logmessage) (void *logstream, const char *message); + /*- + * A log message will be generated at least every time something goes + * wrong and an ErrMsgBuf is filled in (or would be if one was + * provided). Other diagnostic information may be written there too, + * including more detailed reasons for errors which are reported in an + * ErrMsgBuf. + * + * When a log message is generated, this callback is called. It + * should write a message to the relevant logging arrangements. + * + * The message string passed will be null-terminated and may be of arbitrary + * length. It will not be prefixed by the time and date, nor by the + * name of the library that is generating it - if this is required, + * the logmessage callback must do it. The message will not have a + * trailing newline (though it may contain internal newlines). + * + * If a null pointer is passed for logmessage a default function is + * used. The default function treats logstream as a FILE* which has + * been converted to a void*. If logstream is 0 it does nothing. + * Otherwise it prepends the date and time and library name and + * writes the message to logstream. Each line will be prefixed by a + * descriptive string containing the date, time and identity of the + * crypto plugin. Errors on the logstream are not reported + * anywhere, and the default function doesn't flush the stream, so + * the application must set the buffering how it wants it. + * + * The crypto plugin may also provide a facility to have copies of + * log messages sent elsewhere, and or for adjusting the verbosity + * of the log messages; any such facilities will be configured by + * external means. + */ +} HWCryptoHook_InitInfo; + +typedef +HWCryptoHook_ContextHandle HWCryptoHook_Init_t(const HWCryptoHook_InitInfo * + initinfo, size_t initinfosize, + const HWCryptoHook_ErrMsgBuf * + errors, + HWCryptoHook_CallerContext * + cactx); +extern HWCryptoHook_Init_t HWCryptoHook_Init; + +/*- + * Caller should set initinfosize to the size of the HWCryptoHook struct, + * so it can be extended later. + * + * On success, a message for display or logging by the server, + * including the name and version number of the plugin, will be filled + * in into *errors; on failure *errors is used for error handling, as + * usual. + */ + +/*- + * All these functions return 0 on success, HWCRYPTOHOOK_ERROR_FAILED + * on most failures. HWCRYPTOHOOK_ERROR_MPISIZE means at least one of + * the output MPI buffer(s) was too small; the sizes of all have been + * set to the desired size (and for those where the buffer was large + * enough, the value may have been copied in), and no error message + * has been recorded. + * + * You may pass 0 for the errors struct. In any case, unless you set + * _NoStderr at init time then messages may be reported to stderr. + */ + +/*- + * The RSAImmed* functions (and key managed RSA) only work with + * modules which have an RSA patent licence - currently that means KM + * units; the ModExp* ones work with all modules, so you need a patent + * licence in the software in the US. They are otherwise identical. + */ + +typedef +void HWCryptoHook_Finish_t(HWCryptoHook_ContextHandle hwctx); +extern HWCryptoHook_Finish_t HWCryptoHook_Finish; +/* You must not have any calls going or keys loaded when you call this. */ + +typedef +int HWCryptoHook_RandomBytes_t(HWCryptoHook_ContextHandle hwctx, + unsigned char *buf, size_t len, + const HWCryptoHook_ErrMsgBuf * errors); +extern HWCryptoHook_RandomBytes_t HWCryptoHook_RandomBytes; + +typedef +int HWCryptoHook_ModExp_t(HWCryptoHook_ContextHandle hwctx, + HWCryptoHook_MPI a, + HWCryptoHook_MPI p, + HWCryptoHook_MPI n, + HWCryptoHook_MPI * r, + const HWCryptoHook_ErrMsgBuf * errors); +extern HWCryptoHook_ModExp_t HWCryptoHook_ModExp; + +typedef +int HWCryptoHook_RSAImmedPub_t(HWCryptoHook_ContextHandle hwctx, + HWCryptoHook_MPI m, + HWCryptoHook_MPI e, + HWCryptoHook_MPI n, + HWCryptoHook_MPI * r, + const HWCryptoHook_ErrMsgBuf * errors); +extern HWCryptoHook_RSAImmedPub_t HWCryptoHook_RSAImmedPub; + +typedef +int HWCryptoHook_ModExpCRT_t(HWCryptoHook_ContextHandle hwctx, + HWCryptoHook_MPI a, + HWCryptoHook_MPI p, + HWCryptoHook_MPI q, + HWCryptoHook_MPI dmp1, + HWCryptoHook_MPI dmq1, + HWCryptoHook_MPI iqmp, + HWCryptoHook_MPI * r, + const HWCryptoHook_ErrMsgBuf * errors); +extern HWCryptoHook_ModExpCRT_t HWCryptoHook_ModExpCRT; + +typedef +int HWCryptoHook_RSAImmedPriv_t(HWCryptoHook_ContextHandle hwctx, + HWCryptoHook_MPI m, + HWCryptoHook_MPI p, + HWCryptoHook_MPI q, + HWCryptoHook_MPI dmp1, + HWCryptoHook_MPI dmq1, + HWCryptoHook_MPI iqmp, + HWCryptoHook_MPI * r, + const HWCryptoHook_ErrMsgBuf * errors); +extern HWCryptoHook_RSAImmedPriv_t HWCryptoHook_RSAImmedPriv; + +/*- + * The RSAImmed* and ModExp* functions may return E_FAILED or + * E_FALLBACK for failure. + * + * E_FAILED means the failure is permanent and definite and there + * should be no attempt to fall back to software. (Eg, for some + * applications, which support only the acceleration-only + * functions, the `key material' may actually be an encoded key + * identifier, and doing the operation in software would give wrong + * answers.) + * + * E_FALLBACK means that doing the computation in software would seem + * reasonable. If an application pays attention to this and is + * able to fall back, it should also set the Fallback init flags. + */ + +typedef +int HWCryptoHook_RSALoadKey_t(HWCryptoHook_ContextHandle hwctx, + const char *key_ident, + HWCryptoHook_RSAKeyHandle * keyhandle_r, + const HWCryptoHook_ErrMsgBuf * errors, + HWCryptoHook_PassphraseContext * ppctx); +extern HWCryptoHook_RSALoadKey_t HWCryptoHook_RSALoadKey; +/*- + * The key_ident is a null-terminated string configured by the + * user via the application's usual configuration mechanisms. + * It is provided to the user by the crypto provider's key management + * system. The user must be able to enter at least any string of between + * 1 and 1023 characters inclusive, consisting of printable 7-bit + * ASCII characters. The provider should avoid using + * any characters except alphanumerics and the punctuation + * characters _ - + . / @ ~ (the user is expected to be able + * to enter these without quoting). The string may be case-sensitive. + * The application may allow the user to enter other NULL-terminated strings, + * and the provider must cope (returning an error if the string is not + * valid). + * + * If the key does not exist, no error is recorded and 0 is returned; + * keyhandle_r will be set to 0 instead of to a key handle. + */ + +typedef +int HWCryptoHook_RSAGetPublicKey_t(HWCryptoHook_RSAKeyHandle k, + HWCryptoHook_MPI * n, + HWCryptoHook_MPI * e, + const HWCryptoHook_ErrMsgBuf * errors); +extern HWCryptoHook_RSAGetPublicKey_t HWCryptoHook_RSAGetPublicKey; +/*- + * The crypto plugin will not store certificates. + * + * Although this function for acquiring the public key value is + * provided, it is not the purpose of this API to deal fully with the + * handling of the public key. + * + * It is expected that the crypto supplier's key generation program + * will provide general facilities for producing X.509 + * self-certificates and certificate requests in PEM format. These + * will be given to the user so that they can configure them in the + * application, send them to CAs, or whatever. + * + * In case this kind of certificate handling is not appropriate, the + * crypto supplier's key generation program should be able to be + * configured not to generate such a self-certificate or certificate + * request. Then the application will need to do all of this, and + * will need to store and handle the public key and certificates + * itself. + */ + +typedef +int HWCryptoHook_RSAUnloadKey_t(HWCryptoHook_RSAKeyHandle k, + const HWCryptoHook_ErrMsgBuf * errors); +extern HWCryptoHook_RSAUnloadKey_t HWCryptoHook_RSAUnloadKey; +/* Might fail due to locking problems, or other serious internal problems. */ + +typedef +int HWCryptoHook_RSA_t(HWCryptoHook_MPI m, + HWCryptoHook_RSAKeyHandle k, + HWCryptoHook_MPI * r, + const HWCryptoHook_ErrMsgBuf * errors); +extern HWCryptoHook_RSA_t HWCryptoHook_RSA; +/* RSA private key operation (sign or decrypt) - raw, unpadded. */ + +#endif /* HWCRYPTOHOOK_H */ diff --git a/Sources/COpenSSL/i2d_.c b/Sources/COpenSSL/i2d_.c new file mode 100644 index 00000000..292daa76 --- /dev/null +++ b/Sources/COpenSSL/i2d_.c @@ -0,0 +1,174 @@ +/* crypto/asn1/i2d_pr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "x509.h" +#include "asn1_locl.h" + +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) +{ + if (a->ameth && a->ameth->old_priv_encode) { + return a->ameth->old_priv_encode(a, pp); + } + if (a->ameth && a->ameth->priv_encode) { + PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); + int ret = 0; + if (p8 != NULL) { + ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp); + PKCS8_PRIV_KEY_INFO_free(p8); + } + return ret; + } + ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; +} +/* crypto/asn1/i2d_pu.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "bn.h" +// #include "evp.h" +#include "objects.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_EC +# include "ec.h" +#endif + +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp) +{ + switch (a->type) { +#ifndef OPENSSL_NO_RSA + case EVP_PKEY_RSA: + return (i2d_RSAPublicKey(a->pkey.rsa, pp)); +#endif +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + return (i2d_DSAPublicKey(a->pkey.dsa, pp)); +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + return (i2o_ECPublicKey(a->pkey.ec, pp)); +#endif + default: + ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return (-1); + } +} diff --git a/Sources/COpenSSL/i_.c b/Sources/COpenSSL/i_.c new file mode 100644 index 00000000..a262c89f --- /dev/null +++ b/Sources/COpenSSL/i_.c @@ -0,0 +1,663 @@ +/* crypto/idea/i_cbc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "idea.h" +#include "idea_lcl.h" + +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int encrypt) +{ + register unsigned long tin0, tin1; + register unsigned long tout0, tout1, xor0, xor1; + register long l = length; + unsigned long tin[2]; + + if (encrypt) { + n2l(iv, tout0); + n2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0]; + l2n(tout0, out); + tout1 = tin[1]; + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0]; + l2n(tout0, out); + tout1 = tin[1]; + l2n(tout1, out); + } + l2n(tout0, iv); + l2n(tout1, iv); + } else { + n2l(iv, xor0); + n2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + tin[0] = tin0; + n2l(in, tin1); + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + tin[0] = tin0; + n2l(in, tin1); + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, iv); + l2n(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +void idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key) +{ + register IDEA_INT *p; + register unsigned long x1, x2, x3, x4, t0, t1, ul; + + x2 = d[0]; + x1 = (x2 >> 16); + x4 = d[1]; + x3 = (x4 >> 16); + + p = &(key->data[0][0]); + + E_IDEA(0); + E_IDEA(1); + E_IDEA(2); + E_IDEA(3); + E_IDEA(4); + E_IDEA(5); + E_IDEA(6); + E_IDEA(7); + + x1 &= 0xffff; + idea_mul(x1, x1, *p, ul); + p++; + + t0 = x3 + *(p++); + t1 = x2 + *(p++); + + x4 &= 0xffff; + idea_mul(x4, x4, *p, ul); + + d[0] = (t0 & 0xffff) | ((x1 & 0xffff) << 16); + d[1] = (x4 & 0xffff) | ((t1 & 0xffff) << 16); +} +/* crypto/idea/i_cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "idea.h" +// #include "idea_lcl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *schedule, + unsigned char *ivec, int *num, int encrypt) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned long ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + idea_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + idea_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} +/* crypto/idea/i_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "idea.h" +// #include "idea_lcl.h" +#include "opensslv.h" + +const char IDEA_version[] = "IDEA" OPENSSL_VERSION_PTEXT; + +const char *idea_options(void) +{ + if (sizeof(short) != sizeof(IDEA_INT)) + return ("idea(int)"); + else + return ("idea(short)"); +} + +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks) +{ + unsigned long l0, l1, d[2]; + + n2l(in, l0); + d[0] = l0; + n2l(in, l1); + d[1] = l1; + idea_encrypt(d, ks); + l0 = d[0]; + l2n(l0, out); + l1 = d[1]; + l2n(l1, out); + l0 = l1 = d[0] = d[1] = 0; +} +/* crypto/idea/i_ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "idea.h" +// #include "idea_lcl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *schedule, + unsigned char *ivec, int *num) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + unsigned long ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + n2l(iv, v0); + n2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2n(v0, dp); + l2n(v1, dp); + while (l--) { + if (n == 0) { + idea_encrypt((unsigned long *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2n(t, dp); + t = ti[1]; + l2n(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2n(v0, iv); + l2n(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} +/* crypto/idea/i_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "crypto.h" +// #include "idea.h" +// #include "idea_lcl.h" + +static IDEA_INT inverse(unsigned int xin); +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(IDEA); + private_idea_set_encrypt_key(key, ks); +} + +void private_idea_set_encrypt_key(const unsigned char *key, + IDEA_KEY_SCHEDULE *ks) +#endif +{ + int i; + register IDEA_INT *kt, *kf, r0, r1, r2; + + kt = &(ks->data[0][0]); + n2s(key, kt[0]); + n2s(key, kt[1]); + n2s(key, kt[2]); + n2s(key, kt[3]); + n2s(key, kt[4]); + n2s(key, kt[5]); + n2s(key, kt[6]); + n2s(key, kt[7]); + + kf = kt; + kt += 8; + for (i = 0; i < 6; i++) { + r2 = kf[1]; + r1 = kf[2]; + *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[3]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[4]; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[5]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[6]; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[7]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[0]; + if (i >= 5) + break; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff; + kf += 8; + } +} + +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) +{ + int r; + register IDEA_INT *fp, *tp, t; + + tp = &(dk->data[0][0]); + fp = &(ek->data[8][0]); + for (r = 0; r < 9; r++) { + *(tp++) = inverse(fp[0]); + *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff); + *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff); + *(tp++) = inverse(fp[3]); + if (r == 8) + break; + fp -= 6; + *(tp++) = fp[4]; + *(tp++) = fp[5]; + } + + tp = &(dk->data[0][0]); + t = tp[1]; + tp[1] = tp[2]; + tp[2] = t; + + t = tp[49]; + tp[49] = tp[50]; + tp[50] = t; +} + +/* taken directly from the 'paper' I'll have a look at it later */ +static IDEA_INT inverse(unsigned int xin) +{ + long n1, n2, q, r, b1, b2, t; + + if (xin == 0) + b2 = 0; + else { + n1 = 0x10001; + n2 = xin; + b2 = 1; + b1 = 0; + + do { + r = (n1 % n2); + q = (n1 - r) / n2; + if (r == 0) { + if (b2 < 0) + b2 = 0x10001 + b2; + } else { + n1 = n2; + n2 = r; + t = b2; + b2 = b1 - q * b2; + b1 = t; + } + } while (r != 0); + } + return ((IDEA_INT) b2); +} diff --git a/Sources/COpenSSL/idea.h b/Sources/COpenSSL/idea.h new file mode 100644 index 00000000..7ea2f06c --- /dev/null +++ b/Sources/COpenSSL/idea.h @@ -0,0 +1,105 @@ +/* crypto/idea/idea.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_IDEA_H +# define HEADER_IDEA_H + +# include "opensslconf.h"/* IDEA_INT, OPENSSL_NO_IDEA */ + +# ifdef OPENSSL_NO_IDEA +# error IDEA is disabled. +# endif + +# define IDEA_ENCRYPT 1 +# define IDEA_DECRYPT 0 + +# define IDEA_BLOCK 8 +# define IDEA_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct idea_key_st { + IDEA_INT data[9][6]; +} IDEA_KEY_SCHEDULE; + +const char *idea_options(void); +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks); +# ifdef OPENSSL_FIPS +void private_idea_set_encrypt_key(const unsigned char *key, + IDEA_KEY_SCHEDULE *ks); +# endif +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int enc); +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num, int enc); +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num); +void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/idea_lcl.h b/Sources/COpenSSL/idea_lcl.h new file mode 100644 index 00000000..e4069538 --- /dev/null +++ b/Sources/COpenSSL/idea_lcl.h @@ -0,0 +1,216 @@ +/* crypto/idea/idea_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * The new form of this macro (check if the a*b == 0) was suggested by Colin + * Plumb + */ +/* Removal of the inner if from from Wei Dai 24/4/96 */ +#define idea_mul(r,a,b,ul) \ +ul=(unsigned long)a*b; \ +if (ul != 0) \ + { \ + r=(ul&0xffff)-(ul>>16); \ + r-=((r)>>16); \ + } \ +else \ + r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ + +#ifdef undef +# define idea_mul(r,a,b,ul,sl) \ +if (a == 0) r=(0x10001-b)&0xffff; \ +else if (b == 0) r=(0x10001-a)&0xffff; \ +else { \ + ul=(unsigned long)a*b; \ + sl=(ul&0xffff)-(ul>>16); \ + if (sl <= 0) sl+=0x10001; \ + r=sl; \ + } +#endif + +/* + * 7/12/95 - Many thanks to Rhys Weatherley for + * pointing out that I was assuming little endian byte order for all + * quantities what idea actually used bigendian. No where in the spec does + * it mention this, it is all in terms of 16 bit numbers and even the example + * does not use byte streams for the input example :-(. If you byte swap each + * pair of input, keys and iv, the functions would produce the output as the + * old version :-(. + */ + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#undef s2n +#define s2n(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff)) + +#undef n2s +#define n2s(c,l) (l =((IDEA_INT)(*((c)++)))<< 8L, \ + l|=((IDEA_INT)(*((c)++))) ) + +#ifdef undef +/* NOTE - c is not incremented as per c2l */ +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +/* NOTE - c is not incremented as per l2c */ +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +# undef c2s +# define c2s(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L) + +# undef s2c +# define s2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff)) + +# undef c2l +# define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +# undef l2c +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) +#endif + +#define E_IDEA(num) \ + x1&=0xffff; \ + idea_mul(x1,x1,*p,ul); p++; \ + x2+= *(p++); \ + x3+= *(p++); \ + x4&=0xffff; \ + idea_mul(x4,x4,*p,ul); p++; \ + t0=(x1^x3)&0xffff; \ + idea_mul(t0,t0,*p,ul); p++; \ + t1=(t0+(x2^x4))&0xffff; \ + idea_mul(t1,t1,*p,ul); p++; \ + t0+=t1; \ + x1^=t1; \ + x4^=t0; \ + ul=x2^t0; /* do the swap to x3 */ \ + x2=x3^t1; \ + x3=ul; diff --git a/Sources/COpenSSL/include/module.modulemap b/Sources/COpenSSL/include/module.modulemap new file mode 100644 index 00000000..989a7c23 --- /dev/null +++ b/Sources/COpenSSL/include/module.modulemap @@ -0,0 +1,3 @@ +module COpenSSL { + header "openssl.h" +} diff --git a/Sources/COpenSSL/include/openssl.h b/Sources/COpenSSL/include/openssl.h new file mode 100644 index 00000000..c9c50822 --- /dev/null +++ b/Sources/COpenSSL/include/openssl.h @@ -0,0 +1,559 @@ + +#ifndef _COPENSSL_H_ +#define _COPENSSL_H_ + +#include "../conf.h" +#include "../ssl.h" +#include "../err.h" +#include "../x509.h" +#include "../x509v3.h" +#include "../sha.h" +#include "../md5.h" +#include "../bio.h" +#include "../hmac.h" +#include "../rand.h" +#include "../cms.h" +#include "../evp.h" + +static int copenssl_EVP_MD_size(const EVP_MD *md) { + return EVP_MD_size(md); +} +static int copenssl_EVP_CIPHER_block_size(const EVP_CIPHER *cipher) { + return EVP_CIPHER_block_size(cipher); +} +static int copenssl_EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { + return EVP_CIPHER_key_length(cipher); +} +static int copenssl_EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { + return EVP_CIPHER_iv_length(cipher); +} +static EVP_MD_CTX * copenssl_EVP_MD_CTX_create() { + return EVP_MD_CTX_create(); +} + +static void copenssl_EVP_MD_CTX_destroy(EVP_MD_CTX * ctx) { + EVP_MD_CTX_destroy(ctx); +} + +static void copenssl_SSL_library_init() { + SSL_library_init(); + ERR_load_crypto_strings(); + SSL_load_error_strings(); + OPENSSL_add_all_algorithms_conf(); +} +static size_t copenssl_stack_st_X509_NAME_num(struct stack_st_X509_NAME * p) { + return sk_X509_NAME_num(p); +} + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +static void * copenssl_CRYPTO_malloc(size_t num, const char *file, int line) { + return CRYPTO_malloc((int)num, file, line); +} +static void copenssl_CRYPTO_free(void * obj, const char *file, int line) { + CRYPTO_free(obj); +} +static void copenssl_SSL_CTX_set_options(SSL_CTX * sslCtx) { +#ifdef SSL_CTRL_SET_ECDH_AUTO + SSL_CTX_ctrl(sslCtx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL); +#endif + SSL_CTX_ctrl(sslCtx, SSL_CTRL_MODE, SSL_MODE_AUTO_RETRY, NULL); + SSL_CTX_ctrl(sslCtx, SSL_CTRL_OPTIONS, SSL_OP_ALL, NULL); +} + +#else +static void * copenssl_CRYPTO_malloc(size_t num, const char *file, int line) { + return CRYPTO_malloc(num, file, line); +} +static void copenssl_CRYPTO_free(void * obj, const char *file, int line) { + CRYPTO_free(obj, file, line); +} +static void copenssl_SSL_CTX_set_options(SSL_CTX * sslCtx) { + SSL_CTX_set_options(sslCtx, SSL_OP_ALL); +} +#undef CRYPTO_set_locking_callback +static void CRYPTO_set_locking_callback(void (*func) (int mode, int type, + const char *file, int line)) {} +#undef CRYPTO_num_locks +static int CRYPTO_num_locks(void) { + return 0; +} +#undef CRYPTO_set_id_callback +static void CRYPTO_set_id_callback(unsigned long (*func) (void)) {} +#undef SSL_CTX_get_ex_new_index +static int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) { + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, + new_func, dup_func, free_func); +} +#undef SSL_get_ex_new_index +static int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, + new_func, dup_func, free_func); +} + +struct bio_method_st {}; +struct asn1_object_st {}; +struct ASN1_ITEM_st {}; +struct asn1_pctx_st {}; +struct asn1_sctx_st {}; +struct dane_st {}; +struct bio_st {}; +struct bignum_st {}; +struct bignum_ctx {}; +struct bn_blinding_st {}; +struct bn_mont_ctx_st {}; +struct bn_recp_ctx_st {}; +struct bn_gencb_st {}; +struct evp_cipher_st {}; +struct evp_cipher_ctx_st {}; +struct evp_md_st {}; +struct evp_md_ctx_st {}; +struct evp_pkey_st {}; +struct evp_pkey_asn1_method_st {}; +struct evp_pkey_method_st {}; +struct evp_pkey_ctx_st {}; +struct evp_Encode_Ctx_st {}; +struct hmac_ctx_st {}; +struct dh_st {}; +struct dh_method {}; +struct dsa_st {}; +struct dsa_method {}; +struct rsa_st {}; +struct rsa_meth_st {}; +struct ec_key_st {}; +struct ec_key_method_st {}; +struct ssl_dane_st {}; +struct x509_st {}; +struct X509_crl_st {}; +struct x509_crl_method_st {}; +struct x509_revoked_st {}; +struct X509_name_st {}; +struct X509_pubkey_st {}; +struct x509_store_st {}; +struct x509_store_ctx_st {}; +struct x509_object_st {}; +struct x509_lookup_st {}; +struct x509_lookup_method_st {}; +struct X509_VERIFY_PARAM_st {}; +struct pkcs8_priv_key_info_st {}; +struct ossl_init_settings_st {}; +struct ui_st {}; +struct ui_method_st {}; +struct engine_st {}; +struct ssl_st {}; +struct ssl_ctx_st {}; +struct comp_ctx_st {}; +struct comp_method_st {}; +struct X509_POLICY_NODE_st {}; +struct X509_POLICY_LEVEL_st {}; +struct X509_POLICY_TREE_st {}; +struct X509_POLICY_CACHE_st {}; +struct ocsp_req_ctx_st {}; +struct ocsp_response_st {}; +struct ocsp_responder_id_st {}; +struct sct_st {}; +struct sct_ctx_st {}; +struct ctlog_st {}; +struct ctlog_store_st {}; +struct ct_policy_eval_ctx_st {}; +#endif + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +static void *OPENSSL_zalloc(size_t num) +{ + void *ret = OPENSSL_malloc(num); + + if (ret != NULL) + memset(ret, 0, num); + return ret; +} + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + /* If the fields n and e in r are NULL, the corresponding input + * parameters MUST be non-NULL for n and e. d may be + * left NULL (in case only the public key is used). + */ + if ((r->n == NULL && n == NULL) + || (r->e == NULL && e == NULL)) + return 0; + + if (n != NULL) { + BN_free(r->n); + r->n = n; + } + if (e != NULL) { + BN_free(r->e); + r->e = e; + } + if (d != NULL) { + BN_free(r->d); + r->d = d; + } + + return 1; +} + +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) +{ + /* If the fields p and q in r are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((r->p == NULL && p == NULL) + || (r->q == NULL && q == NULL)) + return 0; + + if (p != NULL) { + BN_free(r->p); + r->p = p; + } + if (q != NULL) { + BN_free(r->q); + r->q = q; + } + + return 1; +} + +int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) +{ + /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((r->dmp1 == NULL && dmp1 == NULL) + || (r->dmq1 == NULL && dmq1 == NULL) + || (r->iqmp == NULL && iqmp == NULL)) + return 0; + + if (dmp1 != NULL) { + BN_free(r->dmp1); + r->dmp1 = dmp1; + } + if (dmq1 != NULL) { + BN_free(r->dmq1); + r->dmq1 = dmq1; + } + if (iqmp != NULL) { + BN_free(r->iqmp); + r->iqmp = iqmp; + } + + return 1; +} + +void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} + +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) +{ + if (p != NULL) + *p = r->p; + if (q != NULL) + *q = r->q; +} + +void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp) +{ + if (dmp1 != NULL) + *dmp1 = r->dmp1; + if (dmq1 != NULL) + *dmq1 = r->dmq1; + if (iqmp != NULL) + *iqmp = r->iqmp; +} + +void DSA_get0_pqg(const DSA *d, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; +} + +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* If the fields p, q and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((d->p == NULL && p == NULL) + || (d->q == NULL && q == NULL) + || (d->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(d->p); + d->p = p; + } + if (q != NULL) { + BN_free(d->q); + d->q = q; + } + if (g != NULL) { + BN_free(d->g); + d->g = g; + } + + return 1; +} + +void DSA_get0_key(const DSA *d, + const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = d->pub_key; + if (priv_key != NULL) + *priv_key = d->priv_key; +} + +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) +{ + /* If the field pub_key in d is NULL, the corresponding input + * parameters MUST be non-NULL. The priv_key field may + * be left NULL. + */ + if (d->pub_key == NULL && pub_key == NULL) + return 0; + + if (pub_key != NULL) { + BN_free(d->pub_key); + d->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(d->priv_key); + d->priv_key = priv_key; + } + + return 1; +} + +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} + +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} + +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +void DH_get0_pqg(const DH *dh, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = dh->p; + if (q != NULL) + *q = dh->q; + if (g != NULL) + *g = dh->g; +} + +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* If the fields p and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. q may remain NULL. + */ + if ((dh->p == NULL && p == NULL) + || (dh->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + if (q != NULL) { + dh->length = BN_num_bits(q); + } + + return 1; +} + +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = dh->pub_key; + if (priv_key != NULL) + *priv_key = dh->priv_key; +} + +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) +{ + /* If the field pub_key in dh is NULL, the corresponding input + * parameters MUST be non-NULL. The priv_key field may + * be left NULL. + */ + if (dh->pub_key == NULL && pub_key == NULL) + return 0; + + if (pub_key != NULL) { + BN_free(dh->pub_key); + dh->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dh->priv_key); + dh->priv_key = priv_key; + } + + return 1; +} + +int DH_set_length(DH *dh, long length) +{ + dh->length = length; + return 1; +} + +const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) +{ + return ctx->iv; +} + +unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) +{ + return ctx->iv; +} + +EVP_MD_CTX *EVP_MD_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); +} + +void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) +{ + RSA_METHOD *ret; + + ret = OPENSSL_malloc(sizeof(RSA_METHOD)); + + if (ret != NULL) { + memcpy(ret, meth, sizeof(*meth)); + ret->name = OPENSSL_strdup(meth->name); + if (ret->name == NULL) { + OPENSSL_free(ret); + return NULL; + } + } + + return ret; +} + +int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) +{ + char *tmpname; + + tmpname = OPENSSL_strdup(name); + if (tmpname == NULL) { + return 0; + } + + OPENSSL_free((char *)meth->name); + meth->name = tmpname; + + return 1; +} + +int RSA_meth_set_priv_enc(RSA_METHOD *meth, + int (*priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + meth->rsa_priv_enc = priv_enc; + return 1; +} + +int RSA_meth_set_priv_dec(RSA_METHOD *meth, + int (*priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, + int padding)) +{ + meth->rsa_priv_dec = priv_dec; + return 1; +} + +int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) +{ + meth->finish = finish; + return 1; +} + +void RSA_meth_free(RSA_METHOD *meth) +{ + if (meth != NULL) { + OPENSSL_free((char *)meth->name); + OPENSSL_free(meth); + } +} + +int RSA_bits(const RSA *r) +{ + return (BN_num_bits(r->n)); +} + +RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + return NULL; + } + return pkey->pkey.rsa; +} + +#endif + +#endif diff --git a/Sources/COpenSSL/krb5_asn.c b/Sources/COpenSSL/krb5_asn.c new file mode 100644 index 00000000..6fa094c2 --- /dev/null +++ b/Sources/COpenSSL/krb5_asn.c @@ -0,0 +1,162 @@ +/* krb5_asn.c */ +/* + * Written by Vern Staats for the OpenSSL project, ** + * using ocsp/{*.h,*asn*.c} as a starting point + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include "asn1.h" +#include "asn1t.h" +#include "krb5_asn.h" + + +ASN1_SEQUENCE(KRB5_ENCDATA) = { + ASN1_EXP(KRB5_ENCDATA, etype, ASN1_INTEGER, 0), + ASN1_EXP_OPT(KRB5_ENCDATA, kvno, ASN1_INTEGER, 1), + ASN1_EXP(KRB5_ENCDATA, cipher, ASN1_OCTET_STRING,2) +} ASN1_SEQUENCE_END(KRB5_ENCDATA) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCDATA) + + +ASN1_SEQUENCE(KRB5_PRINCNAME) = { + ASN1_EXP(KRB5_PRINCNAME, nametype, ASN1_INTEGER, 0), + ASN1_EXP_SEQUENCE_OF(KRB5_PRINCNAME, namestring, ASN1_GENERALSTRING, 1) +} ASN1_SEQUENCE_END(KRB5_PRINCNAME) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_PRINCNAME) + +/* [APPLICATION 1] = 0x61 */ +ASN1_SEQUENCE(KRB5_TKTBODY) = { + ASN1_EXP(KRB5_TKTBODY, tktvno, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_TKTBODY, realm, ASN1_GENERALSTRING, 1), + ASN1_EXP(KRB5_TKTBODY, sname, KRB5_PRINCNAME, 2), + ASN1_EXP(KRB5_TKTBODY, encdata, KRB5_ENCDATA, 3) +} ASN1_SEQUENCE_END(KRB5_TKTBODY) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_TKTBODY) + + +ASN1_ITEM_TEMPLATE(KRB5_TICKET) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 1, + KRB5_TICKET, KRB5_TKTBODY) +ASN1_ITEM_TEMPLATE_END(KRB5_TICKET) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_TICKET) + +/* [APPLICATION 14] = 0x6e */ +ASN1_SEQUENCE(KRB5_APREQBODY) = { + ASN1_EXP(KRB5_APREQBODY, pvno, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_APREQBODY, msgtype, ASN1_INTEGER, 1), + ASN1_EXP(KRB5_APREQBODY, apoptions, ASN1_BIT_STRING, 2), + ASN1_EXP(KRB5_APREQBODY, ticket, KRB5_TICKET, 3), + ASN1_EXP(KRB5_APREQBODY, authenticator, KRB5_ENCDATA, 4), +} ASN1_SEQUENCE_END(KRB5_APREQBODY) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQBODY) + +ASN1_ITEM_TEMPLATE(KRB5_APREQ) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 14, + KRB5_APREQ, KRB5_APREQBODY) +ASN1_ITEM_TEMPLATE_END(KRB5_APREQ) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQ) + +/* Authenticator stuff */ + +ASN1_SEQUENCE(KRB5_CHECKSUM) = { + ASN1_EXP(KRB5_CHECKSUM, ctype, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_CHECKSUM, checksum, ASN1_OCTET_STRING,1) +} ASN1_SEQUENCE_END(KRB5_CHECKSUM) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_CHECKSUM) + + +ASN1_SEQUENCE(KRB5_ENCKEY) = { + ASN1_EXP(KRB5_ENCKEY, ktype, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_ENCKEY, keyvalue, ASN1_OCTET_STRING,1) +} ASN1_SEQUENCE_END(KRB5_ENCKEY) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCKEY) + +/* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */ +ASN1_SEQUENCE(KRB5_AUTHDATA) = { + ASN1_EXP(KRB5_AUTHDATA, adtype, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_AUTHDATA, addata, ASN1_OCTET_STRING,1) +} ASN1_SEQUENCE_END(KRB5_AUTHDATA) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHDATA) + +/* [APPLICATION 2] = 0x62 */ +ASN1_SEQUENCE(KRB5_AUTHENTBODY) = { + ASN1_EXP(KRB5_AUTHENTBODY, avno, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_AUTHENTBODY, crealm, ASN1_GENERALSTRING, 1), + ASN1_EXP(KRB5_AUTHENTBODY, cname, KRB5_PRINCNAME, 2), + ASN1_EXP_OPT(KRB5_AUTHENTBODY, cksum, KRB5_CHECKSUM, 3), + ASN1_EXP(KRB5_AUTHENTBODY, cusec, ASN1_INTEGER, 4), + ASN1_EXP(KRB5_AUTHENTBODY, ctime, ASN1_GENERALIZEDTIME, 5), + ASN1_EXP_OPT(KRB5_AUTHENTBODY, subkey, KRB5_ENCKEY, 6), + ASN1_EXP_OPT(KRB5_AUTHENTBODY, seqnum, ASN1_INTEGER, 7), + ASN1_EXP_SEQUENCE_OF_OPT + (KRB5_AUTHENTBODY, authorization, KRB5_AUTHDATA, 8), +} ASN1_SEQUENCE_END(KRB5_AUTHENTBODY) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) + +ASN1_ITEM_TEMPLATE(KRB5_AUTHENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 2, + KRB5_AUTHENT, KRB5_AUTHENTBODY) +ASN1_ITEM_TEMPLATE_END(KRB5_AUTHENT) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENT) diff --git a/Sources/COpenSSL/krb5_asn.h b/Sources/COpenSSL/krb5_asn.h new file mode 100644 index 00000000..9fd6720c --- /dev/null +++ b/Sources/COpenSSL/krb5_asn.h @@ -0,0 +1,240 @@ +/* krb5_asn.h */ +/* + * Written by Vern Staats for the OpenSSL project, ** + * using ocsp/{*.h,*asn*.c} as a starting point + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_KRB5_ASN_H +# define HEADER_KRB5_ASN_H + +/* + * #include + */ +# include "safestack.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ASN.1 from Kerberos RFC 1510 + */ + +/*- EncryptedData ::= SEQUENCE { + * etype[0] INTEGER, -- EncryptionType + * kvno[1] INTEGER OPTIONAL, + * cipher[2] OCTET STRING -- ciphertext + * } + */ +typedef struct krb5_encdata_st { + ASN1_INTEGER *etype; + ASN1_INTEGER *kvno; + ASN1_OCTET_STRING *cipher; +} KRB5_ENCDATA; + +DECLARE_STACK_OF(KRB5_ENCDATA) + +/*- PrincipalName ::= SEQUENCE { + * name-type[0] INTEGER, + * name-string[1] SEQUENCE OF GeneralString + * } + */ +typedef struct krb5_princname_st { + ASN1_INTEGER *nametype; + STACK_OF(ASN1_GENERALSTRING) *namestring; +} KRB5_PRINCNAME; + +DECLARE_STACK_OF(KRB5_PRINCNAME) + +/*- Ticket ::= [APPLICATION 1] SEQUENCE { + * tkt-vno[0] INTEGER, + * realm[1] Realm, + * sname[2] PrincipalName, + * enc-part[3] EncryptedData + * } + */ +typedef struct krb5_tktbody_st { + ASN1_INTEGER *tktvno; + ASN1_GENERALSTRING *realm; + KRB5_PRINCNAME *sname; + KRB5_ENCDATA *encdata; +} KRB5_TKTBODY; + +typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET; +DECLARE_STACK_OF(KRB5_TKTBODY) + +/*- AP-REQ ::= [APPLICATION 14] SEQUENCE { + * pvno[0] INTEGER, + * msg-type[1] INTEGER, + * ap-options[2] APOptions, + * ticket[3] Ticket, + * authenticator[4] EncryptedData + * } + * + * APOptions ::= BIT STRING { + * reserved(0), use-session-key(1), mutual-required(2) } + */ +typedef struct krb5_ap_req_st { + ASN1_INTEGER *pvno; + ASN1_INTEGER *msgtype; + ASN1_BIT_STRING *apoptions; + KRB5_TICKET *ticket; + KRB5_ENCDATA *authenticator; +} KRB5_APREQBODY; + +typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ; +DECLARE_STACK_OF(KRB5_APREQBODY) + +/* Authenticator Stuff */ + +/*- Checksum ::= SEQUENCE { + * cksumtype[0] INTEGER, + * checksum[1] OCTET STRING + * } + */ +typedef struct krb5_checksum_st { + ASN1_INTEGER *ctype; + ASN1_OCTET_STRING *checksum; +} KRB5_CHECKSUM; + +DECLARE_STACK_OF(KRB5_CHECKSUM) + +/*- EncryptionKey ::= SEQUENCE { + * keytype[0] INTEGER, + * keyvalue[1] OCTET STRING + * } + */ +typedef struct krb5_encryptionkey_st { + ASN1_INTEGER *ktype; + ASN1_OCTET_STRING *keyvalue; +} KRB5_ENCKEY; + +DECLARE_STACK_OF(KRB5_ENCKEY) + +/*- AuthorizationData ::= SEQUENCE OF SEQUENCE { + * ad-type[0] INTEGER, + * ad-data[1] OCTET STRING + * } + */ +typedef struct krb5_authorization_st { + ASN1_INTEGER *adtype; + ASN1_OCTET_STRING *addata; +} KRB5_AUTHDATA; + +DECLARE_STACK_OF(KRB5_AUTHDATA) + +/*- -- Unencrypted authenticator + * Authenticator ::= [APPLICATION 2] SEQUENCE { + * authenticator-vno[0] INTEGER, + * crealm[1] Realm, + * cname[2] PrincipalName, + * cksum[3] Checksum OPTIONAL, + * cusec[4] INTEGER, + * ctime[5] KerberosTime, + * subkey[6] EncryptionKey OPTIONAL, + * seq-number[7] INTEGER OPTIONAL, + * authorization-data[8] AuthorizationData OPTIONAL + * } + */ +typedef struct krb5_authenticator_st { + ASN1_INTEGER *avno; + ASN1_GENERALSTRING *crealm; + KRB5_PRINCNAME *cname; + KRB5_CHECKSUM *cksum; + ASN1_INTEGER *cusec; + ASN1_GENERALIZEDTIME *ctime; + KRB5_ENCKEY *subkey; + ASN1_INTEGER *seqnum; + KRB5_AUTHDATA *authorization; +} KRB5_AUTHENTBODY; + +typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT; +DECLARE_STACK_OF(KRB5_AUTHENTBODY) + +/*- DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) = + * type *name##_new(void); + * void name##_free(type *a); + * DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) = + * DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) = + * type *d2i_##name(type **a, const unsigned char **in, long len); + * int i2d_##name(type *a, unsigned char **out); + * DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it + */ + +DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA) +DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME) +DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_TICKET) +DECLARE_ASN1_FUNCTIONS(KRB5_APREQ) + +DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM) +DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT) + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/kssl.c b/Sources/COpenSSL/kssl.c new file mode 100644 index 00000000..e291c1c4 --- /dev/null +++ b/Sources/COpenSSL/kssl.c @@ -0,0 +1,2271 @@ +/* ssl/kssl.c */ +/* + * Written by Vern Staats for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/*- + * ssl/kssl.c -- Routines to support (& debug) Kerberos5 auth for openssl + * + * 19990701 VRS Started. + * 200011?? Jeffrey Altman, Richard Levitte + * Generalized for Heimdal, Newer MIT, & Win32. + * Integrated into main OpenSSL 0.9.7 snapshots. + * 20010413 Simon Wilkinson, VRS + * Real RFC2712 KerberosWrapper replaces AP_REQ. + */ + +#include "opensslconf.h" + +#include + +#define KRB5_PRIVATE 1 + +#include "ssl.h" +#include "evp.h" +#include "objects.h" +#include "krb5_asn.h" +#include "o_time.h" +#include "kssl_lcl.h" + +#ifndef OPENSSL_NO_KRB5 + +# ifndef ENOMEM +# define ENOMEM KRB5KRB_ERR_GENERIC +# endif + +/* + * When OpenSSL is built on Windows, we do not want to require that + * the Kerberos DLLs be available in order for the OpenSSL DLLs to + * work. Therefore, all Kerberos routines are loaded at run time + * and we do not link to a .LIB file. + */ + +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +/* + * The purpose of the following pre-processor statements is to provide + * compatibility with different releases of MIT Kerberos for Windows. + * All versions up to 1.2 used macros. But macros do not allow for + * a binary compatible interface for DLLs. Therefore, all macros are + * being replaced by function calls. The following code will allow + * an OpenSSL DLL built on Windows to work whether or not the macro + * or function form of the routines are utilized. + */ +# ifdef krb5_cc_get_principal +# define NO_DEF_KRB5_CCACHE +# undef krb5_cc_get_principal +# endif +# define krb5_cc_get_principal kssl_krb5_cc_get_principal + +# define krb5_free_data_contents kssl_krb5_free_data_contents +# define krb5_free_context kssl_krb5_free_context +# define krb5_auth_con_free kssl_krb5_auth_con_free +# define krb5_free_principal kssl_krb5_free_principal +# define krb5_mk_req_extended kssl_krb5_mk_req_extended +# define krb5_get_credentials kssl_krb5_get_credentials +# define krb5_cc_default kssl_krb5_cc_default +# define krb5_sname_to_principal kssl_krb5_sname_to_principal +# define krb5_init_context kssl_krb5_init_context +# define krb5_free_ticket kssl_krb5_free_ticket +# define krb5_rd_req kssl_krb5_rd_req +# define krb5_kt_default kssl_krb5_kt_default +# define krb5_kt_resolve kssl_krb5_kt_resolve +/* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */ +# ifndef krb5_kt_close +# define krb5_kt_close kssl_krb5_kt_close +# endif /* krb5_kt_close */ +# ifndef krb5_kt_get_entry +# define krb5_kt_get_entry kssl_krb5_kt_get_entry +# endif /* krb5_kt_get_entry */ +# define krb5_auth_con_init kssl_krb5_auth_con_init + +# define krb5_principal_compare kssl_krb5_principal_compare +# define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part +# define krb5_timeofday kssl_krb5_timeofday +# define krb5_rc_default kssl_krb5_rc_default + +# ifdef krb5_rc_initialize +# undef krb5_rc_initialize +# endif +# define krb5_rc_initialize kssl_krb5_rc_initialize + +# ifdef krb5_rc_get_lifespan +# undef krb5_rc_get_lifespan +# endif +# define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan + +# ifdef krb5_rc_destroy +# undef krb5_rc_destroy +# endif +# define krb5_rc_destroy kssl_krb5_rc_destroy + +# define valid_cksumtype kssl_valid_cksumtype +# define krb5_checksum_size kssl_krb5_checksum_size +# define krb5_kt_free_entry kssl_krb5_kt_free_entry +# define krb5_auth_con_setrcache kssl_krb5_auth_con_setrcache +# define krb5_auth_con_getrcache kssl_krb5_auth_con_getrcache +# define krb5_get_server_rcache kssl_krb5_get_server_rcache + +/* Prototypes for built in stubs */ +void kssl_krb5_free_data_contents(krb5_context, krb5_data *); +void kssl_krb5_free_principal(krb5_context, krb5_principal); +krb5_error_code kssl_krb5_kt_resolve(krb5_context, + krb5_const char *, krb5_keytab *); +krb5_error_code kssl_krb5_kt_default(krb5_context, krb5_keytab *); +krb5_error_code kssl_krb5_free_ticket(krb5_context, krb5_ticket *); +krb5_error_code kssl_krb5_rd_req(krb5_context, krb5_auth_context *, + krb5_const krb5_data *, + krb5_const_principal, krb5_keytab, + krb5_flags *, krb5_ticket **); + +krb5_boolean kssl_krb5_principal_compare(krb5_context, krb5_const_principal, + krb5_const_principal); +krb5_error_code kssl_krb5_mk_req_extended(krb5_context, + krb5_auth_context *, + krb5_const krb5_flags, + krb5_data *, + krb5_creds *, krb5_data *); +krb5_error_code kssl_krb5_init_context(krb5_context *); +void kssl_krb5_free_context(krb5_context); +krb5_error_code kssl_krb5_cc_default(krb5_context, krb5_ccache *); +krb5_error_code kssl_krb5_sname_to_principal(krb5_context, + krb5_const char *, + krb5_const char *, + krb5_int32, krb5_principal *); +krb5_error_code kssl_krb5_get_credentials(krb5_context, + krb5_const krb5_flags, + krb5_ccache, + krb5_creds *, krb5_creds * *); +krb5_error_code kssl_krb5_auth_con_init(krb5_context, krb5_auth_context *); +krb5_error_code kssl_krb5_cc_get_principal(krb5_context context, + krb5_ccache cache, + krb5_principal *principal); +krb5_error_code kssl_krb5_auth_con_free(krb5_context, krb5_auth_context); +size_t kssl_krb5_checksum_size(krb5_context context, krb5_cksumtype ctype); +krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype); +krb5_error_code krb5_kt_free_entry(krb5_context, krb5_keytab_entry FAR *); +krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context, + krb5_auth_context, krb5_rcache); +krb5_error_code kssl_krb5_get_server_rcache(krb5_context, + krb5_const krb5_data *, + krb5_rcache *); +krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context, + krb5_auth_context, + krb5_rcache *); + +/* Function pointers (almost all Kerberos functions are _stdcall) */ +static void (_stdcall *p_krb5_free_data_contents) (krb5_context, krb5_data *) + = NULL; +static void (_stdcall *p_krb5_free_principal) (krb5_context, krb5_principal) + = NULL; +static krb5_error_code(_stdcall *p_krb5_kt_resolve) + (krb5_context, krb5_const char *, krb5_keytab *) = NULL; +static krb5_error_code(_stdcall *p_krb5_kt_default) (krb5_context, + krb5_keytab *) = NULL; +static krb5_error_code(_stdcall *p_krb5_free_ticket) (krb5_context, + krb5_ticket *) = NULL; +static krb5_error_code(_stdcall *p_krb5_rd_req) (krb5_context, + krb5_auth_context *, + krb5_const krb5_data *, + krb5_const_principal, + krb5_keytab, krb5_flags *, + krb5_ticket **) = NULL; +static krb5_error_code(_stdcall *p_krb5_mk_req_extended) + (krb5_context, krb5_auth_context *, + krb5_const krb5_flags, krb5_data *, krb5_creds *, krb5_data *) = NULL; +static krb5_error_code(_stdcall *p_krb5_init_context) (krb5_context *) = NULL; +static void (_stdcall *p_krb5_free_context) (krb5_context) = NULL; +static krb5_error_code(_stdcall *p_krb5_cc_default) (krb5_context, + krb5_ccache *) = NULL; +static krb5_error_code(_stdcall *p_krb5_sname_to_principal) + (krb5_context, krb5_const char *, krb5_const char *, + krb5_int32, krb5_principal *) = NULL; +static krb5_error_code(_stdcall *p_krb5_get_credentials) + (krb5_context, krb5_const krb5_flags, krb5_ccache, + krb5_creds *, krb5_creds **) = NULL; +static krb5_error_code(_stdcall *p_krb5_auth_con_init) + (krb5_context, krb5_auth_context *) = NULL; +static krb5_error_code(_stdcall *p_krb5_cc_get_principal) + (krb5_context context, krb5_ccache cache, krb5_principal *principal) = NULL; +static krb5_error_code(_stdcall *p_krb5_auth_con_free) + (krb5_context, krb5_auth_context) = NULL; +static krb5_error_code(_stdcall *p_krb5_decrypt_tkt_part) + (krb5_context, krb5_const krb5_keyblock *, krb5_ticket *) = NULL; +static krb5_error_code(_stdcall *p_krb5_timeofday) + (krb5_context context, krb5_int32 *timeret) = NULL; +static krb5_error_code(_stdcall *p_krb5_rc_default) + (krb5_context context, krb5_rcache *rc) = NULL; +static krb5_error_code(_stdcall *p_krb5_rc_initialize) + (krb5_context context, krb5_rcache rc, krb5_deltat lifespan) = NULL; +static krb5_error_code(_stdcall *p_krb5_rc_get_lifespan) + (krb5_context context, krb5_rcache rc, krb5_deltat *lifespan) = NULL; +static krb5_error_code(_stdcall *p_krb5_rc_destroy) + (krb5_context context, krb5_rcache rc) = NULL; +static krb5_boolean(_stdcall *p_krb5_principal_compare) + (krb5_context, krb5_const_principal, krb5_const_principal) = NULL; +static size_t (_stdcall *p_krb5_checksum_size) (krb5_context context, + krb5_cksumtype ctype) = NULL; +static krb5_boolean(_stdcall *p_valid_cksumtype) (krb5_cksumtype ctype) = + NULL; +static krb5_error_code(_stdcall *p_krb5_kt_free_entry) + (krb5_context, krb5_keytab_entry *) = NULL; +static krb5_error_code(_stdcall *p_krb5_auth_con_setrcache) (krb5_context, + krb5_auth_context, + krb5_rcache) = + NULL; +static krb5_error_code(_stdcall *p_krb5_get_server_rcache) (krb5_context, + krb5_const + krb5_data *, + krb5_rcache *) = + NULL; +static krb5_error_code(*p_krb5_auth_con_getrcache) (krb5_context, + krb5_auth_context, + krb5_rcache *) = NULL; +static krb5_error_code(_stdcall *p_krb5_kt_close) (krb5_context context, + krb5_keytab keytab) = NULL; +static krb5_error_code(_stdcall *p_krb5_kt_get_entry) (krb5_context context, + krb5_keytab keytab, + krb5_const_principal + principal, + krb5_kvno vno, + krb5_enctype enctype, + krb5_keytab_entry + *entry) = NULL; +static int krb5_loaded = 0; /* only attempt to initialize func ptrs once */ + +/* Function to Load the Kerberos 5 DLL and initialize function pointers */ +void load_krb5_dll(void) +{ + HANDLE hKRB5_32; + + krb5_loaded++; + hKRB5_32 = LoadLibrary(TEXT("KRB5_32")); + if (!hKRB5_32) + return; + + (FARPROC) p_krb5_free_data_contents = + GetProcAddress(hKRB5_32, "krb5_free_data_contents"); + (FARPROC) p_krb5_free_context = + GetProcAddress(hKRB5_32, "krb5_free_context"); + (FARPROC) p_krb5_auth_con_free = + GetProcAddress(hKRB5_32, "krb5_auth_con_free"); + (FARPROC) p_krb5_free_principal = + GetProcAddress(hKRB5_32, "krb5_free_principal"); + (FARPROC) p_krb5_mk_req_extended = + GetProcAddress(hKRB5_32, "krb5_mk_req_extended"); + (FARPROC) p_krb5_get_credentials = + GetProcAddress(hKRB5_32, "krb5_get_credentials"); + (FARPROC) p_krb5_cc_get_principal = + GetProcAddress(hKRB5_32, "krb5_cc_get_principal"); + (FARPROC) p_krb5_cc_default = GetProcAddress(hKRB5_32, "krb5_cc_default"); + (FARPROC) p_krb5_sname_to_principal = + GetProcAddress(hKRB5_32, "krb5_sname_to_principal"); + (FARPROC) p_krb5_init_context = + GetProcAddress(hKRB5_32, "krb5_init_context"); + (FARPROC) p_krb5_free_ticket = + GetProcAddress(hKRB5_32, "krb5_free_ticket"); + (FARPROC) p_krb5_rd_req = GetProcAddress(hKRB5_32, "krb5_rd_req"); + (FARPROC) p_krb5_principal_compare = + GetProcAddress(hKRB5_32, "krb5_principal_compare"); + (FARPROC) p_krb5_decrypt_tkt_part = + GetProcAddress(hKRB5_32, "krb5_decrypt_tkt_part"); + (FARPROC) p_krb5_timeofday = GetProcAddress(hKRB5_32, "krb5_timeofday"); + (FARPROC) p_krb5_rc_default = GetProcAddress(hKRB5_32, "krb5_rc_default"); + (FARPROC) p_krb5_rc_initialize = + GetProcAddress(hKRB5_32, "krb5_rc_initialize"); + (FARPROC) p_krb5_rc_get_lifespan = + GetProcAddress(hKRB5_32, "krb5_rc_get_lifespan"); + (FARPROC) p_krb5_rc_destroy = GetProcAddress(hKRB5_32, "krb5_rc_destroy"); + (FARPROC) p_krb5_kt_default = GetProcAddress(hKRB5_32, "krb5_kt_default"); + (FARPROC) p_krb5_kt_resolve = GetProcAddress(hKRB5_32, "krb5_kt_resolve"); + (FARPROC) p_krb5_auth_con_init = + GetProcAddress(hKRB5_32, "krb5_auth_con_init"); + (FARPROC) p_valid_cksumtype = GetProcAddress(hKRB5_32, "valid_cksumtype"); + (FARPROC) p_krb5_checksum_size = + GetProcAddress(hKRB5_32, "krb5_checksum_size"); + (FARPROC) p_krb5_kt_free_entry = + GetProcAddress(hKRB5_32, "krb5_kt_free_entry"); + (FARPROC) p_krb5_auth_con_setrcache = + GetProcAddress(hKRB5_32, "krb5_auth_con_setrcache"); + (FARPROC) p_krb5_get_server_rcache = + GetProcAddress(hKRB5_32, "krb5_get_server_rcache"); + (FARPROC) p_krb5_auth_con_getrcache = + GetProcAddress(hKRB5_32, "krb5_auth_con_getrcache"); + (FARPROC) p_krb5_kt_close = GetProcAddress(hKRB5_32, "krb5_kt_close"); + (FARPROC) p_krb5_kt_get_entry = + GetProcAddress(hKRB5_32, "krb5_kt_get_entry"); +} + +/* Stubs for each function to be dynamicly loaded */ +void kssl_krb5_free_data_contents(krb5_context CO, krb5_data *data) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_free_data_contents) + p_krb5_free_data_contents(CO, data); +} + +krb5_error_code +kssl_krb5_mk_req_extended(krb5_context CO, + krb5_auth_context *pACO, + krb5_const krb5_flags F, + krb5_data *pD1, krb5_creds *pC, krb5_data *pD2) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_mk_req_extended) + return (p_krb5_mk_req_extended(CO, pACO, F, pD1, pC, pD2)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_auth_con_init(krb5_context CO, krb5_auth_context *pACO) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_auth_con_init) + return (p_krb5_auth_con_init(CO, pACO)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_auth_con_free(krb5_context CO, krb5_auth_context ACO) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_auth_con_free) + return (p_krb5_auth_con_free(CO, ACO)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_get_credentials(krb5_context CO, + krb5_const krb5_flags F, + krb5_ccache CC, krb5_creds *pCR, krb5_creds **ppCR) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_get_credentials) + return (p_krb5_get_credentials(CO, F, CC, pCR, ppCR)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_sname_to_principal(krb5_context CO, + krb5_const char *pC1, + krb5_const char *pC2, + krb5_int32 I, krb5_principal *pPR) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_sname_to_principal) + return (p_krb5_sname_to_principal(CO, pC1, pC2, I, pPR)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_cc_default(krb5_context CO, krb5_ccache *pCC) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_cc_default) + return (p_krb5_cc_default(CO, pCC)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_init_context(krb5_context *pCO) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_init_context) + return (p_krb5_init_context(pCO)); + else + return KRB5KRB_ERR_GENERIC; +} + +void kssl_krb5_free_context(krb5_context CO) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_free_context) + p_krb5_free_context(CO); +} + +void kssl_krb5_free_principal(krb5_context c, krb5_principal p) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_free_principal) + p_krb5_free_principal(c, p); +} + +krb5_error_code +kssl_krb5_kt_resolve(krb5_context con, krb5_const char *sz, krb5_keytab *kt) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_kt_resolve) + return (p_krb5_kt_resolve(con, sz, kt)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_kt_default(krb5_context con, krb5_keytab *kt) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_kt_default) + return (p_krb5_kt_default(con, kt)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_free_ticket(krb5_context con, krb5_ticket *kt) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_free_ticket) + return (p_krb5_free_ticket(con, kt)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_rd_req(krb5_context con, krb5_auth_context *pacon, + krb5_const krb5_data *data, + krb5_const_principal princ, krb5_keytab keytab, + krb5_flags *flags, krb5_ticket **pptkt) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rd_req) + return (p_krb5_rd_req(con, pacon, data, princ, keytab, flags, pptkt)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_boolean +krb5_principal_compare(krb5_context con, krb5_const_principal princ1, + krb5_const_principal princ2) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_principal_compare) + return (p_krb5_principal_compare(con, princ1, princ2)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +krb5_decrypt_tkt_part(krb5_context con, krb5_const krb5_keyblock *keys, + krb5_ticket *ticket) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_decrypt_tkt_part) + return (p_krb5_decrypt_tkt_part(con, keys, ticket)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code krb5_timeofday(krb5_context con, krb5_int32 *timeret) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_timeofday) + return (p_krb5_timeofday(con, timeret)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code krb5_rc_default(krb5_context con, krb5_rcache *rc) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rc_default) + return (p_krb5_rc_default(con, rc)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +krb5_rc_initialize(krb5_context con, krb5_rcache rc, krb5_deltat lifespan) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rc_initialize) + return (p_krb5_rc_initialize(con, rc, lifespan)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +krb5_rc_get_lifespan(krb5_context con, krb5_rcache rc, krb5_deltat *lifespanp) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rc_get_lifespan) + return (p_krb5_rc_get_lifespan(con, rc, lifespanp)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code krb5_rc_destroy(krb5_context con, krb5_rcache rc) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rc_destroy) + return (p_krb5_rc_destroy(con, rc)); + else + return KRB5KRB_ERR_GENERIC; +} + +size_t krb5_checksum_size(krb5_context context, krb5_cksumtype ctype) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_checksum_size) + return (p_krb5_checksum_size(context, ctype)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_boolean valid_cksumtype(krb5_cksumtype ctype) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_valid_cksumtype) + return (p_valid_cksumtype(ctype)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code krb5_kt_free_entry(krb5_context con, krb5_keytab_entry *entry) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_kt_free_entry) + return (p_krb5_kt_free_entry(con, entry)); + else + return KRB5KRB_ERR_GENERIC; +} + +/* Structure definitions */ +# ifndef NO_DEF_KRB5_CCACHE +# ifndef krb5_x +# define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1)) +# define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0)) +# endif + +typedef krb5_pointer krb5_cc_cursor; /* cursor for sequential lookup */ + +typedef struct _krb5_ccache { + krb5_magic magic; + struct _krb5_cc_ops FAR *ops; + krb5_pointer data; +} *krb5_ccache; + +typedef struct _krb5_cc_ops { + krb5_magic magic; + char *prefix; + char *(KRB5_CALLCONV *get_name) + (krb5_context, krb5_ccache); + krb5_error_code(KRB5_CALLCONV *resolve) + (krb5_context, krb5_ccache *, const char *); + krb5_error_code(KRB5_CALLCONV *gen_new) + (krb5_context, krb5_ccache *); + krb5_error_code(KRB5_CALLCONV *init) + (krb5_context, krb5_ccache, krb5_principal); + krb5_error_code(KRB5_CALLCONV *destroy) + (krb5_context, krb5_ccache); + krb5_error_code(KRB5_CALLCONV *close) + (krb5_context, krb5_ccache); + krb5_error_code(KRB5_CALLCONV *store) + (krb5_context, krb5_ccache, krb5_creds *); + krb5_error_code(KRB5_CALLCONV *retrieve) + (krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *); + krb5_error_code(KRB5_CALLCONV *get_princ) + (krb5_context, krb5_ccache, krb5_principal *); + krb5_error_code(KRB5_CALLCONV *get_first) + (krb5_context, krb5_ccache, krb5_cc_cursor *); + krb5_error_code(KRB5_CALLCONV *get_next) + (krb5_context, krb5_ccache, krb5_cc_cursor *, krb5_creds *); + krb5_error_code(KRB5_CALLCONV *end_get) + (krb5_context, krb5_ccache, krb5_cc_cursor *); + krb5_error_code(KRB5_CALLCONV *remove_cred) + (krb5_context, krb5_ccache, krb5_flags, krb5_creds *); + krb5_error_code(KRB5_CALLCONV *set_flags) + (krb5_context, krb5_ccache, krb5_flags); +} krb5_cc_ops; +# endif /* NO_DEF_KRB5_CCACHE */ + +krb5_error_code + kssl_krb5_cc_get_principal + (krb5_context context, krb5_ccache cache, krb5_principal *principal) { + if (p_krb5_cc_get_principal) + return (p_krb5_cc_get_principal(context, cache, principal)); + else + return (krb5_x((cache)->ops->get_princ, (context, cache, principal))); +} + +krb5_error_code +kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon, + krb5_rcache rcache) +{ + if (p_krb5_auth_con_setrcache) + return (p_krb5_auth_con_setrcache(con, acon, rcache)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data *data, + krb5_rcache *rcache) +{ + if (p_krb5_get_server_rcache) + return (p_krb5_get_server_rcache(con, data, rcache)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon, + krb5_rcache *prcache) +{ + if (p_krb5_auth_con_getrcache) + return (p_krb5_auth_con_getrcache(con, acon, prcache)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab) +{ + if (p_krb5_kt_close) + return (p_krb5_kt_close(context, keytab)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, + krb5_const_principal principal, krb5_kvno vno, + krb5_enctype enctype, krb5_keytab_entry *entry) +{ + if (p_krb5_kt_get_entry) + return (p_krb5_kt_get_entry + (context, keytab, principal, vno, enctype, entry)); + else + return KRB5KRB_ERR_GENERIC; +} +# endif /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */ + +/* + * memory allocation functions for non-temporary storage (e.g. stuff that + * gets saved into the kssl context) + */ +static void *kssl_calloc(size_t nmemb, size_t size) +{ + void *p; + + p = OPENSSL_malloc(nmemb * size); + if (p) { + memset(p, 0, nmemb * size); + } + return p; +} + +# define kssl_malloc(size) OPENSSL_malloc((size)) +# define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size) +# define kssl_free(ptr) OPENSSL_free((ptr)) + +char +*kstring(char *string) +{ + static char *null = "[NULL]"; + + return ((string == NULL) ? null : string); +} + +/* + * Given KRB5 enctype (basically DES or 3DES), return closest match openssl + * EVP_ encryption algorithm. Return NULL for unknown or problematic + * (krb5_dk_encrypt) enctypes. Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are + * OK. + */ +const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype) +{ + switch (enctype) { + case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */ + case ENCTYPE_DES_CBC_CRC: + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + return EVP_des_cbc(); + break; + case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ + case ENCTYPE_DES3_CBC_SHA: + case ENCTYPE_DES3_CBC_RAW: + return EVP_des_ede3_cbc(); + break; + default: + return NULL; + break; + } +} + +/* + * Return true:1 if p "looks like" the start of the real authenticator + * described in kssl_skip_confound() below. The ASN.1 pattern is "62 xx 30 + * yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and xx and yy are + * possibly multi-byte length fields. + */ +static int kssl_test_confound(unsigned char *p) +{ + int len = 2; + int xx = 0, yy = 0; + + if (*p++ != 0x62) + return 0; + if (*p > 0x82) + return 0; + switch (*p) { + case 0x82: + p++; + xx = (*p++ << 8); + xx += *p++; + break; + case 0x81: + p++; + xx = *p++; + break; + case 0x80: + return 0; + default: + xx = *p++; + break; + } + if (*p++ != 0x30) + return 0; + if (*p > 0x82) + return 0; + switch (*p) { + case 0x82: + p++; + len += 2; + yy = (*p++ << 8); + yy += *p++; + break; + case 0x81: + p++; + len++; + yy = *p++; + break; + case 0x80: + return 0; + default: + yy = *p++; + break; + } + + return (xx - len == yy) ? 1 : 0; +} + +/* + * Allocate, fill, and return cksumlens array of checksum lengths. This + * array holds just the unique elements from the krb5_cksumarray[]. array[n] + * == 0 signals end of data. The krb5_cksumarray[] was an internal variable + * that has since been replaced by a more general method for storing the + * data. It should not be used. Instead we use real API calls and make a + * guess for what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 + * it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. + */ +static size_t *populate_cksumlens(void) +{ + int i, j, n; + static size_t *cklens = NULL; + +# ifdef KRB5_MIT_OLD11 + n = krb5_max_cksum; +# else + n = 0x0010; +# endif /* KRB5_MIT_OLD11 */ + +# ifdef KRB5CHECKAUTH + if (!cklens && !(cklens = (size_t *)calloc(sizeof(int), n + 1))) + return NULL; + + for (i = 0; i < n; i++) { + if (!valid_cksumtype(i)) + continue; /* array has holes */ + for (j = 0; j < n; j++) { + if (cklens[j] == 0) { + cklens[j] = krb5_checksum_size(NULL, i); + break; /* krb5 elem was new: add */ + } + if (cklens[j] == krb5_checksum_size(NULL, i)) { + break; /* ignore duplicate elements */ + } + } + } +# endif /* KRB5CHECKAUTH */ + + return cklens; +} + +/*- + * Return pointer to start of real authenticator within authenticator, or + * return NULL on error. + * Decrypted authenticator looks like this: + * [0 or 8 byte confounder] [4-24 byte checksum] [real authent'r] + * This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the + * krb5_auth_con_getcksumtype() function advertised in its krb5.h. + */ +unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) +{ + int i, conlen; + size_t cklen; + static size_t *cksumlens = NULL; + unsigned char *test_auth; + + conlen = (etype) ? 8 : 0; + + if (!cksumlens && !(cksumlens = populate_cksumlens())) + return NULL; + for (i = 0; (cklen = cksumlens[i]) != 0; i++) { + test_auth = a + conlen + cklen; + if (kssl_test_confound(test_auth)) + return test_auth; + } + + return NULL; +} + +/* + * Set kssl_err error info when reason text is a simple string kssl_err = + * struct { int reason; char text[KSSL_ERR_MAX+1]; } + */ +void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text) +{ + if (kssl_err == NULL) + return; + + kssl_err->reason = reason; + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text); + return; +} + +/* + * Display contents of krb5_data struct, for debugging + */ +void print_krb5_data(char *label, krb5_data *kdata) +{ + int i; + + fprintf(stderr, "%s[%d] ", label, kdata->length); + for (i = 0; i < (int)kdata->length; i++) { + if (0 && isprint((int)kdata->data[i])) + fprintf(stderr, "%c ", kdata->data[i]); + else + fprintf(stderr, "%02x ", (unsigned char)kdata->data[i]); + } + fprintf(stderr, "\n"); +} + +/* + * Display contents of krb5_authdata struct, for debugging + */ +void print_krb5_authdata(char *label, krb5_authdata **adata) +{ + if (adata == NULL) { + fprintf(stderr, "%s, authdata==0\n", label); + return; + } + fprintf(stderr, "%s [%p]\n", label, (void *)adata); +# if 0 + { + int i; + fprintf(stderr, "%s[at%d:%d] ", label, adata->ad_type, adata->length); + for (i = 0; i < adata->length; i++) { + fprintf(stderr, (isprint(adata->contents[i])) ? "%c " : "%02x", + adata->contents[i]); + } + fprintf(stderr, "\n"); + } +# endif +} + +/* + * Display contents of krb5_keyblock struct, for debugging + */ +void print_krb5_keyblock(char *label, krb5_keyblock *keyblk) +{ + int i; + + if (keyblk == NULL) { + fprintf(stderr, "%s, keyblk==0\n", label); + return; + } +# ifdef KRB5_HEIMDAL + fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->keytype, + keyblk->keyvalue->length); + for (i = 0; i < (int)keyblk->keyvalue->length; i++) { + fprintf(stderr, "%02x", + (unsigned char *)(keyblk->keyvalue->contents)[i]); + } + fprintf(stderr, "\n"); +# else + fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->enctype, + keyblk->length); + for (i = 0; i < (int)keyblk->length; i++) { + fprintf(stderr, "%02x", keyblk->contents[i]); + } + fprintf(stderr, "\n"); +# endif +} + +/* + * Display contents of krb5_principal_data struct, for debugging + * (krb5_principal is typedef'd == krb5_principal_data *) + */ +static void print_krb5_princ(char *label, krb5_principal_data *princ) +{ + int i, ui, uj; + + fprintf(stderr, "%s principal Realm: ", label); + if (princ == NULL) + return; + for (ui = 0; ui < (int)princ->realm.length; ui++) + putchar(princ->realm.data[ui]); + fprintf(stderr, " (nametype %d) has %d strings:\n", princ->type, + princ->length); + for (i = 0; i < (int)princ->length; i++) { + fprintf(stderr, "\t%d [%d]: ", i, princ->data[i].length); + for (uj = 0; uj < (int)princ->data[i].length; uj++) { + putchar(princ->data[i].data[uj]); + } + fprintf(stderr, "\n"); + } + return; +} + +/*- Given krb5 service (typically "kssl") and hostname in kssl_ctx, + * Return encrypted Kerberos ticket for service @ hostname. + * If authenp is non-NULL, also return encrypted authenticator, + * whose data should be freed by caller. + * (Originally was: Create Kerberos AP_REQ message for SSL Client.) + * + * 19990628 VRS Started; Returns Kerberos AP_REQ message. + * 20010409 VRS Modified for RFC2712; Returns enc tkt. + * 20010606 VRS May also return optional authenticator. + */ +krb5_error_code kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, + /* + * OUT + */ krb5_data **enc_ticketp, + /* + * UPDATE + */ krb5_data *authenp, + /* + * OUT + */ KSSL_ERR *kssl_err) +{ + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + krb5_context krb5context = NULL; + krb5_auth_context krb5auth_context = NULL; + krb5_ccache krb5ccdef = NULL; + krb5_creds krb5creds, *krb5credsp = NULL; + krb5_data krb5_app_req; + + kssl_err_set(kssl_err, 0, ""); + memset((char *)&krb5creds, 0, sizeof(krb5creds)); + + if (!kssl_ctx) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n"); + goto err; + } else if (!kssl_ctx->service_host) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "kssl_ctx service_host undefined.\n"); + goto err; + } + + if ((krb5rc = krb5_init_context(&krb5context)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "krb5_init_context() fails: %d\n", krb5rc); + kssl_err->reason = SSL_R_KRB5_C_INIT; + goto err; + } + + if ((krb5rc = krb5_sname_to_principal(krb5context, + kssl_ctx->service_host, + (kssl_ctx->service_name) ? + kssl_ctx->service_name : KRB5SVC, + KRB5_NT_SRV_HST, + &krb5creds.server)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "krb5_sname_to_principal() fails for %s/%s\n", + kssl_ctx->service_host, + (kssl_ctx-> + service_name) ? kssl_ctx->service_name : KRB5SVC); + kssl_err->reason = SSL_R_KRB5_C_INIT; + goto err; + } + + if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, + "krb5_cc_default fails.\n"); + goto err; + } + + if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, + &krb5creds.client)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, + "krb5_cc_get_principal() fails.\n"); + goto err; + } + + if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, + &krb5creds, &krb5credsp)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED, + "krb5_get_credentials() fails.\n"); + goto err; + } + + *enc_ticketp = &krb5credsp->ticket; +# ifdef KRB5_HEIMDAL + kssl_ctx->enctype = krb5credsp->session.keytype; +# else + kssl_ctx->enctype = krb5credsp->keyblock.enctype; +# endif + + krb5rc = KRB5KRB_ERR_GENERIC; + /* caller should free data of krb5_app_req */ + /* + * 20010406 VRS deleted for real KerberosWrapper 20010605 VRS reinstated + * to offer Authenticator to KerberosWrapper + */ + krb5_app_req.length = 0; + if (authenp) { + krb5_data krb5in_data; + const unsigned char *p; + long arlen; + KRB5_APREQBODY *ap_req; + + authenp->length = 0; + krb5in_data.data = NULL; + krb5in_data.length = 0; + if ((krb5rc = krb5_mk_req_extended(krb5context, + &krb5auth_context, 0, &krb5in_data, + krb5credsp, &krb5_app_req)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ, + "krb5_mk_req_extended() fails.\n"); + goto err; + } + + arlen = krb5_app_req.length; + p = (unsigned char *)krb5_app_req.data; + ap_req = (KRB5_APREQBODY *)d2i_KRB5_APREQ(NULL, &p, arlen); + if (ap_req) { + authenp->length = i2d_KRB5_ENCDATA(ap_req->authenticator, NULL); + if (authenp->length && (authenp->data = malloc(authenp->length))) { + unsigned char *adp = (unsigned char *)authenp->data; + authenp->length = + i2d_KRB5_ENCDATA(ap_req->authenticator, &adp); + } + } + + if (ap_req) + KRB5_APREQ_free((KRB5_APREQ *) ap_req); + if (krb5_app_req.length) + kssl_krb5_free_data_contents(krb5context, &krb5_app_req); + } +# ifdef KRB5_HEIMDAL + if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, + "kssl_ctx_setkey() fails.\n"); + } +# else + if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, + "kssl_ctx_setkey() fails.\n"); + } +# endif + else + krb5rc = 0; + + err: +# ifdef KSSL_DEBUG + kssl_ctx_show(kssl_ctx); +# endif /* KSSL_DEBUG */ + + if (krb5creds.client) + krb5_free_principal(krb5context, krb5creds.client); + if (krb5creds.server) + krb5_free_principal(krb5context, krb5creds.server); + if (krb5auth_context) + krb5_auth_con_free(krb5context, krb5auth_context); + if (krb5context) + krb5_free_context(krb5context); + return (krb5rc); +} + +/*- + * Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. + * Return Kerberos error code and kssl_err struct on error. + * Allocates krb5_ticket and krb5_principal; caller should free these. + * + * 20010410 VRS Implemented krb5_decode_ticket() as + * old_krb5_decode_ticket(). Missing from MIT1.0.6. + * 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. + * Re-used some of the old krb5_decode_ticket() + * code here. This tkt should alloc/free just + * like the real thing. + */ +static krb5_error_code kssl_TKT2tkt( /* IN */ krb5_context krb5context, + /* + * IN + */ KRB5_TKTBODY *asn1ticket, + /* + * OUT + */ krb5_ticket **krb5ticket, + /* + * OUT + */ KSSL_ERR *kssl_err) +{ + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + krb5_ticket *new5ticket = NULL; + ASN1_GENERALSTRING *gstr_svc, *gstr_host; + + *krb5ticket = NULL; + + if (asn1ticket == NULL || asn1ticket->realm == NULL || + asn1ticket->sname == NULL || + sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Null field in asn1ticket.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + return KRB5KRB_ERR_GENERIC; + } + + if ((new5ticket = (krb5_ticket *)calloc(1, sizeof(krb5_ticket))) == NULL) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Unable to allocate new krb5_ticket.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + return ENOMEM; /* or KRB5KRB_ERR_GENERIC; */ + } + + gstr_svc = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0); + gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1); + + if ((krb5rc = kssl_build_principal_2(krb5context, + &new5ticket->server, + asn1ticket->realm->length, + (char *)asn1ticket->realm->data, + gstr_svc->length, + (char *)gstr_svc->data, + gstr_host->length, + (char *)gstr_host->data)) != 0) { + free(new5ticket); + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Error building ticket server principal.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + return krb5rc; /* or KRB5KRB_ERR_GENERIC; */ + } + + krb5_princ_type(krb5context, new5ticket->server) = + asn1ticket->sname->nametype->data[0]; + new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0]; + new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0]; + new5ticket->enc_part.ciphertext.length = + asn1ticket->encdata->cipher->length; + if ((new5ticket->enc_part.ciphertext.data = + calloc(1, asn1ticket->encdata->cipher->length)) == NULL) { + free(new5ticket); + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Error allocating cipher in krb5ticket.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + return KRB5KRB_ERR_GENERIC; + } else { + memcpy(new5ticket->enc_part.ciphertext.data, + asn1ticket->encdata->cipher->data, + asn1ticket->encdata->cipher->length); + } + + *krb5ticket = new5ticket; + return 0; +} + +/*- + * Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), + * and krb5 AP_REQ message & message length, + * Return Kerberos session key and client principle + * to SSL Server in KSSL_CTX *kssl_ctx. + * + * 19990702 VRS Started. + */ +krb5_error_code kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, + /* + * IN + */ krb5_data *indata, + /* + * OUT + */ krb5_ticket_times *ttimes, + /* + * OUT + */ KSSL_ERR *kssl_err) +{ + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + static krb5_context krb5context = NULL; + static krb5_auth_context krb5auth_context = NULL; + krb5_ticket *krb5ticket = NULL; + KRB5_TKTBODY *asn1ticket = NULL; + const unsigned char *p; + krb5_keytab krb5keytab = NULL; + krb5_keytab_entry kt_entry; + krb5_principal krb5server; + krb5_rcache rcache = NULL; + + kssl_err_set(kssl_err, 0, ""); + + if (!kssl_ctx) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n"); + goto err; + } +# ifdef KSSL_DEBUG + fprintf(stderr, "in kssl_sget_tkt(%s)\n", + kstring(kssl_ctx->service_name)); +# endif /* KSSL_DEBUG */ + + if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_init_context() fails.\n"); + goto err; + } + if (krb5auth_context && + (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_auth_con_free() fails.\n"); + goto err; + } else + krb5auth_context = NULL; + if (!krb5auth_context && + (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_auth_con_init() fails.\n"); + goto err; + } + + if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context, + &rcache))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_auth_con_getrcache() fails.\n"); + goto err; + } + + if ((krb5rc = krb5_sname_to_principal(krb5context, NULL, + (kssl_ctx->service_name) ? + kssl_ctx->service_name : KRB5SVC, + KRB5_NT_SRV_HST, + &krb5server)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_sname_to_principal() fails.\n"); + goto err; + } + + if (rcache == NULL) { + if ((krb5rc = krb5_get_server_rcache(krb5context, + krb5_princ_component(krb5context, + krb5server, + 0), + &rcache))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_get_server_rcache() fails.\n"); + goto err; + } + } + + if ((krb5rc = + krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_auth_con_setrcache() fails.\n"); + goto err; + } + + /* + * kssl_ctx->keytab_file == NULL ==> use Kerberos default + */ + if (kssl_ctx->keytab_file) { + krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, + &krb5keytab); + if (krb5rc) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_kt_resolve() fails.\n"); + goto err; + } + } else { + krb5rc = krb5_kt_default(krb5context, &krb5keytab); + if (krb5rc) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_kt_default() fails.\n"); + goto err; + } + } + + /*- Actual Kerberos5 krb5_recvauth() has initial conversation here + * o check KRB5_SENDAUTH_BADAUTHVERS + * unless KRB5_RECVAUTH_SKIP_VERSION + * o check KRB5_SENDAUTH_BADAPPLVERS + * o send "0" msg if all OK + */ + + /*- + * 20010411 was using AP_REQ instead of true KerberosWrapper + * + * if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, + * &krb5in_data, krb5server, krb5keytab, + * &ap_option, &krb5ticket)) != 0) { Error } + */ + + p = (unsigned char *)indata->data; + if ((asn1ticket = (KRB5_TKTBODY *)d2i_KRB5_TICKET(NULL, &p, + (long)indata->length)) + == NULL) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "d2i_KRB5_TICKET() ASN.1 decode failure.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } + + /* + * Was: krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) + */ + if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket, + kssl_err)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Error converting ASN.1 ticket to krb5_ticket.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } + + if (!krb5_principal_compare(krb5context, krb5server, krb5ticket->server)) { + krb5rc = KRB5_PRINC_NOMATCH; + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "server principal != ticket principal\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } + if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, + krb5ticket->server, + krb5ticket->enc_part.kvno, + krb5ticket->enc_part.enctype, + &kt_entry)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "krb5_kt_get_entry() fails with %x.\n", krb5rc); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } + if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key, + krb5ticket)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "krb5_decrypt_tkt_part() failed.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } else { + krb5_kt_free_entry(krb5context, &kt_entry); +# ifdef KSSL_DEBUG + { + int i; + krb5_address **paddr = krb5ticket->enc_part2->caddrs; + fprintf(stderr, "Decrypted ticket fields:\n"); + fprintf(stderr, "\tflags: %X, transit-type: %X", + krb5ticket->enc_part2->flags, + krb5ticket->enc_part2->transited.tr_type); + print_krb5_data("\ttransit-data: ", + &(krb5ticket->enc_part2->transited.tr_contents)); + fprintf(stderr, "\tcaddrs: %p, authdata: %p\n", + krb5ticket->enc_part2->caddrs, + krb5ticket->enc_part2->authorization_data); + if (paddr) { + fprintf(stderr, "\tcaddrs:\n"); + for (i = 0; paddr[i] != NULL; i++) { + krb5_data d; + d.length = paddr[i]->length; + d.data = paddr[i]->contents; + print_krb5_data("\t\tIP: ", &d); + } + } + fprintf(stderr, "\tstart/auth/end times: %d / %d / %d\n", + krb5ticket->enc_part2->times.starttime, + krb5ticket->enc_part2->times.authtime, + krb5ticket->enc_part2->times.endtime); + } +# endif /* KSSL_DEBUG */ + } + + krb5rc = KRB5_NO_TKT_SUPPLIED; + if (!krb5ticket || !krb5ticket->enc_part2 || + !krb5ticket->enc_part2->client || + !krb5ticket->enc_part2->client->data || + !krb5ticket->enc_part2->session) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, + "bad ticket from krb5_rd_req.\n"); + } else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT, + &krb5ticket->enc_part2->client->realm, + krb5ticket->enc_part2->client->data, + krb5ticket->enc_part2->client->length)) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, + "kssl_ctx_setprinc() fails.\n"); + } else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session)) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, + "kssl_ctx_setkey() fails.\n"); + } else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID) { + krb5rc = KRB5KRB_AP_ERR_TKT_INVALID; + kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, + "invalid ticket from krb5_rd_req.\n"); + } else + krb5rc = 0; + + kssl_ctx->enctype = krb5ticket->enc_part.enctype; + ttimes->authtime = krb5ticket->enc_part2->times.authtime; + ttimes->starttime = krb5ticket->enc_part2->times.starttime; + ttimes->endtime = krb5ticket->enc_part2->times.endtime; + ttimes->renew_till = krb5ticket->enc_part2->times.renew_till; + + err: +# ifdef KSSL_DEBUG + kssl_ctx_show(kssl_ctx); +# endif /* KSSL_DEBUG */ + + if (asn1ticket) + KRB5_TICKET_free((KRB5_TICKET *) asn1ticket); + if (krb5keytab) + krb5_kt_close(krb5context, krb5keytab); + if (krb5ticket) + krb5_free_ticket(krb5context, krb5ticket); + if (krb5server) + krb5_free_principal(krb5context, krb5server); + return (krb5rc); +} + +/* + * Allocate & return a new kssl_ctx struct. + */ +KSSL_CTX *kssl_ctx_new(void) +{ + return ((KSSL_CTX *)kssl_calloc(1, sizeof(KSSL_CTX))); +} + +/* + * Frees a kssl_ctx struct and any allocated memory it holds. Returns NULL. + */ +KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx) +{ + if (kssl_ctx == NULL) + return kssl_ctx; + + if (kssl_ctx->key) + OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); + if (kssl_ctx->key) + kssl_free(kssl_ctx->key); + if (kssl_ctx->client_princ) + kssl_free(kssl_ctx->client_princ); + if (kssl_ctx->service_host) + kssl_free(kssl_ctx->service_host); + if (kssl_ctx->service_name) + kssl_free(kssl_ctx->service_name); + if (kssl_ctx->keytab_file) + kssl_free(kssl_ctx->keytab_file); + + kssl_free(kssl_ctx); + return (KSSL_CTX *)NULL; +} + +/* + * Given an array of (krb5_data *) entity (and optional realm), set the plain + * (char *) client_princ or service_host member of the kssl_ctx struct. + */ +krb5_error_code +kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, + krb5_data *realm, krb5_data *entity, int nentities) +{ + char **princ; + int length; + int i; + + if (kssl_ctx == NULL || entity == NULL) + return KSSL_CTX_ERR; + + switch (which) { + case KSSL_CLIENT: + princ = &kssl_ctx->client_princ; + break; + case KSSL_SERVER: + princ = &kssl_ctx->service_host; + break; + default: + return KSSL_CTX_ERR; + break; + } + if (*princ) + kssl_free(*princ); + + /* Add up all the entity->lengths */ + length = 0; + for (i = 0; i < nentities; i++) { + length += entity[i].length; + } + /* Add in space for the '/' character(s) (if any) */ + length += nentities - 1; + /* Space for the ('@'+realm+NULL | NULL) */ + length += ((realm) ? realm->length + 2 : 1); + + if ((*princ = kssl_calloc(1, length)) == NULL) + return KSSL_CTX_ERR; + else { + for (i = 0; i < nentities; i++) { + strncat(*princ, entity[i].data, entity[i].length); + if (i < nentities - 1) { + strcat(*princ, "/"); + } + } + if (realm) { + strcat(*princ, "@"); + (void)strncat(*princ, realm->data, realm->length); + } + } + + return KSSL_CTX_OK; +} + +/*- Set one of the plain (char *) string members of the kssl_ctx struct. + * Default values should be: + * which == KSSL_SERVICE => "khost" (KRB5SVC) + * which == KSSL_KEYTAB => "/etc/krb5.keytab" (KRB5KEYTAB) + */ +krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) +{ + char **string; + + if (!kssl_ctx) + return KSSL_CTX_ERR; + + switch (which) { + case KSSL_SERVICE: + string = &kssl_ctx->service_name; + break; + case KSSL_SERVER: + string = &kssl_ctx->service_host; + break; + case KSSL_CLIENT: + string = &kssl_ctx->client_princ; + break; + case KSSL_KEYTAB: + string = &kssl_ctx->keytab_file; + break; + default: + return KSSL_CTX_ERR; + break; + } + if (*string) + kssl_free(*string); + + if (!text) { + *string = '\0'; + return KSSL_CTX_OK; + } + + if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL) + return KSSL_CTX_ERR; + else + strcpy(*string, text); + + return KSSL_CTX_OK; +} + +/* + * Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx + * struct. Clear kssl_ctx->key if Kerberos session key is NULL. + */ +krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) +{ + int length; + krb5_enctype enctype; + krb5_octet FAR *contents = NULL; + + if (!kssl_ctx) + return KSSL_CTX_ERR; + + if (kssl_ctx->key) { + OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); + kssl_free(kssl_ctx->key); + } + + if (session) { + +# ifdef KRB5_HEIMDAL + length = session->keyvalue->length; + enctype = session->keytype; + contents = session->keyvalue->contents; +# else + length = session->length; + enctype = session->enctype; + contents = session->contents; +# endif + kssl_ctx->enctype = enctype; + kssl_ctx->length = length; + } else { + kssl_ctx->enctype = ENCTYPE_UNKNOWN; + kssl_ctx->length = 0; + return KSSL_CTX_OK; + } + + if ((kssl_ctx->key = + (krb5_octet FAR *)kssl_calloc(1, kssl_ctx->length)) == NULL) { + kssl_ctx->length = 0; + return KSSL_CTX_ERR; + } else + memcpy(kssl_ctx->key, contents, length); + + return KSSL_CTX_OK; +} + +/* + * Display contents of kssl_ctx struct + */ +void kssl_ctx_show(KSSL_CTX *kssl_ctx) +{ + int i; + + printf("kssl_ctx: "); + if (kssl_ctx == NULL) { + printf("NULL\n"); + return; + } else + printf("%p\n", (void *)kssl_ctx); + + printf("\tservice:\t%s\n", + (kssl_ctx->service_name) ? kssl_ctx->service_name : "NULL"); + printf("\tclient:\t%s\n", + (kssl_ctx->client_princ) ? kssl_ctx->client_princ : "NULL"); + printf("\tserver:\t%s\n", + (kssl_ctx->service_host) ? kssl_ctx->service_host : "NULL"); + printf("\tkeytab:\t%s\n", + (kssl_ctx->keytab_file) ? kssl_ctx->keytab_file : "NULL"); + printf("\tkey [%d:%d]:\t", kssl_ctx->enctype, kssl_ctx->length); + + for (i = 0; i < kssl_ctx->length && kssl_ctx->key; i++) { + printf("%02x", kssl_ctx->key[i]); + } + printf("\n"); + return; +} + +int kssl_keytab_is_available(KSSL_CTX *kssl_ctx) +{ + krb5_context krb5context = NULL; + krb5_keytab krb5keytab = NULL; + krb5_keytab_entry entry; + krb5_principal princ = NULL; + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + int rc = 0; + + if ((krb5rc = krb5_init_context(&krb5context))) + return (0); + + /* + * kssl_ctx->keytab_file == NULL ==> use Kerberos default + */ + if (kssl_ctx->keytab_file) { + krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, + &krb5keytab); + if (krb5rc) + goto exit; + } else { + krb5rc = krb5_kt_default(krb5context, &krb5keytab); + if (krb5rc) + goto exit; + } + + /* the host key we are looking for */ + krb5rc = krb5_sname_to_principal(krb5context, NULL, + kssl_ctx-> + service_name ? kssl_ctx->service_name : + KRB5SVC, KRB5_NT_SRV_HST, &princ); + + if (krb5rc) + goto exit; + + krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ, + /* IGNORE_VNO */ + 0, + /* IGNORE_ENCTYPE */ + 0, &entry); + if (krb5rc == KRB5_KT_NOTFOUND) { + rc = 1; + goto exit; + } else if (krb5rc) + goto exit; + + krb5_kt_free_entry(krb5context, &entry); + rc = 1; + + exit: + if (krb5keytab) + krb5_kt_close(krb5context, krb5keytab); + if (princ) + krb5_free_principal(krb5context, princ); + if (krb5context) + krb5_free_context(krb5context); + return (rc); +} + +int kssl_tgt_is_available(KSSL_CTX *kssl_ctx) +{ + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + krb5_context krb5context = NULL; + krb5_ccache krb5ccdef = NULL; + krb5_creds krb5creds, *krb5credsp = NULL; + int rc = 0; + + memset((char *)&krb5creds, 0, sizeof(krb5creds)); + + if (!kssl_ctx) + return (0); + + if (!kssl_ctx->service_host) + return (0); + + if ((krb5rc = krb5_init_context(&krb5context)) != 0) + goto err; + + if ((krb5rc = krb5_sname_to_principal(krb5context, + kssl_ctx->service_host, + (kssl_ctx->service_name) ? + kssl_ctx->service_name : KRB5SVC, + KRB5_NT_SRV_HST, + &krb5creds.server)) != 0) + goto err; + + if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) + goto err; + + if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, + &krb5creds.client)) != 0) + goto err; + + if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, + &krb5creds, &krb5credsp)) != 0) + goto err; + + rc = 1; + + err: +# ifdef KSSL_DEBUG + kssl_ctx_show(kssl_ctx); +# endif /* KSSL_DEBUG */ + + if (krb5creds.client) + krb5_free_principal(krb5context, krb5creds.client); + if (krb5creds.server) + krb5_free_principal(krb5context, krb5creds.server); + if (krb5context) + krb5_free_context(krb5context); + return (rc); +} + +# if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32) +void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) +{ +# ifdef KRB5_HEIMDAL + data->length = 0; + if (data->data) + free(data->data); +# elif defined(KRB5_MIT_OLD11) + if (data->data) { + krb5_xfree(data->data); + data->data = 0; + } +# else + krb5_free_data_contents(NULL, data); +# endif +} +# endif +/* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */ + +/* + * Given pointers to KerberosTime and struct tm structs, convert the + * KerberosTime string to struct tm. Note that KerberosTime is a + * ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional seconds + * as defined in RFC 1510. Return pointer to the (partially) filled in + * struct tm on success, return NULL on failure. + */ +static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) +{ + char c, *p; + + if (!k_tm) + return NULL; + if (gtime == NULL || gtime->length < 14) + return NULL; + if (gtime->data == NULL) + return NULL; + + p = (char *)>ime->data[14]; + + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_sec = atoi(p); + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_min = atoi(p); + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_hour = atoi(p); + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_mday = atoi(p); + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_mon = atoi(p) - 1; + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 4; + k_tm->tm_year = atoi(p) - 1900; + *(p + 4) = c; + + return k_tm; +} + +/* + * Helper function for kssl_validate_times(). We need context->clockskew, + * but krb5_context is an opaque struct. So we try to sneek the clockskew + * out through the replay cache. If that fails just return a likely default + * (300 seconds). + */ +static krb5_deltat get_rc_clockskew(krb5_context context) +{ + krb5_rcache rc; + krb5_deltat clockskew; + + if (krb5_rc_default(context, &rc)) + return KSSL_CLOCKSKEW; + if (krb5_rc_initialize(context, rc, 0)) + return KSSL_CLOCKSKEW; + if (krb5_rc_get_lifespan(context, rc, &clockskew)) { + clockskew = KSSL_CLOCKSKEW; + } + (void)krb5_rc_destroy(context, rc); + return clockskew; +} + +/* + * kssl_validate_times() combines (and more importantly exposes) the MIT KRB5 + * internal function krb5_validate_times() and the in_clock_skew() macro. + * The authenticator client time is checked to be within clockskew secs of + * the current time and the current time is checked to be within the ticket + * start and expire times. Either check may be omitted by supplying a NULL + * value. Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. See + * Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c 20010420 VRS + */ +krb5_error_code kssl_validate_times(krb5_timestamp atime, + krb5_ticket_times *ttimes) +{ + krb5_deltat skew; + krb5_timestamp start, now; + krb5_error_code rc; + krb5_context context; + + if ((rc = krb5_init_context(&context))) + return SSL_R_KRB5_S_BAD_TICKET; + skew = get_rc_clockskew(context); + if ((rc = krb5_timeofday(context, &now))) + return SSL_R_KRB5_S_BAD_TICKET; + krb5_free_context(context); + + if (atime && labs(atime - now) >= skew) + return SSL_R_KRB5_S_TKT_SKEW; + + if (!ttimes) + return 0; + + start = (ttimes->starttime != 0) ? ttimes->starttime : ttimes->authtime; + if (start - now > skew) + return SSL_R_KRB5_S_TKT_NYV; + if ((now - ttimes->endtime) > skew) + return SSL_R_KRB5_S_TKT_EXPIRED; + +# ifdef KSSL_DEBUG + fprintf(stderr, "kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", + start, atime, now, skew, ttimes->endtime); +# endif /* KSSL_DEBUG */ + + return 0; +} + +/* + * Decode and decrypt given DER-encoded authenticator, then pass + * authenticator ctime back in *atimep (or 0 if time unavailable). Returns + * krb5_error_code and kssl_err on error. A NULL authenticator + * (authentp->length == 0) is not considered an error. Note that + * kssl_check_authent() makes use of the KRB5 session key; you must call + * kssl_sget_tkt() to get the key before calling this routine. + */ +krb5_error_code kssl_check_authent( + /* + * IN + */ KSSL_CTX *kssl_ctx, + /* + * IN + */ krb5_data *authentp, + /* + * OUT + */ krb5_timestamp *atimep, + /* + * OUT + */ KSSL_ERR *kssl_err) +{ + krb5_error_code krb5rc = 0; + KRB5_ENCDATA *dec_authent = NULL; + KRB5_AUTHENTBODY *auth = NULL; + krb5_enctype enctype; + EVP_CIPHER_CTX ciph_ctx; + const EVP_CIPHER *enc = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + const unsigned char *p; + unsigned char *unenc_authent; + int outl, unencbufsize; + struct tm tm_time, *tm_l, *tm_g; + time_t now, tl, tg, tr, tz_offset; + struct tm gmt_result = {0}; + struct tm lt_result = {0}; + + EVP_CIPHER_CTX_init(&ciph_ctx); + *atimep = 0; + kssl_err_set(kssl_err, 0, ""); + +# ifndef KRB5CHECKAUTH + authentp = NULL; +# else +# if KRB5CHECKAUTH == 0 + authentp = NULL; +# endif +# endif /* KRB5CHECKAUTH */ + + if (authentp == NULL || authentp->length == 0) + return 0; + +# ifdef KSSL_DEBUG + { + unsigned int ui; + fprintf(stderr, "kssl_check_authent: authenticator[%d]:\n", + authentp->length); + p = authentp->data; + for (ui = 0; ui < authentp->length; ui++) + fprintf(stderr, "%02x ", p[ui]); + fprintf(stderr, "\n"); + } +# endif /* KSSL_DEBUG */ + + unencbufsize = 2 * authentp->length; + if ((unenc_authent = calloc(1, unencbufsize)) == NULL) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "Unable to allocate authenticator buffer.\n"); + krb5rc = KRB5KRB_ERR_GENERIC; + goto err; + } + + p = (unsigned char *)authentp->data; + if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p, + (long)authentp->length)) == NULL) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "Error decoding authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + + enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */ +# if !defined(KRB5_MIT_OLD11) + switch (enctype) { + case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ + case ENCTYPE_DES3_CBC_SHA: + case ENCTYPE_DES3_CBC_RAW: + krb5rc = 0; /* Skip, can't handle derived keys */ + goto err; + } +# endif + enc = kssl_map_enc(enctype); + memset(iv, 0, sizeof(iv)); /* per RFC 1510 */ + + if (enc == NULL) { + /* + * Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. This + * enctype indicates the authenticator was encrypted using key-usage + * derived keys which openssl cannot decrypt. + */ + goto err; + } + + if (!EVP_CipherInit(&ciph_ctx, enc, kssl_ctx->key, iv, 0)) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "EVP_CipherInit error decrypting authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + outl = dec_authent->cipher->length; + if (!EVP_Cipher + (&ciph_ctx, unenc_authent, dec_authent->cipher->data, outl)) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "EVP_Cipher error decrypting authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + +# ifdef KSSL_DEBUG + { + int padl; + fprintf(stderr, "kssl_check_authent: decrypted authenticator[%d] =\n", + outl); + for (padl = 0; padl < outl; padl++) + fprintf(stderr, "%02x ", unenc_authent[padl]); + fprintf(stderr, "\n"); + } +# endif /* KSSL_DEBUG */ + + if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "confounded by authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + outl -= p - unenc_authent; + + if ((auth = (KRB5_AUTHENTBODY *)d2i_KRB5_AUTHENT(NULL, &p, + (long)outl)) == NULL) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "Error decoding authenticator body.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + + memset(&tm_time, 0, sizeof(struct tm)); + if (k_gmtime(auth->ctime, &tm_time) && + ((tr = mktime(&tm_time)) != (time_t)(-1))) { + now = time(&now); + tm_g = OPENSSL_gmtime(&now, &gmt_result); + +# if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && \ + !defined(OPENSSL_SYS_OS2) && !defined(OPENSSL_SYS_SUNOS) && \ + (!defined(OPENSSL_SYS_VMS) || defined(localtime_r)) + tm_l = localtime_r(&now, <_result); +# else + tm_l = localtime(&now); +# endif + + tl = mktime(tm_l); + tg = mktime(tm_g); + tz_offset = tg - tl; + + *atimep = (krb5_timestamp)(tr - tz_offset); + } +# ifdef KSSL_DEBUG + fprintf(stderr, "kssl_check_authent: returns %d for client time ", + *atimep); + if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) + fprintf(stderr, "%.*s\n", auth->ctime->length, auth->ctime->data); + else + fprintf(stderr, "NULL\n"); +# endif /* KSSL_DEBUG */ + + err: + if (auth) + KRB5_AUTHENT_free((KRB5_AUTHENT *) auth); + if (dec_authent) + KRB5_ENCDATA_free(dec_authent); + if (unenc_authent) + free(unenc_authent); + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + return krb5rc; +} + +/* + * Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host), + * because I don't know how to stub varargs. Returns krb5_error_code == + * ENOMEM on alloc error, otherwise passes back newly constructed principal, + * which should be freed by caller. + */ +krb5_error_code kssl_build_principal_2( + /* + * UPDATE + */ krb5_context context, + /* + * OUT + */ krb5_principal *princ, + /* + * IN + */ int rlen, const char *realm, + /* + * IN + */ int slen, const char *svc, + /* + * IN + */ int hlen, const char *host) +{ + krb5_data *p_data = NULL; + krb5_principal new_p = NULL; + char *new_r = NULL; + + if ((p_data = (krb5_data *)calloc(2, sizeof(krb5_data))) == NULL || + (new_p = (krb5_principal)calloc(1, sizeof(krb5_principal_data))) + == NULL) + goto err; + new_p->length = 2; + new_p->data = p_data; + + if ((new_r = calloc(1, rlen + 1)) == NULL) + goto err; + memcpy(new_r, realm, rlen); + krb5_princ_set_realm_length(context, new_p, rlen); + krb5_princ_set_realm_data(context, new_p, new_r); + + if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL) + goto err; + memcpy(new_p->data[0].data, svc, slen); + new_p->data[0].length = slen; + + if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL) + goto err; + memcpy(new_p->data[1].data, host, hlen); + new_p->data[1].length = hlen; + + krb5_princ_type(context, new_p) = KRB5_NT_UNKNOWN; + *princ = new_p; + return 0; + + err: + if (new_p && new_p[0].data) + free(new_p[0].data); + if (new_p && new_p[1].data) + free(new_p[1].data); + if (new_p) + free(new_p); + if (new_r) + free(new_r); + return ENOMEM; +} + +void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx) +{ + s->kssl_ctx = kctx; +} + +KSSL_CTX *SSL_get0_kssl_ctx(SSL *s) +{ + return s->kssl_ctx; +} + +char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx) +{ + if (kctx) + return kctx->client_princ; + return NULL; +} + +#else /* !OPENSSL_NO_KRB5 */ + +# if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS) +static void *dummy = &dummy; +# endif + +#endif /* !OPENSSL_NO_KRB5 */ diff --git a/Sources/COpenSSL/kssl.h b/Sources/COpenSSL/kssl.h new file mode 100644 index 00000000..048fc592 --- /dev/null +++ b/Sources/COpenSSL/kssl.h @@ -0,0 +1,197 @@ +/* ssl/kssl.h */ +/* + * Written by Vern Staats for the OpenSSL project + * 2000. project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + ** 19990701 VRS Started. + */ + +#ifndef KSSL_H +# define KSSL_H + +# include "opensslconf.h" + +# ifndef OPENSSL_NO_KRB5 + +# include +# include +# include +# ifdef OPENSSL_SYS_WIN32 +/* + * These can sometimes get redefined indirectly by krb5 header files after + * they get undefed in ossl_typ.h + */ +# undef X509_NAME +# undef X509_EXTENSIONS +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Depending on which KRB5 implementation used, some types from + * the other may be missing. Resolve that here and now + */ +# ifdef KRB5_HEIMDAL +typedef unsigned char krb5_octet; +# define FAR +# else + +# ifndef FAR +# define FAR +# endif + +# endif + +/*- + * Uncomment this to debug kssl problems or + * to trace usage of the Kerberos session key + * + * #define KSSL_DEBUG + */ + +# ifndef KRB5SVC +# define KRB5SVC "host" +# endif + +# ifndef KRB5KEYTAB +# define KRB5KEYTAB "/etc/krb5.keytab" +# endif + +# ifndef KRB5SENDAUTH +# define KRB5SENDAUTH 1 +# endif + +# ifndef KRB5CHECKAUTH +# define KRB5CHECKAUTH 1 +# endif + +# ifndef KSSL_CLOCKSKEW +# define KSSL_CLOCKSKEW 300; +# endif + +# define KSSL_ERR_MAX 255 +typedef struct kssl_err_st { + int reason; + char text[KSSL_ERR_MAX + 1]; +} KSSL_ERR; + +/*- Context for passing + * (1) Kerberos session key to SSL, and + * (2) Config data between application and SSL lib + */ +typedef struct kssl_ctx_st { + /* used by: disposition: */ + char *service_name; /* C,S default ok (kssl) */ + char *service_host; /* C input, REQUIRED */ + char *client_princ; /* S output from krb5 ticket */ + char *keytab_file; /* S NULL (/etc/krb5.keytab) */ + char *cred_cache; /* C NULL (default) */ + krb5_enctype enctype; + int length; + krb5_octet FAR *key; +} KSSL_CTX; + +# define KSSL_CLIENT 1 +# define KSSL_SERVER 2 +# define KSSL_SERVICE 3 +# define KSSL_KEYTAB 4 + +# define KSSL_CTX_OK 0 +# define KSSL_CTX_ERR 1 +# define KSSL_NOMEM 2 + +/* Public (for use by applications that use OpenSSL with Kerberos 5 support */ +krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text); +KSSL_CTX *kssl_ctx_new(void); +KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx); +void kssl_ctx_show(KSSL_CTX *kssl_ctx); +krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, + krb5_data *realm, krb5_data *entity, + int nentities); +krb5_error_code kssl_cget_tkt(KSSL_CTX *kssl_ctx, krb5_data **enc_tktp, + krb5_data *authenp, KSSL_ERR *kssl_err); +krb5_error_code kssl_sget_tkt(KSSL_CTX *kssl_ctx, krb5_data *indata, + krb5_ticket_times *ttimes, KSSL_ERR *kssl_err); +krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session); +void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text); +void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data); +krb5_error_code kssl_build_principal_2(krb5_context context, + krb5_principal *princ, int rlen, + const char *realm, int slen, + const char *svc, int hlen, + const char *host); +krb5_error_code kssl_validate_times(krb5_timestamp atime, + krb5_ticket_times *ttimes); +krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp, + krb5_timestamp *atimep, + KSSL_ERR *kssl_err); +unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn); + +void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx); +KSSL_CTX *SSL_get0_kssl_ctx(SSL *s); +char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx); + +#ifdef __cplusplus +} +#endif +# endif /* OPENSSL_NO_KRB5 */ +#endif /* KSSL_H */ diff --git a/Sources/COpenSSL/kssl_lcl.h b/Sources/COpenSSL/kssl_lcl.h new file mode 100644 index 00000000..52f49fa5 --- /dev/null +++ b/Sources/COpenSSL/kssl_lcl.h @@ -0,0 +1,88 @@ +/* ssl/kssl.h */ +/* + * Written by Vern Staats for the OpenSSL project + * 2000. project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef KSSL_LCL_H +# define KSSL_LCL_H + +# include "kssl.h" + +# ifndef OPENSSL_NO_KRB5 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private (internal to OpenSSL) */ +void print_krb5_data(char *label, krb5_data *kdata); +void print_krb5_authdata(char *label, krb5_authdata **adata); +void print_krb5_keyblock(char *label, krb5_keyblock *keyblk); + +char *kstring(char *string); +char *knumber(int len, krb5_octet *contents); + +const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype); + +int kssl_keytab_is_available(KSSL_CTX *kssl_ctx); +int kssl_tgt_is_available(KSSL_CTX *kssl_ctx); + +#ifdef __cplusplus +} +#endif +# endif /* OPENSSL_NO_KRB5 */ +#endif /* KSSL_LCL_H */ diff --git a/Sources/COpenSSL/lh_stats.c b/Sources/COpenSSL/lh_stats.c new file mode 100644 index 00000000..e70153a0 --- /dev/null +++ b/Sources/COpenSSL/lh_stats.c @@ -0,0 +1,246 @@ +/* crypto/lhash/lh_stats.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +/* + * If you wish to build this outside of SSLeay, remove the following lines + * and things should work as expected + */ +#include "cryptlib.h" + +#ifndef OPENSSL_NO_BIO +# include "bio.h" +#endif +#include "lhash.h" + +#ifdef OPENSSL_NO_BIO + +void lh_stats(LHASH *lh, FILE *out) +{ + fprintf(out, "num_items = %lu\n", lh->num_items); + fprintf(out, "num_nodes = %u\n", lh->num_nodes); + fprintf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); + fprintf(out, "num_expands = %lu\n", lh->num_expands); + fprintf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs); + fprintf(out, "num_contracts = %lu\n", lh->num_contracts); + fprintf(out, "num_contract_reallocs = %lu\n", lh->num_contract_reallocs); + fprintf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); + fprintf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); + fprintf(out, "num_insert = %lu\n", lh->num_insert); + fprintf(out, "num_replace = %lu\n", lh->num_replace); + fprintf(out, "num_delete = %lu\n", lh->num_delete); + fprintf(out, "num_no_delete = %lu\n", lh->num_no_delete); + fprintf(out, "num_retrieve = %lu\n", lh->num_retrieve); + fprintf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); + fprintf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); +# if 0 + fprintf(out, "p = %u\n", lh->p); + fprintf(out, "pmax = %u\n", lh->pmax); + fprintf(out, "up_load = %lu\n", lh->up_load); + fprintf(out, "down_load = %lu\n", lh->down_load); +# endif +} + +void lh_node_stats(LHASH *lh, FILE *out) +{ + LHASH_NODE *n; + unsigned int i, num; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + fprintf(out, "node %6u -> %3u\n", i, num); + } +} + +void lh_node_usage_stats(LHASH *lh, FILE *out) +{ + LHASH_NODE *n; + unsigned long num; + unsigned int i; + unsigned long total = 0, n_used = 0; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + if (num != 0) { + n_used++; + total += num; + } + } + fprintf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes); + fprintf(out, "%lu items\n", total); + if (n_used == 0) + return; + fprintf(out, "load %d.%02d actual load %d.%02d\n", + (int)(total / lh->num_nodes), + (int)((total % lh->num_nodes) * 100 / lh->num_nodes), + (int)(total / n_used), (int)((total % n_used) * 100 / n_used)); +} + +#else + +# ifndef OPENSSL_NO_FP_API +void lh_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_stats_bio(lh, bp); + BIO_free(bp); + end:; +} + +void lh_node_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_node_stats_bio(lh, bp); + BIO_free(bp); + end:; +} + +void lh_node_usage_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_node_usage_stats_bio(lh, bp); + BIO_free(bp); + end:; +} + +# endif + +void lh_stats_bio(const _LHASH *lh, BIO *out) +{ + BIO_printf(out, "num_items = %lu\n", lh->num_items); + BIO_printf(out, "num_nodes = %u\n", lh->num_nodes); + BIO_printf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); + BIO_printf(out, "num_expands = %lu\n", lh->num_expands); + BIO_printf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs); + BIO_printf(out, "num_contracts = %lu\n", lh->num_contracts); + BIO_printf(out, "num_contract_reallocs = %lu\n", + lh->num_contract_reallocs); + BIO_printf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); + BIO_printf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); + BIO_printf(out, "num_insert = %lu\n", lh->num_insert); + BIO_printf(out, "num_replace = %lu\n", lh->num_replace); + BIO_printf(out, "num_delete = %lu\n", lh->num_delete); + BIO_printf(out, "num_no_delete = %lu\n", lh->num_no_delete); + BIO_printf(out, "num_retrieve = %lu\n", lh->num_retrieve); + BIO_printf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); + BIO_printf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); +# if 0 + BIO_printf(out, "p = %u\n", lh->p); + BIO_printf(out, "pmax = %u\n", lh->pmax); + BIO_printf(out, "up_load = %lu\n", lh->up_load); + BIO_printf(out, "down_load = %lu\n", lh->down_load); +# endif +} + +void lh_node_stats_bio(const _LHASH *lh, BIO *out) +{ + LHASH_NODE *n; + unsigned int i, num; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + BIO_printf(out, "node %6u -> %3u\n", i, num); + } +} + +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out) +{ + LHASH_NODE *n; + unsigned long num; + unsigned int i; + unsigned long total = 0, n_used = 0; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + if (num != 0) { + n_used++; + total += num; + } + } + BIO_printf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes); + BIO_printf(out, "%lu items\n", total); + if (n_used == 0) + return; + BIO_printf(out, "load %d.%02d actual load %d.%02d\n", + (int)(total / lh->num_nodes), + (int)((total % lh->num_nodes) * 100 / lh->num_nodes), + (int)(total / n_used), (int)((total % n_used) * 100 / n_used)); +} + +#endif diff --git a/Sources/COpenSSL/lhash.c b/Sources/COpenSSL/lhash.c new file mode 100644 index 00000000..cd5d3682 --- /dev/null +++ b/Sources/COpenSSL/lhash.c @@ -0,0 +1,477 @@ +/* crypto/lhash/lhash.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * Code for dynamic hash table routines + * Author - Eric Young v 2.0 + * + * 2.2 eay - added #include "crypto.h" so the memory leak checking code is + * present. eay 18-Jun-98 + * + * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98 + * + * 2.0 eay - Fixed a bug that occurred when using lh_delete + * from inside lh_doall(). As entries were deleted, + * the 'table' was 'contract()ed', making some entries + * jump from the end of the table to the start, there by + * skipping the lh_doall() processing. eay - 4/12/95 + * + * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs + * were not being free()ed. 21/11/95 + * + * 1.8 eay - Put the stats routines into a separate file, lh_stats.c + * 19/09/95 + * + * 1.7 eay - Removed the fputs() for realloc failures - the code + * should silently tolerate them. I have also fixed things + * lint complained about 04/05/95 + * + * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92 + * + * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992 + * + * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91 + * + * 1.3 eay - Fixed a few lint problems 19/3/1991 + * + * 1.2 eay - Fixed lh_doall problem 13/3/1991 + * + * 1.1 eay - Added lh_doall + * + * 1.0 eay - First version + */ +#include +#include +#include +#include "crypto.h" +#include "lhash.h" + +/* + * A hashing implementation that appears to be based on the linear hashing + * alogrithm: + * https://en.wikipedia.org/wiki/Linear_hashing + * + * Litwin, Witold (1980), "Linear hashing: A new tool for file and table + * addressing", Proc. 6th Conference on Very Large Databases: 212-223 + * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf + * + * From the wikipedia article "Linear hashing is used in the BDB Berkeley + * database system, which in turn is used by many software systems such as + * OpenLDAP, using a C implementation derived from the CACM article and first + * published on the Usenet in 1988 by Esmond Pitt." + * + * The CACM paper is available here: + * https://pdfs.semanticscholar.org/ff4d/1c5deca6269cc316bfd952172284dbf610ee.pdf + */ + +const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; + +#undef MIN_NODES +#define MIN_NODES 16 +#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ +#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ + +static int expand(_LHASH *lh); +static void contract(_LHASH *lh); +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); + +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) +{ + _LHASH *ret; + int i; + + if ((ret = OPENSSL_malloc(sizeof(_LHASH))) == NULL) + goto err0; + if ((ret->b = OPENSSL_malloc(sizeof(LHASH_NODE *) * MIN_NODES)) == NULL) + goto err1; + for (i = 0; i < MIN_NODES; i++) + ret->b[i] = NULL; + ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c); + ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h); + ret->num_nodes = MIN_NODES / 2; + ret->num_alloc_nodes = MIN_NODES; + ret->p = 0; + ret->pmax = MIN_NODES / 2; + ret->up_load = UP_LOAD; + ret->down_load = DOWN_LOAD; + ret->num_items = 0; + + ret->num_expands = 0; + ret->num_expand_reallocs = 0; + ret->num_contracts = 0; + ret->num_contract_reallocs = 0; + ret->num_hash_calls = 0; + ret->num_comp_calls = 0; + ret->num_insert = 0; + ret->num_replace = 0; + ret->num_delete = 0; + ret->num_no_delete = 0; + ret->num_retrieve = 0; + ret->num_retrieve_miss = 0; + ret->num_hash_comps = 0; + + ret->error = 0; + return (ret); + err1: + OPENSSL_free(ret); + err0: + return (NULL); +} + +void lh_free(_LHASH *lh) +{ + unsigned int i; + LHASH_NODE *n, *nn; + + if (lh == NULL) + return; + + for (i = 0; i < lh->num_nodes; i++) { + n = lh->b[i]; + while (n != NULL) { + nn = n->next; + OPENSSL_free(n); + n = nn; + } + } + OPENSSL_free(lh->b); + OPENSSL_free(lh); +} + +void *lh_insert(_LHASH *lh, void *data) +{ + unsigned long hash; + LHASH_NODE *nn, **rn; + void *ret; + + lh->error = 0; + if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes) + && !expand(lh)) + return NULL; + + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + if ((nn = (LHASH_NODE *)OPENSSL_malloc(sizeof(LHASH_NODE))) == NULL) { + lh->error++; + return (NULL); + } + nn->data = data; + nn->next = NULL; +#ifndef OPENSSL_NO_HASH_COMP + nn->hash = hash; +#endif + *rn = nn; + ret = NULL; + lh->num_insert++; + lh->num_items++; + } else { /* replace same key */ + + ret = (*rn)->data; + (*rn)->data = data; + lh->num_replace++; + } + return (ret); +} + +void *lh_delete(_LHASH *lh, const void *data) +{ + unsigned long hash; + LHASH_NODE *nn, **rn; + void *ret; + + lh->error = 0; + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + lh->num_no_delete++; + return (NULL); + } else { + nn = *rn; + *rn = nn->next; + ret = nn->data; + OPENSSL_free(nn); + lh->num_delete++; + } + + lh->num_items--; + if ((lh->num_nodes > MIN_NODES) && + (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))) + contract(lh); + + return (ret); +} + +void *lh_retrieve(_LHASH *lh, const void *data) +{ + unsigned long hash; + LHASH_NODE **rn; + void *ret; + + lh->error = 0; + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + lh->num_retrieve_miss++; + return (NULL); + } else { + ret = (*rn)->data; + lh->num_retrieve++; + } + return (ret); +} + +static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, + LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) +{ + int i; + LHASH_NODE *a, *n; + + if (lh == NULL) + return; + + /* + * reverse the order so we search from 'top to bottom' We were having + * memory leaks otherwise + */ + for (i = lh->num_nodes - 1; i >= 0; i--) { + a = lh->b[i]; + while (a != NULL) { + /* + * 28/05/91 - eay - n added so items can be deleted via lh_doall + */ + /* + * 22/05/08 - ben - eh? since a is not passed, this should not be + * needed + */ + n = a->next; + if (use_arg) + func_arg(a->data, arg); + else + func(a->data); + a = n; + } + } +} + +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) +{ + doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); +} + +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) +{ + doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); +} + +static int expand(_LHASH *lh) +{ + LHASH_NODE **n, **n1, **n2, *np; + unsigned int p, pmax, nni, j; + unsigned long hash; + + nni = lh->num_alloc_nodes; + p = lh->p; + pmax = lh->pmax; + if (p + 1 >= pmax) { + j = nni * 2; + n = OPENSSL_realloc(lh->b, (int)(sizeof(LHASH_NODE *) * j)); + if (n == NULL) { + lh->error++; + return 0; + } + lh->b = n; + memset(n + nni, 0, sizeof(*n) * (j - nni)); + lh->pmax = nni; + lh->num_alloc_nodes = j; + lh->num_expand_reallocs++; + lh->p = 0; + } else { + lh->p++; + } + + lh->num_nodes++; + lh->num_expands++; + n1 = &(lh->b[p]); + n2 = &(lh->b[p + pmax]); + *n2 = NULL; + + for (np = *n1; np != NULL;) { +#ifndef OPENSSL_NO_HASH_COMP + hash = np->hash; +#else + hash = lh->hash(np->data); + lh->num_hash_calls++; +#endif + if ((hash % nni) != p) { /* move it */ + *n1 = (*n1)->next; + np->next = *n2; + *n2 = np; + } else + n1 = &((*n1)->next); + np = *n1; + } + + return 1; +} + +static void contract(_LHASH *lh) +{ + LHASH_NODE **n, *n1, *np; + + np = lh->b[lh->p + lh->pmax - 1]; + lh->b[lh->p + lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */ + if (lh->p == 0) { + n = (LHASH_NODE **)OPENSSL_realloc(lh->b, + (unsigned int)(sizeof(LHASH_NODE *) + * lh->pmax)); + if (n == NULL) { +/* fputs("realloc error in lhash",stderr); */ + lh->error++; + return; + } + lh->num_contract_reallocs++; + lh->num_alloc_nodes /= 2; + lh->pmax /= 2; + lh->p = lh->pmax - 1; + lh->b = n; + } else + lh->p--; + + lh->num_nodes--; + lh->num_contracts++; + + n1 = lh->b[(int)lh->p]; + if (n1 == NULL) + lh->b[(int)lh->p] = np; + else { + while (n1->next != NULL) + n1 = n1->next; + n1->next = np; + } +} + +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) +{ + LHASH_NODE **ret, *n1; + unsigned long hash, nn; + LHASH_COMP_FN_TYPE cf; + + hash = (*(lh->hash)) (data); + lh->num_hash_calls++; + *rhash = hash; + + nn = hash % lh->pmax; + if (nn < lh->p) + nn = hash % lh->num_alloc_nodes; + + cf = lh->comp; + ret = &(lh->b[(int)nn]); + for (n1 = *ret; n1 != NULL; n1 = n1->next) { +#ifndef OPENSSL_NO_HASH_COMP + lh->num_hash_comps++; + if (n1->hash != hash) { + ret = &(n1->next); + continue; + } +#endif + lh->num_comp_calls++; + if (cf(n1->data, data) == 0) + break; + ret = &(n1->next); + } + return (ret); +} + +/* + * The following hash seems to work very well on normal text strings no + * collisions on /usr/dict/words and it distributes on %2^n quite well, not + * as good as MD5, but still good. + */ +unsigned long lh_strhash(const char *c) +{ + unsigned long ret = 0; + long n; + unsigned long v; + int r; + + if ((c == NULL) || (*c == '\0')) + return (ret); +/*- + unsigned char b[16]; + MD5(c,strlen(c),b); + return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24)); +*/ + + n = 0x100; + while (*c) { + v = n | (*c); + n += 0x100; + r = (int)((v >> 2) ^ v) & 0x0f; + ret = (ret << r) | (ret >> (32 - r)); + ret &= 0xFFFFFFFFL; + ret ^= v * v; + c++; + } + return ((ret >> 16) ^ ret); +} + +unsigned long lh_num_items(const _LHASH *lh) +{ + return lh ? lh->num_items : 0; +} diff --git a/Sources/COpenSSL/lhash.h b/Sources/COpenSSL/lhash.h new file mode 100644 index 00000000..14aaa03a --- /dev/null +++ b/Sources/COpenSSL/lhash.h @@ -0,0 +1,240 @@ +/* crypto/lhash/lhash.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * Header for dynamic hash table routines Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +# define HEADER_LHASH_H + +# include "e_os2.h" +# ifndef OPENSSL_NO_FP_API +# include +# endif + +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st { + void *data; + struct lhash_node_st *next; +# ifndef OPENSSL_NO_HASH_COMP + unsigned long hash; +# endif +} LHASH_NODE; + +typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *); +typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *); +typedef void (*LHASH_DOALL_FN_TYPE) (void *); +typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *); + +/* + * Macros for declaring and implementing type-safe wrappers for LHASH + * callbacks. This way, callbacks can be provided to LHASH structures without + * function pointer casting and the macro-defined callbacks provide + * per-variable casting before deferring to the underlying type-specific + * callbacks. NB: It is possible to place a "static" in front of both the + * DECLARE and IMPLEMENT macros if the functions are strictly internal. + */ + +/* First: "hash" functions */ +# define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +# define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +# define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +# define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Third: "doall" functions */ +# define DECLARE_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *); +# define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *arg) { \ + o_type *a = arg; \ + name##_doall(a); } +# define LHASH_DOALL_FN(name) name##_LHASH_DOALL + +/* Fourth: "doall_arg" functions */ +# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + +typedef struct lhash_st { + LHASH_NODE **b; + LHASH_COMP_FN_TYPE comp; + LHASH_HASH_FN_TYPE hash; + unsigned int num_nodes; + unsigned int num_alloc_nodes; + unsigned int p; + unsigned int pmax; + unsigned long up_load; /* load times 256 */ + unsigned long down_load; /* load times 256 */ + unsigned long num_items; + unsigned long num_expands; + unsigned long num_expand_reallocs; + unsigned long num_contracts; + unsigned long num_contract_reallocs; + unsigned long num_hash_calls; + unsigned long num_comp_calls; + unsigned long num_insert; + unsigned long num_replace; + unsigned long num_delete; + unsigned long num_no_delete; + unsigned long num_retrieve; + unsigned long num_retrieve_miss; + unsigned long num_hash_comps; + int error; +} _LHASH; /* Do not use _LHASH directly, use LHASH_OF + * and friends */ + +# define LH_LOAD_MULT 256 + +/* + * Indicates a malloc() error in the last call, this is only bad in + * lh_insert(). + */ +# define lh_error(lh) ((lh)->error) + +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); +void lh_free(_LHASH *lh); +void *lh_insert(_LHASH *lh, void *data); +void *lh_delete(_LHASH *lh, const void *data); +void *lh_retrieve(_LHASH *lh, const void *data); +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); +unsigned long lh_strhash(const char *c); +unsigned long lh_num_items(const _LHASH *lh); + +# ifndef OPENSSL_NO_FP_API +void lh_stats(const _LHASH *lh, FILE *out); +void lh_node_stats(const _LHASH *lh, FILE *out); +void lh_node_usage_stats(const _LHASH *lh, FILE *out); +# endif + +# ifndef OPENSSL_NO_BIO +void lh_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); +# endif + +/* Type checking... */ + +# define LHASH_OF(type) struct lhash_st_##type + +# define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +# define CHECKED_LHASH_OF(type,lh) \ + ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) + +/* Define wrapper functions. */ +# define LHM_lh_new(type, name) \ + ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name))) +# define LHM_lh_error(type, lh) \ + lh_error(CHECKED_LHASH_OF(type,lh)) +# define LHM_lh_insert(type, lh, inst) \ + ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_retrieve(type, lh, inst) \ + ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_delete(type, lh, inst) \ + ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn) +# define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ + lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) +# define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh)) +# define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load) +# define LHM_lh_node_stats_bio(type, lh, out) \ + lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_node_usage_stats_bio(type, lh, out) \ + lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_stats_bio(type, lh, out) \ + lh_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh)) + +DECLARE_LHASH_OF(OPENSSL_STRING); +DECLARE_LHASH_OF(OPENSSL_CSTRING); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/m_dss.c b/Sources/COpenSSL/m_dss.c new file mode 100644 index 00000000..573497e9 --- /dev/null +++ b/Sources/COpenSSL/m_dss.c @@ -0,0 +1,104 @@ +/* crypto/evp/m_dss.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "objects.h" +#include "sha.h" +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif + +#ifndef OPENSSL_NO_SHA + +static int init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD dsa_md = { + NID_dsaWithSHA, + NID_dsaWithSHA, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_DIGEST, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_DSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_dss(void) +{ + return (&dsa_md); +} +#endif diff --git a/Sources/COpenSSL/m_dss1.c b/Sources/COpenSSL/m_dss1.c new file mode 100644 index 00000000..9ff5c9c2 --- /dev/null +++ b/Sources/COpenSSL/m_dss1.c @@ -0,0 +1,105 @@ +/* crypto/evp/m_dss1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_SHA + +# include "evp.h" +# include "objects.h" +# include "sha.h" +# ifndef OPENSSL_NO_DSA +# include "dsa.h" +# endif + +static int init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD dss1_md = { + NID_dsa, + NID_dsaWithSHA1, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_DIGEST, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_DSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_dss1(void) +{ + return (&dss1_md); +} +#endif diff --git a/Sources/COpenSSL/m_ecdsa.c b/Sources/COpenSSL/m_ecdsa.c new file mode 100644 index 00000000..5ea47a7c --- /dev/null +++ b/Sources/COpenSSL/m_ecdsa.c @@ -0,0 +1,154 @@ +/* crypto/evp/m_ecdsa.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "objects.h" +#include "x509.h" + +#ifndef OPENSSL_NO_SHA + +static int init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD ecdsa_md = { + NID_ecdsa_with_SHA1, + NID_ecdsa_with_SHA1, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_DIGEST, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_ECDSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_ecdsa(void) +{ + return (&ecdsa_md); +} +#endif diff --git a/Sources/COpenSSL/m_md2.c b/Sources/COpenSSL/m_md2.c new file mode 100644 index 00000000..484fcca8 --- /dev/null +++ b/Sources/COpenSSL/m_md2.c @@ -0,0 +1,106 @@ +/* crypto/evp/m_md2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_MD2 + +# include "evp.h" +# include "objects.h" +# include "x509.h" +# include +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif + +static int init(EVP_MD_CTX *ctx) +{ + return MD2_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MD2_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MD2_Final(md, ctx->md_data); +} + +static const EVP_MD md2_md = { + NID_md2, + NID_md2WithRSAEncryption, + MD2_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + MD2_BLOCK, + sizeof(EVP_MD *) + sizeof(MD2_CTX), +}; + +const EVP_MD *EVP_md2(void) +{ + return (&md2_md); +} +#endif diff --git a/Sources/COpenSSL/m_md4.c b/Sources/COpenSSL/m_md4.c new file mode 100644 index 00000000..7279456f --- /dev/null +++ b/Sources/COpenSSL/m_md4.c @@ -0,0 +1,108 @@ +/* crypto/evp/m_md4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_MD4 + +# include "evp.h" +# include "objects.h" +# include "x509.h" +# include "md4.h" +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif + +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return MD4_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MD4_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MD4_Final(md, ctx->md_data); +} + +static const EVP_MD md4_md = { + NID_md4, + NID_md4WithRSAEncryption, + MD4_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + MD4_CBLOCK, + sizeof(EVP_MD *) + sizeof(MD4_CTX), +}; + +const EVP_MD *EVP_md4(void) +{ + return (&md4_md); +} +#endif diff --git a/Sources/COpenSSL/m_md5.c b/Sources/COpenSSL/m_md5.c new file mode 100644 index 00000000..018892e2 --- /dev/null +++ b/Sources/COpenSSL/m_md5.c @@ -0,0 +1,107 @@ +/* crypto/evp/m_md5.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_MD5 + +# include "evp.h" +# include "objects.h" +# include "x509.h" +# include "md5.h" +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return MD5_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MD5_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MD5_Final(md, ctx->md_data); +} + +static const EVP_MD md5_md = { + NID_md5, + NID_md5WithRSAEncryption, + MD5_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + MD5_CBLOCK, + sizeof(EVP_MD *) + sizeof(MD5_CTX), +}; + +const EVP_MD *EVP_md5(void) +{ + return (&md5_md); +} +#endif diff --git a/Sources/COpenSSL/m_mdc2.c b/Sources/COpenSSL/m_mdc2.c new file mode 100644 index 00000000..877391af --- /dev/null +++ b/Sources/COpenSSL/m_mdc2.c @@ -0,0 +1,108 @@ +/* crypto/evp/m_mdc2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_MDC2 + +# include "evp.h" +# include "objects.h" +# include "x509.h" +# include "mdc2.h" +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif + +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return MDC2_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MDC2_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MDC2_Final(md, ctx->md_data); +} + +static const EVP_MD mdc2_md = { + NID_mdc2, + NID_mdc2WithRSA, + MDC2_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_ASN1_OCTET_STRING_method, + MDC2_BLOCK, + sizeof(EVP_MD *) + sizeof(MDC2_CTX), +}; + +const EVP_MD *EVP_mdc2(void) +{ + return (&mdc2_md); +} +#endif diff --git a/Sources/COpenSSL/m_null.c b/Sources/COpenSSL/m_null.c new file mode 100644 index 00000000..469afbc9 --- /dev/null +++ b/Sources/COpenSSL/m_null.c @@ -0,0 +1,98 @@ +/* crypto/evp/m_null.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "objects.h" +#include "x509.h" + +static int init(EVP_MD_CTX *ctx) +{ + return 1; +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return 1; +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return 1; +} + +static const EVP_MD null_md = { + NID_undef, + NID_undef, + 0, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_NULL_method, + 0, + sizeof(EVP_MD *), +}; + +const EVP_MD *EVP_md_null(void) +{ + return (&null_md); +} diff --git a/Sources/COpenSSL/m_ripemd.c b/Sources/COpenSSL/m_ripemd.c new file mode 100644 index 00000000..211fe7af --- /dev/null +++ b/Sources/COpenSSL/m_ripemd.c @@ -0,0 +1,107 @@ +/* crypto/evp/m_ripemd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RIPEMD + +# include "ripemd.h" +# include "evp.h" +# include "objects.h" +# include "x509.h" +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return RIPEMD160_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return RIPEMD160_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return RIPEMD160_Final(md, ctx->md_data); +} + +static const EVP_MD ripemd160_md = { + NID_ripemd160, + NID_ripemd160WithRSA, + RIPEMD160_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + RIPEMD160_CBLOCK, + sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX), +}; + +const EVP_MD *EVP_ripemd160(void) +{ + return (&ripemd160_md); +} +#endif diff --git a/Sources/COpenSSL/m_sha.c b/Sources/COpenSSL/m_sha.c new file mode 100644 index 00000000..e952f579 --- /dev/null +++ b/Sources/COpenSSL/m_sha.c @@ -0,0 +1,106 @@ +/* crypto/evp/m_sha.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0) + +# include "evp.h" +# include "objects.h" +# include "x509.h" +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return SHA_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA_Final(md, ctx->md_data); +} + +static const EVP_MD sha_md = { + NID_sha, + NID_shaWithRSAEncryption, + SHA_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_sha(void) +{ + return (&sha_md); +} +#endif diff --git a/Sources/COpenSSL/m_sha1.c b/Sources/COpenSSL/m_sha1.c new file mode 100644 index 00000000..9374ca9b --- /dev/null +++ b/Sources/COpenSSL/m_sha1.c @@ -0,0 +1,235 @@ +/* crypto/evp/m_sha1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_SHA + +# include "evp.h" +# include "objects.h" +# include "sha.h" +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif + +static int init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD sha1_md = { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_sha1(void) +{ + return (&sha1_md); +} +#endif + +#ifndef OPENSSL_NO_SHA256 +static int init224(EVP_MD_CTX *ctx) +{ + return SHA224_Init(ctx->md_data); +} + +static int init256(EVP_MD_CTX *ctx) +{ + return SHA256_Init(ctx->md_data); +} + +/* + * Even though there're separate SHA224_[Update|Final], we call + * SHA256 functions even in SHA224 context. This is what happens + * there anyway, so we can spare few CPU cycles:-) + */ +static int update256(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA256_Update(ctx->md_data, data, count); +} + +static int final256(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA256_Final(md, ctx->md_data); +} + +static const EVP_MD sha224_md = { + NID_sha224, + NID_sha224WithRSAEncryption, + SHA224_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init224, + update256, + final256, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA256_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA256_CTX), +}; + +const EVP_MD *EVP_sha224(void) +{ + return (&sha224_md); +} + +static const EVP_MD sha256_md = { + NID_sha256, + NID_sha256WithRSAEncryption, + SHA256_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init256, + update256, + final256, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA256_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA256_CTX), +}; + +const EVP_MD *EVP_sha256(void) +{ + return (&sha256_md); +} +#endif /* ifndef OPENSSL_NO_SHA256 */ + +#ifndef OPENSSL_NO_SHA512 +static int init384(EVP_MD_CTX *ctx) +{ + return SHA384_Init(ctx->md_data); +} + +static int init512(EVP_MD_CTX *ctx) +{ + return SHA512_Init(ctx->md_data); +} + +/* See comment in SHA224/256 section */ +static int update512(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA512_Update(ctx->md_data, data, count); +} + +static int final512(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA512_Final(md, ctx->md_data); +} + +static const EVP_MD sha384_md = { + NID_sha384, + NID_sha384WithRSAEncryption, + SHA384_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init384, + update512, + final512, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA512_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA512_CTX), +}; + +const EVP_MD *EVP_sha384(void) +{ + return (&sha384_md); +} + +static const EVP_MD sha512_md = { + NID_sha512, + NID_sha512WithRSAEncryption, + SHA512_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init512, + update512, + final512, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA512_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA512_CTX), +}; + +const EVP_MD *EVP_sha512(void) +{ + return (&sha512_md); +} +#endif /* ifndef OPENSSL_NO_SHA512 */ diff --git a/Sources/COpenSSL/m_sigver.c b/Sources/COpenSSL/m_sigver.c new file mode 100644 index 00000000..195111aa --- /dev/null +++ b/Sources/COpenSSL/m_sigver.c @@ -0,0 +1,203 @@ +/* m_sigver.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006,2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "objects.h" +#include "x509.h" +#include "evp_locl.h" + +static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, + int ver) +{ + if (ctx->pctx == NULL) + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + if (ctx->pctx == NULL) + return 0; + + if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { + + if (type == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) + type = EVP_get_digestbynid(def_nid); + } + + if (type == NULL) { + EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); + return 0; + } + } + + if (ver) { + if (ctx->pctx->pmeth->verifyctx_init) { + if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0) + return 0; + ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; + } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) + return 0; + } else { + if (ctx->pctx->pmeth->signctx_init) { + if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) + return 0; + ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; + } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) + return 0; + } + if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) + return 0; + if (pctx) + *pctx = ctx->pctx; + if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) + return 1; + if (!EVP_DigestInit_ex(ctx, type, e)) + return 0; + return 1; +} + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) +{ + return do_sigver_init(ctx, pctx, type, e, pkey, 0); +} + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) +{ + return do_sigver_init(ctx, pctx, type, e, pkey, 1); +} + +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen) +{ + int sctx, r = 0; + EVP_PKEY_CTX *pctx = ctx->pctx; + if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { + EVP_PKEY_CTX *dctx; + if (!sigret) + return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); + dctx = EVP_PKEY_CTX_dup(ctx->pctx); + if (!dctx) + return 0; + r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx); + EVP_PKEY_CTX_free(dctx); + return r; + } + if (pctx->pmeth->signctx) + sctx = 1; + else + sctx = 0; + if (sigret) { + EVP_MD_CTX tmp_ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + return 0; + if (sctx) + r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, + sigret, siglen, &tmp_ctx); + else + r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + if (sctx || !r) + return r; + if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) + return 0; + } else { + if (sctx) { + if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0) + return 0; + } else { + int s = EVP_MD_size(ctx->digest); + if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0) + return 0; + } + } + return 1; +} + +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, + size_t siglen) +{ + EVP_MD_CTX tmp_ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + int r; + unsigned int mdlen; + int vctx; + + if (ctx->pctx->pmeth->verifyctx) + vctx = 1; + else + vctx = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + return -1; + if (vctx) { + r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, + sig, siglen, &tmp_ctx); + } else + r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + if (vctx || !r) + return r; + return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); +} diff --git a/Sources/COpenSSL/m_wp.c b/Sources/COpenSSL/m_wp.c new file mode 100644 index 00000000..7698e0cd --- /dev/null +++ b/Sources/COpenSSL/m_wp.c @@ -0,0 +1,48 @@ +/* crypto/evp/m_wp.c */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_WHIRLPOOL + +# include "evp.h" +# include "objects.h" +# include "x509.h" +# include "whrlpool.h" +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return WHIRLPOOL_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return WHIRLPOOL_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return WHIRLPOOL_Final(md, ctx->md_data); +} + +static const EVP_MD whirlpool_md = { + NID_whirlpool, + 0, + WHIRLPOOL_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_NULL_method, + WHIRLPOOL_BBLOCK / 8, + sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX), +}; + +const EVP_MD *EVP_whirlpool(void) +{ + return (&whirlpool_md); +} +#endif diff --git a/Sources/COpenSSL/md32_common.h b/Sources/COpenSSL/md32_common.h new file mode 100644 index 00000000..ab6a5efc --- /dev/null +++ b/Sources/COpenSSL/md32_common.h @@ -0,0 +1,436 @@ +/* crypto/md32_common.h */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +/*- + * This is a generic 32 bit "collector" for message digest algorithms. + * Whenever needed it collects input character stream into chunks of + * 32 bit values and invokes a block function that performs actual hash + * calculations. + * + * Porting guide. + * + * Obligatory macros: + * + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN + * this macro defines byte order of input stream. + * HASH_CBLOCK + * size of a unit chunk HASH_BLOCK operates on. + * HASH_LONG + * has to be at lest 32 bit wide, if it's wider, then + * HASH_LONG_LOG2 *has to* be defined along + * HASH_CTX + * context structure that at least contains following + * members: + * typedef struct { + * ... + * HASH_LONG Nl,Nh; + * either { + * HASH_LONG data[HASH_LBLOCK]; + * unsigned char data[HASH_CBLOCK]; + * }; + * unsigned int num; + * ... + * } HASH_CTX; + * data[] vector is expected to be zeroed upon first call to + * HASH_UPDATE. + * HASH_UPDATE + * name of "Update" function, implemented here. + * HASH_TRANSFORM + * name of "Transform" function, implemented here. + * HASH_FINAL + * name of "Final" function, implemented here. + * HASH_BLOCK_DATA_ORDER + * name of "block" function capable of treating *unaligned* input + * message in original (data) byte order, implemented externally. + * HASH_MAKE_STRING + * macro convering context variables to an ASCII hash string. + * + * MD5 example: + * + * #define DATA_ORDER_IS_LITTLE_ENDIAN + * + * #define HASH_LONG MD5_LONG + * #define HASH_LONG_LOG2 MD5_LONG_LOG2 + * #define HASH_CTX MD5_CTX + * #define HASH_CBLOCK MD5_CBLOCK + * #define HASH_UPDATE MD5_Update + * #define HASH_TRANSFORM MD5_Transform + * #define HASH_FINAL MD5_Final + * #define HASH_BLOCK_DATA_ORDER md5_block_data_order + * + * + */ + +#include "crypto.h" + +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# error "DATA_ORDER must be defined!" +#endif + +#ifndef HASH_CBLOCK +# error "HASH_CBLOCK must be defined!" +#endif +#ifndef HASH_LONG +# error "HASH_LONG must be defined!" +#endif +#ifndef HASH_CTX +# error "HASH_CTX must be defined!" +#endif + +#ifndef HASH_UPDATE +# error "HASH_UPDATE must be defined!" +#endif +#ifndef HASH_TRANSFORM +# error "HASH_TRANSFORM must be defined!" +#endif +#ifndef HASH_FINAL +# error "HASH_FINAL must be defined!" +#endif + +#ifndef HASH_BLOCK_DATA_ORDER +# error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif + +/* + * Engage compiler specific rotate intrinsic function if available. + */ +#undef ROTATE +#ifndef PEDANTIC +# if defined(_MSC_VER) +# define ROTATE(a,n) _lrotl(a,n) +# elif defined(__ICC) +# define ROTATE(a,n) _rotl(a,n) +# elif defined(__MWERKS__) +# if defined(__POWERPC__) +# define ROTATE(a,n) __rlwinm(a,n,0,31) +# elif defined(__MC68K__) + /* Motorola specific tweak. */ +# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) +# else +# define ROTATE(a,n) __rol(a,n) +# endif +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) + /* + * Some GNU C inline assembler templates. Note that these are + * rotates by *constant* number of bits! But that's exactly + * what we need here... + * + */ +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "roll %1,%0" \ + : "=r"(ret) \ + : "I"(n), "0"((unsigned int)(a)) \ + : "cc"); \ + ret; \ + }) +# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ + defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "rlwinm %0,%1,%2,0,31" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# elif defined(__s390x__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ("rll %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# endif +# endif +#endif /* PEDANTIC */ + +#ifndef ROTATE +# define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +# ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \ + (defined(__x86_64) || defined(__x86_64__)) +# if !defined(B_ENDIAN) + /* + * This gives ~30-40% performance improvement in SHA-256 compiled + * with gcc [on P4]. Well, first macro to be frank. We can pull + * this trick on x86* platforms only, because these CPUs can fetch + * unaligned data without raising an exception. + */ +# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + (c)+=4; (l)=r; }) +# define HOST_l2c(l,c) ({ unsigned int r=(l); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + *((unsigned int *)(c))=r; (c)+=4; r; }) +# endif +# elif defined(__aarch64__) +# if defined(__BYTE_ORDER__) +# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define HOST_c2l(c,l) ({ unsigned int r; \ + asm ("rev %w0,%w1" \ + :"=r"(r) \ + :"r"(*((const unsigned int *)(c))));\ + (c)+=4; (l)=r; }) +# define HOST_l2c(l,c) ({ unsigned int r; \ + asm ("rev %w0,%w1" \ + :"=r"(r) \ + :"r"((unsigned int)(l)));\ + *((unsigned int *)(c))=r; (c)+=4; r; }) +# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l)) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l)) +# endif +# endif +# endif +# endif +# if defined(__s390__) || defined(__s390x__) +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l)) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l)) +# endif +# endif + +# ifndef HOST_c2l +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) ) ) +# endif +# ifndef HOST_l2c +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff), \ + l) +# endif + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +# ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__s390x__) +# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \ + :"=d"(l) :"m"(*(const unsigned int *)(c)));\ + (c)+=4; (l); }) +# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \ + :"=m"(*(unsigned int *)(c)) :"d"(l));\ + (c)+=4; (l); }) +# endif +# endif +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# ifndef B_ENDIAN + /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l) +# endif +# endif +# endif + +# ifndef HOST_c2l +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24) ) +# endif +# ifndef HOST_l2c +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + l) +# endif + +#endif + +/* + * Time for some action:-) + */ + +int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = data_; + unsigned char *p; + HASH_LONG l; + size_t n; + + if (len == 0) + return 1; + + l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL; + /* + * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai + * for pointing it out. + */ + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on + * 16-bit */ + c->Nl = l; + + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + memcpy(p + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER(c, p, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + /* + * We use memset rather than OPENSSL_cleanse() here deliberately. + * Using OPENSSL_cleanse() here could be a performance issue. It + * will get properly cleansed on finalisation so this isn't a + * security problem. + */ + memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ + } else { + memcpy(p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + + n = len / HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER(c, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy(p, data, len); + } + return 1; +} + +void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data) +{ + HASH_BLOCK_DATA_ORDER(c, data, 1); +} + +int HASH_FINAL(unsigned char *md, HASH_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + size_t n = c->num; + + p[n] = 0x80; /* there is always room for one */ + n++; + + if (n > (HASH_CBLOCK - 8)) { + memset(p + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER(c, p, 1); + } + memset(p + n, 0, HASH_CBLOCK - 8 - n); + + p += HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + (void)HOST_l2c(c->Nh, p); + (void)HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + (void)HOST_l2c(c->Nl, p); + (void)HOST_l2c(c->Nh, p); +#endif + p -= HASH_CBLOCK; + HASH_BLOCK_DATA_ORDER(c, p, 1); + c->num = 0; + OPENSSL_cleanse(p, HASH_CBLOCK); + +#ifndef HASH_MAKE_STRING +# error "HASH_MAKE_STRING must be defined!" +#else + HASH_MAKE_STRING(c, md); +#endif + + return 1; +} + +#ifndef MD32_REG_T +# if defined(__alpha) || defined(__sparcv9) || defined(__mips) +# define MD32_REG_T long +/* + * This comment was originaly written for MD5, which is why it + * discusses A-D. But it basically applies to all 32-bit digests, + * which is why it was moved to common header file. + * + * In case you wonder why A-D are declared as long and not + * as MD5_LONG. Doing so results in slight performance + * boost on LP64 architectures. The catch is we don't + * really care if 32 MSBs of a 64-bit register get polluted + * with eventual overflows as we *save* only 32 LSBs in + * *either* case. Now declaring 'em long excuses the compiler + * from keeping 32 MSBs zeroed resulting in 13% performance + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. + * Well, to be honest it should say that this *prevents* + * performance degradation. + * + */ +# else +/* + * Above is not absolute and there are LP64 compilers that + * generate better code if MD32_REG_T is defined int. The above + * pre-processor condition reflects the circumstances under which + * the conclusion was made and is subject to further extension. + * + */ +# define MD32_REG_T int +# endif +#endif diff --git a/Sources/COpenSSL/md4.h b/Sources/COpenSSL/md4.h new file mode 100644 index 00000000..66fa0a6f --- /dev/null +++ b/Sources/COpenSSL/md4.h @@ -0,0 +1,119 @@ +/* crypto/md4/md4.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MD4_H +# define HEADER_MD4_H + +# include "e_os2.h" +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MD4 +# error MD4 is disabled. +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! MD4_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define MD4_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define MD4_LONG unsigned long +# define MD4_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define MD4_LONG unsigned int +# endif + +# define MD4_CBLOCK 64 +# define MD4_LBLOCK (MD4_CBLOCK/4) +# define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st { + MD4_LONG A, B, C, D; + MD4_LONG Nl, Nh; + MD4_LONG data[MD4_LBLOCK]; + unsigned int num; +} MD4_CTX; + +# ifdef OPENSSL_FIPS +int private_MD4_Init(MD4_CTX *c); +# endif +int MD4_Init(MD4_CTX *c); +int MD4_Update(MD4_CTX *c, const void *data, size_t len); +int MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/md4_.c b/Sources/COpenSSL/md4_.c new file mode 100644 index 00000000..fe8c8401 --- /dev/null +++ b/Sources/COpenSSL/md4_.c @@ -0,0 +1,295 @@ +/* crypto/md4/md4_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "opensslv.h" +#include "crypto.h" +#include "md4_locl.h" + +const char MD4_version[] = "MD4" OPENSSL_VERSION_PTEXT; + +/* + * Implemented from RFC1186 The MD4 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +fips_md_init(MD4) +{ + memset(c, 0, sizeof(*c)); + c->A = INIT_DATA_A; + c->B = INIT_DATA_B; + c->C = INIT_DATA_C; + c->D = INIT_DATA_D; + return 1; +} + +#ifndef md4_block_data_order +# ifdef X +# undef X +# endif +void md4_block_data_order(MD4_CTX *c, const void *data_, size_t num) +{ + const unsigned char *data = data_; + register unsigned MD32_REG_T A, B, C, D, l; +# ifndef MD32_XARRAY + /* See comment in crypto/sha/sha_locl.h for details. */ + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# define X(i) XX##i +# else + MD4_LONG XX[MD4_LBLOCK]; +# define X(i) XX[i] +# endif + + A = c->A; + B = c->B; + C = c->C; + D = c->D; + + for (; num--;) { + (void)HOST_c2l(data, l); + X(0) = l; + (void)HOST_c2l(data, l); + X(1) = l; + /* Round 0 */ + R0(A, B, C, D, X(0), 3, 0); + (void)HOST_c2l(data, l); + X(2) = l; + R0(D, A, B, C, X(1), 7, 0); + (void)HOST_c2l(data, l); + X(3) = l; + R0(C, D, A, B, X(2), 11, 0); + (void)HOST_c2l(data, l); + X(4) = l; + R0(B, C, D, A, X(3), 19, 0); + (void)HOST_c2l(data, l); + X(5) = l; + R0(A, B, C, D, X(4), 3, 0); + (void)HOST_c2l(data, l); + X(6) = l; + R0(D, A, B, C, X(5), 7, 0); + (void)HOST_c2l(data, l); + X(7) = l; + R0(C, D, A, B, X(6), 11, 0); + (void)HOST_c2l(data, l); + X(8) = l; + R0(B, C, D, A, X(7), 19, 0); + (void)HOST_c2l(data, l); + X(9) = l; + R0(A, B, C, D, X(8), 3, 0); + (void)HOST_c2l(data, l); + X(10) = l; + R0(D, A, B, C, X(9), 7, 0); + (void)HOST_c2l(data, l); + X(11) = l; + R0(C, D, A, B, X(10), 11, 0); + (void)HOST_c2l(data, l); + X(12) = l; + R0(B, C, D, A, X(11), 19, 0); + (void)HOST_c2l(data, l); + X(13) = l; + R0(A, B, C, D, X(12), 3, 0); + (void)HOST_c2l(data, l); + X(14) = l; + R0(D, A, B, C, X(13), 7, 0); + (void)HOST_c2l(data, l); + X(15) = l; + R0(C, D, A, B, X(14), 11, 0); + R0(B, C, D, A, X(15), 19, 0); + /* Round 1 */ + R1(A, B, C, D, X(0), 3, 0x5A827999L); + R1(D, A, B, C, X(4), 5, 0x5A827999L); + R1(C, D, A, B, X(8), 9, 0x5A827999L); + R1(B, C, D, A, X(12), 13, 0x5A827999L); + R1(A, B, C, D, X(1), 3, 0x5A827999L); + R1(D, A, B, C, X(5), 5, 0x5A827999L); + R1(C, D, A, B, X(9), 9, 0x5A827999L); + R1(B, C, D, A, X(13), 13, 0x5A827999L); + R1(A, B, C, D, X(2), 3, 0x5A827999L); + R1(D, A, B, C, X(6), 5, 0x5A827999L); + R1(C, D, A, B, X(10), 9, 0x5A827999L); + R1(B, C, D, A, X(14), 13, 0x5A827999L); + R1(A, B, C, D, X(3), 3, 0x5A827999L); + R1(D, A, B, C, X(7), 5, 0x5A827999L); + R1(C, D, A, B, X(11), 9, 0x5A827999L); + R1(B, C, D, A, X(15), 13, 0x5A827999L); + /* Round 2 */ + R2(A, B, C, D, X(0), 3, 0x6ED9EBA1L); + R2(D, A, B, C, X(8), 9, 0x6ED9EBA1L); + R2(C, D, A, B, X(4), 11, 0x6ED9EBA1L); + R2(B, C, D, A, X(12), 15, 0x6ED9EBA1L); + R2(A, B, C, D, X(2), 3, 0x6ED9EBA1L); + R2(D, A, B, C, X(10), 9, 0x6ED9EBA1L); + R2(C, D, A, B, X(6), 11, 0x6ED9EBA1L); + R2(B, C, D, A, X(14), 15, 0x6ED9EBA1L); + R2(A, B, C, D, X(1), 3, 0x6ED9EBA1L); + R2(D, A, B, C, X(9), 9, 0x6ED9EBA1L); + R2(C, D, A, B, X(5), 11, 0x6ED9EBA1L); + R2(B, C, D, A, X(13), 15, 0x6ED9EBA1L); + R2(A, B, C, D, X(3), 3, 0x6ED9EBA1L); + R2(D, A, B, C, X(11), 9, 0x6ED9EBA1L); + R2(C, D, A, B, X(7), 11, 0x6ED9EBA1L); + R2(B, C, D, A, X(15), 15, 0x6ED9EBA1L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } +} +#endif +/* crypto/md4/md4_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "md4.h" +// #include "crypto.h" + +#ifdef CHARSET_EBCDIC +# include "ebcdic.h" +#endif + +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md) +{ + MD4_CTX c; + static unsigned char m[MD4_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MD4_Init(&c)) + return NULL; +#ifndef CHARSET_EBCDIC + MD4_Update(&c, d, n); +#else + { + char temp[1024]; + unsigned long chunk; + + while (n > 0) { + chunk = (n > sizeof(temp)) ? sizeof(temp) : n; + ebcdic2ascii(temp, d, chunk); + MD4_Update(&c, temp, chunk); + n -= chunk; + d += chunk; + } + } +#endif + MD4_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ + return (md); +} diff --git a/Sources/COpenSSL/md4_locl.h b/Sources/COpenSSL/md4_locl.h new file mode 100644 index 00000000..9d332d24 --- /dev/null +++ b/Sources/COpenSSL/md4_locl.h @@ -0,0 +1,113 @@ +/* crypto/md4/md4_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "opensslconf.h" +#include "md4.h" + +#ifndef MD4_LONG_LOG2 +# define MD4_LONG_LOG2 2 /* default to 32 bits */ +#endif + +void md4_block_data_order(MD4_CTX *c, const void *p, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG MD4_LONG +#define HASH_CTX MD4_CTX +#define HASH_CBLOCK MD4_CBLOCK +#define HASH_UPDATE MD4_Update +#define HASH_TRANSFORM MD4_Transform +#define HASH_FINAL MD4_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; (void)HOST_l2c(ll,(s)); \ + ll=(c)->B; (void)HOST_l2c(ll,(s)); \ + ll=(c)->C; (void)HOST_l2c(ll,(s)); \ + ll=(c)->D; (void)HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md4_block_data_order + +#include "md32_common.h" + +/*- +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (y)) | ((x) & ((z))) | ((y) & ((z)))) +*/ + +/* + * As pointed out by Wei Dai , the above can be simplified + * to the code below. Wei attributes these optimizations to Peter Gutmann's + * SHS code, and he attributes it to Rich Schroeppel. + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) +#define H(b,c,d) ((b) ^ (c) ^ (d)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); }; + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); };\ + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); }; diff --git a/Sources/COpenSSL/md5.h b/Sources/COpenSSL/md5.h new file mode 100644 index 00000000..2b8daa1f --- /dev/null +++ b/Sources/COpenSSL/md5.h @@ -0,0 +1,119 @@ +/* crypto/md5/md5.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MD5_H +# define HEADER_MD5_H + +# include "e_os2.h" +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MD5 +# error MD5 is disabled. +# endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! MD5_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define MD5_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define MD5_LONG unsigned long +# define MD5_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define MD5_LONG unsigned int +# endif + +# define MD5_CBLOCK 64 +# define MD5_LBLOCK (MD5_CBLOCK/4) +# define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st { + MD5_LONG A, B, C, D; + MD5_LONG Nl, Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; +} MD5_CTX; + +# ifdef OPENSSL_FIPS +int private_MD5_Init(MD5_CTX *c); +# endif +int MD5_Init(MD5_CTX *c); +int MD5_Update(MD5_CTX *c, const void *data, size_t len); +int MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/md5_.c b/Sources/COpenSSL/md5_.c new file mode 100644 index 00000000..1186439c --- /dev/null +++ b/Sources/COpenSSL/md5_.c @@ -0,0 +1,312 @@ +/* crypto/md5/md5_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "md5_locl.h" +#include "opensslv.h" +// #include "crypto.h" + +const char MD5_version[] = "MD5" OPENSSL_VERSION_PTEXT; + +/* + * Implemented from RFC1321 The MD5 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +fips_md_init(MD5) +{ + memset(c, 0, sizeof(*c)); + c->A = INIT_DATA_A; + c->B = INIT_DATA_B; + c->C = INIT_DATA_C; + c->D = INIT_DATA_D; + return 1; +} + +#ifndef md5_block_data_order +# ifdef X +# undef X +# endif +void md5_block_data_order(MD5_CTX *c, const void *data_, size_t num) +{ + const unsigned char *data = data_; + register unsigned MD32_REG_T A, B, C, D, l; +# ifndef MD32_XARRAY + /* See comment in crypto/sha/sha_locl.h for details. */ + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# define X(i) XX##i +# else + MD5_LONG XX[MD5_LBLOCK]; +# define X(i) XX[i] +# endif + + A = c->A; + B = c->B; + C = c->C; + D = c->D; + + for (; num--;) { + HOST_c2l(data, l); + X(0) = l; + HOST_c2l(data, l); + X(1) = l; + /* Round 0 */ + R0(A, B, C, D, X(0), 7, 0xd76aa478L); + HOST_c2l(data, l); + X(2) = l; + R0(D, A, B, C, X(1), 12, 0xe8c7b756L); + HOST_c2l(data, l); + X(3) = l; + R0(C, D, A, B, X(2), 17, 0x242070dbL); + HOST_c2l(data, l); + X(4) = l; + R0(B, C, D, A, X(3), 22, 0xc1bdceeeL); + HOST_c2l(data, l); + X(5) = l; + R0(A, B, C, D, X(4), 7, 0xf57c0fafL); + HOST_c2l(data, l); + X(6) = l; + R0(D, A, B, C, X(5), 12, 0x4787c62aL); + HOST_c2l(data, l); + X(7) = l; + R0(C, D, A, B, X(6), 17, 0xa8304613L); + HOST_c2l(data, l); + X(8) = l; + R0(B, C, D, A, X(7), 22, 0xfd469501L); + HOST_c2l(data, l); + X(9) = l; + R0(A, B, C, D, X(8), 7, 0x698098d8L); + HOST_c2l(data, l); + X(10) = l; + R0(D, A, B, C, X(9), 12, 0x8b44f7afL); + HOST_c2l(data, l); + X(11) = l; + R0(C, D, A, B, X(10), 17, 0xffff5bb1L); + HOST_c2l(data, l); + X(12) = l; + R0(B, C, D, A, X(11), 22, 0x895cd7beL); + HOST_c2l(data, l); + X(13) = l; + R0(A, B, C, D, X(12), 7, 0x6b901122L); + HOST_c2l(data, l); + X(14) = l; + R0(D, A, B, C, X(13), 12, 0xfd987193L); + HOST_c2l(data, l); + X(15) = l; + R0(C, D, A, B, X(14), 17, 0xa679438eL); + R0(B, C, D, A, X(15), 22, 0x49b40821L); + /* Round 1 */ + R1(A, B, C, D, X(1), 5, 0xf61e2562L); + R1(D, A, B, C, X(6), 9, 0xc040b340L); + R1(C, D, A, B, X(11), 14, 0x265e5a51L); + R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL); + R1(A, B, C, D, X(5), 5, 0xd62f105dL); + R1(D, A, B, C, X(10), 9, 0x02441453L); + R1(C, D, A, B, X(15), 14, 0xd8a1e681L); + R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L); + R1(A, B, C, D, X(9), 5, 0x21e1cde6L); + R1(D, A, B, C, X(14), 9, 0xc33707d6L); + R1(C, D, A, B, X(3), 14, 0xf4d50d87L); + R1(B, C, D, A, X(8), 20, 0x455a14edL); + R1(A, B, C, D, X(13), 5, 0xa9e3e905L); + R1(D, A, B, C, X(2), 9, 0xfcefa3f8L); + R1(C, D, A, B, X(7), 14, 0x676f02d9L); + R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL); + /* Round 2 */ + R2(A, B, C, D, X(5), 4, 0xfffa3942L); + R2(D, A, B, C, X(8), 11, 0x8771f681L); + R2(C, D, A, B, X(11), 16, 0x6d9d6122L); + R2(B, C, D, A, X(14), 23, 0xfde5380cL); + R2(A, B, C, D, X(1), 4, 0xa4beea44L); + R2(D, A, B, C, X(4), 11, 0x4bdecfa9L); + R2(C, D, A, B, X(7), 16, 0xf6bb4b60L); + R2(B, C, D, A, X(10), 23, 0xbebfbc70L); + R2(A, B, C, D, X(13), 4, 0x289b7ec6L); + R2(D, A, B, C, X(0), 11, 0xeaa127faL); + R2(C, D, A, B, X(3), 16, 0xd4ef3085L); + R2(B, C, D, A, X(6), 23, 0x04881d05L); + R2(A, B, C, D, X(9), 4, 0xd9d4d039L); + R2(D, A, B, C, X(12), 11, 0xe6db99e5L); + R2(C, D, A, B, X(15), 16, 0x1fa27cf8L); + R2(B, C, D, A, X(2), 23, 0xc4ac5665L); + /* Round 3 */ + R3(A, B, C, D, X(0), 6, 0xf4292244L); + R3(D, A, B, C, X(7), 10, 0x432aff97L); + R3(C, D, A, B, X(14), 15, 0xab9423a7L); + R3(B, C, D, A, X(5), 21, 0xfc93a039L); + R3(A, B, C, D, X(12), 6, 0x655b59c3L); + R3(D, A, B, C, X(3), 10, 0x8f0ccc92L); + R3(C, D, A, B, X(10), 15, 0xffeff47dL); + R3(B, C, D, A, X(1), 21, 0x85845dd1L); + R3(A, B, C, D, X(8), 6, 0x6fa87e4fL); + R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L); + R3(C, D, A, B, X(6), 15, 0xa3014314L); + R3(B, C, D, A, X(13), 21, 0x4e0811a1L); + R3(A, B, C, D, X(4), 6, 0xf7537e82L); + R3(D, A, B, C, X(11), 10, 0xbd3af235L); + R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL); + R3(B, C, D, A, X(9), 21, 0xeb86d391L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } +} +#endif +/* crypto/md5/md5_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "md5.h" +// #include "crypto.h" + +#ifdef CHARSET_EBCDIC +# include "ebcdic.h" +#endif + +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md) +{ + MD5_CTX c; + static unsigned char m[MD5_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MD5_Init(&c)) + return NULL; +#ifndef CHARSET_EBCDIC + MD5_Update(&c, d, n); +#else + { + char temp[1024]; + unsigned long chunk; + + while (n > 0) { + chunk = (n > sizeof(temp)) ? sizeof(temp) : n; + ebcdic2ascii(temp, d, chunk); + MD5_Update(&c, temp, chunk); + n -= chunk; + d += chunk; + } + } +#endif + MD5_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ + return (md); +} diff --git a/Sources/COpenSSL/md5_locl.h b/Sources/COpenSSL/md5_locl.h new file mode 100644 index 00000000..24b52983 --- /dev/null +++ b/Sources/COpenSSL/md5_locl.h @@ -0,0 +1,133 @@ +/* crypto/md5/md5_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "e_os2.h" +#include "md5.h" + +#ifndef MD5_LONG_LOG2 +# define MD5_LONG_LOG2 2 /* default to 32 bits */ +#endif + +#ifdef MD5_ASM +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) +# define md5_block_data_order md5_block_asm_data_order +# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) +# define md5_block_data_order md5_block_asm_data_order +# elif defined(__sparc) || defined(__sparc__) +# define md5_block_data_order md5_block_asm_data_order +# endif +#endif + +void md5_block_data_order(MD5_CTX *c, const void *p, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG MD5_LONG +#define HASH_CTX MD5_CTX +#define HASH_CBLOCK MD5_CBLOCK +#define HASH_UPDATE MD5_Update +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; (void)HOST_l2c(ll,(s)); \ + ll=(c)->B; (void)HOST_l2c(ll,(s)); \ + ll=(c)->C; (void)HOST_l2c(ll,(s)); \ + ll=(c)->D; (void)HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md5_block_data_order + +#include "md32_common.h" + +/*- +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) +*/ + +/* + * As pointed out by Wei Dai , the above can be simplified + * to the code below. Wei attributes these optimizations to Peter Gutmann's + * SHS code, and he attributes it to Rich Schroeppel. + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) +#define H(b,c,d) ((b) ^ (c) ^ (d)) +#define I(b,c,d) (((~(d)) | (b)) ^ (c)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; };\ + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R3(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+I((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; diff --git a/Sources/COpenSSL/md_rand.c b/Sources/COpenSSL/md_rand.c new file mode 100644 index 00000000..b742e493 --- /dev/null +++ b/Sources/COpenSSL/md_rand.c @@ -0,0 +1,626 @@ +/* crypto/rand/md_rand.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#define OPENSSL_FIPSEVP + +#ifdef MD_RAND_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#include +#include +#include + +#include "e_os.h" + +#include "crypto.h" +#include "rand.h" +#include "rand_lcl.h" + +#include "err.h" + +#ifdef BN_DEBUG +# define PREDICT +#endif + +/* #define PREDICT 1 */ + +#define STATE_SIZE 1023 +static size_t state_num = 0, state_index = 0; +static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH]; +static unsigned char md[MD_DIGEST_LENGTH]; +static long md_count[2] = { 0, 0 }; + +static double entropy = 0; +static int initialized = 0; + +static unsigned int crypto_lock_rand = 0; /* may be set only when a thread + * holds CRYPTO_LOCK_RAND (to + * prevent double locking) */ +/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ +/* valid iff crypto_lock_rand is set */ +static CRYPTO_THREADID locking_threadid; + +#ifdef PREDICT +int rand_predictable = 0; +#endif + +const char RAND_version[] = "RAND" OPENSSL_VERSION_PTEXT; + +static void ssleay_rand_cleanup(void); +static void ssleay_rand_seed(const void *buf, int num); +static void ssleay_rand_add(const void *buf, int num, double add_entropy); +static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num); +static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num); +static int ssleay_rand_status(void); + +RAND_METHOD rand_ssleay_meth = { + ssleay_rand_seed, + ssleay_rand_nopseudo_bytes, + ssleay_rand_cleanup, + ssleay_rand_add, + ssleay_rand_pseudo_bytes, + ssleay_rand_status +}; + +RAND_METHOD *RAND_SSLeay(void) +{ + return (&rand_ssleay_meth); +} + +static void ssleay_rand_cleanup(void) +{ + OPENSSL_cleanse(state, sizeof(state)); + state_num = 0; + state_index = 0; + OPENSSL_cleanse(md, MD_DIGEST_LENGTH); + md_count[0] = 0; + md_count[1] = 0; + entropy = 0; + initialized = 0; +} + +static void ssleay_rand_add(const void *buf, int num, double add) +{ + int i, j, k, st_idx; + long md_c[2]; + unsigned char local_md[MD_DIGEST_LENGTH]; + EVP_MD_CTX m; + int do_not_lock; + + if (!num) + return; + + /* + * (Based on the rand(3) manpage) + * + * The input is chopped up into units of 20 bytes (or less for + * the last block). Each of these blocks is run through the hash + * function as follows: The data passed to the hash function + * is the current 'md', the same number of bytes from the 'state' + * (the location determined by in incremented looping index) as + * the current 'block', the new key data 'block', and 'count' + * (which is incremented after each use). + * The result of this is kept in 'md' and also xored into the + * 'state' at the same locations that were used as input into the + * hash function. + */ + + /* check if we already have the lock */ + if (crypto_lock_rand) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + CRYPTO_r_lock(CRYPTO_LOCK_RAND2); + do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); + CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); + } else + do_not_lock = 0; + + if (!do_not_lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + st_idx = state_index; + + /* + * use our own copies of the counters so that even if a concurrent thread + * seeds with exactly the same data and uses the same subarray there's + * _some_ difference + */ + md_c[0] = md_count[0]; + md_c[1] = md_count[1]; + + memcpy(local_md, md, sizeof(md)); + + /* state_index <= state_num <= STATE_SIZE */ + state_index += num; + if (state_index >= STATE_SIZE) { + state_index %= STATE_SIZE; + state_num = STATE_SIZE; + } else if (state_num < STATE_SIZE) { + if (state_index > state_num) + state_num = state_index; + } + /* state_index <= state_num <= STATE_SIZE */ + + /* + * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we + * will use now, but other threads may use them as well + */ + + md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0); + + if (!do_not_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + EVP_MD_CTX_init(&m); + for (i = 0; i < num; i += MD_DIGEST_LENGTH) { + j = (num - i); + j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j; + + if (!MD_Init(&m) || + !MD_Update(&m, local_md, MD_DIGEST_LENGTH)) + goto err; + k = (st_idx + j) - STATE_SIZE; + if (k > 0) { + if (!MD_Update(&m, &(state[st_idx]), j - k) || + !MD_Update(&m, &(state[0]), k)) + goto err; + } else + if (!MD_Update(&m, &(state[st_idx]), j)) + goto err; + + /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ + if (!MD_Update(&m, buf, j)) + goto err; + /* + * We know that line may cause programs such as purify and valgrind + * to complain about use of uninitialized data. The problem is not, + * it's with the caller. Removing that line will make sure you get + * really bad randomness and thereby other problems such as very + * insecure keys. + */ + + if (!MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)) || + !MD_Final(&m, local_md)) + goto err; + md_c[1]++; + + buf = (const char *)buf + j; + + for (k = 0; k < j; k++) { + /* + * Parallel threads may interfere with this, but always each byte + * of the new state is the XOR of some previous value of its and + * local_md (itermediate values may be lost). Alway using locking + * could hurt performance more than necessary given that + * conflicts occur only when the total seeding is longer than the + * random state. + */ + state[st_idx++] ^= local_md[k]; + if (st_idx >= STATE_SIZE) + st_idx = 0; + } + } + + if (!do_not_lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + /* + * Don't just copy back local_md into md -- this could mean that other + * thread's seeding remains without effect (except for the incremented + * counter). By XORing it we keep at least as much entropy as fits into + * md. + */ + for (k = 0; k < (int)sizeof(md); k++) { + md[k] ^= local_md[k]; + } + if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */ + entropy += add; + if (!do_not_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + +#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) + assert(md_c[1] == md_count[1]); +#endif + + err: + EVP_MD_CTX_cleanup(&m); +} + +static void ssleay_rand_seed(const void *buf, int num) +{ + ssleay_rand_add(buf, num, (double)num); +} + +int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) +{ + static volatile int stirred_pool = 0; + int i, j, k; + size_t num_ceil, st_idx, st_num; + long md_c[2]; + unsigned char local_md[MD_DIGEST_LENGTH]; + EVP_MD_CTX m; +#ifndef GETPID_IS_MEANINGLESS + pid_t curr_pid = getpid(); +#endif + int do_stir_pool = 0; + +#ifdef PREDICT + if (rand_predictable) { + static unsigned char val = 0; + + for (i = 0; i < num; i++) + buf[i] = val++; + return (1); + } +#endif + + if (num <= 0) + return 1; + + EVP_MD_CTX_init(&m); + /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ + num_ceil = + (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2); + + /* + * (Based on the rand(3) manpage:) + * + * For each group of 10 bytes (or less), we do the following: + * + * Input into the hash function the local 'md' (which is initialized from + * the global 'md' before any bytes are generated), the bytes that are to + * be overwritten by the random bytes, and bytes from the 'state' + * (incrementing looping index). From this digest output (which is kept + * in 'md'), the top (up to) 10 bytes are returned to the caller and the + * bottom 10 bytes are xored into the 'state'. + * + * Finally, after we have finished 'num' random bytes for the + * caller, 'count' (which is incremented) and the local and global 'md' + * are fed into the hash function and the results are kept in the + * global 'md'. + */ + if (lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + + /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ + CRYPTO_w_lock(CRYPTO_LOCK_RAND2); + CRYPTO_THREADID_current(&locking_threadid); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); + crypto_lock_rand = 1; + + if (!initialized) { + RAND_poll(); + initialized = (entropy >= ENTROPY_NEEDED); + } + + if (!stirred_pool) + do_stir_pool = 1; + + if (!initialized) { + /* + * If the PRNG state is not yet unpredictable, then seeing the PRNG + * output may help attackers to determine the new state; thus we have + * to decrease the entropy estimate. Once we've had enough initial + * seeding we don't bother to adjust the entropy count, though, + * because we're not ambitious to provide *information-theoretic* + * randomness. NOTE: This approach fails if the program forks before + * we have enough entropy. Entropy should be collected in a separate + * input pool and be transferred to the output pool only when the + * entropy limit has been reached. + */ + entropy -= num; + if (entropy < 0) + entropy = 0; + } + + if (do_stir_pool) { + /* + * In the output function only half of 'md' remains secret, so we + * better make sure that the required entropy gets 'evenly + * distributed' through 'state', our randomness pool. The input + * function (ssleay_rand_add) chains all of 'md', which makes it more + * suitable for this purpose. + */ + + int n = STATE_SIZE; /* so that the complete pool gets accessed */ + while (n > 0) { +#if MD_DIGEST_LENGTH > 20 +# error "Please adjust DUMMY_SEED." +#endif +#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */ + /* + * Note that the seed does not matter, it's just that + * ssleay_rand_add expects to have something to hash. + */ + ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0); + n -= MD_DIGEST_LENGTH; + } + if (initialized) + stirred_pool = 1; + } + + st_idx = state_index; + st_num = state_num; + md_c[0] = md_count[0]; + md_c[1] = md_count[1]; + memcpy(local_md, md, sizeof(md)); + + state_index += num_ceil; + if (state_index > state_num) + state_index %= state_num; + + /* + * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now + * ours (but other threads may use them too) + */ + + md_count[0] += 1; + + /* before unlocking, we must clear 'crypto_lock_rand' */ + crypto_lock_rand = 0; + if (lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + while (num > 0) { + /* num_ceil -= MD_DIGEST_LENGTH/2 */ + j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num; + num -= j; + if (!MD_Init(&m)) + goto err; +#ifndef GETPID_IS_MEANINGLESS + if (curr_pid) { /* just in the first iteration to save time */ + if (!MD_Update(&m, (unsigned char *)&curr_pid, sizeof(curr_pid))) + goto err; + curr_pid = 0; + } +#endif + if (!MD_Update(&m, local_md, MD_DIGEST_LENGTH) || + !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c))) + goto err; + +#ifndef PURIFY /* purify complains */ + /* + * The following line uses the supplied buffer as a small source of + * entropy: since this buffer is often uninitialised it may cause + * programs such as purify or valgrind to complain. So for those + * builds it is not used: the removal of such a small source of + * entropy has negligible impact on security. + */ + if (!MD_Update(&m, buf, j)) + goto err; +#endif + + k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num; + if (k > 0) { + if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k) || + !MD_Update(&m, &(state[0]), k)) + goto err; + } else { + if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2)) + goto err; + } + if (!MD_Final(&m, local_md)) + goto err; + + for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) { + /* may compete with other threads */ + state[st_idx++] ^= local_md[i]; + if (st_idx >= st_num) + st_idx = 0; + if (i < j) + *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2]; + } + } + + if (!MD_Init(&m) || + !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)) || + !MD_Update(&m, local_md, MD_DIGEST_LENGTH)) + goto err; + if (lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + if (!MD_Update(&m, md, MD_DIGEST_LENGTH) || + !MD_Final(&m, md)) { + if (lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + goto err; + } + if (lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + EVP_MD_CTX_cleanup(&m); + if (initialized) + return (1); + else if (pseudo) + return 0; + else { + RANDerr(RAND_F_SSLEAY_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED); + ERR_add_error_data(1, "You need to read the OpenSSL FAQ, " + "http://www.openssl.org/support/faq.html"); + return (0); + } + + err: + EVP_MD_CTX_cleanup(&m); + return (0); +} + +/* + * Returns ssleay_rand_bytes(), enforcing a reseeding from the + * system entropy sources using RAND_poll() before generating +`* the random bytes. + */ + +int ssleay_rand_bytes_from_system(unsigned char *buf, int num) +{ + initialized = 0; + return ssleay_rand_bytes(buf, num, 0, 0); +} + +static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num) +{ + return ssleay_rand_bytes(buf, num, 0, 1); +} + +/* + * pseudo-random bytes that are guaranteed to be unique but not unpredictable + */ +static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) +{ + return ssleay_rand_bytes(buf, num, 1, 1); +} + +static int ssleay_rand_status(void) +{ + CRYPTO_THREADID cur; + int ret; + int do_not_lock; + + CRYPTO_THREADID_current(&cur); + /* + * check if we already have the lock (could happen if a RAND_poll() + * implementation calls RAND_status()) + */ + if (crypto_lock_rand) { + CRYPTO_r_lock(CRYPTO_LOCK_RAND2); + do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); + CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); + } else + do_not_lock = 0; + + if (!do_not_lock) { + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + + /* + * prevent ssleay_rand_bytes() from trying to obtain the lock again + */ + CRYPTO_w_lock(CRYPTO_LOCK_RAND2); + CRYPTO_THREADID_cpy(&locking_threadid, &cur); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); + crypto_lock_rand = 1; + } + + if (!initialized) { + RAND_poll(); + initialized = (entropy >= ENTROPY_NEEDED); + } + + ret = initialized; + + if (!do_not_lock) { + /* before unlocking, we must clear 'crypto_lock_rand' */ + crypto_lock_rand = 0; + + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + + return ret; +} diff --git a/Sources/COpenSSL/mdc2.h b/Sources/COpenSSL/mdc2.h new file mode 100644 index 00000000..8b6658ae --- /dev/null +++ b/Sources/COpenSSL/mdc2.h @@ -0,0 +1,94 @@ +/* crypto/mdc2/mdc2.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MDC2_H +# define HEADER_MDC2_H + +# include "des.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MDC2 +# error MDC2 is disabled. +# endif + +# define MDC2_BLOCK 8 +# define MDC2_DIGEST_LENGTH 16 + +typedef struct mdc2_ctx_st { + unsigned int num; + unsigned char data[MDC2_BLOCK]; + DES_cblock h, hh; + int pad_type; /* either 1 or 2, default 1 */ +} MDC2_CTX; + +# ifdef OPENSSL_FIPS +int private_MDC2_Init(MDC2_CTX *c); +# endif +int MDC2_Init(MDC2_CTX *c); +int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); +int MDC2_Final(unsigned char *md, MDC2_CTX *c); +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/mdc2_one.c b/Sources/COpenSSL/mdc2_one.c new file mode 100644 index 00000000..09c5afaf --- /dev/null +++ b/Sources/COpenSSL/mdc2_one.c @@ -0,0 +1,76 @@ +/* crypto/mdc2/mdc2_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "mdc2.h" + +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md) +{ + MDC2_CTX c; + static unsigned char m[MDC2_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MDC2_Init(&c)) + return NULL; + MDC2_Update(&c, d, n); + MDC2_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ + return (md); +} diff --git a/Sources/COpenSSL/mdc2dgst.c b/Sources/COpenSSL/mdc2dgst.c new file mode 100644 index 00000000..6fdf2657 --- /dev/null +++ b/Sources/COpenSSL/mdc2dgst.c @@ -0,0 +1,196 @@ +/* crypto/mdc2/mdc2dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "crypto.h" +#include "des.h" +#include "mdc2.h" + +#undef c2l +#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<<24L) + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); +fips_md_init(MDC2) +{ + c->num = 0; + c->pad_type = 1; + memset(&(c->h[0]), 0x52, MDC2_BLOCK); + memset(&(c->hh[0]), 0x25, MDC2_BLOCK); + return 1; +} + +int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len) +{ + size_t i, j; + + i = c->num; + if (i != 0) { + if (len < MDC2_BLOCK - i) { + /* partial block */ + memcpy(&(c->data[i]), in, len); + c->num += (int)len; + return 1; + } else { + /* filled one */ + j = MDC2_BLOCK - i; + memcpy(&(c->data[i]), in, j); + len -= j; + in += j; + c->num = 0; + mdc2_body(c, &(c->data[0]), MDC2_BLOCK); + } + } + i = len & ~((size_t)MDC2_BLOCK - 1); + if (i > 0) + mdc2_body(c, in, i); + j = len - i; + if (j > 0) { + memcpy(&(c->data[0]), &(in[i]), j); + c->num = (int)j; + } + return 1; +} + +static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len) +{ + register DES_LONG tin0, tin1; + register DES_LONG ttin0, ttin1; + DES_LONG d[2], dd[2]; + DES_key_schedule k; + unsigned char *p; + size_t i; + + for (i = 0; i < len; i += 8) { + c2l(in, tin0); + d[0] = dd[0] = tin0; + c2l(in, tin1); + d[1] = dd[1] = tin1; + c->h[0] = (c->h[0] & 0x9f) | 0x40; + c->hh[0] = (c->hh[0] & 0x9f) | 0x20; + + DES_set_odd_parity(&c->h); + DES_set_key_unchecked(&c->h, &k); + DES_encrypt1(d, &k, 1); + + DES_set_odd_parity(&c->hh); + DES_set_key_unchecked(&c->hh, &k); + DES_encrypt1(dd, &k, 1); + + ttin0 = tin0 ^ dd[0]; + ttin1 = tin1 ^ dd[1]; + tin0 ^= d[0]; + tin1 ^= d[1]; + + p = c->h; + l2c(tin0, p); + l2c(ttin1, p); + p = c->hh; + l2c(ttin0, p); + l2c(tin1, p); + } +} + +int MDC2_Final(unsigned char *md, MDC2_CTX *c) +{ + unsigned int i; + int j; + + i = c->num; + j = c->pad_type; + if ((i > 0) || (j == 2)) { + if (j == 2) + c->data[i++] = 0x80; + memset(&(c->data[i]), 0, MDC2_BLOCK - i); + mdc2_body(c, c->data, MDC2_BLOCK); + } + memcpy(md, (char *)c->h, MDC2_BLOCK); + memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK); + return 1; +} + +#undef TEST + +#ifdef TEST +main() +{ + unsigned char md[MDC2_DIGEST_LENGTH]; + int i; + MDC2_CTX c; + static char *text = "Now is the time for all "; + + MDC2_Init(&c); + MDC2_Update(&c, text, strlen(text)); + MDC2_Final(&(md[0]), &c); + + for (i = 0; i < MDC2_DIGEST_LENGTH; i++) + printf("%02X", md[i]); + printf("\n"); +} + +#endif diff --git a/Sources/COpenSSL/mem.c b/Sources/COpenSSL/mem.c new file mode 100644 index 00000000..d7c43982 --- /dev/null +++ b/Sources/COpenSSL/mem.c @@ -0,0 +1,458 @@ +/* crypto/mem.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "crypto.h" +#include "cryptlib.h" + +static int allow_customize = 1; /* we provide flexible functions for */ +static int allow_customize_debug = 1; /* exchanging memory-related functions + * at run-time, but this must be done + * before any blocks are actually + * allocated; or we'll run into huge + * problems when malloc/free pairs + * don't match etc. */ + +/* + * the following pointers may be changed as long as 'allow_customize' is set + */ + +static void *(*malloc_func) (size_t) = malloc; +static void *default_malloc_ex(size_t num, const char *file, int line) +{ + return malloc_func(num); +} + +static void *(*malloc_ex_func) (size_t, const char *file, int line) + = default_malloc_ex; + +#ifdef OPENSSL_SYS_VMS +# if __INITIAL_POINTER_SIZE == 64 +# define realloc _realloc64 +# elif __INITIAL_POINTER_SIZE == 32 +# define realloc _realloc32 +# endif +#endif + +static void *(*realloc_func) (void *, size_t) = realloc; +static void *default_realloc_ex(void *str, size_t num, + const char *file, int line) +{ + return realloc_func(str, num); +} + +static void *(*realloc_ex_func) (void *, size_t, const char *file, int line) + = default_realloc_ex; + +#ifdef OPENSSL_SYS_VMS + static void (*free_func) (__void_ptr64) = free; +#else + static void (*free_func) (void *) = free; +#endif + +static void *(*malloc_locked_func) (size_t) = malloc; +static void *default_malloc_locked_ex(size_t num, const char *file, int line) +{ + return malloc_locked_func(num); +} + +static void *(*malloc_locked_ex_func) (size_t, const char *file, int line) + = default_malloc_locked_ex; + +#ifdef OPENSSL_SYS_VMS + static void (*free_locked_func) (__void_ptr64) = free; +#else + static void (*free_locked_func) (void *) = free; +#endif + +/* may be changed as long as 'allow_customize_debug' is set */ +/* XXX use correct function pointer types */ +#ifdef CRYPTO_MDEBUG +/* use default functions from mem_dbg.c */ +static void (*malloc_debug_func) (void *, int, const char *, int, int) + = CRYPTO_dbg_malloc; +static void (*realloc_debug_func) (void *, void *, int, const char *, int, + int) + = CRYPTO_dbg_realloc; +static void (*free_debug_func) (void *, int) = CRYPTO_dbg_free; +static void (*set_debug_options_func) (long) = CRYPTO_dbg_set_options; +static long (*get_debug_options_func) (void) = CRYPTO_dbg_get_options; +#else +/* + * applications can use CRYPTO_malloc_debug_init() to select above case at + * run-time + */ +static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL; +static void (*realloc_debug_func) (void *, void *, int, const char *, int, + int) + = NULL; +static void (*free_debug_func) (void *, int) = NULL; +static void (*set_debug_options_func) (long) = NULL; +static long (*get_debug_options_func) (void) = NULL; +#endif + +int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), + void (*f) (void *)) +{ + if (!allow_customize) + return 0; + if ((m == 0) || (r == 0) || (f == 0)) + return 0; + /* Dummy call just to ensure OPENSSL_init() gets linked in */ + OPENSSL_init(); + malloc_func = m; + malloc_ex_func = default_malloc_ex; + realloc_func = r; + realloc_ex_func = default_realloc_ex; + free_func = f; + malloc_locked_func = m; + malloc_locked_ex_func = default_malloc_locked_ex; + free_locked_func = f; + return 1; +} + +int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, + int), void (*f) (void *)) +{ + if (!allow_customize) + return 0; + if ((m == 0) || (r == 0) || (f == 0)) + return 0; + malloc_func = 0; + malloc_ex_func = m; + realloc_func = 0; + realloc_ex_func = r; + free_func = f; + malloc_locked_func = 0; + malloc_locked_ex_func = m; + free_locked_func = f; + return 1; +} + +int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *)) +{ + if (!allow_customize) + return 0; + if ((m == NULL) || (f == NULL)) + return 0; + malloc_locked_func = m; + malloc_locked_ex_func = default_malloc_locked_ex; + free_locked_func = f; + return 1; +} + +int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), + void (*f) (void *)) +{ + if (!allow_customize) + return 0; + if ((m == NULL) || (f == NULL)) + return 0; + malloc_locked_func = 0; + malloc_locked_ex_func = m; + free_func = f; + return 1; +} + +int CRYPTO_set_mem_debug_functions(void (*m) + (void *, int, const char *, int, int), + void (*r) (void *, void *, int, + const char *, int, int), + void (*f) (void *, int), void (*so) (long), + long (*go) (void)) +{ + if (!allow_customize_debug) + return 0; + OPENSSL_init(); + malloc_debug_func = m; + realloc_debug_func = r; + free_debug_func = f; + set_debug_options_func = so; + get_debug_options_func = go; + return 1; +} + +void CRYPTO_get_mem_functions(void *(**m) (size_t), + void *(**r) (void *, size_t), + void (**f) (void *)) +{ + if (m != NULL) + *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0; + if (r != NULL) + *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0; + if (f != NULL) + *f = free_func; +} + +void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), + void *(**r) (void *, size_t, const char *, + int), void (**f) (void *)) +{ + if (m != NULL) + *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0; + if (r != NULL) + *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0; + if (f != NULL) + *f = free_func; +} + +void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), + void (**f) (void *)) +{ + if (m != NULL) + *m = (malloc_locked_ex_func == default_malloc_locked_ex) ? + malloc_locked_func : 0; + if (f != NULL) + *f = free_locked_func; +} + +void CRYPTO_get_locked_mem_ex_functions(void + *(**m) (size_t, const char *, int), + void (**f) (void *)) +{ + if (m != NULL) + *m = (malloc_locked_ex_func != default_malloc_locked_ex) ? + malloc_locked_ex_func : 0; + if (f != NULL) + *f = free_locked_func; +} + +void CRYPTO_get_mem_debug_functions(void (**m) + (void *, int, const char *, int, int), + void (**r) (void *, void *, int, + const char *, int, int), + void (**f) (void *, int), + void (**so) (long), long (**go) (void)) +{ + if (m != NULL) + *m = malloc_debug_func; + if (r != NULL) + *r = realloc_debug_func; + if (f != NULL) + *f = free_debug_func; + if (so != NULL) + *so = set_debug_options_func; + if (go != NULL) + *go = get_debug_options_func; +} + +void *CRYPTO_malloc_locked(int num, const char *file, int line) +{ + void *ret = NULL; + + if (num <= 0) + return NULL; + + if (allow_customize) + allow_customize = 0; + if (malloc_debug_func != NULL) { + if (allow_customize_debug) + allow_customize_debug = 0; + malloc_debug_func(NULL, num, file, line, 0); + } + ret = malloc_locked_ex_func(num, file, line); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); +#endif + if (malloc_debug_func != NULL) + malloc_debug_func(ret, num, file, line, 1); + + return ret; +} + +void CRYPTO_free_locked(void *str) +{ + if (free_debug_func != NULL) + free_debug_func(str, 0); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); +#endif + free_locked_func(str); + if (free_debug_func != NULL) + free_debug_func(NULL, 1); +} + +void *CRYPTO_malloc(int num, const char *file, int line) +{ + void *ret = NULL; + + if (num <= 0) + return NULL; + + if (allow_customize) + allow_customize = 0; + if (malloc_debug_func != NULL) { + if (allow_customize_debug) + allow_customize_debug = 0; + malloc_debug_func(NULL, num, file, line, 0); + } + ret = malloc_ex_func(num, file, line); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); +#endif + if (malloc_debug_func != NULL) + malloc_debug_func(ret, num, file, line, 1); + + return ret; +} + +char *CRYPTO_strdup(const char *str, const char *file, int line) +{ + char *ret = CRYPTO_malloc(strlen(str) + 1, file, line); + + if (ret == NULL) + return NULL; + + strcpy(ret, str); + return ret; +} + +void *CRYPTO_realloc(void *str, int num, const char *file, int line) +{ + void *ret = NULL; + + if (str == NULL) + return CRYPTO_malloc(num, file, line); + + if (num <= 0) + return NULL; + + if (realloc_debug_func != NULL) + realloc_debug_func(str, NULL, num, file, line, 0); + ret = realloc_ex_func(str, num, file, line); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, + ret, num); +#endif + if (realloc_debug_func != NULL) + realloc_debug_func(str, ret, num, file, line, 1); + + return ret; +} + +void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file, + int line) +{ + void *ret = NULL; + + if (str == NULL) + return CRYPTO_malloc(num, file, line); + + if (num <= 0) + return NULL; + + /* + * We don't support shrinking the buffer. Note the memcpy that copies + * |old_len| bytes to the new buffer, below. + */ + if (num < old_len) + return NULL; + + if (realloc_debug_func != NULL) + realloc_debug_func(str, NULL, num, file, line, 0); + ret = malloc_ex_func(num, file, line); + if (ret) { + memcpy(ret, str, old_len); + OPENSSL_cleanse(str, old_len); + free_func(str); + } +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, + "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", + str, ret, num); +#endif + if (realloc_debug_func != NULL) + realloc_debug_func(str, ret, num, file, line, 1); + + return ret; +} + +void CRYPTO_free(void *str) +{ + if (free_debug_func != NULL) + free_debug_func(str, 0); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); +#endif + free_func(str); + if (free_debug_func != NULL) + free_debug_func(NULL, 1); +} + +void *CRYPTO_remalloc(void *a, int num, const char *file, int line) +{ + if (a != NULL) + OPENSSL_free(a); + a = (char *)OPENSSL_malloc(num); + return (a); +} + +void CRYPTO_set_mem_debug_options(long bits) +{ + if (set_debug_options_func != NULL) + set_debug_options_func(bits); +} + +long CRYPTO_get_mem_debug_options(void) +{ + if (get_debug_options_func != NULL) + return get_debug_options_func(); + return 0; +} diff --git a/Sources/COpenSSL/mem_.c b/Sources/COpenSSL/mem_.c new file mode 100644 index 00000000..ebbe5cba --- /dev/null +++ b/Sources/COpenSSL/mem_.c @@ -0,0 +1,911 @@ +/* crypto/mem_clr.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "crypto.h" + +/* + * Pointer to memset is volatile so that compiler must de-reference + * the pointer and can't assume that it points to any function in + * particular (such as memset, which it then might further "optimize") + */ +typedef void *(*memset_t)(void *,int,size_t); + +static volatile memset_t memset_func = memset; + +void OPENSSL_cleanse(void *ptr, size_t len) +{ + memset_func(ptr, 0, len); +} +/* crypto/mem_dbg.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +// #include "crypto.h" +#include "buffer.h" +#include "bio.h" +#include "lhash.h" + +static int mh_mode = CRYPTO_MEM_CHECK_OFF; +/* + * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when + * the application asks for it (usually after library initialisation for + * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only + * temporarily when the library thinks that certain allocations should not be + * checked (e.g. the data structures used for memory checking). It is not + * suitable as an initial state: the library will unexpectedly enable memory + * checking when it executes one of those sections that want to disable + * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes + * no sense whatsoever. + */ + +static unsigned long order = 0; /* number of memory requests */ + +DECLARE_LHASH_OF(MEM); +static LHASH_OF(MEM) *mh = NULL; /* hash-table of memory requests (address as + * key); access requires MALLOC2 lock */ + +typedef struct app_mem_info_st +/*- + * For application-defined information (static C-string `info') + * to be displayed in memory leak list. + * Each thread has its own stack. For applications, there is + * CRYPTO_push_info("...") to push an entry, + * CRYPTO_pop_info() to pop an entry, + * CRYPTO_remove_all_info() to pop all entries. + */ +{ + CRYPTO_THREADID threadid; + const char *file; + int line; + const char *info; + struct app_mem_info_st *next; /* tail of thread's stack */ + int references; +} APP_INFO; + +static void app_info_free(APP_INFO *); + +DECLARE_LHASH_OF(APP_INFO); +static LHASH_OF(APP_INFO) *amih = NULL; /* hash-table with those + * app_mem_info_st's that are at the + * top of their thread's stack (with + * `thread' as key); access requires + * MALLOC2 lock */ + +typedef struct mem_st +/* memory-block description */ +{ + void *addr; + int num; + const char *file; + int line; + CRYPTO_THREADID threadid; + unsigned long order; + time_t time; + APP_INFO *app_info; +} MEM; + +static long options = /* extra information to be recorded */ +#if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL) + V_CRYPTO_MDEBUG_TIME | +#endif +#if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL) + V_CRYPTO_MDEBUG_THREAD | +#endif + 0; + +static unsigned int num_disable = 0; /* num_disable > 0 iff mh_mode == + * CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */ + +/* + * Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this + * case (by the thread named in disabling_thread). + */ +static CRYPTO_THREADID disabling_threadid; + +static void app_info_free(APP_INFO *inf) +{ + if (--(inf->references) <= 0) { + if (inf->next != NULL) { + app_info_free(inf->next); + } + OPENSSL_free(inf); + } +} + +int CRYPTO_mem_ctrl(int mode) +{ + int ret = mh_mode; + + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + switch (mode) { + /* + * for applications (not to be called while multiple threads use the + * library): + */ + case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */ + mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE; + num_disable = 0; + break; + case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */ + mh_mode = 0; + num_disable = 0; /* should be true *before* MemCheck_stop is + * used, or there'll be a lot of confusion */ + break; + + /* switch off temporarily (for library-internal use): */ + case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ + if (mh_mode & CRYPTO_MEM_CHECK_ON) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + /* see if we don't have the MALLOC2 lock already */ + if (!num_disable + || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) { + /* + * Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed + * while we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock + * if somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot + * release it because we block entry to this function). Give + * them a chance, first, and then claim the locks in + * appropriate order (long-time lock first). + */ + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + /* + * Note that after we have waited for CRYPTO_LOCK_MALLOC2 and + * CRYPTO_LOCK_MALLOC, we'll still be in the right "case" and + * "if" branch because MemCheck_start and MemCheck_stop may + * never be used while there are multiple OpenSSL threads. + */ + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; + CRYPTO_THREADID_cpy(&disabling_threadid, &cur); + } + num_disable++; + } + break; + case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */ + if (mh_mode & CRYPTO_MEM_CHECK_ON) { + if (num_disable) { /* always true, or something is going wrong */ + num_disable--; + if (num_disable == 0) { + mh_mode |= CRYPTO_MEM_CHECK_ENABLE; + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); + } + } + } + break; + + default: + break; + } + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + return (ret); +} + +int CRYPTO_is_mem_check_on(void) +{ + int ret = 0; + + if (mh_mode & CRYPTO_MEM_CHECK_ON) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); + + ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) + || CRYPTO_THREADID_cmp(&disabling_threadid, &cur); + + CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC); + } + return (ret); +} + +void CRYPTO_dbg_set_options(long bits) +{ + options = bits; +} + +long CRYPTO_dbg_get_options(void) +{ + return options; +} + +static int mem_cmp(const MEM *a, const MEM *b) +{ +#ifdef _WIN64 + const char *ap = (const char *)a->addr, *bp = (const char *)b->addr; + if (ap == bp) + return 0; + else if (ap > bp) + return 1; + else + return -1; +#else + return (const char *)a->addr - (const char *)b->addr; +#endif +} + +static IMPLEMENT_LHASH_COMP_FN(mem, MEM) + +static unsigned long mem_hash(const MEM *a) +{ + unsigned long ret; + + ret = (unsigned long)a->addr; + + ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251; + return (ret); +} + +static IMPLEMENT_LHASH_HASH_FN(mem, MEM) + +/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */ +static int app_info_cmp(const void *a_void, const void *b_void) +{ + return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid, + &((const APP_INFO *)b_void)->threadid); +} + +static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO) + +static unsigned long app_info_hash(const APP_INFO *a) +{ + unsigned long ret; + + ret = CRYPTO_THREADID_hash(&a->threadid); + /* This is left in as a "who am I to question legacy?" measure */ + ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251; + return (ret); +} + +static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO) + +static APP_INFO *pop_info(void) +{ + APP_INFO tmp; + APP_INFO *ret = NULL; + + if (amih != NULL) { + CRYPTO_THREADID_current(&tmp.threadid); + if ((ret = lh_APP_INFO_delete(amih, &tmp)) != NULL) { + APP_INFO *next = ret->next; + + if (next != NULL) { + next->references++; + (void)lh_APP_INFO_insert(amih, next); + } +#ifdef LEVITTE_DEBUG_MEM + if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid)) { + fprintf(stderr, + "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n", + CRYPTO_THREADID_hash(&ret->threadid), + CRYPTO_THREADID_hash(&tmp.threadid)); + abort(); + } +#endif + if (--(ret->references) <= 0) { + ret->next = NULL; + if (next != NULL) + next->references--; + OPENSSL_free(ret); + } + } + } + return (ret); +} + +int CRYPTO_push_info_(const char *info, const char *file, int line) +{ + APP_INFO *ami, *amim; + int ret = 0; + + if (is_MemCheck_on()) { + MemCheck_off(); /* obtain MALLOC2 lock */ + + if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) { + ret = 0; + goto err; + } + if (amih == NULL) { + if ((amih = lh_APP_INFO_new()) == NULL) { + OPENSSL_free(ami); + ret = 0; + goto err; + } + } + + CRYPTO_THREADID_current(&ami->threadid); + ami->file = file; + ami->line = line; + ami->info = info; + ami->references = 1; + ami->next = NULL; + + if ((amim = lh_APP_INFO_insert(amih, ami)) != NULL) { +#ifdef LEVITTE_DEBUG_MEM + if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid)) { + fprintf(stderr, + "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n", + CRYPTO_THREADID_hash(&amim->threadid), + CRYPTO_THREADID_hash(&ami->threadid)); + abort(); + } +#endif + ami->next = amim; + } + err: + MemCheck_on(); /* release MALLOC2 lock */ + } + + return (ret); +} + +int CRYPTO_pop_info(void) +{ + int ret = 0; + + if (is_MemCheck_on()) { /* _must_ be true, or something went severely + * wrong */ + MemCheck_off(); /* obtain MALLOC2 lock */ + + ret = (pop_info() != NULL); + + MemCheck_on(); /* release MALLOC2 lock */ + } + return (ret); +} + +int CRYPTO_remove_all_info(void) +{ + int ret = 0; + + if (is_MemCheck_on()) { /* _must_ be true */ + MemCheck_off(); /* obtain MALLOC2 lock */ + + while (pop_info() != NULL) + ret++; + + MemCheck_on(); /* release MALLOC2 lock */ + } + return (ret); +} + +static unsigned long break_order_num = 0; +void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, + int before_p) +{ + MEM *m, *mm; + APP_INFO tmp, *amim; + + switch (before_p & 127) { + case 0: + break; + case 1: + if (addr == NULL) + break; + + if (is_MemCheck_on()) { + MemCheck_off(); /* make sure we hold MALLOC2 lock */ + if ((m = (MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) { + OPENSSL_free(addr); + MemCheck_on(); /* release MALLOC2 lock if num_disabled drops + * to 0 */ + return; + } + if (mh == NULL) { + if ((mh = lh_MEM_new()) == NULL) { + OPENSSL_free(addr); + OPENSSL_free(m); + addr = NULL; + goto err; + } + } + + m->addr = addr; + m->file = file; + m->line = line; + m->num = num; + if (options & V_CRYPTO_MDEBUG_THREAD) + CRYPTO_THREADID_current(&m->threadid); + else + memset(&m->threadid, 0, sizeof(m->threadid)); + + if (order == break_order_num) { + /* BREAK HERE */ + m->order = order; + } + m->order = order++; +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n", + m->order, (before_p & 128) ? '*' : '+', m->addr, m->num); +#endif + if (options & V_CRYPTO_MDEBUG_TIME) + m->time = time(NULL); + else + m->time = 0; + + CRYPTO_THREADID_current(&tmp.threadid); + m->app_info = NULL; + if (amih != NULL + && (amim = lh_APP_INFO_retrieve(amih, &tmp)) != NULL) { + m->app_info = amim; + amim->references++; + } + + if ((mm = lh_MEM_insert(mh, m)) != NULL) { + /* Not good, but don't sweat it */ + if (mm->app_info != NULL) { + mm->app_info->references--; + } + OPENSSL_free(mm); + } + err: + MemCheck_on(); /* release MALLOC2 lock if num_disabled drops + * to 0 */ + } + break; + } + return; +} + +void CRYPTO_dbg_free(void *addr, int before_p) +{ + MEM m, *mp; + + switch (before_p) { + case 0: + if (addr == NULL) + break; + + if (is_MemCheck_on() && (mh != NULL)) { + MemCheck_off(); /* make sure we hold MALLOC2 lock */ + + m.addr = addr; + mp = lh_MEM_delete(mh, &m); + if (mp != NULL) { +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n", + mp->order, mp->addr, mp->num); +#endif + if (mp->app_info != NULL) + app_info_free(mp->app_info); + OPENSSL_free(mp); + } + + MemCheck_on(); /* release MALLOC2 lock if num_disabled drops + * to 0 */ + } + break; + case 1: + break; + } +} + +void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, + const char *file, int line, int before_p) +{ + MEM m, *mp; + +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, + "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n", + addr1, addr2, num, file, line, before_p); +#endif + + switch (before_p) { + case 0: + break; + case 1: + if (addr2 == NULL) + break; + + if (addr1 == NULL) { + CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p); + break; + } + + if (is_MemCheck_on()) { + MemCheck_off(); /* make sure we hold MALLOC2 lock */ + + m.addr = addr1; + mp = lh_MEM_delete(mh, &m); + if (mp != NULL) { +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, + "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n", + mp->order, mp->addr, mp->num, addr2, num); +#endif + mp->addr = addr2; + mp->num = num; + (void)lh_MEM_insert(mh, mp); + } + + MemCheck_on(); /* release MALLOC2 lock if num_disabled drops + * to 0 */ + } + break; + } + return; +} + +typedef struct mem_leak_st { + BIO *bio; + int chunks; + long bytes; +} MEM_LEAK; + +static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l) +{ + char buf[1024]; + char *bufp = buf; + APP_INFO *amip; + int ami_cnt; + struct tm *lcl = NULL; + struct tm result = {0}; + CRYPTO_THREADID ti; + +#define BUF_REMAIN (sizeof(buf) - (size_t)(bufp - buf)) + + if (m->addr == (char *)l->bio) + return; + + if (options & V_CRYPTO_MDEBUG_TIME) { +# if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && \ + !defined(OPENSSL_SYS_OS2) && !defined(OPENSSL_SYS_SUNOS) && \ + (!defined(OPENSSL_SYS_VMS) || defined(localtime_r)) + lcl = localtime_r(&m->time, &result); +# else + lcl = localtime(&m->time); +# endif + BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ", + lcl->tm_hour, lcl->tm_min, lcl->tm_sec); + bufp += strlen(bufp); + } + + BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ", + m->order, m->file, m->line); + bufp += strlen(bufp); + + if (options & V_CRYPTO_MDEBUG_THREAD) { + BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", + CRYPTO_THREADID_hash(&m->threadid)); + bufp += strlen(bufp); + } + + BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n", + m->num, (unsigned long)m->addr); + bufp += strlen(bufp); + + BIO_puts(l->bio, buf); + + l->chunks++; + l->bytes += m->num; + + amip = m->app_info; + ami_cnt = 0; + if (!amip) + return; + CRYPTO_THREADID_cpy(&ti, &amip->threadid); + + do { + int buf_len; + int info_len; + + ami_cnt++; + memset(buf, '>', ami_cnt); + BIO_snprintf(buf + ami_cnt, sizeof(buf) - ami_cnt, + " thread=%lu, file=%s, line=%d, info=\"", + CRYPTO_THREADID_hash(&amip->threadid), amip->file, + amip->line); + buf_len = strlen(buf); + info_len = strlen(amip->info); + if (128 - buf_len - 3 < info_len) { + memcpy(buf + buf_len, amip->info, 128 - buf_len - 3); + buf_len = 128 - 3; + } else { + BUF_strlcpy(buf + buf_len, amip->info, sizeof(buf) - buf_len); + buf_len = strlen(buf); + } + BIO_snprintf(buf + buf_len, sizeof(buf) - buf_len, "\"\n"); + + BIO_puts(l->bio, buf); + + amip = amip->next; + } + while (amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti)); + +#ifdef LEVITTE_DEBUG_MEM + if (amip) { + fprintf(stderr, "Thread switch detected in backtrace!!!!\n"); + abort(); + } +#endif +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK) + +void CRYPTO_mem_leaks(BIO *b) +{ + MEM_LEAK ml; + + if (mh == NULL && amih == NULL) + return; + + MemCheck_off(); /* obtain MALLOC2 lock */ + + ml.bio = b; + ml.bytes = 0; + ml.chunks = 0; + if (mh != NULL) + lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK, &ml); + if (ml.chunks != 0) { + BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks); +#ifdef CRYPTO_MDEBUG_ABORT + abort(); +#endif + } else { + /* + * Make sure that, if we found no leaks, memory-leak debugging itself + * does not introduce memory leaks (which might irritate external + * debugging tools). (When someone enables leak checking, but does not + * call this function, we declare it to be their fault.) XXX This + * should be in CRYPTO_mem_leaks_cb, and CRYPTO_mem_leaks should be + * implemented by using CRYPTO_mem_leaks_cb. (Also there should be a + * variant of lh_doall_arg that takes a function pointer instead of a + * void *; this would obviate the ugly and illegal void_fn_to_char + * kludge in CRYPTO_mem_leaks_cb. Otherwise the code police will come + * and get us.) + */ + int old_mh_mode; + + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + + /* + * avoid deadlock when lh_free() uses CRYPTO_dbg_free(), which uses + * CRYPTO_is_mem_check_on + */ + old_mh_mode = mh_mode; + mh_mode = CRYPTO_MEM_CHECK_OFF; + + if (mh != NULL) { + lh_MEM_free(mh); + mh = NULL; + } + if (amih != NULL) { + if (lh_APP_INFO_num_items(amih) == 0) { + lh_APP_INFO_free(amih); + amih = NULL; + } + } + + mh_mode = old_mh_mode; + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + } + MemCheck_on(); /* release MALLOC2 lock */ +} + +#ifndef OPENSSL_NO_FP_API +void CRYPTO_mem_leaks_fp(FILE *fp) +{ + BIO *b; + + if (mh == NULL) + return; + /* + * Need to turn off memory checking when allocated BIOs ... especially as + * we're creating them at a time when we're trying to check we've not + * left anything un-free()'d!! + */ + MemCheck_off(); + b = BIO_new(BIO_s_file()); + MemCheck_on(); + if (!b) + return; + BIO_set_fp(b, fp, BIO_NOCLOSE); + CRYPTO_mem_leaks(b); + BIO_free(b); +} +#endif + +/* + * FIXME: We really don't allow much to the callback. For example, it has no + * chance of reaching the info stack for the item it processes. Should it + * really be this way? -- Richard Levitte + */ +/* + * NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside + * crypto.h If this code is restructured, remove the callback type if it is + * no longer needed. -- Geoff Thorpe + */ + +/* + * Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it is a + * function pointer and conversion to void * is prohibited. Instead pass its + * address + */ + +typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB; + +static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb) +{ + (*cb) (m->order, m->file, m->line, m->num, m->addr); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB) + +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb) +{ + if (mh == NULL) + return; + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); + lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB, + &cb); + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); +} diff --git a/Sources/COpenSSL/modes.h b/Sources/COpenSSL/modes.h new file mode 100644 index 00000000..fd488499 --- /dev/null +++ b/Sources/COpenSSL/modes.h @@ -0,0 +1,163 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Rights for redistribution and usage in source and binary + * forms are granted according to the OpenSSL license. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef void (*block128_f) (const unsigned char in[16], + unsigned char out[16], const void *key); + +typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); + +typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], unsigned int *num, + block128_f block); + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], + unsigned int *num, ctr128_f ctr); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +typedef struct gcm128_context GCM128_CONTEXT; + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len); +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); + +typedef struct ccm128_context CCM128_CONTEXT; + +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, + block128_f block); +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce, + size_t nlen, size_t mlen); +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad, + size_t alen); +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); + +typedef struct xts128_context XTS128_CONTEXT; + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc); + +size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); + +size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block); + +#ifdef __cplusplus +} +#endif diff --git a/Sources/COpenSSL/modes_lcl.h b/Sources/COpenSSL/modes_lcl.h new file mode 100644 index 00000000..820d5d01 --- /dev/null +++ b/Sources/COpenSSL/modes_lcl.h @@ -0,0 +1,143 @@ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use is governed by OpenSSL license. + * ==================================================================== + */ + +#include "modes.h" + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +typedef __int64 i64; +typedef unsigned __int64 u64; +# define U64(C) C##UI64 +#elif defined(__arch64__) +typedef long i64; +typedef unsigned long u64; +# define U64(C) C##UL +#else +typedef long long i64; +typedef unsigned long long u64; +# define U64(C) C##ULL +#endif + +typedef unsigned int u32; +typedef unsigned char u8; + +#define STRICT_ALIGNMENT 1 +#ifndef PEDANTIC +# if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__aarch64__) || \ + defined(__s390__) || defined(__s390x__) +# undef STRICT_ALIGNMENT +# endif +#endif + +#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# define BSWAP8(x) ({ u64 ret_=(x); \ + asm ("bswapq %0" \ + : "+r"(ret_)); ret_; }) +# define BSWAP4(x) ({ u32 ret_=(x); \ + asm ("bswapl %0" \ + : "+r"(ret_)); ret_; }) +# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) +# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ + asm ("bswapl %0; bswapl %1" \ + : "+r"(hi_),"+r"(lo_)); \ + (u64)hi_<<32|lo_; }) +# define BSWAP4(x) ({ u32 ret_=(x); \ + asm ("bswapl %0" \ + : "+r"(ret_)); ret_; }) +# elif defined(__aarch64__) +# define BSWAP8(x) ({ u64 ret_; \ + asm ("rev %0,%1" \ + : "=r"(ret_) : "r"(x)); ret_; }) +# define BSWAP4(x) ({ u32 ret_; \ + asm ("rev %w0,%w1" \ + : "=r"(ret_) : "r"(x)); ret_; }) +# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) +# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ + asm ("rev %0,%0; rev %1,%1" \ + : "+r"(hi_),"+r"(lo_)); \ + (u64)hi_<<32|lo_; }) +# define BSWAP4(x) ({ u32 ret_; \ + asm ("rev %0,%1" \ + : "=r"(ret_) : "r"((u32)(x))); \ + ret_; }) +# endif +# elif defined(_MSC_VER) +# if _MSC_VER>=1300 +# pragma intrinsic(_byteswap_uint64,_byteswap_ulong) +# define BSWAP8(x) _byteswap_uint64((u64)(x)) +# define BSWAP4(x) _byteswap_ulong((u32)(x)) +# elif defined(_M_IX86) +__inline u32 _bswap4(u32 val) +{ +_asm mov eax, val _asm bswap eax} +# define BSWAP4(x) _bswap4(x) +# endif +# endif +#endif +#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) +# define GETU32(p) BSWAP4(*(const u32 *)(p)) +# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) +#else +# define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) +# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) +#endif +/*- GCM definitions */ typedef struct { + u64 hi, lo; +} u128; + +#ifdef TABLE_BITS +# undef TABLE_BITS +#endif +/* + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should + * never be set to 8 [or 1]. For further information see gcm128.c. + */ +#define TABLE_BITS 4 + +struct gcm128_context { + /* Following 6 names follow names in GCM specification */ + union { + u64 u[2]; + u32 d[4]; + u8 c[16]; + size_t t[16 / sizeof(size_t)]; + } Yi, EKi, EK0, len, Xi, H; + /* + * Relative position of Xi, H and pre-computed Htable is used in some + * assembler modules, i.e. don't change the order! + */ +#if TABLE_BITS==8 + u128 Htable[256]; +#else + u128 Htable[16]; + void (*gmult) (u64 Xi[2], const u128 Htable[16]); + void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +#endif + unsigned int mres, ares; + block128_f block; + void *key; +}; + +struct xts128_context { + void *key1, *key2; + block128_f block1, block2; +}; + +struct ccm128_context { + union { + u64 u[2]; + u8 c[16]; + } nonce, cmac; + u64 blocks; + block128_f block; + void *key; +}; diff --git a/Sources/COpenSSL/n_pkey.c b/Sources/COpenSSL/n_pkey.c new file mode 100644 index 00000000..4641059e --- /dev/null +++ b/Sources/COpenSSL/n_pkey.c @@ -0,0 +1,345 @@ +/* crypto/asn1/n_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +# include "objects.h" +# include "asn1t.h" +# include "asn1_mac.h" +# include "evp.h" +# include "x509.h" + +# ifndef OPENSSL_NO_RC4 + +typedef struct netscape_pkey_st { + long version; + X509_ALGOR *algor; + ASN1_OCTET_STRING *private_key; +} NETSCAPE_PKEY; + +typedef struct netscape_encrypted_pkey_st { + ASN1_OCTET_STRING *os; + /* + * This is the same structure as DigestInfo so use it: although this + * isn't really anything to do with digests. + */ + X509_SIG *enckey; +} NETSCAPE_ENCRYPTED_PKEY; + + +ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = { + ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING), + ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG) +} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY) + +DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY) +IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY) + +ASN1_SEQUENCE(NETSCAPE_PKEY) = { + ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG), + ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR), + ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(NETSCAPE_PKEY) + +DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY) +IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) + +static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey); + +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify)) +{ + return i2d_RSA_NET(a, pp, cb, 0); +} + +int i2d_RSA_NET(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey) +{ + int i, j, ret = 0; + int rsalen, pkeylen, olen; + NETSCAPE_PKEY *pkey = NULL; + NETSCAPE_ENCRYPTED_PKEY *enckey = NULL; + unsigned char buf[256], *zz; + unsigned char key[EVP_MAX_KEY_LENGTH]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (a == NULL) + return (0); + + if ((pkey = NETSCAPE_PKEY_new()) == NULL) + goto err; + if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL) + goto err; + pkey->version = 0; + + pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption); + if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL) + goto err; + pkey->algor->parameter->type = V_ASN1_NULL; + + rsalen = i2d_RSAPrivateKey(a, NULL); + + /* + * Fake some octet strings just for the initial length calculation. + */ + + pkey->private_key->length = rsalen; + + pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL); + + enckey->enckey->digest->length = pkeylen; + + enckey->os->length = 11; /* "private-key" */ + + enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4); + if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL) + goto err; + enckey->enckey->algor->parameter->type = V_ASN1_NULL; + + if (pp == NULL) { + olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL); + NETSCAPE_PKEY_free(pkey); + NETSCAPE_ENCRYPTED_PKEY_free(enckey); + return olen; + } + + /* Since its RC4 encrypted length is actual length */ + if ((zz = (unsigned char *)OPENSSL_malloc(rsalen)) == NULL) { + ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); + goto err; + } + + pkey->private_key->data = zz; + /* Write out private key encoding */ + i2d_RSAPrivateKey(a, &zz); + + if ((zz = OPENSSL_malloc(pkeylen)) == NULL) { + ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!ASN1_STRING_set(enckey->os, "private-key", -1)) { + ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); + goto err; + } + enckey->enckey->digest->data = zz; + i2d_NETSCAPE_PKEY(pkey, &zz); + + /* Wipe the private key encoding */ + OPENSSL_cleanse(pkey->private_key->data, rsalen); + + if (cb == NULL) + cb = EVP_read_pw_string; + i = cb((char *)buf, 256, "Enter Private Key password:", 1); + if (i != 0) { + ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ); + goto err; + } + i = strlen((char *)buf); + /* If the key is used for SGC the algorithm is modified a little. */ + if (sgckey) { + if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL)) + goto err; + memcpy(buf + 16, "SGCKEYSALT", 10); + i = 26; + } + + if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL)) + goto err; + OPENSSL_cleanse(buf, 256); + + /* Encrypt private key in place */ + zz = enckey->enckey->digest->data; + if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL)) + goto err; + if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen)) + goto err; + if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j)) + goto err; + + ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp); + err: + EVP_CIPHER_CTX_cleanup(&ctx); + NETSCAPE_ENCRYPTED_PKEY_free(enckey); + NETSCAPE_PKEY_free(pkey); + return (ret); +} + +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify)) +{ + return d2i_RSA_NET(a, pp, length, cb, 0); +} + +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey) +{ + RSA *ret = NULL; + const unsigned char *p; + NETSCAPE_ENCRYPTED_PKEY *enckey = NULL; + + p = *pp; + + enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length); + if (!enckey) { + ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_DECODING_ERROR); + return NULL; + } + + if ((enckey->os->length != 11) || (strncmp("private-key", + (char *)enckey->os->data, + 11) != 0)) { + ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING); + NETSCAPE_ENCRYPTED_PKEY_free(enckey); + return NULL; + } + if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) { + ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM); + goto err; + } + if (cb == NULL) + cb = EVP_read_pw_string; + if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb, sgckey)) == NULL) + goto err; + + *pp = p; + + err: + NETSCAPE_ENCRYPTED_PKEY_free(enckey); + return ret; + +} + +static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey) +{ + NETSCAPE_PKEY *pkey = NULL; + RSA *ret = NULL; + int i, j; + unsigned char buf[256]; + const unsigned char *zz; + unsigned char key[EVP_MAX_KEY_LENGTH]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + i = cb((char *)buf, 256, "Enter Private Key password:", 0); + if (i != 0) { + ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_BAD_PASSWORD_READ); + goto err; + } + + i = strlen((char *)buf); + if (sgckey) { + if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL)) + goto err; + memcpy(buf + 16, "SGCKEYSALT", 10); + i = 26; + } + + if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL)) + goto err; + OPENSSL_cleanse(buf, 256); + + if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL)) + goto err; + if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length)) + goto err; + if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j)) + goto err; + os->length = i + j; + + zz = os->data; + + if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) { + ASN1err(ASN1_F_D2I_RSA_NET_2, + ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY); + goto err; + } + + zz = pkey->private_key->data; + if ((ret = d2i_RSAPrivateKey(a, &zz, pkey->private_key->length)) == NULL) { + ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_UNABLE_TO_DECODE_RSA_KEY); + goto err; + } + err: + EVP_CIPHER_CTX_cleanup(&ctx); + NETSCAPE_PKEY_free(pkey); + return (ret); +} + +# endif /* OPENSSL_NO_RC4 */ + +#else /* !OPENSSL_NO_RSA */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/Sources/COpenSSL/names.c b/Sources/COpenSSL/names.c new file mode 100644 index 00000000..c6a73084 --- /dev/null +++ b/Sources/COpenSSL/names.c @@ -0,0 +1,215 @@ +/* crypto/evp/names.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "objects.h" +#include "x509.h" + +int EVP_add_cipher(const EVP_CIPHER *c) +{ + int r; + + if (c == NULL) + return 0; + + OPENSSL_init(); + + r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH, + (const char *)c); + if (r == 0) + return (0); + check_defer(c->nid); + r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH, + (const char *)c); + return (r); +} + +int EVP_add_digest(const EVP_MD *md) +{ + int r; + const char *name; + OPENSSL_init(); + + name = OBJ_nid2sn(md->type); + r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md); + if (r == 0) + return (0); + check_defer(md->type); + r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH, + (const char *)md); + if (r == 0) + return (0); + + if (md->pkey_type && md->type != md->pkey_type) { + r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type), + OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name); + if (r == 0) + return (0); + check_defer(md->pkey_type); + r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type), + OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name); + } + return (r); +} + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name) +{ + const EVP_CIPHER *cp; + + cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); + return (cp); +} + +const EVP_MD *EVP_get_digestbyname(const char *name) +{ + const EVP_MD *cp; + + cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); + return (cp); +} + +void EVP_cleanup(void) +{ + OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH); + OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH); + /* + * The above calls will only clean out the contents of the name hash + * table, but not the hash table itself. The following line does that + * part. -- Richard Levitte + */ + OBJ_NAME_cleanup(-1); + + EVP_PBE_cleanup(); + if (obj_cleanup_defer == 2) { + obj_cleanup_defer = 0; + OBJ_cleanup(); + } + OBJ_sigid_free(); +} + +struct doall_cipher { + void *arg; + void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *arg); +}; + +static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg) +{ + struct doall_cipher *dc = arg; + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg); +} + +void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), + void *arg) +{ + struct doall_cipher dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); +} + +void EVP_CIPHER_do_all_sorted(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, + void *x), void *arg) +{ + struct doall_cipher dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); +} + +struct doall_md { + void *arg; + void (*fn) (const EVP_MD *ciph, + const char *from, const char *to, void *arg); +}; + +static void do_all_md_fn(const OBJ_NAME *nm, void *arg) +{ + struct doall_md *dc = arg; + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg); +} + +void EVP_MD_do_all(void (*fn) (const EVP_MD *md, + const char *from, const char *to, void *x), + void *arg) +{ + struct doall_md dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); +} + +void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md, + const char *from, const char *to, + void *x), void *arg) +{ + struct doall_md dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); +} diff --git a/Sources/COpenSSL/ncbc_enc.h b/Sources/COpenSSL/ncbc_enc.h new file mode 100644 index 00000000..ab267cbf --- /dev/null +++ b/Sources/COpenSSL/ncbc_enc.h @@ -0,0 +1,154 @@ +/* crypto/des/ncbc_enc.c */ +/*- + * #included by: + * cbc_enc.c (DES_cbc_encrypt) + * des_enc.c (DES_ncbc_encrypt) + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +#ifdef CBC_ENC_C__DONT_UPDATE_IV +void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + DES_key_schedule *_schedule, DES_cblock *ivec, int enc) +#else +void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *_schedule, + DES_cblock *ivec, int enc) +#endif +{ + register DES_LONG tin0, tin1; + register DES_LONG tout0, tout1, xor0, xor1; + register long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } +#ifndef CBC_ENC_C__DONT_UPDATE_IV + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); +#endif + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); +#ifndef CBC_ENC_C__DONT_UPDATE_IV + xor0 = tin0; + xor1 = tin1; +#endif + } +#ifndef CBC_ENC_C__DONT_UPDATE_IV + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); +#endif + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} diff --git a/Sources/COpenSSL/nsseq.c b/Sources/COpenSSL/nsseq.c new file mode 100644 index 00000000..cbcdb0fa --- /dev/null +++ b/Sources/COpenSSL/nsseq.c @@ -0,0 +1,84 @@ +/* nsseq.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "asn1t.h" +#include "x509.h" +#include "objects.h" + +static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_POST) { + NETSCAPE_CERT_SEQUENCE *nsseq; + nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval; + nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence); + } + return 1; +} + +/* Netscape certificate sequence structure */ + +ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = { + ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT), + ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0) +} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) diff --git a/Sources/COpenSSL/o_.c b/Sources/COpenSSL/o_.c new file mode 100644 index 00000000..bbb007d7 --- /dev/null +++ b/Sources/COpenSSL/o_.c @@ -0,0 +1,1235 @@ +/* crypto/o_dir.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "e_os.h" + +/* + * The routines really come from the Levitte Programming, so to make life + * simple, let's just use the raw files and hack the symbols to fit our + * namespace. + */ +#define LP_DIR_CTX OPENSSL_DIR_CTX +#define LP_dir_context_st OPENSSL_dir_context_st +#define LP_find_file OPENSSL_DIR_read +#define LP_find_file_end OPENSSL_DIR_end + +#include "o_dir.h" + +#define LPDIR_H +#if defined OPENSSL_SYS_UNIX || defined DJGPP \ + || (defined __VMS_VER && __VMS_VER >= 70000000) +# include "LPdir_unix.h" +#elif defined OPENSSL_SYS_VMS +# include "LPdir_vms.c" +#elif defined OPENSSL_SYS_WIN32 +# include "LPdir_win32.c" +#elif defined OPENSSL_SYS_WINCE +# include "LPdir_wince.c" +#else +# include "LPdir_nyi.c" +#endif +/* + * Written by Stephen henson (steve@openssl.org) for the OpenSSL project + * 2011. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#ifdef OPENSSL_FIPS +# include +# include +# include "rand.h" +#endif + +int FIPS_mode(void) +{ + OPENSSL_init(); +#ifdef OPENSSL_FIPS + return FIPS_module_mode(); +#else + return 0; +#endif +} + +int FIPS_mode_set(int r) +{ + OPENSSL_init(); +#ifdef OPENSSL_FIPS +# ifndef FIPS_AUTH_USER_PASS +# define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password" +# endif + if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS)) + return 0; + if (r) + RAND_set_rand_method(FIPS_rand_get_method()); + else + RAND_set_rand_method(NULL); + return 1; +#else + if (r == 0) + return 1; + CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED); + return 0; +#endif +} +/* o_init.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "e_os.h" +#include "err.h" +#ifdef OPENSSL_FIPS +# include +# include "rand.h" + +# ifndef OPENSSL_NO_DEPRECATED +/* the prototype is missing in */ +void FIPS_crypto_set_id_callback(unsigned long (*func)(void)); +# endif +#endif + +/* + * Perform any essential OpenSSL initialization operations. Currently only + * sets FIPS callbacks + */ + +void OPENSSL_init(void) +{ + static int done = 0; + if (done) + return; + done = 1; +#ifdef OPENSSL_FIPS + FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock); +# ifndef OPENSSL_NO_DEPRECATED + FIPS_crypto_set_id_callback(CRYPTO_thread_id); +# endif + FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); + FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); + RAND_init_fips(); +#endif +#if 0 + fprintf(stderr, "Called OPENSSL_init\n"); +#endif +} +#include +#include +#include + +// #include "err.h" +#include "lhash.h" +#include "objects.h" +#include "safestack.h" +#include "e_os2.h" + +/* + * Later versions of DEC C has started to add lnkage information to certain + * functions, which makes it tricky to use them as values to regular function + * pointers. One way is to define a macro that takes care of casting them + * correctly. + */ +#ifdef OPENSSL_SYS_VMS_DECC +# define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp +#else +# define OPENSSL_strcmp strcmp +#endif + +/* + * I use the ex_data stuff to manage the identifiers for the obj_name_types + * that applications may define. I only really use the free function field. + */ +DECLARE_LHASH_OF(OBJ_NAME); +static LHASH_OF(OBJ_NAME) *names_lh = NULL; +static int names_type_num = OBJ_NAME_TYPE_NUM; + +typedef struct name_funcs_st { + unsigned long (*hash_func) (const char *name); + int (*cmp_func) (const char *a, const char *b); + void (*free_func) (const char *, int, const char *); +} NAME_FUNCS; + +DECLARE_STACK_OF(NAME_FUNCS) +IMPLEMENT_STACK_OF(NAME_FUNCS) + +static STACK_OF(NAME_FUNCS) *name_funcs_stack; + +/* + * The LHASH callbacks now use the raw "void *" prototypes and do + * per-variable casting in the functions. This prevents function pointer + * casting without the need for macro-generated wrapper functions. + */ + +/* static unsigned long obj_name_hash(OBJ_NAME *a); */ +static unsigned long obj_name_hash(const void *a_void); +/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */ +static int obj_name_cmp(const void *a_void, const void *b_void); + +static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME) +static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME) + +int OBJ_NAME_init(void) +{ + if (names_lh != NULL) + return (1); + MemCheck_off(); + names_lh = lh_OBJ_NAME_new(); + MemCheck_on(); + return (names_lh != NULL); +} + +int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), + int (*cmp_func) (const char *, const char *), + void (*free_func) (const char *, int, const char *)) +{ + int ret; + int i; + NAME_FUNCS *name_funcs; + + if (name_funcs_stack == NULL) { + MemCheck_off(); + name_funcs_stack = sk_NAME_FUNCS_new_null(); + MemCheck_on(); + } + if (name_funcs_stack == NULL) { + /* ERROR */ + return (0); + } + ret = names_type_num; + names_type_num++; + for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { + MemCheck_off(); + name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS)); + MemCheck_on(); + if (!name_funcs) { + OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); + return (0); + } + name_funcs->hash_func = lh_strhash; + name_funcs->cmp_func = OPENSSL_strcmp; + name_funcs->free_func = 0; /* NULL is often declared to * ((void + * *)0), which according * to Compaq C is + * not really * compatible with a function + * * pointer. -- Richard Levitte */ + MemCheck_off(); + sk_NAME_FUNCS_push(name_funcs_stack, name_funcs); + MemCheck_on(); + } + name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret); + if (hash_func != NULL) + name_funcs->hash_func = hash_func; + if (cmp_func != NULL) + name_funcs->cmp_func = cmp_func; + if (free_func != NULL) + name_funcs->free_func = free_func; + return (ret); +} + +/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */ +static int obj_name_cmp(const void *a_void, const void *b_void) +{ + int ret; + const OBJ_NAME *a = (const OBJ_NAME *)a_void; + const OBJ_NAME *b = (const OBJ_NAME *)b_void; + + ret = a->type - b->type; + if (ret == 0) { + if ((name_funcs_stack != NULL) + && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { + ret = sk_NAME_FUNCS_value(name_funcs_stack, + a->type)->cmp_func(a->name, b->name); + } else + ret = strcmp(a->name, b->name); + } + return (ret); +} + +/* static unsigned long obj_name_hash(OBJ_NAME *a) */ +static unsigned long obj_name_hash(const void *a_void) +{ + unsigned long ret; + const OBJ_NAME *a = (const OBJ_NAME *)a_void; + + if ((name_funcs_stack != NULL) + && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { + ret = + sk_NAME_FUNCS_value(name_funcs_stack, + a->type)->hash_func(a->name); + } else { + ret = lh_strhash(a->name); + } + ret ^= a->type; + return (ret); +} + +const char *OBJ_NAME_get(const char *name, int type) +{ + OBJ_NAME on, *ret; + int num = 0, alias; + + if (name == NULL) + return (NULL); + if ((names_lh == NULL) && !OBJ_NAME_init()) + return (NULL); + + alias = type & OBJ_NAME_ALIAS; + type &= ~OBJ_NAME_ALIAS; + + on.name = name; + on.type = type; + + for (;;) { + ret = lh_OBJ_NAME_retrieve(names_lh, &on); + if (ret == NULL) + return (NULL); + if ((ret->alias) && !alias) { + if (++num > 10) + return (NULL); + on.name = ret->data; + } else { + return (ret->data); + } + } +} + +int OBJ_NAME_add(const char *name, int type, const char *data) +{ + OBJ_NAME *onp, *ret; + int alias; + + if ((names_lh == NULL) && !OBJ_NAME_init()) + return (0); + + alias = type & OBJ_NAME_ALIAS; + type &= ~OBJ_NAME_ALIAS; + + onp = (OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME)); + if (onp == NULL) { + /* ERROR */ + return 0; + } + + onp->name = name; + onp->alias = alias; + onp->type = type; + onp->data = data; + + ret = lh_OBJ_NAME_insert(names_lh, onp); + if (ret != NULL) { + /* free things */ + if ((name_funcs_stack != NULL) + && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { + /* + * XXX: I'm not sure I understand why the free function should + * get three arguments... -- Richard Levitte + */ + sk_NAME_FUNCS_value(name_funcs_stack, + ret->type)->free_func(ret->name, ret->type, + ret->data); + } + OPENSSL_free(ret); + } else { + if (lh_OBJ_NAME_error(names_lh)) { + /* ERROR */ + OPENSSL_free(onp); + return 0; + } + } + return 1; +} + +int OBJ_NAME_remove(const char *name, int type) +{ + OBJ_NAME on, *ret; + + if (names_lh == NULL) + return (0); + + type &= ~OBJ_NAME_ALIAS; + on.name = name; + on.type = type; + ret = lh_OBJ_NAME_delete(names_lh, &on); + if (ret != NULL) { + /* free things */ + if ((name_funcs_stack != NULL) + && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { + /* + * XXX: I'm not sure I understand why the free function should + * get three arguments... -- Richard Levitte + */ + sk_NAME_FUNCS_value(name_funcs_stack, + ret->type)->free_func(ret->name, ret->type, + ret->data); + } + OPENSSL_free(ret); + return (1); + } else + return (0); +} + +struct doall { + int type; + void (*fn) (const OBJ_NAME *, void *arg); + void *arg; +}; + +static void do_all_fn_doall_arg(const OBJ_NAME *name, struct doall *d) +{ + if (name->type == d->type) + d->fn(name, d->arg); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall) + +void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), + void *arg) +{ + struct doall d; + + d.type = type; + d.fn = fn; + d.arg = arg; + + lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn), + struct doall, &d); +} + +struct doall_sorted { + int type; + int n; + const OBJ_NAME **names; +}; + +static void do_all_sorted_fn(const OBJ_NAME *name, void *d_) +{ + struct doall_sorted *d = d_; + + if (name->type != d->type) + return; + + d->names[d->n++] = name; +} + +static int do_all_sorted_cmp(const void *n1_, const void *n2_) +{ + const OBJ_NAME *const *n1 = n1_; + const OBJ_NAME *const *n2 = n2_; + + return strcmp((*n1)->name, (*n2)->name); +} + +void OBJ_NAME_do_all_sorted(int type, + void (*fn) (const OBJ_NAME *, void *arg), + void *arg) +{ + struct doall_sorted d; + int n; + + d.type = type; + d.names = + OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh) * sizeof(*d.names)); + /* Really should return an error if !d.names...but its a void function! */ + if (d.names) { + d.n = 0; + OBJ_NAME_do_all(type, do_all_sorted_fn, &d); + + qsort((void *)d.names, d.n, sizeof(*d.names), do_all_sorted_cmp); + + for (n = 0; n < d.n; ++n) + fn(d.names[n], arg); + + OPENSSL_free((void *)d.names); + } +} + +static int free_type; + +static void names_lh_free_doall(OBJ_NAME *onp) +{ + if (onp == NULL) + return; + + if (free_type < 0 || free_type == onp->type) + OBJ_NAME_remove(onp->name, onp->type); +} + +static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME) + +static void name_funcs_free(NAME_FUNCS *ptr) +{ + OPENSSL_free(ptr); +} + +void OBJ_NAME_cleanup(int type) +{ + unsigned long down_load; + + if (names_lh == NULL) + return; + + free_type = type; + down_load = lh_OBJ_NAME_down_load(names_lh); + lh_OBJ_NAME_down_load(names_lh) = 0; + + lh_OBJ_NAME_doall(names_lh, LHASH_DOALL_FN(names_lh_free)); + if (type < 0) { + lh_OBJ_NAME_free(names_lh); + sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free); + names_lh = NULL; + name_funcs_stack = NULL; + } else + lh_OBJ_NAME_down_load(names_lh) = down_load; +} +/* crypto/o_str.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "e_os.h" +#include "o_str.h" + +#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \ + !defined(OPENSSL_SYSNAME_WIN32) && !defined(OPENSSL_SYSNAME_WINCE) && \ + !defined(NETWARE_CLIB) +# include +#endif + +int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n) +{ +#if defined(OPENSSL_IMPLEMENTS_strncasecmp) + while (*str1 && *str2 && n) { + int res = toupper(*str1) - toupper(*str2); + if (res) + return res < 0 ? -1 : 1; + str1++; + str2++; + n--; + } + if (n == 0) + return 0; + if (*str1) + return 1; + if (*str2) + return -1; + return 0; +#else + /* + * Recursion hazard warning! Whenever strncasecmp is #defined as + * OPENSSL_strncasecmp, OPENSSL_IMPLEMENTS_strncasecmp must be defined as + * well. + */ + return strncasecmp(str1, str2, n); +#endif +} + +int OPENSSL_strcasecmp(const char *str1, const char *str2) +{ +#if defined(OPENSSL_IMPLEMENTS_strncasecmp) + return OPENSSL_strncasecmp(str1, str2, (size_t)-1); +#else + return strcasecmp(str1, str2); +#endif +} + +int OPENSSL_memcmp(const void *v1, const void *v2, size_t n) +{ + const unsigned char *c1 = v1, *c2 = v2; + int ret = 0; + + while (n && (ret = *c1 - *c2) == 0) + n--, c1++, c2++; + + return ret; +} +/* crypto/o_time.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2008. + */ +/* ==================================================================== + * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "e_os2.h" +#include +#include "o_time.h" + +#ifdef OPENSSL_SYS_VMS +# if __CRTL_VER >= 70000000 && \ + (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE) +# define VMS_GMTIME_OK +# endif +# ifndef VMS_GMTIME_OK +# include +# include +# include +# include +# include +# include +# endif /* ndef VMS_GMTIME_OK */ + + +/* + * Needed to pick up the correct definitions and declarations in some of the + * DEC C Header Files (*.H). + */ +# define __NEW_STARLET 1 + +# if (defined(__alpha) || defined(__ia64)) +# include +# else + +/* VAX */ +typedef struct _ile3 { /* Copied from ILEDEF.H for Alpha */ +# pragma __nomember_alignment + unsigned short int ile3$w_length; /* Length of buffer in bytes */ + unsigned short int ile3$w_code; /* Item code value */ + void *ile3$ps_bufaddr; /* Buffer address */ + unsigned short int *ile3$ps_retlen_addr; /* Address of word for returned length */ +} ILE3; +# endif /* alpha || ia64 */ +#endif /* OPENSSL_SYS_VMS */ + +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) +{ + struct tm *ts = NULL; + +#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_SUNOS) + if (gmtime_r(timer, result) == NULL) + return NULL; + ts = result; +#elif defined (OPENSSL_SYS_WINDOWS) && defined(_MSC_VER) && _MSC_VER >= 1400 + if (gmtime_s(result, timer)) + return NULL; + ts = result; +#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK) + ts = gmtime(timer); + if (ts == NULL) + return NULL; + + memcpy(result, ts, sizeof(struct tm)); + ts = result; +#endif +#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK) + if (ts == NULL) { + static $DESCRIPTOR(tabnam, "LNM$DCL_LOGICAL"); + static $DESCRIPTOR(lognam, "SYS$TIMEZONE_DIFFERENTIAL"); + char logvalue[256]; + unsigned int reslen = 0; +# if __INITIAL_POINTER_SIZE == 64 + ILEB_64 itemlist[2], *pitem; +# else + ILE3 itemlist[2], *pitem; +# endif + int status; + time_t t; + + + /* + * Setup an itemlist for the call to $TRNLNM - Translate Logical Name. + */ + pitem = itemlist; + +# if __INITIAL_POINTER_SIZE == 64 + pitem->ileb_64$w_mbo = 1; + pitem->ileb_64$w_code = LNM$_STRING; + pitem->ileb_64$l_mbmo = -1; + pitem->ileb_64$q_length = sizeof(logvalue); + pitem->ileb_64$pq_bufaddr = logvalue; + pitem->ileb_64$pq_retlen_addr = (unsigned __int64 *) &reslen; + pitem++; + /* Last item of the item list is null terminated */ + pitem->ileb_64$q_length = pitem->ileb_64$w_code = 0; +# else + pitem->ile3$w_length = sizeof(logvalue); + pitem->ile3$w_code = LNM$_STRING; + pitem->ile3$ps_bufaddr = logvalue; + pitem->ile3$ps_retlen_addr = (unsigned short int *) &reslen; + pitem++; + /* Last item of the item list is null terminated */ + pitem->ile3$w_length = pitem->ile3$w_code = 0; +# endif + + + /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */ + status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist); + if (!(status & 1)) + return NULL; + logvalue[reslen] = '\0'; + + t = *timer; + + /* The following is extracted from the DEC C header time.h */ + /* + ** Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime + ** have two implementations. One implementation is provided + ** for compatibility and deals with time in terms of local time, + ** the other __utc_* deals with time in terms of UTC. + */ + /* + * We use the same conditions as in said time.h to check if we should + * assume that t contains local time (and should therefore be + * adjusted) or UTC (and should therefore be left untouched). + */ +# if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE + /* Get the numerical value of the equivalence string */ + status = atoi(logvalue); + + /* and use it to move time to GMT */ + t -= status; +# endif + + /* then convert the result to the time structure */ + + /* + * Since there was no gmtime_r() to do this stuff for us, we have to + * do it the hard way. + */ + { + /*- + * The VMS epoch is the astronomical Smithsonian date, + if I remember correctly, which is November 17, 1858. + Furthermore, time is measure in thenths of microseconds + and stored in quadwords (64 bit integers). unix_epoch + below is January 1st 1970 expressed as a VMS time. The + following code was used to get this number: + + #include + #include + #include + #include + + main() + { + unsigned long systime[2]; + unsigned short epoch_values[7] = + { 1970, 1, 1, 0, 0, 0, 0 }; + + lib$cvt_vectim(epoch_values, systime); + + printf("%u %u", systime[0], systime[1]); + } + */ + unsigned long unix_epoch[2] = { 1273708544, 8164711 }; + unsigned long deltatime[2]; + unsigned long systime[2]; + struct vms_vectime { + short year, month, day, hour, minute, second, centi_second; + } time_values; + long operation; + + /* + * Turn the number of seconds since January 1st 1970 to an + * internal delta time. Note that lib$cvt_to_internal_time() will + * assume that t is signed, and will therefore break on 32-bit + * systems some time in 2038. + */ + operation = LIB$K_DELTA_SECONDS; + status = lib$cvt_to_internal_time(&operation, &t, deltatime); + + /* + * Add the delta time with the Unix epoch and we have the current + * UTC time in internal format + */ + status = lib$add_times(unix_epoch, deltatime, systime); + + /* Turn the internal time into a time vector */ + status = sys$numtim(&time_values, systime); + + /* Fill in the struct tm with the result */ + result->tm_sec = time_values.second; + result->tm_min = time_values.minute; + result->tm_hour = time_values.hour; + result->tm_mday = time_values.day; + result->tm_mon = time_values.month - 1; + result->tm_year = time_values.year - 1900; + + operation = LIB$K_DAY_OF_WEEK; + status = lib$cvt_from_internal_time(&operation, + &result->tm_wday, systime); + result->tm_wday %= 7; + + operation = LIB$K_DAY_OF_YEAR; + status = lib$cvt_from_internal_time(&operation, + &result->tm_yday, systime); + result->tm_yday--; + + result->tm_isdst = 0; /* There's no way to know... */ + + ts = result; + } + } +#endif + return ts; +} + +/* + * Take a tm structure and add an offset to it. This avoids any OS issues + * with restricted date types and overflows which cause the year 2038 + * problem. + */ + +#define SECS_PER_DAY (24 * 60 * 60) + +static long date_to_julian(int y, int m, int d); +static void julian_to_date(long jd, int *y, int *m, int *d); +static int julian_adj(const struct tm *tm, int off_day, long offset_sec, + long *pday, int *psec); + +int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) +{ + int time_sec, time_year, time_month, time_day; + long time_jd; + + /* Convert time and offset into julian day and seconds */ + if (!julian_adj(tm, off_day, offset_sec, &time_jd, &time_sec)) + return 0; + + /* Convert Julian day back to date */ + + julian_to_date(time_jd, &time_year, &time_month, &time_day); + + if (time_year < 1900 || time_year > 9999) + return 0; + + /* Update tm structure */ + + tm->tm_year = time_year - 1900; + tm->tm_mon = time_month - 1; + tm->tm_mday = time_day; + + tm->tm_hour = time_sec / 3600; + tm->tm_min = (time_sec / 60) % 60; + tm->tm_sec = time_sec % 60; + + return 1; + +} + +int OPENSSL_gmtime_diff(int *pday, int *psec, + const struct tm *from, const struct tm *to) +{ + int from_sec, to_sec, diff_sec; + long from_jd, to_jd, diff_day; + if (!julian_adj(from, 0, 0, &from_jd, &from_sec)) + return 0; + if (!julian_adj(to, 0, 0, &to_jd, &to_sec)) + return 0; + diff_day = to_jd - from_jd; + diff_sec = to_sec - from_sec; + /* Adjust differences so both positive or both negative */ + if (diff_day > 0 && diff_sec < 0) { + diff_day--; + diff_sec += SECS_PER_DAY; + } + if (diff_day < 0 && diff_sec > 0) { + diff_day++; + diff_sec -= SECS_PER_DAY; + } + + if (pday) + *pday = (int)diff_day; + if (psec) + *psec = diff_sec; + + return 1; + +} + +/* Convert tm structure and offset into julian day and seconds */ +static int julian_adj(const struct tm *tm, int off_day, long offset_sec, + long *pday, int *psec) +{ + int offset_hms, offset_day; + long time_jd; + int time_year, time_month, time_day; + /* split offset into days and day seconds */ + offset_day = offset_sec / SECS_PER_DAY; + /* Avoid sign issues with % operator */ + offset_hms = offset_sec - (offset_day * SECS_PER_DAY); + offset_day += off_day; + /* Add current time seconds to offset */ + offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; + /* Adjust day seconds if overflow */ + if (offset_hms >= SECS_PER_DAY) { + offset_day++; + offset_hms -= SECS_PER_DAY; + } else if (offset_hms < 0) { + offset_day--; + offset_hms += SECS_PER_DAY; + } + + /* + * Convert date of time structure into a Julian day number. + */ + + time_year = tm->tm_year + 1900; + time_month = tm->tm_mon + 1; + time_day = tm->tm_mday; + + time_jd = date_to_julian(time_year, time_month, time_day); + + /* Work out Julian day of new date */ + time_jd += offset_day; + + if (time_jd < 0) + return 0; + + *pday = time_jd; + *psec = offset_hms; + return 1; +} + +/* + * Convert date to and from julian day Uses Fliegel & Van Flandern algorithm + */ +static long date_to_julian(int y, int m, int d) +{ + return (1461 * (y + 4800 + (m - 14) / 12)) / 4 + + (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - + (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075; +} + +static void julian_to_date(long jd, int *y, int *m, int *d) +{ + long L = jd + 68569; + long n = (4 * L) / 146097; + long i, j; + + L = L - (146097 * n + 3) / 4; + i = (4000 * (L + 1)) / 1461001; + L = L - (1461 * i) / 4 + 31; + j = (80 * L) / 2447; + *d = L - (2447 * j) / 80; + L = j / 11; + *m = j + 2 - (12 * L); + *y = 100 * (n - 49) + i + L; +} + +#ifdef OPENSSL_TIME_TEST + +# include + +/* + * Time checking test code. Check times are identical for a wide range of + * offsets. This should be run on a machine with 64 bit time_t or it will + * trigger the very errors the routines fix. + */ + +int main(int argc, char **argv) +{ + long offset; + for (offset = 0; offset < 1000000; offset++) { + check_time(offset); + check_time(-offset); + check_time(offset * 1000); + check_time(-offset * 1000); + } +} + +int check_time(long offset) +{ + struct tm tm1, tm2, o1; + int off_day, off_sec; + long toffset; + time_t t1, t2; + time(&t1); + t2 = t1 + offset; + OPENSSL_gmtime(&t2, &tm2); + OPENSSL_gmtime(&t1, &tm1); + o1 = tm1; + OPENSSL_gmtime_adj(&tm1, 0, offset); + if ((tm1.tm_year != tm2.tm_year) || + (tm1.tm_mon != tm2.tm_mon) || + (tm1.tm_mday != tm2.tm_mday) || + (tm1.tm_hour != tm2.tm_hour) || + (tm1.tm_min != tm2.tm_min) || (tm1.tm_sec != tm2.tm_sec)) { + fprintf(stderr, "TIME ERROR!!\n"); + fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n", + tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900, + tm2.tm_hour, tm2.tm_min, tm2.tm_sec); + fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n", + tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900, + tm1.tm_hour, tm1.tm_min, tm1.tm_sec); + return 0; + } + OPENSSL_gmtime_diff(&o1, &tm1, &off_day, &off_sec); + toffset = (long)off_day *SECS_PER_DAY + off_sec; + if (offset != toffset) { + fprintf(stderr, "TIME OFFSET ERROR!!\n"); + fprintf(stderr, "Expected %ld, Got %ld (%d:%d)\n", + offset, toffset, off_day, off_sec); + return 0; + } + return 1; +} + +#endif diff --git a/Sources/COpenSSL/o_dir.h b/Sources/COpenSSL/o_dir.h new file mode 100644 index 00000000..bf45a14d --- /dev/null +++ b/Sources/COpenSSL/o_dir.h @@ -0,0 +1,55 @@ +/* crypto/o_dir.h */ +/* + * Copied from Richard Levitte's (richard@levitte.org) LP library. All + * symbol names have been changed, with permission from the author. + */ + +/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef O_DIR_H +# define O_DIR_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX; + + /* + * returns NULL on error or end-of-directory. If it is end-of-directory, + * errno will be zero + */ +const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory); + /* returns 1 on success, 0 on error */ +int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* LPDIR_H */ diff --git a/Sources/COpenSSL/o_str.h b/Sources/COpenSSL/o_str.h new file mode 100644 index 00000000..fa512eb3 --- /dev/null +++ b/Sources/COpenSSL/o_str.h @@ -0,0 +1,69 @@ +/* crypto/o_str.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_O_STR_H +# define HEADER_O_STR_H + +# include /* to get size_t */ + +int OPENSSL_strcasecmp(const char *str1, const char *str2); +int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n); +int OPENSSL_memcmp(const void *p1, const void *p2, size_t n); + +#endif diff --git a/Sources/COpenSSL/o_time.h b/Sources/COpenSSL/o_time.h new file mode 100644 index 00000000..f192c6dc --- /dev/null +++ b/Sources/COpenSSL/o_time.h @@ -0,0 +1,70 @@ +/* crypto/o_time.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_O_TIME_H +# define HEADER_O_TIME_H + +# include + +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); +int OPENSSL_gmtime_diff(int *pday, int *psec, + const struct tm *from, const struct tm *to); + +#endif diff --git a/Sources/COpenSSL/obj_.c b/Sources/COpenSSL/obj_.c new file mode 100644 index 00000000..02700251 --- /dev/null +++ b/Sources/COpenSSL/obj_.c @@ -0,0 +1,1264 @@ +/* crypto/objects/obj_dat.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" +#include "lhash.h" +#include "asn1.h" +#include "objects.h" +#include "bn.h" + +/* obj_dat.h is generated from objects.h by obj_dat.pl */ +#ifndef OPENSSL_NO_OBJECT +# include "obj_dat.h" +#else +/* You will have to load all the objects needed manually in the application */ +# define NUM_NID 0 +# define NUM_SN 0 +# define NUM_LN 0 +# define NUM_OBJ 0 +static const unsigned char lvalues[1]; +static const ASN1_OBJECT nid_objs[1]; +static const unsigned int sn_objs[1]; +static const unsigned int ln_objs[1]; +static const unsigned int obj_objs[1]; +#endif + +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); + +#define ADDED_DATA 0 +#define ADDED_SNAME 1 +#define ADDED_LNAME 2 +#define ADDED_NID 3 + +typedef struct added_obj_st { + int type; + ASN1_OBJECT *obj; +} ADDED_OBJ; +DECLARE_LHASH_OF(ADDED_OBJ); + +static int new_nid = NUM_NID; +static LHASH_OF(ADDED_OBJ) *added = NULL; + +static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) +{ + return (strcmp((*a)->sn, nid_objs[*b].sn)); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); + +static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) +{ + return (strcmp((*a)->ln, nid_objs[*b].ln)); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); + +static unsigned long added_obj_hash(const ADDED_OBJ *ca) +{ + const ASN1_OBJECT *a; + int i; + unsigned long ret = 0; + unsigned char *p; + + a = ca->obj; + switch (ca->type) { + case ADDED_DATA: + ret = a->length << 20L; + p = (unsigned char *)a->data; + for (i = 0; i < a->length; i++) + ret ^= p[i] << ((i * 3) % 24); + break; + case ADDED_SNAME: + ret = lh_strhash(a->sn); + break; + case ADDED_LNAME: + ret = lh_strhash(a->ln); + break; + case ADDED_NID: + ret = a->nid; + break; + default: + /* abort(); */ + return 0; + } + ret &= 0x3fffffffL; + ret |= ((unsigned long)ca->type) << 30L; + return (ret); +} + +static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ) + +static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) +{ + ASN1_OBJECT *a, *b; + int i; + + i = ca->type - cb->type; + if (i) + return (i); + a = ca->obj; + b = cb->obj; + switch (ca->type) { + case ADDED_DATA: + i = (a->length - b->length); + if (i) + return (i); + return (memcmp(a->data, b->data, (size_t)a->length)); + case ADDED_SNAME: + if (a->sn == NULL) + return (-1); + else if (b->sn == NULL) + return (1); + else + return (strcmp(a->sn, b->sn)); + case ADDED_LNAME: + if (a->ln == NULL) + return (-1); + else if (b->ln == NULL) + return (1); + else + return (strcmp(a->ln, b->ln)); + case ADDED_NID: + return (a->nid - b->nid); + default: + /* abort(); */ + return 0; + } +} + +static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ) + +static int init_added(void) +{ + if (added != NULL) + return (1); + added = lh_ADDED_OBJ_new(); + return (added != NULL); +} + +static void cleanup1_doall(ADDED_OBJ *a) +{ + a->obj->nid = 0; + a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC | + ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA; +} + +static void cleanup2_doall(ADDED_OBJ *a) +{ + a->obj->nid++; +} + +static void cleanup3_doall(ADDED_OBJ *a) +{ + if (--a->obj->nid == 0) + ASN1_OBJECT_free(a->obj); + OPENSSL_free(a); +} + +static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ) +static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ) +static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ) + +/* + * The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting to + * use freed up OIDs. If neccessary the actual freeing up of OIDs is delayed. + */ +int obj_cleanup_defer = 0; + +void check_defer(int nid) +{ + if (!obj_cleanup_defer && nid >= NUM_NID) + obj_cleanup_defer = 1; +} + +void OBJ_cleanup(void) +{ + if (obj_cleanup_defer) { + obj_cleanup_defer = 2; + return; + } + if (added == NULL) + return; + lh_ADDED_OBJ_down_load(added) = 0; + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */ + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */ + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */ + lh_ADDED_OBJ_free(added); + added = NULL; +} + +int OBJ_new_nid(int num) +{ + int i; + + i = new_nid; + new_nid += num; + return (i); +} + +int OBJ_add_object(const ASN1_OBJECT *obj) +{ + ASN1_OBJECT *o; + ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop; + int i; + + if (added == NULL) + if (!init_added()) + return (0); + if ((o = OBJ_dup(obj)) == NULL) + goto err; + if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + goto err2; + if ((o->length != 0) && (obj->data != NULL)) + if (! + (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + goto err2; + if (o->sn != NULL) + if (! + (ao[ADDED_SNAME] = + (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + goto err2; + if (o->ln != NULL) + if (! + (ao[ADDED_LNAME] = + (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + goto err2; + + for (i = ADDED_DATA; i <= ADDED_NID; i++) { + if (ao[i] != NULL) { + ao[i]->type = i; + ao[i]->obj = o; + aop = lh_ADDED_OBJ_insert(added, ao[i]); + /* memory leak, buit should not normally matter */ + if (aop != NULL) + OPENSSL_free(aop); + } + } + o->flags &= + ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + + return (o->nid); + err2: + OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE); + err: + for (i = ADDED_DATA; i <= ADDED_NID; i++) + if (ao[i] != NULL) + OPENSSL_free(ao[i]); + ASN1_OBJECT_free(o); + return NID_undef; +} + +ASN1_OBJECT *OBJ_nid2obj(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); + return (NULL); + } + return ((ASN1_OBJECT *)&(nid_objs[n])); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj); + else { + OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} + +const char *OBJ_nid2sn(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); + return (NULL); + } + return (nid_objs[n].sn); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->sn); + else { + OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} + +const char *OBJ_nid2ln(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); + return (NULL); + } + return (nid_objs[n].ln); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->ln); + else { + OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} + +static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp) +{ + int j; + const ASN1_OBJECT *a = *ap; + const ASN1_OBJECT *b = &nid_objs[*bp]; + + j = (a->length - b->length); + if (j) + return (j); + if (a->length == 0) + return 0; + return (memcmp(a->data, b->data, a->length)); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); + +int OBJ_obj2nid(const ASN1_OBJECT *a) +{ + const unsigned int *op; + ADDED_OBJ ad, *adp; + + if (a == NULL) + return (NID_undef); + if (a->nid != 0) + return (a->nid); + + if (a->length == 0) + return NID_undef; + + if (added != NULL) { + ad.type = ADDED_DATA; + ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} + +/* + * Convert an object name into an ASN1_OBJECT if "noname" is not set then + * search for short and long names first. This will convert the "dotted" form + * into an object: unlike OBJ_txt2nid it can be used with any objects, not + * just registered ones. + */ + +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) +{ + int nid = NID_undef; + ASN1_OBJECT *op = NULL; + unsigned char *buf; + unsigned char *p; + const unsigned char *cp; + int i, j; + + if (!no_name) { + if (((nid = OBJ_sn2nid(s)) != NID_undef) || + ((nid = OBJ_ln2nid(s)) != NID_undef)) + return OBJ_nid2obj(nid); + } + + /* Work out size of content octets */ + i = a2d_ASN1_OBJECT(NULL, 0, s, -1); + if (i <= 0) { + /* Don't clear the error */ + /* + * ERR_clear_error(); + */ + return NULL; + } + /* Work out total size */ + j = ASN1_object_size(0, i, V_ASN1_OBJECT); + + if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL) + return NULL; + + p = buf; + /* Write out tag+length */ + ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); + /* Write out contents */ + a2d_ASN1_OBJECT(p, i, s, -1); + + cp = buf; + op = d2i_ASN1_OBJECT(NULL, &cp, j); + OPENSSL_free(buf); + return op; +} + +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) +{ + int i, n = 0, len, nid, first, use_bn; + BIGNUM *bl; + unsigned long l; + const unsigned char *p; + char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2]; + + /* Ensure that, at every state, |buf| is NUL-terminated. */ + if (buf && buf_len > 0) + buf[0] = '\0'; + + if ((a == NULL) || (a->data == NULL)) + return (0); + + if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) { + const char *s; + s = OBJ_nid2ln(nid); + if (s == NULL) + s = OBJ_nid2sn(nid); + if (s) { + if (buf) + BUF_strlcpy(buf, s, buf_len); + n = strlen(s); + return n; + } + } + + len = a->length; + p = a->data; + + first = 1; + bl = NULL; + + while (len > 0) { + l = 0; + use_bn = 0; + for (;;) { + unsigned char c = *p++; + len--; + if ((len == 0) && (c & 0x80)) + goto err; + if (use_bn) { + if (!BN_add_word(bl, c & 0x7f)) + goto err; + } else + l |= c & 0x7f; + if (!(c & 0x80)) + break; + if (!use_bn && (l > (ULONG_MAX >> 7L))) { + if (!bl && !(bl = BN_new())) + goto err; + if (!BN_set_word(bl, l)) + goto err; + use_bn = 1; + } + if (use_bn) { + if (!BN_lshift(bl, bl, 7)) + goto err; + } else + l <<= 7L; + } + + if (first) { + first = 0; + if (l >= 80) { + i = 2; + if (use_bn) { + if (!BN_sub_word(bl, 80)) + goto err; + } else + l -= 80; + } else { + i = (int)(l / 40); + l -= (long)(i * 40); + } + if (buf && (buf_len > 1)) { + *buf++ = i + '0'; + *buf = '\0'; + buf_len--; + } + n++; + } + + if (use_bn) { + char *bndec; + bndec = BN_bn2dec(bl); + if (!bndec) + goto err; + i = strlen(bndec); + if (buf) { + if (buf_len > 1) { + *buf++ = '.'; + *buf = '\0'; + buf_len--; + } + BUF_strlcpy(buf, bndec, buf_len); + if (i > buf_len) { + buf += buf_len; + buf_len = 0; + } else { + buf += i; + buf_len -= i; + } + } + n++; + n += i; + OPENSSL_free(bndec); + } else { + BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l); + i = strlen(tbuf); + if (buf && (buf_len > 0)) { + BUF_strlcpy(buf, tbuf, buf_len); + if (i > buf_len) { + buf += buf_len; + buf_len = 0; + } else { + buf += i; + buf_len -= i; + } + } + n += i; + l = 0; + } + } + + if (bl) + BN_free(bl); + return n; + + err: + if (bl) + BN_free(bl); + return -1; +} + +int OBJ_txt2nid(const char *s) +{ + ASN1_OBJECT *obj; + int nid; + obj = OBJ_txt2obj(s, 0); + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + return nid; +} + +int OBJ_ln2nid(const char *s) +{ + ASN1_OBJECT o; + const ASN1_OBJECT *oo = &o; + ADDED_OBJ ad, *adp; + const unsigned int *op; + + o.ln = s; + if (added != NULL) { + ad.type = ADDED_LNAME; + ad.obj = &o; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} + +int OBJ_sn2nid(const char *s) +{ + ASN1_OBJECT o; + const ASN1_OBJECT *oo = &o; + ADDED_OBJ ad, *adp; + const unsigned int *op; + + o.sn = s; + if (added != NULL) { + ad.type = ADDED_SNAME; + ad.obj = &o; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} + +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp) (const void *, const void *)) +{ + return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); +} + +const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, + int size, + int (*cmp) (const void *, const void *), + int flags) +{ + const char *base = base_; + int l, h, i = 0, c = 0; + const char *p = NULL; + + if (num == 0) + return (NULL); + l = 0; + h = num; + while (l < h) { + i = (l + h) / 2; + p = &(base[i * size]); + c = (*cmp) (key, p); + if (c < 0) + h = i; + else if (c > 0) + l = i + 1; + else + break; + } +#ifdef CHARSET_EBCDIC + /* + * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I + * don't have perl (yet), we revert to a *LINEAR* search when the object + * wasn't found in the binary search. + */ + if (c != 0) { + for (i = 0; i < num; ++i) { + p = &(base[i * size]); + c = (*cmp) (key, p); + if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))) + return p; + } + } +#endif + if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)) + p = NULL; + else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) { + while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0) + i--; + p = &(base[i * size]); + } + return (p); +} + +/* + * Parse a BIO sink to create some extra oid's objects. + * Line format: + */ +int OBJ_create_objects(BIO *in) +{ + MS_STATIC char buf[512]; + int i, num = 0; + char *o, *s, *l = NULL; + + for (;;) { + s = o = NULL; + i = BIO_gets(in, buf, 512); + if (i <= 0) + return (num); + buf[i - 1] = '\0'; + if (!isalnum((unsigned char)buf[0])) + return (num); + o = s = buf; + while (isdigit((unsigned char)*s) || (*s == '.')) + s++; + if (*s != '\0') { + *(s++) = '\0'; + while (isspace((unsigned char)*s)) + s++; + if (*s == '\0') { + s = NULL; + } else { + l = s; + while ((*l != '\0') && !isspace((unsigned char)*l)) + l++; + if (*l != '\0') { + *(l++) = '\0'; + while (isspace((unsigned char)*l)) + l++; + if (*l == '\0') { + l = NULL; + } + } else { + l = NULL; + } + } + } else { + s = NULL; + } + if (*o == '\0') + return num; + if (!OBJ_create(o, s, l)) + return (num); + num++; + } + /* return(num); */ +} + +int OBJ_create(const char *oid, const char *sn, const char *ln) +{ + int ok = 0; + ASN1_OBJECT *op = NULL; + unsigned char *buf; + int i; + + i = a2d_ASN1_OBJECT(NULL, 0, oid, -1); + if (i <= 0) + return (0); + + if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) { + OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE); + return (0); + } + i = a2d_ASN1_OBJECT(buf, i, oid, -1); + if (i == 0) + goto err; + op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln); + if (op == NULL) + goto err; + ok = OBJ_add_object(op); + err: + ASN1_OBJECT_free(op); + OPENSSL_free(buf); + return (ok); +} +/* crypto/objects/obj_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "objects.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason) + +static ERR_STRING_DATA OBJ_str_functs[] = { + {ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT), "OBJ_add_object"}, + {ERR_FUNC(OBJ_F_OBJ_CREATE), "OBJ_create"}, + {ERR_FUNC(OBJ_F_OBJ_DUP), "OBJ_dup"}, + {ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX), "OBJ_NAME_new_index"}, + {ERR_FUNC(OBJ_F_OBJ_NID2LN), "OBJ_nid2ln"}, + {ERR_FUNC(OBJ_F_OBJ_NID2OBJ), "OBJ_nid2obj"}, + {ERR_FUNC(OBJ_F_OBJ_NID2SN), "OBJ_nid2sn"}, + {0, NULL} +}; + +static ERR_STRING_DATA OBJ_str_reasons[] = { + {ERR_REASON(OBJ_R_MALLOC_FAILURE), "malloc failure"}, + {ERR_REASON(OBJ_R_UNKNOWN_NID), "unknown nid"}, + {0, NULL} +}; + +#endif + +void ERR_load_OBJ_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) { + ERR_load_strings(0, OBJ_str_functs); + ERR_load_strings(0, OBJ_str_reasons); + } +#endif +} +/* crypto/objects/obj_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "lhash.h" +// #include "objects.h" +#include "buffer.h" + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) +{ + ASN1_OBJECT *r; + int i; + char *ln = NULL, *sn = NULL; + unsigned char *data = NULL; + + if (o == NULL) + return (NULL); + if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) + return ((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of duplication + * is this??? */ + + r = ASN1_OBJECT_new(); + if (r == NULL) { + OBJerr(OBJ_F_OBJ_DUP, ERR_R_ASN1_LIB); + return (NULL); + } + data = OPENSSL_malloc(o->length); + if (data == NULL) + goto err; + if (o->data != NULL) + memcpy(data, o->data, o->length); + /* once data attached to object it remains const */ + r->data = data; + r->length = o->length; + r->nid = o->nid; + r->ln = r->sn = NULL; + if (o->ln != NULL) { + i = strlen(o->ln) + 1; + ln = OPENSSL_malloc(i); + if (ln == NULL) + goto err; + memcpy(ln, o->ln, i); + r->ln = ln; + } + + if (o->sn != NULL) { + i = strlen(o->sn) + 1; + sn = OPENSSL_malloc(i); + if (sn == NULL) + goto err; + memcpy(sn, o->sn, i); + r->sn = sn; + } + r->flags = o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | + ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + return (r); + err: + OBJerr(OBJ_F_OBJ_DUP, ERR_R_MALLOC_FAILURE); + if (ln != NULL) + OPENSSL_free(ln); + if (sn != NULL) + OPENSSL_free(sn); + if (data != NULL) + OPENSSL_free(data); + if (r != NULL) + OPENSSL_free(r); + return (NULL); +} + +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) +{ + int ret; + + ret = (a->length - b->length); + if (ret) + return (ret); + return (memcmp(a->data, b->data, a->length)); +} +/* crypto/objects/obj_xref.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "objects.h" +#include "obj_xref.h" + +DECLARE_STACK_OF(nid_triple) +STACK_OF(nid_triple) *sig_app, *sigx_app; + +static int sig_cmp(const nid_triple *a, const nid_triple *b) +{ + return a->sign_id - b->sign_id; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); + +static int sig_sk_cmp(const nid_triple *const *a, const nid_triple *const *b) +{ + return (*a)->sign_id - (*b)->sign_id; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); + +static int sigx_cmp(const nid_triple *const *a, const nid_triple *const *b) +{ + int ret; + ret = (*a)->hash_id - (*b)->hash_id; + if (ret) + return ret; + return (*a)->pkey_id - (*b)->pkey_id; +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid) +{ + nid_triple tmp; + const nid_triple *rv = NULL; + tmp.sign_id = signid; + + if (sig_app) { + int idx = sk_nid_triple_find(sig_app, &tmp); + if (idx >= 0) + rv = sk_nid_triple_value(sig_app, idx); + } +#ifndef OBJ_XREF_TEST2 + if (rv == NULL) { + rv = OBJ_bsearch_sig(&tmp, sigoid_srt, + sizeof(sigoid_srt) / sizeof(nid_triple)); + } +#endif + if (rv == NULL) + return 0; + if (pdig_nid) + *pdig_nid = rv->hash_id; + if (ppkey_nid) + *ppkey_nid = rv->pkey_id; + return 1; +} + +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid) +{ + nid_triple tmp; + const nid_triple *t = &tmp; + const nid_triple **rv = NULL; + + tmp.hash_id = dig_nid; + tmp.pkey_id = pkey_nid; + + if (sigx_app) { + int idx = sk_nid_triple_find(sigx_app, &tmp); + if (idx >= 0) { + t = sk_nid_triple_value(sigx_app, idx); + rv = &t; + } + } +#ifndef OBJ_XREF_TEST2 + if (rv == NULL) { + rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, + sizeof(sigoid_srt_xref) / sizeof(nid_triple *) + ); + } +#endif + if (rv == NULL) + return 0; + if (psignid) + *psignid = (*rv)->sign_id; + return 1; +} + +int OBJ_add_sigid(int signid, int dig_id, int pkey_id) +{ + nid_triple *ntr; + if (!sig_app) + sig_app = sk_nid_triple_new(sig_sk_cmp); + if (!sig_app) + return 0; + if (!sigx_app) + sigx_app = sk_nid_triple_new(sigx_cmp); + if (!sigx_app) + return 0; + ntr = OPENSSL_malloc(sizeof(int) * 3); + if (!ntr) + return 0; + ntr->sign_id = signid; + ntr->hash_id = dig_id; + ntr->pkey_id = pkey_id; + + if (!sk_nid_triple_push(sig_app, ntr)) { + OPENSSL_free(ntr); + return 0; + } + + if (!sk_nid_triple_push(sigx_app, ntr)) + return 0; + + sk_nid_triple_sort(sig_app); + sk_nid_triple_sort(sigx_app); + + return 1; +} + +static void sid_free(nid_triple *tt) +{ + OPENSSL_free(tt); +} + +void OBJ_sigid_free(void) +{ + if (sig_app) { + sk_nid_triple_pop_free(sig_app, sid_free); + sig_app = NULL; + } + if (sigx_app) { + sk_nid_triple_free(sigx_app); + sigx_app = NULL; + } +} + +#ifdef OBJ_XREF_TEST + +main() +{ + int n1, n2, n3; + + int i, rv; +# ifdef OBJ_XREF_TEST2 + for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) { + OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1], sigoid_srt[i][2]); + } +# endif + + for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) { + n1 = sigoid_srt[i][0]; + rv = OBJ_find_sigid_algs(n1, &n2, &n3); + printf("Forward: %d, %s %s %s\n", rv, + OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); + n1 = 0; + rv = OBJ_find_sigid_by_algs(&n1, n2, n3); + printf("Reverse: %d, %s %s %s\n", rv, + OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); + } +} + +#endif diff --git a/Sources/COpenSSL/obj_dat.h b/Sources/COpenSSL/obj_dat.h new file mode 100644 index 00000000..b7e3cf28 --- /dev/null +++ b/Sources/COpenSSL/obj_dat.h @@ -0,0 +1,5319 @@ +/* crypto/objects/obj_dat.h */ + +/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the + * following command: + * perl obj_dat.pl obj_mac.h obj_dat.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define NUM_NID 958 +#define NUM_SN 951 +#define NUM_LN 951 +#define NUM_OBJ 890 + +static const unsigned char lvalues[6255]={ +0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05, /* [ 21] OBJ_md5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04, /* [ 29] OBJ_rc4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,/* [ 37] OBJ_rsaEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,/* [ 46] OBJ_md2WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,/* [ 55] OBJ_md5WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,/* [ 64] OBJ_pbeWithMD2AndDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,/* [ 73] OBJ_pbeWithMD5AndDES_CBC */ +0x55, /* [ 82] OBJ_X500 */ +0x55,0x04, /* [ 83] OBJ_X509 */ +0x55,0x04,0x03, /* [ 85] OBJ_commonName */ +0x55,0x04,0x06, /* [ 88] OBJ_countryName */ +0x55,0x04,0x07, /* [ 91] OBJ_localityName */ +0x55,0x04,0x08, /* [ 94] OBJ_stateOrProvinceName */ +0x55,0x04,0x0A, /* [ 97] OBJ_organizationName */ +0x55,0x04,0x0B, /* [100] OBJ_organizationalUnitName */ +0x55,0x08,0x01,0x01, /* [103] OBJ_rsa */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07, /* [107] OBJ_pkcs7 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,/* [115] OBJ_pkcs7_data */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,/* [124] OBJ_pkcs7_signed */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,/* [133] OBJ_pkcs7_enveloped */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,/* [142] OBJ_pkcs7_signedAndEnveloped */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,/* [151] OBJ_pkcs7_digest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,/* [160] OBJ_pkcs7_encrypted */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03, /* [169] OBJ_pkcs3 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,/* [177] OBJ_dhKeyAgreement */ +0x2B,0x0E,0x03,0x02,0x06, /* [186] OBJ_des_ecb */ +0x2B,0x0E,0x03,0x02,0x09, /* [191] OBJ_des_cfb64 */ +0x2B,0x0E,0x03,0x02,0x07, /* [196] OBJ_des_cbc */ +0x2B,0x0E,0x03,0x02,0x11, /* [201] OBJ_des_ede_ecb */ +0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,/* [206] OBJ_idea_cbc */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02, /* [217] OBJ_rc2_cbc */ +0x2B,0x0E,0x03,0x02,0x12, /* [225] OBJ_sha */ +0x2B,0x0E,0x03,0x02,0x0F, /* [230] OBJ_shaWithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07, /* [235] OBJ_des_ede3_cbc */ +0x2B,0x0E,0x03,0x02,0x08, /* [243] OBJ_des_ofb64 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09, /* [248] OBJ_pkcs9 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,/* [256] OBJ_pkcs9_emailAddress */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,/* [265] OBJ_pkcs9_unstructuredName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,/* [274] OBJ_pkcs9_contentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,/* [283] OBJ_pkcs9_messageDigest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,/* [292] OBJ_pkcs9_signingTime */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,/* [301] OBJ_pkcs9_countersignature */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,/* [310] OBJ_pkcs9_challengePassword */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,/* [319] OBJ_pkcs9_unstructuredAddress */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,/* [328] OBJ_pkcs9_extCertAttributes */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42, /* [337] OBJ_netscape */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01, /* [344] OBJ_netscape_cert_extension */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02, /* [352] OBJ_netscape_data_type */ +0x2B,0x0E,0x03,0x02,0x1A, /* [360] OBJ_sha1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,/* [365] OBJ_sha1WithRSAEncryption */ +0x2B,0x0E,0x03,0x02,0x0D, /* [374] OBJ_dsaWithSHA */ +0x2B,0x0E,0x03,0x02,0x0C, /* [379] OBJ_dsa_2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,/* [384] OBJ_pbeWithSHA1AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,/* [393] OBJ_id_pbkdf2 */ +0x2B,0x0E,0x03,0x02,0x1B, /* [402] OBJ_dsaWithSHA1_2 */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,/* [407] OBJ_netscape_cert_type */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,/* [416] OBJ_netscape_base_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,/* [425] OBJ_netscape_revocation_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,/* [434] OBJ_netscape_ca_revocation_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,/* [443] OBJ_netscape_renewal_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,/* [452] OBJ_netscape_ca_policy_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,/* [461] OBJ_netscape_ssl_server_name */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,/* [470] OBJ_netscape_comment */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,/* [479] OBJ_netscape_cert_sequence */ +0x55,0x1D, /* [488] OBJ_id_ce */ +0x55,0x1D,0x0E, /* [490] OBJ_subject_key_identifier */ +0x55,0x1D,0x0F, /* [493] OBJ_key_usage */ +0x55,0x1D,0x10, /* [496] OBJ_private_key_usage_period */ +0x55,0x1D,0x11, /* [499] OBJ_subject_alt_name */ +0x55,0x1D,0x12, /* [502] OBJ_issuer_alt_name */ +0x55,0x1D,0x13, /* [505] OBJ_basic_constraints */ +0x55,0x1D,0x14, /* [508] OBJ_crl_number */ +0x55,0x1D,0x20, /* [511] OBJ_certificate_policies */ +0x55,0x1D,0x23, /* [514] OBJ_authority_key_identifier */ +0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,/* [517] OBJ_bf_cbc */ +0x55,0x08,0x03,0x65, /* [526] OBJ_mdc2 */ +0x55,0x08,0x03,0x64, /* [530] OBJ_mdc2WithRSA */ +0x55,0x04,0x2A, /* [534] OBJ_givenName */ +0x55,0x04,0x04, /* [537] OBJ_surname */ +0x55,0x04,0x2B, /* [540] OBJ_initials */ +0x55,0x1D,0x1F, /* [543] OBJ_crl_distribution_points */ +0x2B,0x0E,0x03,0x02,0x03, /* [546] OBJ_md5WithRSA */ +0x55,0x04,0x05, /* [551] OBJ_serialNumber */ +0x55,0x04,0x0C, /* [554] OBJ_title */ +0x55,0x04,0x0D, /* [557] OBJ_description */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,/* [560] OBJ_cast5_cbc */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,/* [569] OBJ_pbeWithMD5AndCast5_CBC */ +0x2A,0x86,0x48,0xCE,0x38,0x04,0x03, /* [578] OBJ_dsaWithSHA1 */ +0x2B,0x0E,0x03,0x02,0x1D, /* [585] OBJ_sha1WithRSA */ +0x2A,0x86,0x48,0xCE,0x38,0x04,0x01, /* [590] OBJ_dsa */ +0x2B,0x24,0x03,0x02,0x01, /* [597] OBJ_ripemd160 */ +0x2B,0x24,0x03,0x03,0x01,0x02, /* [602] OBJ_ripemd160WithRSA */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08, /* [608] OBJ_rc5_cbc */ +0x29,0x01,0x01,0x85,0x1A,0x01, /* [616] OBJ_rle_compression */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [622] OBJ_zlib_compression */ +0x55,0x1D,0x25, /* [633] OBJ_ext_key_usage */ +0x2B,0x06,0x01,0x05,0x05,0x07, /* [636] OBJ_id_pkix */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03, /* [642] OBJ_id_kp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, /* [649] OBJ_server_auth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02, /* [657] OBJ_client_auth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03, /* [665] OBJ_code_sign */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04, /* [673] OBJ_email_protect */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08, /* [681] OBJ_time_stamp */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [689] OBJ_ms_code_ind */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [699] OBJ_ms_code_com */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [709] OBJ_ms_ctl_sign */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [719] OBJ_ms_sgc */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [729] OBJ_ms_efs */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [739] OBJ_ns_sgc */ +0x55,0x1D,0x1B, /* [748] OBJ_delta_crl */ +0x55,0x1D,0x15, /* [751] OBJ_crl_reason */ +0x55,0x1D,0x18, /* [754] OBJ_invalidity_date */ +0x2B,0x65,0x01,0x04,0x01, /* [757] OBJ_sxnet */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [762] OBJ_pbe_WithSHA1And128BitRC4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [772] OBJ_pbe_WithSHA1And40BitRC4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [782] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [792] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [802] OBJ_pbe_WithSHA1And128BitRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [812] OBJ_pbe_WithSHA1And40BitRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [822] OBJ_keyBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [833] OBJ_pkcs8ShroudedKeyBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [844] OBJ_certBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [855] OBJ_crlBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [866] OBJ_secretBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [877] OBJ_safeContentsBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [888] OBJ_friendlyName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [897] OBJ_localKeyID */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [906] OBJ_x509Certificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [916] OBJ_sdsiCertificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [926] OBJ_x509Crl */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [936] OBJ_pbes2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [945] OBJ_pbmac1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07, /* [954] OBJ_hmacWithSHA1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01, /* [962] OBJ_id_qt_cps */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02, /* [970] OBJ_id_qt_unotice */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [978] OBJ_SMIMECapabilities */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [987] OBJ_pbeWithMD2AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [996] OBJ_pbeWithMD5AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1005] OBJ_pbeWithSHA1AndDES_CBC */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1014] OBJ_ms_ext_req */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1024] OBJ_ext_req */ +0x55,0x04,0x29, /* [1033] OBJ_name */ +0x55,0x04,0x2E, /* [1036] OBJ_dnQualifier */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01, /* [1039] OBJ_id_pe */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30, /* [1046] OBJ_id_ad */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, /* [1053] OBJ_info_access */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, /* [1061] OBJ_ad_OCSP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, /* [1069] OBJ_ad_ca_issuers */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09, /* [1077] OBJ_OCSP_sign */ +0x2A, /* [1085] OBJ_member_body */ +0x2A,0x86,0x48, /* [1086] OBJ_ISO_US */ +0x2A,0x86,0x48,0xCE,0x38, /* [1089] OBJ_X9_57 */ +0x2A,0x86,0x48,0xCE,0x38,0x04, /* [1094] OBJ_X9cm */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, /* [1100] OBJ_pkcs1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05, /* [1108] OBJ_pkcs5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1116] OBJ_SMIME */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1125] OBJ_id_smime_mod */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1135] OBJ_id_smime_ct */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1145] OBJ_id_smime_aa */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1155] OBJ_id_smime_alg */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1165] OBJ_id_smime_cd */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1175] OBJ_id_smime_spq */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1185] OBJ_id_smime_cti */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1195] OBJ_id_smime_mod_cms */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1206] OBJ_id_smime_mod_ess */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1217] OBJ_id_smime_mod_oid */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1228] OBJ_id_smime_mod_msg_v3 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1239] OBJ_id_smime_mod_ets_eSignature_88 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1250] OBJ_id_smime_mod_ets_eSignature_97 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1261] OBJ_id_smime_mod_ets_eSigPolicy_88 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1272] OBJ_id_smime_mod_ets_eSigPolicy_97 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1283] OBJ_id_smime_ct_receipt */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1294] OBJ_id_smime_ct_authData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1305] OBJ_id_smime_ct_publishCert */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1316] OBJ_id_smime_ct_TSTInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1327] OBJ_id_smime_ct_TDTInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1338] OBJ_id_smime_ct_contentInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1349] OBJ_id_smime_ct_DVCSRequestData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1360] OBJ_id_smime_ct_DVCSResponseData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1371] OBJ_id_smime_aa_receiptRequest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1382] OBJ_id_smime_aa_securityLabel */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1393] OBJ_id_smime_aa_mlExpandHistory */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1404] OBJ_id_smime_aa_contentHint */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1415] OBJ_id_smime_aa_msgSigDigest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1426] OBJ_id_smime_aa_encapContentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1437] OBJ_id_smime_aa_contentIdentifier */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1448] OBJ_id_smime_aa_macValue */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1459] OBJ_id_smime_aa_equivalentLabels */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1470] OBJ_id_smime_aa_contentReference */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1481] OBJ_id_smime_aa_encrypKeyPref */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1492] OBJ_id_smime_aa_signingCertificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1503] OBJ_id_smime_aa_smimeEncryptCerts */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1514] OBJ_id_smime_aa_timeStampToken */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1525] OBJ_id_smime_aa_ets_sigPolicyId */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1536] OBJ_id_smime_aa_ets_commitmentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1547] OBJ_id_smime_aa_ets_signerLocation */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1558] OBJ_id_smime_aa_ets_signerAttr */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1569] OBJ_id_smime_aa_ets_otherSigCert */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1580] OBJ_id_smime_aa_ets_contentTimestamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1591] OBJ_id_smime_aa_ets_CertificateRefs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1602] OBJ_id_smime_aa_ets_RevocationRefs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1613] OBJ_id_smime_aa_ets_certValues */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1624] OBJ_id_smime_aa_ets_revocationValues */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1635] OBJ_id_smime_aa_ets_escTimeStamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1646] OBJ_id_smime_aa_ets_certCRLTimestamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1657] OBJ_id_smime_aa_ets_archiveTimeStamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1668] OBJ_id_smime_aa_signatureType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1679] OBJ_id_smime_aa_dvcs_dvc */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1690] OBJ_id_smime_alg_ESDHwith3DES */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1701] OBJ_id_smime_alg_ESDHwithRC2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1712] OBJ_id_smime_alg_3DESwrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1723] OBJ_id_smime_alg_RC2wrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1734] OBJ_id_smime_alg_ESDH */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1745] OBJ_id_smime_alg_CMS3DESwrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1756] OBJ_id_smime_alg_CMSRC2wrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1767] OBJ_id_smime_cd_ldap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1778] OBJ_id_smime_spq_ets_sqt_uri */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1789] OBJ_id_smime_spq_ets_sqt_unotice */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1800] OBJ_id_smime_cti_ets_proofOfOrigin */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1811] OBJ_id_smime_cti_ets_proofOfReceipt */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1822] OBJ_id_smime_cti_ets_proofOfDelivery */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1833] OBJ_id_smime_cti_ets_proofOfSender */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1844] OBJ_id_smime_cti_ets_proofOfApproval */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1855] OBJ_id_smime_cti_ets_proofOfCreation */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04, /* [1866] OBJ_md4 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00, /* [1874] OBJ_id_pkix_mod */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02, /* [1881] OBJ_id_qt */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04, /* [1888] OBJ_id_it */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05, /* [1895] OBJ_id_pkip */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06, /* [1902] OBJ_id_alg */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07, /* [1909] OBJ_id_cmc */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08, /* [1916] OBJ_id_on */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09, /* [1923] OBJ_id_pda */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A, /* [1930] OBJ_id_aca */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0B, /* [1937] OBJ_id_qcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C, /* [1944] OBJ_id_cct */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01, /* [1951] OBJ_id_pkix1_explicit_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02, /* [1959] OBJ_id_pkix1_implicit_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03, /* [1967] OBJ_id_pkix1_explicit_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04, /* [1975] OBJ_id_pkix1_implicit_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05, /* [1983] OBJ_id_mod_crmf */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06, /* [1991] OBJ_id_mod_cmc */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07, /* [1999] OBJ_id_mod_kea_profile_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08, /* [2007] OBJ_id_mod_kea_profile_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09, /* [2015] OBJ_id_mod_cmp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A, /* [2023] OBJ_id_mod_qualified_cert_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B, /* [2031] OBJ_id_mod_qualified_cert_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C, /* [2039] OBJ_id_mod_attribute_cert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D, /* [2047] OBJ_id_mod_timestamp_protocol */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E, /* [2055] OBJ_id_mod_ocsp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F, /* [2063] OBJ_id_mod_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10, /* [2071] OBJ_id_mod_cmp2000 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02, /* [2079] OBJ_biometricInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03, /* [2087] OBJ_qcStatements */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04, /* [2095] OBJ_ac_auditEntity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05, /* [2103] OBJ_ac_targeting */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06, /* [2111] OBJ_aaControls */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07, /* [2119] OBJ_sbgp_ipAddrBlock */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08, /* [2127] OBJ_sbgp_autonomousSysNum */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09, /* [2135] OBJ_sbgp_routerIdentifier */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03, /* [2143] OBJ_textNotice */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05, /* [2151] OBJ_ipsecEndSystem */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06, /* [2159] OBJ_ipsecTunnel */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07, /* [2167] OBJ_ipsecUser */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A, /* [2175] OBJ_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01, /* [2183] OBJ_id_it_caProtEncCert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02, /* [2191] OBJ_id_it_signKeyPairTypes */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03, /* [2199] OBJ_id_it_encKeyPairTypes */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04, /* [2207] OBJ_id_it_preferredSymmAlg */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05, /* [2215] OBJ_id_it_caKeyUpdateInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06, /* [2223] OBJ_id_it_currentCRL */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07, /* [2231] OBJ_id_it_unsupportedOIDs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08, /* [2239] OBJ_id_it_subscriptionRequest */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09, /* [2247] OBJ_id_it_subscriptionResponse */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A, /* [2255] OBJ_id_it_keyPairParamReq */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B, /* [2263] OBJ_id_it_keyPairParamRep */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C, /* [2271] OBJ_id_it_revPassphrase */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D, /* [2279] OBJ_id_it_implicitConfirm */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E, /* [2287] OBJ_id_it_confirmWaitTime */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F, /* [2295] OBJ_id_it_origPKIMessage */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01, /* [2303] OBJ_id_regCtrl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02, /* [2311] OBJ_id_regInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2319] OBJ_id_regCtrl_regToken */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2328] OBJ_id_regCtrl_authenticator */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2337] OBJ_id_regCtrl_pkiPublicationInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2346] OBJ_id_regCtrl_pkiArchiveOptions */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2355] OBJ_id_regCtrl_oldCertID */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2364] OBJ_id_regCtrl_protocolEncrKey */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2373] OBJ_id_regInfo_utf8Pairs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2382] OBJ_id_regInfo_certReq */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01, /* [2391] OBJ_id_alg_des40 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02, /* [2399] OBJ_id_alg_noSignature */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03, /* [2407] OBJ_id_alg_dh_sig_hmac_sha1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04, /* [2415] OBJ_id_alg_dh_pop */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01, /* [2423] OBJ_id_cmc_statusInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02, /* [2431] OBJ_id_cmc_identification */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03, /* [2439] OBJ_id_cmc_identityProof */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04, /* [2447] OBJ_id_cmc_dataReturn */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05, /* [2455] OBJ_id_cmc_transactionId */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06, /* [2463] OBJ_id_cmc_senderNonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07, /* [2471] OBJ_id_cmc_recipientNonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08, /* [2479] OBJ_id_cmc_addExtensions */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09, /* [2487] OBJ_id_cmc_encryptedPOP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A, /* [2495] OBJ_id_cmc_decryptedPOP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B, /* [2503] OBJ_id_cmc_lraPOPWitness */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F, /* [2511] OBJ_id_cmc_getCert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10, /* [2519] OBJ_id_cmc_getCRL */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11, /* [2527] OBJ_id_cmc_revokeRequest */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12, /* [2535] OBJ_id_cmc_regInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13, /* [2543] OBJ_id_cmc_responseInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15, /* [2551] OBJ_id_cmc_queryPending */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16, /* [2559] OBJ_id_cmc_popLinkRandom */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17, /* [2567] OBJ_id_cmc_popLinkWitness */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18, /* [2575] OBJ_id_cmc_confirmCertAcceptance */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01, /* [2583] OBJ_id_on_personalData */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01, /* [2591] OBJ_id_pda_dateOfBirth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02, /* [2599] OBJ_id_pda_placeOfBirth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03, /* [2607] OBJ_id_pda_gender */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04, /* [2615] OBJ_id_pda_countryOfCitizenship */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05, /* [2623] OBJ_id_pda_countryOfResidence */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01, /* [2631] OBJ_id_aca_authenticationInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02, /* [2639] OBJ_id_aca_accessIdentity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03, /* [2647] OBJ_id_aca_chargingIdentity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04, /* [2655] OBJ_id_aca_group */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05, /* [2663] OBJ_id_aca_role */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01, /* [2671] OBJ_id_qcs_pkixQCSyntax_v1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01, /* [2679] OBJ_id_cct_crs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02, /* [2687] OBJ_id_cct_PKIData */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03, /* [2695] OBJ_id_cct_PKIResponse */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03, /* [2703] OBJ_ad_timeStamping */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04, /* [2711] OBJ_ad_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2719] OBJ_id_pkix_OCSP_basic */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2728] OBJ_id_pkix_OCSP_Nonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2737] OBJ_id_pkix_OCSP_CrlID */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2746] OBJ_id_pkix_OCSP_acceptableResponses */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2755] OBJ_id_pkix_OCSP_noCheck */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2764] OBJ_id_pkix_OCSP_archiveCutoff */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2773] OBJ_id_pkix_OCSP_serviceLocator */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2782] OBJ_id_pkix_OCSP_extendedStatus */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2791] OBJ_id_pkix_OCSP_valid */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2800] OBJ_id_pkix_OCSP_path */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2809] OBJ_id_pkix_OCSP_trustRoot */ +0x2B,0x0E,0x03,0x02, /* [2818] OBJ_algorithm */ +0x2B,0x0E,0x03,0x02,0x0B, /* [2822] OBJ_rsaSignature */ +0x55,0x08, /* [2827] OBJ_X500algorithms */ +0x2B, /* [2829] OBJ_org */ +0x2B,0x06, /* [2830] OBJ_dod */ +0x2B,0x06,0x01, /* [2832] OBJ_iana */ +0x2B,0x06,0x01,0x01, /* [2835] OBJ_Directory */ +0x2B,0x06,0x01,0x02, /* [2839] OBJ_Management */ +0x2B,0x06,0x01,0x03, /* [2843] OBJ_Experimental */ +0x2B,0x06,0x01,0x04, /* [2847] OBJ_Private */ +0x2B,0x06,0x01,0x05, /* [2851] OBJ_Security */ +0x2B,0x06,0x01,0x06, /* [2855] OBJ_SNMPv2 */ +0x2B,0x06,0x01,0x07, /* [2859] OBJ_Mail */ +0x2B,0x06,0x01,0x04,0x01, /* [2863] OBJ_Enterprises */ +0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2868] OBJ_dcObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2877] OBJ_domainComponent */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2887] OBJ_Domain */ +0x55,0x01,0x05, /* [2897] OBJ_selected_attribute_types */ +0x55,0x01,0x05,0x37, /* [2900] OBJ_clearance */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2904] OBJ_md4WithRSAEncryption */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A, /* [2913] OBJ_ac_proxying */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B, /* [2921] OBJ_sinfo_access */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06, /* [2929] OBJ_id_aca_encAttrs */ +0x55,0x04,0x48, /* [2937] OBJ_role */ +0x55,0x1D,0x24, /* [2940] OBJ_policy_constraints */ +0x55,0x1D,0x37, /* [2943] OBJ_target_information */ +0x55,0x1D,0x38, /* [2946] OBJ_no_rev_avail */ +0x2A,0x86,0x48,0xCE,0x3D, /* [2949] OBJ_ansi_X9_62 */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01, /* [2954] OBJ_X9_62_prime_field */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02, /* [2961] OBJ_X9_62_characteristic_two_field */ +0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, /* [2968] OBJ_X9_62_id_ecPublicKey */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01, /* [2975] OBJ_X9_62_prime192v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02, /* [2983] OBJ_X9_62_prime192v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03, /* [2991] OBJ_X9_62_prime192v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04, /* [2999] OBJ_X9_62_prime239v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05, /* [3007] OBJ_X9_62_prime239v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06, /* [3015] OBJ_X9_62_prime239v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07, /* [3023] OBJ_X9_62_prime256v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01, /* [3031] OBJ_ecdsa_with_SHA1 */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3038] OBJ_ms_csp_name */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3047] OBJ_aes_128_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3056] OBJ_aes_128_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3065] OBJ_aes_128_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3074] OBJ_aes_128_cfb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3083] OBJ_aes_192_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3092] OBJ_aes_192_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3101] OBJ_aes_192_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3110] OBJ_aes_192_cfb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3119] OBJ_aes_256_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3128] OBJ_aes_256_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3137] OBJ_aes_256_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3146] OBJ_aes_256_cfb128 */ +0x55,0x1D,0x17, /* [3155] OBJ_hold_instruction_code */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x01, /* [3158] OBJ_hold_instruction_none */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x02, /* [3165] OBJ_hold_instruction_call_issuer */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x03, /* [3172] OBJ_hold_instruction_reject */ +0x09, /* [3179] OBJ_data */ +0x09,0x92,0x26, /* [3180] OBJ_pss */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C, /* [3183] OBJ_ucl */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64, /* [3190] OBJ_pilot */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3198] OBJ_pilotAttributeType */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3207] OBJ_pilotAttributeSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3216] OBJ_pilotObjectClass */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3225] OBJ_pilotGroups */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3234] OBJ_iA5StringSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3244] OBJ_caseIgnoreIA5StringSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3254] OBJ_pilotObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3264] OBJ_pilotPerson */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3274] OBJ_account */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3284] OBJ_document */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3294] OBJ_room */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3304] OBJ_documentSeries */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3314] OBJ_rFC822localPart */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3324] OBJ_dNSDomain */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3334] OBJ_domainRelatedObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3344] OBJ_friendlyCountry */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3354] OBJ_simpleSecurityObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3364] OBJ_pilotOrganization */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3374] OBJ_pilotDSA */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3384] OBJ_qualityLabelledData */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3394] OBJ_userId */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3404] OBJ_textEncodedORAddress */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3414] OBJ_rfc822Mailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3424] OBJ_info */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3434] OBJ_favouriteDrink */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3444] OBJ_roomNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3454] OBJ_photo */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3464] OBJ_userClass */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3474] OBJ_host */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3484] OBJ_manager */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3494] OBJ_documentIdentifier */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3504] OBJ_documentTitle */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3514] OBJ_documentVersion */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3524] OBJ_documentAuthor */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3534] OBJ_documentLocation */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3544] OBJ_homeTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3554] OBJ_secretary */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3564] OBJ_otherMailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3574] OBJ_lastModifiedTime */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3584] OBJ_lastModifiedBy */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3594] OBJ_aRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3604] OBJ_pilotAttributeType27 */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3614] OBJ_mXRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3624] OBJ_nSRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3634] OBJ_sOARecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3644] OBJ_cNAMERecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3654] OBJ_associatedDomain */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3664] OBJ_associatedName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3674] OBJ_homePostalAddress */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3684] OBJ_personalTitle */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3694] OBJ_mobileTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3704] OBJ_pagerTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3714] OBJ_friendlyCountryName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3724] OBJ_organizationalStatus */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3734] OBJ_janetMailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3744] OBJ_mailPreferenceOption */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3754] OBJ_buildingName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3764] OBJ_dSAQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3774] OBJ_singleLevelQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3784] OBJ_subtreeMinimumQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3794] OBJ_subtreeMaximumQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3804] OBJ_personalSignature */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3814] OBJ_dITRedirect */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3824] OBJ_audio */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3834] OBJ_documentPublisher */ +0x55,0x04,0x2D, /* [3844] OBJ_x500UniqueIdentifier */ +0x2B,0x06,0x01,0x07,0x01, /* [3847] OBJ_mime_mhs */ +0x2B,0x06,0x01,0x07,0x01,0x01, /* [3852] OBJ_mime_mhs_headings */ +0x2B,0x06,0x01,0x07,0x01,0x02, /* [3858] OBJ_mime_mhs_bodies */ +0x2B,0x06,0x01,0x07,0x01,0x01,0x01, /* [3864] OBJ_id_hex_partial_message */ +0x2B,0x06,0x01,0x07,0x01,0x01,0x02, /* [3871] OBJ_id_hex_multipart_message */ +0x55,0x04,0x2C, /* [3878] OBJ_generationQualifier */ +0x55,0x04,0x41, /* [3881] OBJ_pseudonym */ +0x67,0x2A, /* [3884] OBJ_id_set */ +0x67,0x2A,0x00, /* [3886] OBJ_set_ctype */ +0x67,0x2A,0x01, /* [3889] OBJ_set_msgExt */ +0x67,0x2A,0x03, /* [3892] OBJ_set_attr */ +0x67,0x2A,0x05, /* [3895] OBJ_set_policy */ +0x67,0x2A,0x07, /* [3898] OBJ_set_certExt */ +0x67,0x2A,0x08, /* [3901] OBJ_set_brand */ +0x67,0x2A,0x00,0x00, /* [3904] OBJ_setct_PANData */ +0x67,0x2A,0x00,0x01, /* [3908] OBJ_setct_PANToken */ +0x67,0x2A,0x00,0x02, /* [3912] OBJ_setct_PANOnly */ +0x67,0x2A,0x00,0x03, /* [3916] OBJ_setct_OIData */ +0x67,0x2A,0x00,0x04, /* [3920] OBJ_setct_PI */ +0x67,0x2A,0x00,0x05, /* [3924] OBJ_setct_PIData */ +0x67,0x2A,0x00,0x06, /* [3928] OBJ_setct_PIDataUnsigned */ +0x67,0x2A,0x00,0x07, /* [3932] OBJ_setct_HODInput */ +0x67,0x2A,0x00,0x08, /* [3936] OBJ_setct_AuthResBaggage */ +0x67,0x2A,0x00,0x09, /* [3940] OBJ_setct_AuthRevReqBaggage */ +0x67,0x2A,0x00,0x0A, /* [3944] OBJ_setct_AuthRevResBaggage */ +0x67,0x2A,0x00,0x0B, /* [3948] OBJ_setct_CapTokenSeq */ +0x67,0x2A,0x00,0x0C, /* [3952] OBJ_setct_PInitResData */ +0x67,0x2A,0x00,0x0D, /* [3956] OBJ_setct_PI_TBS */ +0x67,0x2A,0x00,0x0E, /* [3960] OBJ_setct_PResData */ +0x67,0x2A,0x00,0x10, /* [3964] OBJ_setct_AuthReqTBS */ +0x67,0x2A,0x00,0x11, /* [3968] OBJ_setct_AuthResTBS */ +0x67,0x2A,0x00,0x12, /* [3972] OBJ_setct_AuthResTBSX */ +0x67,0x2A,0x00,0x13, /* [3976] OBJ_setct_AuthTokenTBS */ +0x67,0x2A,0x00,0x14, /* [3980] OBJ_setct_CapTokenData */ +0x67,0x2A,0x00,0x15, /* [3984] OBJ_setct_CapTokenTBS */ +0x67,0x2A,0x00,0x16, /* [3988] OBJ_setct_AcqCardCodeMsg */ +0x67,0x2A,0x00,0x17, /* [3992] OBJ_setct_AuthRevReqTBS */ +0x67,0x2A,0x00,0x18, /* [3996] OBJ_setct_AuthRevResData */ +0x67,0x2A,0x00,0x19, /* [4000] OBJ_setct_AuthRevResTBS */ +0x67,0x2A,0x00,0x1A, /* [4004] OBJ_setct_CapReqTBS */ +0x67,0x2A,0x00,0x1B, /* [4008] OBJ_setct_CapReqTBSX */ +0x67,0x2A,0x00,0x1C, /* [4012] OBJ_setct_CapResData */ +0x67,0x2A,0x00,0x1D, /* [4016] OBJ_setct_CapRevReqTBS */ +0x67,0x2A,0x00,0x1E, /* [4020] OBJ_setct_CapRevReqTBSX */ +0x67,0x2A,0x00,0x1F, /* [4024] OBJ_setct_CapRevResData */ +0x67,0x2A,0x00,0x20, /* [4028] OBJ_setct_CredReqTBS */ +0x67,0x2A,0x00,0x21, /* [4032] OBJ_setct_CredReqTBSX */ +0x67,0x2A,0x00,0x22, /* [4036] OBJ_setct_CredResData */ +0x67,0x2A,0x00,0x23, /* [4040] OBJ_setct_CredRevReqTBS */ +0x67,0x2A,0x00,0x24, /* [4044] OBJ_setct_CredRevReqTBSX */ +0x67,0x2A,0x00,0x25, /* [4048] OBJ_setct_CredRevResData */ +0x67,0x2A,0x00,0x26, /* [4052] OBJ_setct_PCertReqData */ +0x67,0x2A,0x00,0x27, /* [4056] OBJ_setct_PCertResTBS */ +0x67,0x2A,0x00,0x28, /* [4060] OBJ_setct_BatchAdminReqData */ +0x67,0x2A,0x00,0x29, /* [4064] OBJ_setct_BatchAdminResData */ +0x67,0x2A,0x00,0x2A, /* [4068] OBJ_setct_CardCInitResTBS */ +0x67,0x2A,0x00,0x2B, /* [4072] OBJ_setct_MeAqCInitResTBS */ +0x67,0x2A,0x00,0x2C, /* [4076] OBJ_setct_RegFormResTBS */ +0x67,0x2A,0x00,0x2D, /* [4080] OBJ_setct_CertReqData */ +0x67,0x2A,0x00,0x2E, /* [4084] OBJ_setct_CertReqTBS */ +0x67,0x2A,0x00,0x2F, /* [4088] OBJ_setct_CertResData */ +0x67,0x2A,0x00,0x30, /* [4092] OBJ_setct_CertInqReqTBS */ +0x67,0x2A,0x00,0x31, /* [4096] OBJ_setct_ErrorTBS */ +0x67,0x2A,0x00,0x32, /* [4100] OBJ_setct_PIDualSignedTBE */ +0x67,0x2A,0x00,0x33, /* [4104] OBJ_setct_PIUnsignedTBE */ +0x67,0x2A,0x00,0x34, /* [4108] OBJ_setct_AuthReqTBE */ +0x67,0x2A,0x00,0x35, /* [4112] OBJ_setct_AuthResTBE */ +0x67,0x2A,0x00,0x36, /* [4116] OBJ_setct_AuthResTBEX */ +0x67,0x2A,0x00,0x37, /* [4120] OBJ_setct_AuthTokenTBE */ +0x67,0x2A,0x00,0x38, /* [4124] OBJ_setct_CapTokenTBE */ +0x67,0x2A,0x00,0x39, /* [4128] OBJ_setct_CapTokenTBEX */ +0x67,0x2A,0x00,0x3A, /* [4132] OBJ_setct_AcqCardCodeMsgTBE */ +0x67,0x2A,0x00,0x3B, /* [4136] OBJ_setct_AuthRevReqTBE */ +0x67,0x2A,0x00,0x3C, /* [4140] OBJ_setct_AuthRevResTBE */ +0x67,0x2A,0x00,0x3D, /* [4144] OBJ_setct_AuthRevResTBEB */ +0x67,0x2A,0x00,0x3E, /* [4148] OBJ_setct_CapReqTBE */ +0x67,0x2A,0x00,0x3F, /* [4152] OBJ_setct_CapReqTBEX */ +0x67,0x2A,0x00,0x40, /* [4156] OBJ_setct_CapResTBE */ +0x67,0x2A,0x00,0x41, /* [4160] OBJ_setct_CapRevReqTBE */ +0x67,0x2A,0x00,0x42, /* [4164] OBJ_setct_CapRevReqTBEX */ +0x67,0x2A,0x00,0x43, /* [4168] OBJ_setct_CapRevResTBE */ +0x67,0x2A,0x00,0x44, /* [4172] OBJ_setct_CredReqTBE */ +0x67,0x2A,0x00,0x45, /* [4176] OBJ_setct_CredReqTBEX */ +0x67,0x2A,0x00,0x46, /* [4180] OBJ_setct_CredResTBE */ +0x67,0x2A,0x00,0x47, /* [4184] OBJ_setct_CredRevReqTBE */ +0x67,0x2A,0x00,0x48, /* [4188] OBJ_setct_CredRevReqTBEX */ +0x67,0x2A,0x00,0x49, /* [4192] OBJ_setct_CredRevResTBE */ +0x67,0x2A,0x00,0x4A, /* [4196] OBJ_setct_BatchAdminReqTBE */ +0x67,0x2A,0x00,0x4B, /* [4200] OBJ_setct_BatchAdminResTBE */ +0x67,0x2A,0x00,0x4C, /* [4204] OBJ_setct_RegFormReqTBE */ +0x67,0x2A,0x00,0x4D, /* [4208] OBJ_setct_CertReqTBE */ +0x67,0x2A,0x00,0x4E, /* [4212] OBJ_setct_CertReqTBEX */ +0x67,0x2A,0x00,0x4F, /* [4216] OBJ_setct_CertResTBE */ +0x67,0x2A,0x00,0x50, /* [4220] OBJ_setct_CRLNotificationTBS */ +0x67,0x2A,0x00,0x51, /* [4224] OBJ_setct_CRLNotificationResTBS */ +0x67,0x2A,0x00,0x52, /* [4228] OBJ_setct_BCIDistributionTBS */ +0x67,0x2A,0x01,0x01, /* [4232] OBJ_setext_genCrypt */ +0x67,0x2A,0x01,0x03, /* [4236] OBJ_setext_miAuth */ +0x67,0x2A,0x01,0x04, /* [4240] OBJ_setext_pinSecure */ +0x67,0x2A,0x01,0x05, /* [4244] OBJ_setext_pinAny */ +0x67,0x2A,0x01,0x07, /* [4248] OBJ_setext_track2 */ +0x67,0x2A,0x01,0x08, /* [4252] OBJ_setext_cv */ +0x67,0x2A,0x05,0x00, /* [4256] OBJ_set_policy_root */ +0x67,0x2A,0x07,0x00, /* [4260] OBJ_setCext_hashedRoot */ +0x67,0x2A,0x07,0x01, /* [4264] OBJ_setCext_certType */ +0x67,0x2A,0x07,0x02, /* [4268] OBJ_setCext_merchData */ +0x67,0x2A,0x07,0x03, /* [4272] OBJ_setCext_cCertRequired */ +0x67,0x2A,0x07,0x04, /* [4276] OBJ_setCext_tunneling */ +0x67,0x2A,0x07,0x05, /* [4280] OBJ_setCext_setExt */ +0x67,0x2A,0x07,0x06, /* [4284] OBJ_setCext_setQualf */ +0x67,0x2A,0x07,0x07, /* [4288] OBJ_setCext_PGWYcapabilities */ +0x67,0x2A,0x07,0x08, /* [4292] OBJ_setCext_TokenIdentifier */ +0x67,0x2A,0x07,0x09, /* [4296] OBJ_setCext_Track2Data */ +0x67,0x2A,0x07,0x0A, /* [4300] OBJ_setCext_TokenType */ +0x67,0x2A,0x07,0x0B, /* [4304] OBJ_setCext_IssuerCapabilities */ +0x67,0x2A,0x03,0x00, /* [4308] OBJ_setAttr_Cert */ +0x67,0x2A,0x03,0x01, /* [4312] OBJ_setAttr_PGWYcap */ +0x67,0x2A,0x03,0x02, /* [4316] OBJ_setAttr_TokenType */ +0x67,0x2A,0x03,0x03, /* [4320] OBJ_setAttr_IssCap */ +0x67,0x2A,0x03,0x00,0x00, /* [4324] OBJ_set_rootKeyThumb */ +0x67,0x2A,0x03,0x00,0x01, /* [4329] OBJ_set_addPolicy */ +0x67,0x2A,0x03,0x02,0x01, /* [4334] OBJ_setAttr_Token_EMV */ +0x67,0x2A,0x03,0x02,0x02, /* [4339] OBJ_setAttr_Token_B0Prime */ +0x67,0x2A,0x03,0x03,0x03, /* [4344] OBJ_setAttr_IssCap_CVM */ +0x67,0x2A,0x03,0x03,0x04, /* [4349] OBJ_setAttr_IssCap_T2 */ +0x67,0x2A,0x03,0x03,0x05, /* [4354] OBJ_setAttr_IssCap_Sig */ +0x67,0x2A,0x03,0x03,0x03,0x01, /* [4359] OBJ_setAttr_GenCryptgrm */ +0x67,0x2A,0x03,0x03,0x04,0x01, /* [4365] OBJ_setAttr_T2Enc */ +0x67,0x2A,0x03,0x03,0x04,0x02, /* [4371] OBJ_setAttr_T2cleartxt */ +0x67,0x2A,0x03,0x03,0x05,0x01, /* [4377] OBJ_setAttr_TokICCsig */ +0x67,0x2A,0x03,0x03,0x05,0x02, /* [4383] OBJ_setAttr_SecDevSig */ +0x67,0x2A,0x08,0x01, /* [4389] OBJ_set_brand_IATA_ATA */ +0x67,0x2A,0x08,0x1E, /* [4393] OBJ_set_brand_Diners */ +0x67,0x2A,0x08,0x22, /* [4397] OBJ_set_brand_AmericanExpress */ +0x67,0x2A,0x08,0x23, /* [4401] OBJ_set_brand_JCB */ +0x67,0x2A,0x08,0x04, /* [4405] OBJ_set_brand_Visa */ +0x67,0x2A,0x08,0x05, /* [4409] OBJ_set_brand_MasterCard */ +0x67,0x2A,0x08,0xAE,0x7B, /* [4413] OBJ_set_brand_Novus */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A, /* [4418] OBJ_des_cdmf */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4426] OBJ_rsaOAEPEncryptionSET */ +0x67, /* [4435] OBJ_international_organizations */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4436] OBJ_ms_smartcard_login */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4446] OBJ_ms_upn */ +0x55,0x04,0x09, /* [4456] OBJ_streetAddress */ +0x55,0x04,0x11, /* [4459] OBJ_postalCode */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15, /* [4462] OBJ_id_ppl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E, /* [4469] OBJ_proxyCertInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00, /* [4477] OBJ_id_ppl_anyLanguage */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01, /* [4485] OBJ_id_ppl_inheritAll */ +0x55,0x1D,0x1E, /* [4493] OBJ_name_constraints */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02, /* [4496] OBJ_Independent */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4504] OBJ_sha256WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4513] OBJ_sha384WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4522] OBJ_sha512WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4531] OBJ_sha224WithRSAEncryption */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4540] OBJ_sha256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4549] OBJ_sha384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4558] OBJ_sha512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4567] OBJ_sha224 */ +0x2B, /* [4576] OBJ_identified_organization */ +0x2B,0x81,0x04, /* [4577] OBJ_certicom_arc */ +0x67,0x2B, /* [4580] OBJ_wap */ +0x67,0x2B,0x01, /* [4582] OBJ_wap_wsg */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03, /* [4585] OBJ_X9_62_id_characteristic_two_basis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4593] OBJ_X9_62_onBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4602] OBJ_X9_62_tpBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4611] OBJ_X9_62_ppBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01, /* [4620] OBJ_X9_62_c2pnb163v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02, /* [4628] OBJ_X9_62_c2pnb163v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03, /* [4636] OBJ_X9_62_c2pnb163v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04, /* [4644] OBJ_X9_62_c2pnb176v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05, /* [4652] OBJ_X9_62_c2tnb191v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06, /* [4660] OBJ_X9_62_c2tnb191v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07, /* [4668] OBJ_X9_62_c2tnb191v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08, /* [4676] OBJ_X9_62_c2onb191v4 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09, /* [4684] OBJ_X9_62_c2onb191v5 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A, /* [4692] OBJ_X9_62_c2pnb208w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B, /* [4700] OBJ_X9_62_c2tnb239v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C, /* [4708] OBJ_X9_62_c2tnb239v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D, /* [4716] OBJ_X9_62_c2tnb239v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E, /* [4724] OBJ_X9_62_c2onb239v4 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F, /* [4732] OBJ_X9_62_c2onb239v5 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10, /* [4740] OBJ_X9_62_c2pnb272w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11, /* [4748] OBJ_X9_62_c2pnb304w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12, /* [4756] OBJ_X9_62_c2tnb359v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13, /* [4764] OBJ_X9_62_c2pnb368w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14, /* [4772] OBJ_X9_62_c2tnb431r1 */ +0x2B,0x81,0x04,0x00,0x06, /* [4780] OBJ_secp112r1 */ +0x2B,0x81,0x04,0x00,0x07, /* [4785] OBJ_secp112r2 */ +0x2B,0x81,0x04,0x00,0x1C, /* [4790] OBJ_secp128r1 */ +0x2B,0x81,0x04,0x00,0x1D, /* [4795] OBJ_secp128r2 */ +0x2B,0x81,0x04,0x00,0x09, /* [4800] OBJ_secp160k1 */ +0x2B,0x81,0x04,0x00,0x08, /* [4805] OBJ_secp160r1 */ +0x2B,0x81,0x04,0x00,0x1E, /* [4810] OBJ_secp160r2 */ +0x2B,0x81,0x04,0x00,0x1F, /* [4815] OBJ_secp192k1 */ +0x2B,0x81,0x04,0x00,0x20, /* [4820] OBJ_secp224k1 */ +0x2B,0x81,0x04,0x00,0x21, /* [4825] OBJ_secp224r1 */ +0x2B,0x81,0x04,0x00,0x0A, /* [4830] OBJ_secp256k1 */ +0x2B,0x81,0x04,0x00,0x22, /* [4835] OBJ_secp384r1 */ +0x2B,0x81,0x04,0x00,0x23, /* [4840] OBJ_secp521r1 */ +0x2B,0x81,0x04,0x00,0x04, /* [4845] OBJ_sect113r1 */ +0x2B,0x81,0x04,0x00,0x05, /* [4850] OBJ_sect113r2 */ +0x2B,0x81,0x04,0x00,0x16, /* [4855] OBJ_sect131r1 */ +0x2B,0x81,0x04,0x00,0x17, /* [4860] OBJ_sect131r2 */ +0x2B,0x81,0x04,0x00,0x01, /* [4865] OBJ_sect163k1 */ +0x2B,0x81,0x04,0x00,0x02, /* [4870] OBJ_sect163r1 */ +0x2B,0x81,0x04,0x00,0x0F, /* [4875] OBJ_sect163r2 */ +0x2B,0x81,0x04,0x00,0x18, /* [4880] OBJ_sect193r1 */ +0x2B,0x81,0x04,0x00,0x19, /* [4885] OBJ_sect193r2 */ +0x2B,0x81,0x04,0x00,0x1A, /* [4890] OBJ_sect233k1 */ +0x2B,0x81,0x04,0x00,0x1B, /* [4895] OBJ_sect233r1 */ +0x2B,0x81,0x04,0x00,0x03, /* [4900] OBJ_sect239k1 */ +0x2B,0x81,0x04,0x00,0x10, /* [4905] OBJ_sect283k1 */ +0x2B,0x81,0x04,0x00,0x11, /* [4910] OBJ_sect283r1 */ +0x2B,0x81,0x04,0x00,0x24, /* [4915] OBJ_sect409k1 */ +0x2B,0x81,0x04,0x00,0x25, /* [4920] OBJ_sect409r1 */ +0x2B,0x81,0x04,0x00,0x26, /* [4925] OBJ_sect571k1 */ +0x2B,0x81,0x04,0x00,0x27, /* [4930] OBJ_sect571r1 */ +0x67,0x2B,0x01,0x04,0x01, /* [4935] OBJ_wap_wsg_idm_ecid_wtls1 */ +0x67,0x2B,0x01,0x04,0x03, /* [4940] OBJ_wap_wsg_idm_ecid_wtls3 */ +0x67,0x2B,0x01,0x04,0x04, /* [4945] OBJ_wap_wsg_idm_ecid_wtls4 */ +0x67,0x2B,0x01,0x04,0x05, /* [4950] OBJ_wap_wsg_idm_ecid_wtls5 */ +0x67,0x2B,0x01,0x04,0x06, /* [4955] OBJ_wap_wsg_idm_ecid_wtls6 */ +0x67,0x2B,0x01,0x04,0x07, /* [4960] OBJ_wap_wsg_idm_ecid_wtls7 */ +0x67,0x2B,0x01,0x04,0x08, /* [4965] OBJ_wap_wsg_idm_ecid_wtls8 */ +0x67,0x2B,0x01,0x04,0x09, /* [4970] OBJ_wap_wsg_idm_ecid_wtls9 */ +0x67,0x2B,0x01,0x04,0x0A, /* [4975] OBJ_wap_wsg_idm_ecid_wtls10 */ +0x67,0x2B,0x01,0x04,0x0B, /* [4980] OBJ_wap_wsg_idm_ecid_wtls11 */ +0x67,0x2B,0x01,0x04,0x0C, /* [4985] OBJ_wap_wsg_idm_ecid_wtls12 */ +0x55,0x1D,0x20,0x00, /* [4990] OBJ_any_policy */ +0x55,0x1D,0x21, /* [4994] OBJ_policy_mappings */ +0x55,0x1D,0x36, /* [4997] OBJ_inhibit_any_policy */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5000] OBJ_camellia_128_cbc */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5011] OBJ_camellia_192_cbc */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5022] OBJ_camellia_256_cbc */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01, /* [5033] OBJ_camellia_128_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15, /* [5041] OBJ_camellia_192_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29, /* [5049] OBJ_camellia_256_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04, /* [5057] OBJ_camellia_128_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18, /* [5065] OBJ_camellia_192_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C, /* [5073] OBJ_camellia_256_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03, /* [5081] OBJ_camellia_128_ofb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17, /* [5089] OBJ_camellia_192_ofb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B, /* [5097] OBJ_camellia_256_ofb128 */ +0x55,0x1D,0x09, /* [5105] OBJ_subject_directory_attributes */ +0x55,0x1D,0x1C, /* [5108] OBJ_issuing_distribution_point */ +0x55,0x1D,0x1D, /* [5111] OBJ_certificate_issuer */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44, /* [5114] OBJ_kisa */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03, /* [5120] OBJ_seed_ecb */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04, /* [5128] OBJ_seed_cbc */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06, /* [5136] OBJ_seed_ofb128 */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05, /* [5144] OBJ_seed_cfb128 */ +0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01, /* [5152] OBJ_hmac_md5 */ +0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02, /* [5160] OBJ_hmac_sha1 */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5168] OBJ_id_PasswordBasedMAC */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5177] OBJ_id_DHBasedMac */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10, /* [5186] OBJ_id_it_suppLangTags */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05, /* [5194] OBJ_caRepository */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5202] OBJ_id_smime_ct_compressedData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5213] OBJ_id_ct_asciiTextWithCRLF */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5224] OBJ_id_aes128_wrap */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5233] OBJ_id_aes192_wrap */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5242] OBJ_id_aes256_wrap */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02, /* [5251] OBJ_ecdsa_with_Recommended */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, /* [5258] OBJ_ecdsa_with_Specified */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01, /* [5265] OBJ_ecdsa_with_SHA224 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02, /* [5273] OBJ_ecdsa_with_SHA256 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03, /* [5281] OBJ_ecdsa_with_SHA384 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04, /* [5289] OBJ_ecdsa_with_SHA512 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06, /* [5297] OBJ_hmacWithMD5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08, /* [5305] OBJ_hmacWithSHA224 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09, /* [5313] OBJ_hmacWithSHA256 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A, /* [5321] OBJ_hmacWithSHA384 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B, /* [5329] OBJ_hmacWithSHA512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5337] OBJ_dsa_with_SHA224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5346] OBJ_dsa_with_SHA256 */ +0x28,0xCF,0x06,0x03,0x00,0x37, /* [5355] OBJ_whirlpool */ +0x2A,0x85,0x03,0x02,0x02, /* [5361] OBJ_cryptopro */ +0x2A,0x85,0x03,0x02,0x09, /* [5366] OBJ_cryptocom */ +0x2A,0x85,0x03,0x02,0x02,0x03, /* [5371] OBJ_id_GostR3411_94_with_GostR3410_2001 */ +0x2A,0x85,0x03,0x02,0x02,0x04, /* [5377] OBJ_id_GostR3411_94_with_GostR3410_94 */ +0x2A,0x85,0x03,0x02,0x02,0x09, /* [5383] OBJ_id_GostR3411_94 */ +0x2A,0x85,0x03,0x02,0x02,0x0A, /* [5389] OBJ_id_HMACGostR3411_94 */ +0x2A,0x85,0x03,0x02,0x02,0x13, /* [5395] OBJ_id_GostR3410_2001 */ +0x2A,0x85,0x03,0x02,0x02,0x14, /* [5401] OBJ_id_GostR3410_94 */ +0x2A,0x85,0x03,0x02,0x02,0x15, /* [5407] OBJ_id_Gost28147_89 */ +0x2A,0x85,0x03,0x02,0x02,0x16, /* [5413] OBJ_id_Gost28147_89_MAC */ +0x2A,0x85,0x03,0x02,0x02,0x17, /* [5419] OBJ_id_GostR3411_94_prf */ +0x2A,0x85,0x03,0x02,0x02,0x62, /* [5425] OBJ_id_GostR3410_2001DH */ +0x2A,0x85,0x03,0x02,0x02,0x63, /* [5431] OBJ_id_GostR3410_94DH */ +0x2A,0x85,0x03,0x02,0x02,0x0E,0x01, /* [5437] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */ +0x2A,0x85,0x03,0x02,0x02,0x0E,0x00, /* [5444] OBJ_id_Gost28147_89_None_KeyMeshing */ +0x2A,0x85,0x03,0x02,0x02,0x1E,0x00, /* [5451] OBJ_id_GostR3411_94_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1E,0x01, /* [5458] OBJ_id_GostR3411_94_CryptoProParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x00, /* [5465] OBJ_id_Gost28147_89_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x01, /* [5472] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x02, /* [5479] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x03, /* [5486] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x04, /* [5493] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x05, /* [5500] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x06, /* [5507] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x07, /* [5514] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x00, /* [5521] OBJ_id_GostR3410_94_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x02, /* [5528] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x03, /* [5535] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x04, /* [5542] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x05, /* [5549] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x01, /* [5556] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x02, /* [5563] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x03, /* [5570] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x00, /* [5577] OBJ_id_GostR3410_2001_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x01, /* [5584] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x02, /* [5591] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x03, /* [5598] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x24,0x00, /* [5605] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x24,0x01, /* [5612] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x01, /* [5619] OBJ_id_GostR3410_94_a */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x02, /* [5626] OBJ_id_GostR3410_94_aBis */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x03, /* [5633] OBJ_id_GostR3410_94_b */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x04, /* [5640] OBJ_id_GostR3410_94_bBis */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01, /* [5647] OBJ_id_Gost28147_89_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03, /* [5655] OBJ_id_GostR3410_94_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04, /* [5663] OBJ_id_GostR3410_2001_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03, /* [5671] OBJ_id_GostR3411_94_with_GostR3410_94_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04, /* [5679] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01, /* [5687] OBJ_id_GostR3410_2001_ParamSet_cc */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5695] OBJ_LocalKeySet */ +0x55,0x1D,0x2E, /* [5704] OBJ_freshest_crl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03, /* [5707] OBJ_id_on_permanentIdentifier */ +0x55,0x04,0x0E, /* [5715] OBJ_searchGuide */ +0x55,0x04,0x0F, /* [5718] OBJ_businessCategory */ +0x55,0x04,0x10, /* [5721] OBJ_postalAddress */ +0x55,0x04,0x12, /* [5724] OBJ_postOfficeBox */ +0x55,0x04,0x13, /* [5727] OBJ_physicalDeliveryOfficeName */ +0x55,0x04,0x14, /* [5730] OBJ_telephoneNumber */ +0x55,0x04,0x15, /* [5733] OBJ_telexNumber */ +0x55,0x04,0x16, /* [5736] OBJ_teletexTerminalIdentifier */ +0x55,0x04,0x17, /* [5739] OBJ_facsimileTelephoneNumber */ +0x55,0x04,0x18, /* [5742] OBJ_x121Address */ +0x55,0x04,0x19, /* [5745] OBJ_internationaliSDNNumber */ +0x55,0x04,0x1A, /* [5748] OBJ_registeredAddress */ +0x55,0x04,0x1B, /* [5751] OBJ_destinationIndicator */ +0x55,0x04,0x1C, /* [5754] OBJ_preferredDeliveryMethod */ +0x55,0x04,0x1D, /* [5757] OBJ_presentationAddress */ +0x55,0x04,0x1E, /* [5760] OBJ_supportedApplicationContext */ +0x55,0x04,0x1F, /* [5763] OBJ_member */ +0x55,0x04,0x20, /* [5766] OBJ_owner */ +0x55,0x04,0x21, /* [5769] OBJ_roleOccupant */ +0x55,0x04,0x22, /* [5772] OBJ_seeAlso */ +0x55,0x04,0x23, /* [5775] OBJ_userPassword */ +0x55,0x04,0x24, /* [5778] OBJ_userCertificate */ +0x55,0x04,0x25, /* [5781] OBJ_cACertificate */ +0x55,0x04,0x26, /* [5784] OBJ_authorityRevocationList */ +0x55,0x04,0x27, /* [5787] OBJ_certificateRevocationList */ +0x55,0x04,0x28, /* [5790] OBJ_crossCertificatePair */ +0x55,0x04,0x2F, /* [5793] OBJ_enhancedSearchGuide */ +0x55,0x04,0x30, /* [5796] OBJ_protocolInformation */ +0x55,0x04,0x31, /* [5799] OBJ_distinguishedName */ +0x55,0x04,0x32, /* [5802] OBJ_uniqueMember */ +0x55,0x04,0x33, /* [5805] OBJ_houseIdentifier */ +0x55,0x04,0x34, /* [5808] OBJ_supportedAlgorithms */ +0x55,0x04,0x35, /* [5811] OBJ_deltaRevocationList */ +0x55,0x04,0x36, /* [5814] OBJ_dmdName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5817] OBJ_id_alg_PWRI_KEK */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5828] OBJ_aes_128_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5837] OBJ_aes_128_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5846] OBJ_id_aes128_wrap_pad */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5855] OBJ_aes_192_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5864] OBJ_aes_192_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5873] OBJ_id_aes192_wrap_pad */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5882] OBJ_aes_256_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5891] OBJ_aes_256_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5900] OBJ_id_aes256_wrap_pad */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5909] OBJ_id_camellia128_wrap */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5920] OBJ_id_camellia192_wrap */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5931] OBJ_id_camellia256_wrap */ +0x55,0x1D,0x25,0x00, /* [5942] OBJ_anyExtendedKeyUsage */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5946] OBJ_mgf1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5955] OBJ_rsassaPss */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5964] OBJ_rsaesOaep */ +0x2A,0x86,0x48,0xCE,0x3E,0x02,0x01, /* [5973] OBJ_dhpublicnumber */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,/* [5980] OBJ_brainpoolP160r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,/* [5989] OBJ_brainpoolP160t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,/* [5998] OBJ_brainpoolP192r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,/* [6007] OBJ_brainpoolP192t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,/* [6016] OBJ_brainpoolP224r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,/* [6025] OBJ_brainpoolP224t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,/* [6034] OBJ_brainpoolP256r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,/* [6043] OBJ_brainpoolP256t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,/* [6052] OBJ_brainpoolP320r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,/* [6061] OBJ_brainpoolP320t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,/* [6070] OBJ_brainpoolP384r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,/* [6079] OBJ_brainpoolP384t1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,/* [6088] OBJ_brainpoolP512r1 */ +0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,/* [6097] OBJ_brainpoolP512t1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09,/* [6106] OBJ_pSpecified */ +0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02,/* [6115] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0B,0x00, /* [6124] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0B,0x01, /* [6130] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0B,0x02, /* [6136] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0B,0x03, /* [6142] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */ +0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03,/* [6148] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0E,0x00, /* [6157] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0E,0x01, /* [6163] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0E,0x02, /* [6169] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */ +0x2B,0x81,0x04,0x01,0x0E,0x03, /* [6175] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */ +0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,/* [6181] OBJ_ct_precert_scts */ +0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x03,/* [6191] OBJ_ct_precert_poison */ +0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x04,/* [6201] OBJ_ct_precert_signer */ +0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x05,/* [6211] OBJ_ct_cert_scts */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,/* [6221] OBJ_jurisdictionLocalityName */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,/* [6232] OBJ_jurisdictionStateOrProvinceName */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,/* [6243] OBJ_jurisdictionCountryName */ +}; + +static const ASN1_OBJECT nid_objs[NUM_NID]={ +{"UNDEF","undefined",NID_undef,0,NULL,0}, +{"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[0]),0}, +{"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[6]),0}, +{"MD2","md2",NID_md2,8,&(lvalues[13]),0}, +{"MD5","md5",NID_md5,8,&(lvalues[21]),0}, +{"RC4","rc4",NID_rc4,8,&(lvalues[29]),0}, +{"rsaEncryption","rsaEncryption",NID_rsaEncryption,9,&(lvalues[37]),0}, +{"RSA-MD2","md2WithRSAEncryption",NID_md2WithRSAEncryption,9, + &(lvalues[46]),0}, +{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9, + &(lvalues[55]),0}, +{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9, + &(lvalues[64]),0}, +{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9, + &(lvalues[73]),0}, +{"X500","directory services (X.500)",NID_X500,1,&(lvalues[82]),0}, +{"X509","X509",NID_X509,2,&(lvalues[83]),0}, +{"CN","commonName",NID_commonName,3,&(lvalues[85]),0}, +{"C","countryName",NID_countryName,3,&(lvalues[88]),0}, +{"L","localityName",NID_localityName,3,&(lvalues[91]),0}, +{"ST","stateOrProvinceName",NID_stateOrProvinceName,3,&(lvalues[94]),0}, +{"O","organizationName",NID_organizationName,3,&(lvalues[97]),0}, +{"OU","organizationalUnitName",NID_organizationalUnitName,3, + &(lvalues[100]),0}, +{"RSA","rsa",NID_rsa,4,&(lvalues[103]),0}, +{"pkcs7","pkcs7",NID_pkcs7,8,&(lvalues[107]),0}, +{"pkcs7-data","pkcs7-data",NID_pkcs7_data,9,&(lvalues[115]),0}, +{"pkcs7-signedData","pkcs7-signedData",NID_pkcs7_signed,9, + &(lvalues[124]),0}, +{"pkcs7-envelopedData","pkcs7-envelopedData",NID_pkcs7_enveloped,9, + &(lvalues[133]),0}, +{"pkcs7-signedAndEnvelopedData","pkcs7-signedAndEnvelopedData", + NID_pkcs7_signedAndEnveloped,9,&(lvalues[142]),0}, +{"pkcs7-digestData","pkcs7-digestData",NID_pkcs7_digest,9, + &(lvalues[151]),0}, +{"pkcs7-encryptedData","pkcs7-encryptedData",NID_pkcs7_encrypted,9, + &(lvalues[160]),0}, +{"pkcs3","pkcs3",NID_pkcs3,8,&(lvalues[169]),0}, +{"dhKeyAgreement","dhKeyAgreement",NID_dhKeyAgreement,9, + &(lvalues[177]),0}, +{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[186]),0}, +{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[191]),0}, +{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[196]),0}, +{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[201]),0}, +{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL,0}, +{"IDEA-CBC","idea-cbc",NID_idea_cbc,11,&(lvalues[206]),0}, +{"IDEA-CFB","idea-cfb",NID_idea_cfb64,0,NULL,0}, +{"IDEA-ECB","idea-ecb",NID_idea_ecb,0,NULL,0}, +{"RC2-CBC","rc2-cbc",NID_rc2_cbc,8,&(lvalues[217]),0}, +{"RC2-ECB","rc2-ecb",NID_rc2_ecb,0,NULL,0}, +{"RC2-CFB","rc2-cfb",NID_rc2_cfb64,0,NULL,0}, +{"RC2-OFB","rc2-ofb",NID_rc2_ofb64,0,NULL,0}, +{"SHA","sha",NID_sha,5,&(lvalues[225]),0}, +{"RSA-SHA","shaWithRSAEncryption",NID_shaWithRSAEncryption,5, + &(lvalues[230]),0}, +{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL,0}, +{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[235]),0}, +{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[243]),0}, +{"IDEA-OFB","idea-ofb",NID_idea_ofb64,0,NULL,0}, +{"pkcs9","pkcs9",NID_pkcs9,8,&(lvalues[248]),0}, +{"emailAddress","emailAddress",NID_pkcs9_emailAddress,9, + &(lvalues[256]),0}, +{"unstructuredName","unstructuredName",NID_pkcs9_unstructuredName,9, + &(lvalues[265]),0}, +{"contentType","contentType",NID_pkcs9_contentType,9,&(lvalues[274]),0}, +{"messageDigest","messageDigest",NID_pkcs9_messageDigest,9, + &(lvalues[283]),0}, +{"signingTime","signingTime",NID_pkcs9_signingTime,9,&(lvalues[292]),0}, +{"countersignature","countersignature",NID_pkcs9_countersignature,9, + &(lvalues[301]),0}, +{"challengePassword","challengePassword",NID_pkcs9_challengePassword, + 9,&(lvalues[310]),0}, +{"unstructuredAddress","unstructuredAddress", + NID_pkcs9_unstructuredAddress,9,&(lvalues[319]),0}, +{"extendedCertificateAttributes","extendedCertificateAttributes", + NID_pkcs9_extCertAttributes,9,&(lvalues[328]),0}, +{"Netscape","Netscape Communications Corp.",NID_netscape,7, + &(lvalues[337]),0}, +{"nsCertExt","Netscape Certificate Extension", + NID_netscape_cert_extension,8,&(lvalues[344]),0}, +{"nsDataType","Netscape Data Type",NID_netscape_data_type,8, + &(lvalues[352]),0}, +{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL,0}, +{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL,0}, +{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL,0}, +{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL,0}, +{"SHA1","sha1",NID_sha1,5,&(lvalues[360]),0}, +{"RSA-SHA1","sha1WithRSAEncryption",NID_sha1WithRSAEncryption,9, + &(lvalues[365]),0}, +{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[374]),0}, +{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[379]),0}, +{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC, + 9,&(lvalues[384]),0}, +{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[393]),0}, +{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[402]),0}, +{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9, + &(lvalues[407]),0}, +{"nsBaseUrl","Netscape Base Url",NID_netscape_base_url,9, + &(lvalues[416]),0}, +{"nsRevocationUrl","Netscape Revocation Url", + NID_netscape_revocation_url,9,&(lvalues[425]),0}, +{"nsCaRevocationUrl","Netscape CA Revocation Url", + NID_netscape_ca_revocation_url,9,&(lvalues[434]),0}, +{"nsRenewalUrl","Netscape Renewal Url",NID_netscape_renewal_url,9, + &(lvalues[443]),0}, +{"nsCaPolicyUrl","Netscape CA Policy Url",NID_netscape_ca_policy_url, + 9,&(lvalues[452]),0}, +{"nsSslServerName","Netscape SSL Server Name", + NID_netscape_ssl_server_name,9,&(lvalues[461]),0}, +{"nsComment","Netscape Comment",NID_netscape_comment,9,&(lvalues[470]),0}, +{"nsCertSequence","Netscape Certificate Sequence", + NID_netscape_cert_sequence,9,&(lvalues[479]),0}, +{"DESX-CBC","desx-cbc",NID_desx_cbc,0,NULL,0}, +{"id-ce","id-ce",NID_id_ce,2,&(lvalues[488]),0}, +{"subjectKeyIdentifier","X509v3 Subject Key Identifier", + NID_subject_key_identifier,3,&(lvalues[490]),0}, +{"keyUsage","X509v3 Key Usage",NID_key_usage,3,&(lvalues[493]),0}, +{"privateKeyUsagePeriod","X509v3 Private Key Usage Period", + NID_private_key_usage_period,3,&(lvalues[496]),0}, +{"subjectAltName","X509v3 Subject Alternative Name", + NID_subject_alt_name,3,&(lvalues[499]),0}, +{"issuerAltName","X509v3 Issuer Alternative Name",NID_issuer_alt_name, + 3,&(lvalues[502]),0}, +{"basicConstraints","X509v3 Basic Constraints",NID_basic_constraints, + 3,&(lvalues[505]),0}, +{"crlNumber","X509v3 CRL Number",NID_crl_number,3,&(lvalues[508]),0}, +{"certificatePolicies","X509v3 Certificate Policies", + NID_certificate_policies,3,&(lvalues[511]),0}, +{"authorityKeyIdentifier","X509v3 Authority Key Identifier", + NID_authority_key_identifier,3,&(lvalues[514]),0}, +{"BF-CBC","bf-cbc",NID_bf_cbc,9,&(lvalues[517]),0}, +{"BF-ECB","bf-ecb",NID_bf_ecb,0,NULL,0}, +{"BF-CFB","bf-cfb",NID_bf_cfb64,0,NULL,0}, +{"BF-OFB","bf-ofb",NID_bf_ofb64,0,NULL,0}, +{"MDC2","mdc2",NID_mdc2,4,&(lvalues[526]),0}, +{"RSA-MDC2","mdc2WithRSA",NID_mdc2WithRSA,4,&(lvalues[530]),0}, +{"RC4-40","rc4-40",NID_rc4_40,0,NULL,0}, +{"RC2-40-CBC","rc2-40-cbc",NID_rc2_40_cbc,0,NULL,0}, +{"GN","givenName",NID_givenName,3,&(lvalues[534]),0}, +{"SN","surname",NID_surname,3,&(lvalues[537]),0}, +{"initials","initials",NID_initials,3,&(lvalues[540]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"crlDistributionPoints","X509v3 CRL Distribution Points", + NID_crl_distribution_points,3,&(lvalues[543]),0}, +{"RSA-NP-MD5","md5WithRSA",NID_md5WithRSA,5,&(lvalues[546]),0}, +{"serialNumber","serialNumber",NID_serialNumber,3,&(lvalues[551]),0}, +{"title","title",NID_title,3,&(lvalues[554]),0}, +{"description","description",NID_description,3,&(lvalues[557]),0}, +{"CAST5-CBC","cast5-cbc",NID_cast5_cbc,9,&(lvalues[560]),0}, +{"CAST5-ECB","cast5-ecb",NID_cast5_ecb,0,NULL,0}, +{"CAST5-CFB","cast5-cfb",NID_cast5_cfb64,0,NULL,0}, +{"CAST5-OFB","cast5-ofb",NID_cast5_ofb64,0,NULL,0}, +{"pbeWithMD5AndCast5CBC","pbeWithMD5AndCast5CBC", + NID_pbeWithMD5AndCast5_CBC,9,&(lvalues[569]),0}, +{"DSA-SHA1","dsaWithSHA1",NID_dsaWithSHA1,7,&(lvalues[578]),0}, +{"MD5-SHA1","md5-sha1",NID_md5_sha1,0,NULL,0}, +{"RSA-SHA1-2","sha1WithRSA",NID_sha1WithRSA,5,&(lvalues[585]),0}, +{"DSA","dsaEncryption",NID_dsa,7,&(lvalues[590]),0}, +{"RIPEMD160","ripemd160",NID_ripemd160,5,&(lvalues[597]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"RSA-RIPEMD160","ripemd160WithRSA",NID_ripemd160WithRSA,6, + &(lvalues[602]),0}, +{"RC5-CBC","rc5-cbc",NID_rc5_cbc,8,&(lvalues[608]),0}, +{"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0}, +{"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0}, +{"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0}, +{"RLE","run length compression",NID_rle_compression,6,&(lvalues[616]),0}, +{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[622]),0}, +{"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3, + &(lvalues[633]),0}, +{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[636]),0}, +{"id-kp","id-kp",NID_id_kp,7,&(lvalues[642]),0}, +{"serverAuth","TLS Web Server Authentication",NID_server_auth,8, + &(lvalues[649]),0}, +{"clientAuth","TLS Web Client Authentication",NID_client_auth,8, + &(lvalues[657]),0}, +{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[665]),0}, +{"emailProtection","E-mail Protection",NID_email_protect,8, + &(lvalues[673]),0}, +{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[681]),0}, +{"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10, + &(lvalues[689]),0}, +{"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10, + &(lvalues[699]),0}, +{"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10, + &(lvalues[709]),0}, +{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[719]),0}, +{"msEFS","Microsoft Encrypted File System",NID_ms_efs,10, + &(lvalues[729]),0}, +{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[739]),0}, +{"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3, + &(lvalues[748]),0}, +{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[751]),0}, +{"invalidityDate","Invalidity Date",NID_invalidity_date,3, + &(lvalues[754]),0}, +{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[757]),0}, +{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4", + NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[762]),0}, +{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4", + NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[772]),0}, +{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC", + NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[782]),0}, +{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC", + NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[792]),0}, +{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC", + NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[802]),0}, +{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC", + NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[812]),0}, +{"keyBag","keyBag",NID_keyBag,11,&(lvalues[822]),0}, +{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag, + 11,&(lvalues[833]),0}, +{"certBag","certBag",NID_certBag,11,&(lvalues[844]),0}, +{"crlBag","crlBag",NID_crlBag,11,&(lvalues[855]),0}, +{"secretBag","secretBag",NID_secretBag,11,&(lvalues[866]),0}, +{"safeContentsBag","safeContentsBag",NID_safeContentsBag,11, + &(lvalues[877]),0}, +{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[888]),0}, +{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[897]),0}, +{"x509Certificate","x509Certificate",NID_x509Certificate,10, + &(lvalues[906]),0}, +{"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10, + &(lvalues[916]),0}, +{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[926]),0}, +{"PBES2","PBES2",NID_pbes2,9,&(lvalues[936]),0}, +{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[945]),0}, +{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[954]),0}, +{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[962]),0}, +{"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8, + &(lvalues[970]),0}, +{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0}, +{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9, + &(lvalues[978]),0}, +{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9, + &(lvalues[987]),0}, +{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9, + &(lvalues[996]),0}, +{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9, + &(lvalues[1005]),0}, +{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10, + &(lvalues[1014]),0}, +{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1024]),0}, +{"name","name",NID_name,3,&(lvalues[1033]),0}, +{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1036]),0}, +{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1039]),0}, +{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1046]),0}, +{"authorityInfoAccess","Authority Information Access",NID_info_access, + 8,&(lvalues[1053]),0}, +{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1061]),0}, +{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1069]),0}, +{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1077]),0}, +{"ISO","iso",NID_iso,0,NULL,0}, +{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1085]),0}, +{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1086]),0}, +{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1089]),0}, +{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1094]),0}, +{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1100]),0}, +{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1108]),0}, +{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1116]),0}, +{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1125]),0}, +{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1135]),0}, +{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1145]),0}, +{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1155]),0}, +{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1165]),0}, +{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1175]),0}, +{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1185]),0}, +{"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11, + &(lvalues[1195]),0}, +{"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11, + &(lvalues[1206]),0}, +{"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11, + &(lvalues[1217]),0}, +{"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3, + 11,&(lvalues[1228]),0}, +{"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88", + NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1239]),0}, +{"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97", + NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1250]),0}, +{"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88", + NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1261]),0}, +{"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97", + NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1272]),0}, +{"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt, + 11,&(lvalues[1283]),0}, +{"id-smime-ct-authData","id-smime-ct-authData", + NID_id_smime_ct_authData,11,&(lvalues[1294]),0}, +{"id-smime-ct-publishCert","id-smime-ct-publishCert", + NID_id_smime_ct_publishCert,11,&(lvalues[1305]),0}, +{"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo, + 11,&(lvalues[1316]),0}, +{"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo, + 11,&(lvalues[1327]),0}, +{"id-smime-ct-contentInfo","id-smime-ct-contentInfo", + NID_id_smime_ct_contentInfo,11,&(lvalues[1338]),0}, +{"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData", + NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1349]),0}, +{"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData", + NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1360]),0}, +{"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest", + NID_id_smime_aa_receiptRequest,11,&(lvalues[1371]),0}, +{"id-smime-aa-securityLabel","id-smime-aa-securityLabel", + NID_id_smime_aa_securityLabel,11,&(lvalues[1382]),0}, +{"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory", + NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1393]),0}, +{"id-smime-aa-contentHint","id-smime-aa-contentHint", + NID_id_smime_aa_contentHint,11,&(lvalues[1404]),0}, +{"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest", + NID_id_smime_aa_msgSigDigest,11,&(lvalues[1415]),0}, +{"id-smime-aa-encapContentType","id-smime-aa-encapContentType", + NID_id_smime_aa_encapContentType,11,&(lvalues[1426]),0}, +{"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier", + NID_id_smime_aa_contentIdentifier,11,&(lvalues[1437]),0}, +{"id-smime-aa-macValue","id-smime-aa-macValue", + NID_id_smime_aa_macValue,11,&(lvalues[1448]),0}, +{"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels", + NID_id_smime_aa_equivalentLabels,11,&(lvalues[1459]),0}, +{"id-smime-aa-contentReference","id-smime-aa-contentReference", + NID_id_smime_aa_contentReference,11,&(lvalues[1470]),0}, +{"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref", + NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1481]),0}, +{"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate", + NID_id_smime_aa_signingCertificate,11,&(lvalues[1492]),0}, +{"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts", + NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1503]),0}, +{"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken", + NID_id_smime_aa_timeStampToken,11,&(lvalues[1514]),0}, +{"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId", + NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1525]),0}, +{"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType", + NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1536]),0}, +{"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation", + NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1547]),0}, +{"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr", + NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1558]),0}, +{"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert", + NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1569]),0}, +{"id-smime-aa-ets-contentTimestamp", + "id-smime-aa-ets-contentTimestamp", + NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1580]),0}, +{"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs", + NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1591]),0}, +{"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs", + NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1602]),0}, +{"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues", + NID_id_smime_aa_ets_certValues,11,&(lvalues[1613]),0}, +{"id-smime-aa-ets-revocationValues", + "id-smime-aa-ets-revocationValues", + NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1624]),0}, +{"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp", + NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1635]),0}, +{"id-smime-aa-ets-certCRLTimestamp", + "id-smime-aa-ets-certCRLTimestamp", + NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1646]),0}, +{"id-smime-aa-ets-archiveTimeStamp", + "id-smime-aa-ets-archiveTimeStamp", + NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1657]),0}, +{"id-smime-aa-signatureType","id-smime-aa-signatureType", + NID_id_smime_aa_signatureType,11,&(lvalues[1668]),0}, +{"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc", + NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1679]),0}, +{"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES", + NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1690]),0}, +{"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2", + NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1701]),0}, +{"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap", + NID_id_smime_alg_3DESwrap,11,&(lvalues[1712]),0}, +{"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap", + NID_id_smime_alg_RC2wrap,11,&(lvalues[1723]),0}, +{"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11, + &(lvalues[1734]),0}, +{"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap", + NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1745]),0}, +{"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap", + NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1756]),0}, +{"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11, + &(lvalues[1767]),0}, +{"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri", + NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1778]),0}, +{"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice", + NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1789]),0}, +{"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin", + NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1800]),0}, +{"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt", + NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1811]),0}, +{"id-smime-cti-ets-proofOfDelivery", + "id-smime-cti-ets-proofOfDelivery", + NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1822]),0}, +{"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender", + NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1833]),0}, +{"id-smime-cti-ets-proofOfApproval", + "id-smime-cti-ets-proofOfApproval", + NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1844]),0}, +{"id-smime-cti-ets-proofOfCreation", + "id-smime-cti-ets-proofOfCreation", + NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1855]),0}, +{"MD4","md4",NID_md4,8,&(lvalues[1866]),0}, +{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1874]),0}, +{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1881]),0}, +{"id-it","id-it",NID_id_it,7,&(lvalues[1888]),0}, +{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1895]),0}, +{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1902]),0}, +{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1909]),0}, +{"id-on","id-on",NID_id_on,7,&(lvalues[1916]),0}, +{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1923]),0}, +{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1930]),0}, +{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1937]),0}, +{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1944]),0}, +{"id-pkix1-explicit-88","id-pkix1-explicit-88", + NID_id_pkix1_explicit_88,8,&(lvalues[1951]),0}, +{"id-pkix1-implicit-88","id-pkix1-implicit-88", + NID_id_pkix1_implicit_88,8,&(lvalues[1959]),0}, +{"id-pkix1-explicit-93","id-pkix1-explicit-93", + NID_id_pkix1_explicit_93,8,&(lvalues[1967]),0}, +{"id-pkix1-implicit-93","id-pkix1-implicit-93", + NID_id_pkix1_implicit_93,8,&(lvalues[1975]),0}, +{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1983]),0}, +{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1991]),0}, +{"id-mod-kea-profile-88","id-mod-kea-profile-88", + NID_id_mod_kea_profile_88,8,&(lvalues[1999]),0}, +{"id-mod-kea-profile-93","id-mod-kea-profile-93", + NID_id_mod_kea_profile_93,8,&(lvalues[2007]),0}, +{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2015]),0}, +{"id-mod-qualified-cert-88","id-mod-qualified-cert-88", + NID_id_mod_qualified_cert_88,8,&(lvalues[2023]),0}, +{"id-mod-qualified-cert-93","id-mod-qualified-cert-93", + NID_id_mod_qualified_cert_93,8,&(lvalues[2031]),0}, +{"id-mod-attribute-cert","id-mod-attribute-cert", + NID_id_mod_attribute_cert,8,&(lvalues[2039]),0}, +{"id-mod-timestamp-protocol","id-mod-timestamp-protocol", + NID_id_mod_timestamp_protocol,8,&(lvalues[2047]),0}, +{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2055]),0}, +{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2063]),0}, +{"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8, + &(lvalues[2071]),0}, +{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2079]),0}, +{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2087]),0}, +{"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8, + &(lvalues[2095]),0}, +{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2103]),0}, +{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2111]),0}, +{"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8, + &(lvalues[2119]),0}, +{"sbgp-autonomousSysNum","sbgp-autonomousSysNum", + NID_sbgp_autonomousSysNum,8,&(lvalues[2127]),0}, +{"sbgp-routerIdentifier","sbgp-routerIdentifier", + NID_sbgp_routerIdentifier,8,&(lvalues[2135]),0}, +{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2143]),0}, +{"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8, + &(lvalues[2151]),0}, +{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2159]),0}, +{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2167]),0}, +{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2175]),0}, +{"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert, + 8,&(lvalues[2183]),0}, +{"id-it-signKeyPairTypes","id-it-signKeyPairTypes", + NID_id_it_signKeyPairTypes,8,&(lvalues[2191]),0}, +{"id-it-encKeyPairTypes","id-it-encKeyPairTypes", + NID_id_it_encKeyPairTypes,8,&(lvalues[2199]),0}, +{"id-it-preferredSymmAlg","id-it-preferredSymmAlg", + NID_id_it_preferredSymmAlg,8,&(lvalues[2207]),0}, +{"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo", + NID_id_it_caKeyUpdateInfo,8,&(lvalues[2215]),0}, +{"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8, + &(lvalues[2223]),0}, +{"id-it-unsupportedOIDs","id-it-unsupportedOIDs", + NID_id_it_unsupportedOIDs,8,&(lvalues[2231]),0}, +{"id-it-subscriptionRequest","id-it-subscriptionRequest", + NID_id_it_subscriptionRequest,8,&(lvalues[2239]),0}, +{"id-it-subscriptionResponse","id-it-subscriptionResponse", + NID_id_it_subscriptionResponse,8,&(lvalues[2247]),0}, +{"id-it-keyPairParamReq","id-it-keyPairParamReq", + NID_id_it_keyPairParamReq,8,&(lvalues[2255]),0}, +{"id-it-keyPairParamRep","id-it-keyPairParamRep", + NID_id_it_keyPairParamRep,8,&(lvalues[2263]),0}, +{"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase, + 8,&(lvalues[2271]),0}, +{"id-it-implicitConfirm","id-it-implicitConfirm", + NID_id_it_implicitConfirm,8,&(lvalues[2279]),0}, +{"id-it-confirmWaitTime","id-it-confirmWaitTime", + NID_id_it_confirmWaitTime,8,&(lvalues[2287]),0}, +{"id-it-origPKIMessage","id-it-origPKIMessage", + NID_id_it_origPKIMessage,8,&(lvalues[2295]),0}, +{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2303]),0}, +{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2311]),0}, +{"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken, + 9,&(lvalues[2319]),0}, +{"id-regCtrl-authenticator","id-regCtrl-authenticator", + NID_id_regCtrl_authenticator,9,&(lvalues[2328]),0}, +{"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo", + NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2337]),0}, +{"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions", + NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2346]),0}, +{"id-regCtrl-oldCertID","id-regCtrl-oldCertID", + NID_id_regCtrl_oldCertID,9,&(lvalues[2355]),0}, +{"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey", + NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2364]),0}, +{"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs", + NID_id_regInfo_utf8Pairs,9,&(lvalues[2373]),0}, +{"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9, + &(lvalues[2382]),0}, +{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2391]),0}, +{"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8, + &(lvalues[2399]),0}, +{"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1", + NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2407]),0}, +{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2415]),0}, +{"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8, + &(lvalues[2423]),0}, +{"id-cmc-identification","id-cmc-identification", + NID_id_cmc_identification,8,&(lvalues[2431]),0}, +{"id-cmc-identityProof","id-cmc-identityProof", + NID_id_cmc_identityProof,8,&(lvalues[2439]),0}, +{"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8, + &(lvalues[2447]),0}, +{"id-cmc-transactionId","id-cmc-transactionId", + NID_id_cmc_transactionId,8,&(lvalues[2455]),0}, +{"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8, + &(lvalues[2463]),0}, +{"id-cmc-recipientNonce","id-cmc-recipientNonce", + NID_id_cmc_recipientNonce,8,&(lvalues[2471]),0}, +{"id-cmc-addExtensions","id-cmc-addExtensions", + NID_id_cmc_addExtensions,8,&(lvalues[2479]),0}, +{"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP, + 8,&(lvalues[2487]),0}, +{"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP, + 8,&(lvalues[2495]),0}, +{"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness", + NID_id_cmc_lraPOPWitness,8,&(lvalues[2503]),0}, +{"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8, + &(lvalues[2511]),0}, +{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2519]),0}, +{"id-cmc-revokeRequest","id-cmc-revokeRequest", + NID_id_cmc_revokeRequest,8,&(lvalues[2527]),0}, +{"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8, + &(lvalues[2535]),0}, +{"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo, + 8,&(lvalues[2543]),0}, +{"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending, + 8,&(lvalues[2551]),0}, +{"id-cmc-popLinkRandom","id-cmc-popLinkRandom", + NID_id_cmc_popLinkRandom,8,&(lvalues[2559]),0}, +{"id-cmc-popLinkWitness","id-cmc-popLinkWitness", + NID_id_cmc_popLinkWitness,8,&(lvalues[2567]),0}, +{"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance", + NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2575]),0}, +{"id-on-personalData","id-on-personalData",NID_id_on_personalData,8, + &(lvalues[2583]),0}, +{"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8, + &(lvalues[2591]),0}, +{"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth, + 8,&(lvalues[2599]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2607]),0}, +{"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship", + NID_id_pda_countryOfCitizenship,8,&(lvalues[2615]),0}, +{"id-pda-countryOfResidence","id-pda-countryOfResidence", + NID_id_pda_countryOfResidence,8,&(lvalues[2623]),0}, +{"id-aca-authenticationInfo","id-aca-authenticationInfo", + NID_id_aca_authenticationInfo,8,&(lvalues[2631]),0}, +{"id-aca-accessIdentity","id-aca-accessIdentity", + NID_id_aca_accessIdentity,8,&(lvalues[2639]),0}, +{"id-aca-chargingIdentity","id-aca-chargingIdentity", + NID_id_aca_chargingIdentity,8,&(lvalues[2647]),0}, +{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2655]),0}, +{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2663]),0}, +{"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1", + NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2671]),0}, +{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2679]),0}, +{"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8, + &(lvalues[2687]),0}, +{"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8, + &(lvalues[2695]),0}, +{"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8, + &(lvalues[2703]),0}, +{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2711]),0}, +{"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9, + &(lvalues[2719]),0}, +{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2728]),0}, +{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2737]),0}, +{"acceptableResponses","Acceptable OCSP Responses", + NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2746]),0}, +{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2755]),0}, +{"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff, + 9,&(lvalues[2764]),0}, +{"serviceLocator","OCSP Service Locator", + NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2773]),0}, +{"extendedStatus","Extended OCSP Status", + NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2782]),0}, +{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2791]),0}, +{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2800]),0}, +{"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9, + &(lvalues[2809]),0}, +{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2818]),0}, +{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2822]),0}, +{"X500algorithms","directory services - algorithms", + NID_X500algorithms,2,&(lvalues[2827]),0}, +{"ORG","org",NID_org,1,&(lvalues[2829]),0}, +{"DOD","dod",NID_dod,2,&(lvalues[2830]),0}, +{"IANA","iana",NID_iana,3,&(lvalues[2832]),0}, +{"directory","Directory",NID_Directory,4,&(lvalues[2835]),0}, +{"mgmt","Management",NID_Management,4,&(lvalues[2839]),0}, +{"experimental","Experimental",NID_Experimental,4,&(lvalues[2843]),0}, +{"private","Private",NID_Private,4,&(lvalues[2847]),0}, +{"security","Security",NID_Security,4,&(lvalues[2851]),0}, +{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2855]),0}, +{"Mail","Mail",NID_Mail,4,&(lvalues[2859]),0}, +{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2863]),0}, +{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2868]),0}, +{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2877]),0}, +{"domain","Domain",NID_Domain,10,&(lvalues[2887]),0}, +{"NULL","NULL",NID_joint_iso_ccitt,0,NULL,0}, +{"selected-attribute-types","Selected Attribute Types", + NID_selected_attribute_types,3,&(lvalues[2897]),0}, +{"clearance","clearance",NID_clearance,4,&(lvalues[2900]),0}, +{"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9, + &(lvalues[2904]),0}, +{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2913]),0}, +{"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8, + &(lvalues[2921]),0}, +{"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8, + &(lvalues[2929]),0}, +{"role","role",NID_role,3,&(lvalues[2937]),0}, +{"policyConstraints","X509v3 Policy Constraints", + NID_policy_constraints,3,&(lvalues[2940]),0}, +{"targetInformation","X509v3 AC Targeting",NID_target_information,3, + &(lvalues[2943]),0}, +{"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3, + &(lvalues[2946]),0}, +{"NULL","NULL",NID_ccitt,0,NULL,0}, +{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2949]),0}, +{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2954]),0}, +{"characteristic-two-field","characteristic-two-field", + NID_X9_62_characteristic_two_field,7,&(lvalues[2961]),0}, +{"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7, + &(lvalues[2968]),0}, +{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2975]),0}, +{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2983]),0}, +{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2991]),0}, +{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[2999]),0}, +{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3007]),0}, +{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3015]),0}, +{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3023]),0}, +{"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7, + &(lvalues[3031]),0}, +{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3038]),0}, +{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3047]),0}, +{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3056]),0}, +{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3065]),0}, +{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3074]),0}, +{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3083]),0}, +{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3092]),0}, +{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3101]),0}, +{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3110]),0}, +{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3119]),0}, +{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3128]),0}, +{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3137]),0}, +{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3146]),0}, +{"holdInstructionCode","Hold Instruction Code", + NID_hold_instruction_code,3,&(lvalues[3155]),0}, +{"holdInstructionNone","Hold Instruction None", + NID_hold_instruction_none,7,&(lvalues[3158]),0}, +{"holdInstructionCallIssuer","Hold Instruction Call Issuer", + NID_hold_instruction_call_issuer,7,&(lvalues[3165]),0}, +{"holdInstructionReject","Hold Instruction Reject", + NID_hold_instruction_reject,7,&(lvalues[3172]),0}, +{"data","data",NID_data,1,&(lvalues[3179]),0}, +{"pss","pss",NID_pss,3,&(lvalues[3180]),0}, +{"ucl","ucl",NID_ucl,7,&(lvalues[3183]),0}, +{"pilot","pilot",NID_pilot,8,&(lvalues[3190]),0}, +{"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9, + &(lvalues[3198]),0}, +{"pilotAttributeSyntax","pilotAttributeSyntax", + NID_pilotAttributeSyntax,9,&(lvalues[3207]),0}, +{"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9, + &(lvalues[3216]),0}, +{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3225]),0}, +{"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10, + &(lvalues[3234]),0}, +{"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax", + NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3244]),0}, +{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3254]),0}, +{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3264]),0}, +{"account","account",NID_account,10,&(lvalues[3274]),0}, +{"document","document",NID_document,10,&(lvalues[3284]),0}, +{"room","room",NID_room,10,&(lvalues[3294]),0}, +{"documentSeries","documentSeries",NID_documentSeries,10, + &(lvalues[3304]),0}, +{"rFC822localPart","rFC822localPart",NID_rFC822localPart,10, + &(lvalues[3314]),0}, +{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3324]),0}, +{"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject, + 10,&(lvalues[3334]),0}, +{"friendlyCountry","friendlyCountry",NID_friendlyCountry,10, + &(lvalues[3344]),0}, +{"simpleSecurityObject","simpleSecurityObject", + NID_simpleSecurityObject,10,&(lvalues[3354]),0}, +{"pilotOrganization","pilotOrganization",NID_pilotOrganization,10, + &(lvalues[3364]),0}, +{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3374]),0}, +{"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData, + 10,&(lvalues[3384]),0}, +{"UID","userId",NID_userId,10,&(lvalues[3394]),0}, +{"textEncodedORAddress","textEncodedORAddress", + NID_textEncodedORAddress,10,&(lvalues[3404]),0}, +{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3414]),0}, +{"info","info",NID_info,10,&(lvalues[3424]),0}, +{"favouriteDrink","favouriteDrink",NID_favouriteDrink,10, + &(lvalues[3434]),0}, +{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3444]),0}, +{"photo","photo",NID_photo,10,&(lvalues[3454]),0}, +{"userClass","userClass",NID_userClass,10,&(lvalues[3464]),0}, +{"host","host",NID_host,10,&(lvalues[3474]),0}, +{"manager","manager",NID_manager,10,&(lvalues[3484]),0}, +{"documentIdentifier","documentIdentifier",NID_documentIdentifier,10, + &(lvalues[3494]),0}, +{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3504]),0}, +{"documentVersion","documentVersion",NID_documentVersion,10, + &(lvalues[3514]),0}, +{"documentAuthor","documentAuthor",NID_documentAuthor,10, + &(lvalues[3524]),0}, +{"documentLocation","documentLocation",NID_documentLocation,10, + &(lvalues[3534]),0}, +{"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber, + 10,&(lvalues[3544]),0}, +{"secretary","secretary",NID_secretary,10,&(lvalues[3554]),0}, +{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3564]),0}, +{"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10, + &(lvalues[3574]),0}, +{"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10, + &(lvalues[3584]),0}, +{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3594]),0}, +{"pilotAttributeType27","pilotAttributeType27", + NID_pilotAttributeType27,10,&(lvalues[3604]),0}, +{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3614]),0}, +{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3624]),0}, +{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3634]),0}, +{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3644]),0}, +{"associatedDomain","associatedDomain",NID_associatedDomain,10, + &(lvalues[3654]),0}, +{"associatedName","associatedName",NID_associatedName,10, + &(lvalues[3664]),0}, +{"homePostalAddress","homePostalAddress",NID_homePostalAddress,10, + &(lvalues[3674]),0}, +{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3684]),0}, +{"mobileTelephoneNumber","mobileTelephoneNumber", + NID_mobileTelephoneNumber,10,&(lvalues[3694]),0}, +{"pagerTelephoneNumber","pagerTelephoneNumber", + NID_pagerTelephoneNumber,10,&(lvalues[3704]),0}, +{"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName, + 10,&(lvalues[3714]),0}, +{"organizationalStatus","organizationalStatus", + NID_organizationalStatus,10,&(lvalues[3724]),0}, +{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3734]),0}, +{"mailPreferenceOption","mailPreferenceOption", + NID_mailPreferenceOption,10,&(lvalues[3744]),0}, +{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3754]),0}, +{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3764]),0}, +{"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10, + &(lvalues[3774]),0}, +{"subtreeMinimumQuality","subtreeMinimumQuality", + NID_subtreeMinimumQuality,10,&(lvalues[3784]),0}, +{"subtreeMaximumQuality","subtreeMaximumQuality", + NID_subtreeMaximumQuality,10,&(lvalues[3794]),0}, +{"personalSignature","personalSignature",NID_personalSignature,10, + &(lvalues[3804]),0}, +{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3814]),0}, +{"audio","audio",NID_audio,10,&(lvalues[3824]),0}, +{"documentPublisher","documentPublisher",NID_documentPublisher,10, + &(lvalues[3834]),0}, +{"x500UniqueIdentifier","x500UniqueIdentifier", + NID_x500UniqueIdentifier,3,&(lvalues[3844]),0}, +{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3847]),0}, +{"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6, + &(lvalues[3852]),0}, +{"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6, + &(lvalues[3858]),0}, +{"id-hex-partial-message","id-hex-partial-message", + NID_id_hex_partial_message,7,&(lvalues[3864]),0}, +{"id-hex-multipart-message","id-hex-multipart-message", + NID_id_hex_multipart_message,7,&(lvalues[3871]),0}, +{"generationQualifier","generationQualifier",NID_generationQualifier, + 3,&(lvalues[3878]),0}, +{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3881]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"id-set","Secure Electronic Transactions",NID_id_set,2, + &(lvalues[3884]),0}, +{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3886]),0}, +{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3889]),0}, +{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3892]),0}, +{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3895]),0}, +{"set-certExt","certificate extensions",NID_set_certExt,3, + &(lvalues[3898]),0}, +{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3901]),0}, +{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3904]),0}, +{"setct-PANToken","setct-PANToken",NID_setct_PANToken,4, + &(lvalues[3908]),0}, +{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3912]),0}, +{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3916]),0}, +{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3920]),0}, +{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3924]),0}, +{"setct-PIDataUnsigned","setct-PIDataUnsigned", + NID_setct_PIDataUnsigned,4,&(lvalues[3928]),0}, +{"setct-HODInput","setct-HODInput",NID_setct_HODInput,4, + &(lvalues[3932]),0}, +{"setct-AuthResBaggage","setct-AuthResBaggage", + NID_setct_AuthResBaggage,4,&(lvalues[3936]),0}, +{"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage", + NID_setct_AuthRevReqBaggage,4,&(lvalues[3940]),0}, +{"setct-AuthRevResBaggage","setct-AuthRevResBaggage", + NID_setct_AuthRevResBaggage,4,&(lvalues[3944]),0}, +{"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4, + &(lvalues[3948]),0}, +{"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4, + &(lvalues[3952]),0}, +{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3956]),0}, +{"setct-PResData","setct-PResData",NID_setct_PResData,4, + &(lvalues[3960]),0}, +{"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4, + &(lvalues[3964]),0}, +{"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4, + &(lvalues[3968]),0}, +{"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4, + &(lvalues[3972]),0}, +{"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4, + &(lvalues[3976]),0}, +{"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4, + &(lvalues[3980]),0}, +{"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4, + &(lvalues[3984]),0}, +{"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg", + NID_setct_AcqCardCodeMsg,4,&(lvalues[3988]),0}, +{"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS, + 4,&(lvalues[3992]),0}, +{"setct-AuthRevResData","setct-AuthRevResData", + NID_setct_AuthRevResData,4,&(lvalues[3996]),0}, +{"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS, + 4,&(lvalues[4000]),0}, +{"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4, + &(lvalues[4004]),0}, +{"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4, + &(lvalues[4008]),0}, +{"setct-CapResData","setct-CapResData",NID_setct_CapResData,4, + &(lvalues[4012]),0}, +{"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4, + &(lvalues[4016]),0}, +{"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX, + 4,&(lvalues[4020]),0}, +{"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData, + 4,&(lvalues[4024]),0}, +{"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4, + &(lvalues[4028]),0}, +{"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4, + &(lvalues[4032]),0}, +{"setct-CredResData","setct-CredResData",NID_setct_CredResData,4, + &(lvalues[4036]),0}, +{"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS, + 4,&(lvalues[4040]),0}, +{"setct-CredRevReqTBSX","setct-CredRevReqTBSX", + NID_setct_CredRevReqTBSX,4,&(lvalues[4044]),0}, +{"setct-CredRevResData","setct-CredRevResData", + NID_setct_CredRevResData,4,&(lvalues[4048]),0}, +{"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4, + &(lvalues[4052]),0}, +{"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4, + &(lvalues[4056]),0}, +{"setct-BatchAdminReqData","setct-BatchAdminReqData", + NID_setct_BatchAdminReqData,4,&(lvalues[4060]),0}, +{"setct-BatchAdminResData","setct-BatchAdminResData", + NID_setct_BatchAdminResData,4,&(lvalues[4064]),0}, +{"setct-CardCInitResTBS","setct-CardCInitResTBS", + NID_setct_CardCInitResTBS,4,&(lvalues[4068]),0}, +{"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS", + NID_setct_MeAqCInitResTBS,4,&(lvalues[4072]),0}, +{"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS, + 4,&(lvalues[4076]),0}, +{"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4, + &(lvalues[4080]),0}, +{"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4, + &(lvalues[4084]),0}, +{"setct-CertResData","setct-CertResData",NID_setct_CertResData,4, + &(lvalues[4088]),0}, +{"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS, + 4,&(lvalues[4092]),0}, +{"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4, + &(lvalues[4096]),0}, +{"setct-PIDualSignedTBE","setct-PIDualSignedTBE", + NID_setct_PIDualSignedTBE,4,&(lvalues[4100]),0}, +{"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE, + 4,&(lvalues[4104]),0}, +{"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4, + &(lvalues[4108]),0}, +{"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4, + &(lvalues[4112]),0}, +{"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4, + &(lvalues[4116]),0}, +{"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4, + &(lvalues[4120]),0}, +{"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4, + &(lvalues[4124]),0}, +{"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4, + &(lvalues[4128]),0}, +{"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE", + NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4132]),0}, +{"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE, + 4,&(lvalues[4136]),0}, +{"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE, + 4,&(lvalues[4140]),0}, +{"setct-AuthRevResTBEB","setct-AuthRevResTBEB", + NID_setct_AuthRevResTBEB,4,&(lvalues[4144]),0}, +{"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4, + &(lvalues[4148]),0}, +{"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4, + &(lvalues[4152]),0}, +{"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4, + &(lvalues[4156]),0}, +{"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4, + &(lvalues[4160]),0}, +{"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX, + 4,&(lvalues[4164]),0}, +{"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4, + &(lvalues[4168]),0}, +{"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4, + &(lvalues[4172]),0}, +{"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4, + &(lvalues[4176]),0}, +{"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4, + &(lvalues[4180]),0}, +{"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE, + 4,&(lvalues[4184]),0}, +{"setct-CredRevReqTBEX","setct-CredRevReqTBEX", + NID_setct_CredRevReqTBEX,4,&(lvalues[4188]),0}, +{"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE, + 4,&(lvalues[4192]),0}, +{"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE", + NID_setct_BatchAdminReqTBE,4,&(lvalues[4196]),0}, +{"setct-BatchAdminResTBE","setct-BatchAdminResTBE", + NID_setct_BatchAdminResTBE,4,&(lvalues[4200]),0}, +{"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE, + 4,&(lvalues[4204]),0}, +{"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4, + &(lvalues[4208]),0}, +{"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4, + &(lvalues[4212]),0}, +{"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4, + &(lvalues[4216]),0}, +{"setct-CRLNotificationTBS","setct-CRLNotificationTBS", + NID_setct_CRLNotificationTBS,4,&(lvalues[4220]),0}, +{"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS", + NID_setct_CRLNotificationResTBS,4,&(lvalues[4224]),0}, +{"setct-BCIDistributionTBS","setct-BCIDistributionTBS", + NID_setct_BCIDistributionTBS,4,&(lvalues[4228]),0}, +{"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4, + &(lvalues[4232]),0}, +{"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4, + &(lvalues[4236]),0}, +{"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4, + &(lvalues[4240]),0}, +{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4244]),0}, +{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4248]),0}, +{"setext-cv","additional verification",NID_setext_cv,4, + &(lvalues[4252]),0}, +{"set-policy-root","set-policy-root",NID_set_policy_root,4, + &(lvalues[4256]),0}, +{"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4, + &(lvalues[4260]),0}, +{"setCext-certType","setCext-certType",NID_setCext_certType,4, + &(lvalues[4264]),0}, +{"setCext-merchData","setCext-merchData",NID_setCext_merchData,4, + &(lvalues[4268]),0}, +{"setCext-cCertRequired","setCext-cCertRequired", + NID_setCext_cCertRequired,4,&(lvalues[4272]),0}, +{"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4, + &(lvalues[4276]),0}, +{"setCext-setExt","setCext-setExt",NID_setCext_setExt,4, + &(lvalues[4280]),0}, +{"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4, + &(lvalues[4284]),0}, +{"setCext-PGWYcapabilities","setCext-PGWYcapabilities", + NID_setCext_PGWYcapabilities,4,&(lvalues[4288]),0}, +{"setCext-TokenIdentifier","setCext-TokenIdentifier", + NID_setCext_TokenIdentifier,4,&(lvalues[4292]),0}, +{"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4, + &(lvalues[4296]),0}, +{"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4, + &(lvalues[4300]),0}, +{"setCext-IssuerCapabilities","setCext-IssuerCapabilities", + NID_setCext_IssuerCapabilities,4,&(lvalues[4304]),0}, +{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4308]),0}, +{"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap, + 4,&(lvalues[4312]),0}, +{"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4, + &(lvalues[4316]),0}, +{"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4, + &(lvalues[4320]),0}, +{"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5, + &(lvalues[4324]),0}, +{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4329]),0}, +{"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5, + &(lvalues[4334]),0}, +{"setAttr-Token-B0Prime","setAttr-Token-B0Prime", + NID_setAttr_Token_B0Prime,5,&(lvalues[4339]),0}, +{"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5, + &(lvalues[4344]),0}, +{"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5, + &(lvalues[4349]),0}, +{"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5, + &(lvalues[4354]),0}, +{"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm, + 6,&(lvalues[4359]),0}, +{"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6, + &(lvalues[4365]),0}, +{"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6, + &(lvalues[4371]),0}, +{"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6, + &(lvalues[4377]),0}, +{"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig, + 6,&(lvalues[4383]),0}, +{"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4, + &(lvalues[4389]),0}, +{"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4, + &(lvalues[4393]),0}, +{"set-brand-AmericanExpress","set-brand-AmericanExpress", + NID_set_brand_AmericanExpress,4,&(lvalues[4397]),0}, +{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4401]),0}, +{"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4, + &(lvalues[4405]),0}, +{"set-brand-MasterCard","set-brand-MasterCard", + NID_set_brand_MasterCard,4,&(lvalues[4409]),0}, +{"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5, + &(lvalues[4413]),0}, +{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4418]),0}, +{"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET", + NID_rsaOAEPEncryptionSET,9,&(lvalues[4426]),0}, +{"ITU-T","itu-t",NID_itu_t,0,NULL,0}, +{"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,0,NULL,0}, +{"international-organizations","International Organizations", + NID_international_organizations,1,&(lvalues[4435]),0}, +{"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login, + 10,&(lvalues[4436]),0}, +{"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10, + &(lvalues[4446]),0}, +{"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0}, +{"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0}, +{"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0}, +{"AES-128-CFB8","aes-128-cfb8",NID_aes_128_cfb8,0,NULL,0}, +{"AES-192-CFB8","aes-192-cfb8",NID_aes_192_cfb8,0,NULL,0}, +{"AES-256-CFB8","aes-256-cfb8",NID_aes_256_cfb8,0,NULL,0}, +{"DES-CFB1","des-cfb1",NID_des_cfb1,0,NULL,0}, +{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0}, +{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0}, +{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0}, +{"street","streetAddress",NID_streetAddress,3,&(lvalues[4456]),0}, +{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4459]),0}, +{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4462]),0}, +{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8, + &(lvalues[4469]),0}, +{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8, + &(lvalues[4477]),0}, +{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8, + &(lvalues[4485]),0}, +{"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3, + &(lvalues[4493]),0}, +{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4496]),0}, +{"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9, + &(lvalues[4504]),0}, +{"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9, + &(lvalues[4513]),0}, +{"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9, + &(lvalues[4522]),0}, +{"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9, + &(lvalues[4531]),0}, +{"SHA256","sha256",NID_sha256,9,&(lvalues[4540]),0}, +{"SHA384","sha384",NID_sha384,9,&(lvalues[4549]),0}, +{"SHA512","sha512",NID_sha512,9,&(lvalues[4558]),0}, +{"SHA224","sha224",NID_sha224,9,&(lvalues[4567]),0}, +{"identified-organization","identified-organization", + NID_identified_organization,1,&(lvalues[4576]),0}, +{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4577]),0}, +{"wap","wap",NID_wap,2,&(lvalues[4580]),0}, +{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4582]),0}, +{"id-characteristic-two-basis","id-characteristic-two-basis", + NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4585]),0}, +{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4593]),0}, +{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4602]),0}, +{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4611]),0}, +{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4620]),0}, +{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4628]),0}, +{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4636]),0}, +{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4644]),0}, +{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4652]),0}, +{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4660]),0}, +{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4668]),0}, +{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4676]),0}, +{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4684]),0}, +{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4692]),0}, +{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4700]),0}, +{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4708]),0}, +{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4716]),0}, +{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4724]),0}, +{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4732]),0}, +{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4740]),0}, +{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4748]),0}, +{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4756]),0}, +{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4764]),0}, +{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4772]),0}, +{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4780]),0}, +{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4785]),0}, +{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4790]),0}, +{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4795]),0}, +{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4800]),0}, +{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4805]),0}, +{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4810]),0}, +{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4815]),0}, +{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4820]),0}, +{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4825]),0}, +{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4830]),0}, +{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4835]),0}, +{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4840]),0}, +{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4845]),0}, +{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4850]),0}, +{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4855]),0}, +{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4860]),0}, +{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4865]),0}, +{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4870]),0}, +{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4875]),0}, +{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4880]),0}, +{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4885]),0}, +{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4890]),0}, +{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4895]),0}, +{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4900]),0}, +{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4905]),0}, +{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4910]),0}, +{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4915]),0}, +{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4920]),0}, +{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4925]),0}, +{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4930]),0}, +{"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1", + NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4935]),0}, +{"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3", + NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4940]),0}, +{"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4", + NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4945]),0}, +{"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5", + NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4950]),0}, +{"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6", + NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4955]),0}, +{"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7", + NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4960]),0}, +{"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8", + NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4965]),0}, +{"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9", + NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4970]),0}, +{"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10", + NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4975]),0}, +{"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11", + NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4980]),0}, +{"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12", + NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4985]),0}, +{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4990]),0}, +{"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3, + &(lvalues[4994]),0}, +{"inhibitAnyPolicy","X509v3 Inhibit Any Policy", + NID_inhibit_any_policy,3,&(lvalues[4997]),0}, +{"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0}, +{"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0}, +{"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11, + &(lvalues[5000]),0}, +{"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11, + &(lvalues[5011]),0}, +{"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11, + &(lvalues[5022]),0}, +{"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8, + &(lvalues[5033]),0}, +{"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8, + &(lvalues[5041]),0}, +{"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8, + &(lvalues[5049]),0}, +{"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8, + &(lvalues[5057]),0}, +{"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8, + &(lvalues[5065]),0}, +{"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8, + &(lvalues[5073]),0}, +{"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0}, +{"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0}, +{"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0}, +{"CAMELLIA-128-CFB8","camellia-128-cfb8",NID_camellia_128_cfb8,0,NULL,0}, +{"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0}, +{"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0}, +{"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8, + &(lvalues[5081]),0}, +{"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8, + &(lvalues[5089]),0}, +{"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8, + &(lvalues[5097]),0}, +{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes", + NID_subject_directory_attributes,3,&(lvalues[5105]),0}, +{"issuingDistributionPoint","X509v3 Issuing Distrubution Point", + NID_issuing_distribution_point,3,&(lvalues[5108]),0}, +{"certificateIssuer","X509v3 Certificate Issuer", + NID_certificate_issuer,3,&(lvalues[5111]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"KISA","kisa",NID_kisa,6,&(lvalues[5114]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5120]),0}, +{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5128]),0}, +{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5136]),0}, +{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5144]),0}, +{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5152]),0}, +{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5160]),0}, +{"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9, + &(lvalues[5168]),0}, +{"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9, + &(lvalues[5177]),0}, +{"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8, + &(lvalues[5186]),0}, +{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5194]),0}, +{"id-smime-ct-compressedData","id-smime-ct-compressedData", + NID_id_smime_ct_compressedData,11,&(lvalues[5202]),0}, +{"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF", + NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5213]),0}, +{"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9, + &(lvalues[5224]),0}, +{"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9, + &(lvalues[5233]),0}, +{"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9, + &(lvalues[5242]),0}, +{"ecdsa-with-Recommended","ecdsa-with-Recommended", + NID_ecdsa_with_Recommended,7,&(lvalues[5251]),0}, +{"ecdsa-with-Specified","ecdsa-with-Specified", + NID_ecdsa_with_Specified,7,&(lvalues[5258]),0}, +{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8, + &(lvalues[5265]),0}, +{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8, + &(lvalues[5273]),0}, +{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8, + &(lvalues[5281]),0}, +{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8, + &(lvalues[5289]),0}, +{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5297]),0}, +{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8, + &(lvalues[5305]),0}, +{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8, + &(lvalues[5313]),0}, +{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8, + &(lvalues[5321]),0}, +{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8, + &(lvalues[5329]),0}, +{"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9, + &(lvalues[5337]),0}, +{"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9, + &(lvalues[5346]),0}, +{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5355]),0}, +{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5361]),0}, +{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5366]),0}, +{"id-GostR3411-94-with-GostR3410-2001", + "GOST R 34.11-94 with GOST R 34.10-2001", + NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5371]),0}, +{"id-GostR3411-94-with-GostR3410-94", + "GOST R 34.11-94 with GOST R 34.10-94", + NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5377]),0}, +{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5383]),0}, +{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6, + &(lvalues[5389]),0}, +{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6, + &(lvalues[5395]),0}, +{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5401]),0}, +{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5407]),0}, +{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0}, +{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6, + &(lvalues[5413]),0}, +{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6, + &(lvalues[5419]),0}, +{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH, + 6,&(lvalues[5425]),0}, +{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6, + &(lvalues[5431]),0}, +{"id-Gost28147-89-CryptoPro-KeyMeshing", + "id-Gost28147-89-CryptoPro-KeyMeshing", + NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5437]),0}, +{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing", + NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5444]),0}, +{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet", + NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5451]),0}, +{"id-GostR3411-94-CryptoProParamSet", + "id-GostR3411-94-CryptoProParamSet", + NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5458]),0}, +{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet", + NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5465]),0}, +{"id-Gost28147-89-CryptoPro-A-ParamSet", + "id-Gost28147-89-CryptoPro-A-ParamSet", + NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5472]),0}, +{"id-Gost28147-89-CryptoPro-B-ParamSet", + "id-Gost28147-89-CryptoPro-B-ParamSet", + NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5479]),0}, +{"id-Gost28147-89-CryptoPro-C-ParamSet", + "id-Gost28147-89-CryptoPro-C-ParamSet", + NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5486]),0}, +{"id-Gost28147-89-CryptoPro-D-ParamSet", + "id-Gost28147-89-CryptoPro-D-ParamSet", + NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5493]),0}, +{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", + "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5500]), + 0}, +{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", + "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", + NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5507]), + 0}, +{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5514]),0}, +{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet", + NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5521]),0}, +{"id-GostR3410-94-CryptoPro-A-ParamSet", + "id-GostR3410-94-CryptoPro-A-ParamSet", + NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5528]),0}, +{"id-GostR3410-94-CryptoPro-B-ParamSet", + "id-GostR3410-94-CryptoPro-B-ParamSet", + NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5535]),0}, +{"id-GostR3410-94-CryptoPro-C-ParamSet", + "id-GostR3410-94-CryptoPro-C-ParamSet", + NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5542]),0}, +{"id-GostR3410-94-CryptoPro-D-ParamSet", + "id-GostR3410-94-CryptoPro-D-ParamSet", + NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5549]),0}, +{"id-GostR3410-94-CryptoPro-XchA-ParamSet", + "id-GostR3410-94-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5556]),0}, +{"id-GostR3410-94-CryptoPro-XchB-ParamSet", + "id-GostR3410-94-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5563]),0}, +{"id-GostR3410-94-CryptoPro-XchC-ParamSet", + "id-GostR3410-94-CryptoPro-XchC-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5570]),0}, +{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet", + NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5577]),0}, +{"id-GostR3410-2001-CryptoPro-A-ParamSet", + "id-GostR3410-2001-CryptoPro-A-ParamSet", + NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5584]),0}, +{"id-GostR3410-2001-CryptoPro-B-ParamSet", + "id-GostR3410-2001-CryptoPro-B-ParamSet", + NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5591]),0}, +{"id-GostR3410-2001-CryptoPro-C-ParamSet", + "id-GostR3410-2001-CryptoPro-C-ParamSet", + NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5598]),0}, +{"id-GostR3410-2001-CryptoPro-XchA-ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5605]),0}, + +{"id-GostR3410-2001-CryptoPro-XchB-ParamSet", + "id-GostR3410-2001-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5612]),0}, + +{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7, + &(lvalues[5619]),0}, +{"id-GostR3410-94-aBis","id-GostR3410-94-aBis", + NID_id_GostR3410_94_aBis,7,&(lvalues[5626]),0}, +{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7, + &(lvalues[5633]),0}, +{"id-GostR3410-94-bBis","id-GostR3410-94-bBis", + NID_id_GostR3410_94_bBis,7,&(lvalues[5640]),0}, +{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet", + NID_id_Gost28147_89_cc,8,&(lvalues[5647]),0}, +{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8, + &(lvalues[5655]),0}, +{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8, + &(lvalues[5663]),0}, +{"id-GostR3411-94-with-GostR3410-94-cc", + "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom", + NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5671]),0}, +{"id-GostR3411-94-with-GostR3410-2001-cc", + "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom", + NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5679]),0}, +{"id-GostR3410-2001-ParamSet-cc", + "GOST R 3410-2001 Parameter Set Cryptocom", + NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5687]),0}, +{"HMAC","hmac",NID_hmac,0,NULL,0}, +{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9, + &(lvalues[5695]),0}, +{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3, + &(lvalues[5704]),0}, +{"id-on-permanentIdentifier","Permanent Identifier", + NID_id_on_permanentIdentifier,8,&(lvalues[5707]),0}, +{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5715]),0}, +{"businessCategory","businessCategory",NID_businessCategory,3, + &(lvalues[5718]),0}, +{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5721]),0}, +{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5724]),0}, +{"physicalDeliveryOfficeName","physicalDeliveryOfficeName", + NID_physicalDeliveryOfficeName,3,&(lvalues[5727]),0}, +{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3, + &(lvalues[5730]),0}, +{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5733]),0}, +{"teletexTerminalIdentifier","teletexTerminalIdentifier", + NID_teletexTerminalIdentifier,3,&(lvalues[5736]),0}, +{"facsimileTelephoneNumber","facsimileTelephoneNumber", + NID_facsimileTelephoneNumber,3,&(lvalues[5739]),0}, +{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5742]),0}, +{"internationaliSDNNumber","internationaliSDNNumber", + NID_internationaliSDNNumber,3,&(lvalues[5745]),0}, +{"registeredAddress","registeredAddress",NID_registeredAddress,3, + &(lvalues[5748]),0}, +{"destinationIndicator","destinationIndicator", + NID_destinationIndicator,3,&(lvalues[5751]),0}, +{"preferredDeliveryMethod","preferredDeliveryMethod", + NID_preferredDeliveryMethod,3,&(lvalues[5754]),0}, +{"presentationAddress","presentationAddress",NID_presentationAddress, + 3,&(lvalues[5757]),0}, +{"supportedApplicationContext","supportedApplicationContext", + NID_supportedApplicationContext,3,&(lvalues[5760]),0}, +{"member","member",NID_member,3,&(lvalues[5763]),0}, +{"owner","owner",NID_owner,3,&(lvalues[5766]),0}, +{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5769]),0}, +{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5772]),0}, +{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5775]),0}, +{"userCertificate","userCertificate",NID_userCertificate,3, + &(lvalues[5778]),0}, +{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5781]),0}, +{"authorityRevocationList","authorityRevocationList", + NID_authorityRevocationList,3,&(lvalues[5784]),0}, +{"certificateRevocationList","certificateRevocationList", + NID_certificateRevocationList,3,&(lvalues[5787]),0}, +{"crossCertificatePair","crossCertificatePair", + NID_crossCertificatePair,3,&(lvalues[5790]),0}, +{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide, + 3,&(lvalues[5793]),0}, +{"protocolInformation","protocolInformation",NID_protocolInformation, + 3,&(lvalues[5796]),0}, +{"distinguishedName","distinguishedName",NID_distinguishedName,3, + &(lvalues[5799]),0}, +{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5802]),0}, +{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3, + &(lvalues[5805]),0}, +{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms, + 3,&(lvalues[5808]),0}, +{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList, + 3,&(lvalues[5811]),0}, +{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5814]),0}, +{"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11, + &(lvalues[5817]),0}, +{"CMAC","cmac",NID_cmac,0,NULL,0}, +{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5828]),0}, +{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5837]),0}, +{"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9, + &(lvalues[5846]),0}, +{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5855]),0}, +{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5864]),0}, +{"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9, + &(lvalues[5873]),0}, +{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5882]),0}, +{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5891]),0}, +{"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9, + &(lvalues[5900]),0}, +{"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0}, +{"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0}, +{"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0}, +{"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap, + 11,&(lvalues[5909]),0}, +{"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap, + 11,&(lvalues[5920]),0}, +{"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap, + 11,&(lvalues[5931]),0}, +{"anyExtendedKeyUsage","Any Extended Key Usage", + NID_anyExtendedKeyUsage,4,&(lvalues[5942]),0}, +{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5946]),0}, +{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5955]),0}, +{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0}, +{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0}, +{"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0}, +{"AES-128-CBC-HMAC-SHA1","aes-128-cbc-hmac-sha1", + NID_aes_128_cbc_hmac_sha1,0,NULL,0}, +{"AES-192-CBC-HMAC-SHA1","aes-192-cbc-hmac-sha1", + NID_aes_192_cbc_hmac_sha1,0,NULL,0}, +{"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1", + NID_aes_256_cbc_hmac_sha1,0,NULL,0}, +{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5964]),0}, +{"dhpublicnumber","X9.42 DH",NID_dhpublicnumber,7,&(lvalues[5973]),0}, +{"brainpoolP160r1","brainpoolP160r1",NID_brainpoolP160r1,9, + &(lvalues[5980]),0}, +{"brainpoolP160t1","brainpoolP160t1",NID_brainpoolP160t1,9, + &(lvalues[5989]),0}, +{"brainpoolP192r1","brainpoolP192r1",NID_brainpoolP192r1,9, + &(lvalues[5998]),0}, +{"brainpoolP192t1","brainpoolP192t1",NID_brainpoolP192t1,9, + &(lvalues[6007]),0}, +{"brainpoolP224r1","brainpoolP224r1",NID_brainpoolP224r1,9, + &(lvalues[6016]),0}, +{"brainpoolP224t1","brainpoolP224t1",NID_brainpoolP224t1,9, + &(lvalues[6025]),0}, +{"brainpoolP256r1","brainpoolP256r1",NID_brainpoolP256r1,9, + &(lvalues[6034]),0}, +{"brainpoolP256t1","brainpoolP256t1",NID_brainpoolP256t1,9, + &(lvalues[6043]),0}, +{"brainpoolP320r1","brainpoolP320r1",NID_brainpoolP320r1,9, + &(lvalues[6052]),0}, +{"brainpoolP320t1","brainpoolP320t1",NID_brainpoolP320t1,9, + &(lvalues[6061]),0}, +{"brainpoolP384r1","brainpoolP384r1",NID_brainpoolP384r1,9, + &(lvalues[6070]),0}, +{"brainpoolP384t1","brainpoolP384t1",NID_brainpoolP384t1,9, + &(lvalues[6079]),0}, +{"brainpoolP512r1","brainpoolP512r1",NID_brainpoolP512r1,9, + &(lvalues[6088]),0}, +{"brainpoolP512t1","brainpoolP512t1",NID_brainpoolP512t1,9, + &(lvalues[6097]),0}, +{"PSPECIFIED","pSpecified",NID_pSpecified,9,&(lvalues[6106]),0}, +{"dhSinglePass-stdDH-sha1kdf-scheme", + "dhSinglePass-stdDH-sha1kdf-scheme", + NID_dhSinglePass_stdDH_sha1kdf_scheme,9,&(lvalues[6115]),0}, +{"dhSinglePass-stdDH-sha224kdf-scheme", + "dhSinglePass-stdDH-sha224kdf-scheme", + NID_dhSinglePass_stdDH_sha224kdf_scheme,6,&(lvalues[6124]),0}, +{"dhSinglePass-stdDH-sha256kdf-scheme", + "dhSinglePass-stdDH-sha256kdf-scheme", + NID_dhSinglePass_stdDH_sha256kdf_scheme,6,&(lvalues[6130]),0}, +{"dhSinglePass-stdDH-sha384kdf-scheme", + "dhSinglePass-stdDH-sha384kdf-scheme", + NID_dhSinglePass_stdDH_sha384kdf_scheme,6,&(lvalues[6136]),0}, +{"dhSinglePass-stdDH-sha512kdf-scheme", + "dhSinglePass-stdDH-sha512kdf-scheme", + NID_dhSinglePass_stdDH_sha512kdf_scheme,6,&(lvalues[6142]),0}, +{"dhSinglePass-cofactorDH-sha1kdf-scheme", + "dhSinglePass-cofactorDH-sha1kdf-scheme", + NID_dhSinglePass_cofactorDH_sha1kdf_scheme,9,&(lvalues[6148]),0}, +{"dhSinglePass-cofactorDH-sha224kdf-scheme", + "dhSinglePass-cofactorDH-sha224kdf-scheme", + NID_dhSinglePass_cofactorDH_sha224kdf_scheme,6,&(lvalues[6157]),0}, +{"dhSinglePass-cofactorDH-sha256kdf-scheme", + "dhSinglePass-cofactorDH-sha256kdf-scheme", + NID_dhSinglePass_cofactorDH_sha256kdf_scheme,6,&(lvalues[6163]),0}, +{"dhSinglePass-cofactorDH-sha384kdf-scheme", + "dhSinglePass-cofactorDH-sha384kdf-scheme", + NID_dhSinglePass_cofactorDH_sha384kdf_scheme,6,&(lvalues[6169]),0}, +{"dhSinglePass-cofactorDH-sha512kdf-scheme", + "dhSinglePass-cofactorDH-sha512kdf-scheme", + NID_dhSinglePass_cofactorDH_sha512kdf_scheme,6,&(lvalues[6175]),0}, +{"dh-std-kdf","dh-std-kdf",NID_dh_std_kdf,0,NULL,0}, +{"dh-cofactor-kdf","dh-cofactor-kdf",NID_dh_cofactor_kdf,0,NULL,0}, +{"AES-128-CBC-HMAC-SHA256","aes-128-cbc-hmac-sha256", + NID_aes_128_cbc_hmac_sha256,0,NULL,0}, +{"AES-192-CBC-HMAC-SHA256","aes-192-cbc-hmac-sha256", + NID_aes_192_cbc_hmac_sha256,0,NULL,0}, +{"AES-256-CBC-HMAC-SHA256","aes-256-cbc-hmac-sha256", + NID_aes_256_cbc_hmac_sha256,0,NULL,0}, +{"ct_precert_scts","CT Precertificate SCTs",NID_ct_precert_scts,10, + &(lvalues[6181]),0}, +{"ct_precert_poison","CT Precertificate Poison",NID_ct_precert_poison, + 10,&(lvalues[6191]),0}, +{"ct_precert_signer","CT Precertificate Signer",NID_ct_precert_signer, + 10,&(lvalues[6201]),0}, +{"ct_cert_scts","CT Certificate SCTs",NID_ct_cert_scts,10, + &(lvalues[6211]),0}, +{"jurisdictionL","jurisdictionLocalityName", + NID_jurisdictionLocalityName,11,&(lvalues[6221]),0}, +{"jurisdictionST","jurisdictionStateOrProvinceName", + NID_jurisdictionStateOrProvinceName,11,&(lvalues[6232]),0}, +{"jurisdictionC","jurisdictionCountryName", + NID_jurisdictionCountryName,11,&(lvalues[6243]),0}, +}; + +static const unsigned int sn_objs[NUM_SN]={ +364, /* "AD_DVCS" */ +419, /* "AES-128-CBC" */ +916, /* "AES-128-CBC-HMAC-SHA1" */ +948, /* "AES-128-CBC-HMAC-SHA256" */ +421, /* "AES-128-CFB" */ +650, /* "AES-128-CFB1" */ +653, /* "AES-128-CFB8" */ +904, /* "AES-128-CTR" */ +418, /* "AES-128-ECB" */ +420, /* "AES-128-OFB" */ +913, /* "AES-128-XTS" */ +423, /* "AES-192-CBC" */ +917, /* "AES-192-CBC-HMAC-SHA1" */ +949, /* "AES-192-CBC-HMAC-SHA256" */ +425, /* "AES-192-CFB" */ +651, /* "AES-192-CFB1" */ +654, /* "AES-192-CFB8" */ +905, /* "AES-192-CTR" */ +422, /* "AES-192-ECB" */ +424, /* "AES-192-OFB" */ +427, /* "AES-256-CBC" */ +918, /* "AES-256-CBC-HMAC-SHA1" */ +950, /* "AES-256-CBC-HMAC-SHA256" */ +429, /* "AES-256-CFB" */ +652, /* "AES-256-CFB1" */ +655, /* "AES-256-CFB8" */ +906, /* "AES-256-CTR" */ +426, /* "AES-256-ECB" */ +428, /* "AES-256-OFB" */ +914, /* "AES-256-XTS" */ +91, /* "BF-CBC" */ +93, /* "BF-CFB" */ +92, /* "BF-ECB" */ +94, /* "BF-OFB" */ +14, /* "C" */ +751, /* "CAMELLIA-128-CBC" */ +757, /* "CAMELLIA-128-CFB" */ +760, /* "CAMELLIA-128-CFB1" */ +763, /* "CAMELLIA-128-CFB8" */ +754, /* "CAMELLIA-128-ECB" */ +766, /* "CAMELLIA-128-OFB" */ +752, /* "CAMELLIA-192-CBC" */ +758, /* "CAMELLIA-192-CFB" */ +761, /* "CAMELLIA-192-CFB1" */ +764, /* "CAMELLIA-192-CFB8" */ +755, /* "CAMELLIA-192-ECB" */ +767, /* "CAMELLIA-192-OFB" */ +753, /* "CAMELLIA-256-CBC" */ +759, /* "CAMELLIA-256-CFB" */ +762, /* "CAMELLIA-256-CFB1" */ +765, /* "CAMELLIA-256-CFB8" */ +756, /* "CAMELLIA-256-ECB" */ +768, /* "CAMELLIA-256-OFB" */ +108, /* "CAST5-CBC" */ +110, /* "CAST5-CFB" */ +109, /* "CAST5-ECB" */ +111, /* "CAST5-OFB" */ +894, /* "CMAC" */ +13, /* "CN" */ +141, /* "CRLReason" */ +417, /* "CSPName" */ +367, /* "CrlID" */ +391, /* "DC" */ +31, /* "DES-CBC" */ +643, /* "DES-CDMF" */ +30, /* "DES-CFB" */ +656, /* "DES-CFB1" */ +657, /* "DES-CFB8" */ +29, /* "DES-ECB" */ +32, /* "DES-EDE" */ +43, /* "DES-EDE-CBC" */ +60, /* "DES-EDE-CFB" */ +62, /* "DES-EDE-OFB" */ +33, /* "DES-EDE3" */ +44, /* "DES-EDE3-CBC" */ +61, /* "DES-EDE3-CFB" */ +658, /* "DES-EDE3-CFB1" */ +659, /* "DES-EDE3-CFB8" */ +63, /* "DES-EDE3-OFB" */ +45, /* "DES-OFB" */ +80, /* "DESX-CBC" */ +380, /* "DOD" */ +116, /* "DSA" */ +66, /* "DSA-SHA" */ +113, /* "DSA-SHA1" */ +70, /* "DSA-SHA1-old" */ +67, /* "DSA-old" */ +297, /* "DVCS" */ +99, /* "GN" */ +855, /* "HMAC" */ +780, /* "HMAC-MD5" */ +781, /* "HMAC-SHA1" */ +381, /* "IANA" */ +34, /* "IDEA-CBC" */ +35, /* "IDEA-CFB" */ +36, /* "IDEA-ECB" */ +46, /* "IDEA-OFB" */ +181, /* "ISO" */ +183, /* "ISO-US" */ +645, /* "ITU-T" */ +646, /* "JOINT-ISO-ITU-T" */ +773, /* "KISA" */ +15, /* "L" */ +856, /* "LocalKeySet" */ + 3, /* "MD2" */ +257, /* "MD4" */ + 4, /* "MD5" */ +114, /* "MD5-SHA1" */ +95, /* "MDC2" */ +911, /* "MGF1" */ +388, /* "Mail" */ +393, /* "NULL" */ +404, /* "NULL" */ +57, /* "Netscape" */ +366, /* "Nonce" */ +17, /* "O" */ +178, /* "OCSP" */ +180, /* "OCSPSigning" */ +379, /* "ORG" */ +18, /* "OU" */ +749, /* "Oakley-EC2N-3" */ +750, /* "Oakley-EC2N-4" */ + 9, /* "PBE-MD2-DES" */ +168, /* "PBE-MD2-RC2-64" */ +10, /* "PBE-MD5-DES" */ +169, /* "PBE-MD5-RC2-64" */ +147, /* "PBE-SHA1-2DES" */ +146, /* "PBE-SHA1-3DES" */ +170, /* "PBE-SHA1-DES" */ +148, /* "PBE-SHA1-RC2-128" */ +149, /* "PBE-SHA1-RC2-40" */ +68, /* "PBE-SHA1-RC2-64" */ +144, /* "PBE-SHA1-RC4-128" */ +145, /* "PBE-SHA1-RC4-40" */ +161, /* "PBES2" */ +69, /* "PBKDF2" */ +162, /* "PBMAC1" */ +127, /* "PKIX" */ +935, /* "PSPECIFIED" */ +98, /* "RC2-40-CBC" */ +166, /* "RC2-64-CBC" */ +37, /* "RC2-CBC" */ +39, /* "RC2-CFB" */ +38, /* "RC2-ECB" */ +40, /* "RC2-OFB" */ + 5, /* "RC4" */ +97, /* "RC4-40" */ +915, /* "RC4-HMAC-MD5" */ +120, /* "RC5-CBC" */ +122, /* "RC5-CFB" */ +121, /* "RC5-ECB" */ +123, /* "RC5-OFB" */ +117, /* "RIPEMD160" */ +124, /* "RLE" */ +19, /* "RSA" */ + 7, /* "RSA-MD2" */ +396, /* "RSA-MD4" */ + 8, /* "RSA-MD5" */ +96, /* "RSA-MDC2" */ +104, /* "RSA-NP-MD5" */ +119, /* "RSA-RIPEMD160" */ +42, /* "RSA-SHA" */ +65, /* "RSA-SHA1" */ +115, /* "RSA-SHA1-2" */ +671, /* "RSA-SHA224" */ +668, /* "RSA-SHA256" */ +669, /* "RSA-SHA384" */ +670, /* "RSA-SHA512" */ +919, /* "RSAES-OAEP" */ +912, /* "RSASSA-PSS" */ +777, /* "SEED-CBC" */ +779, /* "SEED-CFB" */ +776, /* "SEED-ECB" */ +778, /* "SEED-OFB" */ +41, /* "SHA" */ +64, /* "SHA1" */ +675, /* "SHA224" */ +672, /* "SHA256" */ +673, /* "SHA384" */ +674, /* "SHA512" */ +188, /* "SMIME" */ +167, /* "SMIME-CAPS" */ +100, /* "SN" */ +16, /* "ST" */ +143, /* "SXNetID" */ +458, /* "UID" */ + 0, /* "UNDEF" */ +11, /* "X500" */ +378, /* "X500algorithms" */ +12, /* "X509" */ +184, /* "X9-57" */ +185, /* "X9cm" */ +125, /* "ZLIB" */ +478, /* "aRecord" */ +289, /* "aaControls" */ +287, /* "ac-auditEntity" */ +397, /* "ac-proxying" */ +288, /* "ac-targeting" */ +368, /* "acceptableResponses" */ +446, /* "account" */ +363, /* "ad_timestamping" */ +376, /* "algorithm" */ +405, /* "ansi-X9-62" */ +910, /* "anyExtendedKeyUsage" */ +746, /* "anyPolicy" */ +370, /* "archiveCutoff" */ +484, /* "associatedDomain" */ +485, /* "associatedName" */ +501, /* "audio" */ +177, /* "authorityInfoAccess" */ +90, /* "authorityKeyIdentifier" */ +882, /* "authorityRevocationList" */ +87, /* "basicConstraints" */ +365, /* "basicOCSPResponse" */ +285, /* "biometricInfo" */ +921, /* "brainpoolP160r1" */ +922, /* "brainpoolP160t1" */ +923, /* "brainpoolP192r1" */ +924, /* "brainpoolP192t1" */ +925, /* "brainpoolP224r1" */ +926, /* "brainpoolP224t1" */ +927, /* "brainpoolP256r1" */ +928, /* "brainpoolP256t1" */ +929, /* "brainpoolP320r1" */ +930, /* "brainpoolP320t1" */ +931, /* "brainpoolP384r1" */ +932, /* "brainpoolP384t1" */ +933, /* "brainpoolP512r1" */ +934, /* "brainpoolP512t1" */ +494, /* "buildingName" */ +860, /* "businessCategory" */ +691, /* "c2onb191v4" */ +692, /* "c2onb191v5" */ +697, /* "c2onb239v4" */ +698, /* "c2onb239v5" */ +684, /* "c2pnb163v1" */ +685, /* "c2pnb163v2" */ +686, /* "c2pnb163v3" */ +687, /* "c2pnb176v1" */ +693, /* "c2pnb208w1" */ +699, /* "c2pnb272w1" */ +700, /* "c2pnb304w1" */ +702, /* "c2pnb368w1" */ +688, /* "c2tnb191v1" */ +689, /* "c2tnb191v2" */ +690, /* "c2tnb191v3" */ +694, /* "c2tnb239v1" */ +695, /* "c2tnb239v2" */ +696, /* "c2tnb239v3" */ +701, /* "c2tnb359v1" */ +703, /* "c2tnb431r1" */ +881, /* "cACertificate" */ +483, /* "cNAMERecord" */ +179, /* "caIssuers" */ +785, /* "caRepository" */ +443, /* "caseIgnoreIA5StringSyntax" */ +152, /* "certBag" */ +677, /* "certicom-arc" */ +771, /* "certificateIssuer" */ +89, /* "certificatePolicies" */ +883, /* "certificateRevocationList" */ +54, /* "challengePassword" */ +407, /* "characteristic-two-field" */ +395, /* "clearance" */ +130, /* "clientAuth" */ +131, /* "codeSigning" */ +50, /* "contentType" */ +53, /* "countersignature" */ +153, /* "crlBag" */ +103, /* "crlDistributionPoints" */ +88, /* "crlNumber" */ +884, /* "crossCertificatePair" */ +806, /* "cryptocom" */ +805, /* "cryptopro" */ +954, /* "ct_cert_scts" */ +952, /* "ct_precert_poison" */ +951, /* "ct_precert_scts" */ +953, /* "ct_precert_signer" */ +500, /* "dITRedirect" */ +451, /* "dNSDomain" */ +495, /* "dSAQuality" */ +434, /* "data" */ +390, /* "dcobject" */ +140, /* "deltaCRL" */ +891, /* "deltaRevocationList" */ +107, /* "description" */ +871, /* "destinationIndicator" */ +947, /* "dh-cofactor-kdf" */ +946, /* "dh-std-kdf" */ +28, /* "dhKeyAgreement" */ +941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */ +942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */ +943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */ +944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */ +945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */ +936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */ +937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */ +938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */ +939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */ +940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */ +920, /* "dhpublicnumber" */ +382, /* "directory" */ +887, /* "distinguishedName" */ +892, /* "dmdName" */ +174, /* "dnQualifier" */ +447, /* "document" */ +471, /* "documentAuthor" */ +468, /* "documentIdentifier" */ +472, /* "documentLocation" */ +502, /* "documentPublisher" */ +449, /* "documentSeries" */ +469, /* "documentTitle" */ +470, /* "documentVersion" */ +392, /* "domain" */ +452, /* "domainRelatedObject" */ +802, /* "dsa_with_SHA224" */ +803, /* "dsa_with_SHA256" */ +791, /* "ecdsa-with-Recommended" */ +416, /* "ecdsa-with-SHA1" */ +793, /* "ecdsa-with-SHA224" */ +794, /* "ecdsa-with-SHA256" */ +795, /* "ecdsa-with-SHA384" */ +796, /* "ecdsa-with-SHA512" */ +792, /* "ecdsa-with-Specified" */ +48, /* "emailAddress" */ +132, /* "emailProtection" */ +885, /* "enhancedSearchGuide" */ +389, /* "enterprises" */ +384, /* "experimental" */ +172, /* "extReq" */ +56, /* "extendedCertificateAttributes" */ +126, /* "extendedKeyUsage" */ +372, /* "extendedStatus" */ +867, /* "facsimileTelephoneNumber" */ +462, /* "favouriteDrink" */ +857, /* "freshestCRL" */ +453, /* "friendlyCountry" */ +490, /* "friendlyCountryName" */ +156, /* "friendlyName" */ +509, /* "generationQualifier" */ +815, /* "gost-mac" */ +811, /* "gost2001" */ +851, /* "gost2001cc" */ +813, /* "gost89" */ +814, /* "gost89-cnt" */ +812, /* "gost94" */ +850, /* "gost94cc" */ +797, /* "hmacWithMD5" */ +163, /* "hmacWithSHA1" */ +798, /* "hmacWithSHA224" */ +799, /* "hmacWithSHA256" */ +800, /* "hmacWithSHA384" */ +801, /* "hmacWithSHA512" */ +432, /* "holdInstructionCallIssuer" */ +430, /* "holdInstructionCode" */ +431, /* "holdInstructionNone" */ +433, /* "holdInstructionReject" */ +486, /* "homePostalAddress" */ +473, /* "homeTelephoneNumber" */ +466, /* "host" */ +889, /* "houseIdentifier" */ +442, /* "iA5StringSyntax" */ +783, /* "id-DHBasedMac" */ +824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ +825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ +826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ +827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ +819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ +829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ +828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ +830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ +820, /* "id-Gost28147-89-None-KeyMeshing" */ +823, /* "id-Gost28147-89-TestParamSet" */ +849, /* "id-Gost28147-89-cc" */ +840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ +841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ +842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ +843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ +844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ +854, /* "id-GostR3410-2001-ParamSet-cc" */ +839, /* "id-GostR3410-2001-TestParamSet" */ +817, /* "id-GostR3410-2001DH" */ +832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ +833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ +834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ +835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ +836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ +837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ +838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ +831, /* "id-GostR3410-94-TestParamSet" */ +845, /* "id-GostR3410-94-a" */ +846, /* "id-GostR3410-94-aBis" */ +847, /* "id-GostR3410-94-b" */ +848, /* "id-GostR3410-94-bBis" */ +818, /* "id-GostR3410-94DH" */ +822, /* "id-GostR3411-94-CryptoProParamSet" */ +821, /* "id-GostR3411-94-TestParamSet" */ +807, /* "id-GostR3411-94-with-GostR3410-2001" */ +853, /* "id-GostR3411-94-with-GostR3410-2001-cc" */ +808, /* "id-GostR3411-94-with-GostR3410-94" */ +852, /* "id-GostR3411-94-with-GostR3410-94-cc" */ +810, /* "id-HMACGostR3411-94" */ +782, /* "id-PasswordBasedMAC" */ +266, /* "id-aca" */ +355, /* "id-aca-accessIdentity" */ +354, /* "id-aca-authenticationInfo" */ +356, /* "id-aca-chargingIdentity" */ +399, /* "id-aca-encAttrs" */ +357, /* "id-aca-group" */ +358, /* "id-aca-role" */ +176, /* "id-ad" */ +896, /* "id-aes128-CCM" */ +895, /* "id-aes128-GCM" */ +788, /* "id-aes128-wrap" */ +897, /* "id-aes128-wrap-pad" */ +899, /* "id-aes192-CCM" */ +898, /* "id-aes192-GCM" */ +789, /* "id-aes192-wrap" */ +900, /* "id-aes192-wrap-pad" */ +902, /* "id-aes256-CCM" */ +901, /* "id-aes256-GCM" */ +790, /* "id-aes256-wrap" */ +903, /* "id-aes256-wrap-pad" */ +262, /* "id-alg" */ +893, /* "id-alg-PWRI-KEK" */ +323, /* "id-alg-des40" */ +326, /* "id-alg-dh-pop" */ +325, /* "id-alg-dh-sig-hmac-sha1" */ +324, /* "id-alg-noSignature" */ +907, /* "id-camellia128-wrap" */ +908, /* "id-camellia192-wrap" */ +909, /* "id-camellia256-wrap" */ +268, /* "id-cct" */ +361, /* "id-cct-PKIData" */ +362, /* "id-cct-PKIResponse" */ +360, /* "id-cct-crs" */ +81, /* "id-ce" */ +680, /* "id-characteristic-two-basis" */ +263, /* "id-cmc" */ +334, /* "id-cmc-addExtensions" */ +346, /* "id-cmc-confirmCertAcceptance" */ +330, /* "id-cmc-dataReturn" */ +336, /* "id-cmc-decryptedPOP" */ +335, /* "id-cmc-encryptedPOP" */ +339, /* "id-cmc-getCRL" */ +338, /* "id-cmc-getCert" */ +328, /* "id-cmc-identification" */ +329, /* "id-cmc-identityProof" */ +337, /* "id-cmc-lraPOPWitness" */ +344, /* "id-cmc-popLinkRandom" */ +345, /* "id-cmc-popLinkWitness" */ +343, /* "id-cmc-queryPending" */ +333, /* "id-cmc-recipientNonce" */ +341, /* "id-cmc-regInfo" */ +342, /* "id-cmc-responseInfo" */ +340, /* "id-cmc-revokeRequest" */ +332, /* "id-cmc-senderNonce" */ +327, /* "id-cmc-statusInfo" */ +331, /* "id-cmc-transactionId" */ +787, /* "id-ct-asciiTextWithCRLF" */ +408, /* "id-ecPublicKey" */ +508, /* "id-hex-multipart-message" */ +507, /* "id-hex-partial-message" */ +260, /* "id-it" */ +302, /* "id-it-caKeyUpdateInfo" */ +298, /* "id-it-caProtEncCert" */ +311, /* "id-it-confirmWaitTime" */ +303, /* "id-it-currentCRL" */ +300, /* "id-it-encKeyPairTypes" */ +310, /* "id-it-implicitConfirm" */ +308, /* "id-it-keyPairParamRep" */ +307, /* "id-it-keyPairParamReq" */ +312, /* "id-it-origPKIMessage" */ +301, /* "id-it-preferredSymmAlg" */ +309, /* "id-it-revPassphrase" */ +299, /* "id-it-signKeyPairTypes" */ +305, /* "id-it-subscriptionRequest" */ +306, /* "id-it-subscriptionResponse" */ +784, /* "id-it-suppLangTags" */ +304, /* "id-it-unsupportedOIDs" */ +128, /* "id-kp" */ +280, /* "id-mod-attribute-cert" */ +274, /* "id-mod-cmc" */ +277, /* "id-mod-cmp" */ +284, /* "id-mod-cmp2000" */ +273, /* "id-mod-crmf" */ +283, /* "id-mod-dvcs" */ +275, /* "id-mod-kea-profile-88" */ +276, /* "id-mod-kea-profile-93" */ +282, /* "id-mod-ocsp" */ +278, /* "id-mod-qualified-cert-88" */ +279, /* "id-mod-qualified-cert-93" */ +281, /* "id-mod-timestamp-protocol" */ +264, /* "id-on" */ +858, /* "id-on-permanentIdentifier" */ +347, /* "id-on-personalData" */ +265, /* "id-pda" */ +352, /* "id-pda-countryOfCitizenship" */ +353, /* "id-pda-countryOfResidence" */ +348, /* "id-pda-dateOfBirth" */ +351, /* "id-pda-gender" */ +349, /* "id-pda-placeOfBirth" */ +175, /* "id-pe" */ +261, /* "id-pkip" */ +258, /* "id-pkix-mod" */ +269, /* "id-pkix1-explicit-88" */ +271, /* "id-pkix1-explicit-93" */ +270, /* "id-pkix1-implicit-88" */ +272, /* "id-pkix1-implicit-93" */ +662, /* "id-ppl" */ +664, /* "id-ppl-anyLanguage" */ +667, /* "id-ppl-independent" */ +665, /* "id-ppl-inheritAll" */ +267, /* "id-qcs" */ +359, /* "id-qcs-pkixQCSyntax-v1" */ +259, /* "id-qt" */ +164, /* "id-qt-cps" */ +165, /* "id-qt-unotice" */ +313, /* "id-regCtrl" */ +316, /* "id-regCtrl-authenticator" */ +319, /* "id-regCtrl-oldCertID" */ +318, /* "id-regCtrl-pkiArchiveOptions" */ +317, /* "id-regCtrl-pkiPublicationInfo" */ +320, /* "id-regCtrl-protocolEncrKey" */ +315, /* "id-regCtrl-regToken" */ +314, /* "id-regInfo" */ +322, /* "id-regInfo-certReq" */ +321, /* "id-regInfo-utf8Pairs" */ +512, /* "id-set" */ +191, /* "id-smime-aa" */ +215, /* "id-smime-aa-contentHint" */ +218, /* "id-smime-aa-contentIdentifier" */ +221, /* "id-smime-aa-contentReference" */ +240, /* "id-smime-aa-dvcs-dvc" */ +217, /* "id-smime-aa-encapContentType" */ +222, /* "id-smime-aa-encrypKeyPref" */ +220, /* "id-smime-aa-equivalentLabels" */ +232, /* "id-smime-aa-ets-CertificateRefs" */ +233, /* "id-smime-aa-ets-RevocationRefs" */ +238, /* "id-smime-aa-ets-archiveTimeStamp" */ +237, /* "id-smime-aa-ets-certCRLTimestamp" */ +234, /* "id-smime-aa-ets-certValues" */ +227, /* "id-smime-aa-ets-commitmentType" */ +231, /* "id-smime-aa-ets-contentTimestamp" */ +236, /* "id-smime-aa-ets-escTimeStamp" */ +230, /* "id-smime-aa-ets-otherSigCert" */ +235, /* "id-smime-aa-ets-revocationValues" */ +226, /* "id-smime-aa-ets-sigPolicyId" */ +229, /* "id-smime-aa-ets-signerAttr" */ +228, /* "id-smime-aa-ets-signerLocation" */ +219, /* "id-smime-aa-macValue" */ +214, /* "id-smime-aa-mlExpandHistory" */ +216, /* "id-smime-aa-msgSigDigest" */ +212, /* "id-smime-aa-receiptRequest" */ +213, /* "id-smime-aa-securityLabel" */ +239, /* "id-smime-aa-signatureType" */ +223, /* "id-smime-aa-signingCertificate" */ +224, /* "id-smime-aa-smimeEncryptCerts" */ +225, /* "id-smime-aa-timeStampToken" */ +192, /* "id-smime-alg" */ +243, /* "id-smime-alg-3DESwrap" */ +246, /* "id-smime-alg-CMS3DESwrap" */ +247, /* "id-smime-alg-CMSRC2wrap" */ +245, /* "id-smime-alg-ESDH" */ +241, /* "id-smime-alg-ESDHwith3DES" */ +242, /* "id-smime-alg-ESDHwithRC2" */ +244, /* "id-smime-alg-RC2wrap" */ +193, /* "id-smime-cd" */ +248, /* "id-smime-cd-ldap" */ +190, /* "id-smime-ct" */ +210, /* "id-smime-ct-DVCSRequestData" */ +211, /* "id-smime-ct-DVCSResponseData" */ +208, /* "id-smime-ct-TDTInfo" */ +207, /* "id-smime-ct-TSTInfo" */ +205, /* "id-smime-ct-authData" */ +786, /* "id-smime-ct-compressedData" */ +209, /* "id-smime-ct-contentInfo" */ +206, /* "id-smime-ct-publishCert" */ +204, /* "id-smime-ct-receipt" */ +195, /* "id-smime-cti" */ +255, /* "id-smime-cti-ets-proofOfApproval" */ +256, /* "id-smime-cti-ets-proofOfCreation" */ +253, /* "id-smime-cti-ets-proofOfDelivery" */ +251, /* "id-smime-cti-ets-proofOfOrigin" */ +252, /* "id-smime-cti-ets-proofOfReceipt" */ +254, /* "id-smime-cti-ets-proofOfSender" */ +189, /* "id-smime-mod" */ +196, /* "id-smime-mod-cms" */ +197, /* "id-smime-mod-ess" */ +202, /* "id-smime-mod-ets-eSigPolicy-88" */ +203, /* "id-smime-mod-ets-eSigPolicy-97" */ +200, /* "id-smime-mod-ets-eSignature-88" */ +201, /* "id-smime-mod-ets-eSignature-97" */ +199, /* "id-smime-mod-msg-v3" */ +198, /* "id-smime-mod-oid" */ +194, /* "id-smime-spq" */ +250, /* "id-smime-spq-ets-sqt-unotice" */ +249, /* "id-smime-spq-ets-sqt-uri" */ +676, /* "identified-organization" */ +461, /* "info" */ +748, /* "inhibitAnyPolicy" */ +101, /* "initials" */ +647, /* "international-organizations" */ +869, /* "internationaliSDNNumber" */ +142, /* "invalidityDate" */ +294, /* "ipsecEndSystem" */ +295, /* "ipsecTunnel" */ +296, /* "ipsecUser" */ +86, /* "issuerAltName" */ +770, /* "issuingDistributionPoint" */ +492, /* "janetMailbox" */ +957, /* "jurisdictionC" */ +955, /* "jurisdictionL" */ +956, /* "jurisdictionST" */ +150, /* "keyBag" */ +83, /* "keyUsage" */ +477, /* "lastModifiedBy" */ +476, /* "lastModifiedTime" */ +157, /* "localKeyID" */ +480, /* "mXRecord" */ +460, /* "mail" */ +493, /* "mailPreferenceOption" */ +467, /* "manager" */ +809, /* "md_gost94" */ +875, /* "member" */ +182, /* "member-body" */ +51, /* "messageDigest" */ +383, /* "mgmt" */ +504, /* "mime-mhs" */ +506, /* "mime-mhs-bodies" */ +505, /* "mime-mhs-headings" */ +488, /* "mobileTelephoneNumber" */ +136, /* "msCTLSign" */ +135, /* "msCodeCom" */ +134, /* "msCodeInd" */ +138, /* "msEFS" */ +171, /* "msExtReq" */ +137, /* "msSGC" */ +648, /* "msSmartcardLogin" */ +649, /* "msUPN" */ +481, /* "nSRecord" */ +173, /* "name" */ +666, /* "nameConstraints" */ +369, /* "noCheck" */ +403, /* "noRevAvail" */ +72, /* "nsBaseUrl" */ +76, /* "nsCaPolicyUrl" */ +74, /* "nsCaRevocationUrl" */ +58, /* "nsCertExt" */ +79, /* "nsCertSequence" */ +71, /* "nsCertType" */ +78, /* "nsComment" */ +59, /* "nsDataType" */ +75, /* "nsRenewalUrl" */ +73, /* "nsRevocationUrl" */ +139, /* "nsSGC" */ +77, /* "nsSslServerName" */ +681, /* "onBasis" */ +491, /* "organizationalStatus" */ +475, /* "otherMailbox" */ +876, /* "owner" */ +489, /* "pagerTelephoneNumber" */ +374, /* "path" */ +112, /* "pbeWithMD5AndCast5CBC" */ +499, /* "personalSignature" */ +487, /* "personalTitle" */ +464, /* "photo" */ +863, /* "physicalDeliveryOfficeName" */ +437, /* "pilot" */ +439, /* "pilotAttributeSyntax" */ +438, /* "pilotAttributeType" */ +479, /* "pilotAttributeType27" */ +456, /* "pilotDSA" */ +441, /* "pilotGroups" */ +444, /* "pilotObject" */ +440, /* "pilotObjectClass" */ +455, /* "pilotOrganization" */ +445, /* "pilotPerson" */ + 2, /* "pkcs" */ +186, /* "pkcs1" */ +27, /* "pkcs3" */ +187, /* "pkcs5" */ +20, /* "pkcs7" */ +21, /* "pkcs7-data" */ +25, /* "pkcs7-digestData" */ +26, /* "pkcs7-encryptedData" */ +23, /* "pkcs7-envelopedData" */ +24, /* "pkcs7-signedAndEnvelopedData" */ +22, /* "pkcs7-signedData" */ +151, /* "pkcs8ShroudedKeyBag" */ +47, /* "pkcs9" */ +401, /* "policyConstraints" */ +747, /* "policyMappings" */ +862, /* "postOfficeBox" */ +861, /* "postalAddress" */ +661, /* "postalCode" */ +683, /* "ppBasis" */ +872, /* "preferredDeliveryMethod" */ +873, /* "presentationAddress" */ +816, /* "prf-gostr3411-94" */ +406, /* "prime-field" */ +409, /* "prime192v1" */ +410, /* "prime192v2" */ +411, /* "prime192v3" */ +412, /* "prime239v1" */ +413, /* "prime239v2" */ +414, /* "prime239v3" */ +415, /* "prime256v1" */ +385, /* "private" */ +84, /* "privateKeyUsagePeriod" */ +886, /* "protocolInformation" */ +663, /* "proxyCertInfo" */ +510, /* "pseudonym" */ +435, /* "pss" */ +286, /* "qcStatements" */ +457, /* "qualityLabelledData" */ +450, /* "rFC822localPart" */ +870, /* "registeredAddress" */ +400, /* "role" */ +877, /* "roleOccupant" */ +448, /* "room" */ +463, /* "roomNumber" */ + 6, /* "rsaEncryption" */ +644, /* "rsaOAEPEncryptionSET" */ +377, /* "rsaSignature" */ + 1, /* "rsadsi" */ +482, /* "sOARecord" */ +155, /* "safeContentsBag" */ +291, /* "sbgp-autonomousSysNum" */ +290, /* "sbgp-ipAddrBlock" */ +292, /* "sbgp-routerIdentifier" */ +159, /* "sdsiCertificate" */ +859, /* "searchGuide" */ +704, /* "secp112r1" */ +705, /* "secp112r2" */ +706, /* "secp128r1" */ +707, /* "secp128r2" */ +708, /* "secp160k1" */ +709, /* "secp160r1" */ +710, /* "secp160r2" */ +711, /* "secp192k1" */ +712, /* "secp224k1" */ +713, /* "secp224r1" */ +714, /* "secp256k1" */ +715, /* "secp384r1" */ +716, /* "secp521r1" */ +154, /* "secretBag" */ +474, /* "secretary" */ +717, /* "sect113r1" */ +718, /* "sect113r2" */ +719, /* "sect131r1" */ +720, /* "sect131r2" */ +721, /* "sect163k1" */ +722, /* "sect163r1" */ +723, /* "sect163r2" */ +724, /* "sect193r1" */ +725, /* "sect193r2" */ +726, /* "sect233k1" */ +727, /* "sect233r1" */ +728, /* "sect239k1" */ +729, /* "sect283k1" */ +730, /* "sect283r1" */ +731, /* "sect409k1" */ +732, /* "sect409r1" */ +733, /* "sect571k1" */ +734, /* "sect571r1" */ +386, /* "security" */ +878, /* "seeAlso" */ +394, /* "selected-attribute-types" */ +105, /* "serialNumber" */ +129, /* "serverAuth" */ +371, /* "serviceLocator" */ +625, /* "set-addPolicy" */ +515, /* "set-attr" */ +518, /* "set-brand" */ +638, /* "set-brand-AmericanExpress" */ +637, /* "set-brand-Diners" */ +636, /* "set-brand-IATA-ATA" */ +639, /* "set-brand-JCB" */ +641, /* "set-brand-MasterCard" */ +642, /* "set-brand-Novus" */ +640, /* "set-brand-Visa" */ +517, /* "set-certExt" */ +513, /* "set-ctype" */ +514, /* "set-msgExt" */ +516, /* "set-policy" */ +607, /* "set-policy-root" */ +624, /* "set-rootKeyThumb" */ +620, /* "setAttr-Cert" */ +631, /* "setAttr-GenCryptgrm" */ +623, /* "setAttr-IssCap" */ +628, /* "setAttr-IssCap-CVM" */ +630, /* "setAttr-IssCap-Sig" */ +629, /* "setAttr-IssCap-T2" */ +621, /* "setAttr-PGWYcap" */ +635, /* "setAttr-SecDevSig" */ +632, /* "setAttr-T2Enc" */ +633, /* "setAttr-T2cleartxt" */ +634, /* "setAttr-TokICCsig" */ +627, /* "setAttr-Token-B0Prime" */ +626, /* "setAttr-Token-EMV" */ +622, /* "setAttr-TokenType" */ +619, /* "setCext-IssuerCapabilities" */ +615, /* "setCext-PGWYcapabilities" */ +616, /* "setCext-TokenIdentifier" */ +618, /* "setCext-TokenType" */ +617, /* "setCext-Track2Data" */ +611, /* "setCext-cCertRequired" */ +609, /* "setCext-certType" */ +608, /* "setCext-hashedRoot" */ +610, /* "setCext-merchData" */ +613, /* "setCext-setExt" */ +614, /* "setCext-setQualf" */ +612, /* "setCext-tunneling" */ +540, /* "setct-AcqCardCodeMsg" */ +576, /* "setct-AcqCardCodeMsgTBE" */ +570, /* "setct-AuthReqTBE" */ +534, /* "setct-AuthReqTBS" */ +527, /* "setct-AuthResBaggage" */ +571, /* "setct-AuthResTBE" */ +572, /* "setct-AuthResTBEX" */ +535, /* "setct-AuthResTBS" */ +536, /* "setct-AuthResTBSX" */ +528, /* "setct-AuthRevReqBaggage" */ +577, /* "setct-AuthRevReqTBE" */ +541, /* "setct-AuthRevReqTBS" */ +529, /* "setct-AuthRevResBaggage" */ +542, /* "setct-AuthRevResData" */ +578, /* "setct-AuthRevResTBE" */ +579, /* "setct-AuthRevResTBEB" */ +543, /* "setct-AuthRevResTBS" */ +573, /* "setct-AuthTokenTBE" */ +537, /* "setct-AuthTokenTBS" */ +600, /* "setct-BCIDistributionTBS" */ +558, /* "setct-BatchAdminReqData" */ +592, /* "setct-BatchAdminReqTBE" */ +559, /* "setct-BatchAdminResData" */ +593, /* "setct-BatchAdminResTBE" */ +599, /* "setct-CRLNotificationResTBS" */ +598, /* "setct-CRLNotificationTBS" */ +580, /* "setct-CapReqTBE" */ +581, /* "setct-CapReqTBEX" */ +544, /* "setct-CapReqTBS" */ +545, /* "setct-CapReqTBSX" */ +546, /* "setct-CapResData" */ +582, /* "setct-CapResTBE" */ +583, /* "setct-CapRevReqTBE" */ +584, /* "setct-CapRevReqTBEX" */ +547, /* "setct-CapRevReqTBS" */ +548, /* "setct-CapRevReqTBSX" */ +549, /* "setct-CapRevResData" */ +585, /* "setct-CapRevResTBE" */ +538, /* "setct-CapTokenData" */ +530, /* "setct-CapTokenSeq" */ +574, /* "setct-CapTokenTBE" */ +575, /* "setct-CapTokenTBEX" */ +539, /* "setct-CapTokenTBS" */ +560, /* "setct-CardCInitResTBS" */ +566, /* "setct-CertInqReqTBS" */ +563, /* "setct-CertReqData" */ +595, /* "setct-CertReqTBE" */ +596, /* "setct-CertReqTBEX" */ +564, /* "setct-CertReqTBS" */ +565, /* "setct-CertResData" */ +597, /* "setct-CertResTBE" */ +586, /* "setct-CredReqTBE" */ +587, /* "setct-CredReqTBEX" */ +550, /* "setct-CredReqTBS" */ +551, /* "setct-CredReqTBSX" */ +552, /* "setct-CredResData" */ +588, /* "setct-CredResTBE" */ +589, /* "setct-CredRevReqTBE" */ +590, /* "setct-CredRevReqTBEX" */ +553, /* "setct-CredRevReqTBS" */ +554, /* "setct-CredRevReqTBSX" */ +555, /* "setct-CredRevResData" */ +591, /* "setct-CredRevResTBE" */ +567, /* "setct-ErrorTBS" */ +526, /* "setct-HODInput" */ +561, /* "setct-MeAqCInitResTBS" */ +522, /* "setct-OIData" */ +519, /* "setct-PANData" */ +521, /* "setct-PANOnly" */ +520, /* "setct-PANToken" */ +556, /* "setct-PCertReqData" */ +557, /* "setct-PCertResTBS" */ +523, /* "setct-PI" */ +532, /* "setct-PI-TBS" */ +524, /* "setct-PIData" */ +525, /* "setct-PIDataUnsigned" */ +568, /* "setct-PIDualSignedTBE" */ +569, /* "setct-PIUnsignedTBE" */ +531, /* "setct-PInitResData" */ +533, /* "setct-PResData" */ +594, /* "setct-RegFormReqTBE" */ +562, /* "setct-RegFormResTBS" */ +606, /* "setext-cv" */ +601, /* "setext-genCrypt" */ +602, /* "setext-miAuth" */ +604, /* "setext-pinAny" */ +603, /* "setext-pinSecure" */ +605, /* "setext-track2" */ +52, /* "signingTime" */ +454, /* "simpleSecurityObject" */ +496, /* "singleLevelQuality" */ +387, /* "snmpv2" */ +660, /* "street" */ +85, /* "subjectAltName" */ +769, /* "subjectDirectoryAttributes" */ +398, /* "subjectInfoAccess" */ +82, /* "subjectKeyIdentifier" */ +498, /* "subtreeMaximumQuality" */ +497, /* "subtreeMinimumQuality" */ +890, /* "supportedAlgorithms" */ +874, /* "supportedApplicationContext" */ +402, /* "targetInformation" */ +864, /* "telephoneNumber" */ +866, /* "teletexTerminalIdentifier" */ +865, /* "telexNumber" */ +459, /* "textEncodedORAddress" */ +293, /* "textNotice" */ +133, /* "timeStamping" */ +106, /* "title" */ +682, /* "tpBasis" */ +375, /* "trustRoot" */ +436, /* "ucl" */ +888, /* "uniqueMember" */ +55, /* "unstructuredAddress" */ +49, /* "unstructuredName" */ +880, /* "userCertificate" */ +465, /* "userClass" */ +879, /* "userPassword" */ +373, /* "valid" */ +678, /* "wap" */ +679, /* "wap-wsg" */ +735, /* "wap-wsg-idm-ecid-wtls1" */ +743, /* "wap-wsg-idm-ecid-wtls10" */ +744, /* "wap-wsg-idm-ecid-wtls11" */ +745, /* "wap-wsg-idm-ecid-wtls12" */ +736, /* "wap-wsg-idm-ecid-wtls3" */ +737, /* "wap-wsg-idm-ecid-wtls4" */ +738, /* "wap-wsg-idm-ecid-wtls5" */ +739, /* "wap-wsg-idm-ecid-wtls6" */ +740, /* "wap-wsg-idm-ecid-wtls7" */ +741, /* "wap-wsg-idm-ecid-wtls8" */ +742, /* "wap-wsg-idm-ecid-wtls9" */ +804, /* "whirlpool" */ +868, /* "x121Address" */ +503, /* "x500UniqueIdentifier" */ +158, /* "x509Certificate" */ +160, /* "x509Crl" */ +}; + +static const unsigned int ln_objs[NUM_LN]={ +363, /* "AD Time Stamping" */ +405, /* "ANSI X9.62" */ +368, /* "Acceptable OCSP Responses" */ +910, /* "Any Extended Key Usage" */ +664, /* "Any language" */ +177, /* "Authority Information Access" */ +365, /* "Basic OCSP Response" */ +285, /* "Biometric Info" */ +179, /* "CA Issuers" */ +785, /* "CA Repository" */ +954, /* "CT Certificate SCTs" */ +952, /* "CT Precertificate Poison" */ +951, /* "CT Precertificate SCTs" */ +953, /* "CT Precertificate Signer" */ +131, /* "Code Signing" */ +783, /* "Diffie-Hellman based MAC" */ +382, /* "Directory" */ +392, /* "Domain" */ +132, /* "E-mail Protection" */ +389, /* "Enterprises" */ +384, /* "Experimental" */ +372, /* "Extended OCSP Status" */ +172, /* "Extension Request" */ +813, /* "GOST 28147-89" */ +849, /* "GOST 28147-89 Cryptocom ParamSet" */ +815, /* "GOST 28147-89 MAC" */ +851, /* "GOST 34.10-2001 Cryptocom" */ +850, /* "GOST 34.10-94 Cryptocom" */ +811, /* "GOST R 34.10-2001" */ +817, /* "GOST R 34.10-2001 DH" */ +812, /* "GOST R 34.10-94" */ +818, /* "GOST R 34.10-94 DH" */ +809, /* "GOST R 34.11-94" */ +816, /* "GOST R 34.11-94 PRF" */ +807, /* "GOST R 34.11-94 with GOST R 34.10-2001" */ +853, /* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */ +808, /* "GOST R 34.11-94 with GOST R 34.10-94" */ +852, /* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */ +854, /* "GOST R 3410-2001 Parameter Set Cryptocom" */ +810, /* "HMAC GOST 34.11-94" */ +432, /* "Hold Instruction Call Issuer" */ +430, /* "Hold Instruction Code" */ +431, /* "Hold Instruction None" */ +433, /* "Hold Instruction Reject" */ +634, /* "ICC or token signature" */ +294, /* "IPSec End System" */ +295, /* "IPSec Tunnel" */ +296, /* "IPSec User" */ +182, /* "ISO Member Body" */ +183, /* "ISO US Member Body" */ +667, /* "Independent" */ +665, /* "Inherit all" */ +647, /* "International Organizations" */ +142, /* "Invalidity Date" */ +504, /* "MIME MHS" */ +388, /* "Mail" */ +383, /* "Management" */ +417, /* "Microsoft CSP Name" */ +135, /* "Microsoft Commercial Code Signing" */ +138, /* "Microsoft Encrypted File System" */ +171, /* "Microsoft Extension Request" */ +134, /* "Microsoft Individual Code Signing" */ +856, /* "Microsoft Local Key set" */ +137, /* "Microsoft Server Gated Crypto" */ +648, /* "Microsoft Smartcardlogin" */ +136, /* "Microsoft Trust List Signing" */ +649, /* "Microsoft Universal Principal Name" */ +393, /* "NULL" */ +404, /* "NULL" */ +72, /* "Netscape Base Url" */ +76, /* "Netscape CA Policy Url" */ +74, /* "Netscape CA Revocation Url" */ +71, /* "Netscape Cert Type" */ +58, /* "Netscape Certificate Extension" */ +79, /* "Netscape Certificate Sequence" */ +78, /* "Netscape Comment" */ +57, /* "Netscape Communications Corp." */ +59, /* "Netscape Data Type" */ +75, /* "Netscape Renewal Url" */ +73, /* "Netscape Revocation Url" */ +77, /* "Netscape SSL Server Name" */ +139, /* "Netscape Server Gated Crypto" */ +178, /* "OCSP" */ +370, /* "OCSP Archive Cutoff" */ +367, /* "OCSP CRL ID" */ +369, /* "OCSP No Check" */ +366, /* "OCSP Nonce" */ +371, /* "OCSP Service Locator" */ +180, /* "OCSP Signing" */ +161, /* "PBES2" */ +69, /* "PBKDF2" */ +162, /* "PBMAC1" */ +127, /* "PKIX" */ +858, /* "Permanent Identifier" */ +164, /* "Policy Qualifier CPS" */ +165, /* "Policy Qualifier User Notice" */ +385, /* "Private" */ +663, /* "Proxy Certificate Information" */ + 1, /* "RSA Data Security, Inc." */ + 2, /* "RSA Data Security, Inc. PKCS" */ +188, /* "S/MIME" */ +167, /* "S/MIME Capabilities" */ +387, /* "SNMPv2" */ +512, /* "Secure Electronic Transactions" */ +386, /* "Security" */ +394, /* "Selected Attribute Types" */ +143, /* "Strong Extranet ID" */ +398, /* "Subject Information Access" */ +130, /* "TLS Web Client Authentication" */ +129, /* "TLS Web Server Authentication" */ +133, /* "Time Stamping" */ +375, /* "Trust Root" */ +12, /* "X509" */ +402, /* "X509v3 AC Targeting" */ +746, /* "X509v3 Any Policy" */ +90, /* "X509v3 Authority Key Identifier" */ +87, /* "X509v3 Basic Constraints" */ +103, /* "X509v3 CRL Distribution Points" */ +88, /* "X509v3 CRL Number" */ +141, /* "X509v3 CRL Reason Code" */ +771, /* "X509v3 Certificate Issuer" */ +89, /* "X509v3 Certificate Policies" */ +140, /* "X509v3 Delta CRL Indicator" */ +126, /* "X509v3 Extended Key Usage" */ +857, /* "X509v3 Freshest CRL" */ +748, /* "X509v3 Inhibit Any Policy" */ +86, /* "X509v3 Issuer Alternative Name" */ +770, /* "X509v3 Issuing Distrubution Point" */ +83, /* "X509v3 Key Usage" */ +666, /* "X509v3 Name Constraints" */ +403, /* "X509v3 No Revocation Available" */ +401, /* "X509v3 Policy Constraints" */ +747, /* "X509v3 Policy Mappings" */ +84, /* "X509v3 Private Key Usage Period" */ +85, /* "X509v3 Subject Alternative Name" */ +769, /* "X509v3 Subject Directory Attributes" */ +82, /* "X509v3 Subject Key Identifier" */ +920, /* "X9.42 DH" */ +184, /* "X9.57" */ +185, /* "X9.57 CM ?" */ +478, /* "aRecord" */ +289, /* "aaControls" */ +287, /* "ac-auditEntity" */ +397, /* "ac-proxying" */ +288, /* "ac-targeting" */ +446, /* "account" */ +364, /* "ad dvcs" */ +606, /* "additional verification" */ +419, /* "aes-128-cbc" */ +916, /* "aes-128-cbc-hmac-sha1" */ +948, /* "aes-128-cbc-hmac-sha256" */ +896, /* "aes-128-ccm" */ +421, /* "aes-128-cfb" */ +650, /* "aes-128-cfb1" */ +653, /* "aes-128-cfb8" */ +904, /* "aes-128-ctr" */ +418, /* "aes-128-ecb" */ +895, /* "aes-128-gcm" */ +420, /* "aes-128-ofb" */ +913, /* "aes-128-xts" */ +423, /* "aes-192-cbc" */ +917, /* "aes-192-cbc-hmac-sha1" */ +949, /* "aes-192-cbc-hmac-sha256" */ +899, /* "aes-192-ccm" */ +425, /* "aes-192-cfb" */ +651, /* "aes-192-cfb1" */ +654, /* "aes-192-cfb8" */ +905, /* "aes-192-ctr" */ +422, /* "aes-192-ecb" */ +898, /* "aes-192-gcm" */ +424, /* "aes-192-ofb" */ +427, /* "aes-256-cbc" */ +918, /* "aes-256-cbc-hmac-sha1" */ +950, /* "aes-256-cbc-hmac-sha256" */ +902, /* "aes-256-ccm" */ +429, /* "aes-256-cfb" */ +652, /* "aes-256-cfb1" */ +655, /* "aes-256-cfb8" */ +906, /* "aes-256-ctr" */ +426, /* "aes-256-ecb" */ +901, /* "aes-256-gcm" */ +428, /* "aes-256-ofb" */ +914, /* "aes-256-xts" */ +376, /* "algorithm" */ +484, /* "associatedDomain" */ +485, /* "associatedName" */ +501, /* "audio" */ +882, /* "authorityRevocationList" */ +91, /* "bf-cbc" */ +93, /* "bf-cfb" */ +92, /* "bf-ecb" */ +94, /* "bf-ofb" */ +921, /* "brainpoolP160r1" */ +922, /* "brainpoolP160t1" */ +923, /* "brainpoolP192r1" */ +924, /* "brainpoolP192t1" */ +925, /* "brainpoolP224r1" */ +926, /* "brainpoolP224t1" */ +927, /* "brainpoolP256r1" */ +928, /* "brainpoolP256t1" */ +929, /* "brainpoolP320r1" */ +930, /* "brainpoolP320t1" */ +931, /* "brainpoolP384r1" */ +932, /* "brainpoolP384t1" */ +933, /* "brainpoolP512r1" */ +934, /* "brainpoolP512t1" */ +494, /* "buildingName" */ +860, /* "businessCategory" */ +691, /* "c2onb191v4" */ +692, /* "c2onb191v5" */ +697, /* "c2onb239v4" */ +698, /* "c2onb239v5" */ +684, /* "c2pnb163v1" */ +685, /* "c2pnb163v2" */ +686, /* "c2pnb163v3" */ +687, /* "c2pnb176v1" */ +693, /* "c2pnb208w1" */ +699, /* "c2pnb272w1" */ +700, /* "c2pnb304w1" */ +702, /* "c2pnb368w1" */ +688, /* "c2tnb191v1" */ +689, /* "c2tnb191v2" */ +690, /* "c2tnb191v3" */ +694, /* "c2tnb239v1" */ +695, /* "c2tnb239v2" */ +696, /* "c2tnb239v3" */ +701, /* "c2tnb359v1" */ +703, /* "c2tnb431r1" */ +881, /* "cACertificate" */ +483, /* "cNAMERecord" */ +751, /* "camellia-128-cbc" */ +757, /* "camellia-128-cfb" */ +760, /* "camellia-128-cfb1" */ +763, /* "camellia-128-cfb8" */ +754, /* "camellia-128-ecb" */ +766, /* "camellia-128-ofb" */ +752, /* "camellia-192-cbc" */ +758, /* "camellia-192-cfb" */ +761, /* "camellia-192-cfb1" */ +764, /* "camellia-192-cfb8" */ +755, /* "camellia-192-ecb" */ +767, /* "camellia-192-ofb" */ +753, /* "camellia-256-cbc" */ +759, /* "camellia-256-cfb" */ +762, /* "camellia-256-cfb1" */ +765, /* "camellia-256-cfb8" */ +756, /* "camellia-256-ecb" */ +768, /* "camellia-256-ofb" */ +443, /* "caseIgnoreIA5StringSyntax" */ +108, /* "cast5-cbc" */ +110, /* "cast5-cfb" */ +109, /* "cast5-ecb" */ +111, /* "cast5-ofb" */ +152, /* "certBag" */ +677, /* "certicom-arc" */ +517, /* "certificate extensions" */ +883, /* "certificateRevocationList" */ +54, /* "challengePassword" */ +407, /* "characteristic-two-field" */ +395, /* "clearance" */ +633, /* "cleartext track 2" */ +894, /* "cmac" */ +13, /* "commonName" */ +513, /* "content types" */ +50, /* "contentType" */ +53, /* "countersignature" */ +14, /* "countryName" */ +153, /* "crlBag" */ +884, /* "crossCertificatePair" */ +806, /* "cryptocom" */ +805, /* "cryptopro" */ +500, /* "dITRedirect" */ +451, /* "dNSDomain" */ +495, /* "dSAQuality" */ +434, /* "data" */ +390, /* "dcObject" */ +891, /* "deltaRevocationList" */ +31, /* "des-cbc" */ +643, /* "des-cdmf" */ +30, /* "des-cfb" */ +656, /* "des-cfb1" */ +657, /* "des-cfb8" */ +29, /* "des-ecb" */ +32, /* "des-ede" */ +43, /* "des-ede-cbc" */ +60, /* "des-ede-cfb" */ +62, /* "des-ede-ofb" */ +33, /* "des-ede3" */ +44, /* "des-ede3-cbc" */ +61, /* "des-ede3-cfb" */ +658, /* "des-ede3-cfb1" */ +659, /* "des-ede3-cfb8" */ +63, /* "des-ede3-ofb" */ +45, /* "des-ofb" */ +107, /* "description" */ +871, /* "destinationIndicator" */ +80, /* "desx-cbc" */ +947, /* "dh-cofactor-kdf" */ +946, /* "dh-std-kdf" */ +28, /* "dhKeyAgreement" */ +941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */ +942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */ +943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */ +944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */ +945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */ +936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */ +937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */ +938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */ +939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */ +940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */ +11, /* "directory services (X.500)" */ +378, /* "directory services - algorithms" */ +887, /* "distinguishedName" */ +892, /* "dmdName" */ +174, /* "dnQualifier" */ +447, /* "document" */ +471, /* "documentAuthor" */ +468, /* "documentIdentifier" */ +472, /* "documentLocation" */ +502, /* "documentPublisher" */ +449, /* "documentSeries" */ +469, /* "documentTitle" */ +470, /* "documentVersion" */ +380, /* "dod" */ +391, /* "domainComponent" */ +452, /* "domainRelatedObject" */ +116, /* "dsaEncryption" */ +67, /* "dsaEncryption-old" */ +66, /* "dsaWithSHA" */ +113, /* "dsaWithSHA1" */ +70, /* "dsaWithSHA1-old" */ +802, /* "dsa_with_SHA224" */ +803, /* "dsa_with_SHA256" */ +297, /* "dvcs" */ +791, /* "ecdsa-with-Recommended" */ +416, /* "ecdsa-with-SHA1" */ +793, /* "ecdsa-with-SHA224" */ +794, /* "ecdsa-with-SHA256" */ +795, /* "ecdsa-with-SHA384" */ +796, /* "ecdsa-with-SHA512" */ +792, /* "ecdsa-with-Specified" */ +48, /* "emailAddress" */ +632, /* "encrypted track 2" */ +885, /* "enhancedSearchGuide" */ +56, /* "extendedCertificateAttributes" */ +867, /* "facsimileTelephoneNumber" */ +462, /* "favouriteDrink" */ +453, /* "friendlyCountry" */ +490, /* "friendlyCountryName" */ +156, /* "friendlyName" */ +631, /* "generate cryptogram" */ +509, /* "generationQualifier" */ +601, /* "generic cryptogram" */ +99, /* "givenName" */ +814, /* "gost89-cnt" */ +855, /* "hmac" */ +780, /* "hmac-md5" */ +781, /* "hmac-sha1" */ +797, /* "hmacWithMD5" */ +163, /* "hmacWithSHA1" */ +798, /* "hmacWithSHA224" */ +799, /* "hmacWithSHA256" */ +800, /* "hmacWithSHA384" */ +801, /* "hmacWithSHA512" */ +486, /* "homePostalAddress" */ +473, /* "homeTelephoneNumber" */ +466, /* "host" */ +889, /* "houseIdentifier" */ +442, /* "iA5StringSyntax" */ +381, /* "iana" */ +824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ +825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ +826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ +827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ +819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ +829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ +828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ +830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ +820, /* "id-Gost28147-89-None-KeyMeshing" */ +823, /* "id-Gost28147-89-TestParamSet" */ +840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ +841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ +842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ +843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ +844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ +839, /* "id-GostR3410-2001-TestParamSet" */ +832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ +833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ +834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ +835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ +836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ +837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ +838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ +831, /* "id-GostR3410-94-TestParamSet" */ +845, /* "id-GostR3410-94-a" */ +846, /* "id-GostR3410-94-aBis" */ +847, /* "id-GostR3410-94-b" */ +848, /* "id-GostR3410-94-bBis" */ +822, /* "id-GostR3411-94-CryptoProParamSet" */ +821, /* "id-GostR3411-94-TestParamSet" */ +266, /* "id-aca" */ +355, /* "id-aca-accessIdentity" */ +354, /* "id-aca-authenticationInfo" */ +356, /* "id-aca-chargingIdentity" */ +399, /* "id-aca-encAttrs" */ +357, /* "id-aca-group" */ +358, /* "id-aca-role" */ +176, /* "id-ad" */ +788, /* "id-aes128-wrap" */ +897, /* "id-aes128-wrap-pad" */ +789, /* "id-aes192-wrap" */ +900, /* "id-aes192-wrap-pad" */ +790, /* "id-aes256-wrap" */ +903, /* "id-aes256-wrap-pad" */ +262, /* "id-alg" */ +893, /* "id-alg-PWRI-KEK" */ +323, /* "id-alg-des40" */ +326, /* "id-alg-dh-pop" */ +325, /* "id-alg-dh-sig-hmac-sha1" */ +324, /* "id-alg-noSignature" */ +907, /* "id-camellia128-wrap" */ +908, /* "id-camellia192-wrap" */ +909, /* "id-camellia256-wrap" */ +268, /* "id-cct" */ +361, /* "id-cct-PKIData" */ +362, /* "id-cct-PKIResponse" */ +360, /* "id-cct-crs" */ +81, /* "id-ce" */ +680, /* "id-characteristic-two-basis" */ +263, /* "id-cmc" */ +334, /* "id-cmc-addExtensions" */ +346, /* "id-cmc-confirmCertAcceptance" */ +330, /* "id-cmc-dataReturn" */ +336, /* "id-cmc-decryptedPOP" */ +335, /* "id-cmc-encryptedPOP" */ +339, /* "id-cmc-getCRL" */ +338, /* "id-cmc-getCert" */ +328, /* "id-cmc-identification" */ +329, /* "id-cmc-identityProof" */ +337, /* "id-cmc-lraPOPWitness" */ +344, /* "id-cmc-popLinkRandom" */ +345, /* "id-cmc-popLinkWitness" */ +343, /* "id-cmc-queryPending" */ +333, /* "id-cmc-recipientNonce" */ +341, /* "id-cmc-regInfo" */ +342, /* "id-cmc-responseInfo" */ +340, /* "id-cmc-revokeRequest" */ +332, /* "id-cmc-senderNonce" */ +327, /* "id-cmc-statusInfo" */ +331, /* "id-cmc-transactionId" */ +787, /* "id-ct-asciiTextWithCRLF" */ +408, /* "id-ecPublicKey" */ +508, /* "id-hex-multipart-message" */ +507, /* "id-hex-partial-message" */ +260, /* "id-it" */ +302, /* "id-it-caKeyUpdateInfo" */ +298, /* "id-it-caProtEncCert" */ +311, /* "id-it-confirmWaitTime" */ +303, /* "id-it-currentCRL" */ +300, /* "id-it-encKeyPairTypes" */ +310, /* "id-it-implicitConfirm" */ +308, /* "id-it-keyPairParamRep" */ +307, /* "id-it-keyPairParamReq" */ +312, /* "id-it-origPKIMessage" */ +301, /* "id-it-preferredSymmAlg" */ +309, /* "id-it-revPassphrase" */ +299, /* "id-it-signKeyPairTypes" */ +305, /* "id-it-subscriptionRequest" */ +306, /* "id-it-subscriptionResponse" */ +784, /* "id-it-suppLangTags" */ +304, /* "id-it-unsupportedOIDs" */ +128, /* "id-kp" */ +280, /* "id-mod-attribute-cert" */ +274, /* "id-mod-cmc" */ +277, /* "id-mod-cmp" */ +284, /* "id-mod-cmp2000" */ +273, /* "id-mod-crmf" */ +283, /* "id-mod-dvcs" */ +275, /* "id-mod-kea-profile-88" */ +276, /* "id-mod-kea-profile-93" */ +282, /* "id-mod-ocsp" */ +278, /* "id-mod-qualified-cert-88" */ +279, /* "id-mod-qualified-cert-93" */ +281, /* "id-mod-timestamp-protocol" */ +264, /* "id-on" */ +347, /* "id-on-personalData" */ +265, /* "id-pda" */ +352, /* "id-pda-countryOfCitizenship" */ +353, /* "id-pda-countryOfResidence" */ +348, /* "id-pda-dateOfBirth" */ +351, /* "id-pda-gender" */ +349, /* "id-pda-placeOfBirth" */ +175, /* "id-pe" */ +261, /* "id-pkip" */ +258, /* "id-pkix-mod" */ +269, /* "id-pkix1-explicit-88" */ +271, /* "id-pkix1-explicit-93" */ +270, /* "id-pkix1-implicit-88" */ +272, /* "id-pkix1-implicit-93" */ +662, /* "id-ppl" */ +267, /* "id-qcs" */ +359, /* "id-qcs-pkixQCSyntax-v1" */ +259, /* "id-qt" */ +313, /* "id-regCtrl" */ +316, /* "id-regCtrl-authenticator" */ +319, /* "id-regCtrl-oldCertID" */ +318, /* "id-regCtrl-pkiArchiveOptions" */ +317, /* "id-regCtrl-pkiPublicationInfo" */ +320, /* "id-regCtrl-protocolEncrKey" */ +315, /* "id-regCtrl-regToken" */ +314, /* "id-regInfo" */ +322, /* "id-regInfo-certReq" */ +321, /* "id-regInfo-utf8Pairs" */ +191, /* "id-smime-aa" */ +215, /* "id-smime-aa-contentHint" */ +218, /* "id-smime-aa-contentIdentifier" */ +221, /* "id-smime-aa-contentReference" */ +240, /* "id-smime-aa-dvcs-dvc" */ +217, /* "id-smime-aa-encapContentType" */ +222, /* "id-smime-aa-encrypKeyPref" */ +220, /* "id-smime-aa-equivalentLabels" */ +232, /* "id-smime-aa-ets-CertificateRefs" */ +233, /* "id-smime-aa-ets-RevocationRefs" */ +238, /* "id-smime-aa-ets-archiveTimeStamp" */ +237, /* "id-smime-aa-ets-certCRLTimestamp" */ +234, /* "id-smime-aa-ets-certValues" */ +227, /* "id-smime-aa-ets-commitmentType" */ +231, /* "id-smime-aa-ets-contentTimestamp" */ +236, /* "id-smime-aa-ets-escTimeStamp" */ +230, /* "id-smime-aa-ets-otherSigCert" */ +235, /* "id-smime-aa-ets-revocationValues" */ +226, /* "id-smime-aa-ets-sigPolicyId" */ +229, /* "id-smime-aa-ets-signerAttr" */ +228, /* "id-smime-aa-ets-signerLocation" */ +219, /* "id-smime-aa-macValue" */ +214, /* "id-smime-aa-mlExpandHistory" */ +216, /* "id-smime-aa-msgSigDigest" */ +212, /* "id-smime-aa-receiptRequest" */ +213, /* "id-smime-aa-securityLabel" */ +239, /* "id-smime-aa-signatureType" */ +223, /* "id-smime-aa-signingCertificate" */ +224, /* "id-smime-aa-smimeEncryptCerts" */ +225, /* "id-smime-aa-timeStampToken" */ +192, /* "id-smime-alg" */ +243, /* "id-smime-alg-3DESwrap" */ +246, /* "id-smime-alg-CMS3DESwrap" */ +247, /* "id-smime-alg-CMSRC2wrap" */ +245, /* "id-smime-alg-ESDH" */ +241, /* "id-smime-alg-ESDHwith3DES" */ +242, /* "id-smime-alg-ESDHwithRC2" */ +244, /* "id-smime-alg-RC2wrap" */ +193, /* "id-smime-cd" */ +248, /* "id-smime-cd-ldap" */ +190, /* "id-smime-ct" */ +210, /* "id-smime-ct-DVCSRequestData" */ +211, /* "id-smime-ct-DVCSResponseData" */ +208, /* "id-smime-ct-TDTInfo" */ +207, /* "id-smime-ct-TSTInfo" */ +205, /* "id-smime-ct-authData" */ +786, /* "id-smime-ct-compressedData" */ +209, /* "id-smime-ct-contentInfo" */ +206, /* "id-smime-ct-publishCert" */ +204, /* "id-smime-ct-receipt" */ +195, /* "id-smime-cti" */ +255, /* "id-smime-cti-ets-proofOfApproval" */ +256, /* "id-smime-cti-ets-proofOfCreation" */ +253, /* "id-smime-cti-ets-proofOfDelivery" */ +251, /* "id-smime-cti-ets-proofOfOrigin" */ +252, /* "id-smime-cti-ets-proofOfReceipt" */ +254, /* "id-smime-cti-ets-proofOfSender" */ +189, /* "id-smime-mod" */ +196, /* "id-smime-mod-cms" */ +197, /* "id-smime-mod-ess" */ +202, /* "id-smime-mod-ets-eSigPolicy-88" */ +203, /* "id-smime-mod-ets-eSigPolicy-97" */ +200, /* "id-smime-mod-ets-eSignature-88" */ +201, /* "id-smime-mod-ets-eSignature-97" */ +199, /* "id-smime-mod-msg-v3" */ +198, /* "id-smime-mod-oid" */ +194, /* "id-smime-spq" */ +250, /* "id-smime-spq-ets-sqt-unotice" */ +249, /* "id-smime-spq-ets-sqt-uri" */ +34, /* "idea-cbc" */ +35, /* "idea-cfb" */ +36, /* "idea-ecb" */ +46, /* "idea-ofb" */ +676, /* "identified-organization" */ +461, /* "info" */ +101, /* "initials" */ +869, /* "internationaliSDNNumber" */ +749, /* "ipsec3" */ +750, /* "ipsec4" */ +181, /* "iso" */ +623, /* "issuer capabilities" */ +645, /* "itu-t" */ +492, /* "janetMailbox" */ +646, /* "joint-iso-itu-t" */ +957, /* "jurisdictionCountryName" */ +955, /* "jurisdictionLocalityName" */ +956, /* "jurisdictionStateOrProvinceName" */ +150, /* "keyBag" */ +773, /* "kisa" */ +477, /* "lastModifiedBy" */ +476, /* "lastModifiedTime" */ +157, /* "localKeyID" */ +15, /* "localityName" */ +480, /* "mXRecord" */ +493, /* "mailPreferenceOption" */ +467, /* "manager" */ + 3, /* "md2" */ + 7, /* "md2WithRSAEncryption" */ +257, /* "md4" */ +396, /* "md4WithRSAEncryption" */ + 4, /* "md5" */ +114, /* "md5-sha1" */ +104, /* "md5WithRSA" */ + 8, /* "md5WithRSAEncryption" */ +95, /* "mdc2" */ +96, /* "mdc2WithRSA" */ +875, /* "member" */ +602, /* "merchant initiated auth" */ +514, /* "message extensions" */ +51, /* "messageDigest" */ +911, /* "mgf1" */ +506, /* "mime-mhs-bodies" */ +505, /* "mime-mhs-headings" */ +488, /* "mobileTelephoneNumber" */ +481, /* "nSRecord" */ +173, /* "name" */ +681, /* "onBasis" */ +379, /* "org" */ +17, /* "organizationName" */ +491, /* "organizationalStatus" */ +18, /* "organizationalUnitName" */ +475, /* "otherMailbox" */ +876, /* "owner" */ +935, /* "pSpecified" */ +489, /* "pagerTelephoneNumber" */ +782, /* "password based MAC" */ +374, /* "path" */ +621, /* "payment gateway capabilities" */ + 9, /* "pbeWithMD2AndDES-CBC" */ +168, /* "pbeWithMD2AndRC2-CBC" */ +112, /* "pbeWithMD5AndCast5CBC" */ +10, /* "pbeWithMD5AndDES-CBC" */ +169, /* "pbeWithMD5AndRC2-CBC" */ +148, /* "pbeWithSHA1And128BitRC2-CBC" */ +144, /* "pbeWithSHA1And128BitRC4" */ +147, /* "pbeWithSHA1And2-KeyTripleDES-CBC" */ +146, /* "pbeWithSHA1And3-KeyTripleDES-CBC" */ +149, /* "pbeWithSHA1And40BitRC2-CBC" */ +145, /* "pbeWithSHA1And40BitRC4" */ +170, /* "pbeWithSHA1AndDES-CBC" */ +68, /* "pbeWithSHA1AndRC2-CBC" */ +499, /* "personalSignature" */ +487, /* "personalTitle" */ +464, /* "photo" */ +863, /* "physicalDeliveryOfficeName" */ +437, /* "pilot" */ +439, /* "pilotAttributeSyntax" */ +438, /* "pilotAttributeType" */ +479, /* "pilotAttributeType27" */ +456, /* "pilotDSA" */ +441, /* "pilotGroups" */ +444, /* "pilotObject" */ +440, /* "pilotObjectClass" */ +455, /* "pilotOrganization" */ +445, /* "pilotPerson" */ +186, /* "pkcs1" */ +27, /* "pkcs3" */ +187, /* "pkcs5" */ +20, /* "pkcs7" */ +21, /* "pkcs7-data" */ +25, /* "pkcs7-digestData" */ +26, /* "pkcs7-encryptedData" */ +23, /* "pkcs7-envelopedData" */ +24, /* "pkcs7-signedAndEnvelopedData" */ +22, /* "pkcs7-signedData" */ +151, /* "pkcs8ShroudedKeyBag" */ +47, /* "pkcs9" */ +862, /* "postOfficeBox" */ +861, /* "postalAddress" */ +661, /* "postalCode" */ +683, /* "ppBasis" */ +872, /* "preferredDeliveryMethod" */ +873, /* "presentationAddress" */ +406, /* "prime-field" */ +409, /* "prime192v1" */ +410, /* "prime192v2" */ +411, /* "prime192v3" */ +412, /* "prime239v1" */ +413, /* "prime239v2" */ +414, /* "prime239v3" */ +415, /* "prime256v1" */ +886, /* "protocolInformation" */ +510, /* "pseudonym" */ +435, /* "pss" */ +286, /* "qcStatements" */ +457, /* "qualityLabelledData" */ +450, /* "rFC822localPart" */ +98, /* "rc2-40-cbc" */ +166, /* "rc2-64-cbc" */ +37, /* "rc2-cbc" */ +39, /* "rc2-cfb" */ +38, /* "rc2-ecb" */ +40, /* "rc2-ofb" */ + 5, /* "rc4" */ +97, /* "rc4-40" */ +915, /* "rc4-hmac-md5" */ +120, /* "rc5-cbc" */ +122, /* "rc5-cfb" */ +121, /* "rc5-ecb" */ +123, /* "rc5-ofb" */ +870, /* "registeredAddress" */ +460, /* "rfc822Mailbox" */ +117, /* "ripemd160" */ +119, /* "ripemd160WithRSA" */ +400, /* "role" */ +877, /* "roleOccupant" */ +448, /* "room" */ +463, /* "roomNumber" */ +19, /* "rsa" */ + 6, /* "rsaEncryption" */ +644, /* "rsaOAEPEncryptionSET" */ +377, /* "rsaSignature" */ +919, /* "rsaesOaep" */ +912, /* "rsassaPss" */ +124, /* "run length compression" */ +482, /* "sOARecord" */ +155, /* "safeContentsBag" */ +291, /* "sbgp-autonomousSysNum" */ +290, /* "sbgp-ipAddrBlock" */ +292, /* "sbgp-routerIdentifier" */ +159, /* "sdsiCertificate" */ +859, /* "searchGuide" */ +704, /* "secp112r1" */ +705, /* "secp112r2" */ +706, /* "secp128r1" */ +707, /* "secp128r2" */ +708, /* "secp160k1" */ +709, /* "secp160r1" */ +710, /* "secp160r2" */ +711, /* "secp192k1" */ +712, /* "secp224k1" */ +713, /* "secp224r1" */ +714, /* "secp256k1" */ +715, /* "secp384r1" */ +716, /* "secp521r1" */ +154, /* "secretBag" */ +474, /* "secretary" */ +717, /* "sect113r1" */ +718, /* "sect113r2" */ +719, /* "sect131r1" */ +720, /* "sect131r2" */ +721, /* "sect163k1" */ +722, /* "sect163r1" */ +723, /* "sect163r2" */ +724, /* "sect193r1" */ +725, /* "sect193r2" */ +726, /* "sect233k1" */ +727, /* "sect233r1" */ +728, /* "sect239k1" */ +729, /* "sect283k1" */ +730, /* "sect283r1" */ +731, /* "sect409k1" */ +732, /* "sect409r1" */ +733, /* "sect571k1" */ +734, /* "sect571r1" */ +635, /* "secure device signature" */ +878, /* "seeAlso" */ +777, /* "seed-cbc" */ +779, /* "seed-cfb" */ +776, /* "seed-ecb" */ +778, /* "seed-ofb" */ +105, /* "serialNumber" */ +625, /* "set-addPolicy" */ +515, /* "set-attr" */ +518, /* "set-brand" */ +638, /* "set-brand-AmericanExpress" */ +637, /* "set-brand-Diners" */ +636, /* "set-brand-IATA-ATA" */ +639, /* "set-brand-JCB" */ +641, /* "set-brand-MasterCard" */ +642, /* "set-brand-Novus" */ +640, /* "set-brand-Visa" */ +516, /* "set-policy" */ +607, /* "set-policy-root" */ +624, /* "set-rootKeyThumb" */ +620, /* "setAttr-Cert" */ +628, /* "setAttr-IssCap-CVM" */ +630, /* "setAttr-IssCap-Sig" */ +629, /* "setAttr-IssCap-T2" */ +627, /* "setAttr-Token-B0Prime" */ +626, /* "setAttr-Token-EMV" */ +622, /* "setAttr-TokenType" */ +619, /* "setCext-IssuerCapabilities" */ +615, /* "setCext-PGWYcapabilities" */ +616, /* "setCext-TokenIdentifier" */ +618, /* "setCext-TokenType" */ +617, /* "setCext-Track2Data" */ +611, /* "setCext-cCertRequired" */ +609, /* "setCext-certType" */ +608, /* "setCext-hashedRoot" */ +610, /* "setCext-merchData" */ +613, /* "setCext-setExt" */ +614, /* "setCext-setQualf" */ +612, /* "setCext-tunneling" */ +540, /* "setct-AcqCardCodeMsg" */ +576, /* "setct-AcqCardCodeMsgTBE" */ +570, /* "setct-AuthReqTBE" */ +534, /* "setct-AuthReqTBS" */ +527, /* "setct-AuthResBaggage" */ +571, /* "setct-AuthResTBE" */ +572, /* "setct-AuthResTBEX" */ +535, /* "setct-AuthResTBS" */ +536, /* "setct-AuthResTBSX" */ +528, /* "setct-AuthRevReqBaggage" */ +577, /* "setct-AuthRevReqTBE" */ +541, /* "setct-AuthRevReqTBS" */ +529, /* "setct-AuthRevResBaggage" */ +542, /* "setct-AuthRevResData" */ +578, /* "setct-AuthRevResTBE" */ +579, /* "setct-AuthRevResTBEB" */ +543, /* "setct-AuthRevResTBS" */ +573, /* "setct-AuthTokenTBE" */ +537, /* "setct-AuthTokenTBS" */ +600, /* "setct-BCIDistributionTBS" */ +558, /* "setct-BatchAdminReqData" */ +592, /* "setct-BatchAdminReqTBE" */ +559, /* "setct-BatchAdminResData" */ +593, /* "setct-BatchAdminResTBE" */ +599, /* "setct-CRLNotificationResTBS" */ +598, /* "setct-CRLNotificationTBS" */ +580, /* "setct-CapReqTBE" */ +581, /* "setct-CapReqTBEX" */ +544, /* "setct-CapReqTBS" */ +545, /* "setct-CapReqTBSX" */ +546, /* "setct-CapResData" */ +582, /* "setct-CapResTBE" */ +583, /* "setct-CapRevReqTBE" */ +584, /* "setct-CapRevReqTBEX" */ +547, /* "setct-CapRevReqTBS" */ +548, /* "setct-CapRevReqTBSX" */ +549, /* "setct-CapRevResData" */ +585, /* "setct-CapRevResTBE" */ +538, /* "setct-CapTokenData" */ +530, /* "setct-CapTokenSeq" */ +574, /* "setct-CapTokenTBE" */ +575, /* "setct-CapTokenTBEX" */ +539, /* "setct-CapTokenTBS" */ +560, /* "setct-CardCInitResTBS" */ +566, /* "setct-CertInqReqTBS" */ +563, /* "setct-CertReqData" */ +595, /* "setct-CertReqTBE" */ +596, /* "setct-CertReqTBEX" */ +564, /* "setct-CertReqTBS" */ +565, /* "setct-CertResData" */ +597, /* "setct-CertResTBE" */ +586, /* "setct-CredReqTBE" */ +587, /* "setct-CredReqTBEX" */ +550, /* "setct-CredReqTBS" */ +551, /* "setct-CredReqTBSX" */ +552, /* "setct-CredResData" */ +588, /* "setct-CredResTBE" */ +589, /* "setct-CredRevReqTBE" */ +590, /* "setct-CredRevReqTBEX" */ +553, /* "setct-CredRevReqTBS" */ +554, /* "setct-CredRevReqTBSX" */ +555, /* "setct-CredRevResData" */ +591, /* "setct-CredRevResTBE" */ +567, /* "setct-ErrorTBS" */ +526, /* "setct-HODInput" */ +561, /* "setct-MeAqCInitResTBS" */ +522, /* "setct-OIData" */ +519, /* "setct-PANData" */ +521, /* "setct-PANOnly" */ +520, /* "setct-PANToken" */ +556, /* "setct-PCertReqData" */ +557, /* "setct-PCertResTBS" */ +523, /* "setct-PI" */ +532, /* "setct-PI-TBS" */ +524, /* "setct-PIData" */ +525, /* "setct-PIDataUnsigned" */ +568, /* "setct-PIDualSignedTBE" */ +569, /* "setct-PIUnsignedTBE" */ +531, /* "setct-PInitResData" */ +533, /* "setct-PResData" */ +594, /* "setct-RegFormReqTBE" */ +562, /* "setct-RegFormResTBS" */ +604, /* "setext-pinAny" */ +603, /* "setext-pinSecure" */ +605, /* "setext-track2" */ +41, /* "sha" */ +64, /* "sha1" */ +115, /* "sha1WithRSA" */ +65, /* "sha1WithRSAEncryption" */ +675, /* "sha224" */ +671, /* "sha224WithRSAEncryption" */ +672, /* "sha256" */ +668, /* "sha256WithRSAEncryption" */ +673, /* "sha384" */ +669, /* "sha384WithRSAEncryption" */ +674, /* "sha512" */ +670, /* "sha512WithRSAEncryption" */ +42, /* "shaWithRSAEncryption" */ +52, /* "signingTime" */ +454, /* "simpleSecurityObject" */ +496, /* "singleLevelQuality" */ +16, /* "stateOrProvinceName" */ +660, /* "streetAddress" */ +498, /* "subtreeMaximumQuality" */ +497, /* "subtreeMinimumQuality" */ +890, /* "supportedAlgorithms" */ +874, /* "supportedApplicationContext" */ +100, /* "surname" */ +864, /* "telephoneNumber" */ +866, /* "teletexTerminalIdentifier" */ +865, /* "telexNumber" */ +459, /* "textEncodedORAddress" */ +293, /* "textNotice" */ +106, /* "title" */ +682, /* "tpBasis" */ +436, /* "ucl" */ + 0, /* "undefined" */ +888, /* "uniqueMember" */ +55, /* "unstructuredAddress" */ +49, /* "unstructuredName" */ +880, /* "userCertificate" */ +465, /* "userClass" */ +458, /* "userId" */ +879, /* "userPassword" */ +373, /* "valid" */ +678, /* "wap" */ +679, /* "wap-wsg" */ +735, /* "wap-wsg-idm-ecid-wtls1" */ +743, /* "wap-wsg-idm-ecid-wtls10" */ +744, /* "wap-wsg-idm-ecid-wtls11" */ +745, /* "wap-wsg-idm-ecid-wtls12" */ +736, /* "wap-wsg-idm-ecid-wtls3" */ +737, /* "wap-wsg-idm-ecid-wtls4" */ +738, /* "wap-wsg-idm-ecid-wtls5" */ +739, /* "wap-wsg-idm-ecid-wtls6" */ +740, /* "wap-wsg-idm-ecid-wtls7" */ +741, /* "wap-wsg-idm-ecid-wtls8" */ +742, /* "wap-wsg-idm-ecid-wtls9" */ +804, /* "whirlpool" */ +868, /* "x121Address" */ +503, /* "x500UniqueIdentifier" */ +158, /* "x509Certificate" */ +160, /* "x509Crl" */ +125, /* "zlib compression" */ +}; + +static const unsigned int obj_objs[NUM_OBJ]={ + 0, /* OBJ_undef 0 */ +181, /* OBJ_iso 1 */ +393, /* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */ +404, /* OBJ_ccitt OBJ_itu_t */ +645, /* OBJ_itu_t 0 */ +646, /* OBJ_joint_iso_itu_t 2 */ +434, /* OBJ_data 0 9 */ +182, /* OBJ_member_body 1 2 */ +379, /* OBJ_org 1 3 */ +676, /* OBJ_identified_organization 1 3 */ +11, /* OBJ_X500 2 5 */ +647, /* OBJ_international_organizations 2 23 */ +380, /* OBJ_dod 1 3 6 */ +12, /* OBJ_X509 2 5 4 */ +378, /* OBJ_X500algorithms 2 5 8 */ +81, /* OBJ_id_ce 2 5 29 */ +512, /* OBJ_id_set 2 23 42 */ +678, /* OBJ_wap 2 23 43 */ +435, /* OBJ_pss 0 9 2342 */ +183, /* OBJ_ISO_US 1 2 840 */ +381, /* OBJ_iana 1 3 6 1 */ +677, /* OBJ_certicom_arc 1 3 132 */ +394, /* OBJ_selected_attribute_types 2 5 1 5 */ +13, /* OBJ_commonName 2 5 4 3 */ +100, /* OBJ_surname 2 5 4 4 */ +105, /* OBJ_serialNumber 2 5 4 5 */ +14, /* OBJ_countryName 2 5 4 6 */ +15, /* OBJ_localityName 2 5 4 7 */ +16, /* OBJ_stateOrProvinceName 2 5 4 8 */ +660, /* OBJ_streetAddress 2 5 4 9 */ +17, /* OBJ_organizationName 2 5 4 10 */ +18, /* OBJ_organizationalUnitName 2 5 4 11 */ +106, /* OBJ_title 2 5 4 12 */ +107, /* OBJ_description 2 5 4 13 */ +859, /* OBJ_searchGuide 2 5 4 14 */ +860, /* OBJ_businessCategory 2 5 4 15 */ +861, /* OBJ_postalAddress 2 5 4 16 */ +661, /* OBJ_postalCode 2 5 4 17 */ +862, /* OBJ_postOfficeBox 2 5 4 18 */ +863, /* OBJ_physicalDeliveryOfficeName 2 5 4 19 */ +864, /* OBJ_telephoneNumber 2 5 4 20 */ +865, /* OBJ_telexNumber 2 5 4 21 */ +866, /* OBJ_teletexTerminalIdentifier 2 5 4 22 */ +867, /* OBJ_facsimileTelephoneNumber 2 5 4 23 */ +868, /* OBJ_x121Address 2 5 4 24 */ +869, /* OBJ_internationaliSDNNumber 2 5 4 25 */ +870, /* OBJ_registeredAddress 2 5 4 26 */ +871, /* OBJ_destinationIndicator 2 5 4 27 */ +872, /* OBJ_preferredDeliveryMethod 2 5 4 28 */ +873, /* OBJ_presentationAddress 2 5 4 29 */ +874, /* OBJ_supportedApplicationContext 2 5 4 30 */ +875, /* OBJ_member 2 5 4 31 */ +876, /* OBJ_owner 2 5 4 32 */ +877, /* OBJ_roleOccupant 2 5 4 33 */ +878, /* OBJ_seeAlso 2 5 4 34 */ +879, /* OBJ_userPassword 2 5 4 35 */ +880, /* OBJ_userCertificate 2 5 4 36 */ +881, /* OBJ_cACertificate 2 5 4 37 */ +882, /* OBJ_authorityRevocationList 2 5 4 38 */ +883, /* OBJ_certificateRevocationList 2 5 4 39 */ +884, /* OBJ_crossCertificatePair 2 5 4 40 */ +173, /* OBJ_name 2 5 4 41 */ +99, /* OBJ_givenName 2 5 4 42 */ +101, /* OBJ_initials 2 5 4 43 */ +509, /* OBJ_generationQualifier 2 5 4 44 */ +503, /* OBJ_x500UniqueIdentifier 2 5 4 45 */ +174, /* OBJ_dnQualifier 2 5 4 46 */ +885, /* OBJ_enhancedSearchGuide 2 5 4 47 */ +886, /* OBJ_protocolInformation 2 5 4 48 */ +887, /* OBJ_distinguishedName 2 5 4 49 */ +888, /* OBJ_uniqueMember 2 5 4 50 */ +889, /* OBJ_houseIdentifier 2 5 4 51 */ +890, /* OBJ_supportedAlgorithms 2 5 4 52 */ +891, /* OBJ_deltaRevocationList 2 5 4 53 */ +892, /* OBJ_dmdName 2 5 4 54 */ +510, /* OBJ_pseudonym 2 5 4 65 */ +400, /* OBJ_role 2 5 4 72 */ +769, /* OBJ_subject_directory_attributes 2 5 29 9 */ +82, /* OBJ_subject_key_identifier 2 5 29 14 */ +83, /* OBJ_key_usage 2 5 29 15 */ +84, /* OBJ_private_key_usage_period 2 5 29 16 */ +85, /* OBJ_subject_alt_name 2 5 29 17 */ +86, /* OBJ_issuer_alt_name 2 5 29 18 */ +87, /* OBJ_basic_constraints 2 5 29 19 */ +88, /* OBJ_crl_number 2 5 29 20 */ +141, /* OBJ_crl_reason 2 5 29 21 */ +430, /* OBJ_hold_instruction_code 2 5 29 23 */ +142, /* OBJ_invalidity_date 2 5 29 24 */ +140, /* OBJ_delta_crl 2 5 29 27 */ +770, /* OBJ_issuing_distribution_point 2 5 29 28 */ +771, /* OBJ_certificate_issuer 2 5 29 29 */ +666, /* OBJ_name_constraints 2 5 29 30 */ +103, /* OBJ_crl_distribution_points 2 5 29 31 */ +89, /* OBJ_certificate_policies 2 5 29 32 */ +747, /* OBJ_policy_mappings 2 5 29 33 */ +90, /* OBJ_authority_key_identifier 2 5 29 35 */ +401, /* OBJ_policy_constraints 2 5 29 36 */ +126, /* OBJ_ext_key_usage 2 5 29 37 */ +857, /* OBJ_freshest_crl 2 5 29 46 */ +748, /* OBJ_inhibit_any_policy 2 5 29 54 */ +402, /* OBJ_target_information 2 5 29 55 */ +403, /* OBJ_no_rev_avail 2 5 29 56 */ +513, /* OBJ_set_ctype 2 23 42 0 */ +514, /* OBJ_set_msgExt 2 23 42 1 */ +515, /* OBJ_set_attr 2 23 42 3 */ +516, /* OBJ_set_policy 2 23 42 5 */ +517, /* OBJ_set_certExt 2 23 42 7 */ +518, /* OBJ_set_brand 2 23 42 8 */ +679, /* OBJ_wap_wsg 2 23 43 1 */ +382, /* OBJ_Directory 1 3 6 1 1 */ +383, /* OBJ_Management 1 3 6 1 2 */ +384, /* OBJ_Experimental 1 3 6 1 3 */ +385, /* OBJ_Private 1 3 6 1 4 */ +386, /* OBJ_Security 1 3 6 1 5 */ +387, /* OBJ_SNMPv2 1 3 6 1 6 */ +388, /* OBJ_Mail 1 3 6 1 7 */ +376, /* OBJ_algorithm 1 3 14 3 2 */ +395, /* OBJ_clearance 2 5 1 5 55 */ +19, /* OBJ_rsa 2 5 8 1 1 */ +96, /* OBJ_mdc2WithRSA 2 5 8 3 100 */ +95, /* OBJ_mdc2 2 5 8 3 101 */ +746, /* OBJ_any_policy 2 5 29 32 0 */ +910, /* OBJ_anyExtendedKeyUsage 2 5 29 37 0 */ +519, /* OBJ_setct_PANData 2 23 42 0 0 */ +520, /* OBJ_setct_PANToken 2 23 42 0 1 */ +521, /* OBJ_setct_PANOnly 2 23 42 0 2 */ +522, /* OBJ_setct_OIData 2 23 42 0 3 */ +523, /* OBJ_setct_PI 2 23 42 0 4 */ +524, /* OBJ_setct_PIData 2 23 42 0 5 */ +525, /* OBJ_setct_PIDataUnsigned 2 23 42 0 6 */ +526, /* OBJ_setct_HODInput 2 23 42 0 7 */ +527, /* OBJ_setct_AuthResBaggage 2 23 42 0 8 */ +528, /* OBJ_setct_AuthRevReqBaggage 2 23 42 0 9 */ +529, /* OBJ_setct_AuthRevResBaggage 2 23 42 0 10 */ +530, /* OBJ_setct_CapTokenSeq 2 23 42 0 11 */ +531, /* OBJ_setct_PInitResData 2 23 42 0 12 */ +532, /* OBJ_setct_PI_TBS 2 23 42 0 13 */ +533, /* OBJ_setct_PResData 2 23 42 0 14 */ +534, /* OBJ_setct_AuthReqTBS 2 23 42 0 16 */ +535, /* OBJ_setct_AuthResTBS 2 23 42 0 17 */ +536, /* OBJ_setct_AuthResTBSX 2 23 42 0 18 */ +537, /* OBJ_setct_AuthTokenTBS 2 23 42 0 19 */ +538, /* OBJ_setct_CapTokenData 2 23 42 0 20 */ +539, /* OBJ_setct_CapTokenTBS 2 23 42 0 21 */ +540, /* OBJ_setct_AcqCardCodeMsg 2 23 42 0 22 */ +541, /* OBJ_setct_AuthRevReqTBS 2 23 42 0 23 */ +542, /* OBJ_setct_AuthRevResData 2 23 42 0 24 */ +543, /* OBJ_setct_AuthRevResTBS 2 23 42 0 25 */ +544, /* OBJ_setct_CapReqTBS 2 23 42 0 26 */ +545, /* OBJ_setct_CapReqTBSX 2 23 42 0 27 */ +546, /* OBJ_setct_CapResData 2 23 42 0 28 */ +547, /* OBJ_setct_CapRevReqTBS 2 23 42 0 29 */ +548, /* OBJ_setct_CapRevReqTBSX 2 23 42 0 30 */ +549, /* OBJ_setct_CapRevResData 2 23 42 0 31 */ +550, /* OBJ_setct_CredReqTBS 2 23 42 0 32 */ +551, /* OBJ_setct_CredReqTBSX 2 23 42 0 33 */ +552, /* OBJ_setct_CredResData 2 23 42 0 34 */ +553, /* OBJ_setct_CredRevReqTBS 2 23 42 0 35 */ +554, /* OBJ_setct_CredRevReqTBSX 2 23 42 0 36 */ +555, /* OBJ_setct_CredRevResData 2 23 42 0 37 */ +556, /* OBJ_setct_PCertReqData 2 23 42 0 38 */ +557, /* OBJ_setct_PCertResTBS 2 23 42 0 39 */ +558, /* OBJ_setct_BatchAdminReqData 2 23 42 0 40 */ +559, /* OBJ_setct_BatchAdminResData 2 23 42 0 41 */ +560, /* OBJ_setct_CardCInitResTBS 2 23 42 0 42 */ +561, /* OBJ_setct_MeAqCInitResTBS 2 23 42 0 43 */ +562, /* OBJ_setct_RegFormResTBS 2 23 42 0 44 */ +563, /* OBJ_setct_CertReqData 2 23 42 0 45 */ +564, /* OBJ_setct_CertReqTBS 2 23 42 0 46 */ +565, /* OBJ_setct_CertResData 2 23 42 0 47 */ +566, /* OBJ_setct_CertInqReqTBS 2 23 42 0 48 */ +567, /* OBJ_setct_ErrorTBS 2 23 42 0 49 */ +568, /* OBJ_setct_PIDualSignedTBE 2 23 42 0 50 */ +569, /* OBJ_setct_PIUnsignedTBE 2 23 42 0 51 */ +570, /* OBJ_setct_AuthReqTBE 2 23 42 0 52 */ +571, /* OBJ_setct_AuthResTBE 2 23 42 0 53 */ +572, /* OBJ_setct_AuthResTBEX 2 23 42 0 54 */ +573, /* OBJ_setct_AuthTokenTBE 2 23 42 0 55 */ +574, /* OBJ_setct_CapTokenTBE 2 23 42 0 56 */ +575, /* OBJ_setct_CapTokenTBEX 2 23 42 0 57 */ +576, /* OBJ_setct_AcqCardCodeMsgTBE 2 23 42 0 58 */ +577, /* OBJ_setct_AuthRevReqTBE 2 23 42 0 59 */ +578, /* OBJ_setct_AuthRevResTBE 2 23 42 0 60 */ +579, /* OBJ_setct_AuthRevResTBEB 2 23 42 0 61 */ +580, /* OBJ_setct_CapReqTBE 2 23 42 0 62 */ +581, /* OBJ_setct_CapReqTBEX 2 23 42 0 63 */ +582, /* OBJ_setct_CapResTBE 2 23 42 0 64 */ +583, /* OBJ_setct_CapRevReqTBE 2 23 42 0 65 */ +584, /* OBJ_setct_CapRevReqTBEX 2 23 42 0 66 */ +585, /* OBJ_setct_CapRevResTBE 2 23 42 0 67 */ +586, /* OBJ_setct_CredReqTBE 2 23 42 0 68 */ +587, /* OBJ_setct_CredReqTBEX 2 23 42 0 69 */ +588, /* OBJ_setct_CredResTBE 2 23 42 0 70 */ +589, /* OBJ_setct_CredRevReqTBE 2 23 42 0 71 */ +590, /* OBJ_setct_CredRevReqTBEX 2 23 42 0 72 */ +591, /* OBJ_setct_CredRevResTBE 2 23 42 0 73 */ +592, /* OBJ_setct_BatchAdminReqTBE 2 23 42 0 74 */ +593, /* OBJ_setct_BatchAdminResTBE 2 23 42 0 75 */ +594, /* OBJ_setct_RegFormReqTBE 2 23 42 0 76 */ +595, /* OBJ_setct_CertReqTBE 2 23 42 0 77 */ +596, /* OBJ_setct_CertReqTBEX 2 23 42 0 78 */ +597, /* OBJ_setct_CertResTBE 2 23 42 0 79 */ +598, /* OBJ_setct_CRLNotificationTBS 2 23 42 0 80 */ +599, /* OBJ_setct_CRLNotificationResTBS 2 23 42 0 81 */ +600, /* OBJ_setct_BCIDistributionTBS 2 23 42 0 82 */ +601, /* OBJ_setext_genCrypt 2 23 42 1 1 */ +602, /* OBJ_setext_miAuth 2 23 42 1 3 */ +603, /* OBJ_setext_pinSecure 2 23 42 1 4 */ +604, /* OBJ_setext_pinAny 2 23 42 1 5 */ +605, /* OBJ_setext_track2 2 23 42 1 7 */ +606, /* OBJ_setext_cv 2 23 42 1 8 */ +620, /* OBJ_setAttr_Cert 2 23 42 3 0 */ +621, /* OBJ_setAttr_PGWYcap 2 23 42 3 1 */ +622, /* OBJ_setAttr_TokenType 2 23 42 3 2 */ +623, /* OBJ_setAttr_IssCap 2 23 42 3 3 */ +607, /* OBJ_set_policy_root 2 23 42 5 0 */ +608, /* OBJ_setCext_hashedRoot 2 23 42 7 0 */ +609, /* OBJ_setCext_certType 2 23 42 7 1 */ +610, /* OBJ_setCext_merchData 2 23 42 7 2 */ +611, /* OBJ_setCext_cCertRequired 2 23 42 7 3 */ +612, /* OBJ_setCext_tunneling 2 23 42 7 4 */ +613, /* OBJ_setCext_setExt 2 23 42 7 5 */ +614, /* OBJ_setCext_setQualf 2 23 42 7 6 */ +615, /* OBJ_setCext_PGWYcapabilities 2 23 42 7 7 */ +616, /* OBJ_setCext_TokenIdentifier 2 23 42 7 8 */ +617, /* OBJ_setCext_Track2Data 2 23 42 7 9 */ +618, /* OBJ_setCext_TokenType 2 23 42 7 10 */ +619, /* OBJ_setCext_IssuerCapabilities 2 23 42 7 11 */ +636, /* OBJ_set_brand_IATA_ATA 2 23 42 8 1 */ +640, /* OBJ_set_brand_Visa 2 23 42 8 4 */ +641, /* OBJ_set_brand_MasterCard 2 23 42 8 5 */ +637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ +638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ +639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ +805, /* OBJ_cryptopro 1 2 643 2 2 */ +806, /* OBJ_cryptocom 1 2 643 2 9 */ +184, /* OBJ_X9_57 1 2 840 10040 */ +405, /* OBJ_ansi_X9_62 1 2 840 10045 */ +389, /* OBJ_Enterprises 1 3 6 1 4 1 */ +504, /* OBJ_mime_mhs 1 3 6 1 7 1 */ +104, /* OBJ_md5WithRSA 1 3 14 3 2 3 */ +29, /* OBJ_des_ecb 1 3 14 3 2 6 */ +31, /* OBJ_des_cbc 1 3 14 3 2 7 */ +45, /* OBJ_des_ofb64 1 3 14 3 2 8 */ +30, /* OBJ_des_cfb64 1 3 14 3 2 9 */ +377, /* OBJ_rsaSignature 1 3 14 3 2 11 */ +67, /* OBJ_dsa_2 1 3 14 3 2 12 */ +66, /* OBJ_dsaWithSHA 1 3 14 3 2 13 */ +42, /* OBJ_shaWithRSAEncryption 1 3 14 3 2 15 */ +32, /* OBJ_des_ede_ecb 1 3 14 3 2 17 */ +41, /* OBJ_sha 1 3 14 3 2 18 */ +64, /* OBJ_sha1 1 3 14 3 2 26 */ +70, /* OBJ_dsaWithSHA1_2 1 3 14 3 2 27 */ +115, /* OBJ_sha1WithRSA 1 3 14 3 2 29 */ +117, /* OBJ_ripemd160 1 3 36 3 2 1 */ +143, /* OBJ_sxnet 1 3 101 1 4 1 */ +721, /* OBJ_sect163k1 1 3 132 0 1 */ +722, /* OBJ_sect163r1 1 3 132 0 2 */ +728, /* OBJ_sect239k1 1 3 132 0 3 */ +717, /* OBJ_sect113r1 1 3 132 0 4 */ +718, /* OBJ_sect113r2 1 3 132 0 5 */ +704, /* OBJ_secp112r1 1 3 132 0 6 */ +705, /* OBJ_secp112r2 1 3 132 0 7 */ +709, /* OBJ_secp160r1 1 3 132 0 8 */ +708, /* OBJ_secp160k1 1 3 132 0 9 */ +714, /* OBJ_secp256k1 1 3 132 0 10 */ +723, /* OBJ_sect163r2 1 3 132 0 15 */ +729, /* OBJ_sect283k1 1 3 132 0 16 */ +730, /* OBJ_sect283r1 1 3 132 0 17 */ +719, /* OBJ_sect131r1 1 3 132 0 22 */ +720, /* OBJ_sect131r2 1 3 132 0 23 */ +724, /* OBJ_sect193r1 1 3 132 0 24 */ +725, /* OBJ_sect193r2 1 3 132 0 25 */ +726, /* OBJ_sect233k1 1 3 132 0 26 */ +727, /* OBJ_sect233r1 1 3 132 0 27 */ +706, /* OBJ_secp128r1 1 3 132 0 28 */ +707, /* OBJ_secp128r2 1 3 132 0 29 */ +710, /* OBJ_secp160r2 1 3 132 0 30 */ +711, /* OBJ_secp192k1 1 3 132 0 31 */ +712, /* OBJ_secp224k1 1 3 132 0 32 */ +713, /* OBJ_secp224r1 1 3 132 0 33 */ +715, /* OBJ_secp384r1 1 3 132 0 34 */ +716, /* OBJ_secp521r1 1 3 132 0 35 */ +731, /* OBJ_sect409k1 1 3 132 0 36 */ +732, /* OBJ_sect409r1 1 3 132 0 37 */ +733, /* OBJ_sect571k1 1 3 132 0 38 */ +734, /* OBJ_sect571r1 1 3 132 0 39 */ +624, /* OBJ_set_rootKeyThumb 2 23 42 3 0 0 */ +625, /* OBJ_set_addPolicy 2 23 42 3 0 1 */ +626, /* OBJ_setAttr_Token_EMV 2 23 42 3 2 1 */ +627, /* OBJ_setAttr_Token_B0Prime 2 23 42 3 2 2 */ +628, /* OBJ_setAttr_IssCap_CVM 2 23 42 3 3 3 */ +629, /* OBJ_setAttr_IssCap_T2 2 23 42 3 3 4 */ +630, /* OBJ_setAttr_IssCap_Sig 2 23 42 3 3 5 */ +642, /* OBJ_set_brand_Novus 2 23 42 8 6011 */ +735, /* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 1 4 1 */ +736, /* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 1 4 3 */ +737, /* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 1 4 4 */ +738, /* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 1 4 5 */ +739, /* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 1 4 6 */ +740, /* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 1 4 7 */ +741, /* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 1 4 8 */ +742, /* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 1 4 9 */ +743, /* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ +744, /* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ +745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ +804, /* OBJ_whirlpool 1 0 10118 3 0 55 */ +124, /* OBJ_rle_compression 1 1 1 1 666 1 */ +773, /* OBJ_kisa 1 2 410 200004 */ +807, /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */ +808, /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */ +809, /* OBJ_id_GostR3411_94 1 2 643 2 2 9 */ +810, /* OBJ_id_HMACGostR3411_94 1 2 643 2 2 10 */ +811, /* OBJ_id_GostR3410_2001 1 2 643 2 2 19 */ +812, /* OBJ_id_GostR3410_94 1 2 643 2 2 20 */ +813, /* OBJ_id_Gost28147_89 1 2 643 2 2 21 */ +815, /* OBJ_id_Gost28147_89_MAC 1 2 643 2 2 22 */ +816, /* OBJ_id_GostR3411_94_prf 1 2 643 2 2 23 */ +817, /* OBJ_id_GostR3410_2001DH 1 2 643 2 2 98 */ +818, /* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ + 1, /* OBJ_rsadsi 1 2 840 113549 */ +185, /* OBJ_X9cm 1 2 840 10040 4 */ +127, /* OBJ_id_pkix 1 3 6 1 5 5 7 */ +505, /* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */ +506, /* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */ +119, /* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */ +937, /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */ +938, /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */ +939, /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */ +940, /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */ +942, /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */ +943, /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */ +944, /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */ +945, /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */ +631, /* OBJ_setAttr_GenCryptgrm 2 23 42 3 3 3 1 */ +632, /* OBJ_setAttr_T2Enc 2 23 42 3 3 4 1 */ +633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ +634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ +635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ +436, /* OBJ_ucl 0 9 2342 19200300 */ +820, /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */ +819, /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */ +845, /* OBJ_id_GostR3410_94_a 1 2 643 2 2 20 1 */ +846, /* OBJ_id_GostR3410_94_aBis 1 2 643 2 2 20 2 */ +847, /* OBJ_id_GostR3410_94_b 1 2 643 2 2 20 3 */ +848, /* OBJ_id_GostR3410_94_bBis 1 2 643 2 2 20 4 */ +821, /* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */ +822, /* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */ +823, /* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */ +824, /* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */ +825, /* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */ +826, /* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */ +827, /* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */ +828, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */ +829, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */ +830, /* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */ +831, /* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */ +832, /* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */ +833, /* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */ +834, /* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */ +835, /* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */ +836, /* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */ +837, /* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */ +838, /* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */ +839, /* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */ +840, /* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */ +841, /* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */ +842, /* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */ +843, /* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */ +844, /* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */ + 2, /* OBJ_pkcs 1 2 840 113549 1 */ +431, /* OBJ_hold_instruction_none 1 2 840 10040 2 1 */ +432, /* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */ +433, /* OBJ_hold_instruction_reject 1 2 840 10040 2 3 */ +116, /* OBJ_dsa 1 2 840 10040 4 1 */ +113, /* OBJ_dsaWithSHA1 1 2 840 10040 4 3 */ +406, /* OBJ_X9_62_prime_field 1 2 840 10045 1 1 */ +407, /* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */ +408, /* OBJ_X9_62_id_ecPublicKey 1 2 840 10045 2 1 */ +416, /* OBJ_ecdsa_with_SHA1 1 2 840 10045 4 1 */ +791, /* OBJ_ecdsa_with_Recommended 1 2 840 10045 4 2 */ +792, /* OBJ_ecdsa_with_Specified 1 2 840 10045 4 3 */ +920, /* OBJ_dhpublicnumber 1 2 840 10046 2 1 */ +258, /* OBJ_id_pkix_mod 1 3 6 1 5 5 7 0 */ +175, /* OBJ_id_pe 1 3 6 1 5 5 7 1 */ +259, /* OBJ_id_qt 1 3 6 1 5 5 7 2 */ +128, /* OBJ_id_kp 1 3 6 1 5 5 7 3 */ +260, /* OBJ_id_it 1 3 6 1 5 5 7 4 */ +261, /* OBJ_id_pkip 1 3 6 1 5 5 7 5 */ +262, /* OBJ_id_alg 1 3 6 1 5 5 7 6 */ +263, /* OBJ_id_cmc 1 3 6 1 5 5 7 7 */ +264, /* OBJ_id_on 1 3 6 1 5 5 7 8 */ +265, /* OBJ_id_pda 1 3 6 1 5 5 7 9 */ +266, /* OBJ_id_aca 1 3 6 1 5 5 7 10 */ +267, /* OBJ_id_qcs 1 3 6 1 5 5 7 11 */ +268, /* OBJ_id_cct 1 3 6 1 5 5 7 12 */ +662, /* OBJ_id_ppl 1 3 6 1 5 5 7 21 */ +176, /* OBJ_id_ad 1 3 6 1 5 5 7 48 */ +507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ +508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ +57, /* OBJ_netscape 2 16 840 1 113730 */ +754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ +766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ +757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ +755, /* OBJ_camellia_192_ecb 0 3 4401 5 3 1 9 21 */ +767, /* OBJ_camellia_192_ofb128 0 3 4401 5 3 1 9 23 */ +758, /* OBJ_camellia_192_cfb128 0 3 4401 5 3 1 9 24 */ +756, /* OBJ_camellia_256_ecb 0 3 4401 5 3 1 9 41 */ +768, /* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ +759, /* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ +437, /* OBJ_pilot 0 9 2342 19200300 100 */ +776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ +777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ +779, /* OBJ_seed_cfb128 1 2 410 200004 1 5 */ +778, /* OBJ_seed_ofb128 1 2 410 200004 1 6 */ +852, /* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */ +853, /* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */ +850, /* OBJ_id_GostR3410_94_cc 1 2 643 2 9 1 5 3 */ +851, /* OBJ_id_GostR3410_2001_cc 1 2 643 2 9 1 5 4 */ +849, /* OBJ_id_Gost28147_89_cc 1 2 643 2 9 1 6 1 */ +854, /* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */ +186, /* OBJ_pkcs1 1 2 840 113549 1 1 */ +27, /* OBJ_pkcs3 1 2 840 113549 1 3 */ +187, /* OBJ_pkcs5 1 2 840 113549 1 5 */ +20, /* OBJ_pkcs7 1 2 840 113549 1 7 */ +47, /* OBJ_pkcs9 1 2 840 113549 1 9 */ + 3, /* OBJ_md2 1 2 840 113549 2 2 */ +257, /* OBJ_md4 1 2 840 113549 2 4 */ + 4, /* OBJ_md5 1 2 840 113549 2 5 */ +797, /* OBJ_hmacWithMD5 1 2 840 113549 2 6 */ +163, /* OBJ_hmacWithSHA1 1 2 840 113549 2 7 */ +798, /* OBJ_hmacWithSHA224 1 2 840 113549 2 8 */ +799, /* OBJ_hmacWithSHA256 1 2 840 113549 2 9 */ +800, /* OBJ_hmacWithSHA384 1 2 840 113549 2 10 */ +801, /* OBJ_hmacWithSHA512 1 2 840 113549 2 11 */ +37, /* OBJ_rc2_cbc 1 2 840 113549 3 2 */ + 5, /* OBJ_rc4 1 2 840 113549 3 4 */ +44, /* OBJ_des_ede3_cbc 1 2 840 113549 3 7 */ +120, /* OBJ_rc5_cbc 1 2 840 113549 3 8 */ +643, /* OBJ_des_cdmf 1 2 840 113549 3 10 */ +680, /* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */ +684, /* OBJ_X9_62_c2pnb163v1 1 2 840 10045 3 0 1 */ +685, /* OBJ_X9_62_c2pnb163v2 1 2 840 10045 3 0 2 */ +686, /* OBJ_X9_62_c2pnb163v3 1 2 840 10045 3 0 3 */ +687, /* OBJ_X9_62_c2pnb176v1 1 2 840 10045 3 0 4 */ +688, /* OBJ_X9_62_c2tnb191v1 1 2 840 10045 3 0 5 */ +689, /* OBJ_X9_62_c2tnb191v2 1 2 840 10045 3 0 6 */ +690, /* OBJ_X9_62_c2tnb191v3 1 2 840 10045 3 0 7 */ +691, /* OBJ_X9_62_c2onb191v4 1 2 840 10045 3 0 8 */ +692, /* OBJ_X9_62_c2onb191v5 1 2 840 10045 3 0 9 */ +693, /* OBJ_X9_62_c2pnb208w1 1 2 840 10045 3 0 10 */ +694, /* OBJ_X9_62_c2tnb239v1 1 2 840 10045 3 0 11 */ +695, /* OBJ_X9_62_c2tnb239v2 1 2 840 10045 3 0 12 */ +696, /* OBJ_X9_62_c2tnb239v3 1 2 840 10045 3 0 13 */ +697, /* OBJ_X9_62_c2onb239v4 1 2 840 10045 3 0 14 */ +698, /* OBJ_X9_62_c2onb239v5 1 2 840 10045 3 0 15 */ +699, /* OBJ_X9_62_c2pnb272w1 1 2 840 10045 3 0 16 */ +700, /* OBJ_X9_62_c2pnb304w1 1 2 840 10045 3 0 17 */ +701, /* OBJ_X9_62_c2tnb359v1 1 2 840 10045 3 0 18 */ +702, /* OBJ_X9_62_c2pnb368w1 1 2 840 10045 3 0 19 */ +703, /* OBJ_X9_62_c2tnb431r1 1 2 840 10045 3 0 20 */ +409, /* OBJ_X9_62_prime192v1 1 2 840 10045 3 1 1 */ +410, /* OBJ_X9_62_prime192v2 1 2 840 10045 3 1 2 */ +411, /* OBJ_X9_62_prime192v3 1 2 840 10045 3 1 3 */ +412, /* OBJ_X9_62_prime239v1 1 2 840 10045 3 1 4 */ +413, /* OBJ_X9_62_prime239v2 1 2 840 10045 3 1 5 */ +414, /* OBJ_X9_62_prime239v3 1 2 840 10045 3 1 6 */ +415, /* OBJ_X9_62_prime256v1 1 2 840 10045 3 1 7 */ +793, /* OBJ_ecdsa_with_SHA224 1 2 840 10045 4 3 1 */ +794, /* OBJ_ecdsa_with_SHA256 1 2 840 10045 4 3 2 */ +795, /* OBJ_ecdsa_with_SHA384 1 2 840 10045 4 3 3 */ +796, /* OBJ_ecdsa_with_SHA512 1 2 840 10045 4 3 4 */ +269, /* OBJ_id_pkix1_explicit_88 1 3 6 1 5 5 7 0 1 */ +270, /* OBJ_id_pkix1_implicit_88 1 3 6 1 5 5 7 0 2 */ +271, /* OBJ_id_pkix1_explicit_93 1 3 6 1 5 5 7 0 3 */ +272, /* OBJ_id_pkix1_implicit_93 1 3 6 1 5 5 7 0 4 */ +273, /* OBJ_id_mod_crmf 1 3 6 1 5 5 7 0 5 */ +274, /* OBJ_id_mod_cmc 1 3 6 1 5 5 7 0 6 */ +275, /* OBJ_id_mod_kea_profile_88 1 3 6 1 5 5 7 0 7 */ +276, /* OBJ_id_mod_kea_profile_93 1 3 6 1 5 5 7 0 8 */ +277, /* OBJ_id_mod_cmp 1 3 6 1 5 5 7 0 9 */ +278, /* OBJ_id_mod_qualified_cert_88 1 3 6 1 5 5 7 0 10 */ +279, /* OBJ_id_mod_qualified_cert_93 1 3 6 1 5 5 7 0 11 */ +280, /* OBJ_id_mod_attribute_cert 1 3 6 1 5 5 7 0 12 */ +281, /* OBJ_id_mod_timestamp_protocol 1 3 6 1 5 5 7 0 13 */ +282, /* OBJ_id_mod_ocsp 1 3 6 1 5 5 7 0 14 */ +283, /* OBJ_id_mod_dvcs 1 3 6 1 5 5 7 0 15 */ +284, /* OBJ_id_mod_cmp2000 1 3 6 1 5 5 7 0 16 */ +177, /* OBJ_info_access 1 3 6 1 5 5 7 1 1 */ +285, /* OBJ_biometricInfo 1 3 6 1 5 5 7 1 2 */ +286, /* OBJ_qcStatements 1 3 6 1 5 5 7 1 3 */ +287, /* OBJ_ac_auditEntity 1 3 6 1 5 5 7 1 4 */ +288, /* OBJ_ac_targeting 1 3 6 1 5 5 7 1 5 */ +289, /* OBJ_aaControls 1 3 6 1 5 5 7 1 6 */ +290, /* OBJ_sbgp_ipAddrBlock 1 3 6 1 5 5 7 1 7 */ +291, /* OBJ_sbgp_autonomousSysNum 1 3 6 1 5 5 7 1 8 */ +292, /* OBJ_sbgp_routerIdentifier 1 3 6 1 5 5 7 1 9 */ +397, /* OBJ_ac_proxying 1 3 6 1 5 5 7 1 10 */ +398, /* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ +663, /* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ +164, /* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ +165, /* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ +293, /* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ +129, /* OBJ_server_auth 1 3 6 1 5 5 7 3 1 */ +130, /* OBJ_client_auth 1 3 6 1 5 5 7 3 2 */ +131, /* OBJ_code_sign 1 3 6 1 5 5 7 3 3 */ +132, /* OBJ_email_protect 1 3 6 1 5 5 7 3 4 */ +294, /* OBJ_ipsecEndSystem 1 3 6 1 5 5 7 3 5 */ +295, /* OBJ_ipsecTunnel 1 3 6 1 5 5 7 3 6 */ +296, /* OBJ_ipsecUser 1 3 6 1 5 5 7 3 7 */ +133, /* OBJ_time_stamp 1 3 6 1 5 5 7 3 8 */ +180, /* OBJ_OCSP_sign 1 3 6 1 5 5 7 3 9 */ +297, /* OBJ_dvcs 1 3 6 1 5 5 7 3 10 */ +298, /* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ +299, /* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ +300, /* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ +301, /* OBJ_id_it_preferredSymmAlg 1 3 6 1 5 5 7 4 4 */ +302, /* OBJ_id_it_caKeyUpdateInfo 1 3 6 1 5 5 7 4 5 */ +303, /* OBJ_id_it_currentCRL 1 3 6 1 5 5 7 4 6 */ +304, /* OBJ_id_it_unsupportedOIDs 1 3 6 1 5 5 7 4 7 */ +305, /* OBJ_id_it_subscriptionRequest 1 3 6 1 5 5 7 4 8 */ +306, /* OBJ_id_it_subscriptionResponse 1 3 6 1 5 5 7 4 9 */ +307, /* OBJ_id_it_keyPairParamReq 1 3 6 1 5 5 7 4 10 */ +308, /* OBJ_id_it_keyPairParamRep 1 3 6 1 5 5 7 4 11 */ +309, /* OBJ_id_it_revPassphrase 1 3 6 1 5 5 7 4 12 */ +310, /* OBJ_id_it_implicitConfirm 1 3 6 1 5 5 7 4 13 */ +311, /* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ +312, /* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ +784, /* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ +313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ +314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ +323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ +324, /* OBJ_id_alg_noSignature 1 3 6 1 5 5 7 6 2 */ +325, /* OBJ_id_alg_dh_sig_hmac_sha1 1 3 6 1 5 5 7 6 3 */ +326, /* OBJ_id_alg_dh_pop 1 3 6 1 5 5 7 6 4 */ +327, /* OBJ_id_cmc_statusInfo 1 3 6 1 5 5 7 7 1 */ +328, /* OBJ_id_cmc_identification 1 3 6 1 5 5 7 7 2 */ +329, /* OBJ_id_cmc_identityProof 1 3 6 1 5 5 7 7 3 */ +330, /* OBJ_id_cmc_dataReturn 1 3 6 1 5 5 7 7 4 */ +331, /* OBJ_id_cmc_transactionId 1 3 6 1 5 5 7 7 5 */ +332, /* OBJ_id_cmc_senderNonce 1 3 6 1 5 5 7 7 6 */ +333, /* OBJ_id_cmc_recipientNonce 1 3 6 1 5 5 7 7 7 */ +334, /* OBJ_id_cmc_addExtensions 1 3 6 1 5 5 7 7 8 */ +335, /* OBJ_id_cmc_encryptedPOP 1 3 6 1 5 5 7 7 9 */ +336, /* OBJ_id_cmc_decryptedPOP 1 3 6 1 5 5 7 7 10 */ +337, /* OBJ_id_cmc_lraPOPWitness 1 3 6 1 5 5 7 7 11 */ +338, /* OBJ_id_cmc_getCert 1 3 6 1 5 5 7 7 15 */ +339, /* OBJ_id_cmc_getCRL 1 3 6 1 5 5 7 7 16 */ +340, /* OBJ_id_cmc_revokeRequest 1 3 6 1 5 5 7 7 17 */ +341, /* OBJ_id_cmc_regInfo 1 3 6 1 5 5 7 7 18 */ +342, /* OBJ_id_cmc_responseInfo 1 3 6 1 5 5 7 7 19 */ +343, /* OBJ_id_cmc_queryPending 1 3 6 1 5 5 7 7 21 */ +344, /* OBJ_id_cmc_popLinkRandom 1 3 6 1 5 5 7 7 22 */ +345, /* OBJ_id_cmc_popLinkWitness 1 3 6 1 5 5 7 7 23 */ +346, /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */ +347, /* OBJ_id_on_personalData 1 3 6 1 5 5 7 8 1 */ +858, /* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ +348, /* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ +349, /* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ +351, /* OBJ_id_pda_gender 1 3 6 1 5 5 7 9 3 */ +352, /* OBJ_id_pda_countryOfCitizenship 1 3 6 1 5 5 7 9 4 */ +353, /* OBJ_id_pda_countryOfResidence 1 3 6 1 5 5 7 9 5 */ +354, /* OBJ_id_aca_authenticationInfo 1 3 6 1 5 5 7 10 1 */ +355, /* OBJ_id_aca_accessIdentity 1 3 6 1 5 5 7 10 2 */ +356, /* OBJ_id_aca_chargingIdentity 1 3 6 1 5 5 7 10 3 */ +357, /* OBJ_id_aca_group 1 3 6 1 5 5 7 10 4 */ +358, /* OBJ_id_aca_role 1 3 6 1 5 5 7 10 5 */ +399, /* OBJ_id_aca_encAttrs 1 3 6 1 5 5 7 10 6 */ +359, /* OBJ_id_qcs_pkixQCSyntax_v1 1 3 6 1 5 5 7 11 1 */ +360, /* OBJ_id_cct_crs 1 3 6 1 5 5 7 12 1 */ +361, /* OBJ_id_cct_PKIData 1 3 6 1 5 5 7 12 2 */ +362, /* OBJ_id_cct_PKIResponse 1 3 6 1 5 5 7 12 3 */ +664, /* OBJ_id_ppl_anyLanguage 1 3 6 1 5 5 7 21 0 */ +665, /* OBJ_id_ppl_inheritAll 1 3 6 1 5 5 7 21 1 */ +667, /* OBJ_Independent 1 3 6 1 5 5 7 21 2 */ +178, /* OBJ_ad_OCSP 1 3 6 1 5 5 7 48 1 */ +179, /* OBJ_ad_ca_issuers 1 3 6 1 5 5 7 48 2 */ +363, /* OBJ_ad_timeStamping 1 3 6 1 5 5 7 48 3 */ +364, /* OBJ_ad_dvcs 1 3 6 1 5 5 7 48 4 */ +785, /* OBJ_caRepository 1 3 6 1 5 5 7 48 5 */ +780, /* OBJ_hmac_md5 1 3 6 1 5 5 8 1 1 */ +781, /* OBJ_hmac_sha1 1 3 6 1 5 5 8 1 2 */ +58, /* OBJ_netscape_cert_extension 2 16 840 1 113730 1 */ +59, /* OBJ_netscape_data_type 2 16 840 1 113730 2 */ +438, /* OBJ_pilotAttributeType 0 9 2342 19200300 100 1 */ +439, /* OBJ_pilotAttributeSyntax 0 9 2342 19200300 100 3 */ +440, /* OBJ_pilotObjectClass 0 9 2342 19200300 100 4 */ +441, /* OBJ_pilotGroups 0 9 2342 19200300 100 10 */ +108, /* OBJ_cast5_cbc 1 2 840 113533 7 66 10 */ +112, /* OBJ_pbeWithMD5AndCast5_CBC 1 2 840 113533 7 66 12 */ +782, /* OBJ_id_PasswordBasedMAC 1 2 840 113533 7 66 13 */ +783, /* OBJ_id_DHBasedMac 1 2 840 113533 7 66 30 */ + 6, /* OBJ_rsaEncryption 1 2 840 113549 1 1 1 */ + 7, /* OBJ_md2WithRSAEncryption 1 2 840 113549 1 1 2 */ +396, /* OBJ_md4WithRSAEncryption 1 2 840 113549 1 1 3 */ + 8, /* OBJ_md5WithRSAEncryption 1 2 840 113549 1 1 4 */ +65, /* OBJ_sha1WithRSAEncryption 1 2 840 113549 1 1 5 */ +644, /* OBJ_rsaOAEPEncryptionSET 1 2 840 113549 1 1 6 */ +919, /* OBJ_rsaesOaep 1 2 840 113549 1 1 7 */ +911, /* OBJ_mgf1 1 2 840 113549 1 1 8 */ +935, /* OBJ_pSpecified 1 2 840 113549 1 1 9 */ +912, /* OBJ_rsassaPss 1 2 840 113549 1 1 10 */ +668, /* OBJ_sha256WithRSAEncryption 1 2 840 113549 1 1 11 */ +669, /* OBJ_sha384WithRSAEncryption 1 2 840 113549 1 1 12 */ +670, /* OBJ_sha512WithRSAEncryption 1 2 840 113549 1 1 13 */ +671, /* OBJ_sha224WithRSAEncryption 1 2 840 113549 1 1 14 */ +28, /* OBJ_dhKeyAgreement 1 2 840 113549 1 3 1 */ + 9, /* OBJ_pbeWithMD2AndDES_CBC 1 2 840 113549 1 5 1 */ +10, /* OBJ_pbeWithMD5AndDES_CBC 1 2 840 113549 1 5 3 */ +168, /* OBJ_pbeWithMD2AndRC2_CBC 1 2 840 113549 1 5 4 */ +169, /* OBJ_pbeWithMD5AndRC2_CBC 1 2 840 113549 1 5 6 */ +170, /* OBJ_pbeWithSHA1AndDES_CBC 1 2 840 113549 1 5 10 */ +68, /* OBJ_pbeWithSHA1AndRC2_CBC 1 2 840 113549 1 5 11 */ +69, /* OBJ_id_pbkdf2 1 2 840 113549 1 5 12 */ +161, /* OBJ_pbes2 1 2 840 113549 1 5 13 */ +162, /* OBJ_pbmac1 1 2 840 113549 1 5 14 */ +21, /* OBJ_pkcs7_data 1 2 840 113549 1 7 1 */ +22, /* OBJ_pkcs7_signed 1 2 840 113549 1 7 2 */ +23, /* OBJ_pkcs7_enveloped 1 2 840 113549 1 7 3 */ +24, /* OBJ_pkcs7_signedAndEnveloped 1 2 840 113549 1 7 4 */ +25, /* OBJ_pkcs7_digest 1 2 840 113549 1 7 5 */ +26, /* OBJ_pkcs7_encrypted 1 2 840 113549 1 7 6 */ +48, /* OBJ_pkcs9_emailAddress 1 2 840 113549 1 9 1 */ +49, /* OBJ_pkcs9_unstructuredName 1 2 840 113549 1 9 2 */ +50, /* OBJ_pkcs9_contentType 1 2 840 113549 1 9 3 */ +51, /* OBJ_pkcs9_messageDigest 1 2 840 113549 1 9 4 */ +52, /* OBJ_pkcs9_signingTime 1 2 840 113549 1 9 5 */ +53, /* OBJ_pkcs9_countersignature 1 2 840 113549 1 9 6 */ +54, /* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ +55, /* OBJ_pkcs9_unstructuredAddress 1 2 840 113549 1 9 8 */ +56, /* OBJ_pkcs9_extCertAttributes 1 2 840 113549 1 9 9 */ +172, /* OBJ_ext_req 1 2 840 113549 1 9 14 */ +167, /* OBJ_SMIMECapabilities 1 2 840 113549 1 9 15 */ +188, /* OBJ_SMIME 1 2 840 113549 1 9 16 */ +156, /* OBJ_friendlyName 1 2 840 113549 1 9 20 */ +157, /* OBJ_localKeyID 1 2 840 113549 1 9 21 */ +681, /* OBJ_X9_62_onBasis 1 2 840 10045 1 2 3 1 */ +682, /* OBJ_X9_62_tpBasis 1 2 840 10045 1 2 3 2 */ +683, /* OBJ_X9_62_ppBasis 1 2 840 10045 1 2 3 3 */ +417, /* OBJ_ms_csp_name 1 3 6 1 4 1 311 17 1 */ +856, /* OBJ_LocalKeySet 1 3 6 1 4 1 311 17 2 */ +390, /* OBJ_dcObject 1 3 6 1 4 1 1466 344 */ +91, /* OBJ_bf_cbc 1 3 6 1 4 1 3029 1 2 */ +315, /* OBJ_id_regCtrl_regToken 1 3 6 1 5 5 7 5 1 1 */ +316, /* OBJ_id_regCtrl_authenticator 1 3 6 1 5 5 7 5 1 2 */ +317, /* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */ +318, /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */ +319, /* OBJ_id_regCtrl_oldCertID 1 3 6 1 5 5 7 5 1 5 */ +320, /* OBJ_id_regCtrl_protocolEncrKey 1 3 6 1 5 5 7 5 1 6 */ +321, /* OBJ_id_regInfo_utf8Pairs 1 3 6 1 5 5 7 5 2 1 */ +322, /* OBJ_id_regInfo_certReq 1 3 6 1 5 5 7 5 2 2 */ +365, /* OBJ_id_pkix_OCSP_basic 1 3 6 1 5 5 7 48 1 1 */ +366, /* OBJ_id_pkix_OCSP_Nonce 1 3 6 1 5 5 7 48 1 2 */ +367, /* OBJ_id_pkix_OCSP_CrlID 1 3 6 1 5 5 7 48 1 3 */ +368, /* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */ +369, /* OBJ_id_pkix_OCSP_noCheck 1 3 6 1 5 5 7 48 1 5 */ +370, /* OBJ_id_pkix_OCSP_archiveCutoff 1 3 6 1 5 5 7 48 1 6 */ +371, /* OBJ_id_pkix_OCSP_serviceLocator 1 3 6 1 5 5 7 48 1 7 */ +372, /* OBJ_id_pkix_OCSP_extendedStatus 1 3 6 1 5 5 7 48 1 8 */ +373, /* OBJ_id_pkix_OCSP_valid 1 3 6 1 5 5 7 48 1 9 */ +374, /* OBJ_id_pkix_OCSP_path 1 3 6 1 5 5 7 48 1 10 */ +375, /* OBJ_id_pkix_OCSP_trustRoot 1 3 6 1 5 5 7 48 1 11 */ +921, /* OBJ_brainpoolP160r1 1 3 36 3 3 2 8 1 1 1 */ +922, /* OBJ_brainpoolP160t1 1 3 36 3 3 2 8 1 1 2 */ +923, /* OBJ_brainpoolP192r1 1 3 36 3 3 2 8 1 1 3 */ +924, /* OBJ_brainpoolP192t1 1 3 36 3 3 2 8 1 1 4 */ +925, /* OBJ_brainpoolP224r1 1 3 36 3 3 2 8 1 1 5 */ +926, /* OBJ_brainpoolP224t1 1 3 36 3 3 2 8 1 1 6 */ +927, /* OBJ_brainpoolP256r1 1 3 36 3 3 2 8 1 1 7 */ +928, /* OBJ_brainpoolP256t1 1 3 36 3 3 2 8 1 1 8 */ +929, /* OBJ_brainpoolP320r1 1 3 36 3 3 2 8 1 1 9 */ +930, /* OBJ_brainpoolP320t1 1 3 36 3 3 2 8 1 1 10 */ +931, /* OBJ_brainpoolP384r1 1 3 36 3 3 2 8 1 1 11 */ +932, /* OBJ_brainpoolP384t1 1 3 36 3 3 2 8 1 1 12 */ +933, /* OBJ_brainpoolP512r1 1 3 36 3 3 2 8 1 1 13 */ +934, /* OBJ_brainpoolP512t1 1 3 36 3 3 2 8 1 1 14 */ +936, /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */ +941, /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */ +418, /* OBJ_aes_128_ecb 2 16 840 1 101 3 4 1 1 */ +419, /* OBJ_aes_128_cbc 2 16 840 1 101 3 4 1 2 */ +420, /* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */ +421, /* OBJ_aes_128_cfb128 2 16 840 1 101 3 4 1 4 */ +788, /* OBJ_id_aes128_wrap 2 16 840 1 101 3 4 1 5 */ +895, /* OBJ_aes_128_gcm 2 16 840 1 101 3 4 1 6 */ +896, /* OBJ_aes_128_ccm 2 16 840 1 101 3 4 1 7 */ +897, /* OBJ_id_aes128_wrap_pad 2 16 840 1 101 3 4 1 8 */ +422, /* OBJ_aes_192_ecb 2 16 840 1 101 3 4 1 21 */ +423, /* OBJ_aes_192_cbc 2 16 840 1 101 3 4 1 22 */ +424, /* OBJ_aes_192_ofb128 2 16 840 1 101 3 4 1 23 */ +425, /* OBJ_aes_192_cfb128 2 16 840 1 101 3 4 1 24 */ +789, /* OBJ_id_aes192_wrap 2 16 840 1 101 3 4 1 25 */ +898, /* OBJ_aes_192_gcm 2 16 840 1 101 3 4 1 26 */ +899, /* OBJ_aes_192_ccm 2 16 840 1 101 3 4 1 27 */ +900, /* OBJ_id_aes192_wrap_pad 2 16 840 1 101 3 4 1 28 */ +426, /* OBJ_aes_256_ecb 2 16 840 1 101 3 4 1 41 */ +427, /* OBJ_aes_256_cbc 2 16 840 1 101 3 4 1 42 */ +428, /* OBJ_aes_256_ofb128 2 16 840 1 101 3 4 1 43 */ +429, /* OBJ_aes_256_cfb128 2 16 840 1 101 3 4 1 44 */ +790, /* OBJ_id_aes256_wrap 2 16 840 1 101 3 4 1 45 */ +901, /* OBJ_aes_256_gcm 2 16 840 1 101 3 4 1 46 */ +902, /* OBJ_aes_256_ccm 2 16 840 1 101 3 4 1 47 */ +903, /* OBJ_id_aes256_wrap_pad 2 16 840 1 101 3 4 1 48 */ +672, /* OBJ_sha256 2 16 840 1 101 3 4 2 1 */ +673, /* OBJ_sha384 2 16 840 1 101 3 4 2 2 */ +674, /* OBJ_sha512 2 16 840 1 101 3 4 2 3 */ +675, /* OBJ_sha224 2 16 840 1 101 3 4 2 4 */ +802, /* OBJ_dsa_with_SHA224 2 16 840 1 101 3 4 3 1 */ +803, /* OBJ_dsa_with_SHA256 2 16 840 1 101 3 4 3 2 */ +71, /* OBJ_netscape_cert_type 2 16 840 1 113730 1 1 */ +72, /* OBJ_netscape_base_url 2 16 840 1 113730 1 2 */ +73, /* OBJ_netscape_revocation_url 2 16 840 1 113730 1 3 */ +74, /* OBJ_netscape_ca_revocation_url 2 16 840 1 113730 1 4 */ +75, /* OBJ_netscape_renewal_url 2 16 840 1 113730 1 7 */ +76, /* OBJ_netscape_ca_policy_url 2 16 840 1 113730 1 8 */ +77, /* OBJ_netscape_ssl_server_name 2 16 840 1 113730 1 12 */ +78, /* OBJ_netscape_comment 2 16 840 1 113730 1 13 */ +79, /* OBJ_netscape_cert_sequence 2 16 840 1 113730 2 5 */ +139, /* OBJ_ns_sgc 2 16 840 1 113730 4 1 */ +458, /* OBJ_userId 0 9 2342 19200300 100 1 1 */ +459, /* OBJ_textEncodedORAddress 0 9 2342 19200300 100 1 2 */ +460, /* OBJ_rfc822Mailbox 0 9 2342 19200300 100 1 3 */ +461, /* OBJ_info 0 9 2342 19200300 100 1 4 */ +462, /* OBJ_favouriteDrink 0 9 2342 19200300 100 1 5 */ +463, /* OBJ_roomNumber 0 9 2342 19200300 100 1 6 */ +464, /* OBJ_photo 0 9 2342 19200300 100 1 7 */ +465, /* OBJ_userClass 0 9 2342 19200300 100 1 8 */ +466, /* OBJ_host 0 9 2342 19200300 100 1 9 */ +467, /* OBJ_manager 0 9 2342 19200300 100 1 10 */ +468, /* OBJ_documentIdentifier 0 9 2342 19200300 100 1 11 */ +469, /* OBJ_documentTitle 0 9 2342 19200300 100 1 12 */ +470, /* OBJ_documentVersion 0 9 2342 19200300 100 1 13 */ +471, /* OBJ_documentAuthor 0 9 2342 19200300 100 1 14 */ +472, /* OBJ_documentLocation 0 9 2342 19200300 100 1 15 */ +473, /* OBJ_homeTelephoneNumber 0 9 2342 19200300 100 1 20 */ +474, /* OBJ_secretary 0 9 2342 19200300 100 1 21 */ +475, /* OBJ_otherMailbox 0 9 2342 19200300 100 1 22 */ +476, /* OBJ_lastModifiedTime 0 9 2342 19200300 100 1 23 */ +477, /* OBJ_lastModifiedBy 0 9 2342 19200300 100 1 24 */ +391, /* OBJ_domainComponent 0 9 2342 19200300 100 1 25 */ +478, /* OBJ_aRecord 0 9 2342 19200300 100 1 26 */ +479, /* OBJ_pilotAttributeType27 0 9 2342 19200300 100 1 27 */ +480, /* OBJ_mXRecord 0 9 2342 19200300 100 1 28 */ +481, /* OBJ_nSRecord 0 9 2342 19200300 100 1 29 */ +482, /* OBJ_sOARecord 0 9 2342 19200300 100 1 30 */ +483, /* OBJ_cNAMERecord 0 9 2342 19200300 100 1 31 */ +484, /* OBJ_associatedDomain 0 9 2342 19200300 100 1 37 */ +485, /* OBJ_associatedName 0 9 2342 19200300 100 1 38 */ +486, /* OBJ_homePostalAddress 0 9 2342 19200300 100 1 39 */ +487, /* OBJ_personalTitle 0 9 2342 19200300 100 1 40 */ +488, /* OBJ_mobileTelephoneNumber 0 9 2342 19200300 100 1 41 */ +489, /* OBJ_pagerTelephoneNumber 0 9 2342 19200300 100 1 42 */ +490, /* OBJ_friendlyCountryName 0 9 2342 19200300 100 1 43 */ +491, /* OBJ_organizationalStatus 0 9 2342 19200300 100 1 45 */ +492, /* OBJ_janetMailbox 0 9 2342 19200300 100 1 46 */ +493, /* OBJ_mailPreferenceOption 0 9 2342 19200300 100 1 47 */ +494, /* OBJ_buildingName 0 9 2342 19200300 100 1 48 */ +495, /* OBJ_dSAQuality 0 9 2342 19200300 100 1 49 */ +496, /* OBJ_singleLevelQuality 0 9 2342 19200300 100 1 50 */ +497, /* OBJ_subtreeMinimumQuality 0 9 2342 19200300 100 1 51 */ +498, /* OBJ_subtreeMaximumQuality 0 9 2342 19200300 100 1 52 */ +499, /* OBJ_personalSignature 0 9 2342 19200300 100 1 53 */ +500, /* OBJ_dITRedirect 0 9 2342 19200300 100 1 54 */ +501, /* OBJ_audio 0 9 2342 19200300 100 1 55 */ +502, /* OBJ_documentPublisher 0 9 2342 19200300 100 1 56 */ +442, /* OBJ_iA5StringSyntax 0 9 2342 19200300 100 3 4 */ +443, /* OBJ_caseIgnoreIA5StringSyntax 0 9 2342 19200300 100 3 5 */ +444, /* OBJ_pilotObject 0 9 2342 19200300 100 4 3 */ +445, /* OBJ_pilotPerson 0 9 2342 19200300 100 4 4 */ +446, /* OBJ_account 0 9 2342 19200300 100 4 5 */ +447, /* OBJ_document 0 9 2342 19200300 100 4 6 */ +448, /* OBJ_room 0 9 2342 19200300 100 4 7 */ +449, /* OBJ_documentSeries 0 9 2342 19200300 100 4 9 */ +392, /* OBJ_Domain 0 9 2342 19200300 100 4 13 */ +450, /* OBJ_rFC822localPart 0 9 2342 19200300 100 4 14 */ +451, /* OBJ_dNSDomain 0 9 2342 19200300 100 4 15 */ +452, /* OBJ_domainRelatedObject 0 9 2342 19200300 100 4 17 */ +453, /* OBJ_friendlyCountry 0 9 2342 19200300 100 4 18 */ +454, /* OBJ_simpleSecurityObject 0 9 2342 19200300 100 4 19 */ +455, /* OBJ_pilotOrganization 0 9 2342 19200300 100 4 20 */ +456, /* OBJ_pilotDSA 0 9 2342 19200300 100 4 21 */ +457, /* OBJ_qualityLabelledData 0 9 2342 19200300 100 4 22 */ +189, /* OBJ_id_smime_mod 1 2 840 113549 1 9 16 0 */ +190, /* OBJ_id_smime_ct 1 2 840 113549 1 9 16 1 */ +191, /* OBJ_id_smime_aa 1 2 840 113549 1 9 16 2 */ +192, /* OBJ_id_smime_alg 1 2 840 113549 1 9 16 3 */ +193, /* OBJ_id_smime_cd 1 2 840 113549 1 9 16 4 */ +194, /* OBJ_id_smime_spq 1 2 840 113549 1 9 16 5 */ +195, /* OBJ_id_smime_cti 1 2 840 113549 1 9 16 6 */ +158, /* OBJ_x509Certificate 1 2 840 113549 1 9 22 1 */ +159, /* OBJ_sdsiCertificate 1 2 840 113549 1 9 22 2 */ +160, /* OBJ_x509Crl 1 2 840 113549 1 9 23 1 */ +144, /* OBJ_pbe_WithSHA1And128BitRC4 1 2 840 113549 1 12 1 1 */ +145, /* OBJ_pbe_WithSHA1And40BitRC4 1 2 840 113549 1 12 1 2 */ +146, /* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */ +147, /* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */ +148, /* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */ +149, /* OBJ_pbe_WithSHA1And40BitRC2_CBC 1 2 840 113549 1 12 1 6 */ +171, /* OBJ_ms_ext_req 1 3 6 1 4 1 311 2 1 14 */ +134, /* OBJ_ms_code_ind 1 3 6 1 4 1 311 2 1 21 */ +135, /* OBJ_ms_code_com 1 3 6 1 4 1 311 2 1 22 */ +136, /* OBJ_ms_ctl_sign 1 3 6 1 4 1 311 10 3 1 */ +137, /* OBJ_ms_sgc 1 3 6 1 4 1 311 10 3 3 */ +138, /* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ +648, /* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ +649, /* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ +951, /* OBJ_ct_precert_scts 1 3 6 1 4 1 11129 2 4 2 */ +952, /* OBJ_ct_precert_poison 1 3 6 1 4 1 11129 2 4 3 */ +953, /* OBJ_ct_precert_signer 1 3 6 1 4 1 11129 2 4 4 */ +954, /* OBJ_ct_cert_scts 1 3 6 1 4 1 11129 2 4 5 */ +751, /* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */ +752, /* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */ +753, /* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */ +907, /* OBJ_id_camellia128_wrap 1 2 392 200011 61 1 1 3 2 */ +908, /* OBJ_id_camellia192_wrap 1 2 392 200011 61 1 1 3 3 */ +909, /* OBJ_id_camellia256_wrap 1 2 392 200011 61 1 1 3 4 */ +196, /* OBJ_id_smime_mod_cms 1 2 840 113549 1 9 16 0 1 */ +197, /* OBJ_id_smime_mod_ess 1 2 840 113549 1 9 16 0 2 */ +198, /* OBJ_id_smime_mod_oid 1 2 840 113549 1 9 16 0 3 */ +199, /* OBJ_id_smime_mod_msg_v3 1 2 840 113549 1 9 16 0 4 */ +200, /* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */ +201, /* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */ +202, /* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */ +203, /* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */ +204, /* OBJ_id_smime_ct_receipt 1 2 840 113549 1 9 16 1 1 */ +205, /* OBJ_id_smime_ct_authData 1 2 840 113549 1 9 16 1 2 */ +206, /* OBJ_id_smime_ct_publishCert 1 2 840 113549 1 9 16 1 3 */ +207, /* OBJ_id_smime_ct_TSTInfo 1 2 840 113549 1 9 16 1 4 */ +208, /* OBJ_id_smime_ct_TDTInfo 1 2 840 113549 1 9 16 1 5 */ +209, /* OBJ_id_smime_ct_contentInfo 1 2 840 113549 1 9 16 1 6 */ +210, /* OBJ_id_smime_ct_DVCSRequestData 1 2 840 113549 1 9 16 1 7 */ +211, /* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */ +786, /* OBJ_id_smime_ct_compressedData 1 2 840 113549 1 9 16 1 9 */ +787, /* OBJ_id_ct_asciiTextWithCRLF 1 2 840 113549 1 9 16 1 27 */ +212, /* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ +213, /* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ +214, /* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ +215, /* OBJ_id_smime_aa_contentHint 1 2 840 113549 1 9 16 2 4 */ +216, /* OBJ_id_smime_aa_msgSigDigest 1 2 840 113549 1 9 16 2 5 */ +217, /* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */ +218, /* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */ +219, /* OBJ_id_smime_aa_macValue 1 2 840 113549 1 9 16 2 8 */ +220, /* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */ +221, /* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */ +222, /* OBJ_id_smime_aa_encrypKeyPref 1 2 840 113549 1 9 16 2 11 */ +223, /* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */ +224, /* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */ +225, /* OBJ_id_smime_aa_timeStampToken 1 2 840 113549 1 9 16 2 14 */ +226, /* OBJ_id_smime_aa_ets_sigPolicyId 1 2 840 113549 1 9 16 2 15 */ +227, /* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */ +228, /* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */ +229, /* OBJ_id_smime_aa_ets_signerAttr 1 2 840 113549 1 9 16 2 18 */ +230, /* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */ +231, /* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */ +232, /* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */ +233, /* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */ +234, /* OBJ_id_smime_aa_ets_certValues 1 2 840 113549 1 9 16 2 23 */ +235, /* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */ +236, /* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */ +237, /* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */ +238, /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */ +239, /* OBJ_id_smime_aa_signatureType 1 2 840 113549 1 9 16 2 28 */ +240, /* OBJ_id_smime_aa_dvcs_dvc 1 2 840 113549 1 9 16 2 29 */ +241, /* OBJ_id_smime_alg_ESDHwith3DES 1 2 840 113549 1 9 16 3 1 */ +242, /* OBJ_id_smime_alg_ESDHwithRC2 1 2 840 113549 1 9 16 3 2 */ +243, /* OBJ_id_smime_alg_3DESwrap 1 2 840 113549 1 9 16 3 3 */ +244, /* OBJ_id_smime_alg_RC2wrap 1 2 840 113549 1 9 16 3 4 */ +245, /* OBJ_id_smime_alg_ESDH 1 2 840 113549 1 9 16 3 5 */ +246, /* OBJ_id_smime_alg_CMS3DESwrap 1 2 840 113549 1 9 16 3 6 */ +247, /* OBJ_id_smime_alg_CMSRC2wrap 1 2 840 113549 1 9 16 3 7 */ +125, /* OBJ_zlib_compression 1 2 840 113549 1 9 16 3 8 */ +893, /* OBJ_id_alg_PWRI_KEK 1 2 840 113549 1 9 16 3 9 */ +248, /* OBJ_id_smime_cd_ldap 1 2 840 113549 1 9 16 4 1 */ +249, /* OBJ_id_smime_spq_ets_sqt_uri 1 2 840 113549 1 9 16 5 1 */ +250, /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */ +251, /* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */ +252, /* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */ +253, /* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */ +254, /* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */ +255, /* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */ +256, /* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */ +150, /* OBJ_keyBag 1 2 840 113549 1 12 10 1 1 */ +151, /* OBJ_pkcs8ShroudedKeyBag 1 2 840 113549 1 12 10 1 2 */ +152, /* OBJ_certBag 1 2 840 113549 1 12 10 1 3 */ +153, /* OBJ_crlBag 1 2 840 113549 1 12 10 1 4 */ +154, /* OBJ_secretBag 1 2 840 113549 1 12 10 1 5 */ +155, /* OBJ_safeContentsBag 1 2 840 113549 1 12 10 1 6 */ +34, /* OBJ_idea_cbc 1 3 6 1 4 1 188 7 1 1 2 */ +955, /* OBJ_jurisdictionLocalityName 1 3 6 1 4 1 311 60 2 1 1 */ +956, /* OBJ_jurisdictionStateOrProvinceName 1 3 6 1 4 1 311 60 2 1 2 */ +957, /* OBJ_jurisdictionCountryName 1 3 6 1 4 1 311 60 2 1 3 */ +}; + diff --git a/Sources/COpenSSL/obj_mac.h b/Sources/COpenSSL/obj_mac.h new file mode 100644 index 00000000..779c309b --- /dev/null +++ b/Sources/COpenSSL/obj_mac.h @@ -0,0 +1,4194 @@ +/* crypto/objects/obj_mac.h */ + +/* + * THIS FILE IS GENERATED FROM objects.txt by objects.pl via the following + * command: perl objects.pl objects.txt obj_mac.num obj_mac.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep OBJ_pkcs1,7L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 OBJ_pkcs1,8L + +#define SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 935 +#define OBJ_pSpecified OBJ_pkcs1,9L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss OBJ_pkcs1,10L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcardlogin" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft Universal Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distrubution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_rle_compression "RLE" +#define LN_rle_compression "run length compression" +#define NID_rle_compression 124 +#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm OBJ_aes,6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm OBJ_aes,7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad OBJ_aes,8L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm OBJ_aes,26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm OBJ_aes,27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad OBJ_aes,28L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm OBJ_aes,46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm OBJ_aes,47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad OBJ_aes,48L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 + +#define SN_aes_128_cbc_hmac_sha256 "AES-128-CBC-HMAC-SHA256" +#define LN_aes_128_cbc_hmac_sha256 "aes-128-cbc-hmac-sha256" +#define NID_aes_128_cbc_hmac_sha256 948 + +#define SN_aes_192_cbc_hmac_sha256 "AES-192-CBC-HMAC-SHA256" +#define LN_aes_192_cbc_hmac_sha256 "aes-192-cbc-hmac-sha256" +#define NID_aes_192_cbc_hmac_sha256 949 + +#define SN_aes_256_cbc_hmac_sha256 "AES-256-CBC-HMAC-SHA256" +#define LN_aes_256_cbc_hmac_sha256 "aes-256-cbc-hmac-sha256" +#define NID_aes_256_cbc_hmac_sha256 950 + +#define SN_dhpublicnumber "dhpublicnumber" +#define LN_dhpublicnumber "X9.42 DH" +#define NID_dhpublicnumber 920 +#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L + +#define SN_brainpoolP160r1 "brainpoolP160r1" +#define NID_brainpoolP160r1 921 +#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L + +#define SN_brainpoolP160t1 "brainpoolP160t1" +#define NID_brainpoolP160t1 922 +#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L + +#define SN_brainpoolP192r1 "brainpoolP192r1" +#define NID_brainpoolP192r1 923 +#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L + +#define SN_brainpoolP192t1 "brainpoolP192t1" +#define NID_brainpoolP192t1 924 +#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L + +#define SN_brainpoolP224r1 "brainpoolP224r1" +#define NID_brainpoolP224r1 925 +#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L + +#define SN_brainpoolP224t1 "brainpoolP224t1" +#define NID_brainpoolP224t1 926 +#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L + +#define SN_brainpoolP256r1 "brainpoolP256r1" +#define NID_brainpoolP256r1 927 +#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L + +#define SN_brainpoolP256t1 "brainpoolP256t1" +#define NID_brainpoolP256t1 928 +#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L + +#define SN_brainpoolP320r1 "brainpoolP320r1" +#define NID_brainpoolP320r1 929 +#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L + +#define SN_brainpoolP320t1 "brainpoolP320t1" +#define NID_brainpoolP320t1 930 +#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L + +#define SN_brainpoolP384r1 "brainpoolP384r1" +#define NID_brainpoolP384r1 931 +#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L + +#define SN_brainpoolP384t1 "brainpoolP384t1" +#define NID_brainpoolP384t1 932 +#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L + +#define SN_brainpoolP512r1 "brainpoolP512r1" +#define NID_brainpoolP512r1 933 +#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L + +#define SN_brainpoolP512t1 "brainpoolP512t1" +#define NID_brainpoolP512t1 934 +#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L + +#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L + +#define OBJ_secg_scheme OBJ_certicom_arc,1L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L + +#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme" +#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938 +#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L + +#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme" +#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939 +#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L + +#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme" +#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940 +#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L + +#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941 +#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L + +#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943 +#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L + +#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944 +#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L + +#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945 +#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L + +#define SN_dh_std_kdf "dh-std-kdf" +#define NID_dh_std_kdf 946 + +#define SN_dh_cofactor_kdf "dh-cofactor-kdf" +#define NID_dh_cofactor_kdf 947 + +#define SN_ct_precert_scts "ct_precert_scts" +#define LN_ct_precert_scts "CT Precertificate SCTs" +#define NID_ct_precert_scts 951 +#define OBJ_ct_precert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L + +#define SN_ct_precert_poison "ct_precert_poison" +#define LN_ct_precert_poison "CT Precertificate Poison" +#define NID_ct_precert_poison 952 +#define OBJ_ct_precert_poison 1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L + +#define SN_ct_precert_signer "ct_precert_signer" +#define LN_ct_precert_signer "CT Precertificate Signer" +#define NID_ct_precert_signer 953 +#define OBJ_ct_precert_signer 1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L + +#define SN_ct_cert_scts "ct_cert_scts" +#define LN_ct_cert_scts "CT Certificate SCTs" +#define NID_ct_cert_scts 954 +#define OBJ_ct_cert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L + +#define SN_jurisdictionLocalityName "jurisdictionL" +#define LN_jurisdictionLocalityName "jurisdictionLocalityName" +#define NID_jurisdictionLocalityName 955 +#define OBJ_jurisdictionLocalityName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L + +#define SN_jurisdictionStateOrProvinceName "jurisdictionST" +#define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" +#define NID_jurisdictionStateOrProvinceName 956 +#define OBJ_jurisdictionStateOrProvinceName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L + +#define SN_jurisdictionCountryName "jurisdictionC" +#define LN_jurisdictionCountryName "jurisdictionCountryName" +#define NID_jurisdictionCountryName 957 +#define OBJ_jurisdictionCountryName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L diff --git a/Sources/COpenSSL/obj_xref.h b/Sources/COpenSSL/obj_xref.h new file mode 100644 index 00000000..e453e99f --- /dev/null +++ b/Sources/COpenSSL/obj_xref.h @@ -0,0 +1,99 @@ +/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */ + +typedef struct { + int sign_id; + int hash_id; + int pkey_id; +} nid_triple; + +static const nid_triple sigoid_srt[] = { + {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption}, + {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, + {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption}, + {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, + {NID_dsaWithSHA, NID_sha, NID_dsa}, + {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, + {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption}, + {NID_md5WithRSA, NID_md5, NID_rsa}, + {NID_dsaWithSHA1, NID_sha1, NID_dsa}, + {NID_sha1WithRSA, NID_sha1, NID_rsa}, + {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption}, + {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, + {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey}, + {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, + {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, + {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, + {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, + {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey}, + {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, + {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, + {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, + NID_id_GostR3410_2001}, + {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, + NID_id_GostR3410_94}, + {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, + NID_id_GostR3410_94_cc}, + {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, + NID_id_GostR3410_2001_cc}, + {NID_rsassaPss, NID_undef, NID_rsaEncryption}, + {NID_dhSinglePass_stdDH_sha1kdf_scheme, NID_sha1, NID_dh_std_kdf}, + {NID_dhSinglePass_stdDH_sha224kdf_scheme, NID_sha224, NID_dh_std_kdf}, + {NID_dhSinglePass_stdDH_sha256kdf_scheme, NID_sha256, NID_dh_std_kdf}, + {NID_dhSinglePass_stdDH_sha384kdf_scheme, NID_sha384, NID_dh_std_kdf}, + {NID_dhSinglePass_stdDH_sha512kdf_scheme, NID_sha512, NID_dh_std_kdf}, + {NID_dhSinglePass_cofactorDH_sha1kdf_scheme, NID_sha1, + NID_dh_cofactor_kdf}, + {NID_dhSinglePass_cofactorDH_sha224kdf_scheme, NID_sha224, + NID_dh_cofactor_kdf}, + {NID_dhSinglePass_cofactorDH_sha256kdf_scheme, NID_sha256, + NID_dh_cofactor_kdf}, + {NID_dhSinglePass_cofactorDH_sha384kdf_scheme, NID_sha384, + NID_dh_cofactor_kdf}, + {NID_dhSinglePass_cofactorDH_sha512kdf_scheme, NID_sha512, + NID_dh_cofactor_kdf}, +}; + +static const nid_triple *const sigoid_srt_xref[] = { + &sigoid_srt[0], + &sigoid_srt[1], + &sigoid_srt[7], + &sigoid_srt[2], + &sigoid_srt[4], + &sigoid_srt[3], + &sigoid_srt[9], + &sigoid_srt[5], + &sigoid_srt[8], + &sigoid_srt[12], + &sigoid_srt[30], + &sigoid_srt[35], + &sigoid_srt[6], + &sigoid_srt[10], + &sigoid_srt[11], + &sigoid_srt[13], + &sigoid_srt[24], + &sigoid_srt[20], + &sigoid_srt[32], + &sigoid_srt[37], + &sigoid_srt[14], + &sigoid_srt[21], + &sigoid_srt[33], + &sigoid_srt[38], + &sigoid_srt[15], + &sigoid_srt[22], + &sigoid_srt[34], + &sigoid_srt[39], + &sigoid_srt[16], + &sigoid_srt[23], + &sigoid_srt[19], + &sigoid_srt[31], + &sigoid_srt[36], + &sigoid_srt[25], + &sigoid_srt[26], + &sigoid_srt[27], + &sigoid_srt[28], +}; diff --git a/Sources/COpenSSL/objects.h b/Sources/COpenSSL/objects.h new file mode 100644 index 00000000..3f31429b --- /dev/null +++ b/Sources/COpenSSL/objects.h @@ -0,0 +1,1143 @@ +/* crypto/objects/objects.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_OBJECTS_H +# define HEADER_OBJECTS_H + +# define USE_OBJ_MAC + +# ifdef USE_OBJ_MAC +# include "obj_mac.h" +# else +# define SN_undef "UNDEF" +# define LN_undef "undefined" +# define NID_undef 0 +# define OBJ_undef 0L + +# define SN_Algorithm "Algorithm" +# define LN_algorithm "algorithm" +# define NID_algorithm 38 +# define OBJ_algorithm 1L,3L,14L,3L,2L + +# define LN_rsadsi "rsadsi" +# define NID_rsadsi 1 +# define OBJ_rsadsi 1L,2L,840L,113549L + +# define LN_pkcs "pkcs" +# define NID_pkcs 2 +# define OBJ_pkcs OBJ_rsadsi,1L + +# define SN_md2 "MD2" +# define LN_md2 "md2" +# define NID_md2 3 +# define OBJ_md2 OBJ_rsadsi,2L,2L + +# define SN_md5 "MD5" +# define LN_md5 "md5" +# define NID_md5 4 +# define OBJ_md5 OBJ_rsadsi,2L,5L + +# define SN_rc4 "RC4" +# define LN_rc4 "rc4" +# define NID_rc4 5 +# define OBJ_rc4 OBJ_rsadsi,3L,4L + +# define LN_rsaEncryption "rsaEncryption" +# define NID_rsaEncryption 6 +# define OBJ_rsaEncryption OBJ_pkcs,1L,1L + +# define SN_md2WithRSAEncryption "RSA-MD2" +# define LN_md2WithRSAEncryption "md2WithRSAEncryption" +# define NID_md2WithRSAEncryption 7 +# define OBJ_md2WithRSAEncryption OBJ_pkcs,1L,2L + +# define SN_md5WithRSAEncryption "RSA-MD5" +# define LN_md5WithRSAEncryption "md5WithRSAEncryption" +# define NID_md5WithRSAEncryption 8 +# define OBJ_md5WithRSAEncryption OBJ_pkcs,1L,4L + +# define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +# define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +# define NID_pbeWithMD2AndDES_CBC 9 +# define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs,5L,1L + +# define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +# define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +# define NID_pbeWithMD5AndDES_CBC 10 +# define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs,5L,3L + +# define LN_X500 "X500" +# define NID_X500 11 +# define OBJ_X500 2L,5L + +# define LN_X509 "X509" +# define NID_X509 12 +# define OBJ_X509 OBJ_X500,4L + +# define SN_commonName "CN" +# define LN_commonName "commonName" +# define NID_commonName 13 +# define OBJ_commonName OBJ_X509,3L + +# define SN_countryName "C" +# define LN_countryName "countryName" +# define NID_countryName 14 +# define OBJ_countryName OBJ_X509,6L + +# define SN_localityName "L" +# define LN_localityName "localityName" +# define NID_localityName 15 +# define OBJ_localityName OBJ_X509,7L + +/* Postal Address? PA */ + +/* should be "ST" (rfc1327) but MS uses 'S' */ +# define SN_stateOrProvinceName "ST" +# define LN_stateOrProvinceName "stateOrProvinceName" +# define NID_stateOrProvinceName 16 +# define OBJ_stateOrProvinceName OBJ_X509,8L + +# define SN_organizationName "O" +# define LN_organizationName "organizationName" +# define NID_organizationName 17 +# define OBJ_organizationName OBJ_X509,10L + +# define SN_organizationalUnitName "OU" +# define LN_organizationalUnitName "organizationalUnitName" +# define NID_organizationalUnitName 18 +# define OBJ_organizationalUnitName OBJ_X509,11L + +# define SN_rsa "RSA" +# define LN_rsa "rsa" +# define NID_rsa 19 +# define OBJ_rsa OBJ_X500,8L,1L,1L + +# define LN_pkcs7 "pkcs7" +# define NID_pkcs7 20 +# define OBJ_pkcs7 OBJ_pkcs,7L + +# define LN_pkcs7_data "pkcs7-data" +# define NID_pkcs7_data 21 +# define OBJ_pkcs7_data OBJ_pkcs7,1L + +# define LN_pkcs7_signed "pkcs7-signedData" +# define NID_pkcs7_signed 22 +# define OBJ_pkcs7_signed OBJ_pkcs7,2L + +# define LN_pkcs7_enveloped "pkcs7-envelopedData" +# define NID_pkcs7_enveloped 23 +# define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +# define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +# define NID_pkcs7_signedAndEnveloped 24 +# define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +# define LN_pkcs7_digest "pkcs7-digestData" +# define NID_pkcs7_digest 25 +# define OBJ_pkcs7_digest OBJ_pkcs7,5L + +# define LN_pkcs7_encrypted "pkcs7-encryptedData" +# define NID_pkcs7_encrypted 26 +# define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +# define LN_pkcs3 "pkcs3" +# define NID_pkcs3 27 +# define OBJ_pkcs3 OBJ_pkcs,3L + +# define LN_dhKeyAgreement "dhKeyAgreement" +# define NID_dhKeyAgreement 28 +# define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +# define SN_des_ecb "DES-ECB" +# define LN_des_ecb "des-ecb" +# define NID_des_ecb 29 +# define OBJ_des_ecb OBJ_algorithm,6L + +# define SN_des_cfb64 "DES-CFB" +# define LN_des_cfb64 "des-cfb" +# define NID_des_cfb64 30 +/* IV + num */ +# define OBJ_des_cfb64 OBJ_algorithm,9L + +# define SN_des_cbc "DES-CBC" +# define LN_des_cbc "des-cbc" +# define NID_des_cbc 31 +/* IV */ +# define OBJ_des_cbc OBJ_algorithm,7L + +# define SN_des_ede "DES-EDE" +# define LN_des_ede "des-ede" +# define NID_des_ede 32 +/* ?? */ +# define OBJ_des_ede OBJ_algorithm,17L + +# define SN_des_ede3 "DES-EDE3" +# define LN_des_ede3 "des-ede3" +# define NID_des_ede3 33 + +# define SN_idea_cbc "IDEA-CBC" +# define LN_idea_cbc "idea-cbc" +# define NID_idea_cbc 34 +# define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +# define SN_idea_cfb64 "IDEA-CFB" +# define LN_idea_cfb64 "idea-cfb" +# define NID_idea_cfb64 35 + +# define SN_idea_ecb "IDEA-ECB" +# define LN_idea_ecb "idea-ecb" +# define NID_idea_ecb 36 + +# define SN_rc2_cbc "RC2-CBC" +# define LN_rc2_cbc "rc2-cbc" +# define NID_rc2_cbc 37 +# define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +# define SN_rc2_ecb "RC2-ECB" +# define LN_rc2_ecb "rc2-ecb" +# define NID_rc2_ecb 38 + +# define SN_rc2_cfb64 "RC2-CFB" +# define LN_rc2_cfb64 "rc2-cfb" +# define NID_rc2_cfb64 39 + +# define SN_rc2_ofb64 "RC2-OFB" +# define LN_rc2_ofb64 "rc2-ofb" +# define NID_rc2_ofb64 40 + +# define SN_sha "SHA" +# define LN_sha "sha" +# define NID_sha 41 +# define OBJ_sha OBJ_algorithm,18L + +# define SN_shaWithRSAEncryption "RSA-SHA" +# define LN_shaWithRSAEncryption "shaWithRSAEncryption" +# define NID_shaWithRSAEncryption 42 +# define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +# define SN_des_ede_cbc "DES-EDE-CBC" +# define LN_des_ede_cbc "des-ede-cbc" +# define NID_des_ede_cbc 43 + +# define SN_des_ede3_cbc "DES-EDE3-CBC" +# define LN_des_ede3_cbc "des-ede3-cbc" +# define NID_des_ede3_cbc 44 +# define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +# define SN_des_ofb64 "DES-OFB" +# define LN_des_ofb64 "des-ofb" +# define NID_des_ofb64 45 +# define OBJ_des_ofb64 OBJ_algorithm,8L + +# define SN_idea_ofb64 "IDEA-OFB" +# define LN_idea_ofb64 "idea-ofb" +# define NID_idea_ofb64 46 + +# define LN_pkcs9 "pkcs9" +# define NID_pkcs9 47 +# define OBJ_pkcs9 OBJ_pkcs,9L + +# define SN_pkcs9_emailAddress "Email" +# define LN_pkcs9_emailAddress "emailAddress" +# define NID_pkcs9_emailAddress 48 +# define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +# define LN_pkcs9_unstructuredName "unstructuredName" +# define NID_pkcs9_unstructuredName 49 +# define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +# define LN_pkcs9_contentType "contentType" +# define NID_pkcs9_contentType 50 +# define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +# define LN_pkcs9_messageDigest "messageDigest" +# define NID_pkcs9_messageDigest 51 +# define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +# define LN_pkcs9_signingTime "signingTime" +# define NID_pkcs9_signingTime 52 +# define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +# define LN_pkcs9_countersignature "countersignature" +# define NID_pkcs9_countersignature 53 +# define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +# define LN_pkcs9_challengePassword "challengePassword" +# define NID_pkcs9_challengePassword 54 +# define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +# define LN_pkcs9_unstructuredAddress "unstructuredAddress" +# define NID_pkcs9_unstructuredAddress 55 +# define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +# define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +# define NID_pkcs9_extCertAttributes 56 +# define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +# define SN_netscape "Netscape" +# define LN_netscape "Netscape Communications Corp." +# define NID_netscape 57 +# define OBJ_netscape 2L,16L,840L,1L,113730L + +# define SN_netscape_cert_extension "nsCertExt" +# define LN_netscape_cert_extension "Netscape Certificate Extension" +# define NID_netscape_cert_extension 58 +# define OBJ_netscape_cert_extension OBJ_netscape,1L + +# define SN_netscape_data_type "nsDataType" +# define LN_netscape_data_type "Netscape Data Type" +# define NID_netscape_data_type 59 +# define OBJ_netscape_data_type OBJ_netscape,2L + +# define SN_des_ede_cfb64 "DES-EDE-CFB" +# define LN_des_ede_cfb64 "des-ede-cfb" +# define NID_des_ede_cfb64 60 + +# define SN_des_ede3_cfb64 "DES-EDE3-CFB" +# define LN_des_ede3_cfb64 "des-ede3-cfb" +# define NID_des_ede3_cfb64 61 + +# define SN_des_ede_ofb64 "DES-EDE-OFB" +# define LN_des_ede_ofb64 "des-ede-ofb" +# define NID_des_ede_ofb64 62 + +# define SN_des_ede3_ofb64 "DES-EDE3-OFB" +# define LN_des_ede3_ofb64 "des-ede3-ofb" +# define NID_des_ede3_ofb64 63 + +/* I'm not sure about the object ID */ +# define SN_sha1 "SHA1" +# define LN_sha1 "sha1" +# define NID_sha1 64 +# define OBJ_sha1 OBJ_algorithm,26L +/* 28 Jun 1996 - eay */ +/* #define OBJ_sha1 1L,3L,14L,2L,26L,05L <- wrong */ + +# define SN_sha1WithRSAEncryption "RSA-SHA1" +# define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +# define NID_sha1WithRSAEncryption 65 +# define OBJ_sha1WithRSAEncryption OBJ_pkcs,1L,5L + +# define SN_dsaWithSHA "DSA-SHA" +# define LN_dsaWithSHA "dsaWithSHA" +# define NID_dsaWithSHA 66 +# define OBJ_dsaWithSHA OBJ_algorithm,13L + +# define SN_dsa_2 "DSA-old" +# define LN_dsa_2 "dsaEncryption-old" +# define NID_dsa_2 67 +# define OBJ_dsa_2 OBJ_algorithm,12L + +/* proposed by microsoft to RSA */ +# define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +# define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +# define NID_pbeWithSHA1AndRC2_CBC 68 +# define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs,5L,11L + +/* + * proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now defined + * explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something completely + * different. + */ +# define LN_id_pbkdf2 "PBKDF2" +# define NID_id_pbkdf2 69 +# define OBJ_id_pbkdf2 OBJ_pkcs,5L,12L + +# define SN_dsaWithSHA1_2 "DSA-SHA1-old" +# define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +# define NID_dsaWithSHA1_2 70 +/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */ +# define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +# define SN_netscape_cert_type "nsCertType" +# define LN_netscape_cert_type "Netscape Cert Type" +# define NID_netscape_cert_type 71 +# define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +# define SN_netscape_base_url "nsBaseUrl" +# define LN_netscape_base_url "Netscape Base Url" +# define NID_netscape_base_url 72 +# define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +# define SN_netscape_revocation_url "nsRevocationUrl" +# define LN_netscape_revocation_url "Netscape Revocation Url" +# define NID_netscape_revocation_url 73 +# define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +# define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +# define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +# define NID_netscape_ca_revocation_url 74 +# define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +# define SN_netscape_renewal_url "nsRenewalUrl" +# define LN_netscape_renewal_url "Netscape Renewal Url" +# define NID_netscape_renewal_url 75 +# define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +# define SN_netscape_ca_policy_url "nsCaPolicyUrl" +# define LN_netscape_ca_policy_url "Netscape CA Policy Url" +# define NID_netscape_ca_policy_url 76 +# define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +# define SN_netscape_ssl_server_name "nsSslServerName" +# define LN_netscape_ssl_server_name "Netscape SSL Server Name" +# define NID_netscape_ssl_server_name 77 +# define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +# define SN_netscape_comment "nsComment" +# define LN_netscape_comment "Netscape Comment" +# define NID_netscape_comment 78 +# define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +# define SN_netscape_cert_sequence "nsCertSequence" +# define LN_netscape_cert_sequence "Netscape Certificate Sequence" +# define NID_netscape_cert_sequence 79 +# define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +# define SN_desx_cbc "DESX-CBC" +# define LN_desx_cbc "desx-cbc" +# define NID_desx_cbc 80 + +# define SN_id_ce "id-ce" +# define NID_id_ce 81 +# define OBJ_id_ce 2L,5L,29L + +# define SN_subject_key_identifier "subjectKeyIdentifier" +# define LN_subject_key_identifier "X509v3 Subject Key Identifier" +# define NID_subject_key_identifier 82 +# define OBJ_subject_key_identifier OBJ_id_ce,14L + +# define SN_key_usage "keyUsage" +# define LN_key_usage "X509v3 Key Usage" +# define NID_key_usage 83 +# define OBJ_key_usage OBJ_id_ce,15L + +# define SN_private_key_usage_period "privateKeyUsagePeriod" +# define LN_private_key_usage_period "X509v3 Private Key Usage Period" +# define NID_private_key_usage_period 84 +# define OBJ_private_key_usage_period OBJ_id_ce,16L + +# define SN_subject_alt_name "subjectAltName" +# define LN_subject_alt_name "X509v3 Subject Alternative Name" +# define NID_subject_alt_name 85 +# define OBJ_subject_alt_name OBJ_id_ce,17L + +# define SN_issuer_alt_name "issuerAltName" +# define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +# define NID_issuer_alt_name 86 +# define OBJ_issuer_alt_name OBJ_id_ce,18L + +# define SN_basic_constraints "basicConstraints" +# define LN_basic_constraints "X509v3 Basic Constraints" +# define NID_basic_constraints 87 +# define OBJ_basic_constraints OBJ_id_ce,19L + +# define SN_crl_number "crlNumber" +# define LN_crl_number "X509v3 CRL Number" +# define NID_crl_number 88 +# define OBJ_crl_number OBJ_id_ce,20L + +# define SN_certificate_policies "certificatePolicies" +# define LN_certificate_policies "X509v3 Certificate Policies" +# define NID_certificate_policies 89 +# define OBJ_certificate_policies OBJ_id_ce,32L + +# define SN_authority_key_identifier "authorityKeyIdentifier" +# define LN_authority_key_identifier "X509v3 Authority Key Identifier" +# define NID_authority_key_identifier 90 +# define OBJ_authority_key_identifier OBJ_id_ce,35L + +# define SN_bf_cbc "BF-CBC" +# define LN_bf_cbc "bf-cbc" +# define NID_bf_cbc 91 +# define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +# define SN_bf_ecb "BF-ECB" +# define LN_bf_ecb "bf-ecb" +# define NID_bf_ecb 92 + +# define SN_bf_cfb64 "BF-CFB" +# define LN_bf_cfb64 "bf-cfb" +# define NID_bf_cfb64 93 + +# define SN_bf_ofb64 "BF-OFB" +# define LN_bf_ofb64 "bf-ofb" +# define NID_bf_ofb64 94 + +# define SN_mdc2 "MDC2" +# define LN_mdc2 "mdc2" +# define NID_mdc2 95 +# define OBJ_mdc2 2L,5L,8L,3L,101L +/* An alternative? 1L,3L,14L,3L,2L,19L */ + +# define SN_mdc2WithRSA "RSA-MDC2" +# define LN_mdc2WithRSA "mdc2withRSA" +# define NID_mdc2WithRSA 96 +# define OBJ_mdc2WithRSA 2L,5L,8L,3L,100L + +# define SN_rc4_40 "RC4-40" +# define LN_rc4_40 "rc4-40" +# define NID_rc4_40 97 + +# define SN_rc2_40_cbc "RC2-40-CBC" +# define LN_rc2_40_cbc "rc2-40-cbc" +# define NID_rc2_40_cbc 98 + +# define SN_givenName "G" +# define LN_givenName "givenName" +# define NID_givenName 99 +# define OBJ_givenName OBJ_X509,42L + +# define SN_surname "S" +# define LN_surname "surname" +# define NID_surname 100 +# define OBJ_surname OBJ_X509,4L + +# define SN_initials "I" +# define LN_initials "initials" +# define NID_initials 101 +# define OBJ_initials OBJ_X509,43L + +# define SN_uniqueIdentifier "UID" +# define LN_uniqueIdentifier "uniqueIdentifier" +# define NID_uniqueIdentifier 102 +# define OBJ_uniqueIdentifier OBJ_X509,45L + +# define SN_crl_distribution_points "crlDistributionPoints" +# define LN_crl_distribution_points "X509v3 CRL Distribution Points" +# define NID_crl_distribution_points 103 +# define OBJ_crl_distribution_points OBJ_id_ce,31L + +# define SN_md5WithRSA "RSA-NP-MD5" +# define LN_md5WithRSA "md5WithRSA" +# define NID_md5WithRSA 104 +# define OBJ_md5WithRSA OBJ_algorithm,3L + +# define SN_serialNumber "SN" +# define LN_serialNumber "serialNumber" +# define NID_serialNumber 105 +# define OBJ_serialNumber OBJ_X509,5L + +# define SN_title "T" +# define LN_title "title" +# define NID_title 106 +# define OBJ_title OBJ_X509,12L + +# define SN_description "D" +# define LN_description "description" +# define NID_description 107 +# define OBJ_description OBJ_X509,13L + +/* CAST5 is CAST-128, I'm just sticking with the documentation */ +# define SN_cast5_cbc "CAST5-CBC" +# define LN_cast5_cbc "cast5-cbc" +# define NID_cast5_cbc 108 +# define OBJ_cast5_cbc 1L,2L,840L,113533L,7L,66L,10L + +# define SN_cast5_ecb "CAST5-ECB" +# define LN_cast5_ecb "cast5-ecb" +# define NID_cast5_ecb 109 + +# define SN_cast5_cfb64 "CAST5-CFB" +# define LN_cast5_cfb64 "cast5-cfb" +# define NID_cast5_cfb64 110 + +# define SN_cast5_ofb64 "CAST5-OFB" +# define LN_cast5_ofb64 "cast5-ofb" +# define NID_cast5_ofb64 111 + +# define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +# define NID_pbeWithMD5AndCast5_CBC 112 +# define OBJ_pbeWithMD5AndCast5_CBC 1L,2L,840L,113533L,7L,66L,12L + +/*- + * This is one sun will soon be using :-( + * id-dsa-with-sha1 ID ::= { + * iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 } + */ +# define SN_dsaWithSHA1 "DSA-SHA1" +# define LN_dsaWithSHA1 "dsaWithSHA1" +# define NID_dsaWithSHA1 113 +# define OBJ_dsaWithSHA1 1L,2L,840L,10040L,4L,3L + +# define NID_md5_sha1 114 +# define SN_md5_sha1 "MD5-SHA1" +# define LN_md5_sha1 "md5-sha1" + +# define SN_sha1WithRSA "RSA-SHA1-2" +# define LN_sha1WithRSA "sha1WithRSA" +# define NID_sha1WithRSA 115 +# define OBJ_sha1WithRSA OBJ_algorithm,29L + +# define SN_dsa "DSA" +# define LN_dsa "dsaEncryption" +# define NID_dsa 116 +# define OBJ_dsa 1L,2L,840L,10040L,4L,1L + +# define SN_ripemd160 "RIPEMD160" +# define LN_ripemd160 "ripemd160" +# define NID_ripemd160 117 +# define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +/* + * The name should actually be rsaSignatureWithripemd160, but I'm going to + * continue using the convention I'm using with the other ciphers + */ +# define SN_ripemd160WithRSA "RSA-RIPEMD160" +# define LN_ripemd160WithRSA "ripemd160WithRSA" +# define NID_ripemd160WithRSA 119 +# define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +/*- + * Taken from rfc2040 + * RC5_CBC_Parameters ::= SEQUENCE { + * version INTEGER (v1_0(16)), + * rounds INTEGER (8..127), + * blockSizeInBits INTEGER (64, 128), + * iv OCTET STRING OPTIONAL + * } + */ +# define SN_rc5_cbc "RC5-CBC" +# define LN_rc5_cbc "rc5-cbc" +# define NID_rc5_cbc 120 +# define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +# define SN_rc5_ecb "RC5-ECB" +# define LN_rc5_ecb "rc5-ecb" +# define NID_rc5_ecb 121 + +# define SN_rc5_cfb64 "RC5-CFB" +# define LN_rc5_cfb64 "rc5-cfb" +# define NID_rc5_cfb64 122 + +# define SN_rc5_ofb64 "RC5-OFB" +# define LN_rc5_ofb64 "rc5-ofb" +# define NID_rc5_ofb64 123 + +# define SN_rle_compression "RLE" +# define LN_rle_compression "run length compression" +# define NID_rle_compression 124 +# define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +# define SN_zlib_compression "ZLIB" +# define LN_zlib_compression "zlib compression" +# define NID_zlib_compression 125 +# define OBJ_zlib_compression 1L,1L,1L,1L,666L,2L + +# define SN_ext_key_usage "extendedKeyUsage" +# define LN_ext_key_usage "X509v3 Extended Key Usage" +# define NID_ext_key_usage 126 +# define OBJ_ext_key_usage OBJ_id_ce,37 + +# define SN_id_pkix "PKIX" +# define NID_id_pkix 127 +# define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +# define SN_id_kp "id-kp" +# define NID_id_kp 128 +# define OBJ_id_kp OBJ_id_pkix,3L + +/* PKIX extended key usage OIDs */ + +# define SN_server_auth "serverAuth" +# define LN_server_auth "TLS Web Server Authentication" +# define NID_server_auth 129 +# define OBJ_server_auth OBJ_id_kp,1L + +# define SN_client_auth "clientAuth" +# define LN_client_auth "TLS Web Client Authentication" +# define NID_client_auth 130 +# define OBJ_client_auth OBJ_id_kp,2L + +# define SN_code_sign "codeSigning" +# define LN_code_sign "Code Signing" +# define NID_code_sign 131 +# define OBJ_code_sign OBJ_id_kp,3L + +# define SN_email_protect "emailProtection" +# define LN_email_protect "E-mail Protection" +# define NID_email_protect 132 +# define OBJ_email_protect OBJ_id_kp,4L + +# define SN_time_stamp "timeStamping" +# define LN_time_stamp "Time Stamping" +# define NID_time_stamp 133 +# define OBJ_time_stamp OBJ_id_kp,8L + +/* Additional extended key usage OIDs: Microsoft */ + +# define SN_ms_code_ind "msCodeInd" +# define LN_ms_code_ind "Microsoft Individual Code Signing" +# define NID_ms_code_ind 134 +# define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +# define SN_ms_code_com "msCodeCom" +# define LN_ms_code_com "Microsoft Commercial Code Signing" +# define NID_ms_code_com 135 +# define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +# define SN_ms_ctl_sign "msCTLSign" +# define LN_ms_ctl_sign "Microsoft Trust List Signing" +# define NID_ms_ctl_sign 136 +# define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +# define SN_ms_sgc "msSGC" +# define LN_ms_sgc "Microsoft Server Gated Crypto" +# define NID_ms_sgc 137 +# define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +# define SN_ms_efs "msEFS" +# define LN_ms_efs "Microsoft Encrypted File System" +# define NID_ms_efs 138 +# define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +/* Additional usage: Netscape */ + +# define SN_ns_sgc "nsSGC" +# define LN_ns_sgc "Netscape Server Gated Crypto" +# define NID_ns_sgc 139 +# define OBJ_ns_sgc OBJ_netscape,4L,1L + +# define SN_delta_crl "deltaCRL" +# define LN_delta_crl "X509v3 Delta CRL Indicator" +# define NID_delta_crl 140 +# define OBJ_delta_crl OBJ_id_ce,27L + +# define SN_crl_reason "CRLReason" +# define LN_crl_reason "CRL Reason Code" +# define NID_crl_reason 141 +# define OBJ_crl_reason OBJ_id_ce,21L + +# define SN_invalidity_date "invalidityDate" +# define LN_invalidity_date "Invalidity Date" +# define NID_invalidity_date 142 +# define OBJ_invalidity_date OBJ_id_ce,24L + +# define SN_sxnet "SXNetID" +# define LN_sxnet "Strong Extranet ID" +# define NID_sxnet 143 +# define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +/* PKCS12 and related OBJECT IDENTIFIERS */ + +# define OBJ_pkcs12 OBJ_pkcs,12L +# define OBJ_pkcs12_pbeids OBJ_pkcs12, 1 + +# define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +# define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +# define NID_pbe_WithSHA1And128BitRC4 144 +# define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids, 1L + +# define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +# define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +# define NID_pbe_WithSHA1And40BitRC4 145 +# define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids, 2L + +# define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +# define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +# define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +# define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L + +# define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +# define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +# define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +# define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L + +# define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +# define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +# define NID_pbe_WithSHA1And128BitRC2_CBC 148 +# define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids, 5L + +# define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +# define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +# define NID_pbe_WithSHA1And40BitRC2_CBC 149 +# define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L + +# define OBJ_pkcs12_Version1 OBJ_pkcs12, 10L + +# define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1, 1L + +# define LN_keyBag "keyBag" +# define NID_keyBag 150 +# define OBJ_keyBag OBJ_pkcs12_BagIds, 1L + +# define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +# define NID_pkcs8ShroudedKeyBag 151 +# define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L + +# define LN_certBag "certBag" +# define NID_certBag 152 +# define OBJ_certBag OBJ_pkcs12_BagIds, 3L + +# define LN_crlBag "crlBag" +# define NID_crlBag 153 +# define OBJ_crlBag OBJ_pkcs12_BagIds, 4L + +# define LN_secretBag "secretBag" +# define NID_secretBag 154 +# define OBJ_secretBag OBJ_pkcs12_BagIds, 5L + +# define LN_safeContentsBag "safeContentsBag" +# define NID_safeContentsBag 155 +# define OBJ_safeContentsBag OBJ_pkcs12_BagIds, 6L + +# define LN_friendlyName "friendlyName" +# define NID_friendlyName 156 +# define OBJ_friendlyName OBJ_pkcs9, 20L + +# define LN_localKeyID "localKeyID" +# define NID_localKeyID 157 +# define OBJ_localKeyID OBJ_pkcs9, 21L + +# define OBJ_certTypes OBJ_pkcs9, 22L + +# define LN_x509Certificate "x509Certificate" +# define NID_x509Certificate 158 +# define OBJ_x509Certificate OBJ_certTypes, 1L + +# define LN_sdsiCertificate "sdsiCertificate" +# define NID_sdsiCertificate 159 +# define OBJ_sdsiCertificate OBJ_certTypes, 2L + +# define OBJ_crlTypes OBJ_pkcs9, 23L + +# define LN_x509Crl "x509Crl" +# define NID_x509Crl 160 +# define OBJ_x509Crl OBJ_crlTypes, 1L + +/* PKCS#5 v2 OIDs */ + +# define LN_pbes2 "PBES2" +# define NID_pbes2 161 +# define OBJ_pbes2 OBJ_pkcs,5L,13L + +# define LN_pbmac1 "PBMAC1" +# define NID_pbmac1 162 +# define OBJ_pbmac1 OBJ_pkcs,5L,14L + +# define LN_hmacWithSHA1 "hmacWithSHA1" +# define NID_hmacWithSHA1 163 +# define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +/* Policy Qualifier Ids */ + +# define LN_id_qt_cps "Policy Qualifier CPS" +# define SN_id_qt_cps "id-qt-cps" +# define NID_id_qt_cps 164 +# define OBJ_id_qt_cps OBJ_id_pkix,2L,1L + +# define LN_id_qt_unotice "Policy Qualifier User Notice" +# define SN_id_qt_unotice "id-qt-unotice" +# define NID_id_qt_unotice 165 +# define OBJ_id_qt_unotice OBJ_id_pkix,2L,2L + +# define SN_rc2_64_cbc "RC2-64-CBC" +# define LN_rc2_64_cbc "rc2-64-cbc" +# define NID_rc2_64_cbc 166 + +# define SN_SMIMECapabilities "SMIME-CAPS" +# define LN_SMIMECapabilities "S/MIME Capabilities" +# define NID_SMIMECapabilities 167 +# define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +# define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +# define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +# define NID_pbeWithMD2AndRC2_CBC 168 +# define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs,5L,4L + +# define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +# define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +# define NID_pbeWithMD5AndRC2_CBC 169 +# define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs,5L,6L + +# define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +# define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +# define NID_pbeWithSHA1AndDES_CBC 170 +# define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs,5L,10L + +/* Extension request OIDs */ + +# define LN_ms_ext_req "Microsoft Extension Request" +# define SN_ms_ext_req "msExtReq" +# define NID_ms_ext_req 171 +# define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +# define LN_ext_req "Extension Request" +# define SN_ext_req "extReq" +# define NID_ext_req 172 +# define OBJ_ext_req OBJ_pkcs9,14L + +# define SN_name "name" +# define LN_name "name" +# define NID_name 173 +# define OBJ_name OBJ_X509,41L + +# define SN_dnQualifier "dnQualifier" +# define LN_dnQualifier "dnQualifier" +# define NID_dnQualifier 174 +# define OBJ_dnQualifier OBJ_X509,46L + +# define SN_id_pe "id-pe" +# define NID_id_pe 175 +# define OBJ_id_pe OBJ_id_pkix,1L + +# define SN_id_ad "id-ad" +# define NID_id_ad 176 +# define OBJ_id_ad OBJ_id_pkix,48L + +# define SN_info_access "authorityInfoAccess" +# define LN_info_access "Authority Information Access" +# define NID_info_access 177 +# define OBJ_info_access OBJ_id_pe,1L + +# define SN_ad_OCSP "OCSP" +# define LN_ad_OCSP "OCSP" +# define NID_ad_OCSP 178 +# define OBJ_ad_OCSP OBJ_id_ad,1L + +# define SN_ad_ca_issuers "caIssuers" +# define LN_ad_ca_issuers "CA Issuers" +# define NID_ad_ca_issuers 179 +# define OBJ_ad_ca_issuers OBJ_id_ad,2L + +# define SN_OCSP_sign "OCSPSigning" +# define LN_OCSP_sign "OCSP Signing" +# define NID_OCSP_sign 180 +# define OBJ_OCSP_sign OBJ_id_kp,9L +# endif /* USE_OBJ_MAC */ + +# include "bio.h" +# include "asn1.h" + +# define OBJ_NAME_TYPE_UNDEF 0x00 +# define OBJ_NAME_TYPE_MD_METH 0x01 +# define OBJ_NAME_TYPE_CIPHER_METH 0x02 +# define OBJ_NAME_TYPE_PKEY_METH 0x03 +# define OBJ_NAME_TYPE_COMP_METH 0x04 +# define OBJ_NAME_TYPE_NUM 0x05 + +# define OBJ_NAME_ALIAS 0x8000 + +# define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +# define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), + int (*cmp_func) (const char *, const char *), + void (*free_func) (const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name, int type); +int OBJ_NAME_add(const char *name, int type, const char *data); +int OBJ_NAME_remove(const char *name, int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type, + void (*fn) (const OBJ_NAME *, void *arg), + void *arg); + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_nid2obj(int n); +const char *OBJ_nid2ln(int n); +const char *OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp) (const void *, const void *)); +const void *OBJ_bsearch_ex_(const void *key, const void *base, int num, + int size, + int (*cmp) (const void *, const void *), + int flags); + +# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/*- + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignement discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, delcare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid, const char *sn, const char *ln); +void OBJ_cleanup(void); +int OBJ_create_objects(BIO *in); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + +extern int obj_cleanup_defer; +void check_defer(int nid); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OBJ_strings(void); + +/* Error codes for the OBJ functions. */ + +/* Function codes. */ +# define OBJ_F_OBJ_ADD_OBJECT 105 +# define OBJ_F_OBJ_CREATE 100 +# define OBJ_F_OBJ_DUP 101 +# define OBJ_F_OBJ_NAME_NEW_INDEX 106 +# define OBJ_F_OBJ_NID2LN 102 +# define OBJ_F_OBJ_NID2OBJ 103 +# define OBJ_F_OBJ_NID2SN 104 + +/* Reason codes. */ +# define OBJ_R_MALLOC_FAILURE 100 +# define OBJ_R_UNKNOWN_NID 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ocsp.h b/Sources/COpenSSL/ocsp.h new file mode 100644 index 00000000..f0b98d34 --- /dev/null +++ b/Sources/COpenSSL/ocsp.h @@ -0,0 +1,637 @@ +/* ocsp.h */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OCSP_H +# define HEADER_OCSP_H + +# include "ossl_typ.h" +# include "x509.h" +# include "x509v3.h" +# include "safestack.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Various flags and values */ + +# define OCSP_DEFAULT_NONCE_LENGTH 16 + +# define OCSP_NOCERTS 0x1 +# define OCSP_NOINTERN 0x2 +# define OCSP_NOSIGS 0x4 +# define OCSP_NOCHAIN 0x8 +# define OCSP_NOVERIFY 0x10 +# define OCSP_NOEXPLICIT 0x20 +# define OCSP_NOCASIGN 0x40 +# define OCSP_NODELEGATED 0x80 +# define OCSP_NOCHECKS 0x100 +# define OCSP_TRUSTOTHER 0x200 +# define OCSP_RESPID_KEY 0x400 +# define OCSP_NOTIME 0x800 + +/*- CertID ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * issuerNameHash OCTET STRING, -- Hash of Issuer's DN + * issuerKeyHash OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields) + * serialNumber CertificateSerialNumber } + */ +typedef struct ocsp_cert_id_st { + X509_ALGOR *hashAlgorithm; + ASN1_OCTET_STRING *issuerNameHash; + ASN1_OCTET_STRING *issuerKeyHash; + ASN1_INTEGER *serialNumber; +} OCSP_CERTID; + +DECLARE_STACK_OF(OCSP_CERTID) + +/*- Request ::= SEQUENCE { + * reqCert CertID, + * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_one_request_st { + OCSP_CERTID *reqCert; + STACK_OF(X509_EXTENSION) *singleRequestExtensions; +} OCSP_ONEREQ; + +DECLARE_STACK_OF(OCSP_ONEREQ) +DECLARE_ASN1_SET_OF(OCSP_ONEREQ) + +/*- TBSRequest ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * requestorName [1] EXPLICIT GeneralName OPTIONAL, + * requestList SEQUENCE OF Request, + * requestExtensions [2] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_req_info_st { + ASN1_INTEGER *version; + GENERAL_NAME *requestorName; + STACK_OF(OCSP_ONEREQ) *requestList; + STACK_OF(X509_EXTENSION) *requestExtensions; +} OCSP_REQINFO; + +/*- Signature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ +typedef struct ocsp_signature_st { + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} OCSP_SIGNATURE; + +/*- OCSPRequest ::= SEQUENCE { + * tbsRequest TBSRequest, + * optionalSignature [0] EXPLICIT Signature OPTIONAL } + */ +typedef struct ocsp_request_st { + OCSP_REQINFO *tbsRequest; + OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */ +} OCSP_REQUEST; + +/*- OCSPResponseStatus ::= ENUMERATED { + * successful (0), --Response has valid confirmations + * malformedRequest (1), --Illegal confirmation request + * internalError (2), --Internal error in issuer + * tryLater (3), --Try again later + * --(4) is not used + * sigRequired (5), --Must sign the request + * unauthorized (6) --Request unauthorized + * } + */ +# define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +# define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +# define OCSP_RESPONSE_STATUS_TRYLATER 3 +# define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +# define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +/*- ResponseBytes ::= SEQUENCE { + * responseType OBJECT IDENTIFIER, + * response OCTET STRING } + */ +typedef struct ocsp_resp_bytes_st { + ASN1_OBJECT *responseType; + ASN1_OCTET_STRING *response; +} OCSP_RESPBYTES; + +/*- OCSPResponse ::= SEQUENCE { + * responseStatus OCSPResponseStatus, + * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } + */ +struct ocsp_response_st { + ASN1_ENUMERATED *responseStatus; + OCSP_RESPBYTES *responseBytes; +}; + +/*- ResponderID ::= CHOICE { + * byName [1] Name, + * byKey [2] KeyHash } + */ +# define V_OCSP_RESPID_NAME 0 +# define V_OCSP_RESPID_KEY 1 +struct ocsp_responder_id_st { + int type; + union { + X509_NAME *byName; + ASN1_OCTET_STRING *byKey; + } value; +}; + +DECLARE_STACK_OF(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) + +/*- KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key + * --(excluding the tag and length fields) + */ + +/*- RevokedInfo ::= SEQUENCE { + * revocationTime GeneralizedTime, + * revocationReason [0] EXPLICIT CRLReason OPTIONAL } + */ +typedef struct ocsp_revoked_info_st { + ASN1_GENERALIZEDTIME *revocationTime; + ASN1_ENUMERATED *revocationReason; +} OCSP_REVOKEDINFO; + +/*- CertStatus ::= CHOICE { + * good [0] IMPLICIT NULL, + * revoked [1] IMPLICIT RevokedInfo, + * unknown [2] IMPLICIT UnknownInfo } + */ +# define V_OCSP_CERTSTATUS_GOOD 0 +# define V_OCSP_CERTSTATUS_REVOKED 1 +# define V_OCSP_CERTSTATUS_UNKNOWN 2 +typedef struct ocsp_cert_status_st { + int type; + union { + ASN1_NULL *good; + OCSP_REVOKEDINFO *revoked; + ASN1_NULL *unknown; + } value; +} OCSP_CERTSTATUS; + +/*- SingleResponse ::= SEQUENCE { + * certID CertID, + * certStatus CertStatus, + * thisUpdate GeneralizedTime, + * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, + * singleExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_single_response_st { + OCSP_CERTID *certId; + OCSP_CERTSTATUS *certStatus; + ASN1_GENERALIZEDTIME *thisUpdate; + ASN1_GENERALIZEDTIME *nextUpdate; + STACK_OF(X509_EXTENSION) *singleExtensions; +} OCSP_SINGLERESP; + +DECLARE_STACK_OF(OCSP_SINGLERESP) +DECLARE_ASN1_SET_OF(OCSP_SINGLERESP) + +/*- ResponseData ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * responderID ResponderID, + * producedAt GeneralizedTime, + * responses SEQUENCE OF SingleResponse, + * responseExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_response_data_st { + ASN1_INTEGER *version; + OCSP_RESPID *responderId; + ASN1_GENERALIZEDTIME *producedAt; + STACK_OF(OCSP_SINGLERESP) *responses; + STACK_OF(X509_EXTENSION) *responseExtensions; +} OCSP_RESPDATA; + +/*- BasicOCSPResponse ::= SEQUENCE { + * tbsResponseData ResponseData, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ + /* + * Note 1: The value for "signature" is specified in the OCSP rfc2560 as + * follows: "The value for the signature SHALL be computed on the hash of + * the DER encoding ResponseData." This means that you must hash the + * DER-encoded tbsResponseData, and then run it through a crypto-signing + * function, which will (at least w/RSA) do a hash-'n'-private-encrypt + * operation. This seems a bit odd, but that's the spec. Also note that + * the data structures do not leave anywhere to independently specify the + * algorithm used for the initial hash. So, we look at the + * signature-specification algorithm, and try to do something intelligent. + * -- Kathy Weinhold, CertCo + */ + /* + * Note 2: It seems that the mentioned passage from RFC 2560 (section + * 4.2.1) is open for interpretation. I've done tests against another + * responder, and found that it doesn't do the double hashing that the RFC + * seems to say one should. Therefore, all relevant functions take a flag + * saying which variant should be used. -- Richard Levitte, OpenSSL team + * and CeloCom + */ +typedef struct ocsp_basic_response_st { + OCSP_RESPDATA *tbsResponseData; + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} OCSP_BASICRESP; + +/*- + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8) } + */ +# define OCSP_REVOKED_STATUS_NOSTATUS -1 +# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +# define OCSP_REVOKED_STATUS_SUPERSEDED 4 +# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 + +/*- + * CrlID ::= SEQUENCE { + * crlUrl [0] EXPLICIT IA5String OPTIONAL, + * crlNum [1] EXPLICIT INTEGER OPTIONAL, + * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL } + */ +typedef struct ocsp_crl_id_st { + ASN1_IA5STRING *crlUrl; + ASN1_INTEGER *crlNum; + ASN1_GENERALIZEDTIME *crlTime; +} OCSP_CRLID; + +/*- + * ServiceLocator ::= SEQUENCE { + * issuer Name, + * locator AuthorityInfoAccessSyntax OPTIONAL } + */ +typedef struct ocsp_service_locator_st { + X509_NAME *issuer; + STACK_OF(ACCESS_DESCRIPTION) *locator; +} OCSP_SERVICELOC; + +# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) + +# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) + +# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ + (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL) + +# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\ + (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL) + +# define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +# define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) + +# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) + +# define OCSP_REQUEST_sign(o,pkey,md) \ + ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\ + o->optionalSignature->signatureAlgorithm,NULL,\ + o->optionalSignature->signature,o->tbsRequest,pkey,md) + +# define OCSP_BASICRESP_sign(o,pkey,md,d) \ + ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\ + o->signature,o->tbsResponseData,pkey,md) + +# define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\ + a->optionalSignature->signatureAlgorithm,\ + a->optionalSignature->signature,a->tbsRequest,r) + +# define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\ + a->signatureAlgorithm,a->signature,a->tbsResponseData,r) + +# define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) + +# define OCSP_CERTSTATUS_dup(cs)\ + (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ + (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) + +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, + ASN1_VALUE *val); +int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval, + const ASN1_ITEM *it); +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, + ASN1_VALUE *val); +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + X509_NAME *issuerName, + ASN1_BIT_STRING *issuerKey, + ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl); + +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b); +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim); + +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, + int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); + +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OCSP_strings(void); + +/* Error codes for the OCSP functions. */ + +/* Function codes. */ +# define OCSP_F_ASN1_STRING_ENCODE 100 +# define OCSP_F_D2I_OCSP_NONCE 102 +# define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 +# define OCSP_F_OCSP_BASIC_SIGN 104 +# define OCSP_F_OCSP_BASIC_VERIFY 105 +# define OCSP_F_OCSP_CERT_ID_NEW 101 +# define OCSP_F_OCSP_CHECK_DELEGATED 106 +# define OCSP_F_OCSP_CHECK_IDS 107 +# define OCSP_F_OCSP_CHECK_ISSUER 108 +# define OCSP_F_OCSP_CHECK_VALIDITY 115 +# define OCSP_F_OCSP_MATCH_ISSUERID 109 +# define OCSP_F_OCSP_PARSE_URL 114 +# define OCSP_F_OCSP_REQUEST_SIGN 110 +# define OCSP_F_OCSP_REQUEST_VERIFY 116 +# define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 +# define OCSP_F_OCSP_SENDREQ_BIO 112 +# define OCSP_F_OCSP_SENDREQ_NBIO 117 +# define OCSP_F_PARSE_HTTP_LINE1 118 +# define OCSP_F_REQUEST_VERIFY 113 + +/* Reason codes. */ +# define OCSP_R_BAD_DATA 100 +# define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 +# define OCSP_R_DIGEST_ERR 102 +# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +# define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +# define OCSP_R_ERROR_PARSING_URL 121 +# define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 +# define OCSP_R_NOT_BASIC_RESPONSE 104 +# define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 +# define OCSP_R_NO_CONTENT 106 +# define OCSP_R_NO_PUBLIC_KEY 107 +# define OCSP_R_NO_RESPONSE_DATA 108 +# define OCSP_R_NO_REVOKED_TIME 109 +# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 +# define OCSP_R_REQUEST_NOT_SIGNED 128 +# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 +# define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +# define OCSP_R_SERVER_READ_ERROR 113 +# define OCSP_R_SERVER_RESPONSE_ERROR 114 +# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 +# define OCSP_R_SERVER_WRITE_ERROR 116 +# define OCSP_R_SIGNATURE_FAILURE 117 +# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +# define OCSP_R_STATUS_EXPIRED 125 +# define OCSP_R_STATUS_NOT_YET_VALID 126 +# define OCSP_R_STATUS_TOO_OLD 127 +# define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 +# define OCSP_R_UNKNOWN_NID 120 +# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ocsp_.c b/Sources/COpenSSL/ocsp_.c new file mode 100644 index 00000000..4fae188e --- /dev/null +++ b/Sources/COpenSSL/ocsp_.c @@ -0,0 +1,3154 @@ +/* ocsp_asn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include "asn1.h" +#include "asn1t.h" +#include "ocsp.h" + +ASN1_SEQUENCE(OCSP_SIGNATURE) = { + ASN1_SIMPLE(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0) +} ASN1_SEQUENCE_END(OCSP_SIGNATURE) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE) + +ASN1_SEQUENCE(OCSP_CERTID) = { + ASN1_SIMPLE(OCSP_CERTID, hashAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING), + ASN1_SIMPLE(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING), + ASN1_SIMPLE(OCSP_CERTID, serialNumber, ASN1_INTEGER) +} ASN1_SEQUENCE_END(OCSP_CERTID) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID) + +ASN1_SEQUENCE(OCSP_ONEREQ) = { + ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0) +} ASN1_SEQUENCE_END(OCSP_ONEREQ) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ) + +ASN1_SEQUENCE(OCSP_REQINFO) = { + ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0), + ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1), + ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2) +} ASN1_SEQUENCE_END(OCSP_REQINFO) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO) + +ASN1_SEQUENCE(OCSP_REQUEST) = { + ASN1_SIMPLE(OCSP_REQUEST, tbsRequest, OCSP_REQINFO), + ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0) +} ASN1_SEQUENCE_END(OCSP_REQUEST) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST) + +/* OCSP_RESPONSE templates */ + +ASN1_SEQUENCE(OCSP_RESPBYTES) = { + ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT), + ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(OCSP_RESPBYTES) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES) + +ASN1_SEQUENCE(OCSP_RESPONSE) = { + ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED), + ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0) +} ASN1_SEQUENCE_END(OCSP_RESPONSE) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE) + +ASN1_CHOICE(OCSP_RESPID) = { + ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1), + ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2) +} ASN1_CHOICE_END(OCSP_RESPID) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID) + +ASN1_SEQUENCE(OCSP_REVOKEDINFO) = { + ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME), + ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0) +} ASN1_SEQUENCE_END(OCSP_REVOKEDINFO) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) + +ASN1_CHOICE(OCSP_CERTSTATUS) = { + ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0), + ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1), + ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2) +} ASN1_CHOICE_END(OCSP_CERTSTATUS) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS) + +ASN1_SEQUENCE(OCSP_SINGLERESP) = { + ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID), + ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS), + ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME), + ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1) +} ASN1_SEQUENCE_END(OCSP_SINGLERESP) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP) + +ASN1_SEQUENCE(OCSP_RESPDATA) = { + ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0), + ASN1_SIMPLE(OCSP_RESPDATA, responderId, OCSP_RESPID), + ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME), + ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1) +} ASN1_SEQUENCE_END(OCSP_RESPDATA) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA) + +ASN1_SEQUENCE(OCSP_BASICRESP) = { + ASN1_SIMPLE(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA), + ASN1_SIMPLE(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0) +} ASN1_SEQUENCE_END(OCSP_BASICRESP) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP) + +ASN1_SEQUENCE(OCSP_CRLID) = { + ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0), + ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1), + ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2) +} ASN1_SEQUENCE_END(OCSP_CRLID) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID) + +ASN1_SEQUENCE(OCSP_SERVICELOC) = { + ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME), + ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION) +} ASN1_SEQUENCE_END(OCSP_SERVICELOC) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC) +/* ocsp_cl.c */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include "objects.h" +#include "rand.h" +#include "x509.h" +#include "pem.h" +#include "x509v3.h" +// #include "ocsp.h" + +/* + * Utility functions related to sending OCSP requests and extracting relevant + * information from the response. + */ + +/* + * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer: + * useful if we want to add extensions. + */ + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) +{ + OCSP_ONEREQ *one = NULL; + + if (!(one = OCSP_ONEREQ_new())) + goto err; + if (one->reqCert) + OCSP_CERTID_free(one->reqCert); + one->reqCert = cid; + if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one)) { + one->reqCert = NULL; /* do not free on error */ + goto err; + } + return one; + err: + OCSP_ONEREQ_free(one); + return NULL; +} + +/* Set requestorName from an X509_NAME structure */ + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm) +{ + GENERAL_NAME *gen; + gen = GENERAL_NAME_new(); + if (gen == NULL) + return 0; + if (!X509_NAME_set(&gen->d.directoryName, nm)) { + GENERAL_NAME_free(gen); + return 0; + } + gen->type = GEN_DIRNAME; + if (req->tbsRequest->requestorName) + GENERAL_NAME_free(req->tbsRequest->requestorName); + req->tbsRequest->requestorName = gen; + return 1; +} + +/* Add a certificate to an OCSP request */ + +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) +{ + OCSP_SIGNATURE *sig; + if (!req->optionalSignature) + req->optionalSignature = OCSP_SIGNATURE_new(); + sig = req->optionalSignature; + if (!sig) + return 0; + if (!cert) + return 1; + if (!sig->certs && !(sig->certs = sk_X509_new_null())) + return 0; + + if (!sk_X509_push(sig->certs, cert)) + return 0; + CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); + return 1; +} + +/* + * Sign an OCSP request set the requestorName to the subjec name of an + * optional signers certificate and include one or more optional certificates + * in the request. Behaves like PKCS7_sign(). + */ + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags) +{ + int i; + OCSP_SIGNATURE *sig; + X509 *x; + + if (!OCSP_request_set1_name(req, X509_get_subject_name(signer))) + goto err; + + if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) + goto err; + if (key) { + if (!X509_check_private_key(signer, key)) { + OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, + OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + if (!OCSP_REQUEST_sign(req, key, dgst)) + goto err; + } + + if (!(flags & OCSP_NOCERTS)) { + if (!OCSP_request_add1_cert(req, signer)) + goto err; + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + if (!OCSP_request_add1_cert(req, x)) + goto err; + } + } + + return 1; + err: + OCSP_SIGNATURE_free(req->optionalSignature); + req->optionalSignature = NULL; + return 0; +} + +/* Get response status */ + +int OCSP_response_status(OCSP_RESPONSE *resp) +{ + return ASN1_ENUMERATED_get(resp->responseStatus); +} + +/* + * Extract basic response from OCSP_RESPONSE or NULL if no basic response + * present. + */ + +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp) +{ + OCSP_RESPBYTES *rb; + rb = resp->responseBytes; + if (!rb) { + OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA); + return NULL; + } + if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { + OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE); + return NULL; + } + + return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP)); +} + +/* + * Return number of OCSP_SINGLERESP reponses present in a basic response. + */ + +int OCSP_resp_count(OCSP_BASICRESP *bs) +{ + if (!bs) + return -1; + return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses); +} + +/* Extract an OCSP_SINGLERESP response with a given index */ + +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx) +{ + if (!bs) + return NULL; + return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx); +} + +/* Look single response matching a given certificate ID */ + +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) +{ + int i; + STACK_OF(OCSP_SINGLERESP) *sresp; + OCSP_SINGLERESP *single; + if (!bs) + return -1; + if (last < 0) + last = 0; + else + last++; + sresp = bs->tbsResponseData->responses; + for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) { + single = sk_OCSP_SINGLERESP_value(sresp, i); + if (!OCSP_id_cmp(id, single->certId)) + return i; + } + return -1; +} + +/* + * Extract status information from an OCSP_SINGLERESP structure. Note: the + * revtime and reason values are only set if the certificate status is + * revoked. Returns numerical value of status. + */ + +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd) +{ + int ret; + OCSP_CERTSTATUS *cst; + if (!single) + return -1; + cst = single->certStatus; + ret = cst->type; + if (ret == V_OCSP_CERTSTATUS_REVOKED) { + OCSP_REVOKEDINFO *rev = cst->value.revoked; + if (revtime) + *revtime = rev->revocationTime; + if (reason) { + if (rev->revocationReason) + *reason = ASN1_ENUMERATED_get(rev->revocationReason); + else + *reason = -1; + } + } + if (thisupd) + *thisupd = single->thisUpdate; + if (nextupd) + *nextupd = single->nextUpdate; + return ret; +} + +/* + * This function combines the previous ones: look up a certificate ID and if + * found extract status information. Return 0 is successful. + */ + +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd) +{ + int i; + OCSP_SINGLERESP *single; + i = OCSP_resp_find(bs, id, -1); + /* Maybe check for multiple responses and give an error? */ + if (i < 0) + return 0; + single = OCSP_resp_get0(bs, i); + i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd); + if (status) + *status = i; + return 1; +} + +/* + * Check validity of thisUpdate and nextUpdate fields. It is possible that + * the request will take a few seconds to process and/or the time wont be + * totally accurate. Therefore to avoid rejecting otherwise valid time we + * allow the times to be within 'nsec' of the current time. Also to avoid + * accepting very old responses without a nextUpdate field an optional maxage + * parameter specifies the maximum age the thisUpdate field can be. + */ + +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) +{ + int ret = 1; + time_t t_now, t_tmp; + time(&t_now); + /* Check thisUpdate is valid and not more than nsec in the future */ + if (!ASN1_GENERALIZEDTIME_check(thisupd)) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD); + ret = 0; + } else { + t_tmp = t_now + nsec; + if (X509_cmp_time(thisupd, &t_tmp) > 0) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID); + ret = 0; + } + + /* + * If maxsec specified check thisUpdate is not more than maxsec in + * the past + */ + if (maxsec >= 0) { + t_tmp = t_now - maxsec; + if (X509_cmp_time(thisupd, &t_tmp) < 0) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD); + ret = 0; + } + } + } + + if (!nextupd) + return ret; + + /* Check nextUpdate is valid and not more than nsec in the past */ + if (!ASN1_GENERALIZEDTIME_check(nextupd)) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); + ret = 0; + } else { + t_tmp = t_now - nsec; + if (X509_cmp_time(nextupd, &t_tmp) < 0) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED); + ret = 0; + } + } + + /* Also don't allow nextUpdate to precede thisUpdate */ + if (ASN1_STRING_cmp(nextupd, thisupd) < 0) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, + OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); + ret = 0; + } + + return ret; +} +/* crypto/ocsp/ocsp_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "ocsp.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason) + +static ERR_STRING_DATA OCSP_str_functs[] = { + {ERR_FUNC(OCSP_F_ASN1_STRING_ENCODE), "ASN1_STRING_encode"}, + {ERR_FUNC(OCSP_F_D2I_OCSP_NONCE), "D2I_OCSP_NONCE"}, + {ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS), "OCSP_basic_add1_status"}, + {ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN), "OCSP_basic_sign"}, + {ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY), "OCSP_basic_verify"}, + {ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW), "OCSP_cert_id_new"}, + {ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED), "OCSP_CHECK_DELEGATED"}, + {ERR_FUNC(OCSP_F_OCSP_CHECK_IDS), "OCSP_CHECK_IDS"}, + {ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER), "OCSP_CHECK_ISSUER"}, + {ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY), "OCSP_check_validity"}, + {ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID), "OCSP_MATCH_ISSUERID"}, + {ERR_FUNC(OCSP_F_OCSP_PARSE_URL), "OCSP_parse_url"}, + {ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN), "OCSP_request_sign"}, + {ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY), "OCSP_request_verify"}, + {ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC), "OCSP_response_get1_basic"}, + {ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO), "OCSP_sendreq_bio"}, + {ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO), "OCSP_sendreq_nbio"}, + {ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1), "PARSE_HTTP_LINE1"}, + {ERR_FUNC(OCSP_F_REQUEST_VERIFY), "REQUEST_VERIFY"}, + {0, NULL} +}; + +static ERR_STRING_DATA OCSP_str_reasons[] = { + {ERR_REASON(OCSP_R_BAD_DATA), "bad data"}, + {ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(OCSP_R_DIGEST_ERR), "digest err"}, + {ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD), + "error in nextupdate field"}, + {ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD), + "error in thisupdate field"}, + {ERR_REASON(OCSP_R_ERROR_PARSING_URL), "error parsing url"}, + {ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE), + "missing ocspsigning usage"}, + {ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE), + "nextupdate before thisupdate"}, + {ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE), "not basic response"}, + {ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN), "no certificates in chain"}, + {ERR_REASON(OCSP_R_NO_CONTENT), "no content"}, + {ERR_REASON(OCSP_R_NO_PUBLIC_KEY), "no public key"}, + {ERR_REASON(OCSP_R_NO_RESPONSE_DATA), "no response data"}, + {ERR_REASON(OCSP_R_NO_REVOKED_TIME), "no revoked time"}, + {ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED), "request not signed"}, + {ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA), + "response contains no revocation data"}, + {ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED), "root ca not trusted"}, + {ERR_REASON(OCSP_R_SERVER_READ_ERROR), "server read error"}, + {ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR), "server response error"}, + {ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR), + "server response parse error"}, + {ERR_REASON(OCSP_R_SERVER_WRITE_ERROR), "server write error"}, + {ERR_REASON(OCSP_R_SIGNATURE_FAILURE), "signature failure"}, + {ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND), + "signer certificate not found"}, + {ERR_REASON(OCSP_R_STATUS_EXPIRED), "status expired"}, + {ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID), "status not yet valid"}, + {ERR_REASON(OCSP_R_STATUS_TOO_OLD), "status too old"}, + {ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST), "unknown message digest"}, + {ERR_REASON(OCSP_R_UNKNOWN_NID), "unknown nid"}, + {ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE), + "unsupported requestorname type"}, + {0, NULL} +}; + +#endif + +void ERR_load_OCSP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) { + ERR_load_strings(0, OCSP_str_functs); + ERR_load_strings(0, OCSP_str_reasons); + } +#endif +} +/* ocsp_ext.c */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "x509.h" +// #include "ocsp.h" +// #include "rand.h" +// #include "x509v3.h" + +/* Standard wrapper functions for extensions */ + +/* OCSP request extensions */ + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) +{ + return (X509v3_get_ext_count(x->tbsRequest->requestExtensions)); +} + +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID + (x->tbsRequest->requestExtensions, nid, lastpos)); +} + +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ + (x->tbsRequest->requestExtensions, obj, lastpos)); +} + +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->tbsRequest->requestExtensions, crit, lastpos)); +} + +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) +{ + return (X509v3_get_ext(x->tbsRequest->requestExtensions, loc)); +} + +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) +{ + return (X509v3_delete_ext(x->tbsRequest->requestExtensions, loc)); +} + +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); +} + +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, + crit, flags); +} + +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, loc) != + NULL); +} + +/* Single extensions */ + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) +{ + return (X509v3_get_ext_count(x->singleRequestExtensions)); +} + +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos)); +} + +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos)); +} + +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->singleRequestExtensions, crit, lastpos)); +} + +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) +{ + return (X509v3_get_ext(x->singleRequestExtensions, loc)); +} + +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) +{ + return (X509v3_delete_ext(x->singleRequestExtensions, loc)); +} + +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); +} + +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, + flags); +} + +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL); +} + +/* OCSP Basic response */ + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) +{ + return (X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); +} + +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID + (x->tbsResponseData->responseExtensions, nid, lastpos)); +} + +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ + (x->tbsResponseData->responseExtensions, obj, lastpos)); +} + +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->tbsResponseData->responseExtensions, crit, lastpos)); +} + +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) +{ + return (X509v3_get_ext(x->tbsResponseData->responseExtensions, loc)); +} + +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) +{ + return (X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc)); +} + +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx) +{ + return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, + idx); +} + +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags) +{ + return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, + value, crit, flags); +} + +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, loc) + != NULL); +} + +/* OCSP single response extensions */ + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) +{ + return (X509v3_get_ext_count(x->singleExtensions)); +} + +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos)); +} + +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos)); +} + +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos) +{ + return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos)); +} + +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) +{ + return (X509v3_get_ext(x->singleExtensions, loc)); +} + +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) +{ + return (X509v3_delete_ext(x->singleExtensions, loc)); +} + +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx) +{ + return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); +} + +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags) +{ + return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); +} + +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL); +} + +/* also CRL Entry Extensions */ +#if 0 +ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, + void *data, STACK_OF(ASN1_OBJECT) *sk) +{ + int i; + unsigned char *p, *b = NULL; + + if (data) { + if ((i = i2d(data, NULL)) <= 0) + goto err; + if (!(b = p = OPENSSL_malloc((unsigned int)i))) + goto err; + if (i2d(data, &p) <= 0) + goto err; + } else if (sk) { + if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL, + (I2D_OF(ASN1_OBJECT)) i2d, + V_ASN1_SEQUENCE, + V_ASN1_UNIVERSAL, + IS_SEQUENCE)) <= 0) + goto err; + if (!(b = p = OPENSSL_malloc((unsigned int)i))) + goto err; + if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p, (I2D_OF(ASN1_OBJECT)) i2d, + V_ASN1_SEQUENCE, + V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0) + goto err; + } else { + OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA); + goto err; + } + if (!s && !(s = ASN1_STRING_new())) + goto err; + if (!(ASN1_STRING_set(s, b, i))) + goto err; + OPENSSL_free(b); + return s; + err: + if (b) + OPENSSL_free(b); + return NULL; +} +#endif + +/* Nonce handling functions */ + +/* + * Add a nonce to an extension stack. A nonce can be specificed or if NULL a + * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an + * OCTET STRING containing the nonce, previous versions used the raw nonce. + */ + +static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, + unsigned char *val, int len) +{ + unsigned char *tmpval; + ASN1_OCTET_STRING os; + int ret = 0; + if (len <= 0) + len = OCSP_DEFAULT_NONCE_LENGTH; + /* + * Create the OCTET STRING manually by writing out the header and + * appending the content octets. This avoids an extra memory allocation + * operation in some cases. Applications should *NOT* do this because it + * relies on library internals. + */ + os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); + os.data = OPENSSL_malloc(os.length); + if (os.data == NULL) + goto err; + tmpval = os.data; + ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); + if (val) + memcpy(tmpval, val, len); + else if (RAND_bytes(tmpval, len) <= 0) + goto err; + if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, + &os, 0, X509V3_ADD_REPLACE)) + goto err; + ret = 1; + err: + if (os.data) + OPENSSL_free(os.data); + return ret; +} + +/* Add nonce to an OCSP request */ + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) +{ + return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); +} + +/* Same as above but for a response */ + +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) +{ + return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, + len); +} + +/*- + * Check nonce validity in a request and response. + * Return value reflects result: + * 1: nonces present and equal. + * 2: nonces both absent. + * 3: nonce present in response only. + * 0: nonces both present and not equal. + * -1: nonce in request only. + * + * For most responders clients can check return > 0. + * If responder doesn't handle nonces return != 0 may be + * necessary. return == 0 is always an error. + */ + +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) +{ + /* + * Since we are only interested in the presence or absence of + * the nonce and comparing its value there is no need to use + * the X509V3 routines: this way we can avoid them allocating an + * ASN1_OCTET_STRING structure for the value which would be + * freed immediately anyway. + */ + + int req_idx, resp_idx; + X509_EXTENSION *req_ext, *resp_ext; + req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); + resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); + /* Check both absent */ + if ((req_idx < 0) && (resp_idx < 0)) + return 2; + /* Check in request only */ + if ((req_idx >= 0) && (resp_idx < 0)) + return -1; + /* Check in response but not request */ + if ((req_idx < 0) && (resp_idx >= 0)) + return 3; + /* + * Otherwise nonce in request and response so retrieve the extensions + */ + req_ext = OCSP_REQUEST_get_ext(req, req_idx); + resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); + if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) + return 0; + return 1; +} + +/* + * Copy the nonce value (if any) from an OCSP request to a response. + */ + +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) +{ + X509_EXTENSION *req_ext; + int req_idx; + /* Check for nonce in request */ + req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); + /* If no nonce that's OK */ + if (req_idx < 0) + return 2; + req_ext = OCSP_REQUEST_get_ext(req, req_idx); + return OCSP_BASICRESP_add_ext(resp, req_ext, -1); +} + +X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) +{ + X509_EXTENSION *x = NULL; + OCSP_CRLID *cid = NULL; + + if (!(cid = OCSP_CRLID_new())) + goto err; + if (url) { + if (!(cid->crlUrl = ASN1_IA5STRING_new())) + goto err; + if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) + goto err; + } + if (n) { + if (!(cid->crlNum = ASN1_INTEGER_new())) + goto err; + if (!(ASN1_INTEGER_set(cid->crlNum, *n))) + goto err; + } + if (tim) { + if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) + goto err; + if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) + goto err; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); + err: + if (cid) + OCSP_CRLID_free(cid); + return x; +} + +/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ +X509_EXTENSION *OCSP_accept_responses_new(char **oids) +{ + int nid; + STACK_OF(ASN1_OBJECT) *sk = NULL; + ASN1_OBJECT *o = NULL; + X509_EXTENSION *x = NULL; + + if (!(sk = sk_ASN1_OBJECT_new_null())) + goto err; + while (oids && *oids) { + if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid))) + sk_ASN1_OBJECT_push(sk, o); + oids++; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); + err: + if (sk) + sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); + return x; +} + +/* ArchiveCutoff ::= GeneralizedTime */ +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim) +{ + X509_EXTENSION *x = NULL; + ASN1_GENERALIZEDTIME *gt = NULL; + + if (!(gt = ASN1_GENERALIZEDTIME_new())) + goto err; + if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) + goto err; + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); + err: + if (gt) + ASN1_GENERALIZEDTIME_free(gt); + return x; +} + +/* + * per ACCESS_DESCRIPTION parameter are oids, of which there are currently + * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method + * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. + */ +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls) +{ + X509_EXTENSION *x = NULL; + ASN1_IA5STRING *ia5 = NULL; + OCSP_SERVICELOC *sloc = NULL; + ACCESS_DESCRIPTION *ad = NULL; + + if (!(sloc = OCSP_SERVICELOC_new())) + goto err; + if (!(sloc->issuer = X509_NAME_dup(issuer))) + goto err; + if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) + goto err; + while (urls && *urls) { + if (!(ad = ACCESS_DESCRIPTION_new())) + goto err; + if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP))) + goto err; + if (!(ad->location = GENERAL_NAME_new())) + goto err; + if (!(ia5 = ASN1_IA5STRING_new())) + goto err; + if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1)) + goto err; + ad->location->type = GEN_URI; + ad->location->d.ia5 = ia5; + if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) + goto err; + urls++; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); + err: + if (sloc) + OCSP_SERVICELOC_free(sloc); + return x; +} +/* ocsp_ht.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include "e_os.h" +// #include "asn1.h" +// #include "ocsp.h" +// #include "err.h" +#include "buffer.h" +#ifdef OPENSSL_SYS_SUNOS +# define strtoul (unsigned long)strtol +#endif /* OPENSSL_SYS_SUNOS */ + +/* Stateful OCSP request code, supporting non-blocking I/O */ + +/* Opaque OCSP request status structure */ + +struct ocsp_req_ctx_st { + int state; /* Current I/O state */ + unsigned char *iobuf; /* Line buffer */ + int iobuflen; /* Line buffer length */ + BIO *io; /* BIO to perform I/O with */ + BIO *mem; /* Memory BIO response is built into */ + unsigned long asn1_len; /* ASN1 length of response */ + unsigned long max_resp_len; /* Maximum length of response */ +}; + +#define OCSP_MAX_RESP_LENGTH (100 * 1024) +#define OCSP_MAX_LINE_LEN 4096; + +/* OCSP states */ + +/* If set no reading should be performed */ +#define OHS_NOREAD 0x1000 +/* Error condition */ +#define OHS_ERROR (0 | OHS_NOREAD) +/* First line being read */ +#define OHS_FIRSTLINE 1 +/* MIME headers being read */ +#define OHS_HEADERS 2 +/* OCSP initial header (tag + length) being read */ +#define OHS_ASN1_HEADER 3 +/* OCSP content octets being read */ +#define OHS_ASN1_CONTENT 4 +/* First call: ready to start I/O */ +#define OHS_ASN1_WRITE_INIT (5 | OHS_NOREAD) +/* Request being sent */ +#define OHS_ASN1_WRITE (6 | OHS_NOREAD) +/* Request being flushed */ +#define OHS_ASN1_FLUSH (7 | OHS_NOREAD) +/* Completed */ +#define OHS_DONE (8 | OHS_NOREAD) +/* Headers set, no final \r\n included */ +#define OHS_HTTP_HEADER (9 | OHS_NOREAD) + +static int parse_http_line1(char *line); + +OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline) +{ + OCSP_REQ_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX)); + if (!rctx) + return NULL; + rctx->state = OHS_ERROR; + rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; + rctx->mem = BIO_new(BIO_s_mem()); + rctx->io = io; + rctx->asn1_len = 0; + if (maxline > 0) + rctx->iobuflen = maxline; + else + rctx->iobuflen = OCSP_MAX_LINE_LEN; + rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); + if (!rctx->iobuf || !rctx->mem) { + OCSP_REQ_CTX_free(rctx); + return NULL; + } + return rctx; +} + +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) +{ + if (rctx->mem) + BIO_free(rctx->mem); + if (rctx->iobuf) + OPENSSL_free(rctx->iobuf); + OPENSSL_free(rctx); +} + +BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx) +{ + return rctx->mem; +} + +void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len) +{ + if (len == 0) + rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; + else + rctx->max_resp_len = len; +} + +int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val) +{ + static const char req_hdr[] = + "Content-Type: application/ocsp-request\r\n" + "Content-Length: %d\r\n\r\n"; + int reqlen = ASN1_item_i2d(val, NULL, it); + if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0) + return 0; + if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0) + return 0; + rctx->state = OHS_ASN1_WRITE_INIT; + return 1; +} + +int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, + ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int rv, len; + const unsigned char *p; + + rv = OCSP_REQ_CTX_nbio(rctx); + if (rv != 1) + return rv; + + len = BIO_get_mem_data(rctx->mem, &p); + *pval = ASN1_item_d2i(NULL, &p, len, it); + if (*pval == NULL) { + rctx->state = OHS_ERROR; + return 0; + } + return 1; +} + +int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path) +{ + static const char http_hdr[] = "%s %s HTTP/1.0\r\n"; + + if (!path) + path = "/"; + + if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0) + return 0; + rctx->state = OHS_HTTP_HEADER; + return 1; +} + +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) +{ + return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST), + (ASN1_VALUE *)req); +} + +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value) +{ + if (!name) + return 0; + if (BIO_puts(rctx->mem, name) <= 0) + return 0; + if (value) { + if (BIO_write(rctx->mem, ": ", 2) != 2) + return 0; + if (BIO_puts(rctx->mem, value) <= 0) + return 0; + } + if (BIO_write(rctx->mem, "\r\n", 2) != 2) + return 0; + rctx->state = OHS_HTTP_HEADER; + return 1; +} + +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, + int maxline) +{ + + OCSP_REQ_CTX *rctx = NULL; + rctx = OCSP_REQ_CTX_new(io, maxline); + if (!rctx) + return NULL; + + if (!OCSP_REQ_CTX_http(rctx, "POST", path)) + goto err; + + if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) + goto err; + + return rctx; + + err: + OCSP_REQ_CTX_free(rctx); + return NULL; +} + +/* + * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We + * need to obtain the numeric code and (optional) informational message. + */ + +static int parse_http_line1(char *line) +{ + int retcode; + char *p, *q, *r; + /* Skip to first white space (passed protocol info) */ + + for (p = line; *p && !isspace((unsigned char)*p); p++) + continue; + if (!*p) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Skip past white space to start of response code */ + while (*p && isspace((unsigned char)*p)) + p++; + + if (!*p) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Find end of response code: first whitespace after start of code */ + for (q = p; *q && !isspace((unsigned char)*q); q++) + continue; + + if (!*q) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Set end of response code and start of message */ + *q++ = 0; + + /* Attempt to parse numeric code */ + retcode = strtoul(p, &r, 10); + + if (*r) + return 0; + + /* Skip over any leading white space in message */ + while (*q && isspace((unsigned char)*q)) + q++; + + if (*q) { + /* + * Finally zap any trailing white space in message (include CRLF) + */ + + /* We know q has a non white space character so this is OK */ + for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) + *r = 0; + } + if (retcode != 200) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR); + if (!*q) + ERR_add_error_data(2, "Code=", p); + else + ERR_add_error_data(4, "Code=", p, ",Reason=", q); + return 0; + } + + return 1; + +} + +int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx) +{ + int i, n; + const unsigned char *p; + next_io: + if (!(rctx->state & OHS_NOREAD)) { + n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen); + + if (n <= 0) { + if (BIO_should_retry(rctx->io)) + return -1; + return 0; + } + + /* Write data to memory BIO */ + + if (BIO_write(rctx->mem, rctx->iobuf, n) != n) + return 0; + } + + switch (rctx->state) { + case OHS_HTTP_HEADER: + /* Last operation was adding headers: need a final \r\n */ + if (BIO_write(rctx->mem, "\r\n", 2) != 2) { + rctx->state = OHS_ERROR; + return 0; + } + rctx->state = OHS_ASN1_WRITE_INIT; + + case OHS_ASN1_WRITE_INIT: + rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); + rctx->state = OHS_ASN1_WRITE; + + case OHS_ASN1_WRITE: + n = BIO_get_mem_data(rctx->mem, &p); + + i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len); + + if (i <= 0) { + if (BIO_should_retry(rctx->io)) + return -1; + rctx->state = OHS_ERROR; + return 0; + } + + rctx->asn1_len -= i; + + if (rctx->asn1_len > 0) + goto next_io; + + rctx->state = OHS_ASN1_FLUSH; + + (void)BIO_reset(rctx->mem); + + case OHS_ASN1_FLUSH: + + i = BIO_flush(rctx->io); + + if (i > 0) { + rctx->state = OHS_FIRSTLINE; + goto next_io; + } + + if (BIO_should_retry(rctx->io)) + return -1; + + rctx->state = OHS_ERROR; + return 0; + + case OHS_ERROR: + return 0; + + case OHS_FIRSTLINE: + case OHS_HEADERS: + + /* Attempt to read a line in */ + + next_line: + /* + * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check + * there's a complete line in there before calling BIO_gets or we'll + * just get a partial read. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if ((n <= 0) || !memchr(p, '\n', n)) { + if (n >= rctx->iobuflen) { + rctx->state = OHS_ERROR; + return 0; + } + goto next_io; + } + n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); + + if (n <= 0) { + if (BIO_should_retry(rctx->mem)) + goto next_io; + rctx->state = OHS_ERROR; + return 0; + } + + /* Don't allow excessive lines */ + if (n == rctx->iobuflen) { + rctx->state = OHS_ERROR; + return 0; + } + + /* First line */ + if (rctx->state == OHS_FIRSTLINE) { + if (parse_http_line1((char *)rctx->iobuf)) { + rctx->state = OHS_HEADERS; + goto next_line; + } else { + rctx->state = OHS_ERROR; + return 0; + } + } else { + /* Look for blank line: end of headers */ + for (p = rctx->iobuf; *p; p++) { + if ((*p != '\r') && (*p != '\n')) + break; + } + if (*p) + goto next_line; + + rctx->state = OHS_ASN1_HEADER; + + } + + /* Fall thru */ + + case OHS_ASN1_HEADER: + /* + * Now reading ASN1 header: can read at least 2 bytes which is enough + * for ASN1 SEQUENCE header and either length field or at least the + * length of the length field. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if (n < 2) + goto next_io; + + /* Check it is an ASN1 SEQUENCE */ + if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { + rctx->state = OHS_ERROR; + return 0; + } + + /* Check out length field */ + if (*p & 0x80) { + /* + * If MSB set on initial length octet we can now always read 6 + * octets: make sure we have them. + */ + if (n < 6) + goto next_io; + n = *p & 0x7F; + /* Not NDEF or excessive length */ + if (!n || (n > 4)) { + rctx->state = OHS_ERROR; + return 0; + } + p++; + rctx->asn1_len = 0; + for (i = 0; i < n; i++) { + rctx->asn1_len <<= 8; + rctx->asn1_len |= *p++; + } + + if (rctx->asn1_len > rctx->max_resp_len) { + rctx->state = OHS_ERROR; + return 0; + } + + rctx->asn1_len += n + 2; + } else + rctx->asn1_len = *p + 2; + + rctx->state = OHS_ASN1_CONTENT; + + /* Fall thru */ + + case OHS_ASN1_CONTENT: + n = BIO_get_mem_data(rctx->mem, NULL); + if (n < (int)rctx->asn1_len) + goto next_io; + + rctx->state = OHS_DONE; + return 1; + + break; + + case OHS_DONE: + return 1; + + } + + return 0; + +} + +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) +{ + return OCSP_REQ_CTX_nbio_d2i(rctx, + (ASN1_VALUE **)presp, + ASN1_ITEM_rptr(OCSP_RESPONSE)); +} + +/* Blocking OCSP request handler: now a special case of non-blocking I/O */ + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) +{ + OCSP_RESPONSE *resp = NULL; + OCSP_REQ_CTX *ctx; + int rv; + + ctx = OCSP_sendreq_new(b, path, req, -1); + + if (!ctx) + return NULL; + + do { + rv = OCSP_sendreq_nbio(&resp, ctx); + } while ((rv == -1) && BIO_should_retry(b)); + + OCSP_REQ_CTX_free(ctx); + + if (rv) + return resp; + + return NULL; +} +/* ocsp_lib.c */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "rand.h" +// #include "x509.h" +// #include "pem.h" +// #include "x509v3.h" +// #include "ocsp.h" +// #include "asn1t.h" + +/* Convert a certificate and its issuer to an OCSP_CERTID */ + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer) +{ + X509_NAME *iname; + ASN1_INTEGER *serial; + ASN1_BIT_STRING *ikey; +#ifndef OPENSSL_NO_SHA1 + if (!dgst) + dgst = EVP_sha1(); +#endif + if (subject) { + iname = X509_get_issuer_name(subject); + serial = X509_get_serialNumber(subject); + } else { + iname = X509_get_subject_name(issuer); + serial = NULL; + } + ikey = X509_get0_pubkey_bitstr(issuer); + return OCSP_cert_id_new(dgst, iname, ikey, serial); +} + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + X509_NAME *issuerName, + ASN1_BIT_STRING *issuerKey, + ASN1_INTEGER *serialNumber) +{ + int nid; + unsigned int i; + X509_ALGOR *alg; + OCSP_CERTID *cid = NULL; + unsigned char md[EVP_MAX_MD_SIZE]; + + if (!(cid = OCSP_CERTID_new())) + goto err; + + alg = cid->hashAlgorithm; + if (alg->algorithm != NULL) + ASN1_OBJECT_free(alg->algorithm); + if ((nid = EVP_MD_type(dgst)) == NID_undef) { + OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID); + goto err; + } + if (!(alg->algorithm = OBJ_nid2obj(nid))) + goto err; + if ((alg->parameter = ASN1_TYPE_new()) == NULL) + goto err; + alg->parameter->type = V_ASN1_NULL; + + if (!X509_NAME_digest(issuerName, dgst, md, &i)) + goto digerr; + if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) + goto err; + + /* Calculate the issuerKey hash, excluding tag and length */ + if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL)) + goto err; + + if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) + goto err; + + if (serialNumber) { + ASN1_INTEGER_free(cid->serialNumber); + if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) + goto err; + } + return cid; + digerr: + OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR); + err: + if (cid) + OCSP_CERTID_free(cid); + return NULL; +} + +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b) +{ + int ret; + ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm); + if (ret) + return ret; + ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash); + if (ret) + return ret; + return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash); +} + +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b) +{ + int ret; + ret = OCSP_id_issuer_cmp(a, b); + if (ret) + return ret; + return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber); +} + +/* + * Parse a URL and split it up into host, port and path components and + * whether it is SSL. + */ + +int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, + int *pssl) +{ + char *p, *buf; + + char *host, *port; + + *phost = NULL; + *pport = NULL; + *ppath = NULL; + + /* dup the buffer since we are going to mess with it */ + buf = BUF_strdup(url); + if (!buf) + goto mem_err; + + /* Check for initial colon */ + p = strchr(buf, ':'); + + if (!p) + goto parse_err; + + *(p++) = '\0'; + + if (!strcmp(buf, "http")) { + *pssl = 0; + port = "80"; + } else if (!strcmp(buf, "https")) { + *pssl = 1; + port = "443"; + } else + goto parse_err; + + /* Check for double slash */ + if ((p[0] != '/') || (p[1] != '/')) + goto parse_err; + + p += 2; + + host = p; + + /* Check for trailing part of path */ + + p = strchr(p, '/'); + + if (!p) + *ppath = BUF_strdup("/"); + else { + *ppath = BUF_strdup(p); + /* Set start of path to 0 so hostname is valid */ + *p = '\0'; + } + + if (!*ppath) + goto mem_err; + + p = host; + if (host[0] == '[') { + /* ipv6 literal */ + host++; + p = strchr(host, ']'); + if (!p) + goto parse_err; + *p = '\0'; + p++; + } + + /* Look for optional ':' for port number */ + if ((p = strchr(p, ':'))) { + *p = 0; + port = p + 1; + } + + *pport = BUF_strdup(port); + if (!*pport) + goto mem_err; + + *phost = BUF_strdup(host); + + if (!*phost) + goto mem_err; + + OPENSSL_free(buf); + + return 1; + + mem_err: + OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE); + goto err; + + parse_err: + OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL); + + err: + if (buf) + OPENSSL_free(buf); + if (*ppath) { + OPENSSL_free(*ppath); + *ppath = NULL; + } + if (*pport) { + OPENSSL_free(*pport); + *pport = NULL; + } + if (*phost) { + OPENSSL_free(*phost); + *phost = NULL; + } + return 0; + +} + +IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID) +/* ocsp_prn.c */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was originally part of ocsp.c and was transfered to + * Richard Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be + * included in OpenSSL or released as a patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "bio.h" +// #include "err.h" +// #include "ocsp.h" +// #include "pem.h" + +static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent) +{ + BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); + indent += 2; + BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); + i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); + BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); + i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); + BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); + i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); + BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); + i2a_ASN1_INTEGER(bp, a->serialNumber); + BIO_printf(bp, "\n"); + return 1; +} + +typedef struct { + long t; + const char *m; +} OCSP_TBLSTR; + +static const char *table2string(long s, const OCSP_TBLSTR *ts, int len) +{ + const OCSP_TBLSTR *p; + for (p = ts; p < ts + len; p++) + if (p->t == s) + return p->m; + return "(UNKNOWN)"; +} + +const char *OCSP_response_status_str(long s) +{ + static const OCSP_TBLSTR rstat_tbl[] = { + {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"}, + {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"}, + {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"}, + {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"}, + {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"}, + {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"} + }; + return table2string(s, rstat_tbl, 6); +} + +const char *OCSP_cert_status_str(long s) +{ + static const OCSP_TBLSTR cstat_tbl[] = { + {V_OCSP_CERTSTATUS_GOOD, "good"}, + {V_OCSP_CERTSTATUS_REVOKED, "revoked"}, + {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"} + }; + return table2string(s, cstat_tbl, 3); +} + +const char *OCSP_crl_reason_str(long s) +{ + static const OCSP_TBLSTR reason_tbl[] = { + {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"}, + {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"}, + {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"}, + {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"}, + {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"}, + {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"}, + {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"}, + {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"} + }; + return table2string(s, reason_tbl, 8); +} + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags) +{ + int i; + long l; + OCSP_CERTID *cid = NULL; + OCSP_ONEREQ *one = NULL; + OCSP_REQINFO *inf = o->tbsRequest; + OCSP_SIGNATURE *sig = o->optionalSignature; + + if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0) + goto err; + l = ASN1_INTEGER_get(inf->version); + if (BIO_printf(bp, " Version: %lu (0x%lx)", l + 1, l) <= 0) + goto err; + if (inf->requestorName != NULL) { + if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0) + goto err; + GENERAL_NAME_print(bp, inf->requestorName); + } + if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0) + goto err; + for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { + one = sk_OCSP_ONEREQ_value(inf->requestList, i); + cid = one->reqCert; + ocsp_certid_print(bp, cid, 8); + if (!X509V3_extensions_print(bp, + "Request Single Extensions", + one->singleRequestExtensions, flags, 8)) + goto err; + } + if (!X509V3_extensions_print(bp, "Request Extensions", + inf->requestExtensions, flags, 4)) + goto err; + if (sig) { + X509_signature_print(bp, sig->signatureAlgorithm, sig->signature); + for (i = 0; i < sk_X509_num(sig->certs); i++) { + X509_print(bp, sk_X509_value(sig->certs, i)); + PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i)); + } + } + return 1; + err: + return 0; +} + +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags) +{ + int i, ret = 0; + long l; + OCSP_CERTID *cid = NULL; + OCSP_BASICRESP *br = NULL; + OCSP_RESPID *rid = NULL; + OCSP_RESPDATA *rd = NULL; + OCSP_CERTSTATUS *cst = NULL; + OCSP_REVOKEDINFO *rev = NULL; + OCSP_SINGLERESP *single = NULL; + OCSP_RESPBYTES *rb = o->responseBytes; + + if (BIO_puts(bp, "OCSP Response Data:\n") <= 0) + goto err; + l = ASN1_ENUMERATED_get(o->responseStatus); + if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n", + OCSP_response_status_str(l), l) <= 0) + goto err; + if (rb == NULL) + return 1; + if (BIO_puts(bp, " Response Type: ") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) + goto err; + if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { + BIO_puts(bp, " (unknown response type)\n"); + return 1; + } + + if ((br = OCSP_response_get1_basic(o)) == NULL) + goto err; + rd = br->tbsResponseData; + l = ASN1_INTEGER_get(rd->version); + if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l + 1, l) <= 0) + goto err; + if (BIO_puts(bp, " Responder Id: ") <= 0) + goto err; + + rid = rd->responderId; + switch (rid->type) { + case V_OCSP_RESPID_NAME: + X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); + break; + case V_OCSP_RESPID_KEY: + i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); + break; + } + + if (BIO_printf(bp, "\n Produced At: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) + goto err; + if (BIO_printf(bp, "\n Responses:\n") <= 0) + goto err; + for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { + if (!sk_OCSP_SINGLERESP_value(rd->responses, i)) + continue; + single = sk_OCSP_SINGLERESP_value(rd->responses, i); + cid = single->certId; + if (ocsp_certid_print(bp, cid, 4) <= 0) + goto err; + cst = single->certStatus; + if (BIO_printf(bp, " Cert Status: %s", + OCSP_cert_status_str(cst->type)) <= 0) + goto err; + if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { + rev = cst->value.revoked; + if (BIO_printf(bp, "\n Revocation Time: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime)) + goto err; + if (rev->revocationReason) { + l = ASN1_ENUMERATED_get(rev->revocationReason); + if (BIO_printf(bp, + "\n Revocation Reason: %s (0x%lx)", + OCSP_crl_reason_str(l), l) <= 0) + goto err; + } + } + if (BIO_printf(bp, "\n This Update: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) + goto err; + if (single->nextUpdate) { + if (BIO_printf(bp, "\n Next Update: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + if (!X509V3_extensions_print(bp, + "Response Single Extensions", + single->singleExtensions, flags, 8)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!X509V3_extensions_print(bp, "Response Extensions", + rd->responseExtensions, flags, 4)) + goto err; + if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) + goto err; + + for (i = 0; i < sk_X509_num(br->certs); i++) { + X509_print(bp, sk_X509_value(br->certs, i)); + PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); + } + + ret = 1; + err: + OCSP_BASICRESP_free(br); + return ret; +} +/* ocsp_srv.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "rand.h" +// #include "x509.h" +// #include "pem.h" +// #include "x509v3.h" +// #include "ocsp.h" + +/* + * Utility functions related to sending OCSP responses and extracting + * relevant information from the request. + */ + +int OCSP_request_onereq_count(OCSP_REQUEST *req) +{ + return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList); +} + +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i) +{ + return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i); +} + +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one) +{ + return one->reqCert; +} + +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid) +{ + if (!cid) + return 0; + if (pmd) + *pmd = cid->hashAlgorithm->algorithm; + if (piNameHash) + *piNameHash = cid->issuerNameHash; + if (pikeyHash) + *pikeyHash = cid->issuerKeyHash; + if (pserial) + *pserial = cid->serialNumber; + return 1; +} + +int OCSP_request_is_signed(OCSP_REQUEST *req) +{ + if (req->optionalSignature) + return 1; + return 0; +} + +/* Create an OCSP response and encode an optional basic response */ +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs) +{ + OCSP_RESPONSE *rsp = NULL; + + if (!(rsp = OCSP_RESPONSE_new())) + goto err; + if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status))) + goto err; + if (!bs) + return rsp; + if (!(rsp->responseBytes = OCSP_RESPBYTES_new())) + goto err; + rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic); + if (!ASN1_item_pack + (bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response)) + goto err; + return rsp; + err: + if (rsp) + OCSP_RESPONSE_free(rsp); + return NULL; +} + +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd) +{ + OCSP_SINGLERESP *single = NULL; + OCSP_CERTSTATUS *cs; + OCSP_REVOKEDINFO *ri; + + if (!rsp->tbsResponseData->responses && + !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null())) + goto err; + + if (!(single = OCSP_SINGLERESP_new())) + goto err; + + if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate)) + goto err; + if (nextupd && + !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate)) + goto err; + + OCSP_CERTID_free(single->certId); + + if (!(single->certId = OCSP_CERTID_dup(cid))) + goto err; + + cs = single->certStatus; + switch (cs->type = status) { + case V_OCSP_CERTSTATUS_REVOKED: + if (!revtime) { + OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS, OCSP_R_NO_REVOKED_TIME); + goto err; + } + if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new())) + goto err; + if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime)) + goto err; + if (reason != OCSP_REVOKED_STATUS_NOSTATUS) { + if (!(ri->revocationReason = ASN1_ENUMERATED_new())) + goto err; + if (!(ASN1_ENUMERATED_set(ri->revocationReason, reason))) + goto err; + } + break; + + case V_OCSP_CERTSTATUS_GOOD: + cs->value.good = ASN1_NULL_new(); + break; + + case V_OCSP_CERTSTATUS_UNKNOWN: + cs->value.unknown = ASN1_NULL_new(); + break; + + default: + goto err; + + } + if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single))) + goto err; + return single; + err: + OCSP_SINGLERESP_free(single); + return NULL; +} + +/* Add a certificate to an OCSP request */ + +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) +{ + if (!resp->certs && !(resp->certs = sk_X509_new_null())) + return 0; + + if (!sk_X509_push(resp->certs, cert)) + return 0; + CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); + return 1; +} + +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags) +{ + int i; + OCSP_RESPID *rid; + + if (!X509_check_private_key(signer, key)) { + OCSPerr(OCSP_F_OCSP_BASIC_SIGN, + OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + + if (!(flags & OCSP_NOCERTS)) { + if (!OCSP_basic_add1_cert(brsp, signer)) + goto err; + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *tmpcert = sk_X509_value(certs, i); + if (!OCSP_basic_add1_cert(brsp, tmpcert)) + goto err; + } + } + + rid = brsp->tbsResponseData->responderId; + if (flags & OCSP_RESPID_KEY) { + unsigned char md[SHA_DIGEST_LENGTH]; + X509_pubkey_digest(signer, EVP_sha1(), md, NULL); + if (!(rid->value.byKey = ASN1_OCTET_STRING_new())) + goto err; + if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md, SHA_DIGEST_LENGTH))) + goto err; + rid->type = V_OCSP_RESPID_KEY; + } else { + if (!X509_NAME_set(&rid->value.byName, X509_get_subject_name(signer))) + goto err; + rid->type = V_OCSP_RESPID_NAME; + } + + if (!(flags & OCSP_NOTIME) && + !X509_gmtime_adj(brsp->tbsResponseData->producedAt, 0)) + goto err; + + /* + * Right now, I think that not doing double hashing is the right thing. + * -- Richard Levitte + */ + + if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0)) + goto err; + + return 1; + err: + return 0; +} +/* ocsp_vfy.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ocsp.h" +// #include "err.h" +#include + +static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, + STACK_OF(X509) *certs, X509_STORE *st, + unsigned long flags); +static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); +static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, + unsigned long flags); +static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, + OCSP_CERTID **ret); +static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, + STACK_OF(OCSP_SINGLERESP) *sresp); +static int ocsp_check_delegated(X509 *x, int flags); +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, + X509_NAME *nm, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + +/* Verify a basic response message */ + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags) +{ + X509 *signer, *x; + STACK_OF(X509) *chain = NULL; + STACK_OF(X509) *untrusted = NULL; + X509_STORE_CTX ctx; + int i, ret = 0; + ret = ocsp_find_signer(&signer, bs, certs, st, flags); + if (!ret) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, + OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + goto end; + } + if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + flags |= OCSP_NOVERIFY; + if (!(flags & OCSP_NOSIGS)) { + EVP_PKEY *skey; + skey = X509_get_pubkey(signer); + if (skey) { + ret = OCSP_BASICRESP_verify(bs, skey, 0); + EVP_PKEY_free(skey); + } + if (!skey || ret <= 0) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); + goto end; + } + } + if (!(flags & OCSP_NOVERIFY)) { + int init_res; + if (flags & OCSP_NOCHAIN) { + untrusted = NULL; + } else if (bs->certs && certs) { + untrusted = sk_X509_dup(bs->certs); + for (i = 0; i < sk_X509_num(certs); i++) { + if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); + goto end; + } + } + } else if (certs != NULL) { + untrusted = certs; + } else { + untrusted = bs->certs; + } + init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted); + if (!init_res) { + ret = -1; + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB); + goto end; + } + + X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); + ret = X509_verify_cert(&ctx); + chain = X509_STORE_CTX_get1_chain(&ctx); + X509_STORE_CTX_cleanup(&ctx); + if (ret <= 0) { + i = X509_STORE_CTX_get_error(&ctx); + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, + OCSP_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(i)); + goto end; + } + if (flags & OCSP_NOCHECKS) { + ret = 1; + goto end; + } + /* + * At this point we have a valid certificate chain need to verify it + * against the OCSP issuer criteria. + */ + ret = ocsp_check_issuer(bs, chain, flags); + + /* If fatal error or valid match then finish */ + if (ret != 0) + goto end; + + /* + * Easy case: explicitly trusted. Get root CA and check for explicit + * trust + */ + if (flags & OCSP_NOEXPLICIT) + goto end; + + x = sk_X509_value(chain, sk_X509_num(chain) - 1); + if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED); + goto end; + } + ret = 1; + } + + end: + if (chain) + sk_X509_pop_free(chain, X509_free); + if (bs->certs && certs) + sk_X509_free(untrusted); + return ret; +} + +static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, + STACK_OF(X509) *certs, X509_STORE *st, + unsigned long flags) +{ + X509 *signer; + OCSP_RESPID *rid = bs->tbsResponseData->responderId; + if ((signer = ocsp_find_signer_sk(certs, rid))) { + *psigner = signer; + return 2; + } + if (!(flags & OCSP_NOINTERN) && + (signer = ocsp_find_signer_sk(bs->certs, rid))) { + *psigner = signer; + return 1; + } + /* Maybe lookup from store if by subject name */ + + *psigner = NULL; + return 0; +} + +static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) +{ + int i; + unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; + X509 *x; + + /* Easy if lookup by name */ + if (id->type == V_OCSP_RESPID_NAME) + return X509_find_by_subject(certs, id->value.byName); + + /* Lookup by key hash */ + + /* If key hash isn't SHA1 length then forget it */ + if (id->value.byKey->length != SHA_DIGEST_LENGTH) + return NULL; + keyhash = id->value.byKey->data; + /* Calculate hash of each key and compare */ + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); + if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) + return x; + } + return NULL; +} + +static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, + unsigned long flags) +{ + STACK_OF(OCSP_SINGLERESP) *sresp; + X509 *signer, *sca; + OCSP_CERTID *caid = NULL; + int i; + sresp = bs->tbsResponseData->responses; + + if (sk_X509_num(chain) <= 0) { + OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN); + return -1; + } + + /* See if the issuer IDs match. */ + i = ocsp_check_ids(sresp, &caid); + + /* If ID mismatch or other error then return */ + if (i <= 0) + return i; + + signer = sk_X509_value(chain, 0); + /* Check to see if OCSP responder CA matches request CA */ + if (sk_X509_num(chain) > 1) { + sca = sk_X509_value(chain, 1); + i = ocsp_match_issuerid(sca, caid, sresp); + if (i < 0) + return i; + if (i) { + /* We have a match, if extensions OK then success */ + if (ocsp_check_delegated(signer, flags)) + return 1; + return 0; + } + } + + /* Otherwise check if OCSP request signed directly by request CA */ + return ocsp_match_issuerid(signer, caid, sresp); +} + +/* + * Check the issuer certificate IDs for equality. If there is a mismatch with + * the same algorithm then there's no point trying to match any certificates + * against the issuer. If the issuer IDs all match then we just need to check + * equality against one of them. + */ + +static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) +{ + OCSP_CERTID *tmpid, *cid; + int i, idcount; + + idcount = sk_OCSP_SINGLERESP_num(sresp); + if (idcount <= 0) { + OCSPerr(OCSP_F_OCSP_CHECK_IDS, + OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); + return -1; + } + + cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; + + *ret = NULL; + + for (i = 1; i < idcount; i++) { + tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; + /* Check to see if IDs match */ + if (OCSP_id_issuer_cmp(cid, tmpid)) { + /* If algoritm mismatch let caller deal with it */ + if (OBJ_cmp(tmpid->hashAlgorithm->algorithm, + cid->hashAlgorithm->algorithm)) + return 2; + /* Else mismatch */ + return 0; + } + } + + /* All IDs match: only need to check one ID */ + *ret = cid; + return 1; +} + +static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, + STACK_OF(OCSP_SINGLERESP) *sresp) +{ + /* If only one ID to match then do it */ + if (cid) { + const EVP_MD *dgst; + X509_NAME *iname; + int mdlen; + unsigned char md[EVP_MAX_MD_SIZE]; + if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) { + OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, + OCSP_R_UNKNOWN_MESSAGE_DIGEST); + return -1; + } + + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; + if ((cid->issuerNameHash->length != mdlen) || + (cid->issuerKeyHash->length != mdlen)) + return 0; + iname = X509_get_subject_name(cert); + if (!X509_NAME_digest(iname, dgst, md, NULL)) + return -1; + if (memcmp(md, cid->issuerNameHash->data, mdlen)) + return 0; + X509_pubkey_digest(cert, dgst, md, NULL); + if (memcmp(md, cid->issuerKeyHash->data, mdlen)) + return 0; + + return 1; + + } else { + /* We have to match the whole lot */ + int i, ret; + OCSP_CERTID *tmpid; + for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { + tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; + ret = ocsp_match_issuerid(cert, tmpid, NULL); + if (ret <= 0) + return ret; + } + return 1; + } + +} + +static int ocsp_check_delegated(X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN)) + return 1; + OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE); + return 0; +} + +/* + * Verify an OCSP request. This is fortunately much easier than OCSP response + * verify. Just find the signers certificate and verify it against a given + * trust value. + */ + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags) +{ + X509 *signer; + X509_NAME *nm; + GENERAL_NAME *gen; + int ret; + X509_STORE_CTX ctx; + if (!req->optionalSignature) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); + return 0; + } + gen = req->tbsRequest->requestorName; + if (!gen || gen->type != GEN_DIRNAME) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, + OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); + return 0; + } + nm = gen->d.directoryName; + ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags); + if (ret <= 0) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, + OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + return 0; + } + if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + flags |= OCSP_NOVERIFY; + if (!(flags & OCSP_NOSIGS)) { + EVP_PKEY *skey; + skey = X509_get_pubkey(signer); + ret = OCSP_REQUEST_verify(req, skey); + EVP_PKEY_free(skey); + if (ret <= 0) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); + return 0; + } + } + if (!(flags & OCSP_NOVERIFY)) { + int init_res; + if (flags & OCSP_NOCHAIN) + init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL); + else + init_res = X509_STORE_CTX_init(&ctx, store, signer, + req->optionalSignature->certs); + if (!init_res) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB); + return 0; + } + + X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); + X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST); + ret = X509_verify_cert(&ctx); + X509_STORE_CTX_cleanup(&ctx); + if (ret <= 0) { + ret = X509_STORE_CTX_get_error(&ctx); + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, + OCSP_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(ret)); + return 0; + } + } + return 1; +} + +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, + X509_NAME *nm, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags) +{ + X509 *signer; + if (!(flags & OCSP_NOINTERN)) { + signer = X509_find_by_subject(req->optionalSignature->certs, nm); + if (signer) { + *psigner = signer; + return 1; + } + } + + signer = X509_find_by_subject(certs, nm); + if (signer) { + *psigner = signer; + return 2; + } + return 0; +} diff --git a/Sources/COpenSSL/ofb128.c b/Sources/COpenSSL/ofb128.c new file mode 100644 index 00000000..ff8e1453 --- /dev/null +++ b/Sources/COpenSSL/ofb128.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "crypto.h" +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * The input and output encrypted as though 128bit ofb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, block128_f block) +{ + unsigned int n; + size_t l = 0; + + assert(in && out && key && ivec && num); + + n = *num; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + while (n && len) { + *(out++) = *(in++) ^ ivec[n]; + --len; + n = (n + 1) % 16; + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != + 0) + break; +# endif + while (len >= 16) { + (*block) (ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(ivec + n); + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block) (ivec, ivec, key); + while (len--) { + out[n] = in[n] ^ ivec[n]; + ++n; + } + } + *num = n; + return; + } while (0); + } + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block) (ivec, ivec, key); + } + out[l] = in[l] ^ ivec[n]; + ++l; + n = (n + 1) % 16; + } + + *num = n; +} diff --git a/Sources/COpenSSL/ofb64ede.c b/Sources/COpenSSL/ofb64ede.c new file mode 100644 index 00000000..45c67505 --- /dev/null +++ b/Sources/COpenSSL/ofb64ede.c @@ -0,0 +1,123 @@ +/* crypto/des/ofb64ede.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void DES_ede3_ofb64_encrypt(register const unsigned char *in, + register unsigned char *out, long length, + DES_key_schedule *k1, DES_key_schedule *k2, + DES_key_schedule *k3, DES_cblock *ivec, int *num) +{ + register DES_LONG v0, v1; + register int n = *num; + register long l = length; + DES_cblock d; + register char *dp; + DES_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + /* ti[0]=v0; */ + /* ti[1]=v1; */ + DES_encrypt3(ti, k1, k2, k3); + v0 = ti[0]; + v1 = ti[1]; + + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { +/*- v0=ti[0]; + v1=ti[1];*/ + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + } + v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} + +#ifdef undef /* MACRO */ +void DES_ede2_ofb64_encrypt(register unsigned char *in, + register unsigned char *out, long length, + DES_key_schedule k1, DES_key_schedule k2, + DES_cblock (*ivec), int *num) +{ + DES_ede3_ofb64_encrypt(in, out, length, k1, k2, k1, ivec, num); +} +#endif diff --git a/Sources/COpenSSL/ofb64enc.c b/Sources/COpenSSL/ofb64enc.c new file mode 100644 index 00000000..8e72dece --- /dev/null +++ b/Sources/COpenSSL/ofb64enc.c @@ -0,0 +1,109 @@ +/* crypto/des/ofb64enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void DES_ofb64_encrypt(register const unsigned char *in, + register unsigned char *out, long length, + DES_key_schedule *schedule, DES_cblock *ivec, int *num) +{ + register DES_LONG v0, v1, t; + register int n = *num; + register long l = length; + DES_cblock d; + register unsigned char *dp; + DES_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + DES_encrypt1(ti, schedule, DES_ENCRYPT); + dp = d; + t = ti[0]; + l2c(t, dp); + t = ti[1]; + l2c(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/Sources/COpenSSL/ofb_enc.c b/Sources/COpenSSL/ofb_enc.c new file mode 100644 index 00000000..02a78775 --- /dev/null +++ b/Sources/COpenSSL/ofb_enc.c @@ -0,0 +1,131 @@ +/* crypto/des/ofb_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* + * The input and output are loaded in multiples of 8 bits. What this means is + * that if you hame numbits=12 and length=2 the first 12 bits will be + * retrieved from the first byte and half the second. The second 12 bits + * will come from the 3rd and half the 4th byte. + */ +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec) +{ + register DES_LONG d0, d1, vv0, vv1, v0, v1, n = (numbits + 7) / 8; + register DES_LONG mask0, mask1; + register long l = length; + register int num = numbits; + DES_LONG ti[2]; + unsigned char *iv; + + if (num > 64) + return; + if (num > 32) { + mask0 = 0xffffffffL; + if (num >= 64) + mask1 = mask0; + else + mask1 = (1L << (num - 32)) - 1; + } else { + if (num == 32) + mask0 = 0xffffffffL; + else + mask0 = (1L << num) - 1; + mask1 = 0x00000000L; + } + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + while (l-- > 0) { + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + vv0 = ti[0]; + vv1 = ti[1]; + c2ln(in, d0, d1, n); + in += n; + d0 = (d0 ^ vv0) & mask0; + d1 = (d1 ^ vv1) & mask1; + l2cn(d0, d1, out, n); + out += n; + + if (num == 32) { + v0 = v1; + v1 = vv0; + } else if (num == 64) { + v0 = vv0; + v1 = vv1; + } else if (num > 32) { /* && num != 64 */ + v0 = ((v1 >> (num - 32)) | (vv0 << (64 - num))) & 0xffffffffL; + v1 = ((vv0 >> (num - 32)) | (vv1 << (64 - num))) & 0xffffffffL; + } else { /* num < 32 */ + + v0 = ((v0 >> num) | (v1 << (32 - num))) & 0xffffffffL; + v1 = ((v1 >> num) | (vv0 << (32 - num))) & 0xffffffffL; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = vv0 = vv1 = 0; +} diff --git a/Sources/COpenSSL/openbsd_hw.c b/Sources/COpenSSL/openbsd_hw.c new file mode 100644 index 00000000..34b0dd84 --- /dev/null +++ b/Sources/COpenSSL/openbsd_hw.c @@ -0,0 +1,453 @@ +/* Written by Ben Laurie, 2001 */ +/* + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "evp.h" +#include "objects.h" +#include "rsa.h" +#include "evp_locl.h" + +/* + * This stuff should now all be supported through + * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up + */ +static void *dummy = &dummy; + +#if 0 + +/* check flag after OpenSSL headers to ensure make depend works */ +# ifdef OPENSSL_OPENBSD_DEV_CRYPTO + +# include +# include +# include +# include +# include +# include +# include + +/* longest key supported in hardware */ +# define MAX_HW_KEY 24 +# define MAX_HW_IV 8 + +# define MD5_DIGEST_LENGTH 16 +# define MD5_CBLOCK 64 + +static int fd; +static int dev_failed; + +typedef struct session_op session_op; + +# define CDATA(ctx) EVP_C_DATA(session_op,ctx) + +static void err(const char *str) +{ + fprintf(stderr, "%s: errno %d\n", str, errno); +} + +static int dev_crypto_init(session_op *ses) +{ + if (dev_failed) + return 0; + if (!fd) { + int cryptodev_fd; + + if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) { + err("/dev/crypto"); + dev_failed = 1; + return 0; + } + if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) { + err("CRIOGET failed"); + close(cryptodev_fd); + dev_failed = 1; + return 0; + } + close(cryptodev_fd); + } + assert(ses); + memset(ses, '\0', sizeof(*ses)); + + return 1; +} + +static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx) +{ + if (ioctl(fd, CIOCFSESSION, &CDATA(ctx)->ses) == -1) + err("CIOCFSESSION failed"); + + OPENSSL_free(CDATA(ctx)->key); + + return 1; +} + +static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx, int cipher, + const unsigned char *key, int klen) +{ + if (!dev_crypto_init(CDATA(ctx))) + return 0; + + CDATA(ctx)->key = OPENSSL_malloc(MAX_HW_KEY); + if (CDATA(ctx)->key == NULL { + err("CDATA(ctx)->key memory allocation failed"); + return 0; + } + + assert(ctx->cipher->iv_len <= MAX_HW_IV); + + memcpy(CDATA(ctx)->key, key, klen); + + CDATA(ctx)->cipher = cipher; + CDATA(ctx)->keylen = klen; + + if (ioctl(fd, CIOCGSESSION, CDATA(ctx)) == -1) { + err("CIOCGSESSION failed"); + return 0; + } + return 1; +} + +static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + struct crypt_op cryp; + unsigned char lb[MAX_HW_IV]; + + if (!inl) + return 1; + + assert(CDATA(ctx)); + assert(!dev_failed); + + memset(&cryp, '\0', sizeof(cryp)); + cryp.ses = CDATA(ctx)->ses; + cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; + cryp.flags = 0; + cryp.len = inl; + assert((inl & (ctx->cipher->block_size - 1)) == 0); + cryp.src = (caddr_t) in; + cryp.dst = (caddr_t) out; + cryp.mac = 0; + if (ctx->cipher->iv_len) + cryp.iv = (caddr_t) ctx->iv; + + if (!ctx->encrypt) + memcpy(lb, &in[cryp.len - ctx->cipher->iv_len], ctx->cipher->iv_len); + + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + if (errno == EINVAL) { /* buffers are misaligned */ + unsigned int cinl = 0; + char *cin = NULL; + char *cout = NULL; + + /* NB: this can only make cinl != inl with stream ciphers */ + cinl = (inl + 3) / 4 * 4; + + if (((unsigned long)in & 3) || cinl != inl) { + cin = OPENSSL_malloc(cinl); + if (cin == NULL) { + err("cin - memory allocation failed"); + abort(); + return 0; + } + memcpy(cin, in, inl); + cryp.src = cin; + } + + if (((unsigned long)out & 3) || cinl != inl) { + cout = OPENSSL_malloc(cinl); + cryp.dst = cout; + } + + cryp.len = cinl; + + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + err("CIOCCRYPT(2) failed"); + printf("src=%p dst=%p\n", cryp.src, cryp.dst); + abort(); + return 0; + } + + if (cout) { + memcpy(out, cout, inl); + OPENSSL_free(cout); + } + if (cin) + OPENSSL_free(cin); + } else { + err("CIOCCRYPT failed"); + abort(); + return 0; + } + } + + if (ctx->encrypt) + memcpy(ctx->iv, &out[cryp.len - ctx->cipher->iv_len], + ctx->cipher->iv_len); + else + memcpy(ctx->iv, lb, ctx->cipher->iv_len); + + return 1; +} + +static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return dev_crypto_init_key(ctx, CRYPTO_3DES_CBC, key, 24); +} + +# define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher + +BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8, + 0, dev_crypto_des_ede3_init_key, + dev_crypto_cleanup, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return dev_crypto_init_key(ctx, CRYPTO_ARC4, key, 16); +} + +static const EVP_CIPHER r4_cipher = { + NID_rc4, + 1, 16, 0, /* FIXME: key should be up to 256 bytes */ + EVP_CIPH_VARIABLE_LENGTH, + dev_crypto_rc4_init_key, + dev_crypto_cipher, + dev_crypto_cleanup, + sizeof(session_op), + NULL, + NULL, + NULL +}; + +const EVP_CIPHER *EVP_dev_crypto_rc4(void) +{ + return &r4_cipher; +} + +typedef struct { + session_op sess; + char *data; + int len; + unsigned char md[EVP_MAX_MD_SIZE]; +} MD_DATA; + +static int dev_crypto_init_digest(MD_DATA *md_data, int mac) +{ + if (!dev_crypto_init(&md_data->sess)) + return 0; + + md_data->len = 0; + md_data->data = NULL; + + md_data->sess.mac = mac; + + if (ioctl(fd, CIOCGSESSION, &md_data->sess) == -1) { + err("CIOCGSESSION failed"); + return 0; + } + return 1; +} + +static int dev_crypto_cleanup_digest(MD_DATA *md_data) +{ + if (ioctl(fd, CIOCFSESSION, &md_data->sess.ses) == -1) { + err("CIOCFSESSION failed"); + return 0; + } + + return 1; +} + +/* FIXME: if device can do chained MACs, then don't accumulate */ +/* FIXME: move accumulation to the framework */ +static int dev_crypto_md5_init(EVP_MD_CTX *ctx) +{ + return dev_crypto_init_digest(ctx->md_data, CRYPTO_MD5); +} + +static int do_digest(int ses, unsigned char *md, const void *data, int len) +{ + struct crypt_op cryp; + static unsigned char md5zero[16] = { + 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e + }; + + /* some cards can't do zero length */ + if (!len) { + memcpy(md, md5zero, 16); + return 1; + } + + memset(&cryp, '\0', sizeof(cryp)); + cryp.ses = ses; + cryp.op = COP_ENCRYPT; /* required to do the MAC rather than check + * it */ + cryp.len = len; + cryp.src = (caddr_t) data; + cryp.dst = (caddr_t) data; // FIXME!!! + cryp.mac = (caddr_t) md; + + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + if (errno == EINVAL) { /* buffer is misaligned */ + char *dcopy; + + dcopy = OPENSSL_malloc(len); + if (dcopy == NULL) { + err("dcopy - memory allocation failed"); + abort(); + return 0; + } + memcpy(dcopy, data, len); + cryp.src = dcopy; + cryp.dst = cryp.src; // FIXME!!! + + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + err("CIOCCRYPT(MAC2) failed"); + abort(); + return 0; + } + OPENSSL_free(dcopy); + } else { + err("CIOCCRYPT(MAC) failed"); + abort(); + return 0; + } + } + // printf("done\n"); + + return 1; +} + +static int dev_crypto_md5_update(EVP_MD_CTX *ctx, const void *data, + unsigned long len) +{ + MD_DATA *md_data = ctx->md_data; + + if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) + return do_digest(md_data->sess.ses, md_data->md, data, len); + + md_data->data = OPENSSL_realloc(md_data->data, md_data->len + len); + if (md_data->data == NULL) { + err("DEV_CRYPTO_MD5_UPDATE: unable to allocate memory"); + abort(); + } + memcpy(md_data->data + md_data->len, data, len); + md_data->len += len; + + return 1; +} + +static int dev_crypto_md5_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + int ret; + MD_DATA *md_data = ctx->md_data; + + if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) { + memcpy(md, md_data->md, MD5_DIGEST_LENGTH); + ret = 1; + } else { + ret = do_digest(md_data->sess.ses, md, md_data->data, md_data->len); + OPENSSL_free(md_data->data); + md_data->data = NULL; + md_data->len = 0; + } + + return ret; +} + +static int dev_crypto_md5_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +{ + const MD_DATA *from_md = from->md_data; + MD_DATA *to_md = to->md_data; + + // How do we copy sessions? + assert(from->digest->flags & EVP_MD_FLAG_ONESHOT); + + to_md->data = OPENSSL_malloc(from_md->len); + if (to_md->data == NULL) { + err("DEV_CRYPTO_MD5_COPY: unable to allocate memory"); + abort(); + } + memcpy(to_md->data, from_md->data, from_md->len); + + return 1; +} + +static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx) +{ + return dev_crypto_cleanup_digest(ctx->md_data); +} + +static const EVP_MD md5_md = { + NID_md5, + NID_md5WithRSAEncryption, + MD5_DIGEST_LENGTH, + EVP_MD_FLAG_ONESHOT, // XXX: set according to device info... + dev_crypto_md5_init, + dev_crypto_md5_update, + dev_crypto_md5_final, + dev_crypto_md5_copy, + dev_crypto_md5_cleanup, + EVP_PKEY_RSA_method, + MD5_CBLOCK, + sizeof(MD_DATA), +}; + +const EVP_MD *EVP_dev_crypto_md5(void) +{ + return &md5_md; +} + +# endif +#endif diff --git a/Sources/COpenSSL/opensslconf.h b/Sources/COpenSSL/opensslconf.h new file mode 100644 index 00000000..64f235ff --- /dev/null +++ b/Sources/COpenSSL/opensslconf.h @@ -0,0 +1,274 @@ +/* opensslconf.h */ +/* WARNING: Generated automatically from opensslconf.h.in by Configure. */ + +#ifdef __cplusplus +extern "C" { +#endif +/* OpenSSL was configured with the following options: */ +#ifndef OPENSSL_SYSNAME_MACOSX +# define OPENSSL_SYSNAME_MACOSX +#endif +#ifndef OPENSSL_DOING_MAKEDEPEND + + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_GMP +# define OPENSSL_NO_GMP +#endif +#ifndef OPENSSL_NO_JPAKE +# define OPENSSL_NO_JPAKE +#endif +#ifndef OPENSSL_NO_KRB5 +# define OPENSSL_NO_KRB5 +#endif +#ifndef OPENSSL_NO_LIBUNBOUND +# define OPENSSL_NO_LIBUNBOUND +#endif +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RFC3779 +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL_TRACE +# define OPENSSL_NO_SSL_TRACE +#endif +#ifndef OPENSSL_NO_SSL2 +# define OPENSSL_NO_SSL2 +#endif +#ifndef OPENSSL_NO_STORE +# define OPENSSL_NO_STORE +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif + +#endif /* OPENSSL_DOING_MAKEDEPEND */ + +#ifndef OPENSSL_THREADS +# define OPENSSL_THREADS +#endif +#ifndef OPENSSL_NO_ASM +# define OPENSSL_NO_ASM +#endif +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define OPENSSL_NO_DYNAMIC_ENGINE +#endif + +/* The OPENSSL_NO_* macros are also defined as NO_* if the application + asks for it. This is a transient feature that is provided for those + who haven't had the time to do the appropriate changes in their + applications. */ +#ifdef OPENSSL_ALGORITHM_DEFINES +# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128) +# define NO_EC_NISTP_64_GCC_128 +# endif +# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP) +# define NO_GMP +# endif +# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE) +# define NO_JPAKE +# endif +# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) +# define NO_KRB5 +# endif +# if defined(OPENSSL_NO_LIBUNBOUND) && !defined(NO_LIBUNBOUND) +# define NO_LIBUNBOUND +# endif +# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2) +# define NO_MD2 +# endif +# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) +# define NO_RC5 +# endif +# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779) +# define NO_RFC3779 +# endif +# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP) +# define NO_SCTP +# endif +# if defined(OPENSSL_NO_SSL_TRACE) && !defined(NO_SSL_TRACE) +# define NO_SSL_TRACE +# endif +# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2) +# define NO_SSL2 +# endif +# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE) +# define NO_STORE +# endif +# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST) +# define NO_UNIT_TEST +# endif +# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS) +# define NO_WEAK_SSL_CIPHERS +# endif +#endif + +/* crypto/opensslconf.h.in */ + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define ENGINESDIR "/usr/local/ssl/lib/engines" +#define OPENSSLDIR "/usr/local/ssl" +#endif +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#define RC4_CHUNK unsigned long +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned int +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ +#ifdef __cplusplus +} +#endif diff --git a/Sources/COpenSSL/opensslv.h b/Sources/COpenSSL/opensslv.h new file mode 100644 index 00000000..73d22b39 --- /dev/null +++ b/Sources/COpenSSL/opensslv.h @@ -0,0 +1,97 @@ +#ifndef HEADER_OPENSSLV_H +# define HEADER_OPENSSLV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * Numeric release version identifier: + * MNNFFPPS: major minor fix patch status + * The status nibble has one of the values 0 for development, 1 to e for betas + * 1 to 14, and f for release. The patch level is exactly that. + * For example: + * 0.9.3-dev 0x00903000 + * 0.9.3-beta1 0x00903001 + * 0.9.3-beta2-dev 0x00903002 + * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) + * 0.9.3 0x0090300f + * 0.9.3a 0x0090301f + * 0.9.4 0x0090400f + * 1.2.3z 0x102031af + * + * For continuity reasons (because 0.9.5 is already out, and is coded + * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level + * part is slightly different, by setting the highest bit. This means + * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start + * with 0x0090600S... + * + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for + * major minor fix final patch/beta) + */ +# define OPENSSL_VERSION_NUMBER 0x1000211fL +# ifdef OPENSSL_FIPS +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2q-fips 20 Nov 2018" +# else +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2q 20 Nov 2018" +# endif +# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + +/*- + * The macros below are to be used for shared library (.so, .dll, ...) + * versioning. That kind of versioning works a bit differently between + * operating systems. The most usual scheme is to set a major and a minor + * number, and have the runtime loader check that the major number is equal + * to what it was at application link time, while the minor number has to + * be greater or equal to what it was at application link time. With this + * scheme, the version number is usually part of the file name, like this: + * + * libcrypto.so.0.9 + * + * Some unixen also make a softlink with the major verson number only: + * + * libcrypto.so.0 + * + * On Tru64 and IRIX 6.x it works a little bit differently. There, the + * shared library version is stored in the file, and is actually a series + * of versions, separated by colons. The rightmost version present in the + * library when linking an application is stored in the application to be + * matched at run time. When the application is run, a check is done to + * see if the library version stored in the application matches any of the + * versions in the version string of the library itself. + * This version string can be constructed in any way, depending on what + * kind of matching is desired. However, to implement the same scheme as + * the one used in the other unixen, all compatible versions, from lowest + * to highest, should be part of the string. Consecutive builds would + * give the following versions strings: + * + * 3.0 + * 3.0:3.1 + * 3.0:3.1:3.2 + * 4.0 + * 4.0:4.1 + * + * Notice how version 4 is completely incompatible with version, and + * therefore give the breach you can see. + * + * There may be other schemes as well that I haven't yet discovered. + * + * So, here's the way it works here: first of all, the library version + * number doesn't need at all to match the overall OpenSSL version. + * However, it's nice and more understandable if it actually does. + * The current library version is stored in the macro SHLIB_VERSION_NUMBER, + * which is just a piece of text in the format "M.m.e" (Major, minor, edit). + * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways, + * we need to keep a history of version numbers, which is done in the + * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and + * should only keep the versions that are binary compatible with the current. + */ +# define SHLIB_VERSION_HISTORY "" +# define SHLIB_VERSION_NUMBER "1.0.0" + + +#ifdef __cplusplus +} +#endif +#endif /* HEADER_OPENSSLV_H */ diff --git a/Sources/COpenSSL/ossl_typ.h b/Sources/COpenSSL/ossl_typ.h new file mode 100644 index 00000000..d5aa651c --- /dev/null +++ b/Sources/COpenSSL/ossl_typ.h @@ -0,0 +1,213 @@ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OPENSSL_TYPES_H +# define HEADER_OPENSSL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include "e_os2.h" + +# ifdef NO_ASN1_TYPEDEFS +# define ASN1_INTEGER ASN1_STRING +# define ASN1_ENUMERATED ASN1_STRING +# define ASN1_BIT_STRING ASN1_STRING +# define ASN1_OCTET_STRING ASN1_STRING +# define ASN1_PRINTABLESTRING ASN1_STRING +# define ASN1_T61STRING ASN1_STRING +# define ASN1_IA5STRING ASN1_STRING +# define ASN1_UTCTIME ASN1_STRING +# define ASN1_GENERALIZEDTIME ASN1_STRING +# define ASN1_TIME ASN1_STRING +# define ASN1_GENERALSTRING ASN1_STRING +# define ASN1_UNIVERSALSTRING ASN1_STRING +# define ASN1_BMPSTRING ASN1_STRING +# define ASN1_VISIBLESTRING ASN1_STRING +# define ASN1_UTF8STRING ASN1_STRING +# define ASN1_BOOLEAN int +# define ASN1_NULL int +# else +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +# endif + +typedef struct asn1_object_st ASN1_OBJECT; + +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_pctx_st ASN1_PCTX; + +# ifdef OPENSSL_SYS_WIN32 +# undef X509_NAME +# undef X509_EXTENSIONS +# undef X509_CERT_PAIR +# undef PKCS7_ISSUER_AND_SERIAL +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +# ifdef BIGNUM +# undef BIGNUM +# endif +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct buf_mem_st BUF_MEM; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct env_md_st EVP_MD; +typedef struct env_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; + +typedef struct rand_meth_st RAND_METHOD; + +typedef struct ecdh_method ECDH_METHOD; +typedef struct ecdsa_method ECDSA_METHOD; + +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; + +typedef struct store_st STORE; +typedef struct store_method_st STORE_METHOD; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct st_ERR_FNS ERR_FNS; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct comp_method_st COMP_METHOD; + +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + + /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ +# define DECLARE_PKCS12_STACK_OF(type)/* Nothing */ +# define IMPLEMENT_PKCS12_STACK_OF(type)/* Nothing */ + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Callback types for crypto.h */ +typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +#ifdef __cplusplus +} +#endif +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/Sources/COpenSSL/p12_.c b/Sources/COpenSSL/p12_.c new file mode 100644 index 00000000..9f497f21 --- /dev/null +++ b/Sources/COpenSSL/p12_.c @@ -0,0 +1,2612 @@ +/* p12_add.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "pkcs12.h" + +/* Pack an object into an OCTET STRING and turn into a safebag */ + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2) +{ + PKCS12_BAGS *bag; + PKCS12_SAFEBAG *safebag; + if (!(bag = PKCS12_BAGS_new())) { + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + bag->type = OBJ_nid2obj(nid1); + if (!ASN1_item_pack(obj, it, &bag->value.octet)) { + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!(safebag = PKCS12_SAFEBAG_new())) { + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + goto err; + } + safebag->value.bag = bag; + safebag->type = OBJ_nid2obj(nid2); + return safebag; + + err: + PKCS12_BAGS_free(bag); + return NULL; +} + +/* Turn PKCS8 object into a keybag */ + +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8) +{ + PKCS12_SAFEBAG *bag; + if (!(bag = PKCS12_SAFEBAG_new())) { + PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + bag->type = OBJ_nid2obj(NID_keyBag); + bag->value.keybag = p8; + return bag; +} + +/* Turn PKCS8 object into a shrouded keybag */ + +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, + int passlen, unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8) +{ + PKCS12_SAFEBAG *bag; + const EVP_CIPHER *pbe_ciph; + + /* Set up the safe bag */ + if (!(bag = PKCS12_SAFEBAG_new())) { + PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + + bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); + + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + + if (pbe_ciph) + pbe_nid = -1; + + if (!(bag->value.shkeybag = + PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter, + p8))) { + PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); + PKCS12_SAFEBAG_free(bag); + return NULL; + } + + return bag; +} + +/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */ +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) +{ + PKCS7 *p7; + if (!(p7 = PKCS7_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + p7->type = OBJ_nid2obj(NID_pkcs7_data); + if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); + goto err; + } + return p7; + + err: + PKCS7_free(p7); + return NULL; +} + +/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */ +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) +{ + if (!PKCS7_type_is_data(p7)) { + PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, + PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } + return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); +} + +/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ + +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags) +{ + PKCS7 *p7; + X509_ALGOR *pbe; + const EVP_CIPHER *pbe_ciph; + if (!(p7 = PKCS7_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, + PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); + goto err; + } + + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + + if (pbe_ciph) + pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen); + else + pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + + if (!pbe) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + goto err; + } + X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); + p7->d.encrypted->enc_data->algorithm = pbe; + M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); + if (!(p7->d.encrypted->enc_data->enc_data = + PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, + passlen, bags, 1))) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); + goto err; + } + + return p7; + + err: + PKCS7_free(p7); + return NULL; +} + +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen) +{ + if (!PKCS7_type_is_encrypted(p7)) + return NULL; + return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, + ASN1_ITEM_rptr(PKCS12_SAFEBAGS), + pass, passlen, + p7->d.encrypted->enc_data->enc_data, 1); +} + +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, + const char *pass, int passlen) +{ + return PKCS8_decrypt(bag->value.shkeybag, pass, passlen); +} + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) +{ + if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES), + &p12->authsafes->d.data)) + return 1; + return 0; +} + +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12) +{ + if (!PKCS7_type_is_data(p12->authsafes)) { + PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, + PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } + return ASN1_item_unpack(p12->authsafes->d.data, + ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); +} +/* p12_asn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +#include "asn1t.h" +// #include "pkcs12.h" + +/* PKCS#12 ASN1 module */ + +ASN1_SEQUENCE(PKCS12) = { + ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS12, authsafes, PKCS7), + ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA) +} ASN1_SEQUENCE_END(PKCS12) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS12) + +ASN1_SEQUENCE(PKCS12_MAC_DATA) = { + ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG), + ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING), + ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER) +} ASN1_SEQUENCE_END(PKCS12_MAC_DATA) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA) + +ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0); + +ASN1_ADB(PKCS12_BAGS) = { + ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)), + ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)), + ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)), +} ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL); + +ASN1_SEQUENCE(PKCS12_BAGS) = { + ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(PKCS12_BAGS), +} ASN1_SEQUENCE_END(PKCS12_BAGS) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS) + +ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0); + +ASN1_ADB(PKCS12_SAFEBAG) = { + ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)), + ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)), + ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SEQUENCE_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)), + ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), + ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), + ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)) +} ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL); + +ASN1_SEQUENCE(PKCS12_SAFEBAG) = { + ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(PKCS12_SAFEBAG), + ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE) +} ASN1_SEQUENCE_END(PKCS12_SAFEBAG) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG) + +/* SEQUENCE OF SafeBag */ +ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG) +ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS) + +/* Authsafes: SEQUENCE OF PKCS7 */ +ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7) +ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES) +/* p12_attr.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +/* Add a local keyid to a safebag */ + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID, + V_ASN1_OCTET_STRING, name, namelen)) + return 1; + else + return 0; +} + +/* Add key usage to PKCS#8 structure */ + +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage) +{ + unsigned char us_val; + us_val = (unsigned char)usage; + if (X509at_add1_attr_by_NID(&p8->attributes, NID_key_usage, + V_ASN1_BIT_STRING, &us_val, 1)) + return 1; + else + return 0; +} + +/* Add a friendlyname to a safebag */ + +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, + MBSTRING_ASC, (unsigned char *)name, namelen)) + return 1; + else + return 0; +} + +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, + MBSTRING_BMP, name, namelen)) + return 1; + else + return 0; +} + +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name, + MBSTRING_ASC, (unsigned char *)name, namelen)) + return 1; + else + return 0; +} + +ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid) +{ + X509_ATTRIBUTE *attrib; + int i; + if (!attrs) + return NULL; + for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { + attrib = sk_X509_ATTRIBUTE_value(attrs, i); + if (OBJ_obj2nid(attrib->object) == attr_nid) { + if (sk_ASN1_TYPE_num(attrib->value.set)) + return sk_ASN1_TYPE_value(attrib->value.set, 0); + else + return NULL; + } + } + return NULL; +} + +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag) +{ + ASN1_TYPE *atype; + if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) + return NULL; + if (atype->type != V_ASN1_BMPSTRING) + return NULL; + return OPENSSL_uni2asc(atype->value.bmpstring->data, + atype->value.bmpstring->length); +} +/* p12_crpt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +/* PKCS#12 PBE algorithms now in static table */ + +void PKCS12_PBE_add(void) +{ +} + +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de) +{ + PBEPARAM *pbe; + int saltlen, iter, ret; + unsigned char *salt; + const unsigned char *pbuf; + unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + + if (cipher == NULL) + return 0; + + /* Extract useful info from parameter */ + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); + return 0; + } + + pbuf = param->value.sequence->data; + if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); + return 0; + } + + if (!pbe->iter) + iter = 1; + else + iter = ASN1_INTEGER_get(pbe->iter); + salt = pbe->salt->data; + saltlen = pbe->salt->length; + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_KEY_ID, + iter, EVP_CIPHER_key_length(cipher), key, md)) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR); + PBEPARAM_free(pbe); + return 0; + } + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_IV_ID, + iter, EVP_CIPHER_iv_length(cipher), iv, md)) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR); + PBEPARAM_free(pbe); + return 0; + } + PBEPARAM_free(pbe); + ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); + return ret; +} +/* p12_crt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag); + +static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) +{ + int idx; + X509_ATTRIBUTE *attr; + idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1); + if (idx < 0) + return 1; + attr = EVP_PKEY_get_attr(pkey, idx); + if (!X509at_add1_attr(&bag->attrib, attr)) + return 0; + return 1; +} + +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype) +{ + PKCS12 *p12 = NULL; + STACK_OF(PKCS7) *safes = NULL; + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; + PKCS12_SAFEBAG *bag = NULL; + int i; + unsigned char keyid[EVP_MAX_MD_SIZE]; + unsigned int keyidlen = 0; + + /* Set defaults */ + if (!nid_cert) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + else +#endif +#ifdef OPENSSL_NO_RC2 + nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; +#else + nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; +#endif + } + if (!nid_key) + nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + if (!iter) + iter = PKCS12_DEFAULT_ITER; + if (!mac_iter) + mac_iter = 1; + + if (!pkey && !cert && !ca) { + PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT); + return NULL; + } + + if (pkey && cert) { + if (!X509_check_private_key(cert, pkey)) + return NULL; + X509_digest(cert, EVP_sha1(), keyid, &keyidlen); + } + + if (cert) { + bag = PKCS12_add_cert(&bags, cert); + if (name && !PKCS12_add_friendlyname(bag, name, -1)) + goto err; + if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + } + + /* Add all other certificates */ + for (i = 0; i < sk_X509_num(ca); i++) { + if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i))) + goto err; + } + + if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass)) + goto err; + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + + if (pkey) { + bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass); + + if (!bag) + goto err; + + if (!copy_bag_attr(bag, pkey, NID_ms_csp_name)) + goto err; + if (!copy_bag_attr(bag, pkey, NID_LocalKeySet)) + goto err; + + if (name && !PKCS12_add_friendlyname(bag, name, -1)) + goto err; + if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + } + + if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL)) + goto err; + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + + p12 = PKCS12_add_safes(safes, 0); + + if (!p12) + goto err; + + sk_PKCS7_pop_free(safes, PKCS7_free); + + safes = NULL; + + if ((mac_iter != -1) && + !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL)) + goto err; + + return p12; + + err: + + if (p12) + PKCS12_free(p12); + if (safes) + sk_PKCS7_pop_free(safes, PKCS7_free); + if (bags) + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + return NULL; + +} + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) +{ + PKCS12_SAFEBAG *bag = NULL; + char *name; + int namelen = -1; + unsigned char *keyid; + int keyidlen = -1; + + /* Add user certificate */ + if (!(bag = PKCS12_x5092certbag(cert))) + goto err; + + /* + * Use friendlyName and localKeyID in certificate. (if present) + */ + + name = (char *)X509_alias_get0(cert, &namelen); + + if (name && !PKCS12_add_friendlyname(bag, name, namelen)) + goto err; + + keyid = X509_keyid_get0(cert, &keyidlen); + + if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + + if (!pkcs12_add_bag(pbags, bag)) + goto err; + + return bag; + + err: + + if (bag) + PKCS12_SAFEBAG_free(bag); + + return NULL; + +} + +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int nid_key, char *pass) +{ + + PKCS12_SAFEBAG *bag = NULL; + PKCS8_PRIV_KEY_INFO *p8 = NULL; + + /* Make a PKCS#8 structure */ + if (!(p8 = EVP_PKEY2PKCS8(key))) + goto err; + if (key_usage && !PKCS8_add_keyusage(p8, key_usage)) + goto err; + if (nid_key != -1) { + bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8); + PKCS8_PRIV_KEY_INFO_free(p8); + } else + bag = PKCS12_MAKE_KEYBAG(p8); + + if (!bag) + goto err; + + if (!pkcs12_add_bag(pbags, bag)) + goto err; + + return bag; + + err: + + if (bag) + PKCS12_SAFEBAG_free(bag); + + return NULL; + +} + +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int nid_safe, int iter, char *pass) +{ + PKCS7 *p7 = NULL; + int free_safes = 0; + + if (!*psafes) { + *psafes = sk_PKCS7_new_null(); + if (!*psafes) + return 0; + free_safes = 1; + } else + free_safes = 0; + + if (nid_safe == 0) +#ifdef OPENSSL_NO_RC2 + nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; +#else + nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC; +#endif + + if (nid_safe == -1) + p7 = PKCS12_pack_p7data(bags); + else + p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags); + if (!p7) + goto err; + + if (!sk_PKCS7_push(*psafes, p7)) + goto err; + + return 1; + + err: + if (free_safes) { + sk_PKCS7_free(*psafes); + *psafes = NULL; + } + + if (p7) + PKCS7_free(p7); + + return 0; + +} + +static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag) +{ + int free_bags; + if (!pbags) + return 1; + if (!*pbags) { + *pbags = sk_PKCS12_SAFEBAG_new_null(); + if (!*pbags) + return 0; + free_bags = 1; + } else + free_bags = 0; + + if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) { + if (free_bags) { + sk_PKCS12_SAFEBAG_free(*pbags); + *pbags = NULL; + } + return 0; + } + + return 1; + +} + +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7) +{ + PKCS12 *p12; + if (nid_p7 <= 0) + nid_p7 = NID_pkcs7_data; + p12 = PKCS12_init(nid_p7); + + if (!p12) + return NULL; + + if (!PKCS12_pack_authsafes(p12, safes)) { + PKCS12_free(p12); + return NULL; + } + + return p12; + +} +/* p12_decr.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +/* Define this to dump decrypted output to files called DERnnn */ +/* + * #define DEBUG_DECRYPT + */ + +/* + * Encrypt/Decrypt a buffer based on password and algor, result in a + * OPENSSL_malloc'ed buffer + */ + +unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, + int passlen, unsigned char *in, int inlen, + unsigned char **data, int *datalen, int en_de) +{ + unsigned char *out; + int outlen, i; + EVP_CIPHER_CTX ctx; + + EVP_CIPHER_CTX_init(&ctx); + /* Decrypt data */ + if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen, + algor->parameter, &ctx, en_de)) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, + PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); + return NULL; + } + + if (!(out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen)) { + OPENSSL_free(out); + out = NULL; + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB); + goto err; + } + + outlen = i; + if (!EVP_CipherFinal_ex(&ctx, out + i, &i)) { + OPENSSL_free(out); + out = NULL; + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, + PKCS12_R_PKCS12_CIPHERFINAL_ERROR); + goto err; + } + outlen += i; + if (datalen) + *datalen = outlen; + if (data) + *data = out; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return out; + +} + +/* + * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer + * after use. + */ + +void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + ASN1_OCTET_STRING *oct, int zbuf) +{ + unsigned char *out; + const unsigned char *p; + void *ret; + int outlen; + + if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length, + &out, &outlen, 0)) { + PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, + PKCS12_R_PKCS12_PBE_CRYPT_ERROR); + return NULL; + } + p = out; +#ifdef DEBUG_DECRYPT + { + FILE *op; + + char fname[30]; + static int fnm = 1; + sprintf(fname, "DER%d", fnm++); + op = fopen(fname, "wb"); + fwrite(p, 1, outlen, op); + fclose(op); + } +#endif + ret = ASN1_item_d2i(NULL, &p, outlen, it); + if (zbuf) + OPENSSL_cleanse(out, outlen); + if (!ret) + PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_DECODE_ERROR); + OPENSSL_free(out); + return ret; +} + +/* + * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero + * encoding. + */ + +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf) +{ + ASN1_OCTET_STRING *oct = NULL; + unsigned char *in = NULL; + int inlen; + if (!(oct = M_ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + inlen = ASN1_item_i2d(obj, &in, it); + if (!in) { + PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR); + goto err; + } + if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data, + &oct->length, 1)) { + PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); + OPENSSL_free(in); + goto err; + } + if (zbuf) + OPENSSL_cleanse(in, inlen); + OPENSSL_free(in); + return oct; + err: + if (oct) + ASN1_OCTET_STRING_free(oct); + return NULL; +} + +IMPLEMENT_PKCS12_STACK_OF(PKCS7) +/* p12_init.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +/* Initialise a PKCS12 structure to take data */ + +PKCS12 *PKCS12_init(int mode) +{ + PKCS12 *pkcs12; + if (!(pkcs12 = PKCS12_new())) { + PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!ASN1_INTEGER_set(pkcs12->version, 3)) + goto err; + pkcs12->authsafes->type = OBJ_nid2obj(mode); + switch (mode) { + case NID_pkcs7_data: + if (!(pkcs12->authsafes->d.data = M_ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); + goto err; + } + break; + default: + PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE); + goto err; + } + + return pkcs12; + err: + if (pkcs12 != NULL) + PKCS12_free(pkcs12); + return NULL; +} +/* p12_key.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" +#include "bn.h" + +/* Uncomment out this line to get debugging info about key generation */ +/* + * #define DEBUG_KEYGEN + */ +#ifdef DEBUG_KEYGEN +# include "bio.h" +extern BIO *bio_err; +void h__dump(unsigned char *p, int len); +#endif + +/* PKCS12 compatible key/IV generation */ +#ifndef min +# define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type) +{ + int ret; + unsigned char *unipass; + int uniplen; + + if (!pass) { + unipass = NULL; + uniplen = 0; + } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { + PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE); + return 0; + } + ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, + id, iter, n, out, md_type); + if (ret <= 0) + return 0; + if (unipass) { + OPENSSL_cleanse(unipass, uniplen); /* Clear password from memory */ + OPENSSL_free(unipass); + } + return ret; +} + +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type) +{ + unsigned char *B, *D, *I, *p, *Ai; + int Slen, Plen, Ilen, Ijlen; + int i, j, u, v; + int ret = 0; + BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */ + EVP_MD_CTX ctx; +#ifdef DEBUG_KEYGEN + unsigned char *tmpout = out; + int tmpn = n; +#endif + +#if 0 + if (!pass) { + PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } +#endif + + EVP_MD_CTX_init(&ctx); +#ifdef DEBUG_KEYGEN + fprintf(stderr, "KEYGEN DEBUG\n"); + fprintf(stderr, "ID %d, ITER %d\n", id, iter); + fprintf(stderr, "Password (length %d):\n", passlen); + h__dump(pass, passlen); + fprintf(stderr, "Salt (length %d):\n", saltlen); + h__dump(salt, saltlen); +#endif + v = EVP_MD_block_size(md_type); + u = EVP_MD_size(md_type); + if (u < 0) + return 0; + D = OPENSSL_malloc(v); + Ai = OPENSSL_malloc(u); + B = OPENSSL_malloc(v + 1); + Slen = v * ((saltlen + v - 1) / v); + if (passlen) + Plen = v * ((passlen + v - 1) / v); + else + Plen = 0; + Ilen = Slen + Plen; + I = OPENSSL_malloc(Ilen); + Ij = BN_new(); + Bpl1 = BN_new(); + if (!D || !Ai || !B || !I || !Ij || !Bpl1) + goto err; + for (i = 0; i < v; i++) + D[i] = id; + p = I; + for (i = 0; i < Slen; i++) + *p++ = salt[i % saltlen]; + for (i = 0; i < Plen; i++) + *p++ = pass[i % passlen]; + for (;;) { + if (!EVP_DigestInit_ex(&ctx, md_type, NULL) + || !EVP_DigestUpdate(&ctx, D, v) + || !EVP_DigestUpdate(&ctx, I, Ilen) + || !EVP_DigestFinal_ex(&ctx, Ai, NULL)) + goto err; + for (j = 1; j < iter; j++) { + if (!EVP_DigestInit_ex(&ctx, md_type, NULL) + || !EVP_DigestUpdate(&ctx, Ai, u) + || !EVP_DigestFinal_ex(&ctx, Ai, NULL)) + goto err; + } + memcpy(out, Ai, min(n, u)); + if (u >= n) { +#ifdef DEBUG_KEYGEN + fprintf(stderr, "Output KEY (length %d)\n", tmpn); + h__dump(tmpout, tmpn); +#endif + ret = 1; + goto end; + } + n -= u; + out += u; + for (j = 0; j < v; j++) + B[j] = Ai[j % u]; + /* Work out B + 1 first then can use B as tmp space */ + if (!BN_bin2bn(B, v, Bpl1)) + goto err; + if (!BN_add_word(Bpl1, 1)) + goto err; + for (j = 0; j < Ilen; j += v) { + if (!BN_bin2bn(I + j, v, Ij)) + goto err; + if (!BN_add(Ij, Ij, Bpl1)) + goto err; + if (!BN_bn2bin(Ij, B)) + goto err; + Ijlen = BN_num_bytes(Ij); + /* If more than 2^(v*8) - 1 cut off MSB */ + if (Ijlen > v) { + if (!BN_bn2bin(Ij, B)) + goto err; + memcpy(I + j, B + 1, v); +#ifndef PKCS12_BROKEN_KEYGEN + /* If less than v bytes pad with zeroes */ + } else if (Ijlen < v) { + memset(I + j, 0, v - Ijlen); + if (!BN_bn2bin(Ij, I + j + v - Ijlen)) + goto err; +#endif + } else if (!BN_bn2bin(Ij, I + j)) + goto err; + } + } + + err: + PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE); + + end: + OPENSSL_free(Ai); + OPENSSL_free(B); + OPENSSL_free(D); + OPENSSL_free(I); + BN_free(Ij); + BN_free(Bpl1); + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +#ifdef DEBUG_KEYGEN +void h__dump(unsigned char *p, int len) +{ + for (; len--; p++) + fprintf(stderr, "%02X", *p); + fprintf(stderr, "\n"); +} +#endif +/* p12_kiss.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +/* Simplified PKCS#12 routines */ + +static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +/* + * Parse and decrypt a PKCS#12 structure returning user key, user cert and + * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it + * should point to a valid STACK structure. pkey and cert can be passed + * unitialised. + */ + +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca) +{ + STACK_OF(X509) *ocerts = NULL; + X509 *x = NULL; + + if (pkey) + *pkey = NULL; + if (cert) + *cert = NULL; + + /* Check for NULL PKCS12 structure */ + + if (!p12) { + PKCS12err(PKCS12_F_PKCS12_PARSE, + PKCS12_R_INVALID_NULL_PKCS12_POINTER); + return 0; + } + + /* Check the mac */ + + /* + * If password is zero length or NULL then try verifying both cases to + * determine which password is correct. The reason for this is that under + * PKCS#12 password based encryption no password and a zero length + * password are two different things... + */ + + if (!pass || !*pass) { + if (PKCS12_verify_mac(p12, NULL, 0)) + pass = NULL; + else if (PKCS12_verify_mac(p12, "", 0)) + pass = ""; + else { + PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); + goto err; + } + } else if (!PKCS12_verify_mac(p12, pass, -1)) { + PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); + goto err; + } + + /* Allocate stack for other certificates */ + ocerts = sk_X509_new_null(); + + if (!ocerts) { + PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { + PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); + goto err; + } + + while ((x = sk_X509_pop(ocerts))) { + if (pkey && *pkey && cert && !*cert) { + ERR_set_mark(); + if (X509_check_private_key(x, *pkey)) { + *cert = x; + x = NULL; + } + ERR_pop_to_mark(); + } + + if (ca && x) { + if (!*ca) + *ca = sk_X509_new_null(); + if (!*ca) + goto err; + if (!sk_X509_push(*ca, x)) + goto err; + x = NULL; + } + if (x) + X509_free(x); + } + + if (ocerts) + sk_X509_pop_free(ocerts, X509_free); + + return 1; + + err: + + if (pkey) { + EVP_PKEY_free(*pkey); + *pkey = NULL; + } + if (cert) { + X509_free(*cert); + *cert = NULL; + } + if (x) + X509_free(x); + if (ocerts) + sk_X509_pop_free(ocerts, X509_free); + return 0; + +} + +/* Parse the outer PKCS#12 structure */ + +static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts) +{ + STACK_OF(PKCS7) *asafes; + STACK_OF(PKCS12_SAFEBAG) *bags; + int i, bagnid; + PKCS7 *p7; + + if (!(asafes = PKCS12_unpack_authsafes(p12))) + return 0; + for (i = 0; i < sk_PKCS7_num(asafes); i++) { + p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + if (bagnid == NID_pkcs7_data) { + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = PKCS12_unpack_p7encdata(p7, pass, passlen); + } else + continue; + if (!bags) { + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + } + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 1; +} + +static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) +{ + int i; + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { + if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), + pass, passlen, pkey, ocerts)) + return 0; + } + return 1; +} + +static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts) +{ + PKCS8_PRIV_KEY_INFO *p8; + X509 *x509; + ASN1_TYPE *attrib; + ASN1_BMPSTRING *fname = NULL; + ASN1_OCTET_STRING *lkid = NULL; + + if ((attrib = PKCS12_get_attr(bag, NID_friendlyName))) + fname = attrib->value.bmpstring; + + if ((attrib = PKCS12_get_attr(bag, NID_localKeyID))) + lkid = attrib->value.octet_string; + + switch (M_PKCS12_bag_type(bag)) { + case NID_keyBag: + if (!pkey || *pkey) + return 1; + if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) + return 0; + break; + + case NID_pkcs8ShroudedKeyBag: + if (!pkey || *pkey) + return 1; + if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) + return 0; + *pkey = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (!(*pkey)) + return 0; + break; + + case NID_certBag: + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) + return 1; + if (!(x509 = PKCS12_certbag2x509(bag))) + return 0; + if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { + X509_free(x509); + return 0; + } + if (fname) { + int len, r; + unsigned char *data; + len = ASN1_STRING_to_UTF8(&data, fname); + if (len >= 0) { + r = X509_alias_set1(x509, data, len); + OPENSSL_free(data); + if (!r) { + X509_free(x509); + return 0; + } + } + } + + if (!sk_X509_push(ocerts, x509)) { + X509_free(x509); + return 0; + } + + break; + + case NID_safeContentsBag: + return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts); + break; + + default: + return 1; + break; + } + return 1; +} +/* p12_mutl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef OPENSSL_NO_HMAC +# include +# include "cryptlib.h" +# include "crypto.h" +# include "hmac.h" +# include "rand.h" +# include "pkcs12.h" + +/* Generate a MAC */ +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen) +{ + const EVP_MD *md_type; + HMAC_CTX hmac; + unsigned char key[EVP_MAX_MD_SIZE], *salt; + int saltlen, iter; + int md_size; + + if (!PKCS7_type_is_data(p12->authsafes)) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA); + return 0; + } + + salt = p12->mac->salt->data; + saltlen = p12->mac->salt->length; + if (!p12->mac->iter) + iter = 1; + else + iter = ASN1_INTEGER_get(p12->mac->iter); + if (!(md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm))) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); + return 0; + } + md_size = EVP_MD_size(md_type); + if (md_size < 0) + return 0; + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, + md_size, key, md_type)) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); + return 0; + } + HMAC_CTX_init(&hmac); + if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) + || !HMAC_Update(&hmac, p12->authsafes->d.data->data, + p12->authsafes->d.data->length) + || !HMAC_Final(&hmac, mac, maclen)) { + HMAC_CTX_cleanup(&hmac); + return 0; + } + HMAC_CTX_cleanup(&hmac); + return 1; +} + +/* Verify the mac */ +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) +{ + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + if (p12->mac == NULL) { + PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT); + return 0; + } + if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { + PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } + if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) + || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen)) + return 0; + return 1; +} + +/* Set a mac */ + +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type) +{ + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + + if (!md_type) + md_type = EVP_sha1(); + if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) { + PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR); + return 0; + } + if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { + PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } + if (!(M_ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))) { + PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR); + return 0; + } + return 1; +} + +/* Set up a mac structure */ +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, + const EVP_MD *md_type) +{ + PKCS12_MAC_DATA_free(p12->mac); + p12->mac = NULL; + + if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL) + return PKCS12_ERROR; + if (iter > 1) { + if (!(p12->mac->iter = M_ASN1_INTEGER_new())) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + } + if (!saltlen) + saltlen = PKCS12_SALT_LEN; + if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + p12->mac->salt->length = saltlen; + if (!salt) { + if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0) + return 0; + } else + memcpy(p12->mac->salt->data, salt, saltlen); + p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type)); + if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; + + return 1; +} +#endif +/* p12_npas.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "pem.h" +#include "err.h" +// #include "pkcs12.h" + +/* PKCS#12 password change routine */ + +static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass); +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, + const char *newpass); +static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, + const char *newpass); +static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen); + +/* + * Change the password on a PKCS#12 structure. + */ + +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass) +{ + /* Check for NULL PKCS12 structure */ + + if (!p12) { + PKCS12err(PKCS12_F_PKCS12_NEWPASS, + PKCS12_R_INVALID_NULL_PKCS12_POINTER); + return 0; + } + + /* Check the mac */ + + if (!PKCS12_verify_mac(p12, oldpass, -1)) { + PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE); + return 0; + } + + if (!newpass_p12(p12, oldpass, newpass)) { + PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR); + return 0; + } + + return 1; +} + +/* Parse the outer PKCS#12 structure */ + +static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) +{ + STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL; + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; + int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; + PKCS7 *p7, *p7new; + ASN1_OCTET_STRING *p12_data_tmp = NULL; + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + int rv = 0; + + if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) + goto err; + if ((newsafes = sk_PKCS7_new_null()) == NULL) + goto err; + for (i = 0; i < sk_PKCS7_num(asafes); i++) { + p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + if (bagnid == NID_pkcs7_data) { + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); + if (!alg_get(p7->d.encrypted->enc_data->algorithm, + &pbe_nid, &pbe_iter, &pbe_saltlen)) + goto err; + } else { + continue; + } + if (bags == NULL) + goto err; + if (!newpass_bags(bags, oldpass, newpass)) + goto err; + /* Repack bag in same form with new password */ + if (bagnid == NID_pkcs7_data) + p7new = PKCS12_pack_p7data(bags); + else + p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, + pbe_saltlen, pbe_iter, bags); + if (!p7new || !sk_PKCS7_push(newsafes, p7new)) + goto err; + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + } + + /* Repack safe: save old safe in case of error */ + + p12_data_tmp = p12->authsafes->d.data; + if ((p12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL) + goto err; + if (!PKCS12_pack_authsafes(p12, newsafes)) + goto err; + if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) + goto err; + if (!ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen)) + goto err; + + rv = 1; + +err: + /* Restore old safe if necessary */ + if (rv == 1) { + ASN1_OCTET_STRING_free(p12_data_tmp); + } else if (p12_data_tmp != NULL) { + ASN1_OCTET_STRING_free(p12->authsafes->d.data); + p12->authsafes->d.data = p12_data_tmp; + } + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + sk_PKCS7_pop_free(asafes, PKCS7_free); + sk_PKCS7_pop_free(newsafes, PKCS7_free); + return rv; +} + +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, + const char *newpass) +{ + int i; + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { + if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass)) + return 0; + } + return 1; +} + +/* Change password of safebag: only needs handle shrouded keybags */ + +static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, + const char *newpass) +{ + PKCS8_PRIV_KEY_INFO *p8; + X509_SIG *p8new; + int p8_nid, p8_saltlen, p8_iter; + + if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) + return 1; + + if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) + return 0; + if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen)) + return 0; + p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, + p8_iter, p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (p8new == NULL) + return 0; + X509_SIG_free(bag->value.shkeybag); + bag->value.shkeybag = p8new; + return 1; +} + +static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) +{ + PBEPARAM *pbe; + const unsigned char *p; + + p = alg->parameter->value.sequence->data; + pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); + if (!pbe) + return 0; + *pnid = OBJ_obj2nid(alg->algorithm); + *piter = ASN1_INTEGER_get(pbe->iter); + *psaltlen = pbe->salt->length; + PBEPARAM_free(pbe); + return 1; +} +/* p12_p8d.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, + int passlen) +{ + return PKCS12_item_decrypt_d2i(p8->algor, + ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass, + passlen, p8->digest, 1); +} +/* p12_p8e.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf) +{ + X509_SIG *p8 = NULL; + X509_ALGOR *pbe; + + if (!(p8 = X509_SIG_new())) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (pbe_nid == -1) + pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen); + else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) + pbe = PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, pbe_nid); + else { + ERR_clear_error(); + pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + } + if (!pbe) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB); + goto err; + } + X509_ALGOR_free(p8->algor); + p8->algor = pbe; + M_ASN1_OCTET_STRING_free(p8->digest); + p8->digest = + PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), + pass, passlen, p8inf, 1); + if (!p8->digest) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); + goto err; + } + + return p8; + + err: + X509_SIG_free(p8); + return NULL; +} +/* p12_utl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "pkcs12.h" + +/* Cheap and nasty Unicode stuff */ + +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen) +{ + int ulen, i; + unsigned char *unitmp; + if (asclen == -1) + asclen = strlen(asc); + ulen = asclen * 2 + 2; + if (!(unitmp = OPENSSL_malloc(ulen))) + return NULL; + for (i = 0; i < ulen - 2; i += 2) { + unitmp[i] = 0; + unitmp[i + 1] = asc[i >> 1]; + } + /* Make result double null terminated */ + unitmp[ulen - 2] = 0; + unitmp[ulen - 1] = 0; + if (unilen) + *unilen = ulen; + if (uni) + *uni = unitmp; + return unitmp; +} + +char *OPENSSL_uni2asc(unsigned char *uni, int unilen) +{ + int asclen, i; + char *asctmp; + + /* string must contain an even number of bytes */ + if (unilen & 1) + return NULL; + asclen = unilen / 2; + /* If no terminating zero allow for one */ + if (!unilen || uni[unilen - 1]) + asclen++; + uni++; + if (!(asctmp = OPENSSL_malloc(asclen))) + return NULL; + for (i = 0; i < unilen; i += 2) + asctmp[i >> 1] = uni[i]; + asctmp[asclen - 1] = 0; + return asctmp; +} + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12); +} + +#ifndef OPENSSL_NO_FP_API +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12); +} +#endif + +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12); +} + +#ifndef OPENSSL_NO_FP_API +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12); +} +#endif + +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509) +{ + return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509), + NID_x509Certificate, NID_certBag); +} + +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl) +{ + return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL), + NID_x509Crl, NID_crlBag); +} + +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag) +{ + if (M_PKCS12_bag_type(bag) != NID_certBag) + return NULL; + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) + return NULL; + return ASN1_item_unpack(bag->value.bag->value.octet, + ASN1_ITEM_rptr(X509)); +} + +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag) +{ + if (M_PKCS12_bag_type(bag) != NID_crlBag) + return NULL; + if (M_PKCS12_cert_bag_type(bag) != NID_x509Crl) + return NULL; + return ASN1_item_unpack(bag->value.bag->value.octet, + ASN1_ITEM_rptr(X509_CRL)); +} diff --git a/Sources/COpenSSL/p5_.c b/Sources/COpenSSL/p5_.c new file mode 100644 index 00000000..466cb28c --- /dev/null +++ b/Sources/COpenSSL/p5_.c @@ -0,0 +1,902 @@ +/* p5_crpt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include "x509.h" +#include "evp.h" + +/* + * Doesn't do anything now: Builtin PBE algorithms in static table. + */ + +void PKCS5_PBE_add(void) +{ +} + +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de) +{ + EVP_MD_CTX ctx; + unsigned char md_tmp[EVP_MAX_MD_SIZE]; + unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + int i; + PBEPARAM *pbe; + int saltlen, iter; + unsigned char *salt; + const unsigned char *pbuf; + int mdsize; + int rv = 0; + EVP_MD_CTX_init(&ctx); + + /* Extract useful info from parameter */ + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + return 0; + } + + pbuf = param->value.sequence->data; + if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { + EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + return 0; + } + + if (!pbe->iter) + iter = 1; + else + iter = ASN1_INTEGER_get(pbe->iter); + salt = pbe->salt->data; + saltlen = pbe->salt->length; + + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + + if (!EVP_DigestInit_ex(&ctx, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, pass, passlen)) + goto err; + if (!EVP_DigestUpdate(&ctx, salt, saltlen)) + goto err; + PBEPARAM_free(pbe); + if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) + goto err; + mdsize = EVP_MD_size(md); + if (mdsize < 0) + return 0; + for (i = 1; i < iter; i++) { + if (!EVP_DigestInit_ex(&ctx, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) + goto err; + } + OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp)); + memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher)); + OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16); + memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), + EVP_CIPHER_iv_length(cipher)); + if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) + goto err; + OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); + rv = 1; + err: + EVP_MD_CTX_cleanup(&ctx); + return rv; +} +/* p5_crpt2.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include +// #include "cryptlib.h" +#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA) +# include "x509.h" +# include "evp.h" +# include "hmac.h" +# include "evp_locl.h" + +/* set this to print out info about the keygen algorithm */ +/* #define DEBUG_PKCS5V2 */ + +# ifdef DEBUG_PKCS5V2 +static void h__dump(const unsigned char *p, int len); +# endif + +/* + * This is an implementation of PKCS#5 v2.0 password based encryption key + * derivation function PBKDF2. SHA1 version verified against test vectors + * posted by Peter Gutmann to the PKCS-TNG + * mailing list. + */ + +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out) +{ + unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; + int cplen, j, k, tkeylen, mdlen; + unsigned long i = 1; + HMAC_CTX hctx_tpl, hctx; + + mdlen = EVP_MD_size(digest); + if (mdlen < 0) + return 0; + + HMAC_CTX_init(&hctx_tpl); + p = out; + tkeylen = keylen; + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + while (tkeylen) { + if (tkeylen > mdlen) + cplen = mdlen; + else + cplen = tkeylen; + /* + * We are unlikely to ever use more than 256 blocks (5120 bits!) but + * just in case... + */ + itmp[0] = (unsigned char)((i >> 24) & 0xff); + itmp[1] = (unsigned char)((i >> 16) & 0xff); + itmp[2] = (unsigned char)((i >> 8) & 0xff); + itmp[3] = (unsigned char)(i & 0xff); + if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + if (!HMAC_Update(&hctx, salt, saltlen) + || !HMAC_Update(&hctx, itmp, 4) + || !HMAC_Final(&hctx, digtmp, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + HMAC_CTX_cleanup(&hctx); + return 0; + } + HMAC_CTX_cleanup(&hctx); + memcpy(p, digtmp, cplen); + for (j = 1; j < iter; j++) { + if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + if (!HMAC_Update(&hctx, digtmp, mdlen) + || !HMAC_Final(&hctx, digtmp, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + HMAC_CTX_cleanup(&hctx); + return 0; + } + HMAC_CTX_cleanup(&hctx); + for (k = 0; k < cplen; k++) + p[k] ^= digtmp[k]; + } + tkeylen -= cplen; + i++; + p += cplen; + } + HMAC_CTX_cleanup(&hctx_tpl); +# ifdef DEBUG_PKCS5V2 + fprintf(stderr, "Password:\n"); + h__dump(pass, passlen); + fprintf(stderr, "Salt:\n"); + h__dump(salt, saltlen); + fprintf(stderr, "Iteration count %d\n", iter); + fprintf(stderr, "Key:\n"); + h__dump(out, keylen); +# endif + return 1; +} + +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out) +{ + return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), + keylen, out); +} + +# ifdef DO_TEST +main() +{ + unsigned char out[4]; + unsigned char salt[] = { 0x12, 0x34, 0x56, 0x78 }; + PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out); + fprintf(stderr, "Out %02X %02X %02X %02X\n", + out[0], out[1], out[2], out[3]); +} + +# endif + +/* + * Now the key derivation function itself. This is a bit evil because it has + * to check the ASN1 parameters are valid: and there are quite a few of + * them... + */ + +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *c, + const EVP_MD *md, int en_de) +{ + const unsigned char *pbuf; + int plen; + PBE2PARAM *pbe2 = NULL; + const EVP_CIPHER *cipher; + + int rv = 0; + + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + pbuf = param->value.sequence->data; + plen = param->value.sequence->length; + if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + /* See if we recognise the key derivation function */ + + if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, + EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); + goto err; + } + + /* + * lets see if we recognise the encryption algorithm. + */ + + cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm); + + if (!cipher) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* Fixup cipher based on AlgorithmIdentifier */ + if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de)) + goto err; + if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR); + goto err; + } + rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen, + pbe2->keyfunc->parameter, c, md, en_de); + err: + PBE2PARAM_free(pbe2); + return rv; +} + +int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de) +{ + unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; + const unsigned char *pbuf; + int saltlen, iter, plen; + int rv = 0; + unsigned int keylen = 0; + int prf_nid, hmac_md_nid; + PBKDF2PARAM *kdf = NULL; + const EVP_MD *prfmd; + + if (EVP_CIPHER_CTX_cipher(ctx) == NULL) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET); + goto err; + } + keylen = EVP_CIPHER_CTX_key_length(ctx); + OPENSSL_assert(keylen <= sizeof(key)); + + /* Decode parameter */ + + if (!param || (param->type != V_ASN1_SEQUENCE)) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + pbuf = param->value.sequence->data; + plen = param->value.sequence->length; + + if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen))) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + keylen = EVP_CIPHER_CTX_key_length(ctx); + + /* Now check the parameters of the kdf */ + + if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH); + goto err; + } + + if (kdf->prf) + prf_nid = OBJ_obj2nid(kdf->prf->algorithm); + else + prf_nid = NID_hmacWithSHA1; + + if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); + goto err; + } + + prfmd = EVP_get_digestbynid(hmac_md_nid); + if (prfmd == NULL) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); + goto err; + } + + if (kdf->salt->type != V_ASN1_OCTET_STRING) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE); + goto err; + } + + /* it seems that its all OK */ + salt = kdf->salt->value.octet_string->data; + saltlen = kdf->salt->value.octet_string->length; + iter = ASN1_INTEGER_get(kdf->iter); + if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, + keylen, key)) + goto err; + rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); + err: + OPENSSL_cleanse(key, keylen); + PBKDF2PARAM_free(kdf); + return rv; +} + +# ifdef DEBUG_PKCS5V2 +static void h__dump(const unsigned char *p, int len) +{ + for (; len--; p++) + fprintf(stderr, "%02X ", *p); + fprintf(stderr, "\n"); +} +# endif +#endif +/* p5_pbe.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +#include "asn1t.h" +// #include "x509.h" +#include "rand.h" + +/* PKCS#5 password based encryption structure */ + +ASN1_SEQUENCE(PBEPARAM) = { + ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING), + ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER) +} ASN1_SEQUENCE_END(PBEPARAM) + +IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM) + +/* Set an algorithm identifier for a PKCS#5 PBE algorithm */ + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen) +{ + PBEPARAM *pbe = NULL; + ASN1_STRING *pbe_str = NULL; + unsigned char *sstr; + + pbe = PBEPARAM_new(); + if (!pbe) { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + goto err; + } + if (iter <= 0) + iter = PKCS5_DEFAULT_ITER; + if (!ASN1_INTEGER_set(pbe->iter, iter)) { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!saltlen) + saltlen = PKCS5_SALT_LEN; + if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + goto err; + } + sstr = ASN1_STRING_data(pbe->salt); + if (salt) + memcpy(sstr, salt, saltlen); + else if (RAND_bytes(sstr, saltlen) <= 0) + goto err; + + if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + goto err; + } + + PBEPARAM_free(pbe); + pbe = NULL; + + if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) + return 1; + + err: + if (pbe != NULL) + PBEPARAM_free(pbe); + if (pbe_str != NULL) + ASN1_STRING_free(pbe_str); + return 0; +} + +/* Return an algorithm identifier for a PKCS#5 PBE algorithm */ + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen) +{ + X509_ALGOR *ret; + ret = X509_ALGOR_new(); + if (!ret) { + ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen)) + return ret; + + X509_ALGOR_free(ret); + return NULL; +} +/* p5_pbev2.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999-2004. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" +// #include "rand.h" + +/* PKCS#5 v2.0 password based encryption structures */ + +ASN1_SEQUENCE(PBE2PARAM) = { + ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR), + ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR) +} ASN1_SEQUENCE_END(PBE2PARAM) + +IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM) + +ASN1_SEQUENCE(PBKDF2PARAM) = { + ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY), + ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER), + ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER), + ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR) +} ASN1_SEQUENCE_END(PBKDF2PARAM) + +IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM) + +/* + * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know + * this is horrible! Extended version to allow application supplied PRF NID + * and IV. + */ + +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid) +{ + X509_ALGOR *scheme = NULL, *ret = NULL; + int alg_nid, keylen; + EVP_CIPHER_CTX ctx; + unsigned char iv[EVP_MAX_IV_LENGTH]; + PBE2PARAM *pbe2 = NULL; + + alg_nid = EVP_CIPHER_type(cipher); + if (alg_nid == NID_undef) { + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, + ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + goto err; + } + + if (!(pbe2 = PBE2PARAM_new())) + goto merr; + + /* Setup the AlgorithmIdentifier for the encryption scheme */ + scheme = pbe2->encryption; + + scheme->algorithm = OBJ_nid2obj(alg_nid); + if (!(scheme->parameter = ASN1_TYPE_new())) + goto merr; + + /* Create random IV */ + if (EVP_CIPHER_iv_length(cipher)) { + if (aiv) + memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); + else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0) + goto err; + } + + EVP_CIPHER_CTX_init(&ctx); + + /* Dummy cipherinit to just setup the IV, and PRF */ + if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0)) + goto err; + if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); + EVP_CIPHER_CTX_cleanup(&ctx); + goto err; + } + /* + * If prf NID unspecified see if cipher has a preference. An error is OK + * here: just means use default PRF. + */ + if ((prf_nid == -1) && + EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { + ERR_clear_error(); + prf_nid = NID_hmacWithSHA1; + } + EVP_CIPHER_CTX_cleanup(&ctx); + + /* If its RC2 then we'd better setup the key length */ + + if (alg_nid == NID_rc2_cbc) + keylen = EVP_CIPHER_key_length(cipher); + else + keylen = -1; + + /* Setup keyfunc */ + + X509_ALGOR_free(pbe2->keyfunc); + + pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen); + + if (!pbe2->keyfunc) + goto merr; + + /* Now set up top level AlgorithmIdentifier */ + + if (!(ret = X509_ALGOR_new())) + goto merr; + if (!(ret->parameter = ASN1_TYPE_new())) + goto merr; + + ret->algorithm = OBJ_nid2obj(NID_pbes2); + + /* Encode PBE2PARAM into parameter */ + + if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM), + &ret->parameter->value.sequence)) + goto merr; + ret->parameter->type = V_ASN1_SEQUENCE; + + PBE2PARAM_free(pbe2); + pbe2 = NULL; + + return ret; + + merr: + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE); + + err: + PBE2PARAM_free(pbe2); + /* Note 'scheme' is freed as part of pbe2 */ + X509_ALGOR_free(ret); + + return NULL; +} + +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen) +{ + return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1); +} + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen) +{ + X509_ALGOR *keyfunc = NULL; + PBKDF2PARAM *kdf = NULL; + ASN1_OCTET_STRING *osalt = NULL; + + if (!(kdf = PBKDF2PARAM_new())) + goto merr; + if (!(osalt = M_ASN1_OCTET_STRING_new())) + goto merr; + + kdf->salt->value.octet_string = osalt; + kdf->salt->type = V_ASN1_OCTET_STRING; + + if (!saltlen) + saltlen = PKCS5_SALT_LEN; + if (!(osalt->data = OPENSSL_malloc(saltlen))) + goto merr; + + osalt->length = saltlen; + + if (salt) + memcpy(osalt->data, salt, saltlen); + else if (RAND_bytes(osalt->data, saltlen) <= 0) + goto merr; + + if (iter <= 0) + iter = PKCS5_DEFAULT_ITER; + + if (!ASN1_INTEGER_set(kdf->iter, iter)) + goto merr; + + /* If have a key len set it up */ + + if (keylen > 0) { + if (!(kdf->keylength = M_ASN1_INTEGER_new())) + goto merr; + if (!ASN1_INTEGER_set(kdf->keylength, keylen)) + goto merr; + } + + /* prf can stay NULL if we are using hmacWithSHA1 */ + if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) { + kdf->prf = X509_ALGOR_new(); + if (!kdf->prf) + goto merr; + X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL); + } + + /* Finally setup the keyfunc structure */ + + keyfunc = X509_ALGOR_new(); + if (!keyfunc) + goto merr; + + keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); + + /* Encode PBKDF2PARAM into parameter of pbe2 */ + + if (!(keyfunc->parameter = ASN1_TYPE_new())) + goto merr; + + if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM), + &keyfunc->parameter->value.sequence)) + goto merr; + keyfunc->parameter->type = V_ASN1_SEQUENCE; + + PBKDF2PARAM_free(kdf); + return keyfunc; + + merr: + ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE); + PBKDF2PARAM_free(kdf); + X509_ALGOR_free(keyfunc); + return NULL; +} diff --git a/Sources/COpenSSL/p8_pkey.c b/Sources/COpenSSL/p8_pkey.c new file mode 100644 index 00000000..b7d90ae5 --- /dev/null +++ b/Sources/COpenSSL/p8_pkey.c @@ -0,0 +1,145 @@ +/* p8_pkey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "asn1t.h" +#include "x509.h" + +/* Minor tweak to operation: zero private key data */ +static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + /* Since the structure must still be valid use ASN1_OP_FREE_PRE */ + if (operation == ASN1_OP_FREE_PRE) { + PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval; + if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING + && key->pkey->value.octet_string != NULL) + OPENSSL_cleanse(key->pkey->value.octet_string->data, + key->pkey->value.octet_string->length); + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = { + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY), + ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0) +} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, + int ptype, void *pval, unsigned char *penc, int penclen) +{ + unsigned char **ppenc = NULL; + if (version >= 0) { + if (!ASN1_INTEGER_set(priv->version, version)) + return 0; + } + if (penc) { + int pmtype; + ASN1_OCTET_STRING *oct; + oct = ASN1_OCTET_STRING_new(); + if (!oct) + return 0; + oct->data = penc; + ppenc = &oct->data; + oct->length = penclen; + if (priv->broken == PKCS8_NO_OCTET) + pmtype = V_ASN1_SEQUENCE; + else + pmtype = V_ASN1_OCTET_STRING; + ASN1_TYPE_set(priv->pkey, pmtype, oct); + } + if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) { + /* If call fails do not swallow 'enc' */ + if (ppenc) + *ppenc = NULL; + return 0; + } + return 1; +} + +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8) +{ + if (ppkalg) + *ppkalg = p8->pkeyalg->algorithm; + if (p8->pkey->type == V_ASN1_OCTET_STRING) { + p8->broken = PKCS8_OK; + if (pk) { + *pk = p8->pkey->value.octet_string->data; + *ppklen = p8->pkey->value.octet_string->length; + } + } else if (p8->pkey->type == V_ASN1_SEQUENCE) { + p8->broken = PKCS8_NO_OCTET; + if (pk) { + *pk = p8->pkey->value.sequence->data; + *ppklen = p8->pkey->value.sequence->length; + } + } else + return 0; + if (pa) + *pa = p8->pkeyalg; + return 1; +} diff --git a/Sources/COpenSSL/p_.c b/Sources/COpenSSL/p_.c new file mode 100644 index 00000000..360c6b67 --- /dev/null +++ b/Sources/COpenSSL/p_.c @@ -0,0 +1,1137 @@ +/* crypto/evp/p_dec.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "rand.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#include "evp.h" +#include "objects.h" +#include "x509.h" + +int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl, + EVP_PKEY *priv) +{ + int ret = -1; + +#ifndef OPENSSL_NO_RSA + if (priv->type != EVP_PKEY_RSA) { +#endif + EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); +#ifndef OPENSSL_NO_RSA + goto err; + } + + ret = + RSA_private_decrypt(ekl, ek, key, priv->pkey.rsa, RSA_PKCS1_PADDING); + err: +#endif + return (ret); +} +/* crypto/evp/p_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "rand.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +// #include "evp.h" +// #include "objects.h" +// #include "x509.h" + +int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, + int key_len, EVP_PKEY *pubk) +{ + int ret = 0; + +#ifndef OPENSSL_NO_RSA + if (pubk->type != EVP_PKEY_RSA) { +#endif + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); +#ifndef OPENSSL_NO_RSA + goto err; + } + ret = + RSA_public_encrypt(key_len, key, ek, pubk->pkey.rsa, + RSA_PKCS1_PADDING); + err: +#endif + return (ret); +} +/* crypto/evp/p_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "bn.h" +#include "err.h" +// #include "objects.h" +// #include "evp.h" +#include "asn1_mac.h" +// #include "x509.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +#include "asn1_locl.h" + +static void EVP_PKEY_free_it(EVP_PKEY *x); + +int EVP_PKEY_bits(EVP_PKEY *pkey) +{ + if (pkey && pkey->ameth && pkey->ameth->pkey_bits) + return pkey->ameth->pkey_bits(pkey); + return 0; +} + +int EVP_PKEY_size(EVP_PKEY *pkey) +{ + if (pkey && pkey->ameth && pkey->ameth->pkey_size) + return pkey->ameth->pkey_size(pkey); + return 0; +} + +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) +{ +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) { + int ret = pkey->save_parameters; + + if (mode >= 0) + pkey->save_parameters = mode; + return (ret); + } +#endif +#ifndef OPENSSL_NO_EC + if (pkey->type == EVP_PKEY_EC) { + int ret = pkey->save_parameters; + + if (mode >= 0) + pkey->save_parameters = mode; + return (ret); + } +#endif + return (0); +} + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + if (to->type != from->type) { + EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES); + goto err; + } + + if (EVP_PKEY_missing_parameters(from)) { + EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS); + goto err; + } + + if (!EVP_PKEY_missing_parameters(to)) { + if (EVP_PKEY_cmp_parameters(to, from) == 1) + return 1; + EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS); + return 0; + } + + if (from->ameth && from->ameth->param_copy) + return from->ameth->param_copy(to, from); + err: + return 0; +} + +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) +{ + if (pkey->ameth && pkey->ameth->param_missing) + return pkey->ameth->param_missing(pkey); + return 0; +} + +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (a->type != b->type) + return -1; + if (a->ameth && a->ameth->param_cmp) + return a->ameth->param_cmp(a, b); + return -2; +} + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (a->type != b->type) + return -1; + + if (a->ameth) { + int ret; + /* Compare parameters if the algorithm has them */ + if (a->ameth->param_cmp) { + ret = a->ameth->param_cmp(a, b); + if (ret <= 0) + return ret; + } + + if (a->ameth->pub_cmp) + return a->ameth->pub_cmp(a, b); + } + + return -2; +} + +EVP_PKEY *EVP_PKEY_new(void) +{ + EVP_PKEY *ret; + + ret = (EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY)); + if (ret == NULL) { + EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->type = EVP_PKEY_NONE; + ret->save_type = EVP_PKEY_NONE; + ret->references = 1; + ret->ameth = NULL; + ret->engine = NULL; + ret->pkey.ptr = NULL; + ret->attributes = NULL; + ret->save_parameters = 1; + return (ret); +} + +/* + * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey + * is NULL just return 1 or 0 if the algorithm exists. + */ + +static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *e = NULL; + if (pkey) { + if (pkey->pkey.ptr) + EVP_PKEY_free_it(pkey); + /* + * If key type matches and a method exists then this lookup has + * succeeded once so just indicate success. + */ + if ((type == pkey->save_type) && pkey->ameth) + return 1; +#ifndef OPENSSL_NO_ENGINE + /* If we have an ENGINE release it */ + if (pkey->engine) { + ENGINE_finish(pkey->engine); + pkey->engine = NULL; + } +#endif + } + if (str) + ameth = EVP_PKEY_asn1_find_str(&e, str, len); + else + ameth = EVP_PKEY_asn1_find(&e, type); +#ifndef OPENSSL_NO_ENGINE + if (!pkey && e) + ENGINE_finish(e); +#endif + if (!ameth) { + EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + if (pkey) { + pkey->ameth = ameth; + pkey->engine = e; + + pkey->type = pkey->ameth->pkey_id; + pkey->save_type = type; + } + return 1; +} + +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) +{ + return pkey_set_type(pkey, type, NULL, -1); +} + +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) +{ + return pkey_set_type(pkey, EVP_PKEY_NONE, str, len); +} + +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) +{ + if (pkey == NULL || !EVP_PKEY_set_type(pkey, type)) + return 0; + pkey->pkey.ptr = key; + return (key != NULL); +} + +void *EVP_PKEY_get0(EVP_PKEY *pkey) +{ + return pkey->pkey.ptr; +} + +#ifndef OPENSSL_NO_RSA +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) +{ + int ret = EVP_PKEY_assign_RSA(pkey, key); + if (ret) + RSA_up_ref(key); + return ret; +} + +RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY); + return NULL; + } + RSA_up_ref(pkey->pkey.rsa); + return pkey->pkey.rsa; +} +#endif + +#ifndef OPENSSL_NO_DSA +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) +{ + int ret = EVP_PKEY_assign_DSA(pkey, key); + if (ret) + DSA_up_ref(key); + return ret; +} + +DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_DSA) { + EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY); + return NULL; + } + DSA_up_ref(pkey->pkey.dsa); + return pkey->pkey.dsa; +} +#endif + +#ifndef OPENSSL_NO_EC + +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) +{ + int ret = EVP_PKEY_assign_EC_KEY(pkey, key); + if (ret) + EC_KEY_up_ref(key); + return ret; +} + +EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_EC) { + EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY); + return NULL; + } + EC_KEY_up_ref(pkey->pkey.ec); + return pkey->pkey.ec; +} +#endif + +#ifndef OPENSSL_NO_DH + +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) +{ + int ret = EVP_PKEY_assign_DH(pkey, key); + if (ret) + DH_up_ref(key); + return ret; +} + +DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) { + EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY); + return NULL; + } + DH_up_ref(pkey->pkey.dh); + return pkey->pkey.dh; +} +#endif + +int EVP_PKEY_type(int type) +{ + int ret; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *e; + ameth = EVP_PKEY_asn1_find(&e, type); + if (ameth) + ret = ameth->pkey_id; + else + ret = NID_undef; +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + return ret; +} + +int EVP_PKEY_id(const EVP_PKEY *pkey) +{ + return pkey->type; +} + +int EVP_PKEY_base_id(const EVP_PKEY *pkey) +{ + return EVP_PKEY_type(pkey->type); +} + +void EVP_PKEY_free(EVP_PKEY *x) +{ + int i; + + if (x == NULL) + return; + + i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", x); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "EVP_PKEY_free, bad reference count\n"); + abort(); + } +#endif + EVP_PKEY_free_it(x); + if (x->attributes) + sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); + OPENSSL_free(x); +} + +static void EVP_PKEY_free_it(EVP_PKEY *x) +{ + if (x->ameth && x->ameth->pkey_free) { + x->ameth->pkey_free(x); + x->pkey.ptr = NULL; + } +#ifndef OPENSSL_NO_ENGINE + if (x->engine) { + ENGINE_finish(x->engine); + x->engine = NULL; + } +#endif +} + +static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, + const char *kstr) +{ + BIO_indent(out, indent, 128); + BIO_printf(out, "%s algorithm \"%s\" unsupported\n", + kstr, OBJ_nid2ln(pkey->type)); + return 1; +} + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->pub_print) + return pkey->ameth->pub_print(out, pkey, indent, pctx); + + return unsup_alg(out, pkey, indent, "Public Key"); +} + +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->priv_print) + return pkey->ameth->priv_print(out, pkey, indent, pctx); + + return unsup_alg(out, pkey, indent, "Private Key"); +} + +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->param_print) + return pkey->ameth->param_print(out, pkey, indent, pctx); + return unsup_alg(out, pkey, indent, "Parameters"); +} + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) +{ + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return -2; + return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, + 0, pnid); +} +/* crypto/evp/p_open.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" + +#ifndef OPENSSL_NO_RSA + +# include "evp.h" +# include "objects.h" +# include "x509.h" +# include "rsa.h" + +int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, + EVP_PKEY *priv) +{ + unsigned char *key = NULL; + int i, size = 0, ret = 0; + + if (type) { + EVP_CIPHER_CTX_init(ctx); + if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL)) + return 0; + } + + if (!priv) + return 1; + + if (priv->type != EVP_PKEY_RSA) { + EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA); + goto err; + } + + size = RSA_size(priv->pkey.rsa); + key = (unsigned char *)OPENSSL_malloc(size + 2); + if (key == NULL) { + /* ERROR */ + EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE); + goto err; + } + + i = EVP_PKEY_decrypt_old(key, ek, ekl, priv); + if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) { + /* ERROR */ + goto err; + } + if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) + goto err; + + ret = 1; + err: + if (key != NULL) + OPENSSL_cleanse(key, size); + OPENSSL_free(key); + return (ret); +} + +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + + i = EVP_DecryptFinal_ex(ctx, out, outl); + if (i) + i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); + return (i); +} +#else /* !OPENSSL_NO_RSA */ + +# ifdef PEDANTIC +static void *dummy = &dummy; +# endif + +#endif +/* crypto/evp/p_seal.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "rand.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +// #include "evp.h" +// #include "objects.h" +// #include "x509.h" + +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk) +{ + unsigned char key[EVP_MAX_KEY_LENGTH]; + int i; + + if (type) { + EVP_CIPHER_CTX_init(ctx); + if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL)) + return 0; + } + if ((npubk <= 0) || !pubk) + return 1; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) + return 0; + if (EVP_CIPHER_CTX_iv_length(ctx) + && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0) + return 0; + + if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) + return 0; + + for (i = 0; i < npubk; i++) { + ekl[i] = + EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx), + pubk[i]); + if (ekl[i] <= 0) + return (-1); + } + return (npubk); +} + +/*- MACRO +void EVP_SealUpdate(ctx,out,outl,in,inl) +EVP_CIPHER_CTX *ctx; +unsigned char *out; +int *outl; +unsigned char *in; +int inl; + { + EVP_EncryptUpdate(ctx,out,outl,in,inl); + } +*/ + +int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + i = EVP_EncryptFinal_ex(ctx, out, outl); + if (i) + i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL); + return i; +} +/* crypto/evp/p_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "objects.h" +// #include "x509.h" + +#ifdef undef +void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) +{ + EVP_DigestInit_ex(ctx, type); +} + +void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) +{ + EVP_DigestUpdate(ctx, data, count); +} +#endif + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey) +{ + unsigned char m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int i = 0, ok = 0, v; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + + *siglen = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + goto err; + if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len)) + goto err; + EVP_MD_CTX_cleanup(&tmp_ctx); + + if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { + size_t sltmp = (size_t)EVP_PKEY_size(pkey); + i = 0; + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx) + goto err; + if (EVP_PKEY_sign_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) + goto err; + if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) + goto err; + *siglen = sltmp; + i = 1; + err: + EVP_PKEY_CTX_free(pkctx); + return i; + } + + for (i = 0; i < 4; i++) { + v = ctx->digest->required_pkey_type[i]; + if (v == 0) + break; + if (pkey->type == v) { + ok = 1; + break; + } + } + if (!ok) { + EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE); + return (0); + } + + if (ctx->digest->sign == NULL) { + EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_NO_SIGN_FUNCTION_CONFIGURED); + return (0); + } + return (ctx->digest->sign(ctx->digest->type, m, m_len, sigret, siglen, + pkey->pkey.ptr)); +} +/* crypto/evp/p_verify.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "objects.h" +// #include "x509.h" + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey) +{ + unsigned char m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int i = 0, ok = 0, v; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + goto err; + if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len)) + goto err; + EVP_MD_CTX_cleanup(&tmp_ctx); + + if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { + i = -1; + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx) + goto err; + if (EVP_PKEY_verify_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) + goto err; + i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); + err: + EVP_PKEY_CTX_free(pkctx); + return i; + } + + for (i = 0; i < 4; i++) { + v = ctx->digest->required_pkey_type[i]; + if (v == 0) + break; + if (pkey->type == v) { + ok = 1; + break; + } + } + if (!ok) { + EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE); + return (-1); + } + if (ctx->digest->verify == NULL) { + EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED); + return (0); + } + + return (ctx->digest->verify(ctx->digest->type, m, m_len, + sigbuf, siglen, pkey->pkey.ptr)); +} diff --git a/Sources/COpenSSL/pcbc_enc.c b/Sources/COpenSSL/pcbc_enc.c new file mode 100644 index 00000000..144d5ed8 --- /dev/null +++ b/Sources/COpenSSL/pcbc_enc.c @@ -0,0 +1,115 @@ +/* crypto/des/pcbc_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc) +{ + register DES_LONG sin0, sin1, xor0, xor1, tout0, tout1; + DES_LONG tin[2]; + const unsigned char *in; + unsigned char *out, *iv; + + in = input; + out = output; + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, xor0); + c2l(iv, xor1); + for (; length > 0; length -= 8) { + if (length >= 8) { + c2l(in, sin0); + c2l(in, sin1); + } else + c2ln(in, sin0, sin1, length); + tin[0] = sin0 ^ xor0; + tin[1] = sin1 ^ xor1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + tout1 = tin[1]; + xor0 = sin0 ^ tout0; + xor1 = sin1 ^ tout1; + l2c(tout0, out); + l2c(tout1, out); + } + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (; length > 0; length -= 8) { + c2l(in, sin0); + c2l(in, sin1); + tin[0] = sin0; + tin[1] = sin1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + if (length >= 8) { + l2c(tout0, out); + l2c(tout1, out); + } else + l2cn(tout0, tout1, out, length); + xor0 = tout0 ^ sin0; + xor1 = tout1 ^ sin1; + } + } + tin[0] = tin[1] = 0; + sin0 = sin1 = xor0 = xor1 = tout0 = tout1 = 0; +} diff --git a/Sources/COpenSSL/pcy_.c b/Sources/COpenSSL/pcy_.c new file mode 100644 index 00000000..fae243c0 --- /dev/null +++ b/Sources/COpenSSL/pcy_.c @@ -0,0 +1,1720 @@ +/* pcy_cache.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "x509.h" +#include "x509v3.h" + +#include "pcy_int.h" + +static int policy_data_cmp(const X509_POLICY_DATA *const *a, + const X509_POLICY_DATA *const *b); +static int policy_cache_set_int(long *out, ASN1_INTEGER *value); + +/* + * Set cache entry according to CertificatePolicies extension. Note: this + * destroys the passed CERTIFICATEPOLICIES structure. + */ + +static int policy_cache_create(X509 *x, + CERTIFICATEPOLICIES *policies, int crit) +{ + int i; + int ret = 0; + X509_POLICY_CACHE *cache = x->policy_cache; + X509_POLICY_DATA *data = NULL; + POLICYINFO *policy; + if (sk_POLICYINFO_num(policies) == 0) + goto bad_policy; + cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); + if (!cache->data) + goto bad_policy; + for (i = 0; i < sk_POLICYINFO_num(policies); i++) { + policy = sk_POLICYINFO_value(policies, i); + data = policy_data_new(policy, NULL, crit); + if (!data) + goto bad_policy; + /* + * Duplicate policy OIDs are illegal: reject if matches found. + */ + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (cache->anyPolicy) { + ret = -1; + goto bad_policy; + } + cache->anyPolicy = data; + } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) { + ret = -1; + goto bad_policy; + } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) + goto bad_policy; + data = NULL; + } + ret = 1; + bad_policy: + if (ret == -1) + x->ex_flags |= EXFLAG_INVALID_POLICY; + if (data) + policy_data_free(data); + sk_POLICYINFO_pop_free(policies, POLICYINFO_free); + if (ret <= 0) { + sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + cache->data = NULL; + } + return ret; +} + +static int policy_cache_new(X509 *x) +{ + X509_POLICY_CACHE *cache; + ASN1_INTEGER *ext_any = NULL; + POLICY_CONSTRAINTS *ext_pcons = NULL; + CERTIFICATEPOLICIES *ext_cpols = NULL; + POLICY_MAPPINGS *ext_pmaps = NULL; + int i; + cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE)); + if (!cache) + return 0; + cache->anyPolicy = NULL; + cache->data = NULL; + cache->any_skip = -1; + cache->explicit_skip = -1; + cache->map_skip = -1; + + x->policy_cache = cache; + + /* + * Handle requireExplicitPolicy *first*. Need to process this even if we + * don't have any policies. + */ + ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL); + + if (!ext_pcons) { + if (i != -1) + goto bad_cache; + } else { + if (!ext_pcons->requireExplicitPolicy + && !ext_pcons->inhibitPolicyMapping) + goto bad_cache; + if (!policy_cache_set_int(&cache->explicit_skip, + ext_pcons->requireExplicitPolicy)) + goto bad_cache; + if (!policy_cache_set_int(&cache->map_skip, + ext_pcons->inhibitPolicyMapping)) + goto bad_cache; + } + + /* Process CertificatePolicies */ + + ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL); + /* + * If no CertificatePolicies extension or problem decoding then there is + * no point continuing because the valid policies will be NULL. + */ + if (!ext_cpols) { + /* If not absent some problem with extension */ + if (i != -1) + goto bad_cache; + return 1; + } + + i = policy_cache_create(x, ext_cpols, i); + + /* NB: ext_cpols freed by policy_cache_set_policies */ + + if (i <= 0) + return i; + + ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL); + + if (!ext_pmaps) { + /* If not absent some problem with extension */ + if (i != -1) + goto bad_cache; + } else { + i = policy_cache_set_mapping(x, ext_pmaps); + if (i <= 0) + goto bad_cache; + } + + ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL); + + if (!ext_any) { + if (i != -1) + goto bad_cache; + } else if (!policy_cache_set_int(&cache->any_skip, ext_any)) + goto bad_cache; + + if (0) { + bad_cache: + x->ex_flags |= EXFLAG_INVALID_POLICY; + } + + if (ext_pcons) + POLICY_CONSTRAINTS_free(ext_pcons); + + if (ext_any) + ASN1_INTEGER_free(ext_any); + + return 1; + +} + +void policy_cache_free(X509_POLICY_CACHE *cache) +{ + if (!cache) + return; + if (cache->anyPolicy) + policy_data_free(cache->anyPolicy); + if (cache->data) + sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + OPENSSL_free(cache); +} + +const X509_POLICY_CACHE *policy_cache_set(X509 *x) +{ + + if (x->policy_cache == NULL) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + policy_cache_new(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + + return x->policy_cache; + +} + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id) +{ + int idx; + X509_POLICY_DATA tmp; + tmp.valid_policy = (ASN1_OBJECT *)id; + idx = sk_X509_POLICY_DATA_find(cache->data, &tmp); + if (idx == -1) + return NULL; + return sk_X509_POLICY_DATA_value(cache->data, idx); +} + +static int policy_data_cmp(const X509_POLICY_DATA *const *a, + const X509_POLICY_DATA *const *b) +{ + return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy); +} + +static int policy_cache_set_int(long *out, ASN1_INTEGER *value) +{ + if (value == NULL) + return 1; + if (value->type == V_ASN1_NEG_INTEGER) + return 0; + *out = ASN1_INTEGER_get(value); + return 1; +} +/* pcy_data.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "x509.h" +// #include "x509v3.h" + +// #include "pcy_int.h" + +/* Policy Node routines */ + +void policy_data_free(X509_POLICY_DATA *data) +{ + ASN1_OBJECT_free(data->valid_policy); + /* Don't free qualifiers if shared */ + if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS)) + sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free); + sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free); + OPENSSL_free(data); +} + +/* + * Create a data based on an existing policy. If 'id' is NULL use the oid in + * the policy, otherwise use 'id'. This behaviour covers the two types of + * data in RFC3280: data with from a CertificatePolcies extension and + * additional data with just the qualifiers of anyPolicy and ID from another + * source. + */ + +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, + const ASN1_OBJECT *cid, int crit) +{ + X509_POLICY_DATA *ret; + ASN1_OBJECT *id; + if (!policy && !cid) + return NULL; + if (cid) { + id = OBJ_dup(cid); + if (!id) + return NULL; + } else + id = NULL; + ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); + if (!ret) + return NULL; + ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); + if (!ret->expected_policy_set) { + OPENSSL_free(ret); + if (id) + ASN1_OBJECT_free(id); + return NULL; + } + + if (crit) + ret->flags = POLICY_DATA_FLAG_CRITICAL; + else + ret->flags = 0; + + if (id) + ret->valid_policy = id; + else { + ret->valid_policy = policy->policyid; + policy->policyid = NULL; + } + + if (policy) { + ret->qualifier_set = policy->qualifiers; + policy->qualifiers = NULL; + } else + ret->qualifier_set = NULL; + + return ret; +} +/* pcy_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "x509.h" +// #include "x509v3.h" + +// #include "pcy_int.h" + +/* accessor functions */ + +/* X509_POLICY_TREE stuff */ + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree) +{ + if (!tree) + return 0; + return tree->nlevel; +} + +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i) +{ + if (!tree || (i < 0) || (i >= tree->nlevel)) + return NULL; + return tree->levels + i; +} + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree) +{ + if (!tree) + return NULL; + return tree->auth_policies; +} + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree) +{ + if (!tree) + return NULL; + if (tree->flags & POLICY_FLAG_ANY_POLICY) + return tree->auth_policies; + else + return tree->user_policies; +} + +/* X509_POLICY_LEVEL stuff */ + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level) +{ + int n; + if (!level) + return 0; + if (level->anyPolicy) + n = 1; + else + n = 0; + if (level->nodes) + n += sk_X509_POLICY_NODE_num(level->nodes); + return n; +} + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) +{ + if (!level) + return NULL; + if (level->anyPolicy) { + if (i == 0) + return level->anyPolicy; + i--; + } + return sk_X509_POLICY_NODE_value(level->nodes, i); +} + +/* X509_POLICY_NODE stuff */ + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node) +{ + if (!node) + return NULL; + return node->data->valid_policy; +} + +#if 0 +int X509_policy_node_get_critical(const X509_POLICY_NODE *node) +{ + if (node_critical(node)) + return 1; + return 0; +} +#endif + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node) +{ + if (!node) + return NULL; + return node->data->qualifier_set; +} + +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node) +{ + if (!node) + return NULL; + return node->parent; +} +/* pcy_map.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "x509.h" +// #include "x509v3.h" + +// #include "pcy_int.h" + +/* + * Set policy mapping entries in cache. Note: this modifies the passed + * POLICY_MAPPINGS structure + */ + +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) +{ + POLICY_MAPPING *map; + X509_POLICY_DATA *data; + X509_POLICY_CACHE *cache = x->policy_cache; + int i; + int ret = 0; + if (sk_POLICY_MAPPING_num(maps) == 0) { + ret = -1; + goto bad_mapping; + } + for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { + map = sk_POLICY_MAPPING_value(maps, i); + /* Reject if map to or from anyPolicy */ + if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) + || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) { + ret = -1; + goto bad_mapping; + } + + /* Attempt to find matching policy data */ + data = policy_cache_find_data(cache, map->issuerDomainPolicy); + /* If we don't have anyPolicy can't map */ + if (!data && !cache->anyPolicy) + continue; + + /* Create a NODE from anyPolicy */ + if (!data) { + data = policy_data_new(NULL, map->issuerDomainPolicy, + cache->anyPolicy->flags + & POLICY_DATA_FLAG_CRITICAL); + if (!data) + goto bad_mapping; + data->qualifier_set = cache->anyPolicy->qualifier_set; + /* + * map->issuerDomainPolicy = NULL; + */ + data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!sk_X509_POLICY_DATA_push(cache->data, data)) { + policy_data_free(data); + goto bad_mapping; + } + } else + data->flags |= POLICY_DATA_FLAG_MAPPED; + if (!sk_ASN1_OBJECT_push(data->expected_policy_set, + map->subjectDomainPolicy)) + goto bad_mapping; + map->subjectDomainPolicy = NULL; + + } + + ret = 1; + bad_mapping: + if (ret == -1) + x->ex_flags |= EXFLAG_INVALID_POLICY; + sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); + return ret; + +} +/* pcy_node.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "asn1.h" +// #include "x509.h" +// #include "x509v3.h" + +// #include "pcy_int.h" + +static int node_cmp(const X509_POLICY_NODE *const *a, + const X509_POLICY_NODE *const *b) +{ + return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); +} + +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) +{ + return sk_X509_POLICY_NODE_new(node_cmp); +} + +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, + const ASN1_OBJECT *id) +{ + X509_POLICY_DATA n; + X509_POLICY_NODE l; + int idx; + + n.valid_policy = (ASN1_OBJECT *)id; + l.data = &n; + + idx = sk_X509_POLICY_NODE_find(nodes, &l); + if (idx == -1) + return NULL; + + return sk_X509_POLICY_NODE_value(nodes, idx); + +} + +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id) +{ + X509_POLICY_NODE *node; + int i; + for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + node = sk_X509_POLICY_NODE_value(level->nodes, i); + if (node->parent == parent) { + if (!OBJ_cmp(node->data->valid_policy, id)) + return node; + } + } + return NULL; +} + +X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + const X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree) +{ + X509_POLICY_NODE *node; + node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); + if (!node) + return NULL; + node->data = data; + node->parent = parent; + node->nchild = 0; + if (level) { + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (level->anyPolicy) + goto node_error; + level->anyPolicy = node; + } else { + + if (!level->nodes) + level->nodes = policy_node_cmp_new(); + if (!level->nodes) + goto node_error; + if (!sk_X509_POLICY_NODE_push(level->nodes, node)) + goto node_error; + } + } + + if (tree) { + if (!tree->extra_data) + tree->extra_data = sk_X509_POLICY_DATA_new_null(); + if (!tree->extra_data) + goto node_error; + if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) + goto node_error; + } + + if (parent) + parent->nchild++; + + return node; + + node_error: + policy_node_free(node); + return 0; + +} + +void policy_node_free(X509_POLICY_NODE *node) +{ + OPENSSL_free(node); +} + +/* + * See if a policy node matches a policy OID. If mapping enabled look through + * expected policy set otherwise just valid policy. + */ + +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) +{ + int i; + ASN1_OBJECT *policy_oid; + const X509_POLICY_DATA *x = node->data; + + if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) + || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) { + if (!OBJ_cmp(x->valid_policy, oid)) + return 1; + return 0; + } + + for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) { + policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); + if (!OBJ_cmp(policy_oid, oid)) + return 1; + } + return 0; + +} +/* pcy_tree.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "x509.h" +// #include "x509v3.h" + +// #include "pcy_int.h" + +/* + * Enable this to print out the complete policy tree at various point during + * evaluation. + */ + +/* + * #define OPENSSL_POLICY_DEBUG + */ + +#ifdef OPENSSL_POLICY_DEBUG + +static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, + X509_POLICY_NODE *node, int indent) +{ + if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) + || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) + BIO_puts(err, " Not Mapped\n"); + else { + int i; + STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; + ASN1_OBJECT *oid; + BIO_puts(err, " Expected: "); + for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) { + oid = sk_ASN1_OBJECT_value(pset, i); + if (i) + BIO_puts(err, ", "); + i2a_ASN1_OBJECT(err, oid); + } + BIO_puts(err, "\n"); + } +} + +static void tree_print(char *str, X509_POLICY_TREE *tree, + X509_POLICY_LEVEL *curr) +{ + X509_POLICY_LEVEL *plev; + X509_POLICY_NODE *node; + int i; + BIO *err; + err = BIO_new_fp(stderr, BIO_NOCLOSE); + if (!curr) + curr = tree->levels + tree->nlevel; + else + curr++; + BIO_printf(err, "Level print after %s\n", str); + BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); + for (plev = tree->levels; plev != curr; plev++) { + BIO_printf(err, "Level %ld, flags = %x\n", + plev - tree->levels, plev->flags); + for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) { + node = sk_X509_POLICY_NODE_value(plev->nodes, i); + X509_POLICY_NODE_print(err, node, 2); + expected_print(err, plev, node, 2); + BIO_printf(err, " Flags: %x\n", node->data->flags); + } + if (plev->anyPolicy) + X509_POLICY_NODE_print(err, plev->anyPolicy, 2); + } + + BIO_free(err); + +} +#else + +# define tree_print(a,b,c) /* */ + +#endif + +/*- + * Initialize policy tree. Return values: + * 0 Some internal error occurred. + * -1 Inconsistent or invalid extensions in certificates. + * 1 Tree initialized OK. + * 2 Policy tree is empty. + * 5 Tree OK and requireExplicitPolicy true. + * 6 Tree empty and requireExplicitPolicy true. + */ + +static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + unsigned int flags) +{ + X509_POLICY_TREE *tree; + X509_POLICY_LEVEL *level; + const X509_POLICY_CACHE *cache; + X509_POLICY_DATA *data = NULL; + X509 *x; + int ret = 1; + int i, n; + int explicit_policy; + int any_skip; + int map_skip; + *ptree = NULL; + n = sk_X509_num(certs); + +#if 0 + /* Disable policy mapping for now... */ + flags |= X509_V_FLAG_INHIBIT_MAP; +#endif + + if (flags & X509_V_FLAG_EXPLICIT_POLICY) + explicit_policy = 0; + else + explicit_policy = n + 1; + + if (flags & X509_V_FLAG_INHIBIT_ANY) + any_skip = 0; + else + any_skip = n + 1; + + if (flags & X509_V_FLAG_INHIBIT_MAP) + map_skip = 0; + else + map_skip = n + 1; + + /* Can't do anything with just a trust anchor */ + if (n == 1) + return 1; + /* + * First setup policy cache in all certificates apart from the trust + * anchor. Note any bad cache results on the way. Also can calculate + * explicit_policy value at this point. + */ + for (i = n - 2; i >= 0; i--) { + x = sk_X509_value(certs, i); + X509_check_purpose(x, -1, -1); + cache = policy_cache_set(x); + /* If cache NULL something bad happened: return immediately */ + if (cache == NULL) + return 0; + /* + * If inconsistent extensions keep a note of it but continue + */ + if (x->ex_flags & EXFLAG_INVALID_POLICY) + ret = -1; + /* + * Otherwise if we have no data (hence no CertificatePolicies) and + * haven't already set an inconsistent code note it. + */ + else if ((ret == 1) && !cache->data) + ret = 2; + if (explicit_policy > 0) { + if (!(x->ex_flags & EXFLAG_SI)) + explicit_policy--; + if ((cache->explicit_skip != -1) + && (cache->explicit_skip < explicit_policy)) + explicit_policy = cache->explicit_skip; + } + } + + if (ret != 1) { + if (ret == 2 && !explicit_policy) + return 6; + return ret; + } + + /* If we get this far initialize the tree */ + + tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE)); + + if (!tree) + return 0; + + tree->flags = 0; + tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n); + tree->nlevel = 0; + tree->extra_data = NULL; + tree->auth_policies = NULL; + tree->user_policies = NULL; + + if (!tree->levels) { + OPENSSL_free(tree); + return 0; + } + + memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); + + tree->nlevel = n; + + level = tree->levels; + + /* Root data: initialize to anyPolicy */ + + data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); + + if (!data || !level_add_node(level, data, NULL, tree)) + goto bad_tree; + + for (i = n - 2; i >= 0; i--) { + level++; + x = sk_X509_value(certs, i); + cache = policy_cache_set(x); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + level->cert = x; + + if (!cache->anyPolicy) + level->flags |= X509_V_FLAG_INHIBIT_ANY; + + /* Determine inhibit any and inhibit map flags */ + if (any_skip == 0) { + /* + * Any matching allowed if certificate is self issued and not the + * last in the chain. + */ + if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) + level->flags |= X509_V_FLAG_INHIBIT_ANY; + } else { + if (!(x->ex_flags & EXFLAG_SI)) + any_skip--; + if ((cache->any_skip >= 0) + && (cache->any_skip < any_skip)) + any_skip = cache->any_skip; + } + + if (map_skip == 0) + level->flags |= X509_V_FLAG_INHIBIT_MAP; + else { + if (!(x->ex_flags & EXFLAG_SI)) + map_skip--; + if ((cache->map_skip >= 0) + && (cache->map_skip < map_skip)) + map_skip = cache->map_skip; + } + + } + + *ptree = tree; + + if (explicit_policy) + return 1; + else + return 5; + + bad_tree: + + X509_policy_tree_free(tree); + + return 0; + +} + +static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, + const X509_POLICY_DATA *data) +{ + X509_POLICY_LEVEL *last = curr - 1; + X509_POLICY_NODE *node; + int i, matched = 0; + /* Iterate through all in nodes linking matches */ + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + if (policy_node_match(last, node, data->valid_policy)) { + if (!level_add_node(curr, data, node, NULL)) + return 0; + matched = 1; + } + } + if (!matched && last->anyPolicy) { + if (!level_add_node(curr, data, last->anyPolicy, NULL)) + return 0; + } + return 1; +} + +/* + * This corresponds to RFC3280 6.1.3(d)(1): link any data from + * CertificatePolicies onto matching parent or anyPolicy if no match. + */ + +static int tree_link_nodes(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache) +{ + int i; + X509_POLICY_DATA *data; + + for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) { + data = sk_X509_POLICY_DATA_value(cache->data, i); + /* + * If a node is mapped any it doesn't have a corresponding + * CertificatePolicies entry. However such an identical node would + * be created if anyPolicy matching is enabled because there would be + * no match with the parent valid_policy_set. So we create link + * because then it will have the mapping flags right and we can prune + * it later. + */ +#if 0 + if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) + && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) + continue; +#endif + /* Look for matching nodes in previous level */ + if (!tree_link_matching_nodes(curr, data)) + return 0; + } + return 1; +} + +/* + * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched + * policies in the parent and link to anyPolicy. + */ + +static int tree_add_unmatched(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id, + X509_POLICY_NODE *node, X509_POLICY_TREE *tree) +{ + X509_POLICY_DATA *data; + if (id == NULL) + id = node->data->valid_policy; + /* + * Create a new node with qualifiers from anyPolicy and id from unmatched + * node. + */ + data = policy_data_new(NULL, id, node_critical(node)); + + if (data == NULL) + return 0; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!level_add_node(curr, data, node, tree)) { + policy_data_free(data); + return 0; + } + + return 1; +} + +static int tree_link_unmatched(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + X509_POLICY_NODE *node, X509_POLICY_TREE *tree) +{ + const X509_POLICY_LEVEL *last = curr - 1; + int i; + + if ((last->flags & X509_V_FLAG_INHIBIT_MAP) + || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) { + /* If no policy mapping: matched if one child present */ + if (node->nchild) + return 1; + if (!tree_add_unmatched(curr, cache, NULL, node, tree)) + return 0; + /* Add it */ + } else { + /* If mapping: matched if one child per expected policy set */ + STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; + if (node->nchild == sk_ASN1_OBJECT_num(expset)) + return 1; + /* Locate unmatched nodes */ + for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) { + ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); + if (level_find_node(curr, node, oid)) + continue; + if (!tree_add_unmatched(curr, cache, oid, node, tree)) + return 0; + } + + } + + return 1; + +} + +static int tree_link_any(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + X509_POLICY_TREE *tree) +{ + int i; + /* + * X509_POLICY_DATA *data; + */ + X509_POLICY_NODE *node; + X509_POLICY_LEVEL *last = curr - 1; + + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + + if (!tree_link_unmatched(curr, cache, node, tree)) + return 0; + +#if 0 + + /* + * Skip any node with any children: we only want unmathced nodes. + * Note: need something better for policy mapping because each node + * may have multiple children + */ + if (node->nchild) + continue; + + /* + * Create a new node with qualifiers from anyPolicy and id from + * unmatched node. + */ + data = policy_data_new(NULL, node->data->valid_policy, + node_critical(node)); + + if (data == NULL) + return 0; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!level_add_node(curr, data, node, tree)) { + policy_data_free(data); + return 0; + } +#endif + + } + /* Finally add link to anyPolicy */ + if (last->anyPolicy) { + if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL)) + return 0; + } + return 1; +} + +/* + * Prune the tree: delete any child mapped child data on the current level + * then proceed up the tree deleting any data with no children. If we ever + * have no data on a level we can halt because the tree will be empty. + */ + +static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) +{ + STACK_OF(X509_POLICY_NODE) *nodes; + X509_POLICY_NODE *node; + int i; + nodes = curr->nodes; + if (curr->flags & X509_V_FLAG_INHIBIT_MAP) { + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { + node = sk_X509_POLICY_NODE_value(nodes, i); + /* Delete any mapped data: see RFC3280 XXXX */ + if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) { + node->parent->nchild--; + OPENSSL_free(node); + (void)sk_X509_POLICY_NODE_delete(nodes, i); + } + } + } + + for (;;) { + --curr; + nodes = curr->nodes; + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { + node = sk_X509_POLICY_NODE_value(nodes, i); + if (node->nchild == 0) { + node->parent->nchild--; + OPENSSL_free(node); + (void)sk_X509_POLICY_NODE_delete(nodes, i); + } + } + if (curr->anyPolicy && !curr->anyPolicy->nchild) { + if (curr->anyPolicy->parent) + curr->anyPolicy->parent->nchild--; + OPENSSL_free(curr->anyPolicy); + curr->anyPolicy = NULL; + } + if (curr == tree->levels) { + /* If we zapped anyPolicy at top then tree is empty */ + if (!curr->anyPolicy) + return 2; + return 1; + } + } + + return 1; + +} + +static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, + X509_POLICY_NODE *pcy) +{ + if (!*pnodes) { + *pnodes = policy_node_cmp_new(); + if (!*pnodes) + return 0; + } else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1) + return 1; + + if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) + return 0; + + return 1; + +} + +/* + * Calculate the authority set based on policy tree. The 'pnodes' parameter + * is used as a store for the set of policy nodes used to calculate the user + * set. If the authority set is not anyPolicy then pnodes will just point to + * the authority set. If however the authority set is anyPolicy then the set + * of valid policies (other than anyPolicy) is store in pnodes. The return + * value of '2' is used in this case to indicate that pnodes should be freed. + */ + +static int tree_calculate_authority_set(X509_POLICY_TREE *tree, + STACK_OF(X509_POLICY_NODE) **pnodes) +{ + X509_POLICY_LEVEL *curr; + X509_POLICY_NODE *node, *anyptr; + STACK_OF(X509_POLICY_NODE) **addnodes; + int i, j; + curr = tree->levels + tree->nlevel - 1; + + /* If last level contains anyPolicy set is anyPolicy */ + if (curr->anyPolicy) { + if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) + return 0; + addnodes = pnodes; + } else + /* Add policies to authority set */ + addnodes = &tree->auth_policies; + + curr = tree->levels; + for (i = 1; i < tree->nlevel; i++) { + /* + * If no anyPolicy node on this this level it can't appear on lower + * levels so end search. + */ + if (!(anyptr = curr->anyPolicy)) + break; + curr++; + for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) { + node = sk_X509_POLICY_NODE_value(curr->nodes, j); + if ((node->parent == anyptr) + && !tree_add_auth_node(addnodes, node)) + return 0; + } + } + + if (addnodes == pnodes) + return 2; + + *pnodes = tree->auth_policies; + + return 1; +} + +static int tree_calculate_user_set(X509_POLICY_TREE *tree, + STACK_OF(ASN1_OBJECT) *policy_oids, + STACK_OF(X509_POLICY_NODE) *auth_nodes) +{ + int i; + X509_POLICY_NODE *node; + ASN1_OBJECT *oid; + + X509_POLICY_NODE *anyPolicy; + X509_POLICY_DATA *extra; + + /* + * Check if anyPolicy present in authority constrained policy set: this + * will happen if it is a leaf node. + */ + + if (sk_ASN1_OBJECT_num(policy_oids) <= 0) + return 1; + + anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; + + for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { + oid = sk_ASN1_OBJECT_value(policy_oids, i); + if (OBJ_obj2nid(oid) == NID_any_policy) { + tree->flags |= POLICY_FLAG_ANY_POLICY; + return 1; + } + } + + for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { + oid = sk_ASN1_OBJECT_value(policy_oids, i); + node = tree_find_sk(auth_nodes, oid); + if (!node) { + if (!anyPolicy) + continue; + /* + * Create a new node with policy ID from user set and qualifiers + * from anyPolicy. + */ + extra = policy_data_new(NULL, oid, node_critical(anyPolicy)); + if (!extra) + return 0; + extra->qualifier_set = anyPolicy->data->qualifier_set; + extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS + | POLICY_DATA_FLAG_EXTRA_NODE; + node = level_add_node(NULL, extra, anyPolicy->parent, tree); + } + if (!tree->user_policies) { + tree->user_policies = sk_X509_POLICY_NODE_new_null(); + if (!tree->user_policies) + return 1; + } + if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) + return 0; + } + return 1; + +} + +static int tree_evaluate(X509_POLICY_TREE *tree) +{ + int ret, i; + X509_POLICY_LEVEL *curr = tree->levels + 1; + const X509_POLICY_CACHE *cache; + + for (i = 1; i < tree->nlevel; i++, curr++) { + cache = policy_cache_set(curr->cert); + if (!tree_link_nodes(curr, cache)) + return 0; + + if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) + && !tree_link_any(curr, cache, tree)) + return 0; + tree_print("before tree_prune()", tree, curr); + ret = tree_prune(tree, curr); + if (ret != 1) + return ret; + } + + return 1; + +} + +static void exnode_free(X509_POLICY_NODE *node) +{ + if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) + OPENSSL_free(node); +} + +void X509_policy_tree_free(X509_POLICY_TREE *tree) +{ + X509_POLICY_LEVEL *curr; + int i; + + if (!tree) + return; + + sk_X509_POLICY_NODE_free(tree->auth_policies); + sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); + + for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) { + if (curr->cert) + X509_free(curr->cert); + if (curr->nodes) + sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free); + if (curr->anyPolicy) + policy_node_free(curr->anyPolicy); + } + + if (tree->extra_data) + sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free); + + OPENSSL_free(tree->levels); + OPENSSL_free(tree); + +} + +/*- + * Application policy checking function. + * Return codes: + * 0 Internal Error. + * 1 Successful. + * -1 One or more certificates contain invalid or inconsistent extensions + * -2 User constrained policy set empty and requireExplicit true. + */ + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) +{ + int ret; + int calc_ret; + X509_POLICY_TREE *tree = NULL; + STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; + *ptree = NULL; + + *pexplicit_policy = 0; + ret = tree_init(&tree, certs, flags); + + switch (ret) { + + /* Tree empty requireExplicit False: OK */ + case 2: + return 1; + + /* Some internal error */ + case -1: + return -1; + + /* Some internal error */ + case 0: + return 0; + + /* Tree empty requireExplicit True: Error */ + + case 6: + *pexplicit_policy = 1; + return -2; + + /* Tree OK requireExplicit True: OK and continue */ + case 5: + *pexplicit_policy = 1; + break; + + /* Tree OK: continue */ + + case 1: + if (!tree) + /* + * tree_init() returns success and a null tree + * if it's just looking at a trust anchor. + * I'm not sure that returning success here is + * correct, but I'm sure that reporting this + * as an internal error which our caller + * interprets as a malloc failure is wrong. + */ + return 1; + break; + } + + if (!tree) + goto error; + ret = tree_evaluate(tree); + + tree_print("tree_evaluate()", tree, NULL); + + if (ret <= 0) + goto error; + + /* Return value 2 means tree empty */ + if (ret == 2) { + X509_policy_tree_free(tree); + if (*pexplicit_policy) + return -2; + else + return 1; + } + + /* Tree is not empty: continue */ + + calc_ret = tree_calculate_authority_set(tree, &auth_nodes); + + if (!calc_ret) + goto error; + + ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); + + if (calc_ret == 2) + sk_X509_POLICY_NODE_free(auth_nodes); + + if (!ret) + goto error; + + + if (tree) + *ptree = tree; + + if (*pexplicit_policy) { + nodes = X509_policy_tree_get0_user_policies(tree); + if (sk_X509_POLICY_NODE_num(nodes) <= 0) + return -2; + } + + return 1; + + error: + + X509_policy_tree_free(tree); + + return 0; + +} diff --git a/Sources/COpenSSL/pcy_int.h b/Sources/COpenSSL/pcy_int.h new file mode 100644 index 00000000..b5075f9e --- /dev/null +++ b/Sources/COpenSSL/pcy_int.h @@ -0,0 +1,217 @@ +/* pcy_int.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; + +DECLARE_STACK_OF(X509_POLICY_DATA) + +/* Internal structures */ + +/* + * This structure and the field names correspond to the Policy 'node' of + * RFC3280. NB this structure contains no pointers to parent or child data: + * X509_POLICY_NODE contains that. This means that the main policy data can + * be kept static and cached with the certificate. + */ + +struct X509_POLICY_DATA_st { + unsigned int flags; + /* Policy OID and qualifiers for this data */ + ASN1_OBJECT *valid_policy; + STACK_OF(POLICYQUALINFO) *qualifier_set; + STACK_OF(ASN1_OBJECT) *expected_policy_set; +}; + +/* X509_POLICY_DATA flags values */ + +/* + * This flag indicates the structure has been mapped using a policy mapping + * extension. If policy mapping is not active its references get deleted. + */ + +#define POLICY_DATA_FLAG_MAPPED 0x1 + +/* + * This flag indicates the data doesn't correspond to a policy in Certificate + * Policies: it has been mapped to any policy. + */ + +#define POLICY_DATA_FLAG_MAPPED_ANY 0x2 + +/* AND with flags to see if any mapping has occurred */ + +#define POLICY_DATA_FLAG_MAP_MASK 0x3 + +/* qualifiers are shared and shouldn't be freed */ + +#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 + +/* Parent node is an extra node and should be freed */ + +#define POLICY_DATA_FLAG_EXTRA_NODE 0x8 + +/* Corresponding CertificatePolicies is critical */ + +#define POLICY_DATA_FLAG_CRITICAL 0x10 + +/* This structure is cached with a certificate */ + +struct X509_POLICY_CACHE_st { + /* anyPolicy data or NULL if no anyPolicy */ + X509_POLICY_DATA *anyPolicy; + /* other policy data */ + STACK_OF(X509_POLICY_DATA) *data; + /* If InhibitAnyPolicy present this is its value or -1 if absent. */ + long any_skip; + /* + * If policyConstraints and requireExplicitPolicy present this is its + * value or -1 if absent. + */ + long explicit_skip; + /* + * If policyConstraints and policyMapping present this is its value or -1 + * if absent. + */ + long map_skip; +}; + +/* + * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL + */ + +/* This structure represents the relationship between nodes */ + +struct X509_POLICY_NODE_st { + /* node data this refers to */ + const X509_POLICY_DATA *data; + /* Parent node */ + X509_POLICY_NODE *parent; + /* Number of child nodes */ + int nchild; +}; + +struct X509_POLICY_LEVEL_st { + /* Cert for this level */ + X509 *cert; + /* nodes at this level */ + STACK_OF(X509_POLICY_NODE) *nodes; + /* anyPolicy node */ + X509_POLICY_NODE *anyPolicy; + /* Extra data */ + /* + * STACK_OF(X509_POLICY_DATA) *extra_data; + */ + unsigned int flags; +}; + +struct X509_POLICY_TREE_st { + /* This is the tree 'level' data */ + X509_POLICY_LEVEL *levels; + int nlevel; + /* + * Extra policy data when additional nodes (not from the certificate) are + * required. + */ + STACK_OF(X509_POLICY_DATA) *extra_data; + /* This is the authority constained policy set */ + STACK_OF(X509_POLICY_NODE) *auth_policies; + STACK_OF(X509_POLICY_NODE) *user_policies; + unsigned int flags; +}; + +/* Set if anyPolicy present in user policies */ +#define POLICY_FLAG_ANY_POLICY 0x2 + +/* Useful macros */ + +#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL) +#define node_critical(node) node_data_critical(node->data) + +/* Internal functions */ + +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, + int crit); +void policy_data_free(X509_POLICY_DATA *data); + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id); +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); + +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); + +void policy_cache_init(void); + +void policy_cache_free(X509_POLICY_CACHE *cache); + +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id); + +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, + const ASN1_OBJECT *id); + +X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + const X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree); +void policy_node_free(X509_POLICY_NODE *node); +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); + +const X509_POLICY_CACHE *policy_cache_set(X509 *x); diff --git a/Sources/COpenSSL/pem.h b/Sources/COpenSSL/pem.h new file mode 100644 index 00000000..0d64a193 --- /dev/null +++ b/Sources/COpenSSL/pem.h @@ -0,0 +1,618 @@ +/* crypto/pem/pem.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PEM_H +# define HEADER_PEM_H + +# include "e_os2.h" +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# ifndef OPENSSL_NO_STACK +# include "stack.h" +# endif +# include "evp.h" +# include "x509.h" +# include "pem2.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# define PEM_BUFSIZE 1024 + +# define PEM_OBJ_UNDEF 0 +# define PEM_OBJ_X509 1 +# define PEM_OBJ_X509_REQ 2 +# define PEM_OBJ_CRL 3 +# define PEM_OBJ_SSL_SESSION 4 +# define PEM_OBJ_PRIV_KEY 10 +# define PEM_OBJ_PRIV_RSA 11 +# define PEM_OBJ_PRIV_DSA 12 +# define PEM_OBJ_PRIV_DH 13 +# define PEM_OBJ_PUB_RSA 14 +# define PEM_OBJ_PUB_DSA 15 +# define PEM_OBJ_PUB_DH 16 +# define PEM_OBJ_DHPARAMS 17 +# define PEM_OBJ_DSAPARAMS 18 +# define PEM_OBJ_PRIV_RSA_PUBLIC 19 +# define PEM_OBJ_PRIV_ECDSA 20 +# define PEM_OBJ_PUB_ECDSA 21 +# define PEM_OBJ_ECPARAMETERS 22 + +# define PEM_ERROR 30 +# define PEM_DEK_DES_CBC 40 +# define PEM_DEK_IDEA_CBC 45 +# define PEM_DEK_DES_EDE 50 +# define PEM_DEK_DES_ECB 60 +# define PEM_DEK_RSA 70 +# define PEM_DEK_RSA_MD2 80 +# define PEM_DEK_RSA_MD5 90 + +# define PEM_MD_MD2 NID_md2 +# define PEM_MD_MD5 NID_md5 +# define PEM_MD_SHA NID_sha +# define PEM_MD_MD2_RSA NID_md2WithRSAEncryption +# define PEM_MD_MD5_RSA NID_md5WithRSAEncryption +# define PEM_MD_SHA_RSA NID_sha1WithRSAEncryption + +# define PEM_STRING_X509_OLD "X509 CERTIFICATE" +# define PEM_STRING_X509 "CERTIFICATE" +# define PEM_STRING_X509_PAIR "CERTIFICATE PAIR" +# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +# define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +# define PEM_STRING_X509_CRL "X509 CRL" +# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +# define PEM_STRING_PUBLIC "PUBLIC KEY" +# define PEM_STRING_RSA "RSA PRIVATE KEY" +# define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +# define PEM_STRING_DSA "DSA PRIVATE KEY" +# define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +# define PEM_STRING_PKCS7 "PKCS7" +# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +# define PEM_STRING_PKCS8INF "PRIVATE KEY" +# define PEM_STRING_DHPARAMS "DH PARAMETERS" +# define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS" +# define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +# define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +# define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +# define PEM_STRING_PARAMETERS "PARAMETERS" +# define PEM_STRING_CMS "CMS" + + /* + * Note that this structure is initialised by PEM_SealInit and cleaned up + * by PEM_SealFinal (at least for now) + */ +typedef struct PEM_Encode_Seal_st { + EVP_ENCODE_CTX encode; + EVP_MD_CTX md; + EVP_CIPHER_CTX cipher; +} PEM_ENCODE_SEAL_CTX; + +/* enc_type is one off */ +# define PEM_TYPE_ENCRYPTED 10 +# define PEM_TYPE_MIC_ONLY 20 +# define PEM_TYPE_MIC_CLEAR 30 +# define PEM_TYPE_CLEAR 40 + +typedef struct pem_recip_st { + char *name; + X509_NAME *dn; + int cipher; + int key_enc; + /* char iv[8]; unused and wrong size */ +} PEM_USER; + +typedef struct pem_ctx_st { + int type; /* what type of object */ + struct { + int version; + int mode; + } proc_type; + + char *domain; + + struct { + int cipher; + /*- + unused, and wrong size + unsigned char iv[8]; */ + } DEK_info; + + PEM_USER *originator; + + int num_recipient; + PEM_USER **recipient; +/*- + XXX(ben): don#t think this is used! + STACK *x509_chain; / * certificate chain */ + EVP_MD *md; /* signature type */ + + int md_enc; /* is the md encrypted or not? */ + int md_len; /* length of md_data */ + char *md_data; /* message digest, could be pkey encrypted */ + + EVP_CIPHER *dec; /* date encryption cipher */ + int key_len; /* key length */ + unsigned char *key; /* key */ + /*- + unused, and wrong size + unsigned char iv[8]; */ + + int data_enc; /* is the data encrypted */ + int data_len; + unsigned char *data; +} PEM_CTX; + +/* + * These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or + * IMPLEMENT_PEM_rw_cb(...) + */ + +# ifdef OPENSSL_NO_FP_API + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ +# else + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# endif + +# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + +# if defined(OPENSSL_NO_FP_API) + +# define DECLARE_PEM_read_fp(name, type) /**/ +# define DECLARE_PEM_write_fp(name, type) /**/ +# define DECLARE_PEM_write_cb_fp(name, type) /**/ +# else + +# define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +# define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +# define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# endif + +# ifndef OPENSSL_NO_BIO +# define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +# define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +# define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# else + +# define DECLARE_PEM_read_bio(name, type) /**/ +# define DECLARE_PEM_write_bio(name, type) /**/ +# define DECLARE_PEM_write_bio_const(name, type) /**/ +# define DECLARE_PEM_write_cb_bio(name, type) /**/ +# endif +# define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) +# define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) +# define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) +# define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) +# define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) +# define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) +# define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) +# if 1 +/* "userdata": new with OpenSSL 0.9.4 */ +typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata); +# else +/* OpenSSL 0.9.3, 0.9.3a */ +typedef int pem_password_cb (char *buf, int size, int rwflag); +# endif + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +# ifndef OPENSSL_NO_BIO +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write_bio(BIO *bp, const char *name, const char *hdr, + const unsigned char *data, long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cd, void *u); +# endif + +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, const char *name, const char *hdr, + const unsigned char *data, long len); +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); + +int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, + EVP_MD *md_type, unsigned char **ek, int *ekl, + unsigned char *iv, EVP_PKEY **pubk, int npubk); +void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, + unsigned char *in, int inl); +int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, + unsigned char *out, int *outl, EVP_PKEY *priv); + +void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +/* The default pem_password_cb that's used internally */ +int PEM_def_callback(char *buf, int num, int rwflag, void *userdata); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + +# include "symhacks.h" + +DECLARE_PEM_rw(X509, X509) +DECLARE_PEM_rw(X509_AUX, X509) +DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR) +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) +DECLARE_PEM_rw(X509_CRL, X509_CRL) +DECLARE_PEM_rw(PKCS7, PKCS7) +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) +DECLARE_PEM_rw(PKCS8, X509_SIG) +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) +# ifndef OPENSSL_NO_RSA +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) +# endif +# ifndef OPENSSL_NO_DSA +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) +DECLARE_PEM_rw(DSA_PUBKEY, DSA) +DECLARE_PEM_rw_const(DSAparams, DSA) +# endif +# ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +# endif +# ifndef OPENSSL_NO_DH +DECLARE_PEM_rw_const(DHparams, DH) +DECLARE_PEM_write_const(DHxparams, DH) +# endif +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cd, + void *u); + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +# ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +void ERR_load_PEM_strings(void); + +/* Error codes for the PEM functions. */ + +/* Function codes. */ +# define PEM_F_B2I_DSS 127 +# define PEM_F_B2I_PVK_BIO 128 +# define PEM_F_B2I_RSA 129 +# define PEM_F_CHECK_BITLEN_DSA 130 +# define PEM_F_CHECK_BITLEN_RSA 131 +# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +# define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +# define PEM_F_DO_B2I 132 +# define PEM_F_DO_B2I_BIO 133 +# define PEM_F_DO_BLOB_HEADER 134 +# define PEM_F_DO_PK8PKEY 126 +# define PEM_F_DO_PK8PKEY_FP 125 +# define PEM_F_DO_PVK_BODY 135 +# define PEM_F_DO_PVK_HEADER 136 +# define PEM_F_I2B_PVK 137 +# define PEM_F_I2B_PVK_BIO 138 +# define PEM_F_LOAD_IV 101 +# define PEM_F_PEM_ASN1_READ 102 +# define PEM_F_PEM_ASN1_READ_BIO 103 +# define PEM_F_PEM_ASN1_WRITE 104 +# define PEM_F_PEM_ASN1_WRITE_BIO 105 +# define PEM_F_PEM_DEF_CALLBACK 100 +# define PEM_F_PEM_DO_HEADER 106 +# define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118 +# define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +# define PEM_F_PEM_PK8PKEY 119 +# define PEM_F_PEM_READ 108 +# define PEM_F_PEM_READ_BIO 109 +# define PEM_F_PEM_READ_BIO_DHPARAMS 141 +# define PEM_F_PEM_READ_BIO_PARAMETERS 140 +# define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +# define PEM_F_PEM_READ_DHPARAMS 142 +# define PEM_F_PEM_READ_PRIVATEKEY 124 +# define PEM_F_PEM_SEALFINAL 110 +# define PEM_F_PEM_SEALINIT 111 +# define PEM_F_PEM_SIGNFINAL 112 +# define PEM_F_PEM_WRITE 113 +# define PEM_F_PEM_WRITE_BIO 114 +# define PEM_F_PEM_WRITE_PRIVATEKEY 139 +# define PEM_F_PEM_X509_INFO_READ 115 +# define PEM_F_PEM_X509_INFO_READ_BIO 116 +# define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* Reason codes. */ +# define PEM_R_BAD_BASE64_DECODE 100 +# define PEM_R_BAD_DECRYPT 101 +# define PEM_R_BAD_END_LINE 102 +# define PEM_R_BAD_IV_CHARS 103 +# define PEM_R_BAD_MAGIC_NUMBER 116 +# define PEM_R_BAD_PASSWORD_READ 104 +# define PEM_R_BAD_VERSION_NUMBER 117 +# define PEM_R_BIO_WRITE_FAILURE 118 +# define PEM_R_CIPHER_IS_NULL 127 +# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +# define PEM_R_HEADER_TOO_LONG 128 +# define PEM_R_INCONSISTENT_HEADER 121 +# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +# define PEM_R_KEYBLOB_TOO_SHORT 123 +# define PEM_R_NOT_DEK_INFO 105 +# define PEM_R_NOT_ENCRYPTED 106 +# define PEM_R_NOT_PROC_TYPE 107 +# define PEM_R_NO_START_LINE 108 +# define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +# define PEM_R_PUBLIC_KEY_NO_RSA 110 +# define PEM_R_PVK_DATA_TOO_SHORT 124 +# define PEM_R_PVK_TOO_SHORT 125 +# define PEM_R_READ_KEY 111 +# define PEM_R_SHORT_HEADER 112 +# define PEM_R_UNSUPPORTED_CIPHER 113 +# define PEM_R_UNSUPPORTED_ENCRYPTION 114 +# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Sources/COpenSSL/pem2.h b/Sources/COpenSSL/pem2.h new file mode 100644 index 00000000..84897d5e --- /dev/null +++ b/Sources/COpenSSL/pem2.h @@ -0,0 +1,70 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This header only exists to break a circular dependency between pem and err + * Ben 30 Jan 1999. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HEADER_PEM_H +void ERR_load_PEM_strings(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/Sources/COpenSSL/pem_.c b/Sources/COpenSSL/pem_.c new file mode 100644 index 00000000..b27b4c3a --- /dev/null +++ b/Sources/COpenSSL/pem_.c @@ -0,0 +1,2921 @@ +/* crypto/pem/pem_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "bio.h" +#include "evp.h" +#include "x509.h" +#include "pkcs7.h" +#include "pem.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +#ifndef OPENSSL_NO_RSA +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); +#endif +#ifndef OPENSSL_NO_DSA +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); +#endif + +#ifndef OPENSSL_NO_EC +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); +#endif + +IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) + +IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) +IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) +IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) + +IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, + PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE) +#ifndef OPENSSL_NO_RSA +/* + * We treat RSA or DSA private keys as a special case. For private keys we + * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract + * the relevant private key: this means can handle "traditional" and PKCS#8 + * formats transparently. + */ +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) +{ + RSA *rtmp; + if (!key) + return NULL; + rtmp = EVP_PKEY_get1_RSA(key); + EVP_PKEY_free(key); + if (!rtmp) + return NULL; + if (rsa) { + RSA_free(*rsa); + *rsa = rtmp; + } + return rtmp; +} + +RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); +} + +# ifndef OPENSSL_NO_FP_API + +RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); +} + +# endif + +# ifdef OPENSSL_FIPS + +int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_RSA(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey, + PEM_STRING_RSA, bp, x, enc, kstr, klen, cb, + u); +} + +# ifndef OPENSSL_NO_FP_API +int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + + EVP_PKEY_set1_RSA(k, x); + + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey, + PEM_STRING_RSA, fp, x, enc, kstr, klen, cb, u); +} +# endif + +# else + +IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, + RSAPrivateKey) +# endif +IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, + RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, + PEM_STRING_PUBLIC, + RSA_PUBKEY) +#endif +#ifndef OPENSSL_NO_DSA +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) +{ + DSA *dtmp; + if (!key) + return NULL; + dtmp = EVP_PKEY_get1_DSA(key); + EVP_PKEY_free(key); + if (!dtmp) + return NULL; + if (dsa) { + DSA_free(*dsa); + *dsa = dtmp; + } + return dtmp; +} + +DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +} + +# ifdef OPENSSL_FIPS + +int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_DSA(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey, + PEM_STRING_DSA, bp, x, enc, kstr, klen, cb, + u); +} + +# ifndef OPENSSL_NO_FP_API +int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_DSA(k, x); + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey, + PEM_STRING_DSA, fp, x, enc, kstr, klen, cb, u); +} +# endif + +# else + +IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, + DSAPrivateKey) +# endif + IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) +# ifndef OPENSSL_NO_FP_API +DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +} + +# endif + +IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) +#endif +#ifndef OPENSSL_NO_EC +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) +{ + EC_KEY *dtmp; + if (!key) + return NULL; + dtmp = EVP_PKEY_get1_EC_KEY(key); + EVP_PKEY_free(key); + if (!dtmp) + return NULL; + if (eckey) { + EC_KEY_free(*eckey); + *eckey = dtmp; + } + return dtmp; +} + +EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_eckey(pktmp, key); /* will free pktmp */ +} + +IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, + ECPKParameters) +# ifdef OPENSSL_FIPS +int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_EC_KEY(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey, + PEM_STRING_ECPRIVATEKEY, + bp, x, enc, kstr, klen, cb, u); +} + +# ifndef OPENSSL_NO_FP_API +int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_EC_KEY(k, x); + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey, + PEM_STRING_ECPRIVATEKEY, + fp, x, enc, kstr, klen, cb, u); +} +# endif + +# else + IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, + ECPrivateKey) +# endif +IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) +# ifndef OPENSSL_NO_FP_API +EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ +} + +# endif + +#endif + +#ifndef OPENSSL_NO_DH + +IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) + IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) +#endif +IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) +/* crypto/pem/pem_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "pem.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason) + +static ERR_STRING_DATA PEM_str_functs[] = { + {ERR_FUNC(PEM_F_B2I_DSS), "B2I_DSS"}, + {ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"}, + {ERR_FUNC(PEM_F_B2I_RSA), "B2I_RSA"}, + {ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"}, + {ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"}, + {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"}, + {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"}, + {ERR_FUNC(PEM_F_DO_B2I), "DO_B2I"}, + {ERR_FUNC(PEM_F_DO_B2I_BIO), "DO_B2I_BIO"}, + {ERR_FUNC(PEM_F_DO_BLOB_HEADER), "DO_BLOB_HEADER"}, + {ERR_FUNC(PEM_F_DO_PK8PKEY), "DO_PK8PKEY"}, + {ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "DO_PK8PKEY_FP"}, + {ERR_FUNC(PEM_F_DO_PVK_BODY), "DO_PVK_BODY"}, + {ERR_FUNC(PEM_F_DO_PVK_HEADER), "DO_PVK_HEADER"}, + {ERR_FUNC(PEM_F_I2B_PVK), "I2B_PVK"}, + {ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"}, + {ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"}, + {ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"}, + {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"}, + {ERR_FUNC(PEM_F_PEM_ASN1_WRITE), "PEM_ASN1_write"}, + {ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO), "PEM_ASN1_write_bio"}, + {ERR_FUNC(PEM_F_PEM_DEF_CALLBACK), "PEM_def_callback"}, + {ERR_FUNC(PEM_F_PEM_DO_HEADER), "PEM_do_header"}, + {ERR_FUNC(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY), + "PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"}, + {ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO), "PEM_get_EVP_CIPHER_INFO"}, + {ERR_FUNC(PEM_F_PEM_PK8PKEY), "PEM_PK8PKEY"}, + {ERR_FUNC(PEM_F_PEM_READ), "PEM_read"}, + {ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"}, + {ERR_FUNC(PEM_F_PEM_READ_BIO_DHPARAMS), "PEM_READ_BIO_DHPARAMS"}, + {ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"}, + {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_READ_BIO_PRIVATEKEY"}, + {ERR_FUNC(PEM_F_PEM_READ_DHPARAMS), "PEM_READ_DHPARAMS"}, + {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"}, + {ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"}, + {ERR_FUNC(PEM_F_PEM_SEALINIT), "PEM_SealInit"}, + {ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"}, + {ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"}, + {ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"}, + {ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_WRITE_PRIVATEKEY"}, + {ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"}, + {ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"}, + {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"}, + {0, NULL} +}; + +static ERR_STRING_DATA PEM_str_reasons[] = { + {ERR_REASON(PEM_R_BAD_BASE64_DECODE), "bad base64 decode"}, + {ERR_REASON(PEM_R_BAD_DECRYPT), "bad decrypt"}, + {ERR_REASON(PEM_R_BAD_END_LINE), "bad end line"}, + {ERR_REASON(PEM_R_BAD_IV_CHARS), "bad iv chars"}, + {ERR_REASON(PEM_R_BAD_MAGIC_NUMBER), "bad magic number"}, + {ERR_REASON(PEM_R_BAD_PASSWORD_READ), "bad password read"}, + {ERR_REASON(PEM_R_BAD_VERSION_NUMBER), "bad version number"}, + {ERR_REASON(PEM_R_BIO_WRITE_FAILURE), "bio write failure"}, + {ERR_REASON(PEM_R_CIPHER_IS_NULL), "cipher is null"}, + {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY), + "error converting private key"}, + {ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB), + "expecting private key blob"}, + {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB), + "expecting public key blob"}, + {ERR_REASON(PEM_R_HEADER_TOO_LONG), "header too long"}, + {ERR_REASON(PEM_R_INCONSISTENT_HEADER), "inconsistent header"}, + {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR), + "keyblob header parse error"}, + {ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT), "keyblob too short"}, + {ERR_REASON(PEM_R_NOT_DEK_INFO), "not dek info"}, + {ERR_REASON(PEM_R_NOT_ENCRYPTED), "not encrypted"}, + {ERR_REASON(PEM_R_NOT_PROC_TYPE), "not proc type"}, + {ERR_REASON(PEM_R_NO_START_LINE), "no start line"}, + {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD), + "problems getting password"}, + {ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA), "public key no rsa"}, + {ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT), "pvk data too short"}, + {ERR_REASON(PEM_R_PVK_TOO_SHORT), "pvk too short"}, + {ERR_REASON(PEM_R_READ_KEY), "read key"}, + {ERR_REASON(PEM_R_SHORT_HEADER), "short header"}, + {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, + {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"}, + {ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS), + "unsupported key components"}, + {0, NULL} +}; + +#endif + +void ERR_load_PEM_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) { + ERR_load_strings(0, PEM_str_functs); + ERR_load_strings(0, PEM_str_reasons); + } +#endif +} +/* crypto/pem/pem_info.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "buffer.h" +#include "objects.h" +// #include "evp.h" +// #include "x509.h" +// #include "pem.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif + +#ifndef OPENSSL_NO_FP_API +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u) +{ + BIO *b; + STACK_OF(X509_INFO) *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_X509_INFO_read_bio(b, sk, cb, u); + BIO_free(b); + return (ret); +} +#endif + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u) +{ + X509_INFO *xi = NULL; + char *name = NULL, *header = NULL; + void *pp; + unsigned char *data = NULL; + const unsigned char *p; + long len, error = 0; + int ok = 0; + STACK_OF(X509_INFO) *ret = NULL; + unsigned int i, raw, ptype; + d2i_of_void *d2i = 0; + + if (sk == NULL) { + if ((ret = sk_X509_INFO_new_null()) == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = sk; + + if ((xi = X509_INFO_new()) == NULL) + goto err; + for (;;) { + raw = 0; + ptype = 0; + i = PEM_read_bio(bp, &name, &header, &data, &len); + if (i == 0) { + error = ERR_GET_REASON(ERR_peek_last_error()); + if (error == PEM_R_NO_START_LINE) { + ERR_clear_error(); + break; + } + goto err; + } + start: + if ((strcmp(name, PEM_STRING_X509) == 0) || + (strcmp(name, PEM_STRING_X509_OLD) == 0)) { + d2i = (D2I_OF(void)) d2i_X509; + if (xi->x509 != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + pp = &(xi->x509); + } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) { + d2i = (D2I_OF(void)) d2i_X509_AUX; + if (xi->x509 != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + pp = &(xi->x509); + } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { + d2i = (D2I_OF(void)) d2i_X509_CRL; + if (xi->crl != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + pp = &(xi->crl); + } else +#ifndef OPENSSL_NO_RSA + if (strcmp(name, PEM_STRING_RSA) == 0) { + d2i = (D2I_OF(void)) d2i_RSAPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + + xi->enc_data = NULL; + xi->enc_len = 0; + + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_RSA; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif +#ifndef OPENSSL_NO_DSA + if (strcmp(name, PEM_STRING_DSA) == 0) { + d2i = (D2I_OF(void)) d2i_DSAPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + + xi->enc_data = NULL; + xi->enc_len = 0; + + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_DSA; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif +#ifndef OPENSSL_NO_EC + if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) { + d2i = (D2I_OF(void)) d2i_ECPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + + xi->enc_data = NULL; + xi->enc_len = 0; + + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_EC; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif + { + d2i = NULL; + pp = NULL; + } + + if (d2i != NULL) { + if (!raw) { + EVP_CIPHER_INFO cipher; + + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) + goto err; + if (!PEM_do_header(&cipher, data, &len, cb, u)) + goto err; + p = data; + if (ptype) { + if (!d2i_PrivateKey(ptype, pp, &p, len)) { + PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB); + goto err; + } + } else if (d2i(pp, &p, len) == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB); + goto err; + } + } else { /* encrypted RSA data */ + if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher)) + goto err; + xi->enc_data = (char *)data; + xi->enc_len = (int)len; + data = NULL; + } + } else { + /* unknown */ + } + if (name != NULL) + OPENSSL_free(name); + if (header != NULL) + OPENSSL_free(header); + if (data != NULL) + OPENSSL_free(data); + name = NULL; + header = NULL; + data = NULL; + } + + /* + * if the last one hasn't been pushed yet and there is anything in it + * then add it to the stack ... + */ + if ((xi->x509 != NULL) || (xi->crl != NULL) || + (xi->x_pkey != NULL) || (xi->enc_data != NULL)) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + xi = NULL; + } + ok = 1; + err: + if (xi != NULL) + X509_INFO_free(xi); + if (!ok) { + for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) { + xi = sk_X509_INFO_value(ret, i); + X509_INFO_free(xi); + } + if (ret != sk) + sk_X509_INFO_free(ret); + ret = NULL; + } + + if (name != NULL) + OPENSSL_free(name); + if (header != NULL) + OPENSSL_free(header); + if (data != NULL) + OPENSSL_free(data); + return (ret); +} + +/* A TJH addition */ +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + EVP_CIPHER_CTX ctx; + int i, ret = 0; + unsigned char *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char *iv = NULL; + + if (enc != NULL) { + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + /* + * now for the fun part ... if we have a private key then we have to be + * able to handle a not-yet-decrypted key being written out correctly ... + * if it is decrypted or it is non-encrypted then we use the base code + */ + if (xi->x_pkey != NULL) { + if ((xi->enc_data != NULL) && (xi->enc_len > 0)) { + if (enc == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_CIPHER_IS_NULL); + goto err; + } + + /* copy from weirdo names into more normal things */ + iv = xi->enc_cipher.iv; + data = (unsigned char *)xi->enc_data; + i = xi->enc_len; + + /* + * we take the encryption data from the internal stuff rather + * than what the user has passed us ... as we have to match + * exactly for some strange reason + */ + objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher)); + if (objstr == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, + PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* create the right magic header stuff */ + OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <= + sizeof(buf)); + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); + + /* use the normal code to write things out */ + i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); + if (i <= 0) + goto err; + } else { + /* Add DSA/DH */ +#ifndef OPENSSL_NO_RSA + /* normal optionally encrypted stuff */ + if (PEM_write_bio_RSAPrivateKey(bp, + xi->x_pkey->dec_pkey->pkey.rsa, + enc, kstr, klen, cb, u) <= 0) + goto err; +#endif + } + } + + /* if we have a certificate then write it out now */ + if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0)) + goto err; + + /* + * we are ignoring anything else that is loaded into the X509_INFO + * structure for the moment ... as I don't need it so I'm not coding it + * here and Eric can do it when this makes it into the base library --tjh + */ + + ret = 1; + + err: + OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); + OPENSSL_cleanse(buf, PEM_BUFSIZE); + return (ret); +} +/* crypto/pem/pem_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "objects.h" +// #include "evp.h" +#include "rand.h" +// #include "x509.h" +// #include "pem.h" +#include "pkcs12.h" +#include "asn1_locl.h" +#ifndef OPENSSL_NO_DES +# include "des.h" +#endif +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +const char PEM_version[] = "PEM" OPENSSL_VERSION_PTEXT; + +#define MIN_LENGTH 4 + +static int load_iv(char **fromp, unsigned char *to, int num); +static int check_pem(const char *nm, const char *name); +int pem_check_suffix(const char *pem_str, const char *suffix); + +int PEM_def_callback(char *buf, int num, int rwflag, void *userdata) +{ + int i, min_len; + const char *prompt; + + /* We assume that the user passes a default password as userdata */ + if (userdata) { + i = strlen(userdata); + i = (i > num) ? num : i; + memcpy(buf, userdata, i); + return i; + } + + prompt = EVP_get_pw_prompt(); + if (prompt == NULL) + prompt = "Enter PEM pass phrase:"; + + /* + * rwflag == 0 means decryption + * rwflag == 1 means encryption + * + * We assume that for encryption, we want a minimum length, while for + * decryption, we cannot know any minimum length, so we assume zero. + */ + min_len = rwflag ? MIN_LENGTH : 0; + + i = EVP_read_pw_string_min(buf, min_len, num, prompt, rwflag); + if (i != 0) { + PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD); + memset(buf, 0, (unsigned int)num); + return -1; + } + return strlen(buf); +} + +void PEM_proc_type(char *buf, int type) +{ + const char *str; + + if (type == PEM_TYPE_ENCRYPTED) + str = "ENCRYPTED"; + else if (type == PEM_TYPE_MIC_CLEAR) + str = "MIC-CLEAR"; + else if (type == PEM_TYPE_MIC_ONLY) + str = "MIC-ONLY"; + else + str = "BAD-TYPE"; + + BUF_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE); + BUF_strlcat(buf, str, PEM_BUFSIZE); + BUF_strlcat(buf, "\n", PEM_BUFSIZE); +} + +void PEM_dek_info(char *buf, const char *type, int len, char *str) +{ + static const unsigned char map[17] = "0123456789ABCDEF"; + long i; + int j; + + BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); + BUF_strlcat(buf, type, PEM_BUFSIZE); + BUF_strlcat(buf, ",", PEM_BUFSIZE); + j = strlen(buf); + if (j + (len * 2) + 1 > PEM_BUFSIZE) + return; + for (i = 0; i < len; i++) { + buf[j + i * 2] = map[(str[i] >> 4) & 0x0f]; + buf[j + i * 2 + 1] = map[(str[i]) & 0x0f]; + } + buf[j + i * 2] = '\n'; + buf[j + i * 2 + 1] = '\0'; +} + +#ifndef OPENSSL_NO_FP_API +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u) +{ + BIO *b; + void *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u); + BIO_free(b); + return (ret); +} +#endif + +static int check_pem(const char *nm, const char *name) +{ + /* Normal matching nm and name */ + if (!strcmp(nm, name)) + return 1; + + /* Make PEM_STRING_EVP_PKEY match any private key */ + + if (!strcmp(name, PEM_STRING_EVP_PKEY)) { + int slen; + const EVP_PKEY_ASN1_METHOD *ameth; + if (!strcmp(nm, PEM_STRING_PKCS8)) + return 1; + if (!strcmp(nm, PEM_STRING_PKCS8INF)) + return 1; + slen = pem_check_suffix(nm, "PRIVATE KEY"); + if (slen > 0) { + /* + * NB: ENGINE implementations wont contain a deprecated old + * private key decode function so don't look for them. + */ + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); + if (ameth && ameth->old_priv_decode) + return 1; + } + return 0; + } + + if (!strcmp(name, PEM_STRING_PARAMETERS)) { + int slen; + const EVP_PKEY_ASN1_METHOD *ameth; + slen = pem_check_suffix(nm, "PARAMETERS"); + if (slen > 0) { + ENGINE *e; + ameth = EVP_PKEY_asn1_find_str(&e, nm, slen); + if (ameth) { + int r; + if (ameth->param_decode) + r = 1; + else + r = 0; +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + return r; + } + } + return 0; + } + /* If reading DH parameters handle X9.42 DH format too */ + if (!strcmp(nm, PEM_STRING_DHXPARAMS) && + !strcmp(name, PEM_STRING_DHPARAMS)) + return 1; + + /* Permit older strings */ + + if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509)) + return 1; + + if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) && + !strcmp(name, PEM_STRING_X509_REQ)) + return 1; + + /* Allow normal certs to be read as trusted certs */ + if (!strcmp(nm, PEM_STRING_X509) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) + return 1; + + if (!strcmp(nm, PEM_STRING_X509_OLD) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) + return 1; + + /* Some CAs use PKCS#7 with CERTIFICATE headers */ + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7)) + return 1; + + if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && + !strcmp(name, PEM_STRING_PKCS7)) + return 1; + +#ifndef OPENSSL_NO_CMS + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS)) + return 1; + /* Allow CMS to be read from PKCS#7 headers */ + if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS)) + return 1; +#endif + + return 0; +} + +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u) +{ + EVP_CIPHER_INFO cipher; + char *nm = NULL, *header = NULL; + unsigned char *data = NULL; + long len; + int ret = 0; + + for (;;) { + if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { + if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) + ERR_add_error_data(2, "Expecting: ", name); + return 0; + } + if (check_pem(nm, name)) + break; + OPENSSL_free(nm); + OPENSSL_free(header); + OPENSSL_free(data); + } + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) + goto err; + if (!PEM_do_header(&cipher, data, &len, cb, u)) + goto err; + + *pdata = data; + *plen = len; + + if (pnm) + *pnm = nm; + + ret = 1; + + err: + if (!ret || !pnm) + OPENSSL_free(nm); + OPENSSL_free(header); + if (!ret) + OPENSSL_free(data); + return ret; +} + +#ifndef OPENSSL_NO_FP_API +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u); + BIO_free(b); + return (ret); +} +#endif + +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u) +{ + EVP_CIPHER_CTX ctx; + int dsize = 0, i, j, ret = 0; + unsigned char *p, *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (enc != NULL) { + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) { + PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + if ((dsize = i2d(x, NULL)) < 0) { + PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB); + dsize = 0; + goto err; + } + /* dzise + 8 bytes are needed */ + /* actually it needs the cipher block size extra... */ + data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20); + if (data == NULL) { + PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + p = data; + i = i2d(x, &p); + + if (enc != NULL) { + if (kstr == NULL) { + if (callback == NULL) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); + else + klen = (*callback) (buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY); + goto err; + } +#ifdef CHARSET_EBCDIC + /* Convert the pass phrase from EBCDIC */ + ebcdic2ascii(buf, buf, klen); +#endif + kstr = (unsigned char *)buf; + } + RAND_add(data, i, 0); /* put in the RSA key. */ + OPENSSL_assert(enc->iv_len <= (int)sizeof(iv)); + if (RAND_bytes(iv, enc->iv_len) <= 0) /* Generate a salt */ + goto err; + /* + * The 'iv' is used as the iv and as a salt. It is NOT taken from + * the BytesToKey function + */ + if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) + goto err; + + if (kstr == (unsigned char *)buf) + OPENSSL_cleanse(buf, PEM_BUFSIZE); + + OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <= + sizeof(buf)); + + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); + /* k=strlen(buf); */ + + EVP_CIPHER_CTX_init(&ctx); + ret = 1; + if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) + || !EVP_EncryptUpdate(&ctx, data, &j, data, i) + || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i)) + ret = 0; + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + goto err; + i += j; + } else { + ret = 1; + buf[0] = '\0'; + } + i = PEM_write_bio(bp, name, buf, data, i); + if (i <= 0) + ret = 0; + err: + OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(iv, sizeof(iv)); + OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); + OPENSSL_cleanse(buf, PEM_BUFSIZE); + if (data != NULL) { + OPENSSL_cleanse(data, (unsigned int)dsize); + OPENSSL_free(data); + } + return (ret); +} + +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, + pem_password_cb *callback, void *u) +{ + int i = 0, j, o, klen; + long len; + EVP_CIPHER_CTX ctx; + unsigned char key[EVP_MAX_KEY_LENGTH]; + char buf[PEM_BUFSIZE]; + + len = *plen; + + if (cipher->cipher == NULL) + return (1); + if (callback == NULL) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u); + else + klen = callback(buf, PEM_BUFSIZE, 0, u); + if (klen < 0) { + PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ); + return (0); + } +#ifdef CHARSET_EBCDIC + /* Convert the pass phrase from EBCDIC */ + ebcdic2ascii(buf, buf, klen); +#endif + + if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]), + (unsigned char *)buf, klen, 1, key, NULL)) + return 0; + + j = (int)len; + EVP_CIPHER_CTX_init(&ctx); + o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0])); + if (o) + o = EVP_DecryptUpdate(&ctx, data, &i, data, j); + if (o) + o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j); + EVP_CIPHER_CTX_cleanup(&ctx); + OPENSSL_cleanse((char *)buf, sizeof(buf)); + OPENSSL_cleanse((char *)key, sizeof(key)); + if (o) + j += i; + else { + PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT); + return (0); + } + *plen = j; + return (1); +} + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) +{ + const EVP_CIPHER *enc = NULL; + char *p, c; + char **header_pp = &header; + + cipher->cipher = NULL; + memset(cipher->iv, 0, sizeof(cipher->iv)); + if ((header == NULL) || (*header == '\0') || (*header == '\n')) + return (1); + if (strncmp(header, "Proc-Type: ", 11) != 0) { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE); + return (0); + } + header += 11; + if (*header != '4') + return (0); + header++; + if (*header != ',') + return (0); + header++; + if (strncmp(header, "ENCRYPTED", 9) != 0) { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED); + return (0); + } + for (; (*header != '\n') && (*header != '\0'); header++) ; + if (*header == '\0') { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER); + return (0); + } + header++; + if (strncmp(header, "DEK-Info: ", 10) != 0) { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO); + return (0); + } + header += 10; + + p = header; + for (;;) { + c = *header; +#ifndef CHARSET_EBCDIC + if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || + ((c >= '0') && (c <= '9')))) + break; +#else + if (!(isupper((unsigned char)c) || (c == '-') + || isdigit((unsigned char)c))) + break; +#endif + header++; + } + *header = '\0'; + cipher->cipher = enc = EVP_get_cipherbyname(p); + *header = c; + header++; + + if (enc == NULL) { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION); + return (0); + } + if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len)) + return (0); + + return (1); +} + +static int load_iv(char **fromp, unsigned char *to, int num) +{ + int v, i; + char *from; + + from = *fromp; + for (i = 0; i < num; i++) + to[i] = 0; + num *= 2; + for (i = 0; i < num; i++) { + if ((*from >= '0') && (*from <= '9')) + v = *from - '0'; + else if ((*from >= 'A') && (*from <= 'F')) + v = *from - 'A' + 10; + else if ((*from >= 'a') && (*from <= 'f')) + v = *from - 'a' + 10; + else { + PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS); + return (0); + } + from++; + to[i / 2] |= v << (long)((!(i & 1)) * 4); + } + + *fromp = from; + return (1); +} + +#ifndef OPENSSL_NO_FP_API +int PEM_write(FILE *fp, const char *name, const char *header, + const unsigned char *data, long len) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_write_bio(b, name, header, data, len); + BIO_free(b); + return (ret); +} +#endif + +int PEM_write_bio(BIO *bp, const char *name, const char *header, + const unsigned char *data, long len) +{ + int nlen, n, i, j, outl; + unsigned char *buf = NULL; + EVP_ENCODE_CTX ctx; + int reason = ERR_R_BUF_LIB; + + EVP_EncodeInit(&ctx); + nlen = strlen(name); + + if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + + i = strlen(header); + if (i > 0) { + if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) + goto err; + } + + buf = OPENSSL_malloc(PEM_BUFSIZE * 8); + if (buf == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + i = j = 0; + while (len > 0) { + n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); + EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n); + if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) + goto err; + i += outl; + len -= n; + j += n; + } + EVP_EncodeFinal(&ctx, buf, &outl); + if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) + goto err; + OPENSSL_cleanse(buf, PEM_BUFSIZE * 8); + OPENSSL_free(buf); + buf = NULL; + if ((BIO_write(bp, "-----END ", 9) != 9) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + return (i + outl); + err: + if (buf) { + OPENSSL_cleanse(buf, PEM_BUFSIZE * 8); + OPENSSL_free(buf); + } + PEMerr(PEM_F_PEM_WRITE_BIO, reason); + return (0); +} + +#ifndef OPENSSL_NO_FP_API +int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, + long *len) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio(b, name, header, data, len); + BIO_free(b); + return (ret); +} +#endif + +int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, + long *len) +{ + EVP_ENCODE_CTX ctx; + int end = 0, i, k, bl = 0, hl = 0, nohead = 0; + char buf[256]; + BUF_MEM *nameB; + BUF_MEM *headerB; + BUF_MEM *dataB, *tmpB; + + nameB = BUF_MEM_new(); + headerB = BUF_MEM_new(); + dataB = BUF_MEM_new(); + if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + return (0); + } + + buf[254] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + + if (i <= 0) { + PEMerr(PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE); + goto err; + } + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (strncmp(buf, "-----BEGIN ", 11) == 0) { + i = strlen(&(buf[11])); + + if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0) + continue; + if (!BUF_MEM_grow(nameB, i + 9)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(nameB->data, &(buf[11]), i - 6); + nameB->data[i - 6] = '\0'; + break; + } + } + hl = 0; + if (!BUF_MEM_grow(headerB, 256)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + headerB->data[0] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (buf[0] == '\n') + break; + if (!BUF_MEM_grow(headerB, hl + i + 9)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + if (strncmp(buf, "-----END ", 9) == 0) { + nohead = 1; + break; + } + memcpy(&(headerB->data[hl]), buf, i); + headerB->data[hl + i] = '\0'; + hl += i; + } + + bl = 0; + if (!BUF_MEM_grow(dataB, 1024)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + dataB->data[0] = '\0'; + if (!nohead) { + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (i != 65) + end = 1; + if (strncmp(buf, "-----END ", 9) == 0) + break; + if (i > 65) + break; + if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(&(dataB->data[bl]), buf, i); + dataB->data[bl + i] = '\0'; + bl += i; + if (end) { + buf[0] = '\0'; + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + break; + } + } + } else { + tmpB = headerB; + headerB = dataB; + dataB = tmpB; + bl = hl; + } + i = strlen(nameB->data); + if ((strncmp(buf, "-----END ", 9) != 0) || + (strncmp(nameB->data, &(buf[9]), i) != 0) || + (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) { + PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE); + goto err; + } + + EVP_DecodeInit(&ctx); + i = EVP_DecodeUpdate(&ctx, + (unsigned char *)dataB->data, &bl, + (unsigned char *)dataB->data, bl); + if (i < 0) { + PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE); + goto err; + } + i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); + if (i < 0) { + PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE); + goto err; + } + bl += k; + + if (bl == 0) + goto err; + *name = nameB->data; + *header = headerB->data; + *data = (unsigned char *)dataB->data; + *len = bl; + OPENSSL_free(nameB); + OPENSSL_free(headerB); + OPENSSL_free(dataB); + return (1); + err: + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + return (0); +} + +/* + * Check pem string and return prefix length. If for example the pem_str == + * "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" the return value is 3 for the + * string "RSA". + */ + +int pem_check_suffix(const char *pem_str, const char *suffix) +{ + int pem_len = strlen(pem_str); + int suffix_len = strlen(suffix); + const char *p; + if (suffix_len + 1 >= pem_len) + return 0; + p = pem_str + pem_len - suffix_len; + if (strcmp(p, suffix)) + return 0; + p--; + if (*p != ' ') + return 0; + return p - pem_str; +} +/* crypto/pem/pem_oth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "objects.h" +// #include "evp.h" +// #include "rand.h" +// #include "x509.h" +// #include "pem.h" + +/* Handle 'other' PEMs: not private keys */ + +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u) +{ + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + char *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) + return NULL; + p = data; + ret = d2i(x, &p, len); + if (ret == NULL) + PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB); + OPENSSL_free(data); + return (ret); +} +/* crypto/pem/pem_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "objects.h" +// #include "evp.h" +// #include "rand.h" +// #include "x509.h" +// #include "pkcs12.h" +// #include "pem.h" + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, + int nid, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u); +static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, + int nid, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u); + +/* + * These functions write a private key in PKCS#8 format: it is a "drop in" + * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' + * is NULL then it uses the unencrypted private key form. The 'nid' versions + * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. + */ + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + X509_SIG *p8; + PKCS8_PRIV_KEY_INFO *p8inf; + char buf[PEM_BUFSIZE]; + int ret; + if (!(p8inf = EVP_PKEY2PKCS8(x))) { + PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + if (enc || (nid != -1)) { + if (!kstr) { + if (!cb) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); + else + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 0; + } + + kstr = buf; + } + p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); + if (kstr == buf) + OPENSSL_cleanse(buf, klen); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (p8 == NULL) + return 0; + if (isder) + ret = i2d_PKCS8_bio(bp, p8); + else + ret = PEM_write_bio_PKCS8(bp, p8); + X509_SIG_free(p8); + return ret; + } else { + if (isder) + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + else + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; + } +} + +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + X509_SIG *p8 = NULL; + int klen; + EVP_PKEY *ret; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_PKCS8_bio(bp, NULL); + if (!p8) + return NULL; + if (cb) + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (klen < 0) { + PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + return NULL; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); + if (!p8inf) + return NULL; + ret = EVP_PKCS82PKEY(p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (!ret) + return NULL; + if (x) { + if (*x) + EVP_PKEY_free(*x); + *x = ret; + } + return ret; +} + +#ifndef OPENSSL_NO_FP_API + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, + void *u) +{ + return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); +} + +static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + BIO *bp; + int ret; + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB); + return (0); + } + ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); + BIO_free(bp); + return ret; +} + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + BIO *bp; + EVP_PKEY *ret; + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP, ERR_R_BUF_LIB); + return NULL; + } + ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); + BIO_free(bp); + return ret; +} + +#endif + +IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) + + +IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, + PKCS8_PRIV_KEY_INFO) +/* crypto/pem/pem_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "objects.h" +// #include "evp.h" +// #include "rand.h" +// #include "x509.h" +// #include "pkcs12.h" +// #include "pem.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +// #include "asn1_locl.h" + +int pem_check_suffix(const char *pem_str, const char *suffix); + +EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + int slen; + EVP_PKEY *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) + return NULL; + p = data; + + if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); + if (!p8inf) + goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + if (*x) + EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + X509_SIG *p8; + int klen; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_X509_SIG(NULL, &p, len); + if (!p8) + goto p8err; + if (cb) + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (klen < 0) { + PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + goto err; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + OPENSSL_cleanse(psbuf, klen); + if (!p8inf) + goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + if (*x) + EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { + const EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); + if (!ameth || !ameth->old_priv_decode) + goto p8err; + ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); + } + p8err: + if (ret == NULL) + PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); + err: + OPENSSL_free(nm); + OPENSSL_cleanse(data, len); + OPENSSL_free(data); + return (ret); +} + +int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + char pem_str[80]; + if (!x->ameth || x->ameth->priv_encode) + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, + (char *)kstr, klen, cb, u); + + BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, + pem_str, bp, x, enc, kstr, klen, cb, u); +} + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + int slen; + EVP_PKEY *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, + bp, 0, NULL)) + return NULL; + p = data; + + if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) { + ret = EVP_PKEY_new(); + if (!ret) + goto err; + if (!EVP_PKEY_set_type_str(ret, nm, slen) + || !ret->ameth->param_decode + || !ret->ameth->param_decode(ret, &p, len)) { + EVP_PKEY_free(ret); + ret = NULL; + goto err; + } + if (x) { + if (*x) + EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + } + err: + if (ret == NULL) + PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB); + OPENSSL_free(nm); + OPENSSL_free(data); + return (ret); +} + +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) +{ + char pem_str[80]; + if (!x->ameth || !x->ameth->param_encode) + return 0; + + BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); + return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, + pem_str, bp, x, NULL, NULL, 0, 0, NULL); +} + +#ifndef OPENSSL_NO_FP_API +EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + BIO *b; + EVP_PKEY *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio_PrivateKey(b, x, cb, u); + BIO_free(b); + return (ret); +} + +int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + BIO *b; + int ret; + + if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { + PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY, ERR_R_BUF_LIB); + return 0; + } + ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); + BIO_free(b); + return ret; +} + +#endif + +#ifndef OPENSSL_NO_DH + +/* Transparently read in PKCS#3 or X9.42 DH parameters */ + +DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + DH *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) + return NULL; + p = data; + + if (!strcmp(nm, PEM_STRING_DHXPARAMS)) + ret = d2i_DHxparams(x, &p, len); + else + ret = d2i_DHparams(x, &p, len); + + if (ret == NULL) + PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB); + OPENSSL_free(nm); + OPENSSL_free(data); + return ret; +} + +# ifndef OPENSSL_NO_FP_API +DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) +{ + BIO *b; + DH *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_READ_DHPARAMS, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio_DHparams(b, x, cb, u); + BIO_free(b); + return (ret); +} +# endif + +#endif +/* crypto/pem/pem_seal.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "opensslconf.h" /* for OPENSSL_NO_RSA */ +#ifndef OPENSSL_NO_RSA +# include +# include "cryptlib.h" +# include "evp.h" +# include "rand.h" +# include "objects.h" +# include "x509.h" +# include "pem.h" +# include "rsa.h" + +int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk) +{ + unsigned char key[EVP_MAX_KEY_LENGTH]; + int ret = -1; + int i, j, max = 0; + char *s = NULL; + + for (i = 0; i < npubk; i++) { + if (pubk[i]->type != EVP_PKEY_RSA) { + PEMerr(PEM_F_PEM_SEALINIT, PEM_R_PUBLIC_KEY_NO_RSA); + goto err; + } + j = RSA_size(pubk[i]->pkey.rsa); + if (j > max) + max = j; + } + s = (char *)OPENSSL_malloc(max * 2); + if (s == NULL) { + PEMerr(PEM_F_PEM_SEALINIT, ERR_R_MALLOC_FAILURE); + goto err; + } + + EVP_EncodeInit(&ctx->encode); + + EVP_MD_CTX_init(&ctx->md); + if (!EVP_SignInit(&ctx->md, md_type)) + goto err; + + EVP_CIPHER_CTX_init(&ctx->cipher); + ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk); + if (ret <= 0) + goto err; + + /* base64 encode the keys */ + for (i = 0; i < npubk; i++) { + j = EVP_EncodeBlock((unsigned char *)s, ek[i], + RSA_size(pubk[i]->pkey.rsa)); + ekl[i] = j; + memcpy(ek[i], s, j + 1); + } + + ret = npubk; + err: + if (s != NULL) + OPENSSL_free(s); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + return (ret); +} + +void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, + unsigned char *in, int inl) +{ + unsigned char buffer[1600]; + int i, j; + + *outl = 0; + EVP_SignUpdate(&ctx->md, in, inl); + for (;;) { + if (inl <= 0) + break; + if (inl > 1200) + i = 1200; + else + i = inl; + EVP_EncryptUpdate(&ctx->cipher, buffer, &j, in, i); + EVP_EncodeUpdate(&ctx->encode, out, &j, buffer, j); + *outl += j; + out += j; + in += i; + inl -= i; + } +} + +int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, + unsigned char *out, int *outl, EVP_PKEY *priv) +{ + unsigned char *s = NULL; + int ret = 0, j; + unsigned int i; + + if (priv->type != EVP_PKEY_RSA) { + PEMerr(PEM_F_PEM_SEALFINAL, PEM_R_PUBLIC_KEY_NO_RSA); + goto err; + } + i = RSA_size(priv->pkey.rsa); + if (i < 100) + i = 100; + s = (unsigned char *)OPENSSL_malloc(i * 2); + if (s == NULL) { + PEMerr(PEM_F_PEM_SEALFINAL, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_EncryptFinal_ex(&ctx->cipher, s, (int *)&i)) + goto err; + EVP_EncodeUpdate(&ctx->encode, out, &j, s, i); + *outl = j; + out += j; + EVP_EncodeFinal(&ctx->encode, out, &j); + *outl += j; + + if (!EVP_SignFinal(&ctx->md, s, &i, priv)) + goto err; + *sigl = EVP_EncodeBlock(sig, s, i); + + ret = 1; + err: + EVP_MD_CTX_cleanup(&ctx->md); + EVP_CIPHER_CTX_cleanup(&ctx->cipher); + if (s != NULL) + OPENSSL_free(s); + return (ret); +} +#else /* !OPENSSL_NO_RSA */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif +/* crypto/pem/pem_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "rand.h" +// #include "evp.h" +// #include "objects.h" +// #include "x509.h" +// #include "pem.h" + +void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) +{ + EVP_DigestInit_ex(ctx, type, NULL); +} + +void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) +{ + EVP_DigestUpdate(ctx, data, count); +} + +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey) +{ + unsigned char *m; + int i, ret = 0; + unsigned int m_len; + + m = (unsigned char *)OPENSSL_malloc(EVP_PKEY_size(pkey) + 2); + if (m == NULL) { + PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0) + goto err; + + i = EVP_EncodeBlock(sigret, m, m_len); + *siglen = i; + ret = 1; + err: + /* ctx has been zeroed by EVP_SignFinal() */ + if (m != NULL) + OPENSSL_free(m); + return (ret); +} +/* pem_x509.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bio.h" +// #include "evp.h" +// #include "x509.h" +// #include "pkcs7.h" +// #include "pem.h" + +IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) +/* pem_xaux.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bio.h" +// #include "evp.h" +// #include "x509.h" +// #include "pkcs7.h" +// #include "pem.h" + +IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX) +IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR, + X509_CERT_PAIR) diff --git a/Sources/COpenSSL/pk12err.c b/Sources/COpenSSL/pk12err.c new file mode 100644 index 00000000..1b8e8cb9 --- /dev/null +++ b/Sources/COpenSSL/pk12err.c @@ -0,0 +1,149 @@ +/* crypto/pkcs12/pk12err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "pkcs12.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason) + +static ERR_STRING_DATA PKCS12_str_functs[] = { + {ERR_FUNC(PKCS12_F_PARSE_BAG), "PARSE_BAG"}, + {ERR_FUNC(PKCS12_F_PARSE_BAGS), "PARSE_BAGS"}, + {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME), "PKCS12_ADD_FRIENDLYNAME"}, + {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC), + "PKCS12_add_friendlyname_asc"}, + {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI), + "PKCS12_add_friendlyname_uni"}, + {ERR_FUNC(PKCS12_F_PKCS12_ADD_LOCALKEYID), "PKCS12_add_localkeyid"}, + {ERR_FUNC(PKCS12_F_PKCS12_CREATE), "PKCS12_create"}, + {ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC), "PKCS12_gen_mac"}, + {ERR_FUNC(PKCS12_F_PKCS12_INIT), "PKCS12_init"}, + {ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I), "PKCS12_item_decrypt_d2i"}, + {ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT), "PKCS12_item_i2d_encrypt"}, + {ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG), "PKCS12_item_pack_safebag"}, + {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC), "PKCS12_key_gen_asc"}, + {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI), "PKCS12_key_gen_uni"}, + {ERR_FUNC(PKCS12_F_PKCS12_MAKE_KEYBAG), "PKCS12_MAKE_KEYBAG"}, + {ERR_FUNC(PKCS12_F_PKCS12_MAKE_SHKEYBAG), "PKCS12_MAKE_SHKEYBAG"}, + {ERR_FUNC(PKCS12_F_PKCS12_NEWPASS), "PKCS12_newpass"}, + {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA), "PKCS12_pack_p7data"}, + {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA), "PKCS12_pack_p7encdata"}, + {ERR_FUNC(PKCS12_F_PKCS12_PARSE), "PKCS12_parse"}, + {ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT), "PKCS12_pbe_crypt"}, + {ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN), "PKCS12_PBE_keyivgen"}, + {ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC), "PKCS12_setup_mac"}, + {ERR_FUNC(PKCS12_F_PKCS12_SET_MAC), "PKCS12_set_mac"}, + {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES), "PKCS12_unpack_authsafes"}, + {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA), "PKCS12_unpack_p7data"}, + {ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"}, + {ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"}, + {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"}, + {0, NULL} +}; + +static ERR_STRING_DATA PKCS12_str_reasons[] = { + {ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"}, + {ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"}, + {ERR_REASON(PKCS12_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(PKCS12_R_ENCODE_ERROR), "encode error"}, + {ERR_REASON(PKCS12_R_ENCRYPT_ERROR), "encrypt error"}, + {ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE), + "error setting encrypted data type"}, + {ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, + {ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER), + "invalid null pkcs12 pointer"}, + {ERR_REASON(PKCS12_R_IV_GEN_ERROR), "iv gen error"}, + {ERR_REASON(PKCS12_R_KEY_GEN_ERROR), "key gen error"}, + {ERR_REASON(PKCS12_R_MAC_ABSENT), "mac absent"}, + {ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR), "mac generation error"}, + {ERR_REASON(PKCS12_R_MAC_SETUP_ERROR), "mac setup error"}, + {ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR), "mac string set error"}, + {ERR_REASON(PKCS12_R_MAC_VERIFY_ERROR), "mac verify error"}, + {ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE), "mac verify failure"}, + {ERR_REASON(PKCS12_R_PARSE_ERROR), "parse error"}, + {ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR), + "pkcs12 algor cipherinit error"}, + {ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR), + "pkcs12 cipherfinal error"}, + {ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR), "pkcs12 pbe crypt error"}, + {ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM), + "unknown digest algorithm"}, + {ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE), "unsupported pkcs12 mode"}, + {0, NULL} +}; + +#endif + +void ERR_load_PKCS12_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) { + ERR_load_strings(0, PKCS12_str_functs); + ERR_load_strings(0, PKCS12_str_reasons); + } +#endif +} diff --git a/Sources/COpenSSL/pk7_.c b/Sources/COpenSSL/pk7_.c new file mode 100644 index 00000000..ee05dacc --- /dev/null +++ b/Sources/COpenSSL/pk7_.c @@ -0,0 +1,3111 @@ +/* pk7_asn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "asn1t.h" +#include "pkcs7.h" +#include "x509.h" + +/* PKCS#7 ASN1 module */ + +/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */ + +ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0); + +ASN1_ADB(PKCS7) = { + ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)), + ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)), + ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)), + ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)), + ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)), + ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) +} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); + +/* PKCS#7 streaming support */ +static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + ASN1_STREAM_ARG *sarg = exarg; + PKCS7 **pp7 = (PKCS7 **)pval; + + switch (operation) { + + case ASN1_OP_STREAM_PRE: + if (PKCS7_stream(&sarg->boundary, *pp7) <= 0) + return 0; + case ASN1_OP_DETACHED_PRE: + sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out); + if (!sarg->ndef_bio) + return 0; + break; + + case ASN1_OP_STREAM_POST: + case ASN1_OP_DETACHED_POST: + if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0) + return 0; + break; + + } + return 1; +} + +ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = { + ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(PKCS7) +}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7) + +IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) + +IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7) + +ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = { + ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7), + ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1), + ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO) +} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) + +/* Minor tweak to operation: free up EVP_PKEY */ +static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; + EVP_PKEY_free(si->pkey); + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = { + ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR), + /* NB this should be a SET OF but we use a SEQUENCE OF so the + * original order * is retained when the structure is reencoded. + * Since the attributes are implicitly tagged this will not affect + * the encoding. + */ + ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1) +} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) + +ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = { + ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME), + ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER) +} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = { + ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), + ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT) +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) + +/* Minor tweak to operation: free up X509 */ +static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; + X509_free(ri->cert); + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = { + ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), + ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR), + ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) + +ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = { + ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), + ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), + ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0) +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) + +ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = { + ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO) +} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) + +ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = { + ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT) +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT) + +ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = { + ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR), + ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7), + ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING) +} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST) + +/* Specials for authenticated attributes */ + +/* + * When signing attributes we want to reorder them to match the sorted + * encoding. + */ + +ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN) + +/* + * When verifying attributes we need to use the received order. So we use + * SEQUENCE OF and tag it to SET OF + */ + +ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, + V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY) + +IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7) +/* pk7_attr.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "bio.h" +#include "asn1.h" +// #include "asn1t.h" +#include "pem.h" +// #include "pkcs7.h" +// #include "x509.h" +#include "err.h" + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap) +{ + ASN1_STRING *seq; + if (!(seq = ASN1_STRING_new())) { + PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data, + ASN1_ITEM_rptr(X509_ALGORS)); + return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, + V_ASN1_SEQUENCE, seq); +} + +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si) +{ + ASN1_TYPE *cap; + const unsigned char *p; + + cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities); + if (!cap || (cap->type != V_ASN1_SEQUENCE)) + return NULL; + p = cap->value.sequence->data; + return (STACK_OF(X509_ALGOR) *) + ASN1_item_d2i(NULL, &p, cap->value.sequence->length, + ASN1_ITEM_rptr(X509_ALGORS)); +} + +/* Basic smime-capabilities OID and optional integer arg */ +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + X509_ALGOR *alg; + + if (!(alg = X509_ALGOR_new())) { + PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(alg->algorithm); + alg->algorithm = OBJ_nid2obj(nid); + if (arg > 0) { + ASN1_INTEGER *nbit; + if (!(alg->parameter = ASN1_TYPE_new())) { + PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!(nbit = ASN1_INTEGER_new())) { + PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!ASN1_INTEGER_set(nbit, arg)) { + PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + alg->parameter->value.integer = nbit; + alg->parameter->type = V_ASN1_INTEGER; + } + sk_X509_ALGOR_push(sk, alg); + return 1; +} + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid) +{ + if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType)) + return 0; + if (!coid) + coid = OBJ_nid2obj(NID_pkcs7_data); + return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, coid); +} + +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t) +{ + if (!t && !(t = X509_gmtime_adj(NULL, 0))) { + PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME, + ERR_R_MALLOC_FAILURE); + return 0; + } + return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, + V_ASN1_UTCTIME, t); +} + +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen) +{ + ASN1_OCTET_STRING *os; + os = ASN1_OCTET_STRING_new(); + if (!os) + return 0; + if (!ASN1_STRING_set(os, md, mdlen) + || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, os)) { + ASN1_OCTET_STRING_free(os); + return 0; + } + return 1; +} +/* crypto/pkcs7/pk7_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "evp.h" +#include "rand.h" +#include "objects.h" +// #include "x509.h" +// #include "pkcs7.h" +/* crypto/pkcs7/pk7_doit.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "rand.h" +// #include "objects.h" +// #include "x509.h" +#include "x509v3.h" +// #include "err.h" + +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, + void *value); +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); + +static int PKCS7_type_is_other(PKCS7 *p7) +{ + int isOther = 1; + + int nid = OBJ_obj2nid(p7->type); + + switch (nid) { + case NID_pkcs7_data: + case NID_pkcs7_signed: + case NID_pkcs7_enveloped: + case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_digest: + case NID_pkcs7_encrypted: + isOther = 0; + break; + default: + isOther = 1; + } + + return isOther; + +} + +static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) +{ + if (PKCS7_type_is_data(p7)) + return p7->d.data; + if (PKCS7_type_is_other(p7) && p7->d.other + && (p7->d.other->type == V_ASN1_OCTET_STRING)) + return p7->d.other->value.octet_string; + return NULL; +} + +static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) +{ + BIO *btmp; + const EVP_MD *md; + if ((btmp = BIO_new(BIO_f_md())) == NULL) { + PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); + goto err; + } + + md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL) { + PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE); + goto err; + } + + BIO_set_md(btmp, md); + if (*pbio == NULL) + *pbio = btmp; + else if (!BIO_push(*pbio, btmp)) { + PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); + goto err; + } + btmp = NULL; + + return 1; + + err: + if (btmp) + BIO_free(btmp); + return 0; + +} + +static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, + unsigned char *key, int keylen) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *pkey = NULL; + unsigned char *ek = NULL; + int ret = 0; + size_t eklen; + + pkey = X509_get_pubkey(ri->cert); + + if (!pkey) + return 0; + + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) { + PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) { + PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) + goto err; + + ASN1_STRING_set0(ri->enc_key, ek, eklen); + ek = NULL; + + ret = 1; + + err: + if (pkey) + EVP_PKEY_free(pkey); + if (pctx) + EVP_PKEY_CTX_free(pctx); + if (ek) + OPENSSL_free(ek); + return ret; + +} + +static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, + PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) +{ + EVP_PKEY_CTX *pctx = NULL; + unsigned char *ek = NULL; + size_t eklen; + + int ret = -1; + + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) + return -1; + + if (EVP_PKEY_decrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, NULL, &eklen, + ri->enc_key->data, ri->enc_key->length) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, ek, &eklen, + ri->enc_key->data, ri->enc_key->length) <= 0) { + ret = 0; + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); + goto err; + } + + ret = 1; + + if (*pek) { + OPENSSL_cleanse(*pek, *peklen); + OPENSSL_free(*pek); + } + + *pek = ek; + *peklen = eklen; + + err: + if (pctx) + EVP_PKEY_CTX_free(pctx); + if (!ret && ek) + OPENSSL_free(ek); + + return ret; +} + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) +{ + int i; + BIO *out = NULL, *btmp = NULL; + X509_ALGOR *xa = NULL; + const EVP_CIPHER *evp_cipher = NULL; + STACK_OF(X509_ALGOR) *md_sk = NULL; + STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; + X509_ALGOR *xalg = NULL; + PKCS7_RECIP_INFO *ri = NULL; + ASN1_OCTET_STRING *os = NULL; + + if (p7 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + /* + * The content field in the PKCS7 ContentInfo is optional, but that really + * only applies to inner content (precisely, detached signatures). + * + * When reading content, missing outer content is therefore treated as an + * error. + * + * When creating content, PKCS7_content_new() must be called before + * calling this method, so a NULL p7->d is always an error. + */ + if (p7->d.ptr == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); + return NULL; + } + + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_signed: + md_sk = p7->d.sign->md_algs; + os = PKCS7_get_octet_string(p7->d.sign->contents); + break; + case NID_pkcs7_signedAndEnveloped: + rsk = p7->d.signed_and_enveloped->recipientinfo; + md_sk = p7->d.signed_and_enveloped->md_algs; + xalg = p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; + if (evp_cipher == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); + goto err; + } + break; + case NID_pkcs7_enveloped: + rsk = p7->d.enveloped->recipientinfo; + xalg = p7->d.enveloped->enc_data->algorithm; + evp_cipher = p7->d.enveloped->enc_data->cipher; + if (evp_cipher == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); + goto err; + } + break; + case NID_pkcs7_digest: + xa = p7->d.digest->md; + os = PKCS7_get_octet_string(p7->d.digest->contents); + break; + case NID_pkcs7_data: + break; + default: + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) + if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) + goto err; + + if (xa && !PKCS7_bio_add_digest(&out, xa)) + goto err; + + if (evp_cipher != NULL) { + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + int keylen, ivlen; + EVP_CIPHER_CTX *ctx; + + if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); + goto err; + } + BIO_get_cipher_ctx(btmp, &ctx); + keylen = EVP_CIPHER_key_length(evp_cipher); + ivlen = EVP_CIPHER_iv_length(evp_cipher); + xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); + if (ivlen > 0) + if (RAND_bytes(iv, ivlen) <= 0) + goto err; + if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) + goto err; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) + goto err; + if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) + goto err; + + if (ivlen > 0) { + if (xalg->parameter == NULL) { + xalg->parameter = ASN1_TYPE_new(); + if (xalg->parameter == NULL) + goto err; + } + if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) + goto err; + } + + /* Lets do the pub key stuff :-) */ + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) + goto err; + } + OPENSSL_cleanse(key, keylen); + + if (out == NULL) + out = btmp; + else + BIO_push(out, btmp); + btmp = NULL; + } + + if (bio == NULL) { + if (PKCS7_is_detached(p7)) { + bio = BIO_new(BIO_s_null()); + } else if (os && os->length > 0) { + bio = BIO_new_mem_buf(os->data, os->length); + } else { + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + goto err; + BIO_set_mem_eof_return(bio, 0); + } + if (bio == NULL) + goto err; + } + if (out) + BIO_push(out, bio); + else + out = bio; + bio = NULL; + if (0) { + err: + if (out != NULL) + BIO_free_all(out); + if (btmp != NULL) + BIO_free_all(btmp); + out = NULL; + } + return (out); +} + +static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) +{ + int ret; + ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, + pcert->cert_info->issuer); + if (ret) + return ret; + return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, + ri->issuer_and_serial->serial); +} + +/* int */ +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) +{ + int i, j; + BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; + X509_ALGOR *xa; + ASN1_OCTET_STRING *data_body = NULL; + const EVP_MD *evp_md; + const EVP_CIPHER *evp_cipher = NULL; + EVP_CIPHER_CTX *evp_ctx = NULL; + X509_ALGOR *enc_alg = NULL; + STACK_OF(X509_ALGOR) *md_sk = NULL; + STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; + PKCS7_RECIP_INFO *ri = NULL; + unsigned char *ek = NULL, *tkey = NULL; + int eklen = 0, tkeylen = 0; + + if (p7 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + + if (p7->d.ptr == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + return NULL; + } + + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_signed: + /* + * p7->d.sign->contents is a PKCS7 structure consisting of a contentType + * field and optional content. + * data_body is NULL if that structure has no (=detached) content + * or if the contentType is wrong (i.e., not "data"). + */ + data_body = PKCS7_get_octet_string(p7->d.sign->contents); + if (!PKCS7_is_detached(p7) && data_body == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_INVALID_SIGNED_DATA_TYPE); + goto err; + } + md_sk = p7->d.sign->md_algs; + break; + case NID_pkcs7_signedAndEnveloped: + rsk = p7->d.signed_and_enveloped->recipientinfo; + md_sk = p7->d.signed_and_enveloped->md_algs; + /* data_body is NULL if the optional EncryptedContent is missing. */ + data_body = p7->d.signed_and_enveloped->enc_data->enc_data; + enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); + if (evp_cipher == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + break; + case NID_pkcs7_enveloped: + rsk = p7->d.enveloped->recipientinfo; + enc_alg = p7->d.enveloped->enc_data->algorithm; + /* data_body is NULL if the optional EncryptedContent is missing. */ + data_body = p7->d.enveloped->enc_data->enc_data; + evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); + if (evp_cipher == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + break; + default: + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + /* Detached content must be supplied via in_bio instead. */ + if (data_body == NULL && in_bio == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + goto err; + } + + /* We will be checking the signature */ + if (md_sk != NULL) { + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { + xa = sk_X509_ALGOR_value(md_sk, i); + if ((btmp = BIO_new(BIO_f_md())) == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); + goto err; + } + + j = OBJ_obj2nid(xa->algorithm); + evp_md = EVP_get_digestbynid(j); + if (evp_md == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_UNKNOWN_DIGEST_TYPE); + goto err; + } + + BIO_set_md(btmp, evp_md); + if (out == NULL) + out = btmp; + else + BIO_push(out, btmp); + btmp = NULL; + } + } + + if (evp_cipher != NULL) { +#if 0 + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char *p; + int keylen, ivlen; + int max; + X509_OBJECT ret; +#endif + + if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); + goto err; + } + + /* + * It was encrypted, we need to decrypt the secret key with the + * private key + */ + + /* + * Find the recipientInfo which matches the passed certificate (if + * any) + */ + + if (pcert) { + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + if (!pkcs7_cmp_ri(ri, pcert)) + break; + ri = NULL; + } + if (ri == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); + goto err; + } + } + + /* If we haven't got a certificate try each ri in turn */ + if (pcert == NULL) { + /* + * Always attempt to decrypt all rinfo even after sucess as a + * defence against MMA timing attacks. + */ + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) + goto err; + ERR_clear_error(); + } + } else { + /* Only exit on fatal errors, not decrypt failure */ + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) + goto err; + ERR_clear_error(); + } + + evp_ctx = NULL; + BIO_get_cipher_ctx(etmp, &evp_ctx); + if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) + goto err; + if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) + goto err; + /* Generate random key as MMA defence */ + tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); + tkey = OPENSSL_malloc(tkeylen); + if (!tkey) + goto err; + if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) + goto err; + if (ek == NULL) { + ek = tkey; + eklen = tkeylen; + tkey = NULL; + } + + if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { + /* + * Some S/MIME clients don't use the same key and effective key + * length. The key length is determined by the size of the + * decrypted RSA key. + */ + if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { + /* Use random key as MMA defence */ + OPENSSL_cleanse(ek, eklen); + OPENSSL_free(ek); + ek = tkey; + eklen = tkeylen; + tkey = NULL; + } + } + /* Clear errors so we don't leak information useful in MMA */ + ERR_clear_error(); + if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) + goto err; + + if (ek) { + OPENSSL_cleanse(ek, eklen); + OPENSSL_free(ek); + ek = NULL; + } + if (tkey) { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + tkey = NULL; + } + + if (out == NULL) + out = etmp; + else + BIO_push(out, etmp); + etmp = NULL; + } +#if 1 + if (in_bio != NULL) { + bio = in_bio; + } else { +# if 0 + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + goto err; + /* + * We need to set this so that when we have read all the data, the + * encrypt BIO, if present, will read EOF and encode the last few + * bytes + */ + BIO_set_mem_eof_return(bio, 0); + + if (data_body->length > 0) + BIO_write(bio, (char *)data_body->data, data_body->length); +# else + if (data_body->length > 0) + bio = BIO_new_mem_buf(data_body->data, data_body->length); + else { + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + goto err; + BIO_set_mem_eof_return(bio, 0); + } + if (bio == NULL) + goto err; +# endif + } + BIO_push(out, bio); + bio = NULL; +#endif + if (0) { + err: + if (ek) { + OPENSSL_cleanse(ek, eklen); + OPENSSL_free(ek); + } + if (tkey) { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + } + if (out != NULL) + BIO_free_all(out); + if (btmp != NULL) + BIO_free_all(btmp); + if (etmp != NULL) + BIO_free_all(etmp); + if (bio != NULL) + BIO_free_all(bio); + out = NULL; + } + return (out); +} + +static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) +{ + for (;;) { + bio = BIO_find_type(bio, BIO_TYPE_MD); + if (bio == NULL) { + PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + return NULL; + } + BIO_get_md_ctx(bio, pmd); + if (*pmd == NULL) { + PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR); + return NULL; + } + if (EVP_MD_CTX_type(*pmd) == nid) + return bio; + bio = BIO_next(bio); + } + return NULL; +} + +static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) +{ + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; + + /* Add signing time if not already present */ + if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { + if (!PKCS7_add0_attrib_signing_time(si, NULL)) { + PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + /* Add digest */ + if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { + PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); + return 0; + } + if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { + PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Now sign the attributes */ + if (!PKCS7_SIGNER_INFO_sign(si)) + return 0; + + return 1; +} + +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) +{ + int ret = 0; + int i, j; + BIO *btmp; + PKCS7_SIGNER_INFO *si; + EVP_MD_CTX *mdc, ctx_tmp; + STACK_OF(X509_ATTRIBUTE) *sk; + STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; + ASN1_OCTET_STRING *os = NULL; + + if (p7 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (p7->d.ptr == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); + return 0; + } + + EVP_MD_CTX_init(&ctx_tmp); + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_data: + os = p7->d.data; + break; + case NID_pkcs7_signedAndEnveloped: + /* XXXXXXXXXXXXXXXX */ + si_sk = p7->d.signed_and_enveloped->signer_info; + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (!os) { + os = M_ASN1_OCTET_STRING_new(); + if (!os) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + goto err; + } + p7->d.signed_and_enveloped->enc_data->enc_data = os; + } + break; + case NID_pkcs7_enveloped: + /* XXXXXXXXXXXXXXXX */ + os = p7->d.enveloped->enc_data->enc_data; + if (!os) { + os = M_ASN1_OCTET_STRING_new(); + if (!os) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + goto err; + } + p7->d.enveloped->enc_data->enc_data = os; + } + break; + case NID_pkcs7_signed: + si_sk = p7->d.sign->signer_info; + os = PKCS7_get_octet_string(p7->d.sign->contents); + /* If detached data then the content is excluded */ + if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { + M_ASN1_OCTET_STRING_free(os); + os = NULL; + p7->d.sign->contents->d.data = NULL; + } + break; + + case NID_pkcs7_digest: + os = PKCS7_get_octet_string(p7->d.digest->contents); + /* If detached data then the content is excluded */ + if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { + M_ASN1_OCTET_STRING_free(os); + os = NULL; + p7->d.digest->contents->d.data = NULL; + } + break; + + default: + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + if (si_sk != NULL) { + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { + si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); + if (si->pkey == NULL) + continue; + + j = OBJ_obj2nid(si->digest_alg->algorithm); + + btmp = bio; + + btmp = PKCS7_find_digest(&mdc, btmp, j); + + if (btmp == NULL) + goto err; + + /* + * We now have the EVP_MD_CTX, lets do the signing. + */ + if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) + goto err; + + sk = si->auth_attr; + + /* + * If there are attributes, we add the digest attribute and only + * sign the attributes + */ + if (sk_X509_ATTRIBUTE_num(sk) > 0) { + if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) + goto err; + } else { + unsigned char *abuf = NULL; + unsigned int abuflen; + abuflen = EVP_PKEY_size(si->pkey); + abuf = OPENSSL_malloc(abuflen); + if (!abuf) + goto err; + + if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); + goto err; + } + ASN1_STRING_set0(si->enc_digest, abuf, abuflen); + } + } + } else if (i == NID_pkcs7_digest) { + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; + if (!PKCS7_find_digest(&mdc, bio, + OBJ_obj2nid(p7->d.digest->md->algorithm))) + goto err; + if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) + goto err; + M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); + } + + if (!PKCS7_is_detached(p7)) { + /* + * NOTE(emilia): I think we only reach os == NULL here because detached + * digested data support is broken. + */ + if (os == NULL) + goto err; + if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { + char *cont; + long contlen; + btmp = BIO_find_type(bio, BIO_TYPE_MEM); + if (btmp == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); + goto err; + } + contlen = BIO_get_mem_data(btmp, &cont); + /* + * Mark the BIO read only then we can use its copy of the data + * instead of making an extra copy. + */ + BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); + BIO_set_mem_eof_return(btmp, 0); + ASN1_STRING_set0(os, (unsigned char *)cont, contlen); + } + } + ret = 1; + err: + EVP_MD_CTX_cleanup(&ctx_tmp); + return (ret); +} + +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) +{ + EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; + unsigned char *abuf = NULL; + int alen; + size_t siglen; + const EVP_MD *md = NULL; + + md = EVP_get_digestbyobj(si->digest_alg->algorithm); + if (md == NULL) + return 0; + + EVP_MD_CTX_init(&mctx); + if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); + goto err; + } + + alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, + ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); + if (!abuf) + goto err; + if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) + goto err; + OPENSSL_free(abuf); + abuf = NULL; + if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) + goto err; + abuf = OPENSSL_malloc(siglen); + if (!abuf) + goto err; + if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); + goto err; + } + + EVP_MD_CTX_cleanup(&mctx); + + ASN1_STRING_set0(si->enc_digest, abuf, siglen); + + return 1; + + err: + if (abuf) + OPENSSL_free(abuf); + EVP_MD_CTX_cleanup(&mctx); + return 0; + +} + +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, + PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + PKCS7_ISSUER_AND_SERIAL *ias; + int ret = 0, i; + STACK_OF(X509) *cert; + X509 *x509; + + if (p7 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (p7->d.ptr == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); + return 0; + } + + if (PKCS7_type_is_signed(p7)) { + cert = p7->d.sign->cert; + } else if (PKCS7_type_is_signedAndEnveloped(p7)) { + cert = p7->d.signed_and_enveloped->cert; + } else { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); + goto err; + } + /* XXXXXXXXXXXXXXXXXXXXXXX */ + ias = si->issuer_and_serial; + + x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); + + /* were we able to find the cert in passed to us */ + if (x509 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, + PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); + goto err; + } + + /* Lets verify */ + if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); + goto err; + } + X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); + i = X509_verify_cert(ctx); + if (i <= 0) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); + X509_STORE_CTX_cleanup(ctx); + goto err; + } + X509_STORE_CTX_cleanup(ctx); + + return PKCS7_signatureVerify(bio, p7, si, x509); + err: + return ret; +} + +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509) +{ + ASN1_OCTET_STRING *os; + EVP_MD_CTX mdc_tmp, *mdc; + int ret = 0, i; + int md_type; + STACK_OF(X509_ATTRIBUTE) *sk; + BIO *btmp; + EVP_PKEY *pkey; + + EVP_MD_CTX_init(&mdc_tmp); + + if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); + goto err; + } + + md_type = OBJ_obj2nid(si->digest_alg->algorithm); + + btmp = bio; + for (;;) { + if ((btmp == NULL) || + ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + goto err; + } + BIO_get_md_ctx(btmp, &mdc); + if (mdc == NULL) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_MD_CTX_type(mdc) == md_type) + break; + /* + * Workaround for some broken clients that put the signature OID + * instead of the digest OID in digest_alg->algorithm + */ + if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) + break; + btmp = BIO_next(btmp); + } + + /* + * mdc is the digest ctx that we want, unless there are attributes, in + * which case the digest is the signed attributes + */ + if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc)) + goto err; + + sk = si->auth_attr; + if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { + unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; + unsigned int md_len; + int alen; + ASN1_OCTET_STRING *message_digest; + + if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) + goto err; + message_digest = PKCS7_digest_from_attributes(sk); + if (!message_digest) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + goto err; + } + if ((message_digest->length != (int)md_len) || + (memcmp(message_digest->data, md_dat, md_len))) { +#if 0 + { + int ii; + for (ii = 0; ii < message_digest->length; ii++) + printf("%02X", message_digest->data[ii]); + printf(" sent\n"); + for (ii = 0; ii < md_len; ii++) + printf("%02X", md_dat[ii]); + printf(" calc\n"); + } +#endif + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); + ret = -1; + goto err; + } + + if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL)) + goto err; + + alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, + ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); + if (alen <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB); + ret = -1; + goto err; + } + if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) + goto err; + + OPENSSL_free(abuf); + } + + os = si->enc_digest; + pkey = X509_get_pubkey(x509); + if (!pkey) { + ret = -1; + goto err; + } + + i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); + EVP_PKEY_free(pkey); + if (i <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); + ret = -1; + goto err; + } else + ret = 1; + err: + EVP_MD_CTX_cleanup(&mdc_tmp); + return (ret); +} + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) +{ + STACK_OF(PKCS7_RECIP_INFO) *rsk; + PKCS7_RECIP_INFO *ri; + int i; + + i = OBJ_obj2nid(p7->type); + if (i != NID_pkcs7_signedAndEnveloped) + return NULL; + if (p7->d.signed_and_enveloped == NULL) + return NULL; + rsk = p7->d.signed_and_enveloped->recipientinfo; + if (rsk == NULL) + return NULL; + if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) + return (NULL); + ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); + return (ri->issuer_and_serial); +} + +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) +{ + return (get_attribute(si->auth_attr, nid)); +} + +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) +{ + return (get_attribute(si->unauth_attr, nid)); +} + +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) +{ + int i; + X509_ATTRIBUTE *xa; + ASN1_OBJECT *o; + + o = OBJ_nid2obj(nid); + if (!o || !sk) + return (NULL); + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + xa = sk_X509_ATTRIBUTE_value(sk, i); + if (OBJ_cmp(xa->object, o) == 0) { + if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) + return (sk_ASN1_TYPE_value(xa->value.set, 0)); + else + return (NULL); + } + } + return (NULL); +} + +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) +{ + ASN1_TYPE *astype; + if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) + return NULL; + return astype->value.octet_string; +} + +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk) +{ + int i; + + if (p7si->auth_attr != NULL) + sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free); + p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk); + if (p7si->auth_attr == NULL) + return 0; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i, + X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value + (sk, i)))) + == NULL) + return (0); + } + return (1); +} + +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk) +{ + int i; + + if (p7si->unauth_attr != NULL) + sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free); + p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk); + if (p7si->unauth_attr == NULL) + return 0; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i, + X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value + (sk, i)))) + == NULL) + return (0); + } + return (1); +} + +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value) +{ + return (add_attribute(&(p7si->auth_attr), nid, atrtype, value)); +} + +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value) +{ + return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value)); +} + +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, + void *value) +{ + X509_ATTRIBUTE *attr = NULL; + + if (*sk == NULL) { + *sk = sk_X509_ATTRIBUTE_new_null(); + if (*sk == NULL) + return 0; + new_attrib: + if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value))) + return 0; + if (!sk_X509_ATTRIBUTE_push(*sk, attr)) { + X509_ATTRIBUTE_free(attr); + return 0; + } + } else { + int i; + + for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) { + attr = sk_X509_ATTRIBUTE_value(*sk, i); + if (OBJ_obj2nid(attr->object) == nid) { + X509_ATTRIBUTE_free(attr); + attr = X509_ATTRIBUTE_create(nid, atrtype, value); + if (attr == NULL) + return 0; + if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) { + X509_ATTRIBUTE_free(attr); + return 0; + } + goto end; + } + } + goto new_attrib; + } + end: + return (1); +} +/* crypto/pkcs7/pk7_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "x509.h" +#include "asn1_locl.h" + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) +{ + int nid; + long ret; + + nid = OBJ_obj2nid(p7->type); + + switch (cmd) { + /* NOTE(emilia): does not support detached digested data. */ + case PKCS7_OP_SET_DETACHED_SIGNATURE: + if (nid == NID_pkcs7_signed) { + ret = p7->detached = (int)larg; + if (ret && PKCS7_type_is_data(p7->d.sign->contents)) { + ASN1_OCTET_STRING *os; + os = p7->d.sign->contents->d.data; + ASN1_OCTET_STRING_free(os); + p7->d.sign->contents->d.data = NULL; + } + } else { + PKCS7err(PKCS7_F_PKCS7_CTRL, + PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + ret = 0; + } + break; + case PKCS7_OP_GET_DETACHED_SIGNATURE: + if (nid == NID_pkcs7_signed) { + if (!p7->d.sign || !p7->d.sign->contents->d.ptr) + ret = 1; + else + ret = 0; + + p7->detached = ret; + } else { + PKCS7err(PKCS7_F_PKCS7_CTRL, + PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + ret = 0; + } + + break; + default: + PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION); + ret = 0; + } + return (ret); +} + +int PKCS7_content_new(PKCS7 *p7, int type) +{ + PKCS7 *ret = NULL; + + if ((ret = PKCS7_new()) == NULL) + goto err; + if (!PKCS7_set_type(ret, type)) + goto err; + if (!PKCS7_set_content(p7, ret)) + goto err; + + return (1); + err: + if (ret != NULL) + PKCS7_free(ret); + return (0); +} + +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) +{ + int i; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + if (p7->d.sign->contents != NULL) + PKCS7_free(p7->d.sign->contents); + p7->d.sign->contents = p7_data; + break; + case NID_pkcs7_digest: + if (p7->d.digest->contents != NULL) + PKCS7_free(p7->d.digest->contents); + p7->d.digest->contents = p7_data; + break; + case NID_pkcs7_data: + case NID_pkcs7_enveloped: + case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_encrypted: + default: + PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + return (1); + err: + return (0); +} + +int PKCS7_set_type(PKCS7 *p7, int type) +{ + ASN1_OBJECT *obj; + + /* + * PKCS7_content_free(p7); + */ + obj = OBJ_nid2obj(type); /* will not fail */ + + switch (type) { + case NID_pkcs7_signed: + p7->type = obj; + if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) { + PKCS7_SIGNED_free(p7->d.sign); + p7->d.sign = NULL; + goto err; + } + break; + case NID_pkcs7_data: + p7->type = obj; + if ((p7->d.data = M_ASN1_OCTET_STRING_new()) == NULL) + goto err; + break; + case NID_pkcs7_signedAndEnveloped: + p7->type = obj; + if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new()) + == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) + goto err; + p7->d.signed_and_enveloped->enc_data->content_type + = OBJ_nid2obj(NID_pkcs7_data); + break; + case NID_pkcs7_enveloped: + p7->type = obj; + if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) + == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0)) + goto err; + p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); + break; + case NID_pkcs7_encrypted: + p7->type = obj; + if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) + == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0)) + goto err; + p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); + break; + + case NID_pkcs7_digest: + p7->type = obj; + if ((p7->d.digest = PKCS7_DIGEST_new()) + == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.digest->version, 0)) + goto err; + break; + default: + PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + return (1); + err: + return (0); +} + +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) +{ + p7->type = OBJ_nid2obj(type); + p7->d.other = other; + return 1; +} + +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) +{ + int i, j, nid; + X509_ALGOR *alg; + STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; + STACK_OF(X509_ALGOR) *md_sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + signer_sk = p7->d.sign->signer_info; + md_sk = p7->d.sign->md_algs; + break; + case NID_pkcs7_signedAndEnveloped: + signer_sk = p7->d.signed_and_enveloped->signer_info; + md_sk = p7->d.signed_and_enveloped->md_algs; + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + nid = OBJ_obj2nid(psi->digest_alg->algorithm); + + /* If the digest is not currently listed, add it */ + j = 0; + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { + alg = sk_X509_ALGOR_value(md_sk, i); + if (OBJ_obj2nid(alg->algorithm) == nid) { + j = 1; + break; + } + } + if (!j) { /* we need to add another algorithm */ + if (!(alg = X509_ALGOR_new()) + || !(alg->parameter = ASN1_TYPE_new())) { + X509_ALGOR_free(alg); + PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE); + return (0); + } + alg->algorithm = OBJ_nid2obj(nid); + alg->parameter->type = V_ASN1_NULL; + if (!sk_X509_ALGOR_push(md_sk, alg)) { + X509_ALGOR_free(alg); + return 0; + } + } + + if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) + return 0; + return (1); +} + +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) +{ + int i; + STACK_OF(X509) **sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + sk = &(p7->d.sign->cert); + break; + case NID_pkcs7_signedAndEnveloped: + sk = &(p7->d.signed_and_enveloped->cert); + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (*sk == NULL) + *sk = sk_X509_new_null(); + if (*sk == NULL) { + PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return 0; + } + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + if (!sk_X509_push(*sk, x509)) { + X509_free(x509); + return 0; + } + return (1); +} + +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) +{ + int i; + STACK_OF(X509_CRL) **sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + sk = &(p7->d.sign->crl); + break; + case NID_pkcs7_signedAndEnveloped: + sk = &(p7->d.signed_and_enveloped->crl); + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (*sk == NULL) + *sk = sk_X509_CRL_new_null(); + if (*sk == NULL) { + PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); + if (!sk_X509_CRL_push(*sk, crl)) { + X509_CRL_free(crl); + return 0; + } + return (1); +} + +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst) +{ + int ret; + + /* We now need to add another PKCS7_SIGNER_INFO entry */ + if (!ASN1_INTEGER_set(p7i->version, 1)) + goto err; + if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, + X509_get_issuer_name(x509))) + goto err; + + /* + * because ASN1_INTEGER_set is used to set a 'long' we will do things the + * ugly way. + */ + M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + if (!(p7i->issuer_and_serial->serial = + M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) + goto err; + + /* lets keep the pkey around for a while */ + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + p7i->pkey = pkey; + + /* Set the algorithms */ + + X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), + V_ASN1_NULL, NULL); + + if (pkey->ameth && pkey->ameth->pkey_ctrl) { + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i); + if (ret > 0) + return 1; + if (ret != -2) { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, + PKCS7_R_SIGNING_CTRL_FAILURE); + return 0; + } + } + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, + PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + err: + return 0; +} + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst) +{ + PKCS7_SIGNER_INFO *si = NULL; + + if (dgst == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) + goto err; + dgst = EVP_get_digestbynid(def_nid); + if (dgst == NULL) { + PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST); + goto err; + } + } + + if ((si = PKCS7_SIGNER_INFO_new()) == NULL) + goto err; + if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) + goto err; + if (!PKCS7_add_signer(p7, si)) + goto err; + return (si); + err: + if (si) + PKCS7_SIGNER_INFO_free(si); + return (NULL); +} + +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) +{ + if (PKCS7_type_is_digest(p7)) { + if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) { + PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + p7->d.digest->md->parameter->type = V_ASN1_NULL; + p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); + return 1; + } + + PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE); + return 1; +} + +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7) +{ + if (p7 == NULL || p7->d.ptr == NULL) + return NULL; + if (PKCS7_type_is_signed(p7)) { + return (p7->d.sign->signer_info); + } else if (PKCS7_type_is_signedAndEnveloped(p7)) { + return (p7->d.signed_and_enveloped->signer_info); + } else + return (NULL); +} + +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig) +{ + if (pk) + *pk = si->pkey; + if (pdig) + *pdig = si->digest_alg; + if (psig) + *psig = si->digest_enc_alg; +} + +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) +{ + if (penc) + *penc = ri->key_enc_algor; +} + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) +{ + PKCS7_RECIP_INFO *ri; + + if ((ri = PKCS7_RECIP_INFO_new()) == NULL) + goto err; + if (!PKCS7_RECIP_INFO_set(ri, x509)) + goto err; + if (!PKCS7_add_recipient_info(p7, ri)) + goto err; + return ri; + err: + if (ri) + PKCS7_RECIP_INFO_free(ri); + return NULL; +} + +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) +{ + int i; + STACK_OF(PKCS7_RECIP_INFO) *sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signedAndEnveloped: + sk = p7->d.signed_and_enveloped->recipientinfo; + break; + case NID_pkcs7_enveloped: + sk = p7->d.enveloped->recipientinfo; + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO, + PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (!sk_PKCS7_RECIP_INFO_push(sk, ri)) + return 0; + return (1); +} + +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) +{ + int ret; + EVP_PKEY *pkey = NULL; + if (!ASN1_INTEGER_set(p7i->version, 0)) + return 0; + if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, + X509_get_issuer_name(x509))) + return 0; + + M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + if (!(p7i->issuer_and_serial->serial = + M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) + return 0; + + pkey = X509_get_pubkey(x509); + + if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i); + if (ret == -2) { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + if (ret <= 0) { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_CTRL_FAILURE); + goto err; + } + + EVP_PKEY_free(pkey); + + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + p7i->cert = x509; + + return 1; + + err: + if (pkey) + EVP_PKEY_free(pkey); + return 0; +} + +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + if (PKCS7_type_is_signed(p7)) + return (X509_find_by_issuer_and_serial(p7->d.sign->cert, + si->issuer_and_serial->issuer, + si-> + issuer_and_serial->serial)); + else + return (NULL); +} + +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) +{ + int i; + PKCS7_ENC_CONTENT *ec; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signedAndEnveloped: + ec = p7->d.signed_and_enveloped->enc_data; + break; + case NID_pkcs7_enveloped: + ec = p7->d.enveloped->enc_data; + break; + default: + PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + /* Check cipher OID exists and has data in it */ + i = EVP_CIPHER_type(cipher); + if (i == NID_undef) { + PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, + PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + return (0); + } + + ec->cipher = cipher; + return 1; +} + +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) +{ + ASN1_OCTET_STRING *os = NULL; + + switch (OBJ_obj2nid(p7->type)) { + case NID_pkcs7_data: + os = p7->d.data; + break; + + case NID_pkcs7_signedAndEnveloped: + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (os == NULL) { + os = M_ASN1_OCTET_STRING_new(); + p7->d.signed_and_enveloped->enc_data->enc_data = os; + } + break; + + case NID_pkcs7_enveloped: + os = p7->d.enveloped->enc_data->enc_data; + if (os == NULL) { + os = M_ASN1_OCTET_STRING_new(); + p7->d.enveloped->enc_data->enc_data = os; + } + break; + + case NID_pkcs7_signed: + os = p7->d.sign->contents->d.data; + break; + + default: + os = NULL; + break; + } + + if (os == NULL) + return 0; + + os->flags |= ASN1_STRING_FLAG_NDEF; + *boundary = &os->data; + + return 1; +} +/* pk7_mime.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "rand.h" +// #include "x509.h" +// #include "asn1.h" + +/* PKCS#7 wrappers round generalised stream and MIME routines */ + +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) +{ + return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags, + ASN1_ITEM_rptr(PKCS7)); +} + +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) +{ + return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)p7, in, flags, + "PKCS7", ASN1_ITEM_rptr(PKCS7)); +} + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) +{ + STACK_OF(X509_ALGOR) *mdalgs; + int ctype_nid = OBJ_obj2nid(p7->type); + if (ctype_nid == NID_pkcs7_signed) + mdalgs = p7->d.sign->md_algs; + else + mdalgs = NULL; + + flags ^= SMIME_OLDMIME; + + return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags, + ctype_nid, NID_undef, mdalgs, + ASN1_ITEM_rptr(PKCS7)); +} + +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) +{ + return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7)); +} +/* pk7_smime.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Simple PKCS#7 processing functions */ + +#include +// #include "cryptlib.h" +// #include "x509.h" +// #include "x509v3.h" + +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags) +{ + PKCS7 *p7; + int i; + + if (!(p7 = PKCS7_new())) { + PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!PKCS7_set_type(p7, NID_pkcs7_signed)) + goto err; + + if (!PKCS7_content_new(p7, NID_pkcs7_data)) + goto err; + + if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) { + PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR); + goto err; + } + + if (!(flags & PKCS7_NOCERTS)) { + for (i = 0; i < sk_X509_num(certs); i++) { + if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) + goto err; + } + } + + if (flags & PKCS7_DETACHED) + PKCS7_set_detached(p7, 1); + + if (flags & (PKCS7_STREAM | PKCS7_PARTIAL)) + return p7; + + if (PKCS7_final(p7, data, flags)) + return p7; + + err: + PKCS7_free(p7); + return NULL; +} + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags) +{ + BIO *p7bio; + int ret = 0; + if (!(p7bio = PKCS7_dataInit(p7, NULL))) { + PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE); + return 0; + } + + SMIME_crlf_copy(data, p7bio, flags); + + (void)BIO_flush(p7bio); + + if (!PKCS7_dataFinal(p7, p7bio)) { + PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN); + goto err; + } + + ret = 1; + + err: + BIO_free_all(p7bio); + + return ret; + +} + +/* Check to see if a cipher exists and if so add S/MIME capabilities */ + +static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + if (EVP_get_cipherbynid(nid)) + return PKCS7_simple_smimecap(sk, nid, arg); + return 1; +} + +static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + if (EVP_get_digestbynid(nid)) + return PKCS7_simple_smimecap(sk, nid, arg); + return 1; +} + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, + EVP_PKEY *pkey, const EVP_MD *md, + int flags) +{ + PKCS7_SIGNER_INFO *si = NULL; + STACK_OF(X509_ALGOR) *smcap = NULL; + if (!X509_check_private_key(signcert, pkey)) { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, + PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return NULL; + } + + if (!(si = PKCS7_add_signature(p7, signcert, pkey, md))) { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, + PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); + return NULL; + } + + if (!(flags & PKCS7_NOCERTS)) { + if (!PKCS7_add_certificate(p7, signcert)) + goto err; + } + + if (!(flags & PKCS7_NOATTR)) { + if (!PKCS7_add_attrib_content_type(si, NULL)) + goto err; + /* Add SMIMECapabilities */ + if (!(flags & PKCS7_NOSMIMECAP)) { + if (!(smcap = sk_X509_ALGOR_new_null())) { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) + || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) + || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) + || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) + || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) + || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 128) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 64) + || !add_cipher_smcap(smcap, NID_des_cbc, -1) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 40) + || !PKCS7_add_attrib_smimecap(si, smcap)) + goto err; + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + smcap = NULL; + } + if (flags & PKCS7_REUSE_DIGEST) { + if (!pkcs7_copy_existing_digest(p7, si)) + goto err; + if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si)) + goto err; + } + } + return si; + err: + if (smcap) + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + return NULL; +} + +/* + * Search for a digest matching SignerInfo digest type and if found copy + * across. + */ + +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + int i; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *sitmp; + ASN1_OCTET_STRING *osdig = NULL; + sinfos = PKCS7_get_signer_info(p7); + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + if (si == sitmp) + break; + if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) + continue; + if (!OBJ_cmp(si->digest_alg->algorithm, sitmp->digest_alg->algorithm)) { + osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); + break; + } + + } + + if (osdig) + return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); + + PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, + PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); + return 0; +} + +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags) +{ + STACK_OF(X509) *signers; + X509 *signer; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *si; + X509_STORE_CTX cert_ctx; + char buf[4096]; + int i, j = 0, k, ret = 0; + BIO *p7bio = NULL; + BIO *tmpin = NULL, *tmpout = NULL; + + if (!p7) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (!PKCS7_type_is_signed(p7)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE); + return 0; + } + + /* Check for no data and no content: no data to verify signature */ + if (PKCS7_get_detached(p7) && !indata) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT); + return 0; + } +#if 0 + /* + * NB: this test commented out because some versions of Netscape + * illegally include zero length content when signing data. Also + * Microsoft Authenticode includes a SpcIndirectDataContent data + * structure which describes the content to be protected by the + * signature, rather than directly embedding that content. So + * Authenticode implementations are also expected to use + * PKCS7_verify() with explicit external data, on non-detached + * PKCS#7 signatures. + * + * In OpenSSL 1.1 a new flag PKCS7_NO_DUAL_CONTENT has been + * introduced to disable this sanity check. For the 1.0.2 branch + * this change is not acceptable, so the check remains completely + * commented out (as it has been for a long time). + */ + + /* Check for data and content: two sets of data */ + if (!PKCS7_get_detached(p7) && indata) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT); + return 0; + } +#endif + + sinfos = PKCS7_get_signer_info(p7); + + if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA); + return 0; + } + + signers = PKCS7_get0_signers(p7, certs, flags); + if (!signers) + return 0; + + /* Now verify the certificates */ + + if (!(flags & PKCS7_NOVERIFY)) + for (k = 0; k < sk_X509_num(signers); k++) { + signer = sk_X509_value(signers, k); + if (!(flags & PKCS7_NOCHAIN)) { + if (!X509_STORE_CTX_init(&cert_ctx, store, signer, + p7->d.sign->cert)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); + goto err; + } + X509_STORE_CTX_set_default(&cert_ctx, "smime_sign"); + } else if (!X509_STORE_CTX_init(&cert_ctx, store, signer, NULL)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); + goto err; + } + if (!(flags & PKCS7_NOCRL)) + X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); + i = X509_verify_cert(&cert_ctx); + if (i <= 0) + j = X509_STORE_CTX_get_error(&cert_ctx); + X509_STORE_CTX_cleanup(&cert_ctx); + if (i <= 0) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, + PKCS7_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(j)); + goto err; + } + /* Check for revocation status here */ + } + + /* + * Performance optimization: if the content is a memory BIO then store + * its contents in a temporary read only memory BIO. This avoids + * potentially large numbers of slow copies of data which will occur when + * reading from a read write memory BIO when signatures are calculated. + */ + + if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) { + char *ptr; + long len; + len = BIO_get_mem_data(indata, &ptr); + tmpin = BIO_new_mem_buf(ptr, len); + if (tmpin == NULL) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + tmpin = indata; + + if (!(p7bio = PKCS7_dataInit(p7, tmpin))) + goto err; + + if (flags & PKCS7_TEXT) { + if (!(tmpout = BIO_new(BIO_s_mem()))) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + BIO_set_mem_eof_return(tmpout, 0); + } else + tmpout = out; + + /* We now have to 'read' from p7bio to calculate digests etc. */ + for (;;) { + i = BIO_read(p7bio, buf, sizeof(buf)); + if (i <= 0) + break; + if (tmpout) + BIO_write(tmpout, buf, i); + } + + if (flags & PKCS7_TEXT) { + if (!SMIME_text(tmpout, out)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR); + BIO_free(tmpout); + goto err; + } + BIO_free(tmpout); + } + + /* Now Verify All Signatures */ + if (!(flags & PKCS7_NOSIGS)) + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + signer = sk_X509_value(signers, i); + j = PKCS7_signatureVerify(p7bio, p7, si, signer); + if (j <= 0) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE); + goto err; + } + } + + ret = 1; + + err: + if (tmpin == indata) { + if (indata) + BIO_pop(p7bio); + } + BIO_free_all(p7bio); + sk_X509_free(signers); + return ret; +} + +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags) +{ + STACK_OF(X509) *signers; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *si; + PKCS7_ISSUER_AND_SERIAL *ias; + X509 *signer; + int i; + + if (!p7) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + + if (!PKCS7_type_is_signed(p7)) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE); + return NULL; + } + + /* Collect all the signers together */ + + sinfos = PKCS7_get_signer_info(p7); + + if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS); + return 0; + } + + if (!(signers = sk_X509_new_null())) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + ias = si->issuer_and_serial; + signer = NULL; + /* If any certificates passed they take priority */ + if (certs) + signer = X509_find_by_issuer_and_serial(certs, + ias->issuer, ias->serial); + if (!signer && !(flags & PKCS7_NOINTERN) + && p7->d.sign->cert) + signer = + X509_find_by_issuer_and_serial(p7->d.sign->cert, + ias->issuer, ias->serial); + if (!signer) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, + PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); + sk_X509_free(signers); + return 0; + } + + if (!sk_X509_push(signers, signer)) { + sk_X509_free(signers); + return NULL; + } + } + return signers; +} + +/* Build a complete PKCS#7 enveloped data */ + +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags) +{ + PKCS7 *p7; + BIO *p7bio = NULL; + int i; + X509 *x509; + if (!(p7 = PKCS7_new())) { + PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) + goto err; + if (!PKCS7_set_cipher(p7, cipher)) { + PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER); + goto err; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + x509 = sk_X509_value(certs, i); + if (!PKCS7_add_recipient(p7, x509)) { + PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT); + goto err; + } + } + + if (flags & PKCS7_STREAM) + return p7; + + if (PKCS7_final(p7, in, flags)) + return p7; + + err: + + BIO_free_all(p7bio); + PKCS7_free(p7); + return NULL; + +} + +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) +{ + BIO *tmpmem; + int ret, i; + char buf[4096]; + + if (!p7) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (!PKCS7_type_is_enveloped(p7)) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE); + return 0; + } + + if (cert && !X509_check_private_key(cert, pkey)) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, + PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return 0; + } + + if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR); + return 0; + } + + if (flags & PKCS7_TEXT) { + BIO *tmpbuf, *bread; + /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ + if (!(tmpbuf = BIO_new(BIO_f_buffer()))) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); + BIO_free_all(tmpmem); + return 0; + } + if (!(bread = BIO_push(tmpbuf, tmpmem))) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); + BIO_free_all(tmpbuf); + BIO_free_all(tmpmem); + return 0; + } + ret = SMIME_text(bread, data); + if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(tmpmem)) + ret = 0; + } + BIO_free_all(bread); + return ret; + } else { + for (;;) { + i = BIO_read(tmpmem, buf, sizeof(buf)); + if (i <= 0) { + ret = 1; + if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(tmpmem)) + ret = 0; + } + + break; + } + if (BIO_write(data, buf, i) != i) { + ret = 0; + break; + } + } + BIO_free_all(tmpmem); + return ret; + } +} diff --git a/Sources/COpenSSL/pk7_enc.h b/Sources/COpenSSL/pk7_enc.h new file mode 100644 index 00000000..f3f4c7ff --- /dev/null +++ b/Sources/COpenSSL/pk7_enc.h @@ -0,0 +1,75 @@ +/* crypto/pkcs7/pk7_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "rand.h" +#include "objects.h" +#include "x509.h" +#include "pkcs7.h" + +PKCS7_in_bio(PKCS7 *p7, BIO *in); +PKCS7_out_bio(PKCS7 *p7, BIO *out); + +PKCS7_add_signer(PKCS7 *p7, X509 *cert, EVP_PKEY *key); +PKCS7_cipher(PKCS7 *p7, EVP_CIPHER *cipher); + +PKCS7_Init(PKCS7 *p7); +PKCS7_Update(PKCS7 *p7); +PKCS7_Finish(PKCS7 *p7); diff --git a/Sources/COpenSSL/pkcs12.h b/Sources/COpenSSL/pkcs12.h new file mode 100644 index 00000000..8674a34a --- /dev/null +++ b/Sources/COpenSSL/pkcs12.h @@ -0,0 +1,342 @@ +/* pkcs12.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PKCS12_H +# define HEADER_PKCS12_H + +# include "bio.h" +# include "x509.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# define PKCS12_KEY_ID 1 +# define PKCS12_IV_ID 2 +# define PKCS12_MAC_ID 3 + +/* Default iteration count */ +# ifndef PKCS12_DEFAULT_ITER +# define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +# endif + +# define PKCS12_MAC_KEY_LENGTH 20 + +# define PKCS12_SALT_LEN 8 + +/* Uncomment out next line for unicode password and names, otherwise ASCII */ + +/* + * #define PBE_UNICODE + */ + +# ifdef PBE_UNICODE +# define PKCS12_key_gen PKCS12_key_gen_uni +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni +# else +# define PKCS12_key_gen PKCS12_key_gen_asc +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc +# endif + +/* MS key usage constants */ + +# define KEY_EX 0x10 +# define KEY_SIG 0x80 + +typedef struct { + X509_SIG *dinfo; + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; /* defaults to 1 */ +} PKCS12_MAC_DATA; + +typedef struct { + ASN1_INTEGER *version; + PKCS12_MAC_DATA *mac; + PKCS7 *authsafes; +} PKCS12; + +typedef struct { + ASN1_OBJECT *type; + union { + struct pkcs12_bag_st *bag; /* secret, crl and certbag */ + struct pkcs8_priv_key_info_st *keybag; /* keybag */ + X509_SIG *shkeybag; /* shrouded key bag */ + STACK_OF(PKCS12_SAFEBAG) *safes; + ASN1_TYPE *other; + } value; + STACK_OF(X509_ATTRIBUTE) *attrib; +} PKCS12_SAFEBAG; + +DECLARE_STACK_OF(PKCS12_SAFEBAG) +DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG) +DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG) + +typedef struct pkcs12_bag_st { + ASN1_OBJECT *type; + union { + ASN1_OCTET_STRING *x509cert; + ASN1_OCTET_STRING *x509crl; + ASN1_OCTET_STRING *octet; + ASN1_IA5STRING *sdsicert; + ASN1_TYPE *other; /* Secret or other bag */ + } value; +} PKCS12_BAGS; + +# define PKCS12_ERROR 0 +# define PKCS12_OK 1 + +/* Compatibility macros */ + +# define M_PKCS12_x5092certbag PKCS12_x5092certbag +# define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag + +# define M_PKCS12_certbag2x509 PKCS12_certbag2x509 +# define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl + +# define M_PKCS12_unpack_p7data PKCS12_unpack_p7data +# define M_PKCS12_pack_authsafes PKCS12_pack_authsafes +# define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes +# define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata + +# define M_PKCS12_decrypt_skey PKCS12_decrypt_skey +# define M_PKCS8_decrypt PKCS8_decrypt + +# define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type) +# define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type) +# define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type + +# define PKCS12_get_attr(bag, attr_nid) \ + PKCS12_get_attr_gen(bag->attrib, attr_nid) + +# define PKCS8_get_attr(p8, attr_nid) \ + PKCS12_get_attr_gen(p8->attributes, attr_nid) + +# define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0) + +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509); +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl); +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, + int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, + const char *pass, int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, + int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, + int passlen, unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, + int passlen, unsigned char *in, int inlen, + unsigned char **data, int *datalen, + int en_de); +void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md_type, int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(unsigned char *uni, int unilen); + +DECLARE_ASN1_FUNCTIONS(PKCS12) +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) + +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int key_nid, char *pass); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS12_strings(void); + +/* Error codes for the PKCS12 functions. */ + +/* Function codes. */ +# define PKCS12_F_PARSE_BAG 129 +# define PKCS12_F_PARSE_BAGS 103 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME 100 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC 127 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI 102 +# define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 +# define PKCS12_F_PKCS12_CREATE 105 +# define PKCS12_F_PKCS12_GEN_MAC 107 +# define PKCS12_F_PKCS12_INIT 109 +# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 +# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 +# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 +# define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +# define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +# define PKCS12_F_PKCS12_MAKE_KEYBAG 112 +# define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 +# define PKCS12_F_PKCS12_NEWPASS 128 +# define PKCS12_F_PKCS12_PACK_P7DATA 114 +# define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +# define PKCS12_F_PKCS12_PARSE 118 +# define PKCS12_F_PKCS12_PBE_CRYPT 119 +# define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +# define PKCS12_F_PKCS12_SETUP_MAC 122 +# define PKCS12_F_PKCS12_SET_MAC 123 +# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 +# define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +# define PKCS12_F_PKCS12_VERIFY_MAC 126 +# define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 +# define PKCS12_F_PKCS8_ENCRYPT 125 + +/* Reason codes. */ +# define PKCS12_R_CANT_PACK_STRUCTURE 100 +# define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 +# define PKCS12_R_DECODE_ERROR 101 +# define PKCS12_R_ENCODE_ERROR 102 +# define PKCS12_R_ENCRYPT_ERROR 103 +# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 +# define PKCS12_R_INVALID_NULL_ARGUMENT 104 +# define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +# define PKCS12_R_IV_GEN_ERROR 106 +# define PKCS12_R_KEY_GEN_ERROR 107 +# define PKCS12_R_MAC_ABSENT 108 +# define PKCS12_R_MAC_GENERATION_ERROR 109 +# define PKCS12_R_MAC_SETUP_ERROR 110 +# define PKCS12_R_MAC_STRING_SET_ERROR 111 +# define PKCS12_R_MAC_VERIFY_ERROR 112 +# define PKCS12_R_MAC_VERIFY_FAILURE 113 +# define PKCS12_R_PARSE_ERROR 114 +# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +# define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/pkcs7.h b/Sources/COpenSSL/pkcs7.h new file mode 100644 index 00000000..64f8a659 --- /dev/null +++ b/Sources/COpenSSL/pkcs7.h @@ -0,0 +1,481 @@ +/* crypto/pkcs7/pkcs7.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PKCS7_H +# define HEADER_PKCS7_H + +# include "asn1.h" +# include "bio.h" +# include "e_os2.h" + +# include "symhacks.h" +# include "ossl_typ.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_SYS_WIN32 +/* Under Win32 thes are defined in wincrypt.h */ +# undef PKCS7_ISSUER_AND_SERIAL +# undef PKCS7_SIGNER_INFO +# endif + +/*- +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + /* The private key to sign with */ + EVP_PKEY *pkey; +} PKCS7_SIGNER_INFO; + +DECLARE_STACK_OF(PKCS7_SIGNER_INFO) +DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ +} PKCS7_RECIP_INFO; + +DECLARE_STACK_OF(PKCS7_RECIP_INFO) +DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* + * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about + * merging the two + */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* + * The following is non NULL if it contains ASN1 encoding of this + * structure + */ + unsigned char *asn1; + long length; +# define PKCS7_S_HEADER 0 +# define PKCS7_S_BODY 1 +# define PKCS7_S_TAIL 2 + int state; /* used during processing */ + int detached; + ASN1_OBJECT *type; + /* content as defined by the type */ + /* + * all encryption/message digests are applied to the 'contents', leaving + * out the 'type' field. + */ + union { + char *ptr; + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + /* Anything else */ + ASN1_TYPE *other; + } d; +} PKCS7; + +DECLARE_STACK_OF(PKCS7) +DECLARE_ASN1_SET_OF(PKCS7) +DECLARE_PKCS12_STACK_OF(PKCS7) + +# define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +# define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +# define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +# define PKCS7_get_attributes(si) ((si)->unauth_attr) + +# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +# define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +# define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +# define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +# define PKCS7_TEXT 0x1 +# define PKCS7_NOCERTS 0x2 +# define PKCS7_NOSIGS 0x4 +# define PKCS7_NOCHAIN 0x8 +# define PKCS7_NOINTERN 0x10 +# define PKCS7_NOVERIFY 0x20 +# define PKCS7_DETACHED 0x40 +# define PKCS7_BINARY 0x80 +# define PKCS7_NOATTR 0x100 +# define PKCS7_NOSMIMECAP 0x200 +# define PKCS7_NOOLDMIMETYPE 0x400 +# define PKCS7_CRLFEOL 0x800 +# define PKCS7_STREAM 0x1000 +# define PKCS7_NOCRL 0x2000 +# define PKCS7_PARTIAL 0x4000 +# define PKCS7_REUSE_DIGEST 0x8000 + +/* Flags: for compatibility with older code */ + +# define SMIME_TEXT PKCS7_TEXT +# define SMIME_NOCERTS PKCS7_NOCERTS +# define SMIME_NOSIGS PKCS7_NOSIGS +# define SMIME_NOCHAIN PKCS7_NOCHAIN +# define SMIME_NOINTERN PKCS7_NOINTERN +# define SMIME_NOVERIFY PKCS7_NOVERIFY +# define SMIME_DETACHED PKCS7_DETACHED +# define SMIME_BINARY PKCS7_BINARY +# define SMIME_NOATTR PKCS7_NOATTR + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len); +# ifndef OPENSSL_NO_FP_API +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); +# endif +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, + const EVP_MD *md, int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, + int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS7_strings(void); + +/* Error codes for the PKCS7 functions. */ + +/* Function codes. */ +# define PKCS7_F_B64_READ_PKCS7 120 +# define PKCS7_F_B64_WRITE_PKCS7 121 +# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +# define PKCS7_F_I2D_PKCS7_BIO_STREAM 140 +# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +# define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +# define PKCS7_F_PKCS7_ADD_CRL 101 +# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +# define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +# define PKCS7_F_PKCS7_ADD_SIGNER 103 +# define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +# define PKCS7_F_PKCS7_CTRL 104 +# define PKCS7_F_PKCS7_DATADECODE 112 +# define PKCS7_F_PKCS7_DATAFINAL 128 +# define PKCS7_F_PKCS7_DATAINIT 105 +# define PKCS7_F_PKCS7_DATASIGN 106 +# define PKCS7_F_PKCS7_DATAVERIFY 107 +# define PKCS7_F_PKCS7_DECRYPT 114 +# define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +# define PKCS7_F_PKCS7_ENCODE_RINFO 132 +# define PKCS7_F_PKCS7_ENCRYPT 115 +# define PKCS7_F_PKCS7_FINAL 134 +# define PKCS7_F_PKCS7_FIND_DIGEST 127 +# define PKCS7_F_PKCS7_GET0_SIGNERS 124 +# define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +# define PKCS7_F_PKCS7_SET_CIPHER 108 +# define PKCS7_F_PKCS7_SET_CONTENT 109 +# define PKCS7_F_PKCS7_SET_DIGEST 126 +# define PKCS7_F_PKCS7_SET_TYPE 110 +# define PKCS7_F_PKCS7_SIGN 116 +# define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +# define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +# define PKCS7_F_PKCS7_VERIFY 117 +# define PKCS7_F_SMIME_READ_PKCS7 122 +# define PKCS7_F_SMIME_TEXT 123 + +/* Reason codes. */ +# define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +# define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +# define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +# define PKCS7_R_CTRL_ERROR 152 +# define PKCS7_R_DECODE_ERROR 130 +# define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 +# define PKCS7_R_DECRYPT_ERROR 119 +# define PKCS7_R_DIGEST_FAILURE 101 +# define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +# define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +# define PKCS7_R_ERROR_SETTING_CIPHER 121 +# define PKCS7_R_INVALID_MIME_TYPE 131 +# define PKCS7_R_INVALID_NULL_POINTER 143 +# define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155 +# define PKCS7_R_MIME_NO_CONTENT_TYPE 132 +# define PKCS7_R_MIME_PARSE_ERROR 133 +# define PKCS7_R_MIME_SIG_PARSE_ERROR 134 +# define PKCS7_R_MISSING_CERIPEND_INFO 103 +# define PKCS7_R_NO_CONTENT 122 +# define PKCS7_R_NO_CONTENT_TYPE 135 +# define PKCS7_R_NO_DEFAULT_DIGEST 151 +# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +# define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 +# define PKCS7_R_NO_MULTIPART_BOUNDARY 137 +# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +# define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146 +# define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +# define PKCS7_R_NO_SIGNERS 142 +# define PKCS7_R_NO_SIG_CONTENT_TYPE 138 +# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +# define PKCS7_R_PKCS7_DATAFINAL 126 +# define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 +# define PKCS7_R_PKCS7_DATASIGN 145 +# define PKCS7_R_PKCS7_PARSE_ERROR 139 +# define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140 +# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +# define PKCS7_R_SIGNATURE_FAILURE 105 +# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +# define PKCS7_R_SIGNING_CTRL_FAILURE 147 +# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +# define PKCS7_R_SIG_INVALID_MIME_TYPE 141 +# define PKCS7_R_SMIME_TEXT_ERROR 129 +# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +# define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +# define PKCS7_R_UNKNOWN_OPERATION 110 +# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +# define PKCS7_R_WRONG_CONTENT_TYPE 113 +# define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/pkcs7err.c b/Sources/COpenSSL/pkcs7err.c new file mode 100644 index 00000000..57a43435 --- /dev/null +++ b/Sources/COpenSSL/pkcs7err.c @@ -0,0 +1,207 @@ +/* crypto/pkcs7/pkcs7err.c */ +/* ==================================================================== + * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "pkcs7.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason) + +static ERR_STRING_DATA PKCS7_str_functs[] = { + {ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"}, + {ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"}, + {ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB), "DO_PKCS7_SIGNED_ATTRIB"}, + {ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM), "i2d_PKCS7_bio_stream"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME), + "PKCS7_add0_attrib_signing_time"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), + "PKCS7_add_attrib_smimecap"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"}, + {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"}, + {ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST), + "PKCS7_COPY_EXISTING_DIGEST"}, + {ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATAINIT), "PKCS7_dataInit"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"}, + {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"}, + {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "PKCS7_DECRYPT_RINFO"}, + {ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "PKCS7_ENCODE_RINFO"}, + {ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"}, + {ERR_FUNC(PKCS7_F_PKCS7_FINAL), "PKCS7_final"}, + {ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"}, + {ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"}, + {ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET), "PKCS7_RECIP_INFO_set"}, + {ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"}, + {ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"}, + {ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"}, + {ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"}, + {ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"}, + {ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"}, + {ERR_FUNC(PKCS7_F_SMIME_TEXT), "SMIME_text"}, + {0, NULL} +}; + +static ERR_STRING_DATA PKCS7_str_reasons[] = { + {ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR), + "certificate verify error"}, + {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), + "cipher has no object identifier"}, + {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED), "cipher not initialized"}, + {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT), + "content and data present"}, + {ERR_REASON(PKCS7_R_CTRL_ERROR), "ctrl error"}, + {ERR_REASON(PKCS7_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH), + "decrypted key is wrong length"}, + {ERR_REASON(PKCS7_R_DECRYPT_ERROR), "decrypt error"}, + {ERR_REASON(PKCS7_R_DIGEST_FAILURE), "digest failure"}, + {ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE), "encryption ctrl failure"}, + {ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), + "encryption not supported for this key type"}, + {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT), "error adding recipient"}, + {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER), "error setting cipher"}, + {ERR_REASON(PKCS7_R_INVALID_MIME_TYPE), "invalid mime type"}, + {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"}, + {ERR_REASON(PKCS7_R_INVALID_SIGNED_DATA_TYPE), + "invalid signed data type"}, + {ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE), "mime no content type"}, + {ERR_REASON(PKCS7_R_MIME_PARSE_ERROR), "mime parse error"}, + {ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"}, + {ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO), "missing ceripend info"}, + {ERR_REASON(PKCS7_R_NO_CONTENT), "no content"}, + {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE), "no content type"}, + {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND), + "no matching digest type found"}, + {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE), + "no multipart body failure"}, + {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"}, + {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE), + "no recipient matches certificate"}, + {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY), + "no recipient matches key"}, + {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"}, + {ERR_REASON(PKCS7_R_NO_SIGNERS), "no signers"}, + {ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE), "no sig content type"}, + {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE), + "operation not supported on this type"}, + {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR), + "pkcs7 add signature error"}, + {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR), "pkcs7 add signer error"}, + {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL), "pkcs7 datafinal"}, + {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR), "pkcs7 datafinal error"}, + {ERR_REASON(PKCS7_R_PKCS7_DATASIGN), "pkcs7 datasign"}, + {ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR), "pkcs7 parse error"}, + {ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR), "pkcs7 sig parse error"}, + {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE), "signature failure"}, + {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND), + "signer certificate not found"}, + {ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE), "signing ctrl failure"}, + {ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), + "signing not supported for this key type"}, + {ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"}, + {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR), "smime text error"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE), + "unable to find certificate"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST), + "unable to find message digest"}, + {ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE), "unknown digest type"}, + {ERR_REASON(PKCS7_R_UNKNOWN_OPERATION), "unknown operation"}, + {ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"}, + {ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE), + "unsupported content type"}, + {ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE), "wrong content type"}, + {ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE), "wrong pkcs7 type"}, + {0, NULL} +}; + +#endif + +void ERR_load_PKCS7_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) { + ERR_load_strings(0, PKCS7_str_functs); + ERR_load_strings(0, PKCS7_str_reasons); + } +#endif +} diff --git a/Sources/COpenSSL/pmeth_.c b/Sources/COpenSSL/pmeth_.c new file mode 100644 index 00000000..5a59488f --- /dev/null +++ b/Sources/COpenSSL/pmeth_.c @@ -0,0 +1,1328 @@ +/* pmeth_fn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include "objects.h" +#include "evp.h" +#include "evp_locl.h" + +#define M_check_autoarg(ctx, arg, arglen, err) \ + if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \ + size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ + \ + if (pksize == 0) { \ + EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \ + return 0; \ + } \ + if (!arg) { \ + *arglen = pksize; \ + return 1; \ + } \ + if (*arglen < pksize) { \ + EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \ + return 0; \ + } \ + } + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + EVPerr(EVP_F_EVP_PKEY_SIGN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_SIGN; + if (!ctx->pmeth->sign_init) + return 1; + ret = ctx->pmeth->sign_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + EVPerr(EVP_F_EVP_PKEY_SIGN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_SIGN) { + EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) + return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); +} + +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_VERIFY; + if (!ctx->pmeth->verify_init) + return 1; + ret = ctx->pmeth->verify_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + EVPerr(EVP_F_EVP_PKEY_VERIFY, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_VERIFY) { + EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); +} + +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; + if (!ctx->pmeth->verify_recover_init) + return 1; + ret = ctx->pmeth->verify_recover_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) + return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); +} + +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_ENCRYPT; + if (!ctx->pmeth->encrypt_init) + return 1; + ret = ctx->pmeth->encrypt_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) + return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_DECRYPT; + if (!ctx->pmeth->decrypt_init) + return 1; + ret = ctx->pmeth->decrypt_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + EVPerr(EVP_F_EVP_PKEY_DECRYPT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DECRYPT) { + EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) + return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_DERIVE; + if (!ctx->pmeth->derive_init) + return 1; + ret = ctx->pmeth->derive_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) +{ + int ret; + if (!ctx || !ctx->pmeth + || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) + || !ctx->pmeth->ctrl) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE + && ctx->operation != EVP_PKEY_OP_ENCRYPT + && ctx->operation != EVP_PKEY_OP_DECRYPT) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) + return ret; + + if (ret == 2) + return 1; + + if (!ctx->pkey) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); + return -1; + } + + if (ctx->pkey->type != peer->type) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES); + return -1; + } + + /* + * ran@cryptocom.ru: For clarity. The error is if parameters in peer are + * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return + * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 + * (different key types) is impossible here because it is checked earlier. + * -2 is OK for us here, as well as 1, so we can check for 0 only. + */ + if (!EVP_PKEY_missing_parameters(peer) && + !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS); + return -1; + } + + if (ctx->peerkey) + EVP_PKEY_free(ctx->peerkey); + ctx->peerkey = peer; + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); + + if (ret <= 0) { + ctx->peerkey = NULL; + return ret; + } + + CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY); + return 1; +} + +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + EVPerr(EVP_F_EVP_PKEY_DERIVE, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE) { + EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) + return ctx->pmeth->derive(ctx, key, pkeylen); +} +/* pmeth_gn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "evp.h" +#include "bn.h" +// #include "evp_locl.h" + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_PARAMGEN; + if (!ctx->pmeth->paramgen_init) + return 1; + ret = ctx->pmeth->paramgen_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ppkey == NULL) + return -1; + + if (*ppkey == NULL) + *ppkey = EVP_PKEY_new(); + + if (*ppkey == NULL) { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE); + return -1; + } + + ret = ctx->pmeth->paramgen(ctx, *ppkey); + if (ret <= 0) { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + } + return ret; +} + +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_KEYGEN; + if (!ctx->pmeth->keygen_init) + return 1; + ret = ctx->pmeth->keygen_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + EVPerr(EVP_F_EVP_PKEY_KEYGEN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_KEYGEN) { + EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (!ppkey) + return -1; + + if (*ppkey == NULL) + *ppkey = EVP_PKEY_new(); + if (*ppkey == NULL) + return -1; + + ret = ctx->pmeth->keygen(ctx, *ppkey); + if (ret <= 0) { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + } + return ret; +} + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) +{ + ctx->pkey_gencb = cb; +} + +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx) +{ + return ctx->pkey_gencb; +} + +/* + * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style + * callbacks. + */ + +static int trans_cb(int a, int b, BN_GENCB *gcb) +{ + EVP_PKEY_CTX *ctx = gcb->arg; + ctx->keygen_info[0] = a; + ctx->keygen_info[1] = b; + return ctx->pkey_gencb(ctx); +} + +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx) +{ + BN_GENCB_set(cb, trans_cb, ctx) +} + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) +{ + if (idx == -1) + return ctx->keygen_info_count; + if (idx < 0 || idx > ctx->keygen_info_count) + return 0; + return ctx->keygen_info[idx]; +} + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + const unsigned char *key, int keylen) +{ + EVP_PKEY_CTX *mac_ctx = NULL; + EVP_PKEY *mac_key = NULL; + mac_ctx = EVP_PKEY_CTX_new_id(type, e); + if (!mac_ctx) + return NULL; + if (EVP_PKEY_keygen_init(mac_ctx) <= 0) + goto merr; + if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, + keylen, (void *)key) <= 0) + goto merr; + if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) + goto merr; + merr: + if (mac_ctx) + EVP_PKEY_CTX_free(mac_ctx); + return mac_key; +} +/* pmeth_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "evp.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +#include "asn1_locl.h" +// #include "evp_locl.h" + +typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); + +DECLARE_STACK_OF(EVP_PKEY_METHOD) +STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; + +extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth; +extern const EVP_PKEY_METHOD dhx_pkey_meth; + +static const EVP_PKEY_METHOD *standard_methods[] = { +#ifndef OPENSSL_NO_RSA + &rsa_pkey_meth, +#endif +#ifndef OPENSSL_NO_DH + &dh_pkey_meth, +#endif +#ifndef OPENSSL_NO_DSA + &dsa_pkey_meth, +#endif +#ifndef OPENSSL_NO_EC + &ec_pkey_meth, +#endif + &hmac_pkey_meth, +#ifndef OPENSSL_NO_CMAC + &cmac_pkey_meth, +#endif +#ifndef OPENSSL_NO_DH + &dhx_pkey_meth +#endif +}; + +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, + pmeth); + +static int pmeth_cmp(const EVP_PKEY_METHOD *const *a, + const EVP_PKEY_METHOD *const *b) +{ + return ((*a)->pkey_id - (*b)->pkey_id); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, + pmeth); + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) +{ + EVP_PKEY_METHOD tmp; + const EVP_PKEY_METHOD *t = &tmp, **ret; + tmp.pkey_id = type; + if (app_pkey_methods) { + int idx; + idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp); + if (idx >= 0) + return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); + } + ret = OBJ_bsearch_pmeth(&t, standard_methods, + sizeof(standard_methods) / + sizeof(EVP_PKEY_METHOD *)); + if (!ret || !*ret) + return NULL; + return *ret; +} + +static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) +{ + EVP_PKEY_CTX *ret; + const EVP_PKEY_METHOD *pmeth; + if (id == -1) { + if (!pkey || !pkey->ameth) + return NULL; + id = pkey->ameth->pkey_id; + } +#ifndef OPENSSL_NO_ENGINE + if (pkey && pkey->engine) + e = pkey->engine; + /* Try to find an ENGINE which implements this method */ + if (e) { + if (!ENGINE_init(e)) { + EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB); + return NULL; + } + } else + e = ENGINE_get_pkey_meth_engine(id); + + /* + * If an ENGINE handled this method look it up. Othewise use internal + * tables. + */ + + if (e) + pmeth = ENGINE_get_pkey_meth(e, id); + else +#endif + pmeth = EVP_PKEY_meth_find(id); + + if (pmeth == NULL) { + EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) { +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->engine = e; + ret->pmeth = pmeth; + ret->operation = EVP_PKEY_OP_UNDEFINED; + ret->pkey = pkey; + ret->peerkey = NULL; + ret->pkey_gencb = 0; + if (pkey) + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + ret->data = NULL; + + if (pmeth->init) { + if (pmeth->init(ret) <= 0) { + ret->pmeth = NULL; + EVP_PKEY_CTX_free(ret); + return NULL; + } + } + + return ret; +} + +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) +{ + EVP_PKEY_METHOD *pmeth; + + pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD)); + if (!pmeth) + return NULL; + + memset(pmeth, 0, sizeof(EVP_PKEY_METHOD)); + + pmeth->pkey_id = id; + pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; + return pmeth; +} + +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth) +{ + if (ppkey_id) + *ppkey_id = meth->pkey_id; + if (pflags) + *pflags = meth->flags; +} + +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) +{ + + dst->init = src->init; + dst->copy = src->copy; + dst->cleanup = src->cleanup; + + dst->paramgen_init = src->paramgen_init; + dst->paramgen = src->paramgen; + + dst->keygen_init = src->keygen_init; + dst->keygen = src->keygen; + + dst->sign_init = src->sign_init; + dst->sign = src->sign; + + dst->verify_init = src->verify_init; + dst->verify = src->verify; + + dst->verify_recover_init = src->verify_recover_init; + dst->verify_recover = src->verify_recover; + + dst->signctx_init = src->signctx_init; + dst->signctx = src->signctx; + + dst->verifyctx_init = src->verifyctx_init; + dst->verifyctx = src->verifyctx; + + dst->encrypt_init = src->encrypt_init; + dst->encrypt = src->encrypt; + + dst->decrypt_init = src->decrypt_init; + dst->decrypt = src->decrypt; + + dst->derive_init = src->derive_init; + dst->derive = src->derive; + + dst->ctrl = src->ctrl; + dst->ctrl_str = src->ctrl_str; +} + +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) +{ + if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC)) + OPENSSL_free(pmeth); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) +{ + return int_ctx_new(pkey, e, -1); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) +{ + return int_ctx_new(NULL, e, id); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) +{ + EVP_PKEY_CTX *rctx; + if (!pctx->pmeth || !pctx->pmeth->copy) + return NULL; +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a pkey context using an ENGINE */ + if (pctx->engine && !ENGINE_init(pctx->engine)) { + EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB); + return 0; + } +#endif + rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!rctx) + return NULL; + + rctx->pmeth = pctx->pmeth; +#ifndef OPENSSL_NO_ENGINE + rctx->engine = pctx->engine; +#endif + + if (pctx->pkey) + CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + + rctx->pkey = pctx->pkey; + + if (pctx->peerkey) + CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + + rctx->peerkey = pctx->peerkey; + + rctx->data = NULL; + rctx->app_data = NULL; + rctx->operation = pctx->operation; + + if (pctx->pmeth->copy(rctx, pctx) > 0) + return rctx; + + rctx->pmeth = NULL; + EVP_PKEY_CTX_free(rctx); + return NULL; + +} + +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) +{ + if (app_pkey_methods == NULL) { + app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp); + if (!app_pkey_methods) + return 0; + } + if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) + return 0; + sk_EVP_PKEY_METHOD_sort(app_pkey_methods); + return 1; +} + +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL) + return; + if (ctx->pmeth && ctx->pmeth->cleanup) + ctx->pmeth->cleanup(ctx); + if (ctx->pkey) + EVP_PKEY_free(ctx->pkey); + if (ctx->peerkey) + EVP_PKEY_free(ctx->peerkey); +#ifndef OPENSSL_NO_ENGINE + if (ctx->engine) + /* + * The EVP_PKEY_CTX we used belongs to an ENGINE, release the + * functional reference we held for this reason. + */ + ENGINE_finish(ctx->engine); +#endif + OPENSSL_free(ctx); +} + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) + return -1; + + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET); + return -1; + } + + if ((optype != -1) && !(ctx->operation & optype)) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); + + if (ret == -2) + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + + return ret; + +} + +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, + const char *name, const char *value) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!strcmp(name, "digest")) { + const EVP_MD *md; + if (!value || !(md = EVP_get_digestbyname(value))) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_set_signature_md(ctx, md); + } + return ctx->pmeth->ctrl_str(ctx, name, value); +} + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx) +{ + return ctx->operation; +} + +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen) +{ + ctx->keygen_info = dat; + ctx->keygen_info_count = datlen; +} + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data) +{ + ctx->data = data; +} + +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx) +{ + return ctx->data; +} + +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) +{ + return ctx->pkey; +} + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx) +{ + return ctx->peerkey; +} + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) +{ + ctx->app_data = data; +} + +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) +{ + return ctx->app_data; +} + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)) +{ + pmeth->init = init; +} + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)) +{ + pmeth->copy = copy; +} + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)) +{ + pmeth->cleanup = cleanup; +} + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + pmeth->paramgen_init = paramgen_init; + pmeth->paramgen = paramgen; +} + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + pmeth->keygen_init = keygen_init; + pmeth->keygen = keygen; +} + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + pmeth->sign_init = sign_init; + pmeth->sign = sign; +} + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + pmeth->verify_init = verify_init; + pmeth->verify = verify; +} + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)) +{ + pmeth->verify_recover_init = verify_recover_init; + pmeth->verify_recover = verify_recover; +} + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)) +{ + pmeth->signctx_init = signctx_init; + pmeth->signctx = signctx; +} + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)) +{ + pmeth->verifyctx_init = verifyctx_init; + pmeth->verifyctx = verifyctx; +} + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + pmeth->encrypt_init = encrypt_init; + pmeth->encrypt = encryptfn; +} + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + pmeth->decrypt_init = decrypt_init; + pmeth->decrypt = decrypt; +} + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)) +{ + pmeth->derive_init = derive_init; + pmeth->derive = derive; +} + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)) +{ + pmeth->ctrl = ctrl; + pmeth->ctrl_str = ctrl_str; +} + +void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, + int (**pinit) (EVP_PKEY_CTX *ctx)) +{ + *pinit = pmeth->init; +} + +void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, + int (**pcopy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)) +{ + *pcopy = pmeth->copy; +} + +void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, + void (**pcleanup) (EVP_PKEY_CTX *ctx)) +{ + *pcleanup = pmeth->cleanup; +} + +void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, + int (**pparamgen_init) (EVP_PKEY_CTX *ctx), + int (**pparamgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + if (pparamgen_init) + *pparamgen_init = pmeth->paramgen_init; + if (pparamgen) + *pparamgen = pmeth->paramgen; +} + +void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, + int (**pkeygen_init) (EVP_PKEY_CTX *ctx), + int (**pkeygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + if (pkeygen_init) + *pkeygen_init = pmeth->keygen_init; + if (pkeygen) + *pkeygen = pmeth->keygen; +} + +void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, + int (**psign_init) (EVP_PKEY_CTX *ctx), + int (**psign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + if (psign_init) + *psign_init = pmeth->sign_init; + if (psign) + *psign = pmeth->sign; +} + +void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, + int (**pverify_init) (EVP_PKEY_CTX *ctx), + int (**pverify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + if (pverify_init) + *pverify_init = pmeth->verify_init; + if (pverify) + *pverify = pmeth->verify; +} + +void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, + int (**pverify_recover_init) (EVP_PKEY_CTX + *ctx), + int (**pverify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)) +{ + if (pverify_recover_init) + *pverify_recover_init = pmeth->verify_recover_init; + if (pverify_recover) + *pverify_recover = pmeth->verify_recover; +} + +void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, + int (**psignctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**psignctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)) +{ + if (psignctx_init) + *psignctx_init = pmeth->signctx_init; + if (psignctx) + *psignctx = pmeth->signctx; +} + +void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, + int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (**pverifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)) +{ + if (pverifyctx_init) + *pverifyctx_init = pmeth->verifyctx_init; + if (pverifyctx) + *pverifyctx = pmeth->verifyctx; +} + +void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, + int (**pencrypt_init) (EVP_PKEY_CTX *ctx), + int (**pencryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + if (pencrypt_init) + *pencrypt_init = pmeth->encrypt_init; + if (pencryptfn) + *pencryptfn = pmeth->encrypt; +} + +void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, + int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), + int (**pdecrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + if (pdecrypt_init) + *pdecrypt_init = pmeth->decrypt_init; + if (pdecrypt) + *pdecrypt = pmeth->decrypt; +} + +void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, + int (**pderive_init) (EVP_PKEY_CTX *ctx), + int (**pderive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)) +{ + if (pderive_init) + *pderive_init = pmeth->derive_init; + if (pderive) + *pderive = pmeth->derive; +} + +void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, + int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (**pctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)) +{ + if (pctrl) + *pctrl = pmeth->ctrl; + if (pctrl_str) + *pctrl_str = pmeth->ctrl_str; +} diff --git a/Sources/COpenSSL/pqueue.c b/Sources/COpenSSL/pqueue.c new file mode 100644 index 00000000..8eded3be --- /dev/null +++ b/Sources/COpenSSL/pqueue.c @@ -0,0 +1,235 @@ +/* crypto/pqueue/pqueue.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "bn.h" +#include "pqueue.h" + +typedef struct _pqueue { + pitem *items; + int count; +} pqueue_s; + +pitem *pitem_new(unsigned char *prio64be, void *data) +{ + pitem *item = (pitem *)OPENSSL_malloc(sizeof(pitem)); + if (item == NULL) + return NULL; + + memcpy(item->priority, prio64be, sizeof(item->priority)); + + item->data = data; + item->next = NULL; + + return item; +} + +void pitem_free(pitem *item) +{ + if (item == NULL) + return; + + OPENSSL_free(item); +} + +pqueue_s *pqueue_new() +{ + pqueue_s *pq = (pqueue_s *)OPENSSL_malloc(sizeof(pqueue_s)); + if (pq == NULL) + return NULL; + + memset(pq, 0x00, sizeof(pqueue_s)); + return pq; +} + +void pqueue_free(pqueue_s *pq) +{ + if (pq == NULL) + return; + + OPENSSL_free(pq); +} + +pitem *pqueue_insert(pqueue_s *pq, pitem *item) +{ + pitem *curr, *next; + + if (pq->items == NULL) { + pq->items = item; + return item; + } + + for (curr = NULL, next = pq->items; + next != NULL; curr = next, next = next->next) { + /* + * we can compare 64-bit value in big-endian encoding with memcmp:-) + */ + int cmp = memcmp(next->priority, item->priority, 8); + if (cmp > 0) { /* next > item */ + item->next = next; + + if (curr == NULL) + pq->items = item; + else + curr->next = item; + + return item; + } + + else if (cmp == 0) /* duplicates not allowed */ + return NULL; + } + + item->next = NULL; + curr->next = item; + + return item; +} + +pitem *pqueue_peek(pqueue_s *pq) +{ + return pq->items; +} + +pitem *pqueue_pop(pqueue_s *pq) +{ + pitem *item = pq->items; + + if (pq->items != NULL) + pq->items = pq->items->next; + + return item; +} + +pitem *pqueue_find(pqueue_s *pq, unsigned char *prio64be) +{ + pitem *next; + pitem *found = NULL; + + if (pq->items == NULL) + return NULL; + + for (next = pq->items; next->next != NULL; next = next->next) { + if (memcmp(next->priority, prio64be, 8) == 0) { + found = next; + break; + } + } + + /* check the one last node */ + if (memcmp(next->priority, prio64be, 8) == 0) + found = next; + + if (!found) + return NULL; + +#if 0 /* find works in peek mode */ + if (prev == NULL) + pq->items = next->next; + else + prev->next = next->next; +#endif + + return found; +} + +void pqueue_print(pqueue_s *pq) +{ + pitem *item = pq->items; + + while (item != NULL) { + printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n", + item->priority[0], item->priority[1], + item->priority[2], item->priority[3], + item->priority[4], item->priority[5], + item->priority[6], item->priority[7]); + item = item->next; + } +} + +pitem *pqueue_iterator(pqueue_s *pq) +{ + return pqueue_peek(pq); +} + +pitem *pqueue_next(pitem **item) +{ + pitem *ret; + + if (item == NULL || *item == NULL) + return NULL; + + /* *item != NULL */ + ret = *item; + *item = (*item)->next; + + return ret; +} + +int pqueue_size(pqueue_s *pq) +{ + pitem *item = pq->items; + int count = 0; + + while (item != NULL) { + count++; + item = item->next; + } + return count; +} diff --git a/Sources/COpenSSL/pqueue.h b/Sources/COpenSSL/pqueue.h new file mode 100644 index 00000000..d40d9c7d --- /dev/null +++ b/Sources/COpenSSL/pqueue.h @@ -0,0 +1,99 @@ +/* crypto/pqueue/pqueue.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PQUEUE_H +# define HEADER_PQUEUE_H + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct _pqueue *pqueue; + +typedef struct _pitem { + unsigned char priority[8]; /* 64-bit value in big-endian encoding */ + void *data; + struct _pitem *next; +} pitem; + +typedef struct _pitem *piterator; + +pitem *pitem_new(unsigned char *prio64be, void *data); +void pitem_free(pitem *item); + +pqueue pqueue_new(void); +void pqueue_free(pqueue pq); + +pitem *pqueue_insert(pqueue pq, pitem *item); +pitem *pqueue_peek(pqueue pq); +pitem *pqueue_pop(pqueue pq); +pitem *pqueue_find(pqueue pq, unsigned char *prio64be); +pitem *pqueue_iterator(pqueue pq); +pitem *pqueue_next(piterator *iter); + +void pqueue_print(pqueue pq); +int pqueue_size(pqueue pq); + +#ifdef __cplusplus +} +#endif +#endif /* ! HEADER_PQUEUE_H */ diff --git a/Sources/COpenSSL/pvkfmt.c b/Sources/COpenSSL/pvkfmt.c new file mode 100644 index 00000000..ad89f664 --- /dev/null +++ b/Sources/COpenSSL/pvkfmt.c @@ -0,0 +1,895 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Support for PVK format keys and related structures (such a PUBLICKEYBLOB + * and PRIVATEKEYBLOB). + */ + +#include "cryptlib.h" +#include "pem.h" +#include "rand.h" +#include "bn.h" +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) +# include "dsa.h" +# include "rsa.h" + +/* + * Utility function: read a DWORD (4 byte unsigned integer) in little endian + * format + */ + +static unsigned int read_ledword(const unsigned char **in) +{ + const unsigned char *p = *in; + unsigned int ret; + ret = *p++; + ret |= (*p++ << 8); + ret |= (*p++ << 16); + ret |= (*p++ << 24); + *in = p; + return ret; +} + +/* + * Read a BIGNUM in little endian format. The docs say that this should take + * up bitlen/8 bytes. + */ + +static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) +{ + const unsigned char *p; + unsigned char *tmpbuf, *q; + unsigned int i; + p = *in + nbyte - 1; + tmpbuf = OPENSSL_malloc(nbyte); + if (!tmpbuf) + return 0; + q = tmpbuf; + for (i = 0; i < nbyte; i++) + *q++ = *p--; + *r = BN_bin2bn(tmpbuf, nbyte, NULL); + OPENSSL_free(tmpbuf); + if (*r) { + *in += nbyte; + return 1; + } else + return 0; +} + +/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */ + +# define MS_PUBLICKEYBLOB 0x6 +# define MS_PRIVATEKEYBLOB 0x7 +# define MS_RSA1MAGIC 0x31415352L +# define MS_RSA2MAGIC 0x32415352L +# define MS_DSS1MAGIC 0x31535344L +# define MS_DSS2MAGIC 0x32535344L + +# define MS_KEYALG_RSA_KEYX 0xa400 +# define MS_KEYALG_DSS_SIGN 0x2200 + +# define MS_KEYTYPE_KEYX 0x1 +# define MS_KEYTYPE_SIGN 0x2 + +/* Maximum length of a blob after header */ +# define BLOB_MAX_LENGTH 102400 + +/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ +# define MS_PVKMAGIC 0xb0b5f11eL +/* Salt length for PVK files */ +# define PVK_SALTLEN 0x10 +/* Maximum length in PVK header */ +# define PVK_MAX_KEYLEN 102400 +/* Maximum salt length */ +# define PVK_MAX_SALTLEN 10240 + +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub); +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub); + +static int do_blob_header(const unsigned char **in, unsigned int length, + unsigned int *pmagic, unsigned int *pbitlen, + int *pisdss, int *pispub) +{ + const unsigned char *p = *in; + if (length < 16) + return 0; + /* bType */ + if (*p == MS_PUBLICKEYBLOB) { + if (*pispub == 0) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + return 0; + } + *pispub = 1; + } else if (*p == MS_PRIVATEKEYBLOB) { + if (*pispub == 1) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + return 0; + } + *pispub = 0; + } else + return 0; + p++; + /* Version */ + if (*p++ != 0x2) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER); + return 0; + } + /* Ignore reserved, aiKeyAlg */ + p += 6; + *pmagic = read_ledword(&p); + *pbitlen = read_ledword(&p); + *pisdss = 0; + switch (*pmagic) { + + case MS_DSS1MAGIC: + *pisdss = 1; + case MS_RSA1MAGIC: + if (*pispub == 0) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + return 0; + } + break; + + case MS_DSS2MAGIC: + *pisdss = 1; + case MS_RSA2MAGIC: + if (*pispub == 1) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + return 0; + } + break; + + default: + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER); + return -1; + } + *in = p; + return 1; +} + +static unsigned int blob_length(unsigned bitlen, int isdss, int ispub) +{ + unsigned int nbyte, hnbyte; + nbyte = (bitlen + 7) >> 3; + hnbyte = (bitlen + 15) >> 4; + if (isdss) { + + /* + * Expected length: 20 for q + 3 components bitlen each + 24 for seed + * structure. + */ + if (ispub) + return 44 + 3 * nbyte; + /* + * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed + * structure. + */ + else + return 64 + 2 * nbyte; + } else { + /* Expected length: 4 for 'e' + 'n' */ + if (ispub) + return 4 + nbyte; + else + /* + * Expected length: 4 for 'e' and 7 other components. 2 + * components are bitlen size, 5 are bitlen/2 + */ + return 4 + 2 * nbyte + 5 * hnbyte; + } + +} + +static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length, + int ispub) +{ + const unsigned char *p = *in; + unsigned int bitlen, magic; + int isdss; + if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) { + PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); + return NULL; + } + length -= 16; + if (length < blob_length(bitlen, isdss, ispub)) { + PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT); + return NULL; + } + if (isdss) + return b2i_dss(&p, length, bitlen, ispub); + else + return b2i_rsa(&p, length, bitlen, ispub); +} + +static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) +{ + const unsigned char *p; + unsigned char hdr_buf[16], *buf = NULL; + unsigned int bitlen, magic, length; + int isdss; + EVP_PKEY *ret = NULL; + if (BIO_read(in, hdr_buf, 16) != 16) { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + return NULL; + } + p = hdr_buf; + if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0) + return NULL; + + length = blob_length(bitlen, isdss, ispub); + if (length > BLOB_MAX_LENGTH) { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG); + return NULL; + } + buf = OPENSSL_malloc(length); + if (!buf) { + PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf; + if (BIO_read(in, buf, length) != (int)length) { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + goto err; + } + + if (isdss) + ret = b2i_dss(&p, length, bitlen, ispub); + else + ret = b2i_rsa(&p, length, bitlen, ispub); + + err: + if (buf) + OPENSSL_free(buf); + return ret; +} + +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub) +{ + const unsigned char *p = *in; + EVP_PKEY *ret = NULL; + DSA *dsa = NULL; + BN_CTX *ctx = NULL; + unsigned int nbyte; + nbyte = (bitlen + 7) >> 3; + + dsa = DSA_new(); + ret = EVP_PKEY_new(); + if (!dsa || !ret) + goto memerr; + if (!read_lebn(&p, nbyte, &dsa->p)) + goto memerr; + if (!read_lebn(&p, 20, &dsa->q)) + goto memerr; + if (!read_lebn(&p, nbyte, &dsa->g)) + goto memerr; + if (ispub) { + if (!read_lebn(&p, nbyte, &dsa->pub_key)) + goto memerr; + } else { + if (!read_lebn(&p, 20, &dsa->priv_key)) + goto memerr; + /* Calculate public key */ + if (!(dsa->pub_key = BN_new())) + goto memerr; + if (!(ctx = BN_CTX_new())) + goto memerr; + + if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) + + goto memerr; + BN_CTX_free(ctx); + } + + EVP_PKEY_set1_DSA(ret, dsa); + DSA_free(dsa); + *in = p; + return ret; + + memerr: + PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE); + if (dsa) + DSA_free(dsa); + if (ret) + EVP_PKEY_free(ret); + if (ctx) + BN_CTX_free(ctx); + return NULL; +} + +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub) +{ + const unsigned char *p = *in; + EVP_PKEY *ret = NULL; + RSA *rsa = NULL; + unsigned int nbyte, hnbyte; + nbyte = (bitlen + 7) >> 3; + hnbyte = (bitlen + 15) >> 4; + rsa = RSA_new(); + ret = EVP_PKEY_new(); + if (!rsa || !ret) + goto memerr; + rsa->e = BN_new(); + if (!rsa->e) + goto memerr; + if (!BN_set_word(rsa->e, read_ledword(&p))) + goto memerr; + if (!read_lebn(&p, nbyte, &rsa->n)) + goto memerr; + if (!ispub) { + if (!read_lebn(&p, hnbyte, &rsa->p)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->q)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->dmp1)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->dmq1)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->iqmp)) + goto memerr; + if (!read_lebn(&p, nbyte, &rsa->d)) + goto memerr; + } + + EVP_PKEY_set1_RSA(ret, rsa); + RSA_free(rsa); + *in = p; + return ret; + memerr: + PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE); + if (rsa) + RSA_free(rsa); + if (ret) + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length) +{ + return do_b2i(in, length, 0); +} + +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length) +{ + return do_b2i(in, length, 1); +} + +EVP_PKEY *b2i_PrivateKey_bio(BIO *in) +{ + return do_b2i_bio(in, 0); +} + +EVP_PKEY *b2i_PublicKey_bio(BIO *in) +{ + return do_b2i_bio(in, 1); +} + +static void write_ledword(unsigned char **out, unsigned int dw) +{ + unsigned char *p = *out; + *p++ = dw & 0xff; + *p++ = (dw >> 8) & 0xff; + *p++ = (dw >> 16) & 0xff; + *p++ = (dw >> 24) & 0xff; + *out = p; +} + +static void write_lebn(unsigned char **out, const BIGNUM *bn, int len) +{ + int nb, i; + unsigned char *p = *out, *q, c; + nb = BN_num_bytes(bn); + BN_bn2bin(bn, p); + q = p + nb - 1; + /* In place byte order reversal */ + for (i = 0; i < nb / 2; i++) { + c = *p; + *p++ = *q; + *q-- = c; + } + *out += nb; + /* Pad with zeroes if we have to */ + if (len > 0) { + len -= nb; + if (len > 0) { + memset(*out, 0, len); + *out += len; + } + } +} + +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic); +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic); + +static void write_rsa(unsigned char **out, RSA *rsa, int ispub); +static void write_dsa(unsigned char **out, DSA *dsa, int ispub); + +static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) +{ + unsigned char *p; + unsigned int bitlen, magic = 0, keyalg; + int outlen, noinc = 0; + if (pk->type == EVP_PKEY_DSA) { + bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic); + keyalg = MS_KEYALG_DSS_SIGN; + } else if (pk->type == EVP_PKEY_RSA) { + bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic); + keyalg = MS_KEYALG_RSA_KEYX; + } else + return -1; + if (bitlen == 0) + return -1; + outlen = 16 + blob_length(bitlen, + keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); + if (out == NULL) + return outlen; + if (*out) + p = *out; + else { + p = OPENSSL_malloc(outlen); + if (!p) + return -1; + *out = p; + noinc = 1; + } + if (ispub) + *p++ = MS_PUBLICKEYBLOB; + else + *p++ = MS_PRIVATEKEYBLOB; + *p++ = 0x2; + *p++ = 0; + *p++ = 0; + write_ledword(&p, keyalg); + write_ledword(&p, magic); + write_ledword(&p, bitlen); + if (keyalg == MS_KEYALG_DSS_SIGN) + write_dsa(&p, pk->pkey.dsa, ispub); + else + write_rsa(&p, pk->pkey.rsa, ispub); + if (!noinc) + *out += outlen; + return outlen; +} + +static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) +{ + unsigned char *tmp = NULL; + int outlen, wrlen; + outlen = do_i2b(&tmp, pk, ispub); + if (outlen < 0) + return -1; + wrlen = BIO_write(out, tmp, outlen); + OPENSSL_free(tmp); + if (wrlen == outlen) + return outlen; + return -1; +} + +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) +{ + int bitlen; + bitlen = BN_num_bits(dsa->p); + if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) + || (BN_num_bits(dsa->g) > bitlen)) + goto badkey; + if (ispub) { + if (BN_num_bits(dsa->pub_key) > bitlen) + goto badkey; + *pmagic = MS_DSS1MAGIC; + } else { + if (BN_num_bits(dsa->priv_key) > 160) + goto badkey; + *pmagic = MS_DSS2MAGIC; + } + + return bitlen; + badkey: + PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; +} + +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) +{ + int nbyte, hnbyte, bitlen; + if (BN_num_bits(rsa->e) > 32) + goto badkey; + bitlen = BN_num_bits(rsa->n); + nbyte = BN_num_bytes(rsa->n); + hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; + if (ispub) { + *pmagic = MS_RSA1MAGIC; + return bitlen; + } else { + *pmagic = MS_RSA2MAGIC; + /* + * For private key each component must fit within nbyte or hnbyte. + */ + if (BN_num_bytes(rsa->d) > nbyte) + goto badkey; + if ((BN_num_bytes(rsa->iqmp) > hnbyte) + || (BN_num_bytes(rsa->p) > hnbyte) + || (BN_num_bytes(rsa->q) > hnbyte) + || (BN_num_bytes(rsa->dmp1) > hnbyte) + || (BN_num_bytes(rsa->dmq1) > hnbyte)) + goto badkey; + } + return bitlen; + badkey: + PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; +} + +static void write_rsa(unsigned char **out, RSA *rsa, int ispub) +{ + int nbyte, hnbyte; + nbyte = BN_num_bytes(rsa->n); + hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; + write_lebn(out, rsa->e, 4); + write_lebn(out, rsa->n, -1); + if (ispub) + return; + write_lebn(out, rsa->p, hnbyte); + write_lebn(out, rsa->q, hnbyte); + write_lebn(out, rsa->dmp1, hnbyte); + write_lebn(out, rsa->dmq1, hnbyte); + write_lebn(out, rsa->iqmp, hnbyte); + write_lebn(out, rsa->d, nbyte); +} + +static void write_dsa(unsigned char **out, DSA *dsa, int ispub) +{ + int nbyte; + nbyte = BN_num_bytes(dsa->p); + write_lebn(out, dsa->p, nbyte); + write_lebn(out, dsa->q, 20); + write_lebn(out, dsa->g, nbyte); + if (ispub) + write_lebn(out, dsa->pub_key, nbyte); + else + write_lebn(out, dsa->priv_key, 20); + /* Set "invalid" for seed structure values */ + memset(*out, 0xff, 24); + *out += 24; + return; +} + +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk) +{ + return do_i2b_bio(out, pk, 0); +} + +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk) +{ + return do_i2b_bio(out, pk, 1); +} + +# ifndef OPENSSL_NO_RC4 + +static int do_PVK_header(const unsigned char **in, unsigned int length, + int skip_magic, + unsigned int *psaltlen, unsigned int *pkeylen) +{ + const unsigned char *p = *in; + unsigned int pvk_magic, is_encrypted; + if (skip_magic) { + if (length < 20) { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); + return 0; + } + } else { + if (length < 24) { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); + return 0; + } + pvk_magic = read_ledword(&p); + if (pvk_magic != MS_PVKMAGIC) { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER); + return 0; + } + } + /* Skip reserved */ + p += 4; + /* + * keytype = + */ read_ledword(&p); + is_encrypted = read_ledword(&p); + *psaltlen = read_ledword(&p); + *pkeylen = read_ledword(&p); + + if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN) + return 0; + + if (is_encrypted && !*psaltlen) { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER); + return 0; + } + + *in = p; + return 1; +} + +static int derive_pvk_key(unsigned char *key, + const unsigned char *salt, unsigned int saltlen, + const unsigned char *pass, int passlen) +{ + EVP_MD_CTX mctx; + int rv = 1; + EVP_MD_CTX_init(&mctx); + if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL) + || !EVP_DigestUpdate(&mctx, salt, saltlen) + || !EVP_DigestUpdate(&mctx, pass, passlen) + || !EVP_DigestFinal_ex(&mctx, key, NULL)) + rv = 0; + + EVP_MD_CTX_cleanup(&mctx); + return rv; +} + +static EVP_PKEY *do_PVK_body(const unsigned char **in, + unsigned int saltlen, unsigned int keylen, + pem_password_cb *cb, void *u) +{ + EVP_PKEY *ret = NULL; + const unsigned char *p = *in; + unsigned int magic; + unsigned char *enctmp = NULL, *q; + EVP_CIPHER_CTX cctx; + EVP_CIPHER_CTX_init(&cctx); + if (saltlen) { + char psbuf[PEM_BUFSIZE]; + unsigned char keybuf[20]; + int enctmplen, inlen; + if (cb) + inlen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (inlen < 0) { + PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ); + goto err; + } + enctmp = OPENSSL_malloc(keylen + 8); + if (!enctmp) { + PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!derive_pvk_key(keybuf, p, saltlen, + (unsigned char *)psbuf, inlen)) + goto err; + p += saltlen; + /* Copy BLOBHEADER across, decrypt rest */ + memcpy(enctmp, p, 8); + p += 8; + if (keylen < 8) { + PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT); + goto err; + } + inlen = keylen - 8; + q = enctmp + 8; + if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) + goto err; + if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen)) + goto err; + if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen)) + goto err; + magic = read_ledword((const unsigned char **)&q); + if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { + q = enctmp + 8; + memset(keybuf + 5, 0, 11); + if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) + goto err; + OPENSSL_cleanse(keybuf, 20); + if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen)) + goto err; + if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen)) + goto err; + magic = read_ledword((const unsigned char **)&q); + if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { + PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT); + goto err; + } + } else + OPENSSL_cleanse(keybuf, 20); + p = enctmp; + } + + ret = b2i_PrivateKey(&p, keylen); + err: + EVP_CIPHER_CTX_cleanup(&cctx); + if (enctmp && saltlen) + OPENSSL_free(enctmp); + return ret; +} + +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) +{ + unsigned char pvk_hdr[24], *buf = NULL; + const unsigned char *p; + int buflen; + EVP_PKEY *ret = NULL; + unsigned int saltlen, keylen; + if (BIO_read(in, pvk_hdr, 24) != 24) { + PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); + return NULL; + } + p = pvk_hdr; + + if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen)) + return 0; + buflen = (int)keylen + saltlen; + buf = OPENSSL_malloc(buflen); + if (!buf) { + PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE); + return 0; + } + p = buf; + if (BIO_read(in, buf, buflen) != buflen) { + PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); + goto err; + } + ret = do_PVK_body(&p, saltlen, keylen, cb, u); + + err: + if (buf) { + OPENSSL_cleanse(buf, buflen); + OPENSSL_free(buf); + } + return ret; +} + +static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u) +{ + int outlen = 24, pklen; + unsigned char *p, *salt = NULL; + EVP_CIPHER_CTX cctx; + EVP_CIPHER_CTX_init(&cctx); + if (enclevel) + outlen += PVK_SALTLEN; + pklen = do_i2b(NULL, pk, 0); + if (pklen < 0) + return -1; + outlen += pklen; + if (!out) + return outlen; + if (*out) + p = *out; + else { + p = OPENSSL_malloc(outlen); + if (!p) { + PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE); + return -1; + } + *out = p; + } + + write_ledword(&p, MS_PVKMAGIC); + write_ledword(&p, 0); + if (pk->type == EVP_PKEY_DSA) + write_ledword(&p, MS_KEYTYPE_SIGN); + else + write_ledword(&p, MS_KEYTYPE_KEYX); + write_ledword(&p, enclevel ? 1 : 0); + write_ledword(&p, enclevel ? PVK_SALTLEN : 0); + write_ledword(&p, pklen); + if (enclevel) { + if (RAND_bytes(p, PVK_SALTLEN) <= 0) + goto error; + salt = p; + p += PVK_SALTLEN; + } + do_i2b(&p, pk, 0); + if (enclevel == 0) + return outlen; + else { + char psbuf[PEM_BUFSIZE]; + unsigned char keybuf[20]; + int enctmplen, inlen; + if (cb) + inlen = cb(psbuf, PEM_BUFSIZE, 1, u); + else + inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u); + if (inlen <= 0) { + PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ); + goto error; + } + if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, + (unsigned char *)psbuf, inlen)) + goto error; + if (enclevel == 1) + memset(keybuf + 5, 0, 11); + p = salt + PVK_SALTLEN + 8; + if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) + goto error; + OPENSSL_cleanse(keybuf, 20); + if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8)) + goto error; + if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen)) + goto error; + } + EVP_CIPHER_CTX_cleanup(&cctx); + return outlen; + + error: + EVP_CIPHER_CTX_cleanup(&cctx); + return -1; +} + +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u) +{ + unsigned char *tmp = NULL; + int outlen, wrlen; + outlen = i2b_PVK(&tmp, pk, enclevel, cb, u); + if (outlen < 0) + return -1; + wrlen = BIO_write(out, tmp, outlen); + OPENSSL_free(tmp); + if (wrlen == outlen) { + PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE); + return outlen; + } + return -1; +} + +# endif + +#endif diff --git a/Sources/COpenSSL/qud_cksm.c b/Sources/COpenSSL/qud_cksm.c new file mode 100644 index 00000000..2a168a57 --- /dev/null +++ b/Sources/COpenSSL/qud_cksm.c @@ -0,0 +1,143 @@ +/* crypto/des/qud_cksm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer IEEE + * Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 This module in + * only based on the code in this paper and is almost definitely not the same + * as the MIT implementation. + */ +#include "des_locl.h" + +/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */ +#define Q_B0(a) (((DES_LONG)(a))) +#define Q_B1(a) (((DES_LONG)(a))<<8) +#define Q_B2(a) (((DES_LONG)(a))<<16) +#define Q_B3(a) (((DES_LONG)(a))<<24) + +/* used to scramble things a bit */ +/* Got the value MIT uses via brute force :-) 2/10/90 eay */ +#define NOISE ((DES_LONG)83653421L) + +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed) +{ + DES_LONG z0, z1, t0, t1; + int i; + long l; + const unsigned char *cp; +#ifdef _CRAY + struct lp_st { + int a:32; + int b:32; + } *lp; +#else + DES_LONG *lp; +#endif + + if (out_count < 1) + out_count = 1; +#ifdef _CRAY + lp = (struct lp_st *)&(output[0])[0]; +#else + lp = (DES_LONG *)&(output[0])[0]; +#endif + + z0 = Q_B0((*seed)[0]) | Q_B1((*seed)[1]) | Q_B2((*seed)[2]) | + Q_B3((*seed)[3]); + z1 = Q_B0((*seed)[4]) | Q_B1((*seed)[5]) | Q_B2((*seed)[6]) | + Q_B3((*seed)[7]); + + for (i = 0; ((i < 4) && (i < out_count)); i++) { + cp = input; + l = length; + while (l > 0) { + if (l > 1) { + t0 = (DES_LONG)(*(cp++)); + t0 |= (DES_LONG)Q_B1(*(cp++)); + l--; + } else + t0 = (DES_LONG)(*(cp++)); + l--; + /* add */ + t0 += z0; + t0 &= 0xffffffffL; + t1 = z1; + /* square, well sort of square */ + z0 = ((((t0 * t0) & 0xffffffffL) + ((t1 * t1) & 0xffffffffL)) + & 0xffffffffL) % 0x7fffffffL; + z1 = ((t0 * ((t1 + NOISE) & 0xffffffffL)) & 0xffffffffL) % + 0x7fffffffL; + } + if (lp != NULL) { + /* + * The MIT library assumes that the checksum is composed of + * 2*out_count 32 bit ints + */ +#ifdef _CRAY + (*lp).a = z0; + (*lp).b = z1; + lp++; +#else + *lp++ = z0; + *lp++ = z1; +#endif + } + } + return (z0); +} diff --git a/Sources/COpenSSL/rand.h b/Sources/COpenSSL/rand.h new file mode 100644 index 00000000..143eae91 --- /dev/null +++ b/Sources/COpenSSL/rand.h @@ -0,0 +1,150 @@ +/* crypto/rand/rand.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RAND_H +# define HEADER_RAND_H + +# include +# include "ossl_typ.h" +# include "e_os2.h" + +# if defined(OPENSSL_SYS_WINDOWS) +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if defined(OPENSSL_FIPS) +# define FIPS_RAND_SIZE_T size_t +# endif + +/* Already defined in ossl_typ.h */ +/* typedef struct rand_meth_st RAND_METHOD; */ + +struct rand_meth_st { + void (*seed) (const void *buf, int num); + int (*bytes) (unsigned char *buf, int num); + void (*cleanup) (void); + void (*add) (const void *buf, int num, double entropy); + int (*pseudorand) (unsigned char *buf, int num); + int (*status) (void); +}; + +# ifdef BN_DEBUG +extern int rand_predictable; +# endif + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +# ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +# endif +RAND_METHOD *RAND_SSLeay(void); +void RAND_cleanup(void); +int RAND_bytes(unsigned char *buf, int num); +int RAND_pseudo_bytes(unsigned char *buf, int num); +void RAND_seed(const void *buf, int num); +void RAND_add(const void *buf, int num, double entropy); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); +int RAND_status(void); +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); +int RAND_egd(const char *path); +int RAND_egd_bytes(const char *path, int bytes); +int RAND_poll(void); + +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) + +void RAND_screen(void); +int RAND_event(UINT, WPARAM, LPARAM); + +# endif + +# ifdef OPENSSL_FIPS +void RAND_set_fips_drbg_type(int type, int flags); +int RAND_init_fips(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RAND_strings(void); + +/* Error codes for the RAND functions. */ + +/* Function codes. */ +# define RAND_F_RAND_GET_RAND_METHOD 101 +# define RAND_F_RAND_INIT_FIPS 102 +# define RAND_F_SSLEAY_RAND_BYTES 100 + +/* Reason codes. */ +# define RAND_R_DUAL_EC_DRBG_DISABLED 104 +# define RAND_R_ERROR_INITIALISING_DRBG 102 +# define RAND_R_ERROR_INSTANTIATING_DRBG 103 +# define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 +# define RAND_R_PRNG_NOT_SEEDED 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/rand_.c b/Sources/COpenSSL/rand_.c new file mode 100644 index 00000000..9b688efe --- /dev/null +++ b/Sources/COpenSSL/rand_.c @@ -0,0 +1,2500 @@ +/* crypto/rand/rand_egd.c */ +/* Written by Ulf Moeller and Lutz Jaenicke for the OpenSSL project. */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "e_os2.h" +#include "rand.h" +#include "buffer.h" + +/*- + * Query the EGD . + * + * This module supplies three routines: + * + * RAND_query_egd_bytes(path, buf, bytes) + * will actually query "bytes" bytes of entropy form the egd-socket located + * at path and will write them to buf (if supplied) or will directly feed + * it to RAND_seed() if buf==NULL. + * The number of bytes is not limited by the maximum chunk size of EGD, + * which is 255 bytes. If more than 255 bytes are wanted, several chunks + * of entropy bytes are requested. The connection is left open until the + * query is competed. + * RAND_query_egd_bytes() returns with + * -1 if an error occured during connection or communication. + * num the number of bytes read from the EGD socket. This number is either + * the number of bytes requested or smaller, if the EGD pool is + * drained and the daemon signals that the pool is empty. + * This routine does not touch any RAND_status(). This is necessary, since + * PRNG functions may call it during initialization. + * + * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them + * used to seed the PRNG. + * RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL. + * Unlike RAND_query_egd_bytes(), RAND_status() is used to test the + * seed status so that the return value can reflect the seed state: + * -1 if an error occured during connection or communication _or_ + * if the PRNG has still not received the required seeding. + * num the number of bytes read from the EGD socket. This number is either + * the number of bytes requested or smaller, if the EGD pool is + * drained and the daemon signals that the pool is empty. + * + * RAND_egd(path) will query 255 bytes and use the bytes retreived to seed + * the PRNG. + * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. + */ + +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS) +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) +{ + return (-1); +} + +int RAND_egd(const char *path) +{ + return (-1); +} + +int RAND_egd_bytes(const char *path, int bytes) +{ + return (-1); +} +#else +# include "opensslconf.h" +# include OPENSSL_UNISTD +# include +# include +# include +# ifndef NO_SYS_UN_H +# ifdef OPENSSL_SYS_VXWORKS +# include +# else +# include +# endif +# else +struct sockaddr_un { + short sun_family; /* AF_UNIX */ + char sun_path[108]; /* path name (gag) */ +}; +# endif /* NO_SYS_UN_H */ +# include +# include + +# ifndef offsetof +# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +# endif + +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) +{ + int ret = 0; + struct sockaddr_un addr; + int len, num, numbytes; + int fd = -1; + int success; + unsigned char egdbuf[2], tempbuf[255], *retrievebuf; + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + if (strlen(path) >= sizeof(addr.sun_path)) + return (-1); + BUF_strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); + len = offsetof(struct sockaddr_un, sun_path) + strlen(path); + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) + return (-1); + success = 0; + while (!success) { + if (connect(fd, (struct sockaddr *)&addr, len) == 0) + success = 1; + else { + switch (errno) { +# ifdef EINTR + case EINTR: +# endif +# ifdef EAGAIN + case EAGAIN: +# endif +# ifdef EINPROGRESS + case EINPROGRESS: +# endif +# ifdef EALREADY + case EALREADY: +# endif + /* No error, try again */ + break; +# ifdef EISCONN + case EISCONN: + success = 1; + break; +# endif + default: + goto err; /* failure */ + } + } + } + + while (bytes > 0) { + egdbuf[0] = 1; + egdbuf[1] = bytes < 255 ? bytes : 255; + numbytes = 0; + while (numbytes != 2) { + num = write(fd, egdbuf + numbytes, 2 - numbytes); + if (num >= 0) + numbytes += num; + else { + switch (errno) { +# ifdef EINTR + case EINTR: +# endif +# ifdef EAGAIN + case EAGAIN: +# endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + numbytes = 0; + while (numbytes != 1) { + num = read(fd, egdbuf, 1); + if (num == 0) + goto err; /* descriptor closed */ + else if (num > 0) + numbytes += num; + else { + switch (errno) { +# ifdef EINTR + case EINTR: +# endif +# ifdef EAGAIN + case EAGAIN: +# endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + if (egdbuf[0] == 0) + goto err; + if (buf) + retrievebuf = buf + ret; + else + retrievebuf = tempbuf; + numbytes = 0; + while (numbytes != egdbuf[0]) { + num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes); + if (num == 0) + goto err; /* descriptor closed */ + else if (num > 0) + numbytes += num; + else { + switch (errno) { +# ifdef EINTR + case EINTR: +# endif +# ifdef EAGAIN + case EAGAIN: +# endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + ret += egdbuf[0]; + bytes -= egdbuf[0]; + if (!buf) + RAND_seed(tempbuf, egdbuf[0]); + } + err: + if (fd != -1) + close(fd); + return (ret); +} + +int RAND_egd_bytes(const char *path, int bytes) +{ + int num, ret = 0; + + num = RAND_query_egd_bytes(path, NULL, bytes); + if (num < 1) + goto err; + if (RAND_status() == 1) + ret = num; + err: + return (ret); +} + +int RAND_egd(const char *path) +{ + return (RAND_egd_bytes(path, 255)); +} + +#endif +/* crypto/rand/rand_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "rand.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason) + +static ERR_STRING_DATA RAND_str_functs[] = { + {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, + {ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"}, + {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, + {0, NULL} +}; + +static ERR_STRING_DATA RAND_str_reasons[] = { + {ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED), "dual ec drbg disabled"}, + {ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, + {ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, + {ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET), + "no fips random method set"}, + {ERR_REASON(RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"}, + {0, NULL} +}; + +#endif + +void ERR_load_RAND_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) { + ERR_load_strings(0, RAND_str_functs); + ERR_load_strings(0, RAND_str_reasons); + } +#endif +} +/* crypto/des/rand_key.c */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "des.h" +// #include "rand.h" + +int DES_random_key(DES_cblock *ret) +{ + do { + if (RAND_bytes((unsigned char *)ret, sizeof(DES_cblock)) != 1) + return (0); + } while (DES_is_weak_key(ret)); + DES_set_odd_parity(ret); + return (1); +} +/* crypto/rand/rand_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +// #include "rand.h" + +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +#ifdef OPENSSL_FIPS +# include +# include +# include "rand_lcl.h" +#endif + +#ifndef OPENSSL_NO_ENGINE +/* non-NULL if default_RAND_meth is ENGINE-provided */ +static ENGINE *funct_ref = NULL; +#endif +static const RAND_METHOD *default_RAND_meth = NULL; + +int RAND_set_rand_method(const RAND_METHOD *meth) +{ +#ifndef OPENSSL_NO_ENGINE + if (funct_ref) { + ENGINE_finish(funct_ref); + funct_ref = NULL; + } +#endif + default_RAND_meth = meth; + return 1; +} + +const RAND_METHOD *RAND_get_rand_method(void) +{ + if (!default_RAND_meth) { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e = ENGINE_get_default_RAND(); + if (e) { + default_RAND_meth = ENGINE_get_RAND(e); + if (!default_RAND_meth) { + ENGINE_finish(e); + e = NULL; + } + } + if (e) + funct_ref = e; + else +#endif + default_RAND_meth = RAND_SSLeay(); + } + return default_RAND_meth; +} + +#ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine) +{ + const RAND_METHOD *tmp_meth = NULL; + if (engine) { + if (!ENGINE_init(engine)) + return 0; + tmp_meth = ENGINE_get_RAND(engine); + if (!tmp_meth) { + ENGINE_finish(engine); + return 0; + } + } + /* This function releases any prior ENGINE so call it first */ + RAND_set_rand_method(tmp_meth); + funct_ref = engine; + return 1; +} +#endif + +void RAND_cleanup(void) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->cleanup) + meth->cleanup(); + RAND_set_rand_method(NULL); +} + +void RAND_seed(const void *buf, int num) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->seed) + meth->seed(buf, num); +} + +void RAND_add(const void *buf, int num, double entropy) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->add) + meth->add(buf, num, entropy); +} + +int RAND_bytes(unsigned char *buf, int num) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->bytes) + return meth->bytes(buf, num); + return (-1); +} + +int RAND_pseudo_bytes(unsigned char *buf, int num) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->pseudorand) + return meth->pseudorand(buf, num); + return (-1); +} + +int RAND_status(void) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->status) + return meth->status(); + return 0; +} + +#ifdef OPENSSL_FIPS + +/* + * FIPS DRBG initialisation code. This sets up the DRBG for use by the rest + * of OpenSSL. + */ + +/* + * Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather + * entropy internally through RAND_poll()). + */ + +static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) +{ + /* Round up request to multiple of block size */ + min_len = ((min_len + 19) / 20) * 20; + *pout = OPENSSL_malloc(min_len); + if (!*pout) + return 0; + + /* Enforces a reseed of the SSLEAY PRNG before generating random bytes */ + if (ssleay_rand_bytes_from_system(*pout, min_len) <= 0) { + OPENSSL_free(*pout); + *pout = NULL; + return 0; + } + return min_len; +} + +static size_t drbg_get_nonce(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) +{ + /* Round up request to multiple of block size */ + min_len = ((min_len + 19) / 20) * 20; + *pout = OPENSSL_malloc(min_len); + if (!*pout) + return 0; + if (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 0) { + OPENSSL_free(*pout); + *pout = NULL; + return 0; + } + return min_len; +} + +static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen) +{ + if (out) { + OPENSSL_cleanse(out, olen); + OPENSSL_free(out); + } +} + +/* + * Set "additional input" when generating random data. This uses the current + * PID, a time value and a counter. + */ + +static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout) +{ + /* Use of static variables is OK as this happens under a lock */ + static unsigned char buf[16]; + static unsigned long counter; + FIPS_get_timevec(buf, &counter); + *pout = buf; + return sizeof(buf); +} + +/* + * RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is + * correctly seeded by RAND_poll(). + */ + +static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen, + double entropy) +{ + RAND_SSLeay()->add(in, inlen, entropy); + return 1; +} + +static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen) +{ + RAND_SSLeay()->seed(in, inlen); + return 1; +} + +# ifndef OPENSSL_DRBG_DEFAULT_TYPE +# define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr +# endif +# ifndef OPENSSL_DRBG_DEFAULT_FLAGS +# define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF +# endif + +static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE; +static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS; + +void RAND_set_fips_drbg_type(int type, int flags) +{ + fips_drbg_type = type; + fips_drbg_flags = flags; +} + +int RAND_init_fips(void) +{ + DRBG_CTX *dctx; + size_t plen; + unsigned char pers[32], *p; +# ifndef OPENSSL_ALLOW_DUAL_EC_DRBG + if (fips_drbg_type >> 16) { + RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED); + return 0; + } +# endif + + dctx = FIPS_get_default_drbg(); + if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0) { + RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG); + return 0; + } + + FIPS_drbg_set_callbacks(dctx, + drbg_get_entropy, drbg_free_entropy, 20, + drbg_get_nonce, drbg_free_entropy); + FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0, + drbg_rand_seed, drbg_rand_add); + /* Personalisation string: a string followed by date time vector */ + strcpy((char *)pers, "OpenSSL DRBG2.0"); + plen = drbg_get_adin(dctx, &p); + memcpy(pers + 16, p, plen); + + if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0) { + RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG); + return 0; + } + FIPS_rand_set_method(FIPS_drbg_method()); + return 1; +} + +#endif +/* crypto/rand/rand_nw.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "rand.h" +#include "rand_lcl.h" + +#if defined (OPENSSL_SYS_NETWARE) + +# if defined(NETWARE_LIBC) +# include +# else +# include +# endif + +extern int GetProcessSwitchCount(void); +# if !defined(NETWARE_LIBC) || (CURRENT_NDK_THRESHOLD < 509220000) +extern void *RunningProcess; /* declare here same as found in newer NDKs */ +extern unsigned long GetSuperHighResolutionTimer(void); +# endif + + /* + * the FAQ indicates we need to provide at least 20 bytes (160 bits) of + * seed + */ +int RAND_poll(void) +{ + unsigned long l; + unsigned long tsc; + int i; + + /* + * There are several options to gather miscellaneous data but for now we + * will loop checking the time stamp counter (rdtsc) and the + * SuperHighResolutionTimer. Each iteration will collect 8 bytes of data + * but it is treated as only 1 byte of entropy. The call to + * ThreadSwitchWithDelay() will introduce additional variability into the + * data returned by rdtsc. Applications can agument the seed material by + * adding additional stuff with RAND_add() and should probably do so. + */ + l = GetProcessSwitchCount(); + RAND_add(&l, sizeof(l), 1); + + /* need to cast the void* to unsigned long here */ + l = (unsigned long)RunningProcess; + RAND_add(&l, sizeof(l), 1); + + for (i = 2; i < ENTROPY_NEEDED; i++) { +# ifdef __MWERKS__ + asm { + rdtsc mov tsc, eax} +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) + asm volatile ("rdtsc":"=a" (tsc)::"edx"); +# endif + + RAND_add(&tsc, sizeof(tsc), 1); + + l = GetSuperHighResolutionTimer(); + RAND_add(&l, sizeof(l), 0); + +# if defined(NETWARE_LIBC) + NXThreadYield(); +# else /* NETWARE_CLIB */ + ThreadSwitchWithDelay(); +# endif + } + + return 1; +} + +#endif +/* crypto/rand/rand_os2.c */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "rand.h" +// #include "rand_lcl.h" + +#ifdef OPENSSL_SYS_OS2 + +# define INCL_DOSPROCESS +# define INCL_DOSPROFILE +# define INCL_DOSMISC +# define INCL_DOSMODULEMGR +# include + +# define CMD_KI_RDCNT (0x63) + +typedef struct _CPUUTIL { + ULONG ulTimeLow; /* Low 32 bits of time stamp */ + ULONG ulTimeHigh; /* High 32 bits of time stamp */ + ULONG ulIdleLow; /* Low 32 bits of idle time */ + ULONG ulIdleHigh; /* High 32 bits of idle time */ + ULONG ulBusyLow; /* Low 32 bits of busy time */ + ULONG ulBusyHigh; /* High 32 bits of busy time */ + ULONG ulIntrLow; /* Low 32 bits of interrupt time */ + ULONG ulIntrHigh; /* High 32 bits of interrupt time */ +} CPUUTIL; + +# ifndef __KLIBC__ +APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, + ULONG ulParm2, ULONG ulParm3) = NULL; +APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, + ULONG _res_, PVOID buf, ULONG bufsz) = + NULL; +# endif +HMODULE hDoscalls = 0; + +int RAND_poll(void) +{ + char failed_module[20]; + QWORD qwTime; + ULONG SysVars[QSV_FOREGROUND_PROCESS]; + + if (hDoscalls == 0) { + ULONG rc = + DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", + &hDoscalls); + +# ifndef __KLIBC__ + if (rc == 0) { + rc = DosQueryProcAddr(hDoscalls, 976, NULL, + (PFN *) & DosPerfSysCall); + + if (rc) + DosPerfSysCall = NULL; + + rc = DosQueryProcAddr(hDoscalls, 368, NULL, + (PFN *) & DosQuerySysState); + + if (rc) + DosQuerySysState = NULL; + } +# endif + } + + /* Sample the hi-res timer, runs at around 1.1 MHz */ + DosTmrQueryTime(&qwTime); + RAND_add(&qwTime, sizeof(qwTime), 2); + + /* + * Sample a bunch of system variables, includes various process & memory + * statistics + */ + DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars)); + RAND_add(SysVars, sizeof(SysVars), 4); + + /* + * If available, sample CPU registers that count at CPU MHz Only fairly + * new CPUs (PPro & K6 onwards) & OS/2 versions support this + */ + if (DosPerfSysCall) { + CPUUTIL util; + + if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG) & util, 0, 0) == 0) { + RAND_add(&util, sizeof(util), 10); + } else { +# ifndef __KLIBC__ + DosPerfSysCall = NULL; +# endif + } + } + + /* + * DosQuerySysState() gives us a huge quantity of process, thread, memory + * & handle stats + */ + if (DosQuerySysState) { + char *buffer = OPENSSL_malloc(256 * 1024); + + if (!buffer) + return 0; + + if (DosQuerySysState(0x1F, 0, 0, 0, buffer, 256 * 1024) == 0) { + /* + * First 4 bytes in buffer is a pointer to the thread count there + * should be at least 1 byte of entropy per thread + */ + RAND_add(buffer, 256 * 1024, **(ULONG **) buffer); + } + + OPENSSL_free(buffer); + return 1; + } + + return 0; +} + +#endif /* OPENSSL_SYS_OS2 */ +/* crypto/rand/rand_unix.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include + +#define USE_SOCKETS +#include "e_os.h" +// #include "cryptlib.h" +// #include "rand.h" +// #include "rand_lcl.h" + +#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) + +# include +# include +# include +# include +# include +# include +# include +# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually + * everywhere */ +# include +# endif +# include +# ifndef FD_SETSIZE +# define FD_SETSIZE (8*sizeof(fd_set)) +# endif + +# if defined(OPENSSL_SYS_VOS) + +/* + * The following algorithm repeatedly samples the real-time clock (RTC) to + * generate a sequence of unpredictable data. The algorithm relies upon the + * uneven execution speed of the code (due to factors such as cache misses, + * interrupts, bus activity, and scheduling) and upon the rather large + * relative difference between the speed of the clock and the rate at which + * it can be read. + * + * If this code is ported to an environment where execution speed is more + * constant or where the RTC ticks at a much slower rate, or the clock can be + * read with fewer instructions, it is likely that the results would be far + * more predictable. + * + * As a precaution, we generate 4 times the minimum required amount of seed + * data. + */ + +int RAND_poll(void) +{ + short int code; + gid_t curr_gid; + pid_t curr_pid; + uid_t curr_uid; + int i, k; + struct timespec ts; + unsigned char v; + +# ifdef OPENSSL_SYS_VOS_HPPA + long duration; + extern void s$sleep(long *_duration, short int *_code); +# else +# ifdef OPENSSL_SYS_VOS_IA32 + long long duration; + extern void s$sleep2(long long *_duration, short int *_code); +# else +# error "Unsupported Platform." +# endif /* OPENSSL_SYS_VOS_IA32 */ +# endif /* OPENSSL_SYS_VOS_HPPA */ + + /* + * Seed with the gid, pid, and uid, to ensure *some* variation between + * different processes. + */ + + curr_gid = getgid(); + RAND_add(&curr_gid, sizeof(curr_gid), 1); + curr_gid = 0; + + curr_pid = getpid(); + RAND_add(&curr_pid, sizeof(curr_pid), 1); + curr_pid = 0; + + curr_uid = getuid(); + RAND_add(&curr_uid, sizeof(curr_uid), 1); + curr_uid = 0; + + for (i = 0; i < (ENTROPY_NEEDED * 4); i++) { + /* + * burn some cpu; hope for interrupts, cache collisions, bus + * interference, etc. + */ + for (k = 0; k < 99; k++) + ts.tv_nsec = random(); + +# ifdef OPENSSL_SYS_VOS_HPPA + /* sleep for 1/1024 of a second (976 us). */ + duration = 1; + s$sleep(&duration, &code); +# else +# ifdef OPENSSL_SYS_VOS_IA32 + /* sleep for 1/65536 of a second (15 us). */ + duration = 1; + s$sleep2(&duration, &code); +# endif /* OPENSSL_SYS_VOS_IA32 */ +# endif /* OPENSSL_SYS_VOS_HPPA */ + + /* get wall clock time. */ + clock_gettime(CLOCK_REALTIME, &ts); + + /* take 8 bits */ + v = (unsigned char)(ts.tv_nsec % 256); + RAND_add(&v, sizeof(v), 1); + v = 0; + } + return 1; +} +# elif defined __OpenBSD__ +int RAND_poll(void) +{ + u_int32_t rnd = 0, i; + unsigned char buf[ENTROPY_NEEDED]; + + for (i = 0; i < sizeof(buf); i++) { + if (i % 4 == 0) + rnd = arc4random(); + buf[i] = rnd; + rnd >>= 8; + } + RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); + OPENSSL_cleanse(buf, sizeof(buf)); + + return 1; +} +# else /* !defined(__OpenBSD__) */ +int RAND_poll(void) +{ + unsigned long l; + pid_t curr_pid = getpid(); +# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) + unsigned char tmpbuf[ENTROPY_NEEDED]; + int n = 0; +# endif +# ifdef DEVRANDOM + static const char *randomfiles[] = { DEVRANDOM }; + struct stat randomstats[sizeof(randomfiles) / sizeof(randomfiles[0])]; + int fd; + unsigned int i; +# endif +# ifdef DEVRANDOM_EGD + static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; + const char **egdsocket = NULL; +# endif + +# ifdef DEVRANDOM + memset(randomstats, 0, sizeof(randomstats)); + /* + * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have + * this. Use /dev/urandom if you can as /dev/random may block if it runs + * out of random entries. + */ + + for (i = 0; (i < sizeof(randomfiles) / sizeof(randomfiles[0])) && + (n < ENTROPY_NEEDED); i++) { + if ((fd = open(randomfiles[i], O_RDONLY +# ifdef O_NONBLOCK + | O_NONBLOCK +# endif +# ifdef O_BINARY + | O_BINARY +# endif +# ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do + * not make it our controlling tty */ + | O_NOCTTY +# endif + )) >= 0) { + int usec = 10 * 1000; /* spend 10ms on each file */ + int r; + unsigned int j; + struct stat *st = &randomstats[i]; + + /* + * Avoid using same input... Used to be O_NOFOLLOW above, but + * it's not universally appropriate... + */ + if (fstat(fd, st) != 0) { + close(fd); + continue; + } + for (j = 0; j < i; j++) { + if (randomstats[j].st_ino == st->st_ino && + randomstats[j].st_dev == st->st_dev) + break; + } + if (j < i) { + close(fd); + continue; + } + + do { + int try_read = 0; + +# if defined(OPENSSL_SYS_BEOS_R5) + /* + * select() is broken in BeOS R5, so we simply try to read + * something and snooze if we couldn't + */ + try_read = 1; + +# elif defined(OPENSSL_SYS_LINUX) + /* use poll() */ + struct pollfd pset; + + pset.fd = fd; + pset.events = POLLIN; + pset.revents = 0; + + if (poll(&pset, 1, usec / 1000) < 0) + usec = 0; + else + try_read = (pset.revents & POLLIN) != 0; + +# else + /* use select() */ + fd_set fset; + struct timeval t; + + t.tv_sec = 0; + t.tv_usec = usec; + + if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) { + /* + * can't use select, so just try to read once anyway + */ + try_read = 1; + } else { + FD_ZERO(&fset); + FD_SET(fd, &fset); + + if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) { + usec = t.tv_usec; + if (FD_ISSET(fd, &fset)) + try_read = 1; + } else + usec = 0; + } +# endif + + if (try_read) { + r = read(fd, (unsigned char *)tmpbuf + n, + ENTROPY_NEEDED - n); + if (r > 0) + n += r; +# if defined(OPENSSL_SYS_BEOS_R5) + if (r == 0) + snooze(t.tv_usec); +# endif + } else + r = -1; + + /* + * Some Unixen will update t in select(), some won't. For + * those who won't, or if we didn't use select() in the first + * place, give up here, otherwise, we will do this once again + * for the remaining time. + */ + if (usec == 10 * 1000) + usec = 0; + } + while ((r > 0 || + (errno == EINTR || errno == EAGAIN)) && usec != 0 + && n < ENTROPY_NEEDED); + + close(fd); + } + } +# endif /* defined(DEVRANDOM) */ + +# ifdef DEVRANDOM_EGD + /* + * Use an EGD socket to read entropy from an EGD or PRNGD entropy + * collecting daemon. + */ + + for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; + egdsocket++) { + int r; + + r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n, + ENTROPY_NEEDED - n); + if (r > 0) + n += r; + } +# endif /* defined(DEVRANDOM_EGD) */ + +# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) + if (n > 0) { + RAND_add(tmpbuf, sizeof(tmpbuf), (double)n); + OPENSSL_cleanse(tmpbuf, n); + } +# endif + + /* put in some default random data, we need more than just this */ + l = curr_pid; + RAND_add(&l, sizeof(l), 0.0); + l = getuid(); + RAND_add(&l, sizeof(l), 0.0); + + l = time(NULL); + RAND_add(&l, sizeof(l), 0.0); + +# if defined(OPENSSL_SYS_BEOS) + { + system_info sysInfo; + get_system_info(&sysInfo); + RAND_add(&sysInfo, sizeof(sysInfo), 0); + } +# endif + +# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) + return 1; +# else + return 0; +# endif +} + +# endif /* defined(__OpenBSD__) */ +#endif /* !(defined(OPENSSL_SYS_WINDOWS) || + * defined(OPENSSL_SYS_WIN32) || + * defined(OPENSSL_SYS_VMS) || + * defined(OPENSSL_SYS_OS2) || + * defined(OPENSSL_SYS_VXWORKS) || + * defined(OPENSSL_SYS_NETWARE)) */ + +#if defined(OPENSSL_SYS_VXWORKS) +int RAND_poll(void) +{ + return 0; +} +#endif +/* crypto/rand/rand_vms.c */ +/* + * Written by Richard Levitte for the OpenSSL project + * 2000. + */ +/* + * Modified by VMS Software, Inc (2016) + * Eliminate looping through all processes (performance) + * Add additional randomizations using rand() function + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "rand.h" +// #include "rand_lcl.h" + +#if defined(OPENSSL_SYS_VMS) +# include +# include +# include +# include +# include +# ifdef __DECC +# pragma message disable DOLLARID +# endif + +/* + * Use 32-bit pointers almost everywhere. Define the type to which to cast a + * pointer passed to an external function. + */ +# if __INITIAL_POINTER_SIZE == 64 +# define PTR_T __void_ptr64 +# pragma pointer_size save +# pragma pointer_size 32 +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define PTR_T void * +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + +static struct items_data_st { + short length, code; /* length is number of bytes */ +} items_data[] = { + {4, JPI$_BUFIO}, + {4, JPI$_CPUTIM}, + {4, JPI$_DIRIO}, + {4, JPI$_IMAGECOUNT}, + {8, JPI$_LAST_LOGIN_I}, + {8, JPI$_LOGINTIM}, + {4, JPI$_PAGEFLTS}, + {4, JPI$_PID}, + {4, JPI$_PPGCNT}, + {4, JPI$_WSPEAK}, + {4, JPI$_FINALEXC}, + {0, 0} /* zero terminated */ +}; + +int RAND_poll(void) +{ + + /* determine the number of items in the JPI array */ + + struct items_data_st item_entry; + int item_entry_count = sizeof(items_data)/sizeof(item_entry); + + /* Create the JPI itemlist array to hold item_data content */ + + struct { + short length, code; + int *buffer; + int *retlen; + } item[item_entry_count], *pitem; /* number of entries in items_data */ + + struct items_data_st *pitems_data; + pitems_data = items_data; + pitem = item; + int data_buffer[(item_entry_count*2)+4]; /* 8 bytes per entry max */ + int iosb[2]; + int sys_time[2]; + int *ptr; + int i, j ; + int tmp_length = 0; + int total_length = 0; + + /* Setup itemlist for GETJPI */ + + while (pitems_data->length) { + pitem->length = pitems_data->length; + pitem->code = pitems_data->code; + pitem->buffer = &data_buffer[total_length]; + pitem->retlen = 0; + /* total_length is in longwords */ + total_length += pitems_data->length/4; + pitems_data++; + pitem ++; + } + pitem->length = pitem->code = 0; + + /* Fill data_buffer with various info bits from this process */ + /* and twist that data to seed the SSL random number init */ + + if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) == SS$_NORMAL) { + for (i = 0; i < total_length; i++) { + sys$gettim((struct _generic_64 *)&sys_time[0]); + srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i); + + if (i == (total_length - 1)) { /* for JPI$_FINALEXC */ + ptr = &data_buffer[i]; + for (j = 0; j < 4; j++) { + data_buffer[i + j] = ptr[j]; + /* OK to use rand() just to scramble the seed */ + data_buffer[i + j] ^= (sys_time[0] ^ rand()); + tmp_length++; + } + } else { + /* OK to use rand() just to scramble the seed */ + data_buffer[i] ^= (sys_time[0] ^ rand()); + } + } + + total_length += (tmp_length - 1); + + /* size of seed is total_length*4 bytes (64bytes) */ + RAND_add((PTR_T) data_buffer, total_length*4, total_length * 2); + } else { + return 0; + } + + return 1; +} +#endif +/* crypto/rand/rand_win.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "rand.h" +// #include "rand_lcl.h" + +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# include +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +# endif +# include +# include + +/* + * Limit the time spent walking through the heap, processes, threads and + * modules to a maximum of 1000 miliseconds each, unless CryptoGenRandom + * failed + */ +# define MAXDELAY 1000 + +/* + * Intel hardware RNG CSP -- available from + * http://developer.intel.com/design/security/rng/redist_license.htm + */ +# define PROV_INTEL_SEC 22 +# define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider" + +static void readtimer(void); +static void readscreen(void); + +/* + * It appears like CURSORINFO, PCURSORINFO and LPCURSORINFO are only defined + * when WINVER is 0x0500 and up, which currently only happens on Win2000. + * Unfortunately, those are typedefs, so they're a little bit difficult to + * detect properly. On the other hand, the macro CURSOR_SHOWING is defined + * within the same conditional, so it can be use to detect the absence of + * said typedefs. + */ + +# ifndef CURSOR_SHOWING +/* + * Information about the global cursor. + */ +typedef struct tagCURSORINFO { + DWORD cbSize; + DWORD flags; + HCURSOR hCursor; + POINT ptScreenPos; +} CURSORINFO, *PCURSORINFO, *LPCURSORINFO; + +# define CURSOR_SHOWING 0x00000001 +# endif /* CURSOR_SHOWING */ + +# if !defined(OPENSSL_SYS_WINCE) +typedef BOOL(WINAPI *CRYPTACQUIRECONTEXTW) (HCRYPTPROV *, LPCWSTR, LPCWSTR, + DWORD, DWORD); +typedef BOOL(WINAPI *CRYPTGENRANDOM) (HCRYPTPROV, DWORD, BYTE *); +typedef BOOL(WINAPI *CRYPTRELEASECONTEXT) (HCRYPTPROV, DWORD); + +typedef HWND(WINAPI *GETFOREGROUNDWINDOW) (VOID); +typedef BOOL(WINAPI *GETCURSORINFO) (PCURSORINFO); +typedef DWORD(WINAPI *GETQUEUESTATUS) (UINT); + +typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD); +typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE); +typedef BOOL(WINAPI *HEAP32FIRST) (LPHEAPENTRY32, DWORD, size_t); +typedef BOOL(WINAPI *HEAP32NEXT) (LPHEAPENTRY32); +typedef BOOL(WINAPI *HEAP32LIST) (HANDLE, LPHEAPLIST32); +typedef BOOL(WINAPI *PROCESS32) (HANDLE, LPPROCESSENTRY32); +typedef BOOL(WINAPI *THREAD32) (HANDLE, LPTHREADENTRY32); +typedef BOOL(WINAPI *MODULE32) (HANDLE, LPMODULEENTRY32); + +# include +# include +# if 1 +/* + * The NET API is Unicode only. It requires the use of the UNICODE macro. + * When UNICODE is defined LPTSTR becomes LPWSTR. LMSTR was was added to the + * Platform SDK to allow the NET API to be used in non-Unicode applications + * provided that Unicode strings were still used for input. LMSTR is defined + * as LPWSTR. + */ +typedef NET_API_STATUS(NET_API_FUNCTION *NETSTATGET) + (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE *); +typedef NET_API_STATUS(NET_API_FUNCTION *NETFREE) (LPBYTE); +# endif /* 1 */ +# endif /* !OPENSSL_SYS_WINCE */ + +#define NOTTOOLONG(start) ((GetTickCount() - (start)) < MAXDELAY) + +int RAND_poll(void) +{ + MEMORYSTATUS m; + HCRYPTPROV hProvider = 0; + DWORD w; + int good = 0; + +# if defined(OPENSSL_SYS_WINCE) +# if defined(_WIN32_WCE) && _WIN32_WCE>=300 + /* + * Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available + * in commonly available implementations prior 300... + */ + { + BYTE buf[64]; + /* poll the CryptoAPI PRNG */ + /* The CryptoAPI returns sizeof(buf) bytes of randomness */ + if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + if (CryptGenRandom(hProvider, sizeof(buf), buf)) + RAND_add(buf, sizeof(buf), sizeof(buf)); + CryptReleaseContext(hProvider, 0); + } + } +# endif +# else /* OPENSSL_SYS_WINCE */ + /* + * None of below libraries are present on Windows CE, which is + * why we #ifndef the whole section. This also excuses us from + * handling the GetProcAddress issue. The trouble is that in + * real Win32 API GetProcAddress is available in ANSI flavor + * only. In WinCE on the other hand GetProcAddress is a macro + * most commonly defined as GetProcAddressW, which accepts + * Unicode argument. If we were to call GetProcAddress under + * WinCE, I'd recommend to either redefine GetProcAddress as + * GetProcAddressA (there seem to be one in common CE spec) or + * implement own shim routine, which would accept ANSI argument + * and expand it to Unicode. + */ + { + /* load functions dynamically - not available on all systems */ + HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL")); + HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL")); + HMODULE user = NULL; + HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL")); + CRYPTACQUIRECONTEXTW acquire = NULL; + CRYPTGENRANDOM gen = NULL; + CRYPTRELEASECONTEXT release = NULL; + NETSTATGET netstatget = NULL; + NETFREE netfree = NULL; + BYTE buf[64]; + + if (netapi) { + netstatget = + (NETSTATGET) GetProcAddress(netapi, "NetStatisticsGet"); + netfree = (NETFREE) GetProcAddress(netapi, "NetApiBufferFree"); + } + + if (netstatget && netfree) { + LPBYTE outbuf; + /* + * NetStatisticsGet() is a Unicode only function + * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0 + * contains 17 fields. We treat each field as a source of one + * byte of entropy. + */ + + if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0) { + RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45); + netfree(outbuf); + } + if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0) { + RAND_add(outbuf, sizeof(STAT_SERVER_0), 17); + netfree(outbuf); + } + } + + if (netapi) + FreeLibrary(netapi); + + /* + * It appears like this can cause an exception deep within + * ADVAPI32.DLL at random times on Windows 2000. Reported by Jeffrey + * Altman. Only use it on NT. + */ + + if (advapi) { + /* + * If it's available, then it's available in both ANSI + * and UNICODE flavors even in Win9x, documentation says. + * We favor Unicode... + */ + acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi, + "CryptAcquireContextW"); + gen = (CRYPTGENRANDOM) GetProcAddress(advapi, "CryptGenRandom"); + release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi, + "CryptReleaseContext"); + } + + if (acquire && gen && release) { + /* poll the CryptoAPI PRNG */ + /* The CryptoAPI returns sizeof(buf) bytes of randomness */ + if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + if (gen(hProvider, sizeof(buf), buf) != 0) { + RAND_add(buf, sizeof(buf), 0); + good = 1; +# if 0 + printf("randomness from PROV_RSA_FULL\n"); +# endif + } + release(hProvider, 0); + } + + /* poll the Pentium PRG with CryptoAPI */ + if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0)) { + if (gen(hProvider, sizeof(buf), buf) != 0) { + RAND_add(buf, sizeof(buf), sizeof(buf)); + good = 1; +# if 0 + printf("randomness from PROV_INTEL_SEC\n"); +# endif + } + release(hProvider, 0); + } + } + + if (advapi) + FreeLibrary(advapi); + + if ((!check_winnt() || + !OPENSSL_isservice()) && + (user = LoadLibrary(TEXT("USER32.DLL")))) { + GETCURSORINFO cursor; + GETFOREGROUNDWINDOW win; + GETQUEUESTATUS queue; + + win = + (GETFOREGROUNDWINDOW) GetProcAddress(user, + "GetForegroundWindow"); + cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo"); + queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus"); + + if (win) { + /* window handle */ + HWND h = win(); + RAND_add(&h, sizeof(h), 0); + } + if (cursor) { + /* + * unfortunately, its not safe to call GetCursorInfo() on NT4 + * even though it exists in SP3 (or SP6) and higher. + */ + if (check_winnt() && !check_win_minplat(5)) + cursor = 0; + } + if (cursor) { + /* cursor position */ + /* assume 2 bytes of entropy */ + CURSORINFO ci; + ci.cbSize = sizeof(CURSORINFO); + if (cursor(&ci)) + RAND_add(&ci, ci.cbSize, 2); + } + + if (queue) { + /* message queue status */ + /* assume 1 byte of entropy */ + w = queue(QS_ALLEVENTS); + RAND_add(&w, sizeof(w), 1); + } + + FreeLibrary(user); + } + + /*- + * Toolhelp32 snapshot: enumerate processes, threads, modules and heap + * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm + * (Win 9x and 2000 only, not available on NT) + * + * This seeding method was proposed in Peter Gutmann, Software + * Generation of Practically Strong Random Numbers, + * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html + * revised version at http://www.cryptoengines.com/~peter/06_random.pdf + * (The assignment of entropy estimates below is arbitrary, but based + * on Peter's analysis the full poll appears to be safe. Additional + * interactive seeding is encouraged.) + */ + + if (kernel) { + CREATETOOLHELP32SNAPSHOT snap; + CLOSETOOLHELP32SNAPSHOT close_snap; + HANDLE handle; + + HEAP32FIRST heap_first; + HEAP32NEXT heap_next; + HEAP32LIST heaplist_first, heaplist_next; + PROCESS32 process_first, process_next; + THREAD32 thread_first, thread_next; + MODULE32 module_first, module_next; + + HEAPLIST32 hlist; + HEAPENTRY32 hentry; + PROCESSENTRY32 p; + THREADENTRY32 t; + MODULEENTRY32 m; + DWORD starttime = 0; + + snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(kernel, "CreateToolhelp32Snapshot"); + close_snap = (CLOSETOOLHELP32SNAPSHOT) + GetProcAddress(kernel, "CloseToolhelp32Snapshot"); + heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First"); + heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next"); + heaplist_first = + (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst"); + heaplist_next = + (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext"); + process_first = + (PROCESS32) GetProcAddress(kernel, "Process32First"); + process_next = + (PROCESS32) GetProcAddress(kernel, "Process32Next"); + thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First"); + thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next"); + module_first = (MODULE32) GetProcAddress(kernel, "Module32First"); + module_next = (MODULE32) GetProcAddress(kernel, "Module32Next"); + + if (snap && heap_first && heap_next && heaplist_first && + heaplist_next && process_first && process_next && + thread_first && thread_next && module_first && + module_next && (handle = snap(TH32CS_SNAPALL, 0)) + != INVALID_HANDLE_VALUE) { + /* heap list and heap walking */ + /* + * HEAPLIST32 contains 3 fields that will change with each + * entry. Consider each field a source of 1 byte of entropy. + * HEAPENTRY32 contains 5 fields that will change with each + * entry. Consider each field a source of 1 byte of entropy. + */ + ZeroMemory(&hlist, sizeof(HEAPLIST32)); + hlist.dwSize = sizeof(HEAPLIST32); + if (good) + starttime = GetTickCount(); +# ifdef _MSC_VER + if (heaplist_first(handle, &hlist)) { + /* + * following discussion on dev ML, exception on WinCE (or + * other Win platform) is theoretically of unknown + * origin; prevent infinite loop here when this + * theoretical case occurs; otherwise cope with the + * expected (MSDN documented) exception-throwing + * behaviour of Heap32Next() on WinCE. + * + * based on patch in original message by Tanguy Fautré + * (2009/03/02) Subject: RAND_poll() and + * CreateToolhelp32Snapshot() stability + */ + int ex_cnt_limit = 42; + do { + RAND_add(&hlist, hlist.dwSize, 3); + __try { + ZeroMemory(&hentry, sizeof(HEAPENTRY32)); + hentry.dwSize = sizeof(HEAPENTRY32); + if (heap_first(&hentry, + hlist.th32ProcessID, + hlist.th32HeapID)) { + int entrycnt = 80; + do + RAND_add(&hentry, hentry.dwSize, 5); + while (heap_next(&hentry) + && (!good || NOTTOOLONG(starttime)) + && --entrycnt > 0); + } + } + __except(EXCEPTION_EXECUTE_HANDLER) { + /* + * ignore access violations when walking the heap + * list + */ + ex_cnt_limit--; + } + } while (heaplist_next(handle, &hlist) + && (!good || NOTTOOLONG(starttime)) + && ex_cnt_limit > 0); + } +# else + if (heaplist_first(handle, &hlist)) { + do { + RAND_add(&hlist, hlist.dwSize, 3); + hentry.dwSize = sizeof(HEAPENTRY32); + if (heap_first(&hentry, + hlist.th32ProcessID, + hlist.th32HeapID)) { + int entrycnt = 80; + do + RAND_add(&hentry, hentry.dwSize, 5); + while (heap_next(&hentry) + && (!good || NOTTOOLONG(starttime)) + && --entrycnt > 0); + } + } while (heaplist_next(handle, &hlist) + && (!good || NOTTOOLONG(starttime))); + } +# endif + + /* process walking */ + /* + * PROCESSENTRY32 contains 9 fields that will change with + * each entry. Consider each field a source of 1 byte of + * entropy. + */ + p.dwSize = sizeof(PROCESSENTRY32); + + if (good) + starttime = GetTickCount(); + if (process_first(handle, &p)) + do + RAND_add(&p, p.dwSize, 9); + while (process_next(handle, &p) + && (!good || NOTTOOLONG(starttime))); + + /* thread walking */ + /* + * THREADENTRY32 contains 6 fields that will change with each + * entry. Consider each field a source of 1 byte of entropy. + */ + t.dwSize = sizeof(THREADENTRY32); + if (good) + starttime = GetTickCount(); + if (thread_first(handle, &t)) + do + RAND_add(&t, t.dwSize, 6); + while (thread_next(handle, &t) + && (!good || NOTTOOLONG(starttime))); + + /* module walking */ + /* + * MODULEENTRY32 contains 9 fields that will change with each + * entry. Consider each field a source of 1 byte of entropy. + */ + m.dwSize = sizeof(MODULEENTRY32); + if (good) + starttime = GetTickCount(); + if (module_first(handle, &m)) + do + RAND_add(&m, m.dwSize, 9); + while (module_next(handle, &m) + && (!good || NOTTOOLONG(starttime))); + if (close_snap) + close_snap(handle); + else + CloseHandle(handle); + + } + + FreeLibrary(kernel); + } + } +# endif /* !OPENSSL_SYS_WINCE */ + + /* timer data */ + readtimer(); + + /* memory usage statistics */ + GlobalMemoryStatus(&m); + RAND_add(&m, sizeof(m), 1); + + /* process ID */ + w = GetCurrentProcessId(); + RAND_add(&w, sizeof(w), 1); + +# if 0 + printf("Exiting RAND_poll\n"); +# endif + + return (1); +} + +int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + double add_entropy = 0; + + switch (iMsg) { + case WM_KEYDOWN: + { + static WPARAM key; + if (key != wParam) + add_entropy = 0.05; + key = wParam; + } + break; + case WM_MOUSEMOVE: + { + static int lastx, lasty, lastdx, lastdy; + int x, y, dx, dy; + + x = LOWORD(lParam); + y = HIWORD(lParam); + dx = lastx - x; + dy = lasty - y; + if (dx != 0 && dy != 0 && dx - lastdx != 0 && dy - lastdy != 0) + add_entropy = .2; + lastx = x, lasty = y; + lastdx = dx, lastdy = dy; + } + break; + } + + readtimer(); + RAND_add(&iMsg, sizeof(iMsg), add_entropy); + RAND_add(&wParam, sizeof(wParam), 0); + RAND_add(&lParam, sizeof(lParam), 0); + + return (RAND_status()); +} + +void RAND_screen(void) +{ /* function available for backward + * compatibility */ + RAND_poll(); + readscreen(); +} + +/* feed timing information to the PRNG */ +static void readtimer(void) +{ + DWORD w; + LARGE_INTEGER l; + static int have_perfc = 1; +# if defined(_MSC_VER) && defined(_M_X86) + static int have_tsc = 1; + DWORD cyclecount; + + if (have_tsc) { + __try { + __asm { + _emit 0x0f _emit 0x31 mov cyclecount, eax} + RAND_add(&cyclecount, sizeof(cyclecount), 1); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + have_tsc = 0; + } + } +# else +# define have_tsc 0 +# endif + + if (have_perfc) { + if (QueryPerformanceCounter(&l) == 0) + have_perfc = 0; + else + RAND_add(&l, sizeof(l), 0); + } + + if (!have_tsc && !have_perfc) { + w = GetTickCount(); + RAND_add(&w, sizeof(w), 0); + } +} + +/* feed screen contents to PRNG */ +/***************************************************************************** + * + * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V. + * + * Code adapted from + * ; + * the original copyright message is: + * + * (C) Copyright Microsoft Corp. 1993. All rights reserved. + * + * You have a royalty-free right to use, modify, reproduce and + * distribute the Sample Files (and/or any modified version) in + * any way you find useful, provided that you agree that + * Microsoft has no warranty obligations or liability for any + * Sample Application Files which are modified. + */ + +static void readscreen(void) +{ +# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) + HDC hScrDC; /* screen DC */ + HBITMAP hBitmap; /* handle for our bitmap */ + BITMAP bm; /* bitmap properties */ + unsigned int size; /* size of bitmap */ + char *bmbits; /* contents of bitmap */ + int w; /* screen width */ + int h; /* screen height */ + int y; /* y-coordinate of screen lines to grab */ + int n = 16; /* number of screen lines to grab at a time */ + BITMAPINFOHEADER bi; /* info about the bitmap */ + + if (check_winnt() && OPENSSL_isservice() > 0) + return; + + /* Get a reference to the screen DC */ + hScrDC = GetDC(NULL); + + /* Get screen resolution */ + w = GetDeviceCaps(hScrDC, HORZRES); + h = GetDeviceCaps(hScrDC, VERTRES); + + /* Create a bitmap compatible with the screen DC */ + hBitmap = CreateCompatibleBitmap(hScrDC, w, n); + + /* Get bitmap properties */ + GetObject(hBitmap, sizeof(bm), (LPSTR)&bm); + size = (unsigned int)4 * bm.bmHeight * bm.bmWidth; + bi.biSize = sizeof(bi); + bi.biWidth = bm.bmWidth; + bi.biHeight = bm.bmHeight; + bi.biPlanes = 1; + bi.biBitCount = 32; + bi.biCompression = BI_RGB; + bi.biSizeImage = 0; + bi.biXPelsPerMeter = 0; + bi.biYPelsPerMeter = 0; + bi.biClrUsed = 0; + bi.biClrImportant = 0; + + bmbits = OPENSSL_malloc(size); + if (bmbits) { + /* Now go through the whole screen, repeatedly grabbing n lines */ + for (y = 0; y < h - n; y += n) { + unsigned char md[MD_DIGEST_LENGTH]; + + /* Copy the bits of the current line range into the buffer */ + GetDIBits(hScrDC, hBitmap, y, n, + bmbits, (LPBITMAPINFO)&bi, DIB_RGB_COLORS); + + /* Get the hash of the bitmap */ + MD(bmbits, size, md); + + /* Seed the random generator with the hash value */ + RAND_add(md, MD_DIGEST_LENGTH, 0); + } + + OPENSSL_free(bmbits); + } + + /* Clean up */ + DeleteObject(hBitmap); + ReleaseDC(NULL, hScrDC); +# endif /* !OPENSSL_SYS_WINCE */ +} + +#endif diff --git a/Sources/COpenSSL/rand_lcl.h b/Sources/COpenSSL/rand_lcl.h new file mode 100644 index 00000000..500a44a2 --- /dev/null +++ b/Sources/COpenSSL/rand_lcl.h @@ -0,0 +1,158 @@ +/* crypto/rand/rand_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_RAND_LCL_H +# define HEADER_RAND_LCL_H + +# define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */ + +# if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +# define USE_SHA1_RAND +# elif !defined(OPENSSL_NO_MD5) +# define USE_MD5_RAND +# elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES) +# define USE_MDC2_RAND +# elif !defined(OPENSSL_NO_MD2) +# define USE_MD2_RAND +# else +# error No message digest algorithm available +# endif +# endif + +# include "evp.h" +# define MD_Update(a,b,c) EVP_DigestUpdate(a,b,c) +# define MD_Final(a,b) EVP_DigestFinal_ex(a,b,NULL) +# if defined(USE_MD5_RAND) +# include "md5.h" +# define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH +# define MD_Init(a) EVP_DigestInit_ex(a,EVP_md5(), NULL) +# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md5(), NULL) +# elif defined(USE_SHA1_RAND) +# include "sha.h" +# define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH +# define MD_Init(a) EVP_DigestInit_ex(a,EVP_sha1(), NULL) +# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL) +# elif defined(USE_MDC2_RAND) +# include "mdc2.h" +# define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH +# define MD_Init(a) EVP_DigestInit_ex(a,EVP_mdc2(), NULL) +# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL) +# elif defined(USE_MD2_RAND) +# include +# define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH +# define MD_Init(a) EVP_DigestInit_ex(a,EVP_md2(), NULL) +# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL) +# endif + +int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock); +int ssleay_rand_bytes_from_system(unsigned char *buf, int num); +#endif diff --git a/Sources/COpenSSL/randfile.c b/Sources/COpenSSL/randfile.c new file mode 100644 index 00000000..ff5a6858 --- /dev/null +++ b/Sources/COpenSSL/randfile.c @@ -0,0 +1,371 @@ +/* crypto/rand/randfile.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#include "cryptlib.h" +#include "e_os.h" +#include "crypto.h" +#include "rand.h" +#include "buffer.h" + +#ifdef OPENSSL_SYS_VMS +# include +#endif +#ifndef NO_SYS_TYPES_H +# include +#endif +#ifndef OPENSSL_NO_POSIX_IO +# include +# include +/* + * Following should not be needed, and we could have been stricter + * and demand S_IS*. But some systems just don't comply... Formally + * below macros are "anatomically incorrect", because normally they + * would look like ((m) & MASK == TYPE), but since MASK availability + * is as questionable, we settle for this poor-man fallback... + */ +# if !defined(S_ISBLK) +# if defined(_S_IFBLK) +# define S_ISBLK(m) ((m) & _S_IFBLK) +# elif defined(S_IFBLK) +# define S_ISBLK(m) ((m) & S_IFBLK) +# elif defined(_WIN32) +# define S_ISBLK(m) 0 /* no concept of block devices on Windows */ +# endif +# endif +# if !defined(S_ISCHR) +# if defined(_S_IFCHR) +# define S_ISCHR(m) ((m) & _S_IFCHR) +# elif defined(S_IFCHR) +# define S_ISCHR(m) ((m) & S_IFCHR) +# endif +# endif +#endif + +#ifdef _WIN32 +# define stat _stat +# define chmod _chmod +# define open _open +# define fdopen _fdopen +#endif + +#undef BUFSIZE +#define BUFSIZE 1024 +#define RAND_DATA 1024 + +#if (defined(OPENSSL_SYS_VMS) && (defined(__alpha) || defined(__ia64))) +/* + * This declaration is a nasty hack to get around vms' extension to fopen for + * passing in sharing options being disabled by our /STANDARD=ANSI89 + */ +static FILE *(*const vms_fopen)(const char *, const char *, ...) = + (FILE *(*)(const char *, const char *, ...))fopen; +# define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0" +#endif + +/* #define RFILE ".rnd" - defined in ../../e_os.h */ + +/* + * Note that these functions are intended for seed files only. Entropy + * devices and EGD sockets are handled in rand_unix.c + */ + +int RAND_load_file(const char *file, long bytes) +{ + /*- + * If bytes >= 0, read up to 'bytes' bytes. + * if bytes == -1, read complete file. + */ + + MS_STATIC unsigned char buf[BUFSIZE]; +#ifndef OPENSSL_NO_POSIX_IO + struct stat sb; +#endif + int i, ret = 0, n; +/* + * If setvbuf() is to be called, then the FILE pointer + * to it must be 32 bit. +*/ + +#if !defined OPENSSL_NO_SETVBUF_IONBF && defined(OPENSSL_SYS_VMS) && defined(__VMS_VER) && (__VMS_VER >= 70000000) + /* For 64-bit-->32 bit API Support*/ +#if __INITIAL_POINTER_SIZE == 64 +#pragma __required_pointer_size __save +#pragma __required_pointer_size 32 +#endif + FILE *in; /* setvbuf() requires 32-bit pointers */ +#if __INITIAL_POINTER_SIZE == 64 +#pragma __required_pointer_size __restore +#endif +#else + FILE *in; +#endif /* OPENSSL_SYS_VMS */ + + if (file == NULL) + return (0); + +#ifndef OPENSSL_NO_POSIX_IO +# ifdef PURIFY + /* + * struct stat can have padding and unused fields that may not be + * initialized in the call to stat(). We need to clear the entire + * structure before calling RAND_add() to avoid complaints from + * applications such as Valgrind. + */ + memset(&sb, 0, sizeof(sb)); +# endif + if (stat(file, &sb) < 0) + return (0); + RAND_add(&sb, sizeof(sb), 0.0); +#endif + if (bytes == 0) + return (ret); + +#ifdef OPENSSL_SYS_VMS + in = vms_fopen(file, "rb", VMS_OPEN_ATTRS); +#else + in = fopen(file, "rb"); +#endif + if (in == NULL) + goto err; +#if defined(S_ISBLK) && defined(S_ISCHR) && !defined(OPENSSL_NO_POSIX_IO) + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { + /* + * this file is a device. we don't want read an infinite number of + * bytes from a random device, nor do we want to use buffered I/O + * because we will waste system entropy. + */ + bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */ +# ifndef OPENSSL_NO_SETVBUF_IONBF + setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */ +# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ + } +#endif + for (;;) { + if (bytes > 0) + n = (bytes < BUFSIZE) ? (int)bytes : BUFSIZE; + else + n = BUFSIZE; + i = fread(buf, 1, n, in); + if (i <= 0) + break; +#ifdef PURIFY + RAND_add(buf, i, (double)i); +#else + /* even if n != i, use the full array */ + RAND_add(buf, n, (double)i); +#endif + ret += i; + if (bytes > 0) { + bytes -= n; + if (bytes <= 0) + break; + } + } + fclose(in); + OPENSSL_cleanse(buf, BUFSIZE); + err: + return (ret); +} + +int RAND_write_file(const char *file) +{ + unsigned char buf[BUFSIZE]; + int i, ret = 0, rand_err = 0; + FILE *out = NULL; + int n; +#ifndef OPENSSL_NO_POSIX_IO + struct stat sb; + + i = stat(file, &sb); + if (i != -1) { +# if defined(S_ISBLK) && defined(S_ISCHR) + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { + /* + * this file is a device. we don't write back to it. we + * "succeed" on the assumption this is some sort of random + * device. Otherwise attempting to write to and chmod the device + * causes problems. + */ + return (1); + } +# endif + } +#endif + +#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS) + { +# ifndef O_BINARY +# define O_BINARY 0 +# endif + /* + * chmod(..., 0600) is too late to protect the file, permissions + * should be restrictive from the start + */ + int fd = open(file, O_WRONLY | O_CREAT | O_BINARY, 0600); + if (fd != -1) + out = fdopen(fd, "wb"); + } +#endif + +#if (defined(OPENSSL_SYS_VMS) && (defined(__alpha) || defined(__ia64))) + /* + * VMS NOTE: Prior versions of this routine created a _new_ version of + * the rand file for each call into this routine, then deleted all + * existing versions named ;-1, and finally renamed the current version + * as ';1'. Under concurrent usage, this resulted in an RMS race + * condition in rename() which could orphan files (see vms message help + * for RMS$_REENT). With the fopen() calls below, openssl/VMS now shares + * the top-level version of the rand file. Note that there may still be + * conditions where the top-level rand file is locked. If so, this code + * will then create a new version of the rand file. Without the delete + * and rename code, this can result in ascending file versions that stop + * at version 32767, and this routine will then return an error. The + * remedy for this is to recode the calling application to avoid + * concurrent use of the rand file, or synchronize usage at the + * application level. Also consider whether or not you NEED a persistent + * rand file in a concurrent use situation. + */ + + out = vms_fopen(file, "rb+", VMS_OPEN_ATTRS); + if (out == NULL) + out = vms_fopen(file, "wb", VMS_OPEN_ATTRS); +#else + if (out == NULL) + out = fopen(file, "wb"); +#endif + if (out == NULL) + goto err; + +#ifndef NO_CHMOD + chmod(file, 0600); +#endif + n = RAND_DATA; + for (;;) { + i = (n > BUFSIZE) ? BUFSIZE : n; + n -= BUFSIZE; + if (RAND_bytes(buf, i) <= 0) + rand_err = 1; + i = fwrite(buf, 1, i, out); + if (i <= 0) { + ret = 0; + break; + } + ret += i; + if (n <= 0) + break; + } + + fclose(out); + OPENSSL_cleanse(buf, BUFSIZE); + err: + return (rand_err ? -1 : ret); +} + +const char *RAND_file_name(char *buf, size_t size) +{ + char *s = NULL; +#ifdef __OpenBSD__ + struct stat sb; +#endif + + s = ossl_safe_getenv("RANDFILE"); + if (s != NULL && *s && strlen(s) + 1 < size) { + if (BUF_strlcpy(buf, s, size) >= size) + return NULL; + } else { + s = ossl_safe_getenv("HOME"); +#ifdef DEFAULT_HOME + if (s == NULL) { + s = DEFAULT_HOME; + } +#endif + if (s && *s && strlen(s) + strlen(RFILE) + 2 < size) { + BUF_strlcpy(buf, s, size); +#ifndef OPENSSL_SYS_VMS + BUF_strlcat(buf, "/", size); +#endif + BUF_strlcat(buf, RFILE, size); + } else + buf[0] = '\0'; /* no file name */ + } + +#ifdef __OpenBSD__ + /* + * given that all random loads just fail if the file can't be seen on a + * stat, we stat the file we're returning, if it fails, use /dev/arandom + * instead. this allows the user to use their own source for good random + * data, but defaults to something hopefully decent if that isn't + * available. + */ + + if (!buf[0]) + if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) { + return (NULL); + } + if (stat(buf, &sb) == -1) + if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) { + return (NULL); + } +#endif + return (buf); +} diff --git a/Sources/COpenSSL/rc2.h b/Sources/COpenSSL/rc2.h new file mode 100644 index 00000000..fb887701 --- /dev/null +++ b/Sources/COpenSSL/rc2.h @@ -0,0 +1,103 @@ +/* crypto/rc2/rc2.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC2_H +# define HEADER_RC2_H + +# include "opensslconf.h"/* OPENSSL_NO_RC2, RC2_INT */ +# ifdef OPENSSL_NO_RC2 +# error RC2 is disabled. +# endif + +# define RC2_ENCRYPT 1 +# define RC2_DECRYPT 0 + +# define RC2_BLOCK 8 +# define RC2_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc2_key_st { + RC2_INT data[64]; +} RC2_KEY; + +# ifdef OPENSSL_FIPS +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, + int bits); +# endif +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC2_KEY *key, int enc); +void RC2_encrypt(unsigned long *data, RC2_KEY *key); +void RC2_decrypt(unsigned long *data, RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int enc); +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/rc2_.c b/Sources/COpenSSL/rc2_.c new file mode 100644 index 00000000..7ca86e23 --- /dev/null +++ b/Sources/COpenSSL/rc2_.c @@ -0,0 +1,477 @@ +/* crypto/rc2/rc2_cbc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "rc2.h" +#include "rc2_locl.h" + +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int encrypt) +{ + register unsigned long tin0, tin1; + register unsigned long tout0, tout1, xor0, xor1; + register long l = length; + unsigned long tin[2]; + + if (encrypt) { + c2l(iv, tout0); + c2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +void RC2_encrypt(unsigned long *d, RC2_KEY *key) +{ + int i, n; + register RC2_INT *p0, *p1; + register RC2_INT x0, x1, x2, x3, t; + unsigned long l; + + l = d[0]; + x0 = (RC2_INT) l & 0xffff; + x1 = (RC2_INT) (l >> 16L); + l = d[1]; + x2 = (RC2_INT) l & 0xffff; + x3 = (RC2_INT) (l >> 16L); + + n = 3; + i = 5; + + p0 = p1 = &(key->data[0]); + for (;;) { + t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; + x0 = (t << 1) | (t >> 15); + t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; + x1 = (t << 2) | (t >> 14); + t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; + x2 = (t << 3) | (t >> 13); + t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; + x3 = (t << 5) | (t >> 11); + + if (--i == 0) { + if (--n == 0) + break; + i = (n == 2) ? 6 : 5; + + x0 += p1[x3 & 0x3f]; + x1 += p1[x0 & 0x3f]; + x2 += p1[x1 & 0x3f]; + x3 += p1[x2 & 0x3f]; + } + } + + d[0] = + (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); + d[1] = + (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); +} + +void RC2_decrypt(unsigned long *d, RC2_KEY *key) +{ + int i, n; + register RC2_INT *p0, *p1; + register RC2_INT x0, x1, x2, x3, t; + unsigned long l; + + l = d[0]; + x0 = (RC2_INT) l & 0xffff; + x1 = (RC2_INT) (l >> 16L); + l = d[1]; + x2 = (RC2_INT) l & 0xffff; + x3 = (RC2_INT) (l >> 16L); + + n = 3; + i = 5; + + p0 = &(key->data[63]); + p1 = &(key->data[0]); + for (;;) { + t = ((x3 << 11) | (x3 >> 5)) & 0xffff; + x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff; + t = ((x2 << 13) | (x2 >> 3)) & 0xffff; + x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff; + t = ((x1 << 14) | (x1 >> 2)) & 0xffff; + x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff; + t = ((x0 << 15) | (x0 >> 1)) & 0xffff; + x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff; + + if (--i == 0) { + if (--n == 0) + break; + i = (n == 2) ? 6 : 5; + + x3 = (x3 - p1[x2 & 0x3f]) & 0xffff; + x2 = (x2 - p1[x1 & 0x3f]) & 0xffff; + x1 = (x1 - p1[x0 & 0x3f]) & 0xffff; + x0 = (x0 - p1[x3 & 0x3f]) & 0xffff; + } + } + + d[0] = + (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); + d[1] = + (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); +} +/* crypto/rc2/rc2_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "rc2.h" +// #include "rc2_locl.h" +#include "opensslv.h" + +const char RC2_version[] = "RC2" OPENSSL_VERSION_PTEXT; + +/*- + * RC2 as implemented frm a posting from + * Newsgroups: sci.crypt + * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann) + * Subject: Specification for Ron Rivests Cipher No.2 + * Message-ID: <4fk39f$f70@net.auckland.ac.nz> + * Date: 11 Feb 1996 06:45:03 GMT + */ + +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks, + int encrypt) +{ + unsigned long l, d[2]; + + c2l(in, l); + d[0] = l; + c2l(in, l); + d[1] = l; + if (encrypt) + RC2_encrypt(d, ks); + else + RC2_decrypt(d, ks); + l = d[0]; + l2c(l, out); + l = d[1]; + l2c(l, out); + l = d[0] = d[1] = 0; +} +/* crypto/rc2/rc2_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "crypto.h" +// #include "rc2.h" +// #include "rc2_locl.h" + +static const unsigned char key_table[256] = { + 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, + 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, + 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5, + 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, + 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, + 0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, + 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f, + 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, + 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, + 0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, + 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde, + 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, + 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, + 0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, + 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85, + 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, + 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, + 0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, + 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b, + 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, + 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, + 0xfe, 0x7f, 0xc1, 0xad, +}; + +#if defined(_MSC_VER) && defined(_ARM_) +# pragma optimize("g",off) +#endif + +/* + * It has come to my attention that there are 2 versions of the RC2 key + * schedule. One which is normal, and anther which has a hook to use a + * reduced key length. BSAFE uses the 'retarded' version. What I previously + * shipped is the same as specifying 1024 for the 'bits' parameter. Bsafe + * uses a version where the bits parameter is the same as len*8 + */ +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(RC2); + private_RC2_set_key(key, len, data, bits); +} + +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, + int bits) +#endif +{ + int i, j; + unsigned char *k; + RC2_INT *ki; + unsigned int c, d; + + k = (unsigned char *)&(key->data[0]); + *k = 0; /* for if there is a zero length key */ + + if (len > 128) + len = 128; + if (bits <= 0) + bits = 1024; + if (bits > 1024) + bits = 1024; + + for (i = 0; i < len; i++) + k[i] = data[i]; + + /* expand table */ + d = k[len - 1]; + j = 0; + for (i = len; i < 128; i++, j++) { + d = key_table[(k[j] + d) & 0xff]; + k[i] = d; + } + + /* hmm.... key reduction to 'bits' bits */ + + j = (bits + 7) >> 3; + i = 128 - j; + c = (0xff >> (-bits & 0x07)); + + d = key_table[k[i] & c]; + k[i] = d; + while (i--) { + d = key_table[k[i + j] ^ d]; + k[i] = d; + } + + /* copy from bytes into RC2_INT's */ + ki = &(key->data[63]); + for (i = 127; i >= 0; i -= 2) + *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff; +} + +#if defined(_MSC_VER) +# pragma optimize("",on) +#endif diff --git a/Sources/COpenSSL/rc2_locl.h b/Sources/COpenSSL/rc2_locl.h new file mode 100644 index 00000000..e72a20c0 --- /dev/null +++ b/Sources/COpenSSL/rc2_locl.h @@ -0,0 +1,155 @@ +/* crypto/rc2/rc2_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#define C_RC2(n) \ + t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \ + x0=(t<<1)|(t>>15); \ + t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \ + x1=(t<<2)|(t>>14); \ + t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \ + x2=(t<<3)|(t>>13); \ + t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \ + x3=(t<<5)|(t>>11); diff --git a/Sources/COpenSSL/rc2cfb64.c b/Sources/COpenSSL/rc2cfb64.c new file mode 100644 index 00000000..445099dc --- /dev/null +++ b/Sources/COpenSSL/rc2cfb64.c @@ -0,0 +1,123 @@ +/* crypto/rc2/rc2cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "rc2.h" +#include "rc2_locl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int encrypt) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned long ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + RC2_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2c(t, iv); + t = ti[1]; + l2c(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + RC2_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2c(t, iv); + t = ti[1]; + l2c(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} diff --git a/Sources/COpenSSL/rc2ofb64.c b/Sources/COpenSSL/rc2ofb64.c new file mode 100644 index 00000000..18f58f18 --- /dev/null +++ b/Sources/COpenSSL/rc2ofb64.c @@ -0,0 +1,110 @@ +/* crypto/rc2/rc2ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "rc2.h" +#include "rc2_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + unsigned long ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + RC2_encrypt((unsigned long *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2c(t, dp); + t = ti[1]; + l2c(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2c(v0, iv); + l2c(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/Sources/COpenSSL/rc4.h b/Sources/COpenSSL/rc4.h new file mode 100644 index 00000000..a9db1753 --- /dev/null +++ b/Sources/COpenSSL/rc4.h @@ -0,0 +1,88 @@ +/* crypto/rc4/rc4.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC4_H +# define HEADER_RC4_H + +# include "opensslconf.h"/* OPENSSL_NO_RC4, RC4_INT */ +# ifdef OPENSSL_NO_RC4 +# error RC4 is disabled. +# endif + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st { + RC4_INT x, y; + RC4_INT data[256]; +} RC4_KEY; + +const char *RC4_options(void); +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/rc4_.c b/Sources/COpenSSL/rc4_.c new file mode 100644 index 00000000..244947d1 --- /dev/null +++ b/Sources/COpenSSL/rc4_.c @@ -0,0 +1,512 @@ +/* crypto/rc4/rc4_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "rc4.h" +#include "rc4_locl.h" + +/*- + * RC4 as implemented from a posting from + * Newsgroups: sci.crypt + * From: sterndark@netcom.com (David Sterndark) + * Subject: RC4 Algorithm revealed. + * Message-ID: + * Date: Wed, 14 Sep 1994 06:35:31 GMT + */ + +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata) +{ + register RC4_INT *d; + register RC4_INT x, y, tx, ty; + size_t i; + + x = key->x; + y = key->y; + d = key->data; + +#if defined(RC4_CHUNK) && !defined(PEDANTIC) + /*- + * The original reason for implementing this(*) was the fact that + * pre-21164a Alpha CPUs don't have byte load/store instructions + * and e.g. a byte store has to be done with 64-bit load, shift, + * and, or and finally 64-bit store. Peaking data and operating + * at natural word size made it possible to reduce amount of + * instructions as well as to perform early read-ahead without + * suffering from RAW (read-after-write) hazard. This resulted + * in ~40%(**) performance improvement on 21064 box with gcc. + * But it's not only Alpha users who win here:-) Thanks to the + * early-n-wide read-ahead this implementation also exhibits + * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending + * on sizeof(RC4_INT)). + * + * (*) "this" means code which recognizes the case when input + * and output pointers appear to be aligned at natural CPU + * word boundary + * (**) i.e. according to 'apps/openssl speed rc4' benchmark, + * crypto/rc4/rc4speed.c exhibits almost 70% speed-up... + * + * Cavets. + * + * - RC4_CHUNK="unsigned long long" should be a #1 choice for + * UltraSPARC. Unfortunately gcc generates very slow code + * (2.5-3 times slower than one generated by Sun's WorkShop + * C) and therefore gcc (at least 2.95 and earlier) should + * always be told that RC4_CHUNK="unsigned long". + * + * + */ + +# define RC4_STEP ( \ + x=(x+1) &0xff, \ + tx=d[x], \ + y=(tx+y)&0xff, \ + ty=d[y], \ + d[y]=tx, \ + d[x]=ty, \ + (RC4_CHUNK)d[(tx+ty)&0xff]\ + ) + + if ((((size_t)indata & (sizeof(RC4_CHUNK) - 1)) | + ((size_t)outdata & (sizeof(RC4_CHUNK) - 1))) == 0) { + RC4_CHUNK ichunk, otp; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + /*- + * I reckon we can afford to implement both endian + * cases and to decide which way to take at run-time + * because the machine code appears to be very compact + * and redundant 1-2KB is perfectly tolerable (i.e. + * in case the compiler fails to eliminate it:-). By + * suggestion from Terrel Larson + * who also stands for the is_endian union:-) + * + * Special notes. + * + * - is_endian is declared automatic as doing otherwise + * (declaring static) prevents gcc from eliminating + * the redundant code; + * - compilers (those I've tried) don't seem to have + * problems eliminating either the operators guarded + * by "if (sizeof(RC4_CHUNK)==8)" or the condition + * expressions themselves so I've got 'em to replace + * corresponding #ifdefs from the previous version; + * - I chose to let the redundant switch cases when + * sizeof(RC4_CHUNK)!=8 be (were also #ifdefed + * before); + * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in + * [LB]ESHFT guards against "shift is out of range" + * warnings when sizeof(RC4_CHUNK)!=8 + * + * + */ + if (!is_endian.little) { /* BIG-ENDIAN CASE */ +# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1)) + for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) { + ichunk = *(RC4_CHUNK *) indata; + otp = RC4_STEP << BESHFT(0); + otp |= RC4_STEP << BESHFT(1); + otp |= RC4_STEP << BESHFT(2); + otp |= RC4_STEP << BESHFT(3); + if (sizeof(RC4_CHUNK) == 8) { + otp |= RC4_STEP << BESHFT(4); + otp |= RC4_STEP << BESHFT(5); + otp |= RC4_STEP << BESHFT(6); + otp |= RC4_STEP << BESHFT(7); + } + *(RC4_CHUNK *) outdata = otp ^ ichunk; + indata += sizeof(RC4_CHUNK); + outdata += sizeof(RC4_CHUNK); + } + if (len) { + RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk; + + ichunk = *(RC4_CHUNK *) indata; + ochunk = *(RC4_CHUNK *) outdata; + otp = 0; + i = BESHFT(0); + mask <<= (sizeof(RC4_CHUNK) - len) << 3; + switch (len & (sizeof(RC4_CHUNK) - 1)) { + case 7: + otp = RC4_STEP << i, i -= 8; + case 6: + otp |= RC4_STEP << i, i -= 8; + case 5: + otp |= RC4_STEP << i, i -= 8; + case 4: + otp |= RC4_STEP << i, i -= 8; + case 3: + otp |= RC4_STEP << i, i -= 8; + case 2: + otp |= RC4_STEP << i, i -= 8; + case 1: + otp |= RC4_STEP << i, i -= 8; + case 0:; /* + * it's never the case, + * but it has to be here + * for ultrix? + */ + } + ochunk &= ~mask; + ochunk |= (otp ^ ichunk) & mask; + *(RC4_CHUNK *) outdata = ochunk; + } + key->x = x; + key->y = y; + return; + } else { /* LITTLE-ENDIAN CASE */ +# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1)) + for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) { + ichunk = *(RC4_CHUNK *) indata; + otp = RC4_STEP; + otp |= RC4_STEP << 8; + otp |= RC4_STEP << 16; + otp |= RC4_STEP << 24; + if (sizeof(RC4_CHUNK) == 8) { + otp |= RC4_STEP << LESHFT(4); + otp |= RC4_STEP << LESHFT(5); + otp |= RC4_STEP << LESHFT(6); + otp |= RC4_STEP << LESHFT(7); + } + *(RC4_CHUNK *) outdata = otp ^ ichunk; + indata += sizeof(RC4_CHUNK); + outdata += sizeof(RC4_CHUNK); + } + if (len) { + RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk; + + ichunk = *(RC4_CHUNK *) indata; + ochunk = *(RC4_CHUNK *) outdata; + otp = 0; + i = 0; + mask >>= (sizeof(RC4_CHUNK) - len) << 3; + switch (len & (sizeof(RC4_CHUNK) - 1)) { + case 7: + otp = RC4_STEP, i += 8; + case 6: + otp |= RC4_STEP << i, i += 8; + case 5: + otp |= RC4_STEP << i, i += 8; + case 4: + otp |= RC4_STEP << i, i += 8; + case 3: + otp |= RC4_STEP << i, i += 8; + case 2: + otp |= RC4_STEP << i, i += 8; + case 1: + otp |= RC4_STEP << i, i += 8; + case 0:; /* + * it's never the case, + * but it has to be here + * for ultrix? + */ + } + ochunk &= ~mask; + ochunk |= (otp ^ ichunk) & mask; + *(RC4_CHUNK *) outdata = ochunk; + } + key->x = x; + key->y = y; + return; + } + } +#endif +#define LOOP(in,out) \ + x=((x+1)&0xff); \ + tx=d[x]; \ + y=(tx+y)&0xff; \ + d[x]=ty=d[y]; \ + d[y]=tx; \ + (out) = d[(tx+ty)&0xff]^ (in); + +#ifndef RC4_INDEX +# define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++)) +#else +# define RC4_LOOP(a,b,i) LOOP(a[i],b[i]) +#endif + + i = len >> 3; + if (i) { + for (;;) { + RC4_LOOP(indata, outdata, 0); + RC4_LOOP(indata, outdata, 1); + RC4_LOOP(indata, outdata, 2); + RC4_LOOP(indata, outdata, 3); + RC4_LOOP(indata, outdata, 4); + RC4_LOOP(indata, outdata, 5); + RC4_LOOP(indata, outdata, 6); + RC4_LOOP(indata, outdata, 7); +#ifdef RC4_INDEX + indata += 8; + outdata += 8; +#endif + if (--i == 0) + break; + } + } + i = len & 0x07; + if (i) { + for (;;) { + RC4_LOOP(indata, outdata, 0); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 1); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 2); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 3); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 4); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 5); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 6); + if (--i == 0) + break; + } + } + key->x = x; + key->y = y; +} +/* crypto/rc4/rc4_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "rc4.h" +// #include "rc4_locl.h" +#include "opensslv.h" + +const char RC4_version[] = "RC4" OPENSSL_VERSION_PTEXT; + +const char *RC4_options(void) +{ +#ifdef RC4_INDEX + if (sizeof(RC4_INT) == 1) + return ("rc4(idx,char)"); + else + return ("rc4(idx,int)"); +#else + if (sizeof(RC4_INT) == 1) + return ("rc4(ptr,char)"); + else + return ("rc4(ptr,int)"); +#endif +} + +/*- + * RC4 as implemented from a posting from + * Newsgroups: sci.crypt + * From: sterndark@netcom.com (David Sterndark) + * Subject: RC4 Algorithm revealed. + * Message-ID: + * Date: Wed, 14 Sep 1994 06:35:31 GMT + */ + +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +{ + register RC4_INT tmp; + register int id1, id2; + register RC4_INT *d; + unsigned int i; + + d = &(key->data[0]); + key->x = 0; + key->y = 0; + id1 = id2 = 0; + +#define SK_LOOP(d,n) { \ + tmp=d[(n)]; \ + id2 = (data[id1] + tmp + id2) & 0xff; \ + if (++id1 == len) id1=0; \ + d[(n)]=d[id2]; \ + d[id2]=tmp; } + + for (i = 0; i < 256; i++) + d[i] = i; + for (i = 0; i < 256; i += 4) { + SK_LOOP(d, i + 0); + SK_LOOP(d, i + 1); + SK_LOOP(d, i + 2); + SK_LOOP(d, i + 3); + } +} +/* crypto/rc4/rc4_utl.c */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "opensslv.h" +#include "crypto.h" +// #include "rc4.h" + +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +{ +#ifdef OPENSSL_FIPS + fips_cipher_abort(RC4); +#endif + private_RC4_set_key(key, len, data); +} diff --git a/Sources/COpenSSL/rc4_locl.h b/Sources/COpenSSL/rc4_locl.h new file mode 100644 index 00000000..5737a64e --- /dev/null +++ b/Sources/COpenSSL/rc4_locl.h @@ -0,0 +1,5 @@ +#ifndef HEADER_RC4_LOCL_H +# define HEADER_RC4_LOCL_H +# include "opensslconf.h" +# include "cryptlib.h" +#endif diff --git a/Sources/COpenSSL/read2pwd.c b/Sources/COpenSSL/read2pwd.c new file mode 100644 index 00000000..a9521856 --- /dev/null +++ b/Sources/COpenSSL/read2pwd.c @@ -0,0 +1,140 @@ +/* crypto/des/read2pwd.c */ +/* ==================================================================== + * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "des.h" +#include "ui.h" +#include "crypto.h" + +int DES_read_password(DES_cblock *key, const char *prompt, int verify) +{ + int ok; + char buf[BUFSIZ], buff[BUFSIZ]; + + if ((ok = UI_UTIL_read_pw(buf, buff, BUFSIZ, prompt, verify)) == 0) + DES_string_to_key(buf, key); + OPENSSL_cleanse(buf, BUFSIZ); + OPENSSL_cleanse(buff, BUFSIZ); + return (ok); +} + +int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, + const char *prompt, int verify) +{ + int ok; + char buf[BUFSIZ], buff[BUFSIZ]; + + if ((ok = UI_UTIL_read_pw(buf, buff, BUFSIZ, prompt, verify)) == 0) + DES_string_to_2keys(buf, key1, key2); + OPENSSL_cleanse(buf, BUFSIZ); + OPENSSL_cleanse(buff, BUFSIZ); + return (ok); +} diff --git a/Sources/COpenSSL/ripemd.h b/Sources/COpenSSL/ripemd.h new file mode 100644 index 00000000..5c5100d7 --- /dev/null +++ b/Sources/COpenSSL/ripemd.h @@ -0,0 +1,105 @@ +/* crypto/ripemd/ripemd.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RIPEMD_H +# define HEADER_RIPEMD_H + +# include "e_os2.h" +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_RIPEMD +# error RIPEMD is disabled. +# endif + +# if defined(__LP32__) +# define RIPEMD160_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define RIPEMD160_LONG unsigned long +# define RIPEMD160_LONG_LOG2 3 +# else +# define RIPEMD160_LONG unsigned int +# endif + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct RIPEMD160state_st { + RIPEMD160_LONG A, B, C, D, E; + RIPEMD160_LONG Nl, Nh; + RIPEMD160_LONG data[RIPEMD160_LBLOCK]; + unsigned int num; +} RIPEMD160_CTX; + +# ifdef OPENSSL_FIPS +int private_RIPEMD160_Init(RIPEMD160_CTX *c); +# endif +int RIPEMD160_Init(RIPEMD160_CTX *c); +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); +unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md); +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/rmd_.c b/Sources/COpenSSL/rmd_.c new file mode 100644 index 00000000..69c8490c --- /dev/null +++ b/Sources/COpenSSL/rmd_.c @@ -0,0 +1,411 @@ +/* crypto/ripemd/rmd_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rmd_locl.h" +#include "opensslv.h" +// #include "crypto.h" + +const char RMD160_version[] = "RIPE-MD160" OPENSSL_VERSION_PTEXT; + +#ifdef RMD160_ASM +void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p, size_t num); +# define ripemd160_block ripemd160_block_x86 +#else +void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p, size_t num); +#endif + +fips_md_init(RIPEMD160) +{ + memset(c, 0, sizeof(*c)); + c->A = RIPEMD160_A; + c->B = RIPEMD160_B; + c->C = RIPEMD160_C; + c->D = RIPEMD160_D; + c->E = RIPEMD160_E; + return 1; +} + +#ifndef ripemd160_block_data_order +# ifdef X +# undef X +# endif +void ripemd160_block_data_order(RIPEMD160_CTX *ctx, const void *p, size_t num) +{ + const unsigned char *data = p; + register unsigned MD32_REG_T A, B, C, D, E; + unsigned MD32_REG_T a, b, c, d, e, l; +# ifndef MD32_XARRAY + /* See comment in crypto/sha/sha_locl.h for details. */ + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# define X(i) XX##i +# else + RIPEMD160_LONG XX[16]; +# define X(i) XX[i] +# endif + + for (; num--;) { + + A = ctx->A; + B = ctx->B; + C = ctx->C; + D = ctx->D; + E = ctx->E; + + (void)HOST_c2l(data, l); + X(0) = l; + (void)HOST_c2l(data, l); + X(1) = l; + RIP1(A, B, C, D, E, WL00, SL00); + (void)HOST_c2l(data, l); + X(2) = l; + RIP1(E, A, B, C, D, WL01, SL01); + (void)HOST_c2l(data, l); + X(3) = l; + RIP1(D, E, A, B, C, WL02, SL02); + (void)HOST_c2l(data, l); + X(4) = l; + RIP1(C, D, E, A, B, WL03, SL03); + (void)HOST_c2l(data, l); + X(5) = l; + RIP1(B, C, D, E, A, WL04, SL04); + (void)HOST_c2l(data, l); + X(6) = l; + RIP1(A, B, C, D, E, WL05, SL05); + (void)HOST_c2l(data, l); + X(7) = l; + RIP1(E, A, B, C, D, WL06, SL06); + (void)HOST_c2l(data, l); + X(8) = l; + RIP1(D, E, A, B, C, WL07, SL07); + (void)HOST_c2l(data, l); + X(9) = l; + RIP1(C, D, E, A, B, WL08, SL08); + (void)HOST_c2l(data, l); + X(10) = l; + RIP1(B, C, D, E, A, WL09, SL09); + (void)HOST_c2l(data, l); + X(11) = l; + RIP1(A, B, C, D, E, WL10, SL10); + (void)HOST_c2l(data, l); + X(12) = l; + RIP1(E, A, B, C, D, WL11, SL11); + (void)HOST_c2l(data, l); + X(13) = l; + RIP1(D, E, A, B, C, WL12, SL12); + (void)HOST_c2l(data, l); + X(14) = l; + RIP1(C, D, E, A, B, WL13, SL13); + (void)HOST_c2l(data, l); + X(15) = l; + RIP1(B, C, D, E, A, WL14, SL14); + RIP1(A, B, C, D, E, WL15, SL15); + + RIP2(E, A, B, C, D, WL16, SL16, KL1); + RIP2(D, E, A, B, C, WL17, SL17, KL1); + RIP2(C, D, E, A, B, WL18, SL18, KL1); + RIP2(B, C, D, E, A, WL19, SL19, KL1); + RIP2(A, B, C, D, E, WL20, SL20, KL1); + RIP2(E, A, B, C, D, WL21, SL21, KL1); + RIP2(D, E, A, B, C, WL22, SL22, KL1); + RIP2(C, D, E, A, B, WL23, SL23, KL1); + RIP2(B, C, D, E, A, WL24, SL24, KL1); + RIP2(A, B, C, D, E, WL25, SL25, KL1); + RIP2(E, A, B, C, D, WL26, SL26, KL1); + RIP2(D, E, A, B, C, WL27, SL27, KL1); + RIP2(C, D, E, A, B, WL28, SL28, KL1); + RIP2(B, C, D, E, A, WL29, SL29, KL1); + RIP2(A, B, C, D, E, WL30, SL30, KL1); + RIP2(E, A, B, C, D, WL31, SL31, KL1); + + RIP3(D, E, A, B, C, WL32, SL32, KL2); + RIP3(C, D, E, A, B, WL33, SL33, KL2); + RIP3(B, C, D, E, A, WL34, SL34, KL2); + RIP3(A, B, C, D, E, WL35, SL35, KL2); + RIP3(E, A, B, C, D, WL36, SL36, KL2); + RIP3(D, E, A, B, C, WL37, SL37, KL2); + RIP3(C, D, E, A, B, WL38, SL38, KL2); + RIP3(B, C, D, E, A, WL39, SL39, KL2); + RIP3(A, B, C, D, E, WL40, SL40, KL2); + RIP3(E, A, B, C, D, WL41, SL41, KL2); + RIP3(D, E, A, B, C, WL42, SL42, KL2); + RIP3(C, D, E, A, B, WL43, SL43, KL2); + RIP3(B, C, D, E, A, WL44, SL44, KL2); + RIP3(A, B, C, D, E, WL45, SL45, KL2); + RIP3(E, A, B, C, D, WL46, SL46, KL2); + RIP3(D, E, A, B, C, WL47, SL47, KL2); + + RIP4(C, D, E, A, B, WL48, SL48, KL3); + RIP4(B, C, D, E, A, WL49, SL49, KL3); + RIP4(A, B, C, D, E, WL50, SL50, KL3); + RIP4(E, A, B, C, D, WL51, SL51, KL3); + RIP4(D, E, A, B, C, WL52, SL52, KL3); + RIP4(C, D, E, A, B, WL53, SL53, KL3); + RIP4(B, C, D, E, A, WL54, SL54, KL3); + RIP4(A, B, C, D, E, WL55, SL55, KL3); + RIP4(E, A, B, C, D, WL56, SL56, KL3); + RIP4(D, E, A, B, C, WL57, SL57, KL3); + RIP4(C, D, E, A, B, WL58, SL58, KL3); + RIP4(B, C, D, E, A, WL59, SL59, KL3); + RIP4(A, B, C, D, E, WL60, SL60, KL3); + RIP4(E, A, B, C, D, WL61, SL61, KL3); + RIP4(D, E, A, B, C, WL62, SL62, KL3); + RIP4(C, D, E, A, B, WL63, SL63, KL3); + + RIP5(B, C, D, E, A, WL64, SL64, KL4); + RIP5(A, B, C, D, E, WL65, SL65, KL4); + RIP5(E, A, B, C, D, WL66, SL66, KL4); + RIP5(D, E, A, B, C, WL67, SL67, KL4); + RIP5(C, D, E, A, B, WL68, SL68, KL4); + RIP5(B, C, D, E, A, WL69, SL69, KL4); + RIP5(A, B, C, D, E, WL70, SL70, KL4); + RIP5(E, A, B, C, D, WL71, SL71, KL4); + RIP5(D, E, A, B, C, WL72, SL72, KL4); + RIP5(C, D, E, A, B, WL73, SL73, KL4); + RIP5(B, C, D, E, A, WL74, SL74, KL4); + RIP5(A, B, C, D, E, WL75, SL75, KL4); + RIP5(E, A, B, C, D, WL76, SL76, KL4); + RIP5(D, E, A, B, C, WL77, SL77, KL4); + RIP5(C, D, E, A, B, WL78, SL78, KL4); + RIP5(B, C, D, E, A, WL79, SL79, KL4); + + a = A; + b = B; + c = C; + d = D; + e = E; + /* Do other half */ + A = ctx->A; + B = ctx->B; + C = ctx->C; + D = ctx->D; + E = ctx->E; + + RIP5(A, B, C, D, E, WR00, SR00, KR0); + RIP5(E, A, B, C, D, WR01, SR01, KR0); + RIP5(D, E, A, B, C, WR02, SR02, KR0); + RIP5(C, D, E, A, B, WR03, SR03, KR0); + RIP5(B, C, D, E, A, WR04, SR04, KR0); + RIP5(A, B, C, D, E, WR05, SR05, KR0); + RIP5(E, A, B, C, D, WR06, SR06, KR0); + RIP5(D, E, A, B, C, WR07, SR07, KR0); + RIP5(C, D, E, A, B, WR08, SR08, KR0); + RIP5(B, C, D, E, A, WR09, SR09, KR0); + RIP5(A, B, C, D, E, WR10, SR10, KR0); + RIP5(E, A, B, C, D, WR11, SR11, KR0); + RIP5(D, E, A, B, C, WR12, SR12, KR0); + RIP5(C, D, E, A, B, WR13, SR13, KR0); + RIP5(B, C, D, E, A, WR14, SR14, KR0); + RIP5(A, B, C, D, E, WR15, SR15, KR0); + + RIP4(E, A, B, C, D, WR16, SR16, KR1); + RIP4(D, E, A, B, C, WR17, SR17, KR1); + RIP4(C, D, E, A, B, WR18, SR18, KR1); + RIP4(B, C, D, E, A, WR19, SR19, KR1); + RIP4(A, B, C, D, E, WR20, SR20, KR1); + RIP4(E, A, B, C, D, WR21, SR21, KR1); + RIP4(D, E, A, B, C, WR22, SR22, KR1); + RIP4(C, D, E, A, B, WR23, SR23, KR1); + RIP4(B, C, D, E, A, WR24, SR24, KR1); + RIP4(A, B, C, D, E, WR25, SR25, KR1); + RIP4(E, A, B, C, D, WR26, SR26, KR1); + RIP4(D, E, A, B, C, WR27, SR27, KR1); + RIP4(C, D, E, A, B, WR28, SR28, KR1); + RIP4(B, C, D, E, A, WR29, SR29, KR1); + RIP4(A, B, C, D, E, WR30, SR30, KR1); + RIP4(E, A, B, C, D, WR31, SR31, KR1); + + RIP3(D, E, A, B, C, WR32, SR32, KR2); + RIP3(C, D, E, A, B, WR33, SR33, KR2); + RIP3(B, C, D, E, A, WR34, SR34, KR2); + RIP3(A, B, C, D, E, WR35, SR35, KR2); + RIP3(E, A, B, C, D, WR36, SR36, KR2); + RIP3(D, E, A, B, C, WR37, SR37, KR2); + RIP3(C, D, E, A, B, WR38, SR38, KR2); + RIP3(B, C, D, E, A, WR39, SR39, KR2); + RIP3(A, B, C, D, E, WR40, SR40, KR2); + RIP3(E, A, B, C, D, WR41, SR41, KR2); + RIP3(D, E, A, B, C, WR42, SR42, KR2); + RIP3(C, D, E, A, B, WR43, SR43, KR2); + RIP3(B, C, D, E, A, WR44, SR44, KR2); + RIP3(A, B, C, D, E, WR45, SR45, KR2); + RIP3(E, A, B, C, D, WR46, SR46, KR2); + RIP3(D, E, A, B, C, WR47, SR47, KR2); + + RIP2(C, D, E, A, B, WR48, SR48, KR3); + RIP2(B, C, D, E, A, WR49, SR49, KR3); + RIP2(A, B, C, D, E, WR50, SR50, KR3); + RIP2(E, A, B, C, D, WR51, SR51, KR3); + RIP2(D, E, A, B, C, WR52, SR52, KR3); + RIP2(C, D, E, A, B, WR53, SR53, KR3); + RIP2(B, C, D, E, A, WR54, SR54, KR3); + RIP2(A, B, C, D, E, WR55, SR55, KR3); + RIP2(E, A, B, C, D, WR56, SR56, KR3); + RIP2(D, E, A, B, C, WR57, SR57, KR3); + RIP2(C, D, E, A, B, WR58, SR58, KR3); + RIP2(B, C, D, E, A, WR59, SR59, KR3); + RIP2(A, B, C, D, E, WR60, SR60, KR3); + RIP2(E, A, B, C, D, WR61, SR61, KR3); + RIP2(D, E, A, B, C, WR62, SR62, KR3); + RIP2(C, D, E, A, B, WR63, SR63, KR3); + + RIP1(B, C, D, E, A, WR64, SR64); + RIP1(A, B, C, D, E, WR65, SR65); + RIP1(E, A, B, C, D, WR66, SR66); + RIP1(D, E, A, B, C, WR67, SR67); + RIP1(C, D, E, A, B, WR68, SR68); + RIP1(B, C, D, E, A, WR69, SR69); + RIP1(A, B, C, D, E, WR70, SR70); + RIP1(E, A, B, C, D, WR71, SR71); + RIP1(D, E, A, B, C, WR72, SR72); + RIP1(C, D, E, A, B, WR73, SR73); + RIP1(B, C, D, E, A, WR74, SR74); + RIP1(A, B, C, D, E, WR75, SR75); + RIP1(E, A, B, C, D, WR76, SR76); + RIP1(D, E, A, B, C, WR77, SR77); + RIP1(C, D, E, A, B, WR78, SR78); + RIP1(B, C, D, E, A, WR79, SR79); + + D = ctx->B + c + D; + ctx->B = ctx->C + d + E; + ctx->C = ctx->D + e + A; + ctx->D = ctx->E + a + B; + ctx->E = ctx->A + b + C; + ctx->A = D; + + } +} +#endif +/* crypto/ripemd/rmd_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "ripemd.h" +// #include "crypto.h" + +unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md) +{ + RIPEMD160_CTX c; + static unsigned char m[RIPEMD160_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!RIPEMD160_Init(&c)) + return NULL; + RIPEMD160_Update(&c, d, n); + RIPEMD160_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ + return (md); +} diff --git a/Sources/COpenSSL/rmd_locl.h b/Sources/COpenSSL/rmd_locl.h new file mode 100644 index 00000000..62d5ecdd --- /dev/null +++ b/Sources/COpenSSL/rmd_locl.h @@ -0,0 +1,149 @@ +/* crypto/ripemd/rmd_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "opensslconf.h" +#include "ripemd.h" + +#ifndef RIPEMD160_LONG_LOG2 +# define RIPEMD160_LONG_LOG2 2 /* default to 32 bits */ +#endif + +/* + * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c + * FOR EXPLANATIONS ON FOLLOWING "CODE." + * + */ +#ifdef RMD160_ASM +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) +# define ripemd160_block_data_order ripemd160_block_asm_data_order +# endif +#endif + +void ripemd160_block_data_order(RIPEMD160_CTX *c, const void *p, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG RIPEMD160_LONG +#define HASH_CTX RIPEMD160_CTX +#define HASH_CBLOCK RIPEMD160_CBLOCK +#define HASH_UPDATE RIPEMD160_Update +#define HASH_TRANSFORM RIPEMD160_Transform +#define HASH_FINAL RIPEMD160_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; (void)HOST_l2c(ll,(s)); \ + ll=(c)->B; (void)HOST_l2c(ll,(s)); \ + ll=(c)->C; (void)HOST_l2c(ll,(s)); \ + ll=(c)->D; (void)HOST_l2c(ll,(s)); \ + ll=(c)->E; (void)HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order + +#include "md32_common.h" + +#if 0 +# define F1(x,y,z) ((x)^(y)^(z)) +# define F2(x,y,z) (((x)&(y))|((~x)&z)) +# define F3(x,y,z) (((x)|(~y))^(z)) +# define F4(x,y,z) (((x)&(z))|((y)&(~(z)))) +# define F5(x,y,z) ((x)^((y)|(~(z)))) +#else +/* + * Transformed F2 and F4 are courtesy of Wei Dai + */ +# define F1(x,y,z) ((x) ^ (y) ^ (z)) +# define F2(x,y,z) ((((y) ^ (z)) & (x)) ^ (z)) +# define F3(x,y,z) (((~(y)) | (x)) ^ (z)) +# define F4(x,y,z) ((((x) ^ (y)) & (z)) ^ (y)) +# define F5(x,y,z) (((~(z)) | (y)) ^ (x)) +#endif + +#define RIPEMD160_A 0x67452301L +#define RIPEMD160_B 0xEFCDAB89L +#define RIPEMD160_C 0x98BADCFEL +#define RIPEMD160_D 0x10325476L +#define RIPEMD160_E 0xC3D2E1F0L + +#include "rmdconst.h" + +#define RIP1(a,b,c,d,e,w,s) { \ + a+=F1(b,c,d)+X(w); \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP2(a,b,c,d,e,w,s,K) { \ + a+=F2(b,c,d)+X(w)+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP3(a,b,c,d,e,w,s,K) { \ + a+=F3(b,c,d)+X(w)+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP4(a,b,c,d,e,w,s,K) { \ + a+=F4(b,c,d)+X(w)+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP5(a,b,c,d,e,w,s,K) { \ + a+=F5(b,c,d)+X(w)+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } diff --git a/Sources/COpenSSL/rmdconst.h b/Sources/COpenSSL/rmdconst.h new file mode 100644 index 00000000..8fe33de1 --- /dev/null +++ b/Sources/COpenSSL/rmdconst.h @@ -0,0 +1,398 @@ +/* crypto/ripemd/rmdconst.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#define KL0 0x00000000L +#define KL1 0x5A827999L +#define KL2 0x6ED9EBA1L +#define KL3 0x8F1BBCDCL +#define KL4 0xA953FD4EL + +#define KR0 0x50A28BE6L +#define KR1 0x5C4DD124L +#define KR2 0x6D703EF3L +#define KR3 0x7A6D76E9L +#define KR4 0x00000000L + +#define WL00 0 +#define SL00 11 +#define WL01 1 +#define SL01 14 +#define WL02 2 +#define SL02 15 +#define WL03 3 +#define SL03 12 +#define WL04 4 +#define SL04 5 +#define WL05 5 +#define SL05 8 +#define WL06 6 +#define SL06 7 +#define WL07 7 +#define SL07 9 +#define WL08 8 +#define SL08 11 +#define WL09 9 +#define SL09 13 +#define WL10 10 +#define SL10 14 +#define WL11 11 +#define SL11 15 +#define WL12 12 +#define SL12 6 +#define WL13 13 +#define SL13 7 +#define WL14 14 +#define SL14 9 +#define WL15 15 +#define SL15 8 + +#define WL16 7 +#define SL16 7 +#define WL17 4 +#define SL17 6 +#define WL18 13 +#define SL18 8 +#define WL19 1 +#define SL19 13 +#define WL20 10 +#define SL20 11 +#define WL21 6 +#define SL21 9 +#define WL22 15 +#define SL22 7 +#define WL23 3 +#define SL23 15 +#define WL24 12 +#define SL24 7 +#define WL25 0 +#define SL25 12 +#define WL26 9 +#define SL26 15 +#define WL27 5 +#define SL27 9 +#define WL28 2 +#define SL28 11 +#define WL29 14 +#define SL29 7 +#define WL30 11 +#define SL30 13 +#define WL31 8 +#define SL31 12 + +#define WL32 3 +#define SL32 11 +#define WL33 10 +#define SL33 13 +#define WL34 14 +#define SL34 6 +#define WL35 4 +#define SL35 7 +#define WL36 9 +#define SL36 14 +#define WL37 15 +#define SL37 9 +#define WL38 8 +#define SL38 13 +#define WL39 1 +#define SL39 15 +#define WL40 2 +#define SL40 14 +#define WL41 7 +#define SL41 8 +#define WL42 0 +#define SL42 13 +#define WL43 6 +#define SL43 6 +#define WL44 13 +#define SL44 5 +#define WL45 11 +#define SL45 12 +#define WL46 5 +#define SL46 7 +#define WL47 12 +#define SL47 5 + +#define WL48 1 +#define SL48 11 +#define WL49 9 +#define SL49 12 +#define WL50 11 +#define SL50 14 +#define WL51 10 +#define SL51 15 +#define WL52 0 +#define SL52 14 +#define WL53 8 +#define SL53 15 +#define WL54 12 +#define SL54 9 +#define WL55 4 +#define SL55 8 +#define WL56 13 +#define SL56 9 +#define WL57 3 +#define SL57 14 +#define WL58 7 +#define SL58 5 +#define WL59 15 +#define SL59 6 +#define WL60 14 +#define SL60 8 +#define WL61 5 +#define SL61 6 +#define WL62 6 +#define SL62 5 +#define WL63 2 +#define SL63 12 + +#define WL64 4 +#define SL64 9 +#define WL65 0 +#define SL65 15 +#define WL66 5 +#define SL66 5 +#define WL67 9 +#define SL67 11 +#define WL68 7 +#define SL68 6 +#define WL69 12 +#define SL69 8 +#define WL70 2 +#define SL70 13 +#define WL71 10 +#define SL71 12 +#define WL72 14 +#define SL72 5 +#define WL73 1 +#define SL73 12 +#define WL74 3 +#define SL74 13 +#define WL75 8 +#define SL75 14 +#define WL76 11 +#define SL76 11 +#define WL77 6 +#define SL77 8 +#define WL78 15 +#define SL78 5 +#define WL79 13 +#define SL79 6 + +#define WR00 5 +#define SR00 8 +#define WR01 14 +#define SR01 9 +#define WR02 7 +#define SR02 9 +#define WR03 0 +#define SR03 11 +#define WR04 9 +#define SR04 13 +#define WR05 2 +#define SR05 15 +#define WR06 11 +#define SR06 15 +#define WR07 4 +#define SR07 5 +#define WR08 13 +#define SR08 7 +#define WR09 6 +#define SR09 7 +#define WR10 15 +#define SR10 8 +#define WR11 8 +#define SR11 11 +#define WR12 1 +#define SR12 14 +#define WR13 10 +#define SR13 14 +#define WR14 3 +#define SR14 12 +#define WR15 12 +#define SR15 6 + +#define WR16 6 +#define SR16 9 +#define WR17 11 +#define SR17 13 +#define WR18 3 +#define SR18 15 +#define WR19 7 +#define SR19 7 +#define WR20 0 +#define SR20 12 +#define WR21 13 +#define SR21 8 +#define WR22 5 +#define SR22 9 +#define WR23 10 +#define SR23 11 +#define WR24 14 +#define SR24 7 +#define WR25 15 +#define SR25 7 +#define WR26 8 +#define SR26 12 +#define WR27 12 +#define SR27 7 +#define WR28 4 +#define SR28 6 +#define WR29 9 +#define SR29 15 +#define WR30 1 +#define SR30 13 +#define WR31 2 +#define SR31 11 + +#define WR32 15 +#define SR32 9 +#define WR33 5 +#define SR33 7 +#define WR34 1 +#define SR34 15 +#define WR35 3 +#define SR35 11 +#define WR36 7 +#define SR36 8 +#define WR37 14 +#define SR37 6 +#define WR38 6 +#define SR38 6 +#define WR39 9 +#define SR39 14 +#define WR40 11 +#define SR40 12 +#define WR41 8 +#define SR41 13 +#define WR42 12 +#define SR42 5 +#define WR43 2 +#define SR43 14 +#define WR44 10 +#define SR44 13 +#define WR45 0 +#define SR45 13 +#define WR46 4 +#define SR46 7 +#define WR47 13 +#define SR47 5 + +#define WR48 8 +#define SR48 15 +#define WR49 6 +#define SR49 5 +#define WR50 4 +#define SR50 8 +#define WR51 1 +#define SR51 11 +#define WR52 3 +#define SR52 14 +#define WR53 11 +#define SR53 14 +#define WR54 15 +#define SR54 6 +#define WR55 0 +#define SR55 14 +#define WR56 5 +#define SR56 6 +#define WR57 12 +#define SR57 9 +#define WR58 2 +#define SR58 12 +#define WR59 13 +#define SR59 9 +#define WR60 9 +#define SR60 12 +#define WR61 7 +#define SR61 5 +#define WR62 10 +#define SR62 15 +#define WR63 14 +#define SR63 8 + +#define WR64 12 +#define SR64 8 +#define WR65 15 +#define SR65 5 +#define WR66 10 +#define SR66 12 +#define WR67 4 +#define SR67 9 +#define WR68 1 +#define SR68 12 +#define WR69 5 +#define SR69 5 +#define WR70 8 +#define SR70 14 +#define WR71 7 +#define SR71 6 +#define WR72 6 +#define SR72 8 +#define WR73 2 +#define SR73 13 +#define WR74 13 +#define SR74 6 +#define WR75 14 +#define SR75 5 +#define WR76 0 +#define SR76 15 +#define WR77 3 +#define SR77 13 +#define WR78 9 +#define SR78 11 +#define WR79 11 +#define SR79 11 diff --git a/Sources/COpenSSL/rpc_des.h b/Sources/COpenSSL/rpc_des.h new file mode 100644 index 00000000..4db9062d --- /dev/null +++ b/Sources/COpenSSL/rpc_des.h @@ -0,0 +1,130 @@ +/* crypto/des/rpc_des.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */ +/*- + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Generic DES driver interface + * Keep this file hardware independent! + * Copyright (c) 1986 by Sun Microsystems, Inc. + */ + +#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */ +#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */ + +#ifdef HEADER_DES_H +# undef ENCRYPT +# undef DECRYPT +#endif + +enum desdir { ENCRYPT, DECRYPT }; +enum desmode { CBC, ECB }; + +/* + * parameters to ioctl call + */ +struct desparams { + unsigned char des_key[8]; /* key (with low bit parity) */ + enum desdir des_dir; /* direction */ + enum desmode des_mode; /* mode */ + unsigned char des_ivec[8]; /* input vector */ + unsigned des_len; /* number of bytes to crypt */ + union { + unsigned char UDES_data[DES_QUICKLEN]; + unsigned char *UDES_buf; + } UDES; +#define des_data UDES.UDES_data /* direct data here if quick */ +#define des_buf UDES.UDES_buf /* otherwise, pointer to data */ +}; + +/* + * Encrypt an arbitrary sized buffer + */ +#define DESIOCBLOCK _IOWR('d', 6, struct desparams) + +/* + * Encrypt of small amount of data, quickly + */ +#define DESIOCQUICK _IOWR('d', 7, struct desparams) diff --git a/Sources/COpenSSL/rpc_enc.c b/Sources/COpenSSL/rpc_enc.c new file mode 100644 index 00000000..f5a84c5b --- /dev/null +++ b/Sources/COpenSSL/rpc_enc.c @@ -0,0 +1,100 @@ +/* crypto/des/rpc_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "rpc_des.h" +#include "des_locl.h" +#include "des_ver.h" + +int _des_crypt(char *buf, int len, struct desparams *desp); +int _des_crypt(char *buf, int len, struct desparams *desp) +{ + DES_key_schedule ks; + int enc; + + DES_set_key_unchecked(&desp->des_key, &ks); + enc = (desp->des_dir == ENCRYPT) ? DES_ENCRYPT : DES_DECRYPT; + + if (desp->des_mode == CBC) + DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf, + (DES_cblock *)desp->UDES.UDES_buf, &ks, enc); + else { + DES_ncbc_encrypt(desp->UDES.UDES_buf, desp->UDES.UDES_buf, + len, &ks, &desp->des_ivec, enc); +#ifdef undef + /* + * len will always be %8 if called from common_crypt in secure_rpc. + * Libdes's cbc encrypt does not copy back the iv, so we have to do + * it here. + */ + /* It does now :-) eay 20/09/95 */ + + a = (char *)&(desp->UDES.UDES_buf[len - 8]); + b = (char *)&(desp->des_ivec[0]); + + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); +#endif + } + return (1); +} diff --git a/Sources/COpenSSL/rsa.h b/Sources/COpenSSL/rsa.h new file mode 100644 index 00000000..d6ea13cc --- /dev/null +++ b/Sources/COpenSSL/rsa.h @@ -0,0 +1,664 @@ +/* crypto/rsa/rsa.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RSA_H +# define HEADER_RSA_H + +# include "asn1.h" + +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# include "crypto.h" +# include "ossl_typ.h" +# ifndef OPENSSL_NO_DEPRECATED +# include "bn.h" +# endif + +# ifdef OPENSSL_NO_RSA +# error RSA is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct rsa_st RSA; */ +/* typedef struct rsa_meth_st RSA_METHOD; */ + +struct rsa_meth_st { + const char *name; + int (*rsa_pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + /* Can be null */ + int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); + /* Can be null */ + int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + /* called at new */ + int (*init) (RSA *rsa); + /* called at free */ + int (*finish) (RSA *rsa); + /* RSA_METHOD_FLAG_* things */ + int flags; + /* may be needed! */ + char *app_data; + /* + * New sign and verify functions: some libraries don't allow arbitrary + * data to be signed/verified: this allows them to be used. Note: for + * this to work the RSA_public_decrypt() and RSA_private_encrypt() should + * *NOT* be used RSA_sign(), RSA_verify() should be used instead. Note: + * for backwards compatibility this functionality is only enabled if the + * RSA_FLAG_SIGN_VER option is set in 'flags'. + */ + int (*rsa_sign) (int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa); + int (*rsa_verify) (int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); + /* + * If this callback is NULL, the builtin software RSA key-gen will be + * used. This is for behavioural compatibility whilst the code gets + * rewired, but one day it would be nice to assume there are no such + * things as "builtin software" implementations. + */ + int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +}; + +struct rsa_st { + /* + * The first parameter is used to pickup errors where this is passed + * instead of aEVP_PKEY, it is set to 0 + */ + int pad; + long version; + const RSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + /* be careful using this if the RSA structure is shared */ + CRYPTO_EX_DATA ex_data; + int references; + int flags; + /* Used to cache montgomery values */ + BN_MONT_CTX *_method_mod_n; + BN_MONT_CTX *_method_mod_p; + BN_MONT_CTX *_method_mod_q; + /* + * all BIGNUM values are actually in the following data, if it is not + * NULL + */ + char *bignum_data; + BN_BLINDING *blinding; + BN_BLINDING *mt_blinding; +}; + +# ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +# endif + +# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +# endif +# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS + +/* exponent limit enforced for "large" modulus only */ +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 +# endif + +# define RSA_3 0x3L +# define RSA_F4 0x10001L + +# define RSA_METHOD_FLAG_NO_CHECK 0x0001/* don't check pub/private + * match */ + +# define RSA_FLAG_CACHE_PUBLIC 0x0002 +# define RSA_FLAG_CACHE_PRIVATE 0x0004 +# define RSA_FLAG_BLINDING 0x0008 +# define RSA_FLAG_THREAD_SAFE 0x0010 +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag + * bn_mod_exp gets called when private key components are absent. + */ +# define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify + * functions. + */ +# define RSA_FLAG_SIGN_VER 0x0040 + +/* + * new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ +# define RSA_FLAG_NO_BLINDING 0x0080 +/* + * new with 0.9.8f; the built-in RSA + * implementation now uses constant time + * operations by default in private key operations, + * e.g., constant time modular exponentiation, + * modular inverse without leaking branches, + * division without leaking branches. This + * flag disables these constant time + * operations and results in faster RSA + * private key operations. + */ +# define RSA_FLAG_NO_CONSTTIME 0x0100 +# ifdef OPENSSL_USE_DEPRECATED +/* deprecated name for the flag*/ +/* + * new with 0.9.7h; the built-in RSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME +# endif + +# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \ + pad, NULL) + +# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \ + EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) + +# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \ + len, NULL) + +# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \ + 0, plen) + +# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +# define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l) + +# define EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)l) + +# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +# define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +# define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 9) +# define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 10) + +# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 11) +# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +# define RSA_PKCS1_PADDING 1 +# define RSA_SSLV23_PADDING 2 +# define RSA_NO_PADDING 3 +# define RSA_PKCS1_OAEP_PADDING 4 +# define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +# define RSA_PKCS1_PSS_PADDING 6 + +# define RSA_PKCS1_PADDING_SIZE 11 + +# define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +# define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_size(const RSA *rsa); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +RSA *RSA_generate_key(int bits, unsigned long e, void + (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); + +int RSA_check_key(const RSA *); + /* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* This function needs the memory locking malloc callbacks to be installed */ +int RSA_memory_lock(RSA *r); + +/* these are the actual SSLeay RSA functions */ +const RSA_METHOD *RSA_PKCS1_SSLeay(void); + +const RSA_METHOD *RSA_null_method(void); + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) + +typedef struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; +} RSA_PSS_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +typedef struct rsa_oaep_params_st { + X509_ALGOR *hashFunc; + X509_ALGOR *maskGenFunc; + X509_ALGOR *pSourceFunc; +} RSA_OAEP_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) + +# ifndef OPENSSL_NO_FP_API +int RSA_print_fp(FILE *fp, const RSA *r, int offset); +# endif + +# ifndef OPENSSL_NO_BIO +int RSA_print(BIO *bp, const RSA *r, int offset); +# endif + +# ifndef OPENSSL_NO_RC4 +int i2d_RSA_NET(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey); +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey); + +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify)); +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify)); +# endif + +/* + * The following 2 functions sign and verify a X509_SIG ASN1 object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* + * The following 2 function sign and verify a ASN1_OCTET_STRING object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md); +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md); +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_X931_hash_id(int nid); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, + int sLen); + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen); + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* + * If this flag is set the RSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define RSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* + * Application has decided PRNG is good enough to generate a key: don't + * check. + */ +# define RSA_FLAG_CHECKED 0x0800 + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RSA_strings(void); + +/* Error codes for the RSA functions. */ + +/* Function codes. */ +# define RSA_F_CHECK_PADDING_MD 140 +# define RSA_F_DO_RSA_PRINT 146 +# define RSA_F_INT_RSA_VERIFY 145 +# define RSA_F_MEMORY_LOCK 100 +# define RSA_F_OLD_RSA_PRIV_DECODE 147 +# define RSA_F_PKEY_RSA_CTRL 143 +# define RSA_F_PKEY_RSA_CTRL_STR 144 +# define RSA_F_PKEY_RSA_SIGN 142 +# define RSA_F_PKEY_RSA_VERIFY 154 +# define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +# define RSA_F_RSA_ALGOR_TO_MD 157 +# define RSA_F_RSA_BUILTIN_KEYGEN 129 +# define RSA_F_RSA_CHECK_KEY 123 +# define RSA_F_RSA_CMS_DECRYPT 158 +# define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 +# define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102 +# define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103 +# define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104 +# define RSA_F_RSA_GENERATE_KEY 105 +# define RSA_F_RSA_GENERATE_KEY_EX 155 +# define RSA_F_RSA_ITEM_VERIFY 156 +# define RSA_F_RSA_MEMORY_LOCK 130 +# define RSA_F_RSA_MGF1_TO_MD 159 +# define RSA_F_RSA_NEW_METHOD 106 +# define RSA_F_RSA_NULL 124 +# define RSA_F_RSA_NULL_MOD_EXP 131 +# define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +# define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +# define RSA_F_RSA_PADDING_ADD_NONE 107 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1 160 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +# define RSA_F_RSA_PADDING_ADD_SSLV23 110 +# define RSA_F_RSA_PADDING_ADD_X931 127 +# define RSA_F_RSA_PADDING_CHECK_NONE 111 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1 161 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +# define RSA_F_RSA_PADDING_CHECK_SSLV23 114 +# define RSA_F_RSA_PADDING_CHECK_X931 128 +# define RSA_F_RSA_PRINT 115 +# define RSA_F_RSA_PRINT_FP 116 +# define RSA_F_RSA_PRIVATE_DECRYPT 150 +# define RSA_F_RSA_PRIVATE_ENCRYPT 151 +# define RSA_F_RSA_PRIV_DECODE 137 +# define RSA_F_RSA_PRIV_ENCODE 138 +# define RSA_F_RSA_PSS_TO_CTX 162 +# define RSA_F_RSA_PUBLIC_DECRYPT 152 +# define RSA_F_RSA_PUBLIC_ENCRYPT 153 +# define RSA_F_RSA_PUB_DECODE 139 +# define RSA_F_RSA_SETUP_BLINDING 136 +# define RSA_F_RSA_SIGN 117 +# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +# define RSA_F_RSA_VERIFY 119 +# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +# define RSA_F_RSA_VERIFY_PKCS1_PSS 126 +# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149 + +/* Reason codes. */ +# define RSA_R_ALGORITHM_MISMATCH 100 +# define RSA_R_BAD_E_VALUE 101 +# define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +# define RSA_R_BAD_PAD_BYTE_COUNT 103 +# define RSA_R_BAD_SIGNATURE 104 +# define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +# define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +# define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +# define RSA_R_DATA_TOO_LARGE 109 +# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +# define RSA_R_DATA_TOO_SMALL 111 +# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +# define RSA_R_DIGEST_DOES_NOT_MATCH 166 +# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +# define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +# define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +# define RSA_R_FIRST_OCTET_INVALID 133 +# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +# define RSA_R_INVALID_DIGEST 160 +# define RSA_R_INVALID_DIGEST_LENGTH 143 +# define RSA_R_INVALID_HEADER 137 +# define RSA_R_INVALID_KEYBITS 145 +# define RSA_R_INVALID_LABEL 161 +# define RSA_R_INVALID_MESSAGE_LENGTH 131 +# define RSA_R_INVALID_MGF1_MD 156 +# define RSA_R_INVALID_OAEP_PARAMETERS 162 +# define RSA_R_INVALID_PADDING 138 +# define RSA_R_INVALID_PADDING_MODE 141 +# define RSA_R_INVALID_PSS_PARAMETERS 149 +# define RSA_R_INVALID_PSS_SALTLEN 146 +# define RSA_R_INVALID_SALT_LENGTH 150 +# define RSA_R_INVALID_TRAILER 139 +# define RSA_R_INVALID_X931_DIGEST 142 +# define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +# define RSA_R_KEY_SIZE_TOO_SMALL 120 +# define RSA_R_LAST_OCTET_INVALID 134 +# define RSA_R_MODULUS_TOO_LARGE 105 +# define RSA_R_NON_FIPS_RSA_METHOD 157 +# define RSA_R_NO_PUBLIC_EXPONENT 140 +# define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +# define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +# define RSA_R_OAEP_DECODING_ERROR 121 +# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158 +# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +# define RSA_R_PADDING_CHECK_FAILED 114 +# define RSA_R_PKCS_DECODING_ERROR 159 +# define RSA_R_P_NOT_PRIME 128 +# define RSA_R_Q_NOT_PRIME 129 +# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +# define RSA_R_SLEN_CHECK_FAILED 136 +# define RSA_R_SLEN_RECOVERY_FAILED 135 +# define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +# define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +# define RSA_R_UNKNOWN_DIGEST 163 +# define RSA_R_UNKNOWN_MASK_DIGEST 151 +# define RSA_R_UNKNOWN_PADDING_TYPE 118 +# define RSA_R_UNKNOWN_PSS_DIGEST 152 +# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE 164 +# define RSA_R_UNSUPPORTED_LABEL_SOURCE 165 +# define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 +# define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 +# define RSA_R_VALUE_MISSING 147 +# define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/rsa_.c b/Sources/COpenSSL/rsa_.c new file mode 100644 index 00000000..36b08d90 --- /dev/null +++ b/Sources/COpenSSL/rsa_.c @@ -0,0 +1,6246 @@ +/* crypto/rsa/rsa_ameth.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "asn1t.h" +#include "x509.h" +#include "rsa.h" +#include "bn.h" +#ifndef OPENSSL_NO_CMS +# include "cms.h" +#endif +#include "asn1_locl.h" + +#ifndef OPENSSL_NO_CMS +static int rsa_cms_sign(CMS_SignerInfo *si); +static int rsa_cms_verify(CMS_SignerInfo *si); +static int rsa_cms_decrypt(CMS_RecipientInfo *ri); +static int rsa_cms_encrypt(CMS_RecipientInfo *ri); +#endif + +static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + unsigned char *penc = NULL; + int penclen; + penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); + if (penclen <= 0) + return 0; + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), + V_ASN1_NULL, NULL, penc, penclen)) + return 1; + + OPENSSL_free(penc); + return 0; +} + +static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p; + int pklen; + RSA *rsa = NULL; + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) + return 0; + if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) { + RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign_RSA(pkey, rsa); + return 1; +} + +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 + || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) + return 0; + return 1; +} + +static int old_rsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + RSA *rsa; + if (!(rsa = d2i_RSAPrivateKey(NULL, pder, derlen))) { + RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign_RSA(pkey, rsa); + return 1; +} + +static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); +} + +static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + unsigned char *rk = NULL; + int rklen; + rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); + + if (rklen <= 0) { + RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0, + V_ASN1_NULL, NULL, rk, rklen)) { + RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p; + int pklen; + if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) + return 0; + return old_rsa_priv_decode(pkey, &p, pklen); +} + +static int int_rsa_size(const EVP_PKEY *pkey) +{ + return RSA_size(pkey->pkey.rsa); +} + +static int rsa_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.rsa->n); +} + +static void int_rsa_free(EVP_PKEY *pkey) +{ + RSA_free(pkey->pkey.rsa); +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) +{ + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; +} + +static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv) +{ + char *str; + const char *s; + unsigned char *m = NULL; + int ret = 0, mod_len = 0; + size_t buf_len = 0; + + update_buflen(x->n, &buf_len); + update_buflen(x->e, &buf_len); + + if (priv) { + update_buflen(x->d, &buf_len); + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->dmp1, &buf_len); + update_buflen(x->dmq1, &buf_len); + update_buflen(x->iqmp, &buf_len); + } + + m = (unsigned char *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + RSAerr(RSA_F_DO_RSA_PRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (x->n != NULL) + mod_len = BN_num_bits(x->n); + + if (!BIO_indent(bp, off, 128)) + goto err; + + if (priv && x->d) { + if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) + <= 0) + goto err; + str = "modulus:"; + s = "publicExponent:"; + } else { + if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) + <= 0) + goto err; + str = "Modulus:"; + s = "Exponent:"; + } + if (!ASN1_bn_print(bp, str, x->n, m, off)) + goto err; + if (!ASN1_bn_print(bp, s, x->e, m, off)) + goto err; + if (priv) { + if (!ASN1_bn_print(bp, "privateExponent:", x->d, m, off)) + goto err; + if (!ASN1_bn_print(bp, "prime1:", x->p, m, off)) + goto err; + if (!ASN1_bn_print(bp, "prime2:", x->q, m, off)) + goto err; + if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, m, off)) + goto err; + if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, m, off)) + goto err; + if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, m, off)) + goto err; + } + ret = 1; + err: + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); +} + +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); +} + +/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */ +static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) +{ + const unsigned char *p; + int plen; + if (alg == NULL || alg->parameter == NULL) + return NULL; + if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) + return NULL; + if (alg->parameter->type != V_ASN1_SEQUENCE) + return NULL; + + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + return d2i_X509_ALGOR(NULL, &p, plen); +} + +static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg, + X509_ALGOR **pmaskHash) +{ + const unsigned char *p; + int plen; + RSA_PSS_PARAMS *pss; + + *pmaskHash = NULL; + + if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) + return NULL; + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); + + if (!pss) + return NULL; + + *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + + return pss; +} + +static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, + X509_ALGOR *maskHash, int indent) +{ + int rv = 0; + if (!pss) { + if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) + return 0; + return 1; + } + if (BIO_puts(bp, "\n") <= 0) + goto err; + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Hash Algorithm: ") <= 0) + goto err; + + if (pss->hashAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) + goto err; + } else if (BIO_puts(bp, "sha1 (default)") <= 0) + goto err; + + if (BIO_puts(bp, "\n") <= 0) + goto err; + + if (!BIO_indent(bp, indent, 128)) + goto err; + + if (BIO_puts(bp, "Mask Algorithm: ") <= 0) + goto err; + if (pss->maskGenAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) + goto err; + if (BIO_puts(bp, " with ") <= 0) + goto err; + if (maskHash) { + if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) + goto err; + } else if (BIO_puts(bp, "INVALID") <= 0) + goto err; + } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) + goto err; + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Salt Length: 0x") <= 0) + goto err; + if (pss->saltLength) { + if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) + goto err; + } else if (BIO_puts(bp, "14 (default)") <= 0) + goto err; + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Trailer Field: 0x") <= 0) + goto err; + if (pss->trailerField) { + if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) + goto err; + } else if (BIO_puts(bp, "BC (default)") <= 0) + goto err; + BIO_puts(bp, "\n"); + + rv = 1; + + err: + return rv; + +} + +static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) +{ + if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) { + int rv; + RSA_PSS_PARAMS *pss; + X509_ALGOR *maskHash; + pss = rsa_pss_decode(sigalg, &maskHash); + rv = rsa_pss_param_print(bp, pss, maskHash, indent); + if (pss) + RSA_PSS_PARAMS_free(pss); + if (maskHash) + X509_ALGOR_free(maskHash); + if (!rv) + return 0; + } else if (!sig && BIO_puts(bp, "\n") <= 0) + return 0; + if (sig) + return X509_signature_dump(bp, sig, indent); + return 1; +} + +static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + X509_ALGOR *alg = NULL; + switch (op) { + + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (arg1 == 0) + PKCS7_RECIP_INFO_get0_alg(arg2, &alg); + break; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + return rsa_cms_sign(arg2); + else if (arg1 == 1) + return rsa_cms_verify(arg2); + break; + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (arg1 == 0) + return rsa_cms_encrypt(arg2); + else if (arg1 == 1) + return rsa_cms_decrypt(arg2); + break; + + case ASN1_PKEY_CTRL_CMS_RI_TYPE: + *(int *)arg2 = CMS_RECIPINFO_TRANS; + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha256; + return 1; + + default: + return -2; + + } + + if (alg) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + + return 1; + +} + +/* allocate and set algorithm ID from EVP_MD, default SHA1 */ +static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) +{ + if (EVP_MD_type(md) == NID_sha1) + return 1; + *palg = X509_ALGOR_new(); + if (!*palg) + return 0; + X509_ALGOR_set_md(*palg, md); + return 1; +} + +/* Allocate and set MGF1 algorithm ID from EVP_MD */ +static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) +{ + X509_ALGOR *algtmp = NULL; + ASN1_STRING *stmp = NULL; + *palg = NULL; + if (EVP_MD_type(mgf1md) == NID_sha1) + return 1; + /* need to embed algorithm ID inside another */ + if (!rsa_md_to_algor(&algtmp, mgf1md)) + goto err; + if (!ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) + goto err; + *palg = X509_ALGOR_new(); + if (!*palg) + goto err; + X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); + stmp = NULL; + err: + if (stmp) + ASN1_STRING_free(stmp); + if (algtmp) + X509_ALGOR_free(algtmp); + if (*palg) + return 1; + return 0; +} + +/* convert algorithm ID to EVP_MD, default SHA1 */ +static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) +{ + const EVP_MD *md; + if (!alg) + return EVP_sha1(); + md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL) + RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST); + return md; +} + +/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */ +static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) +{ + const EVP_MD *md; + if (!alg) + return EVP_sha1(); + /* Check mask and lookup mask hash algorithm */ + if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) { + RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_ALGORITHM); + return NULL; + } + if (!maskHash) { + RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_PARAMETER); + return NULL; + } + md = EVP_get_digestbyobj(maskHash->algorithm); + if (md == NULL) { + RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNKNOWN_MASK_DIGEST); + return NULL; + } + return md; +} + +/* + * Convert EVP_PKEY_CTX is PSS mode into corresponding algorithm parameter, + * suitable for setting an AlgorithmIdentifier. + */ + +static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) +{ + const EVP_MD *sigmd, *mgf1md; + RSA_PSS_PARAMS *pss = NULL; + ASN1_STRING *os = NULL; + EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); + int saltlen, rv = 0; + if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) + goto err; + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + goto err; + if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) + goto err; + if (saltlen == -1) + saltlen = EVP_MD_size(sigmd); + else if (saltlen == -2) { + saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; + if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) + saltlen--; + } + pss = RSA_PSS_PARAMS_new(); + if (!pss) + goto err; + if (saltlen != 20) { + pss->saltLength = ASN1_INTEGER_new(); + if (!pss->saltLength) + goto err; + if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) + goto err; + } + if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd)) + goto err; + if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) + goto err; + /* Finally create string with pss parameter encoding. */ + if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) + goto err; + rv = 1; + err: + if (pss) + RSA_PSS_PARAMS_free(pss); + if (rv) + return os; + if (os) + ASN1_STRING_free(os); + return NULL; +} + +/* + * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL + * then the EVP_MD_CTX is setup and initalised. If it is NULL parameters are + * passed to pkctx instead. + */ + +static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, + X509_ALGOR *sigalg, EVP_PKEY *pkey) +{ + int rv = -1; + int saltlen; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_PSS_PARAMS *pss; + X509_ALGOR *maskHash; + /* Sanity check: make sure it is PSS */ + if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { + RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + return -1; + } + /* Decode PSS parameters */ + pss = rsa_pss_decode(sigalg, &maskHash); + + if (pss == NULL) { + RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); + goto err; + } + mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); + if (!mgf1md) + goto err; + md = rsa_algor_to_md(pss->hashAlgorithm); + if (!md) + goto err; + + if (pss->saltLength) { + saltlen = ASN1_INTEGER_get(pss->saltLength); + + /* + * Could perform more salt length sanity checks but the main RSA + * routines will trap other invalid values anyway. + */ + if (saltlen < 0) { + RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH); + goto err; + } + } else + saltlen = 20; + + /* + * low-level routines support only trailer field 0xbc (value 1) and + * PKCS#1 says we should reject any other value anyway. + */ + if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { + RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER); + goto err; + } + + /* We have all parameters now set up context */ + + if (pkey) { + if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) + goto err; + } else { + const EVP_MD *checkmd; + if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) + goto err; + if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { + RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); + goto err; + } + } + + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) + goto err; + + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) + goto err; + /* Carry on */ + rv = 1; + + err: + RSA_PSS_PARAMS_free(pss); + if (maskHash) + X509_ALGOR_free(maskHash); + return rv; +} + +#ifndef OPENSSL_NO_CMS +static int rsa_cms_verify(CMS_SignerInfo *si) +{ + int nid, nid2; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + nid = OBJ_obj2nid(alg->algorithm); + if (nid == NID_rsaEncryption) + return 1; + if (nid == NID_rsassaPss) + return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); + /* Workaround for some implementation that use a signature OID */ + if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { + if (nid2 == NID_rsaEncryption) + return 1; + } + return 0; +} +#endif + +/* + * Customised RSA item verification routine. This is called when a signature + * is encountered requiring special handling. We currently only handle PSS. + */ + +static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, + EVP_PKEY *pkey) +{ + /* Sanity check: make sure it is PSS */ + if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + return -1; + } + if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { + /* Carry on */ + return 2; + } + return -1; +} + +#ifndef OPENSSL_NO_CMS +static int rsa_cms_sign(CMS_SignerInfo *si) +{ + int pad_mode = RSA_PKCS1_PADDING; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); + ASN1_STRING *os = NULL; + CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); + if (pkctx) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* We don't support it */ + if (pad_mode != RSA_PKCS1_PSS_PADDING) + return 0; + os = rsa_ctx_to_pss(pkctx); + if (!os) + return 0; + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os); + return 1; +} +#endif + +static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, + ASN1_BIT_STRING *sig) +{ + int pad_mode; + EVP_PKEY_CTX *pkctx = ctx->pctx; + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + if (pad_mode == RSA_PKCS1_PADDING) + return 2; + if (pad_mode == RSA_PKCS1_PSS_PADDING) { + ASN1_STRING *os1 = NULL; + os1 = rsa_ctx_to_pss(pkctx); + if (!os1) + return 0; + /* Duplicate parameters if we have to */ + if (alg2) { + ASN1_STRING *os2 = ASN1_STRING_dup(os1); + if (!os2) { + ASN1_STRING_free(os1); + return 0; + } + X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), + V_ASN1_SEQUENCE, os2); + } + X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), + V_ASN1_SEQUENCE, os1); + return 3; + } + return 2; +} + +#ifndef OPENSSL_NO_CMS +static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, + X509_ALGOR **pmaskHash) +{ + const unsigned char *p; + int plen; + RSA_OAEP_PARAMS *pss; + + *pmaskHash = NULL; + + if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) + return NULL; + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + pss = d2i_RSA_OAEP_PARAMS(NULL, &p, plen); + + if (!pss) + return NULL; + + *pmaskHash = rsa_mgf1_decode(pss->maskGenFunc); + + return pss; +} + +static int rsa_cms_decrypt(CMS_RecipientInfo *ri) +{ + EVP_PKEY_CTX *pkctx; + X509_ALGOR *cmsalg; + int nid; + int rv = -1; + unsigned char *label = NULL; + int labellen = 0; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_OAEP_PARAMS *oaep; + X509_ALGOR *maskHash; + pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + if (!pkctx) + return 0; + if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) + return -1; + nid = OBJ_obj2nid(cmsalg->algorithm); + if (nid == NID_rsaEncryption) + return 1; + if (nid != NID_rsaesOaep) { + RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); + return -1; + } + /* Decode OAEP parameters */ + oaep = rsa_oaep_decode(cmsalg, &maskHash); + + if (oaep == NULL) { + RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS); + goto err; + } + + mgf1md = rsa_mgf1_to_md(oaep->maskGenFunc, maskHash); + if (!mgf1md) + goto err; + md = rsa_algor_to_md(oaep->hashFunc); + if (!md) + goto err; + + if (oaep->pSourceFunc) { + X509_ALGOR *plab = oaep->pSourceFunc; + if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { + RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE); + goto err; + } + if (plab->parameter->type != V_ASN1_OCTET_STRING) { + RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL); + goto err; + } + + label = plab->parameter->value.octet_string->data; + /* Stop label being freed when OAEP parameters are freed */ + plab->parameter->value.octet_string->data = NULL; + labellen = plab->parameter->value.octet_string->length; + } + + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) + goto err; + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) + goto err; + if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) + goto err; + /* Carry on */ + rv = 1; + + err: + RSA_OAEP_PARAMS_free(oaep); + if (maskHash) + X509_ALGOR_free(maskHash); + return rv; +} + +static int rsa_cms_encrypt(CMS_RecipientInfo *ri) +{ + const EVP_MD *md, *mgf1md; + RSA_OAEP_PARAMS *oaep = NULL; + ASN1_STRING *os = NULL; + X509_ALGOR *alg; + EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); + int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; + unsigned char *label; + CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg); + if (pkctx) { + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + } + if (pad_mode == RSA_PKCS1_PADDING) { + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + return 1; + } + /* Not supported */ + if (pad_mode != RSA_PKCS1_OAEP_PADDING) + return 0; + if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) + goto err; + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + goto err; + labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); + if (labellen < 0) + goto err; + oaep = RSA_OAEP_PARAMS_new(); + if (!oaep) + goto err; + if (!rsa_md_to_algor(&oaep->hashFunc, md)) + goto err; + if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) + goto err; + if (labellen > 0) { + ASN1_OCTET_STRING *los = ASN1_OCTET_STRING_new(); + oaep->pSourceFunc = X509_ALGOR_new(); + if (!oaep->pSourceFunc) + goto err; + if (!los) + goto err; + if (!ASN1_OCTET_STRING_set(los, label, labellen)) { + ASN1_OCTET_STRING_free(los); + goto err; + } + X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), + V_ASN1_OCTET_STRING, los); + } + /* create string with pss parameter encoding. */ + if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) + goto err; + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); + os = NULL; + rv = 1; + err: + if (oaep) + RSA_OAEP_PARAMS_free(oaep); + if (os) + ASN1_STRING_free(os); + return rv; +} +#endif + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { + { + EVP_PKEY_RSA, + EVP_PKEY_RSA, + ASN1_PKEY_SIGPARAM_NULL, + + "RSA", + "OpenSSL RSA method", + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + rsa_pub_print, + + rsa_priv_decode, + rsa_priv_encode, + rsa_priv_print, + + int_rsa_size, + rsa_bits, + + 0, 0, 0, 0, 0, 0, + + rsa_sig_print, + int_rsa_free, + rsa_pkey_ctrl, + old_rsa_priv_decode, + old_rsa_priv_encode, + rsa_item_verify, + rsa_item_sign}, + + { + EVP_PKEY_RSA2, + EVP_PKEY_RSA, + ASN1_PKEY_ALIAS} +}; +/* rsa_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "x509.h" +// #include "asn1t.h" + +/* Override the default free and new methods */ +static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)RSA_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + RSA_free((RSA *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = { + ASN1_SIMPLE(RSA, version, LONG), + ASN1_SIMPLE(RSA, n, BIGNUM), + ASN1_SIMPLE(RSA, e, BIGNUM), + ASN1_SIMPLE(RSA, d, BIGNUM), + ASN1_SIMPLE(RSA, p, BIGNUM), + ASN1_SIMPLE(RSA, q, BIGNUM), + ASN1_SIMPLE(RSA, dmp1, BIGNUM), + ASN1_SIMPLE(RSA, dmq1, BIGNUM), + ASN1_SIMPLE(RSA, iqmp, BIGNUM) +} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey) + + +ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = { + ASN1_SIMPLE(RSA, n, BIGNUM), + ASN1_SIMPLE(RSA, e, BIGNUM), +} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey) + +ASN1_SEQUENCE(RSA_PSS_PARAMS) = { + ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0), + ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1), + ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2), + ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3) +} ASN1_SEQUENCE_END(RSA_PSS_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +ASN1_SEQUENCE(RSA_OAEP_PARAMS) = { + ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0), + ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1), + ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2), +} ASN1_SEQUENCE_END(RSA_OAEP_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey) + +RSA *RSAPublicKey_dup(RSA *rsa) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); +} + +RSA *RSAPrivateKey_dup(RSA *rsa) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); +} +/* crypto/rsa/rsa_chk.c */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +// #include "bn.h" +#include "err.h" +// #include "rsa.h" + +int RSA_check_key(const RSA *key) +{ + BIGNUM *i, *j, *k, *l, *m; + BN_CTX *ctx; + int ret = 1; + + if (!key->p || !key->q || !key->n || !key->e || !key->d) { + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING); + return 0; + } + + i = BN_new(); + j = BN_new(); + k = BN_new(); + l = BN_new(); + m = BN_new(); + ctx = BN_CTX_new(); + if (i == NULL || j == NULL || k == NULL || l == NULL + || m == NULL || ctx == NULL) { + ret = -1; + RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BN_is_one(key->e)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_BAD_E_VALUE); + } + if (!BN_is_odd(key->e)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_BAD_E_VALUE); + } + + /* p prime? */ + if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL) != 1) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME); + } + + /* q prime? */ + if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL) != 1) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME); + } + + /* n = p*q? */ + if (!BN_mul(i, key->p, key->q, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(i, key->n) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q); + } + + /* d*e = 1 mod lcm(p-1,q-1)? */ + if (!BN_sub(i, key->p, BN_value_one())) { + ret = -1; + goto err; + } + if (!BN_sub(j, key->q, BN_value_one())) { + ret = -1; + goto err; + } + + /* now compute k = lcm(i,j) */ + if (!BN_mul(l, i, j, ctx)) { + ret = -1; + goto err; + } + if (!BN_gcd(m, i, j, ctx)) { + ret = -1; + goto err; + } + if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */ + ret = -1; + goto err; + } + if (!BN_mod_mul(i, key->d, key->e, k, ctx)) { + ret = -1; + goto err; + } + + if (!BN_is_one(i)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1); + } + + if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { + /* dmp1 = d mod (p-1)? */ + if (!BN_sub(i, key->p, BN_value_one())) { + ret = -1; + goto err; + } + if (!BN_mod(j, key->d, i, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(j, key->dmp1) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D); + } + + /* dmq1 = d mod (q-1)? */ + if (!BN_sub(i, key->q, BN_value_one())) { + ret = -1; + goto err; + } + if (!BN_mod(j, key->d, i, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(j, key->dmq1) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); + } + + /* iqmp = q^-1 mod p? */ + if (!BN_mod_inverse(i, key->q, key->p, ctx)) { + ret = -1; + goto err; + } + if (BN_cmp(i, key->iqmp) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q); + } + } + + err: + BN_free(i); + BN_free(j); + BN_free(k); + BN_free(l); + BN_free(m); + BN_CTX_free(ctx); + return ret; +} +/* crypto/rsa/rsa_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "crypto.h" +// #include "cryptlib.h" +#include "lhash.h" +// #include "bn.h" +// #include "rsa.h" +#include "rand.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +int RSA_size(const RSA *r) +{ + return (BN_num_bytes(r->n)); +} + +int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); + return -1; + } +#endif + return (rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding)); +} + +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); + return -1; + } +#endif + return (rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); +} + +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); + return -1; + } +#endif + return (rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding)); +} + +int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); + return -1; + } +#endif + return (rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); +} + +int RSA_flags(const RSA *r) +{ + return ((r == NULL) ? 0 : r->meth->flags); +} + +void RSA_blinding_off(RSA *rsa) +{ + if (rsa->blinding != NULL) { + BN_BLINDING_free(rsa->blinding); + rsa->blinding = NULL; + } + rsa->flags &= ~RSA_FLAG_BLINDING; + rsa->flags |= RSA_FLAG_NO_BLINDING; +} + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) +{ + int ret = 0; + + if (rsa->blinding != NULL) + RSA_blinding_off(rsa); + + rsa->blinding = RSA_setup_blinding(rsa, ctx); + if (rsa->blinding == NULL) + goto err; + + rsa->flags |= RSA_FLAG_BLINDING; + rsa->flags &= ~RSA_FLAG_NO_BLINDING; + ret = 1; + err: + return (ret); +} + +static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, + const BIGNUM *q, BN_CTX *ctx) +{ + BIGNUM *ret = NULL, *r0, *r1, *r2; + + if (d == NULL || p == NULL || q == NULL) + return NULL; + + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + if (r2 == NULL) + goto err; + + if (!BN_sub(r1, p, BN_value_one())) + goto err; + if (!BN_sub(r2, q, BN_value_one())) + goto err; + if (!BN_mul(r0, r1, r2, ctx)) + goto err; + + ret = BN_mod_inverse(NULL, d, r0, ctx); + err: + BN_CTX_end(ctx); + return ret; +} + +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) +{ + BIGNUM local_n; + BIGNUM *e, *n; + BN_CTX *ctx; + BN_BLINDING *ret = NULL; + + if (in_ctx == NULL) { + if ((ctx = BN_CTX_new()) == NULL) + return 0; + } else + ctx = in_ctx; + + BN_CTX_start(ctx); + e = BN_CTX_get(ctx); + if (e == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (rsa->e == NULL) { + e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); + if (e == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); + goto err; + } + } else + e = rsa->e; + + if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) { + /* + * if PRNG is not properly seeded, resort to secret exponent as + * unpredictable seed + */ + RAND_add(rsa->d->d, rsa->d->dmax * sizeof(rsa->d->d[0]), 0.0); + } + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + /* Set BN_FLG_CONSTTIME flag */ + n = &local_n; + BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); + } else + n = rsa->n; + + ret = BN_BLINDING_create_param(NULL, e, n, ctx, + rsa->meth->bn_mod_exp, rsa->_method_mod_n); + if (ret == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); + goto err; + } + CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); + err: + BN_CTX_end(ctx); + if (in_ctx == NULL) + BN_CTX_free(ctx); + if (rsa->e == NULL) + BN_free(e); + + return ret; +} +/* crypto/rsa/rsa_depr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NB: This file contains deprecated functions (compatibility wrappers to the + * "new" versions). + */ + +#include +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" + +#ifdef OPENSSL_NO_DEPRECATED + +static void *dummy = &dummy; + +#else + +RSA *RSA_generate_key(int bits, unsigned long e_value, + void (*callback) (int, int, void *), void *cb_arg) +{ + BN_GENCB cb; + int i; + RSA *rsa = RSA_new(); + BIGNUM *e = BN_new(); + + if (!rsa || !e) + goto err; + + /* + * The problem is when building with 8, 16, or 32 BN_ULONG, unsigned long + * can be larger + */ + for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) { + if (e_value & (1UL << i)) + if (BN_set_bit(e, i) == 0) + goto err; + } + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (RSA_generate_key_ex(rsa, bits, e, &cb)) { + BN_free(e); + return rsa; + } + err: + if (e) + BN_free(e); + if (rsa) + RSA_free(rsa); + return 0; +} +#endif +/* crypto/rsa/rsa_eay.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "rand.h" +#include "bn_int.h" + +#ifndef RSA_NULL + +static int RSA_eay_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_eay_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_eay_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_eay_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx); +static int RSA_eay_init(RSA *rsa); +static int RSA_eay_finish(RSA *rsa); +static RSA_METHOD rsa_pkcs1_eay_meth = { + "Eric Young's PKCS#1 RSA", + RSA_eay_public_encrypt, + RSA_eay_public_decrypt, /* signature verification */ + RSA_eay_private_encrypt, /* signing */ + RSA_eay_private_decrypt, + RSA_eay_mod_exp, + BN_mod_exp_mont, /* XXX probably we should not use Montgomery + * if e == 3 */ + RSA_eay_init, + RSA_eay_finish, + 0, /* flags */ + NULL, + 0, /* rsa_sign */ + 0, /* rsa_verify */ + NULL /* rsa_keygen */ +}; + +const RSA_METHOD *RSA_PKCS1_SSLeay(void) +{ + return (&rsa_pkcs1_eay_meth); +} + +static int RSA_eay_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int i, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); + break; +# ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); + break; +# endif + case RSA_SSLV23_PADDING: + i = RSA_padding_add_SSLv23(buf, num, from, flen); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) + goto err; + + if (BN_bin2bn(buf, num, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) + goto err; + + if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + + /* + * BN_bn2binpad puts in leading 0 bytes if the number is less than + * the length of the modulus. + */ + r = bn_bn2binpad(ret, to, num); + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) { + OPENSSL_cleanse(buf, num); + OPENSSL_free(buf); + } + return (r); +} + +static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) +{ + BN_BLINDING *ret; + int got_write_lock = 0; + CRYPTO_THREADID cur; + + CRYPTO_r_lock(CRYPTO_LOCK_RSA); + + if (rsa->blinding == NULL) { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + + if (rsa->blinding == NULL) + rsa->blinding = RSA_setup_blinding(rsa, ctx); + } + + ret = rsa->blinding; + if (ret == NULL) + goto err; + + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) { + /* rsa->blinding is ours! */ + + *local = 1; + } else { + /* resort to rsa->mt_blinding instead */ + + /* + * instructs rsa_blinding_convert(), rsa_blinding_invert() that the + * BN_BLINDING is shared, meaning that accesses require locks, and + * that the blinding factor must be stored outside the BN_BLINDING + */ + *local = 0; + + if (rsa->mt_blinding == NULL) { + if (!got_write_lock) { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + } + + if (rsa->mt_blinding == NULL) + rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); + } + ret = rsa->mt_blinding; + } + + err: + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RSA); + else + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + return ret; +} + +static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) +{ + if (unblind == NULL) + /* + * Local blinding: store the unblinding factor in BN_BLINDING. + */ + return BN_BLINDING_convert_ex(f, NULL, b, ctx); + else { + /* + * Shared blinding: store the unblinding factor outside BN_BLINDING. + */ + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); + ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); + return ret; + } +} + +static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) +{ + /* + * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex + * will use the unblinding factor stored in BN_BLINDING. If BN_BLINDING + * is shared between threads, unblind must be non-null: + * BN_BLINDING_invert_ex will then use the local unblinding factor, and + * will only read the modulus from BN_BLINDING. In both cases it's safe + * to access the blinding without a lock. + */ + return BN_BLINDING_invert_ex(f, unblind, b, ctx); +} + +/* signing */ +static int RSA_eay_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret, *res; + int i, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; + /* + * Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. + */ + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); + break; + case RSA_X931_PADDING: + i = RSA_padding_add_X931(buf, num, from, flen); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + case RSA_SSLV23_PADDING: + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) + goto err; + + if (BN_bin2bn(buf, num, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } + + if ((rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) + goto err; + } else { + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + BN_init(&local_d); + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) + goto err; + + if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } + + if (blinding) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + + if (padding == RSA_X931_PADDING) { + BN_sub(f, rsa->n, ret); + if (BN_cmp(ret, f) > 0) + res = f; + else + res = ret; + } else + res = ret; + + /* + * BN_bn2binpad puts in leading 0 bytes if the number is less than + * the length of the modulus. + */ + r = bn_bn2binpad(res, to, num); + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) { + OPENSSL_cleanse(buf, num); + OPENSSL_free(buf); + } + return (r); +} + +static int RSA_eay_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int j, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; + /* + * Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. + */ + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * This check was for equality but PGP does evil things and chops off the + * top '0' bytes + */ + if (flen > num) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, + RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + /* make data into a big number */ + if (BN_bin2bn(from, (int)flen, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } + + /* do the decrypt */ + if ((rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) + goto err; + } else { + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) + goto err; + if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } + + if (blinding) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + + j = bn_bn2binpad(ret, buf, num); + + switch (padding) { + case RSA_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); + break; +# ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); + break; +# endif + case RSA_SSLV23_PADDING: + r = RSA_padding_check_SSLv23(to, num, buf, j, num); + break; + case RSA_NO_PADDING: + memcpy(to, buf, (r = j)); + break; + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); + + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) { + OPENSSL_cleanse(buf, num); + OPENSSL_free(buf); + } + return (r); +} + +/* signature verification */ +static int RSA_eay_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int i, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * This check was for equality but PGP does evil things and chops off the + * top '0' bytes + */ + if (flen > num) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + if (BN_bin2bn(from, flen, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) + goto err; + + if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + + if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12)) + if (!BN_sub(ret, rsa->n, ret)) + goto err; + + i = bn_bn2binpad(ret, buf, num); + + switch (padding) { + case RSA_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num); + break; + case RSA_X931_PADDING: + r = RSA_padding_check_X931(to, num, buf, i, num); + break; + case RSA_NO_PADDING: + memcpy(to, buf, (r = i)); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED); + + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) { + OPENSSL_cleanse(buf, num); + OPENSSL_free(buf); + } + return (r); +} + +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) +{ + BIGNUM *r1, *m1, *vrfy; + BIGNUM local_dmp1, local_dmq1, local_c, local_r1; + BIGNUM *dmp1, *dmq1, *c, *pr1; + int ret = 0, smooth = 0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + vrfy = BN_CTX_get(ctx); + + { + BIGNUM local_p, local_q; + BIGNUM *p = NULL, *q = NULL; + + /* + * Make sure BN_mod_inverse in Montgomery intialization uses the + * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) + */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + BN_init(&local_p); + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + + BN_init(&local_q); + q = &local_q; + BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME); + } else { + p = rsa->p; + q = rsa->q; + } + + if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, + p, ctx)) + goto err; + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, + q, ctx)) + goto err; + + smooth = (rsa->meth->bn_mod_exp == BN_mod_exp_mont) + && (BN_num_bits(q) == BN_num_bits(p)); + } + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, + rsa->n, ctx)) + goto err; + + if (smooth) { + /* + * Conversion from Montgomery domain, a.k.a. Montgomery reduction, + * accepts values in [0-m*2^w) range. w is m's bit width rounded up + * to limb width. So that at the very least if |I| is fully reduced, + * i.e. less than p*q, we can count on from-to round to perform + * below modulo operations on |I|. Unlike BN_mod it's constant time. + */ + if (/* m1 = I moq q */ + !bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx) + || !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx) + /* m1 = m1^dmq1 mod q */ + || !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx, + rsa->_method_mod_q) + /* r1 = I mod p */ + || !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx) + || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) + /* r1 = r1^dmp1 mod p */ + || !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx, + rsa->_method_mod_p) + /* r1 = (r1 - m1) mod p */ + /* + * bn_mod_sub_fixed_top is not regular modular subtraction, + * it can tolerate subtrahend to be larger than modulus, but + * not bit-wise wider. This makes up for uncommon q>p case, + * when |m1| can be larger than |rsa->p|. + */ + || !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p) + + /* r1 = r1 * iqmp mod p */ + || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) + || !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p, + ctx) + /* r0 = r1 * q + m1 */ + || !bn_mul_fixed_top(r0, r1, rsa->q, ctx) + || !bn_mod_add_fixed_top(r0, r0, m1, rsa->n)) + goto err; + + goto tail; + } + + /* compute I mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1, c, rsa->q, ctx)) + goto err; + } else { + if (!BN_mod(r1, I, rsa->q, ctx)) + goto err; + } + + /* compute r1^dmq1 mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + dmq1 = &local_dmq1; + BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); + } else + dmq1 = rsa->dmq1; + if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) + goto err; + + /* compute I mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1, c, rsa->p, ctx)) + goto err; + } else { + if (!BN_mod(r1, I, rsa->p, ctx)) + goto err; + } + + /* compute r1^dmp1 mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + dmp1 = &local_dmp1; + BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); + } else + dmp1 = rsa->dmp1; + if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) + goto err; + + if (!BN_sub(r0, r0, m1)) + goto err; + /* + * This will help stop the size of r0 increasing, which does affect the + * multiply if it optimised for a power of 2 size + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + + if (!BN_mul(r1, r0, rsa->iqmp, ctx)) + goto err; + + /* Turn BN_FLG_CONSTTIME flag on before division operation */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + pr1 = &local_r1; + BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); + } else + pr1 = r1; + if (!BN_mod(r0, pr1, rsa->p, ctx)) + goto err; + + /* + * If p < q it is occasionally possible for the correction of adding 'p' + * if r0 is negative above to leave the result still negative. This can + * break the private key operations: the following second correction + * should *always* correct this rare occurrence. This will *never* happen + * with OpenSSL generated keys because they ensure p > q [steve] + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + if (!BN_mul(r1, r0, rsa->q, ctx)) + goto err; + if (!BN_add(r0, r1, m1)) + goto err; + + tail: + if (rsa->e && rsa->n) { + if (rsa->meth->bn_mod_exp == BN_mod_exp_mont) { + if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } else { + bn_correct_top(r0); + if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } + /* + * If 'I' was greater than (or equal to) rsa->n, the operation will + * be equivalent to using 'I mod n'. However, the result of the + * verify will *always* be less than 'n' so we don't check for + * absolute equality, just congruency. + */ + if (!BN_sub(vrfy, vrfy, I)) + goto err; + if (BN_is_zero(vrfy)) { + bn_correct_top(r0); + ret = 1; + goto err; /* not actually error */ + } + if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) + goto err; + if (BN_is_negative(vrfy)) + if (!BN_add(vrfy, vrfy, rsa->n)) + goto err; + if (!BN_is_zero(vrfy)) { + /* + * 'I' and 'vrfy' aren't congruent mod n. Don't leak + * miscalculated CRT output, just do a raw (slower) mod_exp and + * return that instead. + */ + + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } + } + /* + * It's unfortunate that we have to bn_correct_top(r0). What hopefully + * saves the day is that correction is highly unlike, and private key + * operations are customarily performed on blinded message. Which means + * that attacker won't observe correlation with chosen plaintext. + * Secondly, remaining code would still handle it in same computational + * time and even conceal memory access pattern around corrected top. + */ + bn_correct_top(r0); + ret = 1; + err: + BN_CTX_end(ctx); + return (ret); +} + +static int RSA_eay_init(RSA *rsa) +{ + rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE; + return (1); +} + +static int RSA_eay_finish(RSA *rsa) +{ + if (rsa->_method_mod_n != NULL) + BN_MONT_CTX_free(rsa->_method_mod_n); + if (rsa->_method_mod_p != NULL) + BN_MONT_CTX_free(rsa->_method_mod_p); + if (rsa->_method_mod_q != NULL) + BN_MONT_CTX_free(rsa->_method_mod_q); + return (1); +} + +#endif +/* crypto/rsa/rsa_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +// #include "err.h" +// #include "rsa.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason) + +static ERR_STRING_DATA RSA_str_functs[] = { + {ERR_FUNC(RSA_F_CHECK_PADDING_MD), "CHECK_PADDING_MD"}, + {ERR_FUNC(RSA_F_DO_RSA_PRINT), "DO_RSA_PRINT"}, + {ERR_FUNC(RSA_F_INT_RSA_VERIFY), "INT_RSA_VERIFY"}, + {ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"}, + {ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "OLD_RSA_PRIV_DECODE"}, + {ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"}, + {ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"}, + {ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"}, + {ERR_FUNC(RSA_F_PKEY_RSA_VERIFY), "PKEY_RSA_VERIFY"}, + {ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"}, + {ERR_FUNC(RSA_F_RSA_ALGOR_TO_MD), "RSA_ALGOR_TO_MD"}, + {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, + {ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"}, + {ERR_FUNC(RSA_F_RSA_CMS_DECRYPT), "RSA_CMS_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"}, + {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"}, + {ERR_FUNC(RSA_F_RSA_GENERATE_KEY), "RSA_generate_key"}, + {ERR_FUNC(RSA_F_RSA_GENERATE_KEY_EX), "RSA_generate_key_ex"}, + {ERR_FUNC(RSA_F_RSA_ITEM_VERIFY), "RSA_ITEM_VERIFY"}, + {ERR_FUNC(RSA_F_RSA_MEMORY_LOCK), "RSA_memory_lock"}, + {ERR_FUNC(RSA_F_RSA_MGF1_TO_MD), "RSA_MGF1_TO_MD"}, + {ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"}, + {ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"}, + {ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP), "RSA_NULL_MOD_EXP"}, + {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_NULL_PRIVATE_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_NULL_PRIVATE_ENCRYPT"}, + {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_NULL_PUBLIC_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_NULL_PUBLIC_ENCRYPT"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP), + "RSA_padding_add_PKCS1_OAEP"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1), + "RSA_padding_add_PKCS1_OAEP_mgf1"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1), + "RSA_padding_add_PKCS1_PSS_mgf1"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1), + "RSA_padding_add_PKCS1_type_1"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2), + "RSA_padding_add_PKCS1_type_2"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE), "RSA_padding_check_none"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP), + "RSA_padding_check_PKCS1_OAEP"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1), + "RSA_padding_check_PKCS1_OAEP_mgf1"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1), + "RSA_padding_check_PKCS1_type_1"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2), + "RSA_padding_check_PKCS1_type_2"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"}, + {ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"}, + {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"}, + {ERR_FUNC(RSA_F_RSA_PRIVATE_DECRYPT), "RSA_private_decrypt"}, + {ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"}, + {ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"}, + {ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"}, + {ERR_FUNC(RSA_F_RSA_PSS_TO_CTX), "RSA_PSS_TO_CTX"}, + {ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"}, + {ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"}, + {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"}, + {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, + {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, + {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), + "RSA_sign_ASN1_OCTET_STRING"}, + {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, + {ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING), + "RSA_verify_ASN1_OCTET_STRING"}, + {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_verify_PKCS1_PSS"}, + {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1), "RSA_verify_PKCS1_PSS_mgf1"}, + {0, NULL} +}; + +static ERR_STRING_DATA RSA_str_reasons[] = { + {ERR_REASON(RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"}, + {ERR_REASON(RSA_R_BAD_E_VALUE), "bad e value"}, + {ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT), "bad fixed header decrypt"}, + {ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count"}, + {ERR_REASON(RSA_R_BAD_SIGNATURE), "bad signature"}, + {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01), "block type is not 01"}, + {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02), "block type is not 02"}, + {ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN), + "data greater than mod len"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE), "data too large"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), + "data too large for key size"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS), + "data too large for modulus"}, + {ERR_REASON(RSA_R_DATA_TOO_SMALL), "data too small"}, + {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), + "data too small for key size"}, + {ERR_REASON(RSA_R_DIGEST_DOES_NOT_MATCH), "digest does not match"}, + {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), + "digest too big for rsa key"}, + {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"}, + {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D), "dmq1 not congruent to d"}, + {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1), "d e not congruent to 1"}, + {ERR_REASON(RSA_R_FIRST_OCTET_INVALID), "first octet invalid"}, + {ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), + "illegal or unsupported padding mode"}, + {ERR_REASON(RSA_R_INVALID_DIGEST), "invalid digest"}, + {ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, + {ERR_REASON(RSA_R_INVALID_HEADER), "invalid header"}, + {ERR_REASON(RSA_R_INVALID_KEYBITS), "invalid keybits"}, + {ERR_REASON(RSA_R_INVALID_LABEL), "invalid label"}, + {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"}, + {ERR_REASON(RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"}, + {ERR_REASON(RSA_R_INVALID_OAEP_PARAMETERS), "invalid oaep parameters"}, + {ERR_REASON(RSA_R_INVALID_PADDING), "invalid padding"}, + {ERR_REASON(RSA_R_INVALID_PADDING_MODE), "invalid padding mode"}, + {ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS), "invalid pss parameters"}, + {ERR_REASON(RSA_R_INVALID_PSS_SALTLEN), "invalid pss saltlen"}, + {ERR_REASON(RSA_R_INVALID_SALT_LENGTH), "invalid salt length"}, + {ERR_REASON(RSA_R_INVALID_TRAILER), "invalid trailer"}, + {ERR_REASON(RSA_R_INVALID_X931_DIGEST), "invalid x931 digest"}, + {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q), "iqmp not inverse of q"}, + {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL), "key size too small"}, + {ERR_REASON(RSA_R_LAST_OCTET_INVALID), "last octet invalid"}, + {ERR_REASON(RSA_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_REASON(RSA_R_NON_FIPS_RSA_METHOD), "non fips rsa method"}, + {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"}, + {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING), + "null before block missing"}, + {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q), "n does not equal p q"}, + {ERR_REASON(RSA_R_OAEP_DECODING_ERROR), "oaep decoding error"}, + {ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE), + "operation not allowed in fips mode"}, + {ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), + "operation not supported for this keytype"}, + {ERR_REASON(RSA_R_PADDING_CHECK_FAILED), "padding check failed"}, + {ERR_REASON(RSA_R_PKCS_DECODING_ERROR), "pkcs decoding error"}, + {ERR_REASON(RSA_R_P_NOT_PRIME), "p not prime"}, + {ERR_REASON(RSA_R_Q_NOT_PRIME), "q not prime"}, + {ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), + "rsa operations not supported"}, + {ERR_REASON(RSA_R_SLEN_CHECK_FAILED), "salt length check failed"}, + {ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED), "salt length recovery failed"}, + {ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK), "sslv3 rollback attack"}, + {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), + "the asn1 object identifier is not known for this md"}, + {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"}, + {ERR_REASON(RSA_R_UNKNOWN_DIGEST), "unknown digest"}, + {ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST), "unknown mask digest"}, + {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE), "unknown padding type"}, + {ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST), "unknown pss digest"}, + {ERR_REASON(RSA_R_UNSUPPORTED_ENCRYPTION_TYPE), + "unsupported encryption type"}, + {ERR_REASON(RSA_R_UNSUPPORTED_LABEL_SOURCE), "unsupported label source"}, + {ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM), + "unsupported mask algorithm"}, + {ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER), + "unsupported mask parameter"}, + {ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE), + "unsupported signature type"}, + {ERR_REASON(RSA_R_VALUE_MISSING), "value missing"}, + {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, + {0, NULL} +}; + +#endif + +void ERR_load_RSA_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) { + ERR_load_strings(0, RSA_str_functs); + ERR_load_strings(0, RSA_str_reasons); + } +#endif +} +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * NB: these functions have been "upgraded", the deprecated versions (which + * are compatibility wrappers using these functions) are in rsa_depr.c. - + * Geoff + */ + +#include +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +#ifdef OPENSSL_FIPS +# include +extern int FIPS_rsa_x931_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb); +#endif + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + BN_GENCB *cb); + +/* + * NB: this wrapper would normally be placed in rsa_lib.c and the static + * implementation would probably be in rsa_eay.c. Nonetheless, is kept here + * so that we don't introduce a new linker dependency. Eg. any application + * that wasn't previously linking object code related to key-generation won't + * have to now just because key-generation is part of RSA_METHOD. + */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD); + return 0; + } +#endif + if (rsa->meth->rsa_keygen) + return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_rsa_x931_generate_key_ex(rsa, bits, e_value, cb); +#endif + return rsa_builtin_keygen(rsa, bits, e_value, cb); +} + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + BN_GENCB *cb) +{ + BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; + BIGNUM local_r0, local_d, local_p; + BIGNUM *pr0, *d, *p; + int bitsp, bitsq, ok = -1, n = 0; + BN_CTX *ctx = NULL; + unsigned long error = 0; + + /* + * When generating ridiculously small keys, we can get stuck + * continually regenerating the same prime values. + */ + if (bits < 16) { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + if (r3 == NULL) + goto err; + + bitsp = (bits + 1) / 2; + bitsq = bits - bitsp; + + /* We need the RSA components non-NULL */ + if (!rsa->n && ((rsa->n = BN_new()) == NULL)) + goto err; + if (!rsa->d && ((rsa->d = BN_new()) == NULL)) + goto err; + if (!rsa->e && ((rsa->e = BN_new()) == NULL)) + goto err; + if (!rsa->p && ((rsa->p = BN_new()) == NULL)) + goto err; + if (!rsa->q && ((rsa->q = BN_new()) == NULL)) + goto err; + if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) + goto err; + if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) + goto err; + if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) + goto err; + + if (BN_copy(rsa->e, e_value) == NULL) + goto err; + + BN_set_flags(rsa->p, BN_FLG_CONSTTIME); + BN_set_flags(rsa->q, BN_FLG_CONSTTIME); + BN_set_flags(r2, BN_FLG_CONSTTIME); + /* generate p and q */ + for (;;) { + if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) + goto err; + if (!BN_sub(r2, rsa->p, BN_value_one())) + goto err; + ERR_set_mark(); + if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { + /* GCD == 1 since inverse exists */ + break; + } + error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_BN + && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { + /* GCD != 1 */ + ERR_pop_to_mark(); + } else { + goto err; + } + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + for (;;) { + do { + if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) + goto err; + } while (BN_cmp(rsa->p, rsa->q) == 0); + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; + ERR_set_mark(); + if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { + /* GCD == 1 since inverse exists */ + break; + } + error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) == ERR_LIB_BN + && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { + /* GCD != 1 */ + ERR_pop_to_mark(); + } else { + goto err; + } + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + if (BN_cmp(rsa->p, rsa->q) < 0) { + tmp = rsa->p; + rsa->p = rsa->q; + rsa->q = tmp; + } + + /* calculate n */ + if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) + goto err; + + /* calculate d */ + if (!BN_sub(r1, rsa->p, BN_value_one())) + goto err; /* p-1 */ + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; /* q-1 */ + if (!BN_mul(r0, r1, r2, ctx)) + goto err; /* (p-1)(q-1) */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + pr0 = &local_r0; + BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); + } else + pr0 = r0; + if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) + goto err; /* d */ + + /* set up d for correct BN_FLG_CONSTTIME flag */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + + /* calculate d mod (p-1) */ + if (!BN_mod(rsa->dmp1, d, r1, ctx)) + goto err; + + /* calculate d mod (q-1) */ + if (!BN_mod(rsa->dmq1, d, r2, ctx)) + goto err; + + /* calculate inverse of q mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + } else + p = rsa->p; + if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) + goto err; + + ok = 1; + err: + if (ok == -1) { + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); + ok = 0; + } + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return ok; +} +/* crypto/rsa/rsa_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "crypto.h" +// #include "cryptlib.h" +// #include "lhash.h" +// #include "bn.h" +// #include "rsa.h" +// #include "rand.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +#ifdef OPENSSL_FIPS +# include +#endif + +const char RSA_version[] = "RSA" OPENSSL_VERSION_PTEXT; + +static const RSA_METHOD *default_RSA_meth = NULL; + +RSA *RSA_new(void) +{ + RSA *r = RSA_new_method(NULL); + + return r; +} + +void RSA_set_default_method(const RSA_METHOD *meth) +{ + default_RSA_meth = meth; +} + +const RSA_METHOD *RSA_get_default_method(void) +{ + if (default_RSA_meth == NULL) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_rsa_pkcs1_ssleay(); + else + return RSA_PKCS1_SSLeay(); +#else +# ifdef RSA_NULL + default_RSA_meth = RSA_null_method(); +# else + default_RSA_meth = RSA_PKCS1_SSLeay(); +# endif +#endif + } + + return default_RSA_meth; +} + +const RSA_METHOD *RSA_get_method(const RSA *rsa) +{ + return rsa->meth; +} + +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const RSA_METHOD *mtmp; + mtmp = rsa->meth; + if (mtmp->finish) + mtmp->finish(rsa); +#ifndef OPENSSL_NO_ENGINE + if (rsa->engine) { + ENGINE_finish(rsa->engine); + rsa->engine = NULL; + } +#endif + rsa->meth = meth; + if (meth->init) + meth->init(rsa); + return 1; +} + +RSA *RSA_new_method(ENGINE *engine) +{ + RSA *ret; + + ret = (RSA *)OPENSSL_malloc(sizeof(RSA)); + if (ret == NULL) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ret,0,sizeof(RSA)); + + ret->meth = RSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine) { + if (!ENGINE_init(engine)) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; + } else + ret->engine = ENGINE_get_default_RSA(); + if (ret->engine) { + ret->meth = ENGINE_get_RSA(ret->engine); + if (!ret->meth) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->pad = 0; + ret->version = 0; + ret->n = NULL; + ret->e = NULL; + ret->d = NULL; + ret->p = NULL; + ret->q = NULL; + ret->dmp1 = NULL; + ret->dmq1 = NULL; + ret->iqmp = NULL; + ret->references = 1; + ret->_method_mod_n = NULL; + ret->_method_mod_p = NULL; + ret->_method_mod_q = NULL; + ret->blinding = NULL; + ret->mt_blinding = NULL; + ret->bignum_data = NULL; + ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + OPENSSL_free(ret); + return (NULL); + } + + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +void RSA_free(RSA *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_RSA); +#ifdef REF_PRINT + REF_PRINT("RSA", r); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "RSA_free, bad reference count\n"); + abort(); + } +#endif + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); + + if (r->n != NULL) + BN_clear_free(r->n); + if (r->e != NULL) + BN_clear_free(r->e); + if (r->d != NULL) + BN_clear_free(r->d); + if (r->p != NULL) + BN_clear_free(r->p); + if (r->q != NULL) + BN_clear_free(r->q); + if (r->dmp1 != NULL) + BN_clear_free(r->dmp1); + if (r->dmq1 != NULL) + BN_clear_free(r->dmq1); + if (r->iqmp != NULL) + BN_clear_free(r->iqmp); + if (r->blinding != NULL) + BN_BLINDING_free(r->blinding); + if (r->mt_blinding != NULL) + BN_BLINDING_free(r->mt_blinding); + if (r->bignum_data != NULL) + OPENSSL_free_locked(r->bignum_data); + OPENSSL_free(r); +} + +int RSA_up_ref(RSA *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); +#ifdef REF_PRINT + REF_PRINT("RSA", r); +#endif +#ifdef REF_CHECK + if (i < 2) { + fprintf(stderr, "RSA_up_ref, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); +} + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, + new_func, dup_func, free_func); +} + +int RSA_set_ex_data(RSA *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *RSA_get_ex_data(const RSA *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +int RSA_memory_lock(RSA *r) +{ + int i, j, k, off; + char *p; + BIGNUM *bn, **t[6], *b; + BN_ULONG *ul; + + if (r->d == NULL) + return (1); + t[0] = &r->d; + t[1] = &r->p; + t[2] = &r->q; + t[3] = &r->dmp1; + t[4] = &r->dmq1; + t[5] = &r->iqmp; + k = sizeof(BIGNUM) * 6; + off = k / sizeof(BN_ULONG) + 1; + j = 1; + for (i = 0; i < 6; i++) + j += (*t[i])->top; + if ((p = OPENSSL_malloc_locked((off + j) * sizeof(BN_ULONG))) == NULL) { + RSAerr(RSA_F_RSA_MEMORY_LOCK, ERR_R_MALLOC_FAILURE); + return (0); + } + bn = (BIGNUM *)p; + ul = (BN_ULONG *)&(p[off]); + for (i = 0; i < 6; i++) { + b = *(t[i]); + *(t[i]) = &(bn[i]); + memcpy((char *)&(bn[i]), (char *)b, sizeof(BIGNUM)); + bn[i].flags = BN_FLG_STATIC_DATA; + bn[i].d = ul; + memcpy((char *)ul, b->d, sizeof(BN_ULONG) * b->top); + ul += b->top; + BN_clear_free(b); + } + + /* I should fix this so it can still be done */ + r->flags &= ~(RSA_FLAG_CACHE_PRIVATE | RSA_FLAG_CACHE_PUBLIC); + + r->bignum_data = p; + return (1); +} +/* crypto/rsa/rsa_none.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "rand.h" + +int RSA_padding_add_none(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + if (flen > tlen) { + RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return (0); + } + + if (flen < tlen) { + RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); + return (0); + } + + memcpy(to, from, (unsigned int)flen); + return (1); +} + +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + + if (flen > tlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE); + return (-1); + } + + memset(to, 0, tlen - flen); + memcpy(to + tlen - flen, from, flen); + return (tlen); +} +/* rsa_null.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "rand.h" + +/* + * This is a dummy RSA implementation that just returns errors when called. + * It is designed to allow some RSA functions to work while stopping those + * covered by the RSA patent. That is RSA, encryption, decryption, signing + * and verify is not allowed but RSA key generation, key checking and other + * operations (like storing RSA keys) are permitted. + */ + +static int RSA_null_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_null_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_null_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_null_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +#if 0 /* not currently used */ +static int RSA_null_mod_exp(const BIGNUM *r0, const BIGNUM *i, RSA *rsa); +#endif +static int RSA_null_init(RSA *rsa); +static int RSA_null_finish(RSA *rsa); +static RSA_METHOD rsa_null_meth = { + "Null RSA", + RSA_null_public_encrypt, + RSA_null_public_decrypt, + RSA_null_private_encrypt, + RSA_null_private_decrypt, + NULL, + NULL, + RSA_null_init, + RSA_null_finish, + 0, + NULL, + NULL, + NULL, + NULL +}; + +const RSA_METHOD *RSA_null_method(void) +{ + return (&rsa_null_meth); +} + +static int RSA_null_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} + +static int RSA_null_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT, + RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} + +static int RSA_null_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT, + RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} + +static int RSA_null_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} + +#if 0 /* not currently used */ +static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) +{ + ... err(RSA_F_RSA_NULL_MOD_EXP, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} +#endif + +static int RSA_null_init(RSA *rsa) +{ + return (1); +} + +static int RSA_null_finish(RSA *rsa) +{ + return (1); +} +/* crypto/rsa/rsa_oaep.c */ +/* + * Written by Ulf Moeller. This software is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + */ + +/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ + +/* + * See Victor Shoup, "OAEP reconsidered," Nov. 2000, for problems with the security + * proof for the original OAEP scheme, which EME-OAEP is based on. A new + * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern, + * "RSA-OEAP is Still Alive!", Dec. 2000, . The new proof has stronger requirements + * for the underlying permutation: "partial-one-wayness" instead of + * one-wayness. For the RSA function, this is an equivalent notion. + */ + +#include "constant_time_locl.h" + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +# include +# include "cryptlib.h" +# include "bn.h" +# include "rsa.h" +# include "evp.h" +# include "rand.h" +# include "sha.h" + +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen) +{ + return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, + param, plen, NULL, NULL); +} + +int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen, + const EVP_MD *md, const EVP_MD *mgf1md) +{ + int i, emlen = tlen - 1; + unsigned char *db, *seed; + unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE]; + int mdlen; + + if (md == NULL) + md = EVP_sha1(); + if (mgf1md == NULL) + mgf1md = md; + + mdlen = EVP_MD_size(md); + + if (flen > emlen - 2 * mdlen - 1) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (emlen < 2 * mdlen + 1) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, + RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + to[0] = 0; + seed = to + 1; + db = to + mdlen + 1; + + if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) + return 0; + memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); + db[emlen - flen - mdlen - 1] = 0x01; + memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen); + if (RAND_bytes(seed, mdlen) <= 0) + return 0; +# ifdef PKCS_TESTVECT + memcpy(seed, + "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f", + 20); +# endif + + dbmask = OPENSSL_malloc(emlen - mdlen); + if (dbmask == NULL) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0) + goto err; + for (i = 0; i < emlen - mdlen; i++) + db[i] ^= dbmask[i]; + + if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0) + goto err; + for (i = 0; i < mdlen; i++) + seed[i] ^= seedmask[i]; + + OPENSSL_free(dbmask); + return 1; + + err: + OPENSSL_free(dbmask); + return 0; +} + +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num, + const unsigned char *param, int plen) +{ + return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num, + param, plen, NULL, NULL); +} + +int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num, const unsigned char *param, + int plen, const EVP_MD *md, + const EVP_MD *mgf1md) +{ + int i, dblen = 0, mlen = -1, one_index = 0, msg_index; + unsigned int good, found_one_byte; + const unsigned char *maskedseed, *maskeddb; + /* + * |em| is the encoded message, zero-padded to exactly |num| bytes: em = + * Y || maskedSeed || maskedDB + */ + unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE], + phash[EVP_MAX_MD_SIZE]; + int mdlen; + + if (md == NULL) + md = EVP_sha1(); + if (mgf1md == NULL) + mgf1md = md; + + mdlen = EVP_MD_size(md); + + if (tlen <= 0 || flen <= 0) + return -1; + /* + * |num| is the length of the modulus; |flen| is the length of the + * encoded message. Therefore, for any |from| that was obtained by + * decrypting a ciphertext, we must have |flen| <= |num|. Similarly, + * num < 2 * mdlen + 2 must hold for the modulus irrespective of + * the ciphertext, see PKCS #1 v2.2, section 7.1.2. + * This does not leak any side-channel information. + */ + if (num < flen || num < 2 * mdlen + 2) + goto decoding_err; + + dblen = num - mdlen - 1; + db = OPENSSL_malloc(dblen); + if (db == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); + goto cleanup; + } + + if (flen != num) { + em = OPENSSL_malloc(num); + if (em == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, + ERR_R_MALLOC_FAILURE); + goto cleanup; + } + + /* + * Caller is encouraged to pass zero-padded message created with + * BN_bn2binpad, but if it doesn't, we do this zero-padding copy + * to avoid leaking that information. The copy still leaks some + * side-channel information, but it's impossible to have a fixed + * memory access pattern since we can't read out of the bounds of + * |from|. + */ + memset(em, 0, num); + memcpy(em + num - flen, from, flen); + from = em; + } + + /* + * The first byte must be zero, however we must not leak if this is + * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA + * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001). + */ + good = constant_time_is_zero(from[0]); + + maskedseed = from + 1; + maskeddb = from + 1 + mdlen; + + if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) + goto cleanup; + for (i = 0; i < mdlen; i++) + seed[i] ^= maskedseed[i]; + + if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) + goto cleanup; + for (i = 0; i < dblen; i++) + db[i] ^= maskeddb[i]; + + if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) + goto cleanup; + + good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen)); + + found_one_byte = 0; + for (i = mdlen; i < dblen; i++) { + /* + * Padding consists of a number of 0-bytes, followed by a 1. + */ + unsigned int equals1 = constant_time_eq(db[i], 1); + unsigned int equals0 = constant_time_is_zero(db[i]); + one_index = constant_time_select_int(~found_one_byte & equals1, + i, one_index); + found_one_byte |= equals1; + good &= (found_one_byte | equals0); + } + + good &= found_one_byte; + + /* + * At this point |good| is zero unless the plaintext was valid, + * so plaintext-awareness ensures timing side-channels are no longer a + * concern. + */ + if (!good) + goto decoding_err; + + msg_index = one_index + 1; + mlen = dblen - msg_index; + + if (tlen < mlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE); + mlen = -1; + } else { + memcpy(to, db + msg_index, mlen); + goto cleanup; + } + + decoding_err: + /* + * To avoid chosen ciphertext attacks, the error message should not + * reveal which kind of decoding error happened. + */ + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, + RSA_R_OAEP_DECODING_ERROR); + cleanup: + if (db != NULL) { + OPENSSL_cleanse(db, dblen); + OPENSSL_free(db); + } + if (em != NULL) { + OPENSSL_cleanse(em, num); + OPENSSL_free(em); + } + return mlen; +} + +int PKCS1_MGF1(unsigned char *mask, long len, + const unsigned char *seed, long seedlen, const EVP_MD *dgst) +{ + long i, outlen = 0; + unsigned char cnt[4]; + EVP_MD_CTX c; + unsigned char md[EVP_MAX_MD_SIZE]; + int mdlen; + int rv = -1; + + EVP_MD_CTX_init(&c); + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + goto err; + for (i = 0; outlen < len; i++) { + cnt[0] = (unsigned char)((i >> 24) & 255); + cnt[1] = (unsigned char)((i >> 16) & 255); + cnt[2] = (unsigned char)((i >> 8)) & 255; + cnt[3] = (unsigned char)(i & 255); + if (!EVP_DigestInit_ex(&c, dgst, NULL) + || !EVP_DigestUpdate(&c, seed, seedlen) + || !EVP_DigestUpdate(&c, cnt, 4)) + goto err; + if (outlen + mdlen <= len) { + if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL)) + goto err; + outlen += mdlen; + } else { + if (!EVP_DigestFinal_ex(&c, md, NULL)) + goto err; + memcpy(mask + outlen, md, len - outlen); + outlen = len; + } + } + rv = 0; + err: + EVP_MD_CTX_cleanup(&c); + return rv; +} + +#endif +/* crypto/rsa/rsa_pk1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "constant_time_locl.h" + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "rand.h" + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int j; + unsigned char *p; + + if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return (0); + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 1; /* Private Key BT (Block Type) */ + + /* pad out with 0xff data */ + j = tlen - 3 - flen; + memset(p, 0xff, j); + p += j; + *(p++) = '\0'; + memcpy(p, from, (unsigned int)flen); + return (1); +} + +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num) +{ + int i, j; + const unsigned char *p; + + p = from; + + /* + * The format is + * 00 || 01 || PS || 00 || D + * PS - padding string, at least 8 bytes of FF + * D - data. + */ + + if (num < 11) + return -1; + + /* Accept inputs with and without the leading 0-byte. */ + if (num == flen) { + if ((*p++) != 0x00) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_INVALID_PADDING); + return -1; + } + flen--; + } + + if ((num != (flen + 1)) || (*(p++) != 01)) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BLOCK_TYPE_IS_NOT_01); + return (-1); + } + + /* scan over padding data */ + j = flen - 1; /* one for type. */ + for (i = 0; i < j; i++) { + if (*p != 0xff) { /* should decrypt to 0xff */ + if (*p == 0) { + p++; + break; + } else { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BAD_FIXED_HEADER_DECRYPT); + return (-1); + } + } + p++; + } + + if (i == j) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_NULL_BEFORE_BLOCK_MISSING); + return (-1); + } + + if (i < 8) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BAD_PAD_BYTE_COUNT); + return (-1); + } + i++; /* Skip over the '\0' */ + j -= i; + if (j > tlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE); + return (-1); + } + memcpy(to, p, (unsigned int)j); + + return (j); +} + +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int i, j; + unsigned char *p; + + if (flen > (tlen - 11)) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return (0); + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 2; /* Public Key BT (Block Type) */ + + /* pad out with non-zero random data */ + j = tlen - 3 - flen; + + if (RAND_bytes(p, j) <= 0) + return (0); + for (i = 0; i < j; i++) { + if (*p == '\0') + do { + if (RAND_bytes(p, 1) <= 0) + return (0); + } while (*p == '\0'); + p++; + } + + *(p++) = '\0'; + + memcpy(p, from, (unsigned int)flen); + return (1); +} + +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num) +{ + int i; + /* |em| is the encoded message, zero-padded to exactly |num| bytes */ + unsigned char *em = NULL; + unsigned int good, found_zero_byte; + int zero_index = 0, msg_index, mlen = -1; + + if (tlen < 0 || flen < 0) + return -1; + + /* + * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", + * section 7.2.2. + */ + + if (flen > num) + goto err; + + if (num < 11) + goto err; + + if (flen != num) { + em = OPENSSL_malloc(num); + if (em == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); + return -1; + } + /* + * Caller is encouraged to pass zero-padded message created with + * BN_bn2binpad, but if it doesn't, we do this zero-padding copy + * to avoid leaking that information. The copy still leaks some + * side-channel information, but it's impossible to have a fixed + * memory access pattern since we can't read out of the bounds of + * |from|. + */ + memset(em, 0, num); + memcpy(em + num - flen, from, flen); + from = em; + } + + good = constant_time_is_zero(from[0]); + good &= constant_time_eq(from[1], 2); + + found_zero_byte = 0; + for (i = 2; i < num; i++) { + unsigned int equals0 = constant_time_is_zero(from[i]); + zero_index = + constant_time_select_int(~found_zero_byte & equals0, i, + zero_index); + found_zero_byte |= equals0; + } + + /* + * PS must be at least 8 bytes long, and it starts two bytes into |from|. + * If we never found a 0-byte, then |zero_index| is 0 and the check + * also fails. + */ + good &= constant_time_ge((unsigned int)(zero_index), 2 + 8); + + /* + * Skip the zero byte. This is incorrect if we never found a zero-byte + * but in this case we also do not copy the message out. + */ + msg_index = zero_index + 1; + mlen = num - msg_index; + + /* + * For good measure, do this check in constant time as well; it could + * leak something if |tlen| was assuming valid padding. + */ + good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen)); + + /* + * We can't continue in constant-time because we need to copy the result + * and we cannot fake its length. This unavoidably leaks timing + * information at the API boundary. + */ + if (!good) { + mlen = -1; + goto err; + } + + memcpy(to, from + msg_index, mlen); + + err: + if (em != NULL) { + OPENSSL_cleanse(em, num); + OPENSSL_free(em); + } + if (mlen == -1) + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, + RSA_R_PKCS_DECODING_ERROR); + return mlen; +} +/* crypto/rsa/rsa_pmeth.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" +// #include "rsa.h" +// #include "bn.h" +#include "evp.h" +#include "x509v3.h" +#ifndef OPENSSL_NO_CMS +# include "cms.h" +#endif +#ifdef OPENSSL_FIPS +# include +#endif +#include "evp_locl.h" +#include "rsa_locl.h" + +/* RSA pkey context structure */ + +typedef struct { + /* Key gen parameters */ + int nbits; + BIGNUM *pub_exp; + /* Keygen callback info */ + int gentmp[2]; + /* RSA padding mode */ + int pad_mode; + /* message digest */ + const EVP_MD *md; + /* message digest for MGF1 */ + const EVP_MD *mgf1md; + /* PSS salt length */ + int saltlen; + /* Temp buffer */ + unsigned char *tbuf; + /* OAEP label */ + unsigned char *oaep_label; + size_t oaep_labellen; +} RSA_PKEY_CTX; + +static int pkey_rsa_init(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); + if (!rctx) + return 0; + rctx->nbits = 1024; + rctx->pub_exp = NULL; + rctx->pad_mode = RSA_PKCS1_PADDING; + rctx->md = NULL; + rctx->mgf1md = NULL; + rctx->tbuf = NULL; + + rctx->saltlen = -2; + + rctx->oaep_label = NULL; + rctx->oaep_labellen = 0; + + ctx->data = rctx; + ctx->keygen_info = rctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + RSA_PKEY_CTX *dctx, *sctx; + if (!pkey_rsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + if (sctx->pub_exp) { + dctx->pub_exp = BN_dup(sctx->pub_exp); + if (!dctx->pub_exp) + return 0; + } + dctx->pad_mode = sctx->pad_mode; + dctx->md = sctx->md; + dctx->mgf1md = sctx->mgf1md; + if (sctx->oaep_label) { + if (dctx->oaep_label) + OPENSSL_free(dctx->oaep_label); + dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen); + if (!dctx->oaep_label) + return 0; + dctx->oaep_labellen = sctx->oaep_labellen; + } + return 1; +} + +static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) +{ + if (ctx->tbuf) + return 1; + ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); + if (!ctx->tbuf) + return 0; + return 1; +} + +static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = ctx->data; + if (rctx) { + if (rctx->pub_exp) + BN_free(rctx->pub_exp); + if (rctx->tbuf) + OPENSSL_free(rctx->tbuf); + if (rctx->oaep_label) + OPENSSL_free(rctx->oaep_label); + OPENSSL_free(rctx); + } +} + +#ifdef OPENSSL_FIPS +/* + * FIP checker. Return value indicates status of context parameters: 1 : + * redirect to FIPS. 0 : don't redirect to FIPS. -1 : illegal operation in + * FIPS mode. + */ + +static int pkey_fips_check_rsa(const RSA *rsa, const EVP_MD **pmd, + const EVP_MD **pmgf1md) +{ + int rv = -1; + + if (!FIPS_mode()) + return 0; + if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + rv = 0; + if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) + return -1; + if (*pmd != NULL) { + *pmd = FIPS_get_digestbynid(EVP_MD_type(*pmd)); + if (*pmd == NULL || !((*pmd)->flags & EVP_MD_FLAG_FIPS)) + return rv; + } + if (*pmgf1md != NULL) { + *pmgf1md = FIPS_get_digestbynid(EVP_MD_type(*pmgf1md)); + if (*pmgf1md == NULL || !((*pmgf1md)->flags & EVP_MD_FLAG_FIPS)) + return rv; + } + return 1; +} +#endif + +static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbslen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const EVP_MD *md = rctx->md; + const EVP_MD *mgf1md = rctx->mgf1md; + +#ifdef OPENSSL_FIPS + ret = pkey_fips_check_rsa(rsa, &md, &mgf1md); + if (ret < 0) { + RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif + + if (md != NULL) { + if (tbslen != (size_t)EVP_MD_size(md)) { + RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); + return -1; + } +#ifdef OPENSSL_FIPS + if (ret > 0) { + unsigned int slen; + ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, md, rctx->pad_mode, + rctx->saltlen, mgf1md, sig, &slen); + if (ret > 0) + *siglen = slen; + else + *siglen = 0; + return ret; + } +#endif + + if (EVP_MD_type(md) == NID_mdc2) { + unsigned int sltmp; + if (rctx->pad_mode != RSA_PKCS1_PADDING) + return -1; + ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, + rsa); + + if (ret <= 0) + return ret; + ret = sltmp; + } else if (rctx->pad_mode == RSA_X931_PADDING) { + if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { + RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + if (!setup_tbuf(rctx, ctx)) { + RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE); + return -1; + } + memcpy(rctx->tbuf, tbs, tbslen); + rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(md)); + ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, + sig, rsa, RSA_X931_PADDING); + } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { + unsigned int sltmp; + ret = RSA_sign(EVP_MD_type(md), tbs, tbslen, sig, &sltmp, rsa); + if (ret <= 0) + return ret; + ret = sltmp; + } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { + if (!setup_tbuf(rctx, ctx)) + return -1; + if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, + md, mgf1md, rctx->saltlen)) + return -1; + ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, + sig, rsa, RSA_NO_PADDING); + } else + return -1; + } else + ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *siglen = ret; + return 1; +} + +static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx->md) { + if (rctx->pad_mode == RSA_X931_PADDING) { + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, + rctx->tbuf, ctx->pkey->pkey.rsa, + RSA_X931_PADDING); + if (ret < 1) + return 0; + ret--; + if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_type(rctx->md))) { + RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, + RSA_R_ALGORITHM_MISMATCH); + return 0; + } + if (ret != EVP_MD_size(rctx->md)) { + RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, + RSA_R_INVALID_DIGEST_LENGTH); + return 0; + } + if (rout) + memcpy(rout, rctx->tbuf, ret); + } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { + size_t sltmp; + ret = int_rsa_verify(EVP_MD_type(rctx->md), + NULL, 0, rout, &sltmp, + sig, siglen, ctx->pkey->pkey.rsa); + if (ret <= 0) + return 0; + ret = sltmp; + } else + return -1; + } else + ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *routlen = ret; + return 1; +} + +static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const EVP_MD *md = rctx->md; + const EVP_MD *mgf1md = rctx->mgf1md; + size_t rslen; + +#ifdef OPENSSL_FIPS + int rv = pkey_fips_check_rsa(rsa, &md, &mgf1md); + + if (rv < 0) { + RSAerr(RSA_F_PKEY_RSA_VERIFY, + RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif + if (md != NULL) { +#ifdef OPENSSL_FIPS + if (rv > 0) { + return FIPS_rsa_verify_digest(rsa, tbs, tbslen, md, rctx->pad_mode, + rctx->saltlen, mgf1md, sig, siglen); + + } +#endif + if (rctx->pad_mode == RSA_PKCS1_PADDING) + return RSA_verify(EVP_MD_type(md), tbs, tbslen, + sig, siglen, rsa); + if (tbslen != (size_t)EVP_MD_size(md)) { + RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); + return -1; + } + if (rctx->pad_mode == RSA_X931_PADDING) { + if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0) + return 0; + } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { + int ret; + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, RSA_NO_PADDING); + if (ret <= 0) + return 0; + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, md, mgf1md, + rctx->tbuf, rctx->saltlen); + if (ret <= 0) + return 0; + return 1; + } else + return -1; + } else { + if (!setup_tbuf(rctx, ctx)) + return -1; + rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, rctx->pad_mode); + if (rslen == 0) + return 0; + } + + if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) + return 0; + + return 1; + +} + +static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + int klen = RSA_size(ctx->pkey->pkey.rsa); + if (!setup_tbuf(rctx, ctx)) + return -1; + if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen, + in, inlen, + rctx->oaep_label, + rctx->oaep_labellen, + rctx->md, rctx->mgf1md)) + return -1; + ret = RSA_public_encrypt(klen, rctx->tbuf, out, + ctx->pkey->pkey.rsa, RSA_NO_PADDING); + } else + ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *outlen = ret; + return 1; +} + +static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_private_decrypt(inlen, in, rctx->tbuf, + ctx->pkey->pkey.rsa, RSA_NO_PADDING); + if (ret <= 0) + return ret; + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf, + ret, ret, + rctx->oaep_label, + rctx->oaep_labellen, + rctx->md, rctx->mgf1md); + } else + ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *outlen = ret; + return 1; +} + +static int check_padding_md(const EVP_MD *md, int padding) +{ + if (!md) + return 1; + + if (padding == RSA_NO_PADDING) { + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); + return 0; + } + + if (padding == RSA_X931_PADDING) { + if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) { + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); + return 0; + } + return 1; + } + + return 1; +} + +static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + RSA_PKEY_CTX *rctx = ctx->data; + switch (type) { + case EVP_PKEY_CTRL_RSA_PADDING: + if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { + if (!check_padding_md(rctx->md, p1)) + return 0; + if (p1 == RSA_PKCS1_PSS_PADDING) { + if (!(ctx->operation & + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + if (p1 == RSA_PKCS1_OAEP_PADDING) { + if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + } + bad_pad: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return -2; + + case EVP_PKEY_CTRL_GET_RSA_PADDING: + *(int *)p2 = rctx->pad_mode; + return 1; + + case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: + case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) + *(int *)p2 = rctx->saltlen; + else { + if (p1 < -2) + return -2; + rctx->saltlen = p1; + } + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < 256) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); + return -2; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE); + return -2; + } + BN_free(rctx->pub_exp); + rctx->pub_exp = p2; + return 1; + + case EVP_PKEY_CTRL_RSA_OAEP_MD: + case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) + *(const EVP_MD **)p2 = rctx->md; + else + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (!check_padding_md(p2, rctx->pad_mode)) + return 0; + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_GET_MD: + *(const EVP_MD **)p2 = rctx->md; + return 1; + + case EVP_PKEY_CTRL_RSA_MGF1_MD: + case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING + && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { + if (rctx->mgf1md) + *(const EVP_MD **)p2 = rctx->mgf1md; + else + *(const EVP_MD **)p2 = rctx->md; + } else + rctx->mgf1md = p2; + return 1; + + case EVP_PKEY_CTRL_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + return -2; + } + if (rctx->oaep_label) + OPENSSL_free(rctx->oaep_label); + if (p2 && p1 > 0) { + rctx->oaep_label = p2; + rctx->oaep_labellen = p1; + } else { + rctx->oaep_label = NULL; + rctx->oaep_labellen = 0; + } + return 1; + + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); + return -2; + } + *(unsigned char **)p2 = rctx->oaep_label; + return rctx->oaep_labellen; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + return 1; +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_ENCRYPT: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; +#endif + case EVP_PKEY_CTRL_PEER_KEY: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + + default: + return -2; + + } +} + +static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!value) { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); + return 0; + } + if (!strcmp(type, "rsa_padding_mode")) { + int pm; + if (!strcmp(value, "pkcs1")) + pm = RSA_PKCS1_PADDING; + else if (!strcmp(value, "sslv23")) + pm = RSA_SSLV23_PADDING; + else if (!strcmp(value, "none")) + pm = RSA_NO_PADDING; + else if (!strcmp(value, "oeap")) + pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "oaep")) + pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "x931")) + pm = RSA_X931_PADDING; + else if (!strcmp(value, "pss")) + pm = RSA_PKCS1_PSS_PADDING; + else { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); + return -2; + } + return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); + } + + if (!strcmp(type, "rsa_pss_saltlen")) { + int saltlen; + saltlen = atoi(value); + return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); + } + + if (!strcmp(type, "rsa_keygen_bits")) { + int nbits; + nbits = atoi(value); + return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); + } + + if (!strcmp(type, "rsa_keygen_pubexp")) { + int ret; + BIGNUM *pubexp = NULL; + if (!BN_asc2bn(&pubexp, value)) + return 0; + ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); + if (ret <= 0) + BN_free(pubexp); + return ret; + } + + if (!strcmp(type, "rsa_mgf1_md")) { + const EVP_MD *md; + if (!(md = EVP_get_digestbyname(value))) { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md); + } + + if (!strcmp(type, "rsa_oaep_md")) { + const EVP_MD *md; + if (!(md = EVP_get_digestbyname(value))) { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md); + } + if (!strcmp(type, "rsa_oaep_label")) { + unsigned char *lab; + long lablen; + int ret; + lab = string_to_hex(value, &lablen); + if (!lab) + return 0; + ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); + if (ret <= 0) + OPENSSL_free(lab); + return ret; + } + + return -2; +} + +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (!rctx->pub_exp) { + rctx->pub_exp = BN_new(); + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) + return 0; + } + rsa = RSA_new(); + if (!rsa) + return 0; + if (ctx->pkey_gencb) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else + pcb = NULL; + ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); + if (ret > 0) + EVP_PKEY_assign_RSA(pkey, rsa); + else + RSA_free(rsa); + return ret; +} + +const EVP_PKEY_METHOD rsa_pkey_meth = { + EVP_PKEY_RSA, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + + 0, 0, + + 0, + pkey_rsa_keygen, + + 0, + pkey_rsa_sign, + + 0, + pkey_rsa_verify, + + 0, + pkey_rsa_verifyrecover, + + 0, 0, 0, 0, + + 0, + pkey_rsa_encrypt, + + 0, + pkey_rsa_decrypt, + + 0, 0, + + pkey_rsa_ctrl, + pkey_rsa_ctrl_str +}; +/* crypto/rsa/rsa_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "rsa.h" +// #include "evp.h" + +#ifndef OPENSSL_NO_FP_API +int RSA_print_fp(FILE *fp, const RSA *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = RSA_print(b, x, off); + BIO_free(b); + return (ret); +} +#endif + +int RSA_print(BIO *bp, const RSA *x, int off) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; +} +/* rsa_pss.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "evp.h" +// #include "rand.h" +#include "sha.h" + +static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +#if defined(_MSC_VER) && defined(_ARM_) +# pragma optimize("g", off) +#endif + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen) +{ + return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen); +} + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen) +{ + int i; + int ret = 0; + int hLen, maskedDBLen, MSBits, emLen; + const unsigned char *H; + unsigned char *DB = NULL; + EVP_MD_CTX ctx; + unsigned char H_[EVP_MAX_MD_SIZE]; + EVP_MD_CTX_init(&ctx); + + if (mgf1Hash == NULL) + mgf1Hash = Hash; + + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; + /*- + * Negative sLen has special meanings: + * -1 sLen == hLen + * -2 salt length is autorecovered from signature + * -N reserved + */ + if (sLen == -1) + sLen = hLen; + else if (sLen == -2) + sLen = -2; + else if (sLen < -2) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (EM[0] & (0xFF << MSBits)) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID); + goto err; + } + if (MSBits == 0) { + EM++; + emLen--; + } + if (emLen < hLen + 2) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (sLen > emLen - hLen - 2) { /* sLen can be small negative */ + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (EM[emLen - 1] != 0xbc) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID); + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + DB = OPENSSL_malloc(maskedDBLen); + if (!DB) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE); + goto err; + } + if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) + goto err; + for (i = 0; i < maskedDBLen; i++) + DB[i] ^= EM[i]; + if (MSBits) + DB[0] &= 0xFF >> (8 - MSBits); + for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ; + if (DB[i++] != 0x1) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED); + goto err; + } + if (sLen >= 0 && (maskedDBLen - i) != sLen) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) + || !EVP_DigestUpdate(&ctx, zeroes, sizeof(zeroes)) + || !EVP_DigestUpdate(&ctx, mHash, hLen)) + goto err; + if (maskedDBLen - i) { + if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i)) + goto err; + } + if (!EVP_DigestFinal_ex(&ctx, H_, NULL)) + goto err; + if (memcmp(H_, H, hLen)) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE); + ret = 0; + } else + ret = 1; + + err: + if (DB) + OPENSSL_free(DB); + EVP_MD_CTX_cleanup(&ctx); + + return ret; + +} + +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, int sLen) +{ + return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen); +} + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen) +{ + int i; + int ret = 0; + int hLen, maskedDBLen, MSBits, emLen; + unsigned char *H, *salt = NULL, *p; + EVP_MD_CTX ctx; + + if (mgf1Hash == NULL) + mgf1Hash = Hash; + + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; + /*- + * Negative sLen has special meanings: + * -1 sLen == hLen + * -2 salt length is maximized + * -N reserved + */ + if (sLen == -1) + sLen = hLen; + else if (sLen == -2) + sLen = -2; + else if (sLen < -2) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (MSBits == 0) { + *EM++ = 0; + emLen--; + } + if (emLen < hLen + 2) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + if (sLen == -2) { + sLen = emLen - hLen - 2; + } else if (sLen > emLen - hLen - 2) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + if (sLen > 0) { + salt = OPENSSL_malloc(sLen); + if (!salt) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (RAND_bytes(salt, sLen) <= 0) + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) + || !EVP_DigestUpdate(&ctx, zeroes, sizeof(zeroes)) + || !EVP_DigestUpdate(&ctx, mHash, hLen)) + goto err; + if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, H, NULL)) + goto err; + EVP_MD_CTX_cleanup(&ctx); + + /* Generate dbMask in place then perform XOR on it */ + if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) + goto err; + + p = EM; + + /* + * Initial PS XORs with all zeroes which is a NOP so just update pointer. + * Note from a test above this value is guaranteed to be non-negative. + */ + p += emLen - sLen - hLen - 2; + *p++ ^= 0x1; + if (sLen > 0) { + for (i = 0; i < sLen; i++) + *p++ ^= salt[i]; + } + if (MSBits) + EM[0] &= 0xFF >> (8 - MSBits); + + /* H is already in place so just set final 0xbc */ + + EM[emLen - 1] = 0xbc; + + ret = 1; + + err: + if (salt) + OPENSSL_free(salt); + + return ret; + +} + +#if defined(_MSC_VER) +# pragma optimize("",on) +#endif +/* crypto/rsa/rsa_saos.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +#include "objects.h" +// #include "x509.h" + +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa) +{ + ASN1_OCTET_STRING sig; + int i, j, ret = 1; + unsigned char *p, *s; + + sig.type = V_ASN1_OCTET_STRING; + sig.length = m_len; + sig.data = (unsigned char *)m; + + i = i2d_ASN1_OCTET_STRING(&sig, NULL); + j = RSA_size(rsa); + if (i > (j - RSA_PKCS1_PADDING_SIZE)) { + RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, + RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return (0); + } + s = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1); + if (s == NULL) { + RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + return (0); + } + p = s; + i2d_ASN1_OCTET_STRING(&sig, &p); + i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); + if (i <= 0) + ret = 0; + else + *siglen = i; + + OPENSSL_cleanse(s, (unsigned int)j + 1); + OPENSSL_free(s); + return (ret); +} + +int RSA_verify_ASN1_OCTET_STRING(int dtype, + const unsigned char *m, + unsigned int m_len, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa) +{ + int i, ret = 0; + unsigned char *s; + const unsigned char *p; + ASN1_OCTET_STRING *sig = NULL; + + if (siglen != (unsigned int)RSA_size(rsa)) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, + RSA_R_WRONG_SIGNATURE_LENGTH); + return (0); + } + + s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen); + if (s == NULL) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + goto err; + } + i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); + + if (i <= 0) + goto err; + + p = s; + sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i); + if (sig == NULL) + goto err; + + if (((unsigned int)sig->length != m_len) || + (memcmp(m, sig->data, m_len) != 0)) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE); + } else + ret = 1; + err: + if (sig != NULL) + M_ASN1_OCTET_STRING_free(sig); + if (s != NULL) { + OPENSSL_cleanse(s, (unsigned int)siglen); + OPENSSL_free(s); + } + return (ret); +} +/* crypto/rsa/rsa_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "objects.h" +// #include "x509.h" +// #include "rsa_locl.h" + +/* Size of an SSL signature: MD5+SHA1 */ +#define SSL_SIG_LENGTH 36 + +int RSA_sign(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, RSA *rsa) +{ + X509_SIG sig; + ASN1_TYPE parameter; + int i, j, ret = 1; + unsigned char *p, *tmps = NULL; + const unsigned char *s = NULL; + X509_ALGOR algor; + ASN1_OCTET_STRING digest; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD); + return 0; + } +#endif + if ((rsa->meth->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) { + return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); + } + /* Special case: SSL signature, just check the length */ + if (type == NID_md5_sha1) { + if (m_len != SSL_SIG_LENGTH) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); + return (0); + } + i = SSL_SIG_LENGTH; + s = m; + } else { + sig.algor = &algor; + sig.algor->algorithm = OBJ_nid2obj(type); + if (sig.algor->algorithm == NULL) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return (0); + } + if (sig.algor->algorithm->length == 0) { + RSAerr(RSA_F_RSA_SIGN, + RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + return (0); + } + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + sig.algor->parameter = ¶meter; + + sig.digest = &digest; + sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */ + sig.digest->length = m_len; + + i = i2d_X509_SIG(&sig, NULL); + } + j = RSA_size(rsa); + if (i > (j - RSA_PKCS1_PADDING_SIZE)) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return (0); + } + if (type != NID_md5_sha1) { + tmps = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1); + if (tmps == NULL) { + RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE); + return (0); + } + p = tmps; + i2d_X509_SIG(&sig, &p); + s = tmps; + } + i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); + if (i <= 0) + ret = 0; + else + *siglen = i; + + if (type != NID_md5_sha1) { + OPENSSL_cleanse(tmps, (unsigned int)j + 1); + OPENSSL_free(tmps); + } + return (ret); +} + +/* + * Check DigestInfo structure does not contain extraneous data by reencoding + * using DER and checking encoding against original. + */ +static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, + int dinfolen) +{ + unsigned char *der = NULL; + int derlen; + int ret = 0; + derlen = i2d_X509_SIG(sig, &der); + if (derlen <= 0) + return 0; + if (derlen == dinfolen && !memcmp(dinfo, der, derlen)) + ret = 1; + OPENSSL_cleanse(der, derlen); + OPENSSL_free(der); + return ret; +} + +int int_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, + unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, RSA *rsa) +{ + int i, ret = 0, sigtype; + unsigned char *s; + X509_SIG *sig = NULL; + +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD); + return 0; + } +#endif + + if (siglen != (unsigned int)RSA_size(rsa)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); + return (0); + } + + if ((dtype == NID_md5_sha1) && rm) { + i = RSA_public_decrypt((int)siglen, + sigbuf, rm, rsa, RSA_PKCS1_PADDING); + if (i <= 0) + return 0; + *prm_len = i; + return 1; + } + + s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen); + if (s == NULL) { + RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); + goto err; + } + i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); + + if (i <= 0) + goto err; + /* + * Oddball MDC2 case: signature can be OCTET STRING. check for correct + * tag and length octets. + */ + if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) { + if (rm) { + memcpy(rm, s + 2, 16); + *prm_len = 16; + ret = 1; + } else if (memcmp(m, s + 2, 16)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + } else { + ret = 1; + } + } else if (dtype == NID_md5_sha1) { + /* Special case: SSL signature */ + if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + else + ret = 1; + } else { + const unsigned char *p = s; + sig = d2i_X509_SIG(NULL, &p, (long)i); + + if (sig == NULL) + goto err; + + /* Excess data can be used to create forgeries */ + if (p != s + i || !rsa_check_digestinfo(sig, s, i)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + goto err; + } + + /* + * Parameters to the signature algorithm can also be used to create + * forgeries + */ + if (sig->algor->parameter + && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + goto err; + } + + sigtype = OBJ_obj2nid(sig->algor->algorithm); + +#ifdef RSA_DEBUG + /* put a backward compatibility flag in EAY */ + fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype), + OBJ_nid2ln(dtype)); +#endif + if (sigtype != dtype) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); + goto err; + } + if (rm) { + const EVP_MD *md; + md = EVP_get_digestbynid(dtype); + if (md && (EVP_MD_size(md) != sig->digest->length)) + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); + else { + memcpy(rm, sig->digest->data, sig->digest->length); + *prm_len = sig->digest->length; + ret = 1; + } + } else if (((unsigned int)sig->digest->length != m_len) || + (memcmp(m, sig->digest->data, m_len) != 0)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + } else + ret = 1; + } + err: + if (sig != NULL) + X509_SIG_free(sig); + if (s != NULL) { + OPENSSL_cleanse(s, (unsigned int)siglen); + OPENSSL_free(s); + } + return (ret); +} + +int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) +{ + + if ((rsa->meth->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) { + return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa); + } + + return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); +} +/* crypto/rsa/rsa_ssl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "rand.h" + +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int i, j; + unsigned char *p; + + if (flen > (tlen - 11)) { + RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return (0); + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 2; /* Public Key BT (Block Type) */ + + /* pad out with non-zero random data */ + j = tlen - 3 - 8 - flen; + + if (RAND_bytes(p, j) <= 0) + return (0); + for (i = 0; i < j; i++) { + if (*p == '\0') + do { + if (RAND_bytes(p, 1) <= 0) + return (0); + } while (*p == '\0'); + p++; + } + + memset(p, 3, 8); + p += 8; + *(p++) = '\0'; + + memcpy(p, from, (unsigned int)flen); + return (1); +} + +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + int i, j, k; + const unsigned char *p; + + p = from; + if (flen < 10) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL); + return (-1); + } + /* Accept even zero-padded input */ + if (flen == num) { + if (*(p++) != 0) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02); + return -1; + } + flen--; + } + if ((num != (flen + 1)) || (*(p++) != 02)) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02); + return (-1); + } + + /* scan over padding data */ + j = flen - 1; /* one for type */ + for (i = 0; i < j; i++) + if (*(p++) == 0) + break; + + if ((i == j) || (i < 8)) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, + RSA_R_NULL_BEFORE_BLOCK_MISSING); + return (-1); + } + for (k = -9; k < -1; k++) { + if (p[k] != 0x03) + break; + } + if (k == -1) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_SSLV3_ROLLBACK_ATTACK); + return (-1); + } + + i++; /* Skip over the '\0' */ + j -= i; + if (j > tlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE); + return (-1); + } + memcpy(to, p, (unsigned int)j); + + return (j); +} +/* rsa_x931.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "rsa.h" +// #include "rand.h" +// #include "objects.h" + +int RSA_padding_add_X931(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int j; + unsigned char *p; + + /* + * Absolute minimum amount of padding is 1 header nibble, 1 padding + * nibble and 2 trailer bytes: but 1 hash if is already in 'from'. + */ + + j = tlen - flen - 2; + + if (j < 0) { + RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return -1; + } + + p = (unsigned char *)to; + + /* If no padding start and end nibbles are in one byte */ + if (j == 0) + *p++ = 0x6A; + else { + *p++ = 0x6B; + if (j > 1) { + memset(p, 0xBB, j - 1); + p += j - 1; + } + *p++ = 0xBA; + } + memcpy(p, from, (unsigned int)flen); + p += flen; + *p = 0xCC; + return (1); +} + +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + int i = 0, j; + const unsigned char *p; + + p = from; + if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER); + return -1; + } + + if (*p++ == 0x6B) { + j = flen - 3; + for (i = 0; i < j; i++) { + unsigned char c = *p++; + if (c == 0xBA) + break; + if (c != 0xBB) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); + return -1; + } + } + + j -= i; + + if (i == 0) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); + return -1; + } + + } else + j = flen - 2; + + if (p[j] != 0xCC) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER); + return -1; + } + + memcpy(to, p, (unsigned int)j); + + return (j); +} + +/* Translate between X931 hash ids and NIDs */ + +int RSA_X931_hash_id(int nid) +{ + switch (nid) { + case NID_sha1: + return 0x33; + + case NID_sha256: + return 0x34; + + case NID_sha384: + return 0x36; + + case NID_sha512: + return 0x35; + + } + return -1; +} diff --git a/Sources/COpenSSL/rsa_locl.h b/Sources/COpenSSL/rsa_locl.h new file mode 100644 index 00000000..3e88187d --- /dev/null +++ b/Sources/COpenSSL/rsa_locl.h @@ -0,0 +1,4 @@ +extern int int_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, unsigned char *rm, + size_t *prm_len, const unsigned char *sigbuf, + size_t siglen, RSA *rsa); diff --git a/Sources/COpenSSL/rsaz_exp.c b/Sources/COpenSSL/rsaz_exp.c new file mode 100644 index 00000000..c54c6feb --- /dev/null +++ b/Sources/COpenSSL/rsaz_exp.c @@ -0,0 +1,346 @@ +/***************************************************************************** +* * +* Copyright (c) 2012, Intel Corporation * +* * +* All rights reserved. * +* * +* Redistribution and use in source and binary forms, with or without * +* modification, are permitted provided that the following conditions are * +* met: * +* * +* * Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above copyright * +* notice, this list of conditions and the following disclaimer in the * +* documentation and/or other materials provided with the * +* distribution. * +* * +* * Neither the name of the Intel Corporation nor the names of its * +* contributors may be used to endorse or promote products derived from * +* this software without specific prior written permission. * +* * +* * +* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY * +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR * +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +* * +****************************************************************************** +* Developers and authors: * +* Shay Gueron (1, 2), and Vlad Krasnov (1) * +* (1) Intel Corporation, Israel Development Center, Haifa, Israel * +* (2) University of Haifa, Israel * +*****************************************************************************/ + +#include "rsaz_exp.h" + +#ifdef RSAZ_ENABLED + +/* + * See crypto/bn/asm/rsaz-avx2.pl for further details. + */ +void rsaz_1024_norm2red_avx2(void *red, const void *norm); +void rsaz_1024_mul_avx2(void *ret, const void *a, const void *b, + const void *n, BN_ULONG k); +void rsaz_1024_sqr_avx2(void *ret, const void *a, const void *n, BN_ULONG k, + int cnt); +void rsaz_1024_scatter5_avx2(void *tbl, const void *val, int i); +void rsaz_1024_gather5_avx2(void *val, const void *tbl, int i); +void rsaz_1024_red2norm_avx2(void *norm, const void *red); + +#if defined(__GNUC__) +# define ALIGN64 __attribute__((aligned(64))) +#elif defined(_MSC_VER) +# define ALIGN64 __declspec(align(64)) +#elif defined(__SUNPRO_C) +# define ALIGN64 +# pragma align 64(one,two80) +#else +/* not fatal, might hurt performance a little */ +# define ALIGN64 +#endif + +ALIGN64 static const BN_ULONG one[40] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +ALIGN64 static const BN_ULONG two80[40] = { + 0, 0, 1 << 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], + const BN_ULONG base_norm[16], + const BN_ULONG exponent[16], + const BN_ULONG m_norm[16], const BN_ULONG RR[16], + BN_ULONG k0) +{ + unsigned char storage[320 * 3 + 32 * 9 * 16 + 64]; /* 5.5KB */ + unsigned char *p_str = storage + (64 - ((size_t)storage % 64)); + unsigned char *a_inv, *m, *result; + unsigned char *table_s = p_str + 320 * 3; + unsigned char *R2 = table_s; /* borrow */ + int index; + int wvalue; + + if ((((size_t)p_str & 4095) + 320) >> 12) { + result = p_str; + a_inv = p_str + 320; + m = p_str + 320 * 2; /* should not cross page */ + } else { + m = p_str; /* should not cross page */ + result = p_str + 320; + a_inv = p_str + 320 * 2; + } + + rsaz_1024_norm2red_avx2(m, m_norm); + rsaz_1024_norm2red_avx2(a_inv, base_norm); + rsaz_1024_norm2red_avx2(R2, RR); + + rsaz_1024_mul_avx2(R2, R2, R2, m, k0); + rsaz_1024_mul_avx2(R2, R2, two80, m, k0); + + /* table[0] = 1 */ + rsaz_1024_mul_avx2(result, R2, one, m, k0); + /* table[1] = a_inv^1 */ + rsaz_1024_mul_avx2(a_inv, a_inv, R2, m, k0); + + rsaz_1024_scatter5_avx2(table_s, result, 0); + rsaz_1024_scatter5_avx2(table_s, a_inv, 1); + + /* table[2] = a_inv^2 */ + rsaz_1024_sqr_avx2(result, a_inv, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 2); +#if 0 + /* this is almost 2x smaller and less than 1% slower */ + for (index = 3; index < 32; index++) { + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, index); + } +#else + /* table[4] = a_inv^4 */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 4); + /* table[8] = a_inv^8 */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 8); + /* table[16] = a_inv^16 */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 16); + /* table[17] = a_inv^17 */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 17); + + /* table[3] */ + rsaz_1024_gather5_avx2(result, table_s, 2); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 3); + /* table[6] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 6); + /* table[12] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 12); + /* table[24] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 24); + /* table[25] */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 25); + + /* table[5] */ + rsaz_1024_gather5_avx2(result, table_s, 4); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 5); + /* table[10] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 10); + /* table[20] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 20); + /* table[21] */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 21); + + /* table[7] */ + rsaz_1024_gather5_avx2(result, table_s, 6); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 7); + /* table[14] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 14); + /* table[28] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 28); + /* table[29] */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 29); + + /* table[9] */ + rsaz_1024_gather5_avx2(result, table_s, 8); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 9); + /* table[18] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 18); + /* table[19] */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 19); + + /* table[11] */ + rsaz_1024_gather5_avx2(result, table_s, 10); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 11); + /* table[22] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 22); + /* table[23] */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 23); + + /* table[13] */ + rsaz_1024_gather5_avx2(result, table_s, 12); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 13); + /* table[26] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 26); + /* table[27] */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 27); + + /* table[15] */ + rsaz_1024_gather5_avx2(result, table_s, 14); + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 15); + /* table[30] */ + rsaz_1024_sqr_avx2(result, result, m, k0, 1); + rsaz_1024_scatter5_avx2(table_s, result, 30); + /* table[31] */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + rsaz_1024_scatter5_avx2(table_s, result, 31); +#endif + + /* load first window */ + p_str = (unsigned char *)exponent; + wvalue = p_str[127] >> 3; + rsaz_1024_gather5_avx2(result, table_s, wvalue); + + index = 1014; + + while (index > -1) { /* loop for the remaining 127 windows */ + + rsaz_1024_sqr_avx2(result, result, m, k0, 5); + + wvalue = *((unsigned short *)&p_str[index / 8]); + wvalue = (wvalue >> (index % 8)) & 31; + index -= 5; + + rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); /* borrow a_inv */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + } + + /* square four times */ + rsaz_1024_sqr_avx2(result, result, m, k0, 4); + + wvalue = p_str[0] & 15; + + rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); /* borrow a_inv */ + rsaz_1024_mul_avx2(result, result, a_inv, m, k0); + + /* from Montgomery */ + rsaz_1024_mul_avx2(result, result, one, m, k0); + + rsaz_1024_red2norm_avx2(result_norm, result); + + OPENSSL_cleanse(storage, sizeof(storage)); +} + +/* + * See crypto/bn/rsaz-x86_64.pl for further details. + */ +void rsaz_512_mul(void *ret, const void *a, const void *b, const void *n, + BN_ULONG k); +void rsaz_512_mul_scatter4(void *ret, const void *a, const void *n, + BN_ULONG k, const void *tbl, unsigned int power); +void rsaz_512_mul_gather4(void *ret, const void *a, const void *tbl, + const void *n, BN_ULONG k, unsigned int power); +void rsaz_512_mul_by_one(void *ret, const void *a, const void *n, BN_ULONG k); +void rsaz_512_sqr(void *ret, const void *a, const void *n, BN_ULONG k, + int cnt); +void rsaz_512_scatter4(void *tbl, const BN_ULONG *val, int power); +void rsaz_512_gather4(BN_ULONG *val, const void *tbl, int power); + +void RSAZ_512_mod_exp(BN_ULONG result[8], + const BN_ULONG base[8], const BN_ULONG exponent[8], + const BN_ULONG m[8], BN_ULONG k0, const BN_ULONG RR[8]) +{ + unsigned char storage[16 * 8 * 8 + 64 * 2 + 64]; /* 1.2KB */ + unsigned char *table = storage + (64 - ((size_t)storage % 64)); + BN_ULONG *a_inv = (BN_ULONG *)(table + 16 * 8 * 8); + BN_ULONG *temp = (BN_ULONG *)(table + 16 * 8 * 8 + 8 * 8); + unsigned char *p_str = (unsigned char *)exponent; + int index; + unsigned int wvalue; + + /* table[0] = 1_inv */ + temp[0] = 0 - m[0]; + temp[1] = ~m[1]; + temp[2] = ~m[2]; + temp[3] = ~m[3]; + temp[4] = ~m[4]; + temp[5] = ~m[5]; + temp[6] = ~m[6]; + temp[7] = ~m[7]; + rsaz_512_scatter4(table, temp, 0); + + /* table [1] = a_inv^1 */ + rsaz_512_mul(a_inv, base, RR, m, k0); + rsaz_512_scatter4(table, a_inv, 1); + + /* table [2] = a_inv^2 */ + rsaz_512_sqr(temp, a_inv, m, k0, 1); + rsaz_512_scatter4(table, temp, 2); + + for (index = 3; index < 16; index++) + rsaz_512_mul_scatter4(temp, a_inv, m, k0, table, index); + + /* load first window */ + wvalue = p_str[63]; + + rsaz_512_gather4(temp, table, wvalue >> 4); + rsaz_512_sqr(temp, temp, m, k0, 4); + rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue & 0xf); + + for (index = 62; index >= 0; index--) { + wvalue = p_str[index]; + + rsaz_512_sqr(temp, temp, m, k0, 4); + rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue >> 4); + + rsaz_512_sqr(temp, temp, m, k0, 4); + rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue & 0x0f); + } + + /* from Montgomery */ + rsaz_512_mul_by_one(result, temp, m, k0); + + OPENSSL_cleanse(storage, sizeof(storage)); +} + +#else + +# if defined(PEDANTIC) || defined(__DECC) || defined(__clang__) +static void *dummy = &dummy; +# endif + +#endif diff --git a/Sources/COpenSSL/rsaz_exp.h b/Sources/COpenSSL/rsaz_exp.h new file mode 100644 index 00000000..ab7ebaa2 --- /dev/null +++ b/Sources/COpenSSL/rsaz_exp.h @@ -0,0 +1,68 @@ +/***************************************************************************** +* * +* Copyright (c) 2012, Intel Corporation * +* * +* All rights reserved. * +* * +* Redistribution and use in source and binary forms, with or without * +* modification, are permitted provided that the following conditions are * +* met: * +* * +* * Redistributions of source code must retain the above copyright * +* notice, this list of conditions and the following disclaimer. * +* * +* * Redistributions in binary form must reproduce the above copyright * +* notice, this list of conditions and the following disclaimer in the * +* documentation and/or other materials provided with the * +* distribution. * +* * +* * Neither the name of the Intel Corporation nor the names of its * +* contributors may be used to endorse or promote products derived from * +* this software without specific prior written permission. * +* * +* * +* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY * +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR * +* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * +* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * +* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * +* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * +* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * +* * +****************************************************************************** +* Developers and authors: * +* Shay Gueron (1, 2), and Vlad Krasnov (1) * +* (1) Intel Corporation, Israel Development Center, Haifa, Israel * +* (2) University of Haifa, Israel * +*****************************************************************************/ + +#ifndef RSAZ_EXP_H +# define RSAZ_EXP_H + +# undef RSAZ_ENABLED +# if defined(OPENSSL_BN_ASM_MONT) && \ + (defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64)) +# define RSAZ_ENABLED + +# include "bn.h" + +void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16], + const BN_ULONG base_norm[16], + const BN_ULONG exponent[16], + const BN_ULONG m_norm[16], const BN_ULONG RR[16], + BN_ULONG k0); +int rsaz_avx2_eligible(); + +void RSAZ_512_mod_exp(BN_ULONG result[8], + const BN_ULONG base_norm[8], const BN_ULONG exponent[8], + const BN_ULONG m_norm[8], BN_ULONG k0, + const BN_ULONG RR[8]); + +# endif + +#endif diff --git a/Sources/COpenSSL/s23_.c b/Sources/COpenSSL/s23_.c new file mode 100644 index 00000000..79216a95 --- /dev/null +++ b/Sources/COpenSSL/s23_.c @@ -0,0 +1,1883 @@ +/* ssl/s23_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ssl_locl.h" +#include "buffer.h" +#include "rand.h" +#include "objects.h" +#include "evp.h" + +static const SSL_METHOD *ssl23_get_client_method(int ver); +static int ssl23_client_hello(SSL *s); +static int ssl23_get_server_hello(SSL *s); +static const SSL_METHOD *ssl23_get_client_method(int ver) +{ +#ifndef OPENSSL_NO_SSL2 + if (ver == SSL2_VERSION) + return (SSLv2_client_method()); +#endif +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_client_method()); +#endif + if (ver == TLS1_VERSION) + return (TLSv1_client_method()); + else if (ver == TLS1_1_VERSION) + return (TLSv1_1_client_method()); + else if (ver == TLS1_2_VERSION) + return (TLSv1_2_client_method()); + else + return (NULL); +} + +IMPLEMENT_ssl23_meth_func(SSLv23_client_method, + ssl_undefined_function, + ssl23_connect, ssl23_get_client_method) + +int ssl23_connect(SSL *s) +{ + BUF_MEM *buf = NULL; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state; + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE | SSL_ST_CONNECT: + case SSL_ST_OK | SSL_ST_CONNECT: + + if (s->session != NULL) { + SSLerr(SSL_F_SSL23_CONNECT, + SSL_R_SSL23_DOING_SESSION_ID_REUSE); + ret = -1; + goto end; + } + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + /* s->version=TLS1_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + ret = -1; + goto end; + } + s->init_buf = buf; + buf = NULL; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + + if (!ssl3_init_finished_mac(s)) { + ret = -1; + goto end; + } + + s->state = SSL23_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + break; + + case SSL23_ST_CW_CLNT_HELLO_A: + case SSL23_ST_CW_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl23_client_hello(s); + if (ret <= 0) + goto end; + s->state = SSL23_ST_CR_SRVR_HELLO_A; + s->init_num = 0; + + break; + + case SSL23_ST_CR_SRVR_HELLO_A: + case SSL23_ST_CR_SRVR_HELLO_B: + ret = ssl23_get_server_hello(s); + if (ret >= 0) + cb = NULL; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_SSL23_CONNECT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (s->debug) { + (void)BIO_flush(s->wbio); + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + end: + s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + return (ret); +} + +static int ssl23_no_ssl2_ciphers(SSL *s) +{ + SSL_CIPHER *cipher; + STACK_OF(SSL_CIPHER) *ciphers; + int i; + ciphers = SSL_get_ciphers(s); + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + cipher = sk_SSL_CIPHER_value(ciphers, i); + if (cipher->algorithm_ssl == SSL_SSLV2) + return 0; + } + return 1; +} + +/* + * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on + * failure, 1 on success. + */ +int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) +{ + int send_time = 0; + if (len < 4) + return 0; + if (server) + send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0; + else + send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0; + if (send_time) { + unsigned long Time = (unsigned long)time(NULL); + unsigned char *p = result; + l2n(Time, p); + return RAND_bytes(p, len - 4); + } else + return RAND_bytes(result, len); +} + +static int ssl23_client_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i, ch_len; + unsigned long l; + int ssl2_compat; + int version = 0, version_major, version_minor; + int al = 0; +#ifndef OPENSSL_NO_COMP + int j; + SSL_COMP *comp; +#endif + int ret; + unsigned long mask, options = s->options; + + ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1; + + if (ssl2_compat && ssl23_no_ssl2_ciphers(s)) + ssl2_compat = 0; + + /* + * SSL_OP_NO_X disables all protocols above X *if* there are + * some protocols below X enabled. This is required in order + * to maintain "version capability" vector contiguous. So + * that if application wants to disable TLS1.0 in favour of + * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the + * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. + */ + mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 +#if !defined(OPENSSL_NO_SSL3) + | SSL_OP_NO_SSLv3 +#endif +#if !defined(OPENSSL_NO_SSL2) + | (ssl2_compat ? SSL_OP_NO_SSLv2 : 0) +#endif + ; +#if !defined(OPENSSL_NO_TLS1_2_CLIENT) + version = TLS1_2_VERSION; + + if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) + version = TLS1_1_VERSION; +#else + version = TLS1_1_VERSION; +#endif + mask &= ~SSL_OP_NO_TLSv1_1; + if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) + version = TLS1_VERSION; + mask &= ~SSL_OP_NO_TLSv1; +#if !defined(OPENSSL_NO_SSL3) + if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) + version = SSL3_VERSION; + mask &= ~SSL_OP_NO_SSLv3; +#endif +#if !defined(OPENSSL_NO_SSL2) + if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask) + version = SSL2_VERSION; +#endif + +#ifndef OPENSSL_NO_TLSEXT + if (version != SSL2_VERSION) { + /* + * have to disable SSL 2.0 compatibility if we need TLS extensions + */ + + if (s->tlsext_hostname != NULL) + ssl2_compat = 0; + if (s->tlsext_status_type != -1) + ssl2_compat = 0; +# ifdef TLSEXT_TYPE_opaque_prf_input + if (s->ctx->tlsext_opaque_prf_input_callback != 0 + || s->tlsext_opaque_prf_input != NULL) + ssl2_compat = 0; +# endif + if (s->cert->cli_ext.meths_count != 0) + ssl2_compat = 0; + } +#endif + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { + /* + * Since we're sending s23 client hello, we're not reusing a session, as + * we'd be using the method from the saved session instead + */ + if (!ssl_get_new_session(s, 0)) { + return -1; + } + + p = s->s3->client_random; + if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) + return -1; + + if (version == TLS1_2_VERSION) { + version_major = TLS1_2_VERSION_MAJOR; + version_minor = TLS1_2_VERSION_MINOR; + } else if (tls1_suiteb(s)) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, + SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); + return -1; + } else if (version == TLS1_1_VERSION) { + version_major = TLS1_1_VERSION_MAJOR; + version_minor = TLS1_1_VERSION_MINOR; + } else if (version == TLS1_VERSION) { + version_major = TLS1_VERSION_MAJOR; + version_minor = TLS1_VERSION_MINOR; + } +#ifdef OPENSSL_FIPS + else if (FIPS_mode()) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif + else if (version == SSL3_VERSION) { + version_major = SSL3_VERSION_MAJOR; + version_minor = SSL3_VERSION_MINOR; + } else if (version == SSL2_VERSION) { + version_major = SSL2_VERSION_MAJOR; + version_minor = SSL2_VERSION_MINOR; + } else { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_PROTOCOLS_AVAILABLE); + return (-1); + } + + s->client_version = version; + + if (ssl2_compat) { + /* create SSL 2.0 compatible Client Hello */ + + /* two byte record header will be written last */ + d = &(buf[2]); + p = d + 9; /* leave space for message type, version, + * individual length fields */ + + *(d++) = SSL2_MT_CLIENT_HELLO; + *(d++) = version_major; + *(d++) = version_minor; + + /* Ciphers supported */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), p, 0); + if (i == 0) { + /* no ciphers */ + SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + return -1; + } + s2n(i, d); + p += i; + + /* + * put in the session-id length (zero since there is no reuse) + */ + s2n(0, d); + + if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) + ch_len = SSL2_CHALLENGE_LENGTH; + else + ch_len = SSL2_MAX_CHALLENGE_LENGTH; + + /* write out sslv2 challenge */ + /* + * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it + * is one of SSL2_MAX_CHALLENGE_LENGTH (32) or + * SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for + * futurproofing + */ + if (SSL3_RANDOM_SIZE < ch_len) + i = SSL3_RANDOM_SIZE; + else + i = ch_len; + s2n(i, d); + memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE); + if (RAND_bytes (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) + <= 0) + return -1; + + memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); + p += i; + + i = p - &(buf[2]); + buf[0] = ((i >> 8) & 0xff) | 0x80; + buf[1] = (i & 0xff); + + /* number of bytes to write */ + s->init_num = i + 2; + s->init_off = 0; + + ssl3_finish_mac(s, &(buf[2]), i); + } else { + /* create Client Hello in SSL 3.0/TLS 1.0 format */ + + /* + * do the record header (5 bytes) and handshake message header (4 + * bytes) last + */ + d = p = &(buf[9]); + + *(p++) = version_major; + *(p++) = version_minor; + + /* Random stuff */ + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* Session ID (zero since there is no reuse) */ + *(p++) = 0; + + /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), + ssl3_put_cipher_by_char); + if (i == 0) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + return -1; + } +#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH + /* + * Some servers hang if client hello > 256 bytes as hack + * workaround chop number of supported ciphers to keep it well + * below this if we use TLS v1.2 + */ + if (TLS1_get_version(s) >= TLS1_2_VERSION + && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) + i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; +#endif + s2n(i, p); + p += i; + + /* COMPRESSION */ +#ifdef OPENSSL_NO_COMP + *(p++) = 1; +#else + if ((s->options & SSL_OP_NO_COMPRESSION) + || !s->ctx->comp_methods) + j = 0; + else + j = sk_SSL_COMP_num(s->ctx->comp_methods); + *(p++) = 1 + j; + for (i = 0; i < j; i++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); + *(p++) = comp->id; + } +#endif + *(p++) = 0; /* Add the NULL method */ + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (ssl_prepare_clienthello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + return -1; + } + if ((p = + ssl_add_clienthello_tlsext(s, p, + buf + SSL3_RT_MAX_PLAIN_LENGTH, + &al)) == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } +#endif + + l = p - d; + + /* fill in 4-byte handshake header */ + d = &(buf[5]); + *(d++) = SSL3_MT_CLIENT_HELLO; + l2n3(l, d); + + l += 4; + + if (l > SSL3_RT_MAX_PLAIN_LENGTH) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* fill in 5-byte record header */ + d = buf; + *(d++) = SSL3_RT_HANDSHAKE; + *(d++) = version_major; + /* + * Some servers hang if we use long client hellos and a record + * number > TLS 1.0. + */ + if (TLS1_get_client_version(s) > TLS1_VERSION) + *(d++) = 1; + else + *(d++) = version_minor; + s2n((int)l, d); + + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + + ssl3_finish_mac(s, &(buf[5]), s->init_num - 5); + } + + s->state = SSL23_ST_CW_CLNT_HELLO_B; + s->init_off = 0; + } + + /* SSL3_ST_CW_CLNT_HELLO_B */ + ret = ssl23_write_bytes(s); + + if ((ret >= 2) && s->msg_callback) { + /* Client Hello has been sent; tell msg_callback */ + + if (ssl2_compat) + s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data + 2, + ret - 2, s, s->msg_callback_arg); + else { + s->msg_callback(1, version, SSL3_RT_HEADER, s->init_buf->data, 5, + s, s->msg_callback_arg); + s->msg_callback(1, version, SSL3_RT_HANDSHAKE, + s->init_buf->data + 5, ret - 5, s, + s->msg_callback_arg); + } + } + + return ret; +} + +static int ssl23_get_server_hello(SSL *s) +{ + char buf[8]; + unsigned char *p; + int i; + int n; + + n = ssl23_read_bytes(s, 7); + + if (n != 7) + return (n); + p = s->packet; + + memcpy(buf, p, n); + + if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) && + (p[5] == 0x00) && (p[6] == 0x02)) { +#ifdef OPENSSL_NO_SSL2 + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; +#else + /* we are talking sslv2 */ + /* + * we need to clean up the SSLv3 setup and put in the sslv2 stuff. + */ + int ch_len; + + if (s->options & SSL_OP_NO_SSLv2) { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + if (s->s2 == NULL) { + if (!ssl2_new(s)) + goto err; + } else + ssl2_clear(s); + + if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) + ch_len = SSL2_CHALLENGE_LENGTH; + else + ch_len = SSL2_MAX_CHALLENGE_LENGTH; + + /* write out sslv2 challenge */ + /* + * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it is + * one of SSL2_MAX_CHALLENGE_LENGTH (32) or SSL2_MAX_CHALLENGE_LENGTH + * (16), but leave the check in for futurproofing + */ + i = (SSL3_RANDOM_SIZE < ch_len) + ? SSL3_RANDOM_SIZE : ch_len; + s->s2->challenge_length = i; + memcpy(s->s2->challenge, + &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); + + if (s->s3 != NULL) + ssl3_free(s); + + if (!BUF_MEM_grow_clean(s->init_buf, + SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, ERR_R_BUF_LIB); + goto err; + } + + s->state = SSL2_ST_GET_SERVER_HELLO_A; + if (!(s->client_version == SSL2_VERSION)) + /* + * use special padding (SSL 3.0 draft/RFC 2246, App. E.2) + */ + s->s2->ssl2_rollback = 1; + + /* + * setup the 7 bytes we have read so we get them from the sslv2 + * buffer + */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + s->packet = &(s->s2->rbuf[0]); + memcpy(s->packet, buf, n); + s->s2->rbuf_left = n; + s->s2->rbuf_offs = 0; + + /* we have already written one */ + s->s2->write_sequence = 1; + + s->method = SSLv2_client_method(); + s->handshake_func = s->method->ssl_connect; +#endif + } else if (p[1] == SSL3_VERSION_MAJOR && + p[2] <= TLS1_2_VERSION_MINOR && + ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || + (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) { + /* we have sslv3 or tls1 (server hello or alert) */ + +#ifndef OPENSSL_NO_SSL3 + if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) { +# ifdef OPENSSL_FIPS + if (FIPS_mode()) { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +# endif + s->version = SSL3_VERSION; + s->method = SSLv3_client_method(); + } else +#endif + if ((p[2] == TLS1_VERSION_MINOR) && !(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + s->method = TLSv1_client_method(); + } else if ((p[2] == TLS1_1_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + s->method = TLSv1_1_client_method(); + } else if ((p[2] == TLS1_2_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + s->method = TLSv1_2_client_method(); + } else { + /* + * Unrecognised version, we'll send a protocol version alert using + * our preferred version. + */ + switch(s->client_version) { + default: + /* + * Shouldn't happen + * Fall through + */ + case TLS1_2_VERSION: + s->version = TLS1_2_VERSION; + s->method = TLSv1_2_client_method(); + break; + case TLS1_1_VERSION: + s->version = TLS1_1_VERSION; + s->method = TLSv1_1_client_method(); + break; + case TLS1_VERSION: + s->version = TLS1_VERSION; + s->method = TLSv1_client_method(); + break; +#ifndef OPENSSL_NO_SSL3 + case SSL3_VERSION: + s->version = SSL3_VERSION; + s->method = SSLv3_client_method(); + break; +#endif + } + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + goto err; + } + + s->session->ssl_version = s->version; + + /* ensure that TLS_MAX_VERSION is up-to-date */ + OPENSSL_assert(s->version <= TLS_MAX_VERSION); + + if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) { + /* fatal alert */ + + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int j; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + i = p[5]; + if (cb != NULL) { + j = (i << 8) | p[6]; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (s->msg_callback) { + s->msg_callback(0, s->version, SSL3_RT_HEADER, p, 5, s, + s->msg_callback_arg); + s->msg_callback(0, s->version, SSL3_RT_ALERT, p + 5, 2, s, + s->msg_callback_arg); + } + + s->rwstate = SSL_NOTHING; + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_AD_REASON_OFFSET + p[6]); + goto err; + } + + if (!ssl_init_wbio_buffer(s, 1)) + goto err; + + /* we are in this state */ + s->state = SSL3_ST_CR_SRVR_HELLO_A; + + /* + * put the 7 bytes we have read into the input buffer for SSLv3 + */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + goto err; + s->packet = &(s->s3->rbuf.buf[0]); + memcpy(s->packet, buf, n); + s->s3->rbuf.left = n; + s->s3->rbuf.offset = 0; + + s->handshake_func = s->method->ssl_connect; + } else { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNKNOWN_PROTOCOL); + goto err; + } + s->init_num = 0; + + return (SSL_connect(s)); + err: + return (-1); +} +/* ssl/s23_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "objects.h" +// #include "ssl_locl.h" + +long ssl23_default_timeout(void) +{ + return (300); +} + +int ssl23_num_ciphers(void) +{ + return (ssl3_num_ciphers() +#ifndef OPENSSL_NO_SSL2 + + ssl2_num_ciphers() +#endif + ); +} + +const SSL_CIPHER *ssl23_get_cipher(unsigned int u) +{ + unsigned int uu = ssl3_num_ciphers(); + + if (u < uu) + return (ssl3_get_cipher(u)); + else +#ifndef OPENSSL_NO_SSL2 + return (ssl2_get_cipher(u - uu)); +#else + return (NULL); +#endif +} + +/* + * This function needs to check if the ciphers required are actually + * available + */ +const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p) +{ + const SSL_CIPHER *cp; + + cp = ssl3_get_cipher_by_char(p); +#ifndef OPENSSL_NO_SSL2 + if (cp == NULL) + cp = ssl2_get_cipher_by_char(p); +#endif + return (cp); +} + +int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) +{ + long l; + + /* We can write SSLv2 and SSLv3 ciphers */ + /* but no ECC ciphers */ + if (c->algorithm_mkey == SSL_kECDHr || + c->algorithm_mkey == SSL_kECDHe || + c->algorithm_mkey == SSL_kEECDH || + c->algorithm_auth == SSL_aECDH || c->algorithm_auth == SSL_aECDSA) + return 0; + if (p != NULL) { + l = c->id; + p[0] = ((unsigned char)(l >> 16L)) & 0xFF; + p[1] = ((unsigned char)(l >> 8L)) & 0xFF; + p[2] = ((unsigned char)(l)) & 0xFF; + } + return (3); +} + +int ssl23_read(SSL *s, void *buf, int len) +{ + int n; + + clear_sys_error(); + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_read(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} + +int ssl23_peek(SSL *s, void *buf, int len) +{ + int n; + + clear_sys_error(); + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_PEEK, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_peek(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} + +int ssl23_write(SSL *s, const void *buf, int len) +{ + int n; + + clear_sys_error(); + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_write(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} +/* ssl/s23_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "objects.h" +// #include "ssl_locl.h" + +static const SSL_METHOD *ssl23_get_method(int ver); +static const SSL_METHOD *ssl23_get_method(int ver) +{ +#ifndef OPENSSL_NO_SSL2 + if (ver == SSL2_VERSION) + return (SSLv2_method()); + else +#endif +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_method()); + else +#endif +#ifndef OPENSSL_NO_TLS1 + if (ver == TLS1_VERSION) + return (TLSv1_method()); + else if (ver == TLS1_1_VERSION) + return (TLSv1_1_method()); + else if (ver == TLS1_2_VERSION) + return (TLSv1_2_method()); + else +#endif + return (NULL); +} + +IMPLEMENT_ssl23_meth_func(SSLv23_method, + ssl23_accept, ssl23_connect, ssl23_get_method) +/* ssl/s23_pkt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +// #include "ssl_locl.h" +// #include "evp.h" +// #include "buffer.h" + +/* + * Return values are as per SSL_write() + */ +int ssl23_write_bytes(SSL *s) +{ + int i, num, tot; + char *buf; + + buf = s->init_buf->data; + tot = s->init_off; + num = s->init_num; + for (;;) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, &(buf[tot]), num); + if (i <= 0) { + s->init_off = tot; + s->init_num = num; + return i; + } + s->rwstate = SSL_NOTHING; + if (i == num) + return (tot + i); + + num -= i; + tot += i; + } +} + +/* return regularly only when we have read (at least) 'n' bytes + * + * Return values are as per SSL_read() + */ +int ssl23_read_bytes(SSL *s, int n) +{ + unsigned char *p; + int j; + + if (s->packet_length < (unsigned int)n) { + p = s->packet; + + for (;;) { + s->rwstate = SSL_READING; + j = BIO_read(s->rbio, (char *)&(p[s->packet_length]), + n - s->packet_length); + if (j <= 0) + return j; + s->rwstate = SSL_NOTHING; + s->packet_length += j; + if (s->packet_length >= (unsigned int)n) + return (s->packet_length); + } + } + return (n); +} +/* ssl/s23_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "ssl_locl.h" +// #include "buffer.h" +// #include "rand.h" +// #include "objects.h" +// #include "evp.h" +#ifdef OPENSSL_FIPS +# include +#endif + +static const SSL_METHOD *ssl23_get_server_method(int ver); +int ssl23_get_client_hello(SSL *s); +static const SSL_METHOD *ssl23_get_server_method(int ver) +{ +#ifndef OPENSSL_NO_SSL2 + if (ver == SSL2_VERSION) + return (SSLv2_server_method()); +#endif +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_server_method()); +#endif + if (ver == TLS1_VERSION) + return (TLSv1_server_method()); + else if (ver == TLS1_1_VERSION) + return (TLSv1_1_server_method()); + else if (ver == TLS1_2_VERSION) + return (TLSv1_2_server_method()); + else + return (NULL); +} + +IMPLEMENT_ssl23_meth_func(SSLv23_server_method, + ssl23_accept, + ssl_undefined_function, ssl23_get_server_method) + +int ssl23_accept(SSL *s) +{ + BUF_MEM *buf; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state; + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + case SSL_ST_OK | SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_ACCEPT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + BUF_MEM_free(buf); + ret = -1; + goto end; + } + s->init_buf = buf; + } + + if (!ssl3_init_finished_mac(s)) { + ret = -1; + goto end; + } + + s->state = SSL23_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + s->init_num = 0; + break; + + case SSL23_ST_SR_CLNT_HELLO_A: + case SSL23_ST_SR_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl23_get_client_hello(s); + if (ret >= 0) + cb = NULL; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_SSL23_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + end: + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +int ssl23_get_client_hello(SSL *s) +{ + /*- + * Request this many bytes in initial read. + * We can detect SSL 3.0/TLS 1.0 Client Hellos + * ('type == 3') correctly only when the following + * is in a single record, which is not guaranteed by + * the protocol specification: + * Byte Content + * 0 type \ + * 1/2 version > record header + * 3/4 length / + * 5 msg_type \ + * 6-8 length > Client Hello message + * 9/10 client_version / + */ + char buf_space[11]; + char *buf = &(buf_space[0]); + unsigned char *p, *d, *d_len, *dd; + unsigned int i; + unsigned int csl, sil, cl; + int n = 0, j; + int type = 0; + int v[2]; + + if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { + /* read the initial header */ + v[0] = v[1] = 0; + + if (!ssl3_setup_buffers(s)) + goto err; + + n = ssl23_read_bytes(s, sizeof(buf_space)); + if (n != sizeof(buf_space)) + return (n); /* n == -1 || n == 0 */ + + p = s->packet; + + memcpy(buf, p, n); + + if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { + /* + * SSLv2 header + */ + if ((p[3] == 0x00) && (p[4] == 0x02)) { + v[0] = p[3]; + v[1] = p[4]; + /* SSLv2 */ + if (!(s->options & SSL_OP_NO_SSLv2)) + type = 1; + } else if (p[3] == SSL3_VERSION_MAJOR) { + v[0] = p[3]; + v[1] = p[4]; + /* SSLv3/TLSv1 */ + if (p[4] >= TLS1_VERSION_MINOR) { + if (p[4] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (p[4] >= TLS1_1_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + /* + * type=2; + *//* + * done later to survive restarts + */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + /* + * type=2; + *//* + * done later to survive restarts + */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + /* type=2; */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_SSLv2)) { + type = 1; + } + } else if (!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + /* type=2; */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_SSLv2)) + type = 1; + + } + } + /* p[4] < 5 ... silly record length? */ + else if ((p[0] == SSL3_RT_HANDSHAKE) && + (p[1] == SSL3_VERSION_MAJOR) && + (p[5] == SSL3_MT_CLIENT_HELLO) && ((p[3] == 0 && p[4] < 5) + || (p[9] >= p[1]))) { + /* + * SSLv3 or tls1 header + */ + + v[0] = p[1]; /* major version (= SSL3_VERSION_MAJOR) */ + /* + * We must look at client_version inside the Client Hello message + * to get the correct minor version. However if we have only a + * pathologically small fragment of the Client Hello message, this + * would be difficult, and we'd have to read more records to find + * out. No known SSL 3.0 client fragments ClientHello like this, + * so we simply reject such connections to avoid protocol version + * downgrade attacks. + */ + if (p[3] == 0 && p[4] < 6) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_SMALL); + goto err; + } + /* + * if major version number > 3 set minor to a value which will + * use the highest version 3 we support. If TLS 2.0 ever appears + * we will need to revise this.... + */ + if (p[9] > SSL3_VERSION_MAJOR) + v[1] = 0xff; + else + v[1] = p[10]; /* minor version according to client_version */ + if (v[1] >= TLS1_VERSION_MINOR) { + if (v[1] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + type = 3; + } else if (v[1] >= TLS1_1_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + type = 3; + } else if (!(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + type = 3; + } else if (!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + type = 3; + } + } else { + /* client requests SSL 3.0 */ + if (!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + type = 3; + } else if (!(s->options & SSL_OP_NO_TLSv1)) { + /* + * we won't be able to use TLS of course, but this will + * send an appropriate alert + */ + s->version = TLS1_VERSION; + type = 3; + } + } + } else if ((strncmp("GET ", (char *)p, 4) == 0) || + (strncmp("POST ", (char *)p, 5) == 0) || + (strncmp("HEAD ", (char *)p, 5) == 0) || + (strncmp("PUT ", (char *)p, 4) == 0)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTP_REQUEST); + goto err; + } else if (strncmp("CONNECT", (char *)p, 7) == 0) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTPS_PROXY_REQUEST); + goto err; + } + } + + /* ensure that TLS_MAX_VERSION is up-to-date */ + OPENSSL_assert(s->version <= TLS_MAX_VERSION); + + if (s->version < TLS1_2_VERSION && tls1_suiteb(s)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); + goto err; + } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (s->version < TLS1_VERSION)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +#endif + + if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { + /* + * we have SSLv3/TLSv1 in an SSLv2 header (other cases skip this + * state) + */ + + type = 2; + p = s->packet; + v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ + v[1] = p[4]; + + /*- + * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 + * header is sent directly on the wire, not wrapped as a TLS + * record. It's format is: + * Byte Content + * 0-1 msg_length + * 2 msg_type + * 3-4 version + * 5-6 cipher_spec_length + * 7-8 session_id_length + * 9-10 challenge_length + * ... ... + */ + n = ((p[0] & 0x7f) << 8) | p[1]; + if (n > (1024 * 4)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_LARGE); + goto err; + } + if (n < 9) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_RECORD_LENGTH_MISMATCH); + goto err; + } + + j = ssl23_read_bytes(s, n + 2); + /* + * We previously read 11 bytes, so if j > 0, we must have j == n+2 == + * s->packet_length. We have at least 11 valid packet bytes. + */ + if (j <= 0) + return (j); + + ssl3_finish_mac(s, s->packet + 2, s->packet_length - 2); + + /* CLIENT-HELLO */ + if (s->msg_callback) + s->msg_callback(0, SSL2_VERSION, 0, s->packet + 2, + s->packet_length - 2, s, s->msg_callback_arg); + + p = s->packet; + p += 5; + n2s(p, csl); + n2s(p, sil); + n2s(p, cl); + d = (unsigned char *)s->init_buf->data; + if ((csl + sil + cl + 11) != s->packet_length) { /* We can't have TLS + * extensions in SSL + * 2.0 format * + * Client Hello, can + * we? Error + * condition should + * be * '>' + * otherweise */ + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_RECORD_LENGTH_MISMATCH); + goto err; + } + + /* record header: msg_type ... */ + *(d++) = SSL3_MT_CLIENT_HELLO; + /* ... and length (actual value will be written later) */ + d_len = d; + d += 3; + + /* client_version */ + *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ + *(d++) = v[1]; + + /* lets populate the random area */ + /* get the challenge_length */ + i = (cl > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : cl; + memset(d, 0, SSL3_RANDOM_SIZE); + memcpy(&(d[SSL3_RANDOM_SIZE - i]), &(p[csl + sil]), i); + d += SSL3_RANDOM_SIZE; + + /* no session-id reuse */ + *(d++) = 0; + + /* ciphers */ + j = 0; + dd = d; + d += 2; + for (i = 0; i < csl; i += 3) { + if (p[i] != 0) + continue; + *(d++) = p[i + 1]; + *(d++) = p[i + 2]; + j += 2; + } + s2n(j, dd); + + /* COMPRESSION */ + *(d++) = 1; + *(d++) = 0; + +#if 0 + /* copy any remaining data with may be extensions */ + p = p + csl + sil + cl; + while (p < s->packet + s->packet_length) { + *(d++) = *(p++); + } +#endif + + i = (d - (unsigned char *)s->init_buf->data) - 4; + l2n3((long)i, d_len); + + /* get the data reused from the init_buf */ + s->s3->tmp.reuse_message = 1; + s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; + s->s3->tmp.message_size = i; + } + + /* imaginary new state (for program structure): */ + /* s->state = SSL23_SR_CLNT_HELLO_C */ + + if (type == 1) { +#ifdef OPENSSL_NO_SSL2 + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; +#else + /* we are talking sslv2 */ + /* + * we need to clean up the SSLv3/TLSv1 setup and put in the sslv2 + * stuff. + */ + + if (s->s2 == NULL) { + if (!ssl2_new(s)) + goto err; + } else + ssl2_clear(s); + + if (s->s3 != NULL) + ssl3_free(s); + + if (!BUF_MEM_grow_clean(s->init_buf, + SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + goto err; + } + + s->state = SSL2_ST_GET_CLIENT_HELLO_A; + if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3) + s->s2->ssl2_rollback = 0; + else + /* + * reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0 + * (SSL 3.0 draft/RFC 2246, App. E.2) + */ + s->s2->ssl2_rollback = 1; + + /* + * setup the n bytes we have read so we get them from the sslv2 + * buffer + */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + s->packet = &(s->s2->rbuf[0]); + memcpy(s->packet, buf, n); + s->s2->rbuf_left = n; + s->s2->rbuf_offs = 0; + + s->method = SSLv2_server_method(); + s->handshake_func = s->method->ssl_accept; +#endif + } + + if ((type == 2) || (type == 3)) { + /* + * we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) + */ + const SSL_METHOD *new_method; + new_method = ssl23_get_server_method(s->version); + if (new_method == NULL) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + s->method = new_method; + + if (!ssl_init_wbio_buffer(s, 1)) + goto err; + + /* we are in this state */ + s->state = SSL3_ST_SR_CLNT_HELLO_A; + + if (type == 3) { + /* + * put the 'n' bytes we have read into the input buffer for SSLv3 + */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + goto err; + + s->packet = &(s->s3->rbuf.buf[0]); + memcpy(s->packet, buf, n); + s->s3->rbuf.left = n; + s->s3->rbuf.offset = 0; + } else { + s->packet_length = 0; + s->s3->rbuf.left = 0; + s->s3->rbuf.offset = 0; + } +#if 0 /* ssl3_get_client_hello does this */ + s->client_version = (v[0] << 8) | v[1]; +#endif + s->handshake_func = s->method->ssl_accept; + } + + if ((type < 1) || (type > 3)) { + /* bad, very bad */ + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); + goto err; + } + s->init_num = 0; + + if (buf != buf_space) + OPENSSL_free(buf); + return (SSL_accept(s)); + err: + if (buf != buf_space) + OPENSSL_free(buf); + return (-1); +} diff --git a/Sources/COpenSSL/s2_.c b/Sources/COpenSSL/s2_.c new file mode 100644 index 00000000..cbee1941 --- /dev/null +++ b/Sources/COpenSSL/s2_.c @@ -0,0 +1,3850 @@ +/* ssl/s2_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +# include +# include "rand.h" +# include "buffer.h" +# include "objects.h" +# include "evp.h" + +static const SSL_METHOD *ssl2_get_client_method(int ver); +static int get_server_finished(SSL *s); +static int get_server_verify(SSL *s); +static int get_server_hello(SSL *s); +static int client_hello(SSL *s); +static int client_master_key(SSL *s); +static int client_finished(SSL *s); +static int client_certificate(SSL *s); +static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, + unsigned char *to, int padding); +# define BREAK break + +static const SSL_METHOD *ssl2_get_client_method(int ver) +{ + if (ver == SSL2_VERSION) + return (SSLv2_client_method()); + else + return (NULL); +} + +IMPLEMENT_ssl2_meth_func(SSLv2_client_method, + ssl_undefined_function, + ssl2_connect, ssl2_get_client_method) + +int ssl2_connect(SSL *s) +{ + unsigned long l = (unsigned long)time(NULL); + BUF_MEM *buf = NULL; + int ret = -1; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int new_state, state; + + RAND_add(&l, sizeof(l), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE | SSL_ST_CONNECT: + case SSL_ST_OK | SSL_ST_CONNECT: + + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + s->version = SSL2_VERSION; + s->type = SSL_ST_CONNECT; + + buf = s->init_buf; + if ((buf == NULL) && ((buf = BUF_MEM_new()) == NULL)) { + ret = -1; + goto end; + } + if (!BUF_MEM_grow(buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + if (buf == s->init_buf) + buf = NULL; + ret = -1; + goto end; + } + s->init_buf = buf; + buf = NULL; + s->init_num = 0; + s->state = SSL2_ST_SEND_CLIENT_HELLO_A; + s->ctx->stats.sess_connect++; + s->handshake_func = ssl2_connect; + BREAK; + + case SSL2_ST_SEND_CLIENT_HELLO_A: + case SSL2_ST_SEND_CLIENT_HELLO_B: + s->shutdown = 0; + ret = client_hello(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_GET_SERVER_HELLO_A; + BREAK; + + case SSL2_ST_GET_SERVER_HELLO_A: + case SSL2_ST_GET_SERVER_HELLO_B: + ret = get_server_hello(s); + if (ret <= 0) + goto end; + s->init_num = 0; + if (!s->hit) { /* new session */ + s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_A; + BREAK; + } else { + s->state = SSL2_ST_CLIENT_START_ENCRYPTION; + break; + } + + case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: + case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: + ret = client_master_key(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_CLIENT_START_ENCRYPTION; + break; + + case SSL2_ST_CLIENT_START_ENCRYPTION: + /* + * Ok, we now have all the stuff needed to start encrypting, so + * lets fire it up :-) + */ + if (!ssl2_enc_init(s, 1)) { + ret = -1; + goto end; + } + s->s2->clear_text = 0; + s->state = SSL2_ST_SEND_CLIENT_FINISHED_A; + break; + + case SSL2_ST_SEND_CLIENT_FINISHED_A: + case SSL2_ST_SEND_CLIENT_FINISHED_B: + ret = client_finished(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_GET_SERVER_VERIFY_A; + break; + + case SSL2_ST_GET_SERVER_VERIFY_A: + case SSL2_ST_GET_SERVER_VERIFY_B: + ret = get_server_verify(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_GET_SERVER_FINISHED_A; + break; + + case SSL2_ST_GET_SERVER_FINISHED_A: + case SSL2_ST_GET_SERVER_FINISHED_B: + ret = get_server_finished(s); + if (ret <= 0) + goto end; + break; + + case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: + case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: + case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: + case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: + case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: + ret = client_certificate(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_GET_SERVER_FINISHED_A; + break; + + case SSL_ST_OK: + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } + s->init_num = 0; + /* ERR_clear_error(); */ + + /* + * If we want to cache session-ids in the client and we + * successfully add the session-id to the cache, and there is a + * callback, then pass it out. 26/11/96 - eay - only add if not a + * re-used session. + */ + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->ctx->stats.sess_connect_good++; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + goto end; + /* break; */ + default: + SSLerr(SSL_F_SSL2_CONNECT, SSL_R_UNKNOWN_STATE); + return (-1); + /* break; */ + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + end: + s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + return (ret); +} + +static int get_server_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p; + int i, j; + unsigned long len; + STACK_OF(SSL_CIPHER) *sk = NULL, *cl, *prio, *allow; + + buf = (unsigned char *)s->init_buf->data; + p = buf; + if (s->state == SSL2_ST_GET_SERVER_HELLO_A) { + i = ssl2_read(s, (char *)&(buf[s->init_num]), 11 - s->init_num); + if (i < (11 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i)); + s->init_num = 11; + + if (*(p++) != SSL2_MT_SERVER_HELLO) { + if (p[-1] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_READ_WRONG_PACKET_TYPE); + } else + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_PEER_ERROR); + return (-1); + } +# if 0 + s->hit = (*(p++)) ? 1 : 0; + /* + * Some [PPC?] compilers fail to increment p in above statement, e.g. + * one provided with Rhapsody 5.5, but most recent example XL C 11.1 + * for AIX, even without optimization flag... + */ +# else + s->hit = (*p) ? 1 : 0; + p++; +# endif + s->s2->tmp.cert_type = *(p++); + n2s(p, i); + if (i < s->version) + s->version = i; + n2s(p, i); + s->s2->tmp.cert_length = i; + n2s(p, i); + s->s2->tmp.csl = i; + n2s(p, i); + s->s2->tmp.conn_id_length = i; + s->state = SSL2_ST_GET_SERVER_HELLO_B; + } + + /* SSL2_ST_GET_SERVER_HELLO_B */ + len = + 11 + (unsigned long)s->s2->tmp.cert_length + + (unsigned long)s->s2->tmp.csl + + (unsigned long)s->s2->tmp.conn_id_length; + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_MESSAGE_TOO_LONG); + return -1; + } + j = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(buf[s->init_num]), j); + if (i != j) + return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i)); + if (s->msg_callback) { + /* SERVER-HELLO */ + s->msg_callback(0, s->version, 0, buf, (size_t)len, s, + s->msg_callback_arg); + } + + /* things are looking good */ + + p = buf + 11; + if (s->hit) { + if (s->s2->tmp.cert_length != 0) { + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CERT_LENGTH_NOT_ZERO); + return (-1); + } + if (s->s2->tmp.cert_type != 0) { + if (!(s->options & SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)) { + SSLerr(SSL_F_GET_SERVER_HELLO, + SSL_R_REUSE_CERT_TYPE_NOT_ZERO); + return (-1); + } + } + if (s->s2->tmp.csl != 0) { + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CIPHER_LIST_NOT_ZERO); + return (-1); + } + } else { +# if 0 + /* very bad */ + memset(s->session->session_id, 0, + SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES); + s->session->session_id_length = 0; +# endif + + /* + * we need to do this in case we were trying to reuse a client + * session but others are already reusing it. If this was a new + * 'blank' session ID, the session-id length will still be 0 + */ + if (s->session->session_id_length > 0) { + if (!ssl_get_new_session(s, 0)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } + + if (ssl2_set_certificate(s, s->s2->tmp.cert_type, + s->s2->tmp.cert_length, p) <= 0) { + ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); + return (-1); + } + p += s->s2->tmp.cert_length; + + if (s->s2->tmp.csl == 0) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_LIST); + return (-1); + } + + /* + * We have just received a list of ciphers back from the server. We + * need to get the ones that match, then select the one we want the + * most :-). + */ + + /* load the ciphers */ + sk = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.csl, + &s->session->ciphers); + p += s->s2->tmp.csl; + if (sk == NULL) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_MALLOC_FAILURE); + return (-1); + } + + (void)sk_SSL_CIPHER_set_cmp_func(sk, ssl_cipher_ptr_id_cmp); + + /* get the array of ciphers we will accept */ + cl = SSL_get_ciphers(s); + (void)sk_SSL_CIPHER_set_cmp_func(cl, ssl_cipher_ptr_id_cmp); + + /* + * If server preference flag set, choose the first + * (highest priority) cipher the server sends, otherwise + * client preference has priority. + */ + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = sk; + allow = cl; + } else { + prio = cl; + allow = sk; + } + /* + * In theory we could have ciphers sent back that we don't want to + * use but that does not matter since we will check against the list + * we originally sent and for performance reasons we should not + * bother to match the two lists up just to check. + */ + for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + if (sk_SSL_CIPHER_find(allow, sk_SSL_CIPHER_value(prio, i)) >= 0) + break; + } + + if (i >= sk_SSL_CIPHER_num(prio)) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_MATCH); + return (-1); + } + s->session->cipher = sk_SSL_CIPHER_value(prio, i); + + if (s->session->peer != NULL) { /* can't happen */ + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + return (-1); + } + + s->session->peer = s->session->sess_cert->peer_key->x509; + /* peer_key->x509 has been set by ssl2_set_certificate. */ + CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509); + } + + if (s->session->sess_cert == NULL + || s->session->peer != s->session->sess_cert->peer_key->x509) + /* can't happen */ + { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + return (-1); + } + + s->s2->conn_id_length = s->s2->tmp.conn_id_length; + if (s->s2->conn_id_length > sizeof(s->s2->conn_id)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG); + return -1; + } + memcpy(s->s2->conn_id, p, s->s2->tmp.conn_id_length); + return (1); +} + +static int client_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; +/* CIPHER **cipher;*/ + int i, n, j; + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A) { + if ((s->session == NULL) || (s->session->ssl_version != s->version)) { + if (!ssl_get_new_session(s, 0)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } + /* else use the pre-loaded session */ + + p = buf; /* header */ + d = p + 9; /* data section */ + *(p++) = SSL2_MT_CLIENT_HELLO; /* type */ + s2n(SSL2_VERSION, p); /* version */ + n = j = 0; + + n = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), d, 0); + d += n; + + if (n == 0) { + SSLerr(SSL_F_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + return (-1); + } + + s2n(n, p); /* cipher spec num bytes */ + + if ((s->session->session_id_length > 0) && + (s->session->session_id_length <= + SSL2_MAX_SSL_SESSION_ID_LENGTH)) { + i = s->session->session_id_length; + s2n(i, p); /* session id length */ + memcpy(d, s->session->session_id, (unsigned int)i); + d += i; + } else { + s2n(0, p); + } + + s->s2->challenge_length = SSL2_CHALLENGE_LENGTH; + s2n(SSL2_CHALLENGE_LENGTH, p); /* challenge length */ + /* + * challenge id data + */ + if (RAND_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) + return -1; + memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH); + d += SSL2_CHALLENGE_LENGTH; + + s->state = SSL2_ST_SEND_CLIENT_HELLO_B; + s->init_num = d - buf; + s->init_off = 0; + } + /* SSL2_ST_SEND_CLIENT_HELLO_B */ + return (ssl2_do_write(s)); +} + +static int client_master_key(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int clear, enc, karg, i; + SSL_SESSION *sess; + const EVP_CIPHER *c; + const EVP_MD *md; + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) { + + if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_CLIENT_MASTER_KEY, + SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); + return (-1); + } + sess = s->session; + p = buf; + d = p + 10; + *(p++) = SSL2_MT_CLIENT_MASTER_KEY; /* type */ + + i = ssl_put_cipher_by_char(s, sess->cipher, p); + p += i; + + /* make key_arg data */ + i = EVP_CIPHER_iv_length(c); + sess->key_arg_length = i; + if (i > SSL_MAX_KEY_ARG_LENGTH) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + if (i > 0) + if (RAND_bytes(sess->key_arg, i) <= 0) + return -1; + + /* make a master key */ + i = EVP_CIPHER_key_length(c); + sess->master_key_length = i; + if (i > 0) { + if (i > (int)sizeof(sess->master_key)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + if (RAND_bytes(sess->master_key, i) <= 0) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } + + if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) + enc = 8; + else if (SSL_C_IS_EXPORT(sess->cipher)) + enc = 5; + else + enc = i; + + if ((int)i < enc) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_CIPHER_TABLE_SRC_ERROR); + return (-1); + } + clear = i - enc; + s2n(clear, p); + memcpy(d, sess->master_key, (unsigned int)clear); + d += clear; + + enc = ssl_rsa_public_encrypt(sess->sess_cert, enc, + &(sess->master_key[clear]), d, + (s-> + s2->ssl2_rollback) ? RSA_SSLV23_PADDING + : RSA_PKCS1_PADDING); + if (enc <= 0) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_PUBLIC_KEY_ENCRYPT_ERROR); + return (-1); + } +# ifdef PKCS1_CHECK + if (s->options & SSL_OP_PKCS1_CHECK_1) + d[1]++; + if (s->options & SSL_OP_PKCS1_CHECK_2) + sess->master_key[clear]++; +# endif + s2n(enc, p); + d += enc; + karg = sess->key_arg_length; + s2n(karg, p); /* key arg size */ + if (karg > (int)sizeof(sess->key_arg)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(d, sess->key_arg, (unsigned int)karg); + d += karg; + + s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_B; + s->init_num = d - buf; + s->init_off = 0; + } + + /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */ + return (ssl2_do_write(s)); +} + +static int client_finished(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL2_MT_CLIENT_FINISHED; + if (s->s2->conn_id_length > sizeof(s->s2->conn_id)) { + SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(p, s->s2->conn_id, (unsigned int)s->s2->conn_id_length); + + s->state = SSL2_ST_SEND_CLIENT_FINISHED_B; + s->init_num = s->s2->conn_id_length + 1; + s->init_off = 0; + } + return (ssl2_do_write(s)); +} + +/* read the data and then respond */ +static int client_certificate(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i; + unsigned int n; + int cert_ch_len; + unsigned char *cert_ch; + + buf = (unsigned char *)s->init_buf->data; + + /* + * We have a cert associated with the SSL, so attach it to the session if + * it does not have one + */ + + if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A) { + i = ssl2_read(s, (char *)&(buf[s->init_num]), + SSL2_MAX_CERT_CHALLENGE_LENGTH + 2 - s->init_num); + if (i < (SSL2_MIN_CERT_CHALLENGE_LENGTH + 2 - s->init_num)) + return (ssl2_part_read(s, SSL_F_CLIENT_CERTIFICATE, i)); + s->init_num += i; + if (s->msg_callback) { + /* REQUEST-CERTIFICATE */ + s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, + s->msg_callback_arg); + } + + /* type=buf[0]; */ + /* type eq x509 */ + if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { + ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); + SSLerr(SSL_F_CLIENT_CERTIFICATE, SSL_R_BAD_AUTHENTICATION_TYPE); + return (-1); + } + + if ((s->cert == NULL) || + (s->cert->key->x509 == NULL) || + (s->cert->key->privatekey == NULL)) { + s->state = SSL2_ST_X509_GET_CLIENT_CERTIFICATE; + } else + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C; + } + + cert_ch = buf + 2; + cert_ch_len = s->init_num - 2; + + if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE) { + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + + /* + * If we get an error we need to ssl->rwstate=SSL_X509_LOOKUP; + * return(error); We should then be retried when things are ok and we + * can get a cert or not + */ + + i = 0; + if (s->ctx->client_cert_cb != NULL) { + i = s->ctx->client_cert_cb(s, &(x509), &(pkey)); + } + + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return (-1); + } + s->rwstate = SSL_NOTHING; + + if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C; + if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) { + i = 0; + } + X509_free(x509); + EVP_PKEY_free(pkey); + } else if (i == 1) { + if (x509 != NULL) + X509_free(x509); + if (pkey != NULL) + EVP_PKEY_free(pkey); + SSLerr(SSL_F_CLIENT_CERTIFICATE, + SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + i = 0; + } + + if (i == 0) { + /* + * We have no client certificate to respond with so send the + * correct error message back + */ + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_B; + p = buf; + *(p++) = SSL2_MT_ERROR; + s2n(SSL2_PE_NO_CERTIFICATE, p); + s->init_off = 0; + s->init_num = 3; + /* Write is done at the end */ + } + } + + if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B) { + return (ssl2_do_write(s)); + } + + if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C) { + EVP_MD_CTX ctx; + + /* + * ok, now we calculate the checksum do it first so we can reuse buf + * :-) + */ + p = buf; + EVP_MD_CTX_init(&ctx); + EVP_SignInit_ex(&ctx, s->ctx->rsa_md5, NULL); + EVP_SignUpdate(&ctx, s->s2->key_material, s->s2->key_material_length); + EVP_SignUpdate(&ctx, cert_ch, (unsigned int)cert_ch_len); + i = i2d_X509(s->session->sess_cert->peer_key->x509, &p); + /* + * Don't update the signature if it fails - FIXME: probably should + * handle this better + */ + if (i > 0) + EVP_SignUpdate(&ctx, buf, (unsigned int)i); + + p = buf; + d = p + 6; + *(p++) = SSL2_MT_CLIENT_CERTIFICATE; + *(p++) = SSL2_CT_X509_CERTIFICATE; + n = i2d_X509(s->cert->key->x509, &d); + s2n(n, p); + + if (!EVP_SignFinal(&ctx, d, &n, s->cert->key->privatekey)) { + /* + * this is not good. If things have failed it means there so + * something wrong with the key. We will continue with a 0 length + * signature + */ + } + EVP_MD_CTX_cleanup(&ctx); + s2n(n, p); + d += n; + + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_D; + s->init_num = d - buf; + s->init_off = 0; + } + /* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */ + return (ssl2_do_write(s)); +} + +static int get_server_verify(SSL *s) +{ + unsigned char *p; + int i, n, len; + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_GET_SERVER_VERIFY_A) { + i = ssl2_read(s, (char *)&(p[s->init_num]), 1 - s->init_num); + if (i < (1 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i)); + s->init_num += i; + + s->state = SSL2_ST_GET_SERVER_VERIFY_B; + if (*p != SSL2_MT_SERVER_VERIFY) { + if (p[0] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_READ_WRONG_PACKET_TYPE); + } else { + SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_PEER_ERROR); + /* try to read the error message */ + i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); + return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); + } + return (-1); + } + } + + p = (unsigned char *)s->init_buf->data; + len = 1 + s->s2->challenge_length; + n = len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), n); + if (i < n) + return (ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i)); + if (s->msg_callback) { + /* SERVER-VERIFY */ + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); + } + p += 1; + + if (CRYPTO_memcmp(p, s->s2->challenge, s->s2->challenge_length) != 0) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_CHALLENGE_IS_DIFFERENT); + return (-1); + } + return (1); +} + +static int get_server_finished(SSL *s) +{ + unsigned char *buf; + unsigned char *p; + int i, n, len; + + buf = (unsigned char *)s->init_buf->data; + p = buf; + if (s->state == SSL2_ST_GET_SERVER_FINISHED_A) { + i = ssl2_read(s, (char *)&(buf[s->init_num]), 1 - s->init_num); + if (i < (1 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i)); + s->init_num += i; + + if (*p == SSL2_MT_REQUEST_CERTIFICATE) { + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_A; + return (1); + } else if (*p != SSL2_MT_SERVER_FINISHED) { + if (p[0] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_FINISHED, + SSL_R_READ_WRONG_PACKET_TYPE); + } else { + SSLerr(SSL_F_GET_SERVER_FINISHED, SSL_R_PEER_ERROR); + /* try to read the error message */ + i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); + return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); + } + return (-1); + } + s->state = SSL2_ST_GET_SERVER_FINISHED_B; + } + + len = 1 + SSL2_SSL_SESSION_ID_LENGTH; + n = len - s->init_num; + i = ssl2_read(s, (char *)&(buf[s->init_num]), n); + if (i < n) { + /* + * XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH, + * that's the maximum + */ + return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i)); + } + s->init_num += i; + if (s->msg_callback) { + /* SERVER-FINISHED */ + s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, + s->msg_callback_arg); + } + + if (!s->hit) { /* new session */ + /* new session-id */ + /* + * Make sure we were not trying to re-use an old SSL_SESSION or bad + * things can happen + */ + /* ZZZZZZZZZZZZZ */ + s->session->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; + memcpy(s->session->session_id, p + 1, SSL2_SSL_SESSION_ID_LENGTH); + } else { + if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG)) { + if ((s->session->session_id_length > + sizeof(s->session->session_id)) + || (0 != + memcmp(buf + 1, s->session->session_id, + (unsigned int)s->session->session_id_length))) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_FINISHED, + SSL_R_SSL_SESSION_ID_IS_DIFFERENT); + return (-1); + } + } + } + s->state = SSL_ST_OK; + return (1); +} + +/* loads in the certificate from the server */ +int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data) +{ + STACK_OF(X509) *sk = NULL; + EVP_PKEY *pkey = NULL; + SESS_CERT *sc = NULL; + int i; + X509 *x509 = NULL; + int ret = 0; + + x509 = d2i_X509(NULL, &data, (long)len); + if (x509 == NULL) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_X509_LIB); + goto err; + } + + if ((sk = sk_X509_new_null()) == NULL || !sk_X509_push(sk, x509)) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + + i = ssl_verify_cert_chain(s, sk); + + if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_CERTIFICATE_VERIFY_FAILED); + goto err; + } + ERR_clear_error(); /* but we keep s->verify_result */ + s->session->verify_result = s->verify_result; + + /* server's cert for this session */ + sc = ssl_sess_cert_new(); + if (sc == NULL) { + ret = -1; + goto err; + } + if (s->session->sess_cert) + ssl_sess_cert_free(s->session->sess_cert); + s->session->sess_cert = sc; + + sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509 = x509; + sc->peer_key = &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]); + + pkey = X509_get_pubkey(x509); + x509 = NULL; + if (pkey == NULL) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, + SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY); + goto err; + } + if (pkey->type != EVP_PKEY_RSA) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_PUBLIC_KEY_NOT_RSA); + goto err; + } + + if (!ssl_set_peer_cert_type(sc, SSL2_CT_X509_CERTIFICATE)) + goto err; + ret = 1; + err: + sk_X509_free(sk); + X509_free(x509); + EVP_PKEY_free(pkey); + return (ret); +} + +static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, + unsigned char *to, int padding) +{ + EVP_PKEY *pkey = NULL; + int i = -1; + + if ((sc == NULL) || (sc->peer_key->x509 == NULL) || + ((pkey = X509_get_pubkey(sc->peer_key->x509)) == NULL)) { + SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_NO_PUBLICKEY); + return (-1); + } + if (pkey->type != EVP_PKEY_RSA) { + SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA); + goto end; + } + + /* we have the public key */ + i = RSA_public_encrypt(len, from, to, pkey->pkey.rsa, padding); + if (i < 0) + SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, ERR_R_RSA_LIB); + end: + EVP_PKEY_free(pkey); + return (i); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif +/* ssl/s2_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +# include + +int ssl2_enc_init(SSL *s, int client) +{ + /* Max number of bytes needed */ + EVP_CIPHER_CTX *rs, *ws; + const EVP_CIPHER *c; + const EVP_MD *md; + int num; + + if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_SSL2_ENC_INIT, SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); + return (0); + } + ssl_replace_hash(&s->read_hash, md); + ssl_replace_hash(&s->write_hash, md); + + if ((s->enc_read_ctx == NULL) && ((s->enc_read_ctx = (EVP_CIPHER_CTX *) + OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) + == NULL)) + goto err; + + /* + * make sure it's intialized in case the malloc for enc_write_ctx fails + * and we exit with an error + */ + rs = s->enc_read_ctx; + EVP_CIPHER_CTX_init(rs); + + if ((s->enc_write_ctx == NULL) && ((s->enc_write_ctx = (EVP_CIPHER_CTX *) + OPENSSL_malloc(sizeof + (EVP_CIPHER_CTX))) == + NULL)) + goto err; + + ws = s->enc_write_ctx; + EVP_CIPHER_CTX_init(ws); + + num = c->key_len; + s->s2->key_material_length = num * 2; + OPENSSL_assert(s->s2->key_material_length <= sizeof(s->s2->key_material)); + + if (ssl2_generate_key_material(s) <= 0) + return 0; + + OPENSSL_assert(c->iv_len <= (int)sizeof(s->session->key_arg)); + EVP_EncryptInit_ex(ws, c, NULL, + &(s->s2->key_material[(client) ? num : 0]), + s->session->key_arg); + EVP_DecryptInit_ex(rs, c, NULL, + &(s->s2->key_material[(client) ? 0 : num]), + s->session->key_arg); + s->s2->read_key = &(s->s2->key_material[(client) ? 0 : num]); + s->s2->write_key = &(s->s2->key_material[(client) ? num : 0]); + return (1); + err: + SSLerr(SSL_F_SSL2_ENC_INIT, ERR_R_MALLOC_FAILURE); + return (0); +} + +/* + * read/writes from s->s2->mac_data using length for encrypt and decrypt. + * It sets s->s2->padding and s->[rw]length if we are encrypting Returns 0 on + * error and 1 on success + */ +int ssl2_enc(SSL *s, int send) +{ + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs; + + if (send) { + ds = s->enc_write_ctx; + l = s->s2->wlength; + } else { + ds = s->enc_read_ctx; + l = s->s2->rlength; + } + + /* check for NULL cipher */ + if (ds == NULL) + return 1; + + bs = ds->cipher->block_size; + /* + * This should be using (bs-1) and bs instead of 7 and 8, but what the + * hell. + */ + if (bs == 8) + l = (l + 7) / 8 * 8; + + if (EVP_Cipher(ds, s->s2->mac_data, s->s2->mac_data, l) < 1) + return 0; + + return 1; +} + +void ssl2_mac(SSL *s, unsigned char *md, int send) +{ + EVP_MD_CTX c; + unsigned char sequence[4], *p, *sec, *act; + unsigned long seq; + unsigned int len; + + if (send) { + seq = s->s2->write_sequence; + sec = s->s2->write_key; + len = s->s2->wact_data_length; + act = s->s2->wact_data; + } else { + seq = s->s2->read_sequence; + sec = s->s2->read_key; + len = s->s2->ract_data_length; + act = s->s2->ract_data; + } + + p = &(sequence[0]); + l2n(seq, p); + + /* There has to be a MAC algorithm. */ + EVP_MD_CTX_init(&c); + EVP_MD_CTX_copy(&c, s->read_hash); + EVP_DigestUpdate(&c, sec, EVP_CIPHER_CTX_key_length(s->enc_read_ctx)); + EVP_DigestUpdate(&c, act, len); + /* the above line also does the pad data */ + EVP_DigestUpdate(&c, sequence, 4); + EVP_DigestFinal_ex(&c, md, NULL); + EVP_MD_CTX_cleanup(&c); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif +/* ssl/s2_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +# include +# include "objects.h" +# include "evp.h" +# include "md5.h" + +const char ssl2_version_str[] = "SSLv2" OPENSSL_VERSION_PTEXT; + +# define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER)) + +/* list of available SSLv2 ciphers (sorted by id) */ +OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = { +# if 0 +/* NULL_WITH_MD5 v3 */ + { + 1, + SSL2_TXT_NULL_WITH_MD5, + SSL2_CK_NULL_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_MD5, + SSL_SSLV2, + SSL_EXPORT | SSL_EXP40 | SSL_STRONG_NONE, + 0, + 0, + 0, + }, +# endif + +/* RC4_128_WITH_MD5 */ + { + 1, + SSL2_TXT_RC4_128_WITH_MD5, + SSL2_CK_RC4_128_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + 0, + 128, + 128, + }, + +# if 0 +/* RC4_128_EXPORT40_WITH_MD5 */ + { + 1, + SSL2_TXT_RC4_128_EXPORT40_WITH_MD5, + SSL2_CK_RC4_128_EXPORT40_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL2_CF_5_BYTE_ENC, + 40, + 128, + }, +# endif + +/* RC2_128_CBC_WITH_MD5 */ + { + 1, + SSL2_TXT_RC2_128_CBC_WITH_MD5, + SSL2_CK_RC2_128_CBC_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + 0, + 128, + 128, + }, + +# if 0 +/* RC2_128_CBC_EXPORT40_WITH_MD5 */ + { + 1, + SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5, + SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL2_CF_5_BYTE_ENC, + 40, + 128, + }, +# endif + +# ifndef OPENSSL_NO_IDEA +/* IDEA_128_CBC_WITH_MD5 */ + { + 1, + SSL2_TXT_IDEA_128_CBC_WITH_MD5, + SSL2_CK_IDEA_128_CBC_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_IDEA, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + 0, + 128, + 128, + }, +# endif + +# if 0 +/* DES_64_CBC_WITH_MD5 */ + { + 1, + SSL2_TXT_DES_64_CBC_WITH_MD5, + SSL2_CK_DES_64_CBC_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + 0, + 56, + 56, + }, +# endif + +/* DES_192_EDE3_CBC_WITH_MD5 */ + { + 1, + SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5, + SSL2_CK_DES_192_EDE3_CBC_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + 0, + 112, + 168, + }, + +# if 0 +/* RC4_64_WITH_MD5 */ + { + 1, + SSL2_TXT_RC4_64_WITH_MD5, + SSL2_CK_RC4_64_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL2_CF_8_BYTE_ENC, + 64, + 64, + }, +# endif + +# if 0 +/* NULL SSLeay (testing) */ + { + 0, + SSL2_TXT_NULL, + SSL2_CK_NULL, + 0, + 0, + 0, + 0, + SSL_SSLV2, + SSL_STRONG_NONE, + 0, + 0, + 0, + }, +# endif + +/* end of list :-) */ +}; + +long ssl2_default_timeout(void) +{ + return (300); +} + +int ssl2_num_ciphers(void) +{ + return (SSL2_NUM_CIPHERS); +} + +const SSL_CIPHER *ssl2_get_cipher(unsigned int u) +{ + if (u < SSL2_NUM_CIPHERS) + return (&(ssl2_ciphers[SSL2_NUM_CIPHERS - 1 - u])); + else + return (NULL); +} + +int ssl2_pending(const SSL *s) +{ + return SSL_in_init(s) ? 0 : s->s2->ract_data_length; +} + +int ssl2_new(SSL *s) +{ + SSL2_STATE *s2; + + if ((s2 = OPENSSL_malloc(sizeof(*s2))) == NULL) + goto err; + memset(s2, 0, sizeof(*s2)); + +# if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2 +# error "assertion failed" +# endif + + if ((s2->rbuf = + OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) == NULL) + goto err; + /* + * wbuf needs one byte more because when using two-byte headers, we leave + * the first byte unused in do_ssl_write (s2_pkt.c) + */ + if ((s2->wbuf = + OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 3)) == NULL) + goto err; + s->s2 = s2; + + ssl2_clear(s); + return (1); + err: + if (s2 != NULL) { + if (s2->wbuf != NULL) + OPENSSL_free(s2->wbuf); + if (s2->rbuf != NULL) + OPENSSL_free(s2->rbuf); + OPENSSL_free(s2); + } + return (0); +} + +void ssl2_free(SSL *s) +{ + SSL2_STATE *s2; + + if (s == NULL) + return; + + s2 = s->s2; + if (s2->rbuf != NULL) + OPENSSL_free(s2->rbuf); + if (s2->wbuf != NULL) + OPENSSL_free(s2->wbuf); + OPENSSL_cleanse(s2, sizeof(*s2)); + OPENSSL_free(s2); + s->s2 = NULL; +} + +void ssl2_clear(SSL *s) +{ + SSL2_STATE *s2; + unsigned char *rbuf, *wbuf; + + s2 = s->s2; + + rbuf = s2->rbuf; + wbuf = s2->wbuf; + + memset(s2, 0, sizeof(*s2)); + + s2->rbuf = rbuf; + s2->wbuf = wbuf; + s2->clear_text = 1; + s->packet = s2->rbuf; + s->version = SSL2_VERSION; + s->packet_length = 0; +} + +long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + + switch (cmd) { + case SSL_CTRL_GET_SESSION_REUSED: + ret = s->hit; + break; + case SSL_CTRL_CHECK_PROTO_VERSION: + return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg); + default: + break; + } + return (ret); +} + +long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) +{ + return (0); +} + +long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + return (0); +} + +long ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) +{ + return (0); +} + +/* + * This function needs to check if the ciphers required are actually + * available + */ +const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p) +{ + SSL_CIPHER c; + const SSL_CIPHER *cp; + unsigned long id; + + id = 0x02000000L | ((unsigned long)p[0] << 16L) | + ((unsigned long)p[1] << 8L) | (unsigned long)p[2]; + c.id = id; + cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS); + return cp; +} + +int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) +{ + long l; + + if (p != NULL) { + l = c->id; + if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) + return (0); + p[0] = ((unsigned char)(l >> 16L)) & 0xFF; + p[1] = ((unsigned char)(l >> 8L)) & 0xFF; + p[2] = ((unsigned char)(l)) & 0xFF; + } + return (3); +} + +int ssl2_generate_key_material(SSL *s) +{ + unsigned int i; + EVP_MD_CTX ctx; + unsigned char *km; + unsigned char c = '0'; + const EVP_MD *md5; + int md_size; + + md5 = EVP_md5(); + +# ifdef CHARSET_EBCDIC + c = os_toascii['0']; /* Must be an ASCII '0', not EBCDIC '0', see + * SSLv2 docu */ +# endif + EVP_MD_CTX_init(&ctx); + km = s->s2->key_material; + + if (s->session->master_key_length < 0 || + s->session->master_key_length > (int)sizeof(s->session->master_key)) { + SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); + return 0; + } + md_size = EVP_MD_size(md5); + if (md_size < 0) + return 0; + for (i = 0; i < s->s2->key_material_length; i += md_size) { + if (((km - s->s2->key_material) + md_size) > + (int)sizeof(s->s2->key_material)) { + /* + * EVP_DigestFinal_ex() below would write beyond buffer + */ + SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); + return 0; + } + + EVP_DigestInit_ex(&ctx, md5, NULL); + + OPENSSL_assert(s->session->master_key_length >= 0 + && s->session->master_key_length + <= (int)sizeof(s->session->master_key)); + EVP_DigestUpdate(&ctx, s->session->master_key, + s->session->master_key_length); + EVP_DigestUpdate(&ctx, &c, 1); + c++; + EVP_DigestUpdate(&ctx, s->s2->challenge, s->s2->challenge_length); + EVP_DigestUpdate(&ctx, s->s2->conn_id, s->s2->conn_id_length); + EVP_DigestFinal_ex(&ctx, km, NULL); + km += md_size; + } + + EVP_MD_CTX_cleanup(&ctx); + return 1; +} + +void ssl2_return_error(SSL *s, int err) +{ + if (!s->error) { + s->error = 3; + s->error_code = err; + + ssl2_write_error(s); + } +} + +void ssl2_write_error(SSL *s) +{ + unsigned char buf[3]; + int i, error; + + buf[0] = SSL2_MT_ERROR; + buf[1] = (s->error_code >> 8) & 0xff; + buf[2] = (s->error_code) & 0xff; + +/* state=s->rwstate;*/ + + error = s->error; /* number of bytes left to write */ + s->error = 0; + OPENSSL_assert(error >= 0 && error <= (int)sizeof(buf)); + i = ssl2_write(s, &(buf[3 - error]), error); + +/* if (i == error) s->rwstate=state; */ + + if (i < 0) + s->error = error; + else { + s->error = error - i; + + if (s->error == 0) + if (s->msg_callback) { + /* ERROR */ + s->msg_callback(1, s->version, 0, buf, 3, s, + s->msg_callback_arg); + } + } +} + +int ssl2_shutdown(SSL *s) +{ + s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + return (1); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif +/* ssl/s2_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2_METHOD +# ifndef OPENSSL_NO_SSL2 +# include +# include "objects.h" + +static const SSL_METHOD *ssl2_get_method(int ver); +static const SSL_METHOD *ssl2_get_method(int ver) +{ + if (ver == SSL2_VERSION) + return (SSLv2_method()); + else + return (NULL); +} + +IMPLEMENT_ssl2_meth_func(SSLv2_method, + ssl2_accept, ssl2_connect, ssl2_get_method) + +# else /* !OPENSSL_NO_SSL2 */ + +const SSL_METHOD *SSLv2_method(void) { return NULL; } +const SSL_METHOD *SSLv2_client_method(void) { return NULL; } +const SSL_METHOD *SSLv2_server_method(void) { return NULL; } + +# endif + +#else /* !OPENSSL_NO_SSL2_METHOD */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif +/* ssl/s2_pkt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +# include +# include +# define USE_SOCKETS + +static int read_n(SSL *s, unsigned int n, unsigned int max, + unsigned int extend); +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); +static int write_pending(SSL *s, const unsigned char *buf, unsigned int len); +static int ssl_mt_error(int n); + +/* + * SSL 2.0 imlementation for SSL_read/SSL_peek - This routine will return 0 + * to len bytes, decrypted etc if required. + */ +static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) +{ + int n; + unsigned char mac[MAX_MAC_SIZE]; + unsigned char *p; + int i; + int mac_size; + + ssl2_read_again: + if (SSL_in_init(s) && !s->in_handshake) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + + clear_sys_error(); + s->rwstate = SSL_NOTHING; + if (len <= 0) + return (len); + + if (s->s2->ract_data_length != 0) { /* read from buffer */ + if (len > s->s2->ract_data_length) + n = s->s2->ract_data_length; + else + n = len; + + memcpy(buf, s->s2->ract_data, (unsigned int)n); + if (!peek) { + s->s2->ract_data_length -= n; + s->s2->ract_data += n; + if (s->s2->ract_data_length == 0) + s->rstate = SSL_ST_READ_HEADER; + } + + return (n); + } + + /* + * s->s2->ract_data_length == 0 Fill the buffer, then goto + * ssl2_read_again. + */ + + if (s->rstate == SSL_ST_READ_HEADER) { + if (s->first_packet) { + n = read_n(s, 5, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); + if (n <= 0) + return (n); /* error or non-blocking */ + s->first_packet = 0; + p = s->packet; + if (!((p[0] & 0x80) && ((p[2] == SSL2_MT_CLIENT_HELLO) || + (p[2] == SSL2_MT_SERVER_HELLO)))) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, + SSL_R_NON_SSLV2_INITIAL_PACKET); + return (-1); + } + } else { + n = read_n(s, 2, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); + if (n <= 0) + return (n); /* error or non-blocking */ + } + /* part read stuff */ + + s->rstate = SSL_ST_READ_BODY; + p = s->packet; + /* Do header */ + /* + * s->s2->padding=0; + */ + s->s2->escape = 0; + s->s2->rlength = (((unsigned int)p[0]) << 8) | ((unsigned int)p[1]); + if ((p[0] & TWO_BYTE_BIT)) { /* Two byte header? */ + s->s2->three_byte_header = 0; + s->s2->rlength &= TWO_BYTE_MASK; + } else { + s->s2->three_byte_header = 1; + s->s2->rlength &= THREE_BYTE_MASK; + + /* security >s2->escape */ + s->s2->escape = ((p[0] & SEC_ESC_BIT)) ? 1 : 0; + } + } + + if (s->rstate == SSL_ST_READ_BODY) { + n = s->s2->rlength + 2 + s->s2->three_byte_header; + if (n > (int)s->packet_length) { + n -= s->packet_length; + i = read_n(s, (unsigned int)n, (unsigned int)n, 1); + if (i <= 0) + return (i); /* ERROR */ + } + + p = &(s->packet[2]); + s->rstate = SSL_ST_READ_HEADER; + if (s->s2->three_byte_header) + s->s2->padding = *(p++); + else + s->s2->padding = 0; + + /* Data portion */ + if (s->s2->clear_text) { + mac_size = 0; + s->s2->mac_data = p; + s->s2->ract_data = p; + if (s->s2->padding) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); + return (-1); + } + } else { + mac_size = EVP_MD_CTX_size(s->read_hash); + if (mac_size < 0) + return -1; + OPENSSL_assert(mac_size <= MAX_MAC_SIZE); + s->s2->mac_data = p; + s->s2->ract_data = &p[mac_size]; + if (s->s2->padding + mac_size > s->s2->rlength) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); + return (-1); + } + } + + s->s2->ract_data_length = s->s2->rlength; + /* + * added a check for length > max_size in case encryption was not + * turned on yet due to an error + */ + if ((!s->s2->clear_text) && + (s->s2->rlength >= (unsigned int)mac_size)) { + if (!ssl2_enc(s, 0)) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_DECRYPTION_FAILED); + return (-1); + } + s->s2->ract_data_length -= mac_size; + ssl2_mac(s, mac, 0); + s->s2->ract_data_length -= s->s2->padding; + if ((CRYPTO_memcmp(mac, s->s2->mac_data, mac_size) != 0) || + (s->s2->rlength % + EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_MAC_DECODE); + return (-1); + } + } + INC32(s->s2->read_sequence); /* expect next number */ + /* s->s2->ract_data is now available for processing */ + + /* + * Possibly the packet that we just read had 0 actual data bytes. + * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.) + * In this case, returning 0 would be interpreted by the caller as + * indicating EOF, so it's not a good idea. Instead, we just + * continue reading; thus ssl2_read_internal may have to process + * multiple packets before it can return. [Note that using select() + * for blocking sockets *never* guarantees that the next SSL_read + * will not block -- the available data may contain incomplete + * packets, and except for SSL 2, renegotiation can confuse things + * even more.] + */ + + goto ssl2_read_again; /* This should really be "return + * ssl2_read(s,buf,len)", but that would + * allow for denial-of-service attacks if a C + * compiler is used that does not recognize + * end-recursion. */ + } else { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_STATE); + return (-1); + } +} + +int ssl2_read(SSL *s, void *buf, int len) +{ + return ssl2_read_internal(s, buf, len, 0); +} + +int ssl2_peek(SSL *s, void *buf, int len) +{ + return ssl2_read_internal(s, buf, len, 1); +} + +/* + * Return values are as per SSL_read() + */ +static int read_n(SSL *s, unsigned int n, unsigned int max, + unsigned int extend) +{ + int i, off, newb; + + /* + * if there is stuff still in the buffer from a previous read, and there + * is more than we want, take some. + */ + if (s->s2->rbuf_left >= (int)n) { + if (extend) + s->packet_length += n; + else { + s->packet = &(s->s2->rbuf[s->s2->rbuf_offs]); + s->packet_length = n; + } + s->s2->rbuf_left -= n; + s->s2->rbuf_offs += n; + return (n); + } + + if (!s->read_ahead) + max = n; + if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) + max = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2; + + /* + * Else we want more than we have. First, if there is some left or we + * want to extend + */ + off = 0; + if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend)) { + newb = s->s2->rbuf_left; + if (extend) { + off = s->packet_length; + if (s->packet != s->s2->rbuf) + memcpy(s->s2->rbuf, s->packet, (unsigned int)newb + off); + } else if (s->s2->rbuf_offs != 0) { + memcpy(s->s2->rbuf, &(s->s2->rbuf[s->s2->rbuf_offs]), + (unsigned int)newb); + s->s2->rbuf_offs = 0; + } + s->s2->rbuf_left = 0; + } else + newb = 0; + + /* + * off is the offset to start writing too. r->s2->rbuf_offs is the + * 'unread data', now 0. newb is the number of new bytes so far + */ + s->packet = s->s2->rbuf; + while (newb < (int)n) { + clear_sys_error(); + if (s->rbio != NULL) { + s->rwstate = SSL_READING; + i = BIO_read(s->rbio, (char *)&(s->s2->rbuf[off + newb]), + max - newb); + } else { + SSLerr(SSL_F_READ_N, SSL_R_READ_BIO_NOT_SET); + i = -1; + } +# ifdef PKT_DEBUG + if (s->debug & 0x01) + sleep(1); +# endif + if (i <= 0) { + s->s2->rbuf_left += newb; + return i; + } + newb += i; + } + + /* record unread data */ + if (newb > (int)n) { + s->s2->rbuf_offs = n + off; + s->s2->rbuf_left = newb - n; + } else { + s->s2->rbuf_offs = 0; + s->s2->rbuf_left = 0; + } + if (extend) + s->packet_length += n; + else + s->packet_length = n; + s->rwstate = SSL_NOTHING; + return (n); +} + +int ssl2_write(SSL *s, const void *_buf, int len) +{ + const unsigned char *buf = _buf; + unsigned int n, tot; + int i; + + if (SSL_in_init(s) && !s->in_handshake) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL2_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + + if (s->error) { + ssl2_write_error(s); + if (s->error) + return (-1); + } + + clear_sys_error(); + s->rwstate = SSL_NOTHING; + if (len <= 0) + return (len); + + tot = s->s2->wnum; + s->s2->wnum = 0; + + n = (len - tot); + for (;;) { + i = n_do_ssl_write(s, &(buf[tot]), n); + if (i <= 0) { + s->s2->wnum = tot; + return (i); + } + if ((i == (int)n) || (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { + return (tot + i); + } + + n -= i; + tot += i; + } +} + +/* + * Return values are as per SSL_write() + */ +static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) +{ + int i; + + /* s->s2->wpend_len != 0 MUST be true. */ + + /* + * check that they have given us the same buffer to write + */ + if ((s->s2->wpend_tot > (int)len) || + ((s->s2->wpend_buf != buf) && + !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))) { + SSLerr(SSL_F_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); + return (-1); + } + + for (;;) { + clear_sys_error(); + if (s->wbio != NULL) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, + (char *)&(s->s2->write_ptr[s->s2->wpend_off]), + (unsigned int)s->s2->wpend_len); + } else { + SSLerr(SSL_F_WRITE_PENDING, SSL_R_WRITE_BIO_NOT_SET); + i = -1; + } +# ifdef PKT_DEBUG + if (s->debug & 0x01) + sleep(1); +# endif + if (i == s->s2->wpend_len) { + s->s2->wpend_len = 0; + s->rwstate = SSL_NOTHING; + return (s->s2->wpend_ret); + } else if (i <= 0) + return i; + s->s2->wpend_off += i; + s->s2->wpend_len -= i; + } +} + +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) +{ + unsigned int j, k, olen, p, bs; + int mac_size; + register unsigned char *pp; + + olen = len; + + /* + * first check if there is data from an encryption waiting to be sent - + * it must be sent because the other end is waiting. This will happen + * with non-blocking IO. We print it and then return. + */ + if (s->s2->wpend_len != 0) + return (write_pending(s, buf, len)); + + /* set mac_size to mac size */ + if (s->s2->clear_text) + mac_size = 0; + else { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + return -1; + } + + /* lets set the pad p */ + if (s->s2->clear_text) { + if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) + len = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; + p = 0; + s->s2->three_byte_header = 0; + /* len=len; */ + } else { + bs = EVP_CIPHER_CTX_block_size(s->enc_read_ctx); + j = len + mac_size; + /* + * Two-byte headers allow for a larger record length than three-byte + * headers, but we can't use them if we need padding or if we have to + * set the escape bit. + */ + if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) && (!s->s2->escape)) { + if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) + j = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; + /* + * set k to the max number of bytes with 2 byte header + */ + k = j - (j % bs); + /* how many data bytes? */ + len = k - mac_size; + s->s2->three_byte_header = 0; + p = 0; + } else if ((bs <= 1) && (!s->s2->escape)) { + /*- + * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus + * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + */ + s->s2->three_byte_header = 0; + p = 0; + } else { /* we may have to use a 3 byte header */ + + /*- + * If s->s2->escape is not set, then + * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus + * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. + */ + p = (j % bs); + p = (p == 0) ? 0 : (bs - p); + if (s->s2->escape) { + s->s2->three_byte_header = 1; + if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) + j = SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER; + } else + s->s2->three_byte_header = (p == 0) ? 0 : 1; + } + } + + /*- + * Now + * j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + * holds, and if s->s2->three_byte_header is set, then even + * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER. + */ + + /* + * mac_size is the number of MAC bytes len is the number of data bytes we + * are going to send p is the number of padding bytes (if it is a + * two-byte header, then p == 0) + */ + + s->s2->wlength = len; + s->s2->padding = p; + s->s2->mac_data = &(s->s2->wbuf[3]); + s->s2->wact_data = &(s->s2->wbuf[3 + mac_size]); + + /* + * It would be clearer to write this as follows: + * if (mac_size + len + p > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) + * However |len| is user input that could in theory be very large. We + * know |mac_size| and |p| are small, so to avoid any possibility of + * overflow we write it like this. + * + * In theory this should never fail because the logic above should have + * modified |len| if it is too big. But we are being cautious. + */ + if (len > (SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - (mac_size + p))) { + return -1; + } + /* we copy the data into s->s2->wbuf */ + memcpy(s->s2->wact_data, buf, len); + if (p) + memset(&(s->s2->wact_data[len]), 0, p); /* arbitrary padding */ + + if (!s->s2->clear_text) { + s->s2->wact_data_length = len + p; + ssl2_mac(s, s->s2->mac_data, 1); + s->s2->wlength += p + mac_size; + if (ssl2_enc(s, 1) < 1) + return -1; + } + + /* package up the header */ + s->s2->wpend_len = s->s2->wlength; + if (s->s2->three_byte_header) { /* 3 byte header */ + pp = s->s2->mac_data; + pp -= 3; + pp[0] = (s->s2->wlength >> 8) & (THREE_BYTE_MASK >> 8); + if (s->s2->escape) + pp[0] |= SEC_ESC_BIT; + pp[1] = s->s2->wlength & 0xff; + pp[2] = s->s2->padding; + s->s2->wpend_len += 3; + } else { + pp = s->s2->mac_data; + pp -= 2; + pp[0] = ((s->s2->wlength >> 8) & (TWO_BYTE_MASK >> 8)) | TWO_BYTE_BIT; + pp[1] = s->s2->wlength & 0xff; + s->s2->wpend_len += 2; + } + s->s2->write_ptr = pp; + + INC32(s->s2->write_sequence); /* expect next number */ + + /* lets try to actually write the data */ + s->s2->wpend_tot = olen; + s->s2->wpend_buf = buf; + + s->s2->wpend_ret = len; + + s->s2->wpend_off = 0; + return (write_pending(s, buf, olen)); +} + +int ssl2_part_read(SSL *s, unsigned long f, int i) +{ + unsigned char *p; + int j; + + if (i < 0) { + /* ssl2_return_error(s); */ + /* + * for non-blocking io, this is not necessarily fatal + */ + return (i); + } else { + s->init_num += i; + + /* + * Check for error. While there are recoverable errors, this + * function is not called when those must be expected; any error + * detected here is fatal. + */ + if (s->init_num >= 3) { + p = (unsigned char *)s->init_buf->data; + if (p[0] == SSL2_MT_ERROR) { + j = (p[1] << 8) | p[2]; + SSLerr((int)f, ssl_mt_error(j)); + s->init_num -= 3; + if (s->init_num > 0) + memmove(p, p + 3, s->init_num); + } + } + + /* + * If it's not an error message, we have some error anyway -- the + * message was shorter than expected. This too is treated as fatal + * (at least if SSL_get_error is asked for its opinion). + */ + return (0); + } +} + +int ssl2_do_write(SSL *s) +{ + int ret; + + ret = ssl2_write(s, &s->init_buf->data[s->init_off], s->init_num); + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, 0, s->init_buf->data, + (size_t)(s->init_off + s->init_num), s, + s->msg_callback_arg); + return (1); + } + if (ret < 0) + return (-1); + s->init_off += ret; + s->init_num -= ret; + return (0); +} + +static int ssl_mt_error(int n) +{ + int ret; + + switch (n) { + case SSL2_PE_NO_CIPHER: + ret = SSL_R_PEER_ERROR_NO_CIPHER; + break; + case SSL2_PE_NO_CERTIFICATE: + ret = SSL_R_PEER_ERROR_NO_CERTIFICATE; + break; + case SSL2_PE_BAD_CERTIFICATE: + ret = SSL_R_PEER_ERROR_CERTIFICATE; + break; + case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE: + ret = SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; + break; + default: + ret = SSL_R_UNKNOWN_REMOTE_ERROR_TYPE; + break; + } + return (ret); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif +/* ssl/s2_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +#include "constant_time_locl.h" +# include +# include "bio.h" +# include "rand.h" +# include "objects.h" +# include "evp.h" + +static const SSL_METHOD *ssl2_get_server_method(int ver); +static int get_client_master_key(SSL *s); +static int get_client_hello(SSL *s); +static int server_hello(SSL *s); +static int get_client_finished(SSL *s); +static int server_verify(SSL *s); +static int server_finish(SSL *s); +static int request_certificate(SSL *s); +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, + unsigned char *to, int padding); +# define BREAK break + +static const SSL_METHOD *ssl2_get_server_method(int ver) +{ + if (ver == SSL2_VERSION) + return (SSLv2_server_method()); + else + return (NULL); +} + +IMPLEMENT_ssl2_meth_func(SSLv2_server_method, + ssl2_accept, + ssl_undefined_function, ssl2_get_server_method) + +int ssl2_accept(SSL *s) +{ + unsigned long l = (unsigned long)time(NULL); + BUF_MEM *buf = NULL; + int ret = -1; + long num1; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int new_state, state; + + RAND_add(&l, sizeof(l), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + if (s->cert == NULL) { + SSLerr(SSL_F_SSL2_ACCEPT, SSL_R_NO_CERTIFICATE_SET); + return (-1); + } + + clear_sys_error(); + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + case SSL_ST_OK | SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + s->version = SSL2_VERSION; + s->type = SSL_ST_ACCEPT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + goto end; + } + if (!BUF_MEM_grow + (buf, (int)SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + BUF_MEM_free(buf); + ret = -1; + goto end; + } + s->init_buf = buf; + } + s->init_num = 0; + s->ctx->stats.sess_accept++; + s->handshake_func = ssl2_accept; + s->state = SSL2_ST_GET_CLIENT_HELLO_A; + BREAK; + + case SSL2_ST_GET_CLIENT_HELLO_A: + case SSL2_ST_GET_CLIENT_HELLO_B: + case SSL2_ST_GET_CLIENT_HELLO_C: + s->shutdown = 0; + ret = get_client_hello(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_SEND_SERVER_HELLO_A; + BREAK; + + case SSL2_ST_SEND_SERVER_HELLO_A: + case SSL2_ST_SEND_SERVER_HELLO_B: + ret = server_hello(s); + if (ret <= 0) + goto end; + s->init_num = 0; + if (!s->hit) { + s->state = SSL2_ST_GET_CLIENT_MASTER_KEY_A; + BREAK; + } else { + s->state = SSL2_ST_SERVER_START_ENCRYPTION; + BREAK; + } + case SSL2_ST_GET_CLIENT_MASTER_KEY_A: + case SSL2_ST_GET_CLIENT_MASTER_KEY_B: + ret = get_client_master_key(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_SERVER_START_ENCRYPTION; + BREAK; + + case SSL2_ST_SERVER_START_ENCRYPTION: + /* + * Ok we how have sent all the stuff needed to start encrypting, + * the next packet back will be encrypted. + */ + if (!ssl2_enc_init(s, 0)) { + ret = -1; + goto end; + } + s->s2->clear_text = 0; + s->state = SSL2_ST_SEND_SERVER_VERIFY_A; + BREAK; + + case SSL2_ST_SEND_SERVER_VERIFY_A: + case SSL2_ST_SEND_SERVER_VERIFY_B: + ret = server_verify(s); + if (ret <= 0) + goto end; + s->init_num = 0; + if (s->hit) { + /* + * If we are in here, we have been buffering the output, so + * we need to flush it and remove buffering from future + * traffic + */ + s->state = SSL2_ST_SEND_SERVER_VERIFY_C; + BREAK; + } else { + s->state = SSL2_ST_GET_CLIENT_FINISHED_A; + break; + } + + case SSL2_ST_SEND_SERVER_VERIFY_C: + /* get the number of bytes to write */ + num1 = BIO_ctrl(s->wbio, BIO_CTRL_INFO, 0, NULL); + if (num1 > 0) { + s->rwstate = SSL_WRITING; + num1 = BIO_flush(s->wbio); + if (num1 <= 0) { + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + } + + /* flushed and now remove buffering */ + s->wbio = BIO_pop(s->wbio); + + s->state = SSL2_ST_GET_CLIENT_FINISHED_A; + BREAK; + + case SSL2_ST_GET_CLIENT_FINISHED_A: + case SSL2_ST_GET_CLIENT_FINISHED_B: + ret = get_client_finished(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_A; + BREAK; + + case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: + case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: + case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: + case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: + /* + * don't do a 'request certificate' if we don't want to, or we + * already have one, and we only want to do it once. + */ + if (!(s->verify_mode & SSL_VERIFY_PEER) || + ((s->session->peer != NULL) && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE))) { + s->state = SSL2_ST_SEND_SERVER_FINISHED_A; + break; + } else { + ret = request_certificate(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_SEND_SERVER_FINISHED_A; + } + BREAK; + + case SSL2_ST_SEND_SERVER_FINISHED_A: + case SSL2_ST_SEND_SERVER_FINISHED_B: + ret = server_finish(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL_ST_OK; + break; + + case SSL_ST_OK: + BUF_MEM_free(s->init_buf); + ssl_free_wbio_buffer(s); + s->init_buf = NULL; + s->init_num = 0; + /* ERR_clear_error(); */ + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + ret = 1; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + goto end; + /* BREAK; */ + + default: + SSLerr(SSL_F_SSL2_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* BREAK; */ + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + end: + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +static int get_client_master_key(SSL *s) +{ + int is_export, i, n, keya; + unsigned int num_encrypted_key_bytes, key_length; + unsigned long len; + unsigned char *p; + const SSL_CIPHER *cp; + const EVP_CIPHER *c; + const EVP_MD *md; + unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + unsigned char decrypt_good; + size_t j; + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A) { + i = ssl2_read(s, (char *)&(p[s->init_num]), 10 - s->init_num); + + if (i < (10 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_MASTER_KEY, i)); + s->init_num = 10; + + if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY) { + if (p[-1] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, + SSL_R_READ_WRONG_PACKET_TYPE); + } else + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR); + return (-1); + } + + cp = ssl2_get_cipher_by_char(p); + if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); + return (-1); + } + s->session->cipher = cp; + + p += 3; + n2s(p, i); + s->s2->tmp.clear = i; + n2s(p, i); + s->s2->tmp.enc = i; + n2s(p, i); + if (i > SSL_MAX_KEY_ARG_LENGTH) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); + return -1; + } + s->session->key_arg_length = i; + s->state = SSL2_ST_GET_CLIENT_MASTER_KEY_B; + } + + /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */ + p = (unsigned char *)s->init_buf->data; + if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + keya = s->session->key_arg_length; + len = + 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + + (unsigned long)keya; + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_MESSAGE_TOO_LONG); + return -1; + } + n = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), n); + if (i != n) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_MASTER_KEY, i)); + if (s->msg_callback) { + /* CLIENT-MASTER-KEY */ + s->msg_callback(0, s->version, 0, p, (size_t)len, s, + s->msg_callback_arg); + } + p += 10; + + memcpy(s->session->key_arg, &(p[s->s2->tmp.clear + s->s2->tmp.enc]), + (unsigned int)keya); + + if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_PRIVATEKEY); + return (-1); + } + + is_export = SSL_C_IS_EXPORT(s->session->cipher); + + if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, + SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); + return (0); + } + + /* + * The format of the CLIENT-MASTER-KEY message is + * 1 byte message type + * 3 bytes cipher + * 2-byte clear key length (stored in s->s2->tmp.clear) + * 2-byte encrypted key length (stored in s->s2->tmp.enc) + * 2-byte key args length (IV etc) + * clear key + * encrypted key + * key args + * + * If the cipher is an export cipher, then the encrypted key bytes + * are a fixed portion of the total key (5 or 8 bytes). The size of + * this portion is in |num_encrypted_key_bytes|. If the cipher is not an + * export cipher, then the entire key material is encrypted (i.e., clear + * key length must be zero). + */ + key_length = (unsigned int)EVP_CIPHER_key_length(c); + if (key_length > SSL_MAX_MASTER_KEY_LENGTH) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) { + is_export = 1; + num_encrypted_key_bytes = 8; + } else if (is_export) { + num_encrypted_key_bytes = 5; + } else { + num_encrypted_key_bytes = key_length; + } + + if (s->s2->tmp.clear + num_encrypted_key_bytes != key_length) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH); + return -1; + } + /* + * The encrypted blob must decrypt to the encrypted portion of the key. + * Decryption can't be expanding, so if we don't have enough encrypted + * bytes to fit the key in the buffer, stop now. + */ + if (s->s2->tmp.enc < num_encrypted_key_bytes) { + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT); + return -1; + } + + /* + * We must not leak whether a decryption failure occurs because of + * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). The code follows that advice of the TLS RFC and + * generates a random premaster secret for the case that the decrypt + * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 + */ + + if (RAND_bytes(rand_premaster_secret, + (int)num_encrypted_key_bytes) <= 0) + return 0; + + i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, + &(p[s->s2->tmp.clear]), + &(p[s->s2->tmp.clear]), + (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING : + RSA_PKCS1_PADDING); + ERR_clear_error(); + /* + * If a bad decrypt, continue with protocol but with a random master + * secret (Bleichenbacher attack) + */ + decrypt_good = constant_time_eq_int_8(i, (int)num_encrypted_key_bytes); + for (j = 0; j < num_encrypted_key_bytes; j++) { + p[s->s2->tmp.clear + j] = + constant_time_select_8(decrypt_good, p[s->s2->tmp.clear + j], + rand_premaster_secret[j]); + } + + s->session->master_key_length = (int)key_length; + memcpy(s->session->master_key, p, key_length); + OPENSSL_cleanse(p, key_length); + + return 1; +} + +static int get_client_hello(SSL *s) +{ + int i, n; + unsigned long len; + unsigned char *p; + STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */ + STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */ + STACK_OF(SSL_CIPHER) *prio, *allow; + int z; + + /* + * This is a bit of a hack to check for the correct packet type the first + * time round. + */ + if (s->state == SSL2_ST_GET_CLIENT_HELLO_A) { + s->first_packet = 1; + s->state = SSL2_ST_GET_CLIENT_HELLO_B; + } + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_GET_CLIENT_HELLO_B) { + i = ssl2_read(s, (char *)&(p[s->init_num]), 9 - s->init_num); + if (i < (9 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_HELLO, i)); + s->init_num = 9; + + if (*(p++) != SSL2_MT_CLIENT_HELLO) { + if (p[-1] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_READ_WRONG_PACKET_TYPE); + } else + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_PEER_ERROR); + return (-1); + } + n2s(p, i); + if (i < s->version) + s->version = i; + n2s(p, i); + s->s2->tmp.cipher_spec_length = i; + n2s(p, i); + s->s2->tmp.session_id_length = i; + if ((i < 0) || (i > SSL_MAX_SSL_SESSION_ID_LENGTH)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + return -1; + } + n2s(p, i); + s->s2->challenge_length = i; + if ((i < SSL2_MIN_CHALLENGE_LENGTH) || + (i > SSL2_MAX_CHALLENGE_LENGTH)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_INVALID_CHALLENGE_LENGTH); + return (-1); + } + s->state = SSL2_ST_GET_CLIENT_HELLO_C; + } + + /* SSL2_ST_GET_CLIENT_HELLO_C */ + p = (unsigned char *)s->init_buf->data; + len = + 9 + (unsigned long)s->s2->tmp.cipher_spec_length + + (unsigned long)s->s2->challenge_length + + (unsigned long)s->s2->tmp.session_id_length; + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_MESSAGE_TOO_LONG); + return -1; + } + n = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), n); + if (i != n) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_HELLO, i)); + if (s->msg_callback) { + /* CLIENT-HELLO */ + s->msg_callback(0, s->version, 0, p, (size_t)len, s, + s->msg_callback_arg); + } + p += 9; + + /* + * get session-id before cipher stuff so we can get out session structure + * if it is cached + */ + /* session-id */ + if ((s->s2->tmp.session_id_length != 0) && + (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_BAD_SSL_SESSION_ID_LENGTH); + return (-1); + } + + if (s->s2->tmp.session_id_length == 0) { + if (!ssl_get_new_session(s, 1)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } else { + i = ssl_get_prev_session(s, &(p[s->s2->tmp.cipher_spec_length]), + s->s2->tmp.session_id_length, NULL); + if (i == 1) { /* previous session */ + s->hit = 1; + } else if (i == -1) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } else { + if (s->cert == NULL) { + ssl2_return_error(s, SSL2_PE_NO_CERTIFICATE); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CERTIFICATE_SET); + return (-1); + } + + if (!ssl_get_new_session(s, 1)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } + } + + if (!s->hit) { + cs = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.cipher_spec_length, + &s->session->ciphers); + if (cs == NULL) + goto mem_err; + + cl = SSL_get_ciphers(s); + + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = sk_SSL_CIPHER_dup(cl); + if (prio == NULL) + goto mem_err; + allow = cs; + } else { + prio = cs; + allow = cl; + } + + /* Generate list of SSLv2 ciphers shared between client and server */ + for (z = 0; z < sk_SSL_CIPHER_num(prio); z++) { + const SSL_CIPHER *cp = sk_SSL_CIPHER_value(prio, z); + if ((cp->algorithm_ssl & SSL_SSLV2) == 0 || + sk_SSL_CIPHER_find(allow, cp) < 0) { + (void)sk_SSL_CIPHER_delete(prio, z); + z--; + } + } + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = prio; + } + + /* Make sure we have at least one cipher in common */ + if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH); + return -1; + } + /* + * s->session->ciphers should now have a list of ciphers that are on + * both the client and server. This list is ordered by the order the + * client sent the ciphers or in the order of the server's preference + * if SSL_OP_CIPHER_SERVER_PREFERENCE was set. + */ + } + p += s->s2->tmp.cipher_spec_length; + /* done cipher selection */ + + /* session id extracted already */ + p += s->s2->tmp.session_id_length; + + /* challenge */ + if (s->s2->challenge_length > sizeof(s->s2->challenge)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(s->s2->challenge, p, (unsigned int)s->s2->challenge_length); + return (1); + mem_err: + SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_MALLOC_FAILURE); + return (0); +} + +static int server_hello(SSL *s) +{ + unsigned char *p, *d; + int n, hit; + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_SEND_SERVER_HELLO_A) { + d = p + 11; + *(p++) = SSL2_MT_SERVER_HELLO; /* type */ + hit = s->hit; + *(p++) = (unsigned char)hit; +# if 1 + if (!hit) { + if (s->session->sess_cert != NULL) + /* + * This can't really happen because get_client_hello has + * called ssl_get_new_session, which does not set sess_cert. + */ + ssl_sess_cert_free(s->session->sess_cert); + s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) { + SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE); + return (-1); + } + } + /* + * If 'hit' is set, then s->sess_cert may be non-NULL or NULL, + * depending on whether it survived in the internal cache or was + * retrieved from an external cache. If it is NULL, we cannot put any + * useful data in it anyway, so we don't touch it. + */ + +# else /* That's what used to be done when cert_st + * and sess_cert_st were * the same. */ + if (!hit) { /* else add cert to session */ + CRYPTO_add(&s->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + if (s->session->sess_cert != NULL) + ssl_cert_free(s->session->sess_cert); + s->session->sess_cert = s->cert; + } else { /* We have a session id-cache hit, if the * + * session-id has no certificate listed + * against * the 'cert' structure, grab the + * 'old' one * listed against the SSL + * connection */ + if (s->session->sess_cert == NULL) { + CRYPTO_add(&s->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + s->session->sess_cert = s->cert; + } + } +# endif + + if (s->cert == NULL) { + ssl2_return_error(s, SSL2_PE_NO_CERTIFICATE); + SSLerr(SSL_F_SERVER_HELLO, SSL_R_NO_CERTIFICATE_SPECIFIED); + return (-1); + } + + if (hit) { + *(p++) = 0; /* no certificate type */ + s2n(s->version, p); /* version */ + s2n(0, p); /* cert len */ + s2n(0, p); /* ciphers len */ + } else { + /* EAY EAY */ + /* put certificate type */ + *(p++) = SSL2_CT_X509_CERTIFICATE; + s2n(s->version, p); /* version */ + n = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, NULL); + s2n(n, p); /* certificate length */ + i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, &d); + n = 0; + + /* + * lets send out the ciphers we like in the prefered order + */ + n = ssl_cipher_list_to_bytes(s, s->session->ciphers, d, 0); + d += n; + s2n(n, p); /* add cipher length */ + } + + /* make and send conn_id */ + s2n(SSL2_CONNECTION_ID_LENGTH, p); /* add conn_id length */ + s->s2->conn_id_length = SSL2_CONNECTION_ID_LENGTH; + if (RAND_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= 0) + return -1; + memcpy(d, s->s2->conn_id, SSL2_CONNECTION_ID_LENGTH); + d += SSL2_CONNECTION_ID_LENGTH; + + s->state = SSL2_ST_SEND_SERVER_HELLO_B; + s->init_num = d - (unsigned char *)s->init_buf->data; + s->init_off = 0; + } + /* SSL2_ST_SEND_SERVER_HELLO_B */ + /* + * If we are using TCP/IP, the performance is bad if we do 2 writes + * without a read between them. This occurs when Session-id reuse is + * used, so I will put in a buffering module + */ + if (s->hit) { + if (!ssl_init_wbio_buffer(s, 1)) + return (-1); + } + + return (ssl2_do_write(s)); +} + +static int get_client_finished(SSL *s) +{ + unsigned char *p; + int i, n; + unsigned long len; + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A) { + i = ssl2_read(s, (char *)&(p[s->init_num]), 1 - s->init_num); + if (i < 1 - s->init_num) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_FINISHED, i)); + s->init_num += i; + + if (*p != SSL2_MT_CLIENT_FINISHED) { + if (*p != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_FINISHED, + SSL_R_READ_WRONG_PACKET_TYPE); + } else { + SSLerr(SSL_F_GET_CLIENT_FINISHED, SSL_R_PEER_ERROR); + /* try to read the error message */ + i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); + return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); + } + return (-1); + } + s->state = SSL2_ST_GET_CLIENT_FINISHED_B; + } + + /* SSL2_ST_GET_CLIENT_FINISHED_B */ + if (s->s2->conn_id_length > sizeof(s->s2->conn_id)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); + return -1; + } + len = 1 + (unsigned long)s->s2->conn_id_length; + n = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), n); + if (i < n) { + return (ssl2_part_read(s, SSL_F_GET_CLIENT_FINISHED, i)); + } + if (s->msg_callback) { + /* CLIENT-FINISHED */ + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); + } + p += 1; + if (memcmp(p, s->s2->conn_id, s->s2->conn_id_length) != 0) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_FINISHED, SSL_R_CONNECTION_ID_IS_DIFFERENT); + return (-1); + } + return (1); +} + +static int server_verify(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL2_MT_SERVER_VERIFY; + if (s->s2->challenge_length > sizeof(s->s2->challenge)) { + SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(p, s->s2->challenge, (unsigned int)s->s2->challenge_length); + /* p+=s->s2->challenge_length; */ + + s->state = SSL2_ST_SEND_SERVER_VERIFY_B; + s->init_num = s->s2->challenge_length + 1; + s->init_off = 0; + } + return (ssl2_do_write(s)); +} + +static int server_finish(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL2_MT_SERVER_FINISHED; + + if (s->session->session_id_length > sizeof(s->session->session_id)) { + SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(p, s->session->session_id, + (unsigned int)s->session->session_id_length); + /* p+=s->session->session_id_length; */ + + s->state = SSL2_ST_SEND_SERVER_FINISHED_B; + s->init_num = s->session->session_id_length + 1; + s->init_off = 0; + } + + /* SSL2_ST_SEND_SERVER_FINISHED_B */ + return (ssl2_do_write(s)); +} + +/* send the request and check the response */ +static int request_certificate(SSL *s) +{ + const unsigned char *cp; + unsigned char *p, *p2, *buf2; + unsigned char *ccd; + int i, j, ctype, ret = -1; + unsigned long len; + X509 *x509 = NULL; + STACK_OF(X509) *sk = NULL; + + ccd = s->s2->tmp.ccl; + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL2_MT_REQUEST_CERTIFICATE; + *(p++) = SSL2_AT_MD5_WITH_RSA_ENCRYPTION; + if (RAND_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) + return -1; + memcpy(p, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH); + + s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_B; + s->init_num = SSL2_MIN_CERT_CHALLENGE_LENGTH + 2; + s->init_off = 0; + } + + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B) { + i = ssl2_do_write(s); + if (i <= 0) { + ret = i; + goto end; + } + + s->init_num = 0; + s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_C; + } + + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C) { + p = (unsigned char *)s->init_buf->data; + /* try to read 6 octets ... */ + i = ssl2_read(s, (char *)&(p[s->init_num]), 6 - s->init_num); + /* + * ... but don't call ssl2_part_read now if we got at least 3 + * (probably NO-CERTIFICATE-ERROR) + */ + if (i < 3 - s->init_num) { + ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, i); + goto end; + } + s->init_num += i; + + if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR)) { + n2s(p, i); + if (i != SSL2_PE_NO_CERTIFICATE) { + /* + * not the error message we expected -- let ssl2_part_read + * handle it + */ + s->init_num -= 3; + ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, 3); + goto end; + } + + if (s->msg_callback) { + /* ERROR */ + s->msg_callback(0, s->version, 0, p, 3, s, + s->msg_callback_arg); + } + + /* + * this is the one place where we can recover from an SSL 2.0 + * error + */ + + if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); + SSLerr(SSL_F_REQUEST_CERTIFICATE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + goto end; + } + ret = 1; + goto end; + } + if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_SHORT_READ); + goto end; + } + if (s->init_num != 6) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR); + goto end; + } + + /* ok we have a response */ + /* certificate type, there is only one right now. */ + ctype = *(p++); + if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { + ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); + SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_BAD_RESPONSE_ARGUMENT); + goto end; + } + n2s(p, i); + s->s2->tmp.clen = i; + n2s(p, i); + s->s2->tmp.rlen = i; + s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_D; + } + + /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */ + p = (unsigned char *)s->init_buf->data; + len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen; + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_MESSAGE_TOO_LONG); + goto end; + } + j = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), j); + if (i < j) { + ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, i); + goto end; + } + if (s->msg_callback) { + /* CLIENT-CERTIFICATE */ + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); + } + p += 6; + + cp = p; + x509 = (X509 *)d2i_X509(NULL, &cp, (long)s->s2->tmp.clen); + if (x509 == NULL) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_X509_LIB); + goto msg_end; + } + + if (((sk = sk_X509_new_null()) == NULL) || (!sk_X509_push(sk, x509))) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto msg_end; + } + + i = ssl_verify_cert_chain(s, sk); + + if (i > 0) { /* we like the packet, now check the chksum */ + EVP_MD_CTX ctx; + EVP_PKEY *pkey = NULL; + + EVP_MD_CTX_init(&ctx); + if (!EVP_VerifyInit_ex(&ctx, s->ctx->rsa_md5, NULL) + || !EVP_VerifyUpdate(&ctx, s->s2->key_material, + s->s2->key_material_length) + || !EVP_VerifyUpdate(&ctx, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH)) + goto msg_end; + + i = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, NULL); + buf2 = OPENSSL_malloc((unsigned int)i); + if (buf2 == NULL) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto msg_end; + } + p2 = buf2; + i = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, &p2); + if (!EVP_VerifyUpdate(&ctx, buf2, (unsigned int)i)) { + OPENSSL_free(buf2); + goto msg_end; + } + OPENSSL_free(buf2); + + pkey = X509_get_pubkey(x509); + if (pkey == NULL) + goto end; + i = EVP_VerifyFinal(&ctx, cp, s->s2->tmp.rlen, pkey); + EVP_PKEY_free(pkey); + EVP_MD_CTX_cleanup(&ctx); + + if (i > 0) { + if (s->session->peer != NULL) + X509_free(s->session->peer); + s->session->peer = x509; + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + s->session->verify_result = s->verify_result; + ret = 1; + goto end; + } else { + SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_BAD_CHECKSUM); + goto msg_end; + } + } else { + msg_end: + ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); + } + end: + sk_X509_free(sk); + X509_free(x509); + return (ret); +} + +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, + unsigned char *to, int padding) +{ + RSA *rsa; + int i; + + if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)) { + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, SSL_R_NO_PRIVATEKEY); + return (-1); + } + if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA) { + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA); + return (-1); + } + rsa = c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa; + + /* we have the public key */ + i = RSA_private_decrypt(len, from, to, rsa, padding); + if (i < 0) + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, ERR_R_RSA_LIB); + return (i); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/Sources/COpenSSL/s3_.c b/Sources/COpenSSL/s3_.c new file mode 100644 index 00000000..45032a05 --- /dev/null +++ b/Sources/COpenSSL/s3_.c @@ -0,0 +1,16474 @@ +/* ssl/s3_both.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include +#include +#include "ssl_locl.h" +#include "buffer.h" +#include "rand.h" +#include "objects.h" +#include "evp.h" +#include "x509.h" + +/* + * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or + * SSL3_RT_CHANGE_CIPHER_SPEC) + */ +int ssl3_do_write(SSL *s, int type) +{ + int ret; + + ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], + s->init_num); + if (ret < 0) + return (-1); + if (type == SSL3_RT_HANDSHAKE) + /* + * should not be done for 'Hello Request's, but in that case we'll + * ignore the result anyway + */ + ssl3_finish_mac(s, (unsigned char *)&s->init_buf->data[s->init_off], + ret); + + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, type, s->init_buf->data, + (size_t)(s->init_off + s->init_num), s, + s->msg_callback_arg); + return (1); + } + s->init_off += ret; + s->init_num -= ret; + return (0); +} + +int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) +{ + unsigned char *p; + int i; + unsigned long l; + + if (s->state == a) { + p = ssl_handshake_start(s); + + i = s->method->ssl3_enc->final_finish_mac(s, + sender, slen, + s->s3->tmp.finish_md); + if (i <= 0) + return 0; + s->s3->tmp.finish_md_len = i; + memcpy(p, s->s3->tmp.finish_md, i); + l = i; + + /* + * Copy the finished so we can use it for renegotiation checks + */ + if (s->type == SSL_ST_CONNECT) { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i); + s->s3->previous_client_finished_len = i; + } else { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i); + s->s3->previous_server_finished_len = i; + } + +#ifdef OPENSSL_SYS_WIN16 + /* + * MSVC 1.5 does not clear the top bytes of the word unless I do + * this. + */ + l &= 0xffff; +#endif + ssl_set_handshake_header(s, SSL3_MT_FINISHED, l); + s->state = b; + } + + /* SSL3_ST_SEND_xxxxxx_HELLO_B */ + return ssl_do_write(s); +} + +#ifndef OPENSSL_NO_NEXTPROTONEG +/* + * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen + * to far. + */ +static void ssl3_take_mac(SSL *s) +{ + const char *sender; + int slen; + /* + * If no new cipher setup return immediately: other functions will set + * the appropriate error. + */ + if (s->s3->tmp.new_cipher == NULL) + return; + if (s->state & SSL_ST_CONNECT) { + sender = s->method->ssl3_enc->server_finished_label; + slen = s->method->ssl3_enc->server_finished_label_len; + } else { + sender = s->method->ssl3_enc->client_finished_label; + slen = s->method->ssl3_enc->client_finished_label_len; + } + + s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, + sender, + slen, + s->s3->tmp.peer_finish_md); +} +#endif + +int ssl3_get_finished(SSL *s, int a, int b) +{ + int al, i, ok; + long n; + unsigned char *p; + +#ifdef OPENSSL_NO_NEXTPROTONEG + /* + * the mac has already been generated when we received the change cipher + * spec message and is in s->s3->tmp.peer_finish_md + */ +#endif + + /* 64 argument should actually be 36+4 :-) */ + n = s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok); + + if (!ok) + return ((int)n); + + /* If this occurs, we have missed a message */ + if (!s->s3->change_cipher_spec) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS); + goto f_err; + } + s->s3->change_cipher_spec = 0; + + p = (unsigned char *)s->init_msg; + i = s->s3->tmp.peer_finish_md_len; + + if (i != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_BAD_DIGEST_LENGTH); + goto f_err; + } + + if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_DIGEST_CHECK_FAILED); + goto f_err; + } + + /* + * Copy the finished so we can use it for renegotiation checks + */ + if (s->type == SSL_ST_ACCEPT) { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, i); + s->s3->previous_client_finished_len = i; + } else { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, i); + s->s3->previous_server_finished_len = i; + } + + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return (0); +} + +/*- + * for these 2 messages, we need to + * ssl->enc_read_ctx re-init + * ssl->s3->read_sequence zero + * ssl->s3->read_mac_secret re-init + * ssl->session->read_sym_enc assign + * ssl->session->read_compression assign + * ssl->session->read_hash assign + */ +int ssl3_send_change_cipher_spec(SSL *s, int a, int b) +{ + unsigned char *p; + + if (s->state == a) { + p = (unsigned char *)s->init_buf->data; + *p = SSL3_MT_CCS; + s->init_num = 1; + s->init_off = 0; + + s->state = b; + } + + /* SSL3_ST_CW_CHANGE_B */ + return (ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); +} + +unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) +{ + unsigned char *p; + unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s); + + if (!ssl_add_cert_chain(s, cpk, &l)) + return 0; + + l -= 3 + SSL_HM_HEADER_LENGTH(s); + p = ssl_handshake_start(s); + l2n3(l, p); + l += 3; + ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l); + return l + SSL_HM_HEADER_LENGTH(s); +} + +/* + * Obtain handshake message of message type 'mt' (any if mt == -1), maximum + * acceptable body length 'max'. The first four bytes (msg_type and length) + * are read in state 'st1', the body is read in state 'stn'. + */ +long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) +{ + unsigned char *p; + unsigned long l; + long n; + int i, al; + + if (s->s3->tmp.reuse_message) { + s->s3->tmp.reuse_message = 0; + if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + *ok = 1; + s->state = stn; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; + s->init_num = (int)s->s3->tmp.message_size; + return s->init_num; + } + + p = (unsigned char *)s->init_buf->data; + + if (s->state == st1) { /* s->init_num < SSL3_HM_HEADER_LENGTH */ + int skip_message; + + do { + while (s->init_num < SSL3_HM_HEADER_LENGTH) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + &p[s->init_num], + SSL3_HM_HEADER_LENGTH - + s->init_num, 0); + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + s->init_num += i; + } + + skip_message = 0; + if (!s->server) + if (p[0] == SSL3_MT_HELLO_REQUEST) + /* + * The server may always send 'Hello Request' messages -- + * we are doing a handshake anyway now, so ignore them if + * their format is correct. Does not count for 'Finished' + * MAC. + */ + if (p[1] == 0 && p[2] == 0 && p[3] == 0) { + s->init_num = 0; + skip_message = 1; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + p, SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); + } + } + while (skip_message); + + /* s->init_num == SSL3_HM_HEADER_LENGTH */ + + if ((mt >= 0) && (*p != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + s->s3->tmp.message_type = *(p++); + + n2l3(p, l); + if (l > (unsigned long)max) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); + goto f_err; + } + /* + * Make buffer slightly larger than message length as a precaution + * against small OOB reads e.g. CVE-2016-6306 + */ + if (l + && !BUF_MEM_grow_clean(s->init_buf, + (int)l + SSL3_HM_HEADER_LENGTH + 16)) { + SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); + goto err; + } + s->s3->tmp.message_size = l; + s->state = stn; + + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; + s->init_num = 0; + } + + /* next state (stn) */ + p = s->init_msg; + n = s->s3->tmp.message_size - s->init_num; + while (n > 0) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], + n, 0); + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + s->init_num += i; + n -= i; + } + +#ifndef OPENSSL_NO_NEXTPROTONEG + /* + * If receiving Finished, record MAC of prior handshake messages for + * Finished verification. + */ + if (*s->init_buf->data == SSL3_MT_FINISHED) + ssl3_take_mac(s); +#endif + + /* Feed this message into MAC computation. */ + ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, + s->init_num + SSL3_HM_HEADER_LENGTH); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); + *ok = 1; + return s->init_num; + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + *ok = 0; + return (-1); +} + +int ssl_cert_type(X509 *x, EVP_PKEY *pkey) +{ + EVP_PKEY *pk; + int ret = -1, i; + + if (pkey == NULL) + pk = X509_get_pubkey(x); + else + pk = pkey; + if (pk == NULL) + goto err; + + i = pk->type; + if (i == EVP_PKEY_RSA) { + ret = SSL_PKEY_RSA_ENC; + } else if (i == EVP_PKEY_DSA) { + ret = SSL_PKEY_DSA_SIGN; + } +#ifndef OPENSSL_NO_EC + else if (i == EVP_PKEY_EC) { + ret = SSL_PKEY_ECC; + } +#endif + else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) { + ret = SSL_PKEY_GOST94; + } else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) { + ret = SSL_PKEY_GOST01; + } else if (x && (i == EVP_PKEY_DH || i == EVP_PKEY_DHX)) { + /* + * For DH two cases: DH certificate signed with RSA and DH + * certificate signed with DSA. + */ + i = X509_certificate_type(x, pk); + if (i & EVP_PKS_RSA) + ret = SSL_PKEY_DH_RSA; + else if (i & EVP_PKS_DSA) + ret = SSL_PKEY_DH_DSA; + } + + err: + if (!pkey) + EVP_PKEY_free(pk); + return (ret); +} + +int ssl_verify_alarm_type(long type) +{ + int al; + + switch (type) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + case X509_V_ERR_UNABLE_TO_GET_CRL: + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + al = SSL_AD_UNKNOWN_CA; + break; + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CRL_NOT_YET_VALID: + case X509_V_ERR_CERT_UNTRUSTED: + case X509_V_ERR_CERT_REJECTED: + case X509_V_ERR_HOSTNAME_MISMATCH: + case X509_V_ERR_EMAIL_MISMATCH: + case X509_V_ERR_IP_ADDRESS_MISMATCH: + al = SSL_AD_BAD_CERTIFICATE; + break; + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + al = SSL_AD_DECRYPT_ERROR; + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_CRL_HAS_EXPIRED: + al = SSL_AD_CERTIFICATE_EXPIRED; + break; + case X509_V_ERR_CERT_REVOKED: + al = SSL_AD_CERTIFICATE_REVOKED; + break; + case X509_V_ERR_UNSPECIFIED: + case X509_V_ERR_OUT_OF_MEM: + case X509_V_ERR_INVALID_CALL: + case X509_V_ERR_STORE_LOOKUP: + al = SSL_AD_INTERNAL_ERROR; + break; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_INVALID_CA: + al = SSL_AD_UNKNOWN_CA; + break; + case X509_V_ERR_APPLICATION_VERIFICATION: + al = SSL_AD_HANDSHAKE_FAILURE; + break; + case X509_V_ERR_INVALID_PURPOSE: + al = SSL_AD_UNSUPPORTED_CERTIFICATE; + break; + default: + al = SSL_AD_CERTIFICATE_UNKNOWN; + break; + } + return (al); +} + +#ifndef OPENSSL_NO_BUF_FREELISTS +/*- + * On some platforms, malloc() performance is bad enough that you can't just + * free() and malloc() buffers all the time, so we need to use freelists from + * unused buffers. Currently, each freelist holds memory chunks of only a + * given size (list->chunklen); other sized chunks are freed and malloced. + * This doesn't help much if you're using many different SSL option settings + * with a given context. (The options affecting buffer size are + * max_send_fragment, read buffer vs write buffer, + * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and + * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.) Using a separate freelist for every + * possible size is not an option, since max_send_fragment can take on many + * different values. + * + * If you are on a platform with a slow malloc(), and you're using SSL + * connections with many different settings for these options, and you need to + * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options: + * - Link against a faster malloc implementation. + * - Use a separate SSL_CTX for each option set. + * - Improve this code. + */ +static void *freelist_extract(SSL_CTX *ctx, int for_read, int sz) +{ + SSL3_BUF_FREELIST *list; + SSL3_BUF_FREELIST_ENTRY *ent = NULL; + void *result = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; + if (list != NULL && sz == (int)list->chunklen) + ent = list->head; + if (ent != NULL) { + list->head = ent->next; + result = ent; + if (--list->len == 0) + list->chunklen = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + if (!result) + result = OPENSSL_malloc(sz); + return result; +} + +static void freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem) +{ + SSL3_BUF_FREELIST *list; + SSL3_BUF_FREELIST_ENTRY *ent; + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; + if (list != NULL && + (sz == list->chunklen || list->chunklen == 0) && + list->len < ctx->freelist_max_len && sz >= sizeof(*ent)) { + list->chunklen = sz; + ent = mem; + ent->next = list->head; + list->head = ent; + ++list->len; + mem = NULL; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + if (mem) + OPENSSL_free(mem); +} +#else +# define freelist_extract(c,fr,sz) OPENSSL_malloc(sz) +# define freelist_insert(c,fr,sz,m) OPENSSL_free(m) +#endif + +int ssl3_setup_read_buffer(SSL *s) +{ + unsigned char *p; + size_t len, align = 0, headerlen; + + if (SSL_IS_DTLS(s)) + headerlen = DTLS1_RT_HEADER_LENGTH; + else + headerlen = SSL3_RT_HEADER_LENGTH; + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + + if (s->s3->rbuf.buf == NULL) { + len = SSL3_RT_MAX_PLAIN_LENGTH + + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; + if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { + s->s3->init_extra = 1; + len += SSL3_RT_MAX_EXTRA; + } +#ifndef OPENSSL_NO_COMP + if (!(s->options & SSL_OP_NO_COMPRESSION)) + len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + if ((p = freelist_extract(s->ctx, 1, len)) == NULL) + goto err; + s->s3->rbuf.buf = p; + s->s3->rbuf.len = len; + } + + s->packet = &(s->s3->rbuf.buf[0]); + return 1; + + err: + SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER, ERR_R_MALLOC_FAILURE); + return 0; +} + +int ssl3_setup_write_buffer(SSL *s) +{ + unsigned char *p; + size_t len, align = 0, headerlen; + + if (SSL_IS_DTLS(s)) + headerlen = DTLS1_RT_HEADER_LENGTH + 1; + else + headerlen = SSL3_RT_HEADER_LENGTH; + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + + if (s->s3->wbuf.buf == NULL) { + len = s->max_send_fragment + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; +#ifndef OPENSSL_NO_COMP + if (!(s->options & SSL_OP_NO_COMPRESSION)) + len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) + len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; + + if ((p = freelist_extract(s->ctx, 0, len)) == NULL) + goto err; + s->s3->wbuf.buf = p; + s->s3->wbuf.len = len; + } + + return 1; + + err: + SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE); + return 0; +} + +int ssl3_setup_buffers(SSL *s) +{ + if (!ssl3_setup_read_buffer(s)) + return 0; + if (!ssl3_setup_write_buffer(s)) + return 0; + return 1; +} + +int ssl3_release_write_buffer(SSL *s) +{ + if (s->s3->wbuf.buf != NULL) { + freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf); + s->s3->wbuf.buf = NULL; + } + return 1; +} + +int ssl3_release_read_buffer(SSL *s) +{ + if (s->s3->rbuf.buf != NULL) { + freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf); + s->s3->rbuf.buf = NULL; + } + return 1; +} +/* ssl/s3_cbc.c */ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "constant_time_locl.h" +// #include "ssl_locl.h" + +#include "md5.h" +#include "sha.h" + +/* + * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's + * length field. (SHA-384/512 have 128-bit length.) + */ +#define MAX_HASH_BIT_COUNT_BYTES 16 + +/* + * MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. + * Currently SHA-384/512 has a 128-byte block size and that's the largest + * supported by TLS.) + */ +#define MAX_HASH_BLOCK_SIZE 128 + +/*- + * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC + * record in |rec| by updating |rec->length| in constant time. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. + */ +int ssl3_cbc_remove_padding(const SSL *s, + SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size) +{ + unsigned padding_length, good; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + + /* + * These lengths are all public so we can test them in non-constant time. + */ + if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length - 1]; + good = constant_time_ge(rec->length, padding_length + overhead); + /* SSLv3 requires that the padding is minimal. */ + good &= constant_time_ge(block_size, padding_length + 1); + padding_length = good & (padding_length + 1); + rec->length -= padding_length; + rec->type |= padding_length << 8; /* kludge: pass padding length */ + return constant_time_select_int(good, 1, -1); +} + +/*- + * tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC + * record in |rec| in constant time and returns 1 if the padding is valid and + * -1 otherwise. It also removes any explicit IV from the start of the record + * without leaking any timing about whether there was enough space after the + * padding was removed. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. + */ +int tls1_cbc_remove_padding(const SSL *s, + SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size) +{ + unsigned padding_length, good, to_check, i; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + /* Check if version requires explicit IV */ + if (SSL_USE_EXPLICIT_IV(s)) { + /* + * These lengths are all public so we can test them in non-constant + * time. + */ + if (overhead + block_size > rec->length) + return 0; + /* We can now safely skip explicit IV */ + rec->data += block_size; + rec->input += block_size; + rec->length -= block_size; + } else if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length - 1]; + + /* + * NB: if compression is in operation the first packet may not be of even + * length so the padding bug check cannot be performed. This bug + * workaround has been around since SSLeay so hopefully it is either + * fixed now or no buggy implementation supports compression [steve] + */ + if ((s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) { + /* First packet is even in size, so check */ + if ((CRYPTO_memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0", 8) == 0) && + !(padding_length & 1)) { + s->s3->flags |= TLS1_FLAGS_TLS_PADDING_BUG; + } + if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && padding_length > 0) { + padding_length--; + } + } + + if (EVP_CIPHER_flags(s->enc_read_ctx->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { + /* padding is already verified */ + rec->length -= padding_length + 1; + return 1; + } + + good = constant_time_ge(rec->length, overhead + padding_length); + /* + * The padding consists of a length byte at the end of the record and + * then that many bytes of padding, all with the same value as the length + * byte. Thus, with the length byte included, there are i+1 bytes of + * padding. We can't check just |padding_length+1| bytes because that + * leaks decrypted information. Therefore we always have to check the + * maximum amount of padding possible. (Again, the length of the record + * is public information so we can use it.) + */ + to_check = 255; /* maximum amount of padding. */ + if (to_check > rec->length - 1) + to_check = rec->length - 1; + + for (i = 0; i < to_check; i++) { + unsigned char mask = constant_time_ge_8(padding_length, i); + unsigned char b = rec->data[rec->length - 1 - i]; + /* + * The final |padding_length+1| bytes should all have the value + * |padding_length|. Therefore the XOR should be zero. + */ + good &= ~(mask & (padding_length ^ b)); + } + + /* + * If any of the final |padding_length+1| bytes had the wrong value, one + * or more of the lower eight bits of |good| will be cleared. + */ + good = constant_time_eq(0xff, good & 0xff); + padding_length = good & (padding_length + 1); + rec->length -= padding_length; + rec->type |= padding_length << 8; /* kludge: pass padding length */ + + return constant_time_select_int(good, 1, -1); +} + +/*- + * ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in + * constant time (independent of the concrete value of rec->length, which may + * vary within a 256-byte window). + * + * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to + * this function. + * + * On entry: + * rec->orig_len >= md_size + * md_size <= EVP_MAX_MD_SIZE + * + * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with + * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into + * a single or pair of cache-lines, then the variable memory accesses don't + * actually affect the timing. CPUs with smaller cache-lines [if any] are + * not multi-core and are not considered vulnerable to cache-timing attacks. + */ +#define CBC_MAC_ROTATE_IN_PLACE + +void ssl3_cbc_copy_mac(unsigned char *out, + const SSL3_RECORD *rec, + unsigned md_size, unsigned orig_len) +{ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; + unsigned char *rotated_mac; +#else + unsigned char rotated_mac[EVP_MAX_MD_SIZE]; +#endif + + /* + * mac_end is the index of |rec->data| just after the end of the MAC. + */ + unsigned mac_end = rec->length; + unsigned mac_start = mac_end - md_size; + /* + * scan_start contains the number of bytes that we can ignore because the + * MAC's position can only vary by 255 bytes. + */ + unsigned scan_start = 0; + unsigned i, j; + unsigned div_spoiler; + unsigned rotate_offset; + + OPENSSL_assert(orig_len >= md_size); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + +#if defined(CBC_MAC_ROTATE_IN_PLACE) + rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63); +#endif + + /* This information is public so it's safe to branch based on it. */ + if (orig_len > md_size + 255 + 1) + scan_start = orig_len - (md_size + 255 + 1); + /* + * div_spoiler contains a multiple of md_size that is used to cause the + * modulo operation to be constant time. Without this, the time varies + * based on the amount of padding when running on Intel chips at least. + * The aim of right-shifting md_size is so that the compiler doesn't + * figure out that it can remove div_spoiler as that would require it to + * prove that md_size is always even, which I hope is beyond it. + */ + div_spoiler = md_size >> 1; + div_spoiler <<= (sizeof(div_spoiler) - 1) * 8; + rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; + + memset(rotated_mac, 0, md_size); + for (i = scan_start, j = 0; i < orig_len; i++) { + unsigned char mac_started = constant_time_ge_8(i, mac_start); + unsigned char mac_ended = constant_time_ge_8(i, mac_end); + unsigned char b = rec->data[i]; + rotated_mac[j++] |= b & mac_started & ~mac_ended; + j &= constant_time_lt(j, md_size); + } + + /* Now rotate the MAC */ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + j = 0; + for (i = 0; i < md_size; i++) { + /* in case cache-line is 32 bytes, touch second line */ + ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32]; + out[j++] = rotated_mac[rotate_offset++]; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + } +#else + memset(out, 0, md_size); + rotate_offset = md_size - rotate_offset; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + for (i = 0; i < md_size; i++) { + for (j = 0; j < md_size; j++) + out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); + rotate_offset++; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + } +#endif +} + +/* + * u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in + * little-endian order. The value of p is advanced by four. + */ +#define u32toLE(n, p) \ + (*((p)++)=(unsigned char)(n), \ + *((p)++)=(unsigned char)(n>>8), \ + *((p)++)=(unsigned char)(n>>16), \ + *((p)++)=(unsigned char)(n>>24)) + +/* + * These functions serialize the state of a hash and thus perform the + * standard "final" operation without adding the padding and length that such + * a function typically does. + */ +static void tls1_md5_final_raw(void *ctx, unsigned char *md_out) +{ + MD5_CTX *md5 = ctx; + u32toLE(md5->A, md_out); + u32toLE(md5->B, md_out); + u32toLE(md5->C, md_out); + u32toLE(md5->D, md_out); +} + +static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out) +{ + SHA_CTX *sha1 = ctx; + l2n(sha1->h0, md_out); + l2n(sha1->h1, md_out); + l2n(sha1->h2, md_out); + l2n(sha1->h3, md_out); + l2n(sha1->h4, md_out); +} + +#define LARGEST_DIGEST_CTX SHA_CTX + +#ifndef OPENSSL_NO_SHA256 +static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out) +{ + SHA256_CTX *sha256 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) { + l2n(sha256->h[i], md_out); + } +} + +# undef LARGEST_DIGEST_CTX +# define LARGEST_DIGEST_CTX SHA256_CTX +#endif + +#ifndef OPENSSL_NO_SHA512 +static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) +{ + SHA512_CTX *sha512 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) { + l2n8(sha512->h[i], md_out); + } +} + +# undef LARGEST_DIGEST_CTX +# define LARGEST_DIGEST_CTX SHA512_CTX +#endif + +/* + * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. + */ +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return 0; +#endif + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + case NID_sha1: +#ifndef OPENSSL_NO_SHA256 + case NID_sha224: + case NID_sha256: +#endif +#ifndef OPENSSL_NO_SHA512 + case NID_sha384: + case NID_sha512: +#endif + return 1; + default: + return 0; + } +} + +/*- + * ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS + * record. + * + * ctx: the EVP_MD_CTX from which we take the hash function. + * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. + * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. + * md_out_size: if non-NULL, the number of output bytes is written here. + * header: the 13-byte, TLS record header. + * data: the record data itself, less any preceeding explicit IV. + * data_plus_mac_size: the secret, reported length of the data and MAC + * once the padding has been removed. + * data_plus_mac_plus_padding_size: the public length of the whole + * record, including padding. + * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. + * + * On entry: by virtue of having been through one of the remove_padding + * functions, above, we know that data_plus_mac_size is large enough to contain + * a padding byte and MAC. (If the padding was invalid, it might contain the + * padding too. ) + * Returns 1 on success or 0 on error + */ +int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + unsigned mac_secret_length, char is_sslv3) +{ + union { + double align; + unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; + } md_state; + void (*md_final_raw) (void *ctx, unsigned char *md_out); + void (*md_transform) (void *ctx, const unsigned char *block); + unsigned md_size, md_block_size = 64; + unsigned sslv3_pad_length = 40, header_length, variance_blocks, + len, max_mac_bytes, num_blocks, + num_starting_blocks, k, mac_end_offset, c, index_a, index_b; + unsigned int bits; /* at most 18 bits */ + unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; + /* hmac_pad is the masked HMAC key. */ + unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; + unsigned char first_block[MAX_HASH_BLOCK_SIZE]; + unsigned char mac_out[EVP_MAX_MD_SIZE]; + unsigned i, j, md_out_size_u; + EVP_MD_CTX md_ctx; + /* + * mdLengthSize is the number of bytes in the length field that + * terminates * the hash. + */ + unsigned md_length_size = 8; + char length_is_big_endian = 1; + + /* + * This is a, hopefully redundant, check that allows us to forget about + * many possible overflows later in this function. + */ + OPENSSL_assert(data_plus_mac_plus_padding_size < 1024 * 1024); + + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + if (MD5_Init((MD5_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_md5_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))MD5_Transform; + md_size = 16; + sslv3_pad_length = 48; + length_is_big_endian = 0; + break; + case NID_sha1: + if (SHA1_Init((SHA_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha1_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA1_Transform; + md_size = 20; + break; +#ifndef OPENSSL_NO_SHA256 + case NID_sha224: + if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha256_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; + md_size = 224 / 8; + break; + case NID_sha256: + if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha256_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; + md_size = 32; + break; +#endif +#ifndef OPENSSL_NO_SHA512 + case NID_sha384: + if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha512_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA512_Transform; + md_size = 384 / 8; + md_block_size = 128; + md_length_size = 16; + break; + case NID_sha512: + if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha512_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA512_Transform; + md_size = 64; + md_block_size = 128; + md_length_size = 16; + break; +#endif + default: + /* + * ssl3_cbc_record_digest_supported should have been called first to + * check that the hash function is supported. + */ + OPENSSL_assert(0); + if (md_out_size) + *md_out_size = 0; + return 0; + } + + OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); + OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + + header_length = 13; + if (is_sslv3) { + header_length = mac_secret_length + sslv3_pad_length + 8 /* sequence + * number */ + + 1 /* record type */ + + 2 /* record length */ ; + } + + /* + * variance_blocks is the number of blocks of the hash that we have to + * calculate in constant time because they could be altered by the + * padding value. In SSLv3, the padding must be minimal so the end of + * the plaintext varies by, at most, 15+20 = 35 bytes. (We conservatively + * assume that the MAC size varies from 0..20 bytes.) In case the 9 bytes + * of hash termination (0x80 + 64-bit length) don't fit in the final + * block, we say that the final two blocks can vary based on the padding. + * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not + * required to be minimal. Therefore we say that the final six blocks can + * vary based on the padding. Later in the function, if the message is + * short and there obviously cannot be this many blocks then + * variance_blocks can be reduced. + */ + variance_blocks = is_sslv3 ? 2 : 6; + /* + * From now on we're dealing with the MAC, which conceptually has 13 + * bytes of `header' before the start of the data (TLS) or 71/75 bytes + * (SSLv3) + */ + len = data_plus_mac_plus_padding_size + header_length; + /* + * max_mac_bytes contains the maximum bytes of bytes in the MAC, + * including * |header|, assuming that there's no padding. + */ + max_mac_bytes = len - md_size - 1; + /* num_blocks is the maximum number of hash blocks. */ + num_blocks = + (max_mac_bytes + 1 + md_length_size + md_block_size - + 1) / md_block_size; + /* + * In order to calculate the MAC in constant time we have to handle the + * final blocks specially because the padding value could cause the end + * to appear somewhere in the final |variance_blocks| blocks and we can't + * leak where. However, |num_starting_blocks| worth of data can be hashed + * right away because no padding value can affect whether they are + * plaintext. + */ + num_starting_blocks = 0; + /* + * k is the starting byte offset into the conceptual header||data where + * we start processing. + */ + k = 0; + /* + * mac_end_offset is the index just past the end of the data to be MACed. + */ + mac_end_offset = data_plus_mac_size + header_length - md_size; + /* + * c is the index of the 0x80 byte in the final hash block that contains + * application data. + */ + c = mac_end_offset % md_block_size; + /* + * index_a is the hash block number that contains the 0x80 terminating + * value. + */ + index_a = mac_end_offset / md_block_size; + /* + * index_b is the hash block number that contains the 64-bit hash length, + * in bits. + */ + index_b = (mac_end_offset + md_length_size) / md_block_size; + /* + * bits is the hash-length in bits. It includes the additional hash block + * for the masked HMAC key, or whole of |header| in the case of SSLv3. + */ + + /* + * For SSLv3, if we're going to have any starting blocks then we need at + * least two because the header is larger than a single block. + */ + if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) { + num_starting_blocks = num_blocks - variance_blocks; + k = md_block_size * num_starting_blocks; + } + + bits = 8 * mac_end_offset; + if (!is_sslv3) { + /* + * Compute the initial HMAC block. For SSLv3, the padding and secret + * bytes are included in |header| because they take more than a + * single block. + */ + bits += 8 * md_block_size; + memset(hmac_pad, 0, md_block_size); + OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); + memcpy(hmac_pad, mac_secret, mac_secret_length); + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x36; + + md_transform(md_state.c, hmac_pad); + } + + if (length_is_big_endian) { + memset(length_bytes, 0, md_length_size - 4); + length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24); + length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16); + length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8); + length_bytes[md_length_size - 1] = (unsigned char)bits; + } else { + memset(length_bytes, 0, md_length_size); + length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24); + length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16); + length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8); + length_bytes[md_length_size - 8] = (unsigned char)bits; + } + + if (k > 0) { + if (is_sslv3) { + unsigned overhang; + + /* + * The SSLv3 header is larger than a single block. overhang is + * the number of bytes beyond a single block that the header + * consumes: either 7 bytes (SHA1) or 11 bytes (MD5). There are no + * ciphersuites in SSLv3 that are not SHA1 or MD5 based and + * therefore we can be confident that the header_length will be + * greater than |md_block_size|. However we add a sanity check just + * in case + */ + if (header_length <= md_block_size) { + /* Should never happen */ + return 0; + } + overhang = header_length - md_block_size; + md_transform(md_state.c, header); + memcpy(first_block, header + md_block_size, overhang); + memcpy(first_block + overhang, data, md_block_size - overhang); + md_transform(md_state.c, first_block); + for (i = 1; i < k / md_block_size - 1; i++) + md_transform(md_state.c, data + md_block_size * i - overhang); + } else { + /* k is a multiple of md_block_size. */ + memcpy(first_block, header, 13); + memcpy(first_block + 13, data, md_block_size - 13); + md_transform(md_state.c, first_block); + for (i = 1; i < k / md_block_size; i++) + md_transform(md_state.c, data + md_block_size * i - 13); + } + } + + memset(mac_out, 0, sizeof(mac_out)); + + /* + * We now process the final hash blocks. For each block, we construct it + * in constant time. If the |i==index_a| then we'll include the 0x80 + * bytes and zero pad etc. For each block we selectively copy it, in + * constant time, to |mac_out|. + */ + for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; + i++) { + unsigned char block[MAX_HASH_BLOCK_SIZE]; + unsigned char is_block_a = constant_time_eq_8(i, index_a); + unsigned char is_block_b = constant_time_eq_8(i, index_b); + for (j = 0; j < md_block_size; j++) { + unsigned char b = 0, is_past_c, is_past_cp1; + if (k < header_length) + b = header[k]; + else if (k < data_plus_mac_plus_padding_size + header_length) + b = data[k - header_length]; + k++; + + is_past_c = is_block_a & constant_time_ge_8(j, c); + is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); + /* + * If this is the block containing the end of the application + * data, and we are at the offset for the 0x80 value, then + * overwrite b with 0x80. + */ + b = constant_time_select_8(is_past_c, 0x80, b); + /* + * If this the the block containing the end of the application + * data and we're past the 0x80 value then just write zero. + */ + b = b & ~is_past_cp1; + /* + * If this is index_b (the final block), but not index_a (the end + * of the data), then the 64-bit length didn't fit into index_a + * and we're having to add an extra block of zeros. + */ + b &= ~is_block_b | is_block_a; + + /* + * The final bytes of one of the blocks contains the length. + */ + if (j >= md_block_size - md_length_size) { + /* If this is index_b, write a length byte. */ + b = constant_time_select_8(is_block_b, + length_bytes[j - + (md_block_size - + md_length_size)], b); + } + block[j] = b; + } + + md_transform(md_state.c, block); + md_final_raw(md_state.c, block); + /* If this is index_b, copy the hash value to |mac_out|. */ + for (j = 0; j < md_size; j++) + mac_out[j] |= block[j] & is_block_b; + } + + EVP_MD_CTX_init(&md_ctx); + if (EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ ) <= 0) + goto err; + if (is_sslv3) { + /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ + memset(hmac_pad, 0x5c, sslv3_pad_length); + + if (EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length) <= 0 + || EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length) <= 0 + || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0) + goto err; + } else { + /* Complete the HMAC in the standard manner. */ + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x6a; + + if (EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size) <= 0 + || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0) + goto err; + } + EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); + if (md_out_size) + *md_out_size = md_out_size_u; + EVP_MD_CTX_cleanup(&md_ctx); + + return 1; +err: + EVP_MD_CTX_cleanup(&md_ctx); + return 0; +} + +#ifdef OPENSSL_FIPS + +/* + * Due to the need to use EVP in FIPS mode we can't reimplement digests but + * we can ensure the number of blocks processed is equal for all cases by + * digesting additional data. + */ + +void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx, + EVP_MD_CTX *mac_ctx, const unsigned char *data, + size_t data_len, size_t orig_len) +{ + size_t block_size, digest_pad, blocks_data, blocks_orig; + if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE) + return; + block_size = EVP_MD_CTX_block_size(mac_ctx); + /*- + * We are in FIPS mode if we get this far so we know we have only SHA* + * digests and TLS to deal with. + * Minimum digest padding length is 17 for SHA384/SHA512 and 9 + * otherwise. + * Additional header is 13 bytes. To get the number of digest blocks + * processed round up the amount of data plus padding to the nearest + * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise. + * So we have: + * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size + * equivalently: + * blocks = (payload_len + digest_pad + 12)/block_size + 1 + * HMAC adds a constant overhead. + * We're ultimately only interested in differences so this becomes + * blocks = (payload_len + 29)/128 + * for SHA384/SHA512 and + * blocks = (payload_len + 21)/64 + * otherwise. + */ + digest_pad = block_size == 64 ? 21 : 29; + blocks_orig = (orig_len + digest_pad) / block_size; + blocks_data = (data_len + digest_pad) / block_size; + /* + * MAC enough blocks to make up the difference between the original and + * actual lengths plus one extra block to ensure this is never a no op. + * The "data" pointer should always have enough space to perform this + * operation as it is large enough for a maximum length TLS buffer. + */ + EVP_DigestSignUpdate(mac_ctx, data, + (blocks_orig - blocks_data + 1) * block_size); +} +#endif +/* ssl/s3_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +// #include "ssl_locl.h" +#include "kssl_lcl.h" +// #include "buffer.h" +// #include "rand.h" +// #include "objects.h" +// #include "evp.h" +// #include "md5.h" +#ifdef OPENSSL_FIPS +# include +#endif +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#include "bn.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b); +#ifndef OPENSSL_NO_TLSEXT +static int ssl3_check_finished(SSL *s); +#endif + +#ifndef OPENSSL_NO_SSL3_METHOD +static const SSL_METHOD *ssl3_get_client_method(int ver) +{ + if (ver == SSL3_VERSION) + return (SSLv3_client_method()); + else + return (NULL); +} + +IMPLEMENT_ssl3_meth_func(SSLv3_client_method, + ssl_undefined_function, + ssl3_connect, ssl3_get_client_method) +#endif +int ssl3_connect(SSL *s) +{ + BUF_MEM *buf = NULL; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + +#ifndef OPENSSL_NO_HEARTBEATS + /* + * If we're awaiting a HeartbeatResponse, pretend we already got and + * don't await it anymore, because Heartbeats don't make sense during + * handshakes anyway. + */ + if (s->tlsext_hb_pending) { + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + s->state = SSL_ST_CONNECT; + s->ctx->stats.sess_connect_renegotiate++; + /* break */ + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE | SSL_ST_CONNECT: + case SSL_ST_OK | SSL_ST_CONNECT: + + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00) != 0x0300) { + SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + ret = -1; + goto end; + } + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->init_buf = buf; + buf = NULL; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* setup buffing BIO */ + if (!ssl_init_wbio_buffer(s, 0)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* don't push the buffering BIO quite yet */ + + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + s->state = SSL3_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + /* + * Should have been reset by ssl3_get_finished, too. + */ + s->s3->change_cipher_spec = 0; + break; + + case SSL3_ST_CW_CLNT_HELLO_A: + case SSL3_ST_CW_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl3_client_hello(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_HELLO_A; + s->init_num = 0; + + /* turn on buffering for the next lot of output */ + if (s->bbio != s->wbio) + s->wbio = BIO_push(s->bbio, s->wbio); + + break; + + case SSL3_ST_CR_SRVR_HELLO_A: + case SSL3_ST_CR_SRVR_HELLO_B: + ret = ssl3_get_server_hello(s); + if (ret <= 0) + goto end; + + if (s->hit) { + s->state = SSL3_ST_CR_FINISHED_A; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_ticket_expected) { + /* receive renewed session ticket */ + s->state = SSL3_ST_CR_SESSION_TICKET_A; + } +#endif + } else { + s->state = SSL3_ST_CR_CERT_A; + } + s->init_num = 0; + break; + case SSL3_ST_CR_CERT_A: + case SSL3_ST_CR_CERT_B: +#ifndef OPENSSL_NO_TLSEXT + /* Noop (ret = 0) for everything but EAP-FAST. */ + ret = ssl3_check_finished(s); + if (ret < 0) + goto end; + if (ret == 1) { + s->hit = 1; + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + } +#endif + /* Check if it is anon DH/ECDH, SRP auth */ + /* or PSK */ + if (! + (s->s3->tmp. + new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + ret = ssl3_get_server_certificate(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state = SSL3_ST_CR_CERT_STATUS_A; + else + s->state = SSL3_ST_CR_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_CR_KEY_EXCH_A; + } +#else + } else + skip = 1; + + s->state = SSL3_ST_CR_KEY_EXCH_A; +#endif + s->init_num = 0; + break; + + case SSL3_ST_CR_KEY_EXCH_A: + case SSL3_ST_CR_KEY_EXCH_B: + ret = ssl3_get_key_exchange(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_CERT_REQ_A; + s->init_num = 0; + + /* + * at this point we check that we have the required stuff from + * the server + */ + if (!ssl3_check_cert_and_algorithm(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + break; + + case SSL3_ST_CR_CERT_REQ_A: + case SSL3_ST_CR_CERT_REQ_B: + ret = ssl3_get_certificate_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_DONE_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_SRVR_DONE_A: + case SSL3_ST_CR_SRVR_DONE_B: + ret = ssl3_get_server_done(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SRP + if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) { + if ((ret = SRP_Calc_A_param(s)) <= 0) { + SSLerr(SSL_F_SSL3_CONNECT, SSL_R_SRP_A_CALC); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + goto end; + } + } +#endif + if (s->s3->tmp.cert_req) + s->state = SSL3_ST_CW_CERT_A; + else + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + + break; + + case SSL3_ST_CW_CERT_A: + case SSL3_ST_CW_CERT_B: + case SSL3_ST_CW_CERT_C: + case SSL3_ST_CW_CERT_D: + ret = ssl3_send_client_certificate(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_KEY_EXCH_A: + case SSL3_ST_CW_KEY_EXCH_B: + ret = ssl3_send_client_key_exchange(s); + if (ret <= 0) + goto end; + /* + * EAY EAY EAY need to check for DH fix cert sent back + */ + /* + * For TLS, cert_req is set to 2, so a cert chain of nothing is + * sent, but no verify packet is sent + */ + /* + * XXX: For now, we do not support client authentication in ECDH + * cipher suites with ECDH (rather than ECDSA) certificates. We + * need to skip the certificate verify message when client's + * ECDH public key is sent inside the client certificate. + */ + if (s->s3->tmp.cert_req == 1) { + s->state = SSL3_ST_CW_CERT_VRFY_A; + } else { + s->state = SSL3_ST_CW_CHANGE_A; + } + if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { + s->state = SSL3_ST_CW_CHANGE_A; + } + + s->init_num = 0; + break; + + case SSL3_ST_CW_CERT_VRFY_A: + case SSL3_ST_CW_CERT_VRFY_B: + ret = ssl3_send_client_verify(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_CW_CHANGE_B: + ret = ssl3_send_change_cipher_spec(s, + SSL3_ST_CW_CHANGE_A, + SSL3_ST_CW_CHANGE_B); + if (ret <= 0) + goto end; + +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) + s->state = SSL3_ST_CW_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_CW_NEXT_PROTO_A; + else + s->state = SSL3_ST_CW_FINISHED_A; +#endif + s->init_num = 0; + + s->session->cipher = s->s3->tmp.new_cipher; +#ifdef OPENSSL_NO_COMP + s->session->compress_meth = 0; +#else + if (s->s3->tmp.new_compression == NULL) + s->session->compress_meth = 0; + else + s->session->compress_meth = s->s3->tmp.new_compression->id; +#endif + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_CLIENT_WRITE)) + { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + break; + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + case SSL3_ST_CW_NEXT_PROTO_A: + case SSL3_ST_CW_NEXT_PROTO_B: + ret = ssl3_send_next_proto(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_FINISHED_A; + break; +#endif + + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_CW_FINISHED_B: + ret = ssl3_send_finished(s, + SSL3_ST_CW_FINISHED_A, + SSL3_ST_CW_FINISHED_B, + s->method-> + ssl3_enc->client_finished_label, + s->method-> + ssl3_enc->client_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_FLUSH; + + /* clear flags */ + s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; + if (s->hit) { + s->s3->tmp.next_state = SSL_ST_OK; + if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { + s->state = SSL_ST_OK; + s->s3->flags |= SSL3_FLAGS_POP_BUFFER; + s->s3->delay_buf_pop_ret = 0; + } + } else { +#ifndef OPENSSL_NO_TLSEXT + /* + * Allow NewSessionTicket if ticket expected + */ + if (s->tlsext_ticket_expected) + s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; + else +#endif + + s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; + } + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_CR_SESSION_TICKET_A: + case SSL3_ST_CR_SESSION_TICKET_B: + ret = ssl3_get_new_session_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_STATUS_A: + case SSL3_ST_CR_CERT_STATUS_B: + ret = ssl3_get_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_KEY_EXCH_A; + s->init_num = 0; + break; +#endif + + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) + goto end; + + if (s->hit) + s->state = SSL3_ST_CW_CHANGE_A; + else + s->state = SSL_ST_OK; + s->init_num = 0; + break; + + case SSL3_ST_CW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL_ST_OK: + /* clean a few things up */ + ssl3_cleanup_key_block(s); + + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } + + /* + * If we are not 'joining' the last two packets, remove the + * buffering now + */ + if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) + ssl_free_wbio_buffer(s); + /* else do it later in ssl3_write */ + + s->init_num = 0; + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->handshake_func = ssl3_connect; + s->ctx->stats.sess_connect_good++; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + goto end; + /* break; */ + + case SSL_ST_ERR: + default: + SSLerr(SSL_F_SSL3_CONNECT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + /* did we do anything */ + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + end: + s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + return (ret); +} + +int ssl3_client_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i; + unsigned long l; + int al = 0; +#ifndef OPENSSL_NO_COMP + int j; + SSL_COMP *comp; +#endif + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { + SSL_SESSION *sess = s->session; + if ((sess == NULL) || (sess->ssl_version != s->version) || +#ifdef OPENSSL_NO_TLSEXT + !sess->session_id_length || +#else + /* + * In the case of EAP-FAST, we can have a pre-shared + * "ticket" without a session ID. + */ + (!sess->session_id_length && !sess->tlsext_tick) || +#endif + (sess->not_resumable)) { + if (!ssl_get_new_session(s, 0)) + goto err; + } + if (s->method->version == DTLS_ANY_VERSION) { + /* Determine which DTLS version to use */ + int options = s->options; + /* If DTLS 1.2 disabled correct the version number */ + if (options & SSL_OP_NO_DTLSv1_2) { + if (tls1_suiteb(s)) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, + SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); + goto err; + } + /* + * Disabling all versions is silly: return an error. + */ + if (options & SSL_OP_NO_DTLSv1) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_WRONG_SSL_VERSION); + goto err; + } + /* + * Update method so we don't use any DTLS 1.2 features. + */ + s->method = DTLSv1_client_method(); + s->version = DTLS1_VERSION; + } else { + /* + * We only support one version: update method + */ + if (options & SSL_OP_NO_DTLSv1) + s->method = DTLSv1_2_client_method(); + s->version = DTLS1_2_VERSION; + } + s->client_version = s->version; + } + /* else use the pre-loaded session */ + + p = s->s3->client_random; + + /* + * for DTLS if client_random is initialized, reuse it, we are + * required to use same upon reply to HelloVerify + */ + if (SSL_IS_DTLS(s)) { + size_t idx; + i = 1; + for (idx = 0; idx < sizeof(s->s3->client_random); idx++) { + if (p[idx]) { + i = 0; + break; + } + } + } else + i = 1; + + if (i && ssl_fill_hello_random(s, 0, p, + sizeof(s->s3->client_random)) <= 0) + goto err; + + /* Do the message type and length last */ + d = p = ssl_handshake_start(s); + + /*- + * version indicates the negotiated version: for example from + * an SSLv2/v3 compatible client hello). The client_version + * field is the maximum version we permit and it is also + * used in RSA encrypted premaster secrets. Some servers can + * choke if we initially report a higher version then + * renegotiate to a lower one in the premaster secret. This + * didn't happen with TLS 1.0 as most servers supported it + * but it can with TLS 1.1 or later if the server only supports + * 1.0. + * + * Possible scenario with previous logic: + * 1. Client hello indicates TLS 1.2 + * 2. Server hello says TLS 1.0 + * 3. RSA encrypted premaster secret uses 1.2. + * 4. Handhaked proceeds using TLS 1.0. + * 5. Server sends hello request to renegotiate. + * 6. Client hello indicates TLS v1.0 as we now + * know that is maximum server supports. + * 7. Server chokes on RSA encrypted premaster secret + * containing version 1.0. + * + * For interoperability it should be OK to always use the + * maximum version we support in client hello and then rely + * on the checking of version to ensure the servers isn't + * being inconsistent: for example initially negotiating with + * TLS 1.0 and renegotiating with TLS 1.2. We do this by using + * client_version in client hello and not resetting it to + * the negotiated version. + */ +#if 0 + *(p++) = s->version >> 8; + *(p++) = s->version & 0xff; + s->client_version = s->version; +#else + *(p++) = s->client_version >> 8; + *(p++) = s->client_version & 0xff; +#endif + + /* Random stuff */ + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* Session ID */ + if (s->new_session) + i = 0; + else + i = s->session->session_id_length; + *(p++) = i; + if (i != 0) { + if (i > (int)sizeof(s->session->session_id)) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } + memcpy(p, s->session->session_id, i); + p += i; + } + + /* cookie stuff for DTLS */ + if (SSL_IS_DTLS(s)) { + if (s->d1->cookie_len > sizeof(s->d1->cookie)) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } + *(p++) = s->d1->cookie_len; + memcpy(p, s->d1->cookie, s->d1->cookie_len); + p += s->d1->cookie_len; + } + + /* Ciphers supported */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0); + if (i == 0) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + goto err; + } +#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH + /* + * Some servers hang if client hello > 256 bytes as hack workaround + * chop number of supported ciphers to keep it well below this if we + * use TLS v1.2 + */ + if (TLS1_get_version(s) >= TLS1_2_VERSION + && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) + i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; +#endif + s2n(i, p); + p += i; + + /* COMPRESSION */ +#ifdef OPENSSL_NO_COMP + *(p++) = 1; +#else + + if ((s->options & SSL_OP_NO_COMPRESSION) + || !s->ctx->comp_methods) + j = 0; + else + j = sk_SSL_COMP_num(s->ctx->comp_methods); + *(p++) = 1 + j; + for (i = 0; i < j; i++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); + *(p++) = comp->id; + } +#endif + *(p++) = 0; /* Add the NULL method */ + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (ssl_prepare_clienthello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + if ((p = + ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH, + &al)) == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } +#endif + + l = p - d; + ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l); + s->state = SSL3_ST_CW_CLNT_HELLO_B; + } + + /* SSL3_ST_CW_CLNT_HELLO_B */ + return ssl_do_write(s); + err: + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_server_hello(SSL *s) +{ + STACK_OF(SSL_CIPHER) *sk; + const SSL_CIPHER *c; + CERT *ct = s->cert; + unsigned char *p, *d; + int i, al = SSL_AD_INTERNAL_ERROR, ok; + unsigned int j; + long n; +#ifndef OPENSSL_NO_COMP + SSL_COMP *comp; +#endif + /* + * Hello verify request and/or server hello version may not match so set + * first packet if we're negotiating version. + */ + if (SSL_IS_DTLS(s)) + s->first_packet = 1; + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_SRVR_HELLO_A, + SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, &ok); + + if (!ok) + return ((int)n); + + if (SSL_IS_DTLS(s)) { + s->first_packet = 0; + if (s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) { + if (s->d1->send_cookie == 0) { + s->s3->tmp.reuse_message = 1; + return 1; + } else { /* already sent a cookie */ + + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + } + } + + if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + + d = p = (unsigned char *)s->init_msg; + if (s->method->version == DTLS_ANY_VERSION) { + /* Work out correct protocol version to use */ + int hversion = (p[0] << 8) | p[1]; + int options = s->options; + if (hversion == DTLS1_2_VERSION && !(options & SSL_OP_NO_DTLSv1_2)) + s->method = DTLSv1_2_client_method(); + else if (tls1_suiteb(s)) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); + s->version = hversion; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } else if (hversion == DTLS1_VERSION && !(options & SSL_OP_NO_DTLSv1)) + s->method = DTLSv1_client_method(); + else { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); + s->version = hversion; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + s->session->ssl_version = s->version = s->method->version; + } + + if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); + s->version = (s->version & 0xff00) | p[1]; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + p += 2; + + /* load the server hello data */ + /* load the server random */ + memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + s->hit = 0; + + /* get the session-id */ + j = *(p++); + + if ((j > sizeof(s->session->session_id)) || (j > SSL3_SESSION_ID_SIZE)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SSL3_SESSION_ID_TOO_LONG); + goto f_err; + } +#ifndef OPENSSL_NO_TLSEXT + /* + * Check if we can resume the session based on external pre-shared secret. + * EAP-FAST (RFC 4851) supports two types of session resumption. + * Resumption based on server-side state works with session IDs. + * Resumption based on pre-shared Protected Access Credentials (PACs) + * works by overriding the SessionTicket extension at the application + * layer, and does not send a session ID. (We do not know whether EAP-FAST + * servers would honour the session ID.) Therefore, the session ID alone + * is not a reliable indicator of session resumption, so we first check if + * we can resume, and later peek at the next handshake message to see if the + * server wants to resume. + */ + if (s->version >= TLS1_VERSION && s->tls_session_secret_cb && + s->session->tlsext_tick) { + SSL_CIPHER *pref_cipher = NULL; + s->session->master_key_length = sizeof(s->session->master_key); + if (s->tls_session_secret_cb(s, s->session->master_key, + &s->session->master_key_length, + NULL, &pref_cipher, + s->tls_session_secret_cb_arg)) { + s->session->cipher = pref_cipher ? + pref_cipher : ssl_get_cipher_by_char(s, p + j); + } else { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } +#endif /* OPENSSL_NO_TLSEXT */ + + if (j != 0 && j == s->session->session_id_length + && memcmp(p, s->session->session_id, j) == 0) { + if (s->sid_ctx_length != s->session->sid_ctx_length + || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) { + /* actually a client application bug */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + goto f_err; + } + s->hit = 1; + } else { + /* + * If we were trying for session-id reuse but the server + * didn't echo the ID, make a new SSL_SESSION. + * In the case of EAP-FAST and PAC, we do not send a session ID, + * so the PAC-based session secret is always preserved. It'll be + * overwritten if the server refuses resumption. + */ + if (s->session->session_id_length > 0) { + if (!ssl_get_new_session(s, 0)) { + goto f_err; + } + } + s->session->session_id_length = j; + memcpy(s->session->session_id, p, j); /* j could be 0 */ + } + p += j; + c = ssl_get_cipher_by_char(s, p); + if (c == NULL) { + /* unknown cipher */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_UNKNOWN_CIPHER_RETURNED); + goto f_err; + } + /* Set version disabled mask now we know version */ + if (!SSL_USE_TLS1_2_CIPHERS(s)) + ct->mask_ssl = SSL_TLSV1_2; + else + ct->mask_ssl = 0; + /* + * If it is a disabled cipher we didn't send it in client hello, so + * return an error. + */ + if (c->algorithm_ssl & ct->mask_ssl || + c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); + goto f_err; + } + p += ssl_put_cipher_by_char(s, NULL, NULL); + + sk = ssl_get_ciphers_by_id(s); + i = sk_SSL_CIPHER_find(sk, c); + if (i < 0) { + /* we did not say we would use this cipher */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); + goto f_err; + } + + /* + * Depending on the session caching (internal/external), the cipher + * and/or cipher_id values may not be set. Make sure that cipher_id is + * set and use it for comparison. + */ + if (s->session->cipher) + s->session->cipher_id = s->session->cipher->id; + if (s->hit && (s->session->cipher_id != c->id)) { +/* Workaround is now obsolete */ +#if 0 + if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) +#endif + { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + goto f_err; + } + } + s->s3->tmp.new_cipher = c; + /* + * Don't digest cached records if no sigalgs: we may need them for client + * authentication. + */ + if (!SSL_USE_SIGALGS(s) && !ssl3_digest_cached_records(s)) + goto f_err; + /* lets get the compression algorithm */ + /* COMPRESSION */ +#ifdef OPENSSL_NO_COMP + if (*(p++) != 0) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + goto f_err; + } + /* + * If compression is disabled we'd better not try to resume a session + * using compression. + */ + if (s->session->compress_meth != 0) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } +#else + j = *(p++); + if (s->hit && j != s->session->compress_meth) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED); + goto f_err; + } + if (j == 0) + comp = NULL; + else if (s->options & SSL_OP_NO_COMPRESSION) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_COMPRESSION_DISABLED); + goto f_err; + } else + comp = ssl3_comp_find(s->ctx->comp_methods, j); + + if ((j != 0) && (comp == NULL)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + goto f_err; + } else { + s->s3->tmp.new_compression = comp; + } +#endif + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (!ssl_parse_serverhello_tlsext(s, &p, d, n)) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_PARSE_TLSEXT); + goto err; + } +#endif + + if (p != (d + n)) { + /* wrong packet length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH); + goto f_err; + } + + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_server_certificate(SSL *s) +{ + int al, i, ok, ret = -1; + unsigned long n, nc, llen, l; + X509 *x = NULL; + const unsigned char *q, *p; + unsigned char *d; + STACK_OF(X509) *sk = NULL; + SESS_CERT *sc; + EVP_PKEY *pkey = NULL; + int need_cert = 1; /* VRS: 0=> will allow null cert if auth == + * KRB5 */ + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_CERT_A, + SSL3_ST_CR_CERT_B, + -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) || + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && + (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE))) { + s->s3->tmp.reuse_message = 1; + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + p = d = (unsigned char *)s->init_msg; + + if ((sk = sk_X509_new_null()) == NULL) { + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + + n2l3(p, llen); + if (llen + 3 != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + for (nc = 0; nc < llen;) { + if (nc + 3 > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + + q = p; + x = d2i_X509(NULL, &q, l); + if (x == NULL) { + al = SSL_AD_BAD_CERTIFICATE; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_ASN1_LIB); + goto f_err; + } + if (q != (p + l)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + if (!sk_X509_push(sk, x)) { + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + x = NULL; + nc += l + 3; + p = q; + } + + i = ssl_verify_cert_chain(s, sk); + if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0) +#ifndef OPENSSL_NO_KRB5 + && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) +#endif /* OPENSSL_NO_KRB5 */ + ) { + al = ssl_verify_alarm_type(s->verify_result); + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERTIFICATE_VERIFY_FAILED); + goto f_err; + } + ERR_clear_error(); /* but we keep s->verify_result */ + + sc = ssl_sess_cert_new(); + if (sc == NULL) + goto err; + + if (s->session->sess_cert) + ssl_sess_cert_free(s->session->sess_cert); + s->session->sess_cert = sc; + + sc->cert_chain = sk; + /* + * Inconsistency alert: cert_chain does include the peer's certificate, + * which we don't include in s3_srvr.c + */ + x = sk_X509_value(sk, 0); + sk = NULL; + /* + * VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end + */ + + pkey = X509_get_pubkey(x); + + /* VRS: allow null cert if auth == KRB5 */ + need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) + ? 0 : 1; + +#ifdef KSSL_DEBUG + fprintf(stderr, "pkey,x = %p, %p\n", pkey, x); + fprintf(stderr, "ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x, pkey)); + fprintf(stderr, "cipher, alg, nc = %s, %lx, %lx, %d\n", + s->s3->tmp.new_cipher->name, + s->s3->tmp.new_cipher->algorithm_mkey, + s->s3->tmp.new_cipher->algorithm_auth, need_cert); +#endif /* KSSL_DEBUG */ + + if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) { + x = NULL; + al = SSL3_AL_FATAL; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); + goto f_err; + } + + i = ssl_cert_type(x, pkey); + if (need_cert && i < 0) { + x = NULL; + al = SSL3_AL_FATAL; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto f_err; + } + + if (need_cert) { + int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); + if (exp_idx >= 0 && i != exp_idx) { + x = NULL; + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_WRONG_CERTIFICATE_TYPE); + goto f_err; + } + sc->peer_cert_type = i; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + /* + * Why would the following ever happen? We just created sc a couple + * of lines ago. + */ + if (sc->peer_pkeys[i].x509 != NULL) + X509_free(sc->peer_pkeys[i].x509); + sc->peer_pkeys[i].x509 = x; + sc->peer_key = &(sc->peer_pkeys[i]); + + if (s->session->peer != NULL) + X509_free(s->session->peer); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + s->session->peer = x; + } else { + sc->peer_cert_type = i; + sc->peer_key = NULL; + + if (s->session->peer != NULL) + X509_free(s->session->peer); + s->session->peer = NULL; + } + s->session->verify_result = s->verify_result; + + x = NULL; + ret = 1; + if (0) { + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + } + + EVP_PKEY_free(pkey); + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return (ret); +} + +int ssl3_get_key_exchange(SSL *s) +{ +#ifndef OPENSSL_NO_RSA + unsigned char *q, md_buf[EVP_MAX_MD_SIZE * 2]; +#endif + EVP_MD_CTX md_ctx; + unsigned char *param, *p; + int al, j, ok; + long i, param_len, n, alg_k, alg_a; + EVP_PKEY *pkey = NULL; + const EVP_MD *md = NULL; +#ifndef OPENSSL_NO_RSA + RSA *rsa = NULL; +#endif +#ifndef OPENSSL_NO_DH + DH *dh = NULL; +#endif +#ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh = NULL; + BN_CTX *bn_ctx = NULL; + EC_POINT *srvr_ecpoint = NULL; + int curve_nid = 0; + int encoded_pt_len = 0; +#endif + + EVP_MD_CTX_init(&md_ctx); + + /* + * use same message size as in ssl3_get_certificate_request() as + * ServerKeyExchange message may be skipped + */ + n = s->method->ssl_get_message(s, + SSL3_ST_CR_KEY_EXCH_A, + SSL3_ST_CR_KEY_EXCH_B, + -1, s->max_cert_list, &ok); + if (!ok) + return ((int)n); + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { + /* + * Can't skip server key exchange if this is an ephemeral + * ciphersuite. + */ + if (alg_k & (SSL_kDHE | SSL_kECDHE)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto f_err; + } +#ifndef OPENSSL_NO_PSK + /* + * In plain PSK ciphersuite, ServerKeyExchange can be omitted if no + * identity hint is sent. Set session->sess_cert anyway to avoid + * problems later. + */ + if (alg_k & SSL_kPSK) { + s->session->sess_cert = ssl_sess_cert_new(); + if (s->ctx->psk_identity_hint) + OPENSSL_free(s->ctx->psk_identity_hint); + s->ctx->psk_identity_hint = NULL; + } +#endif + s->s3->tmp.reuse_message = 1; + return (1); + } + + param = p = (unsigned char *)s->init_msg; + if (s->session->sess_cert != NULL) { +#ifndef OPENSSL_NO_RSA + if (s->session->sess_cert->peer_rsa_tmp != NULL) { + RSA_free(s->session->sess_cert->peer_rsa_tmp); + s->session->sess_cert->peer_rsa_tmp = NULL; + } +#endif +#ifndef OPENSSL_NO_DH + if (s->session->sess_cert->peer_dh_tmp) { + DH_free(s->session->sess_cert->peer_dh_tmp); + s->session->sess_cert->peer_dh_tmp = NULL; + } +#endif +#ifndef OPENSSL_NO_ECDH + if (s->session->sess_cert->peer_ecdh_tmp) { + EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); + s->session->sess_cert->peer_ecdh_tmp = NULL; + } +#endif + } else { + s->session->sess_cert = ssl_sess_cert_new(); + } + + /* Total length of the parameters including the length prefix */ + param_len = 0; + + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + + al = SSL_AD_DECODE_ERROR; + +#ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kPSK) { + param_len = 2; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + /* + * Store PSK identity hint for later use, hint is used in + * ssl3_send_client_key_exchange. Assume that the maximum length of + * a PSK identity hint can be as long as the maximum length of a PSK + * identity. + */ + if (i > PSK_MAX_IDENTITY_LEN) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); + goto f_err; + } + param_len += i; + + s->session->psk_identity_hint = BUF_strndup((char *)p, i); + if (s->session->psk_identity_hint == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; + } + + p += i; + n -= param_len; + } else +#endif /* !OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (alg_k & SSL_kSRP) { + param_len = 2; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH); + goto f_err; + } + param_len += i; + + if (!(s->srp_ctx.N = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH); + goto f_err; + } + param_len += i; + + if (!(s->srp_ctx.g = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (1 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 1; + + i = (unsigned int)(p[0]); + p++; + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_S_LENGTH); + goto f_err; + } + param_len += i; + + if (!(s->srp_ctx.s = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_B_LENGTH); + goto f_err; + } + param_len += i; + + if (!(s->srp_ctx.B = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + n -= param_len; + + if (!srp_verify_server_param(s, &al)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_PARAMETERS); + goto f_err; + } + +/* We must check if there is a certificate */ +# ifndef OPENSSL_NO_RSA + if (alg_a & SSL_aRSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); +# else + if (0) ; +# endif +# ifndef OPENSSL_NO_DSA + else if (alg_a & SSL_aDSS) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN]. + x509); +# endif + } else +#endif /* !OPENSSL_NO_SRP */ +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) { + /* Temporary RSA keys only allowed in export ciphersuites */ + if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + if ((rsa = RSA_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + param_len = 2; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH); + goto f_err; + } + param_len += i; + + if (!(rsa->n = BN_bin2bn(p, i, rsa->n))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_E_LENGTH); + goto f_err; + } + param_len += i; + + if (!(rsa->e = BN_bin2bn(p, i, rsa->e))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + n -= param_len; + + /* this should be because we are using an export cipher */ + if (alg_a & SSL_aRSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); + else { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (EVP_PKEY_bits(pkey) <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + s->session->sess_cert->peer_rsa_tmp = rsa; + rsa = NULL; + } +#else /* OPENSSL_NO_RSA */ + if (0) ; +#endif +#ifndef OPENSSL_NO_DH + else if (alg_k & SSL_kEDH) { + if ((dh = DH_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + + param_len = 2; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH); + goto f_err; + } + param_len += i; + + if (!(dh->p = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_LENGTH); + goto f_err; + } + param_len += i; + + if (!(dh->g = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_LENGTH); + goto f_err; + } + param_len += i; + + if (!(dh->pub_key = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + n -= param_len; + + if (BN_is_zero(dh->pub_key)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE); + goto f_err; + } + + /*- + * Check that p and g are suitable enough + * + * p is odd + * 1 < g < p - 1 + */ + { + BIGNUM *tmp = NULL; + + if (!BN_is_odd(dh->p)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE); + goto f_err; + } + if (BN_is_negative(dh->g) || BN_is_zero(dh->g) + || BN_is_one(dh->g)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); + goto f_err; + } + if ((tmp = BN_new()) == NULL + || BN_copy(tmp, dh->p) == NULL + || !BN_sub_word(tmp, 1)) { + BN_free(tmp); + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + if (BN_cmp(dh->g, tmp) >= 0) { + BN_free(tmp); + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); + goto f_err; + } + BN_free(tmp); + } + +# ifndef OPENSSL_NO_RSA + if (alg_a & SSL_aRSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); +# else + if (0) ; +# endif +# ifndef OPENSSL_NO_DSA + else if (alg_a & SSL_aDSS) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN]. + x509); +# endif + /* else anonymous DH, so no certificate or pkey. */ + + s->session->sess_cert->peer_dh_tmp = dh; + dh = NULL; + } else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); + goto f_err; + } +#endif /* !OPENSSL_NO_DH */ + +#ifndef OPENSSL_NO_ECDH + else if (alg_k & SSL_kEECDH) { + EC_GROUP *ngroup; + const EC_GROUP *group; + + if ((ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Extract elliptic curve parameters and the server's ephemeral ECDH + * public key. Keep accumulating lengths of various components in + * param_len and make sure it never exceeds n. + */ + + /* + * XXX: For now we only support named (not generic) curves and the + * ECParameters in this case is just three bytes. We also need one + * byte for the length of the encoded point + */ + param_len = 4; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + /* + * Check curve is one of our preferences, if not server has sent an + * invalid curve. ECParameters is 3 bytes. + */ + if (!tls1_check_curve(s, p, 3)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE); + goto f_err; + } + + if ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); + goto f_err; + } + + ngroup = EC_GROUP_new_by_curve_name(curve_nid); + if (ngroup == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + if (EC_KEY_set_group(ecdh, ngroup) == 0) { + EC_GROUP_free(ngroup); + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + EC_GROUP_free(ngroup); + + group = EC_KEY_get0_group(ecdh); + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + (EC_GROUP_get_degree(group) > 163)) { + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); + goto f_err; + } + + p += 3; + + /* Next, get the encoded ECPoint */ + if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || + ((bn_ctx = BN_CTX_new()) == NULL)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + encoded_pt_len = *p; /* length of encoded point */ + p += 1; + + if ((encoded_pt_len > n - param_len) || + (EC_POINT_oct2point(group, srvr_ecpoint, + p, encoded_pt_len, bn_ctx) == 0)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); + goto f_err; + } + param_len += encoded_pt_len; + + n -= param_len; + p += encoded_pt_len; + + /* + * The ECC/TLS specification does not mention the use of DSA to sign + * ECParameters in the server key exchange message. We do support RSA + * and ECDSA. + */ + if (0) ; +# ifndef OPENSSL_NO_RSA + else if (alg_a & SSL_aRSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); +# endif +# ifndef OPENSSL_NO_ECDSA + else if (alg_a & SSL_aECDSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); +# endif + /* else anonymous ECDH, so no certificate or pkey. */ + EC_KEY_set_public_key(ecdh, srvr_ecpoint); + s->session->sess_cert->peer_ecdh_tmp = ecdh; + ecdh = NULL; + BN_CTX_free(bn_ctx); + bn_ctx = NULL; + EC_POINT_free(srvr_ecpoint); + srvr_ecpoint = NULL; + } else if (alg_k) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } +#endif /* !OPENSSL_NO_ECDH */ + + /* p points to the next byte, there are 'n' bytes left */ + + /* if it was signed, check the signature */ + if (pkey != NULL) { + if (SSL_USE_SIGALGS(s)) { + int rv; + if (2 > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + rv = tls12_check_peer_sigalg(&md, s, p, pkey); + if (rv == -1) + goto err; + else if (rv == 0) { + goto f_err; + } +#ifdef SSL_DEBUG + fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); +#endif + p += 2; + n -= 2; + } else + md = EVP_sha1(); + + if (2 > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + n -= 2; + j = EVP_PKEY_size(pkey); + + /* + * Check signature length. If n is 0 then signature is empty + */ + if ((i != n) || (n > j) || (n <= 0)) { + /* wrong packet length */ + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH); + goto f_err; + } +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { + int num; + unsigned int size; + + j = 0; + q = md_buf; + for (num = 2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + if (EVP_DigestInit_ex(&md_ctx, + (num == 2) ? s->ctx->md5 : s->ctx->sha1, + NULL) <= 0 + || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&md_ctx, param, param_len) <= 0 + || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + q += size; + j += size; + } + i = RSA_verify(NID_md5_sha1, md_buf, j, p, n, pkey->pkey.rsa); + if (i < 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT); + goto f_err; + } + if (i == 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); + goto f_err; + } + } else +#endif + { + if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0 + || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_VerifyUpdate(&md_ctx, param, param_len) <= 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EVP_LIB); + goto f_err; + } + if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); + goto f_err; + } + } + } else { + /* aNULL, aSRP or kPSK do not need public keys */ + if (!(alg_a & (SSL_aNULL | SSL_aSRP)) && !(alg_k & SSL_kPSK)) { + /* Might be wrong key type, check it */ + if (ssl3_check_cert_and_algorithm(s)) + /* Otherwise this shouldn't happen */ + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + /* still data left over */ + if (n != 0) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE); + goto f_err; + } + } + EVP_PKEY_free(pkey); + EVP_MD_CTX_cleanup(&md_ctx); + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + EVP_PKEY_free(pkey); +#ifndef OPENSSL_NO_RSA + if (rsa != NULL) + RSA_free(rsa); +#endif +#ifndef OPENSSL_NO_DH + if (dh != NULL) + DH_free(dh); +#endif +#ifndef OPENSSL_NO_ECDH + BN_CTX_free(bn_ctx); + EC_POINT_free(srvr_ecpoint); + if (ecdh != NULL) + EC_KEY_free(ecdh); +#endif + EVP_MD_CTX_cleanup(&md_ctx); + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_certificate_request(SSL *s) +{ + int ok, ret = 0; + unsigned long n, nc, l; + unsigned int llen, ctype_num, i; + X509_NAME *xn = NULL; + const unsigned char *p, *q; + unsigned char *d; + STACK_OF(X509_NAME) *ca_sk = NULL; + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_CERT_REQ_A, + SSL3_ST_CR_CERT_REQ_B, + -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + s->s3->tmp.cert_req = 0; + + if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) { + s->s3->tmp.reuse_message = 1; + /* + * If we get here we don't need any cached handshake records as we + * wont be doing client auth. + */ + if (s->s3->handshake_buffer) { + if (!ssl3_digest_cached_records(s)) + goto err; + } + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_WRONG_MESSAGE_TYPE); + goto err; + } + + /* TLS does not like anon-DH with client cert */ + if (s->version > SSL3_VERSION) { + if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); + goto err; + } + } + + p = d = (unsigned char *)s->init_msg; + + if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* get the certificate types */ + ctype_num = *(p++); + if (s->cert->ctypes) { + OPENSSL_free(s->cert->ctypes); + s->cert->ctypes = NULL; + } + if (ctype_num > SSL3_CT_NUMBER) { + /* If we exceed static buffer copy all to cert structure */ + s->cert->ctypes = OPENSSL_malloc(ctype_num); + if (s->cert->ctypes == NULL) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(s->cert->ctypes, p, ctype_num); + s->cert->ctype_num = (size_t)ctype_num; + ctype_num = SSL3_CT_NUMBER; + } + for (i = 0; i < ctype_num; i++) + s->s3->tmp.ctype[i] = p[i]; + p += p[-1]; + if (SSL_USE_SIGALGS(s)) { + n2s(p, llen); + /* + * Check we have enough room for signature algorithms and following + * length value. + */ + if ((unsigned long)(p - d + llen + 2) > n) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + /* Clear certificate digests and validity flags */ + for (i = 0; i < SSL_PKEY_NUM; i++) { + s->cert->pkeys[i].digest = NULL; + s->cert->pkeys[i].valid_flags = 0; + } + if ((llen & 1) || !tls1_save_sigalgs(s, p, llen)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_SIGNATURE_ALGORITHMS_ERROR); + goto err; + } + if (!tls1_process_sigalgs(s)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + goto err; + } + p += llen; + } + + /* get the CA RDNs */ + n2s(p, llen); +#if 0 + { + FILE *out; + out = fopen("/tmp/vsign.der", "w"); + fwrite(p, 1, llen, out); + fclose(out); + } +#endif + + if ((unsigned long)(p - d + llen) != n) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); + goto err; + } + + for (nc = 0; nc < llen;) { + if (nc + 2 > llen) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); + goto err; + } + n2s(p, l); + if ((l + nc + 2) > llen) { + if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) + goto cont; /* netscape bugs */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); + goto err; + } + + q = p; + + if ((xn = d2i_X509_NAME(NULL, &q, l)) == NULL) { + /* If netscape tolerance is on, ignore errors */ + if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG) + goto cont; + else { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB); + goto err; + } + } + + if (q != (p + l)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_CA_DN_LENGTH_MISMATCH); + goto err; + } + if (!sk_X509_NAME_push(ca_sk, xn)) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + goto err; + } + xn = NULL; + + p += l; + nc += l + 2; + } + + if (0) { + cont: + ERR_clear_error(); + } + + /* we should setup a certificate to return.... */ + s->s3->tmp.cert_req = 1; + s->s3->tmp.ctype_num = ctype_num; + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + s->s3->tmp.ca_names = ca_sk; + ca_sk = NULL; + + ret = 1; + goto done; + err: + s->state = SSL_ST_ERR; + done: + X509_NAME_free(xn); + if (ca_sk != NULL) + sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); + return (ret); +} + +static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b) +{ + return (X509_NAME_cmp(*a, *b)); +} + +#ifndef OPENSSL_NO_TLSEXT +int ssl3_get_new_session_ticket(SSL *s) +{ + int ok, al, ret = 0, ticklen; + long n; + const unsigned char *p; + unsigned char *d; + unsigned long ticket_lifetime_hint; + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_SESSION_TICKET_A, + SSL3_ST_CR_SESSION_TICKET_B, + SSL3_MT_NEWSESSION_TICKET, 16384, &ok); + + if (!ok) + return ((int)n); + + if (n < 6) { + /* need at least ticket_lifetime_hint + ticket length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + p = d = (unsigned char *)s->init_msg; + + n2l(p, ticket_lifetime_hint); + n2s(p, ticklen); + /* ticket_lifetime_hint + ticket_length + ticket */ + if (ticklen + 6 != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + /* Server is allowed to change its mind and send an empty ticket. */ + if (ticklen == 0) + return 1; + + if (s->session->session_id_length > 0) { + int i = s->session_ctx->session_cache_mode; + SSL_SESSION *new_sess; + /* + * We reused an existing session, so we need to replace it with a new + * one + */ + if (i & SSL_SESS_CACHE_CLIENT) { + /* + * Remove the old session from the cache + */ + if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) { + if (s->session_ctx->remove_session_cb != NULL) + s->session_ctx->remove_session_cb(s->session_ctx, + s->session); + } else { + /* We carry on if this fails */ + SSL_CTX_remove_session(s->session_ctx, s->session); + } + } + + if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); + goto f_err; + } + + SSL_SESSION_free(s->session); + s->session = new_sess; + } + + if (s->session->tlsext_tick) { + OPENSSL_free(s->session->tlsext_tick); + s->session->tlsext_ticklen = 0; + } + s->session->tlsext_tick = OPENSSL_malloc(ticklen); + if (!s->session->tlsext_tick) { + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(s->session->tlsext_tick, p, ticklen); + s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; + s->session->tlsext_ticklen = ticklen; + /* + * There are two ways to detect a resumed ticket session. One is to set + * an appropriate session ID and then the server must return a match in + * ServerHello. This allows the normal client session ID matching to work + * and we know much earlier that the ticket has been accepted. The + * other way is to set zero length session ID when the ticket is + * presented and rely on the handshake to determine session resumption. + * We choose the former approach because this fits in with assumptions + * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is + * SHA256 is disabled) hash of the ticket. + */ + EVP_Digest(p, ticklen, + s->session->session_id, &s->session->session_id_length, +# ifndef OPENSSL_NO_SHA256 + EVP_sha256(), NULL); +# else + EVP_sha1(), NULL); +# endif + ret = 1; + return (ret); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_cert_status(SSL *s) +{ + int ok, al; + unsigned long resplen, n; + const unsigned char *p; + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_CERT_STATUS_A, + SSL3_ST_CR_CERT_STATUS_B, + -1, 16384, &ok); + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { + /* + * The CertificateStatus message is optional even if + * tlsext_status_expected is set + */ + s->s3->tmp.reuse_message = 1; + } else { + if (n < 4) { + /* need at least status type + length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + p = (unsigned char *)s->init_msg; + if (*p++ != TLSEXT_STATUSTYPE_ocsp) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE); + goto f_err; + } + n2l3(p, resplen); + if (resplen + 4 != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + s->tlsext_ocsp_resp = BUF_memdup(p, resplen); + if (s->tlsext_ocsp_resp == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE); + goto f_err; + } + s->tlsext_ocsp_resplen = resplen; + } + if (s->ctx->tlsext_status_cb) { + int ret; + ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + if (ret == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_INVALID_STATUS_RESPONSE); + goto f_err; + } + if (ret < 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE); + goto f_err; + } + } + return 1; + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->state = SSL_ST_ERR; + return (-1); +} +#endif + +int ssl3_get_server_done(SSL *s) +{ + int ok, ret = 0; + long n; + + /* Second to last param should be very small, like 0 :-) */ + n = s->method->ssl_get_message(s, + SSL3_ST_CR_SRVR_DONE_A, + SSL3_ST_CR_SRVR_DONE_B, + SSL3_MT_SERVER_DONE, 30, &ok); + + if (!ok) + return ((int)n); + if (n > 0) { + /* should contain no data */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_SERVER_DONE, SSL_R_LENGTH_MISMATCH); + s->state = SSL_ST_ERR; + return -1; + } + ret = 1; + return (ret); +} + +#ifndef OPENSSL_NO_DH +static DH *get_server_static_dh_key(SESS_CERT *scert) +{ + DH *dh_srvr = NULL; + EVP_PKEY *spkey = NULL; + int idx = scert->peer_cert_type; + + if (idx >= 0) + spkey = X509_get_pubkey(scert->peer_pkeys[idx].x509); + if (spkey) { + dh_srvr = EVP_PKEY_get1_DH(spkey); + EVP_PKEY_free(spkey); + } + if (dh_srvr == NULL) + SSLerr(SSL_F_GET_SERVER_STATIC_DH_KEY, ERR_R_INTERNAL_ERROR); + return dh_srvr; +} +#endif + +int ssl3_send_client_key_exchange(SSL *s) +{ + unsigned char *p; + int n; + unsigned long alg_k; +#ifndef OPENSSL_NO_RSA + unsigned char *q; + EVP_PKEY *pkey = NULL; +#endif +#ifndef OPENSSL_NO_KRB5 + KSSL_ERR kssl_err; +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_ECDH + EC_KEY *clnt_ecdh = NULL; + const EC_POINT *srvr_ecpoint = NULL; + EVP_PKEY *srvr_pub_pkey = NULL; + unsigned char *encodedPoint = NULL; + int encoded_pt_len = 0; + BN_CTX *bn_ctx = NULL; +#endif + + if (s->state == SSL3_ST_CW_KEY_EXCH_A) { + p = ssl_handshake_start(s); + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* Fool emacs indentation */ + if (0) { + } +#ifndef OPENSSL_NO_RSA + else if (alg_k & SSL_kRSA) { + RSA *rsa; + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + + if (s->session->sess_cert == NULL) { + /* + * We should always have a server certificate with SSL_kRSA. + */ + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (s->session->sess_cert->peer_rsa_tmp != NULL) + rsa = s->session->sess_cert->peer_rsa_tmp; + else { + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC]. + x509); + if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) + || (pkey->pkey.rsa == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + EVP_PKEY_free(pkey); + goto err; + } + rsa = pkey->pkey.rsa; + EVP_PKEY_free(pkey); + } + + tmp_buf[0] = s->client_version >> 8; + tmp_buf[1] = s->client_version & 0xff; + if (RAND_bytes(&(tmp_buf[2]), sizeof(tmp_buf) - 2) <= 0) + goto err; + + s->session->master_key_length = sizeof(tmp_buf); + + q = p; + /* Fix buf for TLS and beyond */ + if (s->version > SSL3_VERSION) + p += 2; + n = RSA_public_encrypt(sizeof(tmp_buf), + tmp_buf, p, rsa, RSA_PKCS1_PADDING); +# ifdef PKCS1_CHECK + if (s->options & SSL_OP_PKCS1_CHECK_1) + p[1]++; + if (s->options & SSL_OP_PKCS1_CHECK_2) + tmp_buf[0] = 0x70; +# endif + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_RSA_ENCRYPT); + goto err; + } + + /* Fix buf for TLS and beyond */ + if (s->version > SSL3_VERSION) { + s2n(n, q); + n += 2; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + tmp_buf, + sizeof(tmp_buf)); + OPENSSL_cleanse(tmp_buf, sizeof(tmp_buf)); + } +#endif +#ifndef OPENSSL_NO_KRB5 + else if (alg_k & SSL_kKRB5) { + krb5_error_code krb5rc; + KSSL_CTX *kssl_ctx = s->kssl_ctx; + /* krb5_data krb5_ap_req; */ + krb5_data *enc_ticket; + krb5_data authenticator, *authp = NULL; + EVP_CIPHER_CTX ciph_ctx; + const EVP_CIPHER *enc = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_IV_LENGTH]; + int padl, outl = sizeof(epms); + + EVP_CIPHER_CTX_init(&ciph_ctx); + +# ifdef KSSL_DEBUG + fprintf(stderr, "ssl3_send_client_key_exchange(%lx & %lx)\n", + alg_k, SSL_kKRB5); +# endif /* KSSL_DEBUG */ + + authp = NULL; +# ifdef KRB5SENDAUTH + if (KRB5SENDAUTH) + authp = &authenticator; +# endif /* KRB5SENDAUTH */ + + krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, &kssl_err); + enc = kssl_map_enc(kssl_ctx->enctype); + if (enc == NULL) + goto err; +# ifdef KSSL_DEBUG + { + fprintf(stderr, "kssl_cget_tkt rtn %d\n", krb5rc); + if (krb5rc && kssl_err.text) + fprintf(stderr, "kssl_cget_tkt kssl_err=%s\n", + kssl_err.text); + } +# endif /* KSSL_DEBUG */ + + if (krb5rc) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason); + goto err; + } + + /*- + * 20010406 VRS - Earlier versions used KRB5 AP_REQ + * in place of RFC 2712 KerberosWrapper, as in: + * + * Send ticket (copy to *p, set n = length) + * n = krb5_ap_req.length; + * memcpy(p, krb5_ap_req.data, krb5_ap_req.length); + * if (krb5_ap_req.data) + * kssl_krb5_free_data_contents(NULL,&krb5_ap_req); + * + * Now using real RFC 2712 KerberosWrapper + * (Thanks to Simon Wilkinson ) + * Note: 2712 "opaque" types are here replaced + * with a 2-byte length followed by the value. + * Example: + * KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms + * Where "xx xx" = length bytes. Shown here with + * optional authenticator omitted. + */ + + /* KerberosWrapper.Ticket */ + s2n(enc_ticket->length, p); + memcpy(p, enc_ticket->data, enc_ticket->length); + p += enc_ticket->length; + n = enc_ticket->length + 2; + + /* KerberosWrapper.Authenticator */ + if (authp && authp->length) { + s2n(authp->length, p); + memcpy(p, authp->data, authp->length); + p += authp->length; + n += authp->length + 2; + + free(authp->data); + authp->data = NULL; + authp->length = 0; + } else { + s2n(0, p); /* null authenticator length */ + n += 2; + } + + tmp_buf[0] = s->client_version >> 8; + tmp_buf[1] = s->client_version & 0xff; + if (RAND_bytes(&(tmp_buf[2]), sizeof(tmp_buf) - 2) <= 0) + goto err; + + /*- + * 20010420 VRS. Tried it this way; failed. + * EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL); + * EVP_CIPHER_CTX_set_key_length(&ciph_ctx, + * kssl_ctx->length); + * EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); + */ + + memset(iv, 0, sizeof(iv)); /* per RFC 1510 */ + EVP_EncryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv); + EVP_EncryptUpdate(&ciph_ctx, epms, &outl, tmp_buf, + sizeof(tmp_buf)); + EVP_EncryptFinal_ex(&ciph_ctx, &(epms[outl]), &padl); + outl += padl; + if (outl > (int)sizeof(epms)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + /* KerberosWrapper.EncryptedPreMasterSecret */ + s2n(outl, p); + memcpy(p, epms, outl); + p += outl; + n += outl + 2; + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + tmp_buf, + sizeof(tmp_buf)); + + OPENSSL_cleanse(tmp_buf, sizeof(tmp_buf)); + OPENSSL_cleanse(epms, outl); + } +#endif +#ifndef OPENSSL_NO_DH + else if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { + DH *dh_srvr, *dh_clnt; + SESS_CERT *scert = s->session->sess_cert; + + if (scert == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNEXPECTED_MESSAGE); + goto err; + } + + if (scert->peer_dh_tmp != NULL) { + dh_srvr = scert->peer_dh_tmp; + } else { + dh_srvr = get_server_static_dh_key(scert); + if (dh_srvr == NULL) + goto err; + } + + if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { + /* Use client certificate key */ + EVP_PKEY *clkey = s->cert->key->privatekey; + dh_clnt = NULL; + if (clkey) + dh_clnt = EVP_PKEY_get1_DH(clkey); + if (dh_clnt == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + /* generate a new random key */ + if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + if (!DH_generate_key(dh_clnt)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + DH_free(dh_clnt); + goto err; + } + } + + /* + * use the 'p' output buffer for the DH key, but make sure to + * clear it out afterwards + */ + + n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); + if (scert->peer_dh_tmp == NULL) + DH_free(dh_srvr); + + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + DH_free(dh_clnt); + goto err; + } + + /* generate master key from the result */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, n); + /* clean up */ + memset(p, 0, n); + + if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) + n = 0; + else { + /* send off the data */ + n = BN_num_bytes(dh_clnt->pub_key); + s2n(n, p); + BN_bn2bin(dh_clnt->pub_key, p); + n += 2; + } + + DH_free(dh_clnt); + } +#endif + +#ifndef OPENSSL_NO_ECDH + else if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { + const EC_GROUP *srvr_group = NULL; + EC_KEY *tkey; + int ecdh_clnt_cert = 0; + int field_size = 0; + + if (s->session->sess_cert == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNEXPECTED_MESSAGE); + goto err; + } + + /* + * Did we send out the client's ECDH share for use in premaster + * computation as part of client certificate? If so, set + * ecdh_clnt_cert to 1. + */ + if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->cert != NULL)) { + /*- + * XXX: For now, we do not support client + * authentication using ECDH certificates. + * To add such support, one needs to add + * code that checks for appropriate + * conditions and sets ecdh_clnt_cert to 1. + * For example, the cert have an ECC + * key on the same curve as the server's + * and the key should be authorized for + * key agreement. + * + * One also needs to add code in ssl3_connect + * to skip sending the certificate verify + * message. + * + * if ((s->cert->key->privatekey != NULL) && + * (s->cert->key->privatekey->type == + * EVP_PKEY_EC) && ...) + * ecdh_clnt_cert = 1; + */ + } + + if (s->session->sess_cert->peer_ecdh_tmp != NULL) { + tkey = s->session->sess_cert->peer_ecdh_tmp; + } else { + /* Get the Server Public Key from Cert */ + srvr_pub_pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); + if ((srvr_pub_pkey == NULL) + || (srvr_pub_pkey->type != EVP_PKEY_EC) + || (srvr_pub_pkey->pkey.ec == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + tkey = srvr_pub_pkey->pkey.ec; + } + + srvr_group = EC_KEY_get0_group(tkey); + srvr_ecpoint = EC_KEY_get0_public_key(tkey); + + if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((clnt_ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + if (ecdh_clnt_cert) { + /* + * Reuse key info from our certificate We only need our + * private key to perform the ECDH computation. + */ + const BIGNUM *priv_key; + tkey = s->cert->key->privatekey->pkey.ec; + priv_key = EC_KEY_get0_private_key(tkey); + if (priv_key == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + } else { + /* Generate a new ECDH key pair */ + if (!(EC_KEY_generate_key(clnt_ecdh))) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + } + + /* + * use the 'p' output buffer for the ECDH key, but make sure to + * clear it out afterwards + */ + + field_size = EC_GROUP_get_degree(srvr_group); + if (field_size <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint, + clnt_ecdh, NULL); + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + /* generate master key from the result */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, n); + + memset(p, 0, n); /* clean up */ + + if (ecdh_clnt_cert) { + /* Send empty client key exch message */ + n = 0; + } else { + /* + * First check the size of encoding and allocate memory + * accordingly. + */ + encoded_pt_len = + EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = (unsigned char *) + OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char)); + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || (bn_ctx == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Encode the public key */ + n = EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encoded_pt_len, bn_ctx); + + *p = n; /* length of encoded point */ + /* Encoded point will be copied here */ + p += 1; + /* copy the point */ + memcpy((unsigned char *)p, encodedPoint, n); + /* increment n to account for length field */ + n += 1; + } + + /* Free allocated memory */ + BN_CTX_free(bn_ctx); + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + if (clnt_ecdh != NULL) + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); + } +#endif /* !OPENSSL_NO_ECDH */ + else if (alg_k & SSL_kGOST) { + /* GOST key exchange message creation */ + EVP_PKEY_CTX *pkey_ctx; + X509 *peer_cert; + size_t msglen; + unsigned int md_len; + int keytype; + unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; + EVP_MD_CTX *ukm_hash; + EVP_PKEY *pub_key; + + /* + * Get server sertificate PKEY and create ctx from it + */ + peer_cert = + s->session-> + sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST01)].x509; + if (!peer_cert) + peer_cert = + s->session-> + sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST94)].x509; + if (!peer_cert) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); + goto err; + } + + pkey_ctx = EVP_PKEY_CTX_new(pub_key = + X509_get_pubkey(peer_cert), NULL); + if (pkey_ctx == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + /* + * If we have send a certificate, and certificate key + * + * * parameters match those of server certificate, use + * certificate key for key exchange + */ + + /* Otherwise, generate ephemeral key pair */ + + if (pkey_ctx == NULL + || EVP_PKEY_encrypt_init(pkey_ctx) <= 0 + /* Generate session key */ + || RAND_bytes(premaster_secret, 32) <= 0) { + EVP_PKEY_CTX_free(pkey_ctx); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* + * Compute shared IV and store it in algorithm-specific context + * data + */ + ukm_hash = EVP_MD_CTX_create(); + if (EVP_DigestInit(ukm_hash, + EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0 + || EVP_DigestUpdate(ukm_hash, s->s3->client_random, + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(ukm_hash, s->s3->server_random, + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) { + EVP_MD_CTX_destroy(ukm_hash); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + EVP_MD_CTX_destroy(ukm_hash); + if (EVP_PKEY_CTX_ctrl + (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8, + shared_ukm) < 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_LIBRARY_BUG); + goto err; + } + /* Make GOST keytransport blob message */ + /* + * Encapsulate it into sequence + */ + *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; + msglen = 255; + if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32) + <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_LIBRARY_BUG); + goto err; + } + if (msglen >= 0x80) { + *(p++) = 0x81; + *(p++) = msglen & 0xff; + n = msglen + 3; + } else { + *(p++) = msglen & 0xff; + n = msglen + 2; + } + memcpy(p, tmp, msglen); + EVP_PKEY_CTX_free(pkey_ctx); + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + premaster_secret, + 32); + EVP_PKEY_free(pub_key); + + } +#ifndef OPENSSL_NO_SRP + else if (alg_k & SSL_kSRP) { + if (s->srp_ctx.A != NULL) { + /* send off the data */ + n = BN_num_bytes(s->srp_ctx.A); + s2n(n, p); + BN_bn2bin(s->srp_ctx.A, p); + n += 2; + } else { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + if (s->session->srp_username != NULL) + OPENSSL_free(s->session->srp_username); + s->session->srp_username = BUF_strdup(s->srp_ctx.login); + if (s->session->srp_username == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((s->session->master_key_length = + SRP_generate_client_master_secret(s, + s->session->master_key)) < + 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + } +#endif +#ifndef OPENSSL_NO_PSK + else if (alg_k & SSL_kPSK) { + /* + * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a + * \0-terminated identity. The last byte is for us for simulating + * strnlen. + */ + char identity[PSK_MAX_IDENTITY_LEN + 2]; + size_t identity_len; + unsigned char *t = NULL; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; + unsigned int pre_ms_len = 0, psk_len = 0; + int psk_err = 1; + + n = 0; + if (s->psk_client_callback == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_CLIENT_CB); + goto err; + } + + memset(identity, 0, sizeof(identity)); + psk_len = s->psk_client_callback(s, s->session->psk_identity_hint, + identity, sizeof(identity) - 1, + psk_or_pre_ms, + sizeof(psk_or_pre_ms)); + if (psk_len > PSK_MAX_PSK_LEN) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } else if (psk_len == 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + goto psk_err; + } + identity[PSK_MAX_IDENTITY_LEN + 1] = '\0'; + identity_len = strlen(identity); + if (identity_len > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } + /* create PSK pre_master_secret */ + pre_ms_len = 2 + psk_len + 2 + psk_len; + t = psk_or_pre_ms; + memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t += psk_len; + s2n(psk_len, t); + + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = + BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL + && s->session->psk_identity_hint == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strdup(identity); + if (s->session->psk_identity == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + psk_or_pre_ms, + pre_ms_len); + s2n(identity_len, p); + memcpy(p, identity, identity_len); + n = 2 + identity_len; + psk_err = 0; + psk_err: + OPENSSL_cleanse(identity, sizeof(identity)); + OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_err != 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + } +#endif + else { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n); + s->state = SSL3_ST_CW_KEY_EXCH_B; + } + + /* SSL3_ST_CW_KEY_EXCH_B */ + return ssl_do_write(s); + err: +#ifndef OPENSSL_NO_ECDH + BN_CTX_free(bn_ctx); + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + if (clnt_ecdh != NULL) + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); +#endif + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_send_client_verify(SSL *s) +{ + unsigned char *p; + unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; + EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx = NULL; + EVP_MD_CTX mctx; + unsigned u = 0; + unsigned long n; + int j; + + EVP_MD_CTX_init(&mctx); + + if (s->state == SSL3_ST_CW_CERT_VRFY_A) { + p = ssl_handshake_start(s); + pkey = s->cert->key->privatekey; +/* Create context from key and test if sha1 is allowed as digest */ + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (pctx == NULL || EVP_PKEY_sign_init(pctx) <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) { + if (!SSL_USE_SIGALGS(s)) + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, + &(data + [MD5_DIGEST_LENGTH])); + } else { + ERR_clear_error(); + } + /* + * For TLS v1.2 send signature algorithm and signature using agreed + * digest and cached handshake records. + */ + if (SSL_USE_SIGALGS(s)) { + long hdatalen = 0; + void *hdata; + const EVP_MD *md = s->cert->key->digest; + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + p += 2; +#ifdef SSL_DEBUG + fprintf(stderr, "Using TLS 1.2 with client alg %s\n", + EVP_MD_name(md)); +#endif + if (!EVP_SignInit_ex(&mctx, md, NULL) + || !EVP_SignUpdate(&mctx, hdata, hdatalen) + || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_EVP_LIB); + goto err; + } + s2n(u, p); + n = u + 4; + if (!ssl3_digest_cached_records(s)) + goto err; + } else +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA) { + s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0])); + if (RSA_sign(NID_md5_sha1, data, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, + &(p[2]), &u, pkey->pkey.rsa) <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB); + goto err; + } + s2n(u, p); + n = u + 2; + } else +#endif +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) { + if (!DSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, &(p[2]), + (unsigned int *)&j, pkey->pkey.dsa)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB); + goto err; + } + s2n(j, p); + n = j + 2; + } else +#endif +#ifndef OPENSSL_NO_ECDSA + if (pkey->type == EVP_PKEY_EC) { + if (!ECDSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, &(p[2]), + (unsigned int *)&j, pkey->pkey.ec)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB); + goto err; + } + s2n(j, p); + n = j + 2; + } else +#endif + if (pkey->type == NID_id_GostR3410_94 + || pkey->type == NID_id_GostR3410_2001) { + unsigned char signbuf[64]; + int i; + size_t sigsize = 64; + s->method->ssl3_enc->cert_verify_mac(s, + NID_id_GostR3411_94, data); + if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + for (i = 63, j = 0; i >= 0; j++, i--) { + p[2 + j] = signbuf[i]; + } + s2n(j, p); + n = j + 2; + } else { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n); + s->state = SSL3_ST_CW_CERT_VRFY_B; + } + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_CTX_free(pctx); + return ssl_do_write(s); + err: + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_CTX_free(pctx); + s->state = SSL_ST_ERR; + return (-1); +} + +/* + * Check a certificate can be used for client authentication. Currently check + * cert exists, if we have a suitable digest for TLS 1.2 if static DH client + * certificates can be used and optionally checks suitability for Suite B. + */ +static int ssl3_check_client_certificate(SSL *s) +{ + unsigned long alg_k; + if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey) + return 0; + /* If no suitable signature algorithm can't use certificate */ + if (SSL_USE_SIGALGS(s) && !s->cert->key->digest) + return 0; + /* + * If strict mode check suitability of chain before using it. This also + * adjusts suite B digest if necessary. + */ + if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT && + !tls1_check_chain(s, NULL, NULL, NULL, -2)) + return 0; + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + /* See if we can use client certificate for fixed DH */ + if (alg_k & (SSL_kDHr | SSL_kDHd)) { + SESS_CERT *scert = s->session->sess_cert; + int i = scert->peer_cert_type; + EVP_PKEY *clkey = NULL, *spkey = NULL; + clkey = s->cert->key->privatekey; + /* If client key not DH assume it can be used */ + if (EVP_PKEY_id(clkey) != EVP_PKEY_DH) + return 1; + if (i >= 0) + spkey = X509_get_pubkey(scert->peer_pkeys[i].x509); + if (spkey) { + /* Compare server and client parameters */ + i = EVP_PKEY_cmp_parameters(clkey, spkey); + EVP_PKEY_free(spkey); + if (i != 1) + return 0; + } + s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; + } + return 1; +} + +int ssl3_send_client_certificate(SSL *s) +{ + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int i; + + if (s->state == SSL3_ST_CW_CERT_A) { + /* Let cert callback update client certificates if required */ + if (s->cert->cert_cb) { + i = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return -1; + } + if (i == 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return 0; + } + s->rwstate = SSL_NOTHING; + } + if (ssl3_check_client_certificate(s)) + s->state = SSL3_ST_CW_CERT_C; + else + s->state = SSL3_ST_CW_CERT_B; + } + + /* We need to get a client cert */ + if (s->state == SSL3_ST_CW_CERT_B) { + /* + * If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP; + * return(-1); We then get retied later + */ + i = ssl_do_client_cert_cb(s, &x509, &pkey); + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return (-1); + } + s->rwstate = SSL_NOTHING; + if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { + s->state = SSL3_ST_CW_CERT_B; + if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) + i = 0; + } else if (i == 1) { + i = 0; + SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, + SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + } + + if (x509 != NULL) + X509_free(x509); + if (pkey != NULL) + EVP_PKEY_free(pkey); + if (i && !ssl3_check_client_certificate(s)) + i = 0; + if (i == 0) { + if (s->version == SSL3_VERSION) { + s->s3->tmp.cert_req = 0; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); + return (1); + } else { + s->s3->tmp.cert_req = 2; + } + } + + /* Ok, we have a cert */ + s->state = SSL3_ST_CW_CERT_C; + } + + if (s->state == SSL3_ST_CW_CERT_C) { + s->state = SSL3_ST_CW_CERT_D; + if (!ssl3_output_cert_chain(s, + (s->s3->tmp.cert_req == + 2) ? NULL : s->cert->key)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return 0; + } + } + /* SSL3_ST_CW_CERT_D */ + return ssl_do_write(s); +} + +#define has_bits(i,m) (((i)&(m)) == (m)) + +int ssl3_check_cert_and_algorithm(SSL *s) +{ + int i, idx; + long alg_k, alg_a; + EVP_PKEY *pkey = NULL; + int pkey_bits; + SESS_CERT *sc; +#ifndef OPENSSL_NO_RSA + RSA *rsa; +#endif +#ifndef OPENSSL_NO_DH + DH *dh; +#endif + int al = SSL_AD_HANDSHAKE_FAILURE; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + + /* we don't have a certificate */ + if ((alg_a & (SSL_aNULL | SSL_aKRB5)) || (alg_k & SSL_kPSK)) + return (1); + + sc = s->session->sess_cert; + if (sc == NULL) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifndef OPENSSL_NO_RSA + rsa = s->session->sess_cert->peer_rsa_tmp; +#endif +#ifndef OPENSSL_NO_DH + dh = s->session->sess_cert->peer_dh_tmp; +#endif + + /* This is the passed certificate */ + + idx = sc->peer_cert_type; +#ifndef OPENSSL_NO_ECDH + if (idx == SSL_PKEY_ECC) { + if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s) == 0) { + /* check failed */ + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_BAD_ECC_CERT); + goto f_err; + } else { + return 1; + } + } else if (alg_a & SSL_aECDSA) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_ECDSA_SIGNING_CERT); + goto f_err; + } else if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_ECDH_CERT); + goto f_err; + } +#endif + pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509); + pkey_bits = EVP_PKEY_bits(pkey); + i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey); + EVP_PKEY_free(pkey); + + /* Check that we have a certificate if we require one */ + if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_SIGNING_CERT); + goto f_err; + } +#ifndef OPENSSL_NO_DSA + else if ((alg_a & SSL_aDSS) && !has_bits(i, EVP_PK_DSA | EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DSA_SIGNING_CERT); + goto f_err; + } +#endif +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) { + if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_ENCRYPTING_CERT); + goto f_err; + } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { + if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_ENCRYPTING_CERT); + goto f_err; + } + if (rsa != NULL) { + /* server key exchange is not allowed. */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); + goto f_err; + } + } + } + } +#endif +#ifndef OPENSSL_NO_DH + if ((alg_k & SSL_kEDH) && dh == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); + goto f_err; + } + if ((alg_k & SSL_kDHr) && !SSL_USE_SIGALGS(s) && + !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DH_RSA_CERT); + goto f_err; + } +# ifndef OPENSSL_NO_DSA + if ((alg_k & SSL_kDHd) && !SSL_USE_SIGALGS(s) && + !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DH_DSA_CERT); + goto f_err; + } +# endif + + if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd)) { + int dh_size; + if (alg_k & SSL_kDHE) { + dh_size = BN_num_bits(dh->p); + } else { + DH *dh_srvr = get_server_static_dh_key(sc); + if (dh_srvr == NULL) + goto f_err; + dh_size = BN_num_bits(dh_srvr->p); + DH_free(dh_srvr); + } + + if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 1024) + || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); + goto f_err; + } + } +#endif /* !OPENSSL_NO_DH */ + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) { + if (rsa == NULL) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_RSA_KEY); + goto f_err; + } else if (BN_num_bits(rsa->n) > + SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + /* We have a temporary RSA key but it's too large. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_RSA_KEY); + goto f_err; + } + } else +#endif +#ifndef OPENSSL_NO_DH + if (alg_k & SSL_kDHE) { + if (BN_num_bits(dh->p) > + SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + /* We have a temporary DH key but it's too large. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_DH_KEY); + goto f_err; + } + } else if (alg_k & (SSL_kDHr | SSL_kDHd)) { + /* The cert should have had an export DH key. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_DH_KEY); + goto f_err; + } else +#endif + { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + goto f_err; + } + } + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (0); +} + +#ifndef OPENSSL_NO_TLSEXT +/* + * Normally, we can tell if the server is resuming the session from + * the session ID. EAP-FAST (RFC 4851), however, relies on the next server + * message after the ServerHello to determine if the server is resuming. + * Therefore, we allow EAP-FAST to peek ahead. + * ssl3_check_finished returns 1 if we are resuming from an external + * pre-shared secret, we have a "ticket" and the next server handshake message + * is Finished; and 0 otherwise. It returns -1 upon an error. + */ +static int ssl3_check_finished(SSL *s) +{ + int ok = 0; + + if (s->version < TLS1_VERSION || !s->tls_session_secret_cb || + !s->session->tlsext_tick) + return 0; + + /* Need to permit this temporarily, in case the next message is Finished. */ + s->s3->flags |= SSL3_FLAGS_CCS_OK; + /* + * This function is called when we might get a Certificate message instead, + * so permit appropriate message length. + * We ignore the return value as we're only interested in the message type + * and not its length. + */ + s->method->ssl_get_message(s, + SSL3_ST_CR_CERT_A, + SSL3_ST_CR_CERT_B, + -1, s->max_cert_list, &ok); + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + + if (!ok) + return -1; + + s->s3->tmp.reuse_message = 1; + + if (s->s3->tmp.message_type == SSL3_MT_FINISHED) + return 1; + + /* If we're not done, then the CCS arrived early and we should bail. */ + if (s->s3->change_cipher_spec) { + SSLerr(SSL_F_SSL3_CHECK_FINISHED, SSL_R_CCS_RECEIVED_EARLY); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + return 0; +} + +# ifndef OPENSSL_NO_NEXTPROTONEG +int ssl3_send_next_proto(SSL *s) +{ + unsigned int len, padding_len; + unsigned char *d; + + if (s->state == SSL3_ST_CW_NEXT_PROTO_A) { + len = s->next_proto_negotiated_len; + padding_len = 32 - ((len + 2) % 32); + d = (unsigned char *)s->init_buf->data; + d[4] = len; + memcpy(d + 5, s->next_proto_negotiated, len); + d[5 + len] = padding_len; + memset(d + 6 + len, 0, padding_len); + *(d++) = SSL3_MT_NEXT_PROTO; + l2n3(2 + len + padding_len, d); + s->state = SSL3_ST_CW_NEXT_PROTO_B; + s->init_num = 4 + 2 + len + padding_len; + s->init_off = 0; + } + + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); +} +#endif /* !OPENSSL_NO_NEXTPROTONEG */ +#endif /* !OPENSSL_NO_TLSEXT */ + +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) +{ + int i = 0; +#ifndef OPENSSL_NO_ENGINE + if (s->ctx->client_cert_engine) { + i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, + SSL_get_client_CA_list(s), + px509, ppkey, NULL, NULL, NULL); + if (i != 0) + return i; + } +#endif + if (s->ctx->client_cert_cb) + i = s->ctx->client_cert_cb(s, px509, ppkey); + return i; +} +/* ssl/s3_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +// #include "ssl_locl.h" +// #include "evp.h" +// #include "md5.h" + +static unsigned char ssl3_pad_1[48] = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 +}; + +static unsigned char ssl3_pad_2[48] = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c +}; + +static int ssl3_handshake_mac(SSL *s, int md_nid, + const char *sender, int len, unsigned char *p); +static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) +{ + EVP_MD_CTX m5; + EVP_MD_CTX s1; + unsigned char buf[16], smd[SHA_DIGEST_LENGTH]; + unsigned char c = 'A'; + unsigned int i, j, k; + +#ifdef CHARSET_EBCDIC + c = os_toascii[c]; /* 'A' in ASCII */ +#endif + k = 0; + EVP_MD_CTX_init(&m5); + EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_MD_CTX_init(&s1); + for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { + k++; + if (k > sizeof(buf)) + /* bug: 'buf' is too small for this ciphersuite */ + goto err; + + for (j = 0; j < k; j++) + buf[j] = c; + c++; + if (!EVP_DigestInit_ex(&s1, EVP_sha1(), NULL) || + !EVP_DigestUpdate(&s1, buf, k) || + !EVP_DigestUpdate(&s1, s->session->master_key, + s->session->master_key_length) || + !EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&s1, smd, NULL)) + goto err2; + + if (!EVP_DigestInit_ex(&m5, EVP_md5(), NULL) || + !EVP_DigestUpdate(&m5, s->session->master_key, + s->session->master_key_length) || + !EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH)) + goto err2; + if ((int)(i + MD5_DIGEST_LENGTH) > num) { + if (!EVP_DigestFinal_ex(&m5, smd, NULL)) + goto err2; + memcpy(km, smd, (num - i)); + } else + if (!EVP_DigestFinal_ex(&m5, km, NULL)) + goto err2; + + km += MD5_DIGEST_LENGTH; + } + OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH); + EVP_MD_CTX_cleanup(&m5); + EVP_MD_CTX_cleanup(&s1); + return 1; + err: + SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); + err2: + EVP_MD_CTX_cleanup(&m5); + EVP_MD_CTX_cleanup(&s1); + return 0; +} + +int ssl3_change_cipher_state(SSL *s, int which) +{ + unsigned char *p, *mac_secret; + unsigned char exp_key[EVP_MAX_KEY_LENGTH]; + unsigned char exp_iv[EVP_MAX_IV_LENGTH]; + unsigned char *ms, *key, *iv, *er1, *er2; + EVP_CIPHER_CTX *dd; + const EVP_CIPHER *c; +#ifndef OPENSSL_NO_COMP + COMP_METHOD *comp; +#endif + const EVP_MD *m; + EVP_MD_CTX md; + int is_exp, n, i, j, k, cl; + int reuse_dd = 0; + + is_exp = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); + c = s->s3->tmp.new_sym_enc; + m = s->s3->tmp.new_hash; + /* m == NULL will lead to a crash later */ + OPENSSL_assert(m); +#ifndef OPENSSL_NO_COMP + if (s->s3->tmp.new_compression == NULL) + comp = NULL; + else + comp = s->s3->tmp.new_compression->method; +#endif + + if (which & SSL3_CC_READ) { + if (s->enc_read_ctx != NULL) + reuse_dd = 1; + else if ((s->enc_read_ctx = + OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) + goto err; + else + /* + * make sure it's intialized in case we exit later with an error + */ + EVP_CIPHER_CTX_init(s->enc_read_ctx); + dd = s->enc_read_ctx; + + if (ssl_replace_hash(&s->read_hash, m) == NULL) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } +#ifndef OPENSSL_NO_COMP + /* COMPRESS */ + if (s->expand != NULL) { + COMP_CTX_free(s->expand); + s->expand = NULL; + } + if (comp != NULL) { + s->expand = COMP_CTX_new(comp); + if (s->expand == NULL) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, + SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + if (s->s3->rrec.comp == NULL) + s->s3->rrec.comp = (unsigned char *) + OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); + if (s->s3->rrec.comp == NULL) + goto err; + } +#endif + memset(&(s->s3->read_sequence[0]), 0, 8); + mac_secret = &(s->s3->read_mac_secret[0]); + } else { + if (s->enc_write_ctx != NULL) + reuse_dd = 1; + else if ((s->enc_write_ctx = + OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) + goto err; + else + /* + * make sure it's intialized in case we exit later with an error + */ + EVP_CIPHER_CTX_init(s->enc_write_ctx); + dd = s->enc_write_ctx; + if (ssl_replace_hash(&s->write_hash, m) == NULL) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } +#ifndef OPENSSL_NO_COMP + /* COMPRESS */ + if (s->compress != NULL) { + COMP_CTX_free(s->compress); + s->compress = NULL; + } + if (comp != NULL) { + s->compress = COMP_CTX_new(comp); + if (s->compress == NULL) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, + SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + } +#endif + memset(&(s->s3->write_sequence[0]), 0, 8); + mac_secret = &(s->s3->write_mac_secret[0]); + } + + if (reuse_dd) + EVP_CIPHER_CTX_cleanup(dd); + + p = s->s3->tmp.key_block; + i = EVP_MD_size(m); + if (i < 0) + goto err2; + cl = EVP_CIPHER_key_length(c); + j = is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? + cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; + /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */ + k = EVP_CIPHER_iv_length(c); + if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || + (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { + ms = &(p[0]); + n = i + i; + key = &(p[n]); + n += j + j; + iv = &(p[n]); + n += k + k; + er1 = &(s->s3->client_random[0]); + er2 = &(s->s3->server_random[0]); + } else { + n = i; + ms = &(p[n]); + n += i + j; + key = &(p[n]); + n += j + k; + iv = &(p[n]); + n += k; + er1 = &(s->s3->server_random[0]); + er2 = &(s->s3->client_random[0]); + } + + if (n > s->s3->tmp.key_block_length) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + + EVP_MD_CTX_init(&md); + memcpy(mac_secret, ms, i); + if (is_exp) { + /* + * In here I set both the read and write key/iv to the same value + * since only the correct one will be used :-). + */ + if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || + !EVP_DigestUpdate(&md, key, j) || + !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL)) { + EVP_MD_CTX_cleanup(&md); + goto err2; + } + key = &(exp_key[0]); + + if (k > 0) { + if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || + !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL)) { + EVP_MD_CTX_cleanup(&md); + goto err2; + } + iv = &(exp_iv[0]); + } + } + EVP_MD_CTX_cleanup(&md); + + s->session->key_arg_length = 0; + + if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) + goto err2; + +#ifdef OPENSSL_SSL_TRACE_CRYPTO + if (s->msg_callback) { + + int wh = which & SSL3_CC_WRITE ? + TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ; + s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC, + mac_secret, EVP_MD_size(m), s, s->msg_callback_arg); + if (c->key_len) + s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, + key, c->key_len, s, s->msg_callback_arg); + if (k) { + s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV, + iv, k, s, s->msg_callback_arg); + } + } +#endif + + OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key)); + OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv)); + return (1); + err: + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); + err2: + return (0); +} + +int ssl3_setup_key_block(SSL *s) +{ + unsigned char *p; + const EVP_CIPHER *c; + const EVP_MD *hash; + int num; + int ret = 0; + SSL_COMP *comp; + + if (s->s3->tmp.key_block_length != 0) + return (1); + + if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp)) { + SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } + + s->s3->tmp.new_sym_enc = c; + s->s3->tmp.new_hash = hash; +#ifdef OPENSSL_NO_COMP + s->s3->tmp.new_compression = NULL; +#else + s->s3->tmp.new_compression = comp; +#endif + + num = EVP_MD_size(hash); + if (num < 0) + return 0; + + num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c); + num *= 2; + + ssl3_cleanup_key_block(s); + + if ((p = OPENSSL_malloc(num)) == NULL) + goto err; + + s->s3->tmp.key_block_length = num; + s->s3->tmp.key_block = p; + + ret = ssl3_generate_key_block(s, p, num); + + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { + /* + * enable vulnerability countermeasure for CBC ciphers with known-IV + * problem (http://www.openssl.org/~bodo/tls-cbc.txt) + */ + s->s3->need_empty_fragments = 1; + + if (s->session->cipher != NULL) { + if (s->session->cipher->algorithm_enc == SSL_eNULL) + s->s3->need_empty_fragments = 0; + +#ifndef OPENSSL_NO_RC4 + if (s->session->cipher->algorithm_enc == SSL_RC4) + s->s3->need_empty_fragments = 0; +#endif + } + } + + return ret; + + err: + SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + return (0); +} + +void ssl3_cleanup_key_block(SSL *s) +{ + if (s->s3->tmp.key_block != NULL) { + OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length); + OPENSSL_free(s->s3->tmp.key_block); + s->s3->tmp.key_block = NULL; + } + s->s3->tmp.key_block_length = 0; +} + +/*- + * ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding is invalid or, if sending, an internal error + * occured. + */ +int ssl3_enc(SSL *s, int send) +{ + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs, i, mac_size = 0; + const EVP_CIPHER *enc; + + if (send) { + ds = s->enc_write_ctx; + rec = &(s->s3->wrec); + if (s->enc_write_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + } else { + ds = s->enc_read_ctx; + rec = &(s->s3->rrec); + if (s->enc_read_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + } + + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + } else { + l = rec->length; + bs = EVP_CIPHER_block_size(ds->cipher); + + /* COMPRESS */ + + if ((bs != 1) && send) { + i = bs - ((int)l % bs); + + /* we need to add 'i-1' padding bytes */ + l += i; + /* + * the last of these zero bytes will be overwritten with the + * padding length. + */ + memset(&rec->input[rec->length], 0, i); + rec->length += i; + rec->input[l - 1] = (i - 1); + } + + if (!send) { + if (l == 0 || l % bs != 0) + return 0; + /* otherwise, rec->length >= bs */ + } + + if (EVP_Cipher(ds, rec->data, rec->input, l) < 1) + return -1; + + if (EVP_MD_CTX_md(s->read_hash) != NULL) + mac_size = EVP_MD_CTX_size(s->read_hash); + if ((bs != 1) && !send) + return ssl3_cbc_remove_padding(s, rec, bs, mac_size); + } + return 1; +} + +int ssl3_init_finished_mac(SSL *s) +{ + if (s->s3->handshake_buffer) + BIO_free(s->s3->handshake_buffer); + if (s->s3->handshake_dgst) + ssl3_free_digest_list(s); + s->s3->handshake_buffer = BIO_new(BIO_s_mem()); + if (s->s3->handshake_buffer == NULL) + return 0; + (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); + return 1; +} + +void ssl3_free_digest_list(SSL *s) +{ + int i; + if (!s->s3->handshake_dgst) + return; + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i]) + EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]); + } + OPENSSL_free(s->s3->handshake_dgst); + s->s3->handshake_dgst = NULL; +} + +void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) +{ + if (s->s3->handshake_buffer + && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { + BIO_write(s->s3->handshake_buffer, (void *)buf, len); + } else { + int i; + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i] != NULL) + EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len); + } + } +} + +int ssl3_digest_cached_records(SSL *s) +{ + int i; + long mask; + const EVP_MD *md; + long hdatalen; + void *hdata; + + /* Allocate handshake_dgst array */ + ssl3_free_digest_list(s); + s->s3->handshake_dgst = + OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); + if (s->s3->handshake_dgst == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); + return 0; + } + memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH); + return 0; + } + + /* Loop through bitso of algorithm2 field and create MD_CTX-es */ + for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { + if ((mask & ssl_get_algorithm2(s)) && md) { + s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); + if (s->s3->handshake_dgst[i] == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); + return 0; + } +#ifdef OPENSSL_FIPS + if (EVP_MD_nid(md) == NID_md5) { + EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i], + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } +#endif + if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL) + || !EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, + hdatalen)) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR); + return 0; + } + } else { + s->s3->handshake_dgst[i] = NULL; + } + } + if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { + /* Free handshake_buffer BIO */ + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + } + + return 1; +} + +int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p) +{ + return (ssl3_handshake_mac(s, md_nid, NULL, 0, p)); +} + +int ssl3_final_finish_mac(SSL *s, + const char *sender, int len, unsigned char *p) +{ + int ret, sha1len; + ret = ssl3_handshake_mac(s, NID_md5, sender, len, p); + if (ret == 0) + return 0; + + p += ret; + + sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p); + if (sha1len == 0) + return 0; + + ret += sha1len; + return (ret); +} + +static int ssl3_handshake_mac(SSL *s, int md_nid, + const char *sender, int len, unsigned char *p) +{ + unsigned int ret; + int npad, n; + unsigned int i; + unsigned char md_buf[EVP_MAX_MD_SIZE]; + EVP_MD_CTX ctx, *d = NULL; + + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; + + /* + * Search for digest of specified type in the handshake_dgst array + */ + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i] + && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { + d = s->s3->handshake_dgst[i]; + break; + } + } + if (!d) { + SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST); + return 0; + } + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_MD_CTX_copy_ex(&ctx, d); + n = EVP_MD_CTX_size(&ctx); + if (n < 0) + return 0; + + npad = (48 / n) * n; + if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0) + || EVP_DigestUpdate(&ctx, s->session->master_key, + s->session->master_key_length) <= 0 + || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0 + || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0 + + || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0 + || EVP_DigestUpdate(&ctx, s->session->master_key, + s->session->master_key_length) <= 0 + || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0 + || EVP_DigestUpdate(&ctx, md_buf, i) <= 0 + || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) { + SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR); + ret = 0; + } + + EVP_MD_CTX_cleanup(&ctx); + + return ((int)ret); +} + +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) +{ + SSL3_RECORD *rec; + unsigned char *mac_sec, *seq; + EVP_MD_CTX md_ctx; + const EVP_MD_CTX *hash; + unsigned char *p, rec_char; + size_t md_size, orig_len; + int npad; + int t; + + if (send) { + rec = &(ssl->s3->wrec); + mac_sec = &(ssl->s3->write_mac_secret[0]); + seq = &(ssl->s3->write_sequence[0]); + hash = ssl->write_hash; + } else { + rec = &(ssl->s3->rrec); + mac_sec = &(ssl->s3->read_mac_secret[0]); + seq = &(ssl->s3->read_sequence[0]); + hash = ssl->read_hash; + } + + t = EVP_MD_CTX_size(hash); + if (t < 0) + return -1; + md_size = t; + npad = (48 / md_size) * md_size; + + /* + * kludge: ssl3_cbc_remove_padding passes padding length in rec->type + */ + orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); + rec->type &= 0xff; + + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(hash)) { + /* + * This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of data we + * are hashing because that gives an attacker a timing-oracle. + */ + + /*- + * npad is, at most, 48 bytes and that's with MD5: + * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. + * + * With SHA-1 (the largest hash speced for SSLv3) the hash size + * goes up 4, but npad goes down by 8, resulting in a smaller + * total size. + */ + unsigned char header[75]; + unsigned j = 0; + memcpy(header + j, mac_sec, md_size); + j += md_size; + memcpy(header + j, ssl3_pad_1, npad); + j += npad; + memcpy(header + j, seq, 8); + j += 8; + header[j++] = rec->type; + header[j++] = rec->length >> 8; + header[j++] = rec->length & 0xff; + + /* Final param == is SSLv3 */ + if (ssl3_cbc_digest_record(hash, + md, &md_size, + header, rec->input, + rec->length + md_size, orig_len, + mac_sec, md_size, 1) <= 0) + return -1; + } else { + unsigned int md_size_u; + /* Chop the digest off the end :-) */ + EVP_MD_CTX_init(&md_ctx); + + rec_char = rec->type; + p = md; + s2n(rec->length, p); + if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0 + || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0 + || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0 + || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0 + || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0 + || EVP_DigestUpdate(&md_ctx, md, 2) <= 0 + || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0 + || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0 + || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0 + || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0 + || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0 + || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0 + || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) { + EVP_MD_CTX_cleanup(&md_ctx); + return -1; + } + md_size = md_size_u; + + EVP_MD_CTX_cleanup(&md_ctx); + } + + ssl3_record_sequence_update(seq); + return (md_size); +} + +void ssl3_record_sequence_update(unsigned char *seq) +{ + int i; + + for (i = 7; i >= 0; i--) { + ++seq[i]; + if (seq[i] != 0) + break; + } +} + +int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, + int len) +{ + static const unsigned char *salt[3] = { +#ifndef CHARSET_EBCDIC + (const unsigned char *)"A", + (const unsigned char *)"BB", + (const unsigned char *)"CCC", +#else + (const unsigned char *)"\x41", + (const unsigned char *)"\x42\x42", + (const unsigned char *)"\x43\x43\x43", +#endif + }; + unsigned char buf[EVP_MAX_MD_SIZE]; + EVP_MD_CTX ctx; + int i, ret = 0; + unsigned int n; +#ifdef OPENSSL_SSL_TRACE_CRYPTO + unsigned char *tmpout = out; +#endif + + EVP_MD_CTX_init(&ctx); + for (i = 0; i < 3; i++) { + if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0 + || EVP_DigestUpdate(&ctx, salt[i], + strlen((const char *)salt[i])) <= 0 + || EVP_DigestUpdate(&ctx, p, len) <= 0 + || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0 + + || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0 + || EVP_DigestUpdate(&ctx, p, len) <= 0 + || EVP_DigestUpdate(&ctx, buf, n) <= 0 + || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) { + SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR); + ret = 0; + break; + } + out += n; + ret += n; + } + EVP_MD_CTX_cleanup(&ctx); + +#ifdef OPENSSL_SSL_TRACE_CRYPTO + if (ret > 0 && s->msg_callback) { + s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER, + p, len, s, s->msg_callback_arg); + s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM, + s->s3->client_random, SSL3_RANDOM_SIZE, + s, s->msg_callback_arg); + s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM, + s->s3->server_random, SSL3_RANDOM_SIZE, + s, s->msg_callback_arg); + s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER, + tmpout, SSL3_MASTER_SECRET_SIZE, + s, s->msg_callback_arg); + } +#endif + OPENSSL_cleanse(buf, sizeof(buf)); + return (ret); +} + +int ssl3_alert_code(int code) +{ + switch (code) { + case SSL_AD_CLOSE_NOTIFY: + return (SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: + return (SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_RECORD_OVERFLOW: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECOMPRESSION_FAILURE: + return (SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_CERTIFICATE: + return (SSL3_AD_NO_CERTIFICATE); + case SSL_AD_BAD_CERTIFICATE: + return (SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE: + return (SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED: + return (SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED: + return (SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN: + return (SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: + return (SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: + return (SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_ACCESS_DENIED: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_DECODE_ERROR: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_DECRYPT_ERROR: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_EXPORT_RESTRICTION: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_PROTOCOL_VERSION: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_INSUFFICIENT_SECURITY: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_INTERNAL_ERROR: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_USER_CANCELLED: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_RENEGOTIATION: + return (-1); /* Don't send it :-) */ + case SSL_AD_UNSUPPORTED_EXTENSION: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_CERTIFICATE_UNOBTAINABLE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_UNRECOGNIZED_NAME: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_UNKNOWN_PSK_IDENTITY: + return (TLS1_AD_UNKNOWN_PSK_IDENTITY); + case SSL_AD_INAPPROPRIATE_FALLBACK: + return (TLS1_AD_INAPPROPRIATE_FALLBACK); + default: + return (-1); + } +} +/* ssl/s3_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +// #include "objects.h" +// #include "ssl_locl.h" +// #include "kssl_lcl.h" +// #include "md5.h" +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +const char ssl3_version_str[] = "SSLv3" OPENSSL_VERSION_PTEXT; + +#define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER)) + +/* list of available SSLv3 ciphers (sorted by id) */ +OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { + +/* The RSA ciphers */ +/* Cipher 01 */ + { + 1, + SSL3_TXT_RSA_NULL_MD5, + SSL3_CK_RSA_NULL_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + +/* Cipher 02 */ + { + 1, + SSL3_TXT_RSA_NULL_SHA, + SSL3_CK_RSA_NULL_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + +/* Cipher 03 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_RSA_RC4_40_MD5, + SSL3_CK_RSA_RC4_40_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +#endif + +/* Cipher 04 */ + { + 1, + SSL3_TXT_RSA_RC4_128_MD5, + SSL3_CK_RSA_RC4_128_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 05 */ + { + 1, + SSL3_TXT_RSA_RC4_128_SHA, + SSL3_CK_RSA_RC4_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 06 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_RSA_RC2_40_MD5, + SSL3_CK_RSA_RC2_40_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +#endif + +/* Cipher 07 */ +#ifndef OPENSSL_NO_IDEA + { + 1, + SSL3_TXT_RSA_IDEA_128_SHA, + SSL3_CK_RSA_IDEA_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_IDEA, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +#endif + +/* Cipher 08 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_RSA_DES_40_CBC_SHA, + SSL3_CK_RSA_DES_40_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 09 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_RSA_DES_64_CBC_SHA, + SSL3_CK_RSA_DES_64_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 0A */ + { + 1, + SSL3_TXT_RSA_DES_192_CBC3_SHA, + SSL3_CK_RSA_DES_192_CBC3_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* The DH ciphers */ +/* Cipher 0B */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 0, + SSL3_TXT_DH_DSS_DES_40_CBC_SHA, + SSL3_CK_DH_DSS_DES_40_CBC_SHA, + SSL_kDHd, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 0C */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_DH_DSS_DES_64_CBC_SHA, + SSL3_CK_DH_DSS_DES_64_CBC_SHA, + SSL_kDHd, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 0D */ + { + 1, + SSL3_TXT_DH_DSS_DES_192_CBC3_SHA, + SSL3_CK_DH_DSS_DES_192_CBC3_SHA, + SSL_kDHd, + SSL_aDH, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 0E */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 0, + SSL3_TXT_DH_RSA_DES_40_CBC_SHA, + SSL3_CK_DH_RSA_DES_40_CBC_SHA, + SSL_kDHr, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 0F */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_DH_RSA_DES_64_CBC_SHA, + SSL3_CK_DH_RSA_DES_64_CBC_SHA, + SSL_kDHr, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 10 */ + { + 1, + SSL3_TXT_DH_RSA_DES_192_CBC3_SHA, + SSL3_CK_DH_RSA_DES_192_CBC3_SHA, + SSL_kDHr, + SSL_aDH, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* The Ephemeral DH ciphers */ +/* Cipher 11 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_EDH_DSS_DES_40_CBC_SHA, + SSL3_CK_EDH_DSS_DES_40_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 12 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_EDH_DSS_DES_64_CBC_SHA, + SSL3_CK_EDH_DSS_DES_64_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 13 */ + { + 1, + SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, + SSL3_CK_EDH_DSS_DES_192_CBC3_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 14 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_EDH_RSA_DES_40_CBC_SHA, + SSL3_CK_EDH_RSA_DES_40_CBC_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 15 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_EDH_RSA_DES_64_CBC_SHA, + SSL3_CK_EDH_RSA_DES_64_CBC_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 16 */ + { + 1, + SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, + SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 17 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_ADH_RC4_40_MD5, + SSL3_CK_ADH_RC4_40_MD5, + SSL_kEDH, + SSL_aNULL, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +#endif + +/* Cipher 18 */ + { + 1, + SSL3_TXT_ADH_RC4_128_MD5, + SSL3_CK_ADH_RC4_128_MD5, + SSL_kEDH, + SSL_aNULL, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 19 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_ADH_DES_40_CBC_SHA, + SSL3_CK_ADH_DES_40_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +#endif + +/* Cipher 1A */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_ADH_DES_64_CBC_SHA, + SSL3_CK_ADH_DES_64_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 1B */ + { + 1, + SSL3_TXT_ADH_DES_192_CBC_SHA, + SSL3_CK_ADH_DES_192_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Fortezza ciphersuite from SSL 3.0 spec */ +#if 0 +/* Cipher 1C */ + { + 0, + SSL3_TXT_FZA_DMS_NULL_SHA, + SSL3_CK_FZA_DMS_NULL_SHA, + SSL_kFZA, + SSL_aFZA, + SSL_eNULL, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + +/* Cipher 1D */ + { + 0, + SSL3_TXT_FZA_DMS_FZA_SHA, + SSL3_CK_FZA_DMS_FZA_SHA, + SSL_kFZA, + SSL_aFZA, + SSL_eFZA, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + +/* Cipher 1E */ + { + 0, + SSL3_TXT_FZA_DMS_RC4_SHA, + SSL3_CK_FZA_DMS_RC4_SHA, + SSL_kFZA, + SSL_aFZA, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +#endif + +#ifndef OPENSSL_NO_KRB5 +/* The Kerberos ciphers*/ +/* Cipher 1E */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_DES_64_CBC_SHA, + SSL3_CK_KRB5_DES_64_CBC_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +# endif + +/* Cipher 1F */ + { + 1, + SSL3_TXT_KRB5_DES_192_CBC3_SHA, + SSL3_CK_KRB5_DES_192_CBC3_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 20 */ + { + 1, + SSL3_TXT_KRB5_RC4_128_SHA, + SSL3_CK_KRB5_RC4_128_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 21 */ + { + 1, + SSL3_TXT_KRB5_IDEA_128_CBC_SHA, + SSL3_CK_KRB5_IDEA_128_CBC_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_IDEA, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 22 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_DES_64_CBC_MD5, + SSL3_CK_KRB5_DES_64_CBC_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +# endif + +/* Cipher 23 */ + { + 1, + SSL3_TXT_KRB5_DES_192_CBC3_MD5, + SSL3_CK_KRB5_DES_192_CBC3_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_3DES, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 24 */ + { + 1, + SSL3_TXT_KRB5_RC4_128_MD5, + SSL3_CK_KRB5_RC4_128_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 25 */ + { + 1, + SSL3_TXT_KRB5_IDEA_128_CBC_MD5, + SSL3_CK_KRB5_IDEA_128_CBC_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_IDEA, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 26 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_DES_40_CBC_SHA, + SSL3_CK_KRB5_DES_40_CBC_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +# endif + +/* Cipher 27 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_RC2_40_CBC_SHA, + SSL3_CK_KRB5_RC2_40_CBC_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC2, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +# endif + +/* Cipher 28 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_RC4_40_SHA, + SSL3_CK_KRB5_RC4_40_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +# endif + +/* Cipher 29 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_DES_40_CBC_MD5, + SSL3_CK_KRB5_DES_40_CBC_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +# endif + +/* Cipher 2A */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_RC2_40_CBC_MD5, + SSL3_CK_KRB5_RC2_40_CBC_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC2, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +# endif + +/* Cipher 2B */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_RC4_40_MD5, + SSL3_CK_KRB5_RC4_40_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +# endif +#endif /* OPENSSL_NO_KRB5 */ + +/* New AES ciphersuites */ +/* Cipher 2F */ + { + 1, + TLS1_TXT_RSA_WITH_AES_128_SHA, + TLS1_CK_RSA_WITH_AES_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 30 */ + { + 1, + TLS1_TXT_DH_DSS_WITH_AES_128_SHA, + TLS1_CK_DH_DSS_WITH_AES_128_SHA, + SSL_kDHd, + SSL_aDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 31 */ + { + 1, + TLS1_TXT_DH_RSA_WITH_AES_128_SHA, + TLS1_CK_DH_RSA_WITH_AES_128_SHA, + SSL_kDHr, + SSL_aDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 32 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_128_SHA, + TLS1_CK_DHE_DSS_WITH_AES_128_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 33 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, + TLS1_CK_DHE_RSA_WITH_AES_128_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 34 */ + { + 1, + TLS1_TXT_ADH_WITH_AES_128_SHA, + TLS1_CK_ADH_WITH_AES_128_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 35 */ + { + 1, + TLS1_TXT_RSA_WITH_AES_256_SHA, + TLS1_CK_RSA_WITH_AES_256_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +/* Cipher 36 */ + { + 1, + TLS1_TXT_DH_DSS_WITH_AES_256_SHA, + TLS1_CK_DH_DSS_WITH_AES_256_SHA, + SSL_kDHd, + SSL_aDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + +/* Cipher 37 */ + { + 1, + TLS1_TXT_DH_RSA_WITH_AES_256_SHA, + TLS1_CK_DH_RSA_WITH_AES_256_SHA, + SSL_kDHr, + SSL_aDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + +/* Cipher 38 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_256_SHA, + TLS1_CK_DHE_DSS_WITH_AES_256_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + +/* Cipher 39 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, + TLS1_CK_DHE_RSA_WITH_AES_256_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 3A */ + { + 1, + TLS1_TXT_ADH_WITH_AES_256_SHA, + TLS1_CK_ADH_WITH_AES_256_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* TLS v1.2 ciphersuites */ + /* Cipher 3B */ + { + 1, + TLS1_TXT_RSA_WITH_NULL_SHA256, + TLS1_CK_RSA_WITH_NULL_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher 3C */ + { + 1, + TLS1_TXT_RSA_WITH_AES_128_SHA256, + TLS1_CK_RSA_WITH_AES_128_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 3D */ + { + 1, + TLS1_TXT_RSA_WITH_AES_256_SHA256, + TLS1_CK_RSA_WITH_AES_256_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 3E */ + { + 1, + TLS1_TXT_DH_DSS_WITH_AES_128_SHA256, + TLS1_CK_DH_DSS_WITH_AES_128_SHA256, + SSL_kDHd, + SSL_aDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 3F */ + { + 1, + TLS1_TXT_DH_RSA_WITH_AES_128_SHA256, + TLS1_CK_DH_RSA_WITH_AES_128_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 40 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256, + TLS1_CK_DHE_DSS_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aDSS, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +#ifndef OPENSSL_NO_CAMELLIA + /* Camellia ciphersuites from RFC4132 (128-bit portion) */ + + /* Cipher 41 */ + { + 1, + TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 42 */ + { + 1, + TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, + SSL_kDHd, + SSL_aDH, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 43 */ + { + 1, + TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, + SSL_kDHr, + SSL_aDH, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 44 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 45 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 46 */ + { + 1, + TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + +#if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES + /* New TLS Export CipherSuites from expired ID */ +# if 0 + /* Cipher 60 */ + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5, + TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 128, + }, + + /* Cipher 61 */ + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, + TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 128, + }, +# endif + + /* Cipher 62 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA, + TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +# endif + + /* Cipher 63 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, + TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +# endif + + /* Cipher 64 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA, + TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 128, + }, +# endif + + /* Cipher 65 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, + TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 128, + }, +# endif + + /* Cipher 66 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA, + TLS1_CK_DHE_DSS_WITH_RC4_128_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +#endif + + /* TLS v1.2 ciphersuites */ + /* Cipher 67 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256, + TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 68 */ + { + 1, + TLS1_TXT_DH_DSS_WITH_AES_256_SHA256, + TLS1_CK_DH_DSS_WITH_AES_256_SHA256, + SSL_kDHd, + SSL_aDH, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 69 */ + { + 1, + TLS1_TXT_DH_RSA_WITH_AES_256_SHA256, + TLS1_CK_DH_RSA_WITH_AES_256_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6A */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256, + TLS1_CK_DHE_DSS_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aDSS, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6B */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256, + TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6C */ + { + 1, + TLS1_TXT_ADH_WITH_AES_128_SHA256, + TLS1_CK_ADH_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 6D */ + { + 1, + TLS1_TXT_ADH_WITH_AES_256_SHA256, + TLS1_CK_ADH_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* GOST Ciphersuites */ + + { + 1, + "GOST94-GOST89-GOST89", + 0x3000080, + SSL_kGOST, + SSL_aGOST94, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC, + 256, + 256}, + { + 1, + "GOST2001-GOST89-GOST89", + 0x3000081, + SSL_kGOST, + SSL_aGOST01, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC, + 256, + 256}, + { + 1, + "GOST94-NULL-GOST94", + 0x3000082, + SSL_kGOST, + SSL_aGOST94, + SSL_eNULL, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94, + 0, + 0}, + { + 1, + "GOST2001-NULL-GOST94", + 0x3000083, + SSL_kGOST, + SSL_aGOST01, + SSL_eNULL, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94, + 0, + 0}, + +#ifndef OPENSSL_NO_CAMELLIA + /* Camellia ciphersuites from RFC4132 (256-bit portion) */ + + /* Cipher 84 */ + { + 1, + TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + /* Cipher 85 */ + { + 1, + TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, + SSL_kDHd, + SSL_aDH, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 86 */ + { + 1, + TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, + SSL_kDHr, + SSL_aDH, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 87 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 88 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 89 */ + { + 1, + TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + +#ifndef OPENSSL_NO_PSK + /* Cipher 8A */ + { + 1, + TLS1_TXT_PSK_WITH_RC4_128_SHA, + TLS1_CK_PSK_WITH_RC4_128_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 8B */ + { + 1, + TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher 8C */ + { + 1, + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, + TLS1_CK_PSK_WITH_AES_128_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 8D */ + { + 1, + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, + TLS1_CK_PSK_WITH_AES_256_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_PSK */ + +#ifndef OPENSSL_NO_SEED + /* SEED ciphersuites from RFC4162 */ + + /* Cipher 96 */ + { + 1, + TLS1_TXT_RSA_WITH_SEED_SHA, + TLS1_CK_RSA_WITH_SEED_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 97 */ + { + 1, + TLS1_TXT_DH_DSS_WITH_SEED_SHA, + TLS1_CK_DH_DSS_WITH_SEED_SHA, + SSL_kDHd, + SSL_aDH, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 98 */ + { + 1, + TLS1_TXT_DH_RSA_WITH_SEED_SHA, + TLS1_CK_DH_RSA_WITH_SEED_SHA, + SSL_kDHr, + SSL_aDH, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 99 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_SEED_SHA, + TLS1_CK_DHE_DSS_WITH_SEED_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 9A */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_SEED_SHA, + TLS1_CK_DHE_RSA_WITH_SEED_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 9B */ + { + 1, + TLS1_TXT_ADH_WITH_SEED_SHA, + TLS1_CK_ADH_WITH_SEED_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +#endif /* OPENSSL_NO_SEED */ + + /* GCM ciphersuites from RFC5288 */ + + /* Cipher 9C */ + { + 1, + TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher 9D */ + { + 1, + TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, + SSL_kRSA, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher 9E */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kEDH, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher 9F */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kEDH, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher A0 */ + { + 1, + TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A1 */ + { + 1, + TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384, + SSL_kDHr, + SSL_aDH, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher A2 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256, + TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256, + SSL_kEDH, + SSL_aDSS, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A3 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384, + TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384, + SSL_kEDH, + SSL_aDSS, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher A4 */ + { + 1, + TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256, + TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256, + SSL_kDHd, + SSL_aDH, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A5 */ + { + 1, + TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384, + TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384, + SSL_kDHd, + SSL_aDH, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher A6 */ + { + 1, + TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256, + TLS1_CK_ADH_WITH_AES_128_GCM_SHA256, + SSL_kEDH, + SSL_aNULL, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A7 */ + { + 1, + TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384, + TLS1_CK_ADH_WITH_AES_256_GCM_SHA384, + SSL_kEDH, + SSL_aNULL, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + { + 1, + "SCSV", + SSL3_CK_SCSV, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0}, +#endif + +#ifndef OPENSSL_NO_ECDH + /* Cipher C001 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA, + TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C002 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C003 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C004 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C005 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C006 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C007 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C008 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C009 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C00A */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C00B */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_NULL_SHA, + TLS1_CK_ECDH_RSA_WITH_NULL_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C00C */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA, + TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C00D */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C00E */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C00F */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C010 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, + TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C011 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, + TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C012 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C013 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C014 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C015 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_NULL_SHA, + TLS1_CK_ECDH_anon_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C016 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA, + TLS1_CK_ECDH_anon_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C017 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C018 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C019 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_ECDH */ + +#ifndef OPENSSL_NO_SRP + /* Cipher C01A */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aSRP, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C01B */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C01C */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C01D */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aSRP, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C01E */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C01F */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C020 */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aSRP, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C021 */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C022 */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_SRP */ +#ifndef OPENSSL_NO_ECDH + + /* HMAC based TLS v1.2 ciphersuites from RFC5289 */ + + /* Cipher C023 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C024 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C025 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256, + TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256, + SSL_kECDHe, + SSL_aECDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C026 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384, + TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384, + SSL_kECDHe, + SSL_aECDH, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C027 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, + SSL_kEECDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C028 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, + SSL_kEECDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C029 */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256, + TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256, + SSL_kECDHr, + SSL_aECDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C02A */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384, + TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384, + SSL_kECDHr, + SSL_aECDH, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* GCM based TLS v1.2 ciphersuites from RFC5289 */ + + /* Cipher C02B */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C02C */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C02D */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHe, + SSL_aECDH, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C02E */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHe, + SSL_aECDH, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C02F */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kEECDH, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C030 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kEECDH, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C031 */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHr, + SSL_aECDH, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C032 */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHr, + SSL_aECDH, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + +#endif /* OPENSSL_NO_ECDH */ + +#ifdef TEMP_GOST_TLS +/* Cipher FF00 */ + { + 1, + "GOST-MD5", + 0x0300ff00, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_MD5, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + { + 1, + "GOST-GOST94", + 0x0300ff01, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256}, + { + 1, + "GOST-GOST89MAC", + 0x0300ff02, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256}, + { + 1, + "GOST-GOST89STREAM", + 0x0300ff03, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF | TLS1_STREAM_MAC, + 256, + 256}, +#endif + +/* end of list */ +}; + +SSL3_ENC_METHOD SSLv3_enc_data = { + ssl3_enc, + n_ssl3_mac, + ssl3_setup_key_block, + ssl3_generate_master_secret, + ssl3_change_cipher_state, + ssl3_final_finish_mac, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, + ssl3_cert_verify_mac, + SSL3_MD_CLIENT_FINISHED_CONST, 4, + SSL3_MD_SERVER_FINISHED_CONST, 4, + ssl3_alert_code, + (int (*)(SSL *, unsigned char *, size_t, const char *, + size_t, const unsigned char *, size_t, + int use_context))ssl_undefined_function, + 0, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write +}; + +long ssl3_default_timeout(void) +{ + /* + * 2 hours, the 24 hours mentioned in the SSLv3 spec is way too long for + * http, the cache would over fill + */ + return (60 * 60 * 2); +} + +int ssl3_num_ciphers(void) +{ + return (SSL3_NUM_CIPHERS); +} + +const SSL_CIPHER *ssl3_get_cipher(unsigned int u) +{ + if (u < SSL3_NUM_CIPHERS) + return (&(ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - u])); + else + return (NULL); +} + +int ssl3_pending(const SSL *s) +{ + if (s->rstate == SSL_ST_READ_BODY) + return 0; + + return (s->s3->rrec.type == + SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0; +} + +void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len) +{ + unsigned char *p = (unsigned char *)s->init_buf->data; + *(p++) = htype; + l2n3(len, p); + s->init_num = (int)len + SSL3_HM_HEADER_LENGTH; + s->init_off = 0; +} + +int ssl3_handshake_write(SSL *s) +{ + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); +} + +int ssl3_new(SSL *s) +{ + SSL3_STATE *s3; + + if ((s3 = OPENSSL_malloc(sizeof(*s3))) == NULL) + goto err; + memset(s3, 0, sizeof(*s3)); + memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num)); + memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num)); + + s->s3 = s3; + +#ifndef OPENSSL_NO_SRP + SSL_SRP_CTX_init(s); +#endif + s->method->ssl_clear(s); + return (1); + err: + return (0); +} + +void ssl3_free(SSL *s) +{ + if (s == NULL || s->s3 == NULL) + return; + +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL) + OPENSSL_free(s->s3->client_opaque_prf_input); + if (s->s3->server_opaque_prf_input != NULL) + OPENSSL_free(s->s3->server_opaque_prf_input); +#endif + + ssl3_cleanup_key_block(s); + if (s->s3->rbuf.buf != NULL) + ssl3_release_read_buffer(s); + if (s->s3->wbuf.buf != NULL) + ssl3_release_write_buffer(s); + if (s->s3->rrec.comp != NULL) + OPENSSL_free(s->s3->rrec.comp); +#ifndef OPENSSL_NO_DH + if (s->s3->tmp.dh != NULL) + DH_free(s->s3->tmp.dh); +#endif +#ifndef OPENSSL_NO_ECDH + if (s->s3->tmp.ecdh != NULL) + EC_KEY_free(s->s3->tmp.ecdh); +#endif + + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + } + if (s->s3->handshake_dgst) + ssl3_free_digest_list(s); +#ifndef OPENSSL_NO_TLSEXT + if (s->s3->alpn_selected) + OPENSSL_free(s->s3->alpn_selected); +#endif + +#ifndef OPENSSL_NO_SRP + SSL_SRP_CTX_free(s); +#endif + OPENSSL_cleanse(s->s3, sizeof(*s->s3)); + OPENSSL_free(s->s3); + s->s3 = NULL; +} + +void ssl3_clear(SSL *s) +{ + unsigned char *rp, *wp; + size_t rlen, wlen; + int init_extra; + +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL) + OPENSSL_free(s->s3->client_opaque_prf_input); + s->s3->client_opaque_prf_input = NULL; + if (s->s3->server_opaque_prf_input != NULL) + OPENSSL_free(s->s3->server_opaque_prf_input); + s->s3->server_opaque_prf_input = NULL; +#endif + + ssl3_cleanup_key_block(s); + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + + if (s->s3->rrec.comp != NULL) { + OPENSSL_free(s->s3->rrec.comp); + s->s3->rrec.comp = NULL; + } +#ifndef OPENSSL_NO_DH + if (s->s3->tmp.dh != NULL) { + DH_free(s->s3->tmp.dh); + s->s3->tmp.dh = NULL; + } +#endif +#ifndef OPENSSL_NO_ECDH + if (s->s3->tmp.ecdh != NULL) { + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + } +#endif +#ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC + s->s3->is_probably_safari = 0; +# endif /* !OPENSSL_NO_EC */ +#endif /* !OPENSSL_NO_TLSEXT */ + + rp = s->s3->rbuf.buf; + wp = s->s3->wbuf.buf; + rlen = s->s3->rbuf.len; + wlen = s->s3->wbuf.len; + init_extra = s->s3->init_extra; + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + } + if (s->s3->handshake_dgst) { + ssl3_free_digest_list(s); + } +#if !defined(OPENSSL_NO_TLSEXT) + if (s->s3->alpn_selected) { + OPENSSL_free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + } +#endif + memset(s->s3, 0, sizeof(*s->s3)); + s->s3->rbuf.buf = rp; + s->s3->wbuf.buf = wp; + s->s3->rbuf.len = rlen; + s->s3->wbuf.len = wlen; + s->s3->init_extra = init_extra; + + ssl_free_wbio_buffer(s); + + s->packet_length = 0; + s->s3->renegotiate = 0; + s->s3->total_renegotiations = 0; + s->s3->num_renegotiations = 0; + s->s3->in_read_app_data = 0; + s->version = SSL3_VERSION; + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + if (s->next_proto_negotiated) { + OPENSSL_free(s->next_proto_negotiated); + s->next_proto_negotiated = NULL; + s->next_proto_negotiated_len = 0; + } +#endif +} + +#ifndef OPENSSL_NO_SRP +static char *MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg) +{ + return BUF_strdup(s->srp_ctx.info); +} +#endif + +static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, + size_t len); + +long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA) + if ( +# ifndef OPENSSL_NO_RSA + cmd == SSL_CTRL_SET_TMP_RSA || cmd == SSL_CTRL_SET_TMP_RSA_CB || +# endif +# ifndef OPENSSL_NO_DSA + cmd == SSL_CTRL_SET_TMP_DH || cmd == SSL_CTRL_SET_TMP_DH_CB || +# endif + 0) { + if (!ssl_cert_inst(&s->cert)) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE); + return (0); + } + } +#endif + + switch (cmd) { + case SSL_CTRL_GET_SESSION_REUSED: + ret = s->hit; + break; + case SSL_CTRL_GET_CLIENT_CERT_REQUEST: + break; + case SSL_CTRL_GET_NUM_RENEGOTIATIONS: + ret = s->s3->num_renegotiations; + break; + case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: + ret = s->s3->num_renegotiations; + s->s3->num_renegotiations = 0; + break; + case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: + ret = s->s3->total_renegotiations; + break; + case SSL_CTRL_GET_FLAGS: + ret = (int)(s->s3->flags); + break; +#ifndef OPENSSL_NO_RSA + case SSL_CTRL_NEED_TMP_RSA: + if ((s->cert != NULL) && (s->cert->rsa_tmp == NULL) && + ((s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) || + (EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > + (512 / 8)))) + ret = 1; + break; + case SSL_CTRL_SET_TMP_RSA: + { + RSA *rsa = (RSA *)parg; + if (rsa == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return (ret); + } + if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_RSA_LIB); + return (ret); + } + if (s->cert->rsa_tmp != NULL) + RSA_free(s->cert->rsa_tmp); + s->cert->rsa_tmp = rsa; + ret = 1; + } + break; + case SSL_CTRL_SET_TMP_RSA_CB: + { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (ret); + } + break; +#endif +#ifndef OPENSSL_NO_DH + case SSL_CTRL_SET_TMP_DH: + { + DH *dh = (DH *)parg; + if (dh == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return (ret); + } + if ((dh = DHparams_dup(dh)) == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB); + return (ret); + } + if (s->cert->dh_tmp != NULL) + DH_free(s->cert->dh_tmp); + s->cert->dh_tmp = dh; + ret = 1; + } + break; + case SSL_CTRL_SET_TMP_DH_CB: + { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (ret); + } + break; +#endif +#ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_TMP_ECDH: + { + EC_KEY *ecdh = NULL; + + if (parg == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return (ret); + } + if (!EC_KEY_up_ref((EC_KEY *)parg)) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB); + return (ret); + } + ecdh = (EC_KEY *)parg; + if (!(s->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + EC_KEY_free(ecdh); + SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB); + return (ret); + } + } + if (s->cert->ecdh_tmp != NULL) + EC_KEY_free(s->cert->ecdh_tmp); + s->cert->ecdh_tmp = ecdh; + ret = 1; + } + break; + case SSL_CTRL_SET_TMP_ECDH_CB: + { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (ret); + } + break; +#endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_HOSTNAME: + if (larg == TLSEXT_NAMETYPE_host_name) { + size_t len; + + if (s->tlsext_hostname != NULL) + OPENSSL_free(s->tlsext_hostname); + s->tlsext_hostname = NULL; + + ret = 1; + if (parg == NULL) + break; + len = strlen((char *)parg); + if (len == 0 || len > TLSEXT_MAXLEN_host_name) { + SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); + return 0; + } + if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR); + return 0; + } + } else { + SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); + return 0; + } + break; + case SSL_CTRL_SET_TLSEXT_DEBUG_ARG: + s->tlsext_debug_arg = parg; + ret = 1; + break; + +# ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT: + if (larg > 12288) { /* actual internal limit is 2^16 for the + * complete hello message * (including the + * cert chain and everything) */ + SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG); + break; + } + if (s->tlsext_opaque_prf_input != NULL) + OPENSSL_free(s->tlsext_opaque_prf_input); + if ((size_t)larg == 0) + s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte + * just to get + * non-NULL */ + else + s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg); + if (s->tlsext_opaque_prf_input != NULL) { + s->tlsext_opaque_prf_input_len = (size_t)larg; + ret = 1; + } else + s->tlsext_opaque_prf_input_len = 0; + break; +# endif + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: + s->tlsext_status_type = larg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS: + *(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts; + ret = 1; + break; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS: + s->tlsext_ocsp_exts = parg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS: + *(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids; + ret = 1; + break; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS: + s->tlsext_ocsp_ids = parg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: + *(unsigned char **)parg = s->tlsext_ocsp_resp; + return s->tlsext_ocsp_resplen; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: + if (s->tlsext_ocsp_resp) + OPENSSL_free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = parg; + s->tlsext_ocsp_resplen = larg; + ret = 1; + break; + +# ifndef OPENSSL_NO_HEARTBEATS + case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT: + if (SSL_IS_DTLS(s)) + ret = dtls1_heartbeat(s); + else + ret = tls1_heartbeat(s); + break; + + case SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING: + ret = s->tlsext_hb_pending; + break; + + case SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS: + if (larg) + s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_RECV_REQUESTS; + else + s->tlsext_heartbeat &= ~SSL_TLSEXT_HB_DONT_RECV_REQUESTS; + ret = 1; + break; +# endif + +#endif /* !OPENSSL_NO_TLSEXT */ + + case SSL_CTRL_CHAIN: + if (larg) + return ssl_cert_set1_chain(s->cert, (STACK_OF(X509) *)parg); + else + return ssl_cert_set0_chain(s->cert, (STACK_OF(X509) *)parg); + + case SSL_CTRL_CHAIN_CERT: + if (larg) + return ssl_cert_add1_chain_cert(s->cert, (X509 *)parg); + else + return ssl_cert_add0_chain_cert(s->cert, (X509 *)parg); + + case SSL_CTRL_GET_CHAIN_CERTS: + *(STACK_OF(X509) **)parg = s->cert->key->chain; + break; + + case SSL_CTRL_SELECT_CURRENT_CERT: + return ssl_cert_select_current(s->cert, (X509 *)parg); + + case SSL_CTRL_SET_CURRENT_CERT: + if (larg == SSL_CERT_SET_SERVER) { + CERT_PKEY *cpk; + const SSL_CIPHER *cipher; + if (!s->server) + return 0; + cipher = s->s3->tmp.new_cipher; + if (!cipher) + return 0; + /* + * No certificate for unauthenticated ciphersuites or using SRP + * authentication + */ + if (cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) + return 2; + cpk = ssl_get_server_send_pkey(s); + if (!cpk) + return 0; + s->cert->key = cpk; + return 1; + } + return ssl_cert_set_current(s->cert, larg); + +#ifndef OPENSSL_NO_EC + case SSL_CTRL_GET_CURVES: + { + unsigned char *clist; + size_t clistlen; + if (!s->session) + return 0; + clist = s->session->tlsext_ellipticcurvelist; + clistlen = s->session->tlsext_ellipticcurvelist_length / 2; + if (parg) { + size_t i; + int *cptr = parg; + unsigned int cid, nid; + for (i = 0; i < clistlen; i++) { + n2s(clist, cid); + nid = tls1_ec_curve_id2nid(cid); + if (nid != 0) + cptr[i] = nid; + else + cptr[i] = TLSEXT_nid_unknown | cid; + } + } + return (int)clistlen; + } + + case SSL_CTRL_SET_CURVES: + return tls1_set_curves(&s->tlsext_ellipticcurvelist, + &s->tlsext_ellipticcurvelist_length, + parg, larg); + + case SSL_CTRL_SET_CURVES_LIST: + return tls1_set_curves_list(&s->tlsext_ellipticcurvelist, + &s->tlsext_ellipticcurvelist_length, + parg); + + case SSL_CTRL_GET_SHARED_CURVE: + return tls1_shared_curve(s, larg); + +# ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_ECDH_AUTO: + s->cert->ecdh_tmp_auto = larg; + return 1; +# endif +#endif + case SSL_CTRL_SET_SIGALGS: + return tls1_set_sigalgs(s->cert, parg, larg, 0); + + case SSL_CTRL_SET_SIGALGS_LIST: + return tls1_set_sigalgs_list(s->cert, parg, 0); + + case SSL_CTRL_SET_CLIENT_SIGALGS: + return tls1_set_sigalgs(s->cert, parg, larg, 1); + + case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: + return tls1_set_sigalgs_list(s->cert, parg, 1); + + case SSL_CTRL_GET_CLIENT_CERT_TYPES: + { + const unsigned char **pctype = parg; + if (s->server || !s->s3->tmp.cert_req) + return 0; + if (s->cert->ctypes) { + if (pctype) + *pctype = s->cert->ctypes; + return (int)s->cert->ctype_num; + } + if (pctype) + *pctype = (unsigned char *)s->s3->tmp.ctype; + return s->s3->tmp.ctype_num; + } + + case SSL_CTRL_SET_CLIENT_CERT_TYPES: + if (!s->server) + return 0; + return ssl3_set_req_cert_type(s->cert, parg, larg); + + case SSL_CTRL_BUILD_CERT_CHAIN: + return ssl_build_cert_chain(s->cert, s->ctx->cert_store, larg); + + case SSL_CTRL_SET_VERIFY_CERT_STORE: + return ssl_cert_set_cert_store(s->cert, parg, 0, larg); + + case SSL_CTRL_SET_CHAIN_CERT_STORE: + return ssl_cert_set_cert_store(s->cert, parg, 1, larg); + + case SSL_CTRL_GET_PEER_SIGNATURE_NID: + if (SSL_USE_SIGALGS(s)) { + if (s->session && s->session->sess_cert) { + const EVP_MD *sig; + sig = s->session->sess_cert->peer_key->digest; + if (sig) { + *(int *)parg = EVP_MD_type(sig); + return 1; + } + } + return 0; + } + /* Might want to do something here for other versions */ + else + return 0; + + case SSL_CTRL_GET_SERVER_TMP_KEY: + if (s->server || !s->session || !s->session->sess_cert) + return 0; + else { + SESS_CERT *sc; + EVP_PKEY *ptmp; + int rv = 0; + sc = s->session->sess_cert; +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDH) + if (!sc->peer_rsa_tmp && !sc->peer_dh_tmp && !sc->peer_ecdh_tmp) + return 0; +#endif + ptmp = EVP_PKEY_new(); + if (!ptmp) + return 0; + if (0) ; +#ifndef OPENSSL_NO_RSA + else if (sc->peer_rsa_tmp) + rv = EVP_PKEY_set1_RSA(ptmp, sc->peer_rsa_tmp); +#endif +#ifndef OPENSSL_NO_DH + else if (sc->peer_dh_tmp) + rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp); +#endif +#ifndef OPENSSL_NO_ECDH + else if (sc->peer_ecdh_tmp) + rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp); +#endif + if (rv) { + *(EVP_PKEY **)parg = ptmp; + return 1; + } + EVP_PKEY_free(ptmp); + return 0; + } +#ifndef OPENSSL_NO_EC + case SSL_CTRL_GET_EC_POINT_FORMATS: + { + SSL_SESSION *sess = s->session; + const unsigned char **pformat = parg; + if (!sess || !sess->tlsext_ecpointformatlist) + return 0; + *pformat = sess->tlsext_ecpointformatlist; + return (int)sess->tlsext_ecpointformatlist_length; + } +#endif + + case SSL_CTRL_CHECK_PROTO_VERSION: + /* + * For library-internal use; checks that the current protocol is the + * highest enabled version (according to s->ctx->method, as version + * negotiation may have changed s->method). + */ + if (s->version == s->ctx->method->version) + return 1; + /* + * Apparently we're using a version-flexible SSL_METHOD (not at its + * highest protocol version). + */ + if (s->ctx->method->version == SSLv23_method()->version) { +#if TLS_MAX_VERSION != TLS1_2_VERSION +# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION. +#endif + if (!(s->options & SSL_OP_NO_TLSv1_2)) + return s->version == TLS1_2_VERSION; + if (!(s->options & SSL_OP_NO_TLSv1_1)) + return s->version == TLS1_1_VERSION; + if (!(s->options & SSL_OP_NO_TLSv1)) + return s->version == TLS1_VERSION; + if (!(s->options & SSL_OP_NO_SSLv3)) + return s->version == SSL3_VERSION; + if (!(s->options & SSL_OP_NO_SSLv2)) + return s->version == SSL2_VERSION; + } + return 0; /* Unexpected state; fail closed. */ + + default: + break; + } + return (ret); +} + +long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) +{ + int ret = 0; + +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA) + if ( +# ifndef OPENSSL_NO_RSA + cmd == SSL_CTRL_SET_TMP_RSA_CB || +# endif +# ifndef OPENSSL_NO_DSA + cmd == SSL_CTRL_SET_TMP_DH_CB || +# endif + 0) { + if (!ssl_cert_inst(&s->cert)) { + SSLerr(SSL_F_SSL3_CALLBACK_CTRL, ERR_R_MALLOC_FAILURE); + return (0); + } + } +#endif + + switch (cmd) { +#ifndef OPENSSL_NO_RSA + case SSL_CTRL_SET_TMP_RSA_CB: + { + s->cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_DH + case SSL_CTRL_SET_TMP_DH_CB: + { + s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_TMP_ECDH_CB: + { + s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_DEBUG_CB: + s->tlsext_debug_cb = (void (*)(SSL *, int, int, + unsigned char *, int, void *))fp; + break; +#endif + default: + break; + } + return (ret); +} + +long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + CERT *cert; + + cert = ctx->cert; + + switch (cmd) { +#ifndef OPENSSL_NO_RSA + case SSL_CTRL_NEED_TMP_RSA: + if ((cert->rsa_tmp == NULL) && + ((cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) || + (EVP_PKEY_size(cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > + (512 / 8))) + ) + return (1); + else + return (0); + /* break; */ + case SSL_CTRL_SET_TMP_RSA: + { + RSA *rsa; + int i; + + rsa = (RSA *)parg; + i = 1; + if (rsa == NULL) + i = 0; + else { + if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) + i = 0; + } + if (!i) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_RSA_LIB); + return (0); + } else { + if (cert->rsa_tmp != NULL) + RSA_free(cert->rsa_tmp); + cert->rsa_tmp = rsa; + return (1); + } + } + /* break; */ + case SSL_CTRL_SET_TMP_RSA_CB: + { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + } + break; +#endif +#ifndef OPENSSL_NO_DH + case SSL_CTRL_SET_TMP_DH: + { + DH *new = NULL, *dh; + + dh = (DH *)parg; + if ((new = DHparams_dup(dh)) == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB); + return 0; + } + if (cert->dh_tmp != NULL) + DH_free(cert->dh_tmp); + cert->dh_tmp = new; + return 1; + } + /* + * break; + */ + case SSL_CTRL_SET_TMP_DH_CB: + { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + } + break; +#endif +#ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_TMP_ECDH: + { + EC_KEY *ecdh = NULL; + + if (parg == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB); + return 0; + } + ecdh = EC_KEY_dup((EC_KEY *)parg); + if (ecdh == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_EC_LIB); + return 0; + } + if (!(ctx->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + EC_KEY_free(ecdh); + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB); + return 0; + } + } + + if (cert->ecdh_tmp != NULL) { + EC_KEY_free(cert->ecdh_tmp); + } + cert->ecdh_tmp = ecdh; + return 1; + } + /* break; */ + case SSL_CTRL_SET_TMP_ECDH_CB: + { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + } + break; +#endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: + ctx->tlsext_servername_arg = parg; + break; + case SSL_CTRL_SET_TLSEXT_TICKET_KEYS: + case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: + { + unsigned char *keys = parg; + if (!keys) + return 48; + if (larg != 48) { + SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) { + memcpy(ctx->tlsext_tick_key_name, keys, 16); + memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16); + memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16); + } else { + memcpy(keys, ctx->tlsext_tick_key_name, 16); + memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16); + memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16); + } + return 1; + } + +# ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG: + ctx->tlsext_opaque_prf_input_callback_arg = parg; + return 1; +# endif + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: + ctx->tlsext_status_arg = parg; + return 1; + break; + +# ifndef OPENSSL_NO_SRP + case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + if (ctx->srp_ctx.login != NULL) + OPENSSL_free(ctx->srp_ctx.login); + ctx->srp_ctx.login = NULL; + if (parg == NULL) + break; + if (strlen((const char *)parg) > 255 + || strlen((const char *)parg) < 1) { + SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME); + return 0; + } + if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR); + return 0; + } + break; + case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD: + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = + srp_password_from_info_cb; + ctx->srp_ctx.info = parg; + break; + case SSL_CTRL_SET_SRP_ARG: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + ctx->srp_ctx.SRP_cb_arg = parg; + break; + + case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH: + ctx->srp_ctx.strength = larg; + break; +# endif + +# ifndef OPENSSL_NO_EC + case SSL_CTRL_SET_CURVES: + return tls1_set_curves(&ctx->tlsext_ellipticcurvelist, + &ctx->tlsext_ellipticcurvelist_length, + parg, larg); + + case SSL_CTRL_SET_CURVES_LIST: + return tls1_set_curves_list(&ctx->tlsext_ellipticcurvelist, + &ctx->tlsext_ellipticcurvelist_length, + parg); +# ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_ECDH_AUTO: + ctx->cert->ecdh_tmp_auto = larg; + return 1; +# endif +# endif + case SSL_CTRL_SET_SIGALGS: + return tls1_set_sigalgs(ctx->cert, parg, larg, 0); + + case SSL_CTRL_SET_SIGALGS_LIST: + return tls1_set_sigalgs_list(ctx->cert, parg, 0); + + case SSL_CTRL_SET_CLIENT_SIGALGS: + return tls1_set_sigalgs(ctx->cert, parg, larg, 1); + + case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: + return tls1_set_sigalgs_list(ctx->cert, parg, 1); + + case SSL_CTRL_SET_CLIENT_CERT_TYPES: + return ssl3_set_req_cert_type(ctx->cert, parg, larg); + + case SSL_CTRL_BUILD_CERT_CHAIN: + return ssl_build_cert_chain(ctx->cert, ctx->cert_store, larg); + + case SSL_CTRL_SET_VERIFY_CERT_STORE: + return ssl_cert_set_cert_store(ctx->cert, parg, 0, larg); + + case SSL_CTRL_SET_CHAIN_CERT_STORE: + return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg); + +#endif /* !OPENSSL_NO_TLSEXT */ + + /* A Thawte special :-) */ + case SSL_CTRL_EXTRA_CHAIN_CERT: + if (ctx->extra_certs == NULL) { + if ((ctx->extra_certs = sk_X509_new_null()) == NULL) + return (0); + } + sk_X509_push(ctx->extra_certs, (X509 *)parg); + break; + + case SSL_CTRL_GET_EXTRA_CHAIN_CERTS: + if (ctx->extra_certs == NULL && larg == 0) + *(STACK_OF(X509) **)parg = ctx->cert->key->chain; + else + *(STACK_OF(X509) **)parg = ctx->extra_certs; + break; + + case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS: + if (ctx->extra_certs) { + sk_X509_pop_free(ctx->extra_certs, X509_free); + ctx->extra_certs = NULL; + } + break; + + case SSL_CTRL_CHAIN: + if (larg) + return ssl_cert_set1_chain(ctx->cert, (STACK_OF(X509) *)parg); + else + return ssl_cert_set0_chain(ctx->cert, (STACK_OF(X509) *)parg); + + case SSL_CTRL_CHAIN_CERT: + if (larg) + return ssl_cert_add1_chain_cert(ctx->cert, (X509 *)parg); + else + return ssl_cert_add0_chain_cert(ctx->cert, (X509 *)parg); + + case SSL_CTRL_GET_CHAIN_CERTS: + *(STACK_OF(X509) **)parg = ctx->cert->key->chain; + break; + + case SSL_CTRL_SELECT_CURRENT_CERT: + return ssl_cert_select_current(ctx->cert, (X509 *)parg); + + case SSL_CTRL_SET_CURRENT_CERT: + return ssl_cert_set_current(ctx->cert, larg); + + default: + return (0); + } + return (1); +} + +long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) +{ + CERT *cert; + + cert = ctx->cert; + + switch (cmd) { +#ifndef OPENSSL_NO_RSA + case SSL_CTRL_SET_TMP_RSA_CB: + { + cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_DH + case SSL_CTRL_SET_TMP_DH_CB: + { + cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_TMP_ECDH_CB: + { + cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: + ctx->tlsext_servername_callback = (int (*)(SSL *, int *, void *))fp; + break; + +# ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB: + ctx->tlsext_opaque_prf_input_callback = + (int (*)(SSL *, void *, size_t, void *))fp; + break; +# endif + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB: + ctx->tlsext_status_cb = (int (*)(SSL *, void *))fp; + break; + + case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB: + ctx->tlsext_ticket_key_cb = (int (*)(SSL *, unsigned char *, + unsigned char *, + EVP_CIPHER_CTX *, + HMAC_CTX *, int))fp; + break; + +# ifndef OPENSSL_NO_SRP + case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + ctx->srp_ctx.SRP_verify_param_callback = (int (*)(SSL *, void *))fp; + break; + case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + ctx->srp_ctx.TLS_ext_srp_username_callback = + (int (*)(SSL *, int *, void *))fp; + break; + case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = + (char *(*)(SSL *, void *))fp; + break; +# endif +#endif + default: + return (0); + } + return (1); +} + +/* + * This function needs to check if the ciphers required are actually + * available + */ +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p) +{ + SSL_CIPHER c; + const SSL_CIPHER *cp; + unsigned long id; + + id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1]; + c.id = id; + cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS); +#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES + if (cp == NULL) + fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]); +#endif + return cp; +} + +int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) +{ + long l; + + if (p != NULL) { + l = c->id; + if ((l & 0xff000000) != 0x03000000) + return (0); + p[0] = ((unsigned char)(l >> 8L)) & 0xFF; + p[1] = ((unsigned char)(l)) & 0xFF; + } + return (2); +} + +SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + STACK_OF(SSL_CIPHER) *srvr) +{ + SSL_CIPHER *c, *ret = NULL; + STACK_OF(SSL_CIPHER) *prio, *allow; + int i, ii, ok; + CERT *cert; + unsigned long alg_k, alg_a, mask_k, mask_a, emask_k, emask_a; + + /* Let's see which ciphers we can support */ + cert = s->cert; + +#if 0 + /* + * Do not set the compare functions, because this may lead to a + * reordering by "id". We want to keep the original ordering. We may pay + * a price in performance during sk_SSL_CIPHER_find(), but would have to + * pay with the price of sk_SSL_CIPHER_dup(). + */ + sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp); + sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp); +#endif + +#ifdef CIPHER_DEBUG + fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), + (void *)srvr); + for (i = 0; i < sk_SSL_CIPHER_num(srvr); ++i) { + c = sk_SSL_CIPHER_value(srvr, i); + fprintf(stderr, "%p:%s\n", (void *)c, c->name); + } + fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), + (void *)clnt); + for (i = 0; i < sk_SSL_CIPHER_num(clnt); ++i) { + c = sk_SSL_CIPHER_value(clnt, i); + fprintf(stderr, "%p:%s\n", (void *)c, c->name); + } +#endif + + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || tls1_suiteb(s)) { + prio = srvr; + allow = clnt; + } else { + prio = clnt; + allow = srvr; + } + + tls1_set_cert_validity(s); + + for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + c = sk_SSL_CIPHER_value(prio, i); + + /* Skip TLS v1.2 only ciphersuites if not supported */ + if ((c->algorithm_ssl & SSL_TLSV1_2) && !SSL_USE_TLS1_2_CIPHERS(s)) + continue; + + ssl_set_cert_masks(cert, c); + mask_k = cert->mask_k; + mask_a = cert->mask_a; + emask_k = cert->export_mask_k; + emask_a = cert->export_mask_a; +#ifndef OPENSSL_NO_SRP + if (s->srp_ctx.srp_Mask & SSL_kSRP) { + mask_k |= SSL_kSRP; + emask_k |= SSL_kSRP; + mask_a |= SSL_aSRP; + emask_a |= SSL_aSRP; + } +#endif + +#ifdef KSSL_DEBUG + /* + * fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n", + * i,c->algorithms); + */ +#endif /* KSSL_DEBUG */ + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + +#ifndef OPENSSL_NO_KRB5 + if (alg_k & SSL_kKRB5) { + if (!kssl_keytab_is_available(s->kssl_ctx)) + continue; + } +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + /* with PSK there must be server callback set */ + if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL) + continue; +#endif /* OPENSSL_NO_PSK */ + + if (SSL_C_IS_EXPORT(c)) { + ok = (alg_k & emask_k) && (alg_a & emask_a); +#ifdef CIPHER_DEBUG + fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n", + ok, alg_k, alg_a, emask_k, emask_a, (void *)c, c->name); +#endif + } else { + ok = (alg_k & mask_k) && (alg_a & mask_a); +#ifdef CIPHER_DEBUG + fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k, + alg_a, mask_k, mask_a, (void *)c, c->name); +#endif + } + +#ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_ECDH + /* + * if we are considering an ECC cipher suite that uses an ephemeral + * EC key check it + */ + if (alg_k & SSL_kEECDH) + ok = ok && tls1_check_ec_tmp_key(s, c->id); +# endif /* OPENSSL_NO_ECDH */ +# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_TLSEXT */ + + if (!ok) + continue; + ii = sk_SSL_CIPHER_find(allow, c); + if (ii >= 0) { +#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT) + if ((alg_k & SSL_kEECDH) && (alg_a & SSL_aECDSA) + && s->s3->is_probably_safari) { + if (!ret) + ret = sk_SSL_CIPHER_value(allow, ii); + continue; + } +#endif + ret = sk_SSL_CIPHER_value(allow, ii); + break; + } + } + return (ret); +} + +int ssl3_get_req_cert_type(SSL *s, unsigned char *p) +{ + int ret = 0; + const unsigned char *sig; + size_t i, siglen; + int have_rsa_sign = 0, have_dsa_sign = 0; +#ifndef OPENSSL_NO_ECDSA + int have_ecdsa_sign = 0; +#endif +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) + int nostrict = 1; +#endif +#if !defined(OPENSSL_NO_GOST) || !defined(OPENSSL_NO_DH) || \ + !defined(OPENSSL_NO_ECDH) + unsigned long alg_k; +#endif + + /* If we have custom certificate types set, use them */ + if (s->cert->ctypes) { + memcpy(p, s->cert->ctypes, s->cert->ctype_num); + return (int)s->cert->ctype_num; + } + /* get configured sigalgs */ + siglen = tls12_get_psigalgs(s, 1, &sig); +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) + if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) + nostrict = 0; +#endif + for (i = 0; i < siglen; i += 2, sig += 2) { + switch (sig[1]) { + case TLSEXT_signature_rsa: + have_rsa_sign = 1; + break; + + case TLSEXT_signature_dsa: + have_dsa_sign = 1; + break; +#ifndef OPENSSL_NO_ECDSA + case TLSEXT_signature_ecdsa: + have_ecdsa_sign = 1; + break; +#endif + } + } + +#if !defined(OPENSSL_NO_GOST) || !defined(OPENSSL_NO_DH) || \ + !defined(OPENSSL_NO_ECDH) + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; +#endif + +#ifndef OPENSSL_NO_GOST + if (s->version >= TLS1_VERSION) { + if (alg_k & SSL_kGOST) { + p[ret++] = TLS_CT_GOST94_SIGN; + p[ret++] = TLS_CT_GOST01_SIGN; + return (ret); + } + } +#endif + +#ifndef OPENSSL_NO_DH + if (alg_k & (SSL_kDHr | SSL_kEDH)) { +# ifndef OPENSSL_NO_RSA + /* + * Since this refers to a certificate signed with an RSA algorithm, + * only check for rsa signing in strict mode. + */ + if (nostrict || have_rsa_sign) + p[ret++] = SSL3_CT_RSA_FIXED_DH; +# endif +# ifndef OPENSSL_NO_DSA + if (nostrict || have_dsa_sign) + p[ret++] = SSL3_CT_DSS_FIXED_DH; +# endif + } + if ((s->version == SSL3_VERSION) && + (alg_k & (SSL_kEDH | SSL_kDHd | SSL_kDHr))) { +# ifndef OPENSSL_NO_RSA + p[ret++] = SSL3_CT_RSA_EPHEMERAL_DH; +# endif +# ifndef OPENSSL_NO_DSA + p[ret++] = SSL3_CT_DSS_EPHEMERAL_DH; +# endif + } +#endif /* !OPENSSL_NO_DH */ +#ifndef OPENSSL_NO_RSA + if (have_rsa_sign) + p[ret++] = SSL3_CT_RSA_SIGN; +#endif +#ifndef OPENSSL_NO_DSA + if (have_dsa_sign) + p[ret++] = SSL3_CT_DSS_SIGN; +#endif +#ifndef OPENSSL_NO_ECDH + if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->version >= TLS1_VERSION)) { + if (nostrict || have_rsa_sign) + p[ret++] = TLS_CT_RSA_FIXED_ECDH; + if (nostrict || have_ecdsa_sign) + p[ret++] = TLS_CT_ECDSA_FIXED_ECDH; + } +#endif + +#ifndef OPENSSL_NO_ECDSA + /* + * ECDSA certs can be used with RSA cipher suites as well so we don't + * need to check for SSL_kECDH or SSL_kEECDH + */ + if (s->version >= TLS1_VERSION) { + if (have_ecdsa_sign) + p[ret++] = TLS_CT_ECDSA_SIGN; + } +#endif + return (ret); +} + +static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len) +{ + if (c->ctypes) { + OPENSSL_free(c->ctypes); + c->ctypes = NULL; + } + if (!p || !len) + return 1; + if (len > 0xff) + return 0; + c->ctypes = OPENSSL_malloc(len); + if (!c->ctypes) + return 0; + memcpy(c->ctypes, p, len); + c->ctype_num = len; + return 1; +} + +int ssl3_shutdown(SSL *s) +{ + int ret; + + /* + * Don't do anything much if we have not done the handshake or we don't + * want to send messages :-) + */ + if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE)) { + s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + return (1); + } + + if (!(s->shutdown & SSL_SENT_SHUTDOWN)) { + s->shutdown |= SSL_SENT_SHUTDOWN; +#if 1 + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); +#endif + /* + * our shutdown alert has been sent now, and if it still needs to be + * written, s->s3->alert_dispatch will be true + */ + if (s->s3->alert_dispatch) + return (-1); /* return WANT_WRITE */ + } else if (s->s3->alert_dispatch) { + /* resend it if not sent */ +#if 1 + ret = s->method->ssl_dispatch_alert(s); + if (ret == -1) { + /* + * we only get to return -1 here the 2nd/Nth invocation, we must + * have already signalled return 0 upon a previous invoation, + * return WANT_WRITE + */ + return (ret); + } +#endif + } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + /* + * If we are waiting for a close from our peer, we are closed + */ + s->method->ssl_read_bytes(s, 0, NULL, 0, 0); + if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + return (-1); /* return WANT_READ */ + } + } + + if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) && + !s->s3->alert_dispatch) + return (1); + else + return (0); +} + +int ssl3_write(SSL *s, const void *buf, int len) +{ + int ret, n; + +#if 0 + if (s->shutdown & SSL_SEND_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + return (0); + } +#endif + clear_sys_error(); + if (s->s3->renegotiate) + ssl3_renegotiate_check(s); + + /* + * This is an experimental flag that sends the last handshake message in + * the same packet as the first use data - used to see if it helps the + * TCP protocol during session-id reuse + */ + /* The second test is because the buffer may have been removed */ + if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) { + /* First time through, we write into the buffer */ + if (s->s3->delay_buf_pop_ret == 0) { + ret = ssl3_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len); + if (ret <= 0) + return (ret); + + s->s3->delay_buf_pop_ret = ret; + } + + s->rwstate = SSL_WRITING; + n = BIO_flush(s->wbio); + if (n <= 0) + return (n); + s->rwstate = SSL_NOTHING; + + /* We have flushed the buffer, so remove it */ + ssl_free_wbio_buffer(s); + s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; + + ret = s->s3->delay_buf_pop_ret; + s->s3->delay_buf_pop_ret = 0; + } else { + ret = s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, + buf, len); + if (ret <= 0) + return (ret); + } + + return (ret); +} + +static int ssl3_read_internal(SSL *s, void *buf, int len, int peek) +{ + int ret; + + clear_sys_error(); + if (s->s3->renegotiate) + ssl3_renegotiate_check(s); + s->s3->in_read_app_data = 1; + ret = + s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, + peek); + if ((ret == -1) && (s->s3->in_read_app_data == 2)) { + /* + * ssl3_read_bytes decided to call s->handshake_func, which called + * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes + * actually found application data and thinks that application data + * makes sense here; so disable handshake processing and try to read + * application data again. + */ + s->in_handshake++; + ret = + s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, + peek); + s->in_handshake--; + } else + s->s3->in_read_app_data = 0; + + return (ret); +} + +int ssl3_read(SSL *s, void *buf, int len) +{ + return ssl3_read_internal(s, buf, len, 0); +} + +int ssl3_peek(SSL *s, void *buf, int len) +{ + return ssl3_read_internal(s, buf, len, 1); +} + +int ssl3_renegotiate(SSL *s) +{ + if (s->handshake_func == NULL) + return (1); + + if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) + return (0); + + s->s3->renegotiate = 1; + return (1); +} + +int ssl3_renegotiate_check(SSL *s) +{ + int ret = 0; + + if (s->s3->renegotiate) { + if ((s->s3->rbuf.left == 0) && + (s->s3->wbuf.left == 0) && !SSL_in_init(s)) { + /* + * if we are the server, and we have sent a 'RENEGOTIATE' + * message, we need to go to SSL_ST_ACCEPT. + */ + /* SSL_ST_ACCEPT */ + s->state = SSL_ST_RENEGOTIATE; + s->s3->renegotiate = 0; + s->s3->num_renegotiations++; + s->s3->total_renegotiations++; + ret = 1; + } + } + return (ret); +} + +/* + * If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and + * handshake macs if required. + */ +long ssl_get_algorithm2(SSL *s) +{ + long alg2; + if (s->s3 == NULL || s->s3->tmp.new_cipher == NULL) + return -1; + alg2 = s->s3->tmp.new_cipher->algorithm2; + if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF + && alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF)) + return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; + return alg2; +} +/* ssl/s3_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "objects.h" +// #include "ssl_locl.h" + +#ifndef OPENSSL_NO_SSL3_METHOD +static const SSL_METHOD *ssl3_get_method(int ver) +{ + if (ver == SSL3_VERSION) + return (SSLv3_method()); + else + return (NULL); +} + +IMPLEMENT_ssl3_meth_func(SSLv3_method, + ssl3_accept, ssl3_connect, ssl3_get_method) +#endif +/* ssl/s3_pkt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#define USE_SOCKETS +// #include "ssl_locl.h" +// #include "evp.h" +// #include "buffer.h" +// #include "rand.h" + +#ifndef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 +#endif + +#if defined(OPENSSL_SMALL_FOOTPRINT) || \ + !( defined(AES_ASM) && ( \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) \ + ) +# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK +# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 +#endif + +static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragment); +static int ssl3_get_record(SSL *s); + +/* + * Return values are as per SSL_read() + */ +int ssl3_read_n(SSL *s, int n, int max, int extend) +{ + /* + * If extend == 0, obtain new n-byte packet; if extend == 1, increase + * packet by another n bytes. The packet will be in the sub-array of + * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If + * s->read_ahead is set, 'max' bytes may be stored in rbuf [plus + * s->packet_length bytes if extend == 1].) + */ + int i, len, left; + long align = 0; + unsigned char *pkt; + SSL3_BUFFER *rb; + + if (n <= 0) + return n; + + rb = &(s->s3->rbuf); + if (rb->buf == NULL) + if (!ssl3_setup_read_buffer(s)) + return -1; + + left = rb->left; +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (long)rb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + + if (!extend) { + /* start with empty packet ... */ + if (left == 0) + rb->offset = align; + else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { + /* + * check if next packet length is large enough to justify payload + * alignment... + */ + pkt = rb->buf + rb->offset; + if (pkt[0] == SSL3_RT_APPLICATION_DATA + && (pkt[3] << 8 | pkt[4]) >= 128) { + /* + * Note that even if packet is corrupted and its length field + * is insane, we can only be led to wrong decision about + * whether memmove will occur or not. Header values has no + * effect on memmove arguments and therefore no buffer + * overrun can be triggered. + */ + memmove(rb->buf + align, pkt, left); + rb->offset = align; + } + } + s->packet = rb->buf + rb->offset; + s->packet_length = 0; + /* ... now we can act as if 'extend' was set */ + } + + /* + * For DTLS/UDP reads should not span multiple packets because the read + * operation returns the whole packet at once (as long as it fits into + * the buffer). + */ + if (SSL_IS_DTLS(s)) { + if (left == 0 && extend) + return 0; + if (left > 0 && n > left) + n = left; + } + + /* if there is enough in the buffer from a previous read, take some */ + if (left >= n) { + s->packet_length += n; + rb->left = left - n; + rb->offset += n; + return (n); + } + + /* else we need to read more data */ + + len = s->packet_length; + pkt = rb->buf + align; + /* + * Move any available bytes to front of buffer: 'len' bytes already + * pointed to by 'packet', 'left' extra ones at the end + */ + if (s->packet != pkt) { /* len > 0 */ + memmove(pkt, s->packet, len + left); + s->packet = pkt; + rb->offset = len + align; + } + + if (n > (int)(rb->len - rb->offset)) { /* does not happen */ + SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* We always act like read_ahead is set for DTLS */ + if (!s->read_ahead && !SSL_IS_DTLS(s)) + /* ignore max parameter */ + max = n; + else { + if (max < n) + max = n; + if (max > (int)(rb->len - rb->offset)) + max = rb->len - rb->offset; + } + + while (left < n) { + /* + * Now we have len+left bytes at the front of s->s3->rbuf.buf and + * need to read in more until we have len+n (up to len+max if + * possible) + */ + + clear_sys_error(); + if (s->rbio != NULL) { + s->rwstate = SSL_READING; + i = BIO_read(s->rbio, pkt + len + left, max - left); + } else { + SSLerr(SSL_F_SSL3_READ_N, SSL_R_READ_BIO_NOT_SET); + i = -1; + } + + if (i <= 0) { + rb->left = left; + if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) + if (len + left == 0) + ssl3_release_read_buffer(s); + return (i); + } + left += i; + /* + * reads should *never* span multiple packets for DTLS because the + * underlying transport protocol is message oriented as opposed to + * byte oriented as in the TLS case. + */ + if (SSL_IS_DTLS(s)) { + if (n > left) + n = left; /* makes the while condition false */ + } + } + + /* done reading, now the book-keeping */ + rb->offset += n; + rb->left = left - n; + s->packet_length += n; + s->rwstate = SSL_NOTHING; + return (n); +} + +/* + * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that + * will be processed per call to ssl3_get_record. Without this limit an + * attacker could send empty records at a faster rate than we can process and + * cause ssl3_get_record to loop forever. + */ +#define MAX_EMPTY_RECORDS 32 + +/*- + * Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data, - data + * ssl->s3->rrec.length, - number of bytes + */ +/* used only by ssl3_read_bytes */ +static int ssl3_get_record(SSL *s) +{ + int ssl_major, ssl_minor, al; + int enc_err, n, i, ret = -1; + SSL3_RECORD *rr; + SSL_SESSION *sess; + unsigned char *p; + unsigned char md[EVP_MAX_MD_SIZE]; + short version; + unsigned mac_size, orig_len; + size_t extra; + unsigned empty_record_count = 0; + + rr = &(s->s3->rrec); + sess = s->session; + + if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) + extra = SSL3_RT_MAX_EXTRA; + else + extra = 0; + if (extra && !s->s3->init_extra) { + /* + * An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER set after + * ssl3_setup_buffers() was done + */ + SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR); + return -1; + } + + again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < SSL3_RT_HEADER_LENGTH)) { + n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); + if (n <= 0) + return (n); /* error or non-blocking */ + s->rstate = SSL_ST_READ_BODY; + + p = s->packet; + if (s->msg_callback) + s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, + s->msg_callback_arg); + + /* Pull apart the header into the SSL3_RECORD */ + rr->type = *(p++); + ssl_major = *(p++); + ssl_minor = *(p++); + version = (ssl_major << 8) | ssl_minor; + n2s(p, rr->length); +#if 0 + fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length); +#endif + + /* Lets check version */ + if (!s->first_packet) { + if (version != s->version) { + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); + if ((s->version & 0xFF00) == (version & 0xFF00) + && !s->enc_write_ctx && !s->write_hash) { + if (rr->type == SSL3_RT_ALERT) { + /* + * The record is using an incorrect version number, but + * what we've got appears to be an alert. We haven't + * read the body yet to check whether its a fatal or + * not - but chances are it is. We probably shouldn't + * send a fatal alert back. We'll just end. + */ + goto err; + } + /* + * Send back error using their minor version number :-) + */ + s->version = (unsigned short)version; + } + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + } + + if ((version >> 8) != SSL3_VERSION_MAJOR) { + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); + goto err; + } + + if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG); + goto f_err; + } + + /* now s->rstate == SSL_ST_READ_BODY */ + } + + /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ + + if (rr->length > s->packet_length - SSL3_RT_HEADER_LENGTH) { + /* now s->packet_length == SSL3_RT_HEADER_LENGTH */ + i = rr->length; + n = ssl3_read_n(s, i, i, 1); + if (n <= 0) + return (n); /* error or non-blocking io */ + /* + * now n == rr->length, and s->packet_length == SSL3_RT_HEADER_LENGTH + * + rr->length + */ + } + + s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ + + /* + * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, + * and we have that many bytes in s->packet + */ + rr->input = &(s->packet[SSL3_RT_HEADER_LENGTH]); + + /* + * ok, we can now read from 's->packet' data into 'rr' rr->input points + * at rr->length bytes, which need to be copied into rr->data by either + * the decryption or by the decompression When the data is 'copied' into + * the rr->data buffer, rr->input will be pointed at the new buffer + */ + + /* + * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length + * bytes of encrypted compressed stuff. + */ + + /* check is not needed I believe */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + goto f_err; + } + + /* decrypt in place in 'rr->input' */ + rr->data = rr->input; + + enc_err = s->method->ssl3_enc->enc(s, 0); + /*- + * enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid + */ + if (enc_err == 0) { + al = SSL_AD_DECRYPTION_FAILED; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); + goto f_err; + } +#ifdef TLS_DEBUG + printf("dec %d\n", rr->length); + { + unsigned int z; + for (z = 0; z < rr->length; z++) + printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); + } + printf("\n"); +#endif + + /* r->length is now the compressed data plus mac */ + if ((sess != NULL) && + (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + + /* + * kludge: *_cbc_remove_padding passes padding length in rr->type + */ + orig_len = rr->length + ((unsigned int)rr->type >> 8); + + /* + * orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different amount + * of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size + 1)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* + * We update the length so that the TLS header bytes can be + * constructed correctly but we need to extract the MAC in + * constant time from within the record, without leaking the + * contents of the padding bytes. + */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; + } else { + /* + * In this case there's no padding, so |orig_len| equals + * |rec->length| and we checked that there's enough bytes for + * |mac_size| above. + */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + + i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); + if (i < 0 || mac == NULL + || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra + mac_size) + enc_err = -1; + } + + if (enc_err < 0) { + /* + * A separate 'decryption_failed' alert was introduced with TLS 1.0, + * SSL 3.0 only has 'bad_record_mac'. But unless a decryption + * failure is directly visible from the ciphertext anyway, we should + * not reveal which kind of error occured -- this might become + * visible to an attacker (e.g. via a logfile) + */ + al = SSL_AD_BAD_RECORD_MAC; + SSLerr(SSL_F_SSL3_GET_RECORD, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + goto f_err; + } + + /* r->length is now just compressed */ + if (s->expand != NULL) { + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_COMPRESSED_LENGTH_TOO_LONG); + goto f_err; + } + if (!ssl3_do_uncompress(s)) { + al = SSL_AD_DECOMPRESSION_FAILURE; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_DECOMPRESSION); + goto f_err; + } + } + + if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH + extra) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + + rr->off = 0; + /*- + * So at this point the following is true + * ssl->s3->rrec.type is the type of record + * ssl->s3->rrec.length == number of bytes in record + * ssl->s3->rrec.off == offset to first valid byte + * ssl->s3->rrec.data == where to take bytes from, increment + * after use :-). + */ + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; + + /* just read a 0 length packet */ + if (rr->length == 0) { + empty_record_count++; + if (empty_record_count > MAX_EMPTY_RECORDS) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_RECORD_TOO_SMALL); + goto f_err; + } + goto again; + } +#if 0 + fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, + rr->length); +#endif + + return (1); + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (ret); +} + +int ssl3_do_uncompress(SSL *ssl) +{ +#ifndef OPENSSL_NO_COMP + int i; + SSL3_RECORD *rr; + + rr = &(ssl->s3->rrec); + i = COMP_expand_block(ssl->expand, rr->comp, + SSL3_RT_MAX_PLAIN_LENGTH, rr->data, + (int)rr->length); + if (i < 0) + return (0); + else + rr->length = i; + rr->data = rr->comp; +#endif + return (1); +} + +int ssl3_do_compress(SSL *ssl) +{ +#ifndef OPENSSL_NO_COMP + int i; + SSL3_RECORD *wr; + + wr = &(ssl->s3->wrec); + i = COMP_compress_block(ssl->compress, wr->data, + SSL3_RT_MAX_COMPRESSED_LENGTH, + wr->input, (int)wr->length); + if (i < 0) + return (0); + else + wr->length = i; + + wr->input = wr->data; +#endif + return (1); +} + +/* + * Call this to write data in records of type 'type' It will return <= 0 if + * not all data has been sent or non-blocking IO. + */ +int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) +{ + const unsigned char *buf = buf_; + int tot; + unsigned int n, nw; +#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + unsigned int max_send_fragment; +#endif + SSL3_BUFFER *wb = &(s->s3->wbuf); + int i; + + s->rwstate = SSL_NOTHING; + OPENSSL_assert(s->s3->wnum <= INT_MAX); + tot = s->s3->wnum; + s->s3->wnum = 0; + + if (SSL_in_init(s) && !s->in_handshake) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + /* + * ensure that if we end up with a smaller value of data to write out + * than the the original len from a write which didn't complete for + * non-blocking I/O and also somehow ended up avoiding the check for + * this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be + * possible to end up with (len-tot) as a large number that will then + * promptly send beyond the end of the users buffer ... so we trap and + * report the error in a way the user will notice + */ + if ((len < tot) || ((wb->left != 0) && (len < (tot + s->s3->wpend_tot)))) { + SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); + return (-1); + } + + /* + * first check if there is a SSL3_BUFFER still being written out. This + * will happen with non blocking IO + */ + if (wb->left != 0) { + i = ssl3_write_pending(s, type, &buf[tot], s->s3->wpend_tot); + if (i <= 0) { + /* XXX should we ssl3_release_write_buffer if i<0? */ + s->s3->wnum = tot; + return i; + } + tot += i; /* this might be last fragment */ + } +#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + /* + * Depending on platform multi-block can deliver several *times* + * better performance. Downside is that it has to allocate + * jumbo buffer to accomodate up to 8 records, but the + * compromise is considered worthy. + */ + if (type == SSL3_RT_APPLICATION_DATA && + len >= 4 * (int)(max_send_fragment = s->max_send_fragment) && + s->compress == NULL && s->msg_callback == NULL && + SSL_USE_EXPLICIT_IV(s) && + s->enc_write_ctx != NULL && + EVP_CIPHER_flags(s->enc_write_ctx->cipher) & + EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) { + unsigned char aad[13]; + EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; + int packlen; + + /* minimize address aliasing conflicts */ + if ((max_send_fragment & 0xfff) == 0) + max_send_fragment -= 512; + + if (tot == 0 || wb->buf == NULL) { /* allocate jumbo buffer */ + ssl3_release_write_buffer(s); + + packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, + EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE, + max_send_fragment, NULL); + + if (len >= 8 * (int)max_send_fragment) + packlen *= 8; + else + packlen *= 4; + + wb->buf = OPENSSL_malloc(packlen); + if (!wb->buf) { + SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_MALLOC_FAILURE); + return -1; + } + wb->len = packlen; + } else if (tot == len) { /* done? */ + OPENSSL_free(wb->buf); /* free jumbo buffer */ + wb->buf = NULL; + return tot; + } + + n = (len - tot); + for (;;) { + if (n < 4 * max_send_fragment) { + OPENSSL_free(wb->buf); /* free jumbo buffer */ + wb->buf = NULL; + break; + } + + if (s->s3->alert_dispatch) { + i = s->method->ssl_dispatch_alert(s); + if (i <= 0) { + s->s3->wnum = tot; + return i; + } + } + + if (n >= 8 * max_send_fragment) + nw = max_send_fragment * (mb_param.interleave = 8); + else + nw = max_send_fragment * (mb_param.interleave = 4); + + memcpy(aad, s->s3->write_sequence, 8); + aad[8] = type; + aad[9] = (unsigned char)(s->version >> 8); + aad[10] = (unsigned char)(s->version); + aad[11] = 0; + aad[12] = 0; + mb_param.out = NULL; + mb_param.inp = aad; + mb_param.len = nw; + + packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, + EVP_CTRL_TLS1_1_MULTIBLOCK_AAD, + sizeof(mb_param), &mb_param); + + if (packlen <= 0 || packlen > (int)wb->len) { /* never happens */ + OPENSSL_free(wb->buf); /* free jumbo buffer */ + wb->buf = NULL; + break; + } + + mb_param.out = wb->buf; + mb_param.inp = &buf[tot]; + mb_param.len = nw; + + if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, + EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT, + sizeof(mb_param), &mb_param) <= 0) + return -1; + + s->s3->write_sequence[7] += mb_param.interleave; + if (s->s3->write_sequence[7] < mb_param.interleave) { + int j = 6; + while (j >= 0 && (++s->s3->write_sequence[j--]) == 0) ; + } + + wb->offset = 0; + wb->left = packlen; + + s->s3->wpend_tot = nw; + s->s3->wpend_buf = &buf[tot]; + s->s3->wpend_type = type; + s->s3->wpend_ret = nw; + + i = ssl3_write_pending(s, type, &buf[tot], nw); + if (i <= 0) { + if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) { + OPENSSL_free(wb->buf); + wb->buf = NULL; + } + s->s3->wnum = tot; + return i; + } + if (i == (int)n) { + OPENSSL_free(wb->buf); /* free jumbo buffer */ + wb->buf = NULL; + return tot + i; + } + n -= i; + tot += i; + } + } else +#endif + if (tot == len) { /* done? */ + if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) + ssl3_release_write_buffer(s); + + return tot; + } + + n = (len - tot); + for (;;) { + if (n > s->max_send_fragment) + nw = s->max_send_fragment; + else + nw = n; + + i = do_ssl3_write(s, type, &(buf[tot]), nw, 0); + if (i <= 0) { + /* XXX should we ssl3_release_write_buffer if i<0? */ + s->s3->wnum = tot; + return i; + } + + if ((i == (int)n) || + (type == SSL3_RT_APPLICATION_DATA && + (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { + /* + * next chunk of data should get another prepended empty fragment + * in ciphersuites with known-IV weakness: + */ + s->s3->empty_fragment_done = 0; + + if ((i == (int)n) && s->mode & SSL_MODE_RELEASE_BUFFERS && + !SSL_IS_DTLS(s)) + ssl3_release_write_buffer(s); + + return tot + i; + } + + n -= i; + tot += i; + } +} + +static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragment) +{ + unsigned char *p, *plen; + int i, mac_size, clear = 0; + int prefix_len = 0; + int eivlen; + long align = 0; + SSL3_RECORD *wr; + SSL3_BUFFER *wb = &(s->s3->wbuf); + SSL_SESSION *sess; + + /* + * first check if there is a SSL3_BUFFER still being written out. This + * will happen with non blocking IO + */ + if (wb->left != 0) + return (ssl3_write_pending(s, type, buf, len)); + + /* If we have an alert to send, lets send it */ + if (s->s3->alert_dispatch) { + i = s->method->ssl_dispatch_alert(s); + if (i <= 0) + return (i); + /* if it went, fall through and send more stuff */ + } + + if (wb->buf == NULL) + if (!ssl3_setup_write_buffer(s)) + return -1; + + if (len == 0 && !create_empty_fragment) + return 0; + + wr = &(s->s3->wrec); + sess = s->session; + + if ((sess == NULL) || + (s->enc_write_ctx == NULL) || + (EVP_MD_CTX_md(s->write_hash) == NULL)) { +#if 1 + clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ +#else + clear = 1; +#endif + mac_size = 0; + } else { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } + + /* + * 'create_empty_fragment' is true only when this function calls itself + */ + if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) { + /* + * countermeasure against known-IV weakness in CBC ciphersuites (see + * http://www.openssl.org/~bodo/tls-cbc.txt) + */ + + if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { + /* + * recursive function call with 'create_empty_fragment' set; this + * prepares and buffers the data for an empty fragment (these + * 'prefix_len' bytes are sent out later together with the actual + * payload) + */ + prefix_len = do_ssl3_write(s, type, buf, 0, 1); + if (prefix_len <= 0) + goto err; + + if (prefix_len > + (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) + { + /* insufficient space */ + SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + s->s3->empty_fragment_done = 1; + } + + if (create_empty_fragment) { +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + /* + * extra fragment would be couple of cipher blocks, which would be + * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real + * payload, then we can just pretent we simply have two headers. + */ + align = (long)wb->buf + 2 * SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + p = wb->buf + align; + wb->offset = align; + } else if (prefix_len) { + p = wb->buf + wb->offset + prefix_len; + } else { +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (long)wb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + p = wb->buf + align; + wb->offset = align; + } + + /* write the header */ + + *(p++) = type & 0xff; + wr->type = type; + + *(p++) = (s->version >> 8); + /* + * Some servers hang if iniatial client hello is larger than 256 bytes + * and record version number > TLS 1.0 + */ + if (s->state == SSL3_ST_CW_CLNT_HELLO_B + && !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION) + *(p++) = 0x1; + else + *(p++) = s->version & 0xff; + + /* field where we are to write out packet length */ + plen = p; + p += 2; + /* Explicit IV length, block ciphers appropriate version flag */ + if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { + int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); + if (mode == EVP_CIPH_CBC_MODE) { + eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); + if (eivlen <= 1) + eivlen = 0; + } + /* Need explicit part of IV for GCM mode */ + else if (mode == EVP_CIPH_GCM_MODE) + eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; + else + eivlen = 0; + } else + eivlen = 0; + + /* lets setup the record stuff. */ + wr->data = p + eivlen; + wr->length = (int)len; + wr->input = (unsigned char *)buf; + + /* + * we now 'read' from wr->input, wr->length bytes into wr->data + */ + + /* first we compress */ + if (s->compress != NULL) { + if (!ssl3_do_compress(s)) { + SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE); + goto err; + } + } else { + memcpy(wr->data, wr->input, wr->length); + wr->input = wr->data; + } + + /* + * we should still have the output to wr->data and the input from + * wr->input. Length should be wr->length. wr->data still points in the + * wb->buf + */ + + if (mac_size != 0) { + if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0) + goto err; + wr->length += mac_size; + } + + wr->input = p; + wr->data = p; + + if (eivlen) { + /* + * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err; + */ + wr->length += eivlen; + } + + if (s->method->ssl3_enc->enc(s, 1) < 1) + goto err; + + /* record length after mac and block padding */ + s2n(wr->length, plen); + + if (s->msg_callback) + s->msg_callback(1, 0, SSL3_RT_HEADER, plen - 5, 5, s, + s->msg_callback_arg); + + /* + * we should now have wr->data pointing to the encrypted data, which is + * wr->length long + */ + wr->type = type; /* not needed but helps for debugging */ + wr->length += SSL3_RT_HEADER_LENGTH; + + if (create_empty_fragment) { + /* + * we are in a recursive call; just return the length, don't write + * out anything here + */ + return wr->length; + } + + /* now let's set up wb */ + wb->left = prefix_len + wr->length; + + /* + * memorize arguments so that ssl3_write_pending can detect bad write + * retries later + */ + s->s3->wpend_tot = len; + s->s3->wpend_buf = buf; + s->s3->wpend_type = type; + s->s3->wpend_ret = len; + + /* we now just need to write the buffer */ + return ssl3_write_pending(s, type, buf, len); + err: + return -1; +} + +/* if s->s3->wbuf.left != 0, we need to call this + * + * Return values are as per SSL_write(), i.e. + */ +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, + unsigned int len) +{ + int i; + SSL3_BUFFER *wb = &(s->s3->wbuf); + + if ((s->s3->wpend_tot > (int)len) + || (!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) + && (s->s3->wpend_buf != buf)) + || (s->s3->wpend_type != type)) { + SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); + return (-1); + } + + for (;;) { + clear_sys_error(); + if (s->wbio != NULL) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, + (char *)&(wb->buf[wb->offset]), + (unsigned int)wb->left); + } else { + SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET); + i = -1; + } + if (i == wb->left) { + wb->left = 0; + wb->offset += i; + s->rwstate = SSL_NOTHING; + return (s->s3->wpend_ret); + } else if (i <= 0) { + if (SSL_IS_DTLS(s)) { + /* + * For DTLS, just drop it. That's kind of the whole point in + * using a datagram service + */ + wb->left = 0; + } + return i; + } + wb->offset += i; + wb->left -= i; + } +} + +/*- + * Return up to 'len' payload bytes received in 'type' records. + * 'type' is one of the following: + * + * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - 0 (during a shutdown, no data has to be returned) + * + * If we don't have stored data to work from, read a SSL/TLS record first + * (possibly multiple records if we still don't have anything to return). + * + * This function must handle any surprises the peer may have for us, such as + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really + * a surprise, but handled as if it were), or renegotiation requests. + * Also if record payloads contain fragments too small to process, we store + * them until there is enough for the respective protocol (the record protocol + * may use arbitrary fragmentation and even interleaving): + * Change cipher spec protocol + * just 1 byte needed, no need for keeping anything stored + * Alert protocol + * 2 bytes needed (AlertLevel, AlertDescription) + * Handshake protocol + * 4 bytes needed (HandshakeType, uint24 length) -- we just have + * to detect unexpected Client Hello and Hello Request messages + * here, anything else is handled by higher layers + * Application data protocol + * none of our business + */ +int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +{ + int al, i, j, ret; + unsigned int n; + SSL3_RECORD *rr; + void (*cb) (const SSL *ssl, int type2, int val) = NULL; + + if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ + if (!ssl3_setup_read_buffer(s)) + return (-1); + + if ((type && (type != SSL3_RT_APPLICATION_DATA) + && (type != SSL3_RT_HANDSHAKE)) || (peek + && (type != + SSL3_RT_APPLICATION_DATA))) { + SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + + if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0)) + /* (partially) satisfy request from storage */ + { + unsigned char *src = s->s3->handshake_fragment; + unsigned char *dst = buf; + unsigned int k; + + /* peek == 0 */ + n = 0; + while ((len > 0) && (s->s3->handshake_fragment_len > 0)) { + *dst++ = *src++; + len--; + s->s3->handshake_fragment_len--; + n++; + } + /* move any remaining fragment bytes: */ + for (k = 0; k < s->s3->handshake_fragment_len; k++) + s->s3->handshake_fragment[k] = *src++; + return n; + } + + /* + * Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. + */ + + if (!s->in_handshake && SSL_in_init(s)) { + /* type == SSL3_RT_APPLICATION_DATA */ + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + start: + s->rwstate = SSL_NOTHING; + + /*- + * s->s3->rrec.type - is the type of record + * s->s3->rrec.data, - data + * s->s3->rrec.off, - offset into 'data' for next read + * s->s3->rrec.length, - number of bytes. + */ + rr = &(s->s3->rrec); + + /* get new packet if necessary */ + if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { + ret = ssl3_get_record(s); + if (ret <= 0) + return (ret); + } + + /* + * Reset the count of consecutive warning alerts if we've got a non-empty + * record that isn't an alert. + */ + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + s->cert->alert_count = 0; + + /* we now have a packet which can be read and processed */ + + if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ + && (rr->type != SSL3_RT_HANDSHAKE)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); + goto f_err; + } + + /* + * If the other end has shut down, throw anything we read away (even in + * 'peek' mode) + */ + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + rr->length = 0; + s->rwstate = SSL_NOTHING; + return (0); + } + + if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or + * SSL3_RT_HANDSHAKE */ + /* + * make sure that we are not getting application data when we are + * doing a handshake for the first time + */ + if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && + (s->enc_read_ctx == NULL)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); + goto f_err; + } + + if (len <= 0) + return (len); + + if ((unsigned int)len > rr->length) + n = rr->length; + else + n = (unsigned int)len; + + memcpy(buf, &(rr->data[rr->off]), n); + if (!peek) { + rr->length -= n; + rr->off += n; + if (rr->length == 0) { + s->rstate = SSL_ST_READ_HEADER; + rr->off = 0; + if (s->mode & SSL_MODE_RELEASE_BUFFERS + && s->s3->rbuf.left == 0) + ssl3_release_read_buffer(s); + } + } + return (n); + } + + /* + * If we get here, then type != rr->type; if we have a handshake message, + * then it was unexpected (Hello Request or Client Hello). + */ + + /* + * In case of record types for which we have 'fragment' storage, fill + * that so that we can process the data at a fixed place. + */ + { + unsigned int dest_maxlen = 0; + unsigned char *dest = NULL; + unsigned int *dest_len = NULL; + + if (rr->type == SSL3_RT_HANDSHAKE) { + dest_maxlen = sizeof(s->s3->handshake_fragment); + dest = s->s3->handshake_fragment; + dest_len = &s->s3->handshake_fragment_len; + } else if (rr->type == SSL3_RT_ALERT) { + dest_maxlen = sizeof(s->s3->alert_fragment); + dest = s->s3->alert_fragment; + dest_len = &s->s3->alert_fragment_len; + } +#ifndef OPENSSL_NO_HEARTBEATS + else if (rr->type == TLS1_RT_HEARTBEAT) { + i = tls1_process_heartbeat(s); + + if (i < 0) + return i; + + rr->length = 0; + if (s->mode & SSL_MODE_AUTO_RETRY) + goto start; + + /* Exit and notify application to read again */ + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + return (-1); + } +#endif + + if (dest_maxlen > 0) { + n = dest_maxlen - *dest_len; /* available space in 'dest' */ + if (rr->length < n) + n = rr->length; /* available bytes */ + + /* now move 'n' bytes: */ + while (n-- > 0) { + dest[(*dest_len)++] = rr->data[rr->off++]; + rr->length--; + } + + if (*dest_len < dest_maxlen) + goto start; /* fragment was too small */ + } + } + + /*- + * s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; + * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. + * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) + */ + + /* If we are a client, check for an incoming 'Hello Request': */ + if ((!s->server) && + (s->s3->handshake_fragment_len >= 4) && + (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && + (s->session != NULL) && (s->session->cipher != NULL)) { + s->s3->handshake_fragment_len = 0; + + if ((s->s3->handshake_fragment[1] != 0) || + (s->s3->handshake_fragment[2] != 0) || + (s->s3->handshake_fragment[3] != 0)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); + goto f_err; + } + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + s->s3->handshake_fragment, 4, s, + s->msg_callback_arg); + + if (SSL_is_init_finished(s) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + !s->s3->renegotiate) { + ssl3_renegotiate(s); + if (ssl3_renegotiate_check(s)) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* + * In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world + */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + } + } + /* + * we either finished a handshake or ignored the request, now try + * again to obtain the (application) data we were asked for + */ + goto start; + } + + /* + * If we are a server and get a client hello when renegotiation isn't + * allowed send back a no renegotiation alert and carry on. + */ + if (s->server + && SSL_is_init_finished(s) + && !s->s3->send_connection_binding + && s->version > SSL3_VERSION + && s->s3->handshake_fragment_len >= SSL3_HM_HEADER_LENGTH + && s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO + && s->s3->previous_client_finished_len != 0 + && (s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) == 0) { + s->s3->handshake_fragment_len = 0; + rr->length = 0; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); + goto start; + } + + if (s->s3->alert_fragment_len >= 2) { + int alert_level = s->s3->alert_fragment[0]; + int alert_descr = s->s3->alert_fragment[1]; + + s->s3->alert_fragment_len = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, + s->s3->alert_fragment, 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (alert_level << 8) | alert_descr; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (alert_level == SSL3_AL_WARNING) { + s->s3->warn_alert = alert_descr; + + s->cert->alert_count++; + if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); + goto f_err; + } + + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return (0); + } + /* + * This is a warning but we receive it if we requested + * renegotiation and the peer denied it. Terminate with a fatal + * alert because if application tried to renegotiatie it + * presumably had a good reason and expects it to succeed. In + * future we might have a renegotiation where we don't care if + * the peer refused it where we carry on. + */ + else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION); + goto f_err; + } +#ifdef SSL_AD_MISSING_SRP_USERNAME + else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME) + return (0); +#endif + } else if (alert_level == SSL3_AL_FATAL) { + char tmp[16]; + + s->rwstate = SSL_NOTHING; + s->s3->fatal_alert = alert_descr; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); + BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr); + ERR_add_error_data(2, "SSL alert number ", tmp); + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->session_ctx, s->session); + return (0); + } else { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); + goto f_err; + } + + goto start; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a + * shutdown */ + s->rwstate = SSL_NOTHING; + rr->length = 0; + return (0); + } + + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { + /* + * 'Change Cipher Spec' is just a single byte, so we know exactly + * what the record payload has to look like + */ + if ((rr->length != 1) || (rr->off != 0) || + (rr->data[0] != SSL3_MT_CCS)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto f_err; + } + + /* Check we have a cipher to change to */ + if (s->s3->tmp.new_cipher == NULL) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); + goto f_err; + } + + if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); + goto f_err; + } + + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + + rr->length = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, + rr->data, 1, s, s->msg_callback_arg); + + s->s3->change_cipher_spec = 1; + if (!ssl3_do_change_cipher_spec(s)) + goto err; + else + goto start; + } + + /* + * Unexpected handshake message (Client Hello, or protocol violation) + */ + if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) { + if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { +#if 0 /* worked only because C operator preferences + * are not as expected (and because this is + * not really needed for clients except for + * detecting protocol violations): */ + s->state = SSL_ST_BEFORE | (s->server) + ? SSL_ST_ACCEPT : SSL_ST_CONNECT; +#else + s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; +#endif + s->renegotiate = 1; + s->new_session = 1; + } + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* + * In the case where we try to read application data, but we + * trigger an SSL handshake, we return -1 with the retry + * option set. Otherwise renegotiation may cause nasty + * problems in the blocking world + */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + goto start; + } + + switch (rr->type) { + default: + /* + * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but + * TLS 1.2 says you MUST send an unexpected message alert. We use the + * TLS 1.2 behaviour for all protocol versions to prevent issues where + * no progress is being made and the peer continually sends unrecognised + * record types, using up resources processing them. + */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + case SSL3_RT_CHANGE_CIPHER_SPEC: + case SSL3_RT_ALERT: + case SSL3_RT_HANDSHAKE: + /* + * we already handled all of these, with the possible exception of + * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not + * happen when type != rr->type + */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); + goto f_err; + case SSL3_RT_APPLICATION_DATA: + /* + * At this point, we were expecting handshake data, but have + * application data. If the library was running inside ssl3_read() + * (i.e. in_read_app_data is set) and it makes sense to read + * application data at this point (session renegotiation not yet + * started), we will indulge it. + */ + if (s->s3->in_read_app_data && + (s->s3->total_renegotiations != 0) && + (((s->state & SSL_ST_CONNECT) && + (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->state <= SSL3_ST_CR_SRVR_HELLO_A) + ) || ((s->state & SSL_ST_ACCEPT) && + (s->state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->state >= SSL3_ST_SR_CLNT_HELLO_A) + ) + )) { + s->s3->in_read_app_data = 2; + return (-1); + } else { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + } + /* not reached */ + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (-1); +} + +int ssl3_do_change_cipher_spec(SSL *s) +{ + int i; + const char *sender; + int slen; + + if (s->state & SSL_ST_ACCEPT) + i = SSL3_CHANGE_CIPHER_SERVER_READ; + else + i = SSL3_CHANGE_CIPHER_CLIENT_READ; + + if (s->s3->tmp.key_block == NULL) { + if (s->session == NULL || s->session->master_key_length == 0) { + /* might happen if dtls1_read_bytes() calls this */ + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, + SSL_R_CCS_RECEIVED_EARLY); + return (0); + } + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) + return (0); + } + + if (!s->method->ssl3_enc->change_cipher_state(s, i)) + return (0); + + /* + * we have to record the message digest at this point so we can get it + * before we read the finished message + */ + if (s->state & SSL_ST_CONNECT) { + sender = s->method->ssl3_enc->server_finished_label; + slen = s->method->ssl3_enc->server_finished_label_len; + } else { + sender = s->method->ssl3_enc->client_finished_label; + slen = s->method->ssl3_enc->client_finished_label_len; + } + + i = s->method->ssl3_enc->final_finish_mac(s, + sender, slen, + s->s3->tmp.peer_finish_md); + if (i == 0) { + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); + return 0; + } + s->s3->tmp.peer_finish_md_len = i; + + return (1); +} + +int ssl3_send_alert(SSL *s, int level, int desc) +{ + /* Map tls/ssl alert value to correct one */ + desc = s->method->ssl3_enc->alert_value(desc); + if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) + desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have + * protocol_version alerts */ + if (desc < 0) + return -1; + /* If a fatal one, remove from cache */ + if ((level == 2) && (s->session != NULL)) + SSL_CTX_remove_session(s->session_ctx, s->session); + + s->s3->alert_dispatch = 1; + s->s3->send_alert[0] = level; + s->s3->send_alert[1] = desc; + if (s->s3->wbuf.left == 0) /* data still being written out? */ + return s->method->ssl_dispatch_alert(s); + /* + * else data is still being written out, we will get written some time in + * the future + */ + return -1; +} + +int ssl3_dispatch_alert(SSL *s) +{ + int i, j; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + + s->s3->alert_dispatch = 0; + i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0); + if (i <= 0) { + s->s3->alert_dispatch = 1; + } else { + /* + * Alert sent to BIO. If it is important, flush it now. If the + * message does not get sent due to non-blocking IO, we will not + * worry too much. + */ + if (s->s3->send_alert[0] == SSL3_AL_FATAL) + (void)BIO_flush(s->wbio); + + if (s->msg_callback) + s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, + 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; + cb(s, SSL_CB_WRITE_ALERT, j); + } + } + return (i); +} +/* ssl/s3_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#define REUSE_CIPHER_BUG +#define NETSCAPE_HANG_BUG + +#include +// #include "ssl_locl.h" +// #include "kssl_lcl.h" +// #include "constant_time_locl.h" +// #include "buffer.h" +// #include "rand.h" +// #include "objects.h" +// #include "evp.h" +#include "hmac.h" +// #include "x509.h" +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +// #include "bn.h" +#ifndef OPENSSL_NO_KRB5 +# include "krb5_asn.h" +#endif +// #include "md5.h" + +#ifndef OPENSSL_NO_SSL3_METHOD +static const SSL_METHOD *ssl3_get_server_method(int ver); + +static const SSL_METHOD *ssl3_get_server_method(int ver) +{ + if (ver == SSL3_VERSION) + return (SSLv3_server_method()); + else + return (NULL); +} + +IMPLEMENT_ssl3_meth_func(SSLv3_server_method, + ssl3_accept, + ssl_undefined_function, ssl3_get_server_method) +#endif +#ifndef OPENSSL_NO_SRP +static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) +{ + int ret = SSL_ERROR_NONE; + + *al = SSL_AD_UNRECOGNIZED_NAME; + + if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) && + (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) { + if (s->srp_ctx.login == NULL) { + /* + * RFC 5054 says SHOULD reject, we do so if There is no srp + * login name + */ + ret = SSL3_AL_FATAL; + *al = SSL_AD_UNKNOWN_PSK_IDENTITY; + } else { + ret = SSL_srp_server_param_with_username(s, al); + } + } + return ret; +} +#endif + +int ssl3_accept(SSL *s) +{ + BUF_MEM *buf; + unsigned long alg_k, Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + if (s->cert == NULL) { + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_NO_CERTIFICATE_SET); + return (-1); + } +#ifndef OPENSSL_NO_HEARTBEATS + /* + * If we're awaiting a HeartbeatResponse, pretend we already got and + * don't await it anymore, because Heartbeats don't make sense during + * handshakes anyway. + */ + if (s->tlsext_hb_pending) { + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + /* s->state=SSL_ST_ACCEPT; */ + + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + case SSL_ST_OK | SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version >> 8) != 3) { + SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } + s->type = SSL_ST_ACCEPT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + BUF_MEM_free(buf); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->init_buf = buf; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + s->init_num = 0; + s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY; + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + /* + * Should have been reset by ssl3_get_finished, too. + */ + s->s3->change_cipher_spec = 0; + + if (s->state != SSL_ST_RENEGOTIATE) { + /* + * Ok, we now need to push on a buffering BIO so that the + * output is sent in a way that TCP likes :-) + */ + if (!ssl_init_wbio_buffer(s, 1)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + s->state = SSL3_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + } else if (!s->s3->send_connection_binding && + !(s->options & + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + /* + * Server attempting to renegotiate with client that doesn't + * support secure renegotiation. + */ + SSLerr(SSL_F_SSL3_ACCEPT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } else { + /* + * s->state == SSL_ST_RENEGOTIATE, we will just send a + * HelloRequest + */ + s->ctx->stats.sess_accept_renegotiate++; + s->state = SSL3_ST_SW_HELLO_REQ_A; + } + break; + + case SSL3_ST_SW_HELLO_REQ_A: + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; + ret = ssl3_send_hello_request(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + break; + + case SSL3_ST_SW_HELLO_REQ_C: + s->state = SSL_ST_OK; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + case SSL3_ST_SR_CLNT_HELLO_B: + case SSL3_ST_SR_CLNT_HELLO_C: + + s->shutdown = 0; + ret = ssl3_get_client_hello(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SRP + s->state = SSL3_ST_SR_CLNT_HELLO_D; + case SSL3_ST_SR_CLNT_HELLO_D: + { + int al; + if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) { + /* + * callback indicates firther work to be done + */ + s->rwstate = SSL_X509_LOOKUP; + goto end; + } + if (ret != SSL_ERROR_NONE) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + /* + * This is not really an error but the only means to for + * a client to detect whether srp is supported. + */ + if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY) + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + } +#endif + + s->renegotiate = 2; + s->state = SSL3_ST_SW_SRVR_HELLO_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_SRVR_HELLO_A: + case SSL3_ST_SW_SRVR_HELLO_B: + ret = ssl3_send_server_hello(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->hit) { + if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->state = SSL3_ST_SW_CHANGE_A; + } +#else + if (s->hit) + s->state = SSL3_ST_SW_CHANGE_A; +#endif + else + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_A: + case SSL3_ST_SW_CERT_B: + /* Check if it is anon DH or anon ECDH, */ + /* normal PSK or KRB5 or SRP */ + if (! + (s->s3->tmp. + new_cipher->algorithm_auth & (SSL_aNULL | SSL_aKRB5 | + SSL_aSRP)) +&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + ret = ssl3_send_server_certificate(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state = SSL3_ST_SW_CERT_STATUS_A; + else + s->state = SSL3_ST_SW_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_SW_KEY_EXCH_A; + } +#else + } else + skip = 1; + + s->state = SSL3_ST_SW_KEY_EXCH_A; +#endif + s->init_num = 0; + break; + + case SSL3_ST_SW_KEY_EXCH_A: + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* + * clear this, it may get reset by + * send_server_key_exchange + */ + s->s3->tmp.use_rsa_tmp = 0; + + /* + * only send if a DH key exchange, fortezza or RSA but we have a + * sign only certificate PSK: may send PSK identity hints For + * ECC ciphersuites, we send a serverKeyExchange message only if + * the cipher suite is either ECDH-anon or ECDHE. In other cases, + * the server certificate contains the server's public key for + * key exchange. + */ + if (0 + /* + * PSK: send ServerKeyExchange if PSK identity hint if + * provided + */ +#ifndef OPENSSL_NO_PSK + || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) +#endif +#ifndef OPENSSL_NO_SRP + /* SRP: send ServerKeyExchange */ + || (alg_k & SSL_kSRP) +#endif + || (alg_k & SSL_kEDH) + || (alg_k & SSL_kEECDH) + || ((alg_k & SSL_kRSA) + && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL + || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) + && EVP_PKEY_size(s->cert->pkeys + [SSL_PKEY_RSA_ENC].privatekey) * + 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) + ) + ) + ) + ) { + ret = ssl3_send_server_key_exchange(s); + if (ret <= 0) + goto end; + } else + skip = 1; + + s->state = SSL3_ST_SW_CERT_REQ_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_REQ_A: + case SSL3_ST_SW_CERT_REQ_B: + if ( /* don't request cert unless asked for it: */ + !(s->verify_mode & SSL_VERIFY_PEER) || + /* + * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert + * during re-negotiation: + */ + (s->s3->tmp.finish_md_len != 0 && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || + /* + * never request cert in anonymous ciphersuites (see + * section "Certificate request" in SSL 3 drafts and in + * RFC 2246): + */ + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + /* + * ... except when the application insists on + * verification (against the specs, but s3_clnt.c accepts + * this for SSL 3) + */ + !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || + /* + * never request cert in Kerberos ciphersuites + */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) || + /* don't request certificate for SRP auth */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP) + /* + * With normal PSK Certificates and Certificate Requests + * are omitted + */ + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + /* no cert request */ + skip = 1; + s->s3->tmp.cert_request = 0; + s->state = SSL3_ST_SW_SRVR_DONE_A; + if (s->s3->handshake_buffer) { + if (!ssl3_digest_cached_records(s)) { + s->state = SSL_ST_ERR; + return -1; + } + } + } else { + s->s3->tmp.cert_request = 1; + ret = ssl3_send_certificate_request(s); + if (ret <= 0) + goto end; +#ifndef NETSCAPE_HANG_BUG + s->state = SSL3_ST_SW_SRVR_DONE_A; +#else + s->state = SSL3_ST_SW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; +#endif + s->init_num = 0; + } + break; + + case SSL3_ST_SW_SRVR_DONE_A: + case SSL3_ST_SW_SRVR_DONE_B: + ret = ssl3_send_server_done(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + break; + + case SSL3_ST_SW_FLUSH: + + /* + * This code originally checked to see if any data was pending + * using BIO_CTRL_INFO and then flushed. This caused problems as + * documented in PR#1939. The proposed fix doesn't completely + * resolve this issue as buggy implementations of + * BIO_CTRL_PENDING still exist. So instead we just flush + * unconditionally. + */ + + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_SR_CERT_A: + case SSL3_ST_SR_CERT_B: + if (s->s3->tmp.cert_request) { + ret = ssl3_get_client_certificate(s); + if (ret <= 0) + goto end; + } + s->init_num = 0; + s->state = SSL3_ST_SR_KEY_EXCH_A; + break; + + case SSL3_ST_SR_KEY_EXCH_A: + case SSL3_ST_SR_KEY_EXCH_B: + ret = ssl3_get_client_key_exchange(s); + if (ret <= 0) + goto end; + if (ret == 2) { + /* + * For the ECDH ciphersuites when the client sends its ECDH + * pub key in a certificate, the CertificateVerify message is + * not sent. Also for GOST ciphersuites when the client uses + * its key from the certificate for key exchange. + */ +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) + s->state = SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_SR_NEXT_PROTO_A; + else + s->state = SSL3_ST_SR_FINISHED_A; +#endif + s->init_num = 0; + } else if (SSL_USE_SIGALGS(s)) { + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + if (!s->session->peer) + break; + /* + * For sigalgs freeze the handshake buffer at this point and + * digest cached records. + */ + if (!s->s3->handshake_buffer) { + SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!ssl3_digest_cached_records(s)) { + s->state = SSL_ST_ERR; + return -1; + } + } else { + int offset = 0; + int dgst_num; + + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + /* + * We need to get hashes here so if there is a client cert, + * it can be verified FIXME - digest processing for + * CertificateVerify should be generalized. But it is next + * step + */ + if (s->s3->handshake_buffer) { + if (!ssl3_digest_cached_records(s)) { + s->state = SSL_ST_ERR; + return -1; + } + } + for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) + if (s->s3->handshake_dgst[dgst_num]) { + int dgst_size; + + s->method->ssl3_enc->cert_verify_mac(s, + EVP_MD_CTX_type + (s-> + s3->handshake_dgst + [dgst_num]), + &(s->s3-> + tmp.cert_verify_md + [offset])); + dgst_size = + EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); + if (dgst_size < 0) { + s->state = SSL_ST_ERR; + ret = -1; + goto end; + } + offset += dgst_size; + } + } + break; + + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + ret = ssl3_get_cert_verify(s); + if (ret <= 0) + goto end; + +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) + s->state = SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_SR_NEXT_PROTO_A; + else + s->state = SSL3_ST_SR_FINISHED_A; +#endif + s->init_num = 0; + break; + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + case SSL3_ST_SR_NEXT_PROTO_A: + case SSL3_ST_SR_NEXT_PROTO_B: + /* + * Enable CCS for NPN. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. This *should* be the + * first time we have received one - but we check anyway to be + * cautious. + * s->s3->change_cipher_spec is set when a CCS is + * processed in s3_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + + ret = ssl3_get_next_proto(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL3_ST_SR_FINISHED_A; + break; +#endif + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: + /* + * Enable CCS for handshakes without NPN. In NPN the CCS flag has + * already been set. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. + * s->s3->change_cipher_spec is set when a CCS is + * processed in s3_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) + goto end; + if (s->hit) + s->state = SSL_ST_OK; +#ifndef OPENSSL_NO_TLSEXT + else if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; +#endif + else + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret = ssl3_send_newsession_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret = ssl3_send_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_KEY_EXCH_A; + s->init_num = 0; + break; + +#endif + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_SW_CHANGE_B: + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + ret = ssl3_send_change_cipher_spec(s, + SSL3_ST_SW_CHANGE_A, + SSL3_ST_SW_CHANGE_B); + + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FINISHED_A; + s->init_num = 0; + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_SERVER_WRITE)) + { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + break; + + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_SW_FINISHED_B: + ret = ssl3_send_finished(s, + SSL3_ST_SW_FINISHED_A, + SSL3_ST_SW_FINISHED_B, + s->method-> + ssl3_enc->server_finished_label, + s->method-> + ssl3_enc->server_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + if (s->hit) { +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) + s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) { + s->s3->tmp.next_state = SSL3_ST_SR_NEXT_PROTO_A; + } else + s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; +#endif + } else + s->s3->tmp.next_state = SSL_ST_OK; + s->init_num = 0; + break; + + case SSL_ST_OK: + /* clean a few things up */ + ssl3_cleanup_key_block(s); + + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + + /* remove buffering on output */ + ssl_free_wbio_buffer(s); + + s->init_num = 0; + + if (s->renegotiate == 2) { /* skipped if we just sent a + * HelloRequest */ + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + s->handshake_func = ssl3_accept; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + } + + ret = 1; + goto end; + /* break; */ + + case SSL_ST_ERR: + default: + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + end: + /* BIO_flush(s->wbio); */ + + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +int ssl3_send_hello_request(SSL *s) +{ + + if (s->state == SSL3_ST_SW_HELLO_REQ_A) { + ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0); + s->state = SSL3_ST_SW_HELLO_REQ_B; + } + + /* SSL3_ST_SW_HELLO_REQ_B */ + return ssl_do_write(s); +} + +int ssl3_get_client_hello(SSL *s) +{ + int i, j, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1, cookie_valid = 0; + unsigned int cookie_len; + long n; + unsigned long id; + unsigned char *p, *d; + SSL_CIPHER *c; +#ifndef OPENSSL_NO_COMP + unsigned char *q; + SSL_COMP *comp = NULL; +#endif + STACK_OF(SSL_CIPHER) *ciphers = NULL; + + if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet) + goto retry_cert; + + /* + * We do this so that we will respond with our native type. If we are + * TLSv1 and we get SSLv3, we will respond with TLSv1, This down + * switching should be handled by a different method. If we are SSLv3, we + * will respond with SSLv3, even if prompted with TLSv1. + */ + if (s->state == SSL3_ST_SR_CLNT_HELLO_A) { + s->state = SSL3_ST_SR_CLNT_HELLO_B; + } + s->first_packet = 1; + n = s->method->ssl_get_message(s, + SSL3_ST_SR_CLNT_HELLO_B, + SSL3_ST_SR_CLNT_HELLO_C, + SSL3_MT_CLIENT_HELLO, + SSL3_RT_MAX_PLAIN_LENGTH, &ok); + + if (!ok) + return ((int)n); + s->first_packet = 0; + d = p = (unsigned char *)s->init_msg; + + /* + * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte + * for session id length + */ + if (n < 2 + SSL3_RANDOM_SIZE + 1) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + /* + * use version from inside client hello, not from record header (may + * differ: see RFC 2246, Appendix E, second paragraph) + */ + s->client_version = (((int)p[0]) << 8) | (int)p[1]; + p += 2; + + if (SSL_IS_DTLS(s) ? (s->client_version > s->version && + s->method->version != DTLS_ANY_VERSION) + : (s->client_version < s->version)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); + if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && + !s->enc_write_ctx && !s->write_hash) { + /* + * similar to ssl3_get_record, send alert using remote version + * number + */ + s->version = s->client_version; + } + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + + /* + * If we require cookies and this ClientHello doesn't contain one, just + * return since we do not want to allocate any memory yet. So check + * cookie length... + */ + if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { + unsigned int session_length, cookie_length; + + session_length = *(p + SSL3_RANDOM_SIZE); + + if (SSL3_RANDOM_SIZE + session_length + 1 + >= (unsigned int)((d + n) - p)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1); + + if (cookie_length == 0) + return 1; + } + + /* load the client random */ + memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* get the session-id */ + j = *(p++); + + if ((d + n) - p < j) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if ((j < 0) || (j > SSL_MAX_SSL_SESSION_ID_LENGTH)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + s->hit = 0; + /* + * Versions before 0.9.7 always allow clients to resume sessions in + * renegotiation. 0.9.7 and later allow this by default, but optionally + * ignore resumption requests with flag + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather + * than a change to default behavior so that applications relying on this + * for security won't even compile against older library versions). + * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to + * request renegotiation but not a new session (s->new_session remains + * unset): for servers, this essentially just means that the + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored. + */ + if ((s->new_session + && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { + if (!ssl_get_new_session(s, 1)) + goto err; + } else { + i = ssl_get_prev_session(s, p, j, d + n); + /* + * Only resume if the session's version matches the negotiated + * version. + * RFC 5246 does not provide much useful advice on resumption + * with a different protocol version. It doesn't forbid it but + * the sanity of such behaviour would be questionable. + * In practice, clients do not accept a version mismatch and + * will abort the handshake with an error. + */ + if (i == 1 && s->version == s->session->ssl_version) { /* previous + * session */ + s->hit = 1; + } else if (i == -1) + goto err; + else { /* i == 0 */ + + if (!ssl_get_new_session(s, 1)) + goto err; + } + } + + p += j; + + if (SSL_IS_DTLS(s)) { + /* cookie stuff */ + if ((d + n) - p < 1) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + cookie_len = *(p++); + + if ((unsigned int)((d + n ) - p) < cookie_len) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + /* + * The ClientHello may contain a cookie even if the + * HelloVerify message has not been sent--make sure that it + * does not cause an overflow. + */ + if (cookie_len > sizeof(s->d1->rcvd_cookie)) { + /* too much data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); + goto f_err; + } + + /* verify the cookie if appropriate option is set. */ + if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) { + memcpy(s->d1->rcvd_cookie, p, cookie_len); + + if (s->ctx->app_verify_cookie_cb != NULL) { + if (s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie, + cookie_len) == 0) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_COOKIE_MISMATCH); + goto f_err; + } + /* else cookie verification succeeded */ + } + /* default verification */ + else if (memcmp(s->d1->rcvd_cookie, s->d1->cookie, + s->d1->cookie_len) != 0) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); + goto f_err; + } + cookie_valid = 1; + } + + p += cookie_len; + if (s->method->version == DTLS_ANY_VERSION) { + /* Select version to use */ + if (s->client_version <= DTLS1_2_VERSION && + !(s->options & SSL_OP_NO_DTLSv1_2)) { + s->version = DTLS1_2_VERSION; + s->method = DTLSv1_2_server_method(); + } else if (tls1_suiteb(s)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); + s->version = s->client_version; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } else if (s->client_version <= DTLS1_VERSION && + !(s->options & SSL_OP_NO_DTLSv1)) { + s->version = DTLS1_VERSION; + s->method = DTLSv1_server_method(); + } else { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_WRONG_VERSION_NUMBER); + s->version = s->client_version; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + s->session->ssl_version = s->version; + } + } + + if ((d + n ) - p < 2) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + if (i == 0) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED); + goto f_err; + } + + /* i bytes of cipher data + 1 byte for compression length later */ + if ((d + n) - p < i + 1) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) { + goto err; + } + p += i; + + /* If it is a hit, check that the cipher is in the list */ + if (s->hit) { + j = 0; + id = s->session->cipher->id; + +#ifdef CIPHER_DEBUG + fprintf(stderr, "client sent %d ciphers\n", + sk_SSL_CIPHER_num(ciphers)); +#endif + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + c = sk_SSL_CIPHER_value(ciphers, i); +#ifdef CIPHER_DEBUG + fprintf(stderr, "client [%2d of %2d]:%s\n", + i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c)); +#endif + if (c->id == id) { + j = 1; + break; + } + } + /* + * Disabled because it can be used in a ciphersuite downgrade attack: + * CVE-2010-4180. + */ +#if 0 + if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) + && (sk_SSL_CIPHER_num(ciphers) == 1)) { + /* + * Special case as client bug workaround: the previously used + * cipher may not be in the current list, the client instead + * might be trying to continue using a cipher that before wasn't + * chosen due to server preferences. We'll have to reject the + * connection if the cipher is not enabled, though. + */ + c = sk_SSL_CIPHER_value(ciphers, 0); + if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) { + s->session->cipher = c; + j = 1; + } + } +#endif + if (j == 0) { + /* + * we need to have the cipher in the cipher list if we are asked + * to reuse it + */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_REQUIRED_CIPHER_MISSING); + goto f_err; + } + } + + /* compression */ + i = *(p++); + if ((d + n) - p < i) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } +#ifndef OPENSSL_NO_COMP + q = p; +#endif + for (j = 0; j < i; j++) { + if (p[j] == 0) + break; + } + + p += i; + if (j >= i) { + /* no compress */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED); + goto f_err; + } +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (s->version >= SSL3_VERSION) { + if (!ssl_parse_clienthello_tlsext(s, &p, d + n)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); + goto err; + } + } + + /* + * Check if we want to use external pre-shared secret for this handshake + * for not reused session only. We need to generate server_random before + * calling tls_session_secret_cb in order to allow SessionTicket + * processing to use it in key derivation. + */ + { + unsigned char *pos; + pos = s->s3->server_random; + if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) { + goto f_err; + } + } + + if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) { + SSL_CIPHER *pref_cipher = NULL; + + s->session->master_key_length = sizeof(s->session->master_key); + if (s->tls_session_secret_cb(s, s->session->master_key, + &s->session->master_key_length, ciphers, + &pref_cipher, + s->tls_session_secret_cb_arg)) { + s->hit = 1; + s->session->ciphers = ciphers; + s->session->verify_result = X509_V_OK; + + ciphers = NULL; + + /* check if some cipher was preferred by call back */ + pref_cipher = + pref_cipher ? pref_cipher : ssl3_choose_cipher(s, + s-> + session->ciphers, + SSL_get_ciphers + (s)); + if (pref_cipher == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); + goto f_err; + } + + s->session->cipher = pref_cipher; + + if (s->cipher_list) + sk_SSL_CIPHER_free(s->cipher_list); + + if (s->cipher_list_by_id) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + + s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); + s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); + } + } +#endif + + /* + * Worst case, we will use the NULL compression, but if we have other + * options, we will now look for them. We have i-1 compression + * algorithms from the client, starting at q. + */ + s->s3->tmp.new_compression = NULL; +#ifndef OPENSSL_NO_COMP + /* This only happens if we have a cache hit */ + if (s->session->compress_meth != 0) { + int m, comp_id = s->session->compress_meth; + /* Perform sanity checks on resumed compression algorithm */ + /* Can't disable compression */ + if (s->options & SSL_OP_NO_COMPRESSION) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } + /* Look for resumed compression method */ + for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); + if (comp_id == comp->id) { + s->s3->tmp.new_compression = comp; + break; + } + } + if (s->s3->tmp.new_compression == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_INVALID_COMPRESSION_ALGORITHM); + goto f_err; + } + /* Look for resumed method in compression list */ + for (m = 0; m < i; m++) { + if (q[m] == comp_id) + break; + } + if (m >= i) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING); + goto f_err; + } + } else if (s->hit) + comp = NULL; + else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) { + /* See if we have a match */ + int m, nn, o, v, done = 0; + + nn = sk_SSL_COMP_num(s->ctx->comp_methods); + for (m = 0; m < nn; m++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); + v = comp->id; + for (o = 0; o < i; o++) { + if (v == q[o]) { + done = 1; + break; + } + } + if (done) + break; + } + if (done) + s->s3->tmp.new_compression = comp; + else + comp = NULL; + } +#else + /* + * If compression is disabled we'd better not try to resume a session + * using compression. + */ + if (s->session->compress_meth != 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } +#endif + + /* + * Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher + */ + + if (!s->hit) { +#ifdef OPENSSL_NO_COMP + s->session->compress_meth = 0; +#else + s->session->compress_meth = (comp == NULL) ? 0 : comp->id; +#endif + if (s->session->ciphers != NULL) + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = ciphers; + if (ciphers == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto f_err; + } + ciphers = NULL; + if (!tls1_set_server_sigalgs(s)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + /* Let cert callback update server certificates if required */ + retry_cert: + if (s->cert->cert_cb) { + int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); + if (rv == 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CERT_CB_ERROR); + goto f_err; + } + if (rv < 0) { + s->rwstate = SSL_X509_LOOKUP; + return -1; + } + s->rwstate = SSL_NOTHING; + } + c = ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); + + if (c == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); + goto f_err; + } + s->s3->tmp.new_cipher = c; + } else { + /* Session-id reuse */ +#ifdef REUSE_CIPHER_BUG + STACK_OF(SSL_CIPHER) *sk; + SSL_CIPHER *nc = NULL; + SSL_CIPHER *ec = NULL; + + if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) { + sk = s->session->ciphers; + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + if (c->algorithm_enc & SSL_eNULL) + nc = c; + if (SSL_C_IS_EXPORT(c)) + ec = c; + } + if (nc != NULL) + s->s3->tmp.new_cipher = nc; + else if (ec != NULL) + s->s3->tmp.new_cipher = ec; + else + s->s3->tmp.new_cipher = s->session->cipher; + } else +#endif + s->s3->tmp.new_cipher = s->session->cipher; + } + + if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) { + if (!ssl3_digest_cached_records(s)) + goto f_err; + } + + /*- + * we now have the following setup. + * client_random + * cipher_list - our prefered list of ciphers + * ciphers - the clients prefered list of ciphers + * compression - basically ignored right now + * ssl version is set - sslv3 + * s->session - The ssl session has been setup. + * s->hit - session reuse flag + * s->tmp.new_cipher - the new cipher to use. + */ + + /* Handles TLS extensions that we couldn't check earlier */ + if (s->version >= SSL3_VERSION) { + if (!ssl_check_clienthello_tlsext_late(s, &al)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto f_err; + } + } + + ret = cookie_valid ? 2 : 1; + if (0) { + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + } + + if (ciphers != NULL) + sk_SSL_CIPHER_free(ciphers); + return ret; +} + +int ssl3_send_server_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i, sl; + int al = 0; + unsigned long l; + + if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { + buf = (unsigned char *)s->init_buf->data; +#ifdef OPENSSL_NO_TLSEXT + p = s->s3->server_random; + if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) { + s->state = SSL_ST_ERR; + return -1; + } +#endif + /* Do the message type and length last */ + d = p = ssl_handshake_start(s); + + *(p++) = s->version >> 8; + *(p++) = s->version & 0xff; + + /* Random stuff */ + memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /*- + * There are several cases for the session ID to send + * back in the server hello: + * - For session reuse from the session cache, + * we send back the old session ID. + * - If stateless session reuse (using a session ticket) + * is successful, we send back the client's "session ID" + * (which doesn't actually identify the session). + * - If it is a new session, we send back the new + * session ID. + * - However, if we want the new session to be single-use, + * we send back a 0-length session ID. + * s->hit is non-zero in either case of session reuse, + * so the following won't overwrite an ID that we're supposed + * to send back. + */ + if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) + && !s->hit) + s->session->session_id_length = 0; + + sl = s->session->session_id_length; + if (sl > (int)sizeof(s->session->session_id)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } + *(p++) = sl; + memcpy(p, s->session->session_id, sl); + p += sl; + + /* put the cipher */ + i = ssl3_put_cipher_by_char(s->s3->tmp.new_cipher, p); + p += i; + + /* put the compression method */ +#ifdef OPENSSL_NO_COMP + *(p++) = 0; +#else + if (s->s3->tmp.new_compression == NULL) + *(p++) = 0; + else + *(p++) = s->s3->tmp.new_compression->id; +#endif +#ifndef OPENSSL_NO_TLSEXT + if (ssl_prepare_serverhello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); + s->state = SSL_ST_ERR; + return -1; + } + if ((p = + ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH, + &al)) == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } +#endif + /* do the header */ + l = (p - d); + ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l); + s->state = SSL3_ST_SW_SRVR_HELLO_B; + } + + /* SSL3_ST_SW_SRVR_HELLO_B */ + return ssl_do_write(s); +} + +int ssl3_send_server_done(SSL *s) +{ + + if (s->state == SSL3_ST_SW_SRVR_DONE_A) { + ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0); + s->state = SSL3_ST_SW_SRVR_DONE_B; + } + + /* SSL3_ST_SW_SRVR_DONE_B */ + return ssl_do_write(s); +} + +int ssl3_send_server_key_exchange(SSL *s) +{ +#ifndef OPENSSL_NO_RSA + unsigned char *q; + int j, num; + RSA *rsa; + unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; + unsigned int u; +#endif +#ifndef OPENSSL_NO_DH +# ifdef OPENSSL_NO_RSA + int j; +# endif + DH *dh = NULL, *dhp; +#endif +#ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh = NULL, *ecdhp; + unsigned char *encodedPoint = NULL; + int encodedlen = 0; + int curve_id = 0; + BN_CTX *bn_ctx = NULL; +#endif + EVP_PKEY *pkey; + const EVP_MD *md = NULL; + unsigned char *p, *d; + int al, i; + unsigned long type; + int n; + CERT *cert; + BIGNUM *r[4]; + int nr[4], kn; + BUF_MEM *buf; + EVP_MD_CTX md_ctx; + + EVP_MD_CTX_init(&md_ctx); + if (s->state == SSL3_ST_SW_KEY_EXCH_A) { + type = s->s3->tmp.new_cipher->algorithm_mkey; + cert = s->cert; + + buf = s->init_buf; + + r[0] = r[1] = r[2] = r[3] = NULL; + n = 0; +#ifndef OPENSSL_NO_RSA + if (type & SSL_kRSA) { + rsa = cert->rsa_tmp; + if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) { + rsa = s->cert->rsa_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s->s3-> + tmp.new_cipher)); + if (rsa == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_ERROR_GENERATING_TMP_RSA_KEY); + goto f_err; + } + RSA_up_ref(rsa); + cert->rsa_tmp = rsa; + } + if (rsa == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_RSA_KEY); + goto f_err; + } + r[0] = rsa->n; + r[1] = rsa->e; + s->s3->tmp.use_rsa_tmp = 1; + } else +#endif +#ifndef OPENSSL_NO_DH + if (type & SSL_kEDH) { + dhp = cert->dh_tmp; + if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) + dhp = s->cert->dh_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s->s3-> + tmp.new_cipher)); + if (dhp == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_DH_KEY); + goto f_err; + } + + if (s->s3->tmp.dh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((dh = DHparams_dup(dhp)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + + s->s3->tmp.dh = dh; + if (!DH_generate_key(dh)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + r[0] = dh->p; + r[1] = dh->g; + r[2] = dh->pub_key; + } else +#endif +#ifndef OPENSSL_NO_ECDH + if (type & SSL_kEECDH) { + const EC_GROUP *group; + + if (s->s3->tmp.ecdh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + ecdhp = cert->ecdh_tmp; + if (s->cert->ecdh_tmp_auto) { + /* Get NID of appropriate shared curve */ + int nid = tls1_shared_curve(s, -2); + if (nid != NID_undef) + ecdhp = EC_KEY_new_by_curve_name(nid); + } else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) { + ecdhp = s->cert->ecdh_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s-> + s3->tmp.new_cipher)); + } + if (ecdhp == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_ECDH_KEY); + goto f_err; + } + + /* Duplicate the ECDH structure. */ + if (s->cert->ecdh_tmp_auto) + ecdh = ecdhp; + else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + s->s3->tmp.ecdh = ecdh; + if ((EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL) || + (s->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + } + + if (((group = EC_KEY_get0_group(ecdh)) == NULL) || + (EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + (EC_GROUP_get_degree(group) > 163)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); + goto err; + } + + /* + * XXX: For now, we only support ephemeral ECDH keys over named + * (not generic) curves. For supported named curves, curve_id is + * non-zero. + */ + if ((curve_id = + tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group))) + == 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + goto err; + } + + /* + * Encode the public key. First check the size of encoding and + * allocate memory accordingly. + */ + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = (unsigned char *) + OPENSSL_malloc(encodedlen * sizeof(unsigned char)); + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || (bn_ctx == NULL)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encodedlen, bn_ctx); + + if (encodedlen == 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + BN_CTX_free(bn_ctx); + bn_ctx = NULL; + + /* + * XXX: For now, we only support named (not generic) curves in + * ECDH ephemeral key exchanges. In this situation, we need four + * additional bytes to encode the entire ServerECDHParams + * structure. + */ + n = 4 + encodedlen; + + /* + * We'll generate the serverKeyExchange message explicitly so we + * can set these to NULLs + */ + r[0] = NULL; + r[1] = NULL; + r[2] = NULL; + r[3] = NULL; + } else +#endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) { + /* + * reserve size for record length and PSK identity hint + */ + n += 2 + strlen(s->ctx->psk_identity_hint); + } else +#endif /* !OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (type & SSL_kSRP) { + if ((s->srp_ctx.N == NULL) || + (s->srp_ctx.g == NULL) || + (s->srp_ctx.s == NULL) || (s->srp_ctx.B == NULL)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_SRP_PARAM); + goto err; + } + r[0] = s->srp_ctx.N; + r[1] = s->srp_ctx.g; + r[2] = s->srp_ctx.s; + r[3] = s->srp_ctx.B; + } else +#endif + { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + goto f_err; + } + for (i = 0; i < 4 && r[i] != NULL; i++) { + nr[i] = BN_num_bytes(r[i]); +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (type & SSL_kSRP)) + n += 1 + nr[i]; + else +#endif +#ifndef OPENSSL_NO_DH + /* + * for interoperability with some versions of the Microsoft TLS + * stack, we need to zero pad the DHE pub key to the same length + * as the prime, so use the length of the prime here + */ + if ((i == 2) && (type & (SSL_kEDH))) + n += 2 + nr[0]; + else +#endif + n += 2 + nr[i]; + } + + if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md)) + == NULL) { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + kn = EVP_PKEY_size(pkey); + /* Allow space for signature algorithm */ + if (SSL_USE_SIGALGS(s)) + kn += 2; + /* Allow space for signature length */ + kn += 2; + } else { + pkey = NULL; + kn = 0; + } + + if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_BUF); + goto err; + } + d = p = ssl_handshake_start(s); + + for (i = 0; i < 4 && r[i] != NULL; i++) { +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (type & SSL_kSRP)) { + *p = nr[i]; + p++; + } else +#endif +#ifndef OPENSSL_NO_DH + /* + * for interoperability with some versions of the Microsoft TLS + * stack, we need to zero pad the DHE pub key to the same length + * as the prime + */ + if ((i == 2) && (type & (SSL_kEDH))) { + s2n(nr[0], p); + for (j = 0; j < (nr[0] - nr[2]); ++j) { + *p = 0; + ++p; + } + } else +#endif + s2n(nr[i], p); + BN_bn2bin(r[i], p); + p += nr[i]; + } + +#ifndef OPENSSL_NO_ECDH + if (type & SSL_kEECDH) { + /* + * XXX: For now, we only support named (not generic) curves. In + * this situation, the serverKeyExchange message has: [1 byte + * CurveType], [2 byte CurveName] [1 byte length of encoded + * point], followed by the actual encoded point itself + */ + *p = NAMED_CURVE_TYPE; + p += 1; + *p = 0; + p += 1; + *p = curve_id; + p += 1; + *p = encodedlen; + p += 1; + memcpy((unsigned char *)p, + (unsigned char *)encodedPoint, encodedlen); + OPENSSL_free(encodedPoint); + encodedPoint = NULL; + p += encodedlen; + } +#endif + +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) { + size_t len = strlen(s->ctx->psk_identity_hint); + + /* copy PSK identity hint */ + s2n(len, p); + memcpy(p, s->ctx->psk_identity_hint, len); + p += len; + } +#endif + + /* not anonymous */ + if (pkey != NULL) { + /* + * n is the length of the params, they start at &(d[4]) and p + * points to the space at the end. + */ +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { + q = md_buf; + j = 0; + for (num = 2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + if (EVP_DigestInit_ex(&md_ctx, + (num == 2) ? s->ctx->md5 + : s->ctx->sha1, + NULL) <= 0 + || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&md_ctx, d, n) <= 0 + || EVP_DigestFinal_ex(&md_ctx, q, + (unsigned int *)&i) <= 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_LIB_EVP); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + q += i; + j += i; + } + if (RSA_sign(NID_md5_sha1, md_buf, j, + &(p[2]), &u, pkey->pkey.rsa) <= 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_RSA); + goto err; + } + s2n(u, p); + n += u + 2; + } else +#endif + if (md) { + /* send signature algorithm */ + if (SSL_USE_SIGALGS(s)) { + if (!tls12_get_sigandhash(p, pkey, md)) { + /* Should never happen */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto f_err; + } + p += 2; + } +#ifdef SSL_DEBUG + fprintf(stderr, "Using hash %s\n", EVP_MD_name(md)); +#endif + if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0 + || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_SignUpdate(&md_ctx, d, n) <= 0 + || EVP_SignFinal(&md_ctx, &(p[2]), + (unsigned int *)&i, pkey) <= 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_EVP); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + s2n(i, p); + n += i + 2; + if (SSL_USE_SIGALGS(s)) + n += 2; + } else { + /* Is this error check actually needed? */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNKNOWN_PKEY_TYPE); + goto f_err; + } + } + + ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n); + } + + s->state = SSL3_ST_SW_KEY_EXCH_B; + EVP_MD_CTX_cleanup(&md_ctx); + return ssl_do_write(s); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: +#ifndef OPENSSL_NO_ECDH + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + BN_CTX_free(bn_ctx); +#endif + EVP_MD_CTX_cleanup(&md_ctx); + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_send_certificate_request(SSL *s) +{ + unsigned char *p, *d; + int i, j, nl, off, n; + STACK_OF(X509_NAME) *sk = NULL; + X509_NAME *name; + BUF_MEM *buf; + + if (s->state == SSL3_ST_SW_CERT_REQ_A) { + buf = s->init_buf; + + d = p = ssl_handshake_start(s); + + /* get the list of acceptable cert types */ + p++; + n = ssl3_get_req_cert_type(s, p); + d[0] = n; + p += n; + n++; + + if (SSL_USE_SIGALGS(s)) { + const unsigned char *psigs; + nl = tls12_get_psigalgs(s, 1, &psigs); + if (nl > SSL_MAX_2_BYTE_LEN) { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, + SSL_R_LENGTH_TOO_LONG); + goto err; + } + s2n(nl, p); + memcpy(p, psigs, nl); + p += nl; + n += nl + 2; + } + + off = n; + p += 2; + n += 2; + + sk = SSL_get_client_CA_list(s); + nl = 0; + if (sk != NULL) { + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + name = sk_X509_NAME_value(sk, i); + j = i2d_X509_NAME(name, NULL); + if (j > SSL_MAX_2_BYTE_LEN) { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, + SSL_R_LENGTH_TOO_LONG); + goto err; + } + if (!BUF_MEM_grow_clean + (buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, + ERR_R_BUF_LIB); + goto err; + } + p = ssl_handshake_start(s) + n; + if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) { + s2n(j, p); + i2d_X509_NAME(name, &p); + n += 2 + j; + nl += 2 + j; + } else { + d = p; + i2d_X509_NAME(name, &p); + j -= 2; + s2n(j, d); + j += 2; + n += j; + nl += j; + } + if (nl > SSL_MAX_2_BYTE_LEN) { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, + SSL_R_LENGTH_TOO_LONG); + goto err; + } + } + } + /* else no CA names */ + p = ssl_handshake_start(s) + off; + s2n(nl, p); + + ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n); + +#ifdef NETSCAPE_HANG_BUG + if (!SSL_IS_DTLS(s)) { + if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_BUF_LIB); + goto err; + } + p = (unsigned char *)s->init_buf->data + s->init_num; + /* do the header */ + *(p++) = SSL3_MT_SERVER_DONE; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + s->init_num += 4; + } +#endif + + s->state = SSL3_ST_SW_CERT_REQ_B; + } + + /* SSL3_ST_SW_CERT_REQ_B */ + return ssl_do_write(s); + err: + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_client_key_exchange(SSL *s) +{ + int i, al, ok; + long n; + unsigned long alg_k; + unsigned char *p; +#ifndef OPENSSL_NO_RSA + RSA *rsa = NULL; + EVP_PKEY *pkey = NULL; +#endif +#ifndef OPENSSL_NO_DH + BIGNUM *pub = NULL; + DH *dh_srvr, *dh_clnt = NULL; +#endif +#ifndef OPENSSL_NO_KRB5 + KSSL_ERR kssl_err; +#endif /* OPENSSL_NO_KRB5 */ + +#ifndef OPENSSL_NO_ECDH + EC_KEY *srvr_ecdh = NULL; + EVP_PKEY *clnt_pub_pkey = NULL; + EC_POINT *clnt_ecpoint = NULL; + BN_CTX *bn_ctx = NULL; +#endif + + n = s->method->ssl_get_message(s, + SSL3_ST_SR_KEY_EXCH_A, + SSL3_ST_SR_KEY_EXCH_B, + SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, &ok); + + if (!ok) + return ((int)n); + p = (unsigned char *)s->init_msg; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) { + unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + int decrypt_len; + unsigned char decrypt_good, version_good; + size_t j, padding_len; + + /* FIX THIS UP EAY EAY EAY EAY */ + if (s->s3->tmp.use_rsa_tmp) { + if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL)) + rsa = s->cert->rsa_tmp; + /* + * Don't do a callback because rsa_tmp should be sent already + */ + if (rsa == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_RSA_PKEY); + goto f_err; + + } + } else { + pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; + if ((pkey == NULL) || + (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_RSA_CERTIFICATE); + goto f_err; + } + rsa = pkey->pkey.rsa; + } + + /* TLS and [incidentally] DTLS{0xFEFF} */ + if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) { + n2s(p, i); + if (n != i + 2) { + if (!(s->options & SSL_OP_TLS_D5_BUG)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto f_err; + } else + p -= 2; + } else + n = i; + } + + /* + * Reject overly short RSA ciphertext because we want to be sure + * that the buffer size makes it safe to iterate over the entire + * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The + * actual expected size is larger due to RSA padding, but the + * bound is sufficient to be safe. + */ + if (n < SSL_MAX_MASTER_KEY_LENGTH) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto f_err; + } + + /* + * We must not leak whether a decryption failure occurs because of + * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). The code follows that advice of the TLS RFC and + * generates a random premaster secret for the case that the decrypt + * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 + */ + + if (RAND_bytes(rand_premaster_secret, + sizeof(rand_premaster_secret)) <= 0) + goto err; + + /* + * Decrypt with no padding. PKCS#1 padding will be removed as part of + * the timing-sensitive code below. + */ + decrypt_len = + RSA_private_decrypt((int)n, p, p, rsa, RSA_NO_PADDING); + if (decrypt_len < 0) + goto err; + + /* Check the padding. See RFC 3447, section 7.2.2. */ + + /* + * The smallest padded premaster is 11 bytes of overhead. Small keys + * are publicly invalid, so this may return immediately. This ensures + * PS is at least 8 bytes. + */ + if (decrypt_len < 11 + SSL_MAX_MASTER_KEY_LENGTH) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto f_err; + } + + padding_len = decrypt_len - SSL_MAX_MASTER_KEY_LENGTH; + decrypt_good = constant_time_eq_int_8(p[0], 0) & + constant_time_eq_int_8(p[1], 2); + for (j = 2; j < padding_len - 1; j++) { + decrypt_good &= ~constant_time_is_zero_8(p[j]); + } + decrypt_good &= constant_time_is_zero_8(p[padding_len - 1]); + p += padding_len; + + /* + * If the version in the decrypted pre-master secret is correct then + * version_good will be 0xff, otherwise it'll be zero. The + * Klima-Pokorny-Rosa extension of Bleichenbacher's attack + * (http://eprint.iacr.org/2003/052/) exploits the version number + * check as a "bad version oracle". Thus version checks are done in + * constant time and are treated like any other decryption error. + */ + version_good = + constant_time_eq_8(p[0], (unsigned)(s->client_version >> 8)); + version_good &= + constant_time_eq_8(p[1], (unsigned)(s->client_version & 0xff)); + + /* + * The premaster secret must contain the same version number as the + * ClientHello to detect version rollback attacks (strangely, the + * protocol does not offer such protection for DH ciphersuites). + * However, buggy clients exist that send the negotiated protocol + * version instead if the server does not support the requested + * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such + * clients. + */ + if (s->options & SSL_OP_TLS_ROLLBACK_BUG) { + unsigned char workaround_good; + workaround_good = + constant_time_eq_8(p[0], (unsigned)(s->version >> 8)); + workaround_good &= + constant_time_eq_8(p[1], (unsigned)(s->version & 0xff)); + version_good |= workaround_good; + } + + /* + * Both decryption and version must be good for decrypt_good to + * remain non-zero (0xff). + */ + decrypt_good &= version_good; + + /* + * Now copy rand_premaster_secret over from p using + * decrypt_good_mask. If decryption failed, then p does not + * contain valid plaintext, however, a check above guarantees + * it is still sufficiently large to read from. + */ + for (j = 0; j < sizeof(rand_premaster_secret); j++) { + p[j] = constant_time_select_8(decrypt_good, p[j], + rand_premaster_secret[j]); + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, + sizeof + (rand_premaster_secret)); + OPENSSL_cleanse(p, sizeof(rand_premaster_secret)); + } else +#endif +#ifndef OPENSSL_NO_DH + if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { + int idx = -1; + EVP_PKEY *skey = NULL; + if (n > 1) { + n2s(p, i); + } else { + if (alg_k & SSL_kDHE) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); + goto f_err; + } + i = 0; + } + if (n && n != i + 2) { + if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } else { + p -= 2; + i = (int)n; + } + } + if (alg_k & SSL_kDHr) + idx = SSL_PKEY_DH_RSA; + else if (alg_k & SSL_kDHd) + idx = SSL_PKEY_DH_DSA; + if (idx >= 0) { + skey = s->cert->pkeys[idx].privatekey; + if ((skey == NULL) || + (skey->type != EVP_PKEY_DH) || (skey->pkey.dh == NULL)) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_RSA_CERTIFICATE); + goto f_err; + } + dh_srvr = skey->pkey.dh; + } else if (s->s3->tmp.dh == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_DH_KEY); + goto f_err; + } else + dh_srvr = s->s3->tmp.dh; + + if (n == 0L) { + /* Get pubkey from cert */ + EVP_PKEY *clkey = X509_get_pubkey(s->session->peer); + if (clkey) { + if (EVP_PKEY_cmp_parameters(clkey, skey) == 1) + dh_clnt = EVP_PKEY_get1_DH(clkey); + } + if (dh_clnt == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_DH_KEY); + goto f_err; + } + EVP_PKEY_free(clkey); + pub = dh_clnt->pub_key; + } else + pub = BN_bin2bn(p, i, NULL); + if (pub == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB); + goto err; + } + + i = DH_compute_key(p, pub, dh_srvr); + + if (i <= 0) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + BN_clear_free(pub); + goto f_err; + } + + DH_free(s->s3->tmp.dh); + s->s3->tmp.dh = NULL; + if (dh_clnt) + DH_free(dh_clnt); + else + BN_clear_free(pub); + pub = NULL; + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, i); + OPENSSL_cleanse(p, i); + if (dh_clnt) + return 2; + } else +#endif +#ifndef OPENSSL_NO_KRB5 + if (alg_k & SSL_kKRB5) { + krb5_error_code krb5rc; + krb5_data enc_ticket; + krb5_data authenticator; + krb5_data enc_pms; + KSSL_CTX *kssl_ctx = s->kssl_ctx; + EVP_CIPHER_CTX ciph_ctx; + const EVP_CIPHER *enc = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH]; + int padl, outl; + krb5_timestamp authtime = 0; + krb5_ticket_times ttimes; + int kerr = 0; + + EVP_CIPHER_CTX_init(&ciph_ctx); + + if (!kssl_ctx) + kssl_ctx = kssl_ctx_new(); + + n2s(p, i); + enc_ticket.length = i; + + if (n < (long)(enc_ticket.length + 6)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + enc_ticket.data = (char *)p; + p += enc_ticket.length; + + n2s(p, i); + authenticator.length = i; + + if (n < (long)(enc_ticket.length + authenticator.length + 6)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + authenticator.data = (char *)p; + p += authenticator.length; + + n2s(p, i); + enc_pms.length = i; + enc_pms.data = (char *)p; + p += enc_pms.length; + + /* + * Note that the length is checked again below, ** after decryption + */ + if (enc_pms.length > sizeof(pms)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if (n != (long)(enc_ticket.length + authenticator.length + + enc_pms.length + 6)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes, + &kssl_err)) != 0) { +# ifdef KSSL_DEBUG + fprintf(stderr, "kssl_sget_tkt rtn %d [%d]\n", + krb5rc, kssl_err.reason); + if (kssl_err.text) + fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); +# endif /* KSSL_DEBUG */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); + goto err; + } + + /* + * Note: no authenticator is not considered an error, ** but will + * return authtime == 0. + */ + if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator, + &authtime, &kssl_err)) != 0) { +# ifdef KSSL_DEBUG + fprintf(stderr, "kssl_check_authent rtn %d [%d]\n", + krb5rc, kssl_err.reason); + if (kssl_err.text) + fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); +# endif /* KSSL_DEBUG */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); + goto err; + } + + if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc); + goto err; + } +# ifdef KSSL_DEBUG + kssl_ctx_show(kssl_ctx); +# endif /* KSSL_DEBUG */ + + enc = kssl_map_enc(kssl_ctx->enctype); + if (enc == NULL) + goto err; + + memset(iv, 0, sizeof(iv)); /* per RFC 1510 */ + + if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto err; + } + if (!EVP_DecryptUpdate(&ciph_ctx, pms, &outl, + (unsigned char *)enc_pms.data, enc_pms.length)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + kerr = 1; + goto kclean; + } + if (outl > SSL_MAX_MASTER_KEY_LENGTH) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + kerr = 1; + goto kclean; + } + if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + kerr = 1; + goto kclean; + } + outl += padl; + if (outl > SSL_MAX_MASTER_KEY_LENGTH) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + kerr = 1; + goto kclean; + } + if (!((pms[0] == (s->client_version >> 8)) + && (pms[1] == (s->client_version & 0xff)))) { + /* + * The premaster secret must contain the same version number as + * the ClientHello to detect version rollback attacks (strangely, + * the protocol does not offer such protection for DH + * ciphersuites). However, buggy clients exist that send random + * bytes instead of the protocol version. If + * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. + * (Perhaps we should have a separate BUG value for the Kerberos + * cipher) + */ + if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_AD_DECODE_ERROR); + kerr = 1; + goto kclean; + } + } + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + pms, outl); + + if (kssl_ctx->client_princ) { + size_t len = strlen(kssl_ctx->client_princ); + if (len < SSL_MAX_KRB5_PRINCIPAL_LENGTH) { + s->session->krb5_client_princ_len = len; + memcpy(s->session->krb5_client_princ, kssl_ctx->client_princ, + len); + } + } + + /*- Was doing kssl_ctx_free() here, + * but it caused problems for apache. + * kssl_ctx = kssl_ctx_free(kssl_ctx); + * if (s->kssl_ctx) s->kssl_ctx = NULL; + */ + + kclean: + OPENSSL_cleanse(pms, sizeof(pms)); + if (kerr) + goto err; + } else +#endif /* OPENSSL_NO_KRB5 */ + +#ifndef OPENSSL_NO_ECDH + if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { + int ret = 1; + int field_size = 0; + const EC_KEY *tkey; + const EC_GROUP *group; + const BIGNUM *priv_key; + + /* initialize structures for server's ECDH key pair */ + if ((srvr_ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Let's get server private key and group information */ + if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { + /* use the certificate */ + tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec; + } else { + /* + * use the ephermeral values we saved when generating the + * ServerKeyExchange msg. + */ + tkey = s->s3->tmp.ecdh; + } + + group = EC_KEY_get0_group(tkey); + priv_key = EC_KEY_get0_private_key(tkey); + + if (!EC_KEY_set_group(srvr_ecdh, group) || + !EC_KEY_set_private_key(srvr_ecdh, priv_key)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + + /* Let's get client's public key */ + if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (n == 0L) { + /* Client Publickey was in Client Certificate */ + + if (alg_k & SSL_kEECDH) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_ECDH_KEY); + goto f_err; + } + if (((clnt_pub_pkey = X509_get_pubkey(s->session->peer)) + == NULL) || (clnt_pub_pkey->type != EVP_PKEY_EC)) { + /* + * XXX: For now, we do not support client authentication + * using ECDH certificates so this branch (n == 0L) of the + * code is never executed. When that support is added, we + * ought to ensure the key received in the certificate is + * authorized for key agreement. ECDH_compute_key implicitly + * checks that the two ECDH shares are for the same group. + */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); + goto f_err; + } + + if (EC_POINT_copy(clnt_ecpoint, + EC_KEY_get0_public_key(clnt_pub_pkey-> + pkey.ec)) == 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + ret = 2; /* Skip certificate verify processing */ + } else { + /* + * Get client's public key from encoded point in the + * ClientKeyExchange message. + */ + if ((bn_ctx = BN_CTX_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Get encoded point length */ + i = *p; + p += 1; + if (n != 1 + i) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + /* + * p is pointing to somewhere in the buffer currently, so set it + * to the start + */ + p = (unsigned char *)s->init_buf->data; + } + + /* Compute the shared pre-master secret */ + field_size = EC_GROUP_get_degree(group); + if (field_size <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + i = ECDH_compute_key(p, (field_size + 7) / 8, clnt_ecpoint, srvr_ecdh, + NULL); + if (i <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + EVP_PKEY_free(clnt_pub_pkey); + EC_POINT_free(clnt_ecpoint); + EC_KEY_free(srvr_ecdh); + BN_CTX_free(bn_ctx); + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + + /* Compute the master secret */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, i); + + OPENSSL_cleanse(p, i); + return (ret); + } else +#endif +#ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kPSK) { + unsigned char *t = NULL; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; + unsigned int pre_ms_len = 0, psk_len = 0; + int psk_err = 1; + char tmp_id[PSK_MAX_IDENTITY_LEN + 1]; + + al = SSL_AD_HANDSHAKE_FAILURE; + + n2s(p, i); + if (n != i + 2) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + goto psk_err; + } + if (i > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto psk_err; + } + if (s->psk_server_callback == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_SERVER_CB); + goto psk_err; + } + + /* + * Create guaranteed NULL-terminated identity string for the callback + */ + memcpy(tmp_id, p, i); + memset(tmp_id + i, 0, PSK_MAX_IDENTITY_LEN + 1 - i); + psk_len = s->psk_server_callback(s, tmp_id, + psk_or_pre_ms, + sizeof(psk_or_pre_ms)); + OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN + 1); + + if (psk_len > PSK_MAX_PSK_LEN) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto psk_err; + } else if (psk_len == 0) { + /* + * PSK related to the given identity not found + */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + al = SSL_AD_UNKNOWN_PSK_IDENTITY; + goto psk_err; + } + + /* create PSK pre_master_secret */ + pre_ms_len = 2 + psk_len + 2 + psk_len; + t = psk_or_pre_ms; + memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t += psk_len; + s2n(psk_len, t); + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strndup((char *)p, i); + if (s->session->psk_identity == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL && + s->session->psk_identity_hint == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + psk_or_pre_ms, + pre_ms_len); + psk_err = 0; + psk_err: + OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_err != 0) + goto f_err; + } else +#endif +#ifndef OPENSSL_NO_SRP + if (alg_k & SSL_kSRP) { + int param_len; + + n2s(p, i); + param_len = i + 2; + if (param_len > n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_SRP_A_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.A = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 + || BN_is_zero(s->srp_ctx.A)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_SRP_PARAMETERS); + goto f_err; + } + if (s->session->srp_username != NULL) + OPENSSL_free(s->session->srp_username); + s->session->srp_username = BUF_strdup(s->srp_ctx.login); + if (s->session->srp_username == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((s->session->master_key_length = + SRP_generate_server_master_secret(s, + s->session->master_key)) < 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + p += i; + } else +#endif /* OPENSSL_NO_SRP */ + if (alg_k & SSL_kGOST) { + int ret = 0; + EVP_PKEY_CTX *pkey_ctx; + EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; + unsigned char premaster_secret[32], *start; + size_t outlen = 32, inlen; + unsigned long alg_a; + int Ttag, Tclass; + long Tlen; + + /* Get our certificate private key */ + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if (alg_a & SSL_aGOST94) + pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; + else if (alg_a & SSL_aGOST01) + pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; + + pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); + if (pkey_ctx == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; + } + if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto gerr; + } + /* + * If client certificate is present and is of the same type, maybe + * use it for key exchange. Don't mind errors from + * EVP_PKEY_derive_set_peer, because it is completely valid to use a + * client certificate for authorization only. + */ + client_pub_pkey = X509_get_pubkey(s->session->peer); + if (client_pub_pkey) { + if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) + ERR_clear_error(); + } + /* Decrypt session key */ + if (ASN1_get_object + ((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, + n) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE + || Tclass != V_ASN1_UNIVERSAL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto gerr; + } + start = p; + inlen = Tlen; + if (EVP_PKEY_decrypt + (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto gerr; + } + /* Generate master secret */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + premaster_secret, 32); + OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret)); + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl + (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) + ret = 2; + else + ret = 1; + gerr: + EVP_PKEY_free(client_pub_pkey); + EVP_PKEY_CTX_free(pkey_ctx); + if (ret) + return ret; + else + goto err; + } else { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE); + goto f_err; + } + + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP) + err: +#endif +#ifndef OPENSSL_NO_ECDH + EVP_PKEY_free(clnt_pub_pkey); + EC_POINT_free(clnt_ecpoint); + if (srvr_ecdh != NULL) + EC_KEY_free(srvr_ecdh); + BN_CTX_free(bn_ctx); +#endif + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_cert_verify(SSL *s) +{ + EVP_PKEY *pkey = NULL; + unsigned char *p; + int al, ok, ret = 0; + long n; + int type = 0, i, j; + X509 *peer; + const EVP_MD *md = NULL; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + + /* + * We should only process a CertificateVerify message if we have received + * a Certificate from the client. If so then |s->session->peer| will be non + * NULL. In some instances a CertificateVerify message is not required even + * if the peer has sent a Certificate (e.g. such as in the case of static + * DH). In that case the ClientKeyExchange processing will skip the + * CertificateVerify state so we should not arrive here. + */ + if (s->session->peer == NULL) { + ret = 1; + goto end; + } + + n = s->method->ssl_get_message(s, + SSL3_ST_SR_CERT_VRFY_A, + SSL3_ST_SR_CERT_VRFY_B, + SSL3_MT_CERTIFICATE_VERIFY, + SSL3_RT_MAX_PLAIN_LENGTH, &ok); + + if (!ok) + return ((int)n); + + peer = s->session->peer; + pkey = X509_get_pubkey(peer); + if (pkey == NULL) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + + type = X509_certificate_type(peer, pkey); + + if (!(type & EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); + al = SSL_AD_ILLEGAL_PARAMETER; + goto f_err; + } + + /* we now have a signature that we need to verify */ + p = (unsigned char *)s->init_msg; + /* Check for broken implementations of GOST ciphersuites */ + /* + * If key is GOST and n is exactly 64, it is bare signature without + * length field + */ + if (n == 64 && (pkey->type == NID_id_GostR3410_94 || + pkey->type == NID_id_GostR3410_2001)) { + i = 64; + } else { + if (SSL_USE_SIGALGS(s)) { + int rv = tls12_check_peer_sigalg(&md, s, p, pkey); + if (rv == -1) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } else if (rv == 0) { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } +#ifdef SSL_DEBUG + fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); +#endif + p += 2; + n -= 2; + } + n2s(p, i); + n -= 2; + if (i > n) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + } + j = EVP_PKEY_size(pkey); + if ((i > j) || (n > j) || (n <= 0)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + + if (SSL_USE_SIGALGS(s)) { + long hdatalen = 0; + void *hdata; + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } +#ifdef SSL_DEBUG + fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n", + EVP_MD_name(md)); +#endif + if (!EVP_VerifyInit_ex(&mctx, md, NULL) + || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + + if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE); + goto f_err; + } + } else +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA) { + i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i, + pkey->pkey.rsa); + if (i < 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT); + goto f_err; + } + if (i == 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE); + goto f_err; + } + } else +#endif +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) { + j = DSA_verify(pkey->save_type, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa); + if (j <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE); + goto f_err; + } + } else +#endif +#ifndef OPENSSL_NO_ECDSA + if (pkey->type == EVP_PKEY_EC) { + j = ECDSA_verify(pkey->save_type, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec); + if (j <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); + goto f_err; + } + } else +#endif + if (pkey->type == NID_id_GostR3410_94 + || pkey->type == NID_id_GostR3410_2001) { + unsigned char signature[64]; + int idx; + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (pctx == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_MALLOC_FAILURE); + goto f_err; + } + if (EVP_PKEY_verify_init(pctx) <= 0) { + EVP_PKEY_CTX_free(pctx); + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + goto f_err; + } + if (i != 64) { +#ifdef SSL_DEBUG + fprintf(stderr, "GOST signature length is %d", i); +#endif + } + for (idx = 0; idx < 64; idx++) { + signature[63 - idx] = p[idx]; + } + j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md, + 32); + EVP_PKEY_CTX_free(pctx); + if (j <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); + goto f_err; + } + } else { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al = SSL_AD_UNSUPPORTED_CERTIFICATE; + goto f_err; + } + + ret = 1; + if (0) { + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->state = SSL_ST_ERR; + } + end: + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; + } + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_free(pkey); + return (ret); +} + +int ssl3_get_client_certificate(SSL *s) +{ + int i, ok, al, ret = -1; + X509 *x = NULL; + unsigned long l, nc, llen, n; + const unsigned char *p, *q; + unsigned char *d; + STACK_OF(X509) *sk = NULL; + + n = s->method->ssl_get_message(s, + SSL3_ST_SR_CERT_A, + SSL3_ST_SR_CERT_B, + -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { + if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + /* + * If tls asked for a client cert, the client must return a 0 list + */ + if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto f_err; + } + s->s3->tmp.reuse_message = 1; + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE); + goto f_err; + } + p = d = (unsigned char *)s->init_msg; + + if ((sk = sk_X509_new_null()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + + n2l3(p, llen); + if (llen + 3 != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + for (nc = 0; nc < llen;) { + if (nc + 3 > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + + q = p; + x = d2i_X509(NULL, &p, l); + if (x == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB); + goto err; + } + if (p != (q + l)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + if (!sk_X509_push(sk, x)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + x = NULL; + nc += l + 3; + } + + if (sk_X509_num(sk) <= 0) { + /* TLS does not mind 0 certs returned */ + if (s->version == SSL3_VERSION) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_NO_CERTIFICATES_RETURNED); + goto f_err; + } + /* Fail for TLS only if we required a certificate */ + else if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + /* No client certificate so digest cached records */ + if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } else { + i = ssl_verify_cert_chain(s, sk); + if (i <= 0) { + al = ssl_verify_alarm_type(s->verify_result); + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERTIFICATE_VERIFY_FAILED); + goto f_err; + } + } + + if (s->session->peer != NULL) /* This should not be needed */ + X509_free(s->session->peer); + s->session->peer = sk_X509_shift(sk); + s->session->verify_result = s->verify_result; + + /* + * With the current implementation, sess_cert will always be NULL when we + * arrive here. + */ + if (s->session->sess_cert == NULL) { + s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if (s->session->sess_cert->cert_chain != NULL) + sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); + s->session->sess_cert->cert_chain = sk; + /* + * Inconsistency alert: cert_chain does *not* include the peer's own + * certificate, while we do include it in s3_clnt.c + */ + + sk = NULL; + + ret = 1; + if (0) { + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + } + + if (x != NULL) + X509_free(x); + if (sk != NULL) + sk_X509_pop_free(sk, X509_free); + return (ret); +} + +int ssl3_send_server_certificate(SSL *s) +{ + CERT_PKEY *cpk; + + if (s->state == SSL3_ST_SW_CERT_A) { + cpk = ssl_get_server_send_pkey(s); + if (cpk == NULL) { + /* VRS: allow null cert if auth == KRB5 */ + if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) || + (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, + ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return (0); + } + } + + if (!ssl3_output_cert_chain(s, cpk)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return (0); + } + s->state = SSL3_ST_SW_CERT_B; + } + + /* SSL3_ST_SW_CERT_B */ + return ssl_do_write(s); +} + +#ifndef OPENSSL_NO_TLSEXT +/* send a new session ticket (not necessarily for a new session) */ +int ssl3_send_newsession_ticket(SSL *s) +{ + unsigned char *senc = NULL; + EVP_CIPHER_CTX ctx; + HMAC_CTX hctx; + + if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { + unsigned char *p, *macstart; + const unsigned char *const_p; + int len, slen_full, slen; + SSL_SESSION *sess; + unsigned int hlen; + SSL_CTX *tctx = s->initial_ctx; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char key_name[16]; + + /* get session encoding length */ + slen_full = i2d_SSL_SESSION(s->session, NULL); + /* + * Some length values are 16 bits, so forget it if session is too + * long + */ + if (slen_full == 0 || slen_full > 0xFF00) { + s->state = SSL_ST_ERR; + return -1; + } + senc = OPENSSL_malloc(slen_full); + if (!senc) { + s->state = SSL_ST_ERR; + return -1; + } + + EVP_CIPHER_CTX_init(&ctx); + HMAC_CTX_init(&hctx); + + p = senc; + if (!i2d_SSL_SESSION(s->session, &p)) + goto err; + + /* + * create a fresh copy (not shared with other threads) to clean up + */ + const_p = senc; + sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); + if (sess == NULL) + goto err; + sess->session_id_length = 0; /* ID is irrelevant for the ticket */ + + slen = i2d_SSL_SESSION(sess, NULL); + if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ + SSL_SESSION_free(sess); + goto err; + } + p = senc; + if (!i2d_SSL_SESSION(sess, &p)) { + SSL_SESSION_free(sess); + goto err; + } + SSL_SESSION_free(sess); + + /*- + * Grow buffer if need be: the length calculation is as + * follows handshake_header_length + + * 4 (ticket lifetime hint) + 2 (ticket length) + + * 16 (key name) + max_iv_len (iv length) + + * session_length + max_enc_block_size (max encrypted session + * length) + max_md_size (HMAC). + */ + if (!BUF_MEM_grow(s->init_buf, + SSL_HM_HEADER_LENGTH(s) + 22 + EVP_MAX_IV_LENGTH + + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) + goto err; + + p = ssl_handshake_start(s); + /* + * Initialize HMAC and cipher contexts. If callback present it does + * all the work otherwise use generated values from parent ctx. + */ + if (tctx->tlsext_ticket_key_cb) { + /* if 0 is returned, write en empty ticket */ + int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, + &hctx, 1); + + if (ret == 0) { + l2n(0, p); /* timeout */ + s2n(0, p); /* length */ + ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, + p - ssl_handshake_start(s)); + s->state = SSL3_ST_SW_SESSION_TICKET_B; + OPENSSL_free(senc); + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + return ssl_do_write(s); + } + if (ret < 0) + goto err; + } else { + if (RAND_bytes(iv, 16) <= 0) + goto err; + if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, iv)) + goto err; + if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL)) + goto err; + memcpy(key_name, tctx->tlsext_tick_key_name, 16); + } + + /* + * Ticket lifetime hint (advisory only): We leave this unspecified + * for resumed session (for simplicity), and guess that tickets for + * new sessions will live as long as their sessions. + */ + l2n(s->hit ? 0 : s->session->timeout, p); + + /* Skip ticket length for now */ + p += 2; + /* Output key name */ + macstart = p; + memcpy(p, key_name, 16); + p += 16; + /* output IV */ + memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); + p += EVP_CIPHER_CTX_iv_length(&ctx); + /* Encrypt session data */ + if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen)) + goto err; + p += len; + if (!EVP_EncryptFinal(&ctx, p, &len)) + goto err; + p += len; + + if (!HMAC_Update(&hctx, macstart, p - macstart)) + goto err; + if (!HMAC_Final(&hctx, p, &hlen)) + goto err; + + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + + p += hlen; + /* Now write out lengths: p points to end of data written */ + /* Total length */ + len = p - ssl_handshake_start(s); + /* Skip ticket lifetime hint */ + p = ssl_handshake_start(s) + 4; + s2n(len - 6, p); + ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len); + s->state = SSL3_ST_SW_SESSION_TICKET_B; + OPENSSL_free(senc); + } + + /* SSL3_ST_SW_SESSION_TICKET_B */ + return ssl_do_write(s); + err: + if (senc) + OPENSSL_free(senc); + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + s->state = SSL_ST_ERR; + return -1; +} + +int ssl3_send_cert_status(SSL *s) +{ + if (s->state == SSL3_ST_SW_CERT_STATUS_A) { + unsigned char *p; + size_t msglen; + + /*- + * Grow buffer if need be: the length calculation is as + * follows handshake_header_length + + * 1 (ocsp response type) + 3 (ocsp response length) + * + (ocsp response) + */ + msglen = 4 + s->tlsext_ocsp_resplen; + if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + msglen)) { + s->state = SSL_ST_ERR; + return -1; + } + + p = ssl_handshake_start(s); + + /* status type */ + *(p++) = s->tlsext_status_type; + /* length of OCSP response */ + l2n3(s->tlsext_ocsp_resplen, p); + /* actual response */ + memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen); + + ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_STATUS, msglen); + } + + /* SSL3_ST_SW_CERT_STATUS_B */ + return (ssl_do_write(s)); +} + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* + * ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. + * It sets the next_proto member in s if found + */ +int ssl3_get_next_proto(SSL *s) +{ + int ok; + int proto_len, padding_len; + long n; + const unsigned char *p; + + /* + * Clients cannot send a NextProtocol message if we didn't see the + * extension in their ClientHello + */ + if (!s->s3->next_proto_neg_seen) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, + SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); + s->state = SSL_ST_ERR; + return -1; + } + + /* See the payload format below */ + n = s->method->ssl_get_message(s, + SSL3_ST_SR_NEXT_PROTO_A, + SSL3_ST_SR_NEXT_PROTO_B, + SSL3_MT_NEXT_PROTO, 514, &ok); + + if (!ok) + return ((int)n); + + /* + * s->state doesn't reflect whether ChangeCipherSpec has been received in + * this handshake, but s->s3->change_cipher_spec does (will be reset by + * ssl3_get_finished). + */ + if (!s->s3->change_cipher_spec) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); + s->state = SSL_ST_ERR; + return -1; + } + + if (n < 2) { + s->state = SSL_ST_ERR; + return 0; /* The body must be > 1 bytes long */ + } + + p = (unsigned char *)s->init_msg; + + /*- + * The payload looks like: + * uint8 proto_len; + * uint8 proto[proto_len]; + * uint8 padding_len; + * uint8 padding[padding_len]; + */ + proto_len = p[0]; + if (proto_len + 2 > s->init_num) { + s->state = SSL_ST_ERR; + return 0; + } + padding_len = p[proto_len + 1]; + if (proto_len + padding_len + 2 != s->init_num) { + s->state = SSL_ST_ERR; + return 0; + } + + s->next_proto_negotiated = OPENSSL_malloc(proto_len); + if (!s->next_proto_negotiated) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE); + s->state = SSL_ST_ERR; + return 0; + } + memcpy(s->next_proto_negotiated, p + 1, proto_len); + s->next_proto_negotiated_len = proto_len; + + return 1; +} +# endif + +#endif diff --git a/Sources/COpenSSL/safestack.h b/Sources/COpenSSL/safestack.h new file mode 100644 index 00000000..0cd2b495 --- /dev/null +++ b/Sources/COpenSSL/safestack.h @@ -0,0 +1,2672 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SAFESTACK_H +# define HEADER_SAFESTACK_H + +# include "stack.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef CHECKED_PTR_OF +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# endif + +/* + * In C++ we get problems because an explicit cast is needed from (void *) we + * use CHECKED_STACK_OF to ensure the correct type is passed in the macros + * below. + */ + +# define CHECKED_STACK_OF(type, p) \ + ((_STACK*) (1 ? p : (STACK_OF(type)*)0)) + +# define CHECKED_SK_COPY_FUNC(type, p) \ + ((void *(*)(void *)) ((1 ? p : (type *(*)(const type *))0))) + +# define CHECKED_SK_FREE_FUNC(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) + +# define CHECKED_SK_CMP_FUNC(type, p) \ + ((int (*)(const void *, const void *)) \ + ((1 ? p : (int (*)(const type * const *, const type * const *))0))) + +# define STACK_OF(type) struct stack_st_##type +# define PREDECLARE_STACK_OF(type) STACK_OF(type); + +# define DECLARE_STACK_OF(type) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; +# define DECLARE_SPECIAL_STACK_OF(type, type2) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; + +/* nada (obsolete in new safestack approach)*/ +# define IMPLEMENT_STACK_OF(type) + +/*- + * Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * + * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; + +typedef const char *OPENSSL_CSTRING; + +/* + * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned + * above, instead of a single char each entry is a NUL-terminated array of + * chars. So, we have to implement STRING specially for STACK_OF. This is + * dealt with in the autogenerated macros below. + */ + +DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char) + +/* + * Similarly, we sometimes use a block of characters, NOT nul-terminated. + * These should also be distinguished from "normal" stacks. + */ +typedef void *OPENSSL_BLOCK; +DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + +/* + * SKM_sk_... stack macros are internal to safestack.h: never use them + * directly, use sk__... instead + */ +# define SKM_sk_new(type, cmp) \ + ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp))) +# define SKM_sk_new_null(type) \ + ((STACK_OF(type) *)sk_new_null()) +# define SKM_sk_free(type, st) \ + sk_free(CHECKED_STACK_OF(type, st)) +# define SKM_sk_num(type, st) \ + sk_num(CHECKED_STACK_OF(type, st)) +# define SKM_sk_value(type, st,i) \ + ((type *)sk_value(CHECKED_STACK_OF(type, st), i)) +# define SKM_sk_set(type, st,i,val) \ + sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val)) +# define SKM_sk_zero(type, st) \ + sk_zero(CHECKED_STACK_OF(type, st)) +# define SKM_sk_push(type, st, val) \ + sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_unshift(type, st, val) \ + sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_find(type, st, val) \ + sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_find_ex(type, st, val) \ + sk_find_ex(CHECKED_STACK_OF(type, st), \ + CHECKED_PTR_OF(type, val)) +# define SKM_sk_delete(type, st, i) \ + (type *)sk_delete(CHECKED_STACK_OF(type, st), i) +# define SKM_sk_delete_ptr(type, st, ptr) \ + (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr)) +# define SKM_sk_insert(type, st,val, i) \ + sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i) +# define SKM_sk_set_cmp_func(type, st, cmp) \ + ((int (*)(const type * const *,const type * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp))) +# define SKM_sk_dup(type, st) \ + (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st)) +# define SKM_sk_pop_free(type, st, free_func) \ + sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) +# define SKM_sk_deep_copy(type, st, copy_func, free_func) \ + (STACK_OF(type) *)sk_deep_copy(CHECKED_STACK_OF(type, st), CHECKED_SK_COPY_FUNC(type, copy_func), CHECKED_SK_FREE_FUNC(type, free_func)) +# define SKM_sk_shift(type, st) \ + (type *)sk_shift(CHECKED_STACK_OF(type, st)) +# define SKM_sk_pop(type, st) \ + (type *)sk_pop(CHECKED_STACK_OF(type, st)) +# define SKM_sk_sort(type, st) \ + sk_sort(CHECKED_STACK_OF(type, st)) +# define SKM_sk_is_sorted(type, st) \ + sk_is_sorted(CHECKED_STACK_OF(type, st)) +# define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + (STACK_OF(type) *)d2i_ASN1_SET( \ + (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \ + pp, length, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + ex_tag, ex_class) +# define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ + i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \ + CHECKED_I2D_OF(type, i2d_func), \ + ex_tag, ex_class, is_set) +# define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \ + ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \ + CHECKED_I2D_OF(type, i2d_func), buf, len) +# define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \ + (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func)) +# define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \ + (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + pass, passlen, oct, seq) +/* + * This block of defines is updated by util/mkstack.pl, please do not touch! + */ +# define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp)) +# define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) +# define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i)) +# define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val)) +# define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i)) +# define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr)) +# define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i)) +# define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp)) +# define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st) +# define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func)) +# define sk_ACCESS_DESCRIPTION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ACCESS_DESCRIPTION, (st), (copy_func), (free_func)) +# define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) +# define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp)) +# define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) +# define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) +# define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) +# define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i)) +# define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val)) +# define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st)) +# define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i)) +# define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr)) +# define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i)) +# define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp)) +# define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st) +# define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func)) +# define sk_ASIdOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASIdOrRange, (st), (copy_func), (free_func)) +# define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st)) +# define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st)) +# define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) +# define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) +# define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp)) +# define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) +# define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i)) +# define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val)) +# define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i)) +# define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr)) +# define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i)) +# define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp)) +# define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st) +# define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func)) +# define sk_ASN1_GENERALSTRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_GENERALSTRING, (st), (copy_func), (free_func)) +# define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp)) +# define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) +# define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i)) +# define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val)) +# define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i)) +# define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr)) +# define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i)) +# define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp)) +# define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st) +# define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func)) +# define sk_ASN1_INTEGER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_INTEGER, (st), (copy_func), (free_func)) +# define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) +# define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp)) +# define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) +# define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i)) +# define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val)) +# define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i)) +# define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr)) +# define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i)) +# define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp)) +# define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st) +# define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func)) +# define sk_ASN1_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_OBJECT, (st), (copy_func), (free_func)) +# define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) +# define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp)) +# define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) +# define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i)) +# define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val)) +# define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i)) +# define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr)) +# define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i)) +# define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp)) +# define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st) +# define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func)) +# define sk_ASN1_STRING_TABLE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_STRING_TABLE, (st), (copy_func), (free_func)) +# define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp)) +# define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) +# define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i)) +# define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val)) +# define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i)) +# define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr)) +# define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i)) +# define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp)) +# define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st) +# define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func)) +# define sk_ASN1_TYPE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_TYPE, (st), (copy_func), (free_func)) +# define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) +# define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp)) +# define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING) +# define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i)) +# define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val)) +# define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i)) +# define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr)) +# define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i)) +# define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp)) +# define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st) +# define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func)) +# define sk_ASN1_UTF8STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_UTF8STRING, (st), (copy_func), (free_func)) +# define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st)) +# define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp)) +# define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) +# define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i)) +# define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val)) +# define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i)) +# define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr)) +# define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i)) +# define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp)) +# define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st) +# define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func)) +# define sk_ASN1_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_VALUE, (st), (copy_func), (free_func)) +# define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) +# define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp)) +# define sk_BIO_new_null() SKM_sk_new_null(BIO) +# define sk_BIO_free(st) SKM_sk_free(BIO, (st)) +# define sk_BIO_num(st) SKM_sk_num(BIO, (st)) +# define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i)) +# define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val)) +# define sk_BIO_zero(st) SKM_sk_zero(BIO, (st)) +# define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val)) +# define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val)) +# define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val)) +# define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val)) +# define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i)) +# define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr)) +# define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i)) +# define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp)) +# define sk_BIO_dup(st) SKM_sk_dup(BIO, st) +# define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func)) +# define sk_BIO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BIO, (st), (copy_func), (free_func)) +# define sk_BIO_shift(st) SKM_sk_shift(BIO, (st)) +# define sk_BIO_pop(st) SKM_sk_pop(BIO, (st)) +# define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) +# define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) +# define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp)) +# define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY) +# define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i)) +# define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val)) +# define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i)) +# define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr)) +# define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i)) +# define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp)) +# define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st) +# define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func)) +# define sk_BY_DIR_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_ENTRY, (st), (copy_func), (free_func)) +# define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp)) +# define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH) +# define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i)) +# define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val)) +# define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i)) +# define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr)) +# define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i)) +# define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp)) +# define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st) +# define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func)) +# define sk_BY_DIR_HASH_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_HASH, (st), (copy_func), (free_func)) +# define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st)) +# define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp)) +# define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) +# define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i)) +# define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val)) +# define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i)) +# define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr)) +# define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i)) +# define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp)) +# define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st) +# define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func)) +# define sk_CMS_CertificateChoices_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_CertificateChoices, (st), (copy_func), (free_func)) +# define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) +# define sk_CMS_RecipientEncryptedKey_new(cmp) SKM_sk_new(CMS_RecipientEncryptedKey, (cmp)) +# define sk_CMS_RecipientEncryptedKey_new_null() SKM_sk_new_null(CMS_RecipientEncryptedKey) +# define sk_CMS_RecipientEncryptedKey_free(st) SKM_sk_free(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_num(st) SKM_sk_num(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_value(st, i) SKM_sk_value(CMS_RecipientEncryptedKey, (st), (i)) +# define sk_CMS_RecipientEncryptedKey_set(st, i, val) SKM_sk_set(CMS_RecipientEncryptedKey, (st), (i), (val)) +# define sk_CMS_RecipientEncryptedKey_zero(st) SKM_sk_zero(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_push(st, val) SKM_sk_push(CMS_RecipientEncryptedKey, (st), (val)) +# define sk_CMS_RecipientEncryptedKey_unshift(st, val) SKM_sk_unshift(CMS_RecipientEncryptedKey, (st), (val)) +# define sk_CMS_RecipientEncryptedKey_find(st, val) SKM_sk_find(CMS_RecipientEncryptedKey, (st), (val)) +# define sk_CMS_RecipientEncryptedKey_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientEncryptedKey, (st), (val)) +# define sk_CMS_RecipientEncryptedKey_delete(st, i) SKM_sk_delete(CMS_RecipientEncryptedKey, (st), (i)) +# define sk_CMS_RecipientEncryptedKey_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientEncryptedKey, (st), (ptr)) +# define sk_CMS_RecipientEncryptedKey_insert(st, val, i) SKM_sk_insert(CMS_RecipientEncryptedKey, (st), (val), (i)) +# define sk_CMS_RecipientEncryptedKey_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientEncryptedKey, (st), (cmp)) +# define sk_CMS_RecipientEncryptedKey_dup(st) SKM_sk_dup(CMS_RecipientEncryptedKey, st) +# define sk_CMS_RecipientEncryptedKey_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientEncryptedKey, (st), (free_func)) +# define sk_CMS_RecipientEncryptedKey_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientEncryptedKey, (st), (copy_func), (free_func)) +# define sk_CMS_RecipientEncryptedKey_shift(st) SKM_sk_shift(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_pop(st) SKM_sk_pop(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_sort(st) SKM_sk_sort(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientEncryptedKey_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientEncryptedKey, (st)) +# define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp)) +# define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) +# define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i)) +# define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val)) +# define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i)) +# define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr)) +# define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i)) +# define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp)) +# define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st) +# define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func)) +# define sk_CMS_RecipientInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientInfo, (st), (copy_func), (free_func)) +# define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) +# define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp)) +# define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) +# define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i)) +# define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val)) +# define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i)) +# define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr)) +# define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i)) +# define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp)) +# define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st) +# define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func)) +# define sk_CMS_RevocationInfoChoice_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RevocationInfoChoice, (st), (copy_func), (free_func)) +# define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp)) +# define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) +# define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i)) +# define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val)) +# define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i)) +# define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr)) +# define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i)) +# define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp)) +# define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st) +# define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func)) +# define sk_CMS_SignerInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_SignerInfo, (st), (copy_func), (free_func)) +# define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) +# define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp)) +# define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) +# define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i)) +# define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val)) +# define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i)) +# define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr)) +# define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i)) +# define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp)) +# define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st) +# define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func)) +# define sk_CONF_IMODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_IMODULE, (st), (copy_func), (free_func)) +# define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) +# define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp)) +# define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) +# define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) +# define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) +# define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i)) +# define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val)) +# define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st)) +# define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i)) +# define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr)) +# define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i)) +# define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp)) +# define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st) +# define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func)) +# define sk_CONF_MODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_MODULE, (st), (copy_func), (free_func)) +# define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st)) +# define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st)) +# define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) +# define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) +# define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp)) +# define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) +# define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) +# define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) +# define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i)) +# define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val)) +# define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st)) +# define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i)) +# define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr)) +# define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i)) +# define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp)) +# define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st) +# define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func)) +# define sk_CONF_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_VALUE, (st), (copy_func), (free_func)) +# define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st)) +# define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st)) +# define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) +# define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp)) +# define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) +# define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr)) +# define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp)) +# define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st) +# define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func)) +# define sk_CRYPTO_EX_DATA_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_EX_DATA_FUNCS, (st), (copy_func), (free_func)) +# define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp)) +# define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) +# define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i)) +# define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val)) +# define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i)) +# define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr)) +# define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i)) +# define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp)) +# define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st) +# define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func)) +# define sk_CRYPTO_dynlock_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_dynlock, (st), (copy_func), (free_func)) +# define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) +# define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp)) +# define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) +# define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) +# define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) +# define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i)) +# define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val)) +# define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st)) +# define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i)) +# define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr)) +# define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i)) +# define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp)) +# define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st) +# define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func)) +# define sk_DIST_POINT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(DIST_POINT, (st), (copy_func), (free_func)) +# define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st)) +# define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st)) +# define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) +# define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) +# define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp)) +# define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE) +# define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st)) +# define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st)) +# define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i)) +# define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val)) +# define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st)) +# define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val)) +# define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val)) +# define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val)) +# define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val)) +# define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i)) +# define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr)) +# define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i)) +# define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp)) +# define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st) +# define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func)) +# define sk_ENGINE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE, (st), (copy_func), (free_func)) +# define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st)) +# define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st)) +# define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st)) +# define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st)) +# define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp)) +# define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM) +# define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i)) +# define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val)) +# define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i)) +# define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr)) +# define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i)) +# define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp)) +# define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st) +# define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func)) +# define sk_ENGINE_CLEANUP_ITEM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE_CLEANUP_ITEM, (st), (copy_func), (free_func)) +# define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp)) +# define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID) +# define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i)) +# define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val)) +# define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i)) +# define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr)) +# define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i)) +# define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp)) +# define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st) +# define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func)) +# define sk_ESS_CERT_ID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ESS_CERT_ID, (st), (copy_func), (free_func)) +# define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st)) +# define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp)) +# define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD) +# define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st)) +# define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st)) +# define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i)) +# define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val)) +# define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st)) +# define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val)) +# define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val)) +# define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val)) +# define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val)) +# define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i)) +# define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr)) +# define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i)) +# define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp)) +# define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st) +# define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func)) +# define sk_EVP_MD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_MD, (st), (copy_func), (free_func)) +# define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st)) +# define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st)) +# define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st)) +# define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st)) +# define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp)) +# define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL) +# define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i)) +# define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val)) +# define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i)) +# define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr)) +# define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i)) +# define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp)) +# define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st) +# define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func)) +# define sk_EVP_PBE_CTL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PBE_CTL, (st), (copy_func), (free_func)) +# define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp)) +# define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD) +# define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr)) +# define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp)) +# define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st) +# define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func)) +# define sk_EVP_PKEY_ASN1_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_ASN1_METHOD, (st), (copy_func), (free_func)) +# define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp)) +# define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD) +# define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i)) +# define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val)) +# define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i)) +# define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr)) +# define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i)) +# define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp)) +# define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st) +# define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func)) +# define sk_EVP_PKEY_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_METHOD, (st), (copy_func), (free_func)) +# define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st)) +# define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp)) +# define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) +# define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i)) +# define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val)) +# define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i)) +# define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr)) +# define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i)) +# define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp)) +# define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st) +# define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) +# define sk_GENERAL_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAME, (st), (copy_func), (free_func)) +# define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) +# define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp)) +# define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) +# define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i)) +# define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val)) +# define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i)) +# define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr)) +# define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i)) +# define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp)) +# define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st) +# define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func)) +# define sk_GENERAL_NAMES_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAMES, (st), (copy_func), (free_func)) +# define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) +# define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp)) +# define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) +# define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i)) +# define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val)) +# define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i)) +# define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr)) +# define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i)) +# define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp)) +# define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st) +# define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func)) +# define sk_GENERAL_SUBTREE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_SUBTREE, (st), (copy_func), (free_func)) +# define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) +# define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp)) +# define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) +# define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) +# define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) +# define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i)) +# define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val)) +# define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st)) +# define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i)) +# define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr)) +# define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i)) +# define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp)) +# define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st) +# define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func)) +# define sk_IPAddressFamily_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressFamily, (st), (copy_func), (free_func)) +# define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st)) +# define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st)) +# define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) +# define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) +# define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp)) +# define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) +# define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i)) +# define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val)) +# define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i)) +# define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr)) +# define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i)) +# define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp)) +# define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st) +# define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func)) +# define sk_IPAddressOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressOrRange, (st), (copy_func), (free_func)) +# define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) +# define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp)) +# define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY) +# define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i)) +# define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val)) +# define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i)) +# define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr)) +# define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i)) +# define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp)) +# define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st) +# define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func)) +# define sk_KRB5_APREQBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_APREQBODY, (st), (copy_func), (free_func)) +# define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st)) +# define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp)) +# define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA) +# define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i)) +# define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val)) +# define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i)) +# define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr)) +# define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i)) +# define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp)) +# define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st) +# define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func)) +# define sk_KRB5_AUTHDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHDATA, (st), (copy_func), (free_func)) +# define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp)) +# define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY) +# define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i)) +# define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val)) +# define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i)) +# define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr)) +# define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i)) +# define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp)) +# define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st) +# define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func)) +# define sk_KRB5_AUTHENTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHENTBODY, (st), (copy_func), (free_func)) +# define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp)) +# define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM) +# define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i)) +# define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val)) +# define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i)) +# define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr)) +# define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i)) +# define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp)) +# define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st) +# define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func)) +# define sk_KRB5_CHECKSUM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_CHECKSUM, (st), (copy_func), (free_func)) +# define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st)) +# define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp)) +# define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA) +# define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i)) +# define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val)) +# define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i)) +# define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr)) +# define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i)) +# define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp)) +# define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st) +# define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func)) +# define sk_KRB5_ENCDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCDATA, (st), (copy_func), (free_func)) +# define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp)) +# define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY) +# define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i)) +# define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val)) +# define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i)) +# define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr)) +# define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i)) +# define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp)) +# define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st) +# define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func)) +# define sk_KRB5_ENCKEY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCKEY, (st), (copy_func), (free_func)) +# define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st)) +# define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp)) +# define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME) +# define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i)) +# define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val)) +# define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i)) +# define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr)) +# define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i)) +# define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp)) +# define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st) +# define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func)) +# define sk_KRB5_PRINCNAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_PRINCNAME, (st), (copy_func), (free_func)) +# define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st)) +# define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp)) +# define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY) +# define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i)) +# define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val)) +# define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i)) +# define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr)) +# define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i)) +# define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp)) +# define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st) +# define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func)) +# define sk_KRB5_TKTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_TKTBODY, (st), (copy_func), (free_func)) +# define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st)) +# define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp)) +# define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA) +# define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i)) +# define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val)) +# define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i)) +# define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr)) +# define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i)) +# define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp)) +# define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st) +# define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func)) +# define sk_MEM_OBJECT_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MEM_OBJECT_DATA, (st), (copy_func), (free_func)) +# define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st)) +# define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp)) +# define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) +# define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) +# define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) +# define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i)) +# define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val)) +# define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st)) +# define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i)) +# define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr)) +# define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i)) +# define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp)) +# define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st) +# define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func)) +# define sk_MIME_HEADER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_HEADER, (st), (copy_func), (free_func)) +# define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st)) +# define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st)) +# define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) +# define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) +# define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp)) +# define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) +# define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) +# define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) +# define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i)) +# define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val)) +# define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st)) +# define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i)) +# define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr)) +# define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i)) +# define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp)) +# define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st) +# define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func)) +# define sk_MIME_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_PARAM, (st), (copy_func), (free_func)) +# define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st)) +# define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st)) +# define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) +# define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) +# define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp)) +# define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) +# define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i)) +# define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val)) +# define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i)) +# define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr)) +# define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i)) +# define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp)) +# define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st) +# define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func)) +# define sk_NAME_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(NAME_FUNCS, (st), (copy_func), (free_func)) +# define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) +# define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp)) +# define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) +# define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i)) +# define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val)) +# define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i)) +# define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr)) +# define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i)) +# define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp)) +# define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st) +# define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func)) +# define sk_OCSP_CERTID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_CERTID, (st), (copy_func), (free_func)) +# define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) +# define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp)) +# define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) +# define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i)) +# define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val)) +# define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i)) +# define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr)) +# define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i)) +# define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp)) +# define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st) +# define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func)) +# define sk_OCSP_ONEREQ_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_ONEREQ, (st), (copy_func), (free_func)) +# define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) +# define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp)) +# define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) +# define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i)) +# define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val)) +# define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i)) +# define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr)) +# define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i)) +# define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp)) +# define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st) +# define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func)) +# define sk_OCSP_RESPID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_RESPID, (st), (copy_func), (free_func)) +# define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) +# define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp)) +# define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) +# define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i)) +# define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val)) +# define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i)) +# define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr)) +# define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i)) +# define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp)) +# define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st) +# define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func)) +# define sk_OCSP_SINGLERESP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_SINGLERESP, (st), (copy_func), (free_func)) +# define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) +# define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp)) +# define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) +# define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i)) +# define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val)) +# define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i)) +# define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr)) +# define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i)) +# define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp)) +# define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st) +# define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func)) +# define sk_PKCS12_SAFEBAG_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS12_SAFEBAG, (st), (copy_func), (free_func)) +# define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) +# define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp)) +# define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) +# define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) +# define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) +# define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i)) +# define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val)) +# define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st)) +# define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val)) +# define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val)) +# define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val)) +# define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val)) +# define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i)) +# define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr)) +# define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i)) +# define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp)) +# define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st) +# define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func)) +# define sk_PKCS7_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7, (st), (copy_func), (free_func)) +# define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st)) +# define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st)) +# define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) +# define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) +# define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp)) +# define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) +# define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i)) +# define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val)) +# define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i)) +# define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr)) +# define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i)) +# define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp)) +# define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st) +# define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func)) +# define sk_PKCS7_RECIP_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_RECIP_INFO, (st), (copy_func), (free_func)) +# define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp)) +# define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) +# define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i)) +# define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val)) +# define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i)) +# define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr)) +# define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i)) +# define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp)) +# define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st) +# define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func)) +# define sk_PKCS7_SIGNER_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_SIGNER_INFO, (st), (copy_func), (free_func)) +# define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) +# define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp)) +# define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) +# define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) +# define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) +# define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i)) +# define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val)) +# define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st)) +# define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i)) +# define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr)) +# define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i)) +# define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp)) +# define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st) +# define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func)) +# define sk_POLICYINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYINFO, (st), (copy_func), (free_func)) +# define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st)) +# define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st)) +# define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) +# define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) +# define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp)) +# define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) +# define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i)) +# define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val)) +# define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i)) +# define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr)) +# define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i)) +# define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp)) +# define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st) +# define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func)) +# define sk_POLICYQUALINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYQUALINFO, (st), (copy_func), (free_func)) +# define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) +# define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp)) +# define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) +# define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i)) +# define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val)) +# define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i)) +# define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr)) +# define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i)) +# define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp)) +# define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st) +# define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func)) +# define sk_POLICY_MAPPING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICY_MAPPING, (st), (copy_func), (free_func)) +# define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) +# define sk_SCT_new(cmp) SKM_sk_new(SCT, (cmp)) +# define sk_SCT_new_null() SKM_sk_new_null(SCT) +# define sk_SCT_free(st) SKM_sk_free(SCT, (st)) +# define sk_SCT_num(st) SKM_sk_num(SCT, (st)) +# define sk_SCT_value(st, i) SKM_sk_value(SCT, (st), (i)) +# define sk_SCT_set(st, i, val) SKM_sk_set(SCT, (st), (i), (val)) +# define sk_SCT_zero(st) SKM_sk_zero(SCT, (st)) +# define sk_SCT_push(st, val) SKM_sk_push(SCT, (st), (val)) +# define sk_SCT_unshift(st, val) SKM_sk_unshift(SCT, (st), (val)) +# define sk_SCT_find(st, val) SKM_sk_find(SCT, (st), (val)) +# define sk_SCT_find_ex(st, val) SKM_sk_find_ex(SCT, (st), (val)) +# define sk_SCT_delete(st, i) SKM_sk_delete(SCT, (st), (i)) +# define sk_SCT_delete_ptr(st, ptr) SKM_sk_delete_ptr(SCT, (st), (ptr)) +# define sk_SCT_insert(st, val, i) SKM_sk_insert(SCT, (st), (val), (i)) +# define sk_SCT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SCT, (st), (cmp)) +# define sk_SCT_dup(st) SKM_sk_dup(SCT, st) +# define sk_SCT_pop_free(st, free_func) SKM_sk_pop_free(SCT, (st), (free_func)) +# define sk_SCT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SCT, (st), (copy_func), (free_func)) +# define sk_SCT_shift(st) SKM_sk_shift(SCT, (st)) +# define sk_SCT_pop(st) SKM_sk_pop(SCT, (st)) +# define sk_SCT_sort(st) SKM_sk_sort(SCT, (st)) +# define sk_SCT_is_sorted(st) SKM_sk_is_sorted(SCT, (st)) +# define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp)) +# define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN) +# define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st)) +# define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st)) +# define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i)) +# define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val)) +# define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st)) +# define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val)) +# define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val)) +# define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val)) +# define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val)) +# define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i)) +# define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr)) +# define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i)) +# define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp)) +# define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st) +# define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func)) +# define sk_SRP_gN_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN, (st), (copy_func), (free_func)) +# define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st)) +# define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st)) +# define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st)) +# define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st)) +# define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp)) +# define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache) +# define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i)) +# define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val)) +# define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i)) +# define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr)) +# define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i)) +# define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp)) +# define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st) +# define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func)) +# define sk_SRP_gN_cache_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN_cache, (st), (copy_func), (free_func)) +# define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st)) +# define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp)) +# define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd) +# define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i)) +# define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val)) +# define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i)) +# define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr)) +# define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i)) +# define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp)) +# define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st) +# define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func)) +# define sk_SRP_user_pwd_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_user_pwd, (st), (copy_func), (free_func)) +# define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st)) +# define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp)) +# define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE) +# define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i)) +# define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val)) +# define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i)) +# define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr)) +# define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i)) +# define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp)) +# define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st) +# define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func)) +# define sk_SRTP_PROTECTION_PROFILE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRTP_PROTECTION_PROFILE, (st), (copy_func), (free_func)) +# define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) +# define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) +# define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i)) +# define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val)) +# define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i)) +# define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr)) +# define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i)) +# define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp)) +# define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st) +# define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func)) +# define sk_SSL_CIPHER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_CIPHER, (st), (copy_func), (free_func)) +# define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) +# define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp)) +# define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) +# define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) +# define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) +# define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i)) +# define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val)) +# define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st)) +# define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i)) +# define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr)) +# define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i)) +# define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp)) +# define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st) +# define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func)) +# define sk_SSL_COMP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_COMP, (st), (copy_func), (free_func)) +# define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st)) +# define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st)) +# define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) +# define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp)) +# define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY) +# define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr)) +# define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp)) +# define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st) +# define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func)) +# define sk_STACK_OF_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STACK_OF_X509_NAME_ENTRY, (st), (copy_func), (free_func)) +# define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp)) +# define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO) +# define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i)) +# define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val)) +# define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i)) +# define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr)) +# define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i)) +# define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp)) +# define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st) +# define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func)) +# define sk_STORE_ATTR_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_ATTR_INFO, (st), (copy_func), (free_func)) +# define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st)) +# define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp)) +# define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) +# define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i)) +# define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val)) +# define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i)) +# define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr)) +# define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i)) +# define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp)) +# define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st) +# define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func)) +# define sk_STORE_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_OBJECT, (st), (copy_func), (free_func)) +# define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) +# define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp)) +# define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID) +# define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st)) +# define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st)) +# define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i)) +# define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val)) +# define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st)) +# define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val)) +# define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val)) +# define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val)) +# define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val)) +# define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i)) +# define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr)) +# define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i)) +# define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp)) +# define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st) +# define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func)) +# define sk_SXNETID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SXNETID, (st), (copy_func), (free_func)) +# define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st)) +# define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st)) +# define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st)) +# define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st)) +# define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp)) +# define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) +# define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) +# define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) +# define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i)) +# define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val)) +# define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st)) +# define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val)) +# define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val)) +# define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val)) +# define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val)) +# define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i)) +# define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr)) +# define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i)) +# define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp)) +# define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st) +# define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func)) +# define sk_UI_STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(UI_STRING, (st), (copy_func), (free_func)) +# define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st)) +# define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st)) +# define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) +# define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) +# define sk_X509_new(cmp) SKM_sk_new(X509, (cmp)) +# define sk_X509_new_null() SKM_sk_new_null(X509) +# define sk_X509_free(st) SKM_sk_free(X509, (st)) +# define sk_X509_num(st) SKM_sk_num(X509, (st)) +# define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i)) +# define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val)) +# define sk_X509_zero(st) SKM_sk_zero(X509, (st)) +# define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val)) +# define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val)) +# define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val)) +# define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val)) +# define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i)) +# define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr)) +# define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i)) +# define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp)) +# define sk_X509_dup(st) SKM_sk_dup(X509, st) +# define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func)) +# define sk_X509_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509, (st), (copy_func), (free_func)) +# define sk_X509_shift(st) SKM_sk_shift(X509, (st)) +# define sk_X509_pop(st) SKM_sk_pop(X509, (st)) +# define sk_X509_sort(st) SKM_sk_sort(X509, (st)) +# define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) +# define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp)) +# define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) +# define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i)) +# define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val)) +# define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i)) +# define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr)) +# define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i)) +# define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp)) +# define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st) +# define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func)) +# define sk_X509V3_EXT_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509V3_EXT_METHOD, (st), (copy_func), (free_func)) +# define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) +# define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp)) +# define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) +# define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) +# define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) +# define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i)) +# define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val)) +# define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st)) +# define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i)) +# define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr)) +# define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i)) +# define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp)) +# define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st) +# define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func)) +# define sk_X509_ALGOR_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ALGOR, (st), (copy_func), (free_func)) +# define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st)) +# define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st)) +# define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) +# define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) +# define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp)) +# define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) +# define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i)) +# define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val)) +# define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i)) +# define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr)) +# define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i)) +# define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp)) +# define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st) +# define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func)) +# define sk_X509_ATTRIBUTE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ATTRIBUTE, (st), (copy_func), (free_func)) +# define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) +# define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp)) +# define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) +# define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) +# define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) +# define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i)) +# define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val)) +# define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st)) +# define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val)) +# define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val)) +# define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val)) +# define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val)) +# define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i)) +# define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr)) +# define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i)) +# define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp)) +# define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st) +# define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func)) +# define sk_X509_CRL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_CRL, (st), (copy_func), (free_func)) +# define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st)) +# define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st)) +# define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) +# define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) +# define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp)) +# define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) +# define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i)) +# define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val)) +# define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i)) +# define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr)) +# define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i)) +# define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp)) +# define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st) +# define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func)) +# define sk_X509_EXTENSION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_EXTENSION, (st), (copy_func), (free_func)) +# define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) +# define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp)) +# define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) +# define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) +# define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) +# define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i)) +# define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val)) +# define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st)) +# define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val)) +# define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val)) +# define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val)) +# define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val)) +# define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i)) +# define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr)) +# define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i)) +# define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp)) +# define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st) +# define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func)) +# define sk_X509_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_INFO, (st), (copy_func), (free_func)) +# define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st)) +# define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st)) +# define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) +# define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) +# define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp)) +# define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) +# define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i)) +# define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val)) +# define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i)) +# define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr)) +# define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i)) +# define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp)) +# define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st) +# define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func)) +# define sk_X509_LOOKUP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_LOOKUP, (st), (copy_func), (free_func)) +# define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) +# define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp)) +# define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) +# define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) +# define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) +# define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i)) +# define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val)) +# define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st)) +# define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val)) +# define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val)) +# define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val)) +# define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val)) +# define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i)) +# define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr)) +# define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i)) +# define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp)) +# define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st) +# define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func)) +# define sk_X509_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME, (st), (copy_func), (free_func)) +# define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st)) +# define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st)) +# define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) +# define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) +# define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp)) +# define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) +# define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i)) +# define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val)) +# define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i)) +# define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr)) +# define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i)) +# define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp)) +# define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st) +# define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func)) +# define sk_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME_ENTRY, (st), (copy_func), (free_func)) +# define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) +# define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp)) +# define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) +# define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) +# define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) +# define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i)) +# define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val)) +# define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st)) +# define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i)) +# define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr)) +# define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i)) +# define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp)) +# define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st) +# define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func)) +# define sk_X509_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_OBJECT, (st), (copy_func), (free_func)) +# define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st)) +# define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st)) +# define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) +# define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) +# define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp)) +# define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA) +# define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i)) +# define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val)) +# define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i)) +# define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr)) +# define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i)) +# define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp)) +# define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st) +# define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func)) +# define sk_X509_POLICY_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_DATA, (st), (copy_func), (free_func)) +# define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) +# define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) +# define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i)) +# define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val)) +# define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i)) +# define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr)) +# define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i)) +# define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp)) +# define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st) +# define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func)) +# define sk_X509_POLICY_NODE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_NODE, (st), (copy_func), (free_func)) +# define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) +# define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp)) +# define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) +# define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i)) +# define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val)) +# define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i)) +# define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr)) +# define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i)) +# define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp)) +# define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st) +# define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func)) +# define sk_X509_PURPOSE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_PURPOSE, (st), (copy_func), (free_func)) +# define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) +# define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp)) +# define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) +# define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) +# define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) +# define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i)) +# define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val)) +# define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st)) +# define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i)) +# define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr)) +# define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i)) +# define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp)) +# define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st) +# define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func)) +# define sk_X509_REVOKED_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_REVOKED, (st), (copy_func), (free_func)) +# define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st)) +# define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st)) +# define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) +# define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) +# define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp)) +# define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) +# define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) +# define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) +# define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i)) +# define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val)) +# define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st)) +# define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i)) +# define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr)) +# define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i)) +# define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp)) +# define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st) +# define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func)) +# define sk_X509_TRUST_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_TRUST, (st), (copy_func), (free_func)) +# define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st)) +# define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st)) +# define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) +# define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) +# define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp)) +# define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) +# define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i)) +# define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val)) +# define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i)) +# define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr)) +# define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i)) +# define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp)) +# define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st) +# define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func)) +# define sk_X509_VERIFY_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_VERIFY_PARAM, (st), (copy_func), (free_func)) +# define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) +# define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp)) +# define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple) +# define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st)) +# define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st)) +# define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i)) +# define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val)) +# define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st)) +# define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val)) +# define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val)) +# define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val)) +# define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val)) +# define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i)) +# define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr)) +# define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i)) +# define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp)) +# define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st) +# define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func)) +# define sk_nid_triple_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(nid_triple, (st), (copy_func), (free_func)) +# define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st)) +# define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st)) +# define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st)) +# define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st)) +# define sk_void_new(cmp) SKM_sk_new(void, (cmp)) +# define sk_void_new_null() SKM_sk_new_null(void) +# define sk_void_free(st) SKM_sk_free(void, (st)) +# define sk_void_num(st) SKM_sk_num(void, (st)) +# define sk_void_value(st, i) SKM_sk_value(void, (st), (i)) +# define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val)) +# define sk_void_zero(st) SKM_sk_zero(void, (st)) +# define sk_void_push(st, val) SKM_sk_push(void, (st), (val)) +# define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val)) +# define sk_void_find(st, val) SKM_sk_find(void, (st), (val)) +# define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val)) +# define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i)) +# define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr)) +# define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i)) +# define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp)) +# define sk_void_dup(st) SKM_sk_dup(void, st) +# define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func)) +# define sk_void_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(void, (st), (copy_func), (free_func)) +# define sk_void_shift(st) SKM_sk_shift(void, (st)) +# define sk_void_pop(st) SKM_sk_pop(void, (st)) +# define sk_void_sort(st) SKM_sk_sort(void, (st)) +# define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st)) +# define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp))) +# define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null()) +# define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i)) +# define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC(char, free_func)) +# define sk_OPENSSL_STRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_STRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_COPY_FUNC(char, copy_func), CHECKED_SK_FREE_FUNC(char, free_func))) +# define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i) +# define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i)) +# define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr)) +# define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \ + ((int (*)(const char * const *,const char * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp))) +# define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st)) +# define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st)) +# define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp))) +# define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null()) +# define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i)) +# define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC(void, free_func)) +# define sk_OPENSSL_BLOCK_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_BLOCK) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_COPY_FUNC(void, copy_func), CHECKED_SK_FREE_FUNC(void, free_func))) +# define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i) +# define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i)) +# define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr)) +# define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \ + ((int (*)(const void * const *,const void * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp))) +# define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st)) +# define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +# define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null()) +# define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i)) +# define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func)) +# define sk_OPENSSL_PSTRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_PSTRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_COPY_FUNC(OPENSSL_STRING, copy_func), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func))) +# define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i) +# define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i)) +# define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr)) +# define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \ + ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +# define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st)) +# define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st)) +# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func)) +# define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) +# define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) +# define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj) +# define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn) +# define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg) +# define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_stats_bio(lh,out) \ + LHM_lh_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh) +# define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info) +# define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst) +# define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst) +# define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst) +# define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn) +# define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg) +# define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh) +# define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh) +# define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh) +# define lh_APP_INFO_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_stats_bio(lh,out) \ + LHM_lh_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh) +# define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value) +# define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn) +# define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg) +# define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh) +# define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh) +# define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh) +# define lh_CONF_VALUE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_stats_bio(lh,out) \ + LHM_lh_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh) +# define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile) +# define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn) +# define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg) +# define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh) +# define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state) +# define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst) +# define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst) +# define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst) +# define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn) +# define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg) +# define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh) +# define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh) +# define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh) +# define lh_ERR_STATE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh) +# define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data) +# define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn) +# define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg) +# define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh) +# define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item) +# define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn) +# define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg) +# define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh) +# define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function) +# define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst) +# define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst) +# define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst) +# define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn) +# define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg) +# define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh) +# define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh) +# define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh) +# define lh_FUNCTION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_stats_bio(lh,out) \ + LHM_lh_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh) +# define lh_MEM_new() LHM_lh_new(MEM,mem) +# define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst) +# define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst) +# define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst) +# define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn) +# define lh_MEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg) +# define lh_MEM_error(lh) LHM_lh_error(MEM,lh) +# define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh) +# define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh) +# define lh_MEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(MEM,lh,out) +# define lh_MEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(MEM,lh,out) +# define lh_MEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(MEM,lh,out) +# define lh_MEM_free(lh) LHM_lh_free(MEM,lh) +# define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name) +# define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn) +# define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg) +# define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh) +# define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh) +# define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh) +# define lh_OBJ_NAME_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_stats_bio(lh,out) \ + LHM_lh_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh) +# define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring) +# define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn) +# define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg) +# define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string) +# define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn) +# define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg) +# define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh) +# define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session) +# define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn) +# define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg) +# define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh) +# define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh) +# define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh) +# define lh_SSL_SESSION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_stats_bio(lh,out) \ + LHM_lh_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh) +#ifdef __cplusplus +} +#endif +#endif /* !defined HEADER_SAFESTACK_H */ diff --git a/Sources/COpenSSL/seed.c b/Sources/COpenSSL/seed.c new file mode 100644 index 00000000..79d2f6f1 --- /dev/null +++ b/Sources/COpenSSL/seed.c @@ -0,0 +1,711 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#ifndef OPENSSL_NO_SEED + +# include +# include +# include +# ifdef WIN32 +# include +# endif + +# include "crypto.h" +# include "seed.h" +# include "seed_locl.h" + +# ifdef SS /* can get defined on Solaris by inclusion of + * */ +# undef SS +# endif + +static const seed_word SS[4][256] = { { + 0x2989a1a8, 0x05858184, 0x16c6d2d4, + 0x13c3d3d0, 0x14445054, 0x1d0d111c, + 0x2c8ca0ac, 0x25052124, + 0x1d4d515c, 0x03434340, 0x18081018, + 0x1e0e121c, 0x11415150, 0x3cccf0fc, + 0x0acac2c8, 0x23436360, + 0x28082028, 0x04444044, 0x20002020, + 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, + 0x08c8c0c8, 0x17071314, + 0x2585a1a4, 0x0f8f838c, 0x03030300, + 0x3b4b7378, 0x3b8bb3b8, 0x13031310, + 0x12c2d2d0, 0x2ecee2ec, + 0x30407070, 0x0c8c808c, 0x3f0f333c, + 0x2888a0a8, 0x32023230, 0x1dcdd1dc, + 0x36c6f2f4, 0x34447074, + 0x2ccce0ec, 0x15859194, 0x0b0b0308, + 0x17475354, 0x1c4c505c, 0x1b4b5358, + 0x3d8db1bc, 0x01010100, + 0x24042024, 0x1c0c101c, 0x33437370, + 0x18889098, 0x10001010, 0x0cccc0cc, + 0x32c2f2f0, 0x19c9d1d8, + 0x2c0c202c, 0x27c7e3e4, 0x32427270, + 0x03838380, 0x1b8b9398, 0x11c1d1d0, + 0x06868284, 0x09c9c1c8, + 0x20406060, 0x10405050, 0x2383a3a0, + 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, + 0x1e8e929c, 0x0f4f434c, + 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, + 0x38487078, 0x2686a2a4, 0x12021210, + 0x2f8fa3ac, 0x15c5d1d4, + 0x21416160, 0x03c3c3c0, 0x3484b0b4, + 0x01414140, 0x12425250, 0x3d4d717c, + 0x0d8d818c, 0x08080008, + 0x1f0f131c, 0x19899198, 0x00000000, + 0x19091118, 0x04040004, 0x13435350, + 0x37c7f3f4, 0x21c1e1e0, + 0x3dcdf1fc, 0x36467274, 0x2f0f232c, + 0x27072324, 0x3080b0b0, 0x0b8b8388, + 0x0e0e020c, 0x2b8ba3a8, + 0x2282a2a0, 0x2e4e626c, 0x13839390, + 0x0d4d414c, 0x29496168, 0x3c4c707c, + 0x09090108, 0x0a0a0208, + 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, + 0x05c5c1c4, 0x07878384, 0x14041014, + 0x3ecef2fc, 0x24446064, + 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, + 0x1a0a1218, 0x06060204, 0x21012120, + 0x2b4b6368, 0x26466264, + 0x02020200, 0x35c5f1f4, 0x12829290, + 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, + 0x3e4e727c, 0x10c0d0d0, + 0x3a4a7278, 0x07474344, 0x16869294, + 0x25c5e1e4, 0x26062224, 0x00808080, + 0x2d8da1ac, 0x1fcfd3dc, + 0x2181a1a0, 0x30003030, 0x37073334, + 0x2e8ea2ac, 0x36063234, 0x15051114, + 0x22022220, 0x38083038, + 0x34c4f0f4, 0x2787a3a4, 0x05454144, + 0x0c4c404c, 0x01818180, 0x29c9e1e8, + 0x04848084, 0x17879394, + 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, + 0x3c0c303c, 0x31417170, 0x11011110, + 0x07c7c3c4, 0x09898188, + 0x35457174, 0x3bcbf3f8, 0x1acad2d8, + 0x38c8f0f8, 0x14849094, 0x19495158, + 0x02828280, 0x04c4c0c4, + 0x3fcff3fc, 0x09494148, 0x39093138, + 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, + 0x17c7d3d4, 0x3888b0b8, + 0x0f0f030c, 0x0e8e828c, 0x02424240, + 0x23032320, 0x11819190, 0x2c4c606c, + 0x1bcbd3d8, 0x2484a0a4, + 0x34043034, 0x31c1f1f0, 0x08484048, + 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, + 0x2d0d212c, 0x00404040, + 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, + 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, + 0x0e4e424c, 0x15455154, + 0x3b0b3338, 0x1cccd0dc, 0x28486068, + 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, + 0x0a4a4248, 0x16465254, + 0x37477374, 0x2080a0a0, 0x2dcde1ec, + 0x06464244, 0x3585b1b4, 0x2b0b2328, + 0x25456164, 0x3acaf2f8, + 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, + 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, + 0x26c6e2e4, 0x3282b2b0, + 0x31013130, 0x2acae2e8, 0x2d4d616c, + 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, + 0x0dcdc1cc, 0x08888088, + 0x16061214, 0x3a0a3238, 0x18485058, + 0x14c4d0d4, 0x22426260, 0x29092128, + 0x07070304, 0x33033330, + 0x28c8e0e8, 0x1b0b1318, 0x05050104, + 0x39497178, 0x10809090, 0x2a4a6268, + 0x2a0a2228, 0x1a8a9298}, { + 0x38380830, + 0xe828c8e0, + 0x2c2d0d21, + 0xa42686a2, + 0xcc0fcfc3, + 0xdc1eced2, + 0xb03383b3, + 0xb83888b0, + 0xac2f8fa3, + 0x60204060, + 0x54154551, + 0xc407c7c3, + 0x44044440, + 0x6c2f4f63, + 0x682b4b63, + 0x581b4b53, + 0xc003c3c3, + 0x60224262, + 0x30330333, + 0xb43585b1, + 0x28290921, + 0xa02080a0, + 0xe022c2e2, + 0xa42787a3, + 0xd013c3d3, + 0x90118191, + 0x10110111, + 0x04060602, + 0x1c1c0c10, + 0xbc3c8cb0, + 0x34360632, + 0x480b4b43, + 0xec2fcfe3, + 0x88088880, + 0x6c2c4c60, + 0xa82888a0, + 0x14170713, + 0xc404c4c0, + 0x14160612, + 0xf434c4f0, + 0xc002c2c2, + 0x44054541, + 0xe021c1e1, + 0xd416c6d2, + 0x3c3f0f33, + 0x3c3d0d31, + 0x8c0e8e82, + 0x98188890, + 0x28280820, + 0x4c0e4e42, + 0xf436c6f2, + 0x3c3e0e32, + 0xa42585a1, + 0xf839c9f1, + 0x0c0d0d01, + 0xdc1fcfd3, + 0xd818c8d0, + 0x282b0b23, + 0x64264662, + 0x783a4a72, + 0x24270723, + 0x2c2f0f23, + 0xf031c1f1, + 0x70324272, + 0x40024242, + 0xd414c4d0, + 0x40014141, + 0xc000c0c0, + 0x70334373, + 0x64274763, + 0xac2c8ca0, + 0x880b8b83, + 0xf437c7f3, + 0xac2d8da1, + 0x80008080, + 0x1c1f0f13, + 0xc80acac2, + 0x2c2c0c20, + 0xa82a8aa2, + 0x34340430, + 0xd012c2d2, + 0x080b0b03, + 0xec2ecee2, + 0xe829c9e1, + 0x5c1d4d51, + 0x94148490, + 0x18180810, + 0xf838c8f0, + 0x54174753, + 0xac2e8ea2, + 0x08080800, + 0xc405c5c1, + 0x10130313, + 0xcc0dcdc1, + 0x84068682, + 0xb83989b1, + 0xfc3fcff3, + 0x7c3d4d71, + 0xc001c1c1, + 0x30310131, + 0xf435c5f1, + 0x880a8a82, + 0x682a4a62, + 0xb03181b1, + 0xd011c1d1, + 0x20200020, + 0xd417c7d3, + 0x00020202, + 0x20220222, + 0x04040400, + 0x68284860, + 0x70314171, + 0x04070703, + 0xd81bcbd3, + 0x9c1d8d91, + 0x98198991, + 0x60214161, + 0xbc3e8eb2, + 0xe426c6e2, + 0x58194951, + 0xdc1dcdd1, + 0x50114151, + 0x90108090, + 0xdc1cccd0, + 0x981a8a92, + 0xa02383a3, + 0xa82b8ba3, + 0xd010c0d0, + 0x80018181, + 0x0c0f0f03, + 0x44074743, + 0x181a0a12, + 0xe023c3e3, + 0xec2ccce0, + 0x8c0d8d81, + 0xbc3f8fb3, + 0x94168692, + 0x783b4b73, + 0x5c1c4c50, + 0xa02282a2, + 0xa02181a1, + 0x60234363, + 0x20230323, + 0x4c0d4d41, + 0xc808c8c0, + 0x9c1e8e92, + 0x9c1c8c90, + 0x383a0a32, + 0x0c0c0c00, + 0x2c2e0e22, + 0xb83a8ab2, + 0x6c2e4e62, + 0x9c1f8f93, + 0x581a4a52, + 0xf032c2f2, + 0x90128292, + 0xf033c3f3, + 0x48094941, + 0x78384870, + 0xcc0cccc0, + 0x14150511, + 0xf83bcbf3, + 0x70304070, + 0x74354571, + 0x7c3f4f73, + 0x34350531, + 0x10100010, + 0x00030303, + 0x64244460, + 0x6c2d4d61, + 0xc406c6c2, + 0x74344470, + 0xd415c5d1, + 0xb43484b0, + 0xe82acae2, + 0x08090901, + 0x74364672, + 0x18190911, + 0xfc3ecef2, + 0x40004040, + 0x10120212, + 0xe020c0e0, + 0xbc3d8db1, + 0x04050501, + 0xf83acaf2, + 0x00010101, + 0xf030c0f0, + 0x282a0a22, + 0x5c1e4e52, + 0xa82989a1, + 0x54164652, + 0x40034343, + 0x84058581, + 0x14140410, + 0x88098981, + 0x981b8b93, + 0xb03080b0, + 0xe425c5e1, + 0x48084840, + 0x78394971, + 0x94178793, + 0xfc3cccf0, + 0x1c1e0e12, + 0x80028282, + 0x20210121, + 0x8c0c8c80, + 0x181b0b13, + 0x5c1f4f53, + 0x74374773, + 0x54144450, + 0xb03282b2, + 0x1c1d0d11, + 0x24250521, + 0x4c0f4f43, + 0x00000000, + 0x44064642, + 0xec2dcde1, + 0x58184850, + 0x50124252, + 0xe82bcbe3, + 0x7c3e4e72, + 0xd81acad2, + 0xc809c9c1, + 0xfc3dcdf1, + 0x30300030, + 0x94158591, + 0x64254561, + 0x3c3c0c30, + 0xb43686b2, + 0xe424c4e0, + 0xb83b8bb3, + 0x7c3c4c70, + 0x0c0e0e02, + 0x50104050, + 0x38390931, + 0x24260622, + 0x30320232, + 0x84048480, + 0x68294961, + 0x90138393, + 0x34370733, + 0xe427c7e3, + 0x24240420, + 0xa42484a0, + 0xc80bcbc3, + 0x50134353, + 0x080a0a02, + 0x84078783, + 0xd819c9d1, + 0x4c0c4c40, + 0x80038383, + 0x8c0f8f83, + 0xcc0ecec2, + 0x383b0b33, + 0x480a4a42, + 0xb43787b3}, +{ + 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, + 0xa0ac2c8c, 0x21242505, + 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, + 0xc2c80aca, 0x63602343, + 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, + 0xc0c808c8, 0x13141707, + 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, + 0xd2d012c2, 0xe2ec2ece, + 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, + 0xf2f436c6, 0x70743444, + 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, + 0xb1bc3d8d, 0x01000101, + 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, + 0xf2f032c2, 0xd1d819c9, + 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, + 0x82840686, 0xc1c809c9, + 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, + 0x929c1e8e, 0x434c0f4f, + 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, + 0xa3ac2f8f, 0xd1d415c5, + 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, + 0x818c0d8d, 0x00080808, + 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, + 0xf3f437c7, 0xe1e021c1, + 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, + 0x020c0e0e, 0xa3a82b8b, + 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, + 0x01080909, 0x02080a0a, + 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, + 0xf2fc3ece, 0x60642444, + 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, + 0x63682b4b, 0x62642646, + 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, + 0x727c3e4e, 0xd0d010c0, + 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, + 0xa1ac2d8d, 0xd3dc1fcf, + 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, + 0x22202202, 0x30383808, + 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, + 0x80840484, 0x93941787, + 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, + 0xc3c407c7, 0x81880989, + 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, + 0x82800282, 0xc0c404c4, + 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, + 0xd3d417c7, 0xb0b83888, + 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, + 0xd3d81bcb, 0xa0a42484, + 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, + 0x212c2d0d, 0x40400040, + 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, + 0x424c0e4e, 0x51541545, + 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, + 0x42480a4a, 0x52541646, + 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, + 0x61642545, 0xf2f83aca, + 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, + 0xe2e426c6, 0xb2b03282, + 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, + 0xc1cc0dcd, 0x80880888, + 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, + 0x03040707, 0x33303303, + 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, + 0x22282a0a, 0x92981a8a}, { + 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, + 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, + 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, + 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, + 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, + 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, + 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, + 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, + 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, + 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, + 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, + 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, + 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, + 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, + 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, + 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, + 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, + 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, + 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, + 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, + 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, + 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, + 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, + 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, + 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, + 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, + 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, + 0x02222022, 0x04000404, 0x48606828, 0x41717031, + 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, + 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, + 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, + 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, + 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, + 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, + 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, + 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, + 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, + 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, + 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, + 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, + 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, + 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, + 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, + 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, + 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, + 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, + 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, + 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, + 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, + 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, + 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, + 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, + 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, + 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, + 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, + 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, + 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, + 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, + 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, + 0x02323032, 0x84808404, 0x49616829, 0x83939013, + 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, + 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, + 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, + 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437} +}; + +/* key schedule constants - golden ratio */ +# define KC0 0x9e3779b9 +# define KC1 0x3c6ef373 +# define KC2 0x78dde6e6 +# define KC3 0xf1bbcdcc +# define KC4 0xe3779b99 +# define KC5 0xc6ef3733 +# define KC6 0x8dde6e67 +# define KC7 0x1bbcdccf +# define KC8 0x3779b99e +# define KC9 0x6ef3733c +# define KC10 0xdde6e678 +# define KC11 0xbbcdccf1 +# define KC12 0x779b99e3 +# define KC13 0xef3733c6 +# define KC14 0xde6e678d +# define KC15 0xbcdccf1b + +# if defined(OPENSSL_SMALL_FOOTPRINT) +static const seed_word KC[] = { + KC0, KC1, KC2, KC3, KC4, KC5, KC6, KC7, + KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15 +}; +# endif +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks) +# ifdef OPENSSL_FIPS +{ + fips_cipher_abort(SEED); + private_SEED_set_key(rawkey, ks); +} + +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks) +# endif +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(rawkey, x1); + char2word(rawkey + 4, x2); + char2word(rawkey + 8, x3); + char2word(rawkey + 12, x4); + + t0 = (x1 + x3 - KC0) & 0xffffffff; + t1 = (x2 - x4 + KC0) & 0xffffffff; + KEYUPDATE_TEMP(t0, t1, &ks->data[0]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1); + KEYUPDATE_TEMP(t0, t1, &ks->data[2]); + +# if !defined(OPENSSL_SMALL_FOOTPRINT) + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2); + KEYUPDATE_TEMP(t0, t1, &ks->data[4]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3); + KEYUPDATE_TEMP(t0, t1, &ks->data[6]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4); + KEYUPDATE_TEMP(t0, t1, &ks->data[8]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5); + KEYUPDATE_TEMP(t0, t1, &ks->data[10]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6); + KEYUPDATE_TEMP(t0, t1, &ks->data[12]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7); + KEYUPDATE_TEMP(t0, t1, &ks->data[14]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8); + KEYUPDATE_TEMP(t0, t1, &ks->data[16]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9); + KEYUPDATE_TEMP(t0, t1, &ks->data[18]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10); + KEYUPDATE_TEMP(t0, t1, &ks->data[20]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11); + KEYUPDATE_TEMP(t0, t1, &ks->data[22]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12); + KEYUPDATE_TEMP(t0, t1, &ks->data[24]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13); + KEYUPDATE_TEMP(t0, t1, &ks->data[26]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14); + KEYUPDATE_TEMP(t0, t1, &ks->data[28]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15); + KEYUPDATE_TEMP(t0, t1, &ks->data[30]); +# else + { + int i; + for (i = 2; i < 16; i += 2) { + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]); + KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i + 1]); + KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2 + 2]); + } + } +# endif +} + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks) +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(s, x1); + char2word(s + 4, x2); + char2word(s + 8, x3); + char2word(s + 12, x4); + +# if !defined(OPENSSL_SMALL_FOOTPRINT) + E_SEED(t0, t1, x1, x2, x3, x4, 0); + E_SEED(t0, t1, x3, x4, x1, x2, 2); + E_SEED(t0, t1, x1, x2, x3, x4, 4); + E_SEED(t0, t1, x3, x4, x1, x2, 6); + E_SEED(t0, t1, x1, x2, x3, x4, 8); + E_SEED(t0, t1, x3, x4, x1, x2, 10); + E_SEED(t0, t1, x1, x2, x3, x4, 12); + E_SEED(t0, t1, x3, x4, x1, x2, 14); + E_SEED(t0, t1, x1, x2, x3, x4, 16); + E_SEED(t0, t1, x3, x4, x1, x2, 18); + E_SEED(t0, t1, x1, x2, x3, x4, 20); + E_SEED(t0, t1, x3, x4, x1, x2, 22); + E_SEED(t0, t1, x1, x2, x3, x4, 24); + E_SEED(t0, t1, x3, x4, x1, x2, 26); + E_SEED(t0, t1, x1, x2, x3, x4, 28); + E_SEED(t0, t1, x3, x4, x1, x2, 30); +# else + { + int i; + for (i = 0; i < 30; i += 4) { + E_SEED(t0, t1, x1, x2, x3, x4, i); + E_SEED(t0, t1, x3, x4, x1, x2, i + 2); + } + } +# endif + + word2char(x3, d); + word2char(x4, d + 4); + word2char(x1, d + 8); + word2char(x2, d + 12); +} + +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks) +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(s, x1); + char2word(s + 4, x2); + char2word(s + 8, x3); + char2word(s + 12, x4); + +# if !defined(OPENSSL_SMALL_FOOTPRINT) + E_SEED(t0, t1, x1, x2, x3, x4, 30); + E_SEED(t0, t1, x3, x4, x1, x2, 28); + E_SEED(t0, t1, x1, x2, x3, x4, 26); + E_SEED(t0, t1, x3, x4, x1, x2, 24); + E_SEED(t0, t1, x1, x2, x3, x4, 22); + E_SEED(t0, t1, x3, x4, x1, x2, 20); + E_SEED(t0, t1, x1, x2, x3, x4, 18); + E_SEED(t0, t1, x3, x4, x1, x2, 16); + E_SEED(t0, t1, x1, x2, x3, x4, 14); + E_SEED(t0, t1, x3, x4, x1, x2, 12); + E_SEED(t0, t1, x1, x2, x3, x4, 10); + E_SEED(t0, t1, x3, x4, x1, x2, 8); + E_SEED(t0, t1, x1, x2, x3, x4, 6); + E_SEED(t0, t1, x3, x4, x1, x2, 4); + E_SEED(t0, t1, x1, x2, x3, x4, 2); + E_SEED(t0, t1, x3, x4, x1, x2, 0); +# else + { + int i; + for (i = 30; i > 0; i -= 4) { + E_SEED(t0, t1, x1, x2, x3, x4, i); + E_SEED(t0, t1, x3, x4, x1, x2, i - 2); + + } + } +# endif + + word2char(x3, d); + word2char(x4, d + 4); + word2char(x1, d + 8); + word2char(x2, d + 12); +} + +#endif /* OPENSSL_NO_SEED */ diff --git a/Sources/COpenSSL/seed.h b/Sources/COpenSSL/seed.h new file mode 100644 index 00000000..30fa2a7d --- /dev/null +++ b/Sources/COpenSSL/seed.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SEED_H +# define HEADER_SEED_H + +# include "opensslconf.h" +# include "e_os2.h" +# include "crypto.h" + +# ifdef OPENSSL_NO_SEED +# error SEED is disabled. +# endif + +/* look whether we need 'long' to get 32 bits */ +# ifdef AES_LONG +# ifndef SEED_LONG +# define SEED_LONG 1 +# endif +# endif + +# if !defined(NO_SYS_TYPES_H) +# include +# endif + +# define SEED_BLOCK_SIZE 16 +# define SEED_KEY_LENGTH 16 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct seed_key_st { +# ifdef SEED_LONG + unsigned long data[32]; +# else + unsigned int data[32]; +# endif +} SEED_KEY_SCHEDULE; + +# ifdef OPENSSL_FIPS +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); +# endif +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, + const SEED_KEY_SCHEDULE *ks, int enc); +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc); +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, + int enc); +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SEED_H */ diff --git a/Sources/COpenSSL/seed_.c b/Sources/COpenSSL/seed_.c new file mode 100644 index 00000000..86d9f35c --- /dev/null +++ b/Sources/COpenSSL/seed_.c @@ -0,0 +1,361 @@ +/* crypto/seed/seed_cbc.c */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "seed.h" +#include "modes.h" + +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc) +{ + if (enc) + CRYPTO_cbc128_encrypt(in, out, len, ks, ivec, + (block128_f) SEED_encrypt); + else + CRYPTO_cbc128_decrypt(in, out, len, ks, ivec, + (block128_f) SEED_decrypt); +} +/* crypto/seed/seed_cfb.c */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "seed.h" +// #include "modes.h" + +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, + int enc) +{ + CRYPTO_cfb128_encrypt(in, out, len, ks, ivec, num, enc, + (block128_f) SEED_encrypt); +} +/* crypto/seed/seed_ecb.c */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "seed.h" + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, + const SEED_KEY_SCHEDULE *ks, int enc) +{ + if (enc) + SEED_encrypt(in, out, ks); + else + SEED_decrypt(in, out, ks); +} +/* crypto/seed/seed_ofb.c */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "seed.h" +// #include "modes.h" + +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num) +{ + CRYPTO_ofb128_encrypt(in, out, len, ks, ivec, num, + (block128_f) SEED_encrypt); +} diff --git a/Sources/COpenSSL/seed_locl.h b/Sources/COpenSSL/seed_locl.h new file mode 100644 index 00000000..8dd4f12a --- /dev/null +++ b/Sources/COpenSSL/seed_locl.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#ifndef HEADER_SEED_LOCL_H +# define HEADER_SEED_LOCL_H + +# include "e_os2.h" +# include "seed.h" + +# ifdef SEED_LONG /* need 32-bit type */ +typedef unsigned long seed_word; +# else +typedef unsigned int seed_word; +# endif + + +#ifdef __cplusplus +extern "C" { +#endif + +# define G_FUNC(v) \ + SS[0][(unsigned char) (v) & 0xff] ^ SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \ + SS[2][(unsigned char)((v)>>16) & 0xff] ^ SS[3][(unsigned char)((v)>>24) & 0xff] + +# define char2word(c, i) \ + (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3])) + +# define word2char(l, c) \ + *((c)+0) = (unsigned char)((l)>>24) & 0xff; \ + *((c)+1) = (unsigned char)((l)>>16) & 0xff; \ + *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \ + *((c)+3) = (unsigned char)((l)) & 0xff + +# define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC) \ + (T0) = (X3); \ + (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff; \ + (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff; \ + (T0) = ((X1) + (X3) - (KC)) & 0xffffffff; \ + (T1) = ((X2) + (KC) - (X4)) & 0xffffffff + +# define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC) \ + (T0) = (X1); \ + (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff; \ + (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff; \ + (T0) = ((X1) + (X3) - (KC)) & 0xffffffff; \ + (T1) = ((X2) + (KC) - (X4)) & 0xffffffff + +# define KEYUPDATE_TEMP(T0, T1, K) \ + (K)[0] = G_FUNC((T0)); \ + (K)[1] = G_FUNC((T1)) + +# define XOR_SEEDBLOCK(DST, SRC) \ + ((DST))[0] ^= ((SRC))[0]; \ + ((DST))[1] ^= ((SRC))[1]; \ + ((DST))[2] ^= ((SRC))[2]; \ + ((DST))[3] ^= ((SRC))[3] + +# define MOV_SEEDBLOCK(DST, SRC) \ + ((DST))[0] = ((SRC))[0]; \ + ((DST))[1] = ((SRC))[1]; \ + ((DST))[2] = ((SRC))[2]; \ + ((DST))[3] = ((SRC))[3] + +# define CHAR2WORD(C, I) \ + char2word((C), (I)[0]); \ + char2word((C+4), (I)[1]); \ + char2word((C+8), (I)[2]); \ + char2word((C+12), (I)[3]) + +# define WORD2CHAR(I, C) \ + word2char((I)[0], (C)); \ + word2char((I)[1], (C+4)); \ + word2char((I)[2], (C+8)); \ + word2char((I)[3], (C+12)) + +# define E_SEED(T0, T1, X1, X2, X3, X4, rbase) \ + (T0) = (X3) ^ (ks->data)[(rbase)]; \ + (T1) = (X4) ^ (ks->data)[(rbase)+1]; \ + (T1) ^= (T0); \ + (T1) = G_FUNC((T1)); \ + (T0) = ((T0) + (T1)) & 0xffffffff; \ + (T0) = G_FUNC((T0)); \ + (T1) = ((T1) + (T0)) & 0xffffffff; \ + (T1) = G_FUNC((T1)); \ + (T0) = ((T0) + (T1)) & 0xffffffff; \ + (X1) ^= (T0); \ + (X2) ^= (T1) + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SEED_LOCL_H */ diff --git a/Sources/COpenSSL/set_key.c b/Sources/COpenSSL/set_key.c new file mode 100644 index 00000000..f75e0f64 --- /dev/null +++ b/Sources/COpenSSL/set_key.c @@ -0,0 +1,447 @@ +/* crypto/des/set_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * set_key.c v 1.4 eay 24/9/91 + * 1.4 Speed up by 400% :-) + * 1.3 added register declarations. + * 1.2 unrolled make_key_sched a bit more + * 1.1 added norm_expand_bits + * 1.0 First working version + */ +#include "crypto.h" +#include "des_locl.h" + +OPENSSL_IMPLEMENT_GLOBAL(int, DES_check_key, 0) + /* + * defaults to false + */ +static const unsigned char odd_parity[256] = { + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, + 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110, + 110, + 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127, + 127, + 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143, + 143, + 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158, + 158, + 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174, + 174, + 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, + 191, + 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, + 206, + 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, + 223, + 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, + 239, + 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254, + 254 +}; + +void DES_set_odd_parity(DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < DES_KEY_SZ; i++) + (*key)[i] = odd_parity[(*key)[i]]; +} + +int DES_check_key_parity(const_DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < DES_KEY_SZ; i++) { + if ((*key)[i] != odd_parity[(*key)[i]]) + return (0); + } + return (1); +} + +/*- + * Weak and semi weak keys as taken from + * %A D.W. Davies + * %A W.L. Price + * %T Security for Computer Networks + * %I John Wiley & Sons + * %D 1984 + * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference + * (and actual cblock values). + */ +#define NUM_WEAK_KEY 16 +static const DES_cblock weak_keys[NUM_WEAK_KEY] = { + /* weak keys */ + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}, + {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, + {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1}, + /* semi-weak keys */ + {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE}, + {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01}, + {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1}, + {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E}, + {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1}, + {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01}, + {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE}, + {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E}, + {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E}, + {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01}, + {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, + {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1} +}; + +int DES_is_weak_key(const_DES_cblock *key) +{ + int i; + + for (i = 0; i < NUM_WEAK_KEY; i++) + /* + * Added == 0 to comparison, I obviously don't run this section very + * often :-(, thanks to engineering@MorningStar.Com for the fix eay + * 93/06/29 Another problem, I was comparing only the first 4 bytes, + * 97/03/18 + */ + if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0) + return (1); + return (0); +} + +/*- + * NOW DEFINED IN des_local.h + * See ecb_encrypt.c for a pseudo description of these macros. + * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + * (b)^=(t),\ + * (a)=((a)^((t)<<(n)))) + */ + +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ + (a)=(a)^(t)^(t>>(16-(n)))) + +static const DES_LONG des_skb[8][64] = { + { + /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ + 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L, + 0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L, + 0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L, + 0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L, + 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L, + 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L, + 0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L, + 0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L, + 0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L, + 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L, + 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L, + 0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L, + 0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L, + 0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L, + 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L, + 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L, + }, + { + /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ + 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L, + 0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L, + 0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L, + 0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L, + 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L, + 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L, + 0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L, + 0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L, + 0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L, + 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L, + 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L, + 0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L, + 0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L, + 0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L, + 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L, + 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L, + }, + { + /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ + 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L, + 0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L, + 0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L, + 0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L, + 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L, + 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L, + 0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L, + 0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L, + 0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L, + 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L, + 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L, + 0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L, + 0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L, + 0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L, + 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L, + 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L, + }, + { + /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ + 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L, + 0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L, + 0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L, + 0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L, + 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L, + 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L, + 0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L, + 0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L, + 0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L, + 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L, + 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L, + 0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L, + 0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L, + 0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L, + 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L, + 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L, + }, + { + /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ + 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L, + 0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L, + 0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L, + 0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L, + 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L, + 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L, + 0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L, + 0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L, + 0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L, + 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L, + 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L, + 0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L, + 0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L, + 0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L, + 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L, + 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L, + }, + { + /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ + 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L, + 0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L, + 0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L, + 0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L, + 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L, + 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L, + 0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L, + 0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L, + 0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L, + 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L, + 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L, + 0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L, + 0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L, + 0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L, + 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L, + 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L, + }, + { + /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ + 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L, + 0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L, + 0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L, + 0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L, + 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L, + 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L, + 0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L, + 0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L, + 0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L, + 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L, + 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L, + 0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L, + 0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L, + 0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L, + 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L, + 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L, + }, + { + /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ + 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L, + 0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L, + 0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L, + 0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L, + 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L, + 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L, + 0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L, + 0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L, + 0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L, + 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L, + 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L, + 0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L, + 0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L, + 0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L, + 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L, + 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L, + } +}; + +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule) +{ + if (DES_check_key) { + return DES_set_key_checked(key, schedule); + } else { + DES_set_key_unchecked(key, schedule); + return 0; + } +} + +/*- + * return 0 if key parity is odd (correct), + * return -1 if key parity error, + * return -2 if illegal weak key. + */ +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule) +{ + if (!DES_check_key_parity(key)) + return (-1); + if (DES_is_weak_key(key)) + return (-2); + DES_set_key_unchecked(key, schedule); + return 0; +} + +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(DES); + private_DES_set_key_unchecked(key, schedule); +} + +void private_DES_set_key_unchecked(const_DES_cblock *key, + DES_key_schedule *schedule) +#endif +{ + static const int shifts2[16] = + { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 }; + register DES_LONG c, d, t, s, t2; + register const unsigned char *in; + register DES_LONG *k; + register int i; + +#ifdef OPENBSD_DEV_CRYPTO + memcpy(schedule->key, key, sizeof(schedule->key)); + schedule->session = NULL; +#endif + k = &schedule->ks->deslong[0]; + in = &(*key)[0]; + + c2l(in, c); + c2l(in, d); + + /* + * do PC1 in 47 simple operations :-) Thanks to John Fletcher + * (john_fletcher@lccmail.ocf.llnl.gov) for the inspiration. :-) + */ + PERM_OP(d, c, t, 4, 0x0f0f0f0fL); + HPERM_OP(c, t, -2, 0xcccc0000L); + HPERM_OP(d, t, -2, 0xcccc0000L); + PERM_OP(d, c, t, 1, 0x55555555L); + PERM_OP(c, d, t, 8, 0x00ff00ffL); + PERM_OP(d, c, t, 1, 0x55555555L); + d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) | + ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L)); + c &= 0x0fffffffL; + + for (i = 0; i < ITERATIONS; i++) { + if (shifts2[i]) { + c = ((c >> 2L) | (c << 26L)); + d = ((d >> 2L) | (d << 26L)); + } else { + c = ((c >> 1L) | (c << 27L)); + d = ((d >> 1L) | (d << 27L)); + } + c &= 0x0fffffffL; + d &= 0x0fffffffL; + /* + * could be a few less shifts but I am to lazy at this point in time + * to investigate + */ + s = des_skb[0][(c) & 0x3f] | + des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] | + des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] | + des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) | + ((c >> 22L) & 0x38)]; + t = des_skb[4][(d) & 0x3f] | + des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] | + des_skb[6][(d >> 15L) & 0x3f] | + des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)]; + + /* table contained 0213 4657 */ + t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL; + *(k++) = ROTATE(t2, 30) & 0xffffffffL; + + t2 = ((s >> 16L) | (t & 0xffff0000L)); + *(k++) = ROTATE(t2, 26) & 0xffffffffL; + } +} + +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule) +{ + return (DES_set_key(key, schedule)); +} + +/*- +#undef des_fixup_key_parity +void des_fixup_key_parity(des_cblock *key) + { + des_set_odd_parity(key); + } +*/ diff --git a/Sources/COpenSSL/sha.h b/Sources/COpenSSL/sha.h new file mode 100644 index 00000000..53ae6f77 --- /dev/null +++ b/Sources/COpenSSL/sha.h @@ -0,0 +1,214 @@ +/* crypto/sha/sha.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SHA_H +# define HEADER_SHA_H + +# include "e_os2.h" +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1)) +# error SHA is disabled. +# endif + +# if defined(OPENSSL_FIPS) +# define FIPS_SHA_SIZE_T size_t +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! SHA_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define SHA_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define SHA_LONG unsigned long +# define SHA_LONG_LOG2 3 +# else +# define SHA_LONG unsigned int +# endif + +# define SHA_LBLOCK 16 +# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA_LAST_BLOCK (SHA_CBLOCK-8) +# define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st { + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +# ifndef OPENSSL_NO_SHA0 +# ifdef OPENSSL_FIPS +int private_SHA_Init(SHA_CTX *c); +# endif +int SHA_Init(SHA_CTX *c); +int SHA_Update(SHA_CTX *c, const void *data, size_t len); +int SHA_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md); +void SHA_Transform(SHA_CTX *c, const unsigned char *data); +# endif +# ifndef OPENSSL_NO_SHA1 +# ifdef OPENSSL_FIPS +int private_SHA1_Init(SHA_CTX *c); +# endif +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +# endif + +# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA224_DIGEST_LENGTH 28 +# define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256state_st { + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; + +# ifndef OPENSSL_NO_SHA256 +# ifdef OPENSSL_FIPS +int private_SHA224_Init(SHA256_CTX *c); +int private_SHA256_Init(SHA256_CTX *c); +# endif +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +# endif + +# define SHA384_DIGEST_LENGTH 48 +# define SHA512_DIGEST_LENGTH 64 + +# ifndef OPENSSL_NO_SHA512 +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +/* + * SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. + */ +# define SHA512_CBLOCK (SHA_LBLOCK*8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define SHA_LONG64 unsigned __int64 +# define U64(C) C##UI64 +# elif defined(__arch64__) +# define SHA_LONG64 unsigned long +# define U64(C) C##UL +# else +# define SHA_LONG64 unsigned long long +# define U64(C) C##ULL +# endif + +typedef struct SHA512state_st { + SHA_LONG64 h[8]; + SHA_LONG64 Nl, Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num, md_len; +} SHA512_CTX; +# endif + +# ifndef OPENSSL_NO_SHA512 +# ifdef OPENSSL_FIPS +int private_SHA384_Init(SHA512_CTX *c); +int private_SHA512_Init(SHA512_CTX *c); +# endif +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/sha1_one.c b/Sources/COpenSSL/sha1_one.c new file mode 100644 index 00000000..d875ce45 --- /dev/null +++ b/Sources/COpenSSL/sha1_one.c @@ -0,0 +1,79 @@ +/* crypto/sha/sha1_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "crypto.h" +#include "sha.h" + +#ifndef OPENSSL_NO_SHA1 +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!SHA1_Init(&c)) + return NULL; + SHA1_Update(&c, d, n); + SHA1_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} +#endif diff --git a/Sources/COpenSSL/sha1dgst.c b/Sources/COpenSSL/sha1dgst.c new file mode 100644 index 00000000..15b12300 --- /dev/null +++ b/Sources/COpenSSL/sha1dgst.c @@ -0,0 +1,74 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "crypto.h" +#include "opensslconf.h" +#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA) + +# undef SHA_0 +# define SHA_1 + +# include "opensslv.h" + +const char SHA1_version[] = "SHA1" OPENSSL_VERSION_PTEXT; + +/* The implementation is in ../md32_common.h */ + +# include "sha_locl.h" + +#endif diff --git a/Sources/COpenSSL/sha256.c b/Sources/COpenSSL/sha256.c new file mode 100644 index 00000000..89c5c710 --- /dev/null +++ b/Sources/COpenSSL/sha256.c @@ -0,0 +1,387 @@ +/* crypto/sha/sha256.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ +#include "opensslconf.h" +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) + +# include +# include + +# include "crypto.h" +# include "sha.h" +# include "opensslv.h" + +const char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT; + +fips_md_init_ctx(SHA224, SHA256) +{ + memset(c, 0, sizeof(*c)); + c->h[0] = 0xc1059ed8UL; + c->h[1] = 0x367cd507UL; + c->h[2] = 0x3070dd17UL; + c->h[3] = 0xf70e5939UL; + c->h[4] = 0xffc00b31UL; + c->h[5] = 0x68581511UL; + c->h[6] = 0x64f98fa7UL; + c->h[7] = 0xbefa4fa4UL; + c->md_len = SHA224_DIGEST_LENGTH; + return 1; +} + +fips_md_init(SHA256) +{ + memset(c, 0, sizeof(*c)); + c->h[0] = 0x6a09e667UL; + c->h[1] = 0xbb67ae85UL; + c->h[2] = 0x3c6ef372UL; + c->h[3] = 0xa54ff53aUL; + c->h[4] = 0x510e527fUL; + c->h[5] = 0x9b05688cUL; + c->h[6] = 0x1f83d9abUL; + c->h[7] = 0x5be0cd19UL; + c->md_len = SHA256_DIGEST_LENGTH; + return 1; +} + +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA256_CTX c; + static unsigned char m[SHA224_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA224_Init(&c); + SHA256_Update(&c, d, n); + SHA256_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA256_CTX c; + static unsigned char m[SHA256_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA256_Init(&c); + SHA256_Update(&c, d, n); + SHA256_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) +{ + return SHA256_Update(c, data, len); +} + +int SHA224_Final(unsigned char *md, SHA256_CTX *c) +{ + return SHA256_Final(md, c); +} + +# define DATA_ORDER_IS_BIG_ENDIAN + +# define HASH_LONG SHA_LONG +# define HASH_CTX SHA256_CTX +# define HASH_CBLOCK SHA_CBLOCK +/* + * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." + * default: case below covers for it. It's not clear however if it's + * permitted to truncate to amount of bytes not divisible by 4. I bet not, + * but if it is, then default: case shall be extended. For reference. + * Idea behind separate cases for pre-defined lenghts is to let the + * compiler decide if it's appropriate to unroll small loops. + */ +# define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + unsigned int nn; \ + switch ((c)->md_len) \ + { case SHA224_DIGEST_LENGTH: \ + for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + case SHA256_DIGEST_LENGTH: \ + for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + default: \ + if ((c)->md_len > SHA256_DIGEST_LENGTH) \ + return 0; \ + for (nn=0;nn<(c)->md_len/4;nn++) \ + { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + } \ + } while (0) + +# define HASH_UPDATE SHA256_Update +# define HASH_TRANSFORM SHA256_Transform +# define HASH_FINAL SHA256_Final +# define HASH_BLOCK_DATA_ORDER sha256_block_data_order +# ifndef SHA256_ASM +static +# endif +void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); + +# include "md32_common.h" + +# ifndef SHA256_ASM +static const SHA_LONG K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* + * FIPS specification refers to right rotations, while our ROTATE macro + * is left one. This is why you might notice that rotation coefficients + * differ from those observed in FIPS document by 32-N... + */ +# define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10)) +# define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7)) +# define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3)) +# define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10)) + +# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +# ifdef OPENSSL_SMALL_FOOTPRINT + +static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, + size_t num) +{ + unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2; + SHA_LONG X[16], l; + int i; + const unsigned char *data = in; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + for (i = 0; i < 16; i++) { + HOST_c2l(data, l); + T1 = X[i] = l; + T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + for (; i < 64; i++) { + s0 = X[(i + 1) & 0x0f]; + s0 = sigma0(s0); + s1 = X[(i + 14) & 0x0f]; + s1 = sigma1(s1); + + T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; + T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + } +} + +# else + +# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ + T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \ + h = Sigma0(a) + Maj(a,b,c); \ + d += T1; h += T1; } while (0) + +# define ROUND_16_63(i,a,b,c,d,e,f,g,h,X) do { \ + s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ + s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ + T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ + ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) + +static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, + size_t num) +{ + unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1; + SHA_LONG X[16]; + int i; + const unsigned char *data = in; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + if (!is_endian.little && sizeof(SHA_LONG) == 4 + && ((size_t)in % 4) == 0) { + const SHA_LONG *W = (const SHA_LONG *)data; + + T1 = X[0] = W[0]; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = W[1]; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = W[2]; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = W[3]; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = W[4]; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = W[5]; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = W[6]; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = W[7]; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = W[8]; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = W[9]; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = W[10]; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = W[11]; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = W[12]; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = W[13]; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = W[14]; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = W[15]; + ROUND_00_15(15, b, c, d, e, f, g, h, a); + + data += SHA256_CBLOCK; + } else { + SHA_LONG l; + + HOST_c2l(data, l); + T1 = X[0] = l; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + HOST_c2l(data, l); + T1 = X[1] = l; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + HOST_c2l(data, l); + T1 = X[2] = l; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + HOST_c2l(data, l); + T1 = X[3] = l; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + HOST_c2l(data, l); + T1 = X[4] = l; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + HOST_c2l(data, l); + T1 = X[5] = l; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + HOST_c2l(data, l); + T1 = X[6] = l; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + HOST_c2l(data, l); + T1 = X[7] = l; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + HOST_c2l(data, l); + T1 = X[8] = l; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + HOST_c2l(data, l); + T1 = X[9] = l; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + HOST_c2l(data, l); + T1 = X[10] = l; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + HOST_c2l(data, l); + T1 = X[11] = l; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + HOST_c2l(data, l); + T1 = X[12] = l; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + HOST_c2l(data, l); + T1 = X[13] = l; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + HOST_c2l(data, l); + T1 = X[14] = l; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + HOST_c2l(data, l); + T1 = X[15] = l; + ROUND_00_15(15, b, c, d, e, f, g, h, a); + } + + for (i = 16; i < 64; i += 8) { + ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X); + ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X); + ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X); + ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X); + ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X); + ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X); + ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X); + ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X); + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + } +} + +# endif +# endif /* SHA256_ASM */ + +#endif /* OPENSSL_NO_SHA256 */ diff --git a/Sources/COpenSSL/sha512.c b/Sources/COpenSSL/sha512.c new file mode 100644 index 00000000..08376c06 --- /dev/null +++ b/Sources/COpenSSL/sha512.c @@ -0,0 +1,684 @@ +/* crypto/sha/sha512.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ +#include "opensslconf.h" +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) +/*- + * IMPLEMENTATION NOTES. + * + * As you might have noticed 32-bit hash algorithms: + * + * - permit SHA_LONG to be wider than 32-bit (case on CRAY); + * - optimized versions implement two transform functions: one operating + * on [aligned] data in host byte order and one - on data in input + * stream byte order; + * - share common byte-order neutral collector and padding function + * implementations, ../md32_common.h; + * + * Neither of the above applies to this SHA-512 implementations. Reasons + * [in reverse order] are: + * + * - it's the only 64-bit hash algorithm for the moment of this writing, + * there is no need for common collector/padding implementation [yet]; + * - by supporting only one transform function [which operates on + * *aligned* data in input stream byte order, big-endian in this case] + * we minimize burden of maintenance in two ways: a) collector/padding + * function is simpler; b) only one transform function to stare at; + * - SHA_LONG64 is required to be exactly 64-bit in order to be able to + * apply a number of optimizations to mitigate potential performance + * penalties caused by previous design decision; + * + * Caveat lector. + * + * Implementation relies on the fact that "long long" is 64-bit on + * both 32- and 64-bit platforms. If some compiler vendor comes up + * with 128-bit long long, adjustment to sha.h would be required. + * As this implementation relies on 64-bit integer type, it's totally + * inappropriate for platforms which don't support it, most notably + * 16-bit platforms. + * + */ +# include +# include + +# include "crypto.h" +# include "sha.h" +# include "opensslv.h" + +# include "cryptlib.h" + +const char SHA512_version[] = "SHA-512" OPENSSL_VERSION_PTEXT; + +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) || \ + defined(__aarch64__) || \ + defined(SHA512_ASM) +# define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA +# endif + +fips_md_init_ctx(SHA384, SHA512) +{ + c->h[0] = U64(0xcbbb9d5dc1059ed8); + c->h[1] = U64(0x629a292a367cd507); + c->h[2] = U64(0x9159015a3070dd17); + c->h[3] = U64(0x152fecd8f70e5939); + c->h[4] = U64(0x67332667ffc00b31); + c->h[5] = U64(0x8eb44a8768581511); + c->h[6] = U64(0xdb0c2e0d64f98fa7); + c->h[7] = U64(0x47b5481dbefa4fa4); + + c->Nl = 0; + c->Nh = 0; + c->num = 0; + c->md_len = SHA384_DIGEST_LENGTH; + return 1; +} + +fips_md_init(SHA512) +{ + c->h[0] = U64(0x6a09e667f3bcc908); + c->h[1] = U64(0xbb67ae8584caa73b); + c->h[2] = U64(0x3c6ef372fe94f82b); + c->h[3] = U64(0xa54ff53a5f1d36f1); + c->h[4] = U64(0x510e527fade682d1); + c->h[5] = U64(0x9b05688c2b3e6c1f); + c->h[6] = U64(0x1f83d9abfb41bd6b); + c->h[7] = U64(0x5be0cd19137e2179); + + c->Nl = 0; + c->Nh = 0; + c->num = 0; + c->md_len = SHA512_DIGEST_LENGTH; + return 1; +} + +# ifndef SHA512_ASM +static +# endif +void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); + +int SHA512_Final(unsigned char *md, SHA512_CTX *c) +{ + unsigned char *p = (unsigned char *)c->u.p; + size_t n = c->num; + + p[n] = 0x80; /* There always is a room for one */ + n++; + if (n > (sizeof(c->u) - 16)) + memset(p + n, 0, sizeof(c->u) - n), n = 0, + sha512_block_data_order(c, p, 1); + + memset(p + n, 0, sizeof(c->u) - 16 - n); +# ifdef B_ENDIAN + c->u.d[SHA_LBLOCK - 2] = c->Nh; + c->u.d[SHA_LBLOCK - 1] = c->Nl; +# else + p[sizeof(c->u) - 1] = (unsigned char)(c->Nl); + p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8); + p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16); + p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24); + p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32); + p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40); + p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48); + p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56); + p[sizeof(c->u) - 9] = (unsigned char)(c->Nh); + p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8); + p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16); + p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24); + p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32); + p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40); + p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48); + p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56); +# endif + + sha512_block_data_order(c, p, 1); + + if (md == 0) + return 0; + + switch (c->md_len) { + /* Let compiler decide if it's appropriate to unroll... */ + case SHA384_DIGEST_LENGTH: + for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) { + SHA_LONG64 t = c->h[n]; + + *(md++) = (unsigned char)(t >> 56); + *(md++) = (unsigned char)(t >> 48); + *(md++) = (unsigned char)(t >> 40); + *(md++) = (unsigned char)(t >> 32); + *(md++) = (unsigned char)(t >> 24); + *(md++) = (unsigned char)(t >> 16); + *(md++) = (unsigned char)(t >> 8); + *(md++) = (unsigned char)(t); + } + break; + case SHA512_DIGEST_LENGTH: + for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) { + SHA_LONG64 t = c->h[n]; + + *(md++) = (unsigned char)(t >> 56); + *(md++) = (unsigned char)(t >> 48); + *(md++) = (unsigned char)(t >> 40); + *(md++) = (unsigned char)(t >> 32); + *(md++) = (unsigned char)(t >> 24); + *(md++) = (unsigned char)(t >> 16); + *(md++) = (unsigned char)(t >> 8); + *(md++) = (unsigned char)(t); + } + break; + /* ... as well as make sure md_len is not abused. */ + default: + return 0; + } + + return 1; +} + +int SHA384_Final(unsigned char *md, SHA512_CTX *c) +{ + return SHA512_Final(md, c); +} + +int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len) +{ + SHA_LONG64 l; + unsigned char *p = c->u.p; + const unsigned char *data = (const unsigned char *)_data; + + if (len == 0) + return 1; + + l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff); + if (l < c->Nl) + c->Nh++; + if (sizeof(len) >= 8) + c->Nh += (((SHA_LONG64) len) >> 61); + c->Nl = l; + + if (c->num != 0) { + size_t n = sizeof(c->u) - c->num; + + if (len < n) { + memcpy(p + c->num, data, len), c->num += (unsigned int)len; + return 1; + } else { + memcpy(p + c->num, data, n), c->num = 0; + len -= n, data += n; + sha512_block_data_order(c, p, 1); + } + } + + if (len >= sizeof(c->u)) { +# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA + if ((size_t)data % sizeof(c->u.d[0]) != 0) + while (len >= sizeof(c->u)) + memcpy(p, data, sizeof(c->u)), + sha512_block_data_order(c, p, 1), + len -= sizeof(c->u), data += sizeof(c->u); + else +# endif + sha512_block_data_order(c, data, len / sizeof(c->u)), + data += len, len %= sizeof(c->u), data -= len; + } + + if (len != 0) + memcpy(p, data, len), c->num = (int)len; + + return 1; +} + +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len) +{ + return SHA512_Update(c, data, len); +} + +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data) +{ +# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA + if ((size_t)data % sizeof(c->u.d[0]) != 0) + memcpy(c->u.p, data, sizeof(c->u.p)), data = c->u.p; +# endif + sha512_block_data_order(c, data, 1); +} + +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA512_CTX c; + static unsigned char m[SHA384_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA384_Init(&c); + SHA512_Update(&c, d, n); + SHA512_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA512_CTX c; + static unsigned char m[SHA512_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA512_Init(&c); + SHA512_Update(&c, d, n); + SHA512_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +# ifndef SHA512_ASM +static const SHA_LONG64 K512[80] = { + U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd), + U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc), + U64(0x3956c25bf348b538), U64(0x59f111f1b605d019), + U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118), + U64(0xd807aa98a3030242), U64(0x12835b0145706fbe), + U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2), + U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1), + U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694), + U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3), + U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65), + U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483), + U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5), + U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210), + U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4), + U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725), + U64(0x06ca6351e003826f), U64(0x142929670a0e6e70), + U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926), + U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df), + U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8), + U64(0x81c2c92e47edaee6), U64(0x92722c851482353b), + U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001), + U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30), + U64(0xd192e819d6ef5218), U64(0xd69906245565a910), + U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8), + U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53), + U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8), + U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb), + U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3), + U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60), + U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec), + U64(0x90befffa23631e28), U64(0xa4506cebde82bde9), + U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b), + U64(0xca273eceea26619c), U64(0xd186b8c721c0c207), + U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178), + U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6), + U64(0x113f9804bef90dae), U64(0x1b710b35131c471b), + U64(0x28db77f523047d84), U64(0x32caab7b40c72493), + U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c), + U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a), + U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817) +}; + +# ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__x86_64) || defined(__x86_64__) +# define ROTR(a,n) ({ SHA_LONG64 ret; \ + asm ("rorq %1,%0" \ + : "=r"(ret) \ + : "J"(n),"0"(a) \ + : "cc"); ret; }) +# if !defined(B_ENDIAN) +# define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x))); \ + asm ("bswapq %0" \ + : "=r"(ret) \ + : "0"(ret)); ret; }) +# endif +# elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN) +# if defined(I386_ONLY) +# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ + unsigned int hi=p[0],lo=p[1]; \ + asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\ + "roll $16,%%eax; roll $16,%%edx; "\ + "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \ + : "=a"(lo),"=d"(hi) \ + : "0"(lo),"1"(hi) : "cc"); \ + ((SHA_LONG64)hi)<<32|lo; }) +# else +# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ + unsigned int hi=p[0],lo=p[1]; \ + asm ("bswapl %0; bswapl %1;" \ + : "=r"(lo),"=r"(hi) \ + : "0"(lo),"1"(hi)); \ + ((SHA_LONG64)hi)<<32|lo; }) +# endif +# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) +# define ROTR(a,n) ({ SHA_LONG64 ret; \ + asm ("rotrdi %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a),"K"(n)); ret; }) +# elif defined(__aarch64__) +# define ROTR(a,n) ({ SHA_LONG64 ret; \ + asm ("ror %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a),"I"(n)); ret; }) +# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define PULL64(x) ({ SHA_LONG64 ret; \ + asm ("rev %0,%1" \ + : "=r"(ret) \ + : "r"(*((const SHA_LONG64 *)(&(x))))); ret; }) +# endif +# endif +# elif defined(_MSC_VER) +# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ +# pragma intrinsic(_rotr64) +# define ROTR(a,n) _rotr64((a),n) +# endif +# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(I386_ONLY) +static SHA_LONG64 __fastcall __pull64be(const void *x) +{ + _asm mov edx,[ecx + 0] + _asm mov eax,[ecx + 4] +_asm xchg dh, dl + _asm xchg ah, al + _asm rol edx, 16 _asm rol eax, 16 _asm xchg dh, dl _asm xchg ah, al} +# else +static SHA_LONG64 __fastcall __pull64be(const void *x) +{ + _asm mov edx,[ecx + 0] + _asm mov eax,[ecx + 4] +_asm bswap edx _asm bswap eax} +# endif +# define PULL64(x) __pull64be(&(x)) +# if _MSC_VER<=1200 +# pragma inline_depth(0) +# endif +# endif +# endif +# endif +# ifndef PULL64 +# define B(x,j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8)) +# define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7)) +# endif +# ifndef ROTR +# define ROTR(x,s) (((x)>>s) | (x)<<(64-s)) +# endif +# define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) +# define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) +# define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) +# define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) +# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) +/* + * This code should give better results on 32-bit CPU with less than + * ~24 registers, both size and performance wise... + */ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, + size_t num) +{ + const SHA_LONG64 *W = in; + SHA_LONG64 A, E, T; + SHA_LONG64 X[9 + 80], *F; + int i; + + while (num--) { + + F = X + 80; + A = ctx->h[0]; + F[1] = ctx->h[1]; + F[2] = ctx->h[2]; + F[3] = ctx->h[3]; + E = ctx->h[4]; + F[5] = ctx->h[5]; + F[6] = ctx->h[6]; + F[7] = ctx->h[7]; + + for (i = 0; i < 16; i++, F--) { +# ifdef B_ENDIAN + T = W[i]; +# else + T = PULL64(W[i]); +# endif + F[0] = A; + F[4] = E; + F[8] = T; + T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i]; + E = F[3] + T; + A = T + Sigma0(A) + Maj(A, F[1], F[2]); + } + + for (; i < 80; i++, F--) { + T = sigma0(F[8 + 16 - 1]); + T += sigma1(F[8 + 16 - 14]); + T += F[8 + 16] + F[8 + 16 - 9]; + + F[0] = A; + F[4] = E; + F[8] = T; + T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i]; + E = F[3] + T; + A = T + Sigma0(A) + Maj(A, F[1], F[2]); + } + + ctx->h[0] += A; + ctx->h[1] += F[1]; + ctx->h[2] += F[2]; + ctx->h[3] += F[3]; + ctx->h[4] += E; + ctx->h[5] += F[5]; + ctx->h[6] += F[6]; + ctx->h[7] += F[7]; + + W += SHA_LBLOCK; + } +} + +# elif defined(OPENSSL_SMALL_FOOTPRINT) +static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, + size_t num) +{ + const SHA_LONG64 *W = in; + SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2; + SHA_LONG64 X[16]; + int i; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + for (i = 0; i < 16; i++) { +# ifdef B_ENDIAN + T1 = X[i] = W[i]; +# else + T1 = X[i] = PULL64(W[i]); +# endif + T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + for (; i < 80; i++) { + s0 = X[(i + 1) & 0x0f]; + s0 = sigma0(s0); + s1 = X[(i + 14) & 0x0f]; + s1 = sigma1(s1); + + T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; + T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + W += SHA_LBLOCK; + } +} + +# else +# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ + T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \ + h = Sigma0(a) + Maj(a,b,c); \ + d += T1; h += T1; } while (0) +# define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \ + s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \ + s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \ + T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \ + ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0) +static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, + size_t num) +{ + const SHA_LONG64 *W = in; + SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1; + SHA_LONG64 X[16]; + int i; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + +# ifdef B_ENDIAN + T1 = X[0] = W[0]; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = W[1]; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = W[2]; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = W[3]; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = W[4]; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = W[5]; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = W[6]; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = W[7]; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = W[8]; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = W[9]; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = W[10]; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = W[11]; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = W[12]; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = W[13]; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = W[14]; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = W[15]; + ROUND_00_15(15, b, c, d, e, f, g, h, a); +# else + T1 = X[0] = PULL64(W[0]); + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = PULL64(W[1]); + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = PULL64(W[2]); + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = PULL64(W[3]); + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = PULL64(W[4]); + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = PULL64(W[5]); + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = PULL64(W[6]); + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = PULL64(W[7]); + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = PULL64(W[8]); + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = PULL64(W[9]); + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = PULL64(W[10]); + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = PULL64(W[11]); + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = PULL64(W[12]); + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = PULL64(W[13]); + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = PULL64(W[14]); + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = PULL64(W[15]); + ROUND_00_15(15, b, c, d, e, f, g, h, a); +# endif + + for (i = 16; i < 80; i += 16) { + ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X); + ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X); + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + W += SHA_LBLOCK; + } +} + +# endif + +# endif /* SHA512_ASM */ + +#else /* !OPENSSL_NO_SHA512 */ + +# if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) +static void *dummy = &dummy; +# endif + +#endif /* !OPENSSL_NO_SHA512 */ diff --git a/Sources/COpenSSL/sha_.c b/Sources/COpenSSL/sha_.c new file mode 100644 index 00000000..e289d108 --- /dev/null +++ b/Sources/COpenSSL/sha_.c @@ -0,0 +1,153 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "crypto.h" +#include "opensslconf.h" +#if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA) + +# undef SHA_1 +# define SHA_0 + +# include "opensslv.h" + +const char SHA_version[] = "SHA" OPENSSL_VERSION_PTEXT; + +/* The implementation is in ../md32_common.h */ + +# include "sha_locl.h" + +#endif +/* crypto/sha/sha_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "sha.h" +// #include "crypto.h" + +#ifndef OPENSSL_NO_SHA0 +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!SHA_Init(&c)) + return NULL; + SHA_Update(&c, d, n); + SHA_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} +#endif diff --git a/Sources/COpenSSL/sha_locl.h b/Sources/COpenSSL/sha_locl.h new file mode 100644 index 00000000..1b3a7c68 --- /dev/null +++ b/Sources/COpenSSL/sha_locl.h @@ -0,0 +1,500 @@ +/* crypto/sha/sha_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include "opensslconf.h" +#include "sha.h" + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_LONG SHA_LONG +#define HASH_CTX SHA_CTX +#define HASH_CBLOCK SHA_CBLOCK +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->h0; (void)HOST_l2c(ll,(s)); \ + ll=(c)->h1; (void)HOST_l2c(ll,(s)); \ + ll=(c)->h2; (void)HOST_l2c(ll,(s)); \ + ll=(c)->h3; (void)HOST_l2c(ll,(s)); \ + ll=(c)->h4; (void)HOST_l2c(ll,(s)); \ + } while (0) + +#if defined(SHA_0) + +# define HASH_UPDATE SHA_Update +# define HASH_TRANSFORM SHA_Transform +# define HASH_FINAL SHA_Final +# define HASH_INIT SHA_Init +# define HASH_BLOCK_DATA_ORDER sha_block_data_order +# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id)) + +static void sha_block_data_order(SHA_CTX *c, const void *p, size_t num); + +#elif defined(SHA_1) + +# define HASH_UPDATE SHA1_Update +# define HASH_TRANSFORM SHA1_Transform +# define HASH_FINAL SHA1_Final +# define HASH_INIT SHA1_Init +# define HASH_BLOCK_DATA_ORDER sha1_block_data_order +# if defined(__MWERKS__) && defined(__MC68K__) + /* Metrowerks for Motorola fails otherwise:-( */ +# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \ + ix=(a)=ROTATE((a),1); \ + } while (0) +# else +# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \ + ix=(a)=ROTATE((a),1) \ + ) +# endif + +# ifndef SHA1_ASM +static +# endif +void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num); + +#else +# error "Either SHA_0 or SHA_1 must be defined." +#endif + +#include "md32_common.h" + +#define INIT_DATA_h0 0x67452301UL +#define INIT_DATA_h1 0xefcdab89UL +#define INIT_DATA_h2 0x98badcfeUL +#define INIT_DATA_h3 0x10325476UL +#define INIT_DATA_h4 0xc3d2e1f0UL + +#ifdef SHA_0 +fips_md_init(SHA) +#else +fips_md_init_ctx(SHA1, SHA) +#endif +{ + memset(c, 0, sizeof(*c)); + c->h0 = INIT_DATA_h0; + c->h1 = INIT_DATA_h1; + c->h2 = INIT_DATA_h2; + c->h3 = INIT_DATA_h3; + c->h4 = INIT_DATA_h4; + return 1; +} + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +/* + * As pointed out by Wei Dai , F() below can be simplified + * to the code in F_00_19. Wei attributes these optimisations to Peter + * Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define + * F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another + * tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a + */ +#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) +#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) +#define F_60_79(b,c,d) F_20_39(b,c,d) + +#ifndef OPENSSL_SMALL_FOOTPRINT + +# define BODY_00_15(i,a,b,c,d,e,f,xi) \ + (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# ifdef X +# undef X +# endif +# ifndef MD32_XARRAY + /* + * Originally X was an array. As it's automatic it's natural + * to expect RISC compiler to accomodate at least part of it in + * the register bank, isn't it? Unfortunately not all compilers + * "find" this expectation reasonable:-( On order to make such + * compilers generate better code I replace X[] with a bunch of + * X0, X1, etc. See the function body below... + * + */ +# define X(i) XX##i +# else + /* + * However! Some compilers (most notably HP C) get overwhelmed by + * that many local variables so that we have to have the way to + * fall down to the original behavior. + */ +# define X(i) XX[i] +# endif + +# if !defined(SHA_1) || !defined(SHA1_ASM) +static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) +{ + const unsigned char *data = p; + register unsigned MD32_REG_T A, B, C, D, E, T, l; +# ifndef MD32_XARRAY + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# else + SHA_LONG XX[16]; +# endif + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + const union { + long one; + char little; + } is_endian = { + 1 + }; + + if (!is_endian.little && sizeof(SHA_LONG) == 4 + && ((size_t)p % 4) == 0) { + const SHA_LONG *W = (const SHA_LONG *)data; + + X(0) = W[0]; + X(1) = W[1]; + BODY_00_15(0, A, B, C, D, E, T, X(0)); + X(2) = W[2]; + BODY_00_15(1, T, A, B, C, D, E, X(1)); + X(3) = W[3]; + BODY_00_15(2, E, T, A, B, C, D, X(2)); + X(4) = W[4]; + BODY_00_15(3, D, E, T, A, B, C, X(3)); + X(5) = W[5]; + BODY_00_15(4, C, D, E, T, A, B, X(4)); + X(6) = W[6]; + BODY_00_15(5, B, C, D, E, T, A, X(5)); + X(7) = W[7]; + BODY_00_15(6, A, B, C, D, E, T, X(6)); + X(8) = W[8]; + BODY_00_15(7, T, A, B, C, D, E, X(7)); + X(9) = W[9]; + BODY_00_15(8, E, T, A, B, C, D, X(8)); + X(10) = W[10]; + BODY_00_15(9, D, E, T, A, B, C, X(9)); + X(11) = W[11]; + BODY_00_15(10, C, D, E, T, A, B, X(10)); + X(12) = W[12]; + BODY_00_15(11, B, C, D, E, T, A, X(11)); + X(13) = W[13]; + BODY_00_15(12, A, B, C, D, E, T, X(12)); + X(14) = W[14]; + BODY_00_15(13, T, A, B, C, D, E, X(13)); + X(15) = W[15]; + BODY_00_15(14, E, T, A, B, C, D, X(14)); + BODY_00_15(15, D, E, T, A, B, C, X(15)); + + data += SHA_CBLOCK; + } else { + (void)HOST_c2l(data, l); + X(0) = l; + (void)HOST_c2l(data, l); + X(1) = l; + BODY_00_15(0, A, B, C, D, E, T, X(0)); + (void)HOST_c2l(data, l); + X(2) = l; + BODY_00_15(1, T, A, B, C, D, E, X(1)); + (void)HOST_c2l(data, l); + X(3) = l; + BODY_00_15(2, E, T, A, B, C, D, X(2)); + (void)HOST_c2l(data, l); + X(4) = l; + BODY_00_15(3, D, E, T, A, B, C, X(3)); + (void)HOST_c2l(data, l); + X(5) = l; + BODY_00_15(4, C, D, E, T, A, B, X(4)); + (void)HOST_c2l(data, l); + X(6) = l; + BODY_00_15(5, B, C, D, E, T, A, X(5)); + (void)HOST_c2l(data, l); + X(7) = l; + BODY_00_15(6, A, B, C, D, E, T, X(6)); + (void)HOST_c2l(data, l); + X(8) = l; + BODY_00_15(7, T, A, B, C, D, E, X(7)); + (void)HOST_c2l(data, l); + X(9) = l; + BODY_00_15(8, E, T, A, B, C, D, X(8)); + (void)HOST_c2l(data, l); + X(10) = l; + BODY_00_15(9, D, E, T, A, B, C, X(9)); + (void)HOST_c2l(data, l); + X(11) = l; + BODY_00_15(10, C, D, E, T, A, B, X(10)); + (void)HOST_c2l(data, l); + X(12) = l; + BODY_00_15(11, B, C, D, E, T, A, X(11)); + (void)HOST_c2l(data, l); + X(13) = l; + BODY_00_15(12, A, B, C, D, E, T, X(12)); + (void)HOST_c2l(data, l); + X(14) = l; + BODY_00_15(13, T, A, B, C, D, E, X(13)); + (void)HOST_c2l(data, l); + X(15) = l; + BODY_00_15(14, E, T, A, B, C, D, X(14)); + BODY_00_15(15, D, E, T, A, B, C, X(15)); + } + + BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13)); + BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14)); + BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15)); + BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0)); + + BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1)); + BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2)); + BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3)); + BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4)); + BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5)); + BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6)); + BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7)); + BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8)); + BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9)); + BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10)); + BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11)); + BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12)); + + BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13)); + BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14)); + BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15)); + BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0)); + BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1)); + BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2)); + BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3)); + BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4)); + + BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5)); + BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6)); + BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7)); + BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8)); + BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9)); + BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10)); + BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11)); + BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12)); + BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13)); + BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14)); + BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15)); + BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0)); + BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1)); + BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2)); + BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3)); + BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4)); + BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5)); + BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6)); + BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7)); + BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8)); + + BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9)); + BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10)); + BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11)); + BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12)); + BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13)); + BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14)); + BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15)); + BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0)); + BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1)); + BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2)); + BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3)); + BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4)); + BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5)); + BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6)); + BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7)); + BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8)); + BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9)); + BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10)); + BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11)); + BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12)); + + c->h0 = (c->h0 + E) & 0xffffffffL; + c->h1 = (c->h1 + T) & 0xffffffffL; + c->h2 = (c->h2 + A) & 0xffffffffL; + c->h3 = (c->h3 + B) & 0xffffffffL; + c->h4 = (c->h4 + C) & 0xffffffffL; + + if (--num == 0) + break; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + } +} +# endif + +#else /* OPENSSL_SMALL_FOOTPRINT */ + +# define BODY_00_15(xi) do { \ + T=E+K_00_19+F_00_19(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T+xi; } while(0) + +# define BODY_16_19(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_00_19+F_00_19(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +# define BODY_20_39(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_20_39+F_20_39(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +# define BODY_40_59(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_40_59+F_40_59(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +# define BODY_60_79(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T=E+K_60_79+F_60_79(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T+xa; } while(0) + +# if !defined(SHA_1) || !defined(SHA1_ASM) +static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) +{ + const unsigned char *data = p; + register unsigned MD32_REG_T A, B, C, D, E, T, l; + int i; + SHA_LONG X[16]; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + for (i = 0; i < 16; i++) { + HOST_c2l(data, l); + X[i] = l; + BODY_00_15(X[i]); + } + for (i = 0; i < 4; i++) { + BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]); + } + for (; i < 24; i++) { + BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15], + X[(i + 13) & 15]); + } + for (i = 0; i < 20; i++) { + BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], + X[(i + 5) & 15]); + } + for (i = 4; i < 24; i++) { + BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], + X[(i + 5) & 15]); + } + + c->h0 = (c->h0 + A) & 0xffffffffL; + c->h1 = (c->h1 + B) & 0xffffffffL; + c->h2 = (c->h2 + C) & 0xffffffffL; + c->h3 = (c->h3 + D) & 0xffffffffL; + c->h4 = (c->h4 + E) & 0xffffffffL; + + if (--num == 0) + break; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + } +} +# endif + +#endif diff --git a/Sources/COpenSSL/spr.h b/Sources/COpenSSL/spr.h new file mode 100644 index 00000000..e85d3100 --- /dev/null +++ b/Sources/COpenSSL/spr.h @@ -0,0 +1,212 @@ +/* crypto/des/spr.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64] = { + { + /* nibble 0 */ + 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, + 0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, + 0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, + 0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, + 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, + 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, + 0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, + 0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, + 0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, + 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, + 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, + 0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, + 0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, + 0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, + 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, + 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, + }, + { + /* nibble 1 */ + 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, + 0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, + 0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, + 0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, + 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, + 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, + 0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, + 0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, + 0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, + 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, + 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, + 0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, + 0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, + 0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, + 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, + 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, + }, + { + /* nibble 2 */ + 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, + 0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, + 0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, + 0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, + 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, + 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, + 0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, + 0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, + 0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, + 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, + 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, + 0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, + 0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, + 0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, + 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, + 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, + }, + { + /* nibble 3 */ + 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, + 0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, + 0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, + 0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, + 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, + 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, + 0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, + 0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, + 0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, + 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, + 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, + 0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, + 0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, + 0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, + 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, + 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, + }, + { + /* nibble 4 */ + 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, + 0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, + 0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, + 0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, + 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, + 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, + 0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, + 0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, + 0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, + 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, + 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, + 0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, + 0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, + 0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, + 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, + 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, + }, + { + /* nibble 5 */ + 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, + 0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, + 0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, + 0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, + 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, + 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, + 0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, + 0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, + 0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, + 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, + 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, + 0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, + 0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, + 0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, + 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, + 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, + }, + { + /* nibble 6 */ + 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, + 0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, + 0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, + 0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, + 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, + 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, + 0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, + 0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, + 0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, + 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, + 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, + 0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, + 0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, + 0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, + 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, + 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, + }, + { + /* nibble 7 */ + 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, + 0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, + 0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, + 0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, + 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, + 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, + 0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, + 0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, + 0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, + 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, + 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, + 0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, + 0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, + 0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, + 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, + 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, + } +}; diff --git a/Sources/COpenSSL/srp.h b/Sources/COpenSSL/srp.h new file mode 100644 index 00000000..20816b67 --- /dev/null +++ b/Sources/COpenSSL/srp.h @@ -0,0 +1,179 @@ +/* crypto/srp/srp.h */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef __SRP_H__ +# define __SRP_H__ + +# ifndef OPENSSL_NO_SRP + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# include "safestack.h" +# include "bn.h" +# include "crypto.h" + +typedef struct SRP_gN_cache_st { + char *b64_bn; + BIGNUM *bn; +} SRP_gN_cache; + + +DECLARE_STACK_OF(SRP_gN_cache) + +typedef struct SRP_user_pwd_st { + /* Owned by us. */ + char *id; + BIGNUM *s; + BIGNUM *v; + /* Not owned by us. */ + const BIGNUM *g; + const BIGNUM *N; + /* Owned by us. */ + char *info; +} SRP_user_pwd; + +DECLARE_STACK_OF(SRP_user_pwd) + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd); + +typedef struct SRP_VBASE_st { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + BIGNUM *default_g; + BIGNUM *default_N; +} SRP_VBASE; + +/* + * Structure interne pour retenir les couples N et g + */ +typedef struct SRP_gN_st { + char *id; + BIGNUM *g; + BIGNUM *N; +} SRP_gN; + +DECLARE_STACK_OF(SRP_gN) + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +int SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file); + +/* This method ignores the configured seed and fails for an unknown user. */ +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username); +/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); + +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, BIGNUM *N, BIGNUM *g); + +# define SRP_NO_ERROR 0 +# define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +# define SRP_ERR_VBASE_BN_LIB 2 +# define SRP_ERR_OPEN_FILE 3 +# define SRP_ERR_MEMORY 4 + +# define DB_srptype 0 +# define DB_srpverifier 1 +# define DB_srpsalt 2 +# define DB_srpid 3 +# define DB_srpgN 4 +# define DB_srpinfo 5 +# undef DB_NUMBER +# define DB_NUMBER 6 + +# define DB_SRP_INDEX 'I' +# define DB_SRP_VALID 'V' +# define DB_SRP_REVOKED 'R' +# define DB_SRP_MODIF 'v' + +/* see srp.c */ +char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N); +SRP_gN *SRP_get_default_gN(const char *id); + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, + BIGNUM *N); +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v); +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N); +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N); + +/* client side .... */ +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g); +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, + BIGNUM *a, BIGNUM *u); +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N); + +# define SRP_MINIMAL_N 1024 + +#ifdef __cplusplus +} +#endif + +# endif +#endif diff --git a/Sources/COpenSSL/srp_.c b/Sources/COpenSSL/srp_.c new file mode 100644 index 00000000..d824ba05 --- /dev/null +++ b/Sources/COpenSSL/srp_.c @@ -0,0 +1,1090 @@ +/* crypto/srp/srp_lib.c */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_SRP +# include "cryptlib.h" +# include "srp_lcl.h" +# include "srp.h" +# include "evp.h" + +# if (BN_BYTES == 8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define bn_pack4(a1,a2,a3,a4) ((a1##UI64<<48)|(a2##UI64<<32)|(a3##UI64<<16)|a4##UI64) +# elif defined(__arch64__) +# define bn_pack4(a1,a2,a3,a4) ((a1##UL<<48)|(a2##UL<<32)|(a3##UL<<16)|a4##UL) +# else +# define bn_pack4(a1,a2,a3,a4) ((a1##ULL<<48)|(a2##ULL<<32)|(a3##ULL<<16)|a4##ULL) +# endif +# elif (BN_BYTES == 4) +# define bn_pack4(a1,a2,a3,a4) ((a3##UL<<16)|a4##UL), ((a1##UL<<16)|a2##UL) +# else +# error "unsupported BN_BYTES" +# endif + +# include "srp_grps.h" + +static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g) +{ + /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */ + + unsigned char digest[SHA_DIGEST_LENGTH]; + unsigned char *tmp; + EVP_MD_CTX ctxt; + int longg; + int longN = BN_num_bytes(N); + + if (BN_ucmp(g, N) >= 0) + return NULL; + + if ((tmp = OPENSSL_malloc(longN)) == NULL) + return NULL; + BN_bn2bin(N, tmp); + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, tmp, longN); + + memset(tmp, 0, longN); + longg = BN_bn2bin(g, tmp); + /* use the zeros behind to pad on left */ + EVP_DigestUpdate(&ctxt, tmp + longg, longN - longg); + EVP_DigestUpdate(&ctxt, tmp, longg); + OPENSSL_free(tmp); + + EVP_DigestFinal_ex(&ctxt, digest, NULL); + EVP_MD_CTX_cleanup(&ctxt); + return BN_bin2bn(digest, sizeof(digest), NULL); +} + +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) +{ + /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */ + + BIGNUM *u; + unsigned char cu[SHA_DIGEST_LENGTH]; + unsigned char *cAB; + EVP_MD_CTX ctxt; + int longN; + if ((A == NULL) || (B == NULL) || (N == NULL)) + return NULL; + + if (BN_ucmp(A, N) >= 0 || BN_ucmp(B, N) >= 0) + return NULL; + + longN = BN_num_bytes(N); + + if ((cAB = OPENSSL_malloc(2 * longN)) == NULL) + return NULL; + + memset(cAB, 0, longN); + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A, cAB + longN), longN); + EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B, cAB + longN), longN); + OPENSSL_free(cAB); + EVP_DigestFinal_ex(&ctxt, cu, NULL); + EVP_MD_CTX_cleanup(&ctxt); + + if (!(u = BN_bin2bn(cu, sizeof(cu), NULL))) + return NULL; + if (!BN_is_zero(u)) + return u; + BN_free(u); + return NULL; +} + +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, + BIGNUM *N) +{ + BIGNUM *tmp = NULL, *S = NULL; + BN_CTX *bn_ctx; + + if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL) + return NULL; + + if ((bn_ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL) + goto err; + + /* S = (A*v**u) ** b */ + + if (!BN_mod_exp(tmp, v, u, N, bn_ctx)) + goto err; + if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx)) + goto err; + + S = BN_new(); + if (S != NULL && !BN_mod_exp(S, tmp, b, N, bn_ctx)) { + BN_free(S); + S = NULL; + } + err: + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + return S; +} + +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v) +{ + BIGNUM *kv = NULL, *gb = NULL; + BIGNUM *B = NULL, *k = NULL; + BN_CTX *bn_ctx; + + if (b == NULL || N == NULL || g == NULL || v == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((kv = BN_new()) == NULL || + (gb = BN_new()) == NULL || (B = BN_new()) == NULL) + goto err; + + /* B = g**b + k*v */ + + if (!BN_mod_exp(gb, g, b, N, bn_ctx) || + !(k = srp_Calc_k(N, g)) || + !BN_mod_mul(kv, v, k, N, bn_ctx) || + !BN_mod_add(B, gb, kv, N, bn_ctx)) { + BN_free(B); + B = NULL; + } + err: + BN_CTX_free(bn_ctx); + BN_clear_free(kv); + BN_clear_free(gb); + BN_free(k); + return B; +} + +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass) +{ + unsigned char dig[SHA_DIGEST_LENGTH]; + EVP_MD_CTX ctxt; + unsigned char *cs; + + if ((s == NULL) || (user == NULL) || (pass == NULL)) + return NULL; + + if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL) + return NULL; + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, user, strlen(user)); + EVP_DigestUpdate(&ctxt, ":", 1); + EVP_DigestUpdate(&ctxt, pass, strlen(pass)); + EVP_DigestFinal_ex(&ctxt, dig, NULL); + + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + BN_bn2bin(s, cs); + EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s)); + OPENSSL_free(cs); + EVP_DigestUpdate(&ctxt, dig, sizeof(dig)); + EVP_DigestFinal_ex(&ctxt, dig, NULL); + EVP_MD_CTX_cleanup(&ctxt); + + return BN_bin2bn(dig, sizeof(dig), NULL); +} + +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g) +{ + BN_CTX *bn_ctx; + BIGNUM *A = NULL; + + if (a == NULL || N == NULL || g == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((A = BN_new()) != NULL && !BN_mod_exp(A, g, a, N, bn_ctx)) { + BN_free(A); + A = NULL; + } + BN_CTX_free(bn_ctx); + return A; +} + +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, + BIGNUM *a, BIGNUM *u) +{ + BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL; + BN_CTX *bn_ctx; + + if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL + || a == NULL || (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((tmp = BN_new()) == NULL || + (tmp2 = BN_new()) == NULL || + (tmp3 = BN_new()) == NULL) + goto err; + + if (!BN_mod_exp(tmp, g, x, N, bn_ctx)) + goto err; + if (!(k = srp_Calc_k(N, g))) + goto err; + if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx)) + goto err; + if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx)) + goto err; + + if (!BN_mul(tmp3, u, x, bn_ctx)) + goto err; + if (!BN_add(tmp2, a, tmp3)) + goto err; + K = BN_new(); + if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) { + BN_free(K); + K = NULL; + } + + err: + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + BN_clear_free(tmp2); + BN_clear_free(tmp3); + BN_free(k); + return K; +} + +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N) +{ + BIGNUM *r; + BN_CTX *bn_ctx; + int ret = 0; + + if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL) + return 0; + + if ((r = BN_new()) == NULL) + goto err; + /* Checks if B % N == 0 */ + if (!BN_nnmod(r, B, N, bn_ctx)) + goto err; + ret = !BN_is_zero(r); + err: + BN_CTX_free(bn_ctx); + BN_free(r); + return ret; +} + +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N) +{ + /* Checks if A % N == 0 */ + return SRP_Verify_B_mod_N(A, N); +} + +/* + * Check if G and N are kwown parameters. The values have been generated + * from the ietf-tls-srp draft version 8 + */ +char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N) +{ + size_t i; + if ((g == NULL) || (N == NULL)) + return 0; + + srp_bn_print(g); + srp_bn_print(N); + + for (i = 0; i < KNOWN_GN_NUMBER; i++) { + if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0) + return knowngN[i].id; + } + return NULL; +} + +SRP_gN *SRP_get_default_gN(const char *id) +{ + size_t i; + + if (id == NULL) + return knowngN; + for (i = 0; i < KNOWN_GN_NUMBER; i++) { + if (strcmp(knowngN[i].id, id) == 0) + return knowngN + i; + } + return NULL; +} +#endif +/* crypto/srp/srp_vfy.c */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_SRP +# include "cryptlib.h" +# include "srp_lcl.h" +# include "srp.h" +# include "evp.h" +# include "buffer.h" +# include "rand.h" +# include "txt_db.h" + +# define SRP_RANDOM_SALT_LEN 20 +# define MAX_LEN 2500 + +static char b64table[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; + +/* + * the following two conversion routines have been inspired by code from + * Stanford + */ + +/* + * Convert a base64 string into raw byte array representation. + */ +static int t_fromb64(unsigned char *a, size_t alen, const char *src) +{ + char *loc; + int i, j; + int size; + + if (alen == 0 || alen > INT_MAX) + return -1; + + while (*src && (*src == ' ' || *src == '\t' || *src == '\n')) + ++src; + size = strlen(src); + if (size < 0 || size >= (int)alen) + return -1; + + i = 0; + while (i < size) { + loc = strchr(b64table, src[i]); + if (loc == (char *)0) + break; + else + a[i] = loc - b64table; + ++i; + } + /* if nothing valid to process we have a zero length response */ + if (i == 0) + return 0; + size = i; + i = size - 1; + j = size; + while (1) { + a[j] = a[i]; + if (--i < 0) + break; + a[j] |= (a[i] & 3) << 6; + --j; + a[j] = (unsigned char)((a[i] & 0x3c) >> 2); + if (--i < 0) + break; + a[j] |= (a[i] & 0xf) << 4; + --j; + a[j] = (unsigned char)((a[i] & 0x30) >> 4); + if (--i < 0) + break; + a[j] |= (a[i] << 2); + + a[--j] = 0; + if (--i < 0) + break; + } + while (j <= size && a[j] == 0) + ++j; + i = 0; + while (j <= size) + a[i++] = a[j++]; + return i; +} + +/* + * Convert a raw byte string into a null-terminated base64 ASCII string. + */ +static char *t_tob64(char *dst, const unsigned char *src, int size) +{ + int c, pos = size % 3; + unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0; + char *olddst = dst; + + switch (pos) { + case 1: + b2 = src[0]; + break; + case 2: + b1 = src[0]; + b2 = src[1]; + break; + } + + while (1) { + c = (b0 & 0xfc) >> 2; + if (notleading || c != 0) { + *dst++ = b64table[c]; + notleading = 1; + } + c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4); + if (notleading || c != 0) { + *dst++ = b64table[c]; + notleading = 1; + } + c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6); + if (notleading || c != 0) { + *dst++ = b64table[c]; + notleading = 1; + } + c = b2 & 0x3f; + if (notleading || c != 0) { + *dst++ = b64table[c]; + notleading = 1; + } + if (pos >= size) + break; + else { + b0 = src[pos++]; + b1 = src[pos++]; + b2 = src[pos++]; + } + } + + *dst++ = '\0'; + return olddst; +} + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd) +{ + if (user_pwd == NULL) + return; + BN_free(user_pwd->s); + BN_clear_free(user_pwd->v); + OPENSSL_free(user_pwd->id); + OPENSSL_free(user_pwd->info); + OPENSSL_free(user_pwd); +} + +static SRP_user_pwd *SRP_user_pwd_new() +{ + SRP_user_pwd *ret = OPENSSL_malloc(sizeof(SRP_user_pwd)); + if (ret == NULL) + return NULL; + ret->N = NULL; + ret->g = NULL; + ret->s = NULL; + ret->v = NULL; + ret->id = NULL; + ret->info = NULL; + return ret; +} + +static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g, + const BIGNUM *N) +{ + vinfo->N = N; + vinfo->g = g; +} + +static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id, + const char *info) +{ + if (id != NULL && NULL == (vinfo->id = BUF_strdup(id))) + return 0; + return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))); +} + +static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s, + const char *v) +{ + unsigned char tmp[MAX_LEN]; + int len; + + vinfo->v = NULL; + vinfo->s = NULL; + + len = t_fromb64(tmp, sizeof(tmp), v); + if (len < 0) + return 0; + if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL))) + return 0; + len = t_fromb64(tmp, sizeof(tmp), s); + if (len < 0) + goto err; + vinfo->s = BN_bin2bn(tmp, len, NULL); + if (vinfo->s == NULL) + goto err; + return 1; + err: + BN_free(vinfo->v); + vinfo->v = NULL; + return 0; +} + +static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v) +{ + vinfo->v = v; + vinfo->s = s; + return (vinfo->s != NULL && vinfo->v != NULL); +} + +static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src) +{ + SRP_user_pwd *ret; + + if (src == NULL) + return NULL; + if ((ret = SRP_user_pwd_new()) == NULL) + return NULL; + + SRP_user_pwd_set_gN(ret, src->g, src->N); + if (!SRP_user_pwd_set_ids(ret, src->id, src->info) + || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) { + SRP_user_pwd_free(ret); + return NULL; + } + return ret; +} + +SRP_VBASE *SRP_VBASE_new(char *seed_key) +{ + SRP_VBASE *vb = (SRP_VBASE *)OPENSSL_malloc(sizeof(SRP_VBASE)); + + if (vb == NULL) + return NULL; + if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) || + !(vb->gN_cache = sk_SRP_gN_cache_new_null())) { + OPENSSL_free(vb); + return NULL; + } + vb->default_g = NULL; + vb->default_N = NULL; + vb->seed_key = NULL; + if ((seed_key != NULL) && (vb->seed_key = BUF_strdup(seed_key)) == NULL) { + sk_SRP_user_pwd_free(vb->users_pwd); + sk_SRP_gN_cache_free(vb->gN_cache); + OPENSSL_free(vb); + return NULL; + } + return vb; +} + +int SRP_VBASE_free(SRP_VBASE *vb) +{ + sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free); + sk_SRP_gN_cache_free(vb->gN_cache); + OPENSSL_free(vb->seed_key); + OPENSSL_free(vb); + return 0; +} + +static SRP_gN_cache *SRP_gN_new_init(const char *ch) +{ + unsigned char tmp[MAX_LEN]; + int len; + + SRP_gN_cache *newgN = + (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache)); + if (newgN == NULL) + return NULL; + + len = t_fromb64(tmp, sizeof(tmp), ch); + if (len < 0) + goto err; + + if ((newgN->b64_bn = BUF_strdup(ch)) == NULL) + goto err; + + if ((newgN->bn = BN_bin2bn(tmp, len, NULL))) + return newgN; + + OPENSSL_free(newgN->b64_bn); + err: + OPENSSL_free(newgN); + return NULL; +} + +static void SRP_gN_free(SRP_gN_cache *gN_cache) +{ + if (gN_cache == NULL) + return; + OPENSSL_free(gN_cache->b64_bn); + BN_free(gN_cache->bn); + OPENSSL_free(gN_cache); +} + +static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab) +{ + int i; + + SRP_gN *gN; + if (gN_tab != NULL) + for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) { + gN = sk_SRP_gN_value(gN_tab, i); + if (gN && (id == NULL || strcmp(gN->id, id) == 0)) + return gN; + } + + return SRP_get_default_gN(id); +} + +static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch) +{ + int i; + if (gN_cache == NULL) + return NULL; + + /* search if we have already one... */ + for (i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) { + SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i); + if (strcmp(cache->b64_bn, ch) == 0) + return cache->bn; + } + { /* it is the first time that we find it */ + SRP_gN_cache *newgN = SRP_gN_new_init(ch); + if (newgN) { + if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0) + return newgN->bn; + SRP_gN_free(newgN); + } + } + return NULL; +} + +/* + * this function parses verifier file. Format is: + * string(index):base64(N):base64(g):0 + * string(username):base64(v):base64(salt):int(index) + */ + +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) +{ + int error_code; + STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null(); + char *last_index = NULL; + int i; + char **pp; + + SRP_gN *gN = NULL; + SRP_user_pwd *user_pwd = NULL; + + TXT_DB *tmpdb = NULL; + BIO *in = BIO_new(BIO_s_file()); + + error_code = SRP_ERR_OPEN_FILE; + + if (in == NULL || BIO_read_filename(in, verifier_file) <= 0) + goto err; + + error_code = SRP_ERR_VBASE_INCOMPLETE_FILE; + + if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) + goto err; + + error_code = SRP_ERR_MEMORY; + + if (vb->seed_key) { + last_index = SRP_get_default_gN(NULL)->id; + } + for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) { + pp = sk_OPENSSL_PSTRING_value(tmpdb->data, i); + if (pp[DB_srptype][0] == DB_SRP_INDEX) { + /* + * we add this couple in the internal Stack + */ + + if ((gN = (SRP_gN *) OPENSSL_malloc(sizeof(SRP_gN))) == NULL) + goto err; + + if (!(gN->id = BUF_strdup(pp[DB_srpid])) + || !(gN->N = + SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier])) + || !(gN->g = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpsalt])) + || sk_SRP_gN_insert(SRP_gN_tab, gN, 0) == 0) + goto err; + + gN = NULL; + + if (vb->seed_key != NULL) { + last_index = pp[DB_srpid]; + } + } else if (pp[DB_srptype][0] == DB_SRP_VALID) { + /* it is a user .... */ + SRP_gN *lgN; + if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN], SRP_gN_tab)) != NULL) { + error_code = SRP_ERR_MEMORY; + if ((user_pwd = SRP_user_pwd_new()) == NULL) + goto err; + + SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N); + if (!SRP_user_pwd_set_ids + (user_pwd, pp[DB_srpid], pp[DB_srpinfo])) + goto err; + + error_code = SRP_ERR_VBASE_BN_LIB; + if (!SRP_user_pwd_set_sv + (user_pwd, pp[DB_srpsalt], pp[DB_srpverifier])) + goto err; + + if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0) + goto err; + user_pwd = NULL; /* abandon responsability */ + } + } + } + + if (last_index != NULL) { + /* this means that we want to simulate a default user */ + + if (((gN = SRP_get_gN_by_id(last_index, SRP_gN_tab)) == NULL)) { + error_code = SRP_ERR_VBASE_BN_LIB; + goto err; + } + vb->default_g = gN->g; + vb->default_N = gN->N; + gN = NULL; + } + error_code = SRP_NO_ERROR; + + err: + /* + * there may be still some leaks to fix, if this fails, the application + * terminates most likely + */ + + if (gN != NULL) { + OPENSSL_free(gN->id); + OPENSSL_free(gN); + } + + SRP_user_pwd_free(user_pwd); + + if (tmpdb) + TXT_DB_free(tmpdb); + if (in) + BIO_free_all(in); + + sk_SRP_gN_free(SRP_gN_tab); + + return error_code; + +} + +static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username) +{ + int i; + SRP_user_pwd *user; + + if (vb == NULL) + return NULL; + + for (i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) { + user = sk_SRP_user_pwd_value(vb->users_pwd, i); + if (strcmp(user->id, username) == 0) + return user; + } + + return NULL; +} + +/* + * This method ignores the configured seed and fails for an unknown user. + * Ownership of the returned pointer is not released to the caller. + * In other words, caller must not free the result. + */ +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username) +{ + return find_user(vb, username); +} + +/* + * Ownership of the returned pointer is released to the caller. + * In other words, caller must free the result once done. + */ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) +{ + SRP_user_pwd *user; + unsigned char digv[SHA_DIGEST_LENGTH]; + unsigned char digs[SHA_DIGEST_LENGTH]; + EVP_MD_CTX ctxt; + + if (vb == NULL) + return NULL; + + if ((user = find_user(vb, username)) != NULL) + return srp_user_pwd_dup(user); + + if ((vb->seed_key == NULL) || + (vb->default_g == NULL) || (vb->default_N == NULL)) + return NULL; + +/* if the user is unknown we set parameters as well if we have a seed_key */ + + if ((user = SRP_user_pwd_new()) == NULL) + return NULL; + + SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N); + + if (!SRP_user_pwd_set_ids(user, username, NULL)) + goto err; + + if (RAND_bytes(digv, SHA_DIGEST_LENGTH) <= 0) + goto err; + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key)); + EVP_DigestUpdate(&ctxt, username, strlen(username)); + EVP_DigestFinal_ex(&ctxt, digs, NULL); + EVP_MD_CTX_cleanup(&ctxt); + if (SRP_user_pwd_set_sv_BN + (user, BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL), + BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL))) + return user; + + err:SRP_user_pwd_free(user); + return NULL; +} + +/* + * create a verifier (*salt,*verifier,g and N are in base64) + */ +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g) +{ + int len; + char *result = NULL, *vf = NULL; + BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL; + unsigned char tmp[MAX_LEN]; + unsigned char tmp2[MAX_LEN]; + char *defgNid = NULL; + int vfsize = 0; + + if ((user == NULL) || + (pass == NULL) || (salt == NULL) || (verifier == NULL)) + goto err; + + if (N) { + if (!(len = t_fromb64(tmp, sizeof(tmp), N))) + goto err; + N_bn = BN_bin2bn(tmp, len, NULL); + if (!(len = t_fromb64(tmp, sizeof(tmp), g))) + goto err; + g_bn = BN_bin2bn(tmp, len, NULL); + defgNid = "*"; + } else { + SRP_gN *gN = SRP_get_gN_by_id(g, NULL); + if (gN == NULL) + goto err; + N_bn = gN->N; + g_bn = gN->g; + defgNid = gN->id; + } + + if (*salt == NULL) { + if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) + goto err; + + s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); + } else { + if (!(len = t_fromb64(tmp2, sizeof(tmp2), *salt))) + goto err; + s = BN_bin2bn(tmp2, len, NULL); + } + + if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) + goto err; + + BN_bn2bin(v, tmp); + vfsize = BN_num_bytes(v) * 2; + if (((vf = OPENSSL_malloc(vfsize)) == NULL)) + goto err; + t_tob64(vf, tmp, BN_num_bytes(v)); + + if (*salt == NULL) { + char *tmp_salt; + + if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) { + goto err; + } + t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN); + *salt = tmp_salt; + } + + *verifier = vf; + vf = NULL; + result = defgNid; + + err: + if (N) { + BN_free(N_bn); + BN_free(g_bn); + } + if (vf != NULL) + OPENSSL_cleanse(vf, vfsize); + OPENSSL_free(vf); + BN_clear_free(s); + BN_clear_free(v); + return result; +} + +/* + * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL + * then the provided salt will be used. On successful exit *verifier will point + * to a newly allocated BIGNUM containing the verifier and (if a salt was not + * provided) *salt will be populated with a newly allocated BIGNUM containing a + * random salt. + * The caller is responsible for freeing the allocated *salt and *verifier + * BIGNUMS. + */ +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, BIGNUM *N, BIGNUM *g) +{ + int result = 0; + BIGNUM *x = NULL; + BN_CTX *bn_ctx = BN_CTX_new(); + unsigned char tmp2[MAX_LEN]; + BIGNUM *salttmp = NULL; + + if ((user == NULL) || + (pass == NULL) || + (salt == NULL) || + (verifier == NULL) || (N == NULL) || (g == NULL) || (bn_ctx == NULL)) + goto err; + + srp_bn_print(N); + srp_bn_print(g); + + if (*salt == NULL) { + if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) + goto err; + + salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); + } else { + salttmp = *salt; + } + + x = SRP_Calc_x(salttmp, user, pass); + + *verifier = BN_new(); + if (*verifier == NULL) + goto err; + + if (!BN_mod_exp(*verifier, g, x, N, bn_ctx)) { + BN_clear_free(*verifier); + goto err; + } + + srp_bn_print(*verifier); + + result = 1; + *salt = salttmp; + + err: + if (*salt != salttmp) + BN_clear_free(salttmp); + BN_clear_free(x); + BN_CTX_free(bn_ctx); + return result; +} + +#endif diff --git a/Sources/COpenSSL/srp_grps.h b/Sources/COpenSSL/srp_grps.h new file mode 100644 index 00000000..f76652cb --- /dev/null +++ b/Sources/COpenSSL/srp_grps.h @@ -0,0 +1,528 @@ +/* start of generated data */ + +static BN_ULONG bn_group_1024_value[] = { + bn_pack4(0x9FC6, 0x1D2F, 0xC0EB, 0x06E3), + bn_pack4(0xFD51, 0x38FE, 0x8376, 0x435B), + bn_pack4(0x2FD4, 0xCBF4, 0x976E, 0xAA9A), + bn_pack4(0x68ED, 0xBC3C, 0x0572, 0x6CC0), + bn_pack4(0xC529, 0xF566, 0x660E, 0x57EC), + bn_pack4(0x8255, 0x9B29, 0x7BCF, 0x1885), + bn_pack4(0xCE8E, 0xF4AD, 0x69B1, 0x5D49), + bn_pack4(0x5DC7, 0xD7B4, 0x6154, 0xD6B6), + bn_pack4(0x8E49, 0x5C1D, 0x6089, 0xDAD1), + bn_pack4(0xE0D5, 0xD8E2, 0x50B9, 0x8BE4), + bn_pack4(0x383B, 0x4813, 0xD692, 0xC6E0), + bn_pack4(0xD674, 0xDF74, 0x96EA, 0x81D3), + bn_pack4(0x9EA2, 0x314C, 0x9C25, 0x6576), + bn_pack4(0x6072, 0x6187, 0x75FF, 0x3C0B), + bn_pack4(0x9C33, 0xF80A, 0xFA8F, 0xC5E8), + bn_pack4(0xEEAF, 0x0AB9, 0xADB3, 0x8DD6) +}; + +static BIGNUM bn_group_1024 = { + bn_group_1024_value, + (sizeof(bn_group_1024_value)) / sizeof(BN_ULONG), + (sizeof(bn_group_1024_value)) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_1536_value[] = { + bn_pack4(0xCF76, 0xE3FE, 0xD135, 0xF9BB), + bn_pack4(0x1518, 0x0F93, 0x499A, 0x234D), + bn_pack4(0x8CE7, 0xA28C, 0x2442, 0xC6F3), + bn_pack4(0x5A02, 0x1FFF, 0x5E91, 0x479E), + bn_pack4(0x7F8A, 0x2FE9, 0xB8B5, 0x292E), + bn_pack4(0x837C, 0x264A, 0xE3A9, 0xBEB8), + bn_pack4(0xE442, 0x734A, 0xF7CC, 0xB7AE), + bn_pack4(0x6577, 0x2E43, 0x7D6C, 0x7F8C), + bn_pack4(0xDB2F, 0xD53D, 0x24B7, 0xC486), + bn_pack4(0x6EDF, 0x0195, 0x3934, 0x9627), + bn_pack4(0x158B, 0xFD3E, 0x2B9C, 0x8CF5), + bn_pack4(0x764E, 0x3F4B, 0x53DD, 0x9DA1), + bn_pack4(0x4754, 0x8381, 0xDBC5, 0xB1FC), + bn_pack4(0x9B60, 0x9E0B, 0xE3BA, 0xB63D), + bn_pack4(0x8134, 0xB1C8, 0xB979, 0x8914), + bn_pack4(0xDF02, 0x8A7C, 0xEC67, 0xF0D0), + bn_pack4(0x80B6, 0x55BB, 0x9A22, 0xE8DC), + bn_pack4(0x1558, 0x903B, 0xA0D0, 0xF843), + bn_pack4(0x51C6, 0xA94B, 0xE460, 0x7A29), + bn_pack4(0x5F4F, 0x5F55, 0x6E27, 0xCBDE), + bn_pack4(0xBEEE, 0xA961, 0x4B19, 0xCC4D), + bn_pack4(0xDBA5, 0x1DF4, 0x99AC, 0x4C80), + bn_pack4(0xB1F1, 0x2A86, 0x17A4, 0x7BBB), + bn_pack4(0x9DEF, 0x3CAF, 0xB939, 0x277A) +}; + +static BIGNUM bn_group_1536 = { + bn_group_1536_value, + (sizeof(bn_group_1536_value)) / sizeof(BN_ULONG), + (sizeof(bn_group_1536_value)) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_2048_value[] = { + bn_pack4(0x0FA7, 0x111F, 0x9E4A, 0xFF73), + bn_pack4(0x9B65, 0xE372, 0xFCD6, 0x8EF2), + bn_pack4(0x35DE, 0x236D, 0x525F, 0x5475), + bn_pack4(0x94B5, 0xC803, 0xD89F, 0x7AE4), + bn_pack4(0x71AE, 0x35F8, 0xE9DB, 0xFBB6), + bn_pack4(0x2A56, 0x98F3, 0xA8D0, 0xC382), + bn_pack4(0x9CCC, 0x041C, 0x7BC3, 0x08D8), + bn_pack4(0xAF87, 0x4E73, 0x03CE, 0x5329), + bn_pack4(0x6160, 0x2790, 0x04E5, 0x7AE6), + bn_pack4(0x032C, 0xFBDB, 0xF52F, 0xB378), + bn_pack4(0x5EA7, 0x7A27, 0x75D2, 0xECFA), + bn_pack4(0x5445, 0x23B5, 0x24B0, 0xD57D), + bn_pack4(0x5B9D, 0x32E6, 0x88F8, 0x7748), + bn_pack4(0xF1D2, 0xB907, 0x8717, 0x461A), + bn_pack4(0x76BD, 0x207A, 0x436C, 0x6481), + bn_pack4(0xCA97, 0xB43A, 0x23FB, 0x8016), + bn_pack4(0x1D28, 0x1E44, 0x6B14, 0x773B), + bn_pack4(0x7359, 0xD041, 0xD5C3, 0x3EA7), + bn_pack4(0xA80D, 0x740A, 0xDBF4, 0xFF74), + bn_pack4(0x55F9, 0x7993, 0xEC97, 0x5EEA), + bn_pack4(0x2918, 0xA996, 0x2F0B, 0x93B8), + bn_pack4(0x661A, 0x05FB, 0xD5FA, 0xAAE8), + bn_pack4(0xCF60, 0x9517, 0x9A16, 0x3AB3), + bn_pack4(0xE808, 0x3969, 0xEDB7, 0x67B0), + bn_pack4(0xCD7F, 0x48A9, 0xDA04, 0xFD50), + bn_pack4(0xD523, 0x12AB, 0x4B03, 0x310D), + bn_pack4(0x8193, 0xE075, 0x7767, 0xA13D), + bn_pack4(0xA373, 0x29CB, 0xB4A0, 0x99ED), + bn_pack4(0xFC31, 0x9294, 0x3DB5, 0x6050), + bn_pack4(0xAF72, 0xB665, 0x1987, 0xEE07), + bn_pack4(0xF166, 0xDE5E, 0x1389, 0x582F), + bn_pack4(0xAC6B, 0xDB41, 0x324A, 0x9A9B) +}; + +static BIGNUM bn_group_2048 = { + bn_group_2048_value, + (sizeof(bn_group_2048_value)) / sizeof(BN_ULONG), + (sizeof(bn_group_2048_value)) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_3072_value[] = { + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), + bn_pack4(0x4B82, 0xD120, 0xA93A, 0xD2CA), + bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), + bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), + bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), + bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), + bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), + bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), + bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), + bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), + bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), + bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), + bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), + bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), + bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), + bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), + bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), + bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), + bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), + bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), + bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), + bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), + bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), + bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), + bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), + bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), + bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), + bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), + bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), + bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), + bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), + bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), + bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), + bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), + bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), + bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), + bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), + bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), + bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), + bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), + bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), + bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), + bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), + bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), + bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), + bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), + bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) +}; + +static BIGNUM bn_group_3072 = { + bn_group_3072_value, + (sizeof(bn_group_3072_value)) / sizeof(BN_ULONG), + (sizeof(bn_group_3072_value)) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_4096_value[] = { + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), + bn_pack4(0x4DF4, 0x35C9, 0x3406, 0x3199), + bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), + bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), + bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), + bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), + bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), + bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), + bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), + bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), + bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), + bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), + bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), + bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), + bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), + bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), + bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), + bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), + bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), + bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), + bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), + bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), + bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), + bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), + bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), + bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), + bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), + bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), + bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), + bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), + bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), + bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), + bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), + bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), + bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), + bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), + bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), + bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), + bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), + bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), + bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), + bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), + bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), + bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), + bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), + bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), + bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), + bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), + bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), + bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), + bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), + bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), + bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), + bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), + bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), + bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), + bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), + bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), + bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), + bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), + bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), + bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), + bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) +}; + +static BIGNUM bn_group_4096 = { + bn_group_4096_value, + (sizeof(bn_group_4096_value)) / sizeof(BN_ULONG), + (sizeof(bn_group_4096_value)) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_6144_value[] = { + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), + bn_pack4(0xE694, 0xF91E, 0x6DCC, 0x4024), + bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6), + bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE), + bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468), + bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632), + bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C), + bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0), + bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76), + bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328), + bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0), + bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8), + bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA), + bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5), + bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE), + bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3), + bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E), + bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82), + bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6), + bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03), + bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC), + bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF), + bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42), + bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B), + bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B), + bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED), + bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918), + bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831), + bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE), + bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E), + bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD), + bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE), + bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026), + bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492), + bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), + bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), + bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), + bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), + bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), + bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), + bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), + bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), + bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), + bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), + bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), + bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), + bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), + bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), + bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), + bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), + bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), + bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), + bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), + bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), + bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), + bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), + bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), + bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), + bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), + bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), + bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), + bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), + bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), + bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), + bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), + bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), + bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), + bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), + bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), + bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), + bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), + bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), + bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), + bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), + bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), + bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), + bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), + bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), + bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), + bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), + bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), + bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), + bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), + bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), + bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), + bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), + bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), + bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), + bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), + bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), + bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), + bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), + bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), + bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), + bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) +}; + +static BIGNUM bn_group_6144 = { + bn_group_6144_value, + (sizeof(bn_group_6144_value)) / sizeof(BN_ULONG), + (sizeof(bn_group_6144_value)) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_8192_value[] = { + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), + bn_pack4(0x60C9, 0x80DD, 0x98ED, 0xD3DF), + bn_pack4(0xC81F, 0x56E8, 0x80B9, 0x6E71), + bn_pack4(0x9E30, 0x50E2, 0x7656, 0x94DF), + bn_pack4(0x9558, 0xE447, 0x5677, 0xE9AA), + bn_pack4(0xC919, 0x0DA6, 0xFC02, 0x6E47), + bn_pack4(0x889A, 0x002E, 0xD5EE, 0x382B), + bn_pack4(0x4009, 0x438B, 0x481C, 0x6CD7), + bn_pack4(0x3590, 0x46F4, 0xEB87, 0x9F92), + bn_pack4(0xFAF3, 0x6BC3, 0x1ECF, 0xA268), + bn_pack4(0xB1D5, 0x10BD, 0x7EE7, 0x4D73), + bn_pack4(0xF9AB, 0x4819, 0x5DED, 0x7EA1), + bn_pack4(0x64F3, 0x1CC5, 0x0846, 0x851D), + bn_pack4(0x4597, 0xE899, 0xA025, 0x5DC1), + bn_pack4(0xDF31, 0x0EE0, 0x74AB, 0x6A36), + bn_pack4(0x6D2A, 0x13F8, 0x3F44, 0xF82D), + bn_pack4(0x062B, 0x3CF5, 0xB3A2, 0x78A6), + bn_pack4(0x7968, 0x3303, 0xED5B, 0xDD3A), + bn_pack4(0xFA9D, 0x4B7F, 0xA2C0, 0x87E8), + bn_pack4(0x4BCB, 0xC886, 0x2F83, 0x85DD), + bn_pack4(0x3473, 0xFC64, 0x6CEA, 0x306B), + bn_pack4(0x13EB, 0x57A8, 0x1A23, 0xF0C7), + bn_pack4(0x2222, 0x2E04, 0xA403, 0x7C07), + bn_pack4(0xE3FD, 0xB8BE, 0xFC84, 0x8AD9), + bn_pack4(0x238F, 0x16CB, 0xE39D, 0x652D), + bn_pack4(0x3423, 0xB474, 0x2BF1, 0xC978), + bn_pack4(0x3AAB, 0x639C, 0x5AE4, 0xF568), + bn_pack4(0x2576, 0xF693, 0x6BA4, 0x2466), + bn_pack4(0x741F, 0xA7BF, 0x8AFC, 0x47ED), + bn_pack4(0x3BC8, 0x32B6, 0x8D9D, 0xD300), + bn_pack4(0xD8BE, 0xC4D0, 0x73B9, 0x31BA), + bn_pack4(0x3877, 0x7CB6, 0xA932, 0xDF8C), + bn_pack4(0x74A3, 0x926F, 0x12FE, 0xE5E4), + bn_pack4(0xE694, 0xF91E, 0x6DBE, 0x1159), + bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6), + bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE), + bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468), + bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632), + bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C), + bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0), + bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76), + bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328), + bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0), + bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8), + bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA), + bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5), + bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE), + bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3), + bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E), + bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82), + bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6), + bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03), + bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC), + bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF), + bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42), + bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B), + bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B), + bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED), + bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918), + bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831), + bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE), + bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E), + bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD), + bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE), + bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026), + bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492), + bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), + bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), + bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), + bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), + bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), + bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), + bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), + bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), + bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), + bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), + bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), + bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), + bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), + bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), + bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), + bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), + bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), + bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), + bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), + bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), + bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), + bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), + bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), + bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), + bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), + bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), + bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), + bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), + bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), + bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), + bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), + bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), + bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), + bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), + bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), + bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), + bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), + bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), + bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), + bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), + bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), + bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), + bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), + bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), + bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), + bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), + bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), + bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), + bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), + bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), + bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), + bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), + bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), + bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), + bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), + bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), + bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), + bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), + bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), + bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), + bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) +}; + +static BIGNUM bn_group_8192 = { + bn_group_8192_value, + (sizeof(bn_group_8192_value)) / sizeof(BN_ULONG), + (sizeof(bn_group_8192_value)) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_generator_19_value[] = { 19 }; + +static BIGNUM bn_generator_19 = { + bn_generator_19_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; +static BN_ULONG bn_generator_5_value[] = { 5 }; + +static BIGNUM bn_generator_5 = { + bn_generator_5_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; +static BN_ULONG bn_generator_2_value[] = { 2 }; + +static BIGNUM bn_generator_2 = { + bn_generator_2_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; + +static SRP_gN knowngN[] = { + {"8192", &bn_generator_19, &bn_group_8192}, + {"6144", &bn_generator_5, &bn_group_6144}, + {"4096", &bn_generator_5, &bn_group_4096}, + {"3072", &bn_generator_5, &bn_group_3072}, + {"2048", &bn_generator_2, &bn_group_2048}, + {"1536", &bn_generator_2, &bn_group_1536}, + {"1024", &bn_generator_2, &bn_group_1024}, +}; + +#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN) + +/* end of generated data */ diff --git a/Sources/COpenSSL/srp_lcl.h b/Sources/COpenSSL/srp_lcl.h new file mode 100644 index 00000000..b74c2496 --- /dev/null +++ b/Sources/COpenSSL/srp_lcl.h @@ -0,0 +1,84 @@ +/* crypto/srp/srp_lcl.h */ +/* + * Written by Peter Sylvester (peter.sylvester@edelweb.fr) for the EdelKey + * project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_SRP_LCL_H +# define HEADER_SRP_LCL_H + +# include "srp.h" +# include "sha.h" + +# if 0 +# define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \ + fprintf(stderr,"\n");} +# else +# define srp_bn_print(a) +# endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/srtp.h b/Sources/COpenSSL/srtp.h new file mode 100644 index 00000000..94d32d8c --- /dev/null +++ b/Sources/COpenSSL/srtp.h @@ -0,0 +1,147 @@ +/* ssl/srtp.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +# define HEADER_D1_SRTP_H + +# include "ssl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# define SRTP_AES128_CM_SHA1_80 0x0001 +# define SRTP_AES128_CM_SHA1_32 0x0002 +# define SRTP_AES128_F8_SHA1_80 0x0003 +# define SRTP_AES128_F8_SHA1_32 0x0004 +# define SRTP_NULL_SHA1_80 0x0005 +# define SRTP_NULL_SHA1_32 0x0006 + +# ifndef OPENSSL_NO_SRTP + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/ssl.h b/Sources/COpenSSL/ssl.h new file mode 100644 index 00000000..189db400 --- /dev/null +++ b/Sources/COpenSSL/ssl.h @@ -0,0 +1,3164 @@ +/* ssl/ssl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_H +# define HEADER_SSL_H + +# include "e_os2.h" + +# ifndef OPENSSL_NO_COMP +# include "comp.h" +# endif +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# ifndef OPENSSL_NO_DEPRECATED +# ifndef OPENSSL_NO_X509 +# include "x509.h" +# endif +# include "crypto.h" +# include "lhash.h" +# include "buffer.h" +# endif +# include "pem.h" +# include "hmac.h" + +# include "kssl.h" +# include "safestack.h" +# include "symhacks.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSLeay version number for ASN.1 encoding of the session information */ +/*- + * Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +# define SSL_SESSION_ASN1_VERSION 0x0001 + +/* text strings for the ciphers */ +# define SSL_TXT_NULL_WITH_MD5 SSL2_TXT_NULL_WITH_MD5 +# define SSL_TXT_RC4_128_WITH_MD5 SSL2_TXT_RC4_128_WITH_MD5 +# define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 +# define SSL_TXT_RC2_128_CBC_WITH_MD5 SSL2_TXT_RC2_128_CBC_WITH_MD5 +# define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 +# define SSL_TXT_IDEA_128_CBC_WITH_MD5 SSL2_TXT_IDEA_128_CBC_WITH_MD5 +# define SSL_TXT_DES_64_CBC_WITH_MD5 SSL2_TXT_DES_64_CBC_WITH_MD5 +# define SSL_TXT_DES_64_CBC_WITH_SHA SSL2_TXT_DES_64_CBC_WITH_SHA +# define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 +# define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA + +/* + * VRS Additional Kerberos5 entries + */ +# define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +# define SSL_TXT_KRB5_RC4_128_SHA SSL3_TXT_KRB5_RC4_128_SHA +# define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA +# define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +# define SSL_TXT_KRB5_RC4_128_MD5 SSL3_TXT_KRB5_RC4_128_MD5 +# define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 + +# define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +# define SSL_TXT_KRB5_RC2_40_CBC_SHA SSL3_TXT_KRB5_RC2_40_CBC_SHA +# define SSL_TXT_KRB5_RC4_40_SHA SSL3_TXT_KRB5_RC4_40_SHA +# define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +# define SSL_TXT_KRB5_RC2_40_CBC_MD5 SSL3_TXT_KRB5_RC2_40_CBC_MD5 +# define SSL_TXT_KRB5_RC4_40_MD5 SSL3_TXT_KRB5_RC4_40_MD5 + +# define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +# define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +# define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +# define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +# define SSL_MAX_KRB5_PRINCIPAL_LENGTH 256 + +# define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +# define SSL_MAX_SID_CTX_LENGTH 32 + +# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +# define SSL_MAX_KEY_ARG_LENGTH 8 +# define SSL_MAX_MASTER_KEY_LENGTH 48 + +/* These are used to specify which ciphers to use and not to use */ + +# define SSL_TXT_EXP40 "EXPORT40" +# define SSL_TXT_EXP56 "EXPORT56" +# define SSL_TXT_LOW "LOW" +# define SSL_TXT_MEDIUM "MEDIUM" +# define SSL_TXT_HIGH "HIGH" +# define SSL_TXT_FIPS "FIPS" + +# define SSL_TXT_kFZA "kFZA"/* unused! */ +# define SSL_TXT_aFZA "aFZA"/* unused! */ +# define SSL_TXT_eFZA "eFZA"/* unused! */ +# define SSL_TXT_FZA "FZA"/* unused! */ + +# define SSL_TXT_aNULL "aNULL" +# define SSL_TXT_eNULL "eNULL" +# define SSL_TXT_NULL "NULL" + +# define SSL_TXT_kRSA "kRSA" +# define SSL_TXT_kDHr "kDHr" +# define SSL_TXT_kDHd "kDHd" +# define SSL_TXT_kDH "kDH" +# define SSL_TXT_kEDH "kEDH" +# define SSL_TXT_kDHE "kDHE"/* alias for kEDH */ +# define SSL_TXT_kKRB5 "kKRB5" +# define SSL_TXT_kECDHr "kECDHr" +# define SSL_TXT_kECDHe "kECDHe" +# define SSL_TXT_kECDH "kECDH" +# define SSL_TXT_kEECDH "kEECDH" +# define SSL_TXT_kECDHE "kECDHE"/* alias for kEECDH */ +# define SSL_TXT_kPSK "kPSK" +# define SSL_TXT_kGOST "kGOST" +# define SSL_TXT_kSRP "kSRP" + +# define SSL_TXT_aRSA "aRSA" +# define SSL_TXT_aDSS "aDSS" +# define SSL_TXT_aDH "aDH" +# define SSL_TXT_aECDH "aECDH" +# define SSL_TXT_aKRB5 "aKRB5" +# define SSL_TXT_aECDSA "aECDSA" +# define SSL_TXT_aPSK "aPSK" +# define SSL_TXT_aGOST94 "aGOST94" +# define SSL_TXT_aGOST01 "aGOST01" +# define SSL_TXT_aGOST "aGOST" +# define SSL_TXT_aSRP "aSRP" + +# define SSL_TXT_DSS "DSS" +# define SSL_TXT_DH "DH" +# define SSL_TXT_EDH "EDH"/* same as "kEDH:-ADH" */ +# define SSL_TXT_DHE "DHE"/* alias for EDH */ +# define SSL_TXT_ADH "ADH" +# define SSL_TXT_RSA "RSA" +# define SSL_TXT_ECDH "ECDH" +# define SSL_TXT_EECDH "EECDH"/* same as "kEECDH:-AECDH" */ +# define SSL_TXT_ECDHE "ECDHE"/* alias for ECDHE" */ +# define SSL_TXT_AECDH "AECDH" +# define SSL_TXT_ECDSA "ECDSA" +# define SSL_TXT_KRB5 "KRB5" +# define SSL_TXT_PSK "PSK" +# define SSL_TXT_SRP "SRP" + +# define SSL_TXT_DES "DES" +# define SSL_TXT_3DES "3DES" +# define SSL_TXT_RC4 "RC4" +# define SSL_TXT_RC2 "RC2" +# define SSL_TXT_IDEA "IDEA" +# define SSL_TXT_SEED "SEED" +# define SSL_TXT_AES128 "AES128" +# define SSL_TXT_AES256 "AES256" +# define SSL_TXT_AES "AES" +# define SSL_TXT_AES_GCM "AESGCM" +# define SSL_TXT_CAMELLIA128 "CAMELLIA128" +# define SSL_TXT_CAMELLIA256 "CAMELLIA256" +# define SSL_TXT_CAMELLIA "CAMELLIA" + +# define SSL_TXT_MD5 "MD5" +# define SSL_TXT_SHA1 "SHA1" +# define SSL_TXT_SHA "SHA"/* same as "SHA1" */ +# define SSL_TXT_GOST94 "GOST94" +# define SSL_TXT_GOST89MAC "GOST89MAC" +# define SSL_TXT_SHA256 "SHA256" +# define SSL_TXT_SHA384 "SHA384" + +# define SSL_TXT_SSLV2 "SSLv2" +# define SSL_TXT_SSLV3 "SSLv3" +# define SSL_TXT_TLSV1 "TLSv1" +# define SSL_TXT_TLSV1_1 "TLSv1.1" +# define SSL_TXT_TLSV1_2 "TLSv1.2" + +# define SSL_TXT_EXP "EXP" +# define SSL_TXT_EXPORT "EXPORT" + +# define SSL_TXT_ALL "ALL" + +/*- + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +# define SSL_TXT_CMPALL "COMPLEMENTOFALL" +# define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* + * The following cipher list is used by default. It also is substituted when + * an application-defined cipher list string starts with 'DEFAULT'. + */ +# define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2" +/* + * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! (The latter are not + * actually enabled by ALL, but "ALL:RSA" would enable some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2) +# define OPENSSL_NO_SSL2 +# endif + +# define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +# define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* + * This is needed to stop compilers complaining about the 'struct ssl_st *' + * function parameters used to prototype callbacks in SSL_CTX. + */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; +typedef struct tls_sigalgs_st TLS_SIGALGS; +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; + +DECLARE_STACK_OF(SSL_CIPHER) + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; + +DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE) + +typedef int (*tls_session_ticket_ext_cb_fn) (SSL *s, + const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn) (SSL *s, void *secret, + int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + SSL_CIPHER **cipher, void *arg); + +# ifndef OPENSSL_NO_TLSEXT + +/* Typedefs for handling custom extensions */ + +typedef int (*custom_ext_add_cb) (SSL *s, unsigned int ext_type, + const unsigned char **out, + size_t *outlen, int *al, void *add_arg); + +typedef void (*custom_ext_free_cb) (SSL *s, unsigned int ext_type, + const unsigned char *out, void *add_arg); + +typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, void *parse_arg); + +# endif + +# ifndef OPENSSL_NO_SSL_INTERN + +/* used to hold info on the particular ciphers used */ +struct ssl_cipher_st { + int valid; + const char *name; /* text name */ + unsigned long id; /* id, 4 bytes, first is version */ + /* + * changed in 0.9.9: these four used to be portions of a single value + * 'algorithms' + */ + unsigned long algorithm_mkey; /* key exchange algorithm */ + unsigned long algorithm_auth; /* server authentication */ + unsigned long algorithm_enc; /* symmetric encryption */ + unsigned long algorithm_mac; /* symmetric authentication */ + unsigned long algorithm_ssl; /* (major) protocol version */ + unsigned long algo_strength; /* strength and export flags */ + unsigned long algorithm2; /* Extra flags */ + int strength_bits; /* Number of bits really used */ + int alg_bits; /* Number of bits for algorithm */ +}; + +/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ +struct ssl_method_st { + int version; + int (*ssl_new) (SSL *s); + void (*ssl_clear) (SSL *s); + void (*ssl_free) (SSL *s); + int (*ssl_accept) (SSL *s); + int (*ssl_connect) (SSL *s); + int (*ssl_read) (SSL *s, void *buf, int len); + int (*ssl_peek) (SSL *s, void *buf, int len); + int (*ssl_write) (SSL *s, const void *buf, int len); + int (*ssl_shutdown) (SSL *s); + int (*ssl_renegotiate) (SSL *s); + int (*ssl_renegotiate_check) (SSL *s); + long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long + max, int *ok); + int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len, + int peek); + int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len); + int (*ssl_dispatch_alert) (SSL *s); + long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg); + long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg); + const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr); + int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr); + int (*ssl_pending) (const SSL *s); + int (*num_ciphers) (void); + const SSL_CIPHER *(*get_cipher) (unsigned ncipher); + const struct ssl_method_st *(*get_ssl_method) (int version); + long (*get_timeout) (void); + struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ + int (*ssl_version) (void); + long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void)); + long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void)); +}; + +/*- + * Lets make this into an ASN.1 type structure as follows + * SSL_SESSION_ID ::= SEQUENCE { + * version INTEGER, -- structure version number + * SSLversion INTEGER, -- SSL version number + * Cipher OCTET STRING, -- the 3 byte cipher ID + * Session_ID OCTET STRING, -- the Session ID + * Master_key OCTET STRING, -- the master key + * KRB5_principal OCTET STRING -- optional Kerberos principal + * Key_Arg [ 0 ] IMPLICIT OCTET STRING, -- the optional Key argument + * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time + * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds + * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate + * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context + * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' + * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension + * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint + * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity + * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket + * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only) + * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method + * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username + * } + * Look in ssl/ssl_asn1.c for more details + * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). + */ +struct ssl_session_st { + int ssl_version; /* what ssl version session info is being + * kept in here? */ + /* only really used in SSLv2 */ + unsigned int key_arg_length; + unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH]; + int master_key_length; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + /* session_id - valid? */ + unsigned int session_id_length; + unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; + /* + * this is used to determine whether the session is being reused in the + * appropriate context. It is up to the application to set this, via + * SSL_new + */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; +# ifndef OPENSSL_NO_KRB5 + unsigned int krb5_client_princ_len; + unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH]; +# endif /* OPENSSL_NO_KRB5 */ +# ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + char *psk_identity; +# endif + /* + * Used to indicate that session resumption is not allowed. Applications + * can also set this bit for a new session via not_resumable_session_cb + * to disable session caching and tickets. + */ + int not_resumable; + /* The cert is the certificate used to establish this connection */ + struct sess_cert_st /* SESS_CERT */ *sess_cert; + /* + * This is the cert for the other end. On clients, it will be the same as + * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is + * not retained in the external representation of sessions, see + * ssl_asn1.c). + */ + X509 *peer; + /* + * when app_verify_callback accepts a session where the peer's + * certificate is not ok, we must remember the error for session reuse: + */ + long verify_result; /* only for servers */ + int references; + long timeout; + long time; + unsigned int compress_meth; /* Need to lookup the method */ + const SSL_CIPHER *cipher; + unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used + * to load the 'cipher' structure */ + STACK_OF(SSL_CIPHER) *ciphers; /* ciphers offered by the client */ + CRYPTO_EX_DATA ex_data; /* application specific data */ + /* + * These are used to make removal of session-ids more efficient and to + * implement a maximum cache size. + */ + struct ssl_session_st *prev, *next; +# ifndef OPENSSL_NO_TLSEXT + char *tlsext_hostname; +# ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; /* peer's list */ + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; /* peer's list */ +# endif /* OPENSSL_NO_EC */ + /* RFC4507 info */ + unsigned char *tlsext_tick; /* Session ticket */ + size_t tlsext_ticklen; /* Session ticket length */ + long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ +# endif +# ifndef OPENSSL_NO_SRP + char *srp_username; +# endif +}; + +# endif + +# define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L +# define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L +/* Allow initial connection to servers that don't support RI */ +# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L +# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L +# define SSL_OP_TLSEXT_PADDING 0x00000010L +# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L +# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L +# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L +# define SSL_OP_TLS_D5_BUG 0x00000100L +# define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L + +/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */ +# define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +/* Refers to ancient SSLREF and SSLv2, retained for compatibility */ +# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 + +/* + * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in + * OpenSSL 0.9.6d. Usually (depending on the application protocol) the + * workaround is not needed. Unfortunately some broken SSL/TLS + * implementations cannot handle it at all, which is why we include it in + * SSL_OP_ALL. + */ +/* added in 0.9.6e */ +# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800L + +/* + * SSL_OP_ALL: various bug workarounds that should be rather harmless. This + * used to be 0x000FFFFFL before 0.9.7. + */ +# define SSL_OP_ALL 0x80000BFFL + +/* DTLS options */ +# define SSL_OP_NO_QUERY_MTU 0x00001000L +/* Turn on Cookie Exchange (on relevant for servers) */ +# define SSL_OP_COOKIE_EXCHANGE 0x00002000L +/* Don't use RFC4507 ticket extension */ +# define SSL_OP_NO_TICKET 0x00004000L +/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client) */ +# define SSL_OP_CISCO_ANYCONNECT 0x00008000L + +/* As server, disallow session resumption on renegotiation */ +# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L +/* Don't use compression even if supported */ +# define SSL_OP_NO_COMPRESSION 0x00020000L +/* Permit unsafe legacy renegotiation */ +# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L +/* If set, always create a new key when using tmp_ecdh parameters */ +# define SSL_OP_SINGLE_ECDH_USE 0x00080000L +/* Does nothing: retained for compatibility */ +# define SSL_OP_SINGLE_DH_USE 0x00100000L +/* Does nothing: retained for compatibiity */ +# define SSL_OP_EPHEMERAL_RSA 0x0 +/* + * Set on servers to choose the cipher according to the server's preferences + */ +# define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L +/* + * If set, a server will allow a client to issue a SSLv3.0 version number as + * latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. + */ +# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000L + +# define SSL_OP_NO_SSLv2 0x01000000L +# define SSL_OP_NO_SSLv3 0x02000000L +# define SSL_OP_NO_TLSv1 0x04000000L +# define SSL_OP_NO_TLSv1_2 0x08000000L +# define SSL_OP_NO_TLSv1_1 0x10000000L + +# define SSL_OP_NO_DTLSv1 0x04000000L +# define SSL_OP_NO_DTLSv1_2 0x08000000L + +# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|\ + SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2) + +/* + * These next two were never actually used for anything since SSLeay zap so + * we have some more flags. + */ +/* + * The next flag deliberately changes the ciphertest, this is a check for the + * PKCS#1 attack + */ +# define SSL_OP_PKCS1_CHECK_1 0x0 +# define SSL_OP_PKCS1_CHECK_2 0x0 + +# define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L +# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L +/* + * Make server add server-hello extension from early version of cryptopro + * draft, when GOST ciphersuite is negotiated. Required for interoperability + * with CryptoPro CSP 3.x + */ +# define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000L + +/* + * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): + */ +# define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L +/* + * Make it possible to retry SSL_write() with changed buffer location (buffer + * contents must stay the same!); this is not the default to avoid the + * misconception that non-blocking SSL_write() behaves like non-blocking + * write(): + */ +# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L +/* + * Never bother the application with retries if the transport is blocking: + */ +# define SSL_MODE_AUTO_RETRY 0x00000004L +/* Don't attempt to automatically build certificate chain */ +# define SSL_MODE_NO_AUTO_CHAIN 0x00000008L +/* + * Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) "Released" buffers are put onto a free-list in the context or + * just freed (depending on the context's setting for freelist_max_len). + */ +# define SSL_MODE_RELEASE_BUFFERS 0x00000010L +/* + * Send the current time in the Random fields of the ClientHello and + * ServerHello records for compatibility with hypothetical implementations + * that require it. + */ +# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L +# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L +/* + * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications + * that reconnect with a downgraded protocol version; see + * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your + * application attempts a normal handshake. Only use this in explicit + * fallback retries, following the guidance in + * draft-ietf-tls-downgrade-scsv-00. + */ +# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L + +/* Cert related flags */ +/* + * Many implementations ignore some aspects of the TLS standards such as + * enforcing certifcate chain algorithms. When this is set we enforce them. + */ +# define SSL_CERT_FLAG_TLS_STRICT 0x00000001L + +/* Suite B modes, takes same values as certificate verify flags */ +# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define SSL_CERT_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define SSL_CERT_FLAG_SUITEB_128_LOS 0x30000 + +/* Perform all sorts of protocol violations for testing purposes */ +# define SSL_CERT_FLAG_BROKEN_PROTOCOL 0x10000000 + +/* Flags for building certificate chains */ +/* Treat any existing certificates as untrusted CAs */ +# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1 +/* Don't include root CA in chain */ +# define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2 +/* Just check certificates already there */ +# define SSL_BUILD_CHAIN_FLAG_CHECK 0x4 +/* Ignore verification errors */ +# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8 +/* Clear verification errors from queue */ +# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10 + +/* Flags returned by SSL_check_chain */ +/* Certificate can be used with this session */ +# define CERT_PKEY_VALID 0x1 +/* Certificate can also be used for signing */ +# define CERT_PKEY_SIGN 0x2 +/* EE certificate signing algorithm OK */ +# define CERT_PKEY_EE_SIGNATURE 0x10 +/* CA signature algorithms OK */ +# define CERT_PKEY_CA_SIGNATURE 0x20 +/* EE certificate parameters OK */ +# define CERT_PKEY_EE_PARAM 0x40 +/* CA certificate parameters OK */ +# define CERT_PKEY_CA_PARAM 0x80 +/* Signing explicitly allowed as opposed to SHA1 fallback */ +# define CERT_PKEY_EXPLICIT_SIGN 0x100 +/* Client CA issuer names match (always set for server cert) */ +# define CERT_PKEY_ISSUER_NAME 0x200 +/* Cert type matches client types (always set for server cert) */ +# define CERT_PKEY_CERT_TYPE 0x400 +/* Cert chain suitable to Suite B */ +# define CERT_PKEY_SUITEB 0x800 + +# define SSL_CONF_FLAG_CMDLINE 0x1 +# define SSL_CONF_FLAG_FILE 0x2 +# define SSL_CONF_FLAG_CLIENT 0x4 +# define SSL_CONF_FLAG_SERVER 0x8 +# define SSL_CONF_FLAG_SHOW_ERRORS 0x10 +# define SSL_CONF_FLAG_CERTIFICATE 0x20 +/* Configuration value types */ +# define SSL_CONF_TYPE_UNKNOWN 0x0 +# define SSL_CONF_TYPE_STRING 0x1 +# define SSL_CONF_TYPE_FILE 0x2 +# define SSL_CONF_TYPE_DIR 0x3 + +/* + * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they + * cannot be used to clear bits. + */ + +# define SSL_CTX_set_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) +# define SSL_CTX_clear_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +# define SSL_CTX_get_options(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL) +# define SSL_set_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL) +# define SSL_clear_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +# define SSL_get_options(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL) + +# define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +# define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +# define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +# define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +# define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) +# define DTLS_set_link_mtu(ssl, mtu) \ + SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL) +# define DTLS_get_link_min_mtu(ssl) \ + SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL) + +# define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_heartbeat(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL) +# endif + +# define SSL_CTX_set_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_set_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL) +# define SSL_CTX_clear_cert_flags(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) +# define SSL_clear_cert_flags(s,op) \ + SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + +# ifndef OPENSSL_NO_SRP + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct srp_ctx_st { + /* param for all the callbacks */ + void *SRP_cb_arg; + /* set client Hello login callback */ + int (*TLS_ext_srp_username_callback) (SSL *, int *, void *); + /* set SRP N/g param callback for verification */ + int (*SRP_verify_param_callback) (SSL *, void *); + /* set SRP client passwd callback */ + char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *); + char *login; + BIGNUM *N, *g, *s, *B, *A; + BIGNUM *a, *b, *v; + char *info; + int strength; + unsigned long srp_Mask; +} SRP_CTX; + +# endif + +/* see tls_srp.c */ +int SSL_SRP_CTX_init(SSL *s); +int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); +int SSL_SRP_CTX_free(SSL *ctx); +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); +int SSL_srp_server_param_with_username(SSL *s, int *ad); +int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key); +int SRP_Calc_A_param(SSL *s); +int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key); + +# endif + +# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) +# define SSL_MAX_CERT_LIST_DEFAULT 1024*30 + /* 30k max cert list :-) */ +# else +# define SSL_MAX_CERT_LIST_DEFAULT 1024*100 + /* 100k max cert list :-) */ +# endif + +# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* + * This callback type is used inside SSL_CTX, SSL, and in the functions that + * set them. It is used to override the generation of SSL/TLS session IDs in + * a server. Return value should be zero on an error, non-zero to proceed. + * Also, callbacks should themselves check if the id they generate is unique + * otherwise the SSL handshake will fail with an error - callbacks can do + * this using the 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in + * is set at the maximum size the session ID can be. In SSLv2 this is 16 + * bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback can alter this + * length to be less if desired, but under SSLv2 session IDs are supposed to + * be fixed at 16 bytes so the id will be padded after the callback returns + * in this case. It is also an error for the callback to set the size to + * zero. + */ +typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id, + unsigned int *id_len); + +typedef struct ssl_comp_st SSL_COMP; + +# ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_comp_st { + int id; + const char *name; +# ifndef OPENSSL_NO_COMP + COMP_METHOD *method; +# else + char *method; +# endif +}; + +DECLARE_STACK_OF(SSL_COMP) +DECLARE_LHASH_OF(SSL_SESSION); + +struct ssl_ctx_st { + const SSL_METHOD *method; + STACK_OF(SSL_CIPHER) *cipher_list; + /* same as above but sorted for lookup */ + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + struct x509_store_st /* X509_STORE */ *cert_store; + LHASH_OF(SSL_SESSION) *sessions; + /* + * Most session-ids that will be cached, default is + * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. + */ + unsigned long session_cache_size; + struct ssl_session_st *session_cache_head; + struct ssl_session_st *session_cache_tail; + /* + * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT, + * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which + * means only SSL_accept which cache SSL_SESSIONS. + */ + int session_cache_mode; + /* + * If timeout is not 0, it is the default timeout value set when + * SSL_new() is called. This has been put in to make life easier to set + * things up + */ + long session_timeout; + /* + * If this callback is not null, it will be called each time a session id + * is added to the cache. If this function returns 1, it means that the + * callback will do a SSL_SESSION_free() when it has finished using it. + * Otherwise, on 0, it means the callback has finished with it. If + * remove_session_cb is not null, it will be called when a session-id is + * removed from the cache. After the call, OpenSSL will + * SSL_SESSION_free() it. + */ + int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess); + void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl, + unsigned char *data, int len, int *copy); + struct { + int sess_connect; /* SSL new conn - started */ + int sess_connect_renegotiate; /* SSL reneg - requested */ + int sess_connect_good; /* SSL new conne/reneg - finished */ + int sess_accept; /* SSL new accept - started */ + int sess_accept_renegotiate; /* SSL reneg - requested */ + int sess_accept_good; /* SSL accept/reneg - finished */ + int sess_miss; /* session lookup misses */ + int sess_timeout; /* reuse attempt on timeouted session */ + int sess_cache_full; /* session removed due to full cache */ + int sess_hit; /* session reuse actually done */ + int sess_cb_hit; /* session-id that was not in the cache was + * passed back via the callback. This + * indicates that the application is + * supplying session-id's from other + * processes - spooky :-) */ + } stats; + + int references; + + /* if defined, these override the X509_verify_cert() calls */ + int (*app_verify_callback) (X509_STORE_CTX *, void *); + void *app_verify_arg; + /* + * before OpenSSL 0.9.7, 'app_verify_arg' was ignored + * ('app_verify_callback' was called with just one argument) + */ + + /* Default password callback. */ + pem_password_cb *default_passwd_callback; + + /* Default password callback user data. */ + void *default_passwd_callback_userdata; + + /* get client cert callback */ + int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey); + + /* cookie generate callback */ + int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); + + /* verify cookie callback */ + int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie, + unsigned int cookie_len); + + CRYPTO_EX_DATA ex_data; + + const EVP_MD *rsa_md5; /* For SSLv2 - name is 'ssl2-md5' */ + const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ + const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ + + STACK_OF(X509) *extra_certs; + STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */ + + /* Default values used when no per-SSL value is defined follow */ + + /* used if SSL's info_callback is NULL */ + void (*info_callback) (const SSL *ssl, int type, int val); + + /* what we put in client cert requests */ + STACK_OF(X509_NAME) *client_CA; + + /* + * Default values to use in SSL structures follow (these are copied by + * SSL_new) + */ + + unsigned long options; + unsigned long mode; + long max_cert_list; + + struct cert_st /* CERT */ *cert; + int read_ahead; + + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback) (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + + int verify_mode; + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + /* called 'verify_callback' in the SSL */ + int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + X509_VERIFY_PARAM *param; + +# if 0 + int purpose; /* Purpose setting */ + int trust; /* Trust setting */ +# endif + + int quiet_shutdown; + + /* + * Maximum amount of data to send in one fragment. actual record size can + * be more than this due to padding and MAC overheads. + */ + unsigned int max_send_fragment; + +# ifndef OPENSSL_NO_ENGINE + /* + * Engine to pass requests for client certs to + */ + ENGINE *client_cert_engine; +# endif + +# ifndef OPENSSL_NO_TLSEXT + /* TLS extensions servername callback */ + int (*tlsext_servername_callback) (SSL *, int *, void *); + void *tlsext_servername_arg; + /* RFC 4507 session ticket keys */ + unsigned char tlsext_tick_key_name[16]; + unsigned char tlsext_tick_hmac_key[16]; + unsigned char tlsext_tick_aes_key[16]; + /* Callback to support customisation of ticket key setting */ + int (*tlsext_ticket_key_cb) (SSL *ssl, + unsigned char *name, unsigned char *iv, + EVP_CIPHER_CTX *ectx, + HMAC_CTX *hctx, int enc); + + /* certificate status request info */ + /* Callback for status request */ + int (*tlsext_status_cb) (SSL *ssl, void *arg); + void *tlsext_status_arg; + + /* draft-rescorla-tls-opaque-prf-input-00.txt information */ + int (*tlsext_opaque_prf_input_callback) (SSL *, void *peerinput, + size_t len, void *arg); + void *tlsext_opaque_prf_input_callback_arg; +# endif + +# ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +# endif + +# ifndef OPENSSL_NO_BUF_FREELISTS +# define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32 + unsigned int freelist_max_len; + struct ssl3_buf_freelist_st *wbuf_freelist; + struct ssl3_buf_freelist_st *rbuf_freelist; +# endif +# ifndef OPENSSL_NO_SRP + SRP_CTX srp_ctx; /* ctx for SRP authentication */ +# endif + +# ifndef OPENSSL_NO_TLSEXT + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* Next protocol negotiation information */ + /* (for experimental NPN extension). */ + + /* + * For a server, this contains a callback function by which the set of + * advertised protocols can be provided. + */ + int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf, + unsigned int *len, void *arg); + void *next_protos_advertised_cb_arg; + /* + * For a client, this contains a callback function that selects the next + * protocol from the list provided by the server. + */ + int (*next_proto_select_cb) (SSL *s, unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, void *arg); + void *next_proto_select_cb_arg; +# endif + /* SRTP profiles we are willing to do from RFC 5764 */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + + /* + * ALPN information (we are in the process of transitioning from NPN to + * ALPN.) + */ + + /*- + * For a server, this contains a callback function that allows the + * server to select the protocol for the connection. + * out: on successful return, this must point to the raw protocol + * name (without the length prefix). + * outlen: on successful return, this contains the length of |*out|. + * in: points to the client's list of supported protocols in + * wire-format. + * inlen: the length of |in|. + */ + int (*alpn_select_cb) (SSL *s, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, void *arg); + void *alpn_select_cb_arg; + + /* + * For a client, this contains the list of supported protocols in wire + * format. + */ + unsigned char *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; + +# ifndef OPENSSL_NO_EC + /* EC extension values inherited by SSL structure */ + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; +# endif /* OPENSSL_NO_EC */ +# endif +}; + +# endif + +# define SSL_SESS_CACHE_OFF 0x0000 +# define SSL_SESS_CACHE_CLIENT 0x0001 +# define SSL_SESS_CACHE_SERVER 0x0002 +# define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +# define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +# define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +# define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +# define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +# define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +# define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +# define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +# define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +# define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +# define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +# define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +# define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +# define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb) (struct ssl_st *ssl, + SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb) (struct ssl_ctx_st + *ctx, + SSL_SESSION + *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb) (struct ssl_st + *ssl, + unsigned char + *data, int len, + int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + unsigned char *Data, + int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, + int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +# ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +# endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + cookie_len)); +# ifndef OPENSSL_NO_NEXTPROTONEG +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, + int (*cb) (SSL *ssl, + const unsigned char + **out, + unsigned int *outlen, + void *arg), void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, + int (*cb) (SSL *ssl, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg); +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len); +# endif + +# ifndef OPENSSL_NO_TLSEXT +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, + unsigned int client_len); +# endif + +# define OPENSSL_NPN_UNSUPPORTED 0 +# define OPENSSL_NPN_NEGOTIATED 1 +# define OPENSSL_NPN_NO_OVERLAP 2 + +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned protos_len); +int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned protos_len); +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg); +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned *len); + +# ifndef OPENSSL_NO_PSK +/* + * the maximum length of the buffer given to callbacks containing the + * resulting identity/psk + */ +# define PSK_MAX_IDENTITY_LEN 128 +# define PSK_MAX_PSK_LEN 256 +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, + unsigned int (*psk_client_callback) (SSL + *ssl, + const + char + *hint, + char + *identity, + unsigned + int + max_identity_len, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_set_psk_client_callback(SSL *ssl, + unsigned int (*psk_client_callback) (SSL + *ssl, + const + char + *hint, + char + *identity, + unsigned + int + max_identity_len, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*psk_server_callback) (SSL + *ssl, + const + char + *identity, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_set_psk_server_callback(SSL *ssl, + unsigned int (*psk_server_callback) (SSL + *ssl, + const + char + *identity, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +# endif + +# ifndef OPENSSL_NO_TLSEXT +/* Register callbacks to handle custom TLS Extensions for client or server. */ + +int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg); + +int SSL_extension_supported(unsigned int ext_type); + +# endif + +# define SSL_NOTHING 1 +# define SSL_WRITING 2 +# define SSL_READING 3 +# define SSL_X509_LOOKUP 4 + +/* These will only be used when doing non-blocking IO */ +# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +# define SSL_want_read(s) (SSL_want(s) == SSL_READING) +# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) + +# define SSL_MAC_FLAG_READ_MAC_STREAM 1 +# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +# ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_st { + /* + * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, + * DTLS1_VERSION) + */ + int version; + /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ + int type; + /* SSLv3 */ + const SSL_METHOD *method; + /* + * There are 2 BIO's even though they are normally both the same. This + * is so data can be read and written to different handlers + */ +# ifndef OPENSSL_NO_BIO + /* used by SSL_read */ + BIO *rbio; + /* used by SSL_write */ + BIO *wbio; + /* used during session-id reuse to concatenate messages */ + BIO *bbio; +# else + /* used by SSL_read */ + char *rbio; + /* used by SSL_write */ + char *wbio; + char *bbio; +# endif + /* + * This holds a variable that indicates what we were doing when a 0 or -1 + * is returned. This is needed for non-blocking IO so we know what + * request needs re-doing when in SSL_accept or SSL_connect + */ + int rwstate; + /* true when we are actually in SSL_accept() or SSL_connect() */ + int in_handshake; + int (*handshake_func) (SSL *); + /* + * Imagine that here's a boolean member "init" that is switched as soon + * as SSL_set_{accept/connect}_state is called for the first time, so + * that "state" and "handshake_func" are properly initialized. But as + * handshake_func is == 0 until then, we use this test instead of an + * "init" member. + */ + /* are we the server side? - mostly used by SSL_clear */ + int server; + /* + * Generate a new session or reuse an old one. + * NB: For servers, the 'new' session may actually be a previously + * cached session or even the previous session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set + */ + int new_session; + /* don't send shutdown packets */ + int quiet_shutdown; + /* we have shut things down, 0x01 sent, 0x02 for received */ + int shutdown; + /* where we are */ + int state; + /* where we are when reading */ + int rstate; + BUF_MEM *init_buf; /* buffer used during init */ + void *init_msg; /* pointer to handshake message body, set by + * ssl3_get_message() */ + int init_num; /* amount read/written */ + int init_off; /* amount read/written */ + /* used internally to point at a raw packet */ + unsigned char *packet; + unsigned int packet_length; + struct ssl2_state_st *s2; /* SSLv2 variables */ + struct ssl3_state_st *s3; /* SSLv3 variables */ + struct dtls1_state_st *d1; /* DTLSv1 variables */ + int read_ahead; /* Read as many input bytes as possible (for + * non-blocking reads) */ + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback) (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + int hit; /* reusing a previous session */ + X509_VERIFY_PARAM *param; +# if 0 + int purpose; /* Purpose setting */ + int trust; /* Trust setting */ +# endif + /* crypto */ + STACK_OF(SSL_CIPHER) *cipher_list; + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + /* + * These are the ones being used, the ones in SSL_SESSION are the ones to + * be 'copied' into these ones + */ + int mac_flags; + EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ + EVP_MD_CTX *read_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *expand; /* uncompress */ +# else + char *expand; +# endif + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +# else + char *compress; +# endif + /* session info */ + /* client cert? */ + /* This is used to hold the server certificate used */ + struct cert_st /* CERT */ *cert; + /* + * the session_id_context is used to ensure sessions are only reused in + * the appropriate context + */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + /* This can also be in the session once a session is established */ + SSL_SESSION *session; + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + /* Used in SSL2 and SSL3 */ + /* + * 0 don't care about verify failure. + * 1 fail if verify fails + */ + int verify_mode; + /* fail if callback returns 0 */ + int (*verify_callback) (int ok, X509_STORE_CTX *ctx); + /* optional informational callback */ + void (*info_callback) (const SSL *ssl, int type, int val); + /* error bytes to be written */ + int error; + /* actual code */ + int error_code; +# ifndef OPENSSL_NO_KRB5 + /* Kerberos 5 context */ + KSSL_CTX *kssl_ctx; +# endif /* OPENSSL_NO_KRB5 */ +# ifndef OPENSSL_NO_PSK + unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +# endif + SSL_CTX *ctx; + /* + * set this flag to 1 and a sleep(1) is put into all SSL_read() and + * SSL_write() calls, good for nbio debuging :-) + */ + int debug; + /* extra application data */ + long verify_result; + CRYPTO_EX_DATA ex_data; + /* for server side, keep the list of CA_dn we can use */ + STACK_OF(X509_NAME) *client_CA; + int references; + /* protocol behaviour */ + unsigned long options; + /* API behaviour */ + unsigned long mode; + long max_cert_list; + int first_packet; + /* what was passed, used for SSLv3/TLS rollback check */ + int client_version; + unsigned int max_send_fragment; +# ifndef OPENSSL_NO_TLSEXT + /* TLS extension debug callback */ + void (*tlsext_debug_cb) (SSL *s, int client_server, int type, + unsigned char *data, int len, void *arg); + void *tlsext_debug_arg; + char *tlsext_hostname; + /*- + * no further mod of servername + * 0 : call the servername extension callback. + * 1 : prepare 2, allow last ack just after in server callback. + * 2 : don't call servername callback, no ack in server hello + */ + int servername_done; + /* certificate status request info */ + /* Status type or -1 if no status type */ + int tlsext_status_type; + /* Expect OCSP CertificateStatus message */ + int tlsext_status_expected; + /* OCSP status request only */ + STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; + X509_EXTENSIONS *tlsext_ocsp_exts; + /* OCSP response received or to be sent */ + unsigned char *tlsext_ocsp_resp; + int tlsext_ocsp_resplen; + /* RFC4507 session ticket expected to be received or sent */ + int tlsext_ticket_expected; +# ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + /* our list */ + unsigned char *tlsext_ecpointformatlist; + size_t tlsext_ellipticcurvelist_length; + /* our list */ + unsigned char *tlsext_ellipticcurvelist; +# endif /* OPENSSL_NO_EC */ + /* + * draft-rescorla-tls-opaque-prf-input-00.txt information to be used for + * handshakes + */ + void *tlsext_opaque_prf_input; + size_t tlsext_opaque_prf_input_len; + /* TLS Session Ticket extension override */ + TLS_SESSION_TICKET_EXT *tlsext_session_ticket; + /* TLS Session Ticket extension callback */ + tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; + void *tls_session_ticket_ext_cb_arg; + /* TLS pre-shared secret session resumption */ + tls_session_secret_cb_fn tls_session_secret_cb; + void *tls_session_secret_cb_arg; + SSL_CTX *initial_ctx; /* initial ctx, used to store sessions */ +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Next protocol negotiation. For the client, this is the protocol that + * we sent in NextProtocol and is set when handling ServerHello + * extensions. For a server, this is the client's selected_protocol from + * NextProtocol and is set when handling the NextProtocol message, before + * the Finished message. + */ + unsigned char *next_proto_negotiated; + unsigned char next_proto_negotiated_len; +# endif +# define session_ctx initial_ctx + /* What we'll do */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + /* What's been chosen */ + SRTP_PROTECTION_PROFILE *srtp_profile; + /*- + * Is use of the Heartbeat extension negotiated? + * 0: disabled + * 1: enabled + * 2: enabled, but not allowed to send Requests + */ + unsigned int tlsext_heartbeat; + /* Indicates if a HeartbeatRequest is in flight */ + unsigned int tlsext_hb_pending; + /* HeartbeatRequest sequence number */ + unsigned int tlsext_hb_seq; +# else +# define session_ctx ctx +# endif /* OPENSSL_NO_TLSEXT */ + /*- + * 1 if we are renegotiating. + * 2 if we are a server and are inside a handshake + * (i.e. not just sending a HelloRequest) + */ + int renegotiate; +# ifndef OPENSSL_NO_SRP + /* ctx for SRP authentication */ + SRP_CTX srp_ctx; +# endif +# ifndef OPENSSL_NO_TLSEXT + /* + * For a client, this contains the list of supported protocols in wire + * format. + */ + unsigned char *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; +# endif /* OPENSSL_NO_TLSEXT */ +}; + +# endif + +#ifdef __cplusplus +} +#endif + +# include "ssl2.h" +# include "ssl3.h" +# include "tls1.h" /* This is mostly sslv3 with a few tweaks */ +# include "dtls1.h" /* Datagram TLS */ +# include "ssl23.h" +# include "srtp.h" /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* compatibility */ +# define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) +# define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +# define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0,(char *)a)) +# define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +# define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg)) + +/* + * The following are the possible values for ssl->state are are used to + * indicate where we are up to in the SSL connection establishment. The + * macros that follow are about the only things you should need to use and + * even then, only when using non-blocking IO. It can also be useful to work + * out where you were when the connection failed + */ + +# define SSL_ST_CONNECT 0x1000 +# define SSL_ST_ACCEPT 0x2000 +# define SSL_ST_MASK 0x0FFF +# define SSL_ST_INIT (SSL_ST_CONNECT|SSL_ST_ACCEPT) +# define SSL_ST_BEFORE 0x4000 +# define SSL_ST_OK 0x03 +# define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) +# define SSL_ST_ERR (0x05|SSL_ST_INIT) + +# define SSL_CB_LOOP 0x01 +# define SSL_CB_EXIT 0x02 +# define SSL_CB_READ 0x04 +# define SSL_CB_WRITE 0x08 +# define SSL_CB_ALERT 0x4000/* used in callback */ +# define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +# define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +# define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +# define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +# define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +# define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +# define SSL_CB_HANDSHAKE_START 0x10 +# define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +# define SSL_get_state(a) SSL_state(a) +# define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK) +# define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT) +# define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE) +# define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT) +# define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT) + +/* + * The following 2 states are kept in ssl->rstate when reads fail, you should + * not need these + */ +# define SSL_ST_READ_HEADER 0xF0 +# define SSL_ST_READ_BODY 0xF1 +# define SSL_ST_READ_DONE 0xF2 + +/*- + * Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. + */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* + * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are + * 'ored' with SSL_VERIFY_PEER if they are desired + */ +# define SSL_VERIFY_NONE 0x00 +# define SSL_VERIFY_PEER 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE 0x04 + +# define OpenSSL_add_ssl_algorithms() SSL_library_init() +# define SSLeay_add_ssl_algorithms() SSL_library_init() + +/* this is for backward compatibility */ +# if 0 /* NEW_SSLEAY */ +# define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c) +# define SSL_set_pref_cipher(c,n) SSL_set_cipher_list(c,n) +# define SSL_add_session(a,b) SSL_CTX_add_session((a),(b)) +# define SSL_remove_session(a,b) SSL_CTX_remove_session((a),(b)) +# define SSL_flush_sessions(a,b) SSL_CTX_flush_sessions((a),(b)) +# endif +/* More backward compatibility */ +# define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +# define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +# define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_time(a) SSL_SESSION_get_time(a) +# define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +# define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +# define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) +# define SSL_AD_REASON_OFFSET 1000/* offset to get SSL_R_... value + * from SSL_AD_... */ +/* These alert types are for SSLv3 and TLSv1 */ +# define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +/* fatal */ +# define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +/* fatal */ +# define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC +# define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +# define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +/* fatal */ +# define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +/* fatal */ +# define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +/* Not for TLS */ +# define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE +# define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +# define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +# define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +# define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +# define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +/* fatal */ +# define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +/* fatal */ +# define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +/* fatal */ +# define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +/* fatal */ +# define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +# define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +/* fatal */ +# define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +/* fatal */ +# define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +/* fatal */ +# define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +/* fatal */ +# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +# define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +/* fatal */ +# define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +/* fatal */ +# define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5/* look at error stack/return + * value/errno */ +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 +# define SSL_CTRL_NEED_TMP_RSA 1 +# define SSL_CTRL_SET_TMP_RSA 2 +# define SSL_CTRL_SET_TMP_DH 3 +# define SSL_CTRL_SET_TMP_ECDH 4 +# define SSL_CTRL_SET_TMP_RSA_CB 5 +# define SSL_CTRL_SET_TMP_DH_CB 6 +# define SSL_CTRL_SET_TMP_ECDH_CB 7 +# define SSL_CTRL_GET_SESSION_REUSED 8 +# define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +# define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +# define SSL_CTRL_GET_FLAGS 13 +# define SSL_CTRL_EXTRA_CHAIN_CERT 14 +# define SSL_CTRL_SET_MSG_CALLBACK 15 +# define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 +/* only applies to datagram connections */ +# define SSL_CTRL_SET_MTU 17 +/* Stats */ +# define SSL_CTRL_SESS_NUMBER 20 +# define SSL_CTRL_SESS_CONNECT 21 +# define SSL_CTRL_SESS_CONNECT_GOOD 22 +# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +# define SSL_CTRL_SESS_ACCEPT 24 +# define SSL_CTRL_SESS_ACCEPT_GOOD 25 +# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +# define SSL_CTRL_SESS_HIT 27 +# define SSL_CTRL_SESS_CB_HIT 28 +# define SSL_CTRL_SESS_MISSES 29 +# define SSL_CTRL_SESS_TIMEOUTS 30 +# define SSL_CTRL_SESS_CACHE_FULL 31 +# define SSL_CTRL_OPTIONS 32 +# define SSL_CTRL_MODE 33 +# define SSL_CTRL_GET_READ_AHEAD 40 +# define SSL_CTRL_SET_READ_AHEAD 41 +# define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +# define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +# define SSL_CTRL_SET_SESS_CACHE_MODE 44 +# define SSL_CTRL_GET_SESS_CACHE_MODE 45 +# define SSL_CTRL_GET_MAX_CERT_LIST 50 +# define SSL_CTRL_SET_MAX_CERT_LIST 51 +# define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 +/* see tls1.h for macros based on these */ +# ifndef OPENSSL_NO_TLSEXT +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +# define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 +# define SSL_CTRL_SET_SRP_ARG 78 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT 85 +# define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86 +# define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87 +# endif +# endif /* OPENSSL_NO_TLSEXT */ +# define DTLS_CTRL_GET_TIMEOUT 73 +# define DTLS_CTRL_HANDLE_TIMEOUT 74 +# define DTLS_CTRL_LISTEN 75 +# define SSL_CTRL_GET_RI_SUPPORT 76 +# define SSL_CTRL_CLEAR_OPTIONS 77 +# define SSL_CTRL_CLEAR_MODE 78 +# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 +# define SSL_CTRL_CHAIN 88 +# define SSL_CTRL_CHAIN_CERT 89 +# define SSL_CTRL_GET_CURVES 90 +# define SSL_CTRL_SET_CURVES 91 +# define SSL_CTRL_SET_CURVES_LIST 92 +# define SSL_CTRL_GET_SHARED_CURVE 93 +# define SSL_CTRL_SET_ECDH_AUTO 94 +# define SSL_CTRL_SET_SIGALGS 97 +# define SSL_CTRL_SET_SIGALGS_LIST 98 +# define SSL_CTRL_CERT_FLAGS 99 +# define SSL_CTRL_CLEAR_CERT_FLAGS 100 +# define SSL_CTRL_SET_CLIENT_SIGALGS 101 +# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 +# define SSL_CTRL_GET_CLIENT_CERT_TYPES 103 +# define SSL_CTRL_SET_CLIENT_CERT_TYPES 104 +# define SSL_CTRL_BUILD_CERT_CHAIN 105 +# define SSL_CTRL_SET_VERIFY_CERT_STORE 106 +# define SSL_CTRL_SET_CHAIN_CERT_STORE 107 +# define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 +# define SSL_CTRL_GET_SERVER_TMP_KEY 109 +# define SSL_CTRL_GET_RAW_CIPHERLIST 110 +# define SSL_CTRL_GET_EC_POINT_FORMATS 111 +# define SSL_CTRL_GET_CHAIN_CERTS 115 +# define SSL_CTRL_SELECT_CURRENT_CERT 116 +# define SSL_CTRL_SET_CURRENT_CERT 117 +# define SSL_CTRL_CHECK_PROTO_VERSION 119 +# define DTLS_CTRL_SET_LINK_MTU 120 +# define DTLS_CTRL_GET_LINK_MIN_MTU 121 +# define SSL_CERT_SET_FIRST 1 +# define SSL_CERT_SET_NEXT 2 +# define SSL_CERT_SET_SERVER 3 +# define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) +# define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +# define DTLSv1_listen(ssl, peer) \ + SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer) +# define SSL_session_reused(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) +# define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) +# define SSL_CTX_need_tmp_RSA(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL) +# define SSL_CTX_set_tmp_rsa(ctx,rsa) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +# define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +# define SSL_need_tmp_RSA(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL) +# define SSL_set_tmp_rsa(ssl,rsa) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +# define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +# define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +# define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509) +# define SSL_CTX_get_extra_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) +# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509) +# define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) +# define SSL_CTX_set0_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk) +# define SSL_CTX_set1_chain(ctx,sk) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk) +# define SSL_CTX_add0_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509) +# define SSL_CTX_add1_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509) +# define SSL_CTX_get0_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_CTX_clear_chain_certs(ctx) \ + SSL_CTX_set0_chain(ctx,NULL) +# define SSL_CTX_build_cert_chain(ctx, flags) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_CTX_select_current_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509) +# define SSL_CTX_set_current_cert(ctx, op) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_CTX_set0_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st) +# define SSL_CTX_set1_verify_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st) +# define SSL_CTX_set0_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st) +# define SSL_CTX_set1_chain_cert_store(ctx,st) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st) +# define SSL_set0_chain(ctx,sk) \ + SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk) +# define SSL_set1_chain(ctx,sk) \ + SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk) +# define SSL_add0_chain_cert(ctx,x509) \ + SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509) +# define SSL_add1_chain_cert(ctx,x509) \ + SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509) +# define SSL_get0_chain_certs(ctx,px509) \ + SSL_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) +# define SSL_clear_chain_certs(ctx) \ + SSL_set0_chain(ctx,NULL) +# define SSL_build_cert_chain(s, flags) \ + SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) +# define SSL_select_current_cert(ctx,x509) \ + SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509) +# define SSL_set_current_cert(ctx,op) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) +# define SSL_set0_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st) +# define SSL_set1_verify_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st) +# define SSL_set0_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st) +# define SSL_set1_chain_cert_store(s,st) \ + SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st) +# define SSL_get1_curves(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s) +# define SSL_CTX_set1_curves(ctx, clist, clistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist) +# define SSL_CTX_set1_curves_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s) +# define SSL_set1_curves(ctx, clist, clistlen) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist) +# define SSL_set1_curves_list(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s) +# define SSL_get_shared_curve(s, n) \ + SSL_ctrl(s,SSL_CTRL_GET_SHARED_CURVE,n,NULL) +# define SSL_CTX_set_ecdh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) +# define SSL_set_ecdh_auto(s, onoff) \ + SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) +# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist) +# define SSL_CTX_set1_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s) +# define SSL_set1_sigalgs(ctx, slist, slistlen) \ + SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist) +# define SSL_set1_sigalgs_list(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s) +# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)slist) +# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s) +# define SSL_set1_client_sigalgs(ctx, slist, slistlen) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)slist) +# define SSL_set1_client_sigalgs_list(ctx, s) \ + SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s) +# define SSL_get0_certificate_types(s, clist) \ + SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist) +# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist) +# define SSL_set1_client_certificate_types(s, clist, clistlen) \ + SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist) +# define SSL_get_peer_signature_nid(s, pn) \ + SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn) +# define SSL_get_server_tmp_key(s, pk) \ + SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk) +# define SSL_get0_raw_cipherlist(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,(char *)plst) +# define SSL_get0_ec_point_formats(s, plst) \ + SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,(char *)plst) +# ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_ssl(void); +BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +# endif + +int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +void SSL_CTX_free(SSL_CTX *); +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +long SSL_CTX_get_timeout(const SSL_CTX *ctx); +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +int SSL_want(const SSL *s); +int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +char *SSL_CIPHER_get_version(const SSL_CIPHER *c); +const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c); + +int SSL_get_fd(const SSL *s); +int SSL_get_rfd(const SSL *s); +int SSL_get_wfd(const SSL *s); +const char *SSL_get_cipher_list(const SSL *s, int n); +char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size); +int SSL_get_read_ahead(const SSL *s); +int SSL_pending(const SSL *s); +# ifndef OPENSSL_NO_SOCK +int SSL_set_fd(SSL *s, int fd); +int SSL_set_rfd(SSL *s, int fd); +int SSL_set_wfd(SSL *s, int fd); +# endif +# ifndef OPENSSL_NO_BIO +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +BIO *SSL_get_rbio(const SSL *s); +BIO *SSL_get_wbio(const SSL *s); +# endif +int SSL_set_cipher_list(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +int SSL_get_verify_mode(const SSL *s); +int SSL_get_verify_depth(const SSL *s); +int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *); +void SSL_set_verify(SSL *s, int mode, + int (*callback) (int ok, X509_STORE_CTX *ctx)); +void SSL_set_verify_depth(SSL *s, int depth); +void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg); +# ifndef OPENSSL_NO_RSA +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +# endif +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len); +int SSL_use_certificate(SSL *ssl, X509 *x); +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); + +# ifndef OPENSSL_NO_TLSEXT +/* Set serverinfo data for the current active cert. */ +int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, + size_t serverinfo_length); +# ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); +# endif /* NO_STDIO */ + +# endif + +# ifndef OPENSSL_NO_STDIO +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_certificate_file(SSL *ssl, const char *file, int type); +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); +/* PEM type */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +# ifndef OPENSSL_SYS_VMS +/* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */ +# ifndef OPENSSL_SYS_MACINTOSH_CLASSIC +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); +# endif +# endif + +# endif + +void SSL_load_error_strings(void); +const char *SSL_state_string(const SSL *s); +const char *SSL_rstate_string(const SSL *s); +const char *SSL_state_string_long(const SSL *s); +const char *SSL_rstate_string_long(const SSL *s); +long SSL_SESSION_get_time(const SSL_SESSION *s); +long SSL_SESSION_set_time(SSL_SESSION *s, long t); +long SSL_SESSION_get_timeout(const SSL_SESSION *s); +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +void SSL_copy_session_id(SSL *to, const SSL *from); +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL_SESSION *SSL_SESSION_new(void); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); +# ifndef OPENSSL_NO_FP_API +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +# endif +# ifndef OPENSSL_NO_BIO +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +# endif +void SSL_SESSION_free(SSL_SESSION *ses); +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); +int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c); +int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); +int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB); +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +# ifdef HEADER_X509_H +X509 *SSL_get_peer_certificate(const SSL *s); +# endif + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, + X509_STORE_CTX *); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*callback) (int, X509_STORE_CTX *)); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg); +void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), + void *arg); +# ifndef OPENSSL_NO_RSA +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +# endif +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len); +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len); +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); + +int SSL_CTX_check_private_key(const SSL_CTX *ctx); +int SSL_check_private_key(const SSL *ctx); + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL *SSL_new(SSL_CTX *ctx); +int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose); +int SSL_set_purpose(SSL *s, int purpose); +int SSL_CTX_set_trust(SSL_CTX *s, int trust); +int SSL_set_trust(SSL *s, int trust); + +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +# ifndef OPENSSL_NO_SRP +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name); +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password); +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)); +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)); +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)); +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info); +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp); + +BIGNUM *SSL_get_srp_g(SSL *s); +BIGNUM *SSL_get_srp_N(SSL *s); + +char *SSL_get_srp_username(SSL *s); +char *SSL_get_srp_userinfo(SSL *s); +# endif + +void SSL_certs_clear(SSL *s); +void SSL_free(SSL *ssl); +int SSL_accept(SSL *ssl); +int SSL_connect(SSL *ssl); +int SSL_read(SSL *ssl, void *buf, int num); +int SSL_peek(SSL *ssl, void *buf, int num); +int SSL_write(SSL *ssl, const void *buf, int num); +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +int SSL_get_error(const SSL *s, int ret_code); +const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +# ifndef OPENSSL_NO_SSL2_METHOD +const SSL_METHOD *SSLv2_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ +# endif + +# ifndef OPENSSL_NO_SSL3_METHOD +const SSL_METHOD *SSLv3_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ +# endif + +const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS + * version */ +const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available + * SSL/TLS version */ +const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available + * SSL/TLS version */ + +const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ + +const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */ + +const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */ + +const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ + +const SSL_METHOD *DTLSv1_2_method(void); /* DTLSv1.2 */ +const SSL_METHOD *DTLSv1_2_server_method(void); /* DTLSv1.2 */ +const SSL_METHOD *DTLSv1_2_client_method(void); /* DTLSv1.2 */ + +const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */ +const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ +const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); + +int SSL_do_handshake(SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +int SSL_renegotiate_pending(SSL *s); +int SSL_shutdown(SSL *s); + +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); +const SSL_METHOD *SSL_get_ssl_method(SSL *s); +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +const char *SSL_alert_type_string_long(int value); +const char *SSL_alert_type_string(int value); +const char *SSL_alert_desc_string_long(int value); +const char *SSL_alert_desc_string(int value); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +int SSL_add_client_CA(SSL *ssl, X509 *x); +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +long SSL_get_default_timeout(const SSL *s); + +int SSL_library_init(void); + +char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk); + +SSL *SSL_dup(SSL *ssl); + +X509 *SSL_get_certificate(const SSL *ssl); +/* + * EVP_PKEY + */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl); + +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl, int mode); +int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl, int mode); +int SSL_get_shutdown(const SSL *ssl); +int SSL_version(const SSL *ssl); +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +# define SSL_get0_session SSL_get_session/* just peek at pointer */ +SSL_SESSION *SSL_get_session(const SSL *ssl); +SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type, + int val); +int SSL_state(const SSL *ssl); +void SSL_set_state(SSL *ssl, int state); + +void SSL_set_verify_result(SSL *ssl, long v); +long SSL_get_verify_result(const SSL *ssl); + +int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +# define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +# define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +# define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +# define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +# define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +# define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +# define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +# define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +# define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) + + /* NB: the keylength is only applicable when is_export is true */ +# ifndef OPENSSL_NO_RSA +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, + RSA *(*cb) (SSL *ssl, int is_export, + int keylength)); + +void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb) (SSL *ssl, int is_export, + int keylength)); +# endif +# ifndef OPENSSL_NO_DH +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +# endif +# ifndef OPENSSL_NO_ECDH +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_ecdh_callback(SSL *ssl, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)); +# endif + +const COMP_METHOD *SSL_get_current_compression(SSL *s); +const COMP_METHOD *SSL_get_current_expansion(SSL *s); +const char *SSL_COMP_get_name(const COMP_METHOD *comp); +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths); +void SSL_COMP_free_compression_methods(void); +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); + +/* TLS extensions functions */ +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn tls_session_secret_cb, + void *arg); + +void SSL_set_debug(SSL *s, int debug); +int SSL_cache_hit(SSL *s); +int SSL_is_server(SSL *s); + +SSL_CONF_CTX *SSL_CONF_CTX_new(void); +int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx); +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); +unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags); +int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre); + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); + +int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value); +int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv); +int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd); + +# ifndef OPENSSL_NO_SSL_TRACE +void SSL_trace(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); +const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c); +# endif + +# ifndef OPENSSL_NO_UNIT_TEST +const struct openssl_ssl_test_functions *SSL_test_functions(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_SSL_strings(void); + +/* Error codes for the SSL functions. */ + +/* Function codes. */ +# define SSL_F_CHECK_SUITEB_CIPHER_LIST 331 +# define SSL_F_CLIENT_CERTIFICATE 100 +# define SSL_F_CLIENT_FINISHED 167 +# define SSL_F_CLIENT_HELLO 101 +# define SSL_F_CLIENT_MASTER_KEY 102 +# define SSL_F_D2I_SSL_SESSION 103 +# define SSL_F_DO_DTLS1_WRITE 245 +# define SSL_F_DO_SSL3_WRITE 104 +# define SSL_F_DTLS1_ACCEPT 246 +# define SSL_F_DTLS1_ADD_CERT_TO_BUF 295 +# define SSL_F_DTLS1_BUFFER_RECORD 247 +# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 316 +# define SSL_F_DTLS1_CLIENT_HELLO 248 +# define SSL_F_DTLS1_CONNECT 249 +# define SSL_F_DTLS1_ENC 250 +# define SSL_F_DTLS1_GET_HELLO_VERIFY 251 +# define SSL_F_DTLS1_GET_MESSAGE 252 +# define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 +# define SSL_F_DTLS1_GET_RECORD 254 +# define SSL_F_DTLS1_HANDLE_TIMEOUT 297 +# define SSL_F_DTLS1_HEARTBEAT 305 +# define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 +# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 +# define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 +# define SSL_F_DTLS1_PROCESS_RECORD 257 +# define SSL_F_DTLS1_READ_BYTES 258 +# define SSL_F_DTLS1_READ_FAILED 259 +# define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST 260 +# define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE 261 +# define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE 262 +# define SSL_F_DTLS1_SEND_CLIENT_VERIFY 263 +# define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST 264 +# define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE 265 +# define SSL_F_DTLS1_SEND_SERVER_HELLO 266 +# define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE 267 +# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +# define SSL_F_GET_CLIENT_FINISHED 105 +# define SSL_F_GET_CLIENT_HELLO 106 +# define SSL_F_GET_CLIENT_MASTER_KEY 107 +# define SSL_F_GET_SERVER_FINISHED 108 +# define SSL_F_GET_SERVER_HELLO 109 +# define SSL_F_GET_SERVER_STATIC_DH_KEY 340 +# define SSL_F_GET_SERVER_VERIFY 110 +# define SSL_F_I2D_SSL_SESSION 111 +# define SSL_F_READ_N 112 +# define SSL_F_REQUEST_CERTIFICATE 113 +# define SSL_F_SERVER_FINISH 239 +# define SSL_F_SERVER_HELLO 114 +# define SSL_F_SERVER_VERIFY 240 +# define SSL_F_SSL23_ACCEPT 115 +# define SSL_F_SSL23_CLIENT_HELLO 116 +# define SSL_F_SSL23_CONNECT 117 +# define SSL_F_SSL23_GET_CLIENT_HELLO 118 +# define SSL_F_SSL23_GET_SERVER_HELLO 119 +# define SSL_F_SSL23_PEEK 237 +# define SSL_F_SSL23_READ 120 +# define SSL_F_SSL23_WRITE 121 +# define SSL_F_SSL2_ACCEPT 122 +# define SSL_F_SSL2_CONNECT 123 +# define SSL_F_SSL2_ENC_INIT 124 +# define SSL_F_SSL2_GENERATE_KEY_MATERIAL 241 +# define SSL_F_SSL2_PEEK 234 +# define SSL_F_SSL2_READ 125 +# define SSL_F_SSL2_READ_INTERNAL 236 +# define SSL_F_SSL2_SET_CERTIFICATE 126 +# define SSL_F_SSL2_WRITE 127 +# define SSL_F_SSL3_ACCEPT 128 +# define SSL_F_SSL3_ADD_CERT_TO_BUF 296 +# define SSL_F_SSL3_CALLBACK_CTRL 233 +# define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +# define SSL_F_SSL3_CHECK_CLIENT_HELLO 304 +# define SSL_F_SSL3_CHECK_FINISHED 339 +# define SSL_F_SSL3_CLIENT_HELLO 131 +# define SSL_F_SSL3_CONNECT 132 +# define SSL_F_SSL3_CTRL 213 +# define SSL_F_SSL3_CTX_CTRL 133 +# define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +# define SSL_F_SSL3_ENC 134 +# define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +# define SSL_F_SSL3_GENERATE_MASTER_SECRET 388 +# define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 +# define SSL_F_SSL3_GET_CERT_STATUS 289 +# define SSL_F_SSL3_GET_CERT_VERIFY 136 +# define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137 +# define SSL_F_SSL3_GET_CLIENT_HELLO 138 +# define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139 +# define SSL_F_SSL3_GET_FINISHED 140 +# define SSL_F_SSL3_GET_KEY_EXCHANGE 141 +# define SSL_F_SSL3_GET_MESSAGE 142 +# define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283 +# define SSL_F_SSL3_GET_NEXT_PROTO 306 +# define SSL_F_SSL3_GET_RECORD 143 +# define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 +# define SSL_F_SSL3_GET_SERVER_DONE 145 +# define SSL_F_SSL3_GET_SERVER_HELLO 146 +# define SSL_F_SSL3_HANDSHAKE_MAC 285 +# define SSL_F_SSL3_NEW_SESSION_TICKET 287 +# define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +# define SSL_F_SSL3_PEEK 235 +# define SSL_F_SSL3_READ_BYTES 148 +# define SSL_F_SSL3_READ_N 149 +# define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150 +# define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151 +# define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152 +# define SSL_F_SSL3_SEND_CLIENT_VERIFY 153 +# define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 +# define SSL_F_SSL3_SEND_SERVER_HELLO 242 +# define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 +# define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +# define SSL_F_SSL3_SETUP_READ_BUFFER 156 +# define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +# define SSL_F_SSL3_WRITE_BYTES 158 +# define SSL_F_SSL3_WRITE_PENDING 159 +# define SSL_F_SSL_ADD_CERT_CHAIN 318 +# define SSL_F_SSL_ADD_CERT_TO_BUF 319 +# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 +# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 +# define SSL_F_SSL_BAD_METHOD 160 +# define SSL_F_SSL_BUILD_CERT_CHAIN 332 +# define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +# define SSL_F_SSL_CERT_DUP 221 +# define SSL_F_SSL_CERT_INST 222 +# define SSL_F_SSL_CERT_INSTANTIATE 214 +# define SSL_F_SSL_CERT_NEW 162 +# define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +# define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +# define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +# define SSL_F_SSL_CLEAR 164 +# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +# define SSL_F_SSL_CONF_CMD 334 +# define SSL_F_SSL_CREATE_CIPHER_LIST 166 +# define SSL_F_SSL_CTRL 232 +# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +# define SSL_F_SSL_CTX_MAKE_PROFILES 309 +# define SSL_F_SSL_CTX_NEW 169 +# define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +# define SSL_F_SSL_CTX_SET_PURPOSE 226 +# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +# define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +# define SSL_F_SSL_CTX_SET_TRUST 229 +# define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +# define SSL_F_SSL_CTX_USE_SERVERINFO 336 +# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 337 +# define SSL_F_SSL_DO_HANDSHAKE 180 +# define SSL_F_SSL_GET_NEW_SESSION 181 +# define SSL_F_SSL_GET_PREV_SESSION 217 +# define SSL_F_SSL_GET_SERVER_CERT_INDEX 322 +# define SSL_F_SSL_GET_SERVER_SEND_CERT 182 +# define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 +# define SSL_F_SSL_GET_SIGN_PKEY 183 +# define SSL_F_SSL_INIT_WBIO_BUFFER 184 +# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +# define SSL_F_SSL_NEW 186 +# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 +# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 +# define SSL_F_SSL_PEEK 270 +# define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281 +# define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282 +# define SSL_F_SSL_READ 223 +# define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 +# define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 +# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 +# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 +# define SSL_F_SSL_SESSION_DUP 348 +# define SSL_F_SSL_SESSION_NEW 189 +# define SSL_F_SSL_SESSION_PRINT_FP 190 +# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +# define SSL_F_SSL_SESS_CERT_NEW 225 +# define SSL_F_SSL_SET_CERT 191 +# define SSL_F_SSL_SET_CIPHER_LIST 271 +# define SSL_F_SSL_SET_FD 192 +# define SSL_F_SSL_SET_PKEY 193 +# define SSL_F_SSL_SET_PURPOSE 227 +# define SSL_F_SSL_SET_RFD 194 +# define SSL_F_SSL_SET_SESSION 195 +# define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +# define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +# define SSL_F_SSL_SET_TRUST 228 +# define SSL_F_SSL_SET_WFD 196 +# define SSL_F_SSL_SHUTDOWN 224 +# define SSL_F_SSL_SRP_CTX_INIT 313 +# define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 +# define SSL_F_SSL_UNDEFINED_FUNCTION 197 +# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +# define SSL_F_SSL_USE_CERTIFICATE 198 +# define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +# define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +# define SSL_F_SSL_USE_PRIVATEKEY 201 +# define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +# define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +# define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +# define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +# define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +# define SSL_F_SSL_WRITE 208 +# define SSL_F_TLS12_CHECK_PEER_SIGALG 333 +# define SSL_F_TLS1_CERT_VERIFY_MAC 286 +# define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +# define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 +# define SSL_F_TLS1_ENC 210 +# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 +# define SSL_F_TLS1_GET_CURVELIST 338 +# define SSL_F_TLS1_HEARTBEAT 315 +# define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 +# define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 +# define SSL_F_TLS1_PRF 284 +# define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +# define SSL_F_TLS1_SET_SERVER_SIGALGS 335 +# define SSL_F_WRITE_PENDING 212 + +/* Reason codes. */ +# define SSL_R_APP_DATA_IN_HANDSHAKE 100 +# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +# define SSL_R_BAD_ALERT_RECORD 101 +# define SSL_R_BAD_AUTHENTICATION_TYPE 102 +# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +# define SSL_R_BAD_CHECKSUM 104 +# define SSL_R_BAD_DATA 390 +# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +# define SSL_R_BAD_DECOMPRESSION 107 +# define SSL_R_BAD_DH_G_LENGTH 108 +# define SSL_R_BAD_DH_G_VALUE 375 +# define SSL_R_BAD_DH_PUB_KEY_LENGTH 109 +# define SSL_R_BAD_DH_PUB_KEY_VALUE 393 +# define SSL_R_BAD_DH_P_LENGTH 110 +# define SSL_R_BAD_DH_P_VALUE 395 +# define SSL_R_BAD_DIGEST_LENGTH 111 +# define SSL_R_BAD_DSA_SIGNATURE 112 +# define SSL_R_BAD_ECC_CERT 304 +# define SSL_R_BAD_ECDSA_SIGNATURE 305 +# define SSL_R_BAD_ECPOINT 306 +# define SSL_R_BAD_HANDSHAKE_LENGTH 332 +# define SSL_R_BAD_HELLO_REQUEST 105 +# define SSL_R_BAD_LENGTH 271 +# define SSL_R_BAD_MAC_DECODE 113 +# define SSL_R_BAD_MAC_LENGTH 333 +# define SSL_R_BAD_MESSAGE_TYPE 114 +# define SSL_R_BAD_PACKET_LENGTH 115 +# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +# define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH 316 +# define SSL_R_BAD_RESPONSE_ARGUMENT 117 +# define SSL_R_BAD_RSA_DECRYPT 118 +# define SSL_R_BAD_RSA_ENCRYPT 119 +# define SSL_R_BAD_RSA_E_LENGTH 120 +# define SSL_R_BAD_RSA_MODULUS_LENGTH 121 +# define SSL_R_BAD_RSA_SIGNATURE 122 +# define SSL_R_BAD_SIGNATURE 123 +# define SSL_R_BAD_SRP_A_LENGTH 347 +# define SSL_R_BAD_SRP_B_LENGTH 348 +# define SSL_R_BAD_SRP_G_LENGTH 349 +# define SSL_R_BAD_SRP_N_LENGTH 350 +# define SSL_R_BAD_SRP_PARAMETERS 371 +# define SSL_R_BAD_SRP_S_LENGTH 351 +# define SSL_R_BAD_SRTP_MKI_VALUE 352 +# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 +# define SSL_R_BAD_SSL_FILETYPE 124 +# define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 +# define SSL_R_BAD_STATE 126 +# define SSL_R_BAD_VALUE 384 +# define SSL_R_BAD_WRITE_RETRY 127 +# define SSL_R_BIO_NOT_SET 128 +# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +# define SSL_R_BN_LIB 130 +# define SSL_R_CA_DN_LENGTH_MISMATCH 131 +# define SSL_R_CA_DN_TOO_LONG 132 +# define SSL_R_CCS_RECEIVED_EARLY 133 +# define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +# define SSL_R_CERT_CB_ERROR 377 +# define SSL_R_CERT_LENGTH_MISMATCH 135 +# define SSL_R_CHALLENGE_IS_DIFFERENT 136 +# define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +# define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +# define SSL_R_CLIENTHELLO_TLSEXT 226 +# define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +# define SSL_R_COMPRESSION_DISABLED 343 +# define SSL_R_COMPRESSION_FAILURE 141 +# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +# define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +# define SSL_R_CONNECTION_ID_IS_DIFFERENT 143 +# define SSL_R_CONNECTION_TYPE_NOT_SET 144 +# define SSL_R_COOKIE_MISMATCH 308 +# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +# define SSL_R_DATA_LENGTH_TOO_LONG 146 +# define SSL_R_DECRYPTION_FAILED 147 +# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +# define SSL_R_DH_KEY_TOO_SMALL 372 +# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +# define SSL_R_DIGEST_CHECK_FAILED 149 +# define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +# define SSL_R_DUPLICATE_COMPRESSION_ID 309 +# define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT 317 +# define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +# define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322 +# define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323 +# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE 374 +# define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310 +# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 +# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +# define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282 +# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +# define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +# define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +# define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355 +# define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356 +# define SSL_R_HTTPS_PROXY_REQUEST 155 +# define SSL_R_HTTP_REQUEST 156 +# define SSL_R_ILLEGAL_PADDING 283 +# define SSL_R_ILLEGAL_SUITEB_DIGEST 380 +# define SSL_R_INAPPROPRIATE_FALLBACK 373 +# define SSL_R_INCONSISTENT_COMPRESSION 340 +# define SSL_R_INVALID_CHALLENGE_LENGTH 158 +# define SSL_R_INVALID_COMMAND 280 +# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +# define SSL_R_INVALID_NULL_CMD_NAME 385 +# define SSL_R_INVALID_PURPOSE 278 +# define SSL_R_INVALID_SERVERINFO_DATA 388 +# define SSL_R_INVALID_SRP_USERNAME 357 +# define SSL_R_INVALID_STATUS_RESPONSE 328 +# define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +# define SSL_R_INVALID_TRUST 279 +# define SSL_R_KEY_ARG_TOO_LONG 284 +# define SSL_R_KRB5 285 +# define SSL_R_KRB5_C_CC_PRINC 286 +# define SSL_R_KRB5_C_GET_CRED 287 +# define SSL_R_KRB5_C_INIT 288 +# define SSL_R_KRB5_C_MK_REQ 289 +# define SSL_R_KRB5_S_BAD_TICKET 290 +# define SSL_R_KRB5_S_INIT 291 +# define SSL_R_KRB5_S_RD_REQ 292 +# define SSL_R_KRB5_S_TKT_EXPIRED 293 +# define SSL_R_KRB5_S_TKT_NYV 294 +# define SSL_R_KRB5_S_TKT_SKEW 295 +# define SSL_R_LENGTH_MISMATCH 159 +# define SSL_R_LENGTH_TOO_LONG 404 +# define SSL_R_LENGTH_TOO_SHORT 160 +# define SSL_R_LIBRARY_BUG 274 +# define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +# define SSL_R_MESSAGE_TOO_LONG 296 +# define SSL_R_MISSING_DH_DSA_CERT 162 +# define SSL_R_MISSING_DH_KEY 163 +# define SSL_R_MISSING_DH_RSA_CERT 164 +# define SSL_R_MISSING_DSA_SIGNING_CERT 165 +# define SSL_R_MISSING_ECDH_CERT 382 +# define SSL_R_MISSING_ECDSA_SIGNING_CERT 381 +# define SSL_R_MISSING_EXPORT_TMP_DH_KEY 166 +# define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 167 +# define SSL_R_MISSING_RSA_CERTIFICATE 168 +# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +# define SSL_R_MISSING_RSA_SIGNING_CERT 170 +# define SSL_R_MISSING_SRP_PARAM 358 +# define SSL_R_MISSING_TMP_DH_KEY 171 +# define SSL_R_MISSING_TMP_ECDH_KEY 311 +# define SSL_R_MISSING_TMP_RSA_KEY 172 +# define SSL_R_MISSING_TMP_RSA_PKEY 173 +# define SSL_R_MISSING_VERIFY_MESSAGE 174 +# define SSL_R_MULTIPLE_SGC_RESTARTS 346 +# define SSL_R_NON_SSLV2_INITIAL_PACKET 175 +# define SSL_R_NO_CERTIFICATES_RETURNED 176 +# define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +# define SSL_R_NO_CERTIFICATE_RETURNED 178 +# define SSL_R_NO_CERTIFICATE_SET 179 +# define SSL_R_NO_CERTIFICATE_SPECIFIED 180 +# define SSL_R_NO_CIPHERS_AVAILABLE 181 +# define SSL_R_NO_CIPHERS_PASSED 182 +# define SSL_R_NO_CIPHERS_SPECIFIED 183 +# define SSL_R_NO_CIPHER_LIST 184 +# define SSL_R_NO_CIPHER_MATCH 185 +# define SSL_R_NO_CLIENT_CERT_METHOD 331 +# define SSL_R_NO_CLIENT_CERT_RECEIVED 186 +# define SSL_R_NO_COMPRESSION_SPECIFIED 187 +# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +# define SSL_R_NO_METHOD_SPECIFIED 188 +# define SSL_R_NO_PEM_EXTENSIONS 389 +# define SSL_R_NO_PRIVATEKEY 189 +# define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +# define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +# define SSL_R_NO_PUBLICKEY 192 +# define SSL_R_NO_RENEGOTIATION 339 +# define SSL_R_NO_REQUIRED_DIGEST 324 +# define SSL_R_NO_SHARED_CIPHER 193 +# define SSL_R_NO_SHARED_SIGATURE_ALGORITHMS 376 +# define SSL_R_NO_SRTP_PROFILES 359 +# define SSL_R_NO_VERIFY_CALLBACK 194 +# define SSL_R_NULL_SSL_CTX 195 +# define SSL_R_NULL_SSL_METHOD_PASSED 196 +# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +# define SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE 387 +# define SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE 379 +# define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 +# define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG 327 +# define SSL_R_PACKET_LENGTH_TOO_LONG 198 +# define SSL_R_PARSE_TLSEXT 227 +# define SSL_R_PATH_TOO_LONG 270 +# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +# define SSL_R_PEER_ERROR 200 +# define SSL_R_PEER_ERROR_CERTIFICATE 201 +# define SSL_R_PEER_ERROR_NO_CERTIFICATE 202 +# define SSL_R_PEER_ERROR_NO_CIPHER 203 +# define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 204 +# define SSL_R_PEM_NAME_BAD_PREFIX 391 +# define SSL_R_PEM_NAME_TOO_SHORT 392 +# define SSL_R_PRE_MAC_LENGTH_TOO_LONG 205 +# define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 206 +# define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +# define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +# define SSL_R_PSK_NO_CLIENT_CB 224 +# define SSL_R_PSK_NO_SERVER_CB 225 +# define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 208 +# define SSL_R_PUBLIC_KEY_IS_NOT_RSA 209 +# define SSL_R_PUBLIC_KEY_NOT_RSA 210 +# define SSL_R_READ_BIO_NOT_SET 211 +# define SSL_R_READ_TIMEOUT_EXPIRED 312 +# define SSL_R_READ_WRONG_PACKET_TYPE 212 +# define SSL_R_RECORD_LENGTH_MISMATCH 213 +# define SSL_R_RECORD_TOO_LARGE 214 +# define SSL_R_RECORD_TOO_SMALL 298 +# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +# define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +# define SSL_R_RENEGOTIATION_MISMATCH 337 +# define SSL_R_REQUIRED_CIPHER_MISSING 215 +# define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING 342 +# define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 +# define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 +# define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 +# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +# define SSL_R_SERVERHELLO_TLSEXT 275 +# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +# define SSL_R_SHORT_READ 219 +# define SSL_R_SHUTDOWN_WHILE_IN_INIT 407 +# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 +# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +# define SSL_R_SRP_A_CALC 361 +# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 +# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 +# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 +# define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 +# define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 +# define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +# define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +# define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 +# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +# define SSL_R_SSL_HANDSHAKE_FAILURE 229 +# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +# define SSL_R_SSL_SESSION_ID_CONFLICT 302 +# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +# define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 231 +# define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +# define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +# define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +# define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +# define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +# define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 +# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 +# define SSL_R_TLS_HEARTBEAT_PENDING 366 +# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 +# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +# define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 +# define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 +# define SSL_R_TOO_MANY_WARN_ALERTS 409 +# define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 +# define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236 +# define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313 +# define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 237 +# define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 238 +# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +# define SSL_R_UNABLE_TO_FIND_SSL_METHOD 240 +# define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 241 +# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +# define SSL_R_UNEXPECTED_MESSAGE 244 +# define SSL_R_UNEXPECTED_RECORD 245 +# define SSL_R_UNINITIALIZED 276 +# define SSL_R_UNKNOWN_ALERT_TYPE 246 +# define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +# define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +# define SSL_R_UNKNOWN_CIPHER_TYPE 249 +# define SSL_R_UNKNOWN_CMD_NAME 386 +# define SSL_R_UNKNOWN_DIGEST 368 +# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +# define SSL_R_UNKNOWN_PKEY_TYPE 251 +# define SSL_R_UNKNOWN_PROTOCOL 252 +# define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 +# define SSL_R_UNKNOWN_SSL_VERSION 254 +# define SSL_R_UNKNOWN_STATE 255 +# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +# define SSL_R_UNSUPPORTED_CIPHER 256 +# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +# define SSL_R_UNSUPPORTED_DIGEST_TYPE 326 +# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +# define SSL_R_UNSUPPORTED_PROTOCOL 258 +# define SSL_R_UNSUPPORTED_SSL_VERSION 259 +# define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +# define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +# define SSL_R_WRITE_BIO_NOT_SET 260 +# define SSL_R_WRONG_CERTIFICATE_TYPE 383 +# define SSL_R_WRONG_CIPHER_RETURNED 261 +# define SSL_R_WRONG_CURVE 378 +# define SSL_R_WRONG_MESSAGE_TYPE 262 +# define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263 +# define SSL_R_WRONG_SIGNATURE_LENGTH 264 +# define SSL_R_WRONG_SIGNATURE_SIZE 265 +# define SSL_R_WRONG_SIGNATURE_TYPE 370 +# define SSL_R_WRONG_SSL_VERSION 266 +# define SSL_R_WRONG_VERSION_NUMBER 267 +# define SSL_R_X509_LIB 268 +# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ssl2.h b/Sources/COpenSSL/ssl2.h new file mode 100644 index 00000000..03c7dd8c --- /dev/null +++ b/Sources/COpenSSL/ssl2.h @@ -0,0 +1,265 @@ +/* ssl/ssl2.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL2_H +# define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Protocol Version Codes */ +# define SSL2_VERSION 0x0002 +# define SSL2_VERSION_MAJOR 0x00 +# define SSL2_VERSION_MINOR 0x02 +/* #define SSL2_CLIENT_VERSION 0x0002 */ +/* #define SSL2_SERVER_VERSION 0x0002 */ + +/* Protocol Message Codes */ +# define SSL2_MT_ERROR 0 +# define SSL2_MT_CLIENT_HELLO 1 +# define SSL2_MT_CLIENT_MASTER_KEY 2 +# define SSL2_MT_CLIENT_FINISHED 3 +# define SSL2_MT_SERVER_HELLO 4 +# define SSL2_MT_SERVER_VERIFY 5 +# define SSL2_MT_SERVER_FINISHED 6 +# define SSL2_MT_REQUEST_CERTIFICATE 7 +# define SSL2_MT_CLIENT_CERTIFICATE 8 + +/* Error Message Codes */ +# define SSL2_PE_UNDEFINED_ERROR 0x0000 +# define SSL2_PE_NO_CIPHER 0x0001 +# define SSL2_PE_NO_CERTIFICATE 0x0002 +# define SSL2_PE_BAD_CERTIFICATE 0x0004 +# define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006 + +/* Cipher Kind Values */ +# define SSL2_CK_NULL_WITH_MD5 0x02000000/* v3 */ +# define SSL2_CK_RC4_128_WITH_MD5 0x02010080 +# define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080 +# define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080 +# define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080 +# define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080 +# define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040 +# define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140/* v3 */ +# define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0 +# define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0/* v3 */ +# define SSL2_CK_RC4_64_WITH_MD5 0x02080080/* MS hack */ + +# define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800/* SSLeay */ +# define SSL2_CK_NULL 0x02ff0810/* SSLeay */ + +# define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1" +# define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5" +# define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5" +# define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5" +# define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5" +# define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5" +# define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5" +# define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5" +# define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA" +# define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5" +# define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA" +# define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5" + +# define SSL2_TXT_NULL "NULL" + +/* Flags for the SSL_CIPHER.algorithm2 field */ +# define SSL2_CF_5_BYTE_ENC 0x01 +# define SSL2_CF_8_BYTE_ENC 0x02 + +/* Certificate Type Codes */ +# define SSL2_CT_X509_CERTIFICATE 0x01 + +/* Authentication Type Code */ +# define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01 + +# define SSL2_MAX_SSL_SESSION_ID_LENGTH 32 + +/* Upper/Lower Bounds */ +# define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256 +# ifdef OPENSSL_SYS_MPE +# define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 29998u +# else +# define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u + /* 2^15-1 */ +# endif +# define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383/* 2^14-1 */ + +# define SSL2_CHALLENGE_LENGTH 16 +/* + * #define SSL2_CHALLENGE_LENGTH 32 + */ +# define SSL2_MIN_CHALLENGE_LENGTH 16 +# define SSL2_MAX_CHALLENGE_LENGTH 32 +# define SSL2_CONNECTION_ID_LENGTH 16 +# define SSL2_MAX_CONNECTION_ID_LENGTH 16 +# define SSL2_SSL_SESSION_ID_LENGTH 16 +# define SSL2_MAX_CERT_CHALLENGE_LENGTH 32 +# define SSL2_MIN_CERT_CHALLENGE_LENGTH 16 +# define SSL2_MAX_KEY_MATERIAL_LENGTH 24 + +# ifndef HEADER_SSL_LOCL_H +# define CERT char +# endif + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl2_state_st { + int three_byte_header; + int clear_text; /* clear text */ + int escape; /* not used in SSLv2 */ + int ssl2_rollback; /* used if SSLv23 rolled back to SSLv2 */ + /* + * non-blocking io info, used to make sure the same args were passwd + */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; + const unsigned char *wpend_buf; + int wpend_off; /* offset to data to write */ + int wpend_len; /* number of bytes passwd to write */ + int wpend_ret; /* number of bytes to return to caller */ + /* buffer raw data */ + int rbuf_left; + int rbuf_offs; + unsigned char *rbuf; + unsigned char *wbuf; + unsigned char *write_ptr; /* used to point to the start due to 2/3 byte + * header. */ + unsigned int padding; + unsigned int rlength; /* passed to ssl2_enc */ + int ract_data_length; /* Set when things are encrypted. */ + unsigned int wlength; /* passed to ssl2_enc */ + int wact_data_length; /* Set when things are decrypted. */ + unsigned char *ract_data; + unsigned char *wact_data; + unsigned char *mac_data; + unsigned char *read_key; + unsigned char *write_key; + /* Stuff specifically to do with this SSL session */ + unsigned int challenge_length; + unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH]; + unsigned int conn_id_length; + unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH]; + unsigned int key_material_length; + unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH * 2]; + unsigned long read_sequence; + unsigned long write_sequence; + struct { + unsigned int conn_id_length; + unsigned int cert_type; + unsigned int cert_length; + unsigned int csl; + unsigned int clear; + unsigned int enc; + unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH]; + unsigned int cipher_spec_length; + unsigned int session_id_length; + unsigned int clen; + unsigned int rlen; + } tmp; +} SSL2_STATE; + +# endif + +/* SSLv2 */ +/* client */ +# define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_HELLO_B (0x11|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_HELLO_A (0x20|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_HELLO_B (0x21|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_MASTER_KEY_A (0x30|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_MASTER_KEY_B (0x31|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_FINISHED_A (0x40|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_FINISHED_B (0x41|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_A (0x50|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_B (0x51|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_C (0x52|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_D (0x53|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_VERIFY_A (0x60|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_VERIFY_B (0x61|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_FINISHED_A (0x70|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_FINISHED_B (0x71|SSL_ST_CONNECT) +# define SSL2_ST_CLIENT_START_ENCRYPTION (0x80|SSL_ST_CONNECT) +# define SSL2_ST_X509_GET_CLIENT_CERTIFICATE (0x90|SSL_ST_CONNECT) +/* server */ +# define SSL2_ST_GET_CLIENT_HELLO_A (0x10|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_HELLO_B (0x11|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_HELLO_C (0x12|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_HELLO_A (0x20|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_HELLO_B (0x21|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_MASTER_KEY_A (0x30|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_MASTER_KEY_B (0x31|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_A (0x40|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_B (0x41|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_C (0x42|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_FINISHED_A (0x50|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_FINISHED_B (0x51|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_FINISHED_A (0x60|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_FINISHED_B (0x61|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_A (0x70|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_B (0x71|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_C (0x72|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_D (0x73|SSL_ST_ACCEPT) +# define SSL2_ST_SERVER_START_ENCRYPTION (0x80|SSL_ST_ACCEPT) +# define SSL2_ST_X509_GET_SERVER_CERTIFICATE (0x90|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ssl23.h b/Sources/COpenSSL/ssl23.h new file mode 100644 index 00000000..9de4685a --- /dev/null +++ b/Sources/COpenSSL/ssl23.h @@ -0,0 +1,84 @@ +/* ssl/ssl23.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL23_H +# define HEADER_SSL23_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * client + */ +/* write to server */ +# define SSL23_ST_CW_CLNT_HELLO_A (0x210|SSL_ST_CONNECT) +# define SSL23_ST_CW_CLNT_HELLO_B (0x211|SSL_ST_CONNECT) +/* read from server */ +# define SSL23_ST_CR_SRVR_HELLO_A (0x220|SSL_ST_CONNECT) +# define SSL23_ST_CR_SRVR_HELLO_B (0x221|SSL_ST_CONNECT) + +/* server */ +/* read from client */ +# define SSL23_ST_SR_CLNT_HELLO_A (0x210|SSL_ST_ACCEPT) +# define SSL23_ST_SR_CLNT_HELLO_B (0x211|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ssl3.h b/Sources/COpenSSL/ssl3.h new file mode 100644 index 00000000..328f72cd --- /dev/null +++ b/Sources/COpenSSL/ssl3.h @@ -0,0 +1,774 @@ +/* ssl/ssl3.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_SSL3_H +# define HEADER_SSL3_H + +# ifndef OPENSSL_NO_COMP +# include "comp.h" +# endif +# include "buffer.h" +# include "evp.h" +# include "ssl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Signalling cipher suite value from RFC 5746 + * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + */ +# define SSL3_CK_SCSV 0x030000FF + +/* + * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 + * (TLS_FALLBACK_SCSV) + */ +# define SSL3_CK_FALLBACK_SCSV 0x03005600 + +# define SSL3_CK_RSA_NULL_MD5 0x03000001 +# define SSL3_CK_RSA_NULL_SHA 0x03000002 +# define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +# define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +# define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +# define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +# define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +# define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +# define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +# define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +# define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +# define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +# define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +# define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA 0x03000011 +# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA SSL3_CK_EDH_DSS_DES_40_CBC_SHA +# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA 0x03000012 +# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA SSL3_CK_EDH_DSS_DES_64_CBC_SHA +# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA SSL3_CK_EDH_DSS_DES_192_CBC3_SHA +# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA SSL3_CK_EDH_RSA_DES_40_CBC_SHA +# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA SSL3_CK_EDH_RSA_DES_64_CBC_SHA +# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 +# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA SSL3_CK_EDH_RSA_DES_192_CBC3_SHA + +# define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +# define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +# define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +# define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +# define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +# if 0 +# define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C +# define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D +# if 0 /* Because it clashes with KRB5, is never + * used any more, and is safe to remove + * according to David Hopwood + * of the + * ietf-tls list */ +# define SSL3_CK_FZA_DMS_RC4_SHA 0x0300001E +# endif +# endif + +/* + * VRS Additional Kerberos5 entries + */ +# define SSL3_CK_KRB5_DES_64_CBC_SHA 0x0300001E +# define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x0300001F +# define SSL3_CK_KRB5_RC4_128_SHA 0x03000020 +# define SSL3_CK_KRB5_IDEA_128_CBC_SHA 0x03000021 +# define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000022 +# define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000023 +# define SSL3_CK_KRB5_RC4_128_MD5 0x03000024 +# define SSL3_CK_KRB5_IDEA_128_CBC_MD5 0x03000025 + +# define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000026 +# define SSL3_CK_KRB5_RC2_40_CBC_SHA 0x03000027 +# define SSL3_CK_KRB5_RC4_40_SHA 0x03000028 +# define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000029 +# define SSL3_CK_KRB5_RC2_40_CBC_MD5 0x0300002A +# define SSL3_CK_KRB5_RC4_40_MD5 0x0300002B + +# define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +# define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +# define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +# define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +# define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +# define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA "EXP-DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA "DHE-DSS-DES-CBC-SHA" +# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA "DHE-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA "EXP-DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA "DHE-RSA-DES-CBC-SHA" +# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA "DHE-RSA-DES-CBC3-SHA" + +/* + * This next block of six "EDH" labels is for backward compatibility with + * older versions of OpenSSL. New code should use the six "DHE" labels above + * instead: + */ +# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +# define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +# define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +# if 0 +# define SSL3_TXT_FZA_DMS_NULL_SHA "FZA-NULL-SHA" +# define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" +# define SSL3_TXT_FZA_DMS_RC4_SHA "FZA-RC4-SHA" +# endif + +# define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" +# define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" +# define SSL3_TXT_KRB5_RC4_128_SHA "KRB5-RC4-SHA" +# define SSL3_TXT_KRB5_IDEA_128_CBC_SHA "KRB5-IDEA-CBC-SHA" +# define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" +# define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" +# define SSL3_TXT_KRB5_RC4_128_MD5 "KRB5-RC4-MD5" +# define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 "KRB5-IDEA-CBC-MD5" + +# define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" +# define SSL3_TXT_KRB5_RC2_40_CBC_SHA "EXP-KRB5-RC2-CBC-SHA" +# define SSL3_TXT_KRB5_RC4_40_SHA "EXP-KRB5-RC4-SHA" +# define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" +# define SSL3_TXT_KRB5_RC2_40_CBC_MD5 "EXP-KRB5-RC2-CBC-MD5" +# define SSL3_TXT_KRB5_RC4_40_MD5 "EXP-KRB5-RC4-MD5" + +# define SSL3_SSL_SESSION_ID_LENGTH 32 +# define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +# define SSL3_MASTER_SECRET_SIZE 48 +# define SSL3_RANDOM_SIZE 32 +# define SSL3_SESSION_ID_SIZE 32 +# define SSL3_RT_HEADER_LENGTH 5 + +# define SSL3_HM_HEADER_LENGTH 4 + +# ifndef SSL3_ALIGN_PAYLOAD + /* + * Some will argue that this increases memory footprint, but it's not + * actually true. Point is that malloc has to return at least 64-bit aligned + * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case. + * Suggested pre-gaping simply moves these wasted bytes from the end of + * allocated region to its front, but makes data payload aligned, which + * improves performance:-) + */ +# define SSL3_ALIGN_PAYLOAD 8 +# else +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 +# error "insane SSL3_ALIGN_PAYLOAD" +# undef SSL3_ALIGN_PAYLOAD +# endif +# endif + +/* + * This is the maximum MAC (digest) size used by the SSL library. Currently + * maximum of 20 is used by SHA1, but we reserve for future extension for + * 512-bit hashes. + */ + +# define SSL3_RT_MAX_MD_SIZE 64 + +/* + * Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +# define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +# define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* + * The standards give a maximum encryption overhead of 1024 bytes. In + * practice the value is lower than this. The overhead is the maximum number + * of padding bytes (256) plus the mac size. + */ +# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +/* + * OpenSSL currently only uses a padding length of at most one block so the + * send overhead is smaller. + */ + +# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ + +# ifdef OPENSSL_NO_COMP +# define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +# else +# define SSL3_RT_MAX_COMPRESSED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) +# endif +# define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +# define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +# define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +# define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +# define SSL3_VERSION 0x0300 +# define SSL3_VERSION_MAJOR 0x03 +# define SSL3_VERSION_MINOR 0x00 + +# define SSL3_RT_CHANGE_CIPHER_SPEC 20 +# define SSL3_RT_ALERT 21 +# define SSL3_RT_HANDSHAKE 22 +# define SSL3_RT_APPLICATION_DATA 23 +# define TLS1_RT_HEARTBEAT 24 + +/* Pseudo content types to indicate additional parameters */ +# define TLS1_RT_CRYPTO 0x1000 +# define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1) +# define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2) +# define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3) +# define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4) + +# define TLS1_RT_CRYPTO_READ 0x0000 +# define TLS1_RT_CRYPTO_WRITE 0x0100 +# define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5) +# define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6) +# define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7) +# define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8) + +/* Pseudo content type for SSL/TLS header info */ +# define SSL3_RT_HEADER 0x100 + +# define SSL3_AL_WARNING 1 +# define SSL3_AL_FATAL 2 + +# define SSL3_AD_CLOSE_NOTIFY 0 +# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ +# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ +# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ +# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ +# define SSL3_AD_NO_CERTIFICATE 41 +# define SSL3_AD_BAD_CERTIFICATE 42 +# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +# define SSL3_AD_CERTIFICATE_REVOKED 44 +# define SSL3_AD_CERTIFICATE_EXPIRED 45 +# define SSL3_AD_CERTIFICATE_UNKNOWN 46 +# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ + +# define TLS1_HB_REQUEST 1 +# define TLS1_HB_RESPONSE 2 + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl3_record_st { + /* type of record */ + /* + * r + */ int type; + /* How many bytes available */ + /* + * rw + */ unsigned int length; + /* read/write offset into 'buf' */ + /* + * r + */ unsigned int off; + /* pointer to the record data */ + /* + * rw + */ unsigned char *data; + /* where the decode bytes are */ + /* + * rw + */ unsigned char *input; + /* only used with decompression - malloc()ed */ + /* + * r + */ unsigned char *comp; + /* epoch number, needed by DTLS1 */ + /* + * r + */ unsigned long epoch; + /* sequence number, needed by DTLS1 */ + /* + * r + */ unsigned char seq_num[8]; +} SSL3_RECORD; + +typedef struct ssl3_buffer_st { + /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */ + unsigned char *buf; + /* buffer size */ + size_t len; + /* where to 'copy from' */ + int offset; + /* how many bytes left */ + int left; +} SSL3_BUFFER; + +# endif + +# define SSL3_CT_RSA_SIGN 1 +# define SSL3_CT_DSS_SIGN 2 +# define SSL3_CT_RSA_FIXED_DH 3 +# define SSL3_CT_DSS_FIXED_DH 4 +# define SSL3_CT_RSA_EPHEMERAL_DH 5 +# define SSL3_CT_DSS_EPHEMERAL_DH 6 +# define SSL3_CT_FORTEZZA_DMS 20 +/* + * SSL3_CT_NUMBER is used to size arrays and it must be large enough to + * contain all of the cert types defined either for SSLv3 and TLSv1. + */ +# define SSL3_CT_NUMBER 9 + +# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 +# define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 +# define SSL3_FLAGS_POP_BUFFER 0x0004 +# define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 +# define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 +# define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 +/* + * Set when the handshake is ready to process peer's ChangeCipherSpec message. + * Cleared after the message has been processed. + */ +# define SSL3_FLAGS_CCS_OK 0x0080 + +/* SSL3_FLAGS_SGC_RESTART_DONE is no longer used */ +# define SSL3_FLAGS_SGC_RESTART_DONE 0x0040 + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl3_state_st { + long flags; + int delay_buf_pop_ret; + unsigned char read_sequence[8]; + int read_mac_secret_size; + unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char write_sequence[8]; + int write_mac_secret_size; + unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char server_random[SSL3_RANDOM_SIZE]; + unsigned char client_random[SSL3_RANDOM_SIZE]; + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + /* The value of 'extra' when the buffers were initialized */ + int init_extra; + SSL3_BUFFER rbuf; /* read IO goes into here */ + SSL3_BUFFER wbuf; /* write IO goes into here */ + SSL3_RECORD rrec; /* each decoded record goes in here */ + SSL3_RECORD wrec; /* goes out from here */ + /* + * storage for Alert/Handshake protocol data received but not yet + * processed by ssl3_read_bytes: + */ + unsigned char alert_fragment[2]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[4]; + unsigned int handshake_fragment_len; + /* partial write - check the numbers match */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; /* number bytes written */ + int wpend_type; + int wpend_ret; /* number of bytes submitted */ + const unsigned char *wpend_buf; + /* used during startup, digest all incoming/outgoing packets */ + BIO *handshake_buffer; + /* + * When set of handshake digests is determined, buffer is hashed and + * freed and MD_CTX-es for all required digests are stored in this array + */ + EVP_MD_CTX **handshake_dgst; + /* + * Set whenever an expected ChangeCipherSpec message is processed. + * Unset when the peer's Finished message is received. + * Unexpected ChangeCipherSpec messages trigger a fatal alert. + */ + int change_cipher_spec; + int warn_alert; + int fatal_alert; + /* + * we allow one fatal and one warning alert to be outstanding, send close + * alert via the warning alert + */ + int alert_dispatch; + unsigned char send_alert[2]; + /* + * This flag is set when we should renegotiate ASAP, basically when there + * is no more data in the read or write buffers + */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + int in_read_app_data; + /* + * Opaque PRF input as used for the current handshake. These fields are + * used only if TLSEXT_TYPE_opaque_prf_input is defined (otherwise, they + * are merely present to improve binary compatibility) + */ + void *client_opaque_prf_input; + size_t client_opaque_prf_input_len; + void *server_opaque_prf_input; + size_t server_opaque_prf_input_len; + struct { + /* actually only needs to be 16+20 */ + unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2]; + /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ + unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; + int finish_md_len; + unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2]; + int peer_finish_md_len; + unsigned long message_size; + int message_type; + /* used to hold the new cipher we are going to use */ + const SSL_CIPHER *new_cipher; +# ifndef OPENSSL_NO_DH + DH *dh; +# endif +# ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh; /* holds short lived ECDH key */ +# endif + /* used when SSL_ST_FLUSH_DATA is entered */ + int next_state; + int reuse_message; + /* used for certificate requests */ + int cert_req; + int ctype_num; + char ctype[SSL3_CT_NUMBER]; + STACK_OF(X509_NAME) *ca_names; + int use_rsa_tmp; + int key_block_length; + unsigned char *key_block; + const EVP_CIPHER *new_sym_enc; + const EVP_MD *new_hash; + int new_mac_pkey_type; + int new_mac_secret_size; +# ifndef OPENSSL_NO_COMP + const SSL_COMP *new_compression; +# else + char *new_compression; +# endif + int cert_request; + } tmp; + + /* Connection binding to prevent renegotiation attacks */ + unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_client_finished_len; + unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_server_finished_len; + int send_connection_binding; /* TODOEKR */ + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Set if we saw the Next Protocol Negotiation extension from our peer. + */ + int next_proto_neg_seen; +# endif + +# ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC + /* + * This is set to true if we believe that this is a version of Safari + * running on OS X 10.6 or newer. We wish to know this because Safari on + * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. + */ + char is_probably_safari; +# endif /* !OPENSSL_NO_EC */ + + /* + * ALPN information (we are in the process of transitioning from NPN to + * ALPN.) + */ + + /* + * In a server these point to the selected ALPN protocol after the + * ClientHello has been processed. In a client these contain the protocol + * that the server selected once the ServerHello has been processed. + */ + unsigned char *alpn_selected; + unsigned alpn_selected_len; +# endif /* OPENSSL_NO_TLSEXT */ +} SSL3_STATE; + +# endif + +/* SSLv3 */ +/* + * client + */ +/* extra state */ +# define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT) +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_ST_CW_WRITE_SOCK (0x310|SSL_ST_CONNECT) +# define DTLS1_SCTP_ST_CR_READ_SOCK (0x320|SSL_ST_CONNECT) +# endif +/* write to server */ +# define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT) +# define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT) +/* read from server */ +# define SSL3_ST_CR_SRVR_HELLO_A (0x120|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_HELLO_B (0x121|SSL_ST_CONNECT) +# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT) +# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_A (0x130|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_B (0x131|SSL_ST_CONNECT) +# define SSL3_ST_CR_KEY_EXCH_A (0x140|SSL_ST_CONNECT) +# define SSL3_ST_CR_KEY_EXCH_B (0x141|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_REQ_A (0x150|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT) +/* write to server */ +# define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_C (0x172|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_D (0x173|SSL_ST_CONNECT) +# define SSL3_ST_CW_KEY_EXCH_A (0x180|SSL_ST_CONNECT) +# define SSL3_ST_CW_KEY_EXCH_B (0x181|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_VRFY_A (0x190|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT) +# define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT) +# define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT) +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT) +# define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT) +# endif +# define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) +# define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT) +/* read from server */ +# define SSL3_ST_CR_CHANGE_A (0x1C0|SSL_ST_CONNECT) +# define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT) +# define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT) +# define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT) +# define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT) +# define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT) + +/* server */ +/* extra state */ +# define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT) +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_ST_SW_WRITE_SOCK (0x310|SSL_ST_ACCEPT) +# define DTLS1_SCTP_ST_SR_READ_SOCK (0x320|SSL_ST_ACCEPT) +# endif +/* read from client */ +/* Do not change the number values, they do matter */ +# define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CLNT_HELLO_D (0x115|SSL_ST_ACCEPT) +/* write to client */ +# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) +# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_A (0x120|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_B (0x121|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_C (0x122|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_HELLO_A (0x130|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_HELLO_B (0x131|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_A (0x140|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_B (0x141|SSL_ST_ACCEPT) +# define SSL3_ST_SW_KEY_EXCH_A (0x150|SSL_ST_ACCEPT) +# define SSL3_ST_SW_KEY_EXCH_B (0x151|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_REQ_A (0x160|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_REQ_B (0x161|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_DONE_A (0x170|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_DONE_B (0x171|SSL_ST_ACCEPT) +/* read from client */ +# define SSL3_ST_SR_CERT_A (0x180|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_B (0x181|SSL_ST_ACCEPT) +# define SSL3_ST_SR_KEY_EXCH_A (0x190|SSL_ST_ACCEPT) +# define SSL3_ST_SR_KEY_EXCH_B (0x191|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_VRFY_A (0x1A0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT) +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT) +# define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT) +# endif +# define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT) +/* write to client */ +# define SSL3_ST_SW_CHANGE_A (0x1D0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT) + +# define SSL3_MT_HELLO_REQUEST 0 +# define SSL3_MT_CLIENT_HELLO 1 +# define SSL3_MT_SERVER_HELLO 2 +# define SSL3_MT_NEWSESSION_TICKET 4 +# define SSL3_MT_CERTIFICATE 11 +# define SSL3_MT_SERVER_KEY_EXCHANGE 12 +# define SSL3_MT_CERTIFICATE_REQUEST 13 +# define SSL3_MT_SERVER_DONE 14 +# define SSL3_MT_CERTIFICATE_VERIFY 15 +# define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +# define SSL3_MT_FINISHED 20 +# define SSL3_MT_CERTIFICATE_STATUS 22 +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_MT_NEXT_PROTO 67 +# endif +# define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +# define SSL3_MT_CCS 1 + +/* These are used when changing over to a new cipher */ +# define SSL3_CC_READ 0x01 +# define SSL3_CC_WRITE 0x02 +# define SSL3_CC_CLIENT 0x10 +# define SSL3_CC_SERVER 0x20 +# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +# define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ssl_.c b/Sources/COpenSSL/ssl_.c new file mode 100644 index 00000000..2e37265c --- /dev/null +++ b/Sources/COpenSSL/ssl_.c @@ -0,0 +1,13100 @@ +/* ssl/ssl_algs.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "objects.h" +#include "lhash.h" +#include "ssl_locl.h" + +int SSL_library_init(void) +{ + +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); +#endif +#ifndef OPENSSL_NO_IDEA + EVP_add_cipher(EVP_idea_cbc()); +#endif +#ifndef OPENSSL_NO_RC4 + EVP_add_cipher(EVP_rc4()); +# if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) + EVP_add_cipher(EVP_rc4_hmac_md5()); +# endif +#endif +#ifndef OPENSSL_NO_RC2 + EVP_add_cipher(EVP_rc2_cbc()); + /* + * Not actually used for SSL/TLS but this makes PKCS#12 work if an + * application only calls SSL_library_init(). + */ + EVP_add_cipher(EVP_rc2_40_cbc()); +#endif +#ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_256_gcm()); +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); +# endif +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); +# endif + +#endif +#ifndef OPENSSL_NO_CAMELLIA + EVP_add_cipher(EVP_camellia_128_cbc()); + EVP_add_cipher(EVP_camellia_256_cbc()); +#endif + +#ifndef OPENSSL_NO_SEED + EVP_add_cipher(EVP_seed_cbc()); +#endif + +#ifndef OPENSSL_NO_MD5 + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); +#endif +#ifndef OPENSSL_NO_SHA + EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); +#endif +#ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +#endif +#ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +#endif +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) + EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ + EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); +#endif +#ifndef OPENSSL_NO_ECDSA + EVP_add_digest(EVP_ecdsa()); +#endif + /* If you want support for phased out ciphers, add the following */ +#if 0 + EVP_add_digest(EVP_sha()); + EVP_add_digest(EVP_dss()); +#endif +#ifndef OPENSSL_NO_COMP + /* + * This will initialise the built-in compression algorithms. The value + * returned is a STACK_OF(SSL_COMP), but that can be discarded safely + */ + (void)SSL_COMP_get_compression_methods(); +#endif + /* initialize cipher/digest methods table */ + ssl_load_ciphers(); + return (1); +} +/* ssl/ssl_asn1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +// #include "ssl_locl.h" +#include "asn1_mac.h" +// #include "objects.h" +#include "x509.h" + +typedef struct ssl_session_asn1_st { + ASN1_INTEGER version; + ASN1_INTEGER ssl_version; + ASN1_OCTET_STRING cipher; + ASN1_OCTET_STRING comp_id; + ASN1_OCTET_STRING master_key; + ASN1_OCTET_STRING session_id; + ASN1_OCTET_STRING session_id_context; + ASN1_OCTET_STRING key_arg; +#ifndef OPENSSL_NO_KRB5 + ASN1_OCTET_STRING krb5_princ; +#endif /* OPENSSL_NO_KRB5 */ + ASN1_INTEGER time; + ASN1_INTEGER timeout; + ASN1_INTEGER verify_result; +#ifndef OPENSSL_NO_TLSEXT + ASN1_OCTET_STRING tlsext_hostname; + ASN1_INTEGER tlsext_tick_lifetime; + ASN1_OCTET_STRING tlsext_tick; +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + ASN1_OCTET_STRING psk_identity_hint; + ASN1_OCTET_STRING psk_identity; +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + ASN1_OCTET_STRING srp_username; +#endif /* OPENSSL_NO_SRP */ +} SSL_SESSION_ASN1; + +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) +{ +#define LSIZE2 (sizeof(long)*2) + int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0; + unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2]; + unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2]; +#ifndef OPENSSL_NO_TLSEXT + int v6 = 0, v9 = 0, v10 = 0; + unsigned char ibuf6[LSIZE2]; +#endif +#ifndef OPENSSL_NO_PSK + int v7 = 0, v8 = 0; +#endif +#ifndef OPENSSL_NO_COMP + unsigned char cbuf; + int v11 = 0; +#endif +#ifndef OPENSSL_NO_SRP + int v12 = 0; +#endif + long l; + SSL_SESSION_ASN1 a; + M_ASN1_I2D_vars(in); + + if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0))) + return (0); + + /* + * Note that I cheat in the following 2 assignments. I know that if the + * ASN1_INTEGER passed to ASN1_INTEGER_set is > sizeof(long)+1, the + * buffer will not be re-OPENSSL_malloc()ed. This is a bit evil but makes + * things simple, no dynamic allocation to clean up :-) + */ + a.version.length = LSIZE2; + a.version.type = V_ASN1_INTEGER; + a.version.data = ibuf1; + ASN1_INTEGER_set(&(a.version), SSL_SESSION_ASN1_VERSION); + + a.ssl_version.length = LSIZE2; + a.ssl_version.type = V_ASN1_INTEGER; + a.ssl_version.data = ibuf2; + ASN1_INTEGER_set(&(a.ssl_version), in->ssl_version); + + a.cipher.type = V_ASN1_OCTET_STRING; + a.cipher.data = buf; + + if (in->cipher == NULL) + l = in->cipher_id; + else + l = in->cipher->id; + if (in->ssl_version == SSL2_VERSION) { + a.cipher.length = 3; + buf[0] = ((unsigned char)(l >> 16L)) & 0xff; + buf[1] = ((unsigned char)(l >> 8L)) & 0xff; + buf[2] = ((unsigned char)(l)) & 0xff; + } else { + a.cipher.length = 2; + buf[0] = ((unsigned char)(l >> 8L)) & 0xff; + buf[1] = ((unsigned char)(l)) & 0xff; + } + +#ifndef OPENSSL_NO_COMP + if (in->compress_meth) { + cbuf = (unsigned char)in->compress_meth; + a.comp_id.length = 1; + a.comp_id.type = V_ASN1_OCTET_STRING; + a.comp_id.data = &cbuf; + } +#endif + + a.master_key.length = in->master_key_length; + a.master_key.type = V_ASN1_OCTET_STRING; + a.master_key.data = in->master_key; + + a.session_id.length = in->session_id_length; + a.session_id.type = V_ASN1_OCTET_STRING; + a.session_id.data = in->session_id; + + a.session_id_context.length = in->sid_ctx_length; + a.session_id_context.type = V_ASN1_OCTET_STRING; + a.session_id_context.data = in->sid_ctx; + + a.key_arg.length = in->key_arg_length; + a.key_arg.type = V_ASN1_OCTET_STRING; + a.key_arg.data = in->key_arg; + +#ifndef OPENSSL_NO_KRB5 + if (in->krb5_client_princ_len) { + a.krb5_princ.length = in->krb5_client_princ_len; + a.krb5_princ.type = V_ASN1_OCTET_STRING; + a.krb5_princ.data = in->krb5_client_princ; + } +#endif /* OPENSSL_NO_KRB5 */ + + if (in->time != 0L) { + a.time.length = LSIZE2; + a.time.type = V_ASN1_INTEGER; + a.time.data = ibuf3; + ASN1_INTEGER_set(&(a.time), in->time); + } + + if (in->timeout != 0L) { + a.timeout.length = LSIZE2; + a.timeout.type = V_ASN1_INTEGER; + a.timeout.data = ibuf4; + ASN1_INTEGER_set(&(a.timeout), in->timeout); + } + + if (in->verify_result != X509_V_OK) { + a.verify_result.length = LSIZE2; + a.verify_result.type = V_ASN1_INTEGER; + a.verify_result.data = ibuf5; + ASN1_INTEGER_set(&a.verify_result, in->verify_result); + } +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_hostname) { + a.tlsext_hostname.length = strlen(in->tlsext_hostname); + a.tlsext_hostname.type = V_ASN1_OCTET_STRING; + a.tlsext_hostname.data = (unsigned char *)in->tlsext_hostname; + } + if (in->tlsext_tick) { + a.tlsext_tick.length = in->tlsext_ticklen; + a.tlsext_tick.type = V_ASN1_OCTET_STRING; + a.tlsext_tick.data = (unsigned char *)in->tlsext_tick; + } + if (in->tlsext_tick_lifetime_hint > 0) { + a.tlsext_tick_lifetime.length = LSIZE2; + a.tlsext_tick_lifetime.type = V_ASN1_INTEGER; + a.tlsext_tick_lifetime.data = ibuf6; + ASN1_INTEGER_set(&a.tlsext_tick_lifetime, + in->tlsext_tick_lifetime_hint); + } +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) { + a.psk_identity_hint.length = strlen(in->psk_identity_hint); + a.psk_identity_hint.type = V_ASN1_OCTET_STRING; + a.psk_identity_hint.data = (unsigned char *)(in->psk_identity_hint); + } + if (in->psk_identity) { + a.psk_identity.length = strlen(in->psk_identity); + a.psk_identity.type = V_ASN1_OCTET_STRING; + a.psk_identity.data = (unsigned char *)(in->psk_identity); + } +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (in->srp_username) { + a.srp_username.length = strlen(in->srp_username); + a.srp_username.type = V_ASN1_OCTET_STRING; + a.srp_username.data = (unsigned char *)(in->srp_username); + } +#endif /* OPENSSL_NO_SRP */ + + M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); + M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); + M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING); +#ifndef OPENSSL_NO_KRB5 + if (in->krb5_client_princ_len) + M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); +#endif /* OPENSSL_NO_KRB5 */ + if (in->key_arg_length > 0) + M_ASN1_I2D_len_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING); + if (in->time != 0L) + M_ASN1_I2D_len_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1); + if (in->timeout != 0L) + M_ASN1_I2D_len_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2); + if (in->peer != NULL) + M_ASN1_I2D_len_EXP_opt(in->peer, i2d_X509, 3, v3); + M_ASN1_I2D_len_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4, + v4); + if (in->verify_result != X509_V_OK) + M_ASN1_I2D_len_EXP_opt(&(a.verify_result), i2d_ASN1_INTEGER, 5, v5); + +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_tick_lifetime_hint > 0) + M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9, + v9); + if (in->tlsext_tick) + M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10, + v10); + if (in->tlsext_hostname) + M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6, + v6); +# ifndef OPENSSL_NO_COMP + if (in->compress_meth) + M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11); +# endif +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) + M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING, + 7, v7); + if (in->psk_identity) + M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8, + v8); +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (in->srp_username) + M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12, + v12); +#endif /* OPENSSL_NO_SRP */ + + M_ASN1_I2D_seq_total(); + + M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER); + M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER); + M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING); +#ifndef OPENSSL_NO_KRB5 + if (in->krb5_client_princ_len) + M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); +#endif /* OPENSSL_NO_KRB5 */ + if (in->key_arg_length > 0) + M_ASN1_I2D_put_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING, 0); + if (in->time != 0L) + M_ASN1_I2D_put_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1); + if (in->timeout != 0L) + M_ASN1_I2D_put_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2); + if (in->peer != NULL) + M_ASN1_I2D_put_EXP_opt(in->peer, i2d_X509, 3, v3); + M_ASN1_I2D_put_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4, + v4); + if (in->verify_result != X509_V_OK) + M_ASN1_I2D_put_EXP_opt(&a.verify_result, i2d_ASN1_INTEGER, 5, v5); +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_hostname) + M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6, + v6); +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) + M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING, + 7, v7); + if (in->psk_identity) + M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8, + v8); +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_tick_lifetime_hint > 0) + M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9, + v9); + if (in->tlsext_tick) + M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10, + v10); +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_COMP + if (in->compress_meth) + M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11); +#endif +#ifndef OPENSSL_NO_SRP + if (in->srp_username) + M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12, + v12); +#endif /* OPENSSL_NO_SRP */ + M_ASN1_I2D_finish(); +} + +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length) +{ + int ssl_version = 0, i; + long id; + ASN1_INTEGER ai, *aip; + ASN1_OCTET_STRING os, *osp; + M_ASN1_D2I_vars(a, SSL_SESSION *, SSL_SESSION_new); + + aip = &ai; + osp = &os; + + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + + ai.data = NULL; + ai.length = 0; + M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); + if (ai.data != NULL) { + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } + + /* we don't care about the version right now :-) */ + M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); + ssl_version = (int)ASN1_INTEGER_get(aip); + ret->ssl_version = ssl_version; + if (ai.data != NULL) { + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } + + os.data = NULL; + os.length = 0; + M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); + if (ssl_version == SSL2_VERSION) { + if (os.length != 3) { + c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; + c.line = __LINE__; + goto err; + } + id = 0x02000000L | + ((unsigned long)os.data[0] << 16L) | + ((unsigned long)os.data[1] << 8L) | (unsigned long)os.data[2]; + } else if ((ssl_version >> 8) == SSL3_VERSION_MAJOR + || (ssl_version >> 8) == DTLS1_VERSION_MAJOR + || ssl_version == DTLS1_BAD_VER) { + if (os.length != 2) { + c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; + c.line = __LINE__; + goto err; + } + id = 0x03000000L | + ((unsigned long)os.data[0] << 8L) | (unsigned long)os.data[1]; + } else { + c.error = SSL_R_UNKNOWN_SSL_VERSION; + c.line = __LINE__; + goto err; + } + + ret->cipher = NULL; + ret->cipher_id = id; + + M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); + if ((ssl_version >> 8) >= SSL3_VERSION_MAJOR) + i = SSL3_MAX_SSL_SESSION_ID_LENGTH; + else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */ + i = SSL2_MAX_SSL_SESSION_ID_LENGTH; + + if (os.length > i) + os.length = i; + if (os.length > (int)sizeof(ret->session_id)) /* can't happen */ + os.length = sizeof(ret->session_id); + + ret->session_id_length = os.length; + OPENSSL_assert(os.length <= (int)sizeof(ret->session_id)); + memcpy(ret->session_id, os.data, os.length); + + M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); + if (os.length > SSL_MAX_MASTER_KEY_LENGTH) + ret->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; + else + ret->master_key_length = os.length; + memcpy(ret->master_key, os.data, ret->master_key_length); + + os.length = 0; + +#ifndef OPENSSL_NO_KRB5 + os.length = 0; + M_ASN1_D2I_get_opt(osp, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING); + if (os.data) { + if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH) + ret->krb5_client_princ_len = 0; + else + ret->krb5_client_princ_len = os.length; + memcpy(ret->krb5_client_princ, os.data, ret->krb5_client_princ_len); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->krb5_client_princ_len = 0; +#endif /* OPENSSL_NO_KRB5 */ + + M_ASN1_D2I_get_IMP_opt(osp, d2i_ASN1_OCTET_STRING, 0, + V_ASN1_OCTET_STRING); + if (os.length > SSL_MAX_KEY_ARG_LENGTH) + ret->key_arg_length = SSL_MAX_KEY_ARG_LENGTH; + else + ret->key_arg_length = os.length; + memcpy(ret->key_arg, os.data, ret->key_arg_length); + if (os.data != NULL) + OPENSSL_free(os.data); + + ai.length = 0; + M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 1); + if (ai.data != NULL) { + ret->time = ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->time = (unsigned long)time(NULL); + + ai.length = 0; + M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 2); + if (ai.data != NULL) { + ret->timeout = ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->timeout = 3; + + if (ret->peer != NULL) { + X509_free(ret->peer); + ret->peer = NULL; + } + M_ASN1_D2I_get_EXP_opt(ret->peer, d2i_X509, 3); + + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 4); + + if (os.data != NULL) { + if (os.length > SSL_MAX_SID_CTX_LENGTH) { + c.error = SSL_R_BAD_LENGTH; + c.line = __LINE__; + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + goto err; + } else { + ret->sid_ctx_length = os.length; + memcpy(ret->sid_ctx, os.data, os.length); + } + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->sid_ctx_length = 0; + + ai.length = 0; + M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 5); + if (ai.data != NULL) { + ret->verify_result = ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->verify_result = X509_V_OK; + +#ifndef OPENSSL_NO_TLSEXT + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 6); + if (os.data) { + ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->tlsext_hostname = NULL; +#endif /* OPENSSL_NO_TLSEXT */ + +#ifndef OPENSSL_NO_PSK + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 7); + if (os.data) { + ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->psk_identity_hint = NULL; + + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 8); + if (os.data) { + ret->psk_identity = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->psk_identity = NULL; +#endif /* OPENSSL_NO_PSK */ + +#ifndef OPENSSL_NO_TLSEXT + ai.length = 0; + M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 9); + if (ai.data != NULL) { + ret->tlsext_tick_lifetime_hint = ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } else if (ret->tlsext_ticklen && ret->session_id_length) + ret->tlsext_tick_lifetime_hint = -1; + else + ret->tlsext_tick_lifetime_hint = 0; + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 10); + if (os.data) { + ret->tlsext_tick = os.data; + ret->tlsext_ticklen = os.length; + os.data = NULL; + os.length = 0; + } else + ret->tlsext_tick = NULL; +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_COMP + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 11); + if (os.data) { + ret->compress_meth = os.data[0]; + OPENSSL_free(os.data); + os.data = NULL; + } +#endif + +#ifndef OPENSSL_NO_SRP + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 12); + if (os.data) { + ret->srp_username = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->srp_username = NULL; +#endif /* OPENSSL_NO_SRP */ + + M_ASN1_D2I_Finish(a, SSL_SESSION_free, SSL_F_D2I_SSL_SESSION); +} +/* + * ! \file ssl/ssl_cert.c + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +#include "e_os.h" +#ifndef NO_SYS_TYPES_H +# include +#endif + +#include "o_dir.h" +// #include "objects.h" +#include "bio.h" +#include "pem.h" +#include "x509v3.h" +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#include "bn.h" +// #include "ssl_locl.h" + +int SSL_get_ex_data_X509_STORE_CTX_idx(void) +{ + static volatile int ssl_x509_store_ctx_idx = -1; + int got_write_lock = 0; + + if (((size_t)&ssl_x509_store_ctx_idx & + (sizeof(ssl_x509_store_ctx_idx) - 1)) + == 0) { /* check alignment, practically always true */ + int ret; + + if ((ret = ssl_x509_store_ctx_idx) < 0) { + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + if ((ret = ssl_x509_store_ctx_idx) < 0) { + ret = ssl_x509_store_ctx_idx = + X509_STORE_CTX_get_ex_new_index(0, + "SSL for verify callback", + NULL, NULL, NULL); + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + } + + return ret; + } else { /* commonly eliminated */ + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + + if (ssl_x509_store_ctx_idx < 0) { + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + got_write_lock = 1; + + if (ssl_x509_store_ctx_idx < 0) { + ssl_x509_store_ctx_idx = + X509_STORE_CTX_get_ex_new_index(0, + "SSL for verify callback", + NULL, NULL, NULL); + } + } + + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + else + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + + return ssl_x509_store_ctx_idx; + } +} + +void ssl_cert_set_default_md(CERT *cert) +{ + /* Set digest values to defaults */ +#ifndef OPENSSL_NO_DSA + cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); +#endif +#ifndef OPENSSL_NO_RSA + cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); + cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); +#endif +#ifndef OPENSSL_NO_ECDSA + cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +#endif +} + +CERT *ssl_cert_new(void) +{ + CERT *ret; + + ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); + if (ret == NULL) { + SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + memset(ret, 0, sizeof(CERT)); + + ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); + ret->references = 1; + ssl_cert_set_default_md(ret); + return (ret); +} + +CERT *ssl_cert_dup(CERT *cert) +{ + CERT *ret; + int i; + + ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); + if (ret == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + memset(ret, 0, sizeof(CERT)); + + ret->references = 1; + ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; + /* + * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that + * more readable + */ + + ret->valid = cert->valid; + ret->mask_k = cert->mask_k; + ret->mask_a = cert->mask_a; + ret->export_mask_k = cert->export_mask_k; + ret->export_mask_a = cert->export_mask_a; + +#ifndef OPENSSL_NO_RSA + if (cert->rsa_tmp != NULL) { + RSA_up_ref(cert->rsa_tmp); + ret->rsa_tmp = cert->rsa_tmp; + } + ret->rsa_tmp_cb = cert->rsa_tmp_cb; +#endif + +#ifndef OPENSSL_NO_DH + if (cert->dh_tmp != NULL) { + ret->dh_tmp = DHparams_dup(cert->dh_tmp); + if (ret->dh_tmp == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); + goto err; + } + if (cert->dh_tmp->priv_key) { + BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); + if (!b) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); + goto err; + } + ret->dh_tmp->priv_key = b; + } + if (cert->dh_tmp->pub_key) { + BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); + if (!b) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); + goto err; + } + ret->dh_tmp->pub_key = b; + } + } + ret->dh_tmp_cb = cert->dh_tmp_cb; +#endif + +#ifndef OPENSSL_NO_ECDH + if (cert->ecdh_tmp) { + ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); + if (ret->ecdh_tmp == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); + goto err; + } + } + ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; + ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; +#endif + + for (i = 0; i < SSL_PKEY_NUM; i++) { + CERT_PKEY *cpk = cert->pkeys + i; + CERT_PKEY *rpk = ret->pkeys + i; + if (cpk->x509 != NULL) { + rpk->x509 = cpk->x509; + CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509); + } + + if (cpk->privatekey != NULL) { + rpk->privatekey = cpk->privatekey; + CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); + } + + if (cpk->chain) { + rpk->chain = X509_chain_up_ref(cpk->chain); + if (!rpk->chain) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + goto err; + } + } + rpk->valid_flags = 0; +#ifndef OPENSSL_NO_TLSEXT + if (cert->pkeys[i].serverinfo != NULL) { + /* Just copy everything. */ + ret->pkeys[i].serverinfo = + OPENSSL_malloc(cert->pkeys[i].serverinfo_length); + if (ret->pkeys[i].serverinfo == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + goto err; + } + ret->pkeys[i].serverinfo_length = + cert->pkeys[i].serverinfo_length; + memcpy(ret->pkeys[i].serverinfo, + cert->pkeys[i].serverinfo, + cert->pkeys[i].serverinfo_length); + } +#endif + } + + /* + * Set digests to defaults. NB: we don't copy existing values as they + * will be set during handshake. + */ + ssl_cert_set_default_md(ret); + /* Peer sigalgs set to NULL as we get these from handshake too */ + ret->peer_sigalgs = NULL; + ret->peer_sigalgslen = 0; + /* Configured sigalgs however we copy across */ + + if (cert->conf_sigalgs) { + ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); + if (!ret->conf_sigalgs) + goto err; + memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); + ret->conf_sigalgslen = cert->conf_sigalgslen; + } else + ret->conf_sigalgs = NULL; + + if (cert->client_sigalgs) { + ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); + if (!ret->client_sigalgs) + goto err; + memcpy(ret->client_sigalgs, cert->client_sigalgs, + cert->client_sigalgslen); + ret->client_sigalgslen = cert->client_sigalgslen; + } else + ret->client_sigalgs = NULL; + /* Shared sigalgs also NULL */ + ret->shared_sigalgs = NULL; + /* Copy any custom client certificate types */ + if (cert->ctypes) { + ret->ctypes = OPENSSL_malloc(cert->ctype_num); + if (!ret->ctypes) + goto err; + memcpy(ret->ctypes, cert->ctypes, cert->ctype_num); + ret->ctype_num = cert->ctype_num; + } + + ret->cert_flags = cert->cert_flags; + + ret->cert_cb = cert->cert_cb; + ret->cert_cb_arg = cert->cert_cb_arg; + + if (cert->verify_store) { + CRYPTO_add(&cert->verify_store->references, 1, + CRYPTO_LOCK_X509_STORE); + ret->verify_store = cert->verify_store; + } + + if (cert->chain_store) { + CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); + ret->chain_store = cert->chain_store; + } + + ret->ciphers_raw = NULL; + +#ifndef OPENSSL_NO_TLSEXT + if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext)) + goto err; + if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext)) + goto err; +#endif + + return (ret); + + err: +#ifndef OPENSSL_NO_RSA + if (ret->rsa_tmp != NULL) + RSA_free(ret->rsa_tmp); +#endif +#ifndef OPENSSL_NO_DH + if (ret->dh_tmp != NULL) + DH_free(ret->dh_tmp); +#endif +#ifndef OPENSSL_NO_ECDH + if (ret->ecdh_tmp != NULL) + EC_KEY_free(ret->ecdh_tmp); +#endif + +#ifndef OPENSSL_NO_TLSEXT + custom_exts_free(&ret->cli_ext); + custom_exts_free(&ret->srv_ext); +#endif + + ssl_cert_clear_certs(ret); + OPENSSL_free(ret); + + return NULL; +} + +/* Free up and clear all certificates and chains */ + +void ssl_cert_clear_certs(CERT *c) +{ + int i; + if (c == NULL) + return; + for (i = 0; i < SSL_PKEY_NUM; i++) { + CERT_PKEY *cpk = c->pkeys + i; + if (cpk->x509) { + X509_free(cpk->x509); + cpk->x509 = NULL; + } + if (cpk->privatekey) { + EVP_PKEY_free(cpk->privatekey); + cpk->privatekey = NULL; + } + if (cpk->chain) { + sk_X509_pop_free(cpk->chain, X509_free); + cpk->chain = NULL; + } +#ifndef OPENSSL_NO_TLSEXT + if (cpk->serverinfo) { + OPENSSL_free(cpk->serverinfo); + cpk->serverinfo = NULL; + cpk->serverinfo_length = 0; + } +#endif + /* Clear all flags apart from explicit sign */ + cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; + } +} + +void ssl_cert_free(CERT *c) +{ + int i; + + if (c == NULL) + return; + + i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); +#ifdef REF_PRINT + REF_PRINT("CERT", c); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "ssl_cert_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + +#ifndef OPENSSL_NO_RSA + if (c->rsa_tmp) + RSA_free(c->rsa_tmp); +#endif +#ifndef OPENSSL_NO_DH + if (c->dh_tmp) + DH_free(c->dh_tmp); +#endif +#ifndef OPENSSL_NO_ECDH + if (c->ecdh_tmp) + EC_KEY_free(c->ecdh_tmp); +#endif + + ssl_cert_clear_certs(c); + if (c->peer_sigalgs) + OPENSSL_free(c->peer_sigalgs); + if (c->conf_sigalgs) + OPENSSL_free(c->conf_sigalgs); + if (c->client_sigalgs) + OPENSSL_free(c->client_sigalgs); + if (c->shared_sigalgs) + OPENSSL_free(c->shared_sigalgs); + if (c->ctypes) + OPENSSL_free(c->ctypes); + if (c->verify_store) + X509_STORE_free(c->verify_store); + if (c->chain_store) + X509_STORE_free(c->chain_store); + if (c->ciphers_raw) + OPENSSL_free(c->ciphers_raw); +#ifndef OPENSSL_NO_TLSEXT + custom_exts_free(&c->cli_ext); + custom_exts_free(&c->srv_ext); + if (c->alpn_proposed) + OPENSSL_free(c->alpn_proposed); +#endif + OPENSSL_free(c); +} + +int ssl_cert_inst(CERT **o) +{ + /* + * Create a CERT if there isn't already one (which cannot really happen, + * as it is initially created in SSL_CTX_new; but the earlier code + * usually allows for that one being non-existant, so we follow that + * behaviour, as it might turn out that there actually is a reason for it + * -- but I'm not sure that *all* of the existing code could cope with + * s->cert being NULL, otherwise we could do without the initialization + * in SSL_CTX_new). + */ + + if (o == NULL) { + SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (*o == NULL) { + if ((*o = ssl_cert_new()) == NULL) { + SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); + return (0); + } + } + return (1); +} + +int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain) +{ + CERT_PKEY *cpk = c->key; + if (!cpk) + return 0; + if (cpk->chain) + sk_X509_pop_free(cpk->chain, X509_free); + cpk->chain = chain; + return 1; +} + +int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) +{ + STACK_OF(X509) *dchain; + if (!chain) + return ssl_cert_set0_chain(c, NULL); + dchain = X509_chain_up_ref(chain); + if (!dchain) + return 0; + if (!ssl_cert_set0_chain(c, dchain)) { + sk_X509_pop_free(dchain, X509_free); + return 0; + } + return 1; +} + +int ssl_cert_add0_chain_cert(CERT *c, X509 *x) +{ + CERT_PKEY *cpk = c->key; + if (!cpk) + return 0; + if (!cpk->chain) + cpk->chain = sk_X509_new_null(); + if (!cpk->chain || !sk_X509_push(cpk->chain, x)) + return 0; + return 1; +} + +int ssl_cert_add1_chain_cert(CERT *c, X509 *x) +{ + if (!ssl_cert_add0_chain_cert(c, x)) + return 0; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + return 1; +} + +int ssl_cert_select_current(CERT *c, X509 *x) +{ + int i; + if (x == NULL) + return 0; + for (i = 0; i < SSL_PKEY_NUM; i++) { + CERT_PKEY *cpk = c->pkeys + i; + if (cpk->x509 == x && cpk->privatekey) { + c->key = cpk; + return 1; + } + } + + for (i = 0; i < SSL_PKEY_NUM; i++) { + CERT_PKEY *cpk = c->pkeys + i; + if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { + c->key = cpk; + return 1; + } + } + return 0; +} + +int ssl_cert_set_current(CERT *c, long op) +{ + int i, idx; + if (!c) + return 0; + if (op == SSL_CERT_SET_FIRST) + idx = 0; + else if (op == SSL_CERT_SET_NEXT) { + idx = (int)(c->key - c->pkeys + 1); + if (idx >= SSL_PKEY_NUM) + return 0; + } else + return 0; + for (i = idx; i < SSL_PKEY_NUM; i++) { + CERT_PKEY *cpk = c->pkeys + i; + if (cpk->x509 && cpk->privatekey) { + c->key = cpk; + return 1; + } + } + return 0; +} + +void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) +{ + c->cert_cb = cb; + c->cert_cb_arg = arg; +} + +SESS_CERT *ssl_sess_cert_new(void) +{ + SESS_CERT *ret; + + ret = OPENSSL_malloc(sizeof(*ret)); + if (ret == NULL) { + SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + memset(ret, 0, sizeof(*ret)); + ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); + ret->references = 1; + + return ret; +} + +void ssl_sess_cert_free(SESS_CERT *sc) +{ + int i; + + if (sc == NULL) + return; + + i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); +#ifdef REF_PRINT + REF_PRINT("SESS_CERT", sc); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "ssl_sess_cert_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + /* i == 0 */ + if (sc->cert_chain != NULL) + sk_X509_pop_free(sc->cert_chain, X509_free); + for (i = 0; i < SSL_PKEY_NUM; i++) { + if (sc->peer_pkeys[i].x509 != NULL) + X509_free(sc->peer_pkeys[i].x509); +#if 0 /* We don't have the peer's private key. + * These lines are just * here as a reminder + * that we're still using a + * not-quite-appropriate * data structure. */ + if (sc->peer_pkeys[i].privatekey != NULL) + EVP_PKEY_free(sc->peer_pkeys[i].privatekey); +#endif + } + +#ifndef OPENSSL_NO_RSA + if (sc->peer_rsa_tmp != NULL) + RSA_free(sc->peer_rsa_tmp); +#endif +#ifndef OPENSSL_NO_DH + if (sc->peer_dh_tmp != NULL) + DH_free(sc->peer_dh_tmp); +#endif +#ifndef OPENSSL_NO_ECDH + if (sc->peer_ecdh_tmp != NULL) + EC_KEY_free(sc->peer_ecdh_tmp); +#endif + + OPENSSL_free(sc); +} + +int ssl_set_peer_cert_type(SESS_CERT *sc, int type) +{ + sc->peer_cert_type = type; + return (1); +} + +int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) +{ + X509 *x; + int i; + X509_STORE *verify_store; + X509_STORE_CTX ctx; + + if (s->cert->verify_store) + verify_store = s->cert->verify_store; + else + verify_store = s->ctx->cert_store; + + if ((sk == NULL) || (sk_X509_num(sk) == 0)) + return (0); + + x = sk_X509_value(sk, 0); + if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) { + SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); + return (0); + } + /* Set suite B flags if needed */ + X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s)); +#if 0 + if (SSL_get_verify_depth(s) >= 0) + X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); +#endif + X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); + + /* + * We need to inherit the verify parameters. These can be determined by + * the context: if its a server it will verify SSL client certificates or + * vice versa. + */ + + X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); + /* + * Anything non-default in "param" should overwrite anything in the ctx. + */ + X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); + + if (s->verify_callback) + X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); + + if (s->ctx->app_verify_callback != NULL) +#if 1 /* new with OpenSSL 0.9.7 */ + i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); +#else + i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ +#endif + else { +#ifndef OPENSSL_NO_X509_VERIFY + i = X509_verify_cert(&ctx); +#else + i = 0; + ctx.error = X509_V_ERR_APPLICATION_VERIFICATION; + SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK); +#endif + } + + s->verify_result = ctx.error; + X509_STORE_CTX_cleanup(&ctx); + + return (i); +} + +static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, + STACK_OF(X509_NAME) *name_list) +{ + if (*ca_list != NULL) + sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); + + *ca_list = name_list; +} + +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) +{ + int i; + STACK_OF(X509_NAME) *ret; + X509_NAME *name; + + ret = sk_X509_NAME_new_null(); + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); + if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { + sk_X509_NAME_pop_free(ret, X509_NAME_free); + return (NULL); + } + } + return (ret); +} + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) +{ + set_client_CA_list(&(s->client_CA), name_list); +} + +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) +{ + set_client_CA_list(&(ctx->client_CA), name_list); +} + +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) +{ + return (ctx->client_CA); +} + +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) +{ + if (s->type == SSL_ST_CONNECT) { /* we are in the client */ + if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL)) + return (s->s3->tmp.ca_names); + else + return (NULL); + } else { + if (s->client_CA != NULL) + return (s->client_CA); + else + return (s->ctx->client_CA); + } +} + +static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) +{ + X509_NAME *name; + + if (x == NULL) + return (0); + if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) + return (0); + + if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) + return (0); + + if (!sk_X509_NAME_push(*sk, name)) { + X509_NAME_free(name); + return (0); + } + return (1); +} + +int SSL_add_client_CA(SSL *ssl, X509 *x) +{ + return (add_client_CA(&(ssl->client_CA), x)); +} + +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ + return (add_client_CA(&(ctx->client_CA), x)); +} + +static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) +{ + return (X509_NAME_cmp(*a, *b)); +} + +#ifndef OPENSSL_NO_STDIO +/** + * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; + * it doesn't really have anything to do with clients (except that a common use + * for a stack of CAs is to send it to the client). Actually, it doesn't have + * much to do with CAs, either, since it will load any old cert. + * \param file the file containing one or more certs. + * \return a ::STACK containing the certs. + */ +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) +{ + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + STACK_OF(X509_NAME) *ret = NULL, *sk; + + sk = sk_X509_NAME_new(xname_cmp); + + in = BIO_new(BIO_s_file_internal()); + + if ((sk == NULL) || (in == NULL)) { + SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) + goto err; + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) + break; + if (ret == NULL) { + ret = sk_X509_NAME_new_null(); + if (ret == NULL) { + SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if ((xn = X509_get_subject_name(x)) == NULL) + goto err; + /* check for duplicates */ + xn = X509_NAME_dup(xn); + if (xn == NULL) + goto err; + if (sk_X509_NAME_find(sk, xn) >= 0) + X509_NAME_free(xn); + else { + sk_X509_NAME_push(sk, xn); + sk_X509_NAME_push(ret, xn); + } + } + + if (0) { + err: + if (ret != NULL) + sk_X509_NAME_pop_free(ret, X509_NAME_free); + ret = NULL; + } + if (sk != NULL) + sk_X509_NAME_free(sk); + if (in != NULL) + BIO_free(in); + if (x != NULL) + X509_free(x); + if (ret != NULL) + ERR_clear_error(); + return (ret); +} +#endif + +/** + * Add a file of certs to a stack. + * \param stack the stack to add to. + * \param file the file to add from. All certs in this file that are not + * already in the stack will be added. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *file) +{ + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + int ret = 1; + int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); + + oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); + + in = BIO_new(BIO_s_file_internal()); + + if (in == NULL) { + SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) + goto err; + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) + break; + if ((xn = X509_get_subject_name(x)) == NULL) + goto err; + xn = X509_NAME_dup(xn); + if (xn == NULL) + goto err; + if (sk_X509_NAME_find(stack, xn) >= 0) + X509_NAME_free(xn); + else + sk_X509_NAME_push(stack, xn); + } + + ERR_clear_error(); + + if (0) { + err: + ret = 0; + } + if (in != NULL) + BIO_free(in); + if (x != NULL) + X509_free(x); + + (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); + + return ret; +} + +/** + * Add a directory of certs to a stack. + * \param stack the stack to append to. + * \param dir the directory to append from. All files in this directory will be + * examined as potential certs. Any that are acceptable to + * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be + * included. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *dir) +{ + OPENSSL_DIR_CTX *d = NULL; + const char *filename; + int ret = 0; + + CRYPTO_w_lock(CRYPTO_LOCK_READDIR); + + /* Note that a side effect is that the CAs will be sorted by name */ + + while ((filename = OPENSSL_DIR_read(&d, dir))) { + char buf[1024]; + int r; + + if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { + SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, + SSL_R_PATH_TOO_LONG); + goto err; + } +#ifdef OPENSSL_SYS_VMS + r = BIO_snprintf(buf, sizeof(buf), "%s%s", dir, filename); +#else + r = BIO_snprintf(buf, sizeof(buf), "%s/%s", dir, filename); +#endif + if (r <= 0 || r >= (int)sizeof(buf)) + goto err; + if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) + goto err; + } + + if (errno) { + SYSerr(SYS_F_OPENDIR, get_last_sys_error()); + ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); + SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); + goto err; + } + + ret = 1; + + err: + if (d) + OPENSSL_DIR_end(&d); + CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); + return ret; +} + +/* Add a certificate to a BUF_MEM structure */ + +static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) +{ + int n; + unsigned char *p; + + n = i2d_X509(x, NULL); + if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) { + SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); + return 0; + } + p = (unsigned char *)&(buf->data[*l]); + l2n3(n, p); + n = i2d_X509(x, &p); + if (n < 0) { + /* Shouldn't happen */ + SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); + return 0; + } + *l += n + 3; + + return 1; +} + +/* Add certificate chain to internal SSL BUF_MEM strcuture */ +int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) +{ + BUF_MEM *buf = s->init_buf; + int no_chain; + int i; + + X509 *x; + STACK_OF(X509) *extra_certs; + X509_STORE *chain_store; + + if (cpk) + x = cpk->x509; + else + x = NULL; + + if (s->cert->chain_store) + chain_store = s->cert->chain_store; + else + chain_store = s->ctx->cert_store; + + /* + * If we have a certificate specific chain use it, else use parent ctx. + */ + if (cpk && cpk->chain) + extra_certs = cpk->chain; + else + extra_certs = s->ctx->extra_certs; + + if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) + no_chain = 1; + else + no_chain = 0; + + /* TLSv1 sends a chain with nothing in it, instead of an alert */ + if (!BUF_MEM_grow_clean(buf, 10)) { + SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_BUF_LIB); + return 0; + } + if (x != NULL) { + if (no_chain) { + if (!ssl_add_cert_to_buf(buf, l, x)) + return 0; + } else { + X509_STORE_CTX xs_ctx; + + if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) { + SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_X509_LIB); + return (0); + } + X509_verify_cert(&xs_ctx); + /* Don't leave errors in the queue */ + ERR_clear_error(); + for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { + x = sk_X509_value(xs_ctx.chain, i); + + if (!ssl_add_cert_to_buf(buf, l, x)) { + X509_STORE_CTX_cleanup(&xs_ctx); + return 0; + } + } + X509_STORE_CTX_cleanup(&xs_ctx); + } + } + for (i = 0; i < sk_X509_num(extra_certs); i++) { + x = sk_X509_value(extra_certs, i); + if (!ssl_add_cert_to_buf(buf, l, x)) + return 0; + } + + return 1; +} + +/* Build a certificate chain for current certificate */ +int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) +{ + CERT_PKEY *cpk = c->key; + X509_STORE_CTX xs_ctx; + STACK_OF(X509) *chain = NULL, *untrusted = NULL; + X509 *x; + int i, rv = 0; + unsigned long error; + + if (!cpk->x509) { + SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET); + goto err; + } + /* Rearranging and check the chain: add everything to a store */ + if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) { + chain_store = X509_STORE_new(); + if (!chain_store) + goto err; + for (i = 0; i < sk_X509_num(cpk->chain); i++) { + x = sk_X509_value(cpk->chain, i); + if (!X509_STORE_add_cert(chain_store, x)) { + error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) != ERR_LIB_X509 || + ERR_GET_REASON(error) != + X509_R_CERT_ALREADY_IN_HASH_TABLE) + goto err; + ERR_clear_error(); + } + } + /* Add EE cert too: it might be self signed */ + if (!X509_STORE_add_cert(chain_store, cpk->x509)) { + error = ERR_peek_last_error(); + if (ERR_GET_LIB(error) != ERR_LIB_X509 || + ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) + goto err; + ERR_clear_error(); + } + } else { + if (c->chain_store) + chain_store = c->chain_store; + + if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) + untrusted = cpk->chain; + } + + if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) { + SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB); + goto err; + } + /* Set suite B flags if needed */ + X509_STORE_CTX_set_flags(&xs_ctx, + c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); + + i = X509_verify_cert(&xs_ctx); + if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { + if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) + ERR_clear_error(); + i = 1; + rv = 2; + } + if (i > 0) + chain = X509_STORE_CTX_get1_chain(&xs_ctx); + if (i <= 0) { + SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED); + i = X509_STORE_CTX_get_error(&xs_ctx); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(i)); + + X509_STORE_CTX_cleanup(&xs_ctx); + goto err; + } + X509_STORE_CTX_cleanup(&xs_ctx); + if (cpk->chain) + sk_X509_pop_free(cpk->chain, X509_free); + /* Remove EE certificate from chain */ + x = sk_X509_shift(chain); + X509_free(x); + if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) { + if (sk_X509_num(chain) > 0) { + /* See if last cert is self signed */ + x = sk_X509_value(chain, sk_X509_num(chain) - 1); + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) { + x = sk_X509_pop(chain); + X509_free(x); + } + } + } + cpk->chain = chain; + if (rv == 0) + rv = 1; + err: + if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) + X509_STORE_free(chain_store); + + return rv; +} + +int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) +{ + X509_STORE **pstore; + if (chain) + pstore = &c->chain_store; + else + pstore = &c->verify_store; + if (*pstore) + X509_STORE_free(*pstore); + *pstore = store; + if (ref && store) + CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); + return 1; +} +/* ssl/ssl_ciph.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +// #include "objects.h" +#ifndef OPENSSL_NO_COMP +# include "comp.h" +#endif +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +// #include "ssl_locl.h" + +#define SSL_ENC_DES_IDX 0 +#define SSL_ENC_3DES_IDX 1 +#define SSL_ENC_RC4_IDX 2 +#define SSL_ENC_RC2_IDX 3 +#define SSL_ENC_IDEA_IDX 4 +#define SSL_ENC_NULL_IDX 5 +#define SSL_ENC_AES128_IDX 6 +#define SSL_ENC_AES256_IDX 7 +#define SSL_ENC_CAMELLIA128_IDX 8 +#define SSL_ENC_CAMELLIA256_IDX 9 +#define SSL_ENC_GOST89_IDX 10 +#define SSL_ENC_SEED_IDX 11 +#define SSL_ENC_AES128GCM_IDX 12 +#define SSL_ENC_AES256GCM_IDX 13 +#define SSL_ENC_NUM_IDX 14 + +static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL +}; + +#define SSL_COMP_NULL_IDX 0 +#define SSL_COMP_ZLIB_IDX 1 +#define SSL_COMP_NUM_IDX 2 + +static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; + +#define SSL_MD_MD5_IDX 0 +#define SSL_MD_SHA1_IDX 1 +#define SSL_MD_GOST94_IDX 2 +#define SSL_MD_GOST89MAC_IDX 3 +#define SSL_MD_SHA256_IDX 4 +#define SSL_MD_SHA384_IDX 5 +/* + * Constant SSL_MAX_DIGEST equal to size of digests array should be defined + * in the ssl_locl.h + */ +#define SSL_MD_NUM_IDX SSL_MAX_DIGEST +static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { + NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* + * PKEY_TYPE for GOST89MAC is known in advance, but, because implementation + * is engine-provided, we'll fill it only if corresponding EVP_PKEY_METHOD is + * found + */ +static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { + EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, + EVP_PKEY_HMAC, EVP_PKEY_HMAC +}; + +static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { + 0, 0, 0, 0, 0, 0 +}; + +static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = { + SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA, + SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA384 +}; + +#define CIPHER_ADD 1 +#define CIPHER_KILL 2 +#define CIPHER_DEL 3 +#define CIPHER_ORD 4 +#define CIPHER_SPECIAL 5 + +typedef struct cipher_order_st { + const SSL_CIPHER *cipher; + int active; + int dead; + struct cipher_order_st *next, *prev; +} CIPHER_ORDER; + +static const SSL_CIPHER cipher_aliases[] = { + /* "ALL" doesn't include eNULL (must be specifically enabled) */ + {0, SSL_TXT_ALL, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, 0}, + /* "COMPLEMENTOFALL" */ + {0, SSL_TXT_CMPALL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, + + /* + * "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in + * ALL!) + */ + {0, SSL_TXT_CMPDEF, 0, 0, 0, 0, 0, 0, SSL_NOT_DEFAULT, 0, 0, 0}, + + /* + * key exchange aliases (some of those using only a single bit here + * combine multiple key exchange algs according to the RFCs, e.g. kEDH + * combines DHE_DSS and DHE_RSA) + */ + {0, SSL_TXT_kRSA, 0, SSL_kRSA, 0, 0, 0, 0, 0, 0, 0, 0}, + + {0, SSL_TXT_kDHr, 0, SSL_kDHr, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kDHd, 0, SSL_kDHd, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kDH, 0, SSL_kDHr | SSL_kDHd, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kEDH, 0, SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kDHE, 0, SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_DH, 0, SSL_kDHr | SSL_kDHd | SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, + 0}, + + {0, SSL_TXT_kKRB5, 0, SSL_kKRB5, 0, 0, 0, 0, 0, 0, 0, 0}, + + {0, SSL_TXT_kECDHr, 0, SSL_kECDHr, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kECDHe, 0, SSL_kECDHe, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kECDH, 0, SSL_kECDHr | SSL_kECDHe, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kEECDH, 0, SSL_kEECDH, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kECDHE, 0, SSL_kEECDH, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_ECDH, 0, SSL_kECDHr | SSL_kECDHe | SSL_kEECDH, 0, 0, 0, 0, 0, + 0, 0, 0}, + + {0, SSL_TXT_kPSK, 0, SSL_kPSK, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kSRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kGOST, 0, SSL_kGOST, 0, 0, 0, 0, 0, 0, 0, 0}, + + /* server authentication aliases */ + {0, SSL_TXT_aRSA, 0, 0, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aDSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_DSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aKRB5, 0, 0, SSL_aKRB5, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aNULL, 0, 0, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + /* no such ciphersuites supported! */ + {0, SSL_TXT_aDH, 0, 0, SSL_aDH, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aECDH, 0, 0, SSL_aECDH, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_ECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aPSK, 0, 0, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aGOST94, 0, 0, SSL_aGOST94, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aGOST01, 0, 0, SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aGOST, 0, 0, SSL_aGOST94 | SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aSRP, 0, 0, SSL_aSRP, 0, 0, 0, 0, 0, 0, 0}, + + /* aliases combining key exchange and server authentication */ + {0, SSL_TXT_EDH, 0, SSL_kEDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_DHE, 0, SSL_kEDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_EECDH, 0, SSL_kEECDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_ECDHE, 0, SSL_kEECDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_NULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_KRB5, 0, SSL_kKRB5, SSL_aKRB5, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_RSA, 0, SSL_kRSA, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_ADH, 0, SSL_kEDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_AECDH, 0, SSL_kEECDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_PSK, 0, SSL_kPSK, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, + + /* symmetric encryption aliases */ + {0, SSL_TXT_DES, 0, 0, 0, SSL_DES, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_3DES, 0, 0, 0, SSL_3DES, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_RC4, 0, 0, 0, SSL_RC4, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_RC2, 0, 0, 0, SSL_RC2, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_IDEA, 0, 0, 0, SSL_IDEA, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SEED, 0, 0, 0, SSL_SEED, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_eNULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_AES128, 0, 0, 0, SSL_AES128 | SSL_AES128GCM, 0, 0, 0, 0, 0, + 0}, + {0, SSL_TXT_AES256, 0, 0, 0, SSL_AES256 | SSL_AES256GCM, 0, 0, 0, 0, 0, + 0}, + {0, SSL_TXT_AES, 0, 0, 0, SSL_AES, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_AES_GCM, 0, 0, 0, SSL_AES128GCM | SSL_AES256GCM, 0, 0, 0, 0, + 0, 0}, + {0, SSL_TXT_CAMELLIA128, 0, 0, 0, SSL_CAMELLIA128, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_CAMELLIA256, 0, 0, 0, SSL_CAMELLIA256, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_CAMELLIA, 0, 0, 0, SSL_CAMELLIA128 | SSL_CAMELLIA256, 0, 0, 0, + 0, 0, 0}, + + /* MAC aliases */ + {0, SSL_TXT_MD5, 0, 0, 0, 0, SSL_MD5, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SHA1, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SHA, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0}, + {0, SSL_TXT_GOST94, 0, 0, 0, 0, SSL_GOST94, 0, 0, 0, 0, 0}, + {0, SSL_TXT_GOST89MAC, 0, 0, 0, 0, SSL_GOST89MAC, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SHA256, 0, 0, 0, 0, SSL_SHA256, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SHA384, 0, 0, 0, 0, SSL_SHA384, 0, 0, 0, 0, 0}, + + /* protocol version aliases */ + {0, SSL_TXT_SSLV2, 0, 0, 0, 0, 0, SSL_SSLV2, 0, 0, 0, 0}, + {0, SSL_TXT_SSLV3, 0, 0, 0, 0, 0, SSL_SSLV3, 0, 0, 0, 0}, + {0, SSL_TXT_TLSV1, 0, 0, 0, 0, 0, SSL_TLSV1, 0, 0, 0, 0}, + {0, SSL_TXT_TLSV1_2, 0, 0, 0, 0, 0, SSL_TLSV1_2, 0, 0, 0, 0}, + + /* export flag */ + {0, SSL_TXT_EXP, 0, 0, 0, 0, 0, 0, SSL_EXPORT, 0, 0, 0}, + {0, SSL_TXT_EXPORT, 0, 0, 0, 0, 0, 0, SSL_EXPORT, 0, 0, 0}, + + /* strength classes */ + {0, SSL_TXT_EXP40, 0, 0, 0, 0, 0, 0, SSL_EXP40, 0, 0, 0}, + {0, SSL_TXT_EXP56, 0, 0, 0, 0, 0, 0, SSL_EXP56, 0, 0, 0}, + {0, SSL_TXT_LOW, 0, 0, 0, 0, 0, 0, SSL_LOW, 0, 0, 0}, + {0, SSL_TXT_MEDIUM, 0, 0, 0, 0, 0, 0, SSL_MEDIUM, 0, 0, 0}, + {0, SSL_TXT_HIGH, 0, 0, 0, 0, 0, 0, SSL_HIGH, 0, 0, 0}, + /* FIPS 140-2 approved ciphersuite */ + {0, SSL_TXT_FIPS, 0, 0, 0, ~SSL_eNULL, 0, 0, SSL_FIPS, 0, 0, 0}, + /* "DHE-" aliases to "EDH-" labels (for forward compatibility) */ + {0, SSL3_TXT_DHE_DSS_DES_40_CBC_SHA, 0, + SSL_kDHE, SSL_aDSS, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_EXPORT | SSL_EXP40, + 0, 0, 0,}, + {0, SSL3_TXT_DHE_DSS_DES_64_CBC_SHA, 0, + SSL_kDHE, SSL_aDSS, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_NOT_EXP | SSL_LOW, + 0, 0, 0,}, + {0, SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA, 0, + SSL_kDHE, SSL_aDSS, SSL_3DES, SSL_SHA1, SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, 0, 0, 0,}, + {0, SSL3_TXT_DHE_RSA_DES_40_CBC_SHA, 0, + SSL_kDHE, SSL_aRSA, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_EXPORT | SSL_EXP40, + 0, 0, 0,}, + {0, SSL3_TXT_DHE_RSA_DES_64_CBC_SHA, 0, + SSL_kDHE, SSL_aRSA, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_NOT_EXP | SSL_LOW, + 0, 0, 0,}, + {0, SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA, 0, + SSL_kDHE, SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, 0, 0, 0,}, +}; + +/* + * Search for public key algorithm with given name and return its pkey_id if + * it is available. Otherwise return 0 + */ +#ifdef OPENSSL_NO_ENGINE + +static int get_optional_pkey_id(const char *pkey_name) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id = 0; + ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1); + if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, + ameth) > 0) { + return pkey_id; + } + return 0; +} + +#else + +static int get_optional_pkey_id(const char *pkey_name) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *tmpeng = NULL; + int pkey_id = 0; + ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1); + if (ameth) { + if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, + ameth) <= 0) + pkey_id = 0; + } + if (tmpeng) + ENGINE_finish(tmpeng); + return pkey_id; +} + +#endif + +void ssl_load_ciphers(void) +{ + ssl_cipher_methods[SSL_ENC_DES_IDX] = EVP_get_cipherbyname(SN_des_cbc); + ssl_cipher_methods[SSL_ENC_3DES_IDX] = + EVP_get_cipherbyname(SN_des_ede3_cbc); + ssl_cipher_methods[SSL_ENC_RC4_IDX] = EVP_get_cipherbyname(SN_rc4); + ssl_cipher_methods[SSL_ENC_RC2_IDX] = EVP_get_cipherbyname(SN_rc2_cbc); +#ifndef OPENSSL_NO_IDEA + ssl_cipher_methods[SSL_ENC_IDEA_IDX] = EVP_get_cipherbyname(SN_idea_cbc); +#else + ssl_cipher_methods[SSL_ENC_IDEA_IDX] = NULL; +#endif + ssl_cipher_methods[SSL_ENC_AES128_IDX] = + EVP_get_cipherbyname(SN_aes_128_cbc); + ssl_cipher_methods[SSL_ENC_AES256_IDX] = + EVP_get_cipherbyname(SN_aes_256_cbc); + ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] = + EVP_get_cipherbyname(SN_camellia_128_cbc); + ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] = + EVP_get_cipherbyname(SN_camellia_256_cbc); + ssl_cipher_methods[SSL_ENC_GOST89_IDX] = + EVP_get_cipherbyname(SN_gost89_cnt); + ssl_cipher_methods[SSL_ENC_SEED_IDX] = EVP_get_cipherbyname(SN_seed_cbc); + + ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] = + EVP_get_cipherbyname(SN_aes_128_gcm); + ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] = + EVP_get_cipherbyname(SN_aes_256_gcm); + + ssl_digest_methods[SSL_MD_MD5_IDX] = EVP_get_digestbyname(SN_md5); + ssl_mac_secret_size[SSL_MD_MD5_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); + ssl_digest_methods[SSL_MD_SHA1_IDX] = EVP_get_digestbyname(SN_sha1); + ssl_mac_secret_size[SSL_MD_SHA1_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); + ssl_digest_methods[SSL_MD_GOST94_IDX] = + EVP_get_digestbyname(SN_id_GostR3411_94); + if (ssl_digest_methods[SSL_MD_GOST94_IDX]) { + ssl_mac_secret_size[SSL_MD_GOST94_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); + } + ssl_digest_methods[SSL_MD_GOST89MAC_IDX] = + EVP_get_digestbyname(SN_id_Gost28147_89_MAC); + ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); + if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { + ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; + } + + ssl_digest_methods[SSL_MD_SHA256_IDX] = EVP_get_digestbyname(SN_sha256); + ssl_mac_secret_size[SSL_MD_SHA256_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); + ssl_digest_methods[SSL_MD_SHA384_IDX] = EVP_get_digestbyname(SN_sha384); + ssl_mac_secret_size[SSL_MD_SHA384_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); +} + +#ifndef OPENSSL_NO_COMP + +static int sk_comp_cmp(const SSL_COMP *const *a, const SSL_COMP *const *b) +{ + return ((*a)->id - (*b)->id); +} + +static void load_builtin_compressions(void) +{ + int got_write_lock = 0; + + CRYPTO_r_lock(CRYPTO_LOCK_SSL); + if (ssl_comp_methods == NULL) { + CRYPTO_r_unlock(CRYPTO_LOCK_SSL); + CRYPTO_w_lock(CRYPTO_LOCK_SSL); + got_write_lock = 1; + + if (ssl_comp_methods == NULL) { + SSL_COMP *comp = NULL; + + MemCheck_off(); + ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp); + if (ssl_comp_methods != NULL) { + comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp != NULL) { + comp->method = COMP_zlib(); + if (comp->method && comp->method->type == NID_undef) + OPENSSL_free(comp); + else { + comp->id = SSL_COMP_ZLIB_IDX; + comp->name = comp->method->name; + sk_SSL_COMP_push(ssl_comp_methods, comp); + } + } + sk_SSL_COMP_sort(ssl_comp_methods); + } + MemCheck_on(); + } + } + + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL); + else + CRYPTO_r_unlock(CRYPTO_LOCK_SSL); +} +#endif + +int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, + int *mac_secret_size, SSL_COMP **comp) +{ + int i; + const SSL_CIPHER *c; + + c = s->cipher; + if (c == NULL) + return (0); + if (comp != NULL) { + SSL_COMP ctmp; +#ifndef OPENSSL_NO_COMP + load_builtin_compressions(); +#endif + + *comp = NULL; + ctmp.id = s->compress_meth; + if (ssl_comp_methods != NULL) { + i = sk_SSL_COMP_find(ssl_comp_methods, &ctmp); + if (i >= 0) + *comp = sk_SSL_COMP_value(ssl_comp_methods, i); + else + *comp = NULL; + } + } + + if ((enc == NULL) || (md == NULL)) + return (0); + + switch (c->algorithm_enc) { + case SSL_DES: + i = SSL_ENC_DES_IDX; + break; + case SSL_3DES: + i = SSL_ENC_3DES_IDX; + break; + case SSL_RC4: + i = SSL_ENC_RC4_IDX; + break; + case SSL_RC2: + i = SSL_ENC_RC2_IDX; + break; + case SSL_IDEA: + i = SSL_ENC_IDEA_IDX; + break; + case SSL_eNULL: + i = SSL_ENC_NULL_IDX; + break; + case SSL_AES128: + i = SSL_ENC_AES128_IDX; + break; + case SSL_AES256: + i = SSL_ENC_AES256_IDX; + break; + case SSL_CAMELLIA128: + i = SSL_ENC_CAMELLIA128_IDX; + break; + case SSL_CAMELLIA256: + i = SSL_ENC_CAMELLIA256_IDX; + break; + case SSL_eGOST2814789CNT: + i = SSL_ENC_GOST89_IDX; + break; + case SSL_SEED: + i = SSL_ENC_SEED_IDX; + break; + case SSL_AES128GCM: + i = SSL_ENC_AES128GCM_IDX; + break; + case SSL_AES256GCM: + i = SSL_ENC_AES256GCM_IDX; + break; + default: + i = -1; + break; + } + + if ((i < 0) || (i >= SSL_ENC_NUM_IDX)) + *enc = NULL; + else { + if (i == SSL_ENC_NULL_IDX) + *enc = EVP_enc_null(); + else + *enc = ssl_cipher_methods[i]; + } + + switch (c->algorithm_mac) { + case SSL_MD5: + i = SSL_MD_MD5_IDX; + break; + case SSL_SHA1: + i = SSL_MD_SHA1_IDX; + break; + case SSL_SHA256: + i = SSL_MD_SHA256_IDX; + break; + case SSL_SHA384: + i = SSL_MD_SHA384_IDX; + break; + case SSL_GOST94: + i = SSL_MD_GOST94_IDX; + break; + case SSL_GOST89MAC: + i = SSL_MD_GOST89MAC_IDX; + break; + default: + i = -1; + break; + } + if ((i < 0) || (i >= SSL_MD_NUM_IDX)) { + *md = NULL; + if (mac_pkey_type != NULL) + *mac_pkey_type = NID_undef; + if (mac_secret_size != NULL) + *mac_secret_size = 0; + if (c->algorithm_mac == SSL_AEAD) + mac_pkey_type = NULL; + } else { + *md = ssl_digest_methods[i]; + if (mac_pkey_type != NULL) + *mac_pkey_type = ssl_mac_pkey_id[i]; + if (mac_secret_size != NULL) + *mac_secret_size = ssl_mac_secret_size[i]; + } + + if ((*enc != NULL) && + (*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)) + && (!mac_pkey_type || *mac_pkey_type != NID_undef)) { + const EVP_CIPHER *evp; + + if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR || + s->ssl_version < TLS1_VERSION) + return 1; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return 1; +#endif + + if (c->algorithm_enc == SSL_RC4 && + c->algorithm_mac == SSL_MD5 && + (evp = EVP_get_cipherbyname("RC4-HMAC-MD5"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES128 && + c->algorithm_mac == SSL_SHA1 && + (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES256 && + c->algorithm_mac == SSL_SHA1 && + (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES128 && + c->algorithm_mac == SSL_SHA256 && + (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES256 && + c->algorithm_mac == SSL_SHA256 && + (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256"))) + *enc = evp, *md = NULL; + return (1); + } else + return (0); +} + +int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) +{ + if (idx < 0 || idx >= SSL_MD_NUM_IDX) { + return 0; + } + *mask = ssl_handshake_digest_flag[idx]; + if (*mask) + *md = ssl_digest_methods[idx]; + else + *md = NULL; + return 1; +} + +#define ITEM_SEP(a) \ + (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) + +static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) +{ + if (curr == *tail) + return; + if (curr == *head) + *head = curr->next; + if (curr->prev != NULL) + curr->prev->next = curr->next; + if (curr->next != NULL) + curr->next->prev = curr->prev; + (*tail)->next = curr; + curr->prev = *tail; + curr->next = NULL; + *tail = curr; +} + +static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) +{ + if (curr == *head) + return; + if (curr == *tail) + *tail = curr->prev; + if (curr->next != NULL) + curr->next->prev = curr->prev; + if (curr->prev != NULL) + curr->prev->next = curr->next; + (*head)->prev = curr; + curr->next = *head; + curr->prev = NULL; + *head = curr; +} + +static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, + unsigned long *enc, unsigned long *mac, + unsigned long *ssl) +{ + *mkey = 0; + *auth = 0; + *enc = 0; + *mac = 0; + *ssl = 0; + +#ifdef OPENSSL_NO_RSA + *mkey |= SSL_kRSA; + *auth |= SSL_aRSA; +#endif +#ifdef OPENSSL_NO_DSA + *auth |= SSL_aDSS; +#endif +#ifdef OPENSSL_NO_DH + *mkey |= SSL_kDHr | SSL_kDHd | SSL_kEDH; + *auth |= SSL_aDH; +#endif +#ifdef OPENSSL_NO_KRB5 + *mkey |= SSL_kKRB5; + *auth |= SSL_aKRB5; +#endif +#ifdef OPENSSL_NO_ECDSA + *auth |= SSL_aECDSA; +#endif +#ifdef OPENSSL_NO_ECDH + *mkey |= SSL_kECDHe | SSL_kECDHr; + *auth |= SSL_aECDH; +#endif +#ifdef OPENSSL_NO_PSK + *mkey |= SSL_kPSK; + *auth |= SSL_aPSK; +#endif +#ifdef OPENSSL_NO_SRP + *mkey |= SSL_kSRP; +#endif + /* + * Check for presence of GOST 34.10 algorithms, and if they do not + * present, disable appropriate auth and key exchange + */ + if (!get_optional_pkey_id("gost94")) { + *auth |= SSL_aGOST94; + } + if (!get_optional_pkey_id("gost2001")) { + *auth |= SSL_aGOST01; + } + /* + * Disable GOST key exchange if no GOST signature algs are available * + */ + if ((*auth & (SSL_aGOST94 | SSL_aGOST01)) == (SSL_aGOST94 | SSL_aGOST01)) { + *mkey |= SSL_kGOST; + } +#ifdef SSL_FORBID_ENULL + *enc |= SSL_eNULL; +#endif + + *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX] == NULL) ? SSL_DES : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX] == NULL) ? SSL_RC4 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX] == NULL) ? SSL_RC2 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256 : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == + NULL) ? SSL_AES128GCM : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == + NULL) ? SSL_AES256GCM : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == + NULL) ? SSL_CAMELLIA128 : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == + NULL) ? SSL_CAMELLIA256 : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == + NULL) ? SSL_eGOST2814789CNT : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED : 0; + + *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX] == NULL) ? SSL_MD5 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384 : 0; + *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94 : 0; + *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL + || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] == + NID_undef) ? SSL_GOST89MAC : 0; + +} + +static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, + int num_of_ciphers, + unsigned long disabled_mkey, + unsigned long disabled_auth, + unsigned long disabled_enc, + unsigned long disabled_mac, + unsigned long disabled_ssl, + CIPHER_ORDER *co_list, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) +{ + int i, co_list_num; + const SSL_CIPHER *c; + + /* + * We have num_of_ciphers descriptions compiled in, depending on the + * method selected (SSLv2 and/or SSLv3, TLSv1 etc). + * These will later be sorted in a linked list with at most num + * entries. + */ + + /* Get the initial list of ciphers */ + co_list_num = 0; /* actual count of ciphers */ + for (i = 0; i < num_of_ciphers; i++) { + c = ssl_method->get_cipher(i); + /* drop those that use any of that is not available */ + if ((c != NULL) && c->valid && +#ifdef OPENSSL_FIPS + (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) && +#endif + !(c->algorithm_mkey & disabled_mkey) && + !(c->algorithm_auth & disabled_auth) && + !(c->algorithm_enc & disabled_enc) && + !(c->algorithm_mac & disabled_mac) && + !(c->algorithm_ssl & disabled_ssl)) { + co_list[co_list_num].cipher = c; + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = 0; + co_list_num++; +#ifdef KSSL_DEBUG + fprintf(stderr, "\t%d: %s %lx %lx %lx\n", i, c->name, c->id, + c->algorithm_mkey, c->algorithm_auth); +#endif /* KSSL_DEBUG */ + /* + * if (!sk_push(ca_list,(char *)c)) goto err; + */ + } + } + + /* + * Prepare linked list from list entries + */ + if (co_list_num > 0) { + co_list[0].prev = NULL; + + if (co_list_num > 1) { + co_list[0].next = &co_list[1]; + + for (i = 1; i < co_list_num - 1; i++) { + co_list[i].prev = &co_list[i - 1]; + co_list[i].next = &co_list[i + 1]; + } + + co_list[co_list_num - 1].prev = &co_list[co_list_num - 2]; + } + + co_list[co_list_num - 1].next = NULL; + + *head_p = &co_list[0]; + *tail_p = &co_list[co_list_num - 1]; + } +} + +static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, + int num_of_group_aliases, + unsigned long disabled_mkey, + unsigned long disabled_auth, + unsigned long disabled_enc, + unsigned long disabled_mac, + unsigned long disabled_ssl, + CIPHER_ORDER *head) +{ + CIPHER_ORDER *ciph_curr; + const SSL_CIPHER **ca_curr; + int i; + unsigned long mask_mkey = ~disabled_mkey; + unsigned long mask_auth = ~disabled_auth; + unsigned long mask_enc = ~disabled_enc; + unsigned long mask_mac = ~disabled_mac; + unsigned long mask_ssl = ~disabled_ssl; + + /* + * First, add the real ciphers as already collected + */ + ciph_curr = head; + ca_curr = ca_list; + while (ciph_curr != NULL) { + *ca_curr = ciph_curr->cipher; + ca_curr++; + ciph_curr = ciph_curr->next; + } + + /* + * Now we add the available ones from the cipher_aliases[] table. + * They represent either one or more algorithms, some of which + * in any affected category must be supported (set in enabled_mask), + * or represent a cipher strength value (will be added in any case because algorithms=0). + */ + for (i = 0; i < num_of_group_aliases; i++) { + unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey; + unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth; + unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc; + unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac; + unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl; + + if (algorithm_mkey) + if ((algorithm_mkey & mask_mkey) == 0) + continue; + + if (algorithm_auth) + if ((algorithm_auth & mask_auth) == 0) + continue; + + if (algorithm_enc) + if ((algorithm_enc & mask_enc) == 0) + continue; + + if (algorithm_mac) + if ((algorithm_mac & mask_mac) == 0) + continue; + + if (algorithm_ssl) + if ((algorithm_ssl & mask_ssl) == 0) + continue; + + *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); + ca_curr++; + } + + *ca_curr = NULL; /* end of list */ +} + +static void ssl_cipher_apply_rule(unsigned long cipher_id, + unsigned long alg_mkey, + unsigned long alg_auth, + unsigned long alg_enc, + unsigned long alg_mac, + unsigned long alg_ssl, + unsigned long algo_strength, int rule, + int strength_bits, CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) +{ + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; + int reverse = 0; + +#ifdef CIPHER_DEBUG + fprintf(stderr, + "Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n", + rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, + algo_strength, strength_bits); +#endif + + if (rule == CIPHER_DEL) + reverse = 1; /* needed to maintain sorting between + * currently deleted ciphers */ + + head = *head_p; + tail = *tail_p; + + if (reverse) { + next = tail; + last = head; + } else { + next = head; + last = tail; + } + + curr = NULL; + for (;;) { + if (curr == last) + break; + + curr = next; + + if (curr == NULL) + break; + + next = reverse ? curr->prev : curr->next; + + cp = curr->cipher; + + /* + * Selection criteria is either the value of strength_bits + * or the algorithms used. + */ + if (strength_bits >= 0) { + if (strength_bits != cp->strength_bits) + continue; + } else { +#ifdef CIPHER_DEBUG + fprintf(stderr, + "\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", + cp->name, cp->algorithm_mkey, cp->algorithm_auth, + cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, + cp->algo_strength); +#endif +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + if (cipher_id && cipher_id != cp->id) + continue; +#endif + if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) + continue; + if (alg_auth && !(alg_auth & cp->algorithm_auth)) + continue; + if (alg_enc && !(alg_enc & cp->algorithm_enc)) + continue; + if (alg_mac && !(alg_mac & cp->algorithm_mac)) + continue; + if (alg_ssl && !(alg_ssl & cp->algorithm_ssl)) + continue; + if ((algo_strength & SSL_EXP_MASK) + && !(algo_strength & SSL_EXP_MASK & cp->algo_strength)) + continue; + if ((algo_strength & SSL_STRONG_MASK) + && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength)) + continue; + if ((algo_strength & SSL_NOT_DEFAULT) + && !(cp->algo_strength & SSL_NOT_DEFAULT)) + continue; + } + +#ifdef CIPHER_DEBUG + fprintf(stderr, "Action = %d\n", rule); +#endif + + /* add the cipher if it has not been added yet. */ + if (rule == CIPHER_ADD) { + /* reverse == 0 */ + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = 1; + } + } + /* Move the added cipher to this location */ + else if (rule == CIPHER_ORD) { + /* reverse == 0 */ + if (curr->active) { + ll_append_tail(&head, curr, &tail); + } + } else if (rule == CIPHER_DEL) { + /* reverse == 1 */ + if (curr->active) { + /* + * most recently deleted ciphersuites get best positions for + * any future CIPHER_ADD (note that the CIPHER_DEL loop works + * in reverse to maintain the order) + */ + ll_append_head(&head, curr, &tail); + curr->active = 0; + } + } else if (rule == CIPHER_KILL) { + /* reverse == 0 */ + if (head == curr) + head = curr->next; + else + curr->prev->next = curr->next; + if (tail == curr) + tail = curr->prev; + curr->active = 0; + if (curr->next != NULL) + curr->next->prev = curr->prev; + if (curr->prev != NULL) + curr->prev->next = curr->next; + curr->next = NULL; + curr->prev = NULL; + } + } + + *head_p = head; + *tail_p = tail; +} + +static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) +{ + int max_strength_bits, i, *number_uses; + CIPHER_ORDER *curr; + + /* + * This routine sorts the ciphers with descending strength. The sorting + * must keep the pre-sorted sequence, so we apply the normal sorting + * routine as '+' movement to the end of the list. + */ + max_strength_bits = 0; + curr = *head_p; + while (curr != NULL) { + if (curr->active && (curr->cipher->strength_bits > max_strength_bits)) + max_strength_bits = curr->cipher->strength_bits; + curr = curr->next; + } + + number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); + if (!number_uses) { + SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE); + return (0); + } + memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); + + /* + * Now find the strength_bits values actually used + */ + curr = *head_p; + while (curr != NULL) { + if (curr->active) + number_uses[curr->cipher->strength_bits]++; + curr = curr->next; + } + /* + * Go through the list of used strength_bits values in descending + * order. + */ + for (i = max_strength_bits; i >= 0; i--) + if (number_uses[i] > 0) + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, + tail_p); + + OPENSSL_free(number_uses); + return (1); +} + +static int ssl_cipher_process_rulestr(const char *rule_str, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p, + const SSL_CIPHER **ca_list) +{ + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, + algo_strength; + const char *l, *buf; + int j, multi, found, rule, retval, ok, buflen; + unsigned long cipher_id = 0; + char ch; + + retval = 1; + l = rule_str; + for (;;) { + ch = *l; + + if (ch == '\0') + break; /* done */ + if (ch == '-') { + rule = CIPHER_DEL; + l++; + } else if (ch == '+') { + rule = CIPHER_ORD; + l++; + } else if (ch == '!') { + rule = CIPHER_KILL; + l++; + } else if (ch == '@') { + rule = CIPHER_SPECIAL; + l++; + } else { + rule = CIPHER_ADD; + } + + if (ITEM_SEP(ch)) { + l++; + continue; + } + + alg_mkey = 0; + alg_auth = 0; + alg_enc = 0; + alg_mac = 0; + alg_ssl = 0; + algo_strength = 0; + + for (;;) { + ch = *l; + buf = l; + buflen = 0; +#ifndef CHARSET_EBCDIC + while (((ch >= 'A') && (ch <= 'Z')) || + ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || (ch == '-') || (ch == '.')) +#else + while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.')) +#endif + { + ch = *(++l); + buflen++; + } + + if (buflen == 0) { + /* + * We hit something we cannot deal with, + * it is no command or separator nor + * alphanumeric, so we call this an error. + */ + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, + SSL_R_INVALID_COMMAND); + retval = found = 0; + l++; + break; + } + + if (rule == CIPHER_SPECIAL) { + found = 0; /* unused -- avoid compiler warning */ + break; /* special treatment */ + } + + /* check for multi-part specification */ + if (ch == '+') { + multi = 1; + l++; + } else + multi = 0; + + /* + * Now search for the cipher alias in the ca_list. Be careful + * with the strncmp, because the "buflen" limitation + * will make the rule "ADH:SOME" and the cipher + * "ADH-MY-CIPHER" look like a match for buflen=3. + * So additionally check whether the cipher name found + * has the correct length. We can save a strlen() call: + * just checking for the '\0' at the right place is + * sufficient, we have to strncmp() anyway. (We cannot + * use strcmp(), because buf is not '\0' terminated.) + */ + j = found = 0; + cipher_id = 0; + while (ca_list[j]) { + if (!strncmp(buf, ca_list[j]->name, buflen) && + (ca_list[j]->name[buflen] == '\0')) { + found = 1; + break; + } else + j++; + } + + if (!found) + break; /* ignore this entry */ + + if (ca_list[j]->algorithm_mkey) { + if (alg_mkey) { + alg_mkey &= ca_list[j]->algorithm_mkey; + if (!alg_mkey) { + found = 0; + break; + } + } else + alg_mkey = ca_list[j]->algorithm_mkey; + } + + if (ca_list[j]->algorithm_auth) { + if (alg_auth) { + alg_auth &= ca_list[j]->algorithm_auth; + if (!alg_auth) { + found = 0; + break; + } + } else + alg_auth = ca_list[j]->algorithm_auth; + } + + if (ca_list[j]->algorithm_enc) { + if (alg_enc) { + alg_enc &= ca_list[j]->algorithm_enc; + if (!alg_enc) { + found = 0; + break; + } + } else + alg_enc = ca_list[j]->algorithm_enc; + } + + if (ca_list[j]->algorithm_mac) { + if (alg_mac) { + alg_mac &= ca_list[j]->algorithm_mac; + if (!alg_mac) { + found = 0; + break; + } + } else + alg_mac = ca_list[j]->algorithm_mac; + } + + if (ca_list[j]->algo_strength & SSL_EXP_MASK) { + if (algo_strength & SSL_EXP_MASK) { + algo_strength &= + (ca_list[j]->algo_strength & SSL_EXP_MASK) | + ~SSL_EXP_MASK; + if (!(algo_strength & SSL_EXP_MASK)) { + found = 0; + break; + } + } else + algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK; + } + + if (ca_list[j]->algo_strength & SSL_STRONG_MASK) { + if (algo_strength & SSL_STRONG_MASK) { + algo_strength &= + (ca_list[j]->algo_strength & SSL_STRONG_MASK) | + ~SSL_STRONG_MASK; + if (!(algo_strength & SSL_STRONG_MASK)) { + found = 0; + break; + } + } else + algo_strength |= + ca_list[j]->algo_strength & SSL_STRONG_MASK; + } + + if (ca_list[j]->algo_strength & SSL_NOT_DEFAULT) { + algo_strength |= SSL_NOT_DEFAULT; + } + + if (ca_list[j]->valid) { + /* + * explicit ciphersuite found; its protocol version does not + * become part of the search pattern! + */ + + cipher_id = ca_list[j]->id; + } else { + /* + * not an explicit ciphersuite; only in this case, the + * protocol version is considered part of the search pattern + */ + + if (ca_list[j]->algorithm_ssl) { + if (alg_ssl) { + alg_ssl &= ca_list[j]->algorithm_ssl; + if (!alg_ssl) { + found = 0; + break; + } + } else + alg_ssl = ca_list[j]->algorithm_ssl; + } + } + + if (!multi) + break; + } + + /* + * Ok, we have the rule, now apply it + */ + if (rule == CIPHER_SPECIAL) { /* special command */ + ok = 0; + if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) + ok = ssl_cipher_strength_sort(head_p, tail_p); + else + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, + SSL_R_INVALID_COMMAND); + if (ok == 0) + retval = 0; + /* + * We do not support any "multi" options + * together with "@", so throw away the + * rest of the command, if any left, until + * end or ':' is found. + */ + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; + } else if (found) { + ssl_cipher_apply_rule(cipher_id, + alg_mkey, alg_auth, alg_enc, alg_mac, + alg_ssl, algo_strength, rule, -1, head_p, + tail_p); + } else { + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; + } + if (*l == '\0') + break; /* done */ + } + + return (retval); +} + +#ifndef OPENSSL_NO_EC +static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, + const char **prule_str) +{ + unsigned int suiteb_flags = 0; +# ifndef OPENSSL_NO_ECDH + unsigned int suiteb_comb2 = 0; +#endif + + if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) { + suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY; + } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) { +# ifndef OPENSSL_NO_ECDH + suiteb_comb2 = 1; +# endif + suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; + } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) { + suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; + } else if (strncmp(*prule_str, "SUITEB192", 9) == 0) { + suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS; + } + + if (suiteb_flags) { + c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS; + c->cert_flags |= suiteb_flags; + } else + suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS; + + if (!suiteb_flags) + return 1; + /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */ + + if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) { + if (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, + SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); + else + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, + SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); + return 0; + } +# ifndef OPENSSL_NO_ECDH + switch (suiteb_flags) { + case SSL_CERT_FLAG_SUITEB_128_LOS: + if (suiteb_comb2) + *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384"; + else + *prule_str = + "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384"; + break; + case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: + *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256"; + break; + case SSL_CERT_FLAG_SUITEB_192_LOS: + *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384"; + break; + } + /* Set auto ECDH parameter determination */ + c->ecdh_tmp_auto = 1; + return 1; +# else + SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, + SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE); + return 0; +# endif +} +#endif + +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER) + **cipher_list, STACK_OF(SSL_CIPHER) + **cipher_list_by_id, + const char *rule_str, CERT *c) +{ + int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; + unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, + disabled_ssl; + STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; + const char *rule_p; + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; + const SSL_CIPHER **ca_list = NULL; + + /* + * Return with error if nothing to do. + */ + if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) + return NULL; +#ifndef OPENSSL_NO_EC + if (!check_suiteb_cipher_list(ssl_method, c, &rule_str)) + return NULL; +#endif + + /* + * To reduce the work to do we only want to process the compiled + * in algorithms, so we first get the mask of disabled ciphers. + */ + ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, + &disabled_mac, &disabled_ssl); + + /* + * Now we have to collect the available ciphers from the compiled + * in ciphers. We cannot get more than the number compiled in, so + * it is used for allocation. + */ + num_of_ciphers = ssl_method->num_ciphers(); +#ifdef KSSL_DEBUG + fprintf(stderr, "ssl_create_cipher_list() for %d ciphers\n", + num_of_ciphers); +#endif /* KSSL_DEBUG */ + co_list = + (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); + if (co_list == NULL) { + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return (NULL); /* Failure */ + } + + ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, + disabled_mkey, disabled_auth, disabled_enc, + disabled_mac, disabled_ssl, co_list, &head, + &tail); + + /* Now arrange all ciphers by preference: */ + + /* + * Everything else being equal, prefer ephemeral ECDH over other key + * exchange mechanisms + */ + ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, + &tail); + ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, + &tail); + + /* AES is our preferred symmetric cipher */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, + &tail); + + /* Temporarily enable everything else for sorting */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + + /* Low priority for MD5 */ + ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, + &tail); + + /* + * Move anonymous ciphers to the end. Usually, these will remain + * disabled. (For applications that allow them, they aren't too bad, but + * we prefer authenticated ciphers.) + */ + ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + + /* Move ciphers without forward secrecy to the end */ + ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + /* + * ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, + * &head, &tail); + */ + ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + ssl_cipher_apply_rule(0, SSL_kKRB5, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + + /* RC4 is sort-of broken -- move the the end */ + ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + + /* + * Now sort by symmetric encryption strength. The above ordering remains + * in force within each class + */ + if (!ssl_cipher_strength_sort(&head, &tail)) { + OPENSSL_free(co_list); + return NULL; + } + + /* Now disable everything (maintaining the ordering!) */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + + /* + * We also need cipher aliases for selecting based on the rule_str. + * There might be two types of entries in the rule_str: 1) names + * of ciphers themselves 2) aliases for groups of ciphers. + * For 1) we need the available ciphers and for 2) the cipher + * groups of cipher_aliases added together in one list (otherwise + * we would be happy with just the cipher_aliases table). + */ + num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); + num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; + ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); + if (ca_list == NULL) { + OPENSSL_free(co_list); + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return (NULL); /* Failure */ + } + ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, + disabled_mkey, disabled_auth, disabled_enc, + disabled_mac, disabled_ssl, head); + + /* + * If the rule_string begins with DEFAULT, apply the default rule + * before using the (possibly available) additional rules. + */ + ok = 1; + rule_p = rule_str; + if (strncmp(rule_str, "DEFAULT", 7) == 0) { + ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, + &head, &tail, ca_list); + rule_p += 7; + if (*rule_p == ':') + rule_p++; + } + + if (ok && (strlen(rule_p) > 0)) + ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); + + OPENSSL_free((void *)ca_list); /* Not needed anymore */ + + if (!ok) { /* Rule processing failure */ + OPENSSL_free(co_list); + return (NULL); + } + + /* + * Allocate new "cipherstack" for the result, return with error + * if we cannot get one. + */ + if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { + OPENSSL_free(co_list); + return (NULL); + } + + /* + * The cipher selection for the list is done. The ciphers are added + * to the resulting precedence to the STACK_OF(SSL_CIPHER). + */ + for (curr = head; curr != NULL; curr = curr->next) { +#ifdef OPENSSL_FIPS + if (curr->active + && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) +#else + if (curr->active) +#endif + { + sk_SSL_CIPHER_push(cipherstack, curr->cipher); +#ifdef CIPHER_DEBUG + fprintf(stderr, "<%s>\n", curr->cipher->name); +#endif + } + } + OPENSSL_free(co_list); /* Not needed any longer */ + + tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack); + if (tmp_cipher_list == NULL) { + sk_SSL_CIPHER_free(cipherstack); + return NULL; + } + if (*cipher_list != NULL) + sk_SSL_CIPHER_free(*cipher_list); + *cipher_list = cipherstack; + if (*cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(*cipher_list_by_id); + *cipher_list_by_id = tmp_cipher_list; + (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, + ssl_cipher_ptr_id_cmp); + + sk_SSL_CIPHER_sort(*cipher_list_by_id); + return (cipherstack); +} + +char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) +{ + int is_export, pkl, kl; + const char *ver, *exp_str; + const char *kx, *au, *enc, *mac; + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2; +#ifdef KSSL_DEBUG + static const char *format = + "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n"; +#else + static const char *format = + "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; +#endif /* KSSL_DEBUG */ + + alg_mkey = cipher->algorithm_mkey; + alg_auth = cipher->algorithm_auth; + alg_enc = cipher->algorithm_enc; + alg_mac = cipher->algorithm_mac; + alg_ssl = cipher->algorithm_ssl; + + alg2 = cipher->algorithm2; + + is_export = SSL_C_IS_EXPORT(cipher); + pkl = SSL_C_EXPORT_PKEYLENGTH(cipher); + kl = SSL_C_EXPORT_KEYLENGTH(cipher); + exp_str = is_export ? " export" : ""; + + if (alg_ssl & SSL_SSLV2) + ver = "SSLv2"; + else if (alg_ssl & SSL_SSLV3) + ver = "SSLv3"; + else if (alg_ssl & SSL_TLSV1_2) + ver = "TLSv1.2"; + else + ver = "unknown"; + + switch (alg_mkey) { + case SSL_kRSA: + kx = is_export ? (pkl == 512 ? "RSA(512)" : "RSA(1024)") : "RSA"; + break; + case SSL_kDHr: + kx = "DH/RSA"; + break; + case SSL_kDHd: + kx = "DH/DSS"; + break; + case SSL_kKRB5: + kx = "KRB5"; + break; + case SSL_kEDH: + kx = is_export ? (pkl == 512 ? "DH(512)" : "DH(1024)") : "DH"; + break; + case SSL_kECDHr: + kx = "ECDH/RSA"; + break; + case SSL_kECDHe: + kx = "ECDH/ECDSA"; + break; + case SSL_kEECDH: + kx = "ECDH"; + break; + case SSL_kPSK: + kx = "PSK"; + break; + case SSL_kSRP: + kx = "SRP"; + break; + case SSL_kGOST: + kx = "GOST"; + break; + default: + kx = "unknown"; + } + + switch (alg_auth) { + case SSL_aRSA: + au = "RSA"; + break; + case SSL_aDSS: + au = "DSS"; + break; + case SSL_aDH: + au = "DH"; + break; + case SSL_aKRB5: + au = "KRB5"; + break; + case SSL_aECDH: + au = "ECDH"; + break; + case SSL_aNULL: + au = "None"; + break; + case SSL_aECDSA: + au = "ECDSA"; + break; + case SSL_aPSK: + au = "PSK"; + break; + case SSL_aSRP: + au = "SRP"; + break; + case SSL_aGOST94: + au = "GOST94"; + break; + case SSL_aGOST01: + au = "GOST01"; + break; + default: + au = "unknown"; + break; + } + + switch (alg_enc) { + case SSL_DES: + enc = (is_export && kl == 5) ? "DES(40)" : "DES(56)"; + break; + case SSL_3DES: + enc = "3DES(168)"; + break; + case SSL_RC4: + enc = is_export ? (kl == 5 ? "RC4(40)" : "RC4(56)") + : ((alg2 & SSL2_CF_8_BYTE_ENC) ? "RC4(64)" : "RC4(128)"); + break; + case SSL_RC2: + enc = is_export ? (kl == 5 ? "RC2(40)" : "RC2(56)") : "RC2(128)"; + break; + case SSL_IDEA: + enc = "IDEA(128)"; + break; + case SSL_eNULL: + enc = "None"; + break; + case SSL_AES128: + enc = "AES(128)"; + break; + case SSL_AES256: + enc = "AES(256)"; + break; + case SSL_AES128GCM: + enc = "AESGCM(128)"; + break; + case SSL_AES256GCM: + enc = "AESGCM(256)"; + break; + case SSL_CAMELLIA128: + enc = "Camellia(128)"; + break; + case SSL_CAMELLIA256: + enc = "Camellia(256)"; + break; + case SSL_SEED: + enc = "SEED(128)"; + break; + case SSL_eGOST2814789CNT: + enc = "GOST89(256)"; + break; + default: + enc = "unknown"; + break; + } + + switch (alg_mac) { + case SSL_MD5: + mac = "MD5"; + break; + case SSL_SHA1: + mac = "SHA1"; + break; + case SSL_SHA256: + mac = "SHA256"; + break; + case SSL_SHA384: + mac = "SHA384"; + break; + case SSL_AEAD: + mac = "AEAD"; + break; + case SSL_GOST89MAC: + mac = "GOST89"; + break; + case SSL_GOST94: + mac = "GOST94"; + break; + default: + mac = "unknown"; + break; + } + + if (buf == NULL) { + len = 128; + buf = OPENSSL_malloc(len); + if (buf == NULL) + return ("OPENSSL_malloc Error"); + } else if (len < 128) + return ("Buffer too small"); + +#ifdef KSSL_DEBUG + BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac, + exp_str, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl); +#else + BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac, + exp_str); +#endif /* KSSL_DEBUG */ + return (buf); +} + +char *SSL_CIPHER_get_version(const SSL_CIPHER *c) +{ + int i; + + if (c == NULL) + return ("(NONE)"); + i = (int)(c->id >> 24L); + if (i == 3) + return ("TLSv1/SSLv3"); + else if (i == 2) + return ("SSLv2"); + else + return ("unknown"); +} + +/* return the actual cipher being used */ +const char *SSL_CIPHER_get_name(const SSL_CIPHER *c) +{ + if (c != NULL) + return (c->name); + return ("(NONE)"); +} + +/* number of bits for symmetric cipher */ +int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) +{ + int ret = 0; + + if (c != NULL) { + if (alg_bits != NULL) + *alg_bits = c->alg_bits; + ret = c->strength_bits; + } + return (ret); +} + +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c) +{ + return c->id; +} + +SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) +{ + SSL_COMP *ctmp; + int i, nn; + + if ((n == 0) || (sk == NULL)) + return (NULL); + nn = sk_SSL_COMP_num(sk); + for (i = 0; i < nn; i++) { + ctmp = sk_SSL_COMP_value(sk, i); + if (ctmp->id == n) + return (ctmp); + } + return (NULL); +} + +#ifdef OPENSSL_NO_COMP +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) +{ + return NULL; +} + +STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths) +{ + return NULL; +} + +void SSL_COMP_free_compression_methods(void) +{ +} + +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) +{ + return 1; +} + +const char *SSL_COMP_get_name(const COMP_METHOD *comp) +{ + return NULL; +} +#else +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) +{ + load_builtin_compressions(); + return (ssl_comp_methods); +} + +STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths) +{ + STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods; + ssl_comp_methods = meths; + return old_meths; +} + +static void cmeth_free(SSL_COMP *cm) +{ + OPENSSL_free(cm); +} + +void SSL_COMP_free_compression_methods(void) +{ + STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods; + ssl_comp_methods = NULL; + sk_SSL_COMP_pop_free(old_meths, cmeth_free); +} + +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) +{ + SSL_COMP *comp; + + if (cm == NULL || cm->type == NID_undef) + return 1; + + /*- + * According to draft-ietf-tls-compression-04.txt, the + * compression number ranges should be the following: + * + * 0 to 63: methods defined by the IETF + * 64 to 192: external party methods assigned by IANA + * 193 to 255: reserved for private use + */ + if (id < 193 || id > 255) { + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, + SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); + return 1; + } + + MemCheck_off(); + comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp == NULL) { + MemCheck_on(); + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); + return 1; + } + comp->id = id; + comp->method = cm; + comp->name = cm->name; + load_builtin_compressions(); + if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) { + OPENSSL_free(comp); + MemCheck_on(); + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, + SSL_R_DUPLICATE_COMPRESSION_ID); + return (1); + } else if ((ssl_comp_methods == NULL) + || !sk_SSL_COMP_push(ssl_comp_methods, comp)) { + OPENSSL_free(comp); + MemCheck_on(); + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); + return (1); + } else { + MemCheck_on(); + return (0); + } +} + +const char *SSL_COMP_get_name(const COMP_METHOD *comp) +{ + if (comp) + return comp->name; + return NULL; +} +#endif +/* For a cipher return the index corresponding to the certificate type */ +int ssl_cipher_get_cert_index(const SSL_CIPHER *c) +{ + unsigned long alg_k, alg_a; + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + + if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { + /* + * we don't need to look at SSL_kEECDH since no certificate is needed + * for anon ECDH and for authenticated EECDH, the check for the auth + * algorithm will set i correctly NOTE: For ECDH-RSA, we need an ECC + * not an RSA cert but for EECDH-RSA we need an RSA cert. Placing the + * checks for SSL_kECDH before RSA checks ensures the correct cert is + * chosen. + */ + return SSL_PKEY_ECC; + } else if (alg_a & SSL_aECDSA) + return SSL_PKEY_ECC; + else if (alg_k & SSL_kDHr) + return SSL_PKEY_DH_RSA; + else if (alg_k & SSL_kDHd) + return SSL_PKEY_DH_DSA; + else if (alg_a & SSL_aDSS) + return SSL_PKEY_DSA_SIGN; + else if (alg_a & SSL_aRSA) + return SSL_PKEY_RSA_ENC; + else if (alg_a & SSL_aKRB5) + /* VRS something else here? */ + return -1; + else if (alg_a & SSL_aGOST94) + return SSL_PKEY_GOST94; + else if (alg_a & SSL_aGOST01) + return SSL_PKEY_GOST01; + return -1; +} + +const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr) +{ + const SSL_CIPHER *c; + c = ssl->method->get_cipher_by_char(ptr); + if (c == NULL || c->valid == 0) + return NULL; + return c; +} + +const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr) +{ + return ssl->method->get_cipher_by_char(ptr); +} +/* + * ! \file ssl/ssl_conf.c \brief SSL configuration functions + */ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef REF_CHECK +# include +#endif +#include +// #include "ssl_locl.h" +#include "conf.h" +// #include "objects.h" +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif + +/* + * structure holding name tables. This is used for pemitted elements in lists + * such as TLSv1 and single command line switches such as no_tls1 + */ + +typedef struct { + const char *name; + int namelen; + unsigned int name_flags; + unsigned long option_value; +} ssl_flag_tbl; + +/* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */ +#define SSL_TFLAG_INV 0x1 +/* Flags refers to cert_flags not options */ +#define SSL_TFLAG_CERT 0x2 +/* Option can only be used for clients */ +#define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT +/* Option can only be used for servers */ +#define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER +#define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER) + +#define SSL_FLAG_TBL(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag} +#define SSL_FLAG_TBL_SRV(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag} +#define SSL_FLAG_TBL_CLI(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag} +#define SSL_FLAG_TBL_INV(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag} +#define SSL_FLAG_TBL_SRV_INV(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag} +#define SSL_FLAG_TBL_CERT(str, flag) \ + {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag} + +/* + * Opaque structure containing SSL configuration context. + */ + +struct ssl_conf_ctx_st { + /* + * Various flags indicating (among other things) which options we will + * recognise. + */ + unsigned int flags; + /* Prefix and length of commands */ + char *prefix; + size_t prefixlen; + /* SSL_CTX or SSL structure to perform operations on */ + SSL_CTX *ctx; + SSL *ssl; + /* Pointer to SSL or SSL_CTX options field or NULL if none */ + unsigned long *poptions; + /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */ + unsigned int *pcert_flags; + /* Current flag table being worked on */ + const ssl_flag_tbl *tbl; + /* Size of table */ + size_t ntbl; +}; + +static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl, + const char *name, int namelen, int onoff) +{ + /* If name not relevant for context skip */ + if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH)) + return 0; + if (namelen == -1) { + if (strcmp(tbl->name, name)) + return 0; + } else if (tbl->namelen != namelen + || strncasecmp(tbl->name, name, namelen)) + return 0; + if (cctx->poptions) { + if (tbl->name_flags & SSL_TFLAG_INV) + onoff ^= 1; + if (tbl->name_flags & SSL_TFLAG_CERT) { + if (onoff) + *cctx->pcert_flags |= tbl->option_value; + else + *cctx->pcert_flags &= ~tbl->option_value; + } else { + if (onoff) + *cctx->poptions |= tbl->option_value; + else + *cctx->poptions &= ~tbl->option_value; + } + } + return 1; +} + +static int ssl_set_option_list(const char *elem, int len, void *usr) +{ + SSL_CONF_CTX *cctx = usr; + size_t i; + const ssl_flag_tbl *tbl; + int onoff = 1; + /* + * len == -1 indicates not being called in list context, just for single + * command line switches, so don't allow +, -. + */ + if (elem == NULL) + return 0; + if (len != -1) { + if (*elem == '+') { + elem++; + len--; + onoff = 1; + } else if (*elem == '-') { + elem++; + len--; + onoff = 0; + } + } + for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) { + if (ssl_match_option(cctx, tbl, elem, len, onoff)) + return 1; + } + return 0; +} + +/* Single command line switches with no argument e.g. -no_ssl3 */ +static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd) +{ + static const ssl_flag_tbl ssl_option_single[] = { + SSL_FLAG_TBL("no_ssl2", SSL_OP_NO_SSLv2), + SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3), + SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1), + SSL_FLAG_TBL("no_tls1_1", SSL_OP_NO_TLSv1_1), + SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2), + SSL_FLAG_TBL("bugs", SSL_OP_ALL), + SSL_FLAG_TBL("no_comp", SSL_OP_NO_COMPRESSION), + SSL_FLAG_TBL_SRV("ecdh_single", SSL_OP_SINGLE_ECDH_USE), +#ifndef OPENSSL_NO_TLSEXT + SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET), +#endif + SSL_FLAG_TBL_SRV("serverpref", SSL_OP_CIPHER_SERVER_PREFERENCE), + SSL_FLAG_TBL("legacy_renegotiation", + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), + SSL_FLAG_TBL_SRV("legacy_server_connect", + SSL_OP_LEGACY_SERVER_CONNECT), + SSL_FLAG_TBL_SRV("no_resumption_on_reneg", + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), + SSL_FLAG_TBL_SRV_INV("no_legacy_server_connect", + SSL_OP_LEGACY_SERVER_CONNECT), + SSL_FLAG_TBL_CERT("strict", SSL_CERT_FLAG_TLS_STRICT), +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + SSL_FLAG_TBL_CERT("debug_broken_protocol", + SSL_CERT_FLAG_BROKEN_PROTOCOL), +#endif + }; + cctx->tbl = ssl_option_single; + cctx->ntbl = sizeof(ssl_option_single) / sizeof(ssl_flag_tbl); + return ssl_set_option_list(cmd, -1, cctx); +} + +/* Set supported signature algorithms */ +static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value) +{ + int rv; + if (cctx->ssl) + rv = SSL_set1_sigalgs_list(cctx->ssl, value); + /* NB: ctx == NULL performs syntax checking only */ + else + rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value); + return rv > 0; +} + +/* Set supported client signature algorithms */ +static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, + const char *value) +{ + int rv; + if (cctx->ssl) + rv = SSL_set1_client_sigalgs_list(cctx->ssl, value); + /* NB: ctx == NULL performs syntax checking only */ + else + rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value); + return rv > 0; +} + +static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value) +{ + int rv; + if (cctx->ssl) + rv = SSL_set1_curves_list(cctx->ssl, value); + /* NB: ctx == NULL performs syntax checking only */ + else + rv = SSL_CTX_set1_curves_list(cctx->ctx, value); + return rv > 0; +} + +#ifndef OPENSSL_NO_ECDH +/* ECDH temporary parameters */ +static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value) +{ + int onoff = -1, rv = 1; + if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) + return -2; + if (cctx->flags & SSL_CONF_FLAG_FILE) { + if (*value == '+') { + onoff = 1; + value++; + } + if (*value == '-') { + onoff = 0; + value++; + } + if (!strcasecmp(value, "automatic")) { + if (onoff == -1) + onoff = 1; + } else if (onoff != -1) + return 0; + } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { + if (!strcmp(value, "auto")) + onoff = 1; + } + + if (onoff != -1) { + if (cctx->ctx) + rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff); + else if (cctx->ssl) + rv = SSL_set_ecdh_auto(cctx->ssl, onoff); + } else { + EC_KEY *ecdh; + int nid; + nid = EC_curve_nist2nid(value); + if (nid == NID_undef) + nid = OBJ_sn2nid(value); + if (nid == 0) + return 0; + ecdh = EC_KEY_new_by_curve_name(nid); + if (!ecdh) + return 0; + if (cctx->ctx) + rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh); + else if (cctx->ssl) + rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh); + EC_KEY_free(ecdh); + } + + return rv > 0; +} +#endif +static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value) +{ + int rv = 1; + if (cctx->ctx) + rv = SSL_CTX_set_cipher_list(cctx->ctx, value); + if (cctx->ssl) + rv = SSL_set_cipher_list(cctx->ssl, value); + return rv > 0; +} + +static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) +{ + static const ssl_flag_tbl ssl_protocol_list[] = { + SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK), + SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2), + SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3), + SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1), + SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1), + SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2) + }; + int ret; + int sslv2off; + + if (!(cctx->flags & SSL_CONF_FLAG_FILE)) + return -2; + cctx->tbl = ssl_protocol_list; + cctx->ntbl = sizeof(ssl_protocol_list) / sizeof(ssl_flag_tbl); + + sslv2off = *cctx->poptions & SSL_OP_NO_SSLv2; + ret = CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); + /* Never turn on SSLv2 through configuration */ + *cctx->poptions |= sslv2off; + return ret; +} + +static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) +{ + static const ssl_flag_tbl ssl_option_list[] = { + SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET), + SSL_FLAG_TBL_INV("EmptyFragments", + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS), + SSL_FLAG_TBL("Bugs", SSL_OP_ALL), + SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION), + SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE), + SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation", + SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), + SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE), + SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), + SSL_FLAG_TBL("UnsafeLegacyRenegotiation", + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), + }; + if (!(cctx->flags & SSL_CONF_FLAG_FILE)) + return -2; + if (value == NULL) + return -3; + cctx->tbl = ssl_option_list; + cctx->ntbl = sizeof(ssl_option_list) / sizeof(ssl_flag_tbl); + return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); +} + +static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) +{ + int rv = 1; + if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) + return -2; + if (cctx->ctx) + rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value); + if (cctx->ssl) + rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM); + return rv > 0; +} + +static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value) +{ + int rv = 1; + if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) + return -2; + if (cctx->ctx) + rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM); + if (cctx->ssl) + rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM); + return rv > 0; +} + +static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value) +{ + int rv = 1; + if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) + return -2; + if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) + return -2; + if (cctx->ctx) + rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value); + return rv > 0; +} + +#ifndef OPENSSL_NO_DH +static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) +{ + int rv = 0; + DH *dh = NULL; + BIO *in = NULL; + if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) + return -2; + if (cctx->ctx || cctx->ssl) { + in = BIO_new(BIO_s_file_internal()); + if (!in) + goto end; + if (BIO_read_filename(in, value) <= 0) + goto end; + dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); + if (!dh) + goto end; + } else + return 1; + if (cctx->ctx) + rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh); + if (cctx->ssl) + rv = SSL_set_tmp_dh(cctx->ssl, dh); + end: + if (dh) + DH_free(dh); + if (in) + BIO_free(in); + return rv > 0; +} +#endif +typedef struct { + int (*cmd) (SSL_CONF_CTX *cctx, const char *value); + const char *str_file; + const char *str_cmdline; + unsigned int value_type; +} ssl_conf_cmd_tbl; + +/* Table of supported parameters */ + +#define SSL_CONF_CMD(name, cmdopt, type) \ + {cmd_##name, #name, cmdopt, type} + +#define SSL_CONF_CMD_STRING(name, cmdopt) \ + SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING) + +static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { + SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"), + SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"), + SSL_CONF_CMD_STRING(Curves, "curves"), +#ifndef OPENSSL_NO_ECDH + SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"), +#endif + SSL_CONF_CMD_STRING(CipherString, "cipher"), + SSL_CONF_CMD_STRING(Protocol, NULL), + SSL_CONF_CMD_STRING(Options, NULL), + SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE), + SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE), + SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE), +#ifndef OPENSSL_NO_DH + SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE) +#endif +}; + +static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) +{ + if (!pcmd || !*pcmd) + return 0; + /* If a prefix is set, check and skip */ + if (cctx->prefix) { + if (strlen(*pcmd) <= cctx->prefixlen) + return 0; + if (cctx->flags & SSL_CONF_FLAG_CMDLINE && + strncmp(*pcmd, cctx->prefix, cctx->prefixlen)) + return 0; + if (cctx->flags & SSL_CONF_FLAG_FILE && + strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen)) + return 0; + *pcmd += cctx->prefixlen; + } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { + if (**pcmd != '-' || !(*pcmd)[1]) + return 0; + *pcmd += 1; + } + return 1; +} + +static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, + const char *cmd) +{ + const ssl_conf_cmd_tbl *t; + size_t i; + if (cmd == NULL) + return NULL; + + /* Look for matching parameter name in table */ + for (i = 0, t = ssl_conf_cmds; + i < sizeof(ssl_conf_cmds) / sizeof(ssl_conf_cmd_tbl); i++, t++) { + if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { + if (t->str_cmdline && !strcmp(t->str_cmdline, cmd)) + return t; + } + if (cctx->flags & SSL_CONF_FLAG_FILE) { + if (t->str_file && !strcasecmp(t->str_file, cmd)) + return t; + } + } + return NULL; +} + +int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) +{ + const ssl_conf_cmd_tbl *runcmd; + if (cmd == NULL) { + SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME); + return 0; + } + + if (!ssl_conf_cmd_skip_prefix(cctx, &cmd)) + return -2; + + runcmd = ssl_conf_cmd_lookup(cctx, cmd); + + if (runcmd) { + int rv; + if (value == NULL) + return -3; + rv = runcmd->cmd(cctx, value); + if (rv > 0) + return 2; + if (rv == -2) + return -2; + if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { + SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE); + ERR_add_error_data(4, "cmd=", cmd, ", value=", value); + } + return 0; + } + + if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { + if (ctrl_str_option(cctx, cmd)) + return 1; + } + + if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { + SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME); + ERR_add_error_data(2, "cmd=", cmd); + } + + return -2; +} + +int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv) +{ + int rv; + const char *arg = NULL, *argn; + if (pargc && *pargc == 0) + return 0; + if (!pargc || *pargc > 0) + arg = **pargv; + if (arg == NULL) + return 0; + if (!pargc || *pargc > 1) + argn = (*pargv)[1]; + else + argn = NULL; + cctx->flags &= ~SSL_CONF_FLAG_FILE; + cctx->flags |= SSL_CONF_FLAG_CMDLINE; + rv = SSL_CONF_cmd(cctx, arg, argn); + if (rv > 0) { + /* Success: update pargc, pargv */ + (*pargv) += rv; + if (pargc) + (*pargc) -= rv; + return rv; + } + /* Unknown switch: indicate no arguments processed */ + if (rv == -2) + return 0; + /* Some error occurred processing command, return fatal error */ + if (rv == 0) + return -1; + return rv; +} + +int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd) +{ + if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) { + const ssl_conf_cmd_tbl *runcmd; + runcmd = ssl_conf_cmd_lookup(cctx, cmd); + if (runcmd) + return runcmd->value_type; + } + return SSL_CONF_TYPE_UNKNOWN; +} + +SSL_CONF_CTX *SSL_CONF_CTX_new(void) +{ + SSL_CONF_CTX *ret; + ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX)); + if (ret) { + ret->flags = 0; + ret->prefix = NULL; + ret->prefixlen = 0; + ret->ssl = NULL; + ret->ctx = NULL; + ret->poptions = NULL; + ret->pcert_flags = NULL; + ret->tbl = NULL; + ret->ntbl = 0; + } + return ret; +} + +int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx) +{ + return 1; +} + +void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx) +{ + if (cctx) { + if (cctx->prefix) + OPENSSL_free(cctx->prefix); + OPENSSL_free(cctx); + } +} + +unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags) +{ + cctx->flags |= flags; + return cctx->flags; +} + +unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags) +{ + cctx->flags &= ~flags; + return cctx->flags; +} + +int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre) +{ + char *tmp = NULL; + if (pre) { + tmp = BUF_strdup(pre); + if (tmp == NULL) + return 0; + } + if (cctx->prefix) + OPENSSL_free(cctx->prefix); + cctx->prefix = tmp; + if (tmp) + cctx->prefixlen = strlen(tmp); + else + cctx->prefixlen = 0; + return 1; +} + +void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl) +{ + cctx->ssl = ssl; + cctx->ctx = NULL; + if (ssl) { + cctx->poptions = &ssl->options; + cctx->pcert_flags = &ssl->cert->cert_flags; + } else { + cctx->poptions = NULL; + cctx->pcert_flags = NULL; + } +} + +void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx) +{ + cctx->ctx = ctx; + cctx->ssl = NULL; + if (ctx) { + cctx->poptions = &ctx->options; + cctx->pcert_flags = &ctx->cert->cert_flags; + } else { + cctx->poptions = NULL; + cctx->pcert_flags = NULL; + } +} +/* ssl/ssl_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "ssl.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason) + +static ERR_STRING_DATA SSL_str_functs[] = { + {ERR_FUNC(SSL_F_CHECK_SUITEB_CIPHER_LIST), "CHECK_SUITEB_CIPHER_LIST"}, + {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"}, + {ERR_FUNC(SSL_F_CLIENT_HELLO), "CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_CLIENT_MASTER_KEY), "CLIENT_MASTER_KEY"}, + {ERR_FUNC(SSL_F_D2I_SSL_SESSION), "d2i_SSL_SESSION"}, + {ERR_FUNC(SSL_F_DO_DTLS1_WRITE), "do_dtls1_write"}, + {ERR_FUNC(SSL_F_DO_SSL3_WRITE), "DO_SSL3_WRITE"}, + {ERR_FUNC(SSL_F_DTLS1_ACCEPT), "dtls1_accept"}, + {ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"}, + {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "dtls1_check_timeout_num"}, + {ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "dtls1_client_hello"}, + {ERR_FUNC(SSL_F_DTLS1_CONNECT), "dtls1_connect"}, + {ERR_FUNC(SSL_F_DTLS1_GET_HELLO_VERIFY), "DTLS1_GET_HELLO_VERIFY"}, + {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE), "dtls1_get_message"}, + {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), + "DTLS1_GET_MESSAGE_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "dtls1_get_record"}, + {ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "dtls1_handle_timeout"}, + {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"}, + {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "dtls1_output_cert_chain"}, + {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), + "DTLS1_PROCESS_BUFFERED_RECORDS"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), + "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "dtls1_read_bytes"}, + {ERR_FUNC(SSL_F_DTLS1_READ_FAILED), "dtls1_read_failed"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST), + "dtls1_send_certificate_request"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE), + "dtls1_send_client_certificate"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE), + "dtls1_send_client_key_exchange"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_VERIFY), "dtls1_send_client_verify"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST), + "DTLS1_SEND_HELLO_VERIFY_REQUEST"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE), + "dtls1_send_server_certificate"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_HELLO), "dtls1_send_server_hello"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE), + "dtls1_send_server_key_exchange"}, + {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES), + "dtls1_write_app_data_bytes"}, + {ERR_FUNC(SSL_F_GET_CLIENT_FINISHED), "GET_CLIENT_FINISHED"}, + {ERR_FUNC(SSL_F_GET_CLIENT_HELLO), "GET_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_GET_CLIENT_MASTER_KEY), "GET_CLIENT_MASTER_KEY"}, + {ERR_FUNC(SSL_F_GET_SERVER_FINISHED), "GET_SERVER_FINISHED"}, + {ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_GET_SERVER_STATIC_DH_KEY), "GET_SERVER_STATIC_DH_KEY"}, + {ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"}, + {ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"}, + {ERR_FUNC(SSL_F_READ_N), "READ_N"}, + {ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"}, + {ERR_FUNC(SSL_F_SERVER_HELLO), "SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SERVER_VERIFY), "SERVER_VERIFY"}, + {ERR_FUNC(SSL_F_SSL23_ACCEPT), "ssl23_accept"}, + {ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO), "SSL23_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_CONNECT), "ssl23_connect"}, + {ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO), "SSL23_GET_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO), "SSL23_GET_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_PEEK), "ssl23_peek"}, + {ERR_FUNC(SSL_F_SSL23_READ), "ssl23_read"}, + {ERR_FUNC(SSL_F_SSL23_WRITE), "ssl23_write"}, + {ERR_FUNC(SSL_F_SSL2_ACCEPT), "ssl2_accept"}, + {ERR_FUNC(SSL_F_SSL2_CONNECT), "ssl2_connect"}, + {ERR_FUNC(SSL_F_SSL2_ENC_INIT), "ssl2_enc_init"}, + {ERR_FUNC(SSL_F_SSL2_GENERATE_KEY_MATERIAL), + "ssl2_generate_key_material"}, + {ERR_FUNC(SSL_F_SSL2_PEEK), "ssl2_peek"}, + {ERR_FUNC(SSL_F_SSL2_READ), "ssl2_read"}, + {ERR_FUNC(SSL_F_SSL2_READ_INTERNAL), "SSL2_READ_INTERNAL"}, + {ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE), "ssl2_set_certificate"}, + {ERR_FUNC(SSL_F_SSL2_WRITE), "ssl2_write"}, + {ERR_FUNC(SSL_F_SSL3_ACCEPT), "ssl3_accept"}, + {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, + {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "ssl3_callback_ctrl"}, + {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "ssl3_change_cipher_state"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), + "ssl3_check_cert_and_algorithm"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "ssl3_check_client_hello"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_FINISHED), "SSL3_CHECK_FINISHED"}, + {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "ssl3_client_hello"}, + {ERR_FUNC(SSL_F_SSL3_CONNECT), "ssl3_connect"}, + {ERR_FUNC(SSL_F_SSL3_CTRL), "ssl3_ctrl"}, + {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "ssl3_ctx_ctrl"}, + {ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS), + "ssl3_digest_cached_records"}, + {ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), + "ssl3_do_change_cipher_spec"}, + {ERR_FUNC(SSL_F_SSL3_ENC), "ssl3_enc"}, + {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET), + "ssl3_generate_master_secret"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), + "ssl3_get_certificate_request"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "ssl3_get_cert_status"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "ssl3_get_cert_verify"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE), + "ssl3_get_client_certificate"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "ssl3_get_client_hello"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE), + "ssl3_get_client_key_exchange"}, + {ERR_FUNC(SSL_F_SSL3_GET_FINISHED), "ssl3_get_finished"}, + {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE), "ssl3_get_key_exchange"}, + {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE), "ssl3_get_message"}, + {ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET), + "ssl3_get_new_session_ticket"}, + {ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO), "ssl3_get_next_proto"}, + {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "SSL3_GET_RECORD"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE), + "ssl3_get_server_certificate"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "ssl3_get_server_done"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO), "ssl3_get_server_hello"}, + {ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC), "ssl3_handshake_mac"}, + {ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET), "SSL3_NEW_SESSION_TICKET"}, + {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "ssl3_output_cert_chain"}, + {ERR_FUNC(SSL_F_SSL3_PEEK), "ssl3_peek"}, + {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "ssl3_read_bytes"}, + {ERR_FUNC(SSL_F_SSL3_READ_N), "ssl3_read_n"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST), + "ssl3_send_certificate_request"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE), + "ssl3_send_client_certificate"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE), + "ssl3_send_client_key_exchange"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "ssl3_send_client_verify"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE), + "ssl3_send_server_certificate"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO), "ssl3_send_server_hello"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE), + "ssl3_send_server_key_exchange"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "ssl3_setup_key_block"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER), "ssl3_setup_read_buffer"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "ssl3_setup_write_buffer"}, + {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "ssl3_write_bytes"}, + {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "ssl3_write_pending"}, + {ERR_FUNC(SSL_F_SSL_ADD_CERT_CHAIN), "ssl_add_cert_chain"}, + {ERR_FUNC(SSL_F_SSL_ADD_CERT_TO_BUF), "SSL_ADD_CERT_TO_BUF"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), + "ssl_add_clienthello_renegotiate_ext"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), + "ssl_add_clienthello_tlsext"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT), + "ssl_add_clienthello_use_srtp_ext"}, + {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), + "SSL_add_dir_cert_subjects_to_stack"}, + {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), + "SSL_add_file_cert_subjects_to_stack"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT), + "ssl_add_serverhello_renegotiate_ext"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), + "ssl_add_serverhello_tlsext"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT), + "ssl_add_serverhello_use_srtp_ext"}, + {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "ssl_bad_method"}, + {ERR_FUNC(SSL_F_SSL_BUILD_CERT_CHAIN), "ssl_build_cert_chain"}, + {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "ssl_bytes_to_cipher_list"}, + {ERR_FUNC(SSL_F_SSL_CERT_DUP), "ssl_cert_dup"}, + {ERR_FUNC(SSL_F_SSL_CERT_INST), "ssl_cert_inst"}, + {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE), "SSL_CERT_INSTANTIATE"}, + {ERR_FUNC(SSL_F_SSL_CERT_NEW), "ssl_cert_new"}, + {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"}, + {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT), + "SSL_CHECK_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG), + "ssl_check_srvr_ecc_cert_and_alg"}, + {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR), + "SSL_CIPHER_PROCESS_RULESTR"}, + {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"}, + {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"}, + {ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD), + "SSL_COMP_add_compression_method"}, + {ERR_FUNC(SSL_F_SSL_CONF_CMD), "SSL_CONF_cmd"}, + {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "ssl_create_cipher_list"}, + {ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"}, + {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"}, + {ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES), "SSL_CTX_MAKE_PROFILES"}, + {ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE), + "SSL_CTX_set_client_cert_engine"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE), "SSL_CTX_set_purpose"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), + "SSL_CTX_set_session_id_context"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST), "SSL_CTX_set_trust"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1), + "SSL_CTX_use_certificate_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE), + "SSL_CTX_use_certificate_chain_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE), + "SSL_CTX_use_certificate_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1), + "SSL_CTX_use_PrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE), + "SSL_CTX_use_PrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT), + "SSL_CTX_use_psk_identity_hint"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY), "SSL_CTX_use_RSAPrivateKey"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1), + "SSL_CTX_use_RSAPrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE), + "SSL_CTX_use_RSAPrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_SERVERINFO), "SSL_CTX_use_serverinfo"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_SERVERINFO_FILE), + "SSL_CTX_use_serverinfo_file"}, + {ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE), "SSL_do_handshake"}, + {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "ssl_get_new_session"}, + {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "ssl_get_prev_session"}, + {ERR_FUNC(SSL_F_SSL_GET_SERVER_CERT_INDEX), "SSL_GET_SERVER_CERT_INDEX"}, + {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"}, + {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "ssl_get_server_send_pkey"}, + {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "ssl_get_sign_pkey"}, + {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "ssl_init_wbio_buffer"}, + {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, + {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT), + "ssl_parse_clienthello_renegotiate_ext"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), + "ssl_parse_clienthello_tlsext"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT), + "ssl_parse_clienthello_use_srtp_ext"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT), + "ssl_parse_serverhello_renegotiate_ext"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), + "ssl_parse_serverhello_tlsext"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT), + "ssl_parse_serverhello_use_srtp_ext"}, + {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"}, + {ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT), + "ssl_prepare_clienthello_tlsext"}, + {ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT), + "ssl_prepare_serverhello_tlsext"}, + {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, + {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, + {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, + {ERR_FUNC(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT), + "SSL_SCAN_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT), + "SSL_SCAN_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"}, + {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"}, + {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, + {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), + "SSL_SESSION_set1_id_context"}, + {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "ssl_sess_cert_new"}, + {ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"}, + {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"}, + {ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"}, + {ERR_FUNC(SSL_F_SSL_SET_PKEY), "SSL_SET_PKEY"}, + {ERR_FUNC(SSL_F_SSL_SET_PURPOSE), "SSL_set_purpose"}, + {ERR_FUNC(SSL_F_SSL_SET_RFD), "SSL_set_rfd"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION), "SSL_set_session"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT), + "SSL_set_session_id_context"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), + "SSL_set_session_ticket_ext"}, + {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, + {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, + {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, + {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), + "ssl_undefined_const_function"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "ssl_undefined_function"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), + "ssl_undefined_void_function"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY), "SSL_use_PrivateKey"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1), "SSL_use_PrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE), "SSL_use_PrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT), "SSL_use_psk_identity_hint"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY), "SSL_use_RSAPrivateKey"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1), + "SSL_use_RSAPrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE), + "SSL_use_RSAPrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "ssl_verify_cert_chain"}, + {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, + {ERR_FUNC(SSL_F_TLS12_CHECK_PEER_SIGALG), "tls12_check_peer_sigalg"}, + {ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"}, + {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "tls1_change_cipher_state"}, + {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), + "TLS1_CHECK_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_ENC), "tls1_enc"}, + {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), + "tls1_export_keying_material"}, + {ERR_FUNC(SSL_F_TLS1_GET_CURVELIST), "TLS1_GET_CURVELIST"}, + {ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "tls1_heartbeat"}, + {ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), + "TLS1_PREPARE_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), + "TLS1_PREPARE_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, + {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "tls1_setup_key_block"}, + {ERR_FUNC(SSL_F_TLS1_SET_SERVER_SIGALGS), "tls1_set_server_sigalgs"}, + {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, + {0, NULL} +}; + +static ERR_STRING_DATA SSL_str_reasons[] = { + {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE), "app data in handshake"}, + {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), + "attempt to reuse session in different context"}, + {ERR_REASON(SSL_R_BAD_ALERT_RECORD), "bad alert record"}, + {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"}, + {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"}, + {ERR_REASON(SSL_R_BAD_CHECKSUM), "bad checksum"}, + {ERR_REASON(SSL_R_BAD_DATA), "bad data"}, + {ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), + "bad data returned by callback"}, + {ERR_REASON(SSL_R_BAD_DECOMPRESSION), "bad decompression"}, + {ERR_REASON(SSL_R_BAD_DH_G_LENGTH), "bad dh g length"}, + {ERR_REASON(SSL_R_BAD_DH_G_VALUE), "bad dh g value"}, + {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH), "bad dh pub key length"}, + {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"}, + {ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"}, + {ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"}, + {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"}, + {ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"}, + {ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"}, + {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE), "bad ecdsa signature"}, + {ERR_REASON(SSL_R_BAD_ECPOINT), "bad ecpoint"}, + {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH), "bad handshake length"}, + {ERR_REASON(SSL_R_BAD_HELLO_REQUEST), "bad hello request"}, + {ERR_REASON(SSL_R_BAD_LENGTH), "bad length"}, + {ERR_REASON(SSL_R_BAD_MAC_DECODE), "bad mac decode"}, + {ERR_REASON(SSL_R_BAD_MAC_LENGTH), "bad mac length"}, + {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE), "bad message type"}, + {ERR_REASON(SSL_R_BAD_PACKET_LENGTH), "bad packet length"}, + {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), + "bad protocol version number"}, + {ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH), + "bad psk identity hint length"}, + {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT), "bad response argument"}, + {ERR_REASON(SSL_R_BAD_RSA_DECRYPT), "bad rsa decrypt"}, + {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT), "bad rsa encrypt"}, + {ERR_REASON(SSL_R_BAD_RSA_E_LENGTH), "bad rsa e length"}, + {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"}, + {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE), "bad rsa signature"}, + {ERR_REASON(SSL_R_BAD_SIGNATURE), "bad signature"}, + {ERR_REASON(SSL_R_BAD_SRP_A_LENGTH), "bad srp a length"}, + {ERR_REASON(SSL_R_BAD_SRP_B_LENGTH), "bad srp b length"}, + {ERR_REASON(SSL_R_BAD_SRP_G_LENGTH), "bad srp g length"}, + {ERR_REASON(SSL_R_BAD_SRP_N_LENGTH), "bad srp n length"}, + {ERR_REASON(SSL_R_BAD_SRP_PARAMETERS), "bad srp parameters"}, + {ERR_REASON(SSL_R_BAD_SRP_S_LENGTH), "bad srp s length"}, + {ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE), "bad srtp mki value"}, + {ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), + "bad srtp protection profile list"}, + {ERR_REASON(SSL_R_BAD_SSL_FILETYPE), "bad ssl filetype"}, + {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH), + "bad ssl session id length"}, + {ERR_REASON(SSL_R_BAD_STATE), "bad state"}, + {ERR_REASON(SSL_R_BAD_VALUE), "bad value"}, + {ERR_REASON(SSL_R_BAD_WRITE_RETRY), "bad write retry"}, + {ERR_REASON(SSL_R_BIO_NOT_SET), "bio not set"}, + {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), + "block cipher pad is wrong"}, + {ERR_REASON(SSL_R_BN_LIB), "bn lib"}, + {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH), "ca dn length mismatch"}, + {ERR_REASON(SSL_R_CA_DN_TOO_LONG), "ca dn too long"}, + {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY), "ccs received early"}, + {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED), + "certificate verify failed"}, + {ERR_REASON(SSL_R_CERT_CB_ERROR), "cert cb error"}, + {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH), "cert length mismatch"}, + {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"}, + {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"}, + {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE), + "cipher or hash unavailable"}, + {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"}, + {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT), "clienthello tlsext"}, + {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG), + "compressed length too long"}, + {ERR_REASON(SSL_R_COMPRESSION_DISABLED), "compression disabled"}, + {ERR_REASON(SSL_R_COMPRESSION_FAILURE), "compression failure"}, + {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), + "compression id not within private range"}, + {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR), + "compression library error"}, + {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT), + "connection id is different"}, + {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"}, + {ERR_REASON(SSL_R_COOKIE_MISMATCH), "cookie mismatch"}, + {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED), + "data between ccs and finished"}, + {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG), "data length too long"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED), "decryption failed"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), + "decryption failed or bad record mac"}, + {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"}, + {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), + "dh public value length is wrong"}, + {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED), "digest check failed"}, + {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG), "dtls message too big"}, + {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"}, + {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT), + "ecc cert not for key agreement"}, + {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"}, + {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE), + "ecc cert should have rsa signature"}, + {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE), + "ecc cert should have sha1 signature"}, + {ERR_REASON(SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE), + "ecdh required for suiteb mode"}, + {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER), + "ecgroup too large for cipher"}, + {ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), + "empty srtp protection profile list"}, + {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG), + "encrypted length too long"}, + {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY), + "error generating tmp rsa key"}, + {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), + "error in received cipher list"}, + {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"}, + {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE), "extra data in message"}, + {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"}, + {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS), + "got next proto before a ccs"}, + {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION), + "got next proto without seeing extension"}, + {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST), "https proxy request"}, + {ERR_REASON(SSL_R_HTTP_REQUEST), "http request"}, + {ERR_REASON(SSL_R_ILLEGAL_PADDING), "illegal padding"}, + {ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST), "illegal Suite B digest"}, + {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"}, + {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"}, + {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"}, + {ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"}, + {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM), + "invalid compression algorithm"}, + {ERR_REASON(SSL_R_INVALID_NULL_CMD_NAME), "invalid null cmd name"}, + {ERR_REASON(SSL_R_INVALID_PURPOSE), "invalid purpose"}, + {ERR_REASON(SSL_R_INVALID_SERVERINFO_DATA), "invalid serverinfo data"}, + {ERR_REASON(SSL_R_INVALID_SRP_USERNAME), "invalid srp username"}, + {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"}, + {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH), + "invalid ticket keys length"}, + {ERR_REASON(SSL_R_INVALID_TRUST), "invalid trust"}, + {ERR_REASON(SSL_R_KEY_ARG_TOO_LONG), "key arg too long"}, + {ERR_REASON(SSL_R_KRB5), "krb5"}, + {ERR_REASON(SSL_R_KRB5_C_CC_PRINC), "krb5 client cc principal (no tkt?)"}, + {ERR_REASON(SSL_R_KRB5_C_GET_CRED), "krb5 client get cred"}, + {ERR_REASON(SSL_R_KRB5_C_INIT), "krb5 client init"}, + {ERR_REASON(SSL_R_KRB5_C_MK_REQ), "krb5 client mk_req (expired tkt?)"}, + {ERR_REASON(SSL_R_KRB5_S_BAD_TICKET), "krb5 server bad ticket"}, + {ERR_REASON(SSL_R_KRB5_S_INIT), "krb5 server init"}, + {ERR_REASON(SSL_R_KRB5_S_RD_REQ), "krb5 server rd_req (keytab perms?)"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED), "krb5 server tkt expired"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_NYV), "krb5 server tkt not yet valid"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_SKEW), "krb5 server tkt skew"}, + {ERR_REASON(SSL_R_LENGTH_MISMATCH), "length mismatch"}, + {ERR_REASON(SSL_R_LENGTH_TOO_SHORT), "length too short"}, + {ERR_REASON(SSL_R_LIBRARY_BUG), "library bug"}, + {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"}, + {ERR_REASON(SSL_R_MESSAGE_TOO_LONG), "message too long"}, + {ERR_REASON(SSL_R_MISSING_DH_DSA_CERT), "missing dh dsa cert"}, + {ERR_REASON(SSL_R_MISSING_DH_KEY), "missing dh key"}, + {ERR_REASON(SSL_R_MISSING_DH_RSA_CERT), "missing dh rsa cert"}, + {ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_ECDH_CERT), "missing ecdh cert"}, + {ERR_REASON(SSL_R_MISSING_ECDSA_SIGNING_CERT), + "missing ecdsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY), + "missing export tmp dh key"}, + {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY), + "missing export tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"}, + {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), + "missing rsa encrypting cert"}, + {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_SRP_PARAM), "can't find SRP server param"}, + {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key"}, + {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY), "missing tmp ecdh key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY), "missing tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY), "missing tmp rsa pkey"}, + {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"}, + {ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS), "multiple sgc restarts"}, + {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"}, + {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_SET), "no certificate set"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"}, + {ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE), "no ciphers available"}, + {ERR_REASON(SSL_R_NO_CIPHERS_PASSED), "no ciphers passed"}, + {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED), "no ciphers specified"}, + {ERR_REASON(SSL_R_NO_CIPHER_LIST), "no cipher list"}, + {ERR_REASON(SSL_R_NO_CIPHER_MATCH), "no cipher match"}, + {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD), "no client cert method"}, + {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"}, + {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"}, + {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), + "Peer haven't sent GOST certificate, required for selected ciphersuite"}, + {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED), "no method specified"}, + {ERR_REASON(SSL_R_NO_PEM_EXTENSIONS), "no pem extensions"}, + {ERR_REASON(SSL_R_NO_PRIVATEKEY), "no privatekey"}, + {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"}, + {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"}, + {ERR_REASON(SSL_R_NO_PUBLICKEY), "no publickey"}, + {ERR_REASON(SSL_R_NO_RENEGOTIATION), "no renegotiation"}, + {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST), + "digest requred for handshake isn't computed"}, + {ERR_REASON(SSL_R_NO_SHARED_CIPHER), "no shared cipher"}, + {ERR_REASON(SSL_R_NO_SHARED_SIGATURE_ALGORITHMS), + "no shared sigature algorithms"}, + {ERR_REASON(SSL_R_NO_SRTP_PROFILES), "no srtp profiles"}, + {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK), "no verify callback"}, + {ERR_REASON(SSL_R_NULL_SSL_CTX), "null ssl ctx"}, + {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"}, + {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), + "old session cipher not returned"}, + {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), + "old session compression algorithm not returned"}, + {ERR_REASON(SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE), + "only DTLS 1.2 allowed in Suite B mode"}, + {ERR_REASON(SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE), + "only TLS 1.2 allowed in Suite B mode"}, + {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), + "only tls allowed in fips mode"}, + {ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG), + "opaque PRF input too long"}, + {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"}, + {ERR_REASON(SSL_R_PARSE_TLSEXT), "parse tlsext"}, + {ERR_REASON(SSL_R_PATH_TOO_LONG), "path too long"}, + {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), + "peer did not return a certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR), "peer error"}, + {ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE), + "peer error no certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER), "peer error no cipher"}, + {ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE), + "peer error unsupported certificate type"}, + {ERR_REASON(SSL_R_PEM_NAME_BAD_PREFIX), "pem name bad prefix"}, + {ERR_REASON(SSL_R_PEM_NAME_TOO_SHORT), "pem name too short"}, + {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"}, + {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS), + "problems mapping cipher functions"}, + {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN), "protocol is shutdown"}, + {ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"}, + {ERR_REASON(SSL_R_PSK_NO_CLIENT_CB), "psk no client cb"}, + {ERR_REASON(SSL_R_PSK_NO_SERVER_CB), "psk no server cb"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA), "public key is not rsa"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, + {ERR_REASON(SSL_R_READ_BIO_NOT_SET), "read bio not set"}, + {ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED), "read timeout expired"}, + {ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"}, + {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"}, + {ERR_REASON(SSL_R_RECORD_TOO_LARGE), "record too large"}, + {ERR_REASON(SSL_R_RECORD_TOO_SMALL), "record too small"}, + {ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"}, + {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR), + "renegotiation encoding err"}, + {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"}, + {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"}, + {ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING), + "required compresssion algorithm missing"}, + {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO), + "reuse cert length not zero"}, + {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"}, + {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO), + "reuse cipher list not zero"}, + {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), + "scsv received when renegotiating"}, + {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"}, + {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), + "session id context uninitialized"}, + {ERR_REASON(SSL_R_SHORT_READ), "short read"}, + {ERR_REASON(SSL_R_SHUTDOWN_WHILE_IN_INIT), "shutdown while in init"}, + {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR), + "signature algorithms error"}, + {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), + "signature for non signing certificate"}, + {ERR_REASON(SSL_R_SRP_A_CALC), "error with the srp params"}, + {ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), + "srtp could not allocate profiles"}, + {ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), + "srtp protection profile list too long"}, + {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), + "srtp unknown protection profile"}, + {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), + "ssl23 doing session id reuse"}, + {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG), + "ssl2 connection id too long"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), + "ssl3 ext invalid ecpointformat"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), + "ssl3 ext invalid servername"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE), + "ssl3 ext invalid servername type"}, + {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"}, + {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT), + "ssl3 session id too short"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), + "sslv3 alert bad certificate"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), + "sslv3 alert bad record mac"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), + "sslv3 alert certificate expired"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), + "sslv3 alert certificate revoked"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), + "sslv3 alert certificate unknown"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), + "sslv3 alert decompression failure"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), + "sslv3 alert handshake failure"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), + "sslv3 alert illegal parameter"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE), + "sslv3 alert no certificate"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), + "sslv3 alert unexpected message"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), + "sslv3 alert unsupported certificate"}, + {ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), + "ssl ctx has no default ssl version"}, + {ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE), "ssl handshake failure"}, + {ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), + "ssl library has no ciphers"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), + "ssl session id callback failed"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), + "ssl session id context too long"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), + "ssl session id has bad length"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT), + "ssl session id is different"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED), + "tlsv1 alert access denied"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), + "tlsv1 alert decryption failed"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), + "tlsv1 alert decrypt error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), + "tlsv1 alert export restriction"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), + "tlsv1 alert inappropriate fallback"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), + "tlsv1 alert insufficient security"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), + "tlsv1 alert internal error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), + "tlsv1 alert no renegotiation"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), + "tlsv1 alert protocol version"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), + "tlsv1 alert record overflow"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED), + "tlsv1 alert user cancelled"}, + {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), + "tlsv1 bad certificate hash value"}, + {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), + "tlsv1 bad certificate status response"}, + {ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), + "tlsv1 certificate unobtainable"}, + {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"}, + {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION), + "tlsv1 unsupported extension"}, + {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER), + "tls client cert req with anon cipher"}, + {ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), + "peer does not accept heartbeats"}, + {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING), + "heartbeat request already pending"}, + {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), + "tls illegal exporter label"}, + {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), + "tls invalid ecpointformat list"}, + {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"}, + {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), + "tls peer did not respond with certificate list"}, + {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), + "tls rsa encrypted value length is wrong"}, + {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), + "tried to use unsupported cipher"}, + {ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS), + "unable to decode dh certs"}, + {ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), + "unable to decode ecdh certs"}, + {ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY), + "unable to extract public key"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS), + "unable to find dh parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), + "unable to find ecdh parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), + "unable to find public key parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD), + "unable to find ssl method"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES), + "unable to load ssl2 md5 routines"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES), + "unable to load ssl3 md5 routines"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), + "unable to load ssl3 sha1 routines"}, + {ERR_REASON(SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, + {ERR_REASON(SSL_R_UNEXPECTED_RECORD), "unexpected record"}, + {ERR_REASON(SSL_R_UNINITIALIZED), "uninitialized"}, + {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"}, + {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"}, + {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"}, + {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE), "unknown cipher type"}, + {ERR_REASON(SSL_R_UNKNOWN_CMD_NAME), "unknown cmd name"}, + {ERR_REASON(SSL_R_UNKNOWN_DIGEST), "unknown digest"}, + {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), + "unknown key exchange type"}, + {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE), "unknown pkey type"}, + {ERR_REASON(SSL_R_UNKNOWN_PROTOCOL), "unknown protocol"}, + {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE), + "unknown remote error type"}, + {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION), "unknown ssl version"}, + {ERR_REASON(SSL_R_UNKNOWN_STATE), "unknown state"}, + {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), + "unsafe legacy renegotiation disabled"}, + {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, + {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), + "unsupported compression algorithm"}, + {ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"}, + {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), + "unsupported elliptic curve"}, + {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL), "unsupported protocol"}, + {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"}, + {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"}, + {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"}, + {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET), "write bio not set"}, + {ERR_REASON(SSL_R_WRONG_CERTIFICATE_TYPE), "wrong certificate type"}, + {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"}, + {ERR_REASON(SSL_R_WRONG_CURVE), "wrong curve"}, + {ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE), "wrong message type"}, + {ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE), "wrong signature size"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE), "wrong signature type"}, + {ERR_REASON(SSL_R_WRONG_SSL_VERSION), "wrong ssl version"}, + {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER), "wrong version number"}, + {ERR_REASON(SSL_R_X509_LIB), "x509 lib"}, + {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), + "x509 verification setup problems"}, + {0, NULL} +}; + +#endif + +void ERR_load_SSL_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) { + ERR_load_strings(0, SSL_str_functs); + ERR_load_strings(0, SSL_str_reasons); + } +#endif +} +/* ssl/ssl_err2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "err.h" +// #include "ssl.h" + +void SSL_load_error_strings(void) +{ +#ifndef OPENSSL_NO_ERR + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); +#endif +} +/* + * ! \file ssl/ssl_lib.c \brief Version independent SSL functions. + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifdef REF_CHECK +# include +#endif +#include +// #include "ssl_locl.h" +#include "kssl_lcl.h" +// #include "objects.h" +// #include "lhash.h" +// #include "x509v3.h" +#include "rand.h" +#include "ocsp.h" +#ifndef OPENSSL_NO_DH +# include "dh.h" +#endif +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif + +const char *SSL_version_str = OPENSSL_VERSION_TEXT; + +SSL3_ENC_METHOD ssl3_undef_enc_method = { + /* + * evil casts, but these functions are only called if there's a library + * bug + */ + (int (*)(SSL *, int))ssl_undefined_function, + (int (*)(SSL *, unsigned char *, int))ssl_undefined_function, + ssl_undefined_function, + (int (*)(SSL *, unsigned char *, unsigned char *, int)) + ssl_undefined_function, + (int (*)(SSL *, int))ssl_undefined_function, + (int (*)(SSL *, const char *, int, unsigned char *)) + ssl_undefined_function, + 0, /* finish_mac_length */ + (int (*)(SSL *, int, unsigned char *))ssl_undefined_function, + NULL, /* client_finished_label */ + 0, /* client_finished_label_len */ + NULL, /* server_finished_label */ + 0, /* server_finished_label_len */ + (int (*)(int))ssl_undefined_function, + (int (*)(SSL *, unsigned char *, size_t, const char *, + size_t, const unsigned char *, size_t, + int use_context))ssl_undefined_function, +}; + +int SSL_clear(SSL *s) +{ + + if (s->method == NULL) { + SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED); + return (0); + } + + if (ssl_clear_bad_session(s)) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + s->error = 0; + s->hit = 0; + s->shutdown = 0; + +#if 0 + /* + * Disabled since version 1.10 of this file (early return not + * needed because SSL_clear is not called when doing renegotiation) + */ + /* + * This is set if we are doing dynamic renegotiation so keep + * the old cipher. It is sort of a SSL_clear_lite :-) + */ + if (s->renegotiate) + return (1); +#else + if (s->renegotiate) { + SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR); + return 0; + } +#endif + + s->type = 0; + + s->state = SSL_ST_BEFORE | ((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT); + + s->version = s->method->version; + s->client_version = s->version; + s->rwstate = SSL_NOTHING; + s->rstate = SSL_ST_READ_HEADER; +#if 0 + s->read_ahead = s->ctx->read_ahead; +#endif + + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } + + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); + + s->first_packet = 0; +#ifndef OPENSSL_NO_TLSEXT + if (s->cert != NULL) { + if (s->cert->alpn_proposed) { + OPENSSL_free(s->cert->alpn_proposed); + s->cert->alpn_proposed = NULL; + } + s->cert->alpn_proposed_len = 0; + s->cert->alpn_sent = 0; + } +#endif +#if 1 + /* + * Check to see if we were changed into a different method, if so, revert + * back if we are not doing session-id reuse. + */ + if (!s->in_handshake && (s->session == NULL) + && (s->method != s->ctx->method)) { + s->method->ssl_free(s); + s->method = s->ctx->method; + if (!s->method->ssl_new(s)) + return (0); + } else +#endif + s->method->ssl_clear(s); + return (1); +} + +/** Used to change an SSL_CTXs default SSL method type */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) +{ + STACK_OF(SSL_CIPHER) *sk; + + ctx->method = meth; + + sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list), + &(ctx->cipher_list_by_id), + meth->version == + SSL2_VERSION ? "SSLv2" : + SSL_DEFAULT_CIPHER_LIST, ctx->cert); + if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { + SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, + SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); + return (0); + } + return (1); +} + +SSL *SSL_new(SSL_CTX *ctx) +{ + SSL *s; + + if (ctx == NULL) { + SSLerr(SSL_F_SSL_NEW, SSL_R_NULL_SSL_CTX); + return (NULL); + } + if (ctx->method == NULL) { + SSLerr(SSL_F_SSL_NEW, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); + return (NULL); + } + + s = (SSL *)OPENSSL_malloc(sizeof(SSL)); + if (s == NULL) + goto err; + memset(s, 0, sizeof(SSL)); + +#ifndef OPENSSL_NO_KRB5 + s->kssl_ctx = kssl_ctx_new(); +#endif /* OPENSSL_NO_KRB5 */ + + s->options = ctx->options; + s->mode = ctx->mode; + s->max_cert_list = ctx->max_cert_list; + s->references = 1; + + if (ctx->cert != NULL) { + /* + * Earlier library versions used to copy the pointer to the CERT, not + * its contents; only when setting new parameters for the per-SSL + * copy, ssl_cert_new would be called (and the direct reference to + * the per-SSL_CTX settings would be lost, but those still were + * indirectly accessed for various purposes, and for that reason they + * used to be known as s->ctx->default_cert). Now we don't look at the + * SSL_CTX's CERT after having duplicated it once. + */ + + s->cert = ssl_cert_dup(ctx->cert); + if (s->cert == NULL) + goto err; + } else + s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */ + + s->read_ahead = ctx->read_ahead; + s->msg_callback = ctx->msg_callback; + s->msg_callback_arg = ctx->msg_callback_arg; + s->verify_mode = ctx->verify_mode; +#if 0 + s->verify_depth = ctx->verify_depth; +#endif + s->sid_ctx_length = ctx->sid_ctx_length; + OPENSSL_assert(s->sid_ctx_length <= sizeof(s->sid_ctx)); + memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); + s->verify_callback = ctx->default_verify_callback; + s->generate_session_id = ctx->generate_session_id; + + s->param = X509_VERIFY_PARAM_new(); + if (!s->param) + goto err; + X509_VERIFY_PARAM_inherit(s->param, ctx->param); +#if 0 + s->purpose = ctx->purpose; + s->trust = ctx->trust; +#endif + s->quiet_shutdown = ctx->quiet_shutdown; + s->max_send_fragment = ctx->max_send_fragment; + + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + s->ctx = ctx; +#ifndef OPENSSL_NO_TLSEXT + s->tlsext_debug_cb = 0; + s->tlsext_debug_arg = NULL; + s->tlsext_ticket_expected = 0; + s->tlsext_status_type = -1; + s->tlsext_status_expected = 0; + s->tlsext_ocsp_ids = NULL; + s->tlsext_ocsp_exts = NULL; + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resplen = -1; + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + s->initial_ctx = ctx; +# ifndef OPENSSL_NO_EC + if (ctx->tlsext_ecpointformatlist) { + s->tlsext_ecpointformatlist = + BUF_memdup(ctx->tlsext_ecpointformatlist, + ctx->tlsext_ecpointformatlist_length); + if (!s->tlsext_ecpointformatlist) + goto err; + s->tlsext_ecpointformatlist_length = + ctx->tlsext_ecpointformatlist_length; + } + if (ctx->tlsext_ellipticcurvelist) { + s->tlsext_ellipticcurvelist = + BUF_memdup(ctx->tlsext_ellipticcurvelist, + ctx->tlsext_ellipticcurvelist_length); + if (!s->tlsext_ellipticcurvelist) + goto err; + s->tlsext_ellipticcurvelist_length = + ctx->tlsext_ellipticcurvelist_length; + } +# endif +# ifndef OPENSSL_NO_NEXTPROTONEG + s->next_proto_negotiated = NULL; +# endif + + if (s->ctx->alpn_client_proto_list) { + s->alpn_client_proto_list = + OPENSSL_malloc(s->ctx->alpn_client_proto_list_len); + if (s->alpn_client_proto_list == NULL) + goto err; + memcpy(s->alpn_client_proto_list, s->ctx->alpn_client_proto_list, + s->ctx->alpn_client_proto_list_len); + s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len; + } +#endif + + s->verify_result = X509_V_OK; + + s->method = ctx->method; + + if (!s->method->ssl_new(s)) + goto err; + + s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1; + + SSL_clear(s); + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + +#ifndef OPENSSL_NO_PSK + s->psk_client_callback = ctx->psk_client_callback; + s->psk_server_callback = ctx->psk_server_callback; +#endif + + return (s); + err: + if (s != NULL) + SSL_free(s); + SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); +} + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > sizeof(ctx->sid_ctx)) { + SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + ctx->sid_ctx_length = sid_ctx_len; + memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { + SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + ssl->sid_ctx_length = sid_ctx_len; + memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) +{ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + ctx->generate_session_id = cb; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return 1; +} + +int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) +{ + CRYPTO_w_lock(CRYPTO_LOCK_SSL); + ssl->generate_session_id = cb; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL); + return 1; +} + +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len) +{ + /* + * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how + * we can "construct" a session to give us the desired check - ie. to + * find if there's a session in the hash table that would conflict with + * any new session built out of this id/id_len and the ssl_version in use + * by this SSL. + */ + SSL_SESSION r, *p; + + if (id_len > sizeof(r.session_id)) + return 0; + + r.ssl_version = ssl->version; + r.session_id_length = id_len; + memcpy(r.session_id, id, id_len); + /* + * NB: SSLv2 always uses a fixed 16-byte session ID, so even if a + * callback is calling us to check the uniqueness of a shorter ID, it + * must be compared as a padded-out ID because that is what it will be + * converted to when the callback has finished choosing it. + */ + if ((r.ssl_version == SSL2_VERSION) && + (id_len < SSL2_SSL_SESSION_ID_LENGTH)) { + memset(r.session_id + id_len, 0, SSL2_SSL_SESSION_ID_LENGTH - id_len); + r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH; + } + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r); + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + return (p != NULL); +} + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(s->param, purpose); +} + +int SSL_set_purpose(SSL *s, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(s->param, purpose); +} + +int SSL_CTX_set_trust(SSL_CTX *s, int trust) +{ + return X509_VERIFY_PARAM_set_trust(s->param, trust); +} + +int SSL_set_trust(SSL *s, int trust) +{ + return X509_VERIFY_PARAM_set_trust(s->param, trust); +} + +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) +{ + return X509_VERIFY_PARAM_set1(ctx->param, vpm); +} + +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) +{ + return X509_VERIFY_PARAM_set1(ssl->param, vpm); +} + +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) +{ + return ctx->param; +} + +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) +{ + return ssl->param; +} + +void SSL_certs_clear(SSL *s) +{ + ssl_cert_clear_certs(s->cert); +} + +void SSL_free(SSL *s) +{ + int i; + + if (s == NULL) + return; + + i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL); +#ifdef REF_PRINT + REF_PRINT("SSL", s); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "SSL_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + if (s->param) + X509_VERIFY_PARAM_free(s->param); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + + if (s->bbio != NULL) { + /* If the buffering BIO is in place, pop it off */ + if (s->bbio == s->wbio) { + s->wbio = BIO_pop(s->wbio); + } + BIO_free(s->bbio); + s->bbio = NULL; + } + if (s->rbio != NULL) + BIO_free_all(s->rbio); + if ((s->wbio != NULL) && (s->wbio != s->rbio)) + BIO_free_all(s->wbio); + + if (s->init_buf != NULL) + BUF_MEM_free(s->init_buf); + + /* add extra stuff */ + if (s->cipher_list != NULL) + sk_SSL_CIPHER_free(s->cipher_list); + if (s->cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + + /* Make the next call work :-) */ + if (s->session != NULL) { + ssl_clear_bad_session(s); + SSL_SESSION_free(s->session); + } + + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); + + if (s->cert != NULL) + ssl_cert_free(s->cert); + /* Free up if allocated */ + +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_hostname) + OPENSSL_free(s->tlsext_hostname); + if (s->initial_ctx) + SSL_CTX_free(s->initial_ctx); +# ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist) + OPENSSL_free(s->tlsext_ecpointformatlist); + if (s->tlsext_ellipticcurvelist) + OPENSSL_free(s->tlsext_ellipticcurvelist); +# endif /* OPENSSL_NO_EC */ + if (s->tlsext_opaque_prf_input) + OPENSSL_free(s->tlsext_opaque_prf_input); + if (s->tlsext_ocsp_exts) + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); + if (s->tlsext_ocsp_ids) + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); + if (s->tlsext_ocsp_resp) + OPENSSL_free(s->tlsext_ocsp_resp); + if (s->alpn_client_proto_list) + OPENSSL_free(s->alpn_client_proto_list); +#endif + + if (s->client_CA != NULL) + sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); + + if (s->method != NULL) + s->method->ssl_free(s); + + if (s->ctx) + SSL_CTX_free(s->ctx); + +#ifndef OPENSSL_NO_KRB5 + if (s->kssl_ctx != NULL) + kssl_ctx_free(s->kssl_ctx); +#endif /* OPENSSL_NO_KRB5 */ + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + if (s->next_proto_negotiated) + OPENSSL_free(s->next_proto_negotiated); +#endif + +#ifndef OPENSSL_NO_SRTP + if (s->srtp_profiles) + sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); +#endif + + OPENSSL_free(s); +} + +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) +{ + /* + * If the output buffering BIO is still in place, remove it + */ + if (s->bbio != NULL) { + if (s->wbio == s->bbio) { + s->wbio = s->wbio->next_bio; + s->bbio->next_bio = NULL; + } + } + if ((s->rbio != NULL) && (s->rbio != rbio)) + BIO_free_all(s->rbio); + if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio)) + BIO_free_all(s->wbio); + s->rbio = rbio; + s->wbio = wbio; +} + +BIO *SSL_get_rbio(const SSL *s) +{ + return (s->rbio); +} + +BIO *SSL_get_wbio(const SSL *s) +{ + return (s->wbio); +} + +int SSL_get_fd(const SSL *s) +{ + return (SSL_get_rfd(s)); +} + +int SSL_get_rfd(const SSL *s) +{ + int ret = -1; + BIO *b, *r; + + b = SSL_get_rbio(s); + r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); + if (r != NULL) + BIO_get_fd(r, &ret); + return (ret); +} + +int SSL_get_wfd(const SSL *s) +{ + int ret = -1; + BIO *b, *r; + + b = SSL_get_wbio(s); + r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); + if (r != NULL) + BIO_get_fd(r, &ret); + return (ret); +} + +#ifndef OPENSSL_NO_SOCK +int SSL_set_fd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, bio, bio); + ret = 1; + err: + return (ret); +} + +int SSL_set_wfd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->rbio, NULL) != fd)) { + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, SSL_get_rbio(s), bio); + } else + SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s)); + ret = 1; + err: + return (ret); +} + +int SSL_set_rfd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->wbio, NULL) != fd)) { + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, bio, SSL_get_wbio(s)); + } else + SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s)); + ret = 1; + err: + return (ret); +} +#endif + +/* return length of latest Finished message we sent, copy to 'buf' */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count) +{ + size_t ret = 0; + + if (s->s3 != NULL) { + ret = s->s3->tmp.finish_md_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3->tmp.finish_md, count); + } + return ret; +} + +/* return length of latest Finished message we expected, copy to 'buf' */ +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) +{ + size_t ret = 0; + + if (s->s3 != NULL) { + ret = s->s3->tmp.peer_finish_md_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3->tmp.peer_finish_md, count); + } + return ret; +} + +int SSL_get_verify_mode(const SSL *s) +{ + return (s->verify_mode); +} + +int SSL_get_verify_depth(const SSL *s) +{ + return X509_VERIFY_PARAM_get_depth(s->param); +} + +int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *) { + return (s->verify_callback); +} + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) +{ + return (ctx->verify_mode); +} + +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) +{ + return X509_VERIFY_PARAM_get_depth(ctx->param); +} + +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, X509_STORE_CTX *) { + return (ctx->default_verify_callback); +} + +void SSL_set_verify(SSL *s, int mode, + int (*callback) (int ok, X509_STORE_CTX *ctx)) +{ + s->verify_mode = mode; + if (callback != NULL) + s->verify_callback = callback; +} + +void SSL_set_verify_depth(SSL *s, int depth) +{ + X509_VERIFY_PARAM_set_depth(s->param, depth); +} + +void SSL_set_read_ahead(SSL *s, int yes) +{ + s->read_ahead = yes; +} + +int SSL_get_read_ahead(const SSL *s) +{ + return (s->read_ahead); +} + +int SSL_pending(const SSL *s) +{ + /* + * SSL_pending cannot work properly if read-ahead is enabled + * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is + * impossible to fix since SSL_pending cannot report errors that may be + * observed while scanning the new data. (Note that SSL_pending() is + * often used as a boolean value, so we'd better not return -1.) + */ + return (s->method->ssl_pending(s)); +} + +X509 *SSL_get_peer_certificate(const SSL *s) +{ + X509 *r; + + if ((s == NULL) || (s->session == NULL)) + r = NULL; + else + r = s->session->peer; + + if (r == NULL) + return (r); + + CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509); + + return (r); +} + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) +{ + STACK_OF(X509) *r; + + if ((s == NULL) || (s->session == NULL) + || (s->session->sess_cert == NULL)) + r = NULL; + else + r = s->session->sess_cert->cert_chain; + + /* + * If we are a client, cert_chain includes the peer's own certificate; if + * we are a server, it does not. + */ + + return (r); +} + +/* + * Now in theory, since the calling process own 't' it should be safe to + * modify. We need to be able to read f without being hassled + */ +void SSL_copy_session_id(SSL *t, const SSL *f) +{ + CERT *tmp; + + /* Do we need to to SSL locking? */ + SSL_set_session(t, SSL_get_session(f)); + + /* + * what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa + */ + if (t->method != f->method) { + t->method->ssl_free(t); /* cleanup current */ + t->method = f->method; /* change method */ + t->method->ssl_new(t); /* setup new */ + } + + tmp = t->cert; + if (f->cert != NULL) { + CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + t->cert = f->cert; + } else + t->cert = NULL; + if (tmp != NULL) + ssl_cert_free(tmp); + SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length); +} + +/* Fix this so it checks all the valid key/cert options */ +int SSL_CTX_check_private_key(const SSL_CTX *ctx) +{ + if ((ctx == NULL) || + (ctx->cert == NULL) || (ctx->cert->key->x509 == NULL)) { + SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, + SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ctx->cert->key->privatekey == NULL) { + SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, + SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return (0); + } + return (X509_check_private_key + (ctx->cert->key->x509, ctx->cert->key->privatekey)); +} + +/* Fix this function so that it takes an optional type parameter */ +int SSL_check_private_key(const SSL *ssl) +{ + if (ssl == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (ssl->cert == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); + return 0; + } + if (ssl->cert->key->x509 == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ssl->cert->key->privatekey == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return (0); + } + return (X509_check_private_key(ssl->cert->key->x509, + ssl->cert->key->privatekey)); +} + +int SSL_accept(SSL *s) +{ + if (s->handshake_func == 0) + /* Not properly initialized yet */ + SSL_set_accept_state(s); + + return (s->method->ssl_accept(s)); +} + +int SSL_connect(SSL *s) +{ + if (s->handshake_func == 0) + /* Not properly initialized yet */ + SSL_set_connect_state(s); + + return (s->method->ssl_connect(s)); +} + +long SSL_get_default_timeout(const SSL *s) +{ + return (s->method->get_timeout()); +} + +int SSL_read(SSL *s, void *buf, int num) +{ + if (s->handshake_func == 0) { + SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED); + return -1; + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + return (0); + } + return (s->method->ssl_read(s, buf, num)); +} + +int SSL_peek(SSL *s, void *buf, int num) +{ + if (s->handshake_func == 0) { + SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED); + return -1; + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + return (0); + } + return (s->method->ssl_peek(s, buf, num)); +} + +int SSL_write(SSL *s, const void *buf, int num) +{ + if (s->handshake_func == 0) { + SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED); + return -1; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN); + return (-1); + } + return (s->method->ssl_write(s, buf, num)); +} + +int SSL_shutdown(SSL *s) +{ + /* + * Note that this function behaves differently from what one might + * expect. Return values are 0 for no success (yet), 1 for success; but + * calling it once is usually not enough, even if blocking I/O is used + * (see ssl3_shutdown). + */ + + if (s->handshake_func == 0) { + SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED); + return -1; + } + + if (!SSL_in_init(s)) { + return s->method->ssl_shutdown(s); + } else { + SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_SHUTDOWN_WHILE_IN_INIT); + return -1; + } +} + +int SSL_renegotiate(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate = 1; + + s->new_session = 1; + + return (s->method->ssl_renegotiate(s)); +} + +int SSL_renegotiate_abbreviated(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate = 1; + + s->new_session = 0; + + return (s->method->ssl_renegotiate(s)); +} + +int SSL_renegotiate_pending(SSL *s) +{ + /* + * becomes true when negotiation is requested; false again once a + * handshake has finished + */ + return (s->renegotiate != 0); +} + +long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + long l; + + switch (cmd) { + case SSL_CTRL_GET_READ_AHEAD: + return (s->read_ahead); + case SSL_CTRL_SET_READ_AHEAD: + l = s->read_ahead; + s->read_ahead = larg; + return (l); + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + s->msg_callback_arg = parg; + return 1; + + case SSL_CTRL_OPTIONS: + return (s->options |= larg); + case SSL_CTRL_CLEAR_OPTIONS: + return (s->options &= ~larg); + case SSL_CTRL_MODE: + return (s->mode |= larg); + case SSL_CTRL_CLEAR_MODE: + return (s->mode &= ~larg); + case SSL_CTRL_GET_MAX_CERT_LIST: + return (s->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: + l = s->max_cert_list; + s->max_cert_list = larg; + return (l); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + s->max_send_fragment = larg; + return 1; + case SSL_CTRL_GET_RI_SUPPORT: + if (s->s3) + return s->s3->send_connection_binding; + else + return 0; + case SSL_CTRL_CERT_FLAGS: + return (s->cert->cert_flags |= larg); + case SSL_CTRL_CLEAR_CERT_FLAGS: + return (s->cert->cert_flags &= ~larg); + + case SSL_CTRL_GET_RAW_CIPHERLIST: + if (parg) { + if (s->cert->ciphers_raw == NULL) + return 0; + *(unsigned char **)parg = s->cert->ciphers_raw; + return (int)s->cert->ciphers_rawlen; + } else + return ssl_put_cipher_by_char(s, NULL, NULL); + default: + return (s->method->ssl_ctrl(s, cmd, larg, parg)); + } +} + +long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) +{ + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + s->msg_callback = (void (*) + (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, + void *arg))(fp); + return 1; + + default: + return (s->method->ssl_callback_ctrl(s, cmd, fp)); + } +} + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) +{ + return ctx->sessions; +} + +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + long l; + /* For some cases with ctx == NULL perform syntax checks */ + if (ctx == NULL) { + switch (cmd) { +#ifndef OPENSSL_NO_EC + case SSL_CTRL_SET_CURVES_LIST: + return tls1_set_curves_list(NULL, NULL, parg); +#endif + case SSL_CTRL_SET_SIGALGS_LIST: + case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: + return tls1_set_sigalgs_list(NULL, parg, 0); + default: + return 0; + } + } + + switch (cmd) { + case SSL_CTRL_GET_READ_AHEAD: + return (ctx->read_ahead); + case SSL_CTRL_SET_READ_AHEAD: + l = ctx->read_ahead; + ctx->read_ahead = larg; + return (l); + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + ctx->msg_callback_arg = parg; + return 1; + + case SSL_CTRL_GET_MAX_CERT_LIST: + return (ctx->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: + l = ctx->max_cert_list; + ctx->max_cert_list = larg; + return (l); + + case SSL_CTRL_SET_SESS_CACHE_SIZE: + l = ctx->session_cache_size; + ctx->session_cache_size = larg; + return (l); + case SSL_CTRL_GET_SESS_CACHE_SIZE: + return (ctx->session_cache_size); + case SSL_CTRL_SET_SESS_CACHE_MODE: + l = ctx->session_cache_mode; + ctx->session_cache_mode = larg; + return (l); + case SSL_CTRL_GET_SESS_CACHE_MODE: + return (ctx->session_cache_mode); + + case SSL_CTRL_SESS_NUMBER: + return (lh_SSL_SESSION_num_items(ctx->sessions)); + case SSL_CTRL_SESS_CONNECT: + return (ctx->stats.sess_connect); + case SSL_CTRL_SESS_CONNECT_GOOD: + return (ctx->stats.sess_connect_good); + case SSL_CTRL_SESS_CONNECT_RENEGOTIATE: + return (ctx->stats.sess_connect_renegotiate); + case SSL_CTRL_SESS_ACCEPT: + return (ctx->stats.sess_accept); + case SSL_CTRL_SESS_ACCEPT_GOOD: + return (ctx->stats.sess_accept_good); + case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: + return (ctx->stats.sess_accept_renegotiate); + case SSL_CTRL_SESS_HIT: + return (ctx->stats.sess_hit); + case SSL_CTRL_SESS_CB_HIT: + return (ctx->stats.sess_cb_hit); + case SSL_CTRL_SESS_MISSES: + return (ctx->stats.sess_miss); + case SSL_CTRL_SESS_TIMEOUTS: + return (ctx->stats.sess_timeout); + case SSL_CTRL_SESS_CACHE_FULL: + return (ctx->stats.sess_cache_full); + case SSL_CTRL_OPTIONS: + return (ctx->options |= larg); + case SSL_CTRL_CLEAR_OPTIONS: + return (ctx->options &= ~larg); + case SSL_CTRL_MODE: + return (ctx->mode |= larg); + case SSL_CTRL_CLEAR_MODE: + return (ctx->mode &= ~larg); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + ctx->max_send_fragment = larg; + return 1; + case SSL_CTRL_CERT_FLAGS: + return (ctx->cert->cert_flags |= larg); + case SSL_CTRL_CLEAR_CERT_FLAGS: + return (ctx->cert->cert_flags &= ~larg); + default: + return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg)); + } +} + +long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) +{ + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + ctx->msg_callback = (void (*) + (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, + void *arg))(fp); + return 1; + + default: + return (ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp)); + } +} + +int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b) +{ + long l; + + l = a->id - b->id; + if (l == 0L) + return (0); + else + return ((l > 0) ? 1 : -1); +} + +int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, + const SSL_CIPHER *const *bp) +{ + long l; + + l = (*ap)->id - (*bp)->id; + if (l == 0L) + return (0); + else + return ((l > 0) ? 1 : -1); +} + +/** return a STACK of the ciphers available for the SSL and in order of + * preference */ +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) +{ + if (s != NULL) { + if (s->cipher_list != NULL) { + return (s->cipher_list); + } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { + return (s->ctx->cipher_list); + } + } + return (NULL); +} + +/** return a STACK of the ciphers available for the SSL and in order of + * algorithm id */ +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) +{ + if (s != NULL) { + if (s->cipher_list_by_id != NULL) { + return (s->cipher_list_by_id); + } else if ((s->ctx != NULL) && (s->ctx->cipher_list_by_id != NULL)) { + return (s->ctx->cipher_list_by_id); + } + } + return (NULL); +} + +/** The old interface to get the same thing as SSL_get_ciphers() */ +const char *SSL_get_cipher_list(const SSL *s, int n) +{ + SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + + if (s == NULL) + return (NULL); + sk = SSL_get_ciphers(s); + if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n)) + return (NULL); + c = sk_SSL_CIPHER_value(sk, n); + if (c == NULL) + return (NULL); + return (c->name); +} + +/** specify the ciphers to be used by default by the SSL_CTX */ +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) +{ + STACK_OF(SSL_CIPHER) *sk; + + sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list, + &ctx->cipher_list_by_id, str, ctx->cert); + /* + * ssl_create_cipher_list may return an empty stack if it was unable to + * find a cipher matching the given rule string (for example if the rule + * string specifies a cipher which has been disabled). This is not an + * error as far as ssl_create_cipher_list is concerned, and hence + * ctx->cipher_list and ctx->cipher_list_by_id has been updated. + */ + if (sk == NULL) + return 0; + else if (sk_SSL_CIPHER_num(sk) == 0) { + SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); + return 0; + } + return 1; +} + +/** specify the ciphers to be used by the SSL */ +int SSL_set_cipher_list(SSL *s, const char *str) +{ + STACK_OF(SSL_CIPHER) *sk; + + sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list, + &s->cipher_list_by_id, str, s->cert); + /* see comment in SSL_CTX_set_cipher_list */ + if (sk == NULL) + return 0; + else if (sk_SSL_CIPHER_num(sk) == 0) { + SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); + return 0; + } + return 1; +} + +/* works well for SSLv2, not so good for SSLv3 */ +char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size) +{ + char *p; + STACK_OF(SSL_CIPHER) *clntsk, *srvrsk; + SSL_CIPHER *c; + int i; + + if (!s->server + || s->session == NULL + || s->session->ciphers == NULL + || size < 2) + return NULL; + + p = buf; + clntsk = s->session->ciphers; + srvrsk = SSL_get_ciphers(s); + if (clntsk == NULL || srvrsk == NULL) + return NULL; + + if (sk_SSL_CIPHER_num(clntsk) == 0 || sk_SSL_CIPHER_num(srvrsk) == 0) + return NULL; + + for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) { + int n; + + c = sk_SSL_CIPHER_value(clntsk, i); + if (sk_SSL_CIPHER_find(srvrsk, c) < 0) + continue; + + n = strlen(c->name); + if (n + 1 > size) { + if (p != buf) + --p; + *p = '\0'; + return buf; + } + strcpy(p, c->name); + p += n; + *(p++) = ':'; + size -= n + 1; + } + p[-1] = '\0'; + return (buf); +} + +int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, + unsigned char *p, + int (*put_cb) (const SSL_CIPHER *, + unsigned char *)) +{ + int i, j = 0; + SSL_CIPHER *c; + CERT *ct = s->cert; + unsigned char *q; + int empty_reneg_info_scsv = !s->renegotiate; + /* Set disabled masks for this session */ + ssl_set_client_disabled(s); + + if (sk == NULL) + return (0); + q = p; + if (put_cb == NULL) + put_cb = s->method->put_cipher_by_char; + + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + /* Skip disabled ciphers */ + if (c->algorithm_ssl & ct->mask_ssl || + c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) + continue; +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + if (c->id == SSL3_CK_SCSV) { + if (!empty_reneg_info_scsv) + continue; + else + empty_reneg_info_scsv = 0; + } +#endif + j = put_cb(c, p); + p += j; + } + /* + * If p == q, no ciphers; caller indicates an error. Otherwise, add + * applicable SCSVs. + */ + if (p != q) { + if (empty_reneg_info_scsv) { + static SSL_CIPHER scsv = { + 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + j = put_cb(&scsv, p); + p += j; +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); +#endif + } + if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { + static SSL_CIPHER scsv = { + 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + j = put_cb(&scsv, p); + p += j; + } + } + + return (p - q); +} + +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, + int num, + STACK_OF(SSL_CIPHER) **skp) +{ + const SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + int i, n; + + if (s->s3) + s->s3->send_connection_binding = 0; + + n = ssl_put_cipher_by_char(s, NULL, NULL); + if (n == 0 || (num % n) != 0) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + return (NULL); + } + if ((skp == NULL) || (*skp == NULL)) { + sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ + if(sk == NULL) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return NULL; + } + } else { + sk = *skp; + sk_SSL_CIPHER_zero(sk); + } + + if (s->cert->ciphers_raw) + OPENSSL_free(s->cert->ciphers_raw); + s->cert->ciphers_raw = BUF_memdup(p, num); + if (s->cert->ciphers_raw == NULL) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + s->cert->ciphers_rawlen = (size_t)num; + + for (i = 0; i < num; i += n) { + /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ + if (s->s3 && (n != 3 || !p[0]) && + (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && + (p[n - 1] == (SSL3_CK_SCSV & 0xff))) { + /* SCSV fatal if renegotiating */ + if (s->renegotiate) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + s->s3->send_connection_binding = 1; + p += n; +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "SCSV received by server\n"); +#endif + continue; + } + + /* Check for TLS_FALLBACK_SCSV */ + if ((n != 3 || !p[0]) && + (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && + (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { + /* + * The SCSV indicates that the client previously tried a higher + * version. Fail if the current version is an unexpected + * downgrade. + */ + if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_INAPPROPRIATE_FALLBACK); + if (s->s3) + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_INAPPROPRIATE_FALLBACK); + goto err; + } + p += n; + continue; + } + + c = ssl_get_cipher_by_char(s, p); + p += n; + if (c != NULL) { + if (!sk_SSL_CIPHER_push(sk, c)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + } + } + + if (skp != NULL) + *skp = sk; + return (sk); + err: + if ((skp == NULL) || (*skp == NULL)) + sk_SSL_CIPHER_free(sk); + return (NULL); +} + +#ifndef OPENSSL_NO_TLSEXT +/** return a servername extension value if provided in Client Hello, or NULL. + * So far, only host_name types are defined (RFC 3546). + */ + +const char *SSL_get_servername(const SSL *s, const int type) +{ + if (type != TLSEXT_NAMETYPE_host_name) + return NULL; + + return s->session && !s->tlsext_hostname ? + s->session->tlsext_hostname : s->tlsext_hostname; +} + +int SSL_get_servername_type(const SSL *s) +{ + if (s->session + && (!s->tlsext_hostname ? s->session-> + tlsext_hostname : s->tlsext_hostname)) + return TLSEXT_NAMETYPE_host_name; + return -1; +} + +/* + * SSL_select_next_proto implements the standard protocol selection. It is + * expected that this function is called from the callback set by + * SSL_CTX_set_next_proto_select_cb. The protocol data is assumed to be a + * vector of 8-bit, length prefixed byte strings. The length byte itself is + * not included in the length. A byte string of length 0 is invalid. No byte + * string may be truncated. The current, but experimental algorithm for + * selecting the protocol is: 1) If the server doesn't support NPN then this + * is indicated to the callback. In this case, the client application has to + * abort the connection or have a default application level protocol. 2) If + * the server supports NPN, but advertises an empty list then the client + * selects the first protcol in its list, but indicates via the API that this + * fallback case was enacted. 3) Otherwise, the client finds the first + * protocol in the server's list that it supports and selects this protocol. + * This is because it's assumed that the server has better information about + * which protocol a client should use. 4) If the client doesn't support any + * of the server's advertised protocols, then this is treated the same as + * case 2. It returns either OPENSSL_NPN_NEGOTIATED if a common protocol was + * found, or OPENSSL_NPN_NO_OVERLAP if the fallback case was reached. + */ +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *server, + unsigned int server_len, + const unsigned char *client, + unsigned int client_len) +{ + unsigned int i, j; + const unsigned char *result; + int status = OPENSSL_NPN_UNSUPPORTED; + + /* + * For each protocol in server preference order, see if we support it. + */ + for (i = 0; i < server_len;) { + for (j = 0; j < client_len;) { + if (server[i] == client[j] && + memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) { + /* We found a match */ + result = &server[i]; + status = OPENSSL_NPN_NEGOTIATED; + goto found; + } + j += client[j]; + j++; + } + i += server[i]; + i++; + } + + /* There's no overlap between our protocols and the server's list. */ + result = client; + status = OPENSSL_NPN_NO_OVERLAP; + + found: + *out = (unsigned char *)result + 1; + *outlen = result[0]; + return status; +} + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* + * SSL_get0_next_proto_negotiated sets *data and *len to point to the + * client's requested protocol for this connection and returns 0. If the + * client didn't request any protocol, then *data is set to NULL. Note that + * the client can request any protocol it chooses. The value returned from + * this function need not be a member of the list of supported protocols + * provided by the callback. + */ +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len) +{ + *data = s->next_proto_negotiated; + if (!*data) { + *len = 0; + } else { + *len = s->next_proto_negotiated_len; + } +} + +/* + * SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when + * a TLS server needs a list of supported protocols for Next Protocol + * Negotiation. The returned list must be in wire format. The list is + * returned by setting |out| to point to it and |outlen| to its length. This + * memory will not be modified, but one should assume that the SSL* keeps a + * reference to it. The callback should return SSL_TLSEXT_ERR_OK if it + * wishes to advertise. Otherwise, no such extension will be included in the + * ServerHello. + */ +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + const unsigned char + **out, + unsigned int *outlen, + void *arg), void *arg) +{ + ctx->next_protos_advertised_cb = cb; + ctx->next_protos_advertised_cb_arg = arg; +} + +/* + * SSL_CTX_set_next_proto_select_cb sets a callback that is called when a + * client needs to select a protocol from the server's provided list. |out| + * must be set to point to the selected protocol (which may be within |in|). + * The length of the protocol name must be written into |outlen|. The + * server's advertised protocols are provided in |in| and |inlen|. The + * callback can assume that |in| is syntactically valid. The client must + * select a protocol. It is fatal to the connection if this callback returns + * a value other than SSL_TLSEXT_ERR_OK. + */ +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *s, unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg) +{ + ctx->next_proto_select_cb = cb; + ctx->next_proto_select_cb_arg = arg; +} +# endif + +/* + * SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|. + * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit + * length-prefixed strings). Returns 0 on success. + */ +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, + unsigned protos_len) +{ + if (ctx->alpn_client_proto_list) + OPENSSL_free(ctx->alpn_client_proto_list); + + ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len); + if (!ctx->alpn_client_proto_list) + return 1; + memcpy(ctx->alpn_client_proto_list, protos, protos_len); + ctx->alpn_client_proto_list_len = protos_len; + + return 0; +} + +/* + * SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|. + * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit + * length-prefixed strings). Returns 0 on success. + */ +int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, + unsigned protos_len) +{ + if (ssl->alpn_client_proto_list) + OPENSSL_free(ssl->alpn_client_proto_list); + + ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len); + if (!ssl->alpn_client_proto_list) + return 1; + memcpy(ssl->alpn_client_proto_list, protos, protos_len); + ssl->alpn_client_proto_list_len = protos_len; + + return 0; +} + +/* + * SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is + * called during ClientHello processing in order to select an ALPN protocol + * from the client's list of offered protocols. + */ +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + const unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg) +{ + ctx->alpn_select_cb = cb; + ctx->alpn_select_cb_arg = arg; +} + +/* + * SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from + * |ssl|. On return it sets |*data| to point to |*len| bytes of protocol name + * (not including the leading length-prefix byte). If the server didn't + * respond with a negotiated protocol then |*len| will be zero. + */ +void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, + unsigned *len) +{ + *data = NULL; + if (ssl->s3) + *data = ssl->s3->alpn_selected; + if (*data == NULL) + *len = 0; + else + *len = ssl->s3->alpn_selected_len; +} + +#endif /* !OPENSSL_NO_TLSEXT */ + +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, size_t contextlen, + int use_context) +{ + if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) + return -1; + + return s->method->ssl3_enc->export_keying_material(s, out, olen, label, + llen, context, + contextlen, use_context); +} + +static unsigned long ssl_session_hash(const SSL_SESSION *a) +{ + const unsigned char *session_id = a->session_id; + unsigned long l; + unsigned char tmp_storage[4]; + + if (a->session_id_length < sizeof(tmp_storage)) { + memset(tmp_storage, 0, sizeof(tmp_storage)); + memcpy(tmp_storage, a->session_id, a->session_id_length); + session_id = tmp_storage; + } + + l = (unsigned long) + ((unsigned long)session_id[0]) | + ((unsigned long)session_id[1] << 8L) | + ((unsigned long)session_id[2] << 16L) | + ((unsigned long)session_id[3] << 24L); + return (l); +} + +/* + * NB: If this function (or indeed the hash function which uses a sort of + * coarser function than this one) is changed, ensure + * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on + * being able to construct an SSL_SESSION that will collide with any existing + * session with a matching session ID. + */ +static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) +{ + if (a->ssl_version != b->ssl_version) + return (1); + if (a->session_id_length != b->session_id_length) + return (1); + return (memcmp(a->session_id, b->session_id, a->session_id_length)); +} + +/* + * These wrapper functions should remain rather than redeclaring + * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each + * variable. The reason is that the functions aren't static, they're exposed + * via ssl.h. + */ +static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION) +static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION) + +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) +{ + SSL_CTX *ret = NULL; + + if (meth == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_NULL_SSL_METHOD_PASSED); + return (NULL); + } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (meth->version < TLS1_VERSION)) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return NULL; + } +#endif + + if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); + goto err; + } + ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX)); + if (ret == NULL) + goto err; + + memset(ret, 0, sizeof(SSL_CTX)); + + ret->method = meth; + + ret->cert_store = NULL; + ret->session_cache_mode = SSL_SESS_CACHE_SERVER; + ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; + ret->session_cache_head = NULL; + ret->session_cache_tail = NULL; + + /* We take the system default */ + ret->session_timeout = meth->get_timeout(); + + ret->new_session_cb = 0; + ret->remove_session_cb = 0; + ret->get_session_cb = 0; + ret->generate_session_id = 0; + + memset((char *)&ret->stats, 0, sizeof(ret->stats)); + + ret->references = 1; + ret->quiet_shutdown = 0; + +/* ret->cipher=NULL;*/ +/*- + ret->s2->challenge=NULL; + ret->master_key=NULL; + ret->key_arg=NULL; + ret->s2->conn_id=NULL; */ + + ret->info_callback = NULL; + + ret->app_verify_callback = 0; + ret->app_verify_arg = NULL; + + ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; + ret->read_ahead = 0; + ret->msg_callback = 0; + ret->msg_callback_arg = NULL; + ret->verify_mode = SSL_VERIFY_NONE; +#if 0 + ret->verify_depth = -1; /* Don't impose a limit (but x509_lu.c does) */ +#endif + ret->sid_ctx_length = 0; + ret->default_verify_callback = NULL; + if ((ret->cert = ssl_cert_new()) == NULL) + goto err; + + ret->default_passwd_callback = 0; + ret->default_passwd_callback_userdata = NULL; + ret->client_cert_cb = 0; + ret->app_gen_cookie_cb = 0; + ret->app_verify_cookie_cb = 0; + + ret->sessions = lh_SSL_SESSION_new(); + if (ret->sessions == NULL) + goto err; + ret->cert_store = X509_STORE_new(); + if (ret->cert_store == NULL) + goto err; + + ssl_create_cipher_list(ret->method, + &ret->cipher_list, &ret->cipher_list_by_id, + meth->version == + SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST, + ret->cert); + if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS); + goto err2; + } + + ret->param = X509_VERIFY_PARAM_new(); + if (!ret->param) + goto err; + + if ((ret->rsa_md5 = EVP_get_digestbyname("ssl2-md5")) == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES); + goto err2; + } + if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); + goto err2; + } + if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); + goto err2; + } + + if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL) + goto err; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); + + ret->extra_certs = NULL; + /* No compression for DTLS */ + if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)) + ret->comp_methods = SSL_COMP_get_compression_methods(); + + ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + +#ifndef OPENSSL_NO_TLSEXT + ret->tlsext_servername_callback = 0; + ret->tlsext_servername_arg = NULL; + /* Setup RFC4507 ticket keys */ + if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0) + || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) + || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) + ret->options |= SSL_OP_NO_TICKET; + + ret->tlsext_status_cb = 0; + ret->tlsext_status_arg = NULL; + +# ifndef OPENSSL_NO_NEXTPROTONEG + ret->next_protos_advertised_cb = 0; + ret->next_proto_select_cb = 0; +# endif +#endif +#ifndef OPENSSL_NO_PSK + ret->psk_identity_hint = NULL; + ret->psk_client_callback = NULL; + ret->psk_server_callback = NULL; +#endif +#ifndef OPENSSL_NO_SRP + SSL_CTX_SRP_CTX_init(ret); +#endif +#ifndef OPENSSL_NO_BUF_FREELISTS + ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; + ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); + if (!ret->rbuf_freelist) + goto err; + ret->rbuf_freelist->chunklen = 0; + ret->rbuf_freelist->len = 0; + ret->rbuf_freelist->head = NULL; + ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); + if (!ret->wbuf_freelist) + goto err; + ret->wbuf_freelist->chunklen = 0; + ret->wbuf_freelist->len = 0; + ret->wbuf_freelist->head = NULL; +#endif +#ifndef OPENSSL_NO_ENGINE + ret->client_cert_engine = NULL; +# ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO +# define eng_strx(x) #x +# define eng_str(x) eng_strx(x) + /* Use specific client engine automatically... ignore errors */ + { + ENGINE *eng; + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + if (!eng) { + ERR_clear_error(); + ENGINE_load_builtin_engines(); + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + } + if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) + ERR_clear_error(); + } +# endif +#endif + /* + * Default is to connect to non-RI servers. When RI is more widely + * deployed might change this. + */ + ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; + + /* + * Disable SSLv2 by default, callers that want to enable SSLv2 will have to + * explicitly clear this option via either of SSL_CTX_clear_options() or + * SSL_clear_options(). + */ + ret->options |= SSL_OP_NO_SSLv2; + + return (ret); + err: + SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); + err2: + if (ret != NULL) + SSL_CTX_free(ret); + return (NULL); +} + +#if 0 +static void SSL_COMP_free(SSL_COMP *comp) +{ + OPENSSL_free(comp); +} +#endif + +#ifndef OPENSSL_NO_BUF_FREELISTS +static void ssl_buf_freelist_free(SSL3_BUF_FREELIST *list) +{ + SSL3_BUF_FREELIST_ENTRY *ent, *next; + for (ent = list->head; ent; ent = next) { + next = ent->next; + OPENSSL_free(ent); + } + OPENSSL_free(list); +} +#endif + +void SSL_CTX_free(SSL_CTX *a) +{ + int i; + + if (a == NULL) + return; + + i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX); +#ifdef REF_PRINT + REF_PRINT("SSL_CTX", a); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "SSL_CTX_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + if (a->param) + X509_VERIFY_PARAM_free(a->param); + + /* + * Free internal session cache. However: the remove_cb() may reference + * the ex_data of SSL_CTX, thus the ex_data store can only be removed + * after the sessions were flushed. + * As the ex_data handling routines might also touch the session cache, + * the most secure solution seems to be: empty (flush) the cache, then + * free ex_data, then finally free the cache. + * (See ticket [openssl.org #212].) + */ + if (a->sessions != NULL) + SSL_CTX_flush_sessions(a, 0); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); + + if (a->sessions != NULL) + lh_SSL_SESSION_free(a->sessions); + + if (a->cert_store != NULL) + X509_STORE_free(a->cert_store); + if (a->cipher_list != NULL) + sk_SSL_CIPHER_free(a->cipher_list); + if (a->cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(a->cipher_list_by_id); + if (a->cert != NULL) + ssl_cert_free(a->cert); + if (a->client_CA != NULL) + sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free); + if (a->extra_certs != NULL) + sk_X509_pop_free(a->extra_certs, X509_free); +#if 0 /* This should never be done, since it + * removes a global database */ + if (a->comp_methods != NULL) + sk_SSL_COMP_pop_free(a->comp_methods, SSL_COMP_free); +#else + a->comp_methods = NULL; +#endif + +#ifndef OPENSSL_NO_SRTP + if (a->srtp_profiles) + sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); +#endif + +#ifndef OPENSSL_NO_PSK + if (a->psk_identity_hint) + OPENSSL_free(a->psk_identity_hint); +#endif +#ifndef OPENSSL_NO_SRP + SSL_CTX_SRP_CTX_free(a); +#endif +#ifndef OPENSSL_NO_ENGINE + if (a->client_cert_engine) + ENGINE_finish(a->client_cert_engine); +#endif + +#ifndef OPENSSL_NO_BUF_FREELISTS + if (a->wbuf_freelist) + ssl_buf_freelist_free(a->wbuf_freelist); + if (a->rbuf_freelist) + ssl_buf_freelist_free(a->rbuf_freelist); +#endif +#ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC + if (a->tlsext_ecpointformatlist) + OPENSSL_free(a->tlsext_ecpointformatlist); + if (a->tlsext_ellipticcurvelist) + OPENSSL_free(a->tlsext_ellipticcurvelist); +# endif /* OPENSSL_NO_EC */ + if (a->alpn_client_proto_list != NULL) + OPENSSL_free(a->alpn_client_proto_list); +#endif + + OPENSSL_free(a); +} + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) +{ + ctx->default_passwd_callback = cb; +} + +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) +{ + ctx->default_passwd_callback_userdata = u; +} + +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg) +{ + ctx->app_verify_callback = cb; + ctx->app_verify_arg = arg; +} + +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*cb) (int, X509_STORE_CTX *)) +{ + ctx->verify_mode = mode; + ctx->default_verify_callback = cb; +} + +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), + void *arg) +{ + ssl_cert_set_cert_cb(c->cert, cb, arg); +} + +void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg) +{ + ssl_cert_set_cert_cb(s->cert, cb, arg); +} + +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) +{ + CERT_PKEY *cpk; + int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign; + int rsa_enc_export, dh_rsa_export, dh_dsa_export; + int rsa_tmp_export, dh_tmp_export, kl; + unsigned long mask_k, mask_a, emask_k, emask_a; +#ifndef OPENSSL_NO_ECDSA + int have_ecc_cert, ecdsa_ok; +#endif +#ifndef OPENSSL_NO_ECDH + int have_ecdh_tmp, ecdh_ok, ecc_pkey_size; +#endif +#ifndef OPENSSL_NO_EC + X509 *x = NULL; + EVP_PKEY *ecc_pkey = NULL; + int signature_nid = 0, pk_nid = 0, md_nid = 0; +#endif + if (c == NULL) + return; + + kl = SSL_C_EXPORT_PKEYLENGTH(cipher); + +#ifndef OPENSSL_NO_RSA + rsa_tmp = (c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL); + rsa_tmp_export = (c->rsa_tmp_cb != NULL || + (rsa_tmp && RSA_size(c->rsa_tmp) * 8 <= kl)); +#else + rsa_tmp = rsa_tmp_export = 0; +#endif +#ifndef OPENSSL_NO_DH + dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL); + dh_tmp_export = (c->dh_tmp_cb != NULL || + (dh_tmp && DH_size(c->dh_tmp) * 8 <= kl)); +#else + dh_tmp = dh_tmp_export = 0; +#endif + +#ifndef OPENSSL_NO_ECDH + have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); +#endif + cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]); + rsa_enc = cpk->valid_flags & CERT_PKEY_VALID; + rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); + cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]); + rsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; + cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]); + dsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; + cpk = &(c->pkeys[SSL_PKEY_DH_RSA]); + dh_rsa = cpk->valid_flags & CERT_PKEY_VALID; + dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); + cpk = &(c->pkeys[SSL_PKEY_DH_DSA]); +/* FIX THIS EAY EAY EAY */ + dh_dsa = cpk->valid_flags & CERT_PKEY_VALID; + dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); + cpk = &(c->pkeys[SSL_PKEY_ECC]); +#ifndef OPENSSL_NO_EC + have_ecc_cert = cpk->valid_flags & CERT_PKEY_VALID; +#endif + mask_k = 0; + mask_a = 0; + emask_k = 0; + emask_a = 0; + +#ifdef CIPHER_DEBUG + fprintf(stderr, + "rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n", + rsa_tmp, rsa_tmp_export, dh_tmp, have_ecdh_tmp, rsa_enc, + rsa_enc_export, rsa_sign, dsa_sign, dh_rsa, dh_dsa); +#endif + + cpk = &(c->pkeys[SSL_PKEY_GOST01]); + if (cpk->x509 != NULL && cpk->privatekey != NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST01; + } + cpk = &(c->pkeys[SSL_PKEY_GOST94]); + if (cpk->x509 != NULL && cpk->privatekey != NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST94; + } + + if (rsa_enc || (rsa_tmp && rsa_sign)) + mask_k |= SSL_kRSA; + if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc))) + emask_k |= SSL_kRSA; + +#if 0 + /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */ + if ((dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign)) + mask_k |= SSL_kEDH; + if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) && + (rsa_enc || rsa_sign || dsa_sign)) + emask_k |= SSL_kEDH; +#endif + + if (dh_tmp_export) + emask_k |= SSL_kEDH; + + if (dh_tmp) + mask_k |= SSL_kEDH; + + if (dh_rsa) + mask_k |= SSL_kDHr; + if (dh_rsa_export) + emask_k |= SSL_kDHr; + + if (dh_dsa) + mask_k |= SSL_kDHd; + if (dh_dsa_export) + emask_k |= SSL_kDHd; + + if (mask_k & (SSL_kDHr | SSL_kDHd)) + mask_a |= SSL_aDH; + + if (rsa_enc || rsa_sign) { + mask_a |= SSL_aRSA; + emask_a |= SSL_aRSA; + } + + if (dsa_sign) { + mask_a |= SSL_aDSS; + emask_a |= SSL_aDSS; + } + + mask_a |= SSL_aNULL; + emask_a |= SSL_aNULL; + +#ifndef OPENSSL_NO_KRB5 + mask_k |= SSL_kKRB5; + mask_a |= SSL_aKRB5; + emask_k |= SSL_kKRB5; + emask_a |= SSL_aKRB5; +#endif + + /* + * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites + * depending on the key usage extension. + */ +#ifndef OPENSSL_NO_EC + if (have_ecc_cert) { + cpk = &c->pkeys[SSL_PKEY_ECC]; + x = cpk->x509; + /* This call populates extension flags (ex_flags) */ + X509_check_purpose(x, -1, 0); +# ifndef OPENSSL_NO_ECDH + ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? + (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; +# endif + ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? + (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; + if (!(cpk->valid_flags & CERT_PKEY_SIGN)) + ecdsa_ok = 0; + ecc_pkey = X509_get_pubkey(x); +# ifndef OPENSSL_NO_ECDH + ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; +# endif + EVP_PKEY_free(ecc_pkey); + if ((x->sig_alg) && (x->sig_alg->algorithm)) { + signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); + OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); + } +# ifndef OPENSSL_NO_ECDH + if (ecdh_ok) { + + if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { + mask_k |= SSL_kECDHr; + mask_a |= SSL_aECDH; + if (ecc_pkey_size <= 163) { + emask_k |= SSL_kECDHr; + emask_a |= SSL_aECDH; + } + } + + if (pk_nid == NID_X9_62_id_ecPublicKey) { + mask_k |= SSL_kECDHe; + mask_a |= SSL_aECDH; + if (ecc_pkey_size <= 163) { + emask_k |= SSL_kECDHe; + emask_a |= SSL_aECDH; + } + } + } +# endif +# ifndef OPENSSL_NO_ECDSA + if (ecdsa_ok) { + mask_a |= SSL_aECDSA; + emask_a |= SSL_aECDSA; + } +# endif + } +#endif + +#ifndef OPENSSL_NO_ECDH + if (have_ecdh_tmp) { + mask_k |= SSL_kEECDH; + emask_k |= SSL_kEECDH; + } +#endif + +#ifndef OPENSSL_NO_PSK + mask_k |= SSL_kPSK; + mask_a |= SSL_aPSK; + emask_k |= SSL_kPSK; + emask_a |= SSL_aPSK; +#endif + + c->mask_k = mask_k; + c->mask_a = mask_a; + c->export_mask_k = emask_k; + c->export_mask_a = emask_a; + c->valid = 1; +} + +/* This handy macro borrowed from crypto/x509v3/v3_purp.c */ +#define ku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) + +#ifndef OPENSSL_NO_ECDH + +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) +{ + unsigned long alg_k, alg_a; + EVP_PKEY *pkey = NULL; + int keysize = 0; + int signature_nid = 0, md_nid = 0, pk_nid = 0; + const SSL_CIPHER *cs = s->s3->tmp.new_cipher; + + alg_k = cs->algorithm_mkey; + alg_a = cs->algorithm_auth; + + if (SSL_C_IS_EXPORT(cs)) { + /* ECDH key length in export ciphers must be <= 163 bits */ + pkey = X509_get_pubkey(x); + if (pkey == NULL) + return 0; + keysize = EVP_PKEY_bits(pkey); + EVP_PKEY_free(pkey); + if (keysize > 163) + return 0; + } + + /* This call populates the ex_flags field correctly */ + X509_check_purpose(x, -1, 0); + if ((x->sig_alg) && (x->sig_alg->algorithm)) { + signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); + OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); + } + if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { + /* key usage, if present, must allow key agreement */ + if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); + return 0; + } + if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION) { + /* signature alg must be ECDSA */ + if (pk_nid != NID_X9_62_id_ecPublicKey) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE); + return 0; + } + } + if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION) { + /* signature alg must be RSA */ + + if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE); + return 0; + } + } + } + if (alg_a & SSL_aECDSA) { + /* key usage, if present, must allow signing */ + if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_NOT_FOR_SIGNING); + return 0; + } + } + + return 1; /* all checks are ok */ +} + +#endif + +static int ssl_get_server_cert_index(const SSL *s) +{ + int idx; + idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); + if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) + idx = SSL_PKEY_RSA_SIGN; + if (idx == -1) + SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR); + return idx; +} + +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) +{ + CERT *c; + int i; + + c = s->cert; + if (!s->s3 || !s->s3->tmp.new_cipher) + return NULL; + ssl_set_cert_masks(c, s->s3->tmp.new_cipher); + +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + /* + * Broken protocol test: return last used certificate: which may mismatch + * the one expected. + */ + if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) + return c->key; +#endif + + i = ssl_get_server_cert_index(s); + + /* This may or may not be an error. */ + if (i < 0) + return NULL; + + /* May be NULL. */ + return &c->pkeys[i]; +} + +EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, + const EVP_MD **pmd) +{ + unsigned long alg_a; + CERT *c; + int idx = -1; + + alg_a = cipher->algorithm_auth; + c = s->cert; + +#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + /* + * Broken protocol test: use last key: which may mismatch the one + * expected. + */ + if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) + idx = c->key - c->pkeys; + else +#endif + + if ((alg_a & SSL_aDSS) && + (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) + idx = SSL_PKEY_DSA_SIGN; + else if (alg_a & SSL_aRSA) { + if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) + idx = SSL_PKEY_RSA_SIGN; + else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) + idx = SSL_PKEY_RSA_ENC; + } else if ((alg_a & SSL_aECDSA) && + (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) + idx = SSL_PKEY_ECC; + if (idx == -1) { + SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR); + return (NULL); + } + if (pmd) + *pmd = c->pkeys[idx].digest; + return c->pkeys[idx].privatekey; +} + +#ifndef OPENSSL_NO_TLSEXT +int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, + size_t *serverinfo_length) +{ + CERT *c = NULL; + int i = 0; + *serverinfo_length = 0; + + c = s->cert; + i = ssl_get_server_cert_index(s); + + if (i == -1) + return 0; + if (c->pkeys[i].serverinfo == NULL) + return 0; + + *serverinfo = c->pkeys[i].serverinfo; + *serverinfo_length = c->pkeys[i].serverinfo_length; + return 1; +} +#endif + +void ssl_update_cache(SSL *s, int mode) +{ + int i; + + /* + * If the session_id_length is 0, we are not supposed to cache it, and it + * would be rather hard to do anyway :-) + */ + if (s->session->session_id_length == 0) + return; + + i = s->session_ctx->session_cache_mode; + if ((i & mode) && (!s->hit) + && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) + || SSL_CTX_add_session(s->session_ctx, s->session)) + && (s->session_ctx->new_session_cb != NULL)) { + CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION); + if (!s->session_ctx->new_session_cb(s, s->session)) + SSL_SESSION_free(s->session); + } + + /* auto flush every 255 connections */ + if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) { + if ((((mode & SSL_SESS_CACHE_CLIENT) + ? s->session_ctx->stats.sess_connect_good + : s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) { + SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL)); + } + } +} + +const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) +{ + return ctx->method; +} + +const SSL_METHOD *SSL_get_ssl_method(SSL *s) +{ + return (s->method); +} + +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth) +{ + int conn = -1; + int ret = 1; + + if (s->method != meth) { + if (s->handshake_func != NULL) + conn = (s->handshake_func == s->method->ssl_connect); + + if (s->method->version == meth->version) + s->method = meth; + else { + s->method->ssl_free(s); + s->method = meth; + ret = s->method->ssl_new(s); + } + + if (conn == 1) + s->handshake_func = meth->ssl_connect; + else if (conn == 0) + s->handshake_func = meth->ssl_accept; + } + return (ret); +} + +int SSL_get_error(const SSL *s, int i) +{ + int reason; + unsigned long l; + BIO *bio; + + if (i > 0) + return (SSL_ERROR_NONE); + + /* + * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc, + * where we do encode the error + */ + if ((l = ERR_peek_error()) != 0) { + if (ERR_GET_LIB(l) == ERR_LIB_SYS) + return (SSL_ERROR_SYSCALL); + else + return (SSL_ERROR_SSL); + } + + if ((i < 0) && SSL_want_read(s)) { + bio = SSL_get_rbio(s); + if (BIO_should_read(bio)) + return (SSL_ERROR_WANT_READ); + else if (BIO_should_write(bio)) + /* + * This one doesn't make too much sense ... We never try to write + * to the rbio, and an application program where rbio and wbio + * are separate couldn't even know what it should wait for. + * However if we ever set s->rwstate incorrectly (so that we have + * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and + * wbio *are* the same, this test works around that bug; so it + * might be safer to keep it. + */ + return (SSL_ERROR_WANT_WRITE); + else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return (SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return (SSL_ERROR_WANT_ACCEPT); + else + return (SSL_ERROR_SYSCALL); /* unknown */ + } + } + + if ((i < 0) && SSL_want_write(s)) { + bio = SSL_get_wbio(s); + if (BIO_should_write(bio)) + return (SSL_ERROR_WANT_WRITE); + else if (BIO_should_read(bio)) + /* + * See above (SSL_want_read(s) with BIO_should_write(bio)) + */ + return (SSL_ERROR_WANT_READ); + else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return (SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return (SSL_ERROR_WANT_ACCEPT); + else + return (SSL_ERROR_SYSCALL); + } + } + if ((i < 0) && SSL_want_x509_lookup(s)) { + return (SSL_ERROR_WANT_X509_LOOKUP); + } + + if (i == 0) { + if (s->version == SSL2_VERSION) { + /* assume it is the socket being closed */ + return (SSL_ERROR_ZERO_RETURN); + } else { + if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && + (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) + return (SSL_ERROR_ZERO_RETURN); + } + } + return (SSL_ERROR_SYSCALL); +} + +int SSL_do_handshake(SSL *s) +{ + int ret = 1; + + if (s->handshake_func == NULL) { + SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET); + return (-1); + } + + s->method->ssl_renegotiate_check(s); + + if (SSL_in_init(s) || SSL_in_before(s)) { + ret = s->handshake_func(s); + } + return (ret); +} + +/* + * For the next 2 functions, SSL_clear() sets shutdown and so one of these + * calls will reset it + */ +void SSL_set_accept_state(SSL *s) +{ + s->server = 1; + s->shutdown = 0; + s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE; + s->handshake_func = s->method->ssl_accept; + /* clear the current cipher */ + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); +} + +void SSL_set_connect_state(SSL *s) +{ + s->server = 0; + s->shutdown = 0; + s->state = SSL_ST_CONNECT | SSL_ST_BEFORE; + s->handshake_func = s->method->ssl_connect; + /* clear the current cipher */ + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); +} + +int ssl_undefined_function(SSL *s) +{ + SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +int ssl_undefined_void_function(void) +{ + SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +int ssl_undefined_const_function(const SSL *s) +{ + SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +SSL_METHOD *ssl_bad_method(int ver) +{ + SSLerr(SSL_F_SSL_BAD_METHOD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (NULL); +} + +const char *SSL_get_version(const SSL *s) +{ + if (s->version == TLS1_2_VERSION) + return ("TLSv1.2"); + else if (s->version == TLS1_1_VERSION) + return ("TLSv1.1"); + else if (s->version == TLS1_VERSION) + return ("TLSv1"); + else if (s->version == SSL3_VERSION) + return ("SSLv3"); + else if (s->version == SSL2_VERSION) + return ("SSLv2"); + else if (s->version == DTLS1_BAD_VER) + return ("DTLSv0.9"); + else if (s->version == DTLS1_VERSION) + return ("DTLSv1"); + else if (s->version == DTLS1_2_VERSION) + return ("DTLSv1.2"); + else + return ("unknown"); +} + +SSL *SSL_dup(SSL *s) +{ + STACK_OF(X509_NAME) *sk; + X509_NAME *xn; + SSL *ret; + int i; + + if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL) + return (NULL); + + ret->version = s->version; + ret->type = s->type; + ret->method = s->method; + + if (s->session != NULL) { + /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */ + SSL_copy_session_id(ret, s); + } else { + /* + * No session has been established yet, so we have to expect that + * s->cert or ret->cert will be changed later -- they should not both + * point to the same object, and thus we can't use + * SSL_copy_session_id. + */ + + ret->method->ssl_free(ret); + ret->method = s->method; + ret->method->ssl_new(ret); + + if (s->cert != NULL) { + if (ret->cert != NULL) { + ssl_cert_free(ret->cert); + } + ret->cert = ssl_cert_dup(s->cert); + if (ret->cert == NULL) + goto err; + } + + SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length); + } + + ret->options = s->options; + ret->mode = s->mode; + SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s)); + SSL_set_read_ahead(ret, SSL_get_read_ahead(s)); + ret->msg_callback = s->msg_callback; + ret->msg_callback_arg = s->msg_callback_arg; + SSL_set_verify(ret, SSL_get_verify_mode(s), SSL_get_verify_callback(s)); + SSL_set_verify_depth(ret, SSL_get_verify_depth(s)); + ret->generate_session_id = s->generate_session_id; + + SSL_set_info_callback(ret, SSL_get_info_callback(s)); + + ret->debug = s->debug; + + /* copy app data, a little dangerous perhaps */ + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data)) + goto err; + + /* setup rbio, and wbio */ + if (s->rbio != NULL) { + if (!BIO_dup_state(s->rbio, (char *)&ret->rbio)) + goto err; + } + if (s->wbio != NULL) { + if (s->wbio != s->rbio) { + if (!BIO_dup_state(s->wbio, (char *)&ret->wbio)) + goto err; + } else + ret->wbio = ret->rbio; + } + ret->rwstate = s->rwstate; + ret->in_handshake = s->in_handshake; + ret->handshake_func = s->handshake_func; + ret->server = s->server; + ret->renegotiate = s->renegotiate; + ret->new_session = s->new_session; + ret->quiet_shutdown = s->quiet_shutdown; + ret->shutdown = s->shutdown; + ret->state = s->state; /* SSL_dup does not really work at any state, + * though */ + ret->rstate = s->rstate; + ret->init_num = 0; /* would have to copy ret->init_buf, + * ret->init_msg, ret->init_num, + * ret->init_off */ + ret->hit = s->hit; + + X509_VERIFY_PARAM_inherit(ret->param, s->param); + + /* dup the cipher_list and cipher_list_by_id stacks */ + if (s->cipher_list != NULL) { + if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) + goto err; + } + if (s->cipher_list_by_id != NULL) + if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id)) + == NULL) + goto err; + + /* Dup the client_CA list */ + if (s->client_CA != NULL) { + if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL) + goto err; + ret->client_CA = sk; + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + xn = sk_X509_NAME_value(sk, i); + if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) { + X509_NAME_free(xn); + goto err; + } + } + } + + if (0) { + err: + if (ret != NULL) + SSL_free(ret); + ret = NULL; + } + return (ret); +} + +void ssl_clear_cipher_ctx(SSL *s) +{ + if (s->enc_read_ctx != NULL) { + EVP_CIPHER_CTX_cleanup(s->enc_read_ctx); + OPENSSL_free(s->enc_read_ctx); + s->enc_read_ctx = NULL; + } + if (s->enc_write_ctx != NULL) { + EVP_CIPHER_CTX_cleanup(s->enc_write_ctx); + OPENSSL_free(s->enc_write_ctx); + s->enc_write_ctx = NULL; + } +#ifndef OPENSSL_NO_COMP + if (s->expand != NULL) { + COMP_CTX_free(s->expand); + s->expand = NULL; + } + if (s->compress != NULL) { + COMP_CTX_free(s->compress); + s->compress = NULL; + } +#endif +} + +X509 *SSL_get_certificate(const SSL *s) +{ + if (s->cert != NULL) + return (s->cert->key->x509); + else + return (NULL); +} + +EVP_PKEY *SSL_get_privatekey(const SSL *s) +{ + if (s->cert != NULL) + return (s->cert->key->privatekey); + else + return (NULL); +} + +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) +{ + if (ctx->cert != NULL) + return ctx->cert->key->x509; + else + return NULL; +} + +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) +{ + if (ctx->cert != NULL) + return ctx->cert->key->privatekey; + else + return NULL; +} + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) +{ + if ((s->session != NULL) && (s->session->cipher != NULL)) + return (s->session->cipher); + return (NULL); +} + +#ifdef OPENSSL_NO_COMP +const COMP_METHOD *SSL_get_current_compression(SSL *s) +{ + return NULL; +} + +const COMP_METHOD *SSL_get_current_expansion(SSL *s) +{ + return NULL; +} +#else + +const COMP_METHOD *SSL_get_current_compression(SSL *s) +{ + if (s->compress != NULL) + return (s->compress->meth); + return (NULL); +} + +const COMP_METHOD *SSL_get_current_expansion(SSL *s) +{ + if (s->expand != NULL) + return (s->expand->meth); + return (NULL); +} +#endif + +int ssl_init_wbio_buffer(SSL *s, int push) +{ + BIO *bbio; + + if (s->bbio == NULL) { + bbio = BIO_new(BIO_f_buffer()); + if (bbio == NULL) + return (0); + s->bbio = bbio; + } else { + bbio = s->bbio; + if (s->bbio == s->wbio) + s->wbio = BIO_pop(s->wbio); + } + (void)BIO_reset(bbio); +/* if (!BIO_set_write_buffer_size(bbio,16*1024)) */ + if (!BIO_set_read_buffer_size(bbio, 1)) { + SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB); + return (0); + } + if (push) { + if (s->wbio != bbio) + s->wbio = BIO_push(bbio, s->wbio); + } else { + if (s->wbio == bbio) + s->wbio = BIO_pop(bbio); + } + return (1); +} + +void ssl_free_wbio_buffer(SSL *s) +{ + if (s->bbio == NULL) + return; + + if (s->bbio == s->wbio) { + /* remove buffering */ + s->wbio = BIO_pop(s->wbio); +#ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids + * adding one more preprocessor symbol */ + assert(s->wbio != NULL); +#endif + } + BIO_free(s->bbio); + s->bbio = NULL; +} + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) +{ + ctx->quiet_shutdown = mode; +} + +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) +{ + return (ctx->quiet_shutdown); +} + +void SSL_set_quiet_shutdown(SSL *s, int mode) +{ + s->quiet_shutdown = mode; +} + +int SSL_get_quiet_shutdown(const SSL *s) +{ + return (s->quiet_shutdown); +} + +void SSL_set_shutdown(SSL *s, int mode) +{ + s->shutdown = mode; +} + +int SSL_get_shutdown(const SSL *s) +{ + return (s->shutdown); +} + +int SSL_version(const SSL *s) +{ + return (s->version); +} + +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) +{ + return (ssl->ctx); +} + +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) +{ + CERT *ocert = ssl->cert; + if (ssl->ctx == ctx) + return ssl->ctx; +#ifndef OPENSSL_NO_TLSEXT + if (ctx == NULL) + ctx = ssl->initial_ctx; +#endif + ssl->cert = ssl_cert_dup(ctx->cert); + if (ocert) { + int i; + /* Preserve any already negotiated parameters */ + if (ssl->server) { + ssl->cert->peer_sigalgs = ocert->peer_sigalgs; + ssl->cert->peer_sigalgslen = ocert->peer_sigalgslen; + ocert->peer_sigalgs = NULL; + ssl->cert->ciphers_raw = ocert->ciphers_raw; + ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen; + ocert->ciphers_raw = NULL; + } + for (i = 0; i < SSL_PKEY_NUM; i++) { + ssl->cert->pkeys[i].digest = ocert->pkeys[i].digest; + } +#ifndef OPENSSL_NO_TLSEXT + ssl->cert->alpn_proposed = ocert->alpn_proposed; + ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len; + ocert->alpn_proposed = NULL; + ssl->cert->alpn_sent = ocert->alpn_sent; + + if (!custom_exts_copy_flags(&ssl->cert->srv_ext, &ocert->srv_ext)) + return NULL; +#endif + ssl_cert_free(ocert); + } + + /* + * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH), + * so setter APIs must prevent invalid lengths from entering the system. + */ + OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx)); + + /* + * If the session ID context matches that of the parent SSL_CTX, + * inherit it from the new SSL_CTX as well. If however the context does + * not match (i.e., it was set per-ssl with SSL_set_session_id_context), + * leave it unchanged. + */ + if ((ssl->ctx != NULL) && + (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) && + (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0)) { + ssl->sid_ctx_length = ctx->sid_ctx_length; + memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx)); + } + + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + if (ssl->ctx != NULL) + SSL_CTX_free(ssl->ctx); /* decrement reference count */ + ssl->ctx = ctx; + + return (ssl->ctx); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) +{ + return (X509_STORE_set_default_paths(ctx->cert_store)); +} + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath) +{ + return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath)); +} +#endif + +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)) +{ + ssl->info_callback = cb; +} + +/* + * One compiler (Diab DCC) doesn't like argument names in returned function + * pointer. + */ +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ , + int /* type */ , + int /* val */ ) { + return ssl->info_callback; +} + +int SSL_state(const SSL *ssl) +{ + return (ssl->state); +} + +void SSL_set_state(SSL *ssl, int state) +{ + ssl->state = state; +} + +void SSL_set_verify_result(SSL *ssl, long arg) +{ + ssl->verify_result = arg; +} + +long SSL_get_verify_result(const SSL *ssl) +{ + return (ssl->verify_result); +} + +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, + new_func, dup_func, free_func); +} + +int SSL_set_ex_data(SSL *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void *SSL_get_ex_data(const SSL *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, + new_func, dup_func, free_func); +} + +int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +int ssl_ok(SSL *s) +{ + return (1); +} + +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) +{ + return (ctx->cert_store); +} + +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) +{ + if (ctx->cert_store != NULL) + X509_STORE_free(ctx->cert_store); + ctx->cert_store = store; +} + +int SSL_want(const SSL *s) +{ + return (s->rwstate); +} + +/** + * \brief Set the callback for generating temporary RSA keys. + * \param ctx the SSL context. + * \param cb the callback + */ + +#ifndef OPENSSL_NO_RSA +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb) (SSL *ssl, + int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb); +} + +void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb) (SSL *ssl, + int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb); +} +#endif + +#ifdef DOXYGEN +/** + * \brief The RSA temporary key callback function. + * \param ssl the SSL session. + * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite. + * \param keylength if \c is_export is \c TRUE, then \c keylength is the size + * of the required key in bits. + * \return the temporary RSA key. + * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback + */ + +RSA *cb(SSL *ssl, int is_export, int keylength) +{ +} +#endif + +/** + * \brief Set the callback for generating temporary DH keys. + * \param ctx the SSL context. + * \param dh the callback + */ + +#ifndef OPENSSL_NO_DH +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); +} + +void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); +} +#endif + +#ifndef OPENSSL_NO_ECDH +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, + (void (*)(void))ecdh); +} + +void SSL_set_tmp_ecdh_callback(SSL *ssl, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh); +} +#endif + +#ifndef OPENSSL_NO_PSK +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) +{ + if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, + SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + if (ctx->psk_identity_hint != NULL) + OPENSSL_free(ctx->psk_identity_hint); + if (identity_hint != NULL) { + ctx->psk_identity_hint = BUF_strdup(identity_hint); + if (ctx->psk_identity_hint == NULL) + return 0; + } else + ctx->psk_identity_hint = NULL; + return 1; +} + +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) +{ + if (s == NULL) + return 0; + + if (s->session == NULL) + return 1; /* session not created yet, ignored */ + + if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + if (identity_hint != NULL) { + s->session->psk_identity_hint = BUF_strdup(identity_hint); + if (s->session->psk_identity_hint == NULL) + return 0; + } else + s->session->psk_identity_hint = NULL; + return 1; +} + +const char *SSL_get_psk_identity_hint(const SSL *s) +{ + if (s == NULL || s->session == NULL) + return NULL; + return (s->session->psk_identity_hint); +} + +const char *SSL_get_psk_identity(const SSL *s) +{ + if (s == NULL || s->session == NULL) + return NULL; + return (s->session->psk_identity); +} + +void SSL_set_psk_client_callback(SSL *s, + unsigned int (*cb) (SSL *ssl, + const char *hint, + char *identity, + unsigned int + max_identity_len, + unsigned char *psk, + unsigned int + max_psk_len)) +{ + s->psk_client_callback = cb; +} + +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, + unsigned int (*cb) (SSL *ssl, + const char *hint, + char *identity, + unsigned int + max_identity_len, + unsigned char *psk, + unsigned int + max_psk_len)) +{ + ctx->psk_client_callback = cb; +} + +void SSL_set_psk_server_callback(SSL *s, + unsigned int (*cb) (SSL *ssl, + const char *identity, + unsigned char *psk, + unsigned int + max_psk_len)) +{ + s->psk_server_callback = cb; +} + +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*cb) (SSL *ssl, + const char *identity, + unsigned char *psk, + unsigned int + max_psk_len)) +{ + ctx->psk_server_callback = cb; +} +#endif + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); +} + +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); +} + +/* + * Allocates new EVP_MD_CTX and sets pointer to it into given pointer + * vairable, freeing EVP_MD_CTX previously stored in that variable, if any. + * If EVP_MD pointer is passed, initializes ctx with this md Returns newly + * allocated ctx; + */ + +EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) +{ + ssl_clear_hash_ctx(hash); + *hash = EVP_MD_CTX_create(); + if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) { + EVP_MD_CTX_destroy(*hash); + *hash = NULL; + return NULL; + } + return *hash; +} + +void ssl_clear_hash_ctx(EVP_MD_CTX **hash) +{ + + if (*hash) + EVP_MD_CTX_destroy(*hash); + *hash = NULL; +} + +void SSL_set_debug(SSL *s, int debug) +{ + s->debug = debug; +} + +int SSL_cache_hit(SSL *s) +{ + return s->hit; +} + +int SSL_is_server(SSL *s) +{ + return s->server; +} + +#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16) +# include "bio/bss_file.c" +#endif + +IMPLEMENT_STACK_OF(SSL_CIPHER) +IMPLEMENT_STACK_OF(SSL_COMP) +IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); +/* ssl/ssl_rsa.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "ssl_locl.h" +// #include "bio.h" +// #include "objects.h" +#include "evp.h" +// #include "x509.h" +// #include "pem.h" + +static int ssl_set_cert(CERT *c, X509 *x509); +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); +int SSL_use_certificate(SSL *ssl, X509 *x) +{ + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_cert(ssl->cert, x)); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_use_certificate_file(SSL *ssl, const char *file, int type) +{ + int j; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); + goto end; + } + + ret = SSL_use_certificate(ssl, x); + end: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d, (long)len); + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_certificate(ssl, x); + X509_free(x); + return (ret); +} + +#ifndef OPENSSL_NO_RSA +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) +{ + EVP_PKEY *pkey; + int ret; + + if (rsa == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + if ((pkey = EVP_PKEY_new()) == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); + return (0); + } + + RSA_up_ref(rsa); + if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { + RSA_free(rsa); + return 0; + } + + ret = ssl_set_pkey(ssl->cert, pkey); + EVP_PKEY_free(pkey); + return (ret); +} +#endif + +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) +{ + int i; + /* + * Special case for DH: check two DH certificate types for a match. This + * means for DH certificates we must set the certificate first. + */ + if (pkey->type == EVP_PKEY_DH) { + X509 *x; + i = -1; + x = c->pkeys[SSL_PKEY_DH_RSA].x509; + if (x && X509_check_private_key(x, pkey)) + i = SSL_PKEY_DH_RSA; + x = c->pkeys[SSL_PKEY_DH_DSA].x509; + if (i == -1 && x && X509_check_private_key(x, pkey)) + i = SSL_PKEY_DH_DSA; + ERR_clear_error(); + } else + i = ssl_cert_type(NULL, pkey); + if (i < 0) { + SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return (0); + } + + if (c->pkeys[i].x509 != NULL) { + EVP_PKEY *pktmp; + pktmp = X509_get_pubkey(c->pkeys[i].x509); + if (pktmp == NULL) { + SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE); + EVP_PKEY_free(pktmp); + return 0; + } + /* + * The return code from EVP_PKEY_copy_parameters is deliberately + * ignored. Some EVP_PKEY types cannot do this. + */ + EVP_PKEY_copy_parameters(pktmp, pkey); + EVP_PKEY_free(pktmp); + ERR_clear_error(); + +#ifndef OPENSSL_NO_RSA + /* + * Don't check the public/private key, this is mostly for smart + * cards. + */ + if ((pkey->type == EVP_PKEY_RSA) && + (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; + else +#endif + if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { + X509_free(c->pkeys[i].x509); + c->pkeys[i].x509 = NULL; + return 0; + } + } + + if (c->pkeys[i].privatekey != NULL) + EVP_PKEY_free(c->pkeys[i].privatekey); + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + c->pkeys[i].privatekey = pkey; + c->key = &(c->pkeys[i]); + + c->valid = 0; + return (1); +} + +#ifndef OPENSSL_NO_RSA +# ifndef OPENSSL_NO_STDIO +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + ssl->ctx->default_passwd_callback, + ssl-> + ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + end: + if (in != NULL) + BIO_free(in); + return (ret); +} +# endif + +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len) +{ + int ret; + const unsigned char *p; + RSA *rsa; + + p = d; + if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + return (ret); +} +#endif /* !OPENSSL_NO_RSA */ + +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) +{ + int ret; + + if (pkey == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + ret = ssl_set_pkey(ssl->cert, pkey); + return (ret); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, + ssl->ctx->default_passwd_callback, + ssl-> + ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (pkey == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + end: + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, + long len) +{ + int ret; + const unsigned char *p; + EVP_PKEY *pkey; + + p = d; + if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) +{ + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_cert(ctx->cert, x)); +} + +static int ssl_set_cert(CERT *c, X509 *x) +{ + EVP_PKEY *pkey; + int i; + + pkey = X509_get_pubkey(x); + if (pkey == NULL) { + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); + return (0); + } + + i = ssl_cert_type(x, pkey); + if (i < 0) { + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + EVP_PKEY_free(pkey); + return (0); + } + + if (c->pkeys[i].privatekey != NULL) { + /* + * The return code from EVP_PKEY_copy_parameters is deliberately + * ignored. Some EVP_PKEY types cannot do this. + */ + EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); + ERR_clear_error(); + +#ifndef OPENSSL_NO_RSA + /* + * Don't check the public/private key, this is mostly for smart + * cards. + */ + if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && + (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & + RSA_METHOD_FLAG_NO_CHECK)) ; + else +#endif /* OPENSSL_NO_RSA */ + if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { + /* + * don't fail for a cert/key mismatch, just free current private + * key (when switching to a different cert & key, first this + * function should be used, then ssl_set_pkey + */ + EVP_PKEY_free(c->pkeys[i].privatekey); + c->pkeys[i].privatekey = NULL; + /* clear error queue */ + ERR_clear_error(); + } + } + + EVP_PKEY_free(pkey); + + if (c->pkeys[i].x509 != NULL) + X509_free(c->pkeys[i].x509); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + c->pkeys[i].x509 = x; + c->key = &(c->pkeys[i]); + + c->valid = 0; + return (1); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) +{ + int j; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + end: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d, (long)len); + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_certificate(ctx, x); + X509_free(x); + return (ret); +} + +#ifndef OPENSSL_NO_RSA +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) +{ + int ret; + EVP_PKEY *pkey; + + if (rsa == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + if ((pkey = EVP_PKEY_new()) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); + return (0); + } + + RSA_up_ref(rsa); + if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { + RSA_free(rsa); + return 0; + } + + ret = ssl_set_pkey(ctx->cert, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +# ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + end: + if (in != NULL) + BIO_free(in); + return (ret); +} +# endif + +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len) +{ + int ret; + const unsigned char *p; + RSA *rsa; + + p = d; + if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + return (ret); +} +#endif /* !OPENSSL_NO_RSA */ + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) +{ + if (pkey == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_pkey(ctx->cert, pkey)); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (pkey == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + end: + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, + const unsigned char *d, long len) +{ + int ret; + const unsigned char *p; + EVP_PKEY *pkey; + + p = d; + if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +#ifndef OPENSSL_NO_STDIO +/* + * Read a file that contains our certificate in "PEM" format, possibly + * followed by a sequence of CA certificates that should be sent to the peer + * in the Certificate message. + */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) +{ + BIO *in; + int ret = 0; + X509 *x = NULL; + + ERR_clear_error(); /* clear error stack for + * SSL_CTX_use_certificate() */ + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); + goto end; + } + + x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + + if (ERR_peek_error() != 0) + ret = 0; /* Key/certificate mismatch doesn't imply + * ret==0 ... */ + if (ret) { + /* + * If we could set up our certificate, now proceed to the CA + * certificates. + */ + X509 *ca; + int r; + unsigned long err; + + SSL_CTX_clear_chain_certs(ctx); + + while ((ca = PEM_read_bio_X509(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata)) + != NULL) { + r = SSL_CTX_add0_chain_cert(ctx, ca); + if (!r) { + X509_free(ca); + ret = 0; + goto end; + } + /* + * Note that we must not free r if it was successfully added to + * the chain (while we must free the main certificate, since its + * reference count is increased by SSL_CTX_use_certificate). + */ + } + /* When the while loop ends, it's usually just EOF. */ + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM + && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) + ERR_clear_error(); + else + ret = 0; /* some real error */ + } + + end: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +#ifndef OPENSSL_NO_TLSEXT +static int serverinfo_find_extension(const unsigned char *serverinfo, + size_t serverinfo_length, + unsigned int extension_type, + const unsigned char **extension_data, + size_t *extension_length) +{ + *extension_data = NULL; + *extension_length = 0; + if (serverinfo == NULL || serverinfo_length == 0) + return -1; + for (;;) { + unsigned int type = 0; + size_t len = 0; + + /* end of serverinfo */ + if (serverinfo_length == 0) + return 0; /* Extension not found */ + + /* read 2-byte type field */ + if (serverinfo_length < 2) + return -1; /* Error */ + type = (serverinfo[0] << 8) + serverinfo[1]; + serverinfo += 2; + serverinfo_length -= 2; + + /* read 2-byte len field */ + if (serverinfo_length < 2) + return -1; /* Error */ + len = (serverinfo[0] << 8) + serverinfo[1]; + serverinfo += 2; + serverinfo_length -= 2; + + if (len > serverinfo_length) + return -1; /* Error */ + + if (type == extension_type) { + *extension_data = serverinfo; + *extension_length = len; + return 1; /* Success */ + } + + serverinfo += len; + serverinfo_length -= len; + } + return 0; /* Error */ +} + +static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type, + const unsigned char *in, + size_t inlen, int *al, void *arg) +{ + + if (inlen != 0) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + return 1; +} + +static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type, + const unsigned char **out, size_t *outlen, + int *al, void *arg) +{ + const unsigned char *serverinfo = NULL; + size_t serverinfo_length = 0; + + /* Is there serverinfo data for the chosen server cert? */ + if ((ssl_get_server_cert_serverinfo(s, &serverinfo, + &serverinfo_length)) != 0) { + /* Find the relevant extension from the serverinfo */ + int retval = serverinfo_find_extension(serverinfo, serverinfo_length, + ext_type, out, outlen); + if (retval == -1) { + *al = SSL_AD_DECODE_ERROR; + return -1; /* Error */ + } + if (retval == 0) + return 0; /* No extension found, don't send extension */ + return 1; /* Send extension */ + } + return 0; /* No serverinfo data found, don't send + * extension */ +} + +/* + * With a NULL context, this function just checks that the serverinfo data + * parses correctly. With a non-NULL context, it registers callbacks for + * the included extensions. + */ +static int serverinfo_process_buffer(const unsigned char *serverinfo, + size_t serverinfo_length, SSL_CTX *ctx) +{ + if (serverinfo == NULL || serverinfo_length == 0) + return 0; + for (;;) { + unsigned int ext_type = 0; + size_t len = 0; + + /* end of serverinfo */ + if (serverinfo_length == 0) + return 1; + + /* read 2-byte type field */ + if (serverinfo_length < 2) + return 0; + /* FIXME: check for types we understand explicitly? */ + + /* Register callbacks for extensions */ + ext_type = (serverinfo[0] << 8) + serverinfo[1]; + if (ctx) { + int have_ext_cbs = 0; + size_t i; + custom_ext_methods *exts = &ctx->cert->srv_ext; + custom_ext_method *meth = exts->meths; + + for (i = 0; i < exts->meths_count; i++, meth++) { + if (ext_type == meth->ext_type) { + have_ext_cbs = 1; + break; + } + } + + if (!have_ext_cbs && !SSL_CTX_add_server_custom_ext(ctx, ext_type, + serverinfo_srv_add_cb, + NULL, NULL, + serverinfo_srv_parse_cb, + NULL)) + return 0; + } + + serverinfo += 2; + serverinfo_length -= 2; + + /* read 2-byte len field */ + if (serverinfo_length < 2) + return 0; + len = (serverinfo[0] << 8) + serverinfo[1]; + serverinfo += 2; + serverinfo_length -= 2; + + if (len > serverinfo_length) + return 0; + + serverinfo += len; + serverinfo_length -= len; + } +} + +int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, + size_t serverinfo_length) +{ + unsigned char *new_serverinfo; + + if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL)) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA); + return 0; + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE); + return 0; + } + if (ctx->cert->key == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR); + return 0; + } + new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, + serverinfo_length); + if (new_serverinfo == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->cert->key->serverinfo = new_serverinfo; + memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); + ctx->cert->key->serverinfo_length = serverinfo_length; + + /* + * Now that the serverinfo is validated and stored, go ahead and + * register callbacks. + */ + if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx)) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA); + return 0; + } + return 1; +} + +# ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) +{ + unsigned char *serverinfo = NULL; + size_t serverinfo_length = 0; + unsigned char *extension = 0; + long extension_length = 0; + char *name = NULL; + char *header = NULL; + char namePrefix[] = "SERVERINFO FOR "; + int ret = 0; + BIO *bin = NULL; + size_t num_extensions = 0; + unsigned char *new_serverinfo; + + if (ctx == NULL || file == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, + ERR_R_PASSED_NULL_PARAMETER); + goto end; + } + + bin = BIO_new(BIO_s_file_internal()); + if (bin == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB); + goto end; + } + if (BIO_read_filename(bin, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB); + goto end; + } + + for (num_extensions = 0;; num_extensions++) { + if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) + == 0) { + /* + * There must be at least one extension in this file + */ + if (num_extensions == 0) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, + SSL_R_NO_PEM_EXTENSIONS); + goto end; + } else /* End of file, we're done */ + break; + } + /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */ + if (strlen(name) < strlen(namePrefix)) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, + SSL_R_PEM_NAME_TOO_SHORT); + goto end; + } + if (strncmp(name, namePrefix, strlen(namePrefix)) != 0) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, + SSL_R_PEM_NAME_BAD_PREFIX); + goto end; + } + /* + * Check that the decoded PEM data is plausible (valid length field) + */ + if (extension_length < 4 + || (extension[2] << 8) + extension[3] != extension_length - 4) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); + goto end; + } + /* Append the decoded extension to the serverinfo buffer */ + new_serverinfo = + OPENSSL_realloc(serverinfo, serverinfo_length + extension_length); + if (new_serverinfo == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); + goto end; + } + serverinfo = new_serverinfo; + memcpy(serverinfo + serverinfo_length, extension, extension_length); + serverinfo_length += extension_length; + + OPENSSL_free(name); + name = NULL; + OPENSSL_free(header); + header = NULL; + OPENSSL_free(extension); + extension = NULL; + } + + ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length); + end: + /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */ + OPENSSL_free(name); + OPENSSL_free(header); + OPENSSL_free(extension); + OPENSSL_free(serverinfo); + if (bin != NULL) + BIO_free(bin); + return ret; +} +# endif /* OPENSSL_NO_STDIO */ +#endif /* OPENSSL_NO_TLSEXT */ +/* ssl/ssl_sess.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +// #include "lhash.h" +// #include "rand.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +// #include "ssl_locl.h" + +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); + +SSL_SESSION *SSL_get_session(const SSL *ssl) +/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ +{ + return (ssl->session); +} + +SSL_SESSION *SSL_get1_session(SSL *ssl) +/* variant of SSL_get_session: caller really gets something */ +{ + SSL_SESSION *sess; + /* + * Need to lock this all up rather than just use CRYPTO_add so that + * somebody doesn't free ssl->session between when we check it's non-null + * and when we up the reference count. + */ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); + sess = ssl->session; + if (sess) + sess->references++; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); + return (sess); +} + +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp, + new_func, dup_func, free_func); +} + +int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +SSL_SESSION *SSL_SESSION_new(void) +{ + SSL_SESSION *ss; + + ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION)); + if (ss == NULL) { + SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); + return (0); + } + memset(ss, 0, sizeof(SSL_SESSION)); + + ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ + ss->references = 1; + ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */ + ss->time = (unsigned long)time(NULL); + ss->prev = NULL; + ss->next = NULL; + ss->compress_meth = 0; +#ifndef OPENSSL_NO_TLSEXT + ss->tlsext_hostname = NULL; +# ifndef OPENSSL_NO_EC + ss->tlsext_ecpointformatlist_length = 0; + ss->tlsext_ecpointformatlist = NULL; + ss->tlsext_ellipticcurvelist_length = 0; + ss->tlsext_ellipticcurvelist = NULL; +# endif +#endif + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); +#ifndef OPENSSL_NO_PSK + ss->psk_identity_hint = NULL; + ss->psk_identity = NULL; +#endif +#ifndef OPENSSL_NO_SRP + ss->srp_username = NULL; +#endif + return (ss); +} + +/* + * Create a new SSL_SESSION and duplicate the contents of |src| into it. If + * ticket == 0 then no ticket information is duplicated, otherwise it is. + */ +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) +{ + SSL_SESSION *dest; + + dest = OPENSSL_malloc(sizeof(*src)); + if (dest == NULL) { + goto err; + } + memcpy(dest, src, sizeof(*dest)); + + /* + * Set the various pointers to NULL so that we can call SSL_SESSION_free in + * the case of an error whilst halfway through constructing dest + */ +#ifndef OPENSSL_NO_PSK + dest->psk_identity_hint = NULL; + dest->psk_identity = NULL; +#endif + dest->ciphers = NULL; +#ifndef OPENSSL_NO_TLSEXT + dest->tlsext_hostname = NULL; +# ifndef OPENSSL_NO_EC + dest->tlsext_ecpointformatlist = NULL; + dest->tlsext_ellipticcurvelist = NULL; +# endif + dest->tlsext_tick = NULL; +#endif +#ifndef OPENSSL_NO_SRP + dest->srp_username = NULL; +#endif + + /* We deliberately don't copy the prev and next pointers */ + dest->prev = NULL; + dest->next = NULL; + + dest->references = 1; + + if (src->sess_cert != NULL) + CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); + + if (src->peer != NULL) + CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) + goto err; + +#ifndef OPENSSL_NO_PSK + if (src->psk_identity_hint) { + dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint); + if (dest->psk_identity_hint == NULL) { + goto err; + } + } + if (src->psk_identity) { + dest->psk_identity = BUF_strdup(src->psk_identity); + if (dest->psk_identity == NULL) { + goto err; + } + } +#endif + + if(src->ciphers != NULL) { + dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); + if (dest->ciphers == NULL) + goto err; + } + + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, + &dest->ex_data, &src->ex_data)) { + goto err; + } + +#ifndef OPENSSL_NO_TLSEXT + if (src->tlsext_hostname) { + dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname); + if (dest->tlsext_hostname == NULL) { + goto err; + } + } +# ifndef OPENSSL_NO_EC + if (src->tlsext_ecpointformatlist) { + dest->tlsext_ecpointformatlist = + BUF_memdup(src->tlsext_ecpointformatlist, + src->tlsext_ecpointformatlist_length); + if (dest->tlsext_ecpointformatlist == NULL) + goto err; + } + if (src->tlsext_ellipticcurvelist) { + dest->tlsext_ellipticcurvelist = + BUF_memdup(src->tlsext_ellipticcurvelist, + src->tlsext_ellipticcurvelist_length); + if (dest->tlsext_ellipticcurvelist == NULL) + goto err; + } +# endif + + if (ticket != 0 && src->tlsext_tick != NULL) { + dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); + if(dest->tlsext_tick == NULL) + goto err; + } else { + dest->tlsext_tick_lifetime_hint = 0; + dest->tlsext_ticklen = 0; + } +#endif + +#ifndef OPENSSL_NO_SRP + if (src->srp_username) { + dest->srp_username = BUF_strdup(src->srp_username); + if (dest->srp_username == NULL) { + goto err; + } + } +#endif + + return dest; +err: + SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(dest); + return NULL; +} + +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len) +{ + if (len) + *len = s->session_id_length; + return s->session_id; +} + +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s) +{ + return s->compress_meth; +} + +/* + * Even with SSLv2, we have 16 bytes (128 bits) of session ID space. + * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random + * gunk repeatedly until we have no conflict is going to complete in one + * iteration pretty much "most" of the time (btw: understatement). So, if it + * takes us 10 iterations and we still can't avoid a conflict - well that's a + * reasonable point to call it quits. Either the RAND code is broken or + * someone is trying to open roughly very close to 2^128 (or 2^256) SSL + * sessions to our server. How you might store that many sessions is perhaps + * a more interesting question ... + */ + +#define MAX_SESS_ID_ATTEMPTS 10 +static int def_generate_session_id(const SSL *ssl, unsigned char *id, + unsigned int *id_len) +{ + unsigned int retry = 0; + do + if (RAND_bytes(id, *id_len) <= 0) + return 0; + while (SSL_has_matching_session_id(ssl, id, *id_len) && + (++retry < MAX_SESS_ID_ATTEMPTS)) ; + if (retry < MAX_SESS_ID_ATTEMPTS) + return 1; + /* else - woops a session_id match */ + /* + * XXX We should also check the external cache -- but the probability of + * a collision is negligible, and we could not prevent the concurrent + * creation of sessions with identical IDs since we currently don't have + * means to atomically check whether a session ID already exists and make + * a reservation for it if it does not (this problem applies to the + * internal cache as well). + */ + return 0; +} + +int ssl_get_new_session(SSL *s, int session) +{ + /* This gets used by clients and servers. */ + + unsigned int tmp; + SSL_SESSION *ss = NULL; + GEN_SESSION_CB cb = def_generate_session_id; + + if ((ss = SSL_SESSION_new()) == NULL) + return (0); + + /* If the context has a default timeout, use it */ + if (s->session_ctx->session_timeout == 0) + ss->timeout = SSL_get_default_timeout(s); + else + ss->timeout = s->session_ctx->session_timeout; + + if (s->session != NULL) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + if (session) { + if (s->version == SSL2_VERSION) { + ss->ssl_version = SSL2_VERSION; + ss->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; + } else if (s->version == SSL3_VERSION) { + ss->ssl_version = SSL3_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == TLS1_VERSION) { + ss->ssl_version = TLS1_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == TLS1_1_VERSION) { + ss->ssl_version = TLS1_1_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == TLS1_2_VERSION) { + ss->ssl_version = TLS1_2_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == DTLS1_BAD_VER) { + ss->ssl_version = DTLS1_BAD_VER; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == DTLS1_VERSION) { + ss->ssl_version = DTLS1_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == DTLS1_2_VERSION) { + ss->ssl_version = DTLS1_2_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); + SSL_SESSION_free(ss); + return (0); + } +#ifndef OPENSSL_NO_TLSEXT + /*- + * If RFC5077 ticket, use empty session ID (as server). + * Note that: + * (a) ssl_get_prev_session() does lookahead into the + * ClientHello extensions to find the session ticket. + * When ssl_get_prev_session() fails, s3_srvr.c calls + * ssl_get_new_session() in ssl3_get_client_hello(). + * At that point, it has not yet parsed the extensions, + * however, because of the lookahead, it already knows + * whether a ticket is expected or not. + * + * (b) s3_clnt.c calls ssl_get_new_session() before parsing + * ServerHello extensions, and before recording the session + * ID received from the server, so this block is a noop. + */ + if (s->tlsext_ticket_expected) { + ss->session_id_length = 0; + goto sess_id_done; + } +#endif + /* Choose which callback will set the session ID */ + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + if (s->generate_session_id) + cb = s->generate_session_id; + else if (s->session_ctx->generate_session_id) + cb = s->session_ctx->generate_session_id; + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + /* Choose a session ID */ + tmp = ss->session_id_length; + if (!cb(s, ss->session_id, &tmp)) { + /* The callback failed */ + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); + SSL_SESSION_free(ss); + return (0); + } + /* + * Don't allow the callback to set the session length to zero. nor + * set it higher than it was. + */ + if (!tmp || (tmp > ss->session_id_length)) { + /* The callback set an illegal length */ + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); + SSL_SESSION_free(ss); + return (0); + } + /* If the session length was shrunk and we're SSLv2, pad it */ + if ((tmp < ss->session_id_length) && (s->version == SSL2_VERSION)) + memset(ss->session_id + tmp, 0, ss->session_id_length - tmp); + else + ss->session_id_length = tmp; + /* Finally, check for a conflict */ + if (SSL_has_matching_session_id(s, ss->session_id, + ss->session_id_length)) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT); + SSL_SESSION_free(ss); + return (0); + } +#ifndef OPENSSL_NO_TLSEXT + sess_id_done: + if (s->tlsext_hostname) { + ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname); + if (ss->tlsext_hostname == NULL) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + } +#endif + } else { + ss->session_id_length = 0; + } + + if (s->sid_ctx_length > sizeof(ss->sid_ctx)) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); + ss->sid_ctx_length = s->sid_ctx_length; + s->session = ss; + ss->ssl_version = s->version; + ss->verify_result = X509_V_OK; + + return (1); +} + +/*- + * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this + * connection. It is only called by servers. + * + * session_id: points at the session ID in the ClientHello. This code will + * read past the end of this in order to parse out the session ticket + * extension, if any. + * len: the length of the session ID. + * limit: a pointer to the first byte after the ClientHello. + * + * Returns: + * -1: error + * 0: a session may have been found. + * + * Side effects: + * - If a session is found then s->session is pointed at it (after freeing an + * existing session if need be) and s->verify_result is set from the session. + * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1 + * if the server should issue a new session ticket (to 0 otherwise). + */ +int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit) +{ + /* This is used only by servers. */ + + SSL_SESSION *ret = NULL; + int fatal = 0; + int try_session_cache = 1; +#ifndef OPENSSL_NO_TLSEXT + int r; +#endif + + if (limit - session_id < len) { + fatal = 1; + goto err; + } + + if (len == 0) + try_session_cache = 0; + +#ifndef OPENSSL_NO_TLSEXT + /* sets s->tlsext_ticket_expected */ + r = tls1_process_ticket(s, session_id, len, limit, &ret); + switch (r) { + case -1: /* Error during processing */ + fatal = 1; + goto err; + case 0: /* No ticket found */ + case 1: /* Zero length ticket found */ + break; /* Ok to carry on processing session id. */ + case 2: /* Ticket found but not decrypted. */ + case 3: /* Ticket decrypted, *ret has been set. */ + try_session_cache = 0; + break; + default: + abort(); + } +#endif + + if (try_session_cache && + ret == NULL && + !(s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { + SSL_SESSION data; + data.ssl_version = s->version; + data.session_id_length = len; + if (len == 0) + return 0; + memcpy(data.session_id, session_id, len); + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); + if (ret != NULL) { + /* don't allow other threads to steal it: */ + CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); + } + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + if (ret == NULL) + s->session_ctx->stats.sess_miss++; + } + + if (try_session_cache && + ret == NULL && s->session_ctx->get_session_cb != NULL) { + int copy = 1; + + if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) { + s->session_ctx->stats.sess_cb_hit++; + + /* + * Increment reference count now if the session callback asks us + * to do so (note that if the session structures returned by the + * callback are shared between threads, it must handle the + * reference count itself [i.e. copy == 0], or things won't be + * thread-safe). + */ + if (copy) + CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); + + /* + * Add the externally cached session to the internal cache as + * well if and only if we are supposed to. + */ + if (! + (s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE)) + /* + * The following should not return 1, otherwise, things are + * very strange + */ + SSL_CTX_add_session(s->session_ctx, ret); + } + } + + if (ret == NULL) + goto err; + + /* Now ret is non-NULL and we own one of its reference counts. */ + + if (ret->sid_ctx_length != s->sid_ctx_length + || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) { + /* + * We have the session requested by the client, but we don't want to + * use it in this context. + */ + goto err; /* treat like cache miss */ + } + + if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { + /* + * We can't be sure if this session is being used out of context, + * which is especially important for SSL_VERIFY_PEER. The application + * should have used SSL[_CTX]_set_session_id_context. For this error + * case, we generate an error instead of treating the event like a + * cache miss (otherwise it would be easy for applications to + * effectively disable the session cache by accident without anyone + * noticing). + */ + + SSLerr(SSL_F_SSL_GET_PREV_SESSION, + SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); + fatal = 1; + goto err; + } + + if (ret->cipher == NULL) { + unsigned char buf[5], *p; + unsigned long l; + + p = buf; + l = ret->cipher_id; + l2n(l, p); + if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR) + ret->cipher = ssl_get_cipher_by_char(s, &(buf[2])); + else + ret->cipher = ssl_get_cipher_by_char(s, &(buf[1])); + if (ret->cipher == NULL) + goto err; + } + + if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */ + s->session_ctx->stats.sess_timeout++; + if (try_session_cache) { + /* session was from the cache, so remove it */ + SSL_CTX_remove_session(s->session_ctx, ret); + } + goto err; + } + + s->session_ctx->stats.sess_hit++; + + if (s->session != NULL) + SSL_SESSION_free(s->session); + s->session = ret; + s->verify_result = s->session->verify_result; + return 1; + + err: + if (ret != NULL) { + SSL_SESSION_free(ret); +#ifndef OPENSSL_NO_TLSEXT + if (!try_session_cache) { + /* + * The session was from a ticket, so we should issue a ticket for + * the new session + */ + s->tlsext_ticket_expected = 1; + } +#endif + } + if (fatal) + return -1; + else + return 0; +} + +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) +{ + int ret = 0; + SSL_SESSION *s; + + /* + * add just 1 reference count for the SSL_CTX's session cache even though + * it has two ways of access: each session is in a doubly linked list and + * an lhash + */ + CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); + /* + * if session c is in already in cache, we take back the increment later + */ + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + s = lh_SSL_SESSION_insert(ctx->sessions, c); + + /* + * s != NULL iff we already had a session with the given PID. In this + * case, s == c should hold (then we did not really modify + * ctx->sessions), or we're in trouble. + */ + if (s != NULL && s != c) { + /* We *are* in trouble ... */ + SSL_SESSION_list_remove(ctx, s); + SSL_SESSION_free(s); + /* + * ... so pretend the other session did not exist in cache (we cannot + * handle two SSL_SESSION structures with identical session ID in the + * same cache, which could happen e.g. when two threads concurrently + * obtain the same session from an external cache) + */ + s = NULL; + } else if (s == NULL && + lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) { + /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */ + + /* + * ... so take back the extra reference and also don't add + * the session to the SSL_SESSION_list at this time + */ + s = c; + } + + /* Put at the head of the queue unless it is already in the cache */ + if (s == NULL) + SSL_SESSION_list_add(ctx, c); + + if (s != NULL) { + /* + * existing cache entry -- decrement previously incremented reference + * count because it already takes into account the cache + */ + + SSL_SESSION_free(s); /* s == c */ + ret = 0; + } else { + /* + * new cache entry -- remove old ones if cache has become too large + */ + + ret = 1; + + if (SSL_CTX_sess_get_cache_size(ctx) > 0) { + while (SSL_CTX_sess_number(ctx) > + SSL_CTX_sess_get_cache_size(ctx)) { + if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) + break; + else + ctx->stats.sess_cache_full++; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return (ret); +} + +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) +{ + return remove_session_lock(ctx, c, 1); +} + +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) +{ + SSL_SESSION *r; + int ret = 0; + + if ((c != NULL) && (c->session_id_length != 0)) { + if (lck) + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { + ret = 1; + r = lh_SSL_SESSION_delete(ctx->sessions, c); + SSL_SESSION_list_remove(ctx, c); + } + + if (lck) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + + if (ret) { + r->not_resumable = 1; + if (ctx->remove_session_cb != NULL) + ctx->remove_session_cb(ctx, r); + SSL_SESSION_free(r); + } + } else + ret = 0; + return (ret); +} + +void SSL_SESSION_free(SSL_SESSION *ss) +{ + int i; + + if (ss == NULL) + return; + + i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); +#ifdef REF_PRINT + REF_PRINT("SSL_SESSION", ss); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "SSL_SESSION_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); + + OPENSSL_cleanse(ss->key_arg, sizeof(ss->key_arg)); + OPENSSL_cleanse(ss->master_key, sizeof(ss->master_key)); + OPENSSL_cleanse(ss->session_id, sizeof(ss->session_id)); + if (ss->sess_cert != NULL) + ssl_sess_cert_free(ss->sess_cert); + if (ss->peer != NULL) + X509_free(ss->peer); + if (ss->ciphers != NULL) + sk_SSL_CIPHER_free(ss->ciphers); +#ifndef OPENSSL_NO_TLSEXT + if (ss->tlsext_hostname != NULL) + OPENSSL_free(ss->tlsext_hostname); + if (ss->tlsext_tick != NULL) + OPENSSL_free(ss->tlsext_tick); +# ifndef OPENSSL_NO_EC + ss->tlsext_ecpointformatlist_length = 0; + if (ss->tlsext_ecpointformatlist != NULL) + OPENSSL_free(ss->tlsext_ecpointformatlist); + ss->tlsext_ellipticcurvelist_length = 0; + if (ss->tlsext_ellipticcurvelist != NULL) + OPENSSL_free(ss->tlsext_ellipticcurvelist); +# endif /* OPENSSL_NO_EC */ +#endif +#ifndef OPENSSL_NO_PSK + if (ss->psk_identity_hint != NULL) + OPENSSL_free(ss->psk_identity_hint); + if (ss->psk_identity != NULL) + OPENSSL_free(ss->psk_identity); +#endif +#ifndef OPENSSL_NO_SRP + if (ss->srp_username != NULL) + OPENSSL_free(ss->srp_username); +#endif + OPENSSL_cleanse(ss, sizeof(*ss)); + OPENSSL_free(ss); +} + +int SSL_set_session(SSL *s, SSL_SESSION *session) +{ + int ret = 0; + const SSL_METHOD *meth; + + if (session != NULL) { + meth = s->ctx->method->get_ssl_method(session->ssl_version); + if (meth == NULL) + meth = s->method->get_ssl_method(session->ssl_version); + if (meth == NULL) { + SSLerr(SSL_F_SSL_SET_SESSION, SSL_R_UNABLE_TO_FIND_SSL_METHOD); + return (0); + } + + if (meth != s->method) { + if (!SSL_set_ssl_method(s, meth)) + return (0); + } +#ifndef OPENSSL_NO_KRB5 + if (s->kssl_ctx && !s->kssl_ctx->client_princ && + session->krb5_client_princ_len > 0) { + s->kssl_ctx->client_princ = + (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); + if (s->kssl_ctx->client_princ == NULL) { + SSLerr(SSL_F_SSL_SET_SESSION, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ, + session->krb5_client_princ_len); + s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; + } +#endif /* OPENSSL_NO_KRB5 */ + + /* CRYPTO_w_lock(CRYPTO_LOCK_SSL); */ + CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); + if (s->session != NULL) + SSL_SESSION_free(s->session); + s->session = session; + s->verify_result = s->session->verify_result; + /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL); */ + ret = 1; + } else { + if (s->session != NULL) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + meth = s->ctx->method; + if (meth != s->method) { + if (!SSL_set_ssl_method(s, meth)) + return (0); + } + ret = 1; + } + return (ret); +} + +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) +{ + if (s == NULL) + return (0); + s->timeout = t; + return (1); +} + +long SSL_SESSION_get_timeout(const SSL_SESSION *s) +{ + if (s == NULL) + return (0); + return (s->timeout); +} + +long SSL_SESSION_get_time(const SSL_SESSION *s) +{ + if (s == NULL) + return (0); + return (s->time); +} + +long SSL_SESSION_set_time(SSL_SESSION *s, long t) +{ + if (s == NULL) + return (0); + s->time = t; + return (t); +} + +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) +{ + return s->peer; +} + +int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { + SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + s->sid_ctx_length = sid_ctx_len; + if (s->sid_ctx != sid_ctx) + memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +long SSL_CTX_set_timeout(SSL_CTX *s, long t) +{ + long l; + if (s == NULL) + return (0); + l = s->session_timeout; + s->session_timeout = t; + return (l); +} + +long SSL_CTX_get_timeout(const SSL_CTX *s) +{ + if (s == NULL) + return (0); + return (s->session_timeout); +} + +#ifndef OPENSSL_NO_TLSEXT +int SSL_set_session_secret_cb(SSL *s, + int (*tls_session_secret_cb) (SSL *s, + void *secret, + int *secret_len, + STACK_OF(SSL_CIPHER) + *peer_ciphers, + SSL_CIPHER + **cipher, + void *arg), + void *arg) +{ + if (s == NULL) + return (0); + s->tls_session_secret_cb = tls_session_secret_cb; + s->tls_session_secret_cb_arg = arg; + return (1); +} + +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg) +{ + if (s == NULL) + return (0); + s->tls_session_ticket_ext_cb = cb; + s->tls_session_ticket_ext_cb_arg = arg; + return (1); +} + +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) +{ + if (s->version >= TLS1_VERSION) { + if (s->tlsext_session_ticket) { + OPENSSL_free(s->tlsext_session_ticket); + s->tlsext_session_ticket = NULL; + } + + s->tlsext_session_ticket = + OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); + if (!s->tlsext_session_ticket) { + SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (ext_data) { + s->tlsext_session_ticket->length = ext_len; + s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; + memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); + } else { + s->tlsext_session_ticket->length = 0; + s->tlsext_session_ticket->data = NULL; + } + + return 1; + } + + return 0; +} +#endif /* OPENSSL_NO_TLSEXT */ + +typedef struct timeout_param_st { + SSL_CTX *ctx; + long time; + LHASH_OF(SSL_SESSION) *cache; +} TIMEOUT_PARAM; + +static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) +{ + if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */ + /* + * The reason we don't call SSL_CTX_remove_session() is to save on + * locking overhead + */ + (void)lh_SSL_SESSION_delete(p->cache, s); + SSL_SESSION_list_remove(p->ctx, s); + s->not_resumable = 1; + if (p->ctx->remove_session_cb != NULL) + p->ctx->remove_session_cb(p->ctx, s); + SSL_SESSION_free(s); + } +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM) + +void SSL_CTX_flush_sessions(SSL_CTX *s, long t) +{ + unsigned long i; + TIMEOUT_PARAM tp; + + tp.ctx = s; + tp.cache = s->sessions; + if (tp.cache == NULL) + return; + tp.time = t; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; + lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), + TIMEOUT_PARAM, &tp); + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); +} + +int ssl_clear_bad_session(SSL *s) +{ + if ((s->session != NULL) && + !(s->shutdown & SSL_SENT_SHUTDOWN) && + !(SSL_in_init(s) || SSL_in_before(s))) { + SSL_CTX_remove_session(s->session_ctx, s->session); + return (1); + } else + return (0); +} + +/* locked by SSL_CTX in the calling function */ +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) +{ + if ((s->next == NULL) || (s->prev == NULL)) + return; + + if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { + /* last element in list */ + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { + /* only one element in list */ + ctx->session_cache_head = NULL; + ctx->session_cache_tail = NULL; + } else { + ctx->session_cache_tail = s->prev; + s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } + } else { + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { + /* first element in list */ + ctx->session_cache_head = s->next; + s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); + } else { + /* middle of list */ + s->next->prev = s->prev; + s->prev->next = s->next; + } + } + s->prev = s->next = NULL; +} + +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) +{ + if ((s->next != NULL) && (s->prev != NULL)) + SSL_SESSION_list_remove(ctx, s); + + if (ctx->session_cache_head == NULL) { + ctx->session_cache_head = s; + ctx->session_cache_tail = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + s->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } else { + s->next = ctx->session_cache_head; + s->next->prev = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = s; + } +} + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*cb) (struct ssl_st *ssl, + SSL_SESSION *sess)) +{ + ctx->new_session_cb = cb; +} + +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) { + return ctx->new_session_cb; +} + +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess)) +{ + ctx->remove_session_cb = cb; +} + +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx, + SSL_SESSION *sess) { + return ctx->remove_session_cb; +} + +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*cb) (struct ssl_st *ssl, + unsigned char *data, int len, + int *copy)) +{ + ctx->get_session_cb = cb; +} + +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl, + unsigned char *data, + int len, int *copy) { + return ctx->get_session_cb; +} + +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, int val)) +{ + ctx->info_callback = cb; +} + +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val) { + return ctx->info_callback; +} + +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)) +{ + ctx->client_cert_cb = cb; +} + +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey) { + return ctx->client_cert_cb; +} + +#ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) +{ + if (!ENGINE_init(e)) { + SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB); + return 0; + } + if (!ENGINE_get_ssl_client_cert_function(e)) { + SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, + SSL_R_NO_CLIENT_CERT_METHOD); + ENGINE_finish(e); + return 0; + } + ctx->client_cert_engine = e; + return 1; +} +#endif + +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + unsigned char *cookie, + unsigned int *cookie_len)) +{ + ctx->app_gen_cookie_cb = cb; +} + +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, unsigned char *cookie, + unsigned int cookie_len)) +{ + ctx->app_verify_cookie_cb = cb; +} + +IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, + SSL_SESSION) +/* ssl/ssl_stat.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +// #include "ssl_locl.h" + +const char *SSL_state_string_long(const SSL *s) +{ + const char *str; + + switch (s->state) { + case SSL_ST_BEFORE: + str = "before SSL initialization"; + break; + case SSL_ST_ACCEPT: + str = "before accept initialization"; + break; + case SSL_ST_CONNECT: + str = "before connect initialization"; + break; + case SSL_ST_OK: + str = "SSL negotiation finished successfully"; + break; + case SSL_ST_RENEGOTIATE: + str = "SSL renegotiate ciphers"; + break; + case SSL_ST_BEFORE | SSL_ST_CONNECT: + str = "before/connect initialization"; + break; + case SSL_ST_OK | SSL_ST_CONNECT: + str = "ok/connect SSL initialization"; + break; + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + str = "before/accept initialization"; + break; + case SSL_ST_OK | SSL_ST_ACCEPT: + str = "ok/accept SSL initialization"; + break; + case SSL_ST_ERR: + str = "error"; + break; +#ifndef OPENSSL_NO_SSL2 + case SSL2_ST_CLIENT_START_ENCRYPTION: + str = "SSLv2 client start encryption"; + break; + case SSL2_ST_SERVER_START_ENCRYPTION: + str = "SSLv2 server start encryption"; + break; + case SSL2_ST_SEND_CLIENT_HELLO_A: + str = "SSLv2 write client hello A"; + break; + case SSL2_ST_SEND_CLIENT_HELLO_B: + str = "SSLv2 write client hello B"; + break; + case SSL2_ST_GET_SERVER_HELLO_A: + str = "SSLv2 read server hello A"; + break; + case SSL2_ST_GET_SERVER_HELLO_B: + str = "SSLv2 read server hello B"; + break; + case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: + str = "SSLv2 write client master key A"; + break; + case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: + str = "SSLv2 write client master key B"; + break; + case SSL2_ST_SEND_CLIENT_FINISHED_A: + str = "SSLv2 write client finished A"; + break; + case SSL2_ST_SEND_CLIENT_FINISHED_B: + str = "SSLv2 write client finished B"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: + str = "SSLv2 write client certificate A"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: + str = "SSLv2 write client certificate B"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: + str = "SSLv2 write client certificate C"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: + str = "SSLv2 write client certificate D"; + break; + case SSL2_ST_GET_SERVER_VERIFY_A: + str = "SSLv2 read server verify A"; + break; + case SSL2_ST_GET_SERVER_VERIFY_B: + str = "SSLv2 read server verify B"; + break; + case SSL2_ST_GET_SERVER_FINISHED_A: + str = "SSLv2 read server finished A"; + break; + case SSL2_ST_GET_SERVER_FINISHED_B: + str = "SSLv2 read server finished B"; + break; + case SSL2_ST_GET_CLIENT_HELLO_A: + str = "SSLv2 read client hello A"; + break; + case SSL2_ST_GET_CLIENT_HELLO_B: + str = "SSLv2 read client hello B"; + break; + case SSL2_ST_GET_CLIENT_HELLO_C: + str = "SSLv2 read client hello C"; + break; + case SSL2_ST_SEND_SERVER_HELLO_A: + str = "SSLv2 write server hello A"; + break; + case SSL2_ST_SEND_SERVER_HELLO_B: + str = "SSLv2 write server hello B"; + break; + case SSL2_ST_GET_CLIENT_MASTER_KEY_A: + str = "SSLv2 read client master key A"; + break; + case SSL2_ST_GET_CLIENT_MASTER_KEY_B: + str = "SSLv2 read client master key B"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_A: + str = "SSLv2 write server verify A"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_B: + str = "SSLv2 write server verify B"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_C: + str = "SSLv2 write server verify C"; + break; + case SSL2_ST_GET_CLIENT_FINISHED_A: + str = "SSLv2 read client finished A"; + break; + case SSL2_ST_GET_CLIENT_FINISHED_B: + str = "SSLv2 read client finished B"; + break; + case SSL2_ST_SEND_SERVER_FINISHED_A: + str = "SSLv2 write server finished A"; + break; + case SSL2_ST_SEND_SERVER_FINISHED_B: + str = "SSLv2 write server finished B"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: + str = "SSLv2 write request certificate A"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: + str = "SSLv2 write request certificate B"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: + str = "SSLv2 write request certificate C"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: + str = "SSLv2 write request certificate D"; + break; + case SSL2_ST_X509_GET_SERVER_CERTIFICATE: + str = "SSLv2 X509 read server certificate"; + break; + case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: + str = "SSLv2 X509 read client certificate"; + break; +#endif + +#ifndef OPENSSL_NO_SSL3 +/* SSLv3 additions */ + case SSL3_ST_CW_CLNT_HELLO_A: + str = "SSLv3 write client hello A"; + break; + case SSL3_ST_CW_CLNT_HELLO_B: + str = "SSLv3 write client hello B"; + break; + case SSL3_ST_CR_SRVR_HELLO_A: + str = "SSLv3 read server hello A"; + break; + case SSL3_ST_CR_SRVR_HELLO_B: + str = "SSLv3 read server hello B"; + break; + case SSL3_ST_CR_CERT_A: + str = "SSLv3 read server certificate A"; + break; + case SSL3_ST_CR_CERT_B: + str = "SSLv3 read server certificate B"; + break; + case SSL3_ST_CR_KEY_EXCH_A: + str = "SSLv3 read server key exchange A"; + break; + case SSL3_ST_CR_KEY_EXCH_B: + str = "SSLv3 read server key exchange B"; + break; + case SSL3_ST_CR_CERT_REQ_A: + str = "SSLv3 read server certificate request A"; + break; + case SSL3_ST_CR_CERT_REQ_B: + str = "SSLv3 read server certificate request B"; + break; + case SSL3_ST_CR_SESSION_TICKET_A: + str = "SSLv3 read server session ticket A"; + break; + case SSL3_ST_CR_SESSION_TICKET_B: + str = "SSLv3 read server session ticket B"; + break; + case SSL3_ST_CR_SRVR_DONE_A: + str = "SSLv3 read server done A"; + break; + case SSL3_ST_CR_SRVR_DONE_B: + str = "SSLv3 read server done B"; + break; + case SSL3_ST_CW_CERT_A: + str = "SSLv3 write client certificate A"; + break; + case SSL3_ST_CW_CERT_B: + str = "SSLv3 write client certificate B"; + break; + case SSL3_ST_CW_CERT_C: + str = "SSLv3 write client certificate C"; + break; + case SSL3_ST_CW_CERT_D: + str = "SSLv3 write client certificate D"; + break; + case SSL3_ST_CW_KEY_EXCH_A: + str = "SSLv3 write client key exchange A"; + break; + case SSL3_ST_CW_KEY_EXCH_B: + str = "SSLv3 write client key exchange B"; + break; + case SSL3_ST_CW_CERT_VRFY_A: + str = "SSLv3 write certificate verify A"; + break; + case SSL3_ST_CW_CERT_VRFY_B: + str = "SSLv3 write certificate verify B"; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_SW_CHANGE_A: + str = "SSLv3 write change cipher spec A"; + break; + case SSL3_ST_CW_CHANGE_B: + case SSL3_ST_SW_CHANGE_B: + str = "SSLv3 write change cipher spec B"; + break; + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_SW_FINISHED_A: + str = "SSLv3 write finished A"; + break; + case SSL3_ST_CW_FINISHED_B: + case SSL3_ST_SW_FINISHED_B: + str = "SSLv3 write finished B"; + break; + case SSL3_ST_CR_CHANGE_A: + case SSL3_ST_SR_CHANGE_A: + str = "SSLv3 read change cipher spec A"; + break; + case SSL3_ST_CR_CHANGE_B: + case SSL3_ST_SR_CHANGE_B: + str = "SSLv3 read change cipher spec B"; + break; + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_SR_FINISHED_A: + str = "SSLv3 read finished A"; + break; + case SSL3_ST_CR_FINISHED_B: + case SSL3_ST_SR_FINISHED_B: + str = "SSLv3 read finished B"; + break; + + case SSL3_ST_CW_FLUSH: + case SSL3_ST_SW_FLUSH: + str = "SSLv3 flush data"; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + str = "SSLv3 read client hello A"; + break; + case SSL3_ST_SR_CLNT_HELLO_B: + str = "SSLv3 read client hello B"; + break; + case SSL3_ST_SR_CLNT_HELLO_C: + str = "SSLv3 read client hello C"; + break; + case SSL3_ST_SW_HELLO_REQ_A: + str = "SSLv3 write hello request A"; + break; + case SSL3_ST_SW_HELLO_REQ_B: + str = "SSLv3 write hello request B"; + break; + case SSL3_ST_SW_HELLO_REQ_C: + str = "SSLv3 write hello request C"; + break; + case SSL3_ST_SW_SRVR_HELLO_A: + str = "SSLv3 write server hello A"; + break; + case SSL3_ST_SW_SRVR_HELLO_B: + str = "SSLv3 write server hello B"; + break; + case SSL3_ST_SW_CERT_A: + str = "SSLv3 write certificate A"; + break; + case SSL3_ST_SW_CERT_B: + str = "SSLv3 write certificate B"; + break; + case SSL3_ST_SW_KEY_EXCH_A: + str = "SSLv3 write key exchange A"; + break; + case SSL3_ST_SW_KEY_EXCH_B: + str = "SSLv3 write key exchange B"; + break; + case SSL3_ST_SW_CERT_REQ_A: + str = "SSLv3 write certificate request A"; + break; + case SSL3_ST_SW_CERT_REQ_B: + str = "SSLv3 write certificate request B"; + break; + case SSL3_ST_SW_SESSION_TICKET_A: + str = "SSLv3 write session ticket A"; + break; + case SSL3_ST_SW_SESSION_TICKET_B: + str = "SSLv3 write session ticket B"; + break; + case SSL3_ST_SW_SRVR_DONE_A: + str = "SSLv3 write server done A"; + break; + case SSL3_ST_SW_SRVR_DONE_B: + str = "SSLv3 write server done B"; + break; + case SSL3_ST_SR_CERT_A: + str = "SSLv3 read client certificate A"; + break; + case SSL3_ST_SR_CERT_B: + str = "SSLv3 read client certificate B"; + break; + case SSL3_ST_SR_KEY_EXCH_A: + str = "SSLv3 read client key exchange A"; + break; + case SSL3_ST_SR_KEY_EXCH_B: + str = "SSLv3 read client key exchange B"; + break; + case SSL3_ST_SR_CERT_VRFY_A: + str = "SSLv3 read certificate verify A"; + break; + case SSL3_ST_SR_CERT_VRFY_B: + str = "SSLv3 read certificate verify B"; + break; +#endif + +/* SSLv2/v3 compatibility states */ +/* client */ + case SSL23_ST_CW_CLNT_HELLO_A: + str = "SSLv2/v3 write client hello A"; + break; + case SSL23_ST_CW_CLNT_HELLO_B: + str = "SSLv2/v3 write client hello B"; + break; + case SSL23_ST_CR_SRVR_HELLO_A: + str = "SSLv2/v3 read server hello A"; + break; + case SSL23_ST_CR_SRVR_HELLO_B: + str = "SSLv2/v3 read server hello B"; + break; +/* server */ + case SSL23_ST_SR_CLNT_HELLO_A: + str = "SSLv2/v3 read client hello A"; + break; + case SSL23_ST_SR_CLNT_HELLO_B: + str = "SSLv2/v3 read client hello B"; + break; + +/* DTLS */ + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + str = "DTLS1 read hello verify request A"; + break; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + str = "DTLS1 read hello verify request B"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + str = "DTLS1 write hello verify request A"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + str = "DTLS1 write hello verify request B"; + break; + + default: + str = "unknown state"; + break; + } + return (str); +} + +const char *SSL_rstate_string_long(const SSL *s) +{ + const char *str; + + switch (s->rstate) { + case SSL_ST_READ_HEADER: + str = "read header"; + break; + case SSL_ST_READ_BODY: + str = "read body"; + break; + case SSL_ST_READ_DONE: + str = "read done"; + break; + default: + str = "unknown"; + break; + } + return (str); +} + +const char *SSL_state_string(const SSL *s) +{ + const char *str; + + switch (s->state) { + case SSL_ST_BEFORE: + str = "PINIT "; + break; + case SSL_ST_ACCEPT: + str = "AINIT "; + break; + case SSL_ST_CONNECT: + str = "CINIT "; + break; + case SSL_ST_OK: + str = "SSLOK "; + break; + case SSL_ST_ERR: + str = "SSLERR"; + break; +#ifndef OPENSSL_NO_SSL2 + case SSL2_ST_CLIENT_START_ENCRYPTION: + str = "2CSENC"; + break; + case SSL2_ST_SERVER_START_ENCRYPTION: + str = "2SSENC"; + break; + case SSL2_ST_SEND_CLIENT_HELLO_A: + str = "2SCH_A"; + break; + case SSL2_ST_SEND_CLIENT_HELLO_B: + str = "2SCH_B"; + break; + case SSL2_ST_GET_SERVER_HELLO_A: + str = "2GSH_A"; + break; + case SSL2_ST_GET_SERVER_HELLO_B: + str = "2GSH_B"; + break; + case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: + str = "2SCMKA"; + break; + case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: + str = "2SCMKB"; + break; + case SSL2_ST_SEND_CLIENT_FINISHED_A: + str = "2SCF_A"; + break; + case SSL2_ST_SEND_CLIENT_FINISHED_B: + str = "2SCF_B"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: + str = "2SCC_A"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: + str = "2SCC_B"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: + str = "2SCC_C"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: + str = "2SCC_D"; + break; + case SSL2_ST_GET_SERVER_VERIFY_A: + str = "2GSV_A"; + break; + case SSL2_ST_GET_SERVER_VERIFY_B: + str = "2GSV_B"; + break; + case SSL2_ST_GET_SERVER_FINISHED_A: + str = "2GSF_A"; + break; + case SSL2_ST_GET_SERVER_FINISHED_B: + str = "2GSF_B"; + break; + case SSL2_ST_GET_CLIENT_HELLO_A: + str = "2GCH_A"; + break; + case SSL2_ST_GET_CLIENT_HELLO_B: + str = "2GCH_B"; + break; + case SSL2_ST_GET_CLIENT_HELLO_C: + str = "2GCH_C"; + break; + case SSL2_ST_SEND_SERVER_HELLO_A: + str = "2SSH_A"; + break; + case SSL2_ST_SEND_SERVER_HELLO_B: + str = "2SSH_B"; + break; + case SSL2_ST_GET_CLIENT_MASTER_KEY_A: + str = "2GCMKA"; + break; + case SSL2_ST_GET_CLIENT_MASTER_KEY_B: + str = "2GCMKA"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_A: + str = "2SSV_A"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_B: + str = "2SSV_B"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_C: + str = "2SSV_C"; + break; + case SSL2_ST_GET_CLIENT_FINISHED_A: + str = "2GCF_A"; + break; + case SSL2_ST_GET_CLIENT_FINISHED_B: + str = "2GCF_B"; + break; + case SSL2_ST_SEND_SERVER_FINISHED_A: + str = "2SSF_A"; + break; + case SSL2_ST_SEND_SERVER_FINISHED_B: + str = "2SSF_B"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: + str = "2SRC_A"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: + str = "2SRC_B"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: + str = "2SRC_C"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: + str = "2SRC_D"; + break; + case SSL2_ST_X509_GET_SERVER_CERTIFICATE: + str = "2X9GSC"; + break; + case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: + str = "2X9GCC"; + break; +#endif + +#ifndef OPENSSL_NO_SSL3 +/* SSLv3 additions */ + case SSL3_ST_SW_FLUSH: + case SSL3_ST_CW_FLUSH: + str = "3FLUSH"; + break; + case SSL3_ST_CW_CLNT_HELLO_A: + str = "3WCH_A"; + break; + case SSL3_ST_CW_CLNT_HELLO_B: + str = "3WCH_B"; + break; + case SSL3_ST_CR_SRVR_HELLO_A: + str = "3RSH_A"; + break; + case SSL3_ST_CR_SRVR_HELLO_B: + str = "3RSH_B"; + break; + case SSL3_ST_CR_CERT_A: + str = "3RSC_A"; + break; + case SSL3_ST_CR_CERT_B: + str = "3RSC_B"; + break; + case SSL3_ST_CR_KEY_EXCH_A: + str = "3RSKEA"; + break; + case SSL3_ST_CR_KEY_EXCH_B: + str = "3RSKEB"; + break; + case SSL3_ST_CR_CERT_REQ_A: + str = "3RCR_A"; + break; + case SSL3_ST_CR_CERT_REQ_B: + str = "3RCR_B"; + break; + case SSL3_ST_CR_SRVR_DONE_A: + str = "3RSD_A"; + break; + case SSL3_ST_CR_SRVR_DONE_B: + str = "3RSD_B"; + break; + case SSL3_ST_CW_CERT_A: + str = "3WCC_A"; + break; + case SSL3_ST_CW_CERT_B: + str = "3WCC_B"; + break; + case SSL3_ST_CW_CERT_C: + str = "3WCC_C"; + break; + case SSL3_ST_CW_CERT_D: + str = "3WCC_D"; + break; + case SSL3_ST_CW_KEY_EXCH_A: + str = "3WCKEA"; + break; + case SSL3_ST_CW_KEY_EXCH_B: + str = "3WCKEB"; + break; + case SSL3_ST_CW_CERT_VRFY_A: + str = "3WCV_A"; + break; + case SSL3_ST_CW_CERT_VRFY_B: + str = "3WCV_B"; + break; + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_CW_CHANGE_A: + str = "3WCCSA"; + break; + case SSL3_ST_SW_CHANGE_B: + case SSL3_ST_CW_CHANGE_B: + str = "3WCCSB"; + break; + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_CW_FINISHED_A: + str = "3WFINA"; + break; + case SSL3_ST_SW_FINISHED_B: + case SSL3_ST_CW_FINISHED_B: + str = "3WFINB"; + break; + case SSL3_ST_SR_CHANGE_A: + case SSL3_ST_CR_CHANGE_A: + str = "3RCCSA"; + break; + case SSL3_ST_SR_CHANGE_B: + case SSL3_ST_CR_CHANGE_B: + str = "3RCCSB"; + break; + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_CR_FINISHED_A: + str = "3RFINA"; + break; + case SSL3_ST_SR_FINISHED_B: + case SSL3_ST_CR_FINISHED_B: + str = "3RFINB"; + break; + + case SSL3_ST_SW_HELLO_REQ_A: + str = "3WHR_A"; + break; + case SSL3_ST_SW_HELLO_REQ_B: + str = "3WHR_B"; + break; + case SSL3_ST_SW_HELLO_REQ_C: + str = "3WHR_C"; + break; + case SSL3_ST_SR_CLNT_HELLO_A: + str = "3RCH_A"; + break; + case SSL3_ST_SR_CLNT_HELLO_B: + str = "3RCH_B"; + break; + case SSL3_ST_SR_CLNT_HELLO_C: + str = "3RCH_C"; + break; + case SSL3_ST_SW_SRVR_HELLO_A: + str = "3WSH_A"; + break; + case SSL3_ST_SW_SRVR_HELLO_B: + str = "3WSH_B"; + break; + case SSL3_ST_SW_CERT_A: + str = "3WSC_A"; + break; + case SSL3_ST_SW_CERT_B: + str = "3WSC_B"; + break; + case SSL3_ST_SW_KEY_EXCH_A: + str = "3WSKEA"; + break; + case SSL3_ST_SW_KEY_EXCH_B: + str = "3WSKEB"; + break; + case SSL3_ST_SW_CERT_REQ_A: + str = "3WCR_A"; + break; + case SSL3_ST_SW_CERT_REQ_B: + str = "3WCR_B"; + break; + case SSL3_ST_SW_SRVR_DONE_A: + str = "3WSD_A"; + break; + case SSL3_ST_SW_SRVR_DONE_B: + str = "3WSD_B"; + break; + case SSL3_ST_SR_CERT_A: + str = "3RCC_A"; + break; + case SSL3_ST_SR_CERT_B: + str = "3RCC_B"; + break; + case SSL3_ST_SR_KEY_EXCH_A: + str = "3RCKEA"; + break; + case SSL3_ST_SR_KEY_EXCH_B: + str = "3RCKEB"; + break; + case SSL3_ST_SR_CERT_VRFY_A: + str = "3RCV_A"; + break; + case SSL3_ST_SR_CERT_VRFY_B: + str = "3RCV_B"; + break; +#endif + +/* SSLv2/v3 compatibility states */ +/* client */ + case SSL23_ST_CW_CLNT_HELLO_A: + str = "23WCHA"; + break; + case SSL23_ST_CW_CLNT_HELLO_B: + str = "23WCHB"; + break; + case SSL23_ST_CR_SRVR_HELLO_A: + str = "23RSHA"; + break; + case SSL23_ST_CR_SRVR_HELLO_B: + str = "23RSHA"; + break; +/* server */ + case SSL23_ST_SR_CLNT_HELLO_A: + str = "23RCHA"; + break; + case SSL23_ST_SR_CLNT_HELLO_B: + str = "23RCHB"; + break; + +/* DTLS */ + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + str = "DRCHVA"; + break; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + str = "DRCHVB"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + str = "DWCHVA"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + str = "DWCHVB"; + break; + + default: + str = "UNKWN "; + break; + } + return (str); +} + +const char *SSL_alert_type_string_long(int value) +{ + value >>= 8; + if (value == SSL3_AL_WARNING) + return ("warning"); + else if (value == SSL3_AL_FATAL) + return ("fatal"); + else + return ("unknown"); +} + +const char *SSL_alert_type_string(int value) +{ + value >>= 8; + if (value == SSL3_AL_WARNING) + return ("W"); + else if (value == SSL3_AL_FATAL) + return ("F"); + else + return ("U"); +} + +const char *SSL_alert_desc_string(int value) +{ + const char *str; + + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + str = "CN"; + break; + case SSL3_AD_UNEXPECTED_MESSAGE: + str = "UM"; + break; + case SSL3_AD_BAD_RECORD_MAC: + str = "BM"; + break; + case SSL3_AD_DECOMPRESSION_FAILURE: + str = "DF"; + break; + case SSL3_AD_HANDSHAKE_FAILURE: + str = "HF"; + break; + case SSL3_AD_NO_CERTIFICATE: + str = "NC"; + break; + case SSL3_AD_BAD_CERTIFICATE: + str = "BC"; + break; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + str = "UC"; + break; + case SSL3_AD_CERTIFICATE_REVOKED: + str = "CR"; + break; + case SSL3_AD_CERTIFICATE_EXPIRED: + str = "CE"; + break; + case SSL3_AD_CERTIFICATE_UNKNOWN: + str = "CU"; + break; + case SSL3_AD_ILLEGAL_PARAMETER: + str = "IP"; + break; + case TLS1_AD_DECRYPTION_FAILED: + str = "DC"; + break; + case TLS1_AD_RECORD_OVERFLOW: + str = "RO"; + break; + case TLS1_AD_UNKNOWN_CA: + str = "CA"; + break; + case TLS1_AD_ACCESS_DENIED: + str = "AD"; + break; + case TLS1_AD_DECODE_ERROR: + str = "DE"; + break; + case TLS1_AD_DECRYPT_ERROR: + str = "CY"; + break; + case TLS1_AD_EXPORT_RESTRICTION: + str = "ER"; + break; + case TLS1_AD_PROTOCOL_VERSION: + str = "PV"; + break; + case TLS1_AD_INSUFFICIENT_SECURITY: + str = "IS"; + break; + case TLS1_AD_INTERNAL_ERROR: + str = "IE"; + break; + case TLS1_AD_USER_CANCELLED: + str = "US"; + break; + case TLS1_AD_NO_RENEGOTIATION: + str = "NR"; + break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str = "UE"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str = "CO"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str = "UN"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "BR"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "BH"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str = "UP"; + break; + default: + str = "UK"; + break; + } + return (str); +} + +const char *SSL_alert_desc_string_long(int value) +{ + const char *str; + + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + str = "close notify"; + break; + case SSL3_AD_UNEXPECTED_MESSAGE: + str = "unexpected_message"; + break; + case SSL3_AD_BAD_RECORD_MAC: + str = "bad record mac"; + break; + case SSL3_AD_DECOMPRESSION_FAILURE: + str = "decompression failure"; + break; + case SSL3_AD_HANDSHAKE_FAILURE: + str = "handshake failure"; + break; + case SSL3_AD_NO_CERTIFICATE: + str = "no certificate"; + break; + case SSL3_AD_BAD_CERTIFICATE: + str = "bad certificate"; + break; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + str = "unsupported certificate"; + break; + case SSL3_AD_CERTIFICATE_REVOKED: + str = "certificate revoked"; + break; + case SSL3_AD_CERTIFICATE_EXPIRED: + str = "certificate expired"; + break; + case SSL3_AD_CERTIFICATE_UNKNOWN: + str = "certificate unknown"; + break; + case SSL3_AD_ILLEGAL_PARAMETER: + str = "illegal parameter"; + break; + case TLS1_AD_DECRYPTION_FAILED: + str = "decryption failed"; + break; + case TLS1_AD_RECORD_OVERFLOW: + str = "record overflow"; + break; + case TLS1_AD_UNKNOWN_CA: + str = "unknown CA"; + break; + case TLS1_AD_ACCESS_DENIED: + str = "access denied"; + break; + case TLS1_AD_DECODE_ERROR: + str = "decode error"; + break; + case TLS1_AD_DECRYPT_ERROR: + str = "decrypt error"; + break; + case TLS1_AD_EXPORT_RESTRICTION: + str = "export restriction"; + break; + case TLS1_AD_PROTOCOL_VERSION: + str = "protocol version"; + break; + case TLS1_AD_INSUFFICIENT_SECURITY: + str = "insufficient security"; + break; + case TLS1_AD_INTERNAL_ERROR: + str = "internal error"; + break; + case TLS1_AD_USER_CANCELLED: + str = "user canceled"; + break; + case TLS1_AD_NO_RENEGOTIATION: + str = "no renegotiation"; + break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str = "unsupported extension"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str = "certificate unobtainable"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str = "unrecognized name"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "bad certificate status response"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "bad certificate hash value"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str = "unknown PSK identity"; + break; + default: + str = "unknown"; + break; + } + return (str); +} + +const char *SSL_rstate_string(const SSL *s) +{ + const char *str; + + switch (s->rstate) { + case SSL_ST_READ_HEADER: + str = "RH"; + break; + case SSL_ST_READ_BODY: + str = "RB"; + break; + case SSL_ST_READ_DONE: + str = "RD"; + break; + default: + str = "unknown"; + break; + } + return (str); +} +/* ssl/ssl_txt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include "buffer.h" +// #include "ssl_locl.h" + +#ifndef OPENSSL_NO_FP_API +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file_internal())) == NULL) { + SSLerr(SSL_F_SSL_SESSION_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = SSL_SESSION_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) +{ + unsigned int i; + const char *s; + + if (x == NULL) + goto err; + if (BIO_puts(bp, "SSL-Session:\n") <= 0) + goto err; + if (x->ssl_version == SSL2_VERSION) + s = "SSLv2"; + else if (x->ssl_version == SSL3_VERSION) + s = "SSLv3"; + else if (x->ssl_version == TLS1_2_VERSION) + s = "TLSv1.2"; + else if (x->ssl_version == TLS1_1_VERSION) + s = "TLSv1.1"; + else if (x->ssl_version == TLS1_VERSION) + s = "TLSv1"; + else if (x->ssl_version == DTLS1_VERSION) + s = "DTLSv1"; + else if (x->ssl_version == DTLS1_2_VERSION) + s = "DTLSv1.2"; + else if (x->ssl_version == DTLS1_BAD_VER) + s = "DTLSv1-bad"; + else + s = "unknown"; + if (BIO_printf(bp, " Protocol : %s\n", s) <= 0) + goto err; + + if (x->cipher == NULL) { + if (((x->cipher_id) & 0xff000000) == 0x02000000) { + if (BIO_printf + (bp, " Cipher : %06lX\n", x->cipher_id & 0xffffff) <= 0) + goto err; + } else { + if (BIO_printf + (bp, " Cipher : %04lX\n", x->cipher_id & 0xffff) <= 0) + goto err; + } + } else { + if (BIO_printf + (bp, " Cipher : %s\n", + ((x->cipher == NULL) ? "unknown" : x->cipher->name)) <= 0) + goto err; + } + if (BIO_puts(bp, " Session-ID: ") <= 0) + goto err; + for (i = 0; i < x->session_id_length; i++) { + if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0) + goto err; + } + if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0) + goto err; + for (i = 0; i < x->sid_ctx_length; i++) { + if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) + goto err; + } + if (BIO_puts(bp, "\n Master-Key: ") <= 0) + goto err; + for (i = 0; i < (unsigned int)x->master_key_length; i++) { + if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0) + goto err; + } + if (BIO_puts(bp, "\n Key-Arg : ") <= 0) + goto err; + if (x->key_arg_length == 0) { + if (BIO_puts(bp, "None") <= 0) + goto err; + } else + for (i = 0; i < x->key_arg_length; i++) { + if (BIO_printf(bp, "%02X", x->key_arg[i]) <= 0) + goto err; + } +#ifndef OPENSSL_NO_KRB5 + if (BIO_puts(bp, "\n Krb5 Principal: ") <= 0) + goto err; + if (x->krb5_client_princ_len == 0) { + if (BIO_puts(bp, "None") <= 0) + goto err; + } else + for (i = 0; i < x->krb5_client_princ_len; i++) { + if (BIO_printf(bp, "%02X", x->krb5_client_princ[i]) <= 0) + goto err; + } +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + if (BIO_puts(bp, "\n PSK identity: ") <= 0) + goto err; + if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) + goto err; + if (BIO_puts(bp, "\n PSK identity hint: ") <= 0) + goto err; + if (BIO_printf + (bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) + goto err; +#endif +#ifndef OPENSSL_NO_SRP + if (BIO_puts(bp, "\n SRP username: ") <= 0) + goto err; + if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) + goto err; +#endif +#ifndef OPENSSL_NO_TLSEXT + if (x->tlsext_tick_lifetime_hint) { + if (BIO_printf(bp, + "\n TLS session ticket lifetime hint: %ld (seconds)", + x->tlsext_tick_lifetime_hint) <= 0) + goto err; + } + if (x->tlsext_tick) { + if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0) + goto err; + if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) + <= 0) + goto err; + } +#endif + +#ifndef OPENSSL_NO_COMP + if (x->compress_meth != 0) { + SSL_COMP *comp = NULL; + + ssl_cipher_get_evp(x, NULL, NULL, NULL, NULL, &comp); + if (comp == NULL) { + if (BIO_printf(bp, "\n Compression: %d", x->compress_meth) <= + 0) + goto err; + } else { + if (BIO_printf + (bp, "\n Compression: %d (%s)", comp->id, + comp->method->name) <= 0) + goto err; + } + } +#endif + if (x->time != 0L) { + if (BIO_printf(bp, "\n Start Time: %ld", x->time) <= 0) + goto err; + } + if (x->timeout != 0L) { + if (BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0) + goto err; + } + if (BIO_puts(bp, "\n") <= 0) + goto err; + + if (BIO_puts(bp, " Verify return code: ") <= 0) + goto err; + if (BIO_printf(bp, "%ld (%s)\n", x->verify_result, + X509_verify_cert_error_string(x->verify_result)) <= 0) + goto err; + + return (1); + err: + return (0); +} +/* ssl_utst.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "ssl_locl.h" + +#ifndef OPENSSL_NO_UNIT_TEST + +static const struct openssl_ssl_test_functions ssl_test_functions = { + ssl_init_wbio_buffer, + ssl3_setup_buffers, + tls1_process_heartbeat, + dtls1_process_heartbeat +}; + +const struct openssl_ssl_test_functions *SSL_test_functions(void) +{ + return &ssl_test_functions; +} + +#endif diff --git a/Sources/COpenSSL/ssl_locl.h b/Sources/COpenSSL/ssl_locl.h new file mode 100644 index 00000000..0365e267 --- /dev/null +++ b/Sources/COpenSSL/ssl_locl.h @@ -0,0 +1,1499 @@ +/* ssl/ssl_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_LOCL_H +# define HEADER_SSL_LOCL_H +# include +# include +# include +# include + +# include "e_os.h" + +# include "buffer.h" +# ifndef OPENSSL_NO_COMP +# include "comp.h" +# endif +# include "bio.h" +# include "stack.h" +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif +# ifndef OPENSSL_NO_DSA +# include "dsa.h" +# endif +# include "err.h" +# include "ssl.h" +# include "symhacks.h" + +# ifdef OPENSSL_BUILD_SHLIBSSL +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +# undef PKCS1_CHECK + +# define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24)) + +/* NOTE - c is not incremented as per c2l */ +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff)) + +# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \ + l|=((unsigned long)(*((c)++)))<<16, \ + l|=((unsigned long)(*((c)++)))<< 8, \ + l|=((unsigned long)(*((c)++)))) + +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \ + l|=((BN_ULLONG)(*((c)++)))<<32, \ + l|=((BN_ULLONG)(*((c)++)))<<24, \ + l|=((BN_ULLONG)(*((c)++)))<<16, \ + l|=((BN_ULLONG)(*((c)++)))<< 8, \ + l|=((BN_ULLONG)(*((c)++)))) + +/* NOTE - c is not incremented as per l2c */ +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +# define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \ + (((unsigned int)(c[1])) )),c+=2) +# define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \ + c[1]=(unsigned char)(((s) )&0xff)),c+=2) + +# define n2l3(c,l) ((l =(((unsigned long)(c[0]))<<16)| \ + (((unsigned long)(c[1]))<< 8)| \ + (((unsigned long)(c[2])) )),c+=3) + +# define l2n3(l,c) ((c[0]=(unsigned char)(((l)>>16)&0xff), \ + c[1]=(unsigned char)(((l)>> 8)&0xff), \ + c[2]=(unsigned char)(((l) )&0xff)),c+=3) + +# define SSL_MAX_2_BYTE_LEN (0xffff) + +/* LOCAL STUFF */ + +# define SSL_DECRYPT 0 +# define SSL_ENCRYPT 1 + +# define TWO_BYTE_BIT 0x80 +# define SEC_ESC_BIT 0x40 +# define TWO_BYTE_MASK 0x7fff +# define THREE_BYTE_MASK 0x3fff + +# define INC32(a) ((a)=((a)+1)&0xffffffffL) +# define DEC32(a) ((a)=((a)-1)&0xffffffffL) +# define MAX_MAC_SIZE 20 /* up from 16 for SSLv3 */ + +/* + * Define the Bitmasks for SSL_CIPHER.algorithms. + * This bits are used packed as dense as possible. If new methods/ciphers + * etc will be added, the bits a likely to change, so this information + * is for internal library use only, even though SSL_CIPHER.algorithms + * can be publicly accessed. + * Use the according functions for cipher management instead. + * + * The bit mask handling in the selection and sorting scheme in + * ssl_create_cipher_list() has only limited capabilities, reflecting + * that the different entities within are mutually exclusive: + * ONLY ONE BIT PER MASK CAN BE SET AT A TIME. + */ + +/* Bits for algorithm_mkey (key exchange algorithm) */ +/* RSA key exchange */ +# define SSL_kRSA 0x00000001L +/* DH cert, RSA CA cert */ +# define SSL_kDHr 0x00000002L +/* DH cert, DSA CA cert */ +# define SSL_kDHd 0x00000004L +/* tmp DH key no DH cert */ +# define SSL_kEDH 0x00000008L +/* forward-compatible synonym */ +# define SSL_kDHE SSL_kEDH +/* Kerberos5 key exchange */ +# define SSL_kKRB5 0x00000010L +/* ECDH cert, RSA CA cert */ +# define SSL_kECDHr 0x00000020L +/* ECDH cert, ECDSA CA cert */ +# define SSL_kECDHe 0x00000040L +/* ephemeral ECDH */ +# define SSL_kEECDH 0x00000080L +/* forward-compatible synonym */ +# define SSL_kECDHE SSL_kEECDH +/* PSK */ +# define SSL_kPSK 0x00000100L +/* GOST key exchange */ +# define SSL_kGOST 0x00000200L +/* SRP */ +# define SSL_kSRP 0x00000400L + +/* Bits for algorithm_auth (server authentication) */ +/* RSA auth */ +# define SSL_aRSA 0x00000001L +/* DSS auth */ +# define SSL_aDSS 0x00000002L +/* no auth (i.e. use ADH or AECDH) */ +# define SSL_aNULL 0x00000004L +/* Fixed DH auth (kDHd or kDHr) */ +# define SSL_aDH 0x00000008L +/* Fixed ECDH auth (kECDHe or kECDHr) */ +# define SSL_aECDH 0x00000010L +/* KRB5 auth */ +# define SSL_aKRB5 0x00000020L +/* ECDSA auth*/ +# define SSL_aECDSA 0x00000040L +/* PSK auth */ +# define SSL_aPSK 0x00000080L +/* GOST R 34.10-94 signature auth */ +# define SSL_aGOST94 0x00000100L +/* GOST R 34.10-2001 signature auth */ +# define SSL_aGOST01 0x00000200L +/* SRP auth */ +# define SSL_aSRP 0x00000400L + +/* Bits for algorithm_enc (symmetric encryption) */ +# define SSL_DES 0x00000001L +# define SSL_3DES 0x00000002L +# define SSL_RC4 0x00000004L +# define SSL_RC2 0x00000008L +# define SSL_IDEA 0x00000010L +# define SSL_eNULL 0x00000020L +# define SSL_AES128 0x00000040L +# define SSL_AES256 0x00000080L +# define SSL_CAMELLIA128 0x00000100L +# define SSL_CAMELLIA256 0x00000200L +# define SSL_eGOST2814789CNT 0x00000400L +# define SSL_SEED 0x00000800L +# define SSL_AES128GCM 0x00001000L +# define SSL_AES256GCM 0x00002000L + +# define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM) +# define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) + +/* Bits for algorithm_mac (symmetric authentication) */ + +# define SSL_MD5 0x00000001L +# define SSL_SHA1 0x00000002L +# define SSL_GOST94 0x00000004L +# define SSL_GOST89MAC 0x00000008L +# define SSL_SHA256 0x00000010L +# define SSL_SHA384 0x00000020L +/* Not a real MAC, just an indication it is part of cipher */ +# define SSL_AEAD 0x00000040L + +/* Bits for algorithm_ssl (protocol version) */ +# define SSL_SSLV2 0x00000001UL +# define SSL_SSLV3 0x00000002UL +# define SSL_TLSV1 SSL_SSLV3/* for now */ +# define SSL_TLSV1_2 0x00000004UL + +/* Bits for algorithm2 (handshake digests and other extra flags) */ + +# define SSL_HANDSHAKE_MAC_MD5 0x10 +# define SSL_HANDSHAKE_MAC_SHA 0x20 +# define SSL_HANDSHAKE_MAC_GOST94 0x40 +# define SSL_HANDSHAKE_MAC_SHA256 0x80 +# define SSL_HANDSHAKE_MAC_SHA384 0x100 +# define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) + +/* + * When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX make + * sure to update this constant too + */ +# define SSL_MAX_DIGEST 6 + +# define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT) + +# define TLS1_PRF_DGST_SHIFT 10 +# define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) + +/* + * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also + * goes into algorithm2) + */ +# define TLS1_STREAM_MAC 0x04 + +/* + * Export and cipher strength information. For each cipher we have to decide + * whether it is exportable or not. This information is likely to change + * over time, since the export control rules are no static technical issue. + * + * Independent of the export flag the cipher strength is sorted into classes. + * SSL_EXP40 was denoting the 40bit US export limit of past times, which now + * is at 56bit (SSL_EXP56). If the exportable cipher class is going to change + * again (eg. to 64bit) the use of "SSL_EXP*" becomes blurred even more, + * since SSL_EXP64 could be similar to SSL_LOW. + * For this reason SSL_MICRO and SSL_MINI macros are included to widen the + * namespace of SSL_LOW-SSL_HIGH to lower values. As development of speed + * and ciphers goes, another extension to SSL_SUPER and/or SSL_ULTRA would + * be possible. + */ +# define SSL_EXP_MASK 0x00000003L +# define SSL_STRONG_MASK 0x000001fcL + +# define SSL_NOT_EXP 0x00000001L +# define SSL_EXPORT 0x00000002L + +# define SSL_STRONG_NONE 0x00000004L +# define SSL_EXP40 0x00000008L +# define SSL_MICRO (SSL_EXP40) +# define SSL_EXP56 0x00000010L +# define SSL_MINI (SSL_EXP56) +# define SSL_LOW 0x00000020L +# define SSL_MEDIUM 0x00000040L +# define SSL_HIGH 0x00000080L +# define SSL_FIPS 0x00000100L +# define SSL_NOT_DEFAULT 0x00000200L + +/* we have used 000003ff - 22 bits left to go */ + +/*- + * Macros to check the export status and cipher strength for export ciphers. + * Even though the macros for EXPORT and EXPORT40/56 have similar names, + * their meaning is different: + * *_EXPORT macros check the 'exportable' status. + * *_EXPORT40/56 macros are used to check whether a certain cipher strength + * is given. + * Since the SSL_IS_EXPORT* and SSL_EXPORT* macros depend on the correct + * algorithm structure element to be passed (algorithms, algo_strength) and no + * typechecking can be done as they are all of type unsigned long, their + * direct usage is discouraged. + * Use the SSL_C_* macros instead. + */ +# define SSL_IS_EXPORT(a) ((a)&SSL_EXPORT) +# define SSL_IS_EXPORT56(a) ((a)&SSL_EXP56) +# define SSL_IS_EXPORT40(a) ((a)&SSL_EXP40) +# define SSL_C_IS_EXPORT(c) SSL_IS_EXPORT((c)->algo_strength) +# define SSL_C_IS_EXPORT56(c) SSL_IS_EXPORT56((c)->algo_strength) +# define SSL_C_IS_EXPORT40(c) SSL_IS_EXPORT40((c)->algo_strength) + +# define SSL_EXPORT_KEYLENGTH(a,s) (SSL_IS_EXPORT40(s) ? 5 : \ + (a) == SSL_DES ? 8 : 7) +# define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024) +# define SSL_C_EXPORT_KEYLENGTH(c) SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \ + (c)->algo_strength) +# define SSL_C_EXPORT_PKEYLENGTH(c) SSL_EXPORT_PKEYLENGTH((c)->algo_strength) + +/* Check if an SSL structure is using DTLS */ +# define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) +/* See if we need explicit IV */ +# define SSL_USE_EXPLICIT_IV(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) +/* + * See if we use signature algorithms extension and signature algorithm + * before signatures. + */ +# define SSL_USE_SIGALGS(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) +/* + * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may + * apply to others in future. + */ +# define SSL_USE_TLS1_2_CIPHERS(s) \ + (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) +/* + * Determine if a client can use TLS 1.2 ciphersuites: can't rely on method + * flags because it may not be set to correct version yet. + */ +# define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \ + ((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \ + (!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION)) +/* + * Determine if a client should send signature algorithms extension: + * as with TLS1.2 cipher we can't rely on method flags. + */ +# define SSL_CLIENT_USE_SIGALGS(s) \ + SSL_CLIENT_USE_TLS1_2_CIPHERS(s) + +/* Mostly for SSLv3 */ +# define SSL_PKEY_RSA_ENC 0 +# define SSL_PKEY_RSA_SIGN 1 +# define SSL_PKEY_DSA_SIGN 2 +# define SSL_PKEY_DH_RSA 3 +# define SSL_PKEY_DH_DSA 4 +# define SSL_PKEY_ECC 5 +# define SSL_PKEY_GOST94 6 +# define SSL_PKEY_GOST01 7 +# define SSL_PKEY_NUM 8 + +/*- + * SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) | + * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN) + * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN) + * SSL_kEDH <- RSA_ENC | RSA_SIGN | DSA_SIGN + * SSL_aRSA <- RSA_ENC | RSA_SIGN + * SSL_aDSS <- DSA_SIGN + */ + +/*- +#define CERT_INVALID 0 +#define CERT_PUBLIC_KEY 1 +#define CERT_PRIVATE_KEY 2 +*/ + +# ifndef OPENSSL_NO_EC +/* + * From ECC-TLS draft, used in encoding the curve type in ECParameters + */ +# define EXPLICIT_PRIME_CURVE_TYPE 1 +# define EXPLICIT_CHAR2_CURVE_TYPE 2 +# define NAMED_CURVE_TYPE 3 +# endif /* OPENSSL_NO_EC */ + +typedef struct cert_pkey_st { + X509 *x509; + EVP_PKEY *privatekey; + /* Digest to use when signing */ + const EVP_MD *digest; + /* Chain for this certificate */ + STACK_OF(X509) *chain; +# ifndef OPENSSL_NO_TLSEXT + /*- + * serverinfo data for this certificate. The data is in TLS Extension + * wire format, specifically it's a series of records like: + * uint16_t extension_type; // (RFC 5246, 7.4.1.4, Extension) + * uint16_t length; + * uint8_t data[length]; + */ + unsigned char *serverinfo; + size_t serverinfo_length; +# endif + /* + * Set if CERT_PKEY can be used with current SSL session: e.g. + * appropriate curve, signature algorithms etc. If zero it can't be used + * at all. + */ + int valid_flags; +} CERT_PKEY; +/* Retrieve Suite B flags */ +# define tls1_suiteb(s) (s->cert->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS) +/* Uses to check strict mode: suite B modes are always strict */ +# define SSL_CERT_FLAGS_CHECK_TLS_STRICT \ + (SSL_CERT_FLAG_SUITEB_128_LOS|SSL_CERT_FLAG_TLS_STRICT) + +typedef struct { + unsigned short ext_type; + /* + * Per-connection flags relating to this extension type: not used if + * part of an SSL_CTX structure. + */ + unsigned short ext_flags; + custom_ext_add_cb add_cb; + custom_ext_free_cb free_cb; + void *add_arg; + custom_ext_parse_cb parse_cb; + void *parse_arg; +} custom_ext_method; + +/* ext_flags values */ + +/* + * Indicates an extension has been received. Used to check for unsolicited or + * duplicate extensions. + */ +# define SSL_EXT_FLAG_RECEIVED 0x1 +/* + * Indicates an extension has been sent: used to enable sending of + * corresponding ServerHello extension. + */ +# define SSL_EXT_FLAG_SENT 0x2 + +# define MAX_WARN_ALERT_COUNT 5 + +typedef struct { + custom_ext_method *meths; + size_t meths_count; +} custom_ext_methods; + +typedef struct cert_st { + /* Current active set */ + /* + * ALWAYS points to an element of the pkeys array + * Probably it would make more sense to store + * an index, not a pointer. + */ + CERT_PKEY *key; + /* + * For servers the following masks are for the key and auth algorithms + * that are supported by the certs below. For clients they are masks of + * *disabled* algorithms based on the current session. + */ + int valid; + unsigned long mask_k; + unsigned long mask_a; + unsigned long export_mask_k; + unsigned long export_mask_a; + /* Client only */ + unsigned long mask_ssl; +# ifndef OPENSSL_NO_RSA + RSA *rsa_tmp; + RSA *(*rsa_tmp_cb) (SSL *ssl, int is_export, int keysize); +# endif +# ifndef OPENSSL_NO_DH + DH *dh_tmp; + DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize); +# endif +# ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh_tmp; + /* Callback for generating ephemeral ECDH keys */ + EC_KEY *(*ecdh_tmp_cb) (SSL *ssl, int is_export, int keysize); + /* Select ECDH parameters automatically */ + int ecdh_tmp_auto; +# endif + /* Flags related to certificates */ + unsigned int cert_flags; + CERT_PKEY pkeys[SSL_PKEY_NUM]; + /* + * Certificate types (received or sent) in certificate request message. + * On receive this is only set if number of certificate types exceeds + * SSL3_CT_NUMBER. + */ + unsigned char *ctypes; + size_t ctype_num; + /* + * signature algorithms peer reports: e.g. supported signature algorithms + * extension for server or as part of a certificate request for client. + */ + unsigned char *peer_sigalgs; + /* Size of above array */ + size_t peer_sigalgslen; + /* + * suppported signature algorithms. When set on a client this is sent in + * the client hello as the supported signature algorithms extension. For + * servers it represents the signature algorithms we are willing to use. + */ + unsigned char *conf_sigalgs; + /* Size of above array */ + size_t conf_sigalgslen; + /* + * Client authentication signature algorithms, if not set then uses + * conf_sigalgs. On servers these will be the signature algorithms sent + * to the client in a cerificate request for TLS 1.2. On a client this + * represents the signature algortithms we are willing to use for client + * authentication. + */ + unsigned char *client_sigalgs; + /* Size of above array */ + size_t client_sigalgslen; + /* + * Signature algorithms shared by client and server: cached because these + * are used most often. + */ + TLS_SIGALGS *shared_sigalgs; + size_t shared_sigalgslen; + /* + * Certificate setup callback: if set is called whenever a certificate + * may be required (client or server). the callback can then examine any + * appropriate parameters and setup any certificates required. This + * allows advanced applications to select certificates on the fly: for + * example based on supported signature algorithms or curves. + */ + int (*cert_cb) (SSL *ssl, void *arg); + void *cert_cb_arg; + /* + * Optional X509_STORE for chain building or certificate validation If + * NULL the parent SSL_CTX store is used instead. + */ + X509_STORE *chain_store; + X509_STORE *verify_store; + /* Raw values of the cipher list from a client */ + unsigned char *ciphers_raw; + size_t ciphers_rawlen; + /* Custom extension methods for server and client */ + custom_ext_methods cli_ext; + custom_ext_methods srv_ext; + int references; /* >1 only if SSL_copy_session_id is used */ + /* non-optimal, but here due to compatibility */ + unsigned char *alpn_proposed; /* server */ + unsigned int alpn_proposed_len; + int alpn_sent; /* client */ + /* Count of the number of consecutive warning alerts received */ + unsigned int alert_count; +} CERT; + +typedef struct sess_cert_st { + STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */ + /* The 'peer_...' members are used only by clients. */ + int peer_cert_type; + CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never + * NULL!) */ + CERT_PKEY peer_pkeys[SSL_PKEY_NUM]; + /* + * Obviously we don't have the private keys of these, so maybe we + * shouldn't even use the CERT_PKEY type here. + */ +# ifndef OPENSSL_NO_RSA + RSA *peer_rsa_tmp; /* not used for SSL 2 */ +# endif +# ifndef OPENSSL_NO_DH + DH *peer_dh_tmp; /* not used for SSL 2 */ +# endif +# ifndef OPENSSL_NO_ECDH + EC_KEY *peer_ecdh_tmp; +# endif + int references; /* actually always 1 at the moment */ +} SESS_CERT; +/* Structure containing decoded values of signature algorithms extension */ +struct tls_sigalgs_st { + /* NID of hash algorithm */ + int hash_nid; + /* NID of signature algorithm */ + int sign_nid; + /* Combined hash and signature NID */ + int signandhash_nid; + /* Raw values used in extension */ + unsigned char rsign; + unsigned char rhash; +}; + +/* + * #define MAC_DEBUG + */ + +/* + * #define ERR_DEBUG + */ +/* + * #define ABORT_DEBUG + */ +/* + * #define PKT_DEBUG 1 + */ +/* + * #define DES_DEBUG + */ +/* + * #define DES_OFB_DEBUG + */ +/* + * #define SSL_DEBUG + */ +/* + * #define RSA_DEBUG + */ +/* + * #define IDEA_DEBUG + */ + +# define FP_ICC (int (*)(const void *,const void *)) +# define ssl_put_cipher_by_char(ssl,ciph,ptr) \ + ((ssl)->method->put_cipher_by_char((ciph),(ptr))) + +/* + * This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit + * of a mess of functions, but hell, think of it as an opaque structure :-) + */ +typedef struct ssl3_enc_method { + int (*enc) (SSL *, int); + int (*mac) (SSL *, unsigned char *, int); + int (*setup_key_block) (SSL *); + int (*generate_master_secret) (SSL *, unsigned char *, unsigned char *, + int); + int (*change_cipher_state) (SSL *, int); + int (*final_finish_mac) (SSL *, const char *, int, unsigned char *); + int finish_mac_length; + int (*cert_verify_mac) (SSL *, int, unsigned char *); + const char *client_finished_label; + int client_finished_label_len; + const char *server_finished_label; + int server_finished_label_len; + int (*alert_value) (int); + int (*export_keying_material) (SSL *, unsigned char *, size_t, + const char *, size_t, + const unsigned char *, size_t, + int use_context); + /* Various flags indicating protocol version requirements */ + unsigned int enc_flags; + /* Handshake header length */ + unsigned int hhlen; + /* Set the handshake header */ + void (*set_handshake_header) (SSL *s, int type, unsigned long len); + /* Write out handshake message */ + int (*do_write) (SSL *s); +} SSL3_ENC_METHOD; + +# define SSL_HM_HEADER_LENGTH(s) s->method->ssl3_enc->hhlen +# define ssl_handshake_start(s) \ + (((unsigned char *)s->init_buf->data) + s->method->ssl3_enc->hhlen) +# define ssl_set_handshake_header(s, htype, len) \ + s->method->ssl3_enc->set_handshake_header(s, htype, len) +# define ssl_do_write(s) s->method->ssl3_enc->do_write(s) + +/* Values for enc_flags */ + +/* Uses explicit IV for CBC mode */ +# define SSL_ENC_FLAG_EXPLICIT_IV 0x1 +/* Uses signature algorithms extension */ +# define SSL_ENC_FLAG_SIGALGS 0x2 +/* Uses SHA256 default PRF */ +# define SSL_ENC_FLAG_SHA256_PRF 0x4 +/* Is DTLS */ +# define SSL_ENC_FLAG_DTLS 0x8 +/* + * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may + * apply to others in future. + */ +# define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x10 + +# ifndef OPENSSL_NO_COMP +/* Used for holding the relevant compression methods loaded into SSL_CTX */ +typedef struct ssl3_comp_st { + int comp_id; /* The identifier byte for this compression + * type */ + char *name; /* Text name used for the compression type */ + COMP_METHOD *method; /* The method :-) */ +} SSL3_COMP; +# endif + +# ifndef OPENSSL_NO_BUF_FREELISTS +typedef struct ssl3_buf_freelist_st { + size_t chunklen; + unsigned int len; + struct ssl3_buf_freelist_entry_st *head; +} SSL3_BUF_FREELIST; + +typedef struct ssl3_buf_freelist_entry_st { + struct ssl3_buf_freelist_entry_st *next; +} SSL3_BUF_FREELIST_ENTRY; +# endif + +extern SSL3_ENC_METHOD ssl3_undef_enc_method; +OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[]; +OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[]; + +SSL_METHOD *ssl_bad_method(int ver); + +extern SSL3_ENC_METHOD TLSv1_enc_data; +extern SSL3_ENC_METHOD TLSv1_1_enc_data; +extern SSL3_ENC_METHOD TLSv1_2_enc_data; +extern SSL3_ENC_METHOD SSLv3_enc_data; +extern SSL3_ENC_METHOD DTLSv1_enc_data; +extern SSL3_ENC_METHOD DTLSv1_2_enc_data; + +# define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ + s_get_meth, enc_data) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + version, \ + tls1_new, \ + tls1_clear, \ + tls1_free, \ + s_accept, \ + s_connect, \ + ssl3_read, \ + ssl3_peek, \ + ssl3_write, \ + ssl3_shutdown, \ + ssl3_renegotiate, \ + ssl3_renegotiate_check, \ + ssl3_get_message, \ + ssl3_read_bytes, \ + ssl3_write_bytes, \ + ssl3_dispatch_alert, \ + ssl3_ctrl, \ + ssl3_ctx_ctrl, \ + ssl3_get_cipher_by_char, \ + ssl3_put_cipher_by_char, \ + ssl3_pending, \ + ssl3_num_ciphers, \ + ssl3_get_cipher, \ + s_get_meth, \ + tls1_default_timeout, \ + &enc_data, \ + ssl_undefined_void_function, \ + ssl3_callback_ctrl, \ + ssl3_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +# define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + SSL3_VERSION, \ + ssl3_new, \ + ssl3_clear, \ + ssl3_free, \ + s_accept, \ + s_connect, \ + ssl3_read, \ + ssl3_peek, \ + ssl3_write, \ + ssl3_shutdown, \ + ssl3_renegotiate, \ + ssl3_renegotiate_check, \ + ssl3_get_message, \ + ssl3_read_bytes, \ + ssl3_write_bytes, \ + ssl3_dispatch_alert, \ + ssl3_ctrl, \ + ssl3_ctx_ctrl, \ + ssl3_get_cipher_by_char, \ + ssl3_put_cipher_by_char, \ + ssl3_pending, \ + ssl3_num_ciphers, \ + ssl3_get_cipher, \ + s_get_meth, \ + ssl3_default_timeout, \ + &SSLv3_enc_data, \ + ssl_undefined_void_function, \ + ssl3_callback_ctrl, \ + ssl3_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +# define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + TLS1_2_VERSION, \ + tls1_new, \ + tls1_clear, \ + tls1_free, \ + s_accept, \ + s_connect, \ + ssl23_read, \ + ssl23_peek, \ + ssl23_write, \ + ssl_undefined_function, \ + ssl_undefined_function, \ + ssl_ok, \ + ssl3_get_message, \ + ssl3_read_bytes, \ + ssl3_write_bytes, \ + ssl3_dispatch_alert, \ + ssl3_ctrl, \ + ssl3_ctx_ctrl, \ + ssl23_get_cipher_by_char, \ + ssl23_put_cipher_by_char, \ + ssl_undefined_const_function, \ + ssl23_num_ciphers, \ + ssl23_get_cipher, \ + s_get_meth, \ + ssl23_default_timeout, \ + &TLSv1_2_enc_data, \ + ssl_undefined_void_function, \ + ssl3_callback_ctrl, \ + ssl3_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +# define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + SSL2_VERSION, \ + ssl2_new, /* local */ \ + ssl2_clear, /* local */ \ + ssl2_free, /* local */ \ + s_accept, \ + s_connect, \ + ssl2_read, \ + ssl2_peek, \ + ssl2_write, \ + ssl2_shutdown, \ + ssl_ok, /* NULL - renegotiate */ \ + ssl_ok, /* NULL - check renegotiate */ \ + NULL, /* NULL - ssl_get_message */ \ + NULL, /* NULL - ssl_get_record */ \ + NULL, /* NULL - ssl_write_bytes */ \ + NULL, /* NULL - dispatch_alert */ \ + ssl2_ctrl, /* local */ \ + ssl2_ctx_ctrl, /* local */ \ + ssl2_get_cipher_by_char, \ + ssl2_put_cipher_by_char, \ + ssl2_pending, \ + ssl2_num_ciphers, \ + ssl2_get_cipher, \ + s_get_meth, \ + ssl2_default_timeout, \ + &ssl3_undef_enc_method, \ + ssl_undefined_void_function, \ + ssl2_callback_ctrl, /* local */ \ + ssl2_ctx_callback_ctrl, /* local */ \ + }; \ + return &func_name##_data; \ + } + +# define IMPLEMENT_dtls1_meth_func(version, func_name, s_accept, s_connect, \ + s_get_meth, enc_data) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + version, \ + dtls1_new, \ + dtls1_clear, \ + dtls1_free, \ + s_accept, \ + s_connect, \ + ssl3_read, \ + ssl3_peek, \ + ssl3_write, \ + dtls1_shutdown, \ + ssl3_renegotiate, \ + ssl3_renegotiate_check, \ + dtls1_get_message, \ + dtls1_read_bytes, \ + dtls1_write_app_data_bytes, \ + dtls1_dispatch_alert, \ + dtls1_ctrl, \ + ssl3_ctx_ctrl, \ + ssl3_get_cipher_by_char, \ + ssl3_put_cipher_by_char, \ + ssl3_pending, \ + ssl3_num_ciphers, \ + dtls1_get_cipher, \ + s_get_meth, \ + dtls1_default_timeout, \ + &enc_data, \ + ssl_undefined_void_function, \ + ssl3_callback_ctrl, \ + ssl3_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +struct openssl_ssl_test_functions { + int (*p_ssl_init_wbio_buffer) (SSL *s, int push); + int (*p_ssl3_setup_buffers) (SSL *s); + int (*p_tls1_process_heartbeat) (SSL *s); + int (*p_dtls1_process_heartbeat) (SSL *s); +}; + +# ifndef OPENSSL_UNIT_TEST + +void ssl_clear_cipher_ctx(SSL *s); +int ssl_clear_bad_session(SSL *s); +CERT *ssl_cert_new(void); +CERT *ssl_cert_dup(CERT *cert); +void ssl_cert_set_default_md(CERT *cert); +int ssl_cert_inst(CERT **o); +void ssl_cert_clear_certs(CERT *c); +void ssl_cert_free(CERT *c); +SESS_CERT *ssl_sess_cert_new(void); +void ssl_sess_cert_free(SESS_CERT *sc); +int ssl_set_peer_cert_type(SESS_CERT *c, int type); +int ssl_get_new_session(SSL *s, int session); +int ssl_get_prev_session(SSL *s, unsigned char *session, int len, + const unsigned char *limit); +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket); +int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); +DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); +int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, + const SSL_CIPHER *const *bp); +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, + int num, + STACK_OF(SSL_CIPHER) **skp); +int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, + unsigned char *p, + int (*put_cb) (const SSL_CIPHER *, + unsigned char *)); +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, + STACK_OF(SSL_CIPHER) **pref, + STACK_OF(SSL_CIPHER) **sorted, + const char *rule_str, CERT *c); +void ssl_update_cache(SSL *s, int mode); +int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, + int *mac_secret_size, SSL_COMP **comp); +int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md); +int ssl_cipher_get_cert_index(const SSL_CIPHER *c); +const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr); +int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain); +int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain); +int ssl_cert_add0_chain_cert(CERT *c, X509 *x); +int ssl_cert_add1_chain_cert(CERT *c, X509 *x); +int ssl_cert_select_current(CERT *c, X509 *x); +int ssl_cert_set_current(CERT *c, long arg); +X509 *ssl_cert_get0_next_certificate(CERT *c, int first); +void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), + void *arg); + +int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk); +int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l); +int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags); +int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref); +int ssl_undefined_function(SSL *s); +int ssl_undefined_void_function(void); +int ssl_undefined_const_function(const SSL *s); +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); +# ifndef OPENSSL_NO_TLSEXT +int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, + size_t *serverinfo_length); +# endif +EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd); +int ssl_cert_type(X509 *x, EVP_PKEY *pkey); +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); +int ssl_verify_alarm_type(long type); +void ssl_load_ciphers(void); +int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len); + +int ssl2_enc_init(SSL *s, int client); +int ssl2_generate_key_material(SSL *s); +int ssl2_enc(SSL *s, int send_data); +void ssl2_mac(SSL *s, unsigned char *mac, int send_data); +const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p); +int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); +int ssl2_part_read(SSL *s, unsigned long f, int i); +int ssl2_do_write(SSL *s); +int ssl2_set_certificate(SSL *s, int type, int len, + const unsigned char *data); +void ssl2_return_error(SSL *s, int reason); +void ssl2_write_error(SSL *s); +int ssl2_num_ciphers(void); +const SSL_CIPHER *ssl2_get_cipher(unsigned int u); +int ssl2_new(SSL *s); +void ssl2_free(SSL *s); +int ssl2_accept(SSL *s); +int ssl2_connect(SSL *s); +int ssl2_read(SSL *s, void *buf, int len); +int ssl2_peek(SSL *s, void *buf, int len); +int ssl2_write(SSL *s, const void *buf, int len); +int ssl2_shutdown(SSL *s); +void ssl2_clear(SSL *s); +long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg); +long ssl2_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); +long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); +long ssl2_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); +int ssl2_pending(const SSL *s); +long ssl2_default_timeout(void); + +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); +int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); +int ssl3_init_finished_mac(SSL *s); +int ssl3_send_server_certificate(SSL *s); +int ssl3_send_newsession_ticket(SSL *s); +int ssl3_send_cert_status(SSL *s); +int ssl3_get_finished(SSL *s, int state_a, int state_b); +int ssl3_setup_key_block(SSL *s); +int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b); +int ssl3_change_cipher_state(SSL *s, int which); +void ssl3_cleanup_key_block(SSL *s); +int ssl3_do_write(SSL *s, int type); +int ssl3_send_alert(SSL *s, int level, int desc); +int ssl3_generate_master_secret(SSL *s, unsigned char *out, + unsigned char *p, int len); +int ssl3_get_req_cert_type(SSL *s, unsigned char *p); +long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); +int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen); +int ssl3_num_ciphers(void); +const SSL_CIPHER *ssl3_get_cipher(unsigned int u); +int ssl3_renegotiate(SSL *ssl); +int ssl3_renegotiate_check(SSL *ssl); +int ssl3_dispatch_alert(SSL *s); +int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); +int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); +int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, + unsigned char *p); +int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); +void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len); +int ssl3_enc(SSL *s, int send_data); +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data); +void ssl3_free_digest_list(SSL *s); +unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk); +SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, + STACK_OF(SSL_CIPHER) *srvr); +int ssl3_setup_buffers(SSL *s); +int ssl3_setup_read_buffer(SSL *s); +int ssl3_setup_write_buffer(SSL *s); +int ssl3_release_read_buffer(SSL *s); +int ssl3_release_write_buffer(SSL *s); +int ssl3_digest_cached_records(SSL *s); +int ssl3_new(SSL *s); +void ssl3_free(SSL *s); +int ssl3_accept(SSL *s); +int ssl3_connect(SSL *s); +int ssl3_read(SSL *s, void *buf, int len); +int ssl3_peek(SSL *s, void *buf, int len); +int ssl3_write(SSL *s, const void *buf, int len); +int ssl3_shutdown(SSL *s); +void ssl3_clear(SSL *s); +long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg); +long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); +long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); +long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); +int ssl3_pending(const SSL *s); + +void ssl3_record_sequence_update(unsigned char *seq); +int ssl3_do_change_cipher_spec(SSL *ssl); +long ssl3_default_timeout(void); + +void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len); +int ssl3_handshake_write(SSL *s); + +int ssl23_num_ciphers(void); +const SSL_CIPHER *ssl23_get_cipher(unsigned int u); +int ssl23_read(SSL *s, void *buf, int len); +int ssl23_peek(SSL *s, void *buf, int len); +int ssl23_write(SSL *s, const void *buf, int len); +int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); +const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p); +long ssl23_default_timeout(void); + +long tls1_default_timeout(void); +int dtls1_do_write(SSL *s, int type); +int ssl3_read_n(SSL *s, int n, int max, int extend); +int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); +int ssl3_do_compress(SSL *ssl); +int ssl3_do_uncompress(SSL *ssl); +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, + unsigned int len); +unsigned char *dtls1_set_message_header(SSL *s, + unsigned char *p, unsigned char mt, + unsigned long len, + unsigned long frag_off, + unsigned long frag_len); + +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len); +int dtls1_write_bytes(SSL *s, int type, const void *buf, int len); + +int dtls1_send_change_cipher_spec(SSL *s, int a, int b); +int dtls1_read_failed(SSL *s, int code); +int dtls1_buffer_message(SSL *s, int ccs); +int dtls1_retransmit_message(SSL *s, unsigned short seq, + unsigned long frag_off, int *found); +int dtls1_get_queue_priority(unsigned short seq, int is_ccs); +int dtls1_retransmit_buffered_messages(SSL *s); +void dtls1_clear_received_buffer(SSL *s); +void dtls1_clear_sent_buffer(SSL *s); +void dtls1_get_message_header(unsigned char *data, + struct hm_header_st *msg_hdr); +void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); +void dtls1_reset_seq_numbers(SSL *s, int rw); +long dtls1_default_timeout(void); +struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft); +int dtls1_check_timeout_num(SSL *s); +int dtls1_handle_timeout(SSL *s); +const SSL_CIPHER *dtls1_get_cipher(unsigned int u); +void dtls1_start_timer(SSL *s); +void dtls1_stop_timer(SSL *s); +int dtls1_is_timer_expired(SSL *s); +void dtls1_double_timeout(SSL *s); +int dtls1_send_newsession_ticket(SSL *s); +unsigned int dtls1_min_mtu(SSL *s); +unsigned int dtls1_link_min_mtu(void); +void dtls1_hm_fragment_free(hm_fragment *frag); + +/* some client-only functions */ +int ssl3_client_hello(SSL *s); +int ssl3_get_server_hello(SSL *s); +int ssl3_get_certificate_request(SSL *s); +int ssl3_get_new_session_ticket(SSL *s); +int ssl3_get_cert_status(SSL *s); +int ssl3_get_server_done(SSL *s); +int ssl3_send_client_verify(SSL *s); +int ssl3_send_client_certificate(SSL *s); +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); +int ssl3_send_client_key_exchange(SSL *s); +int ssl3_get_key_exchange(SSL *s); +int ssl3_get_server_certificate(SSL *s); +int ssl3_check_cert_and_algorithm(SSL *s); +# ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_NEXTPROTONEG +int ssl3_send_next_proto(SSL *s); +# endif +# endif + +int dtls1_client_hello(SSL *s); + +/* some server-only functions */ +int ssl3_get_client_hello(SSL *s); +int ssl3_send_server_hello(SSL *s); +int ssl3_send_hello_request(SSL *s); +int ssl3_send_server_key_exchange(SSL *s); +int ssl3_send_certificate_request(SSL *s); +int ssl3_send_server_done(SSL *s); +int ssl3_get_client_certificate(SSL *s); +int ssl3_get_client_key_exchange(SSL *s); +int ssl3_get_cert_verify(SSL *s); +# ifndef OPENSSL_NO_NEXTPROTONEG +int ssl3_get_next_proto(SSL *s); +# endif + +int ssl23_accept(SSL *s); +int ssl23_connect(SSL *s); +int ssl23_read_bytes(SSL *s, int n); +int ssl23_write_bytes(SSL *s); + +int tls1_new(SSL *s); +void tls1_free(SSL *s); +void tls1_clear(SSL *s); +long tls1_ctrl(SSL *s, int cmd, long larg, void *parg); +long tls1_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); + +int dtls1_new(SSL *s); +int dtls1_accept(SSL *s); +int dtls1_connect(SSL *s); +void dtls1_free(SSL *s); +void dtls1_clear(SSL *s); +long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); +int dtls1_shutdown(SSL *s); + +long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); +int dtls1_get_record(SSL *s); +int do_dtls1_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragement); +int dtls1_dispatch_alert(SSL *s); + +int ssl_init_wbio_buffer(SSL *s, int push); +void ssl_free_wbio_buffer(SSL *s); + +int tls1_change_cipher_state(SSL *s, int which); +int tls1_setup_key_block(SSL *s); +int tls1_enc(SSL *s, int snd); +int tls1_final_finish_mac(SSL *s, + const char *str, int slen, unsigned char *p); +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); +int tls1_mac(SSL *ssl, unsigned char *md, int snd); +int tls1_generate_master_secret(SSL *s, unsigned char *out, + unsigned char *p, int len); +int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *p, size_t plen, + int use_context); +int tls1_alert_code(int code); +int ssl3_alert_code(int code); +int ssl_ok(SSL *s); + +# ifndef OPENSSL_NO_ECDH +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); +# endif + +SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); + +# ifndef OPENSSL_NO_EC +int tls1_ec_curve_id2nid(int curve_id); +int tls1_ec_nid2curve_id(int nid); +int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); +int tls1_shared_curve(SSL *s, int nmatch); +int tls1_set_curves(unsigned char **pext, size_t *pextlen, + int *curves, size_t ncurves); +int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, + const char *str); +# ifndef OPENSSL_NO_ECDH +int tls1_check_ec_tmp_key(SSL *s, unsigned long id); +# endif /* OPENSSL_NO_ECDH */ +# endif /* OPENSSL_NO_EC */ + +# ifndef OPENSSL_NO_TLSEXT +int tls1_shared_list(SSL *s, + const unsigned char *l1, size_t l1len, + const unsigned char *l2, size_t l2len, int nmatch); +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit, int *al); +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit, int *al); +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, + unsigned char *limit); +int tls1_set_server_sigalgs(SSL *s); +int ssl_check_clienthello_tlsext_late(SSL *s, int *al); +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, + unsigned char *d, int n); +int ssl_prepare_clienthello_tlsext(SSL *s); +int ssl_prepare_serverhello_tlsext(SSL *s); + +# ifndef OPENSSL_NO_HEARTBEATS +int tls1_heartbeat(SSL *s); +int dtls1_heartbeat(SSL *s); +int tls1_process_heartbeat(SSL *s); +int dtls1_process_heartbeat(SSL *s); +# endif + +# ifdef OPENSSL_NO_SHA256 +# define tlsext_tick_md EVP_sha1 +# else +# define tlsext_tick_md EVP_sha256 +# endif +int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit, SSL_SESSION **ret); + +int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, + const EVP_MD *md); +int tls12_get_sigid(const EVP_PKEY *pk); +const EVP_MD *tls12_get_hash(unsigned char hash_alg); + +int tls1_set_sigalgs_list(CERT *c, const char *str, int client); +int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, int client); +int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, + int idx); +void tls1_set_cert_validity(SSL *s); + +# endif +EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md); +void ssl_clear_hash_ctx(EVP_MD_CTX **hash); +int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen); +int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al); +int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen); +int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al); +long ssl_get_algorithm2(SSL *s); +int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize); +int tls1_process_sigalgs(SSL *s); +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs); +int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, + const unsigned char *sig, EVP_PKEY *pkey); +void ssl_set_client_disabled(SSL *s); + +int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, + int maxlen); +int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len, + int *al); +int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, + int maxlen); +int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len, + int *al); + +/* s3_cbc.c */ +void ssl3_cbc_copy_mac(unsigned char *out, + const SSL3_RECORD *rec, + unsigned md_size, unsigned orig_len); +int ssl3_cbc_remove_padding(const SSL *s, + SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size); +int tls1_cbc_remove_padding(const SSL *s, + SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size); +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + unsigned mac_secret_length, char is_sslv3); + +void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx, + EVP_MD_CTX *mac_ctx, const unsigned char *data, + size_t data_len, size_t orig_len); + +int srp_verify_server_param(SSL *s, int *al); + +/* t1_ext.c */ + +void custom_ext_init(custom_ext_methods *meths); + +int custom_ext_parse(SSL *s, int server, + unsigned int ext_type, + const unsigned char *ext_data, size_t ext_size, int *al); +int custom_ext_add(SSL *s, int server, + unsigned char **pret, unsigned char *limit, int *al); + +int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src); +int custom_exts_copy_flags(custom_ext_methods *dst, + const custom_ext_methods *src); +void custom_exts_free(custom_ext_methods *exts); + +# else + +# define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer +# define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers +# define tls1_process_heartbeat SSL_test_functions()->p_tls1_process_heartbeat +# define dtls1_process_heartbeat SSL_test_functions()->p_dtls1_process_heartbeat + +# endif +#endif diff --git a/Sources/COpenSSL/stack.c b/Sources/COpenSSL/stack.c new file mode 100644 index 00000000..2ae0c354 --- /dev/null +++ b/Sources/COpenSSL/stack.c @@ -0,0 +1,384 @@ +/* crypto/stack/stack.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * Code for stacks + * Author - Eric Young v 1.0 + * 1.2 eay 12-Mar-97 - Modified sk_find so that it _DOES_ return the + * lowest index for the searched item. + * + * 1.1 eay - Take from netdb and added to SSLeay + * + * 1.0 eay - First version 29/07/92 + */ +#include +#include "cryptlib.h" +#include "stack.h" +#include "objects.h" + +#undef MIN_NODES +#define MIN_NODES 4 + +const char STACK_version[] = "Stack" OPENSSL_VERSION_PTEXT; + +#include + +int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) + (const void *, const void *) { + int (*old) (const void *, const void *) = sk->comp; + + if (sk->comp != c) + sk->sorted = 0; + sk->comp = c; + + return old; +} + +_STACK *sk_dup(_STACK *sk) +{ + _STACK *ret; + char **s; + + if ((ret = sk_new(sk->comp)) == NULL) + goto err; + s = (char **)OPENSSL_realloc((char *)ret->data, + (unsigned int)sizeof(char *) * + sk->num_alloc); + if (s == NULL) + goto err; + ret->data = s; + + ret->num = sk->num; + memcpy(ret->data, sk->data, sizeof(char *) * sk->num); + ret->sorted = sk->sorted; + ret->num_alloc = sk->num_alloc; + ret->comp = sk->comp; + return (ret); + err: + if (ret) + sk_free(ret); + return (NULL); +} + +_STACK *sk_deep_copy(_STACK *sk, void *(*copy_func) (void *), + void (*free_func) (void *)) +{ + _STACK *ret; + int i; + + if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL) + return ret; + ret->comp = sk->comp; + ret->sorted = sk->sorted; + ret->num = sk->num; + ret->num_alloc = sk->num > MIN_NODES ? sk->num : MIN_NODES; + ret->data = OPENSSL_malloc(sizeof(char *) * ret->num_alloc); + if (ret->data == NULL) { + OPENSSL_free(ret); + return NULL; + } + for (i = 0; i < ret->num_alloc; i++) + ret->data[i] = NULL; + + for (i = 0; i < ret->num; ++i) { + if (sk->data[i] == NULL) + continue; + if ((ret->data[i] = copy_func(sk->data[i])) == NULL) { + while (--i >= 0) + if (ret->data[i] != NULL) + free_func(ret->data[i]); + sk_free(ret); + return NULL; + } + } + return ret; +} + +_STACK *sk_new_null(void) +{ + return sk_new((int (*)(const void *, const void *))0); +} + +_STACK *sk_new(int (*c) (const void *, const void *)) +{ + _STACK *ret; + int i; + + if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL) + goto err; + if ((ret->data = OPENSSL_malloc(sizeof(char *) * MIN_NODES)) == NULL) + goto err; + for (i = 0; i < MIN_NODES; i++) + ret->data[i] = NULL; + ret->comp = c; + ret->num_alloc = MIN_NODES; + ret->num = 0; + ret->sorted = 0; + return (ret); + err: + if (ret) + OPENSSL_free(ret); + return (NULL); +} + +int sk_insert(_STACK *st, void *data, int loc) +{ + char **s; + + if (st == NULL) + return 0; + if (st->num_alloc <= st->num + 1) { + s = OPENSSL_realloc((char *)st->data, + (unsigned int)sizeof(char *) * st->num_alloc * 2); + if (s == NULL) + return (0); + st->data = s; + st->num_alloc *= 2; + } + if ((loc >= (int)st->num) || (loc < 0)) + st->data[st->num] = data; + else { + int i; + char **f, **t; + + f = st->data; + t = &(st->data[1]); + for (i = st->num; i >= loc; i--) + t[i] = f[i]; + +#ifdef undef /* no memmove on sunos :-( */ + memmove(&(st->data[loc + 1]), + &(st->data[loc]), sizeof(char *) * (st->num - loc)); +#endif + st->data[loc] = data; + } + st->num++; + st->sorted = 0; + return (st->num); +} + +void *sk_delete_ptr(_STACK *st, void *p) +{ + int i; + + for (i = 0; i < st->num; i++) + if (st->data[i] == p) + return (sk_delete(st, i)); + return (NULL); +} + +void *sk_delete(_STACK *st, int loc) +{ + char *ret; + int i, j; + + if (!st || (loc < 0) || (loc >= st->num)) + return NULL; + + ret = st->data[loc]; + if (loc != st->num - 1) { + j = st->num - 1; + for (i = loc; i < j; i++) + st->data[i] = st->data[i + 1]; + /* + * In theory memcpy is not safe for this memcpy( &(st->data[loc]), + * &(st->data[loc+1]), sizeof(char *)*(st->num-loc-1)); + */ + } + st->num--; + return (ret); +} + +static int internal_find(_STACK *st, void *data, int ret_val_options) +{ + const void *const *r; + int i; + + if (st == NULL) + return -1; + + if (st->comp == NULL) { + for (i = 0; i < st->num; i++) + if (st->data[i] == data) + return (i); + return (-1); + } + sk_sort(st); + if (data == NULL) + return (-1); + r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp, + ret_val_options); + if (r == NULL) + return (-1); + return (int)((char **)r - st->data); +} + +int sk_find(_STACK *st, void *data) +{ + return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); +} + +int sk_find_ex(_STACK *st, void *data) +{ + return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); +} + +int sk_push(_STACK *st, void *data) +{ + return (sk_insert(st, data, st->num)); +} + +int sk_unshift(_STACK *st, void *data) +{ + return (sk_insert(st, data, 0)); +} + +void *sk_shift(_STACK *st) +{ + if (st == NULL) + return (NULL); + if (st->num <= 0) + return (NULL); + return (sk_delete(st, 0)); +} + +void *sk_pop(_STACK *st) +{ + if (st == NULL) + return (NULL); + if (st->num <= 0) + return (NULL); + return (sk_delete(st, st->num - 1)); +} + +void sk_zero(_STACK *st) +{ + if (st == NULL) + return; + if (st->num <= 0) + return; + memset((char *)st->data, 0, sizeof(*st->data) * st->num); + st->num = 0; +} + +void sk_pop_free(_STACK *st, void (*func) (void *)) +{ + int i; + + if (st == NULL) + return; + for (i = 0; i < st->num; i++) + if (st->data[i] != NULL) + func(st->data[i]); + sk_free(st); +} + +void sk_free(_STACK *st) +{ + if (st == NULL) + return; + if (st->data != NULL) + OPENSSL_free(st->data); + OPENSSL_free(st); +} + +int sk_num(const _STACK *st) +{ + if (st == NULL) + return -1; + return st->num; +} + +void *sk_value(const _STACK *st, int i) +{ + if (!st || (i < 0) || (i >= st->num)) + return NULL; + return st->data[i]; +} + +void *sk_set(_STACK *st, int i, void *value) +{ + if (!st || (i < 0) || (i >= st->num)) + return NULL; + return (st->data[i] = value); +} + +void sk_sort(_STACK *st) +{ + if (st && !st->sorted && st->comp != NULL) { + int (*comp_func) (const void *, const void *); + + /* + * same comment as in sk_find ... previously st->comp was declared as + * a (void*,void*) callback type, but this made the population of the + * callback pointer illogical - our callbacks compare type** with + * type**, so we leave the casting until absolutely necessary (ie. + * "now"). + */ + comp_func = (int (*)(const void *, const void *))(st->comp); + qsort(st->data, st->num, sizeof(char *), comp_func); + st->sorted = 1; + } +} + +int sk_is_sorted(const _STACK *st) +{ + if (!st) + return 1; + return st->sorted; +} diff --git a/Sources/COpenSSL/stack.h b/Sources/COpenSSL/stack.h new file mode 100644 index 00000000..eb072166 --- /dev/null +++ b/Sources/COpenSSL/stack.h @@ -0,0 +1,107 @@ +/* crypto/stack/stack.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_STACK_H +# define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st { + int num; + char **data; + int sorted; + int num_alloc; + int (*comp) (const void *, const void *); +} _STACK; /* Use STACK_OF(...) instead */ + +# define M_sk_num(sk) ((sk) ? (sk)->num:-1) +# define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) + +int sk_num(const _STACK *); +void *sk_value(const _STACK *, int); + +void *sk_set(_STACK *, int, void *); + +_STACK *sk_new(int (*cmp) (const void *, const void *)); +_STACK *sk_new_null(void); +void sk_free(_STACK *); +void sk_pop_free(_STACK *st, void (*func) (void *)); +_STACK *sk_deep_copy(_STACK *, void *(*)(void *), void (*)(void *)); +int sk_insert(_STACK *sk, void *data, int where); +void *sk_delete(_STACK *st, int loc); +void *sk_delete_ptr(_STACK *st, void *p); +int sk_find(_STACK *st, void *data); +int sk_find_ex(_STACK *st, void *data); +int sk_push(_STACK *st, void *data); +int sk_unshift(_STACK *st, void *data); +void *sk_shift(_STACK *st); +void *sk_pop(_STACK *st); +void sk_zero(_STACK *st); +int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) + (const void *, const void *); +_STACK *sk_dup(_STACK *st); +void sk_sort(_STACK *st); +int sk_is_sorted(const _STACK *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/str2key.c b/Sources/COpenSSL/str2key.c new file mode 100644 index 00000000..be1438b6 --- /dev/null +++ b/Sources/COpenSSL/str2key.c @@ -0,0 +1,164 @@ +/* crypto/des/str2key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "crypto.h" +#include "des_locl.h" + +void DES_string_to_key(const char *str, DES_cblock *key) +{ + DES_key_schedule ks; + int i, length; + register unsigned char j; + + memset(key, 0, 8); + length = strlen(str); +#ifdef OLD_STR_TO_KEY + for (i = 0; i < length; i++) + (*key)[i % 8] ^= (str[i] << 1); +#else /* MIT COMPATIBLE */ + for (i = 0; i < length; i++) { + j = str[i]; + if ((i % 16) < 8) + (*key)[i % 8] ^= (j << 1); + else { + /* Reverse the bit order 05/05/92 eay */ + j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f); + j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33); + j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55); + (*key)[7 - (i % 8)] ^= j; + } + } +#endif + DES_set_odd_parity(key); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key)) + (*key)[7] ^= 0xF0; + DES_set_key(key, &ks); +#else + DES_set_key_unchecked(key, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key, length, &ks, key); + OPENSSL_cleanse(&ks, sizeof(ks)); + DES_set_odd_parity(key); +} + +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2) +{ + DES_key_schedule ks; + int i, length; + register unsigned char j; + + memset(key1, 0, 8); + memset(key2, 0, 8); + length = strlen(str); +#ifdef OLD_STR_TO_KEY + if (length <= 8) { + for (i = 0; i < length; i++) { + (*key2)[i] = (*key1)[i] = (str[i] << 1); + } + } else { + for (i = 0; i < length; i++) { + if ((i / 8) & 1) + (*key2)[i % 8] ^= (str[i] << 1); + else + (*key1)[i % 8] ^= (str[i] << 1); + } + } +#else /* MIT COMPATIBLE */ + for (i = 0; i < length; i++) { + j = str[i]; + if ((i % 32) < 16) { + if ((i % 16) < 8) + (*key1)[i % 8] ^= (j << 1); + else + (*key2)[i % 8] ^= (j << 1); + } else { + j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f); + j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33); + j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55); + if ((i % 16) < 8) + (*key1)[7 - (i % 8)] ^= j; + else + (*key2)[7 - (i % 8)] ^= j; + } + } + if (length <= 8) + memcpy(key2, key1, 8); +#endif + DES_set_odd_parity(key1); + DES_set_odd_parity(key2); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key1)) + (*key1)[7] ^= 0xF0; + DES_set_key(key1, &ks); +#else + DES_set_key_unchecked(key1, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key1, length, &ks, key1); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key2)) + (*key2)[7] ^= 0xF0; + DES_set_key(key2, &ks); +#else + DES_set_key_unchecked(key2, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key2, length, &ks, key2); + OPENSSL_cleanse(&ks, sizeof(ks)); + DES_set_odd_parity(key1); + DES_set_odd_parity(key2); +} diff --git a/Sources/COpenSSL/sureware.h b/Sources/COpenSSL/sureware.h new file mode 100644 index 00000000..b1423e19 --- /dev/null +++ b/Sources/COpenSSL/sureware.h @@ -0,0 +1,250 @@ +/*- + * Written by Corinne Dive-Reclus(cdive@baltimore.com) + * + * Copyright@2001 Baltimore Technologies Ltd. + * + * THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef WIN32 +# define SW_EXPORT __declspec ( dllexport ) +#else +# define SW_EXPORT +#endif + +/* + * List of exposed SureWare errors + */ +#define SUREWAREHOOK_ERROR_FAILED -1 +#define SUREWAREHOOK_ERROR_FALLBACK -2 +#define SUREWAREHOOK_ERROR_UNIT_FAILURE -3 +#define SUREWAREHOOK_ERROR_DATA_SIZE -4 +#define SUREWAREHOOK_ERROR_INVALID_PAD -5 +/*- +* -----------------WARNING----------------------------------- +* In all the following functions: +* msg is a string with at least 24 bytes free. +* A 24 bytes string will be concatenated to the existing content of msg. +*/ +/*- +* SureWare Initialisation function +* in param threadsafe, if !=0, thread safe enabled +* return SureWareHOOK_ERROR_UNIT_FAILURE if failure, 1 if success +*/ +typedef int SureWareHook_Init_t(char *const msg, int threadsafe); +extern SW_EXPORT SureWareHook_Init_t SureWareHook_Init; +/*- +* SureWare Finish function +*/ +typedef void SureWareHook_Finish_t(void); +extern SW_EXPORT SureWareHook_Finish_t SureWareHook_Finish; +/*- +* PRE_CONDITION: +* DO NOT CALL ANY OF THE FOLLOWING FUNCTIONS IN CASE OF INIT FAILURE +*/ +/*- +* SureWare RAND Bytes function +* In case of failure, the content of buf is unpredictable. +* return 1 if success +* SureWareHOOK_ERROR_FALLBACK if function not available in hardware +* SureWareHOOK_ERROR_FAILED if error while processing +* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure +* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf +* +* in/out param buf : a num bytes long buffer where random bytes will be put +* in param num : the number of bytes into buf +*/ +typedef int SureWareHook_Rand_Bytes_t(char *const msg, unsigned char *buf, + int num); +extern SW_EXPORT SureWareHook_Rand_Bytes_t SureWareHook_Rand_Bytes; + +/*- +* SureWare RAND Seed function +* Adds some seed to the Hardware Random Number Generator +* return 1 if success +* SureWareHOOK_ERROR_FALLBACK if function not available in hardware +* SureWareHOOK_ERROR_FAILED if error while processing +* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure +* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf +* +* in param buf : the seed to add into the HRNG +* in param num : the number of bytes into buf +*/ +typedef int SureWareHook_Rand_Seed_t(char *const msg, const void *buf, + int num); +extern SW_EXPORT SureWareHook_Rand_Seed_t SureWareHook_Rand_Seed; + +/*- +* SureWare Load Private Key function +* return 1 if success +* SureWareHOOK_ERROR_FAILED if error while processing +* No hardware is contact for this function. +* +* in param key_id :the name of the private protected key file without the extension + ".sws" +* out param hptr : a pointer to a buffer allocated by SureWare_Hook +* out param num: the effective key length in bytes +* out param keytype: 1 if RSA 2 if DSA +*/ +typedef int SureWareHook_Load_Privkey_t(char *const msg, const char *key_id, + char **hptr, unsigned long *num, + char *keytype); +extern SW_EXPORT SureWareHook_Load_Privkey_t SureWareHook_Load_Privkey; + +/*- +* SureWare Info Public Key function +* return 1 if success +* SureWareHOOK_ERROR_FAILED if error while processing +* No hardware is contact for this function. +* +* in param key_id :the name of the private protected key file without the extension + ".swp" +* out param hptr : a pointer to a buffer allocated by SureWare_Hook +* out param num: the effective key length in bytes +* out param keytype: 1 if RSA 2 if DSA +*/ +typedef int SureWareHook_Info_Pubkey_t(char *const msg, const char *key_id, + unsigned long *num, char *keytype); +extern SW_EXPORT SureWareHook_Info_Pubkey_t SureWareHook_Info_Pubkey; + +/*- +* SureWare Load Public Key function +* return 1 if success +* SureWareHOOK_ERROR_FAILED if error while processing +* No hardware is contact for this function. +* +* in param key_id :the name of the public protected key file without the extension + ".swp" +* in param num : the bytes size of n and e +* out param n: where to write modulus in bn format +* out param e: where to write exponent in bn format +*/ +typedef int SureWareHook_Load_Rsa_Pubkey_t(char *const msg, + const char *key_id, + unsigned long num, + unsigned long *n, + unsigned long *e); +extern SW_EXPORT SureWareHook_Load_Rsa_Pubkey_t SureWareHook_Load_Rsa_Pubkey; + +/*- +* SureWare Load DSA Public Key function +* return 1 if success +* SureWareHOOK_ERROR_FAILED if error while processing +* No hardware is contact for this function. +* +* in param key_id :the name of the public protected key file without the extension + ".swp" +* in param num : the bytes size of n and e +* out param pub: where to write pub key in bn format +* out param p: where to write prime in bn format +* out param q: where to write sunprime (length 20 bytes) in bn format +* out param g: where to write base in bn format +*/ +typedef int SureWareHook_Load_Dsa_Pubkey_t(char *const msg, + const char *key_id, + unsigned long num, + unsigned long *pub, + unsigned long *p, unsigned long *q, + unsigned long *g); +extern SW_EXPORT SureWareHook_Load_Dsa_Pubkey_t SureWareHook_Load_Dsa_Pubkey; + +/*- +* SureWare Free function +* Destroy the key into the hardware if destroy==1 +*/ +typedef void SureWareHook_Free_t(char *p, int destroy); +extern SW_EXPORT SureWareHook_Free_t SureWareHook_Free; + +#define SUREWARE_PKCS1_PAD 1 +#define SUREWARE_ISO9796_PAD 2 +#define SUREWARE_NO_PAD 0 +/*- +* SureWare RSA Private Decryption +* return 1 if success +* SureWareHOOK_ERROR_FAILED if error while processing +* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure +* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf +* +* in param flen : byte size of from and to +* in param from : encrypted data buffer, should be a not-null valid pointer +* out param tlen: byte size of decrypted data, if error, unexpected value +* out param to : decrypted data buffer, should be a not-null valid pointer +* in param prsa: a protected key pointer, should be a not-null valid pointer +* int padding: padding id as follow +* SUREWARE_PKCS1_PAD +* SUREWARE_NO_PAD +* +*/ +typedef int SureWareHook_Rsa_Priv_Dec_t(char *const msg, int flen, + unsigned char *from, int *tlen, + unsigned char *to, char *prsa, + int padding); +extern SW_EXPORT SureWareHook_Rsa_Priv_Dec_t SureWareHook_Rsa_Priv_Dec; +/*- +* SureWare RSA Signature +* return 1 if success +* SureWareHOOK_ERROR_FAILED if error while processing +* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure +* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf +* +* in param flen : byte size of from and to +* in param from : encrypted data buffer, should be a not-null valid pointer +* out param tlen: byte size of decrypted data, if error, unexpected value +* out param to : decrypted data buffer, should be a not-null valid pointer +* in param prsa: a protected key pointer, should be a not-null valid pointer +* int padding: padding id as follow +* SUREWARE_PKCS1_PAD +* SUREWARE_ISO9796_PAD +* +*/ +typedef int SureWareHook_Rsa_Sign_t(char *const msg, int flen, + unsigned char *from, int *tlen, + unsigned char *to, char *prsa, + int padding); +extern SW_EXPORT SureWareHook_Rsa_Sign_t SureWareHook_Rsa_Sign; +/*- +* SureWare DSA Signature +* return 1 if success +* SureWareHOOK_ERROR_FAILED if error while processing +* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure +* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf +* +* in param flen : byte size of from and to +* in param from : encrypted data buffer, should be a not-null valid pointer +* out param to : decrypted data buffer, should be a 40bytes valid pointer +* in param pdsa: a protected key pointer, should be a not-null valid pointer +* +*/ +typedef int SureWareHook_Dsa_Sign_t(char *const msg, int flen, + const unsigned char *from, + unsigned long *r, unsigned long *s, + char *pdsa); +extern SW_EXPORT SureWareHook_Dsa_Sign_t SureWareHook_Dsa_Sign; + +/*- +* SureWare Mod Exp +* return 1 if success +* SureWareHOOK_ERROR_FAILED if error while processing +* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure +* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf +* +* mod and res are mlen bytes long. +* exp is elen bytes long +* data is dlen bytes long +* mlen,elen and dlen are all multiple of sizeof(unsigned long) +*/ +typedef int SureWareHook_Mod_Exp_t(char *const msg, int mlen, + const unsigned long *mod, int elen, + const unsigned long *exponent, int dlen, + unsigned long *data, unsigned long *res); +extern SW_EXPORT SureWareHook_Mod_Exp_t SureWareHook_Mod_Exp; diff --git a/Sources/COpenSSL/symhacks.h b/Sources/COpenSSL/symhacks.h new file mode 100644 index 00000000..f5677389 --- /dev/null +++ b/Sources/COpenSSL/symhacks.h @@ -0,0 +1,518 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SYMHACKS_H +# define HEADER_SYMHACKS_H + +# include "e_os2.h" + +/* + * Hacks to solve the problem with linkers incapable of handling very long + * symbol names. In the case of VMS, the limit is 31 characters on VMS for + * VAX. + */ +/* + * Note that this affects util/libeay.num and util/ssleay.num... you may + * change those manually, but that's not recommended, as those files are + * controlled centrally and updated on Unix, and the central definition may + * disagree with yours, which in turn may come with shareable library + * incompatibilities. + */ +# ifdef OPENSSL_SYS_VMS + +/* Hack a long name in crypto/ex_data.c */ +# undef CRYPTO_get_ex_data_implementation +# define CRYPTO_get_ex_data_implementation CRYPTO_get_ex_data_impl +# undef CRYPTO_set_ex_data_implementation +# define CRYPTO_set_ex_data_implementation CRYPTO_set_ex_data_impl + +/* Hack a long name in crypto/asn1/a_mbstr.c */ +# undef ASN1_STRING_set_default_mask_asc +# define ASN1_STRING_set_default_mask_asc ASN1_STRING_set_def_mask_asc + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */ +# undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO +# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO i2d_ASN1_SET_OF_PKCS7_SIGINF +# undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO +# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO d2i_ASN1_SET_OF_PKCS7_SIGINF +# endif + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */ +# undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO +# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO i2d_ASN1_SET_OF_PKCS7_RECINF +# undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO +# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO d2i_ASN1_SET_OF_PKCS7_RECINF +# endif + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */ +# undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION +# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION i2d_ASN1_SET_OF_ACC_DESC +# undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION +# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION d2i_ASN1_SET_OF_ACC_DESC +# endif + +/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */ +# undef PEM_read_NETSCAPE_CERT_SEQUENCE +# define PEM_read_NETSCAPE_CERT_SEQUENCE PEM_read_NS_CERT_SEQ +# undef PEM_write_NETSCAPE_CERT_SEQUENCE +# define PEM_write_NETSCAPE_CERT_SEQUENCE PEM_write_NS_CERT_SEQ +# undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_read_bio_NETSCAPE_CERT_SEQUENCE PEM_read_bio_NS_CERT_SEQ +# undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_write_bio_NETSCAPE_CERT_SEQUENCE PEM_write_bio_NS_CERT_SEQ +# undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ + +/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */ +# undef PEM_read_PKCS8_PRIV_KEY_INFO +# define PEM_read_PKCS8_PRIV_KEY_INFO PEM_read_P8_PRIV_KEY_INFO +# undef PEM_write_PKCS8_PRIV_KEY_INFO +# define PEM_write_PKCS8_PRIV_KEY_INFO PEM_write_P8_PRIV_KEY_INFO +# undef PEM_read_bio_PKCS8_PRIV_KEY_INFO +# define PEM_read_bio_PKCS8_PRIV_KEY_INFO PEM_read_bio_P8_PRIV_KEY_INFO +# undef PEM_write_bio_PKCS8_PRIV_KEY_INFO +# define PEM_write_bio_PKCS8_PRIV_KEY_INFO PEM_write_bio_P8_PRIV_KEY_INFO +# undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO +# define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO PEM_wrt_cb_bio_P8_PRIV_KEY_INFO + +/* Hack other PEM names */ +# undef PEM_write_bio_PKCS8PrivateKey_nid +# define PEM_write_bio_PKCS8PrivateKey_nid PEM_write_bio_PKCS8PrivKey_nid + +/* Hack some long X509 names */ +# undef X509_REVOKED_get_ext_by_critical +# define X509_REVOKED_get_ext_by_critical X509_REVOKED_get_ext_by_critic +# undef X509_policy_tree_get0_user_policies +# define X509_policy_tree_get0_user_policies X509_pcy_tree_get0_usr_policies +# undef X509_policy_node_get0_qualifiers +# define X509_policy_node_get0_qualifiers X509_pcy_node_get0_qualifiers +# undef X509_STORE_CTX_get_explicit_policy +# define X509_STORE_CTX_get_explicit_policy X509_STORE_CTX_get_expl_policy +# undef X509_STORE_CTX_get0_current_issuer +# define X509_STORE_CTX_get0_current_issuer X509_STORE_CTX_get0_cur_issuer + +/* Hack some long CRYPTO names */ +# undef CRYPTO_set_dynlock_destroy_callback +# define CRYPTO_set_dynlock_destroy_callback CRYPTO_set_dynlock_destroy_cb +# undef CRYPTO_set_dynlock_create_callback +# define CRYPTO_set_dynlock_create_callback CRYPTO_set_dynlock_create_cb +# undef CRYPTO_set_dynlock_lock_callback +# define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb +# undef CRYPTO_get_dynlock_lock_callback +# define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb +# undef CRYPTO_get_dynlock_destroy_callback +# define CRYPTO_get_dynlock_destroy_callback CRYPTO_get_dynlock_destroy_cb +# undef CRYPTO_get_dynlock_create_callback +# define CRYPTO_get_dynlock_create_callback CRYPTO_get_dynlock_create_cb +# undef CRYPTO_set_locked_mem_ex_functions +# define CRYPTO_set_locked_mem_ex_functions CRYPTO_set_locked_mem_ex_funcs +# undef CRYPTO_get_locked_mem_ex_functions +# define CRYPTO_get_locked_mem_ex_functions CRYPTO_get_locked_mem_ex_funcs + +/* Hack some long SSL/TLS names */ +# undef SSL_CTX_set_default_verify_paths +# define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths +# undef SSL_get_ex_data_X509_STORE_CTX_idx +# define SSL_get_ex_data_X509_STORE_CTX_idx SSL_get_ex_d_X509_STORE_CTX_idx +# undef SSL_add_file_cert_subjects_to_stack +# define SSL_add_file_cert_subjects_to_stack SSL_add_file_cert_subjs_to_stk +# undef SSL_add_dir_cert_subjects_to_stack +# define SSL_add_dir_cert_subjects_to_stack SSL_add_dir_cert_subjs_to_stk +# undef SSL_CTX_use_certificate_chain_file +# define SSL_CTX_use_certificate_chain_file SSL_CTX_use_cert_chain_file +# undef SSL_CTX_set_cert_verify_callback +# define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb +# undef SSL_CTX_set_default_passwd_cb_userdata +# define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud +# undef SSL_COMP_get_compression_methods +# define SSL_COMP_get_compression_methods SSL_COMP_get_compress_methods +# undef SSL_COMP_set0_compression_methods +# define SSL_COMP_set0_compression_methods SSL_COMP_set0_compress_methods +# undef SSL_COMP_free_compression_methods +# define SSL_COMP_free_compression_methods SSL_COMP_free_compress_methods +# undef ssl_add_clienthello_renegotiate_ext +# define ssl_add_clienthello_renegotiate_ext ssl_add_clienthello_reneg_ext +# undef ssl_add_serverhello_renegotiate_ext +# define ssl_add_serverhello_renegotiate_ext ssl_add_serverhello_reneg_ext +# undef ssl_parse_clienthello_renegotiate_ext +# define ssl_parse_clienthello_renegotiate_ext ssl_parse_clienthello_reneg_ext +# undef ssl_parse_serverhello_renegotiate_ext +# define ssl_parse_serverhello_renegotiate_ext ssl_parse_serverhello_reneg_ext +# undef SSL_srp_server_param_with_username +# define SSL_srp_server_param_with_username SSL_srp_server_param_with_un +# undef SSL_CTX_set_srp_client_pwd_callback +# define SSL_CTX_set_srp_client_pwd_callback SSL_CTX_set_srp_client_pwd_cb +# undef SSL_CTX_set_srp_verify_param_callback +# define SSL_CTX_set_srp_verify_param_callback SSL_CTX_set_srp_vfy_param_cb +# undef SSL_CTX_set_srp_username_callback +# define SSL_CTX_set_srp_username_callback SSL_CTX_set_srp_un_cb +# undef ssl_add_clienthello_use_srtp_ext +# define ssl_add_clienthello_use_srtp_ext ssl_add_clihello_use_srtp_ext +# undef ssl_add_serverhello_use_srtp_ext +# define ssl_add_serverhello_use_srtp_ext ssl_add_serhello_use_srtp_ext +# undef ssl_parse_clienthello_use_srtp_ext +# define ssl_parse_clienthello_use_srtp_ext ssl_parse_clihello_use_srtp_ext +# undef ssl_parse_serverhello_use_srtp_ext +# define ssl_parse_serverhello_use_srtp_ext ssl_parse_serhello_use_srtp_ext +# undef SSL_CTX_set_next_protos_advertised_cb +# define SSL_CTX_set_next_protos_advertised_cb SSL_CTX_set_next_protos_adv_cb +# undef SSL_CTX_set_next_proto_select_cb +# define SSL_CTX_set_next_proto_select_cb SSL_CTX_set_next_proto_sel_cb + +# undef tls1_send_server_supplemental_data +# define tls1_send_server_supplemental_data tls1_send_server_suppl_data +# undef tls1_send_client_supplemental_data +# define tls1_send_client_supplemental_data tls1_send_client_suppl_data +# undef tls1_get_server_supplemental_data +# define tls1_get_server_supplemental_data tls1_get_server_suppl_data +# undef tls1_get_client_supplemental_data +# define tls1_get_client_supplemental_data tls1_get_client_suppl_data + +# undef ssl3_cbc_record_digest_supported +# define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support +# undef ssl_check_clienthello_tlsext_late +# define ssl_check_clienthello_tlsext_late ssl_check_clihello_tlsext_late +# undef ssl_check_clienthello_tlsext_early +# define ssl_check_clienthello_tlsext_early ssl_check_clihello_tlsext_early + +/* Hack some RSA long names */ +# undef RSA_padding_check_PKCS1_OAEP_mgf1 +# define RSA_padding_check_PKCS1_OAEP_mgf1 RSA_pad_check_PKCS1_OAEP_mgf1 + +/* Hack some ENGINE long names */ +# undef ENGINE_get_default_BN_mod_exp_crt +# define ENGINE_get_default_BN_mod_exp_crt ENGINE_get_def_BN_mod_exp_crt +# undef ENGINE_set_default_BN_mod_exp_crt +# define ENGINE_set_default_BN_mod_exp_crt ENGINE_set_def_BN_mod_exp_crt +# undef ENGINE_set_load_privkey_function +# define ENGINE_set_load_privkey_function ENGINE_set_load_privkey_fn +# undef ENGINE_get_load_privkey_function +# define ENGINE_get_load_privkey_function ENGINE_get_load_privkey_fn +# undef ENGINE_unregister_pkey_asn1_meths +# define ENGINE_unregister_pkey_asn1_meths ENGINE_unreg_pkey_asn1_meths +# undef ENGINE_register_all_pkey_asn1_meths +# define ENGINE_register_all_pkey_asn1_meths ENGINE_reg_all_pkey_asn1_meths +# undef ENGINE_set_default_pkey_asn1_meths +# define ENGINE_set_default_pkey_asn1_meths ENGINE_set_def_pkey_asn1_meths +# undef ENGINE_get_pkey_asn1_meth_engine +# define ENGINE_get_pkey_asn1_meth_engine ENGINE_get_pkey_asn1_meth_eng +# undef ENGINE_set_load_ssl_client_cert_function +# define ENGINE_set_load_ssl_client_cert_function \ + ENGINE_set_ld_ssl_clnt_cert_fn +# undef ENGINE_get_ssl_client_cert_function +# define ENGINE_get_ssl_client_cert_function ENGINE_get_ssl_client_cert_fn + +/* Hack some long OCSP names */ +# undef OCSP_REQUEST_get_ext_by_critical +# define OCSP_REQUEST_get_ext_by_critical OCSP_REQUEST_get_ext_by_crit +# undef OCSP_BASICRESP_get_ext_by_critical +# define OCSP_BASICRESP_get_ext_by_critical OCSP_BASICRESP_get_ext_by_crit +# undef OCSP_SINGLERESP_get_ext_by_critical +# define OCSP_SINGLERESP_get_ext_by_critical OCSP_SINGLERESP_get_ext_by_crit + +/* Hack some long DES names */ +# undef _ossl_old_des_ede3_cfb64_encrypt +# define _ossl_old_des_ede3_cfb64_encrypt _ossl_odes_ede3_cfb64_encrypt +# undef _ossl_old_des_ede3_ofb64_encrypt +# define _ossl_old_des_ede3_ofb64_encrypt _ossl_odes_ede3_ofb64_encrypt + +/* Hack some long EVP names */ +# undef OPENSSL_add_all_algorithms_noconf +# define OPENSSL_add_all_algorithms_noconf OPENSSL_add_all_algo_noconf +# undef OPENSSL_add_all_algorithms_conf +# define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algo_conf +# undef EVP_PKEY_meth_set_verify_recover +# define EVP_PKEY_meth_set_verify_recover EVP_PKEY_meth_set_vrfy_recover +# undef EVP_PKEY_meth_get_verify_recover +# define EVP_PKEY_meth_get_verify_recover EVP_PKEY_meth_get_vrfy_recover + +/* Hack some long EC names */ +# undef EC_GROUP_set_point_conversion_form +# define EC_GROUP_set_point_conversion_form EC_GROUP_set_point_conv_form +# undef EC_GROUP_get_point_conversion_form +# define EC_GROUP_get_point_conversion_form EC_GROUP_get_point_conv_form +# undef EC_GROUP_clear_free_all_extra_data +# define EC_GROUP_clear_free_all_extra_data EC_GROUP_clr_free_all_xtra_data +# undef EC_KEY_set_public_key_affine_coordinates +# define EC_KEY_set_public_key_affine_coordinates \ + EC_KEY_set_pub_key_aff_coords +# undef EC_POINT_set_Jprojective_coordinates_GFp +# define EC_POINT_set_Jprojective_coordinates_GFp \ + EC_POINT_set_Jproj_coords_GFp +# undef EC_POINT_get_Jprojective_coordinates_GFp +# define EC_POINT_get_Jprojective_coordinates_GFp \ + EC_POINT_get_Jproj_coords_GFp +# undef EC_POINT_set_affine_coordinates_GFp +# define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coords_GFp +# undef EC_POINT_get_affine_coordinates_GFp +# define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coords_GFp +# undef EC_POINT_set_compressed_coordinates_GFp +# define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp +# undef EC_POINT_set_affine_coordinates_GF2m +# define EC_POINT_set_affine_coordinates_GF2m EC_POINT_set_affine_coords_GF2m +# undef EC_POINT_get_affine_coordinates_GF2m +# define EC_POINT_get_affine_coordinates_GF2m EC_POINT_get_affine_coords_GF2m +# undef EC_POINT_set_compressed_coordinates_GF2m +# define EC_POINT_set_compressed_coordinates_GF2m \ + EC_POINT_set_compr_coords_GF2m +# undef ec_GF2m_simple_group_clear_finish +# define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish +# undef ec_GF2m_simple_group_check_discriminant +# define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim +# undef ec_GF2m_simple_point_clear_finish +# define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish +# undef ec_GF2m_simple_point_set_to_infinity +# define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf +# undef ec_GF2m_simple_points_make_affine +# define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine +# undef ec_GF2m_simple_point_set_affine_coordinates +# define ec_GF2m_simple_point_set_affine_coordinates \ + ec_GF2m_smp_pt_set_af_coords +# undef ec_GF2m_simple_point_get_affine_coordinates +# define ec_GF2m_simple_point_get_affine_coordinates \ + ec_GF2m_smp_pt_get_af_coords +# undef ec_GF2m_simple_set_compressed_coordinates +# define ec_GF2m_simple_set_compressed_coordinates \ + ec_GF2m_smp_set_compr_coords +# undef ec_GFp_simple_group_set_curve_GFp +# define ec_GFp_simple_group_set_curve_GFp ec_GFp_simple_grp_set_curve_GFp +# undef ec_GFp_simple_group_get_curve_GFp +# define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp +# undef ec_GFp_simple_group_clear_finish +# define ec_GFp_simple_group_clear_finish ec_GFp_simple_grp_clear_finish +# undef ec_GFp_simple_group_set_generator +# define ec_GFp_simple_group_set_generator ec_GFp_simple_grp_set_generator +# undef ec_GFp_simple_group_get0_generator +# define ec_GFp_simple_group_get0_generator ec_GFp_simple_grp_gt0_generator +# undef ec_GFp_simple_group_get_cofactor +# define ec_GFp_simple_group_get_cofactor ec_GFp_simple_grp_get_cofactor +# undef ec_GFp_simple_point_clear_finish +# define ec_GFp_simple_point_clear_finish ec_GFp_simple_pt_clear_finish +# undef ec_GFp_simple_point_set_to_infinity +# define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf +# undef ec_GFp_simple_points_make_affine +# define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine +# undef ec_GFp_simple_set_Jprojective_coordinates_GFp +# define ec_GFp_simple_set_Jprojective_coordinates_GFp \ + ec_GFp_smp_set_Jproj_coords_GFp +# undef ec_GFp_simple_get_Jprojective_coordinates_GFp +# define ec_GFp_simple_get_Jprojective_coordinates_GFp \ + ec_GFp_smp_get_Jproj_coords_GFp +# undef ec_GFp_simple_point_set_affine_coordinates_GFp +# define ec_GFp_simple_point_set_affine_coordinates_GFp \ + ec_GFp_smp_pt_set_af_coords_GFp +# undef ec_GFp_simple_point_get_affine_coordinates_GFp +# define ec_GFp_simple_point_get_affine_coordinates_GFp \ + ec_GFp_smp_pt_get_af_coords_GFp +# undef ec_GFp_simple_set_compressed_coordinates_GFp +# define ec_GFp_simple_set_compressed_coordinates_GFp \ + ec_GFp_smp_set_compr_coords_GFp +# undef ec_GFp_simple_point_set_affine_coordinates +# define ec_GFp_simple_point_set_affine_coordinates \ + ec_GFp_smp_pt_set_af_coords +# undef ec_GFp_simple_point_get_affine_coordinates +# define ec_GFp_simple_point_get_affine_coordinates \ + ec_GFp_smp_pt_get_af_coords +# undef ec_GFp_simple_set_compressed_coordinates +# define ec_GFp_simple_set_compressed_coordinates \ + ec_GFp_smp_set_compr_coords +# undef ec_GFp_simple_group_check_discriminant +# define ec_GFp_simple_group_check_discriminant ec_GFp_simple_grp_chk_discrim + +/* Hack som long STORE names */ +# undef STORE_method_set_initialise_function +# define STORE_method_set_initialise_function STORE_meth_set_initialise_fn +# undef STORE_method_set_cleanup_function +# define STORE_method_set_cleanup_function STORE_meth_set_cleanup_fn +# undef STORE_method_set_generate_function +# define STORE_method_set_generate_function STORE_meth_set_generate_fn +# undef STORE_method_set_modify_function +# define STORE_method_set_modify_function STORE_meth_set_modify_fn +# undef STORE_method_set_revoke_function +# define STORE_method_set_revoke_function STORE_meth_set_revoke_fn +# undef STORE_method_set_delete_function +# define STORE_method_set_delete_function STORE_meth_set_delete_fn +# undef STORE_method_set_list_start_function +# define STORE_method_set_list_start_function STORE_meth_set_list_start_fn +# undef STORE_method_set_list_next_function +# define STORE_method_set_list_next_function STORE_meth_set_list_next_fn +# undef STORE_method_set_list_end_function +# define STORE_method_set_list_end_function STORE_meth_set_list_end_fn +# undef STORE_method_set_update_store_function +# define STORE_method_set_update_store_function STORE_meth_set_update_store_fn +# undef STORE_method_set_lock_store_function +# define STORE_method_set_lock_store_function STORE_meth_set_lock_store_fn +# undef STORE_method_set_unlock_store_function +# define STORE_method_set_unlock_store_function STORE_meth_set_unlock_store_fn +# undef STORE_method_get_initialise_function +# define STORE_method_get_initialise_function STORE_meth_get_initialise_fn +# undef STORE_method_get_cleanup_function +# define STORE_method_get_cleanup_function STORE_meth_get_cleanup_fn +# undef STORE_method_get_generate_function +# define STORE_method_get_generate_function STORE_meth_get_generate_fn +# undef STORE_method_get_modify_function +# define STORE_method_get_modify_function STORE_meth_get_modify_fn +# undef STORE_method_get_revoke_function +# define STORE_method_get_revoke_function STORE_meth_get_revoke_fn +# undef STORE_method_get_delete_function +# define STORE_method_get_delete_function STORE_meth_get_delete_fn +# undef STORE_method_get_list_start_function +# define STORE_method_get_list_start_function STORE_meth_get_list_start_fn +# undef STORE_method_get_list_next_function +# define STORE_method_get_list_next_function STORE_meth_get_list_next_fn +# undef STORE_method_get_list_end_function +# define STORE_method_get_list_end_function STORE_meth_get_list_end_fn +# undef STORE_method_get_update_store_function +# define STORE_method_get_update_store_function STORE_meth_get_update_store_fn +# undef STORE_method_get_lock_store_function +# define STORE_method_get_lock_store_function STORE_meth_get_lock_store_fn +# undef STORE_method_get_unlock_store_function +# define STORE_method_get_unlock_store_function STORE_meth_get_unlock_store_fn + +/* Hack some long TS names */ +# undef TS_RESP_CTX_set_status_info_cond +# define TS_RESP_CTX_set_status_info_cond TS_RESP_CTX_set_stat_info_cond +# undef TS_RESP_CTX_set_clock_precision_digits +# define TS_RESP_CTX_set_clock_precision_digits TS_RESP_CTX_set_clk_prec_digits +# undef TS_CONF_set_clock_precision_digits +# define TS_CONF_set_clock_precision_digits TS_CONF_set_clk_prec_digits + +/* Hack some long CMS names */ +# undef CMS_RecipientInfo_ktri_get0_algs +# define CMS_RecipientInfo_ktri_get0_algs CMS_RecipInfo_ktri_get0_algs +# undef CMS_RecipientInfo_ktri_get0_signer_id +# define CMS_RecipientInfo_ktri_get0_signer_id CMS_RecipInfo_ktri_get0_sigr_id +# undef CMS_OtherRevocationInfoFormat_it +# define CMS_OtherRevocationInfoFormat_it CMS_OtherRevocInfoFormat_it +# undef CMS_KeyAgreeRecipientIdentifier_it +# define CMS_KeyAgreeRecipientIdentifier_it CMS_KeyAgreeRecipIdentifier_it +# undef CMS_OriginatorIdentifierOrKey_it +# define CMS_OriginatorIdentifierOrKey_it CMS_OriginatorIdOrKey_it +# undef cms_SignerIdentifier_get0_signer_id +# define cms_SignerIdentifier_get0_signer_id cms_SignerId_get0_signer_id +# undef CMS_RecipientInfo_kari_get0_orig_id +# define CMS_RecipientInfo_kari_get0_orig_id CMS_RecipInfo_kari_get0_orig_id +# undef CMS_RecipientInfo_kari_get0_reks +# define CMS_RecipientInfo_kari_get0_reks CMS_RecipInfo_kari_get0_reks +# undef CMS_RecipientEncryptedKey_cert_cmp +# define CMS_RecipientEncryptedKey_cert_cmp CMS_RecipEncryptedKey_cert_cmp +# undef CMS_RecipientInfo_kari_set0_pkey +# define CMS_RecipientInfo_kari_set0_pkey CMS_RecipInfo_kari_set0_pkey +# undef CMS_RecipientEncryptedKey_get0_id +# define CMS_RecipientEncryptedKey_get0_id CMS_RecipEncryptedKey_get0_id +# undef CMS_RecipientInfo_kari_orig_id_cmp +# define CMS_RecipientInfo_kari_orig_id_cmp CMS_RecipInfo_kari_orig_id_cmp + +/* Hack some long DTLS1 names */ +# undef dtls1_retransmit_buffered_messages +# define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs + +/* Hack some long SRP names */ +# undef SRP_generate_server_master_secret +# define SRP_generate_server_master_secret SRP_gen_server_master_secret +# undef SRP_generate_client_master_secret +# define SRP_generate_client_master_secret SRP_gen_client_master_secret + +/* Hack some long UI names */ +# undef UI_method_get_prompt_constructor +# define UI_method_get_prompt_constructor UI_method_get_prompt_constructr +# undef UI_method_set_prompt_constructor +# define UI_method_set_prompt_constructor UI_method_set_prompt_constructr + +# endif /* defined OPENSSL_SYS_VMS */ + +/* Case insensitive linking causes problems.... */ +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) +# undef ERR_load_CRYPTO_strings +# define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +# undef OCSP_crlID_new +# define OCSP_crlID_new OCSP_crlID2_new + +# undef d2i_ECPARAMETERS +# define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS +# undef i2d_ECPARAMETERS +# define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS +# undef d2i_ECPKPARAMETERS +# define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS +# undef i2d_ECPKPARAMETERS +# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS + +/* + * These functions do not seem to exist! However, I'm paranoid... Original + * command in x509v3.h: These functions are being redefined in another + * directory, and clash when the linker is case-insensitive, so let's hide + * them a little, by giving them an extra 'o' at the beginning of the name... + */ +# undef X509v3_cleanup_extensions +# define X509v3_cleanup_extensions oX509v3_cleanup_extensions +# undef X509v3_add_extension +# define X509v3_add_extension oX509v3_add_extension +# undef X509v3_add_netscape_extensions +# define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions +# undef X509v3_add_standard_extensions +# define X509v3_add_standard_extensions oX509v3_add_standard_extensions + +/* This one clashes with CMS_data_create */ +# undef cms_Data_create +# define cms_Data_create priv_cms_Data_create + +# endif + +#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/Sources/COpenSSL/t1_.c b/Sources/COpenSSL/t1_.c new file mode 100644 index 00000000..515776b8 --- /dev/null +++ b/Sources/COpenSSL/t1_.c @@ -0,0 +1,8110 @@ +/* ssl/t1_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "ssl_locl.h" +#include "buffer.h" +#include "rand.h" +#include "objects.h" +#include "evp.h" + +static const SSL_METHOD *tls1_get_client_method(int ver); +static const SSL_METHOD *tls1_get_client_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return TLSv1_2_client_method(); + if (ver == TLS1_1_VERSION) + return TLSv1_1_client_method(); + if (ver == TLS1_VERSION) + return TLSv1_client_method(); + return NULL; +} + +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method, + ssl_undefined_function, + ssl3_connect, + tls1_get_client_method, TLSv1_2_enc_data) + + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method, + ssl_undefined_function, + ssl3_connect, + tls1_get_client_method, TLSv1_1_enc_data) + + IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method, + ssl_undefined_function, + ssl3_connect, tls1_get_client_method, TLSv1_enc_data) +/* ssl/t1_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +// #include "ssl_locl.h" +#ifndef OPENSSL_NO_COMP +# include "comp.h" +#endif +// #include "evp.h" +#include "hmac.h" +#include "md5.h" +// #include "rand.h" +#ifdef KSSL_DEBUG +# include "des.h" +#endif + +/* seed1 through seed5 are virtually concatenated */ +static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, + int sec_len, + const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + const void *seed4, int seed4_len, + const void *seed5, int seed5_len, + unsigned char *out, int olen) +{ + int chunk; + size_t j; + EVP_MD_CTX ctx, ctx_tmp, ctx_init; + EVP_PKEY *mac_key; + unsigned char A1[EVP_MAX_MD_SIZE]; + size_t A1_len; + int ret = 0; + + chunk = EVP_MD_size(md); + OPENSSL_assert(chunk >= 0); + + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_init(&ctx_tmp); + EVP_MD_CTX_init(&ctx_init); + EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); + if (!mac_key) + goto err; + if (!EVP_DigestSignInit(&ctx_init, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) + goto err; + if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) + goto err; + if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) + goto err; + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + + for (;;) { + /* Reinit mac contexts */ + if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) + goto err; + if (!EVP_DigestSignUpdate(&ctx, A1, A1_len)) + goto err; + if (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) + goto err; + if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) + goto err; + if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) + goto err; + + if (olen > chunk) { + if (!EVP_DigestSignFinal(&ctx, out, &j)) + goto err; + out += j; + olen -= j; + /* calc the next A1 value */ + if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) + goto err; + } else { /* last one */ + + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + memcpy(out, A1, olen); + break; + } + } + ret = 1; + err: + EVP_PKEY_free(mac_key); + EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_cleanup(&ctx_tmp); + EVP_MD_CTX_cleanup(&ctx_init); + OPENSSL_cleanse(A1, sizeof(A1)); + return ret; +} + +/* seed1 through seed5 are virtually concatenated */ +static int tls1_PRF(long digest_mask, + const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + const void *seed4, int seed4_len, + const void *seed5, int seed5_len, + const unsigned char *sec, int slen, + unsigned char *out1, unsigned char *out2, int olen) +{ + int len, i, idx, count; + const unsigned char *S1; + long m; + const EVP_MD *md; + int ret = 0; + + /* Count number of digests and partition sec evenly */ + count = 0; + for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { + if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) + count++; + } + if (!count) { + /* Should never happen */ + SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); + goto err; + } + len = slen / count; + if (count == 1) + slen = 0; + S1 = sec; + memset(out1, 0, olen); + for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { + if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) { + if (!md) { + SSLerr(SSL_F_TLS1_PRF, SSL_R_UNSUPPORTED_DIGEST_TYPE); + goto err; + } + if (!tls1_P_hash(md, S1, len + (slen & 1), + seed1, seed1_len, seed2, seed2_len, seed3, + seed3_len, seed4, seed4_len, seed5, seed5_len, + out2, olen)) + goto err; + S1 += len; + for (i = 0; i < olen; i++) { + out1[i] ^= out2[i]; + } + } + } + ret = 1; + err: + return ret; +} + +static int tls1_generate_key_block(SSL *s, unsigned char *km, + unsigned char *tmp, int num) +{ + int ret; + ret = tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_KEY_EXPANSION_CONST, + TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random, + SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, + NULL, 0, NULL, 0, s->session->master_key, + s->session->master_key_length, km, tmp, num); +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_generate_key_block() ==> %d byte master_key =\n\t", + s->session->master_key_length); + { + int i; + for (i = 0; i < s->session->master_key_length; i++) { + fprintf(stderr, "%02X", s->session->master_key[i]); + } + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + return ret; +} + +int tls1_change_cipher_state(SSL *s, int which) +{ + static const unsigned char empty[] = ""; + unsigned char *p, *mac_secret; + unsigned char *exp_label; + unsigned char tmp1[EVP_MAX_KEY_LENGTH]; + unsigned char tmp2[EVP_MAX_KEY_LENGTH]; + unsigned char iv1[EVP_MAX_IV_LENGTH * 2]; + unsigned char iv2[EVP_MAX_IV_LENGTH * 2]; + unsigned char *ms, *key, *iv; + int client_write; + EVP_CIPHER_CTX *dd; + const EVP_CIPHER *c; +#ifndef OPENSSL_NO_COMP + const SSL_COMP *comp; +#endif + const EVP_MD *m; + int mac_type; + int *mac_secret_size; + EVP_MD_CTX *mac_ctx; + EVP_PKEY *mac_key; + int is_export, n, i, j, k, exp_label_len, cl; + int reuse_dd = 0; + + is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); + c = s->s3->tmp.new_sym_enc; + m = s->s3->tmp.new_hash; + mac_type = s->s3->tmp.new_mac_pkey_type; +#ifndef OPENSSL_NO_COMP + comp = s->s3->tmp.new_compression; +#endif + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_change_cipher_state(which= %d) w/\n", which); + fprintf(stderr, "\talg= %ld/%ld, comp= %p\n", + s->s3->tmp.new_cipher->algorithm_mkey, + s->s3->tmp.new_cipher->algorithm_auth, comp); + fprintf(stderr, "\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); + fprintf(stderr, "\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", + c->nid, c->block_size, c->key_len, c->iv_len); + fprintf(stderr, "\tkey_block: len= %d, data= ", + s->s3->tmp.key_block_length); + { + int i; + for (i = 0; i < s->s3->tmp.key_block_length; i++) + fprintf(stderr, "%02x", s->s3->tmp.key_block[i]); + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + + if (which & SSL3_CC_READ) { + if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; + + if (s->enc_read_ctx != NULL) + reuse_dd = 1; + else if ((s->enc_read_ctx = + OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) + goto err; + else + /* + * make sure it's intialized in case we exit later with an error + */ + EVP_CIPHER_CTX_init(s->enc_read_ctx); + dd = s->enc_read_ctx; + mac_ctx = ssl_replace_hash(&s->read_hash, NULL); + if (mac_ctx == NULL) + goto err; +#ifndef OPENSSL_NO_COMP + if (s->expand != NULL) { + COMP_CTX_free(s->expand); + s->expand = NULL; + } + if (comp != NULL) { + s->expand = COMP_CTX_new(comp->method); + if (s->expand == NULL) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, + SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + if (s->s3->rrec.comp == NULL) + s->s3->rrec.comp = (unsigned char *) + OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); + if (s->s3->rrec.comp == NULL) + goto err; + } +#endif + /* + * this is done by dtls1_reset_seq_numbers for DTLS + */ + if (!SSL_IS_DTLS(s)) + memset(&(s->s3->read_sequence[0]), 0, 8); + mac_secret = &(s->s3->read_mac_secret[0]); + mac_secret_size = &(s->s3->read_mac_secret_size); + } else { + if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; + if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) + reuse_dd = 1; + else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + dd = s->enc_write_ctx; + if (SSL_IS_DTLS(s)) { + mac_ctx = EVP_MD_CTX_create(); + if (mac_ctx == NULL) + goto err; + s->write_hash = mac_ctx; + } else { + mac_ctx = ssl_replace_hash(&s->write_hash, NULL); + if (mac_ctx == NULL) + goto err; + } +#ifndef OPENSSL_NO_COMP + if (s->compress != NULL) { + COMP_CTX_free(s->compress); + s->compress = NULL; + } + if (comp != NULL) { + s->compress = COMP_CTX_new(comp->method); + if (s->compress == NULL) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, + SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + } +#endif + /* + * this is done by dtls1_reset_seq_numbers for DTLS + */ + if (!SSL_IS_DTLS(s)) + memset(&(s->s3->write_sequence[0]), 0, 8); + mac_secret = &(s->s3->write_mac_secret[0]); + mac_secret_size = &(s->s3->write_mac_secret_size); + } + + if (reuse_dd) + EVP_CIPHER_CTX_cleanup(dd); + + p = s->s3->tmp.key_block; + i = *mac_secret_size = s->s3->tmp.new_mac_secret_size; + + cl = EVP_CIPHER_key_length(c); + j = is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? + cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; + /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ + /* If GCM mode only part of IV comes from PRF */ + if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) + k = EVP_GCM_TLS_FIXED_IV_LEN; + else + k = EVP_CIPHER_iv_length(c); + if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || + (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { + ms = &(p[0]); + n = i + i; + key = &(p[n]); + n += j + j; + iv = &(p[n]); + n += k + k; + exp_label = (unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; + exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; + client_write = 1; + } else { + n = i; + ms = &(p[n]); + n += i + j; + key = &(p[n]); + n += j + k; + iv = &(p[n]); + n += k; + exp_label = (unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; + exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; + client_write = 0; + } + + if (n > s->s3->tmp.key_block_length) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + + memcpy(mac_secret, ms, i); + + if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, + mac_secret, *mac_secret_size); + if (mac_key == NULL + || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) { + EVP_PKEY_free(mac_key); + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + EVP_PKEY_free(mac_key); + } +#ifdef TLS_DEBUG + printf("which = %04X\nmac key=", which); + { + int z; + for (z = 0; z < i; z++) + printf("%02X%c", ms[z], ((z + 1) % 16) ? ' ' : '\n'); + } +#endif + if (is_export) { + /* + * In here I set both the read and write key/iv to the same value + * since only the correct one will be used :-). + */ + if (!tls1_PRF(ssl_get_algorithm2(s), + exp_label, exp_label_len, + s->s3->client_random, SSL3_RANDOM_SIZE, + s->s3->server_random, SSL3_RANDOM_SIZE, + NULL, 0, NULL, 0, + key, j, tmp1, tmp2, EVP_CIPHER_key_length(c))) + goto err2; + key = tmp1; + + if (k > 0) { + if (!tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, + s->s3->server_random, SSL3_RANDOM_SIZE, + NULL, 0, NULL, 0, empty, 0, iv1, iv2, k * 2)) + goto err2; + if (client_write) + iv = iv1; + else + iv = &(iv1[k]); + } + } + + s->session->key_arg_length = 0; +#ifdef KSSL_DEBUG + { + int i; + fprintf(stderr, "EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); + fprintf(stderr, "\tkey= "); + for (i = 0; i < c->key_len; i++) + fprintf(stderr, "%02x", key[i]); + fprintf(stderr, "\n"); + fprintf(stderr, "\t iv= "); + for (i = 0; i < c->iv_len; i++) + fprintf(stderr, "%02x", iv[i]); + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + + if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { + if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE)) + || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv)) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + } else { + if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + } + /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ + if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size + && !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY, + *mac_secret_size, mac_secret)) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } +#ifdef OPENSSL_SSL_TRACE_CRYPTO + if (s->msg_callback) { + int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0; + if (*mac_secret_size) + s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC, + mac_secret, *mac_secret_size, + s, s->msg_callback_arg); + if (c->key_len) + s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, + key, c->key_len, s, s->msg_callback_arg); + if (k) { + if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) + wh |= TLS1_RT_CRYPTO_FIXED_IV; + else + wh |= TLS1_RT_CRYPTO_IV; + s->msg_callback(2, s->version, wh, iv, k, s, s->msg_callback_arg); + } + } +#endif + +#ifdef TLS_DEBUG + printf("which = %04X\nkey=", which); + { + int z; + for (z = 0; z < EVP_CIPHER_key_length(c); z++) + printf("%02X%c", key[z], ((z + 1) % 16) ? ' ' : '\n'); + } + printf("\niv="); + { + int z; + for (z = 0; z < k; z++) + printf("%02X%c", iv[z], ((z + 1) % 16) ? ' ' : '\n'); + } + printf("\n"); +#endif + + OPENSSL_cleanse(tmp1, sizeof(tmp1)); + OPENSSL_cleanse(tmp2, sizeof(tmp1)); + OPENSSL_cleanse(iv1, sizeof(iv1)); + OPENSSL_cleanse(iv2, sizeof(iv2)); + return (1); + err: + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); + err2: + return (0); +} + +int tls1_setup_key_block(SSL *s) +{ + unsigned char *p1, *p2 = NULL; + const EVP_CIPHER *c; + const EVP_MD *hash; + int num; + SSL_COMP *comp; + int mac_type = NID_undef, mac_secret_size = 0; + int ret = 0; + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_setup_key_block()\n"); +#endif /* KSSL_DEBUG */ + + if (s->s3->tmp.key_block_length != 0) + return (1); + + if (!ssl_cipher_get_evp + (s->session, &c, &hash, &mac_type, &mac_secret_size, &comp)) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } + + s->s3->tmp.new_sym_enc = c; + s->s3->tmp.new_hash = hash; + s->s3->tmp.new_mac_pkey_type = mac_type; + s->s3->tmp.new_mac_secret_size = mac_secret_size; + num = + EVP_CIPHER_key_length(c) + mac_secret_size + EVP_CIPHER_iv_length(c); + num *= 2; + + ssl3_cleanup_key_block(s); + + if ((p1 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + goto err; + } + + s->s3->tmp.key_block_length = num; + s->s3->tmp.key_block = p1; + + if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + goto err; + } +#ifdef TLS_DEBUG + printf("client random\n"); + { + int z; + for (z = 0; z < SSL3_RANDOM_SIZE; z++) + printf("%02X%c", s->s3->client_random[z], + ((z + 1) % 16) ? ' ' : '\n'); + } + printf("server random\n"); + { + int z; + for (z = 0; z < SSL3_RANDOM_SIZE; z++) + printf("%02X%c", s->s3->server_random[z], + ((z + 1) % 16) ? ' ' : '\n'); + } + printf("pre-master\n"); + { + int z; + for (z = 0; z < s->session->master_key_length; z++) + printf("%02X%c", s->session->master_key[z], + ((z + 1) % 16) ? ' ' : '\n'); + } +#endif + if (!tls1_generate_key_block(s, p1, p2, num)) + goto err; +#ifdef TLS_DEBUG + printf("\nkey block\n"); + { + int z; + for (z = 0; z < num; z++) + printf("%02X%c", p1[z], ((z + 1) % 16) ? ' ' : '\n'); + } +#endif + + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) + && s->method->version <= TLS1_VERSION) { + /* + * enable vulnerability countermeasure for CBC ciphers with known-IV + * problem (http://www.openssl.org/~bodo/tls-cbc.txt) + */ + s->s3->need_empty_fragments = 1; + + if (s->session->cipher != NULL) { + if (s->session->cipher->algorithm_enc == SSL_eNULL) + s->s3->need_empty_fragments = 0; + +#ifndef OPENSSL_NO_RC4 + if (s->session->cipher->algorithm_enc == SSL_RC4) + s->s3->need_empty_fragments = 0; +#endif + } + } + + ret = 1; + err: + if (p2) { + OPENSSL_cleanse(p2, num); + OPENSSL_free(p2); + } + return (ret); +} + +/*- + * tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. + */ +int tls1_enc(SSL *s, int send) +{ + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs, i, j, k, pad = 0, ret, mac_size = 0; + const EVP_CIPHER *enc; + + if (send) { + if (EVP_MD_CTX_md(s->write_hash)) { + int n = EVP_MD_CTX_size(s->write_hash); + OPENSSL_assert(n >= 0); + } + ds = s->enc_write_ctx; + rec = &(s->s3->wrec); + if (s->enc_write_ctx == NULL) + enc = NULL; + else { + int ivlen; + enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + /* For TLSv1.1 and later explicit IV */ + if (SSL_USE_EXPLICIT_IV(s) + && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) + ivlen = EVP_CIPHER_iv_length(enc); + else + ivlen = 0; + if (ivlen > 1) { + if (rec->data != rec->input) + /* + * we can't write into the input stream: Can this ever + * happen?? (steve) + */ + fprintf(stderr, + "%s:%d: rec->data != rec->input\n", + __FILE__, __LINE__); + else if (RAND_bytes(rec->input, ivlen) <= 0) + return -1; + } + } + } else { + if (EVP_MD_CTX_md(s->read_hash)) { + int n = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(n >= 0); + } + ds = s->enc_read_ctx; + rec = &(s->s3->rrec); + if (s->enc_read_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + } + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_enc(%d)\n", send); +#endif /* KSSL_DEBUG */ + + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + ret = 1; + } else { + l = rec->length; + bs = EVP_CIPHER_block_size(ds->cipher); + + if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { + unsigned char buf[EVP_AEAD_TLS1_AAD_LEN], *seq; + + seq = send ? s->s3->write_sequence : s->s3->read_sequence; + + if (SSL_IS_DTLS(s)) { + unsigned char dtlsseq[9], *p = dtlsseq; + + s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p); + memcpy(p, &seq[2], 6); + memcpy(buf, dtlsseq, 8); + } else { + memcpy(buf, seq, 8); + for (i = 7; i >= 0; i--) { /* increment */ + ++seq[i]; + if (seq[i] != 0) + break; + } + } + + buf[8] = rec->type; + buf[9] = (unsigned char)(s->version >> 8); + buf[10] = (unsigned char)(s->version); + buf[11] = rec->length >> 8; + buf[12] = rec->length & 0xff; + pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, + EVP_AEAD_TLS1_AAD_LEN, buf); + if (pad <= 0) + return -1; + if (send) { + l += pad; + rec->length += pad; + } + } else if ((bs != 1) && send) { + i = bs - ((int)l % bs); + + /* Add weird padding of upto 256 bytes */ + + /* we need to add 'i' padding bytes of value j */ + j = i - 1; + if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { + if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) + j++; + } + for (k = (int)l; k < (int)(l + i); k++) + rec->input[k] = j; + l += i; + rec->length += i; + } +#ifdef KSSL_DEBUG + { + unsigned long ui; + fprintf(stderr, + "EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", + ds, rec->data, rec->input, l); + fprintf(stderr, + "\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n", + ds->buf_len, ds->cipher->key_len, DES_KEY_SZ, + DES_SCHEDULE_SZ, ds->cipher->iv_len); + fprintf(stderr, "\t\tIV: "); + for (i = 0; i < ds->cipher->iv_len; i++) + fprintf(stderr, "%02X", ds->iv[i]); + fprintf(stderr, "\n"); + fprintf(stderr, "\trec->input="); + for (ui = 0; ui < l; ui++) + fprintf(stderr, " %02x", rec->input[ui]); + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + + if (!send) { + if (l == 0 || l % bs != 0) + return 0; + } + + i = EVP_Cipher(ds, rec->data, rec->input, l); + if ((EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_CUSTOM_CIPHER) + ? (i < 0) + : (i == 0)) + return -1; /* AEAD can fail to verify MAC */ + if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send) { + rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + } +#ifdef KSSL_DEBUG + { + unsigned long i; + fprintf(stderr, "\trec->data="); + for (i = 0; i < l; i++) + fprintf(stderr, " %02x", rec->data[i]); + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + + ret = 1; + if (EVP_MD_CTX_md(s->read_hash) != NULL) + mac_size = EVP_MD_CTX_size(s->read_hash); + if ((bs != 1) && !send) + ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); + if (pad && !send) + rec->length -= pad; + } + return ret; +} + +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) +{ + unsigned int ret; + EVP_MD_CTX ctx, *d = NULL; + int i; + + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; + + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i] + && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { + d = s->s3->handshake_dgst[i]; + break; + } + } + if (!d) { + SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC, SSL_R_NO_REQUIRED_DIGEST); + return 0; + } + + EVP_MD_CTX_init(&ctx); + if (EVP_MD_CTX_copy_ex(&ctx, d) <=0 + || EVP_DigestFinal_ex(&ctx, out, &ret) <= 0) + ret = 0; + EVP_MD_CTX_cleanup(&ctx); + return ((int)ret); +} + +int tls1_final_finish_mac(SSL *s, + const char *str, int slen, unsigned char *out) +{ + unsigned int i; + EVP_MD_CTX ctx; + unsigned char buf[2 * EVP_MAX_MD_SIZE]; + unsigned char *q, buf2[12]; + int idx; + long mask; + int err = 0; + const EVP_MD *md; + + q = buf; + + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; + + EVP_MD_CTX_init(&ctx); + + for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) { + if (mask & ssl_get_algorithm2(s)) { + int hashsize = EVP_MD_size(md); + EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx]; + if (!hdgst || hashsize < 0 + || hashsize > (int)(sizeof(buf) - (size_t)(q - buf))) { + /* + * internal error: 'buf' is too small for this cipersuite! + */ + err = 1; + } else { + if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) || + !EVP_DigestFinal_ex(&ctx, q, &i) || + (i != (unsigned int)hashsize)) + err = 1; + q += hashsize; + } + } + } + + if (!tls1_PRF(ssl_get_algorithm2(s), + str, slen, buf, (int)(q - buf), NULL, 0, NULL, 0, NULL, 0, + s->session->master_key, s->session->master_key_length, + out, buf2, sizeof(buf2))) + err = 1; + EVP_MD_CTX_cleanup(&ctx); + + OPENSSL_cleanse(buf, (int)(q - buf)); + OPENSSL_cleanse(buf2, sizeof(buf2)); + if (err) + return 0; + else + return sizeof(buf2); +} + +int tls1_mac(SSL *ssl, unsigned char *md, int send) +{ + SSL3_RECORD *rec; + unsigned char *seq; + EVP_MD_CTX *hash; + size_t md_size, orig_len; + int i; + EVP_MD_CTX hmac, *mac_ctx; + unsigned char header[13]; + int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) + : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); + int t; + + if (send) { + rec = &(ssl->s3->wrec); + seq = &(ssl->s3->write_sequence[0]); + hash = ssl->write_hash; + } else { + rec = &(ssl->s3->rrec); + seq = &(ssl->s3->read_sequence[0]); + hash = ssl->read_hash; + } + + t = EVP_MD_CTX_size(hash); + OPENSSL_assert(t >= 0); + md_size = t; + + /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ + if (stream_mac) { + mac_ctx = hash; + } else { + if (!EVP_MD_CTX_copy(&hmac, hash)) + return -1; + mac_ctx = &hmac; + } + + if (SSL_IS_DTLS(ssl)) { + unsigned char dtlsseq[8], *p = dtlsseq; + + s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p); + memcpy(p, &seq[2], 6); + + memcpy(header, dtlsseq, 8); + } else + memcpy(header, seq, 8); + + /* + * kludge: tls1_cbc_remove_padding passes padding length in rec->type + */ + orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); + rec->type &= 0xff; + + header[8] = rec->type; + header[9] = (unsigned char)(ssl->version >> 8); + header[10] = (unsigned char)(ssl->version); + header[11] = (rec->length) >> 8; + header[12] = (rec->length) & 0xff; + + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(mac_ctx)) { + /* + * This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of data we + * are hashing because that gives an attacker a timing-oracle. + */ + /* Final param == not SSLv3 */ + if (ssl3_cbc_digest_record(mac_ctx, + md, &md_size, + header, rec->input, + rec->length + md_size, orig_len, + ssl->s3->read_mac_secret, + ssl->s3->read_mac_secret_size, 0) <= 0) { + if (!stream_mac) + EVP_MD_CTX_cleanup(&hmac); + return -1; + } + } else { + if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 + || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 + || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { + if (!stream_mac) + EVP_MD_CTX_cleanup(&hmac); + return -1; + } +#ifdef OPENSSL_FIPS + if (!send && FIPS_mode()) + tls_fips_digest_extra(ssl->enc_read_ctx, + mac_ctx, rec->input, rec->length, orig_len); +#endif + } + + if (!stream_mac) + EVP_MD_CTX_cleanup(&hmac); +#ifdef TLS_DEBUG + fprintf(stderr, "seq="); + { + int z; + for (z = 0; z < 8; z++) + fprintf(stderr, "%02X ", seq[z]); + fprintf(stderr, "\n"); + } + fprintf(stderr, "rec="); + { + unsigned int z; + for (z = 0; z < rec->length; z++) + fprintf(stderr, "%02X ", rec->data[z]); + fprintf(stderr, "\n"); + } +#endif + + if (!SSL_IS_DTLS(ssl)) { + for (i = 7; i >= 0; i--) { + ++seq[i]; + if (seq[i] != 0) + break; + } + } +#ifdef TLS_DEBUG + { + unsigned int z; + for (z = 0; z < md_size; z++) + fprintf(stderr, "%02X ", md[z]); + fprintf(stderr, "\n"); + } +#endif + return (md_size); +} + +int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, + int len) +{ + unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; + const void *co = NULL, *so = NULL; + int col = 0, sol = 0; + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_generate_master_secret(%p,%p, %p, %d)\n", s, out, p, + len); +#endif /* KSSL_DEBUG */ + +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL + && s->s3->server_opaque_prf_input != NULL + && s->s3->client_opaque_prf_input_len > 0 + && s->s3->client_opaque_prf_input_len == + s->s3->server_opaque_prf_input_len) { + co = s->s3->client_opaque_prf_input; + col = s->s3->server_opaque_prf_input_len; + so = s->s3->server_opaque_prf_input; + /* + * must be same as col (see + * draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) + */ + sol = s->s3->client_opaque_prf_input_len; + } +#endif + + tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, + co, col, + s->s3->server_random, SSL3_RANDOM_SIZE, + so, sol, p, len, s->session->master_key, buff, sizeof(buff)); + OPENSSL_cleanse(buff, sizeof(buff)); +#ifdef SSL_DEBUG + fprintf(stderr, "Premaster Secret:\n"); + BIO_dump_fp(stderr, (char *)p, len); + fprintf(stderr, "Client Random:\n"); + BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE); + fprintf(stderr, "Server Random:\n"); + BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE); + fprintf(stderr, "Master Secret:\n"); + BIO_dump_fp(stderr, (char *)s->session->master_key, + SSL3_MASTER_SECRET_SIZE); +#endif + +#ifdef OPENSSL_SSL_TRACE_CRYPTO + if (s->msg_callback) { + s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER, + p, len, s, s->msg_callback_arg); + s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM, + s->s3->client_random, SSL3_RANDOM_SIZE, + s, s->msg_callback_arg); + s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM, + s->s3->server_random, SSL3_RANDOM_SIZE, + s, s->msg_callback_arg); + s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER, + s->session->master_key, + SSL3_MASTER_SECRET_SIZE, s, s->msg_callback_arg); + } +#endif + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_generate_master_secret() complete\n"); +#endif /* KSSL_DEBUG */ + return (SSL3_MASTER_SECRET_SIZE); +} + +int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen, int use_context) +{ + unsigned char *buff; + unsigned char *val = NULL; + size_t vallen, currentvalpos; + int rv; + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n", + s, out, olen, label, llen, context, contextlen); +#endif /* KSSL_DEBUG */ + + buff = OPENSSL_malloc(olen); + if (buff == NULL) + goto err2; + + /* + * construct PRF arguments we construct the PRF argument ourself rather + * than passing separate values into the TLS PRF to ensure that the + * concatenation of values does not create a prohibited label. + */ + vallen = llen + SSL3_RANDOM_SIZE * 2; + if (use_context) { + vallen += 2 + contextlen; + } + + val = OPENSSL_malloc(vallen); + if (val == NULL) + goto err2; + currentvalpos = 0; + memcpy(val + currentvalpos, (unsigned char *)label, llen); + currentvalpos += llen; + memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE); + currentvalpos += SSL3_RANDOM_SIZE; + memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE); + currentvalpos += SSL3_RANDOM_SIZE; + + if (use_context) { + val[currentvalpos] = (contextlen >> 8) & 0xff; + currentvalpos++; + val[currentvalpos] = contextlen & 0xff; + currentvalpos++; + if ((contextlen > 0) || (context != NULL)) { + memcpy(val + currentvalpos, context, contextlen); + } + } + + /* + * disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited + * label len) = 15, so size of val > max(prohibited label len) = 15 and + * the comparisons won't have buffer overflow + */ + if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST, + TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_SERVER_FINISH_CONST, + TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_MASTER_SECRET_CONST, + TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST, + TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) + goto err1; + + rv = tls1_PRF(ssl_get_algorithm2(s), + val, vallen, + NULL, 0, + NULL, 0, + NULL, 0, + NULL, 0, + s->session->master_key, s->session->master_key_length, + out, buff, olen); + OPENSSL_cleanse(val, vallen); + OPENSSL_cleanse(buff, olen); + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_export_keying_material() complete\n"); +#endif /* KSSL_DEBUG */ + goto ret; + err1: + SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, + SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); + rv = 0; + goto ret; + err2: + SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE); + rv = 0; + ret: + if (buff != NULL) + OPENSSL_free(buff); + if (val != NULL) + OPENSSL_free(val); + return (rv); +} + +int tls1_alert_code(int code) +{ + switch (code) { + case SSL_AD_CLOSE_NOTIFY: + return (SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: + return (SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: + return (TLS1_AD_DECRYPTION_FAILED); + case SSL_AD_RECORD_OVERFLOW: + return (TLS1_AD_RECORD_OVERFLOW); + case SSL_AD_DECOMPRESSION_FAILURE: + return (SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_CERTIFICATE: + return (-1); + case SSL_AD_BAD_CERTIFICATE: + return (SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE: + return (SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED: + return (SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED: + return (SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN: + return (SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: + return (SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: + return (TLS1_AD_UNKNOWN_CA); + case SSL_AD_ACCESS_DENIED: + return (TLS1_AD_ACCESS_DENIED); + case SSL_AD_DECODE_ERROR: + return (TLS1_AD_DECODE_ERROR); + case SSL_AD_DECRYPT_ERROR: + return (TLS1_AD_DECRYPT_ERROR); + case SSL_AD_EXPORT_RESTRICTION: + return (TLS1_AD_EXPORT_RESTRICTION); + case SSL_AD_PROTOCOL_VERSION: + return (TLS1_AD_PROTOCOL_VERSION); + case SSL_AD_INSUFFICIENT_SECURITY: + return (TLS1_AD_INSUFFICIENT_SECURITY); + case SSL_AD_INTERNAL_ERROR: + return (TLS1_AD_INTERNAL_ERROR); + case SSL_AD_USER_CANCELLED: + return (TLS1_AD_USER_CANCELLED); + case SSL_AD_NO_RENEGOTIATION: + return (TLS1_AD_NO_RENEGOTIATION); + case SSL_AD_UNSUPPORTED_EXTENSION: + return (TLS1_AD_UNSUPPORTED_EXTENSION); + case SSL_AD_CERTIFICATE_UNOBTAINABLE: + return (TLS1_AD_CERTIFICATE_UNOBTAINABLE); + case SSL_AD_UNRECOGNIZED_NAME: + return (TLS1_AD_UNRECOGNIZED_NAME); + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return (TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: + return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); + case SSL_AD_UNKNOWN_PSK_IDENTITY: + return (TLS1_AD_UNKNOWN_PSK_IDENTITY); + case SSL_AD_INAPPROPRIATE_FALLBACK: + return (TLS1_AD_INAPPROPRIATE_FALLBACK); +#if 0 + /* not appropriate for TLS, not used for DTLS */ + case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: + return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); +#endif + default: + return (-1); + } +} +/* ssl/t1_ext.c */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Custom extension utility functions */ + +// #include "ssl_locl.h" + +#ifndef OPENSSL_NO_TLSEXT + +/* Find a custom extension from the list. */ +static custom_ext_method *custom_ext_find(custom_ext_methods *exts, + unsigned int ext_type) +{ + size_t i; + custom_ext_method *meth = exts->meths; + for (i = 0; i < exts->meths_count; i++, meth++) { + if (ext_type == meth->ext_type) + return meth; + } + return NULL; +} + +/* + * Initialise custom extensions flags to indicate neither sent nor received. + */ +void custom_ext_init(custom_ext_methods *exts) +{ + size_t i; + custom_ext_method *meth = exts->meths; + for (i = 0; i < exts->meths_count; i++, meth++) + meth->ext_flags = 0; +} + +/* Pass received custom extension data to the application for parsing. */ +int custom_ext_parse(SSL *s, int server, + unsigned int ext_type, + const unsigned char *ext_data, size_t ext_size, int *al) +{ + custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext; + custom_ext_method *meth; + meth = custom_ext_find(exts, ext_type); + /* If not found return success */ + if (!meth) + return 1; + if (!server) { + /* + * If it's ServerHello we can't have any extensions not sent in + * ClientHello. + */ + if (!(meth->ext_flags & SSL_EXT_FLAG_SENT)) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + } + /* If already present it's a duplicate */ + if (meth->ext_flags & SSL_EXT_FLAG_RECEIVED) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + meth->ext_flags |= SSL_EXT_FLAG_RECEIVED; + /* If no parse function set return success */ + if (!meth->parse_cb) + return 1; + + return meth->parse_cb(s, ext_type, ext_data, ext_size, al, + meth->parse_arg); +} + +/* + * Request custom extension data from the application and add to the return + * buffer. + */ +int custom_ext_add(SSL *s, int server, + unsigned char **pret, unsigned char *limit, int *al) +{ + custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext; + custom_ext_method *meth; + unsigned char *ret = *pret; + size_t i; + + for (i = 0; i < exts->meths_count; i++) { + const unsigned char *out = NULL; + size_t outlen = 0; + meth = exts->meths + i; + + if (server) { + /* + * For ServerHello only send extensions present in ClientHello. + */ + if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED)) + continue; + /* If callback absent for server skip it */ + if (!meth->add_cb) + continue; + } + if (meth->add_cb) { + int cb_retval = 0; + cb_retval = meth->add_cb(s, meth->ext_type, + &out, &outlen, al, meth->add_arg); + if (cb_retval < 0) + return 0; /* error */ + if (cb_retval == 0) + continue; /* skip this extension */ + } + if (4 > limit - ret || outlen > (size_t)(limit - ret - 4)) + return 0; + s2n(meth->ext_type, ret); + s2n(outlen, ret); + if (outlen) { + memcpy(ret, out, outlen); + ret += outlen; + } + /* + * We can't send duplicates: code logic should prevent this. + */ + OPENSSL_assert(!(meth->ext_flags & SSL_EXT_FLAG_SENT)); + /* + * Indicate extension has been sent: this is both a sanity check to + * ensure we don't send duplicate extensions and indicates that it is + * not an error if the extension is present in ServerHello. + */ + meth->ext_flags |= SSL_EXT_FLAG_SENT; + if (meth->free_cb) + meth->free_cb(s, meth->ext_type, out, meth->add_arg); + } + *pret = ret; + return 1; +} + +/* Copy the flags from src to dst for any extensions that exist in both */ +int custom_exts_copy_flags(custom_ext_methods *dst, + const custom_ext_methods *src) +{ + size_t i; + custom_ext_method *methsrc = src->meths; + + for (i = 0; i < src->meths_count; i++, methsrc++) { + custom_ext_method *methdst = custom_ext_find(dst, methsrc->ext_type); + + if (methdst == NULL) + continue; + + methdst->ext_flags = methsrc->ext_flags; + } + + return 1; +} + +/* Copy table of custom extensions */ +int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src) +{ + if (src->meths_count) { + dst->meths = + BUF_memdup(src->meths, + sizeof(custom_ext_method) * src->meths_count); + if (dst->meths == NULL) + return 0; + dst->meths_count = src->meths_count; + } + return 1; +} + +void custom_exts_free(custom_ext_methods *exts) +{ + if (exts->meths) + OPENSSL_free(exts->meths); +} + +/* Set callbacks for a custom extension. */ +static int custom_ext_meth_add(custom_ext_methods *exts, + unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, void *parse_arg) +{ + custom_ext_method *meth; + /* + * Check application error: if add_cb is not set free_cb will never be + * called. + */ + if (!add_cb && free_cb) + return 0; + /* Don't add if extension supported internally. */ + if (SSL_extension_supported(ext_type)) + return 0; + /* Extension type must fit in 16 bits */ + if (ext_type > 0xffff) + return 0; + /* Search for duplicate */ + if (custom_ext_find(exts, ext_type)) + return 0; + meth = OPENSSL_realloc(exts->meths, + (exts->meths_count + 1) + * sizeof(custom_ext_method)); + if (meth == NULL) + return 0; + + exts->meths = meth; + meth += exts->meths_count; + memset(meth, 0, sizeof(custom_ext_method)); + meth->parse_cb = parse_cb; + meth->add_cb = add_cb; + meth->free_cb = free_cb; + meth->ext_type = ext_type; + meth->add_arg = add_arg; + meth->parse_arg = parse_arg; + exts->meths_count++; + return 1; +} + +/* Application level functions to add custom extension callbacks */ +int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg) +{ + return custom_ext_meth_add(&ctx->cert->cli_ext, ext_type, + add_cb, free_cb, add_arg, parse_cb, parse_arg); +} + +int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type, + custom_ext_add_cb add_cb, + custom_ext_free_cb free_cb, + void *add_arg, + custom_ext_parse_cb parse_cb, + void *parse_arg) +{ + return custom_ext_meth_add(&ctx->cert->srv_ext, ext_type, + add_cb, free_cb, add_arg, parse_cb, parse_arg); +} + +int SSL_extension_supported(unsigned int ext_type) +{ + switch (ext_type) { + /* Internally supported extensions. */ + case TLSEXT_TYPE_application_layer_protocol_negotiation: + case TLSEXT_TYPE_ec_point_formats: + case TLSEXT_TYPE_elliptic_curves: + case TLSEXT_TYPE_heartbeat: +# ifndef OPENSSL_NO_NEXTPROTONEG + case TLSEXT_TYPE_next_proto_neg: +# endif + case TLSEXT_TYPE_padding: + case TLSEXT_TYPE_renegotiate: + case TLSEXT_TYPE_server_name: + case TLSEXT_TYPE_session_ticket: + case TLSEXT_TYPE_signature_algorithms: + case TLSEXT_TYPE_srp: + case TLSEXT_TYPE_status_request: + case TLSEXT_TYPE_use_srtp: +# ifdef TLSEXT_TYPE_opaque_prf_input + case TLSEXT_TYPE_opaque_prf_input: +# endif +# ifdef TLSEXT_TYPE_encrypt_then_mac + case TLSEXT_TYPE_encrypt_then_mac: +# endif + return 1; + default: + return 0; + } +} +#endif +/* ssl/t1_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "objects.h" +// #include "evp.h" +// #include "hmac.h" +#ifndef OPENSSL_NO_EC +#ifdef OPENSSL_NO_EC2M +# include "ec.h" +#endif +#endif +#include "ocsp.h" +// #include "rand.h" +// #include "ssl_locl.h" + +const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT; + +#ifndef OPENSSL_NO_TLSEXT +static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, + const unsigned char *sess_id, int sesslen, + SSL_SESSION **psess); +static int ssl_check_clienthello_tlsext_early(SSL *s); +int ssl_check_serverhello_tlsext(SSL *s); +#endif + +#define CHECKLEN(curr, val, limit) \ + (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val)) + +SSL3_ENC_METHOD TLSv1_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + 0, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write +}; + +SSL3_ENC_METHOD TLSv1_1_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_EXPLICIT_IV, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write +}; + +SSL3_ENC_METHOD TLSv1_2_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF + | SSL_ENC_FLAG_TLS1_2_CIPHERS, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write +}; + +long tls1_default_timeout(void) +{ + /* + * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for + * http, the cache would over fill + */ + return (60 * 60 * 2); +} + +int tls1_new(SSL *s) +{ + if (!ssl3_new(s)) + return (0); + s->method->ssl_clear(s); + return (1); +} + +void tls1_free(SSL *s) +{ +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_session_ticket) { + OPENSSL_free(s->tlsext_session_ticket); + } +#endif /* OPENSSL_NO_TLSEXT */ + ssl3_free(s); +} + +void tls1_clear(SSL *s) +{ + ssl3_clear(s); + s->version = s->method->version; +} + +#ifndef OPENSSL_NO_EC + +static int nid_list[] = { + NID_sect163k1, /* sect163k1 (1) */ + NID_sect163r1, /* sect163r1 (2) */ + NID_sect163r2, /* sect163r2 (3) */ + NID_sect193r1, /* sect193r1 (4) */ + NID_sect193r2, /* sect193r2 (5) */ + NID_sect233k1, /* sect233k1 (6) */ + NID_sect233r1, /* sect233r1 (7) */ + NID_sect239k1, /* sect239k1 (8) */ + NID_sect283k1, /* sect283k1 (9) */ + NID_sect283r1, /* sect283r1 (10) */ + NID_sect409k1, /* sect409k1 (11) */ + NID_sect409r1, /* sect409r1 (12) */ + NID_sect571k1, /* sect571k1 (13) */ + NID_sect571r1, /* sect571r1 (14) */ + NID_secp160k1, /* secp160k1 (15) */ + NID_secp160r1, /* secp160r1 (16) */ + NID_secp160r2, /* secp160r2 (17) */ + NID_secp192k1, /* secp192k1 (18) */ + NID_X9_62_prime192v1, /* secp192r1 (19) */ + NID_secp224k1, /* secp224k1 (20) */ + NID_secp224r1, /* secp224r1 (21) */ + NID_secp256k1, /* secp256k1 (22) */ + NID_X9_62_prime256v1, /* secp256r1 (23) */ + NID_secp384r1, /* secp384r1 (24) */ + NID_secp521r1, /* secp521r1 (25) */ + NID_brainpoolP256r1, /* brainpoolP256r1 (26) */ + NID_brainpoolP384r1, /* brainpoolP384r1 (27) */ + NID_brainpoolP512r1 /* brainpool512r1 (28) */ +}; + +static const unsigned char ecformats_default[] = { + TLSEXT_ECPOINTFORMAT_uncompressed, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 +}; + +/* The client's default curves / the server's 'auto' curves. */ +static const unsigned char eccurves_auto[] = { + /* Prefer P-256 which has the fastest and most secure implementations. */ + 0, 23, /* secp256r1 (23) */ + /* Other >= 256-bit prime curves. */ + 0, 25, /* secp521r1 (25) */ + 0, 28, /* brainpool512r1 (28) */ + 0, 27, /* brainpoolP384r1 (27) */ + 0, 24, /* secp384r1 (24) */ + 0, 26, /* brainpoolP256r1 (26) */ + 0, 22, /* secp256k1 (22) */ +# ifndef OPENSSL_NO_EC2M + /* >= 256-bit binary curves. */ + 0, 14, /* sect571r1 (14) */ + 0, 13, /* sect571k1 (13) */ + 0, 11, /* sect409k1 (11) */ + 0, 12, /* sect409r1 (12) */ + 0, 9, /* sect283k1 (9) */ + 0, 10, /* sect283r1 (10) */ +# endif +}; + +static const unsigned char eccurves_all[] = { + /* Prefer P-256 which has the fastest and most secure implementations. */ + 0, 23, /* secp256r1 (23) */ + /* Other >= 256-bit prime curves. */ + 0, 25, /* secp521r1 (25) */ + 0, 28, /* brainpool512r1 (28) */ + 0, 27, /* brainpoolP384r1 (27) */ + 0, 24, /* secp384r1 (24) */ + 0, 26, /* brainpoolP256r1 (26) */ + 0, 22, /* secp256k1 (22) */ +# ifndef OPENSSL_NO_EC2M + /* >= 256-bit binary curves. */ + 0, 14, /* sect571r1 (14) */ + 0, 13, /* sect571k1 (13) */ + 0, 11, /* sect409k1 (11) */ + 0, 12, /* sect409r1 (12) */ + 0, 9, /* sect283k1 (9) */ + 0, 10, /* sect283r1 (10) */ +# endif + /* + * Remaining curves disabled by default but still permitted if set + * via an explicit callback or parameters. + */ + 0, 20, /* secp224k1 (20) */ + 0, 21, /* secp224r1 (21) */ + 0, 18, /* secp192k1 (18) */ + 0, 19, /* secp192r1 (19) */ + 0, 15, /* secp160k1 (15) */ + 0, 16, /* secp160r1 (16) */ + 0, 17, /* secp160r2 (17) */ +# ifndef OPENSSL_NO_EC2M + 0, 8, /* sect239k1 (8) */ + 0, 6, /* sect233k1 (6) */ + 0, 7, /* sect233r1 (7) */ + 0, 4, /* sect193r1 (4) */ + 0, 5, /* sect193r2 (5) */ + 0, 1, /* sect163k1 (1) */ + 0, 2, /* sect163r1 (2) */ + 0, 3, /* sect163r2 (3) */ +# endif +}; + +static const unsigned char suiteb_curves[] = { + 0, TLSEXT_curve_P_256, + 0, TLSEXT_curve_P_384 +}; + +# ifdef OPENSSL_FIPS +/* Brainpool not allowed in FIPS mode */ +static const unsigned char fips_curves_default[] = { +# ifndef OPENSSL_NO_EC2M + 0, 14, /* sect571r1 (14) */ + 0, 13, /* sect571k1 (13) */ +# endif + 0, 25, /* secp521r1 (25) */ +# ifndef OPENSSL_NO_EC2M + 0, 11, /* sect409k1 (11) */ + 0, 12, /* sect409r1 (12) */ +# endif + 0, 24, /* secp384r1 (24) */ +# ifndef OPENSSL_NO_EC2M + 0, 9, /* sect283k1 (9) */ + 0, 10, /* sect283r1 (10) */ +# endif + 0, 22, /* secp256k1 (22) */ + 0, 23, /* secp256r1 (23) */ +# ifndef OPENSSL_NO_EC2M + 0, 8, /* sect239k1 (8) */ + 0, 6, /* sect233k1 (6) */ + 0, 7, /* sect233r1 (7) */ +# endif + 0, 20, /* secp224k1 (20) */ + 0, 21, /* secp224r1 (21) */ +# ifndef OPENSSL_NO_EC2M + 0, 4, /* sect193r1 (4) */ + 0, 5, /* sect193r2 (5) */ +# endif + 0, 18, /* secp192k1 (18) */ + 0, 19, /* secp192r1 (19) */ +# ifndef OPENSSL_NO_EC2M + 0, 1, /* sect163k1 (1) */ + 0, 2, /* sect163r1 (2) */ + 0, 3, /* sect163r2 (3) */ +# endif + 0, 15, /* secp160k1 (15) */ + 0, 16, /* secp160r1 (16) */ + 0, 17, /* secp160r2 (17) */ +}; +# endif + +int tls1_ec_curve_id2nid(int curve_id) +{ + /* ECC curves from RFC 4492 and RFC 7027 */ + if ((curve_id < 1) || ((unsigned int)curve_id > + sizeof(nid_list) / sizeof(nid_list[0]))) + return 0; + return nid_list[curve_id - 1]; +} + +int tls1_ec_nid2curve_id(int nid) +{ + /* ECC curves from RFC 4492 and RFC 7027 */ + switch (nid) { + case NID_sect163k1: /* sect163k1 (1) */ + return 1; + case NID_sect163r1: /* sect163r1 (2) */ + return 2; + case NID_sect163r2: /* sect163r2 (3) */ + return 3; + case NID_sect193r1: /* sect193r1 (4) */ + return 4; + case NID_sect193r2: /* sect193r2 (5) */ + return 5; + case NID_sect233k1: /* sect233k1 (6) */ + return 6; + case NID_sect233r1: /* sect233r1 (7) */ + return 7; + case NID_sect239k1: /* sect239k1 (8) */ + return 8; + case NID_sect283k1: /* sect283k1 (9) */ + return 9; + case NID_sect283r1: /* sect283r1 (10) */ + return 10; + case NID_sect409k1: /* sect409k1 (11) */ + return 11; + case NID_sect409r1: /* sect409r1 (12) */ + return 12; + case NID_sect571k1: /* sect571k1 (13) */ + return 13; + case NID_sect571r1: /* sect571r1 (14) */ + return 14; + case NID_secp160k1: /* secp160k1 (15) */ + return 15; + case NID_secp160r1: /* secp160r1 (16) */ + return 16; + case NID_secp160r2: /* secp160r2 (17) */ + return 17; + case NID_secp192k1: /* secp192k1 (18) */ + return 18; + case NID_X9_62_prime192v1: /* secp192r1 (19) */ + return 19; + case NID_secp224k1: /* secp224k1 (20) */ + return 20; + case NID_secp224r1: /* secp224r1 (21) */ + return 21; + case NID_secp256k1: /* secp256k1 (22) */ + return 22; + case NID_X9_62_prime256v1: /* secp256r1 (23) */ + return 23; + case NID_secp384r1: /* secp384r1 (24) */ + return 24; + case NID_secp521r1: /* secp521r1 (25) */ + return 25; + case NID_brainpoolP256r1: /* brainpoolP256r1 (26) */ + return 26; + case NID_brainpoolP384r1: /* brainpoolP384r1 (27) */ + return 27; + case NID_brainpoolP512r1: /* brainpool512r1 (28) */ + return 28; + default: + return 0; + } +} + +/* + * Get curves list, if "sess" is set return client curves otherwise + * preferred list. + * Sets |num_curves| to the number of curves in the list, i.e., + * the length of |pcurves| is 2 * num_curves. + * Returns 1 on success and 0 if the client curves list has invalid format. + * The latter indicates an internal error: we should not be accepting such + * lists in the first place. + * TODO(emilia): we should really be storing the curves list in explicitly + * parsed form instead. (However, this would affect binary compatibility + * so cannot happen in the 1.0.x series.) + */ +static int tls1_get_curvelist(SSL *s, int sess, + const unsigned char **pcurves, + size_t *num_curves) +{ + size_t pcurveslen = 0; + if (sess) { + *pcurves = s->session->tlsext_ellipticcurvelist; + pcurveslen = s->session->tlsext_ellipticcurvelist_length; + } else { + /* For Suite B mode only include P-256, P-384 */ + switch (tls1_suiteb(s)) { + case SSL_CERT_FLAG_SUITEB_128_LOS: + *pcurves = suiteb_curves; + pcurveslen = sizeof(suiteb_curves); + break; + + case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: + *pcurves = suiteb_curves; + pcurveslen = 2; + break; + + case SSL_CERT_FLAG_SUITEB_192_LOS: + *pcurves = suiteb_curves + 2; + pcurveslen = 2; + break; + default: + *pcurves = s->tlsext_ellipticcurvelist; + pcurveslen = s->tlsext_ellipticcurvelist_length; + } + if (!*pcurves) { +# ifdef OPENSSL_FIPS + if (FIPS_mode()) { + *pcurves = fips_curves_default; + pcurveslen = sizeof(fips_curves_default); + } else +# endif + { + if (!s->server +# ifndef OPENSSL_NO_ECDH + || s->cert->ecdh_tmp_auto +# endif + ) { + *pcurves = eccurves_auto; + pcurveslen = sizeof(eccurves_auto); + } else { + *pcurves = eccurves_all; + pcurveslen = sizeof(eccurves_all); + } + } + } + } + /* We do not allow odd length arrays to enter the system. */ + if (pcurveslen & 1) { + SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR); + *num_curves = 0; + return 0; + } else { + *num_curves = pcurveslen / 2; + return 1; + } +} + +/* Check a curve is one of our preferences */ +int tls1_check_curve(SSL *s, const unsigned char *p, size_t len) +{ + const unsigned char *curves; + size_t num_curves, i; + unsigned int suiteb_flags = tls1_suiteb(s); + if (len != 3 || p[0] != NAMED_CURVE_TYPE) + return 0; + /* Check curve matches Suite B preferences */ + if (suiteb_flags) { + unsigned long cid = s->s3->tmp.new_cipher->id; + if (p[1]) + return 0; + if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { + if (p[2] != TLSEXT_curve_P_256) + return 0; + } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) { + if (p[2] != TLSEXT_curve_P_384) + return 0; + } else /* Should never happen */ + return 0; + } + if (!tls1_get_curvelist(s, 0, &curves, &num_curves)) + return 0; + for (i = 0; i < num_curves; i++, curves += 2) { + if (p[1] == curves[0] && p[2] == curves[1]) + return 1; + } + return 0; +} + +/*- + * Return |nmatch|th shared curve or NID_undef if there is no match. + * For nmatch == -1, return number of matches + * For nmatch == -2, return the NID of the curve to use for + * an EC tmp key, or NID_undef if there is no match. + */ +int tls1_shared_curve(SSL *s, int nmatch) +{ + const unsigned char *pref, *supp; + size_t num_pref, num_supp, i, j; + int k; + /* Can't do anything on client side */ + if (s->server == 0) + return -1; + if (nmatch == -2) { + if (tls1_suiteb(s)) { + /* + * For Suite B ciphersuite determines curve: we already know + * these are acceptable due to previous checks. + */ + unsigned long cid = s->s3->tmp.new_cipher->id; + if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) + return NID_X9_62_prime256v1; /* P-256 */ + if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) + return NID_secp384r1; /* P-384 */ + /* Should never happen */ + return NID_undef; + } + /* If not Suite B just return first preference shared curve */ + nmatch = 0; + } + /* + * Avoid truncation. tls1_get_curvelist takes an int + * but s->options is a long... + */ + if (!tls1_get_curvelist + (s, (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, &supp, + &num_supp)) + /* In practice, NID_undef == 0 but let's be precise. */ + return nmatch == -1 ? 0 : NID_undef; + if (!tls1_get_curvelist + (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref, + &num_pref)) + return nmatch == -1 ? 0 : NID_undef; + + /* + * If the client didn't send the elliptic_curves extension all of them + * are allowed. + */ + if (num_supp == 0 && (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0) { + supp = eccurves_all; + num_supp = sizeof(eccurves_all) / 2; + } else if (num_pref == 0 && + (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) { + pref = eccurves_all; + num_pref = sizeof(eccurves_all) / 2; + } + + k = 0; + for (i = 0; i < num_pref; i++, pref += 2) { + const unsigned char *tsupp = supp; + for (j = 0; j < num_supp; j++, tsupp += 2) { + if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) { + if (nmatch == k) { + int id = (pref[0] << 8) | pref[1]; + return tls1_ec_curve_id2nid(id); + } + k++; + } + } + } + if (nmatch == -1) + return k; + /* Out of range (nmatch > k). */ + return NID_undef; +} + +int tls1_set_curves(unsigned char **pext, size_t *pextlen, + int *curves, size_t ncurves) +{ + unsigned char *clist, *p; + size_t i; + /* + * Bitmap of curves included to detect duplicates: only works while curve + * ids < 32 + */ + unsigned long dup_list = 0; +# ifdef OPENSSL_NO_EC2M + EC_GROUP *curve; +# endif + + clist = OPENSSL_malloc(ncurves * 2); + if (!clist) + return 0; + for (i = 0, p = clist; i < ncurves; i++) { + unsigned long idmask; + int id; + id = tls1_ec_nid2curve_id(curves[i]); +# ifdef OPENSSL_FIPS + /* NB: 25 is last curve ID supported by FIPS module */ + if (FIPS_mode() && id > 25) { + OPENSSL_free(clist); + return 0; + } +# endif +# ifdef OPENSSL_NO_EC2M + curve = EC_GROUP_new_by_curve_name(curves[i]); + if (!curve || EC_METHOD_get_field_type(EC_GROUP_method_of(curve)) + == NID_X9_62_characteristic_two_field) { + if (curve) + EC_GROUP_free(curve); + OPENSSL_free(clist); + return 0; + } else + EC_GROUP_free(curve); +# endif + idmask = 1L << id; + if (!id || (dup_list & idmask)) { + OPENSSL_free(clist); + return 0; + } + dup_list |= idmask; + s2n(id, p); + } + if (*pext) + OPENSSL_free(*pext); + *pext = clist; + *pextlen = ncurves * 2; + return 1; +} + +# define MAX_CURVELIST 28 + +typedef struct { + size_t nidcnt; + int nid_arr[MAX_CURVELIST]; +} nid_cb_st; + +static int nid_cb(const char *elem, int len, void *arg) +{ + nid_cb_st *narg = arg; + size_t i; + int nid; + char etmp[20]; + if (elem == NULL) + return 0; + if (narg->nidcnt == MAX_CURVELIST) + return 0; + if (len > (int)(sizeof(etmp) - 1)) + return 0; + memcpy(etmp, elem, len); + etmp[len] = 0; + nid = EC_curve_nist2nid(etmp); + if (nid == NID_undef) + nid = OBJ_sn2nid(etmp); + if (nid == NID_undef) + nid = OBJ_ln2nid(etmp); + if (nid == NID_undef) + return 0; + for (i = 0; i < narg->nidcnt; i++) + if (narg->nid_arr[i] == nid) + return 0; + narg->nid_arr[narg->nidcnt++] = nid; + return 1; +} + +/* Set curves based on a colon separate list */ +int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, + const char *str) +{ + nid_cb_st ncb; + ncb.nidcnt = 0; + if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) + return 0; + if (pext == NULL) + return 1; + return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt); +} + +/* For an EC key set TLS id and required compression based on parameters */ +static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, + EC_KEY *ec) +{ + int is_prime, id; + const EC_GROUP *grp; + const EC_METHOD *meth; + if (!ec) + return 0; + /* Determine if it is a prime field */ + grp = EC_KEY_get0_group(ec); + if (!grp) + return 0; + meth = EC_GROUP_method_of(grp); + if (!meth) + return 0; + if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) + is_prime = 1; + else + is_prime = 0; + /* Determine curve ID */ + id = EC_GROUP_get_curve_name(grp); + id = tls1_ec_nid2curve_id(id); + /* If we have an ID set it, otherwise set arbitrary explicit curve */ + if (id) { + curve_id[0] = 0; + curve_id[1] = (unsigned char)id; + } else { + curve_id[0] = 0xff; + if (is_prime) + curve_id[1] = 0x01; + else + curve_id[1] = 0x02; + } + if (comp_id) { + if (EC_KEY_get0_public_key(ec) == NULL) + return 0; + if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) { + if (is_prime) + *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + else + *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + } else + *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; + } + return 1; +} + +/* Check an EC key is compatible with extensions */ +static int tls1_check_ec_key(SSL *s, + unsigned char *curve_id, unsigned char *comp_id) +{ + const unsigned char *pformats, *pcurves; + size_t num_formats, num_curves, i; + int j; + /* + * If point formats extension present check it, otherwise everything is + * supported (see RFC4492). + */ + if (comp_id && s->session->tlsext_ecpointformatlist) { + pformats = s->session->tlsext_ecpointformatlist; + num_formats = s->session->tlsext_ecpointformatlist_length; + for (i = 0; i < num_formats; i++, pformats++) { + if (*comp_id == *pformats) + break; + } + if (i == num_formats) + return 0; + } + if (!curve_id) + return 1; + /* Check curve is consistent with client and server preferences */ + for (j = 0; j <= 1; j++) { + if (!tls1_get_curvelist(s, j, &pcurves, &num_curves)) + return 0; + if (j == 1 && num_curves == 0) { + /* + * If we've not received any curves then skip this check. + * RFC 4492 does not require the supported elliptic curves extension + * so if it is not sent we can just choose any curve. + * It is invalid to send an empty list in the elliptic curves + * extension, so num_curves == 0 always means no extension. + */ + break; + } + for (i = 0; i < num_curves; i++, pcurves += 2) { + if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1]) + break; + } + if (i == num_curves) + return 0; + /* For clients can only check sent curve list */ + if (!s->server) + return 1; + } + return 1; +} + +static void tls1_get_formatlist(SSL *s, const unsigned char **pformats, + size_t *num_formats) +{ + /* + * If we have a custom point format list use it otherwise use default + */ + if (s->tlsext_ecpointformatlist) { + *pformats = s->tlsext_ecpointformatlist; + *num_formats = s->tlsext_ecpointformatlist_length; + } else { + *pformats = ecformats_default; + /* For Suite B we don't support char2 fields */ + if (tls1_suiteb(s)) + *num_formats = sizeof(ecformats_default) - 1; + else + *num_formats = sizeof(ecformats_default); + } +} + +/* + * Check cert parameters compatible with extensions: currently just checks EC + * certificates have compatible curves and compression. + */ +static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) +{ + unsigned char comp_id, curve_id[2]; + EVP_PKEY *pkey; + int rv; + pkey = X509_get_pubkey(x); + if (!pkey) + return 0; + /* If not EC nothing to do */ + if (pkey->type != EVP_PKEY_EC) { + EVP_PKEY_free(pkey); + return 1; + } + rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec); + EVP_PKEY_free(pkey); + if (!rv) + return 0; + /* + * Can't check curve_id for client certs as we don't have a supported + * curves extension. + */ + rv = tls1_check_ec_key(s, s->server ? curve_id : NULL, &comp_id); + if (!rv) + return 0; + /* + * Special case for suite B. We *MUST* sign using SHA256+P-256 or + * SHA384+P-384, adjust digest if necessary. + */ + if (set_ee_md && tls1_suiteb(s)) { + int check_md; + size_t i; + CERT *c = s->cert; + if (curve_id[0]) + return 0; + /* Check to see we have necessary signing algorithm */ + if (curve_id[1] == TLSEXT_curve_P_256) + check_md = NID_ecdsa_with_SHA256; + else if (curve_id[1] == TLSEXT_curve_P_384) + check_md = NID_ecdsa_with_SHA384; + else + return 0; /* Should never happen */ + for (i = 0; i < c->shared_sigalgslen; i++) + if (check_md == c->shared_sigalgs[i].signandhash_nid) + break; + if (i == c->shared_sigalgslen) + return 0; + if (set_ee_md == 2) { + if (check_md == NID_ecdsa_with_SHA256) + c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256(); + else + c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384(); + } + } + return rv; +} + +# ifndef OPENSSL_NO_ECDH +/* Check EC temporary key is compatible with client extensions */ +int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) +{ + unsigned char curve_id[2]; + EC_KEY *ec = s->cert->ecdh_tmp; +# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + /* Allow any curve: not just those peer supports */ + if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) + return 1; +# endif + /* + * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other + * curves permitted. + */ + if (tls1_suiteb(s)) { + /* Curve to check determined by ciphersuite */ + if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) + curve_id[1] = TLSEXT_curve_P_256; + else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) + curve_id[1] = TLSEXT_curve_P_384; + else + return 0; + curve_id[0] = 0; + /* Check this curve is acceptable */ + if (!tls1_check_ec_key(s, curve_id, NULL)) + return 0; + /* If auto or setting curve from callback assume OK */ + if (s->cert->ecdh_tmp_auto || s->cert->ecdh_tmp_cb) + return 1; + /* Otherwise check curve is acceptable */ + else { + unsigned char curve_tmp[2]; + if (!ec) + return 0; + if (!tls1_set_ec_id(curve_tmp, NULL, ec)) + return 0; + if (!curve_tmp[0] || curve_tmp[1] == curve_id[1]) + return 1; + return 0; + } + + } + if (s->cert->ecdh_tmp_auto) { + /* Need a shared curve */ + if (tls1_shared_curve(s, 0)) + return 1; + else + return 0; + } + if (!ec) { + if (s->cert->ecdh_tmp_cb) + return 1; + else + return 0; + } + if (!tls1_set_ec_id(curve_id, NULL, ec)) + return 0; +/* Set this to allow use of invalid curves for testing */ +# if 0 + return 1; +# else + return tls1_check_ec_key(s, curve_id, NULL); +# endif +} +# endif /* OPENSSL_NO_ECDH */ + +#else + +static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) +{ + return 1; +} + +#endif /* OPENSSL_NO_EC */ + +#ifndef OPENSSL_NO_TLSEXT + +/* + * List of supported signature algorithms and hashes. Should make this + * customisable at some point, for now include everything we support. + */ + +# ifdef OPENSSL_NO_RSA +# define tlsext_sigalg_rsa(md) /* */ +# else +# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa, +# endif + +# ifdef OPENSSL_NO_DSA +# define tlsext_sigalg_dsa(md) /* */ +# else +# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa, +# endif + +# ifdef OPENSSL_NO_ECDSA +# define tlsext_sigalg_ecdsa(md) + /* */ +# else +# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa, +# endif + +# define tlsext_sigalg(md) \ + tlsext_sigalg_rsa(md) \ + tlsext_sigalg_dsa(md) \ + tlsext_sigalg_ecdsa(md) + +static unsigned char tls12_sigalgs[] = { +# ifndef OPENSSL_NO_SHA512 + tlsext_sigalg(TLSEXT_hash_sha512) + tlsext_sigalg(TLSEXT_hash_sha384) +# endif +# ifndef OPENSSL_NO_SHA256 + tlsext_sigalg(TLSEXT_hash_sha256) + tlsext_sigalg(TLSEXT_hash_sha224) +# endif +# ifndef OPENSSL_NO_SHA + tlsext_sigalg(TLSEXT_hash_sha1) +# endif +}; + +# ifndef OPENSSL_NO_ECDSA +static unsigned char suiteb_sigalgs[] = { + tlsext_sigalg_ecdsa(TLSEXT_hash_sha256) + tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) +}; +# endif +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs) +{ + /* + * If Suite B mode use Suite B sigalgs only, ignore any other + * preferences. + */ +# ifndef OPENSSL_NO_EC + switch (tls1_suiteb(s)) { + case SSL_CERT_FLAG_SUITEB_128_LOS: + *psigs = suiteb_sigalgs; + return sizeof(suiteb_sigalgs); + + case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: + *psigs = suiteb_sigalgs; + return 2; + + case SSL_CERT_FLAG_SUITEB_192_LOS: + *psigs = suiteb_sigalgs + 2; + return 2; + } +# endif + /* If server use client authentication sigalgs if not NULL */ + if (s->server == sent && s->cert->client_sigalgs) { + *psigs = s->cert->client_sigalgs; + return s->cert->client_sigalgslen; + } else if (s->cert->conf_sigalgs) { + *psigs = s->cert->conf_sigalgs; + return s->cert->conf_sigalgslen; + } else { + *psigs = tls12_sigalgs; + return sizeof(tls12_sigalgs); + } +} + +/* + * Check signature algorithm is consistent with sent supported signature + * algorithms and if so return relevant digest. + */ +int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, + const unsigned char *sig, EVP_PKEY *pkey) +{ + const unsigned char *sent_sigs; + size_t sent_sigslen, i; + int sigalg = tls12_get_sigid(pkey); + /* Should never happen */ + if (sigalg == -1) + return -1; + /* Check key type is consistent with signature */ + if (sigalg != (int)sig[1]) { + SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); + return 0; + } +# ifndef OPENSSL_NO_EC + if (pkey->type == EVP_PKEY_EC) { + unsigned char curve_id[2], comp_id; + /* Check compression and curve matches extensions */ + if (!tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec)) + return 0; + if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) { + SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); + return 0; + } + /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */ + if (tls1_suiteb(s)) { + if (curve_id[0]) + return 0; + if (curve_id[1] == TLSEXT_curve_P_256) { + if (sig[0] != TLSEXT_hash_sha256) { + SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_ILLEGAL_SUITEB_DIGEST); + return 0; + } + } else if (curve_id[1] == TLSEXT_curve_P_384) { + if (sig[0] != TLSEXT_hash_sha384) { + SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, + SSL_R_ILLEGAL_SUITEB_DIGEST); + return 0; + } + } else + return 0; + } + } else if (tls1_suiteb(s)) + return 0; +# endif + + /* Check signature matches a type we sent */ + sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); + for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) { + if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1]) + break; + } + /* Allow fallback to SHA1 if not strict mode */ + if (i == sent_sigslen + && (sig[0] != TLSEXT_hash_sha1 + || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { + SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); + return 0; + } + *pmd = tls12_get_hash(sig[0]); + if (*pmd == NULL) { + SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST); + return 0; + } + /* + * Store the digest used so applications can retrieve it if they wish. + */ + if (s->session && s->session->sess_cert) + s->session->sess_cert->peer_key->digest = *pmd; + return 1; +} + +/* + * Get a mask of disabled algorithms: an algorithm is disabled if it isn't + * supported or doesn't appear in supported signature algorithms. Unlike + * ssl_cipher_get_disabled this applies to a specific session and not global + * settings. + */ +void ssl_set_client_disabled(SSL *s) +{ + CERT *c = s->cert; + const unsigned char *sigalgs; + size_t i, sigalgslen; + int have_rsa = 0, have_dsa = 0, have_ecdsa = 0; + c->mask_a = 0; + c->mask_k = 0; + /* Don't allow TLS 1.2 only ciphers if we don't suppport them */ + if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s)) + c->mask_ssl = SSL_TLSV1_2; + else + c->mask_ssl = 0; + /* + * Now go through all signature algorithms seeing if we support any for + * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. + */ + sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); + for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { + switch (sigalgs[1]) { +# ifndef OPENSSL_NO_RSA + case TLSEXT_signature_rsa: + have_rsa = 1; + break; +# endif +# ifndef OPENSSL_NO_DSA + case TLSEXT_signature_dsa: + have_dsa = 1; + break; +# endif +# ifndef OPENSSL_NO_ECDSA + case TLSEXT_signature_ecdsa: + have_ecdsa = 1; + break; +# endif + } + } + /* + * Disable auth and static DH if we don't include any appropriate + * signature algorithms. + */ + if (!have_rsa) { + c->mask_a |= SSL_aRSA; + c->mask_k |= SSL_kDHr | SSL_kECDHr; + } + if (!have_dsa) { + c->mask_a |= SSL_aDSS; + c->mask_k |= SSL_kDHd; + } + if (!have_ecdsa) { + c->mask_a |= SSL_aECDSA; + c->mask_k |= SSL_kECDHe; + } +# ifndef OPENSSL_NO_KRB5 + if (!kssl_tgt_is_available(s->kssl_ctx)) { + c->mask_a |= SSL_aKRB5; + c->mask_k |= SSL_kKRB5; + } +# endif +# ifndef OPENSSL_NO_PSK + /* with PSK there must be client callback set */ + if (!s->psk_client_callback) { + c->mask_a |= SSL_aPSK; + c->mask_k |= SSL_kPSK; + } +# endif /* OPENSSL_NO_PSK */ +# ifndef OPENSSL_NO_SRP + if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) { + c->mask_a |= SSL_aSRP; + c->mask_k |= SSL_kSRP; + } +# endif + c->valid = 1; +} + +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit, int *al) +{ + int extdatalen = 0; + unsigned char *orig = buf; + unsigned char *ret = buf; +# ifndef OPENSSL_NO_EC + /* See if we support any ECC ciphersuites */ + int using_ecc = 0; + if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) { + int i; + unsigned long alg_k, alg_a; + STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s); + + for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) { + SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + if ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe) + || (alg_a & SSL_aECDSA))) { + using_ecc = 1; + break; + } + } + } +# endif + + /* don't add extensions for SSLv3 unless doing secure renegotiation */ + if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) + return orig; + + ret += 2; + + if (ret >= limit) + return NULL; /* this really never occurs, but ... */ + + if (s->tlsext_hostname != NULL) { + /* Add TLS extension servername to the Client Hello message */ + size_t size_str; + + /*- + * check for enough space. + * 4 for the servername type and entension length + * 2 for servernamelist length + * 1 for the hostname type + * 2 for hostname length + * + hostname length + */ + size_str = strlen(s->tlsext_hostname); + if (CHECKLEN(ret, 9 + size_str, limit)) + return NULL; + + /* extension type and length */ + s2n(TLSEXT_TYPE_server_name, ret); + s2n(size_str + 5, ret); + + /* length of servername list */ + s2n(size_str + 3, ret); + + /* hostname type, length and hostname */ + *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name; + s2n(size_str, ret); + memcpy(ret, s->tlsext_hostname, size_str); + ret += size_str; + } + + /* Add RI if renegotiating */ + if (s->renegotiate) { + int el; + + if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + if ((limit - ret - 4 - el) < 0) + return NULL; + + s2n(TLSEXT_TYPE_renegotiate, ret); + s2n(el, ret); + + if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + ret += el; + } +# ifndef OPENSSL_NO_SRP + /* Add SRP username if there is one */ + if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the + * Client Hello message */ + + size_t login_len = strlen(s->srp_ctx.login); + if (login_len > 255 || login_len == 0) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /*- + * check for enough space. + * 4 for the srp type type and entension length + * 1 for the srp user identity + * + srp user identity length + */ + if (CHECKLEN(ret, 5 + login_len, limit)) + return NULL; + + /* fill in the extension */ + s2n(TLSEXT_TYPE_srp, ret); + s2n(login_len + 1, ret); + (*ret++) = (unsigned char)login_len; + memcpy(ret, s->srp_ctx.login, login_len); + ret += login_len; + } +# endif + +# ifndef OPENSSL_NO_EC + if (using_ecc) { + /* + * Add TLS extension ECPointFormats to the ClientHello message + */ + const unsigned char *pcurves, *pformats; + size_t num_curves, num_formats, curves_list_len; + + tls1_get_formatlist(s, &pformats, &num_formats); + + if (num_formats > 255) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + /*- + * check for enough space. + * 4 bytes for the ec point formats type and extension length + * 1 byte for the length of the formats + * + formats length + */ + if (CHECKLEN(ret, 5 + num_formats, limit)) + return NULL; + + s2n(TLSEXT_TYPE_ec_point_formats, ret); + /* The point format list has 1-byte length. */ + s2n(num_formats + 1, ret); + *(ret++) = (unsigned char)num_formats; + memcpy(ret, pformats, num_formats); + ret += num_formats; + + /* + * Add TLS extension EllipticCurves to the ClientHello message + */ + pcurves = s->tlsext_ellipticcurvelist; + if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) + return NULL; + + if (num_curves > 65532 / 2) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + curves_list_len = 2 * num_curves; + /*- + * check for enough space. + * 4 bytes for the ec curves type and extension length + * 2 bytes for the curve list length + * + curve list length + */ + if (CHECKLEN(ret, 6 + curves_list_len, limit)) + return NULL; + + s2n(TLSEXT_TYPE_elliptic_curves, ret); + s2n(curves_list_len + 2, ret); + s2n(curves_list_len, ret); + memcpy(ret, pcurves, curves_list_len); + ret += curves_list_len; + } +# endif /* OPENSSL_NO_EC */ + + if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { + size_t ticklen; + if (!s->new_session && s->session && s->session->tlsext_tick) + ticklen = s->session->tlsext_ticklen; + else if (s->session && s->tlsext_session_ticket && + s->tlsext_session_ticket->data) { + ticklen = s->tlsext_session_ticket->length; + s->session->tlsext_tick = OPENSSL_malloc(ticklen); + if (!s->session->tlsext_tick) + return NULL; + memcpy(s->session->tlsext_tick, + s->tlsext_session_ticket->data, ticklen); + s->session->tlsext_ticklen = ticklen; + } else + ticklen = 0; + if (ticklen == 0 && s->tlsext_session_ticket && + s->tlsext_session_ticket->data == NULL) + goto skip_ext; + /* + * Check for enough room 2 for extension type, 2 for len rest for + * ticket + */ + if (CHECKLEN(ret, 4 + ticklen, limit)) + return NULL; + s2n(TLSEXT_TYPE_session_ticket, ret); + s2n(ticklen, ret); + if (ticklen > 0) { + memcpy(ret, s->session->tlsext_tick, ticklen); + ret += ticklen; + } + } + skip_ext: + + if (SSL_CLIENT_USE_SIGALGS(s)) { + size_t salglen; + const unsigned char *salg; + salglen = tls12_get_psigalgs(s, 1, &salg); + + /*- + * check for enough space. + * 4 bytes for the sigalgs type and extension length + * 2 bytes for the sigalg list length + * + sigalg list length + */ + if (CHECKLEN(ret, salglen + 6, limit)) + return NULL; + s2n(TLSEXT_TYPE_signature_algorithms, ret); + s2n(salglen + 2, ret); + s2n(salglen, ret); + memcpy(ret, salg, salglen); + ret += salglen; + } +# ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL) { + size_t col = s->s3->client_opaque_prf_input_len; + + if ((long)(limit - ret - 6 - col < 0)) + return NULL; + if (col > 0xFFFD) /* can't happen */ + return NULL; + + s2n(TLSEXT_TYPE_opaque_prf_input, ret); + s2n(col + 2, ret); + s2n(col, ret); + memcpy(ret, s->s3->client_opaque_prf_input, col); + ret += col; + } +# endif + + if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { + int i; + size_t extlen, idlen; + int lentmp; + OCSP_RESPID *id; + + idlen = 0; + for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { + id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); + lentmp = i2d_OCSP_RESPID(id, NULL); + if (lentmp <= 0) + return NULL; + idlen += (size_t)lentmp + 2; + } + + if (s->tlsext_ocsp_exts) { + lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); + if (lentmp < 0) + return NULL; + extlen = (size_t)lentmp; + } else + extlen = 0; + + if (extlen + idlen > 0xFFF0) + return NULL; + /* + * 2 bytes for status request type + * 2 bytes for status request len + * 1 byte for OCSP request type + * 2 bytes for length of ids + * 2 bytes for length of extensions + * + length of ids + * + length of extensions + */ + if (CHECKLEN(ret, 9 + idlen + extlen, limit)) + return NULL; + + s2n(TLSEXT_TYPE_status_request, ret); + s2n(extlen + idlen + 5, ret); + *(ret++) = TLSEXT_STATUSTYPE_ocsp; + s2n(idlen, ret); + for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { + /* save position of id len */ + unsigned char *q = ret; + id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); + /* skip over id len */ + ret += 2; + lentmp = i2d_OCSP_RESPID(id, &ret); + /* write id len */ + s2n(lentmp, q); + } + s2n(extlen, ret); + if (extlen > 0) + i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret); + } +# ifndef OPENSSL_NO_HEARTBEATS + /* Add Heartbeat extension */ + + /*- + * check for enough space. + * 4 bytes for the heartbeat ext type and extension length + * 1 byte for the mode + */ + if (CHECKLEN(ret, 5, limit)) + return NULL; + + s2n(TLSEXT_TYPE_heartbeat, ret); + s2n(1, ret); + /*- + * Set mode: + * 1: peer may send requests + * 2: peer not allowed to send requests + */ + if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) + *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; + else + *(ret++) = SSL_TLSEXT_HB_ENABLED; +# endif + +# ifndef OPENSSL_NO_NEXTPROTONEG + if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) { + /* + * The client advertises an emtpy extension to indicate its support + * for Next Protocol Negotiation + */ + + /*- + * check for enough space. + * 4 bytes for the NPN ext type and extension length + */ + if (CHECKLEN(ret, 4, limit)) + return NULL; + s2n(TLSEXT_TYPE_next_proto_neg, ret); + s2n(0, ret); + } +# endif + + if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) { + /*- + * check for enough space. + * 4 bytes for the ALPN type and extension length + * 2 bytes for the ALPN protocol list length + * + ALPN protocol list length + */ + if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit)) + return NULL; + s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); + s2n(2 + s->alpn_client_proto_list_len, ret); + s2n(s->alpn_client_proto_list_len, ret); + memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len); + ret += s->alpn_client_proto_list_len; + s->cert->alpn_sent = 1; + } +# ifndef OPENSSL_NO_SRTP + if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { + int el; + + ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); + + /*- + * check for enough space. + * 4 bytes for the SRTP type and extension length + * + SRTP profiles length + */ + if (CHECKLEN(ret, 4 + el, limit)) + return NULL; + + s2n(TLSEXT_TYPE_use_srtp, ret); + s2n(el, ret); + + if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + ret += el; + } +# endif + custom_ext_init(&s->cert->cli_ext); + /* Add custom TLS Extensions to ClientHello */ + if (!custom_ext_add(s, 0, &ret, limit, al)) + return NULL; + + /* + * Add padding to workaround bugs in F5 terminators. See + * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this + * code works out the length of all existing extensions it MUST always + * appear last. + */ + if (s->options & SSL_OP_TLSEXT_PADDING) { + int hlen = ret - (unsigned char *)s->init_buf->data; + /* + * The code in s23_clnt.c to build ClientHello messages includes the + * 5-byte record header in the buffer, while the code in s3_clnt.c + * does not. + */ + if (s->state == SSL23_ST_CW_CLNT_HELLO_A) + hlen -= 5; + if (hlen > 0xff && hlen < 0x200) { + hlen = 0x200 - hlen; + if (hlen >= 4) + hlen -= 4; + else + hlen = 0; + + /*- + * check for enough space. Strictly speaking we know we've already + * got enough space because to get here the message size is < 0x200, + * but we know that we've allocated far more than that in the buffer + * - but for consistency and robustness we're going to check anyway. + * + * 4 bytes for the padding type and extension length + * + padding length + */ + if (CHECKLEN(ret, 4 + hlen, limit)) + return NULL; + s2n(TLSEXT_TYPE_padding, ret); + s2n(hlen, ret); + memset(ret, 0, hlen); + ret += hlen; + } + } + + if ((extdatalen = ret - orig - 2) == 0) + return orig; + + s2n(extdatalen, orig); + return ret; +} + +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit, int *al) +{ + int extdatalen = 0; + unsigned char *orig = buf; + unsigned char *ret = buf; +# ifndef OPENSSL_NO_NEXTPROTONEG + int next_proto_neg_seen; +# endif +# ifndef OPENSSL_NO_EC + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + int using_ecc = (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) + || (alg_a & SSL_aECDSA); + using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL); +# endif + /* + * don't add extensions for SSLv3, unless doing secure renegotiation + */ + if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) + return orig; + + ret += 2; + if (ret >= limit) + return NULL; /* this really never occurs, but ... */ + + if (!s->hit && s->servername_done == 1 + && s->session->tlsext_hostname != NULL) { + if ((long)(limit - ret - 4) < 0) + return NULL; + + s2n(TLSEXT_TYPE_server_name, ret); + s2n(0, ret); + } + + if (s->s3->send_connection_binding) { + int el; + + if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /*- + * check for enough space. + * 4 bytes for the reneg type and extension length + * + reneg data length + */ + if (CHECKLEN(ret, 4 + el, limit)) + return NULL; + + s2n(TLSEXT_TYPE_renegotiate, ret); + s2n(el, ret); + + if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + ret += el; + } +# ifndef OPENSSL_NO_EC + if (using_ecc) { + const unsigned char *plist; + size_t plistlen; + /* + * Add TLS extension ECPointFormats to the ServerHello message + */ + + tls1_get_formatlist(s, &plist, &plistlen); + + if (plistlen > 255) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /*- + * check for enough space. + * 4 bytes for the ec points format type and extension length + * 1 byte for the points format list length + * + length of points format list + */ + if (CHECKLEN(ret, 5 + plistlen, limit)) + return NULL; + + s2n(TLSEXT_TYPE_ec_point_formats, ret); + s2n(plistlen + 1, ret); + *(ret++) = (unsigned char)plistlen; + memcpy(ret, plist, plistlen); + ret += plistlen; + + } + /* + * Currently the server should not respond with a SupportedCurves + * extension + */ +# endif /* OPENSSL_NO_EC */ + + if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) { + /*- + * check for enough space. + * 4 bytes for the Ticket type and extension length + */ + if (CHECKLEN(ret, 4, limit)) + return NULL; + s2n(TLSEXT_TYPE_session_ticket, ret); + s2n(0, ret); + } else { + /* if we don't add the above TLSEXT, we can't add a session ticket later */ + s->tlsext_ticket_expected = 0; + } + + if (s->tlsext_status_expected) { + /*- + * check for enough space. + * 4 bytes for the Status request type and extension length + */ + if (CHECKLEN(ret, 4, limit)) + return NULL; + s2n(TLSEXT_TYPE_status_request, ret); + s2n(0, ret); + } +# ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->server_opaque_prf_input != NULL) { + size_t sol = s->s3->server_opaque_prf_input_len; + + if ((long)(limit - ret - 6 - sol) < 0) + return NULL; + if (sol > 0xFFFD) /* can't happen */ + return NULL; + + s2n(TLSEXT_TYPE_opaque_prf_input, ret); + s2n(sol + 2, ret); + s2n(sol, ret); + memcpy(ret, s->s3->server_opaque_prf_input, sol); + ret += sol; + } +# endif + +# ifndef OPENSSL_NO_SRTP + if (SSL_IS_DTLS(s) && s->srtp_profile) { + int el; + + ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); + + /*- + * check for enough space. + * 4 bytes for the SRTP profiles type and extension length + * + length of the SRTP profiles list + */ + if (CHECKLEN(ret, 4 + el, limit)) + return NULL; + + s2n(TLSEXT_TYPE_use_srtp, ret); + s2n(el, ret); + + if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + ret += el; + } +# endif + + if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80 + || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81) + && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) { + const unsigned char cryptopro_ext[36] = { + 0xfd, 0xe8, /* 65000 */ + 0x00, 0x20, /* 32 bytes length */ + 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, + 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, + 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 + }; + + /* check for enough space. */ + if (CHECKLEN(ret, sizeof(cryptopro_ext), limit)) + return NULL; + memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext)); + ret += sizeof(cryptopro_ext); + + } +# ifndef OPENSSL_NO_HEARTBEATS + /* Add Heartbeat extension if we've received one */ + if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) { + /*- + * check for enough space. + * 4 bytes for the Heartbeat type and extension length + * 1 byte for the mode + */ + if (CHECKLEN(ret, 5, limit)) + return NULL; + s2n(TLSEXT_TYPE_heartbeat, ret); + s2n(1, ret); + /*- + * Set mode: + * 1: peer may send requests + * 2: peer not allowed to send requests + */ + if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) + *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; + else + *(ret++) = SSL_TLSEXT_HB_ENABLED; + + } +# endif + +# ifndef OPENSSL_NO_NEXTPROTONEG + next_proto_neg_seen = s->s3->next_proto_neg_seen; + s->s3->next_proto_neg_seen = 0; + if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) { + const unsigned char *npa; + unsigned int npalen; + int r; + + r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, + s-> + ctx->next_protos_advertised_cb_arg); + if (r == SSL_TLSEXT_ERR_OK) { + /*- + * check for enough space. + * 4 bytes for the NPN type and extension length + * + length of protocols list + */ + if (CHECKLEN(ret, 4 + npalen, limit)) + return NULL; + s2n(TLSEXT_TYPE_next_proto_neg, ret); + s2n(npalen, ret); + memcpy(ret, npa, npalen); + ret += npalen; + s->s3->next_proto_neg_seen = 1; + } + } +# endif + if (!custom_ext_add(s, 1, &ret, limit, al)) + return NULL; + + if (s->s3->alpn_selected) { + const unsigned char *selected = s->s3->alpn_selected; + size_t len = s->s3->alpn_selected_len; + + /*- + * check for enough space. + * 4 bytes for the ALPN type and extension length + * 2 bytes for ALPN data length + * 1 byte for selected protocol length + * + length of the selected protocol + */ + if (CHECKLEN(ret, 7 + len, limit)) + return NULL; + s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); + s2n(3 + len, ret); + s2n(1 + len, ret); + *ret++ = (unsigned char)len; + memcpy(ret, selected, len); + ret += len; + } + + if ((extdatalen = ret - orig - 2) == 0) + return orig; + + s2n(extdatalen, orig); + return ret; +} + +# ifndef OPENSSL_NO_EC +/*- + * ssl_check_for_safari attempts to fingerprint Safari using OS X + * SecureTransport using the TLS extension block in |d|, of length |n|. + * Safari, since 10.6, sends exactly these extensions, in this order: + * SNI, + * elliptic_curves + * ec_point_formats + * + * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8, + * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them. + * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from + * 10.8..10.8.3 (which don't work). + */ +static void ssl_check_for_safari(SSL *s, const unsigned char *data, + const unsigned char *limit) +{ + unsigned short type, size; + static const unsigned char kSafariExtensionsBlock[] = { + 0x00, 0x0a, /* elliptic_curves extension */ + 0x00, 0x08, /* 8 bytes */ + 0x00, 0x06, /* 6 bytes of curve ids */ + 0x00, 0x17, /* P-256 */ + 0x00, 0x18, /* P-384 */ + 0x00, 0x19, /* P-521 */ + + 0x00, 0x0b, /* ec_point_formats */ + 0x00, 0x02, /* 2 bytes */ + 0x01, /* 1 point format */ + 0x00, /* uncompressed */ + }; + + /* The following is only present in TLS 1.2 */ + static const unsigned char kSafariTLS12ExtensionsBlock[] = { + 0x00, 0x0d, /* signature_algorithms */ + 0x00, 0x0c, /* 12 bytes */ + 0x00, 0x0a, /* 10 bytes */ + 0x05, 0x01, /* SHA-384/RSA */ + 0x04, 0x01, /* SHA-256/RSA */ + 0x02, 0x01, /* SHA-1/RSA */ + 0x04, 0x03, /* SHA-256/ECDSA */ + 0x02, 0x03, /* SHA-1/ECDSA */ + }; + + if (limit - data <= 2) + return; + data += 2; + + if (limit - data < 4) + return; + n2s(data, type); + n2s(data, size); + + if (type != TLSEXT_TYPE_server_name) + return; + + if (limit - data < size) + return; + data += size; + + if (TLS1_get_client_version(s) >= TLS1_2_VERSION) { + const size_t len1 = sizeof(kSafariExtensionsBlock); + const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); + + if (limit - data != (int)(len1 + len2)) + return; + if (memcmp(data, kSafariExtensionsBlock, len1) != 0) + return; + if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0) + return; + } else { + const size_t len = sizeof(kSafariExtensionsBlock); + + if (limit - data != (int)(len)) + return; + if (memcmp(data, kSafariExtensionsBlock, len) != 0) + return; + } + + s->s3->is_probably_safari = 1; +} +# endif /* !OPENSSL_NO_EC */ + +/* + * tls1_alpn_handle_client_hello is called to save the ALPN extension in a + * ClientHello. data: the contents of the extension, not including the type + * and length. data_len: the number of bytes in |data| al: a pointer to the + * alert value to send in the event of a non-zero return. returns: 0 on + * success. + */ +static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, + unsigned data_len, int *al) +{ + unsigned i; + unsigned proto_len; + + if (data_len < 2) + goto parse_error; + + /* + * data should contain a uint16 length followed by a series of 8-bit, + * length-prefixed strings. + */ + i = ((unsigned)data[0]) << 8 | ((unsigned)data[1]); + data_len -= 2; + data += 2; + if (data_len != i) + goto parse_error; + + if (data_len < 2) + goto parse_error; + + for (i = 0; i < data_len;) { + proto_len = data[i]; + i++; + + if (proto_len == 0) + goto parse_error; + + if (i + proto_len < i || i + proto_len > data_len) + goto parse_error; + + i += proto_len; + } + + if (s->cert->alpn_proposed != NULL) + OPENSSL_free(s->cert->alpn_proposed); + s->cert->alpn_proposed = OPENSSL_malloc(data_len); + if (s->cert->alpn_proposed == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return -1; + } + memcpy(s->cert->alpn_proposed, data, data_len); + s->cert->alpn_proposed_len = data_len; + return 0; + + parse_error: + *al = SSL_AD_DECODE_ERROR; + return -1; +} + +/* + * Process the ALPN extension in a ClientHello. + * al: a pointer to the alert value to send in the event of a failure. + * returns 1 on success, 0 on failure: al set only on failure + */ +static int tls1_alpn_handle_client_hello_late(SSL *s, int *al) +{ + const unsigned char *selected = NULL; + unsigned char selected_len = 0; + + if (s->ctx->alpn_select_cb != NULL && s->cert->alpn_proposed != NULL) { + int r = s->ctx->alpn_select_cb(s, &selected, &selected_len, + s->cert->alpn_proposed, + s->cert->alpn_proposed_len, + s->ctx->alpn_select_cb_arg); + + if (r == SSL_TLSEXT_ERR_OK) { + OPENSSL_free(s->s3->alpn_selected); + s->s3->alpn_selected = OPENSSL_malloc(selected_len); + if (s->s3->alpn_selected == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + memcpy(s->s3->alpn_selected, selected, selected_len); + s->s3->alpn_selected_len = selected_len; +# ifndef OPENSSL_NO_NEXTPROTONEG + /* ALPN takes precedence over NPN. */ + s->s3->next_proto_neg_seen = 0; +# endif + } + } + + return 1; +} + +static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, + unsigned char *limit, int *al) +{ + unsigned short type; + unsigned short size; + unsigned short len; + unsigned char *data = *p; + int renegotiate_seen = 0; + + s->servername_done = 0; + s->tlsext_status_type = -1; +# ifndef OPENSSL_NO_NEXTPROTONEG + s->s3->next_proto_neg_seen = 0; +# endif + + if (s->s3->alpn_selected) { + OPENSSL_free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + } + s->s3->alpn_selected_len = 0; + if (s->cert->alpn_proposed) { + OPENSSL_free(s->cert->alpn_proposed); + s->cert->alpn_proposed = NULL; + } + s->cert->alpn_proposed_len = 0; +# ifndef OPENSSL_NO_HEARTBEATS + s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | + SSL_TLSEXT_HB_DONT_SEND_REQUESTS); +# endif + +# ifndef OPENSSL_NO_EC + if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) + ssl_check_for_safari(s, data, limit); +# endif /* !OPENSSL_NO_EC */ + + /* Clear any signature algorithms extension received */ + if (s->cert->peer_sigalgs) { + OPENSSL_free(s->cert->peer_sigalgs); + s->cert->peer_sigalgs = NULL; + } +# ifndef OPENSSL_NO_SRP + if (s->srp_ctx.login != NULL) { + OPENSSL_free(s->srp_ctx.login); + s->srp_ctx.login = NULL; + } +# endif + + s->srtp_profile = NULL; + + if (data == limit) + goto ri_check; + + if (limit - data < 2) + goto err; + + n2s(data, len); + + if (limit - data != len) + goto err; + + while (limit - data >= 4) { + n2s(data, type); + n2s(data, size); + + if (limit - data < size) + goto err; +# if 0 + fprintf(stderr, "Received extension type %d size %d\n", type, size); +# endif + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); +/*- + * The servername extension is treated as follows: + * + * - Only the hostname type is supported with a maximum length of 255. + * - The servername is rejected if too long or if it contains zeros, + * in which case an fatal alert is generated. + * - The servername field is maintained together with the session cache. + * - When a session is resumed, the servername call back invoked in order + * to allow the application to position itself to the right context. + * - The servername is acknowledged if it is new for a session or when + * it is identical to a previously used for the same session. + * Applications can control the behaviour. They can at any time + * set a 'desirable' servername for a new SSL object. This can be the + * case for example with HTTPS when a Host: header field is received and + * a renegotiation is requested. In this case, a possible servername + * presented in the new client hello is only acknowledged if it matches + * the value of the Host: field. + * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + * if they provide for changing an explicit servername context for the + * session, i.e. when the session has been established with a servername + * extension. + * - On session reconnect, the servername extension may be absent. + * + */ + + if (type == TLSEXT_TYPE_server_name) { + unsigned char *sdata; + int servname_type; + int dsize; + + if (size < 2) + goto err; + n2s(data, dsize); + size -= 2; + if (dsize > size) + goto err; + + sdata = data; + while (dsize > 3) { + servname_type = *(sdata++); + n2s(sdata, len); + dsize -= 3; + + if (len > dsize) + goto err; + + if (s->servername_done == 0) + switch (servname_type) { + case TLSEXT_NAMETYPE_host_name: + if (!s->hit) { + if (s->session->tlsext_hostname) + goto err; + + if (len > TLSEXT_MAXLEN_host_name) { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + if ((s->session->tlsext_hostname = + OPENSSL_malloc(len + 1)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(s->session->tlsext_hostname, sdata, len); + s->session->tlsext_hostname[len] = '\0'; + if (strlen(s->session->tlsext_hostname) != len) { + OPENSSL_free(s->session->tlsext_hostname); + s->session->tlsext_hostname = NULL; + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + s->servername_done = 1; + + } else + s->servername_done = s->session->tlsext_hostname + && strlen(s->session->tlsext_hostname) == len + && strncmp(s->session->tlsext_hostname, + (char *)sdata, len) == 0; + + break; + + default: + break; + } + + dsize -= len; + } + if (dsize != 0) + goto err; + + } +# ifndef OPENSSL_NO_SRP + else if (type == TLSEXT_TYPE_srp) { + if (size == 0 || ((len = data[0])) != (size - 1)) + goto err; + if (s->srp_ctx.login != NULL) + goto err; + if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL) + return -1; + memcpy(s->srp_ctx.login, &data[1], len); + s->srp_ctx.login[len] = '\0'; + + if (strlen(s->srp_ctx.login) != len) + goto err; + } +# endif + +# ifndef OPENSSL_NO_EC + else if (type == TLSEXT_TYPE_ec_point_formats) { + unsigned char *sdata = data; + int ecpointformatlist_length; + + if (size == 0) + goto err; + + ecpointformatlist_length = *(sdata++); + if (ecpointformatlist_length != size - 1 || + ecpointformatlist_length < 1) + goto err; + if (!s->hit) { + if (s->session->tlsext_ecpointformatlist) { + OPENSSL_free(s->session->tlsext_ecpointformatlist); + s->session->tlsext_ecpointformatlist = NULL; + } + s->session->tlsext_ecpointformatlist_length = 0; + if ((s->session->tlsext_ecpointformatlist = + OPENSSL_malloc(ecpointformatlist_length)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = + ecpointformatlist_length; + memcpy(s->session->tlsext_ecpointformatlist, sdata, + ecpointformatlist_length); + } +# if 0 + fprintf(stderr, + "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", + s->session->tlsext_ecpointformatlist_length); + sdata = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) + fprintf(stderr, "%i ", *(sdata++)); + fprintf(stderr, "\n"); +# endif + } else if (type == TLSEXT_TYPE_elliptic_curves) { + unsigned char *sdata = data; + int ellipticcurvelist_length = (*(sdata++) << 8); + ellipticcurvelist_length += (*(sdata++)); + + if (ellipticcurvelist_length != size - 2 || + ellipticcurvelist_length < 1 || + /* Each NamedCurve is 2 bytes. */ + ellipticcurvelist_length & 1) + goto err; + + if (!s->hit) { + if (s->session->tlsext_ellipticcurvelist) + goto err; + + s->session->tlsext_ellipticcurvelist_length = 0; + if ((s->session->tlsext_ellipticcurvelist = + OPENSSL_malloc(ellipticcurvelist_length)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ellipticcurvelist_length = + ellipticcurvelist_length; + memcpy(s->session->tlsext_ellipticcurvelist, sdata, + ellipticcurvelist_length); + } +# if 0 + fprintf(stderr, + "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", + s->session->tlsext_ellipticcurvelist_length); + sdata = s->session->tlsext_ellipticcurvelist; + for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++) + fprintf(stderr, "%i ", *(sdata++)); + fprintf(stderr, "\n"); +# endif + } +# endif /* OPENSSL_NO_EC */ +# ifdef TLSEXT_TYPE_opaque_prf_input + else if (type == TLSEXT_TYPE_opaque_prf_input) { + unsigned char *sdata = data; + + if (size < 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(sdata, s->s3->client_opaque_prf_input_len); + if (s->s3->client_opaque_prf_input_len != size - 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (s->s3->client_opaque_prf_input != NULL) { + /* shouldn't really happen */ + OPENSSL_free(s->s3->client_opaque_prf_input); + } + + /* dummy byte just to get non-NULL */ + if (s->s3->client_opaque_prf_input_len == 0) + s->s3->client_opaque_prf_input = OPENSSL_malloc(1); + else + s->s3->client_opaque_prf_input = + BUF_memdup(sdata, s->s3->client_opaque_prf_input_len); + if (s->s3->client_opaque_prf_input == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } +# endif + else if (type == TLSEXT_TYPE_session_ticket) { + if (s->tls_session_ticket_ext_cb && + !s->tls_session_ticket_ext_cb(s, data, size, + s->tls_session_ticket_ext_cb_arg)) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } else if (type == TLSEXT_TYPE_renegotiate) { + if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) + return 0; + renegotiate_seen = 1; + } else if (type == TLSEXT_TYPE_signature_algorithms) { + int dsize; + if (s->cert->peer_sigalgs || size < 2) + goto err; + n2s(data, dsize); + size -= 2; + if (dsize != size || dsize & 1 || !dsize) + goto err; + if (!tls1_save_sigalgs(s, data, dsize)) + goto err; + } else if (type == TLSEXT_TYPE_status_request && !s->hit) { + if (size < 5) + goto err; + + s->tlsext_status_type = *data++; + size--; + if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { + const unsigned char *sdata; + int dsize; + /* Read in responder_id_list */ + n2s(data, dsize); + size -= 2; + if (dsize > size) + goto err; + + /* + * We remove any OCSP_RESPIDs from a previous handshake + * to prevent unbounded memory growth - CVE-2016-6304 + */ + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, + OCSP_RESPID_free); + if (dsize > 0) { + s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); + if (s->tlsext_ocsp_ids == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } else { + s->tlsext_ocsp_ids = NULL; + } + + while (dsize > 0) { + OCSP_RESPID *id; + int idsize; + if (dsize < 4) + goto err; + n2s(data, idsize); + dsize -= 2 + idsize; + size -= 2 + idsize; + if (dsize < 0) + goto err; + sdata = data; + data += idsize; + id = d2i_OCSP_RESPID(NULL, &sdata, idsize); + if (!id) + goto err; + if (data != sdata) { + OCSP_RESPID_free(id); + goto err; + } + if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { + OCSP_RESPID_free(id); + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + /* Read in request_extensions */ + if (size < 2) + goto err; + n2s(data, dsize); + size -= 2; + if (dsize != size) + goto err; + sdata = data; + if (dsize > 0) { + if (s->tlsext_ocsp_exts) { + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + } + + s->tlsext_ocsp_exts = + d2i_X509_EXTENSIONS(NULL, &sdata, dsize); + if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) + goto err; + } + } + /* + * We don't know what to do with any other type * so ignore it. + */ + else + s->tlsext_status_type = -1; + } +# ifndef OPENSSL_NO_HEARTBEATS + else if (type == TLSEXT_TYPE_heartbeat) { + switch (data[0]) { + case 0x01: /* Client allows us to send HB requests */ + s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; + break; + case 0x02: /* Client doesn't accept HB requests */ + s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; + s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; + break; + default: + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + } +# endif +# ifndef OPENSSL_NO_NEXTPROTONEG + else if (type == TLSEXT_TYPE_next_proto_neg && + s->s3->tmp.finish_md_len == 0) { + /*- + * We shouldn't accept this extension on a + * renegotiation. + * + * s->new_session will be set on renegotiation, but we + * probably shouldn't rely that it couldn't be set on + * the initial renegotation too in certain cases (when + * there's some other reason to disallow resuming an + * earlier session -- the current code won't be doing + * anything like that, but this might change). + * + * A valid sign that there's been a previous handshake + * in this connection is if s->s3->tmp.finish_md_len > + * 0. (We are talking about a check that will happen + * in the Hello protocol round, well before a new + * Finished message could have been computed.) + */ + s->s3->next_proto_neg_seen = 1; + } +# endif + + else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation && + s->s3->tmp.finish_md_len == 0) { + if (tls1_alpn_handle_client_hello(s, data, size, al) != 0) + return 0; + } + + /* session ticket processed earlier */ +# ifndef OPENSSL_NO_SRTP + else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) + && type == TLSEXT_TYPE_use_srtp) { + if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) + return 0; + } +# endif + + data += size; + } + + /* Spurious data on the end */ + if (data != limit) + goto err; + + *p = data; + + ri_check: + + /* Need RI if renegotiating */ + + if (!renegotiate_seen && s->renegotiate && + !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + + return 1; +err: + *al = SSL_AD_DECODE_ERROR; + return 0; +} + +/* + * Parse any custom extensions found. "data" is the start of the extension data + * and "limit" is the end of the record. TODO: add strict syntax checking. + */ + +static int ssl_scan_clienthello_custom_tlsext(SSL *s, + const unsigned char *data, + const unsigned char *limit, + int *al) +{ + unsigned short type, size, len; + /* If resumed session or no custom extensions nothing to do */ + if (s->hit || s->cert->srv_ext.meths_count == 0) + return 1; + + if (limit - data <= 2) + return 1; + n2s(data, len); + + if (limit - data < len) + return 1; + + while (limit - data >= 4) { + n2s(data, type); + n2s(data, size); + + if (limit - data < size) + return 1; + if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0) + return 0; + + data += size; + } + + return 1; +} + +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, + unsigned char *limit) +{ + int al = -1; + unsigned char *ptmp = *p; + /* + * Internally supported extensions are parsed first so SNI can be handled + * before custom extensions. An application processing SNI will typically + * switch the parent context using SSL_set_SSL_CTX and custom extensions + * need to be handled by the new SSL_CTX structure. + */ + if (ssl_scan_clienthello_tlsext(s, p, limit, &al) <= 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return 0; + } + + if (ssl_check_clienthello_tlsext_early(s) <= 0) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT); + return 0; + } + + custom_ext_init(&s->cert->srv_ext); + if (ssl_scan_clienthello_custom_tlsext(s, ptmp, limit, &al) <= 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return 0; + } + + return 1; +} + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* + * ssl_next_proto_validate validates a Next Protocol Negotiation block. No + * elements of zero length are allowed and the set of elements must exactly + * fill the length of the block. + */ +static char ssl_next_proto_validate(unsigned char *d, unsigned len) +{ + unsigned int off = 0; + + while (off < len) { + if (d[off] == 0) + return 0; + off += d[off]; + off++; + } + + return off == len; +} +# endif + +static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, + unsigned char *d, int n, int *al) +{ + unsigned short length; + unsigned short type; + unsigned short size; + unsigned char *data = *p; + int tlsext_servername = 0; + int renegotiate_seen = 0; + +# ifndef OPENSSL_NO_NEXTPROTONEG + s->s3->next_proto_neg_seen = 0; +# endif + s->tlsext_ticket_expected = 0; + + if (s->s3->alpn_selected) { + OPENSSL_free(s->s3->alpn_selected); + s->s3->alpn_selected = NULL; + } +# ifndef OPENSSL_NO_HEARTBEATS + s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | + SSL_TLSEXT_HB_DONT_SEND_REQUESTS); +# endif + + if ((d + n) - data <= 2) + goto ri_check; + + n2s(data, length); + if ((d + n) - data != length) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + while ((d + n) - data >= 4) { + n2s(data, type); + n2s(data, size); + + if ((d + n) - data < size) + goto ri_check; + + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg); + + if (type == TLSEXT_TYPE_server_name) { + if (s->tlsext_hostname == NULL || size > 0) { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + tlsext_servername = 1; + } +# ifndef OPENSSL_NO_EC + else if (type == TLSEXT_TYPE_ec_point_formats) { + unsigned char *sdata = data; + int ecpointformatlist_length; + + if (size == 0) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + + ecpointformatlist_length = *(sdata++); + if (ecpointformatlist_length != size - 1) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + if (!s->hit) { + s->session->tlsext_ecpointformatlist_length = 0; + if (s->session->tlsext_ecpointformatlist != NULL) + OPENSSL_free(s->session->tlsext_ecpointformatlist); + if ((s->session->tlsext_ecpointformatlist = + OPENSSL_malloc(ecpointformatlist_length)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = + ecpointformatlist_length; + memcpy(s->session->tlsext_ecpointformatlist, sdata, + ecpointformatlist_length); + } +# if 0 + fprintf(stderr, + "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); + sdata = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) + fprintf(stderr, "%i ", *(sdata++)); + fprintf(stderr, "\n"); +# endif + } +# endif /* OPENSSL_NO_EC */ + + else if (type == TLSEXT_TYPE_session_ticket) { + if (s->tls_session_ticket_ext_cb && + !s->tls_session_ticket_ext_cb(s, data, size, + s->tls_session_ticket_ext_cb_arg)) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + if ((SSL_get_options(s) & SSL_OP_NO_TICKET) + || (size > 0)) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + s->tlsext_ticket_expected = 1; + } +# ifdef TLSEXT_TYPE_opaque_prf_input + else if (type == TLSEXT_TYPE_opaque_prf_input) { + unsigned char *sdata = data; + + if (size < 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(sdata, s->s3->server_opaque_prf_input_len); + if (s->s3->server_opaque_prf_input_len != size - 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (s->s3->server_opaque_prf_input != NULL) { + /* shouldn't really happen */ + OPENSSL_free(s->s3->server_opaque_prf_input); + } + if (s->s3->server_opaque_prf_input_len == 0) { + /* dummy byte just to get non-NULL */ + s->s3->server_opaque_prf_input = OPENSSL_malloc(1); + } else { + s->s3->server_opaque_prf_input = + BUF_memdup(sdata, s->s3->server_opaque_prf_input_len); + } + + if (s->s3->server_opaque_prf_input == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } +# endif + else if (type == TLSEXT_TYPE_status_request) { + /* + * MUST be empty and only sent if we've requested a status + * request message. + */ + if ((s->tlsext_status_type == -1) || (size > 0)) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + /* Set flag to expect CertificateStatus message */ + s->tlsext_status_expected = 1; + } +# ifndef OPENSSL_NO_NEXTPROTONEG + else if (type == TLSEXT_TYPE_next_proto_neg && + s->s3->tmp.finish_md_len == 0) { + unsigned char *selected; + unsigned char selected_len; + + /* We must have requested it. */ + if (s->ctx->next_proto_select_cb == NULL) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + /* The data must be valid */ + if (!ssl_next_proto_validate(data, size)) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + if (s-> + ctx->next_proto_select_cb(s, &selected, &selected_len, data, + size, + s->ctx->next_proto_select_cb_arg) != + SSL_TLSEXT_ERR_OK) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + /* + * Could be non-NULL if server has sent multiple NPN extensions in + * a single Serverhello + */ + OPENSSL_free(s->next_proto_negotiated); + s->next_proto_negotiated = OPENSSL_malloc(selected_len); + if (!s->next_proto_negotiated) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(s->next_proto_negotiated, selected, selected_len); + s->next_proto_negotiated_len = selected_len; + s->s3->next_proto_neg_seen = 1; + } +# endif + + else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) { + unsigned len; + + /* We must have requested it. */ + if (!s->cert->alpn_sent) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + if (size < 4) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + /*- + * The extension data consists of: + * uint16 list_length + * uint8 proto_length; + * uint8 proto[proto_length]; + */ + len = data[0]; + len <<= 8; + len |= data[1]; + if (len != (unsigned)size - 2) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + len = data[2]; + if (len != (unsigned)size - 3) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + if (s->s3->alpn_selected) + OPENSSL_free(s->s3->alpn_selected); + s->s3->alpn_selected = OPENSSL_malloc(len); + if (!s->s3->alpn_selected) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(s->s3->alpn_selected, data + 3, len); + s->s3->alpn_selected_len = len; + } + + else if (type == TLSEXT_TYPE_renegotiate) { + if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) + return 0; + renegotiate_seen = 1; + } +# ifndef OPENSSL_NO_HEARTBEATS + else if (type == TLSEXT_TYPE_heartbeat) { + switch (data[0]) { + case 0x01: /* Server allows us to send HB requests */ + s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; + break; + case 0x02: /* Server doesn't accept HB requests */ + s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; + s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; + break; + default: + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + } +# endif +# ifndef OPENSSL_NO_SRTP + else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { + if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al)) + return 0; + } +# endif + /* + * If this extension type was not otherwise handled, but matches a + * custom_cli_ext_record, then send it to the c callback + */ + else if (custom_ext_parse(s, 0, type, data, size, al) <= 0) + return 0; + + data += size; + } + + if (data != d + n) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (!s->hit && tlsext_servername == 1) { + if (s->tlsext_hostname) { + if (s->session->tlsext_hostname == NULL) { + s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname); + if (!s->session->tlsext_hostname) { + *al = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + } else { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + } + } + + *p = data; + + ri_check: + + /* + * Determine if we need to see RI. Strictly speaking if we want to avoid + * an attack we should *always* see RI even on initial server hello + * because the client doesn't see any renegotiation during an attack. + * However this would mean we could not connect to any server which + * doesn't support RI so for the immediate future tolerate RI absence on + * initial connect only. + */ + if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) + && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + + return 1; +} + +int ssl_prepare_clienthello_tlsext(SSL *s) +{ + +# ifdef TLSEXT_TYPE_opaque_prf_input + { + int r = 1; + + if (s->ctx->tlsext_opaque_prf_input_callback != 0) { + r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, + s-> + ctx->tlsext_opaque_prf_input_callback_arg); + if (!r) + return -1; + } + + if (s->tlsext_opaque_prf_input != NULL) { + if (s->s3->client_opaque_prf_input != NULL) { + /* shouldn't really happen */ + OPENSSL_free(s->s3->client_opaque_prf_input); + } + + if (s->tlsext_opaque_prf_input_len == 0) { + /* dummy byte just to get non-NULL */ + s->s3->client_opaque_prf_input = OPENSSL_malloc(1); + } else { + s->s3->client_opaque_prf_input = + BUF_memdup(s->tlsext_opaque_prf_input, + s->tlsext_opaque_prf_input_len); + } + if (s->s3->client_opaque_prf_input == NULL) { + SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT, + ERR_R_MALLOC_FAILURE); + return -1; + } + s->s3->client_opaque_prf_input_len = + s->tlsext_opaque_prf_input_len; + } + + if (r == 2) + /* + * at callback's request, insist on receiving an appropriate + * server opaque PRF input + */ + s->s3->server_opaque_prf_input_len = + s->tlsext_opaque_prf_input_len; + } +# endif + + s->cert->alpn_sent = 0; + return 1; +} + +int ssl_prepare_serverhello_tlsext(SSL *s) +{ + return 1; +} + +static int ssl_check_clienthello_tlsext_early(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + +# ifndef OPENSSL_NO_EC + /* + * The handling of the ECPointFormats extension is done elsewhere, namely + * in ssl3_choose_cipher in s3_lib.c. + */ + /* + * The handling of the EllipticCurves extension is done elsewhere, namely + * in ssl3_choose_cipher in s3_lib.c. + */ +# endif + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = + s->ctx->tlsext_servername_callback(s, &al, + s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL + && s->initial_ctx->tlsext_servername_callback != 0) + ret = + s->initial_ctx->tlsext_servername_callback(s, &al, + s-> + initial_ctx->tlsext_servername_arg); + +# ifdef TLSEXT_TYPE_opaque_prf_input + { + /* + * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we + * might be sending an alert in response to the client hello, so this + * has to happen here in ssl_check_clienthello_tlsext_early(). + */ + + int r = 1; + + if (s->ctx->tlsext_opaque_prf_input_callback != 0) { + r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, + s-> + ctx->tlsext_opaque_prf_input_callback_arg); + if (!r) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + + if (s->s3->server_opaque_prf_input != NULL) { + /* shouldn't really happen */ + OPENSSL_free(s->s3->server_opaque_prf_input); + } + s->s3->server_opaque_prf_input = NULL; + + if (s->tlsext_opaque_prf_input != NULL) { + if (s->s3->client_opaque_prf_input != NULL && + s->s3->client_opaque_prf_input_len == + s->tlsext_opaque_prf_input_len) { + /* + * can only use this extension if we have a server opaque PRF + * input of the same length as the client opaque PRF input! + */ + + if (s->tlsext_opaque_prf_input_len == 0) { + /* dummy byte just to get non-NULL */ + s->s3->server_opaque_prf_input = OPENSSL_malloc(1); + } else { + s->s3->server_opaque_prf_input = + BUF_memdup(s->tlsext_opaque_prf_input, + s->tlsext_opaque_prf_input_len); + } + if (s->s3->server_opaque_prf_input == NULL) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + s->s3->server_opaque_prf_input_len = + s->tlsext_opaque_prf_input_len; + } + } + + if (r == 2 && s->s3->server_opaque_prf_input == NULL) { + /* + * The callback wants to enforce use of the extension, but we + * can't do that with the client opaque PRF input; abort the + * handshake. + */ + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_HANDSHAKE_FAILURE; + } + } + + err: +# endif + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + + case SSL_TLSEXT_ERR_NOACK: + s->servername_done = 0; + default: + return 1; + } +} + +int tls1_set_server_sigalgs(SSL *s) +{ + int al; + size_t i; + /* Clear any shared sigtnature algorithms */ + if (s->cert->shared_sigalgs) { + OPENSSL_free(s->cert->shared_sigalgs); + s->cert->shared_sigalgs = NULL; + s->cert->shared_sigalgslen = 0; + } + /* Clear certificate digests and validity flags */ + for (i = 0; i < SSL_PKEY_NUM; i++) { + s->cert->pkeys[i].digest = NULL; + s->cert->pkeys[i].valid_flags = 0; + } + + /* If sigalgs received process it. */ + if (s->cert->peer_sigalgs) { + if (!tls1_process_sigalgs(s)) { + SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE); + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + /* Fatal error is no shared signature algorithms */ + if (!s->cert->shared_sigalgs) { + SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, + SSL_R_NO_SHARED_SIGATURE_ALGORITHMS); + al = SSL_AD_HANDSHAKE_FAILURE; + goto err; + } + } else + ssl_cert_set_default_md(s->cert); + return 1; + err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return 0; +} + +/* + * Upon success, returns 1. + * Upon failure, returns 0 and sets |al| to the appropriate fatal alert. + */ +int ssl_check_clienthello_tlsext_late(SSL *s, int *al) +{ + + /* + * If status request then ask callback what to do. Note: this must be + * called after servername callbacks in case the certificate has changed, + * and must be called after the cipher has been chosen because this may + * influence which certificate is sent + */ + if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) { + int ret; + CERT_PKEY *certpkey; + certpkey = ssl_get_server_send_pkey(s); + /* If no certificate can't return certificate status */ + if (certpkey != NULL) { + /* + * Set current certificate to one we will use so SSL_get_certificate + * et al can pick it up. + */ + s->cert->key = certpkey; + ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + switch (ret) { + /* We don't want to send a status request response */ + case SSL_TLSEXT_ERR_NOACK: + s->tlsext_status_expected = 0; + break; + /* status request response should be sent */ + case SSL_TLSEXT_ERR_OK: + if (s->tlsext_ocsp_resp) + s->tlsext_status_expected = 1; + break; + /* something bad happened */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + default: + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + } + + if (!tls1_alpn_handle_client_hello_late(s, al)) { + return 0; + } + + return 1; +} + +int ssl_check_serverhello_tlsext(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + +# ifndef OPENSSL_NO_EC + /* + * If we are client and using an elliptic curve cryptography cipher + * suite, then if server returns an EC point formats lists extension it + * must contain uncompressed. + */ + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if ((s->tlsext_ecpointformatlist != NULL) + && (s->tlsext_ecpointformatlist_length > 0) + && (s->session->tlsext_ecpointformatlist != NULL) + && (s->session->tlsext_ecpointformatlist_length > 0) + && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) + || (alg_a & SSL_aECDSA))) { + /* we are using an ECC cipher */ + size_t i; + unsigned char *list; + int found_uncompressed = 0; + list = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) { + if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) { + found_uncompressed = 1; + break; + } + } + if (!found_uncompressed) { + SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT, + SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); + return -1; + } + } + ret = SSL_TLSEXT_ERR_OK; +# endif /* OPENSSL_NO_EC */ + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = + s->ctx->tlsext_servername_callback(s, &al, + s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL + && s->initial_ctx->tlsext_servername_callback != 0) + ret = + s->initial_ctx->tlsext_servername_callback(s, &al, + s-> + initial_ctx->tlsext_servername_arg); + +# ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->server_opaque_prf_input_len > 0) { + /* + * This case may indicate that we, as a client, want to insist on + * using opaque PRF inputs. So first verify that we really have a + * value from the server too. + */ + + if (s->s3->server_opaque_prf_input == NULL) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_HANDSHAKE_FAILURE; + } + + /* + * Anytime the server *has* sent an opaque PRF input, we need to + * check that we have a client opaque PRF input of the same size. + */ + if (s->s3->client_opaque_prf_input == NULL || + s->s3->client_opaque_prf_input_len != + s->s3->server_opaque_prf_input_len) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_ILLEGAL_PARAMETER; + } + } +# endif + + OPENSSL_free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resplen = -1; + /* + * If we've requested certificate status and we wont get one tell the + * callback + */ + if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected) + && !(s->hit) && s->ctx && s->ctx->tlsext_status_cb) { + int r; + /* + * Call callback with resp == NULL and resplen == -1 so callback + * knows there is no response + */ + r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + if (r == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + if (r < 0) { + al = SSL_AD_INTERNAL_ERROR; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + } + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + + case SSL_TLSEXT_ERR_NOACK: + s->servername_done = 0; + default: + return 1; + } +} + +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, + int n) +{ + int al = -1; + if (s->version < SSL3_VERSION) + return 1; + if (ssl_scan_serverhello_tlsext(s, p, d, n, &al) <= 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return 0; + } + + if (ssl_check_serverhello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT); + return 0; + } + return 1; +} + +/*- + * Since the server cache lookup is done early on in the processing of the + * ClientHello, and other operations depend on the result, we need to handle + * any TLS session ticket extension at the same time. + * + * session_id: points at the session ID in the ClientHello. This code will + * read past the end of this in order to parse out the session ticket + * extension, if any. + * len: the length of the session ID. + * limit: a pointer to the first byte after the ClientHello. + * ret: (output) on return, if a ticket was decrypted, then this is set to + * point to the resulting session. + * + * If s->tls_session_secret_cb is set then we are expecting a pre-shared key + * ciphersuite, in which case we have no use for session tickets and one will + * never be decrypted, nor will s->tlsext_ticket_expected be set to 1. + * + * Returns: + * -1: fatal error, either from parsing or decrypting the ticket. + * 0: no ticket was found (or was ignored, based on settings). + * 1: a zero length extension was found, indicating that the client supports + * session tickets but doesn't currently have one to offer. + * 2: either s->tls_session_secret_cb was set, or a ticket was offered but + * couldn't be decrypted because of a non-fatal error. + * 3: a ticket was successfully decrypted and *ret was set. + * + * Side effects: + * Sets s->tlsext_ticket_expected to 1 if the server will have to issue + * a new session ticket to the client because the client indicated support + * (and s->tls_session_secret_cb is NULL) but the client either doesn't have + * a session ticket or we couldn't use the one it gave us, or if + * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket. + * Otherwise, s->tlsext_ticket_expected is set to 0. + */ +int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit, SSL_SESSION **ret) +{ + /* Point after session ID in client hello */ + const unsigned char *p = session_id + len; + unsigned short i; + + *ret = NULL; + s->tlsext_ticket_expected = 0; + + /* + * If tickets disabled behave as if no ticket present to permit stateful + * resumption. + */ + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return 0; + if ((s->version <= SSL3_VERSION) || !limit) + return 0; + if (p >= limit) + return -1; + /* Skip past DTLS cookie */ + if (SSL_IS_DTLS(s)) { + i = *(p++); + + if (limit - p <= i) + return -1; + + p += i; + } + /* Skip past cipher list */ + n2s(p, i); + if (limit - p <= i) + return -1; + p += i; + + /* Skip past compression algorithm list */ + i = *(p++); + if (limit - p < i) + return -1; + p += i; + + /* Now at start of extensions */ + if (limit - p <= 2) + return 0; + n2s(p, i); + while (limit - p >= 4) { + unsigned short type, size; + n2s(p, type); + n2s(p, size); + if (limit - p < size) + return 0; + if (type == TLSEXT_TYPE_session_ticket) { + int r; + if (size == 0) { + /* + * The client will accept a ticket but doesn't currently have + * one. + */ + s->tlsext_ticket_expected = 1; + return 1; + } + if (s->tls_session_secret_cb) { + /* + * Indicate that the ticket couldn't be decrypted rather than + * generating the session from ticket now, trigger + * abbreviated handshake based on external mechanism to + * calculate the master secret later. + */ + return 2; + } + r = tls_decrypt_ticket(s, p, size, session_id, len, ret); + switch (r) { + case 2: /* ticket couldn't be decrypted */ + s->tlsext_ticket_expected = 1; + return 2; + case 3: /* ticket was decrypted */ + return r; + case 4: /* ticket decrypted but need to renew */ + s->tlsext_ticket_expected = 1; + return 3; + default: /* fatal error */ + return -1; + } + } + p += size; + } + return 0; +} + +/*- + * tls_decrypt_ticket attempts to decrypt a session ticket. + * + * etick: points to the body of the session ticket extension. + * eticklen: the length of the session tickets extenion. + * sess_id: points at the session ID. + * sesslen: the length of the session ID. + * psess: (output) on return, if a ticket was decrypted, then this is set to + * point to the resulting session. + * + * Returns: + * -1: fatal error, either from parsing or decrypting the ticket. + * 2: the ticket couldn't be decrypted. + * 3: a ticket was successfully decrypted and *psess was set. + * 4: same as 3, but the ticket needs to be renewed. + */ +static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, + int eticklen, const unsigned char *sess_id, + int sesslen, SSL_SESSION **psess) +{ + SSL_SESSION *sess; + unsigned char *sdec; + const unsigned char *p; + int slen, mlen, renew_ticket = 0; + unsigned char tick_hmac[EVP_MAX_MD_SIZE]; + HMAC_CTX hctx; + EVP_CIPHER_CTX ctx; + SSL_CTX *tctx = s->initial_ctx; + + /* Need at least keyname + iv */ + if (eticklen < 16 + EVP_MAX_IV_LENGTH) + return 2; + + /* Initialize session ticket encryption and HMAC contexts */ + HMAC_CTX_init(&hctx); + EVP_CIPHER_CTX_init(&ctx); + if (tctx->tlsext_ticket_key_cb) { + unsigned char *nctick = (unsigned char *)etick; + int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, + &ctx, &hctx, 0); + if (rv < 0) + goto err; + if (rv == 0) { + HMAC_CTX_cleanup(&hctx); + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + if (rv == 2) + renew_ticket = 1; + } else { + /* Check key name matches */ + if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) + return 2; + if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL) <= 0 + || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, + etick + 16) <= 0) { + goto err; + } + } + /* + * Attempt to process session ticket, first conduct sanity and integrity + * checks on ticket. + */ + mlen = HMAC_size(&hctx); + if (mlen < 0) { + goto err; + } + /* Sanity check ticket length: must exceed keyname + IV + HMAC */ + if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { + HMAC_CTX_cleanup(&hctx); + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + + eticklen -= mlen; + /* Check HMAC of encrypted ticket */ + if (HMAC_Update(&hctx, etick, eticklen) <= 0 + || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) { + goto err; + } + HMAC_CTX_cleanup(&hctx); + if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) { + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + /* Attempt to decrypt session data */ + /* Move p after IV to start of encrypted ticket, update length */ + p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); + eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); + sdec = OPENSSL_malloc(eticklen); + if (sdec == NULL + || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + OPENSSL_free(sdec); + return -1; + } + if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + OPENSSL_free(sdec); + return 2; + } + slen += mlen; + EVP_CIPHER_CTX_cleanup(&ctx); + p = sdec; + + sess = d2i_SSL_SESSION(NULL, &p, slen); + slen -= p - sdec; + OPENSSL_free(sdec); + if (sess) { + /* Some additional consistency checks */ + if (slen != 0 || sess->session_id_length != 0) { + SSL_SESSION_free(sess); + return 2; + } + /* + * The session ID, if non-empty, is used by some clients to detect + * that the ticket has been accepted. So we copy it to the session + * structure. If it is empty set length to zero as required by + * standard. + */ + if (sesslen) + memcpy(sess->session_id, sess_id, sesslen); + sess->session_id_length = sesslen; + *psess = sess; + if (renew_ticket) + return 4; + else + return 3; + } + ERR_clear_error(); + /* + * For session parse failure, indicate that we need to send a new ticket. + */ + return 2; +err: + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + return -1; +} + +/* Tables to translate from NIDs to TLS v1.2 ids */ + +typedef struct { + int nid; + int id; +} tls12_lookup; + +static tls12_lookup tls12_md[] = { + {NID_md5, TLSEXT_hash_md5}, + {NID_sha1, TLSEXT_hash_sha1}, + {NID_sha224, TLSEXT_hash_sha224}, + {NID_sha256, TLSEXT_hash_sha256}, + {NID_sha384, TLSEXT_hash_sha384}, + {NID_sha512, TLSEXT_hash_sha512} +}; + +static tls12_lookup tls12_sig[] = { + {EVP_PKEY_RSA, TLSEXT_signature_rsa}, + {EVP_PKEY_DSA, TLSEXT_signature_dsa}, + {EVP_PKEY_EC, TLSEXT_signature_ecdsa} +}; + +static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen) +{ + size_t i; + for (i = 0; i < tlen; i++) { + if (table[i].nid == nid) + return table[i].id; + } + return -1; +} + +static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen) +{ + size_t i; + for (i = 0; i < tlen; i++) { + if ((table[i].id) == id) + return table[i].nid; + } + return NID_undef; +} + +int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, + const EVP_MD *md) +{ + int sig_id, md_id; + if (!md) + return 0; + md_id = tls12_find_id(EVP_MD_type(md), tls12_md, + sizeof(tls12_md) / sizeof(tls12_lookup)); + if (md_id == -1) + return 0; + sig_id = tls12_get_sigid(pk); + if (sig_id == -1) + return 0; + p[0] = (unsigned char)md_id; + p[1] = (unsigned char)sig_id; + return 1; +} + +int tls12_get_sigid(const EVP_PKEY *pk) +{ + return tls12_find_id(pk->type, tls12_sig, + sizeof(tls12_sig) / sizeof(tls12_lookup)); +} + +const EVP_MD *tls12_get_hash(unsigned char hash_alg) +{ + switch (hash_alg) { +# ifndef OPENSSL_NO_MD5 + case TLSEXT_hash_md5: +# ifdef OPENSSL_FIPS + if (FIPS_mode()) + return NULL; +# endif + return EVP_md5(); +# endif +# ifndef OPENSSL_NO_SHA + case TLSEXT_hash_sha1: + return EVP_sha1(); +# endif +# ifndef OPENSSL_NO_SHA256 + case TLSEXT_hash_sha224: + return EVP_sha224(); + + case TLSEXT_hash_sha256: + return EVP_sha256(); +# endif +# ifndef OPENSSL_NO_SHA512 + case TLSEXT_hash_sha384: + return EVP_sha384(); + + case TLSEXT_hash_sha512: + return EVP_sha512(); +# endif + default: + return NULL; + + } +} + +static int tls12_get_pkey_idx(unsigned char sig_alg) +{ + switch (sig_alg) { +# ifndef OPENSSL_NO_RSA + case TLSEXT_signature_rsa: + return SSL_PKEY_RSA_SIGN; +# endif +# ifndef OPENSSL_NO_DSA + case TLSEXT_signature_dsa: + return SSL_PKEY_DSA_SIGN; +# endif +# ifndef OPENSSL_NO_ECDSA + case TLSEXT_signature_ecdsa: + return SSL_PKEY_ECC; +# endif + } + return -1; +} + +/* Convert TLS 1.2 signature algorithm extension values into NIDs */ +static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid, + int *psignhash_nid, const unsigned char *data) +{ + int sign_nid = NID_undef, hash_nid = NID_undef; + if (!phash_nid && !psign_nid && !psignhash_nid) + return; + if (phash_nid || psignhash_nid) { + hash_nid = tls12_find_nid(data[0], tls12_md, + sizeof(tls12_md) / sizeof(tls12_lookup)); + if (phash_nid) + *phash_nid = hash_nid; + } + if (psign_nid || psignhash_nid) { + sign_nid = tls12_find_nid(data[1], tls12_sig, + sizeof(tls12_sig) / sizeof(tls12_lookup)); + if (psign_nid) + *psign_nid = sign_nid; + } + if (psignhash_nid) { + if (sign_nid == NID_undef || hash_nid == NID_undef + || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, + sign_nid) <= 0) + *psignhash_nid = NID_undef; + } +} + +/* Given preference and allowed sigalgs set shared sigalgs */ +static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig, + const unsigned char *pref, size_t preflen, + const unsigned char *allow, + size_t allowlen) +{ + const unsigned char *ptmp, *atmp; + size_t i, j, nmatch = 0; + for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) { + /* Skip disabled hashes or signature algorithms */ + if (tls12_get_hash(ptmp[0]) == NULL) + continue; + if (tls12_get_pkey_idx(ptmp[1]) == -1) + continue; + for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) { + if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) { + nmatch++; + if (shsig) { + shsig->rhash = ptmp[0]; + shsig->rsign = ptmp[1]; + tls1_lookup_sigalg(&shsig->hash_nid, + &shsig->sign_nid, + &shsig->signandhash_nid, ptmp); + shsig++; + } + break; + } + } + } + return nmatch; +} + +/* Set shared signature algorithms for SSL structures */ +static int tls1_set_shared_sigalgs(SSL *s) +{ + const unsigned char *pref, *allow, *conf; + size_t preflen, allowlen, conflen; + size_t nmatch; + TLS_SIGALGS *salgs = NULL; + CERT *c = s->cert; + unsigned int is_suiteb = tls1_suiteb(s); + if (c->shared_sigalgs) { + OPENSSL_free(c->shared_sigalgs); + c->shared_sigalgs = NULL; + c->shared_sigalgslen = 0; + } + /* If client use client signature algorithms if not NULL */ + if (!s->server && c->client_sigalgs && !is_suiteb) { + conf = c->client_sigalgs; + conflen = c->client_sigalgslen; + } else if (c->conf_sigalgs && !is_suiteb) { + conf = c->conf_sigalgs; + conflen = c->conf_sigalgslen; + } else + conflen = tls12_get_psigalgs(s, 0, &conf); + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { + pref = conf; + preflen = conflen; + allow = c->peer_sigalgs; + allowlen = c->peer_sigalgslen; + } else { + allow = conf; + allowlen = conflen; + pref = c->peer_sigalgs; + preflen = c->peer_sigalgslen; + } + nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen); + if (nmatch) { + salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS)); + if (!salgs) + return 0; + nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen); + } else { + salgs = NULL; + } + c->shared_sigalgs = salgs; + c->shared_sigalgslen = nmatch; + return 1; +} + +/* Set preferred digest for each key type */ + +int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize) +{ + CERT *c = s->cert; + /* Extension ignored for inappropriate versions */ + if (!SSL_USE_SIGALGS(s)) + return 1; + /* Should never happen */ + if (!c) + return 0; + + if (c->peer_sigalgs) + OPENSSL_free(c->peer_sigalgs); + c->peer_sigalgs = OPENSSL_malloc(dsize); + if (!c->peer_sigalgs) + return 0; + c->peer_sigalgslen = dsize; + memcpy(c->peer_sigalgs, data, dsize); + return 1; +} + +int tls1_process_sigalgs(SSL *s) +{ + int idx; + size_t i; + const EVP_MD *md; + CERT *c = s->cert; + TLS_SIGALGS *sigptr; + if (!tls1_set_shared_sigalgs(s)) + return 0; + +# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { + /* + * Use first set signature preference to force message digest, + * ignoring any peer preferences. + */ + const unsigned char *sigs = NULL; + if (s->server) + sigs = c->conf_sigalgs; + else + sigs = c->client_sigalgs; + if (sigs) { + idx = tls12_get_pkey_idx(sigs[1]); + md = tls12_get_hash(sigs[0]); + c->pkeys[idx].digest = md; + c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; + if (idx == SSL_PKEY_RSA_SIGN) { + c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = + CERT_PKEY_EXPLICIT_SIGN; + c->pkeys[SSL_PKEY_RSA_ENC].digest = md; + } + } + } +# endif + + for (i = 0, sigptr = c->shared_sigalgs; + i < c->shared_sigalgslen; i++, sigptr++) { + idx = tls12_get_pkey_idx(sigptr->rsign); + if (idx > 0 && c->pkeys[idx].digest == NULL) { + md = tls12_get_hash(sigptr->rhash); + c->pkeys[idx].digest = md; + c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; + if (idx == SSL_PKEY_RSA_SIGN) { + c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = + CERT_PKEY_EXPLICIT_SIGN; + c->pkeys[SSL_PKEY_RSA_ENC].digest = md; + } + } + + } + /* + * In strict mode leave unset digests as NULL to indicate we can't use + * the certificate for signing. + */ + if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { + /* + * Set any remaining keys to default values. NOTE: if alg is not + * supported it stays as NULL. + */ +# ifndef OPENSSL_NO_DSA + if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) + c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); +# endif +# ifndef OPENSSL_NO_RSA + if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) { + c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); + c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); + } +# endif +# ifndef OPENSSL_NO_ECDSA + if (!c->pkeys[SSL_PKEY_ECC].digest) + c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +# endif + } + return 1; +} + +int SSL_get_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignhash, + unsigned char *rsig, unsigned char *rhash) +{ + const unsigned char *psig = s->cert->peer_sigalgs; + if (psig == NULL) + return 0; + if (idx >= 0) { + idx <<= 1; + if (idx >= (int)s->cert->peer_sigalgslen) + return 0; + psig += idx; + if (rhash) + *rhash = psig[0]; + if (rsig) + *rsig = psig[1]; + tls1_lookup_sigalg(phash, psign, psignhash, psig); + } + return s->cert->peer_sigalgslen / 2; +} + +int SSL_get_shared_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignhash, + unsigned char *rsig, unsigned char *rhash) +{ + TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs; + if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen) + return 0; + shsigalgs += idx; + if (phash) + *phash = shsigalgs->hash_nid; + if (psign) + *psign = shsigalgs->sign_nid; + if (psignhash) + *psignhash = shsigalgs->signandhash_nid; + if (rsig) + *rsig = shsigalgs->rsign; + if (rhash) + *rhash = shsigalgs->rhash; + return s->cert->shared_sigalgslen; +} + +# ifndef OPENSSL_NO_HEARTBEATS +int tls1_process_heartbeat(SSL *s) +{ + unsigned char *p = &s->s3->rrec.data[0], *pl; + unsigned short hbtype; + unsigned int payload; + unsigned int padding = 16; /* Use minimum padding */ + + if (s->msg_callback) + s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, + &s->s3->rrec.data[0], s->s3->rrec.length, + s, s->msg_callback_arg); + + /* Read type and payload length first */ + if (1 + 2 + 16 > s->s3->rrec.length) + return 0; /* silently discard */ + hbtype = *p++; + n2s(p, payload); + if (1 + 2 + payload + 16 > s->s3->rrec.length) + return 0; /* silently discard per RFC 6520 sec. 4 */ + pl = p; + + if (hbtype == TLS1_HB_REQUEST) { + unsigned char *buffer, *bp; + int r; + + /* + * Allocate memory for the response, size is 1 bytes message type, + * plus 2 bytes payload length, plus payload, plus padding + */ + buffer = OPENSSL_malloc(1 + 2 + payload + padding); + if (buffer == NULL) + return -1; + bp = buffer; + + /* Enter response type, length and copy payload */ + *bp++ = TLS1_HB_RESPONSE; + s2n(payload, bp); + memcpy(bp, pl, payload); + bp += payload; + /* Random padding */ + if (RAND_bytes(bp, padding) <= 0) { + OPENSSL_free(buffer); + return -1; + } + + r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, + 3 + payload + padding); + + if (r >= 0 && s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, + buffer, 3 + payload + padding, + s, s->msg_callback_arg); + + OPENSSL_free(buffer); + + if (r < 0) + return r; + } else if (hbtype == TLS1_HB_RESPONSE) { + unsigned int seq; + + /* + * We only send sequence numbers (2 bytes unsigned int), and 16 + * random bytes, so we just try to read the sequence number + */ + n2s(pl, seq); + + if (payload == 18 && seq == s->tlsext_hb_seq) { + s->tlsext_hb_seq++; + s->tlsext_hb_pending = 0; + } + } + + return 0; +} + +int tls1_heartbeat(SSL *s) +{ + unsigned char *buf, *p; + int ret = -1; + unsigned int payload = 18; /* Sequence number + random bytes */ + unsigned int padding = 16; /* Use minimum padding */ + + /* Only send if peer supports and accepts HB requests... */ + if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || + s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { + SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); + return -1; + } + + /* ...and there is none in flight yet... */ + if (s->tlsext_hb_pending) { + SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); + return -1; + } + + /* ...and no handshake in progress. */ + if (SSL_in_init(s) || s->in_handshake) { + SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); + return -1; + } + + /* + * Check if padding is too long, payload and padding must not exceed 2^14 + * - 3 = 16381 bytes in total. + */ + OPENSSL_assert(payload + padding <= 16381); + + /*- + * Create HeartBeat message, we just use a sequence number + * as payload to distuingish different messages and add + * some random stuff. + * - Message Type, 1 byte + * - Payload Length, 2 bytes (unsigned int) + * - Payload, the sequence number (2 bytes uint) + * - Payload, random bytes (16 bytes uint) + * - Padding + */ + buf = OPENSSL_malloc(1 + 2 + payload + padding); + if (buf == NULL) + return -1; + p = buf; + /* Message Type */ + *p++ = TLS1_HB_REQUEST; + /* Payload length (18 bytes here) */ + s2n(payload, p); + /* Sequence number */ + s2n(s->tlsext_hb_seq, p); + /* 16 random bytes */ + if (RAND_bytes(p, 16) <= 0) { + SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); + goto err; + } + p += 16; + /* Random padding */ + if (RAND_bytes(p, padding) <= 0) { + SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); + if (ret >= 0) { + if (s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, + buf, 3 + payload + padding, + s, s->msg_callback_arg); + + s->tlsext_hb_pending = 1; + } + +err: + OPENSSL_free(buf); + + return ret; +} +# endif + +# define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2) + +typedef struct { + size_t sigalgcnt; + int sigalgs[MAX_SIGALGLEN]; +} sig_cb_st; + +static int sig_cb(const char *elem, int len, void *arg) +{ + sig_cb_st *sarg = arg; + size_t i; + char etmp[20], *p; + int sig_alg, hash_alg; + if (elem == NULL) + return 0; + if (sarg->sigalgcnt == MAX_SIGALGLEN) + return 0; + if (len > (int)(sizeof(etmp) - 1)) + return 0; + memcpy(etmp, elem, len); + etmp[len] = 0; + p = strchr(etmp, '+'); + if (!p) + return 0; + *p = 0; + p++; + if (!*p) + return 0; + + if (!strcmp(etmp, "RSA")) + sig_alg = EVP_PKEY_RSA; + else if (!strcmp(etmp, "DSA")) + sig_alg = EVP_PKEY_DSA; + else if (!strcmp(etmp, "ECDSA")) + sig_alg = EVP_PKEY_EC; + else + return 0; + + hash_alg = OBJ_sn2nid(p); + if (hash_alg == NID_undef) + hash_alg = OBJ_ln2nid(p); + if (hash_alg == NID_undef) + return 0; + + for (i = 0; i < sarg->sigalgcnt; i += 2) { + if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg) + return 0; + } + sarg->sigalgs[sarg->sigalgcnt++] = hash_alg; + sarg->sigalgs[sarg->sigalgcnt++] = sig_alg; + return 1; +} + +/* + * Set suppored signature algorithms based on a colon separated list of the + * form sig+hash e.g. RSA+SHA512:DSA+SHA512 + */ +int tls1_set_sigalgs_list(CERT *c, const char *str, int client) +{ + sig_cb_st sig; + sig.sigalgcnt = 0; + if (!CONF_parse_list(str, ':', 1, sig_cb, &sig)) + return 0; + if (c == NULL) + return 1; + return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client); +} + +int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, + int client) +{ + unsigned char *sigalgs, *sptr; + int rhash, rsign; + size_t i; + if (salglen & 1) + return 0; + sigalgs = OPENSSL_malloc(salglen); + if (sigalgs == NULL) + return 0; + for (i = 0, sptr = sigalgs; i < salglen; i += 2) { + rhash = tls12_find_id(*psig_nids++, tls12_md, + sizeof(tls12_md) / sizeof(tls12_lookup)); + rsign = tls12_find_id(*psig_nids++, tls12_sig, + sizeof(tls12_sig) / sizeof(tls12_lookup)); + + if (rhash == -1 || rsign == -1) + goto err; + *sptr++ = rhash; + *sptr++ = rsign; + } + + if (client) { + if (c->client_sigalgs) + OPENSSL_free(c->client_sigalgs); + c->client_sigalgs = sigalgs; + c->client_sigalgslen = salglen; + } else { + if (c->conf_sigalgs) + OPENSSL_free(c->conf_sigalgs); + c->conf_sigalgs = sigalgs; + c->conf_sigalgslen = salglen; + } + + return 1; + + err: + OPENSSL_free(sigalgs); + return 0; +} + +static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid) +{ + int sig_nid; + size_t i; + if (default_nid == -1) + return 1; + sig_nid = X509_get_signature_nid(x); + if (default_nid) + return sig_nid == default_nid ? 1 : 0; + for (i = 0; i < c->shared_sigalgslen; i++) + if (sig_nid == c->shared_sigalgs[i].signandhash_nid) + return 1; + return 0; +} + +/* Check to see if a certificate issuer name matches list of CA names */ +static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x) +{ + X509_NAME *nm; + int i; + nm = X509_get_issuer_name(x); + for (i = 0; i < sk_X509_NAME_num(names); i++) { + if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i))) + return 1; + } + return 0; +} + +/* + * Check certificate chain is consistent with TLS extensions and is usable by + * server. This servers two purposes: it allows users to check chains before + * passing them to the server and it allows the server to check chains before + * attempting to use them. + */ + +/* Flags which need to be set for a certificate when stict mode not set */ + +# define CERT_PKEY_VALID_FLAGS \ + (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM) +/* Strict mode flags */ +# define CERT_PKEY_STRICT_FLAGS \ + (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \ + | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE) + +int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, + int idx) +{ + int i; + int rv = 0; + int check_flags = 0, strict_mode; + CERT_PKEY *cpk = NULL; + CERT *c = s->cert; + unsigned int suiteb_flags = tls1_suiteb(s); + /* idx == -1 means checking server chains */ + if (idx != -1) { + /* idx == -2 means checking client certificate chains */ + if (idx == -2) { + cpk = c->key; + idx = cpk - c->pkeys; + } else + cpk = c->pkeys + idx; + x = cpk->x509; + pk = cpk->privatekey; + chain = cpk->chain; + strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT; + /* If no cert or key, forget it */ + if (!x || !pk) + goto end; +# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL + /* Allow any certificate to pass test */ + if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { + rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN | + CERT_PKEY_VALID | CERT_PKEY_SIGN; + cpk->valid_flags = rv; + return rv; + } +# endif + } else { + if (!x || !pk) + return 0; + idx = ssl_cert_type(x, pk); + if (idx == -1) + return 0; + cpk = c->pkeys + idx; + if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) + check_flags = CERT_PKEY_STRICT_FLAGS; + else + check_flags = CERT_PKEY_VALID_FLAGS; + strict_mode = 1; + } + + if (suiteb_flags) { + int ok; + if (check_flags) + check_flags |= CERT_PKEY_SUITEB; + ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags); + if (ok == X509_V_OK) + rv |= CERT_PKEY_SUITEB; + else if (!check_flags) + goto end; + } + + /* + * Check all signature algorithms are consistent with signature + * algorithms extension if TLS 1.2 or later and strict mode. + */ + if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) { + int default_nid; + unsigned char rsign = 0; + if (c->peer_sigalgs) + default_nid = 0; + /* If no sigalgs extension use defaults from RFC5246 */ + else { + switch (idx) { + case SSL_PKEY_RSA_ENC: + case SSL_PKEY_RSA_SIGN: + case SSL_PKEY_DH_RSA: + rsign = TLSEXT_signature_rsa; + default_nid = NID_sha1WithRSAEncryption; + break; + + case SSL_PKEY_DSA_SIGN: + case SSL_PKEY_DH_DSA: + rsign = TLSEXT_signature_dsa; + default_nid = NID_dsaWithSHA1; + break; + + case SSL_PKEY_ECC: + rsign = TLSEXT_signature_ecdsa; + default_nid = NID_ecdsa_with_SHA1; + break; + + default: + default_nid = -1; + break; + } + } + /* + * If peer sent no signature algorithms extension and we have set + * preferred signature algorithms check we support sha1. + */ + if (default_nid > 0 && c->conf_sigalgs) { + size_t j; + const unsigned char *p = c->conf_sigalgs; + for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2) { + if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign) + break; + } + if (j == c->conf_sigalgslen) { + if (check_flags) + goto skip_sigs; + else + goto end; + } + } + /* Check signature algorithm of each cert in chain */ + if (!tls1_check_sig_alg(c, x, default_nid)) { + if (!check_flags) + goto end; + } else + rv |= CERT_PKEY_EE_SIGNATURE; + rv |= CERT_PKEY_CA_SIGNATURE; + for (i = 0; i < sk_X509_num(chain); i++) { + if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) { + if (check_flags) { + rv &= ~CERT_PKEY_CA_SIGNATURE; + break; + } else + goto end; + } + } + } + /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */ + else if (check_flags) + rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE; + skip_sigs: + /* Check cert parameters are consistent */ + if (tls1_check_cert_param(s, x, check_flags ? 1 : 2)) + rv |= CERT_PKEY_EE_PARAM; + else if (!check_flags) + goto end; + if (!s->server) + rv |= CERT_PKEY_CA_PARAM; + /* In strict mode check rest of chain too */ + else if (strict_mode) { + rv |= CERT_PKEY_CA_PARAM; + for (i = 0; i < sk_X509_num(chain); i++) { + X509 *ca = sk_X509_value(chain, i); + if (!tls1_check_cert_param(s, ca, 0)) { + if (check_flags) { + rv &= ~CERT_PKEY_CA_PARAM; + break; + } else + goto end; + } + } + } + if (!s->server && strict_mode) { + STACK_OF(X509_NAME) *ca_dn; + int check_type = 0; + switch (pk->type) { + case EVP_PKEY_RSA: + check_type = TLS_CT_RSA_SIGN; + break; + case EVP_PKEY_DSA: + check_type = TLS_CT_DSS_SIGN; + break; + case EVP_PKEY_EC: + check_type = TLS_CT_ECDSA_SIGN; + break; + case EVP_PKEY_DH: + case EVP_PKEY_DHX: + { + int cert_type = X509_certificate_type(x, pk); + if (cert_type & EVP_PKS_RSA) + check_type = TLS_CT_RSA_FIXED_DH; + if (cert_type & EVP_PKS_DSA) + check_type = TLS_CT_DSS_FIXED_DH; + } + } + if (check_type) { + const unsigned char *ctypes; + int ctypelen; + if (c->ctypes) { + ctypes = c->ctypes; + ctypelen = (int)c->ctype_num; + } else { + ctypes = (unsigned char *)s->s3->tmp.ctype; + ctypelen = s->s3->tmp.ctype_num; + } + for (i = 0; i < ctypelen; i++) { + if (ctypes[i] == check_type) { + rv |= CERT_PKEY_CERT_TYPE; + break; + } + } + if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags) + goto end; + } else + rv |= CERT_PKEY_CERT_TYPE; + + ca_dn = s->s3->tmp.ca_names; + + if (!sk_X509_NAME_num(ca_dn)) + rv |= CERT_PKEY_ISSUER_NAME; + + if (!(rv & CERT_PKEY_ISSUER_NAME)) { + if (ssl_check_ca_name(ca_dn, x)) + rv |= CERT_PKEY_ISSUER_NAME; + } + if (!(rv & CERT_PKEY_ISSUER_NAME)) { + for (i = 0; i < sk_X509_num(chain); i++) { + X509 *xtmp = sk_X509_value(chain, i); + if (ssl_check_ca_name(ca_dn, xtmp)) { + rv |= CERT_PKEY_ISSUER_NAME; + break; + } + } + } + if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME)) + goto end; + } else + rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE; + + if (!check_flags || (rv & check_flags) == check_flags) + rv |= CERT_PKEY_VALID; + + end: + + if (TLS1_get_version(s) >= TLS1_2_VERSION) { + if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN) + rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN; + else if (cpk->digest) + rv |= CERT_PKEY_SIGN; + } else + rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN; + + /* + * When checking a CERT_PKEY structure all flags are irrelevant if the + * chain is invalid. + */ + if (!check_flags) { + if (rv & CERT_PKEY_VALID) + cpk->valid_flags = rv; + else { + /* Preserve explicit sign flag, clear rest */ + cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; + return 0; + } + } + return rv; +} + +/* Set validity of certificates in an SSL structure */ +void tls1_set_cert_validity(SSL *s) +{ + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA); + tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC); +} + +/* User level utiity function to check a chain is suitable */ +int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) +{ + return tls1_check_chain(s, x, pk, chain, -1); +} + +#endif +/* ssl/t1_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "objects.h" +// #include "ssl_locl.h" + +static const SSL_METHOD *tls1_get_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return TLSv1_2_method(); + if (ver == TLS1_1_VERSION) + return TLSv1_1_method(); + if (ver == TLS1_VERSION) + return TLSv1_method(); + return NULL; +} + +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method, + ssl3_accept, + ssl3_connect, tls1_get_method, TLSv1_2_enc_data) + + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method, + ssl3_accept, + ssl3_connect, tls1_get_method, TLSv1_1_enc_data) + + IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method, + ssl3_accept, + ssl3_connect, tls1_get_method, TLSv1_enc_data) +/* ssl/t1_reneg.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2009 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +// #include "objects.h" +// #include "ssl_locl.h" + +/* Add the client's renegotiation binding */ +int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + if (p) { + if ((s->s3->previous_client_finished_len + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATE_EXT_TOO_LONG); + return 0; + } + + /* Length byte */ + *p = s->s3->previous_client_finished_len; + p++; + + memcpy(p, s->s3->previous_client_finished, + s->s3->previous_client_finished_len); +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "%s RI extension sent by client\n", + s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); +#endif + } + + *len = s->s3->previous_client_finished_len + 1; + + return 1; +} + +/* + * Parse the client's renegotiation binding and abort if it's not right + */ +int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al) +{ + int ilen; + + /* Parse the length byte */ + if (len < 1) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + ilen = *d; + d++; + + /* Consistency check */ + if ((ilen + 1) != len) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* Check that the extension matches */ + if (ilen != s->s3->previous_client_finished_len) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + if (memcmp(d, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "%s RI extension received by server\n", + ilen ? "Non-empty" : "Empty"); +#endif + + s->s3->send_connection_binding = 1; + + return 1; +} + +/* Add the server's renegotiation binding */ +int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + if (p) { + if ((s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATE_EXT_TOO_LONG); + return 0; + } + + /* Length byte */ + *p = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len; + p++; + + memcpy(p, s->s3->previous_client_finished, + s->s3->previous_client_finished_len); + p += s->s3->previous_client_finished_len; + + memcpy(p, s->s3->previous_server_finished, + s->s3->previous_server_finished_len); +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "%s RI extension sent by server\n", + s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); +#endif + } + + *len = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len + 1; + + return 1; +} + +/* + * Parse the server's renegotiation binding and abort if it's not right + */ +int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al) +{ + int expected_len = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len; + int ilen; + + /* Check for logic errors */ + OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len); + OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len); + + /* Parse the length byte */ + if (len < 1) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + ilen = *d; + d++; + + /* Consistency check */ + if (ilen + 1 != len) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* Check that the extension matches */ + if (ilen != expected_len) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + if (memcmp(d, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + d += s->s3->previous_client_finished_len; + + if (memcmp(d, s->s3->previous_server_finished, + s->s3->previous_server_finished_len)) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "%s RI extension received by client\n", + ilen ? "Non-empty" : "Empty"); +#endif + s->s3->send_connection_binding = 1; + + return 1; +} +/* ssl/t1_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "ssl_locl.h" +// #include "buffer.h" +// #include "rand.h" +// #include "objects.h" +// #include "evp.h" +#include "x509.h" + +static const SSL_METHOD *tls1_get_server_method(int ver); +static const SSL_METHOD *tls1_get_server_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return TLSv1_2_server_method(); + if (ver == TLS1_1_VERSION) + return TLSv1_1_server_method(); + if (ver == TLS1_VERSION) + return TLSv1_server_method(); + return NULL; +} + +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method, + ssl3_accept, + ssl_undefined_function, + tls1_get_server_method, TLSv1_2_enc_data) + + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method, + ssl3_accept, + ssl_undefined_function, + tls1_get_server_method, TLSv1_1_enc_data) + + IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method, + ssl3_accept, + ssl_undefined_function, + tls1_get_server_method, TLSv1_enc_data) +/* ssl/t1_trce.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2012-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +// #include "ssl_locl.h" + +#ifndef OPENSSL_NO_SSL_TRACE + +/* Packet trace support for OpenSSL */ + +typedef struct { + int num; + const char *name; +} ssl_trace_tbl; + +# define ssl_trace_str(val, tbl) \ + do_ssl_trace_str(val, tbl, sizeof(tbl)/sizeof(ssl_trace_tbl)) + +# define ssl_trace_list(bio, indent, msg, msglen, value, table) \ + do_ssl_trace_list(bio, indent, msg, msglen, value, \ + table, sizeof(table)/sizeof(ssl_trace_tbl)) + +static const char *do_ssl_trace_str(int val, ssl_trace_tbl *tbl, size_t ntbl) +{ + size_t i; + for (i = 0; i < ntbl; i++, tbl++) { + if (tbl->num == val) + return tbl->name; + } + return "UNKNOWN"; +} + +static int do_ssl_trace_list(BIO *bio, int indent, + const unsigned char *msg, size_t msglen, + size_t vlen, ssl_trace_tbl *tbl, size_t ntbl) +{ + int val; + if (msglen % vlen) + return 0; + while (msglen) { + val = msg[0]; + if (vlen == 2) + val = (val << 8) | msg[1]; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "%s (%d)\n", do_ssl_trace_str(val, tbl, ntbl), val); + msg += vlen; + msglen -= vlen; + } + return 1; +} + +/* Version number */ + +static ssl_trace_tbl ssl_version_tbl[] = { + {SSL2_VERSION, "SSL 2.0"}, + {SSL3_VERSION, "SSL 3.0"}, + {TLS1_VERSION, "TLS 1.0"}, + {TLS1_1_VERSION, "TLS 1.1"}, + {TLS1_2_VERSION, "TLS 1.2"}, + {DTLS1_VERSION, "DTLS 1.0"}, + {DTLS1_2_VERSION, "DTLS 1.2"}, + {DTLS1_BAD_VER, "DTLS 1.0 (bad)"} +}; + +static ssl_trace_tbl ssl_content_tbl[] = { + {SSL3_RT_CHANGE_CIPHER_SPEC, "ChangeCipherSpec"}, + {SSL3_RT_ALERT, "Alert"}, + {SSL3_RT_HANDSHAKE, "Handshake"}, + {SSL3_RT_APPLICATION_DATA, "ApplicationData"}, + {TLS1_RT_HEARTBEAT, "HeartBeat"} +}; + +/* Handshake types */ +static ssl_trace_tbl ssl_handshake_tbl[] = { + {SSL3_MT_HELLO_REQUEST, "HelloRequest"}, + {SSL3_MT_CLIENT_HELLO, "ClientHello"}, + {SSL3_MT_SERVER_HELLO, "ServerHello"}, + {DTLS1_MT_HELLO_VERIFY_REQUEST, "HelloVerifyRequest"}, + {SSL3_MT_NEWSESSION_TICKET, "NewSessionTicket"}, + {SSL3_MT_CERTIFICATE, "Certificate"}, + {SSL3_MT_SERVER_KEY_EXCHANGE, "ServerKeyExchange"}, + {SSL3_MT_CERTIFICATE_REQUEST, "CertificateRequest"}, + {SSL3_MT_CLIENT_KEY_EXCHANGE, "ClientKeyExchange"}, + {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"}, + {SSL3_MT_SERVER_DONE, "ServerHelloDone"}, + {SSL3_MT_CERTIFICATE_VERIFY, "CertificateVerify"}, + {SSL3_MT_CLIENT_KEY_EXCHANGE, "ClientKeyExchange"}, + {SSL3_MT_FINISHED, "Finished"}, + {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"} +}; + +/* Cipher suites */ +static ssl_trace_tbl ssl_ciphers_tbl[] = { + {0x0000, "SSL_NULL_WITH_NULL_NULL"}, + {0x0001, "SSL_RSA_WITH_NULL_MD5"}, + {0x0002, "SSL_RSA_WITH_NULL_SHA"}, + {0x0003, "SSL_RSA_EXPORT_WITH_RC4_40_MD5"}, + {0x0004, "SSL_RSA_WITH_RC4_128_MD5"}, + {0x0005, "SSL_RSA_WITH_RC4_128_SHA"}, + {0x0006, "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"}, + {0x0007, "SSL_RSA_WITH_IDEA_CBC_SHA"}, + {0x0008, "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"}, + {0x0009, "SSL_RSA_WITH_DES_CBC_SHA"}, + {0x000A, "SSL_RSA_WITH_3DES_EDE_CBC_SHA"}, + {0x000B, "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"}, + {0x000C, "SSL_DH_DSS_WITH_DES_CBC_SHA"}, + {0x000D, "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"}, + {0x000E, "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"}, + {0x000F, "SSL_DH_RSA_WITH_DES_CBC_SHA"}, + {0x0010, "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"}, + {0x0011, "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"}, + {0x0012, "SSL_DHE_DSS_WITH_DES_CBC_SHA"}, + {0x0013, "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"}, + {0x0014, "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"}, + {0x0015, "SSL_DHE_RSA_WITH_DES_CBC_SHA"}, + {0x0016, "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"}, + {0x0017, "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"}, + {0x0018, "SSL_DH_anon_WITH_RC4_128_MD5"}, + {0x0019, "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"}, + {0x001A, "SSL_DH_anon_WITH_DES_CBC_SHA"}, + {0x001B, "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"}, + {0x001D, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"}, + {0x001E, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"}, + {0x001F, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA"}, + {0x0020, "TLS_KRB5_WITH_RC4_128_SHA"}, + {0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA"}, + {0x0022, "TLS_KRB5_WITH_DES_CBC_MD5"}, + {0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5"}, + {0x0024, "TLS_KRB5_WITH_RC4_128_MD5"}, + {0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5"}, + {0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA"}, + {0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"}, + {0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA"}, + {0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"}, + {0x002A, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"}, + {0x002B, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5"}, + {0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA"}, + {0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"}, + {0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"}, + {0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"}, + {0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"}, + {0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA"}, + {0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA"}, + {0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"}, + {0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"}, + {0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"}, + {0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"}, + {0x003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA"}, + {0x003B, "TLS_RSA_WITH_NULL_SHA256"}, + {0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256"}, + {0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256"}, + {0x003E, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"}, + {0x003F, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"}, + {0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"}, + {0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"}, + {0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA"}, + {0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA"}, + {0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"}, + {0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"}, + {0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"}, + {0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"}, + {0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"}, + {0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"}, + {0x006A, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"}, + {0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"}, + {0x006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"}, + {0x006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"}, + {0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"}, + {0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA"}, + {0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA"}, + {0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"}, + {0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"}, + {0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA"}, + {0x008A, "TLS_PSK_WITH_RC4_128_SHA"}, + {0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA"}, + {0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA"}, + {0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA"}, + {0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA"}, + {0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"}, + {0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"}, + {0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"}, + {0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA"}, + {0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"}, + {0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"}, + {0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"}, + {0x0096, "TLS_RSA_WITH_SEED_CBC_SHA"}, + {0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA"}, + {0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA"}, + {0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA"}, + {0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA"}, + {0x009B, "TLS_DH_anon_WITH_SEED_CBC_SHA"}, + {0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256"}, + {0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384"}, + {0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"}, + {0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"}, + {0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"}, + {0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"}, + {0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"}, + {0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"}, + {0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"}, + {0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"}, + {0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256"}, + {0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384"}, + {0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256"}, + {0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384"}, + {0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"}, + {0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"}, + {0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"}, + {0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"}, + {0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256"}, + {0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384"}, + {0x00B0, "TLS_PSK_WITH_NULL_SHA256"}, + {0x00B1, "TLS_PSK_WITH_NULL_SHA384"}, + {0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"}, + {0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"}, + {0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256"}, + {0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384"}, + {0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"}, + {0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"}, + {0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256"}, + {0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384"}, + {0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, + {0x00BB, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256"}, + {0x00BC, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, + {0x00BD, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"}, + {0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, + {0x00BF, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"}, + {0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, + {0x00C1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"}, + {0x00C2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, + {0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256"}, + {0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, + {0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"}, + {0x00FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"}, + {0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA"}, + {0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"}, + {0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"}, + {0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"}, + {0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"}, + {0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"}, + {0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"}, + {0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"}, + {0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"}, + {0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"}, + {0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA"}, + {0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA"}, + {0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"}, + {0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"}, + {0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"}, + {0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA"}, + {0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"}, + {0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"}, + {0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"}, + {0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"}, + {0xC015, "TLS_ECDH_anon_WITH_NULL_SHA"}, + {0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA"}, + {0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"}, + {0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"}, + {0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"}, + {0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA"}, + {0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA"}, + {0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA"}, + {0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA"}, + {0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA"}, + {0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA"}, + {0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA"}, + {0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA"}, + {0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA"}, + {0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"}, + {0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"}, + {0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"}, + {0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"}, + {0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"}, + {0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"}, + {0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"}, + {0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"}, + {0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"}, + {0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"}, + {0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"}, + {0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"}, + {0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"}, + {0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"}, + {0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"}, + {0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"}, + {0xFEFE, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, + {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, +}; + +/* Compression methods */ +static ssl_trace_tbl ssl_comp_tbl[] = { + {0x0000, "No Compression"}, + {0x0001, "Zlib Compression"} +}; + +/* Extensions */ +static ssl_trace_tbl ssl_exts_tbl[] = { + {TLSEXT_TYPE_server_name, "server_name"}, + {TLSEXT_TYPE_max_fragment_length, "max_fragment_length"}, + {TLSEXT_TYPE_client_certificate_url, "client_certificate_url"}, + {TLSEXT_TYPE_trusted_ca_keys, "trusted_ca_keys"}, + {TLSEXT_TYPE_truncated_hmac, "truncated_hmac"}, + {TLSEXT_TYPE_status_request, "status_request"}, + {TLSEXT_TYPE_user_mapping, "user_mapping"}, + {TLSEXT_TYPE_client_authz, "client_authz"}, + {TLSEXT_TYPE_server_authz, "server_authz"}, + {TLSEXT_TYPE_cert_type, "cert_type"}, + {TLSEXT_TYPE_elliptic_curves, "elliptic_curves"}, + {TLSEXT_TYPE_ec_point_formats, "ec_point_formats"}, + {TLSEXT_TYPE_srp, "srp"}, + {TLSEXT_TYPE_signature_algorithms, "signature_algorithms"}, + {TLSEXT_TYPE_use_srtp, "use_srtp"}, + {TLSEXT_TYPE_heartbeat, "heartbeat"}, + {TLSEXT_TYPE_session_ticket, "session_ticket"}, +# ifdef TLSEXT_TYPE_opaque_prf_input + {TLSEXT_TYPE_opaque_prf_input, "opaque_prf_input"}, +# endif + {TLSEXT_TYPE_renegotiate, "renegotiate"}, + {TLSEXT_TYPE_next_proto_neg, "next_proto_neg"}, + {TLSEXT_TYPE_padding, "padding"} +}; + +static ssl_trace_tbl ssl_curve_tbl[] = { + {1, "sect163k1 (K-163)"}, + {2, "sect163r1"}, + {3, "sect163r2 (B-163)"}, + {4, "sect193r1"}, + {5, "sect193r2"}, + {6, "sect233k1 (K-233)"}, + {7, "sect233r1 (B-233)"}, + {8, "sect239k1"}, + {9, "sect283k1 (K-283)"}, + {10, "sect283r1 (B-283)"}, + {11, "sect409k1 (K-409)"}, + {12, "sect409r1 (B-409)"}, + {13, "sect571k1 (K-571)"}, + {14, "sect571r1 (B-571)"}, + {15, "secp160k1"}, + {16, "secp160r1"}, + {17, "secp160r2"}, + {18, "secp192k1"}, + {19, "secp192r1 (P-192)"}, + {20, "secp224k1"}, + {21, "secp224r1 (P-224)"}, + {22, "secp256k1"}, + {23, "secp256r1 (P-256)"}, + {24, "secp384r1 (P-384)"}, + {25, "secp521r1 (P-521)"}, + {26, "brainpoolP256r1"}, + {27, "brainpoolP384r1"}, + {28, "brainpoolP512r1"}, + {0xFF01, "arbitrary_explicit_prime_curves"}, + {0xFF02, "arbitrary_explicit_char2_curves"} +}; + +static ssl_trace_tbl ssl_point_tbl[] = { + {0, "uncompressed"}, + {1, "ansiX962_compressed_prime"}, + {2, "ansiX962_compressed_char2"} +}; + +static ssl_trace_tbl ssl_md_tbl[] = { + {0, "none"}, + {1, "md5"}, + {2, "sha1"}, + {3, "sha224"}, + {4, "sha256"}, + {5, "sha384"}, + {6, "sha512"} +}; + +static ssl_trace_tbl ssl_sig_tbl[] = { + {0, "anonymous"}, + {1, "rsa"}, + {2, "dsa"}, + {3, "ecdsa"} +}; + +static ssl_trace_tbl ssl_hb_tbl[] = { + {1, "peer_allowed_to_send"}, + {2, "peer_not_allowed_to_send"} +}; + +static ssl_trace_tbl ssl_hb_type_tbl[] = { + {1, "heartbeat_request"}, + {2, "heartbeat_response"} +}; + +static ssl_trace_tbl ssl_ctype_tbl[] = { + {1, "rsa_sign"}, + {2, "dss_sign"}, + {3, "rsa_fixed_dh"}, + {4, "dss_fixed_dh"}, + {5, "rsa_ephemeral_dh"}, + {6, "dss_ephemeral_dh"}, + {20, "fortezza_dms"}, + {64, "ecdsa_sign"}, + {65, "rsa_fixed_ecdh"}, + {66, "ecdsa_fixed_ecdh"} +}; + +static ssl_trace_tbl ssl_crypto_tbl[] = { + {TLS1_RT_CRYPTO_PREMASTER, "Premaster Secret"}, + {TLS1_RT_CRYPTO_CLIENT_RANDOM, "Client Random"}, + {TLS1_RT_CRYPTO_SERVER_RANDOM, "Server Random"}, + {TLS1_RT_CRYPTO_MASTER, "Master Secret"}, + {TLS1_RT_CRYPTO_MAC | TLS1_RT_CRYPTO_WRITE, "Write Mac Secret"}, + {TLS1_RT_CRYPTO_MAC | TLS1_RT_CRYPTO_READ, "Read Mac Secret"}, + {TLS1_RT_CRYPTO_KEY | TLS1_RT_CRYPTO_WRITE, "Write Key"}, + {TLS1_RT_CRYPTO_KEY | TLS1_RT_CRYPTO_READ, "Read Key"}, + {TLS1_RT_CRYPTO_IV | TLS1_RT_CRYPTO_WRITE, "Write IV"}, + {TLS1_RT_CRYPTO_IV | TLS1_RT_CRYPTO_READ, "Read IV"}, + {TLS1_RT_CRYPTO_FIXED_IV | TLS1_RT_CRYPTO_WRITE, "Write IV (fixed part)"}, + {TLS1_RT_CRYPTO_FIXED_IV | TLS1_RT_CRYPTO_READ, "Read IV (fixed part)"} +}; + +static void ssl_print_hex(BIO *bio, int indent, const char *name, + const unsigned char *msg, size_t msglen) +{ + size_t i; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "%s (len=%d): ", name, (int)msglen); + for (i = 0; i < msglen; i++) + BIO_printf(bio, "%02X", msg[i]); + BIO_puts(bio, "\n"); +} + +static int ssl_print_hexbuf(BIO *bio, int indent, + const char *name, size_t nlen, + const unsigned char **pmsg, size_t *pmsglen) +{ + size_t blen; + const unsigned char *p = *pmsg; + if (*pmsglen < nlen) + return 0; + blen = p[0]; + if (nlen > 1) + blen = (blen << 8) | p[1]; + if (*pmsglen < nlen + blen) + return 0; + p += nlen; + ssl_print_hex(bio, indent, name, p, blen); + *pmsg += blen + nlen; + *pmsglen -= blen + nlen; + return 1; +} + +static int ssl_print_version(BIO *bio, int indent, const char *name, + const unsigned char **pmsg, size_t *pmsglen) +{ + int vers; + if (*pmsglen < 2) + return 0; + vers = ((*pmsg)[0] << 8) | (*pmsg)[1]; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "%s=0x%x (%s)\n", + name, vers, ssl_trace_str(vers, ssl_version_tbl)); + *pmsg += 2; + *pmsglen -= 2; + return 1; +} + +static int ssl_print_random(BIO *bio, int indent, + const unsigned char **pmsg, size_t *pmsglen) +{ + unsigned int tm; + const unsigned char *p = *pmsg; + if (*pmsglen < 32) + return 0; + tm = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + p += 4; + BIO_indent(bio, indent, 80); + BIO_puts(bio, "Random:\n"); + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "gmt_unix_time=0x%08X\n", tm); + ssl_print_hex(bio, indent + 2, "random_bytes", p, 28); + *pmsg += 32; + *pmsglen -= 32; + return 1; +} + +static int ssl_print_signature(BIO *bio, int indent, SSL *s, + const unsigned char **pmsg, size_t *pmsglen) +{ + if (*pmsglen < 2) + return 0; + if (SSL_USE_SIGALGS(s)) { + const unsigned char *p = *pmsg; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "Signature Algorithm %s+%s (%d+%d)\n", + ssl_trace_str(p[0], ssl_md_tbl), + ssl_trace_str(p[1], ssl_sig_tbl), p[0], p[1]); + *pmsg += 2; + *pmsglen -= 2; + } + return ssl_print_hexbuf(bio, indent, "Signature", 2, pmsg, pmsglen); +} + +static int ssl_print_extension(BIO *bio, int indent, int server, int extype, + const unsigned char *ext, size_t extlen) +{ + size_t xlen; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "extension_type=%s(%d), length=%d\n", + ssl_trace_str(extype, ssl_exts_tbl), extype, (int)extlen); + switch (extype) { + case TLSEXT_TYPE_ec_point_formats: + if (extlen < 1) + return 0; + xlen = ext[0]; + if (extlen != xlen + 1) + return 0; + return ssl_trace_list(bio, indent + 2, + ext + 1, xlen, 1, ssl_point_tbl); + + case TLSEXT_TYPE_elliptic_curves: + if (extlen < 2) + return 0; + xlen = (ext[0] << 8) | ext[1]; + if (extlen != xlen + 2) + return 0; + return ssl_trace_list(bio, indent + 2, + ext + 2, xlen, 2, ssl_curve_tbl); + + case TLSEXT_TYPE_signature_algorithms: + + if (extlen < 2) + return 0; + xlen = (ext[0] << 8) | ext[1]; + if (extlen != xlen + 2) + return 0; + if (xlen & 1) + return 0; + ext += 2; + while (xlen > 0) { + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "%s+%s (%d+%d)\n", + ssl_trace_str(ext[0], ssl_md_tbl), + ssl_trace_str(ext[1], ssl_sig_tbl), ext[0], ext[1]); + xlen -= 2; + ext += 2; + } + break; + + case TLSEXT_TYPE_renegotiate: + if (extlen < 1) + return 0; + xlen = ext[0]; + if (xlen + 1 != extlen) + return 0; + ext++; + if (xlen) { + if (server) { + if (xlen & 1) + return 0; + xlen >>= 1; + } + ssl_print_hex(bio, indent + 4, "client_verify_data", ext, xlen); + if (server) { + ext += xlen; + ssl_print_hex(bio, indent + 4, + "server_verify_data", ext, xlen); + } + } else { + BIO_indent(bio, indent + 4, 80); + BIO_puts(bio, "\n"); + } + break; + + case TLSEXT_TYPE_heartbeat: + if (extlen != 1) + return 0; + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "HeartbeatMode: %s\n", + ssl_trace_str(ext[0], ssl_hb_tbl)); + break; + + case TLSEXT_TYPE_session_ticket: + if (extlen != 0) + ssl_print_hex(bio, indent + 4, "ticket", ext, extlen); + break; + + default: + BIO_dump_indent(bio, (char *)ext, extlen, indent + 2); + } + return 1; +} + +static int ssl_print_extensions(BIO *bio, int indent, int server, + const unsigned char *msg, size_t msglen) +{ + size_t extslen; + BIO_indent(bio, indent, 80); + if (msglen == 0) { + BIO_puts(bio, "No Extensions\n"); + return 1; + } + if (msglen < 2) + return 0; + extslen = (msg[0] << 8) | msg[1]; + if (extslen != msglen - 2) + return 0; + msg += 2; + msglen = extslen; + BIO_printf(bio, "extensions, length = %d\n", (int)msglen); + while (msglen > 0) { + int extype; + size_t extlen; + if (msglen < 4) + return 0; + extype = (msg[0] << 8) | msg[1]; + extlen = (msg[2] << 8) | msg[3]; + if (msglen < extlen + 4) + return 0; + msg += 4; + if (!ssl_print_extension(bio, indent + 2, server, + extype, msg, extlen)) + return 0; + msg += extlen; + msglen -= extlen + 4; + } + return 1; +} + +static int ssl_print_client_hello(BIO *bio, SSL *ssl, int indent, + const unsigned char *msg, size_t msglen) +{ + size_t len; + unsigned int cs; + if (!ssl_print_version(bio, indent, "client_version", &msg, &msglen)) + return 0; + if (!ssl_print_random(bio, indent, &msg, &msglen)) + return 0; + if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen)) + return 0; + if (SSL_IS_DTLS(ssl)) { + if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen)) + return 0; + } + if (msglen < 2) + return 0; + len = (msg[0] << 8) | msg[1]; + msg += 2; + msglen -= 2; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "cipher_suites (len=%d)\n", (int)len); + if (msglen < len || len & 1) + return 0; + while (len > 0) { + cs = (msg[0] << 8) | msg[1]; + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "{0x%02X, 0x%02X} %s\n", + msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl)); + msg += 2; + msglen -= 2; + len -= 2; + } + if (msglen < 1) + return 0; + len = msg[0]; + msg++; + msglen--; + if (msglen < len) + return 0; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "compression_methods (len=%d)\n", (int)len); + while (len > 0) { + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "%s (0x%02X)\n", + ssl_trace_str(msg[0], ssl_comp_tbl), msg[0]); + msg++; + msglen--; + len--; + } + if (!ssl_print_extensions(bio, indent, 0, msg, msglen)) + return 0; + return 1; +} + +static int dtls_print_hello_vfyrequest(BIO *bio, int indent, + const unsigned char *msg, + size_t msglen) +{ + if (!ssl_print_version(bio, indent, "server_version", &msg, &msglen)) + return 0; + if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen)) + return 0; + return 1; +} + +static int ssl_print_server_hello(BIO *bio, int indent, + const unsigned char *msg, size_t msglen) +{ + unsigned int cs; + if (!ssl_print_version(bio, indent, "server_version", &msg, &msglen)) + return 0; + if (!ssl_print_random(bio, indent, &msg, &msglen)) + return 0; + if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen)) + return 0; + if (msglen < 2) + return 0; + cs = (msg[0] << 8) | msg[1]; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "cipher_suite {0x%02X, 0x%02X} %s\n", + msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl)); + msg += 2; + msglen -= 2; + if (msglen < 1) + return 0; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "compression_method: %s (0x%02X)\n", + ssl_trace_str(msg[0], ssl_comp_tbl), msg[0]); + msg++; + msglen--; + if (!ssl_print_extensions(bio, indent, 1, msg, msglen)) + return 0; + return 1; +} + +static int ssl_get_keyex(const char **pname, SSL *ssl) +{ + unsigned long alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey; + if (alg_k & SSL_kRSA) { + *pname = "rsa"; + return SSL_kRSA; + } + if (alg_k & SSL_kDHr) { + *pname = "dh_rsa"; + return SSL_kDHr; + } + if (alg_k & SSL_kDHd) { + *pname = "dh_dss"; + return SSL_kDHd; + } + if (alg_k & SSL_kKRB5) { + *pname = "krb5"; + return SSL_kKRB5; + } + if (alg_k & SSL_kEDH) { + *pname = "edh"; + return SSL_kEDH; + } + if (alg_k & SSL_kEECDH) { + *pname = "EECDH"; + return SSL_kEECDH; + } + if (alg_k & SSL_kECDHr) { + *pname = "ECDH RSA"; + return SSL_kECDHr; + } + if (alg_k & SSL_kECDHe) { + *pname = "ECDH ECDSA"; + return SSL_kECDHe; + } + if (alg_k & SSL_kPSK) { + *pname = "PSK"; + return SSL_kPSK; + } + if (alg_k & SSL_kSRP) { + *pname = "SRP"; + return SSL_kSRP; + } + if (alg_k & SSL_kGOST) { + *pname = "GOST"; + return SSL_kGOST; + } + *pname = "UNKNOWN"; + return 0; +} + +static int ssl_print_client_keyex(BIO *bio, int indent, SSL *ssl, + const unsigned char *msg, size_t msglen) +{ + const char *algname; + int id; + id = ssl_get_keyex(&algname, ssl); + BIO_indent(bio, indent, 80); + BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname); + switch (id) { + + case SSL_kRSA: + if (TLS1_get_version(ssl) == SSL3_VERSION) { + ssl_print_hex(bio, indent + 2, + "EncyptedPreMasterSecret", msg, msglen); + } else { + if (!ssl_print_hexbuf(bio, indent + 2, + "EncyptedPreMasterSecret", 2, + &msg, &msglen)) + return 0; + } + break; + + /* Implicit parameters only allowed for static DH */ + case SSL_kDHd: + case SSL_kDHr: + if (msglen == 0) { + BIO_indent(bio, indent + 2, 80); + BIO_puts(bio, "implicit\n"); + break; + } + case SSL_kEDH: + if (!ssl_print_hexbuf(bio, indent + 2, "dh_Yc", 2, &msg, &msglen)) + return 0; + break; + + case SSL_kECDHr: + case SSL_kECDHe: + if (msglen == 0) { + BIO_indent(bio, indent + 2, 80); + BIO_puts(bio, "implicit\n"); + break; + } + case SSL_kEECDH: + if (!ssl_print_hexbuf(bio, indent + 2, "ecdh_Yc", 1, &msg, &msglen)) + return 0; + break; + } + + return 1; +} + +static int ssl_print_server_keyex(BIO *bio, int indent, SSL *ssl, + const unsigned char *msg, size_t msglen) +{ + const char *algname; + int id; + id = ssl_get_keyex(&algname, ssl); + BIO_indent(bio, indent, 80); + BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname); + switch (id) { + /* Should never happen */ + case SSL_kDHd: + case SSL_kDHr: + case SSL_kECDHr: + case SSL_kECDHe: + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "Unexpected Message\n"); + break; + + case SSL_kRSA: + + if (!ssl_print_hexbuf(bio, indent + 2, "rsa_modulus", 2, + &msg, &msglen)) + return 0; + if (!ssl_print_hexbuf(bio, indent + 2, "rsa_exponent", 2, + &msg, &msglen)) + return 0; + break; + + case SSL_kEDH: + if (!ssl_print_hexbuf(bio, indent + 2, "dh_p", 2, &msg, &msglen)) + return 0; + if (!ssl_print_hexbuf(bio, indent + 2, "dh_g", 2, &msg, &msglen)) + return 0; + if (!ssl_print_hexbuf(bio, indent + 2, "dh_Ys", 2, &msg, &msglen)) + return 0; + break; + + case SSL_kEECDH: + if (msglen < 1) + return 0; + BIO_indent(bio, indent + 2, 80); + if (msg[0] == EXPLICIT_PRIME_CURVE_TYPE) + BIO_puts(bio, "explicit_prime\n"); + else if (msg[0] == EXPLICIT_CHAR2_CURVE_TYPE) + BIO_puts(bio, "explicit_char2\n"); + else if (msg[0] == NAMED_CURVE_TYPE) { + int curve; + if (msglen < 3) + return 0; + curve = (msg[1] << 8) | msg[2]; + BIO_printf(bio, "named_curve: %s (%d)\n", + ssl_trace_str(curve, ssl_curve_tbl), curve); + msg += 3; + msglen -= 3; + if (!ssl_print_hexbuf(bio, indent + 2, "point", 1, &msg, &msglen)) + return 0; + } + break; + } + return ssl_print_signature(bio, indent, ssl, &msg, &msglen); +} + +static int ssl_print_certificate(BIO *bio, int indent, + const unsigned char **pmsg, size_t *pmsglen) +{ + size_t msglen = *pmsglen; + size_t clen; + X509 *x; + const unsigned char *p = *pmsg, *q; + if (msglen < 3) + return 0; + clen = (p[0] << 16) | (p[1] << 8) | p[2]; + if (msglen < clen + 3) + return 0; + q = p + 3; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "ASN.1Cert, length=%d", (int)clen); + x = d2i_X509(NULL, &q, clen); + if (!x) + BIO_puts(bio, "\n"); + else { + BIO_puts(bio, "\n------details-----\n"); + X509_print_ex(bio, x, XN_FLAG_ONELINE, 0); + PEM_write_bio_X509(bio, x); + /* Print certificate stuff */ + BIO_puts(bio, "------------------\n"); + X509_free(x); + } + if (q != p + 3 + clen) { + BIO_puts(bio, "\n"); + } + *pmsg += clen + 3; + *pmsglen -= clen + 3; + return 1; +} + +static int ssl_print_certificates(BIO *bio, int indent, + const unsigned char *msg, size_t msglen) +{ + size_t clen; + if (msglen < 3) + return 0; + clen = (msg[0] << 16) | (msg[1] << 8) | msg[2]; + if (msglen != clen + 3) + return 0; + msg += 3; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "certificate_list, length=%d\n", (int)clen); + while (clen > 0) { + if (!ssl_print_certificate(bio, indent + 2, &msg, &clen)) + return 0; + } + return 1; +} + +static int ssl_print_cert_request(BIO *bio, int indent, SSL *s, + const unsigned char *msg, size_t msglen) +{ + size_t xlen; + if (msglen < 1) + return 0; + xlen = msg[0]; + if (msglen < xlen + 1) + return 0; + msg++; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "certificate_types (len=%d)\n", (int)xlen); + if (!ssl_trace_list(bio, indent + 2, msg, xlen, 1, ssl_ctype_tbl)) + return 0; + msg += xlen; + msglen -= xlen + 1; + if (!SSL_USE_SIGALGS(s)) + goto skip_sig; + if (msglen < 2) + return 0; + xlen = (msg[0] << 8) | msg[1]; + if (msglen < xlen + 2 || (xlen & 1)) + return 0; + msg += 2; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "signature_algorithms (len=%d)\n", (int)xlen); + while (xlen > 0) { + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "%s+%s (%d+%d)\n", + ssl_trace_str(msg[0], ssl_md_tbl), + ssl_trace_str(msg[1], ssl_sig_tbl), msg[0], msg[1]); + xlen -= 2; + msg += 2; + } + msg += xlen; + msglen -= xlen + 2; + + skip_sig: + if (msglen < 2) + return 0; + xlen = (msg[0] << 8) | msg[1]; + BIO_indent(bio, indent, 80); + if (msglen < xlen + 2) + return 0; + msg += 2; + msglen -= 2; + BIO_printf(bio, "certificate_authorities (len=%d)\n", (int)xlen); + while (xlen > 0) { + size_t dlen; + X509_NAME *nm; + const unsigned char *p; + if (xlen < 2) + return 0; + dlen = (msg[0] << 8) | msg[1]; + if (xlen < dlen + 2) + return 0; + msg += 2; + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "DistinguishedName (len=%d): ", (int)dlen); + p = msg; + nm = d2i_X509_NAME(NULL, &p, dlen); + if (!nm) { + BIO_puts(bio, "\n"); + } else { + X509_NAME_print_ex(bio, nm, 0, XN_FLAG_ONELINE); + BIO_puts(bio, "\n"); + X509_NAME_free(nm); + } + xlen -= dlen + 2; + msg += dlen; + } + return 1; +} + +static int ssl_print_ticket(BIO *bio, int indent, + const unsigned char *msg, size_t msglen) +{ + unsigned int tick_life; + if (msglen == 0) { + BIO_indent(bio, indent + 2, 80); + BIO_puts(bio, "No Ticket\n"); + return 1; + } + if (msglen < 4) + return 0; + tick_life = (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3]; + msglen -= 4; + msg += 4; + BIO_indent(bio, indent + 2, 80); + BIO_printf(bio, "ticket_lifetime_hint=%u\n", tick_life); + if (!ssl_print_hexbuf(bio, indent + 2, "ticket", 2, &msg, &msglen)) + return 0; + if (msglen) + return 0; + return 1; +} + +static int ssl_print_handshake(BIO *bio, SSL *ssl, + const unsigned char *msg, size_t msglen, + int indent) +{ + size_t hlen; + unsigned char htype; + if (msglen < 4) + return 0; + htype = msg[0]; + hlen = (msg[1] << 16) | (msg[2] << 8) | msg[3]; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "%s, Length=%d\n", + ssl_trace_str(htype, ssl_handshake_tbl), (int)hlen); + msg += 4; + msglen -= 4; + if (SSL_IS_DTLS(ssl)) { + if (msglen < 8) + return 0; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "message_seq=%d, fragment_offset=%d, " + "fragment_length=%d\n", + (msg[0] << 8) | msg[1], + (msg[2] << 16) | (msg[3] << 8) | msg[4], + (msg[5] << 16) | (msg[6] << 8) | msg[7]); + msg += 8; + msglen -= 8; + } + if (msglen < hlen) + return 0; + switch (htype) { + case SSL3_MT_CLIENT_HELLO: + if (!ssl_print_client_hello(bio, ssl, indent + 2, msg, msglen)) + return 0; + break; + + case DTLS1_MT_HELLO_VERIFY_REQUEST: + if (!dtls_print_hello_vfyrequest(bio, indent + 2, msg, msglen)) + return 0; + break; + + case SSL3_MT_SERVER_HELLO: + if (!ssl_print_server_hello(bio, indent + 2, msg, msglen)) + return 0; + break; + + case SSL3_MT_SERVER_KEY_EXCHANGE: + if (!ssl_print_server_keyex(bio, indent + 2, ssl, msg, msglen)) + return 0; + break; + + case SSL3_MT_CLIENT_KEY_EXCHANGE: + if (!ssl_print_client_keyex(bio, indent + 2, ssl, msg, msglen)) + return 0; + break; + + case SSL3_MT_CERTIFICATE: + if (!ssl_print_certificates(bio, indent + 2, msg, msglen)) + return 0; + break; + + case SSL3_MT_CERTIFICATE_VERIFY: + if (!ssl_print_signature(bio, indent + 2, ssl, &msg, &msglen)) + return 0; + break; + + case SSL3_MT_CERTIFICATE_REQUEST: + if (!ssl_print_cert_request(bio, indent + 2, ssl, msg, msglen)) + return 0; + break; + + case SSL3_MT_FINISHED: + ssl_print_hex(bio, indent + 2, "verify_data", msg, msglen); + break; + + case SSL3_MT_SERVER_DONE: + if (msglen != 0) + ssl_print_hex(bio, indent + 2, "unexpected value", msg, msglen); + break; + + case SSL3_MT_NEWSESSION_TICKET: + if (!ssl_print_ticket(bio, indent + 2, msg, msglen)) + return 0; + break; + + default: + BIO_indent(bio, indent + 2, 80); + BIO_puts(bio, "Unsupported, hex dump follows:\n"); + BIO_dump_indent(bio, (char *)msg, msglen, indent + 4); + } + return 1; +} + +static int ssl_print_heartbeat(BIO *bio, int indent, + const unsigned char *msg, size_t msglen) +{ + if (msglen < 3) + return 0; + BIO_indent(bio, indent, 80); + BIO_printf(bio, "HeartBeatMessageType: %s\n", + ssl_trace_str(msg[0], ssl_hb_type_tbl)); + msg++; + msglen--; + if (!ssl_print_hexbuf(bio, indent, "payload", 2, &msg, &msglen)) + return 0; + ssl_print_hex(bio, indent, "padding", msg, msglen); + return 1; +} + +const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c) +{ + if (c->algorithm_ssl & SSL_SSLV2) + return NULL; + return ssl_trace_str(c->id & 0xFFFF, ssl_ciphers_tbl); +} + +void SSL_trace(int write_p, int version, int content_type, + const void *buf, size_t msglen, SSL *ssl, void *arg) +{ + const unsigned char *msg = buf; + BIO *bio = arg; + + if (write_p == 2) { + BIO_puts(bio, "Session "); + ssl_print_hex(bio, 0, + ssl_trace_str(content_type, ssl_crypto_tbl), + msg, msglen); + return; + } + switch (content_type) { + case SSL3_RT_HEADER: + { + int hvers; + + /* avoid overlapping with length at the end of buffer */ + if (msglen < (SSL_IS_DTLS(ssl) ? 13 : 5)) { + BIO_puts(bio, write_p ? "Sent" : "Received"); + ssl_print_hex(bio, 0, " too short message", msg, msglen); + break; + } + hvers = msg[1] << 8 | msg[2]; + BIO_puts(bio, write_p ? "Sent" : "Received"); + BIO_printf(bio, " Record\nHeader:\n Version = %s (0x%x)\n", + ssl_trace_str(hvers, ssl_version_tbl), hvers); + if (SSL_IS_DTLS(ssl)) { + BIO_printf(bio, + " epoch=%d, sequence_number=%04x%04x%04x\n", + (msg[3] << 8 | msg[4]), + (msg[5] << 8 | msg[6]), + (msg[7] << 8 | msg[8]), (msg[9] << 8 | msg[10])); +# if 0 + /* + * Just print handshake type so we can see what is going on + * during fragmentation. + */ + BIO_printf(bio, "(%s)\n", + ssl_trace_str(msg[msglen], ssl_handshake_tbl)); +# endif + } + + BIO_printf(bio, " Content Type = %s (%d)\n Length = %d", + ssl_trace_str(msg[0], ssl_content_tbl), msg[0], + msg[msglen - 2] << 8 | msg[msglen - 1]); + } + break; + case SSL3_RT_HANDSHAKE: + if (!ssl_print_handshake(bio, ssl, msg, msglen, 4)) + BIO_printf(bio, "Message length parse error!\n"); + break; + + case SSL3_RT_CHANGE_CIPHER_SPEC: + if (msglen == 1 && msg[0] == 1) + BIO_puts(bio, " change_cipher_spec (1)\n"); + else + ssl_print_hex(bio, 4, "unknown value", msg, msglen); + break; + + case SSL3_RT_ALERT: + if (msglen != 2) { + BIO_puts(bio, " Illegal Alert Length\n"); + } else { + BIO_printf(bio, " Level=%s(%d), description=%s(%d)\n", + SSL_alert_type_string_long(msg[0] << 8), + msg[0], SSL_alert_desc_string_long(msg[1]), msg[1]); + } + break; + + case TLS1_RT_HEARTBEAT: + ssl_print_heartbeat(bio, 4, msg, msglen); + break; + + } + + BIO_puts(bio, "\n"); +} + +#endif diff --git a/Sources/COpenSSL/t_.c b/Sources/COpenSSL/t_.c new file mode 100644 index 00000000..851f7fcc --- /dev/null +++ b/Sources/COpenSSL/t_.c @@ -0,0 +1,1385 @@ +/* t_bitst.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "conf.h" +#include "x509v3.h" + +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent) +{ + BIT_STRING_BITNAME *bnam; + char first = 1; + BIO_printf(out, "%*s", indent, ""); + for (bnam = tbl; bnam->lname; bnam++) { + if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) { + if (!first) + BIO_puts(out, ", "); + BIO_puts(out, bnam->lname); + first = 0; + } + } + BIO_puts(out, "\n"); + return 1; +} + +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, + BIT_STRING_BITNAME *tbl) +{ + int bitnum; + bitnum = ASN1_BIT_STRING_num_asc(name, tbl); + if (bitnum < 0) + return 0; + if (bs) { + if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value)) + return 0; + } + return 1; +} + +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl) +{ + BIT_STRING_BITNAME *bnam; + for (bnam = tbl; bnam->lname; bnam++) { + if (!strcmp(bnam->sname, name) || !strcmp(bnam->lname, name)) + return bnam->bitnum; + } + return -1; +} +/* t_crl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +#include "buffer.h" +#include "bn.h" +#include "objects.h" +#include "x509.h" +// #include "x509v3.h" + +#ifndef OPENSSL_NO_FP_API +int X509_CRL_print_fp(FILE *fp, X509_CRL *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = X509_CRL_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int X509_CRL_print(BIO *out, X509_CRL *x) +{ + STACK_OF(X509_REVOKED) *rev; + X509_REVOKED *r; + long l; + int i; + char *p; + + BIO_printf(out, "Certificate Revocation List (CRL):\n"); + l = X509_CRL_get_version(x); + BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l); + i = OBJ_obj2nid(x->sig_alg->algorithm); + X509_signature_print(out, x->sig_alg, NULL); + p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); + BIO_printf(out, "%8sIssuer: %s\n", "", p); + OPENSSL_free(p); + BIO_printf(out, "%8sLast Update: ", ""); + ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x)); + BIO_printf(out, "\n%8sNext Update: ", ""); + if (X509_CRL_get_nextUpdate(x)) + ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x)); + else + BIO_printf(out, "NONE"); + BIO_printf(out, "\n"); + + X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8); + + rev = X509_CRL_get_REVOKED(x); + + if (sk_X509_REVOKED_num(rev) > 0) + BIO_printf(out, "Revoked Certificates:\n"); + else + BIO_printf(out, "No Revoked Certificates.\n"); + + for (i = 0; i < sk_X509_REVOKED_num(rev); i++) { + r = sk_X509_REVOKED_value(rev, i); + BIO_printf(out, " Serial Number: "); + i2a_ASN1_INTEGER(out, r->serialNumber); + BIO_printf(out, "\n Revocation Date: "); + ASN1_TIME_print(out, r->revocationDate); + BIO_printf(out, "\n"); + X509V3_extensions_print(out, "CRL entry extensions", + r->extensions, 0, 8); + } + X509_signature_print(out, x->sig_alg, x->signature); + + return 1; + +} +/* crypto/asn1/t_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "buffer.h" +// #include "bn.h" + +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off) +{ + int n, i; + const char *neg; + + if (num == NULL) + return (1); + neg = (BN_is_negative(num)) ? "-" : ""; + if (!BIO_indent(bp, off, 128)) + return 0; + if (BN_is_zero(num)) { + if (BIO_printf(bp, "%s 0\n", number) <= 0) + return 0; + return 1; + } + + if (BN_num_bytes(num) <= BN_BYTES) { + if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg, + (unsigned long)num->d[0], neg, + (unsigned long)num->d[0]) + <= 0) + return (0); + } else { + buf[0] = 0; + if (BIO_printf(bp, "%s%s", number, + (neg[0] == '-') ? " (Negative)" : "") <= 0) + return (0); + n = BN_bn2bin(num, &buf[1]); + + if (buf[1] & 0x80) + n++; + else + buf++; + + for (i = 0; i < n; i++) { + if ((i % 15) == 0) { + if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, off + 4, 128)) + return 0; + } + if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") + <= 0) + return (0); + } + if (BIO_write(bp, "\n", 1) <= 0) + return (0); + } + return (1); +} +/* crypto/asn1/t_req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "bn.h" +// #include "objects.h" +// #include "x509.h" +// #include "x509v3.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif + +#ifndef OPENSSL_NO_FP_API +int X509_REQ_print_fp(FILE *fp, X509_REQ *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = X509_REQ_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, + unsigned long cflag) +{ + unsigned long l; + int i; + const char *neg; + X509_REQ_INFO *ri; + EVP_PKEY *pkey; + STACK_OF(X509_ATTRIBUTE) *sk; + STACK_OF(X509_EXTENSION) *exts; + char mlch = ' '; + int nmindent = 0; + + if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + nmindent = 12; + } + + if (nmflags == X509_FLAG_COMPAT) + nmindent = 16; + + ri = x->req_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bp, "Certificate Request:\n", 21) <= 0) + goto err; + if (BIO_write(bp, " Data:\n", 10) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : ""; + l = 0; + for (i = 0; i < ri->version->length; i++) { + l <<= 8; + l += ri->version->data[i]; + } + if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg, l, neg, + l) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bp, " Subject:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) + goto err; + if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0) + goto err; + if (BIO_puts(bp, "\n") <= 0) + goto err; + + pkey = X509_REQ_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bp, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bp); + } else { + EVP_PKEY_print_public(bp, pkey, 16, NULL); + EVP_PKEY_free(pkey); + } + } + + if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { + /* may not be */ + if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0) + goto err; + + sk = x->req_info->attributes; + if (sk_X509_ATTRIBUTE_num(sk) == 0) { + if (BIO_printf(bp, "%12sa0:00\n", "") <= 0) + goto err; + } else { + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + ASN1_TYPE *at; + X509_ATTRIBUTE *a; + ASN1_BIT_STRING *bs = NULL; + ASN1_TYPE *t; + int j, type = 0, count = 1, ii = 0; + + a = sk_X509_ATTRIBUTE_value(sk, i); + if (X509_REQ_extension_nid(OBJ_obj2nid(a->object))) + continue; + if (BIO_printf(bp, "%12s", "") <= 0) + goto err; + if ((j = i2a_ASN1_OBJECT(bp, a->object)) > 0) { + if (a->single) { + t = a->value.single; + type = t->type; + bs = t->value.bit_string; + } else { + ii = 0; + count = sk_ASN1_TYPE_num(a->value.set); + get_next: + at = sk_ASN1_TYPE_value(a->value.set, ii); + type = at->type; + bs = at->value.asn1_string; + } + } + for (j = 25 - j; j > 0; j--) + if (BIO_write(bp, " ", 1) != 1) + goto err; + if (BIO_puts(bp, ":") <= 0) + goto err; + if ((type == V_ASN1_PRINTABLESTRING) || + (type == V_ASN1_UTF8STRING) || + (type == V_ASN1_T61STRING) || + (type == V_ASN1_IA5STRING)) { + if (BIO_write(bp, (char *)bs->data, bs->length) + != bs->length) + goto err; + BIO_puts(bp, "\n"); + } else { + BIO_puts(bp, "unable to print attribute\n"); + } + if (++ii < count) + goto get_next; + } + } + } + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { + exts = X509_REQ_get_extensions(x); + if (exts) { + BIO_printf(bp, "%8sRequested Extensions:\n", ""); + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + int j; + ex = sk_X509_EXTENSION_value(exts, i); + if (BIO_printf(bp, "%12s", "") <= 0) + goto err; + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp, obj); + j = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) + goto err; + if (!X509V3_EXT_print(bp, ex, cflag, 16)) { + BIO_printf(bp, "%16s", ""); + M_ASN1_OCTET_STRING_print(bp, ex->value); + } + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + } + } + + if (!(cflag & X509_FLAG_NO_SIGDUMP)) { + if (!X509_signature_print(bp, x->sig_alg, x->signature)) + goto err; + } + + return (1); + err: + X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB); + return (0); +} + +int X509_REQ_print(BIO *bp, X509_REQ *x) +{ + return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} +/* t_spki.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "x509.h" +#include "asn1.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +// #include "bn.h" + +/* Print out an SPKI */ + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) +{ + EVP_PKEY *pkey; + ASN1_IA5STRING *chal; + int i, n; + char *s; + BIO_printf(out, "Netscape SPKI:\n"); + i = OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm); + BIO_printf(out, " Public Key Algorithm: %s\n", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); + pkey = X509_PUBKEY_get(spki->spkac->pubkey); + if (!pkey) + BIO_printf(out, " Unable to load public key\n"); + else { + EVP_PKEY_print_public(out, pkey, 4, NULL); + EVP_PKEY_free(pkey); + } + chal = spki->spkac->challenge; + if (chal->length) + BIO_printf(out, " Challenge String: %s\n", chal->data); + i = OBJ_obj2nid(spki->sig_algor->algorithm); + BIO_printf(out, " Signature Algorithm: %s", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); + + n = spki->signature->length; + s = (char *)spki->signature->data; + for (i = 0; i < n; i++) { + if ((i % 18) == 0) + BIO_write(out, "\n ", 7); + BIO_printf(out, "%02x%s", (unsigned char)s[i], + ((i + 1) == n) ? "" : ":"); + } + BIO_write(out, "\n", 1); + return 1; +} +/* crypto/asn1/t_x509.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "buffer.h" +// #include "bn.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif +#ifndef OPENSSL_NO_EC +# include "ec.h" +#endif +// #include "objects.h" +// #include "x509.h" +// #include "x509v3.h" +#include "asn1_locl.h" + +#ifndef OPENSSL_NO_FP_API +int X509_print_fp(FILE *fp, X509 *x) +{ + return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} + +int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, + unsigned long cflag) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = X509_print_ex(b, x, nmflag, cflag); + BIO_free(b); + return (ret); +} +#endif + +int X509_print(BIO *bp, X509 *x) +{ + return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} + +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, + unsigned long cflag) +{ + long l; + int ret = 0, i; + char *m = NULL, mlch = ' '; + int nmindent = 0; + X509_CINF *ci; + ASN1_INTEGER *bs; + EVP_PKEY *pkey = NULL; + const char *neg; + + if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + nmindent = 12; + } + + if (nmflags == X509_FLAG_COMPAT) + nmindent = 16; + + ci = x->cert_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bp, "Certificate:\n", 13) <= 0) + goto err; + if (BIO_write(bp, " Data:\n", 10) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + l = X509_get_version(x); + if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_SERIAL)) { + + if (BIO_write(bp, " Serial Number:", 22) <= 0) + goto err; + + bs = X509_get_serialNumber(x); + if (bs->length < (int)sizeof(long) + || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) { + l = ASN1_INTEGER_get(bs); + if (bs->type == V_ASN1_NEG_INTEGER) { + l = -l; + neg = "-"; + } else + neg = ""; + if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0) + goto err; + } else { + neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; + if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) + goto err; + + for (i = 0; i < bs->length; i++) { + if (BIO_printf(bp, "%02x%c", bs->data[i], + ((i + 1 == bs->length) ? '\n' : ':')) <= 0) + goto err; + } + } + + } + + if (!(cflag & X509_FLAG_NO_SIGNAME)) { + if (X509_signature_print(bp, ci->signature, NULL) <= 0) + goto err; +#if 0 + if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0) + goto err; + if (BIO_puts(bp, "\n") <= 0) + goto err; +#endif + } + + if (!(cflag & X509_FLAG_NO_ISSUER)) { + if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) + < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_VALIDITY)) { + if (BIO_write(bp, " Validity\n", 17) <= 0) + goto err; + if (BIO_write(bp, " Not Before: ", 24) <= 0) + goto err; + if (!ASN1_TIME_print(bp, X509_get_notBefore(x))) + goto err; + if (BIO_write(bp, "\n Not After : ", 25) <= 0) + goto err; + if (!ASN1_TIME_print(bp, X509_get_notAfter(x))) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bp, " Subject:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex + (bp, X509_get_subject_name(x), nmindent, nmflags) < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) + goto err; + if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) + goto err; + if (BIO_puts(bp, "\n") <= 0) + goto err; + + pkey = X509_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bp, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bp); + } else { + EVP_PKEY_print_public(bp, pkey, 16, NULL); + EVP_PKEY_free(pkey); + } + } + + if (!(cflag & X509_FLAG_NO_IDS)) { + if (ci->issuerUID) { + if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) + goto err; + if (!X509_signature_dump(bp, ci->issuerUID, 12)) + goto err; + } + if (ci->subjectUID) { + if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) + goto err; + if (!X509_signature_dump(bp, ci->subjectUID, 12)) + goto err; + } + } + + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) + X509V3_extensions_print(bp, "X509v3 extensions", + ci->extensions, cflag, 8); + + if (!(cflag & X509_FLAG_NO_SIGDUMP)) { + if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_AUX)) { + if (!X509_CERT_AUX_print(bp, x->aux, 0)) + goto err; + } + ret = 1; + err: + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +int X509_ocspid_print(BIO *bp, X509 *x) +{ + unsigned char *der = NULL; + unsigned char *dertmp; + int derlen; + int i; + unsigned char SHA1md[SHA_DIGEST_LENGTH]; + + /* + * display the hash of the subject as it would appear in OCSP requests + */ + if (BIO_printf(bp, " Subject OCSP hash: ") <= 0) + goto err; + derlen = i2d_X509_NAME(x->cert_info->subject, NULL); + if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL) + goto err; + i2d_X509_NAME(x->cert_info->subject, &dertmp); + + if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) + goto err; + for (i = 0; i < SHA_DIGEST_LENGTH; i++) { + if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) + goto err; + } + OPENSSL_free(der); + der = NULL; + + /* + * display the hash of the public key as it would appear in OCSP requests + */ + if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0) + goto err; + + if (!EVP_Digest(x->cert_info->key->public_key->data, + x->cert_info->key->public_key->length, + SHA1md, NULL, EVP_sha1(), NULL)) + goto err; + for (i = 0; i < SHA_DIGEST_LENGTH; i++) { + if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) + goto err; + } + BIO_printf(bp, "\n"); + + return (1); + err: + if (der != NULL) + OPENSSL_free(der); + return (0); +} + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) +{ + const unsigned char *s; + int i, n; + + n = sig->length; + s = sig->data; + for (i = 0; i < n; i++) { + if ((i % 18) == 0) { + if (BIO_write(bp, "\n", 1) <= 0) + return 0; + if (BIO_indent(bp, indent, indent) <= 0) + return 0; + } + if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0) + return 0; + } + if (BIO_write(bp, "\n", 1) != 1) + return 0; + + return 1; +} + +int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig) +{ + int sig_nid; + if (BIO_puts(bp, " Signature Algorithm: ") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) + return 0; + + sig_nid = OBJ_obj2nid(sigalg->algorithm); + if (sig_nid != NID_undef) { + int pkey_nid, dig_nid; + const EVP_PKEY_ASN1_METHOD *ameth; + if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) { + ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); + if (ameth && ameth->sig_print) + return ameth->sig_print(bp, sigalg, sig, 9, 0); + } + } + if (sig) + return X509_signature_dump(bp, sig, 9); + else if (BIO_puts(bp, "\n") <= 0) + return 0; + return 1; +} + +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) +{ + int i, n; + char buf[80]; + const char *p; + + if (v == NULL) + return (0); + n = 0; + p = (const char *)v->data; + for (i = 0; i < v->length; i++) { + if ((p[i] > '~') || ((p[i] < ' ') && + (p[i] != '\n') && (p[i] != '\r'))) + buf[n] = '.'; + else + buf[n] = p[i]; + n++; + if (n >= 80) { + if (BIO_write(bp, buf, n) <= 0) + return (0); + n = 0; + } + } + if (n > 0) + if (BIO_write(bp, buf, n) <= 0) + return (0); + return (1); +} + +int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) +{ + if (tm->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_print(bp, tm); + if (tm->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_print(bp, tm); + BIO_write(bp, "Bad time value", 14); + return (0); +} + +static const char *mon[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) +{ + char *v; + int gmt = 0; + int i; + int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; + char *f = NULL; + int f_len = 0; + + i = tm->length; + v = (char *)tm->data; + + if (i < 12) + goto err; + if (v[i - 1] == 'Z') + gmt = 1; + for (i = 0; i < 12; i++) + if ((v[i] > '9') || (v[i] < '0')) + goto err; + y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + + (v[2] - '0') * 10 + (v[3] - '0'); + M = (v[4] - '0') * 10 + (v[5] - '0'); + if ((M > 12) || (M < 1)) + goto err; + d = (v[6] - '0') * 10 + (v[7] - '0'); + h = (v[8] - '0') * 10 + (v[9] - '0'); + m = (v[10] - '0') * 10 + (v[11] - '0'); + if (tm->length >= 14 && + (v[12] >= '0') && (v[12] <= '9') && + (v[13] >= '0') && (v[13] <= '9')) { + s = (v[12] - '0') * 10 + (v[13] - '0'); + /* Check for fractions of seconds. */ + if (tm->length >= 15 && v[14] == '.') { + int l = tm->length; + f = &v[14]; /* The decimal point. */ + f_len = 1; + while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9') + ++f_len; + } + } + + if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", + mon[M - 1], d, h, m, s, f_len, f, y, + (gmt) ? " GMT" : "") <= 0) + return (0); + else + return (1); + err: + BIO_write(bp, "Bad time value", 14); + return (0); +} + +int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) +{ + const char *v; + int gmt = 0; + int i; + int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; + + i = tm->length; + v = (const char *)tm->data; + + if (i < 10) + goto err; + if (v[i - 1] == 'Z') + gmt = 1; + for (i = 0; i < 10; i++) + if ((v[i] > '9') || (v[i] < '0')) + goto err; + y = (v[0] - '0') * 10 + (v[1] - '0'); + if (y < 50) + y += 100; + M = (v[2] - '0') * 10 + (v[3] - '0'); + if ((M > 12) || (M < 1)) + goto err; + d = (v[4] - '0') * 10 + (v[5] - '0'); + h = (v[6] - '0') * 10 + (v[7] - '0'); + m = (v[8] - '0') * 10 + (v[9] - '0'); + if (tm->length >= 12 && + (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9')) + s = (v[10] - '0') * 10 + (v[11] - '0'); + + if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", + mon[M - 1], d, h, m, s, y + 1900, + (gmt) ? " GMT" : "") <= 0) + return (0); + else + return (1); + err: + BIO_write(bp, "Bad time value", 14); + return (0); +} + +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase) +{ + char *s, *c, *b; + int ret = 0, l, i; + + l = 80 - 2 - obase; + + b = X509_NAME_oneline(name, NULL, 0); + if (!b) + return 0; + if (!*b) { + OPENSSL_free(b); + return 1; + } + s = b + 1; /* skip the first slash */ + + c = s; + for (;;) { +#ifndef CHARSET_EBCDIC + if (((*s == '/') && + ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || + ((s[2] >= 'A') + && (s[2] <= 'Z') + && (s[3] == '=')) + ))) || (*s == '\0')) +#else + if (((*s == '/') && + (isupper(s[1]) && ((s[2] == '=') || + (isupper(s[2]) && (s[3] == '=')) + ))) || (*s == '\0')) +#endif + { + i = s - c; + if (BIO_write(bp, c, i) != i) + goto err; + c = s + 1; /* skip following slash */ + if (*s != '\0') { + if (BIO_write(bp, ", ", 2) != 2) + goto err; + } + l--; + } + if (*s == '\0') + break; + s++; + l--; + } + + ret = 1; + if (0) { + err: + X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB); + } + OPENSSL_free(b); + return (ret); +} +/* t_x509a.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +#include "evp.h" +// #include "asn1.h" +// #include "x509.h" + +/* + * X509_CERT_AUX and string set routines + */ + +int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) +{ + char oidstr[80], first; + int i; + if (!aux) + return 1; + if (aux->trust) { + first = 1; + BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, ""); + for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { + if (!first) + BIO_puts(out, ", "); + else + first = 0; + OBJ_obj2txt(oidstr, sizeof(oidstr), + sk_ASN1_OBJECT_value(aux->trust, i), 0); + BIO_puts(out, oidstr); + } + BIO_puts(out, "\n"); + } else + BIO_printf(out, "%*sNo Trusted Uses.\n", indent, ""); + if (aux->reject) { + first = 1; + BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, ""); + for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { + if (!first) + BIO_puts(out, ", "); + else + first = 0; + OBJ_obj2txt(oidstr, sizeof(oidstr), + sk_ASN1_OBJECT_value(aux->reject, i), 0); + BIO_puts(out, oidstr); + } + BIO_puts(out, "\n"); + } else + BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); + if (aux->alias) + BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data); + if (aux->keyid) { + BIO_printf(out, "%*sKey Id: ", indent, ""); + for (i = 0; i < aux->keyid->length; i++) + BIO_printf(out, "%s%02X", i ? ":" : "", aux->keyid->data[i]); + BIO_write(out, "\n", 1); + } + return 1; +} diff --git a/Sources/COpenSSL/tasn_.c b/Sources/COpenSSL/tasn_.c new file mode 100644 index 00000000..20d21bcb --- /dev/null +++ b/Sources/COpenSSL/tasn_.c @@ -0,0 +1,3567 @@ +/* tasn_dec.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "asn1.h" +#include "asn1t.h" +#include "objects.h" +#include "buffer.h" +#include "err.h" + +/* + * Constructed types with a recursive definition (such as can be found in PKCS7) + * could eventually exceed the stack given malicious input with excessive + * recursion. Therefore we limit the stack depth. This is the maximum number of + * recursive invocations of asn1_item_embed_d2i(). + */ +#define ASN1_MAX_CONSTRUCTED_NEST 30 + +static int asn1_check_eoc(const unsigned char **in, long len); +static int asn1_find_end(const unsigned char **in, long len, char inf); + +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, + char inf, int tag, int aclass, int depth); + +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); + +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + char *inf, char *cst, + const unsigned char **in, long len, + int exptag, int expclass, char opt, ASN1_TLC *ctx); + +static int asn1_template_ex_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx, int depth); +static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx, int depth); +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, + ASN1_TLC *ctx); + +/* Table to convert tags to bit values, used for MSTRING type */ +static const unsigned long tag2bit[32] = { + /* tags 0 - 3 */ + 0, 0, 0, B_ASN1_BIT_STRING, + /* tags 4- 7 */ + B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, + /* tags 8-11 */ + B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, + /* tags 12-15 */ + B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, + /* tags 16-19 */ + B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, + /* tags 20-22 */ + B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, + /* tags 23-24 */ + B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, + /* tags 25-27 */ + B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, + /* tags 28-31 */ + B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, +}; + +unsigned long ASN1_tag2bit(int tag) +{ + if ((tag < 0) || (tag > 30)) + return 0; + return tag2bit[tag]; +} + +/* Macro to initialize and invalidate the cache */ + +#define asn1_tlc_clear(c) if (c) (c)->valid = 0 +/* Version to avoid compiler warning about 'c' always non-NULL */ +#define asn1_tlc_clear_nc(c) (c)->valid = 0 + +/* + * Decode an ASN1 item, this currently behaves just like a standard 'd2i' + * function. 'in' points to a buffer to read the data from, in future we + * will have more advanced versions that can input data a piece at a time and + * this will simply be a special case. + */ + +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it) +{ + ASN1_TLC c; + ASN1_VALUE *ptmpval = NULL; + if (!pval) + pval = &ptmpval; + asn1_tlc_clear_nc(&c); + if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) + return *pval; + return NULL; +} + +int ASN1_template_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt) +{ + ASN1_TLC c; + asn1_tlc_clear_nc(&c); + return asn1_template_ex_d2i(pval, in, len, tt, 0, &c, 0); +} + +/* + * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and + * tag mismatch return -1 to handle OPTIONAL + */ +static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, + long len, const ASN1_ITEM *it, int tag, int aclass, + char opt, ASN1_TLC *ctx, int depth) +{ + const ASN1_TEMPLATE *tt, *errtt = NULL; + const ASN1_COMPAT_FUNCS *cf; + const ASN1_EXTERN_FUNCS *ef; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + const unsigned char *p = NULL, *q; + unsigned char *wp = NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ + unsigned char imphack = 0, oclass; + char seq_eoc, seq_nolen, cst, isopt; + long tmplen; + int i; + int otag; + int ret = 0; + ASN1_VALUE **pchptr, *ptmpval; + int combine = aclass & ASN1_TFLG_COMBINE; + aclass &= ~ASN1_TFLG_COMBINE; + if (!pval) + return 0; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + else + asn1_cb = 0; + + if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NESTED_TOO_DEEP); + goto err; + } + + switch (it->itype) { + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + /* + * tagging or OPTIONAL is currently illegal on an item template + * because the flags can't get passed down. In practice this + * isn't a problem: we include the relevant flags from the item + * template in the template itself. + */ + if ((tag != -1) || opt) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); + goto err; + } + return asn1_template_ex_d2i(pval, in, len, + it->templates, opt, ctx, depth); + } + return asn1_d2i_ex_primitive(pval, in, len, it, + tag, aclass, opt, ctx); + break; + + case ASN1_ITYPE_MSTRING: + p = *in; + /* Just read in tag and class */ + ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, + &p, len, -1, 0, 1, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + /* Must be UNIVERSAL class */ + if (oclass != V_ASN1_UNIVERSAL) { + /* If OPTIONAL, assume this is OK */ + if (opt) + return -1; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); + goto err; + } + /* Check tag matches bit map */ + if (!(ASN1_tag2bit(otag) & it->utype)) { + /* If OPTIONAL, assume this is OK */ + if (opt) + return -1; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG); + goto err; + } + return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); + + case ASN1_ITYPE_EXTERN: + /* Use new style d2i */ + ef = it->funcs; + return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); + + case ASN1_ITYPE_COMPAT: + /* we must resort to old style evil hackery */ + cf = it->funcs; + + /* If OPTIONAL see if it is there */ + if (opt) { + int exptag; + p = *in; + if (tag == -1) + exptag = it->utype; + else + exptag = tag; + /* + * Don't care about anything other than presence of expected tag + */ + + ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, + &p, len, exptag, aclass, 1, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (ret == -1) + return -1; + } + + /* + * This is the old style evil hack IMPLICIT handling: since the + * underlying code is expecting a tag and class other than the one + * present we change the buffer temporarily then change it back + * afterwards. This doesn't and never did work for tags > 30. Yes + * this is *horrible* but it is only needed for old style d2i which + * will hopefully not be around for much longer. FIXME: should copy + * the buffer then modify it so the input buffer can be const: we + * should *always* copy because the old style d2i might modify the + * buffer. + */ + + if (tag != -1) { + wp = *(unsigned char **)in; + imphack = *wp; + if (p == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) + | it->utype); + } + + ptmpval = cf->asn1_d2i(pval, in, len); + + if (tag != -1) + *wp = imphack; + + if (ptmpval) + return 1; + + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + + case ASN1_ITYPE_CHOICE: + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; + if (*pval) { + /* Free up and zero CHOICE value if initialised */ + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + tt = it->templates + i; + pchptr = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchptr, tt); + asn1_set_choice_selector(pval, -1, it); + } + } else if (!ASN1_item_ex_new(pval, it)) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + /* CHOICE type, try each possibility in turn */ + p = *in; + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + pchptr = asn1_get_field_ptr(pval, tt); + /* + * We mark field as OPTIONAL so its absence can be recognised. + */ + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); + /* If field not present, try the next one */ + if (ret == -1) + continue; + /* If positive return, read OK, break loop */ + if (ret > 0) + break; + /* Otherwise must be an ASN1 parsing error */ + errtt = tt; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + /* Did we fall off the end without reading anything? */ + if (i == it->tcount) { + /* If OPTIONAL, this is OK */ + if (opt) { + /* Free and zero it */ + ASN1_item_ex_free(pval, it); + return -1; + } + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); + goto err; + } + + asn1_set_choice_selector(pval, i, it); + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) + goto auxerr; + *in = p; + return 1; + + case ASN1_ITYPE_NDEF_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: + p = *in; + tmplen = len; + + /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ + if (tag == -1) { + tag = V_ASN1_SEQUENCE; + aclass = V_ASN1_UNIVERSAL; + } + /* Get SEQUENCE length and update len, p */ + ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, + &p, len, tag, aclass, opt, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + if (aux && (aux->flags & ASN1_AFLG_BROKEN)) { + len = tmplen - (p - *in); + seq_nolen = 1; + } + /* If indefinite we don't do a length check */ + else + seq_nolen = seq_eoc; + if (!cst) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); + goto err; + } + + if (!*pval && !ASN1_item_ex_new(pval, it)) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; + + /* Free up and zero any ADB found */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + if (tt->flags & ASN1_TFLG_ADB_MASK) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 0); + if (seqtt == NULL) + continue; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } + } + + /* Get each field entry */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (seqtt == NULL) + goto err; + pseqval = asn1_get_field_ptr(pval, seqtt); + /* Have we ran out of data? */ + if (!len) + break; + q = p; + if (asn1_check_eoc(&p, len)) { + if (!seq_eoc) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC); + goto err; + } + len -= p - q; + seq_eoc = 0; + q = p; + break; + } + /* + * This determines the OPTIONAL flag value. The field cannot be + * omitted if it is the last of a SEQUENCE and there is still + * data to be read. This isn't strictly necessary but it + * increases efficiency in some cases. + */ + if (i == (it->tcount - 1)) + isopt = 0; + else + isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); + /* + * attempt to read in field, allowing each to be OPTIONAL + */ + + ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, + depth); + if (!ret) { + errtt = seqtt; + goto err; + } else if (ret == -1) { + /* + * OPTIONAL component absent. Free and zero the field. + */ + ASN1_template_free(pseqval, seqtt); + continue; + } + /* Update length */ + len -= p - q; + } + + /* Check for EOC if expecting one */ + if (seq_eoc && !asn1_check_eoc(&p, len)) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); + goto err; + } + /* Check all data read */ + if (!seq_nolen && len) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); + goto err; + } + + /* + * If we get here we've got no more data in the SEQUENCE, however we + * may not have read all fields so check all remaining are OPTIONAL + * and clear any that are. + */ + for (; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + seqtt = asn1_do_adb(pval, tt, 1); + if (seqtt == NULL) + goto err; + if (seqtt->flags & ASN1_TFLG_OPTIONAL) { + ASN1_VALUE **pseqval; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } else { + errtt = seqtt; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING); + goto err; + } + } + /* Save encoding */ + if (!asn1_enc_save(pval, *in, p - *in, it)) + goto auxerr; + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) + goto auxerr; + *in = p; + return 1; + + default: + return 0; + } + auxerr: + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); + err: + if (combine == 0) + ASN1_item_ex_free(pval, it); + if (errtt) + ERR_add_error_data(4, "Field=", errtt->field_name, + ", Type=", it->sname); + else + ERR_add_error_data(2, "Type=", it->sname); + return 0; +} + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); +} + +/* + * Templates are handled with two separate functions. One handles any + * EXPLICIT tag and the other handles the rest. + */ + +static int asn1_template_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long inlen, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx, int depth) +{ + int flags, aclass; + int ret; + long len; + const unsigned char *p, *q; + char exp_eoc; + if (!val) + return 0; + flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; + + p = *in; + + /* Check if EXPLICIT tag expected */ + if (flags & ASN1_TFLG_EXPTAG) { + char cst; + /* + * Need to work out amount of data available to the inner content and + * where it starts: so read in EXPLICIT header to get the info. + */ + ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, + &p, inlen, tt->tag, aclass, opt, ctx); + q = p; + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + if (!cst) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); + return 0; + } + /* We've found the field so it can't be OPTIONAL now */ + ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + /* We read the field in OK so update length */ + len -= p - q; + if (exp_eoc) { + /* If NDEF we must have an EOC here */ + if (!asn1_check_eoc(&p, len)) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC); + goto err; + } + } else { + /* + * Otherwise we must hit the EXPLICIT tag end or its an error + */ + if (len) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ASN1_R_EXPLICIT_LENGTH_MISMATCH); + goto err; + } + } + } else + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); + + *in = p; + return 1; + + err: + ASN1_template_free(val, tt); + return 0; +} + +static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx, int depth) +{ + int flags, aclass; + int ret; + const unsigned char *p, *q; + if (!val) + return 0; + flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; + + p = *in; + q = p; + + if (flags & ASN1_TFLG_SK_MASK) { + /* SET OF, SEQUENCE OF */ + int sktag, skaclass; + char sk_eoc; + /* First work out expected inner tag value */ + if (flags & ASN1_TFLG_IMPTAG) { + sktag = tt->tag; + skaclass = aclass; + } else { + skaclass = V_ASN1_UNIVERSAL; + if (flags & ASN1_TFLG_SET_OF) + sktag = V_ASN1_SET; + else + sktag = V_ASN1_SEQUENCE; + } + /* Get the tag */ + ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, + &p, len, sktag, skaclass, opt, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + if (!*val) + *val = (ASN1_VALUE *)sk_new_null(); + else { + /* + * We've got a valid STACK: free up any items present + */ + STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val; + ASN1_VALUE *vtmp; + while (sk_ASN1_VALUE_num(sktmp) > 0) { + vtmp = sk_ASN1_VALUE_pop(sktmp); + ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); + } + } + + if (!*val) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Read as many items as we can */ + while (len > 0) { + ASN1_VALUE *skfield; + q = p; + /* See if EOC found */ + if (asn1_check_eoc(&p, len)) { + if (!sk_eoc) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ASN1_R_UNEXPECTED_EOC); + goto err; + } + len -= p - q; + sk_eoc = 0; + break; + } + skfield = NULL; + if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), + -1, 0, 0, ctx, depth)) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_NESTED_ASN1_ERROR); + goto err; + } + len -= p - q; + if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { + ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if (sk_eoc) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); + goto err; + } + } else if (flags & ASN1_TFLG_IMPTAG) { + /* IMPLICIT tagging */ + ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, + aclass, opt, ctx, depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + } else { + /* Nothing special */ + ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), + -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, + depth); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + } + + *in = p; + return 1; + + err: + ASN1_template_free(val, tt); + return 0; +} + +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long inlen, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + int ret = 0, utype; + long plen; + char cst, inf, free_cont = 0; + const unsigned char *p; + BUF_MEM buf = { 0, NULL, 0 }; + const unsigned char *cont = NULL; + long len; + if (!pval) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); + return 0; /* Should never happen */ + } + + if (it->itype == ASN1_ITYPE_MSTRING) { + utype = tag; + tag = -1; + } else + utype = it->utype; + + if (utype == V_ASN1_ANY) { + /* If type is ANY need to figure out type from tag */ + unsigned char oclass; + if (tag >= 0) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); + return 0; + } + if (opt) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ASN1_R_ILLEGAL_OPTIONAL_ANY); + return 0; + } + p = *in; + ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, + &p, inlen, -1, 0, 0, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + if (oclass != V_ASN1_UNIVERSAL) + utype = V_ASN1_OTHER; + } + if (tag == -1) { + tag = utype; + aclass = V_ASN1_UNIVERSAL; + } + p = *in; + /* Check header */ + ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, + &p, inlen, tag, aclass, opt, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + ret = 0; + /* SEQUENCE, SET and "OTHER" are left in encoded form */ + if ((utype == V_ASN1_SEQUENCE) + || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { + /* + * Clear context cache for type OTHER because the auto clear when we + * have a exact match wont work + */ + if (utype == V_ASN1_OTHER) { + asn1_tlc_clear(ctx); + } + /* SEQUENCE and SET must be constructed */ + else if (!cst) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ASN1_R_TYPE_NOT_CONSTRUCTED); + return 0; + } + + cont = *in; + /* If indefinite length constructed find the real end */ + if (inf) { + if (!asn1_find_end(&p, plen, inf)) + goto err; + len = p - cont; + } else { + len = p - cont + plen; + p += plen; + } + } else if (cst) { + if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN + || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER + || utype == V_ASN1_ENUMERATED) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE); + return 0; + } + + /* Free any returned 'buf' content */ + free_cont = 1; + /* + * Should really check the internal tags are correct but some things + * may get this wrong. The relevant specs say that constructed string + * types should be OCTET STRINGs internally irrespective of the type. + * So instead just check for UNIVERSAL class and ignore the tag. + */ + if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) { + goto err; + } + len = buf.length; + /* Append a final null to string */ + if (!BUF_MEM_grow_clean(&buf, len + 1)) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); + goto err; + } + buf.data[len] = 0; + cont = (const unsigned char *)buf.data; + } else { + cont = p; + len = plen; + p += plen; + } + + /* We now have content length and type: translate into a structure */ + /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */ + if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) + goto err; + + *in = p; + ret = 1; + err: + if (free_cont && buf.data) + OPENSSL_free(buf.data); + return ret; +} + +/* Translate ASN1 content octets into a structure */ + +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) +{ + ASN1_VALUE **opval = NULL; + ASN1_STRING *stmp; + ASN1_TYPE *typ = NULL; + int ret = 0; + const ASN1_PRIMITIVE_FUNCS *pf; + ASN1_INTEGER **tint; + pf = it->funcs; + + if (pf && pf->prim_c2i) + return pf->prim_c2i(pval, cont, len, utype, free_cont, it); + /* If ANY type clear type and set pointer to internal value */ + if (it->utype == V_ASN1_ANY) { + if (!*pval) { + typ = ASN1_TYPE_new(); + if (typ == NULL) + goto err; + *pval = (ASN1_VALUE *)typ; + } else + typ = (ASN1_TYPE *)*pval; + + if (utype != typ->type) + ASN1_TYPE_set(typ, utype, NULL); + opval = pval; + pval = &typ->value.asn1_value; + } + switch (utype) { + case V_ASN1_OBJECT: + if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) + goto err; + break; + + case V_ASN1_NULL: + if (len) { + ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH); + goto err; + } + *pval = (ASN1_VALUE *)1; + break; + + case V_ASN1_BOOLEAN: + if (len != 1) { + ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + goto err; + } else { + ASN1_BOOLEAN *tbool; + tbool = (ASN1_BOOLEAN *)pval; + *tbool = *cont; + } + break; + + case V_ASN1_BIT_STRING: + if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) + goto err; + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + tint = (ASN1_INTEGER **)pval; + if (!c2i_ASN1_INTEGER(tint, &cont, len)) + goto err; + /* Fixup type to match the expected form */ + (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); + break; + + case V_ASN1_OCTET_STRING: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_OTHER: + case V_ASN1_SET: + case V_ASN1_SEQUENCE: + default: + if (utype == V_ASN1_BMPSTRING && (len & 1)) { + ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); + goto err; + } + if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { + ASN1err(ASN1_F_ASN1_EX_C2I, + ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); + goto err; + } + /* All based on ASN1_STRING and handled the same */ + if (!*pval) { + stmp = ASN1_STRING_type_new(utype); + if (!stmp) { + ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); + goto err; + } + *pval = (ASN1_VALUE *)stmp; + } else { + stmp = (ASN1_STRING *)*pval; + stmp->type = utype; + } + /* If we've already allocated a buffer use it */ + if (*free_cont) { + if (stmp->data) + OPENSSL_free(stmp->data); + stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ + stmp->length = len; + *free_cont = 0; + } else { + if (!ASN1_STRING_set(stmp, cont, len)) { + ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(stmp); + *pval = NULL; + goto err; + } + } + break; + } + /* If ASN1_ANY and NULL type fix up value */ + if (typ && (utype == V_ASN1_NULL)) + typ->value.ptr = NULL; + + ret = 1; + err: + if (!ret) { + ASN1_TYPE_free(typ); + if (opval) + *opval = NULL; + } + return ret; +} + +/* + * This function finds the end of an ASN1 structure when passed its maximum + * length, whether it is indefinite length and a pointer to the content. This + * is more efficient than calling asn1_collect because it does not recurse on + * each indefinite length header. + */ + +static int asn1_find_end(const unsigned char **in, long len, char inf) +{ + int expected_eoc; + long plen; + const unsigned char *p = *in, *q; + /* If not indefinite length constructed just add length */ + if (inf == 0) { + *in += len; + return 1; + } + expected_eoc = 1; + /* + * Indefinite length constructed form. Find the end when enough EOCs are + * found. If more indefinite length constructed headers are encountered + * increment the expected eoc count otherwise just skip to the end of the + * data. + */ + while (len > 0) { + if (asn1_check_eoc(&p, len)) { + expected_eoc--; + if (expected_eoc == 0) + break; + len -= 2; + continue; + } + q = p; + /* Just read in a header: only care about the length */ + if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, + -1, 0, 0, NULL)) { + ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + if (inf) + expected_eoc++; + else + p += plen; + len -= p - q; + } + if (expected_eoc) { + ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); + return 0; + } + *in = p; + return 1; +} + +/* + * This function collects the asn1 data from a constructred string type into + * a buffer. The values of 'in' and 'len' should refer to the contents of the + * constructed type and 'inf' should be set if it is indefinite length. + */ + +#ifndef ASN1_MAX_STRING_NEST +/* + * This determines how many levels of recursion are permitted in ASN1 string + * types. If it is not limited stack overflows can occur. If set to zero no + * recursion is allowed at all. Although zero should be adequate examples + * exist that require a value of 1. So 5 should be more than enough. + */ +# define ASN1_MAX_STRING_NEST 5 +#endif + +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, + char inf, int tag, int aclass, int depth) +{ + const unsigned char *p, *q; + long plen; + char cst, ininf; + p = *in; + inf &= 1; + /* + * If no buffer and not indefinite length constructed just pass over the + * encoded data + */ + if (!buf && !inf) { + *in += len; + return 1; + } + while (len > 0) { + q = p; + /* Check for EOC */ + if (asn1_check_eoc(&p, len)) { + /* + * EOC is illegal outside indefinite length constructed form + */ + if (!inf) { + ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); + return 0; + } + inf = 0; + break; + } + + if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, + len, tag, aclass, 0, NULL)) { + ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + + /* If indefinite length constructed update max length */ + if (cst) { + if (depth >= ASN1_MAX_STRING_NEST) { + ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); + return 0; + } + if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1)) + return 0; + } else if (plen && !collect_data(buf, &p, plen)) + return 0; + len -= p - q; + } + if (inf) { + ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); + return 0; + } + *in = p; + return 1; +} + +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) +{ + int len; + if (buf) { + len = buf->length; + if (!BUF_MEM_grow_clean(buf, len + plen)) { + ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(buf->data + len, *p, plen); + } + *p += plen; + return 1; +} + +/* Check for ASN1 EOC and swallow it if found */ + +static int asn1_check_eoc(const unsigned char **in, long len) +{ + const unsigned char *p; + if (len < 2) + return 0; + p = *in; + if (!p[0] && !p[1]) { + *in += 2; + return 1; + } + return 0; +} + +/* + * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the + * length for indefinite length constructed form, we don't know the exact + * length but we can set an upper bound to the amount of data available minus + * the header length just read. + */ + +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + char *inf, char *cst, + const unsigned char **in, long len, + int exptag, int expclass, char opt, ASN1_TLC *ctx) +{ + int i; + int ptag, pclass; + long plen; + const unsigned char *p, *q; + p = *in; + q = p; + + if (ctx && ctx->valid) { + i = ctx->ret; + plen = ctx->plen; + pclass = ctx->pclass; + ptag = ctx->ptag; + p += ctx->hdrlen; + } else { + i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); + if (ctx) { + ctx->ret = i; + ctx->plen = plen; + ctx->pclass = pclass; + ctx->ptag = ptag; + ctx->hdrlen = p - q; + ctx->valid = 1; + /* + * If definite length, and no error, length + header can't exceed + * total amount of data available. + */ + if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { + ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); + asn1_tlc_clear(ctx); + return 0; + } + } + } + + if (i & 0x80) { + ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); + asn1_tlc_clear(ctx); + return 0; + } + if (exptag >= 0) { + if ((exptag != ptag) || (expclass != pclass)) { + /* + * If type is OPTIONAL, not an error: indicate missing type. + */ + if (opt) + return -1; + asn1_tlc_clear(ctx); + ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); + return 0; + } + /* + * We have a tag and class match: assume we are going to do something + * with it + */ + asn1_tlc_clear(ctx); + } + + if (i & 1) + plen = len - (p - q); + + if (inf) + *inf = i & 1; + + if (cst) + *cst = i & V_ASN1_CONSTRUCTED; + + if (olen) + *olen = plen; + + if (oclass) + *oclass = pclass; + + if (otag) + *otag = ptag; + + *in = p; + return 1; +} +/* tasn_enc.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "objects.h" + +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, + int skcontlen, const ASN1_ITEM *item, + int do_sort, int iclass); +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt, int tag, int aclass); +static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it, int flags); + +/* + * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use + * indefinite length constructed encoding, where appropriate + */ + +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it) +{ + return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); +} + +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) +{ + return asn1_item_flags_i2d(val, out, it, 0); +} + +/* + * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out' + * points to a buffer to output the data to. The new i2d has one additional + * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is + * allocated and populated with the encoding. + */ + +static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it, int flags) +{ + if (out && !*out) { + unsigned char *p, *buf; + int len; + len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); + if (len <= 0) + return len; + buf = OPENSSL_malloc(len); + if (!buf) + return -1; + p = buf; + ASN1_item_ex_i2d(&val, &p, it, -1, flags); + *out = buf; + return len; + } + + return ASN1_item_ex_i2d(&val, out, it, -1, flags); +} + +/* + * Encode an item, taking care of IMPLICIT tagging (if any). This function + * performs the normal item handling: it can be used in external types. + */ + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + const ASN1_TEMPLATE *tt = NULL; + unsigned char *p = NULL; + int i, seqcontlen, seqlen, ndef = 1; + const ASN1_COMPAT_FUNCS *cf; + const ASN1_EXTERN_FUNCS *ef; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = 0; + + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + return 0; + + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + + switch (it->itype) { + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) + return asn1_template_ex_i2d(pval, out, it->templates, + tag, aclass); + return asn1_i2d_ex_primitive(pval, out, it, tag, aclass); + break; + + case ASN1_ITYPE_MSTRING: + return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); + + case ASN1_ITYPE_CHOICE: + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) + return 0; + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + ASN1_VALUE **pchval; + const ASN1_TEMPLATE *chtt; + chtt = it->templates + i; + pchval = asn1_get_field_ptr(pval, chtt); + return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass); + } + /* Fixme: error condition if selector out of range */ + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) + return 0; + break; + + case ASN1_ITYPE_EXTERN: + /* If new style i2d it does all the work */ + ef = it->funcs; + return ef->asn1_ex_i2d(pval, out, it, tag, aclass); + + case ASN1_ITYPE_COMPAT: + /* old style hackery... */ + cf = it->funcs; + if (out) + p = *out; + i = cf->asn1_i2d(*pval, out); + /* + * Fixup for IMPLICIT tag: note this messes up for tags > 30, but so + * did the old code. Tags > 30 are very rare anyway. + */ + if (out && (tag != -1)) + *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED); + return i; + + case ASN1_ITYPE_NDEF_SEQUENCE: + /* Use indefinite length constructed if requested */ + if (aclass & ASN1_TFLG_NDEF) + ndef = 2; + /* fall through */ + + case ASN1_ITYPE_SEQUENCE: + i = asn1_enc_restore(&seqcontlen, out, pval, it); + /* An error occurred */ + if (i < 0) + return 0; + /* We have a valid cached encoding... */ + if (i > 0) + return seqcontlen; + /* Otherwise carry on */ + seqcontlen = 0; + /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ + if (tag == -1) { + tag = V_ASN1_SEQUENCE; + /* Retain any other flags in aclass */ + aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) + | V_ASN1_UNIVERSAL; + } + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) + return 0; + /* First work out sequence content length */ + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + int tmplen; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + return 0; + pseqval = asn1_get_field_ptr(pval, seqtt); + tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass); + if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) + return -1; + seqcontlen += tmplen; + } + + seqlen = ASN1_object_size(ndef, seqcontlen, tag); + if (!out || seqlen == -1) + return seqlen; + /* Output SEQUENCE header */ + ASN1_put_object(out, ndef, seqcontlen, tag, aclass); + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + return 0; + pseqval = asn1_get_field_ptr(pval, seqtt); + /* FIXME: check for errors in enhanced version */ + asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); + } + if (ndef == 2) + ASN1_put_eoc(out); + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) + return 0; + return seqlen; + + default: + return 0; + + } + return 0; +} + +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt) +{ + return asn1_template_ex_i2d(pval, out, tt, -1, 0); +} + +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt, int tag, int iclass) +{ + int i, ret, flags, ttag, tclass, ndef; + flags = tt->flags; + /* + * Work out tag and class to use: tagging may come either from the + * template or the arguments, not both because this would create + * ambiguity. Additionally the iclass argument may contain some + * additional flags which should be noted and passed down to other + * levels. + */ + if (flags & ASN1_TFLG_TAG_MASK) { + /* Error if argument and template tagging */ + if (tag != -1) + /* FIXME: error code here */ + return -1; + /* Get tagging from template */ + ttag = tt->tag; + tclass = flags & ASN1_TFLG_TAG_CLASS; + } else if (tag != -1) { + /* No template tagging, get from arguments */ + ttag = tag; + tclass = iclass & ASN1_TFLG_TAG_CLASS; + } else { + ttag = -1; + tclass = 0; + } + /* + * Remove any class mask from iflag. + */ + iclass &= ~ASN1_TFLG_TAG_CLASS; + + /* + * At this point 'ttag' contains the outer tag to use, 'tclass' is the + * class and iclass is any flags passed to this function. + */ + + /* if template and arguments require ndef, use it */ + if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF)) + ndef = 2; + else + ndef = 1; + + if (flags & ASN1_TFLG_SK_MASK) { + /* SET OF, SEQUENCE OF */ + STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + int isset, sktag, skaclass; + int skcontlen, sklen; + ASN1_VALUE *skitem; + + if (!*pval) + return 0; + + if (flags & ASN1_TFLG_SET_OF) { + isset = 1; + /* 2 means we reorder */ + if (flags & ASN1_TFLG_SEQUENCE_OF) + isset = 2; + } else + isset = 0; + + /* + * Work out inner tag value: if EXPLICIT or no tagging use underlying + * type. + */ + if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { + sktag = ttag; + skaclass = tclass; + } else { + skaclass = V_ASN1_UNIVERSAL; + if (isset) + sktag = V_ASN1_SET; + else + sktag = V_ASN1_SEQUENCE; + } + + /* Determine total length of items */ + skcontlen = 0; + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + int tmplen; + skitem = sk_ASN1_VALUE_value(sk, i); + tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), + -1, iclass); + if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) + return -1; + skcontlen += tmplen; + } + sklen = ASN1_object_size(ndef, skcontlen, sktag); + if (sklen == -1) + return -1; + /* If EXPLICIT need length of surrounding tag */ + if (flags & ASN1_TFLG_EXPTAG) + ret = ASN1_object_size(ndef, sklen, ttag); + else + ret = sklen; + + if (!out || ret == -1) + return ret; + + /* Now encode this lot... */ + /* EXPLICIT tag */ + if (flags & ASN1_TFLG_EXPTAG) + ASN1_put_object(out, ndef, sklen, ttag, tclass); + /* SET or SEQUENCE and IMPLICIT tag */ + ASN1_put_object(out, ndef, skcontlen, sktag, skaclass); + /* And the stuff itself */ + asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), + isset, iclass); + if (ndef == 2) { + ASN1_put_eoc(out); + if (flags & ASN1_TFLG_EXPTAG) + ASN1_put_eoc(out); + } + + return ret; + } + + if (flags & ASN1_TFLG_EXPTAG) { + /* EXPLICIT tagging */ + /* Find length of tagged item */ + i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass); + if (!i) + return 0; + /* Find length of EXPLICIT tag */ + ret = ASN1_object_size(ndef, i, ttag); + if (out && ret != -1) { + /* Output tag and item */ + ASN1_put_object(out, ndef, i, ttag, tclass); + ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass); + if (ndef == 2) + ASN1_put_eoc(out); + } + return ret; + } + + /* Either normal or IMPLICIT tagging: combine class and flags */ + return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), + ttag, tclass | iclass); + +} + +/* Temporary structure used to hold DER encoding of items for SET OF */ + +typedef struct { + unsigned char *data; + int length; + ASN1_VALUE *field; +} DER_ENC; + +static int der_cmp(const void *a, const void *b) +{ + const DER_ENC *d1 = a, *d2 = b; + int cmplen, i; + cmplen = (d1->length < d2->length) ? d1->length : d2->length; + i = memcmp(d1->data, d2->data, cmplen); + if (i) + return i; + return d1->length - d2->length; +} + +/* Output the content octets of SET OF or SEQUENCE OF */ + +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, + int skcontlen, const ASN1_ITEM *item, + int do_sort, int iclass) +{ + int i; + ASN1_VALUE *skitem; + unsigned char *tmpdat = NULL, *p = NULL; + DER_ENC *derlst = NULL, *tder; + if (do_sort) { + /* Don't need to sort less than 2 items */ + if (sk_ASN1_VALUE_num(sk) < 2) + do_sort = 0; + else { + derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) + * sizeof(*derlst)); + if (!derlst) + return 0; + tmpdat = OPENSSL_malloc(skcontlen); + if (!tmpdat) { + OPENSSL_free(derlst); + return 0; + } + } + } + /* If not sorting just output each item */ + if (!do_sort) { + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + skitem = sk_ASN1_VALUE_value(sk, i); + ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); + } + return 1; + } + p = tmpdat; + + /* Doing sort: build up a list of each member's DER encoding */ + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { + skitem = sk_ASN1_VALUE_value(sk, i); + tder->data = p; + tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); + tder->field = skitem; + } + + /* Now sort them */ + qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); + /* Output sorted DER encoding */ + p = *out; + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { + memcpy(p, tder->data, tder->length); + p += tder->length; + } + *out = p; + /* If do_sort is 2 then reorder the STACK */ + if (do_sort == 2) { + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) + (void)sk_ASN1_VALUE_set(sk, i, tder->field); + } + OPENSSL_free(derlst); + OPENSSL_free(tmpdat); + return 1; +} + +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + int len; + int utype; + int usetag; + int ndef = 0; + + utype = it->utype; + + /* + * Get length of content octets and maybe find out the underlying type. + */ + + len = asn1_ex_i2c(pval, NULL, &utype, it); + + /* + * If SEQUENCE, SET or OTHER then header is included in pseudo content + * octets so don't include tag+length. We need to check here because the + * call to asn1_ex_i2c() could change utype. + */ + if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || + (utype == V_ASN1_OTHER)) + usetag = 0; + else + usetag = 1; + + /* -1 means omit type */ + + if (len == -1) + return 0; + + /* -2 return is special meaning use ndef */ + if (len == -2) { + ndef = 2; + len = 0; + } + + /* If not implicitly tagged get tag from underlying type */ + if (tag == -1) + tag = utype; + + /* Output tag+length followed by content octets */ + if (out) { + if (usetag) + ASN1_put_object(out, ndef, len, tag, aclass); + asn1_ex_i2c(pval, *out, &utype, it); + if (ndef) + ASN1_put_eoc(out); + else + *out += len; + } + + if (usetag) + return ASN1_object_size(ndef, len, tag); + return len; +} + +/* Produce content octets from a structure */ + +int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, + const ASN1_ITEM *it) +{ + ASN1_BOOLEAN *tbool = NULL; + ASN1_STRING *strtmp; + ASN1_OBJECT *otmp; + int utype; + const unsigned char *cont; + unsigned char c; + int len; + const ASN1_PRIMITIVE_FUNCS *pf; + pf = it->funcs; + if (pf && pf->prim_i2c) + return pf->prim_i2c(pval, cout, putype, it); + + /* Should type be omitted? */ + if ((it->itype != ASN1_ITYPE_PRIMITIVE) + || (it->utype != V_ASN1_BOOLEAN)) { + if (!*pval) + return -1; + } + + if (it->itype == ASN1_ITYPE_MSTRING) { + /* If MSTRING type set the underlying type */ + strtmp = (ASN1_STRING *)*pval; + utype = strtmp->type; + *putype = utype; + } else if (it->utype == V_ASN1_ANY) { + /* If ANY set type and pointer to value */ + ASN1_TYPE *typ; + typ = (ASN1_TYPE *)*pval; + utype = typ->type; + *putype = utype; + pval = &typ->value.asn1_value; + } else + utype = *putype; + + switch (utype) { + case V_ASN1_OBJECT: + otmp = (ASN1_OBJECT *)*pval; + cont = otmp->data; + len = otmp->length; + if (cont == NULL || len == 0) + return -1; + break; + + case V_ASN1_NULL: + cont = NULL; + len = 0; + break; + + case V_ASN1_BOOLEAN: + tbool = (ASN1_BOOLEAN *)pval; + if (*tbool == -1) + return -1; + if (it->utype != V_ASN1_ANY) { + /* + * Default handling if value == size field then omit + */ + if (*tbool && (it->size > 0)) + return -1; + if (!*tbool && !it->size) + return -1; + } + c = (unsigned char)*tbool; + cont = &c; + len = 1; + break; + + case V_ASN1_BIT_STRING: + return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, + cout ? &cout : NULL); + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + /* + * These are all have the same content format as ASN1_INTEGER + */ + return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); + break; + + case V_ASN1_OCTET_STRING: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + default: + /* All based on ASN1_STRING and handled the same */ + strtmp = (ASN1_STRING *)*pval; + /* Special handling for NDEF */ + if ((it->size == ASN1_TFLG_NDEF) + && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) { + if (cout) { + strtmp->data = cout; + strtmp->length = 0; + } + /* Special return code */ + return -2; + } + cont = strtmp->data; + len = strtmp->length; + + break; + + } + if (cout && len) + memcpy(cout, cont, len); + return len; +} +/* tasn_fre.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "asn1.h" +// #include "asn1t.h" +// #include "objects.h" +#include "asn1_int.h" + +/* Free up an ASN1 structure */ + +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) +{ + asn1_item_combine_free(&val, it, 0); +} + +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + asn1_item_combine_free(pval, it, 0); +} + +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) +{ + const ASN1_TEMPLATE *tt = NULL, *seqtt; + const ASN1_EXTERN_FUNCS *ef; + const ASN1_COMPAT_FUNCS *cf; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + int i; + if (!pval) + return; + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + return; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + else + asn1_cb = 0; + + switch (it->itype) { + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) + ASN1_template_free(pval, it->templates); + else + ASN1_primitive_free(pval, it); + break; + + case ASN1_ITYPE_MSTRING: + ASN1_primitive_free(pval, it); + break; + + case ASN1_ITYPE_CHOICE: + if (asn1_cb) { + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); + if (i == 2) + return; + } + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + ASN1_VALUE **pchval; + tt = it->templates + i; + pchval = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchval, tt); + } + if (asn1_cb) + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); + if (!combine) { + OPENSSL_free(*pval); + *pval = NULL; + } + break; + + case ASN1_ITYPE_COMPAT: + cf = it->funcs; + if (cf && cf->asn1_free) + cf->asn1_free(*pval); + break; + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_free) + ef->asn1_ex_free(pval, it); + break; + + case ASN1_ITYPE_NDEF_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: + if (asn1_do_lock(pval, -1, it) > 0) + return; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); + if (i == 2) + return; + } + asn1_enc_free(pval, it); + /* + * If we free up as normal we will invalidate any ANY DEFINED BY + * field and we wont be able to determine the type of the field it + * defines. So free up in reverse order. + */ + tt = it->templates + it->tcount - 1; + for (i = 0; i < it->tcount; tt--, i++) { + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 0); + if (!seqtt) + continue; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } + if (asn1_cb) + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); + if (!combine) { + OPENSSL_free(*pval); + *pval = NULL; + } + break; + } +} + +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + int i; + if (tt->flags & ASN1_TFLG_SK_MASK) { + STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *vtmp; + vtmp = sk_ASN1_VALUE_value(sk, i); + asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0); + } + sk_ASN1_VALUE_free(sk); + *pval = NULL; + } else + asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), + tt->flags & ASN1_TFLG_COMBINE); +} + +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int utype; + if (it) { + const ASN1_PRIMITIVE_FUNCS *pf; + pf = it->funcs; + if (pf && pf->prim_free) { + pf->prim_free(pval, it); + return; + } + } + /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ + if (!it) { + ASN1_TYPE *typ = (ASN1_TYPE *)*pval; + utype = typ->type; + pval = &typ->value.asn1_value; + if (!*pval) + return; + } else if (it->itype == ASN1_ITYPE_MSTRING) { + utype = -1; + if (!*pval) + return; + } else { + utype = it->utype; + if ((utype != V_ASN1_BOOLEAN) && !*pval) + return; + } + + switch (utype) { + case V_ASN1_OBJECT: + ASN1_OBJECT_free((ASN1_OBJECT *)*pval); + break; + + case V_ASN1_BOOLEAN: + if (it) + *(ASN1_BOOLEAN *)pval = it->size; + else + *(ASN1_BOOLEAN *)pval = -1; + return; + + case V_ASN1_NULL: + break; + + case V_ASN1_ANY: + ASN1_primitive_free(pval, NULL); + OPENSSL_free(*pval); + break; + + default: + ASN1_STRING_free((ASN1_STRING *)*pval); + *pval = NULL; + break; + } + *pval = NULL; +} +/* tasn_new.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "asn1.h" +// #include "objects.h" +// #include "err.h" +// #include "asn1t.h" +#include +// #include "asn1_int.h" + +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); + +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) +{ + ASN1_VALUE *ret = NULL; + if (ASN1_item_ex_new(&ret, it) > 0) + return ret; + return NULL; +} + +/* Allocate an ASN1 structure */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + return asn1_item_ex_combine_new(pval, it, 0); +} + +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine) +{ + const ASN1_TEMPLATE *tt = NULL; + const ASN1_COMPAT_FUNCS *cf; + const ASN1_EXTERN_FUNCS *ef; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + ASN1_VALUE **pseqval; + int i; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + else + asn1_cb = 0; + +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_push_info(it->sname); +#endif + + switch (it->itype) { + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_new) { + if (!ef->asn1_ex_new(pval, it)) + goto memerr; + } + break; + + case ASN1_ITYPE_COMPAT: + cf = it->funcs; + if (cf && cf->asn1_new) { + *pval = cf->asn1_new(); + if (!*pval) + goto memerr; + } + break; + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + if (!ASN1_template_new(pval, it->templates)) + goto memerr; + } else if (!ASN1_primitive_new(pval, it)) + goto memerr; + break; + + case ASN1_ITYPE_MSTRING: + if (!ASN1_primitive_new(pval, it)) + goto memerr; + break; + + case ASN1_ITYPE_CHOICE: + if (asn1_cb) { + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); + if (!i) + goto auxerr; + if (i == 2) { +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 1; + } + } + if (!combine) { + *pval = OPENSSL_malloc(it->size); + if (!*pval) + goto memerr; + memset(*pval, 0, it->size); + } + asn1_set_choice_selector(pval, -1, it); + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) + goto auxerr2; + break; + + case ASN1_ITYPE_NDEF_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: + if (asn1_cb) { + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); + if (!i) + goto auxerr; + if (i == 2) { +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 1; + } + } + if (!combine) { + *pval = OPENSSL_malloc(it->size); + if (!*pval) + goto memerr; + memset(*pval, 0, it->size); + asn1_do_lock(pval, 0, it); + asn1_enc_init(pval, it); + } + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + pseqval = asn1_get_field_ptr(pval, tt); + if (!ASN1_template_new(pseqval, tt)) + goto memerr2; + } + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) + goto auxerr2; + break; + } +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 1; + + memerr2: + asn1_item_combine_free(pval, it, combine); + memerr: + ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 0; + + auxerr2: + asn1_item_combine_free(pval, it, combine); + auxerr: + ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 0; + +} + +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + const ASN1_EXTERN_FUNCS *ef; + + switch (it->itype) { + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_clear) + ef->asn1_ex_clear(pval, it); + else + *pval = NULL; + break; + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) + asn1_template_clear(pval, it->templates); + else + asn1_primitive_clear(pval, it); + break; + + case ASN1_ITYPE_MSTRING: + asn1_primitive_clear(pval, it); + break; + + case ASN1_ITYPE_COMPAT: + case ASN1_ITYPE_CHOICE: + case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_NDEF_SEQUENCE: + *pval = NULL; + break; + } +} + +int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); + int ret; + if (tt->flags & ASN1_TFLG_OPTIONAL) { + asn1_template_clear(pval, tt); + return 1; + } + /* If ANY DEFINED BY nothing to do */ + + if (tt->flags & ASN1_TFLG_ADB_MASK) { + *pval = NULL; + return 1; + } +#ifdef CRYPTO_MDEBUG + if (tt->field_name) + CRYPTO_push_info(tt->field_name); +#endif + /* If SET OF or SEQUENCE OF, its a STACK */ + if (tt->flags & ASN1_TFLG_SK_MASK) { + STACK_OF(ASN1_VALUE) *skval; + skval = sk_ASN1_VALUE_new_null(); + if (!skval) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); + ret = 0; + goto done; + } + *pval = (ASN1_VALUE *)skval; + ret = 1; + goto done; + } + /* Otherwise pass it back to the item routine */ + ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); + done: +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return ret; +} + +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + /* If ADB or STACK just NULL the field */ + if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) + *pval = NULL; + else + asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); +} + +/* + * NB: could probably combine most of the real XXX_new() behaviour and junk + * all the old functions. + */ + +int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + ASN1_TYPE *typ; + ASN1_STRING *str; + int utype; + + if (!it) + return 0; + + if (it->funcs) { + const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; + if (pf->prim_new) + return pf->prim_new(pval, it); + } + + if (it->itype == ASN1_ITYPE_MSTRING) + utype = -1; + else + utype = it->utype; + switch (utype) { + case V_ASN1_OBJECT: + *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); + return 1; + + case V_ASN1_BOOLEAN: + *(ASN1_BOOLEAN *)pval = it->size; + return 1; + + case V_ASN1_NULL: + *pval = (ASN1_VALUE *)1; + return 1; + + case V_ASN1_ANY: + typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); + if (!typ) + return 0; + typ->value.ptr = NULL; + typ->type = -1; + *pval = (ASN1_VALUE *)typ; + break; + + default: + str = ASN1_STRING_type_new(utype); + if (it->itype == ASN1_ITYPE_MSTRING && str) + str->flags |= ASN1_STRING_FLAG_MSTRING; + *pval = (ASN1_VALUE *)str; + break; + } + if (*pval) + return 1; + return 0; +} + +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int utype; + if (it && it->funcs) { + const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; + if (pf->prim_clear) + pf->prim_clear(pval, it); + else + *pval = NULL; + return; + } + if (!it || (it->itype == ASN1_ITYPE_MSTRING)) + utype = -1; + else + utype = it->utype; + if (utype == V_ASN1_BOOLEAN) + *(ASN1_BOOLEAN *)pval = it->size; + else + *pval = NULL; +} +/* tasn_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "objects.h" +// #include "buffer.h" +// #include "err.h" +#include "x509v3.h" +#include "asn1_locl.h" + +/* + * Print routines. + */ + +/* ASN1_PCTX routines */ + +ASN1_PCTX default_pctx = { + ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ + 0, /* nm_flags */ + 0, /* cert_flags */ + 0, /* oid_flags */ + 0 /* str_flags */ +}; + +ASN1_PCTX *ASN1_PCTX_new(void) +{ + ASN1_PCTX *ret; + ret = OPENSSL_malloc(sizeof(ASN1_PCTX)); + if (ret == NULL) { + ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->flags = 0; + ret->nm_flags = 0; + ret->cert_flags = 0; + ret->oid_flags = 0; + ret->str_flags = 0; + return ret; +} + +void ASN1_PCTX_free(ASN1_PCTX *p) +{ + OPENSSL_free(p); +} + +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p) +{ + return p->flags; +} + +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->flags = flags; +} + +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p) +{ + return p->nm_flags; +} + +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->nm_flags = flags; +} + +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p) +{ + return p->cert_flags; +} + +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->cert_flags = flags; +} + +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p) +{ + return p->oid_flags; +} + +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->oid_flags = flags; +} + +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p) +{ + return p->str_flags; +} + +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->str_flags = flags; +} + +/* Main print routines */ + +static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_ITEM *it, + const char *fname, const char *sname, + int nohdr, const ASN1_PCTX *pctx); + +int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); + +static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, + const ASN1_ITEM *it, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx); + +static int asn1_print_fsname(BIO *out, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx); + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx) +{ + const char *sname; + if (pctx == NULL) + pctx = &default_pctx; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) + sname = NULL; + else + sname = it->sname; + return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx); +} + +static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_ITEM *it, + const char *fname, const char *sname, + int nohdr, const ASN1_PCTX *pctx) +{ + const ASN1_TEMPLATE *tt; + const ASN1_EXTERN_FUNCS *ef; + ASN1_VALUE **tmpfld; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + ASN1_PRINT_ARG parg; + int i; + if (aux && aux->asn1_cb) { + parg.out = out; + parg.indent = indent; + parg.pctx = pctx; + asn1_cb = aux->asn1_cb; + } else + asn1_cb = 0; + + if (((it->itype != ASN1_ITYPE_PRIMITIVE) + || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) { + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + } + return 1; + } + + switch (it->itype) { + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + if (!asn1_template_print_ctx(out, fld, indent, + it->templates, pctx)) + return 0; + break; + } + /* fall thru */ + case ASN1_ITYPE_MSTRING: + if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx)) + return 0; + break; + + case ASN1_ITYPE_EXTERN: + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + /* Use new style print routine if possible */ + ef = it->funcs; + if (ef && ef->asn1_ex_print) { + i = ef->asn1_ex_print(out, fld, indent, "", pctx); + if (!i) + return 0; + if ((i == 2) && (BIO_puts(out, "\n") <= 0)) + return 0; + return 1; + } else if (sname && + BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0) + return 0; + break; + + case ASN1_ITYPE_CHOICE: +#if 0 + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; +#endif + /* CHOICE type, get selector */ + i = asn1_get_choice_selector(fld, it); + /* This should never happen... */ + if ((i < 0) || (i >= it->tcount)) { + if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0) + return 0; + return 1; + } + tt = it->templates + i; + tmpfld = asn1_get_field_ptr(fld, tt); + if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) + return 0; + break; + + case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_NDEF_SEQUENCE: + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + if (fname || sname) { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { + if (BIO_puts(out, " {\n") <= 0) + return 0; + } else { + if (BIO_puts(out, "\n") <= 0) + return 0; + } + } + + if (asn1_cb) { + i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg); + if (i == 0) + return 0; + if (i == 2) + return 1; + } + + /* Print each field entry */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + const ASN1_TEMPLATE *seqtt; + seqtt = asn1_do_adb(fld, tt, 1); + if (!seqtt) + return 0; + tmpfld = asn1_get_field_ptr(fld, seqtt); + if (!asn1_template_print_ctx(out, tmpfld, + indent + 2, seqtt, pctx)) + return 0; + } + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { + if (BIO_printf(out, "%*s}\n", indent, "") < 0) + return 0; + } + + if (asn1_cb) { + i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg); + if (i == 0) + return 0; + } + break; + + default: + BIO_printf(out, "Unprocessed type %d\n", it->itype); + return 0; + } + + return 1; +} + +int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) +{ + int i, flags; + const char *sname, *fname; + flags = tt->flags; + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME) + sname = ASN1_ITEM_ptr(tt->item)->sname; + else + sname = NULL; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) + fname = NULL; + else + fname = tt->field_name; + if (flags & ASN1_TFLG_SK_MASK) { + char *tname; + ASN1_VALUE *skitem; + STACK_OF(ASN1_VALUE) *stack; + + /* SET OF, SEQUENCE OF */ + if (fname) { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) { + if (flags & ASN1_TFLG_SET_OF) + tname = "SET"; + else + tname = "SEQUENCE"; + if (BIO_printf(out, "%*s%s OF %s {\n", + indent, "", tname, tt->field_name) <= 0) + return 0; + } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0) + return 0; + } + stack = (STACK_OF(ASN1_VALUE) *)*fld; + for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) { + if ((i > 0) && (BIO_puts(out, "\n") <= 0)) + return 0; + + skitem = sk_ASN1_VALUE_value(stack, i); + if (!asn1_item_print_ctx(out, &skitem, indent + 2, + ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, + pctx)) + return 0; + } + if (!i && BIO_printf(out, "%*s\n", indent + 2, "") <= 0) + return 0; + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { + if (BIO_printf(out, "%*s}\n", indent, "") <= 0) + return 0; + } + return 1; + } + return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item), + fname, sname, 0, pctx); +} + +static int asn1_print_fsname(BIO *out, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx) +{ + static char spaces[] = " "; + const int nspaces = sizeof(spaces) - 1; + +#if 0 + if (!sname && !fname) + return 1; +#endif + + while (indent > nspaces) { + if (BIO_write(out, spaces, nspaces) != nspaces) + return 0; + indent -= nspaces; + } + if (BIO_write(out, spaces, indent) != indent) + return 0; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) + sname = NULL; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) + fname = NULL; + if (!sname && !fname) + return 1; + if (fname) { + if (BIO_puts(out, fname) <= 0) + return 0; + } + if (sname) { + if (fname) { + if (BIO_printf(out, " (%s)", sname) <= 0) + return 0; + } else { + if (BIO_puts(out, sname) <= 0) + return 0; + } + } + if (BIO_write(out, ": ", 2) != 2) + return 0; + return 1; +} + +static int asn1_print_boolean_ctx(BIO *out, int boolval, + const ASN1_PCTX *pctx) +{ + const char *str; + switch (boolval) { + case -1: + str = "BOOL ABSENT"; + break; + + case 0: + str = "FALSE"; + break; + + default: + str = "TRUE"; + break; + + } + + if (BIO_puts(out, str) <= 0) + return 0; + return 1; + +} + +static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, + const ASN1_PCTX *pctx) +{ + char *s; + int ret = 1; + s = i2s_ASN1_INTEGER(NULL, str); + if (s == NULL) + return 0; + if (BIO_puts(out, s) <= 0) + ret = 0; + OPENSSL_free(s); + return ret; +} + +static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, + const ASN1_PCTX *pctx) +{ + char objbuf[80]; + const char *ln; + ln = OBJ_nid2ln(OBJ_obj2nid(oid)); + if (!ln) + ln = ""; + OBJ_obj2txt(objbuf, sizeof(objbuf), oid, 1); + if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) + return 0; + return 1; +} + +static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent, + const ASN1_PCTX *pctx) +{ + if (str->type == V_ASN1_BIT_STRING) { + if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0) + return 0; + } else if (BIO_puts(out, "\n") <= 0) + return 0; + if ((str->length > 0) + && BIO_dump_indent(out, (char *)str->data, str->length, + indent + 2) <= 0) + return 0; + return 1; +} + +static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, + const ASN1_ITEM *it, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx) +{ + long utype; + ASN1_STRING *str; + int ret = 1, needlf = 1; + const char *pname; + const ASN1_PRIMITIVE_FUNCS *pf; + pf = it->funcs; + if (!asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + if (pf && pf->prim_print) + return pf->prim_print(out, fld, it, indent, pctx); + if (it->itype == ASN1_ITYPE_MSTRING) { + str = (ASN1_STRING *)*fld; + utype = str->type & ~V_ASN1_NEG; + } else { + utype = it->utype; + if (utype == V_ASN1_BOOLEAN) + str = NULL; + else + str = (ASN1_STRING *)*fld; + } + if (utype == V_ASN1_ANY) { + ASN1_TYPE *atype = (ASN1_TYPE *)*fld; + utype = atype->type; + fld = &atype->value.asn1_value; + str = (ASN1_STRING *)*fld; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) + pname = NULL; + else + pname = ASN1_tag2str(utype); + } else { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE) + pname = ASN1_tag2str(utype); + else + pname = NULL; + } + + if (utype == V_ASN1_NULL) { + if (BIO_puts(out, "NULL\n") <= 0) + return 0; + return 1; + } + + if (pname) { + if (BIO_puts(out, pname) <= 0) + return 0; + if (BIO_puts(out, ":") <= 0) + return 0; + } + + switch (utype) { + case V_ASN1_BOOLEAN: + { + int boolval = *(int *)fld; + if (boolval == -1) + boolval = it->size; + ret = asn1_print_boolean_ctx(out, boolval, pctx); + } + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + ret = asn1_print_integer_ctx(out, str, pctx); + break; + + case V_ASN1_UTCTIME: + ret = ASN1_UTCTIME_print(out, str); + break; + + case V_ASN1_GENERALIZEDTIME: + ret = ASN1_GENERALIZEDTIME_print(out, str); + break; + + case V_ASN1_OBJECT: + ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx); + break; + + case V_ASN1_OCTET_STRING: + case V_ASN1_BIT_STRING: + ret = asn1_print_obstring_ctx(out, str, indent, pctx); + needlf = 0; + break; + + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_OTHER: + if (BIO_puts(out, "\n") <= 0) + return 0; + if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0) + ret = 0; + needlf = 0; + break; + + default: + ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); + + } + if (!ret) + return 0; + if (needlf && BIO_puts(out, "\n") <= 0) + return 0; + return 1; +} +/* tasn_typ.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +// #include "asn1.h" +// #include "asn1t.h" + +/* Declarations for string types */ + + +IMPLEMENT_ASN1_TYPE(ASN1_INTEGER) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER) + +IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_NULL) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL) + +IMPLEMENT_ASN1_TYPE(ASN1_OBJECT) + +IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_T61STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME) + +IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) + +IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_ANY) + +/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */ +IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE) + +IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +/* Multistring types */ + +IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE) +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT) +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) + +IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING) +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) + +/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */ +IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1) +IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1) +IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0) + +/* Special, OCTET STRING with indefinite length constructed support */ + +IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF) + +ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY) + +ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY) +/* tasn_utl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +// #include "asn1.h" +// #include "asn1t.h" +// #include "objects.h" +// #include "err.h" + +/* Utility functions for manipulating fields and offsets */ + +/* Add 'offset' to 'addr' */ +#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset) + +/* + * Given an ASN1_ITEM CHOICE type return the selector value + */ + +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int *sel = offset2ptr(*pval, it->utype); + return *sel; +} + +/* + * Given an ASN1_ITEM CHOICE type set the selector value, return old value. + */ + +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, + const ASN1_ITEM *it) +{ + int *sel, ret; + sel = offset2ptr(*pval, it->utype); + ret = *sel; + *sel = value; + return ret; +} + +/* + * Do reference counting. The value 'op' decides what to do. if it is +1 + * then the count is incremented. If op is 0 count is set to 1. If op is -1 + * count is decremented and the return value is the current refrence count or + * 0 if no reference count exists. + */ + +int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) +{ + const ASN1_AUX *aux; + int *lck, ret; + if ((it->itype != ASN1_ITYPE_SEQUENCE) + && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE)) + return 0; + aux = it->funcs; + if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) + return 0; + lck = offset2ptr(*pval, aux->ref_offset); + if (op == 0) { + *lck = 1; + return 1; + } + ret = CRYPTO_add(lck, op, aux->ref_lock); +#ifdef REF_PRINT + fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck); +#endif +#ifdef REF_CHECK + if (ret < 0) + fprintf(stderr, "%s, bad reference count\n", it->sname); +#endif + return ret; +} + +static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + const ASN1_AUX *aux; + if (!pval || !*pval) + return NULL; + aux = it->funcs; + if (!aux || !(aux->flags & ASN1_AFLG_ENCODING)) + return NULL; + return offset2ptr(*pval, aux->enc_offset); +} + +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (enc) { + enc->enc = NULL; + enc->len = 0; + enc->modified = 1; + } +} + +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (enc) { + if (enc->enc) + OPENSSL_free(enc->enc); + enc->enc = NULL; + enc->len = 0; + enc->modified = 1; + } +} + +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it) +{ + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (!enc) + return 1; + + if (enc->enc) + OPENSSL_free(enc->enc); + enc->enc = OPENSSL_malloc(inlen); + if (!enc->enc) + return 0; + memcpy(enc->enc, in, inlen); + enc->len = inlen; + enc->modified = 0; + + return 1; +} + +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, + const ASN1_ITEM *it) +{ + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (!enc || enc->modified) + return 0; + if (out) { + memcpy(*out, enc->enc, enc->len); + *out += enc->len; + } + if (len) + *len = enc->len; + return 1; +} + +/* Given an ASN1_TEMPLATE get a pointer to a field */ +ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + ASN1_VALUE **pvaltmp; + if (tt->flags & ASN1_TFLG_COMBINE) + return pval; + pvaltmp = offset2ptr(*pval, tt->offset); + /* + * NOTE for BOOLEAN types the field is just a plain int so we can't + * return int **, so settle for (int *). + */ + return pvaltmp; +} + +/* + * Handle ANY DEFINED BY template, find the selector, look up the relevant + * ASN1_TEMPLATE in the table and return it. + */ + +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + int nullerr) +{ + const ASN1_ADB *adb; + const ASN1_ADB_TABLE *atbl; + long selector; + ASN1_VALUE **sfld; + int i; + if (!(tt->flags & ASN1_TFLG_ADB_MASK)) + return tt; + + /* Else ANY DEFINED BY ... get the table */ + adb = ASN1_ADB_ptr(tt->item); + + /* Get the selector field */ + sfld = offset2ptr(*pval, adb->offset); + + /* Check if NULL */ + if (*sfld == NULL) { + if (!adb->null_tt) + goto err; + return adb->null_tt; + } + + /* + * Convert type to a long: NB: don't check for NID_undef here because it + * might be a legitimate value in the table + */ + if (tt->flags & ASN1_TFLG_ADB_OID) + selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); + else + selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld); + + /* + * Try to find matching entry in table Maybe should check application + * types first to allow application override? Might also be useful to + * have a flag which indicates table is sorted and we can do a binary + * search. For now stick to a linear search. + */ + + for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++) + if (atbl->value == selector) + return &atbl->tt; + + /* FIXME: need to search application table too */ + + /* No match, return default type */ + if (!adb->default_tt) + goto err; + return adb->default_tt; + + err: + /* FIXME: should log the value or OID of unsupported type */ + if (nullerr) + ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); + return NULL; +} diff --git a/Sources/COpenSSL/tb_asnmth.c b/Sources/COpenSSL/tb_asnmth.c new file mode 100644 index 00000000..865e0606 --- /dev/null +++ b/Sources/COpenSSL/tb_asnmth.c @@ -0,0 +1,246 @@ +/* ==================================================================== + * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" +#include "asn1_locl.h" +#include "evp.h" + +/* + * If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the + * function that is used by EVP to hook in pkey_asn1_meth code and cache + * defaults (etc), will display brief debugging summaries to stderr with the + * 'nid'. + */ +/* #define ENGINE_PKEY_ASN1_METH_DEBUG */ + +static ENGINE_TABLE *pkey_asn1_meth_table = NULL; + +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e) +{ + engine_table_unregister(&pkey_asn1_meth_table, e); +} + +static void engine_unregister_all_pkey_asn1_meths(void) +{ + engine_table_cleanup(&pkey_asn1_meth_table); +} + +int ENGINE_register_pkey_asn1_meths(ENGINE *e) +{ + if (e->pkey_asn1_meths) { + const int *nids; + int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&pkey_asn1_meth_table, + engine_unregister_all_pkey_asn1_meths, + e, nids, num_nids, 0); + } + return 1; +} + +void ENGINE_register_all_pkey_asn1_meths(void) +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_pkey_asn1_meths(e); +} + +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e) +{ + if (e->pkey_asn1_meths) { + const int *nids; + int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&pkey_asn1_meth_table, + engine_unregister_all_pkey_asn1_meths, + e, nids, num_nids, 1); + } + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given pkey_asn1_meth 'nid' + */ +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid) +{ + return engine_table_select(&pkey_asn1_meth_table, nid); +} + +/* + * Obtains a pkey_asn1_meth implementation from an ENGINE functional + * reference + */ +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid) +{ + EVP_PKEY_ASN1_METHOD *ret; + ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e); + if (!fn || !fn(e, &ret, NULL, nid)) { + ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, + ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); + return NULL; + } + return ret; +} + +/* Gets the pkey_asn1_meth callback from an ENGINE structure */ +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e) +{ + return e->pkey_asn1_meths; +} + +/* Sets the pkey_asn1_meth callback in an ENGINE structure */ +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f) +{ + e->pkey_asn1_meths = f; + return 1; +} + +/* + * Internal function to free up EVP_PKEY_ASN1_METHOD structures before an + * ENGINE is destroyed + */ + +void engine_pkey_asn1_meths_free(ENGINE *e) +{ + int i; + EVP_PKEY_ASN1_METHOD *pkm; + if (e->pkey_asn1_meths) { + const int *pknids; + int npknids; + npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0); + for (i = 0; i < npknids; i++) { + if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i])) { + EVP_PKEY_asn1_free(pkm); + } + } + } +} + +/* + * Find a method based on a string. This does a linear search through all + * implemented algorithms. This is OK in practice because only a small number + * of algorithms are likely to be implemented in an engine and it is not used + * for speed critical operations. + */ + +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, + int len) +{ + int i, nidcount; + const int *nids; + EVP_PKEY_ASN1_METHOD *ameth; + if (!e->pkey_asn1_meths) + return NULL; + if (len == -1) + len = strlen(str); + nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0); + for (i = 0; i < nidcount; i++) { + e->pkey_asn1_meths(e, &ameth, NULL, nids[i]); + if (((int)strlen(ameth->pem_str) == len) && + !strncasecmp(ameth->pem_str, str, len)) + return ameth; + } + return NULL; +} + +typedef struct { + ENGINE *e; + const EVP_PKEY_ASN1_METHOD *ameth; + const char *str; + int len; +} ENGINE_FIND_STR; + +static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg) +{ + ENGINE_FIND_STR *lk = arg; + int i; + if (lk->ameth) + return; + for (i = 0; i < sk_ENGINE_num(sk); i++) { + ENGINE *e = sk_ENGINE_value(sk, i); + EVP_PKEY_ASN1_METHOD *ameth; + e->pkey_asn1_meths(e, &ameth, NULL, nid); + if (ameth != NULL && ((int)strlen(ameth->pem_str) == lk->len) && + !strncasecmp(ameth->pem_str, lk->str, lk->len)) { + lk->e = e; + lk->ameth = ameth; + return; + } + } +} + +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, + int len) +{ + ENGINE_FIND_STR fstr; + fstr.e = NULL; + fstr.ameth = NULL; + fstr.str = str; + fstr.len = len; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr); + /* If found obtain a structural reference to engine */ + if (fstr.e) { + fstr.e->struct_ref++; + engine_ref_debug(fstr.e, 0, 1) + } + *pe = fstr.e; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return fstr.ameth; +} diff --git a/Sources/COpenSSL/tb_cipher.c b/Sources/COpenSSL/tb_cipher.c new file mode 100644 index 00000000..fcfb2efd --- /dev/null +++ b/Sources/COpenSSL/tb_cipher.c @@ -0,0 +1,143 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_cipher_engine(), the function + * that is used by EVP to hook in cipher code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_CIPHER_DEBUG */ + +static ENGINE_TABLE *cipher_table = NULL; + +void ENGINE_unregister_ciphers(ENGINE *e) +{ + engine_table_unregister(&cipher_table, e); +} + +static void engine_unregister_all_ciphers(void) +{ + engine_table_cleanup(&cipher_table); +} + +int ENGINE_register_ciphers(ENGINE *e) +{ + if (e->ciphers) { + const int *nids; + int num_nids = e->ciphers(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&cipher_table, + engine_unregister_all_ciphers, e, + nids, num_nids, 0); + } + return 1; +} + +void ENGINE_register_all_ciphers() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_ciphers(e); +} + +int ENGINE_set_default_ciphers(ENGINE *e) +{ + if (e->ciphers) { + const int *nids; + int num_nids = e->ciphers(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&cipher_table, + engine_unregister_all_ciphers, e, + nids, num_nids, 1); + } + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given cipher 'nid' + */ +ENGINE *ENGINE_get_cipher_engine(int nid) +{ + return engine_table_select(&cipher_table, nid); +} + +/* Obtains a cipher implementation from an ENGINE functional reference */ +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid) +{ + const EVP_CIPHER *ret; + ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e); + if (!fn || !fn(e, &ret, NULL, nid)) { + ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER, ENGINE_R_UNIMPLEMENTED_CIPHER); + return NULL; + } + return ret; +} + +/* Gets the cipher callback from an ENGINE structure */ +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e) +{ + return e->ciphers; +} + +/* Sets the cipher callback in an ENGINE structure */ +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f) +{ + e->ciphers = f; + return 1; +} diff --git a/Sources/COpenSSL/tb_dh.c b/Sources/COpenSSL/tb_dh.c new file mode 100644 index 00000000..8114afa6 --- /dev/null +++ b/Sources/COpenSSL/tb_dh.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_DH(), the function that + * is used by DH to hook in implementation code and cache defaults (etc), + * will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_DH_DEBUG */ + +static ENGINE_TABLE *dh_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_DH(ENGINE *e) +{ + engine_table_unregister(&dh_table, e); +} + +static void engine_unregister_all_DH(void) +{ + engine_table_cleanup(&dh_table); +} + +int ENGINE_register_DH(ENGINE *e) +{ + if (e->dh_meth) + return engine_table_register(&dh_table, + engine_unregister_all_DH, e, &dummy_nid, + 1, 0); + return 1; +} + +void ENGINE_register_all_DH() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_DH(e); +} + +int ENGINE_set_default_DH(ENGINE *e) +{ + if (e->dh_meth) + return engine_table_register(&dh_table, + engine_unregister_all_DH, e, &dummy_nid, + 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_DH(void) +{ + return engine_table_select(&dh_table, dummy_nid); +} + +/* Obtains an DH implementation from an ENGINE functional reference */ +const DH_METHOD *ENGINE_get_DH(const ENGINE *e) +{ + return e->dh_meth; +} + +/* Sets an DH implementation in an ENGINE structure */ +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth) +{ + e->dh_meth = dh_meth; + return 1; +} diff --git a/Sources/COpenSSL/tb_digest.c b/Sources/COpenSSL/tb_digest.c new file mode 100644 index 00000000..de1ad9c0 --- /dev/null +++ b/Sources/COpenSSL/tb_digest.c @@ -0,0 +1,143 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_digest_engine(), the function + * that is used by EVP to hook in digest code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_DIGEST_DEBUG */ + +static ENGINE_TABLE *digest_table = NULL; + +void ENGINE_unregister_digests(ENGINE *e) +{ + engine_table_unregister(&digest_table, e); +} + +static void engine_unregister_all_digests(void) +{ + engine_table_cleanup(&digest_table); +} + +int ENGINE_register_digests(ENGINE *e) +{ + if (e->digests) { + const int *nids; + int num_nids = e->digests(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&digest_table, + engine_unregister_all_digests, e, + nids, num_nids, 0); + } + return 1; +} + +void ENGINE_register_all_digests() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_digests(e); +} + +int ENGINE_set_default_digests(ENGINE *e) +{ + if (e->digests) { + const int *nids; + int num_nids = e->digests(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&digest_table, + engine_unregister_all_digests, e, + nids, num_nids, 1); + } + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given digest 'nid' + */ +ENGINE *ENGINE_get_digest_engine(int nid) +{ + return engine_table_select(&digest_table, nid); +} + +/* Obtains a digest implementation from an ENGINE functional reference */ +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid) +{ + const EVP_MD *ret; + ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e); + if (!fn || !fn(e, &ret, NULL, nid)) { + ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST, ENGINE_R_UNIMPLEMENTED_DIGEST); + return NULL; + } + return ret; +} + +/* Gets the digest callback from an ENGINE structure */ +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e) +{ + return e->digests; +} + +/* Sets the digest callback in an ENGINE structure */ +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f) +{ + e->digests = f; + return 1; +} diff --git a/Sources/COpenSSL/tb_dsa.c b/Sources/COpenSSL/tb_dsa.c new file mode 100644 index 00000000..c1f57f14 --- /dev/null +++ b/Sources/COpenSSL/tb_dsa.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_DSA(), the function that + * is used by DSA to hook in implementation code and cache defaults (etc), + * will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_DSA_DEBUG */ + +static ENGINE_TABLE *dsa_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_DSA(ENGINE *e) +{ + engine_table_unregister(&dsa_table, e); +} + +static void engine_unregister_all_DSA(void) +{ + engine_table_cleanup(&dsa_table); +} + +int ENGINE_register_DSA(ENGINE *e) +{ + if (e->dsa_meth) + return engine_table_register(&dsa_table, + engine_unregister_all_DSA, e, &dummy_nid, + 1, 0); + return 1; +} + +void ENGINE_register_all_DSA() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_DSA(e); +} + +int ENGINE_set_default_DSA(ENGINE *e) +{ + if (e->dsa_meth) + return engine_table_register(&dsa_table, + engine_unregister_all_DSA, e, &dummy_nid, + 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_DSA(void) +{ + return engine_table_select(&dsa_table, dummy_nid); +} + +/* Obtains an DSA implementation from an ENGINE functional reference */ +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e) +{ + return e->dsa_meth; +} + +/* Sets an DSA implementation in an ENGINE structure */ +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth) +{ + e->dsa_meth = dsa_meth; + return 1; +} diff --git a/Sources/COpenSSL/tb_ecdh.c b/Sources/COpenSSL/tb_ecdh.c new file mode 100644 index 00000000..c51441be --- /dev/null +++ b/Sources/COpenSSL/tb_ecdh.c @@ -0,0 +1,139 @@ +/* crypto/engine/tb_ecdh.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH engine software is originally written by Nils Gura and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_ECDH(), the function + * that is used by ECDH to hook in implementation code and cache defaults + * (etc), will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_ECDH_DEBUG */ + +static ENGINE_TABLE *ecdh_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_ECDH(ENGINE *e) +{ + engine_table_unregister(&ecdh_table, e); +} + +static void engine_unregister_all_ECDH(void) +{ + engine_table_cleanup(&ecdh_table); +} + +int ENGINE_register_ECDH(ENGINE *e) +{ + if (e->ecdh_meth) + return engine_table_register(&ecdh_table, + engine_unregister_all_ECDH, e, + &dummy_nid, 1, 0); + return 1; +} + +void ENGINE_register_all_ECDH() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_ECDH(e); +} + +int ENGINE_set_default_ECDH(ENGINE *e) +{ + if (e->ecdh_meth) + return engine_table_register(&ecdh_table, + engine_unregister_all_ECDH, e, + &dummy_nid, 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_ECDH(void) +{ + return engine_table_select(&ecdh_table, dummy_nid); +} + +/* Obtains an ECDH implementation from an ENGINE functional reference */ +const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e) +{ + return e->ecdh_meth; +} + +/* Sets an ECDH implementation in an ENGINE structure */ +int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth) +{ + e->ecdh_meth = ecdh_meth; + return 1; +} diff --git a/Sources/COpenSSL/tb_ecdsa.c b/Sources/COpenSSL/tb_ecdsa.c new file mode 100644 index 00000000..a8b9be60 --- /dev/null +++ b/Sources/COpenSSL/tb_ecdsa.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_ECDSA(), the function + * that is used by ECDSA to hook in implementation code and cache defaults + * (etc), will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_ECDSA_DEBUG */ + +static ENGINE_TABLE *ecdsa_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_ECDSA(ENGINE *e) +{ + engine_table_unregister(&ecdsa_table, e); +} + +static void engine_unregister_all_ECDSA(void) +{ + engine_table_cleanup(&ecdsa_table); +} + +int ENGINE_register_ECDSA(ENGINE *e) +{ + if (e->ecdsa_meth) + return engine_table_register(&ecdsa_table, + engine_unregister_all_ECDSA, e, + &dummy_nid, 1, 0); + return 1; +} + +void ENGINE_register_all_ECDSA() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_ECDSA(e); +} + +int ENGINE_set_default_ECDSA(ENGINE *e) +{ + if (e->ecdsa_meth) + return engine_table_register(&ecdsa_table, + engine_unregister_all_ECDSA, e, + &dummy_nid, 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_ECDSA(void) +{ + return engine_table_select(&ecdsa_table, dummy_nid); +} + +/* Obtains an ECDSA implementation from an ENGINE functional reference */ +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e) +{ + return e->ecdsa_meth; +} + +/* Sets an ECDSA implementation in an ENGINE structure */ +int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth) +{ + e->ecdsa_meth = ecdsa_meth; + return 1; +} diff --git a/Sources/COpenSSL/tb_pkmeth.c b/Sources/COpenSSL/tb_pkmeth.c new file mode 100644 index 00000000..1256573f --- /dev/null +++ b/Sources/COpenSSL/tb_pkmeth.c @@ -0,0 +1,166 @@ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" +#include "evp.h" + +/* + * If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function + * that is used by EVP to hook in pkey_meth code and cache defaults (etc), + * will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_PKEY_METH_DEBUG */ + +static ENGINE_TABLE *pkey_meth_table = NULL; + +void ENGINE_unregister_pkey_meths(ENGINE *e) +{ + engine_table_unregister(&pkey_meth_table, e); +} + +static void engine_unregister_all_pkey_meths(void) +{ + engine_table_cleanup(&pkey_meth_table); +} + +int ENGINE_register_pkey_meths(ENGINE *e) +{ + if (e->pkey_meths) { + const int *nids; + int num_nids = e->pkey_meths(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&pkey_meth_table, + engine_unregister_all_pkey_meths, e, + nids, num_nids, 0); + } + return 1; +} + +void ENGINE_register_all_pkey_meths() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_pkey_meths(e); +} + +int ENGINE_set_default_pkey_meths(ENGINE *e) +{ + if (e->pkey_meths) { + const int *nids; + int num_nids = e->pkey_meths(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&pkey_meth_table, + engine_unregister_all_pkey_meths, e, + nids, num_nids, 1); + } + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given pkey_meth 'nid' + */ +ENGINE *ENGINE_get_pkey_meth_engine(int nid) +{ + return engine_table_select(&pkey_meth_table, nid); +} + +/* Obtains a pkey_meth implementation from an ENGINE functional reference */ +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid) +{ + EVP_PKEY_METHOD *ret; + ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e); + if (!fn || !fn(e, &ret, NULL, nid)) { + ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH, + ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); + return NULL; + } + return ret; +} + +/* Gets the pkey_meth callback from an ENGINE structure */ +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e) +{ + return e->pkey_meths; +} + +/* Sets the pkey_meth callback in an ENGINE structure */ +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f) +{ + e->pkey_meths = f; + return 1; +} + +/* + * Internal function to free up EVP_PKEY_METHOD structures before an ENGINE + * is destroyed + */ + +void engine_pkey_meths_free(ENGINE *e) +{ + int i; + EVP_PKEY_METHOD *pkm; + if (e->pkey_meths) { + const int *pknids; + int npknids; + npknids = e->pkey_meths(e, NULL, &pknids, 0); + for (i = 0; i < npknids; i++) { + if (e->pkey_meths(e, &pkm, NULL, pknids[i])) { + EVP_PKEY_meth_free(pkm); + } + } + } +} diff --git a/Sources/COpenSSL/tb_rand.c b/Sources/COpenSSL/tb_rand.c new file mode 100644 index 00000000..a522264d --- /dev/null +++ b/Sources/COpenSSL/tb_rand.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_RAND(), the function + * that is used by RAND to hook in implementation code and cache defaults + * (etc), will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_RAND_DEBUG */ + +static ENGINE_TABLE *rand_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_RAND(ENGINE *e) +{ + engine_table_unregister(&rand_table, e); +} + +static void engine_unregister_all_RAND(void) +{ + engine_table_cleanup(&rand_table); +} + +int ENGINE_register_RAND(ENGINE *e) +{ + if (e->rand_meth) + return engine_table_register(&rand_table, + engine_unregister_all_RAND, e, + &dummy_nid, 1, 0); + return 1; +} + +void ENGINE_register_all_RAND() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_RAND(e); +} + +int ENGINE_set_default_RAND(ENGINE *e) +{ + if (e->rand_meth) + return engine_table_register(&rand_table, + engine_unregister_all_RAND, e, + &dummy_nid, 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_RAND(void) +{ + return engine_table_select(&rand_table, dummy_nid); +} + +/* Obtains an RAND implementation from an ENGINE functional reference */ +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e) +{ + return e->rand_meth; +} + +/* Sets an RAND implementation in an ENGINE structure */ +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth) +{ + e->rand_meth = rand_meth; + return 1; +} diff --git a/Sources/COpenSSL/tb_rsa.c b/Sources/COpenSSL/tb_rsa.c new file mode 100644 index 00000000..2790a821 --- /dev/null +++ b/Sources/COpenSSL/tb_rsa.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_RSA(), the function that + * is used by RSA to hook in implementation code and cache defaults (etc), + * will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_RSA_DEBUG */ + +static ENGINE_TABLE *rsa_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_RSA(ENGINE *e) +{ + engine_table_unregister(&rsa_table, e); +} + +static void engine_unregister_all_RSA(void) +{ + engine_table_cleanup(&rsa_table); +} + +int ENGINE_register_RSA(ENGINE *e) +{ + if (e->rsa_meth) + return engine_table_register(&rsa_table, + engine_unregister_all_RSA, e, &dummy_nid, + 1, 0); + return 1; +} + +void ENGINE_register_all_RSA() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_RSA(e); +} + +int ENGINE_set_default_RSA(ENGINE *e) +{ + if (e->rsa_meth) + return engine_table_register(&rsa_table, + engine_unregister_all_RSA, e, &dummy_nid, + 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_RSA(void) +{ + return engine_table_select(&rsa_table, dummy_nid); +} + +/* Obtains an RSA implementation from an ENGINE functional reference */ +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e) +{ + return e->rsa_meth; +} + +/* Sets an RSA implementation in an ENGINE structure */ +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth) +{ + e->rsa_meth = rsa_meth; + return 1; +} diff --git a/Sources/COpenSSL/tb_store.c b/Sources/COpenSSL/tb_store.c new file mode 100644 index 00000000..1eab49d7 --- /dev/null +++ b/Sources/COpenSSL/tb_store.c @@ -0,0 +1,129 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_STORE(), the function + * that is used by STORE to hook in implementation code and cache defaults + * (etc), will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_STORE_DEBUG */ + +static ENGINE_TABLE *store_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_STORE(ENGINE *e) +{ + engine_table_unregister(&store_table, e); +} + +static void engine_unregister_all_STORE(void) +{ + engine_table_cleanup(&store_table); +} + +int ENGINE_register_STORE(ENGINE *e) +{ + if (e->store_meth) + return engine_table_register(&store_table, + engine_unregister_all_STORE, e, + &dummy_nid, 1, 0); + return 1; +} + +void ENGINE_register_all_STORE() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_STORE(e); +} + +/* The following two functions are removed because they're useless. */ +#if 0 +int ENGINE_set_default_STORE(ENGINE *e) +{ + if (e->store_meth) + return engine_table_register(&store_table, + engine_unregister_all_STORE, e, + &dummy_nid, 1, 1); + return 1; +} +#endif + +#if 0 +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_STORE(void) +{ + return engine_table_select(&store_table, dummy_nid); +} +#endif + +/* Obtains an STORE implementation from an ENGINE functional reference */ +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e) +{ + return e->store_meth; +} + +/* Sets an STORE implementation in an ENGINE structure */ +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth) +{ + e->store_meth = store_meth; + return 1; +} diff --git a/Sources/COpenSSL/th-lock.c b/Sources/COpenSSL/th-lock.c new file mode 100644 index 00000000..1c6d8046 --- /dev/null +++ b/Sources/COpenSSL/th-lock.c @@ -0,0 +1,389 @@ +/* crypto/threads/th-lock.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#ifdef LINUX +# include +#endif +#ifdef OPENSSL_SYS_WIN32 +# include +#endif +#ifdef SOLARIS +# include +# include +#endif +#ifdef IRIX +# include +# include +#endif +#ifdef PTHREADS +# include +#endif +#include "lhash.h" +#include "crypto.h" +#include "buffer.h" +#include "e_os.h" +#include "x509.h" +#include "ssl.h" +#include "err.h" + +void CRYPTO_thread_setup(void); +void CRYPTO_thread_cleanup(void); + +static void irix_locking_callback(int mode, int type, char *file, int line); +static void solaris_locking_callback(int mode, int type, char *file, + int line); +static void win32_locking_callback(int mode, int type, char *file, int line); +static void pthreads_locking_callback(int mode, int type, char *file, + int line); + +static unsigned long irix_thread_id(void); +static unsigned long solaris_thread_id(void); +static unsigned long pthreads_thread_id(void); + +/*- + * usage: + * CRYPTO_thread_setup(); + * application code + * CRYPTO_thread_cleanup(); + */ + +#define THREAD_STACK_SIZE (16*1024) + +#ifdef OPENSSL_SYS_WIN32 + +static HANDLE *lock_cs; + +void CRYPTO_thread_setup(void) +{ + int i; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); + if (!lock_cs) { + /* Nothing we can do about this...void function! */ + return; + } + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_cs[i] = CreateMutex(NULL, FALSE, NULL); + } + + CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) + win32_locking_callback); + /* id callback defined */ + return (1); +} + +static void CRYPTO_thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) + CloseHandle(lock_cs[i]); + OPENSSL_free(lock_cs); +} + +void win32_locking_callback(int mode, int type, char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + WaitForSingleObject(lock_cs[type], INFINITE); + } else { + ReleaseMutex(lock_cs[type]); + } +} + +#endif /* OPENSSL_SYS_WIN32 */ + +#ifdef SOLARIS + +# define USE_MUTEX + +# ifdef USE_MUTEX +static mutex_t *lock_cs; +# else +static rwlock_t *lock_cs; +# endif +static long *lock_count; + +void CRYPTO_thread_setup(void) +{ + int i; + +# ifdef USE_MUTEX + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t)); +# else + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(rwlock_t)); +# endif + if (!lock_cs) { + /* Nothing we can do about this...void function! */ + return; + } + lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_count[i] = 0; +# ifdef USE_MUTEX + mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL); +# else + rwlock_init(&(lock_cs[i]), USYNC_THREAD, NULL); +# endif + } + + CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id); + CRYPTO_set_locking_callback((void (*)())solaris_locking_callback); +} + +void CRYPTO_thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { +# ifdef USE_MUTEX + mutex_destroy(&(lock_cs[i])); +# else + rwlock_destroy(&(lock_cs[i])); +# endif + } + OPENSSL_free(lock_cs); + OPENSSL_free(lock_count); +} + +void solaris_locking_callback(int mode, int type, char *file, int line) +{ +# if 0 + fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode & CRYPTO_LOCK) ? "l" : "u", + (type & CRYPTO_READ) ? "r" : "w", file, line); +# endif + +# if 0 + if (CRYPTO_LOCK_SSL_CERT == type) + fprintf(stderr, "(t,m,f,l) %ld %d %s %d\n", + CRYPTO_thread_id(), mode, file, line); +# endif + if (mode & CRYPTO_LOCK) { +# ifdef USE_MUTEX + mutex_lock(&(lock_cs[type])); +# else + if (mode & CRYPTO_READ) + rw_rdlock(&(lock_cs[type])); + else + rw_wrlock(&(lock_cs[type])); +# endif + lock_count[type]++; + } else { +# ifdef USE_MUTEX + mutex_unlock(&(lock_cs[type])); +# else + rw_unlock(&(lock_cs[type])); +# endif + } +} + +unsigned long solaris_thread_id(void) +{ + unsigned long ret; + + ret = (unsigned long)thr_self(); + return (ret); +} +#endif /* SOLARIS */ + +#ifdef IRIX +/* I don't think this works..... */ + +static usptr_t *arena; +static usema_t **lock_cs; + +void CRYPTO_thread_setup(void) +{ + int i; + char filename[20]; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *)); + if (!lock_cs) { + /* Nothing we can do about this...void function! */ + return; + } + + strcpy(filename, "/tmp/mttest.XXXXXX"); + mktemp(filename); + + usconfig(CONF_STHREADIOOFF); + usconfig(CONF_STHREADMALLOCOFF); + usconfig(CONF_INITUSERS, 100); + usconfig(CONF_LOCKTYPE, US_DEBUGPLUS); + arena = usinit(filename); + unlink(filename); + + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_cs[i] = usnewsema(arena, 1); + } + + CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id); + CRYPTO_set_locking_callback((void (*)())irix_locking_callback); +} + +void CRYPTO_thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { + char buf[10]; + + sprintf(buf, "%2d:", i); + usdumpsema(lock_cs[i], stdout, buf); + usfreesema(lock_cs[i], arena); + } + OPENSSL_free(lock_cs); +} + +void irix_locking_callback(int mode, int type, char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + uspsema(lock_cs[type]); + } else { + usvsema(lock_cs[type]); + } +} + +unsigned long irix_thread_id(void) +{ + unsigned long ret; + + ret = (unsigned long)getpid(); + return (ret); +} +#endif /* IRIX */ + +/* Linux and a few others */ +#ifdef PTHREADS + +static pthread_mutex_t *lock_cs; +static long *lock_count; + +void CRYPTO_thread_setup(void) +{ + int i; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); + if (!lock_cs || !lock_count) { + /* Nothing we can do about this...void function! */ + if (lock_cs) + OPENSSL_free(lock_cs); + if (lock_count) + OPENSSL_free(lock_count); + return; + } + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_count[i] = 0; + pthread_mutex_init(&(lock_cs[i]), NULL); + } + + CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); + CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); +} + +void thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_destroy(&(lock_cs[i])); + } + OPENSSL_free(lock_cs); + OPENSSL_free(lock_count); +} + +void pthreads_locking_callback(int mode, int type, char *file, int line) +{ +# if 0 + fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode & CRYPTO_LOCK) ? "l" : "u", + (type & CRYPTO_READ) ? "r" : "w", file, line); +# endif +# if 0 + if (CRYPTO_LOCK_SSL_CERT == type) + fprintf(stderr, "(t,m,f,l) %ld %d %s %d\n", + CRYPTO_thread_id(), mode, file, line); +# endif + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&(lock_cs[type])); + lock_count[type]++; + } else { + pthread_mutex_unlock(&(lock_cs[type])); + } +} + +unsigned long pthreads_thread_id(void) +{ + unsigned long ret; + + ret = (unsigned long)pthread_self(); + return (ret); +} + +#endif /* PTHREADS */ diff --git a/Sources/COpenSSL/tls1.h b/Sources/COpenSSL/tls1.h new file mode 100644 index 00000000..8295c82c --- /dev/null +++ b/Sources/COpenSSL/tls1.h @@ -0,0 +1,810 @@ +/* ssl/tls1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_TLS1_H +# define HEADER_TLS1_H + +# include "buffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 + +# define TLS1_VERSION 0x0301 +# define TLS1_1_VERSION 0x0302 +# define TLS1_2_VERSION 0x0303 +# define TLS_MAX_VERSION TLS1_2_VERSION + +# define TLS1_VERSION_MAJOR 0x03 +# define TLS1_VERSION_MINOR 0x01 + +# define TLS1_1_VERSION_MAJOR 0x03 +# define TLS1_1_VERSION_MINOR 0x02 + +# define TLS1_2_VERSION_MAJOR 0x03 +# define TLS1_2_VERSION_MINOR 0x03 + +# define TLS1_get_version(s) \ + ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0) + +# define TLS1_get_client_version(s) \ + ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0) + +# define TLS1_AD_DECRYPTION_FAILED 21 +# define TLS1_AD_RECORD_OVERFLOW 22 +# define TLS1_AD_UNKNOWN_CA 48/* fatal */ +# define TLS1_AD_ACCESS_DENIED 49/* fatal */ +# define TLS1_AD_DECODE_ERROR 50/* fatal */ +# define TLS1_AD_DECRYPT_ERROR 51 +# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ +# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ +# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ +# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ +# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ +# define TLS1_AD_USER_CANCELLED 90 +# define TLS1_AD_NO_RENEGOTIATION 100 +/* codes 110-114 are from RFC3546 */ +# define TLS1_AD_UNSUPPORTED_EXTENSION 110 +# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +# define TLS1_AD_UNRECOGNIZED_NAME 112 +# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ + +/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ +# define TLSEXT_TYPE_server_name 0 +# define TLSEXT_TYPE_max_fragment_length 1 +# define TLSEXT_TYPE_client_certificate_url 2 +# define TLSEXT_TYPE_trusted_ca_keys 3 +# define TLSEXT_TYPE_truncated_hmac 4 +# define TLSEXT_TYPE_status_request 5 +/* ExtensionType values from RFC4681 */ +# define TLSEXT_TYPE_user_mapping 6 +/* ExtensionType values from RFC5878 */ +# define TLSEXT_TYPE_client_authz 7 +# define TLSEXT_TYPE_server_authz 8 +/* ExtensionType values from RFC6091 */ +# define TLSEXT_TYPE_cert_type 9 + +/* ExtensionType values from RFC4492 */ +# define TLSEXT_TYPE_elliptic_curves 10 +# define TLSEXT_TYPE_ec_point_formats 11 + +/* ExtensionType value from RFC5054 */ +# define TLSEXT_TYPE_srp 12 + +/* ExtensionType values from RFC5246 */ +# define TLSEXT_TYPE_signature_algorithms 13 + +/* ExtensionType value from RFC5764 */ +# define TLSEXT_TYPE_use_srtp 14 + +/* ExtensionType value from RFC5620 */ +# define TLSEXT_TYPE_heartbeat 15 + +/* ExtensionType value from RFC7301 */ +# define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +/* + * ExtensionType value for TLS padding extension. + * http://tools.ietf.org/html/draft-agl-tls-padding + */ +# define TLSEXT_TYPE_padding 21 + +/* ExtensionType value from RFC4507 */ +# define TLSEXT_TYPE_session_ticket 35 + +/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */ +# if 0 +/* + * will have to be provided externally for now , + * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183 + * using whatever extension number you'd like to try + */ +# define TLSEXT_TYPE_opaque_prf_input ?? +# endif + +/* Temporary extension type */ +# define TLSEXT_TYPE_renegotiate 0xff01 + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* This is not an IANA defined extension number */ +# define TLSEXT_TYPE_next_proto_neg 13172 +# endif + +/* NameType value from RFC3546 */ +# define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC3546 */ +# define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from RFC4492 */ +# define TLSEXT_ECPOINTFORMAT_first 0 +# define TLSEXT_ECPOINTFORMAT_uncompressed 0 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +# define TLSEXT_ECPOINTFORMAT_last 2 + +/* Signature and hash algorithms from RFC5246 */ +# define TLSEXT_signature_anonymous 0 +# define TLSEXT_signature_rsa 1 +# define TLSEXT_signature_dsa 2 +# define TLSEXT_signature_ecdsa 3 + +/* Total number of different signature algorithms */ +# define TLSEXT_signature_num 4 + +# define TLSEXT_hash_none 0 +# define TLSEXT_hash_md5 1 +# define TLSEXT_hash_sha1 2 +# define TLSEXT_hash_sha224 3 +# define TLSEXT_hash_sha256 4 +# define TLSEXT_hash_sha384 5 +# define TLSEXT_hash_sha512 6 + +/* Total number of different digest algorithms */ + +# define TLSEXT_hash_num 7 + +/* Flag set for unrecognised algorithms */ +# define TLSEXT_nid_unknown 0x1000000 + +/* ECC curves */ + +# define TLSEXT_curve_P_256 23 +# define TLSEXT_curve_P_384 24 + +# ifndef OPENSSL_NO_TLSEXT + +# define TLSEXT_MAXLEN_host_name 255 + +const char *SSL_get_servername(const SSL *s, const int type); +int SSL_get_servername_type(const SSL *s); +/* + * SSL_export_keying_material exports a value derived from the master secret, + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and + * optional context. (Since a zero length context is allowed, the |use_context| + * flag controls whether a context is included.) It returns 1 on success and + * zero otherwise. + */ +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, size_t contextlen, + int use_context); + +int SSL_get_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +int SSL_get_shared_sigalgs(SSL *s, int idx, + int *psign, int *phash, int *psignandhash, + unsigned char *rsig, unsigned char *rhash); + +int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain); + +# define SSL_set_tlsext_host_name(s,name) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) + +# define SSL_set_tlsext_debug_callback(ssl, cb) \ +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb) + +# define SSL_set_tlsext_debug_arg(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg) + +# define SSL_set_tlsext_status_type(ssl, type) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL) + +# define SSL_get_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +# define SSL_set_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +# define SSL_get_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +# define SSL_set_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +# define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg) + +# define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg) + +# define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) + +# define SSL_TLSEXT_ERR_OK 0 +# define SSL_TLSEXT_ERR_ALERT_WARNING 1 +# define SSL_TLSEXT_ERR_ALERT_FATAL 2 +# define SSL_TLSEXT_ERR_NOACK 3 + +# define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) + +# define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys)) +# define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys)) + +# define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) + +# define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ +SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg) + +# define SSL_set_tlsext_opaque_prf_input(s, src, len) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src) +# define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb) +# define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg) + +# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_TLSEXT_HB_ENABLED 0x01 +# define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02 +# define SSL_TLSEXT_HB_DONT_RECV_REQUESTS 0x04 + +# define SSL_get_tlsext_heartbeat_pending(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL) +# define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \ + SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL) +# endif +# endif + +/* PSK ciphersuites from 4279 */ +# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D + +/* + * Additional TLS ciphersuites from expired Internet Draft + * draft-ietf-tls-56-bit-ciphersuites-01.txt (available if + * TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see s3_lib.c). We + * actually treat them like SSL 3.0 ciphers, which we probably shouldn't. + * Note that the first two are actually not in the IDs. + */ +# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060/* not in + * ID */ +# define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061/* not in + * ID */ +# define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 +# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 +# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 +# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x03000065 +# define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066 + +/* AES ciphersuites from RFC3268 */ +# define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +# define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 + +# define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +# define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +# define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +# define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +# define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +# define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +# define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +# define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +# define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +# define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +# define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +/* + * ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in + * draft 13 + */ +# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +# define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* SRP ciphersuites from RFC 5054 */ +# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +/* ECDH HMAC based ciphersuites from RFC5289 */ + +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +/* + * XXX * Backward compatibility alert: + * Older versions of OpenSSL gave + * some DHE ciphers names with "EDH" + * instead of "DHE". Going forward, we + * should be using DHE + * everywhere, though we may indefinitely maintain + * aliases for users + * or configurations that used "EDH" + + */ +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5" +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5" +# define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DES-CBC-SHA" +# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DHE-DSS-DES-CBC-SHA" +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA "EXP1024-RC4-SHA" +# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA "EXP1024-DHE-DSS-RC4-SHA" +# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +/* AES ciphersuites from RFC3268 */ +# define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +# define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +# define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +# define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279 */ +# define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +/* SRP ciphersuite from RFC 5054 */ +# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +# define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +# define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +# define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +/* TLS v1.2 ciphersuites */ +# define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +# define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +# define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +/* ECDH HMAC based ciphersuites from RFC5289 */ + +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +# define TLS_CT_RSA_SIGN 1 +# define TLS_CT_DSS_SIGN 2 +# define TLS_CT_RSA_FIXED_DH 3 +# define TLS_CT_DSS_FIXED_DH 4 +# define TLS_CT_ECDSA_SIGN 64 +# define TLS_CT_RSA_FIXED_ECDH 65 +# define TLS_CT_ECDSA_FIXED_ECDH 66 +# define TLS_CT_GOST94_SIGN 21 +# define TLS_CT_GOST01_SIGN 22 +/* + * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) + */ +# define TLS_CT_NUMBER 9 + +# define TLS1_FINISH_MAC_LENGTH 12 + +# define TLS_MD_MAX_CONST_SIZE 20 +# define TLS_MD_CLIENT_FINISH_CONST "client finished" +# define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_FINISH_CONST "server finished" +# define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_KEY_EXPANSION_CONST "key expansion" +# define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +# define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_IV_BLOCK_CONST "IV block" +# define TLS_MD_IV_BLOCK_CONST_SIZE 8 +# define TLS_MD_MASTER_SECRET_CONST "master secret" +# define TLS_MD_MASTER_SECRET_CONST_SIZE 13 + +# ifdef CHARSET_EBCDIC +# undef TLS_MD_CLIENT_FINISH_CONST +/* + * client finished + */ +# define TLS_MD_CLIENT_FINISH_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_FINISH_CONST +/* + * server finished + */ +# define TLS_MD_SERVER_FINISH_CONST "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_KEY_EXPANSION_CONST +/* + * key expansion + */ +# define TLS_MD_KEY_EXPANSION_CONST "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e" + +# undef TLS_MD_CLIENT_WRITE_KEY_CONST +/* + * client write key + */ +# define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_IV_BLOCK_CONST +/* + * IV block + */ +# define TLS_MD_IV_BLOCK_CONST "\x49\x56\x20\x62\x6c\x6f\x63\x6b" + +# undef TLS_MD_MASTER_SECRET_CONST +/* + * master secret + */ +# define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# endif + +/* TLS Session Ticket extension struct */ +struct tls_session_ticket_ext_st { + unsigned short length; + void *data; +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/tls_srp.c b/Sources/COpenSSL/tls_srp.c new file mode 100644 index 00000000..b7471194 --- /dev/null +++ b/Sources/COpenSSL/tls_srp.c @@ -0,0 +1,542 @@ +/* ssl/tls_srp.c */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SRP + +# include "rand.h" +# include "srp.h" +# include "err.h" + +int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) +{ + if (ctx == NULL) + return 0; + OPENSSL_free(ctx->srp_ctx.login); + BN_free(ctx->srp_ctx.N); + BN_free(ctx->srp_ctx.g); + BN_free(ctx->srp_ctx.s); + BN_free(ctx->srp_ctx.B); + BN_free(ctx->srp_ctx.A); + BN_free(ctx->srp_ctx.a); + BN_free(ctx->srp_ctx.b); + BN_free(ctx->srp_ctx.v); + ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; + ctx->srp_ctx.SRP_cb_arg = NULL; + ctx->srp_ctx.SRP_verify_param_callback = NULL; + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + ctx->srp_ctx.N = NULL; + ctx->srp_ctx.g = NULL; + ctx->srp_ctx.s = NULL; + ctx->srp_ctx.B = NULL; + ctx->srp_ctx.A = NULL; + ctx->srp_ctx.a = NULL; + ctx->srp_ctx.b = NULL; + ctx->srp_ctx.v = NULL; + ctx->srp_ctx.login = NULL; + ctx->srp_ctx.info = NULL; + ctx->srp_ctx.strength = SRP_MINIMAL_N; + ctx->srp_ctx.srp_Mask = 0; + return (1); +} + +int SSL_SRP_CTX_free(struct ssl_st *s) +{ + if (s == NULL) + return 0; + OPENSSL_free(s->srp_ctx.login); + BN_free(s->srp_ctx.N); + BN_free(s->srp_ctx.g); + BN_free(s->srp_ctx.s); + BN_free(s->srp_ctx.B); + BN_free(s->srp_ctx.A); + BN_free(s->srp_ctx.a); + BN_free(s->srp_ctx.b); + BN_free(s->srp_ctx.v); + s->srp_ctx.TLS_ext_srp_username_callback = NULL; + s->srp_ctx.SRP_cb_arg = NULL; + s->srp_ctx.SRP_verify_param_callback = NULL; + s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + s->srp_ctx.N = NULL; + s->srp_ctx.g = NULL; + s->srp_ctx.s = NULL; + s->srp_ctx.B = NULL; + s->srp_ctx.A = NULL; + s->srp_ctx.a = NULL; + s->srp_ctx.b = NULL; + s->srp_ctx.v = NULL; + s->srp_ctx.login = NULL; + s->srp_ctx.info = NULL; + s->srp_ctx.strength = SRP_MINIMAL_N; + s->srp_ctx.srp_Mask = 0; + return (1); +} + +int SSL_SRP_CTX_init(struct ssl_st *s) +{ + SSL_CTX *ctx; + + if ((s == NULL) || ((ctx = s->ctx) == NULL)) + return 0; + s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg; + /* set client Hello login callback */ + s->srp_ctx.TLS_ext_srp_username_callback = + ctx->srp_ctx.TLS_ext_srp_username_callback; + /* set SRP N/g param callback for verification */ + s->srp_ctx.SRP_verify_param_callback = + ctx->srp_ctx.SRP_verify_param_callback; + /* set SRP client passwd callback */ + s->srp_ctx.SRP_give_srp_client_pwd_callback = + ctx->srp_ctx.SRP_give_srp_client_pwd_callback; + + s->srp_ctx.N = NULL; + s->srp_ctx.g = NULL; + s->srp_ctx.s = NULL; + s->srp_ctx.B = NULL; + s->srp_ctx.A = NULL; + s->srp_ctx.a = NULL; + s->srp_ctx.b = NULL; + s->srp_ctx.v = NULL; + s->srp_ctx.login = NULL; + s->srp_ctx.info = ctx->srp_ctx.info; + s->srp_ctx.strength = ctx->srp_ctx.strength; + + if (((ctx->srp_ctx.N != NULL) && + ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) || + ((ctx->srp_ctx.g != NULL) && + ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) || + ((ctx->srp_ctx.s != NULL) && + ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) || + ((ctx->srp_ctx.B != NULL) && + ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) || + ((ctx->srp_ctx.A != NULL) && + ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) || + ((ctx->srp_ctx.a != NULL) && + ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) || + ((ctx->srp_ctx.v != NULL) && + ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || + ((ctx->srp_ctx.b != NULL) && + ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) { + SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB); + goto err; + } + if ((ctx->srp_ctx.login != NULL) && + ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL)) { + SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR); + goto err; + } + s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; + + return (1); + err: + OPENSSL_free(s->srp_ctx.login); + BN_free(s->srp_ctx.N); + BN_free(s->srp_ctx.g); + BN_free(s->srp_ctx.s); + BN_free(s->srp_ctx.B); + BN_free(s->srp_ctx.A); + BN_free(s->srp_ctx.a); + BN_free(s->srp_ctx.b); + BN_free(s->srp_ctx.v); + return (0); +} + +int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) +{ + if (ctx == NULL) + return 0; + + ctx->srp_ctx.SRP_cb_arg = NULL; + /* set client Hello login callback */ + ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; + /* set SRP N/g param callback for verification */ + ctx->srp_ctx.SRP_verify_param_callback = NULL; + /* set SRP client passwd callback */ + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + + ctx->srp_ctx.N = NULL; + ctx->srp_ctx.g = NULL; + ctx->srp_ctx.s = NULL; + ctx->srp_ctx.B = NULL; + ctx->srp_ctx.A = NULL; + ctx->srp_ctx.a = NULL; + ctx->srp_ctx.b = NULL; + ctx->srp_ctx.v = NULL; + ctx->srp_ctx.login = NULL; + ctx->srp_ctx.srp_Mask = 0; + ctx->srp_ctx.info = NULL; + ctx->srp_ctx.strength = SRP_MINIMAL_N; + + return (1); +} + +/* server side */ +int SSL_srp_server_param_with_username(SSL *s, int *ad) +{ + unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; + int al; + + *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; + if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && + ((al = + s->srp_ctx.TLS_ext_srp_username_callback(s, ad, + s->srp_ctx.SRP_cb_arg)) != + SSL_ERROR_NONE)) + return al; + + *ad = SSL_AD_INTERNAL_ERROR; + if ((s->srp_ctx.N == NULL) || + (s->srp_ctx.g == NULL) || + (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) + return SSL3_AL_FATAL; + + if (RAND_bytes(b, sizeof(b)) <= 0) + return SSL3_AL_FATAL; + s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); + OPENSSL_cleanse(b, sizeof(b)); + + /* Calculate: B = (kv + g^b) % N */ + + return ((s->srp_ctx.B = + SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, + s->srp_ctx.v)) != + NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL; +} + +/* + * If the server just has the raw password, make up a verifier entry on the + * fly + */ +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp) +{ + SRP_gN *GN = SRP_get_default_gN(grp); + if (GN == NULL) + return -1; + s->srp_ctx.N = BN_dup(GN->N); + s->srp_ctx.g = BN_dup(GN->g); + if (s->srp_ctx.v != NULL) { + BN_clear_free(s->srp_ctx.v); + s->srp_ctx.v = NULL; + } + if (s->srp_ctx.s != NULL) { + BN_clear_free(s->srp_ctx.s); + s->srp_ctx.s = NULL; + } + if (!SRP_create_verifier_BN + (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) + return -1; + + return 1; +} + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info) +{ + if (N != NULL) { + if (s->srp_ctx.N != NULL) { + if (!BN_copy(s->srp_ctx.N, N)) { + BN_free(s->srp_ctx.N); + s->srp_ctx.N = NULL; + } + } else + s->srp_ctx.N = BN_dup(N); + } + if (g != NULL) { + if (s->srp_ctx.g != NULL) { + if (!BN_copy(s->srp_ctx.g, g)) { + BN_free(s->srp_ctx.g); + s->srp_ctx.g = NULL; + } + } else + s->srp_ctx.g = BN_dup(g); + } + if (sa != NULL) { + if (s->srp_ctx.s != NULL) { + if (!BN_copy(s->srp_ctx.s, sa)) { + BN_free(s->srp_ctx.s); + s->srp_ctx.s = NULL; + } + } else + s->srp_ctx.s = BN_dup(sa); + } + if (v != NULL) { + if (s->srp_ctx.v != NULL) { + if (!BN_copy(s->srp_ctx.v, v)) { + BN_free(s->srp_ctx.v); + s->srp_ctx.v = NULL; + } + } else + s->srp_ctx.v = BN_dup(v); + } + s->srp_ctx.info = info; + + if (!(s->srp_ctx.N) || + !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v)) + return -1; + + return 1; +} + +int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key) +{ + BIGNUM *K = NULL, *u = NULL; + int ret = -1, tmp_len; + unsigned char *tmp = NULL; + + if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) + goto err; + if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) + goto err; + if (! + (K = + SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, + s->srp_ctx.N))) + goto err; + + tmp_len = BN_num_bytes(K); + if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) + goto err; + BN_bn2bin(K, tmp); + ret = + s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, + tmp_len); + err: + if (tmp) { + OPENSSL_cleanse(tmp, tmp_len); + OPENSSL_free(tmp); + } + BN_clear_free(K); + BN_clear_free(u); + return ret; +} + +/* client side */ +int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key) +{ + BIGNUM *x = NULL, *u = NULL, *K = NULL; + int ret = -1, tmp_len; + char *passwd = NULL; + unsigned char *tmp = NULL; + + /* + * Checks if b % n == 0 + */ + if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0) + goto err; + if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) + goto err; + if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) + goto err; + if (! + (passwd = + s->srp_ctx.SRP_give_srp_client_pwd_callback(s, + s->srp_ctx.SRP_cb_arg))) + goto err; + if (!(x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd))) + goto err; + if (! + (K = + SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, + s->srp_ctx.a, u))) + goto err; + + tmp_len = BN_num_bytes(K); + if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) + goto err; + BN_bn2bin(K, tmp); + ret = + s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, + tmp_len); + err: + if (tmp) { + OPENSSL_cleanse(tmp, tmp_len); + OPENSSL_free(tmp); + } + BN_clear_free(K); + BN_clear_free(x); + if (passwd) { + OPENSSL_cleanse(passwd, strlen(passwd)); + OPENSSL_free(passwd); + } + BN_clear_free(u); + return ret; +} + +int srp_verify_server_param(SSL *s, int *al) +{ + SRP_CTX *srp = &s->srp_ctx; + /* + * Sanity check parameters: we can quickly check B % N == 0 by checking B + * != 0 since B < N + */ + if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0 + || BN_is_zero(srp->B)) { + *al = SSL3_AD_ILLEGAL_PARAMETER; + return 0; + } + + if (BN_num_bits(srp->N) < srp->strength) { + *al = TLS1_AD_INSUFFICIENT_SECURITY; + return 0; + } + + if (srp->SRP_verify_param_callback) { + if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) { + *al = TLS1_AD_INSUFFICIENT_SECURITY; + return 0; + } + } else if (!SRP_check_known_gN_param(srp->g, srp->N)) { + *al = TLS1_AD_INSUFFICIENT_SECURITY; + return 0; + } + + return 1; +} + +int SRP_Calc_A_param(SSL *s) +{ + unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; + + if (RAND_bytes(rnd, sizeof(rnd)) <= 0) + return -1; + s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); + OPENSSL_cleanse(rnd, sizeof(rnd)); + + if (! + (s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g))) + return -1; + + return 1; +} + +BIGNUM *SSL_get_srp_g(SSL *s) +{ + if (s->srp_ctx.g != NULL) + return s->srp_ctx.g; + return s->ctx->srp_ctx.g; +} + +BIGNUM *SSL_get_srp_N(SSL *s) +{ + if (s->srp_ctx.N != NULL) + return s->srp_ctx.N; + return s->ctx->srp_ctx.N; +} + +char *SSL_get_srp_username(SSL *s) +{ + if (s->srp_ctx.login != NULL) + return s->srp_ctx.login; + return s->ctx->srp_ctx.login; +} + +char *SSL_get_srp_userinfo(SSL *s) +{ + if (s->srp_ctx.info != NULL) + return s->srp_ctx.info; + return s->ctx->srp_ctx.info; +} + +# define tls1_ctx_ctrl ssl3_ctx_ctrl +# define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl + +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name) +{ + return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name); +} + +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password) +{ + return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password); +} + +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength) +{ + return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength, + NULL); +} + +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)) +{ + return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB, + (void (*)(void))cb); +} + +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg) +{ + return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg); +} + +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)) +{ + return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB, + (void (*)(void))cb); +} + +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)) +{ + return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB, + (void (*)(void))cb); +} + +#endif diff --git a/Sources/COpenSSL/ts.h b/Sources/COpenSSL/ts.h new file mode 100644 index 00000000..f31fab7d --- /dev/null +++ b/Sources/COpenSSL/ts.h @@ -0,0 +1,865 @@ +/* crypto/ts/ts.h */ +/* + * Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL project + * 2002, 2003, 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_TS_H +# define HEADER_TS_H + +# include "opensslconf.h" +# include "symhacks.h" +# ifndef OPENSSL_NO_BUFFER +# include "buffer.h" +# endif +# ifndef OPENSSL_NO_EVP +# include "evp.h" +# endif +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# include "stack.h" +# include "asn1.h" +# include "safestack.h" + +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif + +# ifndef OPENSSL_NO_DSA +# include "dsa.h" +# endif + +# ifndef OPENSSL_NO_DH +# include "dh.h" +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef WIN32 +/* Under Win32 this is defined in wincrypt.h */ +# undef X509_NAME +# endif + +# include "x509.h" +# include "x509v3.h" + +/*- +MessageImprint ::= SEQUENCE { + hashAlgorithm AlgorithmIdentifier, + hashedMessage OCTET STRING } +*/ + +typedef struct TS_msg_imprint_st { + X509_ALGOR *hash_algo; + ASN1_OCTET_STRING *hashed_msg; +} TS_MSG_IMPRINT; + +/*- +TimeStampReq ::= SEQUENCE { + version INTEGER { v1(1) }, + messageImprint MessageImprint, + --a hash algorithm OID and the hash value of the data to be + --time-stamped + reqPolicy TSAPolicyId OPTIONAL, + nonce INTEGER OPTIONAL, + certReq BOOLEAN DEFAULT FALSE, + extensions [0] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_req_st { + ASN1_INTEGER *version; + TS_MSG_IMPRINT *msg_imprint; + ASN1_OBJECT *policy_id; /* OPTIONAL */ + ASN1_INTEGER *nonce; /* OPTIONAL */ + ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */ + STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ +} TS_REQ; + +/*- +Accuracy ::= SEQUENCE { + seconds INTEGER OPTIONAL, + millis [0] INTEGER (1..999) OPTIONAL, + micros [1] INTEGER (1..999) OPTIONAL } +*/ + +typedef struct TS_accuracy_st { + ASN1_INTEGER *seconds; + ASN1_INTEGER *millis; + ASN1_INTEGER *micros; +} TS_ACCURACY; + +/*- +TSTInfo ::= SEQUENCE { + version INTEGER { v1(1) }, + policy TSAPolicyId, + messageImprint MessageImprint, + -- MUST have the same value as the similar field in + -- TimeStampReq + serialNumber INTEGER, + -- Time-Stamping users MUST be ready to accommodate integers + -- up to 160 bits. + genTime GeneralizedTime, + accuracy Accuracy OPTIONAL, + ordering BOOLEAN DEFAULT FALSE, + nonce INTEGER OPTIONAL, + -- MUST be present if the similar field was present + -- in TimeStampReq. In that case it MUST have the same value. + tsa [0] GeneralName OPTIONAL, + extensions [1] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_tst_info_st { + ASN1_INTEGER *version; + ASN1_OBJECT *policy_id; + TS_MSG_IMPRINT *msg_imprint; + ASN1_INTEGER *serial; + ASN1_GENERALIZEDTIME *time; + TS_ACCURACY *accuracy; + ASN1_BOOLEAN ordering; + ASN1_INTEGER *nonce; + GENERAL_NAME *tsa; + STACK_OF(X509_EXTENSION) *extensions; +} TS_TST_INFO; + +/*- +PKIStatusInfo ::= SEQUENCE { + status PKIStatus, + statusString PKIFreeText OPTIONAL, + failInfo PKIFailureInfo OPTIONAL } + +From RFC 1510 - section 3.1.1: +PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String + -- text encoded as UTF-8 String (note: each UTF8String SHOULD + -- include an RFC 1766 language tag to indicate the language + -- of the contained text) +*/ + +/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */ + +# define TS_STATUS_GRANTED 0 +# define TS_STATUS_GRANTED_WITH_MODS 1 +# define TS_STATUS_REJECTION 2 +# define TS_STATUS_WAITING 3 +# define TS_STATUS_REVOCATION_WARNING 4 +# define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* + * Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c + */ + +# define TS_INFO_BAD_ALG 0 +# define TS_INFO_BAD_REQUEST 2 +# define TS_INFO_BAD_DATA_FORMAT 5 +# define TS_INFO_TIME_NOT_AVAILABLE 14 +# define TS_INFO_UNACCEPTED_POLICY 15 +# define TS_INFO_UNACCEPTED_EXTENSION 16 +# define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +# define TS_INFO_SYSTEM_FAILURE 25 + +typedef struct TS_status_info_st { + ASN1_INTEGER *status; + STACK_OF(ASN1_UTF8STRING) *text; + ASN1_BIT_STRING *failure_info; +} TS_STATUS_INFO; + +DECLARE_STACK_OF(ASN1_UTF8STRING) +DECLARE_ASN1_SET_OF(ASN1_UTF8STRING) + +/*- +TimeStampResp ::= SEQUENCE { + status PKIStatusInfo, + timeStampToken TimeStampToken OPTIONAL } +*/ + +typedef struct TS_resp_st { + TS_STATUS_INFO *status_info; + PKCS7 *token; + TS_TST_INFO *tst_info; +} TS_RESP; + +/* The structure below would belong to the ESS component. */ + +/*- +IssuerSerial ::= SEQUENCE { + issuer GeneralNames, + serialNumber CertificateSerialNumber + } +*/ + +typedef struct ESS_issuer_serial { + STACK_OF(GENERAL_NAME) *issuer; + ASN1_INTEGER *serial; +} ESS_ISSUER_SERIAL; + +/*- +ESSCertID ::= SEQUENCE { + certHash Hash, + issuerSerial IssuerSerial OPTIONAL +} +*/ + +typedef struct ESS_cert_id { + ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ + ESS_ISSUER_SERIAL *issuer_serial; +} ESS_CERT_ID; + +DECLARE_STACK_OF(ESS_CERT_ID) +DECLARE_ASN1_SET_OF(ESS_CERT_ID) + +/*- +SigningCertificate ::= SEQUENCE { + certs SEQUENCE OF ESSCertID, + policies SEQUENCE OF PolicyInformation OPTIONAL +} +*/ + +typedef struct ESS_signing_cert { + STACK_OF(ESS_CERT_ID) *cert_ids; + STACK_OF(POLICYINFO) *policy_info; +} ESS_SIGNING_CERT; + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, + long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +void ERR_load_TS_strings(void); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* + * Declarations related to response generation, defined in ts/ts_resp_sign.c. + */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +# define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +# define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +# define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *); + +/* + * This must return the seconds and microseconds since Jan 1, 1970 in the sec + * and usec variables allocated by the caller. Return non-zero for success + * and zero for failure. + */ +typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec, + long *usec); + +/* + * This must process the given extension. It can modify the TS_TST_INFO + * object of the context. Return values: !0 (processed), 0 (error, it must + * set the status info/failure info of the response). + */ +typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *, + void *); + +typedef struct TS_resp_ctx { + X509 *signer_cert; + EVP_PKEY *signer_key; + STACK_OF(X509) *certs; /* Certs to include in signed data. */ + STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ + ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ + STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */ + ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */ + unsigned clock_precision_digits; /* fraction of seconds in time stamp + * token. */ + unsigned flags; /* Optional info, see values above. */ + /* Callback functions. */ + TS_serial_cb serial_cb; + void *serial_cb_data; /* User data for serial_cb. */ + TS_time_cb time_cb; + void *time_cb_data; /* User data for time_cb. */ + TS_extension_cb extension_cb; + void *extension_cb_data; /* User data for extension_cb. */ + /* These members are used only while creating the response. */ + TS_REQ *request; + TS_RESP *response; + TS_TST_INFO *tst_info; +} TS_RESP_CTX; + +DECLARE_STACK_OF(EVP_MD) +DECLARE_ASN1_SET_OF(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* + * Adds a new acceptable policy, only the default policy is accepted by + * default. + */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy); + +/* + * Adds a new acceptable message digest. Note that no message digests are + * accepted by default. The md argument is shared with the caller. + */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* + * Clock precision digits, i.e. the number of decimal digits: '0' means sec, + * '3' msec, '6' usec, and so on. Default is 0. + */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +# define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* Maximum status message length */ +# define TS_MAX_STATUS_LENGTH (1024 * 1024) + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback uses the gettimeofday() and gmtime() system calls. */ +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); + +/* + * Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. + */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_resp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +# define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +# define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +# define TS_VFY_POLICY (1u << 2) +/* + * Verify the message imprint provided by the user. This flag should not be + * specified with TS_VFY_DATA. + */ +# define TS_VFY_IMPRINT (1u << 3) +/* + * Verify the message imprint computed by the verify method from the user + * provided data and the MD algorithm of the response. This flag should not + * be specified with TS_VFY_IMPRINT. + */ +# define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +# define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +# define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +# define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +# define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +# define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx { + /* Set this to the union of TS_VFY_... flags you want to carry out. */ + unsigned flags; + /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */ + X509_STORE *store; + STACK_OF(X509) *certs; + /* Must be set only with TS_VFY_POLICY. */ + ASN1_OBJECT *policy; + /* + * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the + * algorithm from the response is used. + */ + X509_ALGOR *md_alg; + unsigned char *imprint; + unsigned imprint_len; + /* Must be set only with TS_VFY_DATA. */ + BIO *data; + /* Must be set only with TS_VFY_TSA_NAME. */ + ASN1_INTEGER *nonce; + /* Must be set only with TS_VFY_TSA_NAME. */ + GENERAL_NAME *tsa_name; +} TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + * they are defined in ts/ts_verify_ctx.c. + */ + +/* Set all fields to zero. */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); + +/*- + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* + * Function declarations for handling configuration options, defined in + * ts/ts_conf.c + */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +/* -------------------------------------------------- */ +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_TS_strings(void); + +/* Error codes for the TS functions. */ + +/* Function codes. */ +# define TS_F_D2I_TS_RESP 147 +# define TS_F_DEF_SERIAL_CB 110 +# define TS_F_DEF_TIME_CB 111 +# define TS_F_ESS_ADD_SIGNING_CERT 112 +# define TS_F_ESS_CERT_ID_NEW_INIT 113 +# define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +# define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +# define TS_F_PKCS7_TO_TS_TST_INFO 148 +# define TS_F_TS_ACCURACY_SET_MICROS 115 +# define TS_F_TS_ACCURACY_SET_MILLIS 116 +# define TS_F_TS_ACCURACY_SET_SECONDS 117 +# define TS_F_TS_CHECK_IMPRINTS 100 +# define TS_F_TS_CHECK_NONCES 101 +# define TS_F_TS_CHECK_POLICY 102 +# define TS_F_TS_CHECK_SIGNING_CERTS 103 +# define TS_F_TS_CHECK_STATUS_INFO 104 +# define TS_F_TS_COMPUTE_IMPRINT 145 +# define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +# define TS_F_TS_GET_STATUS_TEXT 105 +# define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +# define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +# define TS_F_TS_REQ_SET_NONCE 120 +# define TS_F_TS_REQ_SET_POLICY_ID 121 +# define TS_F_TS_RESP_CREATE_RESPONSE 122 +# define TS_F_TS_RESP_CREATE_TST_INFO 123 +# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +# define TS_F_TS_RESP_CTX_ADD_MD 125 +# define TS_F_TS_RESP_CTX_ADD_POLICY 126 +# define TS_F_TS_RESP_CTX_NEW 127 +# define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +# define TS_F_TS_RESP_CTX_SET_CERTS 129 +# define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +# define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +# define TS_F_TS_RESP_GET_POLICY 133 +# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +# define TS_F_TS_RESP_SET_STATUS_INFO 135 +# define TS_F_TS_RESP_SET_TST_INFO 150 +# define TS_F_TS_RESP_SIGN 136 +# define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +# define TS_F_TS_RESP_VERIFY_TOKEN 107 +# define TS_F_TS_TST_INFO_SET_ACCURACY 137 +# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +# define TS_F_TS_TST_INFO_SET_NONCE 139 +# define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +# define TS_F_TS_TST_INFO_SET_SERIAL 141 +# define TS_F_TS_TST_INFO_SET_TIME 142 +# define TS_F_TS_TST_INFO_SET_TSA 143 +# define TS_F_TS_VERIFY 108 +# define TS_F_TS_VERIFY_CERT 109 +# define TS_F_TS_VERIFY_CTX_NEW 144 + +/* Reason codes. */ +# define TS_R_BAD_PKCS7_TYPE 132 +# define TS_R_BAD_TYPE 133 +# define TS_R_CERTIFICATE_VERIFY_ERROR 100 +# define TS_R_COULD_NOT_SET_ENGINE 127 +# define TS_R_COULD_NOT_SET_TIME 115 +# define TS_R_D2I_TS_RESP_INT_FAILED 128 +# define TS_R_DETACHED_CONTENT 134 +# define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +# define TS_R_INVALID_NULL_POINTER 102 +# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +# define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +# define TS_R_NONCE_MISMATCH 104 +# define TS_R_NONCE_NOT_RETURNED 105 +# define TS_R_NO_CONTENT 106 +# define TS_R_NO_TIME_STAMP_TOKEN 107 +# define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +# define TS_R_POLICY_MISMATCH 108 +# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +# define TS_R_RESPONSE_SETUP_ERROR 121 +# define TS_R_SIGNATURE_FAILURE 109 +# define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +# define TS_R_TIME_SYSCALL_ERROR 122 +# define TS_R_TOKEN_NOT_PRESENT 130 +# define TS_R_TOKEN_PRESENT 131 +# define TS_R_TSA_NAME_MISMATCH 111 +# define TS_R_TSA_UNTRUSTED 112 +# define TS_R_TST_INFO_SETUP_ERROR 123 +# define TS_R_TS_DATASIGN 124 +# define TS_R_UNACCEPTABLE_POLICY 125 +# define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +# define TS_R_UNSUPPORTED_VERSION 113 +# define TS_R_WRONG_CONTENT_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ts_.c b/Sources/COpenSSL/ts_.c new file mode 100644 index 00000000..7175419b --- /dev/null +++ b/Sources/COpenSSL/ts_.c @@ -0,0 +1,4090 @@ +/* crypto/ts/ts_asn1.c */ +/* + * Written by Nils Larsch for the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ts.h" +#include "err.h" +#include "asn1t.h" + +ASN1_SEQUENCE(TS_MSG_IMPRINT) = { + ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR), + ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(TS_MSG_IMPRINT) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT) +#ifndef OPENSSL_NO_BIO +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a) +{ + return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, + d2i_TS_MSG_IMPRINT, bp, a); +} + +int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a) +{ + return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a) +{ + return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, + d2i_TS_MSG_IMPRINT, fp, a); +} + +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a) +{ + return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a); +} +#endif + +ASN1_SEQUENCE(TS_REQ) = { + ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER), + ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT), + ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT), + ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER), + ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN), + ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0) +} ASN1_SEQUENCE_END(TS_REQ) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ) +#ifndef OPENSSL_NO_BIO +TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a) +{ + return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a); +} + +int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a) +{ + return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a) +{ + return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a); +} + +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a) +{ + return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a); +} +#endif + +ASN1_SEQUENCE(TS_ACCURACY) = { + ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER), + ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0), + ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1) +} ASN1_SEQUENCE_END(TS_ACCURACY) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY) + +ASN1_SEQUENCE(TS_TST_INFO) = { + ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT), + ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT), + ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER), + ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME), + ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY), + ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN), + ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER), + ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0), + ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1) +} ASN1_SEQUENCE_END(TS_TST_INFO) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO) +#ifndef OPENSSL_NO_BIO +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a) +{ + return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, + a); +} + +int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a) +{ + return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a) +{ + return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, + a); +} + +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a) +{ + return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a); +} +#endif + +ASN1_SEQUENCE(TS_STATUS_INFO) = { + ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER), + ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING), + ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(TS_STATUS_INFO) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO) + +static int ts_resp_set_tst_info(TS_RESP *a) +{ + long status; + + status = ASN1_INTEGER_get(a->status_info->status); + + if (a->token) { + if (status != 0 && status != 1) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT); + return 0; + } + if (a->tst_info != NULL) + TS_TST_INFO_free(a->tst_info); + a->tst_info = PKCS7_to_TS_TST_INFO(a->token); + if (!a->tst_info) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, + TS_R_PKCS7_TO_TS_TST_INFO_FAILED); + return 0; + } + } else if (status == 0 || status == 1) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT); + return 0; + } + + return 1; +} + +static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + TS_RESP *ts_resp = (TS_RESP *)*pval; + if (op == ASN1_OP_NEW_POST) { + ts_resp->tst_info = NULL; + } else if (op == ASN1_OP_FREE_POST) { + if (ts_resp->tst_info != NULL) + TS_TST_INFO_free(ts_resp->tst_info); + } else if (op == ASN1_OP_D2I_POST) { + if (ts_resp_set_tst_info(ts_resp) == 0) + return 0; + } + return 1; +} + +ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = { + ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO), + ASN1_OPT(TS_RESP, token, PKCS7), +} ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP) + +IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP) + +#ifndef OPENSSL_NO_BIO +TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a) +{ + return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a); +} + +int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a) +{ + return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a) +{ + return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a); +} + +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a) +{ + return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a); +} +#endif + +ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = { + ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME), + ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER) +} ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL) + +ASN1_SEQUENCE(ESS_CERT_ID) = { + ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING), + ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL) +} ASN1_SEQUENCE_END(ESS_CERT_ID) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID) + +ASN1_SEQUENCE(ESS_SIGNING_CERT) = { + ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID), + ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO) +} ASN1_SEQUENCE_END(ESS_SIGNING_CERT) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT) + +/* Getting encapsulated TS_TST_INFO object from PKCS7. */ +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) +{ + PKCS7_SIGNED *pkcs7_signed; + PKCS7 *enveloped; + ASN1_TYPE *tst_info_wrapper; + ASN1_OCTET_STRING *tst_info_der; + const unsigned char *p; + + if (!PKCS7_type_is_signed(token)) { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); + return NULL; + } + + /* Content must be present. */ + if (PKCS7_get_detached(token)) { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT); + return NULL; + } + + /* We have a signed data with content. */ + pkcs7_signed = token->d.sign; + enveloped = pkcs7_signed->contents; + if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); + return NULL; + } + + /* We have a DER encoded TST_INFO as the signed data. */ + tst_info_wrapper = enveloped->d.other; + if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE); + return NULL; + } + + /* We have the correct ASN1_OCTET_STRING type. */ + tst_info_der = tst_info_wrapper->value.octet_string; + /* At last, decode the TST_INFO. */ + p = tst_info_der->data; + return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length); +} +/* crypto/ts/ts_conf.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "crypto.h" +#include "cryptlib.h" +#include "pem.h" +#ifndef OPENSSL_NO_ENGINE +# include "engine.h" +#endif +// #include "ts.h" + +/* Macro definitions for the configuration file. */ + +#define BASE_SECTION "tsa" +#define ENV_DEFAULT_TSA "default_tsa" +#define ENV_SERIAL "serial" +#define ENV_CRYPTO_DEVICE "crypto_device" +#define ENV_SIGNER_CERT "signer_cert" +#define ENV_CERTS "certs" +#define ENV_SIGNER_KEY "signer_key" +#define ENV_DEFAULT_POLICY "default_policy" +#define ENV_OTHER_POLICIES "other_policies" +#define ENV_DIGESTS "digests" +#define ENV_ACCURACY "accuracy" +#define ENV_ORDERING "ordering" +#define ENV_TSA_NAME "tsa_name" +#define ENV_ESS_CERT_ID_CHAIN "ess_cert_id_chain" +#define ENV_VALUE_SECS "secs" +#define ENV_VALUE_MILLISECS "millisecs" +#define ENV_VALUE_MICROSECS "microsecs" +#define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits" +#define ENV_VALUE_YES "yes" +#define ENV_VALUE_NO "no" + +/* Function definitions for certificate and key loading. */ + +X509 *TS_CONF_load_cert(const char *file) +{ + BIO *cert = NULL; + X509 *x = NULL; + + if ((cert = BIO_new_file(file, "r")) == NULL) + goto end; + x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); + end: + if (x == NULL) + fprintf(stderr, "unable to load certificate: %s\n", file); + BIO_free(cert); + return x; +} + +STACK_OF(X509) *TS_CONF_load_certs(const char *file) +{ + BIO *certs = NULL; + STACK_OF(X509) *othercerts = NULL; + STACK_OF(X509_INFO) *allcerts = NULL; + int i; + + if (!(certs = BIO_new_file(file, "r"))) + goto end; + + if (!(othercerts = sk_X509_new_null())) + goto end; + allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL); + for (i = 0; i < sk_X509_INFO_num(allcerts); i++) { + X509_INFO *xi = sk_X509_INFO_value(allcerts, i); + if (xi->x509) { + sk_X509_push(othercerts, xi->x509); + xi->x509 = NULL; + } + } + end: + if (othercerts == NULL) + fprintf(stderr, "unable to load certificates: %s\n", file); + sk_X509_INFO_pop_free(allcerts, X509_INFO_free); + BIO_free(certs); + return othercerts; +} + +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass) +{ + BIO *key = NULL; + EVP_PKEY *pkey = NULL; + + if (!(key = BIO_new_file(file, "r"))) + goto end; + pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *)pass); + end: + if (pkey == NULL) + fprintf(stderr, "unable to load private key: %s\n", file); + BIO_free(key); + return pkey; +} + +/* Function definitions for handling configuration options. */ + +static void TS_CONF_lookup_fail(const char *name, const char *tag) +{ + fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag); +} + +static void TS_CONF_invalid(const char *name, const char *tag) +{ + fprintf(stderr, "invalid variable value for %s::%s\n", name, tag); +} + +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section) +{ + if (!section) { + section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA); + if (!section) + TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA); + } + return section; +} + +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx) +{ + int ret = 0; + char *serial = NCONF_get_string(conf, section, ENV_SERIAL); + if (!serial) { + TS_CONF_lookup_fail(section, ENV_SERIAL); + goto err; + } + TS_RESP_CTX_set_serial_cb(ctx, cb, serial); + + ret = 1; + err: + return ret; +} + +#ifndef OPENSSL_NO_ENGINE + +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device) +{ + int ret = 0; + + if (!device) + device = NCONF_get_string(conf, section, ENV_CRYPTO_DEVICE); + + if (device && !TS_CONF_set_default_engine(device)) { + TS_CONF_invalid(section, ENV_CRYPTO_DEVICE); + goto err; + } + ret = 1; + err: + return ret; +} + +int TS_CONF_set_default_engine(const char *name) +{ + ENGINE *e = NULL; + int ret = 0; + + /* Leave the default if builtin specified. */ + if (strcmp(name, "builtin") == 0) + return 1; + + if (!(e = ENGINE_by_id(name))) + goto err; + /* Enable the use of the NCipher HSM for forked children. */ + if (strcmp(name, "chil") == 0) + ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0); + /* All the operations are going to be carried out by the engine. */ + if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) + goto err; + ret = 1; + err: + if (!ret) { + TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, TS_R_COULD_NOT_SET_ENGINE); + ERR_add_error_data(2, "engine:", name); + } + if (e) + ENGINE_free(e); + return ret; +} + +#endif + +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx) +{ + int ret = 0; + X509 *cert_obj = NULL; + if (!cert) + cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT); + if (!cert) { + TS_CONF_lookup_fail(section, ENV_SIGNER_CERT); + goto err; + } + if (!(cert_obj = TS_CONF_load_cert(cert))) + goto err; + if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj)) + goto err; + + ret = 1; + err: + X509_free(cert_obj); + return ret; +} + +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx) +{ + int ret = 0; + STACK_OF(X509) *certs_obj = NULL; + if (!certs) + certs = NCONF_get_string(conf, section, ENV_CERTS); + /* Certificate chain is optional. */ + if (!certs) + goto end; + if (!(certs_obj = TS_CONF_load_certs(certs))) + goto err; + if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) + goto err; + end: + ret = 1; + err: + sk_X509_pop_free(certs_obj, X509_free); + return ret; +} + +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx) +{ + int ret = 0; + EVP_PKEY *key_obj = NULL; + if (!key) + key = NCONF_get_string(conf, section, ENV_SIGNER_KEY); + if (!key) { + TS_CONF_lookup_fail(section, ENV_SIGNER_KEY); + goto err; + } + if (!(key_obj = TS_CONF_load_key(key, pass))) + goto err; + if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) + goto err; + + ret = 1; + err: + EVP_PKEY_free(key_obj); + return ret; +} + +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx) +{ + int ret = 0; + ASN1_OBJECT *policy_obj = NULL; + if (!policy) + policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY); + if (!policy) { + TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY); + goto err; + } + if (!(policy_obj = OBJ_txt2obj(policy, 0))) { + TS_CONF_invalid(section, ENV_DEFAULT_POLICY); + goto err; + } + if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj)) + goto err; + + ret = 1; + err: + ASN1_OBJECT_free(policy_obj); + return ret; +} + +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + STACK_OF(CONF_VALUE) *list = NULL; + char *policies = NCONF_get_string(conf, section, + ENV_OTHER_POLICIES); + /* If no other policy is specified, that's fine. */ + if (policies && !(list = X509V3_parse_list(policies))) { + TS_CONF_invalid(section, ENV_OTHER_POLICIES); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + const char *extval = val->value ? val->value : val->name; + ASN1_OBJECT *objtmp; + if (!(objtmp = OBJ_txt2obj(extval, 0))) { + TS_CONF_invalid(section, ENV_OTHER_POLICIES); + goto err; + } + if (!TS_RESP_CTX_add_policy(ctx, objtmp)) + goto err; + ASN1_OBJECT_free(objtmp); + } + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} + +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + STACK_OF(CONF_VALUE) *list = NULL; + char *digests = NCONF_get_string(conf, section, ENV_DIGESTS); + if (!digests) { + TS_CONF_lookup_fail(section, ENV_DIGESTS); + goto err; + } + if (!(list = X509V3_parse_list(digests))) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + if (sk_CONF_VALUE_num(list) == 0) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + const char *extval = val->value ? val->value : val->name; + const EVP_MD *md; + if (!(md = EVP_get_digestbyname(extval))) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + if (!TS_RESP_CTX_add_md(ctx, md)) + goto err; + } + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} + +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + int secs = 0, millis = 0, micros = 0; + STACK_OF(CONF_VALUE) *list = NULL; + char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY); + + if (accuracy && !(list = X509V3_parse_list(accuracy))) { + TS_CONF_invalid(section, ENV_ACCURACY); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + if (strcmp(val->name, ENV_VALUE_SECS) == 0) { + if (val->value) + secs = atoi(val->value); + } else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) { + if (val->value) + millis = atoi(val->value); + } else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) { + if (val->value) + micros = atoi(val->value); + } else { + TS_CONF_invalid(section, ENV_ACCURACY); + goto err; + } + } + if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros)) + goto err; + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} + +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx) +{ + int ret = 0; + long digits = 0; + + /* + * If not specified, set the default value to 0, i.e. sec precision + */ + if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS, + &digits)) + digits = 0; + if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) { + TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS); + goto err; + } + + if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits)) + goto err; + + return 1; + err: + return ret; +} + +static int TS_CONF_add_flag(CONF *conf, const char *section, + const char *field, int flag, TS_RESP_CTX *ctx) +{ + /* Default is false. */ + const char *value = NCONF_get_string(conf, section, field); + if (value) { + if (strcmp(value, ENV_VALUE_YES) == 0) + TS_RESP_CTX_add_flags(ctx, flag); + else if (strcmp(value, ENV_VALUE_NO) != 0) { + TS_CONF_invalid(section, field); + return 0; + } + } + + return 1; +} + +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx); +} + +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx); +} + +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, + TS_ESS_CERT_ID_CHAIN, ctx); +} +/* crypto/ts/ts_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +// #include "err.h" +// #include "ts.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason) + +static ERR_STRING_DATA TS_str_functs[] = { + {ERR_FUNC(TS_F_D2I_TS_RESP), "d2i_TS_RESP"}, + {ERR_FUNC(TS_F_DEF_SERIAL_CB), "DEF_SERIAL_CB"}, + {ERR_FUNC(TS_F_DEF_TIME_CB), "DEF_TIME_CB"}, + {ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_ADD_SIGNING_CERT"}, + {ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ESS_CERT_ID_NEW_INIT"}, + {ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ESS_SIGNING_CERT_NEW_INIT"}, + {ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "INT_TS_RESP_VERIFY_TOKEN"}, + {ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"}, + {ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"}, + {ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS), "TS_ACCURACY_set_millis"}, + {ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS), "TS_ACCURACY_set_seconds"}, + {ERR_FUNC(TS_F_TS_CHECK_IMPRINTS), "TS_CHECK_IMPRINTS"}, + {ERR_FUNC(TS_F_TS_CHECK_NONCES), "TS_CHECK_NONCES"}, + {ERR_FUNC(TS_F_TS_CHECK_POLICY), "TS_CHECK_POLICY"}, + {ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "TS_CHECK_SIGNING_CERTS"}, + {ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "TS_CHECK_STATUS_INFO"}, + {ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "TS_COMPUTE_IMPRINT"}, + {ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"}, + {ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "TS_GET_STATUS_TEXT"}, + {ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"}, + {ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT), "TS_REQ_set_msg_imprint"}, + {ERR_FUNC(TS_F_TS_REQ_SET_NONCE), "TS_REQ_set_nonce"}, + {ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID), "TS_REQ_set_policy_id"}, + {ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE), "TS_RESP_create_response"}, + {ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO), "TS_RESP_CREATE_TST_INFO"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO), + "TS_RESP_CTX_add_failure_info"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD), "TS_RESP_CTX_add_md"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY), "TS_RESP_CTX_add_policy"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_NEW), "TS_RESP_CTX_new"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY), "TS_RESP_CTX_set_accuracy"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS), "TS_RESP_CTX_set_certs"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY), "TS_RESP_CTX_set_def_policy"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT), + "TS_RESP_CTX_set_signer_cert"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO), + "TS_RESP_CTX_set_status_info"}, + {ERR_FUNC(TS_F_TS_RESP_GET_POLICY), "TS_RESP_GET_POLICY"}, + {ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION), + "TS_RESP_SET_GENTIME_WITH_PRECISION"}, + {ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO), "TS_RESP_set_status_info"}, + {ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO), "TS_RESP_set_tst_info"}, + {ERR_FUNC(TS_F_TS_RESP_SIGN), "TS_RESP_SIGN"}, + {ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE), "TS_RESP_verify_signature"}, + {ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN), "TS_RESP_verify_token"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY), "TS_TST_INFO_set_accuracy"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT), + "TS_TST_INFO_set_msg_imprint"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE), "TS_TST_INFO_set_nonce"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID), "TS_TST_INFO_set_policy_id"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL), "TS_TST_INFO_set_serial"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME), "TS_TST_INFO_set_time"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA), "TS_TST_INFO_set_tsa"}, + {ERR_FUNC(TS_F_TS_VERIFY), "TS_VERIFY"}, + {ERR_FUNC(TS_F_TS_VERIFY_CERT), "TS_VERIFY_CERT"}, + {ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW), "TS_VERIFY_CTX_new"}, + {0, NULL} +}; + +static ERR_STRING_DATA TS_str_reasons[] = { + {ERR_REASON(TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type"}, + {ERR_REASON(TS_R_BAD_TYPE), "bad type"}, + {ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(TS_R_COULD_NOT_SET_ENGINE), "could not set engine"}, + {ERR_REASON(TS_R_COULD_NOT_SET_TIME), "could not set time"}, + {ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED), "d2i ts resp int failed"}, + {ERR_REASON(TS_R_DETACHED_CONTENT), "detached content"}, + {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR), + "ess add signing cert error"}, + {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR), + "ess signing certificate error"}, + {ERR_REASON(TS_R_INVALID_NULL_POINTER), "invalid null pointer"}, + {ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE), + "invalid signer certificate purpose"}, + {ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH), "message imprint mismatch"}, + {ERR_REASON(TS_R_NONCE_MISMATCH), "nonce mismatch"}, + {ERR_REASON(TS_R_NONCE_NOT_RETURNED), "nonce not returned"}, + {ERR_REASON(TS_R_NO_CONTENT), "no content"}, + {ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN), "no time stamp token"}, + {ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"}, + {ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR), + "pkcs7 add signed attr error"}, + {ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED), + "pkcs7 to ts tst info failed"}, + {ERR_REASON(TS_R_POLICY_MISMATCH), "policy mismatch"}, + {ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_REASON(TS_R_RESPONSE_SETUP_ERROR), "response setup error"}, + {ERR_REASON(TS_R_SIGNATURE_FAILURE), "signature failure"}, + {ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER), "there must be one signer"}, + {ERR_REASON(TS_R_TIME_SYSCALL_ERROR), "time syscall error"}, + {ERR_REASON(TS_R_TOKEN_NOT_PRESENT), "token not present"}, + {ERR_REASON(TS_R_TOKEN_PRESENT), "token present"}, + {ERR_REASON(TS_R_TSA_NAME_MISMATCH), "tsa name mismatch"}, + {ERR_REASON(TS_R_TSA_UNTRUSTED), "tsa untrusted"}, + {ERR_REASON(TS_R_TST_INFO_SETUP_ERROR), "tst info setup error"}, + {ERR_REASON(TS_R_TS_DATASIGN), "ts datasign"}, + {ERR_REASON(TS_R_UNACCEPTABLE_POLICY), "unacceptable policy"}, + {ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM), "unsupported md algorithm"}, + {ERR_REASON(TS_R_UNSUPPORTED_VERSION), "unsupported version"}, + {ERR_REASON(TS_R_WRONG_CONTENT_TYPE), "wrong content type"}, + {0, NULL} +}; + +#endif + +void ERR_load_TS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(TS_str_functs[0].error) == NULL) { + ERR_load_strings(0, TS_str_functs); + ERR_load_strings(0, TS_str_reasons); + } +#endif +} +/* crypto/ts/ts_lib.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +#include "objects.h" +#include "bn.h" +#include "x509v3.h" +// #include "ts.h" + +/* Local function declarations. */ + +/* Function definitions. */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num) +{ + BIGNUM num_bn; + int result = 0; + char *hex; + + BN_init(&num_bn); + ASN1_INTEGER_to_BN(num, &num_bn); + if ((hex = BN_bn2hex(&num_bn))) { + result = BIO_write(bio, "0x", 2) > 0; + result = result && BIO_write(bio, hex, strlen(hex)) > 0; + OPENSSL_free(hex); + } + BN_free(&num_bn); + + return result; +} + +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj) +{ + char obj_txt[128]; + + OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); + BIO_printf(bio, "%s\n", obj_txt); + + return 1; +} + +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions) +{ + int i, critical, n; + X509_EXTENSION *ex; + ASN1_OBJECT *obj; + + BIO_printf(bio, "Extensions:\n"); + n = X509v3_get_ext_count(extensions); + for (i = 0; i < n; i++) { + ex = X509v3_get_ext(extensions, i); + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bio, obj); + critical = X509_EXTENSION_get_critical(ex); + BIO_printf(bio, ": %s\n", critical ? "critical" : ""); + if (!X509V3_EXT_print(bio, ex, 0, 4)) { + BIO_printf(bio, "%4s", ""); + M_ASN1_OCTET_STRING_print(bio, ex->value); + } + BIO_write(bio, "\n", 1); + } + + return 1; +} + +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg) +{ + int i = OBJ_obj2nid(alg->algorithm); + return BIO_printf(bio, "Hash Algorithm: %s\n", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); +} + +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a) +{ + const ASN1_OCTET_STRING *msg; + + TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a)); + + BIO_printf(bio, "Message data:\n"); + msg = TS_MSG_IMPRINT_get_msg(a); + BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg), + M_ASN1_STRING_length(msg), 4); + + return 1; +} +/* crypto/ts/ts_req_print.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "bn.h" +// #include "x509v3.h" +// #include "ts.h" + +/* Function definitions. */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a) +{ + int v; + ASN1_OBJECT *policy_id; + const ASN1_INTEGER *nonce; + + if (a == NULL) + return 0; + + v = TS_REQ_get_version(a); + BIO_printf(bio, "Version: %d\n", v); + + TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a)); + + BIO_printf(bio, "Policy OID: "); + policy_id = TS_REQ_get_policy_id(a); + if (policy_id == NULL) + BIO_printf(bio, "unspecified\n"); + else + TS_OBJ_print_bio(bio, policy_id); + + BIO_printf(bio, "Nonce: "); + nonce = TS_REQ_get_nonce(a); + if (nonce == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, nonce); + BIO_write(bio, "\n", 1); + + BIO_printf(bio, "Certificate required: %s\n", + TS_REQ_get_cert_req(a) ? "yes" : "no"); + + TS_ext_print_bio(bio, TS_REQ_get_exts(a)); + + return 1; +} +/* crypto/ts/ts_req_utils.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "x509v3.h" +// #include "ts.h" + +int TS_REQ_set_version(TS_REQ *a, long version) +{ + return ASN1_INTEGER_set(a->version, version); +} + +long TS_REQ_get_version(const TS_REQ *a) +{ + return ASN1_INTEGER_get(a->version); +} + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint) +{ + TS_MSG_IMPRINT *new_msg_imprint; + + if (a->msg_imprint == msg_imprint) + return 1; + new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); + if (new_msg_imprint == NULL) { + TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_MSG_IMPRINT_free(a->msg_imprint); + a->msg_imprint = new_msg_imprint; + return 1; +} + +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a) +{ + return a->msg_imprint; +} + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg) +{ + X509_ALGOR *new_alg; + + if (a->hash_algo == alg) + return 1; + new_alg = X509_ALGOR_dup(alg); + if (new_alg == NULL) { + TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE); + return 0; + } + X509_ALGOR_free(a->hash_algo); + a->hash_algo = new_alg; + return 1; +} + +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a) +{ + return a->hash_algo; +} + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len) +{ + return ASN1_OCTET_STRING_set(a->hashed_msg, d, len); +} + +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a) +{ + return a->hashed_msg; +} + +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy) +{ + ASN1_OBJECT *new_policy; + + if (a->policy_id == policy) + return 1; + new_policy = OBJ_dup(policy); + if (new_policy == NULL) { + TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(a->policy_id); + a->policy_id = new_policy; + return 1; +} + +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a) +{ + return a->policy_id; +} + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce) +{ + ASN1_INTEGER *new_nonce; + + if (a->nonce == nonce) + return 1; + new_nonce = ASN1_INTEGER_dup(nonce); + if (new_nonce == NULL) { + TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->nonce); + a->nonce = new_nonce; + return 1; +} + +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a) +{ + return a->nonce; +} + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req) +{ + a->cert_req = cert_req ? 0xFF : 0x00; + return 1; +} + +int TS_REQ_get_cert_req(const TS_REQ *a) +{ + return a->cert_req ? 1 : 0; +} + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a) +{ + return a->extensions; +} + +void TS_REQ_ext_free(TS_REQ *a) +{ + if (!a) + return; + sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); + a->extensions = NULL; +} + +int TS_REQ_get_ext_count(TS_REQ *a) +{ + return X509v3_get_ext_count(a->extensions); +} + +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); +} + +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos) +{ + return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); +} + +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); +} + +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc) +{ + return X509v3_get_ext(a->extensions, loc); +} + +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc) +{ + return X509v3_delete_ext(a->extensions, loc); +} + +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&a->extensions, ex, loc) != NULL; +} + +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(a->extensions, nid, crit, idx); +} +/* crypto/ts/ts_resp_print.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "bn.h" +// #include "x509v3.h" +// #include "ts.h" + +struct status_map_st { + int bit; + const char *text; +}; + +/* Local function declarations. */ + +static int TS_status_map_print(BIO *bio, struct status_map_st *a, + ASN1_BIT_STRING *v); +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy); + +/* Function definitions. */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a) +{ + TS_TST_INFO *tst_info; + + BIO_printf(bio, "Status info:\n"); + TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a)); + + BIO_printf(bio, "\nTST info:\n"); + tst_info = TS_RESP_get_tst_info(a); + if (tst_info != NULL) + TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a)); + else + BIO_printf(bio, "Not included.\n"); + + return 1; +} + +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a) +{ + static const char *status_map[] = { + "Granted.", + "Granted with modifications.", + "Rejected.", + "Waiting.", + "Revocation warning.", + "Revoked." + }; + static struct status_map_st failure_map[] = { + {TS_INFO_BAD_ALG, + "unrecognized or unsupported algorithm identifier"}, + {TS_INFO_BAD_REQUEST, + "transaction not permitted or supported"}, + {TS_INFO_BAD_DATA_FORMAT, + "the data submitted has the wrong format"}, + {TS_INFO_TIME_NOT_AVAILABLE, + "the TSA's time source is not available"}, + {TS_INFO_UNACCEPTED_POLICY, + "the requested TSA policy is not supported by the TSA"}, + {TS_INFO_UNACCEPTED_EXTENSION, + "the requested extension is not supported by the TSA"}, + {TS_INFO_ADD_INFO_NOT_AVAILABLE, + "the additional information requested could not be understood " + "or is not available"}, + {TS_INFO_SYSTEM_FAILURE, + "the request cannot be handled due to system failure"}, + {-1, NULL} + }; + long status; + int i, lines = 0; + + /* Printing status code. */ + BIO_printf(bio, "Status: "); + status = ASN1_INTEGER_get(a->status); + if (0 <= status + && status < (long)(sizeof(status_map) / sizeof(status_map[0]))) + BIO_printf(bio, "%s\n", status_map[status]); + else + BIO_printf(bio, "out of bounds\n"); + + /* Printing status description. */ + BIO_printf(bio, "Status description: "); + for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) { + if (i > 0) + BIO_puts(bio, "\t"); + ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i), 0); + BIO_puts(bio, "\n"); + } + if (i == 0) + BIO_printf(bio, "unspecified\n"); + + /* Printing failure information. */ + BIO_printf(bio, "Failure info: "); + if (a->failure_info != NULL) + lines = TS_status_map_print(bio, failure_map, a->failure_info); + if (lines == 0) + BIO_printf(bio, "unspecified"); + BIO_printf(bio, "\n"); + + return 1; +} + +static int TS_status_map_print(BIO *bio, struct status_map_st *a, + ASN1_BIT_STRING *v) +{ + int lines = 0; + + for (; a->bit >= 0; ++a) { + if (ASN1_BIT_STRING_get_bit(v, a->bit)) { + if (++lines > 1) + BIO_printf(bio, ", "); + BIO_printf(bio, "%s", a->text); + } + } + + return lines; +} + +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a) +{ + int v; + ASN1_OBJECT *policy_id; + const ASN1_INTEGER *serial; + const ASN1_GENERALIZEDTIME *gtime; + TS_ACCURACY *accuracy; + const ASN1_INTEGER *nonce; + GENERAL_NAME *tsa_name; + + if (a == NULL) + return 0; + + /* Print version. */ + v = TS_TST_INFO_get_version(a); + BIO_printf(bio, "Version: %d\n", v); + + /* Print policy id. */ + BIO_printf(bio, "Policy OID: "); + policy_id = TS_TST_INFO_get_policy_id(a); + TS_OBJ_print_bio(bio, policy_id); + + /* Print message imprint. */ + TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a)); + + /* Print serial number. */ + BIO_printf(bio, "Serial number: "); + serial = TS_TST_INFO_get_serial(a); + if (serial == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, serial); + BIO_write(bio, "\n", 1); + + /* Print time stamp. */ + BIO_printf(bio, "Time stamp: "); + gtime = TS_TST_INFO_get_time(a); + ASN1_GENERALIZEDTIME_print(bio, gtime); + BIO_write(bio, "\n", 1); + + /* Print accuracy. */ + BIO_printf(bio, "Accuracy: "); + accuracy = TS_TST_INFO_get_accuracy(a); + if (accuracy == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ACCURACY_print_bio(bio, accuracy); + BIO_write(bio, "\n", 1); + + /* Print ordering. */ + BIO_printf(bio, "Ordering: %s\n", + TS_TST_INFO_get_ordering(a) ? "yes" : "no"); + + /* Print nonce. */ + BIO_printf(bio, "Nonce: "); + nonce = TS_TST_INFO_get_nonce(a); + if (nonce == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, nonce); + BIO_write(bio, "\n", 1); + + /* Print TSA name. */ + BIO_printf(bio, "TSA: "); + tsa_name = TS_TST_INFO_get_tsa(a); + if (tsa_name == NULL) + BIO_printf(bio, "unspecified"); + else { + STACK_OF(CONF_VALUE) *nval; + if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL))) + X509V3_EXT_val_prn(bio, nval, 0, 0); + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + } + BIO_write(bio, "\n", 1); + + /* Print extensions. */ + TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a)); + + return 1; +} + +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy) +{ + const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy); + const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy); + const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy); + + if (seconds != NULL) + TS_ASN1_INTEGER_print_bio(bio, seconds); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " seconds, "); + if (millis != NULL) + TS_ASN1_INTEGER_print_bio(bio, millis); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " millis, "); + if (micros != NULL) + TS_ASN1_INTEGER_print_bio(bio, micros); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " micros"); + + return 1; +} +/* crypto/ts/ts_resp_sign.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +#include "o_time.h" + +#if defined(OPENSSL_SYS_UNIX) +# include +#endif + +// #include "objects.h" +// #include "ts.h" +#include "pkcs7.h" + +/* Private function declarations. */ + +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *); +static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec); +static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *); + +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx); +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx); +static int TS_RESP_check_request(TS_RESP_CTX *ctx); +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx); +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, + ASN1_OBJECT *policy); +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx); +static int TS_RESP_sign(TS_RESP_CTX *ctx); + +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, + STACK_OF(X509) *certs); +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); +static int TS_TST_INFO_content_new(PKCS7 *p7); +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); + +static ASN1_GENERALIZEDTIME +*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long, + unsigned); + +/* Default callbacks for response generation. */ + +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) +{ + ASN1_INTEGER *serial = ASN1_INTEGER_new(); + if (!serial) + goto err; + if (!ASN1_INTEGER_set(serial, 1)) + goto err; + return serial; + err: + TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Error during serial number generation."); + return NULL; +} + +#if defined(OPENSSL_SYS_UNIX) + +/* Use the gettimeofday function call. */ +static int def_time_cb(struct TS_resp_ctx *ctx, void *data, + long *sec, long *usec) +{ + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) { + TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Time is not available."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); + return 0; + } + /* Return time to caller. */ + *sec = tv.tv_sec; + *usec = tv.tv_usec; + + return 1; +} + +#else + +/* Use the time function call that provides only seconds precision. */ +static int def_time_cb(struct TS_resp_ctx *ctx, void *data, + long *sec, long *usec) +{ + time_t t; + if (time(&t) == (time_t)-1) { + TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Time is not available."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); + return 0; + } + /* Return time to caller, only second precision. */ + *sec = (long)t; + *usec = 0; + + return 1; +} + +#endif + +static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, + void *data) +{ + /* No extensions are processed here. */ + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Unsupported extension."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION); + return 0; +} + +/* TS_RESP_CTX management functions. */ + +TS_RESP_CTX *TS_RESP_CTX_new() +{ + TS_RESP_CTX *ctx; + + if (!(ctx = (TS_RESP_CTX *)OPENSSL_malloc(sizeof(TS_RESP_CTX)))) { + TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ctx, 0, sizeof(TS_RESP_CTX)); + + /* Setting default callbacks. */ + ctx->serial_cb = def_serial_cb; + ctx->time_cb = def_time_cb; + ctx->extension_cb = def_extension_cb; + + return ctx; +} + +void TS_RESP_CTX_free(TS_RESP_CTX *ctx) +{ + if (!ctx) + return; + + X509_free(ctx->signer_cert); + EVP_PKEY_free(ctx->signer_key); + sk_X509_pop_free(ctx->certs, X509_free); + sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free); + ASN1_OBJECT_free(ctx->default_policy); + sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */ + ASN1_INTEGER_free(ctx->seconds); + ASN1_INTEGER_free(ctx->millis); + ASN1_INTEGER_free(ctx->micros); + OPENSSL_free(ctx); +} + +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) +{ + if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) { + TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, + TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); + return 0; + } + if (ctx->signer_cert) + X509_free(ctx->signer_cert); + ctx->signer_cert = signer; + CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509); + return 1; +} + +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key) +{ + if (ctx->signer_key) + EVP_PKEY_free(ctx->signer_key); + ctx->signer_key = key; + CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY); + + return 1; +} + +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy) +{ + if (ctx->default_policy) + ASN1_OBJECT_free(ctx->default_policy); + if (!(ctx->default_policy = OBJ_dup(def_policy))) + goto err; + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE); + return 0; +} + +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) +{ + + if (ctx->certs) { + sk_X509_pop_free(ctx->certs, X509_free); + ctx->certs = NULL; + } + if (!certs) + return 1; + if (!(ctx->certs = X509_chain_up_ref(certs))) { + TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) +{ + ASN1_OBJECT *copy = NULL; + + /* Create new policy stack if necessary. */ + if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) + goto err; + if (!(copy = OBJ_dup(policy))) + goto err; + if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) + goto err; + + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE); + ASN1_OBJECT_free(copy); + return 0; +} + +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) +{ + /* Create new md stack if necessary. */ + if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) + goto err; + /* Add the shared md, no copy needed. */ + if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) + goto err; + + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE); + return 0; +} + +#define TS_RESP_CTX_accuracy_free(ctx) \ + ASN1_INTEGER_free(ctx->seconds); \ + ctx->seconds = NULL; \ + ASN1_INTEGER_free(ctx->millis); \ + ctx->millis = NULL; \ + ASN1_INTEGER_free(ctx->micros); \ + ctx->micros = NULL; + +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros) +{ + + TS_RESP_CTX_accuracy_free(ctx); + if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->seconds, secs))) + goto err; + if (millis && (!(ctx->millis = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->millis, millis))) + goto err; + if (micros && (!(ctx->micros = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->micros, micros))) + goto err; + + return 1; + err: + TS_RESP_CTX_accuracy_free(ctx); + TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE); + return 0; +} + +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data) +{ + ctx->serial_cb = cb; + ctx->serial_cb_data = data; +} + +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data) +{ + ctx->time_cb = cb; + ctx->time_cb_data = data; +} + +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data) +{ + ctx->extension_cb = cb; + ctx->extension_cb_data = data; +} + +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text) +{ + TS_STATUS_INFO *si = NULL; + ASN1_UTF8STRING *utf8_text = NULL; + int ret = 0; + + if (!(si = TS_STATUS_INFO_new())) + goto err; + if (!ASN1_INTEGER_set(si->status, status)) + goto err; + if (text) { + if (!(utf8_text = ASN1_UTF8STRING_new()) + || !ASN1_STRING_set(utf8_text, text, strlen(text))) + goto err; + if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null())) + goto err; + if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) + goto err; + utf8_text = NULL; /* Ownership is lost. */ + } + if (!TS_RESP_set_status_info(ctx->response, si)) + goto err; + ret = 1; + err: + if (!ret) + TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); + TS_STATUS_INFO_free(si); + ASN1_UTF8STRING_free(utf8_text); + return ret; +} + +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text) +{ + int ret = 1; + TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + + if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) { + /* Status has not been set, set it now. */ + ret = TS_RESP_CTX_set_status_info(ctx, status, text); + } + return ret; +} + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) +{ + TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new())) + goto err; + if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1)) + goto err; + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE); + return 0; +} + +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx) +{ + return ctx->request; +} + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx) +{ + return ctx->tst_info; +} + +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned precision) +{ + if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) + return 0; + ctx->clock_precision_digits = precision; + return 1; +} + +/* Main entry method of the response generation. */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) +{ + ASN1_OBJECT *policy; + TS_RESP *response; + int result = 0; + + TS_RESP_CTX_init(ctx); + + /* Creating the response object. */ + if (!(ctx->response = TS_RESP_new())) { + TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE); + goto end; + } + + /* Parsing DER request. */ + if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad request format or " "system error."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); + goto end; + } + + /* Setting default status info. */ + if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL)) + goto end; + + /* Checking the request format. */ + if (!TS_RESP_check_request(ctx)) + goto end; + + /* Checking acceptable policies. */ + if (!(policy = TS_RESP_get_policy(ctx))) + goto end; + + /* Creating the TS_TST_INFO object. */ + if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy))) + goto end; + + /* Processing extensions. */ + if (!TS_RESP_process_extensions(ctx)) + goto end; + + /* Generating the signature. */ + if (!TS_RESP_sign(ctx)) + goto end; + + /* Everything was successful. */ + result = 1; + end: + if (!result) { + TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR); + if (ctx->response != NULL) { + if (TS_RESP_CTX_set_status_info_cond(ctx, + TS_STATUS_REJECTION, + "Error during response " + "generation.") == 0) { + TS_RESP_free(ctx->response); + ctx->response = NULL; + } + } + } + response = ctx->response; + ctx->response = NULL; /* Ownership will be returned to caller. */ + TS_RESP_CTX_cleanup(ctx); + return response; +} + +/* Initializes the variable part of the context. */ +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx) +{ + ctx->request = NULL; + ctx->response = NULL; + ctx->tst_info = NULL; +} + +/* Cleans up the variable part of the context. */ +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx) +{ + TS_REQ_free(ctx->request); + ctx->request = NULL; + TS_RESP_free(ctx->response); + ctx->response = NULL; + TS_TST_INFO_free(ctx->tst_info); + ctx->tst_info = NULL; +} + +/* Checks the format and content of the request. */ +static int TS_RESP_check_request(TS_RESP_CTX *ctx) +{ + TS_REQ *request = ctx->request; + TS_MSG_IMPRINT *msg_imprint; + X509_ALGOR *md_alg; + int md_alg_id; + const ASN1_OCTET_STRING *digest; + EVP_MD *md = NULL; + int i; + + /* Checking request version. */ + if (TS_REQ_get_version(request) != 1) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad request version."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST); + return 0; + } + + /* Checking message digest algorithm. */ + msg_imprint = TS_REQ_get_msg_imprint(request); + md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint); + md_alg_id = OBJ_obj2nid(md_alg->algorithm); + for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) { + EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); + if (md_alg_id == EVP_MD_type(current_md)) + md = current_md; + } + if (!md) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Message digest algorithm is " + "not supported."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); + return 0; + } + + /* No message digest takes parameter. */ + if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Superfluous message digest " + "parameter."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); + return 0; + } + /* Checking message digest size. */ + digest = TS_MSG_IMPRINT_get_msg(msg_imprint); + if (digest->length != EVP_MD_size(md)) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad message digest."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); + return 0; + } + + return 1; +} + +/* Returns the TSA policy based on the requested and acceptable policies. */ +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx) +{ + ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request); + ASN1_OBJECT *policy = NULL; + int i; + + if (ctx->default_policy == NULL) { + TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER); + return NULL; + } + /* + * Return the default policy if none is requested or the default is + * requested. + */ + if (!requested || !OBJ_cmp(requested, ctx->default_policy)) + policy = ctx->default_policy; + + /* Check if the policy is acceptable. */ + for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) { + ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i); + if (!OBJ_cmp(requested, current)) + policy = current; + } + if (!policy) { + TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Requested policy is not " "supported."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY); + } + return policy; +} + +/* Creates the TS_TST_INFO object based on the settings of the context. */ +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, + ASN1_OBJECT *policy) +{ + int result = 0; + TS_TST_INFO *tst_info = NULL; + ASN1_INTEGER *serial = NULL; + ASN1_GENERALIZEDTIME *asn1_time = NULL; + long sec, usec; + TS_ACCURACY *accuracy = NULL; + const ASN1_INTEGER *nonce; + GENERAL_NAME *tsa_name = NULL; + + if (!(tst_info = TS_TST_INFO_new())) + goto end; + if (!TS_TST_INFO_set_version(tst_info, 1)) + goto end; + if (!TS_TST_INFO_set_policy_id(tst_info, policy)) + goto end; + if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint)) + goto end; + if (!(serial = (*ctx->serial_cb) (ctx, ctx->serial_cb_data)) + || !TS_TST_INFO_set_serial(tst_info, serial)) + goto end; + if (!(*ctx->time_cb) (ctx, ctx->time_cb_data, &sec, &usec) + || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, + sec, usec, + ctx->clock_precision_digits)) + || !TS_TST_INFO_set_time(tst_info, asn1_time)) + goto end; + + /* Setting accuracy if needed. */ + if ((ctx->seconds || ctx->millis || ctx->micros) + && !(accuracy = TS_ACCURACY_new())) + goto end; + + if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds)) + goto end; + if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis)) + goto end; + if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros)) + goto end; + if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) + goto end; + + /* Setting ordering. */ + if ((ctx->flags & TS_ORDERING) + && !TS_TST_INFO_set_ordering(tst_info, 1)) + goto end; + + /* Setting nonce if needed. */ + if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL + && !TS_TST_INFO_set_nonce(tst_info, nonce)) + goto end; + + /* Setting TSA name to subject of signer certificate. */ + if (ctx->flags & TS_TSA_NAME) { + if (!(tsa_name = GENERAL_NAME_new())) + goto end; + tsa_name->type = GEN_DIRNAME; + tsa_name->d.dirn = + X509_NAME_dup(ctx->signer_cert->cert_info->subject); + if (!tsa_name->d.dirn) + goto end; + if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) + goto end; + } + + result = 1; + end: + if (!result) { + TS_TST_INFO_free(tst_info); + tst_info = NULL; + TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR); + TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, + "Error during TSTInfo " + "generation."); + } + GENERAL_NAME_free(tsa_name); + TS_ACCURACY_free(accuracy); + ASN1_GENERALIZEDTIME_free(asn1_time); + ASN1_INTEGER_free(serial); + + return tst_info; +} + +/* Processing the extensions of the request. */ +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx) +{ + STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request); + int i; + int ok = 1; + + for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) { + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + /* + * XXXXX The last argument was previously (void *)ctx->extension_cb, + * but ISO C doesn't permit converting a function pointer to void *. + * For lack of better information, I'm placing a NULL there instead. + * The callback can pick its own address out from the ctx anyway... + */ + ok = (*ctx->extension_cb) (ctx, ext, NULL); + } + + return ok; +} + +/* Functions for signing the TS_TST_INFO structure of the context. */ +static int TS_RESP_sign(TS_RESP_CTX *ctx) +{ + int ret = 0; + PKCS7 *p7 = NULL; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *certs; /* Certificates to include in sc. */ + ESS_SIGNING_CERT *sc = NULL; + ASN1_OBJECT *oid; + BIO *p7bio = NULL; + int i; + + /* Check if signcert and pkey match. */ + if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + + /* Create a new PKCS7 signed object. */ + if (!(p7 = PKCS7_new())) { + TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!PKCS7_set_type(p7, NID_pkcs7_signed)) + goto err; + + /* Force SignedData version to be 3 instead of the default 1. */ + if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) + goto err; + + /* Add signer certificate and optional certificate chain. */ + if (TS_REQ_get_cert_req(ctx->request)) { + PKCS7_add_certificate(p7, ctx->signer_cert); + if (ctx->certs) { + for (i = 0; i < sk_X509_num(ctx->certs); ++i) { + X509 *cert = sk_X509_value(ctx->certs, i); + PKCS7_add_certificate(p7, cert); + } + } + } + + /* Add a new signer info. */ + if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, + ctx->signer_key, EVP_sha1()))) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR); + goto err; + } + + /* Add content type signed attribute to the signer info. */ + oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); + if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, oid)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); + goto err; + } + + /* + * Create the ESS SigningCertificate attribute which contains the signer + * certificate id and optionally the certificate chain. + */ + certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; + if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs))) + goto err; + + /* Add SigningCertificate signed attribute to the signer info. */ + if (!ESS_add_signing_cert(si, sc)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); + goto err; + } + + /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */ + if (!TS_TST_INFO_content_new(p7)) + goto err; + + /* Add the DER encoded tst_info to the PKCS7 structure. */ + if (!(p7bio = PKCS7_dataInit(p7, NULL))) { + TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Convert tst_info to DER. */ + if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); + goto err; + } + + /* Create the signature and add it to the signer info. */ + if (!PKCS7_dataFinal(p7, p7bio)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); + goto err; + } + + /* Set new PKCS7 and TST_INFO objects. */ + TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); + p7 = NULL; /* Ownership is lost. */ + ctx->tst_info = NULL; /* Ownership is lost. */ + + ret = 1; + err: + if (!ret) + TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, + "Error during signature " + "generation."); + BIO_free_all(p7bio); + ESS_SIGNING_CERT_free(sc); + PKCS7_free(p7); + return ret; +} + +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, + STACK_OF(X509) *certs) +{ + ESS_CERT_ID *cid; + ESS_SIGNING_CERT *sc = NULL; + int i; + + /* Creating the ESS_CERT_ID stack. */ + if (!(sc = ESS_SIGNING_CERT_new())) + goto err; + if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null())) + goto err; + + /* Adding the signing certificate id. */ + if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + /* Adding the certificate chain ids. */ + for (i = 0; i < sk_X509_num(certs); ++i) { + X509 *cert = sk_X509_value(certs, i); + if (!(cid = ESS_CERT_ID_new_init(cert, 1)) + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + } + + return sc; + err: + ESS_SIGNING_CERT_free(sc); + TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) +{ + ESS_CERT_ID *cid = NULL; + GENERAL_NAME *name = NULL; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + X509_check_purpose(cert, -1, 0); + + if (!(cid = ESS_CERT_ID_new())) + goto err; + if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash, + sizeof(cert->sha1_hash))) + goto err; + + /* Setting the issuer/serial if requested. */ + if (issuer_needed) { + /* Creating issuer/serial structure. */ + if (!cid->issuer_serial + && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new())) + goto err; + /* Creating general name from the certificate issuer. */ + if (!(name = GENERAL_NAME_new())) + goto err; + name->type = GEN_DIRNAME; + if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) + goto err; + if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) + goto err; + name = NULL; /* Ownership is lost. */ + /* Setting the serial number. */ + ASN1_INTEGER_free(cid->issuer_serial->serial); + if (!(cid->issuer_serial->serial = + ASN1_INTEGER_dup(cert->cert_info->serialNumber))) + goto err; + } + + return cid; + err: + GENERAL_NAME_free(name); + ESS_CERT_ID_free(cid); + TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static int TS_TST_INFO_content_new(PKCS7 *p7) +{ + PKCS7 *ret = NULL; + ASN1_OCTET_STRING *octet_string = NULL; + + /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */ + if (!(ret = PKCS7_new())) + goto err; + if (!(ret->d.other = ASN1_TYPE_new())) + goto err; + ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); + if (!(octet_string = ASN1_OCTET_STRING_new())) + goto err; + ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string); + octet_string = NULL; + + /* Add encapsulated content to signed PKCS7 structure. */ + if (!PKCS7_set_content(p7, ret)) + goto err; + + return 1; + err: + ASN1_OCTET_STRING_free(octet_string); + PKCS7_free(ret); + return 0; +} + +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) +{ + ASN1_STRING *seq = NULL; + unsigned char *p, *pp = NULL; + int len; + + len = i2d_ESS_SIGNING_CERT(sc, NULL); + if (!(pp = (unsigned char *)OPENSSL_malloc(len))) { + TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); + goto err; + } + p = pp; + i2d_ESS_SIGNING_CERT(sc, &p); + if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { + TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_free(pp); + pp = NULL; + return PKCS7_add_signed_attribute(si, + NID_id_smime_aa_signingCertificate, + V_ASN1_SEQUENCE, seq); + err: + ASN1_STRING_free(seq); + OPENSSL_free(pp); + + return 0; +} + +static ASN1_GENERALIZEDTIME +*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, + long sec, long usec, unsigned precision) +{ + time_t time_sec = (time_t)sec; + struct tm *tm = NULL; + struct tm result = {0}; + char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; + char *p = genTime_str; + char *p_end = genTime_str + sizeof(genTime_str); + + if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) + goto err; + + if (!(tm = OPENSSL_gmtime(&time_sec, &result))) + goto err; + + /* + * Put "genTime_str" in GeneralizedTime format. We work around the + * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST + * NOT include fractional seconds") and OpenSSL related functions to + * meet the rfc3161 requirement: "GeneralizedTime syntax can include + * fraction-of-second details". + */ + p += BIO_snprintf(p, p_end - p, + "%04d%02d%02d%02d%02d%02d", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + if (precision > 0) { + /* Add fraction of seconds (leave space for dot and null). */ + BIO_snprintf(p, 2 + precision, ".%06ld", usec); + /* + * We cannot use the snprintf return value, because it might have + * been truncated. + */ + p += strlen(p); + + /* + * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the + * following restrictions for a DER-encoding, which OpenSSL + * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't + * support: "The encoding MUST terminate with a "Z" (which means + * "Zulu" time). The decimal point element, if present, MUST be the + * point option ".". The fractional-seconds elements, if present, + * MUST omit all trailing 0's; if the elements correspond to 0, they + * MUST be wholly omitted, and the decimal point element also MUST be + * omitted." + */ + /* + * Remove trailing zeros. The dot guarantees the exit condition of + * this loop even if all the digits are zero. + */ + while (*--p == '0') + /* + * empty + */ ; + /* p points to either the dot or the last non-zero digit. */ + if (*p != '.') + ++p; + } + /* Add the trailing Z and the terminating null. */ + *p++ = 'Z'; + *p++ = '\0'; + + /* Now call OpenSSL to check and set our genTime value */ + if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new())) + goto err; + if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) { + ASN1_GENERALIZEDTIME_free(asn1_time); + goto err; + } + + return asn1_time; + err: + TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME); + return NULL; +} +/* crypto/ts/ts_resp_utils.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "ts.h" +// #include "pkcs7.h" + +/* Function definitions. */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info) +{ + TS_STATUS_INFO *new_status_info; + + if (a->status_info == status_info) + return 1; + new_status_info = TS_STATUS_INFO_dup(status_info); + if (new_status_info == NULL) { + TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_STATUS_INFO_free(a->status_info); + a->status_info = new_status_info; + + return 1; +} + +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a) +{ + return a->status_info; +} + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info) +{ + /* Set new PKCS7 and TST_INFO objects. */ + PKCS7_free(a->token); + a->token = p7; + TS_TST_INFO_free(a->tst_info); + a->tst_info = tst_info; +} + +PKCS7 *TS_RESP_get_token(TS_RESP *a) +{ + return a->token; +} + +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a) +{ + return a->tst_info; +} + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version) +{ + return ASN1_INTEGER_set(a->version, version); +} + +long TS_TST_INFO_get_version(const TS_TST_INFO *a) +{ + return ASN1_INTEGER_get(a->version); +} + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy) +{ + ASN1_OBJECT *new_policy; + + if (a->policy_id == policy) + return 1; + new_policy = OBJ_dup(policy); + if (new_policy == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(a->policy_id); + a->policy_id = new_policy; + return 1; +} + +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a) +{ + return a->policy_id; +} + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint) +{ + TS_MSG_IMPRINT *new_msg_imprint; + + if (a->msg_imprint == msg_imprint) + return 1; + new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); + if (new_msg_imprint == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_MSG_IMPRINT_free(a->msg_imprint); + a->msg_imprint = new_msg_imprint; + return 1; +} + +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a) +{ + return a->msg_imprint; +} + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial) +{ + ASN1_INTEGER *new_serial; + + if (a->serial == serial) + return 1; + new_serial = ASN1_INTEGER_dup(serial); + if (new_serial == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->serial); + a->serial = new_serial; + return 1; +} + +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a) +{ + return a->serial; +} + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime) +{ + ASN1_GENERALIZEDTIME *new_time; + + if (a->time == gtime) + return 1; + new_time = M_ASN1_GENERALIZEDTIME_dup(gtime); + if (new_time == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_GENERALIZEDTIME_free(a->time); + a->time = new_time; + return 1; +} + +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a) +{ + return a->time; +} + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy) +{ + TS_ACCURACY *new_accuracy; + + if (a->accuracy == accuracy) + return 1; + new_accuracy = TS_ACCURACY_dup(accuracy); + if (new_accuracy == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_ACCURACY_free(a->accuracy); + a->accuracy = new_accuracy; + return 1; +} + +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a) +{ + return a->accuracy; +} + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds) +{ + ASN1_INTEGER *new_seconds; + + if (a->seconds == seconds) + return 1; + new_seconds = ASN1_INTEGER_dup(seconds); + if (new_seconds == NULL) { + TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->seconds); + a->seconds = new_seconds; + return 1; +} + +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a) +{ + return a->seconds; +} + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis) +{ + ASN1_INTEGER *new_millis = NULL; + + if (a->millis == millis) + return 1; + if (millis != NULL) { + new_millis = ASN1_INTEGER_dup(millis); + if (new_millis == NULL) { + TSerr(TS_F_TS_ACCURACY_SET_MILLIS, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ASN1_INTEGER_free(a->millis); + a->millis = new_millis; + return 1; +} + +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a) +{ + return a->millis; +} + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros) +{ + ASN1_INTEGER *new_micros = NULL; + + if (a->micros == micros) + return 1; + if (micros != NULL) { + new_micros = ASN1_INTEGER_dup(micros); + if (new_micros == NULL) { + TSerr(TS_F_TS_ACCURACY_SET_MICROS, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ASN1_INTEGER_free(a->micros); + a->micros = new_micros; + return 1; +} + +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a) +{ + return a->micros; +} + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering) +{ + a->ordering = ordering ? 0xFF : 0x00; + return 1; +} + +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a) +{ + return a->ordering ? 1 : 0; +} + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce) +{ + ASN1_INTEGER *new_nonce; + + if (a->nonce == nonce) + return 1; + new_nonce = ASN1_INTEGER_dup(nonce); + if (new_nonce == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->nonce); + a->nonce = new_nonce; + return 1; +} + +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a) +{ + return a->nonce; +} + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa) +{ + GENERAL_NAME *new_tsa; + + if (a->tsa == tsa) + return 1; + new_tsa = GENERAL_NAME_dup(tsa); + if (new_tsa == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE); + return 0; + } + GENERAL_NAME_free(a->tsa); + a->tsa = new_tsa; + return 1; +} + +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a) +{ + return a->tsa; +} + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a) +{ + return a->extensions; +} + +void TS_TST_INFO_ext_free(TS_TST_INFO *a) +{ + if (!a) + return; + sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); + a->extensions = NULL; +} + +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a) +{ + return X509v3_get_ext_count(a->extensions); +} + +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); +} + +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos) +{ + return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); +} + +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); +} + +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc) +{ + return X509v3_get_ext(a->extensions, loc); +} + +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc) +{ + return X509v3_delete_ext(a->extensions, loc); +} + +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&a->extensions, ex, loc) != NULL; +} + +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(a->extensions, nid, crit, idx); +} +/* crypto/ts/ts_resp_verify.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "objects.h" +// #include "ts.h" +// #include "pkcs7.h" + +/* Private function declarations. */ + +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, + X509 *signer, STACK_OF(X509) **chain); +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, + STACK_OF(X509) *chain); +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo); +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, + PKCS7 *token, TS_TST_INFO *tst_info); +static int TS_check_status_info(TS_RESP *response); +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, + X509_ALGOR **md_alg, + unsigned char **imprint, unsigned *imprint_len); +static int TS_check_imprints(X509_ALGOR *algor_a, + unsigned char *imprint_a, unsigned len_a, + TS_TST_INFO *tst_info); +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, + GENERAL_NAME *name); + +/* + * Local mapping between response codes and descriptions. + * Don't forget to change TS_STATUS_BUF_SIZE when modifying + * the elements of this array. + */ +static const char *TS_status_text[] = { "granted", + "grantedWithMods", + "rejection", + "waiting", + "revocationWarning", + "revocationNotification" +}; + +#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) + +/* + * This must be greater or equal to the sum of the strings in TS_status_text + * plus the number of its elements. + */ +#define TS_STATUS_BUF_SIZE 256 + +static struct { + int code; + const char *text; +} TS_failure_info[] = { + { + TS_INFO_BAD_ALG, "badAlg" + }, + { + TS_INFO_BAD_REQUEST, "badRequest" + }, + { + TS_INFO_BAD_DATA_FORMAT, "badDataFormat" + }, + { + TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" + }, + { + TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" + }, + { + TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" + }, + { + TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" + }, + { + TS_INFO_SYSTEM_FAILURE, "systemFailure" + } +}; + +#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ + sizeof(*TS_failure_info)) + +/* Functions for verifying a signed TS_TST_INFO structure. */ + +/*- + * This function carries out the following tasks: + * - Checks if there is one and only one signer. + * - Search for the signing certificate in 'certs' and in the response. + * - Check the extended key usage and key usage fields of the signer + * certificate (done by the path validation). + * - Build and validate the certificate path. + * - Check if the certificate path meets the requirements of the + * SigningCertificate ESS signed attribute. + * - Verify the signature value. + * - Returns the signer certificate in 'signer', if 'signer' is not NULL. + */ +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out) +{ + STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *signers = NULL; + X509 *signer; + STACK_OF(X509) *chain = NULL; + char buf[4096]; + int i, j = 0, ret = 0; + BIO *p7bio = NULL; + + /* Some sanity checks first. */ + if (!token) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER); + goto err; + } + + /* Check for the correct content type */ + if (!PKCS7_type_is_signed(token)) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE); + goto err; + } + + /* Check if there is one and only one signer. */ + sinfos = PKCS7_get_signer_info(token); + if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_THERE_MUST_BE_ONE_SIGNER); + goto err; + } + si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); + + /* Check for no content: no data to verify signature. */ + if (PKCS7_get_detached(token)) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT); + goto err; + } + + /* + * Get hold of the signer certificate, search only internal certificates + * if it was requested. + */ + signers = PKCS7_get0_signers(token, certs, 0); + if (!signers || sk_X509_num(signers) != 1) + goto err; + signer = sk_X509_value(signers, 0); + + /* Now verify the certificate. */ + if (!TS_verify_cert(store, certs, signer, &chain)) + goto err; + + /* + * Check if the signer certificate is consistent with the ESS extension. + */ + if (!TS_check_signing_certs(si, chain)) + goto err; + + /* Creating the message digest. */ + p7bio = PKCS7_dataInit(token, NULL); + + /* We now have to 'read' from p7bio to calculate digests etc. */ + while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0) ; + + /* Verifying the signature. */ + j = PKCS7_signatureVerify(p7bio, token, si, signer); + if (j <= 0) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE); + goto err; + } + + /* Return the signer certificate if needed. */ + if (signer_out) { + *signer_out = signer; + CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); + } + + ret = 1; + + err: + BIO_free_all(p7bio); + sk_X509_pop_free(chain, X509_free); + sk_X509_free(signers); + + return ret; +} + +/* + * The certificate chain is returned in chain. Caller is responsible for + * freeing the vector. + */ +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, + X509 *signer, STACK_OF(X509) **chain) +{ + X509_STORE_CTX cert_ctx; + int i; + int ret = 1; + + /* chain is an out argument. */ + *chain = NULL; + if (!X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted)) + return 0; + X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); + i = X509_verify_cert(&cert_ctx); + if (i <= 0) { + int j = X509_STORE_CTX_get_error(&cert_ctx); + TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(j)); + ret = 0; + } else { + /* Get a copy of the certificate chain. */ + *chain = X509_STORE_CTX_get1_chain(&cert_ctx); + } + + X509_STORE_CTX_cleanup(&cert_ctx); + + return ret; +} + +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, + STACK_OF(X509) *chain) +{ + ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); + STACK_OF(ESS_CERT_ID) *cert_ids = NULL; + X509 *cert; + int i = 0; + int ret = 0; + + if (!ss) + goto err; + cert_ids = ss->cert_ids; + /* The signer certificate must be the first in cert_ids. */ + cert = sk_X509_value(chain, 0); + if (TS_find_cert(cert_ids, cert) != 0) + goto err; + + /* + * Check the other certificates of the chain if there are more than one + * certificate ids in cert_ids. + */ + if (sk_ESS_CERT_ID_num(cert_ids) > 1) { + /* All the certificates of the chain must be in cert_ids. */ + for (i = 1; i < sk_X509_num(chain); ++i) { + cert = sk_X509_value(chain, i); + if (TS_find_cert(cert_ids, cert) < 0) + goto err; + } + } + ret = 1; + err: + if (!ret) + TSerr(TS_F_TS_CHECK_SIGNING_CERTS, + TS_R_ESS_SIGNING_CERTIFICATE_ERROR); + ESS_SIGNING_CERT_free(ss); + return ret; +} + +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) +{ + ASN1_TYPE *attr; + const unsigned char *p; + attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate); + if (!attr) + return NULL; + p = attr->value.sequence->data; + return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); +} + +/* Returns < 0 if certificate is not found, certificate index otherwise. */ +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) +{ + int i; + + if (!cert_ids || !cert) + return -1; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + X509_check_purpose(cert, -1, 0); + + /* Look for cert in the cert_ids vector. */ + for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { + ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); + + /* Check the SHA-1 hash first. */ + if (cid->hash->length == sizeof(cert->sha1_hash) + && !memcmp(cid->hash->data, cert->sha1_hash, + sizeof(cert->sha1_hash))) { + /* Check the issuer/serial as well if specified. */ + ESS_ISSUER_SERIAL *is = cid->issuer_serial; + if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) + return i; + } + } + + return -1; +} + +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo) +{ + GENERAL_NAME *issuer; + + if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) + return -1; + + /* Check the issuer first. It must be a directory name. */ + issuer = sk_GENERAL_NAME_value(is->issuer, 0); + if (issuer->type != GEN_DIRNAME + || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer)) + return -1; + + /* Check the serial number, too. */ + if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber)) + return -1; + + return 0; +} + +/*- + * Verifies whether 'response' contains a valid response with regards + * to the settings of the context: + * - Gives an error message if the TS_TST_INFO is not present. + * - Calls _TS_RESP_verify_token to verify the token content. + */ +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) +{ + PKCS7 *token = TS_RESP_get_token(response); + TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); + int ret = 0; + + /* Check if we have a successful TS_TST_INFO object in place. */ + if (!TS_check_status_info(response)) + goto err; + + /* Check the contents of the time stamp token. */ + if (!int_TS_RESP_verify_token(ctx, token, tst_info)) + goto err; + + ret = 1; + err: + return ret; +} + +/* + * Tries to extract a TS_TST_INFO structure from the PKCS7 token and + * calls the internal int_TS_RESP_verify_token function for verifying it. + */ +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) +{ + TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); + int ret = 0; + if (tst_info) { + ret = int_TS_RESP_verify_token(ctx, token, tst_info); + TS_TST_INFO_free(tst_info); + } + return ret; +} + +/*- + * Verifies whether the 'token' contains a valid time stamp token + * with regards to the settings of the context. Only those checks are + * carried out that are specified in the context: + * - Verifies the signature of the TS_TST_INFO. + * - Checks the version number of the response. + * - Check if the requested and returned policies math. + * - Check if the message imprints are the same. + * - Check if the nonces are the same. + * - Check if the TSA name matches the signer. + * - Check if the TSA name is the expected TSA. + */ +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, + PKCS7 *token, TS_TST_INFO *tst_info) +{ + X509 *signer = NULL; + GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); + X509_ALGOR *md_alg = NULL; + unsigned char *imprint = NULL; + unsigned imprint_len = 0; + int ret = 0; + int flags = ctx->flags; + + /* Some options require us to also check the signature */ + if (((flags & TS_VFY_SIGNER) && tsa_name != NULL) + || (flags & TS_VFY_TSA_NAME)) { + flags |= TS_VFY_SIGNATURE; + } + + /* Verify the signature. */ + if ((flags & TS_VFY_SIGNATURE) + && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer)) + goto err; + + /* Check version number of response. */ + if ((flags & TS_VFY_VERSION) + && TS_TST_INFO_get_version(tst_info) != 1) { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); + goto err; + } + + /* Check policies. */ + if ((flags & TS_VFY_POLICY) + && !TS_check_policy(ctx->policy, tst_info)) + goto err; + + /* Check message imprints. */ + if ((flags & TS_VFY_IMPRINT) + && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, + tst_info)) + goto err; + + /* Compute and check message imprints. */ + if ((flags & TS_VFY_DATA) + && (!TS_compute_imprint(ctx->data, tst_info, + &md_alg, &imprint, &imprint_len) + || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) + goto err; + + /* Check nonces. */ + if ((flags & TS_VFY_NONCE) + && !TS_check_nonces(ctx->nonce, tst_info)) + goto err; + + /* Check whether TSA name and signer certificate match. */ + if ((flags & TS_VFY_SIGNER) + && tsa_name && !TS_check_signer_name(tsa_name, signer)) { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); + goto err; + } + + /* Check whether the TSA is the expected one. */ + if ((flags & TS_VFY_TSA_NAME) + && !TS_check_signer_name(ctx->tsa_name, signer)) { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); + goto err; + } + + ret = 1; + err: + X509_free(signer); + X509_ALGOR_free(md_alg); + OPENSSL_free(imprint); + return ret; +} + +static int TS_check_status_info(TS_RESP *response) +{ + TS_STATUS_INFO *info = TS_RESP_get_status_info(response); + long status = ASN1_INTEGER_get(info->status); + const char *status_text = NULL; + char *embedded_status_text = NULL; + char failure_text[TS_STATUS_BUF_SIZE] = ""; + + /* Check if everything went fine. */ + if (status == 0 || status == 1) + return 1; + + /* There was an error, get the description in status_text. */ + if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE) + status_text = TS_status_text[status]; + else + status_text = "unknown code"; + + /* Set the embedded_status_text to the returned description. */ + if (sk_ASN1_UTF8STRING_num(info->text) > 0 + && !(embedded_status_text = TS_get_status_text(info->text))) + return 0; + + /* Filling in failure_text with the failure information. */ + if (info->failure_info) { + int i; + int first = 1; + for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) { + if (ASN1_BIT_STRING_get_bit(info->failure_info, + TS_failure_info[i].code)) { + if (!first) + strcat(failure_text, ","); + else + first = 0; + strcat(failure_text, TS_failure_info[i].text); + } + } + } + if (failure_text[0] == '\0') + strcpy(failure_text, "unspecified"); + + /* Making up the error string. */ + TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN); + ERR_add_error_data(6, + "status code: ", status_text, + ", status text: ", embedded_status_text ? + embedded_status_text : "unspecified", + ", failure codes: ", failure_text); + OPENSSL_free(embedded_status_text); + + return 0; +} + +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) +{ + int i; + int length = 0; + char *result = NULL; + char *p; + + /* Determine length first. */ + for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) { + ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + if (ASN1_STRING_length(current) > TS_MAX_STATUS_LENGTH - length - 1) + return NULL; + length += ASN1_STRING_length(current); + length += 1; /* separator character */ + } + /* Allocate memory (closing '\0' included). */ + if (!(result = OPENSSL_malloc(length))) { + TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Concatenate the descriptions. */ + for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) { + ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + length = ASN1_STRING_length(current); + if (i > 0) + *p++ = '/'; + strncpy(p, (const char *)ASN1_STRING_data(current), length); + p += length; + } + /* We do have space for this, too. */ + *p = '\0'; + + return result; +} + +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) +{ + ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); + + if (OBJ_cmp(req_oid, resp_oid) != 0) { + TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH); + return 0; + } + + return 1; +} + +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, + X509_ALGOR **md_alg, + unsigned char **imprint, unsigned *imprint_len) +{ + TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); + X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); + const EVP_MD *md; + EVP_MD_CTX md_ctx; + unsigned char buffer[4096]; + int length; + + *md_alg = NULL; + *imprint = NULL; + + /* Return the MD algorithm of the response. */ + if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) + goto err; + + /* Getting the MD object. */ + if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) { + TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM); + goto err; + } + + /* Compute message digest. */ + length = EVP_MD_size(md); + if (length < 0) + goto err; + *imprint_len = length; + if (!(*imprint = OPENSSL_malloc(*imprint_len))) { + TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestInit(&md_ctx, md)) + goto err; + while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) { + if (!EVP_DigestUpdate(&md_ctx, buffer, length)) + goto err; + } + if (!EVP_DigestFinal(&md_ctx, *imprint, NULL)) + goto err; + + return 1; + err: + X509_ALGOR_free(*md_alg); + OPENSSL_free(*imprint); + *imprint_len = 0; + *imprint = 0; + return 0; +} + +static int TS_check_imprints(X509_ALGOR *algor_a, + unsigned char *imprint_a, unsigned len_a, + TS_TST_INFO *tst_info) +{ + TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); + X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); + int ret = 0; + + /* algor_a is optional. */ + if (algor_a) { + /* Compare algorithm OIDs. */ + if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) + goto err; + + /* The parameter must be NULL in both. */ + if ((algor_a->parameter + && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) + || (algor_b->parameter + && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL)) + goto err; + } + + /* Compare octet strings. */ + ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) && + memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0; + err: + if (!ret) + TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH); + return ret; +} + +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) +{ + const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); + + /* Error if nonce is missing. */ + if (!b) { + TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED); + return 0; + } + + /* No error if a nonce is returned without being requested. */ + if (ASN1_INTEGER_cmp(a, b) != 0) { + TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH); + return 0; + } + + return 1; +} + +/* + * Check if the specified TSA name matches either the subject or one of the + * subject alternative names of the TSA certificate. + */ +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) +{ + STACK_OF(GENERAL_NAME) *gen_names = NULL; + int idx = -1; + int found = 0; + + /* Check the subject name first. */ + if (tsa_name->type == GEN_DIRNAME + && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0) + return 1; + + /* Check all the alternative names. */ + gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx); + while (gen_names != NULL + && !(found = TS_find_name(gen_names, tsa_name) >= 0)) { + /* + * Get the next subject alternative name, although there should be no + * more than one. + */ + GENERAL_NAMES_free(gen_names); + gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, + NULL, &idx); + } + if (gen_names) + GENERAL_NAMES_free(gen_names); + + return found; +} + +/* Returns 1 if name is in gen_names, 0 otherwise. */ +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) +{ + int i, found; + for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); ++i) { + GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); + found = GENERAL_NAME_cmp(current, name) == 0; + } + return found ? i - 1 : -1; +} +/* crypto/ts/ts_verify_ctx.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +// #include "cryptlib.h" +// #include "objects.h" +// #include "ts.h" + +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void) +{ + TS_VERIFY_CTX *ctx = + (TS_VERIFY_CTX *)OPENSSL_malloc(sizeof(TS_VERIFY_CTX)); + if (ctx) + memset(ctx, 0, sizeof(TS_VERIFY_CTX)); + else + TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE); + return ctx; +} + +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx) +{ + OPENSSL_assert(ctx != NULL); + memset(ctx, 0, sizeof(TS_VERIFY_CTX)); +} + +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx) +{ + if (!ctx) + return; + + TS_VERIFY_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx) +{ + if (!ctx) + return; + + X509_STORE_free(ctx->store); + sk_X509_pop_free(ctx->certs, X509_free); + + ASN1_OBJECT_free(ctx->policy); + + X509_ALGOR_free(ctx->md_alg); + OPENSSL_free(ctx->imprint); + + BIO_free_all(ctx->data); + + ASN1_INTEGER_free(ctx->nonce); + + GENERAL_NAME_free(ctx->tsa_name); + + TS_VERIFY_CTX_init(ctx); +} + +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx) +{ + TS_VERIFY_CTX *ret = ctx; + ASN1_OBJECT *policy; + TS_MSG_IMPRINT *imprint; + X509_ALGOR *md_alg; + ASN1_OCTET_STRING *msg; + const ASN1_INTEGER *nonce; + + OPENSSL_assert(req != NULL); + if (ret) + TS_VERIFY_CTX_cleanup(ret); + else if (!(ret = TS_VERIFY_CTX_new())) + return NULL; + + /* Setting flags. */ + ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE); + + /* Setting policy. */ + if ((policy = TS_REQ_get_policy_id(req)) != NULL) { + if (!(ret->policy = OBJ_dup(policy))) + goto err; + } else + ret->flags &= ~TS_VFY_POLICY; + + /* Setting md_alg, imprint and imprint_len. */ + imprint = TS_REQ_get_msg_imprint(req); + md_alg = TS_MSG_IMPRINT_get_algo(imprint); + if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) + goto err; + msg = TS_MSG_IMPRINT_get_msg(imprint); + ret->imprint_len = ASN1_STRING_length(msg); + if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) + goto err; + memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len); + + /* Setting nonce. */ + if ((nonce = TS_REQ_get_nonce(req)) != NULL) { + if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) + goto err; + } else + ret->flags &= ~TS_VFY_NONCE; + + return ret; + err: + if (ctx) + TS_VERIFY_CTX_cleanup(ctx); + else + TS_VERIFY_CTX_free(ret); + return NULL; +} diff --git a/Sources/COpenSSL/txt_db.c b/Sources/COpenSSL/txt_db.c new file mode 100644 index 00000000..ae2d2e10 --- /dev/null +++ b/Sources/COpenSSL/txt_db.c @@ -0,0 +1,397 @@ +/* crypto/txt_db/txt_db.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" +#include "buffer.h" +#include "txt_db.h" + +#undef BUFSIZE +#define BUFSIZE 512 + +const char TXT_DB_version[] = "TXT_DB" OPENSSL_VERSION_PTEXT; + +TXT_DB *TXT_DB_read(BIO *in, int num) +{ + TXT_DB *ret = NULL; + int er = 1; + int esc = 0; + long ln = 0; + int i, add, n; + int size = BUFSIZE; + int offset = 0; + char *p, *f; + OPENSSL_STRING *pp; + BUF_MEM *buf = NULL; + + if ((buf = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(buf, size)) + goto err; + + if ((ret = OPENSSL_malloc(sizeof(TXT_DB))) == NULL) + goto err; + ret->num_fields = num; + ret->index = NULL; + ret->qual = NULL; + if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL) + goto err; + if ((ret->index = OPENSSL_malloc(sizeof(*ret->index) * num)) == NULL) + goto err; + if ((ret->qual = OPENSSL_malloc(sizeof(*(ret->qual)) * num)) == NULL) + goto err; + for (i = 0; i < num; i++) { + ret->index[i] = NULL; + ret->qual[i] = NULL; + } + + add = (num + 1) * sizeof(char *); + buf->data[size - 1] = '\0'; + offset = 0; + for (;;) { + if (offset != 0) { + size += BUFSIZE; + if (!BUF_MEM_grow_clean(buf, size)) + goto err; + } + buf->data[offset] = '\0'; + BIO_gets(in, &(buf->data[offset]), size - offset); + ln++; + if (buf->data[offset] == '\0') + break; + if ((offset == 0) && (buf->data[0] == '#')) + continue; + i = strlen(&(buf->data[offset])); + offset += i; + if (buf->data[offset - 1] != '\n') + continue; + else { + buf->data[offset - 1] = '\0'; /* blat the '\n' */ + if (!(p = OPENSSL_malloc(add + offset))) + goto err; + offset = 0; + } + pp = (char **)p; + p += add; + n = 0; + pp[n++] = p; + i = 0; + f = buf->data; + + esc = 0; + for (;;) { + if (*f == '\0') + break; + if (*f == '\t') { + if (esc) + p--; + else { + *(p++) = '\0'; + f++; + if (n >= num) + break; + pp[n++] = p; + continue; + } + } + esc = (*f == '\\'); + *(p++) = *(f++); + } + *(p++) = '\0'; + if ((n != num) || (*f != '\0')) { +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary + * fix :-( */ + fprintf(stderr, + "wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n", + ln, num, n, f); +#endif + OPENSSL_free(pp); + er = 2; + goto err; + } + pp[n] = p; + if (!sk_OPENSSL_PSTRING_push(ret->data, pp)) { +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary + * fix :-( */ + fprintf(stderr, "failure in sk_push\n"); +#endif + OPENSSL_free(pp); + er = 2; + goto err; + } + } + er = 0; + err: + BUF_MEM_free(buf); + if (er) { +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) + if (er == 1) + fprintf(stderr, "OPENSSL_malloc failure\n"); +#endif + if (ret != NULL) { + if (ret->data != NULL) + sk_OPENSSL_PSTRING_free(ret->data); + if (ret->index != NULL) + OPENSSL_free(ret->index); + if (ret->qual != NULL) + OPENSSL_free(ret->qual); + if (ret != NULL) + OPENSSL_free(ret); + } + return (NULL); + } else + return (ret); +} + +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, + OPENSSL_STRING *value) +{ + OPENSSL_STRING *ret; + LHASH_OF(OPENSSL_STRING) *lh; + + if (idx >= db->num_fields) { + db->error = DB_ERROR_INDEX_OUT_OF_RANGE; + return (NULL); + } + lh = db->index[idx]; + if (lh == NULL) { + db->error = DB_ERROR_NO_INDEX; + return (NULL); + } + ret = lh_OPENSSL_STRING_retrieve(lh, value); + db->error = DB_ERROR_OK; + return (ret); +} + +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) +{ + LHASH_OF(OPENSSL_STRING) *idx; + OPENSSL_STRING *r, *k; + int i, n; + + if (field >= db->num_fields) { + db->error = DB_ERROR_INDEX_OUT_OF_RANGE; + return (0); + } + /* FIXME: we lose type checking at this point */ + if ((idx = (LHASH_OF(OPENSSL_STRING) *)lh_new(hash, cmp)) == NULL) { + db->error = DB_ERROR_MALLOC; + return (0); + } + n = sk_OPENSSL_PSTRING_num(db->data); + for (i = 0; i < n; i++) { + r = sk_OPENSSL_PSTRING_value(db->data, i); + if ((qual != NULL) && (qual(r) == 0)) + continue; + if ((k = lh_OPENSSL_STRING_insert(idx, r)) != NULL) { + db->error = DB_ERROR_INDEX_CLASH; + db->arg1 = sk_OPENSSL_PSTRING_find(db->data, k); + db->arg2 = i; + lh_OPENSSL_STRING_free(idx); + return (0); + } + if (lh_OPENSSL_STRING_retrieve(idx, r) == NULL) { + db->error = DB_ERROR_MALLOC; + lh_OPENSSL_STRING_free(idx); + return (0); + } + } + if (db->index[field] != NULL) + lh_OPENSSL_STRING_free(db->index[field]); + db->index[field] = idx; + db->qual[field] = qual; + return (1); +} + +long TXT_DB_write(BIO *out, TXT_DB *db) +{ + long i, j, n, nn, l, tot = 0; + char *p, **pp, *f; + BUF_MEM *buf = NULL; + long ret = -1; + + if ((buf = BUF_MEM_new()) == NULL) + goto err; + n = sk_OPENSSL_PSTRING_num(db->data); + nn = db->num_fields; + for (i = 0; i < n; i++) { + pp = sk_OPENSSL_PSTRING_value(db->data, i); + + l = 0; + for (j = 0; j < nn; j++) { + if (pp[j] != NULL) + l += strlen(pp[j]); + } + if (!BUF_MEM_grow_clean(buf, (int)(l * 2 + nn))) + goto err; + + p = buf->data; + for (j = 0; j < nn; j++) { + f = pp[j]; + if (f != NULL) + for (;;) { + if (*f == '\0') + break; + if (*f == '\t') + *(p++) = '\\'; + *(p++) = *(f++); + } + *(p++) = '\t'; + } + p[-1] = '\n'; + j = p - buf->data; + if (BIO_write(out, buf->data, (int)j) != j) + goto err; + tot += j; + } + ret = tot; + err: + if (buf != NULL) + BUF_MEM_free(buf); + return (ret); +} + +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row) +{ + int i; + OPENSSL_STRING *r; + + for (i = 0; i < db->num_fields; i++) { + if (db->index[i] != NULL) { + if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) + continue; + r = lh_OPENSSL_STRING_retrieve(db->index[i], row); + if (r != NULL) { + db->error = DB_ERROR_INDEX_CLASH; + db->arg1 = i; + db->arg_row = r; + goto err; + } + } + } + + for (i = 0; i < db->num_fields; i++) { + if (db->index[i] != NULL) { + if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) + continue; + (void)lh_OPENSSL_STRING_insert(db->index[i], row); + if (lh_OPENSSL_STRING_retrieve(db->index[i], row) == NULL) + goto err1; + } + } + if (!sk_OPENSSL_PSTRING_push(db->data, row)) + goto err1; + return (1); + + err1: + db->error = DB_ERROR_MALLOC; + while (i-- > 0) { + if (db->index[i] != NULL) { + if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) + continue; + (void)lh_OPENSSL_STRING_delete(db->index[i], row); + } + } + err: + return (0); +} + +void TXT_DB_free(TXT_DB *db) +{ + int i, n; + char **p, *max; + + if (db == NULL) + return; + + if (db->index != NULL) { + for (i = db->num_fields - 1; i >= 0; i--) + if (db->index[i] != NULL) + lh_OPENSSL_STRING_free(db->index[i]); + OPENSSL_free(db->index); + } + if (db->qual != NULL) + OPENSSL_free(db->qual); + if (db->data != NULL) { + for (i = sk_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) { + /* + * check if any 'fields' have been allocated from outside of the + * initial block + */ + p = sk_OPENSSL_PSTRING_value(db->data, i); + max = p[db->num_fields]; /* last address */ + if (max == NULL) { /* new row */ + for (n = 0; n < db->num_fields; n++) + if (p[n] != NULL) + OPENSSL_free(p[n]); + } else { + for (n = 0; n < db->num_fields; n++) { + if (((p[n] < (char *)p) || (p[n] > max)) + && (p[n] != NULL)) + OPENSSL_free(p[n]); + } + } + OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data, i)); + } + sk_OPENSSL_PSTRING_free(db->data); + } + OPENSSL_free(db); +} diff --git a/Sources/COpenSSL/txt_db.h b/Sources/COpenSSL/txt_db.h new file mode 100644 index 00000000..e16e960e --- /dev/null +++ b/Sources/COpenSSL/txt_db.h @@ -0,0 +1,112 @@ +/* crypto/txt_db/txt_db.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_TXT_DB_H +# define HEADER_TXT_DB_H + +# include "opensslconf.h" +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# include "stack.h" +# include "lhash.h" + +# define DB_ERROR_OK 0 +# define DB_ERROR_MALLOC 1 +# define DB_ERROR_INDEX_CLASH 2 +# define DB_ERROR_INDEX_OUT_OF_RANGE 3 +# define DB_ERROR_NO_INDEX 4 +# define DB_ERROR_INSERT_INDEX_CLASH 5 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + +typedef struct txt_db_st { + int num_fields; + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual) (OPENSSL_STRING *); + long error; + long arg1; + long arg2; + OPENSSL_STRING *arg_row; +} TXT_DB; + +# ifndef OPENSSL_NO_BIO +TXT_DB *TXT_DB_read(BIO *in, int num); +long TXT_DB_write(BIO *out, TXT_DB *db); +# else +TXT_DB *TXT_DB_read(char *in, int num); +long TXT_DB_write(char *out, TXT_DB *db); +# endif +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); +void TXT_DB_free(TXT_DB *db); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, + OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/ui.h b/Sources/COpenSSL/ui.h new file mode 100644 index 00000000..f6154e07 --- /dev/null +++ b/Sources/COpenSSL/ui.h @@ -0,0 +1,415 @@ +/* crypto/ui/ui.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_H +# define HEADER_UI_H + +# ifndef OPENSSL_NO_DEPRECATED +# include "crypto.h" +# endif +# include "safestack.h" +# include "ossl_typ.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct ui_st UI; */ +/* typedef struct ui_method_st UI_METHOD; */ + +/* + * All the following functions return -1 or NULL on error and in some cases + * (UI_process()) -2 if interrupted or in some other way cancelled. When + * everything is fine, they return 0, a positive value or a non-NULL pointer, + * all depending on their purpose. + */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/*- + The following functions are used to add strings to be printed and prompt + strings to prompt for data. The names are UI_{add,dup}__string + and UI_{add,dup}_input_boolean. + + UI_{add,dup}__string have the following meanings: + add add a text or prompt string. The pointers given to these + functions are used verbatim, no copying is done. + dup make a copy of the text or prompt string, then add the copy + to the collection of strings in the user interface. + + The function is a name for the functionality that the given + string shall be used for. It can be one of: + input use the string as data prompt. + verify use the string as verification prompt. This + is used to verify a previous input. + info use the string for informational output. + error use the string for error output. + Honestly, there's currently no difference between info and error for the + moment. + + UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + and are typically used when one wants to prompt for a yes/no response. + + All of the functions in this group take a UI and a prompt string. + The string input and verify addition functions also take a flag argument, + a buffer for the result to end up with, a minimum input size and a maximum + input size (the result buffer MUST be large enough to be able to contain + the maximum number of characters). Additionally, the verify addition + functions takes another buffer to compare the result against. + The boolean input functions take an action description string (which should + be safe to ignore if the expected user action is obvious, for example with + a dialog box with an OK button and a Cancel button), a string of acceptable + characters to mean OK and to mean Cancel. The two last strings are checked + to make sure they don't have common characters. Additionally, the same + flag argument as for the string input is taken, as well as a result buffer. + The result buffer is required to be at least one byte long. Depending on + the answer, the first character from the OK or the Cancel character strings + will be stored in the first byte of the result buffer. No NUL will be + added, so the result is *not* a string. + + On success, the all return an index of the added information. That index + is usefull when retrieving results with UI_get0_result(). */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +# define UI_INPUT_FLAG_ECHO 0x01 +/* + * Use a default password. Where that password is found is completely up to + * the application, it might for example be in the user data set with + * UI_add_user_data(). It is not recommended to have more than one input in + * each UI being marked with this flag, or the application might get + * confused. + */ +# define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/*- + * The user of these routines may want to define flags of their own. The core + * UI won't look at those, but will pass them on to the method routines. They + * must use higher bits so they don't get confused with the UI bits above. + * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + * example of use is this: + * + * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + * +*/ +# define UI_INPUT_FLAG_USER_BASE 16 + +/*- + * The following function helps construct a prompt. object_desc is a + * textual short description of the object, for example "pass phrase", + * and object_name is the name of the object (might be a card name or + * a file name. + * The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + * + * If the ui_method doesn't contain a pointer to a user-defined prompt + * constructor, a default string is built, looking like this: + * + * "Enter {object_desc} for {object_name}:" + * + * So, if object_desc has the value "pass phrase" and object_name has + * the value "foo.key", the resulting string is: + * + * "Enter pass phrase for foo.key:" +*/ +char *UI_construct_prompt(UI *ui_method, + const char *object_desc, const char *object_name); + +/* + * The following function is used to store a pointer to user-specific data. + * Any previous such pointer will be returned and replaced. + * + * For callback purposes, this function makes a lot more sense than using + * ex_data, since the latter requires that different parts of OpenSSL or + * applications share the same ex_data index. + * + * Note that the UI_OpenSSL() method completely ignores the user data. Other + * methods may not, however. + */ +void *UI_add_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* + * Give a user interface parametrised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as be + * used to get information from a UI. + */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)); + +/* The commands */ +/* + * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + * OpenSSL error stack before printing any info or added error messages and + * before any prompting. + */ +# define UI_CTRL_PRINT_ERRORS 1 +/* + * Check if a UI_process() is possible to do again with the same instance of + * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + * if not. + */ +# define UI_CTRL_IS_REDOABLE 2 + +/* Some methods may use extra data */ +# define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +# define UI_get_app_data(s) UI_get_ex_data(s,0) +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + +/* ---------- For method writers ---------- */ +/*- + A method contains a number of functions that implement the low level + of the User Interface. The functions are: + + an opener This function starts a session, maybe by opening + a channel to a tty, or by opening a window. + a writer This function is called to write a given string, + maybe to the tty, maybe as a field label in a + window. + a flusher This function is called to flush everything that + has been output so far. It can be used to actually + display a dialog box after it has been built. + a reader This function is called to read a given prompt, + maybe from the tty, maybe from a field in a + window. Note that it's called wth all string + structures, not only the prompt ones, so it must + check such things itself. + a closer This function closes the session, maybe by closing + the channel to the tty, or closing the window. + + All these functions are expected to return: + + 0 on error. + 1 on success. + -1 on out-of-band events, for example if some prompting has + been canceled (by pressing Ctrl-C, for example). This is + only checked when returned by the flusher or the reader. + + The way this is used, the opener is first called, then the writer for all + strings, then the flusher, then the reader for all strings and finally the + closer. Note that if you want to prompt from a terminal or other command + line interface, the best is to have the reader also write the prompts + instead of having the writer do it. If you want to prompt from a dialog + box, the writer can be used to build up the contents of the box, and the + flusher to actually display the box and run the event loop until all data + has been given, after which the reader only grabs the given data and puts + them back into the UI strings. + + All method functions take a UI as argument. Additionally, the writer and + the reader take a UI_STRING. +*/ + +/* + * The UI_STRING type is the data structure that contains all the needed info + * about a string or a prompt, including test data for a verification prompt. + */ +typedef struct ui_string_st UI_STRING; +DECLARE_STACK_OF(UI_STRING) + +/* + * The different types of strings that are currently supported. This is only + * needed by method authors. + */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)); +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)); +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)); +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *object_desc, + const char + *object_name)); +int (*UI_method_get_opener(UI_METHOD *method)) (UI *); +int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_flusher(UI_METHOD *method)) (UI *); +int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_closer(UI_METHOD *method)) (UI *); +char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *, + const char *, + const char *); + +/* + * The following functions are helpers for method writers to access relevant + * data from a UI_STRING. + */ + +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* + * Return the optional action string to output (the boolean promtp + * instruction) + */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +/* + * Return the string to test the result against. Only useful with verifies. + */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_UI_strings(void); + +/* Error codes for the UI functions. */ + +/* Function codes. */ +# define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 +# define UI_F_GENERAL_ALLOCATE_PROMPT 109 +# define UI_F_GENERAL_ALLOCATE_STRING 100 +# define UI_F_UI_CTRL 111 +# define UI_F_UI_DUP_ERROR_STRING 101 +# define UI_F_UI_DUP_INFO_STRING 102 +# define UI_F_UI_DUP_INPUT_BOOLEAN 110 +# define UI_F_UI_DUP_INPUT_STRING 103 +# define UI_F_UI_DUP_VERIFY_STRING 106 +# define UI_F_UI_GET0_RESULT 107 +# define UI_F_UI_NEW_METHOD 104 +# define UI_F_UI_SET_RESULT 105 + +/* Reason codes. */ +# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 +# define UI_R_INDEX_TOO_LARGE 102 +# define UI_R_INDEX_TOO_SMALL 103 +# define UI_R_NO_RESULT_BUFFER 105 +# define UI_R_RESULT_TOO_LARGE 100 +# define UI_R_RESULT_TOO_SMALL 101 +# define UI_R_UNKNOWN_CONTROL_COMMAND 106 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ui_.c b/Sources/COpenSSL/ui_.c new file mode 100644 index 00000000..191306b5 --- /dev/null +++ b/Sources/COpenSSL/ui_.c @@ -0,0 +1,1899 @@ +/* crypto/ui/ui_compat.c */ +/* ==================================================================== + * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ui_compat.h" + +int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, + int verify) +{ + return UI_UTIL_read_pw_string(buf, length, prompt, verify); +} + +int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify) +{ + return UI_UTIL_read_pw(buf, buff, size, prompt, verify); +} +/* crypto/ui/ui_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "ui.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_UI,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_UI,0,reason) + +static ERR_STRING_DATA UI_str_functs[] = { + {ERR_FUNC(UI_F_GENERAL_ALLOCATE_BOOLEAN), "GENERAL_ALLOCATE_BOOLEAN"}, + {ERR_FUNC(UI_F_GENERAL_ALLOCATE_PROMPT), "GENERAL_ALLOCATE_PROMPT"}, + {ERR_FUNC(UI_F_GENERAL_ALLOCATE_STRING), "GENERAL_ALLOCATE_STRING"}, + {ERR_FUNC(UI_F_UI_CTRL), "UI_ctrl"}, + {ERR_FUNC(UI_F_UI_DUP_ERROR_STRING), "UI_dup_error_string"}, + {ERR_FUNC(UI_F_UI_DUP_INFO_STRING), "UI_dup_info_string"}, + {ERR_FUNC(UI_F_UI_DUP_INPUT_BOOLEAN), "UI_dup_input_boolean"}, + {ERR_FUNC(UI_F_UI_DUP_INPUT_STRING), "UI_dup_input_string"}, + {ERR_FUNC(UI_F_UI_DUP_VERIFY_STRING), "UI_dup_verify_string"}, + {ERR_FUNC(UI_F_UI_GET0_RESULT), "UI_get0_result"}, + {ERR_FUNC(UI_F_UI_NEW_METHOD), "UI_new_method"}, + {ERR_FUNC(UI_F_UI_SET_RESULT), "UI_set_result"}, + {0, NULL} +}; + +static ERR_STRING_DATA UI_str_reasons[] = { + {ERR_REASON(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS), + "common ok and cancel characters"}, + {ERR_REASON(UI_R_INDEX_TOO_LARGE), "index too large"}, + {ERR_REASON(UI_R_INDEX_TOO_SMALL), "index too small"}, + {ERR_REASON(UI_R_NO_RESULT_BUFFER), "no result buffer"}, + {ERR_REASON(UI_R_RESULT_TOO_LARGE), "result too large"}, + {ERR_REASON(UI_R_RESULT_TOO_SMALL), "result too small"}, + {ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND), "unknown control command"}, + {0, NULL} +}; + +#endif + +void ERR_load_UI_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(UI_str_functs[0].error) == NULL) { + ERR_load_strings(0, UI_str_functs); + ERR_load_strings(0, UI_str_reasons); + } +#endif +} +/* crypto/ui/ui_lib.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "e_os2.h" +#include "buffer.h" +// #include "ui.h" +// #include "err.h" +#include "ui_locl.h" + +IMPLEMENT_STACK_OF(UI_STRING_ST) + +static const UI_METHOD *default_UI_meth = NULL; + +UI *UI_new(void) +{ + return (UI_new_method(NULL)); +} + +UI *UI_new_method(const UI_METHOD *method) +{ + UI *ret; + + ret = (UI *)OPENSSL_malloc(sizeof(UI)); + if (ret == NULL) { + UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (method == NULL) + ret->meth = UI_get_default_method(); + else + ret->meth = method; + + ret->strings = NULL; + ret->user_data = NULL; + ret->flags = 0; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data); + return ret; +} + +static void free_string(UI_STRING *uis) +{ + if (uis->flags & OUT_STRING_FREEABLE) { + OPENSSL_free((char *)uis->out_string); + switch (uis->type) { + case UIT_BOOLEAN: + OPENSSL_free((char *)uis->_.boolean_data.action_desc); + OPENSSL_free((char *)uis->_.boolean_data.ok_chars); + OPENSSL_free((char *)uis->_.boolean_data.cancel_chars); + break; + default: + break; + } + } + OPENSSL_free(uis); +} + +void UI_free(UI *ui) +{ + if (ui == NULL) + return; + sk_UI_STRING_pop_free(ui->strings, free_string); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data); + OPENSSL_free(ui); +} + +static int allocate_string_stack(UI *ui) +{ + if (ui->strings == NULL) { + ui->strings = sk_UI_STRING_new_null(); + if (ui->strings == NULL) { + return -1; + } + } + return 0; +} + +static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt, + int prompt_freeable, + enum UI_string_types type, + int input_flags, char *result_buf) +{ + UI_STRING *ret = NULL; + + if (prompt == NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, ERR_R_PASSED_NULL_PARAMETER); + } else if ((type == UIT_PROMPT || type == UIT_VERIFY + || type == UIT_BOOLEAN) && result_buf == NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, UI_R_NO_RESULT_BUFFER); + } else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING)))) { + ret->out_string = prompt; + ret->flags = prompt_freeable ? OUT_STRING_FREEABLE : 0; + ret->input_flags = input_flags; + ret->type = type; + ret->result_buf = result_buf; + } + return ret; +} + +static int general_allocate_string(UI *ui, const char *prompt, + int prompt_freeable, + enum UI_string_types type, int input_flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf) +{ + int ret = -1; + UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable, + type, input_flags, result_buf); + + if (s != NULL) { + if (allocate_string_stack(ui) >= 0) { + s->_.string_data.result_minsize = minsize; + s->_.string_data.result_maxsize = maxsize; + s->_.string_data.test_buf = test_buf; + ret = sk_UI_STRING_push(ui->strings, s); + /* sk_push() returns 0 on error. Let's addapt that */ + if (ret <= 0) + ret--; + } else + free_string(s); + } + return ret; +} + +static int general_allocate_boolean(UI *ui, + const char *prompt, + const char *action_desc, + const char *ok_chars, + const char *cancel_chars, + int prompt_freeable, + enum UI_string_types type, + int input_flags, char *result_buf) +{ + int ret = -1; + UI_STRING *s; + const char *p; + + if (ok_chars == NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER); + } else if (cancel_chars == NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER); + } else { + for (p = ok_chars; *p != '\0'; p++) { + if (strchr(cancel_chars, *p) != NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, + UI_R_COMMON_OK_AND_CANCEL_CHARACTERS); + } + } + + s = general_allocate_prompt(ui, prompt, prompt_freeable, + type, input_flags, result_buf); + + if (s != NULL) { + if (allocate_string_stack(ui) >= 0) { + s->_.boolean_data.action_desc = action_desc; + s->_.boolean_data.ok_chars = ok_chars; + s->_.boolean_data.cancel_chars = cancel_chars; + ret = sk_UI_STRING_push(ui->strings, s); + /* + * sk_push() returns 0 on error. Let's addapt that + */ + if (ret <= 0) + ret--; + } else + free_string(s); + } + } + return ret; +} + +/* + * Returns the index to the place in the stack or -1 for error. Uses a + * direct reference to the prompt. + */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize) +{ + return general_allocate_string(ui, prompt, 0, + UIT_PROMPT, flags, result_buf, minsize, + maxsize, NULL); +} + +/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */ +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize) +{ + char *prompt_copy = NULL; + + if (prompt != NULL) { + prompt_copy = BUF_strdup(prompt); + if (prompt_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + return general_allocate_string(ui, prompt_copy, 1, + UIT_PROMPT, flags, result_buf, minsize, + maxsize, NULL); +} + +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf) +{ + return general_allocate_string(ui, prompt, 0, + UIT_VERIFY, flags, result_buf, minsize, + maxsize, test_buf); +} + +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf) +{ + char *prompt_copy = NULL; + + if (prompt != NULL) { + prompt_copy = BUF_strdup(prompt); + if (prompt_copy == NULL) { + UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE); + return -1; + } + } + + return general_allocate_string(ui, prompt_copy, 1, + UIT_VERIFY, flags, result_buf, minsize, + maxsize, test_buf); +} + +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf) +{ + return general_allocate_boolean(ui, prompt, action_desc, + ok_chars, cancel_chars, 0, UIT_BOOLEAN, + flags, result_buf); +} + +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf) +{ + char *prompt_copy = NULL; + char *action_desc_copy = NULL; + char *ok_chars_copy = NULL; + char *cancel_chars_copy = NULL; + + if (prompt != NULL) { + prompt_copy = BUF_strdup(prompt); + if (prompt_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (action_desc != NULL) { + action_desc_copy = BUF_strdup(action_desc); + if (action_desc_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (ok_chars != NULL) { + ok_chars_copy = BUF_strdup(ok_chars); + if (ok_chars_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (cancel_chars != NULL) { + cancel_chars_copy = BUF_strdup(cancel_chars); + if (cancel_chars_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + return general_allocate_boolean(ui, prompt_copy, action_desc_copy, + ok_chars_copy, cancel_chars_copy, 1, + UIT_BOOLEAN, flags, result_buf); + err: + if (prompt_copy) + OPENSSL_free(prompt_copy); + if (action_desc_copy) + OPENSSL_free(action_desc_copy); + if (ok_chars_copy) + OPENSSL_free(ok_chars_copy); + if (cancel_chars_copy) + OPENSSL_free(cancel_chars_copy); + return -1; +} + +int UI_add_info_string(UI *ui, const char *text) +{ + return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0, + NULL); +} + +int UI_dup_info_string(UI *ui, const char *text) +{ + char *text_copy = NULL; + + if (text != NULL) { + text_copy = BUF_strdup(text); + if (text_copy == NULL) { + UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE); + return -1; + } + } + + return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL, + 0, 0, NULL); +} + +int UI_add_error_string(UI *ui, const char *text) +{ + return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0, + NULL); +} + +int UI_dup_error_string(UI *ui, const char *text) +{ + char *text_copy = NULL; + + if (text != NULL) { + text_copy = BUF_strdup(text); + if (text_copy == NULL) { + UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE); + return -1; + } + } + return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL, + 0, 0, NULL); +} + +char *UI_construct_prompt(UI *ui, const char *object_desc, + const char *object_name) +{ + char *prompt = NULL; + + if (ui->meth->ui_construct_prompt != NULL) + prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name); + else { + char prompt1[] = "Enter "; + char prompt2[] = " for "; + char prompt3[] = ":"; + int len = 0; + + if (object_desc == NULL) + return NULL; + len = sizeof(prompt1) - 1 + strlen(object_desc); + if (object_name != NULL) + len += sizeof(prompt2) - 1 + strlen(object_name); + len += sizeof(prompt3) - 1; + + prompt = (char *)OPENSSL_malloc(len + 1); + if (prompt == NULL) + return NULL; + BUF_strlcpy(prompt, prompt1, len + 1); + BUF_strlcat(prompt, object_desc, len + 1); + if (object_name != NULL) { + BUF_strlcat(prompt, prompt2, len + 1); + BUF_strlcat(prompt, object_name, len + 1); + } + BUF_strlcat(prompt, prompt3, len + 1); + } + return prompt; +} + +void *UI_add_user_data(UI *ui, void *user_data) +{ + void *old_data = ui->user_data; + ui->user_data = user_data; + return old_data; +} + +void *UI_get0_user_data(UI *ui) +{ + return ui->user_data; +} + +const char *UI_get0_result(UI *ui, int i) +{ + if (i < 0) { + UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL); + return NULL; + } + if (i >= sk_UI_STRING_num(ui->strings)) { + UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE); + return NULL; + } + return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i)); +} + +static int print_error(const char *str, size_t len, UI *ui) +{ + UI_STRING uis; + + memset(&uis, 0, sizeof(uis)); + uis.type = UIT_ERROR; + uis.out_string = str; + + if (ui->meth->ui_write_string != NULL + && ui->meth->ui_write_string(ui, &uis) <= 0) + return -1; + return 0; +} + +int UI_process(UI *ui) +{ + int i, ok = 0; + + if (ui->meth->ui_open_session != NULL + && ui->meth->ui_open_session(ui) <= 0) { + ok = -1; + goto err; + } + + if (ui->flags & UI_FLAG_PRINT_ERRORS) + ERR_print_errors_cb((int (*)(const char *, size_t, void *)) + print_error, (void *)ui); + + for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) { + if (ui->meth->ui_write_string != NULL + && (ui->meth->ui_write_string(ui, + sk_UI_STRING_value(ui->strings, i)) + <= 0)) + { + ok = -1; + goto err; + } + } + + if (ui->meth->ui_flush != NULL) + switch (ui->meth->ui_flush(ui)) { + case -1: /* Interrupt/Cancel/something... */ + ok = -2; + goto err; + case 0: /* Errors */ + ok = -1; + goto err; + default: /* Success */ + ok = 0; + break; + } + + for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) { + if (ui->meth->ui_read_string != NULL) { + switch (ui->meth->ui_read_string(ui, + sk_UI_STRING_value(ui->strings, + i))) { + case -1: /* Interrupt/Cancel/something... */ + ok = -2; + goto err; + case 0: /* Errors */ + ok = -1; + goto err; + default: /* Success */ + ok = 0; + break; + } + } + } + + err: + if (ui->meth->ui_close_session != NULL + && ui->meth->ui_close_session(ui) <= 0) + return -1; + return ok; +} + +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)) +{ + if (ui == NULL) { + UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + switch (cmd) { + case UI_CTRL_PRINT_ERRORS: + { + int save_flag = ! !(ui->flags & UI_FLAG_PRINT_ERRORS); + if (i) + ui->flags |= UI_FLAG_PRINT_ERRORS; + else + ui->flags &= ~UI_FLAG_PRINT_ERRORS; + return save_flag; + } + case UI_CTRL_IS_REDOABLE: + return ! !(ui->flags & UI_FLAG_REDOABLE); + default: + break; + } + UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND); + return -1; +} + +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp, + new_func, dup_func, free_func); +} + +int UI_set_ex_data(UI *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *UI_get_ex_data(UI *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +void UI_set_default_method(const UI_METHOD *meth) +{ + default_UI_meth = meth; +} + +const UI_METHOD *UI_get_default_method(void) +{ + if (default_UI_meth == NULL) { + default_UI_meth = UI_OpenSSL(); + } + return default_UI_meth; +} + +const UI_METHOD *UI_get_method(UI *ui) +{ + return ui->meth; +} + +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth) +{ + ui->meth = meth; + return ui->meth; +} + +UI_METHOD *UI_create_method(char *name) +{ + UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD)); + + if (ui_method) { + memset(ui_method, 0, sizeof(*ui_method)); + ui_method->name = BUF_strdup(name); + } + return ui_method; +} + +/* + * BIG FSCKING WARNING!!!! If you use this on a statically allocated method + * (that is, it hasn't been allocated using UI_create_method(), you deserve + * anything Murphy can throw at you and more! You have been warned. + */ +void UI_destroy_method(UI_METHOD *ui_method) +{ + OPENSSL_free(ui_method->name); + ui_method->name = NULL; + OPENSSL_free(ui_method); +} + +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)) +{ + if (method != NULL) { + method->ui_open_session = opener; + return 0; + } + return -1; +} + +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)) +{ + if (method != NULL) { + method->ui_write_string = writer; + return 0; + } + return -1; +} + +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)) +{ + if (method != NULL) { + method->ui_flush = flusher; + return 0; + } + return -1; +} + +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)) +{ + if (method != NULL) { + method->ui_read_string = reader; + return 0; + } + return -1; +} + +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)) +{ + if (method != NULL) { + method->ui_close_session = closer; + return 0; + } + return -1; +} + +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *object_desc, + const char + *object_name)) +{ + if (method != NULL) { + method->ui_construct_prompt = prompt_constructor; + return 0; + } + return -1; +} + +int (*UI_method_get_opener(UI_METHOD *method)) (UI *) +{ + if (method != NULL) + return method->ui_open_session; + return NULL; +} + +int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) +{ + if (method != NULL) + return method->ui_write_string; + return NULL; +} + +int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) +{ + if (method != NULL) + return method->ui_flush; + return NULL; +} + +int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) +{ + if (method != NULL) + return method->ui_read_string; + return NULL; +} + +int (*UI_method_get_closer(UI_METHOD *method)) (UI *) +{ + if (method != NULL) + return method->ui_close_session; + return NULL; +} + +char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *, + const char *, + const char *) +{ + if (method != NULL) + return method->ui_construct_prompt; + return NULL; +} + +enum UI_string_types UI_get_string_type(UI_STRING *uis) +{ + if (!uis) + return UIT_NONE; + return uis->type; +} + +int UI_get_input_flags(UI_STRING *uis) +{ + if (!uis) + return 0; + return uis->input_flags; +} + +const char *UI_get0_output_string(UI_STRING *uis) +{ + if (!uis) + return NULL; + return uis->out_string; +} + +const char *UI_get0_action_string(UI_STRING *uis) +{ + if (!uis) + return NULL; + switch (uis->type) { + case UIT_BOOLEAN: + return uis->_.boolean_data.action_desc; + default: + return NULL; + } +} + +const char *UI_get0_result_string(UI_STRING *uis) +{ + if (!uis) + return NULL; + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->result_buf; + default: + return NULL; + } +} + +const char *UI_get0_test_string(UI_STRING *uis) +{ + if (!uis) + return NULL; + switch (uis->type) { + case UIT_VERIFY: + return uis->_.string_data.test_buf; + default: + return NULL; + } +} + +int UI_get_result_minsize(UI_STRING *uis) +{ + if (!uis) + return -1; + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->_.string_data.result_minsize; + default: + return -1; + } +} + +int UI_get_result_maxsize(UI_STRING *uis) +{ + if (!uis) + return -1; + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->_.string_data.result_maxsize; + default: + return -1; + } +} + +int UI_set_result(UI *ui, UI_STRING *uis, const char *result) +{ + int l = strlen(result); + + ui->flags &= ~UI_FLAG_REDOABLE; + + if (!uis) + return -1; + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + { + char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1]; + char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1]; + + BIO_snprintf(number1, sizeof(number1), "%d", + uis->_.string_data.result_minsize); + BIO_snprintf(number2, sizeof(number2), "%d", + uis->_.string_data.result_maxsize); + + if (l < uis->_.string_data.result_minsize) { + ui->flags |= UI_FLAG_REDOABLE; + UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_SMALL); + ERR_add_error_data(5, "You must type in ", + number1, " to ", number2, " characters"); + return -1; + } + if (l > uis->_.string_data.result_maxsize) { + ui->flags |= UI_FLAG_REDOABLE; + UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_LARGE); + ERR_add_error_data(5, "You must type in ", + number1, " to ", number2, " characters"); + return -1; + } + } + + if (!uis->result_buf) { + UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER); + return -1; + } + + BUF_strlcpy(uis->result_buf, result, + uis->_.string_data.result_maxsize + 1); + break; + case UIT_BOOLEAN: + { + const char *p; + + if (!uis->result_buf) { + UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER); + return -1; + } + + uis->result_buf[0] = '\0'; + for (p = result; *p; p++) { + if (strchr(uis->_.boolean_data.ok_chars, *p)) { + uis->result_buf[0] = uis->_.boolean_data.ok_chars[0]; + break; + } + if (strchr(uis->_.boolean_data.cancel_chars, *p)) { + uis->result_buf[0] = uis->_.boolean_data.cancel_chars[0]; + break; + } + } + } + default: + break; + } + return 0; +} +/* crypto/ui/ui_openssl.c */ +/* + * Written by Richard Levitte (richard@levitte.org) and others for the + * OpenSSL project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/*- + * The lowest level part of this file was previously in crypto/des/read_pwd.c, + * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +// #include "e_os2.h" + +/* + * need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc + * [maybe others?], because it masks interfaces not discussed in standard, + * sigaction and fileno included. -pedantic would be more appropriate for the + * intended purposes, but we can't prevent users from adding -ansi. + */ +#if defined(OPENSSL_SYSNAME_VXWORKS) +# include +#endif + +#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) +# ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 2 +# endif +#endif +#include +#include +#include +#include + +#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +/* + * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX + * system and have sigaction and termios. + */ +# if defined(_POSIX_VERSION) + +# define SIGACTION +# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) +# define TERMIOS +# endif + +# endif +#endif + +#ifdef WIN16TTY +# undef OPENSSL_SYS_WIN16 +# undef WIN16 +# undef _WINDOWS +# include +#endif + +/* 06-Apr-92 Luke Brennan Support for VMS */ +// #include "ui_locl.h" +// #include "cryptlib.h" + +#ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ +# include +# ifdef __DECC +# pragma message disable DOLLARID +# endif +#endif + +#ifdef WIN_CONSOLE_BUG +# include +# ifndef OPENSSL_SYS_WINCE +# include +# endif +#endif + +/* + * There are 5 types of terminal interface supported, TERMIO, TERMIOS, VMS, + * MSDOS and SGTTY. + * + * If someone defines one of the macros TERMIO, TERMIOS or SGTTY, it will + * remain respected. Otherwise, we default to TERMIOS except for a few + * systems that require something different. + * + * Note: we do not use SGTTY unless it's defined by the configuration. We + * may eventually opt to remove it's use entirely. + */ + +#if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) + +# if defined(_LIBC) +# undef TERMIOS +# define TERMIO +# undef SGTTY +/* + * We know that VMS, MSDOS, VXWORKS, NETWARE use entirely other mechanisms. + * MAC_OS_GUSI_SOURCE should probably go away, but that needs to be confirmed. + */ +# elif !defined(OPENSSL_SYS_VMS) \ + && !defined(OPENSSL_SYS_MSDOS) \ + && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) \ + && !defined(MAC_OS_GUSI_SOURCE) \ + && !defined(OPENSSL_SYS_VXWORKS) \ + && !defined(OPENSSL_SYS_NETWARE) +# define TERMIOS +# undef TERMIO +# undef SGTTY +# endif + +#endif + +#ifdef TERMIOS +# include +# define TTY_STRUCT struct termios +# define TTY_FLAGS c_lflag +# define TTY_get(tty,data) tcgetattr(tty,data) +# define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) +#endif + +#ifdef TERMIO +# include +# define TTY_STRUCT struct termio +# define TTY_FLAGS c_lflag +# define TTY_get(tty,data) ioctl(tty,TCGETA,data) +# define TTY_set(tty,data) ioctl(tty,TCSETA,data) +#endif + +#ifdef SGTTY +# include +# define TTY_STRUCT struct sgttyb +# define TTY_FLAGS sg_flags +# define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) +# define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) +#endif + +#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS) +# include +#endif + +#ifdef OPENSSL_SYS_MSDOS +# include +#endif + +#ifdef OPENSSL_SYS_VMS +# include +# include +# include +# include +struct IOSB { + short iosb$w_value; + short iosb$w_count; + long iosb$l_info; +}; +#endif + +#ifdef OPENSSL_SYS_SUNOS +typedef int sig_atomic_t; +#endif + +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE) +/* + * This one needs work. As a matter of fact the code is unoperational + * and this is only a trick to get it compiled. + * + */ +# define TTY_STRUCT int +#endif + +#ifndef NX509_SIG +# define NX509_SIG 32 +#endif + +/* Define globals. They are protected by a lock */ +#ifdef SIGACTION +static struct sigaction savsig[NX509_SIG]; +#else +static void (*savsig[NX509_SIG]) (int); +#endif + +#ifdef OPENSSL_SYS_VMS +static struct IOSB iosb; +static $DESCRIPTOR(terminal, "TT"); +static long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this + * will always suffice for the actual + * structures? */ +static long status; +static unsigned short channel = 0; +#else +# if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) +static TTY_STRUCT tty_orig, tty_new; +# endif +#endif +static FILE *tty_in, *tty_out; +static int is_a_tty; + +/* Declare static functions */ +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) +static int read_till_nl(FILE *); +static void recsig(int); +static void pushsig(void); +static void popsig(void); +#endif +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) +static int noecho_fgets(char *buf, int size, FILE *tty); +#endif +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); + +static int read_string(UI *ui, UI_STRING *uis); +static int write_string(UI *ui, UI_STRING *uis); + +static int open_console(UI *ui); +static int echo_console(UI *ui); +static int noecho_console(UI *ui); +static int close_console(UI *ui); + +static UI_METHOD ui_openssl = { + "OpenSSL default user interface", + open_console, + write_string, + NULL, /* No flusher is needed for command lines */ + read_string, + close_console, + NULL +}; + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void) +{ + return &ui_openssl; +} + +/* + * The following function makes sure that info and error strings are printed + * before any prompt. + */ +static int write_string(UI *ui, UI_STRING *uis) +{ + switch (UI_get_string_type(uis)) { + case UIT_ERROR: + case UIT_INFO: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + break; + default: + break; + } + return 1; +} + +static int read_string(UI *ui, UI_STRING *uis) +{ + int ok = 0; + + switch (UI_get_string_type(uis)) { + case UIT_BOOLEAN: + fputs(UI_get0_output_string(uis), tty_out); + fputs(UI_get0_action_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, + 0); + case UIT_PROMPT: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, + 1); + case UIT_VERIFY: + fprintf(tty_out, "Verifying - %s", UI_get0_output_string(uis)); + fflush(tty_out); + if ((ok = read_string_inner(ui, uis, + UI_get_input_flags(uis) & + UI_INPUT_FLAG_ECHO, 1)) <= 0) + return ok; + if (strcmp(UI_get0_result_string(uis), UI_get0_test_string(uis)) != 0) { + fprintf(tty_out, "Verify failure\n"); + fflush(tty_out); + return 0; + } + break; + default: + break; + } + return 1; +} + +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) +/* Internal functions to read a string without echoing */ +static int read_till_nl(FILE *in) +{ +# define SIZE 4 + char buf[SIZE + 1]; + + do { + if (!fgets(buf, SIZE, in)) + return 0; + } while (strchr(buf, '\n') == NULL); + return 1; +} + +static volatile sig_atomic_t intr_signal; +#endif + +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) +{ + static int ps; + int ok; + char result[BUFSIZ]; + int maxsize = BUFSIZ - 1; +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) + char *p; + + intr_signal = 0; + ok = 0; + ps = 0; + + pushsig(); + ps = 1; + + if (!echo && !noecho_console(ui)) + goto error; + ps = 2; + + result[0] = '\0'; +# ifdef OPENSSL_SYS_MSDOS + if (!echo) { + noecho_fgets(result, maxsize, tty_in); + p = result; /* FIXME: noecho_fgets doesn't return errors */ + } else + p = fgets(result, maxsize, tty_in); +# else + p = fgets(result, maxsize, tty_in); +# endif + if (p == NULL) + goto error; + if (feof(tty_in)) + goto error; + if (ferror(tty_in)) + goto error; + if ((p = (char *)strchr(result, '\n')) != NULL) { + if (strip_nl) + *p = '\0'; + } else if (!read_till_nl(tty_in)) + goto error; + if (UI_set_result(ui, uis, result) >= 0) + ok = 1; + + error: + if (intr_signal == SIGINT) + ok = -1; + if (!echo) + fprintf(tty_out, "\n"); + if (ps >= 2 && !echo && !echo_console(ui)) + ok = 0; + + if (ps >= 1) + popsig(); +#else + ok = 1; +#endif + + OPENSSL_cleanse(result, BUFSIZ); + return ok; +} + +/* Internal functions to open, handle and close a channel to the console. */ +static int open_console(UI *ui) +{ + CRYPTO_w_lock(CRYPTO_LOCK_UI); + is_a_tty = 1; + +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS) + tty_in = stdin; + tty_out = stderr; +#else +# ifdef OPENSSL_SYS_MSDOS +# define DEV_TTY "con" +# else +# define DEV_TTY "/dev/tty" +# endif + if ((tty_in = fopen(DEV_TTY, "r")) == NULL) + tty_in = stdin; + if ((tty_out = fopen(DEV_TTY, "w")) == NULL) + tty_out = stderr; +#endif + +#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) + if (TTY_get(fileno(tty_in), &tty_orig) == -1) { +# ifdef ENOTTY + if (errno == ENOTTY) + is_a_tty = 0; + else +# endif +# ifdef EINVAL + /* + * Ariel Glenn ariel@columbia.edu reports that solaris can return + * EINVAL instead. This should be ok + */ + if (errno == EINVAL) + is_a_tty = 0; + else +# endif +# ifdef ENXIO + /* + * Solaris can return ENXIO. + * This should be ok + */ + if (errno == ENXIO) + is_a_tty = 0; + else +# endif +# ifdef EIO + /* + * Linux can return EIO. + * This should be ok + */ + if (errno == EIO) + is_a_tty = 0; + else +# endif +# ifdef ENODEV + /* + * MacOS X returns ENODEV (Operation not supported by device), + * which seems appropriate. + */ + if (errno == ENODEV) + is_a_tty = 0; + else +# endif + return 0; + } +#endif +#ifdef OPENSSL_SYS_VMS + status = sys$assign(&terminal, &channel, 0, 0); + + /* if there isn't a TT device, something is very wrong */ + if (status != SS$_NORMAL) + return 0; + + status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, + 0, 0, 0, 0); + + /* If IO$_SENSEMODE doesn't work, this is not a terminal device */ + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + is_a_tty = 0; +#endif + return 1; +} + +static int noecho_console(UI *ui) +{ +#ifdef TTY_FLAGS + memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); + tty_new.TTY_FLAGS &= ~ECHO; +#endif + +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) + if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) + return 0; +#endif +#ifdef OPENSSL_SYS_VMS + if (is_a_tty) { + tty_new[0] = tty_orig[0]; + tty_new[1] = tty_orig[1] | TT$M_NOECHO; + tty_new[2] = tty_orig[2]; + status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, + 0, 0, 0, 0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return 0; + } +#endif + return 1; +} + +static int echo_console(UI *ui) +{ +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) + memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); + if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) + return 0; +#endif +#ifdef OPENSSL_SYS_VMS + if (is_a_tty) { + tty_new[0] = tty_orig[0]; + tty_new[1] = tty_orig[1]; + tty_new[2] = tty_orig[2]; + status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, + 0, 0, 0, 0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return 0; + } +#endif + return 1; +} + +static int close_console(UI *ui) +{ + if (tty_in != stdin) + fclose(tty_in); + if (tty_out != stderr) + fclose(tty_out); +#ifdef OPENSSL_SYS_VMS + status = sys$dassgn(channel); + if (status != SS$_NORMAL) + return 0; +#endif + CRYPTO_w_unlock(CRYPTO_LOCK_UI); + + return 1; +} + +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) +/* Internal functions to handle signals and act on them */ +static void pushsig(void) +{ +# ifndef OPENSSL_SYS_WIN32 + int i; +# endif +# ifdef SIGACTION + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = recsig; +# endif + +# ifdef OPENSSL_SYS_WIN32 + savsig[SIGABRT] = signal(SIGABRT, recsig); + savsig[SIGFPE] = signal(SIGFPE, recsig); + savsig[SIGILL] = signal(SIGILL, recsig); + savsig[SIGINT] = signal(SIGINT, recsig); + savsig[SIGSEGV] = signal(SIGSEGV, recsig); + savsig[SIGTERM] = signal(SIGTERM, recsig); +# else + for (i = 1; i < NX509_SIG; i++) { +# ifdef SIGUSR1 + if (i == SIGUSR1) + continue; +# endif +# ifdef SIGUSR2 + if (i == SIGUSR2) + continue; +# endif +# ifdef SIGKILL + if (i == SIGKILL) /* We can't make any action on that. */ + continue; +# endif +# ifdef SIGACTION + sigaction(i, &sa, &savsig[i]); +# else + savsig[i] = signal(i, recsig); +# endif + } +# endif + +# ifdef SIGWINCH + signal(SIGWINCH, SIG_DFL); +# endif +} + +static void popsig(void) +{ +# ifdef OPENSSL_SYS_WIN32 + signal(SIGABRT, savsig[SIGABRT]); + signal(SIGFPE, savsig[SIGFPE]); + signal(SIGILL, savsig[SIGILL]); + signal(SIGINT, savsig[SIGINT]); + signal(SIGSEGV, savsig[SIGSEGV]); + signal(SIGTERM, savsig[SIGTERM]); +# else + int i; + for (i = 1; i < NX509_SIG; i++) { +# ifdef SIGUSR1 + if (i == SIGUSR1) + continue; +# endif +# ifdef SIGUSR2 + if (i == SIGUSR2) + continue; +# endif +# ifdef SIGACTION + sigaction(i, &savsig[i], NULL); +# else + signal(i, savsig[i]); +# endif + } +# endif +} + +static void recsig(int i) +{ + intr_signal = i; +} +#endif + +/* Internal functions specific for Windows */ +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) +static int noecho_fgets(char *buf, int size, FILE *tty) +{ + int i; + char *p; + + p = buf; + for (;;) { + if (size == 0) { + *p = '\0'; + break; + } + size--; +# ifdef WIN16TTY + i = _inchar(); +# elif defined(_WIN32) + i = _getch(); +# else + i = getch(); +# endif + if (i == '\r') + i = '\n'; + *(p++) = i; + if (i == '\n') { + *p = '\0'; + break; + } + } +# ifdef WIN_CONSOLE_BUG + /* + * Win95 has several evil console bugs: one of these is that the last + * character read using getch() is passed to the next read: this is + * usually a CR so this can be trouble. No STDIO fix seems to work but + * flushing the console appears to do the trick. + */ + { + HANDLE inh; + inh = GetStdHandle(STD_INPUT_HANDLE); + FlushConsoleInputBuffer(inh); + } +# endif + return (strlen(buf)); +} +#endif +/* crypto/ui/ui_util.c */ +/* ==================================================================== + * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "ui_locl.h" + +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify) +{ + char buff[BUFSIZ]; + int ret; + + ret = + UI_UTIL_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length, + prompt, verify); + OPENSSL_cleanse(buff, BUFSIZ); + return (ret); +} + +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify) +{ + int ok = 0; + UI *ui; + + if (size < 1) + return -1; + + ui = UI_new(); + if (ui) { + ok = UI_add_input_string(ui, prompt, 0, buf, 0, size - 1); + if (ok >= 0 && verify) + ok = UI_add_verify_string(ui, prompt, 0, buff, 0, size - 1, buf); + if (ok >= 0) + ok = UI_process(ui); + UI_free(ui); + } + if (ok > 0) + ok = 0; + return (ok); +} diff --git a/Sources/COpenSSL/ui_compat.h b/Sources/COpenSSL/ui_compat.h new file mode 100644 index 00000000..8d7b5f19 --- /dev/null +++ b/Sources/COpenSSL/ui_compat.h @@ -0,0 +1,88 @@ +/* crypto/ui/ui.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_COMPAT_H +# define HEADER_UI_COMPAT_H + +# include "opensslconf.h" +# include "ui.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following functions were previously part of the DES section, and are + * provided here for backward compatibility reasons. + */ + +# define des_read_pw_string(b,l,p,v) \ + _ossl_old_des_read_pw_string((b),(l),(p),(v)) +# define des_read_pw(b,bf,s,p,v) \ + _ossl_old_des_read_pw((b),(bf),(s),(p),(v)) + +int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/ui_locl.h b/Sources/COpenSSL/ui_locl.h new file mode 100644 index 00000000..2d6063fd --- /dev/null +++ b/Sources/COpenSSL/ui_locl.h @@ -0,0 +1,145 @@ +/* crypto/ui/ui.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_LOCL_H +# define HEADER_UI_LOCL_H + +# include "ui.h" +# include "crypto.h" + +# ifdef _ +# undef _ +# endif + +struct ui_method_st { + char *name; + /* + * All the functions return 1 or non-NULL for success and 0 or NULL for + * failure + */ + /* + * Open whatever channel for this, be it the console, an X window or + * whatever. This function should use the ex_data structure to save + * intermediate data. + */ + int (*ui_open_session) (UI *ui); + int (*ui_write_string) (UI *ui, UI_STRING *uis); + /* + * Flush the output. If a GUI dialog box is used, this function can be + * used to actually display it. + */ + int (*ui_flush) (UI *ui); + int (*ui_read_string) (UI *ui, UI_STRING *uis); + int (*ui_close_session) (UI *ui); + /* + * Construct a prompt in a user-defined manner. object_desc is a textual + * short description of the object, for example "pass phrase", and + * object_name is the name of the object (might be a card name or a file + * name. The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + */ + char *(*ui_construct_prompt) (UI *ui, const char *object_desc, + const char *object_name); +}; + +struct ui_string_st { + enum UI_string_types type; /* Input */ + const char *out_string; /* Input */ + int input_flags; /* Flags from the user */ + /* + * The following parameters are completely irrelevant for UIT_INFO, and + * can therefore be set to 0 or NULL + */ + char *result_buf; /* Input and Output: If not NULL, + * user-defined with size in result_maxsize. + * Otherwise, it may be allocated by the UI + * routine, meaning result_minsize is going + * to be overwritten. */ + union { + struct { + int result_minsize; /* Input: minimum required size of the + * result. */ + int result_maxsize; /* Input: maximum permitted size of the + * result */ + const char *test_buf; /* Input: test string to verify against */ + } string_data; + struct { + const char *action_desc; /* Input */ + const char *ok_chars; /* Input */ + const char *cancel_chars; /* Input */ + } boolean_data; + } _; + +# define OUT_STRING_FREEABLE 0x01 + int flags; /* flags for internal use */ +}; + +struct ui_st { + const UI_METHOD *meth; + STACK_OF(UI_STRING) *strings; /* We might want to prompt for more than + * one thing at a time, and with different + * echoing status. */ + void *user_data; + CRYPTO_EX_DATA ex_data; +# define UI_FLAG_REDOABLE 0x0001 +# define UI_FLAG_PRINT_ERRORS 0x0100 + int flags; +}; + +#endif diff --git a/Sources/COpenSSL/uid.c b/Sources/COpenSSL/uid.c new file mode 100644 index 00000000..d10536e7 --- /dev/null +++ b/Sources/COpenSSL/uid.c @@ -0,0 +1,88 @@ +/* crypto/uid.c */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "crypto.h" +#include "opensslconf.h" + +#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2) + +# include OPENSSL_UNISTD + +int OPENSSL_issetugid(void) +{ + return issetugid(); +} + +#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) + +int OPENSSL_issetugid(void) +{ + return 0; +} + +#else + +# include OPENSSL_UNISTD +# include + +int OPENSSL_issetugid(void) +{ + if (getuid() != geteuid()) + return 1; + if (getgid() != getegid()) + return 1; + return 0; +} +#endif diff --git a/Sources/COpenSSL/v3_.c b/Sources/COpenSSL/v3_.c new file mode 100644 index 00000000..30a9654d --- /dev/null +++ b/Sources/COpenSSL/v3_.c @@ -0,0 +1,10781 @@ +/* + * Contributed to the OpenSSL Project by the American Registry for + * Internet Numbers ("ARIN"). + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +/* + * Implementation of RFC 3779 section 2.2. + */ + +#include +#include + +#include "cryptlib.h" +#include "conf.h" +#include "asn1.h" +#include "asn1t.h" +#include "buffer.h" +#include "x509v3.h" + +#ifndef OPENSSL_NO_RFC3779 + +/* + * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. + */ + +ASN1_SEQUENCE(IPAddressRange) = { + ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), + ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(IPAddressRange) + +ASN1_CHOICE(IPAddressOrRange) = { + ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), + ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) +} ASN1_CHOICE_END(IPAddressOrRange) + +ASN1_CHOICE(IPAddressChoice) = { + ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), + ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) +} ASN1_CHOICE_END(IPAddressChoice) + +ASN1_SEQUENCE(IPAddressFamily) = { + ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), + ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) +} ASN1_SEQUENCE_END(IPAddressFamily) + +ASN1_ITEM_TEMPLATE(IPAddrBlocks) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + IPAddrBlocks, IPAddressFamily) +ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) + +IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) +IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange) +IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice) +IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * How much buffer space do we need for a raw address? + */ +# define ADDR_RAW_BUF_LEN 16 + +/* + * What's the address length associated with this AFI? + */ +static int length_from_afi(const unsigned afi) +{ + switch (afi) { + case IANA_AFI_IPV4: + return 4; + case IANA_AFI_IPV6: + return 16; + default: + return 0; + } +} + +/* + * Extract the AFI from an IPAddressFamily. + */ +unsigned int v3_addr_get_afi(const IPAddressFamily *f) +{ + if (f == NULL + || f->addressFamily == NULL + || f->addressFamily->data == NULL + || f->addressFamily->length < 2) + return 0; + return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1]; +} + +/* + * Expand the bitstring form of an address into a raw byte array. + * At the moment this is coded for simplicity, not speed. + */ +static int addr_expand(unsigned char *addr, + const ASN1_BIT_STRING *bs, + const int length, const unsigned char fill) +{ + if (bs->length < 0 || bs->length > length) + return 0; + if (bs->length > 0) { + memcpy(addr, bs->data, bs->length); + if ((bs->flags & 7) != 0) { + unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); + if (fill == 0) + addr[bs->length - 1] &= ~mask; + else + addr[bs->length - 1] |= mask; + } + } + memset(addr + bs->length, fill, length - bs->length); + return 1; +} + +/* + * Extract the prefix length from a bitstring. + */ +# define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) + +/* + * i2r handler for one address bitstring. + */ +static int i2r_address(BIO *out, + const unsigned afi, + const unsigned char fill, const ASN1_BIT_STRING *bs) +{ + unsigned char addr[ADDR_RAW_BUF_LEN]; + int i, n; + + if (bs->length < 0) + return 0; + switch (afi) { + case IANA_AFI_IPV4: + if (!addr_expand(addr, bs, 4, fill)) + return 0; + BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); + break; + case IANA_AFI_IPV6: + if (!addr_expand(addr, bs, 16, fill)) + return 0; + for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; + n -= 2) ; + for (i = 0; i < n; i += 2) + BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], + (i < 14 ? ":" : "")); + if (i < 16) + BIO_puts(out, ":"); + if (i == 0) + BIO_puts(out, ":"); + break; + default: + for (i = 0; i < bs->length; i++) + BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); + BIO_printf(out, "[%d]", (int)(bs->flags & 7)); + break; + } + return 1; +} + +/* + * i2r handler for a sequence of addresses and ranges. + */ +static int i2r_IPAddressOrRanges(BIO *out, + const int indent, + const IPAddressOrRanges *aors, + const unsigned afi) +{ + int i; + for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { + const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); + BIO_printf(out, "%*s", indent, ""); + switch (aor->type) { + case IPAddressOrRange_addressPrefix: + if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) + return 0; + BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); + continue; + case IPAddressOrRange_addressRange: + if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) + return 0; + BIO_puts(out, "-"); + if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) + return 0; + BIO_puts(out, "\n"); + continue; + } + } + return 1; +} + +/* + * i2r handler for an IPAddrBlocks extension. + */ +static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, + void *ext, BIO *out, int indent) +{ + const IPAddrBlocks *addr = ext; + int i; + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + const unsigned int afi = v3_addr_get_afi(f); + switch (afi) { + case IANA_AFI_IPV4: + BIO_printf(out, "%*sIPv4", indent, ""); + break; + case IANA_AFI_IPV6: + BIO_printf(out, "%*sIPv6", indent, ""); + break; + default: + BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); + break; + } + if (f->addressFamily->length > 2) { + switch (f->addressFamily->data[2]) { + case 1: + BIO_puts(out, " (Unicast)"); + break; + case 2: + BIO_puts(out, " (Multicast)"); + break; + case 3: + BIO_puts(out, " (Unicast/Multicast)"); + break; + case 4: + BIO_puts(out, " (MPLS)"); + break; + case 64: + BIO_puts(out, " (Tunnel)"); + break; + case 65: + BIO_puts(out, " (VPLS)"); + break; + case 66: + BIO_puts(out, " (BGP MDT)"); + break; + case 128: + BIO_puts(out, " (MPLS-labeled VPN)"); + break; + default: + BIO_printf(out, " (Unknown SAFI %u)", + (unsigned)f->addressFamily->data[2]); + break; + } + } + switch (f->ipAddressChoice->type) { + case IPAddressChoice_inherit: + BIO_puts(out, ": inherit\n"); + break; + case IPAddressChoice_addressesOrRanges: + BIO_puts(out, ":\n"); + if (!i2r_IPAddressOrRanges(out, + indent + 2, + f->ipAddressChoice-> + u.addressesOrRanges, afi)) + return 0; + break; + } + } + return 1; +} + +/* + * Sort comparison function for a sequence of IPAddressOrRange + * elements. + * + * There's no sane answer we can give if addr_expand() fails, and an + * assertion failure on externally supplied data is seriously uncool, + * so we just arbitrarily declare that if given invalid inputs this + * function returns -1. If this messes up your preferred sort order + * for garbage input, tough noogies. + */ +static int IPAddressOrRange_cmp(const IPAddressOrRange *a, + const IPAddressOrRange *b, const int length) +{ + unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; + int prefixlen_a = 0, prefixlen_b = 0; + int r; + + switch (a->type) { + case IPAddressOrRange_addressPrefix: + if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) + return -1; + prefixlen_a = addr_prefixlen(a->u.addressPrefix); + break; + case IPAddressOrRange_addressRange: + if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) + return -1; + prefixlen_a = length * 8; + break; + } + + switch (b->type) { + case IPAddressOrRange_addressPrefix: + if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) + return -1; + prefixlen_b = addr_prefixlen(b->u.addressPrefix); + break; + case IPAddressOrRange_addressRange: + if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) + return -1; + prefixlen_b = length * 8; + break; + } + + if ((r = memcmp(addr_a, addr_b, length)) != 0) + return r; + else + return prefixlen_a - prefixlen_b; +} + +/* + * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() + * comparision routines are only allowed two arguments. + */ +static int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, + const IPAddressOrRange *const *b) +{ + return IPAddressOrRange_cmp(*a, *b, 4); +} + +/* + * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() + * comparision routines are only allowed two arguments. + */ +static int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, + const IPAddressOrRange *const *b) +{ + return IPAddressOrRange_cmp(*a, *b, 16); +} + +/* + * Calculate whether a range collapses to a prefix. + * See last paragraph of RFC 3779 2.2.3.7. + */ +static int range_should_be_prefix(const unsigned char *min, + const unsigned char *max, const int length) +{ + unsigned char mask; + int i, j; + + OPENSSL_assert(memcmp(min, max, length) <= 0); + for (i = 0; i < length && min[i] == max[i]; i++) ; + for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ; + if (i < j) + return -1; + if (i > j) + return i * 8; + mask = min[i] ^ max[i]; + switch (mask) { + case 0x01: + j = 7; + break; + case 0x03: + j = 6; + break; + case 0x07: + j = 5; + break; + case 0x0F: + j = 4; + break; + case 0x1F: + j = 3; + break; + case 0x3F: + j = 2; + break; + case 0x7F: + j = 1; + break; + default: + return -1; + } + if ((min[i] & mask) != 0 || (max[i] & mask) != mask) + return -1; + else + return i * 8 + j; +} + +/* + * Construct a prefix. + */ +static int make_addressPrefix(IPAddressOrRange **result, + unsigned char *addr, const int prefixlen) +{ + int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; + IPAddressOrRange *aor = IPAddressOrRange_new(); + + if (aor == NULL) + return 0; + aor->type = IPAddressOrRange_addressPrefix; + if (aor->u.addressPrefix == NULL && + (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) + goto err; + if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) + goto err; + aor->u.addressPrefix->flags &= ~7; + aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (bitlen > 0) { + aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); + aor->u.addressPrefix->flags |= 8 - bitlen; + } + + *result = aor; + return 1; + + err: + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Construct a range. If it can be expressed as a prefix, + * return a prefix instead. Doing this here simplifies + * the rest of the code considerably. + */ +static int make_addressRange(IPAddressOrRange **result, + unsigned char *min, + unsigned char *max, const int length) +{ + IPAddressOrRange *aor; + int i, prefixlen; + + if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) + return make_addressPrefix(result, min, prefixlen); + + if ((aor = IPAddressOrRange_new()) == NULL) + return 0; + aor->type = IPAddressOrRange_addressRange; + OPENSSL_assert(aor->u.addressRange == NULL); + if ((aor->u.addressRange = IPAddressRange_new()) == NULL) + goto err; + if (aor->u.addressRange->min == NULL && + (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) + goto err; + if (aor->u.addressRange->max == NULL && + (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) + goto err; + + for (i = length; i > 0 && min[i - 1] == 0x00; --i) ; + if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) + goto err; + aor->u.addressRange->min->flags &= ~7; + aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (i > 0) { + unsigned char b = min[i - 1]; + int j = 1; + while ((b & (0xFFU >> j)) != 0) + ++j; + aor->u.addressRange->min->flags |= 8 - j; + } + + for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ; + if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) + goto err; + aor->u.addressRange->max->flags &= ~7; + aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (i > 0) { + unsigned char b = max[i - 1]; + int j = 1; + while ((b & (0xFFU >> j)) != (0xFFU >> j)) + ++j; + aor->u.addressRange->max->flags |= 8 - j; + } + + *result = aor; + return 1; + + err: + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Construct a new address family or find an existing one. + */ +static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, + const unsigned afi, + const unsigned *safi) +{ + IPAddressFamily *f; + unsigned char key[3]; + unsigned keylen; + int i; + + key[0] = (afi >> 8) & 0xFF; + key[1] = afi & 0xFF; + if (safi != NULL) { + key[2] = *safi & 0xFF; + keylen = 3; + } else { + keylen = 2; + } + + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + f = sk_IPAddressFamily_value(addr, i); + OPENSSL_assert(f->addressFamily->data != NULL); + if (f->addressFamily->length == keylen && + !memcmp(f->addressFamily->data, key, keylen)) + return f; + } + + if ((f = IPAddressFamily_new()) == NULL) + goto err; + if (f->ipAddressChoice == NULL && + (f->ipAddressChoice = IPAddressChoice_new()) == NULL) + goto err; + if (f->addressFamily == NULL && + (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) + goto err; + if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) + goto err; + if (!sk_IPAddressFamily_push(addr, f)) + goto err; + + return f; + + err: + IPAddressFamily_free(f); + return NULL; +} + +/* + * Add an inheritance element. + */ +int v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi) +{ + IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); + if (f == NULL || + f->ipAddressChoice == NULL || + (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && + f->ipAddressChoice->u.addressesOrRanges != NULL)) + return 0; + if (f->ipAddressChoice->type == IPAddressChoice_inherit && + f->ipAddressChoice->u.inherit != NULL) + return 1; + if (f->ipAddressChoice->u.inherit == NULL && + (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) + return 0; + f->ipAddressChoice->type = IPAddressChoice_inherit; + return 1; +} + +/* + * Construct an IPAddressOrRange sequence, or return an existing one. + */ +static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, + const unsigned afi, + const unsigned *safi) +{ + IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); + IPAddressOrRanges *aors = NULL; + + if (f == NULL || + f->ipAddressChoice == NULL || + (f->ipAddressChoice->type == IPAddressChoice_inherit && + f->ipAddressChoice->u.inherit != NULL)) + return NULL; + if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) + aors = f->ipAddressChoice->u.addressesOrRanges; + if (aors != NULL) + return aors; + if ((aors = sk_IPAddressOrRange_new_null()) == NULL) + return NULL; + switch (afi) { + case IANA_AFI_IPV4: + (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); + break; + case IANA_AFI_IPV6: + (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); + break; + } + f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; + f->ipAddressChoice->u.addressesOrRanges = aors; + return aors; +} + +/* + * Add a prefix. + */ +int v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, + const unsigned *safi, + unsigned char *a, const int prefixlen) +{ + IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); + IPAddressOrRange *aor; + if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) + return 0; + if (sk_IPAddressOrRange_push(aors, aor)) + return 1; + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Add a range. + */ +int v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, + const unsigned *safi, + unsigned char *min, unsigned char *max) +{ + IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); + IPAddressOrRange *aor; + int length = length_from_afi(afi); + if (aors == NULL) + return 0; + if (!make_addressRange(&aor, min, max, length)) + return 0; + if (sk_IPAddressOrRange_push(aors, aor)) + return 1; + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Extract min and max values from an IPAddressOrRange. + */ +static int extract_min_max(IPAddressOrRange *aor, + unsigned char *min, unsigned char *max, int length) +{ + if (aor == NULL || min == NULL || max == NULL) + return 0; + switch (aor->type) { + case IPAddressOrRange_addressPrefix: + return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && + addr_expand(max, aor->u.addressPrefix, length, 0xFF)); + case IPAddressOrRange_addressRange: + return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && + addr_expand(max, aor->u.addressRange->max, length, 0xFF)); + } + return 0; +} + +/* + * Public wrapper for extract_min_max(). + */ +int v3_addr_get_range(IPAddressOrRange *aor, + const unsigned afi, + unsigned char *min, + unsigned char *max, const int length) +{ + int afi_length = length_from_afi(afi); + if (aor == NULL || min == NULL || max == NULL || + afi_length == 0 || length < afi_length || + (aor->type != IPAddressOrRange_addressPrefix && + aor->type != IPAddressOrRange_addressRange) || + !extract_min_max(aor, min, max, afi_length)) + return 0; + + return afi_length; +} + +/* + * Sort comparision function for a sequence of IPAddressFamily. + * + * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about + * the ordering: I can read it as meaning that IPv6 without a SAFI + * comes before IPv4 with a SAFI, which seems pretty weird. The + * examples in appendix B suggest that the author intended the + * null-SAFI rule to apply only within a single AFI, which is what I + * would have expected and is what the following code implements. + */ +static int IPAddressFamily_cmp(const IPAddressFamily *const *a_, + const IPAddressFamily *const *b_) +{ + const ASN1_OCTET_STRING *a = (*a_)->addressFamily; + const ASN1_OCTET_STRING *b = (*b_)->addressFamily; + int len = ((a->length <= b->length) ? a->length : b->length); + int cmp = memcmp(a->data, b->data, len); + return cmp ? cmp : a->length - b->length; +} + +/* + * Check whether an IPAddrBLocks is in canonical form. + */ +int v3_addr_is_canonical(IPAddrBlocks *addr) +{ + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; + IPAddressOrRanges *aors; + int i, j, k; + + /* + * Empty extension is cannonical. + */ + if (addr == NULL) + return 1; + + /* + * Check whether the top-level list is in order. + */ + for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { + const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); + const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); + if (IPAddressFamily_cmp(&a, &b) >= 0) + return 0; + } + + /* + * Top level's ok, now check each address family. + */ + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + int length = length_from_afi(v3_addr_get_afi(f)); + + /* + * Inheritance is canonical. Anything other than inheritance or + * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. + */ + if (f == NULL || f->ipAddressChoice == NULL) + return 0; + switch (f->ipAddressChoice->type) { + case IPAddressChoice_inherit: + continue; + case IPAddressChoice_addressesOrRanges: + break; + default: + return 0; + } + + /* + * It's an IPAddressOrRanges sequence, check it. + */ + aors = f->ipAddressChoice->u.addressesOrRanges; + if (sk_IPAddressOrRange_num(aors) == 0) + return 0; + for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); + + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; + + /* + * Punt misordered list, overlapping start, or inverted range. + */ + if (memcmp(a_min, b_min, length) >= 0 || + memcmp(a_min, a_max, length) > 0 || + memcmp(b_min, b_max, length) > 0) + return 0; + + /* + * Punt if adjacent or overlapping. Check for adjacency by + * subtracting one from b_min first. + */ + for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ; + if (memcmp(a_max, b_min, length) >= 0) + return 0; + + /* + * Check for range that should be expressed as a prefix. + */ + if (a->type == IPAddressOrRange_addressRange && + range_should_be_prefix(a_min, a_max, length) >= 0) + return 0; + } + + /* + * Check range to see if it's inverted or should be a + * prefix. + */ + j = sk_IPAddressOrRange_num(aors) - 1; + { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + if (!extract_min_max(a, a_min, a_max, length)) + return 0; + if (memcmp(a_min, a_max, length) > 0 || + range_should_be_prefix(a_min, a_max, length) >= 0) + return 0; + } + } + } + + /* + * If we made it through all that, we're happy. + */ + return 1; +} + +/* + * Whack an IPAddressOrRanges into canonical form. + */ +static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, + const unsigned afi) +{ + int i, j, length = length_from_afi(afi); + + /* + * Sort the IPAddressOrRanges sequence. + */ + sk_IPAddressOrRange_sort(aors); + + /* + * Clean up representation issues, punt on duplicates or overlaps. + */ + for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); + IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; + + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; + + /* + * Punt inverted ranges. + */ + if (memcmp(a_min, a_max, length) > 0 || + memcmp(b_min, b_max, length) > 0) + return 0; + + /* + * Punt overlaps. + */ + if (memcmp(a_max, b_min, length) >= 0) + return 0; + + /* + * Merge if a and b are adjacent. We check for + * adjacency by subtracting one from b_min first. + */ + for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ; + if (memcmp(a_max, b_min, length) == 0) { + IPAddressOrRange *merged; + if (!make_addressRange(&merged, a_min, b_max, length)) + return 0; + (void)sk_IPAddressOrRange_set(aors, i, merged); + (void)sk_IPAddressOrRange_delete(aors, i + 1); + IPAddressOrRange_free(a); + IPAddressOrRange_free(b); + --i; + continue; + } + } + + /* + * Check for inverted final range. + */ + j = sk_IPAddressOrRange_num(aors) - 1; + { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + extract_min_max(a, a_min, a_max, length); + if (memcmp(a_min, a_max, length) > 0) + return 0; + } + } + + return 1; +} + +/* + * Whack an IPAddrBlocks extension into canonical form. + */ +int v3_addr_canonize(IPAddrBlocks *addr) +{ + int i; + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && + !IPAddressOrRanges_canonize(f->ipAddressChoice-> + u.addressesOrRanges, + v3_addr_get_afi(f))) + return 0; + } + (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); + sk_IPAddressFamily_sort(addr); + OPENSSL_assert(v3_addr_is_canonical(addr)); + return 1; +} + +/* + * v2i handler for the IPAddrBlocks extension. + */ +static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values) +{ + static const char v4addr_chars[] = "0123456789."; + static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; + IPAddrBlocks *addr = NULL; + char *s = NULL, *t; + int i; + + if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + CONF_VALUE *val = sk_CONF_VALUE_value(values, i); + unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; + unsigned afi, *safi = NULL, safi_; + const char *addr_chars; + int prefixlen, i1, i2, delim, length; + + if (!name_cmp(val->name, "IPv4")) { + afi = IANA_AFI_IPV4; + } else if (!name_cmp(val->name, "IPv6")) { + afi = IANA_AFI_IPV6; + } else if (!name_cmp(val->name, "IPv4-SAFI")) { + afi = IANA_AFI_IPV4; + safi = &safi_; + } else if (!name_cmp(val->name, "IPv6-SAFI")) { + afi = IANA_AFI_IPV6; + safi = &safi_; + } else { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_err(val); + goto err; + } + + switch (afi) { + case IANA_AFI_IPV4: + addr_chars = v4addr_chars; + break; + case IANA_AFI_IPV6: + addr_chars = v6addr_chars; + break; + } + + length = length_from_afi(afi); + + /* + * Handle SAFI, if any, and BUF_strdup() so we can null-terminate + * the other input values. + */ + if (safi != NULL) { + *safi = strtoul(val->value, &t, 0); + t += strspn(t, " \t"); + if (*safi > 0xFF || *t++ != ':') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); + X509V3_conf_err(val); + goto err; + } + t += strspn(t, " \t"); + s = BUF_strdup(t); + } else { + s = BUF_strdup(val->value); + } + if (s == NULL) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Check for inheritance. Not worth additional complexity to + * optimize this (seldom-used) case. + */ + if (!strcmp(s, "inherit")) { + if (!v3_addr_add_inherit(addr, afi, safi)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_INVALID_INHERITANCE); + X509V3_conf_err(val); + goto err; + } + OPENSSL_free(s); + s = NULL; + continue; + } + + i1 = strspn(s, addr_chars); + i2 = i1 + strspn(s + i1, " \t"); + delim = s[i2++]; + s[i1] = '\0'; + + if (a2i_ipadd(min, s) != length) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); + X509V3_conf_err(val); + goto err; + } + + switch (delim) { + case '/': + prefixlen = (int)strtoul(s + i2, &t, 10); + if (t == s + i2 || *t != '\0') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + goto err; + } + break; + case '-': + i1 = i2 + strspn(s + i2, " \t"); + i2 = i1 + strspn(s + i1, addr_chars); + if (i1 == i2 || s[i2] != '\0') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (a2i_ipadd(max, s + i1) != length) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_INVALID_IPADDRESS); + X509V3_conf_err(val); + goto err; + } + if (memcmp(min, max, length_from_afi(afi)) > 0) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (!v3_addr_add_range(addr, afi, safi, min, max)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + goto err; + } + break; + case '\0': + if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + goto err; + } + break; + default: + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + + OPENSSL_free(s); + s = NULL; + } + + /* + * Canonize the result, then we're done. + */ + if (!v3_addr_canonize(addr)) + goto err; + return addr; + + err: + OPENSSL_free(s); + sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); + return NULL; +} + +/* + * OpenSSL dispatch + */ +const X509V3_EXT_METHOD v3_addr = { + NID_sbgp_ipAddrBlock, /* nid */ + 0, /* flags */ + ASN1_ITEM_ref(IPAddrBlocks), /* template */ + 0, 0, 0, 0, /* old functions, ignored */ + 0, /* i2s */ + 0, /* s2i */ + 0, /* i2v */ + v2i_IPAddrBlocks, /* v2i */ + i2r_IPAddrBlocks, /* i2r */ + 0, /* r2i */ + NULL /* extension-specific data */ +}; + +/* + * Figure out whether extension sues inheritance. + */ +int v3_addr_inherits(IPAddrBlocks *addr) +{ + int i; + if (addr == NULL) + return 0; + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + if (f->ipAddressChoice->type == IPAddressChoice_inherit) + return 1; + } + return 0; +} + +/* + * Figure out whether parent contains child. + */ +static int addr_contains(IPAddressOrRanges *parent, + IPAddressOrRanges *child, int length) +{ + unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; + unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; + int p, c; + + if (child == NULL || parent == child) + return 1; + if (parent == NULL) + return 0; + + p = 0; + for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { + if (!extract_min_max(sk_IPAddressOrRange_value(child, c), + c_min, c_max, length)) + return -1; + for (;; p++) { + if (p >= sk_IPAddressOrRange_num(parent)) + return 0; + if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), + p_min, p_max, length)) + return 0; + if (memcmp(p_max, c_max, length) < 0) + continue; + if (memcmp(p_min, c_min, length) > 0) + return 0; + break; + } + } + + return 1; +} + +/* + * Test whether a is a subset of b. + */ +int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) +{ + int i; + if (a == NULL || a == b) + return 1; + if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) + return 0; + (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); + for (i = 0; i < sk_IPAddressFamily_num(a); i++) { + IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); + int j = sk_IPAddressFamily_find(b, fa); + IPAddressFamily *fb; + fb = sk_IPAddressFamily_value(b, j); + if (fb == NULL) + return 0; + if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, + fa->ipAddressChoice->u.addressesOrRanges, + length_from_afi(v3_addr_get_afi(fb)))) + return 0; + } + return 1; +} + +/* + * Validation error handling via callback. + */ +# define validation_err(_err_) \ + do { \ + if (ctx != NULL) { \ + ctx->error = _err_; \ + ctx->error_depth = i; \ + ctx->current_cert = x; \ + ret = ctx->verify_cb(0, ctx); \ + } else { \ + ret = 0; \ + } \ + if (!ret) \ + goto done; \ + } while (0) + +/* + * Core code for RFC 3779 2.3 path validation. + * + * Returns 1 for success, 0 on error. + * + * When returning 0, ctx->error MUST be set to an appropriate value other than + * X509_V_OK. + */ +static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, + STACK_OF(X509) *chain, + IPAddrBlocks *ext) +{ + IPAddrBlocks *child = NULL; + int i, j, ret = 1; + X509 *x; + + OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); + OPENSSL_assert(ctx != NULL || ext != NULL); + OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); + + /* + * Figure out where to start. If we don't have an extension to + * check, we're done. Otherwise, check canonical form and + * set up for walking up the chain. + */ + if (ext != NULL) { + i = -1; + x = NULL; + } else { + i = 0; + x = sk_X509_value(chain, i); + OPENSSL_assert(x != NULL); + if ((ext = x->rfc3779_addr) == NULL) + goto done; + } + if (!v3_addr_is_canonical(ext)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); + if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { + X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, + ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ret = 0; + goto done; + } + + /* + * Now walk up the chain. No cert may list resources that its + * parent doesn't list. + */ + for (i++; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + OPENSSL_assert(x != NULL); + if (!v3_addr_is_canonical(x->rfc3779_addr)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (x->rfc3779_addr == NULL) { + for (j = 0; j < sk_IPAddressFamily_num(child); j++) { + IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); + if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + break; + } + } + continue; + } + (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, + IPAddressFamily_cmp); + for (j = 0; j < sk_IPAddressFamily_num(child); j++) { + IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); + int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); + IPAddressFamily *fp = + sk_IPAddressFamily_value(x->rfc3779_addr, k); + if (fp == NULL) { + if (fc->ipAddressChoice->type == + IPAddressChoice_addressesOrRanges) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + break; + } + continue; + } + if (fp->ipAddressChoice->type == + IPAddressChoice_addressesOrRanges) { + if (fc->ipAddressChoice->type == IPAddressChoice_inherit + || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, + fc->ipAddressChoice->u.addressesOrRanges, + length_from_afi(v3_addr_get_afi(fc)))) + sk_IPAddressFamily_set(child, j, fp); + else + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + } + + /* + * Trust anchor can't inherit. + */ + OPENSSL_assert(x != NULL); + if (x->rfc3779_addr != NULL) { + for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { + IPAddressFamily *fp = + sk_IPAddressFamily_value(x->rfc3779_addr, j); + if (fp->ipAddressChoice->type == IPAddressChoice_inherit + && sk_IPAddressFamily_find(child, fp) >= 0) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + + done: + sk_IPAddressFamily_free(child); + return ret; +} + +# undef validation_err + +/* + * RFC 3779 2.3 path validation -- called from X509_verify_cert(). + */ +int v3_addr_validate_path(X509_STORE_CTX *ctx) +{ + return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); +} + +/* + * RFC 3779 2.3 path validation of an extension. + * Test whether chain covers extension. + */ +int v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance) +{ + if (ext == NULL) + return 1; + if (chain == NULL || sk_X509_num(chain) == 0) + return 0; + if (!allow_inheritance && v3_addr_inherits(ext)) + return 0; + return v3_addr_validate_path_internal(NULL, chain, ext); +} + +#endif /* OPENSSL_NO_RFC3779 */ +/* v3_akey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, + STACK_OF(CONF_VALUE) + *extlist); +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_akey_id = { + NID_authority_key_identifier, + X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID, + (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, + 0, 0, + NULL +}; + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, + STACK_OF(CONF_VALUE) + *extlist) +{ + char *tmp; + if (akeyid->keyid) { + tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length); + X509V3_add_value("keyid", tmp, &extlist); + OPENSSL_free(tmp); + } + if (akeyid->issuer) + extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); + if (akeyid->serial) { + tmp = hex_to_string(akeyid->serial->data, akeyid->serial->length); + X509V3_add_value("serial", tmp, &extlist); + OPENSSL_free(tmp); + } + return extlist; +} + +/*- + * Currently two options: + * keyid: use the issuers subject keyid, the value 'always' means its is + * an error if the issuer certificate doesn't have a key id. + * issuer: use the issuers cert issuer and serial number. The default is + * to only use this if keyid is not present. With the option 'always' + * this is always included. + */ + +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + char keyid = 0, issuer = 0; + int i; + CONF_VALUE *cnf; + ASN1_OCTET_STRING *ikeyid = NULL; + X509_NAME *isname = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + ASN1_INTEGER *serial = NULL; + X509_EXTENSION *ext; + X509 *cert; + AUTHORITY_KEYID *akeyid; + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + cnf = sk_CONF_VALUE_value(values, i); + if (!strcmp(cnf->name, "keyid")) { + keyid = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + keyid = 2; + } else if (!strcmp(cnf->name, "issuer")) { + issuer = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + issuer = 2; + } else { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION); + ERR_add_error_data(2, "name=", cnf->name); + return NULL; + } + } + + if (!ctx || !ctx->issuer_cert) { + if (ctx && (ctx->flags == CTX_TEST)) + return AUTHORITY_KEYID_new(); + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_NO_ISSUER_CERTIFICATE); + return NULL; + } + + cert = ctx->issuer_cert; + + if (keyid) { + i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); + if ((i >= 0) && (ext = X509_get_ext(cert, i))) + ikeyid = X509V3_EXT_d2i(ext); + if (keyid == 2 && !ikeyid) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); + return NULL; + } + } + + if ((issuer && !ikeyid) || (issuer == 2)) { + isname = X509_NAME_dup(X509_get_issuer_name(cert)); + serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)); + if (!isname || !serial) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); + goto err; + } + } + + if (!(akeyid = AUTHORITY_KEYID_new())) + goto err; + + if (isname) { + if (!(gens = sk_GENERAL_NAME_new_null()) + || !(gen = GENERAL_NAME_new()) + || !sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->type = GEN_DIRNAME; + gen->d.dirn = isname; + } + + akeyid->issuer = gens; + akeyid->serial = serial; + akeyid->keyid = ikeyid; + + return akeyid; + + err: + X509_NAME_free(isname); + M_ASN1_INTEGER_free(serial); + M_ASN1_OCTET_STRING_free(ikeyid); + return NULL; +} +/* v3_akey_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" + +ASN1_SEQUENCE(AUTHORITY_KEYID) = { + ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), + ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), + ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) +} ASN1_SEQUENCE_END(AUTHORITY_KEYID) + +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) +/* v3_alt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "x509v3.h" + +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); + +const X509V3_EXT_METHOD v3_alt[] = { + {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + (X509V3_EXT_V2I)v2i_subject_alt, + NULL, NULL, NULL}, + + {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + (X509V3_EXT_V2I)v2i_issuer_alt, + NULL, NULL, NULL}, + + {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + NULL, NULL, NULL, NULL}, +}; + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gens, + STACK_OF(CONF_VALUE) *ret) +{ + int i; + GENERAL_NAME *gen; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + ret = i2v_GENERAL_NAME(method, gen, ret); + } + if (!ret) + return sk_CONF_VALUE_new_null(); + return ret; +} + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret) +{ + unsigned char *p; + char oline[256], htmp[5]; + int i; + switch (gen->type) { + case GEN_OTHERNAME: + if (!X509V3_add_value("othername", "", &ret)) + return NULL; + break; + + case GEN_X400: + if (!X509V3_add_value("X400Name", "", &ret)) + return NULL; + break; + + case GEN_EDIPARTY: + if (!X509V3_add_value("EdiPartyName", "", &ret)) + return NULL; + break; + + case GEN_EMAIL: + if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) + return NULL; + break; + + case GEN_DNS: + if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) + return NULL; + break; + + case GEN_URI: + if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) + return NULL; + break; + + case GEN_DIRNAME: + if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL + || !X509V3_add_value("DirName", oline, &ret)) + return NULL; + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + BIO_snprintf(oline, sizeof(oline), + "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + oline[0] = 0; + for (i = 0; i < 8; i++) { + BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]); + p += 2; + strcat(oline, htmp); + if (i != 7) + strcat(oline, ":"); + } + } else { + if (!X509V3_add_value("IP Address", "", &ret)) + return NULL; + break; + } + if (!X509V3_add_value("IP Address", oline, &ret)) + return NULL; + break; + + case GEN_RID: + i2t_ASN1_OBJECT(oline, 256, gen->d.rid); + if (!X509V3_add_value("Registered ID", oline, &ret)) + return NULL; + break; + } + return ret; +} + +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) +{ + unsigned char *p; + int i; + switch (gen->type) { + case GEN_OTHERNAME: + BIO_printf(out, "othername:"); + break; + + case GEN_X400: + BIO_printf(out, "X400Name:"); + break; + + case GEN_EDIPARTY: + /* Maybe fix this: it is supported now */ + BIO_printf(out, "EdiPartyName:"); + break; + + case GEN_EMAIL: + BIO_printf(out, "email:%s", gen->d.ia5->data); + break; + + case GEN_DNS: + BIO_printf(out, "DNS:%s", gen->d.ia5->data); + break; + + case GEN_URI: + BIO_printf(out, "URI:%s", gen->d.ia5->data); + break; + + case GEN_DIRNAME: + BIO_printf(out, "DirName: "); + X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + BIO_printf(out, "IP Address"); + for (i = 0; i < 8; i++) { + BIO_printf(out, ":%X", p[0] << 8 | p[1]); + p += 2; + } + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "IP Address:"); + break; + } + break; + + case GEN_RID: + BIO_printf(out, "Registered ID"); + i2a_ASN1_OBJECT(out, gen->d.rid); + break; + } + return 1; +} + +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!name_cmp(cnf->name, "issuer") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_issuer(ctx, gens)) + goto err; + } else { + GENERAL_NAME *gen; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Append subject altname of issuer to issuer alt name of subject */ + +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) +{ + GENERAL_NAMES *ialt; + GENERAL_NAME *gen; + X509_EXTENSION *ext; + int i; + if (ctx && (ctx->flags == CTX_TEST)) + return 1; + if (!ctx || !ctx->issuer_cert) { + X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); + goto err; + } + i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); + if (i < 0) + return 1; + if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || + !(ialt = X509V3_EXT_d2i(ext))) { + X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { + gen = sk_GENERAL_NAME_value(ialt, i); + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_GENERAL_NAME_free(ialt); + + return 1; + + err: + return 0; + +} + +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_email(ctx, gens, 0)) + goto err; + } else if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "move")) { + if (!copy_email(ctx, gens, 1)) + goto err; + } else { + GENERAL_NAME *gen; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* + * Copy any email addresses in a certificate or request to GENERAL_NAMES + */ + +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) +{ + X509_NAME *nm; + ASN1_IA5STRING *email = NULL; + X509_NAME_ENTRY *ne; + GENERAL_NAME *gen = NULL; + int i; + if (ctx != NULL && ctx->flags == CTX_TEST) + return 1; + if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); + goto err; + } + /* Find the subject name */ + if (ctx->subject_cert) + nm = X509_get_subject_name(ctx->subject_cert); + else + nm = X509_REQ_get_subject_name(ctx->subject_req); + + /* Now add any email address(es) to STACK */ + i = -1; + while ((i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(nm, i); + email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); + if (move_p) { + X509_NAME_delete_entry(nm, i); + X509_NAME_ENTRY_free(ne); + i--; + } + if (!email || !(gen = GENERAL_NAME_new())) { + X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); + goto err; + } + gen = NULL; + } + + return 1; + + err: + GENERAL_NAME_free(gen); + M_ASN1_IA5STRING_free(email); + return 0; + +} + +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAME *gen; + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf) +{ + return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); +} + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, char *value, + int is_nc) +{ + char is_string = 0; + GENERAL_NAME *gen = NULL; + + if (!value) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (out) + gen = out; + else { + gen = GENERAL_NAME_new(); + if (gen == NULL) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); + return NULL; + } + } + + switch (gen_type) { + case GEN_URI: + case GEN_EMAIL: + case GEN_DNS: + is_string = 1; + break; + + case GEN_RID: + { + ASN1_OBJECT *obj; + if (!(obj = OBJ_txt2obj(value, 0))) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", value); + goto err; + } + gen->d.rid = obj; + } + break; + + case GEN_IPADD: + if (is_nc) + gen->d.ip = a2i_IPADDRESS_NC(value); + else + gen->d.ip = a2i_IPADDRESS(value); + if (gen->d.ip == NULL) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS); + ERR_add_error_data(2, "value=", value); + goto err; + } + break; + + case GEN_DIRNAME: + if (!do_dirname(gen, value, ctx)) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR); + goto err; + } + break; + + case GEN_OTHERNAME: + if (!do_othername(gen, value, ctx)) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR); + goto err; + } + break; + default: + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); + goto err; + } + + if (is_string) { + if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || + !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, + strlen(value))) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + gen->type = gen_type; + + return gen; + + err: + if (!out) + GENERAL_NAME_free(gen); + return NULL; +} + +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) +{ + int type; + + char *name, *value; + + name = cnf->name; + value = cnf->value; + + if (!value) { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (!name_cmp(name, "email")) + type = GEN_EMAIL; + else if (!name_cmp(name, "URI")) + type = GEN_URI; + else if (!name_cmp(name, "DNS")) + type = GEN_DNS; + else if (!name_cmp(name, "RID")) + type = GEN_RID; + else if (!name_cmp(name, "IP")) + type = GEN_IPADD; + else if (!name_cmp(name, "dirName")) + type = GEN_DIRNAME; + else if (!name_cmp(name, "otherName")) + type = GEN_OTHERNAME; + else { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); + ERR_add_error_data(2, "name=", name); + return NULL; + } + + return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); + +} + +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +{ + char *objtmp = NULL, *p; + int objlen; + if (!(p = strchr(value, ';'))) + return 0; + if (!(gen->d.otherName = OTHERNAME_new())) + return 0; + /* + * Free this up because we will overwrite it. no need to free type_id + * because it is static + */ + ASN1_TYPE_free(gen->d.otherName->value); + if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) + return 0; + objlen = p - value; + objtmp = OPENSSL_malloc(objlen + 1); + if (objtmp == NULL) + return 0; + strncpy(objtmp, value, objlen); + objtmp[objlen] = 0; + gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); + OPENSSL_free(objtmp); + if (!gen->d.otherName->type_id) + return 0; + return 1; +} + +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +{ + int ret = 0; + STACK_OF(CONF_VALUE) *sk = NULL; + X509_NAME *nm = NULL; + if (!(nm = X509_NAME_new())) + goto err; + sk = X509V3_get_section(ctx, value); + if (!sk) { + X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); + ERR_add_error_data(2, "section=", value); + goto err; + } + /* FIXME: should allow other character types... */ + ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); + if (!ret) + goto err; + gen->d.dirn = nm; + +err: + if (ret == 0) + X509_NAME_free(nm); + X509V3_section_free(ctx, sk); + return ret; +} +/* + * Contributed to the OpenSSL Project by the American Registry for + * Internet Numbers ("ARIN"). + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +/* + * Implementation of RFC 3779 section 3.2. + */ + +#include +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" +#include "x509.h" +#include "bn.h" + +#ifndef OPENSSL_NO_RFC3779 + +/* + * OpenSSL ASN.1 template translation of RFC 3779 3.2.3. + */ + +ASN1_SEQUENCE(ASRange) = { + ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), + ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) +} ASN1_SEQUENCE_END(ASRange) + +ASN1_CHOICE(ASIdOrRange) = { + ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), + ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) +} ASN1_CHOICE_END(ASIdOrRange) + +ASN1_CHOICE(ASIdentifierChoice) = { + ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), + ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) +} ASN1_CHOICE_END(ASIdentifierChoice) + +ASN1_SEQUENCE(ASIdentifiers) = { + ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), + ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) +} ASN1_SEQUENCE_END(ASIdentifiers) + +IMPLEMENT_ASN1_FUNCTIONS(ASRange) +IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange) +IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice) +IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) + +/* + * i2r method for an ASIdentifierChoice. + */ +static int i2r_ASIdentifierChoice(BIO *out, + ASIdentifierChoice *choice, + int indent, const char *msg) +{ + int i; + char *s; + if (choice == NULL) + return 1; + BIO_printf(out, "%*s%s:\n", indent, "", msg); + switch (choice->type) { + case ASIdentifierChoice_inherit: + BIO_printf(out, "%*sinherit\n", indent + 2, ""); + break; + case ASIdentifierChoice_asIdsOrRanges: + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) { + ASIdOrRange *aor = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + switch (aor->type) { + case ASIdOrRange_id: + if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL) + return 0; + BIO_printf(out, "%*s%s\n", indent + 2, "", s); + OPENSSL_free(s); + break; + case ASIdOrRange_range: + if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL) + return 0; + BIO_printf(out, "%*s%s-", indent + 2, "", s); + OPENSSL_free(s); + if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL) + return 0; + BIO_printf(out, "%s\n", s); + OPENSSL_free(s); + break; + default: + return 0; + } + } + break; + default: + return 0; + } + return 1; +} + +/* + * i2r method for an ASIdentifier extension. + */ +static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, + void *ext, BIO *out, int indent) +{ + ASIdentifiers *asid = ext; + return (i2r_ASIdentifierChoice(out, asid->asnum, indent, + "Autonomous System Numbers") && + i2r_ASIdentifierChoice(out, asid->rdi, indent, + "Routing Domain Identifiers")); +} + +/* + * Sort comparision function for a sequence of ASIdOrRange elements. + */ +static int ASIdOrRange_cmp(const ASIdOrRange *const *a_, + const ASIdOrRange *const *b_) +{ + const ASIdOrRange *a = *a_, *b = *b_; + + OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || + (a->type == ASIdOrRange_range && a->u.range != NULL && + a->u.range->min != NULL && a->u.range->max != NULL)); + + OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || + (b->type == ASIdOrRange_range && b->u.range != NULL && + b->u.range->min != NULL && b->u.range->max != NULL)); + + if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) + return ASN1_INTEGER_cmp(a->u.id, b->u.id); + + if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { + int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); + return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, + b->u.range->max); + } + + if (a->type == ASIdOrRange_id) + return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); + else + return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); +} + +/* + * Add an inherit element. + */ +int v3_asid_add_inherit(ASIdentifiers *asid, int which) +{ + ASIdentifierChoice **choice; + if (asid == NULL) + return 0; + switch (which) { + case V3_ASID_ASNUM: + choice = &asid->asnum; + break; + case V3_ASID_RDI: + choice = &asid->rdi; + break; + default: + return 0; + } + if (*choice == NULL) { + if ((*choice = ASIdentifierChoice_new()) == NULL) + return 0; + OPENSSL_assert((*choice)->u.inherit == NULL); + if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) + return 0; + (*choice)->type = ASIdentifierChoice_inherit; + } + return (*choice)->type == ASIdentifierChoice_inherit; +} + +/* + * Add an ID or range to an ASIdentifierChoice. + */ +int v3_asid_add_id_or_range(ASIdentifiers *asid, + int which, ASN1_INTEGER *min, ASN1_INTEGER *max) +{ + ASIdentifierChoice **choice; + ASIdOrRange *aor; + if (asid == NULL) + return 0; + switch (which) { + case V3_ASID_ASNUM: + choice = &asid->asnum; + break; + case V3_ASID_RDI: + choice = &asid->rdi; + break; + default: + return 0; + } + if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) + return 0; + if (*choice == NULL) { + if ((*choice = ASIdentifierChoice_new()) == NULL) + return 0; + OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); + (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); + if ((*choice)->u.asIdsOrRanges == NULL) + return 0; + (*choice)->type = ASIdentifierChoice_asIdsOrRanges; + } + if ((aor = ASIdOrRange_new()) == NULL) + return 0; + if (max == NULL) { + aor->type = ASIdOrRange_id; + aor->u.id = min; + } else { + aor->type = ASIdOrRange_range; + if ((aor->u.range = ASRange_new()) == NULL) + goto err; + ASN1_INTEGER_free(aor->u.range->min); + aor->u.range->min = min; + ASN1_INTEGER_free(aor->u.range->max); + aor->u.range->max = max; + } + if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) + goto err; + return 1; + + err: + ASIdOrRange_free(aor); + return 0; +} + +/* + * Extract min and max values from an ASIdOrRange. + */ +static void extract_min_max(ASIdOrRange *aor, + ASN1_INTEGER **min, ASN1_INTEGER **max) +{ + OPENSSL_assert(aor != NULL && min != NULL && max != NULL); + switch (aor->type) { + case ASIdOrRange_id: + *min = aor->u.id; + *max = aor->u.id; + return; + case ASIdOrRange_range: + *min = aor->u.range->min; + *max = aor->u.range->max; + return; + } +} + +/* + * Check whether an ASIdentifierChoice is in canonical form. + */ +static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) +{ + ASN1_INTEGER *a_max_plus_one = NULL; + BIGNUM *bn = NULL; + int i, ret = 0; + + /* + * Empty element or inheritance is canonical. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If not a list, or if empty list, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) + return 0; + + /* + * It's a list, check it. + */ + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); + ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; + + extract_min_max(a, &a_min, &a_max); + extract_min_max(b, &b_min, &b_max); + + /* + * Punt misordered list, overlapping start, or inverted range. + */ + if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || + ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* + * Calculate a_max + 1 to check for adjacency. + */ + if ((bn == NULL && (bn = BN_new()) == NULL) || + ASN1_INTEGER_to_BN(a_max, bn) == NULL || + !BN_add_word(bn, 1) || + (a_max_plus_one = + BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, + ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * Punt if adjacent or overlapping. + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) + goto done; + } + + /* + * Check for inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + extract_min_max(a, &a_min, &a_max); + if (ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + + ret = 1; + + done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; +} + +/* + * Check whether an ASIdentifier extension is in canonical form. + */ +int v3_asid_is_canonical(ASIdentifiers *asid) +{ + return (asid == NULL || + (ASIdentifierChoice_is_canonical(asid->asnum) && + ASIdentifierChoice_is_canonical(asid->rdi))); +} + +/* + * Whack an ASIdentifierChoice into canonical form. + */ +static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) +{ + ASN1_INTEGER *a_max_plus_one = NULL; + BIGNUM *bn = NULL; + int i, ret = 0; + + /* + * Nothing to do for empty element or inheritance. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If not a list, or if empty list, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + X509V3_R_EXTENSION_VALUE_ERROR); + return 0; + } + + /* + * We have a non-empty list. Sort it. + */ + sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); + + /* + * Now check for errors and suboptimal encoding, rejecting the + * former and fixing the latter. + */ + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); + ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; + + extract_min_max(a, &a_min, &a_max); + extract_min_max(b, &b_min, &b_max); + + /* + * Make sure we're properly sorted (paranoia). + */ + OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); + + /* + * Punt inverted ranges. + */ + if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* + * Check for overlaps. + */ + if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + X509V3_R_EXTENSION_VALUE_ERROR); + goto done; + } + + /* + * Calculate a_max + 1 to check for adjacency. + */ + if ((bn == NULL && (bn = BN_new()) == NULL) || + ASN1_INTEGER_to_BN(a_max, bn) == NULL || + !BN_add_word(bn, 1) || + (a_max_plus_one = + BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * If a and b are adjacent, merge them. + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { + ASRange *r; + switch (a->type) { + case ASIdOrRange_id: + if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + ERR_R_MALLOC_FAILURE); + goto done; + } + r->min = a_min; + r->max = b_max; + a->type = ASIdOrRange_range; + a->u.range = r; + break; + case ASIdOrRange_range: + ASN1_INTEGER_free(a->u.range->max); + a->u.range->max = b_max; + break; + } + switch (b->type) { + case ASIdOrRange_id: + b->u.id = NULL; + break; + case ASIdOrRange_range: + b->u.range->max = NULL; + break; + } + ASIdOrRange_free(b); + (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); + i--; + continue; + } + } + + /* + * Check for final inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + extract_min_max(a, &a_min, &a_max); + if (ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + + OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ + + ret = 1; + + done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; +} + +/* + * Whack an ASIdentifier extension into canonical form. + */ +int v3_asid_canonize(ASIdentifiers *asid) +{ + return (asid == NULL || + (ASIdentifierChoice_canonize(asid->asnum) && + ASIdentifierChoice_canonize(asid->rdi))); +} + +/* + * v2i method for an ASIdentifier extension. + */ +static void *v2i_ASIdentifiers(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values) +{ + ASN1_INTEGER *min = NULL, *max = NULL; + ASIdentifiers *asid = NULL; + int i; + + if ((asid = ASIdentifiers_new()) == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + CONF_VALUE *val = sk_CONF_VALUE_value(values, i); + int i1, i2, i3, is_range, which; + + /* + * Figure out whether this is an AS or an RDI. + */ + if (!name_cmp(val->name, "AS")) { + which = V3_ASID_ASNUM; + } else if (!name_cmp(val->name, "RDI")) { + which = V3_ASID_RDI; + } else { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_err(val); + goto err; + } + + /* + * Handle inheritance. + */ + if (!strcmp(val->value, "inherit")) { + if (v3_asid_add_inherit(asid, which)) + continue; + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_INHERITANCE); + X509V3_conf_err(val); + goto err; + } + + /* + * Number, range, or mistake, pick it apart and figure out which. + */ + i1 = strspn(val->value, "0123456789"); + if (val->value[i1] == '\0') { + is_range = 0; + } else { + is_range = 1; + i2 = i1 + strspn(val->value + i1, " \t"); + if (val->value[i2] != '-') { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_ASNUMBER); + X509V3_conf_err(val); + goto err; + } + i2++; + i2 = i2 + strspn(val->value + i2, " \t"); + i3 = i2 + strspn(val->value + i2, "0123456789"); + if (val->value[i3] != '\0') { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_ASRANGE); + X509V3_conf_err(val); + goto err; + } + } + + /* + * Syntax is ok, read and add it. + */ + if (!is_range) { + if (!X509V3_get_value_int(val, &min)) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + char *s = BUF_strdup(val->value); + if (s == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + goto err; + } + s[i1] = '\0'; + min = s2i_ASN1_INTEGER(NULL, s); + max = s2i_ASN1_INTEGER(NULL, s + i2); + OPENSSL_free(s); + if (min == NULL || max == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + goto err; + } + if (ASN1_INTEGER_cmp(min, max) > 0) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_EXTENSION_VALUE_ERROR); + goto err; + } + } + if (!v3_asid_add_id_or_range(asid, which, min, max)) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + goto err; + } + min = max = NULL; + } + + /* + * Canonize the result, then we're done. + */ + if (!v3_asid_canonize(asid)) + goto err; + return asid; + + err: + ASIdentifiers_free(asid); + ASN1_INTEGER_free(min); + ASN1_INTEGER_free(max); + return NULL; +} + +/* + * OpenSSL dispatch. + */ +const X509V3_EXT_METHOD v3_asid = { + NID_sbgp_autonomousSysNum, /* nid */ + 0, /* flags */ + ASN1_ITEM_ref(ASIdentifiers), /* template */ + 0, 0, 0, 0, /* old functions, ignored */ + 0, /* i2s */ + 0, /* s2i */ + 0, /* i2v */ + v2i_ASIdentifiers, /* v2i */ + i2r_ASIdentifiers, /* i2r */ + 0, /* r2i */ + NULL /* extension-specific data */ +}; + +/* + * Figure out whether extension uses inheritance. + */ +int v3_asid_inherits(ASIdentifiers *asid) +{ + return (asid != NULL && + ((asid->asnum != NULL && + asid->asnum->type == ASIdentifierChoice_inherit) || + (asid->rdi != NULL && + asid->rdi->type == ASIdentifierChoice_inherit))); +} + +/* + * Figure out whether parent contains child. + */ +static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) +{ + ASN1_INTEGER *p_min, *p_max, *c_min, *c_max; + int p, c; + + if (child == NULL || parent == child) + return 1; + if (parent == NULL) + return 0; + + p = 0; + for (c = 0; c < sk_ASIdOrRange_num(child); c++) { + extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max); + for (;; p++) { + if (p >= sk_ASIdOrRange_num(parent)) + return 0; + extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max); + if (ASN1_INTEGER_cmp(p_max, c_max) < 0) + continue; + if (ASN1_INTEGER_cmp(p_min, c_min) > 0) + return 0; + break; + } + } + + return 1; +} + +/* + * Test whether a is a subet of b. + */ +int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) +{ + return (a == NULL || + a == b || + (b != NULL && + !v3_asid_inherits(a) && + !v3_asid_inherits(b) && + asid_contains(b->asnum->u.asIdsOrRanges, + a->asnum->u.asIdsOrRanges) && + asid_contains(b->rdi->u.asIdsOrRanges, + a->rdi->u.asIdsOrRanges))); +} + +/* + * Validation error handling via callback. + */ +# define validation_err(_err_) \ + do { \ + if (ctx != NULL) { \ + ctx->error = _err_; \ + ctx->error_depth = i; \ + ctx->current_cert = x; \ + ret = ctx->verify_cb(0, ctx); \ + } else { \ + ret = 0; \ + } \ + if (!ret) \ + goto done; \ + } while (0) + +/* + * Core code for RFC 3779 3.3 path validation. + */ +static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, + STACK_OF(X509) *chain, + ASIdentifiers *ext) +{ + ASIdOrRanges *child_as = NULL, *child_rdi = NULL; + int i, ret = 1, inherit_as = 0, inherit_rdi = 0; + X509 *x; + + OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); + OPENSSL_assert(ctx != NULL || ext != NULL); + OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); + + /* + * Figure out where to start. If we don't have an extension to + * check, we're done. Otherwise, check canonical form and + * set up for walking up the chain. + */ + if (ext != NULL) { + i = -1; + x = NULL; + } else { + i = 0; + x = sk_X509_value(chain, i); + OPENSSL_assert(x != NULL); + if ((ext = x->rfc3779_asid) == NULL) + goto done; + } + if (!v3_asid_is_canonical(ext)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (ext->asnum != NULL) { + switch (ext->asnum->type) { + case ASIdentifierChoice_inherit: + inherit_as = 1; + break; + case ASIdentifierChoice_asIdsOrRanges: + child_as = ext->asnum->u.asIdsOrRanges; + break; + } + } + if (ext->rdi != NULL) { + switch (ext->rdi->type) { + case ASIdentifierChoice_inherit: + inherit_rdi = 1; + break; + case ASIdentifierChoice_asIdsOrRanges: + child_rdi = ext->rdi->u.asIdsOrRanges; + break; + } + } + + /* + * Now walk up the chain. Extensions must be in canonical form, no + * cert may list resources that its parent doesn't list. + */ + for (i++; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + OPENSSL_assert(x != NULL); + if (x->rfc3779_asid == NULL) { + if (child_as != NULL || child_rdi != NULL) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + continue; + } + if (!v3_asid_is_canonical(x->rfc3779_asid)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + child_as = NULL; + inherit_as = 0; + } + if (x->rfc3779_asid->asnum != NULL && + x->rfc3779_asid->asnum->type == + ASIdentifierChoice_asIdsOrRanges) { + if (inherit_as + || asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, + child_as)) { + child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; + inherit_as = 0; + } else { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + child_rdi = NULL; + inherit_rdi = 0; + } + if (x->rfc3779_asid->rdi != NULL && + x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { + if (inherit_rdi || + asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, + child_rdi)) { + child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; + inherit_rdi = 0; + } else { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + } + + /* + * Trust anchor can't inherit. + */ + OPENSSL_assert(x != NULL); + if (x->rfc3779_asid != NULL) { + if (x->rfc3779_asid->asnum != NULL && + x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + if (x->rfc3779_asid->rdi != NULL && + x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + + done: + return ret; +} + +# undef validation_err + +/* + * RFC 3779 3.3 path validation -- called from X509_verify_cert(). + */ +int v3_asid_validate_path(X509_STORE_CTX *ctx) +{ + return v3_asid_validate_path_internal(ctx, ctx->chain, NULL); +} + +/* + * RFC 3779 3.3 path validation of an extension. + * Test whether chain covers extension. + */ +int v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, int allow_inheritance) +{ + if (ext == NULL) + return 1; + if (chain == NULL || sk_X509_num(chain) == 0) + return 0; + if (!allow_inheritance && v3_asid_inherits(ext)) + return 0; + return v3_asid_validate_path_internal(NULL, chain, ext); +} + +#endif /* OPENSSL_NO_RFC3779 */ +/* v3_bcons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "conf.h" +// #include "x509v3.h" + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) + *extlist); +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_bcons = { + NID_basic_constraints, 0, + ASN1_ITEM_ref(BASIC_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS, + (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, + NULL, NULL, + NULL +}; + +ASN1_SEQUENCE(BASIC_CONSTRAINTS) = { + ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN), + ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER) +} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS) + +IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) + *extlist) +{ + X509V3_add_value_bool("CA", bcons->ca, &extlist); + X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); + return extlist; +} + +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + BASIC_CONSTRAINTS *bcons = NULL; + CONF_VALUE *val; + int i; + if (!(bcons = BASIC_CONSTRAINTS_new())) { + X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "CA")) { + if (!X509V3_get_value_bool(val, &bcons->ca)) + goto err; + } else if (!strcmp(val->name, "pathlen")) { + if (!X509V3_get_value_int(val, &bcons->pathlen)) + goto err; + } else { + X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + return bcons; + err: + BASIC_CONSTRAINTS_free(bcons); + return NULL; +} +/* v3_bitst.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "x509v3.h" + +static BIT_STRING_BITNAME ns_cert_type_table[] = { + {0, "SSL Client", "client"}, + {1, "SSL Server", "server"}, + {2, "S/MIME", "email"}, + {3, "Object Signing", "objsign"}, + {4, "Unused", "reserved"}, + {5, "SSL CA", "sslCA"}, + {6, "S/MIME CA", "emailCA"}, + {7, "Object Signing CA", "objCA"}, + {-1, NULL, NULL} +}; + +static BIT_STRING_BITNAME key_usage_type_table[] = { + {0, "Digital Signature", "digitalSignature"}, + {1, "Non Repudiation", "nonRepudiation"}, + {2, "Key Encipherment", "keyEncipherment"}, + {3, "Data Encipherment", "dataEncipherment"}, + {4, "Key Agreement", "keyAgreement"}, + {5, "Certificate Sign", "keyCertSign"}, + {6, "CRL Sign", "cRLSign"}, + {7, "Encipher Only", "encipherOnly"}, + {8, "Decipher Only", "decipherOnly"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_nscert = +EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); +const X509V3_EXT_METHOD v3_key_usage = +EXT_BITSTRING(NID_key_usage, key_usage_type_table); + +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *ret) +{ + BIT_STRING_BITNAME *bnam; + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) + X509V3_add_value(bnam->lname, NULL, &ret); + } + return ret; +} + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + CONF_VALUE *val; + ASN1_BIT_STRING *bs; + int i; + BIT_STRING_BITNAME *bnam; + if (!(bs = M_ASN1_BIT_STRING_new())) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (!strcmp(bnam->sname, val->name) || + !strcmp(bnam->lname, val->name)) { + if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, + ERR_R_MALLOC_FAILURE); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } + break; + } + } + if (!bnam->lname) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, + X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); + X509V3_conf_err(val); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } + } + return bs; +} +/* v3_conf.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* extension creation utilities */ + +#include +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "x509.h" +// #include "x509v3.h" + +static int v3_check_critical(char **value); +static int v3_check_generic(char **value); +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, + int crit, char *value); +static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, + int crit, int type, + X509V3_CTX *ctx); +static char *conf_lhash_get_string(void *db, char *section, char *value); +static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section); +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, + int ext_nid, int crit, void *ext_struc); +static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, + long *ext_len); +/* CONF *conf: Config file */ +/* char *name: Name */ +/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, + char *value) +{ + int crit; + int ext_type; + X509_EXTENSION *ret; + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(name, value, crit, ext_type, ctx); + ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); + if (!ret) { + X509V3err(X509V3_F_X509V3_EXT_NCONF, X509V3_R_ERROR_IN_EXTENSION); + ERR_add_error_data(4, "name=", name, ", value=", value); + } + return ret; +} + +/* CONF *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + char *value) +{ + int crit; + int ext_type; + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(OBJ_nid2sn(ext_nid), + value, crit, ext_type, ctx); + return do_ext_nconf(conf, ctx, ext_nid, crit, value); +} + +/* CONF *conf: Config file */ +/* char *value: Value */ +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, + int crit, char *value) +{ + const X509V3_EXT_METHOD *method; + X509_EXTENSION *ext; + STACK_OF(CONF_VALUE) *nval; + void *ext_struc; + if (ext_nid == NID_undef) { + X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME); + return NULL; + } + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + /* Now get internal extension representation based on type */ + if (method->v2i) { + if (*value == '@') + nval = NCONF_get_section(conf, value + 1); + else + nval = X509V3_parse_list(value); + if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { + X509V3err(X509V3_F_DO_EXT_NCONF, + X509V3_R_INVALID_EXTENSION_STRING); + ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", + value); + if (*value != '@') + sk_CONF_VALUE_free(nval); + return NULL; + } + ext_struc = method->v2i(method, ctx, nval); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + if (!ext_struc) + return NULL; + } else if (method->s2i) { + if (!(ext_struc = method->s2i(method, ctx, value))) + return NULL; + } else if (method->r2i) { + if (!ctx->db || !ctx->db_meth) { + X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } + if (!(ext_struc = method->r2i(method, ctx, value))) + return NULL; + } else { + X509V3err(X509V3_F_DO_EXT_NCONF, + X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); + ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); + return NULL; + } + + ext = do_ext_i2d(method, ext_nid, crit, ext_struc); + if (method->it) + ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_struc); + return ext; + +} + +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, + int ext_nid, int crit, void *ext_struc) +{ + unsigned char *ext_der; + int ext_len; + ASN1_OCTET_STRING *ext_oct; + X509_EXTENSION *ext; + /* Convert internal representation to DER */ + if (method->it) { + ext_der = NULL; + ext_len = + ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); + if (ext_len < 0) + goto merr; + } else { + unsigned char *p; + ext_len = method->i2d(ext_struc, NULL); + if (!(ext_der = OPENSSL_malloc(ext_len))) + goto merr; + p = ext_der; + method->i2d(ext_struc, &p); + } + if (!(ext_oct = M_ASN1_OCTET_STRING_new())) + goto merr; + ext_oct->data = ext_der; + ext_oct->length = ext_len; + + ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); + if (!ext) + goto merr; + M_ASN1_OCTET_STRING_free(ext_oct); + + return ext; + + merr: + X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE); + return NULL; + +} + +/* Given an internal structure, nid and critical flag create an extension */ + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) +{ + const X509V3_EXT_METHOD *method; + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + return do_ext_i2d(method, ext_nid, crit, ext_struc); +} + +/* Check the extension string for critical flag */ +static int v3_check_critical(char **value) +{ + char *p = *value; + if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) + return 0; + p += 9; + while (isspace((unsigned char)*p)) + p++; + *value = p; + return 1; +} + +/* Check extension string for generic extension and return the type */ +static int v3_check_generic(char **value) +{ + int gen_type = 0; + char *p = *value; + if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { + p += 4; + gen_type = 1; + } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { + p += 5; + gen_type = 2; + } else + return 0; + + while (isspace((unsigned char)*p)) + p++; + *value = p; + return gen_type; +} + +/* Create a generic extension: for now just handle DER type */ +static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, + int crit, int gen_type, + X509V3_CTX *ctx) +{ + unsigned char *ext_der = NULL; + long ext_len; + ASN1_OBJECT *obj = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_EXTENSION *extension = NULL; + if (!(obj = OBJ_txt2obj(ext, 0))) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, + X509V3_R_EXTENSION_NAME_ERROR); + ERR_add_error_data(2, "name=", ext); + goto err; + } + + if (gen_type == 1) + ext_der = string_to_hex(value, &ext_len); + else if (gen_type == 2) + ext_der = generic_asn1(value, ctx, &ext_len); + + if (ext_der == NULL) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, + X509V3_R_EXTENSION_VALUE_ERROR); + ERR_add_error_data(2, "value=", value); + goto err; + } + + if (!(oct = M_ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE); + goto err; + } + + oct->data = ext_der; + oct->length = ext_len; + ext_der = NULL; + + extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); + + err: + ASN1_OBJECT_free(obj); + M_ASN1_OCTET_STRING_free(oct); + if (ext_der) + OPENSSL_free(ext_der); + return extension; + +} + +static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, + long *ext_len) +{ + ASN1_TYPE *typ; + unsigned char *ext_der = NULL; + typ = ASN1_generate_v3(value, ctx); + if (typ == NULL) + return NULL; + *ext_len = i2d_ASN1_TYPE(typ, &ext_der); + ASN1_TYPE_free(typ); + return ext_der; +} + +/* + * This is the main function: add a bunch of extensions based on a config + * file section to an extension STACK. + */ + +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, + STACK_OF(X509_EXTENSION) **sk) +{ + X509_EXTENSION *ext; + STACK_OF(CONF_VALUE) *nval; + CONF_VALUE *val; + int i; + if (!(nval = NCONF_get_section(conf, section))) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) + return 0; + if (sk != NULL) { + if (X509v3_add_ext(sk, ext, -1) == NULL) { + X509_EXTENSION_free(ext); + return 0; + } + } + X509_EXTENSION_free(ext); + } + return 1; +} + +/* + * Convenience functions to add extensions to a certificate, CRL and request + */ + +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509 *cert) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + if (cert) + sk = &cert->cert_info->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Same as above but for a CRL */ + +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_CRL *crl) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + if (crl) + sk = &crl->crl->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Add extensions to certificate request */ + +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_REQ *req) +{ + STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; + int i; + if (req) + sk = &extlist; + i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); + if (!i || !sk) + return i; + i = X509_REQ_add_extensions(req, extlist); + sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); + return i; +} + +/* Config database functions */ + +char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { + X509V3err(X509V3_F_X509V3_GET_STRING, X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + if (ctx->db_meth->get_string) + return ctx->db_meth->get_string(ctx->db, name, section); + return NULL; +} + +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { + X509V3err(X509V3_F_X509V3_GET_SECTION, + X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + if (ctx->db_meth->get_section) + return ctx->db_meth->get_section(ctx->db, section); + return NULL; +} + +void X509V3_string_free(X509V3_CTX *ctx, char *str) +{ + if (!str) + return; + if (ctx->db_meth->free_string) + ctx->db_meth->free_string(ctx->db, str); +} + +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) +{ + if (!section) + return; + if (ctx->db_meth->free_section) + ctx->db_meth->free_section(ctx->db, section); +} + +static char *nconf_get_string(void *db, char *section, char *value) +{ + return NCONF_get_string(db, section, value); +} + +static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section) +{ + return NCONF_get_section(db, section); +} + +static X509V3_CONF_METHOD nconf_method = { + nconf_get_string, + nconf_get_section, + NULL, + NULL +}; + +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) +{ + ctx->db_meth = &nconf_method; + ctx->db = conf; +} + +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, + X509_CRL *crl, int flags) +{ + ctx->issuer_cert = issuer; + ctx->subject_cert = subj; + ctx->crl = crl; + ctx->subject_req = req; + ctx->flags = flags; +} + +/* Old conf compatibility functions */ + +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *name, char *value) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_nconf(&ctmp, ctx, name, value); +} + +/* LHASH *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, char *value) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value); +} + +static char *conf_lhash_get_string(void *db, char *section, char *value) +{ + return CONF_get_string(db, section, value); +} + +static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section) +{ + return CONF_get_section(db, section); +} + +static X509V3_CONF_METHOD conf_lhash_method = { + conf_lhash_get_string, + conf_lhash_get_section, + NULL, + NULL +}; + +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) +{ + ctx->db_meth = &conf_lhash_method; + ctx->db = lhash; +} + +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509 *cert) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert); +} + +/* Same as above but for a CRL */ + +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl); +} + +/* Add extensions to certificate request */ + +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req); +} +/* v3_cpols.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" + +#include "pcy_int.h" + +/* Certificate policies extension support: this one is a bit complex... */ + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent); +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value); +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + int indent); +static void print_notice(BIO *out, USERNOTICE *notice, int indent); +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org); +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org); +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); + +const X509V3_EXT_METHOD v3_cpols = { + NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES), + 0, 0, 0, 0, + 0, 0, + 0, 0, + (X509V3_EXT_I2R)i2r_certpol, + (X509V3_EXT_R2I)r2i_certpol, + NULL +}; + +ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO) +ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES) + +IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) + +ASN1_SEQUENCE(POLICYINFO) = { + ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), + ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO) +} ASN1_SEQUENCE_END(POLICYINFO) + +IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO) + +ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY); + +ASN1_ADB(POLICYQUALINFO) = { + ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)), + ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)) +} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL); + +ASN1_SEQUENCE(POLICYQUALINFO) = { + ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), + ASN1_ADB_OBJECT(POLICYQUALINFO) +} ASN1_SEQUENCE_END(POLICYQUALINFO) + +IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO) + +ASN1_SEQUENCE(USERNOTICE) = { + ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), + ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT) +} ASN1_SEQUENCE_END(USERNOTICE) + +IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE) + +ASN1_SEQUENCE(NOTICEREF) = { + ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), + ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER) +} ASN1_SEQUENCE_END(NOTICEREF) + +IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF) + +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value) +{ + STACK_OF(POLICYINFO) *pols = NULL; + char *pstr; + POLICYINFO *pol; + ASN1_OBJECT *pobj; + STACK_OF(CONF_VALUE) *vals; + CONF_VALUE *cnf; + int i, ia5org; + pols = sk_POLICYINFO_new_null(); + if (pols == NULL) { + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + return NULL; + } + vals = X509V3_parse_list(value); + if (vals == NULL) { + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB); + goto err; + } + ia5org = 0; + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + cnf = sk_CONF_VALUE_value(vals, i); + if (cnf->value || !cnf->name) { + X509V3err(X509V3_F_R2I_CERTPOL, + X509V3_R_INVALID_POLICY_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pstr = cnf->name; + if (!strcmp(pstr, "ia5org")) { + ia5org = 1; + continue; + } else if (*pstr == '@') { + STACK_OF(CONF_VALUE) *polsect; + polsect = X509V3_get_section(ctx, pstr + 1); + if (!polsect) { + X509V3err(X509V3_F_R2I_CERTPOL, X509V3_R_INVALID_SECTION); + + X509V3_conf_err(cnf); + goto err; + } + pol = policy_section(ctx, polsect, ia5org); + X509V3_section_free(ctx, polsect); + if (!pol) + goto err; + } else { + if (!(pobj = OBJ_txt2obj(cnf->name, 0))) { + X509V3err(X509V3_F_R2I_CERTPOL, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol = POLICYINFO_new(); + if (pol == NULL) { + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + goto err; + } + pol->policyid = pobj; + } + if (!sk_POLICYINFO_push(pols, pol)) { + POLICYINFO_free(pol); + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pols; + err: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + sk_POLICYINFO_pop_free(pols, POLICYINFO_free); + return NULL; +} + +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org) +{ + int i; + CONF_VALUE *cnf; + POLICYINFO *pol; + POLICYQUALINFO *qual; + if (!(pol = POLICYINFO_new())) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { + cnf = sk_CONF_VALUE_value(polstrs, i); + if (!strcmp(cnf->name, "policyIdentifier")) { + ASN1_OBJECT *pobj; + if (!(pobj = OBJ_txt2obj(cnf->value, 0))) { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol->policyid = pobj; + + } else if (!name_cmp(cnf->name, "CPS")) { + if (!pol->qualifiers) + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (!(qual = POLICYQUALINFO_new())) + goto merr; + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) + goto merr; + if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_cps))) { + X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!(qual->d.cpsuri = M_ASN1_IA5STRING_new())) + goto merr; + if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!name_cmp(cnf->name, "userNotice")) { + STACK_OF(CONF_VALUE) *unot; + if (*cnf->value != '@') { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_EXPECTED_A_SECTION_NAME); + X509V3_conf_err(cnf); + goto err; + } + unot = X509V3_get_section(ctx, cnf->value + 1); + if (!unot) { + X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_SECTION); + + X509V3_conf_err(cnf); + goto err; + } + qual = notice_section(ctx, unot, ia5org); + X509V3_section_free(ctx, unot); + if (!qual) + goto err; + if (!pol->qualifiers) + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) + goto merr; + } else { + X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_OPTION); + + X509V3_conf_err(cnf); + goto err; + } + } + if (!pol->policyid) { + X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_NO_POLICY_IDENTIFIER); + goto err; + } + + return pol; + + merr: + X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE); + + err: + POLICYINFO_free(pol); + return NULL; + +} + +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org) +{ + int i, ret; + CONF_VALUE *cnf; + USERNOTICE *not; + POLICYQUALINFO *qual; + if (!(qual = POLICYQUALINFO_new())) + goto merr; + if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice))) { + X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!(not = USERNOTICE_new())) + goto merr; + qual->d.usernotice = not; + for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { + cnf = sk_CONF_VALUE_value(unot, i); + if (!strcmp(cnf->name, "explicitText")) { + if (!(not->exptext = M_ASN1_VISIBLESTRING_new())) + goto merr; + if (!ASN1_STRING_set(not->exptext, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "organization")) { + NOTICEREF *nref; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + if (ia5org) + nref->organization->type = V_ASN1_IA5STRING; + else + nref->organization->type = V_ASN1_VISIBLESTRING; + if (!ASN1_STRING_set(nref->organization, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "noticeNumbers")) { + NOTICEREF *nref; + STACK_OF(CONF_VALUE) *nos; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + nos = X509V3_parse_list(cnf->value); + if (!nos || !sk_CONF_VALUE_num(nos)) { + X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_NUMBERS); + X509V3_conf_err(cnf); + goto err; + } + ret = nref_nos(nref->noticenos, nos); + sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); + if (!ret) + goto err; + } else { + X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + + if (not->noticeref && + (!not->noticeref->noticenos || !not->noticeref->organization)) { + X509V3err(X509V3_F_NOTICE_SECTION, + X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + goto err; + } + + return qual; + + merr: + X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE); + + err: + POLICYQUALINFO_free(qual); + return NULL; +} + +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) +{ + CONF_VALUE *cnf; + ASN1_INTEGER *aint; + + int i; + + for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { + cnf = sk_CONF_VALUE_value(nos, i); + if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { + X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER); + goto err; + } + if (!sk_ASN1_INTEGER_push(nnums, aint)) + goto merr; + } + return 1; + + merr: + ASN1_INTEGER_free(aint); + X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE); + + err: + return 0; +} + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent) +{ + int i; + POLICYINFO *pinfo; + /* First print out the policy OIDs */ + for (i = 0; i < sk_POLICYINFO_num(pol); i++) { + pinfo = sk_POLICYINFO_value(pol, i); + BIO_printf(out, "%*sPolicy: ", indent, ""); + i2a_ASN1_OBJECT(out, pinfo->policyid); + BIO_puts(out, "\n"); + if (pinfo->qualifiers) + print_qualifiers(out, pinfo->qualifiers, indent + 2); + } + return 1; +} + +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + int indent) +{ + POLICYQUALINFO *qualinfo; + int i; + for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { + qualinfo = sk_POLICYQUALINFO_value(quals, i); + switch (OBJ_obj2nid(qualinfo->pqualid)) { + case NID_id_qt_cps: + BIO_printf(out, "%*sCPS: %s\n", indent, "", + qualinfo->d.cpsuri->data); + break; + + case NID_id_qt_unotice: + BIO_printf(out, "%*sUser Notice:\n", indent, ""); + print_notice(out, qualinfo->d.usernotice, indent + 2); + break; + + default: + BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, ""); + + i2a_ASN1_OBJECT(out, qualinfo->pqualid); + BIO_puts(out, "\n"); + break; + } + } +} + +static void print_notice(BIO *out, USERNOTICE *notice, int indent) +{ + int i; + if (notice->noticeref) { + NOTICEREF *ref; + ref = notice->noticeref; + BIO_printf(out, "%*sOrganization: %s\n", indent, "", + ref->organization->data); + BIO_printf(out, "%*sNumber%s: ", indent, "", + sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); + for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { + ASN1_INTEGER *num; + char *tmp; + num = sk_ASN1_INTEGER_value(ref->noticenos, i); + if (i) + BIO_puts(out, ", "); + if (num == NULL) + BIO_puts(out, "(null)"); + else { + tmp = i2s_ASN1_INTEGER(NULL, num); + if (tmp == NULL) + return; + BIO_puts(out, tmp); + OPENSSL_free(tmp); + } + } + BIO_puts(out, "\n"); + } + if (notice->exptext) + BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", + notice->exptext->data); +} + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) +{ + const X509_POLICY_DATA *dat = node->data; + + BIO_printf(out, "%*sPolicy: ", indent, ""); + + i2a_ASN1_OBJECT(out, dat->valid_policy); + BIO_puts(out, "\n"); + BIO_printf(out, "%*s%s\n", indent + 2, "", + node_data_critical(dat) ? "Critical" : "Non Critical"); + if (dat->qualifier_set) + print_qualifiers(out, dat->qualifier_set, indent + 2); + else + BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); +} + + +IMPLEMENT_STACK_OF(X509_POLICY_NODE) + +IMPLEMENT_STACK_OF(X509_POLICY_DATA) +/* v3_crld.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" + +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent); + +const X509V3_EXT_METHOD v3_crld = { + NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_crld, + i2r_crldp, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_freshest_crl = { + NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_crld, + i2r_crldp, 0, + NULL +}; + +static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, + char *sect) +{ + STACK_OF(CONF_VALUE) *gnsect; + STACK_OF(GENERAL_NAME) *gens; + if (*sect == '@') + gnsect = X509V3_get_section(ctx, sect + 1); + else + gnsect = X509V3_parse_list(sect); + if (!gnsect) { + X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, X509V3_R_SECTION_NOT_FOUND); + return NULL; + } + gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); + if (*sect == '@') + X509V3_section_free(ctx, gnsect); + else + sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); + return gens; +} + +static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, + CONF_VALUE *cnf) +{ + STACK_OF(GENERAL_NAME) *fnm = NULL; + STACK_OF(X509_NAME_ENTRY) *rnm = NULL; + if (!strncmp(cnf->name, "fullname", 9)) { + fnm = gnames_from_sectname(ctx, cnf->value); + if (!fnm) + goto err; + } else if (!strcmp(cnf->name, "relativename")) { + int ret; + STACK_OF(CONF_VALUE) *dnsect; + X509_NAME *nm; + nm = X509_NAME_new(); + if (!nm) + return -1; + dnsect = X509V3_get_section(ctx, cnf->value); + if (!dnsect) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_SECTION_NOT_FOUND); + return -1; + } + ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); + X509V3_section_free(ctx, dnsect); + rnm = nm->entries; + nm->entries = NULL; + X509_NAME_free(nm); + if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) + goto err; + /* + * Since its a name fragment can't have more than one RDNSequence + */ + if (sk_X509_NAME_ENTRY_value(rnm, + sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } else + return 0; + + if (*pdp) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_DISTPOINT_ALREADY_SET); + goto err; + } + + *pdp = DIST_POINT_NAME_new(); + if (!*pdp) + goto err; + if (fnm) { + (*pdp)->type = 0; + (*pdp)->name.fullname = fnm; + } else { + (*pdp)->type = 1; + (*pdp)->name.relativename = rnm; + } + + return 1; + + err: + if (fnm) + sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); + if (rnm) + sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); + return -1; +} + +static const BIT_STRING_BITNAME reason_flags[] = { + {0, "Unused", "unused"}, + {1, "Key Compromise", "keyCompromise"}, + {2, "CA Compromise", "CACompromise"}, + {3, "Affiliation Changed", "affiliationChanged"}, + {4, "Superseded", "superseded"}, + {5, "Cessation Of Operation", "cessationOfOperation"}, + {6, "Certificate Hold", "certificateHold"}, + {7, "Privilege Withdrawn", "privilegeWithdrawn"}, + {8, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +static int set_reasons(ASN1_BIT_STRING **preas, char *value) +{ + STACK_OF(CONF_VALUE) *rsk = NULL; + const BIT_STRING_BITNAME *pbn; + const char *bnam; + int i, ret = 0; + rsk = X509V3_parse_list(value); + if (!rsk) + return 0; + if (*preas) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { + bnam = sk_CONF_VALUE_value(rsk, i)->name; + if (!*preas) { + *preas = ASN1_BIT_STRING_new(); + if (!*preas) + goto err; + } + for (pbn = reason_flags; pbn->lname; pbn++) { + if (!strcmp(pbn->sname, bnam)) { + if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) + goto err; + break; + } + } + if (!pbn->lname) + goto err; + } + ret = 1; + + err: + sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); + return ret; +} + +static int print_reasons(BIO *out, const char *rname, + ASN1_BIT_STRING *rflags, int indent) +{ + int first = 1; + const BIT_STRING_BITNAME *pbn; + BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); + for (pbn = reason_flags; pbn->lname; pbn++) { + if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { + if (first) + first = 0; + else + BIO_puts(out, ", "); + BIO_puts(out, pbn->lname); + } + } + if (first) + BIO_puts(out, "\n"); + else + BIO_puts(out, "\n"); + return 1; +} + +static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE *cnf; + DIST_POINT *point = NULL; + point = DIST_POINT_new(); + if (!point) + goto err; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + int ret; + cnf = sk_CONF_VALUE_value(nval, i); + ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(cnf->name, "reasons")) { + if (!set_reasons(&point->reasons, cnf->value)) + goto err; + } else if (!strcmp(cnf->name, "CRLissuer")) { + point->CRLissuer = gnames_from_sectname(ctx, cnf->value); + if (!point->CRLissuer) + goto err; + } + } + + return point; + + err: + if (point) + DIST_POINT_free(point); + return NULL; +} + +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + STACK_OF(DIST_POINT) *crld = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + CONF_VALUE *cnf; + int i; + if (!(crld = sk_DIST_POINT_new_null())) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + DIST_POINT *point; + cnf = sk_CONF_VALUE_value(nval, i); + if (!cnf->value) { + STACK_OF(CONF_VALUE) *dpsect; + dpsect = X509V3_get_section(ctx, cnf->name); + if (!dpsect) + goto err; + point = crldp_from_section(ctx, dpsect); + X509V3_section_free(ctx, dpsect); + if (!point) + goto err; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + } else { + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (!(gens = GENERAL_NAMES_new())) + goto merr; + if (!sk_GENERAL_NAME_push(gens, gen)) + goto merr; + gen = NULL; + if (!(point = DIST_POINT_new())) + goto merr; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + if (!(point->distpoint = DIST_POINT_NAME_new())) + goto merr; + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } + } + return crld; + + merr: + X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE); + err: + GENERAL_NAME_free(gen); + GENERAL_NAMES_free(gens); + sk_DIST_POINT_pop_free(crld, DIST_POINT_free); + return NULL; +} + +IMPLEMENT_STACK_OF(DIST_POINT) + +IMPLEMENT_ASN1_SET_OF(DIST_POINT) + +static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; + + switch (operation) { + case ASN1_OP_NEW_POST: + dpn->dpname = NULL; + break; + + case ASN1_OP_FREE_POST: + if (dpn->dpname) + X509_NAME_free(dpn->dpname); + break; + } + return 1; +} + + +ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { + ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), + ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) +} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) + + +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) + +ASN1_SEQUENCE(DIST_POINT) = { + ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), + ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2) +} ASN1_SEQUENCE_END(DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT) + +ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT) +ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) + +IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) + +ASN1_SEQUENCE(ISSUING_DIST_POINT) = { + ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), + ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5) +} ASN1_SEQUENCE_END(ISSUING_DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent); +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); + +const X509V3_EXT_METHOD v3_idp = { + NID_issuing_distribution_point, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ISSUING_DIST_POINT), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_idp, + i2r_idp, 0, + NULL +}; + +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + ISSUING_DIST_POINT *idp = NULL; + CONF_VALUE *cnf; + char *name, *val; + int i, ret; + idp = ISSUING_DIST_POINT_new(); + if (!idp) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + name = cnf->name; + val = cnf->value; + ret = set_dist_point_name(&idp->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(name, "onlyuser")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) + goto err; + } else if (!strcmp(name, "onlyCA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) + goto err; + } else if (!strcmp(name, "onlyAA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) + goto err; + } else if (!strcmp(name, "indirectCRL")) { + if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) + goto err; + } else if (!strcmp(name, "onlysomereasons")) { + if (!set_reasons(&idp->onlysomereasons, val)) + goto err; + } else { + X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; + } + } + return idp; + + merr: + X509V3err(X509V3_F_V2I_IDP, ERR_R_MALLOC_FAILURE); + err: + ISSUING_DIST_POINT_free(idp); + return NULL; +} + +static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) +{ + int i; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + BIO_printf(out, "%*s", indent + 2, ""); + GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); + BIO_puts(out, "\n"); + } + return 1; +} + +static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) +{ + if (dpn->type == 0) { + BIO_printf(out, "%*sFull Name:\n", indent, ""); + print_gens(out, dpn->name.fullname, indent); + } else { + X509_NAME ntmp; + ntmp.entries = dpn->name.relativename; + BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); + X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); + BIO_puts(out, "\n"); + } + return 1; +} + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent) +{ + ISSUING_DIST_POINT *idp = pidp; + if (idp->distpoint) + print_distpoint(out, idp->distpoint, indent); + if (idp->onlyuser > 0) + BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); + if (idp->onlyCA > 0) + BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); + if (idp->indirectCRL > 0) + BIO_printf(out, "%*sIndirect CRL\n", indent, ""); + if (idp->onlysomereasons) + print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent); + if (idp->onlyattr > 0) + BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); + if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) + && (idp->indirectCRL <= 0) && !idp->onlysomereasons + && (idp->onlyattr <= 0)) + BIO_printf(out, "%*s\n", indent, ""); + + return 1; +} + +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent) +{ + STACK_OF(DIST_POINT) *crld = pcrldp; + DIST_POINT *point; + int i; + for (i = 0; i < sk_DIST_POINT_num(crld); i++) { + BIO_puts(out, "\n"); + point = sk_DIST_POINT_value(crld, i); + if (point->distpoint) + print_distpoint(out, point->distpoint, indent); + if (point->reasons) + print_reasons(out, "Reasons", point->reasons, indent); + if (point->CRLissuer) { + BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); + print_gens(out, point->CRLissuer, indent); + } + } + return 1; +} + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) +{ + int i; + STACK_OF(X509_NAME_ENTRY) *frag; + X509_NAME_ENTRY *ne; + if (!dpn || (dpn->type != 1)) + return 1; + frag = dpn->name.relativename; + dpn->dpname = X509_NAME_dup(iname); + if (!dpn->dpname) + return 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { + ne = sk_X509_NAME_ENTRY_value(frag, i); + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + } + /* generate cached encoding of name */ + if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + return 1; +} +/* v3_enum.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "x509v3.h" + +static ENUMERATED_NAMES crl_reasons[] = { + {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, + {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, + {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, + {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", + "affiliationChanged"}, + {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, + {CRL_REASON_CESSATION_OF_OPERATION, + "Cessation Of Operation", "cessationOfOperation"}, + {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, + {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, + {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", + "privilegeWithdrawn"}, + {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_crl_reason = { + NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, + 0, + 0, 0, 0, 0, + crl_reasons +}; + +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e) +{ + ENUMERATED_NAMES *enam; + long strval; + strval = ASN1_ENUMERATED_get(e); + for (enam = method->usr_data; enam->lname; enam++) { + if (strval == enam->bitnum) + return BUF_strdup(enam->lname); + } + return i2s_ASN1_ENUMERATED(method, e); +} +/* v3_extku.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "conf.h" +// #include "x509v3.h" + +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD + *method, void *eku, STACK_OF(CONF_VALUE) + *extlist); + +const X509V3_EXT_METHOD v3_ext_ku = { + NID_ext_key_usage, 0, + ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + 0, 0, 0, 0, + 0, 0, + i2v_EXTENDED_KEY_USAGE, + v2i_EXTENDED_KEY_USAGE, + 0, 0, + NULL +}; + +/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ +const X509V3_EXT_METHOD v3_ocsp_accresp = { + NID_id_pkix_OCSP_acceptableResponses, 0, + ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + 0, 0, 0, 0, + 0, 0, + i2v_EXTENDED_KEY_USAGE, + v2i_EXTENDED_KEY_USAGE, + 0, 0, + NULL +}; + +ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT) +ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE) + +IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) + +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *ext_list) +{ + EXTENDED_KEY_USAGE *eku = a; + int i; + ASN1_OBJECT *obj; + char obj_tmp[80]; + for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + obj = sk_ASN1_OBJECT_value(eku, i); + i2t_ASN1_OBJECT(obj_tmp, 80, obj); + X509V3_add_value(NULL, obj_tmp, &ext_list); + } + return ext_list; +} + +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + EXTENDED_KEY_USAGE *extku; + char *extval; + ASN1_OBJECT *objtmp; + CONF_VALUE *val; + int i; + + if (!(extku = sk_ASN1_OBJECT_new_null())) { + X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (val->value) + extval = val->value; + else + extval = val->name; + if (!(objtmp = OBJ_txt2obj(extval, 0))) { + sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); + X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + sk_ASN1_OBJECT_push(extku, objtmp); + } + return extku; +} +/* v3_genn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "conf.h" +// #include "x509v3.h" + +ASN1_SEQUENCE(OTHERNAME) = { + ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), + /* Maybe have a true ANY DEFINED BY later */ + ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0) +} ASN1_SEQUENCE_END(OTHERNAME) + +IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME) + +ASN1_SEQUENCE(EDIPARTYNAME) = { + ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), + ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) +} ASN1_SEQUENCE_END(EDIPARTYNAME) + +IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME) + +ASN1_CHOICE(GENERAL_NAME) = { + ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), + ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL), + ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS), + /* Don't decode this */ + ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400), + /* X509_NAME is a CHOICE type so use EXPLICIT */ + ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME), + ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY), + ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI), + ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD), + ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID) +} ASN1_CHOICE_END(GENERAL_NAME) + +IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME) + +ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME) +ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) + +IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) + +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a) +{ + return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME, + (d2i_of_void *)d2i_GENERAL_NAME, + (char *)a); +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) +{ + int result = -1; + + if (!a || !b || a->type != b->type) + return -1; + switch (a->type) { + case GEN_X400: + case GEN_EDIPARTY: + result = ASN1_TYPE_cmp(a->d.other, b->d.other); + break; + + case GEN_OTHERNAME: + result = OTHERNAME_cmp(a->d.otherName, b->d.otherName); + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5); + break; + + case GEN_DIRNAME: + result = X509_NAME_cmp(a->d.dirn, b->d.dirn); + break; + + case GEN_IPADD: + result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); + break; + + case GEN_RID: + result = OBJ_cmp(a->d.rid, b->d.rid); + break; + } + return result; +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) +{ + int result = -1; + + if (!a || !b) + return -1; + /* Check their type first. */ + if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) + return result; + /* Check the value. */ + result = ASN1_TYPE_cmp(a->value, b->value); + return result; +} + +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) +{ + switch (type) { + case GEN_X400: + case GEN_EDIPARTY: + a->d.other = value; + break; + + case GEN_OTHERNAME: + a->d.otherName = value; + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + a->d.ia5 = value; + break; + + case GEN_DIRNAME: + a->d.dirn = value; + break; + + case GEN_IPADD: + a->d.ip = value; + break; + + case GEN_RID: + a->d.rid = value; + break; + } + a->type = type; +} + +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) +{ + if (ptype) + *ptype = a->type; + switch (a->type) { + case GEN_X400: + case GEN_EDIPARTY: + return a->d.other; + + case GEN_OTHERNAME: + return a->d.otherName; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + return a->d.ia5; + + case GEN_DIRNAME: + return a->d.dirn; + + case GEN_IPADD: + return a->d.ip; + + case GEN_RID: + return a->d.rid; + + default: + return NULL; + } +} + +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value) +{ + OTHERNAME *oth; + oth = OTHERNAME_new(); + if (!oth) + return 0; + ASN1_TYPE_free(oth->value); + oth->type_id = oid; + oth->value = value; + GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); + return 1; +} + +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue) +{ + if (gen->type != GEN_OTHERNAME) + return 0; + if (poid) + *poid = gen->d.otherName->type_id; + if (pvalue) + *pvalue = gen->d.otherName->value; + return 1; +} +/* v3_ia5.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "conf.h" +// #include "x509v3.h" + +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + ASN1_IA5STRING *ia5); +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); +const X509V3_EXT_METHOD v3_ns_ia5_list[] = { + EXT_IA5STRING(NID_netscape_base_url), + EXT_IA5STRING(NID_netscape_revocation_url), + EXT_IA5STRING(NID_netscape_ca_revocation_url), + EXT_IA5STRING(NID_netscape_renewal_url), + EXT_IA5STRING(NID_netscape_ca_policy_url), + EXT_IA5STRING(NID_netscape_ssl_server_name), + EXT_IA5STRING(NID_netscape_comment), + EXT_END +}; + +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + ASN1_IA5STRING *ia5) +{ + char *tmp; + if (!ia5 || !ia5->length) + return NULL; + if (!(tmp = OPENSSL_malloc(ia5->length + 1))) { + X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + memcpy(tmp, ia5->data, ia5->length); + tmp[ia5->length] = 0; + return tmp; +} + +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + ASN1_IA5STRING *ia5; + if (!str) { + X509V3err(X509V3_F_S2I_ASN1_IA5STRING, + X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(ia5 = M_ASN1_IA5STRING_new())) + goto err; + if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char *)str, + strlen(str))) { + M_ASN1_IA5STRING_free(ia5); + goto err; + } +#ifdef CHARSET_EBCDIC + ebcdic2ascii(ia5->data, ia5->data, ia5->length); +#endif /* CHARSET_EBCDIC */ + return ia5; + err: + X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); + return NULL; +} +/* v3_info.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, AUTHORITY_INFO_ACCESS + *ainfo, STACK_OF(CONF_VALUE) + *ret); +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) + *nval); + +const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, + (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + 0, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, + (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + 0, 0, + NULL +}; + +ASN1_SEQUENCE(ACCESS_DESCRIPTION) = { + ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT), + ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME) +} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION) + +IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) + +ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION) +ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS) + +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( + X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, + STACK_OF(CONF_VALUE) *ret) +{ + ACCESS_DESCRIPTION *desc; + int i, nlen; + char objtmp[80], *ntmp; + CONF_VALUE *vtmp; + STACK_OF(CONF_VALUE) *tret = ret; + + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { + STACK_OF(CONF_VALUE) *tmp; + + desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); + tmp = i2v_GENERAL_NAME(method, desc->location, tret); + if (tmp == NULL) + goto err; + tret = tmp; + vtmp = sk_CONF_VALUE_value(tret, i); + i2t_ASN1_OBJECT(objtmp, sizeof(objtmp), desc->method); + nlen = strlen(objtmp) + strlen(vtmp->name) + 5; + ntmp = OPENSSL_malloc(nlen); + if (ntmp == NULL) + goto err; + BUF_strlcpy(ntmp, objtmp, nlen); + BUF_strlcat(ntmp, " - ", nlen); + BUF_strlcat(ntmp, vtmp->name, nlen); + OPENSSL_free(vtmp->name); + vtmp->name = ntmp; + + } + if (ret == NULL && tret == NULL) + return sk_CONF_VALUE_new_null(); + + return tret; + err: + X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); + if (ret == NULL && tret != NULL) + sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); + return NULL; +} + +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) + *nval) +{ + AUTHORITY_INFO_ACCESS *ainfo = NULL; + CONF_VALUE *cnf, ctmp; + ACCESS_DESCRIPTION *acc; + int i, objlen; + char *objtmp, *ptmp; + if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!(acc = ACCESS_DESCRIPTION_new()) + || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + goto err; + } + ptmp = strchr(cnf->name, ';'); + if (!ptmp) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + X509V3_R_INVALID_SYNTAX); + goto err; + } + objlen = ptmp - cnf->name; + ctmp.name = ptmp + 1; + ctmp.value = cnf->value; + if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) + goto err; + if (!(objtmp = OPENSSL_malloc(objlen + 1))) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + goto err; + } + strncpy(objtmp, cnf->name, objlen); + objtmp[objlen] = 0; + acc->method = OBJ_txt2obj(objtmp, 0); + if (!acc->method) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", objtmp); + OPENSSL_free(objtmp); + goto err; + } + OPENSSL_free(objtmp); + + } + return ainfo; + err: + sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); + return NULL; +} + +int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a) +{ + i2a_ASN1_OBJECT(bp, a->method); +#ifdef UNDEF + i2a_GENERAL_NAME(bp, a->location); +#endif + return 2; +} +/* v3_int.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "x509v3.h" + +const X509V3_EXT_METHOD v3_crl_num = { + NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + 0, + 0, 0, 0, 0, NULL +}; + +const X509V3_EXT_METHOD v3_delta_crl = { + NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + 0, + 0, 0, 0, 0, NULL +}; + +static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, + char *value) +{ + return s2i_ASN1_INTEGER(meth, value); +} + +const X509V3_EXT_METHOD v3_inhibit_anyp = { + NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + (X509V3_EXT_S2I)s2i_asn1_int, + 0, 0, 0, 0, NULL +}; +/* v3_ncons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "conf.h" +// #include "x509v3.h" + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + BIO *bp, int ind); +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, + int ind, char *name); +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); +static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); +static int nc_dn(X509_NAME *sub, X509_NAME *nm); +static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); +static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); + +const X509V3_EXT_METHOD v3_name_constraints = { + NID_name_constraints, 0, + ASN1_ITEM_ref(NAME_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + 0, v2i_NAME_CONSTRAINTS, + i2r_NAME_CONSTRAINTS, 0, + NULL +}; + +ASN1_SEQUENCE(GENERAL_SUBTREE) = { + ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), + ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), + ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1) +} ASN1_SEQUENCE_END(GENERAL_SUBTREE) + +ASN1_SEQUENCE(NAME_CONSTRAINTS) = { + ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, + GENERAL_SUBTREE, 0), + ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, + GENERAL_SUBTREE, 1), +} ASN1_SEQUENCE_END(NAME_CONSTRAINTS) + + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +/* + * We cannot use strncasecmp here because that applies locale specific rules. + * For example in Turkish 'I' is not the uppercase character for 'i'. We need to + * do a simple ASCII case comparison ignoring the locale (that is why we use + * numeric constants below). + */ +static int ia5ncasecmp(const char *s1, const char *s2, size_t n) +{ + for (; n > 0; n--, s1++, s2++) { + if (*s1 != *s2) { + unsigned char c1 = (unsigned char)*s1, c2 = (unsigned char)*s2; + + /* Convert to lower case */ + if (c1 >= 0x41 /* A */ && c1 <= 0x5A /* Z */) + c1 += 0x20; + if (c2 >= 0x41 /* A */ && c2 <= 0x5A /* Z */) + c2 += 0x20; + + if (c1 == c2) + continue; + + if (c1 < c2) + return -1; + + /* c1 > c2 */ + return 1; + } else if (*s1 == 0) { + /* If we get here we know that *s2 == 0 too */ + return 0; + } + } + + return 0; +} + +static int ia5casecmp(const char *s1, const char *s2) +{ + /* No portable definition of SIZE_MAX, so we use (size_t)(-1) instead */ + return ia5ncasecmp(s1, s2, (size_t)(-1)); +} + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE tval, *val; + STACK_OF(GENERAL_SUBTREE) **ptree = NULL; + NAME_CONSTRAINTS *ncons = NULL; + GENERAL_SUBTREE *sub = NULL; + ncons = NAME_CONSTRAINTS_new(); + if (!ncons) + goto memerr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!strncmp(val->name, "permitted", 9) && val->name[9]) { + ptree = &ncons->permittedSubtrees; + tval.name = val->name + 10; + } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { + ptree = &ncons->excludedSubtrees; + tval.name = val->name + 9; + } else { + X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX); + goto err; + } + tval.value = val->value; + sub = GENERAL_SUBTREE_new(); + if (sub == NULL) + goto memerr; + if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) + goto err; + if (!*ptree) + *ptree = sk_GENERAL_SUBTREE_new_null(); + if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) + goto memerr; + sub = NULL; + } + + return ncons; + + memerr: + X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + err: + if (ncons) + NAME_CONSTRAINTS_free(ncons); + if (sub) + GENERAL_SUBTREE_free(sub); + + return NULL; +} + +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + BIO *bp, int ind) +{ + NAME_CONSTRAINTS *ncons = a; + do_i2r_name_constraints(method, ncons->permittedSubtrees, + bp, ind, "Permitted"); + do_i2r_name_constraints(method, ncons->excludedSubtrees, + bp, ind, "Excluded"); + return 1; +} + +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, + BIO *bp, int ind, char *name) +{ + GENERAL_SUBTREE *tree; + int i; + if (sk_GENERAL_SUBTREE_num(trees) > 0) + BIO_printf(bp, "%*s%s:\n", ind, "", name); + for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { + tree = sk_GENERAL_SUBTREE_value(trees, i); + BIO_printf(bp, "%*s", ind + 2, ""); + if (tree->base->type == GEN_IPADD) + print_nc_ipadd(bp, tree->base->d.ip); + else + GENERAL_NAME_print(bp, tree->base); + BIO_puts(bp, "\n"); + } + return 1; +} + +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) +{ + int i, len; + unsigned char *p; + p = ip->data; + len = ip->length; + BIO_puts(bp, "IP:"); + if (len == 8) { + BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + } else if (len == 32) { + for (i = 0; i < 16; i++) { + BIO_printf(bp, "%X", p[0] << 8 | p[1]); + p += 2; + if (i == 7) + BIO_puts(bp, "/"); + else if (i != 15) + BIO_puts(bp, ":"); + } + } else + BIO_printf(bp, "IP Address:"); + return 1; +} + +/*- + * Check a certificate conforms to a specified set of constraints. + * Return values: + * X509_V_OK: All constraints obeyed. + * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. + * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. + * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. + * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name + */ + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) +{ + int r, i; + X509_NAME *nm; + + nm = X509_get_subject_name(x); + + if (X509_NAME_entry_count(nm) > 0) { + GENERAL_NAME gntmp; + gntmp.type = GEN_DIRNAME; + gntmp.d.directoryName = nm; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + + gntmp.type = GEN_EMAIL; + + /* Process any email address attributes in subject name */ + + for (i = -1;;) { + X509_NAME_ENTRY *ne; + i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i); + if (i == -1) + break; + ne = X509_NAME_get_entry(nm, i); + gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); + if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + } + + } + + for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); + r = nc_match(gen, nc); + if (r != X509_V_OK) + return r; + } + + return X509_V_OK; + +} + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) +{ + GENERAL_SUBTREE *sub; + int i, r, match = 0; + + /* + * Permitted subtrees: if any subtrees exist of matching the type at + * least one subtree must match. + */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + /* If we already have a match don't bother trying any more */ + if (match == 2) + continue; + if (match == 0) + match = 1; + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + match = 2; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + } + + if (match == 1) + return X509_V_ERR_PERMITTED_VIOLATION; + + /* Excluded subtrees: must not match any of these */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + return X509_V_ERR_EXCLUDED_VIOLATION; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + + } + + return X509_V_OK; + +} + +static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) +{ + switch (base->type) { + case GEN_DIRNAME: + return nc_dn(gen->d.directoryName, base->d.directoryName); + + case GEN_DNS: + return nc_dns(gen->d.dNSName, base->d.dNSName); + + case GEN_EMAIL: + return nc_email(gen->d.rfc822Name, base->d.rfc822Name); + + case GEN_URI: + return nc_uri(gen->d.uniformResourceIdentifier, + base->d.uniformResourceIdentifier); + + default: + return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; + } + +} + +/* + * directoryName name constraint matching. The canonical encoding of + * X509_NAME makes this comparison easy. It is matched if the subtree is a + * subset of the name. + */ + +static int nc_dn(X509_NAME *nm, X509_NAME *base) +{ + /* Ensure canonical encodings are up to date. */ + if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->modified && i2d_X509_NAME(base, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->canon_enclen > nm->canon_enclen) + return X509_V_ERR_PERMITTED_VIOLATION; + if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) + return X509_V_ERR_PERMITTED_VIOLATION; + return X509_V_OK; +} + +static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) +{ + char *baseptr = (char *)base->data; + char *dnsptr = (char *)dns->data; + /* Empty matches everything */ + if (!*baseptr) + return X509_V_OK; + /* + * Otherwise can add zero or more components on the left so compare RHS + * and if dns is longer and expect '.' as preceding character. + */ + if (dns->length > base->length) { + dnsptr += dns->length - base->length; + if (*baseptr != '.' && dnsptr[-1] != '.') + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if (ia5casecmp(baseptr, dnsptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} + +static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *emlptr = (char *)eml->data; + + const char *baseat = strchr(baseptr, '@'); + const char *emlat = strchr(emlptr, '@'); + if (!emlat) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + /* Special case: inital '.' is RHS match */ + if (!baseat && (*baseptr == '.')) { + if (eml->length > base->length) { + emlptr += eml->length - base->length; + if (ia5casecmp(baseptr, emlptr) == 0) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + /* If we have anything before '@' match local part */ + + if (baseat) { + if (baseat != baseptr) { + if ((baseat - baseptr) != (emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + /* Case sensitive match of local part */ + if (strncmp(baseptr, emlptr, emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + } + /* Position base after '@' */ + baseptr = baseat + 1; + } + emlptr = emlat + 1; + /* Just have hostname left to match: case insensitive */ + if (ia5casecmp(baseptr, emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} + +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *hostptr = (char *)uri->data; + const char *p = strchr(hostptr, ':'); + int hostlen; + /* Check for foo:// and skip past it */ + if (!p || (p[1] != '/') || (p[2] != '/')) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + hostptr = p + 3; + + /* Determine length of hostname part of URI */ + + /* Look for a port indicator as end of hostname first */ + + p = strchr(hostptr, ':'); + /* Otherwise look for trailing slash */ + if (!p) + p = strchr(hostptr, '/'); + + if (!p) + hostlen = strlen(hostptr); + else + hostlen = p - hostptr; + + if (hostlen == 0) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + /* Special case: inital '.' is RHS match */ + if (*baseptr == '.') { + if (hostlen > base->length) { + p = hostptr + hostlen - base->length; + if (ia5ncasecmp(p, baseptr, base->length) == 0) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if ((base->length != (int)hostlen) + || ia5ncasecmp(hostptr, baseptr, hostlen)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} +/* v3_ocsp.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef OPENSSL_NO_OCSP + +# include +# include "cryptlib.h" +# include "conf.h" +# include "asn1.h" +# include "ocsp.h" +# include "x509v3.h" + +/* + * OCSP extensions and a couple of CRL entry extensions + */ + +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out, + int indent); + +static void *ocsp_nonce_new(void); +static int i2d_ocsp_nonce(void *a, unsigned char **pp); +static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); +static void ocsp_nonce_free(void *a); +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); + +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, + void *nocheck, BIO *out, int indent); +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, + BIO *bp, int ind); + +const X509V3_EXT_METHOD v3_ocsp_crlid = { + NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_crlid, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_acutoff = { + NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_acutoff, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_crl_invdate = { + NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_acutoff, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_crl_hold = { + NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_object, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_nonce = { + NID_id_pkix_OCSP_Nonce, 0, NULL, + ocsp_nonce_new, + ocsp_nonce_free, + d2i_ocsp_nonce, + i2d_ocsp_nonce, + 0, 0, + 0, 0, + i2r_ocsp_nonce, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_nocheck = { + NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + 0, s2i_ocsp_nocheck, + 0, 0, + i2r_ocsp_nocheck, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_serviceloc = { + NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_serviceloc, 0, + NULL +}; + +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp, + int ind) +{ + OCSP_CRLID *a = in; + if (a->crlUrl) { + if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) + goto err; + if (!ASN1_STRING_print(bp, (ASN1_STRING *)a->crlUrl)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (a->crlNum) { + if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) + goto err; + if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (a->crlTime) { + if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + return 1; + err: + return 0; +} + +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, + BIO *bp, int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) + return 0; + return 1; +} + +static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp, + int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, oid) <= 0) + return 0; + return 1; +} + +/* + * OCSP nonce. This is needs special treatment because it doesn't have an + * ASN1 encoding at all: it just contains arbitrary data. + */ + +static void *ocsp_nonce_new(void) +{ + return ASN1_OCTET_STRING_new(); +} + +static int i2d_ocsp_nonce(void *a, unsigned char **pp) +{ + ASN1_OCTET_STRING *os = a; + if (pp) { + memcpy(*pp, os->data, os->length); + *pp += os->length; + } + return os->length; +} + +static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) +{ + ASN1_OCTET_STRING *os, **pos; + pos = a; + if (!pos || !*pos) + os = ASN1_OCTET_STRING_new(); + else + os = *pos; + if (!ASN1_OCTET_STRING_set(os, *pp, length)) + goto err; + + *pp += length; + + if (pos) + *pos = os; + return os; + + err: + if (os && (!pos || (*pos != os))) + M_ASN1_OCTET_STRING_free(os); + OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static void ocsp_nonce_free(void *a) +{ + M_ASN1_OCTET_STRING_free(a); +} + +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent) +{ + if (BIO_printf(out, "%*s", indent, "") <= 0) + return 0; + if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) + return 0; + return 1; +} + +/* Nocheck is just a single NULL. Don't print anything and always set it */ + +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, + BIO *out, int indent) +{ + return 1; +} + +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, + BIO *bp, int ind) +{ + int i; + OCSP_SERVICELOC *a = in; + ACCESS_DESCRIPTION *ad; + + if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) + goto err; + if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) + goto err; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) { + ad = sk_ACCESS_DESCRIPTION_value(a->locator, i); + if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ad->method) <= 0) + goto err; + if (BIO_puts(bp, " - ") <= 0) + goto err; + if (GENERAL_NAME_print(bp, ad->location) <= 0) + goto err; + } + return 1; + err: + return 0; +} +#endif +/* v3_pci.c */ +/* + * Contributed to the OpenSSL Project 2004 by Richard Levitte + * (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "x509v3.h" + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, + BIO *out, int indent); +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +const X509V3_EXT_METHOD v3_pci = + { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), + 0, 0, 0, 0, + 0, 0, + NULL, NULL, + (X509V3_EXT_I2R)i2r_pci, + (X509V3_EXT_R2I)r2i_pci, + NULL, +}; + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, + BIO *out, int indent) +{ + BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); + if (pci->pcPathLengthConstraint) + i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); + else + BIO_printf(out, "infinite"); + BIO_puts(out, "\n"); + BIO_printf(out, "%*sPolicy Language: ", indent, ""); + i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); + BIO_puts(out, "\n"); + if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) + BIO_printf(out, "%*sPolicy Text: %s\n", indent, "", + pci->proxyPolicy->policy->data); + return 1; +} + +static int process_pci_value(CONF_VALUE *val, + ASN1_OBJECT **language, ASN1_INTEGER **pathlen, + ASN1_OCTET_STRING **policy) +{ + int free_policy = 0; + + if (strcmp(val->name, "language") == 0) { + if (*language) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!(*language = OBJ_txt2obj(val->value, 0))) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return 0; + } + } else if (strcmp(val->name, "pathlen") == 0) { + if (*pathlen) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!X509V3_get_value_int(val, pathlen)) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_PATH_LENGTH); + X509V3_conf_err(val); + return 0; + } + } else if (strcmp(val->name, "policy") == 0) { + unsigned char *tmp_data = NULL; + long val_len; + if (!*policy) { + *policy = ASN1_OCTET_STRING_new(); + if (!*policy) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + return 0; + } + free_policy = 1; + } + if (strncmp(val->value, "hex:", 4) == 0) { + unsigned char *tmp_data2 = + string_to_hex(val->value + 4, &val_len); + + if (!tmp_data2) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_ILLEGAL_HEX_DIGIT); + X509V3_conf_err(val); + goto err; + } + + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) { + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + tmp_data2, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } else { + OPENSSL_free(tmp_data2); + /* + * realloc failure implies the original data space is b0rked + * too! + */ + (*policy)->data = NULL; + (*policy)->length = 0; + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + OPENSSL_free(tmp_data2); + } else if (strncmp(val->value, "file:", 5) == 0) { + unsigned char buf[2048]; + int n; + BIO *b = BIO_new_file(val->value + 5, "r"); + if (!b) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); + X509V3_conf_err(val); + goto err; + } + while ((n = BIO_read(b, buf, sizeof(buf))) > 0 + || (n == 0 && BIO_should_retry(b))) { + if (!n) + continue; + + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + n + 1); + + if (!tmp_data) + break; + + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], buf, n); + (*policy)->length += n; + (*policy)->data[(*policy)->length] = '\0'; + } + BIO_free_all(b); + + if (n < 0) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); + X509V3_conf_err(val); + goto err; + } + } else if (strncmp(val->value, "text:", 5) == 0) { + val_len = strlen(val->value + 5); + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) { + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + val->value + 5, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } else { + /* + * realloc failure implies the original data space is b0rked + * too! + */ + (*policy)->data = NULL; + (*policy)->length = 0; + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } else { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); + X509V3_conf_err(val); + goto err; + } + if (!tmp_data) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } + return 1; + err: + if (free_policy) { + ASN1_OCTET_STRING_free(*policy); + *policy = NULL; + } + return 0; +} + +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value) +{ + PROXY_CERT_INFO_EXTENSION *pci = NULL; + STACK_OF(CONF_VALUE) *vals; + ASN1_OBJECT *language = NULL; + ASN1_INTEGER *pathlen = NULL; + ASN1_OCTET_STRING *policy = NULL; + int i, j; + + vals = X509V3_parse_list(value); + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); + if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_INVALID_PROXY_POLICY_SETTING); + X509V3_conf_err(cnf); + goto err; + } + if (*cnf->name == '@') { + STACK_OF(CONF_VALUE) *sect; + int success_p = 1; + + sect = X509V3_get_section(ctx, cnf->name + 1); + if (!sect) { + X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) { + success_p = + process_pci_value(sk_CONF_VALUE_value(sect, j), + &language, &pathlen, &policy); + } + X509V3_section_free(ctx, sect); + if (!success_p) + goto err; + } else { + if (!process_pci_value(cnf, &language, &pathlen, &policy)) { + X509V3_conf_err(cnf); + goto err; + } + } + } + + /* Language is mandatory */ + if (!language) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); + goto err; + } + i = OBJ_obj2nid(language); + if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); + goto err; + } + + pci = PROXY_CERT_INFO_EXTENSION_new(); + if (!pci) { + X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE); + goto err; + } + + pci->proxyPolicy->policyLanguage = language; + language = NULL; + pci->proxyPolicy->policy = policy; + policy = NULL; + pci->pcPathLengthConstraint = pathlen; + pathlen = NULL; + goto end; + err: + if (language) { + ASN1_OBJECT_free(language); + language = NULL; + } + if (pathlen) { + ASN1_INTEGER_free(pathlen); + pathlen = NULL; + } + if (policy) { + ASN1_OCTET_STRING_free(policy); + policy = NULL; + } + if (pci) { + PROXY_CERT_INFO_EXTENSION_free(pci); + pci = NULL; + } + end: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pci; +} +/* v3_pcia.c */ +/* + * Contributed to the OpenSSL Project 2004 by Richard Levitte + * (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" + +ASN1_SEQUENCE(PROXY_POLICY) = + { + ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT), + ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(PROXY_POLICY) + +IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY) + +ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) = + { + ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER), + ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY) +} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION) + +IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) +/* v3_pcons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "conf.h" +// #include "x509v3.h" + +static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD + *method, void *bcons, STACK_OF(CONF_VALUE) + *extlist); +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_policy_constraints = { + NID_policy_constraints, 0, + ASN1_ITEM_ref(POLICY_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + i2v_POLICY_CONSTRAINTS, + v2i_POLICY_CONSTRAINTS, + NULL, NULL, + NULL +}; + +ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { + ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0), + ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1) +} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS) + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) + +static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *extlist) +{ + POLICY_CONSTRAINTS *pcons = a; + X509V3_add_value_int("Require Explicit Policy", + pcons->requireExplicitPolicy, &extlist); + X509V3_add_value_int("Inhibit Policy Mapping", + pcons->inhibitPolicyMapping, &extlist); + return extlist; +} + +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + POLICY_CONSTRAINTS *pcons = NULL; + CONF_VALUE *val; + int i; + if (!(pcons = POLICY_CONSTRAINTS_new())) { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "requireExplicitPolicy")) { + if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) + goto err; + } else if (!strcmp(val->name, "inhibitPolicyMapping")) { + if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) + goto err; + } else { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, + X509V3_R_ILLEGAL_EMPTY_EXTENSION); + goto err; + } + + return pcons; + err: + POLICY_CONSTRAINTS_free(pcons); + return NULL; +} +/* v3_pku.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" + +static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, + PKEY_USAGE_PERIOD *usage, BIO *out, + int indent); +/* + * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, + * X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + */ +const X509V3_EXT_METHOD v3_pkey_usage_period = { + NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD), + 0, 0, 0, 0, + 0, 0, 0, 0, + (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL, + NULL +}; + +ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = { + ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0), + ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1) +} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD) + +IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, + PKEY_USAGE_PERIOD *usage, BIO *out, + int indent) +{ + BIO_printf(out, "%*s", indent, ""); + if (usage->notBefore) { + BIO_write(out, "Not Before: ", 12); + ASN1_GENERALIZEDTIME_print(out, usage->notBefore); + if (usage->notAfter) + BIO_write(out, ", ", 2); + } + if (usage->notAfter) { + BIO_write(out, "Not After: ", 11); + ASN1_GENERALIZEDTIME_print(out, usage->notAfter); + } + return 1; +} + +/*- +static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values) +X509V3_EXT_METHOD *method; +X509V3_CTX *ctx; +STACK_OF(CONF_VALUE) *values; +{ +return NULL; +} +*/ +/* v3_pmaps.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "conf.h" +// #include "x509v3.h" + +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD + *method, void *pmps, STACK_OF(CONF_VALUE) + *extlist); + +const X509V3_EXT_METHOD v3_policy_mappings = { + NID_policy_mappings, 0, + ASN1_ITEM_ref(POLICY_MAPPINGS), + 0, 0, 0, 0, + 0, 0, + i2v_POLICY_MAPPINGS, + v2i_POLICY_MAPPINGS, + 0, 0, + NULL +}; + +ASN1_SEQUENCE(POLICY_MAPPING) = { + ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT), + ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT) +} ASN1_SEQUENCE_END(POLICY_MAPPING) + +ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS, + POLICY_MAPPING) +ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) + +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *ext_list) +{ + POLICY_MAPPINGS *pmaps = a; + POLICY_MAPPING *pmap; + int i; + char obj_tmp1[80]; + char obj_tmp2[80]; + for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { + pmap = sk_POLICY_MAPPING_value(pmaps, i); + i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); + i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); + X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); + } + return ext_list; +} + +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + POLICY_MAPPINGS *pmaps; + POLICY_MAPPING *pmap; + ASN1_OBJECT *obj1, *obj2; + CONF_VALUE *val; + int i; + + if (!(pmaps = sk_POLICY_MAPPING_new_null())) { + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!val->value || !val->name) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + obj1 = OBJ_txt2obj(val->name, 0); + obj2 = OBJ_txt2obj(val->value, 0); + if (!obj1 || !obj2) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + pmap = POLICY_MAPPING_new(); + if (!pmap) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); + return NULL; + } + pmap->issuerDomainPolicy = obj1; + pmap->subjectDomainPolicy = obj2; + sk_POLICY_MAPPING_push(pmaps, pmap); + } + return pmaps; +} +/* v3_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "x509v3.h" + +/* Extension printing routines */ + +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, + unsigned long flag, int indent, int supported); + +/* Print out a name+value stack */ + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml) +{ + int i; + CONF_VALUE *nval; + if (!val) + return; + if (!ml || !sk_CONF_VALUE_num(val)) { + BIO_printf(out, "%*s", indent, ""); + if (!sk_CONF_VALUE_num(val)) + BIO_puts(out, "\n"); + } + for (i = 0; i < sk_CONF_VALUE_num(val); i++) { + if (ml) + BIO_printf(out, "%*s", indent, ""); + else if (i > 0) + BIO_printf(out, ", "); + nval = sk_CONF_VALUE_value(val, i); + if (!nval->name) + BIO_puts(out, nval->value); + else if (!nval->value) + BIO_puts(out, nval->name); +#ifndef CHARSET_EBCDIC + else + BIO_printf(out, "%s:%s", nval->name, nval->value); +#else + else { + int len; + char *tmp; + len = strlen(nval->value) + 1; + tmp = OPENSSL_malloc(len); + if (tmp) { + ascii2ebcdic(tmp, nval->value, len); + BIO_printf(out, "%s:%s", nval->name, tmp); + OPENSSL_free(tmp); + } + } +#endif + if (ml) + BIO_puts(out, "\n"); + } +} + +/* Main routine: print out a general extension */ + +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent) +{ + void *ext_str = NULL; + char *value = NULL; + const unsigned char *p; + const X509V3_EXT_METHOD *method; + STACK_OF(CONF_VALUE) *nval = NULL; + int ok = 1; + + if (!(method = X509V3_EXT_get(ext))) + return unknown_ext_print(out, ext, flag, indent, 0); + p = ext->value->data; + if (method->it) + ext_str = + ASN1_item_d2i(NULL, &p, ext->value->length, + ASN1_ITEM_ptr(method->it)); + else + ext_str = method->d2i(NULL, &p, ext->value->length); + + if (!ext_str) + return unknown_ext_print(out, ext, flag, indent, 1); + + if (method->i2s) { + if (!(value = method->i2s(method, ext_str))) { + ok = 0; + goto err; + } +#ifndef CHARSET_EBCDIC + BIO_printf(out, "%*s%s", indent, "", value); +#else + { + int len; + char *tmp; + len = strlen(value) + 1; + tmp = OPENSSL_malloc(len); + if (tmp) { + ascii2ebcdic(tmp, value, len); + BIO_printf(out, "%*s%s", indent, "", tmp); + OPENSSL_free(tmp); + } + } +#endif + } else if (method->i2v) { + if (!(nval = method->i2v(method, ext_str, NULL))) { + ok = 0; + goto err; + } + X509V3_EXT_val_prn(out, nval, indent, + method->ext_flags & X509V3_EXT_MULTILINE); + } else if (method->i2r) { + if (!method->i2r(method, ext_str, out, indent)) + ok = 0; + } else + ok = 0; + + err: + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + if (value) + OPENSSL_free(value); + if (method->it) + ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_str); + return ok; +} + +int X509V3_extensions_print(BIO *bp, char *title, + STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent) +{ + int i, j; + + if (sk_X509_EXTENSION_num(exts) <= 0) + return 1; + + if (title) { + BIO_printf(bp, "%*s%s:\n", indent, "", title); + indent += 4; + } + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + ex = sk_X509_EXTENSION_value(exts, i); + if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) + return 0; + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp, obj); + j = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) + return 0; + if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { + BIO_printf(bp, "%*s", indent + 4, ""); + M_ASN1_OCTET_STRING_print(bp, ex->value); + } + if (BIO_write(bp, "\n", 1) <= 0) + return 0; + } + return 1; +} + +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, + unsigned long flag, int indent, int supported) +{ + switch (flag & X509V3_EXT_UNKNOWN_MASK) { + + case X509V3_EXT_DEFAULT: + return 0; + + case X509V3_EXT_ERROR_UNKNOWN: + if (supported) + BIO_printf(out, "%*s", indent, ""); + else + BIO_printf(out, "%*s", indent, ""); + return 1; + + case X509V3_EXT_PARSE_UNKNOWN: + return ASN1_parse_dump(out, + ext->value->data, ext->value->length, indent, + -1); + case X509V3_EXT_DUMP_UNKNOWN: + return BIO_dump_indent(out, (char *)ext->value->data, + ext->value->length, indent); + + default: + return 1; + } +} + +#ifndef OPENSSL_NO_FP_API +int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) +{ + BIO *bio_tmp; + int ret; + if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) + return 0; + ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); + BIO_free(bio_tmp); + return ret; +} +#endif +/* v3_purp.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "x509v3.h" +#include "x509_vfy.h" + +static void x509v3_cache_extensions(X509 *x); + +static int check_ssl_ca(const X509 *x); +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int purpose_smime(const X509 *x, int ca); +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); + +static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b); +static void xptable_free(X509_PURPOSE *p); + +static X509_PURPOSE xstandard[] = { + {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, + check_purpose_ssl_client, "SSL client", "sslclient", NULL}, + {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ssl_server, "SSL server", "sslserver", NULL}, + {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL}, + {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, + "S/MIME signing", "smimesign", NULL}, + {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, + check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, + {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, + "CRL signing", "crlsign", NULL}, + {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", + NULL}, + {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, + "OCSP helper", "ocsphelper", NULL}, + {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, + check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", + NULL}, +}; + +#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) + +IMPLEMENT_STACK_OF(X509_PURPOSE) + +static STACK_OF(X509_PURPOSE) *xptable = NULL; + +static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) +{ + return (*a)->purpose - (*b)->purpose; +} + +/* + * As much as I'd like to make X509_check_purpose use a "const" X509* I + * really can't because it does recalculate hashes and do other non-const + * things. + */ +int X509_check_purpose(X509 *x, int id, int ca) +{ + int idx; + const X509_PURPOSE *pt; + + x509v3_cache_extensions(x); + + /* Return if side-effect only call */ + if (id == -1) + return 1; + idx = X509_PURPOSE_get_by_id(id); + if (idx == -1) + return -1; + pt = X509_PURPOSE_get0(idx); + return pt->check_purpose(pt, x, ca); +} + +int X509_PURPOSE_set(int *p, int purpose) +{ + if (X509_PURPOSE_get_by_id(purpose) == -1) { + X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE); + return 0; + } + *p = purpose; + return 1; +} + +int X509_PURPOSE_get_count(void) +{ + if (!xptable) + return X509_PURPOSE_COUNT; + return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; +} + +X509_PURPOSE *X509_PURPOSE_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_PURPOSE_COUNT) + return xstandard + idx; + return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); +} + +int X509_PURPOSE_get_by_sname(char *sname) +{ + int i; + X509_PURPOSE *xptmp; + for (i = 0; i < X509_PURPOSE_get_count(); i++) { + xptmp = X509_PURPOSE_get0(i); + if (!strcmp(xptmp->sname, sname)) + return i; + } + return -1; +} + +int X509_PURPOSE_get_by_id(int purpose) +{ + X509_PURPOSE tmp; + int idx; + if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) + return purpose - X509_PURPOSE_MIN; + tmp.purpose = purpose; + if (!xptable) + return -1; + idx = sk_X509_PURPOSE_find(xptable, &tmp); + if (idx == -1) + return -1; + return idx + X509_PURPOSE_COUNT; +} + +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg) +{ + int idx; + X509_PURPOSE *ptmp; + /* + * This is set according to what we change: application can't set it + */ + flags &= ~X509_PURPOSE_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_PURPOSE_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_PURPOSE_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + ptmp->flags = X509_PURPOSE_DYNAMIC; + } else + ptmp = X509_PURPOSE_get0(idx); + + /* OPENSSL_free existing name if dynamic */ + if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { + OPENSSL_free(ptmp->name); + OPENSSL_free(ptmp->sname); + } + /* dup supplied name */ + ptmp->name = BUF_strdup(name); + ptmp->sname = BUF_strdup(sname); + if (!ptmp->name || !ptmp->sname) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + /* Keep the dynamic flag of existing entry */ + ptmp->flags &= X509_PURPOSE_DYNAMIC; + /* Set all other flags */ + ptmp->flags |= flags; + + ptmp->purpose = id; + ptmp->trust = trust; + ptmp->check_purpose = ck; + ptmp->usr_data = arg; + + /* If its a new entry manage the dynamic table */ + if (idx == -1) { + if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509_PURPOSE_push(xptable, ptmp)) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + +static void xptable_free(X509_PURPOSE *p) +{ + if (!p) + return; + if (p->flags & X509_PURPOSE_DYNAMIC) { + if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { + OPENSSL_free(p->name); + OPENSSL_free(p->sname); + } + OPENSSL_free(p); + } +} + +void X509_PURPOSE_cleanup(void) +{ + unsigned int i; + sk_X509_PURPOSE_pop_free(xptable, xptable_free); + for (i = 0; i < X509_PURPOSE_COUNT; i++) + xptable_free(xstandard + i); + xptable = NULL; +} + +int X509_PURPOSE_get_id(X509_PURPOSE *xp) +{ + return xp->purpose; +} + +char *X509_PURPOSE_get0_name(X509_PURPOSE *xp) +{ + return xp->name; +} + +char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp) +{ + return xp->sname; +} + +int X509_PURPOSE_get_trust(X509_PURPOSE *xp) +{ + return xp->trust; +} + +static int nid_cmp(const int *a, const int *b) +{ + return *a - *b; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid); + +int X509_supported_extension(X509_EXTENSION *ex) +{ + /* + * This table is a list of the NIDs of supported extensions: that is + * those which are used by the verify process. If an extension is + * critical and doesn't appear in this list then the verify process will + * normally reject the certificate. The list must be kept in numerical + * order because it will be searched using bsearch. + */ + + static const int supported_nids[] = { + NID_netscape_cert_type, /* 71 */ + NID_key_usage, /* 83 */ + NID_subject_alt_name, /* 85 */ + NID_basic_constraints, /* 87 */ + NID_certificate_policies, /* 89 */ + NID_crl_distribution_points, /* 103 */ + NID_ext_key_usage, /* 126 */ +#ifndef OPENSSL_NO_RFC3779 + NID_sbgp_ipAddrBlock, /* 290 */ + NID_sbgp_autonomousSysNum, /* 291 */ +#endif + NID_policy_constraints, /* 401 */ + NID_proxyCertInfo, /* 663 */ + NID_name_constraints, /* 666 */ + NID_policy_mappings, /* 747 */ + NID_inhibit_any_policy /* 748 */ + }; + + int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (ex_nid == NID_undef) + return 0; + + if (OBJ_bsearch_nid(&ex_nid, supported_nids, + sizeof(supported_nids) / sizeof(int))) + return 1; + return 0; +} + +static void setup_dp(X509 *x, DIST_POINT *dp) +{ + X509_NAME *iname = NULL; + int i; + if (dp->reasons) { + if (dp->reasons->length > 0) + dp->dp_reasons = dp->reasons->data[0]; + if (dp->reasons->length > 1) + dp->dp_reasons |= (dp->reasons->data[1] << 8); + dp->dp_reasons &= CRLDP_ALL_REASONS; + } else + dp->dp_reasons = CRLDP_ALL_REASONS; + if (!dp->distpoint || (dp->distpoint->type != 1)) + return; + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) { + iname = gen->d.directoryName; + break; + } + } + if (!iname) + iname = X509_get_issuer_name(x); + + DIST_POINT_set_dpname(dp->distpoint, iname); + +} + +static void setup_crldp(X509 *x) +{ + int i; + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) + setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); +} + +#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) +#define ku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) +#define xku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) +#define ns_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) + +static void x509v3_cache_extensions(X509 *x) +{ + BASIC_CONSTRAINTS *bs; + PROXY_CERT_INFO_EXTENSION *pci; + ASN1_BIT_STRING *usage; + ASN1_BIT_STRING *ns; + EXTENDED_KEY_USAGE *extusage; + X509_EXTENSION *ex; + int i; + + CRYPTO_w_lock(CRYPTO_LOCK_X509); + if (x->ex_flags & EXFLAG_SET) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + return; + } + +#ifndef OPENSSL_NO_SHA + X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); +#endif + /* V1 should mean no extensions ... */ + if (!X509_get_version(x)) + x->ex_flags |= EXFLAG_V1; + /* Handle basic constraints */ + if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { + if (bs->ca) + x->ex_flags |= EXFLAG_CA; + if (bs->pathlen) { + if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) + || !bs->ca) { + x->ex_flags |= EXFLAG_INVALID; + x->ex_pathlen = 0; + } else + x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); + } else + x->ex_pathlen = -1; + BASIC_CONSTRAINTS_free(bs); + x->ex_flags |= EXFLAG_BCONS; + } + /* Handle proxy certificates */ + if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { + if (x->ex_flags & EXFLAG_CA + || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 + || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { + x->ex_flags |= EXFLAG_INVALID; + } + if (pci->pcPathLengthConstraint) { + x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); + } else + x->ex_pcpathlen = -1; + PROXY_CERT_INFO_EXTENSION_free(pci); + x->ex_flags |= EXFLAG_PROXY; + } + /* Handle key usage */ + if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { + if (usage->length > 0) { + x->ex_kusage = usage->data[0]; + if (usage->length > 1) + x->ex_kusage |= usage->data[1] << 8; + } else + x->ex_kusage = 0; + x->ex_flags |= EXFLAG_KUSAGE; + ASN1_BIT_STRING_free(usage); + } + x->ex_xkusage = 0; + if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { + x->ex_flags |= EXFLAG_XKUSAGE; + for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { + switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { + case NID_server_auth: + x->ex_xkusage |= XKU_SSL_SERVER; + break; + + case NID_client_auth: + x->ex_xkusage |= XKU_SSL_CLIENT; + break; + + case NID_email_protect: + x->ex_xkusage |= XKU_SMIME; + break; + + case NID_code_sign: + x->ex_xkusage |= XKU_CODE_SIGN; + break; + + case NID_ms_sgc: + case NID_ns_sgc: + x->ex_xkusage |= XKU_SGC; + break; + + case NID_OCSP_sign: + x->ex_xkusage |= XKU_OCSP_SIGN; + break; + + case NID_time_stamp: + x->ex_xkusage |= XKU_TIMESTAMP; + break; + + case NID_dvcs: + x->ex_xkusage |= XKU_DVCS; + break; + + case NID_anyExtendedKeyUsage: + x->ex_xkusage |= XKU_ANYEKU; + break; + } + } + sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); + } + + if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { + if (ns->length > 0) + x->ex_nscert = ns->data[0]; + else + x->ex_nscert = 0; + x->ex_flags |= EXFLAG_NSCERT; + ASN1_BIT_STRING_free(ns); + } + x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); + x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); + /* Does subject name match issuer ? */ + if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { + x->ex_flags |= EXFLAG_SI; + /* If SKID matches AKID also indicate self signed */ + if (X509_check_akid(x, x->akid) == X509_V_OK && + !ku_reject(x, KU_KEY_CERT_SIGN)) + x->ex_flags |= EXFLAG_SS; + } + x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); + if (!x->nc && (i != -1)) + x->ex_flags |= EXFLAG_INVALID; + setup_crldp(x); + +#ifndef OPENSSL_NO_RFC3779 + x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); + x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, + NULL, NULL); +#endif + for (i = 0; i < X509_get_ext_count(x); i++) { + ex = X509_get_ext(x, i); + if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) + == NID_freshest_crl) + x->ex_flags |= EXFLAG_FRESHEST; + if (!X509_EXTENSION_get_critical(ex)) + continue; + if (!X509_supported_extension(ex)) { + x->ex_flags |= EXFLAG_CRITICAL; + break; + } + } + x->ex_flags |= EXFLAG_SET; + CRYPTO_w_unlock(CRYPTO_LOCK_X509); +} + +/*- + * CA checks common to all purposes + * return codes: + * 0 not a CA + * 1 is a CA + * 2 basicConstraints absent so "maybe" a CA + * 3 basicConstraints absent but self signed V1. + * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. + */ + +static int check_ca(const X509 *x) +{ + /* keyUsage if present should allow cert signing */ + if (ku_reject(x, KU_KEY_CERT_SIGN)) + return 0; + if (x->ex_flags & EXFLAG_BCONS) { + if (x->ex_flags & EXFLAG_CA) + return 1; + /* If basicConstraints says not a CA then say so */ + else + return 0; + } else { + /* we support V1 roots for... uh, I don't really know why. */ + if ((x->ex_flags & V1_ROOT) == V1_ROOT) + return 3; + /* + * If key usage present it must have certSign so tolerate it + */ + else if (x->ex_flags & EXFLAG_KUSAGE) + return 4; + /* Older certificates could have Netscape-specific CA types */ + else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA) + return 5; + /* can this still be regarded a CA certificate? I doubt it */ + return 0; + } +} + +int X509_check_ca(X509 *x) +{ + x509v3_cache_extensions(x); + + return check_ca(x); +} + +/* Check SSL CA: common checks for SSL client and server */ +static int check_ssl_ca(const X509 *x) +{ + int ca_ret; + ca_ret = check_ca(x); + if (!ca_ret) + return 0; + /* check nsCertType if present */ + if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) + return ca_ret; + else + return 0; +} + +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (xku_reject(x, XKU_SSL_CLIENT)) + return 0; + if (ca) + return check_ssl_ca(x); + /* We need to do digital signatures or key agreement */ + if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) + return 0; + /* nsCertType if present should allow SSL client use */ + if (ns_reject(x, NS_SSL_CLIENT)) + return 0; + return 1; +} + +/* + * Key usage needed for TLS/SSL server: digital signature, encipherment or + * key agreement. The ssl code can check this more thoroughly for individual + * key types. + */ +#define KU_TLS \ + KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT + +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC)) + return 0; + if (ca) + return check_ssl_ca(x); + + if (ns_reject(x, NS_SSL_SERVER)) + return 0; + if (ku_reject(x, KU_TLS)) + return 0; + + return 1; + +} + +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = check_purpose_ssl_server(xp, x, ca); + if (!ret || ca) + return ret; + /* We need to encipher or Netscape complains */ + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +/* common S/MIME checks */ +static int purpose_smime(const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SMIME)) + return 0; + if (ca) { + int ca_ret; + ca_ret = check_ca(x); + if (!ca_ret) + return 0; + /* check nsCertType if present */ + if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) + return ca_ret; + else + return 0; + } + if (x->ex_flags & EXFLAG_NSCERT) { + if (x->ex_nscert & NS_SMIME) + return 1; + /* Workaround for some buggy certificates */ + if (x->ex_nscert & NS_SSL_CLIENT) + return 2; + return 0; + } + return 1; +} + +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) + return 0; + return ret; +} + +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (ca) { + int ca_ret; + if ((ca_ret = check_ca(x)) != 2) + return ca_ret; + else + return 0; + } + if (ku_reject(x, KU_CRL_SIGN)) + return 0; + return 1; +} + +/* + * OCSP helper: this is *not* a full OCSP check. It just checks that each CA + * is valid. Additional checks must be made on the chain. + */ + +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + /* + * Must be a valid CA. Should we really support the "I don't know" value + * (2)? + */ + if (ca) + return check_ca(x); + /* leaf certificate is checked in OCSP_verify() */ + return 1; +} + +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int i_ext; + + /* If ca is true we must return if this is a valid CA certificate. */ + if (ca) + return check_ca(x); + + /* + * Check the optional key usage field: + * if Key Usage is present, it must be one of digitalSignature + * and/or nonRepudiation (other values are not consistent and shall + * be rejected). + */ + if ((x->ex_flags & EXFLAG_KUSAGE) + && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || + !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) + return 0; + + /* Only time stamp key usage is permitted and it's required. */ + if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) + return 0; + + /* Extended Key Usage MUST be critical */ + i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1); + if (i_ext >= 0) { + X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); + if (!X509_EXTENSION_get_critical(ext)) + return 0; + } + + return 1; +} + +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + return 1; +} + +/*- + * Various checks to see if one certificate issued the second. + * This can be used to prune a set of possible issuer certificates + * which have been looked up using some simple method such as by + * subject name. + * These are: + * 1. Check issuer_name(subject) == subject_name(issuer) + * 2. If akid(subject) exists check it matches issuer + * 3. If key_usage(issuer) exists check it supports certificate signing + * returns 0 for OK, positive for reason for mismatch, reasons match + * codes for X509_verify_cert() + */ + +int X509_check_issued(X509 *issuer, X509 *subject) +{ + if (X509_NAME_cmp(X509_get_subject_name(issuer), + X509_get_issuer_name(subject))) + return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; + + x509v3_cache_extensions(issuer); + x509v3_cache_extensions(subject); + + if (subject->akid) { + int ret = X509_check_akid(issuer, subject->akid); + if (ret != X509_V_OK) + return ret; + } + + if (subject->ex_flags & EXFLAG_PROXY) { + if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) + return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; + } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) + return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + return X509_V_OK; +} + +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) +{ + + if (!akid) + return X509_V_OK; + + /* Check key ids (if present) */ + if (akid->keyid && issuer->skid && + ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) + return X509_V_ERR_AKID_SKID_MISMATCH; + /* Check serial number */ + if (akid->serial && + ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + /* Check issuer name */ + if (akid->issuer) { + /* + * Ugh, for some peculiar reason AKID includes SEQUENCE OF + * GeneralName. So look for a DirName. There may be more than one but + * we only take any notice of the first. + */ + GENERAL_NAMES *gens; + GENERAL_NAME *gen; + X509_NAME *nm = NULL; + int i; + gens = akid->issuer; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type == GEN_DIRNAME) { + nm = gen->d.dirn; + break; + } + } + if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + } + return X509_V_OK; +} +/* v3_scts.c */ +/* + * Written by Rob Stradling (rob@comodo.com) for the OpenSSL project 2014. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "x509v3.h" + +/* Signature and hash algorithms from RFC 5246 */ +#define TLSEXT_hash_sha256 4 + +#define TLSEXT_signature_rsa 1 +#define TLSEXT_signature_ecdsa 3 + + +#define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \ + (((unsigned int)(c[1])) )),c+=2) + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define SCT_TIMESTAMP unsigned __int64 +#elif defined(__arch64__) +# define SCT_TIMESTAMP unsigned long +#else +# define SCT_TIMESTAMP unsigned long long +#endif + +#define n2l8(c,l) (l =((SCT_TIMESTAMP)(*((c)++)))<<56, \ + l|=((SCT_TIMESTAMP)(*((c)++)))<<48, \ + l|=((SCT_TIMESTAMP)(*((c)++)))<<40, \ + l|=((SCT_TIMESTAMP)(*((c)++)))<<32, \ + l|=((SCT_TIMESTAMP)(*((c)++)))<<24, \ + l|=((SCT_TIMESTAMP)(*((c)++)))<<16, \ + l|=((SCT_TIMESTAMP)(*((c)++)))<< 8, \ + l|=((SCT_TIMESTAMP)(*((c)++)))) + +typedef struct SCT_st { + /* The encoded SCT */ + unsigned char *sct; + unsigned short sctlen; + /* + * Components of the SCT. "logid", "ext" and "sig" point to addresses + * inside "sct". + */ + unsigned char version; + unsigned char *logid; + unsigned short logidlen; + SCT_TIMESTAMP timestamp; + unsigned char *ext; + unsigned short extlen; + unsigned char hash_alg; + unsigned char sig_alg; + unsigned char *sig; + unsigned short siglen; +} SCT; + +DECLARE_STACK_OF(SCT) + +static void SCT_LIST_free(STACK_OF(SCT) *a); +static STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, + const unsigned char **pp, long length); +static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list, + BIO *out, int indent); + +const X509V3_EXT_METHOD v3_ct_scts[] = { + {NID_ct_precert_scts, 0, NULL, + 0, (X509V3_EXT_FREE)SCT_LIST_free, + (X509V3_EXT_D2I)d2i_SCT_LIST, 0, + 0, 0, 0, 0, + (X509V3_EXT_I2R)i2r_SCT_LIST, 0, + NULL}, + + {NID_ct_cert_scts, 0, NULL, + 0, (X509V3_EXT_FREE)SCT_LIST_free, + (X509V3_EXT_D2I)d2i_SCT_LIST, 0, + 0, 0, 0, 0, + (X509V3_EXT_I2R)i2r_SCT_LIST, 0, + NULL}, +}; + +static void tls12_signature_print(BIO *out, const unsigned char hash_alg, + const unsigned char sig_alg) +{ + int nid = NID_undef; + /* RFC6962 only permits two signature algorithms */ + if (hash_alg == TLSEXT_hash_sha256) { + if (sig_alg == TLSEXT_signature_rsa) + nid = NID_sha256WithRSAEncryption; + else if (sig_alg == TLSEXT_signature_ecdsa) + nid = NID_ecdsa_with_SHA256; + } + if (nid == NID_undef) + BIO_printf(out, "%02X%02X", hash_alg, sig_alg); + else + BIO_printf(out, "%s", OBJ_nid2ln(nid)); +} + +static void timestamp_print(BIO *out, SCT_TIMESTAMP timestamp) +{ + ASN1_GENERALIZEDTIME *gen; + char genstr[20]; + gen = ASN1_GENERALIZEDTIME_new(); + ASN1_GENERALIZEDTIME_adj(gen, (time_t)0, + (int)(timestamp / 86400000), + (int)(timestamp % 86400000) / 1000); + /* + * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15 + * characters long with a final Z. Update it with fractional seconds. + */ + BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ", + ASN1_STRING_data(gen), (unsigned int)(timestamp % 1000)); + ASN1_GENERALIZEDTIME_set_string(gen, genstr); + ASN1_GENERALIZEDTIME_print(out, gen); + ASN1_GENERALIZEDTIME_free(gen); +} + +static void SCT_free(SCT *sct) +{ + if (sct) { + if (sct->sct) + OPENSSL_free(sct->sct); + OPENSSL_free(sct); + } +} + +static void SCT_LIST_free(STACK_OF(SCT) *a) +{ + sk_SCT_pop_free(a, SCT_free); +} + +static STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, + const unsigned char **pp, long length) +{ + ASN1_OCTET_STRING *oct = NULL; + STACK_OF(SCT) *sk = NULL; + SCT *sct; + unsigned char *p, *p2; + unsigned short listlen, sctlen = 0, fieldlen; + const unsigned char *q = *pp; + + if (d2i_ASN1_OCTET_STRING(&oct, &q, length) == NULL) + return NULL; + if (oct->length < 2) + goto done; + p = oct->data; + n2s(p, listlen); + if (listlen != oct->length - 2) + goto done; + + if ((sk = sk_SCT_new_null()) == NULL) + goto done; + + while (listlen > 0) { + if (listlen < 2) + goto err; + n2s(p, sctlen); + listlen -= 2; + + if ((sctlen < 1) || (sctlen > listlen)) + goto err; + listlen -= sctlen; + + sct = OPENSSL_malloc(sizeof(SCT)); + if (!sct) + goto err; + if (!sk_SCT_push(sk, sct)) { + OPENSSL_free(sct); + goto err; + } + + sct->sct = OPENSSL_malloc(sctlen); + if (!sct->sct) + goto err; + memcpy(sct->sct, p, sctlen); + sct->sctlen = sctlen; + p += sctlen; + p2 = sct->sct; + + sct->version = *p2++; + if (sct->version == 0) { /* SCT v1 */ + /*- + * Fixed-length header: + * struct { + * (1 byte) Version sct_version; + * (32 bytes) LogID id; + * (8 bytes) uint64 timestamp; + * (2 bytes + ?) CtExtensions extensions; + */ + if (sctlen < 43) + goto err; + sctlen -= 43; + + sct->logid = p2; + sct->logidlen = 32; + p2 += 32; + + n2l8(p2, sct->timestamp); + + n2s(p2, fieldlen); + if (sctlen < fieldlen) + goto err; + sct->ext = p2; + sct->extlen = fieldlen; + p2 += fieldlen; + sctlen -= fieldlen; + + /*- + * digitally-signed struct header: + * (1 byte) Hash algorithm + * (1 byte) Signature algorithm + * (2 bytes + ?) Signature + */ + if (sctlen < 4) + goto err; + sctlen -= 4; + + sct->hash_alg = *p2++; + sct->sig_alg = *p2++; + n2s(p2, fieldlen); + if (sctlen != fieldlen) + goto err; + sct->sig = p2; + sct->siglen = fieldlen; + } + } + + done: + ASN1_OCTET_STRING_free(oct); + *pp = q; + return sk; + + err: + SCT_LIST_free(sk); + sk = NULL; + goto done; +} + +static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list, + BIO *out, int indent) +{ + SCT *sct; + int i; + + for (i = 0; i < sk_SCT_num(sct_list);) { + sct = sk_SCT_value(sct_list, i); + + BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, ""); + BIO_printf(out, "\n%*sVersion : ", indent + 4, ""); + + if (sct->version == 0) { /* SCT v1 */ + BIO_printf(out, "v1(0)"); + + BIO_printf(out, "\n%*sLog ID : ", indent + 4, ""); + BIO_hex_string(out, indent + 16, 16, sct->logid, sct->logidlen); + + BIO_printf(out, "\n%*sTimestamp : ", indent + 4, ""); + timestamp_print(out, sct->timestamp); + + BIO_printf(out, "\n%*sExtensions: ", indent + 4, ""); + if (sct->extlen == 0) + BIO_printf(out, "none"); + else + BIO_hex_string(out, indent + 16, 16, sct->ext, sct->extlen); + + BIO_printf(out, "\n%*sSignature : ", indent + 4, ""); + tls12_signature_print(out, sct->hash_alg, sct->sig_alg); + BIO_printf(out, "\n%*s ", indent + 4, ""); + BIO_hex_string(out, indent + 16, 16, sct->sig, sct->siglen); + } else { /* Unknown version */ + + BIO_printf(out, "unknown\n%*s", indent + 16, ""); + BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sctlen); + } + + if (++i < sk_SCT_num(sct_list)) + BIO_printf(out, "\n"); + } + + return 1; +} +/* v3_skey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "x509v3.h" + +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); +const X509V3_EXT_METHOD v3_skey_id = { + NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, + (X509V3_EXT_S2I)s2i_skey_id, + 0, 0, 0, 0, + NULL +}; + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct) +{ + return hex_to_string(oct->data, oct->length); +} + +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + ASN1_OCTET_STRING *oct; + long length; + + if (!(oct = M_ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!(oct->data = string_to_hex(str, &length))) { + M_ASN1_OCTET_STRING_free(oct); + return NULL; + } + + oct->length = length; + + return oct; + +} + +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + ASN1_OCTET_STRING *oct; + ASN1_BIT_STRING *pk; + unsigned char pkey_dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + if (strcmp(str, "hash")) + return s2i_ASN1_OCTET_STRING(method, ctx, str); + + if (!(oct = M_ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ctx && (ctx->flags == CTX_TEST)) + return oct; + + if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { + X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (ctx->subject_req) + pk = ctx->subject_req->req_info->pubkey->public_key; + else + pk = ctx->subject_cert->cert_info->key->public_key; + + if (!pk) { + X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (!EVP_Digest + (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL)) + goto err; + + if (!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { + X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); + goto err; + } + + return oct; + + err: + M_ASN1_OCTET_STRING_free(oct); + return NULL; +} +/* v3_sxnet.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "asn1.h" +// #include "asn1t.h" +// #include "x509v3.h" + +/* Support for Thawte strong extranet extension */ + +#define SXNET_TEST + +static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, + int indent); +#ifdef SXNET_TEST +static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +#endif +const X509V3_EXT_METHOD v3_sxnet = { + NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET), + 0, 0, 0, 0, + 0, 0, + 0, +#ifdef SXNET_TEST + (X509V3_EXT_V2I)sxnet_v2i, +#else + 0, +#endif + (X509V3_EXT_I2R)sxnet_i2r, + 0, + NULL +}; + +ASN1_SEQUENCE(SXNETID) = { + ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER), + ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(SXNETID) + +IMPLEMENT_ASN1_FUNCTIONS(SXNETID) + +ASN1_SEQUENCE(SXNET) = { + ASN1_SIMPLE(SXNET, version, ASN1_INTEGER), + ASN1_SEQUENCE_OF(SXNET, ids, SXNETID) +} ASN1_SEQUENCE_END(SXNET) + +IMPLEMENT_ASN1_FUNCTIONS(SXNET) + +static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, + int indent) +{ + long v; + char *tmp; + SXNETID *id; + int i; + v = ASN1_INTEGER_get(sx->version); + BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v); + for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { + id = sk_SXNETID_value(sx->ids, i); + tmp = i2s_ASN1_INTEGER(NULL, id->zone); + BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); + OPENSSL_free(tmp); + M_ASN1_OCTET_STRING_print(out, id->user); + } + return 1; +} + +#ifdef SXNET_TEST + +/* + * NBB: this is used for testing only. It should *not* be used for anything + * else because it will just take static IDs from the configuration file and + * they should really be separate values for each user. + */ + +static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + CONF_VALUE *cnf; + SXNET *sx = NULL; + int i; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) + return NULL; + } + return sx; +} + +#endif + +/* Strong Extranet utility functions */ + +/* Add an id given the zone as an ASCII number */ + +int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen) +{ + ASN1_INTEGER *izone = NULL; + if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) { + X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); + return 0; + } + return SXNET_add_id_INTEGER(psx, izone, user, userlen); +} + +/* Add an id given the zone as an unsigned long */ + +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, + int userlen) +{ + ASN1_INTEGER *izone = NULL; + if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { + X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE); + M_ASN1_INTEGER_free(izone); + return 0; + } + return SXNET_add_id_INTEGER(psx, izone, user, userlen); + +} + +/* + * Add an id given the zone as an ASN1_INTEGER. Note this version uses the + * passed integer and doesn't make a copy so don't free it up afterwards. + */ + +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user, + int userlen) +{ + SXNET *sx = NULL; + SXNETID *id = NULL; + if (!psx || !zone || !user) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, + X509V3_R_INVALID_NULL_ARGUMENT); + return 0; + } + if (userlen == -1) + userlen = strlen(user); + if (userlen > 64) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG); + return 0; + } + if (!*psx) { + if (!(sx = SXNET_new())) + goto err; + if (!ASN1_INTEGER_set(sx->version, 0)) + goto err; + *psx = sx; + } else + sx = *psx; + if (SXNET_get_id_INTEGER(sx, zone)) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID); + return 0; + } + + if (!(id = SXNETID_new())) + goto err; + if (userlen == -1) + userlen = strlen(user); + + if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) + goto err; + if (!sk_SXNETID_push(sx->ids, id)) + goto err; + id->zone = zone; + return 1; + + err: + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE); + SXNETID_free(id); + SXNET_free(sx); + *psx = NULL; + return 0; +} + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone) +{ + ASN1_INTEGER *izone = NULL; + ASN1_OCTET_STRING *oct; + if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) { + X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); + return NULL; + } + oct = SXNET_get_id_INTEGER(sx, izone); + M_ASN1_INTEGER_free(izone); + return oct; +} + +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) +{ + ASN1_INTEGER *izone = NULL; + ASN1_OCTET_STRING *oct; + if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { + X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE); + M_ASN1_INTEGER_free(izone); + return NULL; + } + oct = SXNET_get_id_INTEGER(sx, izone); + M_ASN1_INTEGER_free(izone); + return oct; +} + +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) +{ + SXNETID *id; + int i; + for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { + id = sk_SXNETID_value(sx->ids, i); + if (!M_ASN1_INTEGER_cmp(id->zone, zone)) + return id->user; + } + return NULL; +} + +IMPLEMENT_STACK_OF(SXNETID) + +IMPLEMENT_ASN1_SET_OF(SXNETID) +/* v3_utl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +#include +// #include "cryptlib.h" +// #include "conf.h" +// #include "x509v3.h" +// #include "bn.h" + +static char *strip_spaces(char *name); +static int sk_strcmp(const char *const *a, const char *const *b); +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, + GENERAL_NAMES *gens); +static void str_free(OPENSSL_STRING str); +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); + +static int ipv4_from_asc(unsigned char *v4, const char *in); +static int ipv6_from_asc(unsigned char *v6, const char *in); +static int ipv6_cb(const char *elem, int len, void *usr); +static int ipv6_hex(unsigned char *out, const char *in, int inlen); + +/* Add a CONF_VALUE name value pair to stack */ + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + CONF_VALUE *vtmp = NULL; + char *tname = NULL, *tvalue = NULL; + if (name && !(tname = BUF_strdup(name))) + goto err; + if (value && !(tvalue = BUF_strdup(value))) + goto err; + if (!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) + goto err; + if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) + goto err; + vtmp->section = NULL; + vtmp->name = tname; + vtmp->value = tvalue; + if (!sk_CONF_VALUE_push(*extlist, vtmp)) + goto err; + return 1; + err: + X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE); + if (vtmp) + OPENSSL_free(vtmp); + if (tname) + OPENSSL_free(tname); + if (tvalue) + OPENSSL_free(tvalue); + return 0; +} + +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + return X509V3_add_value(name, (const char *)value, extlist); +} + +/* Free function for STACK_OF(CONF_VALUE) */ + +void X509V3_conf_free(CONF_VALUE *conf) +{ + if (!conf) + return; + if (conf->name) + OPENSSL_free(conf->name); + if (conf->value) + OPENSSL_free(conf->value); + if (conf->section) + OPENSSL_free(conf->section); + OPENSSL_free(conf); +} + +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return X509V3_add_value(name, "FALSE", extlist); +} + +int X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return 1; +} + +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a) +{ + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + if (!a) + return NULL; + if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || + !(strtmp = BN_bn2dec(bntmp))) + X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} + +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a) +{ + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + if (!a) + return NULL; + if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || + !(strtmp = BN_bn2dec(bntmp))) + X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} + +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value) +{ + BIGNUM *bn = NULL; + ASN1_INTEGER *aint; + int isneg, ishex; + int ret; + if (!value) { + X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE); + return 0; + } + bn = BN_new(); + if (value[0] == '-') { + value++; + isneg = 1; + } else + isneg = 0; + + if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { + value += 2; + ishex = 1; + } else + ishex = 0; + + if (ishex) + ret = BN_hex2bn(&bn, value); + else + ret = BN_dec2bn(&bn, value); + + if (!ret || value[ret]) { + BN_free(bn); + X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR); + return 0; + } + + if (isneg && BN_is_zero(bn)) + isneg = 0; + + aint = BN_to_ASN1_INTEGER(bn, NULL); + BN_free(bn); + if (!aint) { + X509V3err(X509V3_F_S2I_ASN1_INTEGER, + X509V3_R_BN_TO_ASN1_INTEGER_ERROR); + return 0; + } + if (isneg) + aint->type |= V_ASN1_NEG; + return aint; +} + +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist) +{ + char *strtmp; + int ret; + if (!aint) + return 1; + if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) + return 0; + ret = X509V3_add_value(name, strtmp, extlist); + OPENSSL_free(strtmp); + return ret; +} + +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool) +{ + char *btmp; + if (!(btmp = value->value)) + goto err; + if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") + || !strcmp(btmp, "Y") || !strcmp(btmp, "y") + || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { + *asn1_bool = 0xff; + return 1; + } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") + || !strcmp(btmp, "N") || !strcmp(btmp, "n") + || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { + *asn1_bool = 0; + return 1; + } + err: + X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL, + X509V3_R_INVALID_BOOLEAN_STRING); + X509V3_conf_err(value); + return 0; +} + +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint) +{ + ASN1_INTEGER *itmp; + if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { + X509V3_conf_err(value); + return 0; + } + *aint = itmp; + return 1; +} + +#define HDR_NAME 1 +#define HDR_VALUE 2 + +/* + * #define DEBUG + */ + +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) +{ + char *p, *q, c; + char *ntmp, *vtmp; + STACK_OF(CONF_VALUE) *values = NULL; + char *linebuf; + int state; + /* We are going to modify the line so copy it first */ + linebuf = BUF_strdup(line); + if (linebuf == NULL) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + state = HDR_NAME; + ntmp = NULL; + /* Go through all characters */ + for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); + p++) { + + switch (state) { + case HDR_NAME: + if (c == ':') { + state = HDR_VALUE; + *p = 0; + ntmp = strip_spaces(q); + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_NAME); + goto err; + } + q = p + 1; + } else if (c == ',') { + *p = 0; + ntmp = strip_spaces(q); + q = p + 1; +#if 0 + printf("%s\n", ntmp); +#endif + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + break; + + case HDR_VALUE: + if (c == ',') { + state = HDR_NAME; + *p = 0; + vtmp = strip_spaces(q); +#if 0 + printf("%s\n", ntmp); +#endif + if (!vtmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + ntmp = NULL; + q = p + 1; + } + + } + } + + if (state == HDR_VALUE) { + vtmp = strip_spaces(q); +#if 0 + printf("%s=%s\n", ntmp, vtmp); +#endif + if (!vtmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + } else { + ntmp = strip_spaces(q); +#if 0 + printf("%s\n", ntmp); +#endif + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + OPENSSL_free(linebuf); + return values; + + err: + OPENSSL_free(linebuf); + sk_CONF_VALUE_pop_free(values, X509V3_conf_free); + return NULL; + +} + +/* Delete leading and trailing spaces from a string */ +static char *strip_spaces(char *name) +{ + char *p, *q; + /* Skip over leading spaces */ + p = name; + while (*p && isspace((unsigned char)*p)) + p++; + if (!*p) + return NULL; + q = p + strlen(p) - 1; + while ((q != p) && isspace((unsigned char)*q)) + q--; + if (p != q) + q[1] = 0; + if (!*p) + return NULL; + return p; +} + +/* hex string utilities */ + +/* + * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its + * hex representation @@@ (Contents of buffer are always kept in ASCII, also + * on EBCDIC machines) + */ + +char *hex_to_string(const unsigned char *buffer, long len) +{ + char *tmp, *q; + const unsigned char *p; + int i; + const static char hexdig[] = "0123456789ABCDEF"; + if (!buffer || !len) + return NULL; + if (!(tmp = OPENSSL_malloc(len * 3 + 1))) { + X509V3err(X509V3_F_HEX_TO_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + q = tmp; + for (i = 0, p = buffer; i < len; i++, p++) { + *q++ = hexdig[(*p >> 4) & 0xf]; + *q++ = hexdig[*p & 0xf]; + *q++ = ':'; + } + q[-1] = 0; +#ifdef CHARSET_EBCDIC + ebcdic2ascii(tmp, tmp, q - tmp - 1); +#endif + + return tmp; +} + +/* + * Give a string of hex digits convert to a buffer + */ + +unsigned char *string_to_hex(const char *str, long *len) +{ + unsigned char *hexbuf, *q; + unsigned char ch, cl, *p; + if (!str) { + X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) + goto err; + for (p = (unsigned char *)str, q = hexbuf; *p;) { + ch = *p++; +#ifdef CHARSET_EBCDIC + ch = os_toebcdic[ch]; +#endif + if (ch == ':') + continue; + cl = *p++; +#ifdef CHARSET_EBCDIC + cl = os_toebcdic[cl]; +#endif + if (!cl) { + X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ODD_NUMBER_OF_DIGITS); + OPENSSL_free(hexbuf); + return NULL; + } + if (isupper(ch)) + ch = tolower(ch); + if (isupper(cl)) + cl = tolower(cl); + + if ((ch >= '0') && (ch <= '9')) + ch -= '0'; + else if ((ch >= 'a') && (ch <= 'f')) + ch -= 'a' - 10; + else + goto badhex; + + if ((cl >= '0') && (cl <= '9')) + cl -= '0'; + else if ((cl >= 'a') && (cl <= 'f')) + cl -= 'a' - 10; + else + goto badhex; + + *q++ = (ch << 4) | cl; + } + + if (len) + *len = q - hexbuf; + + return hexbuf; + + err: + if (hexbuf) + OPENSSL_free(hexbuf); + X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE); + return NULL; + + badhex: + OPENSSL_free(hexbuf); + X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT); + return NULL; + +} + +/* + * V2I name comparison function: returns zero if 'name' matches cmp or cmp.* + */ + +int name_cmp(const char *name, const char *cmp) +{ + int len, ret; + char c; + len = strlen(cmp); + if ((ret = strncmp(name, cmp, len))) + return ret; + c = name[len]; + if (!c || (c == '.')) + return 0; + return 1; +} + +static int sk_strcmp(const char *const *a, const char *const *b) +{ + return strcmp(*a, *b); +} + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) +{ + GENERAL_NAMES *gens; + STACK_OF(OPENSSL_STRING) *ret; + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) +{ + AUTHORITY_INFO_ACCESS *info; + STACK_OF(OPENSSL_STRING) *ret = NULL; + int i; + + info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); + if (!info) + return NULL; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { + ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); + if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { + if (ad->location->type == GEN_URI) { + if (!append_ia5 + (&ret, ad->location->d.uniformResourceIdentifier)) + break; + } + } + } + AUTHORITY_INFO_ACCESS_free(info); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) +{ + GENERAL_NAMES *gens; + STACK_OF(X509_EXTENSION) *exts; + STACK_OF(OPENSSL_STRING) *ret; + + exts = X509_REQ_get_extensions(x); + gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_REQ_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return ret; +} + +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, + GENERAL_NAMES *gens) +{ + STACK_OF(OPENSSL_STRING) *ret = NULL; + X509_NAME_ENTRY *ne; + ASN1_IA5STRING *email; + GENERAL_NAME *gen; + int i; + /* Now add any email address(es) to STACK */ + i = -1; + /* First supplied X509_NAME */ + while ((i = X509_NAME_get_index_by_NID(name, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(name, i); + email = X509_NAME_ENTRY_get_data(ne); + if (!append_ia5(&ret, email)) + return NULL; + } + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type != GEN_EMAIL) + continue; + if (!append_ia5(&ret, gen->d.ia5)) + return NULL; + } + return ret; +} + +static void str_free(OPENSSL_STRING str) +{ + OPENSSL_free(str); +} + +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) +{ + char *emtmp; + /* First some sanity checks */ + if (email->type != V_ASN1_IA5STRING) + return 1; + if (!email->data || !email->length) + return 1; + if (!*sk) + *sk = sk_OPENSSL_STRING_new(sk_strcmp); + if (!*sk) + return 0; + /* Don't add duplicates */ + if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) + return 1; + emtmp = BUF_strdup((char *)email->data); + if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) { + X509_email_free(*sk); + *sk = NULL; + return 0; + } + return 1; +} + +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk) +{ + sk_OPENSSL_STRING_pop_free(sk, str_free); +} + +typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags); + +/* Skip pattern prefix to match "wildcard" subject */ +static void skip_prefix(const unsigned char **p, size_t *plen, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + const unsigned char *pattern = *p; + size_t pattern_len = *plen; + + /* + * If subject starts with a leading '.' followed by more octets, and + * pattern is longer, compare just an equal-length suffix with the + * full subject (starting at the '.'), provided the prefix contains + * no NULs. + */ + if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0) + return; + + while (pattern_len > subject_len && *pattern) { + if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) && + *pattern == '.') + break; + ++pattern; + --pattern_len; + } + + /* Skip if entire prefix acceptable */ + if (pattern_len == subject_len) { + *p = pattern; + *plen = pattern_len; + } +} + +/* Compare while ASCII ignoring case. */ +static int equal_nocase(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); + if (pattern_len != subject_len) + return 0; + while (pattern_len) { + unsigned char l = *pattern; + unsigned char r = *subject; + /* The pattern must not contain NUL characters. */ + if (l == 0) + return 0; + if (l != r) { + if ('A' <= l && l <= 'Z') + l = (l - 'A') + 'a'; + if ('A' <= r && r <= 'Z') + r = (r - 'A') + 'a'; + if (l != r) + return 0; + } + ++pattern; + ++subject; + --pattern_len; + } + return 1; +} + +/* Compare using memcmp. */ +static int equal_case(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); + if (pattern_len != subject_len) + return 0; + return !memcmp(pattern, subject, pattern_len); +} + +/* + * RFC 5280, section 7.5, requires that only the domain is compared in a + * case-insensitive manner. + */ +static int equal_email(const unsigned char *a, size_t a_len, + const unsigned char *b, size_t b_len, + unsigned int unused_flags) +{ + size_t i = a_len; + if (a_len != b_len) + return 0; + /* + * We search backwards for the '@' character, so that we do not have to + * deal with quoted local-parts. The domain part is compared in a + * case-insensitive manner. + */ + while (i > 0) { + --i; + if (a[i] == '@' || b[i] == '@') { + if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0)) + return 0; + break; + } + } + if (i == 0) + i = a_len; + return equal_case(a, i, b, i, 0); +} + +/* + * Compare the prefix and suffix with the subject, and check that the + * characters in-between are valid. + */ +static int wildcard_match(const unsigned char *prefix, size_t prefix_len, + const unsigned char *suffix, size_t suffix_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + const unsigned char *wildcard_start; + const unsigned char *wildcard_end; + const unsigned char *p; + int allow_multi = 0; + int allow_idna = 0; + + if (subject_len < prefix_len + suffix_len) + return 0; + if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags)) + return 0; + wildcard_start = subject + prefix_len; + wildcard_end = subject + (subject_len - suffix_len); + if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags)) + return 0; + /* + * If the wildcard makes up the entire first label, it must match at + * least one character. + */ + if (prefix_len == 0 && *suffix == '.') { + if (wildcard_start == wildcard_end) + return 0; + allow_idna = 1; + if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS) + allow_multi = 1; + } + /* IDNA labels cannot match partial wildcards */ + if (!allow_idna && + subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0) + return 0; + /* The wildcard may match a literal '*' */ + if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') + return 1; + /* + * Check that the part matched by the wildcard contains only + * permitted characters and only matches a single label unless + * allow_multi is set. + */ + for (p = wildcard_start; p != wildcard_end; ++p) + if (!(('0' <= *p && *p <= '9') || + ('A' <= *p && *p <= 'Z') || + ('a' <= *p && *p <= 'z') || + *p == '-' || (allow_multi && *p == '.'))) + return 0; + return 1; +} + +#define LABEL_START (1 << 0) +#define LABEL_END (1 << 1) +#define LABEL_HYPHEN (1 << 2) +#define LABEL_IDNA (1 << 3) + +static const unsigned char *valid_star(const unsigned char *p, size_t len, + unsigned int flags) +{ + const unsigned char *star = 0; + size_t i; + int state = LABEL_START; + int dots = 0; + for (i = 0; i < len; ++i) { + /* + * Locate first and only legal wildcard, either at the start + * or end of a non-IDNA first and not final label. + */ + if (p[i] == '*') { + int atstart = (state & LABEL_START); + int atend = (i == len - 1 || p[i + 1] == '.'); + /*- + * At most one wildcard per pattern. + * No wildcards in IDNA labels. + * No wildcards after the first label. + */ + if (star != NULL || (state & LABEL_IDNA) != 0 || dots) + return NULL; + /* Only full-label '*.example.com' wildcards? */ + if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS) + && (!atstart || !atend)) + return NULL; + /* No 'foo*bar' wildcards */ + if (!atstart && !atend) + return NULL; + star = &p[i]; + state &= ~LABEL_START; + } else if (('a' <= p[i] && p[i] <= 'z') + || ('A' <= p[i] && p[i] <= 'Z') + || ('0' <= p[i] && p[i] <= '9')) { + if ((state & LABEL_START) != 0 + && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0) + state |= LABEL_IDNA; + state &= ~(LABEL_HYPHEN | LABEL_START); + } else if (p[i] == '.') { + if ((state & (LABEL_HYPHEN | LABEL_START)) != 0) + return NULL; + state = LABEL_START; + ++dots; + } else if (p[i] == '-') { + /* no domain/subdomain starts with '-' */ + if ((state & LABEL_START) != 0) + return NULL; + state |= LABEL_HYPHEN; + } else + return NULL; + } + + /* + * The final label must not end in a hyphen or ".", and + * there must be at least two dots after the star. + */ + if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2) + return NULL; + return star; +} + +/* Compare using wildcards. */ +static int equal_wildcard(const unsigned char *pattern, size_t pattern_len, + const unsigned char *subject, size_t subject_len, + unsigned int flags) +{ + const unsigned char *star = NULL; + + /* + * Subject names starting with '.' can only match a wildcard pattern + * via a subject sub-domain pattern suffix match. + */ + if (!(subject_len > 1 && subject[0] == '.')) + star = valid_star(pattern, pattern_len, flags); + if (star == NULL) + return equal_nocase(pattern, pattern_len, + subject, subject_len, flags); + return wildcard_match(pattern, star - pattern, + star + 1, (pattern + pattern_len) - star - 1, + subject, subject_len, flags); +} + +/* + * Compare an ASN1_STRING to a supplied string. If they match return 1. If + * cmp_type > 0 only compare if string matches the type, otherwise convert it + * to UTF8. + */ + +static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, + unsigned int flags, const char *b, size_t blen, + char **peername) +{ + int rv = 0; + + if (!a->data || !a->length) + return 0; + if (cmp_type > 0) { + if (cmp_type != a->type) + return 0; + if (cmp_type == V_ASN1_IA5STRING) + rv = equal(a->data, a->length, (unsigned char *)b, blen, flags); + else if (a->length == (int)blen && !memcmp(a->data, b, blen)) + rv = 1; + if (rv > 0 && peername) + *peername = BUF_strndup((char *)a->data, a->length); + } else { + int astrlen; + unsigned char *astr; + astrlen = ASN1_STRING_to_UTF8(&astr, a); + if (astrlen < 0) { + /* + * -1 could be an internal malloc failure or a decoding error from + * malformed input; we can't distinguish. + */ + return -1; + } + rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); + if (rv > 0 && peername) + *peername = BUF_strndup((char *)astr, astrlen); + OPENSSL_free(astr); + } + return rv; +} + +static int do_x509_check(X509 *x, const char *chk, size_t chklen, + unsigned int flags, int check_type, char **peername) +{ + GENERAL_NAMES *gens = NULL; + X509_NAME *name = NULL; + int i; + int cnid = NID_undef; + int alt_type; + int san_present = 0; + int rv = 0; + equal_fn equal; + + /* See below, this flag is internal-only */ + flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS; + if (check_type == GEN_EMAIL) { + cnid = NID_pkcs9_emailAddress; + alt_type = V_ASN1_IA5STRING; + equal = equal_email; + } else if (check_type == GEN_DNS) { + cnid = NID_commonName; + /* Implicit client-side DNS sub-domain pattern */ + if (chklen > 1 && chk[0] == '.') + flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS; + alt_type = V_ASN1_IA5STRING; + if (flags & X509_CHECK_FLAG_NO_WILDCARDS) + equal = equal_nocase; + else + equal = equal_wildcard; + } else { + alt_type = V_ASN1_OCTET_STRING; + equal = equal_case; + } + + if (chklen == 0) + chklen = strlen(chk); + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + if (gens) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + GENERAL_NAME *gen; + ASN1_STRING *cstr; + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type != check_type) + continue; + san_present = 1; + if (check_type == GEN_EMAIL) + cstr = gen->d.rfc822Name; + else if (check_type == GEN_DNS) + cstr = gen->d.dNSName; + else + cstr = gen->d.iPAddress; + /* Positive on success, negative on error! */ + if ((rv = do_check_string(cstr, alt_type, equal, flags, + chk, chklen, peername)) != 0) + break; + } + GENERAL_NAMES_free(gens); + if (rv != 0) + return rv; + if (cnid == NID_undef + || (san_present + && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))) + return 0; + } + + /* We're done if CN-ID is not pertinent */ + if (cnid == NID_undef) + return 0; + + i = -1; + name = X509_get_subject_name(x); + while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) { + X509_NAME_ENTRY *ne; + ASN1_STRING *str; + ne = X509_NAME_get_entry(name, i); + str = X509_NAME_ENTRY_get_data(ne); + /* Positive on success, negative on error! */ + if ((rv = do_check_string(str, -1, equal, flags, + chk, chklen, peername)) != 0) + return rv; + } + return 0; +} + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername) +{ + if (chk == NULL) + return -2; + /* + * Embedded NULs are disallowed, except as the last character of a + * string of length 2 or more (tolerate caller including terminating + * NUL in string length). + */ + if (chklen == 0) + chklen = strlen(chk); + else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen)) + return -2; + if (chklen > 1 && chk[chklen - 1] == '\0') + --chklen; + return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername); +} + +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags) +{ + if (chk == NULL) + return -2; + /* + * Embedded NULs are disallowed, except as the last character of a + * string of length 2 or more (tolerate caller including terminating + * NUL in string length). + */ + if (chklen == 0) + chklen = strlen((char *)chk); + else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen)) + return -2; + if (chklen > 1 && chk[chklen - 1] == '\0') + --chklen; + return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL); +} + +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags) +{ + if (chk == NULL) + return -2; + return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL); +} + +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) +{ + unsigned char ipout[16]; + size_t iplen; + + if (ipasc == NULL) + return -2; + iplen = (size_t)a2i_ipadd(ipout, ipasc); + if (iplen == 0) + return -2; + return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); +} + +/* + * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible + * with RFC3280. + */ + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) +{ + unsigned char ipout[16]; + ASN1_OCTET_STRING *ret; + int iplen; + + /* If string contains a ':' assume IPv6 */ + + iplen = a2i_ipadd(ipout, ipasc); + + if (!iplen) + return NULL; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { + ASN1_OCTET_STRING_free(ret); + return NULL; + } + return ret; +} + +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) +{ + ASN1_OCTET_STRING *ret = NULL; + unsigned char ipout[32]; + char *iptmp = NULL, *p; + int iplen1, iplen2; + p = strchr(ipasc, '/'); + if (!p) + return NULL; + iptmp = BUF_strdup(ipasc); + if (!iptmp) + return NULL; + p = iptmp + (p - ipasc); + *p++ = 0; + + iplen1 = a2i_ipadd(ipout, iptmp); + + if (!iplen1) + goto err; + + iplen2 = a2i_ipadd(ipout + iplen1, p); + + OPENSSL_free(iptmp); + iptmp = NULL; + + if (!iplen2 || (iplen1 != iplen2)) + goto err; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + goto err; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) + goto err; + + return ret; + + err: + if (iptmp) + OPENSSL_free(iptmp); + if (ret) + ASN1_OCTET_STRING_free(ret); + return NULL; +} + +int a2i_ipadd(unsigned char *ipout, const char *ipasc) +{ + /* If string contains a ':' assume IPv6 */ + + if (strchr(ipasc, ':')) { + if (!ipv6_from_asc(ipout, ipasc)) + return 0; + return 16; + } else { + if (!ipv4_from_asc(ipout, ipasc)) + return 0; + return 4; + } +} + +static int ipv4_from_asc(unsigned char *v4, const char *in) +{ + int a0, a1, a2, a3; + if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) + return 0; + if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) + || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) + return 0; + v4[0] = a0; + v4[1] = a1; + v4[2] = a2; + v4[3] = a3; + return 1; +} + +typedef struct { + /* Temporary store for IPV6 output */ + unsigned char tmp[16]; + /* Total number of bytes in tmp */ + int total; + /* The position of a zero (corresponding to '::') */ + int zero_pos; + /* Number of zeroes */ + int zero_cnt; +} IPV6_STAT; + +static int ipv6_from_asc(unsigned char *v6, const char *in) +{ + IPV6_STAT v6stat; + v6stat.total = 0; + v6stat.zero_pos = -1; + v6stat.zero_cnt = 0; + /* + * Treat the IPv6 representation as a list of values separated by ':'. + * The presence of a '::' will parse as one, two or three zero length + * elements. + */ + if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) + return 0; + + /* Now for some sanity checks */ + + if (v6stat.zero_pos == -1) { + /* If no '::' must have exactly 16 bytes */ + if (v6stat.total != 16) + return 0; + } else { + /* If '::' must have less than 16 bytes */ + if (v6stat.total == 16) + return 0; + /* More than three zeroes is an error */ + if (v6stat.zero_cnt > 3) + return 0; + /* Can only have three zeroes if nothing else present */ + else if (v6stat.zero_cnt == 3) { + if (v6stat.total > 0) + return 0; + } + /* Can only have two zeroes if at start or end */ + else if (v6stat.zero_cnt == 2) { + if ((v6stat.zero_pos != 0) + && (v6stat.zero_pos != v6stat.total)) + return 0; + } else + /* Can only have one zero if *not* start or end */ + { + if ((v6stat.zero_pos == 0) + || (v6stat.zero_pos == v6stat.total)) + return 0; + } + } + + /* Format result */ + + if (v6stat.zero_pos >= 0) { + /* Copy initial part */ + memcpy(v6, v6stat.tmp, v6stat.zero_pos); + /* Zero middle */ + memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); + /* Copy final part */ + if (v6stat.total != v6stat.zero_pos) + memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } else + memcpy(v6, v6stat.tmp, 16); + + return 1; +} + +static int ipv6_cb(const char *elem, int len, void *usr) +{ + IPV6_STAT *s = usr; + /* Error if 16 bytes written */ + if (s->total == 16) + return 0; + if (len == 0) { + /* Zero length element, corresponds to '::' */ + if (s->zero_pos == -1) + s->zero_pos = s->total; + /* If we've already got a :: its an error */ + else if (s->zero_pos != s->total) + return 0; + s->zero_cnt++; + } else { + /* If more than 4 characters could be final a.b.c.d form */ + if (len > 4) { + /* Need at least 4 bytes left */ + if (s->total > 12) + return 0; + /* Must be end of string */ + if (elem[len]) + return 0; + if (!ipv4_from_asc(s->tmp + s->total, elem)) + return 0; + s->total += 4; + } else { + if (!ipv6_hex(s->tmp + s->total, elem, len)) + return 0; + s->total += 2; + } + } + return 1; +} + +/* + * Convert a string of up to 4 hex digits into the corresponding IPv6 form. + */ + +static int ipv6_hex(unsigned char *out, const char *in, int inlen) +{ + unsigned char c; + unsigned int num = 0; + if (inlen > 4) + return 0; + while (inlen--) { + c = *in++; + num <<= 4; + if ((c >= '0') && (c <= '9')) + num |= c - '0'; + else if ((c >= 'A') && (c <= 'F')) + num |= c - 'A' + 10; + else if ((c >= 'a') && (c <= 'f')) + num |= c - 'a' + 10; + else + return 0; + } + out[0] = num >> 8; + out[1] = num & 0xff; + return 1; +} + +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype) +{ + CONF_VALUE *v; + int i, mval; + char *p, *type; + if (!nm) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { + v = sk_CONF_VALUE_value(dn_sk, i); + type = v->name; + /* + * Skip past any leading X. X: X, etc to allow for multiple instances + */ + for (p = type; *p; p++) +#ifndef CHARSET_EBCDIC + if ((*p == ':') || (*p == ',') || (*p == '.')) +#else + if ((*p == os_toascii[':']) || (*p == os_toascii[',']) + || (*p == os_toascii['.'])) +#endif + { + p++; + if (*p) + type = p; + break; + } +#ifndef CHARSET_EBCDIC + if (*type == '+') +#else + if (*type == os_toascii['+']) +#endif + { + mval = -1; + type++; + } else + mval = 0; + if (!X509_NAME_add_entry_by_txt(nm, type, chtype, + (unsigned char *)v->value, -1, -1, + mval)) + return 0; + + } + return 1; +} diff --git a/Sources/COpenSSL/v3_lib.c b/Sources/COpenSSL/v3_lib.c new file mode 100644 index 00000000..28bcdafc --- /dev/null +++ b/Sources/COpenSSL/v3_lib.c @@ -0,0 +1,371 @@ +/* v3_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +#include "cryptlib.h" +#include "conf.h" +#include "x509v3.h" + +#include "ext_dat.h" + +static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; + +static int ext_cmp(const X509V3_EXT_METHOD *const *a, + const X509V3_EXT_METHOD *const *b); +static void ext_list_free(X509V3_EXT_METHOD *ext); + +int X509V3_EXT_add(X509V3_EXT_METHOD *ext) +{ + if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) { + X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { + X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static int ext_cmp(const X509V3_EXT_METHOD *const *a, + const X509V3_EXT_METHOD *const *b) +{ + return ((*a)->ext_nid - (*b)->ext_nid); +} + +DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, + const X509V3_EXT_METHOD *, ext); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, + const X509V3_EXT_METHOD *, ext); + +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) +{ + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, *const *ret; + int idx; + if (nid < 0) + return NULL; + tmp.ext_nid = nid; + ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT); + if (ret) + return *ret; + if (!ext_list) + return NULL; + idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); + if (idx == -1) + return NULL; + return sk_X509V3_EXT_METHOD_value(ext_list, idx); +} + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext) +{ + int nid; + if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) + return NULL; + return X509V3_EXT_get_nid(nid); +} + +int X509V3_EXT_free(int nid, void *ext_data) +{ + const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid); + if (ext_method == NULL) { + X509V3err(X509V3_F_X509V3_EXT_FREE, + X509V3_R_CANNOT_FIND_FREE_FUNCTION); + return 0; + } + + if (ext_method->it != NULL) + ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it)); + else if (ext_method->ext_free != NULL) + ext_method->ext_free(ext_data); + else { + X509V3err(X509V3_F_X509V3_EXT_FREE, + X509V3_R_CANNOT_FIND_FREE_FUNCTION); + return 0; + } + + return 1; +} + +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) +{ + for (; extlist->ext_nid != -1; extlist++) + if (!X509V3_EXT_add(extlist)) + return 0; + return 1; +} + +int X509V3_EXT_add_alias(int nid_to, int nid_from) +{ + const X509V3_EXT_METHOD *ext; + X509V3_EXT_METHOD *tmpext; + + if (!(ext = X509V3_EXT_get_nid(nid_from))) { + X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, + X509V3_R_EXTENSION_NOT_FOUND); + return 0; + } + if (! + (tmpext = + (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { + X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE); + return 0; + } + *tmpext = *ext; + tmpext->ext_nid = nid_to; + tmpext->ext_flags |= X509V3_EXT_DYNAMIC; + return X509V3_EXT_add(tmpext); +} + +void X509V3_EXT_cleanup(void) +{ + sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free); + ext_list = NULL; +} + +static void ext_list_free(X509V3_EXT_METHOD *ext) +{ + if (ext->ext_flags & X509V3_EXT_DYNAMIC) + OPENSSL_free(ext); +} + +/* + * Legacy function: we don't need to add standard extensions any more because + * they are now kept in ext_dat.h. + */ + +int X509V3_add_standard_extensions(void) +{ + return 1; +} + +/* Return an extension internal structure */ + +void *X509V3_EXT_d2i(X509_EXTENSION *ext) +{ + const X509V3_EXT_METHOD *method; + const unsigned char *p; + + if (!(method = X509V3_EXT_get(ext))) + return NULL; + p = ext->value->data; + if (method->it) + return ASN1_item_d2i(NULL, &p, ext->value->length, + ASN1_ITEM_ptr(method->it)); + return method->d2i(NULL, &p, ext->value->length); +} + +/*- + * Get critical flag and decoded version of extension from a NID. + * The "idx" variable returns the last found extension and can + * be used to retrieve multiple extensions of the same NID. + * However multiple extensions with the same NID is usually + * due to a badly encoded certificate so if idx is NULL we + * choke if multiple extensions exist. + * The "crit" variable is set to the critical value. + * The return value is the decoded extension or NULL on + * error. The actual error can have several different causes, + * the value of *crit reflects the cause: + * >= 0, extension found but not decoded (reflects critical value). + * -1 extension not found. + * -2 extension occurs more than once. + */ + +void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx) +{ + int lastpos, i; + X509_EXTENSION *ex, *found_ex = NULL; + if (!x) { + if (idx) + *idx = -1; + if (crit) + *crit = -1; + return NULL; + } + if (idx) + lastpos = *idx + 1; + else + lastpos = 0; + if (lastpos < 0) + lastpos = 0; + for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) { + ex = sk_X509_EXTENSION_value(x, i); + if (OBJ_obj2nid(ex->object) == nid) { + if (idx) { + *idx = i; + found_ex = ex; + break; + } else if (found_ex) { + /* Found more than one */ + if (crit) + *crit = -2; + return NULL; + } + found_ex = ex; + } + } + if (found_ex) { + /* Found it */ + if (crit) + *crit = X509_EXTENSION_get_critical(found_ex); + return X509V3_EXT_d2i(found_ex); + } + + /* Extension not found */ + if (idx) + *idx = -1; + if (crit) + *crit = -1; + return NULL; +} + +/* + * This function is a general extension append, replace and delete utility. + * The precise operation is governed by the 'flags' value. The 'crit' and + * 'value' arguments (if relevant) are the extensions internal structure. + */ + +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags) +{ + int errcode, extidx = -1; + X509_EXTENSION *ext = NULL, *extmp; + STACK_OF(X509_EXTENSION) *ret = NULL; + unsigned long ext_op = flags & X509V3_ADD_OP_MASK; + + /* + * If appending we don't care if it exists, otherwise look for existing + * extension. + */ + if (ext_op != X509V3_ADD_APPEND) + extidx = X509v3_get_ext_by_NID(*x, nid, -1); + + /* See if extension exists */ + if (extidx >= 0) { + /* If keep existing, nothing to do */ + if (ext_op == X509V3_ADD_KEEP_EXISTING) + return 1; + /* If default then its an error */ + if (ext_op == X509V3_ADD_DEFAULT) { + errcode = X509V3_R_EXTENSION_EXISTS; + goto err; + } + /* If delete, just delete it */ + if (ext_op == X509V3_ADD_DELETE) { + if (!sk_X509_EXTENSION_delete(*x, extidx)) + return -1; + return 1; + } + } else { + /* + * If replace existing or delete, error since extension must exist + */ + if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || + (ext_op == X509V3_ADD_DELETE)) { + errcode = X509V3_R_EXTENSION_NOT_FOUND; + goto err; + } + } + + /* + * If we get this far then we have to create an extension: could have + * some flags for alternative encoding schemes... + */ + + ext = X509V3_EXT_i2d(nid, crit, value); + + if (!ext) { + X509V3err(X509V3_F_X509V3_ADD1_I2D, + X509V3_R_ERROR_CREATING_EXTENSION); + return 0; + } + + /* If extension exists replace it.. */ + if (extidx >= 0) { + extmp = sk_X509_EXTENSION_value(*x, extidx); + X509_EXTENSION_free(extmp); + if (!sk_X509_EXTENSION_set(*x, extidx, ext)) + return -1; + return 1; + } + + if ((ret = *x) == NULL + && (ret = sk_X509_EXTENSION_new_null()) == NULL) + goto m_fail; + if (!sk_X509_EXTENSION_push(ret, ext)) + goto m_fail; + + *x = ret; + return 1; + + m_fail: + if (ret != *x) + sk_X509_EXTENSION_free(ret); + X509_EXTENSION_free(ext); + return -1; + + err: + if (!(flags & X509V3_ADD_SILENT)) + X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode); + return 0; +} + +IMPLEMENT_STACK_OF(X509V3_EXT_METHOD) diff --git a/Sources/COpenSSL/v3err.c b/Sources/COpenSSL/v3err.c new file mode 100644 index 00000000..1274e690 --- /dev/null +++ b/Sources/COpenSSL/v3err.c @@ -0,0 +1,249 @@ +/* crypto/x509v3/v3err.c */ +/* ==================================================================== + * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +#include "x509v3.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason) + +static ERR_STRING_DATA X509V3_str_functs[] = { + {ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "a2i_GENERAL_NAME"}, + {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), + "ASIDENTIFIERCHOICE_CANONIZE"}, + {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), + "ASIDENTIFIERCHOICE_IS_CANONICAL"}, + {ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"}, + {ERR_FUNC(X509V3_F_COPY_ISSUER), "COPY_ISSUER"}, + {ERR_FUNC(X509V3_F_DO_DIRNAME), "DO_DIRNAME"}, + {ERR_FUNC(X509V3_F_DO_EXT_CONF), "DO_EXT_CONF"}, + {ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"}, + {ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"}, + {ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "GNAMES_FROM_SECTNAME"}, + {ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"}, + {ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS), + "I2V_AUTHORITY_INFO_ACCESS"}, + {ERR_FUNC(X509V3_F_NOTICE_SECTION), "NOTICE_SECTION"}, + {ERR_FUNC(X509V3_F_NREF_NOS), "NREF_NOS"}, + {ERR_FUNC(X509V3_F_POLICY_SECTION), "POLICY_SECTION"}, + {ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "PROCESS_PCI_VALUE"}, + {ERR_FUNC(X509V3_F_R2I_CERTPOL), "R2I_CERTPOL"}, + {ERR_FUNC(X509V3_F_R2I_PCI), "R2I_PCI"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "S2I_ASN1_IA5STRING"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"}, + {ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"}, + {ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "SET_DIST_POINT_NAME"}, + {ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"}, + {ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"}, + {ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"}, + {ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "V2I_ASIDENTIFIERS"}, + {ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"}, + {ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS), + "V2I_AUTHORITY_INFO_ACCESS"}, + {ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "V2I_AUTHORITY_KEYID"}, + {ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "V2I_BASIC_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_CRLD), "V2I_CRLD"}, + {ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"}, + {ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"}, + {ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"}, + {ERR_FUNC(X509V3_F_V2I_IDP), "V2I_IDP"}, + {ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"}, + {ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"}, + {ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "V2I_POLICY_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "V2I_POLICY_MAPPINGS"}, + {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "V2I_SUBJECT_ALT"}, + {ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL), + "V3_ADDR_VALIDATE_PATH_INTERNAL"}, + {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "V3_GENERIC_EXTENSION"}, + {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"}, + {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_CONF), "X509V3_EXT_conf"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_FREE), "X509V3_EXT_free"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"}, + {ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"}, + {ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"}, + {ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"}, + {ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"}, + {ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"}, + {ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"}, + {0, NULL} +}; + +static ERR_STRING_DATA X509V3_str_reasons[] = { + {ERR_REASON(X509V3_R_BAD_IP_ADDRESS), "bad ip address"}, + {ERR_REASON(X509V3_R_BAD_OBJECT), "bad object"}, + {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR), "bn dec2bn error"}, + {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR), + "bn to asn1 integer error"}, + {ERR_REASON(X509V3_R_CANNOT_FIND_FREE_FUNCTION), + "cannot find free function"}, + {ERR_REASON(X509V3_R_DIRNAME_ERROR), "dirname error"}, + {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"}, + {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID), "duplicate zone id"}, + {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, + {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION), + "error creating extension"}, + {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION), "error in extension"}, + {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"}, + {ERR_REASON(X509V3_R_EXTENSION_EXISTS), "extension exists"}, + {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"}, + {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"}, + {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), + "extension setting not supported"}, + {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"}, + {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"}, + {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"}, + {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), + "incorrect policy syntax tag"}, + {ERR_REASON(X509V3_R_INVALID_ASNUMBER), "invalid asnumber"}, + {ERR_REASON(X509V3_R_INVALID_ASRANGE), "invalid asrange"}, + {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, + {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING), + "invalid extension string"}, + {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"}, + {ERR_REASON(X509V3_R_INVALID_IPADDRESS), "invalid ipaddress"}, + {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"}, + {ERR_REASON(X509V3_R_INVALID_NAME), "invalid name"}, + {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, + {ERR_REASON(X509V3_R_INVALID_NULL_NAME), "invalid null name"}, + {ERR_REASON(X509V3_R_INVALID_NULL_VALUE), "invalid null value"}, + {ERR_REASON(X509V3_R_INVALID_NUMBER), "invalid number"}, + {ERR_REASON(X509V3_R_INVALID_NUMBERS), "invalid numbers"}, + {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER), + "invalid object identifier"}, + {ERR_REASON(X509V3_R_INVALID_OPTION), "invalid option"}, + {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER), + "invalid policy identifier"}, + {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING), + "invalid proxy policy setting"}, + {ERR_REASON(X509V3_R_INVALID_PURPOSE), "invalid purpose"}, + {ERR_REASON(X509V3_R_INVALID_SAFI), "invalid safi"}, + {ERR_REASON(X509V3_R_INVALID_SECTION), "invalid section"}, + {ERR_REASON(X509V3_R_INVALID_SYNTAX), "invalid syntax"}, + {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"}, + {ERR_REASON(X509V3_R_MISSING_VALUE), "missing value"}, + {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), + "need organization and numbers"}, + {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE), "no config database"}, + {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"}, + {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS), "no issuer details"}, + {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"}, + {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), + "no proxy cert policy language defined"}, + {ERR_REASON(X509V3_R_NO_PUBLIC_KEY), "no public key"}, + {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS), "no subject details"}, + {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, + {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"}, + {ERR_REASON(X509V3_R_OTHERNAME_ERROR), "othername error"}, + {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), + "policy language already defined"}, + {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH), "policy path length"}, + {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), + "policy path length already defined"}, + {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED), + "policy syntax not currently supported"}, + {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), + "policy when proxy language requires no policy"}, + {ERR_REASON(X509V3_R_SECTION_NOT_FOUND), "section not found"}, + {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), + "unable to get issuer details"}, + {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), + "unable to get issuer keyid"}, + {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), + "unknown bit string argument"}, + {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION), "unknown extension"}, + {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"}, + {ERR_REASON(X509V3_R_UNKNOWN_OPTION), "unknown option"}, + {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION), "unsupported option"}, + {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE), "unsupported type"}, + {ERR_REASON(X509V3_R_USER_TOO_LONG), "user too long"}, + {0, NULL} +}; + +#endif + +void ERR_load_X509V3_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { + ERR_load_strings(0, X509V3_str_functs); + ERR_load_strings(0, X509V3_str_reasons); + } +#endif +} diff --git a/Sources/COpenSSL/vpm_int.h b/Sources/COpenSSL/vpm_int.h new file mode 100644 index 00000000..9c55defc --- /dev/null +++ b/Sources/COpenSSL/vpm_int.h @@ -0,0 +1,70 @@ +/* vpm_int.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2013. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* internal only structure to hold additional X509_VERIFY_PARAM data */ + +struct X509_VERIFY_PARAM_ID_st { + STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */ + unsigned int hostflags; /* Flags to control matching features */ + char *peername; /* Matching hostname in peer certificate */ + char *email; /* If not NULL email address to match */ + size_t emaillen; + unsigned char *ip; /* If not NULL IP address to match */ + size_t iplen; /* Length of IP address */ +}; diff --git a/Sources/COpenSSL/whrlpool.h b/Sources/COpenSSL/whrlpool.h new file mode 100644 index 00000000..b6f3d035 --- /dev/null +++ b/Sources/COpenSSL/whrlpool.h @@ -0,0 +1,41 @@ +#ifndef HEADER_WHRLPOOL_H +# define HEADER_WHRLPOOL_H + +# include "e_os2.h" +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define WHIRLPOOL_DIGEST_LENGTH (512/8) +# define WHIRLPOOL_BBLOCK 512 +# define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK / 8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)]; +} WHIRLPOOL_CTX; + +# ifndef OPENSSL_NO_WHIRLPOOL +# ifdef OPENSSL_FIPS +int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +# endif +int WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits); +int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md); +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Sources/COpenSSL/wp_.c b/Sources/COpenSSL/wp_.c new file mode 100644 index 00000000..cf6a3191 --- /dev/null +++ b/Sources/COpenSSL/wp_.c @@ -0,0 +1,1038 @@ +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "wp_locl.h" +#include + +typedef unsigned char u8; +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32) +typedef unsigned __int64 u64; +#elif defined(__arch64__) +typedef unsigned long u64; +#else +typedef unsigned long long u64; +#endif + +#define ROUNDS 10 + +#define STRICT_ALIGNMENT +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) +/* + * Well, formally there're couple of other architectures, which permit + * unaligned loads, specifically those not crossing cache lines, IA-64 and + * PowerPC... + */ +# undef STRICT_ALIGNMENT +#endif + +#undef SMALL_REGISTER_BANK +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define SMALL_REGISTER_BANK +# if defined(WHIRLPOOL_ASM) +# ifndef OPENSSL_SMALL_FOOTPRINT +/* + * it appears that for elder non-MMX + * CPUs this is actually faster! + */ +# define OPENSSL_SMALL_FOOTPRINT +# endif +# define GO_FOR_MMX(ctx,inp,num) do { \ + extern unsigned int OPENSSL_ia32cap_P[]; \ + void whirlpool_block_mmx(void *,const void *,size_t); \ + if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \ + whirlpool_block_mmx(ctx->H.c,inp,num); return; \ + } while (0) +# endif +#endif + +#undef ROTATE +#if defined(_MSC_VER) +# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ +# pragma intrinsic(_rotl64) +# define ROTATE(a,n) _rotl64((a),n) +# endif +#elif defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# if defined(L_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \ + : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) +# elif defined(B_ENDIAN) + /* + * Most will argue that x86_64 is always little-endian. Well, yes, but + * then we have stratus.com who has modified gcc to "emulate" + * big-endian on x86. Is there evidence that they [or somebody else] + * won't do same for x86_64? Naturally no. And this line is waiting + * ready for that brave soul:-) + */ +# define ROTATE(a,n) ({ u64 ret; asm ("rorq %1,%0" \ + : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) +# endif +# elif defined(__ia64) || defined(__ia64__) +# if defined(L_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ + : "=r"(ret) : "r"(a),"M"(64-(n))); ret; }) +# elif defined(B_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ + : "=r"(ret) : "r"(a),"M"(n)); ret; }) +# endif +# endif +#endif + +#if defined(OPENSSL_SMALL_FOOTPRINT) +# if !defined(ROTATE) +# if defined(L_ENDIAN) /* little-endians have to rotate left */ +# define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n)) +# elif defined(B_ENDIAN) /* big-endians have to rotate right */ +# define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n)) +# endif +# endif +# if defined(ROTATE) && !defined(STRICT_ALIGNMENT) +# define STRICT_ALIGNMENT /* ensure smallest table size */ +# endif +#endif + +/* + * Table size depends on STRICT_ALIGNMENT and whether or not endian- + * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not + * defined, which is normally the case on x86[_64] CPUs, the table is + * 4KB large unconditionally. Otherwise if ROTATE is defined, the + * table is 2KB large, and otherwise - 16KB. 2KB table requires a + * whole bunch of additional rotations, but I'm willing to "trade," + * because 16KB table certainly trashes L1 cache. I wish all CPUs + * could handle unaligned load as 4KB table doesn't trash the cache, + * nor does it require additional rotations. + */ +/* + * Note that every Cn macro expands as two loads: one byte load and + * one quadword load. One can argue that that many single-byte loads + * is too excessive, as one could load a quadword and "milk" it for + * eight 8-bit values instead. Well, yes, but in order to do so *and* + * avoid excessive loads you have to accomodate a handful of 64-bit + * values in the register bank and issue a bunch of shifts and mask. + * It's a tradeoff: loads vs. shift and mask in big register bank[!]. + * On most CPUs eight single-byte loads are faster and I let other + * ones to depend on smart compiler to fold byte loads if beneficial. + * Hand-coded assembler would be another alternative:-) + */ +#ifdef STRICT_ALIGNMENT +# if defined(ROTATE) +# define N 1 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (Cx.q[K.c[(i)*8+0]]) +# define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8) +# define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16) +# define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24) +# define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32) +# define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40) +# define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48) +# define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56) +# else +# define N 8 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c7,c0,c1,c2,c3,c4,c5,c6, \ + c6,c7,c0,c1,c2,c3,c4,c5, \ + c5,c6,c7,c0,c1,c2,c3,c4, \ + c4,c5,c6,c7,c0,c1,c2,c3, \ + c3,c4,c5,c6,c7,c0,c1,c2, \ + c2,c3,c4,c5,c6,c7,c0,c1, \ + c1,c2,c3,c4,c5,c6,c7,c0 +# define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]]) +# define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]]) +# define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]]) +# define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]]) +# define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]]) +# define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]]) +# define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]]) +# define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]]) +# endif +#else +# define N 2 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) +# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) +# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) +# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) +# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) +# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) +# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) +# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) +#endif + +static const + union { + u8 c[(256 * N + ROUNDS) * sizeof(u64)]; + u64 q[(256 * N + ROUNDS)]; +} Cx = { + { + /* Note endian-neutral representation:-) */ + LL(0x18, 0x18, 0x60, 0x18, 0xc0, 0x78, 0x30, 0xd8), + LL(0x23, 0x23, 0x8c, 0x23, 0x05, 0xaf, 0x46, 0x26), + LL(0xc6, 0xc6, 0x3f, 0xc6, 0x7e, 0xf9, 0x91, 0xb8), + LL(0xe8, 0xe8, 0x87, 0xe8, 0x13, 0x6f, 0xcd, 0xfb), + LL(0x87, 0x87, 0x26, 0x87, 0x4c, 0xa1, 0x13, 0xcb), + LL(0xb8, 0xb8, 0xda, 0xb8, 0xa9, 0x62, 0x6d, 0x11), + LL(0x01, 0x01, 0x04, 0x01, 0x08, 0x05, 0x02, 0x09), + LL(0x4f, 0x4f, 0x21, 0x4f, 0x42, 0x6e, 0x9e, 0x0d), + LL(0x36, 0x36, 0xd8, 0x36, 0xad, 0xee, 0x6c, 0x9b), + LL(0xa6, 0xa6, 0xa2, 0xa6, 0x59, 0x04, 0x51, 0xff), + LL(0xd2, 0xd2, 0x6f, 0xd2, 0xde, 0xbd, 0xb9, 0x0c), + LL(0xf5, 0xf5, 0xf3, 0xf5, 0xfb, 0x06, 0xf7, 0x0e), + LL(0x79, 0x79, 0xf9, 0x79, 0xef, 0x80, 0xf2, 0x96), + LL(0x6f, 0x6f, 0xa1, 0x6f, 0x5f, 0xce, 0xde, 0x30), + LL(0x91, 0x91, 0x7e, 0x91, 0xfc, 0xef, 0x3f, 0x6d), + LL(0x52, 0x52, 0x55, 0x52, 0xaa, 0x07, 0xa4, 0xf8), + LL(0x60, 0x60, 0x9d, 0x60, 0x27, 0xfd, 0xc0, 0x47), + LL(0xbc, 0xbc, 0xca, 0xbc, 0x89, 0x76, 0x65, 0x35), + LL(0x9b, 0x9b, 0x56, 0x9b, 0xac, 0xcd, 0x2b, 0x37), + LL(0x8e, 0x8e, 0x02, 0x8e, 0x04, 0x8c, 0x01, 0x8a), + LL(0xa3, 0xa3, 0xb6, 0xa3, 0x71, 0x15, 0x5b, 0xd2), + LL(0x0c, 0x0c, 0x30, 0x0c, 0x60, 0x3c, 0x18, 0x6c), + LL(0x7b, 0x7b, 0xf1, 0x7b, 0xff, 0x8a, 0xf6, 0x84), + LL(0x35, 0x35, 0xd4, 0x35, 0xb5, 0xe1, 0x6a, 0x80), + LL(0x1d, 0x1d, 0x74, 0x1d, 0xe8, 0x69, 0x3a, 0xf5), + LL(0xe0, 0xe0, 0xa7, 0xe0, 0x53, 0x47, 0xdd, 0xb3), + LL(0xd7, 0xd7, 0x7b, 0xd7, 0xf6, 0xac, 0xb3, 0x21), + LL(0xc2, 0xc2, 0x2f, 0xc2, 0x5e, 0xed, 0x99, 0x9c), + LL(0x2e, 0x2e, 0xb8, 0x2e, 0x6d, 0x96, 0x5c, 0x43), + LL(0x4b, 0x4b, 0x31, 0x4b, 0x62, 0x7a, 0x96, 0x29), + LL(0xfe, 0xfe, 0xdf, 0xfe, 0xa3, 0x21, 0xe1, 0x5d), + LL(0x57, 0x57, 0x41, 0x57, 0x82, 0x16, 0xae, 0xd5), + LL(0x15, 0x15, 0x54, 0x15, 0xa8, 0x41, 0x2a, 0xbd), + LL(0x77, 0x77, 0xc1, 0x77, 0x9f, 0xb6, 0xee, 0xe8), + LL(0x37, 0x37, 0xdc, 0x37, 0xa5, 0xeb, 0x6e, 0x92), + LL(0xe5, 0xe5, 0xb3, 0xe5, 0x7b, 0x56, 0xd7, 0x9e), + LL(0x9f, 0x9f, 0x46, 0x9f, 0x8c, 0xd9, 0x23, 0x13), + LL(0xf0, 0xf0, 0xe7, 0xf0, 0xd3, 0x17, 0xfd, 0x23), + LL(0x4a, 0x4a, 0x35, 0x4a, 0x6a, 0x7f, 0x94, 0x20), + LL(0xda, 0xda, 0x4f, 0xda, 0x9e, 0x95, 0xa9, 0x44), + LL(0x58, 0x58, 0x7d, 0x58, 0xfa, 0x25, 0xb0, 0xa2), + LL(0xc9, 0xc9, 0x03, 0xc9, 0x06, 0xca, 0x8f, 0xcf), + LL(0x29, 0x29, 0xa4, 0x29, 0x55, 0x8d, 0x52, 0x7c), + LL(0x0a, 0x0a, 0x28, 0x0a, 0x50, 0x22, 0x14, 0x5a), + LL(0xb1, 0xb1, 0xfe, 0xb1, 0xe1, 0x4f, 0x7f, 0x50), + LL(0xa0, 0xa0, 0xba, 0xa0, 0x69, 0x1a, 0x5d, 0xc9), + LL(0x6b, 0x6b, 0xb1, 0x6b, 0x7f, 0xda, 0xd6, 0x14), + LL(0x85, 0x85, 0x2e, 0x85, 0x5c, 0xab, 0x17, 0xd9), + LL(0xbd, 0xbd, 0xce, 0xbd, 0x81, 0x73, 0x67, 0x3c), + LL(0x5d, 0x5d, 0x69, 0x5d, 0xd2, 0x34, 0xba, 0x8f), + LL(0x10, 0x10, 0x40, 0x10, 0x80, 0x50, 0x20, 0x90), + LL(0xf4, 0xf4, 0xf7, 0xf4, 0xf3, 0x03, 0xf5, 0x07), + LL(0xcb, 0xcb, 0x0b, 0xcb, 0x16, 0xc0, 0x8b, 0xdd), + LL(0x3e, 0x3e, 0xf8, 0x3e, 0xed, 0xc6, 0x7c, 0xd3), + LL(0x05, 0x05, 0x14, 0x05, 0x28, 0x11, 0x0a, 0x2d), + LL(0x67, 0x67, 0x81, 0x67, 0x1f, 0xe6, 0xce, 0x78), + LL(0xe4, 0xe4, 0xb7, 0xe4, 0x73, 0x53, 0xd5, 0x97), + LL(0x27, 0x27, 0x9c, 0x27, 0x25, 0xbb, 0x4e, 0x02), + LL(0x41, 0x41, 0x19, 0x41, 0x32, 0x58, 0x82, 0x73), + LL(0x8b, 0x8b, 0x16, 0x8b, 0x2c, 0x9d, 0x0b, 0xa7), + LL(0xa7, 0xa7, 0xa6, 0xa7, 0x51, 0x01, 0x53, 0xf6), + LL(0x7d, 0x7d, 0xe9, 0x7d, 0xcf, 0x94, 0xfa, 0xb2), + LL(0x95, 0x95, 0x6e, 0x95, 0xdc, 0xfb, 0x37, 0x49), + LL(0xd8, 0xd8, 0x47, 0xd8, 0x8e, 0x9f, 0xad, 0x56), + LL(0xfb, 0xfb, 0xcb, 0xfb, 0x8b, 0x30, 0xeb, 0x70), + LL(0xee, 0xee, 0x9f, 0xee, 0x23, 0x71, 0xc1, 0xcd), + LL(0x7c, 0x7c, 0xed, 0x7c, 0xc7, 0x91, 0xf8, 0xbb), + LL(0x66, 0x66, 0x85, 0x66, 0x17, 0xe3, 0xcc, 0x71), + LL(0xdd, 0xdd, 0x53, 0xdd, 0xa6, 0x8e, 0xa7, 0x7b), + LL(0x17, 0x17, 0x5c, 0x17, 0xb8, 0x4b, 0x2e, 0xaf), + LL(0x47, 0x47, 0x01, 0x47, 0x02, 0x46, 0x8e, 0x45), + LL(0x9e, 0x9e, 0x42, 0x9e, 0x84, 0xdc, 0x21, 0x1a), + LL(0xca, 0xca, 0x0f, 0xca, 0x1e, 0xc5, 0x89, 0xd4), + LL(0x2d, 0x2d, 0xb4, 0x2d, 0x75, 0x99, 0x5a, 0x58), + LL(0xbf, 0xbf, 0xc6, 0xbf, 0x91, 0x79, 0x63, 0x2e), + LL(0x07, 0x07, 0x1c, 0x07, 0x38, 0x1b, 0x0e, 0x3f), + LL(0xad, 0xad, 0x8e, 0xad, 0x01, 0x23, 0x47, 0xac), + LL(0x5a, 0x5a, 0x75, 0x5a, 0xea, 0x2f, 0xb4, 0xb0), + LL(0x83, 0x83, 0x36, 0x83, 0x6c, 0xb5, 0x1b, 0xef), + LL(0x33, 0x33, 0xcc, 0x33, 0x85, 0xff, 0x66, 0xb6), + LL(0x63, 0x63, 0x91, 0x63, 0x3f, 0xf2, 0xc6, 0x5c), + LL(0x02, 0x02, 0x08, 0x02, 0x10, 0x0a, 0x04, 0x12), + LL(0xaa, 0xaa, 0x92, 0xaa, 0x39, 0x38, 0x49, 0x93), + LL(0x71, 0x71, 0xd9, 0x71, 0xaf, 0xa8, 0xe2, 0xde), + LL(0xc8, 0xc8, 0x07, 0xc8, 0x0e, 0xcf, 0x8d, 0xc6), + LL(0x19, 0x19, 0x64, 0x19, 0xc8, 0x7d, 0x32, 0xd1), + LL(0x49, 0x49, 0x39, 0x49, 0x72, 0x70, 0x92, 0x3b), + LL(0xd9, 0xd9, 0x43, 0xd9, 0x86, 0x9a, 0xaf, 0x5f), + LL(0xf2, 0xf2, 0xef, 0xf2, 0xc3, 0x1d, 0xf9, 0x31), + LL(0xe3, 0xe3, 0xab, 0xe3, 0x4b, 0x48, 0xdb, 0xa8), + LL(0x5b, 0x5b, 0x71, 0x5b, 0xe2, 0x2a, 0xb6, 0xb9), + LL(0x88, 0x88, 0x1a, 0x88, 0x34, 0x92, 0x0d, 0xbc), + LL(0x9a, 0x9a, 0x52, 0x9a, 0xa4, 0xc8, 0x29, 0x3e), + LL(0x26, 0x26, 0x98, 0x26, 0x2d, 0xbe, 0x4c, 0x0b), + LL(0x32, 0x32, 0xc8, 0x32, 0x8d, 0xfa, 0x64, 0xbf), + LL(0xb0, 0xb0, 0xfa, 0xb0, 0xe9, 0x4a, 0x7d, 0x59), + LL(0xe9, 0xe9, 0x83, 0xe9, 0x1b, 0x6a, 0xcf, 0xf2), + LL(0x0f, 0x0f, 0x3c, 0x0f, 0x78, 0x33, 0x1e, 0x77), + LL(0xd5, 0xd5, 0x73, 0xd5, 0xe6, 0xa6, 0xb7, 0x33), + LL(0x80, 0x80, 0x3a, 0x80, 0x74, 0xba, 0x1d, 0xf4), + LL(0xbe, 0xbe, 0xc2, 0xbe, 0x99, 0x7c, 0x61, 0x27), + LL(0xcd, 0xcd, 0x13, 0xcd, 0x26, 0xde, 0x87, 0xeb), + LL(0x34, 0x34, 0xd0, 0x34, 0xbd, 0xe4, 0x68, 0x89), + LL(0x48, 0x48, 0x3d, 0x48, 0x7a, 0x75, 0x90, 0x32), + LL(0xff, 0xff, 0xdb, 0xff, 0xab, 0x24, 0xe3, 0x54), + LL(0x7a, 0x7a, 0xf5, 0x7a, 0xf7, 0x8f, 0xf4, 0x8d), + LL(0x90, 0x90, 0x7a, 0x90, 0xf4, 0xea, 0x3d, 0x64), + LL(0x5f, 0x5f, 0x61, 0x5f, 0xc2, 0x3e, 0xbe, 0x9d), + LL(0x20, 0x20, 0x80, 0x20, 0x1d, 0xa0, 0x40, 0x3d), + LL(0x68, 0x68, 0xbd, 0x68, 0x67, 0xd5, 0xd0, 0x0f), + LL(0x1a, 0x1a, 0x68, 0x1a, 0xd0, 0x72, 0x34, 0xca), + LL(0xae, 0xae, 0x82, 0xae, 0x19, 0x2c, 0x41, 0xb7), + LL(0xb4, 0xb4, 0xea, 0xb4, 0xc9, 0x5e, 0x75, 0x7d), + LL(0x54, 0x54, 0x4d, 0x54, 0x9a, 0x19, 0xa8, 0xce), + LL(0x93, 0x93, 0x76, 0x93, 0xec, 0xe5, 0x3b, 0x7f), + LL(0x22, 0x22, 0x88, 0x22, 0x0d, 0xaa, 0x44, 0x2f), + LL(0x64, 0x64, 0x8d, 0x64, 0x07, 0xe9, 0xc8, 0x63), + LL(0xf1, 0xf1, 0xe3, 0xf1, 0xdb, 0x12, 0xff, 0x2a), + LL(0x73, 0x73, 0xd1, 0x73, 0xbf, 0xa2, 0xe6, 0xcc), + LL(0x12, 0x12, 0x48, 0x12, 0x90, 0x5a, 0x24, 0x82), + LL(0x40, 0x40, 0x1d, 0x40, 0x3a, 0x5d, 0x80, 0x7a), + LL(0x08, 0x08, 0x20, 0x08, 0x40, 0x28, 0x10, 0x48), + LL(0xc3, 0xc3, 0x2b, 0xc3, 0x56, 0xe8, 0x9b, 0x95), + LL(0xec, 0xec, 0x97, 0xec, 0x33, 0x7b, 0xc5, 0xdf), + LL(0xdb, 0xdb, 0x4b, 0xdb, 0x96, 0x90, 0xab, 0x4d), + LL(0xa1, 0xa1, 0xbe, 0xa1, 0x61, 0x1f, 0x5f, 0xc0), + LL(0x8d, 0x8d, 0x0e, 0x8d, 0x1c, 0x83, 0x07, 0x91), + LL(0x3d, 0x3d, 0xf4, 0x3d, 0xf5, 0xc9, 0x7a, 0xc8), + LL(0x97, 0x97, 0x66, 0x97, 0xcc, 0xf1, 0x33, 0x5b), + LL(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + LL(0xcf, 0xcf, 0x1b, 0xcf, 0x36, 0xd4, 0x83, 0xf9), + LL(0x2b, 0x2b, 0xac, 0x2b, 0x45, 0x87, 0x56, 0x6e), + LL(0x76, 0x76, 0xc5, 0x76, 0x97, 0xb3, 0xec, 0xe1), + LL(0x82, 0x82, 0x32, 0x82, 0x64, 0xb0, 0x19, 0xe6), + LL(0xd6, 0xd6, 0x7f, 0xd6, 0xfe, 0xa9, 0xb1, 0x28), + LL(0x1b, 0x1b, 0x6c, 0x1b, 0xd8, 0x77, 0x36, 0xc3), + LL(0xb5, 0xb5, 0xee, 0xb5, 0xc1, 0x5b, 0x77, 0x74), + LL(0xaf, 0xaf, 0x86, 0xaf, 0x11, 0x29, 0x43, 0xbe), + LL(0x6a, 0x6a, 0xb5, 0x6a, 0x77, 0xdf, 0xd4, 0x1d), + LL(0x50, 0x50, 0x5d, 0x50, 0xba, 0x0d, 0xa0, 0xea), + LL(0x45, 0x45, 0x09, 0x45, 0x12, 0x4c, 0x8a, 0x57), + LL(0xf3, 0xf3, 0xeb, 0xf3, 0xcb, 0x18, 0xfb, 0x38), + LL(0x30, 0x30, 0xc0, 0x30, 0x9d, 0xf0, 0x60, 0xad), + LL(0xef, 0xef, 0x9b, 0xef, 0x2b, 0x74, 0xc3, 0xc4), + LL(0x3f, 0x3f, 0xfc, 0x3f, 0xe5, 0xc3, 0x7e, 0xda), + LL(0x55, 0x55, 0x49, 0x55, 0x92, 0x1c, 0xaa, 0xc7), + LL(0xa2, 0xa2, 0xb2, 0xa2, 0x79, 0x10, 0x59, 0xdb), + LL(0xea, 0xea, 0x8f, 0xea, 0x03, 0x65, 0xc9, 0xe9), + LL(0x65, 0x65, 0x89, 0x65, 0x0f, 0xec, 0xca, 0x6a), + LL(0xba, 0xba, 0xd2, 0xba, 0xb9, 0x68, 0x69, 0x03), + LL(0x2f, 0x2f, 0xbc, 0x2f, 0x65, 0x93, 0x5e, 0x4a), + LL(0xc0, 0xc0, 0x27, 0xc0, 0x4e, 0xe7, 0x9d, 0x8e), + LL(0xde, 0xde, 0x5f, 0xde, 0xbe, 0x81, 0xa1, 0x60), + LL(0x1c, 0x1c, 0x70, 0x1c, 0xe0, 0x6c, 0x38, 0xfc), + LL(0xfd, 0xfd, 0xd3, 0xfd, 0xbb, 0x2e, 0xe7, 0x46), + LL(0x4d, 0x4d, 0x29, 0x4d, 0x52, 0x64, 0x9a, 0x1f), + LL(0x92, 0x92, 0x72, 0x92, 0xe4, 0xe0, 0x39, 0x76), + LL(0x75, 0x75, 0xc9, 0x75, 0x8f, 0xbc, 0xea, 0xfa), + LL(0x06, 0x06, 0x18, 0x06, 0x30, 0x1e, 0x0c, 0x36), + LL(0x8a, 0x8a, 0x12, 0x8a, 0x24, 0x98, 0x09, 0xae), + LL(0xb2, 0xb2, 0xf2, 0xb2, 0xf9, 0x40, 0x79, 0x4b), + LL(0xe6, 0xe6, 0xbf, 0xe6, 0x63, 0x59, 0xd1, 0x85), + LL(0x0e, 0x0e, 0x38, 0x0e, 0x70, 0x36, 0x1c, 0x7e), + LL(0x1f, 0x1f, 0x7c, 0x1f, 0xf8, 0x63, 0x3e, 0xe7), + LL(0x62, 0x62, 0x95, 0x62, 0x37, 0xf7, 0xc4, 0x55), + LL(0xd4, 0xd4, 0x77, 0xd4, 0xee, 0xa3, 0xb5, 0x3a), + LL(0xa8, 0xa8, 0x9a, 0xa8, 0x29, 0x32, 0x4d, 0x81), + LL(0x96, 0x96, 0x62, 0x96, 0xc4, 0xf4, 0x31, 0x52), + LL(0xf9, 0xf9, 0xc3, 0xf9, 0x9b, 0x3a, 0xef, 0x62), + LL(0xc5, 0xc5, 0x33, 0xc5, 0x66, 0xf6, 0x97, 0xa3), + LL(0x25, 0x25, 0x94, 0x25, 0x35, 0xb1, 0x4a, 0x10), + LL(0x59, 0x59, 0x79, 0x59, 0xf2, 0x20, 0xb2, 0xab), + LL(0x84, 0x84, 0x2a, 0x84, 0x54, 0xae, 0x15, 0xd0), + LL(0x72, 0x72, 0xd5, 0x72, 0xb7, 0xa7, 0xe4, 0xc5), + LL(0x39, 0x39, 0xe4, 0x39, 0xd5, 0xdd, 0x72, 0xec), + LL(0x4c, 0x4c, 0x2d, 0x4c, 0x5a, 0x61, 0x98, 0x16), + LL(0x5e, 0x5e, 0x65, 0x5e, 0xca, 0x3b, 0xbc, 0x94), + LL(0x78, 0x78, 0xfd, 0x78, 0xe7, 0x85, 0xf0, 0x9f), + LL(0x38, 0x38, 0xe0, 0x38, 0xdd, 0xd8, 0x70, 0xe5), + LL(0x8c, 0x8c, 0x0a, 0x8c, 0x14, 0x86, 0x05, 0x98), + LL(0xd1, 0xd1, 0x63, 0xd1, 0xc6, 0xb2, 0xbf, 0x17), + LL(0xa5, 0xa5, 0xae, 0xa5, 0x41, 0x0b, 0x57, 0xe4), + LL(0xe2, 0xe2, 0xaf, 0xe2, 0x43, 0x4d, 0xd9, 0xa1), + LL(0x61, 0x61, 0x99, 0x61, 0x2f, 0xf8, 0xc2, 0x4e), + LL(0xb3, 0xb3, 0xf6, 0xb3, 0xf1, 0x45, 0x7b, 0x42), + LL(0x21, 0x21, 0x84, 0x21, 0x15, 0xa5, 0x42, 0x34), + LL(0x9c, 0x9c, 0x4a, 0x9c, 0x94, 0xd6, 0x25, 0x08), + LL(0x1e, 0x1e, 0x78, 0x1e, 0xf0, 0x66, 0x3c, 0xee), + LL(0x43, 0x43, 0x11, 0x43, 0x22, 0x52, 0x86, 0x61), + LL(0xc7, 0xc7, 0x3b, 0xc7, 0x76, 0xfc, 0x93, 0xb1), + LL(0xfc, 0xfc, 0xd7, 0xfc, 0xb3, 0x2b, 0xe5, 0x4f), + LL(0x04, 0x04, 0x10, 0x04, 0x20, 0x14, 0x08, 0x24), + LL(0x51, 0x51, 0x59, 0x51, 0xb2, 0x08, 0xa2, 0xe3), + LL(0x99, 0x99, 0x5e, 0x99, 0xbc, 0xc7, 0x2f, 0x25), + LL(0x6d, 0x6d, 0xa9, 0x6d, 0x4f, 0xc4, 0xda, 0x22), + LL(0x0d, 0x0d, 0x34, 0x0d, 0x68, 0x39, 0x1a, 0x65), + LL(0xfa, 0xfa, 0xcf, 0xfa, 0x83, 0x35, 0xe9, 0x79), + LL(0xdf, 0xdf, 0x5b, 0xdf, 0xb6, 0x84, 0xa3, 0x69), + LL(0x7e, 0x7e, 0xe5, 0x7e, 0xd7, 0x9b, 0xfc, 0xa9), + LL(0x24, 0x24, 0x90, 0x24, 0x3d, 0xb4, 0x48, 0x19), + LL(0x3b, 0x3b, 0xec, 0x3b, 0xc5, 0xd7, 0x76, 0xfe), + LL(0xab, 0xab, 0x96, 0xab, 0x31, 0x3d, 0x4b, 0x9a), + LL(0xce, 0xce, 0x1f, 0xce, 0x3e, 0xd1, 0x81, 0xf0), + LL(0x11, 0x11, 0x44, 0x11, 0x88, 0x55, 0x22, 0x99), + LL(0x8f, 0x8f, 0x06, 0x8f, 0x0c, 0x89, 0x03, 0x83), + LL(0x4e, 0x4e, 0x25, 0x4e, 0x4a, 0x6b, 0x9c, 0x04), + LL(0xb7, 0xb7, 0xe6, 0xb7, 0xd1, 0x51, 0x73, 0x66), + LL(0xeb, 0xeb, 0x8b, 0xeb, 0x0b, 0x60, 0xcb, 0xe0), + LL(0x3c, 0x3c, 0xf0, 0x3c, 0xfd, 0xcc, 0x78, 0xc1), + LL(0x81, 0x81, 0x3e, 0x81, 0x7c, 0xbf, 0x1f, 0xfd), + LL(0x94, 0x94, 0x6a, 0x94, 0xd4, 0xfe, 0x35, 0x40), + LL(0xf7, 0xf7, 0xfb, 0xf7, 0xeb, 0x0c, 0xf3, 0x1c), + LL(0xb9, 0xb9, 0xde, 0xb9, 0xa1, 0x67, 0x6f, 0x18), + LL(0x13, 0x13, 0x4c, 0x13, 0x98, 0x5f, 0x26, 0x8b), + LL(0x2c, 0x2c, 0xb0, 0x2c, 0x7d, 0x9c, 0x58, 0x51), + LL(0xd3, 0xd3, 0x6b, 0xd3, 0xd6, 0xb8, 0xbb, 0x05), + LL(0xe7, 0xe7, 0xbb, 0xe7, 0x6b, 0x5c, 0xd3, 0x8c), + LL(0x6e, 0x6e, 0xa5, 0x6e, 0x57, 0xcb, 0xdc, 0x39), + LL(0xc4, 0xc4, 0x37, 0xc4, 0x6e, 0xf3, 0x95, 0xaa), + LL(0x03, 0x03, 0x0c, 0x03, 0x18, 0x0f, 0x06, 0x1b), + LL(0x56, 0x56, 0x45, 0x56, 0x8a, 0x13, 0xac, 0xdc), + LL(0x44, 0x44, 0x0d, 0x44, 0x1a, 0x49, 0x88, 0x5e), + LL(0x7f, 0x7f, 0xe1, 0x7f, 0xdf, 0x9e, 0xfe, 0xa0), + LL(0xa9, 0xa9, 0x9e, 0xa9, 0x21, 0x37, 0x4f, 0x88), + LL(0x2a, 0x2a, 0xa8, 0x2a, 0x4d, 0x82, 0x54, 0x67), + LL(0xbb, 0xbb, 0xd6, 0xbb, 0xb1, 0x6d, 0x6b, 0x0a), + LL(0xc1, 0xc1, 0x23, 0xc1, 0x46, 0xe2, 0x9f, 0x87), + LL(0x53, 0x53, 0x51, 0x53, 0xa2, 0x02, 0xa6, 0xf1), + LL(0xdc, 0xdc, 0x57, 0xdc, 0xae, 0x8b, 0xa5, 0x72), + LL(0x0b, 0x0b, 0x2c, 0x0b, 0x58, 0x27, 0x16, 0x53), + LL(0x9d, 0x9d, 0x4e, 0x9d, 0x9c, 0xd3, 0x27, 0x01), + LL(0x6c, 0x6c, 0xad, 0x6c, 0x47, 0xc1, 0xd8, 0x2b), + LL(0x31, 0x31, 0xc4, 0x31, 0x95, 0xf5, 0x62, 0xa4), + LL(0x74, 0x74, 0xcd, 0x74, 0x87, 0xb9, 0xe8, 0xf3), + LL(0xf6, 0xf6, 0xff, 0xf6, 0xe3, 0x09, 0xf1, 0x15), + LL(0x46, 0x46, 0x05, 0x46, 0x0a, 0x43, 0x8c, 0x4c), + LL(0xac, 0xac, 0x8a, 0xac, 0x09, 0x26, 0x45, 0xa5), + LL(0x89, 0x89, 0x1e, 0x89, 0x3c, 0x97, 0x0f, 0xb5), + LL(0x14, 0x14, 0x50, 0x14, 0xa0, 0x44, 0x28, 0xb4), + LL(0xe1, 0xe1, 0xa3, 0xe1, 0x5b, 0x42, 0xdf, 0xba), + LL(0x16, 0x16, 0x58, 0x16, 0xb0, 0x4e, 0x2c, 0xa6), + LL(0x3a, 0x3a, 0xe8, 0x3a, 0xcd, 0xd2, 0x74, 0xf7), + LL(0x69, 0x69, 0xb9, 0x69, 0x6f, 0xd0, 0xd2, 0x06), + LL(0x09, 0x09, 0x24, 0x09, 0x48, 0x2d, 0x12, 0x41), + LL(0x70, 0x70, 0xdd, 0x70, 0xa7, 0xad, 0xe0, 0xd7), + LL(0xb6, 0xb6, 0xe2, 0xb6, 0xd9, 0x54, 0x71, 0x6f), + LL(0xd0, 0xd0, 0x67, 0xd0, 0xce, 0xb7, 0xbd, 0x1e), + LL(0xed, 0xed, 0x93, 0xed, 0x3b, 0x7e, 0xc7, 0xd6), + LL(0xcc, 0xcc, 0x17, 0xcc, 0x2e, 0xdb, 0x85, 0xe2), + LL(0x42, 0x42, 0x15, 0x42, 0x2a, 0x57, 0x84, 0x68), + LL(0x98, 0x98, 0x5a, 0x98, 0xb4, 0xc2, 0x2d, 0x2c), + LL(0xa4, 0xa4, 0xaa, 0xa4, 0x49, 0x0e, 0x55, 0xed), + LL(0x28, 0x28, 0xa0, 0x28, 0x5d, 0x88, 0x50, 0x75), + LL(0x5c, 0x5c, 0x6d, 0x5c, 0xda, 0x31, 0xb8, 0x86), + LL(0xf8, 0xf8, 0xc7, 0xf8, 0x93, 0x3f, 0xed, 0x6b), + LL(0x86, 0x86, 0x22, 0x86, 0x44, 0xa4, 0x11, 0xc2), +#define RC (&(Cx.q[256*N])) + 0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, + /* rc[ROUNDS] */ + 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, 0x60, 0xbc, 0x9b, + 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, + 0xfe, 0x57, 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, + 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, 0xbd, 0x5d, 0x10, 0xf4, + 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, + 0xd8, 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, + 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33 + } + }; + +void whirlpool_block(WHIRLPOOL_CTX *ctx, const void *inp, size_t n) +{ + int r; + const u8 *p = inp; + union { + u64 q[8]; + u8 c[64]; + } S, K, *H = (void *)ctx->H.q; + +#ifdef GO_FOR_MMX + GO_FOR_MMX(ctx, inp, n); +#endif + do { +#ifdef OPENSSL_SMALL_FOOTPRINT + u64 L[8]; + int i; + + for (i = 0; i < 64; i++) + S.c[i] = (K.c[i] = H->c[i]) ^ p[i]; + for (r = 0; r < ROUNDS; r++) { + for (i = 0; i < 8; i++) { + L[i] = i ? 0 : RC[r]; + L[i] ^= C0(K, i) ^ C1(K, (i - 1) & 7) ^ + C2(K, (i - 2) & 7) ^ C3(K, (i - 3) & 7) ^ + C4(K, (i - 4) & 7) ^ C5(K, (i - 5) & 7) ^ + C6(K, (i - 6) & 7) ^ C7(K, (i - 7) & 7); + } + memcpy(K.q, L, 64); + for (i = 0; i < 8; i++) { + L[i] ^= C0(S, i) ^ C1(S, (i - 1) & 7) ^ + C2(S, (i - 2) & 7) ^ C3(S, (i - 3) & 7) ^ + C4(S, (i - 4) & 7) ^ C5(S, (i - 5) & 7) ^ + C6(S, (i - 6) & 7) ^ C7(S, (i - 7) & 7); + } + memcpy(S.q, L, 64); + } + for (i = 0; i < 64; i++) + H->c[i] ^= S.c[i] ^ p[i]; +#else + u64 L0, L1, L2, L3, L4, L5, L6, L7; + +# ifdef STRICT_ALIGNMENT + if ((size_t)p & 7) { + memcpy(S.c, p, 64); + S.q[0] ^= (K.q[0] = H->q[0]); + S.q[1] ^= (K.q[1] = H->q[1]); + S.q[2] ^= (K.q[2] = H->q[2]); + S.q[3] ^= (K.q[3] = H->q[3]); + S.q[4] ^= (K.q[4] = H->q[4]); + S.q[5] ^= (K.q[5] = H->q[5]); + S.q[6] ^= (K.q[6] = H->q[6]); + S.q[7] ^= (K.q[7] = H->q[7]); + } else +# endif + { + const u64 *pa = (const u64 *)p; + S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; + S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; + S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; + S.q[3] = (K.q[3] = H->q[3]) ^ pa[3]; + S.q[4] = (K.q[4] = H->q[4]) ^ pa[4]; + S.q[5] = (K.q[5] = H->q[5]) ^ pa[5]; + S.q[6] = (K.q[6] = H->q[6]) ^ pa[6]; + S.q[7] = (K.q[7] = H->q[7]) ^ pa[7]; + } + + for (r = 0; r < ROUNDS; r++) { +# ifdef SMALL_REGISTER_BANK + L0 = C0(K, 0) ^ C1(K, 7) ^ C2(K, 6) ^ C3(K, 5) ^ + C4(K, 4) ^ C5(K, 3) ^ C6(K, 2) ^ C7(K, 1) ^ RC[r]; + L1 = C0(K, 1) ^ C1(K, 0) ^ C2(K, 7) ^ C3(K, 6) ^ + C4(K, 5) ^ C5(K, 4) ^ C6(K, 3) ^ C7(K, 2); + L2 = C0(K, 2) ^ C1(K, 1) ^ C2(K, 0) ^ C3(K, 7) ^ + C4(K, 6) ^ C5(K, 5) ^ C6(K, 4) ^ C7(K, 3); + L3 = C0(K, 3) ^ C1(K, 2) ^ C2(K, 1) ^ C3(K, 0) ^ + C4(K, 7) ^ C5(K, 6) ^ C6(K, 5) ^ C7(K, 4); + L4 = C0(K, 4) ^ C1(K, 3) ^ C2(K, 2) ^ C3(K, 1) ^ + C4(K, 0) ^ C5(K, 7) ^ C6(K, 6) ^ C7(K, 5); + L5 = C0(K, 5) ^ C1(K, 4) ^ C2(K, 3) ^ C3(K, 2) ^ + C4(K, 1) ^ C5(K, 0) ^ C6(K, 7) ^ C7(K, 6); + L6 = C0(K, 6) ^ C1(K, 5) ^ C2(K, 4) ^ C3(K, 3) ^ + C4(K, 2) ^ C5(K, 1) ^ C6(K, 0) ^ C7(K, 7); + L7 = C0(K, 7) ^ C1(K, 6) ^ C2(K, 5) ^ C3(K, 4) ^ + C4(K, 3) ^ C5(K, 2) ^ C6(K, 1) ^ C7(K, 0); + + K.q[0] = L0; + K.q[1] = L1; + K.q[2] = L2; + K.q[3] = L3; + K.q[4] = L4; + K.q[5] = L5; + K.q[6] = L6; + K.q[7] = L7; + + L0 ^= C0(S, 0) ^ C1(S, 7) ^ C2(S, 6) ^ C3(S, 5) ^ + C4(S, 4) ^ C5(S, 3) ^ C6(S, 2) ^ C7(S, 1); + L1 ^= C0(S, 1) ^ C1(S, 0) ^ C2(S, 7) ^ C3(S, 6) ^ + C4(S, 5) ^ C5(S, 4) ^ C6(S, 3) ^ C7(S, 2); + L2 ^= C0(S, 2) ^ C1(S, 1) ^ C2(S, 0) ^ C3(S, 7) ^ + C4(S, 6) ^ C5(S, 5) ^ C6(S, 4) ^ C7(S, 3); + L3 ^= C0(S, 3) ^ C1(S, 2) ^ C2(S, 1) ^ C3(S, 0) ^ + C4(S, 7) ^ C5(S, 6) ^ C6(S, 5) ^ C7(S, 4); + L4 ^= C0(S, 4) ^ C1(S, 3) ^ C2(S, 2) ^ C3(S, 1) ^ + C4(S, 0) ^ C5(S, 7) ^ C6(S, 6) ^ C7(S, 5); + L5 ^= C0(S, 5) ^ C1(S, 4) ^ C2(S, 3) ^ C3(S, 2) ^ + C4(S, 1) ^ C5(S, 0) ^ C6(S, 7) ^ C7(S, 6); + L6 ^= C0(S, 6) ^ C1(S, 5) ^ C2(S, 4) ^ C3(S, 3) ^ + C4(S, 2) ^ C5(S, 1) ^ C6(S, 0) ^ C7(S, 7); + L7 ^= C0(S, 7) ^ C1(S, 6) ^ C2(S, 5) ^ C3(S, 4) ^ + C4(S, 3) ^ C5(S, 2) ^ C6(S, 1) ^ C7(S, 0); + + S.q[0] = L0; + S.q[1] = L1; + S.q[2] = L2; + S.q[3] = L3; + S.q[4] = L4; + S.q[5] = L5; + S.q[6] = L6; + S.q[7] = L7; +# else + L0 = C0(K, 0); + L1 = C1(K, 0); + L2 = C2(K, 0); + L3 = C3(K, 0); + L4 = C4(K, 0); + L5 = C5(K, 0); + L6 = C6(K, 0); + L7 = C7(K, 0); + L0 ^= RC[r]; + + L1 ^= C0(K, 1); + L2 ^= C1(K, 1); + L3 ^= C2(K, 1); + L4 ^= C3(K, 1); + L5 ^= C4(K, 1); + L6 ^= C5(K, 1); + L7 ^= C6(K, 1); + L0 ^= C7(K, 1); + + L2 ^= C0(K, 2); + L3 ^= C1(K, 2); + L4 ^= C2(K, 2); + L5 ^= C3(K, 2); + L6 ^= C4(K, 2); + L7 ^= C5(K, 2); + L0 ^= C6(K, 2); + L1 ^= C7(K, 2); + + L3 ^= C0(K, 3); + L4 ^= C1(K, 3); + L5 ^= C2(K, 3); + L6 ^= C3(K, 3); + L7 ^= C4(K, 3); + L0 ^= C5(K, 3); + L1 ^= C6(K, 3); + L2 ^= C7(K, 3); + + L4 ^= C0(K, 4); + L5 ^= C1(K, 4); + L6 ^= C2(K, 4); + L7 ^= C3(K, 4); + L0 ^= C4(K, 4); + L1 ^= C5(K, 4); + L2 ^= C6(K, 4); + L3 ^= C7(K, 4); + + L5 ^= C0(K, 5); + L6 ^= C1(K, 5); + L7 ^= C2(K, 5); + L0 ^= C3(K, 5); + L1 ^= C4(K, 5); + L2 ^= C5(K, 5); + L3 ^= C6(K, 5); + L4 ^= C7(K, 5); + + L6 ^= C0(K, 6); + L7 ^= C1(K, 6); + L0 ^= C2(K, 6); + L1 ^= C3(K, 6); + L2 ^= C4(K, 6); + L3 ^= C5(K, 6); + L4 ^= C6(K, 6); + L5 ^= C7(K, 6); + + L7 ^= C0(K, 7); + L0 ^= C1(K, 7); + L1 ^= C2(K, 7); + L2 ^= C3(K, 7); + L3 ^= C4(K, 7); + L4 ^= C5(K, 7); + L5 ^= C6(K, 7); + L6 ^= C7(K, 7); + + K.q[0] = L0; + K.q[1] = L1; + K.q[2] = L2; + K.q[3] = L3; + K.q[4] = L4; + K.q[5] = L5; + K.q[6] = L6; + K.q[7] = L7; + + L0 ^= C0(S, 0); + L1 ^= C1(S, 0); + L2 ^= C2(S, 0); + L3 ^= C3(S, 0); + L4 ^= C4(S, 0); + L5 ^= C5(S, 0); + L6 ^= C6(S, 0); + L7 ^= C7(S, 0); + + L1 ^= C0(S, 1); + L2 ^= C1(S, 1); + L3 ^= C2(S, 1); + L4 ^= C3(S, 1); + L5 ^= C4(S, 1); + L6 ^= C5(S, 1); + L7 ^= C6(S, 1); + L0 ^= C7(S, 1); + + L2 ^= C0(S, 2); + L3 ^= C1(S, 2); + L4 ^= C2(S, 2); + L5 ^= C3(S, 2); + L6 ^= C4(S, 2); + L7 ^= C5(S, 2); + L0 ^= C6(S, 2); + L1 ^= C7(S, 2); + + L3 ^= C0(S, 3); + L4 ^= C1(S, 3); + L5 ^= C2(S, 3); + L6 ^= C3(S, 3); + L7 ^= C4(S, 3); + L0 ^= C5(S, 3); + L1 ^= C6(S, 3); + L2 ^= C7(S, 3); + + L4 ^= C0(S, 4); + L5 ^= C1(S, 4); + L6 ^= C2(S, 4); + L7 ^= C3(S, 4); + L0 ^= C4(S, 4); + L1 ^= C5(S, 4); + L2 ^= C6(S, 4); + L3 ^= C7(S, 4); + + L5 ^= C0(S, 5); + L6 ^= C1(S, 5); + L7 ^= C2(S, 5); + L0 ^= C3(S, 5); + L1 ^= C4(S, 5); + L2 ^= C5(S, 5); + L3 ^= C6(S, 5); + L4 ^= C7(S, 5); + + L6 ^= C0(S, 6); + L7 ^= C1(S, 6); + L0 ^= C2(S, 6); + L1 ^= C3(S, 6); + L2 ^= C4(S, 6); + L3 ^= C5(S, 6); + L4 ^= C6(S, 6); + L5 ^= C7(S, 6); + + L7 ^= C0(S, 7); + L0 ^= C1(S, 7); + L1 ^= C2(S, 7); + L2 ^= C3(S, 7); + L3 ^= C4(S, 7); + L4 ^= C5(S, 7); + L5 ^= C6(S, 7); + L6 ^= C7(S, 7); + + S.q[0] = L0; + S.q[1] = L1; + S.q[2] = L2; + S.q[3] = L3; + S.q[4] = L4; + S.q[5] = L5; + S.q[6] = L6; + S.q[7] = L7; +# endif + } + +# ifdef STRICT_ALIGNMENT + if ((size_t)p & 7) { + int i; + for (i = 0; i < 64; i++) + H->c[i] ^= S.c[i] ^ p[i]; + } else +# endif + { + const u64 *pa = (const u64 *)p; + H->q[0] ^= S.q[0] ^ pa[0]; + H->q[1] ^= S.q[1] ^ pa[1]; + H->q[2] ^= S.q[2] ^ pa[2]; + H->q[3] ^= S.q[3] ^ pa[3]; + H->q[4] ^= S.q[4] ^ pa[4]; + H->q[5] ^= S.q[5] ^ pa[5]; + H->q[6] ^= S.q[6] ^ pa[6]; + H->q[7] ^= S.q[7] ^ pa[7]; + } +#endif + p += 64; + } while (--n); +} +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * OpenSSL-specific implementation notes. + * + * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect + * number of *bytes* as input length argument. Bit-oriented routine + * as specified by authors is called WHIRLPOOL_BitUpdate[!] and + * does not have one-stroke counterpart. + * + * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially + * to serve WHIRLPOOL_Update. This is done for performance. + * + * Unlike authors' reference implementation, block processing + * routine whirlpool_block is designed to operate on multi-block + * input. This is done for perfomance. + */ + +#include "crypto.h" +// #include "wp_locl.h" +// #include "crypto.h" +#include + +fips_md_init(WHIRLPOOL) +{ + memset(c, 0, sizeof(*c)); + return (1); +} + +int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes) +{ + /* + * Well, largest suitable chunk size actually is + * (1<<(sizeof(size_t)*8-3))-64, but below number is large enough for not + * to care about excessive calls to WHIRLPOOL_BitUpdate... + */ + size_t chunk = ((size_t)1) << (sizeof(size_t) * 8 - 4); + const unsigned char *inp = _inp; + + while (bytes >= chunk) { + WHIRLPOOL_BitUpdate(c, inp, chunk * 8); + bytes -= chunk; + inp += chunk; + } + if (bytes) + WHIRLPOOL_BitUpdate(c, inp, bytes * 8); + + return (1); +} + +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) +{ + size_t n; + unsigned int bitoff = c->bitoff, + bitrem = bitoff % 8, inpgap = (8 - (unsigned int)bits % 8) & 7; + const unsigned char *inp = _inp; + + /* + * This 256-bit increment procedure relies on the size_t being natural + * size of CPU register, so that we don't have to mask the value in order + * to detect overflows. + */ + c->bitlen[0] += bits; + if (c->bitlen[0] < bits) { /* overflow */ + n = 1; + do { + c->bitlen[n]++; + } while (c->bitlen[n] == 0 + && ++n < (WHIRLPOOL_COUNTER / sizeof(size_t))); + } +#ifndef OPENSSL_SMALL_FOOTPRINT + reconsider: + if (inpgap == 0 && bitrem == 0) { /* byte-oriented loop */ + while (bits) { + if (bitoff == 0 && (n = bits / WHIRLPOOL_BBLOCK)) { + whirlpool_block(c, inp, n); + inp += n * WHIRLPOOL_BBLOCK / 8; + bits %= WHIRLPOOL_BBLOCK; + } else { + unsigned int byteoff = bitoff / 8; + + bitrem = WHIRLPOOL_BBLOCK - bitoff; /* re-use bitrem */ + if (bits >= bitrem) { + bits -= bitrem; + bitrem /= 8; + memcpy(c->data + byteoff, inp, bitrem); + inp += bitrem; + whirlpool_block(c, c->data, 1); + bitoff = 0; + } else { + memcpy(c->data + byteoff, inp, bits / 8); + bitoff += (unsigned int)bits; + bits = 0; + } + c->bitoff = bitoff; + } + } + } else /* bit-oriented loop */ +#endif + { + /*- + inp + | + +-------+-------+------- + ||||||||||||||||||||| + +-------+-------+------- + +-------+-------+-------+-------+------- + |||||||||||||| c->data + +-------+-------+-------+-------+------- + | + c->bitoff/8 + */ + while (bits) { + unsigned int byteoff = bitoff / 8; + unsigned char b; + +#ifndef OPENSSL_SMALL_FOOTPRINT + if (bitrem == inpgap) { + c->data[byteoff++] |= inp[0] & (0xff >> inpgap); + inpgap = 8 - inpgap; + bitoff += inpgap; + bitrem = 0; /* bitoff%8 */ + bits -= inpgap; + inpgap = 0; /* bits%8 */ + inp++; + if (bitoff == WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + bitoff = 0; + } + c->bitoff = bitoff; + goto reconsider; + } else +#endif + if (bits > 8) { + b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap))); + b &= 0xff; + if (bitrem) + c->data[byteoff++] |= b >> bitrem; + else + c->data[byteoff++] = b; + bitoff += 8; + bits -= 8; + inp++; + if (bitoff >= WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) + c->data[byteoff] = b << (8 - bitrem); + } else { /* remaining less than or equal to 8 bits */ + + b = (inp[0] << inpgap) & 0xff; + if (bitrem) + c->data[byteoff++] |= b >> bitrem; + else + c->data[byteoff++] = b; + bitoff += (unsigned int)bits; + if (bitoff == WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) + c->data[byteoff] = b << (8 - bitrem); + bits = 0; + } + c->bitoff = bitoff; + } + } +} + +int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c) +{ + unsigned int bitoff = c->bitoff, byteoff = bitoff / 8; + size_t i, j, v; + unsigned char *p; + + bitoff %= 8; + if (bitoff) + c->data[byteoff] |= 0x80 >> bitoff; + else + c->data[byteoff] = 0x80; + byteoff++; + + /* pad with zeros */ + if (byteoff > (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) { + if (byteoff < WHIRLPOOL_BBLOCK / 8) + memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK / 8 - byteoff); + whirlpool_block(c, c->data, 1); + byteoff = 0; + } + if (byteoff < (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) + memset(&c->data[byteoff], 0, + (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER) - byteoff); + /* smash 256-bit c->bitlen in big-endian order */ + p = &c->data[WHIRLPOOL_BBLOCK / 8 - 1]; /* last byte in c->data */ + for (i = 0; i < WHIRLPOOL_COUNTER / sizeof(size_t); i++) + for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8) + *p-- = (unsigned char)(v & 0xff); + + whirlpool_block(c, c->data, 1); + + if (md) { + memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH); + OPENSSL_cleanse(c, sizeof(*c)); + return (1); + } + return (0); +} + +unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md) +{ + WHIRLPOOL_CTX ctx; + static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + WHIRLPOOL_Init(&ctx); + WHIRLPOOL_Update(&ctx, inp, bytes); + WHIRLPOOL_Final(md, &ctx); + return (md); +} diff --git a/Sources/COpenSSL/wp_locl.h b/Sources/COpenSSL/wp_locl.h new file mode 100644 index 00000000..3017e2db --- /dev/null +++ b/Sources/COpenSSL/wp_locl.h @@ -0,0 +1,3 @@ +#include "whrlpool.h" + +void whirlpool_block(WHIRLPOOL_CTX *, const void *, size_t); diff --git a/Sources/COpenSSL/wrap128.c b/Sources/COpenSSL/wrap128.c new file mode 100644 index 00000000..8ed6da3d --- /dev/null +++ b/Sources/COpenSSL/wrap128.c @@ -0,0 +1,138 @@ +/* crypto/modes/wrap128.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include "modes.h" + +static const unsigned char default_iv[] = { + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, +}; + +/* + * Input size limit: lower than maximum of standards but far larger than + * anything that will be used in practice. + */ +#define CRYPTO128_WRAP_MAX (1UL << 31) + +size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block) +{ + unsigned char *A, B[16], *R; + size_t i, j, t; + if ((inlen & 0x7) || (inlen < 8) || (inlen > CRYPTO128_WRAP_MAX)) + return 0; + A = B; + t = 1; + memmove(out + 8, in, inlen); + if (!iv) + iv = default_iv; + + memcpy(A, iv, 8); + + for (j = 0; j < 6; j++) { + R = out + 8; + for (i = 0; i < inlen; i += 8, t++, R += 8) { + memcpy(B + 8, R, 8); + block(B, B, key); + A[7] ^= (unsigned char)(t & 0xff); + if (t > 0xff) { + A[6] ^= (unsigned char)((t >> 8) & 0xff); + A[5] ^= (unsigned char)((t >> 16) & 0xff); + A[4] ^= (unsigned char)((t >> 24) & 0xff); + } + memcpy(R, B + 8, 8); + } + } + memcpy(out, A, 8); + return inlen + 8; +} + +size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, size_t inlen, + block128_f block) +{ + unsigned char *A, B[16], *R; + size_t i, j, t; + inlen -= 8; + if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) + return 0; + A = B; + t = 6 * (inlen >> 3); + memcpy(A, in, 8); + memmove(out, in + 8, inlen); + for (j = 0; j < 6; j++) { + R = out + inlen - 8; + for (i = 0; i < inlen; i += 8, t--, R -= 8) { + A[7] ^= (unsigned char)(t & 0xff); + if (t > 0xff) { + A[6] ^= (unsigned char)((t >> 8) & 0xff); + A[5] ^= (unsigned char)((t >> 16) & 0xff); + A[4] ^= (unsigned char)((t >> 24) & 0xff); + } + memcpy(B + 8, R, 8); + block(B, B, key); + memcpy(R, B + 8, 8); + } + } + if (!iv) + iv = default_iv; + if (memcmp(A, iv, 8)) { + OPENSSL_cleanse(out, inlen); + return 0; + } + return inlen; +} diff --git a/Sources/COpenSSL/x509.h b/Sources/COpenSSL/x509.h new file mode 100644 index 00000000..46eda8fa --- /dev/null +++ b/Sources/COpenSSL/x509.h @@ -0,0 +1,1330 @@ +/* crypto/x509/x509.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_X509_H +# define HEADER_X509_H + +# include "e_os2.h" +# include "symhacks.h" +# ifndef OPENSSL_NO_BUFFER +# include "buffer.h" +# endif +# ifndef OPENSSL_NO_EVP +# include "evp.h" +# endif +# ifndef OPENSSL_NO_BIO +# include "bio.h" +# endif +# include "stack.h" +# include "asn1.h" +# include "safestack.h" + +# ifndef OPENSSL_NO_EC +# include "ec.h" +# endif + +# ifndef OPENSSL_NO_ECDSA +# include "ecdsa.h" +# endif + +# ifndef OPENSSL_NO_ECDH +# include "ecdh.h" +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# ifndef OPENSSL_NO_RSA +# include "rsa.h" +# endif +# ifndef OPENSSL_NO_DSA +# include "dsa.h" +# endif +# ifndef OPENSSL_NO_DH +# include "dh.h" +# endif +# endif + +# ifndef OPENSSL_NO_SHA +# include "sha.h" +# endif +# include "ossl_typ.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_SYS_WIN32 +/* Under Win32 these are defined in wincrypt.h */ +# undef X509_NAME +# undef X509_CERT_PAIR +# undef X509_EXTENSIONS +# endif + +# define X509_FILETYPE_PEM 1 +# define X509_FILETYPE_ASN1 2 +# define X509_FILETYPE_DEFAULT 3 + +# define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +# define X509v3_KU_NON_REPUDIATION 0x0040 +# define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +# define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +# define X509v3_KU_KEY_AGREEMENT 0x0008 +# define X509v3_KU_KEY_CERT_SIGN 0x0004 +# define X509v3_KU_CRL_SIGN 0x0002 +# define X509v3_KU_ENCIPHER_ONLY 0x0001 +# define X509v3_KU_DECIPHER_ONLY 0x8000 +# define X509v3_KU_UNDEF 0xffff + +typedef struct X509_objects_st { + int nid; + int (*a2i) (void); + int (*i2a) (void); +} X509_OBJECTS; + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */ ; + +DECLARE_ASN1_SET_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +struct X509_pubkey_st { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; +}; + +typedef struct X509_sig_st { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; +} X509_SIG; + +typedef struct X509_name_entry_st { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ +} X509_NAME_ENTRY; + +DECLARE_STACK_OF(X509_NAME_ENTRY) +DECLARE_ASN1_SET_OF(X509_NAME_ENTRY) + +/* we always keep X509_NAMEs in 2 forms. */ +struct X509_name_st { + STACK_OF(X509_NAME_ENTRY) *entries; + int modified; /* true if 'bytes' needs to be built */ +# ifndef OPENSSL_NO_BUFFER + BUF_MEM *bytes; +# else + char *bytes; +# endif +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; +} /* X509_NAME */ ; + +DECLARE_STACK_OF(X509_NAME) + +# define X509_EX_V_NETSCAPE_HACK 0x8000 +# define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; +} X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DECLARE_STACK_OF(X509_EXTENSION) +DECLARE_ASN1_SET_OF(X509_EXTENSION) + +/* a sequence of these are used */ +typedef struct x509_attributes_st { + ASN1_OBJECT *object; + int single; /* 0 for a set, 1 for a single item (which is + * wrong) */ + union { + char *ptr; + /* + * 0 + */ STACK_OF(ASN1_TYPE) *set; + /* + * 1 + */ ASN1_TYPE *single; + } value; +} X509_ATTRIBUTE; + +DECLARE_STACK_OF(X509_ATTRIBUTE) +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) + +typedef struct X509_req_info_st { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + X509_PUBKEY *pubkey; + /* d=2 hl=2 l= 0 cons: cont: 00 */ + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} X509_REQ_INFO; + +typedef struct X509_req_st { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; +} X509_REQ; + +typedef struct x509_cinf_st { + ASN1_INTEGER *version; /* [ 0 ] default of v1 */ + ASN1_INTEGER *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + X509_PUBKEY *key; + ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */ + ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */ + STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */ + ASN1_ENCODING enc; +} X509_CINF; + +/* + * This stuff is certificate "auxiliary info" it contains details which are + * useful in certificate stores and databases. When used this is tagged onto + * the end of the certificate itself + */ + +typedef struct x509_cert_aux_st { + STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */ + STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */ + ASN1_UTF8STRING *alias; /* "friendly name" */ + ASN1_OCTET_STRING *keyid; /* key id of private key */ + STACK_OF(X509_ALGOR) *other; /* other unspecified info */ +} X509_CERT_AUX; + +struct x509_st { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int valid; + int references; + char *name; + CRYPTO_EX_DATA ex_data; + /* These contain copies of various extension values */ + long ex_pathlen; + long ex_pcpathlen; + unsigned long ex_flags; + unsigned long ex_kusage; + unsigned long ex_xkusage; + unsigned long ex_nscert; + ASN1_OCTET_STRING *skid; + AUTHORITY_KEYID *akid; + X509_POLICY_CACHE *policy_cache; + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; +# ifndef OPENSSL_NO_RFC3779 + STACK_OF(IPAddressFamily) *rfc3779_addr; + struct ASIdentifiers_st *rfc3779_asid; +# endif +# ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +# endif + X509_CERT_AUX *aux; +} /* X509 */ ; + +DECLARE_STACK_OF(X509) +DECLARE_ASN1_SET_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust) (struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DECLARE_STACK_OF(X509_TRUST) + +typedef struct x509_cert_pair_st { + X509 *forward; + X509 *reverse; +} X509_CERT_PAIR; + +/* standard trust ids */ + +# define X509_TRUST_DEFAULT -1/* Only valid in purpose settings */ + +# define X509_TRUST_COMPAT 1 +# define X509_TRUST_SSL_CLIENT 2 +# define X509_TRUST_SSL_SERVER 3 +# define X509_TRUST_EMAIL 4 +# define X509_TRUST_OBJECT_SIGN 5 +# define X509_TRUST_OCSP_SIGN 6 +# define X509_TRUST_OCSP_REQUEST 7 +# define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +# define X509_TRUST_MIN 1 +# define X509_TRUST_MAX 8 + +/* trust_flags values */ +# define X509_TRUST_DYNAMIC 1 +# define X509_TRUST_DYNAMIC_NAME 2 + +/* check_trust return codes */ + +# define X509_TRUST_TRUSTED 1 +# define X509_TRUST_REJECTED 2 +# define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +# define X509_FLAG_COMPAT 0 +# define X509_FLAG_NO_HEADER 1L +# define X509_FLAG_NO_VERSION (1L << 1) +# define X509_FLAG_NO_SERIAL (1L << 2) +# define X509_FLAG_NO_SIGNAME (1L << 3) +# define X509_FLAG_NO_ISSUER (1L << 4) +# define X509_FLAG_NO_VALIDITY (1L << 5) +# define X509_FLAG_NO_SUBJECT (1L << 6) +# define X509_FLAG_NO_PUBKEY (1L << 7) +# define X509_FLAG_NO_EXTENSIONS (1L << 8) +# define X509_FLAG_NO_SIGDUMP (1L << 9) +# define X509_FLAG_NO_AUX (1L << 10) +# define X509_FLAG_NO_ATTRIBUTES (1L << 11) +# define X509_FLAG_NO_IDS (1L << 12) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +# define XN_FLAG_SEP_MASK (0xf << 16) + +# define XN_FLAG_COMPAT 0/* Traditional SSLeay: use old + * X509_NAME_print */ +# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */ +# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */ +# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */ +# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */ + +# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */ + +/* How the field name is shown */ + +# define XN_FLAG_FN_MASK (0x3 << 21) + +# define XN_FLAG_FN_SN 0/* Object short name */ +# define XN_FLAG_FN_LN (1 << 21)/* Object long name */ +# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */ +# define XN_FLAG_FN_NONE (3 << 21)/* No field names */ + +# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */ + +/* + * This determines if we dump fields we don't recognise: RFC2253 requires + * this. + */ + +# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20 + * characters */ + +/* Complete set of RFC2253 flags */ + +# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +struct x509_revoked_st { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + /* Set up if indirect CRL */ + STACK_OF(GENERAL_NAME) *issuer; + /* Revocation reason */ + int reason; + int sequence; /* load sequence */ +}; + +DECLARE_STACK_OF(X509_REVOKED) +DECLARE_ASN1_SET_OF(X509_REVOKED) + +typedef struct X509_crl_info_st { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + STACK_OF(X509_REVOKED) *revoked; + STACK_OF(X509_EXTENSION) /* [0] */ *extensions; + ASN1_ENCODING enc; +} X509_CRL_INFO; + +struct X509_crl_st { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + int flags; + /* Copies of various extensions */ + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; + /* Convenient breakdown of IDP */ + int idp_flags; + int idp_reasons; + /* CRL and base CRL numbers for delta processing */ + ASN1_INTEGER *crl_number; + ASN1_INTEGER *base_crl_number; +# ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +# endif + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; +} /* X509_CRL */ ; + +DECLARE_STACK_OF(X509_CRL) +DECLARE_ASN1_SET_OF(X509_CRL) + +typedef struct private_key_st { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; + int references; +} X509_PKEY; + +# ifndef OPENSSL_NO_EVP +typedef struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + int references; +} X509_INFO; + +DECLARE_STACK_OF(X509_INFO) +# endif + +/* + * The next 2 structures and their 8 routines were sent to me by Pat Richard + * and are used to manipulate Netscapes spki structures - + * useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ +} NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; +} NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; +} NETSCAPE_CERT_SEQUENCE; + +/*- Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { + X509_ALGOR *keyfunc; + X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +/* Usually OCTET STRING but could be anything */ + ASN1_TYPE *salt; + ASN1_INTEGER *iter; + ASN1_INTEGER *keylength; + X509_ALGOR *prf; +} PBKDF2PARAM; + +/* PKCS#8 private key info structure */ + +struct pkcs8_priv_key_info_st { + /* Flag for various broken formats */ + int broken; +# define PKCS8_OK 0 +# define PKCS8_NO_OCTET 1 +# define PKCS8_EMBEDDED_PARAM 2 +# define PKCS8_NS_DB 3 +# define PKCS8_NEG_PRIVKEY 4 + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + /* Should be OCTET STRING but some are broken */ + ASN1_TYPE *pkey; + STACK_OF(X509_ATTRIBUTE) *attributes; +}; + +#ifdef __cplusplus +} +#endif + +# include "x509_vfy.h" +# include "pkcs7.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# define X509_EXT_PACK_UNKNOWN 1 +# define X509_EXT_PACK_STRING 2 + +# define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version) +/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */ +# define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore) +# define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter) +# define X509_extract_key(x) X509_get_pubkey(x)/*****/ +# define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version) +# define X509_REQ_get_subject_name(x) ((x)->req_info->subject) +# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) +# define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm)) + +# define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version) +# define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate) +# define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate) +# define X509_CRL_get_issuer(x) ((x)->crl->issuer) +# define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +/* + * This one is only used so that a binary form can output, as in + * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) + */ +# define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) + +const char *X509_verify_cert_error_string(long n); + +# ifndef OPENSSL_NO_EVP +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len); +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +# endif + +# ifndef OPENSSL_NO_FP_API +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp, X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +# endif + +# ifndef OPENSSL_NO_BIO +X509 *d2i_X509_bio(BIO *bp, X509 **x509); +int i2d_X509_bio(BIO *bp, X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +# endif + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, + void *pval); +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char *X509_get_default_cert_area(void); +const char *X509_get_default_cert_dir(void); +const char *X509_get_default_cert_file(void); +const char *X509_get_default_cert_dir_env(void); +const char *X509_get_default_cert_file_env(void); +const char *X509_get_default_private_dir(void); + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp); +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); +# ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp); +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); +# endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR) + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a, unsigned char **pp); +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length); + +int i2d_re_X509_tbs(X509 *x, unsigned char **pp); + +void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, + const X509 *x); +int X509_get_signature_nid(const X509 *x); + +int X509_alias_set1(X509 *x, unsigned char *name, int len); +int X509_keyid_set1(X509 *x, unsigned char *id, int len); +unsigned char *X509_alias_get0(X509 *x, int *len); +unsigned char *X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY *X509_PKEY_new(void); +void X509_PKEY_free(X509_PKEY *a); +int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp); +X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +# ifndef OPENSSL_NO_EVP +X509_INFO *X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char *X509_NAME_oneline(X509_NAME *a, char *buf, int size); + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey); + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey, const EVP_MD *type); + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, + unsigned char *md, unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + void *asn, EVP_MD_CTX *ctx); +# endif + +int X509_set_version(X509 *x, long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER *X509_get_serialNumber(X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_issuer_name(X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_subject_name(X509 *a); +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +EVP_PKEY *X509_get_pubkey(X509 *x); +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ ); + +int X509_REQ_set_version(X509_REQ *x, long version); +int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int *X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); + +int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +int X509_check_private_key(X509 *x509, EVP_PKEY *pkey); +int X509_chain_check_suiteb(int *perror_depth, + X509 *x, STACK_OF(X509) *chain, + unsigned long flags); +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +# ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +# endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +# ifndef OPENSSL_NO_FP_API +int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print_fp(FILE *bp, X509 *x); +int X509_CRL_print_fp(FILE *bp, X509_CRL *x); +int X509_REQ_print_fp(FILE *bp, X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, + unsigned long flags); +# endif + +# ifndef OPENSSL_NO_BIO +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, + unsigned long flags); +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print(BIO *bp, X509 *x); +int X509_ocspid_print(BIO *bp, X509 *x); +int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent); +int X509_CRL_print(BIO *bp, X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); +int X509_REQ_print(BIO *bp, X509_REQ *req); +# endif + +int X509_NAME_entry_count(X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + char *buf, int len); + +/* + * NOTE: you should be passsing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. + */ +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, + int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, unsigned char *bytes, + int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + ASN1_OBJECT *obj, int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(X509 *x); +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos); +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(X509_CRL *x); +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos); +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, + int lastpos); +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, + ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj, + int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, + void *data); +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST *X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(X509_TRUST *xp); +char *X509_TRUST_get0_name(X509_TRUST *xp); +int X509_TRUST_get_trust(X509_TRUST *xp); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +void ERR_load_X509_strings(void); + +/* Error codes for the X509 functions. */ + +/* Function codes. */ +# define X509_F_ADD_CERT_DIR 100 +# define X509_F_BY_FILE_CTRL 101 +# define X509_F_CHECK_NAME_CONSTRAINTS 106 +# define X509_F_CHECK_POLICY 145 +# define X509_F_DIR_CTRL 102 +# define X509_F_GET_CERT_BY_SUBJECT 103 +# define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +# define X509_F_X509AT_ADD1_ATTR 135 +# define X509_F_X509V3_ADD_EXT 104 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +# define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +# define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +# define X509_F_X509_CHECK_PRIVATE_KEY 128 +# define X509_F_X509_CRL_DIFF 105 +# define X509_F_X509_CRL_PRINT_FP 147 +# define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +# define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +# define X509_F_X509_LOAD_CERT_CRL_FILE 132 +# define X509_F_X509_LOAD_CERT_FILE 111 +# define X509_F_X509_LOAD_CRL_FILE 112 +# define X509_F_X509_NAME_ADD_ENTRY 113 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +# define X509_F_X509_NAME_ONELINE 116 +# define X509_F_X509_NAME_PRINT 117 +# define X509_F_X509_PRINT_EX_FP 118 +# define X509_F_X509_PUBKEY_GET 119 +# define X509_F_X509_PUBKEY_SET 120 +# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +# define X509_F_X509_REQ_PRINT_EX 121 +# define X509_F_X509_REQ_PRINT_FP 122 +# define X509_F_X509_REQ_TO_X509 123 +# define X509_F_X509_STORE_ADD_CERT 124 +# define X509_F_X509_STORE_ADD_CRL 125 +# define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +# define X509_F_X509_STORE_CTX_INIT 143 +# define X509_F_X509_STORE_CTX_NEW 142 +# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +# define X509_F_X509_TO_X509_REQ 126 +# define X509_F_X509_TRUST_ADD 133 +# define X509_F_X509_TRUST_SET 141 +# define X509_F_X509_VERIFY_CERT 127 + +/* Reason codes. */ +# define X509_R_AKID_MISMATCH 110 +# define X509_R_BAD_X509_FILETYPE 100 +# define X509_R_BASE64_DECODE_ERROR 118 +# define X509_R_CANT_CHECK_DH_KEY 114 +# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +# define X509_R_CRL_ALREADY_DELTA 127 +# define X509_R_CRL_VERIFY_FAILURE 131 +# define X509_R_ERR_ASN1_LIB 102 +# define X509_R_IDP_MISMATCH 128 +# define X509_R_INVALID_DIRECTORY 113 +# define X509_R_INVALID_FIELD_NAME 119 +# define X509_R_INVALID_TRUST 123 +# define X509_R_ISSUER_MISMATCH 129 +# define X509_R_KEY_TYPE_MISMATCH 115 +# define X509_R_KEY_VALUES_MISMATCH 116 +# define X509_R_LOADING_CERT_DIR 103 +# define X509_R_LOADING_DEFAULTS 104 +# define X509_R_METHOD_NOT_SUPPORTED 124 +# define X509_R_NAME_TOO_LONG 134 +# define X509_R_NEWER_CRL_NOT_NEWER 132 +# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +# define X509_R_NO_CRL_NUMBER 130 +# define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +# define X509_R_SHOULD_RETRY 106 +# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +# define X509_R_UNKNOWN_KEY_TYPE 117 +# define X509_R_UNKNOWN_NID 109 +# define X509_R_UNKNOWN_PURPOSE_ID 121 +# define X509_R_UNKNOWN_TRUST_ID 120 +# define X509_R_UNSUPPORTED_ALGORITHM 111 +# define X509_R_WRONG_LOOKUP_TYPE 112 +# define X509_R_WRONG_TYPE 122 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/Sources/COpenSSL/x509_.c b/Sources/COpenSSL/x509_.c new file mode 100644 index 00000000..c7183957 --- /dev/null +++ b/Sources/COpenSSL/x509_.c @@ -0,0 +1,7117 @@ +/* crypto/x509/x509_att.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "stack.h" +#include "cryptlib.h" +#include "asn1.h" +#include "objects.h" +#include "evp.h" +#include "x509.h" +#include "x509v3.h" + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) +{ + return sk_X509_ATTRIBUTE_num(x); +} + +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509at_get_attr_by_OBJ(x, obj, lastpos)); +} + +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_ATTRIBUTE *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_ATTRIBUTE_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_ATTRIBUTE_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_ATTRIBUTE_value(x, loc); +} + +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + X509_ATTRIBUTE *ret; + + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return (NULL); + ret = sk_X509_ATTRIBUTE_delete(x, loc); + return (ret); +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr) +{ + X509_ATTRIBUTE *new_attr = NULL; + STACK_OF(X509_ATTRIBUTE) *sk = NULL; + + if (x == NULL) { + X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) { + if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) + goto err; + } else + sk = *x; + + if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) + goto err2; + if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + err: + X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE); + err2: + if (new_attr != NULL) + X509_ATTRIBUTE_free(new_attr); + if (sk != NULL) + sk_X509_ATTRIBUTE_free(sk); + return (NULL); +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + ASN1_OBJECT *obj, int lastpos, int type) +{ + int i; + X509_ATTRIBUTE *at; + i = X509at_get_attr_by_OBJ(x, obj, lastpos); + if (i == -1) + return NULL; + if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) + return NULL; + at = X509at_get_attr(x, i); + if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) + return NULL; + return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); + if (ret == NULL) + ASN1_OBJECT_free(obj); + return (ret); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len) +{ + X509_ATTRIBUTE *ret; + + if ((attr == NULL) || (*attr == NULL)) { + if ((ret = X509_ATTRIBUTE_new()) == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, + ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret = *attr; + + if (!X509_ATTRIBUTE_set1_object(ret, obj)) + goto err; + if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len)) + goto err; + + if ((attr != NULL) && (*attr == NULL)) + *attr = ret; + return (ret); + err: + if ((attr == NULL) || (ret != *attr)) + X509_ATTRIBUTE_free(ret); + return (NULL); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *nattr; + + obj = OBJ_txt2obj(atrname, 0); + if (obj == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, + X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", atrname); + return (NULL); + } + nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nattr; +} + +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) +{ + if ((attr == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(attr->object); + attr->object = OBJ_dup(obj); + return (1); +} + +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len) +{ + ASN1_TYPE *ttmp = NULL; + ASN1_STRING *stmp = NULL; + int atype = 0; + if (!attr) + return 0; + if (attrtype & MBSTRING_FLAG) { + stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, + OBJ_obj2nid(attr->object)); + if (!stmp) { + X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB); + return 0; + } + atype = stmp->type; + } else if (len != -1) { + if (!(stmp = ASN1_STRING_type_new(attrtype))) + goto err; + if (!ASN1_STRING_set(stmp, data, len)) + goto err; + atype = attrtype; + } + if (!(attr->value.set = sk_ASN1_TYPE_new_null())) + goto err; + attr->single = 0; + /* + * This is a bit naughty because the attribute should really have at + * least one value but some types use and zero length SET and require + * this. + */ + if (attrtype == 0) { + ASN1_STRING_free(stmp); + return 1; + } + if (!(ttmp = ASN1_TYPE_new())) + goto err; + if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { + if (!ASN1_TYPE_set1(ttmp, attrtype, data)) + goto err; + } else { + ASN1_TYPE_set(ttmp, atype, stmp); + stmp = NULL; + } + if (!sk_ASN1_TYPE_push(attr->value.set, ttmp)) + goto err; + return 1; + err: + X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); + ASN1_TYPE_free(ttmp); + ASN1_STRING_free(stmp); + return 0; +} + +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr) +{ + if (!attr->single) + return sk_ASN1_TYPE_num(attr->value.set); + if (attr->value.single) + return 1; + return 0; +} + +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) +{ + if (attr == NULL) + return (NULL); + return (attr->object); +} + +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data) +{ + ASN1_TYPE *ttmp; + ttmp = X509_ATTRIBUTE_get0_type(attr, idx); + if (!ttmp) + return NULL; + if (atrtype != ASN1_TYPE_get(ttmp)) { + X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE); + return NULL; + } + return ttmp->value.ptr; +} + +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) +{ + if (attr == NULL) + return (NULL); + if (idx >= X509_ATTRIBUTE_count(attr)) + return NULL; + if (!attr->single) + return sk_ASN1_TYPE_value(attr->value.set, idx); + else + return attr->value.single; +} +/* crypto/x509/x509_cmp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "objects.h" +// #include "x509.h" +// #include "x509v3.h" + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) +{ + int i; + X509_CINF *ai, *bi; + + ai = a->cert_info; + bi = b->cert_info; + i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber); + if (i) + return (i); + return (X509_NAME_cmp(ai->issuer, bi->issuer)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_and_serial_hash(X509 *a) +{ + unsigned long ret = 0; + EVP_MD_CTX ctx; + unsigned char md[16]; + char *f; + + EVP_MD_CTX_init(&ctx); + f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0); + if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f))) + goto err; + OPENSSL_free(f); + if (!EVP_DigestUpdate + (&ctx, (unsigned char *)a->cert_info->serialNumber->data, + (unsigned long)a->cert_info->serialNumber->length)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL)) + goto err; + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + err: + EVP_MD_CTX_cleanup(&ctx); + return (ret); +} +#endif + +int X509_issuer_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); +} + +int X509_subject_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); +} + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) +{ + return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); +} + +#ifndef OPENSSL_NO_SHA +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) +{ + return memcmp(a->sha1_hash, b->sha1_hash, 20); +} +#endif + +X509_NAME *X509_get_issuer_name(X509 *a) +{ + return (a->cert_info->issuer); +} + +unsigned long X509_issuer_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->issuer)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->issuer)); +} +#endif + +X509_NAME *X509_get_subject_name(X509 *a) +{ + return (a->cert_info->subject); +} + +ASN1_INTEGER *X509_get_serialNumber(X509 *a) +{ + return (a->cert_info->serialNumber); +} + +unsigned long X509_subject_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->subject)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_subject_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->subject)); +} +#endif + +#ifndef OPENSSL_NO_SHA +/* + * Compare two certificates: they must be identical for this to work. NB: + * Although "cmp" operations are generally prototyped to take "const" + * arguments (eg. for use in STACKs), the way X509 handling is - these + * operations may involve ensuring the hashes are up-to-date and ensuring + * certain cert information is cached. So this is the point where the + * "depth-first" constification tree has to halt with an evil cast. + */ +int X509_cmp(const X509 *a, const X509 *b) +{ + int rv; + /* ensure hash is valid */ + X509_check_purpose((X509 *)a, -1, 0); + X509_check_purpose((X509 *)b, -1, 0); + + rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); + if (rv) + return rv; + /* Check for match against stored encoding too */ + if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) { + rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len); + if (rv) + return rv; + return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc, + a->cert_info->enc.len); + } + return rv; +} +#endif + +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) +{ + int ret; + + /* Ensure canonical encoding is present and up to date */ + + if (!a->canon_enc || a->modified) { + ret = i2d_X509_NAME((X509_NAME *)a, NULL); + if (ret < 0) + return -2; + } + + if (!b->canon_enc || b->modified) { + ret = i2d_X509_NAME((X509_NAME *)b, NULL); + if (ret < 0) + return -2; + } + + ret = a->canon_enclen - b->canon_enclen; + + if (ret != 0 || a->canon_enclen == 0) + return ret; + + return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); + +} + +unsigned long X509_NAME_hash(X509_NAME *x) +{ + unsigned long ret = 0; + unsigned char md[SHA_DIGEST_LENGTH]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), + NULL)) + return 0; + + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + return (ret); +} + +#ifndef OPENSSL_NO_MD5 +/* + * I now DER encode the name and hash it. Since I cache the DER encoding, + * this is reasonably efficient. + */ + +unsigned long X509_NAME_hash_old(X509_NAME *x) +{ + EVP_MD_CTX md_ctx; + unsigned long ret = 0; + unsigned char md[16]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + EVP_MD_CTX_init(&md_ctx); + EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) + && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) + && EVP_DigestFinal_ex(&md_ctx, md, NULL)) + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + EVP_MD_CTX_cleanup(&md_ctx); + + return (ret); +} +#endif + +/* Search a stack of X509 for a match */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial) +{ + int i; + X509_CINF cinf; + X509 x, *x509 = NULL; + + if (!sk) + return NULL; + + x.cert_info = &cinf; + cinf.serialNumber = serial; + cinf.issuer = name; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_issuer_and_serial_cmp(x509, &x) == 0) + return (x509); + } + return (NULL); +} + +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) +{ + X509 *x509; + int i; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) + return (x509); + } + return (NULL); +} + +EVP_PKEY *X509_get_pubkey(X509 *x) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->cert_info->key)); +} + +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) +{ + if (!x) + return NULL; + return x->cert_info->key->public_key; +} + +int X509_check_private_key(X509 *x, EVP_PKEY *k) +{ + EVP_PKEY *xk; + int ret; + + xk = X509_get_pubkey(x); + + if (xk) + ret = EVP_PKEY_cmp(xk, k); + else + ret = -2; + + switch (ret) { + case 1: + break; + case 0: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); + } + if (xk) + EVP_PKEY_free(xk); + if (ret > 0) + return 1; + return 0; +} + +/* + * Check a suite B algorithm is permitted: pass in a public key and the NID + * of its signature (or 0 if no signature). The pflags is a pointer to a + * flags field which must contain the suite B verification flags. + */ + +#ifndef OPENSSL_NO_EC + +static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) +{ + const EC_GROUP *grp = NULL; + int curve_nid; + if (pkey && pkey->type == EVP_PKEY_EC) + grp = EC_KEY_get0_group(pkey->pkey.ec); + if (!grp) + return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; + curve_nid = EC_GROUP_get_curve_name(grp); + /* Check curve is consistent with LOS */ + if (curve_nid == NID_secp384r1) { /* P-384 */ + /* + * Check signature algorithm is consistent with curve. + */ + if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384) + return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; + if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS)) + return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; + /* If we encounter P-384 we cannot use P-256 later */ + *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY; + } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */ + if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256) + return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; + if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) + return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; + } else + return X509_V_ERR_SUITE_B_INVALID_CURVE; + + return X509_V_OK; +} + +int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, + unsigned long flags) +{ + int rv, i, sign_nid; + EVP_PKEY *pk = NULL; + unsigned long tflags; + if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) + return X509_V_OK; + tflags = flags; + /* If no EE certificate passed in must be first in chain */ + if (x == NULL) { + x = sk_X509_value(chain, 0); + i = 1; + } else + i = 0; + + if (X509_get_version(x) != 2) { + rv = X509_V_ERR_SUITE_B_INVALID_VERSION; + /* Correct error depth */ + i = 0; + goto end; + } + + pk = X509_get_pubkey(x); + /* Check EE key only */ + rv = check_suite_b(pk, -1, &tflags); + if (rv != X509_V_OK) { + /* Correct error depth */ + i = 0; + goto end; + } + for (; i < sk_X509_num(chain); i++) { + sign_nid = X509_get_signature_nid(x); + x = sk_X509_value(chain, i); + if (X509_get_version(x) != 2) { + rv = X509_V_ERR_SUITE_B_INVALID_VERSION; + goto end; + } + EVP_PKEY_free(pk); + pk = X509_get_pubkey(x); + rv = check_suite_b(pk, sign_nid, &tflags); + if (rv != X509_V_OK) + goto end; + } + + /* Final check: root CA signature */ + rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags); + end: + if (pk) + EVP_PKEY_free(pk); + if (rv != X509_V_OK) { + /* Invalid signature or LOS errors are for previous cert */ + if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM + || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i) + i--; + /* + * If we have LOS error and flags changed then we are signing P-384 + * with P-256. Use more meaninggul error. + */ + if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags) + rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; + if (perror_depth) + *perror_depth = i; + } + return rv; +} + +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) +{ + int sign_nid; + if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) + return X509_V_OK; + sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm); + return check_suite_b(pk, sign_nid, &flags); +} + +#else +int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, + unsigned long flags) +{ + return 0; +} + +int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) +{ + return 0; +} + +#endif +/* + * Not strictly speaking an "up_ref" as a STACK doesn't have a reference + * count but it has the same effect by duping the STACK and upping the ref of + * each X509 structure. + */ +STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) +{ + STACK_OF(X509) *ret; + int i; + ret = sk_X509_dup(chain); + for (i = 0; i < sk_X509_num(ret); i++) { + X509 *x = sk_X509_value(ret, i); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + } + return ret; +} +/* crypto/x509/x509_d2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "crypto.h" +// #include "x509.h" + +#ifndef OPENSSL_NO_STDIO +int X509_STORE_set_default_paths(X509_STORE *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* clear any errors */ + ERR_clear_error(); + + return (1); +} + +int X509_STORE_load_locations(X509_STORE *ctx, const char *file, + const char *path) +{ + X509_LOOKUP *lookup; + + if (file != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) + return (0); + } + if (path != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) + return (0); + } + if ((path == NULL) && (file == NULL)) + return (0); + return (1); +} + +#endif +/* crypto/x509/x509_def.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "crypto.h" +// #include "x509.h" + +const char *X509_get_default_private_dir(void) +{ + return (X509_PRIVATE_DIR); +} + +const char *X509_get_default_cert_area(void) +{ + return (X509_CERT_AREA); +} + +const char *X509_get_default_cert_dir(void) +{ + return (X509_CERT_DIR); +} + +const char *X509_get_default_cert_file(void) +{ + return (X509_CERT_FILE); +} + +const char *X509_get_default_cert_dir_env(void) +{ + return (X509_CERT_DIR_EVP); +} + +const char *X509_get_default_cert_file_env(void) +{ + return (X509_CERT_FILE_EVP); +} +/* crypto/x509/x509_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include "err.h" +// #include "x509.h" + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason) + +static ERR_STRING_DATA X509_str_functs[] = { + {ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"}, + {ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"}, + {ERR_FUNC(X509_F_CHECK_NAME_CONSTRAINTS), "CHECK_NAME_CONSTRAINTS"}, + {ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"}, + {ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"}, + {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"}, + {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"}, + {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"}, + {ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"}, + {ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID), + "X509_ATTRIBUTE_create_by_NID"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ), + "X509_ATTRIBUTE_create_by_OBJ"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT), + "X509_ATTRIBUTE_create_by_txt"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"}, + {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"}, + {ERR_FUNC(X509_F_X509_CRL_DIFF), "X509_CRL_diff"}, + {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"}, + {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID), + "X509_EXTENSION_create_by_NID"}, + {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ), + "X509_EXTENSION_create_by_OBJ"}, + {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS), + "X509_get_pubkey_parameters"}, + {ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"}, + {ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"}, + {ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"}, + {ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID), + "X509_NAME_ENTRY_create_by_NID"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT), + "X509_NAME_ENTRY_create_by_txt"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT), + "X509_NAME_ENTRY_set_object"}, + {ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"}, + {ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"}, + {ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"}, + {ERR_FUNC(X509_F_X509_PUBKEY_GET), "X509_PUBKEY_get"}, + {ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"}, + {ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY), + "X509_REQ_check_private_key"}, + {ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"}, + {ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"}, + {ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"}, + {ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"}, + {ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER), + "X509_STORE_CTX_get1_issuer"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT), + "X509_STORE_CTX_purpose_inherit"}, + {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"}, + {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"}, + {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"}, + {ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"}, + {0, NULL} +}; + +static ERR_STRING_DATA X509_str_reasons[] = { + {ERR_REASON(X509_R_AKID_MISMATCH), "akid mismatch"}, + {ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"}, + {ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"}, + {ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"}, + {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE), + "cert already in hash table"}, + {ERR_REASON(X509_R_CRL_ALREADY_DELTA), "crl already delta"}, + {ERR_REASON(X509_R_CRL_VERIFY_FAILURE), "crl verify failure"}, + {ERR_REASON(X509_R_ERR_ASN1_LIB), "err asn1 lib"}, + {ERR_REASON(X509_R_IDP_MISMATCH), "idp mismatch"}, + {ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"}, + {ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"}, + {ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"}, + {ERR_REASON(X509_R_ISSUER_MISMATCH), "issuer mismatch"}, + {ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"}, + {ERR_REASON(X509_R_KEY_VALUES_MISMATCH), "key values mismatch"}, + {ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"}, + {ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"}, + {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"}, + {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"}, + {ERR_REASON(X509_R_NEWER_CRL_NOT_NEWER), "newer crl not newer"}, + {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), + "no cert set for us to verify"}, + {ERR_REASON(X509_R_NO_CRL_NUMBER), "no crl number"}, + {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"}, + {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"}, + {ERR_REASON(X509_R_SHOULD_RETRY), "should retry"}, + {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), + "unable to find parameters in chain"}, + {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), + "unable to get certs public key"}, + {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"}, + {ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"}, + {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"}, + {ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"}, + {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, + {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"}, + {ERR_REASON(X509_R_WRONG_TYPE), "wrong type"}, + {0, NULL} +}; + +#endif + +void ERR_load_X509_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { + ERR_load_strings(0, X509_str_functs); + ERR_load_strings(0, X509_str_reasons); + } +#endif +} +/* crypto/x509/x509_ext.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "stack.h" +// #include "cryptlib.h" +// #include "asn1.h" +// #include "objects.h" +// #include "evp.h" +// #include "x509.h" +// #include "x509v3.h" + +int X509_CRL_get_ext_count(X509_CRL *x) +{ + return (X509v3_get_ext_count(x->crl->extensions)); +} + +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); +} + +int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); +} + +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc) +{ + return (X509v3_get_ext(x->crl->extensions, loc)); +} + +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) +{ + return (X509v3_delete_ext(x->crl->extensions, loc)); +} + +void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->crl->extensions, nid, crit, idx); +} + +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); +} + +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); +} + +int X509_get_ext_count(X509 *x) +{ + return (X509v3_get_ext_count(x->cert_info->extensions)); +} + +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); +} + +int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); +} + +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->cert_info->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_get_ext(X509 *x, int loc) +{ + return (X509v3_get_ext(x->cert_info->extensions, loc)); +} + +X509_EXTENSION *X509_delete_ext(X509 *x, int loc) +{ + return (X509v3_delete_ext(x->cert_info->extensions, loc)); +} + +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); +} + +void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx); +} + +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, + flags); +} + +int X509_REVOKED_get_ext_count(X509_REVOKED *x) +{ + return (X509v3_get_ext_count(x->extensions)); +} + +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); +} + +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); +} + +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc) +{ + return (X509v3_get_ext(x->extensions, loc)); +} + +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) +{ + return (X509v3_delete_ext(x->extensions, loc)); +} + +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); +} + +void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->extensions, nid, crit, idx); +} + +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); +} + +IMPLEMENT_STACK_OF(X509_EXTENSION) + +IMPLEMENT_ASN1_SET_OF(X509_EXTENSION) +/* crypto/x509/x509_lu.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "lhash.h" +// #include "x509.h" +// #include "x509v3.h" + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) +{ + X509_LOOKUP *ret; + + ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); + if (ret == NULL) + return NULL; + + ret->init = 0; + ret->skip = 0; + ret->method = method; + ret->method_data = NULL; + ret->store_ctx = NULL; + if ((method->new_item != NULL) && !method->new_item(ret)) { + OPENSSL_free(ret); + return NULL; + } + return ret; +} + +void X509_LOOKUP_free(X509_LOOKUP *ctx) +{ + if (ctx == NULL) + return; + if ((ctx->method != NULL) && (ctx->method->free != NULL)) + (*ctx->method->free) (ctx); + OPENSSL_free(ctx); +} + +int X509_LOOKUP_init(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->init != NULL) + return ctx->method->init(ctx); + else + return 1; +} + +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->shutdown != NULL) + return ctx->method->shutdown(ctx); + else + return 1; +} + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret) +{ + if (ctx->method == NULL) + return -1; + if (ctx->method->ctrl != NULL) + return ctx->method->ctrl(ctx, cmd, argc, argl, ret); + else + return 1; +} + +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) + return X509_LU_FAIL; + if (ctx->skip) + return 0; + return ctx->method->get_by_subject(ctx, type, name, ret); +} + +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret); +} + +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret); +} + +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_alias(ctx, type, str, len, ret); +} + +static int x509_object_cmp(const X509_OBJECT *const *a, + const X509_OBJECT *const *b) +{ + int ret; + + ret = ((*a)->type - (*b)->type); + if (ret) + return ret; + switch ((*a)->type) { + case X509_LU_X509: + ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); + break; + case X509_LU_CRL: + ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); + break; + default: + /* abort(); */ + return 0; + } + return ret; +} + +X509_STORE *X509_STORE_new(void) +{ + X509_STORE *ret; + + if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) + return NULL; + if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) + goto err0; + ret->cache = 1; + if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) + goto err1; + ret->verify = 0; + ret->verify_cb = 0; + + if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) + goto err2; + + ret->get_issuer = 0; + ret->check_issued = 0; + ret->check_revocation = 0; + ret->get_crl = 0; + ret->check_crl = 0; + ret->cert_crl = 0; + ret->lookup_certs = 0; + ret->lookup_crls = 0; + ret->cleanup = 0; + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) + goto err3; + + ret->references = 1; + return ret; + + err3: + X509_VERIFY_PARAM_free(ret->param); + err2: + sk_X509_LOOKUP_free(ret->get_cert_methods); + err1: + sk_X509_OBJECT_free(ret->objs); + err0: + OPENSSL_free(ret); + return NULL; +} + +static void cleanup(X509_OBJECT *a) +{ + if (!a) + return; + if (a->type == X509_LU_X509) { + X509_free(a->data.x509); + } else if (a->type == X509_LU_CRL) { + X509_CRL_free(a->data.crl); + } else { + /* abort(); */ + } + + OPENSSL_free(a); +} + +void X509_STORE_free(X509_STORE *vfy) +{ + int i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + if (vfy == NULL) + return; + + i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE); +#ifdef REF_PRINT + REF_PRINT("X509_STORE", vfy); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "X509_STORE_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + sk = vfy->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); + if (vfy->param) + X509_VERIFY_PARAM_free(vfy->param); + OPENSSL_free(vfy); +} + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) +{ + int i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + sk = v->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + if (m == lu->method) { + return lu; + } + } + /* a new one */ + lu = X509_LOOKUP_new(m); + if (lu == NULL) + return NULL; + else { + lu->store_ctx = v; + if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) + return lu; + else { + X509_LOOKUP_free(lu); + return NULL; + } + } +} + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + X509_STORE *ctx = vs->ctx; + X509_LOOKUP *lu; + X509_OBJECT stmp, *tmp; + int i, j; + + if (ctx == NULL) + return 0; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + if (tmp == NULL || type == X509_LU_CRL) { + for (i = vs->current_method; + i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + j = X509_LOOKUP_by_subject(lu, type, name, &stmp); + if (j < 0) { + vs->current_method = j; + return j; + } else if (j) { + tmp = &stmp; + break; + } + } + vs->current_method = 0; + if (tmp == NULL) + return 0; + } + +/*- if (ret->data.ptr != NULL) + X509_OBJECT_free_contents(ret); */ + + ret->type = tmp->type; + ret->data.ptr = tmp->data.ptr; + + X509_OBJECT_up_ref_count(ret); + + return 1; +} + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) +{ + X509_OBJECT *obj; + int ret = 1; + + if (x == NULL) + return 0; + obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + if (obj == NULL) { + X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_X509; + obj->data.x509 = x; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CERT, + X509_R_CERT_ALREADY_IN_HASH_TABLE); + ret = 0; + } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); + ret = 0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return ret; +} + +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) +{ + X509_OBJECT *obj; + int ret = 1; + + if (x == NULL) + return 0; + obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + if (obj == NULL) { + X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_CRL; + obj->data.crl = x; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE); + ret = 0; + } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); + ret = 0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return ret; +} + +void X509_OBJECT_up_ref_count(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509); + break; + case X509_LU_CRL: + CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL); + break; + } +} + +void X509_OBJECT_free_contents(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + X509_free(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_free(a->data.crl); + break; + } +} + +static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name, int *pnmatch) +{ + X509_OBJECT stmp; + X509 x509_s; + X509_CINF cinf_s; + X509_CRL crl_s; + X509_CRL_INFO crl_info_s; + int idx; + + stmp.type = type; + switch (type) { + case X509_LU_X509: + stmp.data.x509 = &x509_s; + x509_s.cert_info = &cinf_s; + cinf_s.subject = name; + break; + case X509_LU_CRL: + stmp.data.crl = &crl_s; + crl_s.crl = &crl_info_s; + crl_info_s.issuer = name; + break; + default: + /* abort(); */ + return -1; + } + + idx = sk_X509_OBJECT_find(h, &stmp); + if (idx >= 0 && pnmatch) { + int tidx; + const X509_OBJECT *tobj, *pstmp; + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { + tobj = sk_X509_OBJECT_value(h, tidx); + if (x509_object_cmp(&tobj, &pstmp)) + break; + (*pnmatch)++; + } + } + return idx; +} + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) +{ + return x509_object_idx_cnt(h, type, name, NULL); +} + +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + int type, X509_NAME *name) +{ + int idx; + idx = X509_OBJECT_idx_by_subject(h, type, name); + if (idx == -1) + return NULL; + return sk_X509_OBJECT_value(h, idx); +} + +STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) +{ + int i, idx, cnt; + STACK_OF(X509) *sk; + X509 *x; + X509_OBJECT *obj; + + if (ctx->ctx == NULL) + return NULL; + + sk = sk_X509_new_null(); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + /* + * Nothing found in cache: do lookup to possibly add new objects to + * cache + */ + X509_OBJECT xobj; + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { + sk_X509_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_free(sk); + return NULL; + } + } + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.x509; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + if (!sk_X509_push(sk, x)) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; + +} + +STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) +{ + int i, idx, cnt; + STACK_OF(X509_CRL) *sk; + X509_CRL *x; + X509_OBJECT *obj, xobj; + + + if (ctx->ctx == NULL) + return NULL; + + sk = sk_X509_CRL_new_null(); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + /* + * Always do lookup to possibly add new CRLs to cache + */ + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { + sk_X509_CRL_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + if (idx < 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_CRL_free(sk); + return NULL; + } + + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.crl; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); + if (!sk_X509_CRL_push(sk, x)) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; +} + +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x) +{ + int idx, i; + X509_OBJECT *obj; + idx = sk_X509_OBJECT_find(h, x); + if (idx == -1) + return NULL; + if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) + return sk_X509_OBJECT_value(h, idx); + for (i = idx; i < sk_X509_OBJECT_num(h); i++) { + obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp + ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) + return NULL; + if (x->type == X509_LU_X509) { + if (!X509_cmp(obj->data.x509, x->data.x509)) + return obj; + } else if (x->type == X509_LU_CRL) { + if (!X509_CRL_match(obj->data.crl, x->data.crl)) + return obj; + } else + return obj; + } + return NULL; +} + +/*- + * Try to get issuer certificate from store. Due to limitations + * of the API this can only retrieve a single certificate matching + * a given subject name. However it will fill the cache with all + * matching certificates, so we can examine the cache for all + * matches. + * + * Return values are: + * 1 lookup successful. + * 0 certificate not found. + * -1 some other error. + */ +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + X509_NAME *xn; + X509_OBJECT obj, *pobj; + int i, ok, idx, ret; + xn = X509_get_issuer_name(x); + ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj); + if (ok != X509_LU_X509) { + if (ok == X509_LU_RETRY) { + X509_OBJECT_free_contents(&obj); + X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY); + return -1; + } else if (ok != X509_LU_FAIL) { + X509_OBJECT_free_contents(&obj); + /* not good :-(, break anyway */ + return -1; + } + return 0; + } + /* If certificate matches all OK */ + if (ctx->check_issued(ctx, x, obj.data.x509)) { + *issuer = obj.data.x509; + return 1; + } + X509_OBJECT_free_contents(&obj); + + if (ctx->ctx == NULL) + return 0; + + /* Else find index of first cert accepted by 'check_issued' */ + ret = 0; + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); + if (idx != -1) { /* should be true as we've had at least one + * match */ + /* Look through all matching certs for suitable issuer */ + for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { + pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); + /* See if we've run past the matches */ + if (pobj->type != X509_LU_X509) + break; + if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) + break; + if (ctx->check_issued(ctx, x, pobj->data.x509)) { + *issuer = pobj->data.x509; + X509_OBJECT_up_ref_count(pobj); + ret = 1; + break; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return ret; +} + +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) +{ + return X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +int X509_STORE_set_depth(X509_STORE *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); + return 1; +} + +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} + +int X509_STORE_set_trust(X509_STORE *ctx, int trust) +{ + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} + +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) +{ + return X509_VERIFY_PARAM_set1(ctx->param, param); +} + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)) +{ + ctx->verify_cb = verify_cb; +} + +void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, + STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX + *ctx, + X509_NAME *nm)) +{ + ctx->lookup_crls = cb; +} + +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) +{ + return ctx->ctx; +} + +IMPLEMENT_STACK_OF(X509_LOOKUP) + +IMPLEMENT_STACK_OF(X509_OBJECT) +/* crypto/x509/x509_obj.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "lhash.h" +// #include "objects.h" +// #include "x509.h" +#include "buffer.h" + +/* + * Limit to ensure we don't overflow: much greater than + * anything enountered in practice. + */ + +#define NAME_ONELINE_MAX (1024 * 1024) + +char *X509_NAME_oneline(X509_NAME *a, char *buf, int len) +{ + X509_NAME_ENTRY *ne; + int i; + int n, lold, l, l1, l2, num, j, type; + const char *s; + char *p; + unsigned char *q; + BUF_MEM *b = NULL; + static const char hex[17] = "0123456789ABCDEF"; + int gs_doit[4]; + char tmp_buf[80]; +#ifdef CHARSET_EBCDIC + char ebcdic_buf[1024]; +#endif + + if (buf == NULL) { + if ((b = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(b, 200)) + goto err; + b->data[0] = '\0'; + len = 200; + } else if (len == 0) { + return NULL; + } + if (a == NULL) { + if (b) { + buf = b->data; + OPENSSL_free(b); + } + strncpy(buf, "NO X509_NAME", len); + buf[len - 1] = '\0'; + return buf; + } + + len--; /* space for '\0' */ + l = 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + ne = sk_X509_NAME_ENTRY_value(a->entries, i); + n = OBJ_obj2nid(ne->object); + if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { + i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); + s = tmp_buf; + } + l1 = strlen(s); + + type = ne->value->type; + num = ne->value->length; + if (num > NAME_ONELINE_MAX) { + X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); + goto end; + } + q = ne->value->data; +#ifdef CHARSET_EBCDIC + if (type == V_ASN1_GENERALSTRING || + type == V_ASN1_VISIBLESTRING || + type == V_ASN1_PRINTABLESTRING || + type == V_ASN1_TELETEXSTRING || + type == V_ASN1_IA5STRING) { + if (num > (int)sizeof(ebcdic_buf)) + num = sizeof(ebcdic_buf); + ascii2ebcdic(ebcdic_buf, q, num); + q = ebcdic_buf; + } +#endif + + if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; + for (j = 0; j < num; j++) + if (q[j] != 0) + gs_doit[j & 3] = 1; + + if (gs_doit[0] | gs_doit[1] | gs_doit[2]) + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + else { + gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; + gs_doit[3] = 1; + } + } else + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + + for (l2 = j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; + l2++; +#ifndef CHARSET_EBCDIC + if ((q[j] < ' ') || (q[j] > '~')) + l2 += 3; +#else + if ((os_toascii[q[j]] < os_toascii[' ']) || + (os_toascii[q[j]] > os_toascii['~'])) + l2 += 3; +#endif + } + + lold = l; + l += 1 + l1 + 1 + l2; + if (l > NAME_ONELINE_MAX) { + X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); + goto end; + } + if (b != NULL) { + if (!BUF_MEM_grow(b, l + 1)) + goto err; + p = &(b->data[lold]); + } else if (l > len) { + break; + } else + p = &(buf[lold]); + *(p++) = '/'; + memcpy(p, s, (unsigned int)l1); + p += l1; + *(p++) = '='; + +#ifndef CHARSET_EBCDIC /* q was assigned above already. */ + q = ne->value->data; +#endif + + for (j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; +#ifndef CHARSET_EBCDIC + n = q[j]; + if ((n < ' ') || (n > '~')) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = n; +#else + n = os_toascii[q[j]]; + if ((n < os_toascii[' ']) || (n > os_toascii['~'])) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = q[j]; +#endif + } + *p = '\0'; + } + if (b != NULL) { + p = b->data; + OPENSSL_free(b); + } else + p = buf; + if (i == 0) + *p = '\0'; + return (p); + err: + X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE); + end: + BUF_MEM_free(b); + return (NULL); +} +/* crypto/x509/x509_r2x.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "bn.h" +// #include "evp.h" +// #include "asn1.h" +// #include "x509.h" +// #include "objects.h" +// #include "buffer.h" + +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) +{ + X509 *ret = NULL; + X509_CINF *xi = NULL; + X509_NAME *xn; + EVP_PKEY *pubkey = NULL; + int res; + + if ((ret = X509_new()) == NULL) { + X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + + /* duplicate the request */ + xi = ret->cert_info; + + if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { + if ((xi->version = M_ASN1_INTEGER_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(xi->version, 2)) + goto err; +/*- xi->extensions=ri->attributes; <- bad, should not ever be done + ri->attributes=NULL; */ + } + + xn = X509_REQ_get_subject_name(r); + if (X509_set_subject_name(ret, xn) == 0) + goto err; + if (X509_set_issuer_name(ret, xn) == 0) + goto err; + + if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) + goto err; + if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) == + NULL) + goto err; + + pubkey = X509_REQ_get_pubkey(r); + res = X509_set_pubkey(ret, pubkey); + EVP_PKEY_free(pubkey); + + if (!res || !X509_sign(ret, pkey, EVP_md5())) + goto err; + if (0) { + err: + X509_free(ret); + ret = NULL; + } + return (ret); +} +/* crypto/x509/x509_req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "bn.h" +// #include "evp.h" +// #include "asn1.h" +#include "asn1t.h" +// #include "x509.h" +// #include "objects.h" +// #include "buffer.h" +#include "pem.h" + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + X509_REQ *ret; + X509_REQ_INFO *ri; + int i; + EVP_PKEY *pktmp; + + ret = X509_REQ_new(); + if (ret == NULL) { + X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE); + goto err; + } + + ri = ret->req_info; + + ri->version->length = 1; + ri->version->data = (unsigned char *)OPENSSL_malloc(1); + if (ri->version->data == NULL) + goto err; + ri->version->data[0] = 0; /* version == 0 */ + + if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) + goto err; + + pktmp = X509_get_pubkey(x); + if (pktmp == NULL) + goto err; + i = X509_REQ_set_pubkey(ret, pktmp); + EVP_PKEY_free(pktmp); + if (!i) + goto err; + + if (pkey != NULL) { + if (!X509_REQ_sign(ret, pkey, md)) + goto err; + } + return (ret); + err: + X509_REQ_free(ret); + return (NULL); +} + +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) +{ + if ((req == NULL) || (req->req_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(req->req_info->pubkey)); +} + +int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) +{ + EVP_PKEY *xk = NULL; + int ok = 0; + + xk = X509_REQ_get_pubkey(x); + switch (EVP_PKEY_cmp(xk, k)) { + case 1: + ok = 1; + break; + case 0: + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: +#ifndef OPENSSL_NO_EC + if (k->type == EVP_PKEY_EC) { + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); + break; + } +#endif +#ifndef OPENSSL_NO_DH + if (k->type == EVP_PKEY_DH) { + /* No idea */ + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + X509_R_CANT_CHECK_DH_KEY); + break; + } +#endif + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); + } + + EVP_PKEY_free(xk); + return (ok); +} + +/* + * It seems several organisations had the same idea of including a list of + * extensions in a certificate request. There are at least two OIDs that are + * used and there may be more: so the list is configurable. + */ + +static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef }; + +static int *ext_nids = ext_nid_list; + +int X509_REQ_extension_nid(int req_nid) +{ + int i, nid; + for (i = 0;; i++) { + nid = ext_nids[i]; + if (nid == NID_undef) + return 0; + else if (req_nid == nid) + return 1; + } +} + +int *X509_REQ_get_extension_nids(void) +{ + return ext_nids; +} + +void X509_REQ_set_extension_nids(int *nids) +{ + ext_nids = nids; +} + +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) +{ + X509_ATTRIBUTE *attr; + ASN1_TYPE *ext = NULL; + int idx, *pnid; + const unsigned char *p; + + if ((req == NULL) || (req->req_info == NULL) || !ext_nids) + return (NULL); + for (pnid = ext_nids; *pnid != NID_undef; pnid++) { + idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); + if (idx == -1) + continue; + attr = X509_REQ_get_attr(req, idx); + if (attr->single) + ext = attr->value.single; + else if (sk_ASN1_TYPE_num(attr->value.set)) + ext = sk_ASN1_TYPE_value(attr->value.set, 0); + break; + } + if (!ext || (ext->type != V_ASN1_SEQUENCE)) + return NULL; + p = ext->value.sequence->data; + return (STACK_OF(X509_EXTENSION) *) + ASN1_item_d2i(NULL, &p, ext->value.sequence->length, + ASN1_ITEM_rptr(X509_EXTENSIONS)); +} + +/* + * Add a STACK_OF extensions to a certificate request: allow alternative OIDs + * in case we want to create a non standard one. + */ + +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid) +{ + ASN1_TYPE *at = NULL; + X509_ATTRIBUTE *attr = NULL; + if (!(at = ASN1_TYPE_new()) || !(at->value.sequence = ASN1_STRING_new())) + goto err; + + at->type = V_ASN1_SEQUENCE; + /* Generate encoding of extensions */ + at->value.sequence->length = + ASN1_item_i2d((ASN1_VALUE *)exts, + &at->value.sequence->data, + ASN1_ITEM_rptr(X509_EXTENSIONS)); + if (!(attr = X509_ATTRIBUTE_new())) + goto err; + if (!(attr->value.set = sk_ASN1_TYPE_new_null())) + goto err; + if (!sk_ASN1_TYPE_push(attr->value.set, at)) + goto err; + at = NULL; + attr->single = 0; + attr->object = OBJ_nid2obj(nid); + if (!req->req_info->attributes) { + if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null())) + goto err; + } + if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) + goto err; + return 1; + err: + X509_ATTRIBUTE_free(attr); + ASN1_TYPE_free(at); + return 0; +} + +/* This is the normal usage: use the "official" OID */ +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) +{ + return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); +} + +/* Request attribute functions */ + +int X509_REQ_get_attr_count(const X509_REQ *req) +{ + return X509at_get_attr_count(req->req_info->attributes); +} + +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); +} + +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); +} + +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) +{ + return X509at_get_attr(req->req_info->attributes, loc); +} + +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) +{ + return X509at_delete_attr(req->req_info->attributes, loc); +} + +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&req->req_info->attributes, attr)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, + type, bytes, len)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid, + type, bytes, len)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, + type, bytes, len)) + return 1; + return 0; +} +/* crypto/x509/x509_set.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1.h" +// #include "objects.h" +// #include "evp.h" +// #include "x509.h" + +int X509_set_version(X509 *x, long version) +{ + if (x == NULL) + return (0); + if (version == 0) { + M_ASN1_INTEGER_free(x->cert_info->version); + x->cert_info->version = NULL; + return (1); + } + if (x->cert_info->version == NULL) { + if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->cert_info->version, version)); +} + +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return (0); + in = x->cert_info->serialNumber; + if (in != serial) { + in = M_ASN1_INTEGER_dup(serial); + if (in != NULL) { + M_ASN1_INTEGER_free(x->cert_info->serialNumber); + x->cert_info->serialNumber = in; + } + } + return (in != NULL); +} + +int X509_set_issuer_name(X509 *x, X509_NAME *name) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_NAME_set(&x->cert_info->issuer, name)); +} + +int X509_set_subject_name(X509 *x, X509_NAME *name) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_NAME_set(&x->cert_info->subject, name)); +} + +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) + return (0); + in = x->cert_info->validity->notBefore; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->cert_info->validity->notBefore); + x->cert_info->validity->notBefore = in; + } + } + return (in != NULL); +} + +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) + return (0); + in = x->cert_info->validity->notAfter; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->cert_info->validity->notAfter); + x->cert_info->validity->notAfter = in; + } + } + return (in != NULL); +} + +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); +} +/* x509_trs.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "x509v3.h" + +static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b); +static void trtable_free(X509_TRUST *p); + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); +static int trust_compat(X509_TRUST *trust, X509 *x, int flags); + +static int obj_trust(int id, X509 *x, int flags); +static int (*default_trust) (int id, X509 *x, int flags) = obj_trust; + +/* + * WARNING: the following table should be kept in order of trust and without + * any gaps so we can just subtract the minimum trust value to get an index + * into the table + */ + +static X509_TRUST trstandard[] = { + {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL}, + {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, + NULL}, + {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, + NULL}, + {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, + NULL}, + {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, + NULL}, + {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, + NULL}, + {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, + NULL}, + {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL} +}; + +#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) + +IMPLEMENT_STACK_OF(X509_TRUST) + +static STACK_OF(X509_TRUST) *trtable = NULL; + +static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b) +{ + return (*a)->trust - (*b)->trust; +} + +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int) { + int (*oldtrust) (int, X509 *, int); + oldtrust = default_trust; + default_trust = trust; + return oldtrust; +} + +int X509_check_trust(X509 *x, int id, int flags) +{ + X509_TRUST *pt; + int idx; + if (id == -1) + return 1; + /* We get this as a default value */ + if (id == 0) { + int rv; + rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); + if (rv != X509_TRUST_UNTRUSTED) + return rv; + return trust_compat(NULL, x, 0); + } + idx = X509_TRUST_get_by_id(id); + if (idx == -1) + return default_trust(id, x, flags); + pt = X509_TRUST_get0(idx); + return pt->check_trust(pt, x, flags); +} + +int X509_TRUST_get_count(void) +{ + if (!trtable) + return X509_TRUST_COUNT; + return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; +} + +X509_TRUST *X509_TRUST_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_TRUST_COUNT) + return trstandard + idx; + return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); +} + +int X509_TRUST_get_by_id(int id) +{ + X509_TRUST tmp; + int idx; + if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) + return id - X509_TRUST_MIN; + tmp.trust = id; + if (!trtable) + return -1; + idx = sk_X509_TRUST_find(trtable, &tmp); + if (idx == -1) + return -1; + return idx + X509_TRUST_COUNT; +} + +int X509_TRUST_set(int *t, int trust) +{ + if (X509_TRUST_get_by_id(trust) == -1) { + X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST); + return 0; + } + *t = trust; + return 1; +} + +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2) +{ + int idx; + X509_TRUST *trtmp; + /* + * This is set according to what we change: application can't set it + */ + flags &= ~X509_TRUST_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_TRUST_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_TRUST_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else + trtmp = X509_TRUST_get0(idx); + + /* OPENSSL_free existing name if dynamic */ + if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(trtmp->name); + /* dup supplied name */ + if (!(trtmp->name = BUF_strdup(name))) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + /* Keep the dynamic flag of existing entry */ + trtmp->flags &= X509_TRUST_DYNAMIC; + /* Set all other flags */ + trtmp->flags |= flags; + + trtmp->trust = id; + trtmp->check_trust = ck; + trtmp->arg1 = arg1; + trtmp->arg2 = arg2; + + /* If its a new entry manage the dynamic table */ + if (idx == -1) { + if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509_TRUST_push(trtable, trtmp)) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + +static void trtable_free(X509_TRUST *p) +{ + if (!p) + return; + if (p->flags & X509_TRUST_DYNAMIC) { + if (p->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(p->name); + OPENSSL_free(p); + } +} + +void X509_TRUST_cleanup(void) +{ + unsigned int i; + for (i = 0; i < X509_TRUST_COUNT; i++) + trtable_free(trstandard + i); + sk_X509_TRUST_pop_free(trtable, trtable_free); + trtable = NULL; +} + +int X509_TRUST_get_flags(X509_TRUST *xp) +{ + return xp->flags; +} + +char *X509_TRUST_get0_name(X509_TRUST *xp) +{ + return xp->name; +} + +int X509_TRUST_get_trust(X509_TRUST *xp) +{ + return xp->trust; +} + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux && (x->aux->trust || x->aux->reject)) + return obj_trust(trust->arg1, x, flags); + /* + * we don't have any trust settings: for compatibility we return trusted + * if it is self signed + */ + return trust_compat(trust, x, flags); +} + +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux) + return obj_trust(trust->arg1, x, flags); + return X509_TRUST_UNTRUSTED; +} + +static int trust_compat(X509_TRUST *trust, X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) + return X509_TRUST_TRUSTED; + else + return X509_TRUST_UNTRUSTED; +} + +static int obj_trust(int id, X509 *x, int flags) +{ + ASN1_OBJECT *obj; + int i; + X509_CERT_AUX *ax; + ax = x->aux; + if (!ax) + return X509_TRUST_UNTRUSTED; + if (ax->reject) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + obj = sk_ASN1_OBJECT_value(ax->reject, i); + if (OBJ_obj2nid(obj) == id) + return X509_TRUST_REJECTED; + } + } + if (ax->trust) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + obj = sk_ASN1_OBJECT_value(ax->trust, i); + if (OBJ_obj2nid(obj) == id) + return X509_TRUST_TRUSTED; + } + } + return X509_TRUST_UNTRUSTED; +} +/* crypto/x509/x509_txt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +// #include "cryptlib.h" +// #include "lhash.h" +// #include "buffer.h" +// #include "evp.h" +// #include "asn1.h" +// #include "x509.h" +// #include "objects.h" + +const char *X509_verify_cert_error_string(long n) +{ + static char buf[100]; + + switch ((int)n) { + case X509_V_OK: + return ("ok"); + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + return ("unable to get issuer certificate"); + case X509_V_ERR_UNABLE_TO_GET_CRL: + return ("unable to get certificate CRL"); + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + return ("unable to decrypt certificate's signature"); + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + return ("unable to decrypt CRL's signature"); + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + return ("unable to decode issuer public key"); + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + return ("certificate signature failure"); + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return ("CRL signature failure"); + case X509_V_ERR_CERT_NOT_YET_VALID: + return ("certificate is not yet valid"); + case X509_V_ERR_CRL_NOT_YET_VALID: + return ("CRL is not yet valid"); + case X509_V_ERR_CERT_HAS_EXPIRED: + return ("certificate has expired"); + case X509_V_ERR_CRL_HAS_EXPIRED: + return ("CRL has expired"); + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + return ("format error in certificate's notBefore field"); + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + return ("format error in certificate's notAfter field"); + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + return ("format error in CRL's lastUpdate field"); + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + return ("format error in CRL's nextUpdate field"); + case X509_V_ERR_OUT_OF_MEM: + return ("out of memory"); + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + return ("self signed certificate"); + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + return ("self signed certificate in certificate chain"); + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + return ("unable to get local issuer certificate"); + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return ("unable to verify the first certificate"); + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + return ("certificate chain too long"); + case X509_V_ERR_CERT_REVOKED: + return ("certificate revoked"); + case X509_V_ERR_INVALID_CA: + return ("invalid CA certificate"); + case X509_V_ERR_INVALID_NON_CA: + return ("invalid non-CA certificate (has CA markings)"); + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + return ("path length constraint exceeded"); + case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: + return ("proxy path length constraint exceeded"); + case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: + return + ("proxy certificates not allowed, please set the appropriate flag"); + case X509_V_ERR_INVALID_PURPOSE: + return ("unsupported certificate purpose"); + case X509_V_ERR_CERT_UNTRUSTED: + return ("certificate not trusted"); + case X509_V_ERR_CERT_REJECTED: + return ("certificate rejected"); + case X509_V_ERR_APPLICATION_VERIFICATION: + return ("application verification failure"); + case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: + return ("subject issuer mismatch"); + case X509_V_ERR_AKID_SKID_MISMATCH: + return ("authority and subject key identifier mismatch"); + case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: + return ("authority and issuer serial number mismatch"); + case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: + return ("key usage does not include certificate signing"); + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + return ("unable to get CRL issuer certificate"); + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + return ("unhandled critical extension"); + case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: + return ("key usage does not include CRL signing"); + case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: + return ("key usage does not include digital signature"); + case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: + return ("unhandled critical CRL extension"); + case X509_V_ERR_INVALID_EXTENSION: + return ("invalid or inconsistent certificate extension"); + case X509_V_ERR_INVALID_POLICY_EXTENSION: + return ("invalid or inconsistent certificate policy extension"); + case X509_V_ERR_NO_EXPLICIT_POLICY: + return ("no explicit policy"); + case X509_V_ERR_DIFFERENT_CRL_SCOPE: + return ("Different CRL scope"); + case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: + return ("Unsupported extension feature"); + case X509_V_ERR_UNNESTED_RESOURCE: + return ("RFC 3779 resource not subset of parent's resources"); + + case X509_V_ERR_PERMITTED_VIOLATION: + return ("permitted subtree violation"); + case X509_V_ERR_EXCLUDED_VIOLATION: + return ("excluded subtree violation"); + case X509_V_ERR_SUBTREE_MINMAX: + return ("name constraints minimum and maximum not supported"); + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: + return ("unsupported name constraint type"); + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: + return ("unsupported or invalid name constraint syntax"); + case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: + return ("unsupported or invalid name syntax"); + case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: + return ("CRL path validation error"); + + case X509_V_ERR_SUITE_B_INVALID_VERSION: + return ("Suite B: certificate version invalid"); + case X509_V_ERR_SUITE_B_INVALID_ALGORITHM: + return ("Suite B: invalid public key algorithm"); + case X509_V_ERR_SUITE_B_INVALID_CURVE: + return ("Suite B: invalid ECC curve"); + case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: + return ("Suite B: invalid signature algorithm"); + case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: + return ("Suite B: curve not allowed for this LOS"); + case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: + return ("Suite B: cannot sign P-384 with P-256"); + + case X509_V_ERR_HOSTNAME_MISMATCH: + return ("Hostname mismatch"); + case X509_V_ERR_EMAIL_MISMATCH: + return ("Email address mismatch"); + case X509_V_ERR_IP_ADDRESS_MISMATCH: + return ("IP address mismatch"); + + case X509_V_ERR_INVALID_CALL: + return ("Invalid certificate verification context"); + case X509_V_ERR_STORE_LOOKUP: + return ("Issuer certificate lookup error"); + case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: + return ("proxy subject name violation"); + + default: + BIO_snprintf(buf, sizeof(buf), "error number %ld", n); + return (buf); + } +} +/* crypto/x509/x509_v3.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "stack.h" +// #include "cryptlib.h" +// #include "asn1.h" +// #include "objects.h" +// #include "evp.h" +// #include "x509.h" +// #include "x509v3.h" + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) +{ + if (x == NULL) + return (0); + return (sk_X509_EXTENSION_num(x)); +} + +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, + int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509v3_get_ext_by_OBJ(x, obj, lastpos)); +} + +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, + ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, + int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit)) + return (lastpos); + } + return (-1); +} + +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) +{ + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_EXTENSION_value(x, loc); +} + +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) +{ + X509_EXTENSION *ret; + + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return (NULL); + ret = sk_X509_EXTENSION_delete(x, loc); + return (ret); +} + +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc) +{ + X509_EXTENSION *new_ex = NULL; + int n; + STACK_OF(X509_EXTENSION) *sk = NULL; + + if (x == NULL) { + X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) { + if ((sk = sk_X509_EXTENSION_new_null()) == NULL) + goto err; + } else + sk = *x; + + n = sk_X509_EXTENSION_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) + goto err2; + if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + err: + X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE); + err2: + if (new_ex != NULL) + X509_EXTENSION_free(new_ex); + if (x != NULL && *x == NULL && sk != NULL) + sk_X509_EXTENSION_free(sk); + return (NULL); +} + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, + int crit, + ASN1_OCTET_STRING *data) +{ + ASN1_OBJECT *obj; + X509_EXTENSION *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); + if (ret == NULL) + ASN1_OBJECT_free(obj); + return (ret); +} + +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data) +{ + X509_EXTENSION *ret; + + if ((ex == NULL) || (*ex == NULL)) { + if ((ret = X509_EXTENSION_new()) == NULL) { + X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ, + ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret = *ex; + + if (!X509_EXTENSION_set_object(ret, obj)) + goto err; + if (!X509_EXTENSION_set_critical(ret, crit)) + goto err; + if (!X509_EXTENSION_set_data(ret, data)) + goto err; + + if ((ex != NULL) && (*ex == NULL)) + *ex = ret; + return (ret); + err: + if ((ex == NULL) || (ret != *ex)) + X509_EXTENSION_free(ret); + return (NULL); +} + +int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj) +{ + if ((ex == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(ex->object); + ex->object = OBJ_dup(obj); + return (1); +} + +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) +{ + if (ex == NULL) + return (0); + ex->critical = (crit) ? 0xFF : -1; + return (1); +} + +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) +{ + int i; + + if (ex == NULL) + return (0); + i = M_ASN1_OCTET_STRING_set(ex->value, data->data, data->length); + if (!i) + return (0); + return (1); +} + +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->object); +} + +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->value); +} + +int X509_EXTENSION_get_critical(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (0); + if (ex->critical > 0) + return 1; + return 0; +} +/* crypto/x509/x509_vfy.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +// #include "cryptlib.h" +// #include "crypto.h" +// #include "lhash.h" +// #include "buffer.h" +// #include "evp.h" +// #include "asn1.h" +// #include "x509.h" +// #include "x509v3.h" +// #include "objects.h" +#include "vpm_int.h" + +/* CRL score values */ + +/* No unhandled critical extensions */ + +#define CRL_SCORE_NOCRITICAL 0x100 + +/* certificate is within CRL scope */ + +#define CRL_SCORE_SCOPE 0x080 + +/* CRL times valid */ + +#define CRL_SCORE_TIME 0x040 + +/* Issuer name matches certificate */ + +#define CRL_SCORE_ISSUER_NAME 0x020 + +/* If this score or above CRL is probably valid */ + +#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) + +/* CRL issuer is certificate issuer */ + +#define CRL_SCORE_ISSUER_CERT 0x018 + +/* CRL issuer is on certificate path */ + +#define CRL_SCORE_SAME_PATH 0x008 + +/* CRL issuer matches CRL AKID */ + +#define CRL_SCORE_AKID 0x004 + +/* Have a delta CRL with valid times */ + +#define CRL_SCORE_TIME_DELTA 0x002 + +static int null_callback(int ok, X509_STORE_CTX *e); +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); +static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_name_constraints(X509_STORE_CTX *ctx); +static int check_id(X509_STORE_CTX *ctx); +static int check_trust(X509_STORE_CTX *ctx); +static int check_revocation(X509_STORE_CTX *ctx); +static int check_cert(X509_STORE_CTX *ctx); +static int check_policy(X509_STORE_CTX *ctx); + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, X509_CRL *crl, X509 *x); +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, + int *pcrl_score, X509_CRL *base, + STACK_OF(X509_CRL) *crls); +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, + int *pcrl_score); +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons); +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); +static int check_crl_chain(X509_STORE_CTX *ctx, + STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path); + +static int internal_verify(X509_STORE_CTX *ctx); +const char X509_version[] = "X.509" OPENSSL_VERSION_PTEXT; + +static int null_callback(int ok, X509_STORE_CTX *e) +{ + return ok; +} + +#if 0 +static int x509_subject_cmp(X509 **a, X509 **b) +{ + return X509_subject_name_cmp(*a, *b); +} +#endif +/* Return 1 is a certificate is self signed */ +static int cert_self_signed(X509 *x) +{ + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) + return 1; + else + return 0; +} + +/* Given a certificate try and find an exact match in the store */ + +static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) +{ + STACK_OF(X509) *certs; + X509 *xtmp = NULL; + int i; + /* Lookup all certs with matching subject name */ + certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); + if (certs == NULL) + return NULL; + /* Look for exact match */ + for (i = 0; i < sk_X509_num(certs); i++) { + xtmp = sk_X509_value(certs, i); + if (!X509_cmp(xtmp, x)) + break; + } + if (i < sk_X509_num(certs)) + CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509); + else + xtmp = NULL; + sk_X509_pop_free(certs, X509_free); + return xtmp; +} + +int X509_verify_cert(X509_STORE_CTX *ctx) +{ + X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; + int bad_chain = 0; + X509_VERIFY_PARAM *param = ctx->param; + int depth, i, ok = 0; + int num, j, retry; + int (*cb) (int xok, X509_STORE_CTX *xctx); + STACK_OF(X509) *sktmp = NULL; + int trust = X509_TRUST_UNTRUSTED; + int err; + + if (ctx->cert == NULL) { + X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + if (ctx->chain != NULL) { + /* + * This X509_STORE_CTX has already been used to verify a cert. We + * cannot do another one. + */ + X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ctx->error = X509_V_ERR_INVALID_CALL; + return -1; + } + + cb = ctx->verify_cb; + + /* + * first we make sure the chain we are going to build is present and that + * the first entry is in place + */ + if (((ctx->chain = sk_X509_new_null()) == NULL) || + (!sk_X509_push(ctx->chain, ctx->cert))) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = -1; + goto err; + } + CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509); + ctx->last_untrusted = 1; + + /* We use a temporary STACK so we can chop and hack at it */ + if (ctx->untrusted != NULL + && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = -1; + goto err; + } + + num = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, num - 1); + depth = param->depth; + + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; /* FIXME: If this happens, we should take + * note of it and, if appropriate, use the + * X509_V_ERR_CERT_CHAIN_TOO_LONG error code + * later. */ + + /* If we are self signed, we break */ + if (cert_self_signed(x)) + break; + /* + * If asked see if we can find issuer in trusted store first + */ + if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { + ok = ctx->get_issuer(&xtmp, ctx, x); + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto err; + } + /* + * If successful for now free up cert so it will be picked up + * again later. + */ + if (ok > 0) { + X509_free(xtmp); + break; + } + } + + /* If we were passed a cert chain, use it first */ + if (ctx->untrusted != NULL) { + xtmp = find_issuer(ctx, sktmp, x); + if (xtmp != NULL) { + if (!sk_X509_push(ctx->chain, xtmp)) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = -1; + goto err; + } + CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509); + (void)sk_X509_delete_ptr(sktmp, xtmp); + ctx->last_untrusted++; + x = xtmp; + num++; + /* + * reparse the full chain for the next one + */ + continue; + } + } + break; + } + + /* Remember how many untrusted certs we have */ + j = num; + /* + * at this point, chain should contain a list of untrusted certificates. + * We now need to add at least one trusted one, if possible, otherwise we + * complain. + */ + + do { + /* + * Examine last certificate in chain and see if it is self signed. + */ + i = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, i - 1); + if (cert_self_signed(x)) { + /* we have a self signed certificate */ + if (sk_X509_num(ctx->chain) == 1) { + /* + * We have a single self signed certificate: see if we can + * find it in the store. We must have an exact match to avoid + * possible impersonation. + */ + ok = ctx->get_issuer(&xtmp, ctx, x); + if ((ok <= 0) || X509_cmp(x, xtmp)) { + ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; + ctx->current_cert = x; + ctx->error_depth = i - 1; + if (ok == 1) + X509_free(xtmp); + bad_chain = 1; + ok = cb(0, ctx); + if (!ok) + goto err; + } else { + /* + * We have a match: replace certificate with store + * version so we get any trust settings. + */ + X509_free(x); + x = xtmp; + (void)sk_X509_set(ctx->chain, i - 1, x); + ctx->last_untrusted = 0; + } + } else { + /* + * extract and save self signed certificate for later use + */ + chain_ss = sk_X509_pop(ctx->chain); + ctx->last_untrusted--; + num--; + j--; + x = sk_X509_value(ctx->chain, num - 1); + } + } + /* We now lookup certs from the certificate store */ + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; + /* If we are self signed, we break */ + if (cert_self_signed(x)) + break; + ok = ctx->get_issuer(&xtmp, ctx, x); + + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto err; + } + if (ok == 0) + break; + x = xtmp; + if (!sk_X509_push(ctx->chain, x)) { + X509_free(xtmp); + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = -1; + goto err; + } + num++; + } + + /* we now have our chain, lets check it... */ + if ((trust = check_trust(ctx)) == X509_TRUST_REJECTED) { + /* Callback already issued */ + ok = 0; + goto err; + } + + /* + * If it's not explicitly trusted then check if there is an alternative + * chain that could be used. We only do this if we haven't already + * checked via TRUSTED_FIRST and the user hasn't switched off alternate + * chain checking + */ + retry = 0; + if (trust != X509_TRUST_TRUSTED + && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) + && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { + while (j-- > 1) { + xtmp2 = sk_X509_value(ctx->chain, j - 1); + ok = ctx->get_issuer(&xtmp, ctx, xtmp2); + if (ok < 0) { + ctx->error = X509_V_ERR_STORE_LOOKUP; + goto err; + } + /* Check if we found an alternate chain */ + if (ok > 0) { + /* + * Free up the found cert we'll add it again later + */ + X509_free(xtmp); + + /* + * Dump all the certs above this point - we've found an + * alternate chain + */ + while (num > j) { + xtmp = sk_X509_pop(ctx->chain); + X509_free(xtmp); + num--; + } + ctx->last_untrusted = sk_X509_num(ctx->chain); + retry = 1; + break; + } + } + } + } while (retry); + + /* + * If not explicitly trusted then indicate error unless it's a single + * self signed certificate in which case we've indicated an error already + * and set bad_chain == 1 + */ + if (trust != X509_TRUST_TRUSTED && !bad_chain) { + if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { + if (ctx->last_untrusted >= num) + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; + else + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; + ctx->current_cert = x; + } else { + + sk_X509_push(ctx->chain, chain_ss); + num++; + ctx->last_untrusted = num; + ctx->current_cert = chain_ss; + ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + chain_ss = NULL; + } + + ctx->error_depth = num - 1; + bad_chain = 1; + ok = cb(0, ctx); + if (!ok) + goto err; + } + + /* We have the chain complete: now we need to check its purpose */ + ok = check_chain_extensions(ctx); + + if (!ok) + goto err; + + /* Check name constraints */ + + ok = check_name_constraints(ctx); + + if (!ok) + goto err; + + ok = check_id(ctx); + + if (!ok) + goto err; + + /* We may as well copy down any DSA parameters that are required */ + X509_get_pubkey_parameters(NULL, ctx->chain); + + /* + * Check revocation status: we do this after copying parameters because + * they may be needed for CRL signature verification. + */ + + ok = ctx->check_revocation(ctx); + if (!ok) + goto err; + + err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain, + ctx->param->flags); + if (err != X509_V_OK) { + ctx->error = err; + ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth); + ok = cb(0, ctx); + if (!ok) + goto err; + } + + /* At this point, we have a chain and need to verify it */ + if (ctx->verify != NULL) + ok = ctx->verify(ctx); + else + ok = internal_verify(ctx); + if (!ok) + goto err; + +#ifndef OPENSSL_NO_RFC3779 + /* RFC 3779 path validation, now that CRL check has been done */ + ok = v3_asid_validate_path(ctx); + if (!ok) + goto err; + ok = v3_addr_validate_path(ctx); + if (!ok) + goto err; +#endif + + /* If we get this far evaluate policies */ + if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) + ok = ctx->check_policy(ctx); + if (!ok) + goto err; + if (0) { + err: + /* Ensure we return an error */ + if (ok > 0) + ok = 0; + X509_get_pubkey_parameters(NULL, ctx->chain); + } + if (sktmp != NULL) + sk_X509_free(sktmp); + if (chain_ss != NULL) + X509_free(chain_ss); + + /* Safety net, error returns must set ctx->error */ + if (ok <= 0 && ctx->error == X509_V_OK) + ctx->error = X509_V_ERR_UNSPECIFIED; + return ok; +} + +/* + * Given a STACK_OF(X509) find the issuer of cert (if any) + */ + +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) +{ + int i; + X509 *issuer; + for (i = 0; i < sk_X509_num(sk); i++) { + issuer = sk_X509_value(sk, i); + if (ctx->check_issued(ctx, x, issuer)) + return issuer; + } + return NULL; +} + +/* Given a possible certificate and issuer check them */ + +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) +{ + int ret; + ret = X509_check_issued(issuer, x); + if (ret == X509_V_OK) + return 1; + /* If we haven't asked for issuer errors don't set ctx */ + if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) + return 0; + + ctx->error = ret; + ctx->current_cert = x; + ctx->current_issuer = issuer; + return ctx->verify_cb(0, ctx); +} + +/* Alternative lookup method: look from a STACK stored in other_ctx */ + +static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + *issuer = find_issuer(ctx, ctx->other_ctx, x); + if (*issuer) { + CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); + return 1; + } else + return 0; +} + +/* + * Check a certificate chains extensions for consistency with the supplied + * purpose + */ + +static int check_chain_extensions(X509_STORE_CTX *ctx) +{ +#ifdef OPENSSL_NO_CHAIN_VERIFY + return 1; +#else + int i, ok = 0, must_be_ca, plen = 0; + X509 *x; + int (*cb) (int xok, X509_STORE_CTX *xctx); + int proxy_path_length = 0; + int purpose; + int allow_proxy_certs; + cb = ctx->verify_cb; + + /*- + * must_be_ca can have 1 of 3 values: + * -1: we accept both CA and non-CA certificates, to allow direct + * use of self-signed certificates (which are marked as CA). + * 0: we only accept non-CA certificates. This is currently not + * used, but the possibility is present for future extensions. + * 1: we only accept CA certificates. This is currently used for + * all certificates in the chain except the leaf certificate. + */ + must_be_ca = -1; + + /* CRL path validation */ + if (ctx->parent) { + allow_proxy_certs = 0; + purpose = X509_PURPOSE_CRL_SIGN; + } else { + allow_proxy_certs = + ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + /* + * A hack to keep people who don't want to modify their software + * happy + */ + if (ossl_safe_getenv("OPENSSL_ALLOW_PROXY_CERTS")) + allow_proxy_certs = 1; + purpose = ctx->param->purpose; + } + + /* Check all untrusted certificates */ + for (i = 0; i < ctx->last_untrusted; i++) { + int ret; + x = sk_X509_value(ctx->chain, i); + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + && (x->ex_flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { + ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + ret = X509_check_ca(x); + switch (must_be_ca) { + case -1: + if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1) && (ret != 0)) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + break; + case 0: + if (ret != 0) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_NON_CA; + } else + ret = 1; + break; + default: + if ((ret == 0) + || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1))) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + break; + } + if (ret == 0) { + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + if (ctx->param->purpose > 0) { + ret = X509_check_purpose(x, purpose, must_be_ca > 0); + if ((ret == 0) + || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1))) { + ctx->error = X509_V_ERR_INVALID_PURPOSE; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + } + /* Check pathlen */ + if ((i > 1) && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length))) { + ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + /* Increment path length if not a self issued intermediate CA */ + if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0) + plen++; + /* + * If this certificate is a proxy certificate, the next certificate + * must be another proxy certificate or a EE certificate. If not, + * the next certificate must be a CA certificate. + */ + if (x->ex_flags & EXFLAG_PROXY) { + /* + * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint + * is less than max_path_length, the former should be copied to + * the latter, and 4.1.4 (a) stipulates that max_path_length + * should be verified to be larger than zero and decrement it. + * + * Because we're checking the certs in the reverse order, we start + * with verifying that proxy_path_length isn't larger than pcPLC, + * and copy the latter to the former if it is, and finally, + * increment proxy_path_length. + */ + if (x->ex_pcpathlen != -1) { + if (proxy_path_length > x->ex_pcpathlen) { + ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + proxy_path_length = x->ex_pcpathlen; + } + proxy_path_length++; + must_be_ca = 0; + } else + must_be_ca = 1; + } + ok = 1; + end: + return ok; +#endif +} + +static int check_name_constraints(X509_STORE_CTX *ctx) +{ + X509 *x; + int i, j, rv; + /* Check name constraints for all certificates */ + for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) { + x = sk_X509_value(ctx->chain, i); + /* Ignore self issued certs unless last in chain */ + if (i && (x->ex_flags & EXFLAG_SI)) + continue; + + /* + * Proxy certificates policy has an extra constraint, where the + * certificate subject MUST be the issuer with a single CN entry + * added. + * (RFC 3820: 3.4, 4.1.3 (a)(4)) + */ + if (x->ex_flags & EXFLAG_PROXY) { + X509_NAME *tmpsubject = X509_get_subject_name(x); + X509_NAME *tmpissuer = X509_get_issuer_name(x); + X509_NAME_ENTRY *tmpentry = NULL; + int last_object_nid = 0; + int err = X509_V_OK; + int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1; + + /* Check that there are at least two RDNs */ + if (last_object_loc < 1) { + err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; + goto proxy_name_done; + } + + /* + * Check that there is exactly one more RDN in subject as + * there is in issuer. + */ + if (X509_NAME_entry_count(tmpsubject) + != X509_NAME_entry_count(tmpissuer) + 1) { + err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; + goto proxy_name_done; + } + + /* + * Check that the last subject component isn't part of a + * multivalued RDN + */ + if (X509_NAME_get_entry(tmpsubject, last_object_loc)->set + == X509_NAME_get_entry(tmpsubject, last_object_loc - 1)->set) { + err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; + goto proxy_name_done; + } + + /* + * Check that the last subject RDN is a commonName, and that + * all the previous RDNs match the issuer exactly + */ + tmpsubject = X509_NAME_dup(tmpsubject); + if (tmpsubject == NULL) { + X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + return 0; + } + + tmpentry = + X509_NAME_delete_entry(tmpsubject, last_object_loc); + last_object_nid = + OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry)); + + if (last_object_nid != NID_commonName + || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) { + err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; + } + + X509_NAME_ENTRY_free(tmpentry); + X509_NAME_free(tmpsubject); + + proxy_name_done: + if (err != X509_V_OK) { + ctx->error = err; + ctx->error_depth = i; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + + /* + * Check against constraints for all certificates higher in chain + * including trust anchor. Trust anchor not strictly speaking needed + * but if it includes constraints it is to be assumed it expects them + * to be obeyed. + */ + for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) { + NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; + if (nc) { + rv = NAME_CONSTRAINTS_check(x, nc); + switch (rv) { + case X509_V_OK: + continue; + case X509_V_ERR_OUT_OF_MEM: + ctx->error = rv; + return 0; + default: + ctx->error = rv; + ctx->error_depth = i; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + break; + } + } + } + } + return 1; +} + +static int check_id_error(X509_STORE_CTX *ctx, int errcode) +{ + ctx->error = errcode; + ctx->current_cert = ctx->cert; + ctx->error_depth = 0; + return ctx->verify_cb(0, ctx); +} + +static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id) +{ + int i; + int n = sk_OPENSSL_STRING_num(id->hosts); + char *name; + + if (id->peername != NULL) { + OPENSSL_free(id->peername); + id->peername = NULL; + } + for (i = 0; i < n; ++i) { + name = sk_OPENSSL_STRING_value(id->hosts, i); + if (X509_check_host(x, name, 0, id->hostflags, &id->peername) > 0) + return 1; + } + return n == 0; +} + +static int check_id(X509_STORE_CTX *ctx) +{ + X509_VERIFY_PARAM *vpm = ctx->param; + X509_VERIFY_PARAM_ID *id = vpm->id; + X509 *x = ctx->cert; + if (id->hosts && check_hosts(x, id) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) + return 0; + } + if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) + return 0; + } + if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) { + if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) + return 0; + } + return 1; +} + +static int check_trust(X509_STORE_CTX *ctx) +{ + int i, ok; + X509 *x = NULL; + int (*cb) (int xok, X509_STORE_CTX *xctx); + cb = ctx->verify_cb; + /* Check all trusted certificates in chain */ + for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) { + x = sk_X509_value(ctx->chain, i); + ok = X509_check_trust(x, ctx->param->trust, 0); + /* If explicitly trusted return trusted */ + if (ok == X509_TRUST_TRUSTED) + return X509_TRUST_TRUSTED; + /* + * If explicitly rejected notify callback and reject if not + * overridden. + */ + if (ok == X509_TRUST_REJECTED) { + ctx->error_depth = i; + ctx->current_cert = x; + ctx->error = X509_V_ERR_CERT_REJECTED; + ok = cb(0, ctx); + if (!ok) + return X509_TRUST_REJECTED; + } + } + /* + * If we accept partial chains and have at least one trusted certificate + * return success. + */ + if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + X509 *mx; + if (ctx->last_untrusted < sk_X509_num(ctx->chain)) + return X509_TRUST_TRUSTED; + x = sk_X509_value(ctx->chain, 0); + mx = lookup_cert_match(ctx, x); + if (mx) { + (void)sk_X509_set(ctx->chain, 0, mx); + X509_free(x); + ctx->last_untrusted = 0; + return X509_TRUST_TRUSTED; + } + } + + /* + * If no trusted certs in chain at all return untrusted and allow + * standard (no issuer cert) etc errors to be indicated. + */ + return X509_TRUST_UNTRUSTED; +} + +static int check_revocation(X509_STORE_CTX *ctx) +{ + int i, last, ok; + if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) + return 1; + if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) + last = sk_X509_num(ctx->chain) - 1; + else { + /* If checking CRL paths this isn't the EE certificate */ + if (ctx->parent) + return 1; + last = 0; + } + for (i = 0; i <= last; i++) { + ctx->error_depth = i; + ok = check_cert(ctx); + if (!ok) + return ok; + } + return 1; +} + +static int check_cert(X509_STORE_CTX *ctx) +{ + X509_CRL *crl = NULL, *dcrl = NULL; + X509 *x; + int ok, cnum; + unsigned int last_reasons; + cnum = ctx->error_depth; + x = sk_X509_value(ctx->chain, cnum); + ctx->current_cert = x; + ctx->current_issuer = NULL; + ctx->current_crl_score = 0; + ctx->current_reasons = 0; + if (x->ex_flags & EXFLAG_PROXY) + return 1; + while (ctx->current_reasons != CRLDP_ALL_REASONS) { + last_reasons = ctx->current_reasons; + /* Try to retrieve relevant CRL */ + if (ctx->get_crl) + ok = ctx->get_crl(ctx, &crl, x); + else + ok = get_crl_delta(ctx, &crl, &dcrl, x); + /* + * If error looking up CRL, nothing we can do except notify callback + */ + if (!ok) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + ctx->current_crl = crl; + ok = ctx->check_crl(ctx, crl); + if (!ok) + goto err; + + if (dcrl) { + ok = ctx->check_crl(ctx, dcrl); + if (!ok) + goto err; + ok = ctx->cert_crl(ctx, dcrl, x); + if (!ok) + goto err; + } else + ok = 1; + + /* Don't look in full CRL if delta reason is removefromCRL */ + if (ok != 2) { + ok = ctx->cert_crl(ctx, crl, x); + if (!ok) + goto err; + } + + X509_CRL_free(crl); + X509_CRL_free(dcrl); + crl = NULL; + dcrl = NULL; + /* + * If reasons not updated we wont get anywhere by another iteration, + * so exit loop. + */ + if (last_reasons == ctx->current_reasons) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + } + err: + X509_CRL_free(crl); + X509_CRL_free(dcrl); + + ctx->current_crl = NULL; + return ok; + +} + +/* Check CRL times against values in X509_STORE_CTX */ + +static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) +{ + time_t *ptime; + int i; + if (notify) + ctx->current_crl = crl; + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else + ptime = NULL; + + i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (X509_CRL_get_nextUpdate(crl)) { + i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); + + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + /* Ignore expiry of base CRL is delta is valid */ + if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + + if (notify) + ctx->current_crl = NULL; + + return 1; +} + +static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, + X509 **pissuer, int *pscore, unsigned int *preasons, + STACK_OF(X509_CRL) *crls) +{ + int i, crl_score, best_score = *pscore; + unsigned int reasons, best_reasons = 0; + X509 *x = ctx->current_cert; + X509_CRL *crl, *best_crl = NULL; + X509 *crl_issuer = NULL, *best_crl_issuer = NULL; + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + crl = sk_X509_CRL_value(crls, i); + reasons = *preasons; + crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); + if (crl_score < best_score || crl_score == 0) + continue; + /* If current CRL is equivalent use it if it is newer */ + if (crl_score == best_score && best_crl != NULL) { + int day, sec; + if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl), + X509_CRL_get_lastUpdate(crl)) == 0) + continue; + /* + * ASN1_TIME_diff never returns inconsistent signs for |day| + * and |sec|. + */ + if (day <= 0 && sec <= 0) + continue; + } + best_crl = crl; + best_crl_issuer = crl_issuer; + best_score = crl_score; + best_reasons = reasons; + } + + if (best_crl) { + if (*pcrl) + X509_CRL_free(*pcrl); + *pcrl = best_crl; + *pissuer = best_crl_issuer; + *pscore = best_score; + *preasons = best_reasons; + CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); + if (*pdcrl) { + X509_CRL_free(*pdcrl); + *pdcrl = NULL; + } + get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); + } + + if (best_score >= CRL_SCORE_VALID) + return 1; + + return 0; +} + +/* + * Compare two CRL extensions for delta checking purposes. They should be + * both present or both absent. If both present all fields must be identical. + */ + +static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) +{ + ASN1_OCTET_STRING *exta, *extb; + int i; + i = X509_CRL_get_ext_by_NID(a, nid, -1); + if (i >= 0) { + /* Can't have multiple occurrences */ + if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) + return 0; + exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); + } else + exta = NULL; + + i = X509_CRL_get_ext_by_NID(b, nid, -1); + + if (i >= 0) { + + if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) + return 0; + extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); + } else + extb = NULL; + + if (!exta && !extb) + return 1; + + if (!exta || !extb) + return 0; + + if (ASN1_OCTET_STRING_cmp(exta, extb)) + return 0; + + return 1; +} + +/* See if a base and delta are compatible */ + +static int check_delta_base(X509_CRL *delta, X509_CRL *base) +{ + /* Delta CRL must be a delta */ + if (!delta->base_crl_number) + return 0; + /* Base must have a CRL number */ + if (!base->crl_number) + return 0; + /* Issuer names must match */ + if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) + return 0; + /* AKID and IDP must match */ + if (!crl_extension_match(delta, base, NID_authority_key_identifier)) + return 0; + if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) + return 0; + /* Delta CRL base number must not exceed Full CRL number. */ + if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) + return 0; + /* Delta CRL number must exceed full CRL number */ + if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) + return 1; + return 0; +} + +/* + * For a given base CRL find a delta... maybe extend to delta scoring or + * retrieve a chain of deltas... + */ + +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, + X509_CRL *base, STACK_OF(X509_CRL) *crls) +{ + X509_CRL *delta; + int i; + if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) + return; + if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) + return; + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + delta = sk_X509_CRL_value(crls, i); + if (check_delta_base(delta, base)) { + if (check_crl_time(ctx, delta, 0)) + *pscore |= CRL_SCORE_TIME_DELTA; + CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); + *dcrl = delta; + return; + } + } + *dcrl = NULL; +} + +/* + * For a given CRL return how suitable it is for the supplied certificate + * 'x'. The return value is a mask of several criteria. If the issuer is not + * the certificate issuer this is returned in *pissuer. The reasons mask is + * also used to determine if the CRL is suitable: if no new reasons the CRL + * is rejected, otherwise reasons is updated. + */ + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, X509_CRL *crl, X509 *x) +{ + + int crl_score = 0; + unsigned int tmp_reasons = *preasons, crl_reasons; + + /* First see if we can reject CRL straight away */ + + /* Invalid IDP cannot be processed */ + if (crl->idp_flags & IDP_INVALID) + return 0; + /* Reason codes or indirect CRLs need extended CRL support */ + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { + if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) + return 0; + } else if (crl->idp_flags & IDP_REASONS) { + /* If no new reasons reject */ + if (!(crl->idp_reasons & ~tmp_reasons)) + return 0; + } + /* Don't process deltas at this stage */ + else if (crl->base_crl_number) + return 0; + /* If issuer name doesn't match certificate need indirect CRL */ + if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { + if (!(crl->idp_flags & IDP_INDIRECT)) + return 0; + } else + crl_score |= CRL_SCORE_ISSUER_NAME; + + if (!(crl->flags & EXFLAG_CRITICAL)) + crl_score |= CRL_SCORE_NOCRITICAL; + + /* Check expiry */ + if (check_crl_time(ctx, crl, 0)) + crl_score |= CRL_SCORE_TIME; + + /* Check authority key ID and locate certificate issuer */ + crl_akid_check(ctx, crl, pissuer, &crl_score); + + /* If we can't locate certificate issuer at this point forget it */ + + if (!(crl_score & CRL_SCORE_AKID)) + return 0; + + /* Check cert for matching CRL distribution points */ + + if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { + /* If no new reasons reject */ + if (!(crl_reasons & ~tmp_reasons)) + return 0; + tmp_reasons |= crl_reasons; + crl_score |= CRL_SCORE_SCOPE; + } + + *preasons = tmp_reasons; + + return crl_score; + +} + +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, + X509 **pissuer, int *pcrl_score) +{ + X509 *crl_issuer = NULL; + X509_NAME *cnm = X509_CRL_get_issuer(crl); + int cidx = ctx->error_depth; + int i; + + if (cidx != sk_X509_num(ctx->chain) - 1) + cidx++; + + crl_issuer = sk_X509_value(ctx->chain, cidx); + + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { + *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT; + *pissuer = crl_issuer; + return; + } + } + + for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { + crl_issuer = sk_X509_value(ctx->chain, cidx); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH; + *pissuer = crl_issuer; + return; + } + } + + /* Anything else needs extended CRL support */ + + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) + return; + + /* + * Otherwise the CRL issuer is not on the path. Look for it in the set of + * untrusted certificates. + */ + for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { + crl_issuer = sk_X509_value(ctx->untrusted, i); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pissuer = crl_issuer; + *pcrl_score |= CRL_SCORE_AKID; + return; + } + } +} + +/* + * Check the path of a CRL issuer certificate. This creates a new + * X509_STORE_CTX and populates it with most of the parameters from the + * parent. This could be optimised somewhat since a lot of path checking will + * be duplicated by the parent, but this will rarely be used in practice. + */ + +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) +{ + X509_STORE_CTX crl_ctx; + int ret; + /* Don't allow recursive CRL path validation */ + if (ctx->parent) + return 0; + if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) + return -1; + + crl_ctx.crls = ctx->crls; + /* Copy verify params across */ + X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); + + crl_ctx.parent = ctx; + crl_ctx.verify_cb = ctx->verify_cb; + + /* Verify CRL issuer */ + ret = X509_verify_cert(&crl_ctx); + + if (ret <= 0) + goto err; + + /* Check chain is acceptable */ + + ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); + err: + X509_STORE_CTX_cleanup(&crl_ctx); + return ret; +} + +/* + * RFC3280 says nothing about the relationship between CRL path and + * certificate path, which could lead to situations where a certificate could + * be revoked or validated by a CA not authorised to do so. RFC5280 is more + * strict and states that the two paths must end in the same trust anchor, + * though some discussions remain... until this is resolved we use the + * RFC5280 version + */ + +static int check_crl_chain(X509_STORE_CTX *ctx, + STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path) +{ + X509 *cert_ta, *crl_ta; + cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); + crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); + if (!X509_cmp(cert_ta, crl_ta)) + return 1; + return 0; +} + +/*- + * Check for match between two dist point names: three separate cases. + * 1. Both are relative names and compare X509_NAME types. + * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. + * 3. Both are full names and compare two GENERAL_NAMES. + * 4. One is NULL: automatic match. + */ + +static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) +{ + X509_NAME *nm = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gena, *genb; + int i, j; + if (!a || !b) + return 1; + if (a->type == 1) { + if (!a->dpname) + return 0; + /* Case 1: two X509_NAME */ + if (b->type == 1) { + if (!b->dpname) + return 0; + if (!X509_NAME_cmp(a->dpname, b->dpname)) + return 1; + else + return 0; + } + /* Case 2: set name and GENERAL_NAMES appropriately */ + nm = a->dpname; + gens = b->name.fullname; + } else if (b->type == 1) { + if (!b->dpname) + return 0; + /* Case 2: set name and GENERAL_NAMES appropriately */ + gens = a->name.fullname; + nm = b->dpname; + } + + /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ + if (nm) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gena = sk_GENERAL_NAME_value(gens, i); + if (gena->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gena->d.directoryName)) + return 1; + } + return 0; + } + + /* Else case 3: two GENERAL_NAMES */ + + for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { + gena = sk_GENERAL_NAME_value(a->name.fullname, i); + for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { + genb = sk_GENERAL_NAME_value(b->name.fullname, j); + if (!GENERAL_NAME_cmp(gena, genb)) + return 1; + } + } + + return 0; + +} + +static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) +{ + int i; + X509_NAME *nm = X509_CRL_get_issuer(crl); + /* If no CRLissuer return is successful iff don't need a match */ + if (!dp->CRLissuer) + return ! !(crl_score & CRL_SCORE_ISSUER_NAME); + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(gen->d.directoryName, nm)) + return 1; + } + return 0; +} + +/* Check CRLDP and IDP */ + +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons) +{ + int i; + if (crl->idp_flags & IDP_ONLYATTR) + return 0; + if (x->ex_flags & EXFLAG_CA) { + if (crl->idp_flags & IDP_ONLYUSER) + return 0; + } else { + if (crl->idp_flags & IDP_ONLYCA) + return 0; + } + *preasons = crl->idp_reasons; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { + DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); + if (crldp_check_crlissuer(dp, crl, crl_score)) { + if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { + *preasons &= dp->dp_reasons; + return 1; + } + } + } + if ((!crl->idp || !crl->idp->distpoint) + && (crl_score & CRL_SCORE_ISSUER_NAME)) + return 1; + return 0; +} + +/* + * Retrieve CRL corresponding to current certificate. If deltas enabled try + * to find a delta CRL too + */ + +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) +{ + int ok; + X509 *issuer = NULL; + int crl_score = 0; + unsigned int reasons; + X509_CRL *crl = NULL, *dcrl = NULL; + STACK_OF(X509_CRL) *skcrl; + X509_NAME *nm = X509_get_issuer_name(x); + reasons = ctx->current_reasons; + ok = get_crl_sk(ctx, &crl, &dcrl, + &issuer, &crl_score, &reasons, ctx->crls); + + if (ok) + goto done; + + /* Lookup CRLs from store */ + + skcrl = ctx->lookup_crls(ctx, nm); + + /* If no CRLs found and a near match from get_crl_sk use that */ + if (!skcrl && crl) + goto done; + + get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); + + sk_X509_CRL_pop_free(skcrl, X509_CRL_free); + + done: + + /* If we got any kind of CRL use it and return success */ + if (crl) { + ctx->current_issuer = issuer; + ctx->current_crl_score = crl_score; + ctx->current_reasons = reasons; + *pcrl = crl; + *pdcrl = dcrl; + return 1; + } + + return 0; +} + +/* Check CRL validity */ +static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) +{ + X509 *issuer = NULL; + EVP_PKEY *ikey = NULL; + int ok = 0, chnum, cnum; + cnum = ctx->error_depth; + chnum = sk_X509_num(ctx->chain) - 1; + /* if we have an alternative CRL issuer cert use that */ + if (ctx->current_issuer) + issuer = ctx->current_issuer; + + /* + * Else find CRL issuer: if not last certificate then issuer is next + * certificate in chain. + */ + else if (cnum < chnum) + issuer = sk_X509_value(ctx->chain, cnum + 1); + else { + issuer = sk_X509_value(ctx->chain, chnum); + /* If not self signed, can't check signature */ + if (!ctx->check_issued(ctx, issuer, issuer)) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (issuer) { + /* + * Skip most tests for deltas because they have already been done + */ + if (!crl->base_crl_number) { + /* Check for cRLSign bit if keyUsage present */ + if ((issuer->ex_flags & EXFLAG_KUSAGE) && + !(issuer->ex_kusage & KU_CRL_SIGN)) { + ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { + ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { + if (check_crl_path(ctx, ctx->current_issuer) <= 0) { + ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (crl->idp_flags & IDP_INVALID) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + } + + if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { + ok = check_crl_time(ctx, crl, 1); + if (!ok) + goto err; + } + + /* Attempt to get issuer certificate public key */ + ikey = X509_get_pubkey(issuer); + + if (!ikey) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } else { + int rv; + rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags); + if (rv != X509_V_OK) { + ctx->error = rv; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + /* Verify CRL signature */ + if (X509_CRL_verify(crl, ikey) <= 0) { + ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + } + + ok = 1; + + err: + EVP_PKEY_free(ikey); + return ok; +} + +/* Check certificate against CRL */ +static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) +{ + int ok; + X509_REVOKED *rev; + /* + * The rules changed for this... previously if a CRL contained unhandled + * critical extensions it could still be used to indicate a certificate + * was revoked. This has since been changed since critical extension can + * change the meaning of CRL entries. + */ + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + && (crl->flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + /* + * Look for serial number of certificate in CRL If found make sure reason + * is not removeFromCRL. + */ + if (X509_CRL_get0_by_cert(crl, &rev, x)) { + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + ctx->error = X509_V_ERR_CERT_REVOKED; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + + return 1; +} + +static int check_policy(X509_STORE_CTX *ctx) +{ + int ret; + if (ctx->parent) + return 1; + ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, + ctx->param->policies, ctx->param->flags); + if (ret == 0) { + X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + return 0; + } + /* Invalid or inconsistent extensions */ + if (ret == -1) { + /* + * Locate certificates with bad extensions and notify callback. + */ + X509 *x; + int i; + for (i = 1; i < sk_X509_num(ctx->chain); i++) { + x = sk_X509_value(ctx->chain, i); + if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) + continue; + ctx->current_cert = x; + ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + return 1; + } + if (ret == -2) { + ctx->current_cert = NULL; + ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; + return ctx->verify_cb(0, ctx); + } + + if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { + ctx->current_cert = NULL; + /* + * Verification errors need to be "sticky", a callback may have allowed + * an SSL handshake to continue despite an error, and we must then + * remain in an error state. Therefore, we MUST NOT clear earlier + * verification errors by setting the error to X509_V_OK. + */ + if (!ctx->verify_cb(2, ctx)) + return 0; + } + + return 1; +} + +static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) +{ + time_t *ptime; + int i; + + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else + ptime = NULL; + + i = X509_cmp_time(X509_get_notBefore(x), ptime); + if (i == 0) { + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + ctx->error = X509_V_ERR_CERT_NOT_YET_VALID; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + i = X509_cmp_time(X509_get_notAfter(x), ptime); + if (i == 0) { + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i < 0) { + ctx->error = X509_V_ERR_CERT_HAS_EXPIRED; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + return 1; +} + +static int internal_verify(X509_STORE_CTX *ctx) +{ + int ok = 0, n; + X509 *xs, *xi; + EVP_PKEY *pkey = NULL; + int (*cb) (int xok, X509_STORE_CTX *xctx); + + cb = ctx->verify_cb; + + n = sk_X509_num(ctx->chain); + ctx->error_depth = n - 1; + n--; + xi = sk_X509_value(ctx->chain, n); + + if (ctx->check_issued(ctx, xi, xi)) + xs = xi; + else { + if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { + xs = xi; + goto check_cert; + } + if (n <= 0) { + ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; + ctx->current_cert = xi; + ok = cb(0, ctx); + goto end; + } else { + n--; + ctx->error_depth = n; + xs = sk_X509_value(ctx->chain, n); + } + } + +/* ctx->error=0; not needed */ + while (n >= 0) { + ctx->error_depth = n; + + /* + * Skip signature check for self signed certificates unless + * explicitly asked for. It doesn't add any security and just wastes + * time. + */ + if (!xs->valid + && (xs != xi + || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) { + if ((pkey = X509_get_pubkey(xi)) == NULL) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ctx->current_cert = xi; + ok = (*cb) (0, ctx); + if (!ok) + goto end; + } else if (X509_verify(xs, pkey) <= 0) { + ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; + ctx->current_cert = xs; + ok = (*cb) (0, ctx); + if (!ok) { + EVP_PKEY_free(pkey); + goto end; + } + } + EVP_PKEY_free(pkey); + pkey = NULL; + } + + xs->valid = 1; + + check_cert: + ok = check_cert_time(ctx, xs); + if (!ok) + goto end; + + /* The last error (if any) is still in the error value */ + ctx->current_issuer = xi; + ctx->current_cert = xs; + ok = (*cb) (1, ctx); + if (!ok) + goto end; + + n--; + if (n >= 0) { + xi = xs; + xs = sk_X509_value(ctx->chain, n); + } + } + ok = 1; + end: + return ok; +} + +int X509_cmp_current_time(const ASN1_TIME *ctm) +{ + return X509_cmp_time(ctm, NULL); +} + +int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) +{ + static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1; + static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1; + ASN1_TIME *asn1_cmp_time = NULL; + int i, day, sec, ret = 0; + + /* + * Note that ASN.1 allows much more slack in the time format than RFC5280. + * In RFC5280, the representation is fixed: + * UTCTime: YYMMDDHHMMSSZ + * GeneralizedTime: YYYYMMDDHHMMSSZ + * + * We do NOT currently enforce the following RFC 5280 requirement: + * "CAs conforming to this profile MUST always encode certificate + * validity dates through the year 2049 as UTCTime; certificate validity + * dates in 2050 or later MUST be encoded as GeneralizedTime." + */ + switch (ctm->type) { + case V_ASN1_UTCTIME: + if (ctm->length != (int)(utctime_length)) + return 0; + break; + case V_ASN1_GENERALIZEDTIME: + if (ctm->length != (int)(generalizedtime_length)) + return 0; + break; + default: + return 0; + } + + /** + * Verify the format: the ASN.1 functions we use below allow a more + * flexible format than what's mandated by RFC 5280. + * Digit and date ranges will be verified in the conversion methods. + */ + for (i = 0; i < ctm->length - 1; i++) { + if (!isdigit(ctm->data[i])) + return 0; + } + if (ctm->data[ctm->length - 1] != 'Z') + return 0; + + /* + * There is ASN1_UTCTIME_cmp_time_t but no + * ASN1_GENERALIZEDTIME_cmp_time_t or ASN1_TIME_cmp_time_t, + * so we go through ASN.1 + */ + asn1_cmp_time = X509_time_adj(NULL, 0, cmp_time); + if (asn1_cmp_time == NULL) + goto err; + if (!ASN1_TIME_diff(&day, &sec, ctm, asn1_cmp_time)) + goto err; + + /* + * X509_cmp_time comparison is <=. + * The return value 0 is reserved for errors. + */ + ret = (day >= 0 && sec >= 0) ? -1 : 1; + + err: + ASN1_TIME_free(asn1_cmp_time); + return ret; +} + +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) +{ + return X509_time_adj(s, adj, NULL); +} + +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) +{ + return X509_time_adj_ex(s, 0, offset_sec, in_tm); +} + +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *in_tm) +{ + time_t t; + + if (in_tm) + t = *in_tm; + else + time(&t); + + if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) { + if (s->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); + if (s->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); + } + return ASN1_TIME_adj(s, t, offset_day, offset_sec); +} + +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) +{ + EVP_PKEY *ktmp = NULL, *ktmp2; + int i, j; + + if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) + return 1; + + for (i = 0; i < sk_X509_num(chain); i++) { + ktmp = X509_get_pubkey(sk_X509_value(chain, i)); + if (ktmp == NULL) { + X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, + X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); + return 0; + } + if (!EVP_PKEY_missing_parameters(ktmp)) + break; + else { + EVP_PKEY_free(ktmp); + ktmp = NULL; + } + } + if (ktmp == NULL) { + X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, + X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); + return 0; + } + + /* first, populate the other certs */ + for (j = i - 1; j >= 0; j--) { + ktmp2 = X509_get_pubkey(sk_X509_value(chain, j)); + EVP_PKEY_copy_parameters(ktmp2, ktmp); + EVP_PKEY_free(ktmp2); + } + + if (pkey != NULL) + EVP_PKEY_copy_parameters(pkey, ktmp); + EVP_PKEY_free(ktmp); + return 1; +} + +/* Make a delta CRL as the diff between two full CRLs */ + +X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags) +{ + X509_CRL *crl = NULL; + int i; + STACK_OF(X509_REVOKED) *revs = NULL; + /* CRLs can't be delta already */ + if (base->base_crl_number || newer->base_crl_number) { + X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_ALREADY_DELTA); + return NULL; + } + /* Base and new CRL must have a CRL number */ + if (!base->crl_number || !newer->crl_number) { + X509err(X509_F_X509_CRL_DIFF, X509_R_NO_CRL_NUMBER); + return NULL; + } + /* Issuer names must match */ + if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) { + X509err(X509_F_X509_CRL_DIFF, X509_R_ISSUER_MISMATCH); + return NULL; + } + /* AKID and IDP must match */ + if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { + X509err(X509_F_X509_CRL_DIFF, X509_R_AKID_MISMATCH); + return NULL; + } + if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { + X509err(X509_F_X509_CRL_DIFF, X509_R_IDP_MISMATCH); + return NULL; + } + /* Newer CRL number must exceed full CRL number */ + if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) { + X509err(X509_F_X509_CRL_DIFF, X509_R_NEWER_CRL_NOT_NEWER); + return NULL; + } + /* CRLs must verify */ + if (skey && (X509_CRL_verify(base, skey) <= 0 || + X509_CRL_verify(newer, skey) <= 0)) { + X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_VERIFY_FAILURE); + return NULL; + } + /* Create new CRL */ + crl = X509_CRL_new(); + if (!crl || !X509_CRL_set_version(crl, 1)) + goto memerr; + /* Set issuer name */ + if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) + goto memerr; + + if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer))) + goto memerr; + if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer))) + goto memerr; + + /* Set base CRL number: must be critical */ + + if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) + goto memerr; + + /* + * Copy extensions across from newest CRL to delta: this will set CRL + * number to correct value too. + */ + + for (i = 0; i < X509_CRL_get_ext_count(newer); i++) { + X509_EXTENSION *ext; + ext = X509_CRL_get_ext(newer, i); + if (!X509_CRL_add_ext(crl, ext, -1)) + goto memerr; + } + + /* Go through revoked entries, copying as needed */ + + revs = X509_CRL_get_REVOKED(newer); + + for (i = 0; i < sk_X509_REVOKED_num(revs); i++) { + X509_REVOKED *rvn, *rvtmp; + rvn = sk_X509_REVOKED_value(revs, i); + /* + * Add only if not also in base. TODO: need something cleverer here + * for some more complex CRLs covering multiple CAs. + */ + if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) { + rvtmp = X509_REVOKED_dup(rvn); + if (!rvtmp) + goto memerr; + if (!X509_CRL_add0_revoked(crl, rvtmp)) { + X509_REVOKED_free(rvtmp); + goto memerr; + } + } + } + /* TODO: optionally prune deleted entries */ + + if (skey && md && !X509_CRL_sign(crl, skey, md)) + goto memerr; + + return crl; + + memerr: + X509err(X509_F_X509_CRL_DIFF, ERR_R_MALLOC_FAILURE); + if (crl) + X509_CRL_free(crl); + return NULL; +} + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + /* + * This function is (usually) called only once, by + * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). + */ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp, + new_func, dup_func, free_func); +} + +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) +{ + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +} + +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) +{ + return CRYPTO_get_ex_data(&ctx->ex_data, idx); +} + +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) +{ + return ctx->error; +} + +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) +{ + ctx->error = err; +} + +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) +{ + return ctx->error_depth; +} + +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) +{ + return ctx->current_cert; +} + +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) +{ + return ctx->chain; +} + +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) +{ + if (!ctx->chain) + return NULL; + return X509_chain_up_ref(ctx->chain); +} + +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) +{ + return ctx->current_issuer; +} + +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) +{ + return ctx->current_crl; +} + +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) +{ + return ctx->parent; +} + +void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) +{ + ctx->cert = x; +} + +void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->untrusted = sk; +} + +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) +{ + ctx->crls = sk; +} + +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); +} + +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); +} + +/* + * This function is used to set the X509_STORE_CTX purpose and trust values. + * This is intended to be used when another structure has its own trust and + * purpose values which (if set) will be inherited by the ctx. If they aren't + * set then we will usually have a default purpose in mind which should then + * be used to set the trust value. An example of this is SSL use: an SSL + * structure will have its own purpose and trust settings which the + * application can set: if they aren't set then we use the default of SSL + * client/server. + */ + +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust) +{ + int idx; + /* If purpose not set use default */ + if (!purpose) + purpose = def_purpose; + /* If we have a purpose then check it is valid */ + if (purpose) { + X509_PURPOSE *ptmp; + idx = X509_PURPOSE_get_by_id(purpose); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + if (ptmp->trust == X509_TRUST_DEFAULT) { + idx = X509_PURPOSE_get_by_id(def_purpose); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + } + /* If trust not set then get from purpose default */ + if (!trust) + trust = ptmp->trust; + } + if (trust) { + idx = X509_TRUST_get_by_id(trust); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_TRUST_ID); + return 0; + } + } + + if (purpose && !ctx->param->purpose) + ctx->param->purpose = purpose; + if (trust && !ctx->param->trust) + ctx->param->trust = trust; + return 1; +} + +X509_STORE_CTX *X509_STORE_CTX_new(void) +{ + X509_STORE_CTX *ctx; + ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); + if (!ctx) { + X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ctx, 0, sizeof(X509_STORE_CTX)); + return ctx; +} + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx) +{ + if (!ctx) + return; + X509_STORE_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, + STACK_OF(X509) *chain) +{ + int ret = 1; + ctx->ctx = store; + ctx->current_method = 0; + ctx->cert = x509; + ctx->untrusted = chain; + ctx->crls = NULL; + ctx->last_untrusted = 0; + ctx->other_ctx = NULL; + ctx->valid = 0; + ctx->chain = NULL; + ctx->error = 0; + ctx->explicit_policy = 0; + ctx->error_depth = 0; + ctx->current_cert = NULL; + ctx->current_issuer = NULL; + ctx->current_crl = NULL; + ctx->current_crl_score = 0; + ctx->current_reasons = 0; + ctx->tree = NULL; + ctx->parent = NULL; + /* Zero ex_data to make sure we're cleanup-safe */ + memset(&ctx->ex_data, 0, sizeof(ctx->ex_data)); + + ctx->param = X509_VERIFY_PARAM_new(); + if (!ctx->param) { + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* + * Inherit callbacks and flags from X509_STORE if not set use defaults. + */ + if (store) + ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); + else + ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE; + + if (store) { + ctx->verify_cb = store->verify_cb; + /* Seems to always be 0 in OpenSSL, else must be idempotent */ + ctx->cleanup = store->cleanup; + } else + ctx->cleanup = 0; + + if (ret) + ret = X509_VERIFY_PARAM_inherit(ctx->param, + X509_VERIFY_PARAM_lookup("default")); + + if (ret == 0) { + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (store && store->check_issued) + ctx->check_issued = store->check_issued; + else + ctx->check_issued = check_issued; + + if (store && store->get_issuer) + ctx->get_issuer = store->get_issuer; + else + ctx->get_issuer = X509_STORE_CTX_get1_issuer; + + if (store && store->verify_cb) + ctx->verify_cb = store->verify_cb; + else + ctx->verify_cb = null_callback; + + if (store && store->verify) + ctx->verify = store->verify; + else + ctx->verify = internal_verify; + + if (store && store->check_revocation) + ctx->check_revocation = store->check_revocation; + else + ctx->check_revocation = check_revocation; + + if (store && store->get_crl) + ctx->get_crl = store->get_crl; + else + ctx->get_crl = NULL; + + if (store && store->check_crl) + ctx->check_crl = store->check_crl; + else + ctx->check_crl = check_crl; + + if (store && store->cert_crl) + ctx->cert_crl = store->cert_crl; + else + ctx->cert_crl = cert_crl; + + if (store && store->lookup_certs) + ctx->lookup_certs = store->lookup_certs; + else + ctx->lookup_certs = X509_STORE_get1_certs; + + if (store && store->lookup_crls) + ctx->lookup_crls = store->lookup_crls; + else + ctx->lookup_crls = X509_STORE_get1_crls; + + ctx->check_policy = check_policy; + + if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, + &ctx->ex_data)) + return 1; + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + + err: + /* + * On error clean up allocated storage, if the store context was not + * allocated with X509_STORE_CTX_new() this is our last chance to do so. + */ + X509_STORE_CTX_cleanup(ctx); + return 0; +} + +/* + * Set alternative lookup method: just a STACK of trusted certificates. This + * avoids X509_STORE nastiness where it isn't needed. + */ + +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->other_ctx = sk; + ctx->get_issuer = get_issuer_sk; +} + +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) +{ + /* + * We need to be idempotent because, unfortunately, free() also calls + * cleanup(), so the natural call sequence new(), init(), cleanup(), free() + * calls cleanup() for the same object twice! Thus we must zero the + * pointers below after they're freed! + */ + /* Seems to always be 0 in OpenSSL, do this at most once. */ + if (ctx->cleanup != NULL) { + ctx->cleanup(ctx); + ctx->cleanup = NULL; + } + if (ctx->param != NULL) { + if (ctx->parent == NULL) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = NULL; + } + if (ctx->tree != NULL) { + X509_policy_tree_free(ctx->tree); + ctx->tree = NULL; + } + if (ctx->chain != NULL) { + sk_X509_pop_free(ctx->chain, X509_free); + ctx->chain = NULL; + } + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); + memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); +} + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) +{ + X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t) +{ + X509_VERIFY_PARAM_set_time(ctx->param, t); +} + +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)) +{ + ctx->verify_cb = verify_cb; +} + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) +{ + return ctx->tree; +} + +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) +{ + return ctx->explicit_policy; +} + +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) +{ + const X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_lookup(name); + if (!param) + return 0; + return X509_VERIFY_PARAM_inherit(ctx->param, param); +} + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) +{ + return ctx->param; +} + +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) +{ + if (ctx->param) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = param; +} + +IMPLEMENT_STACK_OF(X509) + +IMPLEMENT_ASN1_SET_OF(X509) + +IMPLEMENT_STACK_OF(X509_NAME) + +IMPLEMENT_STACK_OF(X509_ATTRIBUTE) + +IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE) +/* x509_vpm.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +// #include "cryptlib.h" +// #include "crypto.h" +// #include "lhash.h" +// #include "buffer.h" +// #include "x509.h" +// #include "x509v3.h" + +// #include "vpm_int.h" + +/* X509_VERIFY_PARAM functions */ + +#define SET_HOST 0 +#define ADD_HOST 1 + +static char *str_copy(const char *s) +{ + return OPENSSL_strdup(s); +} + +static void str_free(char *s) +{ + OPENSSL_free(s); +} + +#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) + +static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode, + const char *name, size_t namelen) +{ + char *copy; + + /* + * Refuse names with embedded NUL bytes, except perhaps as final byte. + * XXX: Do we need to push an error onto the error stack? + */ + if (namelen == 0 || name == NULL) + namelen = name ? strlen(name) : 0; + else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen)) + return 0; + if (namelen > 0 && name[namelen - 1] == '\0') + --namelen; + + if (mode == SET_HOST && id->hosts) { + string_stack_free(id->hosts); + id->hosts = NULL; + } + if (name == NULL || namelen == 0) + return 1; + + copy = BUF_strndup(name, namelen); + if (copy == NULL) + return 0; + + if (id->hosts == NULL && + (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { + OPENSSL_free(copy); + return 0; + } + + if (!sk_OPENSSL_STRING_push(id->hosts, copy)) { + OPENSSL_free(copy); + if (sk_OPENSSL_STRING_num(id->hosts) == 0) { + sk_OPENSSL_STRING_free(id->hosts); + id->hosts = NULL; + } + return 0; + } + + return 1; +} + +static void x509_verify_param_zero(X509_VERIFY_PARAM *param) +{ + X509_VERIFY_PARAM_ID *paramid; + if (!param) + return; + param->name = NULL; + param->purpose = 0; + param->trust = 0; + /* + * param->inh_flags = X509_VP_FLAG_DEFAULT; + */ + param->inh_flags = 0; + param->flags = 0; + param->depth = -1; + if (param->policies) { + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + param->policies = NULL; + } + paramid = param->id; + if (paramid->hosts) { + string_stack_free(paramid->hosts); + paramid->hosts = NULL; + } + if (paramid->peername) + OPENSSL_free(paramid->peername); + paramid->peername = NULL; + if (paramid->email) { + OPENSSL_free(paramid->email); + paramid->email = NULL; + paramid->emaillen = 0; + } + if (paramid->ip) { + OPENSSL_free(paramid->ip); + paramid->ip = NULL; + paramid->iplen = 0; + } +} + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) +{ + X509_VERIFY_PARAM *param; + X509_VERIFY_PARAM_ID *paramid; + + param = OPENSSL_malloc(sizeof(*param)); + if (!param) + return NULL; + memset(param, 0, sizeof(*param)); + + paramid = OPENSSL_malloc(sizeof(*paramid)); + if (!paramid) { + OPENSSL_free(param); + return NULL; + } + memset(paramid, 0, sizeof(*paramid)); + /* Exotic platforms may have non-zero bit representation of NULL */ + paramid->hosts = NULL; + paramid->peername = NULL; + paramid->email = NULL; + paramid->ip = NULL; + + param->id = paramid; + x509_verify_param_zero(param); + return param; +} + +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) +{ + if (param == NULL) + return; + x509_verify_param_zero(param); + OPENSSL_free(param->id); + OPENSSL_free(param); +} + +/*- + * This function determines how parameters are "inherited" from one structure + * to another. There are several different ways this can happen. + * + * 1. If a child structure needs to have its values initialized from a parent + * they are simply copied across. For example SSL_CTX copied to SSL. + * 2. If the structure should take on values only if they are currently unset. + * For example the values in an SSL structure will take appropriate value + * for SSL servers or clients but only if the application has not set new + * ones. + * + * The "inh_flags" field determines how this function behaves. + * + * Normally any values which are set in the default are not copied from the + * destination and verify flags are ORed together. + * + * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied + * to the destination. Effectively the values in "to" become default values + * which will be used only if nothing new is set in "from". + * + * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether + * they are set or not. Flags is still Ored though. + * + * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead + * of ORed. + * + * If X509_VP_FLAG_LOCKED is set then no values are copied. + * + * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed + * after the next call. + */ + +/* Macro to test if a field should be copied from src to dest */ + +#define test_x509_verify_param_copy(field, def) \ + (to_overwrite || \ + ((src->field != def) && (to_default || (dest->field == def)))) + +/* As above but for ID fields */ + +#define test_x509_verify_param_copy_id(idf, def) \ + test_x509_verify_param_copy(id->idf, def) + +/* Macro to test and copy a field if necessary */ + +#define x509_verify_param_copy(field, def) \ + if (test_x509_verify_param_copy(field, def)) \ + dest->field = src->field + +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, + const X509_VERIFY_PARAM *src) +{ + unsigned long inh_flags; + int to_default, to_overwrite; + X509_VERIFY_PARAM_ID *id; + if (!src) + return 1; + id = src->id; + inh_flags = dest->inh_flags | src->inh_flags; + + if (inh_flags & X509_VP_FLAG_ONCE) + dest->inh_flags = 0; + + if (inh_flags & X509_VP_FLAG_LOCKED) + return 1; + + if (inh_flags & X509_VP_FLAG_DEFAULT) + to_default = 1; + else + to_default = 0; + + if (inh_flags & X509_VP_FLAG_OVERWRITE) + to_overwrite = 1; + else + to_overwrite = 0; + + x509_verify_param_copy(purpose, 0); + x509_verify_param_copy(trust, 0); + x509_verify_param_copy(depth, -1); + + /* If overwrite or check time not set, copy across */ + + if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { + dest->check_time = src->check_time; + dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; + /* Don't need to copy flag: that is done below */ + } + + if (inh_flags & X509_VP_FLAG_RESET_FLAGS) + dest->flags = 0; + + dest->flags |= src->flags; + + if (test_x509_verify_param_copy(policies, NULL)) { + if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) + return 0; + } + + /* Copy the host flags if and only if we're copying the host list */ + if (test_x509_verify_param_copy_id(hosts, NULL)) { + if (dest->id->hosts) { + string_stack_free(dest->id->hosts); + dest->id->hosts = NULL; + } + if (id->hosts) { + dest->id->hosts = + sk_OPENSSL_STRING_deep_copy(id->hosts, str_copy, str_free); + if (dest->id->hosts == NULL) + return 0; + dest->id->hostflags = id->hostflags; + } + } + + if (test_x509_verify_param_copy_id(email, NULL)) { + if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen)) + return 0; + } + + if (test_x509_verify_param_copy_id(ip, NULL)) { + if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen)) + return 0; + } + + return 1; +} + +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from) +{ + unsigned long save_flags = to->inh_flags; + int ret; + to->inh_flags |= X509_VP_FLAG_DEFAULT; + ret = X509_VERIFY_PARAM_inherit(to, from); + to->inh_flags = save_flags; + return ret; +} + +static int int_x509_param_set1(char **pdest, size_t *pdestlen, + const char *src, size_t srclen) +{ + void *tmp; + if (src) { + if (srclen == 0) { + tmp = BUF_strdup(src); + srclen = strlen(src); + } else + tmp = BUF_memdup(src, srclen); + if (!tmp) + return 0; + } else { + tmp = NULL; + srclen = 0; + } + if (*pdest) + OPENSSL_free(*pdest); + *pdest = tmp; + if (pdestlen) + *pdestlen = srclen; + return 1; +} + +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) +{ + if (param->name) + OPENSSL_free(param->name); + param->name = BUF_strdup(name); + if (param->name) + return 1; + return 0; +} + +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) +{ + param->flags |= flags; + if (flags & X509_V_FLAG_POLICY_MASK) + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; +} + +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags) +{ + param->flags &= ~flags; + return 1; +} + +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) +{ + return param->flags; +} + +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) +{ + return X509_PURPOSE_set(¶m->purpose, purpose); +} + +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) +{ + return X509_TRUST_set(¶m->trust, trust); +} + +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) +{ + param->depth = depth; +} + +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) +{ + param->check_time = t; + param->flags |= X509_V_FLAG_USE_CHECK_TIME; +} + +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy) +{ + if (!param->policies) { + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + } + if (!sk_ASN1_OBJECT_push(param->policies, policy)) + return 0; + return 1; +} + +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies) +{ + int i; + ASN1_OBJECT *oid, *doid; + if (!param) + return 0; + if (param->policies) + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + + if (!policies) { + param->policies = NULL; + return 1; + } + + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + + for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { + oid = sk_ASN1_OBJECT_value(policies, i); + doid = OBJ_dup(oid); + if (!doid) + return 0; + if (!sk_ASN1_OBJECT_push(param->policies, doid)) { + ASN1_OBJECT_free(doid); + return 0; + } + } + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; +} + +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen) +{ + return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen); +} + +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen) +{ + return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen); +} + +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags) +{ + param->id->hostflags = flags; +} + +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) +{ + return param->id->peername; +} + +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen) +{ + return int_x509_param_set1(¶m->id->email, ¶m->id->emaillen, + email, emaillen); +} + +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen) +{ + if (iplen != 0 && iplen != 4 && iplen != 16) + return 0; + return int_x509_param_set1((char **)¶m->id->ip, ¶m->id->iplen, + (char *)ip, iplen); +} + +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) +{ + unsigned char ipout[16]; + size_t iplen; + + iplen = (size_t)a2i_ipadd(ipout, ipasc); + if (iplen == 0) + return 0; + return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); +} + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) +{ + return param->depth; +} + +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) +{ + return param->name; +} + +static X509_VERIFY_PARAM_ID _empty_id = { NULL, 0U, NULL, NULL, 0, NULL, 0 }; + +#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id + +/* + * Default verify parameters: these are used for various applications and can + * be overridden by the user specified table. NB: the 'name' field *must* be + * in alphabetical order because it will be searched using OBJ_search. + */ + +static const X509_VERIFY_PARAM default_table[] = { + { + "default", /* X509 default parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + 0, /* purpose */ + 0, /* trust */ + 100, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + "pkcs7", /* S/MIME sign parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + "smime_sign", /* S/MIME sign parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + "ssl_client", /* SSL/TLS client parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_CLIENT, /* purpose */ + X509_TRUST_SSL_CLIENT, /* trust */ + -1, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + "ssl_server", /* SSL/TLS server parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_SERVER, /* purpose */ + X509_TRUST_SSL_SERVER, /* trust */ + -1, /* depth */ + NULL, /* policies */ + vpm_empty_id} +}; + +static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; + +static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) +{ + return strcmp(a->name, b->name); +} + +DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); + +static int param_cmp(const X509_VERIFY_PARAM *const *a, + const X509_VERIFY_PARAM *const *b) +{ + return strcmp((*a)->name, (*b)->name); +} + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) +{ + int idx; + X509_VERIFY_PARAM *ptmp; + if (!param_table) { + param_table = sk_X509_VERIFY_PARAM_new(param_cmp); + if (!param_table) + return 0; + } else { + idx = sk_X509_VERIFY_PARAM_find(param_table, param); + if (idx != -1) { + ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); + X509_VERIFY_PARAM_free(ptmp); + (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); + } + } + if (!sk_X509_VERIFY_PARAM_push(param_table, param)) + return 0; + return 1; +} + +int X509_VERIFY_PARAM_get_count(void) +{ + int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + if (param_table) + num += sk_X509_VERIFY_PARAM_num(param_table); + return num; +} + +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id) +{ + int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + if (id < num) + return default_table + id; + return sk_X509_VERIFY_PARAM_value(param_table, id - num); +} + +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) +{ + int idx; + X509_VERIFY_PARAM pm; + + pm.name = (char *)name; + if (param_table) { + idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); + if (idx != -1) + return sk_X509_VERIFY_PARAM_value(param_table, idx); + } + return OBJ_bsearch_table(&pm, default_table, + sizeof(default_table) / + sizeof(X509_VERIFY_PARAM)); +} + +void X509_VERIFY_PARAM_table_cleanup(void) +{ + if (param_table) + sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free); + param_table = NULL; +} diff --git a/Sources/COpenSSL/x509_vfy.h b/Sources/COpenSSL/x509_vfy.h new file mode 100644 index 00000000..76b4ffdc --- /dev/null +++ b/Sources/COpenSSL/x509_vfy.h @@ -0,0 +1,652 @@ +/* crypto/x509/x509_vfy.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_X509_H +# include "x509.h" +/* + * openssl/x509.h ends up #include-ing this file at about the only + * appropriate moment. + */ +#endif + +#ifndef HEADER_X509_VFY_H +# define HEADER_X509_VFY_H + +# include "opensslconf.h" +# ifndef OPENSSL_NO_LHASH +# include "lhash.h" +# endif +# include "bio.h" +# include "crypto.h" +# include "symhacks.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# if 0 +/* Outer object */ +typedef struct x509_hash_dir_st { + int num_dirs; + char **dirs; + int *dirs_type; + int num_dirs_alloced; +} X509_HASH_DIR_CTX; +# endif + +typedef struct x509_file_st { + int num_paths; /* number of paths to files or directories */ + int num_alloced; + char **paths; /* the list of paths or directories */ + int *path_type; +} X509_CERT_FILE_CTX; + +/*******************************/ +/*- +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +# define X509_LU_RETRY -1 +# define X509_LU_FAIL 0 +# define X509_LU_X509 1 +# define X509_LU_CRL 2 +# define X509_LU_PKEY 3 + +typedef struct x509_object_st { + /* one of the above types */ + int type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; +} X509_OBJECT; + +typedef struct x509_lookup_st X509_LOOKUP; + +DECLARE_STACK_OF(X509_LOOKUP) +DECLARE_STACK_OF(X509_OBJECT) + +/* This is a static that defines the function interface */ +typedef struct x509_lookup_method_st { + const char *name; + int (*new_item) (X509_LOOKUP *ctx); + void (*free) (X509_LOOKUP *ctx); + int (*init) (X509_LOOKUP *ctx); + int (*shutdown) (X509_LOOKUP *ctx); + int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret); + int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); + int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret); + int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret); +} X509_LOOKUP_METHOD; + +typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID; + +/* + * This structure hold all parameters associated with a verify operation by + * including an X509_VERIFY_PARAM structure in related structures the + * parameters used can be customized + */ + +typedef struct X509_VERIFY_PARAM_st { + char *name; + time_t check_time; /* Time to use */ + unsigned long inh_flags; /* Inheritance flags */ + unsigned long flags; /* Various verify flags */ + int purpose; /* purpose to check untrusted certificates */ + int trust; /* trust setting to check */ + int depth; /* Verify depth */ + STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ + X509_VERIFY_PARAM_ID *id; /* opaque ID data */ +} X509_VERIFY_PARAM; + +DECLARE_STACK_OF(X509_VERIFY_PARAM) + +/* + * This is used to hold everything. It is used for all certificate + * validation. Once we have a certificate chain, the 'verify' function is + * then called to actually check the cert chain. + */ +struct x509_store_st { + /* The following is a cache of trusted certs */ + int cache; /* if true, stash any hits */ + STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + X509_VERIFY_PARAM *param; + /* Callbacks for various operations */ + /* called to verify a certificate */ + int (*verify) (X509_STORE_CTX *ctx); + /* error callback */ + int (*verify_cb) (int ok, X509_STORE_CTX *ctx); + /* get issuers cert from ctx */ + int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + /* check issued */ + int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + /* Check revocation status of chain */ + int (*check_revocation) (X509_STORE_CTX *ctx); + /* retrieve CRL */ + int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); + /* Check CRL validity */ + int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); + /* Check certificate against CRL */ + int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup) (X509_STORE_CTX *ctx); + CRYPTO_EX_DATA ex_data; + int references; +} /* X509_STORE */ ; + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func)) +# define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func)) + +/* This is the functions plus an instance of the local variables. */ +struct x509_lookup_st { + int init; /* have we been started */ + int skip; /* don't use us. */ + X509_LOOKUP_METHOD *method; /* the functions */ + char *method_data; /* method data */ + X509_STORE *store_ctx; /* who owns us */ +} /* X509_LOOKUP */ ; + +/* + * This is a used when verifying cert chains. Since the gathering of the + * cert chain can take some time (and have to be 'retried', this needs to be + * kept and passed around. + */ +struct x509_store_ctx_st { /* X509_STORE_CTX */ + X509_STORE *ctx; + /* used when looking up certs */ + int current_method; + /* The following are set by the caller */ + /* The cert to check */ + X509 *cert; + /* chain of X509s - untrusted - passed in */ + STACK_OF(X509) *untrusted; + /* set of CRLs passed in */ + STACK_OF(X509_CRL) *crls; + X509_VERIFY_PARAM *param; + /* Other info for use with get_issuer() */ + void *other_ctx; + /* Callbacks for various operations */ + /* called to verify a certificate */ + int (*verify) (X509_STORE_CTX *ctx); + /* error callback */ + int (*verify_cb) (int ok, X509_STORE_CTX *ctx); + /* get issuers cert from ctx */ + int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + /* check issued */ + int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + /* Check revocation status of chain */ + int (*check_revocation) (X509_STORE_CTX *ctx); + /* retrieve CRL */ + int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); + /* Check CRL validity */ + int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); + /* Check certificate against CRL */ + int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + int (*check_policy) (X509_STORE_CTX *ctx); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup) (X509_STORE_CTX *ctx); + /* The following is built up */ + /* if 0, rebuild chain */ + int valid; + /* index of last untrusted cert */ + int last_untrusted; + /* chain of X509s - built up and trusted */ + STACK_OF(X509) *chain; + /* Valid policy tree */ + X509_POLICY_TREE *tree; + /* Require explicit policy value */ + int explicit_policy; + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + /* cert currently being tested as valid issuer */ + X509 *current_issuer; + /* current CRL */ + X509_CRL *current_crl; + /* score of current CRL */ + int current_crl_score; + /* Reason mask */ + unsigned int current_reasons; + /* For CRL path validation: parent context */ + X509_STORE_CTX *parent; + CRYPTO_EX_DATA ex_data; +} /* X509_STORE_CTX */ ; + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +# define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +# define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +# define X509_L_FILE_LOAD 1 +# define X509_L_ADD_DIR 2 + +# define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +# define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +# define X509_V_OK 0 +# define X509_V_ERR_UNSPECIFIED 1 + +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +# define X509_V_ERR_UNABLE_TO_GET_CRL 3 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +# define X509_V_ERR_CERT_NOT_YET_VALID 9 +# define X509_V_ERR_CERT_HAS_EXPIRED 10 +# define X509_V_ERR_CRL_NOT_YET_VALID 11 +# define X509_V_ERR_CRL_HAS_EXPIRED 12 +# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +# define X509_V_ERR_OUT_OF_MEM 17 +# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +# define X509_V_ERR_CERT_REVOKED 23 +# define X509_V_ERR_INVALID_CA 24 +# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +# define X509_V_ERR_INVALID_PURPOSE 26 +# define X509_V_ERR_CERT_UNTRUSTED 27 +# define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +# define X509_V_ERR_AKID_SKID_MISMATCH 30 +# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 + +# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +# define X509_V_ERR_INVALID_NON_CA 37 +# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 + +# define X509_V_ERR_INVALID_EXTENSION 41 +# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +# define X509_V_ERR_NO_EXPLICIT_POLICY 43 +# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 + +# define X509_V_ERR_UNNESTED_RESOURCE 46 + +# define X509_V_ERR_PERMITTED_VIOLATION 47 +# define X509_V_ERR_EXCLUDED_VIOLATION 48 +# define X509_V_ERR_SUBTREE_MINMAX 49 +# define X509_V_ERR_APPLICATION_VERIFICATION 50 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 + +/* Suite B mode algorithm violation */ +# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 +# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 +# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 +# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 +# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 +# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 + +/* Host, email and IP check errors */ +# define X509_V_ERR_HOSTNAME_MISMATCH 62 +# define X509_V_ERR_EMAIL_MISMATCH 63 +# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 + +/* Caller error */ +# define X509_V_ERR_INVALID_CALL 65 +/* Issuer lookup error */ +# define X509_V_ERR_STORE_LOOKUP 66 + +# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 67 + +/* Certificate verify flags */ + +/* Send issuer+subject checks to verify_cb */ +# define X509_V_FLAG_CB_ISSUER_CHECK 0x1 +/* Use check time instead of current time */ +# define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +# define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +# define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +# define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +# define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +# define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +# define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +# define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +# define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +# define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +# define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check selfsigned CA signature */ +# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* Use trusted store first */ +# define X509_V_FLAG_TRUSTED_FIRST 0x8000 +/* Suite B 128 bit only mode: not normally used */ +# define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 +/* Suite B 192 bit only mode */ +# define X509_V_FLAG_SUITEB_192_LOS 0x20000 +/* Suite B 128 bit mode allowing 192 bit algorithms */ +# define X509_V_FLAG_SUITEB_128_LOS 0x30000 + +/* Allow partial chains if at least one certificate is in trusted store */ +# define X509_V_FLAG_PARTIAL_CHAIN 0x80000 +/* + * If the initial chain is not trusted, do not attempt to build an alternative + * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag + * will force the behaviour to match that of previous versions. + */ +# define X509_V_FLAG_NO_ALT_CHAINS 0x100000 + +# define X509_VP_FLAG_DEFAULT 0x1 +# define X509_VP_FLAG_OVERWRITE 0x2 +# define X509_VP_FLAG_RESET_FLAGS 0x4 +# define X509_VP_FLAG_LOCKED 0x8 +# define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + int type, X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +void X509_OBJECT_up_ref_count(X509_OBJECT *a); +void X509_OBJECT_free_contents(X509_OBJECT *a); +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *v); + +STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)); + +void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, + STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX + *ctx, + X509_NAME *nm)); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, + X509_OBJECT *ret); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +# ifndef OPENSSL_NO_STDIO +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); +# endif + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +# ifndef OPENSSL_NO_STDIO +int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); +# endif + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data); +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); +void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + +int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); +int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); +int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ipasc); + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_get_count(void); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, + int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node); +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/x509cset.c b/Sources/COpenSSL/x509cset.c new file mode 100644 index 00000000..7c28a968 --- /dev/null +++ b/Sources/COpenSSL/x509cset.c @@ -0,0 +1,167 @@ +/* crypto/x509/x509cset.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "asn1.h" +#include "objects.h" +#include "evp.h" +#include "x509.h" + +int X509_CRL_set_version(X509_CRL *x, long version) +{ + if (x == NULL) + return (0); + if (x->crl->version == NULL) { + if ((x->crl->version = M_ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->crl->version, version)); +} + +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +{ + if ((x == NULL) || (x->crl == NULL)) + return (0); + return (X509_NAME_set(&x->crl->issuer, name)); +} + +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->lastUpdate; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->crl->lastUpdate); + x->crl->lastUpdate = in; + } + } + return (in != NULL); +} + +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->nextUpdate; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->crl->nextUpdate); + x->crl->nextUpdate = in; + } + } + return (in != NULL); +} + +int X509_CRL_sort(X509_CRL *c) +{ + int i; + X509_REVOKED *r; + /* + * sort the data so it will be written in serial number order + */ + sk_X509_REVOKED_sort(c->crl->revoked); + for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) { + r = sk_X509_REVOKED_value(c->crl->revoked, i); + r->sequence = i; + } + c->crl->enc.modified = 1; + return 1; +} + +int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->revocationDate; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->revocationDate); + x->revocationDate = in; + } + } + return (in != NULL); +} + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return (0); + in = x->serialNumber; + if (in != serial) { + in = M_ASN1_INTEGER_dup(serial); + if (in != NULL) { + M_ASN1_INTEGER_free(x->serialNumber); + x->serialNumber = in; + } + } + return (in != NULL); +} diff --git a/Sources/COpenSSL/x509name.c b/Sources/COpenSSL/x509name.c new file mode 100644 index 00000000..d1959b4c --- /dev/null +++ b/Sources/COpenSSL/x509name.c @@ -0,0 +1,397 @@ +/* crypto/x509/x509name.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "stack.h" +#include "cryptlib.h" +#include "asn1.h" +#include "objects.h" +#include "evp.h" +#include "x509.h" + +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-1); + return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); +} + +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf, + int len) +{ + int i; + ASN1_STRING *data; + + i = X509_NAME_get_index_by_OBJ(name, obj, -1); + if (i < 0) + return (-1); + data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); + i = (data->length > (len - 1)) ? (len - 1) : data->length; + if (buf == NULL) + return (data->length); + memcpy(buf, data->data, i); + buf[i] = '\0'; + return (i); +} + +int X509_NAME_entry_count(X509_NAME *name) +{ + if (name == NULL) + return (0); + return (sk_X509_NAME_ENTRY_num(name->entries)); +} + +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); +} + +/* NOTE: you should be passsing -1, not 0 as lastpos */ +int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_NAME_ENTRY *ne; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (-1); + if (lastpos < 0) + lastpos = -1; + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + for (lastpos++; lastpos < n; lastpos++) { + ne = sk_X509_NAME_ENTRY_value(sk, lastpos); + if (OBJ_cmp(ne->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc) +{ + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc + || loc < 0) + return (NULL); + else + return (sk_X509_NAME_ENTRY_value(name->entries, loc)); +} + +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) +{ + X509_NAME_ENTRY *ret; + int i, n, set_prev, set_next; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc + || loc < 0) + return (NULL); + sk = name->entries; + ret = sk_X509_NAME_ENTRY_delete(sk, loc); + n = sk_X509_NAME_ENTRY_num(sk); + name->modified = 1; + if (loc == n) + return (ret); + + /* else we need to fixup the set field */ + if (loc != 0) + set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; + else + set_prev = ret->set - 1; + set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; + + /*- + * set_prev is the previous set + * set is the current set + * set_next is the following + * prev 1 1 1 1 1 1 1 1 + * set 1 1 2 2 + * next 1 1 2 2 2 2 3 2 + * so basically only if prev and next differ by 2, then + * re-number down by 1 + */ + if (set_prev + 1 < set_next) + for (i = loc; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i)->set--; + return (ret); +} + +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +/* + * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the + * guy we are about to stomp on. + */ +int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc, + int set) +{ + X509_NAME_ENTRY *new_name = NULL; + int n, i, inc; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (0); + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + name->modified = 1; + + if (set == -1) { + if (loc == 0) { + set = 0; + inc = 1; + } else { + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; + inc = 0; + } + } else { /* if (set >= 0) */ + + if (loc >= n) { + if (loc != 0) + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; + else + set = 0; + } else + set = sk_X509_NAME_ENTRY_value(sk, loc)->set; + inc = (set == 0) ? 1 : 0; + } + + if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL) + goto err; + new_name->set = set; + if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { + X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (inc) { + n = sk_X509_NAME_ENTRY_num(sk); + for (i = loc + 1; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1; + } + return (1); + err: + if (new_name != NULL) + X509_NAME_ENTRY_free(new_name); + return (0); +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_txt2obj(field, 0); + if (obj == NULL) { + X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, + X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", field); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, unsigned char *bytes, + int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len) +{ + X509_NAME_ENTRY *ret; + + if ((ne == NULL) || (*ne == NULL)) { + if ((ret = X509_NAME_ENTRY_new()) == NULL) + return (NULL); + } else + ret = *ne; + + if (!X509_NAME_ENTRY_set_object(ret, obj)) + goto err; + if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) + goto err; + + if ((ne != NULL) && (*ne == NULL)) + *ne = ret; + return (ret); + err: + if ((ne == NULL) || (ret != *ne)) + X509_NAME_ENTRY_free(ret); + return (NULL); +} + +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj) +{ + if ((ne == NULL) || (obj == NULL)) { + X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT, + ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + ASN1_OBJECT_free(ne->object); + ne->object = OBJ_dup(obj); + return ((ne->object == NULL) ? 0 : 1); +} + +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len) +{ + int i; + + if ((ne == NULL) || ((bytes == NULL) && (len != 0))) + return (0); + if ((type > 0) && (type & MBSTRING_FLAG)) + return ASN1_STRING_set_by_NID(&ne->value, bytes, + len, type, + OBJ_obj2nid(ne->object)) ? 1 : 0; + if (len < 0) + len = strlen((const char *)bytes); + i = ASN1_STRING_set(ne->value, bytes, len); + if (!i) + return (0); + if (type != V_ASN1_UNDEF) { + if (type == V_ASN1_APP_CHOOSE) + ne->value->type = ASN1_PRINTABLE_type(bytes, len); + else + ne->value->type = type; + } + return (1); +} + +ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->object); +} + +ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->value); +} diff --git a/Sources/COpenSSL/x509rset.c b/Sources/COpenSSL/x509rset.c new file mode 100644 index 00000000..0bfa5070 --- /dev/null +++ b/Sources/COpenSSL/x509rset.c @@ -0,0 +1,85 @@ +/* crypto/x509/x509rset.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "asn1.h" +#include "objects.h" +#include "evp.h" +#include "x509.h" + +int X509_REQ_set_version(X509_REQ *x, long version) +{ + if (x == NULL) + return (0); + return (ASN1_INTEGER_set(x->req_info->version, version)); +} + +int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + return (X509_NAME_set(&x->req_info->subject, name)); +} + +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + return (X509_PUBKEY_set(&x->req_info->pubkey, pkey)); +} diff --git a/Sources/COpenSSL/x509spki.c b/Sources/COpenSSL/x509spki.c new file mode 100644 index 00000000..8bbfa793 --- /dev/null +++ b/Sources/COpenSSL/x509spki.c @@ -0,0 +1,125 @@ +/* x509spki.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "x509.h" + +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); +} + +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->spkac->pubkey)); +} + +/* Load a Netscape SPKI from a base64 encoded string */ + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) +{ + unsigned char *spki_der; + const unsigned char *p; + int spki_len; + NETSCAPE_SPKI *spki; + if (len <= 0) + len = strlen(str); + if (!(spki_der = OPENSSL_malloc(len + 1))) { + X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE); + return NULL; + } + spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); + if (spki_len < 0) { + X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, X509_R_BASE64_DECODE_ERROR); + OPENSSL_free(spki_der); + return NULL; + } + p = spki_der; + spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); + OPENSSL_free(spki_der); + return spki; +} + +/* Generate a base64 encoded string from an SPKI */ + +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) +{ + unsigned char *der_spki, *p; + char *b64_str; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + der_spki = OPENSSL_malloc(der_len); + b64_str = OPENSSL_malloc(der_len * 2); + if (!der_spki || !b64_str) { + OPENSSL_free(der_spki); + OPENSSL_free(b64_str); + X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); + return NULL; + } + p = der_spki; + i2d_NETSCAPE_SPKI(spki, &p); + EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); + OPENSSL_free(der_spki); + return b64_str; +} diff --git a/Sources/COpenSSL/x509type.c b/Sources/COpenSSL/x509type.c new file mode 100644 index 00000000..9782f6ca --- /dev/null +++ b/Sources/COpenSSL/x509type.c @@ -0,0 +1,127 @@ +/* crypto/x509/x509type.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "evp.h" +#include "objects.h" +#include "x509.h" + +int X509_certificate_type(X509 *x, EVP_PKEY *pkey) +{ + EVP_PKEY *pk; + int ret = 0, i; + + if (x == NULL) + return (0); + + if (pkey == NULL) + pk = X509_get_pubkey(x); + else + pk = pkey; + + if (pk == NULL) + return (0); + + switch (pk->type) { + case EVP_PKEY_RSA: + ret = EVP_PK_RSA | EVP_PKT_SIGN; +/* if (!sign only extension) */ + ret |= EVP_PKT_ENC; + break; + case EVP_PKEY_DSA: + ret = EVP_PK_DSA | EVP_PKT_SIGN; + break; + case EVP_PKEY_EC: + ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH; + break; + case EVP_PKEY_DH: + ret = EVP_PK_DH | EVP_PKT_EXCH; + break; + case NID_id_GostR3410_94: + case NID_id_GostR3410_2001: + ret = EVP_PKT_EXCH | EVP_PKT_SIGN; + break; + default: + break; + } + + i = OBJ_obj2nid(x->sig_alg->algorithm); + if (i && OBJ_find_sigid_algs(i, NULL, &i)) { + + switch (i) { + case NID_rsaEncryption: + case NID_rsa: + ret |= EVP_PKS_RSA; + break; + case NID_dsa: + case NID_dsa_2: + ret |= EVP_PKS_DSA; + break; + case NID_X9_62_id_ecPublicKey: + ret |= EVP_PKS_EC; + break; + default: + break; + } + } + + if (pkey == NULL) + EVP_PKEY_free(pk); + return (ret); +} diff --git a/Sources/COpenSSL/x509v3.h b/Sources/COpenSSL/x509v3.h new file mode 100644 index 00000000..92bf77b0 --- /dev/null +++ b/Sources/COpenSSL/x509v3.h @@ -0,0 +1,1055 @@ +/* x509v3.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_X509V3_H +# define HEADER_X509V3_H + +# include "bio.h" +# include "x509.h" +# include "conf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_SYS_WIN32 +/* Under Win32 these are defined in wincrypt.h */ +# undef X509_NAME +# undef X509_CERT_PAIR +# undef X509_EXTENSIONS +# endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE) (void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D) (void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, + void *ext); +typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { + int ext_nid; + int ext_flags; +/* If this is set the following four fields are ignored */ + ASN1_ITEM_EXP *it; +/* Old style ASN1 calls */ + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; +/* The following pair is used for string extensions */ + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; +/* The following pair is used for multi-valued extensions */ + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; +/* The following are used for raw extensions */ + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string) (void *db, char *section, char *value); + STACK_OF(CONF_VALUE) *(*get_section) (void *db, char *section); + void (*free_string) (void *db, char *string); + void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { +# define CTX_TEST 0x1 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + X509V3_CONF_METHOD *db_meth; + void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DECLARE_STACK_OF(X509V3_EXT_METHOD) + +/* ext_flags values */ +# define X509V3_EXT_DYNAMIC 0x1 +# define X509V3_EXT_CTX_DEP 0x2 +# define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + +typedef struct PKEY_USAGE_PERIOD_st { + ASN1_GENERALIZEDTIME *notBefore; + ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +# define GEN_OTHERNAME 0 +# define GEN_EMAIL 1 +# define GEN_DNS 2 +# define GEN_X400 3 +# define GEN_DIRNAME 4 +# define GEN_EDIPARTY 5 +# define GEN_URI 6 +# define GEN_IPADD 7 +# define GEN_RID 8 + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, + * uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ + } d; +} GENERAL_NAME; + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +DECLARE_STACK_OF(GENERAL_NAME) +DECLARE_ASN1_SET_OF(GENERAL_NAME) + +DECLARE_STACK_OF(ACCESS_DESCRIPTION) +DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; +/* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +# define CRLDP_ALL_REASONS 0x807f + +# define CRL_REASON_NONE -1 +# define CRL_REASON_UNSPECIFIED 0 +# define CRL_REASON_KEY_COMPROMISE 1 +# define CRL_REASON_CA_COMPROMISE 2 +# define CRL_REASON_AFFILIATION_CHANGED 3 +# define CRL_REASON_SUPERSEDED 4 +# define CRL_REASON_CESSATION_OF_OPERATION 5 +# define CRL_REASON_CERTIFICATE_HOLD 6 +# define CRL_REASON_REMOVE_FROM_CRL 8 +# define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +# define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DECLARE_STACK_OF(DIST_POINT) +DECLARE_ASN1_SET_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +/* Strong extranet structures */ + +typedef struct SXNET_ID_st { + ASN1_INTEGER *zone; + ASN1_OCTET_STRING *user; +} SXNETID; + +DECLARE_STACK_OF(SXNETID) +DECLARE_ASN1_SET_OF(SXNETID) + +typedef struct SXNET_st { + ASN1_INTEGER *version; + STACK_OF(SXNETID) *ids; +} SXNET; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DECLARE_STACK_OF(POLICYQUALINFO) +DECLARE_ASN1_SET_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DECLARE_STACK_OF(POLICYINFO) +DECLARE_ASN1_SET_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DECLARE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DECLARE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; +} PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; +} PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +/* Values in idp_flags field */ +/* IDP present */ +# define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +# define IDP_INVALID 0x2 +/* onlyuser true */ +# define IDP_ONLYUSER 0x4 +/* onlyCA true */ +# define IDP_ONLYCA 0x8 +/* onlyattr true */ +# define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +# define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +# define IDP_REASONS 0x40 + +# define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \ +",name:", val->name, ",value:", val->value); + +# define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* X509_PURPOSE stuff */ + +# define EXFLAG_BCONS 0x1 +# define EXFLAG_KUSAGE 0x2 +# define EXFLAG_XKUSAGE 0x4 +# define EXFLAG_NSCERT 0x8 + +# define EXFLAG_CA 0x10 +/* Really self issued not necessarily self signed */ +# define EXFLAG_SI 0x20 +# define EXFLAG_V1 0x40 +# define EXFLAG_INVALID 0x80 +# define EXFLAG_SET 0x100 +# define EXFLAG_CRITICAL 0x200 +# define EXFLAG_PROXY 0x400 + +# define EXFLAG_INVALID_POLICY 0x800 +# define EXFLAG_FRESHEST 0x1000 +/* Self signed */ +# define EXFLAG_SS 0x2000 + +# define KU_DIGITAL_SIGNATURE 0x0080 +# define KU_NON_REPUDIATION 0x0040 +# define KU_KEY_ENCIPHERMENT 0x0020 +# define KU_DATA_ENCIPHERMENT 0x0010 +# define KU_KEY_AGREEMENT 0x0008 +# define KU_KEY_CERT_SIGN 0x0004 +# define KU_CRL_SIGN 0x0002 +# define KU_ENCIPHER_ONLY 0x0001 +# define KU_DECIPHER_ONLY 0x8000 + +# define NS_SSL_CLIENT 0x80 +# define NS_SSL_SERVER 0x40 +# define NS_SMIME 0x20 +# define NS_OBJSIGN 0x10 +# define NS_SSL_CA 0x04 +# define NS_SMIME_CA 0x02 +# define NS_OBJSIGN_CA 0x01 +# define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +# define XKU_SSL_SERVER 0x1 +# define XKU_SSL_CLIENT 0x2 +# define XKU_SMIME 0x4 +# define XKU_CODE_SIGN 0x8 +# define XKU_SGC 0x10 +# define XKU_OCSP_SIGN 0x20 +# define XKU_TIMESTAMP 0x40 +# define XKU_DVCS 0x80 +# define XKU_ANYEKU 0x100 + +# define X509_PURPOSE_DYNAMIC 0x1 +# define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +# define X509_PURPOSE_SSL_CLIENT 1 +# define X509_PURPOSE_SSL_SERVER 2 +# define X509_PURPOSE_NS_SSL_SERVER 3 +# define X509_PURPOSE_SMIME_SIGN 4 +# define X509_PURPOSE_SMIME_ENCRYPT 5 +# define X509_PURPOSE_CRL_SIGN 6 +# define X509_PURPOSE_ANY 7 +# define X509_PURPOSE_OCSP_HELPER 8 +# define X509_PURPOSE_TIMESTAMP_SIGN 9 + +# define X509_PURPOSE_MIN 1 +# define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +# define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +# define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +# define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +# define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +# define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +# define X509V3_ADD_OP_MASK 0xfL +# define X509V3_ADD_DEFAULT 0L +# define X509V3_ADD_APPEND 1L +# define X509V3_ADD_REPLACE 2L +# define X509V3_ADD_REPLACE_EXISTING 3L +# define X509V3_ADD_KEEP_EXISTING 4L +# define X509V3_ADD_DELETE 5L +# define X509V3_ADD_SILENT 0x10 + +DECLARE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(SXNET) +DECLARE_ASN1_FUNCTIONS(SXNETID) + +int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, + int userlen); +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, + int userlen); + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone); +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, char *value, + int is_nc); + +# ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, + int is_nc); +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, + char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, + STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, + char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *name, char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +# endif + +char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint); +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value); +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx); +int X509V3_EXT_free(int nid, void *ext_data); + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags); + +char *hex_to_string(const unsigned char *buffer, long len); +unsigned char *string_to_hex(const char *str, long *len); +int name_cmp(const char *name, const char *cmp); + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); + +int X509V3_extensions_print(BIO *out, char *title, + STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +int X509_PURPOSE_get_count(void); +X509_PURPOSE *X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg); +char *X509_PURPOSE_get0_name(X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(X509_PURPOSE *); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); +/* Flags for X509_check_* functions */ + +/* + * Always check subject name for host match even if subject alt names present + */ +# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 +/* Disable wildcard matching for dnsName fields and common name. */ +# define X509_CHECK_FLAG_NO_WILDCARDS 0x2 +/* Wildcards must not match a partial label. */ +# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 +/* Allow (non-partial) wildcards to match multiple labels. */ +# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 +/* Constraint verifier subdomain patterns to match a single labels. */ +# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 +/* + * Match reference identifiers starting with "." to any sub-domain. + * This is a non-public flag, turned on implicitly when the subject + * reference identity is a DNS name. + */ +# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 + +int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int a2i_ipadd(unsigned char *ipout, const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype); + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DECLARE_STACK_OF(X509_POLICY_NODE) + +# ifndef OPENSSL_NO_RFC3779 + +typedef struct ASRange_st { + ASN1_INTEGER *min, *max; +} ASRange; + +# define ASIdOrRange_id 0 +# define ASIdOrRange_range 1 + +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; + +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; +DECLARE_STACK_OF(ASIdOrRange) + +# define ASIdentifierChoice_inherit 0 +# define ASIdentifierChoice_asIdsOrRanges 1 + +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; + +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum, *rdi; +} ASIdentifiers; + +DECLARE_ASN1_FUNCTIONS(ASRange) +DECLARE_ASN1_FUNCTIONS(ASIdOrRange) +DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice) +DECLARE_ASN1_FUNCTIONS(ASIdentifiers) + +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min, *max; +} IPAddressRange; + +# define IPAddressOrRange_addressPrefix 0 +# define IPAddressOrRange_addressRange 1 + +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; + +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +DECLARE_STACK_OF(IPAddressOrRange) + +# define IPAddressChoice_inherit 0 +# define IPAddressChoice_addressesOrRanges 1 + +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; + +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; + +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +DECLARE_STACK_OF(IPAddressFamily) + +DECLARE_ASN1_FUNCTIONS(IPAddressRange) +DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) +DECLARE_ASN1_FUNCTIONS(IPAddressChoice) +DECLARE_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * API tag for elements of the ASIdentifer SEQUENCE. + */ +# define V3_ASID_ASNUM 0 +# define V3_ASID_RDI 1 + +/* + * AFI values, assigned by IANA. It'd be nice to make the AFI + * handling code totally generic, but there are too many little things + * that would need to be defined for other address families for it to + * be worth the trouble. + */ +# define IANA_AFI_IPV4 1 +# define IANA_AFI_IPV6 2 + +/* + * Utilities to construct and extract values from RFC3779 extensions, + * since some of the encodings (particularly for IP address prefixes + * and ranges) are a bit tedious to work with directly. + */ +int v3_asid_add_inherit(ASIdentifiers *asid, int which); +int v3_asid_add_id_or_range(ASIdentifiers *asid, int which, + ASN1_INTEGER *min, ASN1_INTEGER *max); +int v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi); +int v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *a, const int prefixlen); +int v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *min, unsigned char *max); +unsigned v3_addr_get_afi(const IPAddressFamily *f); +int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, + const int length); + +/* + * Canonical forms. + */ +int v3_asid_is_canonical(ASIdentifiers *asid); +int v3_addr_is_canonical(IPAddrBlocks *addr); +int v3_asid_canonize(ASIdentifiers *asid); +int v3_addr_canonize(IPAddrBlocks *addr); + +/* + * Tests for inheritance and containment. + */ +int v3_asid_inherits(ASIdentifiers *asid); +int v3_addr_inherits(IPAddrBlocks *addr); +int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); +int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); + +/* + * Check whether RFC 3779 extensions nest properly in chains. + */ +int v3_asid_validate_path(X509_STORE_CTX *); +int v3_addr_validate_path(X509_STORE_CTX *); +int v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, int allow_inheritance); +int v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance); + +# endif /* OPENSSL_NO_RFC3779 */ + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509V3_strings(void); + +/* Error codes for the X509V3 functions. */ + +/* Function codes. */ +# define X509V3_F_A2I_GENERAL_NAME 164 +# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 +# define X509V3_F_COPY_EMAIL 122 +# define X509V3_F_COPY_ISSUER 123 +# define X509V3_F_DO_DIRNAME 144 +# define X509V3_F_DO_EXT_CONF 124 +# define X509V3_F_DO_EXT_I2D 135 +# define X509V3_F_DO_EXT_NCONF 151 +# define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 +# define X509V3_F_GNAMES_FROM_SECTNAME 156 +# define X509V3_F_HEX_TO_STRING 111 +# define X509V3_F_I2S_ASN1_ENUMERATED 121 +# define X509V3_F_I2S_ASN1_IA5STRING 149 +# define X509V3_F_I2S_ASN1_INTEGER 120 +# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 +# define X509V3_F_NOTICE_SECTION 132 +# define X509V3_F_NREF_NOS 133 +# define X509V3_F_POLICY_SECTION 131 +# define X509V3_F_PROCESS_PCI_VALUE 150 +# define X509V3_F_R2I_CERTPOL 130 +# define X509V3_F_R2I_PCI 155 +# define X509V3_F_S2I_ASN1_IA5STRING 100 +# define X509V3_F_S2I_ASN1_INTEGER 108 +# define X509V3_F_S2I_ASN1_OCTET_STRING 112 +# define X509V3_F_S2I_ASN1_SKEY_ID 114 +# define X509V3_F_S2I_SKEY_ID 115 +# define X509V3_F_SET_DIST_POINT_NAME 158 +# define X509V3_F_STRING_TO_HEX 113 +# define X509V3_F_SXNET_ADD_ID_ASC 125 +# define X509V3_F_SXNET_ADD_ID_INTEGER 126 +# define X509V3_F_SXNET_ADD_ID_ULONG 127 +# define X509V3_F_SXNET_GET_ID_ASC 128 +# define X509V3_F_SXNET_GET_ID_ULONG 129 +# define X509V3_F_V2I_ASIDENTIFIERS 163 +# define X509V3_F_V2I_ASN1_BIT_STRING 101 +# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 +# define X509V3_F_V2I_AUTHORITY_KEYID 119 +# define X509V3_F_V2I_BASIC_CONSTRAINTS 102 +# define X509V3_F_V2I_CRLD 134 +# define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 +# define X509V3_F_V2I_GENERAL_NAMES 118 +# define X509V3_F_V2I_GENERAL_NAME_EX 117 +# define X509V3_F_V2I_IDP 157 +# define X509V3_F_V2I_IPADDRBLOCKS 159 +# define X509V3_F_V2I_ISSUER_ALT 153 +# define X509V3_F_V2I_NAME_CONSTRAINTS 147 +# define X509V3_F_V2I_POLICY_CONSTRAINTS 146 +# define X509V3_F_V2I_POLICY_MAPPINGS 145 +# define X509V3_F_V2I_SUBJECT_ALT 154 +# define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 +# define X509V3_F_V3_GENERIC_EXTENSION 116 +# define X509V3_F_X509V3_ADD1_I2D 140 +# define X509V3_F_X509V3_ADD_VALUE 105 +# define X509V3_F_X509V3_EXT_ADD 104 +# define X509V3_F_X509V3_EXT_ADD_ALIAS 106 +# define X509V3_F_X509V3_EXT_CONF 107 +# define X509V3_F_X509V3_EXT_FREE 165 +# define X509V3_F_X509V3_EXT_I2D 136 +# define X509V3_F_X509V3_EXT_NCONF 152 +# define X509V3_F_X509V3_GET_SECTION 142 +# define X509V3_F_X509V3_GET_STRING 143 +# define X509V3_F_X509V3_GET_VALUE_BOOL 110 +# define X509V3_F_X509V3_PARSE_LIST 109 +# define X509V3_F_X509_PURPOSE_ADD 137 +# define X509V3_F_X509_PURPOSE_SET 141 + +/* Reason codes. */ +# define X509V3_R_BAD_IP_ADDRESS 118 +# define X509V3_R_BAD_OBJECT 119 +# define X509V3_R_BN_DEC2BN_ERROR 100 +# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 +# define X509V3_R_CANNOT_FIND_FREE_FUNCTION 168 +# define X509V3_R_DIRNAME_ERROR 149 +# define X509V3_R_DISTPOINT_ALREADY_SET 160 +# define X509V3_R_DUPLICATE_ZONE_ID 133 +# define X509V3_R_ERROR_CONVERTING_ZONE 131 +# define X509V3_R_ERROR_CREATING_EXTENSION 144 +# define X509V3_R_ERROR_IN_EXTENSION 128 +# define X509V3_R_EXPECTED_A_SECTION_NAME 137 +# define X509V3_R_EXTENSION_EXISTS 145 +# define X509V3_R_EXTENSION_NAME_ERROR 115 +# define X509V3_R_EXTENSION_NOT_FOUND 102 +# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 +# define X509V3_R_EXTENSION_VALUE_ERROR 116 +# define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 +# define X509V3_R_ILLEGAL_HEX_DIGIT 113 +# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 +# define X509V3_R_INVALID_ASNUMBER 162 +# define X509V3_R_INVALID_ASRANGE 163 +# define X509V3_R_INVALID_BOOLEAN_STRING 104 +# define X509V3_R_INVALID_EXTENSION_STRING 105 +# define X509V3_R_INVALID_INHERITANCE 165 +# define X509V3_R_INVALID_IPADDRESS 166 +# define X509V3_R_INVALID_MULTIPLE_RDNS 161 +# define X509V3_R_INVALID_NAME 106 +# define X509V3_R_INVALID_NULL_ARGUMENT 107 +# define X509V3_R_INVALID_NULL_NAME 108 +# define X509V3_R_INVALID_NULL_VALUE 109 +# define X509V3_R_INVALID_NUMBER 140 +# define X509V3_R_INVALID_NUMBERS 141 +# define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 +# define X509V3_R_INVALID_OPTION 138 +# define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +# define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 +# define X509V3_R_INVALID_PURPOSE 146 +# define X509V3_R_INVALID_SAFI 164 +# define X509V3_R_INVALID_SECTION 135 +# define X509V3_R_INVALID_SYNTAX 143 +# define X509V3_R_ISSUER_DECODE_ERROR 126 +# define X509V3_R_MISSING_VALUE 124 +# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +# define X509V3_R_NO_CONFIG_DATABASE 136 +# define X509V3_R_NO_ISSUER_CERTIFICATE 121 +# define X509V3_R_NO_ISSUER_DETAILS 127 +# define X509V3_R_NO_POLICY_IDENTIFIER 139 +# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 +# define X509V3_R_NO_PUBLIC_KEY 114 +# define X509V3_R_NO_SUBJECT_DETAILS 125 +# define X509V3_R_ODD_NUMBER_OF_DIGITS 112 +# define X509V3_R_OPERATION_NOT_DEFINED 148 +# define X509V3_R_OTHERNAME_ERROR 147 +# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 +# define X509V3_R_POLICY_PATH_LENGTH 156 +# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 +# define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 +# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 +# define X509V3_R_SECTION_NOT_FOUND 150 +# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 +# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 +# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +# define X509V3_R_UNKNOWN_EXTENSION 129 +# define X509V3_R_UNKNOWN_EXTENSION_NAME 130 +# define X509V3_R_UNKNOWN_OPTION 120 +# define X509V3_R_UNSUPPORTED_OPTION 117 +# define X509V3_R_UNSUPPORTED_TYPE 167 +# define X509V3_R_USER_TOO_LONG 132 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/COpenSSL/x_.c b/Sources/COpenSSL/x_.c new file mode 100644 index 00000000..23732cb1 --- /dev/null +++ b/Sources/COpenSSL/x_.c @@ -0,0 +1,3892 @@ +/* x_algor.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "x509.h" +#include "asn1.h" +#include "asn1t.h" + +ASN1_SEQUENCE(X509_ALGOR) = { + ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), + ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY) +} ASN1_SEQUENCE_END(X509_ALGOR) + +ASN1_ITEM_TEMPLATE(X509_ALGORS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR) +ASN1_ITEM_TEMPLATE_END(X509_ALGORS) + +IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR) + +IMPLEMENT_STACK_OF(X509_ALGOR) +IMPLEMENT_ASN1_SET_OF(X509_ALGOR) + +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) +{ + if (!alg) + return 0; + if (ptype != V_ASN1_UNDEF) { + if (alg->parameter == NULL) + alg->parameter = ASN1_TYPE_new(); + if (alg->parameter == NULL) + return 0; + } + if (alg) { + if (alg->algorithm) + ASN1_OBJECT_free(alg->algorithm); + alg->algorithm = aobj; + } + if (ptype == 0) + return 1; + if (ptype == V_ASN1_UNDEF) { + if (alg->parameter) { + ASN1_TYPE_free(alg->parameter); + alg->parameter = NULL; + } + } else + ASN1_TYPE_set(alg->parameter, ptype, pval); + return 1; +} + +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor) +{ + if (paobj) + *paobj = algor->algorithm; + if (pptype) { + if (algor->parameter == NULL) { + *pptype = V_ASN1_UNDEF; + return; + } else + *pptype = algor->parameter->type; + if (ppval) + *ppval = algor->parameter->value.ptr; + } +} + +/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ + +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) +{ + int param_type; + + if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) + param_type = V_ASN1_UNDEF; + else + param_type = V_ASN1_NULL; + + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); + +} + +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) +{ + int rv; + rv = OBJ_cmp(a->algorithm, b->algorithm); + if (rv) + return rv; + if (!a->parameter && !b->parameter) + return 0; + return ASN1_TYPE_cmp(a->parameter, b->parameter); +} +/* crypto/x509/x_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "stack.h" +#include "cryptlib.h" +#include "buffer.h" +// #include "asn1.h" +#include "evp.h" +// #include "x509.h" +#include "ocsp.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif + +int X509_verify(X509 *a, EVP_PKEY *r) +{ + if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature)) + return 0; + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg, + a->signature, a->cert_info, r)); +} + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), + a->sig_alg, a->signature, a->req_info, r)); +} + +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), + a->sig_algor, a->signature, a->spkac, r)); +} + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->cert_info->enc.modified = 1; + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, pkey, md)); +} + +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) +{ + x->cert_info->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), + x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, ctx); +} + +int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert) +{ + return OCSP_REQ_CTX_nbio_d2i(rctx, + (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509)); +} + +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, + x->signature, x->req_info, pkey, md)); +} + +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) +{ + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), + x->sig_alg, NULL, x->signature, x->req_info, + ctx); +} + +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->crl->enc.modified = 1; + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, pkey, md)); +} + +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) +{ + x->crl->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), + x->crl->sig_alg, x->sig_alg, x->signature, + x->crl, ctx); +} + +int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl) +{ + return OCSP_REQ_CTX_nbio_d2i(rctx, + (ASN1_VALUE **)pcrl, + ASN1_ITEM_rptr(X509_CRL)); +} + +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, + x->signature, x->spkac, pkey, md)); +} + +#ifndef OPENSSL_NO_FP_API +X509 *d2i_X509_fp(FILE *fp, X509 **x509) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); +} + +int i2d_X509_fp(FILE *fp, X509 *x509) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); +} +#endif + +X509 *d2i_X509_bio(BIO *bp, X509 **x509) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); +} + +int i2d_X509_bio(BIO *bp, X509 *x509) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); +} + +#ifndef OPENSSL_NO_FP_API +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +} + +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +} +#endif + +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +} + +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +} + +#ifndef OPENSSL_NO_FP_API +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); +} + +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); +} +#endif + +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); +} + +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); +} + +#ifndef OPENSSL_NO_FP_API +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); +} + +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); +} +#endif + +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +} + +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +} + +#ifndef OPENSSL_NO_RSA + +# ifndef OPENSSL_NO_FP_API +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); +} + +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); +} + +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); +} + +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa) +{ + return ASN1_d2i_fp((void *(*)(void)) + RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp, + (void **)rsa); +} + +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); +} + +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) +{ + return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa); +} +# endif + +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); +} + +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); +} + +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); +} + +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa) +{ + return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa); +} + +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); +} + +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) +{ + return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa); +} +#endif + +#ifndef OPENSSL_NO_DSA +# ifndef OPENSSL_NO_FP_API +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) +{ + return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa); +} + +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) +{ + return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa); +} + +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa) +{ + return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa); +} + +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa) +{ + return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa); +} +# endif + +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) +{ + return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa); +} + +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) +{ + return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa); +} + +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa) +{ + return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa); +} + +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa) +{ + return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa); +} + +#endif + +#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_FP_API +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey) +{ + return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey); +} + +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey) +{ + return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey); +} + +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) +{ + return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey); +} + +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) +{ + return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey); +} +# endif +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey) +{ + return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey); +} + +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa) +{ + return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa); +} + +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) +{ + return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey); +} + +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) +{ + return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey); +} +#endif + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + ASN1_BIT_STRING *key; + key = X509_get0_pubkey_bitstr(data); + if (!key) + return 0; + return EVP_Digest(key->data, key->length, md, len, type, NULL); +} + +int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509), type, (char *)data, md, len)); +} + +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len)); +} + +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len)); +} + +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len)); +} + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type, + (char *)data, md, len)); +} + +#ifndef OPENSSL_NO_FP_API +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) +{ + return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8); +} + +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) +{ + return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8); +} +#endif + +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) +{ + return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8); +} + +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) +{ + return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8); +} + +#ifndef OPENSSL_NO_FP_API +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf) +{ + return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, + d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf); +} + +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) +{ + return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp, + p8inf); +} + +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} + +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) +{ + return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey); +} + +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a); +} + +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey) +{ + return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey); +} + +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a); +} + +#endif + +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf) +{ + return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, + d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf); +} + +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) +{ + return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp, + p8inf); +} + +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} + +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey); +} + +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) +{ + return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a); +} + +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey); +} + +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) +{ + return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a); +} +/* crypto/asn1/x_attrib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +#include "objects.h" +// #include "asn1t.h" +// #include "x509.h" + +/*- + * X509_ATTRIBUTE: this has the following form: + * + * typedef struct x509_attributes_st + * { + * ASN1_OBJECT *object; + * int single; + * union { + * char *ptr; + * STACK_OF(ASN1_TYPE) *set; + * ASN1_TYPE *single; + * } value; + * } X509_ATTRIBUTE; + * + * this needs some extra thought because the CHOICE type is + * merged with the main structure and because the value can + * be anything at all we *must* try the SET OF first because + * the ASN1_ANY type will swallow anything including the whole + * SET OF structure. + */ + +ASN1_CHOICE(X509_ATTRIBUTE_SET) = { + ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY), + ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY) +} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single) + +ASN1_SEQUENCE(X509_ATTRIBUTE) = { + ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT), + /* CHOICE type merged with parent */ + ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET) +} ASN1_SEQUENCE_END(X509_ATTRIBUTE) + +IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE) + +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value) +{ + X509_ATTRIBUTE *ret = NULL; + ASN1_TYPE *val = NULL; + + if ((ret = X509_ATTRIBUTE_new()) == NULL) + return (NULL); + ret->object = OBJ_nid2obj(nid); + ret->single = 0; + if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL) + goto err; + if ((val = ASN1_TYPE_new()) == NULL) + goto err; + if (!sk_ASN1_TYPE_push(ret->value.set, val)) + goto err; + + ASN1_TYPE_set(val, atrtype, value); + return (ret); + err: + if (ret != NULL) + X509_ATTRIBUTE_free(ret); + if (val != NULL) + ASN1_TYPE_free(val); + return (NULL); +} +/* x_bignum.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +#include "bn.h" + +/* + * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER + * as a BIGNUM directly. Currently it ignores the sign which isn't a problem + * since all BIGNUMs used are non negative and anything that looks negative + * is normally due to an encoding error. + */ + +#define BN_SENSITIVE 1 + +static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it); +static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it); +static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx); + +static ASN1_PRIMITIVE_FUNCS bignum_pf = { + NULL, 0, + bn_new, + bn_free, + 0, + bn_c2i, + bn_i2c, + bn_print +}; + +ASN1_ITEM_start(BIGNUM) + ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM" +ASN1_ITEM_end(BIGNUM) + +ASN1_ITEM_start(CBIGNUM) + ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM" +ASN1_ITEM_end(CBIGNUM) + +static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + *pval = (ASN1_VALUE *)BN_new(); + if (*pval) + return 1; + else + return 0; +} + +static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + if (!*pval) + return; + if (it->size & BN_SENSITIVE) + BN_clear_free((BIGNUM *)*pval); + else + BN_free((BIGNUM *)*pval); + *pval = NULL; +} + +static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it) +{ + BIGNUM *bn; + int pad; + if (!*pval) + return -1; + bn = (BIGNUM *)*pval; + /* If MSB set in an octet we need a padding byte */ + if (BN_num_bits(bn) & 0x7) + pad = 0; + else + pad = 1; + if (cont) { + if (pad) + *cont++ = 0; + BN_bn2bin(bn, cont); + } + return pad + BN_num_bytes(bn); +} + +static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) +{ + BIGNUM *bn; + + if (*pval == NULL && !bn_new(pval, it)) + return 0; + bn = (BIGNUM *)*pval; + if (!BN_bin2bn(cont, len, bn)) { + bn_free(pval, it); + return 0; + } + return 1; +} + +static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx) +{ + if (!BN_print(out, *(BIGNUM **)pval)) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + return 1; +} +/* crypto/asn1/x_crl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +#include "asn1_locl.h" +// #include "x509.h" +#include "x509v3.h" + +static int X509_REVOKED_cmp(const X509_REVOKED *const *a, + const X509_REVOKED *const *b); +static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); + +ASN1_SEQUENCE(X509_REVOKED) = { + ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) +} ASN1_SEQUENCE_END(X509_REVOKED) + +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer); + +static X509_CRL_METHOD int_crl_meth = { + 0, + 0, 0, + def_crl_lookup, + def_crl_verify +}; + +static const X509_CRL_METHOD *default_crl_method = &int_crl_meth; + +/* + * The X509_CRL_INFO structure needs a bit of customisation. Since we cache + * the original encoding the signature wont be affected by reordering of the + * revoked field. + */ +static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; + + if (!a || !a->revoked) + return 1; + switch (operation) { + /* + * Just set cmp function here. We don't sort because that would + * affect the output of X509_CRL_print(). + */ + case ASN1_OP_D2I_POST: + (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp); + break; + } + return 1; +} + + +ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { + ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME), + ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME), + ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED), + ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) +} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) + +/* + * Set CRL entry issuer according to CRL certificate issuer extension. Check + * for unhandled critical CRL entry extensions. + */ + +static int crl_set_issuers(X509_CRL *crl) +{ + + int i, j; + GENERAL_NAMES *gens, *gtmp; + STACK_OF(X509_REVOKED) *revoked; + + revoked = X509_CRL_get_REVOKED(crl); + + gens = NULL; + for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { + X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); + STACK_OF(X509_EXTENSION) *exts; + ASN1_ENUMERATED *reason; + X509_EXTENSION *ext; + gtmp = X509_REVOKED_get_ext_d2i(rev, + NID_certificate_issuer, &j, NULL); + if (!gtmp && (j != -1)) { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (gtmp) { + gens = gtmp; + if (!crl->issuers) { + crl->issuers = sk_GENERAL_NAMES_new_null(); + if (!crl->issuers) + return 0; + } + if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) + return 0; + } + rev->issuer = gens; + + reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); + if (!reason && (j != -1)) { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (reason) { + rev->reason = ASN1_ENUMERATED_get(reason); + ASN1_ENUMERATED_free(reason); + } else + rev->reason = CRL_REASON_NONE; + + /* Check for critical CRL entry extensions */ + + exts = rev->extensions; + + for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) { + ext = sk_X509_EXTENSION_value(exts, j); + if (ext->critical > 0) { + if (OBJ_obj2nid(ext->object) == NID_certificate_issuer) + continue; + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + + } + + return 1; + +} + +/* + * The X509_CRL structure needs a bit of customisation. Cache some extensions + * and hash of the whole CRL. + */ +static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_CRL *crl = (X509_CRL *)*pval; + STACK_OF(X509_EXTENSION) *exts; + X509_EXTENSION *ext; + int idx; + + switch (operation) { + case ASN1_OP_NEW_POST: + crl->idp = NULL; + crl->akid = NULL; + crl->flags = 0; + crl->idp_flags = 0; + crl->idp_reasons = CRLDP_ALL_REASONS; + crl->meth = default_crl_method; + crl->meth_data = NULL; + crl->issuers = NULL; + crl->crl_number = NULL; + crl->base_crl_number = NULL; + break; + + case ASN1_OP_D2I_POST: +#ifndef OPENSSL_NO_SHA + X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); +#endif + crl->idp = X509_CRL_get_ext_d2i(crl, + NID_issuing_distribution_point, NULL, + NULL); + if (crl->idp) + setup_idp(crl, crl->idp); + + crl->akid = X509_CRL_get_ext_d2i(crl, + NID_authority_key_identifier, NULL, + NULL); + + crl->crl_number = X509_CRL_get_ext_d2i(crl, + NID_crl_number, NULL, NULL); + + crl->base_crl_number = X509_CRL_get_ext_d2i(crl, + NID_delta_crl, NULL, + NULL); + /* Delta CRLs must have CRL number */ + if (crl->base_crl_number && !crl->crl_number) + crl->flags |= EXFLAG_INVALID; + + /* + * See if we have any unhandled critical CRL extensions and indicate + * this in a flag. We only currently handle IDP so anything else + * critical sets the flag. This code accesses the X509_CRL structure + * directly: applications shouldn't do this. + */ + + exts = crl->crl->extensions; + + for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { + int nid; + + ext = sk_X509_EXTENSION_value(exts, idx); + nid = OBJ_obj2nid(ext->object); + if (nid == NID_freshest_crl) + crl->flags |= EXFLAG_FRESHEST; + if (ext->critical > 0) { + /* We handle IDP and deltas */ + if ((nid == NID_issuing_distribution_point) + || (nid == NID_authority_key_identifier) + || (nid == NID_delta_crl)) + continue; + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + + if (!crl_set_issuers(crl)) + return 0; + + if (crl->meth->crl_init) { + if (crl->meth->crl_init(crl) == 0) + return 0; + } + break; + + case ASN1_OP_FREE_POST: + if (crl->meth->crl_free) { + if (!crl->meth->crl_free(crl)) + return 0; + } + if (crl->akid) + AUTHORITY_KEYID_free(crl->akid); + if (crl->idp) + ISSUING_DIST_POINT_free(crl->idp); + ASN1_INTEGER_free(crl->crl_number); + ASN1_INTEGER_free(crl->base_crl_number); + sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); + break; + } + return 1; +} + +/* Convert IDP into a more convenient form */ + +static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) +{ + int idp_only = 0; + /* Set various flags according to IDP */ + crl->idp_flags |= IDP_PRESENT; + if (idp->onlyuser > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYUSER; + } + if (idp->onlyCA > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYCA; + } + if (idp->onlyattr > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYATTR; + } + + if (idp_only > 1) + crl->idp_flags |= IDP_INVALID; + + if (idp->indirectCRL > 0) + crl->idp_flags |= IDP_INDIRECT; + + if (idp->onlysomereasons) { + crl->idp_flags |= IDP_REASONS; + if (idp->onlysomereasons->length > 0) + crl->idp_reasons = idp->onlysomereasons->data[0]; + if (idp->onlysomereasons->length > 1) + crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); + crl->idp_reasons &= CRLDP_ALL_REASONS; + } + + DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); +} + +ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = { + ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), + ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CRL) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL) + +static int X509_REVOKED_cmp(const X509_REVOKED *const *a, + const X509_REVOKED *const *b) +{ + return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber, + (ASN1_STRING *)(*b)->serialNumber)); +} + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) +{ + X509_CRL_INFO *inf; + inf = crl->crl; + if (!inf->revoked) + inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); + if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) { + ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE); + return 0; + } + inf->enc.modified = 1; + return 1; +} + +int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r) +{ + if (crl->meth->crl_verify) + return crl->meth->crl_verify(crl, r); + return 0; +} + +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial) +{ + if (crl->meth->crl_lookup) + return crl->meth->crl_lookup(crl, ret, serial, NULL); + return 0; +} + +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) +{ + if (crl->meth->crl_lookup) + return crl->meth->crl_lookup(crl, ret, + X509_get_serialNumber(x), + X509_get_issuer_name(x)); + return 0; +} + +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), + crl->sig_alg, crl->signature, crl->crl, r)); +} + +static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, + X509_REVOKED *rev) +{ + int i; + + if (!rev->issuer) { + if (!nm) + return 1; + if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) + return 1; + return 0; + } + + if (!nm) + nm = X509_CRL_get_issuer(crl); + + for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gen->d.directoryName)) + return 1; + } + return 0; + +} + +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer) +{ + X509_REVOKED rtmp, *rev; + int idx; + rtmp.serialNumber = serial; + /* + * Sort revoked into serial number order if not already sorted. Do this + * under a lock to avoid race condition. + */ + if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { + CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); + sk_X509_REVOKED_sort(crl->crl->revoked); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); + } + idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); + if (idx < 0) + return 0; + /* Need to look for matching name */ + for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { + rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); + if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) + return 0; + if (crl_revoked_issuer_match(crl, issuer, rev)) { + if (ret) + *ret = rev; + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + return 1; + } + } + return 0; +} + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) +{ + if (meth == NULL) + default_crl_method = &int_crl_meth; + else + default_crl_method = meth; +} + +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)) +{ + X509_CRL_METHOD *m; + m = OPENSSL_malloc(sizeof(X509_CRL_METHOD)); + if (!m) + return NULL; + m->crl_init = crl_init; + m->crl_free = crl_free; + m->crl_lookup = crl_lookup; + m->crl_verify = crl_verify; + m->flags = X509_CRL_METHOD_DYNAMIC; + return m; +} + +void X509_CRL_METHOD_free(X509_CRL_METHOD *m) +{ + if (!(m->flags & X509_CRL_METHOD_DYNAMIC)) + return; + OPENSSL_free(m); +} + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat) +{ + crl->meth_data = dat; +} + +void *X509_CRL_get_meth_data(X509_CRL *crl) +{ + return crl->meth_data; +} + +IMPLEMENT_STACK_OF(X509_REVOKED) + +IMPLEMENT_ASN1_SET_OF(X509_REVOKED) + +IMPLEMENT_STACK_OF(X509_CRL) + +IMPLEMENT_ASN1_SET_OF(X509_CRL) +/* x_exten.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "x509.h" +// #include "asn1.h" +// #include "asn1t.h" + +ASN1_SEQUENCE(X509_EXTENSION) = { + ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT), + ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN), + ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(X509_EXTENSION) + +ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION) +ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS) + +IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION) +/* crypto/asn1/x_info.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "asn1.h" +// #include "x509.h" + +X509_INFO *X509_INFO_new(void) +{ + X509_INFO *ret = NULL; + + ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); + if (ret == NULL) { + ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->enc_cipher.cipher = NULL; + ret->enc_len = 0; + ret->enc_data = NULL; + + ret->references = 1; + ret->x509 = NULL; + ret->crl = NULL; + ret->x_pkey = NULL; + return (ret); +} + +void X509_INFO_free(X509_INFO *x) +{ + int i; + + if (x == NULL) + return; + + i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_INFO); +#ifdef REF_PRINT + REF_PRINT("X509_INFO", x); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "X509_INFO_free, bad reference count\n"); + abort(); + } +#endif + + if (x->x509 != NULL) + X509_free(x->x509); + if (x->crl != NULL) + X509_CRL_free(x->crl); + if (x->x_pkey != NULL) + X509_PKEY_free(x->x_pkey); + if (x->enc_data != NULL) + OPENSSL_free(x->enc_data); + OPENSSL_free(x); +} + +IMPLEMENT_STACK_OF(X509_INFO) +/* x_long.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "bn.h" + +/* + * Custom primitive type for long handling. This converts between an + * ASN1_INTEGER and a long directly. + */ + +static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it); +static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it); +static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx); + +static ASN1_PRIMITIVE_FUNCS long_pf = { + NULL, 0, + long_new, + long_free, + long_free, /* Clear should set to initial value */ + long_c2i, + long_i2c, + long_print +}; + +ASN1_ITEM_start(LONG) + ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG" +ASN1_ITEM_end(LONG) + +ASN1_ITEM_start(ZLONG) + ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG" +ASN1_ITEM_end(ZLONG) + +static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + *(long *)pval = it->size; + return 1; +} + +static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + *(long *)pval = it->size; +} + +static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it) +{ + long ltmp; + unsigned long utmp; + int clen, pad, i; + /* this exists to bypass broken gcc optimization */ + char *cp = (char *)pval; + + /* use memcpy, because we may not be long aligned */ + memcpy(<mp, cp, sizeof(long)); + + if (ltmp == it->size) + return -1; + /* + * Convert the long to positive: we subtract one if negative so we can + * cleanly handle the padding if only the MSB of the leading octet is + * set. + */ + if (ltmp < 0) + utmp = 0 - (unsigned long)ltmp - 1; + else + utmp = ltmp; + clen = BN_num_bits_word(utmp); + /* If MSB of leading octet set we need to pad */ + if (!(clen & 0x7)) + pad = 1; + else + pad = 0; + + /* Convert number of bits to number of octets */ + clen = (clen + 7) >> 3; + + if (cont) { + if (pad) + *cont++ = (ltmp < 0) ? 0xff : 0; + for (i = clen - 1; i >= 0; i--) { + cont[i] = (unsigned char)(utmp & 0xff); + if (ltmp < 0) + cont[i] ^= 0xff; + utmp >>= 8; + } + } + return clen + pad; +} + +static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) +{ + int neg = -1, i; + long ltmp; + unsigned long utmp = 0; + char *cp = (char *)pval; + + if (len) { + /* + * Check possible pad byte. Worst case, we're skipping past actual + * content, but since that's only with 0x00 and 0xff and we set neg + * accordingly, the result will be correct in the end anyway. + */ + switch (cont[0]) { + case 0xff: + cont++; + len--; + neg = 1; + break; + case 0: + cont++; + len--; + neg = 0; + break; + } + } + if (len > (int)sizeof(long)) { + ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); + return 0; + } + if (neg == -1) { + /* Is it negative? */ + if (len && (cont[0] & 0x80)) + neg = 1; + else + neg = 0; + } + utmp = 0; + for (i = 0; i < len; i++) { + utmp <<= 8; + if (neg) + utmp |= cont[i] ^ 0xff; + else + utmp |= cont[i]; + } + ltmp = (long)utmp; + if (neg) { + ltmp = -ltmp; + ltmp--; + } + if (ltmp == it->size) { + ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); + return 0; + } + memcpy(cp, <mp, sizeof(long)); + return 1; +} + +static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx) +{ + return BIO_printf(out, "%ld\n", *(long *)pval); +} +/* crypto/asn1/x_name.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" +// #include "asn1_locl.h" + +typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; +DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY) + +/* + * Maximum length of X509_NAME: much larger than anything we should + * ever see in practice. + */ + +#define X509_NAME_MAX (1024 * 1024) + +static int x509_name_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); +static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); + +static int x509_name_encode(X509_NAME *a); +static int x509_name_canon(X509_NAME *a); +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, + unsigned char **in); + +static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, + int indent, + const char *fname, const ASN1_PCTX *pctx); + +ASN1_SEQUENCE(X509_NAME_ENTRY) = { + ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), + ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) +} ASN1_SEQUENCE_END(X509_NAME_ENTRY) + +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) + +/* + * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so + * declare two template wrappers for this + */ + +ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) +ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) + +ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) +ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) + +/* + * Normally that's where it would end: we'd have two nested STACK structures + * representing the ASN1. Unfortunately X509_NAME uses a completely different + * form and caches encodings so we have to process the internal form and + * convert to the external form. + */ + +const ASN1_EXTERN_FUNCS x509_name_ff = { + NULL, + x509_name_ex_new, + x509_name_ex_free, + 0, /* Default clear behaviour is OK */ + x509_name_ex_d2i, + x509_name_ex_i2d, + x509_name_ex_print +}; + +IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) + +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) + +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) +{ + X509_NAME *ret = NULL; + ret = OPENSSL_malloc(sizeof(X509_NAME)); + if (!ret) + goto memerr; + if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) + goto memerr; + if ((ret->bytes = BUF_MEM_new()) == NULL) + goto memerr; + ret->canon_enc = NULL; + ret->canon_enclen = 0; + ret->modified = 1; + *val = (ASN1_VALUE *)ret; + return 1; + + memerr: + ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); + if (ret) { + if (ret->entries) + sk_X509_NAME_ENTRY_free(ret->entries); + OPENSSL_free(ret); + } + return 0; +} + +static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + X509_NAME *a; + if (!pval || !*pval) + return; + a = (X509_NAME *)*pval; + + BUF_MEM_free(a->bytes); + sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); + if (a->canon_enc) + OPENSSL_free(a->canon_enc); + OPENSSL_free(a); + *pval = NULL; +} + +static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) +{ + sk_X509_NAME_ENTRY_free(ne); +} + +static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) +{ + sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); +} + +static int x509_name_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, + char opt, ASN1_TLC *ctx) +{ + const unsigned char *p = *in, *q; + union { + STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; + ASN1_VALUE *a; + } intname = { + NULL + }; + union { + X509_NAME *x; + ASN1_VALUE *a; + } nm = { + NULL + }; + int i, j, ret; + STACK_OF(X509_NAME_ENTRY) *entries; + X509_NAME_ENTRY *entry; + if (len > X509_NAME_MAX) + len = X509_NAME_MAX; + q = p; + + /* Get internal representation of Name */ + ret = ASN1_item_ex_d2i(&intname.a, + &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), + tag, aclass, opt, ctx); + + if (ret <= 0) + return ret; + + if (*val) + x509_name_ex_free(val, NULL); + if (!x509_name_ex_new(&nm.a, NULL)) + goto err; + /* We've decoded it: now cache encoding */ + if (!BUF_MEM_grow(nm.x->bytes, p - q)) + goto err; + memcpy(nm.x->bytes->data, q, p - q); + + /* Convert internal representation to X509_NAME structure */ + for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { + entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); + for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { + entry = sk_X509_NAME_ENTRY_value(entries, j); + entry->set = i; + if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) + goto err; + sk_X509_NAME_ENTRY_set(entries, j, NULL); + } + } + ret = x509_name_canon(nm.x); + if (!ret) + goto err; + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); + nm.x->modified = 0; + *val = nm.a; + *in = p; + return ret; + err: + if (nm.x != NULL) + X509_NAME_free(nm.x); + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_pop_free); + ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; +} + +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + int ret; + X509_NAME *a = (X509_NAME *)*val; + if (a->modified) { + ret = x509_name_encode(a); + if (ret < 0) + return ret; + ret = x509_name_canon(a); + if (ret < 0) + return ret; + } + ret = a->bytes->length; + if (out != NULL) { + memcpy(*out, a->bytes->data, ret); + *out += ret; + } + return ret; +} + +static int x509_name_encode(X509_NAME *a) +{ + union { + STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; + ASN1_VALUE *a; + } intname = { + NULL + }; + int len; + unsigned char *p; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry; + int i, set = -1; + intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname.s) + goto memerr; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) + goto memerr; + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) { + sk_X509_NAME_ENTRY_free(entries); + goto memerr; + } + set = entry->set; + } + if (!sk_X509_NAME_ENTRY_push(entries, entry)) + goto memerr; + } + len = ASN1_item_ex_i2d(&intname.a, NULL, + ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); + if (!BUF_MEM_grow(a->bytes, len)) + goto memerr; + p = (unsigned char *)a->bytes->data; + ASN1_item_ex_i2d(&intname.a, + &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); + a->modified = 0; + return len; + memerr: + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); + ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); + return -1; +} + +static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, + int indent, + const char *fname, const ASN1_PCTX *pctx) +{ + if (X509_NAME_print_ex(out, (X509_NAME *)*pval, + indent, pctx->nm_flags) <= 0) + return 0; + return 2; +} + +/* + * This function generates the canonical encoding of the Name structure. In + * it all strings are converted to UTF8, leading, trailing and multiple + * spaces collapsed, converted to lower case and the leading SEQUENCE header + * removed. In future we could also normalize the UTF8 too. By doing this + * comparison of Name structures can be rapidly perfomed by just using + * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name + * constraints of type dirName can also be checked with a simple memcmp(). + */ + +static int x509_name_canon(X509_NAME *a) +{ + unsigned char *p; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry, *tmpentry = NULL; + int i, set = -1, ret = 0; + + if (a->canon_enc) { + OPENSSL_free(a->canon_enc); + a->canon_enc = NULL; + } + /* Special case: empty X509_NAME => null encoding */ + if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { + a->canon_enclen = 0; + return 1; + } + intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname) + goto err; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) + goto err; + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { + sk_X509_NAME_ENTRY_free(entries); + goto err; + } + set = entry->set; + } + tmpentry = X509_NAME_ENTRY_new(); + if (!tmpentry) + goto err; + tmpentry->object = OBJ_dup(entry->object); + if (!asn1_string_canon(tmpentry->value, entry->value)) + goto err; + if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) + goto err; + tmpentry = NULL; + } + + /* Finally generate encoding */ + + a->canon_enclen = i2d_name_canon(intname, NULL); + + p = OPENSSL_malloc(a->canon_enclen); + + if (!p) + goto err; + + a->canon_enc = p; + + i2d_name_canon(intname, &p); + + ret = 1; + + err: + + if (tmpentry) + X509_NAME_ENTRY_free(tmpentry); + if (intname) + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_pop_free); + return ret; +} + +/* Bitmap of all the types of string that will be canonicalized. */ + +#define ASN1_MASK_CANON \ + (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ + | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ + | B_ASN1_VISIBLESTRING) + +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) +{ + unsigned char *to, *from; + int len, i; + + /* If type not in bitmask just copy string across */ + if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { + if (!ASN1_STRING_copy(out, in)) + return 0; + return 1; + } + + out->type = V_ASN1_UTF8STRING; + out->length = ASN1_STRING_to_UTF8(&out->data, in); + if (out->length == -1) + return 0; + + to = out->data; + from = to; + + len = out->length; + + /* + * Convert string in place to canonical form. Ultimately we may need to + * handle a wider range of characters but for now ignore anything with + * MSB set and rely on the isspace() and tolower() functions. + */ + + /* Ignore leading spaces */ + while ((len > 0) && !(*from & 0x80) && isspace(*from)) { + from++; + len--; + } + + to = from + len - 1; + + /* Ignore trailing spaces */ + while ((len > 0) && !(*to & 0x80) && isspace(*to)) { + to--; + len--; + } + + to = out->data; + + i = 0; + while (i < len) { + /* If MSB set just copy across */ + if (*from & 0x80) { + *to++ = *from++; + i++; + } + /* Collapse multiple spaces */ + else if (isspace(*from)) { + /* Copy one space across */ + *to++ = ' '; + /* + * Ignore subsequent spaces. Note: don't need to check len here + * because we know the last character is a non-space so we can't + * overflow. + */ + do { + from++; + i++; + } + while (!(*from & 0x80) && isspace(*from)); + } else { + *to++ = tolower(*from); + from++; + i++; + } + } + + out->length = to - out->data; + + return 1; + +} + +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, + unsigned char **in) +{ + int i, len, ltmp; + ASN1_VALUE *v; + STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; + + len = 0; + for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { + v = sk_ASN1_VALUE_value(intname, i); + ltmp = ASN1_item_ex_i2d(&v, in, + ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); + if (ltmp < 0) + return ltmp; + len += ltmp; + } + return len; +} + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name) +{ + if ((name = X509_NAME_dup(name)) == NULL) + return 0; + X509_NAME_free(*xn); + *xn = name; + return 1; +} + +IMPLEMENT_STACK_OF(X509_NAME_ENTRY) + +IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY) +/* x_nx509.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "x509.h" +// #include "asn1.h" +// #include "asn1t.h" + +/* Old netscape certificate wrapper format */ + +ASN1_SEQUENCE(NETSCAPE_X509) = { + ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING), + ASN1_OPT(NETSCAPE_X509, cert, X509) +} ASN1_SEQUENCE_END(NETSCAPE_X509) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509) +/* crypto/asn1/x_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "objects.h" +#include "asn1_mac.h" +// #include "x509.h" + +/* need to implement */ +int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp) +{ + return (0); +} + +X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length) +{ + int i; + M_ASN1_D2I_vars(a, X509_PKEY *, X509_PKEY_new); + + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + M_ASN1_D2I_get_x(X509_ALGOR, ret->enc_algor, d2i_X509_ALGOR); + M_ASN1_D2I_get_x(ASN1_OCTET_STRING, ret->enc_pkey, d2i_ASN1_OCTET_STRING); + + ret->cipher.cipher = + EVP_get_cipherbyname(OBJ_nid2ln + (OBJ_obj2nid(ret->enc_algor->algorithm))); + if (ret->cipher.cipher == NULL) { + c.error = ASN1_R_UNSUPPORTED_CIPHER; + c.line = __LINE__; + goto err; + } + if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING) { + i = ret->enc_algor->parameter->value.octet_string->length; + if (i > EVP_MAX_IV_LENGTH) { + c.error = ASN1_R_IV_TOO_LARGE; + c.line = __LINE__; + goto err; + } + memcpy(ret->cipher.iv, + ret->enc_algor->parameter->value.octet_string->data, i); + } else + memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); + M_ASN1_D2I_Finish(a, X509_PKEY_free, ASN1_F_D2I_X509_PKEY); +} + +X509_PKEY *X509_PKEY_new(void) +{ + X509_PKEY *ret = NULL; + ASN1_CTX c; + + ret = OPENSSL_malloc(sizeof(X509_PKEY)); + if (ret == NULL) { + c.line = __LINE__; + goto err; + } + ret->version = 0; + ret->enc_algor = X509_ALGOR_new(); + ret->enc_pkey = M_ASN1_OCTET_STRING_new(); + ret->dec_pkey = NULL; + ret->key_length = 0; + ret->key_data = NULL; + ret->key_free = 0; + ret->cipher.cipher = NULL; + memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); + ret->references = 1; + if (ret->enc_algor == NULL || ret->enc_pkey == NULL) { + c.line = __LINE__; + goto err; + } + return ret; +err: + X509_PKEY_free(ret); + ASN1_MAC_H_err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE, c.line); + return NULL; +} + +void X509_PKEY_free(X509_PKEY *x) +{ + int i; + + if (x == NULL) + return; + + i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_PKEY); +#ifdef REF_PRINT + REF_PRINT("X509_PKEY", x); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "X509_PKEY_free, bad reference count\n"); + abort(); + } +#endif + + if (x->enc_algor != NULL) + X509_ALGOR_free(x->enc_algor); + if (x->enc_pkey != NULL) + M_ASN1_OCTET_STRING_free(x->enc_pkey); + if (x->dec_pkey != NULL) + EVP_PKEY_free(x->dec_pkey); + if ((x->key_data != NULL) && (x->key_free)) + OPENSSL_free(x->key_data); + OPENSSL_free(x); +} +/* crypto/asn1/x_pubkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" +// #include "asn1_locl.h" +#ifndef OPENSSL_NO_RSA +# include "rsa.h" +#endif +#ifndef OPENSSL_NO_DSA +# include "dsa.h" +#endif + +/* Minor tweak to operation: free up EVP_PKEY */ +static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; + EVP_PKEY_free(pubkey->pkey); + } + return 1; +} + +ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { + ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), + ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) + +IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) +{ + X509_PUBKEY *pk = NULL; + + if (x == NULL) + return (0); + + if ((pk = X509_PUBKEY_new()) == NULL) + goto error; + + if (pkey->ameth) { + if (pkey->ameth->pub_encode) { + if (!pkey->ameth->pub_encode(pk, pkey)) { + X509err(X509_F_X509_PUBKEY_SET, + X509_R_PUBLIC_KEY_ENCODE_ERROR); + goto error; + } + } else { + X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED); + goto error; + } + } else { + X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM); + goto error; + } + + if (*x != NULL) + X509_PUBKEY_free(*x); + + *x = pk; + + return 1; + error: + if (pk != NULL) + X509_PUBKEY_free(pk); + return 0; +} + +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) +{ + EVP_PKEY *ret = NULL; + + if (key == NULL) + goto error; + + if (key->pkey != NULL) { + CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + return key->pkey; + } + + if (key->public_key == NULL) + goto error; + + if ((ret = EVP_PKEY_new()) == NULL) { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); + goto error; + } + + if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) { + X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM); + goto error; + } + + if (ret->ameth->pub_decode) { + if (!ret->ameth->pub_decode(ret, key)) { + X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + } else { + X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED); + goto error; + } + + /* Check to see if another thread set key->pkey first */ + CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); + if (key->pkey) { + CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_free(ret); + ret = key->pkey; + } else { + key->pkey = ret; + CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + } + CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); + + return ret; + + error: + if (ret != NULL) + EVP_PKEY_free(ret); + return (NULL); +} + +/* + * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or + * decode as X509_PUBKEY + */ + +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) +{ + X509_PUBKEY *xpk; + EVP_PKEY *pktmp; + const unsigned char *q; + q = *pp; + xpk = d2i_X509_PUBKEY(NULL, &q, length); + if (!xpk) + return NULL; + pktmp = X509_PUBKEY_get(xpk); + X509_PUBKEY_free(xpk); + if (!pktmp) + return NULL; + *pp = q; + if (a) { + EVP_PKEY_free(*a); + *a = pktmp; + } + return pktmp; +} + +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) +{ + X509_PUBKEY *xpk = NULL; + int ret; + if (!a) + return 0; + if (!X509_PUBKEY_set(&xpk, a)) + return 0; + ret = i2d_X509_PUBKEY(xpk, pp); + X509_PUBKEY_free(xpk); + return ret; +} + +/* + * The following are equivalents but which return RSA and DSA keys + */ +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + RSA *key; + const unsigned char *q; + q = *pp; + pkey = d2i_PUBKEY(NULL, &q, length); + if (!pkey) + return NULL; + key = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + if (!key) + return NULL; + *pp = q; + if (a) { + RSA_free(*a); + *a = key; + } + return key; +} + +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (!pktmp) { + ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_PKEY_set1_RSA(pktmp, a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return ret; +} +#endif + +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + DSA *key; + const unsigned char *q; + q = *pp; + pkey = d2i_PUBKEY(NULL, &q, length); + if (!pkey) + return NULL; + key = EVP_PKEY_get1_DSA(pkey); + EVP_PKEY_free(pkey); + if (!key) + return NULL; + *pp = q; + if (a) { + DSA_free(*a); + *a = key; + } + return key; +} + +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (!pktmp) { + ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_PKEY_set1_DSA(pktmp, a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return ret; +} +#endif + +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + EC_KEY *key; + const unsigned char *q; + q = *pp; + pkey = d2i_PUBKEY(NULL, &q, length); + if (!pkey) + return (NULL); + key = EVP_PKEY_get1_EC_KEY(pkey); + EVP_PKEY_free(pkey); + if (!key) + return (NULL); + *pp = q; + if (a) { + EC_KEY_free(*a); + *a = key; + } + return (key); +} + +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return (0); + if ((pktmp = EVP_PKEY_new()) == NULL) { + ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + EVP_PKEY_set1_EC_KEY(pktmp, a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return (ret); +} +#endif + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen) +{ + if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) + return 0; + if (penc) { + if (pub->public_key->data) + OPENSSL_free(pub->public_key->data); + pub->public_key->data = penc; + pub->public_key->length = penclen; + /* Set number of unused bits to zero */ + pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; + } + return 1; +} + +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, X509_PUBKEY *pub) +{ + if (ppkalg) + *ppkalg = pub->algor->algorithm; + if (pk) { + *pk = pub->public_key->data; + *ppklen = pub->public_key->length; + } + if (pa) + *pa = pub->algor; + return 1; +} +/* crypto/asn1/x_req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" + +/*- + * X509_REQ_INFO is handled in an unusual way to get round + * invalid encodings. Some broken certificate requests don't + * encode the attributes field if it is empty. This is in + * violation of PKCS#10 but we need to tolerate it. We do + * this by making the attributes field OPTIONAL then using + * the callback to initialise it to an empty STACK. + * + * This means that the field will be correctly encoded unless + * we NULL out the field. + * + * As a result we no longer need the req_kludge field because + * the information is now contained in the attributes field: + * 1. If it is NULL then it's the invalid omission. + * 2. If it is empty it is the correct encoding. + * 3. If it is not empty then some attributes are present. + * + */ + +static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; + + if (operation == ASN1_OP_NEW_POST) { + rinf->attributes = sk_X509_ATTRIBUTE_new_null(); + if (!rinf->attributes) + return 0; + } + return 1; +} + +ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { + ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), + ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), + /* This isn't really OPTIONAL but it gets round invalid + * encodings + */ + ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0) +} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) + +ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = { + ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO), + ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) +/* crypto/asn1/x_sig.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" + +ASN1_SEQUENCE(X509_SIG) = { + ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR), + ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(X509_SIG) + +IMPLEMENT_ASN1_FUNCTIONS(X509_SIG) +/* crypto/asn1/x_spki.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + /* + * This module was send to me my Pat Richards who wrote it. + * It is under my Copyright with his permission + */ + +#include +// #include "cryptlib.h" +// #include "x509.h" +// #include "asn1t.h" + +ASN1_SEQUENCE(NETSCAPE_SPKAC) = { + ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY), + ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING) +} ASN1_SEQUENCE_END(NETSCAPE_SPKAC) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC) + +ASN1_SEQUENCE(NETSCAPE_SPKI) = { + ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC), + ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR), + ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(NETSCAPE_SPKI) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI) +/* crypto/asn1/x_val.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "asn1t.h" +// #include "x509.h" + +ASN1_SEQUENCE(X509_VAL) = { + ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME), + ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME) +} ASN1_SEQUENCE_END(X509_VAL) + +IMPLEMENT_ASN1_FUNCTIONS(X509_VAL) +/* crypto/asn1/x_x509.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "asn1t.h" +// #include "x509.h" +// #include "x509v3.h" + +ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { + ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), + ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR), + ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), + ASN1_SIMPLE(X509_CINF, validity, X509_VAL), + ASN1_SIMPLE(X509_CINF, subject, X509_NAME), + ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), + ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), + ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), + ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3) +} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) +/* X509 top level structure needs a bit of customisation */ + +extern void policy_cache_free(X509_POLICY_CACHE *cache); + +static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509 *ret = (X509 *)*pval; + + switch (operation) { + + case ASN1_OP_NEW_POST: + ret->valid = 0; + ret->name = NULL; + ret->ex_flags = 0; + ret->ex_pathlen = -1; + ret->skid = NULL; + ret->akid = NULL; +#ifndef OPENSSL_NO_RFC3779 + ret->rfc3779_addr = NULL; + ret->rfc3779_asid = NULL; +#endif + ret->aux = NULL; + ret->crldp = NULL; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); + break; + + case ASN1_OP_D2I_POST: + if (ret->name != NULL) + OPENSSL_free(ret->name); + ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0); + break; + + case ASN1_OP_FREE_POST: + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); + X509_CERT_AUX_free(ret->aux); + ASN1_OCTET_STRING_free(ret->skid); + AUTHORITY_KEYID_free(ret->akid); + CRL_DIST_POINTS_free(ret->crldp); + policy_cache_free(ret->policy_cache); + GENERAL_NAMES_free(ret->altname); + NAME_CONSTRAINTS_free(ret->nc); +#ifndef OPENSSL_NO_RFC3779 + sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); + ASIdentifiers_free(ret->rfc3779_asid); +#endif + + if (ret->name != NULL) + OPENSSL_free(ret->name); + break; + + } + + return 1; + +} + +ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = { + ASN1_SIMPLE(X509, cert_info, X509_CINF), + ASN1_SIMPLE(X509, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509, X509) + +IMPLEMENT_ASN1_FUNCTIONS(X509) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509) + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp, + new_func, dup_func, free_func); +} + +int X509_set_ex_data(X509 *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *X509_get_ex_data(X509 *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +/* + * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with + * extra info tagged on the end. Since these functions set how a certificate + * is trusted they should only be used when the certificate comes from a + * reliable source such as local storage. + */ + +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) +{ + const unsigned char *q; + X509 *ret; + int freeret = 0; + + /* Save start position */ + q = *pp; + + if (!a || *a == NULL) { + freeret = 1; + } + ret = d2i_X509(a, &q, length); + /* If certificate unreadable then forget it */ + if (!ret) + return NULL; + /* update length */ + length -= q - *pp; + if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length)) + goto err; + *pp = q; + return ret; + err: + if (freeret) { + X509_free(ret); + if (a) + *a = NULL; + } + return NULL; +} + +/* + * Serialize trusted certificate to *pp or just return the required buffer + * length if pp == NULL. We ultimately want to avoid modifying *pp in the + * error path, but that depends on similar hygiene in lower-level functions. + * Here we avoid compounding the problem. + */ +static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) +{ + int length, tmplen; + unsigned char *start = pp != NULL ? *pp : NULL; + + OPENSSL_assert(pp == NULL || *pp != NULL); + + /* + * This might perturb *pp on error, but fixing that belongs in i2d_X509() + * not here. It should be that if a == NULL length is zero, but we check + * both just in case. + */ + length = i2d_X509(a, pp); + if (length <= 0 || a == NULL) + return length; + + tmplen = i2d_X509_CERT_AUX(a->aux, pp); + if (tmplen < 0) { + if (start != NULL) + *pp = start; + return tmplen; + } + length += tmplen; + + return length; +} + +/* + * Serialize trusted certificate to *pp, or just return the required buffer + * length if pp == NULL. + * + * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since + * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do + * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the + * allocated buffer. + */ +int i2d_X509_AUX(X509 *a, unsigned char **pp) +{ + int length; + unsigned char *tmp; + + /* Buffer provided by caller */ + if (pp == NULL || *pp != NULL) + return i2d_x509_aux_internal(a, pp); + + /* Obtain the combined length */ + if ((length = i2d_x509_aux_internal(a, NULL)) <= 0) + return length; + + /* Allocate requisite combined storage */ + *pp = tmp = OPENSSL_malloc(length); + if (tmp == NULL) + return -1; /* Push error onto error stack? */ + + /* Encode, but keep *pp at the originally malloced pointer */ + length = i2d_x509_aux_internal(a, &tmp); + if (length <= 0) { + OPENSSL_free(*pp); + *pp = NULL; + } + return length; +} + +int i2d_re_X509_tbs(X509 *x, unsigned char **pp) +{ + x->cert_info->enc.modified = 1; + return i2d_X509_CINF(x->cert_info, pp); +} + +void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, + const X509 *x) +{ + if (psig) + *psig = x->signature; + if (palg) + *palg = x->sig_alg; +} + +int X509_get_signature_nid(const X509 *x) +{ + return OBJ_obj2nid(x->sig_alg->algorithm); +} +/* a_x509a.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +// #include "cryptlib.h" +// #include "evp.h" +// #include "asn1t.h" +// #include "x509.h" + +/* + * X509_CERT_AUX routines. These are used to encode additional user + * modifiable data about a certificate. This data is appended to the X509 + * encoding when the *_X509_AUX routines are used. This means that the + * "traditional" X509 routines will simply ignore the extra data. + */ + +static X509_CERT_AUX *aux_get(X509 *x); + +ASN1_SEQUENCE(X509_CERT_AUX) = { + ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT), + ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0), + ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING), + ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING), + ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1) +} ASN1_SEQUENCE_END(X509_CERT_AUX) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX) + +static X509_CERT_AUX *aux_get(X509 *x) +{ + if (!x) + return NULL; + if (!x->aux && !(x->aux = X509_CERT_AUX_new())) + return NULL; + return x->aux; +} + +int X509_alias_set1(X509 *x, unsigned char *name, int len) +{ + X509_CERT_AUX *aux; + if (!name) { + if (!x || !x->aux || !x->aux->alias) + return 1; + ASN1_UTF8STRING_free(x->aux->alias); + x->aux->alias = NULL; + return 1; + } + if (!(aux = aux_get(x))) + return 0; + if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) + return 0; + return ASN1_STRING_set(aux->alias, name, len); +} + +int X509_keyid_set1(X509 *x, unsigned char *id, int len) +{ + X509_CERT_AUX *aux; + if (!id) { + if (!x || !x->aux || !x->aux->keyid) + return 1; + ASN1_OCTET_STRING_free(x->aux->keyid); + x->aux->keyid = NULL; + return 1; + } + if (!(aux = aux_get(x))) + return 0; + if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) + return 0; + return ASN1_STRING_set(aux->keyid, id, len); +} + +unsigned char *X509_alias_get0(X509 *x, int *len) +{ + if (!x->aux || !x->aux->alias) + return NULL; + if (len) + *len = x->aux->alias->length; + return x->aux->alias->data; +} + +unsigned char *X509_keyid_get0(X509 *x, int *len) +{ + if (!x->aux || !x->aux->keyid) + return NULL; + if (len) + *len = x->aux->keyid->length; + return x->aux->keyid->data; +} + +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) +{ + X509_CERT_AUX *aux; + ASN1_OBJECT *objtmp; + if (!(objtmp = OBJ_dup(obj))) + return 0; + if (!(aux = aux_get(x))) + return 0; + if (!aux->trust && !(aux->trust = sk_ASN1_OBJECT_new_null())) + return 0; + return sk_ASN1_OBJECT_push(aux->trust, objtmp); +} + +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) +{ + X509_CERT_AUX *aux; + ASN1_OBJECT *objtmp; + if (!(objtmp = OBJ_dup(obj))) + return 0; + if (!(aux = aux_get(x))) + goto err; + if (!aux->reject && !(aux->reject = sk_ASN1_OBJECT_new_null())) + goto err; + return sk_ASN1_OBJECT_push(aux->reject, objtmp); + err: + ASN1_OBJECT_free(objtmp); + return 0; +} + +void X509_trust_clear(X509 *x) +{ + if (x->aux && x->aux->trust) { + sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free); + x->aux->trust = NULL; + } +} + +void X509_reject_clear(X509 *x) +{ + if (x->aux && x->aux->reject) { + sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free); + x->aux->reject = NULL; + } +} + +ASN1_SEQUENCE(X509_CERT_PAIR) = { + ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0), + ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1) +} ASN1_SEQUENCE_END(X509_CERT_PAIR) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR) diff --git a/Sources/COpenSSL/xcbc_enc.c b/Sources/COpenSSL/xcbc_enc.c new file mode 100644 index 00000000..6fe021be --- /dev/null +++ b/Sources/COpenSSL/xcbc_enc.c @@ -0,0 +1,216 @@ +/* crypto/des/xcbc_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* RSA's DESX */ + +#if 0 /* broken code, preserved just in case anyone + * specifically looks for this */ +static const unsigned char desx_white_in2out[256] = { + 0xBD, 0x56, 0xEA, 0xF2, 0xA2, 0xF1, 0xAC, 0x2A, 0xB0, 0x93, 0xD1, 0x9C, + 0x1B, 0x33, 0xFD, 0xD0, + 0x30, 0x04, 0xB6, 0xDC, 0x7D, 0xDF, 0x32, 0x4B, 0xF7, 0xCB, 0x45, 0x9B, + 0x31, 0xBB, 0x21, 0x5A, + 0x41, 0x9F, 0xE1, 0xD9, 0x4A, 0x4D, 0x9E, 0xDA, 0xA0, 0x68, 0x2C, 0xC3, + 0x27, 0x5F, 0x80, 0x36, + 0x3E, 0xEE, 0xFB, 0x95, 0x1A, 0xFE, 0xCE, 0xA8, 0x34, 0xA9, 0x13, 0xF0, + 0xA6, 0x3F, 0xD8, 0x0C, + 0x78, 0x24, 0xAF, 0x23, 0x52, 0xC1, 0x67, 0x17, 0xF5, 0x66, 0x90, 0xE7, + 0xE8, 0x07, 0xB8, 0x60, + 0x48, 0xE6, 0x1E, 0x53, 0xF3, 0x92, 0xA4, 0x72, 0x8C, 0x08, 0x15, 0x6E, + 0x86, 0x00, 0x84, 0xFA, + 0xF4, 0x7F, 0x8A, 0x42, 0x19, 0xF6, 0xDB, 0xCD, 0x14, 0x8D, 0x50, 0x12, + 0xBA, 0x3C, 0x06, 0x4E, + 0xEC, 0xB3, 0x35, 0x11, 0xA1, 0x88, 0x8E, 0x2B, 0x94, 0x99, 0xB7, 0x71, + 0x74, 0xD3, 0xE4, 0xBF, + 0x3A, 0xDE, 0x96, 0x0E, 0xBC, 0x0A, 0xED, 0x77, 0xFC, 0x37, 0x6B, 0x03, + 0x79, 0x89, 0x62, 0xC6, + 0xD7, 0xC0, 0xD2, 0x7C, 0x6A, 0x8B, 0x22, 0xA3, 0x5B, 0x05, 0x5D, 0x02, + 0x75, 0xD5, 0x61, 0xE3, + 0x18, 0x8F, 0x55, 0x51, 0xAD, 0x1F, 0x0B, 0x5E, 0x85, 0xE5, 0xC2, 0x57, + 0x63, 0xCA, 0x3D, 0x6C, + 0xB4, 0xC5, 0xCC, 0x70, 0xB2, 0x91, 0x59, 0x0D, 0x47, 0x20, 0xC8, 0x4F, + 0x58, 0xE0, 0x01, 0xE2, + 0x16, 0x38, 0xC4, 0x6F, 0x3B, 0x0F, 0x65, 0x46, 0xBE, 0x7E, 0x2D, 0x7B, + 0x82, 0xF9, 0x40, 0xB5, + 0x1D, 0x73, 0xF8, 0xEB, 0x26, 0xC7, 0x87, 0x97, 0x25, 0x54, 0xB1, 0x28, + 0xAA, 0x98, 0x9D, 0xA5, + 0x64, 0x6D, 0x7A, 0xD4, 0x10, 0x81, 0x44, 0xEF, 0x49, 0xD6, 0xAE, 0x2E, + 0xDD, 0x76, 0x5C, 0x2F, + 0xA7, 0x1C, 0xC9, 0x09, 0x69, 0x9A, 0x83, 0xCF, 0x29, 0x39, 0xB9, 0xE9, + 0x4C, 0xFF, 0x43, 0xAB, +}; + +void DES_xwhite_in2out(const_DES_cblock *des_key, const_DES_cblock *in_white, + DES_cblock *out_white) +{ + int out0, out1; + int i; + const unsigned char *key = &(*des_key)[0]; + const unsigned char *in = &(*in_white)[0]; + unsigned char *out = &(*out_white)[0]; + + out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = 0; + out0 = out1 = 0; + for (i = 0; i < 8; i++) { + out[i] = key[i] ^ desx_white_in2out[out0 ^ out1]; + out0 = out1; + out1 = (int)out[i & 0x07]; + } + + out0 = out[0]; + out1 = out[i]; /* BUG: out-of-bounds read */ + for (i = 0; i < 8; i++) { + out[i] = in[i] ^ desx_white_in2out[out0 ^ out1]; + out0 = out1; + out1 = (int)out[i & 0x07]; + } +} +#endif + +void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc) +{ + register DES_LONG tin0, tin1; + register DES_LONG tout0, tout1, xor0, xor1; + register DES_LONG inW0, inW1, outW0, outW1; + register const unsigned char *in2; + register long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + in2 = &(*inw)[0]; + c2l(in2, inW0); + c2l(in2, inW1); + in2 = &(*outw)[0]; + c2l(in2, outW0); + c2l(in2, outW1); + + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0 ^ inW0; + tin[0] = tin0; + tin1 ^= tout1 ^ inW1; + tin[1] = tin1; + DES_encrypt1(tin, schedule, DES_ENCRYPT); + tout0 = tin[0] ^ outW0; + l2c(tout0, out); + tout1 = tin[1] ^ outW1; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0 ^ inW0; + tin[0] = tin0; + tin1 ^= tout1 ^ inW1; + tin[1] = tin1; + DES_encrypt1(tin, schedule, DES_ENCRYPT); + tout0 = tin[0] ^ outW0; + l2c(tout0, out); + tout1 = tin[1] ^ outW1; + l2c(tout1, out); + } + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l > 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0 ^ outW0; + c2l(in, tin1); + tin[1] = tin1 ^ outW1; + DES_encrypt1(tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0 ^ inW0; + tout1 = tin[1] ^ xor1 ^ inW1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0 ^ outW0; + c2l(in, tin1); + tin[1] = tin1 ^ outW1; + DES_encrypt1(tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0 ^ inW0; + tout1 = tin[1] ^ xor1 ^ inW1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + inW0 = inW1 = outW0 = outW1 = 0; + tin[0] = tin[1] = 0; +} diff --git a/Sources/COpenSSL/xts128.c b/Sources/COpenSSL/xts128.c new file mode 100644 index 00000000..59b439c1 --- /dev/null +++ b/Sources/COpenSSL/xts128.c @@ -0,0 +1,204 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "crypto.h" +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + union { + u64 u[2]; + u32 d[4]; + u8 c[16]; + } tweak, scratch; + unsigned int i; + + if (len < 16) + return -1; + + memcpy(tweak.c, iv, 16); + + (*ctx->block2) (tweak.c, tweak.c, ctx->key2); + + if (!enc && (len % 16)) + len -= 16; + + while (len >= 16) { +#if defined(STRICT_ALIGNMENT) + memcpy(scratch.c, inp, 16); + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; +#else + scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0]; + scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1]; +#endif + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); +#if defined(STRICT_ALIGNMENT) + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out, scratch.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0]; + ((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1]; +#endif + inp += 16; + out += 16; + len -= 16; + + if (len == 0) + return 0; + + if (is_endian.little) { + unsigned int carry, res; + + res = 0x87 & (((int)tweak.d[3]) >> 31); + carry = (unsigned int)(tweak.u[0] >> 63); + tweak.u[0] = (tweak.u[0] << 1) ^ res; + tweak.u[1] = (tweak.u[1] << 1) | carry; + } else { + size_t c; + + for (c = 0, i = 0; i < 16; ++i) { + /* + * + substitutes for |, because c is 1 bit + */ + c += ((size_t)tweak.c[i]) << 1; + tweak.c[i] = (u8)c; + c = c >> 8; + } + tweak.c[0] ^= (u8)(0x87 & (0 - c)); + } + } + if (enc) { + for (i = 0; i < len; ++i) { + u8 c = inp[i]; + out[i] = scratch.c[i]; + scratch.c[i] = c; + } + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out - 16, scratch.c, 16); + } else { + union { + u64 u[2]; + u8 c[16]; + } tweak1; + + if (is_endian.little) { + unsigned int carry, res; + + res = 0x87 & (((int)tweak.d[3]) >> 31); + carry = (unsigned int)(tweak.u[0] >> 63); + tweak1.u[0] = (tweak.u[0] << 1) ^ res; + tweak1.u[1] = (tweak.u[1] << 1) | carry; + } else { + size_t c; + + for (c = 0, i = 0; i < 16; ++i) { + /* + * + substitutes for |, because c is 1 bit + */ + c += ((size_t)tweak.c[i]) << 1; + tweak1.c[i] = (u8)c; + c = c >> 8; + } + tweak1.c[0] ^= (u8)(0x87 & (0 - c)); + } +#if defined(STRICT_ALIGNMENT) + memcpy(scratch.c, inp, 16); + scratch.u[0] ^= tweak1.u[0]; + scratch.u[1] ^= tweak1.u[1]; +#else + scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0]; + scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1]; +#endif + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); + scratch.u[0] ^= tweak1.u[0]; + scratch.u[1] ^= tweak1.u[1]; + + for (i = 0; i < len; ++i) { + u8 c = inp[16 + i]; + out[16 + i] = scratch.c[i]; + scratch.c[i] = c; + } + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); +#if defined(STRICT_ALIGNMENT) + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out, scratch.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0]; + ((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1]; +#endif + } + + return 0; +} diff --git a/Sources/LinuxBridge/LinuxBridge.c b/Sources/LinuxBridge/LinuxBridge.c new file mode 100644 index 00000000..480ee5c5 --- /dev/null +++ b/Sources/LinuxBridge/LinuxBridge.c @@ -0,0 +1,25 @@ + +#include "LinuxBridge.h" + +#undef SIG_IGN +__sighandler_t SIG_IGN = (__sighandler_t)1; + +int linux_fcntl_get(int fd, int cmd) +{ + return fcntl(fd, cmd); +} + +int linux_fcntl_set(int fd, int cmd, int value) +{ + return fcntl(fd, cmd, value); +} + +int linux_open(const char *path, int oflag, mode_t mode) +{ + return open(path, oflag, mode); +} + +int linux_errno() +{ + return errno; +} diff --git a/Sources/LinuxBridge/include/LinuxBridge.h b/Sources/LinuxBridge/include/LinuxBridge.h new file mode 100644 index 00000000..2ccc2d2a --- /dev/null +++ b/Sources/LinuxBridge/include/LinuxBridge.h @@ -0,0 +1,26 @@ +#ifndef _LINUXBRIDGE_H_ +#define _LINUXBRIDGE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef SIG_IGN +__sighandler_t SIG_IGN; + +int linux_fcntl_get(int fd, int cmd); +int linux_fcntl_set(int fd, int cmd, int value); +int linux_open(const char *path, int oflag, mode_t mode); +int linux_errno(); + +#endif diff --git a/Sources/PerfectCHTTPParser/http_parser.c b/Sources/PerfectCHTTPParser/http_parser.c new file mode 100755 index 00000000..895bf0c7 --- /dev/null +++ b/Sources/PerfectCHTTPParser/http_parser.c @@ -0,0 +1,2470 @@ +/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev + * + * Additional changes are licensed under the same terms as NGINX and + * copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#include "http_parser.h" +#include +#include +#include +#include +#include +#include + +#ifndef ULLONG_MAX +# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ +#endif + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#ifndef BIT_AT +# define BIT_AT(a, i) \ + (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ + (1 << ((unsigned int) (i) & 7)))) +#endif + +#ifndef ELEM_AT +# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v)) +#endif + +#define SET_ERRNO(e) \ +do { \ + parser->http_errno = (e); \ +} while(0) + +#define CURRENT_STATE() p_state +#define UPDATE_STATE(V) p_state = (enum state) (V); +#define RETURN(V) \ +do { \ + parser->state = CURRENT_STATE(); \ + return (V); \ +} while (0); +#define REEXECUTE() \ + goto reexecute; \ + + +#ifdef __GNUC__ +# define LIKELY(X) __builtin_expect(!!(X), 1) +# define UNLIKELY(X) __builtin_expect(!!(X), 0) +#else +# define LIKELY(X) (X) +# define UNLIKELY(X) (X) +#endif + + +/* Run the notify callback FOR, returning ER if it fails */ +#define CALLBACK_NOTIFY_(FOR, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != settings->on_##FOR(parser))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + UPDATE_STATE(parser->state); \ + \ + /* We either errored above or got paused; get out */ \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ + return (ER); \ + } \ + } \ +} while (0) + +/* Run the notify callback FOR and consume the current byte */ +#define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1) + +/* Run the notify callback FOR and don't consume the current byte */ +#define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data) + +/* Run data callback FOR with LEN bytes, returning ER if it fails */ +#define CALLBACK_DATA_(FOR, LEN, ER) \ +do { \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (FOR##_mark) { \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != \ + settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + UPDATE_STATE(parser->state); \ + \ + /* We either errored above or got paused; get out */ \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ + return (ER); \ + } \ + } \ + FOR##_mark = NULL; \ + } \ +} while (0) + +/* Run the data callback FOR and consume the current byte */ +#define CALLBACK_DATA(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) + +/* Run the data callback FOR and don't consume the current byte */ +#define CALLBACK_DATA_NOADVANCE(FOR) \ + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) + +/* Set the mark FOR; non-destructive if mark is already set */ +#define MARK(FOR) \ +do { \ + if (!FOR##_mark) { \ + FOR##_mark = p; \ + } \ +} while (0) + +/* Don't allow the total size of the HTTP headers (including the status + * line) to exceed HTTP_MAX_HEADER_SIZE. This check is here to protect + * embedders against denial-of-service attacks where the attacker feeds + * us a never-ending header that the embedder keeps buffering. + * + * This check is arguably the responsibility of embedders but we're doing + * it on the embedder's behalf because most won't bother and this way we + * make the web a little safer. HTTP_MAX_HEADER_SIZE is still far bigger + * than any reasonable request or response so this should never affect + * day-to-day operation. + */ +#define COUNT_HEADER_SIZE(V) \ +do { \ + parser->nread += (V); \ + if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \ + SET_ERRNO(HPE_HEADER_OVERFLOW); \ + goto error; \ + } \ +} while (0) + + +#define PROXY_CONNECTION "proxy-connection" +#define CONNECTION "connection" +#define CONTENT_LENGTH "content-length" +#define TRANSFER_ENCODING "transfer-encoding" +#define UPGRADE "upgrade" +#define CHUNKED "chunked" +#define KEEP_ALIVE "keep-alive" +#define CLOSE "close" + + +static const char *method_strings[] = + { +#define XX(num, name, string) #string, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +/* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ +static const char tokens[256] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0, '!', 0, '#', '$', '%', '&', '\'', +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 0, 0, '*', '+', 0, '-', '.', 0, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + '0', '1', '2', '3', '4', '5', '6', '7', +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + '8', '9', 0, 0, 0, 0, 0, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 'x', 'y', 'z', 0, 0, 0, '^', '_', +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 'x', 'y', 'z', 0, '|', 0, '~', 0 }; + + +static const int8_t unhex[256] = + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; + + +#if HTTP_PARSER_STRICT +# define T(v) 0 +#else +# define T(v) v +#endif + + +static const uint8_t normal_url_char[32] = { +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; + +#undef T + +enum state + { s_dead = 1 /* important that this is > 0 */ + + , s_start_req_or_res + , s_res_or_resp_H + , s_start_res + , s_res_H + , s_res_HT + , s_res_HTT + , s_res_HTTP + , s_res_first_http_major + , s_res_http_major + , s_res_first_http_minor + , s_res_http_minor + , s_res_first_status_code + , s_res_status_code + , s_res_status_start + , s_res_status + , s_res_line_almost_done + + , s_start_req + + , s_req_method + , s_req_spaces_before_url + , s_req_schema + , s_req_schema_slash + , s_req_schema_slash_slash + , s_req_server_start + , s_req_server + , s_req_server_with_at + , s_req_path + , s_req_query_string_start + , s_req_query_string + , s_req_fragment_start + , s_req_fragment + , s_req_http_start + , s_req_http_H + , s_req_http_HT + , s_req_http_HTT + , s_req_http_HTTP + , s_req_first_http_major + , s_req_http_major + , s_req_first_http_minor + , s_req_http_minor + , s_req_line_almost_done + + , s_header_field_start + , s_header_field + , s_header_value_discard_ws + , s_header_value_discard_ws_almost_done + , s_header_value_discard_lws + , s_header_value_start + , s_header_value + , s_header_value_lws + + , s_header_almost_done + + , s_chunk_size_start + , s_chunk_size + , s_chunk_parameters + , s_chunk_size_almost_done + + , s_headers_almost_done + , s_headers_done + + /* Important: 's_headers_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + + , s_chunk_data + , s_chunk_data_almost_done + , s_chunk_data_done + + , s_body_identity + , s_body_identity_eof + + , s_message_done + }; + + +#define PARSING_HEADER(state) (state <= s_headers_done) + + +enum header_states + { h_general = 0 + , h_C + , h_CO + , h_CON + + , h_matching_connection + , h_matching_proxy_connection + , h_matching_content_length + , h_matching_transfer_encoding + , h_matching_upgrade + + , h_connection + , h_content_length + , h_transfer_encoding + , h_upgrade + + , h_matching_transfer_encoding_chunked + , h_matching_connection_token_start + , h_matching_connection_keep_alive + , h_matching_connection_close + , h_matching_connection_upgrade + , h_matching_connection_token + + , h_transfer_encoding_chunked + , h_connection_keep_alive + , h_connection_close + , h_connection_upgrade + }; + +enum http_host_state + { + s_http_host_dead = 1 + , s_http_userinfo_start + , s_http_userinfo + , s_http_host_start + , s_http_host_v6_start + , s_http_host + , s_http_host_v6 + , s_http_host_v6_end + , s_http_host_v6_zone_start + , s_http_host_v6_zone + , s_http_host_port_start + , s_http_host_port +}; + +/* Macros for character classes; depends on strict-mode */ +#define CR '\r' +#define LF '\n' +#define LOWER(c) (unsigned char)(c | 0x20) +#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') +#define IS_NUM(c) ((c) >= '0' && (c) <= '9') +#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) +#define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) +#define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ + (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ + (c) == ')') +#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ + (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ + (c) == '$' || (c) == ',') + +#define STRICT_TOKEN(c) (tokens[(unsigned char)c]) + +#if HTTP_PARSER_STRICT +#define TOKEN(c) (tokens[(unsigned char)c]) +#define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) +#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') +#else +#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) +#define IS_URL_CHAR(c) \ + (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) +#define IS_HOST_CHAR(c) \ + (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') +#endif + +/** + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + **/ +#define IS_HEADER_CHAR(ch) \ + (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127)) + +#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) + + +#if HTTP_PARSER_STRICT +# define STRICT_CHECK(cond) \ +do { \ + if (cond) { \ + SET_ERRNO(HPE_STRICT); \ + goto error; \ + } \ +} while (0) +# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) +#else +# define STRICT_CHECK(cond) +# define NEW_MESSAGE() start_state +#endif + + +/* Map errno values to strings for human-readable output */ +#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, +static struct { + const char *name; + const char *description; +} http_strerror_tab[] = { + HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) +}; +#undef HTTP_STRERROR_GEN + +int http_message_needs_eof(const http_parser *parser); + +/* Our URL parser. + * + * This is designed to be shared by http_parser_execute() for URL validation, + * hence it has a state transition + byte-for-byte interface. In addition, it + * is meant to be embedded in http_parser_parse_url(), which does the dirty + * work of turning state transitions URL components for its API. + * + * This function should only be invoked with non-space characters. It is + * assumed that the caller cares about (and can detect) the transition between + * URL and non-URL states by looking for these. + */ +static enum state +parse_url_char(enum state s, const char ch) +{ + if (ch == ' ' || ch == '\r' || ch == '\n') { + return s_dead; + } + +#if HTTP_PARSER_STRICT + if (ch == '\t' || ch == '\f') { + return s_dead; + } +#endif + + switch (s) { + case s_req_spaces_before_url: + /* Proxied requests are followed by scheme of an absolute URI (alpha). + * All methods except CONNECT are followed by '/' or '*'. + */ + + if (ch == '/' || ch == '*') { + return s_req_path; + } + + if (IS_ALPHA(ch)) { + return s_req_schema; + } + + break; + + case s_req_schema: + if (IS_ALPHA(ch)) { + return s; + } + + if (ch == ':') { + return s_req_schema_slash; + } + + break; + + case s_req_schema_slash: + if (ch == '/') { + return s_req_schema_slash_slash; + } + + break; + + case s_req_schema_slash_slash: + if (ch == '/') { + return s_req_server_start; + } + + break; + + case s_req_server_with_at: + if (ch == '@') { + return s_dead; + } + + /* FALLTHROUGH */ + case s_req_server_start: + case s_req_server: + if (ch == '/') { + return s_req_path; + } + + if (ch == '?') { + return s_req_query_string_start; + } + + if (ch == '@') { + return s_req_server_with_at; + } + + if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { + return s_req_server; + } + + break; + + case s_req_path: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + return s_req_query_string_start; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_query_string_start: + case s_req_query_string: + if (IS_URL_CHAR(ch)) { + return s_req_query_string; + } + + switch (ch) { + case '?': + /* allow extra '?' in query string */ + return s_req_query_string; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_fragment_start: + if (IS_URL_CHAR(ch)) { + return s_req_fragment; + } + + switch (ch) { + case '?': + return s_req_fragment; + + case '#': + return s; + } + + break; + + case s_req_fragment: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + case '#': + return s; + } + + break; + + default: + break; + } + + /* We should never fall out of the switch above unless there's an error */ + return s_dead; +} + +size_t http_parser_execute (http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len) +{ + char c, ch; + int8_t unhex_val; + const char *p = data; + const char *header_field_mark = 0; + const char *header_value_mark = 0; + const char *url_mark = 0; + const char *body_mark = 0; + const char *status_mark = 0; + enum state p_state = (enum state) parser->state; + const unsigned int lenient = parser->lenient_http_headers; + + /* We're in an error state. Don't bother doing anything. */ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + return 0; + } + + if (len == 0) { + switch (CURRENT_STATE()) { + case s_body_identity_eof: + /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if + * we got paused. + */ + CALLBACK_NOTIFY_NOADVANCE(message_complete); + return 0; + + case s_dead: + case s_start_req_or_res: + case s_start_res: + case s_start_req: + return 0; + + default: + SET_ERRNO(HPE_INVALID_EOF_STATE); + return 1; + } + } + + + if (CURRENT_STATE() == s_header_field) + header_field_mark = data; + if (CURRENT_STATE() == s_header_value) + header_value_mark = data; + switch (CURRENT_STATE()) { + case s_req_path: + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_server: + case s_req_server_with_at: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + url_mark = data; + break; + case s_res_status: + status_mark = data; + break; + default: + break; + } + + for (p=data; p != data + len; p++) { + ch = *p; + + if (PARSING_HEADER(CURRENT_STATE())) + COUNT_HEADER_SIZE(1); + +reexecute: + switch (CURRENT_STATE()) { + + case s_dead: + /* this state is used after a 'Connection: close' message + * the parser will error out if it reads another message + */ + if (LIKELY(ch == CR || ch == LF)) + break; + + SET_ERRNO(HPE_CLOSED_CONNECTION); + goto error; + + case s_start_req_or_res: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (ch == 'H') { + UPDATE_STATE(s_res_or_resp_H); + + CALLBACK_NOTIFY(message_begin); + } else { + parser->type = HTTP_REQUEST; + UPDATE_STATE(s_start_req); + REEXECUTE(); + } + + break; + } + + case s_res_or_resp_H: + if (ch == 'T') { + parser->type = HTTP_RESPONSE; + UPDATE_STATE(s_res_HT); + } else { + if (UNLIKELY(ch != 'E')) { + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + parser->type = HTTP_REQUEST; + parser->method = HTTP_HEAD; + parser->index = 2; + UPDATE_STATE(s_req_method); + } + break; + + case s_start_res: + { + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + switch (ch) { + case 'H': + UPDATE_STATE(s_res_H); + break; + + case CR: + case LF: + break; + + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + CALLBACK_NOTIFY(message_begin); + break; + } + + case s_res_H: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_res_HT); + break; + + case s_res_HT: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_res_HTT); + break; + + case s_res_HTT: + STRICT_CHECK(ch != 'P'); + UPDATE_STATE(s_res_HTTP); + break; + + case s_res_HTTP: + STRICT_CHECK(ch != '/'); + UPDATE_STATE(s_res_first_http_major); + break; + + case s_res_first_http_major: + if (UNLIKELY(ch < '0' || ch > '9')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + UPDATE_STATE(s_res_http_major); + break; + + /* major HTTP version or dot */ + case s_res_http_major: + { + if (ch == '.') { + UPDATE_STATE(s_res_first_http_minor); + break; + } + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (UNLIKELY(parser->http_major > 999)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* first digit of minor HTTP version */ + case s_res_first_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + UPDATE_STATE(s_res_http_minor); + break; + + /* minor HTTP version or end of request line */ + case s_res_http_minor: + { + if (ch == ' ') { + UPDATE_STATE(s_res_first_status_code); + break; + } + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (UNLIKELY(parser->http_minor > 999)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + case s_res_first_status_code: + { + if (!IS_NUM(ch)) { + if (ch == ' ') { + break; + } + + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + parser->status_code = ch - '0'; + UPDATE_STATE(s_res_status_code); + break; + } + + case s_res_status_code: + { + if (!IS_NUM(ch)) { + switch (ch) { + case ' ': + UPDATE_STATE(s_res_status_start); + break; + case CR: + UPDATE_STATE(s_res_line_almost_done); + break; + case LF: + UPDATE_STATE(s_header_field_start); + break; + default: + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + break; + } + + parser->status_code *= 10; + parser->status_code += ch - '0'; + + if (UNLIKELY(parser->status_code > 999)) { + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + + break; + } + + case s_res_status_start: + { + if (ch == CR) { + UPDATE_STATE(s_res_line_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + break; + } + + MARK(status); + UPDATE_STATE(s_res_status); + parser->index = 0; + break; + } + + case s_res_status: + if (ch == CR) { + UPDATE_STATE(s_res_line_almost_done); + CALLBACK_DATA(status); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA(status); + break; + } + + break; + + case s_res_line_almost_done: + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_field_start); + break; + + case s_start_req: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (UNLIKELY(!IS_ALPHA(ch))) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + parser->method = (enum http_method) 0; + parser->index = 1; + switch (ch) { + case 'A': parser->method = HTTP_ACL; break; + case 'B': parser->method = HTTP_BIND; break; + case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; + case 'D': parser->method = HTTP_DELETE; break; + case 'G': parser->method = HTTP_GET; break; + case 'H': parser->method = HTTP_HEAD; break; + case 'L': parser->method = HTTP_LOCK; /* or LINK */ break; + case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; + case 'N': parser->method = HTTP_NOTIFY; break; + case 'O': parser->method = HTTP_OPTIONS; break; + case 'P': parser->method = HTTP_POST; + /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ + break; + case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break; + case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; + case 'T': parser->method = HTTP_TRACE; break; + case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break; + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + UPDATE_STATE(s_req_method); + + CALLBACK_NOTIFY(message_begin); + + break; + } + + case s_req_method: + { + const char *matcher; + if (UNLIKELY(ch == '\0')) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + matcher = method_strings[parser->method]; + if (ch == ' ' && matcher[parser->index] == '\0') { + UPDATE_STATE(s_req_spaces_before_url); + } else if (ch == matcher[parser->index]) { + ; /* nada */ + } else if (IS_ALPHA(ch)) { + + switch (parser->method << 16 | parser->index << 8 | ch) { +#define XX(meth, pos, ch, new_meth) \ + case (HTTP_##meth << 16 | pos << 8 | ch): \ + parser->method = HTTP_##new_meth; break; + + XX(POST, 1, 'U', PUT) + XX(POST, 1, 'A', PATCH) + XX(CONNECT, 1, 'H', CHECKOUT) + XX(CONNECT, 2, 'P', COPY) + XX(MKCOL, 1, 'O', MOVE) + XX(MKCOL, 1, 'E', MERGE) + XX(MKCOL, 2, 'A', MKACTIVITY) + XX(MKCOL, 3, 'A', MKCALENDAR) + XX(SUBSCRIBE, 1, 'E', SEARCH) + XX(REPORT, 2, 'B', REBIND) + XX(POST, 1, 'R', PROPFIND) + XX(PROPFIND, 4, 'P', PROPPATCH) + XX(PUT, 2, 'R', PURGE) + XX(LOCK, 1, 'I', LINK) + XX(UNLOCK, 2, 'S', UNSUBSCRIBE) + XX(UNLOCK, 2, 'B', UNBIND) + XX(UNLOCK, 3, 'I', UNLINK) +#undef XX + + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + } else if (ch == '-' && + parser->index == 1 && + parser->method == HTTP_MKCOL) { + parser->method = HTTP_MSEARCH; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + ++parser->index; + break; + } + + case s_req_spaces_before_url: + { + if (ch == ' ') break; + + MARK(url); + if (parser->method == HTTP_CONNECT) { + UPDATE_STATE(s_req_server_start); + } + + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + + break; + } + + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + { + switch (ch) { + /* No whitespace allowed here */ + case ' ': + case CR: + case LF: + SET_ERRNO(HPE_INVALID_URL); + goto error; + default: + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + + break; + } + + case s_req_server: + case s_req_server_with_at: + case s_req_path: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + { + switch (ch) { + case ' ': + UPDATE_STATE(s_req_http_start); + CALLBACK_DATA(url); + break; + case CR: + case LF: + parser->http_major = 0; + parser->http_minor = 9; + UPDATE_STATE((ch == CR) ? + s_req_line_almost_done : + s_header_field_start); + CALLBACK_DATA(url); + break; + default: + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + break; + } + + case s_req_http_start: + switch (ch) { + case 'H': + UPDATE_STATE(s_req_http_H); + break; + case ' ': + break; + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + break; + + case s_req_http_H: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_req_http_HT); + break; + + case s_req_http_HT: + STRICT_CHECK(ch != 'T'); + UPDATE_STATE(s_req_http_HTT); + break; + + case s_req_http_HTT: + STRICT_CHECK(ch != 'P'); + UPDATE_STATE(s_req_http_HTTP); + break; + + case s_req_http_HTTP: + STRICT_CHECK(ch != '/'); + UPDATE_STATE(s_req_first_http_major); + break; + + /* first digit of major HTTP version */ + case s_req_first_http_major: + if (UNLIKELY(ch < '1' || ch > '9')) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + UPDATE_STATE(s_req_http_major); + break; + + /* major HTTP version or dot */ + case s_req_http_major: + { + if (ch == '.') { + UPDATE_STATE(s_req_first_http_minor); + break; + } + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (UNLIKELY(parser->http_major > 999)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* first digit of minor HTTP version */ + case s_req_first_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + UPDATE_STATE(s_req_http_minor); + break; + + /* minor HTTP version or end of request line */ + case s_req_http_minor: + { + if (ch == CR) { + UPDATE_STATE(s_req_line_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_field_start); + break; + } + + /* XXX allow spaces after digit? */ + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (UNLIKELY(parser->http_minor > 999)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* end of request line */ + case s_req_line_almost_done: + { + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + UPDATE_STATE(s_header_field_start); + break; + } + + case s_header_field_start: + { + if (ch == CR) { + UPDATE_STATE(s_headers_almost_done); + break; + } + + if (ch == LF) { + /* they might be just sending \n instead of \r\n so this would be + * the second \n to denote the end of headers*/ + UPDATE_STATE(s_headers_almost_done); + REEXECUTE(); + } + + c = TOKEN(ch); + + if (UNLIKELY(!c)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + MARK(header_field); + + parser->index = 0; + UPDATE_STATE(s_header_field); + + switch (c) { + case 'c': + parser->header_state = h_C; + break; + + case 'p': + parser->header_state = h_matching_proxy_connection; + break; + + case 't': + parser->header_state = h_matching_transfer_encoding; + break; + + case 'u': + parser->header_state = h_matching_upgrade; + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_field: + { + const char* start = p; + for (; p != data + len; p++) { + ch = *p; + c = TOKEN(ch); + + if (!c) + break; + + switch (parser->header_state) { + case h_general: + break; + + case h_C: + parser->index++; + parser->header_state = (c == 'o' ? h_CO : h_general); + break; + + case h_CO: + parser->index++; + parser->header_state = (c == 'n' ? h_CON : h_general); + break; + + case h_CON: + parser->index++; + switch (c) { + case 'n': + parser->header_state = h_matching_connection; + break; + case 't': + parser->header_state = h_matching_content_length; + break; + default: + parser->header_state = h_general; + break; + } + break; + + /* connection */ + + case h_matching_connection: + parser->index++; + if (parser->index > sizeof(CONNECTION)-1 + || c != CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* proxy-connection */ + + case h_matching_proxy_connection: + parser->index++; + if (parser->index > sizeof(PROXY_CONNECTION)-1 + || c != PROXY_CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* content-length */ + + case h_matching_content_length: + parser->index++; + if (parser->index > sizeof(CONTENT_LENGTH)-1 + || c != CONTENT_LENGTH[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { + parser->header_state = h_content_length; + } + break; + + /* transfer-encoding */ + + case h_matching_transfer_encoding: + parser->index++; + if (parser->index > sizeof(TRANSFER_ENCODING)-1 + || c != TRANSFER_ENCODING[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { + parser->header_state = h_transfer_encoding; + } + break; + + /* upgrade */ + + case h_matching_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE)-1 + || c != UPGRADE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(UPGRADE)-2) { + parser->header_state = h_upgrade; + } + break; + + case h_connection: + case h_content_length: + case h_transfer_encoding: + case h_upgrade: + if (ch != ' ') parser->header_state = h_general; + break; + + default: + assert(0 && "Unknown header_state"); + break; + } + } + + COUNT_HEADER_SIZE(p - start); + + if (p == data + len) { + --p; + break; + } + + if (ch == ':') { + UPDATE_STATE(s_header_value_discard_ws); + CALLBACK_DATA(header_field); + break; + } + + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + case s_header_value_discard_ws: + if (ch == ' ' || ch == '\t') break; + + if (ch == CR) { + UPDATE_STATE(s_header_value_discard_ws_almost_done); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_value_discard_lws); + break; + } + + /* FALLTHROUGH */ + + case s_header_value_start: + { + MARK(header_value); + + UPDATE_STATE(s_header_value); + parser->index = 0; + + c = LOWER(ch); + + switch (parser->header_state) { + case h_upgrade: + parser->flags |= F_UPGRADE; + parser->header_state = h_general; + break; + + case h_transfer_encoding: + /* looking for 'Transfer-Encoding: chunked' */ + if ('c' == c) { + parser->header_state = h_matching_transfer_encoding_chunked; + } else { + parser->header_state = h_general; + } + break; + + case h_content_length: + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + if (parser->flags & F_CONTENTLENGTH) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + parser->flags |= F_CONTENTLENGTH; + parser->content_length = ch - '0'; + break; + + case h_connection: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + parser->header_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + parser->header_state = h_matching_connection_close; + } else if (c == 'u') { + parser->header_state = h_matching_connection_upgrade; + } else { + parser->header_state = h_matching_connection_token; + } + break; + + /* Multi-value `Connection` header */ + case h_matching_connection_token_start: + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_value: + { + const char* start = p; + enum header_states h_state = (enum header_states) parser->header_state; + for (; p != data + len; p++) { + ch = *p; + if (ch == CR) { + UPDATE_STATE(s_header_almost_done); + parser->header_state = h_state; + CALLBACK_DATA(header_value); + break; + } + + if (ch == LF) { + UPDATE_STATE(s_header_almost_done); + COUNT_HEADER_SIZE(p - start); + parser->header_state = h_state; + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + + if (!lenient && !IS_HEADER_CHAR(ch)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + c = LOWER(ch); + + switch (h_state) { + case h_general: + { + const char* p_cr; + const char* p_lf; + size_t limit = data + len - p; + + limit = MIN(limit, HTTP_MAX_HEADER_SIZE); + + p_cr = (const char*) memchr(p, CR, limit); + p_lf = (const char*) memchr(p, LF, limit); + if (p_cr != NULL) { + if (p_lf != NULL && p_cr >= p_lf) + p = p_lf; + else + p = p_cr; + } else if (UNLIKELY(p_lf != NULL)) { + p = p_lf; + } else { + p = data + len; + } + --p; + + break; + } + + case h_connection: + case h_transfer_encoding: + assert(0 && "Shouldn't get here."); + break; + + case h_content_length: + { + uint64_t t; + + if (ch == ' ') break; + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + t = parser->content_length; + t *= 10; + t += ch - '0'; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + parser->content_length = t; + break; + } + + /* Transfer-Encoding: chunked */ + case h_matching_transfer_encoding_chunked: + parser->index++; + if (parser->index > sizeof(CHUNKED)-1 + || c != CHUNKED[parser->index]) { + h_state = h_general; + } else if (parser->index == sizeof(CHUNKED)-2) { + h_state = h_transfer_encoding_chunked; + } + break; + + case h_matching_connection_token_start: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + h_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + h_state = h_matching_connection_close; + } else if (c == 'u') { + h_state = h_matching_connection_upgrade; + } else if (STRICT_TOKEN(c)) { + h_state = h_matching_connection_token; + } else if (c == ' ' || c == '\t') { + /* Skip lws */ + } else { + h_state = h_general; + } + break; + + /* looking for 'Connection: keep-alive' */ + case h_matching_connection_keep_alive: + parser->index++; + if (parser->index > sizeof(KEEP_ALIVE)-1 + || c != KEEP_ALIVE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(KEEP_ALIVE)-2) { + h_state = h_connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case h_matching_connection_close: + parser->index++; + if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(CLOSE)-2) { + h_state = h_connection_close; + } + break; + + /* looking for 'Connection: upgrade' */ + case h_matching_connection_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE) - 1 || + c != UPGRADE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(UPGRADE)-2) { + h_state = h_connection_upgrade; + } + break; + + case h_matching_connection_token: + if (ch == ',') { + h_state = h_matching_connection_token_start; + parser->index = 0; + } + break; + + case h_transfer_encoding_chunked: + if (ch != ' ') h_state = h_general; + break; + + case h_connection_keep_alive: + case h_connection_close: + case h_connection_upgrade: + if (ch == ',') { + if (h_state == h_connection_keep_alive) { + parser->flags |= F_CONNECTION_KEEP_ALIVE; + } else if (h_state == h_connection_close) { + parser->flags |= F_CONNECTION_CLOSE; + } else if (h_state == h_connection_upgrade) { + parser->flags |= F_CONNECTION_UPGRADE; + } + h_state = h_matching_connection_token_start; + parser->index = 0; + } else if (ch != ' ') { + h_state = h_matching_connection_token; + } + break; + + default: + UPDATE_STATE(s_header_value); + h_state = h_general; + break; + } + } + parser->header_state = h_state; + + COUNT_HEADER_SIZE(p - start); + + if (p == data + len) + --p; + break; + } + + case s_header_almost_done: + { + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + UPDATE_STATE(s_header_value_lws); + break; + } + + case s_header_value_lws: + { + if (ch == ' ' || ch == '\t') { + UPDATE_STATE(s_header_value_start); + REEXECUTE(); + } + + /* finished the header */ + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + default: + break; + } + + UPDATE_STATE(s_header_field_start); + REEXECUTE(); + } + + case s_header_value_discard_ws_almost_done: + { + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_value_discard_lws); + break; + } + + case s_header_value_discard_lws: + { + if (ch == ' ' || ch == '\t') { + UPDATE_STATE(s_header_value_discard_ws); + break; + } else { + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + default: + break; + } + + /* header value was empty */ + MARK(header_value); + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + } + + case s_headers_almost_done: + { + STRICT_CHECK(ch != LF); + + if (parser->flags & F_TRAILING) { + /* End of a chunked request */ + UPDATE_STATE(s_message_done); + CALLBACK_NOTIFY_NOADVANCE(chunk_complete); + REEXECUTE(); + } + + /* Cannot use chunked encoding and a content-length header together + per the HTTP specification. */ + if ((parser->flags & F_CHUNKED) && + (parser->flags & F_CONTENTLENGTH)) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + UPDATE_STATE(s_headers_done); + + /* Set this here so that on_headers_complete() callbacks can see it */ + parser->upgrade = + ((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) == + (F_UPGRADE | F_CONNECTION_UPGRADE) || + parser->method == HTTP_CONNECT); + + /* Here we call the headers_complete callback. This is somewhat + * different than other callbacks because if the user returns 1, we + * will interpret that as saying that this message has no body. This + * is needed for the annoying case of recieving a response to a HEAD + * request. + * + * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so + * we have to simulate it by handling a change in errno below. + */ + if (settings->on_headers_complete) { + switch (settings->on_headers_complete(parser)) { + case 0: + break; + + case 2: + parser->upgrade = 1; + + case 1: + parser->flags |= F_SKIPBODY; + break; + + default: + SET_ERRNO(HPE_CB_headers_complete); + RETURN(p - data); /* Error */ + } + } + + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + RETURN(p - data); + } + + REEXECUTE(); + } + + case s_headers_done: + { + int hasBody; + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + hasBody = parser->flags & F_CHUNKED || + (parser->content_length > 0 && parser->content_length != ULLONG_MAX); + if (parser->upgrade && (parser->method == HTTP_CONNECT || + (parser->flags & F_SKIPBODY) || !hasBody)) { + /* Exit, the rest of the message is in a different protocol. */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + RETURN((p - data) + 1); + } + + if (parser->flags & F_SKIPBODY) { + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else if (parser->flags & F_CHUNKED) { + /* chunked encoding - ignore Content-Length header */ + UPDATE_STATE(s_chunk_size_start); + } else { + if (parser->content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else if (parser->content_length != ULLONG_MAX) { + /* Content-Length header given and non-zero */ + UPDATE_STATE(s_body_identity); + } else { + if (!http_message_needs_eof(parser)) { + /* Assume content-length 0 - read the next */ + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + } else { + /* Read body until EOF */ + UPDATE_STATE(s_body_identity_eof); + } + } + } + + break; + } + + case s_body_identity: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* The difference between advancing content_length and p is because + * the latter will automaticaly advance on the next loop iteration. + * Further, if content_length ends up at 0, we want to see the last + * byte again for our message complete callback. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + UPDATE_STATE(s_message_done); + + /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. + * + * The alternative to doing this is to wait for the next byte to + * trigger the data callback, just as in every other case. The + * problem with this is that this makes it difficult for the test + * harness to distinguish between complete-on-EOF and + * complete-on-length. It's not clear that this distinction is + * important for applications, but let's keep it for now. + */ + CALLBACK_DATA_(body, p - body_mark + 1, p - data); + REEXECUTE(); + } + + break; + } + + /* read until EOF */ + case s_body_identity_eof: + MARK(body); + p = data + len - 1; + + break; + + case s_message_done: + UPDATE_STATE(NEW_MESSAGE()); + CALLBACK_NOTIFY(message_complete); + if (parser->upgrade) { + /* Exit, the rest of the message is in a different protocol. */ + RETURN((p - data) + 1); + } + break; + + case s_chunk_size_start: + { + assert(parser->nread == 1); + assert(parser->flags & F_CHUNKED); + + unhex_val = unhex[(unsigned char)ch]; + if (UNLIKELY(unhex_val == -1)) { + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + parser->content_length = unhex_val; + UPDATE_STATE(s_chunk_size); + break; + } + + case s_chunk_size: + { + uint64_t t; + + assert(parser->flags & F_CHUNKED); + + if (ch == CR) { + UPDATE_STATE(s_chunk_size_almost_done); + break; + } + + unhex_val = unhex[(unsigned char)ch]; + + if (unhex_val == -1) { + if (ch == ';' || ch == ' ') { + UPDATE_STATE(s_chunk_parameters); + break; + } + + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + t = parser->content_length; + t *= 16; + t += unhex_val; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = t; + break; + } + + case s_chunk_parameters: + { + assert(parser->flags & F_CHUNKED); + /* just ignore this shit. TODO check for overflow */ + if (ch == CR) { + UPDATE_STATE(s_chunk_size_almost_done); + break; + } + break; + } + + case s_chunk_size_almost_done: + { + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + if (parser->content_length == 0) { + parser->flags |= F_TRAILING; + UPDATE_STATE(s_header_field_start); + } else { + UPDATE_STATE(s_chunk_data); + } + CALLBACK_NOTIFY(chunk_header); + break; + } + + case s_chunk_data: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->flags & F_CHUNKED); + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* See the explanation in s_body_identity for why the content + * length and data pointers are managed this way. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + UPDATE_STATE(s_chunk_data_almost_done); + } + + break; + } + + case s_chunk_data_almost_done: + assert(parser->flags & F_CHUNKED); + assert(parser->content_length == 0); + STRICT_CHECK(ch != CR); + UPDATE_STATE(s_chunk_data_done); + CALLBACK_DATA(body); + break; + + case s_chunk_data_done: + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + parser->nread = 0; + UPDATE_STATE(s_chunk_size_start); + CALLBACK_NOTIFY(chunk_complete); + break; + + default: + assert(0 && "unhandled state"); + SET_ERRNO(HPE_INVALID_INTERNAL_STATE); + goto error; + } + } + + /* Run callbacks for any marks that we have leftover after we ran our of + * bytes. There should be at most one of these set, so it's OK to invoke + * them in series (unset marks will not result in callbacks). + * + * We use the NOADVANCE() variety of callbacks here because 'p' has already + * overflowed 'data' and this allows us to correct for the off-by-one that + * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' + * value that's in-bounds). + */ + + assert(((header_field_mark ? 1 : 0) + + (header_value_mark ? 1 : 0) + + (url_mark ? 1 : 0) + + (body_mark ? 1 : 0) + + (status_mark ? 1 : 0)) <= 1); + + CALLBACK_DATA_NOADVANCE(header_field); + CALLBACK_DATA_NOADVANCE(header_value); + CALLBACK_DATA_NOADVANCE(url); + CALLBACK_DATA_NOADVANCE(body); + CALLBACK_DATA_NOADVANCE(status); + + RETURN(len); + +error: + if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { + SET_ERRNO(HPE_UNKNOWN); + } + + RETURN(p - data); +} + + +/* Does the parser need to see an EOF to find the end of the message? */ +int +http_message_needs_eof (const http_parser *parser) +{ + if (parser->type == HTTP_REQUEST) { + return 0; + } + + /* See RFC 2616 section 4.4 */ + if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ + parser->status_code == 204 || /* No Content */ + parser->status_code == 304 || /* Not Modified */ + parser->flags & F_SKIPBODY) { /* response to a HEAD request */ + return 0; + } + + if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { + return 0; + } + + return 1; +} + + +int +http_should_keep_alive (const http_parser *parser) +{ + if (parser->http_major > 0 && parser->http_minor > 0) { + /* HTTP/1.1 */ + if (parser->flags & F_CONNECTION_CLOSE) { + return 0; + } + } else { + /* HTTP/1.0 or earlier */ + if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { + return 0; + } + } + + return !http_message_needs_eof(parser); +} + + +const char * +http_method_str (enum http_method m) +{ + return ELEM_AT(method_strings, m, ""); +} + + +void +http_parser_init (http_parser *parser, enum http_parser_type t) +{ + void *data = parser->data; /* preserve application data */ + memset(parser, 0, sizeof(*parser)); + parser->data = data; + parser->type = t; + parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); + parser->http_errno = HPE_OK; +} + +void +http_parser_settings_init(http_parser_settings *settings) +{ + memset(settings, 0, sizeof(*settings)); +} + +const char * +http_errno_name(enum http_errno err) { + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + return http_strerror_tab[err].name; +} + +const char * +http_errno_description(enum http_errno err) { + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); + return http_strerror_tab[err].description; +} + +static enum http_host_state +http_parse_host_char(enum http_host_state s, const char ch) { + switch(s) { + case s_http_userinfo: + case s_http_userinfo_start: + if (ch == '@') { + return s_http_host_start; + } + + if (IS_USERINFO_CHAR(ch)) { + return s_http_userinfo; + } + break; + + case s_http_host_start: + if (ch == '[') { + return s_http_host_v6_start; + } + + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + break; + + case s_http_host: + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + /* FALLTHROUGH */ + case s_http_host_v6_end: + if (ch == ':') { + return s_http_host_port_start; + } + + break; + + case s_http_host_v6: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_start: + if (IS_HEX(ch) || ch == ':' || ch == '.') { + return s_http_host_v6; + } + + if (s == s_http_host_v6 && ch == '%') { + return s_http_host_v6_zone_start; + } + break; + + case s_http_host_v6_zone: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_zone_start: + /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */ + if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' || + ch == '~') { + return s_http_host_v6_zone; + } + break; + + case s_http_host_port: + case s_http_host_port_start: + if (IS_NUM(ch)) { + return s_http_host_port; + } + + break; + + default: + break; + } + return s_http_host_dead; +} + +static int +http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { + enum http_host_state s; + + const char *p; + size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; + + assert(u->field_set & (1 << UF_HOST)); + + u->field_data[UF_HOST].len = 0; + + s = found_at ? s_http_userinfo_start : s_http_host_start; + + for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { + enum http_host_state new_s = http_parse_host_char(s, *p); + + if (new_s == s_http_host_dead) { + return 1; + } + + switch(new_s) { + case s_http_host: + if (s != s_http_host) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6: + if (s != s_http_host_v6) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + u->field_data[UF_HOST].len++; + break; + + case s_http_host_port: + if (s != s_http_host_port) { + u->field_data[UF_PORT].off = p - buf; + u->field_data[UF_PORT].len = 0; + u->field_set |= (1 << UF_PORT); + } + u->field_data[UF_PORT].len++; + break; + + case s_http_userinfo: + if (s != s_http_userinfo) { + u->field_data[UF_USERINFO].off = p - buf ; + u->field_data[UF_USERINFO].len = 0; + u->field_set |= (1 << UF_USERINFO); + } + u->field_data[UF_USERINFO].len++; + break; + + default: + break; + } + s = new_s; + } + + /* Make sure we don't end somewhere unexpected */ + switch (s) { + case s_http_host_start: + case s_http_host_v6_start: + case s_http_host_v6: + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + case s_http_host_port_start: + case s_http_userinfo: + case s_http_userinfo_start: + return 1; + default: + break; + } + + return 0; +} + +void +http_parser_url_init(struct http_parser_url *u) { + memset(u, 0, sizeof(*u)); +} + +int +http_parser_parse_url(const char *buf, size_t buflen, int is_connect, + struct http_parser_url *u) +{ + enum state s; + const char *p; + enum http_parser_url_fields uf, old_uf; + int found_at = 0; + + u->port = u->field_set = 0; + s = is_connect ? s_req_server_start : s_req_spaces_before_url; + old_uf = UF_MAX; + + for (p = buf; p < buf + buflen; p++) { + s = parse_url_char(s, *p); + + /* Figure out the next field that we're operating on */ + switch (s) { + case s_dead: + return 1; + + /* Skip delimeters */ + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_query_string_start: + case s_req_fragment_start: + continue; + + case s_req_schema: + uf = UF_SCHEMA; + break; + + case s_req_server_with_at: + found_at = 1; + + /* FALLTROUGH */ + case s_req_server: + uf = UF_HOST; + break; + + case s_req_path: + uf = UF_PATH; + break; + + case s_req_query_string: + uf = UF_QUERY; + break; + + case s_req_fragment: + uf = UF_FRAGMENT; + break; + + default: + assert(!"Unexpected state"); + return 1; + } + + /* Nothing's changed; soldier on */ + if (uf == old_uf) { + u->field_data[uf].len++; + continue; + } + + u->field_data[uf].off = p - buf; + u->field_data[uf].len = 1; + + u->field_set |= (1 << uf); + old_uf = uf; + } + + /* host must be present if there is a schema */ + /* parsing http:///toto will fail */ + if ((u->field_set & (1 << UF_SCHEMA)) && + (u->field_set & (1 << UF_HOST)) == 0) { + return 1; + } + + if (u->field_set & (1 << UF_HOST)) { + if (http_parse_host(buf, u, found_at) != 0) { + return 1; + } + } + + /* CONNECT requests can only contain "hostname:port" */ + if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { + return 1; + } + + if (u->field_set & (1 << UF_PORT)) { + /* Don't bother with endp; we've already validated the string */ + unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); + + /* Ports have a max value of 2^16 */ + if (v > 0xffff) { + return 1; + } + + u->port = (uint16_t) v; + } + + return 0; +} + +void +http_parser_pause(http_parser *parser, int paused) { + /* Users should only be pausing/unpausing a parser that is not in an error + * state. In non-debug builds, there's not much that we can do about this + * other than ignore it. + */ + if (HTTP_PARSER_ERRNO(parser) == HPE_OK || + HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { + SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); + } else { + assert(0 && "Attempting to pause parser in error state"); + } +} + +int +http_body_is_final(const struct http_parser *parser) { + return parser->state == s_message_done; +} + +unsigned long +http_parser_version(void) { + return HTTP_PARSER_VERSION_MAJOR * 0x10000 | + HTTP_PARSER_VERSION_MINOR * 0x00100 | + HTTP_PARSER_VERSION_PATCH * 0x00001; +} diff --git a/Sources/PerfectCHTTPParser/http_parser.h b/Sources/PerfectCHTTPParser/http_parser.h new file mode 100755 index 00000000..0534bb45 --- /dev/null +++ b/Sources/PerfectCHTTPParser/http_parser.h @@ -0,0 +1,2 @@ + +#include "include/http_parser.h" diff --git a/Sources/PerfectCHTTPParser/include/http_parser.h b/Sources/PerfectCHTTPParser/include/http_parser.h new file mode 100755 index 00000000..ea263948 --- /dev/null +++ b/Sources/PerfectCHTTPParser/include/http_parser.h @@ -0,0 +1,362 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +#ifndef http_parser_h +#define http_parser_h +#ifdef __cplusplus +extern "C" { +#endif + +/* Also update SONAME in the Makefile whenever you change these. */ +#define HTTP_PARSER_VERSION_MAJOR 2 +#define HTTP_PARSER_VERSION_MINOR 7 +#define HTTP_PARSER_VERSION_PATCH 1 + +#include +#if defined(_WIN32) && !defined(__MINGW32__) && \ + (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__) +#include +#include +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +#include +#endif + +/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run + * faster + */ +#ifndef HTTP_PARSER_STRICT +# define HTTP_PARSER_STRICT 1 +#endif + +/* Maximium header size allowed. If the macro is not defined + * before including this header then the default is used. To + * change the maximum header size, define the macro in the build + * environment (e.g. -DHTTP_MAX_HEADER_SIZE=). To remove + * the effective limit on the size of the header, define the macro + * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff) + */ +#ifndef HTTP_MAX_HEADER_SIZE +# define HTTP_MAX_HEADER_SIZE (80*1024) +#endif + +typedef struct http_parser http_parser; +typedef struct http_parser_settings http_parser_settings; + + +/* Callbacks should return non-zero to indicate an error. The parser will + * then halt execution. + * + * The one exception is on_headers_complete. In a HTTP_RESPONSE parser + * returning '1' from on_headers_complete will tell the parser that it + * should not expect a body. This is used when receiving a response to a + * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: + * chunked' headers that indicate the presence of a body. + * + * Returning `2` from on_headers_complete will tell parser that it should not + * expect neither a body nor any futher responses on this connection. This is + * useful for handling responses to a CONNECT request which may not contain + * `Upgrade` or `Connection: upgrade` headers. + * + * http_data_cb does not return data chunks. It will be called arbitrarily + * many times for each string. E.G. you might get 10 callbacks for "on_url" + * each providing just a few characters more data. + */ +typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); +typedef int (*http_cb) (http_parser*); + + +/* Request Methods */ +#define HTTP_METHOD_MAP(XX) \ + XX(0, DELETE, DELETE) \ + XX(1, GET, GET) \ + XX(2, HEAD, HEAD) \ + XX(3, POST, POST) \ + XX(4, PUT, PUT) \ + /* pathological */ \ + XX(5, CONNECT, CONNECT) \ + XX(6, OPTIONS, OPTIONS) \ + XX(7, TRACE, TRACE) \ + /* WebDAV */ \ + XX(8, COPY, COPY) \ + XX(9, LOCK, LOCK) \ + XX(10, MKCOL, MKCOL) \ + XX(11, MOVE, MOVE) \ + XX(12, PROPFIND, PROPFIND) \ + XX(13, PROPPATCH, PROPPATCH) \ + XX(14, SEARCH, SEARCH) \ + XX(15, UNLOCK, UNLOCK) \ + XX(16, BIND, BIND) \ + XX(17, REBIND, REBIND) \ + XX(18, UNBIND, UNBIND) \ + XX(19, ACL, ACL) \ + /* subversion */ \ + XX(20, REPORT, REPORT) \ + XX(21, MKACTIVITY, MKACTIVITY) \ + XX(22, CHECKOUT, CHECKOUT) \ + XX(23, MERGE, MERGE) \ + /* upnp */ \ + XX(24, MSEARCH, M-SEARCH) \ + XX(25, NOTIFY, NOTIFY) \ + XX(26, SUBSCRIBE, SUBSCRIBE) \ + XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ + /* RFC-5789 */ \ + XX(28, PATCH, PATCH) \ + XX(29, PURGE, PURGE) \ + /* CalDAV */ \ + XX(30, MKCALENDAR, MKCALENDAR) \ + /* RFC-2068, section 19.6.1.2 */ \ + XX(31, LINK, LINK) \ + XX(32, UNLINK, UNLINK) \ + +enum http_method + { +#define XX(num, name, string) HTTP_##name = num, + HTTP_METHOD_MAP(XX) +#undef XX + }; + + +enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; + + +/* Flag values for http_parser.flags field */ +enum flags + { F_CHUNKED = 1 << 0 + , F_CONNECTION_KEEP_ALIVE = 1 << 1 + , F_CONNECTION_CLOSE = 1 << 2 + , F_CONNECTION_UPGRADE = 1 << 3 + , F_TRAILING = 1 << 4 + , F_UPGRADE = 1 << 5 + , F_SKIPBODY = 1 << 6 + , F_CONTENTLENGTH = 1 << 7 + }; + + +/* Map for errno-related constants + * + * The provided argument should be a macro that takes 2 arguments. + */ +#define HTTP_ERRNO_MAP(XX) \ + /* No error */ \ + XX(OK, "success") \ + \ + /* Callback-related errors */ \ + XX(CB_message_begin, "the on_message_begin callback failed") \ + XX(CB_url, "the on_url callback failed") \ + XX(CB_header_field, "the on_header_field callback failed") \ + XX(CB_header_value, "the on_header_value callback failed") \ + XX(CB_headers_complete, "the on_headers_complete callback failed") \ + XX(CB_body, "the on_body callback failed") \ + XX(CB_message_complete, "the on_message_complete callback failed") \ + XX(CB_status, "the on_status callback failed") \ + XX(CB_chunk_header, "the on_chunk_header callback failed") \ + XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ + \ + /* Parsing-related errors */ \ + XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ + XX(HEADER_OVERFLOW, \ + "too many header bytes seen; overflow detected") \ + XX(CLOSED_CONNECTION, \ + "data received after completed connection: close message") \ + XX(INVALID_VERSION, "invalid HTTP version") \ + XX(INVALID_STATUS, "invalid HTTP status code") \ + XX(INVALID_METHOD, "invalid HTTP method") \ + XX(INVALID_URL, "invalid URL") \ + XX(INVALID_HOST, "invalid host") \ + XX(INVALID_PORT, "invalid port") \ + XX(INVALID_PATH, "invalid path") \ + XX(INVALID_QUERY_STRING, "invalid query string") \ + XX(INVALID_FRAGMENT, "invalid fragment") \ + XX(LF_EXPECTED, "LF character expected") \ + XX(INVALID_HEADER_TOKEN, "invalid character in header") \ + XX(INVALID_CONTENT_LENGTH, \ + "invalid character in content-length header") \ + XX(UNEXPECTED_CONTENT_LENGTH, \ + "unexpected content-length header") \ + XX(INVALID_CHUNK_SIZE, \ + "invalid character in chunk size header") \ + XX(INVALID_CONSTANT, "invalid constant string") \ + XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ + XX(STRICT, "strict mode assertion failed") \ + XX(PAUSED, "parser is paused") \ + XX(UNKNOWN, "an unknown error occurred") + + +/* Define HPE_* values for each errno value above */ +#define HTTP_ERRNO_GEN(n, s) HPE_##n, +enum http_errno { + HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) +}; +#undef HTTP_ERRNO_GEN + + +/* Get an http_errno value from an http_parser */ +#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) + + +struct http_parser { + /** PRIVATE **/ + unsigned int type : 2; /* enum http_parser_type */ + unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */ + unsigned int state : 7; /* enum state from http_parser.c */ + unsigned int header_state : 7; /* enum header_state from http_parser.c */ + unsigned int index : 7; /* index into current matcher */ + unsigned int lenient_http_headers : 1; + + uint32_t nread; /* # bytes read in various scenarios */ + uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ + + /** READ-ONLY **/ + unsigned short http_major; + unsigned short http_minor; + unsigned int status_code : 16; /* responses only */ + unsigned int method : 8; /* requests only */ + unsigned int http_errno : 7; + + /* 1 = Upgrade header was present and the parser has exited because of that. + * 0 = No upgrade header present. + * Should be checked when http_parser_execute() returns in addition to + * error checking. + */ + unsigned int upgrade : 1; + + /** PUBLIC **/ + void *data; /* A pointer to get hook to the "connection" or "socket" object */ +}; + + +struct http_parser_settings { + http_cb on_message_begin; + http_data_cb on_url; + http_data_cb on_status; + http_data_cb on_header_field; + http_data_cb on_header_value; + http_cb on_headers_complete; + http_data_cb on_body; + http_cb on_message_complete; + /* When on_chunk_header is called, the current chunk length is stored + * in parser->content_length. + */ + http_cb on_chunk_header; + http_cb on_chunk_complete; +}; + + +enum http_parser_url_fields + { UF_SCHEMA = 0 + , UF_HOST = 1 + , UF_PORT = 2 + , UF_PATH = 3 + , UF_QUERY = 4 + , UF_FRAGMENT = 5 + , UF_USERINFO = 6 + , UF_MAX = 7 + }; + + +/* Result structure for http_parser_parse_url(). + * + * Callers should index into field_data[] with UF_* values iff field_set + * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and + * because we probably have padding left over), we convert any port to + * a uint16_t. + */ +struct http_parser_url { + uint16_t field_set; /* Bitmask of (1 << UF_*) values */ + uint16_t port; /* Converted UF_PORT string */ + + struct { + uint16_t off; /* Offset into buffer in which field starts */ + uint16_t len; /* Length of run in buffer */ + } field_data[UF_MAX]; +}; + + +/* Returns the library version. Bits 16-23 contain the major version number, + * bits 8-15 the minor version number and bits 0-7 the patch level. + * Usage example: + * + * unsigned long version = http_parser_version(); + * unsigned major = (version >> 16) & 255; + * unsigned minor = (version >> 8) & 255; + * unsigned patch = version & 255; + * printf("http_parser v%u.%u.%u\n", major, minor, patch); + */ +unsigned long http_parser_version(void); + +void http_parser_init(http_parser *parser, enum http_parser_type type); + + +/* Initialize http_parser_settings members to 0 + */ +void http_parser_settings_init(http_parser_settings *settings); + + +/* Executes the parser. Returns number of parsed bytes. Sets + * `parser->http_errno` on error. */ +size_t http_parser_execute(http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len); + + +/* If http_should_keep_alive() in the on_headers_complete or + * on_message_complete callback returns 0, then this should be + * the last message on the connection. + * If you are the server, respond with the "Connection: close" header. + * If you are the client, close the connection. + */ +int http_should_keep_alive(const http_parser *parser); + +/* Returns a string version of the HTTP method. */ +const char *http_method_str(enum http_method m); + +/* Return a string name of the given error */ +const char *http_errno_name(enum http_errno err); + +/* Return a string description of the given error */ +const char *http_errno_description(enum http_errno err); + +/* Initialize all http_parser_url members to 0 */ +void http_parser_url_init(struct http_parser_url *u); + +/* Parse a URL; return nonzero on failure */ +int http_parser_parse_url(const char *buf, size_t buflen, + int is_connect, + struct http_parser_url *u); + +/* Pause or un-pause the parser; a nonzero value pauses */ +void http_parser_pause(http_parser *parser, int paused); + +/* Checks if this is the final chunk of the body. */ +int http_body_is_final(const http_parser *parser); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/Sources/PerfectCHTTPParser/include/module.modulemap b/Sources/PerfectCHTTPParser/include/module.modulemap new file mode 100644 index 00000000..895f5a0f --- /dev/null +++ b/Sources/PerfectCHTTPParser/include/module.modulemap @@ -0,0 +1,4 @@ +module PerfectCHTTPParser { + header "http_parser.h" + export * +} diff --git a/Sources/PerfectCRUD/Coding/Coding.swift b/Sources/PerfectCRUD/Coding/Coding.swift new file mode 100644 index 00000000..4db198e2 --- /dev/null +++ b/Sources/PerfectCRUD/Coding/Coding.swift @@ -0,0 +1,73 @@ +// +// PerfectCRUDCoding.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-11-22. +// Copyright (C) 2017 PerfectlySoft, Inc. +// +// ===----------------------------------------------------------------------===// +// +// This source file is part of the Perfect.org open source project +// +// Copyright (c) 2015 - 2017 PerfectlySoft Inc. and the Perfect project authors +// Licensed under Apache License v2.0 +// +// See http://perfect.org/licensing.html for license information +// +// ===----------------------------------------------------------------------===// +// + +import Foundation + +public struct CRUDDecoderError: Error { + public let msg: String + public init(_ m: String) { + msg = m + CRUDLogging.log(.error, m) + } +} + +public struct CRUDEncoderError: Error { + public let msg: String + public init(_ m: String) { + msg = m + CRUDLogging.log(.error, m) + } +} + +public struct ColumnKey: CodingKey { + public var stringValue: String + public var intValue: Int? = nil + public init?(stringValue s: String) { + stringValue = s + } + public init?(intValue: Int) { + return nil + } +} + +public indirect enum SpecialType { + case uint8Array, int8Array, data, uuid, date, codable, url, wrapped + public init?(_ type: Any.Type) { + switch type { + case is WrappedCodableProvider.Type: + self = .wrapped + case is [Int8].Type: + self = .int8Array + case is [UInt8].Type: + self = .uint8Array + case is Data.Type: + self = .data + case is UUID.Type: + self = .uuid + case is Date.Type: + self = .date + case is URL.Type: + self = .url + case is Codable.Type: + self = .codable + default: + return nil + } + } +} diff --git a/Sources/PerfectCRUD/Coding/CodingBindings.swift b/Sources/PerfectCRUD/Coding/CodingBindings.swift new file mode 100644 index 00000000..907af203 --- /dev/null +++ b/Sources/PerfectCRUD/Coding/CodingBindings.swift @@ -0,0 +1,192 @@ +// +// PerfectCRUDCodingBindings.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-11-25. +// Copyright (C) 2017 PerfectlySoft, Inc. +// +// ===----------------------------------------------------------------------===// +// +// This source file is part of the Perfect.org open source project +// +// Copyright (c) 2015 - 2017 PerfectlySoft Inc. and the Perfect project authors +// Licensed under Apache License v2.0 +// +// See http://perfect.org/licensing.html for license information +// +// ===----------------------------------------------------------------------===// +// + +import Foundation + +// -- generates bindings for an object +class CRUDBindingsWriter: KeyedEncodingContainerProtocol { + typealias Key = K + let codingPath: [CodingKey] = [] + let parent: CRUDBindingsEncoder + init(_ p: CRUDBindingsEncoder) { + parent = p + } + func addBinding(_ key: Key, value: Expression) throws { + try parent.addBinding(key: key, value: value) + } + func encodeNil(forKey key: K) throws { + // !FIX! this is never called + // Expect this to change in the future + // When nulls are important we have to use the column named decoder first + // and pass in the list of optionals to CRUDBindingsEncoder + CRUDLogging.log(.info, "CRUDBindingsWriter.encodeNil started being called.") + // try addBinding(key, value: .null) + } + func encode(_ value: Bool, forKey key: K) throws { + try addBinding(key, value: .bool(value)) + } + func encode(_ value: Int, forKey key: K) throws { + try addBinding(key, value: .integer(value)) + } + func encode(_ value: Int8, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: Int16, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: Int32, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: Int64, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: UInt, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: UInt8, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: UInt16, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: UInt32, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: UInt64, forKey key: K) throws { + try addBinding(key, value: .integer(Int(value))) + } + func encode(_ value: Float, forKey key: K) throws { + try addBinding(key, value: .decimal(Double(value))) + } + func encode(_ value: Double, forKey key: K) throws { + try addBinding(key, value: .decimal(value)) + } + func encode(_ value: String, forKey key: K) throws { + try addBinding(key, value: .string(value)) + } + // swiftlint:disable force_cast + func encode(_ value: T, forKey key: K) throws where T: Encodable { + guard let special = SpecialType(T.self) else { + throw CRUDEncoderError("Unsupported encoding type: \(value) for key: \(key.stringValue)") + } + switch special { + case .uint8Array: + try addBinding(key, value: .blob((value as! [UInt8]))) + case .int8Array: + try addBinding(key, value: .blob((value as! [Int8]).map { UInt8($0) })) + case .data: + try addBinding(key, value: .blob((value as! Data).map { $0 })) + case .uuid: + try addBinding(key, value: .uuid(value as! UUID)) + case .date: + try addBinding(key, value: .date(value as! Date)) + case .url: + try addBinding(key, value: .url(value as! URL)) + case .codable: + let data = try JSONEncoder().encode(value) + if let str = String(data: data, encoding: .utf8) { + try addBinding(key, value: .string(str)) + } + case .wrapped: + guard let wrapped = value as? WrappedCodableProvider else { + throw CRUDEncoderError("Unsupported encoding type: wrapped(\(value)) for key: \(key.stringValue)") + } + let wrappedValue = wrapped.provideWrappedValue() + switch wrappedValue { + case let m as Bool: try encode(m, forKey: key) + case let m as Int: try encode(m, forKey: key) + case let m as Int8: try encode(m, forKey: key) + case let m as Int16: try encode(m, forKey: key) + case let m as Int32: try encode(m, forKey: key) + case let m as Int64: try encode(m, forKey: key) + case let m as UInt: try encode(m, forKey: key) + case let m as UInt8: try encode(m, forKey: key) + case let m as UInt16: try encode(m, forKey: key) + case let m as UInt32: try encode(m, forKey: key) + case let m as UInt64: try encode(m, forKey: key) + case let m as Float: try encode(m, forKey: key) + case let m as Double: try encode(m, forKey: key) + case let m as String: try encode(m, forKey: key) + case let m as [UInt8]: try encode(m, forKey: key) + case let m as [Int8]: try encode(m, forKey: key) + case let m as Data: try encode(m, forKey: key) + case let m as UUID: try encode(m, forKey: key) + case let m as Date: try encode(m, forKey: key) + case let m as URL: try encode(m, forKey: key) + default: + throw CRUDEncoderError("Unsupported encoding type: wrapped(\(wrappedValue)) for key: \(key.stringValue)") + } + + } + } + func nestedContainer(keyedBy keyType: NestedKey.Type, forKey key: K) -> KeyedEncodingContainer where NestedKey: CodingKey { + fatalError("Unimplemented") + } + func nestedUnkeyedContainer(forKey key: K) -> UnkeyedEncodingContainer { + fatalError("Unimplemented") + } + func superEncoder() -> Encoder { + fatalError("Unimplemented") + } + func superEncoder(forKey key: K) -> Encoder { + fatalError("Unimplemented") + } +} + +public class CRUDBindingsEncoder: Encoder { + public let codingPath: [CodingKey] = [] + public let userInfo: [CodingUserInfoKey: Any] = [:] + let delegate: SQLGenDelegate + private var collectedBinds: [(String, Expression)] = [] + + public init(delegate d: SQLGenDelegate) throws { + delegate = d + } + + public func completedBindings(allKeys: [String], ignoreKeys: Set) throws -> [(column: String, identifier: String)] { + let exprDict: [String: Expression] = .init(uniqueKeysWithValues: collectedBinds) + let ret: [(column: String, identifier: String)] = try allKeys.filter { !ignoreKeys.contains($0) }.map { key in + let bindId: String + if let expr = exprDict[key] { + bindId = try delegate.getBinding(for: expr) + } else { + bindId = try delegate.getBinding(for: .null) + } + return (key, bindId) + } + return ret + } + + func completedBindings(ignoreKeys: Set) throws -> [(column: String, identifier: String)] { + return try completedBindings(allKeys: collectedBinds.map { $0.0 }, ignoreKeys: ignoreKeys) + } + + func addBinding(key: Key, value: Expression) throws { + collectedBinds.append((key.stringValue, value)) + } + public func container(keyedBy type: Key.Type) -> KeyedEncodingContainer where Key: CodingKey { + return KeyedEncodingContainer(CRUDBindingsWriter(self)) + } + public func unkeyedContainer() -> UnkeyedEncodingContainer { + fatalError("Unimplemented") + } + public func singleValueContainer() -> SingleValueEncodingContainer { + fatalError("Unimplemented") + } +} diff --git a/Sources/PerfectCRUD/Coding/CodingJoins.swift b/Sources/PerfectCRUD/Coding/CodingJoins.swift new file mode 100644 index 00000000..707fc300 --- /dev/null +++ b/Sources/PerfectCRUD/Coding/CodingJoins.swift @@ -0,0 +1,169 @@ +// +// PerfectCRUDCodingJoinings.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-12-01. +// + +import Foundation + +class SQLTopRowReader: KeyedDecodingContainerProtocol { + typealias Key = K + var codingPath: [CodingKey] = [] + var allKeys: [Key] = [] + let exeDelegate: SQLTopExeDelegate + let subRowReader: KeyedDecodingContainer + init(exeDelegate e: SQLTopExeDelegate, subRowReader s: KeyedDecodingContainer) { + exeDelegate = e + subRowReader = s + } + func contains(_ key: Key) -> Bool { + return subRowReader.contains(key) || nil != exeDelegate.subObjects.index(forKey: key.stringValue) + } + func decodeNil(forKey key: Key) throws -> Bool { + if nil != exeDelegate.subObjects.index(forKey: key.stringValue) { + return false + } + return try subRowReader.decodeNil(forKey: key) + } + func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: Int.Type, forKey key: Key) throws -> Int { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: Float.Type, forKey key: Key) throws -> Float { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: Double.Type, forKey key: Key) throws -> Double { + return try subRowReader.decode(type, forKey: key) + } + func decode(_ type: String.Type, forKey key: Key) throws -> String { + return try subRowReader.decode(type, forKey: key) + } + // main table join mechanism + // !FIX! to put cached sub objects in foreign key dictionary + func decode(_ intype: T.Type, forKey key: Key) throws -> T where T: Decodable { + if let (onKeyName, onKey, equalsKey, objects) = exeDelegate.subObjects[key.stringValue], + let columnKey = Key(stringValue: onKeyName), + let comparisonType = type(of: onKey).valueType as? Decodable.Type { + + // I could not get this to compile. because comparisonType isn't known at compile time? + // let keyValue = try subRowReader.decode(comparisonType, forKey: columnKey) + let theseObjs: [Any] + switch comparisonType { + case let i as Bool.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Int.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Int8.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Int16.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Int32.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Int64.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as UInt.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as UInt8.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as UInt16.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as UInt32.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as UInt64.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Float.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Double.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as String.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Date.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as Data.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + case let i as UUID.Type: + let keyValue = try subRowReader.decode(i, forKey: columnKey) + theseObjs = filteredValues(objects, lhs: keyValue, rhsKey: equalsKey) + default: + throw CRUDSQLExeError("Invalid join comparison type \(comparisonType).") + } + // swiftlint:disable force_cast + return theseObjs as! T + } + return try subRowReader.decode(intype, forKey: key) + } + private func filteredValues(_ values: [Any], lhs: ComparisonType, rhsKey: AnyKeyPath) -> [Any] { + return values.compactMap { + if let p = $0 as? PivotContainer { + guard let rhs = p.keys.first as? ComparisonType, + lhs == rhs else { + return nil + } + return p.instance + } + guard let rhs = $0[keyPath: rhsKey] as? ComparisonType, + lhs == rhs else { + return nil + } + return $0 + } + } + func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + return try subRowReader.nestedContainer(keyedBy: type, forKey: key) + } + func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer { + return try subRowReader.nestedUnkeyedContainer(forKey: key) + } + func superDecoder() throws -> Decoder { + return try subRowReader.superDecoder() + } + func superDecoder(forKey key: Key) throws -> Decoder { + return try subRowReader.superDecoder(forKey: key) + } +} diff --git a/Sources/PerfectCRUD/Coding/CodingKeyPaths.swift b/Sources/PerfectCRUD/Coding/CodingKeyPaths.swift new file mode 100644 index 00000000..71563fc0 --- /dev/null +++ b/Sources/PerfectCRUD/Coding/CodingKeyPaths.swift @@ -0,0 +1,457 @@ +// +// PerfectCRUDCodingKeyPaths.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-11-27. +// + +import Foundation + +class CRUDKeyPathsReader: KeyedDecodingContainerProtocol { + typealias Key = K + let codingPath: [CodingKey] = [] + let allKeys: [Key] = [] + let parent: CRUDKeyPathsDecoder + + init(_ p: CRUDKeyPathsDecoder) { + parent = p + } + func contains(_ key: Key) -> Bool { + return true + } + func decodeNil(forKey key: Key) throws -> Bool { + return false + } + func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { + return try parent.countBool(key) + } + func decode(_ type: Int.Type, forKey key: Key) throws -> Int { + return Int(parent.countKey(key)) + } + func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 { + return parent.countKey(key) + } + func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 { + return Int16(parent.countKey(key)) + } + func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { + return Int32(parent.countKey(key)) + } + func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 { + return Int64(parent.countKey(key)) + } + func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt { + return UInt(parent.countKey(key)) + } + func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 { + return UInt8(parent.countKey(key)) + } + func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 { + return UInt16(parent.countKey(key)) + } + func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 { + return UInt32(parent.countKey(key)) + } + func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 { + return UInt64(parent.countKey(key)) + } + func decode(_ type: Float.Type, forKey key: Key) throws -> Float { + return Float(parent.countKey(key)) + } + func decode(_ type: Double.Type, forKey key: Key) throws -> Double { + return Double(parent.countKey(key)) + } + func decode(_ type: String.Type, forKey key: Key) throws -> String { + return "\(parent.countKey(key))" + } + // swiftlint:disable comma force_cast + func decode(_ type: T.Type, forKey key: Key) throws -> T { + if type is WrappedCodableProvider.Type { + parent.wrappedKey = key + let decoded = try T(from: parent) + defer { + parent.wrappedKey = nil + } + return decoded + } + let counter = parent.countKey(key) + if let special = SpecialType(type) { + switch special { + case .uint8Array: + return [UInt8(counter)] as! T + case .int8Array: + return [Int8(counter)] as! T + case .data: + return Data([UInt8(counter)]) as! T + case .uuid: + return UUID(uuid: uuid_t(UInt8(counter),0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)) as! T + case .date: + return Date(timeIntervalSinceReferenceDate: TimeInterval(counter)) as! T + case .url: + return URL(string: "http://localhost:\(counter)/")! as! T + case .codable: + let decoder = CRUDKeyPathsDecoder(depth: 1 + parent.depth) + let decoded = try T(from: decoder) + parent.subTypeMap.append((key.stringValue, type, decoder)) + return decoded + case .wrapped: + throw CRUDDecoderError("Unhandled decode type \(type)") + } + } else { + let decoder = CRUDKeyPathsDecoder(depth: 1 + parent.depth) + let decoded = try T(from: decoder) + parent.subTypeMap.append((key.stringValue, type, decoder)) + return decoded + } + } + func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + throw CRUDDecoderError("Unimplimented nestedContainer") + } + func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer { + throw CRUDDecoderError("Unimplimented nestedUnkeyedContainer") + } + func superDecoder() throws -> Decoder { + return parent + } + func superDecoder(forKey key: Key) throws -> Decoder { + throw CRUDDecoderError("Unimplimented superDecoder") + } +} + +class CRUDKeyPathsUnkeyedReader: UnkeyedDecodingContainer, SingleValueDecodingContainer { + let codingPath: [CodingKey] = [] + var count: Int? = 1 + var isAtEnd: Bool { return !(currentIndex < count ?? 0) } + var currentIndex: Int = 0 + let parent: CRUDKeyPathsDecoder + let wrappedKey: CodingKey + + init(_ p: CRUDKeyPathsDecoder, key: CodingKey) { + wrappedKey = key + parent = p + } + + func decodeNil() -> Bool { + return false + } + + func decode(_ type: Bool.Type) throws -> Bool { + return try parent.countBool(wrappedKey) + } + + func decode(_ type: Int.Type) throws -> Int { + return Int(parent.countKey(wrappedKey)) + } + + func decode(_ type: Int8.Type) throws -> Int8 { + return Int8(parent.countKey(wrappedKey)) + } + + func decode(_ type: Int16.Type) throws -> Int16 { + return Int16(parent.countKey(wrappedKey)) + } + + func decode(_ type: Int32.Type) throws -> Int32 { + return Int32(parent.countKey(wrappedKey)) + } + + func decode(_ type: Int64.Type) throws -> Int64 { + return Int64(parent.countKey(wrappedKey)) + } + + func decode(_ type: UInt.Type) throws -> UInt { + return UInt(parent.countKey(wrappedKey)) + } + + func decode(_ type: UInt8.Type) throws -> UInt8 { + return UInt8(parent.countKey(wrappedKey)) + } + + func decode(_ type: UInt16.Type) throws -> UInt16 { + return UInt16(parent.countKey(wrappedKey)) + } + + func decode(_ type: UInt32.Type) throws -> UInt32 { + return UInt32(parent.countKey(wrappedKey)) + } + + func decode(_ type: UInt64.Type) throws -> UInt64 { + return UInt64(parent.countKey(wrappedKey)) + } + + func decode(_ type: Float.Type) throws -> Float { + return Float(parent.countKey(wrappedKey)) + } + + func decode(_ type: Double.Type) throws -> Double { + return Double(parent.countKey(wrappedKey)) + } + + func decode(_ type: String.Type) throws -> String { + return "\(parent.countKey(wrappedKey))" + } + + // swiftlint:disable comma + func decode(_ type: T.Type) throws -> T { + // this is being called in some cases for primitive types like Int + // instead of the proper funtion above + switch type { + case let t as Bool.Type: return try decode(t) as! T + case let t as Int.Type: return try decode(t) as! T + case let t as Int8.Type: return try decode(t) as! T + case let t as Int16.Type: return try decode(t) as! T + case let t as Int32.Type: return try decode(t) as! T + case let t as Int64.Type: return try decode(t) as! T + case let t as UInt.Type: return try decode(t) as! T + case let t as UInt8.Type: return try decode(t) as! T + case let t as UInt16.Type: return try decode(t) as! T + case let t as UInt32.Type: return try decode(t) as! T + case let t as UInt64.Type: return try decode(t) as! T + case let t as Float.Type: return try decode(t) as! T + case let t as Double.Type: return try decode(t) as! T + case let t as String.Type: return try decode(t) as! T + default: () + } + currentIndex += 1 + let counter = parent.countKey(wrappedKey) + if let special = SpecialType(type) { + switch special { + case .uint8Array: + return [UInt8(counter)] as! T + case .int8Array: + return [Int8(counter)] as! T + case .data: + return Data([UInt8(counter)]) as! T + case .uuid: + return UUID(uuid: uuid_t(UInt8(counter),0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)) as! T + case .date: + return Date(timeIntervalSinceReferenceDate: TimeInterval(counter)) as! T + case .url: + return URL(string: "http://localhost:\(counter)/")! as! T + case .codable: + let decoder = CRUDKeyPathsDecoder(depth: 1 + parent.depth) + let decoded = try T(from: decoder) + parent.subTypeMap.append((wrappedKey.stringValue, type, decoder)) + return decoded + case .wrapped: + throw CRUDDecoderError("Unhandled decode type \(type)") + } + } else { + let decoder = CRUDKeyPathsDecoder(depth: 1 + parent.depth) + let decoded = try T(from: decoder) + parent.subTypeMap.append((wrappedKey.stringValue, type, decoder)) + return decoded + } + } + + func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + throw CRUDDecoderError("Unimplimented nestedContainer") + } + + func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { + throw CRUDDecoderError("Unimplimented nestedUnkeyedContainer") + } + + func superDecoder() throws -> Decoder { + currentIndex += 1 + return parent + } +} + +class MyUnkeyedDecodingContainer: UnkeyedDecodingContainer { + var codingPath: [CodingKey] = [] + var count: Int? = 0 + var isAtEnd: Bool = true + var currentIndex: Int = 0 + + func decodeNil() throws -> Bool { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: Bool.Type) throws -> Bool { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: String.Type) throws -> String { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: Double.Type) throws -> Double { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: Float.Type) throws -> Float { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: Int.Type) throws -> Int { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: Int8.Type) throws -> Int8 { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: Int16.Type) throws -> Int16 { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: Int32.Type) throws -> Int32 { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: Int64.Type) throws -> Int64 { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: UInt.Type) throws -> UInt { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: UInt8.Type) throws -> UInt8 { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: UInt16.Type) throws -> UInt16 { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: UInt32.Type) throws -> UInt32 { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: UInt64.Type) throws -> UInt64 { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func decode(_ type: T.Type) throws -> T where T: Decodable { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } + + func superDecoder() throws -> Decoder { + throw CRUDDecoderError("MyUnkeyedDecodingContainer zero count") + } +} + +public class CRUDKeyPathsDecoder: Decoder { + public var codingPath: [CodingKey] = [] + public var userInfo: [CodingUserInfoKey: Any] = [:] + var counter: Int8 = 1 + var boolCounter: Int8 = 0 + var typeMap: [Int8: String] = [:] + var subTypeMap: [(String, Decodable.Type, CRUDKeyPathsDecoder)] = [] + let depth: Int + var wrappedKey: CodingKey? + + init(depth d: Int = 0) { + depth = d + } + + func countKey(_ key: CodingKey) -> Int8 { + counter += 1 + typeMap[counter] = key.stringValue + return counter + } + + func countBool(_ key: CodingKey) throws -> Bool { + guard boolCounter < 2 else { + throw CRUDDecoderError("Perfect-CRUD table types can have up to two Bool properties. Try using small ints (Int8) with bool 'var' accessors.") + } + typeMap[boolCounter] = key.stringValue + boolCounter += 1 + return boolCounter == 2 + } + + public func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer { + return KeyedDecodingContainer(CRUDKeyPathsReader(self)) + } + public func unkeyedContainer() throws -> UnkeyedDecodingContainer { + return MyUnkeyedDecodingContainer() + } + public func singleValueContainer() throws -> SingleValueDecodingContainer { + guard let wrappedKey = self.wrappedKey else { + throw CRUDDecoderError("No wrappedKey waiting for unkeyedContainer") + } + return CRUDKeyPathsUnkeyedReader(self, key: wrappedKey) + } + public func getKeyPathName(_ instance: Any, keyPath: AnyKeyPath) throws -> String? { + guard let v = instance[keyPath: keyPath] else { + return nil + } + return try getKeyPathName(fromValue: v) + } + private func getKeyPathName(fromValue v: Any) throws -> String? { + switch v { + case let b as Bool: + return typeMap[b ? 1 : 0] + case let s as String: + guard let v = Int8(s) else { + return nil + } + return typeMap[v] + case let i as Int: + return typeMap[Int8(i)] + case let i as Int8: + return typeMap[Int8(i)] + case let i as Int16: + return typeMap[Int8(i)] + case let i as Int32: + return typeMap[Int8(i)] + case let i as Int64: + return typeMap[Int8(i)] + case let i as UInt: + return typeMap[Int8(i)] + case let i as UInt8: + return typeMap[Int8(i)] + case let i as UInt16: + return typeMap[Int8(i)] + case let i as UInt32: + return typeMap[Int8(i)] + case let i as UInt64: + return typeMap[Int8(i)] + case let i as Float: + return typeMap[Int8(i)] + case let i as Double: + return typeMap[Int8(i)] + case let o as Any?: + guard let unType = o else { + return nil + } + if let found = subTypeMap.first(where: { $0.1 == type(of: unType) }) { + return found.0 + } + if let special = SpecialType(type(of: unType)) { + switch special { + case .uint8Array: + return typeMap[Int8((v as! [UInt8])[0])] + case .int8Array: + return typeMap[Int8((v as! [Int8])[0])] + case .data: + return typeMap[Int8((v as! Data).first!)] + case .uuid: + return typeMap[Int8((v as! UUID).uuid.0)] + case .date: + return typeMap[Int8((v as! Date).timeIntervalSinceReferenceDate)] + case .url: + return typeMap[Int8((v as! URL).port!)] + case .codable, .wrapped: + throw CRUDDecoderError("Unsupported operation on codable column.") + } + } + return nil + default: + guard let found = subTypeMap.first(where: { $0.1 == type(of: v) }) else { + return nil + } + return found.0 + } + } +} diff --git a/Sources/PerfectCRUD/Coding/CodingNames.swift b/Sources/PerfectCRUD/Coding/CodingNames.swift new file mode 100644 index 00000000..89e9c382 --- /dev/null +++ b/Sources/PerfectCRUD/Coding/CodingNames.swift @@ -0,0 +1,384 @@ +// +// PerfectCRUDCodingNames.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-11-25. +// Copyright (C) 2017 PerfectlySoft, Inc. +// +// ===----------------------------------------------------------------------===// +// +// This source file is part of the Perfect.org open source project +// +// Copyright (c) 2015 - 2017 PerfectlySoft Inc. and the Perfect project authors +// Licensed under Apache License v2.0 +// +// See http://perfect.org/licensing.html for license information +// +// ===----------------------------------------------------------------------===// +// + +import Foundation + +// -- reads and records the coding keys for an object +class CRUDColumnNamesReader: KeyedDecodingContainerProtocol { + typealias Key = K + var codingPath: [CodingKey] = [] + + var allKeys: [Key] = [] + var parent: CRUDColumnNameDecoder + var knownKeys = Set() + var isOptional = false + init(_ p: CRUDColumnNameDecoder) { + parent = p + } + func appendKey(_ key: Key, _ type: Any.Type) { + let s = key.stringValue + if !knownKeys.contains(s) { + parent.collectedKeys.append((s, isOptional, type)) + knownKeys.insert(s) + } + isOptional = false // reset + } + func contains(_ key: Key) -> Bool { + return true + } + func decodeNil(forKey key: Key) throws -> Bool { + isOptional = true + return false + } + func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { + appendKey(key, type) + return true + } + func decode(_ type: Int.Type, forKey key: Key) throws -> Int { + appendKey(key, type) + return 0 + } + func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 { + appendKey(key, type) + return 0 + } + func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 { + appendKey(key, type) + return 0 + } + func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { + appendKey(key, type) + return 0 + } + func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 { + appendKey(key, type) + return 0 + } + func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt { + appendKey(key, type) + return 0 + } + func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 { + appendKey(key, type) + return 0 + } + func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 { + appendKey(key, type) + return 0 + } + func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 { + appendKey(key, type) + return 0 + } + func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 { + appendKey(key, type) + return 0 + } + func decode(_ type: Float.Type, forKey key: Key) throws -> Float { + appendKey(key, type) + return 0 + } + func decode(_ type: Double.Type, forKey key: Key) throws -> Double { + appendKey(key, type) + return 0 + } + func decode(_ type: String.Type, forKey key: Key) throws -> String { + appendKey(key, type) + return "" + } + // swiftlint:disable force_cast + func decode(_ t: T.Type, forKey key: Key) throws -> T { + if let special = SpecialType(t) { + switch special { + case .uint8Array: + appendKey(key, t) + return [UInt8]() as! T + case .int8Array: + appendKey(key, t) + return [Int8]() as! T + case .data: + appendKey(key, t) + return Data() as! T + case .uuid: + appendKey(key, t) + return UUID() as! T + case .date: + appendKey(key, t) + return Date() as! T + case .url: + appendKey(key, t) + return URL(string: "http://localhost")! as! T + case .codable: + () + case .wrapped: + () +// guard let wrapped = t as? WrappedCodableProvider.Type else { +// throw CRUDEncoderError("Unsupported decoding type: \(t) for key: \(key.stringValue)") +// } +// let wrappedValueType = wrapped.provideWrappedValueType() +// switch wrappedValueType { +// case let m as Bool.Type: return try decode(m, forKey: key) +// case let m as Int.Type: return try decode(m, forKey: key) +// case let m as Int8.Type: return try decode(m, forKey: key) +// case let m as Int16.Type: return try decode(m, forKey: key) +// case let m as Int32.Type: return try decode(m, forKey: key) +// case let m as Int64.Type: return try decode(m, forKey: key) +// case let m as UInt.Type: return try decode(m, forKey: key) +// case let m as UInt8.Type: return try decode(m, forKey: key) +// case let m as UInt16.Type: return try decode(m, forKey: key) +// case let m as UInt32.Type: return try decode(m, forKey: key) +// case let m as UInt64.Type: return try decode(m, forKey: key) +// case let m as Float.Type: return try decode(m, forKey: key) +// case let m as Double.Type: return try decode(m, forKey: key) +// case let m as String.Type: return try decode(m, forKey: key) +// default: +// throw CRUDEncoderError("Unsupported decoding type: wrapped(\(wrappedValueType)) for key: \(key.stringValue)") +// } + } + } + return try decodeInner(t, forKey: key) + } + + func decodeInner(_ t: T.Type, forKey key: Key) throws -> T { + let sub = CRUDColumnNameDecoder(depth: 1 + parent.depth) + let ret = try T(from: sub) + if let ar = ret as? [Codable] { + if !ar.isEmpty { + let subType = type(of: ar[0]) + sub.codingPath.append(key) + sub.tableNamePath.append(subType.CRUDTableName) + ar[0].addSubTable(to: parent, name: key.stringValue, decoder: sub) + } + return ret +// } else if ret is WrappedValueTypeProvider { +// appendKey(key, type(of: ret as! WrappedValueTypeProvider).wrappedValueType()) +// return ret + } else if ret is Codable { // ... + appendKey(key, type(of: ret)) + return ret + } + throw CRUDSQLGenError("Unsupported sub-table type \(T.self)") + } + + func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { + throw CRUDDecoderError("Unimplimented nestedContainer") + } + func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer { + throw CRUDDecoderError("Unimplimented nestedUnkeyedContainer") + } + func superDecoder() throws -> Decoder { + throw CRUDDecoderError("Unimplimented superDecoder") + } + func superDecoder(forKey key: Key) throws -> Decoder { + throw CRUDDecoderError("Unimplimented superDecoder") + } +} + +class CRUDColumnNameUnkeyedReader: UnkeyedDecodingContainer, SingleValueDecodingContainer { + let codingPath: [CodingKey] = [] + var count: Int? = 1 + var isAtEnd: Bool { return !(currentIndex < count ?? 0) } + var currentIndex: Int = 0 + let parent: CRUDColumnNameDecoder + var decodedType: Any.Type? + var typeDecoder: CRUDColumnNameDecoder? + init(parent p: CRUDColumnNameDecoder) { + parent = p + } + func advance(_ t: Any.Type) { + currentIndex += 1 + decodedType = t + } + func decodeNil() -> Bool { + return false + } + + func decode(_ type: Bool.Type) throws -> Bool { + advance(type) + return false + } + + func decode(_ type: Int.Type) throws -> Int { + advance(type) + return 0 + } + + func decode(_ type: Int8.Type) throws -> Int8 { + advance(type) + return 0 + } + + func decode(_ type: Int16.Type) throws -> Int16 { + advance(type) + return 0 + } + + func decode(_ type: Int32.Type) throws -> Int32 { + advance(type) + return 0 + } + + func decode(_ type: Int64.Type) throws -> Int64 { + advance(type) + return 0 + } + + func decode(_ type: UInt.Type) throws -> UInt { + advance(type) + return 0 + } + + func decode(_ type: UInt8.Type) throws -> UInt8 { + advance(type) + return 0 + } + + func decode(_ type: UInt16.Type) throws -> UInt16 { + advance(type) + return 0 + } + + func decode(_ type: UInt32.Type) throws -> UInt32 { + advance(type) + return 0 + } + func decode(_ type: UInt64.Type) throws -> UInt64 { + advance(type) + return 0 + } + func decode(_ type: Float.Type) throws -> Float { + advance(type) + return 0 + } + func decode(_ type: Double.Type) throws -> Double { + advance(type) + return 0 + } + func decode(_ type: String.Type) throws -> String { + advance(type) + return "" + } + // swiftlint:disable force_cast + func decode(_ t: T.Type) throws -> T { + advance(t) + if let special = SpecialType(t) { + switch special { + case .uint8Array: + return [UInt8]() as! T + case .int8Array: + return [Int8]() as! T + case .data: + return Data() as! T + case .uuid: + return UUID() as! T + case .date: + return Date() as! T + case .url: + return URL(string: "http://localhost")! as! T + case .codable, .wrapped: + () + } + } + return try T(from: parent) + } + func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer { + throw CRUDDecoderError("Unimplimented nestedContainer") + } + func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { + throw CRUDDecoderError("Unimplimented nestedUnkeyedContainer") + } + func superDecoder() throws -> Decoder { + currentIndex += 1 + return parent + } +} + +protocol SubTableProto { + var name: String { get } +// var type: Decodable.Type { get } +// var decoder: CRUDColumnNameDecoder { get } + func tableStructure() throws -> TableStructure + func matches(_ type: T.Type) -> Bool +} + +struct SubTable: SubTableProto { + let name: String + let type: T.Type + let decoder: CRUDColumnNameDecoder + let realType: R.Type + func tableStructure() throws -> TableStructure { + return try type.self.CRUDTableStructure(columnDecoder: decoder) + } + func matches(_ type: T.Type) -> Bool { + return self.type == type + } +} + +extension Decodable where Self: Encodable { + // !FIX! causing ciompiler crash + func makeSubTable(name: String, decoder: CRUDColumnNameDecoder) -> some SubTableProto { + return SubTable(name: name, type: Self.self, decoder: decoder, realType: Self.self) + } + + func addSubTable(to: CRUDColumnNameDecoder, name: String, decoder: CRUDColumnNameDecoder) { + to.addSubTable(SubTable(name: name, type: Self.self, decoder: decoder, realType: Self.self)) + } +} + +public class CRUDColumnNameDecoder: Decoder { + public var codingPath: [CodingKey] = [] + public var userInfo: [CodingUserInfoKey: Any] = [:] + + var tableNamePath: [String] = [] + public var collectedKeys: [(name: String, optional: Bool, type: Any.Type)] = [] + var subTables: [SubTableProto] = [] + var pendingReader: CRUDColumnNameUnkeyedReader? + let depth: Int + public init(depth d: Int = 0) { + depth = d + } + func addSubTable(_ name: String, type: T.Type, decoder: CRUDColumnNameDecoder) { + guard subTables.filter({ $0.name == name }).count == 0 else { + return + } + subTables.append(SubTable(name: name, type: type, decoder: decoder, realType: type)) + } + func addSubTable(_ sub: T) { + guard subTables.filter({ $0.name == sub.name }).count == 0 else { + return + } + subTables.append(sub) + } + + public func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer { + return KeyedDecodingContainer(CRUDColumnNamesReader(self)) + } + public func unkeyedContainer() throws -> UnkeyedDecodingContainer { + let r = CRUDColumnNameUnkeyedReader(parent: self) + if depth > 1 { + r.count = 0 + } + pendingReader = r + return r + } + public func singleValueContainer() throws -> SingleValueDecodingContainer { + let r = CRUDColumnNameUnkeyedReader(parent: self) + return r + } +} diff --git a/Sources/PerfectCRUD/Coding/CodingRows.swift b/Sources/PerfectCRUD/Coding/CodingRows.swift new file mode 100644 index 00000000..241595b1 --- /dev/null +++ b/Sources/PerfectCRUD/Coding/CodingRows.swift @@ -0,0 +1,291 @@ +// +// PerfectCRUDCodingRows.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-11-25. +// Copyright (C) 2017 PerfectlySoft, Inc. +// +// ===----------------------------------------------------------------------===// +// +// This source file is part of the Perfect.org open source project +// +// Copyright (c) 2015 - 2017 PerfectlySoft Inc. and the Perfect project authors +// Licensed under Apache License v2.0 +// +// See http://perfect.org/licensing.html for license information +// +// ===----------------------------------------------------------------------===// +// + +import Foundation + +public class CRUDRowDecoder: Decoder { + public typealias Key = K + public var codingPath: [CodingKey] = [] + public var userInfo: [CodingUserInfoKey: Any] = [:] + let delegate: SQLExeDelegate + public init(delegate d: SQLExeDelegate) { + delegate = d + } + public func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer where Key: CodingKey { + guard let next: KeyedDecodingContainer = try delegate.next() else { + throw CRUDDecoderError("No row.") + } + return next + } + public func unkeyedContainer() throws -> UnkeyedDecodingContainer { + throw CRUDDecoderError("Unimplemented") + } + public func singleValueContainer() throws -> SingleValueDecodingContainer { + throw CRUDDecoderError("Unimplemented") + } +} + +public class CRUDColumnValueDecoder: Decoder, SingleValueDecodingContainer { + + public typealias Key = K + public var codingPath: [CodingKey] = [] + public var userInfo: [CodingUserInfoKey: Any] = [:] + // swiftlint:disable force_cast + var key: Key { codingPath.first! as! Key } + let source: KeyedDecodingContainer + public init(source: KeyedDecodingContainer, key: K) { + self.source = source + codingPath = [key] + } + public func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer where Key: CodingKey { + throw CRUDDecoderError("Unimplemented container") + } + public func unkeyedContainer() throws -> UnkeyedDecodingContainer { + throw CRUDDecoderError("Unimplemented") + } + public func singleValueContainer() throws -> SingleValueDecodingContainer { + return self // throw CRUDDecoderError("Unimplemented singleValueContainer") + } + + public func decodeNil() -> Bool { + return (try? source.decodeNil(forKey: key)) ?? false + } + + public func decode(_ type: Bool.Type) throws -> Bool { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: String.Type) throws -> String { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: Double.Type) throws -> Double { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: Float.Type) throws -> Float { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: Int.Type) throws -> Int { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: Int8.Type) throws -> Int8 { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: Int16.Type) throws -> Int16 { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: Int32.Type) throws -> Int32 { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: Int64.Type) throws -> Int64 { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: UInt.Type) throws -> UInt { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: UInt8.Type) throws -> UInt8 { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: UInt16.Type) throws -> UInt16 { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: UInt32.Type) throws -> UInt32 { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: UInt64.Type) throws -> UInt64 { + return try source.decode(type, forKey: key) + } + + public func decode(_ type: T.Type) throws -> T where T: Decodable { + return try source.decode(type, forKey: key) + } +} + +struct PivotKey: Codable { + let _crud_pivot_id_: T +} + +public class CRUDPivotRowDecoder: Decoder { + public typealias Key = K + + public var codingPath: [CodingKey] = [] + public var userInfo: [CodingUserInfoKey: Any] = [:] + let delegate: SQLExeDelegate + let pivotOnType: Codable.Type + public var orderedKeys: [Codable] = [] + public init(delegate d: SQLExeDelegate, pivotOn p: Codable.Type) { + delegate = d + pivotOnType = p + } + public func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer where Key: CodingKey { + guard let next: KeyedDecodingContainer = try delegate.next(), + let columnKey = ColumnKey(stringValue: joinPivotIdColumnName) else { + throw CRUDDecoderError("No row.") + } + switch pivotOnType { + case let i as Bool.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Int.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Int8.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Int16.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Int32.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Int64.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as UInt.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as UInt8.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as UInt16.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as UInt32.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as UInt64.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Float.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Double.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as String.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Date.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as Data.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + case let i as UUID.Type: + let keyValue = try next.decode(i, forKey: columnKey) + orderedKeys.append(keyValue) + default: + throw CRUDSQLExeError("Invalid join comparison type \(pivotOnType).") + } + return KeyedDecodingContainer(CRUDPivotRowReader(subReader: next)) + } + public func unkeyedContainer() throws -> UnkeyedDecodingContainer { + throw CRUDDecoderError("Unimplemented") + } + public func singleValueContainer() throws -> SingleValueDecodingContainer { + throw CRUDDecoderError("Unimplemented") + } +} + +class CRUDPivotRowReader: KeyedDecodingContainerProtocol { + typealias Key = K + var codingPath: [CodingKey] = [] + var allKeys: [K] = [] + let subReader: KeyedDecodingContainer + init(subReader s: KeyedDecodingContainer) { + subReader = s + } + private func k(_ key: Key) -> K2 { + return K2(stringValue: key.stringValue)! + } + func contains(_ key: K) -> Bool { + return subReader.contains(k(key)) + } + func decodeNil(forKey key: K) throws -> Bool { + return try subReader.decodeNil(forKey: k(key)) + } + func decode(_ type: Bool.Type, forKey key: K) throws -> Bool { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: Int.Type, forKey key: K) throws -> Int { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: Int8.Type, forKey key: K) throws -> Int8 { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: Int16.Type, forKey key: K) throws -> Int16 { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: Int32.Type, forKey key: K) throws -> Int32 { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: Int64.Type, forKey key: K) throws -> Int64 { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: UInt.Type, forKey key: K) throws -> UInt { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: UInt8.Type, forKey key: K) throws -> UInt8 { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: UInt16.Type, forKey key: K) throws -> UInt16 { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: UInt32.Type, forKey key: K) throws -> UInt32 { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: UInt64.Type, forKey key: K) throws -> UInt64 { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: Float.Type, forKey key: K) throws -> Float { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: Double.Type, forKey key: K) throws -> Double { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: String.Type, forKey key: K) throws -> String { + return try subReader.decode(type, forKey: k(key)) + } + func decode(_ type: T.Type, forKey key: K) throws -> T where T: Decodable { + return try subReader.decode(type, forKey: k(key)) + } + func nestedContainer(keyedBy type: NestedKey.Type, forKey key: K) throws -> KeyedDecodingContainer where NestedKey: CodingKey { + return try subReader.nestedContainer(keyedBy: type, forKey: k(key)) + } + func nestedUnkeyedContainer(forKey key: K) throws -> UnkeyedDecodingContainer { + return try subReader.nestedUnkeyedContainer(forKey: k(key)) + } + func superDecoder() throws -> Decoder { + return try subReader.superDecoder() + } + func superDecoder(forKey key: K) throws -> Decoder { + return try subReader.superDecoder(forKey: k(key)) + } +} diff --git a/Sources/PerfectCRUD/Create.swift b/Sources/PerfectCRUD/Create.swift new file mode 100644 index 00000000..8cf4eed0 --- /dev/null +++ b/Sources/PerfectCRUD/Create.swift @@ -0,0 +1,303 @@ +// +// PerfectCRUDCreate.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-12-03. +// + +import Foundation + +public struct TableCreatePolicy: OptionSet { + public let rawValue: Int + public init(rawValue r: Int) { rawValue = r } + public static let shallow = TableCreatePolicy(rawValue: 1) + public static let dropTable = TableCreatePolicy(rawValue: 2) + public static let reconcileTable = TableCreatePolicy(rawValue: 4) + + public static let defaultPolicy: TableCreatePolicy = [] +} + +public class TableStructure { + public class Column { + public enum Property: Equatable { + case primaryKey + case foreignKey(String, String, ForeignKeyAction, ForeignKeyAction) // table, column, onDelete, onUpdate + } + public let name: String + public let type: Any.Type + public let optional: Bool + public let properties: [Property] + init(name: String, type: Any.Type, optional: Bool, properties: [Property]) { + self.name = name + self.type = type + self.optional = optional + self.properties = properties + } + } + public let tableName: String + public var primaryKeyName: String? { columns.first(where: { $0.properties.contains(.primaryKey) })?.name } + public let columns: [Column] + public var subTables: [TableStructure] + public let indexes: [String] + init(tableName: String, columns: [Column], subTables: [TableStructure], indexes: [String]) { + self.tableName = tableName + self.columns = columns + self.subTables = subTables + self.indexes = indexes + } +} + +public protocol WrappedCodableProvider: Codable { + static func provideWrappedValueType() -> Codable.Type + func provideWrappedValue() -> Codable +} + +protocol PrimaryKeyWrapper: WrappedCodableProvider {} + +@propertyWrapper +public struct PrimaryKey: PrimaryKeyWrapper, Codable { + public static func provideWrappedValueType() -> Codable.Type { Value.self } + public var wrappedValue: Value + public var projectedValue: Value { wrappedValue } + public init(wrappedValue: Value) { + self.wrappedValue = wrappedValue + } + public init(from decoder: Decoder) throws { + wrappedValue = try decoder.singleValueContainer().decode(Value.self) + } + public func encode(to encoder: Encoder) throws { + var c = encoder.singleValueContainer() + try c.encode(wrappedValue) + } + public func provideWrappedValue() -> Codable { + return wrappedValue + } +} + +public enum ForeignKeyAction { + case ignore, restrict, setNull, setDefault, cascade +} + +public protocol ForeignKeyActionProvider { + static var action: ForeignKeyAction { get } +} + +public struct ForeignKeyActionIgnore: ForeignKeyActionProvider { + static public var action = ForeignKeyAction.ignore +} + +public struct ForeignKeyActionRestrict: ForeignKeyActionProvider { + static public var action = ForeignKeyAction.restrict +} + +public struct ForeignKeyActionSetNull: ForeignKeyActionProvider { + static public var action = ForeignKeyAction.setNull +} + +public struct ForeignKeyActionSetDefault: ForeignKeyActionProvider { + static public var action = ForeignKeyAction.setDefault +} + +public struct ForeignKeyActionCascade: ForeignKeyActionProvider { + static public var action = ForeignKeyAction.cascade +} + +public let ignore = ForeignKeyActionIgnore() +public let restrict = ForeignKeyActionRestrict() +public let setNull = ForeignKeyActionSetNull() +public let setDefault = ForeignKeyActionSetDefault() +public let cascade = ForeignKeyActionCascade() + +protocol ForeignKeyWrapper: WrappedCodableProvider { + static func foreignTableStructure() throws -> TableStructure + static func foreignKeyDeleteAction() -> ForeignKeyAction + static func foreignKeyUpdateAction() -> ForeignKeyAction +} + +@propertyWrapper +public struct ForeignKey: ForeignKeyWrapper, Codable { + public static func provideWrappedValueType() -> Codable.Type { Value.self } + static func foreignKeyDeleteAction() -> ForeignKeyAction { DeleteAction.action } + static func foreignKeyUpdateAction() -> ForeignKeyAction { UpdateAction.action } + static func foreignTableStructure() throws -> TableStructure { + return try Table.CRUDTableStructure() + } + + public var wrappedValue: Value { + get { projectedValue! } + set { projectedValue = newValue } + } + public var projectedValue: Value? = nil + + public init(_ parent: Table.Type, onDelete: DeleteAction, onUpdate: UpdateAction, wrappedValue: Value) { + self.projectedValue = wrappedValue + } + public init(_ parent: Table.Type, onDelete: DeleteAction, onUpdate: UpdateAction) { + + } + public init(from decoder: Decoder) throws { + projectedValue = try decoder.singleValueContainer().decode(Value.self) + } + public func encode(to encoder: Encoder) throws { + var c = encoder.singleValueContainer() + try c.encode(projectedValue!) + } + public func provideWrappedValue() -> Codable { + return wrappedValue + } +} + +private var tableStructureCache: [String: TableStructure] = [:] + +// for tests +public func CRUDClearTableStructureCache() { + tableStructureCache.removeAll() +} + +extension Decodable { + static func CRUDTableStructure(primaryKey: PartialKeyPath? = nil) throws -> TableStructure { + let columnDecoder = CRUDColumnNameDecoder() + columnDecoder.tableNamePath.append("\(Self.CRUDTableName)") + _ = try Self.init(from: columnDecoder) + return try CRUDTableStructure(columnDecoder: columnDecoder, primaryKey: primaryKey) + } + static func CRUDTableStructure(columnDecoder: CRUDColumnNameDecoder, primaryKey: PartialKeyPath? = nil) throws -> TableStructure { + let cacheKey = "\(type(of: Self.self))" + if let cached = tableStructureCache[cacheKey] { + return cached + } + let primaryKeyName: String? + if let pkpk = primaryKey { + let pathDecoder = CRUDKeyPathsDecoder() + let pathInstance = try Self.init(from: pathDecoder) + guard let pkn = try pathDecoder.getKeyPathName(pathInstance, keyPath: pkpk) else { + throw CRUDSQLGenError("Could not get column name for primary key \(Self.self).") + } + primaryKeyName = pkn + } else if let key = columnDecoder.collectedKeys.filter({$0.type is PrimaryKeyWrapper.Type }).first { + primaryKeyName = key.name + } else if columnDecoder.collectedKeys.map({$0.0}).contains("id") { + primaryKeyName = "id" + } else { + primaryKeyName = nil + } + let thisTableName = columnDecoder.tableNamePath.last! + let tableStruct = TableStructure( + tableName: thisTableName, + columns: columnDecoder.collectedKeys.map { + var props: [TableStructure.Column.Property] = [] + if $0.0 == primaryKeyName { + props.append(.primaryKey) + } + if let foreignWrapper = $0.type as? ForeignKeyWrapper.Type, + let foreignInfo = try? foreignWrapper.foreignTableStructure(), + let foreignPK = foreignInfo.columns.first(where: { $0.properties.contains(.primaryKey) }) { + props.append(.foreignKey(foreignInfo.tableName, foreignPK.name, foreignWrapper.foreignKeyDeleteAction(), foreignWrapper.foreignKeyUpdateAction())) + } + let itype: Any.Type + if let wrapper = $0.type as? WrappedCodableProvider.Type { + itype = wrapper.provideWrappedValueType() + } else { + itype = $0.type + } + return .init(name: $0.name, type: itype, optional: $0.optional, properties: props) + }, + subTables: [], + indexes: []) + tableStructureCache[cacheKey] = tableStruct + tableStruct.subTables = try columnDecoder.subTables.filter { !$0.matches(Self.self) }.map { + return try $0.tableStructure() + } + return tableStruct + } +} + +public struct Create { + typealias OverAllForm = OAF + let fromDatabase: D + let policy: TableCreatePolicy + let tableStructure: TableStructure + init(fromDatabase ft: D, primaryKey: PartialKeyPath?, policy p: TableCreatePolicy) throws { + fromDatabase = ft + policy = p + tableStructure = try OverAllForm.CRUDTableStructure(primaryKey: primaryKey) + let delegate = fromDatabase.configuration.sqlGenDelegate + let sql = try delegate.getCreateTableSQL(forTable: tableStructure, policy: policy) + for stat in sql { + CRUDLogging.log(.query, stat) + let exeDelegate = try fromDatabase.configuration.sqlExeDelegate(forSQL: stat) + _ = try exeDelegate.hasNext() + } + } +} + +public struct Index: FromTableProtocol, TableProtocol { + public typealias Form = OAF + public typealias FromTableType = A + public typealias OverAllForm = OAF + public let fromTable: FromTableType + init(fromTable ft: FromTableType, keys: [PartialKeyPath], unique: Bool) throws { + fromTable = ft + let delegate = ft.databaseConfiguration.sqlGenDelegate + let tableName = "\(OverAllForm.CRUDTableName)" + let pathDecoder = CRUDKeyPathsDecoder() + let pathInstance = try OverAllForm.init(from: pathDecoder) + let keyNames: [String] = try keys.map { + guard let pkn = try pathDecoder.getKeyPathName(pathInstance, keyPath: $0) else { + throw CRUDSQLGenError("Could not get column name for index \(OverAllForm.self).") + } + return pkn + } + let sql = try delegate.getCreateIndexSQL(forTable: tableName, on: keyNames, unique: unique) + for stat in sql { + CRUDLogging.log(.query, stat) + let exeDelegate = try ft.databaseConfiguration.sqlExeDelegate(forSQL: stat) + _ = try exeDelegate.hasNext() + } + } + public func setState(state: inout SQLGenState) throws {} + public func setSQL(state: inout SQLGenState) throws {} +} + +public extension DatabaseProtocol { + @discardableResult + func create(_ type: A.Type, policy: TableCreatePolicy = .defaultPolicy) throws -> Table { + let _: Create = try Create(fromDatabase: self, primaryKey: nil, policy: policy) + return Table(database: self) + } + @discardableResult + func create(_ type: A.Type, primaryKey: KeyPath? = nil, policy: TableCreatePolicy = .defaultPolicy) throws -> Table { + let _: Create = try Create(fromDatabase: self, primaryKey: primaryKey, policy: policy) + return Table(database: self) + } +} +// swiftlint:disable line_length +public extension Table { + @discardableResult + func index(unique: Bool = false, _ keys: PartialKeyPath...) throws -> Index { + return try .init(fromTable: self, keys: keys, unique: unique) + } + // !FIX! Swift 4.0.2 seems to have a problem with type inference for the above func + // would not let \.name type references to be used + // this is an ugly work around + @discardableResult + func index(unique: Bool = false, _ key: KeyPath) throws -> Index { + return try .init(fromTable: self, keys: [key], unique: unique) + } + @discardableResult + func index(unique: Bool = false, _ key: KeyPath, _ key2: KeyPath) throws -> Index { + return try .init(fromTable: self, keys: [key, key2], unique: unique) + } + @discardableResult + func index(unique: Bool = false, _ key: KeyPath, _ key2: KeyPath, _ key3: KeyPath) throws -> Index { + return try .init(fromTable: self, keys: [key, key2, key3], unique: unique) + } + @discardableResult + func index(unique: Bool = false, _ key: KeyPath, _ key2: KeyPath, _ key3: KeyPath, _ key4: KeyPath) throws -> Index { + return try .init(fromTable: self, keys: [key, key2, key3, key4], unique: unique) + } + @discardableResult + func index(unique: Bool = false, _ key: KeyPath, _ key2: KeyPath, _ key3: KeyPath, _ key4: KeyPath, _ key5: KeyPath) throws -> Index { + return try .init(fromTable: self, keys: [key, key2, key3, key4, key5], unique: unique) + } +} diff --git a/Sources/PerfectCRUD/Database.swift b/Sources/PerfectCRUD/Database.swift new file mode 100644 index 00000000..f607f2cd --- /dev/null +++ b/Sources/PerfectCRUD/Database.swift @@ -0,0 +1,70 @@ +// +// PerfectCRUDDatabase.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-12-02. +// + +import Foundation + +public struct Database: DatabaseProtocol { + public typealias Configuration = C + public let configuration: Configuration + public init(configuration c: Configuration) { + configuration = c + } + public func table(_ form: T.Type) -> Table { + return .init(database: self) + } +} + +public extension Database { + func sql(_ sql: String, bindings: Bindings = []) throws { + CRUDLogging.log(.query, sql) + let delegate = try configuration.sqlExeDelegate(forSQL: sql) + try delegate.bind(bindings, skip: 0) + _ = try delegate.hasNext() + } + func sql(_ sql: String, bindings: Bindings = [], _ type: A.Type) throws -> [A] { + CRUDLogging.log(.query, sql) + let delegate = try configuration.sqlExeDelegate(forSQL: sql) + try delegate.bind(bindings, skip: 0) + var ret: [A] = [] + while try delegate.hasNext() { + let rowDecoder: CRUDRowDecoder = CRUDRowDecoder(delegate: delegate) + ret.append(try A(from: rowDecoder)) + } + return ret + } + func asyncSql(_ sql: String, bindings: Bindings = [], _ type: A.Type, completion: @escaping ([A], Error?) -> ()) throws { + CRUDLogging.log(.query, sql) + let delegate = try configuration.sqlExeDelegate(forSQL: sql) + try delegate.bind(bindings, skip: 0) + delegate.asyncExecute { delegate in + var ret: [A] = [] + do { + while try delegate.hasNext() { + let rowDecoder: CRUDRowDecoder = CRUDRowDecoder(delegate: delegate) + ret.append(try A(from: rowDecoder)) + } + completion(ret, nil) + } catch { + completion(ret, error) + } + } + } +} + +public extension Database { + func transaction(_ body: () throws -> T) throws -> T { + try sql("BEGIN") + do { + let r = try body() + try sql("COMMIT") + return r + } catch { + try sql("ROLLBACK") + throw error + } + } +} diff --git a/Sources/PerfectCRUD/Delete.swift b/Sources/PerfectCRUD/Delete.swift new file mode 100644 index 00000000..dfe046fc --- /dev/null +++ b/Sources/PerfectCRUD/Delete.swift @@ -0,0 +1,41 @@ +// +// PerfectCRUDDelete.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-12-03. +// + +import Foundation + +public protocol Deleteable: TableProtocol { + @discardableResult + func delete() throws -> Delete +} + +public extension Deleteable { + @discardableResult + func delete() throws -> Delete { + return try .init(fromTable: self) + } +} + +public struct Delete: FromTableProtocol, CommandProtocol { + public typealias FromTableType = A + public typealias OverAllForm = OAF + public let fromTable: FromTableType + public let sqlGenState: SQLGenState + init(fromTable ft: FromTableType) throws { + fromTable = ft + let delegate = ft.databaseConfiguration.sqlGenDelegate + var state = SQLGenState(delegate: delegate) + state.command = .delete + try ft.setState(state: &state) + try ft.setSQL(state: &state) + sqlGenState = state + for stat in state.statements { + let exeDelegate = try databaseConfiguration.sqlExeDelegate(forSQL: stat.sql) + try exeDelegate.bind(stat.bindings) + _ = try exeDelegate.hasNext() + } + } +} diff --git a/Sources/PerfectCRUD/Expression/Comparison.swift b/Sources/PerfectCRUD/Expression/Comparison.swift new file mode 100644 index 00000000..4b66a3c8 --- /dev/null +++ b/Sources/PerfectCRUD/Expression/Comparison.swift @@ -0,0 +1,73 @@ +// +// Comparison.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-02-18. +// + +import Foundation + +// < +public func < (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .string(rhs))) +} +public func < (lhs: KeyPath, rhs: Double) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .decimal(rhs))) +} +public func < (lhs: KeyPath, rhs: Bool) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .bool(rhs))) +} +public func < (lhs: KeyPath, rhs: UUID) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .uuid(rhs))) +} +public func < (lhs: KeyPath, rhs: Date) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .date(rhs))) +} +// > +public func > (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .string(rhs))) +} +public func > (lhs: KeyPath, rhs: Double) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .decimal(rhs))) +} +public func > (lhs: KeyPath, rhs: Bool) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .bool(rhs))) +} +public func > (lhs: KeyPath, rhs: UUID) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .uuid(rhs))) +} +public func > (lhs: KeyPath, rhs: Date) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .date(rhs))) +} +// <= +public func <= (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .string(rhs))) +} +public func <= (lhs: KeyPath, rhs: Double) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .decimal(rhs))) +} +public func <= (lhs: KeyPath, rhs: Bool) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .bool(rhs))) +} +public func <= (lhs: KeyPath, rhs: UUID) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .uuid(rhs))) +} +public func <= (lhs: KeyPath, rhs: Date) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .date(rhs))) +} +// >= +public func >= (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .string(rhs))) +} +public func >= (lhs: KeyPath, rhs: Double) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .decimal(rhs))) +} +public func >= (lhs: KeyPath, rhs: Bool) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .bool(rhs))) +} +public func >= (lhs: KeyPath, rhs: UUID) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .uuid(rhs))) +} +public func >= (lhs: KeyPath, rhs: Date) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .date(rhs))) +} diff --git a/Sources/PerfectCRUD/Expression/ComparisonInts.swift b/Sources/PerfectCRUD/Expression/ComparisonInts.swift new file mode 100644 index 00000000..504d5859 --- /dev/null +++ b/Sources/PerfectCRUD/Expression/ComparisonInts.swift @@ -0,0 +1,157 @@ +// +// ComparisonInts.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-03-11. +// + +import Foundation + +// < +public func < (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .integer(rhs))) +} +public func < (lhs: KeyPath, rhs: UInt) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .uinteger(rhs))) +} +public func < (lhs: KeyPath, rhs: Int64) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .integer64(rhs))) +} +public func < (lhs: KeyPath, rhs: UInt64) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .uinteger64(rhs))) +} +public func < (lhs: KeyPath, rhs: Int32) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .integer32(rhs))) +} +public func < (lhs: KeyPath, rhs: UInt32) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .uinteger32(rhs))) +} +public func < (lhs: KeyPath, rhs: Int16) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .integer16(rhs))) +} +public func < (lhs: KeyPath, rhs: UInt16) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .uinteger16(rhs))) +} +public func < (lhs: KeyPath, rhs: Int8) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .integer8(rhs))) +} +public func < (lhs: KeyPath, rhs: UInt8) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .uinteger8(rhs))) +} +public func < (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .blob(rhs))) +} +public func < (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThan(lhs: .keyPath(lhs), rhs: .sblob(rhs))) +} +// > +public func > (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .integer(rhs))) +} +public func > (lhs: KeyPath, rhs: UInt) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .uinteger(rhs))) +} +public func > (lhs: KeyPath, rhs: Int64) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .integer64(rhs))) +} +public func > (lhs: KeyPath, rhs: UInt64) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .uinteger64(rhs))) +} +public func > (lhs: KeyPath, rhs: Int32) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .integer32(rhs))) +} +public func > (lhs: KeyPath, rhs: UInt32) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .uinteger32(rhs))) +} +public func > (lhs: KeyPath, rhs: Int16) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .integer16(rhs))) +} +public func > (lhs: KeyPath, rhs: UInt16) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .uinteger16(rhs))) +} +public func > (lhs: KeyPath, rhs: Int8) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .integer8(rhs))) +} +public func > (lhs: KeyPath, rhs: UInt8) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .uinteger8(rhs))) +} +public func > (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .blob(rhs))) +} +public func > (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThan(lhs: .keyPath(lhs), rhs: .sblob(rhs))) +} +// <= +public func <= (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .integer(rhs))) +} +public func <= (lhs: KeyPath, rhs: UInt) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .uinteger(rhs))) +} +public func <= (lhs: KeyPath, rhs: Int64) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .integer64(rhs))) +} +public func <= (lhs: KeyPath, rhs: UInt64) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .uinteger64(rhs))) +} +public func <= (lhs: KeyPath, rhs: Int32) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .integer32(rhs))) +} +public func <= (lhs: KeyPath, rhs: UInt32) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .uinteger32(rhs))) +} +public func <= (lhs: KeyPath, rhs: Int16) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .integer16(rhs))) +} +public func <= (lhs: KeyPath, rhs: UInt16) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .uinteger16(rhs))) +} +public func <= (lhs: KeyPath, rhs: Int8) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .integer8(rhs))) +} +public func <= (lhs: KeyPath, rhs: UInt8) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .uinteger8(rhs))) +} +public func <= (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .blob(rhs))) +} +public func <= (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.lessThanEqual(lhs: .keyPath(lhs), rhs: .sblob(rhs))) +} +// >= +public func >= (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .integer(rhs))) +} +public func >= (lhs: KeyPath, rhs: UInt) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .uinteger(rhs))) +} +public func >= (lhs: KeyPath, rhs: Int64) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .integer64(rhs))) +} +public func >= (lhs: KeyPath, rhs: UInt64) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .uinteger64(rhs))) +} +public func >= (lhs: KeyPath, rhs: Int32) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .integer32(rhs))) +} +public func >= (lhs: KeyPath, rhs: UInt32) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .uinteger32(rhs))) +} +public func >= (lhs: KeyPath, rhs: Int16) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .integer16(rhs))) +} +public func >= (lhs: KeyPath, rhs: UInt16) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .uinteger16(rhs))) +} +public func >= (lhs: KeyPath, rhs: Int8) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .integer8(rhs))) +} +public func >= (lhs: KeyPath, rhs: UInt8) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .uinteger8(rhs))) +} +public func >= (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .blob(rhs))) +} +public func >= (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.greaterThanEqual(lhs: .keyPath(lhs), rhs: .sblob(rhs))) +} diff --git a/Sources/PerfectCRUD/Expression/Equality.swift b/Sources/PerfectCRUD/Expression/Equality.swift new file mode 100644 index 00000000..42b82364 --- /dev/null +++ b/Sources/PerfectCRUD/Expression/Equality.swift @@ -0,0 +1,121 @@ +// +// Equality.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-02-18. +// + +import Foundation + +// == +public func == (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .string(rhs))) +} +public func == (lhs: KeyPath, rhs: Double) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .decimal(rhs))) +} +public func == (lhs: KeyPath, rhs: Float) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .float(rhs))) +} +public func == (lhs: KeyPath, rhs: Bool) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .bool(rhs))) +} +public func == (lhs: KeyPath, rhs: UUID) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uuid(rhs))) +} +public func == (lhs: KeyPath, rhs: Date) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .date(rhs))) +} +// == ? +public func == (lhs: KeyPath, rhs: String?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .string(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Double?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .decimal(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Float?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .float(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Bool?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .bool(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: UUID?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uuid(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Date?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .date(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +// != +public func != (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .string(rhs))) +} +public func != (lhs: KeyPath, rhs: Double) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .decimal(rhs))) +} +public func != (lhs: KeyPath, rhs: Float) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .float(rhs))) +} +public func != (lhs: KeyPath, rhs: Bool) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .bool(rhs))) +} +public func != (lhs: KeyPath, rhs: UUID) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uuid(rhs))) +} +public func != (lhs: KeyPath, rhs: Date) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .date(rhs))) +} +// != ? +public func != (lhs: KeyPath, rhs: String?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .string(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Double?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .decimal(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Float?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .float(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Bool?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .bool(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: UUID?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uuid(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Date?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .date(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} diff --git a/Sources/PerfectCRUD/Expression/EqualityInts.swift b/Sources/PerfectCRUD/Expression/EqualityInts.swift new file mode 100644 index 00000000..f147cb67 --- /dev/null +++ b/Sources/PerfectCRUD/Expression/EqualityInts.swift @@ -0,0 +1,367 @@ +// +// EqualityInts.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-03-11. +// + +import Foundation + +// == +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer(rhs))) +} +public func == (lhs: KeyPath, rhs: UInt) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger(UInt(rhs)))) +} +public func == (lhs: KeyPath, rhs: Int64) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer64(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer64(Int64(rhs)))) +} +public func == (lhs: KeyPath, rhs: UInt64) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger64(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger64(UInt64(rhs)))) +} +public func == (lhs: KeyPath, rhs: Int32) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer32(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer32(Int32(rhs)))) +} +public func == (lhs: KeyPath, rhs: UInt32) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger32(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger32(UInt32(rhs)))) +} +public func == (lhs: KeyPath, rhs: Int16) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer16(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer16(Int16(rhs)))) +} +public func == (lhs: KeyPath, rhs: UInt16) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger16(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger16(UInt16(rhs)))) +} +public func == (lhs: KeyPath, rhs: Int8) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer8(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer8(Int8(rhs)))) +} +public func == (lhs: KeyPath, rhs: UInt8) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger8(rhs))) +} +public func == (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger8(UInt8(rhs)))) +} +public func == (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .blob(rhs))) +} +public func == (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .sblob(rhs))) +} +// == ? +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: UInt?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger(UInt(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int64?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer64(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer64(Int64(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: UInt64?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger64(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger64(UInt64(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int32?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer32(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer32(Int32(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: UInt32?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger32(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger32(UInt32(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int16?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer16(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer16(Int16(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: UInt16?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger16(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger16(UInt16(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int8?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer8(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .integer8(Int8(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: UInt8?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger8(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .uinteger8(UInt8(rhs)))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: [UInt8]?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .blob(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +public func == (lhs: KeyPath, rhs: [Int8]?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .sblob(rhs))) + } + return RealBooleanExpression(.equality(lhs: .keyPath(lhs), rhs: .null)) +} +// != +public func != (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer(rhs))) +} +public func != (lhs: KeyPath, rhs: UInt) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger(rhs))) +} +public func != (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger(UInt(rhs)))) +} +public func != (lhs: KeyPath, rhs: Int64) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer64(rhs))) +} +public func != (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer64(Int64(rhs)))) +} +public func != (lhs: KeyPath, rhs: Int32) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer32(rhs))) +} +public func != (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer32(Int32(rhs)))) +} +public func != (lhs: KeyPath, rhs: Int16) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer16(rhs))) +} +public func != (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer16(Int16(rhs)))) +} +public func != (lhs: KeyPath, rhs: Int8) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer8(rhs))) +} +public func != (lhs: KeyPath, rhs: Int) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer8(Int8(rhs)))) +} +public func != (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .blob(rhs))) +} +public func != (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .sblob(rhs))) +} +// != ? +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: UInt?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger(UInt(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int64?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer64(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer64(Int64(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: UInt64?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger64(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger64(UInt64(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int32?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer32(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer32(Int32(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: UInt32?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger32(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger32(UInt32(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int16?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer16(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer16(Int16(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: UInt16?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger16(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger16(UInt16(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int8?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer8(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .integer8(Int8(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: UInt8?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger8(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: Int?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .uinteger8(UInt8(rhs)))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: [UInt8]?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .blob(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} +public func != (lhs: KeyPath, rhs: [Int8]?) -> CRUDBooleanExpression { + if let rhs = rhs { + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .sblob(rhs))) + } + return RealBooleanExpression(.inequality(lhs: .keyPath(lhs), rhs: .null)) +} diff --git a/Sources/PerfectCRUD/Expression/Expression.swift b/Sources/PerfectCRUD/Expression/Expression.swift new file mode 100644 index 00000000..54092b47 --- /dev/null +++ b/Sources/PerfectCRUD/Expression/Expression.swift @@ -0,0 +1,204 @@ +// +// PerfectCRUDExpressions.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-11-22. +// Copyright (C) 2017 PerfectlySoft, Inc. +// +// ===----------------------------------------------------------------------===// +// +// This source file is part of the Perfect.org open source project +// +// Copyright (c) 2015 - 2017 PerfectlySoft Inc. and the Perfect project authors +// Licensed under Apache License v2.0 +// +// See http://perfect.org/licensing.html for license information +// +// ===----------------------------------------------------------------------===// +// +import Foundation + +public indirect enum CRUDExpression { + public typealias ExpressionProducer = () -> CRUDExpression + + case column(String) + case and(lhs: CRUDExpression, rhs: CRUDExpression) + case or(lhs: CRUDExpression, rhs: CRUDExpression) + case equality(lhs: CRUDExpression, rhs: CRUDExpression) + case inequality(lhs: CRUDExpression, rhs: CRUDExpression) + case not(rhs: CRUDExpression) + case lessThan(lhs: CRUDExpression, rhs: CRUDExpression) + case lessThanEqual(lhs: CRUDExpression, rhs: CRUDExpression) + case greaterThan(lhs: CRUDExpression, rhs: CRUDExpression) + case greaterThanEqual(lhs: CRUDExpression, rhs: CRUDExpression) + case `in`(lhs: CRUDExpression, rhs: [CRUDExpression]) + case like(lhs: CRUDExpression, wild1: Bool, String, wild2: Bool) + case lazy(ExpressionProducer) + case keyPath(AnyKeyPath) + + case integer(Int) + case uinteger(UInt) + case integer64(Int64) + case uinteger64(UInt64) + case integer32(Int32) + case uinteger32(UInt32) + case integer16(Int16) + case uinteger16(UInt16) + case integer8(Int8) + case uinteger8(UInt8) + + case decimal(Double) + case float(Float) + case string(String) + case blob([UInt8]) + case sblob([Int8]) + case bool(Bool) + case uuid(UUID) + case date(Date) + case url(URL) + case null + + // todo: + // .blob with Data + // .integer of varying width +} + +public protocol CRUDBooleanExpression { + var crudExpression: CRUDExpression { get } +} + +struct RealBooleanExpression: CRUDBooleanExpression { + let crudExpression: CRUDExpression + init(_ e: CRUDExpression) { + crudExpression = e + } +} + +infix operator ~: ComparisonPrecedence // IN, matches +infix operator !~: ComparisonPrecedence // NOT IN, matches +infix operator %=%: ComparisonPrecedence // LIKE %v% . string or regexp or in array +infix operator =%: ComparisonPrecedence // LIKE v% . string +infix operator %!=: ComparisonPrecedence // NOT LIKE %v . string +infix operator %!=%: ComparisonPrecedence // NOT LIKE %v% . string or regexp or array +infix operator !=%: ComparisonPrecedence // NOT LIKE v% . string + +extension CRUDExpression { + static func sqlSnippet(keyPath: AnyKeyPath, tableData: SQLGenState.TableData, state: SQLGenState) throws -> String { + let delegate = state.delegate + let rootType = type(of: keyPath).rootType + guard let modelInstance = tableData.modelInstance else { + throw CRUDSQLGenError("Unable to get table for KeyPath root \(rootType).") + } + guard let keyName = try tableData.keyPathDecoder.getKeyPathName(modelInstance, keyPath: keyPath) else { + throw CRUDSQLGenError("Unable to get KeyPath name for table \(rootType).") + } + let nameQ = try delegate.quote(identifier: keyName) + switch state.command { + case .select, .count: + let aliasQ = try delegate.quote(identifier: tableData.alias) + return "\(aliasQ).\(nameQ)" + case .insert, .update, .delete: + return nameQ + case .unknown: + throw CRUDSQLGenError("Can not process unknown command.") + } + } + func sqlSnippet(state: SQLGenState) throws -> String { + let delegate = state.delegate + switch self { + case .column(let name): + return try delegate.quote(identifier: name) + case .and(let lhs, let rhs): + return try binparen(state, "AND", lhs, rhs) + case .or(let lhs, let rhs): + return try binparen(state, "OR", lhs, rhs) + case .equality(let lhs, let rhs): + if case .null = rhs { + return "\(try lhs.sqlSnippet(state: state)) IS NULL" + } + return try bin(state, "=", lhs, rhs) + case .inequality(let lhs, let rhs): + if case .null = rhs { + return "\(try lhs.sqlSnippet(state: state)) IS NOT NULL" + } + return try bin(state, "!=", lhs, rhs) + case .not(let rhs): + let rhsStr = try rhs.sqlSnippet(state: state) + return "NOT (\(rhsStr))" + case .lessThan(let lhs, let rhs): + return try bin(state, "<", lhs, rhs) + case .lessThanEqual(let lhs, let rhs): + return try bin(state, "<=", lhs, rhs) + case .greaterThan(let lhs, let rhs): + return try bin(state, ">", lhs, rhs) + case .greaterThanEqual(let lhs, let rhs): + return try bin(state, ">=", lhs, rhs) + case .keyPath(let k): + let rootType = type(of: k).rootType + guard let tableData = state.getTableData(type: rootType) else { + throw CRUDSQLGenError("Unable to get table for KeyPath root \(rootType).") + } + return try CRUDExpression.sqlSnippet(keyPath: k, tableData: tableData, state: state) + case .null: + return "NULL" + case .lazy(let e): + return try e().sqlSnippet(state: state) + case .integer(_), .uinteger(_), .integer64(_), .uinteger64(_), .integer32(_), .uinteger32(_), .integer16(_), .uinteger16(_), .integer8(_), .uinteger8(_): + return try delegate.getBinding(for: self) + case .decimal(_), .float(_), .string(_), .blob(_), .sblob(_), .bool(_), .uuid(_), .date(_), .url(_): + return try delegate.getBinding(for: self) + case .in(let lhs, let exprs): + return "\(try lhs.sqlSnippet(state: state)) IN (\(try exprs.map { try $0.sqlSnippet(state: state) }.joined(separator: ",")))" + case .like(let lhs, let wild1, let match, let wild2): + let rhs = "\(wild1 ? "%" : "")\(match.replacingOccurrences(of: "%", with: "\\%"))\(wild2 ? "%" : "")" + return try bin(state, "LIKE", lhs, .string(rhs)) + } + } + private func bin(_ state: SQLGenState, _ op: String, _ lhs: CRUDExpression, _ rhs: CRUDExpression) throws -> String { + return "\(try lhs.sqlSnippet(state: state)) \(op) \(try rhs.sqlSnippet(state: state))" + } + private func binparen(_ state: SQLGenState, _ op: String, _ lhs: CRUDExpression, _ rhs: CRUDExpression) throws -> String { + return "(\(try lhs.sqlSnippet(state: state)) \(op) \(try rhs.sqlSnippet(state: state)))" + } + private func un(_ state: SQLGenState, _ op: String, _ rhs: CRUDExpression) throws -> String { + return "\(op) \(try rhs.sqlSnippet(state: state))" + } + func referencedTypes() -> [Any.Type] { + switch self { + case .column(_): + return [] + case .and(let lhs, let rhs): + return lhs.referencedTypes() + rhs.referencedTypes() + case .or(let lhs, let rhs): + return lhs.referencedTypes() + rhs.referencedTypes() + case .equality(let lhs, let rhs): + return lhs.referencedTypes() + rhs.referencedTypes() + case .inequality(let lhs, let rhs): + return lhs.referencedTypes() + rhs.referencedTypes() + case .not(let rhs): + return rhs.referencedTypes() + case .lessThan(let lhs, let rhs): + return lhs.referencedTypes() + rhs.referencedTypes() + case .lessThanEqual(let lhs, let rhs): + return lhs.referencedTypes() + rhs.referencedTypes() + case .greaterThan(let lhs, let rhs): + return lhs.referencedTypes() + rhs.referencedTypes() + case .greaterThanEqual(let lhs, let rhs): + return lhs.referencedTypes() + rhs.referencedTypes() + case .keyPath(let k): + return [type(of: k).rootType] + case .null: + return [] + case .lazy(let e): + return e().referencedTypes() + case .integer(_), .uinteger(_), .integer64(_), .uinteger64(_), .integer32(_), .uinteger32(_), .integer16(_), .uinteger16(_), .integer8(_), .uinteger8(_): + return [] + case .decimal(_), .float(_), .string(_), .blob(_), .sblob(_), .bool(_), .uuid(_), .date(_), .url(_): + return [] + case .in(let lhs, let exprs): + return lhs.referencedTypes() + exprs.flatMap { $0.referencedTypes() } + case .like(let lhs, _, _, _): + return lhs.referencedTypes() + } + } +} diff --git a/Sources/PerfectCRUD/Expression/In.swift b/Sources/PerfectCRUD/Expression/In.swift new file mode 100644 index 00000000..7ab57e91 --- /dev/null +++ b/Sources/PerfectCRUD/Expression/In.swift @@ -0,0 +1,47 @@ +// +// In.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-02-18. +// + +import Foundation + +// ~ IN +public func ~ (lhs: KeyPath, rhs: [String]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .string($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Double]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .decimal($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UUID]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uuid($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Date]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .date($0) })) +} +public func ~ (lhs: KeyPath, rhs: [String]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .string($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Double]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .decimal($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UUID]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uuid($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Date]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .date($0) })) +} +// !~ NOT IN +public func !~ (lhs: KeyPath, rhs: [String]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Double]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UUID]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Date]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} diff --git a/Sources/PerfectCRUD/Expression/InInts.swift b/Sources/PerfectCRUD/Expression/InInts.swift new file mode 100644 index 00000000..2ad64a24 --- /dev/null +++ b/Sources/PerfectCRUD/Expression/InInts.swift @@ -0,0 +1,131 @@ +// +// InInts.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-03-11. +// + +import Foundation + +// ~ IN +public func ~ (lhs: KeyPath, rhs: [Int]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int64]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer64($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int64]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer64($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt64]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger64($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt64]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger64($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int32]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer32($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int32]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer32($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt32]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger32($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt32]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger32($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int16]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer16($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int16]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer16($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt16]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger16($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt16]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger16($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer8($0) })) +} +public func ~ (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .integer8($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger8($0) })) +} +public func ~ (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return RealBooleanExpression(.in(lhs: .keyPath(lhs), rhs: rhs.map { .uinteger8($0) })) +} +// !~ NOT IN +public func !~ (lhs: KeyPath, rhs: [Int]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int64]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int64]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt64]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt64]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int32]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int32]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt32]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt32]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int16]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int16]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt16]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt16]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [Int8]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} +public func !~ (lhs: KeyPath, rhs: [UInt8]) -> CRUDBooleanExpression { + return !(lhs ~ rhs) +} diff --git a/Sources/PerfectCRUD/Expression/Like.swift b/Sources/PerfectCRUD/Expression/Like.swift new file mode 100644 index 00000000..6d808f59 --- /dev/null +++ b/Sources/PerfectCRUD/Expression/Like.swift @@ -0,0 +1,49 @@ +// +// Like.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-02-18. +// + +import Foundation + +// %=% LIKE +public func %=% (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.like(lhs: .keyPath(lhs), wild1: true, rhs, wild2: true)) +} +public func %=% (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.like(lhs: .keyPath(lhs), wild1: true, rhs, wild2: true)) +} +// *~ LIKE v% +public func =% (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.like(lhs: .keyPath(lhs), wild1: false, rhs, wild2: true)) +} +public func =% (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.like(lhs: .keyPath(lhs), wild1: false, rhs, wild2: true)) +} +// ~* LIKE %v +public func %= (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.like(lhs: .keyPath(lhs), wild1: true, rhs, wild2: false)) +} +public func %= (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return RealBooleanExpression(.like(lhs: .keyPath(lhs), wild1: true, rhs, wild2: false)) +} +// !~ NOT LIKE +public func %!=% (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return !(lhs %=% rhs) +} +public func %!=% (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return !(lhs %=% rhs) +} +public func !=% (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return !(lhs =% rhs) +} +public func !=% (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return !(lhs =% rhs) +} +public func %!= (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return !(lhs %= rhs) +} +public func %!= (lhs: KeyPath, rhs: String) -> CRUDBooleanExpression { + return !(lhs %= rhs) +} diff --git a/Sources/PerfectCRUD/Expression/Logical.swift b/Sources/PerfectCRUD/Expression/Logical.swift new file mode 100644 index 00000000..cb12fa6e --- /dev/null +++ b/Sources/PerfectCRUD/Expression/Logical.swift @@ -0,0 +1,21 @@ +// +// Logical.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-02-18. +// + +import Foundation + +// && +public func && (lhs: CRUDBooleanExpression, rhs: CRUDBooleanExpression) -> CRUDBooleanExpression { + return RealBooleanExpression(.and(lhs: lhs.crudExpression, rhs: rhs.crudExpression)) +} +// || +public func || (lhs: CRUDBooleanExpression, rhs: CRUDBooleanExpression) -> CRUDBooleanExpression { + return RealBooleanExpression(.or(lhs: lhs.crudExpression, rhs: rhs.crudExpression)) +} +// ! +public prefix func ! (rhs: CRUDBooleanExpression) -> CRUDBooleanExpression { + return RealBooleanExpression(.not(rhs: rhs.crudExpression)) +} diff --git a/Sources/PerfectCRUD/Insert.swift b/Sources/PerfectCRUD/Insert.swift new file mode 100644 index 00000000..7f95af3a --- /dev/null +++ b/Sources/PerfectCRUD/Insert.swift @@ -0,0 +1,102 @@ +// +// PerfectCRUDInsert.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-12-02. +// + +import Foundation + +public struct Insert: FromTableProtocol, CommandProtocol { + public typealias FromTableType = A + public typealias OverAllForm = OAF + public let fromTable: FromTableType + public let sqlGenState: SQLGenState + init(fromTable ft: FromTableType, instances: [OAF], includeKeys: [PartialKeyPath], excludeKeys: [PartialKeyPath]) throws { + fromTable = ft + let delegate = ft.databaseConfiguration.sqlGenDelegate + var state = SQLGenState(delegate: delegate) + state.command = .insert + try ft.setState(state: &state) + let td = state.tableData[0] + let kpDecoder = td.keyPathDecoder + guard let kpInstance = td.modelInstance else { + throw CRUDSQLGenError("Could not get model instance for key path decoder \(OAF.self)") + } + let includeNames: [String] + if includeKeys.isEmpty { + let columnDecoder = CRUDColumnNameDecoder() + _ = try OverAllForm.init(from: columnDecoder) + includeNames = columnDecoder.collectedKeys.map { $0.name } + } else { + includeNames = try includeKeys.map { + guard let n = try kpDecoder.getKeyPathName(kpInstance, keyPath: $0) else { + throw CRUDSQLGenError("Could not get key path name for \(OAF.self) \($0)") + } + return n + } + } + let excludeNames: [String] = try excludeKeys.map { + guard let n = try kpDecoder.getKeyPathName(kpInstance, keyPath: $0) else { + throw CRUDSQLGenError("Could not get key path name for \(OAF.self) \($0)") + } + return n + } + + let encoder = try CRUDBindingsEncoder(delegate: delegate) + try instances[0].encode(to: encoder) + + let bindings = try encoder.completedBindings(allKeys: includeNames, ignoreKeys: Set(excludeNames)) + let columnNames = try bindings.map { try delegate.quote(identifier: $0.column) } + let bindIdentifiers = bindings.map { $0.identifier } + + let nameQ = try delegate.quote(identifier: "\(OAF.CRUDTableName)") + let sqlStr: String + if columnNames.isEmpty { + sqlStr = "INSERT INTO \(nameQ) \(delegate.getEmptyInsertSnippet())" + } else { + sqlStr = "INSERT INTO \(nameQ) (\(columnNames.joined(separator: ", "))) VALUES (\(bindIdentifiers.joined(separator: ", ")))" + } + CRUDLogging.log(.query, sqlStr) + sqlGenState = state + let exeDelegate = try databaseConfiguration.sqlExeDelegate(forSQL: sqlStr) + try exeDelegate.bind(delegate.bindings) + _ = try exeDelegate.hasNext() + + for instance in instances[1...] { + let delegate = databaseConfiguration.sqlGenDelegate + let encoder = try CRUDBindingsEncoder(delegate: delegate) + try instance.encode(to: encoder) + _ = try encoder.completedBindings(allKeys: includeNames, ignoreKeys: Set(excludeNames)) + try exeDelegate.bind(delegate.bindings) + _ = try exeDelegate.hasNext() + } + } +} + +public extension Table { + @discardableResult + func insert(_ instances: [Form]) throws -> Insert { + return try .init(fromTable: self, instances: instances, includeKeys: [], excludeKeys: []) + } + @discardableResult + func insert(_ instance: Form) throws -> Insert { + return try .init(fromTable: self, instances: [instance], includeKeys: [], excludeKeys: []) + } + @discardableResult + func insert(_ instances: [Form], setKeys: KeyPath, _ rest: PartialKeyPath...) throws -> Insert { + return try .init(fromTable: self, instances: instances, includeKeys: [setKeys] + rest, excludeKeys: []) + } + @discardableResult + func insert(_ instance: Form, setKeys: KeyPath, _ rest: PartialKeyPath...) throws -> Insert { + return try .init(fromTable: self, instances: [instance], includeKeys: [setKeys] + rest, excludeKeys: []) + } + @discardableResult + func insert(_ instances: [Form], ignoreKeys: KeyPath, _ rest: PartialKeyPath...) throws -> Insert { + return try .init(fromTable: self, instances: instances, includeKeys: [], excludeKeys: [ignoreKeys] + rest) + } + @discardableResult + func insert(_ instance: Form, ignoreKeys: KeyPath, _ rest: PartialKeyPath...) throws -> Insert { + return try .init(fromTable: self, instances: [instance], includeKeys: [], excludeKeys: [ignoreKeys] + rest) + } +} diff --git a/Sources/PerfectCRUD/Join.swift b/Sources/PerfectCRUD/Join.swift new file mode 100644 index 00000000..b48d8b71 --- /dev/null +++ b/Sources/PerfectCRUD/Join.swift @@ -0,0 +1,205 @@ +// +// PerfectCRUDJoin.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2018-01-03. +// + +import Foundation + +let joinPivotIdColumnName = "_crud_pivot_id_" + +let joinWord = "LEFT JOIN" + +public struct Join: TableProtocol, FromTableProtocol, Joinable, Selectable, Whereable, Orderable, Limitable { + public typealias Form = B + public typealias FromTableType = A + public typealias ComparisonType = O + public typealias OverAllForm = OAF + public let fromTable: FromTableType + let to: KeyPath + let on: KeyPath + let equals: KeyPath + public func setState(state: inout SQLGenState) throws { + try fromTable.setState(state: &state) + try state.addTable(type: Form.self, joinData: .init(to: to, on: on, equals: equals, pivot: nil)) + } + public func setSQL(state: inout SQLGenState) throws { + let (orderings, limit) = state.consumeState() + try fromTable.setSQL(state: &state) + let delegate = state.delegate + guard let poppedTableData = state.popTableData() else { + throw CRUDSQLGenError("No tables specified.") + } + let myTable = poppedTableData.myTable + let firstTable = poppedTableData.firstTable + let joinTables = poppedTableData.remainingTables + let nameQ = try delegate.quote(identifier: Form.CRUDTableName) + let aliasQ = try delegate.quote(identifier: myTable.alias) + let fNameQ = try delegate.quote(identifier: firstTable.type.CRUDTableName) + let fAliasQ = try delegate.quote(identifier: firstTable.alias) + let lhsStr = try Expression.sqlSnippet(keyPath: on, tableData: firstTable, state: state) + let rhsStr = try Expression.sqlSnippet(keyPath: equals, tableData: myTable, state: state) + switch state.command { + case .count: + () // joins do nothing on .count except limit master # + case .select: + var sqlStr = + """ + SELECT DISTINCT \(aliasQ).* + FROM \(nameQ) AS \(aliasQ) + \(joinWord) \(fNameQ) AS \(fAliasQ) ON \(lhsStr) = \(rhsStr) + + """ + if let whereExpr = state.whereExpr { + let referencedTypes = whereExpr.referencedTypes() + for type in referencedTypes { + guard type != firstTable.type && type != Form.self else { + continue + } + guard let joinTable = joinTables.first(where: { type == $0.type }) else { + throw CRUDSQLGenError("Unknown type included in where clause \(type).") + } + guard let joinData = joinTable.joinData else { + throw CRUDSQLGenError("Join without a clause \(type).") + } + let nameQ = try delegate.quote(identifier: joinTable.type.CRUDTableName) + let aliasQ = try delegate.quote(identifier: joinTable.alias) + let lhsStr = try Expression.keyPath(joinData.on).sqlSnippet(state: state) + let rhsStr = try Expression.keyPath(joinData.equals).sqlSnippet(state: state) + sqlStr += "\(joinWord) \(nameQ) AS \(aliasQ) ON \(lhsStr) = \(rhsStr)\n" + } + sqlStr += "WHERE \(try whereExpr.sqlSnippet(state: state))\n" + } + if !orderings.isEmpty { + let m = try orderings.map { "\(try Expression.keyPath($0.key).sqlSnippet(state: state))\($0.desc ? " DESC" : "")" } + sqlStr += "ORDER BY \(m.joined(separator: ", "))\n" + } + if let (max, skip) = limit { + if max > 0 { + sqlStr += "LIMIT \(max)\n" + } + if skip > 0 { + sqlStr += "OFFSET \(skip)\n" + } + } + state.statements.append(.init(sql: sqlStr, bindings: delegate.bindings)) + state.delegate.bindings = [] + CRUDLogging.log(.query, sqlStr) + // ordering + case .insert, .update, .delete:() + // state.fromStr.append("\(myTable)") + case .unknown: + throw CRUDSQLGenError("SQL command was not set.") + } + } +} + +public struct JoinPivot: TableProtocol, FromTableProtocol, Joinable, Selectable, Whereable, Orderable, Limitable { + public typealias Form = MyForm + public typealias FromTableType = MasterTable + public typealias PivotTableType = With + public typealias ComparisonType = PivotCompType + public typealias ComparisonType2 = PivotCompType2 + public typealias OverAllForm = OAF + + public let fromTable: FromTableType + let to: KeyPath + let on: KeyPath + let equals: KeyPath + let and: KeyPath + let alsoEquals: KeyPath + + public func setState(state: inout SQLGenState) throws { + try fromTable.setState(state: &state) + try state.addTable(type: Form.self, joinData: .init(to: to, on: on, equals: equals, pivot: PivotTableType.self)) + try state.addTable(type: PivotTableType.self) + } + public func setSQL(state: inout SQLGenState) throws { + let (orderings, limit) = state.consumeState() + try fromTable.setSQL(state: &state) + let delegate = state.delegate + + guard let poppedTableData1 = state.popTableData(), + let poppedTableData2 = state.popTableData() else { + throw CRUDSQLGenError("No tables specified.") + } + let myTable = poppedTableData1.myTable + let firstTable = poppedTableData1.firstTable + let joinTables = poppedTableData1.remainingTables + let pivotTable = poppedTableData2.myTable + + let myNameQ = try delegate.quote(identifier: myTable.type.CRUDTableName) + let myAliasQ = try delegate.quote(identifier: myTable.alias) + + let firstNameQ = try delegate.quote(identifier: firstTable.type.CRUDTableName) + let firstAliasQ = try delegate.quote(identifier: firstTable.alias) + + let lhsStr = try Expression.sqlSnippet(keyPath: on, tableData: firstTable, state: state) + let rhsStr = try Expression.sqlSnippet(keyPath: equals, tableData: pivotTable, state: state) + + let pivotNameQ = try delegate.quote(identifier: pivotTable.type.CRUDTableName) + let pivotAliasQ = try delegate.quote(identifier: pivotTable.alias) + + let lhsStr2 = try Expression.sqlSnippet(keyPath: and, tableData: myTable, state: state) + let rhsStr2 = try Expression.sqlSnippet(keyPath: alsoEquals, tableData: pivotTable, state: state) + + let tempColumnNameQ = try delegate.quote(identifier: joinPivotIdColumnName) + + switch state.command { + case .count: + () // joins do nothing on .count except limit master # + case .select: + var sqlStr = + """ + SELECT DISTINCT \(myAliasQ).*, \(lhsStr) AS \(tempColumnNameQ) + FROM \(myNameQ) AS \(myAliasQ) + \(joinWord) \(pivotNameQ) AS \(pivotAliasQ) ON \(lhsStr2) = \(rhsStr2) + \(joinWord) \(firstNameQ) AS \(firstAliasQ) ON \(lhsStr) = \(rhsStr) + + """ + if let whereExpr = state.whereExpr { + let referencedTypes = whereExpr.referencedTypes() + for type in referencedTypes { + guard type != firstTable.type, + type != Form.self, + type != PivotTableType.self else { + continue + } + guard let joinTable = joinTables.first(where: { type == $0.type }) else { + throw CRUDSQLGenError("Unknown type included in where clause \(type).") + } + guard let joinData = joinTable.joinData else { + throw CRUDSQLGenError("Join without a clause \(type).") + } + let nameQ = try delegate.quote(identifier: joinTable.type.CRUDTableName) + let aliasQ = try delegate.quote(identifier: joinTable.alias) + let lhsStr = try Expression.keyPath(joinData.on).sqlSnippet(state: state) + let rhsStr = try Expression.keyPath(joinData.equals).sqlSnippet(state: state) + sqlStr += "\(joinWord) \(nameQ) AS \(aliasQ) ON \(lhsStr) = \(rhsStr)\n" + } + sqlStr += "WHERE \(try whereExpr.sqlSnippet(state: state))\n" + } + if !orderings.isEmpty { + let m = try orderings.map { "\(try Expression.keyPath($0.key).sqlSnippet(state: state))\($0.desc ? " DESC" : "")" } + sqlStr += "ORDER BY \(m.joined(separator: ", "))\n" + } + if let (max, skip) = limit { + if max > 0 { + sqlStr += "LIMIT \(max)\n" + } + if skip > 0 { + sqlStr += "OFFSET \(skip)\n" + } + } + state.statements.append(.init(sql: sqlStr, bindings: delegate.bindings)) + state.delegate.bindings = [] + CRUDLogging.log(.query, sqlStr) + // ordering + case .insert, .update, .delete:() + // state.fromStr.append("\(myTable)") + case .unknown: + throw CRUDSQLGenError("SQL command was not set.") + } + } +} diff --git a/Sources/PerfectCRUD/Logging.swift b/Sources/PerfectCRUD/Logging.swift new file mode 100644 index 00000000..6e20ffd2 --- /dev/null +++ b/Sources/PerfectCRUD/Logging.swift @@ -0,0 +1,166 @@ +// +// PerfectCRUDLogging.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-11-24. +// Copyright (C) 2017 PerfectlySoft, Inc. +// +// ===----------------------------------------------------------------------===// +// +// This source file is part of the Perfect.org open source project +// +// Copyright (c) 2015 - 2017 PerfectlySoft Inc. and the Perfect project authors +// Licensed under Apache License v2.0 +// +// See http://perfect.org/licensing.html for license information +// +// ===----------------------------------------------------------------------===// +// + +import Foundation +import Dispatch + +public struct CRUDSQLGenError: Error, CustomStringConvertible { + public let description: String + public init(_ msg: String) { + description = msg + CRUDLogging.log(.error, msg) + } +} +public struct CRUDSQLExeError: Error, CustomStringConvertible { + public let description: String + public init(_ msg: String) { + description = msg + CRUDLogging.log(.error, msg) + } +} + +public enum CRUDLogDestination { + case none + case console + case file(String) + case custom((CRUDLogEvent) -> ()) + + func handleEvent(_ event: CRUDLogEvent) { + switch self { + case .none: + () + case .console: + print("\(event)") + case .file(let name): + let fm = FileManager() + guard fm.isWritableFile(atPath: name) || fm.createFile(atPath: name, contents: nil, attributes: nil), + let fileHandle = FileHandle(forWritingAtPath: name), + let data = "\(event)\n".data(using: .utf8) else { + print("[ERR] Unable to open file at \"\(name)\" to log event \(event)") + return + } + defer { + fileHandle.closeFile() + } + fileHandle.seekToEndOfFile() + fileHandle.write(data) + case .custom(let code): + code(event) + } + } +} + +public enum CRUDLogEventType: CustomStringConvertible { + case info, warning, error, query + public var description: String { + switch self { + case .info: + return "INFO" + case .warning: + return "WARN" + case .error: + return "ERR" + case .query: + return "QUERY" + } + } +} + +public struct CRUDLogEvent: CustomStringConvertible { + public let time: Date + public let type: CRUDLogEventType + public let msg: String + public var description: String { + let formatter = DateFormatter() + formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss ZZ" + return "[\(formatter.string(from: time))] [\(type)] \(msg)" + } +} + +public struct CRUDLogging { + private static var _queryLogDestinations: [CRUDLogDestination] = [.console] + private static var _errorLogDestinations: [CRUDLogDestination] = [.console] + private static var pendingEvents: [CRUDLogEvent] = [] + private static var loggingQueue: DispatchQueue = { + let q = DispatchQueue(label: "CRUDLoggingQueue", qos: .background) + scheduleLogCheck(q) + return q + }() + private static func logCheckReschedulingInSerialQueue() { + logCheckInSerialQueue() + scheduleLogCheck(loggingQueue) + } + private static func logCheckInSerialQueue() { + guard !pendingEvents.isEmpty else { + return + } + let eventsToLog = pendingEvents + pendingEvents = [] + eventsToLog.forEach { + logEventInSerialQueue($0) + } + } + private static func logEventInSerialQueue(_ event: CRUDLogEvent) { + if case .query = event.type { + _queryLogDestinations.forEach { $0.handleEvent(event) } + } else { + _errorLogDestinations.forEach { $0.handleEvent(event) } + } + } + private static func scheduleLogCheck(_ queue: DispatchQueue) { + queue.asyncAfter(deadline: .now() + 0.5, execute: logCheckReschedulingInSerialQueue) + } +} + +public extension CRUDLogging { + static func flush() { + loggingQueue.sync { + logCheckInSerialQueue() + } + } + static var queryLogDestinations: [CRUDLogDestination] { + get { + return loggingQueue.sync { return _queryLogDestinations } + } + set { + loggingQueue.async { _queryLogDestinations = newValue } + } + } + static var errorLogDestinations: [CRUDLogDestination] { + get { + return loggingQueue.sync { return _errorLogDestinations } + } + set { + loggingQueue.async { _errorLogDestinations = newValue } + } + } + static func log(_ type: CRUDLogEventType, _ msg: String) { + let now = Date() + #if DEBUG || Xcode + loggingQueue.sync { + pendingEvents.append(.init(time: now, type: type, msg: msg)) + logCheckInSerialQueue() + } + #else + loggingQueue.async { + pendingEvents.append(.init(time: now, type: type, msg: msg)) + } + #endif + } +} diff --git a/Sources/PerfectCRUD/PerfectCRUD.swift b/Sources/PerfectCRUD/PerfectCRUD.swift new file mode 100644 index 00000000..1ffbc372 --- /dev/null +++ b/Sources/PerfectCRUD/PerfectCRUD.swift @@ -0,0 +1,434 @@ +// +// TestDeleteMe.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-11-26. +// + +import Foundation + +public typealias Expression = CRUDExpression +public typealias Bindings = [(String, Expression)] + +public protocol QueryItem { + associatedtype OverAllForm: Codable + func setState(state: inout SQLGenState) throws + func setSQL(state: inout SQLGenState) throws +} + +public protocol TableProtocol: QueryItem { + associatedtype Form: Codable + var databaseConfiguration: DatabaseConfigurationProtocol { get } +} + +public protocol FromTableProtocol { + associatedtype FromTableType: TableProtocol + var fromTable: FromTableType { get } +} + +public protocol CommandProtocol: QueryItem { + var sqlGenState: SQLGenState { get } +} + +public protocol SelectProtocol: Sequence, FromTableProtocol, CommandProtocol { + var fromTable: FromTableType { get } +} +// swiftlint:disable class_delegate_protocol +public protocol SQLGenDelegate { + var bindings: Bindings { get set } + func getBinding(for: Expression) throws -> String + func quote(identifier: String) throws -> String + func getCreateTableSQL(forTable: TableStructure, policy: TableCreatePolicy) throws -> [String] + func getCreateIndexSQL(forTable name: String, on columns: [String], unique: Bool) throws -> [String] + func getEmptyInsertSnippet() -> String // usually DEFAULT VALUES vs. VALUES () +} + +public extension SQLGenDelegate { + func getEmptyInsertSnippet() -> String { + return "DEFAULT VALUES" + } +} +// swiftlint:disable class_delegate_protocol +public protocol SQLExeDelegate { + func bind(_ bindings: Bindings, skip: Int) throws + func hasNext() throws -> Bool + func next() throws -> KeyedDecodingContainer? + func asyncExecute(completion: @escaping (SQLExeDelegate) -> ()) +} + +public protocol DatabaseConfigurationProtocol { + var sqlGenDelegate: SQLGenDelegate { get } + func sqlExeDelegate(forSQL: String) throws -> SQLExeDelegate + + init(url: String?, name: String?, host: String?, port: Int?, user: String?, pass: String?) throws +} + +public protocol DatabaseProtocol { + associatedtype Configuration: DatabaseConfigurationProtocol + var configuration: Configuration { get } + func table(_ form: T.Type) -> Table +} + +public protocol TableNameProvider { + static var tableName: String { get } +} + +public protocol Joinable: TableProtocol { + func join(_ to: KeyPath, on: KeyPath, equals: KeyPath) throws -> Join +} + +public protocol Selectable: TableProtocol { + func select() throws -> Select + func count() throws -> Int +} + +public protocol Whereable: TableProtocol { + func `where`(_ expr: CRUDBooleanExpression) -> Where +} + +public protocol Orderable: TableProtocol { + func order(by: PartialKeyPath

...) -> Ordering + func order(descending by: PartialKeyPath...) -> Ordering +} + +public protocol Limitable: TableProtocol { + func limit(_ max: Int, skip: Int) -> Limit +} +// swiftlint:disable line_length +public extension Joinable { + func join(_ to: KeyPath, on: KeyPath, equals: KeyPath) throws -> Join { + return .init(fromTable: self, to: to, on: on, equals: equals) + } + + func join(_ to: KeyPath, with: Pivot.Type, on: KeyPath, equals: KeyPath, and: KeyPath, is: KeyPath) throws -> JoinPivot { + return .init(fromTable: self, to: to, on: on, equals: equals, and: and, alsoEquals: `is`) + } +} + +public extension Selectable { + func select() throws -> Select { + return try .init(fromTable: self) + } + func count() throws -> Int { + var state = SQLGenState(delegate: databaseConfiguration.sqlGenDelegate) + state.command = .count + try setState(state: &state) + try setSQL(state: &state) + guard state.statements.count == 1 else { + throw CRUDSQLGenError("Too many statements for count().") + } + let stat = state.statements[0] + let exeDelegate = try databaseConfiguration.sqlExeDelegate(forSQL: stat.sql) + try exeDelegate.bind(stat.bindings) + guard try exeDelegate.hasNext(), + let container: KeyedDecodingContainer = try exeDelegate.next() else { + throw CRUDSQLGenError("No rows returned in count().") + } + return try container.decode(Int.self, forKey: ColumnKey(stringValue: "count")!) + } + func first() throws -> OverAllForm? { + var i = try select().makeIterator() + return try i.nextElement() + } +} + +public extension Selectable where Self: Limitable { + func first() throws -> OverAllForm? { + var i = try limit(1).select().makeIterator() + return try i.nextElement() + } +} + +public extension Whereable { + func `where`(_ expr: CRUDBooleanExpression) -> Where { + return .init(fromTable: self, expression: expr.crudExpression) + } +} +// swiftlint:disable line_length +public extension Orderable { + func order(by: PartialKeyPath...) -> Ordering { + return .init(fromTable: self, keys: by, descending: false) + } + func order(descending by: PartialKeyPath...) -> Ordering { + return .init(fromTable: self, keys: by, descending: true) + } + // !FIX! Swift 4.0.2 seems to have a problem with type inference for the above two funcs + // would not let \.name type references to be used + // this is an ugly work around + func order(by: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by], descending: false) + } + func order(by: KeyPath, _ thenBy: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by, thenBy], descending: false) + } + func order(by: KeyPath, _ thenBy: KeyPath, _ thenBy2: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by, thenBy, thenBy2], descending: false) + } + func order(by: KeyPath, _ thenBy: KeyPath, _ thenBy2: KeyPath, _ thenBy3: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by, thenBy, thenBy2, thenBy3], descending: false) + } + func order(by: KeyPath, _ thenBy: KeyPath, _ thenBy2: KeyPath, _ thenBy3: KeyPath, _ thenBy4: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by, thenBy, thenBy2, thenBy3, thenBy4], descending: false) + } + // desc + func order(descending by: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by], descending: true) + } + func order(descending by: KeyPath, _ thenBy: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by, thenBy], descending: true) + } + func order(descending by: KeyPath, _ thenBy: KeyPath, _ thenBy2: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by, thenBy, thenBy2], descending: true) + } + func order(descending by: KeyPath, _ thenBy: KeyPath, _ thenBy2: KeyPath, _ thenBy3: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by, thenBy, thenBy2, thenBy3], descending: true) + } + func order(descending by: KeyPath, _ thenBy: KeyPath, _ thenBy2: KeyPath, _ thenBy3: KeyPath, _ thenBy4: KeyPath) -> Ordering { + return .init(fromTable: self, keys: [by, thenBy, thenBy2, thenBy3, thenBy4], descending: true) + } +} + +public extension Limitable { + func limit(_ max: Int = 0, skip: Int = 0) -> Limit { + return .init(fromTable: self, max: max, skip: skip) + } + func limit(_ range: Range) -> Limit { + return limit(range.count, skip: range.lowerBound) + } + func limit(_ range: ClosedRange) -> Limit { + return limit(range.count, skip: range.lowerBound) + } + func limit(_ range: PartialRangeFrom) -> Limit { + return limit(skip: range.lowerBound) + } + func limit(_ range: PartialRangeThrough) -> Limit { + return limit(range.upperBound + 1) + } + func limit(_ range: PartialRangeUpTo) -> Limit { + return limit(range.upperBound) + } +} + +extension FromTableProtocol { + public var databaseConfiguration: DatabaseConfigurationProtocol { return fromTable.databaseConfiguration } +} + +extension CommandProtocol { + public func setState(state: inout SQLGenState) throws {} + public func setSQL(state: inout SQLGenState) throws {} +} + +public extension SQLExeDelegate { + func bind(_ bindings: Bindings) throws { return try bind(bindings, skip: 0) } +} + +public extension Decodable { + static var CRUDTableName: String { + if let p = self as? TableNameProvider.Type { + return p.tableName + } + return "\(Self.self)" + } +} + +struct PivotContainer { + let instance: Codable + let keys: [Codable] +} + +struct SQLTopExeDelegate: SQLExeDelegate { + func asyncExecute(completion: @escaping (SQLExeDelegate) -> ()) { + // place holder + } + + let genState: SQLGenState + let master: (table: SQLGenState.TableData, delegate: SQLExeDelegate) + let subObjects: [String:(onKeyName: String, onKey: AnyKeyPath, equalsKey: AnyKeyPath, objects: [Any])] + init(genState state: SQLGenState, configurator: DatabaseConfigurationProtocol) throws { + genState = state + let delegates: [(table: SQLGenState.TableData, delegate: SQLExeDelegate)] = try zip(state.tableData, state.statements).map { + let sd = try configurator.sqlExeDelegate(forSQL: $0.1.sql) + try sd.bind($0.1.bindings) + return ($0.0, sd) + } + guard !delegates.isEmpty else { + throw CRUDSQLExeError("No tables in query.") + } + master = delegates[0] + guard let modelInstance = master.table.modelInstance else { + throw CRUDSQLExeError("No model instance for type \(master.table.type).") + } + let joins = delegates[1...] + let keyPathDecoder = master.table.keyPathDecoder + subObjects = Dictionary(uniqueKeysWithValues: try joins.map { + let (joinTable, joinDelegate) = $0 + guard let joinData = joinTable.joinData, + let keyStr = try keyPathDecoder.getKeyPathName(modelInstance, keyPath: joinData.to), + let onKeyStr = try keyPathDecoder.getKeyPathName(modelInstance, keyPath: joinData.on) else { + throw CRUDSQLExeError("No join data on \(joinTable.type)") + } + var ary: [Any] = [] + let joinTableType = joinTable.type + if nil != joinData.pivot { + guard let onType = type(of: joinData.on).valueType as? Codable.Type else { + throw CRUDSQLExeError("Invalid join comparison type \(joinData.on).") + } + while try joinDelegate.hasNext() { + let decoder = CRUDPivotRowDecoder(delegate: joinDelegate, pivotOn: onType) + let instance = try joinTableType.init(from: decoder) + let keys = decoder.orderedKeys + ary.append(PivotContainer(instance: instance, keys: keys)) + } + } else { + while try joinDelegate.hasNext() { + let decoder = CRUDRowDecoder(delegate: joinDelegate) + ary.append(try joinTableType.init(from: decoder)) + } + } + return (keyStr, (onKeyStr, joinData.on, joinData.equals, ary)) + }) + } + func bind(_ bindings: Bindings, skip: Int) throws { + try master.delegate.bind(bindings, skip: skip) + } + func hasNext() throws -> Bool { + return try master.delegate.hasNext() + } + func next() throws -> KeyedDecodingContainer? where A: CodingKey { + guard let k: KeyedDecodingContainer = try master.delegate.next() else { + return nil + } + return KeyedDecodingContainer(SQLTopRowReader(exeDelegate: self, subRowReader: k)) + } +} + +public struct SQLGenState { + public enum Command { + case select, insert, update, delete, unknown + case count + } + public struct TableData { + public let type: Codable.Type + public let alias: String + public let modelInstance: Codable? + public let keyPathDecoder: CRUDKeyPathsDecoder + public let joinData: PropertyJoinData? + } + public struct PropertyJoinData { + public let to: AnyKeyPath + public let on: AnyKeyPath + public let equals: AnyKeyPath + public let pivot: Codable.Type? + } + public struct Statement { + public let sql: String + public let bindings: Bindings + } + struct MyTableData { + let firstTable: TableData + let myTable: TableData + let remainingTables: [TableData] + } + typealias Ordering = (key: AnyKeyPath, desc: Bool) + var delegate: SQLGenDelegate + var aliasCounter = 0 + public var tableData: [TableData] = [] + var tablePopCount = 0 + public var command: Command = .unknown + var whereExpr: Expression? + public var statements: [Statement] = [] // statements count must match tableData count for exe to succeed + var accumulatedOrderings: [Ordering] = [] + var currentLimit: (max: Int, skip: Int)? + public var bindingsEncoder: CRUDBindingsEncoder? + public var columnFilters: (include: [String], exclude: [String]) = ([], []) + public init(delegate d: SQLGenDelegate) { + delegate = d + } + mutating func consumeState() -> ([Ordering], (max: Int, skip: Int)?) { + defer { + accumulatedOrderings = [] + currentLimit = nil + } + return (accumulatedOrderings, currentLimit) + } + mutating func addTable(type: A.Type, joinData: PropertyJoinData? = nil) throws { + let decoder = CRUDKeyPathsDecoder() + let model = try A(from: decoder) + tableData.append(.init(type: type, + alias: nextAlias(), + modelInstance: model, + keyPathDecoder: decoder, + joinData: joinData)) + } + mutating func getAlias(type: A.Type) -> String? { + return tableData.first { $0.type == type }?.alias + } + func getTableData(type: Any.Type) -> TableData? { + return tableData.first { $0.type == type } + } + mutating func nextAlias() -> String { + defer { aliasCounter += 1 } + return "t\(aliasCounter)" + } + func getTableName(type: A.Type) -> String { + return type.CRUDTableName + } + mutating func getKeyName(type: A.Type, key: PartialKeyPath) throws -> String? { + guard let td = getTableData(type: type), + let instance = td.modelInstance as? A, + let name = try td.keyPathDecoder.getKeyPathName(instance, keyPath: key) else { + return nil + } + return name + } + mutating func popTableData() -> MyTableData? { + guard !tableData.isEmpty else { + return nil + } + let myTableIndex = tablePopCount + tablePopCount += 1 + return MyTableData(firstTable: tableData[0], + myTable: tableData[myTableIndex], + remainingTables: myTableIndex == 0 ? Array(tableData[1...]) : Array(tableData[1.. String { + let dateFormatter = DateFormatter() + dateFormatter.locale = Locale(identifier: "en_US_POSIX") + dateFormatter.timeZone = TimeZone(abbreviation: "GMT") + dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS" + let ret = dateFormatter.string(from: self) + "Z" + return ret + } + + init?(fromISO8601 string: String) { + let dateFormatter = DateFormatter() + dateFormatter.locale = Locale(identifier: "en_US_POSIX") + dateFormatter.timeZone = TimeZone.current + let validFormats = [ + "yyyy-MM-dd'T'HH:mm:ss.SSSZ", + "yyyy-MM-dd HH:mm:ss.SSSx", + "yyyy-MM-dd'T'HH:mm:ssZ", + "yyyy-MM-dd HH:mm:ssx"] + for fmt in validFormats { + dateFormatter.dateFormat = fmt + if let slf = dateFormatter.date(from: string) { + self = slf + return + } + } + return nil + } +} + +#if swift(>=4.1) +#else +// Added for Swift 4.0/4.1 compat +extension Collection { + func compactMap(_ transform: (Element) throws -> ElementOfResult?) rethrows -> [ElementOfResult] { + return try flatMap(transform) + } +} +#endif diff --git a/Sources/PerfectCRUD/Select.swift b/Sources/PerfectCRUD/Select.swift new file mode 100644 index 00000000..c6f97126 --- /dev/null +++ b/Sources/PerfectCRUD/Select.swift @@ -0,0 +1,105 @@ +// +// PerfectCRUDSelect.swift +// PerfectCRUD +// +// Created by Kyle Jessup on 2017-12-02. +// + +import Foundation + +public struct SelectIterator: IteratorProtocol { + public typealias Element = A.OverAllForm + let select: A? + let exeDelegate: SQLExeDelegate? + init(select s: A) throws { + select = s + exeDelegate = try SQLTopExeDelegate(genState: s.sqlGenState, configurator: s.fromTable.databaseConfiguration) + } + init() { + select = nil + exeDelegate = nil + } + public mutating func next() -> Element? { + guard let delegate = exeDelegate else { + return nil + } + do { + if try delegate.hasNext() { + let rowDecoder: CRUDRowDecoder = CRUDRowDecoder(delegate: delegate) + return try Element(from: rowDecoder) + } + } catch { + CRUDLogging.log(.error, "Error thrown in SelectIterator.next(). Caught: \(error)") + } + return nil + } + public mutating func nextElement() throws -> Element? { + guard let delegate = exeDelegate else { + return nil + } + if try delegate.hasNext() { + let rowDecoder: CRUDRowDecoder = CRUDRowDecoder(delegate: delegate) + return try Element(from: rowDecoder) + } + return nil + } +} + +public struct Select: SelectProtocol { + public typealias Iterator = SelectIterator + +
+ + +
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+ +
+ +
+

Note: This page will expire in {{ minutes }} minutes.

+{{ > inc/footer }} diff --git a/templates/pages/inc/footer.mustache b/templates/pages/inc/footer.mustache new file mode 100644 index 00000000..0f7d808e --- /dev/null +++ b/templates/pages/inc/footer.mustache @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/templates/pages/inc/header.mustache b/templates/pages/inc/header.mustache new file mode 100644 index 00000000..85f52106 --- /dev/null +++ b/templates/pages/inc/header.mustache @@ -0,0 +1,55 @@ + + + + + + + + + + + Welcome! + + +
+ diff --git a/templates/pages/index.mustache b/templates/pages/index.mustache new file mode 100644 index 00000000..af305b0e --- /dev/null +++ b/templates/pages/index.mustache @@ -0,0 +1,4 @@ +{{ > inc/header }} +

Welcome!

+ +{{ > inc/footer }} diff --git a/webroot/favicon.ico b/webroot/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..44aa32e12e807a8ee8a28da5609605dfe2a6de44 GIT binary patch literal 34494 zcmeHw2XK_v)%GUNALq|xl1wI(@nkZNC*$3f029EDo!E{6(Tk{}SJO>5-SiH|7-Nhv zy@)QFKm`y21PBlyBoHd7_lDX^T5Z!x=YP)K_b#ht)evBR-|wBddUsdvd+&K}IrrXk zo^w~F`i1KMsQ&mz6|QfoCjCmK8mLmK-gv|IdHw%YsjlF=x8AaSK8E``|6ZkP)k^uS zR;h~LRH@pvvwe2+P^q?cRH@vM2W~}gwuWZrWeAQrkU; zG(EFP(<_s-gR)6GtBkY@^rT&^C%5H#TH(>aG)^un_}Gx2-| zY5S&=c4Q7|=a(zbSCHGP3R)as-s$*!OroWgwo{I^Rqt$?xi*)+J(x%B#_;oLr0t(V z+KKr!o_AkYLD!P4U1c7#*OYjxJD}XoS@gl63_5fwmQqsEX#24gYCArOv;z}K`*|Vc zx0Ua{&OoD%nyyIP@Ab+pRCmb2^BJV+3YmMR((JVlC@$_XML&w6EeE5i?UZfhplz}z_<&!>^5M+)#K)10-pDLCi?T@SfJcf#({*soF{ zLmBb&?q3-wp`faTuDt4x>W-*$4?Nom&vwPLJ(9`2PaFR_tvvqL5~9&Z9kNGbk%7n{*{5l$(=HDalC`8~up(o=>9Q zTT5uvz9J$2nB%4(S^x3r))sEVN-b`qN@>id3YxgJg2rqqqY>ZgXz=D@>h}%mehK%V zr}ck3&FUea=j)EMrg@qXI?{|OCCx-R z$CX*@dVbwS^TsON>-@a@9G78jIeU-c(0g;ri)Hz(m+19V4jWJ3Pq%(3@2l_1WfYWF zy^&v9^;fHl@$&R}mCE#Yl`8FZq}Noc5Txb5aGm&ne2)(I@-u)f^bAy$3hGGcFPBON zUp_6*wZ3`T|4+}e{^Nk3e(L-KhP`9987_?8ZU~xn*m!8iRr9>q9BWH%zvq!5Cdtxj z%+jJjjVHzs>z=`R=r`y)+;8Th&#~@Wq$jWKhOirT=s)MOS)T8YlrMDek!#V|bz&B2 z`#>*_faYsxSOm&p8^SFMF&?(Tz?|Gq&9>`njoU^Q=;F0x z8nGDj#(*Spx-VoIl^t4n;PD-R0%$uBVB`NNTTo7^Sw$3=luMDZ>2y0XiGpuGrU6?DT#m0n-o{&w=g=k7q<1Ei85&wY?kg&+UtKbXwbZ{G*7jo$7y}<>KGkK;vex&xsI2PGzG0T(YfqUr&D?J|HsgTNXT=%Q z)?;Co30cKeZ`SwxEBXHotP@qsR94mBRXWulkX~1%A%&=3Q_?R~%dv`bOi%y!nz)yr z;b%Dy&Wn&I%g+0~w~*Q)@jkM)*DJvZd0u2WSjYb5UQ*@9m!c~BTzpvB=XOG6yUe1h zx17iRi!3uHrLyI!U8S2nCgdk+hdd$8bm$J&8?%tGuG7xb(|=a!^XB>(_uojcc6?E? zBxY2)jaydiujz?-L|Id6dt*)<4ISuIzS|eJwWW4R1@+!$hzL!pxu|;ane?dDb^ucF)txwR)Ga+0+dCfGr0L zY0dV0`llCU5Nm4S?t^mWy4nkC-*H$kI`ltV``hZD@pJjLt+AyXv)AhO+t%8s`%c;P zj%OCF{UMuHY|SRWD^Dmnt$<9snrma+aKlfx*uzE z?I5Jt7!!4r&uh5g1ZyveSzdP>)z4G6L)mgKAj(I5V?UtjmO<@CrO@FMH^n+VGb3Hd z^59VtE!~<(t%vd60BhYr*cL0PuGyL{2?=nLZ0pwfV&gQ7W)M*AM48= zY1ABbzIek8v1VjD4DTCw&ByEe#oxtJ>yfZY@!nx{3b`#se_Y|*{hd278O>sD~7G_aQCW z8bfVHKPI<{8AAW?_QAtb5_=IYAJ`rCJKAn2n{9YKlWlvRUP<)s;5a&b@F1Nz=|chM&eEle=jj^uCM?f` z$Owu}$f7Q@AjA9um-tUVsvIrxCuUfi@wn4)`R!3Q?F zMMi{ER%QmVZGh{U#{uu{7`MQVJzda+Kp|5U-X~+6`rJ2AE0oLSfAF25kjI>3`TP7# z)71m8zvx>)UQ;sYhl3gPFe+K-8{UVqy*Du-o{Ec#sHmur^7C?q47~5-@8e>k#Tevq zcr`4BKHZg1UkBvT<$KBWxexZ>LjT*!pW|mb4g%eJ=#KDJ-59yoO+o<3MpTBrUCO|^D( zE}uUy*;%no>_vxQk2t)PT2CycZ%&)&RH%h~ZkXwCh=KNB($lUBrL--en7%z*KpW5G z)4CJ6wCZ>^%|Dn;EtX(CScm@azu$PbwzVPG!MkHh3)M>b8rZMJes3)Hs}qnWVV%Ky zrl}}nI#M0$KUec#vo8&FFT?t=E9~++|C_KWyrlBi2b(v@a_YK%eayI0GaP;K1>&D@ z%;fJl=hRg`x6j7okYSXv-)>_4PdaAut;;@In=EHN?0KLnZ<4BVg(Z84+V z92R$;3CZ9|^@ z3El&d@Jf4~X!$Ro1y#$eDpgyPO7(Z7Kj@IsRI1mN^je5YRcFF|uPOJw&d+iloEPWG zd5bc1C`);o*_dg}P(1UO6^Q)LXa%oXe%YnIi&A1ZV9Lzr9&ym;;q}Y(z7T~_1 z-0HcxB4R_JX>C-dwM}hv{>#P~l~mbg%KDOH?tS1ll=dU`OZG+j47QV6}t#XOU(6{c`H6l4F`qkeh9eoY)WF4T*j6!uIGWKV%j* zNR}V6v;1C2)1Z?STXaL^XWyvDRzpgT?)lqc{Z9CSh0PN3!^dA!e#mW?AN^g_zmy*` zvmLXaV#fqmN;?bwdA6lG=^r_MZT*H{07Lk14TwIpk2DPMipRo|CwRC_@74s3H}`N8k&l1?g z77d!6OZiW9bT6uqCa%aPH*vApZcQN%=MAuZGEQpsqWOk1f{fU)Lvl zHtfaCy5yOJy;{hRI*0ts`D45BfEihI??Dc2I}E$P*Ey7zUr2@Um4`*-(!`aSfV`VFEqL&l7eZ=HZ3j%LI-za%0*1p}tvm$$=3(71-*A0LNUcF|dAU zjQm}88Ds0>#PRy^Uw!lQ)a}_`&hjh#8Mc`V`O()QKikc<-81Nmjfr&k&Rt;}%gN5B zY}k#Y{p?y;3QbrEdo|ne9c=l`vk~_65x}<)^Ru++FlSJ)YqS2B`p4G)75gT*l;9J# ztE~;L-7|Lb9u&_RK9}`I%pYx)=42dY66! z;k$r67knd4&va@HAI(==uLzEdqwGnrAF{2MZFrZi#nSjykEz*U*o_Aw!JptZ1U`ky z82gQozx{SYT5W6YUgHbG)omfSkRP(!<%jIdxwXp=+1d6lTX2g)u7-$u zXCDa59uL{s2Fi9=wt-%}8buRU$5AuL&honrfluP|Ck?KDw~ZB)rF)jAfWH5$W}U!y z6Y|@*SAr`nd=`*h$Pc-}8y4JOyZo>z!+*h?EN!n8>Nqxv`~q(Y+b#QW*pI@zT9(~0 z1%*V>#I>>1Y#8L{w4k^_{hw{z!3mXi8@udF8M)TCgs+7;%919(+4`(KWx55_}&_E9Z?eHebB zy2dZdzyF?Prj%P=BV#S^JIb$N?wgPwbuWB2Qhw-naIb~$M)K9{@6n*!;`!2@&}eyDT4 zrzsG=Aoe|63BDx!LAT%&WBH>VJfIxR8`m&zyvrCSr$c`1lbM^xz5(W-D;z!MqI3PP z3N~+%a?9(jhn99?+_JB#9TNMin7=1{R*V6%3;7|tkRN@8eOGq>6=aA1isf$u-E#Wm zDLQmupYWsk`JSQk0e-@l#(oy|;jll=##fIJx|VhC<**EDJvNryW?`*WxBQ!>-17P` zq4GVoXOYdsSiS?D>l-`6s9*cJPqOjKb|K_@7wUk?4v!7J`P2EpN zYUXB0f1Rj*$S&k(znPQ#!gmMRd!pWj|1go-j*g~1-j@(haE81g|5^AE*^hZKFhFo2 zr9X}5yZiU<68qGcyU4nU{arlo`Gus?KY2_qFLl{}4&Jv+m2%4~`@P;7tkVnLqzCGr z{f!=wUHTk5vHa*S;8NP^A96!}Eqsq34vVK5EAP|3!@+_N>T~ok9roT2d4q(EJYLxk z%e+dCv515h@>M`Akh^La`A~G5c!v9*T(+M9iW690Q5$jRr7|TAy z>o~`?L|FJE8n_i)Z)N@Fz7qDtZ6(xs3&yPr{pt2q1x4jp+c?VX{C?{R<3cGv`;65? z;VWg1?+7HtZ`cQO(&@)sjctMy254w(DwB!9cvWpwI>g~|-oq|;XuxU7_4Qb}0_ zCQ8n(p!oDMicTp3Z@ZAfqVwtI!(0l9$fiqoGAQ6y8lAh5N~c4TX}f<4wSjJI?EWht zwz8kIyskcPJ!xFvN`6`YnlbQMv+r^|5@M+A{zHzXl0NJP+MgR*|6cozVRh{t9dQ`V z)xYU9vnY?zpJB{C0DgT%wrog87Hr99>HfT5oz(N1KD*5}t_E~Cdn!k+4%xcEKF^`gW@e0Oo z|J}yBC5GxhHKd<3m0F_m5Y!Yu>+?pp>2MOF5? z4^9qZoc~ha`s>G*|L5`>&5hwIV?K@3HAIk>sG7+|_&<}4_zLpT>wFCXA&IZc!7t(~ zct-pOx8nij+E#`5DZFsSFAO`Z!H)1P24qY=(`s%D{^`fK3?X$fNhh`r%9GZ97xOjnEW+Yy)t&ubXxb<7<2oFx}# zzMk4F)$7LYG5GJhVV;^@T=ln~Do$s)5;7~@mhLFq(q>qGp^d-C=URX#fwPG;gY!wm zp*8@2O+HGwb=WRLu>ZqKub*nac${9@?6b8xA7Hi$?w@1)tKk1Bbubb!e~rbj#0c^k z9Ufm-B>3F3jQpw8gHB)d`=#5;wzzrb+0J>9+($eA5xDL6VLN9I;W+R_>goSA+TQ`c zn{rNx=l6z)dssU=_rF*9`TBjc$HyZIG6ZkZ&fNnqh_N$w(wRSrIAp=0><7-(WY}mO zd7w_?zdroTi-29)x;oIbv9a;WO|2v5|84RvU#jhvXSMS#Yv5O~3;yC${;MqxTH#?1 z!1vQ(>y4xa4sT!Pxj5 za{}`?n}DDF>K}exkrSC|eXpr)Ti5gDhN|BVpIdZ6(;3+9_|exHyB$Bby@K72U%}2C zP>EggSVw_R`~vWE%<8)v47%|2y5q&_!dKV-n6Eo}L2;nqybAolEO@Vs9hmLhS7-dd zF8RAP@Pp&TJlOt7<1r^RvHeBN?ivHVyU|bCCS$PhDJc~f$=d-k?AP(JO{nHTrC&$0wm2k{H@Uw66-`^PW(r~^;UG3SJ|Ls1h zpK9Z*qTe&;nXwD}z%F^u0za@ja);~158Qkn0w+Er;B$pbjP+kr@H02XbC)p!=My$L z#w#k`(#oCBD-)bu#t-bA9Pm$Eo=@E;;eXu~{C4g!x4+~cJ93bLmCs_3Jmmi1jxd*Z zDDIhqvjAQIe)f$o2{dnQOglT@%QnbvV+$VGIKNLh%kI#1?%dws{&M@fW1c^Ixmctg zlTkNz{NQWY@dL9XhuMxFxFvq(0guW8ekVS*i}lYlyhw-sZ|5d~-+Uwa`Oj3@eoQ}0 zV6VY>=JwA9UpR;6f0aY;_UG}RMa{9syBJzbrMgn`4KAb}Q}8{oYdnEl@}C8Mw7Wcu z!_I@|_6K%OTnFRxn%w^dHv;j)U3M5AbNr)o+t&BFNLTfzRz35IZTKbU*oIy5raO#= z5Bo+A{ct#kJU-2$mN;YP%IzY-mncHq`RPk}ZG3BI&NbRq@MbaA!5eRZ_?jI@bHJ;}rIY7# zXw(;(bp39D;9D?XfjJkaE@q=1c>HtQ1G6h0xdWHnjk)B5a8BJUtdSRDU))6eAAV=Z zX^bu`uc-cAn_l_FHTdRs&N=W)&N=XN+=8ZCCQVuf-g$BsF|X&^t$6TsvZ>%nzQR8T z?+2exUdSNN>8|jjy+!}W6`W&%pU+JkivBPkb3zmGGe7Z21331wPaFv_j8nHmyW9Ed zlCxg3?d5qhlK0(iR0f^DoFKSM%pqf*5ObcGN9o96_X$iT&l#u(!NUh;$zxZ}rIB2A z!Dkz9}h^PUNgZlwByHn5sP5s@-u$Hho1l) z0zQ0G@H0m#Cb#}L^W4I!H#8o()~EOtzQ3Jw4%{+k!3n>X`TyYl^Vv5;X2p`9|0ThV zWS$jcXWpB{&foDlAI#x9>X$&hXQ97)F@9jS#{$^!yMbG;orW`Gx$U2`{kac(bG?4P zhtGNAXb~&GXB#=j3)H}mc4zE%-aT}ih@H0pKW@_zmK1NgZZ?qk7zAwjW@HxEg9pW_veqiTwu4K%H zh;Q_E%ygp5a)_{-2a-eOvtr`o6&L81I3$uPx@oA@0M5AGmuk zb{l@Jz|VDnc@ATtS-&J&yy+g=J4TFo(e6qdi{$?@e>nmia*hpQE-okLlJaP8-|-hN>I#2zc6#JgzF2LyI|%m}wX+M98UgmxEkBeMM^ zex>c5@N*0ar?uZ*5p%;uoKeg%41s>caV@JFO$NLEUe4ew2IRSPVGsAUYk2_)P z=;Mf+;be>5K%0yHk9Oy_cZfl0-amnM?mR#zjvW!_a`BmD92dc{C|n;L4y3B+8p?8@jEj9h1(w3l^7oG`|Hs6j~_WC>VVI~<1^s`&T%XZVtFng z9s}_i*YKMae75%Oo3?l)8B@ah3tmfcOzUo6@c2id4)7ZtZs4d(`&V81uP*#SVV0ii zo`p8-HShyF%lMjKjMG1BL1f){?>?r^FJ3LV#vJr?G#w1&%x5bu{lOegN-Z)WH<=2WM`+3;jRF#}w$??(*}U=*kb( zeQ~B8+xP^2w7ZPg@=);GW1dhC_P8PL|7dq^eM{)sepQKabO9DlZd z&n^)M<;QVoz|XNnwy_W0hj<*0rITY{;^+C0*9*LM5`6*jUElen*y>ZD~{1M{^cIEs<{ymmHSOe|x zz94ixpMSq^_f91a%wg;YU8E3>WrOa!6?)x1_IXa^m?YK%9FN4YDvo{O>%;iXmys9? zi)_EIBJDqH{}6MZGXJl?TKk!9>{D$%P-hUaGCdHh)DCSf;;p#t73}tyF~_(i1wYPR z6tP!I{1s#GF)4w{iRxkA03+;&b)+_iA|T%Xlot z9C;sSL?RxC#{<_3>jPddIQE702M|yFDb@!o5U0YiO)lCWc7O@8y^R9F=&jFV{Uja$om1_ z2l4u!*E`(jdER#%`;3*_obld-PT>5we{kK^=nL3WY(JAueO6+ATnl~Z0{{KYx_!or zf2i2X_%&WU4hpdbM%&xt)wmBZex>b!Un}D7lJOfDi8OD0EcpgRB6i<)&MLPd_hrV* z^BceCam#v3*aCo`$1v{)L_E2&7G|70-nrd5cI@fce}H-k5%UGFldfLAWQ)_nxZrqV z&f8$9ptu|(b=m%G`?vhYV5sj59{*5tKRf<`sDtj%g?9YFuEe}?%-+9XznQr@iB1JP z#@rkw^z;3D_k_OYzRPXI@o(IwjFatQ9KXc2F^)@R9nSk<*5_g`$a^95gPQxG2V&fF z-{<{6*sV}8cd(x1wr3q6pW(AUYsAJmwg2#=#w)J+yyJH`qvZGQ19c|R{)~SBpK;3L z--f*<=J!cU(#Xdzl@byVgBWj%e`DEL9&R)4myDU)j@wzME3wCK@j0X%gC^qu?PCCa zK<j>C9N+IdA5Yr?GbuVDgHkbexZYR?B&BB1+|y36bx!zqg;{1fVy*4{_%(W8 zJATA_xp@`P==s@n*f)n#(`@l)+;%elkM}U#XIV$vbXB;BQ{>n+KL50|RA;k^BZiRe z!6FV)jsfJueS>X5VhnIB9`bX<%NK~Ay38-4 zo{I{p*ODhRe$x}gxD}JdVj+v!Y>PkC>qYz?{~j2hLo02Q-2Y{~AI?~<5wpd=9iqhDybE625B?^?nUW%Q z(Q37dI*{>;Itr{Qg-}?Z4;aD*M!h+4+Ba{Y+Eq z!{2gzDQ)mEQ3+xm9bZ*dRU&@VY&Jn3+hR~ThLhuHi!cUkdJuMTS7QL7uRZo^pDZb(j~18GM>yBw1H6B4Q5m(ynKdn8=jZg! zqH=1Et2^8Mo9zFoAiwBJFX#4c$YzUv5X)6 z4E!GEeNF)u#~9Kk^4}V2{~O|M40+zTDSmF`Dt+MpRQ&IJWiUO?t7_Jewyy1-ESw+F zMmgiUHvRWgZT}rNEpuwa)tK*t?pV5OhLl?WC*dD=%yf=`=bX9-G??8U&ch55L zAmSi*2Ak*XylkF_-w~L8;*Mo>NNi>2q&(}}IM4T2&y)Yp&%Bse)t~F}|EqdLbGv+* z{%-pkhY#>e9Mpho8Xwev7fu%V1z&N%08Vn?^Bh#Fw&FGwPITb&9Qfn{zFj;J!dDzw zAg*|DIe$jZ;$pup6WJg`aZUmSlq>&M4ZrwzZ|b`8Z`<(ed9TmpFUxh3 zhkrMRU-H^k!6UEB6uk1P)C1}xgdf8-jjyODaYaSTdK4L>US&Otj0mp~r5$jiXcydw P+wfX$Yd7(})<6FbXh4|G literal 0 HcmV?d00001 diff --git a/webroot/img/logo.svg b/webroot/img/logo.svg new file mode 100644 index 00000000..a43d8937 --- /dev/null +++ b/webroot/img/logo.svg @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 3d20052bfb9fd016840865578352139d8bbf660d Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Mon, 4 Jul 2022 10:27:48 -0400 Subject: [PATCH 30/48] dev snapshot --- templates/pages/inc/footer.mustache | 1 + templates/pages/inc/header.mustache | 25 +++++++++++++++++++++++-- webroot/js/api.js | 16 ++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 webroot/js/api.js diff --git a/templates/pages/inc/footer.mustache b/templates/pages/inc/footer.mustache index 0f7d808e..56e17a19 100644 --- a/templates/pages/inc/footer.mustache +++ b/templates/pages/inc/footer.mustache @@ -1,3 +1,4 @@
+ \ No newline at end of file diff --git a/templates/pages/inc/header.mustache b/templates/pages/inc/header.mustache index 85f52106..9a4e7c2a 100644 --- a/templates/pages/inc/header.mustache +++ b/templates/pages/inc/header.mustache @@ -43,8 +43,8 @@ @@ -62,7 +62,7 @@ diff --git a/webroot/js/api.js b/webroot/js/api.js index 35210db5..8d843dac 100644 --- a/webroot/js/api.js +++ b/webroot/js/api.js @@ -3,47 +3,52 @@ function getMeta(name) { const m = Array.prototype.slice.call(elements).find( m => m.getAttribute("http-equiv") == name ); return m ? m.getAttribute("content") : ""; } -function getCsrfToken() { - return getMeta("X-CSRF-Token"); -} -function getAuthorization() { - return getMeta("Authorization"); +function preparePost(uri, form) { + const xauth = "Authorization"; + const xcsrf = "X-CSRF-Token"; + var headers = {}; + headers[xauth] = getMeta(xauth); + headers[xcsrf] = getMeta(xcsrf); + return { + url: uri, dataType: "json", contentType: "application/json", + headers: headers, + data: JSON.stringify(form) + }; } function onClickSignUp() { - let csrf = getCsrfToken(); - let email = $('#email').val(); - $.post({ - url: "/api/invite", - dataType: "json", - contentType: "application/json", - headers: { - "X-CSRF-Token": csrf - }, - data: JSON.stringify({ - "email": email - }) - }).done( () => { + const form = {"email": $('#email').val()}; + const body = preparePost("/api/invite", form); + $.post(body).done( () => { alert("Please check your email for an invitation link."); }).fail( error => alert(error.responseText) ); } +function onClickSignIn() { + const form = { + "email": $('#email').val(), + "password": $('#password').val() + }; + const body = preparePost("/api/login", form); + $.post(body).done( (data) => { + if (data.token.length > 0) { + $('head').append(``); + $('#popupLogin').modal('toggle'); + } else { + alert("sorry, unable to login."); + console.dir(data); + } + }).fail( + error => alert(error.responseText) + ); +} function onClickJoin() { - let csrf = getCsrfToken(); - let code = $('#code').val(); - let password = $('#newPassword').val(); - $.post({ - url: "/api/register", - dataType: "json", - contentType: "application/json", - headers: { - "X-CSRF-Token": csrf - }, - data: JSON.stringify({ - "code": code, - "password": password - }) - }).done( () => { + const form = { + "code": $('#code').val(), + "password": $('#newPassword').val() + }; + const body = preparePost("/api/register", form); + $.post(body).done( () => { alert("Success! Please login!"); window.location = "/"; }).fail( From 8261bb41cbe8451f9645b0bad731f914d9d906cd Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Mon, 4 Jul 2022 14:57:07 -0400 Subject: [PATCH 33/48] cleaning up --- Sources/PerfectAuth/Nonce.swift | 3 +- Sources/httpd/Gateway.swift | 81 +++++++++++++++++++++++---- templates/pages/accountreset.mustache | 25 +++++++++ templates/pages/inc/header.mustache | 1 + webroot/js/api.js | 22 ++++++++ 5 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 templates/pages/accountreset.mustache diff --git a/Sources/PerfectAuth/Nonce.swift b/Sources/PerfectAuth/Nonce.swift index 518a9f04..d16c5700 100644 --- a/Sources/PerfectAuth/Nonce.swift +++ b/Sources/PerfectAuth/Nonce.swift @@ -29,7 +29,8 @@ public struct Nonce { } /// check if this nonce is valid - public static func validate(nonce: String, valid seconds: Int = 900, authorityPublicKey: PEMKey) throws { + public static func validate(nonce: String, seconds: Int = 900, authorityPublicKey: PEMKey) throws { + // swiftlint:disable type_name typealias exception = AuthenticationTokenClaim.Exception guard let jwt = JWTVerifier(nonce) else { throw exception.invalidJsonWebToken diff --git a/Sources/httpd/Gateway.swift b/Sources/httpd/Gateway.swift index 3e08078a..d3e620ce 100644 --- a/Sources/httpd/Gateway.swift +++ b/Sources/httpd/Gateway.swift @@ -13,14 +13,16 @@ public struct Gateway { var error = "" var token = "" } + // swiftlint:disable comma public static func load(routes: Routes = Routes()) throws -> Routes { var routes = routes - routes.add(method: .get, uri: "/p/account/new", handler: accountNew) routes.add(method: .post, uri: "/api/invite", handler: invite) - routes.add(method: .post, uri: "/api/register", handler: register) + routes.add(method: .post, uri: "/api/register", handler: resetPassword) routes.add(method: .post, uri: "/api/login", handler: login) routes.add(method: .post, uri: "/api/reset/attempt", handler: resetPasswordRequest) - routes.add(method: .get, uri: "/api/rest/confirm", handler: resetPassword) + routes.add(method: .post, uri: "/api/reset/confirm", handler: resetPassword) + routes.add(method: .get, uri: "/p/account/new", handler: accountNew) + routes.add(method: .get, uri: "/p/account/reset", handler: accountReset) routes.add(method: .get, uri: "/s/api/secret", handler: secretResource) routes.add(method: .get, uri: "/**", handler: template) return routes @@ -42,7 +44,7 @@ public struct Gateway { return } do { - try Nonce.validate(nonce: nonce, valid: Settings.default.validTokenSeconds, authorityPublicKey: Settings.default.keyPublic) + try Nonce.validate(nonce: nonce, seconds: Settings.default.validTokenSeconds, authorityPublicKey: Settings.default.keyPublic) callback(.continue(request, response)) } catch { CRUDLogging.log(.warning, "invalid CSRF token: \(nonce) because \(error)") @@ -147,7 +149,7 @@ public struct Gateway { } } public static func accountNew(request: HTTPRequest, response: HTTPResponse) { - guard let param = (request.queryParams.first { $0.0 == "code"}), + guard let param = (request.queryParams.first { $0.0 == "code"}), let code = UUID(uuidString: param.1) else { response.setHeader(.contentType, value: MimeType.text) response.status = .badRequest @@ -182,7 +184,7 @@ public struct Gateway { } response.completed() } - public static func register(request: HTTPRequest, response: HTTPResponse) { + public static func resetPassword(request: HTTPRequest, response: HTTPResponse) { struct Form: Codable { let code: String let password: String @@ -230,13 +232,68 @@ public struct Gateway { response.completed() } public static func resetPasswordRequest(request: HTTPRequest, response: HTTPResponse) { - response.setHeader(.contentType, value: "application/json") - response.appendBody(string: Settings.default.json) - response.completed() + struct InvitationRequest: Codable { + let email: String + } + response.setHeader(.contentType, value: MimeType.json) + do { + guard let invitationRequest = try request.postBodyJson(InvitationRequest.self) else { + throw Exception.invalidJSON + } + guard let account = try Account.find(email: invitationRequest.email) else { + throw Exception.invalidAccount + } + let code = try Account.requestPasswordReset(email: account.email) + let cfg = Settings.default + let content: [String: Any] = [ + "name": cfg.name, + "url": "\(cfg.url)/p/account/reset?code=\(code.uuidString.lowercased())", + "minutes": cfg.validResetSeconds / 60 + ] + try Email.compose(recepient: account.email, content: content, template: "passwordreset") { error in + let error = error ?? Exception.ok + response.setBody(string: error.jsonString) + response.completed() + } + } catch { + response.setBody(string: error.jsonString) + response.completed() + } } - public static func resetPassword(request: HTTPRequest, response: HTTPResponse) { - response.setHeader(.contentType, value: "application/json") - response.appendBody(string: Settings.default.json) + public static func accountReset(request: HTTPRequest, response: HTTPResponse) { + guard let param = (request.queryParams.first { $0.0 == "code"}), + let code = UUID(uuidString: param.1) else { + response.setHeader(.contentType, value: MimeType.text) + response.status = .badRequest + response.setBody(string: "400 Bad Request") + response.completed() + return + } + let cfg = Settings.default + do { + let id = try Access.recover(code: code) + guard let account = try Account.lookup(id: id) else { + throw Exception.invalidAccount + } + var content: [String: Any] = [ + "name": cfg.name, + "email": account.email, + "code": code.uuidString.lowercased(), + "minutes": cfg.validResetSeconds / 60 + ] + if let nonce = (try? Nonce.allocate(authorityPrivateKey: cfg.keyPrivate)) { + content["csrf"] = nonce + } + let context = MustacheEvaluationContext(templatePath: "\(cfg.pathTemplates)/pages/accountreset.mustache", map: content) + let collector = MustacheEvaluationOutputCollector() + let html = try context.formulateResponse(withCollector: collector) + response.setHeader(.contentType, value: MimeType.html) + response.setBody(string: html) + } catch { + response.setHeader(.contentType, value: MimeType.text) + response.status = .badRequest + response.setBody(string: "\(error)") + } response.completed() } public static func secretResource(request: HTTPRequest, response: HTTPResponse) { diff --git a/templates/pages/accountreset.mustache b/templates/pages/accountreset.mustache new file mode 100644 index 00000000..5a8b1c63 --- /dev/null +++ b/templates/pages/accountreset.mustache @@ -0,0 +1,25 @@ +{{ > inc/header }} + +{{ > inc/footer }} diff --git a/templates/pages/inc/header.mustache b/templates/pages/inc/header.mustache index 4f669890..22fa28e4 100644 --- a/templates/pages/inc/header.mustache +++ b/templates/pages/inc/header.mustache @@ -68,6 +68,7 @@ diff --git a/webroot/js/api.js b/webroot/js/api.js index 8d843dac..d616686f 100644 --- a/webroot/js/api.js +++ b/webroot/js/api.js @@ -54,4 +54,26 @@ function onClickJoin() { }).fail( error => alert(error.responseText) ); +} +function onClickReset() { + const form = {"email": $('#email').val()}; + const body = preparePost("/api/reset/attempt", form); + $.post(body).done( () => { + alert("Please check your email for an password reset link."); + }).fail( + error => alert(error.responseText) + ); +} +function onClickConfirmReset() { + const form = { + "code": $('#code').val(), + "password": $('#newPassword').val() + }; + const body = preparePost("/api/reset/confirm", form); + $.post(body).done( () => { + alert("Success! Please login!"); + window.location = "/"; + }).fail( + error => alert(error.responseText) + ); } \ No newline at end of file From 0099e9eae6010ba6c4f52478783341d611c26fec Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Mon, 18 Jul 2022 13:19:40 -0400 Subject: [PATCH 34/48] introducing one-time code --- Package.swift | 4 +- Sources/PerfectAuth/Transient.swift | 87 +++++++++++++++++++ Tests/PerfectAuthTests/PerfectAuthTests.swift | 36 ++++++++ 3 files changed, 125 insertions(+), 2 deletions(-) create mode 100644 Sources/PerfectAuth/Transient.swift diff --git a/Package.swift b/Package.swift index 24a551cd..71079959 100644 --- a/Package.swift +++ b/Package.swift @@ -55,7 +55,7 @@ let package = Package( targets: ostag + [ .target(name: "COpenSSL"), .target(name: "cURL"), - .target(name: "PerfectAuth", dependencies: ["PerfectCrypto"]), + .target(name: "PerfectAuth", dependencies: ["PerfectCrypto", "PerfectCRUD", "PerfectSQLite"]), .target(name: "PerfectCZlib", exclude: czLibExcludes), .target(name: "PerfectCHTTPParser"), .target(name: "PerfectLib", dependencies: osdep), @@ -70,7 +70,7 @@ let package = Package( .target(name: "PerfectSMTP", dependencies: ["PerfectCURL", "PerfectCrypto", "PerfectHTTP"]), .target(name: "PerfectSQLite", dependencies: sqldep), .target(name: "PerfectWebSockets", dependencies: ["PerfectHTTP"]), - .testTarget(name: "PerfectAuthTests", dependencies: ["PerfectAuth"]), + .testTarget(name: "PerfectAuthTests", dependencies: ["PerfectAuth", "PerfectCRUD", "PerfectLib", "PerfectSQLite"]), .testTarget(name: "PerfectCryptoTests", dependencies: ["PerfectCrypto"]), .testTarget(name: "PerfectCURLTests", dependencies: ["PerfectCURL"]), .testTarget(name: "PerfectHTTPTests", dependencies: ["PerfectHTTP"]), diff --git a/Sources/PerfectAuth/Transient.swift b/Sources/PerfectAuth/Transient.swift new file mode 100644 index 00000000..80732dde --- /dev/null +++ b/Sources/PerfectAuth/Transient.swift @@ -0,0 +1,87 @@ +// +// Transient.swift +// +// +// Created by Rockford Wei on 2022-07-12. +// + +import Foundation +import PerfectCRUD +import PerfectSQLite + +public struct OneTimeRecord: Codable { + let id: Int + let subject: String + let createdAt: Int + init(id i: Int = Int.random(in: 0..<1_000_000), subject s: String, createdAt c: Int = Date().timestamp) { + id = i; subject = s; createdAt = c + } +} + +public final class Transient { + public enum Exception: Error { + case overAttempted + case subjectNotFound + case invalidCode + case expired + } + public static let minimalRetrySeconds = 60 + public static let expirySeconds = 900 // 15 minutes + public static let dbPath = "/tmp/perfect-transient.sqlite3" + private static let queue = DispatchQueue(label: UUID().uuidString) + private static let db: Database = { + do { + let config = try SQLiteDatabaseConfiguration(dbPath) + let db = Database(configuration: config) + try db.create(OneTimeRecord.self, policy: .reconcileTable) + return db + } catch { + fatalError("unable load \(dbPath) for transient code control because \(error)") + } + }() + public static func cleanup(expiry: Int = expirySeconds) { + do { + let expired = Date().timestamp - expiry + let table = db.table(OneTimeRecord.self) + try table.where(\OneTimeRecord.createdAt <= expired).delete() + queue.asyncAfter(deadline: .now() + Double(expiry)) { + #if DEBUG + CRUDLogging.log(.info, "\(expired):: cleaning up obsolete records") + #endif + cleanup(expiry: expiry) + } + } catch { + CRUDLogging.log(.warning, "unable to clean the transient allocator because \(error)") + } + } + public static func record(of subject: String) throws -> OneTimeRecord? { + let table = db.table(OneTimeRecord.self) + return try table.order(descending: \OneTimeRecord.createdAt) + .where(\OneTimeRecord.subject == subject) + .first() + } + public static func allocate(subject: String, minimalRetry: Int = minimalRetrySeconds) throws -> Int { + let table = db.table(OneTimeRecord.self) + if let record = try record(of: subject) { + if Date().timestamp - record.createdAt < minimalRetry { + throw Exception.overAttempted + } else { + try table.where(\OneTimeRecord.subject == subject).delete() + } + } + let record = OneTimeRecord(subject: subject) + try table.insert(record) + return record.id + } + public static func validate(id: Int, subject: String, expiry: Int = expirySeconds) throws { + guard let record = try record(of: subject) else { + throw Exception.subjectNotFound + } + guard id == record.id else { + throw Exception.invalidCode + } + guard Date().timestamp < record.createdAt + expiry else { + throw Exception.expired + } + } +} diff --git a/Tests/PerfectAuthTests/PerfectAuthTests.swift b/Tests/PerfectAuthTests/PerfectAuthTests.swift index 2b04bb71..9afa9cd9 100644 --- a/Tests/PerfectAuthTests/PerfectAuthTests.swift +++ b/Tests/PerfectAuthTests/PerfectAuthTests.swift @@ -1,4 +1,5 @@ import Foundation +import PerfectLib import PerfectCrypto import XCTest @@ -7,6 +8,41 @@ import XCTest // swiftlint:disable line_length class PerfectAuthTests: XCTestCase { + func testOneTimeCode() throws { + File(Transient.dbPath).delete() + let subject = "800-000-1111" + let expiry = 3 + var code = try Transient.allocate(subject: subject, minimalRetry: expiry) + XCTAssertTrue(code >= 0 && code < 1_000_000) + do { + _ = try Transient.allocate(subject: subject, minimalRetry: expiry) + } catch Transient.Exception.overAttempted { + print("over attempt caught") + } + try Transient.validate(id: code, subject: subject) + do { + try Transient.validate(id: code, subject: "") + } catch Transient.Exception.subjectNotFound { + print("invalid subject caught") + } + do { + try Transient.validate(id: -1, subject: subject) + } catch Transient.Exception.invalidCode { + print("invalid code caught") + } + sleep(UInt32(expiry + 1)) + do { + try Transient.validate(id: code, subject: subject, expiry: expiry) + } catch Transient.Exception.expired { + print("expiration caught") + } + Transient.cleanup(expiry: expiry) + code = try Transient.allocate(subject: subject, minimalRetry: expiry) + XCTAssertTrue(code >= 0 && code < 1_000_000) + sleep(UInt32(expiry) + 1) + XCTAssertNil(try Transient.record(of: subject)) + } + func testPasswordUtilities() throws { let password = UUID().uuidString.lowercased() guard let hash = AuthenticationUtilities.hash(password: password) else { From f7f186e35f2d8d7c686c58d39daad28c5e172e6c Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Tue, 19 Jul 2022 14:22:34 -0400 Subject: [PATCH 35/48] improving transient code with better error suggestion. --- Sources/PerfectAuth/Transient.swift | 7 ++++--- Tests/PerfectAuthTests/PerfectAuthTests.swift | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Sources/PerfectAuth/Transient.swift b/Sources/PerfectAuth/Transient.swift index 80732dde..23e2309f 100644 --- a/Sources/PerfectAuth/Transient.swift +++ b/Sources/PerfectAuth/Transient.swift @@ -20,7 +20,7 @@ public struct OneTimeRecord: Codable { public final class Transient { public enum Exception: Error { - case overAttempted + case overAttempted(shouldWaitSeconds: Int) case subjectNotFound case invalidCode case expired @@ -63,8 +63,9 @@ public final class Transient { public static func allocate(subject: String, minimalRetry: Int = minimalRetrySeconds) throws -> Int { let table = db.table(OneTimeRecord.self) if let record = try record(of: subject) { - if Date().timestamp - record.createdAt < minimalRetry { - throw Exception.overAttempted + let secondsToWait = minimalRetry - (Date().timestamp - record.createdAt) + if secondsToWait > 0 { + throw Exception.overAttempted(shouldWaitSeconds: secondsToWait) } else { try table.where(\OneTimeRecord.subject == subject).delete() } diff --git a/Tests/PerfectAuthTests/PerfectAuthTests.swift b/Tests/PerfectAuthTests/PerfectAuthTests.swift index 9afa9cd9..e1a69cb6 100644 --- a/Tests/PerfectAuthTests/PerfectAuthTests.swift +++ b/Tests/PerfectAuthTests/PerfectAuthTests.swift @@ -16,8 +16,8 @@ class PerfectAuthTests: XCTestCase { XCTAssertTrue(code >= 0 && code < 1_000_000) do { _ = try Transient.allocate(subject: subject, minimalRetry: expiry) - } catch Transient.Exception.overAttempted { - print("over attempt caught") + } catch Transient.Exception.overAttempted(let secondsToWait) { + print("over attempt caught: \(secondsToWait) seconds") } try Transient.validate(id: code, subject: subject) do { From 2baed197e4ab41a15b4a1ba565ec8ef9b6fc58b2 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Fri, 29 Jul 2022 08:00:16 -0400 Subject: [PATCH 36/48] exposing OneTimeRecord attributes for public access --- Sources/PerfectAuth/Transient.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/PerfectAuth/Transient.swift b/Sources/PerfectAuth/Transient.swift index 23e2309f..41f561f4 100644 --- a/Sources/PerfectAuth/Transient.swift +++ b/Sources/PerfectAuth/Transient.swift @@ -10,9 +10,9 @@ import PerfectCRUD import PerfectSQLite public struct OneTimeRecord: Codable { - let id: Int - let subject: String - let createdAt: Int + public let id: Int + public let subject: String + public let createdAt: Int init(id i: Int = Int.random(in: 0..<1_000_000), subject s: String, createdAt c: Int = Date().timestamp) { id = i; subject = s; createdAt = c } From e1d9ecdbe904a6a89728d4e027c246d9f60a07b1 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Fri, 29 Jul 2022 22:07:38 -0400 Subject: [PATCH 37/48] implementing `httpRequest.setBody(Error, jsonLike)` --- Sources/PerfectHTTP/HTTPResponse.swift | 12 +++++++ Tests/PerfectHTTPTests/PerfectHTTPTests.swift | 31 ++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Sources/PerfectHTTP/HTTPResponse.swift b/Sources/PerfectHTTP/HTTPResponse.swift index 5df7dd6b..6ab0c0ad 100644 --- a/Sources/PerfectHTTP/HTTPResponse.swift +++ b/Sources/PerfectHTTP/HTTPResponse.swift @@ -341,6 +341,18 @@ public extension HTTPResponse { return setBody(bytes: Array(data)) } + @discardableResult + func setBody(error: Error, asJson: Bool = true) -> Self { + let text = "\(error)".replacingOccurrences(of: "\"", with: "'") + if asJson { + setHeader(.contentType, value: MimeType.json) + return setBody(string: "{\n\t\"error\": \"\(text)\"\n}\n") + } else { + setHeader(.contentType, value: MimeType.text) + return setBody(string: "\(text)") + } + } + /// Encodes the JSONConvertible as a JSON string and converts that to a UTF-8 encoded [UInt8]. /// Adds the "application/json" content type unless `skipContentType` is true. @discardableResult diff --git a/Tests/PerfectHTTPTests/PerfectHTTPTests.swift b/Tests/PerfectHTTPTests/PerfectHTTPTests.swift index 5a465d5a..c34125a4 100644 --- a/Tests/PerfectHTTPTests/PerfectHTTPTests.swift +++ b/Tests/PerfectHTTPTests/PerfectHTTPTests.swift @@ -744,7 +744,36 @@ class PerfectHTTPTests: XCTestCase { func testMimeForExtension() { XCTAssert(MimeType.forExtension("ts") == "video/mp2t") } - func testJSONBody() { + + func testErrorBodyInJson() { + let response = ShimHTTPResponse() + let errResp = HTTPResponseError(status: .badRequest, description: "invalid request") + response.setBody(error: errResp) + let data = Data(response.bodyBytes) + struct ErrorCodable: Codable { + let error: String + } + do { + let e = try JSONDecoder().decode(ErrorCodable.self, from: data) + XCTAssertEqual(e.error, "HTTPResponseError(status: 400 Bad Request, description: 'invalid request')") + } catch { + XCTFail("\(error)") + } + } + + func testErrorBodyIntext() { + let response = ShimHTTPResponse() + let errResp = HTTPResponseError(status: .badRequest, description: "invalid request") + response.setBody(error: errResp, asJson: false) + let data = Data(response.bodyBytes) + guard let text = String(data: data, encoding: .utf8) else { + XCTFail("unable to encode error body in text") + return + } + XCTAssertEqual(text, "HTTPResponseError(status: 400 Bad Request, description: 'invalid request')") + } + + func testJSONBody() { do { let response = ShimHTTPResponse() struct MyCodable: Codable { From 1b4ddb5330116328dd978e20a05cda63853a0b98 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Fri, 12 Aug 2022 13:16:01 -0400 Subject: [PATCH 38/48] improving post json body header verification. --- Sources/PerfectHTTP/HTTPRequest.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/PerfectHTTP/HTTPRequest.swift b/Sources/PerfectHTTP/HTTPRequest.swift index 66a4da47..70d44d68 100644 --- a/Sources/PerfectHTTP/HTTPRequest.swift +++ b/Sources/PerfectHTTP/HTTPRequest.swift @@ -139,9 +139,9 @@ public extension HTTPRequest { public extension HTTPRequest { func postBodyJson(_ `type`: T.Type) throws -> T? { - let ctype = header(.contentType)?.lowercased() - guard ctype == MimeType.json else { - throw HTTPResponseError(status: .badRequest, description: "unexpected content type \(ctype ?? "N/A"); expecting \(MimeType.json)") + let ctype = header(.contentType)?.lowercased() ?? "N/A" + guard ctype.contains(string: MimeType.json) else { + throw HTTPResponseError(status: .badRequest, description: "unexpected content type \(ctype); expecting \(MimeType.json)") } guard let bytes = postBodyBytes else { throw HTTPResponseError(status: .badRequest, description: "unexpected empty posting body") From 4d578a425234a8f2558b9b7a662b34ca4d7dec93 Mon Sep 17 00:00:00 2001 From: xxw8 Date: Tue, 25 Apr 2023 14:55:26 -0400 Subject: [PATCH 39/48] clear all warnings. --- Package.swift | 7 +++++-- Sources/PerfectCURL/CURLRequestOptions.swift | 6 ++++-- Tests/PerfectNetTests/PerfectNetTests.swift | 6 +++--- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Package.swift b/Package.swift index 71079959..01cfa898 100644 --- a/Package.swift +++ b/Package.swift @@ -24,6 +24,9 @@ let czLibExcludes: [String] = [ "zlib.map", "zlib.pc", "zlib.pc.cmakein", "zlib.pc.in", "zlib2ansi" ] +let flags: [String] = ["-Wno-conversion"] +let cSettings = [CSetting.unsafeFlags(flags)] + #if os(Linux) let osdep: [Target.Dependency] = ["LinuxBridge"] let ostag: [Target] = [.target(name: "LinuxBridge"), .target(name: "PerfectCSQLite3")] @@ -53,10 +56,10 @@ let package = Package( ], dependencies: [ ], targets: ostag + [ - .target(name: "COpenSSL"), + .target(name: "COpenSSL", cSettings: cSettings), .target(name: "cURL"), .target(name: "PerfectAuth", dependencies: ["PerfectCrypto", "PerfectCRUD", "PerfectSQLite"]), - .target(name: "PerfectCZlib", exclude: czLibExcludes), + .target(name: "PerfectCZlib", exclude: czLibExcludes, cSettings: cSettings), .target(name: "PerfectCHTTPParser"), .target(name: "PerfectLib", dependencies: osdep), .target(name: "PerfectThread", dependencies: osdep), diff --git a/Sources/PerfectCURL/CURLRequestOptions.swift b/Sources/PerfectCURL/CURLRequestOptions.swift index 2c8b38cb..4cf16d2f 100644 --- a/Sources/PerfectCURL/CURLRequestOptions.swift +++ b/Sources/PerfectCURL/CURLRequestOptions.swift @@ -127,8 +127,8 @@ extension CURLRequest.Option { optArray.forEach { curl.setOption(CURLOPT_POSTQUOTE, s: $0) } case .ftpPort(let optString): curl.setOption(CURLOPT_FTPPORT, s: optString) - case .ftpResponseTimeout(let optInt): - curl.setOption(CURLOPT_FTP_RESPONSE_TIMEOUT, int: optInt) + //case .ftpResponseTimeout(let optInt): + // curl.setOption(CURLOPT_FTP_RESPONSE_TIMEOUT, int: optInt) case .sshPublicKey(let optString): curl.setOption(CURLOPT_SSH_PUBLIC_KEYFILE, s: optString) case .sshPrivateKey(let optString): @@ -196,6 +196,8 @@ extension CURLRequest.Option { return CURLRequest.Option.upload(FileUploader(File(path))).apply(to: request) case .acceptEncoding(let str): curl.setOption(CURLOPT_ACCEPT_ENCODING, s: str) + default: + () } } } diff --git a/Tests/PerfectNetTests/PerfectNetTests.swift b/Tests/PerfectNetTests/PerfectNetTests.swift index 00198069..3b209162 100644 --- a/Tests/PerfectNetTests/PerfectNetTests.swift +++ b/Tests/PerfectNetTests/PerfectNetTests.swift @@ -119,8 +119,8 @@ class PerfectNetTests: XCTestCase { } func testTCPSSLClient() { - let address = "www.treefrog.ca" - let requestString = [UInt8](("GET / HTTP/1.0\r\nHost: \(address)\r\n\r\n").utf8) + let address = "httpbin.org" + let requestString = [UInt8](("GET /get HTTP/1.0\r\nHost: \(address)\r\n\r\n").utf8) let requestCount = requestString.count let clientExpectation = self.expectation(description: "client") let net = NetTCPSSL() @@ -147,7 +147,7 @@ class PerfectNetTests: XCTestCase { readBytesCpy.append(0) let s2 = readBytesCpy.withUnsafeBytes { String(validatingUTF8: $0.bindMemory(to: CChar.self).baseAddress!)! } let s = s1 + s2 - XCTAssert(s.starts(with: "HTTP/1.1 200 OK")) + XCTAssert(s.starts(with: "HTTP/1.1 200 OK")) clientExpectation.fulfill() } } From a33126b5bfc48d257299ea5c489cde8076cf2986 Mon Sep 17 00:00:00 2001 From: RockfordWei Date: Thu, 27 Apr 2023 11:31:22 +0000 Subject: [PATCH 40/48] Linux 5.8 --- Package.swift | 2 +- Sources/PerfectNet/NetAddress.swift | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 01cfa898..b1e43621 100644 --- a/Package.swift +++ b/Package.swift @@ -24,7 +24,7 @@ let czLibExcludes: [String] = [ "zlib.map", "zlib.pc", "zlib.pc.cmakein", "zlib.pc.in", "zlib2ansi" ] -let flags: [String] = ["-Wno-conversion"] +let flags: [String] = ["-Wno-conversion", "-Wno-deprecated-non-prototype"] let cSettings = [CSetting.unsafeFlags(flags)] #if os(Linux) diff --git a/Sources/PerfectNet/NetAddress.swift b/Sources/PerfectNet/NetAddress.swift index f39f6ce7..da1b69a2 100644 --- a/Sources/PerfectNet/NetAddress.swift +++ b/Sources/PerfectNet/NetAddress.swift @@ -10,6 +10,8 @@ import PerfectThread #if os(Linux) import SwiftGlibc + fileprivate let SOCK_STREAM = __socket_type(1) + fileprivate let SOCK_DGRAM = __socket_type(2) public let AF_UNSPEC: Int32 = 0 #else import Darwin From d0dfb664158ae7dbf2723352da6662cd1b104aef Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Sun, 28 May 2023 21:14:31 -0400 Subject: [PATCH 41/48] suppressing C warnings. --- Package.swift | 7 ++----- Sources/COpenSSL/a_.c | 1 + Sources/COpenSSL/aes_.c | 1 + Sources/COpenSSL/ameth_lib.c | 1 + Sources/COpenSSL/asn1_.c | 1 + Sources/COpenSSL/asn_.c | 1 + Sources/COpenSSL/b_dump.c | 1 + Sources/COpenSSL/b_print.c | 1 + Sources/COpenSSL/bf_.c | 1 + Sources/COpenSSL/bio_.c | 1 + Sources/COpenSSL/bn_.c | 1 + Sources/COpenSSL/bss_.c | 1 + Sources/COpenSSL/buffer.c | 1 + Sources/COpenSSL/by_.c | 1 + Sources/COpenSSL/c_.c | 1 + Sources/COpenSSL/cm_.c | 1 + Sources/COpenSSL/cmac.c | 1 + Sources/COpenSSL/cms_.c | 1 + Sources/COpenSSL/conf_.c | 1 + Sources/COpenSSL/d1_.c | 1 + Sources/COpenSSL/d1_lib.c | 1 + Sources/COpenSSL/d2i_.c | 1 + Sources/COpenSSL/dh_.c | 1 + Sources/COpenSSL/dsa_.c | 1 + Sources/COpenSSL/e_4758cca.c | 1 + Sources/COpenSSL/e_aep.c | 1 + Sources/COpenSSL/e_aes.c | 1 + Sources/COpenSSL/e_atalla.c | 1 + Sources/COpenSSL/e_chil.c | 1 + Sources/COpenSSL/e_cswift.c | 1 + Sources/COpenSSL/e_des3.c | 1 + Sources/COpenSSL/e_nuron.c | 1 + Sources/COpenSSL/e_sureware.c | 1 + Sources/COpenSSL/e_ubsec.c | 1 + Sources/COpenSSL/ec2_.c | 1 + Sources/COpenSSL/ec_.c | 1 + Sources/COpenSSL/ech_.c | 1 + Sources/COpenSSL/ecp_oct.c | 1 + Sources/COpenSSL/enc_.c | 1 + Sources/COpenSSL/encode.c | 1 + Sources/COpenSSL/eng_.c | 1 + Sources/COpenSSL/err_.c | 1 + Sources/COpenSSL/evp_.c | 1 + Sources/COpenSSL/gost_.c | 1 + Sources/COpenSSL/gosthash.c | 1 + Sources/COpenSSL/hm_.c | 1 + Sources/COpenSSL/hmac.c | 1 + Sources/COpenSSL/m_sigver.c | 1 + Sources/COpenSSL/md32_common.h | 1 + Sources/COpenSSL/md_rand.c | 1 + Sources/COpenSSL/mem.c | 1 + Sources/COpenSSL/mem_.c | 1 + Sources/COpenSSL/n_pkey.c | 1 + Sources/COpenSSL/o_.c | 1 + Sources/COpenSSL/obj_.c | 1 + Sources/COpenSSL/ocsp_.c | 1 + Sources/COpenSSL/ofb_enc.c | 1 + Sources/COpenSSL/p12_.c | 1 + Sources/COpenSSL/p5_.c | 1 + Sources/COpenSSL/p_.c | 1 + Sources/COpenSSL/pcy_.c | 1 + Sources/COpenSSL/pem_.c | 1 + Sources/COpenSSL/pk7_.c | 1 + Sources/COpenSSL/pvkfmt.c | 1 + Sources/COpenSSL/rand_.c | 1 + Sources/COpenSSL/randfile.c | 1 + Sources/COpenSSL/rsa_.c | 1 + Sources/COpenSSL/s23_.c | 1 + Sources/COpenSSL/s3_.c | 1 + Sources/COpenSSL/set_key.c | 1 + Sources/COpenSSL/sha256.c | 1 + Sources/COpenSSL/sha_locl.h | 1 + Sources/COpenSSL/srp_.c | 1 + Sources/COpenSSL/ssl_.c | 1 + Sources/COpenSSL/str2key.c | 1 + Sources/COpenSSL/t1_.c | 1 + Sources/COpenSSL/t_.c | 1 + Sources/COpenSSL/tasn_.c | 1 + Sources/COpenSSL/tb_asnmth.c | 1 + Sources/COpenSSL/tls_srp.c | 1 + Sources/COpenSSL/ts_.c | 1 + Sources/COpenSSL/txt_db.c | 1 + Sources/COpenSSL/ui_.c | 1 + Sources/COpenSSL/v3_.c | 1 + Sources/COpenSSL/x509_.c | 1 + Sources/COpenSSL/x509name.c | 1 + Sources/COpenSSL/x509spki.c | 1 + Sources/COpenSSL/x_.c | 1 + Sources/PerfectCZlib/deflate.c | 1 + Sources/PerfectCZlib/gzread.c | 1 + Sources/PerfectCZlib/gzwrite.c | 1 + 91 files changed, 92 insertions(+), 5 deletions(-) diff --git a/Package.swift b/Package.swift index b1e43621..71079959 100644 --- a/Package.swift +++ b/Package.swift @@ -24,9 +24,6 @@ let czLibExcludes: [String] = [ "zlib.map", "zlib.pc", "zlib.pc.cmakein", "zlib.pc.in", "zlib2ansi" ] -let flags: [String] = ["-Wno-conversion", "-Wno-deprecated-non-prototype"] -let cSettings = [CSetting.unsafeFlags(flags)] - #if os(Linux) let osdep: [Target.Dependency] = ["LinuxBridge"] let ostag: [Target] = [.target(name: "LinuxBridge"), .target(name: "PerfectCSQLite3")] @@ -56,10 +53,10 @@ let package = Package( ], dependencies: [ ], targets: ostag + [ - .target(name: "COpenSSL", cSettings: cSettings), + .target(name: "COpenSSL"), .target(name: "cURL"), .target(name: "PerfectAuth", dependencies: ["PerfectCrypto", "PerfectCRUD", "PerfectSQLite"]), - .target(name: "PerfectCZlib", exclude: czLibExcludes, cSettings: cSettings), + .target(name: "PerfectCZlib", exclude: czLibExcludes), .target(name: "PerfectCHTTPParser"), .target(name: "PerfectLib", dependencies: osdep), .target(name: "PerfectThread", dependencies: osdep), diff --git a/Sources/COpenSSL/a_.c b/Sources/COpenSSL/a_.c index 82d63aa4..50119ff6 100644 --- a/Sources/COpenSSL/a_.c +++ b/Sources/COpenSSL/a_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/asn1/a_bitstr.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/aes_.c b/Sources/COpenSSL/aes_.c index bd0850f7..cca4be8d 100644 --- a/Sources/COpenSSL/aes_.c +++ b/Sources/COpenSSL/aes_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/aes/aes_cbc.c */ /* ==================================================================== * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. diff --git a/Sources/COpenSSL/ameth_lib.c b/Sources/COpenSSL/ameth_lib.c index be73058e..cefdb168 100644 --- a/Sources/COpenSSL/ameth_lib.c +++ b/Sources/COpenSSL/ameth_lib.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2006. diff --git a/Sources/COpenSSL/asn1_.c b/Sources/COpenSSL/asn1_.c index 36299ec2..1f09a786 100644 --- a/Sources/COpenSSL/asn1_.c +++ b/Sources/COpenSSL/asn1_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/asn1/asn1_err.c */ /* ==================================================================== * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. diff --git a/Sources/COpenSSL/asn_.c b/Sources/COpenSSL/asn_.c index d0d0e941..ff174b05 100644 --- a/Sources/COpenSSL/asn_.c +++ b/Sources/COpenSSL/asn_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* asn_mime.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL diff --git a/Sources/COpenSSL/b_dump.c b/Sources/COpenSSL/b_dump.c index fcfd6995..d836d59c 100644 --- a/Sources/COpenSSL/b_dump.c +++ b/Sources/COpenSSL/b_dump.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/bio/b_dump.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/b_print.c b/Sources/COpenSSL/b_print.c index a2ebe2b5..59e585c5 100644 --- a/Sources/COpenSSL/b_print.c +++ b/Sources/COpenSSL/b_print.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/bio/b_print.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/bf_.c b/Sources/COpenSSL/bf_.c index 0833fede..f3b4661b 100644 --- a/Sources/COpenSSL/bf_.c +++ b/Sources/COpenSSL/bf_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/bio/bf_buff.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/bio_.c b/Sources/COpenSSL/bio_.c index fe3bc19e..41fa1a34 100644 --- a/Sources/COpenSSL/bio_.c +++ b/Sources/COpenSSL/bio_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* bio_asn1.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL diff --git a/Sources/COpenSSL/bn_.c b/Sources/COpenSSL/bn_.c index a7d8db1b..a49987fd 100644 --- a/Sources/COpenSSL/bn_.c +++ b/Sources/COpenSSL/bn_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/bn/bn_add.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/bss_.c b/Sources/COpenSSL/bss_.c index b5a671d6..28ad4eb6 100644 --- a/Sources/COpenSSL/bss_.c +++ b/Sources/COpenSSL/bss_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/bio/bss_acpt.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/buffer.c b/Sources/COpenSSL/buffer.c index 82f462e8..2a0e7d1a 100644 --- a/Sources/COpenSSL/buffer.c +++ b/Sources/COpenSSL/buffer.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/buffer/buffer.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/by_.c b/Sources/COpenSSL/by_.c index ff48e154..eebf6149 100644 --- a/Sources/COpenSSL/by_.c +++ b/Sources/COpenSSL/by_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/x509/by_dir.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/c_.c b/Sources/COpenSSL/c_.c index 3b72d6da..0e37a8c0 100644 --- a/Sources/COpenSSL/c_.c +++ b/Sources/COpenSSL/c_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/evp/c_all.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/cm_.c b/Sources/COpenSSL/cm_.c index 53393010..ce66d1fd 100644 --- a/Sources/COpenSSL/cm_.c +++ b/Sources/COpenSSL/cm_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2010. diff --git a/Sources/COpenSSL/cmac.c b/Sources/COpenSSL/cmac.c index 9ae59c9b..6d9aafa3 100644 --- a/Sources/COpenSSL/cmac.c +++ b/Sources/COpenSSL/cmac.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/cmac/cmac.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL diff --git a/Sources/COpenSSL/cms_.c b/Sources/COpenSSL/cms_.c index afbec0a0..bd1bc961 100644 --- a/Sources/COpenSSL/cms_.c +++ b/Sources/COpenSSL/cms_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/cms/cms_asn1.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL diff --git a/Sources/COpenSSL/conf_.c b/Sources/COpenSSL/conf_.c index ab0d3893..1548dd8c 100644 --- a/Sources/COpenSSL/conf_.c +++ b/Sources/COpenSSL/conf_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* conf_api.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/d1_.c b/Sources/COpenSSL/d1_.c index ba720193..4bd26443 100644 --- a/Sources/COpenSSL/d1_.c +++ b/Sources/COpenSSL/d1_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ssl/d1_both.c */ /* * DTLS implementation written by Nagendra Modadugu diff --git a/Sources/COpenSSL/d1_lib.c b/Sources/COpenSSL/d1_lib.c index ab052545..cb2656ac 100644 --- a/Sources/COpenSSL/d1_lib.c +++ b/Sources/COpenSSL/d1_lib.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ssl/d1_lib.c */ /* * DTLS implementation written by Nagendra Modadugu diff --git a/Sources/COpenSSL/d2i_.c b/Sources/COpenSSL/d2i_.c index de45a985..63aaafbe 100644 --- a/Sources/COpenSSL/d2i_.c +++ b/Sources/COpenSSL/d2i_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/asn1/d2i_pr.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/dh_.c b/Sources/COpenSSL/dh_.c index 2e9b4056..8a993724 100644 --- a/Sources/COpenSSL/dh_.c +++ b/Sources/COpenSSL/dh_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2006. diff --git a/Sources/COpenSSL/dsa_.c b/Sources/COpenSSL/dsa_.c index f1d90aa9..07f39f79 100644 --- a/Sources/COpenSSL/dsa_.c +++ b/Sources/COpenSSL/dsa_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2006. diff --git a/Sources/COpenSSL/e_4758cca.c b/Sources/COpenSSL/e_4758cca.c index d331c134..a5e5e04e 100644 --- a/Sources/COpenSSL/e_4758cca.c +++ b/Sources/COpenSSL/e_4758cca.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* Author: Maurice Gittens */ /* ==================================================================== * Copyright (c) 1999 The OpenSSL Project. All rights reserved. diff --git a/Sources/COpenSSL/e_aep.c b/Sources/COpenSSL/e_aep.c index edf7c229..0f433ec7 100644 --- a/Sources/COpenSSL/e_aep.c +++ b/Sources/COpenSSL/e_aep.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ==================================================================== * Copyright (c) 1999 The OpenSSL Project. All rights reserved. * diff --git a/Sources/COpenSSL/e_aes.c b/Sources/COpenSSL/e_aes.c index 4ff534b7..5a55b18d 100644 --- a/Sources/COpenSSL/e_aes.c +++ b/Sources/COpenSSL/e_aes.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ==================================================================== * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. * diff --git a/Sources/COpenSSL/e_atalla.c b/Sources/COpenSSL/e_atalla.c index 0774c84f..b3b03e2d 100644 --- a/Sources/COpenSSL/e_atalla.c +++ b/Sources/COpenSSL/e_atalla.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/engine/hw_atalla.c */ /* * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project diff --git a/Sources/COpenSSL/e_chil.c b/Sources/COpenSSL/e_chil.c index 3abc504d..fb6af219 100644 --- a/Sources/COpenSSL/e_chil.c +++ b/Sources/COpenSSL/e_chil.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/engine/e_chil.c */ /* * Written by Richard Levitte (richard@levitte.org), Geoff Thorpe diff --git a/Sources/COpenSSL/e_cswift.c b/Sources/COpenSSL/e_cswift.c index f0fcbc7e..aff8bb7a 100644 --- a/Sources/COpenSSL/e_cswift.c +++ b/Sources/COpenSSL/e_cswift.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/engine/hw_cswift.c */ /* * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project diff --git a/Sources/COpenSSL/e_des3.c b/Sources/COpenSSL/e_des3.c index bd30bac1..63e341f1 100644 --- a/Sources/COpenSSL/e_des3.c +++ b/Sources/COpenSSL/e_des3.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/evp/e_des3.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/e_nuron.c b/Sources/COpenSSL/e_nuron.c index 1c943521..2dd3f5a2 100644 --- a/Sources/COpenSSL/e_nuron.c +++ b/Sources/COpenSSL/e_nuron.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/engine/hw_nuron.c */ /* * Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff diff --git a/Sources/COpenSSL/e_sureware.c b/Sources/COpenSSL/e_sureware.c index f32c6aa1..d1bd6709 100644 --- a/Sources/COpenSSL/e_sureware.c +++ b/Sources/COpenSSL/e_sureware.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /*- * Written by Corinne Dive-Reclus(cdive@baltimore.com) * diff --git a/Sources/COpenSSL/e_ubsec.c b/Sources/COpenSSL/e_ubsec.c index e00ea4bd..ba20fbc5 100644 --- a/Sources/COpenSSL/e_ubsec.c +++ b/Sources/COpenSSL/e_ubsec.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/engine/hw_ubsec.c */ /* * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project diff --git a/Sources/COpenSSL/ec2_.c b/Sources/COpenSSL/ec2_.c index b289761b..5dcc7db9 100644 --- a/Sources/COpenSSL/ec2_.c +++ b/Sources/COpenSSL/ec2_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/ec/ec2_mult.c */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. diff --git a/Sources/COpenSSL/ec_.c b/Sources/COpenSSL/ec_.c index f1e6243f..ab3e9446 100644 --- a/Sources/COpenSSL/ec_.c +++ b/Sources/COpenSSL/ec_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2006. diff --git a/Sources/COpenSSL/ech_.c b/Sources/COpenSSL/ech_.c index 88894864..6538b6c2 100644 --- a/Sources/COpenSSL/ech_.c +++ b/Sources/COpenSSL/ech_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/ecdh/ech_err.c */ /* ==================================================================== * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. diff --git a/Sources/COpenSSL/ecp_oct.c b/Sources/COpenSSL/ecp_oct.c index f08d0d45..dbc143e6 100644 --- a/Sources/COpenSSL/ecp_oct.c +++ b/Sources/COpenSSL/ecp_oct.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/ec/ecp_oct.c */ /* * Includes code written by Lenka Fibikova diff --git a/Sources/COpenSSL/enc_.c b/Sources/COpenSSL/enc_.c index 6b1abee1..3efa8dec 100644 --- a/Sources/COpenSSL/enc_.c +++ b/Sources/COpenSSL/enc_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/des/enc_read.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/encode.c b/Sources/COpenSSL/encode.c index 06ecf637..61786587 100644 --- a/Sources/COpenSSL/encode.c +++ b/Sources/COpenSSL/encode.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/evp/encode.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/eng_.c b/Sources/COpenSSL/eng_.c index 8e2c7aba..b5c2000c 100644 --- a/Sources/COpenSSL/eng_.c +++ b/Sources/COpenSSL/eng_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/engine/eng_all.c */ /* * Written by Richard Levitte for the OpenSSL project diff --git a/Sources/COpenSSL/err_.c b/Sources/COpenSSL/err_.c index 9c981be7..31cddd7b 100644 --- a/Sources/COpenSSL/err_.c +++ b/Sources/COpenSSL/err_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/err/err_all.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/evp_.c b/Sources/COpenSSL/evp_.c index 6d2babb4..a09db50e 100644 --- a/Sources/COpenSSL/evp_.c +++ b/Sources/COpenSSL/evp_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* evp_acnf.c */ /* * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/gost_.c b/Sources/COpenSSL/gost_.c index a1f0cbb9..904540d7 100644 --- a/Sources/COpenSSL/gost_.c +++ b/Sources/COpenSSL/gost_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /********************************************************************** * gost_ameth.c * * Copyright (c) 2005-2006 Cryptocom LTD * diff --git a/Sources/COpenSSL/gosthash.c b/Sources/COpenSSL/gosthash.c index bfc884ae..c2ce919e 100644 --- a/Sources/COpenSSL/gosthash.c +++ b/Sources/COpenSSL/gosthash.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /********************************************************************** * gosthash.c * * Copyright (c) 2005-2006 Cryptocom LTD * diff --git a/Sources/COpenSSL/hm_.c b/Sources/COpenSSL/hm_.c index 030ca777..90be770a 100644 --- a/Sources/COpenSSL/hm_.c +++ b/Sources/COpenSSL/hm_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2007. diff --git a/Sources/COpenSSL/hmac.c b/Sources/COpenSSL/hmac.c index 8587fc62..f1b6d081 100644 --- a/Sources/COpenSSL/hmac.c +++ b/Sources/COpenSSL/hmac.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/hmac/hmac.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/m_sigver.c b/Sources/COpenSSL/m_sigver.c index 195111aa..36658927 100644 --- a/Sources/COpenSSL/m_sigver.c +++ b/Sources/COpenSSL/m_sigver.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* m_sigver.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/md32_common.h b/Sources/COpenSSL/md32_common.h index ab6a5efc..597e7ba8 100644 --- a/Sources/COpenSSL/md32_common.h +++ b/Sources/COpenSSL/md32_common.h @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/md32_common.h */ /* ==================================================================== * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. diff --git a/Sources/COpenSSL/md_rand.c b/Sources/COpenSSL/md_rand.c index b742e493..6e1adafe 100644 --- a/Sources/COpenSSL/md_rand.c +++ b/Sources/COpenSSL/md_rand.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/rand/md_rand.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/mem.c b/Sources/COpenSSL/mem.c index d7c43982..112b21f9 100644 --- a/Sources/COpenSSL/mem.c +++ b/Sources/COpenSSL/mem.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/mem.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/mem_.c b/Sources/COpenSSL/mem_.c index ebbe5cba..d09b787a 100644 --- a/Sources/COpenSSL/mem_.c +++ b/Sources/COpenSSL/mem_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/mem_clr.c */ /* * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project diff --git a/Sources/COpenSSL/n_pkey.c b/Sources/COpenSSL/n_pkey.c index 4641059e..823f9af3 100644 --- a/Sources/COpenSSL/n_pkey.c +++ b/Sources/COpenSSL/n_pkey.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/asn1/n_pkey.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/o_.c b/Sources/COpenSSL/o_.c index bbb007d7..5e279834 100644 --- a/Sources/COpenSSL/o_.c +++ b/Sources/COpenSSL/o_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/o_dir.c */ /* * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project diff --git a/Sources/COpenSSL/obj_.c b/Sources/COpenSSL/obj_.c index 02700251..8896826e 100644 --- a/Sources/COpenSSL/obj_.c +++ b/Sources/COpenSSL/obj_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/objects/obj_dat.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/ocsp_.c b/Sources/COpenSSL/ocsp_.c index 4fae188e..6308d15a 100644 --- a/Sources/COpenSSL/ocsp_.c +++ b/Sources/COpenSSL/ocsp_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ocsp_asn.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/ofb_enc.c b/Sources/COpenSSL/ofb_enc.c index 02a78775..998a3cc9 100644 --- a/Sources/COpenSSL/ofb_enc.c +++ b/Sources/COpenSSL/ofb_enc.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/des/ofb_enc.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/p12_.c b/Sources/COpenSSL/p12_.c index 9f497f21..6dd30de6 100644 --- a/Sources/COpenSSL/p12_.c +++ b/Sources/COpenSSL/p12_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* p12_add.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/p5_.c b/Sources/COpenSSL/p5_.c index 466cb28c..86692df3 100644 --- a/Sources/COpenSSL/p5_.c +++ b/Sources/COpenSSL/p5_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* p5_crpt.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/p_.c b/Sources/COpenSSL/p_.c index 360c6b67..b6d6d274 100644 --- a/Sources/COpenSSL/p_.c +++ b/Sources/COpenSSL/p_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/evp/p_dec.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/pcy_.c b/Sources/COpenSSL/pcy_.c index fae243c0..800e0642 100644 --- a/Sources/COpenSSL/pcy_.c +++ b/Sources/COpenSSL/pcy_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* pcy_cache.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/pem_.c b/Sources/COpenSSL/pem_.c index b27b4c3a..1d3a8f59 100644 --- a/Sources/COpenSSL/pem_.c +++ b/Sources/COpenSSL/pem_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/pem/pem_all.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/pk7_.c b/Sources/COpenSSL/pk7_.c index ee05dacc..beaf5ce2 100644 --- a/Sources/COpenSSL/pk7_.c +++ b/Sources/COpenSSL/pk7_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* pk7_asn.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/pvkfmt.c b/Sources/COpenSSL/pvkfmt.c index ad89f664..d5852b13 100644 --- a/Sources/COpenSSL/pvkfmt.c +++ b/Sources/COpenSSL/pvkfmt.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project * 2005. diff --git a/Sources/COpenSSL/rand_.c b/Sources/COpenSSL/rand_.c index 9b688efe..03b915f1 100644 --- a/Sources/COpenSSL/rand_.c +++ b/Sources/COpenSSL/rand_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/rand/rand_egd.c */ /* Written by Ulf Moeller and Lutz Jaenicke for the OpenSSL project. */ /* ==================================================================== diff --git a/Sources/COpenSSL/randfile.c b/Sources/COpenSSL/randfile.c index ff5a6858..db4ca5b2 100644 --- a/Sources/COpenSSL/randfile.c +++ b/Sources/COpenSSL/randfile.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/rand/randfile.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/rsa_.c b/Sources/COpenSSL/rsa_.c index 36b08d90..6ab5d9c8 100644 --- a/Sources/COpenSSL/rsa_.c +++ b/Sources/COpenSSL/rsa_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/rsa/rsa_ameth.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/s23_.c b/Sources/COpenSSL/s23_.c index 79216a95..e14f5fa1 100644 --- a/Sources/COpenSSL/s23_.c +++ b/Sources/COpenSSL/s23_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ssl/s23_clnt.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/s3_.c b/Sources/COpenSSL/s3_.c index 45032a05..8a611fd6 100644 --- a/Sources/COpenSSL/s3_.c +++ b/Sources/COpenSSL/s3_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ssl/s3_both.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/set_key.c b/Sources/COpenSSL/set_key.c index f75e0f64..166c42bc 100644 --- a/Sources/COpenSSL/set_key.c +++ b/Sources/COpenSSL/set_key.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/des/set_key.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/sha256.c b/Sources/COpenSSL/sha256.c index 89c5c710..1bdaa249 100644 --- a/Sources/COpenSSL/sha256.c +++ b/Sources/COpenSSL/sha256.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/sha/sha256.c */ /* ==================================================================== * Copyright (c) 2004 The OpenSSL Project. All rights reserved diff --git a/Sources/COpenSSL/sha_locl.h b/Sources/COpenSSL/sha_locl.h index 1b3a7c68..8ebcf822 100644 --- a/Sources/COpenSSL/sha_locl.h +++ b/Sources/COpenSSL/sha_locl.h @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/sha/sha_locl.h */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/srp_.c b/Sources/COpenSSL/srp_.c index d824ba05..cdbb8769 100644 --- a/Sources/COpenSSL/srp_.c +++ b/Sources/COpenSSL/srp_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/srp/srp_lib.c */ /* * Written by Christophe Renou (christophe.renou@edelweb.fr) with the diff --git a/Sources/COpenSSL/ssl_.c b/Sources/COpenSSL/ssl_.c index 2e37265c..8e765126 100644 --- a/Sources/COpenSSL/ssl_.c +++ b/Sources/COpenSSL/ssl_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ssl/ssl_algs.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/str2key.c b/Sources/COpenSSL/str2key.c index be1438b6..bcb8b1ca 100644 --- a/Sources/COpenSSL/str2key.c +++ b/Sources/COpenSSL/str2key.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/des/str2key.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/t1_.c b/Sources/COpenSSL/t1_.c index 515776b8..83e7e297 100644 --- a/Sources/COpenSSL/t1_.c +++ b/Sources/COpenSSL/t1_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ssl/t1_clnt.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/t_.c b/Sources/COpenSSL/t_.c index 851f7fcc..756b66ba 100644 --- a/Sources/COpenSSL/t_.c +++ b/Sources/COpenSSL/t_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* t_bitst.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/tasn_.c b/Sources/COpenSSL/tasn_.c index 20d21bcb..a27f70c7 100644 --- a/Sources/COpenSSL/tasn_.c +++ b/Sources/COpenSSL/tasn_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* tasn_dec.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/tb_asnmth.c b/Sources/COpenSSL/tb_asnmth.c index 865e0606..751ebe3e 100644 --- a/Sources/COpenSSL/tb_asnmth.c +++ b/Sources/COpenSSL/tb_asnmth.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ==================================================================== * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. * diff --git a/Sources/COpenSSL/tls_srp.c b/Sources/COpenSSL/tls_srp.c index b7471194..09b8f370 100644 --- a/Sources/COpenSSL/tls_srp.c +++ b/Sources/COpenSSL/tls_srp.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* ssl/tls_srp.c */ /* * Written by Christophe Renou (christophe.renou@edelweb.fr) with the diff --git a/Sources/COpenSSL/ts_.c b/Sources/COpenSSL/ts_.c index 7175419b..118721c9 100644 --- a/Sources/COpenSSL/ts_.c +++ b/Sources/COpenSSL/ts_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/ts/ts_asn1.c */ /* * Written by Nils Larsch for the OpenSSL project 2004. diff --git a/Sources/COpenSSL/txt_db.c b/Sources/COpenSSL/txt_db.c index ae2d2e10..316bc6aa 100644 --- a/Sources/COpenSSL/txt_db.c +++ b/Sources/COpenSSL/txt_db.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/txt_db/txt_db.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/ui_.c b/Sources/COpenSSL/ui_.c index 191306b5..0313f443 100644 --- a/Sources/COpenSSL/ui_.c +++ b/Sources/COpenSSL/ui_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/ui/ui_compat.c */ /* ==================================================================== * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. diff --git a/Sources/COpenSSL/v3_.c b/Sources/COpenSSL/v3_.c index 30a9654d..e77010c5 100644 --- a/Sources/COpenSSL/v3_.c +++ b/Sources/COpenSSL/v3_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* * Contributed to the OpenSSL Project by the American Registry for * Internet Numbers ("ARIN"). diff --git a/Sources/COpenSSL/x509_.c b/Sources/COpenSSL/x509_.c index c7183957..3e96217b 100644 --- a/Sources/COpenSSL/x509_.c +++ b/Sources/COpenSSL/x509_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/x509/x509_att.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/x509name.c b/Sources/COpenSSL/x509name.c index d1959b4c..4b78c5cc 100644 --- a/Sources/COpenSSL/x509name.c +++ b/Sources/COpenSSL/x509name.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* crypto/x509/x509name.c */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. diff --git a/Sources/COpenSSL/x509spki.c b/Sources/COpenSSL/x509spki.c index 8bbfa793..c89c20ac 100644 --- a/Sources/COpenSSL/x509spki.c +++ b/Sources/COpenSSL/x509spki.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* x509spki.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/COpenSSL/x_.c b/Sources/COpenSSL/x_.c index 23732cb1..337d6534 100644 --- a/Sources/COpenSSL/x_.c +++ b/Sources/COpenSSL/x_.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* x_algor.c */ /* * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project diff --git a/Sources/PerfectCZlib/deflate.c b/Sources/PerfectCZlib/deflate.c index 415adbf9..a44d5baa 100644 --- a/Sources/PerfectCZlib/deflate.c +++ b/Sources/PerfectCZlib/deflate.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* deflate.c -- compress data using the deflation algorithm * Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/Sources/PerfectCZlib/gzread.c b/Sources/PerfectCZlib/gzread.c index 956b91ea..00c70bbc 100644 --- a/Sources/PerfectCZlib/gzread.c +++ b/Sources/PerfectCZlib/gzread.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* gzread.c -- zlib functions for reading gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h diff --git a/Sources/PerfectCZlib/gzwrite.c b/Sources/PerfectCZlib/gzwrite.c index a2ee573d..c39cbabf 100644 --- a/Sources/PerfectCZlib/gzwrite.c +++ b/Sources/PerfectCZlib/gzwrite.c @@ -1,3 +1,4 @@ +#pragma clang diagnostic ignored "-Wconversion" /* gzwrite.c -- zlib functions for writing gzip files * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h From 7726549581a8a896f048bf405e55c7536d5fd6f9 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Tue, 15 Aug 2023 12:23:38 -0400 Subject: [PATCH 42/48] Update Transient.swift to allow configurable one time code settings --- Sources/PerfectAuth/Transient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/PerfectAuth/Transient.swift b/Sources/PerfectAuth/Transient.swift index 41f561f4..456c437e 100644 --- a/Sources/PerfectAuth/Transient.swift +++ b/Sources/PerfectAuth/Transient.swift @@ -25,7 +25,7 @@ public final class Transient { case invalidCode case expired } - public static let minimalRetrySeconds = 60 + public static var minimalRetrySeconds = 60 public static let expirySeconds = 900 // 15 minutes public static let dbPath = "/tmp/perfect-transient.sqlite3" private static let queue = DispatchQueue(label: UUID().uuidString) From 7b82b4abcc0a08a35481203f438dd338eebc6921 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Mon, 21 Aug 2023 09:58:31 -0400 Subject: [PATCH 43/48] adding extensions to net tcp --- Sources/PerfectNet/Net.swift | 93 +++++++++++++++------------- Sources/PerfectNet/NetExt.swift | 106 ++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 43 deletions(-) create mode 100644 Sources/PerfectNet/NetExt.swift diff --git a/Sources/PerfectNet/Net.swift b/Sources/PerfectNet/Net.swift index 89ab641d..a1a65583 100644 --- a/Sources/PerfectNet/Net.swift +++ b/Sources/PerfectNet/Net.swift @@ -87,7 +87,10 @@ public enum PerfectNetError: Error { func ThrowNetworkError(file: String = #file, function: String = #function, line: Int = #line) throws -> Never { let err = errno - let msg = String(validatingUTF8: strerror(err))! + let bufferSize = 1024 + var buffer = [CChar](repeating: 0, count: bufferSize) + _ = strerror_r(errno, &buffer, bufferSize) + let msg = String(cString: buffer) throw PerfectNetError.networkError(err, msg + " \(file) \(function) \(line)") } @@ -203,48 +206,52 @@ open class Net { fd.switchToNonBlocking() } } -// -// func makeAddress(_ sin: inout sockaddr_storage, host: String, port: UInt16) -> Int { -// let aiFlags: Int32 = 0 -// let family: Int32 = AF_UNSPEC -// let bPort = port.bigEndian -// var hints = addrinfo(ai_flags: aiFlags, ai_family: family, ai_socktype: SOCK_STREAM, ai_protocol: 0, ai_addrlen: 0, ai_canonname: nil, ai_addr: nil, ai_next: nil) -// var resultList = UnsafeMutablePointer(bitPattern: 0) -// var result = getaddrinfo(host, nil, &hints, &resultList) -// while EAI_AGAIN == result { -// Threading.sleep(seconds: 0.1) -// result = getaddrinfo(host, nil, &hints, &resultList) -// } -// if result == EAI_NONAME { -// hints = addrinfo(ai_flags: aiFlags, ai_family: AF_INET6, ai_socktype: SOCK_STREAM, ai_protocol: 0, ai_addrlen: 0, ai_canonname: nil, ai_addr: nil, ai_next: nil) -// result = getaddrinfo(host, nil, &hints, &resultList) -// } -// if result == 0, var resultList = resultList { -// defer { -// freeaddrinfo(resultList) -// } -// guard let addr = resultList.pointee.ai_addr else { -// return -1 -// } -// switch Int32(addr.pointee.sa_family) { -// case AF_INET6: -// memcpy(&sin, addr, MemoryLayout.size) -// UnsafeMutablePointer(&sin).withMemoryRebound(to: sockaddr_in6.self, capacity: 1) { -// $0.pointee.sin6_port = in_port_t(bPort) -// } -// case AF_INET: -// memcpy(&sin, addr, MemoryLayout.size) -// UnsafeMutablePointer(&sin).withMemoryRebound(to: sockaddr_in.self, capacity: 1) { -// $0.pointee.sin_port = in_port_t(bPort) -// } -// default: -// return -1 -// } -// } else { -// return -1 -// } -// return 0 -// } + + func makeAddress(_ sin: inout sockaddr_storage, host: String, port: UInt16) -> Int { + let aiFlags: Int32 = 0 + let family: Int32 = AF_UNSPEC + let bPort = port.bigEndian + var hints = addrinfo(ai_flags: aiFlags, ai_family: family, ai_socktype: SOCK_STREAM, ai_protocol: 0, ai_addrlen: 0, ai_canonname: nil, ai_addr: nil, ai_next: nil) + var resultList = UnsafeMutablePointer(bitPattern: 0) + var result = getaddrinfo(host, nil, &hints, &resultList) + while EAI_AGAIN == result { + Threading.sleep(seconds: 0.1) + result = getaddrinfo(host, nil, &hints, &resultList) + } + if result == EAI_NONAME { + hints = addrinfo(ai_flags: aiFlags, ai_family: AF_INET6, ai_socktype: SOCK_STREAM, ai_protocol: 0, ai_addrlen: 0, ai_canonname: nil, ai_addr: nil, ai_next: nil) + result = getaddrinfo(host, nil, &hints, &resultList) + } + if result == 0, let resultList { + defer { + freeaddrinfo(resultList) + } + guard let addr = resultList.pointee.ai_addr else { + return -1 + } + switch Int32(addr.pointee.sa_family) { + case AF_INET6: + let size = MemoryLayout.size + memcpy(&sin, addr, size) + var addr6 = sockaddr_in6() + memcpy(&addr6, &sin, size) + addr6.sin6_port = in_port_t(bPort) + memcpy(&sin, &addr6, size) + case AF_INET: + let size = MemoryLayout.size + memcpy(&sin, addr, size) + var addr4 = sockaddr_in() + memcpy(&addr4, &sin, size) + addr4.sin_port = in_port_t(bPort) + memcpy(&sin, &addr4, size) + default: + return -1 + } + } else { + return -1 + } + return 0 + } func isEAgain(err: Int) -> Bool { return err == -1 && errno == EAGAIN diff --git a/Sources/PerfectNet/NetExt.swift b/Sources/PerfectNet/NetExt.swift new file mode 100644 index 00000000..cdfcc587 --- /dev/null +++ b/Sources/PerfectNet/NetExt.swift @@ -0,0 +1,106 @@ +// +// NetExt.swift +// +// +// Created by Rocky Wei on 2023-08-21. +// + +import Foundation + +@available(macOS 10.15.0, *) +public extension NetTCP { + /// Read the indicated number of bytes and deliver them concurrently. + /// - parameter count: The number of bytes to read + /// - parameter timeoutSeconds: The number of seconds to wait for the requested number of bytes. A timeout value of negative one indicates that the request should have no timeout. + /// - returns: If the timeout occurs before the requested number of bytes have been read, an empty array will be delivered to the callback. + /// If an error or disconnection occurs then a nil object will be delivered. + func readBytesFullyWithContinuation(count: Int, timeoutSeconds: Double) async -> [UInt8]? { + return await withCheckedContinuation { continuation in + readBytesFully(count: count, timeoutSeconds: timeoutSeconds) { data in + continuation.resume(returning: data) + } + } + } + + /// Read up to the indicated number of bytes and deliver them concurrently + /// - parameter count: The maximum number of bytes to read. + /// - returns: If an error occurs during the read then a nil object will be passed, otherwise, the immediately available number of bytes, which may be zero, will be passed. + func readSomeBytes(count: Int) async -> [UInt8]? { + return await withCheckedContinuation { continuation in + readSomeBytes(count: count) { data in + continuation.resume(returning: data) + } + } + } + + /// Write the string and return the number of bytes which were written. + /// - parameter s: The string to write. The string will be written based on its UTF-8 encoding. + /// - returns: The number of bytes which were successfuly written, which may be zero. + func writeWithContinuation(string: String) async -> Int { + return await withCheckedContinuation { continuation in + write(string: string) { written in + continuation.resume(returning: written) + } + } + } + + /// Write the indicated bytes and return the number of bytes which were written. + /// - parameter bytes: The array of UInt8 to write. + /// - returns: The number of bytes which were successfuly written, which may be zero. + func writeWithContinuation(bytes: [UInt8]) async -> Int { + return await withCheckedContinuation { continuation in + write(bytes: bytes) { written in + continuation.resume(returning: written) + } + } + } + + /// Write the indicated bytes and return the number of bytes which were written. + /// - parameter bytes: The array of UInt8 to write. + /// - parameter offsetBy: The offset within `bytes` at which to begin writing. + /// - parameter count: The number of bytes to write. + /// - returns: The number of bytes which were successfuly written, which may be zero. + func writeWithContinuation(bytes: [UInt8], offsetBy: Int, count: Int) async -> Int { + return await withCheckedContinuation { continuation in + write(bytes: bytes, offsetBy: offsetBy, count: count) { written in + continuation.resume(returning: written) + } + } + } + + /// Connect to the indicated server + /// - parameter address: The server's address, expressed as a string. + /// - parameter port: The port on which to connect. + /// - parameter timeoutSeconds: The number of seconds to wait for the connection to complete. A timeout of negative one indicates that there is no timeout. + /// - returns: If the connection completes successfully then the current NetTCP instance will be passed to the callback, otherwise, a nil object will be passed. + /// - returns: `PerfectError.NetworkError` + func connectWithContinuation(address: String, port: UInt16, timeoutSeconds: Double) async throws -> NetTCP? { + return try await withCheckedThrowingContinuation { continuation in + do { + try connect(address: address, port: port, timeoutSeconds: timeoutSeconds) { + continuation.resume(returning: $0) + } + } catch { + continuation.resume(throwing: error) + } + } + } + + /// Connect to the indicated server + /// - parameter address: The server's address, expressed as a string. + /// - parameter port: The port on which to connect. + /// - parameter timeoutSeconds: The number of seconds to wait for the connection to complete. A timeout of negative one indicates that there is no timeout. + /// - returns:. If the connection completes successfully then the current NetTCP instance will be passed to the callback, otherwise, a nil object will be passed. + /// - throws: `PerfectError.NetworkError` + func acceptWithContinuation(timeoutSeconds: Double) async throws -> NetTCP? { + return try await withCheckedThrowingContinuation { continuation in + do { + try accept(timeoutSeconds: timeoutSeconds) { + continuation.resume(returning: $0) + } + } catch { + continuation.resume(throwing: error) + } + } + } +} From 224e0391615bb183cea22ce68a74019a42ca49d2 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Mon, 21 Aug 2023 18:35:47 -0400 Subject: [PATCH 44/48] fixing the socket issue --- Sources/PerfectNet/Net.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sources/PerfectNet/Net.swift b/Sources/PerfectNet/Net.swift index a1a65583..bc2b3cb3 100644 --- a/Sources/PerfectNet/Net.swift +++ b/Sources/PerfectNet/Net.swift @@ -211,6 +211,9 @@ open class Net { let aiFlags: Int32 = 0 let family: Int32 = AF_UNSPEC let bPort = port.bigEndian + #if os(Linux) + let SOCK_STREAM = __socket_type(1) + #endif var hints = addrinfo(ai_flags: aiFlags, ai_family: family, ai_socktype: SOCK_STREAM, ai_protocol: 0, ai_addrlen: 0, ai_canonname: nil, ai_addr: nil, ai_next: nil) var resultList = UnsafeMutablePointer(bitPattern: 0) var result = getaddrinfo(host, nil, &hints, &resultList) From f71909382c26cacbbab3367811312be67d6d67a1 Mon Sep 17 00:00:00 2001 From: xxw8 Date: Wed, 23 Aug 2023 16:25:52 -0400 Subject: [PATCH 45/48] gm --- Package.resolved | 32 + Package.swift | 77 +- README.md | 4 +- Sources/COpenSSL/LPdir_unix.h | 122 - Sources/COpenSSL/a_.c | 6179 ------ Sources/COpenSSL/aep.h | 235 - Sources/COpenSSL/aes.h | 149 - Sources/COpenSSL/aes_.c | 2193 -- Sources/COpenSSL/aes_locl.h | 89 - Sources/COpenSSL/ameth_lib.c | 499 - Sources/COpenSSL/asn1.h | 1424 -- Sources/COpenSSL/asn1_.c | 2097 -- Sources/COpenSSL/asn1_int.h | 63 - Sources/COpenSSL/asn1_locl.h | 135 - Sources/COpenSSL/asn1_mac.h | 579 - Sources/COpenSSL/asn1t.h | 973 - Sources/COpenSSL/asn_.c | 1338 -- Sources/COpenSSL/atalla.h | 44 - Sources/COpenSSL/b_dump.c | 194 - Sources/COpenSSL/b_print.c | 870 - Sources/COpenSSL/b_sock.c | 983 - Sources/COpenSSL/bf_.c | 2109 -- Sources/COpenSSL/bf_locl.h | 221 - Sources/COpenSSL/bf_pi.h | 579 - Sources/COpenSSL/bio.h | 883 - Sources/COpenSSL/bio_.c | 4210 ---- Sources/COpenSSL/bio_lcl.h | 36 - Sources/COpenSSL/blowfish.h | 130 - Sources/COpenSSL/bn.h | 1015 - Sources/COpenSSL/bn_.c | 14933 -------------- Sources/COpenSSL/bn_int.h | 21 - Sources/COpenSSL/bn_lcl.h | 538 - Sources/COpenSSL/bn_prime.h | 326 - Sources/COpenSSL/bss_.c | 6064 ------ Sources/COpenSSL/buf_.c | 234 - Sources/COpenSSL/buffer.c | 188 - Sources/COpenSSL/buffer.h | 125 - Sources/COpenSSL/buildinf.h | 5 - Sources/COpenSSL/by_.c | 720 - Sources/COpenSSL/c_.c | 1958 -- Sources/COpenSSL/camellia.c | 584 - Sources/COpenSSL/camellia.h | 132 - Sources/COpenSSL/cast.h | 107 - Sources/COpenSSL/cast_lcl.h | 227 - Sources/COpenSSL/cast_s.h | 592 - Sources/COpenSSL/cbc128.c | 207 - Sources/COpenSSL/cbc3_enc.c | 95 - Sources/COpenSSL/cbc_.c | 164 - Sources/COpenSSL/ccm128.c | 479 - Sources/COpenSSL/cfb128.c | 254 - Sources/COpenSSL/cfb64ede.c | 249 - Sources/COpenSSL/cfb64enc.c | 122 - Sources/COpenSSL/cfb_enc.c | 199 - Sources/COpenSSL/charmap.h | 15 - Sources/COpenSSL/cm_.c | 313 - Sources/COpenSSL/cmac.c | 307 - Sources/COpenSSL/cmac.h | 82 - Sources/COpenSSL/cmll_.c | 610 - Sources/COpenSSL/cmll_locl.h | 88 - Sources/COpenSSL/cms.h | 555 - Sources/COpenSSL/cms_.c | 6362 ------ Sources/COpenSSL/cms_lcl.h | 471 - Sources/COpenSSL/comp.h | 83 - Sources/COpenSSL/comp_.c | 164 - Sources/COpenSSL/conf.h | 268 - Sources/COpenSSL/conf_.c | 2334 --- Sources/COpenSSL/conf_api.h | 89 - Sources/COpenSSL/conf_def.h | 181 - Sources/COpenSSL/constant_time_locl.h | 211 - Sources/COpenSSL/cpt_err.c | 104 - Sources/COpenSSL/cryptlib.c | 1037 - Sources/COpenSSL/cryptlib.h | 113 - Sources/COpenSSL/crypto.h | 661 - Sources/COpenSSL/cswift.h | 235 - Sources/COpenSSL/ctr128.c | 263 - Sources/COpenSSL/cversion.c | 107 - Sources/COpenSSL/d1_.c | 6037 ------ Sources/COpenSSL/d1_lib.c | 589 - Sources/COpenSSL/d2i_.c | 314 - Sources/COpenSSL/des.h | 257 - Sources/COpenSSL/des_enc.c | 389 - Sources/COpenSSL/des_locl.h | 443 - Sources/COpenSSL/des_old.c | 345 - Sources/COpenSSL/des_old.h | 497 - Sources/COpenSSL/des_old2.c | 80 - Sources/COpenSSL/des_ver.h | 73 - Sources/COpenSSL/dh.h | 412 - Sources/COpenSSL/dh_.c | 3418 ---- Sources/COpenSSL/digest.c | 408 - Sources/COpenSSL/dsa.h | 335 - Sources/COpenSSL/dsa_.c | 3495 ---- Sources/COpenSSL/dsa_locl.h | 69 - Sources/COpenSSL/dso.h | 451 - Sources/COpenSSL/dso_.c | 3214 --- Sources/COpenSSL/dtls1.h | 272 - Sources/COpenSSL/e_4758cca.c | 961 - Sources/COpenSSL/e_4758cca_err.c | 153 - Sources/COpenSSL/e_4758cca_err.h | 98 - Sources/COpenSSL/e_aep.c | 1168 -- Sources/COpenSSL/e_aep_err.c | 159 - Sources/COpenSSL/e_aep_err.h | 106 - Sources/COpenSSL/e_aes.c | 2034 -- Sources/COpenSSL/e_aes_cbc_hmac_sha1.c | 1015 - Sources/COpenSSL/e_aes_cbc_hmac_sha256.c | 996 - Sources/COpenSSL/e_atalla.c | 627 - Sources/COpenSSL/e_atalla_err.c | 145 - Sources/COpenSSL/e_atalla_err.h | 94 - Sources/COpenSSL/e_bf.c | 87 - Sources/COpenSSL/e_camellia.c | 396 - Sources/COpenSSL/e_capi.c | 1909 -- Sources/COpenSSL/e_capi_err.c | 187 - Sources/COpenSSL/e_capi_err.h | 129 - Sources/COpenSSL/e_cast.c | 89 - Sources/COpenSSL/e_chil.c | 1367 -- Sources/COpenSSL/e_chil_err.c | 157 - Sources/COpenSSL/e_chil_err.h | 105 - Sources/COpenSSL/e_cswift.c | 1104 -- Sources/COpenSSL/e_cswift_err.c | 150 - Sources/COpenSSL/e_cswift_err.h | 99 - Sources/COpenSSL/e_des.c | 269 - Sources/COpenSSL/e_des3.c | 498 - Sources/COpenSSL/e_gmp.c | 492 - Sources/COpenSSL/e_gmp_err.c | 137 - Sources/COpenSSL/e_gmp_err.h | 86 - Sources/COpenSSL/e_gost_err.c | 221 - Sources/COpenSSL/e_gost_err.h | 158 - Sources/COpenSSL/e_idea.c | 119 - Sources/COpenSSL/e_null.c | 100 - Sources/COpenSSL/e_nuron.c | 437 - Sources/COpenSSL/e_nuron_err.c | 142 - Sources/COpenSSL/e_nuron_err.h | 91 - Sources/COpenSSL/e_old.c | 164 - Sources/COpenSSL/e_os.h | 782 - Sources/COpenSSL/e_os2.h | 328 - Sources/COpenSSL/e_padlock.c | 1266 -- Sources/COpenSSL/e_rc2.c | 235 - Sources/COpenSSL/e_rc4.c | 133 - Sources/COpenSSL/e_rc4_hmac_md5.c | 312 - Sources/COpenSSL/e_rc5.c | 122 - Sources/COpenSSL/e_seed.c | 83 - Sources/COpenSSL/e_sureware.c | 1102 -- Sources/COpenSSL/e_sureware_err.c | 154 - Sources/COpenSSL/e_sureware_err.h | 104 - Sources/COpenSSL/e_ubsec.c | 1086 - Sources/COpenSSL/e_ubsec_err.c | 154 - Sources/COpenSSL/e_ubsec_err.h | 102 - Sources/COpenSSL/e_xcbc_d.c | 130 - Sources/COpenSSL/ebcdic.c | 284 - Sources/COpenSSL/ebcdic.h | 26 - Sources/COpenSSL/ec.h | 1282 -- Sources/COpenSSL/ec2_.c | 1667 -- Sources/COpenSSL/ec_.c | 9962 ---------- Sources/COpenSSL/ec_lcl.h | 567 - Sources/COpenSSL/ecb3_enc.c | 82 - Sources/COpenSSL/ecb_enc.c | 124 - Sources/COpenSSL/ecdh.h | 134 - Sources/COpenSSL/ecdsa.h | 335 - Sources/COpenSSL/ech_.c | 783 - Sources/COpenSSL/ech_locl.h | 104 - Sources/COpenSSL/eck_prn.c | 377 - Sources/COpenSSL/ecp_mont.c | 310 - Sources/COpenSSL/ecp_nist.c | 220 - Sources/COpenSSL/ecp_nistp224.c | 1767 -- Sources/COpenSSL/ecp_nistp256.c | 2369 --- Sources/COpenSSL/ecp_nistp521.c | 2146 -- Sources/COpenSSL/ecp_nistputil.c | 218 - Sources/COpenSSL/ecp_oct.c | 429 - Sources/COpenSSL/ecp_smpl.c | 1418 -- Sources/COpenSSL/ecs_.c | 1245 -- Sources/COpenSSL/ecs_locl.h | 120 - Sources/COpenSSL/ede_cbcm_enc.c | 189 - Sources/COpenSSL/enc_.c | 418 - Sources/COpenSSL/encode.c | 461 - Sources/COpenSSL/eng_.c | 5258 ----- Sources/COpenSSL/eng_int.h | 224 - Sources/COpenSSL/engine.h | 960 - Sources/COpenSSL/err.c | 1158 -- Sources/COpenSSL/err.h | 390 - Sources/COpenSSL/err_.c | 282 - Sources/COpenSSL/evp.h | 1628 -- Sources/COpenSSL/evp_.c | 2444 --- Sources/COpenSSL/evp_locl.h | 373 - Sources/COpenSSL/ex_data.c | 660 - Sources/COpenSSL/ext_dat.h | 136 - Sources/COpenSSL/f_.c | 627 - Sources/COpenSSL/fcrypt.c | 167 - Sources/COpenSSL/fcrypt_b.c | 140 - Sources/COpenSSL/fips_err.h | 223 - Sources/COpenSSL/fips_ers.c | 7 - Sources/COpenSSL/gcm128.c | 2371 --- Sources/COpenSSL/getenv.c | 31 - Sources/COpenSSL/gost2001.c | 474 - Sources/COpenSSL/gost2001_keyx.c | 294 - Sources/COpenSSL/gost2001_keyx.h | 10 - Sources/COpenSSL/gost89.c | 576 - Sources/COpenSSL/gost89.h | 98 - Sources/COpenSSL/gost94_keyx.c | 282 - Sources/COpenSSL/gost_.c | 3397 ---- Sources/COpenSSL/gost_keywrap.h | 56 - Sources/COpenSSL/gost_lcl.h | 229 - Sources/COpenSSL/gost_params.h | 34 - Sources/COpenSSL/gosthash.c | 269 - Sources/COpenSSL/gosthash.h | 52 - Sources/COpenSSL/hm_.c | 433 - Sources/COpenSSL/hmac.c | 269 - Sources/COpenSSL/hmac.h | 109 - Sources/COpenSSL/hw_4758_cca.h | 150 - Sources/COpenSSL/hw_ubsec.h | 124 - Sources/COpenSSL/hwcryptohook.h | 502 - Sources/COpenSSL/i2d_.c | 174 - Sources/COpenSSL/i_.c | 663 - Sources/COpenSSL/idea.h | 105 - Sources/COpenSSL/idea_lcl.h | 216 - Sources/COpenSSL/include/module.modulemap | 3 - Sources/COpenSSL/include/openssl.h | 559 - Sources/COpenSSL/krb5_asn.c | 162 - Sources/COpenSSL/krb5_asn.h | 240 - Sources/COpenSSL/kssl.c | 2271 --- Sources/COpenSSL/kssl.h | 197 - Sources/COpenSSL/kssl_lcl.h | 88 - Sources/COpenSSL/lh_stats.c | 246 - Sources/COpenSSL/lhash.c | 477 - Sources/COpenSSL/lhash.h | 240 - Sources/COpenSSL/m_dss.c | 104 - Sources/COpenSSL/m_dss1.c | 105 - Sources/COpenSSL/m_ecdsa.c | 154 - Sources/COpenSSL/m_md2.c | 106 - Sources/COpenSSL/m_md4.c | 108 - Sources/COpenSSL/m_md5.c | 107 - Sources/COpenSSL/m_mdc2.c | 108 - Sources/COpenSSL/m_null.c | 98 - Sources/COpenSSL/m_ripemd.c | 107 - Sources/COpenSSL/m_sha.c | 106 - Sources/COpenSSL/m_sha1.c | 235 - Sources/COpenSSL/m_sigver.c | 204 - Sources/COpenSSL/m_wp.c | 48 - Sources/COpenSSL/md32_common.h | 437 - Sources/COpenSSL/md4.h | 119 - Sources/COpenSSL/md4_.c | 295 - Sources/COpenSSL/md4_locl.h | 113 - Sources/COpenSSL/md5.h | 119 - Sources/COpenSSL/md5_.c | 312 - Sources/COpenSSL/md5_locl.h | 133 - Sources/COpenSSL/md_rand.c | 627 - Sources/COpenSSL/mdc2.h | 94 - Sources/COpenSSL/mdc2_one.c | 76 - Sources/COpenSSL/mdc2dgst.c | 196 - Sources/COpenSSL/mem.c | 459 - Sources/COpenSSL/mem_.c | 912 - Sources/COpenSSL/modes.h | 163 - Sources/COpenSSL/modes_lcl.h | 143 - Sources/COpenSSL/n_pkey.c | 346 - Sources/COpenSSL/names.c | 215 - Sources/COpenSSL/ncbc_enc.h | 154 - Sources/COpenSSL/nsseq.c | 84 - Sources/COpenSSL/o_.c | 1236 -- Sources/COpenSSL/o_dir.h | 55 - Sources/COpenSSL/o_str.h | 69 - Sources/COpenSSL/o_time.h | 70 - Sources/COpenSSL/obj_.c | 1265 -- Sources/COpenSSL/obj_dat.h | 5319 ----- Sources/COpenSSL/obj_mac.h | 4194 ---- Sources/COpenSSL/obj_xref.h | 99 - Sources/COpenSSL/objects.h | 1143 -- Sources/COpenSSL/ocsp.h | 637 - Sources/COpenSSL/ocsp_.c | 3155 --- Sources/COpenSSL/ofb128.c | 124 - Sources/COpenSSL/ofb64ede.c | 123 - Sources/COpenSSL/ofb64enc.c | 109 - Sources/COpenSSL/ofb_enc.c | 132 - Sources/COpenSSL/openbsd_hw.c | 453 - Sources/COpenSSL/opensslconf.h | 274 - Sources/COpenSSL/opensslv.h | 97 - Sources/COpenSSL/ossl_typ.h | 213 - Sources/COpenSSL/p12_.c | 2613 --- Sources/COpenSSL/p5_.c | 903 - Sources/COpenSSL/p8_pkey.c | 145 - Sources/COpenSSL/p_.c | 1138 -- Sources/COpenSSL/pcbc_enc.c | 115 - Sources/COpenSSL/pcy_.c | 1721 -- Sources/COpenSSL/pcy_int.h | 217 - Sources/COpenSSL/pem.h | 618 - Sources/COpenSSL/pem2.h | 70 - Sources/COpenSSL/pem_.c | 2922 --- Sources/COpenSSL/pk12err.c | 149 - Sources/COpenSSL/pk7_.c | 3112 --- Sources/COpenSSL/pk7_enc.h | 75 - Sources/COpenSSL/pkcs12.h | 342 - Sources/COpenSSL/pkcs7.h | 481 - Sources/COpenSSL/pkcs7err.c | 207 - Sources/COpenSSL/pmeth_.c | 1328 -- Sources/COpenSSL/pqueue.c | 235 - Sources/COpenSSL/pqueue.h | 99 - Sources/COpenSSL/pvkfmt.c | 896 - Sources/COpenSSL/qud_cksm.c | 143 - Sources/COpenSSL/rand.h | 150 - Sources/COpenSSL/rand_.c | 2501 --- Sources/COpenSSL/rand_lcl.h | 158 - Sources/COpenSSL/randfile.c | 372 - Sources/COpenSSL/rc2.h | 103 - Sources/COpenSSL/rc2_.c | 477 - Sources/COpenSSL/rc2_locl.h | 155 - Sources/COpenSSL/rc2cfb64.c | 123 - Sources/COpenSSL/rc2ofb64.c | 110 - Sources/COpenSSL/rc4.h | 88 - Sources/COpenSSL/rc4_.c | 512 - Sources/COpenSSL/rc4_locl.h | 5 - Sources/COpenSSL/read2pwd.c | 140 - Sources/COpenSSL/ripemd.h | 105 - Sources/COpenSSL/rmd_.c | 411 - Sources/COpenSSL/rmd_locl.h | 149 - Sources/COpenSSL/rmdconst.h | 398 - Sources/COpenSSL/rpc_des.h | 130 - Sources/COpenSSL/rpc_enc.c | 100 - Sources/COpenSSL/rsa.h | 664 - Sources/COpenSSL/rsa_.c | 6247 ------ Sources/COpenSSL/rsa_locl.h | 4 - Sources/COpenSSL/rsaz_exp.c | 346 - Sources/COpenSSL/rsaz_exp.h | 68 - Sources/COpenSSL/s23_.c | 1884 -- Sources/COpenSSL/s2_.c | 3850 ---- Sources/COpenSSL/s3_.c | 16475 ---------------- Sources/COpenSSL/safestack.h | 2672 --- Sources/COpenSSL/seed.c | 711 - Sources/COpenSSL/seed.h | 149 - Sources/COpenSSL/seed_.c | 361 - Sources/COpenSSL/seed_locl.h | 115 - Sources/COpenSSL/set_key.c | 448 - Sources/COpenSSL/sha.h | 214 - Sources/COpenSSL/sha1_one.c | 79 - Sources/COpenSSL/sha1dgst.c | 74 - Sources/COpenSSL/sha256.c | 388 - Sources/COpenSSL/sha512.c | 684 - Sources/COpenSSL/sha_.c | 153 - Sources/COpenSSL/sha_locl.h | 501 - Sources/COpenSSL/spr.h | 212 - Sources/COpenSSL/srp.h | 179 - Sources/COpenSSL/srp_.c | 1091 - Sources/COpenSSL/srp_grps.h | 528 - Sources/COpenSSL/srp_lcl.h | 84 - Sources/COpenSSL/srtp.h | 147 - Sources/COpenSSL/ssl.h | 3164 --- Sources/COpenSSL/ssl2.h | 265 - Sources/COpenSSL/ssl23.h | 84 - Sources/COpenSSL/ssl3.h | 774 - Sources/COpenSSL/ssl_.c | 13101 ------------ Sources/COpenSSL/ssl_locl.h | 1499 -- Sources/COpenSSL/stack.c | 384 - Sources/COpenSSL/stack.h | 107 - Sources/COpenSSL/str2key.c | 165 - Sources/COpenSSL/sureware.h | 250 - Sources/COpenSSL/symhacks.h | 518 - Sources/COpenSSL/t1_.c | 8111 -------- Sources/COpenSSL/t_.c | 1386 -- Sources/COpenSSL/tasn_.c | 3568 ---- Sources/COpenSSL/tb_asnmth.c | 247 - Sources/COpenSSL/tb_cipher.c | 143 - Sources/COpenSSL/tb_dh.c | 124 - Sources/COpenSSL/tb_digest.c | 143 - Sources/COpenSSL/tb_dsa.c | 124 - Sources/COpenSSL/tb_ecdh.c | 139 - Sources/COpenSSL/tb_ecdsa.c | 124 - Sources/COpenSSL/tb_pkmeth.c | 166 - Sources/COpenSSL/tb_rand.c | 124 - Sources/COpenSSL/tb_rsa.c | 124 - Sources/COpenSSL/tb_store.c | 129 - Sources/COpenSSL/th-lock.c | 389 - Sources/COpenSSL/tls1.h | 810 - Sources/COpenSSL/tls_srp.c | 543 - Sources/COpenSSL/ts.h | 865 - Sources/COpenSSL/ts_.c | 4091 ---- Sources/COpenSSL/txt_db.c | 398 - Sources/COpenSSL/txt_db.h | 112 - Sources/COpenSSL/ui.h | 415 - Sources/COpenSSL/ui_.c | 1900 -- Sources/COpenSSL/ui_compat.h | 88 - Sources/COpenSSL/ui_locl.h | 145 - Sources/COpenSSL/uid.c | 88 - Sources/COpenSSL/v3_.c | 10782 ---------- Sources/COpenSSL/v3_lib.c | 371 - Sources/COpenSSL/v3err.c | 249 - Sources/COpenSSL/vpm_int.h | 70 - Sources/COpenSSL/whrlpool.h | 41 - Sources/COpenSSL/wp_.c | 1038 - Sources/COpenSSL/wp_locl.h | 3 - Sources/COpenSSL/wrap128.c | 138 - Sources/COpenSSL/x509.h | 1330 -- Sources/COpenSSL/x509_.c | 7118 ------- Sources/COpenSSL/x509_vfy.h | 652 - Sources/COpenSSL/x509cset.c | 167 - Sources/COpenSSL/x509name.c | 398 - Sources/COpenSSL/x509rset.c | 85 - Sources/COpenSSL/x509spki.c | 126 - Sources/COpenSSL/x509type.c | 127 - Sources/COpenSSL/x509v3.h | 1055 - Sources/COpenSSL/x_.c | 3893 ---- Sources/COpenSSL/xcbc_enc.c | 216 - Sources/COpenSSL/xts128.c | 204 - Sources/LinuxBridge/LinuxBridge.c | 25 - Sources/LinuxBridge/include/LinuxBridge.h | 26 - Sources/PerfectCZlib/CMakeLists.txt | 249 - Sources/PerfectCZlib/ChangeLog | 1504 -- Sources/PerfectCZlib/FAQ | 368 - Sources/PerfectCZlib/INDEX | 68 - Sources/PerfectCZlib/Makefile | 405 - Sources/PerfectCZlib/Makefile.in | 405 - Sources/PerfectCZlib/README | 115 - Sources/PerfectCZlib/adler32.c | 186 - Sources/PerfectCZlib/amiga/Makefile.pup | 69 - Sources/PerfectCZlib/amiga/Makefile.sas | 68 - Sources/PerfectCZlib/compress.c | 86 - Sources/PerfectCZlib/configure | 921 - Sources/PerfectCZlib/configure.log | 922 - Sources/PerfectCZlib/crc32.c | 442 - Sources/PerfectCZlib/crc32.h | 441 - Sources/PerfectCZlib/deflate.c | 2157 -- Sources/PerfectCZlib/deflate.h | 349 - Sources/PerfectCZlib/doc/algorithm.txt | 209 - Sources/PerfectCZlib/doc/rfc1950.txt | 619 - Sources/PerfectCZlib/doc/rfc1951.txt | 955 - Sources/PerfectCZlib/doc/rfc1952.txt | 675 - Sources/PerfectCZlib/doc/txtvsbin.txt | 107 - Sources/PerfectCZlib/gzclose.c | 25 - Sources/PerfectCZlib/gzguts.h | 218 - Sources/PerfectCZlib/gzlib.c | 637 - Sources/PerfectCZlib/gzread.c | 655 - Sources/PerfectCZlib/gzwrite.c | 665 - Sources/PerfectCZlib/include/czlib.h | 5 - Sources/PerfectCZlib/include/inflate.h | 125 - Sources/PerfectCZlib/include/inftrees.h | 62 - Sources/PerfectCZlib/include/module.modulemap | 4 - Sources/PerfectCZlib/include/zconf.h | 534 - Sources/PerfectCZlib/include/zlib.h | 1910 -- Sources/PerfectCZlib/infback.c | 640 - Sources/PerfectCZlib/inffast.c | 321 - Sources/PerfectCZlib/inffast.h | 11 - Sources/PerfectCZlib/inffixed.h | 94 - Sources/PerfectCZlib/inflate.c | 1561 -- Sources/PerfectCZlib/inflate.h | 125 - Sources/PerfectCZlib/inftrees.c | 304 - Sources/PerfectCZlib/inftrees.h | 62 - Sources/PerfectCZlib/make_vms.com | 867 - Sources/PerfectCZlib/msdos/Makefile.bor | 115 - Sources/PerfectCZlib/msdos/Makefile.dj2 | 104 - Sources/PerfectCZlib/msdos/Makefile.emx | 69 - Sources/PerfectCZlib/msdos/Makefile.msc | 112 - Sources/PerfectCZlib/msdos/Makefile.tc | 100 - Sources/PerfectCZlib/nintendods/Makefile | 126 - Sources/PerfectCZlib/nintendods/README | 5 - Sources/PerfectCZlib/old/Makefile.emx | 69 - Sources/PerfectCZlib/old/Makefile.riscos | 151 - Sources/PerfectCZlib/old/README | 3 - Sources/PerfectCZlib/old/descrip.mms | 48 - Sources/PerfectCZlib/old/os2/Makefile.os2 | 136 - Sources/PerfectCZlib/old/os2/zlib.def | 51 - Sources/PerfectCZlib/old/visual-basic.txt | 160 - Sources/PerfectCZlib/os400/README400 | 48 - Sources/PerfectCZlib/os400/bndsrc | 119 - Sources/PerfectCZlib/os400/make.sh | 366 - Sources/PerfectCZlib/os400/zlib.inc | 527 - Sources/PerfectCZlib/qnx/package.qpg | 141 - Sources/PerfectCZlib/treebuild.xml | 116 - Sources/PerfectCZlib/trees.c | 1203 -- Sources/PerfectCZlib/trees.h | 128 - Sources/PerfectCZlib/uncompr.c | 93 - Sources/PerfectCZlib/watcom/watcom_f.mak | 43 - Sources/PerfectCZlib/watcom/watcom_l.mak | 43 - Sources/PerfectCZlib/win32/DLL_FAQ.txt | 397 - Sources/PerfectCZlib/win32/Makefile.bor | 110 - Sources/PerfectCZlib/win32/Makefile.gcc | 182 - Sources/PerfectCZlib/win32/Makefile.msc | 163 - Sources/PerfectCZlib/win32/README-WIN32.txt | 103 - Sources/PerfectCZlib/win32/VisualC.txt | 3 - Sources/PerfectCZlib/win32/zlib.def | 94 - Sources/PerfectCZlib/win32/zlib1.rc | 40 - Sources/PerfectCZlib/zconf.h | 534 - Sources/PerfectCZlib/zconf.h.cmakein | 536 - Sources/PerfectCZlib/zconf.h.in | 534 - Sources/PerfectCZlib/zlib.3 | 149 - Sources/PerfectCZlib/zlib.3.pdf | Bin 19422 -> 0 bytes Sources/PerfectCZlib/zlib.h | 1910 -- Sources/PerfectCZlib/zlib.map | 94 - Sources/PerfectCZlib/zlib.pc | 13 - Sources/PerfectCZlib/zlib.pc.cmakein | 13 - Sources/PerfectCZlib/zlib.pc.in | 13 - Sources/PerfectCZlib/zlib2ansi | 152 - Sources/PerfectCZlib/zutil.c | 325 - Sources/PerfectCZlib/zutil.h | 271 - .../PerfectWebSockets/WebSocketHandler.swift | 382 - Sources/cURL/ccurl.c | 0 Sources/cURL/include/module.modulemap | 5 - Sources/cURL/include/p_curl.h | 114 - 492 files changed, 73 insertions(+), 361797 deletions(-) create mode 100644 Package.resolved delete mode 100644 Sources/COpenSSL/LPdir_unix.h delete mode 100644 Sources/COpenSSL/a_.c delete mode 100644 Sources/COpenSSL/aep.h delete mode 100644 Sources/COpenSSL/aes.h delete mode 100644 Sources/COpenSSL/aes_.c delete mode 100644 Sources/COpenSSL/aes_locl.h delete mode 100644 Sources/COpenSSL/ameth_lib.c delete mode 100644 Sources/COpenSSL/asn1.h delete mode 100644 Sources/COpenSSL/asn1_.c delete mode 100644 Sources/COpenSSL/asn1_int.h delete mode 100644 Sources/COpenSSL/asn1_locl.h delete mode 100644 Sources/COpenSSL/asn1_mac.h delete mode 100644 Sources/COpenSSL/asn1t.h delete mode 100644 Sources/COpenSSL/asn_.c delete mode 100644 Sources/COpenSSL/atalla.h delete mode 100644 Sources/COpenSSL/b_dump.c delete mode 100644 Sources/COpenSSL/b_print.c delete mode 100644 Sources/COpenSSL/b_sock.c delete mode 100644 Sources/COpenSSL/bf_.c delete mode 100644 Sources/COpenSSL/bf_locl.h delete mode 100644 Sources/COpenSSL/bf_pi.h delete mode 100644 Sources/COpenSSL/bio.h delete mode 100644 Sources/COpenSSL/bio_.c delete mode 100644 Sources/COpenSSL/bio_lcl.h delete mode 100644 Sources/COpenSSL/blowfish.h delete mode 100644 Sources/COpenSSL/bn.h delete mode 100644 Sources/COpenSSL/bn_.c delete mode 100644 Sources/COpenSSL/bn_int.h delete mode 100644 Sources/COpenSSL/bn_lcl.h delete mode 100644 Sources/COpenSSL/bn_prime.h delete mode 100644 Sources/COpenSSL/bss_.c delete mode 100644 Sources/COpenSSL/buf_.c delete mode 100644 Sources/COpenSSL/buffer.c delete mode 100644 Sources/COpenSSL/buffer.h delete mode 100644 Sources/COpenSSL/buildinf.h delete mode 100644 Sources/COpenSSL/by_.c delete mode 100644 Sources/COpenSSL/c_.c delete mode 100644 Sources/COpenSSL/camellia.c delete mode 100644 Sources/COpenSSL/camellia.h delete mode 100644 Sources/COpenSSL/cast.h delete mode 100644 Sources/COpenSSL/cast_lcl.h delete mode 100644 Sources/COpenSSL/cast_s.h delete mode 100644 Sources/COpenSSL/cbc128.c delete mode 100644 Sources/COpenSSL/cbc3_enc.c delete mode 100644 Sources/COpenSSL/cbc_.c delete mode 100644 Sources/COpenSSL/ccm128.c delete mode 100644 Sources/COpenSSL/cfb128.c delete mode 100644 Sources/COpenSSL/cfb64ede.c delete mode 100644 Sources/COpenSSL/cfb64enc.c delete mode 100644 Sources/COpenSSL/cfb_enc.c delete mode 100644 Sources/COpenSSL/charmap.h delete mode 100644 Sources/COpenSSL/cm_.c delete mode 100644 Sources/COpenSSL/cmac.c delete mode 100644 Sources/COpenSSL/cmac.h delete mode 100644 Sources/COpenSSL/cmll_.c delete mode 100644 Sources/COpenSSL/cmll_locl.h delete mode 100644 Sources/COpenSSL/cms.h delete mode 100644 Sources/COpenSSL/cms_.c delete mode 100644 Sources/COpenSSL/cms_lcl.h delete mode 100644 Sources/COpenSSL/comp.h delete mode 100644 Sources/COpenSSL/comp_.c delete mode 100644 Sources/COpenSSL/conf.h delete mode 100644 Sources/COpenSSL/conf_.c delete mode 100644 Sources/COpenSSL/conf_api.h delete mode 100644 Sources/COpenSSL/conf_def.h delete mode 100644 Sources/COpenSSL/constant_time_locl.h delete mode 100644 Sources/COpenSSL/cpt_err.c delete mode 100644 Sources/COpenSSL/cryptlib.c delete mode 100644 Sources/COpenSSL/cryptlib.h delete mode 100644 Sources/COpenSSL/crypto.h delete mode 100644 Sources/COpenSSL/cswift.h delete mode 100644 Sources/COpenSSL/ctr128.c delete mode 100644 Sources/COpenSSL/cversion.c delete mode 100644 Sources/COpenSSL/d1_.c delete mode 100644 Sources/COpenSSL/d1_lib.c delete mode 100644 Sources/COpenSSL/d2i_.c delete mode 100644 Sources/COpenSSL/des.h delete mode 100644 Sources/COpenSSL/des_enc.c delete mode 100644 Sources/COpenSSL/des_locl.h delete mode 100644 Sources/COpenSSL/des_old.c delete mode 100644 Sources/COpenSSL/des_old.h delete mode 100644 Sources/COpenSSL/des_old2.c delete mode 100644 Sources/COpenSSL/des_ver.h delete mode 100644 Sources/COpenSSL/dh.h delete mode 100644 Sources/COpenSSL/dh_.c delete mode 100644 Sources/COpenSSL/digest.c delete mode 100644 Sources/COpenSSL/dsa.h delete mode 100644 Sources/COpenSSL/dsa_.c delete mode 100644 Sources/COpenSSL/dsa_locl.h delete mode 100644 Sources/COpenSSL/dso.h delete mode 100644 Sources/COpenSSL/dso_.c delete mode 100644 Sources/COpenSSL/dtls1.h delete mode 100644 Sources/COpenSSL/e_4758cca.c delete mode 100644 Sources/COpenSSL/e_4758cca_err.c delete mode 100644 Sources/COpenSSL/e_4758cca_err.h delete mode 100644 Sources/COpenSSL/e_aep.c delete mode 100644 Sources/COpenSSL/e_aep_err.c delete mode 100644 Sources/COpenSSL/e_aep_err.h delete mode 100644 Sources/COpenSSL/e_aes.c delete mode 100644 Sources/COpenSSL/e_aes_cbc_hmac_sha1.c delete mode 100644 Sources/COpenSSL/e_aes_cbc_hmac_sha256.c delete mode 100644 Sources/COpenSSL/e_atalla.c delete mode 100644 Sources/COpenSSL/e_atalla_err.c delete mode 100644 Sources/COpenSSL/e_atalla_err.h delete mode 100644 Sources/COpenSSL/e_bf.c delete mode 100644 Sources/COpenSSL/e_camellia.c delete mode 100644 Sources/COpenSSL/e_capi.c delete mode 100644 Sources/COpenSSL/e_capi_err.c delete mode 100644 Sources/COpenSSL/e_capi_err.h delete mode 100644 Sources/COpenSSL/e_cast.c delete mode 100644 Sources/COpenSSL/e_chil.c delete mode 100644 Sources/COpenSSL/e_chil_err.c delete mode 100644 Sources/COpenSSL/e_chil_err.h delete mode 100644 Sources/COpenSSL/e_cswift.c delete mode 100644 Sources/COpenSSL/e_cswift_err.c delete mode 100644 Sources/COpenSSL/e_cswift_err.h delete mode 100644 Sources/COpenSSL/e_des.c delete mode 100644 Sources/COpenSSL/e_des3.c delete mode 100644 Sources/COpenSSL/e_gmp.c delete mode 100644 Sources/COpenSSL/e_gmp_err.c delete mode 100644 Sources/COpenSSL/e_gmp_err.h delete mode 100644 Sources/COpenSSL/e_gost_err.c delete mode 100644 Sources/COpenSSL/e_gost_err.h delete mode 100644 Sources/COpenSSL/e_idea.c delete mode 100644 Sources/COpenSSL/e_null.c delete mode 100644 Sources/COpenSSL/e_nuron.c delete mode 100644 Sources/COpenSSL/e_nuron_err.c delete mode 100644 Sources/COpenSSL/e_nuron_err.h delete mode 100644 Sources/COpenSSL/e_old.c delete mode 100644 Sources/COpenSSL/e_os.h delete mode 100644 Sources/COpenSSL/e_os2.h delete mode 100644 Sources/COpenSSL/e_padlock.c delete mode 100644 Sources/COpenSSL/e_rc2.c delete mode 100644 Sources/COpenSSL/e_rc4.c delete mode 100644 Sources/COpenSSL/e_rc4_hmac_md5.c delete mode 100644 Sources/COpenSSL/e_rc5.c delete mode 100644 Sources/COpenSSL/e_seed.c delete mode 100644 Sources/COpenSSL/e_sureware.c delete mode 100644 Sources/COpenSSL/e_sureware_err.c delete mode 100644 Sources/COpenSSL/e_sureware_err.h delete mode 100644 Sources/COpenSSL/e_ubsec.c delete mode 100644 Sources/COpenSSL/e_ubsec_err.c delete mode 100644 Sources/COpenSSL/e_ubsec_err.h delete mode 100644 Sources/COpenSSL/e_xcbc_d.c delete mode 100644 Sources/COpenSSL/ebcdic.c delete mode 100644 Sources/COpenSSL/ebcdic.h delete mode 100644 Sources/COpenSSL/ec.h delete mode 100644 Sources/COpenSSL/ec2_.c delete mode 100644 Sources/COpenSSL/ec_.c delete mode 100644 Sources/COpenSSL/ec_lcl.h delete mode 100644 Sources/COpenSSL/ecb3_enc.c delete mode 100644 Sources/COpenSSL/ecb_enc.c delete mode 100644 Sources/COpenSSL/ecdh.h delete mode 100644 Sources/COpenSSL/ecdsa.h delete mode 100644 Sources/COpenSSL/ech_.c delete mode 100644 Sources/COpenSSL/ech_locl.h delete mode 100644 Sources/COpenSSL/eck_prn.c delete mode 100644 Sources/COpenSSL/ecp_mont.c delete mode 100644 Sources/COpenSSL/ecp_nist.c delete mode 100644 Sources/COpenSSL/ecp_nistp224.c delete mode 100644 Sources/COpenSSL/ecp_nistp256.c delete mode 100644 Sources/COpenSSL/ecp_nistp521.c delete mode 100644 Sources/COpenSSL/ecp_nistputil.c delete mode 100644 Sources/COpenSSL/ecp_oct.c delete mode 100644 Sources/COpenSSL/ecp_smpl.c delete mode 100644 Sources/COpenSSL/ecs_.c delete mode 100644 Sources/COpenSSL/ecs_locl.h delete mode 100644 Sources/COpenSSL/ede_cbcm_enc.c delete mode 100644 Sources/COpenSSL/enc_.c delete mode 100644 Sources/COpenSSL/encode.c delete mode 100644 Sources/COpenSSL/eng_.c delete mode 100644 Sources/COpenSSL/eng_int.h delete mode 100644 Sources/COpenSSL/engine.h delete mode 100644 Sources/COpenSSL/err.c delete mode 100644 Sources/COpenSSL/err.h delete mode 100644 Sources/COpenSSL/err_.c delete mode 100644 Sources/COpenSSL/evp.h delete mode 100644 Sources/COpenSSL/evp_.c delete mode 100644 Sources/COpenSSL/evp_locl.h delete mode 100644 Sources/COpenSSL/ex_data.c delete mode 100644 Sources/COpenSSL/ext_dat.h delete mode 100644 Sources/COpenSSL/f_.c delete mode 100644 Sources/COpenSSL/fcrypt.c delete mode 100644 Sources/COpenSSL/fcrypt_b.c delete mode 100644 Sources/COpenSSL/fips_err.h delete mode 100644 Sources/COpenSSL/fips_ers.c delete mode 100644 Sources/COpenSSL/gcm128.c delete mode 100644 Sources/COpenSSL/getenv.c delete mode 100644 Sources/COpenSSL/gost2001.c delete mode 100644 Sources/COpenSSL/gost2001_keyx.c delete mode 100644 Sources/COpenSSL/gost2001_keyx.h delete mode 100644 Sources/COpenSSL/gost89.c delete mode 100644 Sources/COpenSSL/gost89.h delete mode 100644 Sources/COpenSSL/gost94_keyx.c delete mode 100644 Sources/COpenSSL/gost_.c delete mode 100644 Sources/COpenSSL/gost_keywrap.h delete mode 100644 Sources/COpenSSL/gost_lcl.h delete mode 100644 Sources/COpenSSL/gost_params.h delete mode 100644 Sources/COpenSSL/gosthash.c delete mode 100644 Sources/COpenSSL/gosthash.h delete mode 100644 Sources/COpenSSL/hm_.c delete mode 100644 Sources/COpenSSL/hmac.c delete mode 100644 Sources/COpenSSL/hmac.h delete mode 100644 Sources/COpenSSL/hw_4758_cca.h delete mode 100644 Sources/COpenSSL/hw_ubsec.h delete mode 100644 Sources/COpenSSL/hwcryptohook.h delete mode 100644 Sources/COpenSSL/i2d_.c delete mode 100644 Sources/COpenSSL/i_.c delete mode 100644 Sources/COpenSSL/idea.h delete mode 100644 Sources/COpenSSL/idea_lcl.h delete mode 100644 Sources/COpenSSL/include/module.modulemap delete mode 100644 Sources/COpenSSL/include/openssl.h delete mode 100644 Sources/COpenSSL/krb5_asn.c delete mode 100644 Sources/COpenSSL/krb5_asn.h delete mode 100644 Sources/COpenSSL/kssl.c delete mode 100644 Sources/COpenSSL/kssl.h delete mode 100644 Sources/COpenSSL/kssl_lcl.h delete mode 100644 Sources/COpenSSL/lh_stats.c delete mode 100644 Sources/COpenSSL/lhash.c delete mode 100644 Sources/COpenSSL/lhash.h delete mode 100644 Sources/COpenSSL/m_dss.c delete mode 100644 Sources/COpenSSL/m_dss1.c delete mode 100644 Sources/COpenSSL/m_ecdsa.c delete mode 100644 Sources/COpenSSL/m_md2.c delete mode 100644 Sources/COpenSSL/m_md4.c delete mode 100644 Sources/COpenSSL/m_md5.c delete mode 100644 Sources/COpenSSL/m_mdc2.c delete mode 100644 Sources/COpenSSL/m_null.c delete mode 100644 Sources/COpenSSL/m_ripemd.c delete mode 100644 Sources/COpenSSL/m_sha.c delete mode 100644 Sources/COpenSSL/m_sha1.c delete mode 100644 Sources/COpenSSL/m_sigver.c delete mode 100644 Sources/COpenSSL/m_wp.c delete mode 100644 Sources/COpenSSL/md32_common.h delete mode 100644 Sources/COpenSSL/md4.h delete mode 100644 Sources/COpenSSL/md4_.c delete mode 100644 Sources/COpenSSL/md4_locl.h delete mode 100644 Sources/COpenSSL/md5.h delete mode 100644 Sources/COpenSSL/md5_.c delete mode 100644 Sources/COpenSSL/md5_locl.h delete mode 100644 Sources/COpenSSL/md_rand.c delete mode 100644 Sources/COpenSSL/mdc2.h delete mode 100644 Sources/COpenSSL/mdc2_one.c delete mode 100644 Sources/COpenSSL/mdc2dgst.c delete mode 100644 Sources/COpenSSL/mem.c delete mode 100644 Sources/COpenSSL/mem_.c delete mode 100644 Sources/COpenSSL/modes.h delete mode 100644 Sources/COpenSSL/modes_lcl.h delete mode 100644 Sources/COpenSSL/n_pkey.c delete mode 100644 Sources/COpenSSL/names.c delete mode 100644 Sources/COpenSSL/ncbc_enc.h delete mode 100644 Sources/COpenSSL/nsseq.c delete mode 100644 Sources/COpenSSL/o_.c delete mode 100644 Sources/COpenSSL/o_dir.h delete mode 100644 Sources/COpenSSL/o_str.h delete mode 100644 Sources/COpenSSL/o_time.h delete mode 100644 Sources/COpenSSL/obj_.c delete mode 100644 Sources/COpenSSL/obj_dat.h delete mode 100644 Sources/COpenSSL/obj_mac.h delete mode 100644 Sources/COpenSSL/obj_xref.h delete mode 100644 Sources/COpenSSL/objects.h delete mode 100644 Sources/COpenSSL/ocsp.h delete mode 100644 Sources/COpenSSL/ocsp_.c delete mode 100644 Sources/COpenSSL/ofb128.c delete mode 100644 Sources/COpenSSL/ofb64ede.c delete mode 100644 Sources/COpenSSL/ofb64enc.c delete mode 100644 Sources/COpenSSL/ofb_enc.c delete mode 100644 Sources/COpenSSL/openbsd_hw.c delete mode 100644 Sources/COpenSSL/opensslconf.h delete mode 100644 Sources/COpenSSL/opensslv.h delete mode 100644 Sources/COpenSSL/ossl_typ.h delete mode 100644 Sources/COpenSSL/p12_.c delete mode 100644 Sources/COpenSSL/p5_.c delete mode 100644 Sources/COpenSSL/p8_pkey.c delete mode 100644 Sources/COpenSSL/p_.c delete mode 100644 Sources/COpenSSL/pcbc_enc.c delete mode 100644 Sources/COpenSSL/pcy_.c delete mode 100644 Sources/COpenSSL/pcy_int.h delete mode 100644 Sources/COpenSSL/pem.h delete mode 100644 Sources/COpenSSL/pem2.h delete mode 100644 Sources/COpenSSL/pem_.c delete mode 100644 Sources/COpenSSL/pk12err.c delete mode 100644 Sources/COpenSSL/pk7_.c delete mode 100644 Sources/COpenSSL/pk7_enc.h delete mode 100644 Sources/COpenSSL/pkcs12.h delete mode 100644 Sources/COpenSSL/pkcs7.h delete mode 100644 Sources/COpenSSL/pkcs7err.c delete mode 100644 Sources/COpenSSL/pmeth_.c delete mode 100644 Sources/COpenSSL/pqueue.c delete mode 100644 Sources/COpenSSL/pqueue.h delete mode 100644 Sources/COpenSSL/pvkfmt.c delete mode 100644 Sources/COpenSSL/qud_cksm.c delete mode 100644 Sources/COpenSSL/rand.h delete mode 100644 Sources/COpenSSL/rand_.c delete mode 100644 Sources/COpenSSL/rand_lcl.h delete mode 100644 Sources/COpenSSL/randfile.c delete mode 100644 Sources/COpenSSL/rc2.h delete mode 100644 Sources/COpenSSL/rc2_.c delete mode 100644 Sources/COpenSSL/rc2_locl.h delete mode 100644 Sources/COpenSSL/rc2cfb64.c delete mode 100644 Sources/COpenSSL/rc2ofb64.c delete mode 100644 Sources/COpenSSL/rc4.h delete mode 100644 Sources/COpenSSL/rc4_.c delete mode 100644 Sources/COpenSSL/rc4_locl.h delete mode 100644 Sources/COpenSSL/read2pwd.c delete mode 100644 Sources/COpenSSL/ripemd.h delete mode 100644 Sources/COpenSSL/rmd_.c delete mode 100644 Sources/COpenSSL/rmd_locl.h delete mode 100644 Sources/COpenSSL/rmdconst.h delete mode 100644 Sources/COpenSSL/rpc_des.h delete mode 100644 Sources/COpenSSL/rpc_enc.c delete mode 100644 Sources/COpenSSL/rsa.h delete mode 100644 Sources/COpenSSL/rsa_.c delete mode 100644 Sources/COpenSSL/rsa_locl.h delete mode 100644 Sources/COpenSSL/rsaz_exp.c delete mode 100644 Sources/COpenSSL/rsaz_exp.h delete mode 100644 Sources/COpenSSL/s23_.c delete mode 100644 Sources/COpenSSL/s2_.c delete mode 100644 Sources/COpenSSL/s3_.c delete mode 100644 Sources/COpenSSL/safestack.h delete mode 100644 Sources/COpenSSL/seed.c delete mode 100644 Sources/COpenSSL/seed.h delete mode 100644 Sources/COpenSSL/seed_.c delete mode 100644 Sources/COpenSSL/seed_locl.h delete mode 100644 Sources/COpenSSL/set_key.c delete mode 100644 Sources/COpenSSL/sha.h delete mode 100644 Sources/COpenSSL/sha1_one.c delete mode 100644 Sources/COpenSSL/sha1dgst.c delete mode 100644 Sources/COpenSSL/sha256.c delete mode 100644 Sources/COpenSSL/sha512.c delete mode 100644 Sources/COpenSSL/sha_.c delete mode 100644 Sources/COpenSSL/sha_locl.h delete mode 100644 Sources/COpenSSL/spr.h delete mode 100644 Sources/COpenSSL/srp.h delete mode 100644 Sources/COpenSSL/srp_.c delete mode 100644 Sources/COpenSSL/srp_grps.h delete mode 100644 Sources/COpenSSL/srp_lcl.h delete mode 100644 Sources/COpenSSL/srtp.h delete mode 100644 Sources/COpenSSL/ssl.h delete mode 100644 Sources/COpenSSL/ssl2.h delete mode 100644 Sources/COpenSSL/ssl23.h delete mode 100644 Sources/COpenSSL/ssl3.h delete mode 100644 Sources/COpenSSL/ssl_.c delete mode 100644 Sources/COpenSSL/ssl_locl.h delete mode 100644 Sources/COpenSSL/stack.c delete mode 100644 Sources/COpenSSL/stack.h delete mode 100644 Sources/COpenSSL/str2key.c delete mode 100644 Sources/COpenSSL/sureware.h delete mode 100644 Sources/COpenSSL/symhacks.h delete mode 100644 Sources/COpenSSL/t1_.c delete mode 100644 Sources/COpenSSL/t_.c delete mode 100644 Sources/COpenSSL/tasn_.c delete mode 100644 Sources/COpenSSL/tb_asnmth.c delete mode 100644 Sources/COpenSSL/tb_cipher.c delete mode 100644 Sources/COpenSSL/tb_dh.c delete mode 100644 Sources/COpenSSL/tb_digest.c delete mode 100644 Sources/COpenSSL/tb_dsa.c delete mode 100644 Sources/COpenSSL/tb_ecdh.c delete mode 100644 Sources/COpenSSL/tb_ecdsa.c delete mode 100644 Sources/COpenSSL/tb_pkmeth.c delete mode 100644 Sources/COpenSSL/tb_rand.c delete mode 100644 Sources/COpenSSL/tb_rsa.c delete mode 100644 Sources/COpenSSL/tb_store.c delete mode 100644 Sources/COpenSSL/th-lock.c delete mode 100644 Sources/COpenSSL/tls1.h delete mode 100644 Sources/COpenSSL/tls_srp.c delete mode 100644 Sources/COpenSSL/ts.h delete mode 100644 Sources/COpenSSL/ts_.c delete mode 100644 Sources/COpenSSL/txt_db.c delete mode 100644 Sources/COpenSSL/txt_db.h delete mode 100644 Sources/COpenSSL/ui.h delete mode 100644 Sources/COpenSSL/ui_.c delete mode 100644 Sources/COpenSSL/ui_compat.h delete mode 100644 Sources/COpenSSL/ui_locl.h delete mode 100644 Sources/COpenSSL/uid.c delete mode 100644 Sources/COpenSSL/v3_.c delete mode 100644 Sources/COpenSSL/v3_lib.c delete mode 100644 Sources/COpenSSL/v3err.c delete mode 100644 Sources/COpenSSL/vpm_int.h delete mode 100644 Sources/COpenSSL/whrlpool.h delete mode 100644 Sources/COpenSSL/wp_.c delete mode 100644 Sources/COpenSSL/wp_locl.h delete mode 100644 Sources/COpenSSL/wrap128.c delete mode 100644 Sources/COpenSSL/x509.h delete mode 100644 Sources/COpenSSL/x509_.c delete mode 100644 Sources/COpenSSL/x509_vfy.h delete mode 100644 Sources/COpenSSL/x509cset.c delete mode 100644 Sources/COpenSSL/x509name.c delete mode 100644 Sources/COpenSSL/x509rset.c delete mode 100644 Sources/COpenSSL/x509spki.c delete mode 100644 Sources/COpenSSL/x509type.c delete mode 100644 Sources/COpenSSL/x509v3.h delete mode 100644 Sources/COpenSSL/x_.c delete mode 100644 Sources/COpenSSL/xcbc_enc.c delete mode 100644 Sources/COpenSSL/xts128.c delete mode 100644 Sources/LinuxBridge/LinuxBridge.c delete mode 100644 Sources/LinuxBridge/include/LinuxBridge.h delete mode 100644 Sources/PerfectCZlib/CMakeLists.txt delete mode 100644 Sources/PerfectCZlib/ChangeLog delete mode 100644 Sources/PerfectCZlib/FAQ delete mode 100644 Sources/PerfectCZlib/INDEX delete mode 100644 Sources/PerfectCZlib/Makefile delete mode 100644 Sources/PerfectCZlib/Makefile.in delete mode 100644 Sources/PerfectCZlib/README delete mode 100644 Sources/PerfectCZlib/adler32.c delete mode 100644 Sources/PerfectCZlib/amiga/Makefile.pup delete mode 100644 Sources/PerfectCZlib/amiga/Makefile.sas delete mode 100644 Sources/PerfectCZlib/compress.c delete mode 100755 Sources/PerfectCZlib/configure delete mode 100644 Sources/PerfectCZlib/configure.log delete mode 100644 Sources/PerfectCZlib/crc32.c delete mode 100644 Sources/PerfectCZlib/crc32.h delete mode 100644 Sources/PerfectCZlib/deflate.c delete mode 100644 Sources/PerfectCZlib/deflate.h delete mode 100644 Sources/PerfectCZlib/doc/algorithm.txt delete mode 100644 Sources/PerfectCZlib/doc/rfc1950.txt delete mode 100644 Sources/PerfectCZlib/doc/rfc1951.txt delete mode 100644 Sources/PerfectCZlib/doc/rfc1952.txt delete mode 100644 Sources/PerfectCZlib/doc/txtvsbin.txt delete mode 100644 Sources/PerfectCZlib/gzclose.c delete mode 100644 Sources/PerfectCZlib/gzguts.h delete mode 100644 Sources/PerfectCZlib/gzlib.c delete mode 100644 Sources/PerfectCZlib/gzread.c delete mode 100644 Sources/PerfectCZlib/gzwrite.c delete mode 100755 Sources/PerfectCZlib/include/czlib.h delete mode 100644 Sources/PerfectCZlib/include/inflate.h delete mode 100644 Sources/PerfectCZlib/include/inftrees.h delete mode 100644 Sources/PerfectCZlib/include/module.modulemap delete mode 100644 Sources/PerfectCZlib/include/zconf.h delete mode 100644 Sources/PerfectCZlib/include/zlib.h delete mode 100644 Sources/PerfectCZlib/infback.c delete mode 100644 Sources/PerfectCZlib/inffast.c delete mode 100644 Sources/PerfectCZlib/inffast.h delete mode 100644 Sources/PerfectCZlib/inffixed.h delete mode 100644 Sources/PerfectCZlib/inflate.c delete mode 100644 Sources/PerfectCZlib/inflate.h delete mode 100644 Sources/PerfectCZlib/inftrees.c delete mode 100644 Sources/PerfectCZlib/inftrees.h delete mode 100644 Sources/PerfectCZlib/make_vms.com delete mode 100644 Sources/PerfectCZlib/msdos/Makefile.bor delete mode 100644 Sources/PerfectCZlib/msdos/Makefile.dj2 delete mode 100644 Sources/PerfectCZlib/msdos/Makefile.emx delete mode 100644 Sources/PerfectCZlib/msdos/Makefile.msc delete mode 100644 Sources/PerfectCZlib/msdos/Makefile.tc delete mode 100644 Sources/PerfectCZlib/nintendods/Makefile delete mode 100644 Sources/PerfectCZlib/nintendods/README delete mode 100644 Sources/PerfectCZlib/old/Makefile.emx delete mode 100644 Sources/PerfectCZlib/old/Makefile.riscos delete mode 100644 Sources/PerfectCZlib/old/README delete mode 100644 Sources/PerfectCZlib/old/descrip.mms delete mode 100644 Sources/PerfectCZlib/old/os2/Makefile.os2 delete mode 100644 Sources/PerfectCZlib/old/os2/zlib.def delete mode 100644 Sources/PerfectCZlib/old/visual-basic.txt delete mode 100644 Sources/PerfectCZlib/os400/README400 delete mode 100644 Sources/PerfectCZlib/os400/bndsrc delete mode 100644 Sources/PerfectCZlib/os400/make.sh delete mode 100644 Sources/PerfectCZlib/os400/zlib.inc delete mode 100644 Sources/PerfectCZlib/qnx/package.qpg delete mode 100644 Sources/PerfectCZlib/treebuild.xml delete mode 100644 Sources/PerfectCZlib/trees.c delete mode 100644 Sources/PerfectCZlib/trees.h delete mode 100644 Sources/PerfectCZlib/uncompr.c delete mode 100644 Sources/PerfectCZlib/watcom/watcom_f.mak delete mode 100644 Sources/PerfectCZlib/watcom/watcom_l.mak delete mode 100644 Sources/PerfectCZlib/win32/DLL_FAQ.txt delete mode 100644 Sources/PerfectCZlib/win32/Makefile.bor delete mode 100644 Sources/PerfectCZlib/win32/Makefile.gcc delete mode 100644 Sources/PerfectCZlib/win32/Makefile.msc delete mode 100644 Sources/PerfectCZlib/win32/README-WIN32.txt delete mode 100644 Sources/PerfectCZlib/win32/VisualC.txt delete mode 100644 Sources/PerfectCZlib/win32/zlib.def delete mode 100644 Sources/PerfectCZlib/win32/zlib1.rc delete mode 100644 Sources/PerfectCZlib/zconf.h delete mode 100644 Sources/PerfectCZlib/zconf.h.cmakein delete mode 100644 Sources/PerfectCZlib/zconf.h.in delete mode 100644 Sources/PerfectCZlib/zlib.3 delete mode 100644 Sources/PerfectCZlib/zlib.3.pdf delete mode 100644 Sources/PerfectCZlib/zlib.h delete mode 100644 Sources/PerfectCZlib/zlib.map delete mode 100644 Sources/PerfectCZlib/zlib.pc delete mode 100644 Sources/PerfectCZlib/zlib.pc.cmakein delete mode 100644 Sources/PerfectCZlib/zlib.pc.in delete mode 100755 Sources/PerfectCZlib/zlib2ansi delete mode 100644 Sources/PerfectCZlib/zutil.c delete mode 100644 Sources/PerfectCZlib/zutil.h delete mode 100644 Sources/PerfectWebSockets/WebSocketHandler.swift delete mode 100644 Sources/cURL/ccurl.c delete mode 100644 Sources/cURL/include/module.modulemap delete mode 100644 Sources/cURL/include/p_curl.h diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 00000000..55185125 --- /dev/null +++ b/Package.resolved @@ -0,0 +1,32 @@ +{ + "pins" : [ + { + "identity" : "perfect-copenssl", + "kind" : "remoteSourceControl", + "location" : "https://github.com/PerfectlySoft/Perfect-COpenSSL.git", + "state" : { + "revision" : "ce3113e159b8c6d8565e5d8db2672b572c81aea9", + "version" : "4.0.2" + } + }, + { + "identity" : "perfect-czlib-src", + "kind" : "remoteSourceControl", + "location" : "https://github.com/PerfectlySoft/Perfect-CZlib-src.git", + "state" : { + "revision" : "b63e46909aad937c6434766f8f8c6720d8f3bd05", + "version" : "0.0.4" + } + }, + { + "identity" : "perfect-libcurl", + "kind" : "remoteSourceControl", + "location" : "https://github.com/PerfectlySoft/Perfect-libcurl.git", + "state" : { + "revision" : "b3d7e65ef5c27c0a027cdc621f34835975301bf1", + "version" : "2.1.0" + } + } + ], + "version" : 2 +} diff --git a/Package.swift b/Package.swift index 71079959..a959f6f3 100644 --- a/Package.swift +++ b/Package.swift @@ -3,36 +3,24 @@ import PackageDescription -let czLibExcludes: [String] = [ - "CMakeLists.txt", "ChangeLog", "FAQ", "INDEX", - "Makefile", "Makefile.in", "README", - "amiga/Makefile.pup", "amiga/Makefile.sas", "configure", "configure.log", - "doc/algorithm.txt", "doc/rfc1950.txt", "doc/rfc1951.txt", - "doc/rfc1952.txt", "doc/txtvsbin.txt", "make_vms.com", - "msdos/Makefile.bor", "msdos/Makefile.dj2", - "msdos/Makefile.emx", "msdos/Makefile.msc", "msdos/Makefile.tc", - "nintendods/Makefile", "nintendods/README", - "old/Makefile.emx", "old/Makefile.riscos", "old/README", - "old/descrip.mms", "old/os2/Makefile.os2", "old/visual-basic.txt", - "os400/README400", "os400/bndsrc", "os400/make.sh", "os400/zlib.inc", - "qnx/package.qpg", "treebuild.xml", - "watcom/watcom_f.mak", "watcom/watcom_l.mak", - "win32/DLL_FAQ.txt", "win32/Makefile.bor", "win32/Makefile.gcc", - "win32/Makefile.msc", "win32/README-WIN32.txt", - "win32/VisualC.txt", "win32/zlib1.rc", - "zconf.h.cmakein", "zconf.h.in", "zlib.3", "zlib.3.pdf", - "zlib.map", "zlib.pc", "zlib.pc.cmakein", "zlib.pc.in", "zlib2ansi" +#if os(Linux) +let pkdep: [Package.Dependency] = [ + .package(url: "https://github.com/PerfectlySoft/Perfect-LinuxBridge.git", from: "3.1.0"), + .package(url: "https://github.com/PerfectlySoft/Perfect-sqlite3-support.git", from: "3.1.1") ] -#if os(Linux) -let osdep: [Target.Dependency] = ["LinuxBridge"] -let ostag: [Target] = [.target(name: "LinuxBridge"), .target(name: "PerfectCSQLite3")] -let sqldep: [Target.Dependency] = ["PerfectCSQLite3", "PerfectCRUD"] +let sqlite3dep: [Target.Dependency] = [ + .product(name: "PerfectCSQLite3", package: "Perfect-sqlite3-support") +] + +let osdep: [Target.Dependency] = sqlite3dep + [.product(name: "LinuxBridge", package: "Perfect-LinuxBridge")] +let sqldep: [Target.Dependency] = sqlite3dep + [.init(stringLiteral: "PerfectCRUD")] #else +let pkdep: [Package.Dependency] = [] let osdep: [Target.Dependency] = [] -let ostag: [Target] = [] let sqldep: [Target.Dependency] = ["PerfectCRUD"] #endif + let package = Package( name: "Perfect", products: [ @@ -48,29 +36,44 @@ let package = Package( .library(name: "PerfectSMTP", targets: ["PerfectSMTP"]), .library(name: "PerfectSQLite", targets: ["PerfectSQLite"]), .library(name: "PerfectThread", targets: ["PerfectThread"]), - .library(name: "PerfectWebSockets", targets: ["PerfectWebSockets"]), .executable(name: "httpd", targets: ["httpd"]) ], - dependencies: [ ], - targets: ostag + [ - .target(name: "COpenSSL"), - .target(name: "cURL"), + dependencies: pkdep + [ + .package(url: "https://github.com/PerfectlySoft/Perfect-libcurl.git", from: "2.0.0"), + .package(url: "https://github.com/PerfectlySoft/Perfect-COpenSSL.git", from: "4.0.2"), + .package(url: "https://github.com/PerfectlySoft/Perfect-CZlib-src.git", from: "0.0.4") + ], + targets: [ .target(name: "PerfectAuth", dependencies: ["PerfectCrypto", "PerfectCRUD", "PerfectSQLite"]), - .target(name: "PerfectCZlib", exclude: czLibExcludes), .target(name: "PerfectCHTTPParser"), .target(name: "PerfectLib", dependencies: osdep), .target(name: "PerfectThread", dependencies: osdep), .target(name: "PerfectCRUD"), - .target(name: "PerfectCrypto", dependencies: ["PerfectLib", "PerfectThread", "COpenSSL"]), - .target(name: "PerfectCURL", dependencies: ["cURL", "PerfectLib", "PerfectThread"]), + .target(name: "PerfectCrypto", dependencies: [ + .init(stringLiteral: "PerfectLib"), + .init(stringLiteral: "PerfectThread"), + .product(name: "COpenSSL", package: "Perfect-COpenSSL") + ]), + .target(name: "PerfectCURL", dependencies: [ + .product(name: "cURL", package: "Perfect-libcurl"), + .init(stringLiteral: "PerfectLib"), + .init(stringLiteral: "PerfectThread") + ]), .target(name: "PerfectHTTP", dependencies: ["PerfectLib", "PerfectNet"]), - .target(name: "PerfectHTTPServer", dependencies: ["PerfectCHTTPParser", "PerfectNet", "PerfectHTTP", "PerfectCZlib"]), + .target(name: "PerfectHTTPServer", dependencies: [ + .init(stringLiteral: "PerfectCHTTPParser"), + .init(stringLiteral: "PerfectCrypto"), + .init(stringLiteral: "PerfectNet"), + .init(stringLiteral: "PerfectHTTP"), + .product(name: "PerfectCZlib", package: "Perfect-CZlib-src") + ]), .target(name: "PerfectMustache", dependencies: ["PerfectLib"]), .target(name: "PerfectNet", dependencies: ["PerfectCrypto", "PerfectThread"]), .target(name: "PerfectSMTP", dependencies: ["PerfectCURL", "PerfectCrypto", "PerfectHTTP"]), .target(name: "PerfectSQLite", dependencies: sqldep), - .target(name: "PerfectWebSockets", dependencies: ["PerfectHTTP"]), - .testTarget(name: "PerfectAuthTests", dependencies: ["PerfectAuth", "PerfectCRUD", "PerfectLib", "PerfectSQLite"]), + .testTarget(name: "PerfectAuthTests", dependencies: [ + "PerfectAuth", "PerfectCRUD", "PerfectCrypto", "PerfectLib", "PerfectSQLite" + ]), .testTarget(name: "PerfectCryptoTests", dependencies: ["PerfectCrypto"]), .testTarget(name: "PerfectCURLTests", dependencies: ["PerfectCURL"]), .testTarget(name: "PerfectHTTPTests", dependencies: ["PerfectHTTP"]), @@ -82,8 +85,8 @@ let package = Package( .testTarget(name: "PerfectSQLiteTests", dependencies: ["PerfectSQLite"]), .testTarget(name: "PerfectThreadTests", dependencies: ["PerfectThread"]), .executableTarget(name: "httpd", dependencies: [ - "PerfectAuth", "PerfectLib", "PerfectHTTPServer", "PerfectHTTP", - "PerfectMustache", "PerfectSMTP", "PerfectSQLite" + "PerfectAuth", "PerfectCrypto", "PerfectLib", "PerfectHTTPServer", "PerfectHTTP", + "PerfectMustache", "PerfectSMTP", "PerfectSQLite" ]) ] ) diff --git a/README.md b/README.md index 94c7d2c9..42279e9b 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,6 @@ Your Perfect project can be deployed to any Swift compatible Linux server. We pr Our library continues to grow as members of [the Swift-Perfect development community have shared many samples and examples](https://github.com/PerfectExamples) of their projects in Perfect. Examples include: -- [WebSockets Server](https://github.com/PerfectExamples/PerfectExample-WebSocketsServer) - [URL Routing](https://github.com/PerfectExamples/PerfectExample-URLRouting) - [Upload Enumerator](https://github.com/PerfectExamples/PerfectExample-UploadEnumerator) @@ -103,7 +102,6 @@ Perfect project is divided into several repositories to make it easy for you to - [Perfect HTTP Server](https://github.com/PerfectlySoft/Perfect-HTTPServer) - HTTP 1.1 server for Perfect - [Perfect Mustache](https://github.com/PerfectlySoft/Perfect-Mustache) - Mustache template support for Perfect - [Perfect CURL](https://github.com/PerfectlySoft/Perfect-CURL) - cURL support for Perfect -- [Perfect WebSockets](https://github.com/PerfectlySoft/Perfect-WebSockets) - WebSockets support for Perfect - [Perfect Zip](https://github.com/PerfectlySoft/Perfect-Zip) - provides simple zip and unzip functionality - [Perfect Notifications](https://github.com/PerfectlySoft/Perfect-Notifications) - provides support for Apple Push Notification Service (APNS). @@ -111,7 +109,7 @@ Perfect project is divided into several repositories to make it easy for you to Perfect operates using either a standalone [HTTP server](https://github.com/PerfectlySoft/Perfect-HTTP), [HTTPS server](https://github.com/PerfectlySoft/Perfect-HTTPServer), or through [FastCGI server](https://github.com/PerfectlySoft/Perfect-FastCGI). It provides a system for loading your Swift-based modules at startup, for interfacing those modules with its request/response objects, or to the built-in [Mustache template processing system](https://github.com/PerfectlySoft/Perfect-Mustache). -Perfect is built on a completely asynchronous, high-performance networking engine to provide a scalable option for internet services. It supports Secure Sockets Layer (SSL) encryption, and it features a suite of tools commonly required by internet servers such as [WebSockets](https://github.com/PerfectlySoft/Perfect-WebSockets) and [iOS push notifications](https://github.com/PerfectlySoft/Perfect-Notifications), but you are not limited to those options. +Perfect is built on a completely asynchronous, high-performance networking engine to provide a scalable option for internet services. It supports Secure Sockets Layer (SSL) encryption, and it features a suite of tools commonly required by internet servers such as [iOS push notifications](https://github.com/PerfectlySoft/Perfect-Notifications), but you are not limited to those options. Feel free to use your favourite JSON or templating systems, etc. diff --git a/Sources/COpenSSL/LPdir_unix.h b/Sources/COpenSSL/LPdir_unix.h deleted file mode 100644 index c97e2604..00000000 --- a/Sources/COpenSSL/LPdir_unix.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2004, Richard Levitte - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#ifndef LPDIR_H -# include "LPdir.h" -#endif - -/* - * The POSIXly macro for the maximum number of characters in a file path is - * NAME_MAX. However, some operating systems use PATH_MAX instead. - * Therefore, it seems natural to first check for PATH_MAX and use that, and - * if it doesn't exist, use NAME_MAX. - */ -#if defined(PATH_MAX) -# define LP_ENTRY_SIZE PATH_MAX -#elif defined(NAME_MAX) -# define LP_ENTRY_SIZE NAME_MAX -#endif - -/* - * Of course, there's the possibility that neither PATH_MAX nor NAME_MAX - * exist. It's also possible that NAME_MAX exists but is define to a very - * small value (HP-UX offers 14), so we need to check if we got a result, and - * if it meets a minimum standard, and create or change it if not. - */ -#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255 -# undef LP_ENTRY_SIZE -# define LP_ENTRY_SIZE 255 -#endif - -struct LP_dir_context_st { - DIR *dir; - char entry_name[LP_ENTRY_SIZE + 1]; -}; - -const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) -{ - struct dirent *direntry = NULL; - - if (ctx == NULL || directory == NULL) { - errno = EINVAL; - return 0; - } - - errno = 0; - if (*ctx == NULL) { - *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); - if (*ctx == NULL) { - errno = ENOMEM; - return 0; - } - memset(*ctx, '\0', sizeof(LP_DIR_CTX)); - - (*ctx)->dir = opendir(directory); - if ((*ctx)->dir == NULL) { - int save_errno = errno; /* Probably not needed, but I'm paranoid */ - free(*ctx); - *ctx = NULL; - errno = save_errno; - return 0; - } - } - - direntry = readdir((*ctx)->dir); - if (direntry == NULL) { - return 0; - } - - strncpy((*ctx)->entry_name, direntry->d_name, - sizeof((*ctx)->entry_name) - 1); - (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; - return (*ctx)->entry_name; -} - -int LP_find_file_end(LP_DIR_CTX **ctx) -{ - if (ctx != NULL && *ctx != NULL) { - int ret = closedir((*ctx)->dir); - - free(*ctx); - switch (ret) { - case 0: - return 1; - case -1: - return 0; - default: - break; - } - } - errno = EINVAL; - return 0; -} diff --git a/Sources/COpenSSL/a_.c b/Sources/COpenSSL/a_.c deleted file mode 100644 index 50119ff6..00000000 --- a/Sources/COpenSSL/a_.c +++ /dev/null @@ -1,6179 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/asn1/a_bitstr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "cryptlib.h" -#include "asn1.h" - -int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) -{ - return M_ASN1_BIT_STRING_set(x, d, len); -} - -int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) -{ - int ret, j, bits, len; - unsigned char *p, *d; - - if (a == NULL) - return (0); - - len = a->length; - - if (len > 0) { - if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) { - bits = (int)a->flags & 0x07; - } else { - for (; len > 0; len--) { - if (a->data[len - 1]) - break; - } - j = a->data[len - 1]; - if (j & 0x01) - bits = 0; - else if (j & 0x02) - bits = 1; - else if (j & 0x04) - bits = 2; - else if (j & 0x08) - bits = 3; - else if (j & 0x10) - bits = 4; - else if (j & 0x20) - bits = 5; - else if (j & 0x40) - bits = 6; - else if (j & 0x80) - bits = 7; - else - bits = 0; /* should not happen */ - } - } else - bits = 0; - - ret = 1 + len; - if (pp == NULL) - return (ret); - - p = *pp; - - *(p++) = (unsigned char)bits; - d = a->data; - if (len > 0) { - memcpy(p, d, len); - p += len; - p[-1] &= (0xff << bits); - } - *pp = p; - return (ret); -} - -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, - const unsigned char **pp, long len) -{ - ASN1_BIT_STRING *ret = NULL; - const unsigned char *p; - unsigned char *s; - int i; - - if (len < 1) { - i = ASN1_R_STRING_TOO_SHORT; - goto err; - } - - if (len > INT_MAX) { - i = ASN1_R_STRING_TOO_LONG; - goto err; - } - - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = M_ASN1_BIT_STRING_new()) == NULL) - return (NULL); - } else - ret = (*a); - - p = *pp; - i = *(p++); - if (i > 7) { - i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT; - goto err; - } - /* - * We do this to preserve the settings. If we modify the settings, via - * the _set_bit function, we will recalculate on output - */ - ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ - ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */ - - if (len-- > 1) { /* using one because of the bits left byte */ - s = (unsigned char *)OPENSSL_malloc((int)len); - if (s == NULL) { - i = ERR_R_MALLOC_FAILURE; - goto err; - } - memcpy(s, p, (int)len); - s[len - 1] &= (0xff << i); - p += len; - } else - s = NULL; - - ret->length = (int)len; - if (ret->data != NULL) - OPENSSL_free(ret->data); - ret->data = s; - ret->type = V_ASN1_BIT_STRING; - if (a != NULL) - (*a) = ret; - *pp = p; - return (ret); - err: - ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - M_ASN1_BIT_STRING_free(ret); - return (NULL); -} - -/* - * These next 2 functions from Goetz Babin-Ebell - */ -int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) -{ - int w, v, iv; - unsigned char *c; - - w = n / 8; - v = 1 << (7 - (n & 0x07)); - iv = ~v; - if (!value) - v = 0; - - if (a == NULL) - return 0; - - a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ - - if ((a->length < (w + 1)) || (a->data == NULL)) { - if (!value) - return (1); /* Don't need to set */ - if (a->data == NULL) - c = (unsigned char *)OPENSSL_malloc(w + 1); - else - c = (unsigned char *)OPENSSL_realloc_clean(a->data, - a->length, w + 1); - if (c == NULL) { - ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE); - return 0; - } - if (w + 1 - a->length > 0) - memset(c + a->length, 0, w + 1 - a->length); - a->data = c; - a->length = w + 1; - } - a->data[w] = ((a->data[w]) & iv) | v; - while ((a->length > 0) && (a->data[a->length - 1] == 0)) - a->length--; - return (1); -} - -int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n) -{ - int w, v; - - w = n / 8; - v = 1 << (7 - (n & 0x07)); - if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) - return (0); - return ((a->data[w] & v) != 0); -} - -/* - * Checks if the given bit string contains only bits specified by - * the flags vector. Returns 0 if there is at least one bit set in 'a' - * which is not specified in 'flags', 1 otherwise. - * 'len' is the length of 'flags'. - */ -int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, - unsigned char *flags, int flags_len) -{ - int i, ok; - /* Check if there is one bit set at all. */ - if (!a || !a->data) - return 1; - - /* - * Check each byte of the internal representation of the bit string. - */ - ok = 1; - for (i = 0; i < a->length && ok; ++i) { - unsigned char mask = i < flags_len ? ~flags[i] : 0xff; - /* We are done if there is an unneeded bit set. */ - ok = (a->data[i] & mask) == 0; - } - return ok; -} -/* crypto/asn1/a_bool.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "asn1t.h" - -int i2d_ASN1_BOOLEAN(int a, unsigned char **pp) -{ - int r; - unsigned char *p, *allocated = NULL; - - r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN); - if (pp == NULL) - return (r); - - if (*pp == NULL) { - if ((p = allocated = OPENSSL_malloc(r)) == NULL) { - ASN1err(ASN1_F_I2D_ASN1_BOOLEAN, ERR_R_MALLOC_FAILURE); - return 0; - } - } else { - p = *pp; - } - - ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL); - *p = (unsigned char)a; - - - /* - * If a new buffer was allocated, just return it back. - * If not, return the incremented buffer pointer. - */ - *pp = allocated != NULL ? allocated : p + 1; - return r; -} - -int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length) -{ - int ret = -1; - const unsigned char *p; - long len; - int inf, tag, xclass; - int i = 0; - - p = *pp; - inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) { - i = ASN1_R_BAD_OBJECT_HEADER; - goto err; - } - - if (tag != V_ASN1_BOOLEAN) { - i = ASN1_R_EXPECTING_A_BOOLEAN; - goto err; - } - - if (len != 1) { - i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH; - goto err; - } - ret = (int)*(p++); - if (a != NULL) - (*a) = ret; - *pp = p; - return (ret); - err: - ASN1err(ASN1_F_D2I_ASN1_BOOLEAN, i); - return (ret); -} -/* crypto/asn1/a_bytes.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" - -static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c, - int depth); -static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a, - const unsigned char **pp, long length, - int Ptag, int Pclass, int depth, - int *perr); -/* - * type is a 'bitmap' of acceptable string types. - */ -ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, - long length, int type) -{ - ASN1_STRING *ret = NULL; - const unsigned char *p; - unsigned char *s; - long len; - int inf, tag, xclass; - int i = 0; - - p = *pp; - inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) - goto err; - - if (tag >= 32) { - i = ASN1_R_TAG_VALUE_TOO_HIGH; - goto err; - } - if (!(ASN1_tag2bit(tag) & type)) { - i = ASN1_R_WRONG_TYPE; - goto err; - } - - /* If a bit-string, exit early */ - if (tag == V_ASN1_BIT_STRING) - return (d2i_ASN1_BIT_STRING(a, pp, length)); - - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = ASN1_STRING_new()) == NULL) - return (NULL); - } else - ret = (*a); - - if (len != 0) { - s = OPENSSL_malloc((int)len + 1); - if (s == NULL) { - i = ERR_R_MALLOC_FAILURE; - goto err; - } - memcpy(s, p, (int)len); - s[len] = '\0'; - p += len; - } else - s = NULL; - - if (ret->data != NULL) - OPENSSL_free(ret->data); - ret->length = (int)len; - ret->data = s; - ret->type = tag; - if (a != NULL) - (*a) = ret; - *pp = p; - return (ret); - err: - ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - ASN1_STRING_free(ret); - return (NULL); -} - -int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass) -{ - int ret, r, constructed; - unsigned char *p; - - if (a == NULL) - return (0); - - if (tag == V_ASN1_BIT_STRING) - return (i2d_ASN1_BIT_STRING(a, pp)); - - ret = a->length; - r = ASN1_object_size(0, ret, tag); - if (pp == NULL) - return (r); - p = *pp; - - if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET)) - constructed = 1; - else - constructed = 0; - ASN1_put_object(&p, constructed, ret, tag, xclass); - memcpy(p, a->data, a->length); - p += a->length; - *pp = p; - return (r); -} - -/* - * Maximum recursion depth of d2i_ASN1_bytes(): much more than should be - * encountered in pratice. - */ - -#define ASN1_BYTES_MAXDEPTH 20 - -ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, - long length, int Ptag, int Pclass) -{ - int err = 0; - ASN1_STRING *s = int_d2i_ASN1_bytes(a, pp, length, Ptag, Pclass, 0, &err); - if (err != 0) - ASN1err(ASN1_F_D2I_ASN1_BYTES, err); - return s; -} - -static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a, - const unsigned char **pp, long length, - int Ptag, int Pclass, - int depth, int *perr) -{ - ASN1_STRING *ret = NULL; - const unsigned char *p; - unsigned char *s; - long len; - int inf, tag, xclass; - - if (depth > ASN1_BYTES_MAXDEPTH) { - *perr = ASN1_R_NESTED_ASN1_STRING; - return NULL; - } - - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = ASN1_STRING_new()) == NULL) - return (NULL); - } else - ret = (*a); - - p = *pp; - inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) { - *perr = ASN1_R_BAD_OBJECT_HEADER; - goto err; - } - - if (tag != Ptag) { - *perr = ASN1_R_WRONG_TAG; - goto err; - } - - if (inf & V_ASN1_CONSTRUCTED) { - ASN1_const_CTX c; - - c.error = 0; - c.pp = pp; - c.p = p; - c.inf = inf; - c.slen = len; - c.tag = Ptag; - c.xclass = Pclass; - c.max = (length == 0) ? 0 : (p + length); - if (!asn1_collate_primitive(ret, &c, depth)) { - *perr = c.error; - goto err; - } else { - p = c.p; - } - } else { - if (len != 0) { - if ((ret->length < len) || (ret->data == NULL)) { - s = OPENSSL_malloc((int)len + 1); - if (s == NULL) { - *perr = ERR_R_MALLOC_FAILURE; - goto err; - } - if (ret->data != NULL) - OPENSSL_free(ret->data); - } else - s = ret->data; - memcpy(s, p, (int)len); - s[len] = '\0'; - p += len; - } else { - s = NULL; - if (ret->data != NULL) - OPENSSL_free(ret->data); - } - - ret->length = (int)len; - ret->data = s; - ret->type = Ptag; - } - - if (a != NULL) - (*a) = ret; - *pp = p; - return (ret); - err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - ASN1_STRING_free(ret); - return (NULL); -} - -/* - * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them - * into the one structure that is then returned - */ -/* - * There have been a few bug fixes for this function from Paul Keogh - * , many thanks to him - */ -static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c, - int depth) -{ - ASN1_STRING *os = NULL; - BUF_MEM b; - int num; - - b.length = 0; - b.max = 0; - b.data = NULL; - - if (a == NULL) { - c->error = ERR_R_PASSED_NULL_PARAMETER; - goto err; - } - - num = 0; - for (;;) { - if (c->inf & 1) { - c->eos = ASN1_const_check_infinite_end(&c->p, - (long)(c->max - c->p)); - if (c->eos) - break; - } else { - if (c->slen <= 0) - break; - } - - c->q = c->p; - if (int_d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass, - depth + 1, &c->error) == NULL) { - goto err; - } - - if (!BUF_MEM_grow_clean(&b, num + os->length)) { - c->error = ERR_R_BUF_LIB; - goto err; - } - memcpy(&(b.data[num]), os->data, os->length); - if (!(c->inf & 1)) - c->slen -= (c->p - c->q); - num += os->length; - } - - if (!asn1_const_Finish(c)) - goto err; - - a->length = num; - if (a->data != NULL) - OPENSSL_free(a->data); - a->data = (unsigned char *)b.data; - if (os != NULL) - ASN1_STRING_free(os); - return (1); - err: - if (os != NULL) - ASN1_STRING_free(os); - if (b.data != NULL) - OPENSSL_free(b.data); - return (0); -} -/* crypto/asn1/a_d2i_fp.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -#include "buffer.h" -#include "asn1_mac.h" - -static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); - -#ifndef NO_OLD_ASN1 -# ifndef OPENSSL_NO_FP_API - -void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x) -{ - BIO *b; - void *ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB); - return (NULL); - } - BIO_set_fp(b, in, BIO_NOCLOSE); - ret = ASN1_d2i_bio(xnew, d2i, b, x); - BIO_free(b); - return (ret); -} -# endif - -void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x) -{ - BUF_MEM *b = NULL; - const unsigned char *p; - void *ret = NULL; - int len; - - len = asn1_d2i_read_bio(in, &b); - if (len < 0) - goto err; - - p = (unsigned char *)b->data; - ret = d2i(x, &p, len); - err: - if (b != NULL) - BUF_MEM_free(b); - return (ret); -} - -#endif - -void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) -{ - BUF_MEM *b = NULL; - const unsigned char *p; - void *ret = NULL; - int len; - - len = asn1_d2i_read_bio(in, &b); - if (len < 0) - goto err; - - p = (const unsigned char *)b->data; - ret = ASN1_item_d2i(x, &p, len, it); - err: - if (b != NULL) - BUF_MEM_free(b); - return (ret); -} - -#ifndef OPENSSL_NO_FP_API -void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) -{ - BIO *b; - char *ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB); - return (NULL); - } - BIO_set_fp(b, in, BIO_NOCLOSE); - ret = ASN1_item_d2i_bio(it, b, x); - BIO_free(b); - return (ret); -} -#endif - -#define HEADER_SIZE 8 -#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) -static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) -{ - BUF_MEM *b; - unsigned char *p; - int i; - ASN1_const_CTX c; - size_t want = HEADER_SIZE; - int eos = 0; - size_t off = 0; - size_t len = 0; - - b = BUF_MEM_new(); - if (b == NULL) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); - return -1; - } - - ERR_clear_error(); - for (;;) { - if (want >= (len - off)) { - want -= (len - off); - - if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - i = BIO_read(in, &(b->data[len]), want); - if ((i < 0) && ((len - off) == 0)) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA); - goto err; - } - if (i > 0) { - if (len + i < len) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); - goto err; - } - len += i; - } - } - /* else data already loaded */ - - p = (unsigned char *)&(b->data[off]); - c.p = p; - c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass), - len - off); - if (c.inf & 0x80) { - unsigned long e; - - e = ERR_GET_REASON(ERR_peek_error()); - if (e != ASN1_R_TOO_LONG) - goto err; - else - ERR_clear_error(); /* clear error */ - } - i = c.p - p; /* header length */ - off += i; /* end of data */ - - if (c.inf & 1) { - /* no data body so go round again */ - eos++; - if (eos < 0) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG); - goto err; - } - want = HEADER_SIZE; - } else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) { - /* eos value, so go back and read another header */ - eos--; - if (eos <= 0) - break; - else - want = HEADER_SIZE; - } else { - /* suck in c.slen bytes of data */ - want = c.slen; - if (want > (len - off)) { - size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; - - want -= (len - off); - if (want > INT_MAX /* BIO_read takes an int length */ || - len + want < len) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); - goto err; - } - while (want > 0) { - /* - * Read content in chunks of increasing size - * so we can return an error for EOF without - * having to allocate the entire content length - * in one go. - */ - size_t chunk = want > chunk_max ? chunk_max : want; - - if (!BUF_MEM_grow_clean(b, len + chunk)) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - want -= chunk; - while (chunk > 0) { - i = BIO_read(in, &(b->data[len]), chunk); - if (i <= 0) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, - ASN1_R_NOT_ENOUGH_DATA); - goto err; - } - /* - * This can't overflow because |len+want| didn't - * overflow. - */ - len += i; - chunk -= i; - } - if (chunk_max < INT_MAX/2) - chunk_max *= 2; - } - } - if (off + c.slen < off) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); - goto err; - } - off += c.slen; - if (eos <= 0) { - break; - } else - want = HEADER_SIZE; - } - } - - if (off > INT_MAX) { - ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); - goto err; - } - - *pb = b; - return off; - err: - if (b != NULL) - BUF_MEM_free(b); - return -1; -} -/* crypto/asn1/a_digest.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include - -// #include "cryptlib.h" - -#ifndef NO_SYS_TYPES_H -# include -#endif - -#include "err.h" -#include "evp.h" -// #include "buffer.h" -#include "x509.h" - -#ifndef NO_ASN1_OLD - -int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, - unsigned char *md, unsigned int *len) -{ - int i; - unsigned char *str, *p; - - i = i2d(data, NULL); - if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { - ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE); - return (0); - } - p = str; - i2d(data, &p); - - if (!EVP_Digest(str, i, md, len, type, NULL)) { - OPENSSL_free(str); - return 0; - } - OPENSSL_free(str); - return (1); -} - -#endif - -int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, - unsigned char *md, unsigned int *len) -{ - int i; - unsigned char *str = NULL; - - i = ASN1_item_i2d(asn, &str, it); - if (!str) - return (0); - - if (!EVP_Digest(str, i, md, len, type, NULL)) { - OPENSSL_free(str); - return 0; - } - OPENSSL_free(str); - return (1); -} -/* crypto/asn1/a_dup.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" - -#ifndef NO_OLD_ASN1 - -void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) -{ - unsigned char *b, *p; - const unsigned char *p2; - int i; - char *ret; - - if (x == NULL) - return (NULL); - - i = i2d(x, NULL); - b = OPENSSL_malloc(i + 10); - if (b == NULL) { - ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE); - return (NULL); - } - p = b; - i = i2d(x, &p); - p2 = b; - ret = d2i(NULL, &p2, i); - OPENSSL_free(b); - return (ret); -} - -#endif - -/* - * ASN1_ITEM version of dup: this follows the model above except we don't - * need to allocate the buffer. At some point this could be rewritten to - * directly dup the underlying structure instead of doing and encode and - * decode. - */ - -void *ASN1_item_dup(const ASN1_ITEM *it, void *x) -{ - unsigned char *b = NULL; - const unsigned char *p; - long i; - void *ret; - - if (x == NULL) - return (NULL); - - i = ASN1_item_i2d(x, &b, it); - if (b == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE); - return (NULL); - } - p = b; - ret = ASN1_item_d2i(NULL, &p, i, it); - OPENSSL_free(b); - return (ret); -} -/* crypto/asn1/a_enum.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -#include "bn.h" - -/* - * Code for ENUMERATED type: identical to INTEGER apart from a different tag. - * for comments on encoding see a_int.c - */ - -int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) -{ - int j, k; - unsigned int i; - unsigned char buf[sizeof(long) + 1]; - long d; - - a->type = V_ASN1_ENUMERATED; - if (a->length < (int)(sizeof(long) + 1)) { - if (a->data != NULL) - OPENSSL_free(a->data); - if ((a->data = - (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL) - memset((char *)a->data, 0, sizeof(long) + 1); - } - if (a->data == NULL) { - ASN1err(ASN1_F_ASN1_ENUMERATED_SET, ERR_R_MALLOC_FAILURE); - return (0); - } - d = v; - if (d < 0) { - d = -d; - a->type = V_ASN1_NEG_ENUMERATED; - } - - for (i = 0; i < sizeof(long); i++) { - if (d == 0) - break; - buf[i] = (int)d & 0xff; - d >>= 8; - } - j = 0; - for (k = i - 1; k >= 0; k--) - a->data[j++] = buf[k]; - a->length = j; - return (1); -} - -long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a) -{ - int neg = 0, i; - long r = 0; - - if (a == NULL) - return (0L); - i = a->type; - if (i == V_ASN1_NEG_ENUMERATED) - neg = 1; - else if (i != V_ASN1_ENUMERATED) - return -1; - - if (a->length > (int)sizeof(long)) { - /* hmm... a bit ugly */ - return (0xffffffffL); - } - if (a->data == NULL) - return 0; - - for (i = 0; i < a->length; i++) { - r <<= 8; - r |= (unsigned char)a->data[i]; - } - if (neg) - r = -r; - return (r); -} - -ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai) -{ - ASN1_ENUMERATED *ret; - int len, j; - - if (ai == NULL) - ret = M_ASN1_ENUMERATED_new(); - else - ret = ai; - if (ret == NULL) { - ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_NESTED_ASN1_ERROR); - goto err; - } - if (BN_is_negative(bn)) - ret->type = V_ASN1_NEG_ENUMERATED; - else - ret->type = V_ASN1_ENUMERATED; - j = BN_num_bits(bn); - len = ((j == 0) ? 0 : ((j / 8) + 1)); - if (ret->length < len + 4) { - unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); - if (!new_data) { - ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); - goto err; - } - ret->data = new_data; - } - - ret->length = BN_bn2bin(bn, ret->data); - return (ret); - err: - if (ret != ai) - M_ASN1_ENUMERATED_free(ret); - return (NULL); -} - -BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn) -{ - BIGNUM *ret; - - if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) - ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN, ASN1_R_BN_LIB); - else if (ai->type == V_ASN1_NEG_ENUMERATED) - BN_set_negative(ret, 1); - return (ret); -} -/* crypto/asn1/a_gentm.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME - */ - -#include -#include -// #include "cryptlib.h" -#include "o_time.h" -// #include "asn1.h" -#include "asn1_locl.h" - -#if 0 - -int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp) -{ -# ifdef CHARSET_EBCDIC - /* KLUDGE! We convert to ascii before writing DER */ - int len; - char tmp[24]; - ASN1_STRING tmpstr = *(ASN1_STRING *)a; - - len = tmpstr.length; - ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof(tmp)) ? sizeof(tmp) : len); - tmpstr.data = tmp; - - a = (ASN1_GENERALIZEDTIME *)&tmpstr; -# endif - return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, - V_ASN1_GENERALIZEDTIME, V_ASN1_UNIVERSAL)); -} - -ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a, - unsigned char **pp, - long length) -{ - ASN1_GENERALIZEDTIME *ret = NULL; - - ret = - (ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length, - V_ASN1_GENERALIZEDTIME, - V_ASN1_UNIVERSAL); - if (ret == NULL) { - ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ERR_R_NESTED_ASN1_ERROR); - return (NULL); - } -# ifdef CHARSET_EBCDIC - ascii2ebcdic(ret->data, ret->data, ret->length); -# endif - if (!ASN1_GENERALIZEDTIME_check(ret)) { - ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ASN1_R_INVALID_TIME_FORMAT); - goto err; - } - - return (ret); - err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - M_ASN1_GENERALIZEDTIME_free(ret); - return (NULL); -} - -#endif - -int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) -{ - static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 }; - static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 }; - char *a; - int n, i, l, o; - - if (d->type != V_ASN1_GENERALIZEDTIME) - return (0); - l = d->length; - a = (char *)d->data; - o = 0; - /* - * GENERALIZEDTIME is similar to UTCTIME except the year is represented - * as YYYY. This stuff treats everything as a two digit field so make - * first two fields 00 to 99 - */ - if (l < 13) - goto err; - for (i = 0; i < 7; i++) { - if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { - i++; - if (tm) - tm->tm_sec = 0; - break; - } - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - if (++o > l) - goto err; - - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if (++o > l) - goto err; - - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - switch (i) { - case 0: - tm->tm_year = n * 100 - 1900; - break; - case 1: - tm->tm_year += n; - break; - case 2: - tm->tm_mon = n - 1; - break; - case 3: - tm->tm_mday = n; - break; - case 4: - tm->tm_hour = n; - break; - case 5: - tm->tm_min = n; - break; - case 6: - tm->tm_sec = n; - break; - } - } - } - /* - * Optional fractional seconds: decimal point followed by one or more - * digits. - */ - if (a[o] == '.') { - if (++o > l) - goto err; - i = o; - while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) - o++; - /* Must have at least one digit after decimal point */ - if (i == o) - goto err; - } - - if (a[o] == 'Z') - o++; - else if ((a[o] == '+') || (a[o] == '-')) { - int offsign = a[o] == '-' ? 1 : -1, offset = 0; - o++; - if (o + 4 > l) - goto err; - for (i = 7; i < 9; i++) { - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - o++; - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - if (i == 7) - offset = n * 3600; - else if (i == 8) - offset += n * 60; - } - o++; - } - if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) - return 0; - } else if (a[o]) { - /* Missing time zone information. */ - goto err; - } - return (o == l); - err: - return (0); -} - -int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) -{ - return asn1_generalizedtime_to_tm(NULL, d); -} - -int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) -{ - ASN1_GENERALIZEDTIME t; - - t.type = V_ASN1_GENERALIZEDTIME; - t.length = strlen(str); - t.data = (unsigned char *)str; - if (ASN1_GENERALIZEDTIME_check(&t)) { - if (s != NULL) { - if (!ASN1_STRING_set((ASN1_STRING *)s, - (unsigned char *)str, t.length)) - return 0; - s->type = V_ASN1_GENERALIZEDTIME; - } - return (1); - } else - return (0); -} - -ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, - time_t t) -{ - return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); -} - -ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, - time_t t, int offset_day, - long offset_sec) -{ - char *p; - struct tm *ts; - struct tm data; - size_t len = 20; - - if (s == NULL) - s = M_ASN1_GENERALIZEDTIME_new(); - if (s == NULL) - return (NULL); - - ts = OPENSSL_gmtime(&t, &data); - if (ts == NULL) - return (NULL); - - if (offset_day || offset_sec) { - if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) - return NULL; - } - - p = (char *)s->data; - if ((p == NULL) || ((size_t)s->length < len)) { - p = OPENSSL_malloc(len); - if (p == NULL) { - ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE); - return (NULL); - } - if (s->data != NULL) - OPENSSL_free(s->data); - s->data = (unsigned char *)p; - } - - BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900, - ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, - ts->tm_sec); - s->length = strlen(p); - s->type = V_ASN1_GENERALIZEDTIME; -#ifdef CHARSET_EBCDIC_not - ebcdic2ascii(s->data, s->data, s->length); -#endif - return (s); -} -/* crypto/asn1/a_i2d_fp.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "asn1.h" - -#ifndef NO_OLD_ASN1 - -# ifndef OPENSSL_NO_FP_API -int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, out, BIO_NOCLOSE); - ret = ASN1_i2d_bio(i2d, b, x); - BIO_free(b); - return (ret); -} -# endif - -int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) -{ - char *b; - unsigned char *p; - int i, j = 0, n, ret = 1; - - n = i2d(x, NULL); - if (n <= 0) - return 0; - - b = (char *)OPENSSL_malloc(n); - if (b == NULL) { - ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE); - return (0); - } - - p = (unsigned char *)b; - i2d(x, &p); - - for (;;) { - i = BIO_write(out, &(b[j]), n); - if (i == n) - break; - if (i <= 0) { - ret = 0; - break; - } - j += i; - n -= i; - } - OPENSSL_free(b); - return (ret); -} - -#endif - -#ifndef OPENSSL_NO_FP_API -int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, out, BIO_NOCLOSE); - ret = ASN1_item_i2d_bio(it, b, x); - BIO_free(b); - return (ret); -} -#endif - -int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) -{ - unsigned char *b = NULL; - int i, j = 0, n, ret = 1; - - n = ASN1_item_i2d(x, &b, it); - if (b == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE); - return (0); - } - - for (;;) { - i = BIO_write(out, &(b[j]), n); - if (i == n) - break; - if (i <= 0) { - ret = 0; - break; - } - j += i; - n -= i; - } - OPENSSL_free(b); - return (ret); -} -/* crypto/asn1/a_int.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "bn.h" - -ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) -{ - return M_ASN1_INTEGER_dup(x); -} - -int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) -{ - int neg, ret; - /* Compare signs */ - neg = x->type & V_ASN1_NEG; - if (neg != (y->type & V_ASN1_NEG)) { - if (neg) - return -1; - else - return 1; - } - - ret = ASN1_STRING_cmp(x, y); - - if (neg) - return -ret; - else - return ret; -} - -/*- - * This converts an ASN1 INTEGER into its content encoding. - * The internal representation is an ASN1_STRING whose data is a big endian - * representation of the value, ignoring the sign. The sign is determined by - * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. - * - * Positive integers are no problem: they are almost the same as the DER - * encoding, except if the first byte is >= 0x80 we need to add a zero pad. - * - * Negative integers are a bit trickier... - * The DER representation of negative integers is in 2s complement form. - * The internal form is converted by complementing each octet and finally - * adding one to the result. This can be done less messily with a little trick. - * If the internal form has trailing zeroes then they will become FF by the - * complement and 0 by the add one (due to carry) so just copy as many trailing - * zeros to the destination as there are in the source. The carry will add one - * to the last none zero octet: so complement this octet and add one and finally - * complement any left over until you get to the start of the string. - * - * Padding is a little trickier too. If the first bytes is > 0x80 then we pad - * with 0xff. However if the first byte is 0x80 and one of the following bytes - * is non-zero we pad with 0xff. The reason for this distinction is that 0x80 - * followed by optional zeros isn't padded. - */ - -int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) -{ - int pad = 0, ret, i, neg; - unsigned char *p, *n, pb = 0; - - if (a == NULL) - return (0); - neg = a->type & V_ASN1_NEG; - if (a->length == 0) - ret = 1; - else { - ret = a->length; - i = a->data[0]; - if (ret == 1 && i == 0) - neg = 0; - if (!neg && (i > 127)) { - pad = 1; - pb = 0; - } else if (neg) { - if (i > 128) { - pad = 1; - pb = 0xFF; - } else if (i == 128) { - /* - * Special case: if any other bytes non zero we pad: - * otherwise we don't. - */ - for (i = 1; i < a->length; i++) - if (a->data[i]) { - pad = 1; - pb = 0xFF; - break; - } - } - } - ret += pad; - } - if (pp == NULL) - return (ret); - p = *pp; - - if (pad) - *(p++) = pb; - if (a->length == 0) - *(p++) = 0; - else if (!neg) - memcpy(p, a->data, (unsigned int)a->length); - else { - /* Begin at the end of the encoding */ - n = a->data + a->length - 1; - p += a->length - 1; - i = a->length; - /* Copy zeros to destination as long as source is zero */ - while (!*n && i > 1) { - *(p--) = 0; - n--; - i--; - } - /* Complement and increment next octet */ - *(p--) = ((*(n--)) ^ 0xff) + 1; - i--; - /* Complement any octets left */ - for (; i > 0; i--) - *(p--) = *(n--) ^ 0xff; - } - - *pp += ret; - return (ret); -} - -/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ - -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, - long len) -{ - ASN1_INTEGER *ret = NULL; - const unsigned char *p, *pend; - unsigned char *to, *s; - int i; - - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = M_ASN1_INTEGER_new()) == NULL) - return (NULL); - ret->type = V_ASN1_INTEGER; - } else - ret = (*a); - - p = *pp; - pend = p + len; - - /* - * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies - * a missing NULL parameter. - */ - s = (unsigned char *)OPENSSL_malloc((int)len + 1); - if (s == NULL) { - i = ERR_R_MALLOC_FAILURE; - goto err; - } - to = s; - if (!len) { - /* - * Strictly speaking this is an illegal INTEGER but we tolerate it. - */ - ret->type = V_ASN1_INTEGER; - } else if (*p & 0x80) { /* a negative number */ - ret->type = V_ASN1_NEG_INTEGER; - if ((*p == 0xff) && (len != 1)) { - p++; - len--; - } - i = len; - p += i - 1; - to += i - 1; - while ((!*p) && i) { - *(to--) = 0; - i--; - p--; - } - /* - * Special case: if all zeros then the number will be of the form FF - * followed by n zero bytes: this corresponds to 1 followed by n zero - * bytes. We've already written n zeros so we just append an extra - * one and set the first byte to a 1. This is treated separately - * because it is the only case where the number of bytes is larger - * than len. - */ - if (!i) { - *s = 1; - s[len] = 0; - len++; - } else { - *(to--) = (*(p--) ^ 0xff) + 1; - i--; - for (; i > 0; i--) - *(to--) = *(p--) ^ 0xff; - } - } else { - ret->type = V_ASN1_INTEGER; - if ((*p == 0) && (len != 1)) { - p++; - len--; - } - memcpy(s, p, (int)len); - } - - if (ret->data != NULL) - OPENSSL_free(ret->data); - ret->data = s; - ret->length = (int)len; - if (a != NULL) - (*a) = ret; - *pp = pend; - return (ret); - err: - ASN1err(ASN1_F_C2I_ASN1_INTEGER, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - M_ASN1_INTEGER_free(ret); - return (NULL); -} - -/* - * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1 - * integers: some broken software can encode a positive INTEGER with its MSB - * set as negative (it doesn't add a padding zero). - */ - -ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, - long length) -{ - ASN1_INTEGER *ret = NULL; - const unsigned char *p; - unsigned char *s; - long len; - int inf, tag, xclass; - int i; - - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = M_ASN1_INTEGER_new()) == NULL) - return (NULL); - ret->type = V_ASN1_INTEGER; - } else - ret = (*a); - - p = *pp; - inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) { - i = ASN1_R_BAD_OBJECT_HEADER; - goto err; - } - - if (tag != V_ASN1_INTEGER) { - i = ASN1_R_EXPECTING_AN_INTEGER; - goto err; - } - - /* - * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies - * a missing NULL parameter. - */ - s = (unsigned char *)OPENSSL_malloc((int)len + 1); - if (s == NULL) { - i = ERR_R_MALLOC_FAILURE; - goto err; - } - ret->type = V_ASN1_INTEGER; - if (len) { - if ((*p == 0) && (len != 1)) { - p++; - len--; - } - memcpy(s, p, (int)len); - p += len; - } - - if (ret->data != NULL) - OPENSSL_free(ret->data); - ret->data = s; - ret->length = (int)len; - if (a != NULL) - (*a) = ret; - *pp = p; - return (ret); - err: - ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - M_ASN1_INTEGER_free(ret); - return (NULL); -} - -int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) -{ - int j, k; - unsigned int i; - unsigned char buf[sizeof(long) + 1]; - long d; - - a->type = V_ASN1_INTEGER; - if (a->length < (int)(sizeof(long) + 1)) { - if (a->data != NULL) - OPENSSL_free(a->data); - if ((a->data = - (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL) - memset((char *)a->data, 0, sizeof(long) + 1); - } - if (a->data == NULL) { - ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE); - return (0); - } - d = v; - if (d < 0) { - d = -d; - a->type = V_ASN1_NEG_INTEGER; - } - - for (i = 0; i < sizeof(long); i++) { - if (d == 0) - break; - buf[i] = (int)d & 0xff; - d >>= 8; - } - j = 0; - for (k = i - 1; k >= 0; k--) - a->data[j++] = buf[k]; - a->length = j; - return (1); -} - -long ASN1_INTEGER_get(const ASN1_INTEGER *a) -{ - int neg = 0, i; - long r = 0; - - if (a == NULL) - return (0L); - i = a->type; - if (i == V_ASN1_NEG_INTEGER) - neg = 1; - else if (i != V_ASN1_INTEGER) - return -1; - - if (a->length > (int)sizeof(long)) { - /* hmm... a bit ugly, return all ones */ - return -1; - } - if (a->data == NULL) - return 0; - - for (i = 0; i < a->length; i++) { - r <<= 8; - r |= (unsigned char)a->data[i]; - } - if (neg) - r = -r; - return (r); -} - -ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) -{ - ASN1_INTEGER *ret; - int len, j; - - if (ai == NULL) - ret = M_ASN1_INTEGER_new(); - else - ret = ai; - if (ret == NULL) { - ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR); - goto err; - } - if (BN_is_negative(bn) && !BN_is_zero(bn)) - ret->type = V_ASN1_NEG_INTEGER; - else - ret->type = V_ASN1_INTEGER; - j = BN_num_bits(bn); - len = ((j == 0) ? 0 : ((j / 8) + 1)); - if (ret->length < len + 4) { - unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); - if (!new_data) { - ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); - goto err; - } - ret->data = new_data; - } - ret->length = BN_bn2bin(bn, ret->data); - /* Correct zero case */ - if (!ret->length) { - ret->data[0] = 0; - ret->length = 1; - } - return (ret); - err: - if (ret != ai) - M_ASN1_INTEGER_free(ret); - return (NULL); -} - -BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) -{ - BIGNUM *ret; - - if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) - ASN1err(ASN1_F_ASN1_INTEGER_TO_BN, ASN1_R_BN_LIB); - else if (ai->type == V_ASN1_NEG_INTEGER) - BN_set_negative(ret, 1); - return (ret); -} - -IMPLEMENT_STACK_OF(ASN1_INTEGER) - -IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER) -/* a_mbstr.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "asn1.h" - -static int traverse_string(const unsigned char *p, int len, int inform, - int (*rfunc) (unsigned long value, void *in), - void *arg); -static int in_utf8(unsigned long value, void *arg); -static int out_utf8(unsigned long value, void *arg); -static int type_str(unsigned long value, void *arg); -static int cpy_asc(unsigned long value, void *arg); -static int cpy_bmp(unsigned long value, void *arg); -static int cpy_univ(unsigned long value, void *arg); -static int cpy_utf8(unsigned long value, void *arg); -static int is_printable(unsigned long value); - -/* - * These functions take a string in UTF8, ASCII or multibyte form and a mask - * of permissible ASN1 string types. It then works out the minimal type - * (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and - * creates a string of the correct type with the supplied data. Yes this is - * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum - * size limits too. - */ - -int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, - int inform, unsigned long mask) -{ - return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0); -} - -int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, - int inform, unsigned long mask, - long minsize, long maxsize) -{ - int str_type; - int ret; - char free_out; - int outform, outlen = 0; - ASN1_STRING *dest; - unsigned char *p; - int nchar; - char strbuf[32]; - int (*cpyfunc) (unsigned long, void *) = NULL; - if (len == -1) - len = strlen((const char *)in); - if (!mask) - mask = DIRSTRING_TYPE; - - /* First do a string check and work out the number of characters */ - switch (inform) { - - case MBSTRING_BMP: - if (len & 1) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, - ASN1_R_INVALID_BMPSTRING_LENGTH); - return -1; - } - nchar = len >> 1; - break; - - case MBSTRING_UNIV: - if (len & 3) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, - ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); - return -1; - } - nchar = len >> 2; - break; - - case MBSTRING_UTF8: - nchar = 0; - /* This counts the characters and does utf8 syntax checking */ - ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar); - if (ret < 0) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING); - return -1; - } - break; - - case MBSTRING_ASC: - nchar = len; - break; - - default: - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT); - return -1; - } - - if ((minsize > 0) && (nchar < minsize)) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT); - BIO_snprintf(strbuf, sizeof(strbuf), "%ld", minsize); - ERR_add_error_data(2, "minsize=", strbuf); - return -1; - } - - if ((maxsize > 0) && (nchar > maxsize)) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG); - BIO_snprintf(strbuf, sizeof(strbuf), "%ld", maxsize); - ERR_add_error_data(2, "maxsize=", strbuf); - return -1; - } - - /* Now work out minimal type (if any) */ - if (traverse_string(in, len, inform, type_str, &mask) < 0) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS); - return -1; - } - - /* Now work out output format and string type */ - outform = MBSTRING_ASC; - if (mask & B_ASN1_PRINTABLESTRING) - str_type = V_ASN1_PRINTABLESTRING; - else if (mask & B_ASN1_IA5STRING) - str_type = V_ASN1_IA5STRING; - else if (mask & B_ASN1_T61STRING) - str_type = V_ASN1_T61STRING; - else if (mask & B_ASN1_BMPSTRING) { - str_type = V_ASN1_BMPSTRING; - outform = MBSTRING_BMP; - } else if (mask & B_ASN1_UNIVERSALSTRING) { - str_type = V_ASN1_UNIVERSALSTRING; - outform = MBSTRING_UNIV; - } else { - str_type = V_ASN1_UTF8STRING; - outform = MBSTRING_UTF8; - } - if (!out) - return str_type; - if (*out) { - free_out = 0; - dest = *out; - if (dest->data) { - dest->length = 0; - OPENSSL_free(dest->data); - dest->data = NULL; - } - dest->type = str_type; - } else { - free_out = 1; - dest = ASN1_STRING_type_new(str_type); - if (!dest) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); - return -1; - } - *out = dest; - } - /* If both the same type just copy across */ - if (inform == outform) { - if (!ASN1_STRING_set(dest, in, len)) { - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); - return -1; - } - return str_type; - } - - /* Work out how much space the destination will need */ - switch (outform) { - case MBSTRING_ASC: - outlen = nchar; - cpyfunc = cpy_asc; - break; - - case MBSTRING_BMP: - outlen = nchar << 1; - cpyfunc = cpy_bmp; - break; - - case MBSTRING_UNIV: - outlen = nchar << 2; - cpyfunc = cpy_univ; - break; - - case MBSTRING_UTF8: - outlen = 0; - traverse_string(in, len, inform, out_utf8, &outlen); - cpyfunc = cpy_utf8; - break; - } - if (!(p = OPENSSL_malloc(outlen + 1))) { - if (free_out) - ASN1_STRING_free(dest); - ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); - return -1; - } - dest->length = outlen; - dest->data = p; - p[outlen] = 0; - traverse_string(in, len, inform, cpyfunc, &p); - return str_type; -} - -/* - * This function traverses a string and passes the value of each character to - * an optional function along with a void * argument. - */ - -static int traverse_string(const unsigned char *p, int len, int inform, - int (*rfunc) (unsigned long value, void *in), - void *arg) -{ - unsigned long value; - int ret; - while (len) { - if (inform == MBSTRING_ASC) { - value = *p++; - len--; - } else if (inform == MBSTRING_BMP) { - value = *p++ << 8; - value |= *p++; - len -= 2; - } else if (inform == MBSTRING_UNIV) { - value = ((unsigned long)*p++) << 24; - value |= ((unsigned long)*p++) << 16; - value |= *p++ << 8; - value |= *p++; - len -= 4; - } else { - ret = UTF8_getc(p, len, &value); - if (ret < 0) - return -1; - len -= ret; - p += ret; - } - if (rfunc) { - ret = rfunc(value, arg); - if (ret <= 0) - return ret; - } - } - return 1; -} - -/* Various utility functions for traverse_string */ - -/* Just count number of characters */ - -static int in_utf8(unsigned long value, void *arg) -{ - int *nchar; - nchar = arg; - (*nchar)++; - return 1; -} - -/* Determine size of output as a UTF8 String */ - -static int out_utf8(unsigned long value, void *arg) -{ - int *outlen; - outlen = arg; - *outlen += UTF8_putc(NULL, -1, value); - return 1; -} - -/* - * Determine the "type" of a string: check each character against a supplied - * "mask". - */ - -static int type_str(unsigned long value, void *arg) -{ - unsigned long types; - types = *((unsigned long *)arg); - if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value)) - types &= ~B_ASN1_PRINTABLESTRING; - if ((types & B_ASN1_IA5STRING) && (value > 127)) - types &= ~B_ASN1_IA5STRING; - if ((types & B_ASN1_T61STRING) && (value > 0xff)) - types &= ~B_ASN1_T61STRING; - if ((types & B_ASN1_BMPSTRING) && (value > 0xffff)) - types &= ~B_ASN1_BMPSTRING; - if (!types) - return -1; - *((unsigned long *)arg) = types; - return 1; -} - -/* Copy one byte per character ASCII like strings */ - -static int cpy_asc(unsigned long value, void *arg) -{ - unsigned char **p, *q; - p = arg; - q = *p; - *q = (unsigned char)value; - (*p)++; - return 1; -} - -/* Copy two byte per character BMPStrings */ - -static int cpy_bmp(unsigned long value, void *arg) -{ - unsigned char **p, *q; - p = arg; - q = *p; - *q++ = (unsigned char)((value >> 8) & 0xff); - *q = (unsigned char)(value & 0xff); - *p += 2; - return 1; -} - -/* Copy four byte per character UniversalStrings */ - -static int cpy_univ(unsigned long value, void *arg) -{ - unsigned char **p, *q; - p = arg; - q = *p; - *q++ = (unsigned char)((value >> 24) & 0xff); - *q++ = (unsigned char)((value >> 16) & 0xff); - *q++ = (unsigned char)((value >> 8) & 0xff); - *q = (unsigned char)(value & 0xff); - *p += 4; - return 1; -} - -/* Copy to a UTF8String */ - -static int cpy_utf8(unsigned long value, void *arg) -{ - unsigned char **p; - int ret; - p = arg; - /* We already know there is enough room so pass 0xff as the length */ - ret = UTF8_putc(*p, 0xff, value); - *p += ret; - return 1; -} - -/* Return 1 if the character is permitted in a PrintableString */ -static int is_printable(unsigned long value) -{ - int ch; - if (value > 0x7f) - return 0; - ch = (int)value; - /* - * Note: we can't use 'isalnum' because certain accented characters may - * count as alphanumeric in some environments. - */ -#ifndef CHARSET_EBCDIC - if ((ch >= 'a') && (ch <= 'z')) - return 1; - if ((ch >= 'A') && (ch <= 'Z')) - return 1; - if ((ch >= '0') && (ch <= '9')) - return 1; - if ((ch == ' ') || strchr("'()+,-./:=?", ch)) - return 1; -#else /* CHARSET_EBCDIC */ - if ((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) - return 1; - if ((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) - return 1; - if ((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) - return 1; - if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) - return 1; -#endif /* CHARSET_EBCDIC */ - return 0; -} -/* crypto/asn1/a_object.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "asn1.h" -#include "objects.h" -// #include "bn.h" - -int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) -{ - unsigned char *p, *allocated = NULL; - int objsize; - - if ((a == NULL) || (a->data == NULL)) - return (0); - - objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT); - if (pp == NULL || objsize == -1) - return objsize; - - if (*pp == NULL) { - if ((p = allocated = OPENSSL_malloc(objsize)) == NULL) { - ASN1err(ASN1_F_I2D_ASN1_OBJECT, ERR_R_MALLOC_FAILURE); - return 0; - } - } else { - p = *pp; - } - - ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); - memcpy(p, a->data, a->length); - - /* - * If a new buffer was allocated, just return it back. - * If not, return the incremented buffer pointer. - */ - *pp = allocated != NULL ? allocated : p + a->length; - return objsize; -} - -int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) -{ - int i, first, len = 0, c, use_bn; - char ftmp[24], *tmp = ftmp; - int tmpsize = sizeof(ftmp); - const char *p; - unsigned long l; - BIGNUM *bl = NULL; - - if (num == 0) - return (0); - else if (num == -1) - num = strlen(buf); - - p = buf; - c = *(p++); - num--; - if ((c >= '0') && (c <= '2')) { - first = c - '0'; - } else { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE); - goto err; - } - - if (num <= 0) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER); - goto err; - } - c = *(p++); - num--; - for (;;) { - if (num <= 0) - break; - if ((c != '.') && (c != ' ')) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR); - goto err; - } - l = 0; - use_bn = 0; - for (;;) { - if (num <= 0) - break; - num--; - c = *(p++); - if ((c == ' ') || (c == '.')) - break; - if ((c < '0') || (c > '9')) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT); - goto err; - } - if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) { - use_bn = 1; - if (!bl) - bl = BN_new(); - if (!bl || !BN_set_word(bl, l)) - goto err; - } - if (use_bn) { - if (!BN_mul_word(bl, 10L) - || !BN_add_word(bl, c - '0')) - goto err; - } else - l = l * 10L + (long)(c - '0'); - } - if (len == 0) { - if ((first < 2) && (l >= 40)) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, - ASN1_R_SECOND_NUMBER_TOO_LARGE); - goto err; - } - if (use_bn) { - if (!BN_add_word(bl, first * 40)) - goto err; - } else - l += (long)first *40; - } - i = 0; - if (use_bn) { - int blsize; - blsize = BN_num_bits(bl); - blsize = (blsize + 6) / 7; - if (blsize > tmpsize) { - if (tmp != ftmp) - OPENSSL_free(tmp); - tmpsize = blsize + 32; - tmp = OPENSSL_malloc(tmpsize); - if (!tmp) - goto err; - } - while (blsize--) { - BN_ULONG t = BN_div_word(bl, 0x80L); - if (t == (BN_ULONG)-1) - goto err; - tmp[i++] = (unsigned char)t; - } - } else { - - for (;;) { - tmp[i++] = (unsigned char)l & 0x7f; - l >>= 7L; - if (l == 0L) - break; - } - - } - if (out != NULL) { - if (len + i > olen) { - ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL); - goto err; - } - while (--i > 0) - out[len++] = tmp[i] | 0x80; - out[len++] = tmp[0]; - } else - len += i; - } - if (tmp != ftmp) - OPENSSL_free(tmp); - if (bl) - BN_free(bl); - return (len); - err: - if (tmp != ftmp) - OPENSSL_free(tmp); - if (bl) - BN_free(bl); - return (0); -} - -int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a) -{ - return OBJ_obj2txt(buf, buf_len, a, 0); -} - -int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) -{ - char buf[80], *p = buf; - int i; - - if ((a == NULL) || (a->data == NULL)) - return (BIO_write(bp, "NULL", 4)); - i = i2t_ASN1_OBJECT(buf, sizeof(buf), a); - if (i > (int)(sizeof(buf) - 1)) { - p = OPENSSL_malloc(i + 1); - if (!p) - return -1; - i2t_ASN1_OBJECT(p, i + 1, a); - } - if (i <= 0) - return BIO_write(bp, "", 9); - BIO_write(bp, p, i); - if (p != buf) - OPENSSL_free(p); - return (i); -} - -ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long length) -{ - const unsigned char *p; - long len; - int tag, xclass; - int inf, i; - ASN1_OBJECT *ret = NULL; - p = *pp; - inf = ASN1_get_object(&p, &len, &tag, &xclass, length); - if (inf & 0x80) { - i = ASN1_R_BAD_OBJECT_HEADER; - goto err; - } - - if (tag != V_ASN1_OBJECT) { - i = ASN1_R_EXPECTING_AN_OBJECT; - goto err; - } - ret = c2i_ASN1_OBJECT(a, &p, len); - if (ret) - *pp = p; - return ret; - err: - ASN1err(ASN1_F_D2I_ASN1_OBJECT, i); - return (NULL); -} - -ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long len) -{ - ASN1_OBJECT *ret = NULL; - const unsigned char *p; - unsigned char *data; - int i, length; - - /* - * Sanity check OID encoding. Need at least one content octet. MSB must - * be clear in the last octet. can't have leading 0x80 in subidentifiers, - * see: X.690 8.19.2 - */ - if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || - p[len - 1] & 0x80) { - ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); - return NULL; - } - /* Now 0 < len <= INT_MAX, so the cast is safe. */ - length = (int)len; - for (i = 0; i < length; i++, p++) { - if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { - ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); - return NULL; - } - } - - /* - * only the ASN1_OBJECTs from the 'table' will have values for ->sn or - * ->ln - */ - if ((a == NULL) || ((*a) == NULL) || - !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { - if ((ret = ASN1_OBJECT_new()) == NULL) - return (NULL); - } else - ret = (*a); - - p = *pp; - /* detach data from object */ - data = (unsigned char *)ret->data; - ret->data = NULL; - /* once detached we can change it */ - if ((data == NULL) || (ret->length < length)) { - ret->length = 0; - if (data != NULL) - OPENSSL_free(data); - data = (unsigned char *)OPENSSL_malloc(length); - if (data == NULL) { - i = ERR_R_MALLOC_FAILURE; - goto err; - } - ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; - } - memcpy(data, p, length); - /* reattach data to object, after which it remains const */ - ret->data = data; - ret->length = length; - ret->sn = NULL; - ret->ln = NULL; - /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ - p += length; - - if (a != NULL) - (*a) = ret; - *pp = p; - return (ret); - err: - ASN1err(ASN1_F_C2I_ASN1_OBJECT, i); - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - ASN1_OBJECT_free(ret); - return (NULL); -} - -ASN1_OBJECT *ASN1_OBJECT_new(void) -{ - ASN1_OBJECT *ret; - - ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); - if (ret == NULL) { - ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - ret->length = 0; - ret->data = NULL; - ret->nid = 0; - ret->sn = NULL; - ret->ln = NULL; - ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; - return (ret); -} - -void ASN1_OBJECT_free(ASN1_OBJECT *a) -{ - if (a == NULL) - return; - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { -#ifndef CONST_STRICT /* disable purely for compile-time strict - * const checking. Doing this on a "real" - * compile will cause memory leaks */ - if (a->sn != NULL) - OPENSSL_free((void *)a->sn); - if (a->ln != NULL) - OPENSSL_free((void *)a->ln); -#endif - a->sn = a->ln = NULL; - } - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { - if (a->data != NULL) - OPENSSL_free((void *)a->data); - a->data = NULL; - a->length = 0; - } - if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) - OPENSSL_free(a); -} - -ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, - const char *sn, const char *ln) -{ - ASN1_OBJECT o; - - o.sn = sn; - o.ln = ln; - o.data = data; - o.nid = nid; - o.length = len; - o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | - ASN1_OBJECT_FLAG_DYNAMIC_DATA; - return (OBJ_dup(&o)); -} - -IMPLEMENT_STACK_OF(ASN1_OBJECT) - -IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT) -/* crypto/asn1/a_octet.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" - -ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x) -{ - return M_ASN1_OCTET_STRING_dup(x); -} - -int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, - const ASN1_OCTET_STRING *b) -{ - return M_ASN1_OCTET_STRING_cmp(a, b); -} - -int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, - int len) -{ - return M_ASN1_OCTET_STRING_set(x, d, len); -} -/* crypto/asn1/a_print.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" - -int ASN1_PRINTABLE_type(const unsigned char *s, int len) -{ - int c; - int ia5 = 0; - int t61 = 0; - - if (len <= 0) - len = -1; - if (s == NULL) - return (V_ASN1_PRINTABLESTRING); - - while ((*s) && (len-- != 0)) { - c = *(s++); -#ifndef CHARSET_EBCDIC - if (!(((c >= 'a') && (c <= 'z')) || - ((c >= 'A') && (c <= 'Z')) || - (c == ' ') || - ((c >= '0') && (c <= '9')) || - (c == ' ') || (c == '\'') || - (c == '(') || (c == ')') || - (c == '+') || (c == ',') || - (c == '-') || (c == '.') || - (c == '/') || (c == ':') || (c == '=') || (c == '?'))) - ia5 = 1; - if (c & 0x80) - t61 = 1; -#else - if (!isalnum(c) && (c != ' ') && strchr("'()+,-./:=?", c) == NULL) - ia5 = 1; - if (os_toascii[c] & 0x80) - t61 = 1; -#endif - } - if (t61) - return (V_ASN1_T61STRING); - if (ia5) - return (V_ASN1_IA5STRING); - return (V_ASN1_PRINTABLESTRING); -} - -int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s) -{ - int i; - unsigned char *p; - - if (s->type != V_ASN1_UNIVERSALSTRING) - return (0); - if ((s->length % 4) != 0) - return (0); - p = s->data; - for (i = 0; i < s->length; i += 4) { - if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0')) - break; - else - p += 4; - } - if (i < s->length) - return (0); - p = s->data; - for (i = 3; i < s->length; i += 4) { - *(p++) = s->data[i]; - } - *(p) = '\0'; - s->length /= 4; - s->type = ASN1_PRINTABLE_type(s->data, s->length); - return (1); -} -/* crypto/asn1/a_set.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "asn1_mac.h" - -#ifndef NO_ASN1_OLD - -typedef struct { - unsigned char *pbData; - int cbData; -} MYBLOB; - -/* - * SetBlobCmp This function compares two elements of SET_OF block - */ -static int SetBlobCmp(const void *elem1, const void *elem2) -{ - const MYBLOB *b1 = (const MYBLOB *)elem1; - const MYBLOB *b2 = (const MYBLOB *)elem2; - int r; - - r = memcmp(b1->pbData, b2->pbData, - b1->cbData < b2->cbData ? b1->cbData : b2->cbData); - if (r != 0) - return r; - return b1->cbData - b2->cbData; -} - -/* - * int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) - */ -int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, - i2d_of_void *i2d, int ex_tag, int ex_class, int is_set) -{ - int ret = 0, r; - int i; - unsigned char *p; - unsigned char *pStart, *pTempMem; - MYBLOB *rgSetBlob; - int totSize; - - if (a == NULL) - return (0); - for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--) { - int tmplen = i2d(sk_OPENSSL_BLOCK_value(a, i), NULL); - if (tmplen > INT_MAX - ret) - return -1; - ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL); - } - r = ASN1_object_size(1, ret, ex_tag); - if (pp == NULL || r == -1) - return (r); - - p = *pp; - ASN1_put_object(&p, 1, ret, ex_tag, ex_class); - -/* Modified by gp@nsj.co.jp */ - /* And then again by Ben */ - /* And again by Steve */ - - if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) { - for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) - i2d(sk_OPENSSL_BLOCK_value(a, i), &p); - - *pp = p; - return (r); - } - - pStart = p; /* Catch the beg of Setblobs */ - /* In this array we will store the SET blobs */ - rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB)); - if (rgSetBlob == NULL) { - ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE); - return (0); - } - - for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) { - rgSetBlob[i].pbData = p; /* catch each set encode blob */ - i2d(sk_OPENSSL_BLOCK_value(a, i), &p); - rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this - * SetBlob */ - } - *pp = p; - totSize = p - pStart; /* This is the total size of all set blobs */ - - /* - * Now we have to sort the blobs. I am using a simple algo. *Sort ptrs - * *Copy to temp-mem *Copy from temp-mem to user-mem - */ - qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp); - if (!(pTempMem = OPENSSL_malloc(totSize))) { - ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE); - return (0); - } - -/* Copy to temp mem */ - p = pTempMem; - for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) { - memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData); - p += rgSetBlob[i].cbData; - } - -/* Copy back to user mem*/ - memcpy(pStart, pTempMem, totSize); - OPENSSL_free(pTempMem); - OPENSSL_free(rgSetBlob); - - return (r); -} - -STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, - const unsigned char **pp, - long length, d2i_of_void *d2i, - void (*free_func) (OPENSSL_BLOCK), - int ex_tag, int ex_class) -{ - ASN1_const_CTX c; - STACK_OF(OPENSSL_BLOCK) *ret = NULL; - - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) { - ASN1err(ASN1_F_D2I_ASN1_SET, ERR_R_MALLOC_FAILURE); - goto err; - } - } else - ret = (*a); - - c.p = *pp; - c.max = (length == 0) ? 0 : (c.p + length); - - c.inf = ASN1_get_object(&c.p, &c.slen, &c.tag, &c.xclass, c.max - c.p); - if (c.inf & 0x80) - goto err; - if (ex_class != c.xclass) { - ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_CLASS); - goto err; - } - if (ex_tag != c.tag) { - ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_TAG); - goto err; - } - if ((c.slen + c.p) > c.max) { - ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_LENGTH_ERROR); - goto err; - } - /* - * check for infinite constructed - it can be as long as the amount of - * data passed to us - */ - if (c.inf == (V_ASN1_CONSTRUCTED + 1)) - c.slen = length + *pp - c.p; - c.max = c.p + c.slen; - - while (c.p < c.max) { - char *s; - - if (M_ASN1_D2I_end_sequence()) - break; - /* - * XXX: This was called with 4 arguments, incorrectly, it seems if - * ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) - */ - if ((s = d2i(NULL, &c.p, c.slen)) == NULL) { - ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_ERROR_PARSING_SET_ELEMENT); - asn1_add_error(*pp, (int)(c.p - *pp)); - goto err; - } - if (!sk_OPENSSL_BLOCK_push(ret, s)) - goto err; - } - if (a != NULL) - (*a) = ret; - *pp = c.p; - return (ret); - err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) { - if (free_func != NULL) - sk_OPENSSL_BLOCK_pop_free(ret, free_func); - else - sk_OPENSSL_BLOCK_free(ret); - } - return (NULL); -} - -#endif -/* crypto/asn1/a_sign.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -// #include "cryptlib.h" - -#ifndef NO_SYS_TYPES_H -# include -#endif - -// #include "bn.h" -// #include "evp.h" -// #include "x509.h" -// #include "objects.h" -// #include "buffer.h" -// #include "asn1_locl.h" - -#ifndef NO_ASN1_OLD - -int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, - const EVP_MD *type) -{ - EVP_MD_CTX ctx; - unsigned char *p, *buf_in = NULL, *buf_out = NULL; - int i, inl = 0, outl = 0, outll = 0; - X509_ALGOR *a; - - EVP_MD_CTX_init(&ctx); - for (i = 0; i < 2; i++) { - if (i == 0) - a = algor1; - else - a = algor2; - if (a == NULL) - continue; - if (type->pkey_type == NID_dsaWithSHA1) { - /* - * special case: RFC 2459 tells us to omit 'parameters' with - * id-dsa-with-sha1 - */ - ASN1_TYPE_free(a->parameter); - a->parameter = NULL; - } else if ((a->parameter == NULL) || - (a->parameter->type != V_ASN1_NULL)) { - ASN1_TYPE_free(a->parameter); - if ((a->parameter = ASN1_TYPE_new()) == NULL) - goto err; - a->parameter->type = V_ASN1_NULL; - } - ASN1_OBJECT_free(a->algorithm); - a->algorithm = OBJ_nid2obj(type->pkey_type); - if (a->algorithm == NULL) { - ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE); - goto err; - } - if (a->algorithm->length == 0) { - ASN1err(ASN1_F_ASN1_SIGN, - ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); - goto err; - } - } - inl = i2d(data, NULL); - buf_in = (unsigned char *)OPENSSL_malloc((unsigned int)inl); - outll = outl = EVP_PKEY_size(pkey); - buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl); - if ((buf_in == NULL) || (buf_out == NULL)) { - outl = 0; - ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - p = buf_in; - - i2d(data, &p); - if (!EVP_SignInit_ex(&ctx, type, NULL) - || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl) - || !EVP_SignFinal(&ctx, (unsigned char *)buf_out, - (unsigned int *)&outl, pkey)) { - outl = 0; - ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB); - goto err; - } - if (signature->data != NULL) - OPENSSL_free(signature->data); - signature->data = buf_out; - buf_out = NULL; - signature->length = outl; - /* - * In the interests of compatibility, I'll make sure that the bit string - * has a 'not-used bits' value of 0 - */ - signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; - err: - EVP_MD_CTX_cleanup(&ctx); - if (buf_in != NULL) { - OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); - OPENSSL_free(buf_in); - } - if (buf_out != NULL) { - OPENSSL_cleanse((char *)buf_out, outll); - OPENSSL_free(buf_out); - } - return (outl); -} - -#endif - -int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, - EVP_PKEY *pkey, const EVP_MD *type) -{ - EVP_MD_CTX ctx; - EVP_MD_CTX_init(&ctx); - if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) { - EVP_MD_CTX_cleanup(&ctx); - return 0; - } - return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); -} - -int ASN1_item_sign_ctx(const ASN1_ITEM *it, - X509_ALGOR *algor1, X509_ALGOR *algor2, - ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) -{ - const EVP_MD *type; - EVP_PKEY *pkey; - unsigned char *buf_in = NULL, *buf_out = NULL; - size_t inl = 0, outl = 0, outll = 0; - int signid, paramtype; - int rv; - - type = EVP_MD_CTX_md(ctx); - pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); - - if (!type || !pkey) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); - return 0; - } - - if (pkey->ameth->item_sign) { - rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); - if (rv == 1) - outl = signature->length; - /*- - * Return value meanings: - * <=0: error. - * 1: method does everything. - * 2: carry on as normal. - * 3: ASN1 method sets algorithm identifiers: just sign. - */ - if (rv <= 0) - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); - if (rv <= 1) - goto err; - } else - rv = 2; - - if (rv == 2) { - if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { - if (!pkey->ameth || - !OBJ_find_sigid_by_algs(&signid, - EVP_MD_nid(type), - pkey->ameth->pkey_id)) { - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, - ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); - return 0; - } - } else - signid = type->pkey_type; - - if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) - paramtype = V_ASN1_NULL; - else - paramtype = V_ASN1_UNDEF; - - if (algor1) - X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); - if (algor2) - X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); - - } - - inl = ASN1_item_i2d(asn, &buf_in, it); - outll = outl = EVP_PKEY_size(pkey); - buf_out = OPENSSL_malloc((unsigned int)outl); - if ((buf_in == NULL) || (buf_out == NULL)) { - outl = 0; - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_DigestSignUpdate(ctx, buf_in, inl) - || !EVP_DigestSignFinal(ctx, buf_out, &outl)) { - outl = 0; - ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); - goto err; - } - if (signature->data != NULL) - OPENSSL_free(signature->data); - signature->data = buf_out; - buf_out = NULL; - signature->length = outl; - /* - * In the interests of compatibility, I'll make sure that the bit string - * has a 'not-used bits' value of 0 - */ - signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; - err: - EVP_MD_CTX_cleanup(ctx); - if (buf_in != NULL) { - OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); - OPENSSL_free(buf_in); - } - if (buf_out != NULL) { - OPENSSL_cleanse((char *)buf_out, outll); - OPENSSL_free(buf_out); - } - return (outl); -} -/* a_strex.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -#include "crypto.h" -// #include "x509.h" -// #include "asn1.h" - -#include "charmap.h" - -/* - * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name - * printing routines handling multibyte characters, RFC2253 and a host of - * other options. - */ - -#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) - -#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ - ASN1_STRFLGS_ESC_QUOTE | \ - ASN1_STRFLGS_ESC_CTRL | \ - ASN1_STRFLGS_ESC_MSB) - -/* - * Three IO functions for sending data to memory, a BIO and and a FILE - * pointer. - */ -#if 0 /* never used */ -static int send_mem_chars(void *arg, const void *buf, int len) -{ - unsigned char **out = arg; - if (!out) - return 1; - memcpy(*out, buf, len); - *out += len; - return 1; -} -#endif - -static int send_bio_chars(void *arg, const void *buf, int len) -{ - if (!arg) - return 1; - if (BIO_write(arg, buf, len) != len) - return 0; - return 1; -} - -static int send_fp_chars(void *arg, const void *buf, int len) -{ - if (!arg) - return 1; - if (fwrite(buf, 1, len, arg) != (unsigned int)len) - return 0; - return 1; -} - -typedef int char_io (void *arg, const void *buf, int len); - -/* - * This function handles display of strings, one character at a time. It is - * passed an unsigned long for each character because it could come from 2 or - * even 4 byte forms. - */ - -static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, - char_io *io_ch, void *arg) -{ - unsigned char chflgs, chtmp; - char tmphex[HEX_SIZE(long) + 3]; - - if (c > 0xffffffffL) - return -1; - if (c > 0xffff) { - BIO_snprintf(tmphex, sizeof(tmphex), "\\W%08lX", c); - if (!io_ch(arg, tmphex, 10)) - return -1; - return 10; - } - if (c > 0xff) { - BIO_snprintf(tmphex, sizeof(tmphex), "\\U%04lX", c); - if (!io_ch(arg, tmphex, 6)) - return -1; - return 6; - } - chtmp = (unsigned char)c; - if (chtmp > 0x7f) - chflgs = flags & ASN1_STRFLGS_ESC_MSB; - else - chflgs = char_type[chtmp] & flags; - if (chflgs & CHARTYPE_BS_ESC) { - /* If we don't escape with quotes, signal we need quotes */ - if (chflgs & ASN1_STRFLGS_ESC_QUOTE) { - if (do_quotes) - *do_quotes = 1; - if (!io_ch(arg, &chtmp, 1)) - return -1; - return 1; - } - if (!io_ch(arg, "\\", 1)) - return -1; - if (!io_ch(arg, &chtmp, 1)) - return -1; - return 2; - } - if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)) { - BIO_snprintf(tmphex, 11, "\\%02X", chtmp); - if (!io_ch(arg, tmphex, 3)) - return -1; - return 3; - } - /* - * If we get this far and do any escaping at all must escape the escape - * character itself: backslash. - */ - if (chtmp == '\\' && flags & ESC_FLAGS) { - if (!io_ch(arg, "\\\\", 2)) - return -1; - return 2; - } - if (!io_ch(arg, &chtmp, 1)) - return -1; - return 1; -} - -#define BUF_TYPE_WIDTH_MASK 0x7 -#define BUF_TYPE_CONVUTF8 0x8 - -/* - * This function sends each character in a buffer to do_esc_char(). It - * interprets the content formats and converts to or from UTF8 as - * appropriate. - */ - -static int do_buf(unsigned char *buf, int buflen, - int type, unsigned char flags, char *quotes, char_io *io_ch, - void *arg) -{ - int i, outlen, len, charwidth; - unsigned char orflags, *p, *q; - unsigned long c; - p = buf; - q = buf + buflen; - outlen = 0; - charwidth = type & BUF_TYPE_WIDTH_MASK; - - switch (charwidth) { - case 4: - if (buflen & 3) { - ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); - return -1; - } - break; - case 2: - if (buflen & 1) { - ASN1err(ASN1_F_DO_BUF, ASN1_R_INVALID_BMPSTRING_LENGTH); - return -1; - } - break; - default: - break; - } - - while (p != q) { - if (p == buf && flags & ASN1_STRFLGS_ESC_2253) - orflags = CHARTYPE_FIRST_ESC_2253; - else - orflags = 0; - - switch (charwidth) { - case 4: - c = ((unsigned long)*p++) << 24; - c |= ((unsigned long)*p++) << 16; - c |= ((unsigned long)*p++) << 8; - c |= *p++; - break; - - case 2: - c = ((unsigned long)*p++) << 8; - c |= *p++; - break; - - case 1: - c = *p++; - break; - - case 0: - i = UTF8_getc(p, buflen, &c); - if (i < 0) - return -1; /* Invalid UTF8String */ - buflen -= i; - p += i; - break; - default: - return -1; /* invalid width */ - } - if (p == q && flags & ASN1_STRFLGS_ESC_2253) - orflags = CHARTYPE_LAST_ESC_2253; - if (type & BUF_TYPE_CONVUTF8) { - unsigned char utfbuf[6]; - int utflen; - utflen = UTF8_putc(utfbuf, sizeof(utfbuf), c); - for (i = 0; i < utflen; i++) { - /* - * We don't need to worry about setting orflags correctly - * because if utflen==1 its value will be correct anyway - * otherwise each character will be > 0x7f and so the - * character will never be escaped on first and last. - */ - len = - do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), - quotes, io_ch, arg); - if (len < 0) - return -1; - outlen += len; - } - } else { - len = - do_esc_char(c, (unsigned char)(flags | orflags), quotes, - io_ch, arg); - if (len < 0) - return -1; - outlen += len; - } - } - return outlen; -} - -/* This function hex dumps a buffer of characters */ - -static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, - int buflen) -{ - static const char hexdig[] = "0123456789ABCDEF"; - unsigned char *p, *q; - char hextmp[2]; - if (arg) { - p = buf; - q = buf + buflen; - while (p != q) { - hextmp[0] = hexdig[*p >> 4]; - hextmp[1] = hexdig[*p & 0xf]; - if (!io_ch(arg, hextmp, 2)) - return -1; - p++; - } - } - return buflen << 1; -} - -/* - * "dump" a string. This is done when the type is unknown, or the flags - * request it. We can either dump the content octets or the entire DER - * encoding. This uses the RFC2253 #01234 format. - */ - -static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, - ASN1_STRING *str) -{ - /* - * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to - * readily obtained - */ - ASN1_TYPE t; - unsigned char *der_buf, *p; - int outlen, der_len; - - if (!io_ch(arg, "#", 1)) - return -1; - /* If we don't dump DER encoding just dump content octets */ - if (!(lflags & ASN1_STRFLGS_DUMP_DER)) { - outlen = do_hex_dump(io_ch, arg, str->data, str->length); - if (outlen < 0) - return -1; - return outlen + 1; - } - t.type = str->type; - t.value.ptr = (char *)str; - der_len = i2d_ASN1_TYPE(&t, NULL); - der_buf = OPENSSL_malloc(der_len); - if (!der_buf) - return -1; - p = der_buf; - i2d_ASN1_TYPE(&t, &p); - outlen = do_hex_dump(io_ch, arg, der_buf, der_len); - OPENSSL_free(der_buf); - if (outlen < 0) - return -1; - return outlen + 1; -} - -/* - * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is - * used for non string types otherwise it is the number of bytes per - * character - */ - -static const signed char tag2nbyte[] = { - -1, -1, -1, -1, -1, /* 0-4 */ - -1, -1, -1, -1, -1, /* 5-9 */ - -1, -1, 0, -1, /* 10-13 */ - -1, -1, -1, -1, /* 15-17 */ - 1, 1, 1, /* 18-20 */ - -1, 1, 1, 1, /* 21-24 */ - -1, 1, -1, /* 25-27 */ - 4, -1, 2 /* 28-30 */ -}; - -/* - * This is the main function, print out an ASN1_STRING taking note of various - * escape and display options. Returns number of characters written or -1 if - * an error occurred. - */ - -static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, - ASN1_STRING *str) -{ - int outlen, len; - int type; - char quotes; - unsigned char flags; - quotes = 0; - /* Keep a copy of escape flags */ - flags = (unsigned char)(lflags & ESC_FLAGS); - - type = str->type; - - outlen = 0; - - if (lflags & ASN1_STRFLGS_SHOW_TYPE) { - const char *tagname; - tagname = ASN1_tag2str(type); - outlen += strlen(tagname); - if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) - return -1; - outlen++; - } - - /* Decide what to do with type, either dump content or display it */ - - /* Dump everything */ - if (lflags & ASN1_STRFLGS_DUMP_ALL) - type = -1; - /* Ignore the string type */ - else if (lflags & ASN1_STRFLGS_IGNORE_TYPE) - type = 1; - else { - /* Else determine width based on type */ - if ((type > 0) && (type < 31)) - type = tag2nbyte[type]; - else - type = -1; - if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) - type = 1; - } - - if (type == -1) { - len = do_dump(lflags, io_ch, arg, str); - if (len < 0) - return -1; - outlen += len; - return outlen; - } - - if (lflags & ASN1_STRFLGS_UTF8_CONVERT) { - /* - * Note: if string is UTF8 and we want to convert to UTF8 then we - * just interpret it as 1 byte per character to avoid converting - * twice. - */ - if (!type) - type = 1; - else - type |= BUF_TYPE_CONVUTF8; - } - - len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL); - if (len < 0) - return -1; - outlen += len; - if (quotes) - outlen += 2; - if (!arg) - return outlen; - if (quotes && !io_ch(arg, "\"", 1)) - return -1; - if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0) - return -1; - if (quotes && !io_ch(arg, "\"", 1)) - return -1; - return outlen; -} - -/* Used for line indenting: print 'indent' spaces */ - -static int do_indent(char_io *io_ch, void *arg, int indent) -{ - int i; - for (i = 0; i < indent; i++) - if (!io_ch(arg, " ", 1)) - return 0; - return 1; -} - -#define FN_WIDTH_LN 25 -#define FN_WIDTH_SN 10 - -static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, - int indent, unsigned long flags) -{ - int i, prev = -1, orflags, cnt; - int fn_opt, fn_nid; - ASN1_OBJECT *fn; - ASN1_STRING *val; - X509_NAME_ENTRY *ent; - char objtmp[80]; - const char *objbuf; - int outlen, len; - char *sep_dn, *sep_mv, *sep_eq; - int sep_dn_len, sep_mv_len, sep_eq_len; - if (indent < 0) - indent = 0; - outlen = indent; - if (!do_indent(io_ch, arg, indent)) - return -1; - switch (flags & XN_FLAG_SEP_MASK) { - case XN_FLAG_SEP_MULTILINE: - sep_dn = "\n"; - sep_dn_len = 1; - sep_mv = " + "; - sep_mv_len = 3; - break; - - case XN_FLAG_SEP_COMMA_PLUS: - sep_dn = ","; - sep_dn_len = 1; - sep_mv = "+"; - sep_mv_len = 1; - indent = 0; - break; - - case XN_FLAG_SEP_CPLUS_SPC: - sep_dn = ", "; - sep_dn_len = 2; - sep_mv = " + "; - sep_mv_len = 3; - indent = 0; - break; - - case XN_FLAG_SEP_SPLUS_SPC: - sep_dn = "; "; - sep_dn_len = 2; - sep_mv = " + "; - sep_mv_len = 3; - indent = 0; - break; - - default: - return -1; - } - - if (flags & XN_FLAG_SPC_EQ) { - sep_eq = " = "; - sep_eq_len = 3; - } else { - sep_eq = "="; - sep_eq_len = 1; - } - - fn_opt = flags & XN_FLAG_FN_MASK; - - cnt = X509_NAME_entry_count(n); - for (i = 0; i < cnt; i++) { - if (flags & XN_FLAG_DN_REV) - ent = X509_NAME_get_entry(n, cnt - i - 1); - else - ent = X509_NAME_get_entry(n, i); - if (prev != -1) { - if (prev == ent->set) { - if (!io_ch(arg, sep_mv, sep_mv_len)) - return -1; - outlen += sep_mv_len; - } else { - if (!io_ch(arg, sep_dn, sep_dn_len)) - return -1; - outlen += sep_dn_len; - if (!do_indent(io_ch, arg, indent)) - return -1; - outlen += indent; - } - } - prev = ent->set; - fn = X509_NAME_ENTRY_get_object(ent); - val = X509_NAME_ENTRY_get_data(ent); - fn_nid = OBJ_obj2nid(fn); - if (fn_opt != XN_FLAG_FN_NONE) { - int objlen, fld_len; - if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) { - OBJ_obj2txt(objtmp, sizeof(objtmp), fn, 1); - fld_len = 0; /* XXX: what should this be? */ - objbuf = objtmp; - } else { - if (fn_opt == XN_FLAG_FN_SN) { - fld_len = FN_WIDTH_SN; - objbuf = OBJ_nid2sn(fn_nid); - } else if (fn_opt == XN_FLAG_FN_LN) { - fld_len = FN_WIDTH_LN; - objbuf = OBJ_nid2ln(fn_nid); - } else { - fld_len = 0; /* XXX: what should this be? */ - objbuf = ""; - } - } - objlen = strlen(objbuf); - if (!io_ch(arg, objbuf, objlen)) - return -1; - if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) { - if (!do_indent(io_ch, arg, fld_len - objlen)) - return -1; - outlen += fld_len - objlen; - } - if (!io_ch(arg, sep_eq, sep_eq_len)) - return -1; - outlen += objlen + sep_eq_len; - } - /* - * If the field name is unknown then fix up the DER dump flag. We - * might want to limit this further so it will DER dump on anything - * other than a few 'standard' fields. - */ - if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) - orflags = ASN1_STRFLGS_DUMP_ALL; - else - orflags = 0; - - len = do_print_ex(io_ch, arg, flags | orflags, val); - if (len < 0) - return -1; - outlen += len; - } - return outlen; -} - -/* Wrappers round the main functions */ - -int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, - unsigned long flags) -{ - if (flags == XN_FLAG_COMPAT) - return X509_NAME_print(out, nm, indent); - return do_name_ex(send_bio_chars, out, nm, indent, flags); -} - -#ifndef OPENSSL_NO_FP_API -int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, - unsigned long flags) -{ - if (flags == XN_FLAG_COMPAT) { - BIO *btmp; - int ret; - btmp = BIO_new_fp(fp, BIO_NOCLOSE); - if (!btmp) - return -1; - ret = X509_NAME_print(btmp, nm, indent); - BIO_free(btmp); - return ret; - } - return do_name_ex(send_fp_chars, fp, nm, indent, flags); -} -#endif - -int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags) -{ - return do_print_ex(send_bio_chars, out, flags, str); -} - -#ifndef OPENSSL_NO_FP_API -int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags) -{ - return do_print_ex(send_fp_chars, fp, flags, str); -} -#endif - -/* - * Utility function: convert any string type to UTF8, returns number of bytes - * in output string or a negative error code - */ - -int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) -{ - ASN1_STRING stmp, *str = &stmp; - int mbflag, type, ret; - if (!in) - return -1; - type = in->type; - if ((type < 0) || (type > 30)) - return -1; - mbflag = tag2nbyte[type]; - if (mbflag == -1) - return -1; - mbflag |= MBSTRING_FLAG; - stmp.data = NULL; - stmp.length = 0; - stmp.flags = 0; - ret = - ASN1_mbstring_copy(&str, in->data, in->length, mbflag, - B_ASN1_UTF8STRING); - if (ret < 0) - return ret; - *out = stmp.data; - return stmp.length; -} -/* a_strnid.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "objects.h" - -static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; -static void st_free(ASN1_STRING_TABLE *tbl); -static int sk_table_cmp(const ASN1_STRING_TABLE *const *a, - const ASN1_STRING_TABLE *const *b); - -/* - * This is the global mask for the mbstring functions: this is use to mask - * out certain types (such as BMPString and UTF8String) because certain - * software (e.g. Netscape) has problems with them. - */ - -static unsigned long global_mask = B_ASN1_UTF8STRING; - -void ASN1_STRING_set_default_mask(unsigned long mask) -{ - global_mask = mask; -} - -unsigned long ASN1_STRING_get_default_mask(void) -{ - return global_mask; -} - -/*- - * This function sets the default to various "flavours" of configuration. - * based on an ASCII string. Currently this is: - * MASK:XXXX : a numerical mask value. - * nobmp : Don't use BMPStrings (just Printable, T61). - * pkix : PKIX recommendation in RFC2459. - * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004). - * default: the default value, Printable, T61, BMP. - */ - -int ASN1_STRING_set_default_mask_asc(const char *p) -{ - unsigned long mask; - char *end; - if (!strncmp(p, "MASK:", 5)) { - if (!p[5]) - return 0; - mask = strtoul(p + 5, &end, 0); - if (*end) - return 0; - } else if (!strcmp(p, "nombstr")) - mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING)); - else if (!strcmp(p, "pkix")) - mask = ~((unsigned long)B_ASN1_T61STRING); - else if (!strcmp(p, "utf8only")) - mask = B_ASN1_UTF8STRING; - else if (!strcmp(p, "default")) - mask = 0xFFFFFFFFL; - else - return 0; - ASN1_STRING_set_default_mask(mask); - return 1; -} - -/* - * The following function generates an ASN1_STRING based on limits in a - * table. Frequently the types and length of an ASN1_STRING are restricted by - * a corresponding OID. For example certificates and certificate requests. - */ - -ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, - const unsigned char *in, int inlen, - int inform, int nid) -{ - ASN1_STRING_TABLE *tbl; - ASN1_STRING *str = NULL; - unsigned long mask; - int ret; - if (!out) - out = &str; - tbl = ASN1_STRING_TABLE_get(nid); - if (tbl) { - mask = tbl->mask; - if (!(tbl->flags & STABLE_NO_MASK)) - mask &= global_mask; - ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask, - tbl->minsize, tbl->maxsize); - } else - ret = - ASN1_mbstring_copy(out, in, inlen, inform, - DIRSTRING_TYPE & global_mask); - if (ret <= 0) - return NULL; - return *out; -} - -/* - * Now the tables and helper functions for the string table: - */ - -/* size limits: this stuff is taken straight from RFC3280 */ - -#define ub_name 32768 -#define ub_common_name 64 -#define ub_locality_name 128 -#define ub_state_name 128 -#define ub_organization_name 64 -#define ub_organization_unit_name 64 -#define ub_title 64 -#define ub_email_address 128 -#define ub_serial_number 64 - -/* This table must be kept in NID order */ - -static const ASN1_STRING_TABLE tbl_standard[] = { - {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, - {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, - {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, - {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0}, - {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0}, - {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, - 0}, - {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, - STABLE_NO_MASK}, - {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0}, - {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0}, - {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0}, - {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0}, - {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0}, - {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0}, - {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, - STABLE_NO_MASK}, - {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}, - {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, - {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, - {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK}, - {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}, - {NID_jurisdictionCountryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK} -}; - -static int sk_table_cmp(const ASN1_STRING_TABLE *const *a, - const ASN1_STRING_TABLE *const *b) -{ - return (*a)->nid - (*b)->nid; -} - -DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table); - -static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b) -{ - return a->nid - b->nid; -} - -IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table); - -ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) -{ - int idx; - ASN1_STRING_TABLE *ttmp; - ASN1_STRING_TABLE fnd; - fnd.nid = nid; - ttmp = OBJ_bsearch_table(&fnd, tbl_standard, - sizeof(tbl_standard) / - sizeof(ASN1_STRING_TABLE)); - if (ttmp) - return ttmp; - if (!stable) - return NULL; - idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); - if (idx < 0) - return NULL; - return sk_ASN1_STRING_TABLE_value(stable, idx); -} - -int ASN1_STRING_TABLE_add(int nid, - long minsize, long maxsize, unsigned long mask, - unsigned long flags) -{ - ASN1_STRING_TABLE *tmp; - char new_nid = 0; - flags &= ~STABLE_FLAGS_MALLOC; - if (!stable) - stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp); - if (!stable) { - ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!(tmp = ASN1_STRING_TABLE_get(nid))) { - tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)); - if (!tmp) { - ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - tmp->flags = flags | STABLE_FLAGS_MALLOC; - tmp->nid = nid; - tmp->minsize = tmp->maxsize = -1; - new_nid = 1; - } else - tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags; - if (minsize != -1) - tmp->minsize = minsize; - if (maxsize != -1) - tmp->maxsize = maxsize; - tmp->mask = mask; - if (new_nid) - sk_ASN1_STRING_TABLE_push(stable, tmp); - return 1; -} - -void ASN1_STRING_TABLE_cleanup(void) -{ - STACK_OF(ASN1_STRING_TABLE) *tmp; - tmp = stable; - if (!tmp) - return; - stable = NULL; - sk_ASN1_STRING_TABLE_pop_free(tmp, st_free); -} - -static void st_free(ASN1_STRING_TABLE *tbl) -{ - if (tbl->flags & STABLE_FLAGS_MALLOC) - OPENSSL_free(tbl); -} - - -IMPLEMENT_STACK_OF(ASN1_STRING_TABLE) - -#ifdef STRING_TABLE_TEST - -main() -{ - ASN1_STRING_TABLE *tmp; - int i, last_nid = -1; - - for (tmp = tbl_standard, i = 0; - i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) { - if (tmp->nid < last_nid) { - last_nid = 0; - break; - } - last_nid = tmp->nid; - } - - if (last_nid != 0) { - printf("Table order OK\n"); - exit(0); - } - - for (tmp = tbl_standard, i = 0; - i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) - printf("Index %d, NID %d, Name=%s\n", i, tmp->nid, - OBJ_nid2ln(tmp->nid)); - -} - -#endif -/* crypto/asn1/a_time.c */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/*- - * This is an implementation of the ASN1 Time structure which is: - * Time ::= CHOICE { - * utcTime UTCTime, - * generalTime GeneralizedTime } - * written by Steve Henson. - */ - -#include -#include -// #include "cryptlib.h" -// #include "o_time.h" -// #include "asn1t.h" -// #include "asn1_locl.h" - -IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) - -IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME) - -#if 0 -int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp) -{ -# ifdef CHARSET_EBCDIC - /* KLUDGE! We convert to ascii before writing DER */ - char tmp[24]; - ASN1_STRING tmpstr; - - if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) { - int len; - - tmpstr = *(ASN1_STRING *)a; - len = tmpstr.length; - ebcdic2ascii(tmp, tmpstr.data, - (len >= sizeof(tmp)) ? sizeof(tmp) : len); - tmpstr.data = tmp; - a = (ASN1_GENERALIZEDTIME *)&tmpstr; - } -# endif - if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) - return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, - a->type, V_ASN1_UNIVERSAL)); - ASN1err(ASN1_F_I2D_ASN1_TIME, ASN1_R_EXPECTING_A_TIME); - return -1; -} -#endif - -ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) -{ - return ASN1_TIME_adj(s, t, 0, 0); -} - -ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, - int offset_day, long offset_sec) -{ - struct tm *ts; - struct tm data; - - ts = OPENSSL_gmtime(&t, &data); - if (ts == NULL) { - ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME); - return NULL; - } - if (offset_day || offset_sec) { - if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) - return NULL; - } - if ((ts->tm_year >= 50) && (ts->tm_year < 150)) - return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); - return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); -} - -int ASN1_TIME_check(ASN1_TIME *t) -{ - if (t->type == V_ASN1_GENERALIZEDTIME) - return ASN1_GENERALIZEDTIME_check(t); - else if (t->type == V_ASN1_UTCTIME) - return ASN1_UTCTIME_check(t); - return 0; -} - -/* Convert an ASN1_TIME structure to GeneralizedTime */ -ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, - ASN1_GENERALIZEDTIME **out) -{ - ASN1_GENERALIZEDTIME *ret = NULL; - char *str; - int newlen; - - if (!ASN1_TIME_check(t)) - return NULL; - - if (!out || !*out) { - if (!(ret = ASN1_GENERALIZEDTIME_new())) - goto err; - } else { - ret = *out; - } - - /* If already GeneralizedTime just copy across */ - if (t->type == V_ASN1_GENERALIZEDTIME) { - if (!ASN1_STRING_set(ret, t->data, t->length)) - goto err; - goto done; - } - - /* grow the string */ - if (!ASN1_STRING_set(ret, NULL, t->length + 2)) - goto err; - /* ASN1_STRING_set() allocated 'len + 1' bytes. */ - newlen = t->length + 2 + 1; - str = (char *)ret->data; - /* Work out the century and prepend */ - if (t->data[0] >= '5') - BUF_strlcpy(str, "19", newlen); - else - BUF_strlcpy(str, "20", newlen); - - BUF_strlcat(str, (char *)t->data, newlen); - - done: - if (out != NULL && *out == NULL) - *out = ret; - return ret; - - err: - if (out == NULL || *out != ret) - ASN1_GENERALIZEDTIME_free(ret); - return NULL; -} - - -int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) -{ - ASN1_TIME t; - - t.length = strlen(str); - t.data = (unsigned char *)str; - t.flags = 0; - - t.type = V_ASN1_UTCTIME; - - if (!ASN1_TIME_check(&t)) { - t.type = V_ASN1_GENERALIZEDTIME; - if (!ASN1_TIME_check(&t)) - return 0; - } - - if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) - return 0; - - return 1; -} - -static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t) -{ - if (t == NULL) { - time_t now_t; - time(&now_t); - if (OPENSSL_gmtime(&now_t, tm)) - return 1; - return 0; - } - - if (t->type == V_ASN1_UTCTIME) - return asn1_utctime_to_tm(tm, t); - else if (t->type == V_ASN1_GENERALIZEDTIME) - return asn1_generalizedtime_to_tm(tm, t); - - return 0; -} - -int ASN1_TIME_diff(int *pday, int *psec, - const ASN1_TIME *from, const ASN1_TIME *to) -{ - struct tm tm_from, tm_to; - if (!asn1_time_to_tm(&tm_from, from)) - return 0; - if (!asn1_time_to_tm(&tm_to, to)) - return 0; - return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to); -} -/* crypto/asn1/a_type.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "objects.h" - -int ASN1_TYPE_get(ASN1_TYPE *a) -{ - if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL)) - return (a->type); - else - return (0); -} - -void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) -{ - if (a->value.ptr != NULL) { - ASN1_TYPE **tmp_a = &a; - ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL); - } - a->type = type; - if (type == V_ASN1_BOOLEAN) - a->value.boolean = value ? 0xff : 0; - else - a->value.ptr = value; -} - -int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) -{ - if (!value || (type == V_ASN1_BOOLEAN)) { - void *p = (void *)value; - ASN1_TYPE_set(a, type, p); - } else if (type == V_ASN1_OBJECT) { - ASN1_OBJECT *odup; - odup = OBJ_dup(value); - if (!odup) - return 0; - ASN1_TYPE_set(a, type, odup); - } else { - ASN1_STRING *sdup; - sdup = ASN1_STRING_dup(value); - if (!sdup) - return 0; - ASN1_TYPE_set(a, type, sdup); - } - return 1; -} - -IMPLEMENT_STACK_OF(ASN1_TYPE) - -IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) - -/* Returns 0 if they are equal, != 0 otherwise. */ -int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) -{ - int result = -1; - - if (!a || !b || a->type != b->type) - return -1; - - switch (a->type) { - case V_ASN1_OBJECT: - result = OBJ_cmp(a->value.object, b->value.object); - break; - case V_ASN1_BOOLEAN: - result = a->value.boolean - b->value.boolean; - break; - case V_ASN1_NULL: - result = 0; /* They do not have content. */ - break; - case V_ASN1_INTEGER: - case V_ASN1_ENUMERATED: - case V_ASN1_BIT_STRING: - case V_ASN1_OCTET_STRING: - case V_ASN1_SEQUENCE: - case V_ASN1_SET: - case V_ASN1_NUMERICSTRING: - case V_ASN1_PRINTABLESTRING: - case V_ASN1_T61STRING: - case V_ASN1_VIDEOTEXSTRING: - case V_ASN1_IA5STRING: - case V_ASN1_UTCTIME: - case V_ASN1_GENERALIZEDTIME: - case V_ASN1_GRAPHICSTRING: - case V_ASN1_VISIBLESTRING: - case V_ASN1_GENERALSTRING: - case V_ASN1_UNIVERSALSTRING: - case V_ASN1_BMPSTRING: - case V_ASN1_UTF8STRING: - case V_ASN1_OTHER: - default: - result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr, - (ASN1_STRING *)b->value.ptr); - break; - } - - return result; -} -/* crypto/asn1/a_utctm.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "o_time.h" -// #include "asn1.h" -// #include "asn1_locl.h" - -#if 0 -int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp) -{ -# ifndef CHARSET_EBCDIC - return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, - V_ASN1_UTCTIME, V_ASN1_UNIVERSAL)); -# else - /* KLUDGE! We convert to ascii before writing DER */ - int len; - char tmp[24]; - ASN1_STRING x = *(ASN1_STRING *)a; - - len = x.length; - ebcdic2ascii(tmp, x.data, (len >= sizeof(tmp)) ? sizeof(tmp) : len); - x.data = tmp; - return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME, V_ASN1_UNIVERSAL); -# endif -} - -ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp, - long length) -{ - ASN1_UTCTIME *ret = NULL; - - ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length, - V_ASN1_UTCTIME, V_ASN1_UNIVERSAL); - if (ret == NULL) { - ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ERR_R_NESTED_ASN1_ERROR); - return (NULL); - } -# ifdef CHARSET_EBCDIC - ascii2ebcdic(ret->data, ret->data, ret->length); -# endif - if (!ASN1_UTCTIME_check(ret)) { - ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ASN1_R_INVALID_TIME_FORMAT); - goto err; - } - - return (ret); - err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - M_ASN1_UTCTIME_free(ret); - return (NULL); -} - -#endif - -int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) -{ - static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; - static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 }; - char *a; - int n, i, l, o; - - if (d->type != V_ASN1_UTCTIME) - return (0); - l = d->length; - a = (char *)d->data; - o = 0; - - if (l < 11) - goto err; - for (i = 0; i < 6; i++) { - if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { - i++; - if (tm) - tm->tm_sec = 0; - break; - } - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - if (++o > l) - goto err; - - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if (++o > l) - goto err; - - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - switch (i) { - case 0: - tm->tm_year = n < 50 ? n + 100 : n; - break; - case 1: - tm->tm_mon = n - 1; - break; - case 2: - tm->tm_mday = n; - break; - case 3: - tm->tm_hour = n; - break; - case 4: - tm->tm_min = n; - break; - case 5: - tm->tm_sec = n; - break; - } - } - } - if (a[o] == 'Z') - o++; - else if ((a[o] == '+') || (a[o] == '-')) { - int offsign = a[o] == '-' ? 1 : -1, offset = 0; - o++; - if (o + 4 > l) - goto err; - for (i = 6; i < 8; i++) { - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = a[o] - '0'; - o++; - if ((a[o] < '0') || (a[o] > '9')) - goto err; - n = (n * 10) + a[o] - '0'; - if ((n < min[i]) || (n > max[i])) - goto err; - if (tm) { - if (i == 6) - offset = n * 3600; - else if (i == 7) - offset += n * 60; - } - o++; - } - if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign)) - return 0; - } - return o == l; - err: - return 0; -} - -int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) -{ - return asn1_utctime_to_tm(NULL, d); -} - -int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) -{ - ASN1_UTCTIME t; - - t.type = V_ASN1_UTCTIME; - t.length = strlen(str); - t.data = (unsigned char *)str; - if (ASN1_UTCTIME_check(&t)) { - if (s != NULL) { - if (!ASN1_STRING_set((ASN1_STRING *)s, - (unsigned char *)str, t.length)) - return 0; - s->type = V_ASN1_UTCTIME; - } - return (1); - } else - return (0); -} - -ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) -{ - return ASN1_UTCTIME_adj(s, t, 0, 0); -} - -ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, - int offset_day, long offset_sec) -{ - char *p; - struct tm *ts; - struct tm data; - size_t len = 20; - int free_s = 0; - - if (s == NULL) { - free_s = 1; - s = M_ASN1_UTCTIME_new(); - } - if (s == NULL) - goto err; - - ts = OPENSSL_gmtime(&t, &data); - if (ts == NULL) - goto err; - - if (offset_day || offset_sec) { - if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) - goto err; - } - - if ((ts->tm_year < 50) || (ts->tm_year >= 150)) - goto err; - - p = (char *)s->data; - if ((p == NULL) || ((size_t)s->length < len)) { - p = OPENSSL_malloc(len); - if (p == NULL) { - ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE); - goto err; - } - if (s->data != NULL) - OPENSSL_free(s->data); - s->data = (unsigned char *)p; - } - - BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100, - ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, - ts->tm_sec); - s->length = strlen(p); - s->type = V_ASN1_UTCTIME; -#ifdef CHARSET_EBCDIC_not - ebcdic2ascii(s->data, s->data, s->length); -#endif - return (s); - err: - if (free_s && s) - M_ASN1_UTCTIME_free(s); - return NULL; -} - -int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) -{ - struct tm stm, ttm; - int day, sec; - - if (!asn1_utctime_to_tm(&stm, s)) - return -2; - - if (!OPENSSL_gmtime(&t, &ttm)) - return -2; - - if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm)) - return -2; - - if (day > 0) - return 1; - if (day < 0) - return -1; - if (sec > 0) - return 1; - if (sec < 0) - return -1; - return 0; -} - -#if 0 -time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s) -{ - struct tm tm; - int offset; - - memset(&tm, '\0', sizeof(tm)); - -# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0') - tm.tm_year = g2(s->data); - if (tm.tm_year < 50) - tm.tm_year += 100; - tm.tm_mon = g2(s->data + 2) - 1; - tm.tm_mday = g2(s->data + 4); - tm.tm_hour = g2(s->data + 6); - tm.tm_min = g2(s->data + 8); - tm.tm_sec = g2(s->data + 10); - if (s->data[12] == 'Z') - offset = 0; - else { - offset = g2(s->data + 13) * 60 + g2(s->data + 15); - if (s->data[12] == '-') - offset = -offset; - } -# undef g2 - - /* - * FIXME: mktime assumes the current timezone - * instead of UTC, and unless we rewrite OpenSSL - * in Lisp we cannot locally change the timezone - * without possibly interfering with other parts - * of the program. timegm, which uses UTC, is - * non-standard. - * Also time_t is inappropriate for general - * UTC times because it may a 32 bit type. - */ - return mktime(&tm) - offset * 60; -} -#endif -/* crypto/asn1/a_utf8.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" - -/* UTF8 utilities */ - -/*- - * This parses a UTF8 string one character at a time. It is passed a pointer - * to the string and the length of the string. It sets 'value' to the value of - * the current character. It returns the number of characters read or a - * negative error code: - * -1 = string too short - * -2 = illegal character - * -3 = subsequent characters not of the form 10xxxxxx - * -4 = character encoded incorrectly (not minimal length). - */ - -int UTF8_getc(const unsigned char *str, int len, unsigned long *val) -{ - const unsigned char *p; - unsigned long value; - int ret; - if (len <= 0) - return 0; - p = str; - - /* Check syntax and work out the encoded value (if correct) */ - if ((*p & 0x80) == 0) { - value = *p++ & 0x7f; - ret = 1; - } else if ((*p & 0xe0) == 0xc0) { - if (len < 2) - return -1; - if ((p[1] & 0xc0) != 0x80) - return -3; - value = (*p++ & 0x1f) << 6; - value |= *p++ & 0x3f; - if (value < 0x80) - return -4; - ret = 2; - } else if ((*p & 0xf0) == 0xe0) { - if (len < 3) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80)) - return -3; - value = (*p++ & 0xf) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x800) - return -4; - ret = 3; - } else if ((*p & 0xf8) == 0xf0) { - if (len < 4) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80) - || ((p[3] & 0xc0) != 0x80)) - return -3; - value = ((unsigned long)(*p++ & 0x7)) << 18; - value |= (*p++ & 0x3f) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x10000) - return -4; - ret = 4; - } else if ((*p & 0xfc) == 0xf8) { - if (len < 5) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80) - || ((p[3] & 0xc0) != 0x80) - || ((p[4] & 0xc0) != 0x80)) - return -3; - value = ((unsigned long)(*p++ & 0x3)) << 24; - value |= ((unsigned long)(*p++ & 0x3f)) << 18; - value |= ((unsigned long)(*p++ & 0x3f)) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x200000) - return -4; - ret = 5; - } else if ((*p & 0xfe) == 0xfc) { - if (len < 6) - return -1; - if (((p[1] & 0xc0) != 0x80) - || ((p[2] & 0xc0) != 0x80) - || ((p[3] & 0xc0) != 0x80) - || ((p[4] & 0xc0) != 0x80) - || ((p[5] & 0xc0) != 0x80)) - return -3; - value = ((unsigned long)(*p++ & 0x1)) << 30; - value |= ((unsigned long)(*p++ & 0x3f)) << 24; - value |= ((unsigned long)(*p++ & 0x3f)) << 18; - value |= ((unsigned long)(*p++ & 0x3f)) << 12; - value |= (*p++ & 0x3f) << 6; - value |= *p++ & 0x3f; - if (value < 0x4000000) - return -4; - ret = 6; - } else - return -2; - *val = value; - return ret; -} - -/* - * This takes a character 'value' and writes the UTF8 encoded value in 'str' - * where 'str' is a buffer containing 'len' characters. Returns the number of - * characters written or -1 if 'len' is too small. 'str' can be set to NULL - * in which case it just returns the number of characters. It will need at - * most 6 characters. - */ - -int UTF8_putc(unsigned char *str, int len, unsigned long value) -{ - if (!str) - len = 6; /* Maximum we will need */ - else if (len <= 0) - return -1; - if (value < 0x80) { - if (str) - *str = (unsigned char)value; - return 1; - } - if (value < 0x800) { - if (len < 2) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 2; - } - if (value < 0x10000) { - if (len < 3) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 3; - } - if (value < 0x200000) { - if (len < 4) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 4; - } - if (value < 0x4000000) { - if (len < 5) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8); - *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 5; - } - if (len < 6) - return -1; - if (str) { - *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc); - *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); - *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); - *str = (unsigned char)((value & 0x3f) | 0x80); - } - return 6; -} -/* crypto/asn1/a_verify.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include - -// #include "cryptlib.h" -// #include "asn1_locl.h" - -#ifndef NO_SYS_TYPES_H -# include -#endif - -// #include "bn.h" -// #include "x509.h" -// #include "objects.h" -// #include "buffer.h" -// #include "evp.h" - -#ifndef NO_ASN1_OLD - -int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, - char *data, EVP_PKEY *pkey) -{ - EVP_MD_CTX ctx; - const EVP_MD *type; - unsigned char *p, *buf_in = NULL; - int ret = -1, i, inl; - - EVP_MD_CTX_init(&ctx); - i = OBJ_obj2nid(a->algorithm); - type = EVP_get_digestbyname(OBJ_nid2sn(i)); - if (type == NULL) { - ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); - goto err; - } - - if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { - ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); - goto err; - } - - inl = i2d(data, NULL); - buf_in = OPENSSL_malloc((unsigned int)inl); - if (buf_in == NULL) { - ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - p = buf_in; - - i2d(data, &p); - if (!EVP_VerifyInit_ex(&ctx, type, NULL) - || !EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl)) { - ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); - ret = 0; - goto err; - } - - OPENSSL_cleanse(buf_in, (unsigned int)inl); - OPENSSL_free(buf_in); - - if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data, - (unsigned int)signature->length, pkey) <= 0) { - ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); - ret = 0; - goto err; - } - /* - * we don't need to zero the 'ctx' because we just checked public - * information - */ - /* memset(&ctx,0,sizeof(ctx)); */ - ret = 1; - err: - EVP_MD_CTX_cleanup(&ctx); - return (ret); -} - -#endif - -int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, - ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) -{ - EVP_MD_CTX ctx; - unsigned char *buf_in = NULL; - int ret = -1, inl; - - int mdnid, pknid; - - if (!pkey) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); - return -1; - } - - if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); - return -1; - } - - EVP_MD_CTX_init(&ctx); - - /* Convert signature OID into digest and public key OIDs */ - if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); - goto err; - } - if (mdnid == NID_undef) { - if (!pkey->ameth || !pkey->ameth->item_verify) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, - ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); - goto err; - } - ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey); - /* - * Return value of 2 means carry on, anything else means we exit - * straight away: either a fatal error of the underlying verification - * routine handles all verification. - */ - if (ret != 2) - goto err; - ret = -1; - } else { - const EVP_MD *type; - type = EVP_get_digestbynid(mdnid); - if (type == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, - ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); - goto err; - } - - /* Check public key OID matches public key type */ - if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE); - goto err; - } - - if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); - ret = 0; - goto err; - } - - } - - inl = ASN1_item_i2d(asn, &buf_in, it); - - if (buf_in == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); - ret = 0; - goto err; - } - - OPENSSL_cleanse(buf_in, (unsigned int)inl); - OPENSSL_free(buf_in); - - if (EVP_DigestVerifyFinal(&ctx, signature->data, - (size_t)signature->length) <= 0) { - ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); - ret = 0; - goto err; - } - /* - * we don't need to zero the 'ctx' because we just checked public - * information - */ - /* memset(&ctx,0,sizeof(ctx)); */ - ret = 1; - err: - EVP_MD_CTX_cleanup(&ctx); - return (ret); -} diff --git a/Sources/COpenSSL/aep.h b/Sources/COpenSSL/aep.h deleted file mode 100644 index 04ab87eb..00000000 --- a/Sources/COpenSSL/aep.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * This header declares the necessary definitions for using the - * exponentiation acceleration capabilities, and rnd number generation of the - * AEP card. - */ - -/* - * - * Some AEP defines - * - */ - -/* - * Successful return value - */ -#define AEP_R_OK 0x00000000 - -/* - * Miscelleanous unsuccessful return value - */ -#define AEP_R_GENERAL_ERROR 0x10000001 - -/* - * Insufficient host memory - */ -#define AEP_R_HOST_MEMORY 0x10000002 - -#define AEP_R_FUNCTION_FAILED 0x10000006 - -/* - * Invalid arguments in function call - */ -#define AEP_R_ARGUMENTS_BAD 0x10020000 - -#define AEP_R_NO_TARGET_RESOURCES 0x10030000 - -/* - * Error occuring on socket operation - */ -#define AEP_R_SOCKERROR 0x10000010 - -/* - * Socket has been closed from the other end - */ -#define AEP_R_SOCKEOF 0x10000011 - -/* - * Invalid handles - */ -#define AEP_R_CONNECTION_HANDLE_INVALID 0x100000B3 - -#define AEP_R_TRANSACTION_HANDLE_INVALID 0x10040000 - -/* - * Transaction has not yet returned from accelerator - */ -#define AEP_R_TRANSACTION_NOT_READY 0x00010000 - -/* - * There is already a thread waiting on this transaction - */ -#define AEP_R_TRANSACTION_CLAIMED 0x10050000 - -/* - * The transaction timed out - */ -#define AEP_R_TIMED_OUT 0x10060000 - -#define AEP_R_FXN_NOT_IMPLEMENTED 0x10070000 - -#define AEP_R_TARGET_ERROR 0x10080000 - -/* - * Error in the AEP daemon process - */ -#define AEP_R_DAEMON_ERROR 0x10090000 - -/* - * Invalid ctx id - */ -#define AEP_R_INVALID_CTX_ID 0x10009000 - -#define AEP_R_NO_KEY_MANAGER 0x1000a000 - -/* - * Error obtaining a mutex - */ -#define AEP_R_MUTEX_BAD 0x000001A0 - -/* - * Fxn call before AEP_Initialise ot after AEP_Finialise - */ -#define AEP_R_AEPAPI_NOT_INITIALIZED 0x10000190 - -/* - * AEP_Initialise has already been called - */ -#define AEP_R_AEPAPI_ALREADY_INITIALIZED 0x10000191 - -/* - * Maximum number of connections to daemon reached - */ -#define AEP_R_NO_MORE_CONNECTION_HNDLS 0x10000200 - -/* - * - * Some AEP Type definitions - * - */ - -/* an unsigned 8-bit value */ -typedef unsigned char AEP_U8; - -/* an unsigned 8-bit character */ -typedef char AEP_CHAR; - -/* a BYTE-sized Boolean flag */ -typedef AEP_U8 AEP_BBOOL; - -/* - * Unsigned value, at least 16 bits long - */ -typedef unsigned short AEP_U16; - -/* an unsigned value, at least 32 bits long */ -#ifdef SIXTY_FOUR_BIT_LONG -typedef unsigned int AEP_U32; -#else -typedef unsigned long AEP_U32; -#endif - -#ifdef SIXTY_FOUR_BIT_LONG -typedef unsigned long AEP_U64; -#else -typedef struct { - unsigned long l1, l2; -} AEP_U64; -#endif - -/* at least 32 bits; each bit is a Boolean flag */ -typedef AEP_U32 AEP_FLAGS; - -typedef AEP_U8 *AEP_U8_PTR; -typedef AEP_CHAR *AEP_CHAR_PTR; -typedef AEP_U32 *AEP_U32_PTR; -typedef AEP_U64 *AEP_U64_PTR; -typedef void *AEP_VOID_PTR; - -/* Pointer to a AEP_VOID_PTR-- i.e., pointer to pointer to void */ -typedef AEP_VOID_PTR *AEP_VOID_PTR_PTR; - -/* - * Used to identify an AEP connection handle - */ -typedef AEP_U32 AEP_CONNECTION_HNDL; - -/* - * Pointer to an AEP connection handle - */ -typedef AEP_CONNECTION_HNDL *AEP_CONNECTION_HNDL_PTR; - -/* - * Used by an application (in conjunction with the apps process id) to - * identify an individual transaction - */ -typedef AEP_U32 AEP_TRANSACTION_ID; - -/* - * Pointer to an applications transaction identifier - */ -typedef AEP_TRANSACTION_ID *AEP_TRANSACTION_ID_PTR; - -/* - * Return value type - */ -typedef AEP_U32 AEP_RV; - -#define MAX_PROCESS_CONNECTIONS 256 - -#define RAND_BLK_SIZE 1024 - -typedef enum { - NotConnected = 0, - Connected = 1, - InUse = 2 -} AEP_CONNECTION_STATE; - -typedef struct AEP_CONNECTION_ENTRY { - AEP_CONNECTION_STATE conn_state; - AEP_CONNECTION_HNDL conn_hndl; -} AEP_CONNECTION_ENTRY; - -typedef AEP_RV t_AEP_OpenConnection(AEP_CONNECTION_HNDL_PTR phConnection); -typedef AEP_RV t_AEP_CloseConnection(AEP_CONNECTION_HNDL hConnection); - -typedef AEP_RV t_AEP_ModExp(AEP_CONNECTION_HNDL hConnection, - AEP_VOID_PTR pA, AEP_VOID_PTR pP, - AEP_VOID_PTR pN, - AEP_VOID_PTR pResult, - AEP_TRANSACTION_ID *pidTransID); - -typedef AEP_RV t_AEP_ModExpCrt(AEP_CONNECTION_HNDL hConnection, - AEP_VOID_PTR pA, AEP_VOID_PTR pP, - AEP_VOID_PTR pQ, - AEP_VOID_PTR pDmp1, AEP_VOID_PTR pDmq1, - AEP_VOID_PTR pIqmp, - AEP_VOID_PTR pResult, - AEP_TRANSACTION_ID *pidTransID); - -#ifdef AEPRAND -typedef AEP_RV t_AEP_GenRandom(AEP_CONNECTION_HNDL hConnection, - AEP_U32 Len, - AEP_U32 Type, - AEP_VOID_PTR pResult, - AEP_TRANSACTION_ID *pidTransID); -#endif - -typedef AEP_RV t_AEP_Initialize(AEP_VOID_PTR pInitArgs); -typedef AEP_RV t_AEP_Finalize(void); -typedef AEP_RV t_AEP_SetBNCallBacks(AEP_RV (*GetBigNumSizeFunc) - (AEP_VOID_PTR ArbBigNum, - AEP_U32 *BigNumSize), - AEP_RV (*MakeAEPBigNumFunc) (AEP_VOID_PTR - ArbBigNum, - AEP_U32 - BigNumSize, - unsigned char - *AEP_BigNum), - AEP_RV (*ConverAEPBigNumFunc) (void - *ArbBigNum, - AEP_U32 - BigNumSize, - unsigned - char - *AEP_BigNum)); diff --git a/Sources/COpenSSL/aes.h b/Sources/COpenSSL/aes.h deleted file mode 100644 index f7bcedc8..00000000 --- a/Sources/COpenSSL/aes.h +++ /dev/null @@ -1,149 +0,0 @@ -/* crypto/aes/aes.h */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#ifndef HEADER_AES_H -# define HEADER_AES_H - -# include "opensslconf.h" - -# ifdef OPENSSL_NO_AES -# error AES is disabled. -# endif - -# include - -# define AES_ENCRYPT 1 -# define AES_DECRYPT 0 - -/* - * Because array size can't be a const in C, the following two are macros. - * Both sizes are in bytes. - */ -# define AES_MAXNR 14 -# define AES_BLOCK_SIZE 16 - -#ifdef __cplusplus -extern "C" { -#endif - -/* This should be a hidden type, but EVP requires that the size be known */ -struct aes_key_st { -# ifdef AES_LONG - unsigned long rd_key[4 * (AES_MAXNR + 1)]; -# else - unsigned int rd_key[4 * (AES_MAXNR + 1)]; -# endif - int rounds; -}; -typedef struct aes_key_st AES_KEY; - -const char *AES_options(void); - -int AES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); -int AES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); - -int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); -int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); - -void AES_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void AES_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); - -void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key, const int enc); -void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, const int enc); -void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, int *num, const int enc); -void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, int *num, const int enc); -void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, int *num, const int enc); -void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, int *num); -void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char ivec[AES_BLOCK_SIZE], - unsigned char ecount_buf[AES_BLOCK_SIZE], - unsigned int *num); -/* NB: the IV is _two_ blocks long */ -void AES_ige_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, const int enc); -/* NB: the IV is _four_ blocks long */ -void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - const AES_KEY *key2, const unsigned char *ivec, - const int enc); - -int AES_wrap_key(AES_KEY *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, unsigned int inlen); -int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, unsigned int inlen); - - -#ifdef __cplusplus -} -#endif - -#endif /* !HEADER_AES_H */ diff --git a/Sources/COpenSSL/aes_.c b/Sources/COpenSSL/aes_.c deleted file mode 100644 index cca4be8d..00000000 --- a/Sources/COpenSSL/aes_.c +++ /dev/null @@ -1,2193 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/aes/aes_cbc.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "aes.h" -#include "modes.h" - -void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec, const int enc) -{ - - if (enc) - CRYPTO_cbc128_encrypt(in, out, len, key, ivec, - (block128_f) AES_encrypt); - else - CRYPTO_cbc128_decrypt(in, out, len, key, ivec, - (block128_f) AES_decrypt); -} -/* crypto/aes/aes_cfb.c */ -/* ==================================================================== - * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "aes.h" -// #include "modes.h" - -/* - * The input and output encrypted as though 128bit cfb mode is being used. - * The extra state information to record how much of the 128bit block we have - * used is contained in *num; - */ - -void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, int *num, const int enc) -{ - - CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) AES_encrypt); -} - -/* N.B. This expects the input to be packed, MS bit first */ -void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, int *num, const int enc) -{ - CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) AES_encrypt); -} - -void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, int *num, const int enc) -{ - CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) AES_encrypt); -} -/* crypto/aes/aes_core.c */ -/** - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen - * @author Antoon Bosselaers - * @author Paulo Barreto - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Note: rewritten a little bit to provide error control and an OpenSSL- - compatible API */ - -#ifndef AES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -#include -// #include "aes.h" -#include "aes_locl.h" - -#ifndef AES_ASM -/*- -Te0[x] = S [x].[02, 01, 01, 03]; -Te1[x] = S [x].[03, 02, 01, 01]; -Te2[x] = S [x].[01, 03, 02, 01]; -Te3[x] = S [x].[01, 01, 03, 02]; - -Td0[x] = Si[x].[0e, 09, 0d, 0b]; -Td1[x] = Si[x].[0b, 0e, 09, 0d]; -Td2[x] = Si[x].[0d, 0b, 0e, 09]; -Td3[x] = Si[x].[09, 0d, 0b, 0e]; -Td4[x] = Si[x].[01]; -*/ - -static const u32 Te0[256] = { - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; -static const u32 Te1[256] = { - 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, - 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, - 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, - 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, - 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, - 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, - 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, - 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, - 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, - 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, - 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, - 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, - 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, - 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, - 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, - 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, - 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, - 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, - 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, - 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, - 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, - 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, - 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, - 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, - 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, - 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, - 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, - 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, - 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, - 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, - 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, - 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, - 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, - 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, - 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, - 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, - 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, - 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, - 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, - 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, - 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, - 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, - 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, - 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, - 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, - 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, - 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, - 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, - 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, - 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, - 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, - 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, - 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, - 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, - 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, - 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, - 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, - 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, - 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, - 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, - 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, - 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, - 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, - 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, -}; -static const u32 Te2[256] = { - 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, - 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, - 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, - 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, - 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, - 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, - 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, - 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, - 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, - 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, - 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, - 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, - 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, - 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, - 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, - 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, - 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, - 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, - 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, - 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, - 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, - 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, - 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, - 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, - 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, - 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, - 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, - 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, - 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, - 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, - 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, - 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, - 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, - 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, - 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, - 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, - 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, - 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, - 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, - 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, - 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, - 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, - 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, - 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, - 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, - 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, - 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, - 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, - 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, - 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, - 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, - 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, - 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, - 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, - 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, - 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, - 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, - 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, - 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, - 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, - 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, - 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, - 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, - 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, -}; -static const u32 Te3[256] = { - 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, - 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, - 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, - 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, - 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, - 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, - 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, - 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, - 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, - 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, - 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, - 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, - 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, - 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, - 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, - 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, - 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, - 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, - 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, - 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, - 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, - 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, - 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, - 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, - 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, - 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, - 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, - 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, - 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, - 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, - 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, - 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, - 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, - 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, - 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, - 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, - 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, - 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, - 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, - 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, - 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, - 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, - 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, - 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, - 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, - 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, - 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, - 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, - 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, - 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, - 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, - 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, - 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, - 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, - 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, - 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, - 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, - 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, - 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, - 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, - 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, - 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, - 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, - 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, -}; - -static const u32 Td0[256] = { - 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, - 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, - 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, - 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, - 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, - 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, - 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, - 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, - 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, - 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, - 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, - 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, - 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, - 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, - 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, - 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, - 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, - 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, - 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, - 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, - 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, - 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, - 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, - 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, - 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, - 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, - 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, - 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, - 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, - 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, - 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, - 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, - 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, - 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, - 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, - 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, - 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, - 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, - 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, - 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, - 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, - 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, - 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, - 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, - 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, - 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, - 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, - 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, - 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, - 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, - 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, - 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, - 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, - 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, - 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, - 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, - 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, - 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, - 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, - 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, - 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, - 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, - 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, - 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, -}; -static const u32 Td1[256] = { - 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, - 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, - 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, - 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, - 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, - 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, - 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, - 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, - 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, - 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, - 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, - 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, - 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, - 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, - 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, - 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, - 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, - 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, - 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, - 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, - 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, - 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, - 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, - 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, - 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, - 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, - 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, - 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, - 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, - 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, - 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, - 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, - 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, - 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, - 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, - 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, - 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, - 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, - 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, - 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, - 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, - 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, - 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, - 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, - 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, - 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, - 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, - 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, - 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, - 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, - 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, - 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, - 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, - 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, - 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, - 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, - 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, - 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, - 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, - 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, - 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, - 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, - 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, - 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, -}; -static const u32 Td2[256] = { - 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, - 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, - 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, - 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, - 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, - 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, - 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, - 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, - 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, - 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, - 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, - 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, - 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, - 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, - 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, - 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, - 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, - 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, - 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, - 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, - 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, - 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, - 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, - 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, - 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, - 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, - 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, - 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, - 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, - 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, - 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, - 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, - 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, - 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, - 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, - 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, - 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, - 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, - 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, - 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, - 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, - 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, - 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, - 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, - 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, - 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, - 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, - 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, - 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, - 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, - 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, - 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, - 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, - 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, - 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, - 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, - 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, - 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, - 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, - 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, - 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, - 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, - 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, - 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, -}; -static const u32 Td3[256] = { - 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, - 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, - 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, - 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, - 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, - 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, - 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, - 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, - 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, - 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, - 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, - 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, - 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, - 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, - 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, - 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, - 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, - 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, - 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, - 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, - 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, - 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, - 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, - 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, - 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, - 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, - 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, - 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, - 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, - 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, - 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, - 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, - 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, - 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, - 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, - 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, - 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, - 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, - 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, - 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, - 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, - 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, - 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, - 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, - 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, - 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, - 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, - 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, - 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, - 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, - 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, - 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, - 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, - 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, - 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, - 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, - 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, - 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, - 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, - 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, - 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, - 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, - 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, - 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, -}; -static const u8 Td4[256] = { - 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, - 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, - 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, - 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, - 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, - 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, - 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, - 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, - 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, - 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, - 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, - 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, - 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, - 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, - 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, - 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, - 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, - 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, - 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, - 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, - 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, - 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, - 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, - 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, - 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, - 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, - 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, - 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, - 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, - 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, - 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, - 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, -}; -static const u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -/** - * Expand the cipher key into the encryption key schedule. - */ -int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) -{ - - u32 *rk; - int i = 0; - u32 temp; - - if (!userKey || !key) - return -1; - if (bits != 128 && bits != 192 && bits != 256) - return -2; - - rk = key->rd_key; - - if (bits==128) - key->rounds = 10; - else if (bits==192) - key->rounds = 12; - else - key->rounds = 14; - - rk[0] = GETU32(userKey ); - rk[1] = GETU32(userKey + 4); - rk[2] = GETU32(userKey + 8); - rk[3] = GETU32(userKey + 12); - if (bits == 128) { - while (1) { - temp = rk[3]; - rk[4] = rk[0] ^ - (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te0[(temp ) & 0xff] & 0x0000ff00) ^ - (Te1[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 0; - } - rk += 4; - } - } - rk[4] = GETU32(userKey + 16); - rk[5] = GETU32(userKey + 20); - if (bits == 192) { - while (1) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te0[(temp ) & 0xff] & 0x0000ff00) ^ - (Te1[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 0; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(userKey + 24); - rk[7] = GETU32(userKey + 28); - if (bits == 256) { - while (1) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ - (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ - (Te0[(temp ) & 0xff] & 0x0000ff00) ^ - (Te1[(temp >> 24) ] & 0x000000ff) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 0; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ - (Te2[(temp >> 24) ] & 0xff000000) ^ - (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^ - (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^ - (Te1[(temp ) & 0xff] & 0x000000ff); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - - rk += 8; - } - } - return 0; -} - -/** - * Expand the cipher key into the decryption key schedule. - */ -int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) -{ - - u32 *rk; - int i, j, status; - u32 temp; - - /* first, start with an encryption schedule */ - status = private_AES_set_encrypt_key(userKey, bits, key); - if (status < 0) - return status; - - rk = key->rd_key; - - /* invert the order of the round keys: */ - for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* apply the inverse MixColumn transform to all round keys but the first and the last: */ - for (i = 1; i < (key->rounds); i++) { - rk += 4; - rk[0] = - Td0[Te1[(rk[0] >> 24) ] & 0xff] ^ - Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^ - Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ - Td3[Te1[(rk[0] ) & 0xff] & 0xff]; - rk[1] = - Td0[Te1[(rk[1] >> 24) ] & 0xff] ^ - Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^ - Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ - Td3[Te1[(rk[1] ) & 0xff] & 0xff]; - rk[2] = - Td0[Te1[(rk[2] >> 24) ] & 0xff] ^ - Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^ - Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ - Td3[Te1[(rk[2] ) & 0xff] & 0xff]; - rk[3] = - Td0[Te1[(rk[3] >> 24) ] & 0xff] ^ - Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^ - Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ - Td3[Te1[(rk[3] ) & 0xff] & 0xff]; - } - return 0; -} - -/* - * Encrypt a single block - * in and out can overlap - */ -void AES_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key) { - - const u32 *rk; - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - assert(in && out && key); - rk = key->rd_key; - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(in ) ^ rk[0]; - s1 = GETU32(in + 4) ^ rk[1]; - s2 = GETU32(in + 8) ^ rk[2]; - s3 = GETU32(in + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; - if (key->rounds > 10) { - /* round 10: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; - if (key->rounds > 12) { - /* round 12: */ - s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; - s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; - s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; - s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; - t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; - t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; - t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; - } - } - rk += key->rounds << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = key->rounds >> 1; - for (;;) { - t0 = - Te0[(s0 >> 24) ] ^ - Te1[(s1 >> 16) & 0xff] ^ - Te2[(s2 >> 8) & 0xff] ^ - Te3[(s3 ) & 0xff] ^ - rk[4]; - t1 = - Te0[(s1 >> 24) ] ^ - Te1[(s2 >> 16) & 0xff] ^ - Te2[(s3 >> 8) & 0xff] ^ - Te3[(s0 ) & 0xff] ^ - rk[5]; - t2 = - Te0[(s2 >> 24) ] ^ - Te1[(s3 >> 16) & 0xff] ^ - Te2[(s0 >> 8) & 0xff] ^ - Te3[(s1 ) & 0xff] ^ - rk[6]; - t3 = - Te0[(s3 >> 24) ] ^ - Te1[(s0 >> 16) & 0xff] ^ - Te2[(s1 >> 8) & 0xff] ^ - Te3[(s2 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Te0[(t0 >> 24) ] ^ - Te1[(t1 >> 16) & 0xff] ^ - Te2[(t2 >> 8) & 0xff] ^ - Te3[(t3 ) & 0xff] ^ - rk[0]; - s1 = - Te0[(t1 >> 24) ] ^ - Te1[(t2 >> 16) & 0xff] ^ - Te2[(t3 >> 8) & 0xff] ^ - Te3[(t0 ) & 0xff] ^ - rk[1]; - s2 = - Te0[(t2 >> 24) ] ^ - Te1[(t3 >> 16) & 0xff] ^ - Te2[(t0 >> 8) & 0xff] ^ - Te3[(t1 ) & 0xff] ^ - rk[2]; - s3 = - Te0[(t3 >> 24) ] ^ - Te1[(t0 >> 16) & 0xff] ^ - Te2[(t1 >> 8) & 0xff] ^ - Te3[(t2 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - (Te2[(t0 >> 24) ] & 0xff000000) ^ - (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ - (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ - (Te1[(t3 ) & 0xff] & 0x000000ff) ^ - rk[0]; - PUTU32(out , s0); - s1 = - (Te2[(t1 >> 24) ] & 0xff000000) ^ - (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ - (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ - (Te1[(t0 ) & 0xff] & 0x000000ff) ^ - rk[1]; - PUTU32(out + 4, s1); - s2 = - (Te2[(t2 >> 24) ] & 0xff000000) ^ - (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ - (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ - (Te1[(t1 ) & 0xff] & 0x000000ff) ^ - rk[2]; - PUTU32(out + 8, s2); - s3 = - (Te2[(t3 >> 24) ] & 0xff000000) ^ - (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ - (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ - (Te1[(t2 ) & 0xff] & 0x000000ff) ^ - rk[3]; - PUTU32(out + 12, s3); -} - -/* - * Decrypt a single block - * in and out can overlap - */ -void AES_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key) -{ - - const u32 *rk; - u32 s0, s1, s2, s3, t0, t1, t2, t3; -#ifndef FULL_UNROLL - int r; -#endif /* ?FULL_UNROLL */ - - assert(in && out && key); - rk = key->rd_key; - - /* - * map byte array block to cipher state - * and add initial round key: - */ - s0 = GETU32(in ) ^ rk[0]; - s1 = GETU32(in + 4) ^ rk[1]; - s2 = GETU32(in + 8) ^ rk[2]; - s3 = GETU32(in + 12) ^ rk[3]; -#ifdef FULL_UNROLL - /* round 1: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; - /* round 2: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; - /* round 3: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; - /* round 4: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; - /* round 5: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; - /* round 6: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; - /* round 7: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; - /* round 8: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; - /* round 9: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; - if (key->rounds > 10) { - /* round 10: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; - /* round 11: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; - if (key->rounds > 12) { - /* round 12: */ - s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; - s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; - s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; - s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; - /* round 13: */ - t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; - t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; - t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; - t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; - } - } - rk += key->rounds << 2; -#else /* !FULL_UNROLL */ - /* - * Nr - 1 full rounds: - */ - r = key->rounds >> 1; - for (;;) { - t0 = - Td0[(s0 >> 24) ] ^ - Td1[(s3 >> 16) & 0xff] ^ - Td2[(s2 >> 8) & 0xff] ^ - Td3[(s1 ) & 0xff] ^ - rk[4]; - t1 = - Td0[(s1 >> 24) ] ^ - Td1[(s0 >> 16) & 0xff] ^ - Td2[(s3 >> 8) & 0xff] ^ - Td3[(s2 ) & 0xff] ^ - rk[5]; - t2 = - Td0[(s2 >> 24) ] ^ - Td1[(s1 >> 16) & 0xff] ^ - Td2[(s0 >> 8) & 0xff] ^ - Td3[(s3 ) & 0xff] ^ - rk[6]; - t3 = - Td0[(s3 >> 24) ] ^ - Td1[(s2 >> 16) & 0xff] ^ - Td2[(s1 >> 8) & 0xff] ^ - Td3[(s0 ) & 0xff] ^ - rk[7]; - - rk += 8; - if (--r == 0) { - break; - } - - s0 = - Td0[(t0 >> 24) ] ^ - Td1[(t3 >> 16) & 0xff] ^ - Td2[(t2 >> 8) & 0xff] ^ - Td3[(t1 ) & 0xff] ^ - rk[0]; - s1 = - Td0[(t1 >> 24) ] ^ - Td1[(t0 >> 16) & 0xff] ^ - Td2[(t3 >> 8) & 0xff] ^ - Td3[(t2 ) & 0xff] ^ - rk[1]; - s2 = - Td0[(t2 >> 24) ] ^ - Td1[(t1 >> 16) & 0xff] ^ - Td2[(t0 >> 8) & 0xff] ^ - Td3[(t3 ) & 0xff] ^ - rk[2]; - s3 = - Td0[(t3 >> 24) ] ^ - Td1[(t2 >> 16) & 0xff] ^ - Td2[(t1 >> 8) & 0xff] ^ - Td3[(t0 ) & 0xff] ^ - rk[3]; - } -#endif /* ?FULL_UNROLL */ - /* - * apply last round and - * map cipher state to byte array block: - */ - s0 = - ((u32)Td4[(t0 >> 24) ] << 24) ^ - ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^ - ((u32)Td4[(t2 >> 8) & 0xff] << 8) ^ - ((u32)Td4[(t1 ) & 0xff]) ^ - rk[0]; - PUTU32(out , s0); - s1 = - ((u32)Td4[(t1 >> 24) ] << 24) ^ - ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^ - ((u32)Td4[(t3 >> 8) & 0xff] << 8) ^ - ((u32)Td4[(t2 ) & 0xff]) ^ - rk[1]; - PUTU32(out + 4, s1); - s2 = - ((u32)Td4[(t2 >> 24) ] << 24) ^ - ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^ - ((u32)Td4[(t0 >> 8) & 0xff] << 8) ^ - ((u32)Td4[(t3 ) & 0xff]) ^ - rk[2]; - PUTU32(out + 8, s2); - s3 = - ((u32)Td4[(t3 >> 24) ] << 24) ^ - ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^ - ((u32)Td4[(t1 >> 8) & 0xff] << 8) ^ - ((u32)Td4[(t0 ) & 0xff]) ^ - rk[3]; - PUTU32(out + 12, s3); -} - -#else /* AES_ASM */ - -static const u8 Te4[256] = { - 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, - 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, - 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, - 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, - 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, - 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U, - 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, - 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, - 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, - 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U, - 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, - 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, - 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, - 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U, - 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, - 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, - 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, - 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U, - 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, - 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, - 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, - 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U, - 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, - 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, - 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, - 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, - 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, - 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU, - 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, - 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, - 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, - 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U -}; -static const u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000, - 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ -}; - -/** - * Expand the cipher key into the encryption key schedule. - */ -int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) -{ - u32 *rk; - int i = 0; - u32 temp; - - if (!userKey || !key) - return -1; - if (bits != 128 && bits != 192 && bits != 256) - return -2; - - rk = key->rd_key; - - if (bits==128) - key->rounds = 10; - else if (bits==192) - key->rounds = 12; - else - key->rounds = 14; - - rk[0] = GETU32(userKey ); - rk[1] = GETU32(userKey + 4); - rk[2] = GETU32(userKey + 8); - rk[3] = GETU32(userKey + 12); - if (bits == 128) { - while (1) { - temp = rk[3]; - rk[4] = rk[0] ^ - ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ - ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ - ((u32)Te4[(temp ) & 0xff] << 8) ^ - ((u32)Te4[(temp >> 24) ]) ^ - rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - if (++i == 10) { - return 0; - } - rk += 4; - } - } - rk[4] = GETU32(userKey + 16); - rk[5] = GETU32(userKey + 20); - if (bits == 192) { - while (1) { - temp = rk[ 5]; - rk[ 6] = rk[ 0] ^ - ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ - ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ - ((u32)Te4[(temp ) & 0xff] << 8) ^ - ((u32)Te4[(temp >> 24) ]) ^ - rcon[i]; - rk[ 7] = rk[ 1] ^ rk[ 6]; - rk[ 8] = rk[ 2] ^ rk[ 7]; - rk[ 9] = rk[ 3] ^ rk[ 8]; - if (++i == 8) { - return 0; - } - rk[10] = rk[ 4] ^ rk[ 9]; - rk[11] = rk[ 5] ^ rk[10]; - rk += 6; - } - } - rk[6] = GETU32(userKey + 24); - rk[7] = GETU32(userKey + 28); - if (bits == 256) { - while (1) { - temp = rk[ 7]; - rk[ 8] = rk[ 0] ^ - ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ - ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ - ((u32)Te4[(temp ) & 0xff] << 8) ^ - ((u32)Te4[(temp >> 24) ]) ^ - rcon[i]; - rk[ 9] = rk[ 1] ^ rk[ 8]; - rk[10] = rk[ 2] ^ rk[ 9]; - rk[11] = rk[ 3] ^ rk[10]; - if (++i == 7) { - return 0; - } - temp = rk[11]; - rk[12] = rk[ 4] ^ - ((u32)Te4[(temp >> 24) ] << 24) ^ - ((u32)Te4[(temp >> 16) & 0xff] << 16) ^ - ((u32)Te4[(temp >> 8) & 0xff] << 8) ^ - ((u32)Te4[(temp ) & 0xff]); - rk[13] = rk[ 5] ^ rk[12]; - rk[14] = rk[ 6] ^ rk[13]; - rk[15] = rk[ 7] ^ rk[14]; - - rk += 8; - } - } - return 0; -} - -/** - * Expand the cipher key into the decryption key schedule. - */ -int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) -{ - - u32 *rk; - int i, j, status; - u32 temp; - - /* first, start with an encryption schedule */ - status = private_AES_set_encrypt_key(userKey, bits, key); - if (status < 0) - return status; - - rk = key->rd_key; - - /* invert the order of the round keys: */ - for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { - temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; - temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; - temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; - temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; - } - /* apply the inverse MixColumn transform to all round keys but the first and the last: */ - for (i = 1; i < (key->rounds); i++) { - rk += 4; - for (j = 0; j < 4; j++) { - u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; - - tp1 = rk[j]; - m = tp1 & 0x80808080; - tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ - ((m - (m >> 7)) & 0x1b1b1b1b); - m = tp2 & 0x80808080; - tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ - ((m - (m >> 7)) & 0x1b1b1b1b); - m = tp4 & 0x80808080; - tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ - ((m - (m >> 7)) & 0x1b1b1b1b); - tp9 = tp8 ^ tp1; - tpb = tp9 ^ tp2; - tpd = tp9 ^ tp4; - tpe = tp8 ^ tp4 ^ tp2; -#if defined(ROTATE) - rk[j] = tpe ^ ROTATE(tpd,16) ^ - ROTATE(tp9,24) ^ ROTATE(tpb,8); -#else - rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ - (tp9 >> 8) ^ (tp9 << 24) ^ - (tpb >> 24) ^ (tpb << 8); -#endif - } - } - return 0; -} - -#endif /* AES_ASM */ -/* crypto/aes/aes_ctr.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "aes.h" -// #include "modes.h" - -void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char ivec[AES_BLOCK_SIZE], - unsigned char ecount_buf[AES_BLOCK_SIZE], - unsigned int *num) -{ - CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, - (block128_f) AES_encrypt); -} -/* crypto/aes/aes_ecb.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#ifndef AES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -// #include "aes.h" -// #include "aes_locl.h" - -void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key, const int enc) -{ - - assert(in && out && key); - assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); - - if (AES_ENCRYPT == enc) - AES_encrypt(in, out, key); - else - AES_decrypt(in, out, key); -} -/* crypto/aes/aes_ige.c */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "cryptlib.h" - -// #include "aes.h" -// #include "aes_locl.h" - -#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) -typedef struct { - unsigned long data[N_WORDS]; -} aes_block_t; - -/* XXX: probably some better way to do this */ -#if defined(__i386__) || defined(__x86_64__) -# define UNALIGNED_MEMOPS_ARE_FAST 1 -#else -# define UNALIGNED_MEMOPS_ARE_FAST 0 -#endif - -#if UNALIGNED_MEMOPS_ARE_FAST -# define load_block(d, s) (d) = *(const aes_block_t *)(s) -# define store_block(d, s) *(aes_block_t *)(d) = (s) -#else -# define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) -# define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) -#endif - -/* N.B. The IV for this mode is _twice_ the block size */ - -void AES_ige_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, const int enc) -{ - size_t n; - size_t len = length; - - OPENSSL_assert(in && out && key && ivec); - OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); - OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); - - len = length / AES_BLOCK_SIZE; - - if (AES_ENCRYPT == enc) { - if (in != out && - (UNALIGNED_MEMOPS_ARE_FAST - || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == - 0)) { - aes_block_t *ivp = (aes_block_t *) ivec; - aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); - - while (len) { - aes_block_t *inp = (aes_block_t *) in; - aes_block_t *outp = (aes_block_t *) out; - - for (n = 0; n < N_WORDS; ++n) - outp->data[n] = inp->data[n] ^ ivp->data[n]; - AES_encrypt((unsigned char *)outp->data, - (unsigned char *)outp->data, key); - for (n = 0; n < N_WORDS; ++n) - outp->data[n] ^= iv2p->data[n]; - ivp = outp; - iv2p = inp; - --len; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - memcpy(ivec, ivp->data, AES_BLOCK_SIZE); - memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); - } else { - aes_block_t tmp, tmp2; - aes_block_t iv; - aes_block_t iv2; - - load_block(iv, ivec); - load_block(iv2, ivec + AES_BLOCK_SIZE); - - while (len) { - load_block(tmp, in); - for (n = 0; n < N_WORDS; ++n) - tmp2.data[n] = tmp.data[n] ^ iv.data[n]; - AES_encrypt((unsigned char *)tmp2.data, - (unsigned char *)tmp2.data, key); - for (n = 0; n < N_WORDS; ++n) - tmp2.data[n] ^= iv2.data[n]; - store_block(out, tmp2); - iv = tmp2; - iv2 = tmp; - --len; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - memcpy(ivec, iv.data, AES_BLOCK_SIZE); - memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); - } - } else { - if (in != out && - (UNALIGNED_MEMOPS_ARE_FAST - || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == - 0)) { - aes_block_t *ivp = (aes_block_t *) ivec; - aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); - - while (len) { - aes_block_t tmp; - aes_block_t *inp = (aes_block_t *) in; - aes_block_t *outp = (aes_block_t *) out; - - for (n = 0; n < N_WORDS; ++n) - tmp.data[n] = inp->data[n] ^ iv2p->data[n]; - AES_decrypt((unsigned char *)tmp.data, - (unsigned char *)outp->data, key); - for (n = 0; n < N_WORDS; ++n) - outp->data[n] ^= ivp->data[n]; - ivp = inp; - iv2p = outp; - --len; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - memcpy(ivec, ivp->data, AES_BLOCK_SIZE); - memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); - } else { - aes_block_t tmp, tmp2; - aes_block_t iv; - aes_block_t iv2; - - load_block(iv, ivec); - load_block(iv2, ivec + AES_BLOCK_SIZE); - - while (len) { - load_block(tmp, in); - tmp2 = tmp; - for (n = 0; n < N_WORDS; ++n) - tmp.data[n] ^= iv2.data[n]; - AES_decrypt((unsigned char *)tmp.data, - (unsigned char *)tmp.data, key); - for (n = 0; n < N_WORDS; ++n) - tmp.data[n] ^= iv.data[n]; - store_block(out, tmp); - iv = tmp2; - iv2 = tmp; - --len; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - memcpy(ivec, iv.data, AES_BLOCK_SIZE); - memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); - } - } -} - -/* - * Note that its effectively impossible to do biIGE in anything other - * than a single pass, so no provision is made for chaining. - */ - -/* N.B. The IV for this mode is _four times_ the block size */ - -void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - const AES_KEY *key2, const unsigned char *ivec, - const int enc) -{ - size_t n; - size_t len = length; - unsigned char tmp[AES_BLOCK_SIZE]; - unsigned char tmp2[AES_BLOCK_SIZE]; - unsigned char tmp3[AES_BLOCK_SIZE]; - unsigned char prev[AES_BLOCK_SIZE]; - const unsigned char *iv; - const unsigned char *iv2; - - OPENSSL_assert(in && out && key && ivec); - OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); - OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); - - if (AES_ENCRYPT == enc) { - /* - * XXX: Do a separate case for when in != out (strictly should check - * for overlap, too) - */ - - /* First the forward pass */ - iv = ivec; - iv2 = ivec + AES_BLOCK_SIZE; - while (len >= AES_BLOCK_SIZE) { - for (n = 0; n < AES_BLOCK_SIZE; ++n) - out[n] = in[n] ^ iv[n]; - AES_encrypt(out, out, key); - for (n = 0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= iv2[n]; - iv = out; - memcpy(prev, in, AES_BLOCK_SIZE); - iv2 = prev; - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - - /* And now backwards */ - iv = ivec + AES_BLOCK_SIZE * 2; - iv2 = ivec + AES_BLOCK_SIZE * 3; - len = length; - while (len >= AES_BLOCK_SIZE) { - out -= AES_BLOCK_SIZE; - /* - * XXX: reduce copies by alternating between buffers - */ - memcpy(tmp, out, AES_BLOCK_SIZE); - for (n = 0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= iv[n]; - /* - * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); - */ - AES_encrypt(out, out, key); - /* - * hexdump(stdout,"enc", out, AES_BLOCK_SIZE); - */ - /* - * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); - */ - for (n = 0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= iv2[n]; - /* - * hexdump(stdout,"out", out, AES_BLOCK_SIZE); - */ - iv = out; - memcpy(prev, tmp, AES_BLOCK_SIZE); - iv2 = prev; - len -= AES_BLOCK_SIZE; - } - } else { - /* First backwards */ - iv = ivec + AES_BLOCK_SIZE * 2; - iv2 = ivec + AES_BLOCK_SIZE * 3; - in += length; - out += length; - while (len >= AES_BLOCK_SIZE) { - in -= AES_BLOCK_SIZE; - out -= AES_BLOCK_SIZE; - memcpy(tmp, in, AES_BLOCK_SIZE); - memcpy(tmp2, in, AES_BLOCK_SIZE); - for (n = 0; n < AES_BLOCK_SIZE; ++n) - tmp[n] ^= iv2[n]; - AES_decrypt(tmp, out, key); - for (n = 0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= iv[n]; - memcpy(tmp3, tmp2, AES_BLOCK_SIZE); - iv = tmp3; - iv2 = out; - len -= AES_BLOCK_SIZE; - } - - /* And now forwards */ - iv = ivec; - iv2 = ivec + AES_BLOCK_SIZE; - len = length; - while (len >= AES_BLOCK_SIZE) { - memcpy(tmp, out, AES_BLOCK_SIZE); - memcpy(tmp2, out, AES_BLOCK_SIZE); - for (n = 0; n < AES_BLOCK_SIZE; ++n) - tmp[n] ^= iv2[n]; - AES_decrypt(tmp, out, key); - for (n = 0; n < AES_BLOCK_SIZE; ++n) - out[n] ^= iv[n]; - memcpy(tmp3, tmp2, AES_BLOCK_SIZE); - iv = tmp3; - iv2 = out; - len -= AES_BLOCK_SIZE; - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - } - } -} -/* crypto/aes/aes_misc.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "opensslv.h" -#include "crypto.h" -// #include "aes.h" -// #include "aes_locl.h" - -const char AES_version[] = "AES" OPENSSL_VERSION_PTEXT; - -const char *AES_options(void) -{ -#ifdef FULL_UNROLL - return "aes(full)"; -#else - return "aes(partial)"; -#endif -} - -/* FIPS wrapper functions to block low level AES calls in FIPS mode */ - -int AES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) -{ -#ifdef OPENSSL_FIPS - fips_cipher_abort(AES); -#endif - return private_AES_set_encrypt_key(userKey, bits, key); -} - -int AES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key) -{ -#ifdef OPENSSL_FIPS - fips_cipher_abort(AES); -#endif - return private_AES_set_decrypt_key(userKey, bits, key); -} -/* crypto/aes/aes_ofb.c */ -/* ==================================================================== - * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "aes.h" -// #include "modes.h" - -void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, int *num) -{ - CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, - (block128_f) AES_encrypt); -} -/* crypto/aes/aes_wrap.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "aes.h" -// #include "modes.h" - -int AES_wrap_key(AES_KEY *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, unsigned int inlen) -{ - return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f) AES_encrypt); -} - -int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, unsigned int inlen) -{ - return CRYPTO_128_unwrap(key, iv, out, in, inlen, - (block128_f) AES_decrypt); -} diff --git a/Sources/COpenSSL/aes_locl.h b/Sources/COpenSSL/aes_locl.h deleted file mode 100644 index b0b62611..00000000 --- a/Sources/COpenSSL/aes_locl.h +++ /dev/null @@ -1,89 +0,0 @@ -/* crypto/aes/aes.h */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#ifndef HEADER_AES_LOCL_H -# define HEADER_AES_LOCL_H - -# include "e_os2.h" - -# ifdef OPENSSL_NO_AES -# error AES is disabled. -# endif - -# include -# include -# include - -# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) -# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) -# define GETU32(p) SWAP(*((u32 *)(p))) -# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } -# else -# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) -# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } -# endif - -# ifdef AES_LONG -typedef unsigned long u32; -# else -typedef unsigned int u32; -# endif -typedef unsigned short u16; -typedef unsigned char u8; - -# define MAXKC (256/32) -# define MAXKB (256/8) -# define MAXNR 14 - -/* This controls loop-unrolling in aes_core.c */ -# undef FULL_UNROLL - -#endif /* !HEADER_AES_LOCL_H */ diff --git a/Sources/COpenSSL/ameth_lib.c b/Sources/COpenSSL/ameth_lib.c deleted file mode 100644 index cefdb168..00000000 --- a/Sources/COpenSSL/ameth_lib.c +++ /dev/null @@ -1,499 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "asn1t.h" -#include "x509.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -#include "asn1_locl.h" - -extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; -extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; -extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; - -/* Keep this sorted in type order !! */ -static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { -#ifndef OPENSSL_NO_RSA - &rsa_asn1_meths[0], - &rsa_asn1_meths[1], -#endif -#ifndef OPENSSL_NO_DH - &dh_asn1_meth, -#endif -#ifndef OPENSSL_NO_DSA - &dsa_asn1_meths[0], - &dsa_asn1_meths[1], - &dsa_asn1_meths[2], - &dsa_asn1_meths[3], - &dsa_asn1_meths[4], -#endif -#ifndef OPENSSL_NO_EC - &eckey_asn1_meth, -#endif - &hmac_asn1_meth, -#ifndef OPENSSL_NO_CMAC - &cmac_asn1_meth, -#endif -#ifndef OPENSSL_NO_DH - &dhx_asn1_meth -#endif -}; - -typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); -DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD) -static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL; - -#ifdef TEST -void main() -{ - int i; - for (i = 0; - i < sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); i++) - fprintf(stderr, "Number %d id=%d (%s)\n", i, - standard_methods[i]->pkey_id, - OBJ_nid2sn(standard_methods[i]->pkey_id)); -} -#endif - -DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, - const EVP_PKEY_ASN1_METHOD *, ameth); - -static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a, - const EVP_PKEY_ASN1_METHOD *const *b) -{ - return ((*a)->pkey_id - (*b)->pkey_id); -} - -IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, - const EVP_PKEY_ASN1_METHOD *, ameth); - -int EVP_PKEY_asn1_get_count(void) -{ - int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); - if (app_methods) - num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods); - return num; -} - -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) -{ - int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); - if (idx < 0) - return NULL; - if (idx < num) - return standard_methods[idx]; - idx -= num; - return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); -} - -static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type) -{ - EVP_PKEY_ASN1_METHOD tmp; - const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret; - tmp.pkey_id = type; - if (app_methods) { - int idx; - idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp); - if (idx >= 0) - return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); - } - ret = OBJ_bsearch_ameth(&t, standard_methods, sizeof(standard_methods) - / sizeof(EVP_PKEY_ASN1_METHOD *)); - if (!ret || !*ret) - return NULL; - return *ret; -} - -/* - * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also - * search through engines and set *pe to a functional reference to the engine - * implementing 'type' or NULL if no engine implements it. - */ - -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type) -{ - const EVP_PKEY_ASN1_METHOD *t; - - for (;;) { - t = pkey_asn1_find(type); - if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS)) - break; - type = t->pkey_base_id; - } - if (pe) { -#ifndef OPENSSL_NO_ENGINE - ENGINE *e; - /* type will contain the final unaliased type */ - e = ENGINE_get_pkey_asn1_meth_engine(type); - if (e) { - *pe = e; - return ENGINE_get_pkey_asn1_meth(e, type); - } -#endif - *pe = NULL; - } - return t; -} - -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, - const char *str, int len) -{ - int i; - const EVP_PKEY_ASN1_METHOD *ameth; - if (len == -1) - len = strlen(str); - if (pe) { -#ifndef OPENSSL_NO_ENGINE - ENGINE *e; - ameth = ENGINE_pkey_asn1_find_str(&e, str, len); - if (ameth) { - /* - * Convert structural into functional reference - */ - if (!ENGINE_init(e)) - ameth = NULL; - ENGINE_free(e); - *pe = e; - return ameth; - } -#endif - *pe = NULL; - } - for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { - ameth = EVP_PKEY_asn1_get0(i); - if (ameth->pkey_flags & ASN1_PKEY_ALIAS) - continue; - if (((int)strlen(ameth->pem_str) == len) && - !strncasecmp(ameth->pem_str, str, len)) - return ameth; - } - return NULL; -} - -int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) -{ - if (app_methods == NULL) { - app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp); - if (!app_methods) - return 0; - } - if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth)) - return 0; - sk_EVP_PKEY_ASN1_METHOD_sort(app_methods); - return 1; -} - -int EVP_PKEY_asn1_add_alias(int to, int from) -{ - EVP_PKEY_ASN1_METHOD *ameth; - ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); - if (!ameth) - return 0; - ameth->pkey_base_id = to; - if (!EVP_PKEY_asn1_add0(ameth)) { - EVP_PKEY_asn1_free(ameth); - return 0; - } - return 1; -} - -int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, - int *ppkey_flags, const char **pinfo, - const char **ppem_str, - const EVP_PKEY_ASN1_METHOD *ameth) -{ - if (!ameth) - return 0; - if (ppkey_id) - *ppkey_id = ameth->pkey_id; - if (ppkey_base_id) - *ppkey_base_id = ameth->pkey_base_id; - if (ppkey_flags) - *ppkey_flags = ameth->pkey_flags; - if (pinfo) - *pinfo = ameth->info; - if (ppem_str) - *ppem_str = ameth->pem_str; - return 1; -} - -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey) -{ - return pkey->ameth; -} - -EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, - const char *pem_str, const char *info) -{ - EVP_PKEY_ASN1_METHOD *ameth; - ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD)); - if (!ameth) - return NULL; - - memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD)); - - ameth->pkey_id = id; - ameth->pkey_base_id = id; - ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC; - - if (info) { - ameth->info = BUF_strdup(info); - if (!ameth->info) - goto err; - } else - ameth->info = NULL; - - /* - * One of the following must be true: - * - * pem_str == NULL AND ASN1_PKEY_ALIAS is set - * pem_str != NULL AND ASN1_PKEY_ALIAS is clear - * - * Anything else is an error and may lead to a corrupt ASN1 method table - */ - if (!((pem_str == NULL && (flags & ASN1_PKEY_ALIAS) != 0) - || (pem_str != NULL && (flags & ASN1_PKEY_ALIAS) == 0))) - goto err; - - if (pem_str) { - ameth->pem_str = BUF_strdup(pem_str); - if (!ameth->pem_str) - goto err; - } else - ameth->pem_str = NULL; - - ameth->pub_decode = 0; - ameth->pub_encode = 0; - ameth->pub_cmp = 0; - ameth->pub_print = 0; - - ameth->priv_decode = 0; - ameth->priv_encode = 0; - ameth->priv_print = 0; - - ameth->old_priv_encode = 0; - ameth->old_priv_decode = 0; - - ameth->item_verify = 0; - ameth->item_sign = 0; - - ameth->pkey_size = 0; - ameth->pkey_bits = 0; - - ameth->param_decode = 0; - ameth->param_encode = 0; - ameth->param_missing = 0; - ameth->param_copy = 0; - ameth->param_cmp = 0; - ameth->param_print = 0; - - ameth->pkey_free = 0; - ameth->pkey_ctrl = 0; - - return ameth; - - err: - - EVP_PKEY_asn1_free(ameth); - return NULL; - -} - -void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, - const EVP_PKEY_ASN1_METHOD *src) -{ - - dst->pub_decode = src->pub_decode; - dst->pub_encode = src->pub_encode; - dst->pub_cmp = src->pub_cmp; - dst->pub_print = src->pub_print; - - dst->priv_decode = src->priv_decode; - dst->priv_encode = src->priv_encode; - dst->priv_print = src->priv_print; - - dst->old_priv_encode = src->old_priv_encode; - dst->old_priv_decode = src->old_priv_decode; - - dst->pkey_size = src->pkey_size; - dst->pkey_bits = src->pkey_bits; - - dst->param_decode = src->param_decode; - dst->param_encode = src->param_encode; - dst->param_missing = src->param_missing; - dst->param_copy = src->param_copy; - dst->param_cmp = src->param_cmp; - dst->param_print = src->param_print; - - dst->pkey_free = src->pkey_free; - dst->pkey_ctrl = src->pkey_ctrl; - - dst->item_sign = src->item_sign; - dst->item_verify = src->item_verify; - -} - -void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) -{ - if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) { - if (ameth->pem_str) - OPENSSL_free(ameth->pem_str); - if (ameth->info) - OPENSSL_free(ameth->info); - OPENSSL_free(ameth); - } -} - -void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, - int (*pub_decode) (EVP_PKEY *pk, - X509_PUBKEY *pub), - int (*pub_encode) (X509_PUBKEY *pub, - const EVP_PKEY *pk), - int (*pub_cmp) (const EVP_PKEY *a, - const EVP_PKEY *b), - int (*pub_print) (BIO *out, - const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx), - int (*pkey_size) (const EVP_PKEY *pk), - int (*pkey_bits) (const EVP_PKEY *pk)) -{ - ameth->pub_decode = pub_decode; - ameth->pub_encode = pub_encode; - ameth->pub_cmp = pub_cmp; - ameth->pub_print = pub_print; - ameth->pkey_size = pkey_size; - ameth->pkey_bits = pkey_bits; -} - -void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, - int (*priv_decode) (EVP_PKEY *pk, - PKCS8_PRIV_KEY_INFO - *p8inf), - int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, - const EVP_PKEY *pk), - int (*priv_print) (BIO *out, - const EVP_PKEY *pkey, - int indent, - ASN1_PCTX *pctx)) -{ - ameth->priv_decode = priv_decode; - ameth->priv_encode = priv_encode; - ameth->priv_print = priv_print; -} - -void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, - int (*param_decode) (EVP_PKEY *pkey, - const unsigned char **pder, - int derlen), - int (*param_encode) (const EVP_PKEY *pkey, - unsigned char **pder), - int (*param_missing) (const EVP_PKEY *pk), - int (*param_copy) (EVP_PKEY *to, - const EVP_PKEY *from), - int (*param_cmp) (const EVP_PKEY *a, - const EVP_PKEY *b), - int (*param_print) (BIO *out, - const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx)) -{ - ameth->param_decode = param_decode; - ameth->param_encode = param_encode; - ameth->param_missing = param_missing; - ameth->param_copy = param_copy; - ameth->param_cmp = param_cmp; - ameth->param_print = param_print; -} - -void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, - void (*pkey_free) (EVP_PKEY *pkey)) -{ - ameth->pkey_free = pkey_free; -} - -void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, - int (*pkey_ctrl) (EVP_PKEY *pkey, int op, - long arg1, void *arg2)) -{ - ameth->pkey_ctrl = pkey_ctrl; -} - -void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, - int (*item_verify) (EVP_MD_CTX *ctx, - const ASN1_ITEM *it, - void *asn, - X509_ALGOR *a, - ASN1_BIT_STRING *sig, - EVP_PKEY *pkey), - int (*item_sign) (EVP_MD_CTX *ctx, - const ASN1_ITEM *it, - void *asn, - X509_ALGOR *alg1, - X509_ALGOR *alg2, - ASN1_BIT_STRING *sig)) -{ - ameth->item_sign = item_sign; - ameth->item_verify = item_verify; -} diff --git a/Sources/COpenSSL/asn1.h b/Sources/COpenSSL/asn1.h deleted file mode 100644 index e41f9870..00000000 --- a/Sources/COpenSSL/asn1.h +++ /dev/null @@ -1,1424 +0,0 @@ -/* crypto/asn1/asn1.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_ASN1_H -# define HEADER_ASN1_H - -# include -# include "e_os2.h" -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# include "stack.h" -# include "safestack.h" - -# include "symhacks.h" - -# include "ossl_typ.h" -# ifndef OPENSSL_NO_DEPRECATED -# include "bn.h" -# endif - -# ifdef OPENSSL_BUILD_SHLIBCRYPTO -# undef OPENSSL_EXTERN -# define OPENSSL_EXTERN OPENSSL_EXPORT -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -# define V_ASN1_UNIVERSAL 0x00 -# define V_ASN1_APPLICATION 0x40 -# define V_ASN1_CONTEXT_SPECIFIC 0x80 -# define V_ASN1_PRIVATE 0xc0 - -# define V_ASN1_CONSTRUCTED 0x20 -# define V_ASN1_PRIMITIVE_TAG 0x1f -# define V_ASN1_PRIMATIVE_TAG 0x1f - -# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */ -# define V_ASN1_OTHER -3/* used in ASN1_TYPE */ -# define V_ASN1_ANY -4/* used in ASN1 template code */ - -# define V_ASN1_NEG 0x100/* negative flag */ - -# define V_ASN1_UNDEF -1 -# define V_ASN1_EOC 0 -# define V_ASN1_BOOLEAN 1 /**/ -# define V_ASN1_INTEGER 2 -# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) -# define V_ASN1_BIT_STRING 3 -# define V_ASN1_OCTET_STRING 4 -# define V_ASN1_NULL 5 -# define V_ASN1_OBJECT 6 -# define V_ASN1_OBJECT_DESCRIPTOR 7 -# define V_ASN1_EXTERNAL 8 -# define V_ASN1_REAL 9 -# define V_ASN1_ENUMERATED 10 -# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) -# define V_ASN1_UTF8STRING 12 -# define V_ASN1_SEQUENCE 16 -# define V_ASN1_SET 17 -# define V_ASN1_NUMERICSTRING 18 /**/ -# define V_ASN1_PRINTABLESTRING 19 -# define V_ASN1_T61STRING 20 -# define V_ASN1_TELETEXSTRING 20/* alias */ -# define V_ASN1_VIDEOTEXSTRING 21 /**/ -# define V_ASN1_IA5STRING 22 -# define V_ASN1_UTCTIME 23 -# define V_ASN1_GENERALIZEDTIME 24 /**/ -# define V_ASN1_GRAPHICSTRING 25 /**/ -# define V_ASN1_ISO64STRING 26 /**/ -# define V_ASN1_VISIBLESTRING 26/* alias */ -# define V_ASN1_GENERALSTRING 27 /**/ -# define V_ASN1_UNIVERSALSTRING 28 /**/ -# define V_ASN1_BMPSTRING 30 -/* For use with d2i_ASN1_type_bytes() */ -# define B_ASN1_NUMERICSTRING 0x0001 -# define B_ASN1_PRINTABLESTRING 0x0002 -# define B_ASN1_T61STRING 0x0004 -# define B_ASN1_TELETEXSTRING 0x0004 -# define B_ASN1_VIDEOTEXSTRING 0x0008 -# define B_ASN1_IA5STRING 0x0010 -# define B_ASN1_GRAPHICSTRING 0x0020 -# define B_ASN1_ISO64STRING 0x0040 -# define B_ASN1_VISIBLESTRING 0x0040 -# define B_ASN1_GENERALSTRING 0x0080 -# define B_ASN1_UNIVERSALSTRING 0x0100 -# define B_ASN1_OCTET_STRING 0x0200 -# define B_ASN1_BIT_STRING 0x0400 -# define B_ASN1_BMPSTRING 0x0800 -# define B_ASN1_UNKNOWN 0x1000 -# define B_ASN1_UTF8STRING 0x2000 -# define B_ASN1_UTCTIME 0x4000 -# define B_ASN1_GENERALIZEDTIME 0x8000 -# define B_ASN1_SEQUENCE 0x10000 -/* For use with ASN1_mbstring_copy() */ -# define MBSTRING_FLAG 0x1000 -# define MBSTRING_UTF8 (MBSTRING_FLAG) -# define MBSTRING_ASC (MBSTRING_FLAG|1) -# define MBSTRING_BMP (MBSTRING_FLAG|2) -# define MBSTRING_UNIV (MBSTRING_FLAG|4) -# define SMIME_OLDMIME 0x400 -# define SMIME_CRLFEOL 0x800 -# define SMIME_STREAM 0x1000 - struct X509_algor_st; -DECLARE_STACK_OF(X509_ALGOR) - -# define DECLARE_ASN1_SET_OF(type)/* filled in by mkstack.pl */ -# define IMPLEMENT_ASN1_SET_OF(type)/* nothing, no longer needed */ - -/* - * We MUST make sure that, except for constness, asn1_ctx_st and - * asn1_const_ctx are exactly the same. Fortunately, as soon as the old ASN1 - * parsing macros are gone, we can throw this away as well... - */ -typedef struct asn1_ctx_st { - unsigned char *p; /* work char pointer */ - int eos; /* end of sequence read for indefinite - * encoding */ - int error; /* error code to use when returning an error */ - int inf; /* constructed if 0x20, indefinite is 0x21 */ - int tag; /* tag from last 'get object' */ - int xclass; /* class from last 'get object' */ - long slen; /* length of last 'get object' */ - unsigned char *max; /* largest value of p allowed */ - unsigned char *q; /* temporary variable */ - unsigned char **pp; /* variable */ - int line; /* used in error processing */ -} ASN1_CTX; - -typedef struct asn1_const_ctx_st { - const unsigned char *p; /* work char pointer */ - int eos; /* end of sequence read for indefinite - * encoding */ - int error; /* error code to use when returning an error */ - int inf; /* constructed if 0x20, indefinite is 0x21 */ - int tag; /* tag from last 'get object' */ - int xclass; /* class from last 'get object' */ - long slen; /* length of last 'get object' */ - const unsigned char *max; /* largest value of p allowed */ - const unsigned char *q; /* temporary variable */ - const unsigned char **pp; /* variable */ - int line; /* used in error processing */ -} ASN1_const_CTX; - -/* - * These are used internally in the ASN1_OBJECT to keep track of whether the - * names and data need to be free()ed - */ -# define ASN1_OBJECT_FLAG_DYNAMIC 0x01/* internal use */ -# define ASN1_OBJECT_FLAG_CRITICAL 0x02/* critical x509v3 object id */ -# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */ -# define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08/* internal use */ -struct asn1_object_st { - const char *sn, *ln; - int nid; - int length; - const unsigned char *data; /* data remains const after init */ - int flags; /* Should we free this one */ -}; - -# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ -/* - * This indicates that the ASN1_STRING is not a real value but just a place - * holder for the location where indefinite length constructed data should be - * inserted in the memory buffer - */ -# define ASN1_STRING_FLAG_NDEF 0x010 - -/* - * This flag is used by the CMS code to indicate that a string is not - * complete and is a place holder for content when it had all been accessed. - * The flag will be reset when content has been written to it. - */ - -# define ASN1_STRING_FLAG_CONT 0x020 -/* - * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING - * type. - */ -# define ASN1_STRING_FLAG_MSTRING 0x040 -/* This is the base type that holds just about everything :-) */ -struct asn1_string_st { - int length; - int type; - unsigned char *data; - /* - * The value of the following field depends on the type being held. It - * is mostly being used for BIT_STRING so if the input data has a - * non-zero 'unused bits' value, it will be handled correctly - */ - long flags; -}; - -/* - * ASN1_ENCODING structure: this is used to save the received encoding of an - * ASN1 type. This is useful to get round problems with invalid encodings - * which can break signatures. - */ - -typedef struct ASN1_ENCODING_st { - unsigned char *enc; /* DER encoding */ - long len; /* Length of encoding */ - int modified; /* set to 1 if 'enc' is invalid */ -} ASN1_ENCODING; - -/* Used with ASN1 LONG type: if a long is set to this it is omitted */ -# define ASN1_LONG_UNDEF 0x7fffffffL - -# define STABLE_FLAGS_MALLOC 0x01 -# define STABLE_NO_MASK 0x02 -# define DIRSTRING_TYPE \ - (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) -# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) - -typedef struct asn1_string_table_st { - int nid; - long minsize; - long maxsize; - unsigned long mask; - unsigned long flags; -} ASN1_STRING_TABLE; - -DECLARE_STACK_OF(ASN1_STRING_TABLE) - -/* size limits: this stuff is taken straight from RFC2459 */ - -# define ub_name 32768 -# define ub_common_name 64 -# define ub_locality_name 128 -# define ub_state_name 128 -# define ub_organization_name 64 -# define ub_organization_unit_name 64 -# define ub_title 64 -# define ub_email_address 128 - -/* - * Declarations for template structures: for full definitions see asn1t.h - */ -typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; -typedef struct ASN1_TLC_st ASN1_TLC; -/* This is just an opaque pointer */ -typedef struct ASN1_VALUE_st ASN1_VALUE; - -/* Declare ASN1 functions: the implement macro in in asn1t.h */ - -# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) - -# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ - DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) - -# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ - DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ - DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) - -# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ - DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ - DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) - -# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ - type *d2i_##name(type **a, const unsigned char **in, long len); \ - int i2d_##name(type *a, unsigned char **out); \ - DECLARE_ASN1_ITEM(itname) - -# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ - type *d2i_##name(type **a, const unsigned char **in, long len); \ - int i2d_##name(const type *a, unsigned char **out); \ - DECLARE_ASN1_ITEM(name) - -# define DECLARE_ASN1_NDEF_FUNCTION(name) \ - int i2d_##name##_NDEF(name *a, unsigned char **out); - -# define DECLARE_ASN1_FUNCTIONS_const(name) \ - DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ - DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) - -# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ - type *name##_new(void); \ - void name##_free(type *a); - -# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ - DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) - -# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ - int fname##_print_ctx(BIO *out, stname *x, int indent, \ - const ASN1_PCTX *pctx); - -# define D2I_OF(type) type *(*)(type **,const unsigned char **,long) -# define I2D_OF(type) int (*)(type *,unsigned char **) -# define I2D_OF_const(type) int (*)(const type *,unsigned char **) - -# define CHECKED_D2I_OF(type, d2i) \ - ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) -# define CHECKED_I2D_OF(type, i2d) \ - ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) -# define CHECKED_NEW_OF(type, xnew) \ - ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) -# define CHECKED_PTR_OF(type, p) \ - ((void*) (1 ? p : (type*)0)) -# define CHECKED_PPTR_OF(type, p) \ - ((void**) (1 ? p : (type**)0)) - -# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) -# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) -# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) - -TYPEDEF_D2I2D_OF(void); - -/*- - * The following macros and typedefs allow an ASN1_ITEM - * to be embedded in a structure and referenced. Since - * the ASN1_ITEM pointers need to be globally accessible - * (possibly from shared libraries) they may exist in - * different forms. On platforms that support it the - * ASN1_ITEM structure itself will be globally exported. - * Other platforms will export a function that returns - * an ASN1_ITEM pointer. - * - * To handle both cases transparently the macros below - * should be used instead of hard coding an ASN1_ITEM - * pointer in a structure. - * - * The structure will look like this: - * - * typedef struct SOMETHING_st { - * ... - * ASN1_ITEM_EXP *iptr; - * ... - * } SOMETHING; - * - * It would be initialised as e.g.: - * - * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; - * - * and the actual pointer extracted with: - * - * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); - * - * Finally an ASN1_ITEM pointer can be extracted from an - * appropriate reference with: ASN1_ITEM_rptr(X509). This - * would be used when a function takes an ASN1_ITEM * argument. - * - */ - -# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION - -/* ASN1_ITEM pointer exported type */ -typedef const ASN1_ITEM ASN1_ITEM_EXP; - -/* Macro to obtain ASN1_ITEM pointer from exported type */ -# define ASN1_ITEM_ptr(iptr) (iptr) - -/* Macro to include ASN1_ITEM pointer from base type */ -# define ASN1_ITEM_ref(iptr) (&(iptr##_it)) - -# define ASN1_ITEM_rptr(ref) (&(ref##_it)) - -# define DECLARE_ASN1_ITEM(name) \ - OPENSSL_EXTERN const ASN1_ITEM name##_it; - -# else - -/* - * Platforms that can't easily handle shared global variables are declared as - * functions returning ASN1_ITEM pointers. - */ - -/* ASN1_ITEM pointer exported type */ -typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); - -/* Macro to obtain ASN1_ITEM pointer from exported type */ -# define ASN1_ITEM_ptr(iptr) (iptr()) - -/* Macro to include ASN1_ITEM pointer from base type */ -# define ASN1_ITEM_ref(iptr) (iptr##_it) - -# define ASN1_ITEM_rptr(ref) (ref##_it()) - -# define DECLARE_ASN1_ITEM(name) \ - const ASN1_ITEM * name##_it(void); - -# endif - -/* Parameters used by ASN1_STRING_print_ex() */ - -/* - * These determine which characters to escape: RFC2253 special characters, - * control characters and MSB set characters - */ - -# define ASN1_STRFLGS_ESC_2253 1 -# define ASN1_STRFLGS_ESC_CTRL 2 -# define ASN1_STRFLGS_ESC_MSB 4 - -/* - * This flag determines how we do escaping: normally RC2253 backslash only, - * set this to use backslash and quote. - */ - -# define ASN1_STRFLGS_ESC_QUOTE 8 - -/* These three flags are internal use only. */ - -/* Character is a valid PrintableString character */ -# define CHARTYPE_PRINTABLESTRING 0x10 -/* Character needs escaping if it is the first character */ -# define CHARTYPE_FIRST_ESC_2253 0x20 -/* Character needs escaping if it is the last character */ -# define CHARTYPE_LAST_ESC_2253 0x40 - -/* - * NB the internal flags are safely reused below by flags handled at the top - * level. - */ - -/* - * If this is set we convert all character strings to UTF8 first - */ - -# define ASN1_STRFLGS_UTF8_CONVERT 0x10 - -/* - * If this is set we don't attempt to interpret content: just assume all - * strings are 1 byte per character. This will produce some pretty odd - * looking output! - */ - -# define ASN1_STRFLGS_IGNORE_TYPE 0x20 - -/* If this is set we include the string type in the output */ -# define ASN1_STRFLGS_SHOW_TYPE 0x40 - -/* - * This determines which strings to display and which to 'dump' (hex dump of - * content octets or DER encoding). We can only dump non character strings or - * everything. If we don't dump 'unknown' they are interpreted as character - * strings with 1 octet per character and are subject to the usual escaping - * options. - */ - -# define ASN1_STRFLGS_DUMP_ALL 0x80 -# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 - -/* - * These determine what 'dumping' does, we can dump the content octets or the - * DER encoding: both use the RFC2253 #XXXXX notation. - */ - -# define ASN1_STRFLGS_DUMP_DER 0x200 - -/* - * All the string flags consistent with RFC2253, escaping control characters - * isn't essential in RFC2253 but it is advisable anyway. - */ - -# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ - ASN1_STRFLGS_ESC_CTRL | \ - ASN1_STRFLGS_ESC_MSB | \ - ASN1_STRFLGS_UTF8_CONVERT | \ - ASN1_STRFLGS_DUMP_UNKNOWN | \ - ASN1_STRFLGS_DUMP_DER) - -DECLARE_STACK_OF(ASN1_INTEGER) -DECLARE_ASN1_SET_OF(ASN1_INTEGER) - -DECLARE_STACK_OF(ASN1_GENERALSTRING) - -typedef struct asn1_type_st { - int type; - union { - char *ptr; - ASN1_BOOLEAN boolean; - ASN1_STRING *asn1_string; - ASN1_OBJECT *object; - ASN1_INTEGER *integer; - ASN1_ENUMERATED *enumerated; - ASN1_BIT_STRING *bit_string; - ASN1_OCTET_STRING *octet_string; - ASN1_PRINTABLESTRING *printablestring; - ASN1_T61STRING *t61string; - ASN1_IA5STRING *ia5string; - ASN1_GENERALSTRING *generalstring; - ASN1_BMPSTRING *bmpstring; - ASN1_UNIVERSALSTRING *universalstring; - ASN1_UTCTIME *utctime; - ASN1_GENERALIZEDTIME *generalizedtime; - ASN1_VISIBLESTRING *visiblestring; - ASN1_UTF8STRING *utf8string; - /* - * set and sequence are left complete and still contain the set or - * sequence bytes - */ - ASN1_STRING *set; - ASN1_STRING *sequence; - ASN1_VALUE *asn1_value; - } value; -} ASN1_TYPE; - -DECLARE_STACK_OF(ASN1_TYPE) -DECLARE_ASN1_SET_OF(ASN1_TYPE) - -typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; - -DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) - -typedef struct NETSCAPE_X509_st { - ASN1_OCTET_STRING *header; - X509 *cert; -} NETSCAPE_X509; - -/* This is used to contain a list of bit names */ -typedef struct BIT_STRING_BITNAME_st { - int bitnum; - const char *lname; - const char *sname; -} BIT_STRING_BITNAME; - -# define M_ASN1_STRING_length(x) ((x)->length) -# define M_ASN1_STRING_length_set(x, n) ((x)->length = (n)) -# define M_ASN1_STRING_type(x) ((x)->type) -# define M_ASN1_STRING_data(x) ((x)->data) - -/* Macros for string operations */ -# define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\ - ASN1_STRING_type_new(V_ASN1_BIT_STRING) -# define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\ - ASN1_STRING_dup((const ASN1_STRING *)a) -# define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\ - (const ASN1_STRING *)a,(const ASN1_STRING *)b) -# define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) - -# define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\ - ASN1_STRING_type_new(V_ASN1_INTEGER) -# define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\ - ASN1_STRING_dup((const ASN1_STRING *)a) -# define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\ - (const ASN1_STRING *)a,(const ASN1_STRING *)b) - -# define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\ - ASN1_STRING_type_new(V_ASN1_ENUMERATED) -# define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\ - ASN1_STRING_dup((const ASN1_STRING *)a) -# define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\ - (const ASN1_STRING *)a,(const ASN1_STRING *)b) - -# define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\ - ASN1_STRING_type_new(V_ASN1_OCTET_STRING) -# define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\ - ASN1_STRING_dup((const ASN1_STRING *)a) -# define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\ - (const ASN1_STRING *)a,(const ASN1_STRING *)b) -# define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) -# define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b) -# define M_i2d_ASN1_OCTET_STRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\ - V_ASN1_UNIVERSAL) - -# define B_ASN1_TIME \ - B_ASN1_UTCTIME | \ - B_ASN1_GENERALIZEDTIME - -# define B_ASN1_PRINTABLE \ - B_ASN1_NUMERICSTRING| \ - B_ASN1_PRINTABLESTRING| \ - B_ASN1_T61STRING| \ - B_ASN1_IA5STRING| \ - B_ASN1_BIT_STRING| \ - B_ASN1_UNIVERSALSTRING|\ - B_ASN1_BMPSTRING|\ - B_ASN1_UTF8STRING|\ - B_ASN1_SEQUENCE|\ - B_ASN1_UNKNOWN - -# define B_ASN1_DIRECTORYSTRING \ - B_ASN1_PRINTABLESTRING| \ - B_ASN1_TELETEXSTRING|\ - B_ASN1_BMPSTRING|\ - B_ASN1_UNIVERSALSTRING|\ - B_ASN1_UTF8STRING - -# define B_ASN1_DISPLAYTEXT \ - B_ASN1_IA5STRING| \ - B_ASN1_VISIBLESTRING| \ - B_ASN1_BMPSTRING|\ - B_ASN1_UTF8STRING - -# define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING) -# define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ - pp,a->type,V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_PRINTABLE(a,pp,l) \ - d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ - B_ASN1_PRINTABLE) - -# define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) -# define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ - pp,a->type,V_ASN1_UNIVERSAL) -# define M_d2i_DIRECTORYSTRING(a,pp,l) \ - d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ - B_ASN1_DIRECTORYSTRING) - -# define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) -# define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ - pp,a->type,V_ASN1_UNIVERSAL) -# define M_d2i_DISPLAYTEXT(a,pp,l) \ - d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ - B_ASN1_DISPLAYTEXT) - -# define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\ - ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) -# define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_ASN1_PRINTABLESTRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\ - V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \ - (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\ - ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING) - -# define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\ - ASN1_STRING_type_new(V_ASN1_T61STRING) -# define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_ASN1_T61STRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\ - V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_T61STRING(a,pp,l) \ - (ASN1_T61STRING *)d2i_ASN1_type_bytes\ - ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING) - -# define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\ - ASN1_STRING_type_new(V_ASN1_IA5STRING) -# define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_ASN1_IA5STRING_dup(a) \ - (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a) -# define M_i2d_ASN1_IA5STRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\ - V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_IA5STRING(a,pp,l) \ - (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\ - B_ASN1_IA5STRING) - -# define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\ - ASN1_STRING_type_new(V_ASN1_UTCTIME) -# define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\ - ASN1_STRING_dup((const ASN1_STRING *)a) - -# define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\ - ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME) -# define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\ - (const ASN1_STRING *)a) - -# define M_ASN1_TIME_new() (ASN1_TIME *)\ - ASN1_STRING_type_new(V_ASN1_UTCTIME) -# define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_ASN1_TIME_dup(a) (ASN1_TIME *)\ - ASN1_STRING_dup((const ASN1_STRING *)a) - -# define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\ - ASN1_STRING_type_new(V_ASN1_GENERALSTRING) -# define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_ASN1_GENERALSTRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\ - V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_GENERALSTRING(a,pp,l) \ - (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\ - ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING) - -# define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\ - ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING) -# define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\ - V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \ - (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\ - ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING) - -# define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\ - ASN1_STRING_type_new(V_ASN1_BMPSTRING) -# define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_ASN1_BMPSTRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\ - V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_BMPSTRING(a,pp,l) \ - (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\ - ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING) - -# define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\ - ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) -# define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_ASN1_VISIBLESTRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\ - V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \ - (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\ - ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING) - -# define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\ - ASN1_STRING_type_new(V_ASN1_UTF8STRING) -# define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) -# define M_i2d_ASN1_UTF8STRING(a,pp) \ - i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\ - V_ASN1_UNIVERSAL) -# define M_d2i_ASN1_UTF8STRING(a,pp,l) \ - (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\ - ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING) - - /* for the is_set parameter to i2d_ASN1_SET */ -# define IS_SEQUENCE 0 -# define IS_SET 1 - -DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) - -int ASN1_TYPE_get(ASN1_TYPE *a); -void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); -int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); -int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); - -ASN1_OBJECT *ASN1_OBJECT_new(void); -void ASN1_OBJECT_free(ASN1_OBJECT *a); -int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp); -ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long length); -ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, - long length); - -DECLARE_ASN1_ITEM(ASN1_OBJECT) - -DECLARE_STACK_OF(ASN1_OBJECT) -DECLARE_ASN1_SET_OF(ASN1_OBJECT) - -ASN1_STRING *ASN1_STRING_new(void); -void ASN1_STRING_free(ASN1_STRING *a); -void ASN1_STRING_clear_free(ASN1_STRING *a); -int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); -ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); -ASN1_STRING *ASN1_STRING_type_new(int type); -int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); - /* - * Since this is used to store all sorts of things, via macros, for now, - * make its data void * - */ -int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); -void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); -int ASN1_STRING_length(const ASN1_STRING *x); -void ASN1_STRING_length_set(ASN1_STRING *x, int n); -int ASN1_STRING_type(ASN1_STRING *x); -unsigned char *ASN1_STRING_data(ASN1_STRING *x); - -DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) -int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp); -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, - const unsigned char **pp, long length); -int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); -int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); -int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); -int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, - unsigned char *flags, int flags_len); - -# ifndef OPENSSL_NO_BIO -int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, - BIT_STRING_BITNAME *tbl, int indent); -# endif -int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl); -int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, - BIT_STRING_BITNAME *tbl); - -int i2d_ASN1_BOOLEAN(int a, unsigned char **pp); -int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length); - -DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) -int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, - long length); -ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, - long length); -ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); -int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); - -DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) - -int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); -ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); -ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, - int offset_day, long offset_sec); -int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); -int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); -# if 0 -time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s); -# endif - -int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); -ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, - time_t t); -ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, - time_t t, int offset_day, - long offset_sec); -int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); -int ASN1_TIME_diff(int *pday, int *psec, - const ASN1_TIME *from, const ASN1_TIME *to); - -DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) -ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); -int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, - const ASN1_OCTET_STRING *b); -int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, - int len); - -DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) -DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) -DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) -DECLARE_ASN1_FUNCTIONS(ASN1_NULL) -DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) - -int UTF8_getc(const unsigned char *str, int len, unsigned long *val); -int UTF8_putc(unsigned char *str, int len, unsigned long value); - -DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) - -DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) -DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) -DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) -DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) -DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) -DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) -DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) -DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) -DECLARE_ASN1_FUNCTIONS(ASN1_TIME) - -DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) - -ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); -ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, - int offset_day, long offset_sec); -int ASN1_TIME_check(ASN1_TIME *t); -ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME - **out); -int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); - -int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, - i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); -STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, - const unsigned char **pp, - long length, d2i_of_void *d2i, - void (*free_func) (OPENSSL_BLOCK), - int ex_tag, int ex_class); - -# ifndef OPENSSL_NO_BIO -int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); -int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); -int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a); -int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); -int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a); -int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); -int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type); -# endif -int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a); - -int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); -ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, - const char *sn, const char *ln); - -int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); -long ASN1_INTEGER_get(const ASN1_INTEGER *a); -ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); -BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); - -int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); -long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); -ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai); -BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn); - -/* General */ -/* given a string, return the correct type, max is the maximum length */ -int ASN1_PRINTABLE_type(const unsigned char *s, int max); - -int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass); -ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, - long length, int Ptag, int Pclass); -unsigned long ASN1_tag2bit(int tag); -/* type is one or more of the B_ASN1_ values. */ -ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, - long length, int type); - -/* PARSING */ -int asn1_Finish(ASN1_CTX *c); -int asn1_const_Finish(ASN1_const_CTX *c); - -/* SPECIALS */ -int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, - int *pclass, long omax); -int ASN1_check_infinite_end(unsigned char **p, long len); -int ASN1_const_check_infinite_end(const unsigned char **p, long len); -void ASN1_put_object(unsigned char **pp, int constructed, int length, - int tag, int xclass); -int ASN1_put_eoc(unsigned char **pp); -int ASN1_object_size(int constructed, int length, int tag); - -/* Used to implement other functions */ -void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); - -# define ASN1_dup_of(type,i2d,d2i,x) \ - ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ - CHECKED_D2I_OF(type, d2i), \ - CHECKED_PTR_OF(type, x))) - -# define ASN1_dup_of_const(type,i2d,d2i,x) \ - ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ - CHECKED_D2I_OF(type, d2i), \ - CHECKED_PTR_OF(const type, x))) - -void *ASN1_item_dup(const ASN1_ITEM *it, void *x); - -/* ASN1 alloc/free macros for when a type is only used internally */ - -# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) -# define M_ASN1_free_of(x, type) \ - ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) - -# ifndef OPENSSL_NO_FP_API -void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); - -# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ - ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ - CHECKED_D2I_OF(type, d2i), \ - in, \ - CHECKED_PPTR_OF(type, x))) - -void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); -int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); - -# define ASN1_i2d_fp_of(type,i2d,out,x) \ - (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ - out, \ - CHECKED_PTR_OF(type, x))) - -# define ASN1_i2d_fp_of_const(type,i2d,out,x) \ - (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ - out, \ - CHECKED_PTR_OF(const type, x))) - -int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); -int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); -# endif - -int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); - -# ifndef OPENSSL_NO_BIO -void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); - -# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ - ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ - CHECKED_D2I_OF(type, d2i), \ - in, \ - CHECKED_PPTR_OF(type, x))) - -void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); -int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); - -# define ASN1_i2d_bio_of(type,i2d,out,x) \ - (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ - out, \ - CHECKED_PTR_OF(type, x))) - -# define ASN1_i2d_bio_of_const(type,i2d,out,x) \ - (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ - out, \ - CHECKED_PTR_OF(const type, x))) - -int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); -int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); -int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); -int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); -int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); -int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); -int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, - unsigned char *buf, int off); -int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); -int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, - int dump); -# endif -const char *ASN1_tag2str(int tag); - -/* Used to load and write netscape format cert */ - -DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509) - -int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); - -int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); -int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len); -int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, - unsigned char *data, int len); -int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, - unsigned char *data, int max_len); - -STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, - d2i_of_void *d2i, - void (*free_func) (OPENSSL_BLOCK)); -unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, - unsigned char **buf, int *len); -void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); -void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); -ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, - ASN1_OCTET_STRING **oct); - -# define ASN1_pack_string_of(type,obj,i2d,oct) \ - (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \ - CHECKED_I2D_OF(type, i2d), \ - oct)) - -ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, - ASN1_OCTET_STRING **oct); - -void ASN1_STRING_set_default_mask(unsigned long mask); -int ASN1_STRING_set_default_mask_asc(const char *p); -unsigned long ASN1_STRING_get_default_mask(void); -int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, - int inform, unsigned long mask); -int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, - int inform, unsigned long mask, - long minsize, long maxsize); - -ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, - const unsigned char *in, int inlen, - int inform, int nid); -ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); -int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); -void ASN1_STRING_TABLE_cleanup(void); - -/* ASN1 template functions */ - -/* Old API compatible functions */ -ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); -void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); -ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, - long len, const ASN1_ITEM *it); -int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); -int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, - const ASN1_ITEM *it); - -void ASN1_add_oid_module(void); - -ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); -ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); - -/* ASN1 Print flags */ - -/* Indicate missing OPTIONAL fields */ -# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 -/* Mark start and end of SEQUENCE */ -# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 -/* Mark start and end of SEQUENCE/SET OF */ -# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 -/* Show the ASN1 type of primitives */ -# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 -/* Don't show ASN1 type of ANY */ -# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 -/* Don't show ASN1 type of MSTRINGs */ -# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 -/* Don't show field names in SEQUENCE */ -# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 -/* Show structure names of each SEQUENCE field */ -# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 -/* Don't show structure name even at top level */ -# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 - -int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, - const ASN1_ITEM *it, const ASN1_PCTX *pctx); -ASN1_PCTX *ASN1_PCTX_new(void); -void ASN1_PCTX_free(ASN1_PCTX *p); -unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p); -void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); -unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p); -void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); -unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p); -void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); -unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p); -void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); -unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p); -void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); - -BIO_METHOD *BIO_f_asn1(void); - -BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); - -int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, - const ASN1_ITEM *it); -int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, - const char *hdr, const ASN1_ITEM *it); -int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, - int ctype_nid, int econt_nid, - STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); -ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); -int SMIME_crlf_copy(BIO *in, BIO *out, int flags); -int SMIME_text(BIO *in, BIO *out); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ - -void ERR_load_ASN1_strings(void); - -/* Error codes for the ASN1 functions. */ - -/* Function codes. */ -# define ASN1_F_A2D_ASN1_OBJECT 100 -# define ASN1_F_A2I_ASN1_ENUMERATED 101 -# define ASN1_F_A2I_ASN1_INTEGER 102 -# define ASN1_F_A2I_ASN1_STRING 103 -# define ASN1_F_APPEND_EXP 176 -# define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 -# define ASN1_F_ASN1_CB 177 -# define ASN1_F_ASN1_CHECK_TLEN 104 -# define ASN1_F_ASN1_COLLATE_PRIMITIVE 105 -# define ASN1_F_ASN1_COLLECT 106 -# define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 -# define ASN1_F_ASN1_D2I_FP 109 -# define ASN1_F_ASN1_D2I_READ_BIO 107 -# define ASN1_F_ASN1_DIGEST 184 -# define ASN1_F_ASN1_DO_ADB 110 -# define ASN1_F_ASN1_DUP 111 -# define ASN1_F_ASN1_ENUMERATED_SET 112 -# define ASN1_F_ASN1_ENUMERATED_TO_BN 113 -# define ASN1_F_ASN1_EX_C2I 204 -# define ASN1_F_ASN1_FIND_END 190 -# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 -# define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 -# define ASN1_F_ASN1_GENERATE_V3 178 -# define ASN1_F_ASN1_GET_OBJECT 114 -# define ASN1_F_ASN1_HEADER_NEW 115 -# define ASN1_F_ASN1_I2D_BIO 116 -# define ASN1_F_ASN1_I2D_FP 117 -# define ASN1_F_ASN1_INTEGER_SET 118 -# define ASN1_F_ASN1_INTEGER_TO_BN 119 -# define ASN1_F_ASN1_ITEM_D2I_FP 206 -# define ASN1_F_ASN1_ITEM_DUP 191 -# define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 -# define ASN1_F_ASN1_ITEM_EX_D2I 120 -# define ASN1_F_ASN1_ITEM_I2D_BIO 192 -# define ASN1_F_ASN1_ITEM_I2D_FP 193 -# define ASN1_F_ASN1_ITEM_PACK 198 -# define ASN1_F_ASN1_ITEM_SIGN 195 -# define ASN1_F_ASN1_ITEM_SIGN_CTX 220 -# define ASN1_F_ASN1_ITEM_UNPACK 199 -# define ASN1_F_ASN1_ITEM_VERIFY 197 -# define ASN1_F_ASN1_MBSTRING_NCOPY 122 -# define ASN1_F_ASN1_OBJECT_NEW 123 -# define ASN1_F_ASN1_OUTPUT_DATA 214 -# define ASN1_F_ASN1_PACK_STRING 124 -# define ASN1_F_ASN1_PCTX_NEW 205 -# define ASN1_F_ASN1_PKCS5_PBE_SET 125 -# define ASN1_F_ASN1_SEQ_PACK 126 -# define ASN1_F_ASN1_SEQ_UNPACK 127 -# define ASN1_F_ASN1_SIGN 128 -# define ASN1_F_ASN1_STR2TYPE 179 -# define ASN1_F_ASN1_STRING_SET 186 -# define ASN1_F_ASN1_STRING_TABLE_ADD 129 -# define ASN1_F_ASN1_STRING_TYPE_NEW 130 -# define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 -# define ASN1_F_ASN1_TEMPLATE_NEW 133 -# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 -# define ASN1_F_ASN1_TIME_ADJ 217 -# define ASN1_F_ASN1_TIME_SET 175 -# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 -# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 -# define ASN1_F_ASN1_UNPACK_STRING 136 -# define ASN1_F_ASN1_UTCTIME_ADJ 218 -# define ASN1_F_ASN1_UTCTIME_SET 187 -# define ASN1_F_ASN1_VERIFY 137 -# define ASN1_F_B64_READ_ASN1 209 -# define ASN1_F_B64_WRITE_ASN1 210 -# define ASN1_F_BIO_NEW_NDEF 208 -# define ASN1_F_BITSTR_CB 180 -# define ASN1_F_BN_TO_ASN1_ENUMERATED 138 -# define ASN1_F_BN_TO_ASN1_INTEGER 139 -# define ASN1_F_C2I_ASN1_BIT_STRING 189 -# define ASN1_F_C2I_ASN1_INTEGER 194 -# define ASN1_F_C2I_ASN1_OBJECT 196 -# define ASN1_F_COLLECT_DATA 140 -# define ASN1_F_D2I_ASN1_BIT_STRING 141 -# define ASN1_F_D2I_ASN1_BOOLEAN 142 -# define ASN1_F_D2I_ASN1_BYTES 143 -# define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144 -# define ASN1_F_D2I_ASN1_HEADER 145 -# define ASN1_F_D2I_ASN1_INTEGER 146 -# define ASN1_F_D2I_ASN1_OBJECT 147 -# define ASN1_F_D2I_ASN1_SET 148 -# define ASN1_F_D2I_ASN1_TYPE_BYTES 149 -# define ASN1_F_D2I_ASN1_UINTEGER 150 -# define ASN1_F_D2I_ASN1_UTCTIME 151 -# define ASN1_F_D2I_AUTOPRIVATEKEY 207 -# define ASN1_F_D2I_NETSCAPE_RSA 152 -# define ASN1_F_D2I_NETSCAPE_RSA_2 153 -# define ASN1_F_D2I_PRIVATEKEY 154 -# define ASN1_F_D2I_PUBLICKEY 155 -# define ASN1_F_D2I_RSA_NET 200 -# define ASN1_F_D2I_RSA_NET_2 201 -# define ASN1_F_D2I_X509 156 -# define ASN1_F_D2I_X509_CINF 157 -# define ASN1_F_D2I_X509_PKEY 159 -# define ASN1_F_DO_BUF 221 -# define ASN1_F_I2D_ASN1_BIO_STREAM 211 -# define ASN1_F_I2D_ASN1_BOOLEAN 223 -# define ASN1_F_I2D_ASN1_OBJECT 222 -# define ASN1_F_I2D_ASN1_SET 188 -# define ASN1_F_I2D_ASN1_TIME 160 -# define ASN1_F_I2D_DSA_PUBKEY 161 -# define ASN1_F_I2D_EC_PUBKEY 181 -# define ASN1_F_I2D_PRIVATEKEY 163 -# define ASN1_F_I2D_PUBLICKEY 164 -# define ASN1_F_I2D_RSA_NET 162 -# define ASN1_F_I2D_RSA_PUBKEY 165 -# define ASN1_F_LONG_C2I 166 -# define ASN1_F_OID_MODULE_INIT 174 -# define ASN1_F_PARSE_TAGGING 182 -# define ASN1_F_PKCS5_PBE2_SET_IV 167 -# define ASN1_F_PKCS5_PBE_SET 202 -# define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 -# define ASN1_F_PKCS5_PBKDF2_SET 219 -# define ASN1_F_SMIME_READ_ASN1 212 -# define ASN1_F_SMIME_TEXT 213 -# define ASN1_F_X509_CINF_NEW 168 -# define ASN1_F_X509_CRL_ADD0_REVOKED 169 -# define ASN1_F_X509_INFO_NEW 170 -# define ASN1_F_X509_NAME_ENCODE 203 -# define ASN1_F_X509_NAME_EX_D2I 158 -# define ASN1_F_X509_NAME_EX_NEW 171 -# define ASN1_F_X509_NEW 172 -# define ASN1_F_X509_PKEY_NEW 173 - -/* Reason codes. */ -# define ASN1_R_ADDING_OBJECT 171 -# define ASN1_R_ASN1_PARSE_ERROR 203 -# define ASN1_R_ASN1_SIG_PARSE_ERROR 204 -# define ASN1_R_AUX_ERROR 100 -# define ASN1_R_BAD_CLASS 101 -# define ASN1_R_BAD_OBJECT_HEADER 102 -# define ASN1_R_BAD_PASSWORD_READ 103 -# define ASN1_R_BAD_TAG 104 -# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 -# define ASN1_R_BN_LIB 105 -# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 -# define ASN1_R_BUFFER_TOO_SMALL 107 -# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 -# define ASN1_R_CONTEXT_NOT_INITIALISED 217 -# define ASN1_R_DATA_IS_WRONG 109 -# define ASN1_R_DECODE_ERROR 110 -# define ASN1_R_DECODING_ERROR 111 -# define ASN1_R_DEPTH_EXCEEDED 174 -# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 -# define ASN1_R_ENCODE_ERROR 112 -# define ASN1_R_ERROR_GETTING_TIME 173 -# define ASN1_R_ERROR_LOADING_SECTION 172 -# define ASN1_R_ERROR_PARSING_SET_ELEMENT 113 -# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 -# define ASN1_R_EXPECTING_AN_INTEGER 115 -# define ASN1_R_EXPECTING_AN_OBJECT 116 -# define ASN1_R_EXPECTING_A_BOOLEAN 117 -# define ASN1_R_EXPECTING_A_TIME 118 -# define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 -# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 -# define ASN1_R_FIELD_MISSING 121 -# define ASN1_R_FIRST_NUM_TOO_LARGE 122 -# define ASN1_R_HEADER_TOO_LONG 123 -# define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 -# define ASN1_R_ILLEGAL_BOOLEAN 176 -# define ASN1_R_ILLEGAL_CHARACTERS 124 -# define ASN1_R_ILLEGAL_FORMAT 177 -# define ASN1_R_ILLEGAL_HEX 178 -# define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 -# define ASN1_R_ILLEGAL_INTEGER 180 -# define ASN1_R_ILLEGAL_NESTED_TAGGING 181 -# define ASN1_R_ILLEGAL_NULL 125 -# define ASN1_R_ILLEGAL_NULL_VALUE 182 -# define ASN1_R_ILLEGAL_OBJECT 183 -# define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 -# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 -# define ASN1_R_ILLEGAL_TAGGED_ANY 127 -# define ASN1_R_ILLEGAL_TIME_VALUE 184 -# define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 -# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 -# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 -# define ASN1_R_INVALID_BMPSTRING_LENGTH 129 -# define ASN1_R_INVALID_DIGIT 130 -# define ASN1_R_INVALID_MIME_TYPE 205 -# define ASN1_R_INVALID_MODIFIER 186 -# define ASN1_R_INVALID_NUMBER 187 -# define ASN1_R_INVALID_OBJECT_ENCODING 216 -# define ASN1_R_INVALID_SEPARATOR 131 -# define ASN1_R_INVALID_TIME_FORMAT 132 -# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 -# define ASN1_R_INVALID_UTF8STRING 134 -# define ASN1_R_IV_TOO_LARGE 135 -# define ASN1_R_LENGTH_ERROR 136 -# define ASN1_R_LIST_ERROR 188 -# define ASN1_R_MIME_NO_CONTENT_TYPE 206 -# define ASN1_R_MIME_PARSE_ERROR 207 -# define ASN1_R_MIME_SIG_PARSE_ERROR 208 -# define ASN1_R_MISSING_EOC 137 -# define ASN1_R_MISSING_SECOND_NUMBER 138 -# define ASN1_R_MISSING_VALUE 189 -# define ASN1_R_MSTRING_NOT_UNIVERSAL 139 -# define ASN1_R_MSTRING_WRONG_TAG 140 -# define ASN1_R_NESTED_ASN1_STRING 197 -# define ASN1_R_NESTED_TOO_DEEP 219 -# define ASN1_R_NON_HEX_CHARACTERS 141 -# define ASN1_R_NOT_ASCII_FORMAT 190 -# define ASN1_R_NOT_ENOUGH_DATA 142 -# define ASN1_R_NO_CONTENT_TYPE 209 -# define ASN1_R_NO_DEFAULT_DIGEST 201 -# define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 -# define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 -# define ASN1_R_NO_MULTIPART_BOUNDARY 211 -# define ASN1_R_NO_SIG_CONTENT_TYPE 212 -# define ASN1_R_NULL_IS_WRONG_LENGTH 144 -# define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 -# define ASN1_R_ODD_NUMBER_OF_CHARS 145 -# define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146 -# define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 -# define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 -# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 -# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 -# define ASN1_R_SHORT_LINE 150 -# define ASN1_R_SIG_INVALID_MIME_TYPE 213 -# define ASN1_R_STREAMING_NOT_SUPPORTED 202 -# define ASN1_R_STRING_TOO_LONG 151 -# define ASN1_R_STRING_TOO_SHORT 152 -# define ASN1_R_TAG_VALUE_TOO_HIGH 153 -# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 -# define ASN1_R_TIME_NOT_ASCII_FORMAT 193 -# define ASN1_R_TOO_LONG 155 -# define ASN1_R_TYPE_NOT_CONSTRUCTED 156 -# define ASN1_R_TYPE_NOT_PRIMITIVE 218 -# define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 -# define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 -# define ASN1_R_UNEXPECTED_EOC 159 -# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 -# define ASN1_R_UNKNOWN_FORMAT 160 -# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 -# define ASN1_R_UNKNOWN_OBJECT_TYPE 162 -# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 -# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 -# define ASN1_R_UNKNOWN_TAG 194 -# define ASN1_R_UNKOWN_FORMAT 195 -# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 -# define ASN1_R_UNSUPPORTED_CIPHER 165 -# define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 -# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 -# define ASN1_R_UNSUPPORTED_TYPE 196 -# define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 -# define ASN1_R_WRONG_TAG 168 -# define ASN1_R_WRONG_TYPE 169 - -# ifdef __cplusplus -} -# endif -#endif diff --git a/Sources/COpenSSL/asn1_.c b/Sources/COpenSSL/asn1_.c deleted file mode 100644 index 1f09a786..00000000 --- a/Sources/COpenSSL/asn1_.c +++ /dev/null @@ -1,2097 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/asn1/asn1_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "asn1.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason) - -static ERR_STRING_DATA ASN1_str_functs[] = { - {ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"}, - {ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"}, - {ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"}, - {ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"}, - {ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"}, - {ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"}, - {ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"}, - {ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"}, - {ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"}, - {ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"}, - {ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"}, - {ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"}, - {ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"}, - {ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"}, - {ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"}, - {ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"}, - {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"}, - {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"}, - {ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"}, - {ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"}, - {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"}, - {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"}, - {ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"}, - {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"}, - {ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"}, - {ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"}, - {ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"}, - {ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"}, - {ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"}, - {ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"}, - {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"}, - {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"}, - {ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"}, - {ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"}, - {ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"}, - {ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"}, - {ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"}, - {ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"}, - {ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"}, - {ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"}, - {ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"}, - {ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"}, - {ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"}, - {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"}, - {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"}, - {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"}, - {ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"}, - {ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"}, - {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), - "ASN1_TYPE_get_int_octetstring"}, - {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"}, - {ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"}, - {ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"}, - {ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"}, - {ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"}, - {ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"}, - {ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"}, - {ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"}, - {ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"}, - {ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"}, - {ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"}, - {ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"}, - {ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"}, - {ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"}, - {ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"}, - {ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"}, - {ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"}, - {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"}, - {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"}, - {ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"}, - {ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"}, - {ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"}, - {ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"}, - {ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"}, - {ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"}, - {ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"}, - {ERR_FUNC(ASN1_F_DO_BUF), "DO_BUF"}, - {ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"}, - {ERR_FUNC(ASN1_F_I2D_ASN1_BOOLEAN), "i2d_ASN1_BOOLEAN"}, - {ERR_FUNC(ASN1_F_I2D_ASN1_OBJECT), "i2d_ASN1_OBJECT"}, - {ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"}, - {ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"}, - {ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"}, - {ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"}, - {ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"}, - {ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"}, - {ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"}, - {ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"}, - {ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"}, - {ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"}, - {ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"}, - {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"}, - {ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"}, - {ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"}, - {ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"}, - {ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"}, - {ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"}, - {ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"}, - {ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"}, - {ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"}, - {ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"}, - {ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"}, - {ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"}, - {ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"}, - {ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"}, - {0, NULL} -}; - -static ERR_STRING_DATA ASN1_str_reasons[] = { - {ERR_REASON(ASN1_R_ADDING_OBJECT), "adding object"}, - {ERR_REASON(ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"}, - {ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR), "asn1 sig parse error"}, - {ERR_REASON(ASN1_R_AUX_ERROR), "aux error"}, - {ERR_REASON(ASN1_R_BAD_CLASS), "bad class"}, - {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"}, - {ERR_REASON(ASN1_R_BAD_PASSWORD_READ), "bad password read"}, - {ERR_REASON(ASN1_R_BAD_TAG), "bad tag"}, - {ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), - "bmpstring is wrong length"}, - {ERR_REASON(ASN1_R_BN_LIB), "bn lib"}, - {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"}, - {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL), "buffer too small"}, - {ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), - "cipher has no object identifier"}, - {ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"}, - {ERR_REASON(ASN1_R_DATA_IS_WRONG), "data is wrong"}, - {ERR_REASON(ASN1_R_DECODE_ERROR), "decode error"}, - {ERR_REASON(ASN1_R_DECODING_ERROR), "decoding error"}, - {ERR_REASON(ASN1_R_DEPTH_EXCEEDED), "depth exceeded"}, - {ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED), - "digest and key type not supported"}, - {ERR_REASON(ASN1_R_ENCODE_ERROR), "encode error"}, - {ERR_REASON(ASN1_R_ERROR_GETTING_TIME), "error getting time"}, - {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"}, - {ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT), - "error parsing set element"}, - {ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS), - "error setting cipher params"}, - {ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER), "expecting an integer"}, - {ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT), "expecting an object"}, - {ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN), "expecting a boolean"}, - {ERR_REASON(ASN1_R_EXPECTING_A_TIME), "expecting a time"}, - {ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"}, - {ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED), - "explicit tag not constructed"}, - {ERR_REASON(ASN1_R_FIELD_MISSING), "field missing"}, - {ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE), "first num too large"}, - {ERR_REASON(ASN1_R_HEADER_TOO_LONG), "header too long"}, - {ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"}, - {ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean"}, - {ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS), "illegal characters"}, - {ERR_REASON(ASN1_R_ILLEGAL_FORMAT), "illegal format"}, - {ERR_REASON(ASN1_R_ILLEGAL_HEX), "illegal hex"}, - {ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG), "illegal implicit tag"}, - {ERR_REASON(ASN1_R_ILLEGAL_INTEGER), "illegal integer"}, - {ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"}, - {ERR_REASON(ASN1_R_ILLEGAL_NULL), "illegal null"}, - {ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE), "illegal null value"}, - {ERR_REASON(ASN1_R_ILLEGAL_OBJECT), "illegal object"}, - {ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY), "illegal optional any"}, - {ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE), - "illegal options on item template"}, - {ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY), "illegal tagged any"}, - {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE), "illegal time value"}, - {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"}, - {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG), - "integer too large for long"}, - {ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT), - "invalid bit string bits left"}, - {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"}, - {ERR_REASON(ASN1_R_INVALID_DIGIT), "invalid digit"}, - {ERR_REASON(ASN1_R_INVALID_MIME_TYPE), "invalid mime type"}, - {ERR_REASON(ASN1_R_INVALID_MODIFIER), "invalid modifier"}, - {ERR_REASON(ASN1_R_INVALID_NUMBER), "invalid number"}, - {ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"}, - {ERR_REASON(ASN1_R_INVALID_SEPARATOR), "invalid separator"}, - {ERR_REASON(ASN1_R_INVALID_TIME_FORMAT), "invalid time format"}, - {ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH), - "invalid universalstring length"}, - {ERR_REASON(ASN1_R_INVALID_UTF8STRING), "invalid utf8string"}, - {ERR_REASON(ASN1_R_IV_TOO_LARGE), "iv too large"}, - {ERR_REASON(ASN1_R_LENGTH_ERROR), "length error"}, - {ERR_REASON(ASN1_R_LIST_ERROR), "list error"}, - {ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE), "mime no content type"}, - {ERR_REASON(ASN1_R_MIME_PARSE_ERROR), "mime parse error"}, - {ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"}, - {ERR_REASON(ASN1_R_MISSING_EOC), "missing eoc"}, - {ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"}, - {ERR_REASON(ASN1_R_MISSING_VALUE), "missing value"}, - {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"}, - {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"}, - {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"}, - {ERR_REASON(ASN1_R_NESTED_TOO_DEEP), "nested too deep"}, - {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"}, - {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"}, - {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"}, - {ERR_REASON(ASN1_R_NO_CONTENT_TYPE), "no content type"}, - {ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST), "no default digest"}, - {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"}, - {ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE), - "no multipart body failure"}, - {ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"}, - {ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE), "no sig content type"}, - {ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH), "null is wrong length"}, - {ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"}, - {ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS), "odd number of chars"}, - {ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING), - "private key header missing"}, - {ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"}, - {ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"}, - {ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"}, - {ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG), - "sequence or set needs config"}, - {ERR_REASON(ASN1_R_SHORT_LINE), "short line"}, - {ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"}, - {ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"}, - {ERR_REASON(ASN1_R_STRING_TOO_LONG), "string too long"}, - {ERR_REASON(ASN1_R_STRING_TOO_SHORT), "string too short"}, - {ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH), "tag value too high"}, - {ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), - "the asn1 object identifier is not known for this md"}, - {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"}, - {ERR_REASON(ASN1_R_TOO_LONG), "too long"}, - {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED), "type not constructed"}, - {ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE), "type not primitive"}, - {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY), "unable to decode rsa key"}, - {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY), - "unable to decode rsa private key"}, - {ERR_REASON(ASN1_R_UNEXPECTED_EOC), "unexpected eoc"}, - {ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), - "universalstring is wrong length"}, - {ERR_REASON(ASN1_R_UNKNOWN_FORMAT), "unknown format"}, - {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), - "unknown message digest algorithm"}, - {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE), "unknown object type"}, - {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"}, - {ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM), - "unknown signature algorithm"}, - {ERR_REASON(ASN1_R_UNKNOWN_TAG), "unknown tag"}, - {ERR_REASON(ASN1_R_UNKOWN_FORMAT), "unknown format"}, - {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE), - "unsupported any defined by type"}, - {ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, - {ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM), - "unsupported encryption algorithm"}, - {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE), - "unsupported public key type"}, - {ERR_REASON(ASN1_R_UNSUPPORTED_TYPE), "unsupported type"}, - {ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"}, - {ERR_REASON(ASN1_R_WRONG_TAG), "wrong tag"}, - {ERR_REASON(ASN1_R_WRONG_TYPE), "wrong type"}, - {0, NULL} -}; - -#endif - -void ERR_load_ASN1_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) { - ERR_load_strings(0, ASN1_str_functs); - ERR_load_strings(0, ASN1_str_reasons); - } -#endif -} -/* asn1_gen.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "cryptlib.h" -// #include "asn1.h" -#include "x509v3.h" - -#define ASN1_GEN_FLAG 0x10000 -#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) -#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) -#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) -#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) -#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) -#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) -#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) -#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) - -#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} - -#define ASN1_FLAG_EXP_MAX 20 -/* Maximum number of nested sequences */ -#define ASN1_GEN_SEQ_MAX_DEPTH 50 - -/* Input formats */ - -/* ASCII: default */ -#define ASN1_GEN_FORMAT_ASCII 1 -/* UTF8 */ -#define ASN1_GEN_FORMAT_UTF8 2 -/* Hex */ -#define ASN1_GEN_FORMAT_HEX 3 -/* List of bits */ -#define ASN1_GEN_FORMAT_BITLIST 4 - -struct tag_name_st { - const char *strnam; - int len; - int tag; -}; - -typedef struct { - int exp_tag; - int exp_class; - int exp_constructed; - int exp_pad; - long exp_len; -} tag_exp_type; - -typedef struct { - int imp_tag; - int imp_class; - int utype; - int format; - const char *str; - tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; - int exp_count; -} tag_exp_arg; - -static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, - int *perr); -static int bitstr_cb(const char *elem, int len, void *bitstr); -static int asn1_cb(const char *elem, int len, void *bitstr); -static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, - int exp_constructed, int exp_pad, int imp_ok); -static int parse_tagging(const char *vstart, int vlen, int *ptag, - int *pclass); -static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, - int depth, int *perr); -static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); -static int asn1_str2tag(const char *tagstr, int len); - -ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) -{ - X509V3_CTX cnf; - - if (!nconf) - return ASN1_generate_v3(str, NULL); - - X509V3_set_nconf(&cnf, nconf); - return ASN1_generate_v3(str, &cnf); -} - -ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) -{ - int err = 0; - ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); - if (err) - ASN1err(ASN1_F_ASN1_GENERATE_V3, err); - return ret; -} - -static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, - int *perr) -{ - ASN1_TYPE *ret; - tag_exp_arg asn1_tags; - tag_exp_type *etmp; - - int i, len; - - unsigned char *orig_der = NULL, *new_der = NULL; - const unsigned char *cpy_start; - unsigned char *p; - const unsigned char *cp; - int cpy_len; - long hdr_len; - int hdr_constructed = 0, hdr_tag, hdr_class; - int r; - - asn1_tags.imp_tag = -1; - asn1_tags.imp_class = -1; - asn1_tags.format = ASN1_GEN_FORMAT_ASCII; - asn1_tags.exp_count = 0; - if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { - *perr = ASN1_R_UNKNOWN_TAG; - return NULL; - } - - if ((asn1_tags.utype == V_ASN1_SEQUENCE) - || (asn1_tags.utype == V_ASN1_SET)) { - if (!cnf) { - *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; - return NULL; - } - if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { - *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; - return NULL; - } - ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); - } else - ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); - - if (!ret) - return NULL; - - /* If no tagging return base type */ - if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) - return ret; - - /* Generate the encoding */ - cpy_len = i2d_ASN1_TYPE(ret, &orig_der); - ASN1_TYPE_free(ret); - ret = NULL; - /* Set point to start copying for modified encoding */ - cpy_start = orig_der; - - /* Do we need IMPLICIT tagging? */ - if (asn1_tags.imp_tag != -1) { - /* If IMPLICIT we will replace the underlying tag */ - /* Skip existing tag+len */ - r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, - cpy_len); - if (r & 0x80) - goto err; - /* Update copy length */ - cpy_len -= cpy_start - orig_der; - /* - * For IMPLICIT tagging the length should match the original length - * and constructed flag should be consistent. - */ - if (r & 0x1) { - /* Indefinite length constructed */ - hdr_constructed = 2; - hdr_len = 0; - } else - /* Just retain constructed flag */ - hdr_constructed = r & V_ASN1_CONSTRUCTED; - /* - * Work out new length with IMPLICIT tag: ignore constructed because - * it will mess up if indefinite length - */ - len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); - } else - len = cpy_len; - - /* Work out length in any EXPLICIT, starting from end */ - - for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; - i < asn1_tags.exp_count; i++, etmp--) { - /* Content length: number of content octets + any padding */ - len += etmp->exp_pad; - etmp->exp_len = len; - /* Total object length: length including new header */ - len = ASN1_object_size(0, len, etmp->exp_tag); - } - - /* Allocate buffer for new encoding */ - - new_der = OPENSSL_malloc(len); - if (!new_der) - goto err; - - /* Generate tagged encoding */ - - p = new_der; - - /* Output explicit tags first */ - - for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; - i++, etmp++) { - ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, - etmp->exp_tag, etmp->exp_class); - if (etmp->exp_pad) - *p++ = 0; - } - - /* If IMPLICIT, output tag */ - - if (asn1_tags.imp_tag != -1) { - if (asn1_tags.imp_class == V_ASN1_UNIVERSAL - && (asn1_tags.imp_tag == V_ASN1_SEQUENCE - || asn1_tags.imp_tag == V_ASN1_SET)) - hdr_constructed = V_ASN1_CONSTRUCTED; - ASN1_put_object(&p, hdr_constructed, hdr_len, - asn1_tags.imp_tag, asn1_tags.imp_class); - } - - /* Copy across original encoding */ - memcpy(p, cpy_start, cpy_len); - - cp = new_der; - - /* Obtain new ASN1_TYPE structure */ - ret = d2i_ASN1_TYPE(NULL, &cp, len); - - err: - if (orig_der) - OPENSSL_free(orig_der); - if (new_der) - OPENSSL_free(new_der); - - return ret; - -} - -static int asn1_cb(const char *elem, int len, void *bitstr) -{ - tag_exp_arg *arg = bitstr; - int i; - int utype; - int vlen = 0; - const char *p, *vstart = NULL; - - int tmp_tag, tmp_class; - - if (elem == NULL) - return -1; - - for (i = 0, p = elem; i < len; p++, i++) { - /* Look for the ':' in name value pairs */ - if (*p == ':') { - vstart = p + 1; - vlen = len - (vstart - elem); - len = p - elem; - break; - } - } - - utype = asn1_str2tag(elem, len); - - if (utype == -1) { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); - ERR_add_error_data(2, "tag=", elem); - return -1; - } - - /* If this is not a modifier mark end of string and exit */ - if (!(utype & ASN1_GEN_FLAG)) { - arg->utype = utype; - arg->str = vstart; - /* If no value and not end of string, error */ - if (!vstart && elem[len]) { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); - return -1; - } - return 0; - } - - switch (utype) { - - case ASN1_GEN_FLAG_IMP: - /* Check for illegal multiple IMPLICIT tagging */ - if (arg->imp_tag != -1) { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); - return -1; - } - if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) - return -1; - break; - - case ASN1_GEN_FLAG_EXP: - - if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) - return -1; - if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) - return -1; - break; - - case ASN1_GEN_FLAG_SEQWRAP: - if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) - return -1; - break; - - case ASN1_GEN_FLAG_SETWRAP: - if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) - return -1; - break; - - case ASN1_GEN_FLAG_BITWRAP: - if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) - return -1; - break; - - case ASN1_GEN_FLAG_OCTWRAP: - if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) - return -1; - break; - - case ASN1_GEN_FLAG_FORMAT: - if (!vstart) { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); - return -1; - } - if (!strncmp(vstart, "ASCII", 5)) - arg->format = ASN1_GEN_FORMAT_ASCII; - else if (!strncmp(vstart, "UTF8", 4)) - arg->format = ASN1_GEN_FORMAT_UTF8; - else if (!strncmp(vstart, "HEX", 3)) - arg->format = ASN1_GEN_FORMAT_HEX; - else if (!strncmp(vstart, "BITLIST", 7)) - arg->format = ASN1_GEN_FORMAT_BITLIST; - else { - ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); - return -1; - } - break; - - } - - return 1; - -} - -static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) -{ - char erch[2]; - long tag_num; - char *eptr; - if (!vstart) - return 0; - tag_num = strtoul(vstart, &eptr, 10); - /* Check we haven't gone past max length: should be impossible */ - if (eptr && *eptr && (eptr > vstart + vlen)) - return 0; - if (tag_num < 0) { - ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); - return 0; - } - *ptag = tag_num; - /* If we have non numeric characters, parse them */ - if (eptr) - vlen -= eptr - vstart; - else - vlen = 0; - if (vlen) { - switch (*eptr) { - - case 'U': - *pclass = V_ASN1_UNIVERSAL; - break; - - case 'A': - *pclass = V_ASN1_APPLICATION; - break; - - case 'P': - *pclass = V_ASN1_PRIVATE; - break; - - case 'C': - *pclass = V_ASN1_CONTEXT_SPECIFIC; - break; - - default: - erch[0] = *eptr; - erch[1] = 0; - ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); - ERR_add_error_data(2, "Char=", erch); - return 0; - break; - - } - } else - *pclass = V_ASN1_CONTEXT_SPECIFIC; - - return 1; - -} - -/* Handle multiple types: SET and SEQUENCE */ - -static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, - int depth, int *perr) -{ - ASN1_TYPE *ret = NULL; - STACK_OF(ASN1_TYPE) *sk = NULL; - STACK_OF(CONF_VALUE) *sect = NULL; - unsigned char *der = NULL; - int derlen; - int i; - sk = sk_ASN1_TYPE_new_null(); - if (!sk) - goto bad; - if (section) { - if (!cnf) - goto bad; - sect = X509V3_get_section(cnf, (char *)section); - if (!sect) - goto bad; - for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { - ASN1_TYPE *typ = - generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, - depth + 1, perr); - if (!typ) - goto bad; - if (!sk_ASN1_TYPE_push(sk, typ)) - goto bad; - } - } - - /* - * Now we has a STACK of the components, convert to the correct form - */ - - if (utype == V_ASN1_SET) - derlen = i2d_ASN1_SET_ANY(sk, &der); - else - derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); - - if (derlen < 0) - goto bad; - - if (!(ret = ASN1_TYPE_new())) - goto bad; - - if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) - goto bad; - - ret->type = utype; - - ret->value.asn1_string->data = der; - ret->value.asn1_string->length = derlen; - - der = NULL; - - bad: - - if (der) - OPENSSL_free(der); - - if (sk) - sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); - if (sect) - X509V3_section_free(cnf, sect); - - return ret; -} - -static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, - int exp_constructed, int exp_pad, int imp_ok) -{ - tag_exp_type *exp_tmp; - /* Can only have IMPLICIT if permitted */ - if ((arg->imp_tag != -1) && !imp_ok) { - ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); - return 0; - } - - if (arg->exp_count == ASN1_FLAG_EXP_MAX) { - ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); - return 0; - } - - exp_tmp = &arg->exp_list[arg->exp_count++]; - - /* - * If IMPLICIT set tag to implicit value then reset implicit tag since it - * has been used. - */ - if (arg->imp_tag != -1) { - exp_tmp->exp_tag = arg->imp_tag; - exp_tmp->exp_class = arg->imp_class; - arg->imp_tag = -1; - arg->imp_class = -1; - } else { - exp_tmp->exp_tag = exp_tag; - exp_tmp->exp_class = exp_class; - } - exp_tmp->exp_constructed = exp_constructed; - exp_tmp->exp_pad = exp_pad; - - return 1; -} - -static int asn1_str2tag(const char *tagstr, int len) -{ - unsigned int i; - static const struct tag_name_st *tntmp, tnst[] = { - ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), - ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), - ASN1_GEN_STR("NULL", V_ASN1_NULL), - ASN1_GEN_STR("INT", V_ASN1_INTEGER), - ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), - ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), - ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), - ASN1_GEN_STR("OID", V_ASN1_OBJECT), - ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), - ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), - ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), - ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), - ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), - ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), - ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), - ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), - ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), - ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), - ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), - ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), - ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), - ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), - ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), - ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), - ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), - ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), - ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), - ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), - ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), - ASN1_GEN_STR("T61", V_ASN1_T61STRING), - ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), - ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), - ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), - ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), - ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), - ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), - - /* Special cases */ - ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), - ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), - ASN1_GEN_STR("SET", V_ASN1_SET), - /* type modifiers */ - /* Explicit tag */ - ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), - ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), - /* Implicit tag */ - ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), - ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), - /* OCTET STRING wrapper */ - ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), - /* SEQUENCE wrapper */ - ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), - /* SET wrapper */ - ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), - /* BIT STRING wrapper */ - ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), - ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), - ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), - }; - - if (len == -1) - len = strlen(tagstr); - - tntmp = tnst; - for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { - if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) - return tntmp->tag; - } - - return -1; -} - -static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) -{ - ASN1_TYPE *atmp = NULL; - - CONF_VALUE vtmp; - - unsigned char *rdata; - long rdlen; - - int no_unused = 1; - - if (!(atmp = ASN1_TYPE_new())) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (!str) - str = ""; - - switch (utype) { - - case V_ASN1_NULL: - if (str && *str) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); - goto bad_form; - } - break; - - case V_ASN1_BOOLEAN: - if (format != ASN1_GEN_FORMAT_ASCII) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); - goto bad_form; - } - vtmp.name = NULL; - vtmp.section = NULL; - vtmp.value = (char *)str; - if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); - goto bad_str; - } - break; - - case V_ASN1_INTEGER: - case V_ASN1_ENUMERATED: - if (format != ASN1_GEN_FORMAT_ASCII) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); - goto bad_form; - } - if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); - goto bad_str; - } - break; - - case V_ASN1_OBJECT: - if (format != ASN1_GEN_FORMAT_ASCII) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); - goto bad_form; - } - if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); - goto bad_str; - } - break; - - case V_ASN1_UTCTIME: - case V_ASN1_GENERALIZEDTIME: - if (format != ASN1_GEN_FORMAT_ASCII) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); - goto bad_form; - } - if (!(atmp->value.asn1_string = ASN1_STRING_new())) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); - goto bad_str; - } - if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); - goto bad_str; - } - atmp->value.asn1_string->type = utype; - if (!ASN1_TIME_check(atmp->value.asn1_string)) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); - goto bad_str; - } - - break; - - case V_ASN1_BMPSTRING: - case V_ASN1_PRINTABLESTRING: - case V_ASN1_IA5STRING: - case V_ASN1_T61STRING: - case V_ASN1_UTF8STRING: - case V_ASN1_VISIBLESTRING: - case V_ASN1_UNIVERSALSTRING: - case V_ASN1_GENERALSTRING: - case V_ASN1_NUMERICSTRING: - - if (format == ASN1_GEN_FORMAT_ASCII) - format = MBSTRING_ASC; - else if (format == ASN1_GEN_FORMAT_UTF8) - format = MBSTRING_UTF8; - else { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); - goto bad_form; - } - - if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, - -1, format, ASN1_tag2bit(utype)) <= 0) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); - goto bad_str; - } - - break; - - case V_ASN1_BIT_STRING: - - case V_ASN1_OCTET_STRING: - - if (!(atmp->value.asn1_string = ASN1_STRING_new())) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); - goto bad_form; - } - - if (format == ASN1_GEN_FORMAT_HEX) { - - if (!(rdata = string_to_hex((char *)str, &rdlen))) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); - goto bad_str; - } - - atmp->value.asn1_string->data = rdata; - atmp->value.asn1_string->length = rdlen; - atmp->value.asn1_string->type = utype; - - } else if (format == ASN1_GEN_FORMAT_ASCII) - ASN1_STRING_set(atmp->value.asn1_string, str, -1); - else if ((format == ASN1_GEN_FORMAT_BITLIST) - && (utype == V_ASN1_BIT_STRING)) { - if (!CONF_parse_list - (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); - goto bad_str; - } - no_unused = 0; - - } else { - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); - goto bad_form; - } - - if ((utype == V_ASN1_BIT_STRING) && no_unused) { - atmp->value.asn1_string->flags - &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; - } - - break; - - default: - ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); - goto bad_str; - break; - } - - atmp->type = utype; - return atmp; - - bad_str: - ERR_add_error_data(2, "string=", str); - bad_form: - - ASN1_TYPE_free(atmp); - return NULL; - -} - -static int bitstr_cb(const char *elem, int len, void *bitstr) -{ - long bitnum; - char *eptr; - if (!elem) - return 0; - bitnum = strtoul(elem, &eptr, 10); - if (eptr && *eptr && (eptr != elem + len)) - return 0; - if (bitnum < 0) { - ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); - return 0; - } - if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { - ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); - return 0; - } - return 1; -} -/* crypto/asn1/asn1_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "asn1.h" -#include "asn1_mac.h" - -static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, - long max); -static void asn1_put_length(unsigned char **pp, int length); -const char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT; - -static int _asn1_check_infinite_end(const unsigned char **p, long len) -{ - /* - * If there is 0 or 1 byte left, the length check should pick things up - */ - if (len <= 0) - return (1); - else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) { - (*p) += 2; - return (1); - } - return (0); -} - -int ASN1_check_infinite_end(unsigned char **p, long len) -{ - return _asn1_check_infinite_end((const unsigned char **)p, len); -} - -int ASN1_const_check_infinite_end(const unsigned char **p, long len) -{ - return _asn1_check_infinite_end(p, len); -} - -int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, - int *pclass, long omax) -{ - int i, ret; - long l; - const unsigned char *p = *pp; - int tag, xclass, inf; - long max = omax; - - if (!max) - goto err; - ret = (*p & V_ASN1_CONSTRUCTED); - xclass = (*p & V_ASN1_PRIVATE); - i = *p & V_ASN1_PRIMITIVE_TAG; - if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */ - p++; - if (--max == 0) - goto err; - l = 0; - while (*p & 0x80) { - l <<= 7L; - l |= *(p++) & 0x7f; - if (--max == 0) - goto err; - if (l > (INT_MAX >> 7L)) - goto err; - } - l <<= 7L; - l |= *(p++) & 0x7f; - tag = (int)l; - if (--max == 0) - goto err; - } else { - tag = i; - p++; - if (--max == 0) - goto err; - } - *ptag = tag; - *pclass = xclass; - if (!asn1_get_length(&p, &inf, plength, max)) - goto err; - - if (inf && !(ret & V_ASN1_CONSTRUCTED)) - goto err; - -#if 0 - fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n", - (int)p, *plength, omax, (int)*pp, (int)(p + *plength), - (int)(omax + *pp)); - -#endif - if (*plength > (omax - (p - *pp))) { - ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG); - /* - * Set this so that even if things are not long enough the values are - * set correctly - */ - ret |= 0x80; - } - *pp = p; - return (ret | inf); - err: - ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG); - return (0x80); -} - -static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, - long max) -{ - const unsigned char *p = *pp; - unsigned long ret = 0; - unsigned long i; - - if (max-- < 1) - return 0; - if (*p == 0x80) { - *inf = 1; - ret = 0; - p++; - } else { - *inf = 0; - i = *p & 0x7f; - if (*(p++) & 0x80) { - if (i > sizeof(ret) || max < (long)i) - return 0; - while (i-- > 0) { - ret <<= 8L; - ret |= *(p++); - } - } else - ret = i; - } - if (ret > LONG_MAX) - return 0; - *pp = p; - *rl = (long)ret; - return 1; -} - -/* - * class 0 is constructed constructed == 2 for indefinite length constructed - */ -void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, - int xclass) -{ - unsigned char *p = *pp; - int i, ttag; - - i = (constructed) ? V_ASN1_CONSTRUCTED : 0; - i |= (xclass & V_ASN1_PRIVATE); - if (tag < 31) - *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); - else { - *(p++) = i | V_ASN1_PRIMITIVE_TAG; - for (i = 0, ttag = tag; ttag > 0; i++) - ttag >>= 7; - ttag = i; - while (i-- > 0) { - p[i] = tag & 0x7f; - if (i != (ttag - 1)) - p[i] |= 0x80; - tag >>= 7; - } - p += ttag; - } - if (constructed == 2) - *(p++) = 0x80; - else - asn1_put_length(&p, length); - *pp = p; -} - -int ASN1_put_eoc(unsigned char **pp) -{ - unsigned char *p = *pp; - *p++ = 0; - *p++ = 0; - *pp = p; - return 2; -} - -static void asn1_put_length(unsigned char **pp, int length) -{ - unsigned char *p = *pp; - int i, l; - if (length <= 127) - *(p++) = (unsigned char)length; - else { - l = length; - for (i = 0; l > 0; i++) - l >>= 8; - *(p++) = i | 0x80; - l = i; - while (i-- > 0) { - p[i] = length & 0xff; - length >>= 8; - } - p += l; - } - *pp = p; -} - -int ASN1_object_size(int constructed, int length, int tag) -{ - int ret = 1; - if (length < 0) - return -1; - if (tag >= 31) { - while (tag > 0) { - tag >>= 7; - ret++; - } - } - if (constructed == 2) { - ret += 3; - } else { - ret++; - if (length > 127) { - int tmplen = length; - while (tmplen > 0) { - tmplen >>= 8; - ret++; - } - } - } - if (ret >= INT_MAX - length) - return -1; - return ret + length; -} - -static int _asn1_Finish(ASN1_const_CTX *c) -{ - if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) { - if (!ASN1_const_check_infinite_end(&c->p, c->slen)) { - c->error = ERR_R_MISSING_ASN1_EOS; - return (0); - } - } - if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) { - c->error = ERR_R_ASN1_LENGTH_MISMATCH; - return (0); - } - return (1); -} - -int asn1_Finish(ASN1_CTX *c) -{ - return _asn1_Finish((ASN1_const_CTX *)c); -} - -int asn1_const_Finish(ASN1_const_CTX *c) -{ - return _asn1_Finish(c); -} - -int asn1_GetSequence(ASN1_const_CTX *c, long *length) -{ - const unsigned char *q; - - q = c->p; - c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass), - *length); - if (c->inf & 0x80) { - c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL; - return (0); - } - if (c->tag != V_ASN1_SEQUENCE) { - c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE; - return (0); - } - (*length) -= (c->p - q); - if (c->max && (*length < 0)) { - c->error = ERR_R_ASN1_LENGTH_MISMATCH; - return (0); - } - if (c->inf == (1 | V_ASN1_CONSTRUCTED)) - c->slen = *length; - c->eos = 0; - return (1); -} - -int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) -{ - if (str == NULL) - return 0; - dst->type = str->type; - if (!ASN1_STRING_set(dst, str->data, str->length)) - return 0; - dst->flags = str->flags; - return 1; -} - -ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) -{ - ASN1_STRING *ret; - if (!str) - return NULL; - ret = ASN1_STRING_new(); - if (!ret) - return NULL; - if (!ASN1_STRING_copy(ret, str)) { - ASN1_STRING_free(ret); - return NULL; - } - return ret; -} - -int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) -{ - unsigned char *c; - const char *data = _data; - - if (len < 0) { - if (data == NULL) - return (0); - else - len = strlen(data); - } - if ((str->length <= len) || (str->data == NULL)) { - c = str->data; - if (c == NULL) - str->data = OPENSSL_malloc(len + 1); - else - str->data = OPENSSL_realloc(c, len + 1); - - if (str->data == NULL) { - ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE); - str->data = c; - return (0); - } - } - str->length = len; - if (data != NULL) { - memcpy(str->data, data, len); - /* an allowance for strings :-) */ - str->data[len] = '\0'; - } - return (1); -} - -void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) -{ - if (str->data) - OPENSSL_free(str->data); - str->data = data; - str->length = len; -} - -ASN1_STRING *ASN1_STRING_new(void) -{ - return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); -} - -ASN1_STRING *ASN1_STRING_type_new(int type) -{ - ASN1_STRING *ret; - - ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); - if (ret == NULL) { - ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - ret->length = 0; - ret->type = type; - ret->data = NULL; - ret->flags = 0; - return (ret); -} - -void ASN1_STRING_free(ASN1_STRING *a) -{ - if (a == NULL) - return; - if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) - OPENSSL_free(a->data); - OPENSSL_free(a); -} - -void ASN1_STRING_clear_free(ASN1_STRING *a) -{ - if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) - OPENSSL_cleanse(a->data, a->length); - ASN1_STRING_free(a); -} - -int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) -{ - int i; - - i = (a->length - b->length); - if (i == 0) { - i = memcmp(a->data, b->data, a->length); - if (i == 0) - return (a->type - b->type); - else - return (i); - } else - return (i); -} - -void asn1_add_error(const unsigned char *address, int offset) -{ - char buf1[DECIMAL_SIZE(address) + 1], buf2[DECIMAL_SIZE(offset) + 1]; - - BIO_snprintf(buf1, sizeof(buf1), "%lu", (unsigned long)address); - BIO_snprintf(buf2, sizeof(buf2), "%d", offset); - ERR_add_error_data(4, "address=", buf1, " offset=", buf2); -} - -int ASN1_STRING_length(const ASN1_STRING *x) -{ - return M_ASN1_STRING_length(x); -} - -void ASN1_STRING_length_set(ASN1_STRING *x, int len) -{ - M_ASN1_STRING_length_set(x, len); - return; -} - -int ASN1_STRING_type(ASN1_STRING *x) -{ - return M_ASN1_STRING_type(x); -} - -unsigned char *ASN1_STRING_data(ASN1_STRING *x) -{ - return M_ASN1_STRING_data(x); -} -/* crypto/asn1/asn1_par.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "buffer.h" -#include "objects.h" -// #include "asn1.h" - -#ifndef ASN1_PARSE_MAXDEPTH -#define ASN1_PARSE_MAXDEPTH 128 -#endif - -static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, - int indent); -static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, - int offset, int depth, int indent, int dump); -static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, - int indent) -{ - static const char fmt[] = "%-18s"; - char str[128]; - const char *p; - - if (constructed & V_ASN1_CONSTRUCTED) - p = "cons: "; - else - p = "prim: "; - if (BIO_write(bp, p, 6) < 6) - goto err; - BIO_indent(bp, indent, 128); - - p = str; - if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - BIO_snprintf(str, sizeof(str), "priv [ %d ] ", tag); - else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - BIO_snprintf(str, sizeof(str), "cont [ %d ]", tag); - else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - BIO_snprintf(str, sizeof(str), "appl [ %d ]", tag); - else if (tag > 30) - BIO_snprintf(str, sizeof(str), "", tag); - else - p = ASN1_tag2str(tag); - - if (BIO_printf(bp, fmt, p) <= 0) - goto err; - return (1); - err: - return (0); -} - -int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent) -{ - return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0)); -} - -int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, - int dump) -{ - return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump)); -} - -static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, - int offset, int depth, int indent, int dump) -{ - const unsigned char *p, *ep, *tot, *op, *opp; - long len; - int tag, xclass, ret = 0; - int nl, hl, j, r; - ASN1_OBJECT *o = NULL; - ASN1_OCTET_STRING *os = NULL; - /* ASN1_BMPSTRING *bmp=NULL; */ - int dump_indent; - -#if 0 - dump_indent = indent; -#else - dump_indent = 6; /* Because we know BIO_dump_indent() */ -#endif - - if (depth > ASN1_PARSE_MAXDEPTH) { - BIO_puts(bp, "BAD RECURSION DEPTH\n"); - return 0; - } - - p = *pp; - tot = p + length; - op = p - 1; - while ((p < tot) && (op < p)) { - op = p; - j = ASN1_get_object(&p, &len, &tag, &xclass, length); -#ifdef LINT - j = j; -#endif - if (j & 0x80) { - if (BIO_write(bp, "Error in encoding\n", 18) <= 0) - goto end; - ret = 0; - goto end; - } - hl = (p - op); - length -= hl; - /* - * if j == 0x21 it is a constructed indefinite length object - */ - if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp)) - <= 0) - goto end; - - if (j != (V_ASN1_CONSTRUCTED | 1)) { - if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ", - depth, (long)hl, len) <= 0) - goto end; - } else { - if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0) - goto end; - } - if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0)) - goto end; - if (j & V_ASN1_CONSTRUCTED) { - const unsigned char *sp; - - ep = p + len; - if (BIO_write(bp, "\n", 1) <= 0) - goto end; - if (len > length) { - BIO_printf(bp, "length is greater than %ld\n", length); - ret = 0; - goto end; - } - if ((j == 0x21) && (len == 0)) { - sp = p; - for (;;) { - r = asn1_parse2(bp, &p, (long)(tot - p), - offset + (p - *pp), depth + 1, - indent, dump); - if (r == 0) { - ret = 0; - goto end; - } - if ((r == 2) || (p >= tot)) { - len = p - sp; - break; - } - } - } else { - long tmp = len; - - while (p < ep) { - sp = p; - r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1, - indent, dump); - if (r == 0) { - ret = 0; - goto end; - } - tmp -= p - sp; - } - } - } else if (xclass != 0) { - p += len; - if (BIO_write(bp, "\n", 1) <= 0) - goto end; - } else { - nl = 0; - if ((tag == V_ASN1_PRINTABLESTRING) || - (tag == V_ASN1_T61STRING) || - (tag == V_ASN1_IA5STRING) || - (tag == V_ASN1_VISIBLESTRING) || - (tag == V_ASN1_NUMERICSTRING) || - (tag == V_ASN1_UTF8STRING) || - (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) { - if (BIO_write(bp, ":", 1) <= 0) - goto end; - if ((len > 0) && BIO_write(bp, (const char *)p, (int)len) - != (int)len) - goto end; - } else if (tag == V_ASN1_OBJECT) { - opp = op; - if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) { - if (BIO_write(bp, ":", 1) <= 0) - goto end; - i2a_ASN1_OBJECT(bp, o); - } else { - if (BIO_write(bp, ":BAD OBJECT", 11) <= 0) - goto end; - } - } else if (tag == V_ASN1_BOOLEAN) { - int ii; - - opp = op; - ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl); - if (ii < 0) { - if (BIO_write(bp, "Bad boolean\n", 12) <= 0) - goto end; - } - BIO_printf(bp, ":%d", ii); - } else if (tag == V_ASN1_BMPSTRING) { - /* do the BMP thang */ - } else if (tag == V_ASN1_OCTET_STRING) { - int i, printable = 1; - - opp = op; - os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl); - if (os != NULL && os->length > 0) { - opp = os->data; - /* - * testing whether the octet string is printable - */ - for (i = 0; i < os->length; i++) { - if (((opp[i] < ' ') && - (opp[i] != '\n') && - (opp[i] != '\r') && - (opp[i] != '\t')) || (opp[i] > '~')) { - printable = 0; - break; - } - } - if (printable) - /* printable string */ - { - if (BIO_write(bp, ":", 1) <= 0) - goto end; - if (BIO_write(bp, (const char *)opp, os->length) <= 0) - goto end; - } else if (!dump) - /* - * not printable => print octet string as hex dump - */ - { - if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0) - goto end; - for (i = 0; i < os->length; i++) { - if (BIO_printf(bp, "%02X", opp[i]) <= 0) - goto end; - } - } else - /* print the normal dump */ - { - if (!nl) { - if (BIO_write(bp, "\n", 1) <= 0) - goto end; - } - if (BIO_dump_indent(bp, - (const char *)opp, - ((dump == -1 || dump > - os-> - length) ? os->length : dump), - dump_indent) <= 0) - goto end; - nl = 1; - } - } - if (os != NULL) { - M_ASN1_OCTET_STRING_free(os); - os = NULL; - } - } else if (tag == V_ASN1_INTEGER) { - ASN1_INTEGER *bs; - int i; - - opp = op; - bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl); - if (bs != NULL) { - if (BIO_write(bp, ":", 1) <= 0) - goto end; - if (bs->type == V_ASN1_NEG_INTEGER) - if (BIO_write(bp, "-", 1) <= 0) - goto end; - for (i = 0; i < bs->length; i++) { - if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) - goto end; - } - if (bs->length == 0) { - if (BIO_write(bp, "00", 2) <= 0) - goto end; - } - } else { - if (BIO_write(bp, "BAD INTEGER", 11) <= 0) - goto end; - } - M_ASN1_INTEGER_free(bs); - } else if (tag == V_ASN1_ENUMERATED) { - ASN1_ENUMERATED *bs; - int i; - - opp = op; - bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl); - if (bs != NULL) { - if (BIO_write(bp, ":", 1) <= 0) - goto end; - if (bs->type == V_ASN1_NEG_ENUMERATED) - if (BIO_write(bp, "-", 1) <= 0) - goto end; - for (i = 0; i < bs->length; i++) { - if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) - goto end; - } - if (bs->length == 0) { - if (BIO_write(bp, "00", 2) <= 0) - goto end; - } - } else { - if (BIO_write(bp, "BAD ENUMERATED", 14) <= 0) - goto end; - } - M_ASN1_ENUMERATED_free(bs); - } else if (len > 0 && dump) { - if (!nl) { - if (BIO_write(bp, "\n", 1) <= 0) - goto end; - } - if (BIO_dump_indent(bp, (const char *)p, - ((dump == -1 || dump > len) ? len : dump), - dump_indent) <= 0) - goto end; - nl = 1; - } - - if (!nl) { - if (BIO_write(bp, "\n", 1) <= 0) - goto end; - } - p += len; - if ((tag == V_ASN1_EOC) && (xclass == 0)) { - ret = 2; /* End of sequence */ - goto end; - } - } - length -= len; - } - ret = 1; - end: - if (o != NULL) - ASN1_OBJECT_free(o); - if (os != NULL) - M_ASN1_OCTET_STRING_free(os); - *pp = p; - return (ret); -} - -const char *ASN1_tag2str(int tag) -{ - static const char *const tag2str[] = { - /* 0-4 */ - "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", - /* 5-9 */ - "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", - /* 10-13 */ - "ENUMERATED", "", "UTF8STRING", "", - /* 15-17 */ - "", "", "SEQUENCE", "SET", - /* 18-20 */ - "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", - /* 21-24 */ - "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", - /* 25-27 */ - "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", - /* 28-30 */ - "UNIVERSALSTRING", "", "BMPSTRING" - }; - - if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED)) - tag &= ~0x100; - - if (tag < 0 || tag > 30) - return "(unknown)"; - return tag2str[tag]; -} diff --git a/Sources/COpenSSL/asn1_int.h b/Sources/COpenSSL/asn1_int.h deleted file mode 100644 index c9fd8b12..00000000 --- a/Sources/COpenSSL/asn1_int.h +++ /dev/null @@ -1,63 +0,0 @@ -/* asn1t.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* Internal ASN1 template structures and functions: not for application use */ - -void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); diff --git a/Sources/COpenSSL/asn1_locl.h b/Sources/COpenSSL/asn1_locl.h deleted file mode 100644 index 4c004fab..00000000 --- a/Sources/COpenSSL/asn1_locl.h +++ /dev/null @@ -1,135 +0,0 @@ -/* asn1t.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* Internal ASN1 structures and functions: not for application use */ - -int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d); -int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d); - -/* ASN1 print context structure */ - -struct asn1_pctx_st { - unsigned long flags; - unsigned long nm_flags; - unsigned long cert_flags; - unsigned long oid_flags; - unsigned long str_flags; -} /* ASN1_PCTX */ ; - -/* ASN1 public key method structure */ - -struct evp_pkey_asn1_method_st { - int pkey_id; - int pkey_base_id; - unsigned long pkey_flags; - char *pem_str; - char *info; - int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub); - int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk); - int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); - int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - int (*priv_decode) (EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf); - int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); - int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - int (*pkey_size) (const EVP_PKEY *pk); - int (*pkey_bits) (const EVP_PKEY *pk); - int (*param_decode) (EVP_PKEY *pkey, - const unsigned char **pder, int derlen); - int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder); - int (*param_missing) (const EVP_PKEY *pk); - int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from); - int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); - int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - int (*sig_print) (BIO *out, - const X509_ALGOR *sigalg, const ASN1_STRING *sig, - int indent, ASN1_PCTX *pctx); - void (*pkey_free) (EVP_PKEY *pkey); - int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2); - /* Legacy functions for old PEM */ - int (*old_priv_decode) (EVP_PKEY *pkey, - const unsigned char **pder, int derlen); - int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder); - /* Custom ASN1 signature verification */ - int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); - int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *alg1, X509_ALGOR *alg2, - ASN1_BIT_STRING *sig); -} /* EVP_PKEY_ASN1_METHOD */ ; - -/* - * Method to handle CRL access. In general a CRL could be very large (several - * Mb) and can consume large amounts of resources if stored in memory by - * multiple processes. This method allows general CRL operations to be - * redirected to more efficient callbacks: for example a CRL entry database. - */ - -#define X509_CRL_METHOD_DYNAMIC 1 - -struct x509_crl_method_st { - int flags; - int (*crl_init) (X509_CRL *crl); - int (*crl_free) (X509_CRL *crl); - int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, - ASN1_INTEGER *ser, X509_NAME *issuer); - int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); -}; diff --git a/Sources/COpenSSL/asn1_mac.h b/Sources/COpenSSL/asn1_mac.h deleted file mode 100644 index 972aac3a..00000000 --- a/Sources/COpenSSL/asn1_mac.h +++ /dev/null @@ -1,579 +0,0 @@ -/* crypto/asn1/asn1_mac.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_ASN1_MAC_H -# define HEADER_ASN1_MAC_H - -# include "asn1.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# ifndef ASN1_MAC_ERR_LIB -# define ASN1_MAC_ERR_LIB ERR_LIB_ASN1 -# endif - -# define ASN1_MAC_H_err(f,r,line) \ - ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line)) - -# define M_ASN1_D2I_vars(a,type,func) \ - ASN1_const_CTX c; \ - type ret=NULL; \ - \ - c.pp=(const unsigned char **)pp; \ - c.q= *(const unsigned char **)pp; \ - c.error=ERR_R_NESTED_ASN1_ERROR; \ - if ((a == NULL) || ((*a) == NULL)) \ - { if ((ret=(type)func()) == NULL) \ - { c.line=__LINE__; goto err; } } \ - else ret=(*a); - -# define M_ASN1_D2I_Init() \ - c.p= *(const unsigned char **)pp; \ - c.max=(length == 0)?0:(c.p+length); - -# define M_ASN1_D2I_Finish_2(a) \ - if (!asn1_const_Finish(&c)) \ - { c.line=__LINE__; goto err; } \ - *(const unsigned char **)pp=c.p; \ - if (a != NULL) (*a)=ret; \ - return(ret); - -# define M_ASN1_D2I_Finish(a,func,e) \ - M_ASN1_D2I_Finish_2(a); \ -err:\ - ASN1_MAC_H_err((e),c.error,c.line); \ - asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \ - if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ - return(NULL) - -# define M_ASN1_D2I_start_sequence() \ - if (!asn1_GetSequence(&c,&length)) \ - { c.line=__LINE__; goto err; } -/* Begin reading ASN1 without a surrounding sequence */ -# define M_ASN1_D2I_begin() \ - c.slen = length; - -/* End reading ASN1 with no check on length */ -# define M_ASN1_D2I_Finish_nolen(a, func, e) \ - *pp=c.p; \ - if (a != NULL) (*a)=ret; \ - return(ret); \ -err:\ - ASN1_MAC_H_err((e),c.error,c.line); \ - asn1_add_error(*pp,(int)(c.q- *pp)); \ - if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ - return(NULL) - -# define M_ASN1_D2I_end_sequence() \ - (((c.inf&1) == 0)?(c.slen <= 0): \ - (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen))) - -/* Don't use this with d2i_ASN1_BOOLEAN() */ -# define M_ASN1_D2I_get(b, func) \ - c.q=c.p; \ - if (func(&(b),&c.p,c.slen) == NULL) \ - {c.line=__LINE__; goto err; } \ - c.slen-=(c.p-c.q); - -/* Don't use this with d2i_ASN1_BOOLEAN() */ -# define M_ASN1_D2I_get_x(type,b,func) \ - c.q=c.p; \ - if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \ - {c.line=__LINE__; goto err; } \ - c.slen-=(c.p-c.q); - -/* use this instead () */ -# define M_ASN1_D2I_get_int(b,func) \ - c.q=c.p; \ - if (func(&(b),&c.p,c.slen) < 0) \ - {c.line=__LINE__; goto err; } \ - c.slen-=(c.p-c.q); - -# define M_ASN1_D2I_get_opt(b,func,type) \ - if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ - == (V_ASN1_UNIVERSAL|(type)))) \ - { \ - M_ASN1_D2I_get(b,func); \ - } - -# define M_ASN1_D2I_get_int_opt(b,func,type) \ - if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ - == (V_ASN1_UNIVERSAL|(type)))) \ - { \ - M_ASN1_D2I_get_int(b,func); \ - } - -# define M_ASN1_D2I_get_imp(b,func, type) \ - M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ - c.q=c.p; \ - if (func(&(b),&c.p,c.slen) == NULL) \ - {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \ - c.slen-=(c.p-c.q);\ - M_ASN1_next_prev=_tmp; - -# define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \ - if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \ - (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \ - { \ - unsigned char _tmp = M_ASN1_next; \ - M_ASN1_D2I_get_imp(b,func, type);\ - } - -# define M_ASN1_D2I_get_set(r,func,free_func) \ - M_ASN1_D2I_get_imp_set(r,func,free_func, \ - V_ASN1_SET,V_ASN1_UNIVERSAL); - -# define M_ASN1_D2I_get_set_type(type,r,func,free_func) \ - M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \ - V_ASN1_SET,V_ASN1_UNIVERSAL); - -# define M_ASN1_D2I_get_set_opt(r,func,free_func) \ - if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ - V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ - { M_ASN1_D2I_get_set(r,func,free_func); } - -# define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \ - if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ - V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ - { M_ASN1_D2I_get_set_type(type,r,func,free_func); } - -# define M_ASN1_I2D_len_SET_opt(a,f) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - M_ASN1_I2D_len_SET(a,f); - -# define M_ASN1_I2D_put_SET_opt(a,f) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - M_ASN1_I2D_put_SET(a,f); - -# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - M_ASN1_I2D_put_SEQUENCE(a,f); - -# define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \ - if ((a != NULL) && (sk_##type##_num(a) != 0)) \ - M_ASN1_I2D_put_SEQUENCE_type(type,a,f); - -# define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \ - if ((c.slen != 0) && \ - (M_ASN1_next == \ - (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ - { \ - M_ASN1_D2I_get_imp_set(b,func,free_func,\ - tag,V_ASN1_CONTEXT_SPECIFIC); \ - } - -# define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \ - if ((c.slen != 0) && \ - (M_ASN1_next == \ - (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ - { \ - M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\ - tag,V_ASN1_CONTEXT_SPECIFIC); \ - } - -# define M_ASN1_D2I_get_seq(r,func,free_func) \ - M_ASN1_D2I_get_imp_set(r,func,free_func,\ - V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); - -# define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \ - M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ - V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) - -# define M_ASN1_D2I_get_seq_opt(r,func,free_func) \ - if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ - V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ - { M_ASN1_D2I_get_seq(r,func,free_func); } - -# define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \ - if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ - V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ - { M_ASN1_D2I_get_seq_type(type,r,func,free_func); } - -# define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \ - M_ASN1_D2I_get_imp_set(r,func,free_func,\ - x,V_ASN1_CONTEXT_SPECIFIC); - -# define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \ - M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ - x,V_ASN1_CONTEXT_SPECIFIC); - -# define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \ - c.q=c.p; \ - if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\ - (void (*)())free_func,a,b) == NULL) \ - { c.line=__LINE__; goto err; } \ - c.slen-=(c.p-c.q); - -# define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \ - c.q=c.p; \ - if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\ - free_func,a,b) == NULL) \ - { c.line=__LINE__; goto err; } \ - c.slen-=(c.p-c.q); - -# define M_ASN1_D2I_get_set_strings(r,func,a,b) \ - c.q=c.p; \ - if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \ - { c.line=__LINE__; goto err; } \ - c.slen-=(c.p-c.q); - -# define M_ASN1_D2I_get_EXP_opt(r,func,tag) \ - if ((c.slen != 0L) && (M_ASN1_next == \ - (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ - { \ - int Tinf,Ttag,Tclass; \ - long Tlen; \ - \ - c.q=c.p; \ - Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ - if (Tinf & 0x80) \ - { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ - c.line=__LINE__; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ - Tlen = c.slen - (c.p - c.q) - 2; \ - if (func(&(r),&c.p,Tlen) == NULL) \ - { c.line=__LINE__; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ - Tlen = c.slen - (c.p - c.q); \ - if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \ - { c.error=ERR_R_MISSING_ASN1_EOS; \ - c.line=__LINE__; goto err; } \ - }\ - c.slen-=(c.p-c.q); \ - } - -# define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \ - if ((c.slen != 0) && (M_ASN1_next == \ - (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ - { \ - int Tinf,Ttag,Tclass; \ - long Tlen; \ - \ - c.q=c.p; \ - Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ - if (Tinf & 0x80) \ - { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ - c.line=__LINE__; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ - Tlen = c.slen - (c.p - c.q) - 2; \ - if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \ - (void (*)())free_func, \ - b,V_ASN1_UNIVERSAL) == NULL) \ - { c.line=__LINE__; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ - Tlen = c.slen - (c.p - c.q); \ - if(!ASN1_check_infinite_end(&c.p, Tlen)) \ - { c.error=ERR_R_MISSING_ASN1_EOS; \ - c.line=__LINE__; goto err; } \ - }\ - c.slen-=(c.p-c.q); \ - } - -# define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \ - if ((c.slen != 0) && (M_ASN1_next == \ - (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ - { \ - int Tinf,Ttag,Tclass; \ - long Tlen; \ - \ - c.q=c.p; \ - Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ - if (Tinf & 0x80) \ - { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ - c.line=__LINE__; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ - Tlen = c.slen - (c.p - c.q) - 2; \ - if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \ - free_func,b,V_ASN1_UNIVERSAL) == NULL) \ - { c.line=__LINE__; goto err; } \ - if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ - Tlen = c.slen - (c.p - c.q); \ - if(!ASN1_check_infinite_end(&c.p, Tlen)) \ - { c.error=ERR_R_MISSING_ASN1_EOS; \ - c.line=__LINE__; goto err; } \ - }\ - c.slen-=(c.p-c.q); \ - } - -/* New macros */ -# define M_ASN1_New_Malloc(ret,type) \ - if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \ - { c.line=__LINE__; goto err2; } - -# define M_ASN1_New(arg,func) \ - if (((arg)=func()) == NULL) return(NULL) - -# define M_ASN1_New_Error(a) \ -/*- err: ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \ - return(NULL);*/ \ - err2: ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \ - return(NULL) - -/* - * BIG UGLY WARNING! This is so damn ugly I wanna puke. Unfortunately, some - * macros that use ASN1_const_CTX still insist on writing in the input - * stream. ARGH! ARGH! ARGH! Let's get rid of this macro package. Please? -- - * Richard Levitte - */ -# define M_ASN1_next (*((unsigned char *)(c.p))) -# define M_ASN1_next_prev (*((unsigned char *)(c.q))) - -/*************************************************/ - -# define M_ASN1_I2D_vars(a) int r=0,ret=0; \ - unsigned char *p; \ - if (a == NULL) return(0) - -/* Length Macros */ -# define M_ASN1_I2D_len(a,f) ret+=f(a,NULL) -# define M_ASN1_I2D_len_IMP_opt(a,f) if (a != NULL) M_ASN1_I2D_len(a,f) - -# define M_ASN1_I2D_len_SET(a,f) \ - ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); - -# define M_ASN1_I2D_len_SET_type(type,a,f) \ - ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \ - V_ASN1_UNIVERSAL,IS_SET); - -# define M_ASN1_I2D_len_SEQUENCE(a,f) \ - ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ - IS_SEQUENCE); - -# define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \ - ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \ - V_ASN1_UNIVERSAL,IS_SEQUENCE) - -# define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - M_ASN1_I2D_len_SEQUENCE(a,f); - -# define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \ - if ((a != NULL) && (sk_##type##_num(a) != 0)) \ - M_ASN1_I2D_len_SEQUENCE_type(type,a,f); - -# define M_ASN1_I2D_len_IMP_SET(a,f,x) \ - ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET); - -# define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \ - ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ - V_ASN1_CONTEXT_SPECIFIC,IS_SET); - -# define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ - IS_SET); - -# define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \ - if ((a != NULL) && (sk_##type##_num(a) != 0)) \ - ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ - V_ASN1_CONTEXT_SPECIFIC,IS_SET); - -# define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \ - ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ - IS_SEQUENCE); - -# define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ - IS_SEQUENCE); - -# define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \ - if ((a != NULL) && (sk_##type##_num(a) != 0)) \ - ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ - V_ASN1_CONTEXT_SPECIFIC, \ - IS_SEQUENCE); - -# define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \ - if (a != NULL)\ - { \ - v=f(a,NULL); \ - ret+=ASN1_object_size(1,v,mtag); \ - } - -# define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \ - if ((a != NULL) && (sk_num(a) != 0))\ - { \ - v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ - ret+=ASN1_object_size(1,v,mtag); \ - } - -# define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ - if ((a != NULL) && (sk_num(a) != 0))\ - { \ - v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \ - IS_SEQUENCE); \ - ret+=ASN1_object_size(1,v,mtag); \ - } - -# define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ - if ((a != NULL) && (sk_##type##_num(a) != 0))\ - { \ - v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \ - V_ASN1_UNIVERSAL, \ - IS_SEQUENCE); \ - ret+=ASN1_object_size(1,v,mtag); \ - } - -/* Put Macros */ -# define M_ASN1_I2D_put(a,f) f(a,&p) - -# define M_ASN1_I2D_put_IMP_opt(a,f,t) \ - if (a != NULL) \ - { \ - unsigned char *q=p; \ - f(a,&p); \ - *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\ - } - -# define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\ - V_ASN1_UNIVERSAL,IS_SET) -# define M_ASN1_I2D_put_SET_type(type,a,f) \ - i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET) -# define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ - V_ASN1_CONTEXT_SPECIFIC,IS_SET) -# define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \ - i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET) -# define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ - V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE) - -# define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\ - V_ASN1_UNIVERSAL,IS_SEQUENCE) - -# define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \ - i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ - IS_SEQUENCE) - -# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - M_ASN1_I2D_put_SEQUENCE(a,f); - -# define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ - IS_SET); } - -# define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \ - if ((a != NULL) && (sk_##type##_num(a) != 0)) \ - { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ - V_ASN1_CONTEXT_SPECIFIC, \ - IS_SET); } - -# define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ - IS_SEQUENCE); } - -# define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \ - if ((a != NULL) && (sk_##type##_num(a) != 0)) \ - { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ - V_ASN1_CONTEXT_SPECIFIC, \ - IS_SEQUENCE); } - -# define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \ - if (a != NULL) \ - { \ - ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \ - f(a,&p); \ - } - -# define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - { \ - ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ - i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ - } - -# define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ - if ((a != NULL) && (sk_num(a) != 0)) \ - { \ - ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ - i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \ - } - -# define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ - if ((a != NULL) && (sk_##type##_num(a) != 0)) \ - { \ - ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ - i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \ - IS_SEQUENCE); \ - } - -# define M_ASN1_I2D_seq_total() \ - r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \ - if (pp == NULL) return(r); \ - p= *pp; \ - ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) - -# define M_ASN1_I2D_INF_seq_start(tag,ctx) \ - *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \ - *(p++)=0x80 - -# define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00 - -# define M_ASN1_I2D_finish() *pp=p; \ - return(r); - -int asn1_GetSequence(ASN1_const_CTX *c, long *length); -void asn1_add_error(const unsigned char *address, int offset); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/asn1t.h b/Sources/COpenSSL/asn1t.h deleted file mode 100644 index ea951808..00000000 --- a/Sources/COpenSSL/asn1t.h +++ /dev/null @@ -1,973 +0,0 @@ -/* asn1t.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef HEADER_ASN1T_H -# define HEADER_ASN1T_H - -# include -# include "e_os2.h" -# include "asn1.h" - -# ifdef OPENSSL_BUILD_SHLIBCRYPTO -# undef OPENSSL_EXTERN -# define OPENSSL_EXTERN OPENSSL_EXPORT -# endif - -/* ASN1 template defines, structures and functions */ - -#ifdef __cplusplus -extern "C" { -#endif - -# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION - -/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ -# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) - -/* Macros for start and end of ASN1_ITEM definition */ - -# define ASN1_ITEM_start(itname) \ - OPENSSL_GLOBAL const ASN1_ITEM itname##_it = { - -# define ASN1_ITEM_end(itname) \ - }; - -# else - -/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ -# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr())) - -/* Macros for start and end of ASN1_ITEM definition */ - -# define ASN1_ITEM_start(itname) \ - const ASN1_ITEM * itname##_it(void) \ - { \ - static const ASN1_ITEM local_it = { - -# define ASN1_ITEM_end(itname) \ - }; \ - return &local_it; \ - } - -# endif - -/* Macros to aid ASN1 template writing */ - -# define ASN1_ITEM_TEMPLATE(tname) \ - static const ASN1_TEMPLATE tname##_item_tt - -# define ASN1_ITEM_TEMPLATE_END(tname) \ - ;\ - ASN1_ITEM_start(tname) \ - ASN1_ITYPE_PRIMITIVE,\ - -1,\ - &tname##_item_tt,\ - 0,\ - NULL,\ - 0,\ - #tname \ - ASN1_ITEM_end(tname) - -/* This is a ASN1 type which just embeds a template */ - -/*- - * This pair helps declare a SEQUENCE. We can do: - * - * ASN1_SEQUENCE(stname) = { - * ... SEQUENCE components ... - * } ASN1_SEQUENCE_END(stname) - * - * This will produce an ASN1_ITEM called stname_it - * for a structure called stname. - * - * If you want the same structure but a different - * name then use: - * - * ASN1_SEQUENCE(itname) = { - * ... SEQUENCE components ... - * } ASN1_SEQUENCE_END_name(stname, itname) - * - * This will create an item called itname_it using - * a structure called stname. - */ - -# define ASN1_SEQUENCE(tname) \ - static const ASN1_TEMPLATE tname##_seq_tt[] - -# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) - -# define ASN1_SEQUENCE_END_name(stname, tname) \ - ;\ - ASN1_ITEM_start(tname) \ - ASN1_ITYPE_SEQUENCE,\ - V_ASN1_SEQUENCE,\ - tname##_seq_tt,\ - sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ - NULL,\ - sizeof(stname),\ - #stname \ - ASN1_ITEM_end(tname) - -# define ASN1_NDEF_SEQUENCE(tname) \ - ASN1_SEQUENCE(tname) - -# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ - ASN1_SEQUENCE_cb(tname, cb) - -# define ASN1_SEQUENCE_cb(tname, cb) \ - static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ - ASN1_SEQUENCE(tname) - -# define ASN1_BROKEN_SEQUENCE(tname) \ - static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ - ASN1_SEQUENCE(tname) - -# define ASN1_SEQUENCE_ref(tname, cb, lck) \ - static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ - ASN1_SEQUENCE(tname) - -# define ASN1_SEQUENCE_enc(tname, enc, cb) \ - static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ - ASN1_SEQUENCE(tname) - -# define ASN1_NDEF_SEQUENCE_END(tname) \ - ;\ - ASN1_ITEM_start(tname) \ - ASN1_ITYPE_NDEF_SEQUENCE,\ - V_ASN1_SEQUENCE,\ - tname##_seq_tt,\ - sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ - NULL,\ - sizeof(tname),\ - #tname \ - ASN1_ITEM_end(tname) - -# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) - -# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) - -# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) - -# define ASN1_SEQUENCE_END_ref(stname, tname) \ - ;\ - ASN1_ITEM_start(tname) \ - ASN1_ITYPE_SEQUENCE,\ - V_ASN1_SEQUENCE,\ - tname##_seq_tt,\ - sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ - &tname##_aux,\ - sizeof(stname),\ - #stname \ - ASN1_ITEM_end(tname) - -# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ - ;\ - ASN1_ITEM_start(tname) \ - ASN1_ITYPE_NDEF_SEQUENCE,\ - V_ASN1_SEQUENCE,\ - tname##_seq_tt,\ - sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ - &tname##_aux,\ - sizeof(stname),\ - #stname \ - ASN1_ITEM_end(tname) - -/*- - * This pair helps declare a CHOICE type. We can do: - * - * ASN1_CHOICE(chname) = { - * ... CHOICE options ... - * ASN1_CHOICE_END(chname) - * - * This will produce an ASN1_ITEM called chname_it - * for a structure called chname. The structure - * definition must look like this: - * typedef struct { - * int type; - * union { - * ASN1_SOMETHING *opt1; - * ASN1_SOMEOTHER *opt2; - * } value; - * } chname; - * - * the name of the selector must be 'type'. - * to use an alternative selector name use the - * ASN1_CHOICE_END_selector() version. - */ - -# define ASN1_CHOICE(tname) \ - static const ASN1_TEMPLATE tname##_ch_tt[] - -# define ASN1_CHOICE_cb(tname, cb) \ - static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ - ASN1_CHOICE(tname) - -# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) - -# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) - -# define ASN1_CHOICE_END_selector(stname, tname, selname) \ - ;\ - ASN1_ITEM_start(tname) \ - ASN1_ITYPE_CHOICE,\ - offsetof(stname,selname) ,\ - tname##_ch_tt,\ - sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ - NULL,\ - sizeof(stname),\ - #stname \ - ASN1_ITEM_end(tname) - -# define ASN1_CHOICE_END_cb(stname, tname, selname) \ - ;\ - ASN1_ITEM_start(tname) \ - ASN1_ITYPE_CHOICE,\ - offsetof(stname,selname) ,\ - tname##_ch_tt,\ - sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ - &tname##_aux,\ - sizeof(stname),\ - #stname \ - ASN1_ITEM_end(tname) - -/* This helps with the template wrapper form of ASN1_ITEM */ - -# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ - (flags), (tag), 0,\ - #name, ASN1_ITEM_ref(type) } - -/* These help with SEQUENCE or CHOICE components */ - -/* used to declare other types */ - -# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ - (flags), (tag), offsetof(stname, field),\ - #field, ASN1_ITEM_ref(type) } - -/* used when the structure is combined with the parent */ - -# define ASN1_EX_COMBINE(flags, tag, type) { \ - (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } - -/* implicit and explicit helper macros */ - -# define ASN1_IMP_EX(stname, field, type, tag, ex) \ - ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) - -# define ASN1_EXP_EX(stname, field, type, tag, ex) \ - ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) - -/* Any defined by macros: the field used is in the table itself */ - -# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION -# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } -# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } -# else -# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } -# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } -# endif -/* Plain simple type */ -# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) - -/* OPTIONAL simple type */ -# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) - -/* IMPLICIT tagged simple type */ -# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) - -/* IMPLICIT tagged OPTIONAL simple type */ -# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) - -/* Same as above but EXPLICIT */ - -# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) -# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) - -/* SEQUENCE OF type */ -# define ASN1_SEQUENCE_OF(stname, field, type) \ - ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) - -/* OPTIONAL SEQUENCE OF */ -# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ - ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) - -/* Same as above but for SET OF */ - -# define ASN1_SET_OF(stname, field, type) \ - ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) - -# define ASN1_SET_OF_OPT(stname, field, type) \ - ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) - -/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ - -# define ASN1_IMP_SET_OF(stname, field, type, tag) \ - ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) - -# define ASN1_EXP_SET_OF(stname, field, type, tag) \ - ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) - -# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ - ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) - -# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ - ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) - -# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ - ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) - -# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ - ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) - -# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ - ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) - -# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ - ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) - -/* EXPLICIT using indefinite length constructed form */ -# define ASN1_NDEF_EXP(stname, field, type, tag) \ - ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) - -/* EXPLICIT OPTIONAL using indefinite length constructed form */ -# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ - ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) - -/* Macros for the ASN1_ADB structure */ - -# define ASN1_ADB(name) \ - static const ASN1_ADB_TABLE name##_adbtbl[] - -# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION - -# define ASN1_ADB_END(name, flags, field, app_table, def, none) \ - ;\ - static const ASN1_ADB name##_adb = {\ - flags,\ - offsetof(name, field),\ - app_table,\ - name##_adbtbl,\ - sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ - def,\ - none\ - } - -# else - -# define ASN1_ADB_END(name, flags, field, app_table, def, none) \ - ;\ - static const ASN1_ITEM *name##_adb(void) \ - { \ - static const ASN1_ADB internal_adb = \ - {\ - flags,\ - offsetof(name, field),\ - app_table,\ - name##_adbtbl,\ - sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ - def,\ - none\ - }; \ - return (const ASN1_ITEM *) &internal_adb; \ - } \ - void dummy_function(void) - -# endif - -# define ADB_ENTRY(val, template) {val, template} - -# define ASN1_ADB_TEMPLATE(name) \ - static const ASN1_TEMPLATE name##_tt - -/* - * This is the ASN1 template structure that defines a wrapper round the - * actual type. It determines the actual position of the field in the value - * structure, various flags such as OPTIONAL and the field name. - */ - -struct ASN1_TEMPLATE_st { - unsigned long flags; /* Various flags */ - long tag; /* tag, not used if no tagging */ - unsigned long offset; /* Offset of this field in structure */ -# ifndef NO_ASN1_FIELD_NAMES - const char *field_name; /* Field name */ -# endif - ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ -}; - -/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ - -# define ASN1_TEMPLATE_item(t) (t->item_ptr) -# define ASN1_TEMPLATE_adb(t) (t->item_ptr) - -typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; -typedef struct ASN1_ADB_st ASN1_ADB; - -struct ASN1_ADB_st { - unsigned long flags; /* Various flags */ - unsigned long offset; /* Offset of selector field */ - STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */ - const ASN1_ADB_TABLE *tbl; /* Table of possible types */ - long tblcount; /* Number of entries in tbl */ - const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ - const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ -}; - -struct ASN1_ADB_TABLE_st { - long value; /* NID for an object or value for an int */ - const ASN1_TEMPLATE tt; /* item for this value */ -}; - -/* template flags */ - -/* Field is optional */ -# define ASN1_TFLG_OPTIONAL (0x1) - -/* Field is a SET OF */ -# define ASN1_TFLG_SET_OF (0x1 << 1) - -/* Field is a SEQUENCE OF */ -# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) - -/* - * Special case: this refers to a SET OF that will be sorted into DER order - * when encoded *and* the corresponding STACK will be modified to match the - * new order. - */ -# define ASN1_TFLG_SET_ORDER (0x3 << 1) - -/* Mask for SET OF or SEQUENCE OF */ -# define ASN1_TFLG_SK_MASK (0x3 << 1) - -/* - * These flags mean the tag should be taken from the tag field. If EXPLICIT - * then the underlying type is used for the inner tag. - */ - -/* IMPLICIT tagging */ -# define ASN1_TFLG_IMPTAG (0x1 << 3) - -/* EXPLICIT tagging, inner tag from underlying type */ -# define ASN1_TFLG_EXPTAG (0x2 << 3) - -# define ASN1_TFLG_TAG_MASK (0x3 << 3) - -/* context specific IMPLICIT */ -# define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT - -/* context specific EXPLICIT */ -# define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT - -/* - * If tagging is in force these determine the type of tag to use. Otherwise - * the tag is determined by the underlying type. These values reflect the - * actual octet format. - */ - -/* Universal tag */ -# define ASN1_TFLG_UNIVERSAL (0x0<<6) -/* Application tag */ -# define ASN1_TFLG_APPLICATION (0x1<<6) -/* Context specific tag */ -# define ASN1_TFLG_CONTEXT (0x2<<6) -/* Private tag */ -# define ASN1_TFLG_PRIVATE (0x3<<6) - -# define ASN1_TFLG_TAG_CLASS (0x3<<6) - -/* - * These are for ANY DEFINED BY type. In this case the 'item' field points to - * an ASN1_ADB structure which contains a table of values to decode the - * relevant type - */ - -# define ASN1_TFLG_ADB_MASK (0x3<<8) - -# define ASN1_TFLG_ADB_OID (0x1<<8) - -# define ASN1_TFLG_ADB_INT (0x1<<9) - -/* - * This flag means a parent structure is passed instead of the field: this is - * useful is a SEQUENCE is being combined with a CHOICE for example. Since - * this means the structure and item name will differ we need to use the - * ASN1_CHOICE_END_name() macro for example. - */ - -# define ASN1_TFLG_COMBINE (0x1<<10) - -/* - * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes - * indefinite length constructed encoding to be used if required. - */ - -# define ASN1_TFLG_NDEF (0x1<<11) - -/* This is the actual ASN1 item itself */ - -struct ASN1_ITEM_st { - char itype; /* The item type, primitive, SEQUENCE, CHOICE - * or extern */ - long utype; /* underlying type */ - const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains - * the contents */ - long tcount; /* Number of templates if SEQUENCE or CHOICE */ - const void *funcs; /* functions that handle this type */ - long size; /* Structure size (usually) */ -# ifndef NO_ASN1_FIELD_NAMES - const char *sname; /* Structure name */ -# endif -}; - -/*- - * These are values for the itype field and - * determine how the type is interpreted. - * - * For PRIMITIVE types the underlying type - * determines the behaviour if items is NULL. - * - * Otherwise templates must contain a single - * template and the type is treated in the - * same way as the type specified in the template. - * - * For SEQUENCE types the templates field points - * to the members, the size field is the - * structure size. - * - * For CHOICE types the templates field points - * to each possible member (typically a union) - * and the 'size' field is the offset of the - * selector. - * - * The 'funcs' field is used for application - * specific functions. - * - * For COMPAT types the funcs field gives a - * set of functions that handle this type, this - * supports the old d2i, i2d convention. - * - * The EXTERN type uses a new style d2i/i2d. - * The new style should be used where possible - * because it avoids things like the d2i IMPLICIT - * hack. - * - * MSTRING is a multiple string type, it is used - * for a CHOICE of character strings where the - * actual strings all occupy an ASN1_STRING - * structure. In this case the 'utype' field - * has a special meaning, it is used as a mask - * of acceptable types using the B_ASN1 constants. - * - * NDEF_SEQUENCE is the same as SEQUENCE except - * that it will use indefinite length constructed - * encoding if requested. - * - */ - -# define ASN1_ITYPE_PRIMITIVE 0x0 - -# define ASN1_ITYPE_SEQUENCE 0x1 - -# define ASN1_ITYPE_CHOICE 0x2 - -# define ASN1_ITYPE_COMPAT 0x3 - -# define ASN1_ITYPE_EXTERN 0x4 - -# define ASN1_ITYPE_MSTRING 0x5 - -# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 - -/* - * Cache for ASN1 tag and length, so we don't keep re-reading it for things - * like CHOICE - */ - -struct ASN1_TLC_st { - char valid; /* Values below are valid */ - int ret; /* return value */ - long plen; /* length */ - int ptag; /* class value */ - int pclass; /* class value */ - int hdrlen; /* header length */ -}; - -/* Typedefs for ASN1 function pointers */ - -typedef ASN1_VALUE *ASN1_new_func(void); -typedef void ASN1_free_func(ASN1_VALUE *a); -typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in, - long length); -typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in); - -typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, char opt, - ASN1_TLC *ctx); - -typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass); -typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); -typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); - -typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, - int indent, const char *fname, - const ASN1_PCTX *pctx); - -typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, - int *putype, const ASN1_ITEM *it); -typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, - int len, int utype, char *free_cont, - const ASN1_ITEM *it); -typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, - const ASN1_ITEM *it, int indent, - const ASN1_PCTX *pctx); - -typedef struct ASN1_COMPAT_FUNCS_st { - ASN1_new_func *asn1_new; - ASN1_free_func *asn1_free; - ASN1_d2i_func *asn1_d2i; - ASN1_i2d_func *asn1_i2d; -} ASN1_COMPAT_FUNCS; - -typedef struct ASN1_EXTERN_FUNCS_st { - void *app_data; - ASN1_ex_new_func *asn1_ex_new; - ASN1_ex_free_func *asn1_ex_free; - ASN1_ex_free_func *asn1_ex_clear; - ASN1_ex_d2i *asn1_ex_d2i; - ASN1_ex_i2d *asn1_ex_i2d; - ASN1_ex_print_func *asn1_ex_print; -} ASN1_EXTERN_FUNCS; - -typedef struct ASN1_PRIMITIVE_FUNCS_st { - void *app_data; - unsigned long flags; - ASN1_ex_new_func *prim_new; - ASN1_ex_free_func *prim_free; - ASN1_ex_free_func *prim_clear; - ASN1_primitive_c2i *prim_c2i; - ASN1_primitive_i2c *prim_i2c; - ASN1_primitive_print *prim_print; -} ASN1_PRIMITIVE_FUNCS; - -/* - * This is the ASN1_AUX structure: it handles various miscellaneous - * requirements. For example the use of reference counts and an informational - * callback. The "informational callback" is called at various points during - * the ASN1 encoding and decoding. It can be used to provide minor - * customisation of the structures used. This is most useful where the - * supplied routines *almost* do the right thing but need some extra help at - * a few points. If the callback returns zero then it is assumed a fatal - * error has occurred and the main operation should be abandoned. If major - * changes in the default behaviour are required then an external type is - * more appropriate. - */ - -typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, - void *exarg); - -typedef struct ASN1_AUX_st { - void *app_data; - int flags; - int ref_offset; /* Offset of reference value */ - int ref_lock; /* Lock type to use */ - ASN1_aux_cb *asn1_cb; - int enc_offset; /* Offset of ASN1_ENCODING structure */ -} ASN1_AUX; - -/* For print related callbacks exarg points to this structure */ -typedef struct ASN1_PRINT_ARG_st { - BIO *out; - int indent; - const ASN1_PCTX *pctx; -} ASN1_PRINT_ARG; - -/* For streaming related callbacks exarg points to this structure */ -typedef struct ASN1_STREAM_ARG_st { - /* BIO to stream through */ - BIO *out; - /* BIO with filters appended */ - BIO *ndef_bio; - /* Streaming I/O boundary */ - unsigned char **boundary; -} ASN1_STREAM_ARG; - -/* Flags in ASN1_AUX */ - -/* Use a reference count */ -# define ASN1_AFLG_REFCOUNT 1 -/* Save the encoding of structure (useful for signatures) */ -# define ASN1_AFLG_ENCODING 2 -/* The Sequence length is invalid */ -# define ASN1_AFLG_BROKEN 4 - -/* operation values for asn1_cb */ - -# define ASN1_OP_NEW_PRE 0 -# define ASN1_OP_NEW_POST 1 -# define ASN1_OP_FREE_PRE 2 -# define ASN1_OP_FREE_POST 3 -# define ASN1_OP_D2I_PRE 4 -# define ASN1_OP_D2I_POST 5 -# define ASN1_OP_I2D_PRE 6 -# define ASN1_OP_I2D_POST 7 -# define ASN1_OP_PRINT_PRE 8 -# define ASN1_OP_PRINT_POST 9 -# define ASN1_OP_STREAM_PRE 10 -# define ASN1_OP_STREAM_POST 11 -# define ASN1_OP_DETACHED_PRE 12 -# define ASN1_OP_DETACHED_POST 13 - -/* Macro to implement a primitive type */ -# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) -# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ - ASN1_ITEM_start(itname) \ - ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ - ASN1_ITEM_end(itname) - -/* Macro to implement a multi string type */ -# define IMPLEMENT_ASN1_MSTRING(itname, mask) \ - ASN1_ITEM_start(itname) \ - ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ - ASN1_ITEM_end(itname) - -/* Macro to implement an ASN1_ITEM in terms of old style funcs */ - -# define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE) - -# define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \ - static const ASN1_COMPAT_FUNCS sname##_ff = { \ - (ASN1_new_func *)sname##_new, \ - (ASN1_free_func *)sname##_free, \ - (ASN1_d2i_func *)d2i_##sname, \ - (ASN1_i2d_func *)i2d_##sname, \ - }; \ - ASN1_ITEM_start(sname) \ - ASN1_ITYPE_COMPAT, \ - tag, \ - NULL, \ - 0, \ - &sname##_ff, \ - 0, \ - #sname \ - ASN1_ITEM_end(sname) - -# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ - ASN1_ITEM_start(sname) \ - ASN1_ITYPE_EXTERN, \ - tag, \ - NULL, \ - 0, \ - &fptrs, \ - 0, \ - #sname \ - ASN1_ITEM_end(sname) - -/* Macro to implement standard functions in terms of ASN1_ITEM structures */ - -# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) - -# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) - -# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ - IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) - -# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ - IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) - -# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ - IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) - -# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ - pre stname *fname##_new(void) \ - { \ - return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ - } \ - pre void fname##_free(stname *a) \ - { \ - ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ - } - -# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ - stname *fname##_new(void) \ - { \ - return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ - } \ - void fname##_free(stname *a) \ - { \ - ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ - } - -# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ - IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ - IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) - -# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ - stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ - { \ - return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ - } \ - int i2d_##fname(stname *a, unsigned char **out) \ - { \ - return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ - } - -# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ - int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ - { \ - return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ - } - -/* - * This includes evil casts to remove const: they will go away when full ASN1 - * constification is done. - */ -# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ - stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ - { \ - return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ - } \ - int i2d_##fname(const stname *a, unsigned char **out) \ - { \ - return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ - } - -# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ - stname * stname##_dup(stname *x) \ - { \ - return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ - } - -# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ - IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) - -# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ - int fname##_print_ctx(BIO *out, stname *x, int indent, \ - const ASN1_PCTX *pctx) \ - { \ - return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ - ASN1_ITEM_rptr(itname), pctx); \ - } - -# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ - IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) - -# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ - IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ - IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) - -/* external definitions for primitive types */ - -DECLARE_ASN1_ITEM(ASN1_BOOLEAN) -DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) -DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) -DECLARE_ASN1_ITEM(ASN1_SEQUENCE) -DECLARE_ASN1_ITEM(CBIGNUM) -DECLARE_ASN1_ITEM(BIGNUM) -DECLARE_ASN1_ITEM(LONG) -DECLARE_ASN1_ITEM(ZLONG) - -DECLARE_STACK_OF(ASN1_VALUE) - -/* Functions used internally by the ASN1 code */ - -int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); -void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); -int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); -int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); - -void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); -int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_TEMPLATE *tt); -int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, char opt, - ASN1_TLC *ctx); - -int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass); -int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_TEMPLATE *tt); -void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); - -int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, - const ASN1_ITEM *it); -int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, char *free_cont, const ASN1_ITEM *it); - -int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); -int asn1_set_choice_selector(ASN1_VALUE **pval, int value, - const ASN1_ITEM *it); - -ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); - -const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, - int nullerr); - -int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); - -void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); -void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); -int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, - const ASN1_ITEM *it); -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/asn_.c b/Sources/COpenSSL/asn_.c deleted file mode 100644 index ff174b05..00000000 --- a/Sources/COpenSSL/asn_.c +++ /dev/null @@ -1,1338 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* asn_mime.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include -#include -#include "cryptlib.h" -#include "rand.h" -#include "x509.h" -#include "asn1.h" -#include "asn1t.h" -#include "asn1_locl.h" - -/* - * Generalised MIME like utilities for streaming ASN1. Although many have a - * PKCS7/CMS like flavour others are more general purpose. - */ - -/* - * MIME format structures Note that all are translated to lower case apart - * from parameter values. Quotes are stripped off - */ - -typedef struct { - char *param_name; /* Param name e.g. "micalg" */ - char *param_value; /* Param value e.g. "sha1" */ -} MIME_PARAM; - -DECLARE_STACK_OF(MIME_PARAM) -IMPLEMENT_STACK_OF(MIME_PARAM) - -typedef struct { - char *name; /* Name of line e.g. "content-type" */ - char *value; /* Value of line e.g. "text/plain" */ - STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */ -} MIME_HEADER; - -DECLARE_STACK_OF(MIME_HEADER) -IMPLEMENT_STACK_OF(MIME_HEADER) - -static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, - const ASN1_ITEM *it); -static char *strip_ends(char *name); -static char *strip_start(char *name); -static char *strip_end(char *name); -static MIME_HEADER *mime_hdr_new(char *name, char *value); -static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value); -static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio); -static int mime_hdr_cmp(const MIME_HEADER *const *a, - const MIME_HEADER *const *b); -static int mime_param_cmp(const MIME_PARAM *const *a, - const MIME_PARAM *const *b); -static void mime_param_free(MIME_PARAM *param); -static int mime_bound_check(char *line, int linelen, char *bound, int blen); -static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret); -static int strip_eol(char *linebuf, int *plen); -static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name); -static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); -static void mime_hdr_free(MIME_HEADER *hdr); - -#define MAX_SMLEN 1024 -#define mime_debug(x) /* x */ - -/* Output an ASN1 structure in BER format streaming if necessary */ - -int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, - const ASN1_ITEM *it) -{ - /* If streaming create stream BIO and copy all content through it */ - if (flags & SMIME_STREAM) { - BIO *bio, *tbio; - bio = BIO_new_NDEF(out, val, it); - if (!bio) { - ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE); - return 0; - } - SMIME_crlf_copy(in, bio, flags); - (void)BIO_flush(bio); - /* Free up successive BIOs until we hit the old output BIO */ - do { - tbio = BIO_pop(bio); - BIO_free(bio); - bio = tbio; - } while (bio != out); - } - /* - * else just write out ASN1 structure which will have all content stored - * internally - */ - else - ASN1_item_i2d_bio(it, out, val); - return 1; -} - -/* Base 64 read and write of ASN1 structure */ - -static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, - const ASN1_ITEM *it) -{ - BIO *b64; - int r; - b64 = BIO_new(BIO_f_base64()); - if (!b64) { - ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE); - return 0; - } - /* - * prepend the b64 BIO so all data is base64 encoded. - */ - out = BIO_push(b64, out); - r = i2d_ASN1_bio_stream(out, val, in, flags, it); - (void)BIO_flush(out); - BIO_pop(out); - BIO_free(b64); - return r; -} - -/* Streaming ASN1 PEM write */ - -int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, - const char *hdr, const ASN1_ITEM *it) -{ - int r; - BIO_printf(out, "-----BEGIN %s-----\n", hdr); - r = B64_write_ASN1(out, val, in, flags, it); - BIO_printf(out, "-----END %s-----\n", hdr); - return r; -} - -static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) -{ - BIO *b64; - ASN1_VALUE *val; - if (!(b64 = BIO_new(BIO_f_base64()))) { - ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE); - return 0; - } - bio = BIO_push(b64, bio); - val = ASN1_item_d2i_bio(it, bio, NULL); - if (!val) - ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR); - (void)BIO_flush(bio); - bio = BIO_pop(bio); - BIO_free(b64); - return val; -} - -/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */ - -static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) -{ - const EVP_MD *md; - int i, have_unknown = 0, write_comma, ret = 0, md_nid; - have_unknown = 0; - write_comma = 0; - for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) { - if (write_comma) - BIO_write(out, ",", 1); - write_comma = 1; - md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); - md = EVP_get_digestbynid(md_nid); - if (md && md->md_ctrl) { - int rv; - char *micstr; - rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr); - if (rv > 0) { - BIO_puts(out, micstr); - OPENSSL_free(micstr); - continue; - } - if (rv != -2) - goto err; - } - switch (md_nid) { - case NID_sha1: - BIO_puts(out, "sha1"); - break; - - case NID_md5: - BIO_puts(out, "md5"); - break; - - case NID_sha256: - BIO_puts(out, "sha-256"); - break; - - case NID_sha384: - BIO_puts(out, "sha-384"); - break; - - case NID_sha512: - BIO_puts(out, "sha-512"); - break; - - case NID_id_GostR3411_94: - BIO_puts(out, "gostr3411-94"); - goto err; - break; - - default: - if (have_unknown) - write_comma = 0; - else { - BIO_puts(out, "unknown"); - have_unknown = 1; - } - break; - - } - } - - ret = 1; - err: - - return ret; - -} - -/* SMIME sender */ - -int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, - int ctype_nid, int econt_nid, - STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it) -{ - char bound[33], c; - int i; - const char *mime_prefix, *mime_eol, *cname = "smime.p7m"; - const char *msg_type = NULL; - if (flags & SMIME_OLDMIME) - mime_prefix = "application/x-pkcs7-"; - else - mime_prefix = "application/pkcs7-"; - - if (flags & SMIME_CRLFEOL) - mime_eol = "\r\n"; - else - mime_eol = "\n"; - if ((flags & SMIME_DETACHED) && data) { - /* We want multipart/signed */ - /* Generate a random boundary */ - if (RAND_bytes((unsigned char *)bound, 32) <= 0) - return 0; - for (i = 0; i < 32; i++) { - c = bound[i] & 0xf; - if (c < 10) - c += '0'; - else - c += 'A' - 10; - bound[i] = c; - } - bound[32] = 0; - BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); - BIO_printf(bio, "Content-Type: multipart/signed;"); - BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix); - BIO_puts(bio, " micalg=\""); - asn1_write_micalg(bio, mdalgs); - BIO_printf(bio, "\"; boundary=\"----%s\"%s%s", - bound, mime_eol, mime_eol); - BIO_printf(bio, "This is an S/MIME signed message%s%s", - mime_eol, mime_eol); - /* Now write out the first part */ - BIO_printf(bio, "------%s%s", bound, mime_eol); - if (!asn1_output_data(bio, data, val, flags, it)) - return 0; - BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); - - /* Headers for signature */ - - BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix); - BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol); - BIO_printf(bio, "Content-Transfer-Encoding: base64%s", mime_eol); - BIO_printf(bio, "Content-Disposition: attachment;"); - BIO_printf(bio, " filename=\"smime.p7s\"%s%s", mime_eol, mime_eol); - B64_write_ASN1(bio, val, NULL, 0, it); - BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound, - mime_eol, mime_eol); - return 1; - } - - /* Determine smime-type header */ - - if (ctype_nid == NID_pkcs7_enveloped) - msg_type = "enveloped-data"; - else if (ctype_nid == NID_pkcs7_signed) { - if (econt_nid == NID_id_smime_ct_receipt) - msg_type = "signed-receipt"; - else if (sk_X509_ALGOR_num(mdalgs) >= 0) - msg_type = "signed-data"; - else - msg_type = "certs-only"; - } else if (ctype_nid == NID_id_smime_ct_compressedData) { - msg_type = "compressed-data"; - cname = "smime.p7z"; - } - /* MIME headers */ - BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); - BIO_printf(bio, "Content-Disposition: attachment;"); - BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol); - BIO_printf(bio, "Content-Type: %smime;", mime_prefix); - if (msg_type) - BIO_printf(bio, " smime-type=%s;", msg_type); - BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol); - BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s", - mime_eol, mime_eol); - if (!B64_write_ASN1(bio, val, data, flags, it)) - return 0; - BIO_printf(bio, "%s", mime_eol); - return 1; -} - -/* Handle output of ASN1 data */ - -static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, - const ASN1_ITEM *it) -{ - BIO *tmpbio; - const ASN1_AUX *aux = it->funcs; - ASN1_STREAM_ARG sarg; - int rv = 1; - - /* - * If data is not deteched or resigning then the output BIO is already - * set up to finalise when it is written through. - */ - if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) { - SMIME_crlf_copy(data, out, flags); - return 1; - } - - if (!aux || !aux->asn1_cb) { - ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED); - return 0; - } - - sarg.out = out; - sarg.ndef_bio = NULL; - sarg.boundary = NULL; - - /* Let ASN1 code prepend any needed BIOs */ - - if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0) - return 0; - - /* Copy data across, passing through filter BIOs for processing */ - SMIME_crlf_copy(data, sarg.ndef_bio, flags); - - /* Finalize structure */ - if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0) - rv = 0; - - /* Now remove any digests prepended to the BIO */ - - while (sarg.ndef_bio != out) { - tmpbio = BIO_pop(sarg.ndef_bio); - BIO_free(sarg.ndef_bio); - sarg.ndef_bio = tmpbio; - } - - return rv; - -} - -/* - * SMIME reader: handle multipart/signed and opaque signing. in multipart - * case the content is placed in a memory BIO pointed to by "bcont". In - * opaque this is set to NULL - */ - -ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) -{ - BIO *asnin; - STACK_OF(MIME_HEADER) *headers = NULL; - STACK_OF(BIO) *parts = NULL; - MIME_HEADER *hdr; - MIME_PARAM *prm; - ASN1_VALUE *val; - int ret; - - if (bcont) - *bcont = NULL; - - if (!(headers = mime_parse_hdr(bio))) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR); - return NULL; - } - - if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE); - return NULL; - } - - /* Handle multipart/signed */ - - if (!strcmp(hdr->value, "multipart/signed")) { - /* Split into two parts */ - prm = mime_param_find(hdr, "boundary"); - if (!prm || !prm->param_value) { - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY); - return NULL; - } - ret = multi_split(bio, prm->param_value, &parts); - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - if (!ret || (sk_BIO_num(parts) != 2)) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE); - sk_BIO_pop_free(parts, BIO_vfree); - return NULL; - } - - /* Parse the signature piece */ - asnin = sk_BIO_value(parts, 1); - - if (!(headers = mime_parse_hdr(asnin))) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR); - sk_BIO_pop_free(parts, BIO_vfree); - return NULL; - } - - /* Get content type */ - - if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE); - sk_BIO_pop_free(parts, BIO_vfree); - return NULL; - } - - if (strcmp(hdr->value, "application/x-pkcs7-signature") && - strcmp(hdr->value, "application/pkcs7-signature")) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE); - ERR_add_error_data(2, "type: ", hdr->value); - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - sk_BIO_pop_free(parts, BIO_vfree); - return NULL; - } - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - /* Read in ASN1 */ - if (!(val = b64_read_asn1(asnin, it))) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR); - sk_BIO_pop_free(parts, BIO_vfree); - return NULL; - } - - if (bcont) { - *bcont = sk_BIO_value(parts, 0); - BIO_free(asnin); - sk_BIO_free(parts); - } else - sk_BIO_pop_free(parts, BIO_vfree); - return val; - } - - /* OK, if not multipart/signed try opaque signature */ - - if (strcmp(hdr->value, "application/x-pkcs7-mime") && - strcmp(hdr->value, "application/pkcs7-mime")) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE); - ERR_add_error_data(2, "type: ", hdr->value); - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - return NULL; - } - - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - - if (!(val = b64_read_asn1(bio, it))) { - ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR); - return NULL; - } - return val; - -} - -/* Copy text from one BIO to another making the output CRLF at EOL */ -int SMIME_crlf_copy(BIO *in, BIO *out, int flags) -{ - BIO *bf; - char eol; - int len; - char linebuf[MAX_SMLEN]; - /* - * Buffer output so we don't write one line at a time. This is useful - * when streaming as we don't end up with one OCTET STRING per line. - */ - bf = BIO_new(BIO_f_buffer()); - if (!bf) - return 0; - out = BIO_push(bf, out); - if (flags & SMIME_BINARY) { - while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0) - BIO_write(out, linebuf, len); - } else { - if (flags & SMIME_TEXT) - BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); - while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) { - eol = strip_eol(linebuf, &len); - if (len) - BIO_write(out, linebuf, len); - if (eol) - BIO_write(out, "\r\n", 2); - } - } - (void)BIO_flush(out); - BIO_pop(out); - BIO_free(bf); - return 1; -} - -/* Strip off headers if they are text/plain */ -int SMIME_text(BIO *in, BIO *out) -{ - char iobuf[4096]; - int len; - STACK_OF(MIME_HEADER) *headers; - MIME_HEADER *hdr; - - if (!(headers = mime_parse_hdr(in))) { - ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR); - return 0; - } - if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { - ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE); - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - return 0; - } - if (strcmp(hdr->value, "text/plain")) { - ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE); - ERR_add_error_data(2, "type: ", hdr->value); - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - return 0; - } - sk_MIME_HEADER_pop_free(headers, mime_hdr_free); - while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) - BIO_write(out, iobuf, len); - if (len < 0) - return 0; - return 1; -} - -/* - * Split a multipart/XXX message body into component parts: result is - * canonical parts in a STACK of bios - */ - -static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret) -{ - char linebuf[MAX_SMLEN]; - int len, blen; - int eol = 0, next_eol = 0; - BIO *bpart = NULL; - STACK_OF(BIO) *parts; - char state, part, first; - - blen = strlen(bound); - part = 0; - state = 0; - first = 1; - parts = sk_BIO_new_null(); - *ret = parts; - while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { - state = mime_bound_check(linebuf, len, bound, blen); - if (state == 1) { - first = 1; - part++; - } else if (state == 2) { - sk_BIO_push(parts, bpart); - return 1; - } else if (part) { - /* Strip CR+LF from linebuf */ - next_eol = strip_eol(linebuf, &len); - if (first) { - first = 0; - if (bpart) - sk_BIO_push(parts, bpart); - bpart = BIO_new(BIO_s_mem()); - if (bpart == NULL) - return 1; - BIO_set_mem_eof_return(bpart, 0); - } else if (eol) - BIO_write(bpart, "\r\n", 2); - eol = next_eol; - if (len) - BIO_write(bpart, linebuf, len); - } - } - return 0; -} - -/* This is the big one: parse MIME header lines up to message body */ - -#define MIME_INVALID 0 -#define MIME_START 1 -#define MIME_TYPE 2 -#define MIME_NAME 3 -#define MIME_VALUE 4 -#define MIME_QUOTE 5 -#define MIME_COMMENT 6 - -static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio) -{ - char *p, *q, c; - char *ntmp; - char linebuf[MAX_SMLEN]; - MIME_HEADER *mhdr = NULL; - STACK_OF(MIME_HEADER) *headers; - int len, state, save_state = 0; - - headers = sk_MIME_HEADER_new(mime_hdr_cmp); - if (!headers) - return NULL; - while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { - /* If whitespace at line start then continuation line */ - if (mhdr && isspace((unsigned char)linebuf[0])) - state = MIME_NAME; - else - state = MIME_START; - ntmp = NULL; - /* Go through all characters */ - for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); - p++) { - - /* - * State machine to handle MIME headers if this looks horrible - * that's because it *is* - */ - - switch (state) { - case MIME_START: - if (c == ':') { - state = MIME_TYPE; - *p = 0; - ntmp = strip_ends(q); - q = p + 1; - } - break; - - case MIME_TYPE: - if (c == ';') { - mime_debug("Found End Value\n"); - *p = 0; - mhdr = mime_hdr_new(ntmp, strip_ends(q)); - sk_MIME_HEADER_push(headers, mhdr); - ntmp = NULL; - q = p + 1; - state = MIME_NAME; - } else if (c == '(') { - save_state = state; - state = MIME_COMMENT; - } - break; - - case MIME_COMMENT: - if (c == ')') { - state = save_state; - } - break; - - case MIME_NAME: - if (c == '=') { - state = MIME_VALUE; - *p = 0; - ntmp = strip_ends(q); - q = p + 1; - } - break; - - case MIME_VALUE: - if (c == ';') { - state = MIME_NAME; - *p = 0; - mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); - ntmp = NULL; - q = p + 1; - } else if (c == '"') { - mime_debug("Found Quote\n"); - state = MIME_QUOTE; - } else if (c == '(') { - save_state = state; - state = MIME_COMMENT; - } - break; - - case MIME_QUOTE: - if (c == '"') { - mime_debug("Found Match Quote\n"); - state = MIME_VALUE; - } - break; - } - } - - if (state == MIME_TYPE) { - mhdr = mime_hdr_new(ntmp, strip_ends(q)); - sk_MIME_HEADER_push(headers, mhdr); - } else if (state == MIME_VALUE) - mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); - if (p == linebuf) - break; /* Blank line means end of headers */ - } - - return headers; - -} - -static char *strip_ends(char *name) -{ - return strip_end(strip_start(name)); -} - -/* Strip a parameter of whitespace from start of param */ -static char *strip_start(char *name) -{ - char *p, c; - /* Look for first non white space or quote */ - for (p = name; (c = *p); p++) { - if (c == '"') { - /* Next char is start of string if non null */ - if (p[1]) - return p + 1; - /* Else null string */ - return NULL; - } - if (!isspace((unsigned char)c)) - return p; - } - return NULL; -} - -/* As above but strip from end of string : maybe should handle brackets? */ -static char *strip_end(char *name) -{ - char *p, c; - if (!name) - return NULL; - /* Look for first non white space or quote */ - for (p = name + strlen(name) - 1; p >= name; p--) { - c = *p; - if (c == '"') { - if (p - 1 == name) - return NULL; - *p = 0; - return name; - } - if (isspace((unsigned char)c)) - *p = 0; - else - return name; - } - return NULL; -} - -static MIME_HEADER *mime_hdr_new(char *name, char *value) -{ - MIME_HEADER *mhdr; - char *tmpname, *tmpval, *p; - int c; - if (name) { - if (!(tmpname = BUF_strdup(name))) - return NULL; - for (p = tmpname; *p; p++) { - c = (unsigned char)*p; - if (isupper(c)) { - c = tolower(c); - *p = c; - } - } - } else - tmpname = NULL; - if (value) { - if (!(tmpval = BUF_strdup(value))) - return NULL; - for (p = tmpval; *p; p++) { - c = (unsigned char)*p; - if (isupper(c)) { - c = tolower(c); - *p = c; - } - } - } else - tmpval = NULL; - mhdr = (MIME_HEADER *)OPENSSL_malloc(sizeof(MIME_HEADER)); - if (!mhdr) - return NULL; - mhdr->name = tmpname; - mhdr->value = tmpval; - if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) - return NULL; - return mhdr; -} - -static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value) -{ - char *tmpname, *tmpval, *p; - int c; - MIME_PARAM *mparam; - if (name) { - tmpname = BUF_strdup(name); - if (!tmpname) - return 0; - for (p = tmpname; *p; p++) { - c = (unsigned char)*p; - if (isupper(c)) { - c = tolower(c); - *p = c; - } - } - } else - tmpname = NULL; - if (value) { - tmpval = BUF_strdup(value); - if (!tmpval) - return 0; - } else - tmpval = NULL; - /* Parameter values are case sensitive so leave as is */ - mparam = (MIME_PARAM *)OPENSSL_malloc(sizeof(MIME_PARAM)); - if (!mparam) - return 0; - mparam->param_name = tmpname; - mparam->param_value = tmpval; - sk_MIME_PARAM_push(mhdr->params, mparam); - return 1; -} - -static int mime_hdr_cmp(const MIME_HEADER *const *a, - const MIME_HEADER *const *b) -{ - if (!(*a)->name || !(*b)->name) - return ! !(*a)->name - ! !(*b)->name; - - return (strcmp((*a)->name, (*b)->name)); -} - -static int mime_param_cmp(const MIME_PARAM *const *a, - const MIME_PARAM *const *b) -{ - if (!(*a)->param_name || !(*b)->param_name) - return ! !(*a)->param_name - ! !(*b)->param_name; - return (strcmp((*a)->param_name, (*b)->param_name)); -} - -/* Find a header with a given name (if possible) */ - -static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name) -{ - MIME_HEADER htmp; - int idx; - htmp.name = name; - idx = sk_MIME_HEADER_find(hdrs, &htmp); - if (idx < 0) - return NULL; - return sk_MIME_HEADER_value(hdrs, idx); -} - -static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name) -{ - MIME_PARAM param; - int idx; - param.param_name = name; - idx = sk_MIME_PARAM_find(hdr->params, ¶m); - if (idx < 0) - return NULL; - return sk_MIME_PARAM_value(hdr->params, idx); -} - -static void mime_hdr_free(MIME_HEADER *hdr) -{ - if (hdr->name) - OPENSSL_free(hdr->name); - if (hdr->value) - OPENSSL_free(hdr->value); - if (hdr->params) - sk_MIME_PARAM_pop_free(hdr->params, mime_param_free); - OPENSSL_free(hdr); -} - -static void mime_param_free(MIME_PARAM *param) -{ - if (param->param_name) - OPENSSL_free(param->param_name); - if (param->param_value) - OPENSSL_free(param->param_value); - OPENSSL_free(param); -} - -/*- - * Check for a multipart boundary. Returns: - * 0 : no boundary - * 1 : part boundary - * 2 : final boundary - */ -static int mime_bound_check(char *line, int linelen, char *bound, int blen) -{ - if (linelen == -1) - linelen = strlen(line); - if (blen == -1) - blen = strlen(bound); - /* Quickly eliminate if line length too short */ - if (blen + 2 > linelen) - return 0; - /* Check for part boundary */ - if (!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) { - if (!strncmp(line + blen + 2, "--", 2)) - return 2; - else - return 1; - } - return 0; -} - -static int strip_eol(char *linebuf, int *plen) -{ - int len = *plen; - char *p, c; - int is_eol = 0; - p = linebuf + len - 1; - for (p = linebuf + len - 1; len > 0; len--, p--) { - c = *p; - if (c == '\n') - is_eol = 1; - else if (c != '\r') - break; - } - *plen = len; - return is_eol; -} -/* asn_moid.c */ -/* - * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "crypto.h" -// #include "cryptlib.h" -#include "conf.h" -#include "dso.h" -// #include "x509.h" - -/* Simple ASN1 OID module: add all objects in a given section */ - -static int do_create(char *value, char *name); - -static int oid_module_init(CONF_IMODULE *md, const CONF *cnf) -{ - int i; - const char *oid_section; - STACK_OF(CONF_VALUE) *sktmp; - CONF_VALUE *oval; - oid_section = CONF_imodule_get_value(md); - if (!(sktmp = NCONF_get_section(cnf, oid_section))) { - ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION); - return 0; - } - for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { - oval = sk_CONF_VALUE_value(sktmp, i); - if (!do_create(oval->value, oval->name)) { - ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT); - return 0; - } - } - return 1; -} - -static void oid_module_finish(CONF_IMODULE *md) -{ - OBJ_cleanup(); -} - -void ASN1_add_oid_module(void) -{ - CONF_module_add("oid_section", oid_module_init, oid_module_finish); -} - -/*- - * Create an OID based on a name value pair. Accept two formats. - * shortname = 1.2.3.4 - * shortname = some long name, 1.2.3.4 - */ - -static int do_create(char *value, char *name) -{ - int nid; - ASN1_OBJECT *oid; - char *ln, *ostr, *p, *lntmp; - p = strrchr(value, ','); - if (!p) { - ln = name; - ostr = value; - } else { - ln = NULL; - ostr = p + 1; - if (!*ostr) - return 0; - while (isspace((unsigned char)*ostr)) - ostr++; - } - - nid = OBJ_create(ostr, name, ln); - - if (nid == NID_undef) - return 0; - - if (p) { - ln = value; - while (isspace((unsigned char)*ln)) - ln++; - p--; - while (isspace((unsigned char)*p)) { - if (p == ln) - return 0; - p--; - } - p++; - lntmp = OPENSSL_malloc((p - ln) + 1); - if (lntmp == NULL) - return 0; - memcpy(lntmp, ln, p - ln); - lntmp[p - ln] = 0; - oid = OBJ_nid2obj(nid); - oid->ln = lntmp; - } - - return 1; -} -/* asn_pack.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" - -#ifndef NO_ASN1_OLD - -/* ASN1 packing and unpacking functions */ - -/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */ - -STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, - d2i_of_void *d2i, - void (*free_func) (OPENSSL_BLOCK)) -{ - STACK_OF(OPENSSL_BLOCK) *sk; - const unsigned char *pbuf; - pbuf = buf; - if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func, - V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL))) - ASN1err(ASN1_F_ASN1_SEQ_UNPACK, ASN1_R_DECODE_ERROR); - return sk; -} - -/* - * Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a - * OPENSSL_malloc'ed buffer - */ - -unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, - unsigned char **buf, int *len) -{ - int safelen; - unsigned char *safe, *p; - if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE, - V_ASN1_UNIVERSAL, IS_SEQUENCE))) { - ASN1err(ASN1_F_ASN1_SEQ_PACK, ASN1_R_ENCODE_ERROR); - return NULL; - } - if (!(safe = OPENSSL_malloc(safelen))) { - ASN1err(ASN1_F_ASN1_SEQ_PACK, ERR_R_MALLOC_FAILURE); - return NULL; - } - p = safe; - i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, - IS_SEQUENCE); - if (len) - *len = safelen; - if (buf) - *buf = safe; - return safe; -} - -/* Extract an ASN1 object from an ASN1_STRING */ - -void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i) -{ - const unsigned char *p; - char *ret; - - p = oct->data; - if (!(ret = d2i(NULL, &p, oct->length))) - ASN1err(ASN1_F_ASN1_UNPACK_STRING, ASN1_R_DECODE_ERROR); - return ret; -} - -/* Pack an ASN1 object into an ASN1_STRING */ - -ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct) -{ - unsigned char *p; - ASN1_STRING *octmp; - - if (!oct || !*oct) { - if (!(octmp = ASN1_STRING_new())) { - ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (oct) - *oct = octmp; - } else - octmp = *oct; - - if (!(octmp->length = i2d(obj, NULL))) { - ASN1err(ASN1_F_ASN1_PACK_STRING, ASN1_R_ENCODE_ERROR); - goto err; - } - if (!(p = OPENSSL_malloc(octmp->length))) { - ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE); - goto err; - } - octmp->data = p; - i2d(obj, &p); - return octmp; - err: - if (!oct || !*oct) { - ASN1_STRING_free(octmp); - if (oct) - *oct = NULL; - } - return NULL; -} - -#endif - -/* ASN1_ITEM versions of the above */ - -ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) -{ - ASN1_STRING *octmp; - - if (!oct || !*oct) { - if (!(octmp = ASN1_STRING_new())) { - ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (oct) - *oct = octmp; - } else - octmp = *oct; - - if (octmp->data) { - OPENSSL_free(octmp->data); - octmp->data = NULL; - } - - if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) { - ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR); - return NULL; - } - if (!octmp->data) { - ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); - return NULL; - } - return octmp; -} - -/* Extract an ASN1 object from an ASN1_STRING */ - -void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it) -{ - const unsigned char *p; - void *ret; - - p = oct->data; - if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it))) - ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR); - return ret; -} diff --git a/Sources/COpenSSL/atalla.h b/Sources/COpenSSL/atalla.h deleted file mode 100644 index 60e7eda5..00000000 --- a/Sources/COpenSSL/atalla.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This header declares the necessary definitions for using the - * exponentiation acceleration capabilities of Atalla cards. The only - * cryptographic operation is performed by "ASI_RSAPrivateKeyOpFn" and this - * takes a structure that defines an "RSA private key". However, it is really - * only performing a regular mod_exp using the supplied modulus and exponent - * - no CRT form is being used. Hence, it is a generic mod_exp function in - * disguise, and we use it as such. Thanks to the people at Atalla for - * letting me know these definitions are fine and that they can be reproduced - * here. Geoff. - */ - -typedef struct ItemStr { - unsigned char *data; - int len; -} Item; - -typedef struct RSAPrivateKeyStr { - void *reserved; - Item version; - Item modulus; - Item publicExponent; - Item privateExponent; - Item prime[2]; - Item exponent[2]; - Item coefficient; -} RSAPrivateKey; - -/* - * Predeclare the function pointer types that we dynamically load from the - * DSO. These use the same names and form that Ben's original support code - * had (in crypto/bn/bn_exp.c) unless of course I've inadvertently changed - * the style somewhere along the way! - */ - -typedef int tfnASI_GetPerformanceStatistics(int reset_flag, - unsigned int *ret_buf); - -typedef int tfnASI_GetHardwareConfig(long card_num, unsigned int *ret_buf); - -typedef int tfnASI_RSAPrivateKeyOpFn(RSAPrivateKey * rsaKey, - unsigned char *output, - unsigned char *input, - unsigned int modulus_len); diff --git a/Sources/COpenSSL/b_dump.c b/Sources/COpenSSL/b_dump.c deleted file mode 100644 index d836d59c..00000000 --- a/Sources/COpenSSL/b_dump.c +++ /dev/null @@ -1,194 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/bio/b_dump.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * Stolen from tjh's ssl/ssl_trc.c stuff. - */ - -#include -#include "cryptlib.h" -#include "bio_lcl.h" - -#define DUMP_WIDTH 16 -#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4)) - -int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), - void *u, const char *s, int len) -{ - return BIO_dump_indent_cb(cb, u, s, len, 0); -} - -int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), - void *u, const char *s, int len, int indent) -{ - int ret = 0; - char buf[288 + 1], tmp[20], str[128 + 1]; - int i, j, rows; - unsigned char ch; - int dump_width; - - if (indent < 0) - indent = 0; - if (indent) { - if (indent > 128) - indent = 128; - memset(str, ' ', indent); - } - str[indent] = '\0'; - - dump_width = DUMP_WIDTH_LESS_INDENT(indent); - rows = (len / dump_width); - if ((rows * dump_width) < len) - rows++; - for (i = 0; i < rows; i++) { - BUF_strlcpy(buf, str, sizeof(buf)); - BIO_snprintf(tmp, sizeof(tmp), "%04x - ", i * dump_width); - BUF_strlcat(buf, tmp, sizeof(buf)); - for (j = 0; j < dump_width; j++) { - if (((i * dump_width) + j) >= len) { - BUF_strlcat(buf, " ", sizeof(buf)); - } else { - ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; - BIO_snprintf(tmp, sizeof(tmp), "%02x%c", ch, - j == 7 ? '-' : ' '); - BUF_strlcat(buf, tmp, sizeof(buf)); - } - } - BUF_strlcat(buf, " ", sizeof(buf)); - for (j = 0; j < dump_width; j++) { - if (((i * dump_width) + j) >= len) - break; - ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; -#ifndef CHARSET_EBCDIC - BIO_snprintf(tmp, sizeof(tmp), "%c", - ((ch >= ' ') && (ch <= '~')) ? ch : '.'); -#else - BIO_snprintf(tmp, sizeof(tmp), "%c", - ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) - ? os_toebcdic[ch] - : '.'); -#endif - BUF_strlcat(buf, tmp, sizeof(buf)); - } - BUF_strlcat(buf, "\n", sizeof(buf)); - /* - * if this is the last call then update the ddt_dump thing so that we - * will move the selection point in the debug window - */ - ret += cb((void *)buf, strlen(buf), u); - } - return ret; -} - -#ifndef OPENSSL_NO_FP_API -static int write_fp(const void *data, size_t len, void *fp) -{ - return UP_fwrite(data, len, 1, fp); -} - -int BIO_dump_fp(FILE *fp, const char *s, int len) -{ - return BIO_dump_cb(write_fp, fp, s, len); -} - -int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent) -{ - return BIO_dump_indent_cb(write_fp, fp, s, len, indent); -} -#endif - -static int write_bio(const void *data, size_t len, void *bp) -{ - return BIO_write((BIO *)bp, (const char *)data, len); -} - -int BIO_dump(BIO *bp, const char *s, int len) -{ - return BIO_dump_cb(write_bio, bp, s, len); -} - -int BIO_dump_indent(BIO *bp, const char *s, int len, int indent) -{ - return BIO_dump_indent_cb(write_bio, bp, s, len, indent); -} - -int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, - int datalen) -{ - int i, j = 0; - - if (datalen < 1) - return 1; - - for (i = 0; i < datalen - 1; i++) { - if (i && !j) - BIO_printf(out, "%*s", indent, ""); - - BIO_printf(out, "%02X:", data[i]); - - j = (j + 1) % width; - if (!j) - BIO_printf(out, "\n"); - } - - if (i && !j) - BIO_printf(out, "%*s", indent, ""); - BIO_printf(out, "%02X", data[datalen - 1]); - return 1; -} diff --git a/Sources/COpenSSL/b_print.c b/Sources/COpenSSL/b_print.c deleted file mode 100644 index 59e585c5..00000000 --- a/Sources/COpenSSL/b_print.c +++ /dev/null @@ -1,870 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/bio/b_print.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* disable assert() unless BIO_DEBUG has been defined */ -#ifndef BIO_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif - -/* - * Stolen from tjh's ssl/ssl_trc.c stuff. - */ - -#include -#include -#include -#include -#include -#include "cryptlib.h" -#ifndef NO_SYS_TYPES_H -# include -#endif -#include "bn.h" /* To get BN_LLONG properly defined */ -#include "bio.h" - -#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT) -# ifndef HAVE_LONG_LONG -# define HAVE_LONG_LONG 1 -# endif -#endif - -/***************************************************************************/ - -/* - * Copyright Patrick Powell 1995 - * This code is based on code written by Patrick Powell - * It may be used for any purpose as long as this notice remains intact - * on all source code distributions. - */ - -/*- - * This code contains numerious changes and enhancements which were - * made by lots of contributors over the last years to Patrick Powell's - * original code: - * - * o Patrick Powell (1995) - * o Brandon Long (1996, for Mutt) - * o Thomas Roessler (1998, for Mutt) - * o Michael Elkins (1998, for Mutt) - * o Andrew Tridgell (1998, for Samba) - * o Luke Mewburn (1999, for LukemFTP) - * o Ralf S. Engelschall (1999, for Pth) - * o ... (for OpenSSL) - */ - -#ifdef HAVE_LONG_DOUBLE -# define LDOUBLE long double -#else -# define LDOUBLE double -#endif - -#ifdef HAVE_LONG_LONG -# if defined(_WIN32) && !defined(__GNUC__) -# define LLONG __int64 -# else -# define LLONG long long -# endif -#else -# define LLONG long -#endif - -static int fmtstr(char **, char **, size_t *, size_t *, - const char *, int, int, int); -static int fmtint(char **, char **, size_t *, size_t *, - LLONG, int, int, int, int); -static int fmtfp(char **, char **, size_t *, size_t *, - LDOUBLE, int, int, int); -static int doapr_outch(char **, char **, size_t *, size_t *, int); -static int _dopr(char **sbuffer, char **buffer, - size_t *maxlen, size_t *retlen, int *truncated, - const char *format, va_list args); - -/* format read states */ -#define DP_S_DEFAULT 0 -#define DP_S_FLAGS 1 -#define DP_S_MIN 2 -#define DP_S_DOT 3 -#define DP_S_MAX 4 -#define DP_S_MOD 5 -#define DP_S_CONV 6 -#define DP_S_DONE 7 - -/* format flags - Bits */ -#define DP_F_MINUS (1 << 0) -#define DP_F_PLUS (1 << 1) -#define DP_F_SPACE (1 << 2) -#define DP_F_NUM (1 << 3) -#define DP_F_ZERO (1 << 4) -#define DP_F_UP (1 << 5) -#define DP_F_UNSIGNED (1 << 6) - -/* conversion flags */ -#define DP_C_SHORT 1 -#define DP_C_LONG 2 -#define DP_C_LDOUBLE 3 -#define DP_C_LLONG 4 - -/* some handy macros */ -#define char_to_int(p) (p - '0') -#define OSSL_MAX(p,q) ((p >= q) ? p : q) - -static int -_dopr(char **sbuffer, - char **buffer, - size_t *maxlen, - size_t *retlen, int *truncated, const char *format, va_list args) -{ - char ch; - LLONG value; - LDOUBLE fvalue; - char *strvalue; - int min; - int max; - int state; - int flags; - int cflags; - size_t currlen; - - state = DP_S_DEFAULT; - flags = currlen = cflags = min = 0; - max = -1; - ch = *format++; - - while (state != DP_S_DONE) { - if (ch == '\0' || (buffer == NULL && currlen >= *maxlen)) - state = DP_S_DONE; - - switch (state) { - case DP_S_DEFAULT: - if (ch == '%') - state = DP_S_FLAGS; - else - if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) - return 0; - ch = *format++; - break; - case DP_S_FLAGS: - switch (ch) { - case '-': - flags |= DP_F_MINUS; - ch = *format++; - break; - case '+': - flags |= DP_F_PLUS; - ch = *format++; - break; - case ' ': - flags |= DP_F_SPACE; - ch = *format++; - break; - case '#': - flags |= DP_F_NUM; - ch = *format++; - break; - case '0': - flags |= DP_F_ZERO; - ch = *format++; - break; - default: - state = DP_S_MIN; - break; - } - break; - case DP_S_MIN: - if (isdigit((unsigned char)ch)) { - min = 10 * min + char_to_int(ch); - ch = *format++; - } else if (ch == '*') { - min = va_arg(args, int); - ch = *format++; - state = DP_S_DOT; - } else - state = DP_S_DOT; - break; - case DP_S_DOT: - if (ch == '.') { - state = DP_S_MAX; - ch = *format++; - } else - state = DP_S_MOD; - break; - case DP_S_MAX: - if (isdigit((unsigned char)ch)) { - if (max < 0) - max = 0; - max = 10 * max + char_to_int(ch); - ch = *format++; - } else if (ch == '*') { - max = va_arg(args, int); - ch = *format++; - state = DP_S_MOD; - } else - state = DP_S_MOD; - break; - case DP_S_MOD: - switch (ch) { - case 'h': - cflags = DP_C_SHORT; - ch = *format++; - break; - case 'l': - if (*format == 'l') { - cflags = DP_C_LLONG; - format++; - } else - cflags = DP_C_LONG; - ch = *format++; - break; - case 'q': - cflags = DP_C_LLONG; - ch = *format++; - break; - case 'L': - cflags = DP_C_LDOUBLE; - ch = *format++; - break; - default: - break; - } - state = DP_S_CONV; - break; - case DP_S_CONV: - switch (ch) { - case 'd': - case 'i': - switch (cflags) { - case DP_C_SHORT: - value = (short int)va_arg(args, int); - break; - case DP_C_LONG: - value = va_arg(args, long int); - break; - case DP_C_LLONG: - value = va_arg(args, LLONG); - break; - default: - value = va_arg(args, int); - break; - } - if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min, - max, flags)) - return 0; - break; - case 'X': - flags |= DP_F_UP; - /* FALLTHROUGH */ - case 'x': - case 'o': - case 'u': - flags |= DP_F_UNSIGNED; - switch (cflags) { - case DP_C_SHORT: - value = (unsigned short int)va_arg(args, unsigned int); - break; - case DP_C_LONG: - value = (LLONG) va_arg(args, unsigned long int); - break; - case DP_C_LLONG: - value = va_arg(args, unsigned LLONG); - break; - default: - value = (LLONG) va_arg(args, unsigned int); - break; - } - if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, - ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), - min, max, flags)) - return 0; - break; - case 'f': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max, - flags)) - return 0; - break; - case 'E': - flags |= DP_F_UP; - case 'e': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - break; - case 'G': - flags |= DP_F_UP; - case 'g': - if (cflags == DP_C_LDOUBLE) - fvalue = va_arg(args, LDOUBLE); - else - fvalue = va_arg(args, double); - break; - case 'c': - if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, - va_arg(args, int))) - return 0; - break; - case 's': - strvalue = va_arg(args, char *); - if (max < 0) { - if (buffer) - max = INT_MAX; - else - max = *maxlen; - } - if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, - flags, min, max)) - return 0; - break; - case 'p': - value = (long)va_arg(args, void *); - if (!fmtint(sbuffer, buffer, &currlen, maxlen, - value, 16, min, max, flags | DP_F_NUM)) - return 0; - break; - case 'n': /* XXX */ - if (cflags == DP_C_SHORT) { - short int *num; - num = va_arg(args, short int *); - *num = (short int)currlen; - } else if (cflags == DP_C_LONG) { /* XXX */ - long int *num; - num = va_arg(args, long int *); - *num = (long int)currlen; - } else if (cflags == DP_C_LLONG) { /* XXX */ - LLONG *num; - num = va_arg(args, LLONG *); - *num = (LLONG) currlen; - } else { - int *num; - num = va_arg(args, int *); - *num = currlen; - } - break; - case '%': - if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) - return 0; - break; - case 'w': - /* not supported yet, treat as next char */ - ch = *format++; - break; - default: - /* unknown, skip */ - break; - } - ch = *format++; - state = DP_S_DEFAULT; - flags = cflags = min = 0; - max = -1; - break; - case DP_S_DONE: - break; - default: - break; - } - } - /* - * We have to truncate if there is no dynamic buffer and we have filled the - * static buffer. - */ - if (buffer == NULL) { - *truncated = (currlen > *maxlen - 1); - if (*truncated) - currlen = *maxlen - 1; - } - if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0')) - return 0; - *retlen = currlen - 1; - return 1; -} - -static int -fmtstr(char **sbuffer, - char **buffer, - size_t *currlen, - size_t *maxlen, const char *value, int flags, int min, int max) -{ - int padlen; - size_t strln; - int cnt = 0; - - if (value == 0) - value = ""; - - strln = strlen(value); - if (strln > INT_MAX) - strln = INT_MAX; - - padlen = min - strln; - if (min < 0 || padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; - - while ((padlen > 0) && (cnt < max)) { - if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) - return 0; - --padlen; - ++cnt; - } - while (*value && (cnt < max)) { - if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++)) - return 0; - ++cnt; - } - while ((padlen < 0) && (cnt < max)) { - if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) - return 0; - ++padlen; - ++cnt; - } - return 1; -} - -static int -fmtint(char **sbuffer, - char **buffer, - size_t *currlen, - size_t *maxlen, LLONG value, int base, int min, int max, int flags) -{ - int signvalue = 0; - const char *prefix = ""; - unsigned LLONG uvalue; - char convert[DECIMAL_SIZE(value) + 3]; - int place = 0; - int spadlen = 0; - int zpadlen = 0; - int caps = 0; - - if (max < 0) - max = 0; - uvalue = value; - if (!(flags & DP_F_UNSIGNED)) { - if (value < 0) { - signvalue = '-'; - uvalue = 0 - (unsigned LLONG)value; - } else if (flags & DP_F_PLUS) - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - } - if (flags & DP_F_NUM) { - if (base == 8) - prefix = "0"; - if (base == 16) - prefix = "0x"; - } - if (flags & DP_F_UP) - caps = 1; - do { - convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef") - [uvalue % (unsigned)base]; - uvalue = (uvalue / (unsigned)base); - } while (uvalue && (place < (int)sizeof(convert))); - if (place == sizeof(convert)) - place--; - convert[place] = 0; - - zpadlen = max - place; - spadlen = - min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix); - if (zpadlen < 0) - zpadlen = 0; - if (spadlen < 0) - spadlen = 0; - if (flags & DP_F_ZERO) { - zpadlen = OSSL_MAX(zpadlen, spadlen); - spadlen = 0; - } - if (flags & DP_F_MINUS) - spadlen = -spadlen; - - /* spaces */ - while (spadlen > 0) { - if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) - return 0; - --spadlen; - } - - /* sign */ - if (signvalue) - if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) - return 0; - - /* prefix */ - while (*prefix) { - if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix)) - return 0; - prefix++; - } - - /* zeros */ - if (zpadlen > 0) { - while (zpadlen > 0) { - if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) - return 0; - --zpadlen; - } - } - /* digits */ - while (place > 0) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place])) - return 0; - } - - /* left justified spaces */ - while (spadlen < 0) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) - return 0; - ++spadlen; - } - return 1; -} - -static LDOUBLE abs_val(LDOUBLE value) -{ - LDOUBLE result = value; - if (value < 0) - result = -value; - return result; -} - -static LDOUBLE pow_10(int in_exp) -{ - LDOUBLE result = 1; - while (in_exp) { - result *= 10; - in_exp--; - } - return result; -} - -static long roundv(LDOUBLE value) -{ - long intpart; - intpart = (long)value; - value = value - intpart; - if (value >= 0.5) - intpart++; - return intpart; -} - -static int -fmtfp(char **sbuffer, - char **buffer, - size_t *currlen, - size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags) -{ - int signvalue = 0; - LDOUBLE ufvalue; - char iconvert[20]; - char fconvert[20]; - int iplace = 0; - int fplace = 0; - int padlen = 0; - int zpadlen = 0; - long intpart; - long fracpart; - long max10; - - if (max < 0) - max = 6; - ufvalue = abs_val(fvalue); - if (fvalue < 0) - signvalue = '-'; - else if (flags & DP_F_PLUS) - signvalue = '+'; - else if (flags & DP_F_SPACE) - signvalue = ' '; - - intpart = (long)ufvalue; - - /* - * sorry, we only support 9 digits past the decimal because of our - * conversion method - */ - if (max > 9) - max = 9; - - /* - * we "cheat" by converting the fractional part to integer by multiplying - * by a factor of 10 - */ - max10 = roundv(pow_10(max)); - fracpart = roundv(pow_10(max) * (ufvalue - intpart)); - - if (fracpart >= max10) { - intpart++; - fracpart -= max10; - } - - /* convert integer part */ - do { - iconvert[iplace++] = "0123456789"[intpart % 10]; - intpart = (intpart / 10); - } while (intpart && (iplace < (int)sizeof(iconvert))); - if (iplace == sizeof(iconvert)) - iplace--; - iconvert[iplace] = 0; - - /* convert fractional part */ - do { - fconvert[fplace++] = "0123456789"[fracpart % 10]; - fracpart = (fracpart / 10); - } while (fplace < max); - if (fplace == sizeof(fconvert)) - fplace--; - fconvert[fplace] = 0; - - /* -1 for decimal point, another -1 if we are printing a sign */ - padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); - zpadlen = max - fplace; - if (zpadlen < 0) - zpadlen = 0; - if (padlen < 0) - padlen = 0; - if (flags & DP_F_MINUS) - padlen = -padlen; - - if ((flags & DP_F_ZERO) && (padlen > 0)) { - if (signvalue) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) - return 0; - --padlen; - signvalue = 0; - } - while (padlen > 0) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) - return 0; - --padlen; - } - } - while (padlen > 0) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) - return 0; - --padlen; - } - if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) - return 0; - - while (iplace > 0) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace])) - return 0; - } - - /* - * Decimal point. This should probably use locale to find the correct - * char to print out. - */ - if (max > 0 || (flags & DP_F_NUM)) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.')) - return 0; - - while (fplace > 0) { - if(!doapr_outch(sbuffer, buffer, currlen, maxlen, - fconvert[--fplace])) - return 0; - } - } - while (zpadlen > 0) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) - return 0; - --zpadlen; - } - - while (padlen < 0) { - if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) - return 0; - ++padlen; - } - return 1; -} - -#define BUFFER_INC 1024 - -static int -doapr_outch(char **sbuffer, - char **buffer, size_t *currlen, size_t *maxlen, int c) -{ - /* If we haven't at least one buffer, someone has doe a big booboo */ - assert(*sbuffer != NULL || buffer != NULL); - - /* |currlen| must always be <= |*maxlen| */ - assert(*currlen <= *maxlen); - - if (buffer && *currlen == *maxlen) { - if (*maxlen > INT_MAX - BUFFER_INC) - return 0; - - *maxlen += BUFFER_INC; - if (*buffer == NULL) { - *buffer = OPENSSL_malloc(*maxlen); - if (*buffer == NULL) - return 0; - if (*currlen > 0) { - assert(*sbuffer != NULL); - memcpy(*buffer, *sbuffer, *currlen); - } - *sbuffer = NULL; - } else { - char *tmpbuf; - tmpbuf = OPENSSL_realloc(*buffer, *maxlen); - if (tmpbuf == NULL) - return 0; - *buffer = tmpbuf; - } - } - - if (*currlen < *maxlen) { - if (*sbuffer) - (*sbuffer)[(*currlen)++] = (char)c; - else - (*buffer)[(*currlen)++] = (char)c; - } - - return 1; -} - -/***************************************************************************/ - -int BIO_printf(BIO *bio, const char *format, ...) -{ - va_list args; - int ret; - - va_start(args, format); - - ret = BIO_vprintf(bio, format, args); - - va_end(args); - return (ret); -} - -int BIO_vprintf(BIO *bio, const char *format, va_list args) -{ - int ret; - size_t retlen; - char hugebuf[1024 * 2]; /* Was previously 10k, which is unreasonable - * in small-stack environments, like threads - * or DOS programs. */ - char *hugebufp = hugebuf; - size_t hugebufsize = sizeof(hugebuf); - char *dynbuf = NULL; - int ignored; - - dynbuf = NULL; - CRYPTO_push_info("doapr()"); - if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, - args)) { - OPENSSL_free(dynbuf); - return -1; - } - if (dynbuf) { - ret = BIO_write(bio, dynbuf, (int)retlen); - OPENSSL_free(dynbuf); - } else { - ret = BIO_write(bio, hugebuf, (int)retlen); - } - CRYPTO_pop_info(); - return (ret); -} - -/* - * As snprintf is not available everywhere, we provide our own - * implementation. This function has nothing to do with BIOs, but it's - * closely related to BIO_printf, and we need *some* name prefix ... (XXX the - * function should be renamed, but to what?) - */ -int BIO_snprintf(char *buf, size_t n, const char *format, ...) -{ - va_list args; - int ret; - - va_start(args, format); - - ret = BIO_vsnprintf(buf, n, format, args); - - va_end(args); - return (ret); -} - -int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) -{ - size_t retlen; - int truncated; - - if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args)) - return -1; - - if (truncated) - /* - * In case of truncation, return -1 like traditional snprintf. - * (Current drafts for ISO/IEC 9899 say snprintf should return the - * number of characters that would have been written, had the buffer - * been large enough.) - */ - return -1; - else - return (retlen <= INT_MAX) ? (int)retlen : -1; -} diff --git a/Sources/COpenSSL/b_sock.c b/Sources/COpenSSL/b_sock.c deleted file mode 100644 index 84cb83b6..00000000 --- a/Sources/COpenSSL/b_sock.c +++ /dev/null @@ -1,983 +0,0 @@ -/* crypto/bio/b_sock.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#define _DEFAULT_SOURCE -#define _BSD_SOURCE - -#include -#include -#include -#define USE_SOCKETS -#include "cryptlib.h" -#include "bio.h" -#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK) -# include -# if defined(NETWARE_CLIB) -# include -NETDB_DEFINE_CONTEXT -# endif -#endif -#ifndef OPENSSL_NO_SOCK -# include "dso.h" -# define SOCKET_PROTOCOL IPPROTO_TCP -# ifdef SO_MAXCONN -# define MAX_LISTEN SO_MAXCONN -# elif defined(SOMAXCONN) -# define MAX_LISTEN SOMAXCONN -# else -# define MAX_LISTEN 32 -# endif -# if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) -static int wsa_init_done = 0; -# endif - -# if defined(__GLIBC__) -# define HAVE_GETHOSTBYNAME_R -# define GETHOSTNAME_R_BUF (2 * 1024) -# endif - -/* - * WSAAPI specifier is required to make indirect calls to run-time - * linked WinSock 2 functions used in this module, to be specific - * [get|free]addrinfo and getnameinfo. This is because WinSock uses - * uses non-C calling convention, __stdcall vs. __cdecl, on x86 - * Windows. On non-WinSock platforms WSAAPI needs to be void. - */ -# ifndef WSAAPI -# define WSAAPI -# endif - -# if 0 -static unsigned long BIO_ghbn_hits = 0L; -static unsigned long BIO_ghbn_miss = 0L; - -# define GHBN_NUM 4 -static struct ghbn_cache_st { - char name[129]; - struct hostent *ent; - unsigned long order; -} ghbn_cache[GHBN_NUM]; -# endif - -static int get_ip(const char *str, unsigned char *ip); -# if 0 -static void ghbn_free(struct hostent *a); -static struct hostent *ghbn_dup(struct hostent *a); -# endif -int BIO_get_host_ip(const char *str, unsigned char *ip) -{ - int i; - int err = 1; - int locked = 0; - struct hostent *he = NULL; -# ifdef HAVE_GETHOSTBYNAME_R - char buf[GETHOSTNAME_R_BUF]; - struct hostent hostent; - int h_errnop; -# endif - - i = get_ip(str, ip); - if (i < 0) { - BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS); - goto err; - } - - /* - * At this point, we have something that is most probably correct in some - * way, so let's init the socket. - */ - if (BIO_sock_init() != 1) - return 0; /* don't generate another error code here */ - - /* - * If the string actually contained an IP address, we need not do - * anything more - */ - if (i > 0) - return (1); - - /* if gethostbyname_r is supported, use it. */ -# ifdef HAVE_GETHOSTBYNAME_R - memset(&hostent, 0x00, sizeof(hostent)); - /* gethostbyname_r() sets |he| to NULL on error, we check it further down */ - gethostbyname_r(str, &hostent, buf, sizeof(buf), &he, &h_errnop); -# else - /* do a gethostbyname */ - CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); - locked = 1; - he = BIO_gethostbyname(str); -# endif - - if (he == NULL) { - BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP); - goto err; - } - - /* cast to short because of win16 winsock definition */ - if ((short)he->h_addrtype != AF_INET) { - BIOerr(BIO_F_BIO_GET_HOST_IP, - BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); - goto err; - } - for (i = 0; i < 4; i++) - ip[i] = he->h_addr_list[0][i]; - err = 0; - - err: - if (locked) - CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); - if (err) { - ERR_add_error_data(2, "host=", str); - return 0; - } else - return 1; -} - -int BIO_get_port(const char *str, unsigned short *port_ptr) -{ - int i; - struct servent *s; - - if (str == NULL) { - BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); - return (0); - } - i = atoi(str); - if (i != 0) - *port_ptr = (unsigned short)i; - else { - CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); - /* - * Note: under VMS with SOCKETSHR, it seems like the first parameter - * is 'char *', instead of 'const char *' - */ -# ifndef CONST_STRICT - s = getservbyname((char *)str, "tcp"); -# else - s = getservbyname(str, "tcp"); -# endif - if (s != NULL) - *port_ptr = ntohs((unsigned short)s->s_port); - CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); - if (s == NULL) { - if (strcmp(str, "http") == 0) - *port_ptr = 80; - else if (strcmp(str, "telnet") == 0) - *port_ptr = 23; - else if (strcmp(str, "socks") == 0) - *port_ptr = 1080; - else if (strcmp(str, "https") == 0) - *port_ptr = 443; - else if (strcmp(str, "ssl") == 0) - *port_ptr = 443; - else if (strcmp(str, "ftp") == 0) - *port_ptr = 21; - else if (strcmp(str, "gopher") == 0) - *port_ptr = 70; -# if 0 - else if (strcmp(str, "wais") == 0) - *port_ptr = 21; -# endif - else { - SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error()); - ERR_add_error_data(3, "service='", str, "'"); - return (0); - } - } - } - return (1); -} - -int BIO_sock_error(int sock) -{ - int j, i; - union { - size_t s; - int i; - } size; - -# if defined(OPENSSL_SYS_BEOS_R5) - return 0; -# endif - - /* heuristic way to adapt for platforms that expect 64-bit optlen */ - size.s = 0, size.i = sizeof(j); - /* - * Note: under Windows the third parameter is of type (char *) whereas - * under other systems it is (void *) if you don't have a cast it will - * choke the compiler: if you do have a cast then you can either go for - * (char *) or (void *). - */ - i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size); - if (i < 0) - return (1); - else - return (j); -} - -# if 0 -long BIO_ghbn_ctrl(int cmd, int iarg, char *parg) -{ - int i; - char **p; - - switch (cmd) { - case BIO_GHBN_CTRL_HITS: - return (BIO_ghbn_hits); - /* break; */ - case BIO_GHBN_CTRL_MISSES: - return (BIO_ghbn_miss); - /* break; */ - case BIO_GHBN_CTRL_CACHE_SIZE: - return (GHBN_NUM); - /* break; */ - case BIO_GHBN_CTRL_GET_ENTRY: - if ((iarg >= 0) && (iarg < GHBN_NUM) && (ghbn_cache[iarg].order > 0)) { - p = (char **)parg; - if (p == NULL) - return (0); - *p = ghbn_cache[iarg].name; - ghbn_cache[iarg].name[128] = '\0'; - return (1); - } - return (0); - /* break; */ - case BIO_GHBN_CTRL_FLUSH: - for (i = 0; i < GHBN_NUM; i++) - ghbn_cache[i].order = 0; - break; - default: - return (0); - } - return (1); -} -# endif - -# if 0 -static struct hostent *ghbn_dup(struct hostent *a) -{ - struct hostent *ret; - int i, j; - - MemCheck_off(); - ret = (struct hostent *)OPENSSL_malloc(sizeof(struct hostent)); - if (ret == NULL) - return (NULL); - memset(ret, 0, sizeof(struct hostent)); - - for (i = 0; a->h_aliases[i] != NULL; i++) ; - i++; - ret->h_aliases = (char **)OPENSSL_malloc(i * sizeof(char *)); - if (ret->h_aliases == NULL) - goto err; - memset(ret->h_aliases, 0, i * sizeof(char *)); - - for (i = 0; a->h_addr_list[i] != NULL; i++) ; - i++; - ret->h_addr_list = (char **)OPENSSL_malloc(i * sizeof(char *)); - if (ret->h_addr_list == NULL) - goto err; - memset(ret->h_addr_list, 0, i * sizeof(char *)); - - j = strlen(a->h_name) + 1; - if ((ret->h_name = OPENSSL_malloc(j)) == NULL) - goto err; - memcpy((char *)ret->h_name, a->h_name, j); - for (i = 0; a->h_aliases[i] != NULL; i++) { - j = strlen(a->h_aliases[i]) + 1; - if ((ret->h_aliases[i] = OPENSSL_malloc(j)) == NULL) - goto err; - memcpy(ret->h_aliases[i], a->h_aliases[i], j); - } - ret->h_length = a->h_length; - ret->h_addrtype = a->h_addrtype; - for (i = 0; a->h_addr_list[i] != NULL; i++) { - if ((ret->h_addr_list[i] = OPENSSL_malloc(a->h_length)) == NULL) - goto err; - memcpy(ret->h_addr_list[i], a->h_addr_list[i], a->h_length); - } - if (0) { - err: - if (ret != NULL) - ghbn_free(ret); - ret = NULL; - } - MemCheck_on(); - return (ret); -} - -static void ghbn_free(struct hostent *a) -{ - int i; - - if (a == NULL) - return; - - if (a->h_aliases != NULL) { - for (i = 0; a->h_aliases[i] != NULL; i++) - OPENSSL_free(a->h_aliases[i]); - OPENSSL_free(a->h_aliases); - } - if (a->h_addr_list != NULL) { - for (i = 0; a->h_addr_list[i] != NULL; i++) - OPENSSL_free(a->h_addr_list[i]); - OPENSSL_free(a->h_addr_list); - } - if (a->h_name != NULL) - OPENSSL_free(a->h_name); - OPENSSL_free(a); -} - -# endif - -struct hostent *BIO_gethostbyname(const char *name) -{ -# if 1 - /* - * Caching gethostbyname() results forever is wrong, so we have to let - * the true gethostbyname() worry about this - */ -# if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__)) - return gethostbyname((char *)name); -# else - return gethostbyname(name); -# endif -# else - struct hostent *ret; - int i, lowi = 0, j; - unsigned long low = (unsigned long)-1; - -# if 0 - /* - * It doesn't make sense to use locking here: The function interface is - * not thread-safe, because threads can never be sure when some other - * thread destroys the data they were given a pointer to. - */ - CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); -# endif - j = strlen(name); - if (j < 128) { - for (i = 0; i < GHBN_NUM; i++) { - if (low > ghbn_cache[i].order) { - low = ghbn_cache[i].order; - lowi = i; - } - if (ghbn_cache[i].order > 0) { - if (strncmp(name, ghbn_cache[i].name, 128) == 0) - break; - } - } - } else - i = GHBN_NUM; - - if (i == GHBN_NUM) { /* no hit */ - BIO_ghbn_miss++; - /* - * Note: under VMS with SOCKETSHR, it seems like the first parameter - * is 'char *', instead of 'const char *' - */ -# ifndef CONST_STRICT - ret = gethostbyname((char *)name); -# else - ret = gethostbyname(name); -# endif - - if (ret == NULL) - goto end; - if (j > 128) { /* too big to cache */ -# if 0 - /* - * If we were trying to make this function thread-safe (which is - * bound to fail), we'd have to give up in this case (or allocate - * more memory). - */ - ret = NULL; -# endif - goto end; - } - - /* else add to cache */ - if (ghbn_cache[lowi].ent != NULL) - ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */ - ghbn_cache[lowi].name[0] = '\0'; - - if ((ret = ghbn_cache[lowi].ent = ghbn_dup(ret)) == NULL) { - BIOerr(BIO_F_BIO_GETHOSTBYNAME, ERR_R_MALLOC_FAILURE); - goto end; - } - strncpy(ghbn_cache[lowi].name, name, 128); - ghbn_cache[lowi].order = BIO_ghbn_miss + BIO_ghbn_hits; - } else { - BIO_ghbn_hits++; - ret = ghbn_cache[i].ent; - ghbn_cache[i].order = BIO_ghbn_miss + BIO_ghbn_hits; - } - end: -# if 0 - CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); -# endif - return (ret); -# endif -} - -int BIO_sock_init(void) -{ -# ifdef OPENSSL_SYS_WINDOWS - static struct WSAData wsa_state; - - if (!wsa_init_done) { - int err; - - wsa_init_done = 1; - memset(&wsa_state, 0, sizeof(wsa_state)); - /* - * Not making wsa_state available to the rest of the code is formally - * wrong. But the structures we use are [beleived to be] invariable - * among Winsock DLLs, while API availability is [expected to be] - * probed at run-time with DSO_global_lookup. - */ - if (WSAStartup(0x0202, &wsa_state) != 0) { - err = WSAGetLastError(); - SYSerr(SYS_F_WSASTARTUP, err); - BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); - return (-1); - } - } -# endif /* OPENSSL_SYS_WINDOWS */ -# ifdef WATT32 - extern int _watt_do_exit; - _watt_do_exit = 0; /* don't make sock_init() call exit() */ - if (sock_init()) - return (-1); -# endif - -# if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) - WORD wVerReq; - WSADATA wsaData; - int err; - - if (!wsa_init_done) { - wsa_init_done = 1; - wVerReq = MAKEWORD(2, 0); - err = WSAStartup(wVerReq, &wsaData); - if (err != 0) { - SYSerr(SYS_F_WSASTARTUP, err); - BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); - return (-1); - } - } -# endif - - return (1); -} - -void BIO_sock_cleanup(void) -{ -# ifdef OPENSSL_SYS_WINDOWS - if (wsa_init_done) { - wsa_init_done = 0; -# if 0 /* this call is claimed to be non-present in - * Winsock2 */ - WSACancelBlockingCall(); -# endif - WSACleanup(); - } -# elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) - if (wsa_init_done) { - wsa_init_done = 0; - WSACleanup(); - } -# endif -} - -# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000 - -int BIO_socket_ioctl(int fd, long type, void *arg) -{ - int i; - -# ifdef __DJGPP__ - i = ioctlsocket(fd, type, (char *)arg); -# else -# if defined(OPENSSL_SYS_VMS) - /*- - * 2011-02-18 SMS. - * VMS ioctl() can't tolerate a 64-bit "void *arg", but we - * observe that all the consumers pass in an "unsigned long *", - * so we arrange a local copy with a short pointer, and use - * that, instead. - */ -# if __INITIAL_POINTER_SIZE == 64 -# define ARG arg_32p -# pragma pointer_size save -# pragma pointer_size 32 - unsigned long arg_32; - unsigned long *arg_32p; -# pragma pointer_size restore - arg_32p = &arg_32; - arg_32 = *((unsigned long *)arg); -# else /* __INITIAL_POINTER_SIZE == 64 */ -# define ARG arg -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ -# else /* defined(OPENSSL_SYS_VMS) */ -# define ARG arg -# endif /* defined(OPENSSL_SYS_VMS) [else] */ - - i = ioctlsocket(fd, type, ARG); -# endif /* __DJGPP__ */ - if (i < 0) - SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error()); - return (i); -} -# endif /* __VMS_VER */ - -/* - * The reason I have implemented this instead of using sscanf is because - * Visual C 1.52c gives an unresolved external when linking a DLL :-( - */ -static int get_ip(const char *str, unsigned char ip[4]) -{ - unsigned int tmp[4]; - int num = 0, c, ok = 0; - - tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; - - for (;;) { - c = *(str++); - if ((c >= '0') && (c <= '9')) { - ok = 1; - tmp[num] = tmp[num] * 10 + c - '0'; - if (tmp[num] > 255) - return (0); - } else if (c == '.') { - if (!ok) - return (-1); - if (num == 3) - return (0); - num++; - ok = 0; - } else if (c == '\0' && (num == 3) && ok) - break; - else - return (0); - } - ip[0] = tmp[0]; - ip[1] = tmp[1]; - ip[2] = tmp[2]; - ip[3] = tmp[3]; - return (1); -} - -int BIO_get_accept_socket(char *host, int bind_mode) -{ - int ret = 0; - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } server, client; - int s = INVALID_SOCKET, cs, addrlen; - unsigned char ip[4]; - unsigned short port; - char *str = NULL, *e; - char *h, *p; - unsigned long l; - int err_num; - - if (BIO_sock_init() != 1) - return (INVALID_SOCKET); - - if ((str = BUF_strdup(host)) == NULL) - return (INVALID_SOCKET); - - h = p = NULL; - h = str; - for (e = str; *e; e++) { - if (*e == ':') { - p = e; - } else if (*e == '/') { - *e = '\0'; - break; - } - } - if (p) - *p++ = '\0'; /* points at last ':', '::port' is special - * [see below] */ - else - p = h, h = NULL; - -# ifdef EAI_FAMILY - do { - static union { - void *p; - int (WSAAPI *f) (const char *, const char *, - const struct addrinfo *, struct addrinfo **); - } p_getaddrinfo = { - NULL - }; - static union { - void *p; - void (WSAAPI *f) (struct addrinfo *); - } p_freeaddrinfo = { - NULL - }; - struct addrinfo *res, hint; - - if (p_getaddrinfo.p == NULL) { - if ((p_getaddrinfo.p = DSO_global_lookup("getaddrinfo")) == NULL - || (p_freeaddrinfo.p = - DSO_global_lookup("freeaddrinfo")) == NULL) - p_getaddrinfo.p = (void *)-1; - } - if (p_getaddrinfo.p == (void *)-1) - break; - - /* - * '::port' enforces IPv6 wildcard listener. Some OSes, e.g. Solaris, - * default to IPv6 without any hint. Also note that commonly IPv6 - * wildchard socket can service IPv4 connections just as well... - */ - memset(&hint, 0, sizeof(hint)); - hint.ai_flags = AI_PASSIVE; - if (h) { - if (strchr(h, ':')) { - if (h[1] == '\0') - h = NULL; -# if OPENSSL_USE_IPV6 - hint.ai_family = AF_INET6; -# else - h = NULL; -# endif - } else if (h[0] == '*' && h[1] == '\0') { - hint.ai_family = AF_INET; - h = NULL; - } - } - - if ((*p_getaddrinfo.f) (h, p, &hint, &res)) - break; - - addrlen = res->ai_addrlen <= sizeof(server) ? - res->ai_addrlen : sizeof(server); - memcpy(&server, res->ai_addr, addrlen); - - (*p_freeaddrinfo.f) (res); - goto again; - } while (0); -# endif - - if (!BIO_get_port(p, &port)) - goto err; - - memset((char *)&server, 0, sizeof(server)); - server.sa_in.sin_family = AF_INET; - server.sa_in.sin_port = htons(port); - addrlen = sizeof(server.sa_in); - - if (h == NULL || strcmp(h, "*") == 0) - server.sa_in.sin_addr.s_addr = INADDR_ANY; - else { - if (!BIO_get_host_ip(h, &(ip[0]))) - goto err; - l = (unsigned long) - ((unsigned long)ip[0] << 24L) | - ((unsigned long)ip[1] << 16L) | - ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]); - server.sa_in.sin_addr.s_addr = htonl(l); - } - - again: - s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL); - if (s == INVALID_SOCKET) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); - ERR_add_error_data(3, "port='", host, "'"); - BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET); - goto err; - } -# ifdef SO_REUSEADDR - if (bind_mode == BIO_BIND_REUSEADDR) { - int i = 1; - - ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)); - bind_mode = BIO_BIND_NORMAL; - } -# endif - if (bind(s, &server.sa, addrlen) == -1) { -# ifdef SO_REUSEADDR - err_num = get_last_socket_error(); - if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && -# ifdef OPENSSL_SYS_WINDOWS - /* - * Some versions of Windows define EADDRINUSE to a dummy value. - */ - (err_num == WSAEADDRINUSE)) -# else - (err_num == EADDRINUSE)) -# endif - { - client = server; - if (h == NULL || strcmp(h, "*") == 0) { -# if OPENSSL_USE_IPV6 - if (client.sa.sa_family == AF_INET6) { - memset(&client.sa_in6.sin6_addr, 0, - sizeof(client.sa_in6.sin6_addr)); - client.sa_in6.sin6_addr.s6_addr[15] = 1; - } else -# endif - if (client.sa.sa_family == AF_INET) { - client.sa_in.sin_addr.s_addr = htonl(0x7F000001); - } else - goto err; - } - cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL); - if (cs != INVALID_SOCKET) { - int ii; - ii = connect(cs, &client.sa, addrlen); - closesocket(cs); - if (ii == INVALID_SOCKET) { - bind_mode = BIO_BIND_REUSEADDR; - closesocket(s); - goto again; - } - /* else error */ - } - /* else error */ - } -# endif - SYSerr(SYS_F_BIND, err_num); - ERR_add_error_data(3, "port='", host, "'"); - BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET); - goto err; - } - if (listen(s, MAX_LISTEN) == -1) { - SYSerr(SYS_F_BIND, get_last_socket_error()); - ERR_add_error_data(3, "port='", host, "'"); - BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET); - goto err; - } - ret = 1; - err: - if (str != NULL) - OPENSSL_free(str); - if ((ret == 0) && (s != INVALID_SOCKET)) { - closesocket(s); - s = INVALID_SOCKET; - } - return (s); -} - -int BIO_accept(int sock, char **addr) -{ - int ret = INVALID_SOCKET; - unsigned long l; - unsigned short port; - char *p; - - struct { - /* - * As for following union. Trouble is that there are platforms - * that have socklen_t and there are platforms that don't, on - * some platforms socklen_t is int and on some size_t. So what - * one can do? One can cook #ifdef spaghetti, which is nothing - * but masochistic. Or one can do union between int and size_t. - * One naturally does it primarily for 64-bit platforms where - * sizeof(int) != sizeof(size_t). But would it work? Note that - * if size_t member is initialized to 0, then later int member - * assignment naturally does the job on little-endian platforms - * regardless accept's expectations! What about big-endians? - * If accept expects int*, then it works, and if size_t*, then - * length value would appear as unreasonably large. But this - * won't prevent it from filling in the address structure. The - * trouble of course would be if accept returns more data than - * actual buffer can accomodate and overwrite stack... That's - * where early OPENSSL_assert comes into picture. Besides, the - * only 64-bit big-endian platform found so far that expects - * size_t* is HP-UX, where stack grows towards higher address. - * - */ - union { - size_t s; - int i; - } len; - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } from; - } sa; - - sa.len.s = 0; - sa.len.i = sizeof(sa.from); - memset(&sa.from, 0, sizeof(sa.from)); - ret = accept(sock, &sa.from.sa, (void *)&sa.len); - if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { - OPENSSL_assert(sa.len.s <= sizeof(sa.from)); - sa.len.i = (int)sa.len.s; - /* use sa.len.i from this point */ - } - if (ret == INVALID_SOCKET) { - if (BIO_sock_should_retry(ret)) - return -2; - SYSerr(SYS_F_ACCEPT, get_last_socket_error()); - BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR); - goto end; - } - - if (addr == NULL) - goto end; - -# ifdef EAI_FAMILY - do { - char h[NI_MAXHOST], s[NI_MAXSERV]; - size_t nl; - static union { - void *p; - int (WSAAPI *f) (const struct sockaddr *, size_t /* socklen_t */ , - char *, size_t, char *, size_t, int); - } p_getnameinfo = { - NULL - }; - /* - * 2nd argument to getnameinfo is specified to be socklen_t. - * Unfortunately there is a number of environments where socklen_t is - * not defined. As it's passed by value, it's safe to pass it as - * size_t... - */ - - if (p_getnameinfo.p == NULL) { - if ((p_getnameinfo.p = DSO_global_lookup("getnameinfo")) == NULL) - p_getnameinfo.p = (void *)-1; - } - if (p_getnameinfo.p == (void *)-1) - break; - - if ((*p_getnameinfo.f) (&sa.from.sa, sa.len.i, h, sizeof(h), s, - sizeof(s), NI_NUMERICHOST | NI_NUMERICSERV)) - break; - nl = strlen(h) + strlen(s) + 2; - p = *addr; - if (p) { - *p = '\0'; - p = OPENSSL_realloc(p, nl); - } else { - p = OPENSSL_malloc(nl); - } - if (p == NULL) { - BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); - goto end; - } - *addr = p; - BIO_snprintf(*addr, nl, "%s:%s", h, s); - goto end; - } while (0); -# endif - if (sa.from.sa.sa_family != AF_INET) - goto end; - l = ntohl(sa.from.sa_in.sin_addr.s_addr); - port = ntohs(sa.from.sa_in.sin_port); - if (*addr == NULL) { - if ((p = OPENSSL_malloc(24)) == NULL) { - BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); - goto end; - } - *addr = p; - } - BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d", - (unsigned char)(l >> 24L) & 0xff, - (unsigned char)(l >> 16L) & 0xff, - (unsigned char)(l >> 8L) & 0xff, - (unsigned char)(l) & 0xff, port); - end: - return (ret); -} - -int BIO_set_tcp_ndelay(int s, int on) -{ - int ret = 0; -# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP)) - int opt; - -# ifdef SOL_TCP - opt = SOL_TCP; -# else -# ifdef IPPROTO_TCP - opt = IPPROTO_TCP; -# endif -# endif - - ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on)); -# endif - return (ret == 0); -} - -int BIO_socket_nbio(int s, int mode) -{ - int ret = -1; - int l; - - l = mode; -# ifdef FIONBIO - ret = BIO_socket_ioctl(s, FIONBIO, &l); -# endif - return (ret == 0); -} -#endif diff --git a/Sources/COpenSSL/bf_.c b/Sources/COpenSSL/bf_.c deleted file mode 100644 index f3b4661b..00000000 --- a/Sources/COpenSSL/bf_.c +++ /dev/null @@ -1,2109 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/bio/bf_buff.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "cryptlib.h" -#include "bio.h" - -static int buffer_write(BIO *h, const char *buf, int num); -static int buffer_read(BIO *h, char *buf, int size); -static int buffer_puts(BIO *h, const char *str); -static int buffer_gets(BIO *h, char *str, int size); -static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int buffer_new(BIO *h); -static int buffer_free(BIO *data); -static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -#define DEFAULT_BUFFER_SIZE 4096 - -static BIO_METHOD methods_buffer = { - BIO_TYPE_BUFFER, - "buffer", - buffer_write, - buffer_read, - buffer_puts, - buffer_gets, - buffer_ctrl, - buffer_new, - buffer_free, - buffer_callback_ctrl, -}; - -BIO_METHOD *BIO_f_buffer(void) -{ - return (&methods_buffer); -} - -static int buffer_new(BIO *bi) -{ - BIO_F_BUFFER_CTX *ctx; - - ctx = (BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX)); - if (ctx == NULL) - return (0); - ctx->ibuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE); - if (ctx->ibuf == NULL) { - OPENSSL_free(ctx); - return (0); - } - ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE); - if (ctx->obuf == NULL) { - OPENSSL_free(ctx->ibuf); - OPENSSL_free(ctx); - return (0); - } - ctx->ibuf_size = DEFAULT_BUFFER_SIZE; - ctx->obuf_size = DEFAULT_BUFFER_SIZE; - ctx->ibuf_len = 0; - ctx->ibuf_off = 0; - ctx->obuf_len = 0; - ctx->obuf_off = 0; - - bi->init = 1; - bi->ptr = (char *)ctx; - bi->flags = 0; - return (1); -} - -static int buffer_free(BIO *a) -{ - BIO_F_BUFFER_CTX *b; - - if (a == NULL) - return (0); - b = (BIO_F_BUFFER_CTX *)a->ptr; - if (b->ibuf != NULL) - OPENSSL_free(b->ibuf); - if (b->obuf != NULL) - OPENSSL_free(b->obuf); - OPENSSL_free(a->ptr); - a->ptr = NULL; - a->init = 0; - a->flags = 0; - return (1); -} - -static int buffer_read(BIO *b, char *out, int outl) -{ - int i, num = 0; - BIO_F_BUFFER_CTX *ctx; - - if (out == NULL) - return (0); - ctx = (BIO_F_BUFFER_CTX *)b->ptr; - - if ((ctx == NULL) || (b->next_bio == NULL)) - return (0); - num = 0; - BIO_clear_retry_flags(b); - - start: - i = ctx->ibuf_len; - /* If there is stuff left over, grab it */ - if (i != 0) { - if (i > outl) - i = outl; - memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i); - ctx->ibuf_off += i; - ctx->ibuf_len -= i; - num += i; - if (outl == i) - return (num); - outl -= i; - out += i; - } - - /* - * We may have done a partial read. try to do more. We have nothing in - * the buffer. If we get an error and have read some data, just return it - * and let them retry to get the error again. copy direct to parent - * address space - */ - if (outl > ctx->ibuf_size) { - for (;;) { - i = BIO_read(b->next_bio, out, outl); - if (i <= 0) { - BIO_copy_next_retry(b); - if (i < 0) - return ((num > 0) ? num : i); - if (i == 0) - return (num); - } - num += i; - if (outl == i) - return (num); - out += i; - outl -= i; - } - } - /* else */ - - /* we are going to be doing some buffering */ - i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size); - if (i <= 0) { - BIO_copy_next_retry(b); - if (i < 0) - return ((num > 0) ? num : i); - if (i == 0) - return (num); - } - ctx->ibuf_off = 0; - ctx->ibuf_len = i; - - /* Lets re-read using ourselves :-) */ - goto start; -} - -static int buffer_write(BIO *b, const char *in, int inl) -{ - int i, num = 0; - BIO_F_BUFFER_CTX *ctx; - - if ((in == NULL) || (inl <= 0)) - return (0); - ctx = (BIO_F_BUFFER_CTX *)b->ptr; - if ((ctx == NULL) || (b->next_bio == NULL)) - return (0); - - BIO_clear_retry_flags(b); - start: - i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off); - /* add to buffer and return */ - if (i >= inl) { - memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl); - ctx->obuf_len += inl; - return (num + inl); - } - /* else */ - /* stuff already in buffer, so add to it first, then flush */ - if (ctx->obuf_len != 0) { - if (i > 0) { /* lets fill it up if we can */ - memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i); - in += i; - inl -= i; - num += i; - ctx->obuf_len += i; - } - /* we now have a full buffer needing flushing */ - for (;;) { - i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]), - ctx->obuf_len); - if (i <= 0) { - BIO_copy_next_retry(b); - - if (i < 0) - return ((num > 0) ? num : i); - if (i == 0) - return (num); - } - ctx->obuf_off += i; - ctx->obuf_len -= i; - if (ctx->obuf_len == 0) - break; - } - } - /* - * we only get here if the buffer has been flushed and we still have - * stuff to write - */ - ctx->obuf_off = 0; - - /* we now have inl bytes to write */ - while (inl >= ctx->obuf_size) { - i = BIO_write(b->next_bio, in, inl); - if (i <= 0) { - BIO_copy_next_retry(b); - if (i < 0) - return ((num > 0) ? num : i); - if (i == 0) - return (num); - } - num += i; - in += i; - inl -= i; - if (inl == 0) - return (num); - } - - /* - * copy the rest into the buffer since we have only a small amount left - */ - goto start; -} - -static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - BIO *dbio; - BIO_F_BUFFER_CTX *ctx; - long ret = 1; - char *p1, *p2; - int r, i, *ip; - int ibs, obs; - - ctx = (BIO_F_BUFFER_CTX *)b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ctx->ibuf_off = 0; - ctx->ibuf_len = 0; - ctx->obuf_off = 0; - ctx->obuf_len = 0; - if (b->next_bio == NULL) - return (0); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_INFO: - ret = (long)ctx->obuf_len; - break; - case BIO_C_GET_BUFF_NUM_LINES: - ret = 0; - p1 = ctx->ibuf; - for (i = 0; i < ctx->ibuf_len; i++) { - if (p1[ctx->ibuf_off + i] == '\n') - ret++; - } - break; - case BIO_CTRL_WPENDING: - ret = (long)ctx->obuf_len; - if (ret == 0) { - if (b->next_bio == NULL) - return (0); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - } - break; - case BIO_CTRL_PENDING: - ret = (long)ctx->ibuf_len; - if (ret == 0) { - if (b->next_bio == NULL) - return (0); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - } - break; - case BIO_C_SET_BUFF_READ_DATA: - if (num > ctx->ibuf_size) { - p1 = OPENSSL_malloc((int)num); - if (p1 == NULL) - goto malloc_error; - if (ctx->ibuf != NULL) - OPENSSL_free(ctx->ibuf); - ctx->ibuf = p1; - } - ctx->ibuf_off = 0; - ctx->ibuf_len = (int)num; - memcpy(ctx->ibuf, ptr, (int)num); - ret = 1; - break; - case BIO_C_SET_BUFF_SIZE: - if (ptr != NULL) { - ip = (int *)ptr; - if (*ip == 0) { - ibs = (int)num; - obs = ctx->obuf_size; - } else { /* if (*ip == 1) */ - - ibs = ctx->ibuf_size; - obs = (int)num; - } - } else { - ibs = (int)num; - obs = (int)num; - } - p1 = ctx->ibuf; - p2 = ctx->obuf; - if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) { - p1 = (char *)OPENSSL_malloc((int)num); - if (p1 == NULL) - goto malloc_error; - } - if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) { - p2 = (char *)OPENSSL_malloc((int)num); - if (p2 == NULL) { - if (p1 != ctx->ibuf) - OPENSSL_free(p1); - goto malloc_error; - } - } - if (ctx->ibuf != p1) { - OPENSSL_free(ctx->ibuf); - ctx->ibuf = p1; - ctx->ibuf_off = 0; - ctx->ibuf_len = 0; - ctx->ibuf_size = ibs; - } - if (ctx->obuf != p2) { - OPENSSL_free(ctx->obuf); - ctx->obuf = p2; - ctx->obuf_off = 0; - ctx->obuf_len = 0; - ctx->obuf_size = obs; - } - break; - case BIO_C_DO_STATE_MACHINE: - if (b->next_bio == NULL) - return (0); - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - - case BIO_CTRL_FLUSH: - if (b->next_bio == NULL) - return (0); - if (ctx->obuf_len <= 0) { - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - - for (;;) { - BIO_clear_retry_flags(b); - if (ctx->obuf_len > 0) { - r = BIO_write(b->next_bio, - &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len); -#if 0 - fprintf(stderr, "FLUSH [%3d] %3d -> %3d\n", ctx->obuf_off, - ctx->obuf_len, r); -#endif - BIO_copy_next_retry(b); - if (r <= 0) - return ((long)r); - ctx->obuf_off += r; - ctx->obuf_len -= r; - } else { - ctx->obuf_len = 0; - ctx->obuf_off = 0; - ret = 1; - break; - } - } - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_DUP: - dbio = (BIO *)ptr; - if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) || - !BIO_set_write_buffer_size(dbio, ctx->obuf_size)) - ret = 0; - break; - default: - if (b->next_bio == NULL) - return (0); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - return (ret); - malloc_error: - BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE); - return (0); -} - -static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return (ret); -} - -static int buffer_gets(BIO *b, char *buf, int size) -{ - BIO_F_BUFFER_CTX *ctx; - int num = 0, i, flag; - char *p; - - ctx = (BIO_F_BUFFER_CTX *)b->ptr; - size--; /* reserve space for a '\0' */ - BIO_clear_retry_flags(b); - - for (;;) { - if (ctx->ibuf_len > 0) { - p = &(ctx->ibuf[ctx->ibuf_off]); - flag = 0; - for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) { - *(buf++) = p[i]; - if (p[i] == '\n') { - flag = 1; - i++; - break; - } - } - num += i; - size -= i; - ctx->ibuf_len -= i; - ctx->ibuf_off += i; - if (flag || size == 0) { - *buf = '\0'; - return (num); - } - } else { /* read another chunk */ - - i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size); - if (i <= 0) { - BIO_copy_next_retry(b); - *buf = '\0'; - if (i < 0) - return ((num > 0) ? num : i); - if (i == 0) - return (num); - } - ctx->ibuf_len = i; - ctx->ibuf_off = 0; - } - } -} - -static int buffer_puts(BIO *b, const char *str) -{ - return (buffer_write(b, str, strlen(str))); -} -/* crypto/bf/bf_cfb64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "blowfish.h" -#include "bf_locl.h" - -/* - * The input and output encrypted as though 64bit cfb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ - -void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, const BF_KEY *schedule, - unsigned char *ivec, int *num, int encrypt) -{ - register BF_LONG v0, v1, t; - register int n = *num; - register long l = length; - BF_LONG ti[2]; - unsigned char *iv, c, cc; - - iv = (unsigned char *)ivec; - if (encrypt) { - while (l--) { - if (n == 0) { - n2l(iv, v0); - ti[0] = v0; - n2l(iv, v1); - ti[1] = v1; - BF_encrypt((BF_LONG *)ti, schedule); - iv = (unsigned char *)ivec; - t = ti[0]; - l2n(t, iv); - t = ti[1]; - l2n(t, iv); - iv = (unsigned char *)ivec; - } - c = *(in++) ^ iv[n]; - *(out++) = c; - iv[n] = c; - n = (n + 1) & 0x07; - } - } else { - while (l--) { - if (n == 0) { - n2l(iv, v0); - ti[0] = v0; - n2l(iv, v1); - ti[1] = v1; - BF_encrypt((BF_LONG *)ti, schedule); - iv = (unsigned char *)ivec; - t = ti[0]; - l2n(t, iv); - t = ti[1]; - l2n(t, iv); - iv = (unsigned char *)ivec; - } - cc = *(in++); - c = iv[n]; - iv[n] = cc; - *(out++) = c ^ cc; - n = (n + 1) & 0x07; - } - } - v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; - *num = n; -} -/* crypto/bf/bf_ecb.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "blowfish.h" -// #include "bf_locl.h" -#include "opensslv.h" - -/* - * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From - * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE - * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) - */ - -const char BF_version[] = "Blowfish" OPENSSL_VERSION_PTEXT; - -const char *BF_options(void) -{ -#ifdef BF_PTR - return ("blowfish(ptr)"); -#elif defined(BF_PTR2) - return ("blowfish(ptr2)"); -#else - return ("blowfish(idx)"); -#endif -} - -void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, - const BF_KEY *key, int encrypt) -{ - BF_LONG l, d[2]; - - n2l(in, l); - d[0] = l; - n2l(in, l); - d[1] = l; - if (encrypt) - BF_encrypt(d, key); - else - BF_decrypt(d, key); - l = d[0]; - l2n(l, out); - l = d[1]; - l2n(l, out); - l = d[0] = d[1] = 0; -} -/* crypto/bf/bf_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "blowfish.h" -// #include "bf_locl.h" - -/* - * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From - * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE - * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) - */ - -#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20) -# error If you set BF_ROUNDS to some value other than 16 or 20, you will have \ -to modify the code. -#endif - -void BF_encrypt(BF_LONG *data, const BF_KEY *key) -{ -#ifndef BF_PTR2 - register BF_LONG l, r; - register const BF_LONG *p, *s; - - p = key->P; - s = &(key->S[0]); - l = data[0]; - r = data[1]; - - l ^= p[0]; - BF_ENC(r, l, s, p[1]); - BF_ENC(l, r, s, p[2]); - BF_ENC(r, l, s, p[3]); - BF_ENC(l, r, s, p[4]); - BF_ENC(r, l, s, p[5]); - BF_ENC(l, r, s, p[6]); - BF_ENC(r, l, s, p[7]); - BF_ENC(l, r, s, p[8]); - BF_ENC(r, l, s, p[9]); - BF_ENC(l, r, s, p[10]); - BF_ENC(r, l, s, p[11]); - BF_ENC(l, r, s, p[12]); - BF_ENC(r, l, s, p[13]); - BF_ENC(l, r, s, p[14]); - BF_ENC(r, l, s, p[15]); - BF_ENC(l, r, s, p[16]); -# if BF_ROUNDS == 20 - BF_ENC(r, l, s, p[17]); - BF_ENC(l, r, s, p[18]); - BF_ENC(r, l, s, p[19]); - BF_ENC(l, r, s, p[20]); -# endif - r ^= p[BF_ROUNDS + 1]; - - data[1] = l & 0xffffffffL; - data[0] = r & 0xffffffffL; -#else - register BF_LONG l, r, t, *k; - - l = data[0]; - r = data[1]; - k = (BF_LONG *)key; - - l ^= k[0]; - BF_ENC(r, l, k, 1); - BF_ENC(l, r, k, 2); - BF_ENC(r, l, k, 3); - BF_ENC(l, r, k, 4); - BF_ENC(r, l, k, 5); - BF_ENC(l, r, k, 6); - BF_ENC(r, l, k, 7); - BF_ENC(l, r, k, 8); - BF_ENC(r, l, k, 9); - BF_ENC(l, r, k, 10); - BF_ENC(r, l, k, 11); - BF_ENC(l, r, k, 12); - BF_ENC(r, l, k, 13); - BF_ENC(l, r, k, 14); - BF_ENC(r, l, k, 15); - BF_ENC(l, r, k, 16); -# if BF_ROUNDS == 20 - BF_ENC(r, l, k, 17); - BF_ENC(l, r, k, 18); - BF_ENC(r, l, k, 19); - BF_ENC(l, r, k, 20); -# endif - r ^= k[BF_ROUNDS + 1]; - - data[1] = l & 0xffffffffL; - data[0] = r & 0xffffffffL; -#endif -} - -#ifndef BF_DEFAULT_OPTIONS - -void BF_decrypt(BF_LONG *data, const BF_KEY *key) -{ -# ifndef BF_PTR2 - register BF_LONG l, r; - register const BF_LONG *p, *s; - - p = key->P; - s = &(key->S[0]); - l = data[0]; - r = data[1]; - - l ^= p[BF_ROUNDS + 1]; -# if BF_ROUNDS == 20 - BF_ENC(r, l, s, p[20]); - BF_ENC(l, r, s, p[19]); - BF_ENC(r, l, s, p[18]); - BF_ENC(l, r, s, p[17]); -# endif - BF_ENC(r, l, s, p[16]); - BF_ENC(l, r, s, p[15]); - BF_ENC(r, l, s, p[14]); - BF_ENC(l, r, s, p[13]); - BF_ENC(r, l, s, p[12]); - BF_ENC(l, r, s, p[11]); - BF_ENC(r, l, s, p[10]); - BF_ENC(l, r, s, p[9]); - BF_ENC(r, l, s, p[8]); - BF_ENC(l, r, s, p[7]); - BF_ENC(r, l, s, p[6]); - BF_ENC(l, r, s, p[5]); - BF_ENC(r, l, s, p[4]); - BF_ENC(l, r, s, p[3]); - BF_ENC(r, l, s, p[2]); - BF_ENC(l, r, s, p[1]); - r ^= p[0]; - - data[1] = l & 0xffffffffL; - data[0] = r & 0xffffffffL; -# else - register BF_LONG l, r, t, *k; - - l = data[0]; - r = data[1]; - k = (BF_LONG *)key; - - l ^= k[BF_ROUNDS + 1]; -# if BF_ROUNDS == 20 - BF_ENC(r, l, k, 20); - BF_ENC(l, r, k, 19); - BF_ENC(r, l, k, 18); - BF_ENC(l, r, k, 17); -# endif - BF_ENC(r, l, k, 16); - BF_ENC(l, r, k, 15); - BF_ENC(r, l, k, 14); - BF_ENC(l, r, k, 13); - BF_ENC(r, l, k, 12); - BF_ENC(l, r, k, 11); - BF_ENC(r, l, k, 10); - BF_ENC(l, r, k, 9); - BF_ENC(r, l, k, 8); - BF_ENC(l, r, k, 7); - BF_ENC(r, l, k, 6); - BF_ENC(l, r, k, 5); - BF_ENC(r, l, k, 4); - BF_ENC(l, r, k, 3); - BF_ENC(r, l, k, 2); - BF_ENC(l, r, k, 1); - r ^= k[0]; - - data[1] = l & 0xffffffffL; - data[0] = r & 0xffffffffL; -# endif -} - -void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, - const BF_KEY *schedule, unsigned char *ivec, int encrypt) -{ - register BF_LONG tin0, tin1; - register BF_LONG tout0, tout1, xor0, xor1; - register long l = length; - BF_LONG tin[2]; - - if (encrypt) { - n2l(ivec, tout0); - n2l(ivec, tout1); - ivec -= 8; - for (l -= 8; l >= 0; l -= 8) { - n2l(in, tin0); - n2l(in, tin1); - tin0 ^= tout0; - tin1 ^= tout1; - tin[0] = tin0; - tin[1] = tin1; - BF_encrypt(tin, schedule); - tout0 = tin[0]; - tout1 = tin[1]; - l2n(tout0, out); - l2n(tout1, out); - } - if (l != -8) { - n2ln(in, tin0, tin1, l + 8); - tin0 ^= tout0; - tin1 ^= tout1; - tin[0] = tin0; - tin[1] = tin1; - BF_encrypt(tin, schedule); - tout0 = tin[0]; - tout1 = tin[1]; - l2n(tout0, out); - l2n(tout1, out); - } - l2n(tout0, ivec); - l2n(tout1, ivec); - } else { - n2l(ivec, xor0); - n2l(ivec, xor1); - ivec -= 8; - for (l -= 8; l >= 0; l -= 8) { - n2l(in, tin0); - n2l(in, tin1); - tin[0] = tin0; - tin[1] = tin1; - BF_decrypt(tin, schedule); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2n(tout0, out); - l2n(tout1, out); - xor0 = tin0; - xor1 = tin1; - } - if (l != -8) { - n2l(in, tin0); - n2l(in, tin1); - tin[0] = tin0; - tin[1] = tin1; - BF_decrypt(tin, schedule); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2nn(tout0, tout1, out, l + 8); - xor0 = tin0; - xor1 = tin1; - } - l2n(xor0, ivec); - l2n(xor1, ivec); - } - tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; - tin[0] = tin[1] = 0; -} - -#endif -/* crypto/bio/bf_buff.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "bio.h" -#include "evp.h" - -static int linebuffer_write(BIO *h, const char *buf, int num); -static int linebuffer_read(BIO *h, char *buf, int size); -static int linebuffer_puts(BIO *h, const char *str); -static int linebuffer_gets(BIO *h, char *str, int size); -static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int linebuffer_new(BIO *h); -static int linebuffer_free(BIO *data); -static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); - -/* A 10k maximum should be enough for most purposes */ -#define DEFAULT_LINEBUFFER_SIZE 1024*10 - -/* #define DEBUG */ - -static BIO_METHOD methods_linebuffer = { - BIO_TYPE_LINEBUFFER, - "linebuffer", - linebuffer_write, - linebuffer_read, - linebuffer_puts, - linebuffer_gets, - linebuffer_ctrl, - linebuffer_new, - linebuffer_free, - linebuffer_callback_ctrl, -}; - -BIO_METHOD *BIO_f_linebuffer(void) -{ - return (&methods_linebuffer); -} - -typedef struct bio_linebuffer_ctx_struct { - char *obuf; /* the output char array */ - int obuf_size; /* how big is the output buffer */ - int obuf_len; /* how many bytes are in it */ -} BIO_LINEBUFFER_CTX; - -static int linebuffer_new(BIO *bi) -{ - BIO_LINEBUFFER_CTX *ctx; - - ctx = (BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX)); - if (ctx == NULL) - return (0); - ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE); - if (ctx->obuf == NULL) { - OPENSSL_free(ctx); - return (0); - } - ctx->obuf_size = DEFAULT_LINEBUFFER_SIZE; - ctx->obuf_len = 0; - - bi->init = 1; - bi->ptr = (char *)ctx; - bi->flags = 0; - return (1); -} - -static int linebuffer_free(BIO *a) -{ - BIO_LINEBUFFER_CTX *b; - - if (a == NULL) - return (0); - b = (BIO_LINEBUFFER_CTX *)a->ptr; - if (b->obuf != NULL) - OPENSSL_free(b->obuf); - OPENSSL_free(a->ptr); - a->ptr = NULL; - a->init = 0; - a->flags = 0; - return (1); -} - -static int linebuffer_read(BIO *b, char *out, int outl) -{ - int ret = 0; - - if (out == NULL) - return (0); - if (b->next_bio == NULL) - return (0); - ret = BIO_read(b->next_bio, out, outl); - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - return (ret); -} - -static int linebuffer_write(BIO *b, const char *in, int inl) -{ - int i, num = 0, foundnl; - BIO_LINEBUFFER_CTX *ctx; - - if ((in == NULL) || (inl <= 0)) - return (0); - ctx = (BIO_LINEBUFFER_CTX *)b->ptr; - if ((ctx == NULL) || (b->next_bio == NULL)) - return (0); - - BIO_clear_retry_flags(b); - - do { - const char *p; - - for (p = in; p < in + inl && *p != '\n'; p++) ; - if (*p == '\n') { - p++; - foundnl = 1; - } else - foundnl = 0; - - /* - * If a NL was found and we already have text in the save buffer, - * concatenate them and write - */ - while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len) - && ctx->obuf_len > 0) { - int orig_olen = ctx->obuf_len; - - i = ctx->obuf_size - ctx->obuf_len; - if (p - in > 0) { - if (i >= p - in) { - memcpy(&(ctx->obuf[ctx->obuf_len]), in, p - in); - ctx->obuf_len += p - in; - inl -= p - in; - num += p - in; - in = p; - } else { - memcpy(&(ctx->obuf[ctx->obuf_len]), in, i); - ctx->obuf_len += i; - inl -= i; - in += i; - num += i; - } - } -#if 0 - BIO_write(b->next_bio, "<*<", 3); -#endif - i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len); - if (i <= 0) { - ctx->obuf_len = orig_olen; - BIO_copy_next_retry(b); - -#if 0 - BIO_write(b->next_bio, ">*>", 3); -#endif - if (i < 0) - return ((num > 0) ? num : i); - if (i == 0) - return (num); - } -#if 0 - BIO_write(b->next_bio, ">*>", 3); -#endif - if (i < ctx->obuf_len) - memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i); - ctx->obuf_len -= i; - } - - /* - * Now that the save buffer is emptied, let's write the input buffer - * if a NL was found and there is anything to write. - */ - if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) { -#if 0 - BIO_write(b->next_bio, "<*<", 3); -#endif - i = BIO_write(b->next_bio, in, p - in); - if (i <= 0) { - BIO_copy_next_retry(b); -#if 0 - BIO_write(b->next_bio, ">*>", 3); -#endif - if (i < 0) - return ((num > 0) ? num : i); - if (i == 0) - return (num); - } -#if 0 - BIO_write(b->next_bio, ">*>", 3); -#endif - num += i; - in += i; - inl -= i; - } - } - while (foundnl && inl > 0); - /* - * We've written as much as we can. The rest of the input buffer, if - * any, is text that doesn't and with a NL and therefore needs to be - * saved for the next trip. - */ - if (inl > 0) { - memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl); - ctx->obuf_len += inl; - num += inl; - } - return num; -} - -static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - BIO *dbio; - BIO_LINEBUFFER_CTX *ctx; - long ret = 1; - char *p; - int r; - int obs; - - ctx = (BIO_LINEBUFFER_CTX *)b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ctx->obuf_len = 0; - if (b->next_bio == NULL) - return (0); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_INFO: - ret = (long)ctx->obuf_len; - break; - case BIO_CTRL_WPENDING: - ret = (long)ctx->obuf_len; - if (ret == 0) { - if (b->next_bio == NULL) - return (0); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - } - break; - case BIO_C_SET_BUFF_SIZE: - obs = (int)num; - p = ctx->obuf; - if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) { - p = (char *)OPENSSL_malloc((int)num); - if (p == NULL) - goto malloc_error; - } - if (ctx->obuf != p) { - if (ctx->obuf_len > obs) { - ctx->obuf_len = obs; - } - memcpy(p, ctx->obuf, ctx->obuf_len); - OPENSSL_free(ctx->obuf); - ctx->obuf = p; - ctx->obuf_size = obs; - } - break; - case BIO_C_DO_STATE_MACHINE: - if (b->next_bio == NULL) - return (0); - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - - case BIO_CTRL_FLUSH: - if (b->next_bio == NULL) - return (0); - if (ctx->obuf_len <= 0) { - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - - for (;;) { - BIO_clear_retry_flags(b); - if (ctx->obuf_len > 0) { - r = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len); -#if 0 - fprintf(stderr, "FLUSH %3d -> %3d\n", ctx->obuf_len, r); -#endif - BIO_copy_next_retry(b); - if (r <= 0) - return ((long)r); - if (r < ctx->obuf_len) - memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r); - ctx->obuf_len -= r; - } else { - ctx->obuf_len = 0; - ret = 1; - break; - } - } - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_DUP: - dbio = (BIO *)ptr; - if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size)) - ret = 0; - break; - default: - if (b->next_bio == NULL) - return (0); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - return (ret); - malloc_error: - BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE); - return (0); -} - -static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return (ret); -} - -static int linebuffer_gets(BIO *b, char *buf, int size) -{ - if (b->next_bio == NULL) - return (0); - return (BIO_gets(b->next_bio, buf, size)); -} - -static int linebuffer_puts(BIO *b, const char *str) -{ - return (linebuffer_write(b, str, strlen(str))); -} -/* crypto/bio/bf_nbio.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -#include "rand.h" -// #include "bio.h" - -/* - * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest - */ - -static int nbiof_write(BIO *h, const char *buf, int num); -static int nbiof_read(BIO *h, char *buf, int size); -static int nbiof_puts(BIO *h, const char *str); -static int nbiof_gets(BIO *h, char *str, int size); -static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int nbiof_new(BIO *h); -static int nbiof_free(BIO *data); -static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -typedef struct nbio_test_st { - /* only set if we sent a 'should retry' error */ - int lrn; - int lwn; -} NBIO_TEST; - -static BIO_METHOD methods_nbiof = { - BIO_TYPE_NBIO_TEST, - "non-blocking IO test filter", - nbiof_write, - nbiof_read, - nbiof_puts, - nbiof_gets, - nbiof_ctrl, - nbiof_new, - nbiof_free, - nbiof_callback_ctrl, -}; - -BIO_METHOD *BIO_f_nbio_test(void) -{ - return (&methods_nbiof); -} - -static int nbiof_new(BIO *bi) -{ - NBIO_TEST *nt; - - if (!(nt = (NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST)))) - return (0); - nt->lrn = -1; - nt->lwn = -1; - bi->ptr = (char *)nt; - bi->init = 1; - bi->flags = 0; - return (1); -} - -static int nbiof_free(BIO *a) -{ - if (a == NULL) - return (0); - if (a->ptr != NULL) - OPENSSL_free(a->ptr); - a->ptr = NULL; - a->init = 0; - a->flags = 0; - return (1); -} - -static int nbiof_read(BIO *b, char *out, int outl) -{ - int ret = 0; -#if 1 - int num; - unsigned char n; -#endif - - if (out == NULL) - return (0); - if (b->next_bio == NULL) - return (0); - - BIO_clear_retry_flags(b); -#if 1 - if (RAND_bytes(&n, 1) <= 0) - return -1; - num = (n & 0x07); - - if (outl > num) - outl = num; - - if (num == 0) { - ret = -1; - BIO_set_retry_read(b); - } else -#endif - { - ret = BIO_read(b->next_bio, out, outl); - if (ret < 0) - BIO_copy_next_retry(b); - } - return (ret); -} - -static int nbiof_write(BIO *b, const char *in, int inl) -{ - NBIO_TEST *nt; - int ret = 0; - int num; - unsigned char n; - - if ((in == NULL) || (inl <= 0)) - return (0); - if (b->next_bio == NULL) - return (0); - nt = (NBIO_TEST *)b->ptr; - - BIO_clear_retry_flags(b); - -#if 1 - if (nt->lwn > 0) { - num = nt->lwn; - nt->lwn = 0; - } else { - if (RAND_bytes(&n, 1) <= 0) - return -1; - num = (n & 7); - } - - if (inl > num) - inl = num; - - if (num == 0) { - ret = -1; - BIO_set_retry_write(b); - } else -#endif - { - ret = BIO_write(b->next_bio, in, inl); - if (ret < 0) { - BIO_copy_next_retry(b); - nt->lwn = inl; - } - } - return (ret); -} - -static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - case BIO_CTRL_DUP: - ret = 0L; - break; - default: - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - return (ret); -} - -static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return (ret); -} - -static int nbiof_gets(BIO *bp, char *buf, int size) -{ - if (bp->next_bio == NULL) - return (0); - return (BIO_gets(bp->next_bio, buf, size)); -} - -static int nbiof_puts(BIO *bp, const char *str) -{ - if (bp->next_bio == NULL) - return (0); - return (BIO_puts(bp->next_bio, str)); -} -/* crypto/bio/bf_null.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "bio.h" - -/* - * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest - */ - -static int nullf_write(BIO *h, const char *buf, int num); -static int nullf_read(BIO *h, char *buf, int size); -static int nullf_puts(BIO *h, const char *str); -static int nullf_gets(BIO *h, char *str, int size); -static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int nullf_new(BIO *h); -static int nullf_free(BIO *data); -static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -static BIO_METHOD methods_nullf = { - BIO_TYPE_NULL_FILTER, - "NULL filter", - nullf_write, - nullf_read, - nullf_puts, - nullf_gets, - nullf_ctrl, - nullf_new, - nullf_free, - nullf_callback_ctrl, -}; - -BIO_METHOD *BIO_f_null(void) -{ - return (&methods_nullf); -} - -static int nullf_new(BIO *bi) -{ - bi->init = 1; - bi->ptr = NULL; - bi->flags = 0; - return (1); -} - -static int nullf_free(BIO *a) -{ - if (a == NULL) - return (0); - /*- - a->ptr=NULL; - a->init=0; - a->flags=0; - */ - return (1); -} - -static int nullf_read(BIO *b, char *out, int outl) -{ - int ret = 0; - - if (out == NULL) - return (0); - if (b->next_bio == NULL) - return (0); - ret = BIO_read(b->next_bio, out, outl); - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - return (ret); -} - -static int nullf_write(BIO *b, const char *in, int inl) -{ - int ret = 0; - - if ((in == NULL) || (inl <= 0)) - return (0); - if (b->next_bio == NULL) - return (0); - ret = BIO_write(b->next_bio, in, inl); - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - return (ret); -} - -static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - case BIO_CTRL_DUP: - ret = 0L; - break; - default: - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - } - return (ret); -} - -static long nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return (ret); -} - -static int nullf_gets(BIO *bp, char *buf, int size) -{ - if (bp->next_bio == NULL) - return (0); - return (BIO_gets(bp->next_bio, buf, size)); -} - -static int nullf_puts(BIO *bp, const char *str) -{ - if (bp->next_bio == NULL) - return (0); - return (BIO_puts(bp->next_bio, str)); -} -/* crypto/bf/bf_ofb64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "blowfish.h" -// #include "bf_locl.h" - -/* - * The input and output encrypted as though 64bit ofb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ -void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, const BF_KEY *schedule, - unsigned char *ivec, int *num) -{ - register BF_LONG v0, v1, t; - register int n = *num; - register long l = length; - unsigned char d[8]; - register char *dp; - BF_LONG ti[2]; - unsigned char *iv; - int save = 0; - - iv = (unsigned char *)ivec; - n2l(iv, v0); - n2l(iv, v1); - ti[0] = v0; - ti[1] = v1; - dp = (char *)d; - l2n(v0, dp); - l2n(v1, dp); - while (l--) { - if (n == 0) { - BF_encrypt((BF_LONG *)ti, schedule); - dp = (char *)d; - t = ti[0]; - l2n(t, dp); - t = ti[1]; - l2n(t, dp); - save++; - } - *(out++) = *(in++) ^ d[n]; - n = (n + 1) & 0x07; - } - if (save) { - v0 = ti[0]; - v1 = ti[1]; - iv = (unsigned char *)ivec; - l2n(v0, iv); - l2n(v1, iv); - } - t = v0 = v1 = ti[0] = ti[1] = 0; - *num = n; -} -/* crypto/bf/bf_skey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "crypto.h" -// #include "blowfish.h" -// #include "bf_locl.h" -#include "bf_pi.h" - -void BF_set_key(BF_KEY *key, int len, const unsigned char *data) -#ifdef OPENSSL_FIPS -{ - fips_cipher_abort(BLOWFISH); - private_BF_set_key(key, len, data); -} - -void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data) -#endif -{ - int i; - BF_LONG *p, ri, in[2]; - const unsigned char *d, *end; - - memcpy(key, &bf_init, sizeof(BF_KEY)); - p = key->P; - - if (len > ((BF_ROUNDS + 2) * 4)) - len = (BF_ROUNDS + 2) * 4; - - d = data; - end = &(data[len]); - for (i = 0; i < (BF_ROUNDS + 2); i++) { - ri = *(d++); - if (d >= end) - d = data; - - ri <<= 8; - ri |= *(d++); - if (d >= end) - d = data; - - ri <<= 8; - ri |= *(d++); - if (d >= end) - d = data; - - ri <<= 8; - ri |= *(d++); - if (d >= end) - d = data; - - p[i] ^= ri; - } - - in[0] = 0L; - in[1] = 0L; - for (i = 0; i < (BF_ROUNDS + 2); i += 2) { - BF_encrypt(in, key); - p[i] = in[0]; - p[i + 1] = in[1]; - } - - p = key->S; - for (i = 0; i < 4 * 256; i += 2) { - BF_encrypt(in, key); - p[i] = in[0]; - p[i + 1] = in[1]; - } -} diff --git a/Sources/COpenSSL/bf_locl.h b/Sources/COpenSSL/bf_locl.h deleted file mode 100644 index 9b0ec73a..00000000 --- a/Sources/COpenSSL/bf_locl.h +++ /dev/null @@ -1,221 +0,0 @@ -/* crypto/bf/bf_locl.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_BF_LOCL_H -# define HEADER_BF_LOCL_H -# include "opensslconf.h"/* BF_PTR, BF_PTR2 */ - -# undef c2l -# define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<<24L) - -/* NOTE - c is not incremented as per c2l */ -# undef c2ln -# define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ - } \ - } - -# undef l2c -# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24L)&0xff)) - -/* NOTE - c is not incremented as per l2c */ -# undef l2cn -# define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -/* NOTE - c is not incremented as per n2l */ -# define n2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c)))) ; \ - case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 6: l2|=((unsigned long)(*(--(c))))<<16; \ - case 5: l2|=((unsigned long)(*(--(c))))<<24; \ - case 4: l1 =((unsigned long)(*(--(c)))) ; \ - case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 2: l1|=((unsigned long)(*(--(c))))<<16; \ - case 1: l1|=((unsigned long)(*(--(c))))<<24; \ - } \ - } - -/* NOTE - c is not incremented as per l2n */ -# define l2nn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - } \ - } - -# undef n2l -# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))) - -# undef l2n -# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -/* - * This is actually a big endian algorithm, the most significant byte is used - * to lookup array 0 - */ - -# if defined(BF_PTR2) - -/* - * This is basically a special Intel version. Point is that Intel - * doesn't have many registers, but offers a reach choice of addressing - * modes. So we spare some registers by directly traversing BF_KEY - * structure and hiring the most decorated addressing mode. The code - * generated by EGCS is *perfectly* competitive with assembler - * implementation! - */ -# define BF_ENC(LL,R,KEY,Pi) (\ - LL^=KEY[Pi], \ - t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \ - t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \ - t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \ - t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \ - LL^=t \ - ) - -# elif defined(BF_PTR) - -# ifndef BF_LONG_LOG2 -# define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */ -# endif -# define BF_M (0xFF<>BF_i)&BF_M gets folded into a single instruction, namely - * rlwinm. So let'em double-check if their compiler does it. - */ - -# define BF_ENC(LL,R,S,P) ( \ - LL^=P, \ - LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \ - *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \ - *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \ - *(BF_LONG *)((unsigned char *)&(S[768])+((R<>24)&0xff)] + \ - S[0x0100+((int)(R>>16)&0xff)])^ \ - S[0x0200+((int)(R>> 8)&0xff)])+ \ - S[0x0300+((int)(R )&0xff)])&0xffffffffL \ - ) -# endif - -#endif diff --git a/Sources/COpenSSL/bf_pi.h b/Sources/COpenSSL/bf_pi.h deleted file mode 100644 index 46a26739..00000000 --- a/Sources/COpenSSL/bf_pi.h +++ /dev/null @@ -1,579 +0,0 @@ -/* crypto/bf/bf_pi.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -static const BF_KEY bf_init = { - { - 0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L, - 0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L, - 0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL, - 0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L, - 0x9216d5d9L, 0x8979fb1b}, { - 0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, - 0xd01adfb7L, - 0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, - 0xf12c7f99L, - 0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, - 0x858efc16L, - 0x636920d8L, 0x71574e69L, 0xa458fea3L, - 0xf4933d7eL, - 0x0d95748fL, 0x728eb658L, 0x718bcd58L, - 0x82154aeeL, - 0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, - 0x2af26013L, - 0xc5d1b023L, 0x286085f0L, 0xca417918L, - 0xb8db38efL, - 0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, - 0xb01e8a3eL, - 0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, - 0x55605c60L, - 0xe65525f3L, 0xaa55ab94L, 0x57489862L, - 0x63e81440L, - 0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, - 0x1141e8ceL, - 0xa15486afL, 0x7c72e993L, 0xb3ee1411L, - 0x636fbc2aL, - 0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, - 0x9b87931eL, - 0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, - 0x28958677L, - 0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, - 0x66282193L, - 0x61d809ccL, 0xfb21a991L, 0x487cac60L, - 0x5dec8032L, - 0xef845d5dL, 0xe98575b1L, 0xdc262302L, - 0xeb651b88L, - 0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, - 0x83f44239L, - 0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, - 0x9e1f9b5eL, - 0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, - 0xabd388f0L, - 0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, - 0xab5133a3L, - 0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, - 0x7efb2a98L, - 0xa1f1651dL, 0x39af0176L, 0x66ca593eL, - 0x82430e88L, - 0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, - 0x3b8b5ebeL, - 0xe06f75d8L, 0x85c12073L, 0x401a449fL, - 0x56c16aa6L, - 0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, - 0x429b023dL, - 0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, - 0x49f1c09bL, - 0x075372c9L, 0x80991b7bL, 0x25d479d8L, - 0xf6e8def7L, - 0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, - 0x04c006baL, - 0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, - 0x196a2463L, - 0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, - 0x3b52ec6fL, - 0x6dfc511fL, 0x9b30952cL, 0xcc814544L, - 0xaf5ebd09L, - 0xbee3d004L, 0xde334afdL, 0x660f2807L, - 0x192e4bb3L, - 0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, - 0xb9d3fbdbL, - 0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, - 0x402c7279L, - 0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, - 0xdb3222f8L, - 0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, - 0xad0552abL, - 0x323db5faL, 0xfd238760L, 0x53317b48L, - 0x3e00df82L, - 0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, - 0xdf1769dbL, - 0xd542a8f6L, 0x287effc3L, 0xac6732c6L, - 0x8c4f5573L, - 0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, - 0xb8f011a0L, - 0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, - 0x2dd1d35bL, - 0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, - 0x4bfb9790L, - 0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, - 0xcee4c6e8L, - 0xef20cadaL, 0x36774c01L, 0xd07e9efeL, - 0x2bf11fb4L, - 0x95dbda4dL, 0xae909198L, 0xeaad8e71L, - 0x6b93d5a0L, - 0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, - 0x8e7594b7L, - 0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, - 0x900df01cL, - 0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, - 0xb3a8c1adL, - 0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, - 0x8b021fa1L, - 0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, - 0xce89e299L, - 0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, - 0xd2ada8d9L, - 0x165fa266L, 0x80957705L, 0x93cc7314L, - 0x211a1477L, - 0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, - 0xfb9d35cfL, - 0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, - 0xae1e7e49L, - 0x00250e2dL, 0x2071b35eL, 0x226800bbL, - 0x57b8e0afL, - 0x2464369bL, 0xf009b91eL, 0x5563911dL, - 0x59dfa6aaL, - 0x78c14389L, 0xd95a537fL, 0x207d5ba2L, - 0x02e5b9c5L, - 0x83260376L, 0x6295cfa9L, 0x11c81968L, - 0x4e734a41L, - 0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, - 0x9a532915L, - 0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, - 0x81e67400L, - 0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, - 0x2a0dd915L, - 0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, - 0xc5855664L, - 0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, - 0x6e85076aL, - 0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, - 0xc4192623L, - 0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, - 0x8fedb266L, - 0xecaa8c71L, 0x699a17ffL, 0x5664526cL, - 0xc2b19ee1L, - 0x193602a5L, 0x75094c29L, 0xa0591340L, - 0xe4183a3eL, - 0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, - 0x99f73fd6L, - 0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, - 0xf0255dc1L, - 0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, - 0x021ecc5eL, - 0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, - 0x6b6a70a1L, - 0x687f3584L, 0x52a0e286L, 0xb79c5305L, - 0xaa500737L, - 0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, - 0x5716f2b8L, - 0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, - 0x0200b3ffL, - 0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, - 0xdc0921bdL, - 0xd19113f9L, 0x7ca92ff6L, 0x94324773L, - 0x22f54701L, - 0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, - 0x9af3dda7L, - 0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, - 0xa4751e41L, - 0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, - 0x183eb331L, - 0x4e548b38L, 0x4f6db908L, 0x6f420d03L, - 0xf60a04bfL, - 0x2cb81290L, 0x24977c79L, 0x5679b072L, - 0xbcaf89afL, - 0xde9a771fL, 0xd9930810L, 0xb38bae12L, - 0xdccf3f2eL, - 0x5512721fL, 0x2e6b7124L, 0x501adde6L, - 0x9f84cd87L, - 0x7a584718L, 0x7408da17L, 0xbc9f9abcL, - 0xe94b7d8cL, - 0xec7aec3aL, 0xdb851dfaL, 0x63094366L, - 0xc464c3d2L, - 0xef1c1847L, 0x3215d908L, 0xdd433b37L, - 0x24c2ba16L, - 0x12a14d43L, 0x2a65c451L, 0x50940002L, - 0x133ae4ddL, - 0x71dff89eL, 0x10314e55L, 0x81ac77d6L, - 0x5f11199bL, - 0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, - 0x5924a509L, - 0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, - 0x1e153c6eL, - 0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, - 0x5a3e2ab3L, - 0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, - 0x99e71d0fL, - 0x803e89d6L, 0x5266c825L, 0x2e4cc978L, - 0x9c10b36aL, - 0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, - 0x1e0a2df4L, - 0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, - 0x19c27960L, - 0x5223a708L, 0xf71312b6L, 0xebadfe6eL, - 0xeac31f66L, - 0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, - 0x018cff28L, - 0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, - 0x68ab9802L, - 0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, - 0x5b6e2f84L, - 0x1521b628L, 0x29076170L, 0xecdd4775L, - 0x619f1510L, - 0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, - 0xaa0363cfL, - 0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, - 0xcbaade14L, - 0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, - 0xb2f3846eL, - 0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, - 0x655abb50L, - 0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, - 0xc021b8f7L, - 0x9b540b19L, 0x875fa099L, 0x95f7997eL, - 0x623d7da8L, - 0xf837889aL, 0x97e32d77L, 0x11ed935fL, - 0x16681281L, - 0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, - 0x7858ba99L, - 0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, - 0x1ac24696L, - 0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, - 0x6dbc3128L, - 0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, - 0xee7c3c73L, - 0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, - 0x203e13e0L, - 0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, - 0xfacb4fd0L, - 0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, - 0x41cd2105L, - 0xd81e799eL, 0x86854dc7L, 0xe44b476aL, - 0x3d816250L, - 0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, - 0xc1c7b6a3L, - 0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, - 0x5692b285L, - 0x095bbf00L, 0xad19489dL, 0x1462b174L, - 0x23820e00L, - 0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, - 0x233f7061L, - 0x3372f092L, 0x8d937e41L, 0xd65fecf1L, - 0x6c223bdbL, - 0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, - 0xce77326eL, - 0xa6078084L, 0x19f8509eL, 0xe8efd855L, - 0x61d99735L, - 0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, - 0x800bcadcL, - 0x9e447a2eL, 0xc3453484L, 0xfdd56705L, - 0x0e1e9ec9L, - 0xdb73dbd3L, 0x105588cdL, 0x675fda79L, - 0xe3674340L, - 0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, - 0xf16dff20L, - 0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, - 0xdb83adf7L, - 0xe93d5a68L, 0x948140f7L, 0xf64c261cL, - 0x94692934L, - 0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, - 0xd4a20068L, - 0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, - 0x500061afL, - 0x1e39f62eL, 0x97244546L, 0x14214f74L, - 0xbf8b8840L, - 0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, - 0x66a02f45L, - 0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, - 0x31cb8504L, - 0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, - 0xabca0a9aL, - 0x28507825L, 0x530429f4L, 0x0a2c86daL, - 0xe9b66dfbL, - 0x68dc1462L, 0xd7486900L, 0x680ec0a4L, - 0x27a18deeL, - 0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, - 0x7af4d6b6L, - 0xaace1e7cL, 0xd3375fecL, 0xce78a399L, - 0x406b2a42L, - 0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, - 0x3b124e8bL, - 0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, - 0xeae397b2L, - 0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, - 0xca7820fbL, - 0xfb0af54eL, 0xd8feb397L, 0x454056acL, - 0xba489527L, - 0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, - 0xd096954bL, - 0x55a867bcL, 0xa1159a58L, 0xcca92963L, - 0x99e1db33L, - 0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, - 0x9029317cL, - 0xfdf8e802L, 0x04272f70L, 0x80bb155cL, - 0x05282ce3L, - 0x95c11548L, 0xe4c66d22L, 0x48c1133fL, - 0xc70f86dcL, - 0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, - 0x5d886e17L, - 0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, - 0x41113564L, - 0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, - 0x1f636c1bL, - 0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, - 0xcad18115L, - 0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, - 0xeebeb922L, - 0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, - 0x2da2f728L, - 0xd0127845L, 0x95b794fdL, 0x647d0862L, - 0xe7ccf5f0L, - 0x5449a36fL, 0x877d48faL, 0xc39dfd27L, - 0xf33e8d1eL, - 0x0a476341L, 0x992eff74L, 0x3a6f6eabL, - 0xf4f8fd37L, - 0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, - 0xdb6e6b0dL, - 0xc67b5510L, 0x6d672c37L, 0x2765d43bL, - 0xdcd0e804L, - 0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, - 0x690fed0bL, - 0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, - 0xd9155ea3L, - 0xbb132f88L, 0x515bad24L, 0x7b9479bfL, - 0x763bd6ebL, - 0x37392eb3L, 0xcc115979L, 0x8026e297L, - 0xf42e312dL, - 0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, - 0x782ef11cL, - 0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, - 0x4bfb6350L, - 0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, - 0xe2e1c3c9L, - 0x44421659L, 0x0a121386L, 0xd90cec6eL, - 0xd5abea2aL, - 0x64af674eL, 0xda86a85fL, 0xbebfe988L, - 0x64e4c3feL, - 0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, - 0x6003604dL, - 0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, - 0xd736fcccL, - 0x83426b33L, 0xf01eab71L, 0xb0804187L, - 0x3c005e5fL, - 0x77a057beL, 0xbde8ae24L, 0x55464299L, - 0xbf582e61L, - 0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, - 0x8789bdc2L, - 0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, - 0x46fcd9b9L, - 0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, - 0x915f95e2L, - 0x466e598eL, 0x20b45770L, 0x8cd55591L, - 0xc902de4cL, - 0xb90bace1L, 0xbb8205d0L, 0x11a86248L, - 0x7574a99eL, - 0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, - 0xc4324633L, - 0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, - 0x1d6efe10L, - 0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, - 0x2868f169L, - 0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, - 0x4fcd7f52L, - 0x50115e01L, 0xa70683faL, 0xa002b5c4L, - 0x0de6d027L, - 0x9af88c27L, 0x773f8641L, 0xc3604c06L, - 0x61a806b5L, - 0xf0177a28L, 0xc0f586e0L, 0x006058aaL, - 0x30dc7d62L, - 0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, - 0xc2c21634L, - 0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, - 0xce591d76L, - 0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, - 0x7c927c24L, - 0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, - 0xd39eb8fcL, - 0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, - 0x4dad0fc4L, - 0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, - 0x6c51133cL, - 0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, - 0xddc6c837L, - 0xd79a3234L, 0x92638212L, 0x670efa8eL, - 0x406000e0L, - 0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, - 0x5ac52d1bL, - 0x5cb0679eL, 0x4fa33742L, 0xd3822740L, - 0x99bc9bbeL, - 0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, - 0xc700c47bL, - 0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, - 0x6a366eb4L, - 0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, - 0x6549c2c8L, - 0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, - 0x4cd04dc6L, - 0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, - 0xbe5ee304L, - 0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, - 0x9a86ee22L, - 0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, - 0x9cf2d0a4L, - 0x83c061baL, 0x9be96a4dL, 0x8fe51550L, - 0xba645bd6L, - 0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, - 0xef5562e9L, - 0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, - 0x77fa0a59L, - 0x80e4a915L, 0x87b08601L, 0x9b09e6adL, - 0x3b3ee593L, - 0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, - 0x022b8b51L, - 0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, - 0x7c7d2d28L, - 0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, - 0x5a88f54cL, - 0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, - 0xed93fa9bL, - 0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, - 0x79132e28L, - 0x785f0191L, 0xed756055L, 0xf7960e44L, - 0xe3d35e8cL, - 0x15056dd4L, 0x88f46dbaL, 0x03a16125L, - 0x0564f0bdL, - 0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, - 0xa93a072aL, - 0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, - 0x26dcf319L, - 0x7533d928L, 0xb155fdf5L, 0x03563482L, - 0x8aba3cbbL, - 0x28517711L, 0xc20ad9f8L, 0xabcc5167L, - 0xccad925fL, - 0x4de81751L, 0x3830dc8eL, 0x379d5862L, - 0x9320f991L, - 0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, - 0x774fbe32L, - 0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, - 0x6413e680L, - 0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, - 0x09072166L, - 0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, - 0x1c20c8aeL, - 0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, - 0x6bb4e3bbL, - 0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, - 0xbcb4cdd5L, - 0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, - 0xbf3c6f47L, - 0xd29be463L, 0x542f5d9eL, 0xaec2771bL, - 0xf64e6370L, - 0x740e0d8dL, 0xe75b1357L, 0xf8721671L, - 0xaf537d5dL, - 0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, - 0x0115af84L, - 0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, - 0xce6ea048L, - 0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, - 0x277227f8L, - 0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, - 0x344525bdL, - 0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, - 0xa01fbac9L, - 0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, - 0xa1e8aac7L, - 0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, - 0xd50ada38L, - 0x0339c32aL, 0xc6913667L, 0x8df9317cL, - 0xe0b12b4fL, - 0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, - 0x27d9459cL, - 0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, - 0x9b941525L, - 0xfae59361L, 0xceb69cebL, 0xc2a86459L, - 0x12baa8d1L, - 0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, - 0xcb03a442L, - 0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, - 0x3278e964L, - 0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, - 0x8971f21eL, - 0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, - 0xc37632d8L, - 0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, - 0x0fe3f11dL, - 0xe54cda54L, 0x1edad891L, 0xce6279cfL, - 0xcd3e7e6fL, - 0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, - 0xf6fb2299L, - 0xf523f357L, 0xa6327623L, 0x93a83531L, - 0x56cccd02L, - 0xacf08162L, 0x5a75ebb5L, 0x6e163697L, - 0x88d273ccL, - 0xde966292L, 0x81b949d0L, 0x4c50901bL, - 0x71c65614L, - 0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, - 0xc3f27b9aL, - 0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, - 0x35bdd2f6L, - 0x71126905L, 0xb2040222L, 0xb6cbcf7cL, - 0xcd769c2bL, - 0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, - 0x2547adf0L, - 0xba38209cL, 0xf746ce76L, 0x77afa1c5L, - 0x20756060L, - 0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, - 0x4cf9aa7eL, - 0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, - 0xd6ebe1f9L, - 0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, - 0xc208e69fL, - 0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, - 0x3ac372e6L, - } -}; diff --git a/Sources/COpenSSL/bio.h b/Sources/COpenSSL/bio.h deleted file mode 100644 index df11a58a..00000000 --- a/Sources/COpenSSL/bio.h +++ /dev/null @@ -1,883 +0,0 @@ -/* crypto/bio/bio.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_BIO_H -# define HEADER_BIO_H - -# include "e_os2.h" - -# ifndef OPENSSL_NO_FP_API -# include -# endif -# include - -# include "crypto.h" - -# ifndef OPENSSL_NO_SCTP -# ifndef OPENSSL_SYS_VMS -# include -# else -# include -# endif -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* These are the 'types' of BIOs */ -# define BIO_TYPE_NONE 0 -# define BIO_TYPE_MEM (1|0x0400) -# define BIO_TYPE_FILE (2|0x0400) - -# define BIO_TYPE_FD (4|0x0400|0x0100) -# define BIO_TYPE_SOCKET (5|0x0400|0x0100) -# define BIO_TYPE_NULL (6|0x0400) -# define BIO_TYPE_SSL (7|0x0200) -# define BIO_TYPE_MD (8|0x0200)/* passive filter */ -# define BIO_TYPE_BUFFER (9|0x0200)/* filter */ -# define BIO_TYPE_CIPHER (10|0x0200)/* filter */ -# define BIO_TYPE_BASE64 (11|0x0200)/* filter */ -# define BIO_TYPE_CONNECT (12|0x0400|0x0100)/* socket - connect */ -# define BIO_TYPE_ACCEPT (13|0x0400|0x0100)/* socket for accept */ -# define BIO_TYPE_PROXY_CLIENT (14|0x0200)/* client proxy BIO */ -# define BIO_TYPE_PROXY_SERVER (15|0x0200)/* server proxy BIO */ -# define BIO_TYPE_NBIO_TEST (16|0x0200)/* server proxy BIO */ -# define BIO_TYPE_NULL_FILTER (17|0x0200) -# define BIO_TYPE_BER (18|0x0200)/* BER -> bin filter */ -# define BIO_TYPE_BIO (19|0x0400)/* (half a) BIO pair */ -# define BIO_TYPE_LINEBUFFER (20|0x0200)/* filter */ -# define BIO_TYPE_DGRAM (21|0x0400|0x0100) -# ifndef OPENSSL_NO_SCTP -# define BIO_TYPE_DGRAM_SCTP (24|0x0400|0x0100) -# endif -# define BIO_TYPE_ASN1 (22|0x0200)/* filter */ -# define BIO_TYPE_COMP (23|0x0200)/* filter */ - -# define BIO_TYPE_DESCRIPTOR 0x0100/* socket, fd, connect or accept */ -# define BIO_TYPE_FILTER 0x0200 -# define BIO_TYPE_SOURCE_SINK 0x0400 - -/* - * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. - * BIO_set_fp(in,stdin,BIO_NOCLOSE); - */ -# define BIO_NOCLOSE 0x00 -# define BIO_CLOSE 0x01 - -/* - * These are used in the following macros and are passed to BIO_ctrl() - */ -# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */ -# define BIO_CTRL_EOF 2/* opt - are we at the eof */ -# define BIO_CTRL_INFO 3/* opt - extra tit-bits */ -# define BIO_CTRL_SET 4/* man - set the 'IO' type */ -# define BIO_CTRL_GET 5/* man - get the 'IO' type */ -# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */ -# define BIO_CTRL_POP 7/* opt - internal, used to signify change */ -# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */ -# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */ -# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */ -# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */ -# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */ -# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */ -/* callback is int cb(BIO *bio,state,ret); */ -# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */ -# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */ - -# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */ - -/* dgram BIO stuff */ -# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */ -# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected - * socket to be passed in */ -# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */ -# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */ -# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */ -# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */ - -# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */ -# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */ - -/* #ifdef IP_MTU_DISCOVER */ -# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */ -/* #endif */ - -# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */ -# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 -# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */ -# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU. - * want to use this if asking - * the kernel fails */ - -# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was - * exceed in the previous write - * operation */ - -# define BIO_CTRL_DGRAM_GET_PEER 46 -# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */ - -# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout - * to adjust socket timeouts */ -# define BIO_CTRL_DGRAM_SET_DONT_FRAG 48 - -# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49 - -# ifndef OPENSSL_NO_SCTP -/* SCTP stuff */ -# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 -# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51 -# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52 -# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53 -# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60 -# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61 -# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62 -# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63 -# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64 -# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65 -# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70 -# endif - -/* modifiers */ -# define BIO_FP_READ 0x02 -# define BIO_FP_WRITE 0x04 -# define BIO_FP_APPEND 0x08 -# define BIO_FP_TEXT 0x10 - -# define BIO_FLAGS_READ 0x01 -# define BIO_FLAGS_WRITE 0x02 -# define BIO_FLAGS_IO_SPECIAL 0x04 -# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) -# define BIO_FLAGS_SHOULD_RETRY 0x08 -# ifndef BIO_FLAGS_UPLINK -/* - * "UPLINK" flag denotes file descriptors provided by application. It - * defaults to 0, as most platforms don't require UPLINK interface. - */ -# define BIO_FLAGS_UPLINK 0 -# endif - -/* Used in BIO_gethostbyname() */ -# define BIO_GHBN_CTRL_HITS 1 -# define BIO_GHBN_CTRL_MISSES 2 -# define BIO_GHBN_CTRL_CACHE_SIZE 3 -# define BIO_GHBN_CTRL_GET_ENTRY 4 -# define BIO_GHBN_CTRL_FLUSH 5 - -/* Mostly used in the SSL BIO */ -/*- - * Not used anymore - * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10 - * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20 - * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40 - */ - -# define BIO_FLAGS_BASE64_NO_NL 0x100 - -/* - * This is used with memory BIOs: it means we shouldn't free up or change the - * data in any way. - */ -# define BIO_FLAGS_MEM_RDONLY 0x200 - -typedef struct bio_st BIO; - -void BIO_set_flags(BIO *b, int flags); -int BIO_test_flags(const BIO *b, int flags); -void BIO_clear_flags(BIO *b, int flags); - -# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) -# define BIO_set_retry_special(b) \ - BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) -# define BIO_set_retry_read(b) \ - BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) -# define BIO_set_retry_write(b) \ - BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) - -/* These are normally used internally in BIOs */ -# define BIO_clear_retry_flags(b) \ - BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) -# define BIO_get_retry_flags(b) \ - BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) - -/* These should be used by the application to tell why we should retry */ -# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) -# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) -# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) -# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) -# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) - -/* - * The next three are used in conjunction with the BIO_should_io_special() - * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int - * *reason); will walk the BIO stack and return the 'reason' for the special - * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return - * the code. - */ -/* - * Returned from the SSL bio when the certificate retrieval code had an error - */ -# define BIO_RR_SSL_X509_LOOKUP 0x01 -/* Returned from the connect BIO when a connect would have blocked */ -# define BIO_RR_CONNECT 0x02 -/* Returned from the accept BIO when an accept would have blocked */ -# define BIO_RR_ACCEPT 0x03 - -/* These are passed by the BIO callback */ -# define BIO_CB_FREE 0x01 -# define BIO_CB_READ 0x02 -# define BIO_CB_WRITE 0x03 -# define BIO_CB_PUTS 0x04 -# define BIO_CB_GETS 0x05 -# define BIO_CB_CTRL 0x06 - -/* - * The callback is called before and after the underling operation, The - * BIO_CB_RETURN flag indicates if it is after the call - */ -# define BIO_CB_RETURN 0x80 -# define BIO_CB_return(a) ((a)|BIO_CB_RETURN) -# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) -# define BIO_cb_post(a) ((a)&BIO_CB_RETURN) - -long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *, - int, long, long); -void BIO_set_callback(BIO *b, - long (*callback) (struct bio_st *, int, const char *, - int, long, long)); -char *BIO_get_callback_arg(const BIO *b); -void BIO_set_callback_arg(BIO *b, char *arg); - -const char *BIO_method_name(const BIO *b); -int BIO_method_type(const BIO *b); - -typedef void bio_info_cb (struct bio_st *, int, const char *, int, long, - long); - -typedef struct bio_method_st { - int type; - const char *name; - int (*bwrite) (BIO *, const char *, int); - int (*bread) (BIO *, char *, int); - int (*bputs) (BIO *, const char *); - int (*bgets) (BIO *, char *, int); - long (*ctrl) (BIO *, int, long, void *); - int (*create) (BIO *); - int (*destroy) (BIO *); - long (*callback_ctrl) (BIO *, int, bio_info_cb *); -} BIO_METHOD; - -struct bio_st { - BIO_METHOD *method; - /* bio, mode, argp, argi, argl, ret */ - long (*callback) (struct bio_st *, int, const char *, int, long, long); - char *cb_arg; /* first argument for the callback */ - int init; - int shutdown; - int flags; /* extra storage */ - int retry_reason; - int num; - void *ptr; - struct bio_st *next_bio; /* used by filter BIOs */ - struct bio_st *prev_bio; /* used by filter BIOs */ - int references; - unsigned long num_read; - unsigned long num_write; - CRYPTO_EX_DATA ex_data; -}; - -DECLARE_STACK_OF(BIO) - -typedef struct bio_f_buffer_ctx_struct { - /*- - * Buffers are setup like this: - * - * <---------------------- size -----------------------> - * +---------------------------------------------------+ - * | consumed | remaining | free space | - * +---------------------------------------------------+ - * <-- off --><------- len -------> - */ - /*- BIO *bio; *//* - * this is now in the BIO struct - */ - int ibuf_size; /* how big is the input buffer */ - int obuf_size; /* how big is the output buffer */ - char *ibuf; /* the char array */ - int ibuf_len; /* how many bytes are in it */ - int ibuf_off; /* write/read offset */ - char *obuf; /* the char array */ - int obuf_len; /* how many bytes are in it */ - int obuf_off; /* write/read offset */ -} BIO_F_BUFFER_CTX; - -/* Prefix and suffix callback in ASN1 BIO */ -typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, - void *parg); - -# ifndef OPENSSL_NO_SCTP -/* SCTP parameter structs */ -struct bio_dgram_sctp_sndinfo { - uint16_t snd_sid; - uint16_t snd_flags; - uint32_t snd_ppid; - uint32_t snd_context; -}; - -struct bio_dgram_sctp_rcvinfo { - uint16_t rcv_sid; - uint16_t rcv_ssn; - uint16_t rcv_flags; - uint32_t rcv_ppid; - uint32_t rcv_tsn; - uint32_t rcv_cumtsn; - uint32_t rcv_context; -}; - -struct bio_dgram_sctp_prinfo { - uint16_t pr_policy; - uint32_t pr_value; -}; -# endif - -/* connect BIO stuff */ -# define BIO_CONN_S_BEFORE 1 -# define BIO_CONN_S_GET_IP 2 -# define BIO_CONN_S_GET_PORT 3 -# define BIO_CONN_S_CREATE_SOCKET 4 -# define BIO_CONN_S_CONNECT 5 -# define BIO_CONN_S_OK 6 -# define BIO_CONN_S_BLOCKED_CONNECT 7 -# define BIO_CONN_S_NBIO 8 -/* - * #define BIO_CONN_get_param_hostname BIO_ctrl - */ - -# define BIO_C_SET_CONNECT 100 -# define BIO_C_DO_STATE_MACHINE 101 -# define BIO_C_SET_NBIO 102 -# define BIO_C_SET_PROXY_PARAM 103 -# define BIO_C_SET_FD 104 -# define BIO_C_GET_FD 105 -# define BIO_C_SET_FILE_PTR 106 -# define BIO_C_GET_FILE_PTR 107 -# define BIO_C_SET_FILENAME 108 -# define BIO_C_SET_SSL 109 -# define BIO_C_GET_SSL 110 -# define BIO_C_SET_MD 111 -# define BIO_C_GET_MD 112 -# define BIO_C_GET_CIPHER_STATUS 113 -# define BIO_C_SET_BUF_MEM 114 -# define BIO_C_GET_BUF_MEM_PTR 115 -# define BIO_C_GET_BUFF_NUM_LINES 116 -# define BIO_C_SET_BUFF_SIZE 117 -# define BIO_C_SET_ACCEPT 118 -# define BIO_C_SSL_MODE 119 -# define BIO_C_GET_MD_CTX 120 -# define BIO_C_GET_PROXY_PARAM 121 -# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */ -# define BIO_C_GET_CONNECT 123 -# define BIO_C_GET_ACCEPT 124 -# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 -# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 -# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 -# define BIO_C_FILE_SEEK 128 -# define BIO_C_GET_CIPHER_CTX 129 -# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input - * value */ -# define BIO_C_SET_BIND_MODE 131 -# define BIO_C_GET_BIND_MODE 132 -# define BIO_C_FILE_TELL 133 -# define BIO_C_GET_SOCKS 134 -# define BIO_C_SET_SOCKS 135 - -# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ -# define BIO_C_GET_WRITE_BUF_SIZE 137 -# define BIO_C_MAKE_BIO_PAIR 138 -# define BIO_C_DESTROY_BIO_PAIR 139 -# define BIO_C_GET_WRITE_GUARANTEE 140 -# define BIO_C_GET_READ_REQUEST 141 -# define BIO_C_SHUTDOWN_WR 142 -# define BIO_C_NREAD0 143 -# define BIO_C_NREAD 144 -# define BIO_C_NWRITE0 145 -# define BIO_C_NWRITE 146 -# define BIO_C_RESET_READ_REQUEST 147 -# define BIO_C_SET_MD_CTX 148 - -# define BIO_C_SET_PREFIX 149 -# define BIO_C_GET_PREFIX 150 -# define BIO_C_SET_SUFFIX 151 -# define BIO_C_GET_SUFFIX 152 - -# define BIO_C_SET_EX_ARG 153 -# define BIO_C_GET_EX_ARG 154 - -# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) -# define BIO_get_app_data(s) BIO_get_ex_data(s,0) - -/* BIO_s_connect() and BIO_s_socks4a_connect() */ -# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) -# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port) -# define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip) -# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) -# define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) -# define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) -# define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) -# define BIO_get_conn_int_port(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) - -# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) - -/* BIO_s_accept() */ -# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) -# define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) -/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ -# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL) -# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) - -# define BIO_BIND_NORMAL 0 -# define BIO_BIND_REUSEADDR_IF_UNUSED 1 -# define BIO_BIND_REUSEADDR 2 -# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) -# define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) - -/* BIO_s_accept() and BIO_s_connect() */ -# define BIO_do_connect(b) BIO_do_handshake(b) -# define BIO_do_accept(b) BIO_do_handshake(b) -# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) - -/* BIO_s_proxy_client() */ -# define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url)) -# define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p)) -/* BIO_set_nbio(b,n) */ -# define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s)) -/* BIO *BIO_get_filter_bio(BIO *bio); */ -# define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)())) -# define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk) -# define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool) - -# define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp) -# define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p)) -# define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url)) -# define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL) - -/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */ -# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) -# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) - -/* BIO_s_file() */ -# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp) -# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp) - -/* BIO_s_fd() and BIO_s_file() */ -# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) -# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) - -/* - * name is cast to lose const, but might be better to route through a - * function so we can do it safely - */ -# ifdef CONST_STRICT -/* - * If you are wondering why this isn't defined, its because CONST_STRICT is - * purely a compile-time kludge to allow const to be checked. - */ -int BIO_read_filename(BIO *b, const char *name); -# else -# define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ - BIO_CLOSE|BIO_FP_READ,(char *)name) -# endif -# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ - BIO_CLOSE|BIO_FP_WRITE,name) -# define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ - BIO_CLOSE|BIO_FP_APPEND,name) -# define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ - BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) - -/* - * WARNING WARNING, this ups the reference count on the read bio of the SSL - * structure. This is because the ssl read BIO is now pointed to by the - * next_bio field in the bio. So when you free the BIO, make sure you are - * doing a BIO_free_all() to catch the underlying BIO. - */ -# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl) -# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) -# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) -# define BIO_set_ssl_renegotiate_bytes(b,num) \ - BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL) -# define BIO_get_num_renegotiates(b) \ - BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL) -# define BIO_set_ssl_renegotiate_timeout(b,seconds) \ - BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL) - -/* defined in evp.h */ -/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */ - -# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) -# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm) -# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp) -# define BIO_set_mem_eof_return(b,v) \ - BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) - -/* For the BIO_f_buffer() type */ -# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) -# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) -# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) -# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) -# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) - -/* Don't use the next one unless you know what you are doing :-) */ -# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) - -# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) -# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) -# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) -# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) -# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) -# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) -/* ...pending macros have inappropriate return type */ -size_t BIO_ctrl_pending(BIO *b); -size_t BIO_ctrl_wpending(BIO *b); -# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) -# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ - cbp) -# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) - -/* For the BIO_f_buffer() type */ -# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) - -/* For BIO_s_bio() */ -# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) -# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) -# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) -# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) -# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) -/* macros with inappropriate type -- but ...pending macros use int too: */ -# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) -# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) -size_t BIO_ctrl_get_write_guarantee(BIO *b); -size_t BIO_ctrl_get_read_request(BIO *b); -int BIO_ctrl_reset_read_request(BIO *b); - -/* ctrl macros for dgram */ -# define BIO_ctrl_dgram_connect(b,peer) \ - (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer) -# define BIO_ctrl_set_connected(b, state, peer) \ - (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer) -# define BIO_dgram_recv_timedout(b) \ - (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) -# define BIO_dgram_send_timedout(b) \ - (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) -# define BIO_dgram_get_peer(b,peer) \ - (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) -# define BIO_dgram_set_peer(b,peer) \ - (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) -# define BIO_dgram_get_mtu_overhead(b) \ - (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) - -/* These two aren't currently implemented */ -/* int BIO_get_ex_num(BIO *bio); */ -/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */ -int BIO_set_ex_data(BIO *bio, int idx, void *data); -void *BIO_get_ex_data(BIO *bio, int idx); -int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -unsigned long BIO_number_read(BIO *bio); -unsigned long BIO_number_written(BIO *bio); - -/* For BIO_f_asn1() */ -int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, - asn1_ps_func *prefix_free); -int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, - asn1_ps_func **pprefix_free); -int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, - asn1_ps_func *suffix_free); -int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, - asn1_ps_func **psuffix_free); - -# ifndef OPENSSL_NO_FP_API -BIO_METHOD *BIO_s_file(void); -BIO *BIO_new_file(const char *filename, const char *mode); -BIO *BIO_new_fp(FILE *stream, int close_flag); -# define BIO_s_file_internal BIO_s_file -# endif -BIO *BIO_new(BIO_METHOD *type); -int BIO_set(BIO *a, BIO_METHOD *type); -int BIO_free(BIO *a); -void BIO_vfree(BIO *a); -int BIO_read(BIO *b, void *data, int len); -int BIO_gets(BIO *bp, char *buf, int size); -int BIO_write(BIO *b, const void *data, int len); -int BIO_puts(BIO *bp, const char *buf); -int BIO_indent(BIO *b, int indent, int max); -long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); -long BIO_callback_ctrl(BIO *b, int cmd, - void (*fp) (struct bio_st *, int, const char *, int, - long, long)); -char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); -long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); -BIO *BIO_push(BIO *b, BIO *append); -BIO *BIO_pop(BIO *b); -void BIO_free_all(BIO *a); -BIO *BIO_find_type(BIO *b, int bio_type); -BIO *BIO_next(BIO *b); -BIO *BIO_get_retry_BIO(BIO *bio, int *reason); -int BIO_get_retry_reason(BIO *bio); -BIO *BIO_dup_chain(BIO *in); - -int BIO_nread0(BIO *bio, char **buf); -int BIO_nread(BIO *bio, char **buf, int num); -int BIO_nwrite0(BIO *bio, char **buf); -int BIO_nwrite(BIO *bio, char **buf, int num); - -long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, - long argl, long ret); - -BIO_METHOD *BIO_s_mem(void); -BIO *BIO_new_mem_buf(const void *buf, int len); -BIO_METHOD *BIO_s_socket(void); -BIO_METHOD *BIO_s_connect(void); -BIO_METHOD *BIO_s_accept(void); -BIO_METHOD *BIO_s_fd(void); -# ifndef OPENSSL_SYS_OS2 -BIO_METHOD *BIO_s_log(void); -# endif -BIO_METHOD *BIO_s_bio(void); -BIO_METHOD *BIO_s_null(void); -BIO_METHOD *BIO_f_null(void); -BIO_METHOD *BIO_f_buffer(void); -# ifdef OPENSSL_SYS_VMS -BIO_METHOD *BIO_f_linebuffer(void); -# endif -BIO_METHOD *BIO_f_nbio_test(void); -# ifndef OPENSSL_NO_DGRAM -BIO_METHOD *BIO_s_datagram(void); -# ifndef OPENSSL_NO_SCTP -BIO_METHOD *BIO_s_datagram_sctp(void); -# endif -# endif - -/* BIO_METHOD *BIO_f_ber(void); */ - -int BIO_sock_should_retry(int i); -int BIO_sock_non_fatal_error(int error); -int BIO_dgram_non_fatal_error(int error); - -int BIO_fd_should_retry(int i); -int BIO_fd_non_fatal_error(int error); -int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), - void *u, const char *s, int len); -int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), - void *u, const char *s, int len, int indent); -int BIO_dump(BIO *b, const char *bytes, int len); -int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); -# ifndef OPENSSL_NO_FP_API -int BIO_dump_fp(FILE *fp, const char *s, int len); -int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); -# endif -int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data, - int datalen); - -struct hostent *BIO_gethostbyname(const char *name); -/*- - * We might want a thread-safe interface too: - * struct hostent *BIO_gethostbyname_r(const char *name, - * struct hostent *result, void *buffer, size_t buflen); - * or something similar (caller allocates a struct hostent, - * pointed to by "result", and additional buffer space for the various - * substructures; if the buffer does not suffice, NULL is returned - * and an appropriate error code is set). - */ -int BIO_sock_error(int sock); -int BIO_socket_ioctl(int fd, long type, void *arg); -int BIO_socket_nbio(int fd, int mode); -int BIO_get_port(const char *str, unsigned short *port_ptr); -int BIO_get_host_ip(const char *str, unsigned char *ip); -int BIO_get_accept_socket(char *host_port, int mode); -int BIO_accept(int sock, char **ip_port); -int BIO_sock_init(void); -void BIO_sock_cleanup(void); -int BIO_set_tcp_ndelay(int sock, int turn_on); - -BIO *BIO_new_socket(int sock, int close_flag); -BIO *BIO_new_dgram(int fd, int close_flag); -# ifndef OPENSSL_NO_SCTP -BIO *BIO_new_dgram_sctp(int fd, int close_flag); -int BIO_dgram_is_sctp(BIO *bio); -int BIO_dgram_sctp_notification_cb(BIO *b, - void (*handle_notifications) (BIO *bio, - void - *context, - void *buf), - void *context); -int BIO_dgram_sctp_wait_for_dry(BIO *b); -int BIO_dgram_sctp_msg_waiting(BIO *b); -# endif -BIO *BIO_new_fd(int fd, int close_flag); -BIO *BIO_new_connect(const char *host_port); -BIO *BIO_new_accept(const char *host_port); - -int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, - BIO **bio2, size_t writebuf2); -/* - * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. - * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default - * value. - */ - -void BIO_copy_next_retry(BIO *b); - -/* - * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); - */ - -# ifdef __GNUC__ -# define __bio_h__attr__ __attribute__ -# else -# define __bio_h__attr__(x) -# endif -int BIO_printf(BIO *bio, const char *format, ...) -__bio_h__attr__((__format__(__printf__, 2, 3))); -int BIO_vprintf(BIO *bio, const char *format, va_list args) -__bio_h__attr__((__format__(__printf__, 2, 0))); -int BIO_snprintf(char *buf, size_t n, const char *format, ...) -__bio_h__attr__((__format__(__printf__, 3, 4))); -int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) -__bio_h__attr__((__format__(__printf__, 3, 0))); -# undef __bio_h__attr__ - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_BIO_strings(void); - -/* Error codes for the BIO functions. */ - -/* Function codes. */ -# define BIO_F_ACPT_STATE 100 -# define BIO_F_BIO_ACCEPT 101 -# define BIO_F_BIO_BER_GET_HEADER 102 -# define BIO_F_BIO_CALLBACK_CTRL 131 -# define BIO_F_BIO_CTRL 103 -# define BIO_F_BIO_GETHOSTBYNAME 120 -# define BIO_F_BIO_GETS 104 -# define BIO_F_BIO_GET_ACCEPT_SOCKET 105 -# define BIO_F_BIO_GET_HOST_IP 106 -# define BIO_F_BIO_GET_PORT 107 -# define BIO_F_BIO_MAKE_PAIR 121 -# define BIO_F_BIO_NEW 108 -# define BIO_F_BIO_NEW_FILE 109 -# define BIO_F_BIO_NEW_MEM_BUF 126 -# define BIO_F_BIO_NREAD 123 -# define BIO_F_BIO_NREAD0 124 -# define BIO_F_BIO_NWRITE 125 -# define BIO_F_BIO_NWRITE0 122 -# define BIO_F_BIO_PUTS 110 -# define BIO_F_BIO_READ 111 -# define BIO_F_BIO_SOCK_INIT 112 -# define BIO_F_BIO_WRITE 113 -# define BIO_F_BUFFER_CTRL 114 -# define BIO_F_CONN_CTRL 127 -# define BIO_F_CONN_STATE 115 -# define BIO_F_DGRAM_SCTP_READ 132 -# define BIO_F_DGRAM_SCTP_WRITE 133 -# define BIO_F_FILE_CTRL 116 -# define BIO_F_FILE_READ 130 -# define BIO_F_LINEBUFFER_CTRL 129 -# define BIO_F_MEM_READ 128 -# define BIO_F_MEM_WRITE 117 -# define BIO_F_SSL_NEW 118 -# define BIO_F_WSASTARTUP 119 - -/* Reason codes. */ -# define BIO_R_ACCEPT_ERROR 100 -# define BIO_R_BAD_FOPEN_MODE 101 -# define BIO_R_BAD_HOSTNAME_LOOKUP 102 -# define BIO_R_BROKEN_PIPE 124 -# define BIO_R_CONNECT_ERROR 103 -# define BIO_R_EOF_ON_MEMORY_BIO 127 -# define BIO_R_ERROR_SETTING_NBIO 104 -# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105 -# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106 -# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 -# define BIO_R_INVALID_ARGUMENT 125 -# define BIO_R_INVALID_IP_ADDRESS 108 -# define BIO_R_IN_USE 123 -# define BIO_R_KEEPALIVE 109 -# define BIO_R_NBIO_CONNECT_ERROR 110 -# define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 -# define BIO_R_NO_HOSTNAME_SPECIFIED 112 -# define BIO_R_NO_PORT_DEFINED 113 -# define BIO_R_NO_PORT_SPECIFIED 114 -# define BIO_R_NO_SUCH_FILE 128 -# define BIO_R_NULL_PARAMETER 115 -# define BIO_R_TAG_MISMATCH 116 -# define BIO_R_UNABLE_TO_BIND_SOCKET 117 -# define BIO_R_UNABLE_TO_CREATE_SOCKET 118 -# define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 -# define BIO_R_UNINITIALIZED 120 -# define BIO_R_UNSUPPORTED_METHOD 121 -# define BIO_R_WRITE_TO_READ_ONLY_BIO 126 -# define BIO_R_WSASTARTUP 122 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/bio_.c b/Sources/COpenSSL/bio_.c deleted file mode 100644 index 41fa1a34..00000000 --- a/Sources/COpenSSL/bio_.c +++ /dev/null @@ -1,4210 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* bio_asn1.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * Experimental ASN1 BIO. When written through the data is converted to an - * ASN1 string type: default is OCTET STRING. Additional functions can be - * provided to add prefix and suffix data. - */ - -#include -#include "bio.h" -#include "asn1.h" - -/* Must be large enough for biggest tag+length */ -#define DEFAULT_ASN1_BUF_SIZE 20 - -typedef enum { - ASN1_STATE_START, - ASN1_STATE_PRE_COPY, - ASN1_STATE_HEADER, - ASN1_STATE_HEADER_COPY, - ASN1_STATE_DATA_COPY, - ASN1_STATE_POST_COPY, - ASN1_STATE_DONE -} asn1_bio_state_t; - -typedef struct BIO_ASN1_EX_FUNCS_st { - asn1_ps_func *ex_func; - asn1_ps_func *ex_free_func; -} BIO_ASN1_EX_FUNCS; - -typedef struct BIO_ASN1_BUF_CTX_t { - /* Internal state */ - asn1_bio_state_t state; - /* Internal buffer */ - unsigned char *buf; - /* Size of buffer */ - int bufsize; - /* Current position in buffer */ - int bufpos; - /* Current buffer length */ - int buflen; - /* Amount of data to copy */ - int copylen; - /* Class and tag to use */ - int asn1_class, asn1_tag; - asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free; - /* Extra buffer for prefix and suffix data */ - unsigned char *ex_buf; - int ex_len; - int ex_pos; - void *ex_arg; -} BIO_ASN1_BUF_CTX; - -static int asn1_bio_write(BIO *h, const char *buf, int num); -static int asn1_bio_read(BIO *h, char *buf, int size); -static int asn1_bio_puts(BIO *h, const char *str); -static int asn1_bio_gets(BIO *h, char *str, int size); -static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int asn1_bio_new(BIO *h); -static int asn1_bio_free(BIO *data); -static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); - -static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size); -static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, - asn1_ps_func *cleanup, asn1_bio_state_t next); -static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, - asn1_ps_func *setup, - asn1_bio_state_t ex_state, - asn1_bio_state_t other_state); - -static BIO_METHOD methods_asn1 = { - BIO_TYPE_ASN1, - "asn1", - asn1_bio_write, - asn1_bio_read, - asn1_bio_puts, - asn1_bio_gets, - asn1_bio_ctrl, - asn1_bio_new, - asn1_bio_free, - asn1_bio_callback_ctrl, -}; - -BIO_METHOD *BIO_f_asn1(void) -{ - return (&methods_asn1); -} - -static int asn1_bio_new(BIO *b) -{ - BIO_ASN1_BUF_CTX *ctx; - ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX)); - if (!ctx) - return 0; - if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) { - OPENSSL_free(ctx); - return 0; - } - b->init = 1; - b->ptr = (char *)ctx; - b->flags = 0; - return 1; -} - -static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) -{ - ctx->buf = OPENSSL_malloc(size); - if (!ctx->buf) - return 0; - ctx->bufsize = size; - ctx->bufpos = 0; - ctx->buflen = 0; - ctx->copylen = 0; - ctx->asn1_class = V_ASN1_UNIVERSAL; - ctx->asn1_tag = V_ASN1_OCTET_STRING; - ctx->ex_buf = NULL; - ctx->ex_len = 0; - ctx->ex_pos = 0; - ctx->state = ASN1_STATE_START; - ctx->prefix = ctx->prefix_free = ctx->suffix = ctx->suffix_free = NULL; - ctx->ex_arg = NULL; - return 1; -} - -static int asn1_bio_free(BIO *b) -{ - BIO_ASN1_BUF_CTX *ctx; - ctx = (BIO_ASN1_BUF_CTX *)b->ptr; - if (ctx == NULL) - return 0; - if (ctx->buf) - OPENSSL_free(ctx->buf); - OPENSSL_free(ctx); - b->init = 0; - b->ptr = NULL; - b->flags = 0; - return 1; -} - -static int asn1_bio_write(BIO *b, const char *in, int inl) -{ - BIO_ASN1_BUF_CTX *ctx; - int wrmax, wrlen, ret; - unsigned char *p; - if (!in || (inl < 0) || (b->next_bio == NULL)) - return 0; - ctx = (BIO_ASN1_BUF_CTX *)b->ptr; - if (ctx == NULL) - return 0; - - wrlen = 0; - ret = -1; - - for (;;) { - switch (ctx->state) { - - /* Setup prefix data, call it */ - case ASN1_STATE_START: - if (!asn1_bio_setup_ex(b, ctx, ctx->prefix, - ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER)) - return 0; - break; - - /* Copy any pre data first */ - case ASN1_STATE_PRE_COPY: - - ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free, - ASN1_STATE_HEADER); - - if (ret <= 0) - goto done; - - break; - - case ASN1_STATE_HEADER: - ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl; - OPENSSL_assert(ctx->buflen <= ctx->bufsize); - p = ctx->buf; - ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class); - ctx->copylen = inl; - ctx->state = ASN1_STATE_HEADER_COPY; - - break; - - case ASN1_STATE_HEADER_COPY: - ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen); - if (ret <= 0) - goto done; - - ctx->buflen -= ret; - if (ctx->buflen) - ctx->bufpos += ret; - else { - ctx->bufpos = 0; - ctx->state = ASN1_STATE_DATA_COPY; - } - - break; - - case ASN1_STATE_DATA_COPY: - - if (inl > ctx->copylen) - wrmax = ctx->copylen; - else - wrmax = inl; - ret = BIO_write(b->next_bio, in, wrmax); - if (ret <= 0) - break; - wrlen += ret; - ctx->copylen -= ret; - in += ret; - inl -= ret; - - if (ctx->copylen == 0) - ctx->state = ASN1_STATE_HEADER; - - if (inl == 0) - goto done; - - break; - - default: - BIO_clear_retry_flags(b); - return 0; - - } - - } - - done: - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - - return (wrlen > 0) ? wrlen : ret; - -} - -static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, - asn1_ps_func *cleanup, asn1_bio_state_t next) -{ - int ret; - if (ctx->ex_len <= 0) - return 1; - for (;;) { - ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len); - if (ret <= 0) - break; - ctx->ex_len -= ret; - if (ctx->ex_len > 0) - ctx->ex_pos += ret; - else { - if (cleanup) - cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); - ctx->state = next; - ctx->ex_pos = 0; - break; - } - } - return ret; -} - -static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, - asn1_ps_func *setup, - asn1_bio_state_t ex_state, - asn1_bio_state_t other_state) -{ - if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) { - BIO_clear_retry_flags(b); - return 0; - } - if (ctx->ex_len > 0) - ctx->state = ex_state; - else - ctx->state = other_state; - return 1; -} - -static int asn1_bio_read(BIO *b, char *in, int inl) -{ - if (!b->next_bio) - return 0; - return BIO_read(b->next_bio, in, inl); -} - -static int asn1_bio_puts(BIO *b, const char *str) -{ - return asn1_bio_write(b, str, strlen(str)); -} - -static int asn1_bio_gets(BIO *b, char *str, int size) -{ - if (!b->next_bio) - return 0; - return BIO_gets(b->next_bio, str, size); -} - -static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - if (b->next_bio == NULL) - return (0); - return BIO_callback_ctrl(b->next_bio, cmd, fp); -} - -static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2) -{ - BIO_ASN1_BUF_CTX *ctx; - BIO_ASN1_EX_FUNCS *ex_func; - long ret = 1; - ctx = (BIO_ASN1_BUF_CTX *)b->ptr; - if (ctx == NULL) - return 0; - switch (cmd) { - - case BIO_C_SET_PREFIX: - ex_func = arg2; - ctx->prefix = ex_func->ex_func; - ctx->prefix_free = ex_func->ex_free_func; - break; - - case BIO_C_GET_PREFIX: - ex_func = arg2; - ex_func->ex_func = ctx->prefix; - ex_func->ex_free_func = ctx->prefix_free; - break; - - case BIO_C_SET_SUFFIX: - ex_func = arg2; - ctx->suffix = ex_func->ex_func; - ctx->suffix_free = ex_func->ex_free_func; - break; - - case BIO_C_GET_SUFFIX: - ex_func = arg2; - ex_func->ex_func = ctx->suffix; - ex_func->ex_free_func = ctx->suffix_free; - break; - - case BIO_C_SET_EX_ARG: - ctx->ex_arg = arg2; - break; - - case BIO_C_GET_EX_ARG: - *(void **)arg2 = ctx->ex_arg; - break; - - case BIO_CTRL_FLUSH: - if (!b->next_bio) - return 0; - - /* Call post function if possible */ - if (ctx->state == ASN1_STATE_HEADER) { - if (!asn1_bio_setup_ex(b, ctx, ctx->suffix, - ASN1_STATE_POST_COPY, ASN1_STATE_DONE)) - return 0; - } - - if (ctx->state == ASN1_STATE_POST_COPY) { - ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free, - ASN1_STATE_DONE); - if (ret <= 0) - return ret; - } - - if (ctx->state == ASN1_STATE_DONE) - return BIO_ctrl(b->next_bio, cmd, arg1, arg2); - else { - BIO_clear_retry_flags(b); - return 0; - } - break; - - default: - if (!b->next_bio) - return 0; - return BIO_ctrl(b->next_bio, cmd, arg1, arg2); - - } - - return ret; -} - -static int asn1_bio_set_ex(BIO *b, int cmd, - asn1_ps_func *ex_func, asn1_ps_func *ex_free_func) -{ - BIO_ASN1_EX_FUNCS extmp; - extmp.ex_func = ex_func; - extmp.ex_free_func = ex_free_func; - return BIO_ctrl(b, cmd, 0, &extmp); -} - -static int asn1_bio_get_ex(BIO *b, int cmd, - asn1_ps_func **ex_func, - asn1_ps_func **ex_free_func) -{ - BIO_ASN1_EX_FUNCS extmp; - int ret; - ret = BIO_ctrl(b, cmd, 0, &extmp); - if (ret > 0) { - *ex_func = extmp.ex_func; - *ex_free_func = extmp.ex_free_func; - } - return ret; -} - -int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, - asn1_ps_func *prefix_free) -{ - return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free); -} - -int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, - asn1_ps_func **pprefix_free) -{ - return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free); -} - -int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, - asn1_ps_func *suffix_free) -{ - return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free); -} - -int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, - asn1_ps_func **psuffix_free) -{ - return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free); -} -/* crypto/evp/bio_b64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "cryptlib.h" -#include "buffer.h" -#include "evp.h" - -static int b64_write(BIO *h, const char *buf, int num); -static int b64_read(BIO *h, char *buf, int size); -static int b64_puts(BIO *h, const char *str); -/* - * static int b64_gets(BIO *h, char *str, int size); - */ -static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int b64_new(BIO *h); -static int b64_free(BIO *data); -static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -#define B64_BLOCK_SIZE 1024 -#define B64_BLOCK_SIZE2 768 -#define B64_NONE 0 -#define B64_ENCODE 1 -#define B64_DECODE 2 - -typedef struct b64_struct { - /* - * BIO *bio; moved to the BIO structure - */ - int buf_len; - int buf_off; - int tmp_len; /* used to find the start when decoding */ - int tmp_nl; /* If true, scan until '\n' */ - int encode; - int start; /* have we started decoding yet? */ - int cont; /* <= 0 when finished */ - EVP_ENCODE_CTX base64; - char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10]; - char tmp[B64_BLOCK_SIZE]; -} BIO_B64_CTX; - -static BIO_METHOD methods_b64 = { - BIO_TYPE_BASE64, "base64 encoding", - b64_write, - b64_read, - b64_puts, - NULL, /* b64_gets, */ - b64_ctrl, - b64_new, - b64_free, - b64_callback_ctrl, -}; - -BIO_METHOD *BIO_f_base64(void) -{ - return (&methods_b64); -} - -static int b64_new(BIO *bi) -{ - BIO_B64_CTX *ctx; - - ctx = (BIO_B64_CTX *)OPENSSL_malloc(sizeof(BIO_B64_CTX)); - if (ctx == NULL) - return (0); - - ctx->buf_len = 0; - ctx->tmp_len = 0; - ctx->tmp_nl = 0; - ctx->buf_off = 0; - ctx->cont = 1; - ctx->start = 1; - ctx->encode = 0; - - bi->init = 1; - bi->ptr = (char *)ctx; - bi->flags = 0; - bi->num = 0; - return (1); -} - -static int b64_free(BIO *a) -{ - if (a == NULL) - return (0); - OPENSSL_free(a->ptr); - a->ptr = NULL; - a->init = 0; - a->flags = 0; - return (1); -} - -static int b64_read(BIO *b, char *out, int outl) -{ - int ret = 0, i, ii, j, k, x, n, num, ret_code = 0; - BIO_B64_CTX *ctx; - unsigned char *p, *q; - - if (out == NULL) - return (0); - ctx = (BIO_B64_CTX *)b->ptr; - - if ((ctx == NULL) || (b->next_bio == NULL)) - return (0); - - BIO_clear_retry_flags(b); - - if (ctx->encode != B64_DECODE) { - ctx->encode = B64_DECODE; - ctx->buf_len = 0; - ctx->buf_off = 0; - ctx->tmp_len = 0; - EVP_DecodeInit(&(ctx->base64)); - } - - /* First check if there are bytes decoded/encoded */ - if (ctx->buf_len > 0) { - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - i = ctx->buf_len - ctx->buf_off; - if (i > outl) - i = outl; - OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf)); - memcpy(out, &(ctx->buf[ctx->buf_off]), i); - ret = i; - out += i; - outl -= i; - ctx->buf_off += i; - if (ctx->buf_len == ctx->buf_off) { - ctx->buf_len = 0; - ctx->buf_off = 0; - } - } - - /* - * At this point, we have room of outl bytes and an empty buffer, so we - * should read in some more. - */ - - ret_code = 0; - while (outl > 0) { - if (ctx->cont <= 0) - break; - - i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]), - B64_BLOCK_SIZE - ctx->tmp_len); - - if (i <= 0) { - ret_code = i; - - /* Should we continue next time we are called? */ - if (!BIO_should_retry(b->next_bio)) { - ctx->cont = i; - /* If buffer empty break */ - if (ctx->tmp_len == 0) - break; - /* Fall through and process what we have */ - else - i = 0; - } - /* else we retry and add more data to buffer */ - else - break; - } - i += ctx->tmp_len; - ctx->tmp_len = i; - - /* - * We need to scan, a line at a time until we have a valid line if we - * are starting. - */ - if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) { - /* ctx->start=1; */ - ctx->tmp_len = 0; - } else if (ctx->start) { - q = p = (unsigned char *)ctx->tmp; - num = 0; - for (j = 0; j < i; j++) { - if (*(q++) != '\n') - continue; - - /* - * due to a previous very long line, we need to keep on - * scanning for a '\n' before we even start looking for - * base64 encoded stuff. - */ - if (ctx->tmp_nl) { - p = q; - ctx->tmp_nl = 0; - continue; - } - - k = EVP_DecodeUpdate(&(ctx->base64), - (unsigned char *)ctx->buf, - &num, p, q - p); - if ((k <= 0) && (num == 0) && (ctx->start)) - EVP_DecodeInit(&ctx->base64); - else { - if (p != (unsigned char *) - &(ctx->tmp[0])) { - i -= (p - (unsigned char *) - &(ctx->tmp[0])); - for (x = 0; x < i; x++) - ctx->tmp[x] = p[x]; - } - EVP_DecodeInit(&ctx->base64); - ctx->start = 0; - break; - } - p = q; - } - - /* we fell off the end without starting */ - if ((j == i) && (num == 0)) { - /* - * Is this is one long chunk?, if so, keep on reading until a - * new line. - */ - if (p == (unsigned char *)&(ctx->tmp[0])) { - /* Check buffer full */ - if (i == B64_BLOCK_SIZE) { - ctx->tmp_nl = 1; - ctx->tmp_len = 0; - } - } else if (p != q) { /* finished on a '\n' */ - n = q - p; - for (ii = 0; ii < n; ii++) - ctx->tmp[ii] = p[ii]; - ctx->tmp_len = n; - } - /* else finished on a '\n' */ - continue; - } else { - ctx->tmp_len = 0; - } - } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) { - /* - * If buffer isn't full and we can retry then restart to read in - * more data. - */ - continue; - } - - if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { - int z, jj; - -#if 0 - jj = (i >> 2) << 2; -#else - jj = i & ~3; /* process per 4 */ -#endif - z = EVP_DecodeBlock((unsigned char *)ctx->buf, - (unsigned char *)ctx->tmp, jj); - if (jj > 2) { - if (ctx->tmp[jj - 1] == '=') { - z--; - if (ctx->tmp[jj - 2] == '=') - z--; - } - } - /* - * z is now number of output bytes and jj is the number consumed - */ - if (jj != i) { - memmove(ctx->tmp, &ctx->tmp[jj], i - jj); - ctx->tmp_len = i - jj; - } - ctx->buf_len = 0; - if (z > 0) { - ctx->buf_len = z; - } - i = z; - } else { - i = EVP_DecodeUpdate(&(ctx->base64), - (unsigned char *)ctx->buf, &ctx->buf_len, - (unsigned char *)ctx->tmp, i); - ctx->tmp_len = 0; - } - /* - * If eof or an error was signalled, then the condition - * 'ctx->cont <= 0' will prevent b64_read() from reading - * more data on subsequent calls. This assignment was - * deleted accidentally in commit 5562cfaca4f3. - */ - ctx->cont = i; - - ctx->buf_off = 0; - if (i < 0) { - ret_code = 0; - ctx->buf_len = 0; - break; - } - - if (ctx->buf_len <= outl) - i = ctx->buf_len; - else - i = outl; - - memcpy(out, ctx->buf, i); - ret += i; - ctx->buf_off = i; - if (ctx->buf_off == ctx->buf_len) { - ctx->buf_len = 0; - ctx->buf_off = 0; - } - outl -= i; - out += i; - } - /* BIO_clear_retry_flags(b); */ - BIO_copy_next_retry(b); - return ((ret == 0) ? ret_code : ret); -} - -static int b64_write(BIO *b, const char *in, int inl) -{ - int ret = 0; - int n; - int i; - BIO_B64_CTX *ctx; - - ctx = (BIO_B64_CTX *)b->ptr; - BIO_clear_retry_flags(b); - - if (ctx->encode != B64_ENCODE) { - ctx->encode = B64_ENCODE; - ctx->buf_len = 0; - ctx->buf_off = 0; - ctx->tmp_len = 0; - EVP_EncodeInit(&(ctx->base64)); - } - - OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf)); - OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - n = ctx->buf_len - ctx->buf_off; - while (n > 0) { - i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); - if (i <= 0) { - BIO_copy_next_retry(b); - return (i); - } - OPENSSL_assert(i <= n); - ctx->buf_off += i; - OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - n -= i; - } - /* at this point all pending data has been written */ - ctx->buf_off = 0; - ctx->buf_len = 0; - - if ((in == NULL) || (inl <= 0)) - return (0); - - while (inl > 0) { - n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl; - - if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { - if (ctx->tmp_len > 0) { - OPENSSL_assert(ctx->tmp_len <= 3); - n = 3 - ctx->tmp_len; - /* - * There's a theoretical possibility for this - */ - if (n > inl) - n = inl; - memcpy(&(ctx->tmp[ctx->tmp_len]), in, n); - ctx->tmp_len += n; - ret += n; - if (ctx->tmp_len < 3) - break; - ctx->buf_len = - EVP_EncodeBlock((unsigned char *)ctx->buf, - (unsigned char *)ctx->tmp, ctx->tmp_len); - OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - /* - * Since we're now done using the temporary buffer, the - * length should be 0'd - */ - ctx->tmp_len = 0; - } else { - if (n < 3) { - memcpy(ctx->tmp, in, n); - ctx->tmp_len = n; - ret += n; - break; - } - n -= n % 3; - ctx->buf_len = - EVP_EncodeBlock((unsigned char *)ctx->buf, - (const unsigned char *)in, n); - OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - ret += n; - } - } else { - EVP_EncodeUpdate(&(ctx->base64), - (unsigned char *)ctx->buf, &ctx->buf_len, - (unsigned char *)in, n); - OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - ret += n; - } - inl -= n; - in += n; - - ctx->buf_off = 0; - n = ctx->buf_len; - while (n > 0) { - i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); - if (i <= 0) { - BIO_copy_next_retry(b); - return ((ret == 0) ? i : ret); - } - OPENSSL_assert(i <= n); - n -= i; - ctx->buf_off += i; - OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - } - ctx->buf_len = 0; - ctx->buf_off = 0; - } - return (ret); -} - -static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - BIO_B64_CTX *ctx; - long ret = 1; - int i; - - ctx = (BIO_B64_CTX *)b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ctx->cont = 1; - ctx->start = 1; - ctx->encode = B64_NONE; - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_EOF: /* More to read */ - if (ctx->cont <= 0) - ret = 1; - else - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_WPENDING: /* More to write in buffer */ - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - ret = ctx->buf_len - ctx->buf_off; - if ((ret == 0) && (ctx->encode != B64_NONE) - && (ctx->base64.num != 0)) - ret = 1; - else if (ret <= 0) - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_PENDING: /* More to read in buffer */ - OPENSSL_assert(ctx->buf_len >= ctx->buf_off); - ret = ctx->buf_len - ctx->buf_off; - if (ret <= 0) - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_FLUSH: - /* do a final write */ - again: - while (ctx->buf_len != ctx->buf_off) { - i = b64_write(b, NULL, 0); - if (i < 0) - return i; - } - if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { - if (ctx->tmp_len != 0) { - ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf, - (unsigned char *)ctx->tmp, - ctx->tmp_len); - ctx->buf_off = 0; - ctx->tmp_len = 0; - goto again; - } - } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) { - ctx->buf_off = 0; - EVP_EncodeFinal(&(ctx->base64), - (unsigned char *)ctx->buf, &(ctx->buf_len)); - /* push out the bytes */ - goto again; - } - /* Finally flush the underlying BIO */ - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - - case BIO_CTRL_DUP: - break; - case BIO_CTRL_INFO: - case BIO_CTRL_GET: - case BIO_CTRL_SET: - default: - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - return (ret); -} - -static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return (ret); -} - -static int b64_puts(BIO *b, const char *str) -{ - return b64_write(b, str, strlen(str)); -} -/* crypto/bio/bio_cb.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -// #include "cryptlib.h" -// #include "bio.h" -#include "err.h" - -long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp, - int argi, long argl, long ret) -{ - BIO *b; - MS_STATIC char buf[256]; - char *p; - long r = 1; - int len; - size_t p_maxlen; - - if (BIO_CB_RETURN & cmd) - r = ret; - - len = BIO_snprintf(buf,sizeof(buf),"BIO[%p]: ",(void *)bio); - - /* Ignore errors and continue printing the other information. */ - if (len < 0) - len = 0; - p = buf + len; - p_maxlen = sizeof(buf) - len; - - switch (cmd) { - case BIO_CB_FREE: - BIO_snprintf(p, p_maxlen, "Free - %s\n", bio->method->name); - break; - case BIO_CB_READ: - if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s fd=%d\n", - bio->num, (unsigned long)argi, - bio->method->name, bio->num); - else - BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s\n", - bio->num, (unsigned long)argi, bio->method->name); - break; - case BIO_CB_WRITE: - if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s fd=%d\n", - bio->num, (unsigned long)argi, - bio->method->name, bio->num); - else - BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s\n", - bio->num, (unsigned long)argi, bio->method->name); - break; - case BIO_CB_PUTS: - BIO_snprintf(p, p_maxlen, "puts() - %s\n", bio->method->name); - break; - case BIO_CB_GETS: - BIO_snprintf(p, p_maxlen, "gets(%lu) - %s\n", (unsigned long)argi, - bio->method->name); - break; - case BIO_CB_CTRL: - BIO_snprintf(p, p_maxlen, "ctrl(%lu) - %s\n", (unsigned long)argi, - bio->method->name); - break; - case BIO_CB_RETURN | BIO_CB_READ: - BIO_snprintf(p, p_maxlen, "read return %ld\n", ret); - break; - case BIO_CB_RETURN | BIO_CB_WRITE: - BIO_snprintf(p, p_maxlen, "write return %ld\n", ret); - break; - case BIO_CB_RETURN | BIO_CB_GETS: - BIO_snprintf(p, p_maxlen, "gets return %ld\n", ret); - break; - case BIO_CB_RETURN | BIO_CB_PUTS: - BIO_snprintf(p, p_maxlen, "puts return %ld\n", ret); - break; - case BIO_CB_RETURN | BIO_CB_CTRL: - BIO_snprintf(p, p_maxlen, "ctrl return %ld\n", ret); - break; - default: - BIO_snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd); - break; - } - - b = (BIO *)bio->cb_arg; - if (b != NULL) - BIO_write(b, buf, strlen(buf)); -#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) - else - fputs(buf, stderr); -#endif - return (r); -} -/* crypto/evp/bio_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "evp.h" - -static int enc_write(BIO *h, const char *buf, int num); -static int enc_read(BIO *h, char *buf, int size); -/* - * static int enc_puts(BIO *h, const char *str); - */ -/* - * static int enc_gets(BIO *h, char *str, int size); - */ -static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int enc_new(BIO *h); -static int enc_free(BIO *data); -static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps); -#define ENC_BLOCK_SIZE (1024*4) -#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2) - -typedef struct enc_struct { - int buf_len; - int buf_off; - int cont; /* <= 0 when finished */ - int finished; - int ok; /* bad decrypt */ - EVP_CIPHER_CTX cipher; - /* - * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return - * up to a block more data than is presented to it - */ - char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2]; -} BIO_ENC_CTX; - -static BIO_METHOD methods_enc = { - BIO_TYPE_CIPHER, "cipher", - enc_write, - enc_read, - NULL, /* enc_puts, */ - NULL, /* enc_gets, */ - enc_ctrl, - enc_new, - enc_free, - enc_callback_ctrl, -}; - -BIO_METHOD *BIO_f_cipher(void) -{ - return (&methods_enc); -} - -static int enc_new(BIO *bi) -{ - BIO_ENC_CTX *ctx; - - ctx = (BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX)); - if (ctx == NULL) - return (0); - EVP_CIPHER_CTX_init(&ctx->cipher); - - ctx->buf_len = 0; - ctx->buf_off = 0; - ctx->cont = 1; - ctx->finished = 0; - ctx->ok = 1; - - bi->init = 0; - bi->ptr = (char *)ctx; - bi->flags = 0; - return (1); -} - -static int enc_free(BIO *a) -{ - BIO_ENC_CTX *b; - - if (a == NULL) - return (0); - b = (BIO_ENC_CTX *)a->ptr; - EVP_CIPHER_CTX_cleanup(&(b->cipher)); - OPENSSL_cleanse(a->ptr, sizeof(BIO_ENC_CTX)); - OPENSSL_free(a->ptr); - a->ptr = NULL; - a->init = 0; - a->flags = 0; - return (1); -} - -static int enc_read(BIO *b, char *out, int outl) -{ - int ret = 0, i; - BIO_ENC_CTX *ctx; - - if (out == NULL) - return (0); - ctx = (BIO_ENC_CTX *)b->ptr; - - if ((ctx == NULL) || (b->next_bio == NULL)) - return (0); - - /* First check if there are bytes decoded/encoded */ - if (ctx->buf_len > 0) { - i = ctx->buf_len - ctx->buf_off; - if (i > outl) - i = outl; - memcpy(out, &(ctx->buf[ctx->buf_off]), i); - ret = i; - out += i; - outl -= i; - ctx->buf_off += i; - if (ctx->buf_len == ctx->buf_off) { - ctx->buf_len = 0; - ctx->buf_off = 0; - } - } - - /* - * At this point, we have room of outl bytes and an empty buffer, so we - * should read in some more. - */ - - while (outl > 0) { - if (ctx->cont <= 0) - break; - - /* - * read in at IV offset, read the EVP_Cipher documentation about why - */ - i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE); - - if (i <= 0) { - /* Should be continue next time we are called? */ - if (!BIO_should_retry(b->next_bio)) { - ctx->cont = i; - i = EVP_CipherFinal_ex(&(ctx->cipher), - (unsigned char *)ctx->buf, - &(ctx->buf_len)); - ctx->ok = i; - ctx->buf_off = 0; - } else { - ret = (ret == 0) ? i : ret; - break; - } - } else { - if (!EVP_CipherUpdate(&ctx->cipher, - (unsigned char *)ctx->buf, &ctx->buf_len, - (unsigned char *)&(ctx->buf[BUF_OFFSET]), - i)) { - BIO_clear_retry_flags(b); - ctx->ok = 0; - return 0; - } - ctx->cont = 1; - /* - * Note: it is possible for EVP_CipherUpdate to decrypt zero - * bytes because this is or looks like the final block: if this - * happens we should retry and either read more data or decrypt - * the final block - */ - if (ctx->buf_len == 0) - continue; - } - - if (ctx->buf_len <= outl) - i = ctx->buf_len; - else - i = outl; - if (i <= 0) - break; - memcpy(out, ctx->buf, i); - ret += i; - ctx->buf_off = i; - outl -= i; - out += i; - } - - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - return ((ret == 0) ? ctx->cont : ret); -} - -static int enc_write(BIO *b, const char *in, int inl) -{ - int ret = 0, n, i; - BIO_ENC_CTX *ctx; - - ctx = (BIO_ENC_CTX *)b->ptr; - ret = inl; - - BIO_clear_retry_flags(b); - n = ctx->buf_len - ctx->buf_off; - while (n > 0) { - i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); - if (i <= 0) { - BIO_copy_next_retry(b); - return (i); - } - ctx->buf_off += i; - n -= i; - } - /* at this point all pending data has been written */ - - if ((in == NULL) || (inl <= 0)) - return (0); - - ctx->buf_off = 0; - while (inl > 0) { - n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl; - if (!EVP_CipherUpdate(&ctx->cipher, - (unsigned char *)ctx->buf, &ctx->buf_len, - (unsigned char *)in, n)) { - BIO_clear_retry_flags(b); - ctx->ok = 0; - return 0; - } - inl -= n; - in += n; - - ctx->buf_off = 0; - n = ctx->buf_len; - while (n > 0) { - i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); - if (i <= 0) { - BIO_copy_next_retry(b); - return (ret == inl) ? i : ret - inl; - } - n -= i; - ctx->buf_off += i; - } - ctx->buf_len = 0; - ctx->buf_off = 0; - } - BIO_copy_next_retry(b); - return (ret); -} - -static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - BIO *dbio; - BIO_ENC_CTX *ctx, *dctx; - long ret = 1; - int i; - EVP_CIPHER_CTX **c_ctx; - - ctx = (BIO_ENC_CTX *)b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ctx->ok = 1; - ctx->finished = 0; - EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL, - ctx->cipher.encrypt); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_EOF: /* More to read */ - if (ctx->cont <= 0) - ret = 1; - else - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_WPENDING: - ret = ctx->buf_len - ctx->buf_off; - if (ret <= 0) - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_PENDING: /* More to read in buffer */ - ret = ctx->buf_len - ctx->buf_off; - if (ret <= 0) - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_FLUSH: - /* do a final write */ - again: - while (ctx->buf_len != ctx->buf_off) { - i = enc_write(b, NULL, 0); - if (i < 0) - return i; - } - - if (!ctx->finished) { - ctx->finished = 1; - ctx->buf_off = 0; - ret = EVP_CipherFinal_ex(&(ctx->cipher), - (unsigned char *)ctx->buf, - &(ctx->buf_len)); - ctx->ok = (int)ret; - if (ret <= 0) - break; - - /* push out the bytes */ - goto again; - } - - /* Finally flush the underlying BIO */ - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_C_GET_CIPHER_STATUS: - ret = (long)ctx->ok; - break; - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - case BIO_C_GET_CIPHER_CTX: - c_ctx = (EVP_CIPHER_CTX **)ptr; - (*c_ctx) = &(ctx->cipher); - b->init = 1; - break; - case BIO_CTRL_DUP: - dbio = (BIO *)ptr; - dctx = (BIO_ENC_CTX *)dbio->ptr; - EVP_CIPHER_CTX_init(&dctx->cipher); - ret = EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher); - if (ret) - dbio->init = 1; - break; - default: - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - return (ret); -} - -static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return (ret); -} - -/*- -void BIO_set_cipher_ctx(b,c) -BIO *b; -EVP_CIPHER_ctx *c; - { - if (b == NULL) return; - - if ((b->callback != NULL) && - (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0)) - return; - - b->init=1; - ctx=(BIO_ENC_CTX *)b->ptr; - memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX)); - - if (b->callback != NULL) - b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L); - } -*/ - -void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, - const unsigned char *i, int e) -{ - BIO_ENC_CTX *ctx; - - if (b == NULL) - return; - - if ((b->callback != NULL) && - (b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <= - 0)) - return; - - b->init = 1; - ctx = (BIO_ENC_CTX *)b->ptr; - EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e); - - if (b->callback != NULL) - b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L); -} -/* crypto/bio/bio_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -// #include "err.h" -// #include "bio.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason) - -static ERR_STRING_DATA BIO_str_functs[] = { - {ERR_FUNC(BIO_F_ACPT_STATE), "ACPT_STATE"}, - {ERR_FUNC(BIO_F_BIO_ACCEPT), "BIO_accept"}, - {ERR_FUNC(BIO_F_BIO_BER_GET_HEADER), "BIO_BER_GET_HEADER"}, - {ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL), "BIO_callback_ctrl"}, - {ERR_FUNC(BIO_F_BIO_CTRL), "BIO_ctrl"}, - {ERR_FUNC(BIO_F_BIO_GETHOSTBYNAME), "BIO_gethostbyname"}, - {ERR_FUNC(BIO_F_BIO_GETS), "BIO_gets"}, - {ERR_FUNC(BIO_F_BIO_GET_ACCEPT_SOCKET), "BIO_get_accept_socket"}, - {ERR_FUNC(BIO_F_BIO_GET_HOST_IP), "BIO_get_host_ip"}, - {ERR_FUNC(BIO_F_BIO_GET_PORT), "BIO_get_port"}, - {ERR_FUNC(BIO_F_BIO_MAKE_PAIR), "BIO_MAKE_PAIR"}, - {ERR_FUNC(BIO_F_BIO_NEW), "BIO_new"}, - {ERR_FUNC(BIO_F_BIO_NEW_FILE), "BIO_new_file"}, - {ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF), "BIO_new_mem_buf"}, - {ERR_FUNC(BIO_F_BIO_NREAD), "BIO_nread"}, - {ERR_FUNC(BIO_F_BIO_NREAD0), "BIO_nread0"}, - {ERR_FUNC(BIO_F_BIO_NWRITE), "BIO_nwrite"}, - {ERR_FUNC(BIO_F_BIO_NWRITE0), "BIO_nwrite0"}, - {ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"}, - {ERR_FUNC(BIO_F_BIO_READ), "BIO_read"}, - {ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"}, - {ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"}, - {ERR_FUNC(BIO_F_BUFFER_CTRL), "BUFFER_CTRL"}, - {ERR_FUNC(BIO_F_CONN_CTRL), "CONN_CTRL"}, - {ERR_FUNC(BIO_F_CONN_STATE), "CONN_STATE"}, - {ERR_FUNC(BIO_F_DGRAM_SCTP_READ), "DGRAM_SCTP_READ"}, - {ERR_FUNC(BIO_F_DGRAM_SCTP_WRITE), "DGRAM_SCTP_WRITE"}, - {ERR_FUNC(BIO_F_FILE_CTRL), "FILE_CTRL"}, - {ERR_FUNC(BIO_F_FILE_READ), "FILE_READ"}, - {ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "LINEBUFFER_CTRL"}, - {ERR_FUNC(BIO_F_MEM_READ), "MEM_READ"}, - {ERR_FUNC(BIO_F_MEM_WRITE), "MEM_WRITE"}, - {ERR_FUNC(BIO_F_SSL_NEW), "SSL_new"}, - {ERR_FUNC(BIO_F_WSASTARTUP), "WSASTARTUP"}, - {0, NULL} -}; - -static ERR_STRING_DATA BIO_str_reasons[] = { - {ERR_REASON(BIO_R_ACCEPT_ERROR), "accept error"}, - {ERR_REASON(BIO_R_BAD_FOPEN_MODE), "bad fopen mode"}, - {ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP), "bad hostname lookup"}, - {ERR_REASON(BIO_R_BROKEN_PIPE), "broken pipe"}, - {ERR_REASON(BIO_R_CONNECT_ERROR), "connect error"}, - {ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO), "EOF on memory BIO"}, - {ERR_REASON(BIO_R_ERROR_SETTING_NBIO), "error setting nbio"}, - {ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET), - "error setting nbio on accepted socket"}, - {ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET), - "error setting nbio on accept socket"}, - {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), - "gethostbyname addr is not af inet"}, - {ERR_REASON(BIO_R_INVALID_ARGUMENT), "invalid argument"}, - {ERR_REASON(BIO_R_INVALID_IP_ADDRESS), "invalid ip address"}, - {ERR_REASON(BIO_R_IN_USE), "in use"}, - {ERR_REASON(BIO_R_KEEPALIVE), "keepalive"}, - {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"}, - {ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED), "no accept port specified"}, - {ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED), "no hostname specified"}, - {ERR_REASON(BIO_R_NO_PORT_DEFINED), "no port defined"}, - {ERR_REASON(BIO_R_NO_PORT_SPECIFIED), "no port specified"}, - {ERR_REASON(BIO_R_NO_SUCH_FILE), "no such file"}, - {ERR_REASON(BIO_R_NULL_PARAMETER), "null parameter"}, - {ERR_REASON(BIO_R_TAG_MISMATCH), "tag mismatch"}, - {ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"}, - {ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"}, - {ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"}, - {ERR_REASON(BIO_R_UNINITIALIZED), "uninitialized"}, - {ERR_REASON(BIO_R_UNSUPPORTED_METHOD), "unsupported method"}, - {ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"}, - {ERR_REASON(BIO_R_WSASTARTUP), "WSAStartup"}, - {0, NULL} -}; - -#endif - -void ERR_load_BIO_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) { - ERR_load_strings(0, BIO_str_functs); - ERR_load_strings(0, BIO_str_reasons); - } -#endif -} -/* crypto/bio/bio_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "crypto.h" -// #include "cryptlib.h" -// #include "bio.h" -#include "stack.h" - -BIO *BIO_new(BIO_METHOD *method) -{ - BIO *ret = NULL; - - ret = (BIO *)OPENSSL_malloc(sizeof(BIO)); - if (ret == NULL) { - BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - if (!BIO_set(ret, method)) { - OPENSSL_free(ret); - ret = NULL; - } - return (ret); -} - -int BIO_set(BIO *bio, BIO_METHOD *method) -{ - bio->method = method; - bio->callback = NULL; - bio->cb_arg = NULL; - bio->init = 0; - bio->shutdown = 1; - bio->flags = 0; - bio->retry_reason = 0; - bio->num = 0; - bio->ptr = NULL; - bio->prev_bio = NULL; - bio->next_bio = NULL; - bio->references = 1; - bio->num_read = 0L; - bio->num_write = 0L; - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); - if (method->create != NULL) - if (!method->create(bio)) { - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); - return (0); - } - return (1); -} - -int BIO_free(BIO *a) -{ - int i; - - if (a == NULL) - return (0); - - i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO); -#ifdef REF_PRINT - REF_PRINT("BIO", a); -#endif - if (i > 0) - return (1); -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "BIO_free, bad reference count\n"); - abort(); - } -#endif - if ((a->callback != NULL) && - ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0)) - return (i); - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); - - if ((a->method != NULL) && (a->method->destroy != NULL)) - a->method->destroy(a); - OPENSSL_free(a); - return (1); -} - -void BIO_vfree(BIO *a) -{ - BIO_free(a); -} - -void BIO_clear_flags(BIO *b, int flags) -{ - b->flags &= ~flags; -} - -int BIO_test_flags(const BIO *b, int flags) -{ - return (b->flags & flags); -} - -void BIO_set_flags(BIO *b, int flags) -{ - b->flags |= flags; -} - -long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *, - int, long, long) { - return b->callback; -} - -void BIO_set_callback(BIO *b, - long (*cb) (struct bio_st *, int, const char *, int, - long, long)) -{ - b->callback = cb; -} - -void BIO_set_callback_arg(BIO *b, char *arg) -{ - b->cb_arg = arg; -} - -char *BIO_get_callback_arg(const BIO *b) -{ - return b->cb_arg; -} - -const char *BIO_method_name(const BIO *b) -{ - return b->method->name; -} - -int BIO_method_type(const BIO *b) -{ - return b->method->type; -} - -int BIO_read(BIO *b, void *out, int outl) -{ - int i; - long (*cb) (BIO *, int, const char *, int, long, long); - - if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { - BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD); - return (-2); - } - - cb = b->callback; - if ((cb != NULL) && - ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0)) - return (i); - - if (!b->init) { - BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED); - return (-2); - } - - i = b->method->bread(b, out, outl); - - if (i > 0) - b->num_read += (unsigned long)i; - - if (cb != NULL) - i = (int)cb(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0L, (long)i); - return (i); -} - -int BIO_write(BIO *b, const void *in, int inl) -{ - int i; - long (*cb) (BIO *, int, const char *, int, long, long); - - if (b == NULL) - return (0); - - cb = b->callback; - if ((b->method == NULL) || (b->method->bwrite == NULL)) { - BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD); - return (-2); - } - - if ((cb != NULL) && - ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0)) - return (i); - - if (!b->init) { - BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED); - return (-2); - } - - i = b->method->bwrite(b, in, inl); - - if (i > 0) - b->num_write += (unsigned long)i; - - if (cb != NULL) - i = (int)cb(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0L, (long)i); - return (i); -} - -int BIO_puts(BIO *b, const char *in) -{ - int i; - long (*cb) (BIO *, int, const char *, int, long, long); - - if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) { - BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD); - return (-2); - } - - cb = b->callback; - - if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0)) - return (i); - - if (!b->init) { - BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED); - return (-2); - } - - i = b->method->bputs(b, in); - - if (i > 0) - b->num_write += (unsigned long)i; - - if (cb != NULL) - i = (int)cb(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0L, (long)i); - return (i); -} - -int BIO_gets(BIO *b, char *in, int inl) -{ - int i; - long (*cb) (BIO *, int, const char *, int, long, long); - - if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { - BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD); - return (-2); - } - - cb = b->callback; - - if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0)) - return (i); - - if (!b->init) { - BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED); - return (-2); - } - - i = b->method->bgets(b, in, inl); - - if (cb != NULL) - i = (int)cb(b, BIO_CB_GETS | BIO_CB_RETURN, in, inl, 0L, (long)i); - return (i); -} - -int BIO_indent(BIO *b, int indent, int max) -{ - if (indent < 0) - indent = 0; - if (indent > max) - indent = max; - while (indent--) - if (BIO_puts(b, " ") != 1) - return 0; - return 1; -} - -long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) -{ - int i; - - i = iarg; - return (BIO_ctrl(b, cmd, larg, (char *)&i)); -} - -char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) -{ - char *p = NULL; - - if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0) - return (NULL); - else - return (p); -} - -long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) -{ - long ret; - long (*cb) (BIO *, int, const char *, int, long, long); - - if (b == NULL) - return (0); - - if ((b->method == NULL) || (b->method->ctrl == NULL)) { - BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD); - return (-2); - } - - cb = b->callback; - - if ((cb != NULL) && - ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0)) - return (ret); - - ret = b->method->ctrl(b, cmd, larg, parg); - - if (cb != NULL) - ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret); - return (ret); -} - -long BIO_callback_ctrl(BIO *b, int cmd, - void (*fp) (struct bio_st *, int, const char *, int, - long, long)) -{ - long ret; - long (*cb) (BIO *, int, const char *, int, long, long); - - if (b == NULL) - return (0); - - if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) { - BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD); - return (-2); - } - - cb = b->callback; - - if ((cb != NULL) && - ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0)) - return (ret); - - ret = b->method->callback_ctrl(b, cmd, fp); - - if (cb != NULL) - ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret); - return (ret); -} - -/* - * It is unfortunate to duplicate in functions what the BIO_(w)pending macros - * do; but those macros have inappropriate return type, and for interfacing - * from other programming languages, C macros aren't much of a help anyway. - */ -size_t BIO_ctrl_pending(BIO *bio) -{ - return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); -} - -size_t BIO_ctrl_wpending(BIO *bio) -{ - return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); -} - -/* put the 'bio' on the end of b's list of operators */ -BIO *BIO_push(BIO *b, BIO *bio) -{ - BIO *lb; - - if (b == NULL) - return (bio); - lb = b; - while (lb->next_bio != NULL) - lb = lb->next_bio; - lb->next_bio = bio; - if (bio != NULL) - bio->prev_bio = lb; - /* called to do internal processing */ - BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb); - return (b); -} - -/* Remove the first and return the rest */ -BIO *BIO_pop(BIO *b) -{ - BIO *ret; - - if (b == NULL) - return (NULL); - ret = b->next_bio; - - BIO_ctrl(b, BIO_CTRL_POP, 0, b); - - if (b->prev_bio != NULL) - b->prev_bio->next_bio = b->next_bio; - if (b->next_bio != NULL) - b->next_bio->prev_bio = b->prev_bio; - - b->next_bio = NULL; - b->prev_bio = NULL; - return (ret); -} - -BIO *BIO_get_retry_BIO(BIO *bio, int *reason) -{ - BIO *b, *last; - - b = last = bio; - for (;;) { - if (!BIO_should_retry(b)) - break; - last = b; - b = b->next_bio; - if (b == NULL) - break; - } - if (reason != NULL) - *reason = last->retry_reason; - return (last); -} - -int BIO_get_retry_reason(BIO *bio) -{ - return (bio->retry_reason); -} - -BIO *BIO_find_type(BIO *bio, int type) -{ - int mt, mask; - - if (!bio) - return NULL; - mask = type & 0xff; - do { - if (bio->method != NULL) { - mt = bio->method->type; - - if (!mask) { - if (mt & type) - return (bio); - } else if (mt == type) - return (bio); - } - bio = bio->next_bio; - } while (bio != NULL); - return (NULL); -} - -BIO *BIO_next(BIO *b) -{ - if (!b) - return NULL; - return b->next_bio; -} - -void BIO_free_all(BIO *bio) -{ - BIO *b; - int ref; - - while (bio != NULL) { - b = bio; - ref = b->references; - bio = bio->next_bio; - BIO_free(b); - /* Since ref count > 1, don't free anyone else. */ - if (ref > 1) - break; - } -} - -BIO *BIO_dup_chain(BIO *in) -{ - BIO *ret = NULL, *eoc = NULL, *bio, *new_bio; - - for (bio = in; bio != NULL; bio = bio->next_bio) { - if ((new_bio = BIO_new(bio->method)) == NULL) - goto err; - new_bio->callback = bio->callback; - new_bio->cb_arg = bio->cb_arg; - new_bio->init = bio->init; - new_bio->shutdown = bio->shutdown; - new_bio->flags = bio->flags; - - /* This will let SSL_s_sock() work with stdin/stdout */ - new_bio->num = bio->num; - - if (!BIO_dup_state(bio, (char *)new_bio)) { - BIO_free(new_bio); - goto err; - } - - /* copy app data */ - if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data, - &bio->ex_data)) { - BIO_free(new_bio); - goto err; - } - - if (ret == NULL) { - eoc = new_bio; - ret = eoc; - } else { - BIO_push(eoc, new_bio); - eoc = new_bio; - } - } - return (ret); - err: - BIO_free_all(ret); - - return (NULL); -} - -void BIO_copy_next_retry(BIO *b) -{ - BIO_set_flags(b, BIO_get_retry_flags(b->next_bio)); - b->retry_reason = b->next_bio->retry_reason; -} - -int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp, - new_func, dup_func, free_func); -} - -int BIO_set_ex_data(BIO *bio, int idx, void *data) -{ - return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data)); -} - -void *BIO_get_ex_data(BIO *bio, int idx) -{ - return (CRYPTO_get_ex_data(&(bio->ex_data), idx)); -} - -unsigned long BIO_number_read(BIO *bio) -{ - if (bio) - return bio->num_read; - return 0; -} - -unsigned long BIO_number_written(BIO *bio) -{ - if (bio) - return bio->num_write; - return 0; -} - -IMPLEMENT_STACK_OF(BIO) -/* crypto/evp/bio_md.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "evp.h" - -/* - * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest - */ - -static int md_write(BIO *h, char const *buf, int num); -static int md_read(BIO *h, char *buf, int size); -/* - * static int md_puts(BIO *h, const char *str); - */ -static int md_gets(BIO *h, char *str, int size); -static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int md_new(BIO *h); -static int md_free(BIO *data); -static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); - -static BIO_METHOD methods_md = { - BIO_TYPE_MD, "message digest", - md_write, - md_read, - NULL, /* md_puts, */ - md_gets, - md_ctrl, - md_new, - md_free, - md_callback_ctrl, -}; - -BIO_METHOD *BIO_f_md(void) -{ - return (&methods_md); -} - -static int md_new(BIO *bi) -{ - EVP_MD_CTX *ctx; - - ctx = EVP_MD_CTX_create(); - if (ctx == NULL) - return (0); - - bi->init = 0; - bi->ptr = (char *)ctx; - bi->flags = 0; - return (1); -} - -static int md_free(BIO *a) -{ - if (a == NULL) - return (0); - EVP_MD_CTX_destroy(a->ptr); - a->ptr = NULL; - a->init = 0; - a->flags = 0; - return (1); -} - -static int md_read(BIO *b, char *out, int outl) -{ - int ret = 0; - EVP_MD_CTX *ctx; - - if (out == NULL) - return (0); - ctx = b->ptr; - - if ((ctx == NULL) || (b->next_bio == NULL)) - return (0); - - ret = BIO_read(b->next_bio, out, outl); - if (b->init) { - if (ret > 0) { - if (EVP_DigestUpdate(ctx, (unsigned char *)out, - (unsigned int)ret) <= 0) - return (-1); - } - } - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - return (ret); -} - -static int md_write(BIO *b, const char *in, int inl) -{ - int ret = 0; - EVP_MD_CTX *ctx; - - if ((in == NULL) || (inl <= 0)) - return (0); - ctx = b->ptr; - - if ((ctx != NULL) && (b->next_bio != NULL)) - ret = BIO_write(b->next_bio, in, inl); - if (b->init) { - if (ret > 0) { - if (!EVP_DigestUpdate(ctx, (const unsigned char *)in, - (unsigned int)ret)) { - BIO_clear_retry_flags(b); - return 0; - } - } - } - if (b->next_bio != NULL) { - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - } - return (ret); -} - -static long md_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - EVP_MD_CTX *ctx, *dctx, **pctx; - const EVP_MD **ppmd; - EVP_MD *md; - long ret = 1; - BIO *dbio; - - ctx = b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - if (b->init) - ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL); - else - ret = 0; - if (ret > 0) - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_C_GET_MD: - if (b->init) { - ppmd = ptr; - *ppmd = ctx->digest; - } else - ret = 0; - break; - case BIO_C_GET_MD_CTX: - pctx = ptr; - *pctx = ctx; - b->init = 1; - break; - case BIO_C_SET_MD_CTX: - if (b->init) - b->ptr = ptr; - else - ret = 0; - break; - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - - case BIO_C_SET_MD: - md = ptr; - ret = EVP_DigestInit_ex(ctx, md, NULL); - if (ret > 0) - b->init = 1; - break; - case BIO_CTRL_DUP: - dbio = ptr; - dctx = dbio->ptr; - if (!EVP_MD_CTX_copy_ex(dctx, ctx)) - return 0; - b->init = 1; - break; - default: - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - return (ret); -} - -static long md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return (ret); -} - -static int md_gets(BIO *bp, char *buf, int size) -{ - EVP_MD_CTX *ctx; - unsigned int ret; - - ctx = bp->ptr; - if (size < ctx->digest->md_size) - return (0); - if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0) - return -1; - - return ((int)ret); -} - -/*- -static int md_puts(bp,str) -BIO *bp; -char *str; - { - return(-1); - } -*/ -/* bio_ndef.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "asn1.h" -#include "asn1t.h" -// #include "bio.h" -// #include "err.h" - -#include - -/* Experimental NDEF ASN1 BIO support routines */ - -/* - * The usage is quite simple, initialize an ASN1 structure, get a BIO from it - * then any data written through the BIO will end up translated to - * approptiate format on the fly. The data is streamed out and does *not* - * need to be all held in memory at once. When the BIO is flushed the output - * is finalized and any signatures etc written out. The BIO is a 'proper' - * BIO and can handle non blocking I/O correctly. The usage is simple. The - * implementation is *not*... - */ - -/* BIO support data stored in the ASN1 BIO ex_arg */ - -typedef struct ndef_aux_st { - /* ASN1 structure this BIO refers to */ - ASN1_VALUE *val; - const ASN1_ITEM *it; - /* Top of the BIO chain */ - BIO *ndef_bio; - /* Output BIO */ - BIO *out; - /* Boundary where content is inserted */ - unsigned char **boundary; - /* DER buffer start */ - unsigned char *derbuf; -} NDEF_SUPPORT; - -static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg); -static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, - void *parg); -static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg); -static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, - void *parg); - -BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) -{ - NDEF_SUPPORT *ndef_aux = NULL; - BIO *asn_bio = NULL; - const ASN1_AUX *aux = it->funcs; - ASN1_STREAM_ARG sarg; - - if (!aux || !aux->asn1_cb) { - ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED); - return NULL; - } - ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT)); - asn_bio = BIO_new(BIO_f_asn1()); - - /* ASN1 bio needs to be next to output BIO */ - - out = BIO_push(asn_bio, out); - - if (!ndef_aux || !asn_bio || !out) - goto err; - - BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free); - BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free); - - /* - * Now let callback prepend any digest, cipher etc BIOs ASN1 structure - * needs. - */ - - sarg.out = out; - sarg.ndef_bio = NULL; - sarg.boundary = NULL; - - if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) - goto err; - - ndef_aux->val = val; - ndef_aux->it = it; - ndef_aux->ndef_bio = sarg.ndef_bio; - ndef_aux->boundary = sarg.boundary; - ndef_aux->out = out; - ndef_aux->derbuf = NULL; - - BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux); - - return sarg.ndef_bio; - - err: - if (asn_bio) - BIO_free(asn_bio); - if (ndef_aux) - OPENSSL_free(ndef_aux); - return NULL; -} - -static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) -{ - NDEF_SUPPORT *ndef_aux; - unsigned char *p; - int derlen; - - if (!parg) - return 0; - - ndef_aux = *(NDEF_SUPPORT **)parg; - - derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); - p = OPENSSL_malloc(derlen); - if (!p) - return 0; - - ndef_aux->derbuf = p; - *pbuf = p; - derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); - - if (!*ndef_aux->boundary) - return 0; - - *plen = *ndef_aux->boundary - *pbuf; - - return 1; -} - -static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, - void *parg) -{ - NDEF_SUPPORT *ndef_aux; - - if (!parg) - return 0; - - ndef_aux = *(NDEF_SUPPORT **)parg; - - if (ndef_aux->derbuf) - OPENSSL_free(ndef_aux->derbuf); - - ndef_aux->derbuf = NULL; - *pbuf = NULL; - *plen = 0; - return 1; -} - -static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, - void *parg) -{ - NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg; - if (!ndef_prefix_free(b, pbuf, plen, parg)) - return 0; - OPENSSL_free(*pndef_aux); - *pndef_aux = NULL; - return 1; -} - -static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) -{ - NDEF_SUPPORT *ndef_aux; - unsigned char *p; - int derlen; - const ASN1_AUX *aux; - ASN1_STREAM_ARG sarg; - - if (!parg) - return 0; - - ndef_aux = *(NDEF_SUPPORT **)parg; - - aux = ndef_aux->it->funcs; - - /* Finalize structures */ - sarg.ndef_bio = ndef_aux->ndef_bio; - sarg.out = ndef_aux->out; - sarg.boundary = ndef_aux->boundary; - if (aux->asn1_cb(ASN1_OP_STREAM_POST, - &ndef_aux->val, ndef_aux->it, &sarg) <= 0) - return 0; - - derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); - p = OPENSSL_malloc(derlen); - if (!p) - return 0; - - ndef_aux->derbuf = p; - *pbuf = p; - derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); - - if (!*ndef_aux->boundary) - return 0; - *pbuf = *ndef_aux->boundary; - *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf); - - return 1; -} -/* crypto/evp/bio_ok.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/*- - From: Arne Ansper - - Why BIO_f_reliable? - - I wrote function which took BIO* as argument, read data from it - and processed it. Then I wanted to store the input file in - encrypted form. OK I pushed BIO_f_cipher to the BIO stack - and everything was OK. BUT if user types wrong password - BIO_f_cipher outputs only garbage and my function crashes. Yes - I can and I should fix my function, but BIO_f_cipher is - easy way to add encryption support to many existing applications - and it's hard to debug and fix them all. - - So I wanted another BIO which would catch the incorrect passwords and - file damages which cause garbage on BIO_f_cipher's output. - - The easy way is to push the BIO_f_md and save the checksum at - the end of the file. However there are several problems with this - approach: - - 1) you must somehow separate checksum from actual data. - 2) you need lot's of memory when reading the file, because you - must read to the end of the file and verify the checksum before - letting the application to read the data. - - BIO_f_reliable tries to solve both problems, so that you can - read and write arbitrary long streams using only fixed amount - of memory. - - BIO_f_reliable splits data stream into blocks. Each block is prefixed - with it's length and suffixed with it's digest. So you need only - several Kbytes of memory to buffer single block before verifying - it's digest. - - BIO_f_reliable goes further and adds several important capabilities: - - 1) the digest of the block is computed over the whole stream - -- so nobody can rearrange the blocks or remove or replace them. - - 2) to detect invalid passwords right at the start BIO_f_reliable - adds special prefix to the stream. In order to avoid known plain-text - attacks this prefix is generated as follows: - - *) digest is initialized with random seed instead of - standardized one. - *) same seed is written to output - *) well-known text is then hashed and the output - of the digest is also written to output. - - reader can now read the seed from stream, hash the same string - and then compare the digest output. - - Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I - initially wrote and tested this code on x86 machine and wrote the - digests out in machine-dependent order :( There are people using - this code and I cannot change this easily without making existing - data files unreadable. - -*/ - -#include -#include -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "bio.h" -// #include "evp.h" -#include "rand.h" - -static int ok_write(BIO *h, const char *buf, int num); -static int ok_read(BIO *h, char *buf, int size); -static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int ok_new(BIO *h); -static int ok_free(BIO *data); -static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); - -static int sig_out(BIO *b); -static int sig_in(BIO *b); -static int block_out(BIO *b); -static int block_in(BIO *b); -#define OK_BLOCK_SIZE (1024*4) -#define OK_BLOCK_BLOCK 4 -#define IOBS (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE) -#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back." - -typedef struct ok_struct { - size_t buf_len; - size_t buf_off; - size_t buf_len_save; - size_t buf_off_save; - int cont; /* <= 0 when finished */ - int finished; - EVP_MD_CTX md; - int blockout; /* output block is ready */ - int sigio; /* must process signature */ - unsigned char buf[IOBS]; -} BIO_OK_CTX; - -static BIO_METHOD methods_ok = { - BIO_TYPE_CIPHER, "reliable", - ok_write, - ok_read, - NULL, /* ok_puts, */ - NULL, /* ok_gets, */ - ok_ctrl, - ok_new, - ok_free, - ok_callback_ctrl, -}; - -BIO_METHOD *BIO_f_reliable(void) -{ - return (&methods_ok); -} - -static int ok_new(BIO *bi) -{ - BIO_OK_CTX *ctx; - - ctx = (BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX)); - if (ctx == NULL) - return (0); - - ctx->buf_len = 0; - ctx->buf_off = 0; - ctx->buf_len_save = 0; - ctx->buf_off_save = 0; - ctx->cont = 1; - ctx->finished = 0; - ctx->blockout = 0; - ctx->sigio = 1; - - EVP_MD_CTX_init(&ctx->md); - - bi->init = 0; - bi->ptr = (char *)ctx; - bi->flags = 0; - return (1); -} - -static int ok_free(BIO *a) -{ - if (a == NULL) - return (0); - EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md); - OPENSSL_cleanse(a->ptr, sizeof(BIO_OK_CTX)); - OPENSSL_free(a->ptr); - a->ptr = NULL; - a->init = 0; - a->flags = 0; - return (1); -} - -static int ok_read(BIO *b, char *out, int outl) -{ - int ret = 0, i, n; - BIO_OK_CTX *ctx; - - if (out == NULL) - return (0); - ctx = (BIO_OK_CTX *)b->ptr; - - if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) - return (0); - - while (outl > 0) { - - /* copy clean bytes to output buffer */ - if (ctx->blockout) { - i = ctx->buf_len - ctx->buf_off; - if (i > outl) - i = outl; - memcpy(out, &(ctx->buf[ctx->buf_off]), i); - ret += i; - out += i; - outl -= i; - ctx->buf_off += i; - - /* all clean bytes are out */ - if (ctx->buf_len == ctx->buf_off) { - ctx->buf_off = 0; - - /* - * copy start of the next block into proper place - */ - if (ctx->buf_len_save - ctx->buf_off_save > 0) { - ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save; - memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]), - ctx->buf_len); - } else { - ctx->buf_len = 0; - } - ctx->blockout = 0; - } - } - - /* output buffer full -- cancel */ - if (outl == 0) - break; - - /* no clean bytes in buffer -- fill it */ - n = IOBS - ctx->buf_len; - i = BIO_read(b->next_bio, &(ctx->buf[ctx->buf_len]), n); - - if (i <= 0) - break; /* nothing new */ - - ctx->buf_len += i; - - /* no signature yet -- check if we got one */ - if (ctx->sigio == 1) { - if (!sig_in(b)) { - BIO_clear_retry_flags(b); - return 0; - } - } - - /* signature ok -- check if we got block */ - if (ctx->sigio == 0) { - if (!block_in(b)) { - BIO_clear_retry_flags(b); - return 0; - } - } - - /* invalid block -- cancel */ - if (ctx->cont <= 0) - break; - - } - - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - return (ret); -} - -static int ok_write(BIO *b, const char *in, int inl) -{ - int ret = 0, n, i; - BIO_OK_CTX *ctx; - - if (inl <= 0) - return inl; - - ctx = (BIO_OK_CTX *)b->ptr; - ret = inl; - - if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) - return (0); - - if (ctx->sigio && !sig_out(b)) - return 0; - - do { - BIO_clear_retry_flags(b); - n = ctx->buf_len - ctx->buf_off; - while (ctx->blockout && n > 0) { - i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); - if (i <= 0) { - BIO_copy_next_retry(b); - if (!BIO_should_retry(b)) - ctx->cont = 0; - return (i); - } - ctx->buf_off += i; - n -= i; - } - - /* at this point all pending data has been written */ - ctx->blockout = 0; - if (ctx->buf_len == ctx->buf_off) { - ctx->buf_len = OK_BLOCK_BLOCK; - ctx->buf_off = 0; - } - - if ((in == NULL) || (inl <= 0)) - return (0); - - n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ? - (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl; - - memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])), - (unsigned char *)in, n); - ctx->buf_len += n; - inl -= n; - in += n; - - if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) { - if (!block_out(b)) { - BIO_clear_retry_flags(b); - return 0; - } - } - } while (inl > 0); - - BIO_clear_retry_flags(b); - BIO_copy_next_retry(b); - return (ret); -} - -static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - BIO_OK_CTX *ctx; - EVP_MD *md; - const EVP_MD **ppmd; - long ret = 1; - int i; - - ctx = b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ctx->buf_len = 0; - ctx->buf_off = 0; - ctx->buf_len_save = 0; - ctx->buf_off_save = 0; - ctx->cont = 1; - ctx->finished = 0; - ctx->blockout = 0; - ctx->sigio = 1; - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_EOF: /* More to read */ - if (ctx->cont <= 0) - ret = 1; - else - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_PENDING: /* More to read in buffer */ - case BIO_CTRL_WPENDING: /* More to read in buffer */ - ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0; - if (ret <= 0) - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_CTRL_FLUSH: - /* do a final write */ - if (ctx->blockout == 0) - if (!block_out(b)) - return 0; - - while (ctx->blockout) { - i = ok_write(b, NULL, 0); - if (i < 0) { - ret = i; - break; - } - } - - ctx->finished = 1; - ctx->buf_off = ctx->buf_len = 0; - ctx->cont = (int)ret; - - /* Finally flush the underlying BIO */ - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - case BIO_CTRL_INFO: - ret = (long)ctx->cont; - break; - case BIO_C_SET_MD: - md = ptr; - if (!EVP_DigestInit_ex(&ctx->md, md, NULL)) - return 0; - b->init = 1; - break; - case BIO_C_GET_MD: - if (b->init) { - ppmd = ptr; - *ppmd = ctx->md.digest; - } else - ret = 0; - break; - default: - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - } - return (ret); -} - -static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - - if (b->next_bio == NULL) - return (0); - switch (cmd) { - default: - ret = BIO_callback_ctrl(b->next_bio, cmd, fp); - break; - } - return (ret); -} - -static void longswap(void *_ptr, size_t len) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - - if (is_endian.little) { - size_t i; - unsigned char *p = _ptr, c; - - for (i = 0; i < len; i += 4) { - c = p[0], p[0] = p[3], p[3] = c; - c = p[1], p[1] = p[2], p[2] = c; - } - } -} - -static int sig_out(BIO *b) -{ - BIO_OK_CTX *ctx; - EVP_MD_CTX *md; - - ctx = b->ptr; - md = &ctx->md; - - if (ctx->buf_len + 2 * md->digest->md_size > OK_BLOCK_SIZE) - return 1; - - if (!EVP_DigestInit_ex(md, md->digest, NULL)) - goto berr; - /* - * FIXME: there's absolutely no guarantee this makes any sense at all, - * particularly now EVP_MD_CTX has been restructured. - */ - if (RAND_bytes(md->md_data, md->digest->md_size) <= 0) - goto berr; - memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size); - longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size); - ctx->buf_len += md->digest->md_size; - - if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) - goto berr; - if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) - goto berr; - ctx->buf_len += md->digest->md_size; - ctx->blockout = 1; - ctx->sigio = 0; - return 1; - berr: - BIO_clear_retry_flags(b); - return 0; -} - -static int sig_in(BIO *b) -{ - BIO_OK_CTX *ctx; - EVP_MD_CTX *md; - unsigned char tmp[EVP_MAX_MD_SIZE]; - int ret = 0; - - ctx = b->ptr; - md = &ctx->md; - - if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md->digest->md_size) - return 1; - - if (!EVP_DigestInit_ex(md, md->digest, NULL)) - goto berr; - memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size); - longswap(md->md_data, md->digest->md_size); - ctx->buf_off += md->digest->md_size; - - if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) - goto berr; - if (!EVP_DigestFinal_ex(md, tmp, NULL)) - goto berr; - ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0; - ctx->buf_off += md->digest->md_size; - if (ret == 1) { - ctx->sigio = 0; - if (ctx->buf_len != ctx->buf_off) { - memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), - ctx->buf_len - ctx->buf_off); - } - ctx->buf_len -= ctx->buf_off; - ctx->buf_off = 0; - } else { - ctx->cont = 0; - } - return 1; - berr: - BIO_clear_retry_flags(b); - return 0; -} - -static int block_out(BIO *b) -{ - BIO_OK_CTX *ctx; - EVP_MD_CTX *md; - unsigned long tl; - - ctx = b->ptr; - md = &ctx->md; - - tl = ctx->buf_len - OK_BLOCK_BLOCK; - ctx->buf[0] = (unsigned char)(tl >> 24); - ctx->buf[1] = (unsigned char)(tl >> 16); - ctx->buf[2] = (unsigned char)(tl >> 8); - ctx->buf[3] = (unsigned char)(tl); - if (!EVP_DigestUpdate(md, - (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl)) - goto berr; - if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) - goto berr; - ctx->buf_len += md->digest->md_size; - ctx->blockout = 1; - return 1; - berr: - BIO_clear_retry_flags(b); - return 0; -} - -static int block_in(BIO *b) -{ - BIO_OK_CTX *ctx; - EVP_MD_CTX *md; - unsigned long tl = 0; - unsigned char tmp[EVP_MAX_MD_SIZE]; - - ctx = b->ptr; - md = &ctx->md; - - assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */ - tl = ctx->buf[0]; - tl <<= 8; - tl |= ctx->buf[1]; - tl <<= 8; - tl |= ctx->buf[2]; - tl <<= 8; - tl |= ctx->buf[3]; - - if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md->digest->md_size) - return 1; - - if (!EVP_DigestUpdate(md, - (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl)) - goto berr; - if (!EVP_DigestFinal_ex(md, tmp, NULL)) - goto berr; - if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == - 0) { - /* there might be parts from next block lurking around ! */ - ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md->digest->md_size; - ctx->buf_len_save = ctx->buf_len; - ctx->buf_off = OK_BLOCK_BLOCK; - ctx->buf_len = tl + OK_BLOCK_BLOCK; - ctx->blockout = 1; - } else { - ctx->cont = 0; - } - return 1; - berr: - BIO_clear_retry_flags(b); - return 0; -} -/* bio_pk7.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "asn1.h" -#include "pkcs7.h" -// #include "bio.h" - -#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS) -# include -#endif -#include - -/* Streaming encode support for PKCS#7 */ - -BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7) -{ - return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7)); -} -/* ssl/bio_ssl.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include -// #include "crypto.h" -// #include "bio.h" -// #include "err.h" -#include "ssl.h" - -static int ssl_write(BIO *h, const char *buf, int num); -static int ssl_read(BIO *h, char *buf, int size); -static int ssl_puts(BIO *h, const char *str); -static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int ssl_new(BIO *h); -static int ssl_free(BIO *data); -static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); -typedef struct bio_ssl_st { - SSL *ssl; /* The ssl handle :-) */ - /* re-negotiate every time the total number of bytes is this size */ - int num_renegotiates; - unsigned long renegotiate_count; - unsigned long byte_count; - unsigned long renegotiate_timeout; - unsigned long last_time; -} BIO_SSL; - -static BIO_METHOD methods_sslp = { - BIO_TYPE_SSL, "ssl", - ssl_write, - ssl_read, - ssl_puts, - NULL, /* ssl_gets, */ - ssl_ctrl, - ssl_new, - ssl_free, - ssl_callback_ctrl, -}; - -BIO_METHOD *BIO_f_ssl(void) -{ - return (&methods_sslp); -} - -static int ssl_new(BIO *bi) -{ - BIO_SSL *bs; - - bs = (BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL)); - if (bs == NULL) { - BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE); - return (0); - } - memset(bs, 0, sizeof(BIO_SSL)); - bi->init = 0; - bi->ptr = (char *)bs; - bi->flags = 0; - return (1); -} - -static int ssl_free(BIO *a) -{ - BIO_SSL *bs; - - if (a == NULL) - return (0); - bs = (BIO_SSL *)a->ptr; - if (bs->ssl != NULL) - SSL_shutdown(bs->ssl); - if (a->shutdown) { - if (a->init && (bs->ssl != NULL)) - SSL_free(bs->ssl); - a->init = 0; - a->flags = 0; - } - if (a->ptr != NULL) - OPENSSL_free(a->ptr); - return (1); -} - -static int ssl_read(BIO *b, char *out, int outl) -{ - int ret = 1; - BIO_SSL *sb; - SSL *ssl; - int retry_reason = 0; - int r = 0; - - if (out == NULL) - return (0); - sb = (BIO_SSL *)b->ptr; - ssl = sb->ssl; - - BIO_clear_retry_flags(b); - -#if 0 - if (!SSL_is_init_finished(ssl)) { -/* ret=SSL_do_handshake(ssl); */ - if (ret > 0) { - - outflags = (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); - ret = -1; - goto end; - } - } -#endif -/* if (ret > 0) */ - ret = SSL_read(ssl, out, outl); - - switch (SSL_get_error(ssl, ret)) { - case SSL_ERROR_NONE: - if (ret <= 0) - break; - if (sb->renegotiate_count > 0) { - sb->byte_count += ret; - if (sb->byte_count > sb->renegotiate_count) { - sb->byte_count = 0; - sb->num_renegotiates++; - SSL_renegotiate(ssl); - r = 1; - } - } - if ((sb->renegotiate_timeout > 0) && (!r)) { - unsigned long tm; - - tm = (unsigned long)time(NULL); - if (tm > sb->last_time + sb->renegotiate_timeout) { - sb->last_time = tm; - sb->num_renegotiates++; - SSL_renegotiate(ssl); - } - } - - break; - case SSL_ERROR_WANT_READ: - BIO_set_retry_read(b); - break; - case SSL_ERROR_WANT_WRITE: - BIO_set_retry_write(b); - break; - case SSL_ERROR_WANT_X509_LOOKUP: - BIO_set_retry_special(b); - retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - case SSL_ERROR_WANT_ACCEPT: - BIO_set_retry_special(b); - retry_reason = BIO_RR_ACCEPT; - break; - case SSL_ERROR_WANT_CONNECT: - BIO_set_retry_special(b); - retry_reason = BIO_RR_CONNECT; - break; - case SSL_ERROR_SYSCALL: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - default: - break; - } - - b->retry_reason = retry_reason; - return (ret); -} - -static int ssl_write(BIO *b, const char *out, int outl) -{ - int ret, r = 0; - int retry_reason = 0; - SSL *ssl; - BIO_SSL *bs; - - if (out == NULL) - return (0); - bs = (BIO_SSL *)b->ptr; - ssl = bs->ssl; - - BIO_clear_retry_flags(b); - - /* - * ret=SSL_do_handshake(ssl); if (ret > 0) - */ - ret = SSL_write(ssl, out, outl); - - switch (SSL_get_error(ssl, ret)) { - case SSL_ERROR_NONE: - if (ret <= 0) - break; - if (bs->renegotiate_count > 0) { - bs->byte_count += ret; - if (bs->byte_count > bs->renegotiate_count) { - bs->byte_count = 0; - bs->num_renegotiates++; - SSL_renegotiate(ssl); - r = 1; - } - } - if ((bs->renegotiate_timeout > 0) && (!r)) { - unsigned long tm; - - tm = (unsigned long)time(NULL); - if (tm > bs->last_time + bs->renegotiate_timeout) { - bs->last_time = tm; - bs->num_renegotiates++; - SSL_renegotiate(ssl); - } - } - break; - case SSL_ERROR_WANT_WRITE: - BIO_set_retry_write(b); - break; - case SSL_ERROR_WANT_READ: - BIO_set_retry_read(b); - break; - case SSL_ERROR_WANT_X509_LOOKUP: - BIO_set_retry_special(b); - retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - case SSL_ERROR_WANT_CONNECT: - BIO_set_retry_special(b); - retry_reason = BIO_RR_CONNECT; - case SSL_ERROR_SYSCALL: - case SSL_ERROR_SSL: - default: - break; - } - - b->retry_reason = retry_reason; - return (ret); -} - -static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - SSL **sslp, *ssl; - BIO_SSL *bs; - BIO *dbio, *bio; - long ret = 1; - - bs = (BIO_SSL *)b->ptr; - ssl = bs->ssl; - if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) - return (0); - switch (cmd) { - case BIO_CTRL_RESET: - SSL_shutdown(ssl); - - if (ssl->handshake_func == ssl->method->ssl_connect) - SSL_set_connect_state(ssl); - else if (ssl->handshake_func == ssl->method->ssl_accept) - SSL_set_accept_state(ssl); - - SSL_clear(ssl); - - if (b->next_bio != NULL) - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - else if (ssl->rbio != NULL) - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); - else - ret = 1; - break; - case BIO_CTRL_INFO: - ret = 0; - break; - case BIO_C_SSL_MODE: - if (num) /* client mode */ - SSL_set_connect_state(ssl); - else - SSL_set_accept_state(ssl); - break; - case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: - ret = bs->renegotiate_timeout; - if (num < 60) - num = 5; - bs->renegotiate_timeout = (unsigned long)num; - bs->last_time = (unsigned long)time(NULL); - break; - case BIO_C_SET_SSL_RENEGOTIATE_BYTES: - ret = bs->renegotiate_count; - if ((long)num >= 512) - bs->renegotiate_count = (unsigned long)num; - break; - case BIO_C_GET_SSL_NUM_RENEGOTIATES: - ret = bs->num_renegotiates; - break; - case BIO_C_SET_SSL: - if (ssl != NULL) { - ssl_free(b); - if (!ssl_new(b)) - return 0; - } - b->shutdown = (int)num; - ssl = (SSL *)ptr; - ((BIO_SSL *)b->ptr)->ssl = ssl; - bio = SSL_get_rbio(ssl); - if (bio != NULL) { - if (b->next_bio != NULL) - BIO_push(bio, b->next_bio); - b->next_bio = bio; - CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); - } - b->init = 1; - break; - case BIO_C_GET_SSL: - if (ptr != NULL) { - sslp = (SSL **)ptr; - *sslp = ssl; - } else - ret = 0; - break; - case BIO_CTRL_GET_CLOSE: - ret = b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_WPENDING: - ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); - break; - case BIO_CTRL_PENDING: - ret = SSL_pending(ssl); - if (ret == 0) - ret = BIO_pending(ssl->rbio); - break; - case BIO_CTRL_FLUSH: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - case BIO_CTRL_PUSH: - if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) { - SSL_set_bio(ssl, b->next_bio, b->next_bio); - CRYPTO_add(&b->next_bio->references, 1, CRYPTO_LOCK_BIO); - } - break; - case BIO_CTRL_POP: - /* Only detach if we are the BIO explicitly being popped */ - if (b == ptr) { - /* - * Shouldn't happen in practice because the rbio and wbio are the - * same when pushed. - */ - if (ssl->rbio != ssl->wbio) - BIO_free_all(ssl->wbio); - if (b->next_bio != NULL) - CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO); - ssl->wbio = NULL; - ssl->rbio = NULL; - } - break; - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - - b->retry_reason = 0; - ret = (int)SSL_do_handshake(ssl); - - switch (SSL_get_error(ssl, (int)ret)) { - case SSL_ERROR_WANT_READ: - BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); - break; - case SSL_ERROR_WANT_WRITE: - BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY); - break; - case SSL_ERROR_WANT_CONNECT: - BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY); - b->retry_reason = b->next_bio->retry_reason; - break; - case SSL_ERROR_WANT_X509_LOOKUP: - BIO_set_retry_special(b); - b->retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - default: - break; - } - break; - case BIO_CTRL_DUP: - dbio = (BIO *)ptr; - if (((BIO_SSL *)dbio->ptr)->ssl != NULL) - SSL_free(((BIO_SSL *)dbio->ptr)->ssl); - ((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl); - ((BIO_SSL *)dbio->ptr)->renegotiate_count = - ((BIO_SSL *)b->ptr)->renegotiate_count; - ((BIO_SSL *)dbio->ptr)->byte_count = ((BIO_SSL *)b->ptr)->byte_count; - ((BIO_SSL *)dbio->ptr)->renegotiate_timeout = - ((BIO_SSL *)b->ptr)->renegotiate_timeout; - ((BIO_SSL *)dbio->ptr)->last_time = ((BIO_SSL *)b->ptr)->last_time; - ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL); - break; - case BIO_C_GET_FD: - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); - break; - case BIO_CTRL_SET_CALLBACK: - { -#if 0 /* FIXME: Should this be used? -- Richard - * Levitte */ - SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - ret = -1; -#else - ret = 0; -#endif - } - break; - case BIO_CTRL_GET_CALLBACK: - { - void (**fptr) (const SSL *xssl, int type, int val); - - fptr = (void (**)(const SSL *xssl, int type, int val))ptr; - *fptr = SSL_get_info_callback(ssl); - } - break; - default: - ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); - break; - } - return (ret); -} - -static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - SSL *ssl; - BIO_SSL *bs; - long ret = 1; - - bs = (BIO_SSL *)b->ptr; - ssl = bs->ssl; - switch (cmd) { - case BIO_CTRL_SET_CALLBACK: - { - /* - * FIXME: setting this via a completely different prototype seems - * like a crap idea - */ - SSL_set_info_callback(ssl, (void (*)(const SSL *, int, int))fp); - } - break; - default: - ret = BIO_callback_ctrl(ssl->rbio, cmd, fp); - break; - } - return (ret); -} - -static int ssl_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = BIO_write(bp, str, n); - return (ret); -} - -BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) -{ -#ifndef OPENSSL_NO_SOCK - BIO *ret = NULL, *buf = NULL, *ssl = NULL; - - if ((buf = BIO_new(BIO_f_buffer())) == NULL) - return (NULL); - if ((ssl = BIO_new_ssl_connect(ctx)) == NULL) - goto err; - if ((ret = BIO_push(buf, ssl)) == NULL) - goto err; - return (ret); - err: - if (buf != NULL) - BIO_free(buf); - if (ssl != NULL) - BIO_free(ssl); -#endif - return (NULL); -} - -BIO *BIO_new_ssl_connect(SSL_CTX *ctx) -{ -#ifndef OPENSSL_NO_SOCK - BIO *ret = NULL, *con = NULL, *ssl = NULL; - - if ((con = BIO_new(BIO_s_connect())) == NULL) - return (NULL); - if ((ssl = BIO_new_ssl(ctx, 1)) == NULL) - goto err; - if ((ret = BIO_push(ssl, con)) == NULL) - goto err; - return (ret); - err: - if (con != NULL) - BIO_free(con); -#endif - return (NULL); -} - -BIO *BIO_new_ssl(SSL_CTX *ctx, int client) -{ - BIO *ret; - SSL *ssl; - - if ((ret = BIO_new(BIO_f_ssl())) == NULL) - return (NULL); - if ((ssl = SSL_new(ctx)) == NULL) { - BIO_free(ret); - return (NULL); - } - if (client) - SSL_set_connect_state(ssl); - else - SSL_set_accept_state(ssl); - - BIO_set_ssl(ret, ssl, BIO_CLOSE); - return (ret); -} - -int BIO_ssl_copy_session_id(BIO *t, BIO *f) -{ - t = BIO_find_type(t, BIO_TYPE_SSL); - f = BIO_find_type(f, BIO_TYPE_SSL); - if ((t == NULL) || (f == NULL)) - return (0); - if ((((BIO_SSL *)t->ptr)->ssl == NULL) || - (((BIO_SSL *)f->ptr)->ssl == NULL)) - return (0); - SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl, ((BIO_SSL *)f->ptr)->ssl); - return (1); -} - -void BIO_ssl_shutdown(BIO *b) -{ - SSL *s; - - while (b != NULL) { - if (b->method->type == BIO_TYPE_SSL) { - s = ((BIO_SSL *)b->ptr)->ssl; - SSL_shutdown(s); - break; - } - b = b->next_bio; - } -} diff --git a/Sources/COpenSSL/bio_lcl.h b/Sources/COpenSSL/bio_lcl.h deleted file mode 100644 index 1d26fe3e..00000000 --- a/Sources/COpenSSL/bio_lcl.h +++ /dev/null @@ -1,36 +0,0 @@ -#include "bio.h" - -#if BIO_FLAGS_UPLINK==0 -/* Shortcut UPLINK calls on most platforms... */ -# define UP_stdin stdin -# define UP_stdout stdout -# define UP_stderr stderr -# define UP_fprintf fprintf -# define UP_fgets fgets -# define UP_fread fread -# define UP_fwrite fwrite -# undef UP_fsetmod -# define UP_feof feof -# define UP_fclose fclose - -# define UP_fopen fopen -# define UP_fseek fseek -# define UP_ftell ftell -# define UP_fflush fflush -# define UP_ferror ferror -# ifdef _WIN32 -# define UP_fileno _fileno -# define UP_open _open -# define UP_read _read -# define UP_write _write -# define UP_lseek _lseek -# define UP_close _close -# else -# define UP_fileno fileno -# define UP_open open -# define UP_read read -# define UP_write write -# define UP_lseek lseek -# define UP_close close -# endif -#endif diff --git a/Sources/COpenSSL/blowfish.h b/Sources/COpenSSL/blowfish.h deleted file mode 100644 index 984e8dbb..00000000 --- a/Sources/COpenSSL/blowfish.h +++ /dev/null @@ -1,130 +0,0 @@ -/* crypto/bf/blowfish.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_BLOWFISH_H -# define HEADER_BLOWFISH_H - -# include "e_os2.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef OPENSSL_NO_BF -# error BF is disabled. -# endif - -# define BF_ENCRYPT 1 -# define BF_DECRYPT 0 - -/*- - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! - * ! BF_LONG_LOG2 has to be defined along. ! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - -# if defined(__LP32__) -# define BF_LONG unsigned long -# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) -# define BF_LONG unsigned long -# define BF_LONG_LOG2 3 -/* - * _CRAY note. I could declare short, but I have no idea what impact - * does it have on performance on none-T3E machines. I could declare - * int, but at least on C90 sizeof(int) can be chosen at compile time. - * So I've chosen long... - * - */ -# else -# define BF_LONG unsigned int -# endif - -# define BF_ROUNDS 16 -# define BF_BLOCK 8 - -typedef struct bf_key_st { - BF_LONG P[BF_ROUNDS + 2]; - BF_LONG S[4 * 256]; -} BF_KEY; - -# ifdef OPENSSL_FIPS -void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data); -# endif -void BF_set_key(BF_KEY *key, int len, const unsigned char *data); - -void BF_encrypt(BF_LONG *data, const BF_KEY *key); -void BF_decrypt(BF_LONG *data, const BF_KEY *key); - -void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, - const BF_KEY *key, int enc); -void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, - const BF_KEY *schedule, unsigned char *ivec, int enc); -void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, const BF_KEY *schedule, - unsigned char *ivec, int *num, int enc); -void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, const BF_KEY *schedule, - unsigned char *ivec, int *num); -const char *BF_options(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/bn.h b/Sources/COpenSSL/bn.h deleted file mode 100644 index d6024069..00000000 --- a/Sources/COpenSSL/bn.h +++ /dev/null @@ -1,1015 +0,0 @@ -/* crypto/bn/bn.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the Eric Young open source - * license provided above. - * - * The binary polynomial arithmetic software is originally written by - * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. - * - */ - -#ifndef HEADER_BN_H -# define HEADER_BN_H - -# include -# include "e_os2.h" -# ifndef OPENSSL_NO_FP_API -# include /* FILE */ -# endif -# include "ossl_typ.h" -# include "crypto.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * These preprocessor symbols control various aspects of the bignum headers - * and library code. They're not defined by any "normal" configuration, as - * they are intended for development and testing purposes. NB: defining all - * three can be useful for debugging application code as well as openssl - * itself. BN_DEBUG - turn on various debugging alterations to the bignum - * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up - * mismanagement of bignum internals. You must also define BN_DEBUG. - */ -/* #define BN_DEBUG */ -/* #define BN_DEBUG_RAND */ - -# ifndef OPENSSL_SMALL_FOOTPRINT -# define BN_MUL_COMBA -# define BN_SQR_COMBA -# define BN_RECURSION -# endif - -/* - * This next option uses the C libraries (2 word)/(1 word) function. If it is - * not defined, I use my C version (which is slower). The reason for this - * flag is that when the particular C compiler library routine is used, and - * the library is linked with a different compiler, the library is missing. - * This mostly happens when the library is built with gcc and then linked - * using normal cc. This would be a common occurrence because gcc normally - * produces code that is 2 times faster than system compilers for the big - * number stuff. For machines with only one compiler (or shared libraries), - * this should be on. Again this in only really a problem on machines using - * "long long's", are 32bit, and are not using my assembler code. - */ -# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \ - defined(OPENSSL_SYS_WIN32) || defined(linux) -# ifndef BN_DIV2W -# define BN_DIV2W -# endif -# endif - -/* - * assuming long is 64bit - this is the DEC Alpha unsigned long long is only - * 64 bits :-(, don't define BN_LLONG for the DEC Alpha - */ -# ifdef SIXTY_FOUR_BIT_LONG -# define BN_ULLONG unsigned long long -# define BN_ULONG unsigned long -# define BN_LONG long -# define BN_BITS 128 -# define BN_BYTES 8 -# define BN_BITS2 64 -# define BN_BITS4 32 -# define BN_MASK // (0xffffffffffffffffffffffffffffffffLL) -# define BN_MASK2 (0xffffffffffffffffL) -# define BN_MASK2l (0xffffffffL) -# define BN_MASK2h (0xffffffff00000000L) -# define BN_MASK2h1 (0xffffffff80000000L) -# define BN_TBIT (0x8000000000000000L) -# define BN_DEC_CONV (10000000000000000000UL) -# define BN_DEC_FMT1 "%lu" -# define BN_DEC_FMT2 "%019lu" -# define BN_DEC_NUM 19 -# define BN_HEX_FMT1 "%lX" -# define BN_HEX_FMT2 "%016lX" -# endif - -/* - * This is where the long long data type is 64 bits, but long is 32. For - * machines where there are 64bit registers, this is the mode to use. IRIX, - * on R4000 and above should use this mode, along with the relevant assembler - * code :-). Do NOT define BN_LLONG. - */ -# ifdef SIXTY_FOUR_BIT -# undef BN_LLONG -# undef BN_ULLONG -# define BN_ULONG unsigned long long -# define BN_LONG long long -# define BN_BITS 128 -# define BN_BYTES 8 -# define BN_BITS2 64 -# define BN_BITS4 32 -# define BN_MASK2 (0xffffffffffffffffLL) -# define BN_MASK2l (0xffffffffL) -# define BN_MASK2h (0xffffffff00000000LL) -# define BN_MASK2h1 (0xffffffff80000000LL) -# define BN_TBIT (0x8000000000000000LL) -# define BN_DEC_CONV (10000000000000000000ULL) -# define BN_DEC_FMT1 "%llu" -# define BN_DEC_FMT2 "%019llu" -# define BN_DEC_NUM 19 -# define BN_HEX_FMT1 "%llX" -# define BN_HEX_FMT2 "%016llX" -# endif - -# ifdef THIRTY_TWO_BIT -# ifdef BN_LLONG -# if defined(_WIN32) && !defined(__GNUC__) -# define BN_ULLONG unsigned __int64 -# define BN_MASK // (0xffffffffffffffffI64) -# else -# define BN_ULLONG unsigned long long -# define BN_MASK // (0xffffffffffffffffLL) -# endif -# endif -# define BN_ULONG unsigned int -# define BN_LONG int -# define BN_BITS 64 -# define BN_BYTES 4 -# define BN_BITS2 32 -# define BN_BITS4 16 -# define BN_MASK2 (0xffffffffL) -# define BN_MASK2l (0xffff) -# define BN_MASK2h1 (0xffff8000L) -# define BN_MASK2h (0xffff0000L) -# define BN_TBIT (0x80000000L) -# define BN_DEC_CONV (1000000000L) -# define BN_DEC_FMT1 "%u" -# define BN_DEC_FMT2 "%09u" -# define BN_DEC_NUM 9 -# define BN_HEX_FMT1 "%X" -# define BN_HEX_FMT2 "%08X" -# endif - -# define BN_DEFAULT_BITS 1280 - -# define BN_FLG_MALLOCED 0x01 -# define BN_FLG_STATIC_DATA 0x02 - -/* - * avoid leaking exponent information through timing, - * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, - * BN_div() will call BN_div_no_branch, - * BN_mod_inverse() will call BN_mod_inverse_no_branch. - */ -# define BN_FLG_CONSTTIME 0x04 - -# ifdef OPENSSL_NO_DEPRECATED -/* deprecated name for the flag */ -# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME -/* - * avoid leaking exponent information through timings - * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) - */ -# endif - -# ifndef OPENSSL_NO_DEPRECATED -# define BN_FLG_FREE 0x8000 - /* used for debuging */ -# endif -# define BN_set_flags(b,n) ((b)->flags|=(n)) -# define BN_get_flags(b,n) ((b)->flags&(n)) - -/* - * get a clone of a BIGNUM with changed flags, for *temporary* use only (the - * two BIGNUMs cannot not be used in parallel!) - */ -# define BN_with_flags(dest,b,n) ((dest)->d=(b)->d, \ - (dest)->top=(b)->top, \ - (dest)->dmax=(b)->dmax, \ - (dest)->neg=(b)->neg, \ - (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \ - | ((b)->flags & ~BN_FLG_MALLOCED) \ - | BN_FLG_STATIC_DATA \ - | (n))) - -/* Already declared in ossl_typ.h */ -# if 0 -typedef struct bignum_st BIGNUM; -/* Used for temp variables (declaration hidden in bn_lcl.h) */ -typedef struct bignum_ctx BN_CTX; -typedef struct bn_blinding_st BN_BLINDING; -typedef struct bn_mont_ctx_st BN_MONT_CTX; -typedef struct bn_recp_ctx_st BN_RECP_CTX; -typedef struct bn_gencb_st BN_GENCB; -# endif - -struct bignum_st { - BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit - * chunks. */ - int top; /* Index of last used d +1. */ - /* The next are internal book keeping for bn_expand. */ - int dmax; /* Size of the d array. */ - int neg; /* one if the number is negative */ - int flags; -}; - -/* Used for montgomery multiplication */ -struct bn_mont_ctx_st { - int ri; /* number of bits in R */ - BIGNUM RR; /* used to convert to montgomery form */ - BIGNUM N; /* The modulus */ - BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only - * stored for bignum algorithm) */ - BN_ULONG n0[2]; /* least significant word(s) of Ni; (type - * changed with 0.9.9, was "BN_ULONG n0;" - * before) */ - int flags; -}; - -/* - * Used for reciprocal division/mod functions It cannot be shared between - * threads - */ -struct bn_recp_ctx_st { - BIGNUM N; /* the divisor */ - BIGNUM Nr; /* the reciprocal */ - int num_bits; - int shift; - int flags; -}; - -/* Used for slow "generation" functions. */ -struct bn_gencb_st { - unsigned int ver; /* To handle binary (in)compatibility */ - void *arg; /* callback-specific data */ - union { - /* if(ver==1) - handles old style callbacks */ - void (*cb_1) (int, int, void *); - /* if(ver==2) - new callback style */ - int (*cb_2) (int, int, BN_GENCB *); - } cb; -}; -/* Wrapper function to make using BN_GENCB easier, */ -int BN_GENCB_call(BN_GENCB *cb, int a, int b); -/* Macro to populate a BN_GENCB structure with an "old"-style callback */ -# define BN_GENCB_set_old(gencb, callback, cb_arg) { \ - BN_GENCB *tmp_gencb = (gencb); \ - tmp_gencb->ver = 1; \ - tmp_gencb->arg = (cb_arg); \ - tmp_gencb->cb.cb_1 = (callback); } -/* Macro to populate a BN_GENCB structure with a "new"-style callback */ -# define BN_GENCB_set(gencb, callback, cb_arg) { \ - BN_GENCB *tmp_gencb = (gencb); \ - tmp_gencb->ver = 2; \ - tmp_gencb->arg = (cb_arg); \ - tmp_gencb->cb.cb_2 = (callback); } - -# define BN_prime_checks 0 /* default: select number of iterations based - * on the size of the number */ - -/* - * BN_prime_checks_for_size() returns the number of Miller-Rabin iterations - * that will be done for checking that a random number is probably prime. The - * error rate for accepting a composite number as prime depends on the size of - * the prime |b|. The error rates used are for calculating an RSA key with 2 primes, - * and so the level is what you would expect for a key of double the size of the - * prime. - * - * This table is generated using the algorithm of FIPS PUB 186-4 - * Digital Signature Standard (DSS), section F.1, page 117. - * (https://dx.doi.org/10.6028/NIST.FIPS.186-4) - * - * The following magma script was used to generate the output: - * securitybits:=125; - * k:=1024; - * for t:=1 to 65 do - * for M:=3 to Floor(2*Sqrt(k-1)-1) do - * S:=0; - * // Sum over m - * for m:=3 to M do - * s:=0; - * // Sum over j - * for j:=2 to m do - * s+:=(RealField(32)!2)^-(j+(k-1)/j); - * end for; - * S+:=2^(m-(m-1)*t)*s; - * end for; - * A:=2^(k-2-M*t); - * B:=8*(Pi(RealField(32))^2-6)/3*2^(k-2)*S; - * pkt:=2.00743*Log(2)*k*2^-k*(A+B); - * seclevel:=Floor(-Log(2,pkt)); - * if seclevel ge securitybits then - * printf "k: %5o, security: %o bits (t: %o, M: %o)\n",k,seclevel,t,M; - * break; - * end if; - * end for; - * if seclevel ge securitybits then break; end if; - * end for; - * - * It can be run online at: - * http://magma.maths.usyd.edu.au/calc - * - * And will output: - * k: 1024, security: 129 bits (t: 6, M: 23) - * - * k is the number of bits of the prime, securitybits is the level we want to - * reach. - * - * prime length | RSA key size | # MR tests | security level - * -------------+--------------|------------+--------------- - * (b) >= 6394 | >= 12788 | 3 | 256 bit - * (b) >= 3747 | >= 7494 | 3 | 192 bit - * (b) >= 1345 | >= 2690 | 4 | 128 bit - * (b) >= 1080 | >= 2160 | 5 | 128 bit - * (b) >= 852 | >= 1704 | 5 | 112 bit - * (b) >= 476 | >= 952 | 5 | 80 bit - * (b) >= 400 | >= 800 | 6 | 80 bit - * (b) >= 347 | >= 694 | 7 | 80 bit - * (b) >= 308 | >= 616 | 8 | 80 bit - * (b) >= 55 | >= 110 | 27 | 64 bit - * (b) >= 6 | >= 12 | 34 | 64 bit - */ - -# define BN_prime_checks_for_size(b) ((b) >= 3747 ? 3 : \ - (b) >= 1345 ? 4 : \ - (b) >= 476 ? 5 : \ - (b) >= 400 ? 6 : \ - (b) >= 347 ? 7 : \ - (b) >= 308 ? 8 : \ - (b) >= 55 ? 27 : \ - /* b >= 6 */ 34) - -# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) - -/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */ -# define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \ - (((w) == 0) && ((a)->top == 0))) -# define BN_is_zero(a) ((a)->top == 0) -# define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg) -# define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg)) -# define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) - -# define BN_one(a) (BN_set_word((a),1)) -# define BN_zero_ex(a) \ - do { \ - BIGNUM *_tmp_bn = (a); \ - _tmp_bn->top = 0; \ - _tmp_bn->neg = 0; \ - } while(0) -# ifdef OPENSSL_NO_DEPRECATED -# define BN_zero(a) BN_zero_ex(a) -# else -# define BN_zero(a) (BN_set_word((a),0)) -# endif - -const BIGNUM *BN_value_one(void); -char *BN_options(void); -BN_CTX *BN_CTX_new(void); -# ifndef OPENSSL_NO_DEPRECATED -void BN_CTX_init(BN_CTX *c); -# endif -void BN_CTX_free(BN_CTX *c); -void BN_CTX_start(BN_CTX *ctx); -BIGNUM *BN_CTX_get(BN_CTX *ctx); -void BN_CTX_end(BN_CTX *ctx); -int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); -int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); -int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); -int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); -int BN_num_bits(const BIGNUM *a); -int BN_num_bits_word(BN_ULONG); -BIGNUM *BN_new(void); -void BN_init(BIGNUM *); -void BN_clear_free(BIGNUM *a); -BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); -void BN_swap(BIGNUM *a, BIGNUM *b); -BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); -int BN_bn2bin(const BIGNUM *a, unsigned char *to); -BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); -int BN_bn2mpi(const BIGNUM *a, unsigned char *to); -int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); -int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); -int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); -int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); -int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); -int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); -/** BN_set_negative sets sign of a BIGNUM - * \param b pointer to the BIGNUM object - * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise - */ -void BN_set_negative(BIGNUM *b, int n); -/** BN_is_negative returns 1 if the BIGNUM is negative - * \param a pointer to the BIGNUM object - * \return 1 if a < 0 and 0 otherwise - */ -# define BN_is_negative(a) ((a)->neg != 0) - -int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, - BN_CTX *ctx); -# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) -int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); -int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, - BN_CTX *ctx); -int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *m); -int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, - BN_CTX *ctx); -int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *m); -int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, - BN_CTX *ctx); -int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); -int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); -int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); -int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, - BN_CTX *ctx); -int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); - -BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); -BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); -int BN_mul_word(BIGNUM *a, BN_ULONG w); -int BN_add_word(BIGNUM *a, BN_ULONG w); -int BN_sub_word(BIGNUM *a, BN_ULONG w); -int BN_set_word(BIGNUM *a, BN_ULONG w); -BN_ULONG BN_get_word(const BIGNUM *a); - -int BN_cmp(const BIGNUM *a, const BIGNUM *b); -void BN_free(BIGNUM *a); -int BN_is_bit_set(const BIGNUM *a, int n); -int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); -int BN_lshift1(BIGNUM *r, const BIGNUM *a); -int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); - -int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); -int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *in_mont); -int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, - const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *m_ctx); -int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); - -int BN_mask_bits(BIGNUM *a, int n); -# ifndef OPENSSL_NO_FP_API -int BN_print_fp(FILE *fp, const BIGNUM *a); -# endif -# ifdef HEADER_BIO_H -int BN_print(BIO *fp, const BIGNUM *a); -# else -int BN_print(void *fp, const BIGNUM *a); -# endif -int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); -int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); -int BN_rshift1(BIGNUM *r, const BIGNUM *a); -void BN_clear(BIGNUM *a); -BIGNUM *BN_dup(const BIGNUM *a); -int BN_ucmp(const BIGNUM *a, const BIGNUM *b); -int BN_set_bit(BIGNUM *a, int n); -int BN_clear_bit(BIGNUM *a, int n); -char *BN_bn2hex(const BIGNUM *a); -char *BN_bn2dec(const BIGNUM *a); -int BN_hex2bn(BIGNUM **a, const char *str); -int BN_dec2bn(BIGNUM **a, const char *str); -int BN_asc2bn(BIGNUM **a, const char *str); -int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); -int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns - * -2 for - * error */ -BIGNUM *BN_mod_inverse(BIGNUM *ret, - const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); -BIGNUM *BN_mod_sqrt(BIGNUM *ret, - const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); - -void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); - -/* Deprecated versions */ -# ifndef OPENSSL_NO_DEPRECATED -BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, - const BIGNUM *add, const BIGNUM *rem, - void (*callback) (int, int, void *), void *cb_arg); -int BN_is_prime(const BIGNUM *p, int nchecks, - void (*callback) (int, int, void *), - BN_CTX *ctx, void *cb_arg); -int BN_is_prime_fasttest(const BIGNUM *p, int nchecks, - void (*callback) (int, int, void *), BN_CTX *ctx, - void *cb_arg, int do_trial_division); -# endif /* !defined(OPENSSL_NO_DEPRECATED) */ - -/* Newer versions */ -int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, - const BIGNUM *rem, BN_GENCB *cb); -int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); -int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, - int do_trial_division, BN_GENCB *cb); - -int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); - -int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, - const BIGNUM *Xp, const BIGNUM *Xp1, - const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, - BN_GENCB *cb); -int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1, - BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, - BN_CTX *ctx, BN_GENCB *cb); - -BN_MONT_CTX *BN_MONT_CTX_new(void); -void BN_MONT_CTX_init(BN_MONT_CTX *ctx); -int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - BN_MONT_CTX *mont, BN_CTX *ctx); -# define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ - (r),(a),&((mont)->RR),(mont),(ctx)) -int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, - BN_MONT_CTX *mont, BN_CTX *ctx); -void BN_MONT_CTX_free(BN_MONT_CTX *mont); -int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); -BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); -BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, - const BIGNUM *mod, BN_CTX *ctx); - -/* BN_BLINDING flags */ -# define BN_BLINDING_NO_UPDATE 0x00000001 -# define BN_BLINDING_NO_RECREATE 0x00000002 - -BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); -void BN_BLINDING_free(BN_BLINDING *b); -int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx); -int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); -int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); -int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); -int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, - BN_CTX *); -# ifndef OPENSSL_NO_DEPRECATED -unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); -void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); -# endif -CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); -unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); -void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); -BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, - const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, - int (*bn_mod_exp) (BIGNUM *r, - const BIGNUM *a, - const BIGNUM *p, - const BIGNUM *m, - BN_CTX *ctx, - BN_MONT_CTX *m_ctx), - BN_MONT_CTX *m_ctx); - -# ifndef OPENSSL_NO_DEPRECATED -void BN_set_params(int mul, int high, int low, int mont); -int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ -# endif - -void BN_RECP_CTX_init(BN_RECP_CTX *recp); -BN_RECP_CTX *BN_RECP_CTX_new(void); -void BN_RECP_CTX_free(BN_RECP_CTX *recp); -int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); -int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, - BN_RECP_CTX *recp, BN_CTX *ctx); -int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); -int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, - BN_RECP_CTX *recp, BN_CTX *ctx); - -# ifndef OPENSSL_NO_EC2M - -/* - * Functions for arithmetic over binary polynomials represented by BIGNUMs. - * The BIGNUM::neg property of BIGNUMs representing binary polynomials is - * ignored. Note that input arguments are not const so that their bit arrays - * can be expanded to the appropriate size if needed. - */ - -/* - * r = a + b - */ -int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); -# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) -/* - * r=a mod p - */ -int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); -/* r = (a * b) mod p */ -int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *p, BN_CTX *ctx); -/* r = (a * a) mod p */ -int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); -/* r = (1 / b) mod p */ -int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); -/* r = (a / b) mod p */ -int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *p, BN_CTX *ctx); -/* r = (a ^ b) mod p */ -int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *p, BN_CTX *ctx); -/* r = sqrt(a) mod p */ -int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - BN_CTX *ctx); -/* r^2 + r = a mod p */ -int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - BN_CTX *ctx); -# define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) -/*- - * Some functions allow for representation of the irreducible polynomials - * as an unsigned int[], say p. The irreducible f(t) is then of the form: - * t^p[0] + t^p[1] + ... + t^p[k] - * where m = p[0] > p[1] > ... > p[k] = 0. - */ -/* r = a mod p */ -int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); -/* r = (a * b) mod p */ -int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const int p[], BN_CTX *ctx); -/* r = (a * a) mod p */ -int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], - BN_CTX *ctx); -/* r = (1 / b) mod p */ -int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], - BN_CTX *ctx); -/* r = (a / b) mod p */ -int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const int p[], BN_CTX *ctx); -/* r = (a ^ b) mod p */ -int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const int p[], BN_CTX *ctx); -/* r = sqrt(a) mod p */ -int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, - const int p[], BN_CTX *ctx); -/* r^2 + r = a mod p */ -int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, - const int p[], BN_CTX *ctx); -int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); -int BN_GF2m_arr2poly(const int p[], BIGNUM *a); - -# endif - -/* - * faster mod functions for the 'NIST primes' 0 <= a < p^2 - */ -int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); -int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); -int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); -int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); -int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); - -const BIGNUM *BN_get0_nist_prime_192(void); -const BIGNUM *BN_get0_nist_prime_224(void); -const BIGNUM *BN_get0_nist_prime_256(void); -const BIGNUM *BN_get0_nist_prime_384(void); -const BIGNUM *BN_get0_nist_prime_521(void); - -/* library internal functions */ - -# define bn_expand(a,bits) \ - ( \ - bits > (INT_MAX - BN_BITS2 + 1) ? \ - NULL \ - : \ - (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \ - (a) \ - : \ - bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \ - ) - -# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) -BIGNUM *bn_expand2(BIGNUM *a, int words); -# ifndef OPENSSL_NO_DEPRECATED -BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */ -# endif - -/*- - * Bignum consistency macros - * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from - * bignum data after direct manipulations on the data. There is also an - * "internal" macro, bn_check_top(), for verifying that there are no leading - * zeroes. Unfortunately, some auditing is required due to the fact that - * bn_fix_top() has become an overabused duct-tape because bignum data is - * occasionally passed around in an inconsistent state. So the following - * changes have been made to sort this out; - * - bn_fix_top()s implementation has been moved to bn_correct_top() - * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and - * bn_check_top() is as before. - * - if BN_DEBUG *is* defined; - * - bn_check_top() tries to pollute unused words even if the bignum 'top' is - * consistent. (ed: only if BN_DEBUG_RAND is defined) - * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything. - * The idea is to have debug builds flag up inconsistent bignums when they - * occur. If that occurs in a bn_fix_top(), we examine the code in question; if - * the use of bn_fix_top() was appropriate (ie. it follows directly after code - * that manipulates the bignum) it is converted to bn_correct_top(), and if it - * was not appropriate, we convert it permanently to bn_check_top() and track - * down the cause of the bug. Eventually, no internal code should be using the - * bn_fix_top() macro. External applications and libraries should try this with - * their own code too, both in terms of building against the openssl headers - * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it - * defined. This not only improves external code, it provides more test - * coverage for openssl's own code. - */ - -# ifdef BN_DEBUG - -/* We only need assert() when debugging */ -# include - -/* - * The new BN_FLG_FIXED_TOP flag marks vectors that were not treated with - * bn_correct_top, in other words such vectors are permitted to have zeros - * in most significant limbs. Such vectors are used internally to achieve - * execution time invariance for critical operations with private keys. - * It's BN_DEBUG-only flag, because user application is not supposed to - * observe it anyway. Moreover, optimizing compiler would actually remove - * all operations manipulating the bit in question in non-BN_DEBUG build. - */ -# define BN_FLG_FIXED_TOP 0x10000 -# ifdef BN_DEBUG_RAND -/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */ -# ifndef RAND_pseudo_bytes -int RAND_pseudo_bytes(unsigned char *buf, int num); -# define BN_DEBUG_TRIX -# endif -# define bn_pollute(a) \ - do { \ - const BIGNUM *_bnum1 = (a); \ - if(_bnum1->top < _bnum1->dmax) { \ - unsigned char _tmp_char; \ - /* We cast away const without the compiler knowing, any \ - * *genuinely* constant variables that aren't mutable \ - * wouldn't be constructed with top!=dmax. */ \ - BN_ULONG *_not_const; \ - memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \ - /* Debug only - safe to ignore error return */ \ - RAND_pseudo_bytes(&_tmp_char, 1); \ - memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \ - (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \ - } \ - } while(0) -# ifdef BN_DEBUG_TRIX -# undef RAND_pseudo_bytes -# endif -# else -# define bn_pollute(a) -# endif -# define bn_check_top(a) \ - do { \ - const BIGNUM *_bnum2 = (a); \ - if (_bnum2 != NULL) { \ - int _top = _bnum2->top; \ - assert((_top == 0) || \ - (_bnum2->flags & BN_FLG_FIXED_TOP) || \ - (_bnum2->d[_top - 1] != 0)); \ - bn_pollute(_bnum2); \ - } \ - } while(0) - -# define bn_fix_top(a) bn_check_top(a) - -# define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) -# define bn_wcheck_size(bn, words) \ - do { \ - const BIGNUM *_bnum2 = (bn); \ - assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \ - /* avoid unused variable warning with NDEBUG */ \ - (void)(_bnum2); \ - } while(0) - -# else /* !BN_DEBUG */ - -# define BN_FLG_FIXED_TOP 0 -# define bn_pollute(a) -# define bn_check_top(a) -# define bn_fix_top(a) bn_correct_top(a) -# define bn_check_size(bn, bits) -# define bn_wcheck_size(bn, words) - -# endif - -# define bn_correct_top(a) \ - { \ - BN_ULONG *ftl; \ - int tmp_top = (a)->top; \ - if (tmp_top > 0) \ - { \ - for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \ - if (*(ftl--)) break; \ - (a)->top = tmp_top; \ - } \ - if ((a)->top == 0) \ - (a)->neg = 0; \ - bn_pollute(a); \ - } - -BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, - BN_ULONG w); -BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); -void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); -BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); -BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - int num); -BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - int num); - -/* Primes from RFC 2409 */ -BIGNUM *get_rfc2409_prime_768(BIGNUM *bn); -BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn); - -/* Primes from RFC 3526 */ -BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn); -BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn); -BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn); -BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn); -BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn); -BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn); - -int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_BN_strings(void); - -/* Error codes for the BN functions. */ - -/* Function codes. */ -# define BN_F_BNRAND 127 -# define BN_F_BN_BLINDING_CONVERT_EX 100 -# define BN_F_BN_BLINDING_CREATE_PARAM 128 -# define BN_F_BN_BLINDING_INVERT_EX 101 -# define BN_F_BN_BLINDING_NEW 102 -# define BN_F_BN_BLINDING_UPDATE 103 -# define BN_F_BN_BN2DEC 104 -# define BN_F_BN_BN2HEX 105 -# define BN_F_BN_CTX_GET 116 -# define BN_F_BN_CTX_NEW 106 -# define BN_F_BN_CTX_START 129 -# define BN_F_BN_DIV 107 -# define BN_F_BN_DIV_NO_BRANCH 138 -# define BN_F_BN_DIV_RECP 130 -# define BN_F_BN_EXP 123 -# define BN_F_BN_EXPAND2 108 -# define BN_F_BN_EXPAND_INTERNAL 120 -# define BN_F_BN_GF2M_MOD 131 -# define BN_F_BN_GF2M_MOD_EXP 132 -# define BN_F_BN_GF2M_MOD_MUL 133 -# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 -# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 -# define BN_F_BN_GF2M_MOD_SQR 136 -# define BN_F_BN_GF2M_MOD_SQRT 137 -# define BN_F_BN_LSHIFT 145 -# define BN_F_BN_MOD_EXP2_MONT 118 -# define BN_F_BN_MOD_EXP_MONT 109 -# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 -# define BN_F_BN_MOD_EXP_MONT_WORD 117 -# define BN_F_BN_MOD_EXP_RECP 125 -# define BN_F_BN_MOD_EXP_SIMPLE 126 -# define BN_F_BN_MOD_INVERSE 110 -# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 -# define BN_F_BN_MOD_LSHIFT_QUICK 119 -# define BN_F_BN_MOD_MUL_RECIPROCAL 111 -# define BN_F_BN_MOD_SQRT 121 -# define BN_F_BN_MPI2BN 112 -# define BN_F_BN_NEW 113 -# define BN_F_BN_RAND 114 -# define BN_F_BN_RAND_RANGE 122 -# define BN_F_BN_RSHIFT 146 -# define BN_F_BN_USUB 115 - -/* Reason codes. */ -# define BN_R_ARG2_LT_ARG3 100 -# define BN_R_BAD_RECIPROCAL 101 -# define BN_R_BIGNUM_TOO_LONG 114 -# define BN_R_BITS_TOO_SMALL 118 -# define BN_R_CALLED_WITH_EVEN_MODULUS 102 -# define BN_R_DIV_BY_ZERO 103 -# define BN_R_ENCODING_ERROR 104 -# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 -# define BN_R_INPUT_NOT_REDUCED 110 -# define BN_R_INVALID_LENGTH 106 -# define BN_R_INVALID_RANGE 115 -# define BN_R_INVALID_SHIFT 119 -# define BN_R_NOT_A_SQUARE 111 -# define BN_R_NOT_INITIALIZED 107 -# define BN_R_NO_INVERSE 108 -# define BN_R_NO_SOLUTION 116 -# define BN_R_P_IS_NOT_PRIME 112 -# define BN_R_TOO_MANY_ITERATIONS 113 -# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/bn_.c b/Sources/COpenSSL/bn_.c deleted file mode 100644 index a49987fd..00000000 --- a/Sources/COpenSSL/bn_.c +++ /dev/null @@ -1,14933 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/bn/bn_add.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "bn_lcl.h" - -/* r can == a or b */ -int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) -{ - const BIGNUM *tmp; - int a_neg = a->neg, ret; - - bn_check_top(a); - bn_check_top(b); - - /*- - * a + b a+b - * a + -b a-b - * -a + b b-a - * -a + -b -(a+b) - */ - if (a_neg ^ b->neg) { - /* only one is negative */ - if (a_neg) { - tmp = a; - a = b; - b = tmp; - } - - /* we are now a - b */ - - if (BN_ucmp(a, b) < 0) { - if (!BN_usub(r, b, a)) - return (0); - r->neg = 1; - } else { - if (!BN_usub(r, a, b)) - return (0); - r->neg = 0; - } - return (1); - } - - ret = BN_uadd(r, a, b); - r->neg = a_neg; - bn_check_top(r); - return ret; -} - -/* unsigned add of b to a */ -int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) -{ - int max, min, dif; - BN_ULONG *ap, *bp, *rp, carry, t1, t2; - const BIGNUM *tmp; - - bn_check_top(a); - bn_check_top(b); - - if (a->top < b->top) { - tmp = a; - a = b; - b = tmp; - } - max = a->top; - min = b->top; - dif = max - min; - - if (bn_wexpand(r, max + 1) == NULL) - return 0; - - r->top = max; - - ap = a->d; - bp = b->d; - rp = r->d; - - carry = bn_add_words(rp, ap, bp, min); - rp += min; - ap += min; - bp += min; - - if (carry) { - while (dif) { - dif--; - t1 = *(ap++); - t2 = (t1 + 1) & BN_MASK2; - *(rp++) = t2; - if (t2) { - carry = 0; - break; - } - } - if (carry) { - /* carry != 0 => dif == 0 */ - *rp = 1; - r->top++; - } - } - if (dif && rp != ap) - while (dif--) - /* copy remaining words if ap != rp */ - *(rp++) = *(ap++); - r->neg = 0; - bn_check_top(r); - return 1; -} - -/* unsigned subtraction of b from a, a must be larger than b. */ -int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) -{ - int max, min, dif; - register BN_ULONG t1, t2, *ap, *bp, *rp; - int i, carry; -#if defined(IRIX_CC_BUG) && !defined(LINT) - int dummy; -#endif - - bn_check_top(a); - bn_check_top(b); - - max = a->top; - min = b->top; - dif = max - min; - - if (dif < 0) { /* hmm... should not be happening */ - BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3); - return (0); - } - - if (bn_wexpand(r, max) == NULL) - return (0); - - ap = a->d; - bp = b->d; - rp = r->d; - -#if 1 - carry = 0; - for (i = min; i != 0; i--) { - t1 = *(ap++); - t2 = *(bp++); - if (carry) { - carry = (t1 <= t2); - t1 = (t1 - t2 - 1) & BN_MASK2; - } else { - carry = (t1 < t2); - t1 = (t1 - t2) & BN_MASK2; - } -# if defined(IRIX_CC_BUG) && !defined(LINT) - dummy = t1; -# endif - *(rp++) = t1 & BN_MASK2; - } -#else - carry = bn_sub_words(rp, ap, bp, min); - ap += min; - bp += min; - rp += min; -#endif - if (carry) { /* subtracted */ - if (!dif) - /* error: a < b */ - return 0; - while (dif) { - dif--; - t1 = *(ap++); - t2 = (t1 - 1) & BN_MASK2; - *(rp++) = t2; - if (t1) - break; - } - } -#if 0 - memcpy(rp, ap, sizeof(*rp) * (max - i)); -#else - if (rp != ap) { - for (;;) { - if (!dif--) - break; - rp[0] = ap[0]; - if (!dif--) - break; - rp[1] = ap[1]; - if (!dif--) - break; - rp[2] = ap[2]; - if (!dif--) - break; - rp[3] = ap[3]; - rp += 4; - ap += 4; - } - } -#endif - - r->top = max; - r->neg = 0; - bn_correct_top(r); - return (1); -} - -int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) -{ - int max; - int add = 0, neg = 0; - const BIGNUM *tmp; - - bn_check_top(a); - bn_check_top(b); - - /*- - * a - b a-b - * a - -b a+b - * -a - b -(a+b) - * -a - -b b-a - */ - if (a->neg) { - if (b->neg) { - tmp = a; - a = b; - b = tmp; - } else { - add = 1; - neg = 1; - } - } else { - if (b->neg) { - add = 1; - neg = 0; - } - } - - if (add) { - if (!BN_uadd(r, a, b)) - return (0); - r->neg = neg; - return (1); - } - - /* We are actually doing a - b :-) */ - - max = (a->top > b->top) ? a->top : b->top; - if (bn_wexpand(r, max) == NULL) - return (0); - if (BN_ucmp(a, b) < 0) { - if (!BN_usub(r, b, a)) - return (0); - r->neg = 1; - } else { - if (!BN_usub(r, a, b)) - return (0); - r->neg = 0; - } - bn_check_top(r); - return (1); -} -/* crypto/bn/bn_asm.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef BN_DEBUG -# undef NDEBUG /* avoid conflicting definitions */ -# define NDEBUG -#endif - -#include -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -#if defined(BN_LLONG) || defined(BN_UMULT_HIGH) - -BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, - BN_ULONG w) -{ - BN_ULONG c1 = 0; - - assert(num >= 0); - if (num <= 0) - return (c1); - -# ifndef OPENSSL_SMALL_FOOTPRINT - while (num & ~3) { - mul_add(rp[0], ap[0], w, c1); - mul_add(rp[1], ap[1], w, c1); - mul_add(rp[2], ap[2], w, c1); - mul_add(rp[3], ap[3], w, c1); - ap += 4; - rp += 4; - num -= 4; - } -# endif - while (num) { - mul_add(rp[0], ap[0], w, c1); - ap++; - rp++; - num--; - } - - return (c1); -} - -BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) -{ - BN_ULONG c1 = 0; - - assert(num >= 0); - if (num <= 0) - return (c1); - -# ifndef OPENSSL_SMALL_FOOTPRINT - while (num & ~3) { - mul(rp[0], ap[0], w, c1); - mul(rp[1], ap[1], w, c1); - mul(rp[2], ap[2], w, c1); - mul(rp[3], ap[3], w, c1); - ap += 4; - rp += 4; - num -= 4; - } -# endif - while (num) { - mul(rp[0], ap[0], w, c1); - ap++; - rp++; - num--; - } - return (c1); -} - -void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) -{ - assert(n >= 0); - if (n <= 0) - return; - -# ifndef OPENSSL_SMALL_FOOTPRINT - while (n & ~3) { - sqr(r[0], r[1], a[0]); - sqr(r[2], r[3], a[1]); - sqr(r[4], r[5], a[2]); - sqr(r[6], r[7], a[3]); - a += 4; - r += 8; - n -= 4; - } -# endif - while (n) { - sqr(r[0], r[1], a[0]); - a++; - r += 2; - n--; - } -} - -#else /* !(defined(BN_LLONG) || - * defined(BN_UMULT_HIGH)) */ - -BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, - BN_ULONG w) -{ - BN_ULONG c = 0; - BN_ULONG bl, bh; - - assert(num >= 0); - if (num <= 0) - return ((BN_ULONG)0); - - bl = LBITS(w); - bh = HBITS(w); - -# ifndef OPENSSL_SMALL_FOOTPRINT - while (num & ~3) { - mul_add(rp[0], ap[0], bl, bh, c); - mul_add(rp[1], ap[1], bl, bh, c); - mul_add(rp[2], ap[2], bl, bh, c); - mul_add(rp[3], ap[3], bl, bh, c); - ap += 4; - rp += 4; - num -= 4; - } -# endif - while (num) { - mul_add(rp[0], ap[0], bl, bh, c); - ap++; - rp++; - num--; - } - return (c); -} - -BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) -{ - BN_ULONG carry = 0; - BN_ULONG bl, bh; - - assert(num >= 0); - if (num <= 0) - return ((BN_ULONG)0); - - bl = LBITS(w); - bh = HBITS(w); - -# ifndef OPENSSL_SMALL_FOOTPRINT - while (num & ~3) { - mul(rp[0], ap[0], bl, bh, carry); - mul(rp[1], ap[1], bl, bh, carry); - mul(rp[2], ap[2], bl, bh, carry); - mul(rp[3], ap[3], bl, bh, carry); - ap += 4; - rp += 4; - num -= 4; - } -# endif - while (num) { - mul(rp[0], ap[0], bl, bh, carry); - ap++; - rp++; - num--; - } - return (carry); -} - -void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) -{ - assert(n >= 0); - if (n <= 0) - return; - -# ifndef OPENSSL_SMALL_FOOTPRINT - while (n & ~3) { - sqr64(r[0], r[1], a[0]); - sqr64(r[2], r[3], a[1]); - sqr64(r[4], r[5], a[2]); - sqr64(r[6], r[7], a[3]); - a += 4; - r += 8; - n -= 4; - } -# endif - while (n) { - sqr64(r[0], r[1], a[0]); - a++; - r += 2; - n--; - } -} - -#endif /* !(defined(BN_LLONG) || - * defined(BN_UMULT_HIGH)) */ - -#if defined(BN_LLONG) && defined(BN_DIV2W) - -BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) -{ - return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d)); -} - -#else - -/* Divide h,l by d and return the result. */ -/* I need to test this some more :-( */ -BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) -{ - BN_ULONG dh, dl, q, ret = 0, th, tl, t; - int i, count = 2; - - if (d == 0) - return (BN_MASK2); - - i = BN_num_bits_word(d); - assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i)); - - i = BN_BITS2 - i; - if (h >= d) - h -= d; - - if (i) { - d <<= i; - h = (h << i) | (l >> (BN_BITS2 - i)); - l <<= i; - } - dh = (d & BN_MASK2h) >> BN_BITS4; - dl = (d & BN_MASK2l); - for (;;) { - if ((h >> BN_BITS4) == dh) - q = BN_MASK2l; - else - q = h / dh; - - th = q * dh; - tl = dl * q; - for (;;) { - t = h - th; - if ((t & BN_MASK2h) || - ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) - break; - q--; - th -= dh; - tl -= dl; - } - t = (tl >> BN_BITS4); - tl = (tl << BN_BITS4) & BN_MASK2h; - th += t; - - if (l < tl) - th++; - l -= tl; - if (h < th) { - h += d; - q--; - } - h -= th; - - if (--count == 0) - break; - - ret = q << BN_BITS4; - h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2; - l = (l & BN_MASK2l) << BN_BITS4; - } - ret |= q; - return (ret); -} -#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */ - -#ifdef BN_LLONG -BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - int n) -{ - BN_ULLONG ll = 0; - - assert(n >= 0); - if (n <= 0) - return ((BN_ULONG)0); - -# ifndef OPENSSL_SMALL_FOOTPRINT - while (n & ~3) { - ll += (BN_ULLONG) a[0] + b[0]; - r[0] = (BN_ULONG)ll & BN_MASK2; - ll >>= BN_BITS2; - ll += (BN_ULLONG) a[1] + b[1]; - r[1] = (BN_ULONG)ll & BN_MASK2; - ll >>= BN_BITS2; - ll += (BN_ULLONG) a[2] + b[2]; - r[2] = (BN_ULONG)ll & BN_MASK2; - ll >>= BN_BITS2; - ll += (BN_ULLONG) a[3] + b[3]; - r[3] = (BN_ULONG)ll & BN_MASK2; - ll >>= BN_BITS2; - a += 4; - b += 4; - r += 4; - n -= 4; - } -# endif - while (n) { - ll += (BN_ULLONG) a[0] + b[0]; - r[0] = (BN_ULONG)ll & BN_MASK2; - ll >>= BN_BITS2; - a++; - b++; - r++; - n--; - } - return ((BN_ULONG)ll); -} -#else /* !BN_LLONG */ -BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - int n) -{ - BN_ULONG c, l, t; - - assert(n >= 0); - if (n <= 0) - return ((BN_ULONG)0); - - c = 0; -# ifndef OPENSSL_SMALL_FOOTPRINT - while (n & ~3) { - t = a[0]; - t = (t + c) & BN_MASK2; - c = (t < c); - l = (t + b[0]) & BN_MASK2; - c += (l < t); - r[0] = l; - t = a[1]; - t = (t + c) & BN_MASK2; - c = (t < c); - l = (t + b[1]) & BN_MASK2; - c += (l < t); - r[1] = l; - t = a[2]; - t = (t + c) & BN_MASK2; - c = (t < c); - l = (t + b[2]) & BN_MASK2; - c += (l < t); - r[2] = l; - t = a[3]; - t = (t + c) & BN_MASK2; - c = (t < c); - l = (t + b[3]) & BN_MASK2; - c += (l < t); - r[3] = l; - a += 4; - b += 4; - r += 4; - n -= 4; - } -# endif - while (n) { - t = a[0]; - t = (t + c) & BN_MASK2; - c = (t < c); - l = (t + b[0]) & BN_MASK2; - c += (l < t); - r[0] = l; - a++; - b++; - r++; - n--; - } - return ((BN_ULONG)c); -} -#endif /* !BN_LLONG */ - -BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - int n) -{ - BN_ULONG t1, t2; - int c = 0; - - assert(n >= 0); - if (n <= 0) - return ((BN_ULONG)0); - -#ifndef OPENSSL_SMALL_FOOTPRINT - while (n & ~3) { - t1 = a[0]; - t2 = b[0]; - r[0] = (t1 - t2 - c) & BN_MASK2; - if (t1 != t2) - c = (t1 < t2); - t1 = a[1]; - t2 = b[1]; - r[1] = (t1 - t2 - c) & BN_MASK2; - if (t1 != t2) - c = (t1 < t2); - t1 = a[2]; - t2 = b[2]; - r[2] = (t1 - t2 - c) & BN_MASK2; - if (t1 != t2) - c = (t1 < t2); - t1 = a[3]; - t2 = b[3]; - r[3] = (t1 - t2 - c) & BN_MASK2; - if (t1 != t2) - c = (t1 < t2); - a += 4; - b += 4; - r += 4; - n -= 4; - } -#endif - while (n) { - t1 = a[0]; - t2 = b[0]; - r[0] = (t1 - t2 - c) & BN_MASK2; - if (t1 != t2) - c = (t1 < t2); - a++; - b++; - r++; - n--; - } - return (c); -} - -#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT) - -# undef bn_mul_comba8 -# undef bn_mul_comba4 -# undef bn_sqr_comba8 -# undef bn_sqr_comba4 - -/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */ -/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */ -/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ -/* - * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number - * c=(c2,c1,c0) - */ - -# ifdef BN_LLONG -/* - * Keep in mind that additions to multiplication result can not - * overflow, because its high half cannot be all-ones. - */ -# define mul_add_c(a,b,c0,c1,c2) do { \ - BN_ULONG hi; \ - BN_ULLONG t = (BN_ULLONG)(a)*(b); \ - t += c0; /* no carry */ \ - c0 = (BN_ULONG)Lw(t); \ - hi = (BN_ULONG)Hw(t); \ - c1 = (c1+hi)&BN_MASK2; if (c1 -/* - * This is essentially reference implementation, which may or may not - * result in performance improvement. E.g. on IA-32 this routine was - * observed to give 40% faster rsa1024 private key operations and 10% - * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only - * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a - * reference implementation, one to be used as starting point for - * platform-specific assembler. Mentioned numbers apply to compiler - * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and - * can vary not only from platform to platform, but even for compiler - * versions. Assembler vs. assembler improvement coefficients can - * [and are known to] differ and are to be documented elsewhere. - */ -int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0p, int num) -{ - BN_ULONG c0, c1, ml, *tp, n0; -# ifdef mul64 - BN_ULONG mh; -# endif - volatile BN_ULONG *vp; - int i = 0, j; - -# if 0 /* template for platform-specific - * implementation */ - if (ap == bp) - return bn_sqr_mont(rp, ap, np, n0p, num); -# endif - vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); - - n0 = *n0p; - - c0 = 0; - ml = bp[0]; -# ifdef mul64 - mh = HBITS(ml); - ml = LBITS(ml); - for (j = 0; j < num; ++j) - mul(tp[j], ap[j], ml, mh, c0); -# else - for (j = 0; j < num; ++j) - mul(tp[j], ap[j], ml, c0); -# endif - - tp[num] = c0; - tp[num + 1] = 0; - goto enter; - - for (i = 0; i < num; i++) { - c0 = 0; - ml = bp[i]; -# ifdef mul64 - mh = HBITS(ml); - ml = LBITS(ml); - for (j = 0; j < num; ++j) - mul_add(tp[j], ap[j], ml, mh, c0); -# else - for (j = 0; j < num; ++j) - mul_add(tp[j], ap[j], ml, c0); -# endif - c1 = (tp[num] + c0) & BN_MASK2; - tp[num] = c1; - tp[num + 1] = (c1 < c0 ? 1 : 0); - enter: - c1 = tp[0]; - ml = (c1 * n0) & BN_MASK2; - c0 = 0; -# ifdef mul64 - mh = HBITS(ml); - ml = LBITS(ml); - mul_add(c1, np[0], ml, mh, c0); -# else - mul_add(c1, ml, np[0], c0); -# endif - for (j = 1; j < num; j++) { - c1 = tp[j]; -# ifdef mul64 - mul_add(c1, np[j], ml, mh, c0); -# else - mul_add(c1, ml, np[j], c0); -# endif - tp[j - 1] = c1 & BN_MASK2; - } - c1 = (tp[num] + c0) & BN_MASK2; - tp[num - 1] = c1; - tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0); - } - - if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { - c0 = bn_sub_words(rp, tp, np, num); - if (tp[num] != 0 || c0 == 0) { - for (i = 0; i < num + 2; i++) - vp[i] = 0; - return 1; - } - } - for (i = 0; i < num; i++) - rp[i] = tp[i], vp[i] = 0; - vp[num] = 0; - vp[num + 1] = 0; - return 1; -} -# else -/* - * Return value of 0 indicates that multiplication/convolution was not - * performed to signal the caller to fall down to alternative/original - * code-path. - */ -int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num) -{ - return 0; -} -# endif /* OPENSSL_BN_ASM_MONT */ -# endif - -#else /* !BN_MUL_COMBA */ - -/* hmm... is it faster just to do a multiply? */ -# undef bn_sqr_comba4 -void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) -{ - BN_ULONG t[8]; - bn_sqr_normal(r, a, 4, t); -} - -# undef bn_sqr_comba8 -void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) -{ - BN_ULONG t[16]; - bn_sqr_normal(r, a, 8, t); -} - -void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) -{ - r[4] = bn_mul_words(&(r[0]), a, 4, b[0]); - r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]); - r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]); - r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]); -} - -void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) -{ - r[8] = bn_mul_words(&(r[0]), a, 8, b[0]); - r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]); - r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]); - r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]); - r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]); - r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]); - r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]); - r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]); -} - -# ifdef OPENSSL_NO_ASM -# ifdef OPENSSL_BN_ASM_MONT -# include -int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0p, int num) -{ - BN_ULONG c0, c1, *tp, n0 = *n0p; - volatile BN_ULONG *vp; - int i = 0, j; - - vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); - - for (i = 0; i <= num; i++) - tp[i] = 0; - - for (i = 0; i < num; i++) { - c0 = bn_mul_add_words(tp, ap, num, bp[i]); - c1 = (tp[num] + c0) & BN_MASK2; - tp[num] = c1; - tp[num + 1] = (c1 < c0 ? 1 : 0); - - c0 = bn_mul_add_words(tp, np, num, tp[0] * n0); - c1 = (tp[num] + c0) & BN_MASK2; - tp[num] = c1; - tp[num + 1] += (c1 < c0 ? 1 : 0); - for (j = 0; j <= num; j++) - tp[j] = tp[j + 1]; - } - - if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { - c0 = bn_sub_words(rp, tp, np, num); - if (tp[num] != 0 || c0 == 0) { - for (i = 0; i < num + 2; i++) - vp[i] = 0; - return 1; - } - } - for (i = 0; i < num; i++) - rp[i] = tp[i], vp[i] = 0; - vp[num] = 0; - vp[num + 1] = 0; - return 1; -} -# else -int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num) -{ - return 0; -} -# endif /* OPENSSL_BN_ASM_MONT */ -# endif - -#endif /* !BN_MUL_COMBA */ -/* crypto/bn/bn_blind.c */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -#define BN_BLINDING_COUNTER 32 - -struct bn_blinding_st { - BIGNUM *A; - BIGNUM *Ai; - BIGNUM *e; - BIGNUM *mod; /* just a reference */ -#ifndef OPENSSL_NO_DEPRECATED - unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; used - * only by crypto/rsa/rsa_eay.c, rsa_lib.c */ -#endif - CRYPTO_THREADID tid; - int counter; - unsigned long flags; - BN_MONT_CTX *m_ctx; - int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -}; - -BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) -{ - BN_BLINDING *ret = NULL; - - bn_check_top(mod); - - if ((ret = (BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL) { - BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - memset(ret, 0, sizeof(BN_BLINDING)); - if (A != NULL) { - if ((ret->A = BN_dup(A)) == NULL) - goto err; - } - if (Ai != NULL) { - if ((ret->Ai = BN_dup(Ai)) == NULL) - goto err; - } - - /* save a copy of mod in the BN_BLINDING structure */ - if ((ret->mod = BN_dup(mod)) == NULL) - goto err; - if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) - BN_set_flags(ret->mod, BN_FLG_CONSTTIME); - - /* - * Set the counter to the special value -1 to indicate that this is - * never-used fresh blinding that does not need updating before first - * use. - */ - ret->counter = -1; - CRYPTO_THREADID_current(&ret->tid); - return (ret); - err: - if (ret != NULL) - BN_BLINDING_free(ret); - return (NULL); -} - -void BN_BLINDING_free(BN_BLINDING *r) -{ - if (r == NULL) - return; - - if (r->A != NULL) - BN_free(r->A); - if (r->Ai != NULL) - BN_free(r->Ai); - if (r->e != NULL) - BN_free(r->e); - if (r->mod != NULL) - BN_free(r->mod); - OPENSSL_free(r); -} - -int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) -{ - int ret = 0; - - if ((b->A == NULL) || (b->Ai == NULL)) { - BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED); - goto err; - } - - if (b->counter == -1) - b->counter = 0; - - if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL && - !(b->flags & BN_BLINDING_NO_RECREATE)) { - /* re-create blinding parameters */ - if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) - goto err; - } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) { - if (b->m_ctx != NULL) { - if (!bn_mul_mont_fixed_top(b->Ai, b->Ai, b->Ai, b->m_ctx, ctx) - || !bn_mul_mont_fixed_top(b->A, b->A, b->A, b->m_ctx, ctx)) - goto err; - } else { - if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx) - || !BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) - goto err; - } - } - - ret = 1; - err: - if (b->counter == BN_BLINDING_COUNTER) - b->counter = 0; - return (ret); -} - -int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) -{ - return BN_BLINDING_convert_ex(n, NULL, b, ctx); -} - -int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) -{ - int ret = 1; - - bn_check_top(n); - - if ((b->A == NULL) || (b->Ai == NULL)) { - BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED); - return (0); - } - - if (b->counter == -1) - /* Fresh blinding, doesn't need updating. */ - b->counter = 0; - else if (!BN_BLINDING_update(b, ctx)) - return (0); - - if (r != NULL && (BN_copy(r, b->Ai) == NULL)) - return 0; - - if (b->m_ctx != NULL) - ret = BN_mod_mul_montgomery(n, n, b->A, b->m_ctx, ctx); - else - ret = BN_mod_mul(n, n, b->A, b->mod, ctx); - - return ret; -} - -int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) -{ - return BN_BLINDING_invert_ex(n, NULL, b, ctx); -} - -int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, - BN_CTX *ctx) -{ - int ret; - - bn_check_top(n); - - if (r == NULL && (r = b->Ai) == NULL) { - BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); - return 0; - } - - if (b->m_ctx != NULL) { - /* ensure that BN_mod_mul_montgomery takes pre-defined path */ - if (n->dmax >= r->top) { - size_t i, rtop = r->top, ntop = n->top; - BN_ULONG mask; - - for (i = 0; i < rtop; i++) { - mask = (BN_ULONG)0 - ((i - ntop) >> (8 * sizeof(i) - 1)); - n->d[i] &= mask; - } - mask = (BN_ULONG)0 - ((rtop - ntop) >> (8 * sizeof(ntop) - 1)); - /* always true, if (rtop >= ntop) n->top = r->top; */ - n->top = (int)(rtop & ~mask) | (ntop & mask); - n->flags |= (BN_FLG_FIXED_TOP & ~mask); - } - ret = BN_mod_mul_montgomery(n, n, r, b->m_ctx, ctx); - } else { - ret = BN_mod_mul(n, n, r, b->mod, ctx); - } - - bn_check_top(n); - return (ret); -} - -#ifndef OPENSSL_NO_DEPRECATED -unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b) -{ - return b->thread_id; -} - -void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) -{ - b->thread_id = n; -} -#endif - -CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b) -{ - return &b->tid; -} - -unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) -{ - return b->flags; -} - -void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) -{ - b->flags = flags; -} - -BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, - const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, - int (*bn_mod_exp) (BIGNUM *r, - const BIGNUM *a, - const BIGNUM *p, - const BIGNUM *m, - BN_CTX *ctx, - BN_MONT_CTX *m_ctx), - BN_MONT_CTX *m_ctx) -{ - int retry_counter = 32; - BN_BLINDING *ret = NULL; - - if (b == NULL) - ret = BN_BLINDING_new(NULL, NULL, m); - else - ret = b; - - if (ret == NULL) - goto err; - - if (ret->A == NULL && (ret->A = BN_new()) == NULL) - goto err; - if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) - goto err; - - if (e != NULL) { - if (ret->e != NULL) - BN_free(ret->e); - ret->e = BN_dup(e); - } - if (ret->e == NULL) - goto err; - - if (bn_mod_exp != NULL) - ret->bn_mod_exp = bn_mod_exp; - if (m_ctx != NULL) - ret->m_ctx = m_ctx; - - do { - if (!BN_rand_range(ret->A, ret->mod)) - goto err; - if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) { - /* - * this should almost never happen for good RSA keys - */ - unsigned long error = ERR_peek_last_error(); - if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) { - if (retry_counter-- == 0) { - BNerr(BN_F_BN_BLINDING_CREATE_PARAM, - BN_R_TOO_MANY_ITERATIONS); - goto err; - } - ERR_clear_error(); - } else - goto err; - } else - break; - } while (1); - - if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { - if (!ret->bn_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) - goto err; - } else { - if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) - goto err; - } - - if (ret->m_ctx != NULL) { - if (!bn_to_mont_fixed_top(ret->Ai, ret->Ai, ret->m_ctx, ctx) - || !bn_to_mont_fixed_top(ret->A, ret->A, ret->m_ctx, ctx)) - goto err; - } - - return ret; - err: - if (b == NULL && ret != NULL) { - BN_BLINDING_free(ret); - ret = NULL; - } - - return ret; -} -/* crypto/bn/knownprimes.c */ -/* Insert boilerplate */ - -#include "bn.h" - -/*- - * "First Oakley Default Group" from RFC2409, section 6.1. - * - * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } - * - * RFC2409 specifies a generator of 2. - * RFC2412 specifies a generator of of 22. - */ - -BIGNUM *get_rfc2409_prime_768(BIGNUM *bn) -{ - static const unsigned char RFC2409_PRIME_768[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn); -} - -/*- - * "Second Oakley Default Group" from RFC2409, section 6.2. - * - * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. - * - * RFC2409 specifies a generator of 2. - * RFC2412 specifies a generator of 22. - */ - -BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn) -{ - static const unsigned char RFC2409_PRIME_1024[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn); -} - -/*- - * "1536-bit MODP Group" from RFC3526, Section 2. - * - * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } - * - * RFC3526 specifies a generator of 2. - * RFC2312 specifies a generator of 22. - */ - -BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn) -{ - static const unsigned char RFC3526_PRIME_1536[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn); -} - -/*- - * "2048-bit MODP Group" from RFC3526, Section 3. - * - * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } - * - * RFC3526 specifies a generator of 2. - */ - -BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn) -{ - static const unsigned char RFC3526_PRIME_2048[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn); -} - -/*- - * "3072-bit MODP Group" from RFC3526, Section 4. - * - * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } - * - * RFC3526 specifies a generator of 2. - */ - -BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn) -{ - static const unsigned char RFC3526_PRIME_3072[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn); -} - -/*- - * "4096-bit MODP Group" from RFC3526, Section 5. - * - * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } - * - * RFC3526 specifies a generator of 2. - */ - -BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn) -{ - static const unsigned char RFC3526_PRIME_4096[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, - 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, - 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, - 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, - 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, - 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, - 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, - 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, - 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, - 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, - 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, - 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, - 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, - 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, - 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, - 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, - 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn); -} - -/*- - * "6144-bit MODP Group" from RFC3526, Section 6. - * - * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } - * - * RFC3526 specifies a generator of 2. - */ - -BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn) -{ - static const unsigned char RFC3526_PRIME_6144[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, - 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, - 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, - 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, - 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, - 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, - 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, - 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, - 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, - 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, - 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, - 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, - 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, - 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, - 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, - 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, - 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, - 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, - 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, - 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, - 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, - 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, - 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, - 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, - 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, - 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, - 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, - 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, - 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, - 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, - 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, - 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, - 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, - 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, - 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, - 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, - 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, - 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, - 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, - 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, - 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, - 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, - 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, - 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, - 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, - 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, - 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, - 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, - 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn); -} - -/*- - * "8192-bit MODP Group" from RFC3526, Section 7. - * - * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } - * - * RFC3526 specifies a generator of 2. - */ - -BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn) -{ - static const unsigned char RFC3526_PRIME_8192[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, - 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, - 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, - 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, - 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, - 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, - 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, - 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, - 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, - 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, - 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, - 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, - 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, - 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, - 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, - 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, - 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, - 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, - 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, - 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, - 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, - 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, - 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, - 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, - 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, - 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, - 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, - 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, - 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, - 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, - 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, - 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, - 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, - 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, - 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, - 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, - 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, - 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, - 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, - 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, - 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, - 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, - 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, - 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, - 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, - 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, - 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, - 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, - 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, - 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, - 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, - 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, - 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, - 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, - 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, - 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, - 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, - 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, - 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, - 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, - 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, - 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, - 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, - 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, - 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, - 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, - 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, - 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, - 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, - 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, - 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, - 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, - 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, - 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, - 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, - 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, - 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, - 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, - 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, - 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, - 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, - 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, - 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, - 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, - 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, - 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, - 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, - 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, - 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, - 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, - 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, - 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, - 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, - 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59, - 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4, - 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, - 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA, - 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, - 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, - 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66, - 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68, - 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, - 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D, - 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, - 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, - 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7, - 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B, - 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, - 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8, - 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, - 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, - 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D, - 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36, - 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, - 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D, - 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, - 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, - 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68, - 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92, - 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, - 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B, - 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, - 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, - 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF, - 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71, - 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - }; - return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn); -} -/* crypto/bn/bn_ctx.c */ -/* Written by Ulf Moeller for the OpenSSL project. */ -/* ==================================================================== - * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG) -# ifndef NDEBUG -# define NDEBUG -# endif -#endif - -#include -#include - -// #include "cryptlib.h" -// #include "bn_lcl.h" - -/*- - * TODO list - * - * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and - * check they can be safely removed. - * - Check +1 and other ugliness in BN_from_montgomery() - * - * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an - * appropriate 'block' size that will be honoured by bn_expand_internal() to - * prevent piddly little reallocations. OTOH, profiling bignum expansions in - * BN_CTX doesn't show this to be a big issue. - */ - -/* How many bignums are in each "pool item"; */ -#define BN_CTX_POOL_SIZE 16 -/* The stack frame info is resizing, set a first-time expansion size; */ -#define BN_CTX_START_FRAMES 32 - -/***********/ -/* BN_POOL */ -/***********/ - -/* A bundle of bignums that can be linked with other bundles */ -typedef struct bignum_pool_item { - /* The bignum values */ - BIGNUM vals[BN_CTX_POOL_SIZE]; - /* Linked-list admin */ - struct bignum_pool_item *prev, *next; -} BN_POOL_ITEM; -/* A linked-list of bignums grouped in bundles */ -typedef struct bignum_pool { - /* Linked-list admin */ - BN_POOL_ITEM *head, *current, *tail; - /* Stack depth and allocation size */ - unsigned used, size; -} BN_POOL; -static void BN_POOL_init(BN_POOL *); -static void BN_POOL_finish(BN_POOL *); -#ifndef OPENSSL_NO_DEPRECATED -static void BN_POOL_reset(BN_POOL *); -#endif -static BIGNUM *BN_POOL_get(BN_POOL *); -static void BN_POOL_release(BN_POOL *, unsigned int); - -/************/ -/* BN_STACK */ -/************/ - -/* A wrapper to manage the "stack frames" */ -typedef struct bignum_ctx_stack { - /* Array of indexes into the bignum stack */ - unsigned int *indexes; - /* Number of stack frames, and the size of the allocated array */ - unsigned int depth, size; -} BN_STACK; -static void BN_STACK_init(BN_STACK *); -static void BN_STACK_finish(BN_STACK *); -#ifndef OPENSSL_NO_DEPRECATED -static void BN_STACK_reset(BN_STACK *); -#endif -static int BN_STACK_push(BN_STACK *, unsigned int); -static unsigned int BN_STACK_pop(BN_STACK *); - -/**********/ -/* BN_CTX */ -/**********/ - -/* The opaque BN_CTX type */ -struct bignum_ctx { - /* The bignum bundles */ - BN_POOL pool; - /* The "stack frames", if you will */ - BN_STACK stack; - /* The number of bignums currently assigned */ - unsigned int used; - /* Depth of stack overflow */ - int err_stack; - /* Block "gets" until an "end" (compatibility behaviour) */ - int too_many; -}; - -/* Enable this to find BN_CTX bugs */ -#ifdef BN_CTX_DEBUG -static const char *ctxdbg_cur = NULL; -static void ctxdbg(BN_CTX *ctx) -{ - unsigned int bnidx = 0, fpidx = 0; - BN_POOL_ITEM *item = ctx->pool.head; - BN_STACK *stack = &ctx->stack; - fprintf(stderr, "(%16p): ", ctx); - while (bnidx < ctx->used) { - fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); - if (!(bnidx % BN_CTX_POOL_SIZE)) - item = item->next; - } - fprintf(stderr, "\n"); - bnidx = 0; - fprintf(stderr, " : "); - while (fpidx < stack->depth) { - while (bnidx++ < stack->indexes[fpidx]) - fprintf(stderr, " "); - fprintf(stderr, "^^^ "); - bnidx++; - fpidx++; - } - fprintf(stderr, "\n"); -} - -# define CTXDBG_ENTRY(str, ctx) do { \ - ctxdbg_cur = (str); \ - fprintf(stderr,"Starting %s\n", ctxdbg_cur); \ - ctxdbg(ctx); \ - } while(0) -# define CTXDBG_EXIT(ctx) do { \ - fprintf(stderr,"Ending %s\n", ctxdbg_cur); \ - ctxdbg(ctx); \ - } while(0) -# define CTXDBG_RET(ctx,ret) -#else -# define CTXDBG_ENTRY(str, ctx) -# define CTXDBG_EXIT(ctx) -# define CTXDBG_RET(ctx,ret) -#endif - -/* - * This function is an evil legacy and should not be used. This - * implementation is WYSIWYG, though I've done my best. - */ -#ifndef OPENSSL_NO_DEPRECATED -void BN_CTX_init(BN_CTX *ctx) -{ - /* - * Assume the caller obtained the context via BN_CTX_new() and so is - * trying to reset it for use. Nothing else makes sense, least of all - * binary compatibility from a time when they could declare a static - * variable. - */ - BN_POOL_reset(&ctx->pool); - BN_STACK_reset(&ctx->stack); - ctx->used = 0; - ctx->err_stack = 0; - ctx->too_many = 0; -} -#endif - -BN_CTX *BN_CTX_new(void) -{ - BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX)); - if (!ret) { - BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - /* Initialise the structure */ - BN_POOL_init(&ret->pool); - BN_STACK_init(&ret->stack); - ret->used = 0; - ret->err_stack = 0; - ret->too_many = 0; - return ret; -} - -void BN_CTX_free(BN_CTX *ctx) -{ - if (ctx == NULL) - return; -#ifdef BN_CTX_DEBUG - { - BN_POOL_ITEM *pool = ctx->pool.head; - fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n", - ctx->stack.size, ctx->pool.size); - fprintf(stderr, "dmaxs: "); - while (pool) { - unsigned loop = 0; - while (loop < BN_CTX_POOL_SIZE) - fprintf(stderr, "%02x ", pool->vals[loop++].dmax); - pool = pool->next; - } - fprintf(stderr, "\n"); - } -#endif - BN_STACK_finish(&ctx->stack); - BN_POOL_finish(&ctx->pool); - OPENSSL_free(ctx); -} - -void BN_CTX_start(BN_CTX *ctx) -{ - CTXDBG_ENTRY("BN_CTX_start", ctx); - /* If we're already overflowing ... */ - if (ctx->err_stack || ctx->too_many) - ctx->err_stack++; - /* (Try to) get a new frame pointer */ - else if (!BN_STACK_push(&ctx->stack, ctx->used)) { - BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES); - ctx->err_stack++; - } - CTXDBG_EXIT(ctx); -} - -void BN_CTX_end(BN_CTX *ctx) -{ - CTXDBG_ENTRY("BN_CTX_end", ctx); - if (ctx->err_stack) - ctx->err_stack--; - else { - unsigned int fp = BN_STACK_pop(&ctx->stack); - /* Does this stack frame have anything to release? */ - if (fp < ctx->used) - BN_POOL_release(&ctx->pool, ctx->used - fp); - ctx->used = fp; - /* Unjam "too_many" in case "get" had failed */ - ctx->too_many = 0; - } - CTXDBG_EXIT(ctx); -} - -BIGNUM *BN_CTX_get(BN_CTX *ctx) -{ - BIGNUM *ret; - CTXDBG_ENTRY("BN_CTX_get", ctx); - if (ctx->err_stack || ctx->too_many) - return NULL; - if ((ret = BN_POOL_get(&ctx->pool)) == NULL) { - /* - * Setting too_many prevents repeated "get" attempts from cluttering - * the error stack. - */ - ctx->too_many = 1; - BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES); - return NULL; - } - /* OK, make sure the returned bignum is "zero" */ - BN_zero(ret); - ctx->used++; - CTXDBG_RET(ctx, ret); - return ret; -} - -/************/ -/* BN_STACK */ -/************/ - -static void BN_STACK_init(BN_STACK *st) -{ - st->indexes = NULL; - st->depth = st->size = 0; -} - -static void BN_STACK_finish(BN_STACK *st) -{ - if (st->size) - OPENSSL_free(st->indexes); -} - -#ifndef OPENSSL_NO_DEPRECATED -static void BN_STACK_reset(BN_STACK *st) -{ - st->depth = 0; -} -#endif - -static int BN_STACK_push(BN_STACK *st, unsigned int idx) -{ - if (st->depth == st->size) - /* Need to expand */ - { - unsigned int newsize = (st->size ? - (st->size * 3 / 2) : BN_CTX_START_FRAMES); - unsigned int *newitems = OPENSSL_malloc(newsize * - sizeof(unsigned int)); - if (!newitems) - return 0; - if (st->depth) - memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int)); - if (st->size) - OPENSSL_free(st->indexes); - st->indexes = newitems; - st->size = newsize; - } - st->indexes[(st->depth)++] = idx; - return 1; -} - -static unsigned int BN_STACK_pop(BN_STACK *st) -{ - return st->indexes[--(st->depth)]; -} - -/***********/ -/* BN_POOL */ -/***********/ - -static void BN_POOL_init(BN_POOL *p) -{ - p->head = p->current = p->tail = NULL; - p->used = p->size = 0; -} - -static void BN_POOL_finish(BN_POOL *p) -{ - while (p->head) { - unsigned int loop = 0; - BIGNUM *bn = p->head->vals; - while (loop++ < BN_CTX_POOL_SIZE) { - if (bn->d) - BN_clear_free(bn); - bn++; - } - p->current = p->head->next; - OPENSSL_free(p->head); - p->head = p->current; - } -} - -#ifndef OPENSSL_NO_DEPRECATED -static void BN_POOL_reset(BN_POOL *p) -{ - BN_POOL_ITEM *item = p->head; - while (item) { - unsigned int loop = 0; - BIGNUM *bn = item->vals; - while (loop++ < BN_CTX_POOL_SIZE) { - if (bn->d) - BN_clear(bn); - bn++; - } - item = item->next; - } - p->current = p->head; - p->used = 0; -} -#endif - -static BIGNUM *BN_POOL_get(BN_POOL *p) -{ - if (p->used == p->size) { - BIGNUM *bn; - unsigned int loop = 0; - BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM)); - if (!item) - return NULL; - /* Initialise the structure */ - bn = item->vals; - while (loop++ < BN_CTX_POOL_SIZE) - BN_init(bn++); - item->prev = p->tail; - item->next = NULL; - /* Link it in */ - if (!p->head) - p->head = p->current = p->tail = item; - else { - p->tail->next = item; - p->tail = item; - p->current = item; - } - p->size += BN_CTX_POOL_SIZE; - p->used++; - /* Return the first bignum from the new pool */ - return item->vals; - } - if (!p->used) - p->current = p->head; - else if ((p->used % BN_CTX_POOL_SIZE) == 0) - p->current = p->current->next; - return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE); -} - -static void BN_POOL_release(BN_POOL *p, unsigned int num) -{ - unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE; - p->used -= num; - while (num--) { - bn_check_top(p->current->vals + offset); - if (!offset) { - offset = BN_CTX_POOL_SIZE - 1; - p->current = p->current->prev; - } else - offset--; - } -} -/* crypto/bn/bn_depr.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * Support for deprecated functions goes here - static linkage will only - * slurp this code if applications are using them directly. - */ - -#include -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" -#include "rand.h" - -static void *dummy = &dummy; - -#ifndef OPENSSL_NO_DEPRECATED -BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, - const BIGNUM *add, const BIGNUM *rem, - void (*callback) (int, int, void *), void *cb_arg) -{ - BN_GENCB cb; - BIGNUM *rnd = NULL; - int found = 0; - - BN_GENCB_set_old(&cb, callback, cb_arg); - - if (ret == NULL) { - if ((rnd = BN_new()) == NULL) - goto err; - } else - rnd = ret; - if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb)) - goto err; - - /* we have a prime :-) */ - found = 1; - err: - if (!found && (ret == NULL) && (rnd != NULL)) - BN_free(rnd); - return (found ? rnd : NULL); -} - -int BN_is_prime(const BIGNUM *a, int checks, - void (*callback) (int, int, void *), BN_CTX *ctx_passed, - void *cb_arg) -{ - BN_GENCB cb; - BN_GENCB_set_old(&cb, callback, cb_arg); - return BN_is_prime_ex(a, checks, ctx_passed, &cb); -} - -int BN_is_prime_fasttest(const BIGNUM *a, int checks, - void (*callback) (int, int, void *), - BN_CTX *ctx_passed, void *cb_arg, - int do_trial_division) -{ - BN_GENCB cb; - BN_GENCB_set_old(&cb, callback, cb_arg); - return BN_is_prime_fasttest_ex(a, checks, ctx_passed, - do_trial_division, &cb); -} -#endif -/* crypto/bn/bn_div.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "bn.h" -// #include "cryptlib.h" -// #include "bn_lcl.h" - -/* The old slow way */ -#if 0 -int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, - BN_CTX *ctx) -{ - int i, nm, nd; - int ret = 0; - BIGNUM *D; - - bn_check_top(m); - bn_check_top(d); - if (BN_is_zero(d)) { - BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); - return (0); - } - - if (BN_ucmp(m, d) < 0) { - if (rem != NULL) { - if (BN_copy(rem, m) == NULL) - return (0); - } - if (dv != NULL) - BN_zero(dv); - return (1); - } - - BN_CTX_start(ctx); - D = BN_CTX_get(ctx); - if (dv == NULL) - dv = BN_CTX_get(ctx); - if (rem == NULL) - rem = BN_CTX_get(ctx); - if (D == NULL || dv == NULL || rem == NULL) - goto end; - - nd = BN_num_bits(d); - nm = BN_num_bits(m); - if (BN_copy(D, d) == NULL) - goto end; - if (BN_copy(rem, m) == NULL) - goto end; - - /* - * The next 2 are needed so we can do a dv->d[0]|=1 later since - * BN_lshift1 will only work once there is a value :-) - */ - BN_zero(dv); - if (bn_wexpand(dv, 1) == NULL) - goto end; - dv->top = 1; - - if (!BN_lshift(D, D, nm - nd)) - goto end; - for (i = nm - nd; i >= 0; i--) { - if (!BN_lshift1(dv, dv)) - goto end; - if (BN_ucmp(rem, D) >= 0) { - dv->d[0] |= 1; - if (!BN_usub(rem, rem, D)) - goto end; - } -/* CAN IMPROVE (and have now :=) */ - if (!BN_rshift1(D, D)) - goto end; - } - rem->neg = BN_is_zero(rem) ? 0 : m->neg; - dv->neg = m->neg ^ d->neg; - ret = 1; - end: - BN_CTX_end(ctx); - return (ret); -} - -#else - -# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \ - && !defined(PEDANTIC) && !defined(BN_DIV3W) -# if defined(__GNUC__) && __GNUC__>=2 -# if defined(__i386) || defined (__i386__) - /*- - * There were two reasons for implementing this template: - * - GNU C generates a call to a function (__udivdi3 to be exact) - * in reply to ((((BN_ULLONG)n0)< - */ -# undef bn_div_words -# define bn_div_words(n0,n1,d0) \ - ({ asm volatile ( \ - "divl %4" \ - : "=a"(q), "=d"(rem) \ - : "a"(n1), "d"(n0), "r"(d0) \ - : "cc"); \ - q; \ - }) -# define REMAINDER_IS_ALREADY_CALCULATED -# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG) - /* - * Same story here, but it's 128-bit by 64-bit division. Wow! - * - */ -# undef bn_div_words -# define bn_div_words(n0,n1,d0) \ - ({ asm volatile ( \ - "divq %4" \ - : "=a"(q), "=d"(rem) \ - : "a"(n1), "d"(n0), "r"(d0) \ - : "cc"); \ - q; \ - }) -# define REMAINDER_IS_ALREADY_CALCULATED -# endif /* __ */ -# endif /* __GNUC__ */ -# endif /* OPENSSL_NO_ASM */ - -/*- - * BN_div computes dv := num / divisor, rounding towards - * zero, and sets up rm such that dv*divisor + rm = num holds. - * Thus: - * dv->neg == num->neg ^ divisor->neg (unless the result is zero) - * rm->neg == num->neg (unless the remainder is zero) - * If 'dv' or 'rm' is NULL, the respective value is not returned. - */ -int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, - BN_CTX *ctx) -{ - int norm_shift, i, loop; - BIGNUM *tmp, wnum, *snum, *sdiv, *res; - BN_ULONG *resp, *wnump; - BN_ULONG d0, d1; - int num_n, div_n; - int no_branch = 0; - - /* - * Invalid zero-padding would have particularly bad consequences so don't - * just rely on bn_check_top() here (bn_check_top() works only for - * BN_DEBUG builds) - */ - if ((num->top > 0 && num->d[num->top - 1] == 0) || - (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) { - BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED); - return 0; - } - - bn_check_top(num); - bn_check_top(divisor); - - if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) - || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) { - no_branch = 1; - } - - bn_check_top(dv); - bn_check_top(rm); - /*- bn_check_top(num); *//* - * 'num' has been checked already - */ - /*- bn_check_top(divisor); *//* - * 'divisor' has been checked already - */ - - if (BN_is_zero(divisor)) { - BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); - return (0); - } - - if (!no_branch && BN_ucmp(num, divisor) < 0) { - if (rm != NULL) { - if (BN_copy(rm, num) == NULL) - return (0); - } - if (dv != NULL) - BN_zero(dv); - return (1); - } - - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - snum = BN_CTX_get(ctx); - sdiv = BN_CTX_get(ctx); - if (dv == NULL) - res = BN_CTX_get(ctx); - else - res = dv; - if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL) - goto err; - - /* First we normalise the numbers */ - norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2); - if (!(BN_lshift(sdiv, divisor, norm_shift))) - goto err; - sdiv->neg = 0; - norm_shift += BN_BITS2; - if (!(BN_lshift(snum, num, norm_shift))) - goto err; - snum->neg = 0; - - if (no_branch) { - /* - * Since we don't know whether snum is larger than sdiv, we pad snum - * with enough zeroes without changing its value. - */ - if (snum->top <= sdiv->top + 1) { - if (bn_wexpand(snum, sdiv->top + 2) == NULL) - goto err; - for (i = snum->top; i < sdiv->top + 2; i++) - snum->d[i] = 0; - snum->top = sdiv->top + 2; - } else { - if (bn_wexpand(snum, snum->top + 1) == NULL) - goto err; - snum->d[snum->top] = 0; - snum->top++; - } - } - - div_n = sdiv->top; - num_n = snum->top; - loop = num_n - div_n; - /* - * Lets setup a 'window' into snum This is the part that corresponds to - * the current 'area' being divided - */ - wnum.neg = 0; - wnum.d = &(snum->d[loop]); - wnum.top = div_n; - wnum.flags = BN_FLG_STATIC_DATA; - /* - * only needed when BN_ucmp messes up the values between top and max - */ - wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */ - - /* Get the top 2 words of sdiv */ - /* div_n=sdiv->top; */ - d0 = sdiv->d[div_n - 1]; - d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2]; - - /* pointer to the 'top' of snum */ - wnump = &(snum->d[num_n - 1]); - - /* Setup to 'res' */ - res->neg = (num->neg ^ divisor->neg); - if (!bn_wexpand(res, (loop + 1))) - goto err; - res->top = loop - no_branch; - resp = &(res->d[loop - 1]); - - /* space for temp */ - if (!bn_wexpand(tmp, (div_n + 1))) - goto err; - - if (!no_branch) { - if (BN_ucmp(&wnum, sdiv) >= 0) { - /* - * If BN_DEBUG_RAND is defined BN_ucmp changes (via bn_pollute) - * the const bignum arguments => clean the values between top and - * max again - */ - bn_clear_top2max(&wnum); - bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n); - *resp = 1; - } else - res->top--; - } - - /* - * if res->top == 0 then clear the neg value otherwise decrease the resp - * pointer - */ - if (res->top == 0) - res->neg = 0; - else - resp--; - - for (i = 0; i < loop - 1; i++, wnump--, resp--) { - BN_ULONG q, l0; - /* - * the first part of the loop uses the top two words of snum and sdiv - * to calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv - */ -# if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM) - BN_ULONG bn_div_3_words(BN_ULONG *, BN_ULONG, BN_ULONG); - q = bn_div_3_words(wnump, d1, d0); -# else - BN_ULONG n0, n1, rem = 0; - - n0 = wnump[0]; - n1 = wnump[-1]; - if (n0 == d0) - q = BN_MASK2; - else { /* n0 < d0 */ - -# ifdef BN_LLONG - BN_ULLONG t2; - -# if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words) - q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0); -# else - q = bn_div_words(n0, n1, d0); -# ifdef BN_DEBUG_LEVITTE - fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ -X) -> 0x%08X\n", n0, n1, d0, q); -# endif -# endif - -# ifndef REMAINDER_IS_ALREADY_CALCULATED - /* - * rem doesn't have to be BN_ULLONG. The least we - * know it's less that d0, isn't it? - */ - rem = (n1 - q * d0) & BN_MASK2; -# endif - t2 = (BN_ULLONG) d1 *q; - - for (;;) { - if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | wnump[-2])) - break; - q--; - rem += d0; - if (rem < d0) - break; /* don't let rem overflow */ - t2 -= d1; - } -# else /* !BN_LLONG */ - BN_ULONG t2l, t2h; - - q = bn_div_words(n0, n1, d0); -# ifdef BN_DEBUG_LEVITTE - fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ -X) -> 0x%08X\n", n0, n1, d0, q); -# endif -# ifndef REMAINDER_IS_ALREADY_CALCULATED - rem = (n1 - q * d0) & BN_MASK2; -# endif - -# if defined(BN_UMULT_LOHI) - BN_UMULT_LOHI(t2l, t2h, d1, q); -# elif defined(BN_UMULT_HIGH) - t2l = d1 * q; - t2h = BN_UMULT_HIGH(d1, q); -# else - { - BN_ULONG ql, qh; - t2l = LBITS(d1); - t2h = HBITS(d1); - ql = LBITS(q); - qh = HBITS(q); - mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */ - } -# endif - - for (;;) { - if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) - break; - q--; - rem += d0; - if (rem < d0) - break; /* don't let rem overflow */ - if (t2l < d1) - t2h--; - t2l -= d1; - } -# endif /* !BN_LLONG */ - } -# endif /* !BN_DIV3W */ - - l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q); - tmp->d[div_n] = l0; - wnum.d--; - /* - * ingore top values of the bignums just sub the two BN_ULONG arrays - * with bn_sub_words - */ - if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) { - /* - * Note: As we have considered only the leading two BN_ULONGs in - * the calculation of q, sdiv * q might be greater than wnum (but - * then (q-1) * sdiv is less or equal than wnum) - */ - q--; - if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n)) - /* - * we can't have an overflow here (assuming that q != 0, but - * if q == 0 then tmp is zero anyway) - */ - (*wnump)++; - } - /* store part of the result */ - *resp = q; - } - bn_correct_top(snum); - if (rm != NULL) { - /* - * Keep a copy of the neg flag in num because if rm==num BN_rshift() - * will overwrite it. - */ - int neg = num->neg; - BN_rshift(rm, snum, norm_shift); - if (!BN_is_zero(rm)) - rm->neg = neg; - bn_check_top(rm); - } - if (no_branch) - bn_correct_top(res); - BN_CTX_end(ctx); - return (1); - err: - bn_check_top(rm); - BN_CTX_end(ctx); - return (0); -} -#endif -/* crypto/bn/bn_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "bn.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason) - -static ERR_STRING_DATA BN_str_functs[] = { - {ERR_FUNC(BN_F_BNRAND), "BNRAND"}, - {ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX), "BN_BLINDING_convert_ex"}, - {ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM), "BN_BLINDING_create_param"}, - {ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX), "BN_BLINDING_invert_ex"}, - {ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"}, - {ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"}, - {ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"}, - {ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"}, - {ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"}, - {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"}, - {ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"}, - {ERR_FUNC(BN_F_BN_DIV), "BN_div"}, - {ERR_FUNC(BN_F_BN_DIV_NO_BRANCH), "BN_div_no_branch"}, - {ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"}, - {ERR_FUNC(BN_F_BN_EXP), "BN_exp"}, - {ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"}, - {ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"}, - {ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"}, - {ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"}, - {ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"}, - {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD), "BN_GF2m_mod_solve_quad"}, - {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"}, - {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"}, - {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"}, - {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"}, - {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"}, - {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"}, - {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"}, - {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD), "BN_mod_exp_mont_word"}, - {ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"}, - {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"}, - {ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"}, - {ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"}, - {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"}, - {ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"}, - {ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"}, - {ERR_FUNC(BN_F_BN_MPI2BN), "BN_mpi2bn"}, - {ERR_FUNC(BN_F_BN_NEW), "BN_new"}, - {ERR_FUNC(BN_F_BN_RAND), "BN_rand"}, - {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"}, - {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"}, - {ERR_FUNC(BN_F_BN_USUB), "BN_usub"}, - {0, NULL} -}; - -static ERR_STRING_DATA BN_str_reasons[] = { - {ERR_REASON(BN_R_ARG2_LT_ARG3), "arg2 lt arg3"}, - {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"}, - {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"}, - {ERR_REASON(BN_R_BITS_TOO_SMALL), "bits too small"}, - {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"}, - {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"}, - {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"}, - {ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA), - "expand on static bignum data"}, - {ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"}, - {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"}, - {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"}, - {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"}, - {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"}, - {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"}, - {ERR_REASON(BN_R_NO_INVERSE), "no inverse"}, - {ERR_REASON(BN_R_NO_SOLUTION), "no solution"}, - {ERR_REASON(BN_R_P_IS_NOT_PRIME), "p is not prime"}, - {ERR_REASON(BN_R_TOO_MANY_ITERATIONS), "too many iterations"}, - {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES), - "too many temporary variables"}, - {0, NULL} -}; - -#endif - -void ERR_load_BN_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(BN_str_functs[0].error) == NULL) { - ERR_load_strings(0, BN_str_functs); - ERR_load_strings(0, BN_str_reasons); - } -#endif -} -/* crypto/bn/bn_exp.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -#include "constant_time_locl.h" -// #include "bn_lcl.h" - -#include -#ifdef _WIN32 -# include -# ifndef alloca -# define alloca _alloca -# endif -#elif defined(__GNUC__) -# ifndef alloca -# define alloca(s) __builtin_alloca((s)) -# endif -#elif defined(__sun) -# include -#endif - -#include "rsaz_exp.h" - -#undef SPARC_T4_MONT -#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc)) -# include "sparc_arch.h" -extern unsigned int OPENSSL_sparcv9cap_P[]; -# define SPARC_T4_MONT -#endif - -/* maximum precomputation table size for *variable* sliding windows */ -#define TABLE_SIZE 32 - -/* this one works - simple but works */ -int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) -{ - int i, bits, ret = 0; - BIGNUM *v, *rr; - - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 - || BN_get_flags(a, BN_FLG_CONSTTIME) != 0) { - /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ - BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - BN_CTX_start(ctx); - if ((r == a) || (r == p)) - rr = BN_CTX_get(ctx); - else - rr = r; - v = BN_CTX_get(ctx); - if (rr == NULL || v == NULL) - goto err; - - if (BN_copy(v, a) == NULL) - goto err; - bits = BN_num_bits(p); - - if (BN_is_odd(p)) { - if (BN_copy(rr, a) == NULL) - goto err; - } else { - if (!BN_one(rr)) - goto err; - } - - for (i = 1; i < bits; i++) { - if (!BN_sqr(v, v, ctx)) - goto err; - if (BN_is_bit_set(p, i)) { - if (!BN_mul(rr, rr, v, ctx)) - goto err; - } - } - if (r != rr && BN_copy(r, rr) == NULL) - goto err; - - ret = 1; - err: - BN_CTX_end(ctx); - bn_check_top(r); - return (ret); -} - -int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, - BN_CTX *ctx) -{ - int ret; - - bn_check_top(a); - bn_check_top(p); - bn_check_top(m); - - /*- - * For even modulus m = 2^k*m_odd, it might make sense to compute - * a^p mod m_odd and a^p mod 2^k separately (with Montgomery - * exponentiation for the odd part), using appropriate exponent - * reductions, and combine the results using the CRT. - * - * For now, we use Montgomery only if the modulus is odd; otherwise, - * exponentiation using the reciprocal-based quick remaindering - * algorithm is used. - * - * (Timing obtained with expspeed.c [computations a^p mod m - * where a, p, m are of the same length: 256, 512, 1024, 2048, - * 4096, 8192 bits], compared to the running time of the - * standard algorithm: - * - * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration] - * 55 .. 77 % [UltraSparc processor, but - * debug-solaris-sparcv8-gcc conf.] - * - * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration] - * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc] - * - * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont - * at 2048 and more bits, but at 512 and 1024 bits, it was - * slower even than the standard algorithm! - * - * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations] - * should be obtained when the new Montgomery reduction code - * has been integrated into OpenSSL.) - */ - -#define MONT_MUL_MOD -#define MONT_EXP_WORD -#define RECP_MUL_MOD - -#ifdef MONT_MUL_MOD - /* - * I have finally been able to take out this pre-condition of the top bit - * being set. It was caused by an error in BN_div with negatives. There - * was also another problem when for a^b%m a >= m. eay 07-May-97 - */ - /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */ - - if (BN_is_odd(m)) { -# ifdef MONT_EXP_WORD - if (a->top == 1 && !a->neg - && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0) - && (BN_get_flags(a, BN_FLG_CONSTTIME) == 0) - && (BN_get_flags(m, BN_FLG_CONSTTIME) == 0)) { - BN_ULONG A = a->d[0]; - ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL); - } else -# endif - ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL); - } else -#endif -#ifdef RECP_MUL_MOD - { - ret = BN_mod_exp_recp(r, a, p, m, ctx); - } -#else - { - ret = BN_mod_exp_simple(r, a, p, m, ctx); - } -#endif - - bn_check_top(r); - return (ret); -} - -int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - int i, j, bits, ret = 0, wstart, wend, window, wvalue; - int start = 1; - BIGNUM *aa; - /* Table of variables obtained from 'ctx' */ - BIGNUM *val[TABLE_SIZE]; - BN_RECP_CTX recp; - - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 - || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 - || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { - /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ - BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - bits = BN_num_bits(p); - if (bits == 0) { - /* x**0 mod 1, or x**0 mod -1 is still zero. */ - if (BN_abs_is_word(m, 1)) { - ret = 1; - BN_zero(r); - } else { - ret = BN_one(r); - } - return ret; - } - - BN_CTX_start(ctx); - aa = BN_CTX_get(ctx); - val[0] = BN_CTX_get(ctx); - if (!aa || !val[0]) - goto err; - - BN_RECP_CTX_init(&recp); - if (m->neg) { - /* ignore sign of 'm' */ - if (!BN_copy(aa, m)) - goto err; - aa->neg = 0; - if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0) - goto err; - } else { - if (BN_RECP_CTX_set(&recp, m, ctx) <= 0) - goto err; - } - - if (!BN_nnmod(val[0], a, m, ctx)) - goto err; /* 1 */ - if (BN_is_zero(val[0])) { - BN_zero(r); - ret = 1; - goto err; - } - - window = BN_window_bits_for_exponent_size(bits); - if (window > 1) { - if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx)) - goto err; /* 2 */ - j = 1 << (window - 1); - for (i = 1; i < j; i++) { - if (((val[i] = BN_CTX_get(ctx)) == NULL) || - !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx)) - goto err; - } - } - - start = 1; /* This is used to avoid multiplication etc - * when there is only the value '1' in the - * buffer. */ - wvalue = 0; /* The 'value' of the window */ - wstart = bits - 1; /* The top bit of the window */ - wend = 0; /* The bottom bit of the window */ - - if (!BN_one(r)) - goto err; - - for (;;) { - if (BN_is_bit_set(p, wstart) == 0) { - if (!start) - if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) - goto err; - if (wstart == 0) - break; - wstart--; - continue; - } - /* - * We now have wstart on a 'set' bit, we now need to work out how bit - * a window to do. To do this we need to scan forward until the last - * set bit before the end of the window - */ - j = wstart; - wvalue = 1; - wend = 0; - for (i = 1; i < window; i++) { - if (wstart - i < 0) - break; - if (BN_is_bit_set(p, wstart - i)) { - wvalue <<= (i - wend); - wvalue |= 1; - wend = i; - } - } - - /* wend is the size of the current window */ - j = wend + 1; - /* add the 'bytes above' */ - if (!start) - for (i = 0; i < j; i++) { - if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) - goto err; - } - - /* wvalue will be an odd number < 2^window */ - if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx)) - goto err; - - /* move the 'window' down further */ - wstart -= wend + 1; - wvalue = 0; - start = 0; - if (wstart < 0) - break; - } - ret = 1; - err: - BN_CTX_end(ctx); - BN_RECP_CTX_free(&recp); - bn_check_top(r); - return (ret); -} - -int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) -{ - int i, j, bits, ret = 0, wstart, wend, window, wvalue; - int start = 1; - BIGNUM *d, *r; - const BIGNUM *aa; - /* Table of variables obtained from 'ctx' */ - BIGNUM *val[TABLE_SIZE]; - BN_MONT_CTX *mont = NULL; - - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 - || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 - || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { - return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); - } - - bn_check_top(a); - bn_check_top(p); - bn_check_top(m); - - if (!BN_is_odd(m)) { - BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); - return (0); - } - bits = BN_num_bits(p); - if (bits == 0) { - /* x**0 mod 1, or x**0 mod -1 is still zero. */ - if (BN_abs_is_word(m, 1)) { - ret = 1; - BN_zero(rr); - } else { - ret = BN_one(rr); - } - return ret; - } - - BN_CTX_start(ctx); - d = BN_CTX_get(ctx); - r = BN_CTX_get(ctx); - val[0] = BN_CTX_get(ctx); - if (!d || !r || !val[0]) - goto err; - - /* - * If this is not done, things will break in the montgomery part - */ - - if (in_mont != NULL) - mont = in_mont; - else { - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - if (!BN_MONT_CTX_set(mont, m, ctx)) - goto err; - } - - if (a->neg || BN_ucmp(a, m) >= 0) { - if (!BN_nnmod(val[0], a, m, ctx)) - goto err; - aa = val[0]; - } else - aa = a; - if (BN_is_zero(aa)) { - BN_zero(rr); - ret = 1; - goto err; - } - if (!bn_to_mont_fixed_top(val[0], aa, mont, ctx)) - goto err; /* 1 */ - - window = BN_window_bits_for_exponent_size(bits); - if (window > 1) { - if (!bn_mul_mont_fixed_top(d, val[0], val[0], mont, ctx)) - goto err; /* 2 */ - j = 1 << (window - 1); - for (i = 1; i < j; i++) { - if (((val[i] = BN_CTX_get(ctx)) == NULL) || - !bn_mul_mont_fixed_top(val[i], val[i - 1], d, mont, ctx)) - goto err; - } - } - - start = 1; /* This is used to avoid multiplication etc - * when there is only the value '1' in the - * buffer. */ - wvalue = 0; /* The 'value' of the window */ - wstart = bits - 1; /* The top bit of the window */ - wend = 0; /* The bottom bit of the window */ - -#if 1 /* by Shay Gueron's suggestion */ - j = m->top; /* borrow j */ - if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) { - if (bn_wexpand(r, j) == NULL) - goto err; - /* 2^(top*BN_BITS2) - m */ - r->d[0] = (0 - m->d[0]) & BN_MASK2; - for (i = 1; i < j; i++) - r->d[i] = (~m->d[i]) & BN_MASK2; - r->top = j; - r->flags |= BN_FLG_FIXED_TOP; - } else -#endif - if (!bn_to_mont_fixed_top(r, BN_value_one(), mont, ctx)) - goto err; - for (;;) { - if (BN_is_bit_set(p, wstart) == 0) { - if (!start) { - if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx)) - goto err; - } - if (wstart == 0) - break; - wstart--; - continue; - } - /* - * We now have wstart on a 'set' bit, we now need to work out how bit - * a window to do. To do this we need to scan forward until the last - * set bit before the end of the window - */ - j = wstart; - wvalue = 1; - wend = 0; - for (i = 1; i < window; i++) { - if (wstart - i < 0) - break; - if (BN_is_bit_set(p, wstart - i)) { - wvalue <<= (i - wend); - wvalue |= 1; - wend = i; - } - } - - /* wend is the size of the current window */ - j = wend + 1; - /* add the 'bytes above' */ - if (!start) - for (i = 0; i < j; i++) { - if (!bn_mul_mont_fixed_top(r, r, r, mont, ctx)) - goto err; - } - - /* wvalue will be an odd number < 2^window */ - if (!bn_mul_mont_fixed_top(r, r, val[wvalue >> 1], mont, ctx)) - goto err; - - /* move the 'window' down further */ - wstart -= wend + 1; - wvalue = 0; - start = 0; - if (wstart < 0) - break; - } - /* - * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery - * removes padding [if any] and makes return value suitable for public - * API consumer. - */ -#if defined(SPARC_T4_MONT) - if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) { - j = mont->N.top; /* borrow j */ - val[0]->d[0] = 1; /* borrow val[0] */ - for (i = 1; i < j; i++) - val[0]->d[i] = 0; - val[0]->top = j; - if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx)) - goto err; - } else -#endif - if (!BN_from_montgomery(rr, r, mont, ctx)) - goto err; - ret = 1; - err: - if ((in_mont == NULL) && (mont != NULL)) - BN_MONT_CTX_free(mont); - BN_CTX_end(ctx); - bn_check_top(rr); - return (ret); -} - -#if defined(SPARC_T4_MONT) -static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos) -{ - BN_ULONG ret = 0; - int wordpos; - - wordpos = bitpos / BN_BITS2; - bitpos %= BN_BITS2; - if (wordpos >= 0 && wordpos < a->top) { - ret = a->d[wordpos] & BN_MASK2; - if (bitpos) { - ret >>= bitpos; - if (++wordpos < a->top) - ret |= a->d[wordpos] << (BN_BITS2 - bitpos); - } - } - - return ret & BN_MASK2; -} -#endif - -/* - * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific - * layout so that accessing any of these table values shows the same access - * pattern as far as cache lines are concerned. The following functions are - * used to transfer a BIGNUM from/to that table. - */ - -static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, - unsigned char *buf, int idx, - int window) -{ - int i, j; - int width = 1 << window; - BN_ULONG *table = (BN_ULONG *)buf; - - if (top > b->top) - top = b->top; /* this works because 'buf' is explicitly - * zeroed */ - for (i = 0, j = idx; i < top; i++, j += width) { - table[j] = b->d[i]; - } - - return 1; -} - -static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, - unsigned char *buf, int idx, - int window) -{ - int i, j; - int width = 1 << window; - volatile BN_ULONG *table = (volatile BN_ULONG *)buf; - - if (bn_wexpand(b, top) == NULL) - return 0; - - if (window <= 3) { - for (i = 0; i < top; i++, table += width) { - BN_ULONG acc = 0; - - for (j = 0; j < width; j++) { - acc |= table[j] & - ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); - } - - b->d[i] = acc; - } - } else { - int xstride = 1 << (window - 2); - BN_ULONG y0, y1, y2, y3; - - i = idx >> (window - 2); /* equivalent of idx / xstride */ - idx &= xstride - 1; /* equivalent of idx % xstride */ - - y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1); - y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1); - y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1); - y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1); - - for (i = 0; i < top; i++, table += width) { - BN_ULONG acc = 0; - - for (j = 0; j < xstride; j++) { - acc |= ( (table[j + 0 * xstride] & y0) | - (table[j + 1 * xstride] & y1) | - (table[j + 2 * xstride] & y2) | - (table[j + 3 * xstride] & y3) ) - & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); - } - - b->d[i] = acc; - } - } - - b->top = top; - b->flags |= BN_FLG_FIXED_TOP; - return 1; -} - -/* - * Given a pointer value, compute the next address that is a cache line - * multiple. - */ -#define MOD_EXP_CTIME_ALIGN(x_) \ - ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK)))) - -/* - * This variant of BN_mod_exp_mont() uses fixed windows and the special - * precomputation memory layout to limit data-dependency to a minimum to - * protect secret exponents (cf. the hyper-threading timing attacks pointed - * out by Colin Percival, - * http://www.daemonology.net/hyperthreading-considered-harmful/) - */ -int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *in_mont) -{ - int i, bits, ret = 0, window, wvalue; - int top; - BN_MONT_CTX *mont = NULL; - - int numPowers; - unsigned char *powerbufFree = NULL; - int powerbufLen = 0; - unsigned char *powerbuf = NULL; - BIGNUM tmp, am; -#if defined(SPARC_T4_MONT) - unsigned int t4 = 0; -#endif - - bn_check_top(a); - bn_check_top(p); - bn_check_top(m); - - if (!BN_is_odd(m)) { - BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS); - return (0); - } - - top = m->top; - - /* - * Use all bits stored in |p|, rather than |BN_num_bits|, so we do not leak - * whether the top bits are zero. - */ - bits = p->top * BN_BITS2; - if (bits == 0) { - /* x**0 mod 1, or x**0 mod -1 is still zero. */ - if (BN_abs_is_word(m, 1)) { - ret = 1; - BN_zero(rr); - } else { - ret = BN_one(rr); - } - return ret; - } - - BN_CTX_start(ctx); - - /* - * Allocate a montgomery context if it was not supplied by the caller. If - * this is not done, things will break in the montgomery part. - */ - if (in_mont != NULL) - mont = in_mont; - else { - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - if (!BN_MONT_CTX_set(mont, m, ctx)) - goto err; - } - -#ifdef RSAZ_ENABLED - /* - * If the size of the operands allow it, perform the optimized - * RSAZ exponentiation. For further information see - * crypto/bn/rsaz_exp.c and accompanying assembly modules. - */ - if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024) - && rsaz_avx2_eligible()) { - if (NULL == bn_wexpand(rr, 16)) - goto err; - RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d, - mont->n0[0]); - rr->top = 16; - rr->neg = 0; - bn_correct_top(rr); - ret = 1; - goto err; - } else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) { - if (NULL == bn_wexpand(rr, 8)) - goto err; - RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d); - rr->top = 8; - rr->neg = 0; - bn_correct_top(rr); - ret = 1; - goto err; - } -#endif - - /* Get the window size to use with size of p. */ - window = BN_window_bits_for_ctime_exponent_size(bits); -#if defined(SPARC_T4_MONT) - if (window >= 5 && (top & 15) == 0 && top <= 64 && - (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) == - (CFR_MONTMUL | CFR_MONTSQR) && (t4 = OPENSSL_sparcv9cap_P[0])) - window = 5; - else -#endif -#if defined(OPENSSL_BN_ASM_MONT5) - if (window >= 5) { - window = 5; /* ~5% improvement for RSA2048 sign, and even - * for RSA4096 */ - /* reserve space for mont->N.d[] copy */ - powerbufLen += top * sizeof(mont->N.d[0]); - } -#endif - (void)0; - - /* - * Allocate a buffer large enough to hold all of the pre-computed powers - * of am, am itself and tmp. - */ - numPowers = 1 << window; - powerbufLen += sizeof(m->d[0]) * (top * numPowers + - ((2 * top) > - numPowers ? (2 * top) : numPowers)); -#ifdef alloca - if (powerbufLen < 3072) - powerbufFree = - alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); - else -#endif - if ((powerbufFree = - (unsigned char *)OPENSSL_malloc(powerbufLen + - MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) - == NULL) - goto err; - - powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree); - memset(powerbuf, 0, powerbufLen); - -#ifdef alloca - if (powerbufLen < 3072) - powerbufFree = NULL; -#endif - - /* lay down tmp and am right after powers table */ - tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers); - am.d = tmp.d + top; - tmp.top = am.top = 0; - tmp.dmax = am.dmax = top; - tmp.neg = am.neg = 0; - tmp.flags = am.flags = BN_FLG_STATIC_DATA; - - /* prepare a^0 in Montgomery domain */ -#if 1 /* by Shay Gueron's suggestion */ - if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) { - /* 2^(top*BN_BITS2) - m */ - tmp.d[0] = (0 - m->d[0]) & BN_MASK2; - for (i = 1; i < top; i++) - tmp.d[i] = (~m->d[i]) & BN_MASK2; - tmp.top = top; - } else -#endif - if (!bn_to_mont_fixed_top(&tmp, BN_value_one(), mont, ctx)) - goto err; - - /* prepare a^1 in Montgomery domain */ - if (a->neg || BN_ucmp(a, m) >= 0) { - if (!BN_mod(&am, a, m, ctx)) - goto err; - if (!bn_to_mont_fixed_top(&am, &am, mont, ctx)) - goto err; - } else if (!bn_to_mont_fixed_top(&am, a, mont, ctx)) - goto err; - -#if defined(SPARC_T4_MONT) - if (t4) { - typedef int (*bn_pwr5_mont_f) (BN_ULONG *tp, const BN_ULONG *np, - const BN_ULONG *n0, const void *table, - int power, int bits); - int bn_pwr5_mont_t4_8(BN_ULONG *tp, const BN_ULONG *np, - const BN_ULONG *n0, const void *table, - int power, int bits); - int bn_pwr5_mont_t4_16(BN_ULONG *tp, const BN_ULONG *np, - const BN_ULONG *n0, const void *table, - int power, int bits); - int bn_pwr5_mont_t4_24(BN_ULONG *tp, const BN_ULONG *np, - const BN_ULONG *n0, const void *table, - int power, int bits); - int bn_pwr5_mont_t4_32(BN_ULONG *tp, const BN_ULONG *np, - const BN_ULONG *n0, const void *table, - int power, int bits); - static const bn_pwr5_mont_f pwr5_funcs[4] = { - bn_pwr5_mont_t4_8, bn_pwr5_mont_t4_16, - bn_pwr5_mont_t4_24, bn_pwr5_mont_t4_32 - }; - bn_pwr5_mont_f pwr5_worker = pwr5_funcs[top / 16 - 1]; - - typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap, - const void *bp, const BN_ULONG *np, - const BN_ULONG *n0); - int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, const void *bp, - const BN_ULONG *np, const BN_ULONG *n0); - int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap, - const void *bp, const BN_ULONG *np, - const BN_ULONG *n0); - int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap, - const void *bp, const BN_ULONG *np, - const BN_ULONG *n0); - int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap, - const void *bp, const BN_ULONG *np, - const BN_ULONG *n0); - static const bn_mul_mont_f mul_funcs[4] = { - bn_mul_mont_t4_8, bn_mul_mont_t4_16, - bn_mul_mont_t4_24, bn_mul_mont_t4_32 - }; - bn_mul_mont_f mul_worker = mul_funcs[top / 16 - 1]; - - void bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap, - const void *bp, const BN_ULONG *np, - const BN_ULONG *n0, int num); - void bn_mul_mont_t4(BN_ULONG *rp, const BN_ULONG *ap, - const void *bp, const BN_ULONG *np, - const BN_ULONG *n0, int num); - void bn_mul_mont_gather5_t4(BN_ULONG *rp, const BN_ULONG *ap, - const void *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); - void bn_flip_n_scatter5_t4(const BN_ULONG *inp, size_t num, - void *table, size_t power); - void bn_gather5_t4(BN_ULONG *out, size_t num, - void *table, size_t power); - void bn_flip_t4(BN_ULONG *dst, BN_ULONG *src, size_t num); - - BN_ULONG *np = mont->N.d, *n0 = mont->n0; - int stride = 5 * (6 - (top / 16 - 1)); /* multiple of 5, but less - * than 32 */ - - /* - * BN_to_montgomery can contaminate words above .top [in - * BN_DEBUG[_DEBUG] build]... - */ - for (i = am.top; i < top; i++) - am.d[i] = 0; - for (i = tmp.top; i < top; i++) - tmp.d[i] = 0; - - bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 0); - bn_flip_n_scatter5_t4(am.d, top, powerbuf, 1); - if (!(*mul_worker) (tmp.d, am.d, am.d, np, n0) && - !(*mul_worker) (tmp.d, am.d, am.d, np, n0)) - bn_mul_mont_vis3(tmp.d, am.d, am.d, np, n0, top); - bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 2); - - for (i = 3; i < 32; i++) { - /* Calculate a^i = a^(i-1) * a */ - if (!(*mul_worker) (tmp.d, tmp.d, am.d, np, n0) && - !(*mul_worker) (tmp.d, tmp.d, am.d, np, n0)) - bn_mul_mont_vis3(tmp.d, tmp.d, am.d, np, n0, top); - bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, i); - } - - /* switch to 64-bit domain */ - np = alloca(top * sizeof(BN_ULONG)); - top /= 2; - bn_flip_t4(np, mont->N.d, top); - - bits--; - for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) - wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); - bn_gather5_t4(tmp.d, top, powerbuf, wvalue); - - /* - * Scan the exponent one window at a time starting from the most - * significant bits. - */ - while (bits >= 0) { - if (bits < stride) - stride = bits + 1; - bits -= stride; - wvalue = bn_get_bits(p, bits + 1); - - if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride)) - continue; - /* retry once and fall back */ - if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride)) - continue; - - bits += stride - 5; - wvalue >>= stride - 5; - wvalue &= 31; - bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont_gather5_t4(tmp.d, tmp.d, powerbuf, np, n0, top, - wvalue); - } - - bn_flip_t4(tmp.d, tmp.d, top); - top *= 2; - /* back to 32-bit domain */ - tmp.top = top; - bn_correct_top(&tmp); - OPENSSL_cleanse(np, top * sizeof(BN_ULONG)); - } else -#endif -#if defined(OPENSSL_BN_ASM_MONT5) - if (window == 5 && top > 1) { - /* - * This optimization uses ideas from http://eprint.iacr.org/2011/239, - * specifically optimization of cache-timing attack countermeasures - * and pre-computation optimization. - */ - - /* - * Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as - * 512-bit RSA is hardly relevant, we omit it to spare size... - */ - void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, - const void *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); - void bn_scatter5(const BN_ULONG *inp, size_t num, - void *table, size_t power); - void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power); - void bn_power5(BN_ULONG *rp, const BN_ULONG *ap, - const void *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); - int bn_get_bits5(const BN_ULONG *ap, int off); - int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap, - const BN_ULONG *not_used, const BN_ULONG *np, - const BN_ULONG *n0, int num); - - BN_ULONG *n0 = mont->n0, *np; - - /* - * BN_to_montgomery can contaminate words above .top [in - * BN_DEBUG[_DEBUG] build]... - */ - for (i = am.top; i < top; i++) - am.d[i] = 0; - for (i = tmp.top; i < top; i++) - tmp.d[i] = 0; - - /* - * copy mont->N.d[] to improve cache locality - */ - for (np = am.d + top, i = 0; i < top; i++) - np[i] = mont->N.d[i]; - - bn_scatter5(tmp.d, top, powerbuf, 0); - bn_scatter5(am.d, am.top, powerbuf, 1); - bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); - bn_scatter5(tmp.d, top, powerbuf, 2); - -# if 0 - for (i = 3; i < 32; i++) { - /* Calculate a^i = a^(i-1) * a */ - bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); - bn_scatter5(tmp.d, top, powerbuf, i); - } -# else - /* same as above, but uses squaring for 1/2 of operations */ - for (i = 4; i < 32; i *= 2) { - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_scatter5(tmp.d, top, powerbuf, i); - } - for (i = 3; i < 8; i += 2) { - int j; - bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); - bn_scatter5(tmp.d, top, powerbuf, i); - for (j = 2 * i; j < 32; j *= 2) { - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_scatter5(tmp.d, top, powerbuf, j); - } - } - for (; i < 16; i += 2) { - bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); - bn_scatter5(tmp.d, top, powerbuf, i); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_scatter5(tmp.d, top, powerbuf, 2 * i); - } - for (; i < 32; i += 2) { - bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); - bn_scatter5(tmp.d, top, powerbuf, i); - } -# endif - bits--; - for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) - wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); - bn_gather5(tmp.d, top, powerbuf, wvalue); - - /* - * Scan the exponent one window at a time starting from the most - * significant bits. - */ - if (top & 7) - while (bits >= 0) { - for (wvalue = 0, i = 0; i < 5; i++, bits--) - wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); - - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, - wvalue); - } else { - while (bits >= 0) { - wvalue = bn_get_bits5(p->d, bits - 4); - bits -= 5; - bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); - } - } - - ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top); - tmp.top = top; - bn_correct_top(&tmp); - if (ret) { - if (!BN_copy(rr, &tmp)) - ret = 0; - goto err; /* non-zero ret means it's not error */ - } - } else -#endif - { - if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window)) - goto err; - if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window)) - goto err; - - /* - * If the window size is greater than 1, then calculate - * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) (even - * powers could instead be computed as (a^(i/2))^2 to use the slight - * performance advantage of sqr over mul). - */ - if (window > 1) { - if (!bn_mul_mont_fixed_top(&tmp, &am, &am, mont, ctx)) - goto err; - if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, - window)) - goto err; - for (i = 3; i < numPowers; i++) { - /* Calculate a^i = a^(i-1) * a */ - if (!bn_mul_mont_fixed_top(&tmp, &am, &tmp, mont, ctx)) - goto err; - if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i, - window)) - goto err; - } - } - - bits--; - for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) - wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); - if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue, - window)) - goto err; - - /* - * Scan the exponent one window at a time starting from the most - * significant bits. - */ - while (bits >= 0) { - wvalue = 0; /* The 'value' of the window */ - - /* Scan the window, squaring the result as we go */ - for (i = 0; i < window; i++, bits--) { - if (!bn_mul_mont_fixed_top(&tmp, &tmp, &tmp, mont, ctx)) - goto err; - wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); - } - - /* - * Fetch the appropriate pre-computed value from the pre-buf - */ - if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, - window)) - goto err; - - /* Multiply the result into the intermediate result */ - if (!bn_mul_mont_fixed_top(&tmp, &tmp, &am, mont, ctx)) - goto err; - } - } - - /* - * Done with zero-padded intermediate BIGNUMs. Final BN_from_montgomery - * removes padding [if any] and makes return value suitable for public - * API consumer. - */ -#if defined(SPARC_T4_MONT) - if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) { - am.d[0] = 1; /* borrow am */ - for (i = 1; i < top; i++) - am.d[i] = 0; - if (!BN_mod_mul_montgomery(rr, &tmp, &am, mont, ctx)) - goto err; - } else -#endif - if (!BN_from_montgomery(rr, &tmp, mont, ctx)) - goto err; - ret = 1; - err: - if ((in_mont == NULL) && (mont != NULL)) - BN_MONT_CTX_free(mont); - if (powerbuf != NULL) { - OPENSSL_cleanse(powerbuf, powerbufLen); - if (powerbufFree) - OPENSSL_free(powerbufFree); - } - BN_CTX_end(ctx); - return (ret); -} - -int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) -{ - BN_MONT_CTX *mont = NULL; - int b, bits, ret = 0; - int r_is_one; - BN_ULONG w, next_w; - BIGNUM *d, *r, *t; - BIGNUM *swap_tmp; -#define BN_MOD_MUL_WORD(r, w, m) \ - (BN_mul_word(r, (w)) && \ - (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \ - (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1)))) - /* - * BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is - * probably more overhead than always using BN_mod (which uses BN_copy if - * a similar test returns true). - */ - /* - * We can use BN_mod and do not need BN_nnmod because our accumulator is - * never negative (the result of BN_mod does not depend on the sign of - * the modulus). - */ -#define BN_TO_MONTGOMERY_WORD(r, w, mont) \ - (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) - - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 - || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { - /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ - BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - bn_check_top(p); - bn_check_top(m); - - if (!BN_is_odd(m)) { - BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS); - return (0); - } - if (m->top == 1) - a %= m->d[0]; /* make sure that 'a' is reduced */ - - bits = BN_num_bits(p); - if (bits == 0) { - /* x**0 mod 1, or x**0 mod -1 is still zero. */ - if (BN_abs_is_word(m, 1)) { - ret = 1; - BN_zero(rr); - } else { - ret = BN_one(rr); - } - return ret; - } - if (a == 0) { - BN_zero(rr); - ret = 1; - return ret; - } - - BN_CTX_start(ctx); - d = BN_CTX_get(ctx); - r = BN_CTX_get(ctx); - t = BN_CTX_get(ctx); - if (d == NULL || r == NULL || t == NULL) - goto err; - - if (in_mont != NULL) - mont = in_mont; - else { - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - if (!BN_MONT_CTX_set(mont, m, ctx)) - goto err; - } - - r_is_one = 1; /* except for Montgomery factor */ - - /* bits-1 >= 0 */ - - /* The result is accumulated in the product r*w. */ - w = a; /* bit 'bits-1' of 'p' is always set */ - for (b = bits - 2; b >= 0; b--) { - /* First, square r*w. */ - next_w = w * w; - if ((next_w / w) != w) { /* overflow */ - if (r_is_one) { - if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) - goto err; - r_is_one = 0; - } else { - if (!BN_MOD_MUL_WORD(r, w, m)) - goto err; - } - next_w = 1; - } - w = next_w; - if (!r_is_one) { - if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) - goto err; - } - - /* Second, multiply r*w by 'a' if exponent bit is set. */ - if (BN_is_bit_set(p, b)) { - next_w = w * a; - if ((next_w / a) != w) { /* overflow */ - if (r_is_one) { - if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) - goto err; - r_is_one = 0; - } else { - if (!BN_MOD_MUL_WORD(r, w, m)) - goto err; - } - next_w = a; - } - w = next_w; - } - } - - /* Finally, set r:=r*w. */ - if (w != 1) { - if (r_is_one) { - if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) - goto err; - r_is_one = 0; - } else { - if (!BN_MOD_MUL_WORD(r, w, m)) - goto err; - } - } - - if (r_is_one) { /* can happen only if a == 1 */ - if (!BN_one(rr)) - goto err; - } else { - if (!BN_from_montgomery(rr, r, mont, ctx)) - goto err; - } - ret = 1; - err: - if ((in_mont == NULL) && (mont != NULL)) - BN_MONT_CTX_free(mont); - BN_CTX_end(ctx); - bn_check_top(rr); - return (ret); -} - -/* The old fallback, simple version :-) */ -int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - int i, j, bits, ret = 0, wstart, wend, window, wvalue; - int start = 1; - BIGNUM *d; - /* Table of variables obtained from 'ctx' */ - BIGNUM *val[TABLE_SIZE]; - - if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0 - || BN_get_flags(a, BN_FLG_CONSTTIME) != 0 - || BN_get_flags(m, BN_FLG_CONSTTIME) != 0) { - /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ - BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - bits = BN_num_bits(p); - if (bits == 0) { - /* x**0 mod 1, or x**0 mod -1 is still zero. */ - if (BN_abs_is_word(m, 1)) { - ret = 1; - BN_zero(r); - } else { - ret = BN_one(r); - } - return ret; - } - - BN_CTX_start(ctx); - d = BN_CTX_get(ctx); - val[0] = BN_CTX_get(ctx); - if (!d || !val[0]) - goto err; - - if (!BN_nnmod(val[0], a, m, ctx)) - goto err; /* 1 */ - if (BN_is_zero(val[0])) { - BN_zero(r); - ret = 1; - goto err; - } - - window = BN_window_bits_for_exponent_size(bits); - if (window > 1) { - if (!BN_mod_mul(d, val[0], val[0], m, ctx)) - goto err; /* 2 */ - j = 1 << (window - 1); - for (i = 1; i < j; i++) { - if (((val[i] = BN_CTX_get(ctx)) == NULL) || - !BN_mod_mul(val[i], val[i - 1], d, m, ctx)) - goto err; - } - } - - start = 1; /* This is used to avoid multiplication etc - * when there is only the value '1' in the - * buffer. */ - wvalue = 0; /* The 'value' of the window */ - wstart = bits - 1; /* The top bit of the window */ - wend = 0; /* The bottom bit of the window */ - - if (!BN_one(r)) - goto err; - - for (;;) { - if (BN_is_bit_set(p, wstart) == 0) { - if (!start) - if (!BN_mod_mul(r, r, r, m, ctx)) - goto err; - if (wstart == 0) - break; - wstart--; - continue; - } - /* - * We now have wstart on a 'set' bit, we now need to work out how bit - * a window to do. To do this we need to scan forward until the last - * set bit before the end of the window - */ - j = wstart; - wvalue = 1; - wend = 0; - for (i = 1; i < window; i++) { - if (wstart - i < 0) - break; - if (BN_is_bit_set(p, wstart - i)) { - wvalue <<= (i - wend); - wvalue |= 1; - wend = i; - } - } - - /* wend is the size of the current window */ - j = wend + 1; - /* add the 'bytes above' */ - if (!start) - for (i = 0; i < j; i++) { - if (!BN_mod_mul(r, r, r, m, ctx)) - goto err; - } - - /* wvalue will be an odd number < 2^window */ - if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx)) - goto err; - - /* move the 'window' down further */ - wstart -= wend + 1; - wvalue = 0; - start = 0; - if (wstart < 0) - break; - } - ret = 1; - err: - BN_CTX_end(ctx); - bn_check_top(r); - return (ret); -} -/* crypto/bn/bn_exp2.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -#define TABLE_SIZE 32 - -int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, - const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *in_mont) -{ - int i, j, bits, b, bits1, bits2, ret = - 0, wpos1, wpos2, window1, window2, wvalue1, wvalue2; - int r_is_one = 1; - BIGNUM *d, *r; - const BIGNUM *a_mod_m; - /* Tables of variables obtained from 'ctx' */ - BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE]; - BN_MONT_CTX *mont = NULL; - - bn_check_top(a1); - bn_check_top(p1); - bn_check_top(a2); - bn_check_top(p2); - bn_check_top(m); - - if (!(m->d[0] & 1)) { - BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); - return (0); - } - bits1 = BN_num_bits(p1); - bits2 = BN_num_bits(p2); - if ((bits1 == 0) && (bits2 == 0)) { - ret = BN_one(rr); - return ret; - } - - bits = (bits1 > bits2) ? bits1 : bits2; - - BN_CTX_start(ctx); - d = BN_CTX_get(ctx); - r = BN_CTX_get(ctx); - val1[0] = BN_CTX_get(ctx); - val2[0] = BN_CTX_get(ctx); - if (!d || !r || !val1[0] || !val2[0]) - goto err; - - if (in_mont != NULL) - mont = in_mont; - else { - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - if (!BN_MONT_CTX_set(mont, m, ctx)) - goto err; - } - - window1 = BN_window_bits_for_exponent_size(bits1); - window2 = BN_window_bits_for_exponent_size(bits2); - - /* - * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1) - */ - if (a1->neg || BN_ucmp(a1, m) >= 0) { - if (!BN_mod(val1[0], a1, m, ctx)) - goto err; - a_mod_m = val1[0]; - } else - a_mod_m = a1; - if (BN_is_zero(a_mod_m)) { - BN_zero(rr); - ret = 1; - goto err; - } - - if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx)) - goto err; - if (window1 > 1) { - if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx)) - goto err; - - j = 1 << (window1 - 1); - for (i = 1; i < j; i++) { - if (((val1[i] = BN_CTX_get(ctx)) == NULL) || - !BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx)) - goto err; - } - } - - /* - * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1) - */ - if (a2->neg || BN_ucmp(a2, m) >= 0) { - if (!BN_mod(val2[0], a2, m, ctx)) - goto err; - a_mod_m = val2[0]; - } else - a_mod_m = a2; - if (BN_is_zero(a_mod_m)) { - BN_zero(rr); - ret = 1; - goto err; - } - if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx)) - goto err; - if (window2 > 1) { - if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx)) - goto err; - - j = 1 << (window2 - 1); - for (i = 1; i < j; i++) { - if (((val2[i] = BN_CTX_get(ctx)) == NULL) || - !BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx)) - goto err; - } - } - - /* Now compute the power product, using independent windows. */ - r_is_one = 1; - wvalue1 = 0; /* The 'value' of the first window */ - wvalue2 = 0; /* The 'value' of the second window */ - wpos1 = 0; /* If wvalue1 > 0, the bottom bit of the - * first window */ - wpos2 = 0; /* If wvalue2 > 0, the bottom bit of the - * second window */ - - if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) - goto err; - for (b = bits - 1; b >= 0; b--) { - if (!r_is_one) { - if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) - goto err; - } - - if (!wvalue1) - if (BN_is_bit_set(p1, b)) { - /* - * consider bits b-window1+1 .. b for this window - */ - i = b - window1 + 1; - while (!BN_is_bit_set(p1, i)) /* works for i<0 */ - i++; - wpos1 = i; - wvalue1 = 1; - for (i = b - 1; i >= wpos1; i--) { - wvalue1 <<= 1; - if (BN_is_bit_set(p1, i)) - wvalue1++; - } - } - - if (!wvalue2) - if (BN_is_bit_set(p2, b)) { - /* - * consider bits b-window2+1 .. b for this window - */ - i = b - window2 + 1; - while (!BN_is_bit_set(p2, i)) - i++; - wpos2 = i; - wvalue2 = 1; - for (i = b - 1; i >= wpos2; i--) { - wvalue2 <<= 1; - if (BN_is_bit_set(p2, i)) - wvalue2++; - } - } - - if (wvalue1 && b == wpos1) { - /* wvalue1 is odd and < 2^window1 */ - if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx)) - goto err; - wvalue1 = 0; - r_is_one = 0; - } - - if (wvalue2 && b == wpos2) { - /* wvalue2 is odd and < 2^window2 */ - if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx)) - goto err; - wvalue2 = 0; - r_is_one = 0; - } - } - if (!BN_from_montgomery(rr, r, mont, ctx)) - goto err; - ret = 1; - err: - if ((in_mont == NULL) && (mont != NULL)) - BN_MONT_CTX_free(mont); - BN_CTX_end(ctx); - bn_check_top(rr); - return (ret); -} -/* crypto/bn/bn_gcd.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "bn_lcl.h" - -static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); - -int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) -{ - BIGNUM *a, *b, *t; - int ret = 0; - - bn_check_top(in_a); - bn_check_top(in_b); - - BN_CTX_start(ctx); - a = BN_CTX_get(ctx); - b = BN_CTX_get(ctx); - if (a == NULL || b == NULL) - goto err; - - if (BN_copy(a, in_a) == NULL) - goto err; - if (BN_copy(b, in_b) == NULL) - goto err; - a->neg = 0; - b->neg = 0; - - if (BN_cmp(a, b) < 0) { - t = a; - a = b; - b = t; - } - t = euclid(a, b); - if (t == NULL) - goto err; - - if (BN_copy(r, t) == NULL) - goto err; - ret = 1; - err: - BN_CTX_end(ctx); - bn_check_top(r); - return (ret); -} - -static BIGNUM *euclid(BIGNUM *a, BIGNUM *b) -{ - BIGNUM *t; - int shifts = 0; - - bn_check_top(a); - bn_check_top(b); - - /* 0 <= b <= a */ - while (!BN_is_zero(b)) { - /* 0 < b <= a */ - - if (BN_is_odd(a)) { - if (BN_is_odd(b)) { - if (!BN_sub(a, a, b)) - goto err; - if (!BN_rshift1(a, a)) - goto err; - if (BN_cmp(a, b) < 0) { - t = a; - a = b; - b = t; - } - } else { /* a odd - b even */ - - if (!BN_rshift1(b, b)) - goto err; - if (BN_cmp(a, b) < 0) { - t = a; - a = b; - b = t; - } - } - } else { /* a is even */ - - if (BN_is_odd(b)) { - if (!BN_rshift1(a, a)) - goto err; - if (BN_cmp(a, b) < 0) { - t = a; - a = b; - b = t; - } - } else { /* a even - b even */ - - if (!BN_rshift1(a, a)) - goto err; - if (!BN_rshift1(b, b)) - goto err; - shifts++; - } - } - /* 0 <= b <= a */ - } - - if (shifts) { - if (!BN_lshift(a, a, shifts)) - goto err; - } - bn_check_top(a); - return (a); - err: - return (NULL); -} - -/* solves ax == 1 (mod n) */ -static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, - const BIGNUM *a, const BIGNUM *n, - BN_CTX *ctx); - -BIGNUM *BN_mod_inverse(BIGNUM *in, - const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) -{ - BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; - BIGNUM *ret = NULL; - int sign; - - if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) - || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) { - return BN_mod_inverse_no_branch(in, a, n, ctx); - } - - bn_check_top(a); - bn_check_top(n); - - BN_CTX_start(ctx); - A = BN_CTX_get(ctx); - B = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - D = BN_CTX_get(ctx); - M = BN_CTX_get(ctx); - Y = BN_CTX_get(ctx); - T = BN_CTX_get(ctx); - if (T == NULL) - goto err; - - if (in == NULL) - R = BN_new(); - else - R = in; - if (R == NULL) - goto err; - - BN_one(X); - BN_zero(Y); - if (BN_copy(B, a) == NULL) - goto err; - if (BN_copy(A, n) == NULL) - goto err; - A->neg = 0; - if (B->neg || (BN_ucmp(B, A) >= 0)) { - if (!BN_nnmod(B, B, A, ctx)) - goto err; - } - sign = -1; - /*- - * From B = a mod |n|, A = |n| it follows that - * - * 0 <= B < A, - * -sign*X*a == B (mod |n|), - * sign*Y*a == A (mod |n|). - */ - - if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { - /* - * Binary inversion algorithm; requires odd modulus. This is faster - * than the general algorithm if the modulus is sufficiently small - * (about 400 .. 500 bits on 32-bit sytems, but much more on 64-bit - * systems) - */ - int shift; - - while (!BN_is_zero(B)) { - /*- - * 0 < B < |n|, - * 0 < A <= |n|, - * (1) -sign*X*a == B (mod |n|), - * (2) sign*Y*a == A (mod |n|) - */ - - /* - * Now divide B by the maximum possible power of two in the - * integers, and divide X by the same value mod |n|. When we're - * done, (1) still holds. - */ - shift = 0; - while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */ - shift++; - - if (BN_is_odd(X)) { - if (!BN_uadd(X, X, n)) - goto err; - } - /* - * now X is even, so we can easily divide it by two - */ - if (!BN_rshift1(X, X)) - goto err; - } - if (shift > 0) { - if (!BN_rshift(B, B, shift)) - goto err; - } - - /* - * Same for A and Y. Afterwards, (2) still holds. - */ - shift = 0; - while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */ - shift++; - - if (BN_is_odd(Y)) { - if (!BN_uadd(Y, Y, n)) - goto err; - } - /* now Y is even */ - if (!BN_rshift1(Y, Y)) - goto err; - } - if (shift > 0) { - if (!BN_rshift(A, A, shift)) - goto err; - } - - /*- - * We still have (1) and (2). - * Both A and B are odd. - * The following computations ensure that - * - * 0 <= B < |n|, - * 0 < A < |n|, - * (1) -sign*X*a == B (mod |n|), - * (2) sign*Y*a == A (mod |n|), - * - * and that either A or B is even in the next iteration. - */ - if (BN_ucmp(B, A) >= 0) { - /* -sign*(X + Y)*a == B - A (mod |n|) */ - if (!BN_uadd(X, X, Y)) - goto err; - /* - * NB: we could use BN_mod_add_quick(X, X, Y, n), but that - * actually makes the algorithm slower - */ - if (!BN_usub(B, B, A)) - goto err; - } else { - /* sign*(X + Y)*a == A - B (mod |n|) */ - if (!BN_uadd(Y, Y, X)) - goto err; - /* - * as above, BN_mod_add_quick(Y, Y, X, n) would slow things - * down - */ - if (!BN_usub(A, A, B)) - goto err; - } - } - } else { - /* general inversion algorithm */ - - while (!BN_is_zero(B)) { - BIGNUM *tmp; - - /*- - * 0 < B < A, - * (*) -sign*X*a == B (mod |n|), - * sign*Y*a == A (mod |n|) - */ - - /* (D, M) := (A/B, A%B) ... */ - if (BN_num_bits(A) == BN_num_bits(B)) { - if (!BN_one(D)) - goto err; - if (!BN_sub(M, A, B)) - goto err; - } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { - /* A/B is 1, 2, or 3 */ - if (!BN_lshift1(T, B)) - goto err; - if (BN_ucmp(A, T) < 0) { - /* A < 2*B, so D=1 */ - if (!BN_one(D)) - goto err; - if (!BN_sub(M, A, B)) - goto err; - } else { - /* A >= 2*B, so D=2 or D=3 */ - if (!BN_sub(M, A, T)) - goto err; - if (!BN_add(D, T, B)) - goto err; /* use D (:= 3*B) as temp */ - if (BN_ucmp(A, D) < 0) { - /* A < 3*B, so D=2 */ - if (!BN_set_word(D, 2)) - goto err; - /* - * M (= A - 2*B) already has the correct value - */ - } else { - /* only D=3 remains */ - if (!BN_set_word(D, 3)) - goto err; - /* - * currently M = A - 2*B, but we need M = A - 3*B - */ - if (!BN_sub(M, M, B)) - goto err; - } - } - } else { - if (!BN_div(D, M, A, B, ctx)) - goto err; - } - - /*- - * Now - * A = D*B + M; - * thus we have - * (**) sign*Y*a == D*B + M (mod |n|). - */ - - tmp = A; /* keep the BIGNUM object, the value does not - * matter */ - - /* (A, B) := (B, A mod B) ... */ - A = B; - B = M; - /* ... so we have 0 <= B < A again */ - - /*- - * Since the former M is now B and the former B is now A, - * (**) translates into - * sign*Y*a == D*A + B (mod |n|), - * i.e. - * sign*Y*a - D*A == B (mod |n|). - * Similarly, (*) translates into - * -sign*X*a == A (mod |n|). - * - * Thus, - * sign*Y*a + D*sign*X*a == B (mod |n|), - * i.e. - * sign*(Y + D*X)*a == B (mod |n|). - * - * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at - * -sign*X*a == B (mod |n|), - * sign*Y*a == A (mod |n|). - * Note that X and Y stay non-negative all the time. - */ - - /* - * most of the time D is very small, so we can optimize tmp := - * D*X+Y - */ - if (BN_is_one(D)) { - if (!BN_add(tmp, X, Y)) - goto err; - } else { - if (BN_is_word(D, 2)) { - if (!BN_lshift1(tmp, X)) - goto err; - } else if (BN_is_word(D, 4)) { - if (!BN_lshift(tmp, X, 2)) - goto err; - } else if (D->top == 1) { - if (!BN_copy(tmp, X)) - goto err; - if (!BN_mul_word(tmp, D->d[0])) - goto err; - } else { - if (!BN_mul(tmp, D, X, ctx)) - goto err; - } - if (!BN_add(tmp, tmp, Y)) - goto err; - } - - M = Y; /* keep the BIGNUM object, the value does not - * matter */ - Y = X; - X = tmp; - sign = -sign; - } - } - - /*- - * The while loop (Euclid's algorithm) ends when - * A == gcd(a,n); - * we have - * sign*Y*a == A (mod |n|), - * where Y is non-negative. - */ - - if (sign < 0) { - if (!BN_sub(Y, n, Y)) - goto err; - } - /* Now Y*a == A (mod |n|). */ - - if (BN_is_one(A)) { - /* Y*a == 1 (mod |n|) */ - if (!Y->neg && BN_ucmp(Y, n) < 0) { - if (!BN_copy(R, Y)) - goto err; - } else { - if (!BN_nnmod(R, Y, n, ctx)) - goto err; - } - } else { - BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE); - goto err; - } - ret = R; - err: - if ((ret == NULL) && (in == NULL)) - BN_free(R); - BN_CTX_end(ctx); - bn_check_top(ret); - return (ret); -} - -/* - * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does - * not contain branches that may leak sensitive information. - */ -static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, - const BIGNUM *a, const BIGNUM *n, - BN_CTX *ctx) -{ - BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; - BIGNUM local_A, local_B; - BIGNUM *pA, *pB; - BIGNUM *ret = NULL; - int sign; - - bn_check_top(a); - bn_check_top(n); - - BN_CTX_start(ctx); - A = BN_CTX_get(ctx); - B = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - D = BN_CTX_get(ctx); - M = BN_CTX_get(ctx); - Y = BN_CTX_get(ctx); - T = BN_CTX_get(ctx); - if (T == NULL) - goto err; - - if (in == NULL) - R = BN_new(); - else - R = in; - if (R == NULL) - goto err; - - BN_one(X); - BN_zero(Y); - if (BN_copy(B, a) == NULL) - goto err; - if (BN_copy(A, n) == NULL) - goto err; - A->neg = 0; - - if (B->neg || (BN_ucmp(B, A) >= 0)) { - /* - * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, - * BN_div_no_branch will be called eventually. - */ - pB = &local_B; - local_B.flags = 0; - BN_with_flags(pB, B, BN_FLG_CONSTTIME); - if (!BN_nnmod(B, pB, A, ctx)) - goto err; - } - sign = -1; - /*- - * From B = a mod |n|, A = |n| it follows that - * - * 0 <= B < A, - * -sign*X*a == B (mod |n|), - * sign*Y*a == A (mod |n|). - */ - - while (!BN_is_zero(B)) { - BIGNUM *tmp; - - /*- - * 0 < B < A, - * (*) -sign*X*a == B (mod |n|), - * sign*Y*a == A (mod |n|) - */ - - /* - * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, - * BN_div_no_branch will be called eventually. - */ - pA = &local_A; - local_A.flags = 0; - BN_with_flags(pA, A, BN_FLG_CONSTTIME); - - /* (D, M) := (A/B, A%B) ... */ - if (!BN_div(D, M, pA, B, ctx)) - goto err; - - /*- - * Now - * A = D*B + M; - * thus we have - * (**) sign*Y*a == D*B + M (mod |n|). - */ - - tmp = A; /* keep the BIGNUM object, the value does not - * matter */ - - /* (A, B) := (B, A mod B) ... */ - A = B; - B = M; - /* ... so we have 0 <= B < A again */ - - /*- - * Since the former M is now B and the former B is now A, - * (**) translates into - * sign*Y*a == D*A + B (mod |n|), - * i.e. - * sign*Y*a - D*A == B (mod |n|). - * Similarly, (*) translates into - * -sign*X*a == A (mod |n|). - * - * Thus, - * sign*Y*a + D*sign*X*a == B (mod |n|), - * i.e. - * sign*(Y + D*X)*a == B (mod |n|). - * - * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at - * -sign*X*a == B (mod |n|), - * sign*Y*a == A (mod |n|). - * Note that X and Y stay non-negative all the time. - */ - - if (!BN_mul(tmp, D, X, ctx)) - goto err; - if (!BN_add(tmp, tmp, Y)) - goto err; - - M = Y; /* keep the BIGNUM object, the value does not - * matter */ - Y = X; - X = tmp; - sign = -sign; - } - - /*- - * The while loop (Euclid's algorithm) ends when - * A == gcd(a,n); - * we have - * sign*Y*a == A (mod |n|), - * where Y is non-negative. - */ - - if (sign < 0) { - if (!BN_sub(Y, n, Y)) - goto err; - } - /* Now Y*a == A (mod |n|). */ - - if (BN_is_one(A)) { - /* Y*a == 1 (mod |n|) */ - if (!Y->neg && BN_ucmp(Y, n) < 0) { - if (!BN_copy(R, Y)) - goto err; - } else { - if (!BN_nnmod(R, Y, n, ctx)) - goto err; - } - } else { - BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE); - goto err; - } - ret = R; - err: - if ((ret == NULL) && (in == NULL)) - BN_free(R); - BN_CTX_end(ctx); - bn_check_top(ret); - return (ret); -} -/* crypto/bn/bn_gf2m.c */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * In addition, Sun covenants to all licensees who provide a reciprocal - * covenant with respect to their own patents if any, not to sue under - * current and future patent claims necessarily infringed by the making, - * using, practicing, selling, offering for sale and/or otherwise - * disposing of the ECC Code as delivered hereunder (or portions thereof), - * provided that such covenant shall not apply: - * 1) for code that a licensee deletes from the ECC Code; - * 2) separates from the ECC Code; or - * 3) for infringements caused by: - * i) the modification of the ECC Code or - * ii) the combination of the ECC Code with other software or - * devices where such combination causes the infringement. - * - * The software is originally written by Sheueling Chang Shantz and - * Douglas Stebila of Sun Microsystems Laboratories. - * - */ - -/* - * NOTE: This file is licensed pursuant to the OpenSSL license below and may - * be modified; but after modifications, the above covenant may no longer - * apply! In such cases, the corresponding paragraph ["In addition, Sun - * covenants ... causes the infringement."] and this note can be edited out; - * but please keep the Sun copyright notice and attribution. - */ - -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -#ifndef OPENSSL_NO_EC2M - -/* - * Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should - * fail. - */ -# define MAX_ITERATIONS 50 - -# define SQR_nibble(w) ((((w) & 8) << 3) \ - | (((w) & 4) << 2) \ - | (((w) & 2) << 1) \ - | ((w) & 1)) - - -/* Platform-specific macros to accelerate squaring. */ -# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) -# define SQR1(w) \ - SQR_nibble((w) >> 60) << 56 | SQR_nibble((w) >> 56) << 48 | \ - SQR_nibble((w) >> 52) << 40 | SQR_nibble((w) >> 48) << 32 | \ - SQR_nibble((w) >> 44) << 24 | SQR_nibble((w) >> 40) << 16 | \ - SQR_nibble((w) >> 36) << 8 | SQR_nibble((w) >> 32) -# define SQR0(w) \ - SQR_nibble((w) >> 28) << 56 | SQR_nibble((w) >> 24) << 48 | \ - SQR_nibble((w) >> 20) << 40 | SQR_nibble((w) >> 16) << 32 | \ - SQR_nibble((w) >> 12) << 24 | SQR_nibble((w) >> 8) << 16 | \ - SQR_nibble((w) >> 4) << 8 | SQR_nibble((w) ) -# endif -# ifdef THIRTY_TWO_BIT -# define SQR1(w) \ - SQR_nibble((w) >> 28) << 24 | SQR_nibble((w) >> 24) << 16 | \ - SQR_nibble((w) >> 20) << 8 | SQR_nibble((w) >> 16) -# define SQR0(w) \ - SQR_nibble((w) >> 12) << 24 | SQR_nibble((w) >> 8) << 16 | \ - SQR_nibble((w) >> 4) << 8 | SQR_nibble((w) ) -# endif - -# if !defined(OPENSSL_BN_ASM_GF2m) -/* - * Product of two polynomials a, b each with degree < BN_BITS2 - 1, result is - * a polynomial r with degree < 2 * BN_BITS - 1 The caller MUST ensure that - * the variables have the right amount of space allocated. - */ -# ifdef THIRTY_TWO_BIT -static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, - const BN_ULONG b) -{ - register BN_ULONG h, l, s; - BN_ULONG tab[8], top2b = a >> 30; - register BN_ULONG a1, a2, a4; - - a1 = a & (0x3FFFFFFF); - a2 = a1 << 1; - a4 = a2 << 1; - - tab[0] = 0; - tab[1] = a1; - tab[2] = a2; - tab[3] = a1 ^ a2; - tab[4] = a4; - tab[5] = a1 ^ a4; - tab[6] = a2 ^ a4; - tab[7] = a1 ^ a2 ^ a4; - - s = tab[b & 0x7]; - l = s; - s = tab[b >> 3 & 0x7]; - l ^= s << 3; - h = s >> 29; - s = tab[b >> 6 & 0x7]; - l ^= s << 6; - h ^= s >> 26; - s = tab[b >> 9 & 0x7]; - l ^= s << 9; - h ^= s >> 23; - s = tab[b >> 12 & 0x7]; - l ^= s << 12; - h ^= s >> 20; - s = tab[b >> 15 & 0x7]; - l ^= s << 15; - h ^= s >> 17; - s = tab[b >> 18 & 0x7]; - l ^= s << 18; - h ^= s >> 14; - s = tab[b >> 21 & 0x7]; - l ^= s << 21; - h ^= s >> 11; - s = tab[b >> 24 & 0x7]; - l ^= s << 24; - h ^= s >> 8; - s = tab[b >> 27 & 0x7]; - l ^= s << 27; - h ^= s >> 5; - s = tab[b >> 30]; - l ^= s << 30; - h ^= s >> 2; - - /* compensate for the top two bits of a */ - - if (top2b & 01) { - l ^= b << 30; - h ^= b >> 2; - } - if (top2b & 02) { - l ^= b << 31; - h ^= b >> 1; - } - - *r1 = h; - *r0 = l; -} -# endif -# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) -static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, - const BN_ULONG b) -{ - register BN_ULONG h, l, s; - BN_ULONG tab[16], top3b = a >> 61; - register BN_ULONG a1, a2, a4, a8; - - a1 = a & (0x1FFFFFFFFFFFFFFFULL); - a2 = a1 << 1; - a4 = a2 << 1; - a8 = a4 << 1; - - tab[0] = 0; - tab[1] = a1; - tab[2] = a2; - tab[3] = a1 ^ a2; - tab[4] = a4; - tab[5] = a1 ^ a4; - tab[6] = a2 ^ a4; - tab[7] = a1 ^ a2 ^ a4; - tab[8] = a8; - tab[9] = a1 ^ a8; - tab[10] = a2 ^ a8; - tab[11] = a1 ^ a2 ^ a8; - tab[12] = a4 ^ a8; - tab[13] = a1 ^ a4 ^ a8; - tab[14] = a2 ^ a4 ^ a8; - tab[15] = a1 ^ a2 ^ a4 ^ a8; - - s = tab[b & 0xF]; - l = s; - s = tab[b >> 4 & 0xF]; - l ^= s << 4; - h = s >> 60; - s = tab[b >> 8 & 0xF]; - l ^= s << 8; - h ^= s >> 56; - s = tab[b >> 12 & 0xF]; - l ^= s << 12; - h ^= s >> 52; - s = tab[b >> 16 & 0xF]; - l ^= s << 16; - h ^= s >> 48; - s = tab[b >> 20 & 0xF]; - l ^= s << 20; - h ^= s >> 44; - s = tab[b >> 24 & 0xF]; - l ^= s << 24; - h ^= s >> 40; - s = tab[b >> 28 & 0xF]; - l ^= s << 28; - h ^= s >> 36; - s = tab[b >> 32 & 0xF]; - l ^= s << 32; - h ^= s >> 32; - s = tab[b >> 36 & 0xF]; - l ^= s << 36; - h ^= s >> 28; - s = tab[b >> 40 & 0xF]; - l ^= s << 40; - h ^= s >> 24; - s = tab[b >> 44 & 0xF]; - l ^= s << 44; - h ^= s >> 20; - s = tab[b >> 48 & 0xF]; - l ^= s << 48; - h ^= s >> 16; - s = tab[b >> 52 & 0xF]; - l ^= s << 52; - h ^= s >> 12; - s = tab[b >> 56 & 0xF]; - l ^= s << 56; - h ^= s >> 8; - s = tab[b >> 60]; - l ^= s << 60; - h ^= s >> 4; - - /* compensate for the top three bits of a */ - - if (top3b & 01) { - l ^= b << 61; - h ^= b >> 3; - } - if (top3b & 02) { - l ^= b << 62; - h ^= b >> 2; - } - if (top3b & 04) { - l ^= b << 63; - h ^= b >> 1; - } - - *r1 = h; - *r0 = l; -} -# endif - -/* - * Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1, - * result is a polynomial r with degree < 4 * BN_BITS2 - 1 The caller MUST - * ensure that the variables have the right amount of space allocated. - */ -static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, - const BN_ULONG b1, const BN_ULONG b0) -{ - BN_ULONG m1, m0; - /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */ - bn_GF2m_mul_1x1(r + 3, r + 2, a1, b1); - bn_GF2m_mul_1x1(r + 1, r, a0, b0); - bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1); - /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */ - r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ - r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ -} -# else -void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, - BN_ULONG b0); -# endif - -/* - * Add polynomials a and b and store result in r; r could be a or b, a and b - * could be equal; r is the bitwise XOR of a and b. - */ -int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) -{ - int i; - const BIGNUM *at, *bt; - - bn_check_top(a); - bn_check_top(b); - - if (a->top < b->top) { - at = b; - bt = a; - } else { - at = a; - bt = b; - } - - if (bn_wexpand(r, at->top) == NULL) - return 0; - - for (i = 0; i < bt->top; i++) { - r->d[i] = at->d[i] ^ bt->d[i]; - } - for (; i < at->top; i++) { - r->d[i] = at->d[i]; - } - - r->top = at->top; - bn_correct_top(r); - - return 1; -} - -/*- - * Some functions allow for representation of the irreducible polynomials - * as an int[], say p. The irreducible f(t) is then of the form: - * t^p[0] + t^p[1] + ... + t^p[k] - * where m = p[0] > p[1] > ... > p[k] = 0. - */ - -/* Performs modular reduction of a and store result in r. r could be a. */ -int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]) -{ - int j, k; - int n, dN, d0, d1; - BN_ULONG zz, *z; - - bn_check_top(a); - - if (!p[0]) { - /* reduction mod 1 => return 0 */ - BN_zero(r); - return 1; - } - - /* - * Since the algorithm does reduction in the r value, if a != r, copy the - * contents of a into r so we can do reduction in r. - */ - if (a != r) { - if (!bn_wexpand(r, a->top)) - return 0; - for (j = 0; j < a->top; j++) { - r->d[j] = a->d[j]; - } - r->top = a->top; - } - z = r->d; - - /* start reduction */ - dN = p[0] / BN_BITS2; - for (j = r->top - 1; j > dN;) { - zz = z[j]; - if (z[j] == 0) { - j--; - continue; - } - z[j] = 0; - - for (k = 1; p[k] != 0; k++) { - /* reducing component t^p[k] */ - n = p[0] - p[k]; - d0 = n % BN_BITS2; - d1 = BN_BITS2 - d0; - n /= BN_BITS2; - z[j - n] ^= (zz >> d0); - if (d0) - z[j - n - 1] ^= (zz << d1); - } - - /* reducing component t^0 */ - n = dN; - d0 = p[0] % BN_BITS2; - d1 = BN_BITS2 - d0; - z[j - n] ^= (zz >> d0); - if (d0) - z[j - n - 1] ^= (zz << d1); - } - - /* final round of reduction */ - while (j == dN) { - - d0 = p[0] % BN_BITS2; - zz = z[dN] >> d0; - if (zz == 0) - break; - d1 = BN_BITS2 - d0; - - /* clear up the top d1 bits */ - if (d0) - z[dN] = (z[dN] << d1) >> d1; - else - z[dN] = 0; - z[0] ^= zz; /* reduction t^0 component */ - - for (k = 1; p[k] != 0; k++) { - BN_ULONG tmp_ulong; - - /* reducing component t^p[k] */ - n = p[k] / BN_BITS2; - d0 = p[k] % BN_BITS2; - d1 = BN_BITS2 - d0; - z[n] ^= (zz << d0); - if (d0 && (tmp_ulong = zz >> d1)) - z[n + 1] ^= tmp_ulong; - } - - } - - bn_correct_top(r); - return 1; -} - -/* - * Performs modular reduction of a by p and store result in r. r could be a. - * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper - * function is only provided for convenience; for best performance, use the - * BN_GF2m_mod_arr function. - */ -int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) -{ - int ret = 0; - int arr[6]; - bn_check_top(a); - bn_check_top(p); - ret = BN_GF2m_poly2arr(p, arr, sizeof(arr) / sizeof(arr[0])); - if (!ret || ret > (int)(sizeof(arr) / sizeof(arr[0]))) { - BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH); - return 0; - } - ret = BN_GF2m_mod_arr(r, a, arr); - bn_check_top(r); - return ret; -} - -/* - * Compute the product of two polynomials a and b, reduce modulo p, and store - * the result in r. r could be a or b; a could be b. - */ -int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const int p[], BN_CTX *ctx) -{ - int zlen, i, j, k, ret = 0; - BIGNUM *s; - BN_ULONG x1, x0, y1, y0, zz[4]; - - bn_check_top(a); - bn_check_top(b); - - if (a == b) { - return BN_GF2m_mod_sqr_arr(r, a, p, ctx); - } - - BN_CTX_start(ctx); - if ((s = BN_CTX_get(ctx)) == NULL) - goto err; - - zlen = a->top + b->top + 4; - if (!bn_wexpand(s, zlen)) - goto err; - s->top = zlen; - - for (i = 0; i < zlen; i++) - s->d[i] = 0; - - for (j = 0; j < b->top; j += 2) { - y0 = b->d[j]; - y1 = ((j + 1) == b->top) ? 0 : b->d[j + 1]; - for (i = 0; i < a->top; i += 2) { - x0 = a->d[i]; - x1 = ((i + 1) == a->top) ? 0 : a->d[i + 1]; - bn_GF2m_mul_2x2(zz, x1, x0, y1, y0); - for (k = 0; k < 4; k++) - s->d[i + j + k] ^= zz[k]; - } - } - - bn_correct_top(s); - if (BN_GF2m_mod_arr(r, s, p)) - ret = 1; - bn_check_top(r); - - err: - BN_CTX_end(ctx); - return ret; -} - -/* - * Compute the product of two polynomials a and b, reduce modulo p, and store - * the result in r. r could be a or b; a could equal b. This function calls - * down to the BN_GF2m_mod_mul_arr implementation; this wrapper function is - * only provided for convenience; for best performance, use the - * BN_GF2m_mod_mul_arr function. - */ -int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *p, BN_CTX *ctx) -{ - int ret = 0; - const int max = BN_num_bits(p) + 1; - int *arr = NULL; - bn_check_top(a); - bn_check_top(b); - bn_check_top(p); - if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) - goto err; - ret = BN_GF2m_poly2arr(p, arr, max); - if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH); - goto err; - } - ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx); - bn_check_top(r); - err: - if (arr) - OPENSSL_free(arr); - return ret; -} - -/* Square a, reduce the result mod p, and store it in a. r could be a. */ -int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], - BN_CTX *ctx) -{ - int i, ret = 0; - BIGNUM *s; - - bn_check_top(a); - BN_CTX_start(ctx); - if ((s = BN_CTX_get(ctx)) == NULL) - goto err; - if (!bn_wexpand(s, 2 * a->top)) - goto err; - - for (i = a->top - 1; i >= 0; i--) { - s->d[2 * i + 1] = SQR1(a->d[i]); - s->d[2 * i] = SQR0(a->d[i]); - } - - s->top = 2 * a->top; - bn_correct_top(s); - if (!BN_GF2m_mod_arr(r, s, p)) - goto err; - bn_check_top(r); - ret = 1; - err: - BN_CTX_end(ctx); - return ret; -} - -/* - * Square a, reduce the result mod p, and store it in a. r could be a. This - * function calls down to the BN_GF2m_mod_sqr_arr implementation; this - * wrapper function is only provided for convenience; for best performance, - * use the BN_GF2m_mod_sqr_arr function. - */ -int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) -{ - int ret = 0; - const int max = BN_num_bits(p) + 1; - int *arr = NULL; - - bn_check_top(a); - bn_check_top(p); - if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) - goto err; - ret = BN_GF2m_poly2arr(p, arr, max); - if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH); - goto err; - } - ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx); - bn_check_top(r); - err: - if (arr) - OPENSSL_free(arr); - return ret; -} - -/* - * Invert a, reduce modulo p, and store the result in r. r could be a. Uses - * Modified Almost Inverse Algorithm (Algorithm 10) from Hankerson, D., - * Hernandez, J.L., and Menezes, A. "Software Implementation of Elliptic - * Curve Cryptography Over Binary Fields". - */ -int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) -{ - BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp; - int ret = 0; - - bn_check_top(a); - bn_check_top(p); - - BN_CTX_start(ctx); - - if ((b = BN_CTX_get(ctx)) == NULL) - goto err; - if ((c = BN_CTX_get(ctx)) == NULL) - goto err; - if ((u = BN_CTX_get(ctx)) == NULL) - goto err; - if ((v = BN_CTX_get(ctx)) == NULL) - goto err; - - if (!BN_GF2m_mod(u, a, p)) - goto err; - if (BN_is_zero(u)) - goto err; - - if (!BN_copy(v, p)) - goto err; -# if 0 - if (!BN_one(b)) - goto err; - - while (1) { - while (!BN_is_odd(u)) { - if (BN_is_zero(u)) - goto err; - if (!BN_rshift1(u, u)) - goto err; - if (BN_is_odd(b)) { - if (!BN_GF2m_add(b, b, p)) - goto err; - } - if (!BN_rshift1(b, b)) - goto err; - } - - if (BN_abs_is_word(u, 1)) - break; - - if (BN_num_bits(u) < BN_num_bits(v)) { - tmp = u; - u = v; - v = tmp; - tmp = b; - b = c; - c = tmp; - } - - if (!BN_GF2m_add(u, u, v)) - goto err; - if (!BN_GF2m_add(b, b, c)) - goto err; - } -# else - { - int i; - int ubits = BN_num_bits(u); - int vbits = BN_num_bits(v); /* v is copy of p */ - int top = p->top; - BN_ULONG *udp, *bdp, *vdp, *cdp; - - if (!bn_wexpand(u, top)) - goto err; - udp = u->d; - for (i = u->top; i < top; i++) - udp[i] = 0; - u->top = top; - if (!bn_wexpand(b, top)) - goto err; - bdp = b->d; - bdp[0] = 1; - for (i = 1; i < top; i++) - bdp[i] = 0; - b->top = top; - if (!bn_wexpand(c, top)) - goto err; - cdp = c->d; - for (i = 0; i < top; i++) - cdp[i] = 0; - c->top = top; - vdp = v->d; /* It pays off to "cache" *->d pointers, - * because it allows optimizer to be more - * aggressive. But we don't have to "cache" - * p->d, because *p is declared 'const'... */ - while (1) { - while (ubits && !(udp[0] & 1)) { - BN_ULONG u0, u1, b0, b1, mask; - - u0 = udp[0]; - b0 = bdp[0]; - mask = (BN_ULONG)0 - (b0 & 1); - b0 ^= p->d[0] & mask; - for (i = 0; i < top - 1; i++) { - u1 = udp[i + 1]; - udp[i] = ((u0 >> 1) | (u1 << (BN_BITS2 - 1))) & BN_MASK2; - u0 = u1; - b1 = bdp[i + 1] ^ (p->d[i + 1] & mask); - bdp[i] = ((b0 >> 1) | (b1 << (BN_BITS2 - 1))) & BN_MASK2; - b0 = b1; - } - udp[i] = u0 >> 1; - bdp[i] = b0 >> 1; - ubits--; - } - - if (ubits <= BN_BITS2) { - if (udp[0] == 0) /* poly was reducible */ - goto err; - if (udp[0] == 1) - break; - } - - if (ubits < vbits) { - i = ubits; - ubits = vbits; - vbits = i; - tmp = u; - u = v; - v = tmp; - tmp = b; - b = c; - c = tmp; - udp = vdp; - vdp = v->d; - bdp = cdp; - cdp = c->d; - } - for (i = 0; i < top; i++) { - udp[i] ^= vdp[i]; - bdp[i] ^= cdp[i]; - } - if (ubits == vbits) { - BN_ULONG ul; - int utop = (ubits - 1) / BN_BITS2; - - while ((ul = udp[utop]) == 0 && utop) - utop--; - ubits = utop * BN_BITS2 + BN_num_bits_word(ul); - } - } - bn_correct_top(b); - } -# endif - - if (!BN_copy(r, b)) - goto err; - bn_check_top(r); - ret = 1; - - err: -# ifdef BN_DEBUG /* BN_CTX_end would complain about the - * expanded form */ - bn_correct_top(c); - bn_correct_top(u); - bn_correct_top(v); -# endif - BN_CTX_end(ctx); - return ret; -} - -/* - * Invert xx, reduce modulo p, and store the result in r. r could be xx. - * This function calls down to the BN_GF2m_mod_inv implementation; this - * wrapper function is only provided for convenience; for best performance, - * use the BN_GF2m_mod_inv function. - */ -int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], - BN_CTX *ctx) -{ - BIGNUM *field; - int ret = 0; - - bn_check_top(xx); - BN_CTX_start(ctx); - if ((field = BN_CTX_get(ctx)) == NULL) - goto err; - if (!BN_GF2m_arr2poly(p, field)) - goto err; - - ret = BN_GF2m_mod_inv(r, xx, field, ctx); - bn_check_top(r); - - err: - BN_CTX_end(ctx); - return ret; -} - -# ifndef OPENSSL_SUN_GF2M_DIV -/* - * Divide y by x, reduce modulo p, and store the result in r. r could be x - * or y, x could equal y. - */ -int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, - const BIGNUM *p, BN_CTX *ctx) -{ - BIGNUM *xinv = NULL; - int ret = 0; - - bn_check_top(y); - bn_check_top(x); - bn_check_top(p); - - BN_CTX_start(ctx); - xinv = BN_CTX_get(ctx); - if (xinv == NULL) - goto err; - - if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) - goto err; - if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) - goto err; - bn_check_top(r); - ret = 1; - - err: - BN_CTX_end(ctx); - return ret; -} -# else -/* - * Divide y by x, reduce modulo p, and store the result in r. r could be x - * or y, x could equal y. Uses algorithm Modular_Division_GF(2^m) from - * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to the - * Great Divide". - */ -int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, - const BIGNUM *p, BN_CTX *ctx) -{ - BIGNUM *a, *b, *u, *v; - int ret = 0; - - bn_check_top(y); - bn_check_top(x); - bn_check_top(p); - - BN_CTX_start(ctx); - - a = BN_CTX_get(ctx); - b = BN_CTX_get(ctx); - u = BN_CTX_get(ctx); - v = BN_CTX_get(ctx); - if (v == NULL) - goto err; - - /* reduce x and y mod p */ - if (!BN_GF2m_mod(u, y, p)) - goto err; - if (!BN_GF2m_mod(a, x, p)) - goto err; - if (!BN_copy(b, p)) - goto err; - - while (!BN_is_odd(a)) { - if (!BN_rshift1(a, a)) - goto err; - if (BN_is_odd(u)) - if (!BN_GF2m_add(u, u, p)) - goto err; - if (!BN_rshift1(u, u)) - goto err; - } - - do { - if (BN_GF2m_cmp(b, a) > 0) { - if (!BN_GF2m_add(b, b, a)) - goto err; - if (!BN_GF2m_add(v, v, u)) - goto err; - do { - if (!BN_rshift1(b, b)) - goto err; - if (BN_is_odd(v)) - if (!BN_GF2m_add(v, v, p)) - goto err; - if (!BN_rshift1(v, v)) - goto err; - } while (!BN_is_odd(b)); - } else if (BN_abs_is_word(a, 1)) - break; - else { - if (!BN_GF2m_add(a, a, b)) - goto err; - if (!BN_GF2m_add(u, u, v)) - goto err; - do { - if (!BN_rshift1(a, a)) - goto err; - if (BN_is_odd(u)) - if (!BN_GF2m_add(u, u, p)) - goto err; - if (!BN_rshift1(u, u)) - goto err; - } while (!BN_is_odd(a)); - } - } while (1); - - if (!BN_copy(r, u)) - goto err; - bn_check_top(r); - ret = 1; - - err: - BN_CTX_end(ctx); - return ret; -} -# endif - -/* - * Divide yy by xx, reduce modulo p, and store the result in r. r could be xx - * * or yy, xx could equal yy. This function calls down to the - * BN_GF2m_mod_div implementation; this wrapper function is only provided for - * convenience; for best performance, use the BN_GF2m_mod_div function. - */ -int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, - const int p[], BN_CTX *ctx) -{ - BIGNUM *field; - int ret = 0; - - bn_check_top(yy); - bn_check_top(xx); - - BN_CTX_start(ctx); - if ((field = BN_CTX_get(ctx)) == NULL) - goto err; - if (!BN_GF2m_arr2poly(p, field)) - goto err; - - ret = BN_GF2m_mod_div(r, yy, xx, field, ctx); - bn_check_top(r); - - err: - BN_CTX_end(ctx); - return ret; -} - -/* - * Compute the bth power of a, reduce modulo p, and store the result in r. r - * could be a. Uses simple square-and-multiply algorithm A.5.1 from IEEE - * P1363. - */ -int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const int p[], BN_CTX *ctx) -{ - int ret = 0, i, n; - BIGNUM *u; - - bn_check_top(a); - bn_check_top(b); - - if (BN_is_zero(b)) - return (BN_one(r)); - - if (BN_abs_is_word(b, 1)) - return (BN_copy(r, a) != NULL); - - BN_CTX_start(ctx); - if ((u = BN_CTX_get(ctx)) == NULL) - goto err; - - if (!BN_GF2m_mod_arr(u, a, p)) - goto err; - - n = BN_num_bits(b) - 1; - for (i = n - 1; i >= 0; i--) { - if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx)) - goto err; - if (BN_is_bit_set(b, i)) { - if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx)) - goto err; - } - } - if (!BN_copy(r, u)) - goto err; - bn_check_top(r); - ret = 1; - err: - BN_CTX_end(ctx); - return ret; -} - -/* - * Compute the bth power of a, reduce modulo p, and store the result in r. r - * could be a. This function calls down to the BN_GF2m_mod_exp_arr - * implementation; this wrapper function is only provided for convenience; - * for best performance, use the BN_GF2m_mod_exp_arr function. - */ -int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *p, BN_CTX *ctx) -{ - int ret = 0; - const int max = BN_num_bits(p) + 1; - int *arr = NULL; - bn_check_top(a); - bn_check_top(b); - bn_check_top(p); - if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) - goto err; - ret = BN_GF2m_poly2arr(p, arr, max); - if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH); - goto err; - } - ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx); - bn_check_top(r); - err: - if (arr) - OPENSSL_free(arr); - return ret; -} - -/* - * Compute the square root of a, reduce modulo p, and store the result in r. - * r could be a. Uses exponentiation as in algorithm A.4.1 from IEEE P1363. - */ -int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], - BN_CTX *ctx) -{ - int ret = 0; - BIGNUM *u; - - bn_check_top(a); - - if (!p[0]) { - /* reduction mod 1 => return 0 */ - BN_zero(r); - return 1; - } - - BN_CTX_start(ctx); - if ((u = BN_CTX_get(ctx)) == NULL) - goto err; - - if (!BN_set_bit(u, p[0] - 1)) - goto err; - ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx); - bn_check_top(r); - - err: - BN_CTX_end(ctx); - return ret; -} - -/* - * Compute the square root of a, reduce modulo p, and store the result in r. - * r could be a. This function calls down to the BN_GF2m_mod_sqrt_arr - * implementation; this wrapper function is only provided for convenience; - * for best performance, use the BN_GF2m_mod_sqrt_arr function. - */ -int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) -{ - int ret = 0; - const int max = BN_num_bits(p) + 1; - int *arr = NULL; - bn_check_top(a); - bn_check_top(p); - if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) - goto err; - ret = BN_GF2m_poly2arr(p, arr, max); - if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH); - goto err; - } - ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx); - bn_check_top(r); - err: - if (arr) - OPENSSL_free(arr); - return ret; -} - -/* - * Find r such that r^2 + r = a mod p. r could be a. If no r exists returns - * 0. Uses algorithms A.4.7 and A.4.6 from IEEE P1363. - */ -int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], - BN_CTX *ctx) -{ - int ret = 0, count = 0, j; - BIGNUM *a, *z, *rho, *w, *w2, *tmp; - - bn_check_top(a_); - - if (!p[0]) { - /* reduction mod 1 => return 0 */ - BN_zero(r); - return 1; - } - - BN_CTX_start(ctx); - a = BN_CTX_get(ctx); - z = BN_CTX_get(ctx); - w = BN_CTX_get(ctx); - if (w == NULL) - goto err; - - if (!BN_GF2m_mod_arr(a, a_, p)) - goto err; - - if (BN_is_zero(a)) { - BN_zero(r); - ret = 1; - goto err; - } - - if (p[0] & 0x1) { /* m is odd */ - /* compute half-trace of a */ - if (!BN_copy(z, a)) - goto err; - for (j = 1; j <= (p[0] - 1) / 2; j++) { - if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) - goto err; - if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) - goto err; - if (!BN_GF2m_add(z, z, a)) - goto err; - } - - } else { /* m is even */ - - rho = BN_CTX_get(ctx); - w2 = BN_CTX_get(ctx); - tmp = BN_CTX_get(ctx); - if (tmp == NULL) - goto err; - do { - if (!BN_rand(rho, p[0], 0, 0)) - goto err; - if (!BN_GF2m_mod_arr(rho, rho, p)) - goto err; - BN_zero(z); - if (!BN_copy(w, rho)) - goto err; - for (j = 1; j <= p[0] - 1; j++) { - if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) - goto err; - if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx)) - goto err; - if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx)) - goto err; - if (!BN_GF2m_add(z, z, tmp)) - goto err; - if (!BN_GF2m_add(w, w2, rho)) - goto err; - } - count++; - } while (BN_is_zero(w) && (count < MAX_ITERATIONS)); - if (BN_is_zero(w)) { - BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_TOO_MANY_ITERATIONS); - goto err; - } - } - - if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) - goto err; - if (!BN_GF2m_add(w, z, w)) - goto err; - if (BN_GF2m_cmp(w, a)) { - BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION); - goto err; - } - - if (!BN_copy(r, z)) - goto err; - bn_check_top(r); - - ret = 1; - - err: - BN_CTX_end(ctx); - return ret; -} - -/* - * Find r such that r^2 + r = a mod p. r could be a. If no r exists returns - * 0. This function calls down to the BN_GF2m_mod_solve_quad_arr - * implementation; this wrapper function is only provided for convenience; - * for best performance, use the BN_GF2m_mod_solve_quad_arr function. - */ -int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - BN_CTX *ctx) -{ - int ret = 0; - const int max = BN_num_bits(p) + 1; - int *arr = NULL; - bn_check_top(a); - bn_check_top(p); - if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) - goto err; - ret = BN_GF2m_poly2arr(p, arr, max); - if (!ret || ret > max) { - BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH); - goto err; - } - ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx); - bn_check_top(r); - err: - if (arr) - OPENSSL_free(arr); - return ret; -} - -/* - * Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i * - * x^i) into an array of integers corresponding to the bits with non-zero - * coefficient. Array is terminated with -1. Up to max elements of the array - * will be filled. Return value is total number of array elements that would - * be filled if array was large enough. - */ -int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max) -{ - int i, j, k = 0; - BN_ULONG mask; - - if (BN_is_zero(a)) - return 0; - - for (i = a->top - 1; i >= 0; i--) { - if (!a->d[i]) - /* skip word if a->d[i] == 0 */ - continue; - mask = BN_TBIT; - for (j = BN_BITS2 - 1; j >= 0; j--) { - if (a->d[i] & mask) { - if (k < max) - p[k] = BN_BITS2 * i + j; - k++; - } - mask >>= 1; - } - } - - if (k < max) { - p[k] = -1; - k++; - } - - return k; -} - -/* - * Convert the coefficient array representation of a polynomial to a - * bit-string. The array must be terminated by -1. - */ -int BN_GF2m_arr2poly(const int p[], BIGNUM *a) -{ - int i; - - bn_check_top(a); - BN_zero(a); - for (i = 0; p[i] != -1; i++) { - if (BN_set_bit(a, p[i]) == 0) - return 0; - } - bn_check_top(a); - - return 1; -} - -#endif -/* crypto/bn/bn_kron.c */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "bn_lcl.h" - -/* least significant word */ -#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0]) - -/* Returns -2 for errors because both -1 and 0 are valid results. */ -int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -{ - int i; - int ret = -2; /* avoid 'uninitialized' warning */ - int err = 0; - BIGNUM *A, *B, *tmp; - /*- - * In 'tab', only odd-indexed entries are relevant: - * For any odd BIGNUM n, - * tab[BN_lsw(n) & 7] - * is $(-1)^{(n^2-1)/8}$ (using TeX notation). - * Note that the sign of n does not matter. - */ - static const int tab[8] = { 0, 1, 0, -1, 0, -1, 0, 1 }; - - bn_check_top(a); - bn_check_top(b); - - BN_CTX_start(ctx); - A = BN_CTX_get(ctx); - B = BN_CTX_get(ctx); - if (B == NULL) - goto end; - - err = !BN_copy(A, a); - if (err) - goto end; - err = !BN_copy(B, b); - if (err) - goto end; - - /* - * Kronecker symbol, imlemented according to Henri Cohen, - * "A Course in Computational Algebraic Number Theory" - * (algorithm 1.4.10). - */ - - /* Cohen's step 1: */ - - if (BN_is_zero(B)) { - ret = BN_abs_is_word(A, 1); - goto end; - } - - /* Cohen's step 2: */ - - if (!BN_is_odd(A) && !BN_is_odd(B)) { - ret = 0; - goto end; - } - - /* now B is non-zero */ - i = 0; - while (!BN_is_bit_set(B, i)) - i++; - err = !BN_rshift(B, B, i); - if (err) - goto end; - if (i & 1) { - /* i is odd */ - /* (thus B was even, thus A must be odd!) */ - - /* set 'ret' to $(-1)^{(A^2-1)/8}$ */ - ret = tab[BN_lsw(A) & 7]; - } else { - /* i is even */ - ret = 1; - } - - if (B->neg) { - B->neg = 0; - if (A->neg) - ret = -ret; - } - - /* - * now B is positive and odd, so what remains to be done is to compute - * the Jacobi symbol (A/B) and multiply it by 'ret' - */ - - while (1) { - /* Cohen's step 3: */ - - /* B is positive and odd */ - - if (BN_is_zero(A)) { - ret = BN_is_one(B) ? ret : 0; - goto end; - } - - /* now A is non-zero */ - i = 0; - while (!BN_is_bit_set(A, i)) - i++; - err = !BN_rshift(A, A, i); - if (err) - goto end; - if (i & 1) { - /* i is odd */ - /* multiply 'ret' by $(-1)^{(B^2-1)/8}$ */ - ret = ret * tab[BN_lsw(B) & 7]; - } - - /* Cohen's step 4: */ - /* multiply 'ret' by $(-1)^{(A-1)(B-1)/4}$ */ - if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2) - ret = -ret; - - /* (A, B) := (B mod |A|, |A|) */ - err = !BN_nnmod(B, B, A, ctx); - if (err) - goto end; - tmp = A; - A = B; - B = tmp; - tmp->neg = 0; - } - end: - BN_CTX_end(ctx); - if (err) - return -2; - else - return ret; -} -/* crypto/bn/bn_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef BN_DEBUG -# undef NDEBUG /* avoid conflicting definitions */ -# define NDEBUG -#endif - -#include -#include -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT; - -/* This stuff appears to be completely unused, so is deprecated */ -#ifndef OPENSSL_NO_DEPRECATED -/*- - * For a 32 bit machine - * 2 - 4 == 128 - * 3 - 8 == 256 - * 4 - 16 == 512 - * 5 - 32 == 1024 - * 6 - 64 == 2048 - * 7 - 128 == 4096 - * 8 - 256 == 8192 - */ -static int bn_limit_bits = 0; -static int bn_limit_num = 8; /* (1<= 0) { - if (mult > (int)(sizeof(int) * 8) - 1) - mult = sizeof(int) * 8 - 1; - bn_limit_bits = mult; - bn_limit_num = 1 << mult; - } - if (high >= 0) { - if (high > (int)(sizeof(int) * 8) - 1) - high = sizeof(int) * 8 - 1; - bn_limit_bits_high = high; - bn_limit_num_high = 1 << high; - } - if (low >= 0) { - if (low > (int)(sizeof(int) * 8) - 1) - low = sizeof(int) * 8 - 1; - bn_limit_bits_low = low; - bn_limit_num_low = 1 << low; - } - if (mont >= 0) { - if (mont > (int)(sizeof(int) * 8) - 1) - mont = sizeof(int) * 8 - 1; - bn_limit_bits_mont = mont; - bn_limit_num_mont = 1 << mont; - } -} - -int BN_get_params(int which) -{ - if (which == 0) - return (bn_limit_bits); - else if (which == 1) - return (bn_limit_bits_high); - else if (which == 2) - return (bn_limit_bits_low); - else if (which == 3) - return (bn_limit_bits_mont); - else - return (0); -} -#endif - -const BIGNUM *BN_value_one(void) -{ - static const BN_ULONG data_one = 1L; - static const BIGNUM const_one = - { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA }; - - return (&const_one); -} - -int BN_num_bits_word(BN_ULONG l) -{ - BN_ULONG x, mask; - int bits = (l != 0); - -#if BN_BITS2 > 32 - x = l >> 32; - mask = (0 - x) & BN_MASK2; - mask = (0 - (mask >> (BN_BITS2 - 1))); - bits += 32 & mask; - l ^= (x ^ l) & mask; -#endif - - x = l >> 16; - mask = (0 - x) & BN_MASK2; - mask = (0 - (mask >> (BN_BITS2 - 1))); - bits += 16 & mask; - l ^= (x ^ l) & mask; - - x = l >> 8; - mask = (0 - x) & BN_MASK2; - mask = (0 - (mask >> (BN_BITS2 - 1))); - bits += 8 & mask; - l ^= (x ^ l) & mask; - - x = l >> 4; - mask = (0 - x) & BN_MASK2; - mask = (0 - (mask >> (BN_BITS2 - 1))); - bits += 4 & mask; - l ^= (x ^ l) & mask; - - x = l >> 2; - mask = (0 - x) & BN_MASK2; - mask = (0 - (mask >> (BN_BITS2 - 1))); - bits += 2 & mask; - l ^= (x ^ l) & mask; - - x = l >> 1; - mask = (0 - x) & BN_MASK2; - mask = (0 - (mask >> (BN_BITS2 - 1))); - bits += 1 & mask; - - return bits; -} - -int BN_num_bits(const BIGNUM *a) -{ - int i = a->top - 1; - bn_check_top(a); - - if (BN_is_zero(a)) - return 0; - return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); -} - -void BN_clear_free(BIGNUM *a) -{ - int i; - - if (a == NULL) - return; - bn_check_top(a); - if (a->d != NULL) { - OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0])); - if (!(BN_get_flags(a, BN_FLG_STATIC_DATA))) - OPENSSL_free(a->d); - } - i = BN_get_flags(a, BN_FLG_MALLOCED); - OPENSSL_cleanse(a, sizeof(BIGNUM)); - if (i) - OPENSSL_free(a); -} - -void BN_free(BIGNUM *a) -{ - if (a == NULL) - return; - bn_check_top(a); - if ((a->d != NULL) && !(BN_get_flags(a, BN_FLG_STATIC_DATA))) - OPENSSL_free(a->d); - if (a->flags & BN_FLG_MALLOCED) - OPENSSL_free(a); - else { -#ifndef OPENSSL_NO_DEPRECATED - a->flags |= BN_FLG_FREE; -#endif - a->d = NULL; - } -} - -void BN_init(BIGNUM *a) -{ - memset(a, 0, sizeof(BIGNUM)); - bn_check_top(a); -} - -BIGNUM *BN_new(void) -{ - BIGNUM *ret; - - if ((ret = (BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL) { - BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - ret->flags = BN_FLG_MALLOCED; - ret->top = 0; - ret->neg = 0; - ret->dmax = 0; - ret->d = NULL; - bn_check_top(ret); - return (ret); -} - -/* This is used both by bn_expand2() and bn_dup_expand() */ -/* The caller MUST check that words > b->dmax before calling this */ -static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) -{ - BN_ULONG *A, *a = NULL; - const BN_ULONG *B; - int i; - - if (words > (INT_MAX / (4 * BN_BITS2))) { - BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG); - return NULL; - } - if (BN_get_flags(b, BN_FLG_STATIC_DATA)) { - BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); - return (NULL); - } - a = A = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words); - if (A == NULL) { - BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE); - return (NULL); - } -#ifdef PURIFY - /* - * Valgrind complains in BN_consttime_swap because we process the whole - * array even if it's not initialised yet. This doesn't matter in that - * function - what's important is constant time operation (we're not - * actually going to use the data) - */ - memset(a, 0, sizeof(BN_ULONG) * words); -#endif - -#if 1 - B = b->d; - /* Check if the previous number needs to be copied */ - if (B != NULL) { - for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { - /* - * The fact that the loop is unrolled - * 4-wise is a tribute to Intel. It's - * the one that doesn't have enough - * registers to accomodate more data. - * I'd unroll it 8-wise otherwise:-) - * - * - */ - BN_ULONG a0, a1, a2, a3; - a0 = B[0]; - a1 = B[1]; - a2 = B[2]; - a3 = B[3]; - A[0] = a0; - A[1] = a1; - A[2] = a2; - A[3] = a3; - } - /* - * workaround for ultrix cc: without 'case 0', the optimizer does - * the switch table by doing a=top&3; a--; goto jump_table[a]; - * which fails for top== 0 - */ - switch (b->top & 3) { - case 3: - A[2] = B[2]; - case 2: - A[1] = B[1]; - case 1: - A[0] = B[0]; - case 0: - ; - } - } -#else - memset(A, 0, sizeof(BN_ULONG) * words); - memcpy(A, b->d, sizeof(b->d[0]) * b->top); -#endif - - return (a); -} - -/* - * This is an internal function that can be used instead of bn_expand2() when - * there is a need to copy BIGNUMs instead of only expanding the data part, - * while still expanding them. Especially useful when needing to expand - * BIGNUMs that are declared 'const' and should therefore not be changed. The - * reason to use this instead of a BN_dup() followed by a bn_expand2() is - * memory allocation overhead. A BN_dup() followed by a bn_expand2() will - * allocate new memory for the BIGNUM data twice, and free it once, while - * bn_dup_expand() makes sure allocation is made only once. - */ - -#ifndef OPENSSL_NO_DEPRECATED -BIGNUM *bn_dup_expand(const BIGNUM *b, int words) -{ - BIGNUM *r = NULL; - - bn_check_top(b); - - /* - * This function does not work if words <= b->dmax && top < words because - * BN_dup() does not preserve 'dmax'! (But bn_dup_expand() is not used - * anywhere yet.) - */ - - if (words > b->dmax) { - BN_ULONG *a = bn_expand_internal(b, words); - - if (a) { - r = BN_new(); - if (r) { - r->top = b->top; - r->dmax = words; - r->neg = b->neg; - r->d = a; - } else { - /* r == NULL, BN_new failure */ - OPENSSL_free(a); - } - } - /* - * If a == NULL, there was an error in allocation in - * bn_expand_internal(), and NULL should be returned - */ - } else { - r = BN_dup(b); - } - - bn_check_top(r); - return r; -} -#endif - -/* - * This is an internal function that should not be used in applications. It - * ensures that 'b' has enough room for a 'words' word number and initialises - * any unused part of b->d with leading zeros. It is mostly used by the - * various BIGNUM routines. If there is an error, NULL is returned. If not, - * 'b' is returned. - */ - -BIGNUM *bn_expand2(BIGNUM *b, int words) -{ - if (words > b->dmax) { - BN_ULONG *a = bn_expand_internal(b, words); - if (!a) - return NULL; - if (b->d) - OPENSSL_free(b->d); - b->d = a; - b->dmax = words; - } - -/* None of this should be necessary because of what b->top means! */ -#if 0 - /* - * NB: bn_wexpand() calls this only if the BIGNUM really has to grow - */ - if (b->top < b->dmax) { - int i; - BN_ULONG *A = &(b->d[b->top]); - for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) { - A[0] = 0; - A[1] = 0; - A[2] = 0; - A[3] = 0; - A[4] = 0; - A[5] = 0; - A[6] = 0; - A[7] = 0; - } - for (i = (b->dmax - b->top) & 7; i > 0; i--, A++) - A[0] = 0; - assert(A == &(b->d[b->dmax])); - } -#endif - return b; -} - -BIGNUM *BN_dup(const BIGNUM *a) -{ - BIGNUM *t; - - if (a == NULL) - return NULL; - bn_check_top(a); - - t = BN_new(); - if (t == NULL) - return NULL; - if (!BN_copy(t, a)) { - BN_free(t); - return NULL; - } - bn_check_top(t); - return t; -} - -BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) -{ - int i; - BN_ULONG *A; - const BN_ULONG *B; - - bn_check_top(b); - - if (a == b) - return (a); - if (bn_wexpand(a, b->top) == NULL) - return (NULL); - -#if 1 - A = a->d; - B = b->d; - for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { - BN_ULONG a0, a1, a2, a3; - a0 = B[0]; - a1 = B[1]; - a2 = B[2]; - a3 = B[3]; - A[0] = a0; - A[1] = a1; - A[2] = a2; - A[3] = a3; - } - /* ultrix cc workaround, see comments in bn_expand_internal */ - switch (b->top & 3) { - case 3: - A[2] = B[2]; - case 2: - A[1] = B[1]; - case 1: - A[0] = B[0]; - case 0:; - } -#else - memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); -#endif - - a->neg = b->neg; - a->top = b->top; - a->flags |= b->flags & BN_FLG_FIXED_TOP; - bn_check_top(a); - return (a); -} - -#define FLAGS_DATA(flags) ((flags) & (BN_FLG_STATIC_DATA \ - | BN_FLG_CONSTTIME \ - | BN_FLG_FIXED_TOP)) -#define FLAGS_STRUCT(flags) ((flags) & (BN_FLG_MALLOCED)) - -void BN_swap(BIGNUM *a, BIGNUM *b) -{ - int flags_old_a, flags_old_b; - BN_ULONG *tmp_d; - int tmp_top, tmp_dmax, tmp_neg; - - bn_check_top(a); - bn_check_top(b); - - flags_old_a = a->flags; - flags_old_b = b->flags; - - tmp_d = a->d; - tmp_top = a->top; - tmp_dmax = a->dmax; - tmp_neg = a->neg; - - a->d = b->d; - a->top = b->top; - a->dmax = b->dmax; - a->neg = b->neg; - - b->d = tmp_d; - b->top = tmp_top; - b->dmax = tmp_dmax; - b->neg = tmp_neg; - - a->flags = FLAGS_STRUCT(flags_old_a) | FLAGS_DATA(flags_old_b); - b->flags = FLAGS_STRUCT(flags_old_b) | FLAGS_DATA(flags_old_a); - bn_check_top(a); - bn_check_top(b); -} - -void BN_clear(BIGNUM *a) -{ - bn_check_top(a); - if (a->d != NULL) - OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0])); - a->top = 0; - a->neg = 0; - a->flags &= ~BN_FLG_FIXED_TOP; -} - -BN_ULONG BN_get_word(const BIGNUM *a) -{ - if (a->top > 1) - return BN_MASK2; - else if (a->top == 1) - return a->d[0]; - /* a->top == 0 */ - return 0; -} - -int BN_set_word(BIGNUM *a, BN_ULONG w) -{ - bn_check_top(a); - if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL) - return (0); - a->neg = 0; - a->d[0] = w; - a->top = (w ? 1 : 0); - a->flags &= ~BN_FLG_FIXED_TOP; - bn_check_top(a); - return (1); -} - -BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) -{ - unsigned int i, m; - unsigned int n; - BN_ULONG l; - BIGNUM *bn = NULL; - - if (ret == NULL) - ret = bn = BN_new(); - if (ret == NULL) - return (NULL); - bn_check_top(ret); - l = 0; - n = len; - if (n == 0) { - ret->top = 0; - return (ret); - } - i = ((n - 1) / BN_BYTES) + 1; - m = ((n - 1) % (BN_BYTES)); - if (bn_wexpand(ret, (int)i) == NULL) { - if (bn) - BN_free(bn); - return NULL; - } - ret->top = i; - ret->neg = 0; - while (n--) { - l = (l << 8L) | *(s++); - if (m-- == 0) { - ret->d[--i] = l; - l = 0; - m = BN_BYTES - 1; - } - } - /* - * need to call this due to clear byte at top if avoiding having the top - * bit set (-ve number) - */ - bn_correct_top(ret); - return (ret); -} - -/* ignore negative */ -static int bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) -{ - int n; - size_t i, lasti, j, atop, mask; - BN_ULONG l; - - /* - * In case |a| is fixed-top, BN_num_bytes can return bogus length, - * but it's assumed that fixed-top inputs ought to be "nominated" - * even for padded output, so it works out... - */ - n = BN_num_bytes(a); - if (tolen == -1) { - tolen = n; - } else if (tolen < n) { /* uncommon/unlike case */ - BIGNUM temp = *a; - - bn_correct_top(&temp); - n = BN_num_bytes(&temp); - if (tolen < n) - return -1; - } - - /* Swipe through whole available data and don't give away padded zero. */ - atop = a->dmax * BN_BYTES; - if (atop == 0) { - OPENSSL_cleanse(to, tolen); - return tolen; - } - - lasti = atop - 1; - atop = a->top * BN_BYTES; - for (i = 0, j = 0, to += tolen; j < (size_t)tolen; j++) { - l = a->d[i / BN_BYTES]; - mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1)); - *--to = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask); - i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */ - } - - return tolen; -} - -int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) -{ - if (tolen < 0) - return -1; - return bn2binpad(a, to, tolen); -} - -int BN_bn2bin(const BIGNUM *a, unsigned char *to) -{ - int n, i; - BN_ULONG l; - - bn_check_top(a); - n = i = BN_num_bytes(a); - while (i--) { - l = a->d[i / BN_BYTES]; - *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; - } - return (n); -} - -int BN_ucmp(const BIGNUM *a, const BIGNUM *b) -{ - int i; - BN_ULONG t1, t2, *ap, *bp; - - bn_check_top(a); - bn_check_top(b); - - i = a->top - b->top; - if (i != 0) - return (i); - ap = a->d; - bp = b->d; - for (i = a->top - 1; i >= 0; i--) { - t1 = ap[i]; - t2 = bp[i]; - if (t1 != t2) - return ((t1 > t2) ? 1 : -1); - } - return (0); -} - -int BN_cmp(const BIGNUM *a, const BIGNUM *b) -{ - int i; - int gt, lt; - BN_ULONG t1, t2; - - if ((a == NULL) || (b == NULL)) { - if (a != NULL) - return (-1); - else if (b != NULL) - return (1); - else - return (0); - } - - bn_check_top(a); - bn_check_top(b); - - if (a->neg != b->neg) { - if (a->neg) - return (-1); - else - return (1); - } - if (a->neg == 0) { - gt = 1; - lt = -1; - } else { - gt = -1; - lt = 1; - } - - if (a->top > b->top) - return (gt); - if (a->top < b->top) - return (lt); - for (i = a->top - 1; i >= 0; i--) { - t1 = a->d[i]; - t2 = b->d[i]; - if (t1 > t2) - return (gt); - if (t1 < t2) - return (lt); - } - return (0); -} - -int BN_set_bit(BIGNUM *a, int n) -{ - int i, j, k; - - if (n < 0) - return 0; - - i = n / BN_BITS2; - j = n % BN_BITS2; - if (a->top <= i) { - if (bn_wexpand(a, i + 1) == NULL) - return (0); - for (k = a->top; k < i + 1; k++) - a->d[k] = 0; - a->top = i + 1; - a->flags &= ~BN_FLG_FIXED_TOP; - } - - a->d[i] |= (((BN_ULONG)1) << j); - bn_check_top(a); - return (1); -} - -int BN_clear_bit(BIGNUM *a, int n) -{ - int i, j; - - bn_check_top(a); - if (n < 0) - return 0; - - i = n / BN_BITS2; - j = n % BN_BITS2; - if (a->top <= i) - return (0); - - a->d[i] &= (~(((BN_ULONG)1) << j)); - bn_correct_top(a); - return (1); -} - -int BN_is_bit_set(const BIGNUM *a, int n) -{ - int i, j; - - bn_check_top(a); - if (n < 0) - return 0; - i = n / BN_BITS2; - j = n % BN_BITS2; - if (a->top <= i) - return 0; - return (int)(((a->d[i]) >> j) & ((BN_ULONG)1)); -} - -int BN_mask_bits(BIGNUM *a, int n) -{ - int b, w; - - bn_check_top(a); - if (n < 0) - return 0; - - w = n / BN_BITS2; - b = n % BN_BITS2; - if (w >= a->top) - return 0; - if (b == 0) - a->top = w; - else { - a->top = w + 1; - a->d[w] &= ~(BN_MASK2 << b); - } - bn_correct_top(a); - return (1); -} - -void BN_set_negative(BIGNUM *a, int b) -{ - if (b && !BN_is_zero(a)) - a->neg = 1; - else - a->neg = 0; -} - -int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) -{ - int i; - BN_ULONG aa, bb; - - aa = a[n - 1]; - bb = b[n - 1]; - if (aa != bb) - return ((aa > bb) ? 1 : -1); - for (i = n - 2; i >= 0; i--) { - aa = a[i]; - bb = b[i]; - if (aa != bb) - return ((aa > bb) ? 1 : -1); - } - return (0); -} - -/* - * Here follows a specialised variants of bn_cmp_words(). It has the - * property of performing the operation on arrays of different sizes. The - * sizes of those arrays is expressed through cl, which is the common length - * ( basicall, min(len(a),len(b)) ), and dl, which is the delta between the - * two lengths, calculated as len(a)-len(b). All lengths are the number of - * BN_ULONGs... - */ - -int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl) -{ - int n, i; - n = cl - 1; - - if (dl < 0) { - for (i = dl; i < 0; i++) { - if (b[n - i] != 0) - return -1; /* a < b */ - } - } - if (dl > 0) { - for (i = dl; i > 0; i--) { - if (a[n + i] != 0) - return 1; /* a > b */ - } - } - return bn_cmp_words(a, b, cl); -} - -/* - * Constant-time conditional swap of a and b. - * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. - * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, - * and that no more than nwords are used by either a or b. - * a and b cannot be the same number - */ -void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) -{ - BN_ULONG t; - int i; - - bn_wcheck_size(a, nwords); - bn_wcheck_size(b, nwords); - - assert(a != b); - assert((condition & (condition - 1)) == 0); - assert(sizeof(BN_ULONG) >= sizeof(int)); - - condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; - - t = (a->top ^ b->top) & condition; - a->top ^= t; - b->top ^= t; - - t = (a->neg ^ b->neg) & condition; - a->neg ^= t; - b->neg ^= t; - - /*- - * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention - * is actually to treat it as it's read-only data, and some (if not most) - * of it does reside in read-only segment. In other words observation of - * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal - * condition. It would either cause SEGV or effectively cause data - * corruption. - * - * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be - * preserved. - * - * BN_FLG_SECURE: must be preserved, because it determines how x->d was - * allocated and hence how to free it. - * - * BN_FLG_CONSTTIME: sufficient to mask and swap - * - * BN_FLG_FIXED_TOP: indicates that we haven't called bn_correct_top() on - * the data, so the d array may be padded with additional 0 values (i.e. - * top could be greater than the minimal value that it could be). We should - * be swapping it - */ - -#define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP) - - t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition; - a->flags ^= t; - b->flags ^= t; - -#define BN_CONSTTIME_SWAP(ind) \ - do { \ - t = (a->d[ind] ^ b->d[ind]) & condition; \ - a->d[ind] ^= t; \ - b->d[ind] ^= t; \ - } while (0) - - switch (nwords) { - default: - for (i = 10; i < nwords; i++) - BN_CONSTTIME_SWAP(i); - /* Fallthrough */ - case 10: - BN_CONSTTIME_SWAP(9); /* Fallthrough */ - case 9: - BN_CONSTTIME_SWAP(8); /* Fallthrough */ - case 8: - BN_CONSTTIME_SWAP(7); /* Fallthrough */ - case 7: - BN_CONSTTIME_SWAP(6); /* Fallthrough */ - case 6: - BN_CONSTTIME_SWAP(5); /* Fallthrough */ - case 5: - BN_CONSTTIME_SWAP(4); /* Fallthrough */ - case 4: - BN_CONSTTIME_SWAP(3); /* Fallthrough */ - case 3: - BN_CONSTTIME_SWAP(2); /* Fallthrough */ - case 2: - BN_CONSTTIME_SWAP(1); /* Fallthrough */ - case 1: - BN_CONSTTIME_SWAP(0); - } -#undef BN_CONSTTIME_SWAP -} -/* crypto/bn/bn_mod.c */ -/* - * Includes code written by Lenka Fibikova - * for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "cryptlib.h" -// #include "bn_lcl.h" - -#if 0 /* now just a #define */ -int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) -{ - return (BN_div(NULL, rem, m, d, ctx)); - /* note that rem->neg == m->neg (unless the remainder is zero) */ -} -#endif - -int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) -{ - /* - * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d| - * always holds) - */ - - if (!(BN_mod(r, m, d, ctx))) - return 0; - if (!r->neg) - return 1; - /* now -|d| < r < 0, so we have to set r := r + |d| */ - return (d->neg ? BN_sub : BN_add) (r, r, d); -} - -int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, - BN_CTX *ctx) -{ - if (!BN_add(r, a, b)) - return 0; - return BN_nnmod(r, r, m, ctx); -} - -/* - * BN_mod_add variant that may be used if both a and b are non-negative and - * less than m. The original algorithm was - * - * if (!BN_uadd(r, a, b)) - * return 0; - * if (BN_ucmp(r, m) >= 0) - * return BN_usub(r, r, m); - * - * which is replaced with addition, subtracting modulus, and conditional - * move depending on whether or not subtraction borrowed. - */ -int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *m) -{ - size_t i, ai, bi, mtop = m->top; - BN_ULONG storage[1024 / BN_BITS2]; - BN_ULONG carry, temp, mask, *rp, *tp = storage; - const BN_ULONG *ap, *bp; - - if (bn_wexpand(r, m->top) == NULL) - return 0; - - if (mtop > sizeof(storage) / sizeof(storage[0]) - && (tp = OPENSSL_malloc(mtop * sizeof(BN_ULONG))) == NULL) - return 0; - - ap = a->d != NULL ? a->d : tp; - bp = b->d != NULL ? b->d : tp; - - for (i = 0, ai = 0, bi = 0, carry = 0; i < mtop;) { - mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); - temp = ((ap[ai] & mask) + carry) & BN_MASK2; - carry = (temp < carry); - - mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); - tp[i] = ((bp[bi] & mask) + temp) & BN_MASK2; - carry += (tp[i] < temp); - - i++; - ai += (i - a->dmax) >> (8 * sizeof(i) - 1); - bi += (i - b->dmax) >> (8 * sizeof(i) - 1); - } - rp = r->d; - carry -= bn_sub_words(rp, tp, m->d, mtop); - for (i = 0; i < mtop; i++) { - rp[i] = (carry & tp[i]) | (~carry & rp[i]); - ((volatile BN_ULONG *)tp)[i] = 0; - } - r->top = mtop; - r->flags |= BN_FLG_FIXED_TOP; - r->neg = 0; - - if (tp != storage) - OPENSSL_free(tp); - - return 1; -} - -int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *m) -{ - int ret = bn_mod_add_fixed_top(r, a, b, m); - - if (ret) - bn_correct_top(r); - - return ret; -} - -int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, - BN_CTX *ctx) -{ - if (!BN_sub(r, a, b)) - return 0; - return BN_nnmod(r, r, m, ctx); -} - -/* - * BN_mod_sub variant that may be used if both a and b are non-negative, - * a is less than m, while b is of same bit width as m. It's implemented - * as subtraction followed by two conditional additions. - * - * 0 <= a < m - * 0 <= b < 2^w < 2*m - * - * after subtraction - * - * -2*m < r = a - b < m - * - * Thus it takes up to two conditional additions to make |r| positive. - */ -int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *m) -{ - size_t i, ai, bi, mtop = m->top; - BN_ULONG borrow, carry, ta, tb, mask, *rp; - const BN_ULONG *ap, *bp; - - if (bn_wexpand(r, m->top) == NULL) - return 0; - - rp = r->d; - ap = a->d != NULL ? a->d : rp; - bp = b->d != NULL ? b->d : rp; - - for (i = 0, ai = 0, bi = 0, borrow = 0; i < mtop;) { - mask = (BN_ULONG)0 - ((i - a->top) >> (8 * sizeof(i) - 1)); - ta = ap[ai] & mask; - - mask = (BN_ULONG)0 - ((i - b->top) >> (8 * sizeof(i) - 1)); - tb = bp[bi] & mask; - rp[i] = ta - tb - borrow; - if (ta != tb) - borrow = (ta < tb); - - i++; - ai += (i - a->dmax) >> (8 * sizeof(i) - 1); - bi += (i - b->dmax) >> (8 * sizeof(i) - 1); - } - ap = m->d; - for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { - ta = ((ap[i] & mask) + carry) & BN_MASK2; - carry = (ta < carry); - rp[i] = (rp[i] + ta) & BN_MASK2; - carry += (rp[i] < ta); - } - borrow -= carry; - for (i = 0, mask = 0 - borrow, carry = 0; i < mtop; i++) { - ta = ((ap[i] & mask) + carry) & BN_MASK2; - carry = (ta < carry); - rp[i] = (rp[i] + ta) & BN_MASK2; - carry += (rp[i] < ta); - } - - r->top = mtop; - r->flags |= BN_FLG_FIXED_TOP; - r->neg = 0; - - return 1; -} - -/* - * BN_mod_sub variant that may be used if both a and b are non-negative and - * less than m - */ -int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *m) -{ - if (!BN_sub(r, a, b)) - return 0; - if (r->neg) - return BN_add(r, r, m); - return 1; -} - -/* slow but works */ -int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, - BN_CTX *ctx) -{ - BIGNUM *t; - int ret = 0; - - bn_check_top(a); - bn_check_top(b); - bn_check_top(m); - - BN_CTX_start(ctx); - if ((t = BN_CTX_get(ctx)) == NULL) - goto err; - if (a == b) { - if (!BN_sqr(t, a, ctx)) - goto err; - } else { - if (!BN_mul(t, a, b, ctx)) - goto err; - } - if (!BN_nnmod(r, t, m, ctx)) - goto err; - bn_check_top(r); - ret = 1; - err: - BN_CTX_end(ctx); - return (ret); -} - -int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) -{ - if (!BN_sqr(r, a, ctx)) - return 0; - /* r->neg == 0, thus we don't need BN_nnmod */ - return BN_mod(r, r, m, ctx); -} - -int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) -{ - if (!BN_lshift1(r, a)) - return 0; - bn_check_top(r); - return BN_nnmod(r, r, m, ctx); -} - -/* - * BN_mod_lshift1 variant that may be used if a is non-negative and less than - * m - */ -int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) -{ - if (!BN_lshift1(r, a)) - return 0; - bn_check_top(r); - if (BN_cmp(r, m) >= 0) - return BN_sub(r, r, m); - return 1; -} - -int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, - BN_CTX *ctx) -{ - BIGNUM *abs_m = NULL; - int ret; - - if (!BN_nnmod(r, a, m, ctx)) - return 0; - - if (m->neg) { - abs_m = BN_dup(m); - if (abs_m == NULL) - return 0; - abs_m->neg = 0; - } - - ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m)); - bn_check_top(r); - - if (abs_m) - BN_free(abs_m); - return ret; -} - -/* - * BN_mod_lshift variant that may be used if a is non-negative and less than - * m - */ -int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) -{ - if (r != a) { - if (BN_copy(r, a) == NULL) - return 0; - } - - while (n > 0) { - int max_shift; - - /* 0 < r < m */ - max_shift = BN_num_bits(m) - BN_num_bits(r); - /* max_shift >= 0 */ - - if (max_shift < 0) { - BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED); - return 0; - } - - if (max_shift > n) - max_shift = n; - - if (max_shift) { - if (!BN_lshift(r, r, max_shift)) - return 0; - n -= max_shift; - } else { - if (!BN_lshift1(r, r)) - return 0; - --n; - } - - /* BN_num_bits(r) <= BN_num_bits(m) */ - - if (BN_cmp(r, m) >= 0) { - if (!BN_sub(r, r, m)) - return 0; - } - } - bn_check_top(r); - - return 1; -} -/* crypto/bn/bn_mont.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * Details about Montgomery multiplication algorithms can be found at - * http://security.ece.orst.edu/publications.html, e.g. - * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and - * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf - */ - -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -#define MONT_WORD /* use the faster word-based algorithm */ - -#ifdef MONT_WORD -static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); -#endif - -int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - BN_MONT_CTX *mont, BN_CTX *ctx) -{ - int ret = bn_mul_mont_fixed_top(r, a, b, mont, ctx); - - bn_correct_top(r); - bn_check_top(r); - - return ret; -} - -int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - BN_MONT_CTX *mont, BN_CTX *ctx) -{ - BIGNUM *tmp; - int ret = 0; -#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) - int num = mont->N.top; - - if (num > 1 && a->top == num && b->top == num) { - if (bn_wexpand(r, num) == NULL) - return (0); - if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { - r->neg = a->neg ^ b->neg; - r->top = num; - r->flags |= BN_FLG_FIXED_TOP; - return 1; - } - } -#endif - - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - if (tmp == NULL) - goto err; - - bn_check_top(tmp); - if (a == b) { - if (!bn_sqr_fixed_top(tmp, a, ctx)) - goto err; - } else { - if (!bn_mul_fixed_top(tmp, a, b, ctx)) - goto err; - } - /* reduce from aRR to aR */ -#ifdef MONT_WORD - if (!bn_from_montgomery_word(r, tmp, mont)) - goto err; -#else - if (!BN_from_montgomery(r, tmp, mont, ctx)) - goto err; -#endif - ret = 1; - err: - BN_CTX_end(ctx); - return (ret); -} - -#ifdef MONT_WORD -static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) -{ - BIGNUM *n; - BN_ULONG *ap, *np, *rp, n0, v, carry; - int nl, max, i; - unsigned int rtop; - - n = &(mont->N); - nl = n->top; - if (nl == 0) { - ret->top = 0; - return (1); - } - - max = (2 * nl); /* carry is stored separately */ - if (bn_wexpand(r, max) == NULL) - return (0); - - r->neg ^= n->neg; - np = n->d; - rp = r->d; - - /* clear the top words of T */ - for (rtop = r->top, i = 0; i < max; i++) { - v = (BN_ULONG)0 - ((i - rtop) >> (8 * sizeof(rtop) - 1)); - rp[i] &= v; - } - - r->top = max; - r->flags |= BN_FLG_FIXED_TOP; - n0 = mont->n0[0]; - - /* - * Add multiples of |n| to |r| until R = 2^(nl * BN_BITS2) divides it. On - * input, we had |r| < |n| * R, so now |r| < 2 * |n| * R. Note that |r| - * includes |carry| which is stored separately. - */ - for (carry = 0, i = 0; i < nl; i++, rp++) { - v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2); - v = (v + carry + rp[nl]) & BN_MASK2; - carry |= (v != rp[nl]); - carry &= (v <= rp[nl]); - rp[nl] = v; - } - - if (bn_wexpand(ret, nl) == NULL) - return (0); - ret->top = nl; - ret->flags |= BN_FLG_FIXED_TOP; - ret->neg = r->neg; - - rp = ret->d; - - /* - * Shift |nl| words to divide by R. We have |ap| < 2 * |n|. Note that |ap| - * includes |carry| which is stored separately. - */ - ap = &(r->d[nl]); - - carry -= bn_sub_words(rp, ap, np, nl); - /* - * |carry| is -1 if |ap| - |np| underflowed or zero if it did not. Note - * |carry| cannot be 1. That would imply the subtraction did not fit in - * |nl| words, and we know at most one subtraction is needed. - */ - for (i = 0; i < nl; i++) { - rp[i] = (carry & ap[i]) | (~carry & rp[i]); - ap[i] = 0; - } - - return (1); -} -#endif /* MONT_WORD */ - -int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, - BN_CTX *ctx) -{ - int retn; - - retn = bn_from_mont_fixed_top(ret, a, mont, ctx); - bn_correct_top(ret); - bn_check_top(ret); - - return retn; -} - -int bn_from_mont_fixed_top(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, - BN_CTX *ctx) -{ - int retn = 0; -#ifdef MONT_WORD - BIGNUM *t; - - BN_CTX_start(ctx); - if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) { - retn = bn_from_montgomery_word(ret, t, mont); - } - BN_CTX_end(ctx); -#else /* !MONT_WORD */ - BIGNUM *t1, *t2; - - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - t2 = BN_CTX_get(ctx); - if (t1 == NULL || t2 == NULL) - goto err; - - if (!BN_copy(t1, a)) - goto err; - BN_mask_bits(t1, mont->ri); - - if (!BN_mul(t2, t1, &mont->Ni, ctx)) - goto err; - BN_mask_bits(t2, mont->ri); - - if (!BN_mul(t1, t2, &mont->N, ctx)) - goto err; - if (!BN_add(t2, a, t1)) - goto err; - if (!BN_rshift(ret, t2, mont->ri)) - goto err; - - if (BN_ucmp(ret, &(mont->N)) >= 0) { - if (!BN_usub(ret, ret, &(mont->N))) - goto err; - } - retn = 1; - bn_check_top(ret); - err: - BN_CTX_end(ctx); -#endif /* MONT_WORD */ - return (retn); -} - -int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, - BN_CTX *ctx) -{ - return bn_mul_mont_fixed_top(r, a, &(mont->RR), mont, ctx); -} - -BN_MONT_CTX *BN_MONT_CTX_new(void) -{ - BN_MONT_CTX *ret; - - if ((ret = (BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL) - return (NULL); - - BN_MONT_CTX_init(ret); - ret->flags = BN_FLG_MALLOCED; - return (ret); -} - -void BN_MONT_CTX_init(BN_MONT_CTX *ctx) -{ - ctx->ri = 0; - BN_init(&(ctx->RR)); - BN_init(&(ctx->N)); - BN_init(&(ctx->Ni)); - ctx->n0[0] = ctx->n0[1] = 0; - ctx->flags = 0; -} - -void BN_MONT_CTX_free(BN_MONT_CTX *mont) -{ - if (mont == NULL) - return; - - BN_clear_free(&(mont->RR)); - BN_clear_free(&(mont->N)); - BN_clear_free(&(mont->Ni)); - if (mont->flags & BN_FLG_MALLOCED) - OPENSSL_free(mont); -} - -int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) -{ - int i, ret = 0; - BIGNUM *Ri, *R; - - if (BN_is_zero(mod)) - return 0; - - BN_CTX_start(ctx); - if ((Ri = BN_CTX_get(ctx)) == NULL) - goto err; - R = &(mont->RR); /* grab RR as a temp */ - if (!BN_copy(&(mont->N), mod)) - goto err; /* Set N */ - if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) - BN_set_flags(&(mont->N), BN_FLG_CONSTTIME); - mont->N.neg = 0; - -#ifdef MONT_WORD - { - BIGNUM tmod; - BN_ULONG buf[2]; - - BN_init(&tmod); - tmod.d = buf; - tmod.dmax = 2; - tmod.neg = 0; - - if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) - BN_set_flags(&tmod, BN_FLG_CONSTTIME); - - mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; - -# if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) - /* - * Only certain BN_BITS2<=32 platforms actually make use of n0[1], - * and we could use the #else case (with a shorter R value) for the - * others. However, currently only the assembler files do know which - * is which. - */ - - BN_zero(R); - if (!(BN_set_bit(R, 2 * BN_BITS2))) - goto err; - - tmod.top = 0; - if ((buf[0] = mod->d[0])) - tmod.top = 1; - if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) - tmod.top = 2; - - if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) - goto err; - if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) - goto err; /* R*Ri */ - if (!BN_is_zero(Ri)) { - if (!BN_sub_word(Ri, 1)) - goto err; - } else { /* if N mod word size == 1 */ - - if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) - goto err; - /* Ri-- (mod double word size) */ - Ri->neg = 0; - Ri->d[0] = BN_MASK2; - Ri->d[1] = BN_MASK2; - Ri->top = 2; - } - if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) - goto err; - /* - * Ni = (R*Ri-1)/N, keep only couple of least significant words: - */ - mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; - mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; -# else - BN_zero(R); - if (!(BN_set_bit(R, BN_BITS2))) - goto err; /* R */ - - buf[0] = mod->d[0]; /* tmod = N mod word size */ - buf[1] = 0; - tmod.top = buf[0] != 0 ? 1 : 0; - /* Ri = R^-1 mod N */ - if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) - goto err; - if (!BN_lshift(Ri, Ri, BN_BITS2)) - goto err; /* R*Ri */ - if (!BN_is_zero(Ri)) { - if (!BN_sub_word(Ri, 1)) - goto err; - } else { /* if N mod word size == 1 */ - - if (!BN_set_word(Ri, BN_MASK2)) - goto err; /* Ri-- (mod word size) */ - } - if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) - goto err; - /* - * Ni = (R*Ri-1)/N, keep only least significant word: - */ - mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; - mont->n0[1] = 0; -# endif - } -#else /* !MONT_WORD */ - { /* bignum version */ - mont->ri = BN_num_bits(&mont->N); - BN_zero(R); - if (!BN_set_bit(R, mont->ri)) - goto err; /* R = 2^ri */ - /* Ri = R^-1 mod N */ - if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL) - goto err; - if (!BN_lshift(Ri, Ri, mont->ri)) - goto err; /* R*Ri */ - if (!BN_sub_word(Ri, 1)) - goto err; - /* - * Ni = (R*Ri-1) / N - */ - if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx)) - goto err; - } -#endif - - /* setup RR for conversions */ - BN_zero(&(mont->RR)); - if (!BN_set_bit(&(mont->RR), mont->ri * 2)) - goto err; - if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) - goto err; - - for (i = mont->RR.top, ret = mont->N.top; i < ret; i++) - mont->RR.d[i] = 0; - mont->RR.top = ret; - mont->RR.flags |= BN_FLG_FIXED_TOP; - - ret = 1; - err: - BN_CTX_end(ctx); - return ret; -} - -BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) -{ - if (to == from) - return (to); - - if (!BN_copy(&(to->RR), &(from->RR))) - return NULL; - if (!BN_copy(&(to->N), &(from->N))) - return NULL; - if (!BN_copy(&(to->Ni), &(from->Ni))) - return NULL; - to->ri = from->ri; - to->n0[0] = from->n0[0]; - to->n0[1] = from->n0[1]; - return (to); -} - -BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, - const BIGNUM *mod, BN_CTX *ctx) -{ - BN_MONT_CTX *ret; - - CRYPTO_r_lock(lock); - ret = *pmont; - CRYPTO_r_unlock(lock); - if (ret) - return ret; - - /* - * We don't want to serialise globally while doing our lazy-init math in - * BN_MONT_CTX_set. That punishes threads that are doing independent - * things. Instead, punish the case where more than one thread tries to - * lazy-init the same 'pmont', by having each do the lazy-init math work - * independently and only use the one from the thread that wins the race - * (the losers throw away the work they've done). - */ - ret = BN_MONT_CTX_new(); - if (!ret) - return NULL; - if (!BN_MONT_CTX_set(ret, mod, ctx)) { - BN_MONT_CTX_free(ret); - return NULL; - } - - /* The locked compare-and-set, after the local work is done. */ - CRYPTO_w_lock(lock); - if (*pmont) { - BN_MONT_CTX_free(ret); - ret = *pmont; - } else - *pmont = ret; - CRYPTO_w_unlock(lock); - return ret; -} -/* crypto/bn/bn_mpi.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -int BN_bn2mpi(const BIGNUM *a, unsigned char *d) -{ - int bits; - int num = 0; - int ext = 0; - long l; - - bits = BN_num_bits(a); - num = (bits + 7) / 8; - if (bits > 0) { - ext = ((bits & 0x07) == 0); - } - if (d == NULL) - return (num + 4 + ext); - - l = num + ext; - d[0] = (unsigned char)(l >> 24) & 0xff; - d[1] = (unsigned char)(l >> 16) & 0xff; - d[2] = (unsigned char)(l >> 8) & 0xff; - d[3] = (unsigned char)(l) & 0xff; - if (ext) - d[4] = 0; - num = BN_bn2bin(a, &(d[4 + ext])); - if (a->neg) - d[4] |= 0x80; - return (num + 4 + ext); -} - -BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a) -{ - long len; - int neg = 0; - - if (n < 4) { - BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH); - return (NULL); - } - len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int) - d[3]; - if ((len + 4) != n) { - BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR); - return (NULL); - } - - if (a == NULL) - a = BN_new(); - if (a == NULL) - return (NULL); - - if (len == 0) { - a->neg = 0; - a->top = 0; - return (a); - } - d += 4; - if ((*d) & 0x80) - neg = 1; - if (BN_bin2bn(d, (int)len, a) == NULL) - return (NULL); - a->neg = neg; - if (neg) { - BN_clear_bit(a, BN_num_bits(a) - 1); - } - bn_check_top(a); - return (a); -} -/* crypto/bn/bn_mul.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef BN_DEBUG -# undef NDEBUG /* avoid conflicting definitions */ -# define NDEBUG -#endif - -#include -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS) -/* - * Here follows specialised variants of bn_add_words() and bn_sub_words(). - * They have the property performing operations on arrays of different sizes. - * The sizes of those arrays is expressed through cl, which is the common - * length ( basicall, min(len(a),len(b)) ), and dl, which is the delta - * between the two lengths, calculated as len(a)-len(b). All lengths are the - * number of BN_ULONGs... For the operations that require a result array as - * parameter, it must have the length cl+abs(dl). These functions should - * probably end up in bn_asm.c as soon as there are assembler counterparts - * for the systems that use assembler files. - */ - -BN_ULONG bn_sub_part_words(BN_ULONG *r, - const BN_ULONG *a, const BN_ULONG *b, - int cl, int dl) -{ - BN_ULONG c, t; - - assert(cl >= 0); - c = bn_sub_words(r, a, b, cl); - - if (dl == 0) - return c; - - r += cl; - a += cl; - b += cl; - - if (dl < 0) { -# ifdef BN_COUNT - fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, - dl, c); -# endif - for (;;) { - t = b[0]; - r[0] = (0 - t - c) & BN_MASK2; - if (t != 0) - c = 1; - if (++dl >= 0) - break; - - t = b[1]; - r[1] = (0 - t - c) & BN_MASK2; - if (t != 0) - c = 1; - if (++dl >= 0) - break; - - t = b[2]; - r[2] = (0 - t - c) & BN_MASK2; - if (t != 0) - c = 1; - if (++dl >= 0) - break; - - t = b[3]; - r[3] = (0 - t - c) & BN_MASK2; - if (t != 0) - c = 1; - if (++dl >= 0) - break; - - b += 4; - r += 4; - } - } else { - int save_dl = dl; -# ifdef BN_COUNT - fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, - dl, c); -# endif - while (c) { - t = a[0]; - r[0] = (t - c) & BN_MASK2; - if (t != 0) - c = 0; - if (--dl <= 0) - break; - - t = a[1]; - r[1] = (t - c) & BN_MASK2; - if (t != 0) - c = 0; - if (--dl <= 0) - break; - - t = a[2]; - r[2] = (t - c) & BN_MASK2; - if (t != 0) - c = 0; - if (--dl <= 0) - break; - - t = a[3]; - r[3] = (t - c) & BN_MASK2; - if (t != 0) - c = 0; - if (--dl <= 0) - break; - - save_dl = dl; - a += 4; - r += 4; - } - if (dl > 0) { -# ifdef BN_COUNT - fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c == 0)\n", - cl, dl); -# endif - if (save_dl > dl) { - switch (save_dl - dl) { - case 1: - r[1] = a[1]; - if (--dl <= 0) - break; - case 2: - r[2] = a[2]; - if (--dl <= 0) - break; - case 3: - r[3] = a[3]; - if (--dl <= 0) - break; - } - a += 4; - r += 4; - } - } - if (dl > 0) { -# ifdef BN_COUNT - fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, copy)\n", - cl, dl); -# endif - for (;;) { - r[0] = a[0]; - if (--dl <= 0) - break; - r[1] = a[1]; - if (--dl <= 0) - break; - r[2] = a[2]; - if (--dl <= 0) - break; - r[3] = a[3]; - if (--dl <= 0) - break; - - a += 4; - r += 4; - } - } - } - return c; -} -#endif - -BN_ULONG bn_add_part_words(BN_ULONG *r, - const BN_ULONG *a, const BN_ULONG *b, - int cl, int dl) -{ - BN_ULONG c, l, t; - - assert(cl >= 0); - c = bn_add_words(r, a, b, cl); - - if (dl == 0) - return c; - - r += cl; - a += cl; - b += cl; - - if (dl < 0) { - int save_dl = dl; -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, - dl, c); -#endif - while (c) { - l = (c + b[0]) & BN_MASK2; - c = (l < c); - r[0] = l; - if (++dl >= 0) - break; - - l = (c + b[1]) & BN_MASK2; - c = (l < c); - r[1] = l; - if (++dl >= 0) - break; - - l = (c + b[2]) & BN_MASK2; - c = (l < c); - r[2] = l; - if (++dl >= 0) - break; - - l = (c + b[3]) & BN_MASK2; - c = (l < c); - r[3] = l; - if (++dl >= 0) - break; - - save_dl = dl; - b += 4; - r += 4; - } - if (dl < 0) { -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c == 0)\n", - cl, dl); -#endif - if (save_dl < dl) { - switch (dl - save_dl) { - case 1: - r[1] = b[1]; - if (++dl >= 0) - break; - case 2: - r[2] = b[2]; - if (++dl >= 0) - break; - case 3: - r[3] = b[3]; - if (++dl >= 0) - break; - } - b += 4; - r += 4; - } - } - if (dl < 0) { -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, copy)\n", - cl, dl); -#endif - for (;;) { - r[0] = b[0]; - if (++dl >= 0) - break; - r[1] = b[1]; - if (++dl >= 0) - break; - r[2] = b[2]; - if (++dl >= 0) - break; - r[3] = b[3]; - if (++dl >= 0) - break; - - b += 4; - r += 4; - } - } - } else { - int save_dl = dl; -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl > 0)\n", cl, dl); -#endif - while (c) { - t = (a[0] + c) & BN_MASK2; - c = (t < c); - r[0] = t; - if (--dl <= 0) - break; - - t = (a[1] + c) & BN_MASK2; - c = (t < c); - r[1] = t; - if (--dl <= 0) - break; - - t = (a[2] + c) & BN_MASK2; - c = (t < c); - r[2] = t; - if (--dl <= 0) - break; - - t = (a[3] + c) & BN_MASK2; - c = (t < c); - r[3] = t; - if (--dl <= 0) - break; - - save_dl = dl; - a += 4; - r += 4; - } -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, - dl); -#endif - if (dl > 0) { - if (save_dl > dl) { - switch (save_dl - dl) { - case 1: - r[1] = a[1]; - if (--dl <= 0) - break; - case 2: - r[2] = a[2]; - if (--dl <= 0) - break; - case 3: - r[3] = a[3]; - if (--dl <= 0) - break; - } - a += 4; - r += 4; - } - } - if (dl > 0) { -#ifdef BN_COUNT - fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, copy)\n", - cl, dl); -#endif - for (;;) { - r[0] = a[0]; - if (--dl <= 0) - break; - r[1] = a[1]; - if (--dl <= 0) - break; - r[2] = a[2]; - if (--dl <= 0) - break; - r[3] = a[3]; - if (--dl <= 0) - break; - - a += 4; - r += 4; - } - } - } - return c; -} - -#ifdef BN_RECURSION -/* - * Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of - * Computer Programming, Vol. 2) - */ - -/*- - * r is 2*n2 words in size, - * a and b are both n2 words in size. - * n2 must be a power of 2. - * We multiply and return the result. - * t must be 2*n2 words in size - * We calculate - * a[0]*b[0] - * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) - * a[1]*b[1] - */ -/* dnX may not be positive, but n2/2+dnX has to be */ -void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, - int dna, int dnb, BN_ULONG *t) -{ - int n = n2 / 2, c1, c2; - int tna = n + dna, tnb = n + dnb; - unsigned int neg, zero; - BN_ULONG ln, lo, *p; - -# ifdef BN_COUNT - fprintf(stderr, " bn_mul_recursive %d%+d * %d%+d\n", n2, dna, n2, dnb); -# endif -# ifdef BN_MUL_COMBA -# if 0 - if (n2 == 4) { - bn_mul_comba4(r, a, b); - return; - } -# endif - /* - * Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete - * [steve] - */ - if (n2 == 8 && dna == 0 && dnb == 0) { - bn_mul_comba8(r, a, b); - return; - } -# endif /* BN_MUL_COMBA */ - /* Else do normal multiply */ - if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) { - bn_mul_normal(r, a, n2 + dna, b, n2 + dnb); - if ((dna + dnb) < 0) - memset(&r[2 * n2 + dna + dnb], 0, - sizeof(BN_ULONG) * -(dna + dnb)); - return; - } - /* r=(a[0]-a[1])*(b[1]-b[0]) */ - c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna); - c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n); - zero = neg = 0; - switch (c1 * 3 + c2) { - case -4: - bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ - bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ - break; - case -3: - zero = 1; - break; - case -2: - bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ - bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */ - neg = 1; - break; - case -1: - case 0: - case 1: - zero = 1; - break; - case 2: - bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */ - bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ - neg = 1; - break; - case 3: - zero = 1; - break; - case 4: - bn_sub_part_words(t, a, &(a[n]), tna, n - tna); - bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); - break; - } - -# ifdef BN_MUL_COMBA - if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take - * extra args to do this well */ - if (!zero) - bn_mul_comba4(&(t[n2]), t, &(t[n])); - else - memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG)); - - bn_mul_comba4(r, a, b); - bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n])); - } else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could - * take extra args to do - * this well */ - if (!zero) - bn_mul_comba8(&(t[n2]), t, &(t[n])); - else - memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG)); - - bn_mul_comba8(r, a, b); - bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n])); - } else -# endif /* BN_MUL_COMBA */ - { - p = &(t[n2 * 2]); - if (!zero) - bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p); - else - memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG)); - bn_mul_recursive(r, a, b, n, 0, 0, p); - bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p); - } - - /*- - * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - */ - - c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); - - if (neg) { /* if t[32] is negative */ - c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); - } else { - /* Might have a carry */ - c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2)); - } - - /*- - * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - * c1 holds the carry bits - */ - c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); - if (c1) { - p = &(r[n + n2]); - lo = *p; - ln = (lo + c1) & BN_MASK2; - *p = ln; - - /* - * The overflow will stop before we over write words we should not - * overwrite - */ - if (ln < (BN_ULONG)c1) { - do { - p++; - lo = *p; - ln = (lo + 1) & BN_MASK2; - *p = ln; - } while (ln == 0); - } - } -} - -/* - * n+tn is the word length t needs to be n*4 is size, as does r - */ -/* tnX may not be negative but less than n */ -void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, - int tna, int tnb, BN_ULONG *t) -{ - int i, j, n2 = n * 2; - int c1, c2, neg; - BN_ULONG ln, lo, *p; - -# ifdef BN_COUNT - fprintf(stderr, " bn_mul_part_recursive (%d%+d) * (%d%+d)\n", - n, tna, n, tnb); -# endif - if (n < 8) { - bn_mul_normal(r, a, n + tna, b, n + tnb); - return; - } - - /* r=(a[0]-a[1])*(b[1]-b[0]) */ - c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna); - c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n); - neg = 0; - switch (c1 * 3 + c2) { - case -4: - bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ - bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ - break; - case -3: - /* break; */ - case -2: - bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ - bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */ - neg = 1; - break; - case -1: - case 0: - case 1: - /* break; */ - case 2: - bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */ - bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ - neg = 1; - break; - case 3: - /* break; */ - case 4: - bn_sub_part_words(t, a, &(a[n]), tna, n - tna); - bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); - break; - } - /* - * The zero case isn't yet implemented here. The speedup would probably - * be negligible. - */ -# if 0 - if (n == 4) { - bn_mul_comba4(&(t[n2]), t, &(t[n])); - bn_mul_comba4(r, a, b); - bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn); - memset(&(r[n2 + tn * 2]), 0, sizeof(BN_ULONG) * (n2 - tn * 2)); - } else -# endif - if (n == 8) { - bn_mul_comba8(&(t[n2]), t, &(t[n])); - bn_mul_comba8(r, a, b); - bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb); - memset(&(r[n2 + tna + tnb]), 0, sizeof(BN_ULONG) * (n2 - tna - tnb)); - } else { - p = &(t[n2 * 2]); - bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p); - bn_mul_recursive(r, a, b, n, 0, 0, p); - i = n / 2; - /* - * If there is only a bottom half to the number, just do it - */ - if (tna > tnb) - j = tna - i; - else - j = tnb - i; - if (j == 0) { - bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), - i, tna - i, tnb - i, p); - memset(&(r[n2 + i * 2]), 0, sizeof(BN_ULONG) * (n2 - i * 2)); - } else if (j > 0) { /* eg, n == 16, i == 8 and tn == 11 */ - bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]), - i, tna - i, tnb - i, p); - memset(&(r[n2 + tna + tnb]), 0, - sizeof(BN_ULONG) * (n2 - tna - tnb)); - } else { /* (j < 0) eg, n == 16, i == 8 and tn == 5 */ - - memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2); - if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL - && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) { - bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb); - } else { - for (;;) { - i /= 2; - /* - * these simplified conditions work exclusively because - * difference between tna and tnb is 1 or 0 - */ - if (i < tna || i < tnb) { - bn_mul_part_recursive(&(r[n2]), - &(a[n]), &(b[n]), - i, tna - i, tnb - i, p); - break; - } else if (i == tna || i == tnb) { - bn_mul_recursive(&(r[n2]), - &(a[n]), &(b[n]), - i, tna - i, tnb - i, p); - break; - } - } - } - } - } - - /*- - * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - */ - - c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); - - if (neg) { /* if t[32] is negative */ - c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); - } else { - /* Might have a carry */ - c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2)); - } - - /*- - * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - * c1 holds the carry bits - */ - c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); - if (c1) { - p = &(r[n + n2]); - lo = *p; - ln = (lo + c1) & BN_MASK2; - *p = ln; - - /* - * The overflow will stop before we over write words we should not - * overwrite - */ - if (ln < (BN_ULONG)c1) { - do { - p++; - lo = *p; - ln = (lo + 1) & BN_MASK2; - *p = ln; - } while (ln == 0); - } - } -} - -/*- - * a and b must be the same size, which is n2. - * r needs to be n2 words and t needs to be n2*2 - */ -void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, - BN_ULONG *t) -{ - int n = n2 / 2; - -# ifdef BN_COUNT - fprintf(stderr, " bn_mul_low_recursive %d * %d\n", n2, n2); -# endif - - bn_mul_recursive(r, a, b, n, 0, 0, &(t[0])); - if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) { - bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2])); - bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); - bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2])); - bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); - } else { - bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n); - bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n); - bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); - bn_add_words(&(r[n]), &(r[n]), &(t[n]), n); - } -} - -/*- - * a and b must be the same size, which is n2. - * r needs to be n2 words and t needs to be n2*2 - * l is the low words of the output. - * t needs to be n2*3 - */ -void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, - BN_ULONG *t) -{ - int i, n; - int c1, c2; - int neg, oneg, zero; - BN_ULONG ll, lc, *lp, *mp; - -# ifdef BN_COUNT - fprintf(stderr, " bn_mul_high %d * %d\n", n2, n2); -# endif - n = n2 / 2; - - /* Calculate (al-ah)*(bh-bl) */ - neg = zero = 0; - c1 = bn_cmp_words(&(a[0]), &(a[n]), n); - c2 = bn_cmp_words(&(b[n]), &(b[0]), n); - switch (c1 * 3 + c2) { - case -4: - bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n); - bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n); - break; - case -3: - zero = 1; - break; - case -2: - bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n); - bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n); - neg = 1; - break; - case -1: - case 0: - case 1: - zero = 1; - break; - case 2: - bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n); - bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n); - neg = 1; - break; - case 3: - zero = 1; - break; - case 4: - bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n); - bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n); - break; - } - - oneg = neg; - /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */ - /* r[10] = (a[1]*b[1]) */ -# ifdef BN_MUL_COMBA - if (n == 8) { - bn_mul_comba8(&(t[0]), &(r[0]), &(r[n])); - bn_mul_comba8(r, &(a[n]), &(b[n])); - } else -# endif - { - bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2])); - bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2])); - } - - /*- - * s0 == low(al*bl) - * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl) - * We know s0 and s1 so the only unknown is high(al*bl) - * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl)) - * high(al*bl) == s1 - (r[0]+l[0]+t[0]) - */ - if (l != NULL) { - lp = &(t[n2 + n]); - c1 = (int)(bn_add_words(lp, &(r[0]), &(l[0]), n)); - } else { - c1 = 0; - lp = &(r[0]); - } - - if (neg) - neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n)); - else { - bn_add_words(&(t[n2]), lp, &(t[0]), n); - neg = 0; - } - - if (l != NULL) { - bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n); - } else { - lp = &(t[n2 + n]); - mp = &(t[n2]); - for (i = 0; i < n; i++) - lp[i] = ((~mp[i]) + 1) & BN_MASK2; - } - - /*- - * s[0] = low(al*bl) - * t[3] = high(al*bl) - * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign - * r[10] = (a[1]*b[1]) - */ - /*- - * R[10] = al*bl - * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0]) - * R[32] = ah*bh - */ - /*- - * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow) - * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow) - * R[3]=r[1]+(carry/borrow) - */ - if (l != NULL) { - lp = &(t[n2]); - c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n)); - } else { - lp = &(t[n2 + n]); - c1 = 0; - } - c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n)); - if (oneg) - c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n)); - else - c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n)); - - c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n)); - c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n)); - if (oneg) - c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n)); - else - c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n)); - - if (c1 != 0) { /* Add starting at r[0], could be +ve or -ve */ - i = 0; - if (c1 > 0) { - lc = c1; - do { - ll = (r[i] + lc) & BN_MASK2; - r[i++] = ll; - lc = (lc > ll); - } while (lc); - } else { - lc = -c1; - do { - ll = r[i]; - r[i++] = (ll - lc) & BN_MASK2; - lc = (lc > ll); - } while (lc); - } - } - if (c2 != 0) { /* Add starting at r[1] */ - i = n; - if (c2 > 0) { - lc = c2; - do { - ll = (r[i] + lc) & BN_MASK2; - r[i++] = ll; - lc = (lc > ll); - } while (lc); - } else { - lc = -c2; - do { - ll = r[i]; - r[i++] = (ll - lc) & BN_MASK2; - lc = (lc > ll); - } while (lc); - } - } -} -#endif /* BN_RECURSION */ - -int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -{ - int ret = bn_mul_fixed_top(r, a, b, ctx); - - bn_correct_top(r); - bn_check_top(r); - - return ret; -} - -int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -{ - int ret = 0; - int top, al, bl; - BIGNUM *rr; -#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) - int i; -#endif -#ifdef BN_RECURSION - BIGNUM *t = NULL; - int j = 0, k; -#endif - -#ifdef BN_COUNT - fprintf(stderr, "BN_mul %d * %d\n", a->top, b->top); -#endif - - bn_check_top(a); - bn_check_top(b); - bn_check_top(r); - - al = a->top; - bl = b->top; - - if ((al == 0) || (bl == 0)) { - BN_zero(r); - return (1); - } - top = al + bl; - - BN_CTX_start(ctx); - if ((r == a) || (r == b)) { - if ((rr = BN_CTX_get(ctx)) == NULL) - goto err; - } else - rr = r; - rr->neg = a->neg ^ b->neg; - -#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) - i = al - bl; -#endif -#ifdef BN_MUL_COMBA - if (i == 0) { -# if 0 - if (al == 4) { - if (bn_wexpand(rr, 8) == NULL) - goto err; - rr->top = 8; - bn_mul_comba4(rr->d, a->d, b->d); - goto end; - } -# endif - if (al == 8) { - if (bn_wexpand(rr, 16) == NULL) - goto err; - rr->top = 16; - bn_mul_comba8(rr->d, a->d, b->d); - goto end; - } - } -#endif /* BN_MUL_COMBA */ -#ifdef BN_RECURSION - if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) { - if (i >= -1 && i <= 1) { - /* - * Find out the power of two lower or equal to the longest of the - * two numbers - */ - if (i >= 0) { - j = BN_num_bits_word((BN_ULONG)al); - } - if (i == -1) { - j = BN_num_bits_word((BN_ULONG)bl); - } - j = 1 << (j - 1); - assert(j <= al || j <= bl); - k = j + j; - t = BN_CTX_get(ctx); - if (t == NULL) - goto err; - if (al > j || bl > j) { - if (bn_wexpand(t, k * 4) == NULL) - goto err; - if (bn_wexpand(rr, k * 4) == NULL) - goto err; - bn_mul_part_recursive(rr->d, a->d, b->d, - j, al - j, bl - j, t->d); - } else { /* al <= j || bl <= j */ - - if (bn_wexpand(t, k * 2) == NULL) - goto err; - if (bn_wexpand(rr, k * 2) == NULL) - goto err; - bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); - } - rr->top = top; - goto end; - } - } -#endif /* BN_RECURSION */ - if (bn_wexpand(rr, top) == NULL) - goto err; - rr->top = top; - bn_mul_normal(rr->d, a->d, al, b->d, bl); - -#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) - end: -#endif - rr->flags |= BN_FLG_FIXED_TOP; - if (r != rr && BN_copy(r, rr) == NULL) - goto err; - - ret = 1; - err: - bn_check_top(r); - BN_CTX_end(ctx); - return (ret); -} - -void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) -{ - BN_ULONG *rr; - -#ifdef BN_COUNT - fprintf(stderr, " bn_mul_normal %d * %d\n", na, nb); -#endif - - if (na < nb) { - int itmp; - BN_ULONG *ltmp; - - itmp = na; - na = nb; - nb = itmp; - ltmp = a; - a = b; - b = ltmp; - - } - rr = &(r[na]); - if (nb <= 0) { - (void)bn_mul_words(r, a, na, 0); - return; - } else - rr[0] = bn_mul_words(r, a, na, b[0]); - - for (;;) { - if (--nb <= 0) - return; - rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]); - if (--nb <= 0) - return; - rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]); - if (--nb <= 0) - return; - rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]); - if (--nb <= 0) - return; - rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]); - rr += 4; - r += 4; - b += 4; - } -} - -void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) -{ -#ifdef BN_COUNT - fprintf(stderr, " bn_mul_low_normal %d * %d\n", n, n); -#endif - bn_mul_words(r, a, n, b[0]); - - for (;;) { - if (--n <= 0) - return; - bn_mul_add_words(&(r[1]), a, n, b[1]); - if (--n <= 0) - return; - bn_mul_add_words(&(r[2]), a, n, b[2]); - if (--n <= 0) - return; - bn_mul_add_words(&(r[3]), a, n, b[3]); - if (--n <= 0) - return; - bn_mul_add_words(&(r[4]), a, n, b[4]); - r += 4; - b += 4; - } -} -/* crypto/bn/bn_nist.c */ -/* - * Written by Nils Larsch for the OpenSSL project - */ -/* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "bn_lcl.h" -// #include "cryptlib.h" - -#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 -#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 -#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 -#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2 -#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2 - -/* pre-computed tables are "carry-less" values of modulus*(i+1) */ -#if BN_BITS2 == 64 -static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { - {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL}, - {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL}, - {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL} -}; - -static const BN_ULONG _nist_p_192_sqr[] = { - 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL, - 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL -}; - -static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { - {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL, - 0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL}, - {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL, - 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is - * "carry-full" */ -}; - -static const BN_ULONG _nist_p_224_sqr[] = { - 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL, - 0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL, - 0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL, - 0xFFFFFFFFFFFFFFFFULL -}; - -static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { - {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL, - 0x0000000000000000ULL, 0xFFFFFFFF00000001ULL}, - {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL, - 0x0000000000000000ULL, 0xFFFFFFFE00000002ULL}, - {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL, - 0x0000000000000000ULL, 0xFFFFFFFD00000003ULL}, - {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL, - 0x0000000000000000ULL, 0xFFFFFFFC00000004ULL}, - {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL, - 0x0000000000000000ULL, 0xFFFFFFFB00000005ULL}, -}; - -static const BN_ULONG _nist_p_256_sqr[] = { - 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL, - 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL, - 0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL, - 0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL -}; - -static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { - {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, - {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, - {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, - {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, - {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, -}; - -static const BN_ULONG _nist_p_384_sqr[] = { - 0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL, - 0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL, - 0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL -}; - -static const BN_ULONG _nist_p_521[] = - { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, - 0x00000000000001FFULL -}; - -static const BN_ULONG _nist_p_521_sqr[] = { - 0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, - 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, - 0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, - 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, - 0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL -}; -#elif BN_BITS2 == 32 -static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} -}; - -static const BN_ULONG _nist_p_192_sqr[] = { - 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000, - 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF -}; - -static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { - {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} -}; - -static const BN_ULONG _nist_p_224_sqr[] = { - 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, - 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002, - 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF -}; - -static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { - {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF}, - {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, - 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE}, - {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, - 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD}, - {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, - 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC}, - {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, - 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB}, -}; - -static const BN_ULONG _nist_p_256_sqr[] = { - 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, - 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, - 0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE -}; - -static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { - {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, - {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, -}; - -static const BN_ULONG _nist_p_384_sqr[] = { - 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE, - 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, - 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF -}; - -static const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0x000001FF -}; - -static const BN_ULONG _nist_p_521_sqr[] = { - 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF -}; -#else -# error "unsupported BN_BITS2" -#endif - -static const BIGNUM _bignum_nist_p_192 = { - (BN_ULONG *)_nist_p_192[0], - BN_NIST_192_TOP, - BN_NIST_192_TOP, - 0, - BN_FLG_STATIC_DATA -}; - -static const BIGNUM _bignum_nist_p_224 = { - (BN_ULONG *)_nist_p_224[0], - BN_NIST_224_TOP, - BN_NIST_224_TOP, - 0, - BN_FLG_STATIC_DATA -}; - -static const BIGNUM _bignum_nist_p_256 = { - (BN_ULONG *)_nist_p_256[0], - BN_NIST_256_TOP, - BN_NIST_256_TOP, - 0, - BN_FLG_STATIC_DATA -}; - -static const BIGNUM _bignum_nist_p_384 = { - (BN_ULONG *)_nist_p_384[0], - BN_NIST_384_TOP, - BN_NIST_384_TOP, - 0, - BN_FLG_STATIC_DATA -}; - -static const BIGNUM _bignum_nist_p_521 = { - (BN_ULONG *)_nist_p_521, - BN_NIST_521_TOP, - BN_NIST_521_TOP, - 0, - BN_FLG_STATIC_DATA -}; - -const BIGNUM *BN_get0_nist_prime_192(void) -{ - return &_bignum_nist_p_192; -} - -const BIGNUM *BN_get0_nist_prime_224(void) -{ - return &_bignum_nist_p_224; -} - -const BIGNUM *BN_get0_nist_prime_256(void) -{ - return &_bignum_nist_p_256; -} - -const BIGNUM *BN_get0_nist_prime_384(void) -{ - return &_bignum_nist_p_384; -} - -const BIGNUM *BN_get0_nist_prime_521(void) -{ - return &_bignum_nist_p_521; -} - -static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max) -{ - int i; - -#ifdef BN_DEBUG - OPENSSL_assert(top <= max); -#endif - for (i = 0; i < top; i++) - dst[i] = src[i]; - for (; i < max; i++) - dst[i] = 0; -} - -static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top) -{ - int i; - - for (i = 0; i < top; i++) - dst[i] = src[i]; -} - -#if BN_BITS2 == 64 -# define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; -# define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0; -/* - * two following macros are implemented under assumption that they - * are called in a sequence with *ascending* n, i.e. as they are... - */ -# define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\ - :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l))) -# define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0)); -# define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n) -# if defined(L_ENDIAN) -# if defined(__arch64__) -# define NIST_INT64 long -# else -# define NIST_INT64 long long -# endif -# endif -#else -# define bn_cp_64(to, n, from, m) \ - { \ - bn_cp_32(to, (n)*2, from, (m)*2); \ - bn_cp_32(to, (n)*2+1, from, (m)*2+1); \ - } -# define bn_64_set_0(to, n) \ - { \ - bn_32_set_0(to, (n)*2); \ - bn_32_set_0(to, (n)*2+1); \ - } -# define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; -# define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0; -# if defined(_WIN32) && !defined(__GNUC__) -# define NIST_INT64 __int64 -# elif defined(BN_LLONG) -# define NIST_INT64 long long -# endif -#endif /* BN_BITS2 != 64 */ - -#define nist_set_192(to, from, a1, a2, a3) \ - { \ - bn_cp_64(to, 0, from, (a3) - 3) \ - bn_cp_64(to, 1, from, (a2) - 3) \ - bn_cp_64(to, 2, from, (a1) - 3) \ - } - -int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, - BN_CTX *ctx) -{ - int top = a->top, i; - int carry; - register BN_ULONG *r_d, *a_d = a->d; - union { - BN_ULONG bn[BN_NIST_192_TOP]; - unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) / - sizeof(unsigned int)]; - } buf; - BN_ULONG c_d[BN_NIST_192_TOP], *res; - PTR_SIZE_INT mask; - static const BIGNUM _bignum_nist_p_192_sqr = { - (BN_ULONG *)_nist_p_192_sqr, - sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]), - sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]), - 0, BN_FLG_STATIC_DATA - }; - - field = &_bignum_nist_p_192; /* just to make sure */ - - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0) - return BN_nnmod(r, a, field, ctx); - - i = BN_ucmp(field, a); - if (i == 0) { - BN_zero(r); - return 1; - } else if (i > 0) - return (r == a) ? 1 : (BN_copy(r, a) != NULL); - - if (r != a) { - if (!bn_wexpand(r, BN_NIST_192_TOP)) - return 0; - r_d = r->d; - nist_cp_bn(r_d, a_d, BN_NIST_192_TOP); - } else - r_d = a_d; - - nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, - BN_NIST_192_TOP); - -#if defined(NIST_INT64) - { - NIST_INT64 acc; /* accumulator */ - unsigned int *rp = (unsigned int *)r_d; - const unsigned int *bp = (const unsigned int *)buf.ui; - - acc = rp[0]; - acc += bp[3 * 2 - 6]; - acc += bp[5 * 2 - 6]; - rp[0] = (unsigned int)acc; - acc >>= 32; - - acc += rp[1]; - acc += bp[3 * 2 - 5]; - acc += bp[5 * 2 - 5]; - rp[1] = (unsigned int)acc; - acc >>= 32; - - acc += rp[2]; - acc += bp[3 * 2 - 6]; - acc += bp[4 * 2 - 6]; - acc += bp[5 * 2 - 6]; - rp[2] = (unsigned int)acc; - acc >>= 32; - - acc += rp[3]; - acc += bp[3 * 2 - 5]; - acc += bp[4 * 2 - 5]; - acc += bp[5 * 2 - 5]; - rp[3] = (unsigned int)acc; - acc >>= 32; - - acc += rp[4]; - acc += bp[4 * 2 - 6]; - acc += bp[5 * 2 - 6]; - rp[4] = (unsigned int)acc; - acc >>= 32; - - acc += rp[5]; - acc += bp[4 * 2 - 5]; - acc += bp[5 * 2 - 5]; - rp[5] = (unsigned int)acc; - - carry = (int)(acc >> 32); - } -#else - { - BN_ULONG t_d[BN_NIST_192_TOP]; - - nist_set_192(t_d, buf.bn, 0, 3, 3); - carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); - nist_set_192(t_d, buf.bn, 4, 4, 0); - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); - nist_set_192(t_d, buf.bn, 5, 5, 5) - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); - } -#endif - if (carry > 0) - carry = - (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1], - BN_NIST_192_TOP); - else - carry = 1; - - /* - * we need 'if (carry==0 || result>=modulus) result-=modulus;' - * as comparison implies subtraction, we can write - * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;' - * this is what happens below, but without explicit if:-) a. - */ - mask = - 0 - (PTR_SIZE_INT) bn_sub_words(c_d, r_d, _nist_p_192[0], - BN_NIST_192_TOP); - mask &= 0 - (PTR_SIZE_INT) carry; - res = c_d; - res = (BN_ULONG *) - (((PTR_SIZE_INT) res & ~mask) | ((PTR_SIZE_INT) r_d & mask)); - nist_cp_bn(r_d, res, BN_NIST_192_TOP); - r->top = BN_NIST_192_TOP; - bn_correct_top(r); - - return 1; -} - -typedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *, - const BN_ULONG *, int); - -#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \ - { \ - bn_cp_32(to, 0, from, (a7) - 7) \ - bn_cp_32(to, 1, from, (a6) - 7) \ - bn_cp_32(to, 2, from, (a5) - 7) \ - bn_cp_32(to, 3, from, (a4) - 7) \ - bn_cp_32(to, 4, from, (a3) - 7) \ - bn_cp_32(to, 5, from, (a2) - 7) \ - bn_cp_32(to, 6, from, (a1) - 7) \ - } - -int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, - BN_CTX *ctx) -{ - int top = a->top, i; - int carry; - BN_ULONG *r_d, *a_d = a->d; - union { - BN_ULONG bn[BN_NIST_224_TOP]; - unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) / - sizeof(unsigned int)]; - } buf; - BN_ULONG c_d[BN_NIST_224_TOP], *res; - PTR_SIZE_INT mask; - union { - bn_addsub_f f; - PTR_SIZE_INT p; - } u; - static const BIGNUM _bignum_nist_p_224_sqr = { - (BN_ULONG *)_nist_p_224_sqr, - sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]), - sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]), - 0, BN_FLG_STATIC_DATA - }; - - field = &_bignum_nist_p_224; /* just to make sure */ - - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0) - return BN_nnmod(r, a, field, ctx); - - i = BN_ucmp(field, a); - if (i == 0) { - BN_zero(r); - return 1; - } else if (i > 0) - return (r == a) ? 1 : (BN_copy(r, a) != NULL); - - if (r != a) { - if (!bn_wexpand(r, BN_NIST_224_TOP)) - return 0; - r_d = r->d; - nist_cp_bn(r_d, a_d, BN_NIST_224_TOP); - } else - r_d = a_d; - -#if BN_BITS2==64 - /* copy upper 256 bits of 448 bit number ... */ - nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1), - top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP); - /* ... and right shift by 32 to obtain upper 224 bits */ - nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8); - /* truncate lower part to 224 bits too */ - r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l; -#else - nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, - BN_NIST_224_TOP); -#endif - -#if defined(NIST_INT64) && BN_BITS2!=64 - { - NIST_INT64 acc; /* accumulator */ - unsigned int *rp = (unsigned int *)r_d; - const unsigned int *bp = (const unsigned int *)buf.ui; - - acc = rp[0]; - acc -= bp[7 - 7]; - acc -= bp[11 - 7]; - rp[0] = (unsigned int)acc; - acc >>= 32; - - acc += rp[1]; - acc -= bp[8 - 7]; - acc -= bp[12 - 7]; - rp[1] = (unsigned int)acc; - acc >>= 32; - - acc += rp[2]; - acc -= bp[9 - 7]; - acc -= bp[13 - 7]; - rp[2] = (unsigned int)acc; - acc >>= 32; - - acc += rp[3]; - acc += bp[7 - 7]; - acc += bp[11 - 7]; - acc -= bp[10 - 7]; - rp[3] = (unsigned int)acc; - acc >>= 32; - - acc += rp[4]; - acc += bp[8 - 7]; - acc += bp[12 - 7]; - acc -= bp[11 - 7]; - rp[4] = (unsigned int)acc; - acc >>= 32; - - acc += rp[5]; - acc += bp[9 - 7]; - acc += bp[13 - 7]; - acc -= bp[12 - 7]; - rp[5] = (unsigned int)acc; - acc >>= 32; - - acc += rp[6]; - acc += bp[10 - 7]; - acc -= bp[13 - 7]; - rp[6] = (unsigned int)acc; - - carry = (int)(acc >> 32); -# if BN_BITS2==64 - rp[7] = carry; -# endif - } -#else - { - BN_ULONG t_d[BN_NIST_224_TOP]; - - nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0); - carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); - nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0); - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); - nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); - nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); - -# if BN_BITS2==64 - carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32); -# endif - } -#endif - u.f = bn_sub_words; - if (carry > 0) { - carry = - (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1], - BN_NIST_224_TOP); -#if BN_BITS2==64 - carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1; -#endif - } else if (carry < 0) { - /* - * it's a bit more comlicated logic in this case. if bn_add_words - * yields no carry, then result has to be adjusted by unconditionally - * *adding* the modulus. but if it does, then result has to be - * compared to the modulus and conditionally adjusted by - * *subtracting* the latter. - */ - carry = - (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1], - BN_NIST_224_TOP); - mask = 0 - (PTR_SIZE_INT) carry; - u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | - ((PTR_SIZE_INT) bn_add_words & ~mask); - } else - carry = 1; - - /* otherwise it's effectively same as in BN_nist_mod_192... */ - mask = - 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP); - mask &= 0 - (PTR_SIZE_INT) carry; - res = c_d; - res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | - ((PTR_SIZE_INT) r_d & mask)); - nist_cp_bn(r_d, res, BN_NIST_224_TOP); - r->top = BN_NIST_224_TOP; - bn_correct_top(r); - - return 1; -} - -#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \ - { \ - bn_cp_32(to, 0, from, (a8) - 8) \ - bn_cp_32(to, 1, from, (a7) - 8) \ - bn_cp_32(to, 2, from, (a6) - 8) \ - bn_cp_32(to, 3, from, (a5) - 8) \ - bn_cp_32(to, 4, from, (a4) - 8) \ - bn_cp_32(to, 5, from, (a3) - 8) \ - bn_cp_32(to, 6, from, (a2) - 8) \ - bn_cp_32(to, 7, from, (a1) - 8) \ - } - -int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, - BN_CTX *ctx) -{ - int i, top = a->top; - int carry = 0; - register BN_ULONG *a_d = a->d, *r_d; - union { - BN_ULONG bn[BN_NIST_256_TOP]; - unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) / - sizeof(unsigned int)]; - } buf; - BN_ULONG c_d[BN_NIST_256_TOP], *res; - PTR_SIZE_INT mask; - union { - bn_addsub_f f; - PTR_SIZE_INT p; - } u; - static const BIGNUM _bignum_nist_p_256_sqr = { - (BN_ULONG *)_nist_p_256_sqr, - sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]), - sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]), - 0, BN_FLG_STATIC_DATA - }; - - field = &_bignum_nist_p_256; /* just to make sure */ - - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0) - return BN_nnmod(r, a, field, ctx); - - i = BN_ucmp(field, a); - if (i == 0) { - BN_zero(r); - return 1; - } else if (i > 0) - return (r == a) ? 1 : (BN_copy(r, a) != NULL); - - if (r != a) { - if (!bn_wexpand(r, BN_NIST_256_TOP)) - return 0; - r_d = r->d; - nist_cp_bn(r_d, a_d, BN_NIST_256_TOP); - } else - r_d = a_d; - - nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, - BN_NIST_256_TOP); - -#if defined(NIST_INT64) - { - NIST_INT64 acc; /* accumulator */ - unsigned int *rp = (unsigned int *)r_d; - const unsigned int *bp = (const unsigned int *)buf.ui; - - acc = rp[0]; - acc += bp[8 - 8]; - acc += bp[9 - 8]; - acc -= bp[11 - 8]; - acc -= bp[12 - 8]; - acc -= bp[13 - 8]; - acc -= bp[14 - 8]; - rp[0] = (unsigned int)acc; - acc >>= 32; - - acc += rp[1]; - acc += bp[9 - 8]; - acc += bp[10 - 8]; - acc -= bp[12 - 8]; - acc -= bp[13 - 8]; - acc -= bp[14 - 8]; - acc -= bp[15 - 8]; - rp[1] = (unsigned int)acc; - acc >>= 32; - - acc += rp[2]; - acc += bp[10 - 8]; - acc += bp[11 - 8]; - acc -= bp[13 - 8]; - acc -= bp[14 - 8]; - acc -= bp[15 - 8]; - rp[2] = (unsigned int)acc; - acc >>= 32; - - acc += rp[3]; - acc += bp[11 - 8]; - acc += bp[11 - 8]; - acc += bp[12 - 8]; - acc += bp[12 - 8]; - acc += bp[13 - 8]; - acc -= bp[15 - 8]; - acc -= bp[8 - 8]; - acc -= bp[9 - 8]; - rp[3] = (unsigned int)acc; - acc >>= 32; - - acc += rp[4]; - acc += bp[12 - 8]; - acc += bp[12 - 8]; - acc += bp[13 - 8]; - acc += bp[13 - 8]; - acc += bp[14 - 8]; - acc -= bp[9 - 8]; - acc -= bp[10 - 8]; - rp[4] = (unsigned int)acc; - acc >>= 32; - - acc += rp[5]; - acc += bp[13 - 8]; - acc += bp[13 - 8]; - acc += bp[14 - 8]; - acc += bp[14 - 8]; - acc += bp[15 - 8]; - acc -= bp[10 - 8]; - acc -= bp[11 - 8]; - rp[5] = (unsigned int)acc; - acc >>= 32; - - acc += rp[6]; - acc += bp[14 - 8]; - acc += bp[14 - 8]; - acc += bp[15 - 8]; - acc += bp[15 - 8]; - acc += bp[14 - 8]; - acc += bp[13 - 8]; - acc -= bp[8 - 8]; - acc -= bp[9 - 8]; - rp[6] = (unsigned int)acc; - acc >>= 32; - - acc += rp[7]; - acc += bp[15 - 8]; - acc += bp[15 - 8]; - acc += bp[15 - 8]; - acc += bp[8 - 8]; - acc -= bp[10 - 8]; - acc -= bp[11 - 8]; - acc -= bp[12 - 8]; - acc -= bp[13 - 8]; - rp[7] = (unsigned int)acc; - - carry = (int)(acc >> 32); - } -#else - { - BN_ULONG t_d[BN_NIST_256_TOP]; - - /* - * S1 - */ - nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0); - /* - * S2 - */ - nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0); - carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP); - /* left shift */ - { - register BN_ULONG *ap, t, c; - ap = t_d; - c = 0; - for (i = BN_NIST_256_TOP; i != 0; --i) { - t = *ap; - *(ap++) = ((t << 1) | c) & BN_MASK2; - c = (t & BN_TBIT) ? 1 : 0; - } - carry <<= 1; - carry |= c; - } - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); - /* - * S3 - */ - nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8); - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); - /* - * S4 - */ - nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9); - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); - /* - * D1 - */ - nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); - /* - * D2 - */ - nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); - /* - * D3 - */ - nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); - /* - * D4 - */ - nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); - - } -#endif - /* see BN_nist_mod_224 for explanation */ - u.f = bn_sub_words; - if (carry > 0) - carry = - (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1], - BN_NIST_256_TOP); - else if (carry < 0) { - carry = - (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1], - BN_NIST_256_TOP); - mask = 0 - (PTR_SIZE_INT) carry; - u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | - ((PTR_SIZE_INT) bn_add_words & ~mask); - } else - carry = 1; - - mask = - 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP); - mask &= 0 - (PTR_SIZE_INT) carry; - res = c_d; - res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | - ((PTR_SIZE_INT) r_d & mask)); - nist_cp_bn(r_d, res, BN_NIST_256_TOP); - r->top = BN_NIST_256_TOP; - bn_correct_top(r); - - return 1; -} - -#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \ - { \ - bn_cp_32(to, 0, from, (a12) - 12) \ - bn_cp_32(to, 1, from, (a11) - 12) \ - bn_cp_32(to, 2, from, (a10) - 12) \ - bn_cp_32(to, 3, from, (a9) - 12) \ - bn_cp_32(to, 4, from, (a8) - 12) \ - bn_cp_32(to, 5, from, (a7) - 12) \ - bn_cp_32(to, 6, from, (a6) - 12) \ - bn_cp_32(to, 7, from, (a5) - 12) \ - bn_cp_32(to, 8, from, (a4) - 12) \ - bn_cp_32(to, 9, from, (a3) - 12) \ - bn_cp_32(to, 10, from, (a2) - 12) \ - bn_cp_32(to, 11, from, (a1) - 12) \ - } - -int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, - BN_CTX *ctx) -{ - int i, top = a->top; - int carry = 0; - register BN_ULONG *r_d, *a_d = a->d; - union { - BN_ULONG bn[BN_NIST_384_TOP]; - unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) / - sizeof(unsigned int)]; - } buf; - BN_ULONG c_d[BN_NIST_384_TOP], *res; - PTR_SIZE_INT mask; - union { - bn_addsub_f f; - PTR_SIZE_INT p; - } u; - static const BIGNUM _bignum_nist_p_384_sqr = { - (BN_ULONG *)_nist_p_384_sqr, - sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]), - sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]), - 0, BN_FLG_STATIC_DATA - }; - - field = &_bignum_nist_p_384; /* just to make sure */ - - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0) - return BN_nnmod(r, a, field, ctx); - - i = BN_ucmp(field, a); - if (i == 0) { - BN_zero(r); - return 1; - } else if (i > 0) - return (r == a) ? 1 : (BN_copy(r, a) != NULL); - - if (r != a) { - if (!bn_wexpand(r, BN_NIST_384_TOP)) - return 0; - r_d = r->d; - nist_cp_bn(r_d, a_d, BN_NIST_384_TOP); - } else - r_d = a_d; - - nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, - BN_NIST_384_TOP); - -#if defined(NIST_INT64) - { - NIST_INT64 acc; /* accumulator */ - unsigned int *rp = (unsigned int *)r_d; - const unsigned int *bp = (const unsigned int *)buf.ui; - - acc = rp[0]; - acc += bp[12 - 12]; - acc += bp[21 - 12]; - acc += bp[20 - 12]; - acc -= bp[23 - 12]; - rp[0] = (unsigned int)acc; - acc >>= 32; - - acc += rp[1]; - acc += bp[13 - 12]; - acc += bp[22 - 12]; - acc += bp[23 - 12]; - acc -= bp[12 - 12]; - acc -= bp[20 - 12]; - rp[1] = (unsigned int)acc; - acc >>= 32; - - acc += rp[2]; - acc += bp[14 - 12]; - acc += bp[23 - 12]; - acc -= bp[13 - 12]; - acc -= bp[21 - 12]; - rp[2] = (unsigned int)acc; - acc >>= 32; - - acc += rp[3]; - acc += bp[15 - 12]; - acc += bp[12 - 12]; - acc += bp[20 - 12]; - acc += bp[21 - 12]; - acc -= bp[14 - 12]; - acc -= bp[22 - 12]; - acc -= bp[23 - 12]; - rp[3] = (unsigned int)acc; - acc >>= 32; - - acc += rp[4]; - acc += bp[21 - 12]; - acc += bp[21 - 12]; - acc += bp[16 - 12]; - acc += bp[13 - 12]; - acc += bp[12 - 12]; - acc += bp[20 - 12]; - acc += bp[22 - 12]; - acc -= bp[15 - 12]; - acc -= bp[23 - 12]; - acc -= bp[23 - 12]; - rp[4] = (unsigned int)acc; - acc >>= 32; - - acc += rp[5]; - acc += bp[22 - 12]; - acc += bp[22 - 12]; - acc += bp[17 - 12]; - acc += bp[14 - 12]; - acc += bp[13 - 12]; - acc += bp[21 - 12]; - acc += bp[23 - 12]; - acc -= bp[16 - 12]; - rp[5] = (unsigned int)acc; - acc >>= 32; - - acc += rp[6]; - acc += bp[23 - 12]; - acc += bp[23 - 12]; - acc += bp[18 - 12]; - acc += bp[15 - 12]; - acc += bp[14 - 12]; - acc += bp[22 - 12]; - acc -= bp[17 - 12]; - rp[6] = (unsigned int)acc; - acc >>= 32; - - acc += rp[7]; - acc += bp[19 - 12]; - acc += bp[16 - 12]; - acc += bp[15 - 12]; - acc += bp[23 - 12]; - acc -= bp[18 - 12]; - rp[7] = (unsigned int)acc; - acc >>= 32; - - acc += rp[8]; - acc += bp[20 - 12]; - acc += bp[17 - 12]; - acc += bp[16 - 12]; - acc -= bp[19 - 12]; - rp[8] = (unsigned int)acc; - acc >>= 32; - - acc += rp[9]; - acc += bp[21 - 12]; - acc += bp[18 - 12]; - acc += bp[17 - 12]; - acc -= bp[20 - 12]; - rp[9] = (unsigned int)acc; - acc >>= 32; - - acc += rp[10]; - acc += bp[22 - 12]; - acc += bp[19 - 12]; - acc += bp[18 - 12]; - acc -= bp[21 - 12]; - rp[10] = (unsigned int)acc; - acc >>= 32; - - acc += rp[11]; - acc += bp[23 - 12]; - acc += bp[20 - 12]; - acc += bp[19 - 12]; - acc -= bp[22 - 12]; - rp[11] = (unsigned int)acc; - - carry = (int)(acc >> 32); - } -#else - { - BN_ULONG t_d[BN_NIST_384_TOP]; - - /* - * S1 - */ - nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4); - /* left shift */ - { - register BN_ULONG *ap, t, c; - ap = t_d; - c = 0; - for (i = 3; i != 0; --i) { - t = *ap; - *(ap++) = ((t << 1) | c) & BN_MASK2; - c = (t & BN_TBIT) ? 1 : 0; - } - *ap = c; - } - carry = - (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2), - t_d, BN_NIST_256_TOP); - /* - * S2 - */ - carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP); - /* - * S3 - */ - nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, - 21); - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); - /* - * S4 - */ - nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23, - 0); - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); - /* - * S5 - */ - nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0); - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); - /* - * S6 - */ - nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20); - carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); - /* - * D1 - */ - nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, - 23); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); - /* - * D2 - */ - nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); - /* - * D3 - */ - nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0); - carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); - - } -#endif - /* see BN_nist_mod_224 for explanation */ - u.f = bn_sub_words; - if (carry > 0) - carry = - (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1], - BN_NIST_384_TOP); - else if (carry < 0) { - carry = - (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1], - BN_NIST_384_TOP); - mask = 0 - (PTR_SIZE_INT) carry; - u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | - ((PTR_SIZE_INT) bn_add_words & ~mask); - } else - carry = 1; - - mask = - 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP); - mask &= 0 - (PTR_SIZE_INT) carry; - res = c_d; - res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | - ((PTR_SIZE_INT) r_d & mask)); - nist_cp_bn(r_d, res, BN_NIST_384_TOP); - r->top = BN_NIST_384_TOP; - bn_correct_top(r); - - return 1; -} - -#define BN_NIST_521_RSHIFT (521%BN_BITS2) -#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT) -#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT) - -int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, - BN_CTX *ctx) -{ - int top = a->top, i; - BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res; - PTR_SIZE_INT mask; - static const BIGNUM _bignum_nist_p_521_sqr = { - (BN_ULONG *)_nist_p_521_sqr, - sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]), - sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]), - 0, BN_FLG_STATIC_DATA - }; - - field = &_bignum_nist_p_521; /* just to make sure */ - - if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0) - return BN_nnmod(r, a, field, ctx); - - i = BN_ucmp(field, a); - if (i == 0) { - BN_zero(r); - return 1; - } else if (i > 0) - return (r == a) ? 1 : (BN_copy(r, a) != NULL); - - if (r != a) { - if (!bn_wexpand(r, BN_NIST_521_TOP)) - return 0; - r_d = r->d; - nist_cp_bn(r_d, a_d, BN_NIST_521_TOP); - } else - r_d = a_d; - - /* upper 521 bits, copy ... */ - nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1), - top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP); - /* ... and right shift */ - for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) { - t_d[i] = (val >> BN_NIST_521_RSHIFT | - (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2; - val = tmp; - } - t_d[i] = val >> BN_NIST_521_RSHIFT; - /* lower 521 bits */ - r_d[i] &= BN_NIST_521_TOP_MASK; - - bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP); - mask = - 0 - (PTR_SIZE_INT) bn_sub_words(t_d, r_d, _nist_p_521, - BN_NIST_521_TOP); - res = t_d; - res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | - ((PTR_SIZE_INT) r_d & mask)); - nist_cp_bn(r_d, res, BN_NIST_521_TOP); - r->top = BN_NIST_521_TOP; - bn_correct_top(r); - - return 1; -} -/* crypto/bn/bn_prime.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" -// #include "rand.h" - -/* - * NB: these functions have been "upgraded", the deprecated versions (which - * are compatibility wrappers using these functions) are in bn_depr.c. - - * Geoff - */ - -/* - * The quick sieve algorithm approach to weeding out primes is Philip - * Zimmermann's, as implemented in PGP. I have had a read of his comments - * and implemented my own version. - */ -#include "bn_prime.h" - -static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, - const BIGNUM *a1_odd, int k, BN_CTX *ctx, - BN_MONT_CTX *mont); -static int probable_prime(BIGNUM *rnd, int bits); -static int probable_prime_dh(BIGNUM *rnd, int bits, - const BIGNUM *add, const BIGNUM *rem, - BN_CTX *ctx); -static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add, - const BIGNUM *rem, BN_CTX *ctx); - -int BN_GENCB_call(BN_GENCB *cb, int a, int b) -{ - /* No callback means continue */ - if (!cb) - return 1; - switch (cb->ver) { - case 1: - /* Deprecated-style callbacks */ - if (!cb->cb.cb_1) - return 1; - cb->cb.cb_1(a, b, cb->arg); - return 1; - case 2: - /* New-style callbacks */ - return cb->cb.cb_2(a, b, cb); - default: - break; - } - /* Unrecognised callback type */ - return 0; -} - -int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, - const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) -{ - BIGNUM *t; - int found = 0; - int i, j, c1 = 0; - BN_CTX *ctx; - int checks = BN_prime_checks_for_size(bits); - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - t = BN_CTX_get(ctx); - if (!t) - goto err; - loop: - /* make a random number and set the top and bottom bits */ - if (add == NULL) { - if (!probable_prime(ret, bits)) - goto err; - } else { - if (safe) { - if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) - goto err; - } else { - if (!probable_prime_dh(ret, bits, add, rem, ctx)) - goto err; - } - } - /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ - if (!BN_GENCB_call(cb, 0, c1++)) - /* aborted */ - goto err; - - if (!safe) { - i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); - if (i == -1) - goto err; - if (i == 0) - goto loop; - } else { - /* - * for "safe prime" generation, check that (p-1)/2 is prime. Since a - * prime is odd, We just need to divide by 2 - */ - if (!BN_rshift1(t, ret)) - goto err; - - for (i = 0; i < checks; i++) { - j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb); - if (j == -1) - goto err; - if (j == 0) - goto loop; - - j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb); - if (j == -1) - goto err; - if (j == 0) - goto loop; - - if (!BN_GENCB_call(cb, 2, c1 - 1)) - goto err; - /* We have a safe prime test pass */ - } - } - /* we have a prime :-) */ - found = 1; - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - bn_check_top(ret); - return found; -} - -int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, - BN_GENCB *cb) -{ - return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb); -} - -int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, - int do_trial_division, BN_GENCB *cb) -{ - int i, j, ret = -1; - int k; - BN_CTX *ctx = NULL; - BIGNUM *A1, *A1_odd, *check; /* taken from ctx */ - BN_MONT_CTX *mont = NULL; - - if (BN_cmp(a, BN_value_one()) <= 0) - return 0; - - if (checks == BN_prime_checks) - checks = BN_prime_checks_for_size(BN_num_bits(a)); - - /* first look for small factors */ - if (!BN_is_odd(a)) - /* a is even => a is prime if and only if a == 2 */ - return BN_is_word(a, 2); - if (do_trial_division) { - for (i = 1; i < NUMPRIMES; i++) - if (BN_mod_word(a, primes[i]) == 0) - return 0; - if (!BN_GENCB_call(cb, 1, -1)) - goto err; - } - - if (ctx_passed != NULL) - ctx = ctx_passed; - else if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - - A1 = BN_CTX_get(ctx); - A1_odd = BN_CTX_get(ctx); - check = BN_CTX_get(ctx); - if (check == NULL) - goto err; - - /* compute A1 := a - 1 */ - if (!BN_copy(A1, a)) - goto err; - if (!BN_sub_word(A1, 1)) - goto err; - if (BN_is_zero(A1)) { - ret = 0; - goto err; - } - - /* write A1 as A1_odd * 2^k */ - k = 1; - while (!BN_is_bit_set(A1, k)) - k++; - if (!BN_rshift(A1_odd, A1, k)) - goto err; - - /* Montgomery setup for computations mod a */ - mont = BN_MONT_CTX_new(); - if (mont == NULL) - goto err; - if (!BN_MONT_CTX_set(mont, a, ctx)) - goto err; - - for (i = 0; i < checks; i++) { - if (!BN_pseudo_rand_range(check, A1)) - goto err; - if (!BN_add_word(check, 1)) - goto err; - /* now 1 <= check < a */ - - j = witness(check, a, A1, A1_odd, k, ctx, mont); - if (j == -1) - goto err; - if (j) { - ret = 0; - goto err; - } - if (!BN_GENCB_call(cb, 1, i)) - goto err; - } - ret = 1; - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - if (ctx_passed == NULL) - BN_CTX_free(ctx); - } - if (mont != NULL) - BN_MONT_CTX_free(mont); - - return (ret); -} - -static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, - const BIGNUM *a1_odd, int k, BN_CTX *ctx, - BN_MONT_CTX *mont) -{ - if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */ - return -1; - if (BN_is_one(w)) - return 0; /* probably prime */ - if (BN_cmp(w, a1) == 0) - return 0; /* w == -1 (mod a), 'a' is probably prime */ - while (--k) { - if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */ - return -1; - if (BN_is_one(w)) - return 1; /* 'a' is composite, otherwise a previous 'w' - * would have been == -1 (mod 'a') */ - if (BN_cmp(w, a1) == 0) - return 0; /* w == -1 (mod a), 'a' is probably prime */ - } - /* - * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and - * it is neither -1 nor +1 -- so 'a' cannot be prime - */ - bn_check_top(w); - return 1; -} - -static int probable_prime(BIGNUM *rnd, int bits) -{ - int i; - prime_t mods[NUMPRIMES]; - BN_ULONG delta, maxdelta; - - again: - if (!BN_rand(rnd, bits, 1, 1)) - return (0); - /* we now have a random number 'rand' to test. */ - for (i = 1; i < NUMPRIMES; i++) - mods[i] = (prime_t) BN_mod_word(rnd, (BN_ULONG)primes[i]); - maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; - delta = 0; - loop:for (i = 1; i < NUMPRIMES; i++) { - /* - * check that rnd is not a prime and also that gcd(rnd-1,primes) == 1 - * (except for 2) - */ - if (((mods[i] + delta) % primes[i]) <= 1) { - delta += 2; - if (delta > maxdelta) - goto again; - goto loop; - } - } - if (!BN_add_word(rnd, delta)) - return (0); - bn_check_top(rnd); - return (1); -} - -static int probable_prime_dh(BIGNUM *rnd, int bits, - const BIGNUM *add, const BIGNUM *rem, - BN_CTX *ctx) -{ - int i, ret = 0; - BIGNUM *t1; - - BN_CTX_start(ctx); - if ((t1 = BN_CTX_get(ctx)) == NULL) - goto err; - - if (!BN_rand(rnd, bits, 0, 1)) - goto err; - - /* we need ((rnd-rem) % add) == 0 */ - - if (!BN_mod(t1, rnd, add, ctx)) - goto err; - if (!BN_sub(rnd, rnd, t1)) - goto err; - if (rem == NULL) { - if (!BN_add_word(rnd, 1)) - goto err; - } else { - if (!BN_add(rnd, rnd, rem)) - goto err; - } - - /* we now have a random number 'rand' to test. */ - - loop:for (i = 1; i < NUMPRIMES; i++) { - /* check that rnd is a prime */ - if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { - if (!BN_add(rnd, rnd, add)) - goto err; - goto loop; - } - } - ret = 1; - err: - BN_CTX_end(ctx); - bn_check_top(rnd); - return (ret); -} - -static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, - const BIGNUM *rem, BN_CTX *ctx) -{ - int i, ret = 0; - BIGNUM *t1, *qadd, *q; - - bits--; - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - qadd = BN_CTX_get(ctx); - if (qadd == NULL) - goto err; - - if (!BN_rshift1(qadd, padd)) - goto err; - - if (!BN_rand(q, bits, 0, 1)) - goto err; - - /* we need ((rnd-rem) % add) == 0 */ - if (!BN_mod(t1, q, qadd, ctx)) - goto err; - if (!BN_sub(q, q, t1)) - goto err; - if (rem == NULL) { - if (!BN_add_word(q, 1)) - goto err; - } else { - if (!BN_rshift1(t1, rem)) - goto err; - if (!BN_add(q, q, t1)) - goto err; - } - - /* we now have a random number 'rand' to test. */ - if (!BN_lshift1(p, q)) - goto err; - if (!BN_add_word(p, 1)) - goto err; - - loop:for (i = 1; i < NUMPRIMES; i++) { - /* check that p and q are prime */ - /* - * check that for p and q gcd(p-1,primes) == 1 (except for 2) - */ - if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) || - (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) { - if (!BN_add(p, p, padd)) - goto err; - if (!BN_add(q, q, qadd)) - goto err; - goto loop; - } - } - ret = 1; - err: - BN_CTX_end(ctx); - bn_check_top(p); - return (ret); -} -/* crypto/bn/bn_print.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -// #include "cryptlib.h" -#include "buffer.h" -// #include "bn_lcl.h" - -static const char Hex[] = "0123456789ABCDEF"; - -/* Must 'OPENSSL_free' the returned data */ -char *BN_bn2hex(const BIGNUM *a) -{ - int i, j, v, z = 0; - char *buf; - char *p; - - if (BN_is_zero(a)) - return OPENSSL_strdup("0"); - buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); - if (buf == NULL) { - BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE); - goto err; - } - p = buf; - if (a->neg) - *(p++) = '-'; - for (i = a->top - 1; i >= 0; i--) { - for (j = BN_BITS2 - 8; j >= 0; j -= 8) { - /* strip leading zeros */ - v = ((int)(a->d[i] >> (long)j)) & 0xff; - if (z || (v != 0)) { - *(p++) = Hex[v >> 4]; - *(p++) = Hex[v & 0x0f]; - z = 1; - } - } - } - *p = '\0'; - err: - return (buf); -} - -/* Must 'OPENSSL_free' the returned data */ -char *BN_bn2dec(const BIGNUM *a) -{ - int i = 0, num, ok = 0; - char *buf = NULL; - char *p; - BIGNUM *t = NULL; - BN_ULONG *bn_data = NULL, *lp; - int bn_data_num; - - /*- - * get an upper bound for the length of the decimal integer - * num <= (BN_num_bits(a) + 1) * log(2) - * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error) - * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1 - */ - i = BN_num_bits(a) * 3; - num = (i / 10 + i / 1000 + 1) + 1; - bn_data_num = num / BN_DEC_NUM + 1; - bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG)); - buf = OPENSSL_malloc(num + 3); - if ((buf == NULL) || (bn_data == NULL)) { - BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); - goto err; - } - if ((t = BN_dup(a)) == NULL) - goto err; - -#define BUF_REMAIN (num+3 - (size_t)(p - buf)) - p = buf; - lp = bn_data; - if (BN_is_zero(t)) { - *(p++) = '0'; - *(p++) = '\0'; - } else { - if (BN_is_negative(t)) - *p++ = '-'; - - while (!BN_is_zero(t)) { - if (lp - bn_data >= bn_data_num) - goto err; - *lp = BN_div_word(t, BN_DEC_CONV); - if (*lp == (BN_ULONG)-1) - goto err; - lp++; - } - lp--; - /* - * We now have a series of blocks, BN_DEC_NUM chars in length, where - * the last one needs truncation. The blocks need to be reversed in - * order. - */ - BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp); - while (*p) - p++; - while (lp != bn_data) { - lp--; - BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp); - while (*p) - p++; - } - } - ok = 1; - err: - if (bn_data != NULL) - OPENSSL_free(bn_data); - if (t != NULL) - BN_free(t); - if (!ok && buf) { - OPENSSL_free(buf); - buf = NULL; - } - - return (buf); -} - -int BN_hex2bn(BIGNUM **bn, const char *a) -{ - BIGNUM *ret = NULL; - BN_ULONG l = 0; - int neg = 0, h, m, i, j, k, c; - int num; - - if ((a == NULL) || (*a == '\0')) - return (0); - - if (*a == '-') { - neg = 1; - a++; - } - - for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++) - continue; - - if (i > INT_MAX/4) - goto err; - - num = i + neg; - if (bn == NULL) - return (num); - - /* a is the start of the hex digits, and it is 'i' long */ - if (*bn == NULL) { - if ((ret = BN_new()) == NULL) - return (0); - } else { - ret = *bn; - BN_zero(ret); - } - - /* i is the number of hex digits */ - if (bn_expand(ret, i * 4) == NULL) - goto err; - - j = i; /* least significant 'hex' */ - m = 0; - h = 0; - while (j > 0) { - m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j; - l = 0; - for (;;) { - c = a[j - m]; - if ((c >= '0') && (c <= '9')) - k = c - '0'; - else if ((c >= 'a') && (c <= 'f')) - k = c - 'a' + 10; - else if ((c >= 'A') && (c <= 'F')) - k = c - 'A' + 10; - else - k = 0; /* paranoia */ - l = (l << 4) | k; - - if (--m <= 0) { - ret->d[h++] = l; - break; - } - } - j -= (BN_BYTES * 2); - } - ret->top = h; - bn_correct_top(ret); - - *bn = ret; - bn_check_top(ret); - /* Don't set the negative flag if it's zero. */ - if (ret->top != 0) - ret->neg = neg; - return (num); - err: - if (*bn == NULL) - BN_free(ret); - return (0); -} - -int BN_dec2bn(BIGNUM **bn, const char *a) -{ - BIGNUM *ret = NULL; - BN_ULONG l = 0; - int neg = 0, i, j; - int num; - - if ((a == NULL) || (*a == '\0')) - return (0); - if (*a == '-') { - neg = 1; - a++; - } - - for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++) - continue; - - if (i > INT_MAX/4) - goto err; - - num = i + neg; - if (bn == NULL) - return (num); - - /* - * a is the start of the digits, and it is 'i' long. We chop it into - * BN_DEC_NUM digits at a time - */ - if (*bn == NULL) { - if ((ret = BN_new()) == NULL) - return (0); - } else { - ret = *bn; - BN_zero(ret); - } - - /* i is the number of digits, a bit of an over expand */ - if (bn_expand(ret, i * 4) == NULL) - goto err; - - j = BN_DEC_NUM - (i % BN_DEC_NUM); - if (j == BN_DEC_NUM) - j = 0; - l = 0; - while (--i >= 0) { - l *= 10; - l += *a - '0'; - a++; - if (++j == BN_DEC_NUM) { - BN_mul_word(ret, BN_DEC_CONV); - BN_add_word(ret, l); - l = 0; - j = 0; - } - } - - bn_correct_top(ret); - *bn = ret; - bn_check_top(ret); - /* Don't set the negative flag if it's zero. */ - if (ret->top != 0) - ret->neg = neg; - return (num); - err: - if (*bn == NULL) - BN_free(ret); - return (0); -} - -int BN_asc2bn(BIGNUM **bn, const char *a) -{ - const char *p = a; - - if (*p == '-') - p++; - - if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) { - if (!BN_hex2bn(bn, p + 2)) - return 0; - } else { - if (!BN_dec2bn(bn, p)) - return 0; - } - /* Don't set the negative flag if it's zero. */ - if (*a == '-' && (*bn)->top != 0) - (*bn)->neg = 1; - return 1; -} - -#ifndef OPENSSL_NO_BIO -# ifndef OPENSSL_NO_FP_API -int BN_print_fp(FILE *fp, const BIGNUM *a) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) - return (0); - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = BN_print(b, a); - BIO_free(b); - return (ret); -} -# endif - -int BN_print(BIO *bp, const BIGNUM *a) -{ - int i, j, v, z = 0; - int ret = 0; - - if ((a->neg) && (BIO_write(bp, "-", 1) != 1)) - goto end; - if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1)) - goto end; - for (i = a->top - 1; i >= 0; i--) { - for (j = BN_BITS2 - 4; j >= 0; j -= 4) { - /* strip leading zeros */ - v = ((int)(a->d[i] >> (long)j)) & 0x0f; - if (z || (v != 0)) { - if (BIO_write(bp, &(Hex[v]), 1) != 1) - goto end; - z = 1; - } - } - } - ret = 1; - end: - return (ret); -} -#endif - -char *BN_options(void) -{ - static int init = 0; - static char data[16]; - - if (!init) { - init++; -#ifdef BN_LLONG - BIO_snprintf(data, sizeof(data), "bn(%d,%d)", - (int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8); -#else - BIO_snprintf(data, sizeof(data), "bn(%d,%d)", - (int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8); -#endif - } - return (data); -} -/* crypto/bn/bn_rand.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" -// #include "rand.h" - -static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) -{ - unsigned char *buf = NULL; - int ret = 0, bit, bytes, mask; - time_t tim; - - if (bits == 0) { - if (top != -1 || bottom != 0) - goto toosmall; - BN_zero(rnd); - return 1; - } - if (bits < 0 || (bits == 1 && top > 0)) - goto toosmall; - - bytes = (bits + 7) / 8; - bit = (bits - 1) % 8; - mask = 0xff << (bit + 1); - - buf = (unsigned char *)OPENSSL_malloc(bytes); - if (buf == NULL) { - BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* make a random number and set the top and bottom bits */ - time(&tim); - RAND_add(&tim, sizeof(tim), 0.0); - - /* We ignore the value of pseudorand and always call RAND_bytes */ - if (RAND_bytes(buf, bytes) <= 0) - goto err; - -#if 1 - if (pseudorand == 2) { - /* - * generate patterns that are more likely to trigger BN library bugs - */ - int i; - unsigned char c; - - for (i = 0; i < bytes; i++) { - if (RAND_pseudo_bytes(&c, 1) < 0) - goto err; - if (c >= 128 && i > 0) - buf[i] = buf[i - 1]; - else if (c < 42) - buf[i] = 0; - else if (c < 84) - buf[i] = 255; - } - } -#endif - - if (top >= 0) { - if (top) { - if (bit == 0) { - buf[0] = 1; - buf[1] |= 0x80; - } else { - buf[0] |= (3 << (bit - 1)); - } - } else { - buf[0] |= (1 << bit); - } - } - buf[0] &= ~mask; - if (bottom) /* set bottom bit if requested */ - buf[bytes - 1] |= 1; - if (!BN_bin2bn(buf, bytes, rnd)) - goto err; - ret = 1; - err: - if (buf != NULL) { - OPENSSL_cleanse(buf, bytes); - OPENSSL_free(buf); - } - bn_check_top(rnd); - return (ret); - -toosmall: - BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL); - return 0; -} - -int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) -{ - return bnrand(0, rnd, bits, top, bottom); -} - -int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) -{ - return bnrand(1, rnd, bits, top, bottom); -} - -#if 1 -int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) -{ - return bnrand(2, rnd, bits, top, bottom); -} -#endif - -/* random number r: 0 <= r < range */ -static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range) -{ - int (*bn_rand) (BIGNUM *, int, int, int) = - pseudo ? BN_pseudo_rand : BN_rand; - int n; - int count = 100; - - if (range->neg || BN_is_zero(range)) { - BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE); - return 0; - } - - n = BN_num_bits(range); /* n > 0 */ - - /* BN_is_bit_set(range, n - 1) always holds */ - - if (n == 1) - BN_zero(r); - else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { - /* - * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer - * than range - */ - do { - if (!bn_rand(r, n + 1, -1, 0)) - return 0; - /* - * If r < 3*range, use r := r MOD range (which is either r, r - - * range, or r - 2*range). Otherwise, iterate once more. Since - * 3*range = 11..._2, each iteration succeeds with probability >= - * .75. - */ - if (BN_cmp(r, range) >= 0) { - if (!BN_sub(r, r, range)) - return 0; - if (BN_cmp(r, range) >= 0) - if (!BN_sub(r, r, range)) - return 0; - } - - if (!--count) { - BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS); - return 0; - } - - } - while (BN_cmp(r, range) >= 0); - } else { - do { - /* range = 11..._2 or range = 101..._2 */ - if (!bn_rand(r, n, -1, 0)) - return 0; - - if (!--count) { - BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS); - return 0; - } - } - while (BN_cmp(r, range) >= 0); - } - - bn_check_top(r); - return 1; -} - -int BN_rand_range(BIGNUM *r, const BIGNUM *range) -{ - return bn_rand_range(0, r, range); -} - -int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) -{ - return bn_rand_range(1, r, range); -} -/* crypto/bn/bn_recp.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -void BN_RECP_CTX_init(BN_RECP_CTX *recp) -{ - BN_init(&(recp->N)); - BN_init(&(recp->Nr)); - recp->num_bits = 0; - recp->shift = 0; - recp->flags = 0; -} - -BN_RECP_CTX *BN_RECP_CTX_new(void) -{ - BN_RECP_CTX *ret; - - if ((ret = (BN_RECP_CTX *)OPENSSL_malloc(sizeof(BN_RECP_CTX))) == NULL) - return (NULL); - - BN_RECP_CTX_init(ret); - ret->flags = BN_FLG_MALLOCED; - return (ret); -} - -void BN_RECP_CTX_free(BN_RECP_CTX *recp) -{ - if (recp == NULL) - return; - - BN_free(&(recp->N)); - BN_free(&(recp->Nr)); - if (recp->flags & BN_FLG_MALLOCED) - OPENSSL_free(recp); -} - -int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) -{ - if (!BN_copy(&(recp->N), d)) - return 0; - BN_zero(&(recp->Nr)); - recp->num_bits = BN_num_bits(d); - recp->shift = 0; - return (1); -} - -int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, - BN_RECP_CTX *recp, BN_CTX *ctx) -{ - int ret = 0; - BIGNUM *a; - const BIGNUM *ca; - - BN_CTX_start(ctx); - if ((a = BN_CTX_get(ctx)) == NULL) - goto err; - if (y != NULL) { - if (x == y) { - if (!BN_sqr(a, x, ctx)) - goto err; - } else { - if (!BN_mul(a, x, y, ctx)) - goto err; - } - ca = a; - } else - ca = x; /* Just do the mod */ - - ret = BN_div_recp(NULL, r, ca, recp, ctx); - err: - BN_CTX_end(ctx); - bn_check_top(r); - return (ret); -} - -int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, - BN_RECP_CTX *recp, BN_CTX *ctx) -{ - int i, j, ret = 0; - BIGNUM *a, *b, *d, *r; - - BN_CTX_start(ctx); - a = BN_CTX_get(ctx); - b = BN_CTX_get(ctx); - if (dv != NULL) - d = dv; - else - d = BN_CTX_get(ctx); - if (rem != NULL) - r = rem; - else - r = BN_CTX_get(ctx); - if (a == NULL || b == NULL || d == NULL || r == NULL) - goto err; - - if (BN_ucmp(m, &(recp->N)) < 0) { - BN_zero(d); - if (!BN_copy(r, m)) { - BN_CTX_end(ctx); - return 0; - } - BN_CTX_end(ctx); - return (1); - } - - /* - * We want the remainder Given input of ABCDEF / ab we need multiply - * ABCDEF by 3 digests of the reciprocal of ab - */ - - /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */ - i = BN_num_bits(m); - j = recp->num_bits << 1; - if (j > i) - i = j; - - /* Nr := round(2^i / N) */ - if (i != recp->shift) - recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx); - /* BN_reciprocal could have returned -1 for an error */ - if (recp->shift == -1) - goto err; - - /*- - * d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))| - * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))| - * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)| - * = |m/N| - */ - if (!BN_rshift(a, m, recp->num_bits)) - goto err; - if (!BN_mul(b, a, &(recp->Nr), ctx)) - goto err; - if (!BN_rshift(d, b, i - recp->num_bits)) - goto err; - d->neg = 0; - - if (!BN_mul(b, &(recp->N), d, ctx)) - goto err; - if (!BN_usub(r, m, b)) - goto err; - r->neg = 0; - -#if 1 - j = 0; - while (BN_ucmp(r, &(recp->N)) >= 0) { - if (j++ > 2) { - BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL); - goto err; - } - if (!BN_usub(r, r, &(recp->N))) - goto err; - if (!BN_add_word(d, 1)) - goto err; - } -#endif - - r->neg = BN_is_zero(r) ? 0 : m->neg; - d->neg = m->neg ^ recp->N.neg; - ret = 1; - err: - BN_CTX_end(ctx); - bn_check_top(dv); - bn_check_top(rem); - return (ret); -} - -/* - * len is the expected size of the result We actually calculate with an extra - * word of precision, so we can do faster division if the remainder is not - * required. - */ -/* r := 2^len / m */ -int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) -{ - int ret = -1; - BIGNUM *t; - - BN_CTX_start(ctx); - if ((t = BN_CTX_get(ctx)) == NULL) - goto err; - - if (!BN_set_bit(t, len)) - goto err; - - if (!BN_div(r, NULL, t, m, ctx)) - goto err; - - ret = len; - err: - bn_check_top(r); - BN_CTX_end(ctx); - return (ret); -} -/* crypto/bn/bn_shift.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -int BN_lshift1(BIGNUM *r, const BIGNUM *a) -{ - register BN_ULONG *ap, *rp, t, c; - int i; - - bn_check_top(r); - bn_check_top(a); - - if (r != a) { - r->neg = a->neg; - if (bn_wexpand(r, a->top + 1) == NULL) - return (0); - r->top = a->top; - } else { - if (bn_wexpand(r, a->top + 1) == NULL) - return (0); - } - ap = a->d; - rp = r->d; - c = 0; - for (i = 0; i < a->top; i++) { - t = *(ap++); - *(rp++) = ((t << 1) | c) & BN_MASK2; - c = (t & BN_TBIT) ? 1 : 0; - } - if (c) { - *rp = 1; - r->top++; - } - bn_check_top(r); - return (1); -} - -int BN_rshift1(BIGNUM *r, const BIGNUM *a) -{ - BN_ULONG *ap, *rp, t, c; - int i, j; - - bn_check_top(r); - bn_check_top(a); - - if (BN_is_zero(a)) { - BN_zero(r); - return (1); - } - i = a->top; - ap = a->d; - j = i - (ap[i - 1] == 1); - if (a != r) { - if (bn_wexpand(r, j) == NULL) - return (0); - r->neg = a->neg; - } - rp = r->d; - t = ap[--i]; - c = (t & 1) ? BN_TBIT : 0; - if (t >>= 1) - rp[i] = t; - while (i > 0) { - t = ap[--i]; - rp[i] = ((t >> 1) & BN_MASK2) | c; - c = (t & 1) ? BN_TBIT : 0; - } - r->top = j; - bn_check_top(r); - return (1); -} - -int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) -{ - int i, nw, lb, rb; - BN_ULONG *t, *f; - BN_ULONG l; - - bn_check_top(r); - bn_check_top(a); - - if (n < 0) { - BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT); - return 0; - } - - r->neg = a->neg; - nw = n / BN_BITS2; - if (bn_wexpand(r, a->top + nw + 1) == NULL) - return (0); - lb = n % BN_BITS2; - rb = BN_BITS2 - lb; - f = a->d; - t = r->d; - t[a->top + nw] = 0; - if (lb == 0) - for (i = a->top - 1; i >= 0; i--) - t[nw + i] = f[i]; - else - for (i = a->top - 1; i >= 0; i--) { - l = f[i]; - t[nw + i + 1] |= (l >> rb) & BN_MASK2; - t[nw + i] = (l << lb) & BN_MASK2; - } - memset(t, 0, nw * sizeof(t[0])); - /* - * for (i=0; itop = a->top + nw + 1; - bn_correct_top(r); - bn_check_top(r); - return (1); -} - -int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) -{ - int i, j, nw, lb, rb; - BN_ULONG *t, *f; - BN_ULONG l, tmp; - - bn_check_top(r); - bn_check_top(a); - - if (n < 0) { - BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT); - return 0; - } - - nw = n / BN_BITS2; - rb = n % BN_BITS2; - lb = BN_BITS2 - rb; - if (nw >= a->top || a->top == 0) { - BN_zero(r); - return (1); - } - i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2; - if (r != a) { - r->neg = a->neg; - if (bn_wexpand(r, i) == NULL) - return (0); - } else { - if (n == 0) - return 1; /* or the copying loop will go berserk */ - } - - f = &(a->d[nw]); - t = r->d; - j = a->top - nw; - r->top = i; - - if (rb == 0) { - for (i = j; i != 0; i--) - *(t++) = *(f++); - } else { - l = *(f++); - for (i = j - 1; i != 0; i--) { - tmp = (l >> rb) & BN_MASK2; - l = *(f++); - *(t++) = (tmp | (l << lb)) & BN_MASK2; - } - if ((l = (l >> rb) & BN_MASK2)) - *(t) = l; - } - bn_check_top(r); - return (1); -} -/* crypto/bn/bn_sqr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -/* r must not be a */ -/* - * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 - */ -int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) -{ - int ret = bn_sqr_fixed_top(r, a, ctx); - - bn_correct_top(r); - bn_check_top(r); - - return ret; -} - -int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) -{ - int max, al; - int ret = 0; - BIGNUM *tmp, *rr; - -#ifdef BN_COUNT - fprintf(stderr, "BN_sqr %d * %d\n", a->top, a->top); -#endif - bn_check_top(a); - - al = a->top; - if (al <= 0) { - r->top = 0; - r->neg = 0; - return 1; - } - - BN_CTX_start(ctx); - rr = (a != r) ? r : BN_CTX_get(ctx); - tmp = BN_CTX_get(ctx); - if (!rr || !tmp) - goto err; - - max = 2 * al; /* Non-zero (from above) */ - if (bn_wexpand(rr, max) == NULL) - goto err; - - if (al == 4) { -#ifndef BN_SQR_COMBA - BN_ULONG t[8]; - bn_sqr_normal(rr->d, a->d, 4, t); -#else - bn_sqr_comba4(rr->d, a->d); -#endif - } else if (al == 8) { -#ifndef BN_SQR_COMBA - BN_ULONG t[16]; - bn_sqr_normal(rr->d, a->d, 8, t); -#else - bn_sqr_comba8(rr->d, a->d); -#endif - } else { -#if defined(BN_RECURSION) - if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) { - BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2]; - bn_sqr_normal(rr->d, a->d, al, t); - } else { - int j, k; - - j = BN_num_bits_word((BN_ULONG)al); - j = 1 << (j - 1); - k = j + j; - if (al == j) { - if (bn_wexpand(tmp, k * 2) == NULL) - goto err; - bn_sqr_recursive(rr->d, a->d, al, tmp->d); - } else { - if (bn_wexpand(tmp, max) == NULL) - goto err; - bn_sqr_normal(rr->d, a->d, al, tmp->d); - } - } -#else - if (bn_wexpand(tmp, max) == NULL) - goto err; - bn_sqr_normal(rr->d, a->d, al, tmp->d); -#endif - } - - rr->neg = 0; - rr->top = max; - rr->flags |= BN_FLG_FIXED_TOP; - if (r != rr && BN_copy(r, rr) == NULL) - goto err; - - ret = 1; - err: - bn_check_top(rr); - bn_check_top(tmp); - BN_CTX_end(ctx); - return (ret); -} - -/* tmp must have 2*n words */ -void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp) -{ - int i, j, max; - const BN_ULONG *ap; - BN_ULONG *rp; - - max = n * 2; - ap = a; - rp = r; - rp[0] = rp[max - 1] = 0; - rp++; - j = n; - - if (--j > 0) { - ap++; - rp[j] = bn_mul_words(rp, ap, j, ap[-1]); - rp += 2; - } - - for (i = n - 2; i > 0; i--) { - j--; - ap++; - rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]); - rp += 2; - } - - bn_add_words(r, r, r, max); - - /* There will not be a carry */ - - bn_sqr_words(tmp, a, n); - - bn_add_words(r, r, tmp, max); -} - -#ifdef BN_RECURSION -/*- - * r is 2*n words in size, - * a and b are both n words in size. (There's not actually a 'b' here ...) - * n must be a power of 2. - * We multiply and return the result. - * t must be 2*n words in size - * We calculate - * a[0]*b[0] - * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) - * a[1]*b[1] - */ -void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t) -{ - int n = n2 / 2; - int zero, c1; - BN_ULONG ln, lo, *p; - -# ifdef BN_COUNT - fprintf(stderr, " bn_sqr_recursive %d * %d\n", n2, n2); -# endif - if (n2 == 4) { -# ifndef BN_SQR_COMBA - bn_sqr_normal(r, a, 4, t); -# else - bn_sqr_comba4(r, a); -# endif - return; - } else if (n2 == 8) { -# ifndef BN_SQR_COMBA - bn_sqr_normal(r, a, 8, t); -# else - bn_sqr_comba8(r, a); -# endif - return; - } - if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) { - bn_sqr_normal(r, a, n2, t); - return; - } - /* r=(a[0]-a[1])*(a[1]-a[0]) */ - c1 = bn_cmp_words(a, &(a[n]), n); - zero = 0; - if (c1 > 0) - bn_sub_words(t, a, &(a[n]), n); - else if (c1 < 0) - bn_sub_words(t, &(a[n]), a, n); - else - zero = 1; - - /* The result will always be negative unless it is zero */ - p = &(t[n2 * 2]); - - if (!zero) - bn_sqr_recursive(&(t[n2]), t, n, p); - else - memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG)); - bn_sqr_recursive(r, a, n, p); - bn_sqr_recursive(&(r[n2]), &(a[n]), n, p); - - /*- - * t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero - * r[10] holds (a[0]*b[0]) - * r[32] holds (b[1]*b[1]) - */ - - c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); - - /* t[32] is negative */ - c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); - - /*- - * t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1]) - * r[10] holds (a[0]*a[0]) - * r[32] holds (a[1]*a[1]) - * c1 holds the carry bits - */ - c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); - if (c1) { - p = &(r[n + n2]); - lo = *p; - ln = (lo + c1) & BN_MASK2; - *p = ln; - - /* - * The overflow will stop before we over write words we should not - * overwrite - */ - if (ln < (BN_ULONG)c1) { - do { - p++; - lo = *p; - ln = (lo + 1) & BN_MASK2; - *p = ln; - } while (ln == 0); - } - } -} -#endif -/* crypto/bn/bn_sqrt.c */ -/* - * Written by Lenka Fibikova and Bodo - * Moeller for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "bn_lcl.h" - -BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) -/* - * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks - * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number - * Theory", algorithm 1.5.1). 'p' must be prime! - */ -{ - BIGNUM *ret = in; - int err = 1; - int r; - BIGNUM *A, *b, *q, *t, *x, *y; - int e, i, j; - - if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { - if (BN_abs_is_word(p, 2)) { - if (ret == NULL) - ret = BN_new(); - if (ret == NULL) - goto end; - if (!BN_set_word(ret, BN_is_bit_set(a, 0))) { - if (ret != in) - BN_free(ret); - return NULL; - } - bn_check_top(ret); - return ret; - } - - BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); - return (NULL); - } - - if (BN_is_zero(a) || BN_is_one(a)) { - if (ret == NULL) - ret = BN_new(); - if (ret == NULL) - goto end; - if (!BN_set_word(ret, BN_is_one(a))) { - if (ret != in) - BN_free(ret); - return NULL; - } - bn_check_top(ret); - return ret; - } - - BN_CTX_start(ctx); - A = BN_CTX_get(ctx); - b = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - t = BN_CTX_get(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - if (y == NULL) - goto end; - - if (ret == NULL) - ret = BN_new(); - if (ret == NULL) - goto end; - - /* A = a mod p */ - if (!BN_nnmod(A, a, p, ctx)) - goto end; - - /* now write |p| - 1 as 2^e*q where q is odd */ - e = 1; - while (!BN_is_bit_set(p, e)) - e++; - /* we'll set q later (if needed) */ - - if (e == 1) { - /*- - * The easy case: (|p|-1)/2 is odd, so 2 has an inverse - * modulo (|p|-1)/2, and square roots can be computed - * directly by modular exponentiation. - * We have - * 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2), - * so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1. - */ - if (!BN_rshift(q, p, 2)) - goto end; - q->neg = 0; - if (!BN_add_word(q, 1)) - goto end; - if (!BN_mod_exp(ret, A, q, p, ctx)) - goto end; - err = 0; - goto vrfy; - } - - if (e == 2) { - /*- - * |p| == 5 (mod 8) - * - * In this case 2 is always a non-square since - * Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime. - * So if a really is a square, then 2*a is a non-square. - * Thus for - * b := (2*a)^((|p|-5)/8), - * i := (2*a)*b^2 - * we have - * i^2 = (2*a)^((1 + (|p|-5)/4)*2) - * = (2*a)^((p-1)/2) - * = -1; - * so if we set - * x := a*b*(i-1), - * then - * x^2 = a^2 * b^2 * (i^2 - 2*i + 1) - * = a^2 * b^2 * (-2*i) - * = a*(-i)*(2*a*b^2) - * = a*(-i)*i - * = a. - * - * (This is due to A.O.L. Atkin, - * , - * November 1992.) - */ - - /* t := 2*a */ - if (!BN_mod_lshift1_quick(t, A, p)) - goto end; - - /* b := (2*a)^((|p|-5)/8) */ - if (!BN_rshift(q, p, 3)) - goto end; - q->neg = 0; - if (!BN_mod_exp(b, t, q, p, ctx)) - goto end; - - /* y := b^2 */ - if (!BN_mod_sqr(y, b, p, ctx)) - goto end; - - /* t := (2*a)*b^2 - 1 */ - if (!BN_mod_mul(t, t, y, p, ctx)) - goto end; - if (!BN_sub_word(t, 1)) - goto end; - - /* x = a*b*t */ - if (!BN_mod_mul(x, A, b, p, ctx)) - goto end; - if (!BN_mod_mul(x, x, t, p, ctx)) - goto end; - - if (!BN_copy(ret, x)) - goto end; - err = 0; - goto vrfy; - } - - /* - * e > 2, so we really have to use the Tonelli/Shanks algorithm. First, - * find some y that is not a square. - */ - if (!BN_copy(q, p)) - goto end; /* use 'q' as temp */ - q->neg = 0; - i = 2; - do { - /* - * For efficiency, try small numbers first; if this fails, try random - * numbers. - */ - if (i < 22) { - if (!BN_set_word(y, i)) - goto end; - } else { - if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) - goto end; - if (BN_ucmp(y, p) >= 0) { - if (!(p->neg ? BN_add : BN_sub) (y, y, p)) - goto end; - } - /* now 0 <= y < |p| */ - if (BN_is_zero(y)) - if (!BN_set_word(y, i)) - goto end; - } - - r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */ - if (r < -1) - goto end; - if (r == 0) { - /* m divides p */ - BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); - goto end; - } - } - while (r == 1 && ++i < 82); - - if (r != -1) { - /* - * Many rounds and still no non-square -- this is more likely a bug - * than just bad luck. Even if p is not prime, we should have found - * some y such that r == -1. - */ - BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS); - goto end; - } - - /* Here's our actual 'q': */ - if (!BN_rshift(q, q, e)) - goto end; - - /* - * Now that we have some non-square, we can find an element of order 2^e - * by computing its q'th power. - */ - if (!BN_mod_exp(y, y, q, p, ctx)) - goto end; - if (BN_is_one(y)) { - BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); - goto end; - } - - /*- - * Now we know that (if p is indeed prime) there is an integer - * k, 0 <= k < 2^e, such that - * - * a^q * y^k == 1 (mod p). - * - * As a^q is a square and y is not, k must be even. - * q+1 is even, too, so there is an element - * - * X := a^((q+1)/2) * y^(k/2), - * - * and it satisfies - * - * X^2 = a^q * a * y^k - * = a, - * - * so it is the square root that we are looking for. - */ - - /* t := (q-1)/2 (note that q is odd) */ - if (!BN_rshift1(t, q)) - goto end; - - /* x := a^((q-1)/2) */ - if (BN_is_zero(t)) { /* special case: p = 2^e + 1 */ - if (!BN_nnmod(t, A, p, ctx)) - goto end; - if (BN_is_zero(t)) { - /* special case: a == 0 (mod p) */ - BN_zero(ret); - err = 0; - goto end; - } else if (!BN_one(x)) - goto end; - } else { - if (!BN_mod_exp(x, A, t, p, ctx)) - goto end; - if (BN_is_zero(x)) { - /* special case: a == 0 (mod p) */ - BN_zero(ret); - err = 0; - goto end; - } - } - - /* b := a*x^2 (= a^q) */ - if (!BN_mod_sqr(b, x, p, ctx)) - goto end; - if (!BN_mod_mul(b, b, A, p, ctx)) - goto end; - - /* x := a*x (= a^((q+1)/2)) */ - if (!BN_mod_mul(x, x, A, p, ctx)) - goto end; - - while (1) { - /*- - * Now b is a^q * y^k for some even k (0 <= k < 2^E - * where E refers to the original value of e, which we - * don't keep in a variable), and x is a^((q+1)/2) * y^(k/2). - * - * We have a*b = x^2, - * y^2^(e-1) = -1, - * b^2^(e-1) = 1. - */ - - if (BN_is_one(b)) { - if (!BN_copy(ret, x)) - goto end; - err = 0; - goto vrfy; - } - - /* find smallest i such that b^(2^i) = 1 */ - i = 1; - if (!BN_mod_sqr(t, b, p, ctx)) - goto end; - while (!BN_is_one(t)) { - i++; - if (i == e) { - BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); - goto end; - } - if (!BN_mod_mul(t, t, t, p, ctx)) - goto end; - } - - /* t := y^2^(e - i - 1) */ - if (!BN_copy(t, y)) - goto end; - for (j = e - i - 1; j > 0; j--) { - if (!BN_mod_sqr(t, t, p, ctx)) - goto end; - } - if (!BN_mod_mul(y, t, t, p, ctx)) - goto end; - if (!BN_mod_mul(x, x, t, p, ctx)) - goto end; - if (!BN_mod_mul(b, b, y, p, ctx)) - goto end; - e = i; - } - - vrfy: - if (!err) { - /* - * verify the result -- the input might have been not a square (test - * added in 0.9.8) - */ - - if (!BN_mod_sqr(x, ret, p, ctx)) - err = 1; - - if (!err && 0 != BN_cmp(x, A)) { - BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); - err = 1; - } - } - - end: - if (err) { - if (ret != NULL && ret != in) { - BN_clear_free(ret); - } - ret = NULL; - } - BN_CTX_end(ctx); - bn_check_top(ret); - return ret; -} -/* crypto/bn/bn_word.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn_lcl.h" - -BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) -{ -#ifndef BN_LLONG - BN_ULONG ret = 0; -#else - BN_ULLONG ret = 0; -#endif - int i; - - if (w == 0) - return (BN_ULONG)-1; - -#ifndef BN_LLONG - /* - * If |w| is too long and we don't have BN_ULLONG then we need to fall - * back to using BN_div_word - */ - if (w > ((BN_ULONG)1 << BN_BITS4)) { - BIGNUM *tmp = BN_dup(a); - if (tmp == NULL) - return (BN_ULONG)-1; - - ret = BN_div_word(tmp, w); - BN_free(tmp); - - return ret; - } -#endif - - bn_check_top(a); - w &= BN_MASK2; - for (i = a->top - 1; i >= 0; i--) { -#ifndef BN_LLONG - /* - * We can assume here that | w <= ((BN_ULONG)1 << BN_BITS4) | and so - * | ret < ((BN_ULONG)1 << BN_BITS4) | and therefore the shifts here are - * safe and will not overflow - */ - ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w; - ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w; -#else - ret = (BN_ULLONG) (((ret << (BN_ULLONG) BN_BITS2) | a->d[i]) % - (BN_ULLONG) w); -#endif - } - return ((BN_ULONG)ret); -} - -BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) -{ - BN_ULONG ret = 0; - int i, j; - - bn_check_top(a); - w &= BN_MASK2; - - if (!w) - /* actually this an error (division by zero) */ - return (BN_ULONG)-1; - if (a->top == 0) - return 0; - - /* normalize input (so bn_div_words doesn't complain) */ - j = BN_BITS2 - BN_num_bits_word(w); - w <<= j; - if (!BN_lshift(a, a, j)) - return (BN_ULONG)-1; - - for (i = a->top - 1; i >= 0; i--) { - BN_ULONG l, d; - - l = a->d[i]; - d = bn_div_words(ret, l, w); - ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2; - a->d[i] = d; - } - if ((a->top > 0) && (a->d[a->top - 1] == 0)) - a->top--; - ret >>= j; - bn_check_top(a); - return (ret); -} - -int BN_add_word(BIGNUM *a, BN_ULONG w) -{ - BN_ULONG l; - int i; - - bn_check_top(a); - w &= BN_MASK2; - - /* degenerate case: w is zero */ - if (!w) - return 1; - /* degenerate case: a is zero */ - if (BN_is_zero(a)) - return BN_set_word(a, w); - /* handle 'a' when negative */ - if (a->neg) { - a->neg = 0; - i = BN_sub_word(a, w); - if (!BN_is_zero(a)) - a->neg = !(a->neg); - return (i); - } - for (i = 0; w != 0 && i < a->top; i++) { - a->d[i] = l = (a->d[i] + w) & BN_MASK2; - w = (w > l) ? 1 : 0; - } - if (w && i == a->top) { - if (bn_wexpand(a, a->top + 1) == NULL) - return 0; - a->top++; - a->d[i] = w; - } - bn_check_top(a); - return (1); -} - -int BN_sub_word(BIGNUM *a, BN_ULONG w) -{ - int i; - - bn_check_top(a); - w &= BN_MASK2; - - /* degenerate case: w is zero */ - if (!w) - return 1; - /* degenerate case: a is zero */ - if (BN_is_zero(a)) { - i = BN_set_word(a, w); - if (i != 0) - BN_set_negative(a, 1); - return i; - } - /* handle 'a' when negative */ - if (a->neg) { - a->neg = 0; - i = BN_add_word(a, w); - a->neg = 1; - return (i); - } - - if ((a->top == 1) && (a->d[0] < w)) { - a->d[0] = w - a->d[0]; - a->neg = 1; - return (1); - } - i = 0; - for (;;) { - if (a->d[i] >= w) { - a->d[i] -= w; - break; - } else { - a->d[i] = (a->d[i] - w) & BN_MASK2; - i++; - w = 1; - } - } - if ((a->d[i] == 0) && (i == (a->top - 1))) - a->top--; - bn_check_top(a); - return (1); -} - -int BN_mul_word(BIGNUM *a, BN_ULONG w) -{ - BN_ULONG ll; - - bn_check_top(a); - w &= BN_MASK2; - if (a->top) { - if (w == 0) - BN_zero(a); - else { - ll = bn_mul_words(a->d, a->d, a->top, w); - if (ll) { - if (bn_wexpand(a, a->top + 1) == NULL) - return (0); - a->d[a->top++] = ll; - } - } - } - bn_check_top(a); - return (1); -} -/* bn_x931p.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2005. - */ -/* ==================================================================== - * Copyright (c) 2005-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "bn.h" - -/* X9.31 routines for prime derivation */ - -/* - * X9.31 prime derivation. This is used to generate the primes pi (p1, p2, - * q1, q2) from a parameter Xpi by checking successive odd integers. - */ - -static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, - BN_GENCB *cb) -{ - int i = 0; - if (!BN_copy(pi, Xpi)) - return 0; - if (!BN_is_odd(pi) && !BN_add_word(pi, 1)) - return 0; - for (;;) { - i++; - BN_GENCB_call(cb, 0, i); - /* NB 27 MR is specificed in X9.31 */ - if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb)) - break; - if (!BN_add_word(pi, 2)) - return 0; - } - BN_GENCB_call(cb, 2, i); - return 1; -} - -/* - * This is the main X9.31 prime derivation function. From parameters Xp1, Xp2 - * and Xp derive the prime p. If the parameters p1 or p2 are not NULL they - * will be returned too: this is needed for testing. - */ - -int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, - const BIGNUM *Xp, const BIGNUM *Xp1, - const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, - BN_GENCB *cb) -{ - int ret = 0; - - BIGNUM *t, *p1p2, *pm1; - - /* Only even e supported */ - if (!BN_is_odd(e)) - return 0; - - BN_CTX_start(ctx); - if (!p1) - p1 = BN_CTX_get(ctx); - - if (!p2) - p2 = BN_CTX_get(ctx); - - t = BN_CTX_get(ctx); - - p1p2 = BN_CTX_get(ctx); - - pm1 = BN_CTX_get(ctx); - - if (!bn_x931_derive_pi(p1, Xp1, ctx, cb)) - goto err; - - if (!bn_x931_derive_pi(p2, Xp2, ctx, cb)) - goto err; - - if (!BN_mul(p1p2, p1, p2, ctx)) - goto err; - - /* First set p to value of Rp */ - - if (!BN_mod_inverse(p, p2, p1, ctx)) - goto err; - - if (!BN_mul(p, p, p2, ctx)) - goto err; - - if (!BN_mod_inverse(t, p1, p2, ctx)) - goto err; - - if (!BN_mul(t, t, p1, ctx)) - goto err; - - if (!BN_sub(p, p, t)) - goto err; - - if (p->neg && !BN_add(p, p, p1p2)) - goto err; - - /* p now equals Rp */ - - if (!BN_mod_sub(p, p, Xp, p1p2, ctx)) - goto err; - - if (!BN_add(p, p, Xp)) - goto err; - - /* p now equals Yp0 */ - - for (;;) { - int i = 1; - BN_GENCB_call(cb, 0, i++); - if (!BN_copy(pm1, p)) - goto err; - if (!BN_sub_word(pm1, 1)) - goto err; - if (!BN_gcd(t, pm1, e, ctx)) - goto err; - if (BN_is_one(t) - /* - * X9.31 specifies 8 MR and 1 Lucas test or any prime test - * offering similar or better guarantees 50 MR is considerably - * better. - */ - && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb)) - break; - if (!BN_add(p, p, p1p2)) - goto err; - } - - BN_GENCB_call(cb, 3, 0); - - ret = 1; - - err: - - BN_CTX_end(ctx); - - return ret; -} - -/* - * Generate pair of paramters Xp, Xq for X9.31 prime generation. Note: nbits - * paramter is sum of number of bits in both. - */ - -int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) -{ - BIGNUM *t; - int i; - /* - * Number of bits for each prime is of the form 512+128s for s = 0, 1, - * ... - */ - if ((nbits < 1024) || (nbits & 0xff)) - return 0; - nbits >>= 1; - /* - * The random value Xp must be between sqrt(2) * 2^(nbits-1) and 2^nbits - * - 1. By setting the top two bits we ensure that the lower bound is - * exceeded. - */ - if (!BN_rand(Xp, nbits, 1, 0)) - goto err; - - BN_CTX_start(ctx); - t = BN_CTX_get(ctx); - if (t == NULL) - goto err; - - for (i = 0; i < 1000; i++) { - if (!BN_rand(Xq, nbits, 1, 0)) - goto err; - - /* Check that |Xp - Xq| > 2^(nbits - 100) */ - if (!BN_sub(t, Xp, Xq)) - goto err; - if (BN_num_bits(t) > (nbits - 100)) - break; - } - - BN_CTX_end(ctx); - - if (i < 1000) - return 1; - - return 0; - - err: - BN_CTX_end(ctx); - return 0; -} - -/* - * Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 and - * Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL the - * relevant parameter will be stored in it. Due to the fact that |Xp - Xq| > - * 2^(nbits - 100) must be satisfied Xp and Xq are generated using the - * previous function and supplied as input. - */ - -int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, - BIGNUM *Xp1, BIGNUM *Xp2, - const BIGNUM *Xp, - const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb) -{ - int ret = 0; - - BN_CTX_start(ctx); - if (Xp1 == NULL) - Xp1 = BN_CTX_get(ctx); - if (Xp2 == NULL) - Xp2 = BN_CTX_get(ctx); - if (Xp1 == NULL || Xp2 == NULL) - goto error; - - if (!BN_rand(Xp1, 101, 0, 0)) - goto error; - if (!BN_rand(Xp2, 101, 0, 0)) - goto error; - if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb)) - goto error; - - ret = 1; - - error: - BN_CTX_end(ctx); - - return ret; - -} diff --git a/Sources/COpenSSL/bn_int.h b/Sources/COpenSSL/bn_int.h deleted file mode 100644 index a552cc20..00000000 --- a/Sources/COpenSSL/bn_int.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Some BIGNUM functions assume most significant limb to be non-zero, which - * is customarily arranged by bn_correct_top. Output from below functions - * is not processed with bn_correct_top, and for this reason it may not be - * returned out of public API. It may only be passed internally into other - * functions known to support non-minimal or zero-padded BIGNUMs. - */ -int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - BN_MONT_CTX *mont, BN_CTX *ctx); -int bn_from_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, - BN_CTX *ctx); -int bn_to_mont_fixed_top(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, - BN_CTX *ctx); -int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *m); -int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, - const BIGNUM *m); -int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); -int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); - -int bn_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen); diff --git a/Sources/COpenSSL/bn_lcl.h b/Sources/COpenSSL/bn_lcl.h deleted file mode 100644 index 86f86e3a..00000000 --- a/Sources/COpenSSL/bn_lcl.h +++ /dev/null @@ -1,538 +0,0 @@ -/* crypto/bn/bn_lcl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_BN_LCL_H -# define HEADER_BN_LCL_H - -# include "bn.h" -# include "bn_int.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/*- - * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions - * - * - * For window size 'w' (w >= 2) and a random 'b' bits exponent, - * the number of multiplications is a constant plus on average - * - * 2^(w-1) + (b-w)/(w+1); - * - * here 2^(w-1) is for precomputing the table (we actually need - * entries only for windows that have the lowest bit set), and - * (b-w)/(w+1) is an approximation for the expected number of - * w-bit windows, not counting the first one. - * - * Thus we should use - * - * w >= 6 if b > 671 - * w = 5 if 671 > b > 239 - * w = 4 if 239 > b > 79 - * w = 3 if 79 > b > 23 - * w <= 2 if 23 > b - * - * (with draws in between). Very small exponents are often selected - * with low Hamming weight, so we use w = 1 for b <= 23. - */ -# if 1 -# define BN_window_bits_for_exponent_size(b) \ - ((b) > 671 ? 6 : \ - (b) > 239 ? 5 : \ - (b) > 79 ? 4 : \ - (b) > 23 ? 3 : 1) -# else -/* - * Old SSLeay/OpenSSL table. Maximum window size was 5, so this table differs - * for b==1024; but it coincides for other interesting values (b==160, - * b==512). - */ -# define BN_window_bits_for_exponent_size(b) \ - ((b) > 255 ? 5 : \ - (b) > 127 ? 4 : \ - (b) > 17 ? 3 : 1) -# endif - -/* - * BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache - * line width of the target processor is at least the following value. - */ -# define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH ( 64 ) -# define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1) - -/* - * Window sizes optimized for fixed window size modular exponentiation - * algorithm (BN_mod_exp_mont_consttime). To achieve the security goals of - * BN_mode_exp_mont_consttime, the maximum size of the window must not exceed - * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). Window size thresholds are - * defined for cache line sizes of 32 and 64, cache line sizes where - * log_2(32)=5 and log_2(64)=6 respectively. A window size of 7 should only be - * used on processors that have a 128 byte or greater cache line size. - */ -# if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64 - -# define BN_window_bits_for_ctime_exponent_size(b) \ - ((b) > 937 ? 6 : \ - (b) > 306 ? 5 : \ - (b) > 89 ? 4 : \ - (b) > 22 ? 3 : 1) -# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6) - -# elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32 - -# define BN_window_bits_for_ctime_exponent_size(b) \ - ((b) > 306 ? 5 : \ - (b) > 89 ? 4 : \ - (b) > 22 ? 3 : 1) -# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5) - -# endif - -/* Pentium pro 16,16,16,32,64 */ -/* Alpha 16,16,16,16.64 */ -# define BN_MULL_SIZE_NORMAL (16)/* 32 */ -# define BN_MUL_RECURSIVE_SIZE_NORMAL (16)/* 32 less than */ -# define BN_SQR_RECURSIVE_SIZE_NORMAL (16)/* 32 */ -# define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32)/* 32 */ -# define BN_MONT_CTX_SET_SIZE_WORD (64)/* 32 */ - -/* - * 2011-02-22 SMS. In various places, a size_t variable or a type cast to - * size_t was used to perform integer-only operations on pointers. This - * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t - * is still only 32 bits. What's needed in these cases is an integer type - * with the same size as a pointer, which size_t is not certain to be. The - * only fix here is VMS-specific. - */ -# if defined(OPENSSL_SYS_VMS) -# if __INITIAL_POINTER_SIZE == 64 -# define PTR_SIZE_INT long long -# else /* __INITIAL_POINTER_SIZE == 64 */ -# define PTR_SIZE_INT int -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ -# elif !defined(PTR_SIZE_INT) /* defined(OPENSSL_SYS_VMS) */ -# define PTR_SIZE_INT size_t -# endif /* defined(OPENSSL_SYS_VMS) [else] */ - -# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) -/* - * BN_UMULT_HIGH section. - * - * No, I'm not trying to overwhelm you when stating that the - * product of N-bit numbers is 2*N bits wide:-) No, I don't expect - * you to be impressed when I say that if the compiler doesn't - * support 2*N integer type, then you have to replace every N*N - * multiplication with 4 (N/2)*(N/2) accompanied by some shifts - * and additions which unavoidably results in severe performance - * penalties. Of course provided that the hardware is capable of - * producing 2*N result... That's when you normally start - * considering assembler implementation. However! It should be - * pointed out that some CPUs (most notably Alpha, PowerPC and - * upcoming IA-64 family:-) provide *separate* instruction - * calculating the upper half of the product placing the result - * into a general purpose register. Now *if* the compiler supports - * inline assembler, then it's not impossible to implement the - * "bignum" routines (and have the compiler optimize 'em) - * exhibiting "native" performance in C. That's what BN_UMULT_HIGH - * macro is about:-) - * - * - */ -# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT)) -# if defined(__DECC) -# include -# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b)) -# elif defined(__GNUC__) && __GNUC__>=2 -# define BN_UMULT_HIGH(a,b) ({ \ - register BN_ULONG ret; \ - asm ("umulh %1,%2,%0" \ - : "=r"(ret) \ - : "r"(a), "r"(b)); \ - ret; }) -# endif /* compiler */ -# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG) -# if defined(__GNUC__) && __GNUC__>=2 -# define BN_UMULT_HIGH(a,b) ({ \ - register BN_ULONG ret; \ - asm ("mulhdu %0,%1,%2" \ - : "=r"(ret) \ - : "r"(a), "r"(b)); \ - ret; }) -# endif /* compiler */ -# elif (defined(__x86_64) || defined(__x86_64__)) && \ - (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT)) -# if defined(__GNUC__) && __GNUC__>=2 -# define BN_UMULT_HIGH(a,b) ({ \ - register BN_ULONG ret,discard; \ - asm ("mulq %3" \ - : "=a"(discard),"=d"(ret) \ - : "a"(a), "g"(b) \ - : "cc"); \ - ret; }) -# define BN_UMULT_LOHI(low,high,a,b) \ - asm ("mulq %3" \ - : "=a"(low),"=d"(high) \ - : "a"(a),"g"(b) \ - : "cc"); -# endif -# elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT) -# if defined(_MSC_VER) && _MSC_VER>=1400 -unsigned __int64 __umulh(unsigned __int64 a, unsigned __int64 b); -unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b, - unsigned __int64 *h); -# pragma intrinsic(__umulh,_umul128) -# define BN_UMULT_HIGH(a,b) __umulh((a),(b)) -# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high))) -# endif -# elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)) -# if defined(__GNUC__) && __GNUC__>=2 -# if __GNUC__>4 || (__GNUC__>=4 && __GNUC_MINOR__>=4) - /* "h" constraint is no more since 4.4 */ -# define BN_UMULT_HIGH(a,b) (((__uint128_t)(a)*(b))>>64) -# define BN_UMULT_LOHI(low,high,a,b) ({ \ - __uint128_t ret=(__uint128_t)(a)*(b); \ - (high)=ret>>64; (low)=ret; }) -# else -# define BN_UMULT_HIGH(a,b) ({ \ - register BN_ULONG ret; \ - asm ("dmultu %1,%2" \ - : "=h"(ret) \ - : "r"(a), "r"(b) : "l"); \ - ret; }) -# define BN_UMULT_LOHI(low,high,a,b)\ - asm ("dmultu %2,%3" \ - : "=l"(low),"=h"(high) \ - : "r"(a), "r"(b)); -# endif -# endif -# elif defined(__aarch64__) && defined(SIXTY_FOUR_BIT_LONG) -# if defined(__GNUC__) && __GNUC__>=2 -# define BN_UMULT_HIGH(a,b) ({ \ - register BN_ULONG ret; \ - asm ("umulh %0,%1,%2" \ - : "=r"(ret) \ - : "r"(a), "r"(b)); \ - ret; }) -# endif -# endif /* cpu */ -# endif /* OPENSSL_NO_ASM */ - -/************************************************************* - * Using the long long type - */ -# define Lw(t) (((BN_ULONG)(t))&BN_MASK2) -# define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) - -# ifdef BN_DEBUG_RAND -# define bn_clear_top2max(a) \ - { \ - int ind = (a)->dmax - (a)->top; \ - BN_ULONG *ftl = &(a)->d[(a)->top-1]; \ - for (; ind != 0; ind--) \ - *(++ftl) = 0x0; \ - } -# else -# define bn_clear_top2max(a) -# endif - -# ifdef BN_LLONG -# define mul_add(r,a,w,c) { \ - BN_ULLONG t; \ - t=(BN_ULLONG)w * (a) + (r) + (c); \ - (r)= Lw(t); \ - (c)= Hw(t); \ - } - -# define mul(r,a,w,c) { \ - BN_ULLONG t; \ - t=(BN_ULLONG)w * (a) + (c); \ - (r)= Lw(t); \ - (c)= Hw(t); \ - } - -# define sqr(r0,r1,a) { \ - BN_ULLONG t; \ - t=(BN_ULLONG)(a)*(a); \ - (r0)=Lw(t); \ - (r1)=Hw(t); \ - } - -# elif defined(BN_UMULT_LOHI) -# define mul_add(r,a,w,c) { \ - BN_ULONG high,low,ret,tmp=(a); \ - ret = (r); \ - BN_UMULT_LOHI(low,high,w,tmp); \ - ret += (c); \ - (c) = (ret<(c))?1:0; \ - (c) += high; \ - ret += low; \ - (c) += (ret>BN_BITS4)&BN_MASK2l) -# define L2HBITS(a) (((a)<>BN_BITS2)&BN_MASKl) -# define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<>(BN_BITS4-1); \ - m =(m&BN_MASK2l)<<(BN_BITS4+1); \ - l=(l+m)&BN_MASK2; if (l < m) h++; \ - (lo)=l; \ - (ho)=h; \ - } - -# define mul_add(r,a,bl,bh,c) { \ - BN_ULONG l,h; \ - \ - h= (a); \ - l=LBITS(h); \ - h=HBITS(h); \ - mul64(l,h,(bl),(bh)); \ - \ - /* non-multiply part */ \ - l=(l+(c))&BN_MASK2; if (l < (c)) h++; \ - (c)=(r); \ - l=(l+(c))&BN_MASK2; if (l < (c)) h++; \ - (c)=h&BN_MASK2; \ - (r)=l; \ - } - -# define mul(r,a,bl,bh,c) { \ - BN_ULONG l,h; \ - \ - h= (a); \ - l=LBITS(h); \ - h=HBITS(h); \ - mul64(l,h,(bl),(bh)); \ - \ - /* non-multiply part */ \ - l+=(c); if ((l&BN_MASK2) < (c)) h++; \ - (c)=h&BN_MASK2; \ - (r)=l&BN_MASK2; \ - } -# endif /* !BN_LLONG */ - -# if defined(OPENSSL_DOING_MAKEDEPEND) && defined(OPENSSL_FIPS) -# undef bn_div_words -# endif - -void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb); -void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); -void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); -void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp); -void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a); -void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a); -int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n); -int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl); -void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, - int dna, int dnb, BN_ULONG *t); -void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, - int n, int tna, int tnb, BN_ULONG *t); -void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t); -void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n); -void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, - BN_ULONG *t); -void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, - BN_ULONG *t); -BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - int cl, int dl); -BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, - int cl, int dl); -int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, int num); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/bn_prime.h b/Sources/COpenSSL/bn_prime.h deleted file mode 100644 index 489af8b4..00000000 --- a/Sources/COpenSSL/bn_prime.h +++ /dev/null @@ -1,326 +0,0 @@ -/* Auto generated by bn_prime.pl */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef EIGHT_BIT -# define NUMPRIMES 2048 -typedef unsigned short prime_t; -#else -# define NUMPRIMES 54 -typedef unsigned char prime_t; -#endif -static const prime_t primes[NUMPRIMES] = { - 2, 3, 5, 7, 11, 13, 17, 19, - 23, 29, 31, 37, 41, 43, 47, 53, - 59, 61, 67, 71, 73, 79, 83, 89, - 97, 101, 103, 107, 109, 113, 127, 131, - 137, 139, 149, 151, 157, 163, 167, 173, - 179, 181, 191, 193, 197, 199, 211, 223, - 227, 229, 233, 239, 241, 251, -#ifndef EIGHT_BIT - 257, 263, - 269, 271, 277, 281, 283, 293, 307, 311, - 313, 317, 331, 337, 347, 349, 353, 359, - 367, 373, 379, 383, 389, 397, 401, 409, - 419, 421, 431, 433, 439, 443, 449, 457, - 461, 463, 467, 479, 487, 491, 499, 503, - 509, 521, 523, 541, 547, 557, 563, 569, - 571, 577, 587, 593, 599, 601, 607, 613, - 617, 619, 631, 641, 643, 647, 653, 659, - 661, 673, 677, 683, 691, 701, 709, 719, - 727, 733, 739, 743, 751, 757, 761, 769, - 773, 787, 797, 809, 811, 821, 823, 827, - 829, 839, 853, 857, 859, 863, 877, 881, - 883, 887, 907, 911, 919, 929, 937, 941, - 947, 953, 967, 971, 977, 983, 991, 997, - 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, - 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, - 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, - 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, - 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, - 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, - 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, - 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, - 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, - 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, - 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, - 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, - 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, - 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, - 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, - 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, - 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, - 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, - 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, - 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, - 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, - 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, - 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, - 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, - 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, - 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, - 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, - 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, - 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, - 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, - 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, - 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, - 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, - 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, - 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, - 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, - 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, - 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, - 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, - 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, - 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, - 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, - 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, - 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, - 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, - 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, - 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, - 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, - 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, - 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, - 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, - 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, - 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, - 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, - 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, - 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, - 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, - 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, - 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, - 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, - 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, - 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, - 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, - 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, - 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, - 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, - 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, - 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, - 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, - 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, - 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, - 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, - 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, - 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, - 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, - 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, - 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, - 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, - 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, - 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, - 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, - 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, - 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, - 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, - 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, - 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, - 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, - 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, - 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, - 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, - 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, - 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, - 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, - 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, - 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, - 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, - 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, - 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, - 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, - 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, - 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, - 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, - 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, - 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, - 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, - 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, - 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, - 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, - 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, - 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, - 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, - 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, - 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, - 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, - 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, - 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, - 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, - 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, - 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, - 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, - 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, - 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, - 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, - 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, - 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, - 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, - 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, - 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, - 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, - 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, - 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, - 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, - 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, - 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, - 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, - 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, - 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, - 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, - 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, - 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, - 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, - 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, - 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, - 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, - 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, - 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, - 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, - 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, - 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, - 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, - 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, - 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, - 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, - 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, - 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, - 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, - 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, - 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, - 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, - 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, - 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, - 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, - 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, - 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, - 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, - 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, - 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, - 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, - 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, - 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, - 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, - 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, - 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, - 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, - 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, - 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, - 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, - 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, - 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, - 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, - 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, - 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, - 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, - 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, - 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, - 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, - 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, - 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, - 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, - 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, - 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, - 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, - 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, - 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, - 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, - 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, - 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, - 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, - 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, - 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, - 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, - 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, - 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, - 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, - 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, - 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, - 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, - 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, - 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, - 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, - 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, - 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, - 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, - 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, - 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, - 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, - 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, - 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, - 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, - 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, - 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, - 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, - 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, - 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, - 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, - 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, - 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, - 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, - 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, - 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, - 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, - 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, - 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, - 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, - 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, -#endif -}; diff --git a/Sources/COpenSSL/bss_.c b/Sources/COpenSSL/bss_.c deleted file mode 100644 index 28ad4eb6..00000000 --- a/Sources/COpenSSL/bss_.c +++ /dev/null @@ -1,6064 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/bio/bss_acpt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#define USE_SOCKETS -#include "cryptlib.h" -#include "bio.h" - -#ifndef OPENSSL_NO_SOCK - -# ifdef OPENSSL_SYS_WIN16 -# define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ -# else -# define SOCKET_PROTOCOL IPPROTO_TCP -# endif - -# if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) -/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ -# undef FIONBIO -# endif - -typedef struct bio_accept_st { - int state; - char *param_addr; - int accept_sock; - int accept_nbio; - char *addr; - int nbio; - /* - * If 0, it means normal, if 1, do a connect on bind failure, and if - * there is no-one listening, bind with SO_REUSEADDR. If 2, always use - * SO_REUSEADDR. - */ - int bind_mode; - BIO *bio_chain; -} BIO_ACCEPT; - -static int acpt_write(BIO *h, const char *buf, int num); -static int acpt_read(BIO *h, char *buf, int size); -static int acpt_puts(BIO *h, const char *str); -static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int acpt_new(BIO *h); -static int acpt_free(BIO *data); -static int acpt_state(BIO *b, BIO_ACCEPT *c); -static void acpt_close_socket(BIO *data); -static BIO_ACCEPT *BIO_ACCEPT_new(void); -static void BIO_ACCEPT_free(BIO_ACCEPT *a); - -# define ACPT_S_BEFORE 1 -# define ACPT_S_GET_ACCEPT_SOCKET 2 -# define ACPT_S_OK 3 - -static BIO_METHOD methods_acceptp = { - BIO_TYPE_ACCEPT, - "socket accept", - acpt_write, - acpt_read, - acpt_puts, - NULL, /* connect_gets, */ - acpt_ctrl, - acpt_new, - acpt_free, - NULL, -}; - -BIO_METHOD *BIO_s_accept(void) -{ - return (&methods_acceptp); -} - -static int acpt_new(BIO *bi) -{ - BIO_ACCEPT *ba; - - bi->init = 0; - bi->num = INVALID_SOCKET; - bi->flags = 0; - if ((ba = BIO_ACCEPT_new()) == NULL) - return (0); - bi->ptr = (char *)ba; - ba->state = ACPT_S_BEFORE; - bi->shutdown = 1; - return (1); -} - -static BIO_ACCEPT *BIO_ACCEPT_new(void) -{ - BIO_ACCEPT *ret; - - if ((ret = (BIO_ACCEPT *)OPENSSL_malloc(sizeof(BIO_ACCEPT))) == NULL) - return (NULL); - - memset(ret, 0, sizeof(BIO_ACCEPT)); - ret->accept_sock = INVALID_SOCKET; - ret->bind_mode = BIO_BIND_NORMAL; - return (ret); -} - -static void BIO_ACCEPT_free(BIO_ACCEPT *a) -{ - if (a == NULL) - return; - - if (a->param_addr != NULL) - OPENSSL_free(a->param_addr); - if (a->addr != NULL) - OPENSSL_free(a->addr); - if (a->bio_chain != NULL) - BIO_free(a->bio_chain); - OPENSSL_free(a); -} - -static void acpt_close_socket(BIO *bio) -{ - BIO_ACCEPT *c; - - c = (BIO_ACCEPT *)bio->ptr; - if (c->accept_sock != INVALID_SOCKET) { - shutdown(c->accept_sock, 2); - closesocket(c->accept_sock); - c->accept_sock = INVALID_SOCKET; - bio->num = INVALID_SOCKET; - } -} - -static int acpt_free(BIO *a) -{ - BIO_ACCEPT *data; - - if (a == NULL) - return (0); - data = (BIO_ACCEPT *)a->ptr; - - if (a->shutdown) { - acpt_close_socket(a); - BIO_ACCEPT_free(data); - a->ptr = NULL; - a->flags = 0; - a->init = 0; - } - return (1); -} - -static int acpt_state(BIO *b, BIO_ACCEPT *c) -{ - BIO *bio = NULL, *dbio; - int s = -1; - int i; - - again: - switch (c->state) { - case ACPT_S_BEFORE: - if (c->param_addr == NULL) { - BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED); - return (-1); - } - s = BIO_get_accept_socket(c->param_addr, c->bind_mode); - if (s == INVALID_SOCKET) - return (-1); - - if (c->accept_nbio) { - if (!BIO_socket_nbio(s, 1)) { - closesocket(s); - BIOerr(BIO_F_ACPT_STATE, - BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET); - return (-1); - } - } - c->accept_sock = s; - b->num = s; - c->state = ACPT_S_GET_ACCEPT_SOCKET; - return (1); - /* break; */ - case ACPT_S_GET_ACCEPT_SOCKET: - if (b->next_bio != NULL) { - c->state = ACPT_S_OK; - goto again; - } - BIO_clear_retry_flags(b); - b->retry_reason = 0; - i = BIO_accept(c->accept_sock, &(c->addr)); - - /* -2 return means we should retry */ - if (i == -2) { - BIO_set_retry_special(b); - b->retry_reason = BIO_RR_ACCEPT; - return -1; - } - - if (i < 0) - return (i); - - bio = BIO_new_socket(i, BIO_CLOSE); - if (bio == NULL) - goto err; - - BIO_set_callback(bio, BIO_get_callback(b)); - BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); - - if (c->nbio) { - if (!BIO_socket_nbio(i, 1)) { - BIOerr(BIO_F_ACPT_STATE, - BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET); - goto err; - } - } - - /* - * If the accept BIO has an bio_chain, we dup it and put the new - * socket at the end. - */ - if (c->bio_chain != NULL) { - if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL) - goto err; - if (!BIO_push(dbio, bio)) - goto err; - bio = dbio; - } - if (BIO_push(b, bio) == NULL) - goto err; - - c->state = ACPT_S_OK; - return (1); - err: - if (bio != NULL) - BIO_free(bio); - else if (s >= 0) - closesocket(s); - return (0); - /* break; */ - case ACPT_S_OK: - if (b->next_bio == NULL) { - c->state = ACPT_S_GET_ACCEPT_SOCKET; - goto again; - } - return (1); - /* break; */ - default: - return (0); - /* break; */ - } - -} - -static int acpt_read(BIO *b, char *out, int outl) -{ - int ret = 0; - BIO_ACCEPT *data; - - BIO_clear_retry_flags(b); - data = (BIO_ACCEPT *)b->ptr; - - while (b->next_bio == NULL) { - ret = acpt_state(b, data); - if (ret <= 0) - return (ret); - } - - ret = BIO_read(b->next_bio, out, outl); - BIO_copy_next_retry(b); - return (ret); -} - -static int acpt_write(BIO *b, const char *in, int inl) -{ - int ret; - BIO_ACCEPT *data; - - BIO_clear_retry_flags(b); - data = (BIO_ACCEPT *)b->ptr; - - while (b->next_bio == NULL) { - ret = acpt_state(b, data); - if (ret <= 0) - return (ret); - } - - ret = BIO_write(b->next_bio, in, inl); - BIO_copy_next_retry(b); - return (ret); -} - -static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - int *ip; - long ret = 1; - BIO_ACCEPT *data; - char **pp; - - data = (BIO_ACCEPT *)b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ret = 0; - data->state = ACPT_S_BEFORE; - acpt_close_socket(b); - b->flags = 0; - break; - case BIO_C_DO_STATE_MACHINE: - /* use this one to start the connection */ - ret = (long)acpt_state(b, data); - break; - case BIO_C_SET_ACCEPT: - if (ptr != NULL) { - if (num == 0) { - b->init = 1; - if (data->param_addr != NULL) - OPENSSL_free(data->param_addr); - data->param_addr = BUF_strdup(ptr); - } else if (num == 1) { - data->accept_nbio = (ptr != NULL); - } else if (num == 2) { - if (data->bio_chain != NULL) - BIO_free(data->bio_chain); - data->bio_chain = (BIO *)ptr; - } - } - break; - case BIO_C_SET_NBIO: - data->nbio = (int)num; - break; - case BIO_C_SET_FD: - b->init = 1; - b->num = *((int *)ptr); - data->accept_sock = b->num; - data->state = ACPT_S_GET_ACCEPT_SOCKET; - b->shutdown = (int)num; - b->init = 1; - break; - case BIO_C_GET_FD: - if (b->init) { - ip = (int *)ptr; - if (ip != NULL) - *ip = data->accept_sock; - ret = data->accept_sock; - } else - ret = -1; - break; - case BIO_C_GET_ACCEPT: - if (b->init) { - if (ptr != NULL) { - pp = (char **)ptr; - *pp = data->param_addr; - } else - ret = -1; - } else - ret = -1; - break; - case BIO_CTRL_GET_CLOSE: - ret = b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - ret = 0; - break; - case BIO_CTRL_FLUSH: - break; - case BIO_C_SET_BIND_MODE: - data->bind_mode = (int)num; - break; - case BIO_C_GET_BIND_MODE: - ret = (long)data->bind_mode; - break; - case BIO_CTRL_DUP: -/*- dbio=(BIO *)ptr; - if (data->param_port) EAY EAY - BIO_set_port(dbio,data->param_port); - if (data->param_hostname) - BIO_set_hostname(dbio,data->param_hostname); - BIO_set_nbio(dbio,data->nbio); */ - break; - - default: - ret = 0; - break; - } - return (ret); -} - -static int acpt_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = acpt_write(bp, str, n); - return (ret); -} - -BIO *BIO_new_accept(const char *str) -{ - BIO *ret; - - ret = BIO_new(BIO_s_accept()); - if (ret == NULL) - return (NULL); - if (BIO_set_accept_port(ret, str)) - return (ret); - else { - BIO_free(ret); - return (NULL); - } -} - -#endif -/* crypto/bio/bss_bio.c */ -/* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * Special method for a BIO where the other endpoint is also a BIO of this - * kind, handled by the same thread (i.e. the "peer" is actually ourselves, - * wearing a different hat). Such "BIO pairs" are mainly for using the SSL - * library with I/O interfaces for which no specific BIO method is available. - * See ssl/ssltest.c for some hints on how this can be used. - */ - -/* BIO_DEBUG implies BIO_PAIR_DEBUG */ -#ifdef BIO_DEBUG -# ifndef BIO_PAIR_DEBUG -# define BIO_PAIR_DEBUG -# endif -#endif - -/* disable assert() unless BIO_PAIR_DEBUG has been defined */ -#ifndef BIO_PAIR_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif - -#include -#include -#include -#include - -// #include "bio.h" -#include "err.h" -#include "crypto.h" - -#include "e_os.h" - -/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */ -#if defined(OPENSSL_SYS_VXWORKS) -# undef SSIZE_MAX -#endif -#ifndef SSIZE_MAX -# define SSIZE_MAX INT_MAX -#endif - -static int bio_new(BIO *bio); -static int bio_free(BIO *bio); -static int bio_read(BIO *bio, char *buf, int size); -static int bio_write(BIO *bio, const char *buf, int num); -static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); -static int bio_puts(BIO *bio, const char *str); - -static int bio_make_pair(BIO *bio1, BIO *bio2); -static void bio_destroy_pair(BIO *bio); - -static BIO_METHOD methods_biop = { - BIO_TYPE_BIO, - "BIO pair", - bio_write, - bio_read, - bio_puts, - NULL /* no bio_gets */ , - bio_ctrl, - bio_new, - bio_free, - NULL /* no bio_callback_ctrl */ -}; - -BIO_METHOD *BIO_s_bio(void) -{ - return &methods_biop; -} - -struct bio_bio_st { - BIO *peer; /* NULL if buf == NULL. If peer != NULL, then - * peer->ptr is also a bio_bio_st, and its - * "peer" member points back to us. peer != - * NULL iff init != 0 in the BIO. */ - /* This is for what we write (i.e. reading uses peer's struct): */ - int closed; /* valid iff peer != NULL */ - size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ - size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ - size_t size; - char *buf; /* "size" elements (if != NULL) */ - size_t request; /* valid iff peer != NULL; 0 if len != 0, - * otherwise set by peer to number of bytes - * it (unsuccessfully) tried to read, never - * more than buffer space (size-len) - * warrants. */ -}; - -static int bio_new(BIO *bio) -{ - struct bio_bio_st *b; - - b = OPENSSL_malloc(sizeof(*b)); - if (b == NULL) - return 0; - - b->peer = NULL; - b->closed = 0; - b->len = 0; - b->offset = 0; - /* enough for one TLS record (just a default) */ - b->size = 17 * 1024; - b->buf = NULL; - b->request = 0; - - bio->ptr = b; - return 1; -} - -static int bio_free(BIO *bio) -{ - struct bio_bio_st *b; - - if (bio == NULL) - return 0; - b = bio->ptr; - - assert(b != NULL); - - if (b->peer) - bio_destroy_pair(bio); - - if (b->buf != NULL) { - OPENSSL_free(b->buf); - } - - OPENSSL_free(b); - - return 1; -} - -static int bio_read(BIO *bio, char *buf, int size_) -{ - size_t size = size_; - size_t rest; - struct bio_bio_st *b, *peer_b; - - BIO_clear_retry_flags(bio); - - if (!bio->init) - return 0; - - b = bio->ptr; - assert(b != NULL); - assert(b->peer != NULL); - peer_b = b->peer->ptr; - assert(peer_b != NULL); - assert(peer_b->buf != NULL); - - peer_b->request = 0; /* will be set in "retry_read" situation */ - - if (buf == NULL || size == 0) - return 0; - - if (peer_b->len == 0) { - if (peer_b->closed) - return 0; /* writer has closed, and no data is left */ - else { - BIO_set_retry_read(bio); /* buffer is empty */ - if (size <= peer_b->size) - peer_b->request = size; - else - /* - * don't ask for more than the peer can deliver in one write - */ - peer_b->request = peer_b->size; - return -1; - } - } - - /* we can read */ - if (peer_b->len < size) - size = peer_b->len; - - /* now read "size" bytes */ - - rest = size; - - assert(rest > 0); - do { /* one or two iterations */ - size_t chunk; - - assert(rest <= peer_b->len); - if (peer_b->offset + rest <= peer_b->size) - chunk = rest; - else - /* wrap around ring buffer */ - chunk = peer_b->size - peer_b->offset; - assert(peer_b->offset + chunk <= peer_b->size); - - memcpy(buf, peer_b->buf + peer_b->offset, chunk); - - peer_b->len -= chunk; - if (peer_b->len) { - peer_b->offset += chunk; - assert(peer_b->offset <= peer_b->size); - if (peer_b->offset == peer_b->size) - peer_b->offset = 0; - buf += chunk; - } else { - /* buffer now empty, no need to advance "buf" */ - assert(chunk == rest); - peer_b->offset = 0; - } - rest -= chunk; - } - while (rest); - - return size; -} - -/*- - * non-copying interface: provide pointer to available data in buffer - * bio_nread0: return number of available bytes - * bio_nread: also advance index - * (example usage: bio_nread0(), read from buffer, bio_nread() - * or just bio_nread(), read from buffer) - */ -/* - * WARNING: The non-copying interface is largely untested as of yet and may - * contain bugs. - */ -static ossl_ssize_t bio_nread0(BIO *bio, char **buf) -{ - struct bio_bio_st *b, *peer_b; - ossl_ssize_t num; - - BIO_clear_retry_flags(bio); - - if (!bio->init) - return 0; - - b = bio->ptr; - assert(b != NULL); - assert(b->peer != NULL); - peer_b = b->peer->ptr; - assert(peer_b != NULL); - assert(peer_b->buf != NULL); - - peer_b->request = 0; - - if (peer_b->len == 0) { - char dummy; - - /* avoid code duplication -- nothing available for reading */ - return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ - } - - num = peer_b->len; - if (peer_b->size < peer_b->offset + num) - /* no ring buffer wrap-around for non-copying interface */ - num = peer_b->size - peer_b->offset; - assert(num > 0); - - if (buf != NULL) - *buf = peer_b->buf + peer_b->offset; - return num; -} - -static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) -{ - struct bio_bio_st *b, *peer_b; - ossl_ssize_t num, available; - - if (num_ > SSIZE_MAX) - num = SSIZE_MAX; - else - num = (ossl_ssize_t) num_; - - available = bio_nread0(bio, buf); - if (num > available) - num = available; - if (num <= 0) - return num; - - b = bio->ptr; - peer_b = b->peer->ptr; - - peer_b->len -= num; - if (peer_b->len) { - peer_b->offset += num; - assert(peer_b->offset <= peer_b->size); - if (peer_b->offset == peer_b->size) - peer_b->offset = 0; - } else - peer_b->offset = 0; - - return num; -} - -static int bio_write(BIO *bio, const char *buf, int num_) -{ - size_t num = num_; - size_t rest; - struct bio_bio_st *b; - - BIO_clear_retry_flags(bio); - - if (!bio->init || buf == NULL || num == 0) - return 0; - - b = bio->ptr; - assert(b != NULL); - assert(b->peer != NULL); - assert(b->buf != NULL); - - b->request = 0; - if (b->closed) { - /* we already closed */ - BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); - return -1; - } - - assert(b->len <= b->size); - - if (b->len == b->size) { - BIO_set_retry_write(bio); /* buffer is full */ - return -1; - } - - /* we can write */ - if (num > b->size - b->len) - num = b->size - b->len; - - /* now write "num" bytes */ - - rest = num; - - assert(rest > 0); - do { /* one or two iterations */ - size_t write_offset; - size_t chunk; - - assert(b->len + rest <= b->size); - - write_offset = b->offset + b->len; - if (write_offset >= b->size) - write_offset -= b->size; - /* b->buf[write_offset] is the first byte we can write to. */ - - if (write_offset + rest <= b->size) - chunk = rest; - else - /* wrap around ring buffer */ - chunk = b->size - write_offset; - - memcpy(b->buf + write_offset, buf, chunk); - - b->len += chunk; - - assert(b->len <= b->size); - - rest -= chunk; - buf += chunk; - } - while (rest); - - return num; -} - -/*- - * non-copying interface: provide pointer to region to write to - * bio_nwrite0: check how much space is available - * bio_nwrite: also increase length - * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() - * or just bio_nwrite(), write to buffer) - */ -static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) -{ - struct bio_bio_st *b; - size_t num; - size_t write_offset; - - BIO_clear_retry_flags(bio); - - if (!bio->init) - return 0; - - b = bio->ptr; - assert(b != NULL); - assert(b->peer != NULL); - assert(b->buf != NULL); - - b->request = 0; - if (b->closed) { - BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); - return -1; - } - - assert(b->len <= b->size); - - if (b->len == b->size) { - BIO_set_retry_write(bio); - return -1; - } - - num = b->size - b->len; - write_offset = b->offset + b->len; - if (write_offset >= b->size) - write_offset -= b->size; - if (write_offset + num > b->size) - /* - * no ring buffer wrap-around for non-copying interface (to fulfil - * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have - * to be called twice) - */ - num = b->size - write_offset; - - if (buf != NULL) - *buf = b->buf + write_offset; - assert(write_offset + num <= b->size); - - return num; -} - -static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) -{ - struct bio_bio_st *b; - ossl_ssize_t num, space; - - if (num_ > SSIZE_MAX) - num = SSIZE_MAX; - else - num = (ossl_ssize_t) num_; - - space = bio_nwrite0(bio, buf); - if (num > space) - num = space; - if (num <= 0) - return num; - b = bio->ptr; - assert(b != NULL); - b->len += num; - assert(b->len <= b->size); - - return num; -} - -static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) -{ - long ret; - struct bio_bio_st *b = bio->ptr; - - assert(b != NULL); - - switch (cmd) { - /* specific CTRL codes */ - - case BIO_C_SET_WRITE_BUF_SIZE: - if (b->peer) { - BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); - ret = 0; - } else if (num == 0) { - BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); - ret = 0; - } else { - size_t new_size = num; - - if (b->size != new_size) { - if (b->buf) { - OPENSSL_free(b->buf); - b->buf = NULL; - } - b->size = new_size; - } - ret = 1; - } - break; - - case BIO_C_GET_WRITE_BUF_SIZE: - ret = (long)b->size; - break; - - case BIO_C_MAKE_BIO_PAIR: - { - BIO *other_bio = ptr; - - if (bio_make_pair(bio, other_bio)) - ret = 1; - else - ret = 0; - } - break; - - case BIO_C_DESTROY_BIO_PAIR: - /* - * Affects both BIOs in the pair -- call just once! Or let - * BIO_free(bio1); BIO_free(bio2); do the job. - */ - bio_destroy_pair(bio); - ret = 1; - break; - - case BIO_C_GET_WRITE_GUARANTEE: - /* - * How many bytes can the caller feed to the next write without - * having to keep any? - */ - if (b->peer == NULL || b->closed) - ret = 0; - else - ret = (long)b->size - b->len; - break; - - case BIO_C_GET_READ_REQUEST: - /* - * If the peer unsuccessfully tried to read, how many bytes were - * requested? (As with BIO_CTRL_PENDING, that number can usually be - * treated as boolean.) - */ - ret = (long)b->request; - break; - - case BIO_C_RESET_READ_REQUEST: - /* - * Reset request. (Can be useful after read attempts at the other - * side that are meant to be non-blocking, e.g. when probing SSL_read - * to see if any data is available.) - */ - b->request = 0; - ret = 1; - break; - - case BIO_C_SHUTDOWN_WR: - /* similar to shutdown(..., SHUT_WR) */ - b->closed = 1; - ret = 1; - break; - - case BIO_C_NREAD0: - /* prepare for non-copying read */ - ret = (long)bio_nread0(bio, ptr); - break; - - case BIO_C_NREAD: - /* non-copying read */ - ret = (long)bio_nread(bio, ptr, (size_t)num); - break; - - case BIO_C_NWRITE0: - /* prepare for non-copying write */ - ret = (long)bio_nwrite0(bio, ptr); - break; - - case BIO_C_NWRITE: - /* non-copying write */ - ret = (long)bio_nwrite(bio, ptr, (size_t)num); - break; - - /* standard CTRL codes follow */ - - case BIO_CTRL_RESET: - if (b->buf != NULL) { - b->len = 0; - b->offset = 0; - } - ret = 0; - break; - - case BIO_CTRL_GET_CLOSE: - ret = bio->shutdown; - break; - - case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; - ret = 1; - break; - - case BIO_CTRL_PENDING: - if (b->peer != NULL) { - struct bio_bio_st *peer_b = b->peer->ptr; - - ret = (long)peer_b->len; - } else - ret = 0; - break; - - case BIO_CTRL_WPENDING: - if (b->buf != NULL) - ret = (long)b->len; - else - ret = 0; - break; - - case BIO_CTRL_DUP: - /* See BIO_dup_chain for circumstances we have to expect. */ - { - BIO *other_bio = ptr; - struct bio_bio_st *other_b; - - assert(other_bio != NULL); - other_b = other_bio->ptr; - assert(other_b != NULL); - - assert(other_b->buf == NULL); /* other_bio is always fresh */ - - other_b->size = b->size; - } - - ret = 1; - break; - - case BIO_CTRL_FLUSH: - ret = 1; - break; - - case BIO_CTRL_EOF: - if (b->peer != NULL) { - struct bio_bio_st *peer_b = b->peer->ptr; - - if (peer_b->len == 0 && peer_b->closed) - ret = 1; - else - ret = 0; - } else { - ret = 1; - } - break; - - default: - ret = 0; - } - return ret; -} - -static int bio_puts(BIO *bio, const char *str) -{ - return bio_write(bio, str, strlen(str)); -} - -static int bio_make_pair(BIO *bio1, BIO *bio2) -{ - struct bio_bio_st *b1, *b2; - - assert(bio1 != NULL); - assert(bio2 != NULL); - - b1 = bio1->ptr; - b2 = bio2->ptr; - - if (b1->peer != NULL || b2->peer != NULL) { - BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); - return 0; - } - - if (b1->buf == NULL) { - b1->buf = OPENSSL_malloc(b1->size); - if (b1->buf == NULL) { - BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); - return 0; - } - b1->len = 0; - b1->offset = 0; - } - - if (b2->buf == NULL) { - b2->buf = OPENSSL_malloc(b2->size); - if (b2->buf == NULL) { - BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); - return 0; - } - b2->len = 0; - b2->offset = 0; - } - - b1->peer = bio2; - b1->closed = 0; - b1->request = 0; - b2->peer = bio1; - b2->closed = 0; - b2->request = 0; - - bio1->init = 1; - bio2->init = 1; - - return 1; -} - -static void bio_destroy_pair(BIO *bio) -{ - struct bio_bio_st *b = bio->ptr; - - if (b != NULL) { - BIO *peer_bio = b->peer; - - if (peer_bio != NULL) { - struct bio_bio_st *peer_b = peer_bio->ptr; - - assert(peer_b != NULL); - assert(peer_b->peer == bio); - - peer_b->peer = NULL; - peer_bio->init = 0; - assert(peer_b->buf != NULL); - peer_b->len = 0; - peer_b->offset = 0; - - b->peer = NULL; - bio->init = 0; - assert(b->buf != NULL); - b->len = 0; - b->offset = 0; - } - } -} - -/* Exported convenience functions */ -int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, - BIO **bio2_p, size_t writebuf2) -{ - BIO *bio1 = NULL, *bio2 = NULL; - long r; - int ret = 0; - - bio1 = BIO_new(BIO_s_bio()); - if (bio1 == NULL) - goto err; - bio2 = BIO_new(BIO_s_bio()); - if (bio2 == NULL) - goto err; - - if (writebuf1) { - r = BIO_set_write_buf_size(bio1, writebuf1); - if (!r) - goto err; - } - if (writebuf2) { - r = BIO_set_write_buf_size(bio2, writebuf2); - if (!r) - goto err; - } - - r = BIO_make_bio_pair(bio1, bio2); - if (!r) - goto err; - ret = 1; - - err: - if (ret == 0) { - if (bio1) { - BIO_free(bio1); - bio1 = NULL; - } - if (bio2) { - BIO_free(bio2); - bio2 = NULL; - } - } - - *bio1_p = bio1; - *bio2_p = bio2; - return ret; -} - -size_t BIO_ctrl_get_write_guarantee(BIO *bio) -{ - return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); -} - -size_t BIO_ctrl_get_read_request(BIO *bio) -{ - return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); -} - -int BIO_ctrl_reset_read_request(BIO *bio) -{ - return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); -} - -/* - * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now - * (conceivably some other BIOs could allow non-copying reads and writes - * too.) - */ -int BIO_nread0(BIO *bio, char **buf) -{ - long ret; - - if (!bio->init) { - BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); - return -2; - } - - ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); - if (ret > INT_MAX) - return INT_MAX; - else - return (int)ret; -} - -int BIO_nread(BIO *bio, char **buf, int num) -{ - int ret; - - if (!bio->init) { - BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); - return -2; - } - - ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf); - if (ret > 0) - bio->num_read += ret; - return ret; -} - -int BIO_nwrite0(BIO *bio, char **buf) -{ - long ret; - - if (!bio->init) { - BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); - return -2; - } - - ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); - if (ret > INT_MAX) - return INT_MAX; - else - return (int)ret; -} - -int BIO_nwrite(BIO *bio, char **buf, int num) -{ - int ret; - - if (!bio->init) { - BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); - return -2; - } - - ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); - if (ret > 0) - bio->num_write += ret; - return ret; -} -/* crypto/bio/bss_conn.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#define USE_SOCKETS -// #include "cryptlib.h" -// #include "bio.h" - -#ifndef OPENSSL_NO_SOCK - -# ifdef OPENSSL_SYS_WIN16 -# define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ -# else -# define SOCKET_PROTOCOL IPPROTO_TCP -# endif - -# if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) -/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ -# undef FIONBIO -# endif - -typedef struct bio_connect_st { - int state; - char *param_hostname; - char *param_port; - int nbio; - unsigned char ip[4]; - unsigned short port; - struct sockaddr_in them; - /* - * int socket; this will be kept in bio->num so that it is compatible - * with the bss_sock bio - */ - /* - * called when the connection is initially made callback(BIO,state,ret); - * The callback should return 'ret'. state is for compatibility with the - * ssl info_callback - */ - int (*info_callback) (const BIO *bio, int state, int ret); -} BIO_CONNECT; - -static int conn_write(BIO *h, const char *buf, int num); -static int conn_read(BIO *h, char *buf, int size); -static int conn_puts(BIO *h, const char *str); -static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int conn_new(BIO *h); -static int conn_free(BIO *data); -static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *); - -static int conn_state(BIO *b, BIO_CONNECT *c); -static void conn_close_socket(BIO *data); -BIO_CONNECT *BIO_CONNECT_new(void); -void BIO_CONNECT_free(BIO_CONNECT *a); - -static BIO_METHOD methods_connectp = { - BIO_TYPE_CONNECT, - "socket connect", - conn_write, - conn_read, - conn_puts, - NULL, /* connect_gets, */ - conn_ctrl, - conn_new, - conn_free, - conn_callback_ctrl, -}; - -static int conn_state(BIO *b, BIO_CONNECT *c) -{ - int ret = -1, i; - unsigned long l; - char *p, *q; - int (*cb) (const BIO *, int, int) = NULL; - - if (c->info_callback != NULL) - cb = c->info_callback; - - for (;;) { - switch (c->state) { - case BIO_CONN_S_BEFORE: - p = c->param_hostname; - if (p == NULL) { - BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_SPECIFIED); - goto exit_loop; - } - for (; *p != '\0'; p++) { - if ((*p == ':') || (*p == '/')) - break; - } - - i = *p; - if ((i == ':') || (i == '/')) { - - *(p++) = '\0'; - if (i == ':') { - for (q = p; *q; q++) - if (*q == '/') { - *q = '\0'; - break; - } - if (c->param_port != NULL) - OPENSSL_free(c->param_port); - c->param_port = BUF_strdup(p); - } - } - - if (c->param_port == NULL) { - BIOerr(BIO_F_CONN_STATE, BIO_R_NO_PORT_SPECIFIED); - ERR_add_error_data(2, "host=", c->param_hostname); - goto exit_loop; - } - c->state = BIO_CONN_S_GET_IP; - break; - - case BIO_CONN_S_GET_IP: - if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0) - goto exit_loop; - c->state = BIO_CONN_S_GET_PORT; - break; - - case BIO_CONN_S_GET_PORT: - if (c->param_port == NULL) { - /* abort(); */ - goto exit_loop; - } else if (BIO_get_port(c->param_port, &c->port) <= 0) - goto exit_loop; - c->state = BIO_CONN_S_CREATE_SOCKET; - break; - - case BIO_CONN_S_CREATE_SOCKET: - /* now setup address */ - memset((char *)&c->them, 0, sizeof(c->them)); - c->them.sin_family = AF_INET; - c->them.sin_port = htons((unsigned short)c->port); - l = (unsigned long) - ((unsigned long)c->ip[0] << 24L) | - ((unsigned long)c->ip[1] << 16L) | - ((unsigned long)c->ip[2] << 8L) | ((unsigned long)c->ip[3]); - c->them.sin_addr.s_addr = htonl(l); - c->state = BIO_CONN_S_CREATE_SOCKET; - - ret = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL); - if (ret == INVALID_SOCKET) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); - ERR_add_error_data(4, "host=", c->param_hostname, - ":", c->param_port); - BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); - goto exit_loop; - } - b->num = ret; - c->state = BIO_CONN_S_NBIO; - break; - - case BIO_CONN_S_NBIO: - if (c->nbio) { - if (!BIO_socket_nbio(b->num, 1)) { - BIOerr(BIO_F_CONN_STATE, BIO_R_ERROR_SETTING_NBIO); - ERR_add_error_data(4, "host=", - c->param_hostname, ":", c->param_port); - goto exit_loop; - } - } - c->state = BIO_CONN_S_CONNECT; - -# if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) - i = 1; - i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, - sizeof(i)); - if (i < 0) { - SYSerr(SYS_F_SOCKET, get_last_socket_error()); - ERR_add_error_data(4, "host=", c->param_hostname, - ":", c->param_port); - BIOerr(BIO_F_CONN_STATE, BIO_R_KEEPALIVE); - goto exit_loop; - } -# endif - break; - - case BIO_CONN_S_CONNECT: - BIO_clear_retry_flags(b); - ret = connect(b->num, - (struct sockaddr *)&c->them, sizeof(c->them)); - b->retry_reason = 0; - if (ret < 0) { - if (BIO_sock_should_retry(ret)) { - BIO_set_retry_special(b); - c->state = BIO_CONN_S_BLOCKED_CONNECT; - b->retry_reason = BIO_RR_CONNECT; - } else { - SYSerr(SYS_F_CONNECT, get_last_socket_error()); - ERR_add_error_data(4, "host=", - c->param_hostname, ":", c->param_port); - BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR); - } - goto exit_loop; - } else - c->state = BIO_CONN_S_OK; - break; - - case BIO_CONN_S_BLOCKED_CONNECT: - i = BIO_sock_error(b->num); - if (i) { - BIO_clear_retry_flags(b); - SYSerr(SYS_F_CONNECT, i); - ERR_add_error_data(4, "host=", - c->param_hostname, ":", c->param_port); - BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR); - ret = 0; - goto exit_loop; - } else - c->state = BIO_CONN_S_OK; - break; - - case BIO_CONN_S_OK: - ret = 1; - goto exit_loop; - default: - /* abort(); */ - goto exit_loop; - } - - if (cb != NULL) { - if (!(ret = cb((BIO *)b, c->state, ret))) - goto end; - } - } - - /* Loop does not exit */ - exit_loop: - if (cb != NULL) - ret = cb((BIO *)b, c->state, ret); - end: - return (ret); -} - -BIO_CONNECT *BIO_CONNECT_new(void) -{ - BIO_CONNECT *ret; - - if ((ret = (BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL) - return (NULL); - ret->state = BIO_CONN_S_BEFORE; - ret->param_hostname = NULL; - ret->param_port = NULL; - ret->info_callback = NULL; - ret->nbio = 0; - ret->ip[0] = 0; - ret->ip[1] = 0; - ret->ip[2] = 0; - ret->ip[3] = 0; - ret->port = 0; - memset((char *)&ret->them, 0, sizeof(ret->them)); - return (ret); -} - -void BIO_CONNECT_free(BIO_CONNECT *a) -{ - if (a == NULL) - return; - - if (a->param_hostname != NULL) - OPENSSL_free(a->param_hostname); - if (a->param_port != NULL) - OPENSSL_free(a->param_port); - OPENSSL_free(a); -} - -BIO_METHOD *BIO_s_connect(void) -{ - return (&methods_connectp); -} - -static int conn_new(BIO *bi) -{ - bi->init = 0; - bi->num = INVALID_SOCKET; - bi->flags = 0; - if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL) - return (0); - else - return (1); -} - -static void conn_close_socket(BIO *bio) -{ - BIO_CONNECT *c; - - c = (BIO_CONNECT *)bio->ptr; - if (bio->num != INVALID_SOCKET) { - /* Only do a shutdown if things were established */ - if (c->state == BIO_CONN_S_OK) - shutdown(bio->num, 2); - closesocket(bio->num); - bio->num = INVALID_SOCKET; - } -} - -static int conn_free(BIO *a) -{ - BIO_CONNECT *data; - - if (a == NULL) - return (0); - data = (BIO_CONNECT *)a->ptr; - - if (a->shutdown) { - conn_close_socket(a); - BIO_CONNECT_free(data); - a->ptr = NULL; - a->flags = 0; - a->init = 0; - } - return (1); -} - -static int conn_read(BIO *b, char *out, int outl) -{ - int ret = 0; - BIO_CONNECT *data; - - data = (BIO_CONNECT *)b->ptr; - if (data->state != BIO_CONN_S_OK) { - ret = conn_state(b, data); - if (ret <= 0) - return (ret); - } - - if (out != NULL) { - clear_socket_error(); - ret = readsocket(b->num, out, outl); - BIO_clear_retry_flags(b); - if (ret <= 0) { - if (BIO_sock_should_retry(ret)) - BIO_set_retry_read(b); - } - } - return (ret); -} - -static int conn_write(BIO *b, const char *in, int inl) -{ - int ret; - BIO_CONNECT *data; - - data = (BIO_CONNECT *)b->ptr; - if (data->state != BIO_CONN_S_OK) { - ret = conn_state(b, data); - if (ret <= 0) - return (ret); - } - - clear_socket_error(); - ret = writesocket(b->num, in, inl); - BIO_clear_retry_flags(b); - if (ret <= 0) { - if (BIO_sock_should_retry(ret)) - BIO_set_retry_write(b); - } - return (ret); -} - -static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - BIO *dbio; - int *ip; - const char **pptr = NULL; - long ret = 1; - BIO_CONNECT *data; - - data = (BIO_CONNECT *)b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ret = 0; - data->state = BIO_CONN_S_BEFORE; - conn_close_socket(b); - b->flags = 0; - break; - case BIO_C_DO_STATE_MACHINE: - /* use this one to start the connection */ - if (data->state != BIO_CONN_S_OK) - ret = (long)conn_state(b, data); - else - ret = 1; - break; - case BIO_C_GET_CONNECT: - if (ptr != NULL) { - pptr = (const char **)ptr; - } - - if (b->init) { - if (pptr != NULL) { - ret = 1; - if (num == 0) { - *pptr = data->param_hostname; - } else if (num == 1) { - *pptr = data->param_port; - } else if (num == 2) { - *pptr = (char *)&(data->ip[0]); - } else { - ret = 0; - } - } - if (num == 3) { - ret = data->port; - } - } else { - if (pptr != NULL) - *pptr = "not initialized"; - ret = 0; - } - break; - case BIO_C_SET_CONNECT: - if (ptr != NULL) { - b->init = 1; - if (num == 0) { - if (data->param_hostname != NULL) - OPENSSL_free(data->param_hostname); - data->param_hostname = BUF_strdup(ptr); - } else if (num == 1) { - if (data->param_port != NULL) - OPENSSL_free(data->param_port); - data->param_port = BUF_strdup(ptr); - } else if (num == 2) { - char buf[16]; - unsigned char *p = ptr; - - BIO_snprintf(buf, sizeof(buf), "%d.%d.%d.%d", - p[0], p[1], p[2], p[3]); - if (data->param_hostname != NULL) - OPENSSL_free(data->param_hostname); - data->param_hostname = BUF_strdup(buf); - memcpy(&(data->ip[0]), ptr, 4); - } else if (num == 3) { - char buf[DECIMAL_SIZE(int) + 1]; - - BIO_snprintf(buf, sizeof(buf), "%d", *(int *)ptr); - if (data->param_port != NULL) - OPENSSL_free(data->param_port); - data->param_port = BUF_strdup(buf); - data->port = *(int *)ptr; - } - } - break; - case BIO_C_SET_NBIO: - data->nbio = (int)num; - break; - case BIO_C_GET_FD: - if (b->init) { - ip = (int *)ptr; - if (ip != NULL) - *ip = b->num; - ret = b->num; - } else - ret = -1; - break; - case BIO_CTRL_GET_CLOSE: - ret = b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - ret = 0; - break; - case BIO_CTRL_FLUSH: - break; - case BIO_CTRL_DUP: - { - dbio = (BIO *)ptr; - if (data->param_port) - BIO_set_conn_port(dbio, data->param_port); - if (data->param_hostname) - BIO_set_conn_hostname(dbio, data->param_hostname); - BIO_set_nbio(dbio, data->nbio); - /* - * FIXME: the cast of the function seems unlikely to be a good - * idea - */ - (void)BIO_set_info_callback(dbio, - (bio_info_cb *)data->info_callback); - } - break; - case BIO_CTRL_SET_CALLBACK: - { -# if 0 /* FIXME: Should this be used? -- Richard - * Levitte */ - BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - ret = -1; -# else - ret = 0; -# endif - } - break; - case BIO_CTRL_GET_CALLBACK: - { - int (**fptr) (const BIO *bio, int state, int xret); - - fptr = (int (**)(const BIO *bio, int state, int xret))ptr; - *fptr = data->info_callback; - } - break; - default: - ret = 0; - break; - } - return (ret); -} - -static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - long ret = 1; - BIO_CONNECT *data; - - data = (BIO_CONNECT *)b->ptr; - - switch (cmd) { - case BIO_CTRL_SET_CALLBACK: - { - data->info_callback = - (int (*)(const struct bio_st *, int, int))fp; - } - break; - default: - ret = 0; - break; - } - return (ret); -} - -static int conn_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = conn_write(bp, str, n); - return (ret); -} - -BIO *BIO_new_connect(const char *str) -{ - BIO *ret; - - ret = BIO_new(BIO_s_connect()); - if (ret == NULL) - return (NULL); - if (BIO_set_conn_hostname(ret, str)) - return (ret); - else { - BIO_free(ret); - return (NULL); - } -} - -#endif -/* crypto/bio/bio_dgram.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#define USE_SOCKETS -// #include "cryptlib.h" - -// #include "bio.h" -#ifndef OPENSSL_NO_DGRAM - -# if defined(OPENSSL_SYS_VMS) -# include -# endif - -# ifndef OPENSSL_NO_SCTP -# include -# include -# define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00 -# define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0 -# endif - -# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU) -# define IP_MTU 14 /* linux is lame */ -# endif - -# if OPENSSL_USE_IPV6 && !defined(IPPROTO_IPV6) -# define IPPROTO_IPV6 41 /* windows is lame */ -# endif - -# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED) -/* Standard definition causes type-punning problems. */ -# undef IN6_IS_ADDR_V4MAPPED -# define s6_addr32 __u6_addr.__u6_addr32 -# define IN6_IS_ADDR_V4MAPPED(a) \ - (((a)->s6_addr32[0] == 0) && \ - ((a)->s6_addr32[1] == 0) && \ - ((a)->s6_addr32[2] == htonl(0x0000ffff))) -# endif - -# ifdef WATT32 -# define sock_write SockWrite /* Watt-32 uses same names */ -# define sock_read SockRead -# define sock_puts SockPuts -# endif - -static int dgram_write(BIO *h, const char *buf, int num); -static int dgram_read(BIO *h, char *buf, int size); -static int dgram_puts(BIO *h, const char *str); -static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int dgram_new(BIO *h); -static int dgram_free(BIO *data); -static int dgram_clear(BIO *bio); - -# ifndef OPENSSL_NO_SCTP -static int dgram_sctp_write(BIO *h, const char *buf, int num); -static int dgram_sctp_read(BIO *h, char *buf, int size); -static int dgram_sctp_puts(BIO *h, const char *str); -static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int dgram_sctp_new(BIO *h); -static int dgram_sctp_free(BIO *data); -# ifdef SCTP_AUTHENTICATION_EVENT -static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification - *snp); -# endif -# endif - -static int BIO_dgram_should_retry(int s); - -static void get_current_time(struct timeval *t); - -static BIO_METHOD methods_dgramp = { - BIO_TYPE_DGRAM, - "datagram socket", - dgram_write, - dgram_read, - dgram_puts, - NULL, /* dgram_gets, */ - dgram_ctrl, - dgram_new, - dgram_free, - NULL, -}; - -# ifndef OPENSSL_NO_SCTP -static BIO_METHOD methods_dgramp_sctp = { - BIO_TYPE_DGRAM_SCTP, - "datagram sctp socket", - dgram_sctp_write, - dgram_sctp_read, - dgram_sctp_puts, - NULL, /* dgram_gets, */ - dgram_sctp_ctrl, - dgram_sctp_new, - dgram_sctp_free, - NULL, -}; -# endif - -typedef struct bio_dgram_data_st { - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } peer; - unsigned int connected; - unsigned int _errno; - unsigned int mtu; - struct timeval next_timeout; - struct timeval socket_timeout; -} bio_dgram_data; - -# ifndef OPENSSL_NO_SCTP -typedef struct bio_dgram_sctp_save_message_st { - BIO *bio; - char *data; - int length; -} bio_dgram_sctp_save_message; - -typedef struct bio_dgram_sctp_data_st { - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } peer; - unsigned int connected; - unsigned int _errno; - unsigned int mtu; - struct bio_dgram_sctp_sndinfo sndinfo; - struct bio_dgram_sctp_rcvinfo rcvinfo; - struct bio_dgram_sctp_prinfo prinfo; - void (*handle_notifications) (BIO *bio, void *context, void *buf); - void *notification_context; - int in_handshake; - int ccs_rcvd; - int ccs_sent; - int save_shutdown; - int peer_auth_tested; - bio_dgram_sctp_save_message saved_message; -} bio_dgram_sctp_data; -# endif - -BIO_METHOD *BIO_s_datagram(void) -{ - return (&methods_dgramp); -} - -BIO *BIO_new_dgram(int fd, int close_flag) -{ - BIO *ret; - - ret = BIO_new(BIO_s_datagram()); - if (ret == NULL) - return (NULL); - BIO_set_fd(ret, fd, close_flag); - return (ret); -} - -static int dgram_new(BIO *bi) -{ - bio_dgram_data *data = NULL; - - bi->init = 0; - bi->num = 0; - data = OPENSSL_malloc(sizeof(bio_dgram_data)); - if (data == NULL) - return 0; - memset(data, 0x00, sizeof(bio_dgram_data)); - bi->ptr = data; - - bi->flags = 0; - return (1); -} - -static int dgram_free(BIO *a) -{ - bio_dgram_data *data; - - if (a == NULL) - return (0); - if (!dgram_clear(a)) - return 0; - - data = (bio_dgram_data *)a->ptr; - if (data != NULL) - OPENSSL_free(data); - - return (1); -} - -static int dgram_clear(BIO *a) -{ - if (a == NULL) - return (0); - if (a->shutdown) { - if (a->init) { - SHUTDOWN2(a->num); - } - a->init = 0; - a->flags = 0; - } - return (1); -} - -static void dgram_adjust_rcv_timeout(BIO *b) -{ -# if defined(SO_RCVTIMEO) - bio_dgram_data *data = (bio_dgram_data *)b->ptr; - union { - size_t s; - int i; - } sz = { - 0 - }; - - /* Is a timer active? */ - if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { - struct timeval timenow, timeleft; - - /* Read current socket timeout */ -# ifdef OPENSSL_SYS_WINDOWS - int timeout; - - sz.i = sizeof(timeout); - if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz.i) < 0) { - perror("getsockopt"); - } else { - data->socket_timeout.tv_sec = timeout / 1000; - data->socket_timeout.tv_usec = (timeout % 1000) * 1000; - } -# else - sz.i = sizeof(data->socket_timeout); - if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - &(data->socket_timeout), (void *)&sz) < 0) { - perror("getsockopt"); - } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) - OPENSSL_assert(sz.s <= sizeof(data->socket_timeout)); -# endif - - /* Get current time */ - get_current_time(&timenow); - - /* Calculate time left until timer expires */ - memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); - if (timeleft.tv_usec < timenow.tv_usec) { - timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec; - timeleft.tv_sec--; - } else { - timeleft.tv_usec -= timenow.tv_usec; - } - if (timeleft.tv_sec < timenow.tv_sec) { - timeleft.tv_sec = 0; - timeleft.tv_usec = 1; - } else { - timeleft.tv_sec -= timenow.tv_sec; - } - - /* - * Adjust socket timeout if next handhake message timer will expire - * earlier. - */ - if ((data->socket_timeout.tv_sec == 0 - && data->socket_timeout.tv_usec == 0) - || (data->socket_timeout.tv_sec > timeleft.tv_sec) - || (data->socket_timeout.tv_sec == timeleft.tv_sec - && data->socket_timeout.tv_usec >= timeleft.tv_usec)) { -# ifdef OPENSSL_SYS_WINDOWS - timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) { - perror("setsockopt"); - } -# else - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, - sizeof(struct timeval)) < 0) { - perror("setsockopt"); - } -# endif - } - } -# endif -} - -static void dgram_reset_rcv_timeout(BIO *b) -{ -# if defined(SO_RCVTIMEO) - bio_dgram_data *data = (bio_dgram_data *)b->ptr; - - /* Is a timer active? */ - if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { -# ifdef OPENSSL_SYS_WINDOWS - int timeout = data->socket_timeout.tv_sec * 1000 + - data->socket_timeout.tv_usec / 1000; - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) { - perror("setsockopt"); - } -# else - if (setsockopt - (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), - sizeof(struct timeval)) < 0) { - perror("setsockopt"); - } -# endif - } -# endif -} - -static int dgram_read(BIO *b, char *out, int outl) -{ - int ret = 0; - bio_dgram_data *data = (bio_dgram_data *)b->ptr; - - struct { - /* - * See commentary in b_sock.c. - */ - union { - size_t s; - int i; - } len; - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } peer; - } sa; - - sa.len.s = 0; - sa.len.i = sizeof(sa.peer); - - if (out != NULL) { - clear_socket_error(); - memset(&sa.peer, 0x00, sizeof(sa.peer)); - dgram_adjust_rcv_timeout(b); - ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, (void *)&sa.len); - if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { - OPENSSL_assert(sa.len.s <= sizeof(sa.peer)); - sa.len.i = (int)sa.len.s; - } - - if (!data->connected && ret >= 0) - BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); - - BIO_clear_retry_flags(b); - if (ret < 0) { - if (BIO_dgram_should_retry(ret)) { - BIO_set_retry_read(b); - data->_errno = get_last_socket_error(); - } - } - - dgram_reset_rcv_timeout(b); - } - return (ret); -} - -static int dgram_write(BIO *b, const char *in, int inl) -{ - int ret; - bio_dgram_data *data = (bio_dgram_data *)b->ptr; - clear_socket_error(); - - if (data->connected) - ret = writesocket(b->num, in, inl); - else { - int peerlen = sizeof(data->peer); - - if (data->peer.sa.sa_family == AF_INET) - peerlen = sizeof(data->peer.sa_in); -# if OPENSSL_USE_IPV6 - else if (data->peer.sa.sa_family == AF_INET6) - peerlen = sizeof(data->peer.sa_in6); -# endif -# if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) - ret = sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); -# else - ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); -# endif - } - - BIO_clear_retry_flags(b); - if (ret <= 0) { - if (BIO_dgram_should_retry(ret)) { - BIO_set_retry_write(b); - data->_errno = get_last_socket_error(); - -# if 0 /* higher layers are responsible for querying - * MTU, if necessary */ - if (data->_errno == EMSGSIZE) - /* retrieve the new MTU */ - BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); -# endif - } - } - return (ret); -} - -static long dgram_get_mtu_overhead(bio_dgram_data *data) -{ - long ret; - - switch (data->peer.sa.sa_family) { - case AF_INET: - /* - * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP - */ - ret = 28; - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: -# ifdef IN6_IS_ADDR_V4MAPPED - if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) - /* - * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP - */ - ret = 28; - else -# endif - /* - * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP - */ - ret = 48; - break; -# endif - default: - /* We don't know. Go with the historical default */ - ret = 28; - break; - } - return ret; -} - -static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret = 1; - int *ip; - struct sockaddr *to = NULL; - bio_dgram_data *data = NULL; - int sockopt_val = 0; -# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU)) - socklen_t sockopt_len; /* assume that system supporting IP_MTU is - * modern enough to define socklen_t */ - socklen_t addr_len; - union { - struct sockaddr sa; - struct sockaddr_in s4; -# if OPENSSL_USE_IPV6 - struct sockaddr_in6 s6; -# endif - } addr; -# endif - - data = (bio_dgram_data *)b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - num = 0; - ret = 0; - break; - case BIO_CTRL_INFO: - ret = 0; - break; - case BIO_C_SET_FD: - dgram_clear(b); - b->num = *((int *)ptr); - b->shutdown = (int)num; - b->init = 1; - break; - case BIO_C_GET_FD: - if (b->init) { - ip = (int *)ptr; - if (ip != NULL) - *ip = b->num; - ret = b->num; - } else - ret = -1; - break; - case BIO_CTRL_GET_CLOSE: - ret = b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - ret = 0; - break; - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - case BIO_CTRL_DGRAM_CONNECT: - to = (struct sockaddr *)ptr; -# if 0 - if (connect(b->num, to, sizeof(struct sockaddr)) < 0) { - perror("connect"); - ret = 0; - } else { -# endif - switch (to->sa_family) { - case AF_INET: - memcpy(&data->peer, to, sizeof(data->peer.sa_in)); - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: - memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); - break; -# endif - default: - memcpy(&data->peer, to, sizeof(data->peer.sa)); - break; - } -# if 0 - } -# endif - break; - /* (Linux)kernel sets DF bit on outgoing IP packets */ - case BIO_CTRL_DGRAM_MTU_DISCOVER: -# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) - addr_len = (socklen_t) sizeof(addr); - memset((void *)&addr, 0, sizeof(addr)); - if (getsockname(b->num, &addr.sa, &addr_len) < 0) { - ret = 0; - break; - } - switch (addr.sa.sa_family) { - case AF_INET: - sockopt_val = IP_PMTUDISC_DO; - if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, - &sockopt_val, sizeof(sockopt_val))) < 0) - perror("setsockopt"); - break; -# if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) - case AF_INET6: - sockopt_val = IPV6_PMTUDISC_DO; - if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, - &sockopt_val, sizeof(sockopt_val))) < 0) - perror("setsockopt"); - break; -# endif - default: - ret = -1; - break; - } - ret = -1; -# else - break; -# endif - case BIO_CTRL_DGRAM_QUERY_MTU: -# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU) - addr_len = (socklen_t) sizeof(addr); - memset((void *)&addr, 0, sizeof(addr)); - if (getsockname(b->num, &addr.sa, &addr_len) < 0) { - ret = 0; - break; - } - sockopt_len = sizeof(sockopt_val); - switch (addr.sa.sa_family) { - case AF_INET: - if ((ret = - getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, - &sockopt_len)) < 0 || sockopt_val < 0) { - ret = 0; - } else { - /* - * we assume that the transport protocol is UDP and no IP - * options are used. - */ - data->mtu = sockopt_val - 8 - 20; - ret = data->mtu; - } - break; -# if OPENSSL_USE_IPV6 && defined(IPV6_MTU) - case AF_INET6: - if ((ret = - getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, - (void *)&sockopt_val, &sockopt_len)) < 0 - || sockopt_val < 0) { - ret = 0; - } else { - /* - * we assume that the transport protocol is UDP and no IPV6 - * options are used. - */ - data->mtu = sockopt_val - 8 - 40; - ret = data->mtu; - } - break; -# endif - default: - ret = 0; - break; - } -# else - ret = 0; -# endif - break; - case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: - ret = -dgram_get_mtu_overhead(data); - switch (data->peer.sa.sa_family) { - case AF_INET: - ret += 576; - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: -# ifdef IN6_IS_ADDR_V4MAPPED - if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) - ret += 576; - else -# endif - ret += 1280; - break; -# endif - default: - ret += 576; - break; - } - break; - case BIO_CTRL_DGRAM_GET_MTU: - return data->mtu; - break; - case BIO_CTRL_DGRAM_SET_MTU: - data->mtu = num; - ret = num; - break; - case BIO_CTRL_DGRAM_SET_CONNECTED: - to = (struct sockaddr *)ptr; - - if (to != NULL) { - data->connected = 1; - switch (to->sa_family) { - case AF_INET: - memcpy(&data->peer, to, sizeof(data->peer.sa_in)); - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: - memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); - break; -# endif - default: - memcpy(&data->peer, to, sizeof(data->peer.sa)); - break; - } - } else { - data->connected = 0; - memset(&(data->peer), 0x00, sizeof(data->peer)); - } - break; - case BIO_CTRL_DGRAM_GET_PEER: - switch (data->peer.sa.sa_family) { - case AF_INET: - ret = sizeof(data->peer.sa_in); - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: - ret = sizeof(data->peer.sa_in6); - break; -# endif - default: - ret = sizeof(data->peer.sa); - break; - } - if (num == 0 || num > ret) - num = ret; - memcpy(ptr, &data->peer, (ret = num)); - break; - case BIO_CTRL_DGRAM_SET_PEER: - to = (struct sockaddr *)ptr; - switch (to->sa_family) { - case AF_INET: - memcpy(&data->peer, to, sizeof(data->peer.sa_in)); - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: - memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); - break; -# endif - default: - memcpy(&data->peer, to, sizeof(data->peer.sa)); - break; - } - break; - case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: - memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); - break; -# if defined(SO_RCVTIMEO) - case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: -# ifdef OPENSSL_SYS_WINDOWS - { - struct timeval *tv = (struct timeval *)ptr; - int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) { - perror("setsockopt"); - ret = -1; - } - } -# else - if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, - sizeof(struct timeval)) < 0) { - perror("setsockopt"); - ret = -1; - } -# endif - break; - case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: - { - union { - size_t s; - int i; - } sz = { - 0 - }; -# ifdef OPENSSL_SYS_WINDOWS - int timeout; - struct timeval *tv = (struct timeval *)ptr; - - sz.i = sizeof(timeout); - if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz.i) < 0) { - perror("getsockopt"); - ret = -1; - } else { - tv->tv_sec = timeout / 1000; - tv->tv_usec = (timeout % 1000) * 1000; - ret = sizeof(*tv); - } -# else - sz.i = sizeof(struct timeval); - if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - ptr, (void *)&sz) < 0) { - perror("getsockopt"); - ret = -1; - } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { - OPENSSL_assert(sz.s <= sizeof(struct timeval)); - ret = (int)sz.s; - } else - ret = sz.i; -# endif - } - break; -# endif -# if defined(SO_SNDTIMEO) - case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: -# ifdef OPENSSL_SYS_WINDOWS - { - struct timeval *tv = (struct timeval *)ptr; - int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; - if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) { - perror("setsockopt"); - ret = -1; - } - } -# else - if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, - sizeof(struct timeval)) < 0) { - perror("setsockopt"); - ret = -1; - } -# endif - break; - case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: - { - union { - size_t s; - int i; - } sz = { - 0 - }; -# ifdef OPENSSL_SYS_WINDOWS - int timeout; - struct timeval *tv = (struct timeval *)ptr; - - sz.i = sizeof(timeout); - if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - (void *)&timeout, &sz.i) < 0) { - perror("getsockopt"); - ret = -1; - } else { - tv->tv_sec = timeout / 1000; - tv->tv_usec = (timeout % 1000) * 1000; - ret = sizeof(*tv); - } -# else - sz.i = sizeof(struct timeval); - if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - ptr, (void *)&sz) < 0) { - perror("getsockopt"); - ret = -1; - } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { - OPENSSL_assert(sz.s <= sizeof(struct timeval)); - ret = (int)sz.s; - } else - ret = sz.i; -# endif - } - break; -# endif - case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: - /* fall-through */ - case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: -# ifdef OPENSSL_SYS_WINDOWS - if (data->_errno == WSAETIMEDOUT) -# else - if (data->_errno == EAGAIN) -# endif - { - ret = 1; - data->_errno = 0; - } else - ret = 0; - break; -# ifdef EMSGSIZE - case BIO_CTRL_DGRAM_MTU_EXCEEDED: - if (data->_errno == EMSGSIZE) { - ret = 1; - data->_errno = 0; - } else - ret = 0; - break; -# endif - case BIO_CTRL_DGRAM_SET_DONT_FRAG: - sockopt_val = num ? 1 : 0; - - switch (data->peer.sa.sa_family) { - case AF_INET: -# if defined(IP_DONTFRAG) - if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAG, - &sockopt_val, sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } -# elif defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined (IP_PMTUDISC_PROBE) - if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT), - (ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, - &sockopt_val, sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } -# elif defined(OPENSSL_SYS_WINDOWS) && defined(IP_DONTFRAGMENT) - if ((ret = setsockopt(b->num, IPPROTO_IP, IP_DONTFRAGMENT, - (const char *)&sockopt_val, - sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } -# else - ret = -1; -# endif - break; -# if OPENSSL_USE_IPV6 - case AF_INET6: -# if defined(IPV6_DONTFRAG) - if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_DONTFRAG, - (const void *)&sockopt_val, - sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } -# elif defined(OPENSSL_SYS_LINUX) && defined(IPV6_MTUDISCOVER) - if ((sockopt_val = num ? IP_PMTUDISC_PROBE : IP_PMTUDISC_DONT), - (ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, - &sockopt_val, sizeof(sockopt_val))) < 0) { - perror("setsockopt"); - ret = -1; - } -# else - ret = -1; -# endif - break; -# endif - default: - ret = -1; - break; - } - break; - case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: - ret = dgram_get_mtu_overhead(data); - break; - default: - ret = 0; - break; - } - return (ret); -} - -static int dgram_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = dgram_write(bp, str, n); - return (ret); -} - -# ifndef OPENSSL_NO_SCTP -BIO_METHOD *BIO_s_datagram_sctp(void) -{ - return (&methods_dgramp_sctp); -} - -BIO *BIO_new_dgram_sctp(int fd, int close_flag) -{ - BIO *bio; - int ret, optval = 20000; - int auth_data = 0, auth_forward = 0; - unsigned char *p; - struct sctp_authchunk auth; - struct sctp_authchunks *authchunks; - socklen_t sockopt_len; -# ifdef SCTP_AUTHENTICATION_EVENT -# ifdef SCTP_EVENT - struct sctp_event event; -# else - struct sctp_event_subscribe event; -# endif -# endif - - bio = BIO_new(BIO_s_datagram_sctp()); - if (bio == NULL) - return (NULL); - BIO_set_fd(bio, fd, close_flag); - - /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */ - auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE; - ret = - setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, - sizeof(struct sctp_authchunk)); - if (ret < 0) { - BIO_vfree(bio); - return (NULL); - } - auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE; - ret = - setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, - sizeof(struct sctp_authchunk)); - if (ret < 0) { - BIO_vfree(bio); - return (NULL); - } - - /* - * Test if activation was successful. When using accept(), SCTP-AUTH has - * to be activated for the listening socket already, otherwise the - * connected socket won't use it. - */ - sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); - authchunks = OPENSSL_malloc(sockopt_len); - if (!authchunks) { - BIO_vfree(bio); - return (NULL); - } - memset(authchunks, 0, sizeof(sockopt_len)); - ret = - getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, - &sockopt_len); - - if (ret < 0) { - OPENSSL_free(authchunks); - BIO_vfree(bio); - return (NULL); - } - - for (p = (unsigned char *)authchunks->gauth_chunks; - p < (unsigned char *)authchunks + sockopt_len; - p += sizeof(uint8_t)) { - if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) - auth_data = 1; - if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) - auth_forward = 1; - } - - OPENSSL_free(authchunks); - - OPENSSL_assert(auth_data); - OPENSSL_assert(auth_forward); - -# ifdef SCTP_AUTHENTICATION_EVENT -# ifdef SCTP_EVENT - memset(&event, 0, sizeof(struct sctp_event)); - event.se_assoc_id = 0; - event.se_type = SCTP_AUTHENTICATION_EVENT; - event.se_on = 1; - ret = - setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, - sizeof(struct sctp_event)); - if (ret < 0) { - BIO_vfree(bio); - return (NULL); - } -# else - sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe); - ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len); - if (ret < 0) { - BIO_vfree(bio); - return (NULL); - } - - event.sctp_authentication_event = 1; - - ret = - setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, - sizeof(struct sctp_event_subscribe)); - if (ret < 0) { - BIO_vfree(bio); - return (NULL); - } -# endif -# endif - - /* - * Disable partial delivery by setting the min size larger than the max - * record size of 2^14 + 2048 + 13 - */ - ret = - setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, - sizeof(optval)); - if (ret < 0) { - BIO_vfree(bio); - return (NULL); - } - - return (bio); -} - -int BIO_dgram_is_sctp(BIO *bio) -{ - return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP); -} - -static int dgram_sctp_new(BIO *bi) -{ - bio_dgram_sctp_data *data = NULL; - - bi->init = 0; - bi->num = 0; - data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data)); - if (data == NULL) - return 0; - memset(data, 0x00, sizeof(bio_dgram_sctp_data)); -# ifdef SCTP_PR_SCTP_NONE - data->prinfo.pr_policy = SCTP_PR_SCTP_NONE; -# endif - bi->ptr = data; - - bi->flags = 0; - return (1); -} - -static int dgram_sctp_free(BIO *a) -{ - bio_dgram_sctp_data *data; - - if (a == NULL) - return (0); - if (!dgram_clear(a)) - return 0; - - data = (bio_dgram_sctp_data *) a->ptr; - if (data != NULL) { - if (data->saved_message.data != NULL) - OPENSSL_free(data->saved_message.data); - OPENSSL_free(data); - } - - return (1); -} - -# ifdef SCTP_AUTHENTICATION_EVENT -void dgram_sctp_handle_auth_free_key_event(BIO *b, - union sctp_notification *snp) -{ - int ret; - struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event; - - if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) { - struct sctp_authkeyid authkeyid; - - /* delete key */ - authkeyid.scact_keynumber = authkeyevent->auth_keynumber; - ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, - &authkeyid, sizeof(struct sctp_authkeyid)); - } -} -# endif - -static int dgram_sctp_read(BIO *b, char *out, int outl) -{ - int ret = 0, n = 0, i, optval; - socklen_t optlen; - bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; - union sctp_notification *snp; - struct msghdr msg; - struct iovec iov; - struct cmsghdr *cmsg; - char cmsgbuf[512]; - - if (out != NULL) { - clear_socket_error(); - - do { - memset(&data->rcvinfo, 0x00, - sizeof(struct bio_dgram_sctp_rcvinfo)); - iov.iov_base = out; - iov.iov_len = outl; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = cmsgbuf; - msg.msg_controllen = 512; - msg.msg_flags = 0; - n = recvmsg(b->num, &msg, 0); - - if (n <= 0) { - if (n < 0) - ret = n; - break; - } - - if (msg.msg_controllen > 0) { - for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; - cmsg = CMSG_NXTHDR(&msg, cmsg)) { - if (cmsg->cmsg_level != IPPROTO_SCTP) - continue; -# ifdef SCTP_RCVINFO - if (cmsg->cmsg_type == SCTP_RCVINFO) { - struct sctp_rcvinfo *rcvinfo; - - rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg); - data->rcvinfo.rcv_sid = rcvinfo->rcv_sid; - data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn; - data->rcvinfo.rcv_flags = rcvinfo->rcv_flags; - data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid; - data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn; - data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn; - data->rcvinfo.rcv_context = rcvinfo->rcv_context; - } -# endif -# ifdef SCTP_SNDRCV - if (cmsg->cmsg_type == SCTP_SNDRCV) { - struct sctp_sndrcvinfo *sndrcvinfo; - - sndrcvinfo = - (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); - data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream; - data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn; - data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags; - data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid; - data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn; - data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn; - data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context; - } -# endif - } - } - - if (msg.msg_flags & MSG_NOTIFICATION) { - snp = (union sctp_notification *)out; - if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { -# ifdef SCTP_EVENT - struct sctp_event event; -# else - struct sctp_event_subscribe event; - socklen_t eventsize; -# endif - /* - * If a message has been delayed until the socket is dry, - * it can be sent now. - */ - if (data->saved_message.length > 0) { - dgram_sctp_write(data->saved_message.bio, - data->saved_message.data, - data->saved_message.length); - OPENSSL_free(data->saved_message.data); - data->saved_message.data = NULL; - data->saved_message.length = 0; - } - - /* disable sender dry event */ -# ifdef SCTP_EVENT - memset(&event, 0, sizeof(struct sctp_event)); - event.se_assoc_id = 0; - event.se_type = SCTP_SENDER_DRY_EVENT; - event.se_on = 0; - i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, - sizeof(struct sctp_event)); - if (i < 0) { - ret = i; - break; - } -# else - eventsize = sizeof(struct sctp_event_subscribe); - i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, - &eventsize); - if (i < 0) { - ret = i; - break; - } - - event.sctp_sender_dry_event = 0; - - i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, - sizeof(struct sctp_event_subscribe)); - if (i < 0) { - ret = i; - break; - } -# endif - } -# ifdef SCTP_AUTHENTICATION_EVENT - if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) - dgram_sctp_handle_auth_free_key_event(b, snp); -# endif - - if (data->handle_notifications != NULL) - data->handle_notifications(b, data->notification_context, - (void *)out); - - memset(out, 0, outl); - } else - ret += n; - } - while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) - && (ret < outl)); - - if (ret > 0 && !(msg.msg_flags & MSG_EOR)) { - /* Partial message read, this should never happen! */ - - /* - * The buffer was too small, this means the peer sent a message - * that was larger than allowed. - */ - if (ret == outl) - return -1; - - /* - * Test if socket buffer can handle max record size (2^14 + 2048 - * + 13) - */ - optlen = (socklen_t) sizeof(int); - ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen); - if (ret >= 0) - OPENSSL_assert(optval >= 18445); - - /* - * Test if SCTP doesn't partially deliver below max record size - * (2^14 + 2048 + 13) - */ - optlen = (socklen_t) sizeof(int); - ret = - getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, - &optval, &optlen); - if (ret >= 0) - OPENSSL_assert(optval >= 18445); - - /* - * Partially delivered notification??? Probably a bug.... - */ - OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION)); - - /* - * Everything seems ok till now, so it's most likely a message - * dropped by PR-SCTP. - */ - memset(out, 0, outl); - BIO_set_retry_read(b); - return -1; - } - - BIO_clear_retry_flags(b); - if (ret < 0) { - if (BIO_dgram_should_retry(ret)) { - BIO_set_retry_read(b); - data->_errno = get_last_socket_error(); - } - } - - /* Test if peer uses SCTP-AUTH before continuing */ - if (!data->peer_auth_tested) { - int ii, auth_data = 0, auth_forward = 0; - unsigned char *p; - struct sctp_authchunks *authchunks; - - optlen = - (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); - authchunks = OPENSSL_malloc(optlen); - if (!authchunks) { - BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE); - return -1; - } - memset(authchunks, 0, sizeof(optlen)); - ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, - authchunks, &optlen); - - if (ii >= 0) - for (p = (unsigned char *)authchunks->gauth_chunks; - p < (unsigned char *)authchunks + optlen; - p += sizeof(uint8_t)) { - if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) - auth_data = 1; - if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) - auth_forward = 1; - } - - OPENSSL_free(authchunks); - - if (!auth_data || !auth_forward) { - BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR); - return -1; - } - - data->peer_auth_tested = 1; - } - } - return (ret); -} - -static int dgram_sctp_write(BIO *b, const char *in, int inl) -{ - int ret; - bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; - struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo); - struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo); - struct bio_dgram_sctp_sndinfo handshake_sinfo; - struct iovec iov[1]; - struct msghdr msg; - struct cmsghdr *cmsg; -# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) - char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + - CMSG_SPACE(sizeof(struct sctp_prinfo))]; - struct sctp_sndinfo *sndinfo; - struct sctp_prinfo *prinfo; -# else - char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; - struct sctp_sndrcvinfo *sndrcvinfo; -# endif - - clear_socket_error(); - - /* - * If we're send anything else than application data, disable all user - * parameters and flags. - */ - if (in[0] != 23) { - memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo)); -# ifdef SCTP_SACK_IMMEDIATELY - handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY; -# endif - sinfo = &handshake_sinfo; - } - - /* - * If we have to send a shutdown alert message and the socket is not dry - * yet, we have to save it and send it as soon as the socket gets dry. - */ - if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) { - char *tmp; - data->saved_message.bio = b; - if (!(tmp = OPENSSL_malloc(inl))) { - BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE); - return -1; - } - if (data->saved_message.data) - OPENSSL_free(data->saved_message.data); - data->saved_message.data = tmp; - memcpy(data->saved_message.data, in, inl); - data->saved_message.length = inl; - return inl; - } - - iov[0].iov_base = (char *)in; - iov[0].iov_len = inl; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - msg.msg_control = (caddr_t) cmsgbuf; - msg.msg_controllen = 0; - msg.msg_flags = 0; -# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) - cmsg = (struct cmsghdr *)cmsgbuf; - cmsg->cmsg_level = IPPROTO_SCTP; - cmsg->cmsg_type = SCTP_SNDINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); - sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg); - memset(sndinfo, 0, sizeof(struct sctp_sndinfo)); - sndinfo->snd_sid = sinfo->snd_sid; - sndinfo->snd_flags = sinfo->snd_flags; - sndinfo->snd_ppid = sinfo->snd_ppid; - sndinfo->snd_context = sinfo->snd_context; - msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); - - cmsg = - (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))]; - cmsg->cmsg_level = IPPROTO_SCTP; - cmsg->cmsg_type = SCTP_PRINFO; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); - prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg); - memset(prinfo, 0, sizeof(struct sctp_prinfo)); - prinfo->pr_policy = pinfo->pr_policy; - prinfo->pr_value = pinfo->pr_value; - msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); -# else - cmsg = (struct cmsghdr *)cmsgbuf; - cmsg->cmsg_level = IPPROTO_SCTP; - cmsg->cmsg_type = SCTP_SNDRCV; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); - sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); - memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); - sndrcvinfo->sinfo_stream = sinfo->snd_sid; - sndrcvinfo->sinfo_flags = sinfo->snd_flags; -# ifdef __FreeBSD__ - sndrcvinfo->sinfo_flags |= pinfo->pr_policy; -# endif - sndrcvinfo->sinfo_ppid = sinfo->snd_ppid; - sndrcvinfo->sinfo_context = sinfo->snd_context; - sndrcvinfo->sinfo_timetolive = pinfo->pr_value; - msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); -# endif - - ret = sendmsg(b->num, &msg, 0); - - BIO_clear_retry_flags(b); - if (ret <= 0) { - if (BIO_dgram_should_retry(ret)) { - BIO_set_retry_write(b); - data->_errno = get_last_socket_error(); - } - } - return (ret); -} - -static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret = 1; - bio_dgram_sctp_data *data = NULL; - socklen_t sockopt_len = 0; - struct sctp_authkeyid authkeyid; - struct sctp_authkey *authkey = NULL; - - data = (bio_dgram_sctp_data *) b->ptr; - - switch (cmd) { - case BIO_CTRL_DGRAM_QUERY_MTU: - /* - * Set to maximum (2^14) and ignore user input to enable transport - * protocol fragmentation. Returns always 2^14. - */ - data->mtu = 16384; - ret = data->mtu; - break; - case BIO_CTRL_DGRAM_SET_MTU: - /* - * Set to maximum (2^14) and ignore input to enable transport - * protocol fragmentation. Returns always 2^14. - */ - data->mtu = 16384; - ret = data->mtu; - break; - case BIO_CTRL_DGRAM_SET_CONNECTED: - case BIO_CTRL_DGRAM_CONNECT: - /* Returns always -1. */ - ret = -1; - break; - case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: - /* - * SCTP doesn't need the DTLS timer Returns always 1. - */ - break; - case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: - /* - * We allow transport protocol fragmentation so this is irrelevant - */ - ret = 0; - break; - case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE: - if (num > 0) - data->in_handshake = 1; - else - data->in_handshake = 0; - - ret = - setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, - &data->in_handshake, sizeof(int)); - break; - case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY: - /* - * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise. - */ - - /* Get active key */ - sockopt_len = sizeof(struct sctp_authkeyid); - ret = - getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, - &sockopt_len); - if (ret < 0) - break; - - /* Add new key */ - sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t); - authkey = OPENSSL_malloc(sockopt_len); - if (authkey == NULL) { - ret = -1; - break; - } - memset(authkey, 0x00, sockopt_len); - authkey->sca_keynumber = authkeyid.scact_keynumber + 1; -# ifndef __FreeBSD__ - /* - * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3 - * and higher work without it. - */ - authkey->sca_keylength = 64; -# endif - memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t)); - - ret = - setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, - sockopt_len); - OPENSSL_free(authkey); - authkey = NULL; - if (ret < 0) - break; - - /* Reset active key */ - ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, - &authkeyid, sizeof(struct sctp_authkeyid)); - if (ret < 0) - break; - - break; - case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY: - /* Returns 0 on success, -1 otherwise. */ - - /* Get active key */ - sockopt_len = sizeof(struct sctp_authkeyid); - ret = - getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, - &sockopt_len); - if (ret < 0) - break; - - /* Set active key */ - authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1; - ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, - &authkeyid, sizeof(struct sctp_authkeyid)); - if (ret < 0) - break; - - /* - * CCS has been sent, so remember that and fall through to check if - * we need to deactivate an old key - */ - data->ccs_sent = 1; - - case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD: - /* Returns 0 on success, -1 otherwise. */ - - /* - * Has this command really been called or is this just a - * fall-through? - */ - if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD) - data->ccs_rcvd = 1; - - /* - * CSS has been both, received and sent, so deactivate an old key - */ - if (data->ccs_rcvd == 1 && data->ccs_sent == 1) { - /* Get active key */ - sockopt_len = sizeof(struct sctp_authkeyid); - ret = - getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, - &authkeyid, &sockopt_len); - if (ret < 0) - break; - - /* - * Deactivate key or delete second last key if - * SCTP_AUTHENTICATION_EVENT is not available. - */ - authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; -# ifdef SCTP_AUTH_DEACTIVATE_KEY - sockopt_len = sizeof(struct sctp_authkeyid); - ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY, - &authkeyid, sockopt_len); - if (ret < 0) - break; -# endif -# ifndef SCTP_AUTHENTICATION_EVENT - if (authkeyid.scact_keynumber > 0) { - authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; - ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, - &authkeyid, sizeof(struct sctp_authkeyid)); - if (ret < 0) - break; - } -# endif - - data->ccs_rcvd = 0; - data->ccs_sent = 0; - } - break; - case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO: - /* Returns the size of the copied struct. */ - if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo)) - num = sizeof(struct bio_dgram_sctp_sndinfo); - - memcpy(ptr, &(data->sndinfo), num); - ret = num; - break; - case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO: - /* Returns the size of the copied struct. */ - if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo)) - num = sizeof(struct bio_dgram_sctp_sndinfo); - - memcpy(&(data->sndinfo), ptr, num); - break; - case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO: - /* Returns the size of the copied struct. */ - if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo)) - num = sizeof(struct bio_dgram_sctp_rcvinfo); - - memcpy(ptr, &data->rcvinfo, num); - - ret = num; - break; - case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO: - /* Returns the size of the copied struct. */ - if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo)) - num = sizeof(struct bio_dgram_sctp_rcvinfo); - - memcpy(&(data->rcvinfo), ptr, num); - break; - case BIO_CTRL_DGRAM_SCTP_GET_PRINFO: - /* Returns the size of the copied struct. */ - if (num > (long)sizeof(struct bio_dgram_sctp_prinfo)) - num = sizeof(struct bio_dgram_sctp_prinfo); - - memcpy(ptr, &(data->prinfo), num); - ret = num; - break; - case BIO_CTRL_DGRAM_SCTP_SET_PRINFO: - /* Returns the size of the copied struct. */ - if (num > (long)sizeof(struct bio_dgram_sctp_prinfo)) - num = sizeof(struct bio_dgram_sctp_prinfo); - - memcpy(&(data->prinfo), ptr, num); - break; - case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN: - /* Returns always 1. */ - if (num > 0) - data->save_shutdown = 1; - else - data->save_shutdown = 0; - break; - - default: - /* - * Pass to default ctrl function to process SCTP unspecific commands - */ - ret = dgram_ctrl(b, cmd, num, ptr); - break; - } - return (ret); -} - -int BIO_dgram_sctp_notification_cb(BIO *b, - void (*handle_notifications) (BIO *bio, - void - *context, - void *buf), - void *context) -{ - bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; - - if (handle_notifications != NULL) { - data->handle_notifications = handle_notifications; - data->notification_context = context; - } else - return -1; - - return 0; -} - -int BIO_dgram_sctp_wait_for_dry(BIO *b) -{ - int is_dry = 0; - int n, sockflags, ret; - union sctp_notification snp; - struct msghdr msg; - struct iovec iov; -# ifdef SCTP_EVENT - struct sctp_event event; -# else - struct sctp_event_subscribe event; - socklen_t eventsize; -# endif - bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; - - /* set sender dry event */ -# ifdef SCTP_EVENT - memset(&event, 0, sizeof(struct sctp_event)); - event.se_assoc_id = 0; - event.se_type = SCTP_SENDER_DRY_EVENT; - event.se_on = 1; - ret = - setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, - sizeof(struct sctp_event)); -# else - eventsize = sizeof(struct sctp_event_subscribe); - ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); - if (ret < 0) - return -1; - - event.sctp_sender_dry_event = 1; - - ret = - setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, - sizeof(struct sctp_event_subscribe)); -# endif - if (ret < 0) - return -1; - - /* peek for notification */ - memset(&snp, 0x00, sizeof(union sctp_notification)); - iov.iov_base = (char *)&snp; - iov.iov_len = sizeof(union sctp_notification); - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - n = recvmsg(b->num, &msg, MSG_PEEK); - if (n <= 0) { - if ((n < 0) && (get_last_socket_error() != EAGAIN) - && (get_last_socket_error() != EWOULDBLOCK)) - return -1; - else - return 0; - } - - /* if we find a notification, process it and try again if necessary */ - while (msg.msg_flags & MSG_NOTIFICATION) { - memset(&snp, 0x00, sizeof(union sctp_notification)); - iov.iov_base = (char *)&snp; - iov.iov_len = sizeof(union sctp_notification); - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - n = recvmsg(b->num, &msg, 0); - if (n <= 0) { - if ((n < 0) && (get_last_socket_error() != EAGAIN) - && (get_last_socket_error() != EWOULDBLOCK)) - return -1; - else - return is_dry; - } - - if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { - is_dry = 1; - - /* disable sender dry event */ -# ifdef SCTP_EVENT - memset(&event, 0, sizeof(struct sctp_event)); - event.se_assoc_id = 0; - event.se_type = SCTP_SENDER_DRY_EVENT; - event.se_on = 0; - ret = - setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, - sizeof(struct sctp_event)); -# else - eventsize = (socklen_t) sizeof(struct sctp_event_subscribe); - ret = - getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, - &eventsize); - if (ret < 0) - return -1; - - event.sctp_sender_dry_event = 0; - - ret = - setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, - sizeof(struct sctp_event_subscribe)); -# endif - if (ret < 0) - return -1; - } -# ifdef SCTP_AUTHENTICATION_EVENT - if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) - dgram_sctp_handle_auth_free_key_event(b, &snp); -# endif - - if (data->handle_notifications != NULL) - data->handle_notifications(b, data->notification_context, - (void *)&snp); - - /* found notification, peek again */ - memset(&snp, 0x00, sizeof(union sctp_notification)); - iov.iov_base = (char *)&snp; - iov.iov_len = sizeof(union sctp_notification); - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - /* if we have seen the dry already, don't wait */ - if (is_dry) { - sockflags = fcntl(b->num, F_GETFL, 0); - fcntl(b->num, F_SETFL, O_NONBLOCK); - } - - n = recvmsg(b->num, &msg, MSG_PEEK); - - if (is_dry) { - fcntl(b->num, F_SETFL, sockflags); - } - - if (n <= 0) { - if ((n < 0) && (get_last_socket_error() != EAGAIN) - && (get_last_socket_error() != EWOULDBLOCK)) - return -1; - else - return is_dry; - } - } - - /* read anything else */ - return is_dry; -} - -int BIO_dgram_sctp_msg_waiting(BIO *b) -{ - int n, sockflags; - union sctp_notification snp; - struct msghdr msg; - struct iovec iov; - bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; - - /* Check if there are any messages waiting to be read */ - do { - memset(&snp, 0x00, sizeof(union sctp_notification)); - iov.iov_base = (char *)&snp; - iov.iov_len = sizeof(union sctp_notification); - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - sockflags = fcntl(b->num, F_GETFL, 0); - fcntl(b->num, F_SETFL, O_NONBLOCK); - n = recvmsg(b->num, &msg, MSG_PEEK); - fcntl(b->num, F_SETFL, sockflags); - - /* if notification, process and try again */ - if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) { -# ifdef SCTP_AUTHENTICATION_EVENT - if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) - dgram_sctp_handle_auth_free_key_event(b, &snp); -# endif - - memset(&snp, 0x00, sizeof(union sctp_notification)); - iov.iov_base = (char *)&snp; - iov.iov_len = sizeof(union sctp_notification); - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - n = recvmsg(b->num, &msg, 0); - - if (data->handle_notifications != NULL) - data->handle_notifications(b, data->notification_context, - (void *)&snp); - } - - } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)); - - /* Return 1 if there is a message to be read, return 0 otherwise. */ - if (n > 0) - return 1; - else - return 0; -} - -static int dgram_sctp_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = dgram_sctp_write(bp, str, n); - return (ret); -} -# endif - -static int BIO_dgram_should_retry(int i) -{ - int err; - - if ((i == 0) || (i == -1)) { - err = get_last_socket_error(); - -# if defined(OPENSSL_SYS_WINDOWS) - /* - * If the socket return value (i) is -1 and err is unexpectedly 0 at - * this point, the error code was overwritten by another system call - * before this error handling is called. - */ -# endif - - return (BIO_dgram_non_fatal_error(err)); - } - return (0); -} - -int BIO_dgram_non_fatal_error(int err) -{ - switch (err) { -# if defined(OPENSSL_SYS_WINDOWS) -# if defined(WSAEWOULDBLOCK) - case WSAEWOULDBLOCK: -# endif - -# if 0 /* This appears to always be an error */ -# if defined(WSAENOTCONN) - case WSAENOTCONN: -# endif -# endif -# endif - -# ifdef EWOULDBLOCK -# ifdef WSAEWOULDBLOCK -# if WSAEWOULDBLOCK != EWOULDBLOCK - case EWOULDBLOCK: -# endif -# else - case EWOULDBLOCK: -# endif -# endif - -# ifdef EINTR - case EINTR: -# endif - -# ifdef EAGAIN -# if EWOULDBLOCK != EAGAIN - case EAGAIN: -# endif -# endif - -# ifdef EPROTO - case EPROTO: -# endif - -# ifdef EINPROGRESS - case EINPROGRESS: -# endif - -# ifdef EALREADY - case EALREADY: -# endif - - return (1); - /* break; */ - default: - break; - } - return (0); -} - -static void get_current_time(struct timeval *t) -{ -# if defined(_WIN32) - SYSTEMTIME st; - union { - unsigned __int64 ul; - FILETIME ft; - } now; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &now.ft); -# ifdef __MINGW32__ - now.ul -= 116444736000000000ULL; -# else - now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ -# endif - t->tv_sec = (long)(now.ul / 10000000); - t->tv_usec = ((int)(now.ul % 10000000)) / 10; -# elif defined(OPENSSL_SYS_VMS) - struct timeb tb; - ftime(&tb); - t->tv_sec = (long)tb.time; - t->tv_usec = (long)tb.millitm * 1000; -# else - gettimeofday(t, NULL); -# endif -} - -#endif -/* crypto/bio/bss_fd.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#define USE_SOCKETS -// #include "cryptlib.h" - -#if defined(OPENSSL_NO_POSIX_IO) -/* - * Dummy placeholder for BIO_s_fd... - */ -BIO *BIO_new_fd(int fd, int close_flag) -{ - return NULL; -} - -int BIO_fd_non_fatal_error(int err) -{ - return 0; -} - -int BIO_fd_should_retry(int i) -{ - return 0; -} - -BIO_METHOD *BIO_s_fd(void) -{ - return NULL; -} -#else -/* - * As for unconditional usage of "UPLINK" interface in this module. - * Trouble is that unlike Unix file descriptors [which are indexes - * in kernel-side per-process table], corresponding descriptors on - * platforms which require "UPLINK" interface seem to be indexes - * in a user-land, non-global table. Well, in fact they are indexes - * in stdio _iob[], and recall that _iob[] was the very reason why - * "UPLINK" interface was introduced in first place. But one way on - * another. Neither libcrypto or libssl use this BIO meaning that - * file descriptors can only be provided by application. Therefore - * "UPLINK" calls are due... - */ -# include "bio_lcl.h" - -static int fd_write(BIO *h, const char *buf, int num); -static int fd_read(BIO *h, char *buf, int size); -static int fd_puts(BIO *h, const char *str); -static int fd_gets(BIO *h, char *buf, int size); -static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int fd_new(BIO *h); -static int fd_free(BIO *data); -int BIO_fd_should_retry(int s); - -static BIO_METHOD methods_fdp = { - BIO_TYPE_FD, "file descriptor", - fd_write, - fd_read, - fd_puts, - fd_gets, - fd_ctrl, - fd_new, - fd_free, - NULL, -}; - -BIO_METHOD *BIO_s_fd(void) -{ - return (&methods_fdp); -} - -BIO *BIO_new_fd(int fd, int close_flag) -{ - BIO *ret; - ret = BIO_new(BIO_s_fd()); - if (ret == NULL) - return (NULL); - BIO_set_fd(ret, fd, close_flag); - return (ret); -} - -static int fd_new(BIO *bi) -{ - bi->init = 0; - bi->num = -1; - bi->ptr = NULL; - bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */ - return (1); -} - -static int fd_free(BIO *a) -{ - if (a == NULL) - return (0); - if (a->shutdown) { - if (a->init) { - UP_close(a->num); - } - a->init = 0; - a->flags = BIO_FLAGS_UPLINK; - } - return (1); -} - -static int fd_read(BIO *b, char *out, int outl) -{ - int ret = 0; - - if (out != NULL) { - clear_sys_error(); - ret = UP_read(b->num, out, outl); - BIO_clear_retry_flags(b); - if (ret <= 0) { - if (BIO_fd_should_retry(ret)) - BIO_set_retry_read(b); - } - } - return (ret); -} - -static int fd_write(BIO *b, const char *in, int inl) -{ - int ret; - clear_sys_error(); - ret = UP_write(b->num, in, inl); - BIO_clear_retry_flags(b); - if (ret <= 0) { - if (BIO_fd_should_retry(ret)) - BIO_set_retry_write(b); - } - return (ret); -} - -static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret = 1; - int *ip; - - switch (cmd) { - case BIO_CTRL_RESET: - num = 0; - case BIO_C_FILE_SEEK: - ret = (long)UP_lseek(b->num, num, 0); - break; - case BIO_C_FILE_TELL: - case BIO_CTRL_INFO: - ret = (long)UP_lseek(b->num, 0, 1); - break; - case BIO_C_SET_FD: - fd_free(b); - b->num = *((int *)ptr); - b->shutdown = (int)num; - b->init = 1; - break; - case BIO_C_GET_FD: - if (b->init) { - ip = (int *)ptr; - if (ip != NULL) - *ip = b->num; - ret = b->num; - } else - ret = -1; - break; - case BIO_CTRL_GET_CLOSE: - ret = b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - ret = 0; - break; - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - default: - ret = 0; - break; - } - return (ret); -} - -static int fd_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = fd_write(bp, str, n); - return (ret); -} - -static int fd_gets(BIO *bp, char *buf, int size) -{ - int ret = 0; - char *ptr = buf; - char *end = buf + size - 1; - - while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n')) - ptr++; - - ptr[0] = '\0'; - - if (buf[0] != '\0') - ret = strlen(buf); - return (ret); -} - -int BIO_fd_should_retry(int i) -{ - int err; - - if ((i == 0) || (i == -1)) { - err = get_last_sys_error(); - -# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps - * not? Ben 4/1/99 */ - if ((i == -1) && (err == 0)) - return (1); -# endif - - return (BIO_fd_non_fatal_error(err)); - } - return (0); -} - -int BIO_fd_non_fatal_error(int err) -{ - switch (err) { - -# ifdef EWOULDBLOCK -# ifdef WSAEWOULDBLOCK -# if WSAEWOULDBLOCK != EWOULDBLOCK - case EWOULDBLOCK: -# endif -# else - case EWOULDBLOCK: -# endif -# endif - -# if defined(ENOTCONN) - case ENOTCONN: -# endif - -# ifdef EINTR - case EINTR: -# endif - -# ifdef EAGAIN -# if EWOULDBLOCK != EAGAIN - case EAGAIN: -# endif -# endif - -# ifdef EPROTO - case EPROTO: -# endif - -# ifdef EINPROGRESS - case EINPROGRESS: -# endif - -# ifdef EALREADY - case EALREADY: -# endif - return (1); - /* break; */ - default: - break; - } - return (0); -} -#endif -/* crypto/bio/bss_file.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/*- - * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout - * with binary data (e.g. asn1parse -inform DER < xxx) under - * Windows - */ - -#ifndef HEADER_BSS_FILE_C -# define HEADER_BSS_FILE_C - -# if defined(__linux) || defined(__sun) || defined(__hpux) -/* - * Following definition aliases fopen to fopen64 on above mentioned - * platforms. This makes it possible to open and sequentially access files - * larger than 2GB from 32-bit application. It does not allow to traverse - * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit - * platform permits that, not with fseek/ftell. Not to mention that breaking - * 2GB limit for seeking would require surgery to *our* API. But sequential - * access suffices for practical cases when you can run into large files, - * such as fingerprinting, so we can let API alone. For reference, the list - * of 32-bit platforms which allow for sequential access of large files - * without extra "magic" comprise *BSD, Darwin, IRIX... - */ -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# endif - -# include -# include -# include "cryptlib.h" -# include "bio_lcl.h" -# include "err.h" - -# if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) -# include -# endif - -# if !defined(OPENSSL_NO_STDIO) - -static int MS_CALLBACK file_write(BIO *h, const char *buf, int num); -static int MS_CALLBACK file_read(BIO *h, char *buf, int size); -static int MS_CALLBACK file_puts(BIO *h, const char *str); -static int MS_CALLBACK file_gets(BIO *h, char *str, int size); -static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int MS_CALLBACK file_new(BIO *h); -static int MS_CALLBACK file_free(BIO *data); -static BIO_METHOD methods_filep = { - BIO_TYPE_FILE, - "FILE pointer", - file_write, - file_read, - file_puts, - file_gets, - file_ctrl, - file_new, - file_free, - NULL, -}; - -static FILE *file_fopen(const char *filename, const char *mode) -{ - FILE *file = NULL; - -# if defined(_WIN32) && defined(CP_UTF8) - int sz, len_0 = (int)strlen(filename) + 1; - DWORD flags; - - /* - * Basically there are three cases to cover: a) filename is - * pure ASCII string; b) actual UTF-8 encoded string and - * c) locale-ized string, i.e. one containing 8-bit - * characters that are meaningful in current system locale. - * If filename is pure ASCII or real UTF-8 encoded string, - * MultiByteToWideChar succeeds and _wfopen works. If - * filename is locale-ized string, chances are that - * MultiByteToWideChar fails reporting - * ERROR_NO_UNICODE_TRANSLATION, in which case we fall - * back to fopen... - */ - if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS), - filename, len_0, NULL, 0)) > 0 || - (GetLastError() == ERROR_INVALID_FLAGS && - (sz = MultiByteToWideChar(CP_UTF8, (flags = 0), - filename, len_0, NULL, 0)) > 0) - ) { - WCHAR wmode[8]; - WCHAR *wfilename = _alloca(sz * sizeof(WCHAR)); - - if (MultiByteToWideChar(CP_UTF8, flags, - filename, len_0, wfilename, sz) && - MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1, - wmode, sizeof(wmode) / sizeof(wmode[0])) && - (file = _wfopen(wfilename, wmode)) == NULL && - (errno == ENOENT || errno == EBADF) - ) { - /* - * UTF-8 decode succeeded, but no file, filename - * could still have been locale-ized... - */ - file = fopen(filename, mode); - } - } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { - file = fopen(filename, mode); - } -# else - file = fopen(filename, mode); -# endif - return (file); -} - -BIO *BIO_new_file(const char *filename, const char *mode) -{ - BIO *ret; - FILE *file = file_fopen(filename, mode); - - if (file == NULL) { - SYSerr(SYS_F_FOPEN, get_last_sys_error()); - ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); - if (errno == ENOENT -# ifdef ENXIO - || errno == ENXIO -# endif - ) - BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); - else - BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB); - return (NULL); - } - if ((ret = BIO_new(BIO_s_file())) == NULL) { - fclose(file); - return (NULL); - } - - BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage - * UPLINK */ - BIO_set_fp(ret, file, BIO_CLOSE); - return (ret); -} - -BIO *BIO_new_fp(FILE *stream, int close_flag) -{ - BIO *ret; - - if ((ret = BIO_new(BIO_s_file())) == NULL) - return (NULL); - - BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for - * documentation puposes */ - BIO_set_fp(ret, stream, close_flag); - return (ret); -} - -BIO_METHOD *BIO_s_file(void) -{ - return (&methods_filep); -} - -static int MS_CALLBACK file_new(BIO *bi) -{ - bi->init = 0; - bi->num = 0; - bi->ptr = NULL; - bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */ - return (1); -} - -static int MS_CALLBACK file_free(BIO *a) -{ - if (a == NULL) - return (0); - if (a->shutdown) { - if ((a->init) && (a->ptr != NULL)) { - if (a->flags & BIO_FLAGS_UPLINK) - UP_fclose(a->ptr); - else - fclose(a->ptr); - a->ptr = NULL; - a->flags = BIO_FLAGS_UPLINK; - } - a->init = 0; - } - return (1); -} - -static int MS_CALLBACK file_read(BIO *b, char *out, int outl) -{ - int ret = 0; - - if (b->init && (out != NULL)) { - if (b->flags & BIO_FLAGS_UPLINK) - ret = UP_fread(out, 1, (int)outl, b->ptr); - else - ret = fread(out, 1, (int)outl, (FILE *)b->ptr); - if (ret == 0 - && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) : - ferror((FILE *)b->ptr)) { - SYSerr(SYS_F_FREAD, get_last_sys_error()); - BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); - ret = -1; - } - } - return (ret); -} - -static int MS_CALLBACK file_write(BIO *b, const char *in, int inl) -{ - int ret = 0; - - if (b->init && (in != NULL)) { - if (b->flags & BIO_FLAGS_UPLINK) - ret = UP_fwrite(in, (int)inl, 1, b->ptr); - else - ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr); - if (ret) - ret = inl; - /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */ - /* - * according to Tim Hudson , the commented out - * version above can cause 'inl' write calls under some stupid stdio - * implementations (VMS) - */ - } - return (ret); -} - -static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret = 1; - FILE *fp = (FILE *)b->ptr; - FILE **fpp; - char p[4]; - int st; - - switch (cmd) { - case BIO_C_FILE_SEEK: - case BIO_CTRL_RESET: - if (b->flags & BIO_FLAGS_UPLINK) - ret = (long)UP_fseek(b->ptr, num, 0); - else - ret = (long)fseek(fp, num, 0); - break; - case BIO_CTRL_EOF: - if (b->flags & BIO_FLAGS_UPLINK) - ret = (long)UP_feof(fp); - else - ret = (long)feof(fp); - break; - case BIO_C_FILE_TELL: - case BIO_CTRL_INFO: - if (b->flags & BIO_FLAGS_UPLINK) - ret = UP_ftell(b->ptr); - else - ret = ftell(fp); - break; - case BIO_C_SET_FILE_PTR: - file_free(b); - b->shutdown = (int)num & BIO_CLOSE; - b->ptr = ptr; - b->init = 1; -# if BIO_FLAGS_UPLINK!=0 -# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) -# define _IOB_ENTRIES 20 -# endif - /* Safety net to catch purely internal BIO_set_fp calls */ -# if defined(_MSC_VER) && _MSC_VER>=1900 - if (ptr == stdin || ptr == stdout || ptr == stderr) - BIO_clear_flags(b, BIO_FLAGS_UPLINK); -# elif defined(_IOB_ENTRIES) - if ((size_t)ptr >= (size_t)stdin && - (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) - BIO_clear_flags(b, BIO_FLAGS_UPLINK); -# endif -# endif -# ifdef UP_fsetmod - if (b->flags & BIO_FLAGS_UPLINK) - UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); - else -# endif - { -# if defined(OPENSSL_SYS_WINDOWS) - int fd = _fileno((FILE *)ptr); - if (num & BIO_FP_TEXT) - _setmode(fd, _O_TEXT); - else - _setmode(fd, _O_BINARY); -# elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) - int fd = fileno((FILE *)ptr); - /* Under CLib there are differences in file modes */ - if (num & BIO_FP_TEXT) - setmode(fd, O_TEXT); - else - setmode(fd, O_BINARY); -# elif defined(OPENSSL_SYS_MSDOS) - int fd = fileno((FILE *)ptr); - /* Set correct text/binary mode */ - if (num & BIO_FP_TEXT) - _setmode(fd, _O_TEXT); - /* Dangerous to set stdin/stdout to raw (unless redirected) */ - else { - if (fd == STDIN_FILENO || fd == STDOUT_FILENO) { - if (isatty(fd) <= 0) - _setmode(fd, _O_BINARY); - } else - _setmode(fd, _O_BINARY); - } -# elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) - int fd = fileno((FILE *)ptr); - if (num & BIO_FP_TEXT) - setmode(fd, O_TEXT); - else - setmode(fd, O_BINARY); -# endif - } - break; - case BIO_C_SET_FILENAME: - file_free(b); - b->shutdown = (int)num & BIO_CLOSE; - if (num & BIO_FP_APPEND) { - if (num & BIO_FP_READ) - BUF_strlcpy(p, "a+", sizeof(p)); - else - BUF_strlcpy(p, "a", sizeof(p)); - } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) - BUF_strlcpy(p, "r+", sizeof(p)); - else if (num & BIO_FP_WRITE) - BUF_strlcpy(p, "w", sizeof(p)); - else if (num & BIO_FP_READ) - BUF_strlcpy(p, "r", sizeof(p)); - else { - BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE); - ret = 0; - break; - } -# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) - if (!(num & BIO_FP_TEXT)) - strcat(p, "b"); - else - strcat(p, "t"); -# endif -# if defined(OPENSSL_SYS_NETWARE) - if (!(num & BIO_FP_TEXT)) - strcat(p, "b"); - else - strcat(p, "t"); -# endif - fp = file_fopen(ptr, p); - if (fp == NULL) { - SYSerr(SYS_F_FOPEN, get_last_sys_error()); - ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); - BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); - ret = 0; - break; - } - b->ptr = fp; - b->init = 1; - BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage - * UPLINK */ - break; - case BIO_C_GET_FILE_PTR: - /* the ptr parameter is actually a FILE ** in this case. */ - if (ptr != NULL) { - fpp = (FILE **)ptr; - *fpp = (FILE *)b->ptr; - } - break; - case BIO_CTRL_GET_CLOSE: - ret = (long)b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_FLUSH: - st = b->flags & BIO_FLAGS_UPLINK - ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr); - if (st == EOF) { - SYSerr(SYS_F_FFLUSH, get_last_sys_error()); - ERR_add_error_data(1, "fflush()"); - BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); - ret = 0; - } - break; - case BIO_CTRL_DUP: - ret = 1; - break; - - case BIO_CTRL_WPENDING: - case BIO_CTRL_PENDING: - case BIO_CTRL_PUSH: - case BIO_CTRL_POP: - default: - ret = 0; - break; - } - return (ret); -} - -static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) -{ - int ret = 0; - - buf[0] = '\0'; - if (bp->flags & BIO_FLAGS_UPLINK) { - if (!UP_fgets(buf, size, bp->ptr)) - goto err; - } else { - if (!fgets(buf, size, (FILE *)bp->ptr)) - goto err; - } - if (buf[0] != '\0') - ret = strlen(buf); - err: - return (ret); -} - -static int MS_CALLBACK file_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = file_write(bp, str, n); - return (ret); -} - -# endif /* OPENSSL_NO_STDIO */ - -#endif /* HEADER_BSS_FILE_C */ -/* crypto/bio/bss_log.c */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * Why BIO_s_log? - * - * BIO_s_log is useful for system daemons (or services under NT). It is - * one-way BIO, it sends all stuff to syslogd (on system that commonly use - * that), or event log (on NT), or OPCOM (on OpenVMS). - * - */ - -#include -#include - -// #include "cryptlib.h" - -#if defined(OPENSSL_SYS_WINCE) -#elif defined(OPENSSL_SYS_WIN32) -#elif defined(OPENSSL_SYS_VMS) -# include -# include -# include -# include -/* Some compiler options may mask the declaration of "_malloc32". */ -# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE -# if __INITIAL_POINTER_SIZE == 64 -# pragma pointer_size save -# pragma pointer_size 32 -void *_malloc32(__size_t); -# pragma pointer_size restore -# endif /* __INITIAL_POINTER_SIZE == 64 */ -# endif /* __INITIAL_POINTER_SIZE && defined - * _ANSI_C_SOURCE */ -#elif defined(__ultrix) -# include -#elif defined(OPENSSL_SYS_NETWARE) -# define NO_SYSLOG -#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) -# include -#endif - -#include "buffer.h" -// #include "err.h" - -#ifndef NO_SYSLOG - -# if defined(OPENSSL_SYS_WIN32) -# define LOG_EMERG 0 -# define LOG_ALERT 1 -# define LOG_CRIT 2 -# define LOG_ERR 3 -# define LOG_WARNING 4 -# define LOG_NOTICE 5 -# define LOG_INFO 6 -# define LOG_DEBUG 7 - -# define LOG_DAEMON (3<<3) -# elif defined(OPENSSL_SYS_VMS) -/* On VMS, we don't really care about these, but we need them to compile */ -# define LOG_EMERG 0 -# define LOG_ALERT 1 -# define LOG_CRIT 2 -# define LOG_ERR 3 -# define LOG_WARNING 4 -# define LOG_NOTICE 5 -# define LOG_INFO 6 -# define LOG_DEBUG 7 - -# define LOG_DAEMON OPC$M_NM_NTWORK -# endif - -static int MS_CALLBACK slg_write(BIO *h, const char *buf, int num); -static int MS_CALLBACK slg_puts(BIO *h, const char *str); -static long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int MS_CALLBACK slg_new(BIO *h); -static int MS_CALLBACK slg_free(BIO *data); -static void xopenlog(BIO *bp, char *name, int level); -static void xsyslog(BIO *bp, int priority, const char *string); -static void xcloselog(BIO *bp); - -static BIO_METHOD methods_slg = { - BIO_TYPE_MEM, "syslog", - slg_write, - NULL, - slg_puts, - NULL, - slg_ctrl, - slg_new, - slg_free, - NULL, -}; - -BIO_METHOD *BIO_s_log(void) -{ - return (&methods_slg); -} - -static int MS_CALLBACK slg_new(BIO *bi) -{ - bi->init = 1; - bi->num = 0; - bi->ptr = NULL; - xopenlog(bi, "application", LOG_DAEMON); - return (1); -} - -static int MS_CALLBACK slg_free(BIO *a) -{ - if (a == NULL) - return (0); - xcloselog(a); - return (1); -} - -static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) -{ - int ret = inl; - char *buf; - char *pp; - int priority, i; - static const struct { - int strl; - char str[10]; - int log_level; - } mapping[] = { - { - 6, "PANIC ", LOG_EMERG - }, - { - 6, "EMERG ", LOG_EMERG - }, - { - 4, "EMR ", LOG_EMERG - }, - { - 6, "ALERT ", LOG_ALERT - }, - { - 4, "ALR ", LOG_ALERT - }, - { - 5, "CRIT ", LOG_CRIT - }, - { - 4, "CRI ", LOG_CRIT - }, - { - 6, "ERROR ", LOG_ERR - }, - { - 4, "ERR ", LOG_ERR - }, - { - 8, "WARNING ", LOG_WARNING - }, - { - 5, "WARN ", LOG_WARNING - }, - { - 4, "WAR ", LOG_WARNING - }, - { - 7, "NOTICE ", LOG_NOTICE - }, - { - 5, "NOTE ", LOG_NOTICE - }, - { - 4, "NOT ", LOG_NOTICE - }, - { - 5, "INFO ", LOG_INFO - }, - { - 4, "INF ", LOG_INFO - }, - { - 6, "DEBUG ", LOG_DEBUG - }, - { - 4, "DBG ", LOG_DEBUG - }, - { - 0, "", LOG_ERR - } - /* The default */ - }; - - if ((buf = (char *)OPENSSL_malloc(inl + 1)) == NULL) { - return (0); - } - memcpy(buf, in, inl); - buf[inl] = '\0'; - - i = 0; - while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0) - i++; - priority = mapping[i].log_level; - pp = buf + mapping[i].strl; - - xsyslog(b, priority, pp); - - OPENSSL_free(buf); - return (ret); -} - -static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - switch (cmd) { - case BIO_CTRL_SET: - xcloselog(b); - xopenlog(b, ptr, num); - break; - default: - break; - } - return (0); -} - -static int MS_CALLBACK slg_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = slg_write(bp, str, n); - return (ret); -} - -# if defined(OPENSSL_SYS_WIN32) - -static void xopenlog(BIO *bp, char *name, int level) -{ - if (check_winnt()) - bp->ptr = RegisterEventSourceA(NULL, name); - else - bp->ptr = NULL; -} - -static void xsyslog(BIO *bp, int priority, const char *string) -{ - LPCSTR lpszStrings[2]; - WORD evtype = EVENTLOG_ERROR_TYPE; - char pidbuf[DECIMAL_SIZE(DWORD) + 4]; - - if (bp->ptr == NULL) - return; - - switch (priority) { - case LOG_EMERG: - case LOG_ALERT: - case LOG_CRIT: - case LOG_ERR: - evtype = EVENTLOG_ERROR_TYPE; - break; - case LOG_WARNING: - evtype = EVENTLOG_WARNING_TYPE; - break; - case LOG_NOTICE: - case LOG_INFO: - case LOG_DEBUG: - evtype = EVENTLOG_INFORMATION_TYPE; - break; - default: - /* - * Should never happen, but set it - * as error anyway. - */ - evtype = EVENTLOG_ERROR_TYPE; - break; - } - - sprintf(pidbuf, "[%u] ", GetCurrentProcessId()); - lpszStrings[0] = pidbuf; - lpszStrings[1] = string; - - ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL); -} - -static void xcloselog(BIO *bp) -{ - if (bp->ptr) - DeregisterEventSource((HANDLE) (bp->ptr)); - bp->ptr = NULL; -} - -# elif defined(OPENSSL_SYS_VMS) - -static int VMS_OPC_target = LOG_DAEMON; - -static void xopenlog(BIO *bp, char *name, int level) -{ - VMS_OPC_target = level; -} - -static void xsyslog(BIO *bp, int priority, const char *string) -{ - struct dsc$descriptor_s opc_dsc; - -/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */ -# if __INITIAL_POINTER_SIZE == 64 -# pragma pointer_size save -# pragma pointer_size 32 -# define OPCDEF_TYPE __char_ptr32 -# define OPCDEF_MALLOC _malloc32 -# else /* __INITIAL_POINTER_SIZE == 64 */ -# define OPCDEF_TYPE char * -# define OPCDEF_MALLOC OPENSSL_malloc -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ - - struct opcdef *opcdef_p; - -# if __INITIAL_POINTER_SIZE == 64 -# pragma pointer_size restore -# endif /* __INITIAL_POINTER_SIZE == 64 */ - - char buf[10240]; - unsigned int len; - struct dsc$descriptor_s buf_dsc; - $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); - char *priority_tag; - - switch (priority) { - case LOG_EMERG: - priority_tag = "Emergency"; - break; - case LOG_ALERT: - priority_tag = "Alert"; - break; - case LOG_CRIT: - priority_tag = "Critical"; - break; - case LOG_ERR: - priority_tag = "Error"; - break; - case LOG_WARNING: - priority_tag = "Warning"; - break; - case LOG_NOTICE: - priority_tag = "Notice"; - break; - case LOG_INFO: - priority_tag = "Info"; - break; - case LOG_DEBUG: - priority_tag = "DEBUG"; - break; - } - - buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - buf_dsc.dsc$b_class = DSC$K_CLASS_S; - buf_dsc.dsc$a_pointer = buf; - buf_dsc.dsc$w_length = sizeof(buf) - 1; - - lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); - - /* We know there's an 8-byte header. That's documented. */ - opcdef_p = OPCDEF_MALLOC(8 + len); - opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; - memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); - opcdef_p->opc$l_ms_rqstid = 0; - memcpy(&opcdef_p->opc$l_ms_text, buf, len); - - opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - opc_dsc.dsc$b_class = DSC$K_CLASS_S; - opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p; - opc_dsc.dsc$w_length = len + 8; - - sys$sndopr(opc_dsc, 0); - - OPENSSL_free(opcdef_p); -} - -static void xcloselog(BIO *bp) -{ -} - -# else /* Unix/Watt32 */ - -static void xopenlog(BIO *bp, char *name, int level) -{ -# ifdef WATT32 /* djgpp/DOS */ - openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level); -# else - openlog(name, LOG_PID | LOG_CONS, level); -# endif -} - -static void xsyslog(BIO *bp, int priority, const char *string) -{ - syslog(priority, "%s", string); -} - -static void xcloselog(BIO *bp) -{ - closelog(); -} - -# endif /* Unix */ - -#endif /* NO_SYSLOG */ -/* crypto/bio/bss_mem.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "bio.h" - -static int mem_write(BIO *h, const char *buf, int num); -static int mem_read(BIO *h, char *buf, int size); -static int mem_puts(BIO *h, const char *str); -static int mem_gets(BIO *h, char *str, int size); -static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int mem_new(BIO *h); -static int mem_free(BIO *data); -static BIO_METHOD mem_method = { - BIO_TYPE_MEM, - "memory buffer", - mem_write, - mem_read, - mem_puts, - mem_gets, - mem_ctrl, - mem_new, - mem_free, - NULL, -}; - -/* - * bio->num is used to hold the value to return on 'empty', if it is 0, - * should_retry is not set - */ - -BIO_METHOD *BIO_s_mem(void) -{ - return (&mem_method); -} - - -BIO *BIO_new_mem_buf(const void *buf, int len) -{ - BIO *ret; - BUF_MEM *b; - size_t sz; - - if (!buf) { - BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER); - return NULL; - } - sz = (len < 0) ? strlen(buf) : (size_t)len; - if (!(ret = BIO_new(BIO_s_mem()))) - return NULL; - b = (BUF_MEM *)ret->ptr; - /* Cast away const and trust in the MEM_RDONLY flag. */ - b->data = (void *)buf; - b->length = sz; - b->max = sz; - ret->flags |= BIO_FLAGS_MEM_RDONLY; - /* Since this is static data retrying wont help */ - ret->num = 0; - return ret; -} - -static int mem_new(BIO *bi) -{ - BUF_MEM *b; - - if ((b = BUF_MEM_new()) == NULL) - return (0); - bi->shutdown = 1; - bi->init = 1; - bi->num = -1; - bi->ptr = (char *)b; - return (1); -} - -static int mem_free(BIO *a) -{ - if (a == NULL) - return (0); - if (a->shutdown) { - if ((a->init) && (a->ptr != NULL)) { - BUF_MEM *b; - b = (BUF_MEM *)a->ptr; - if (a->flags & BIO_FLAGS_MEM_RDONLY) - b->data = NULL; - BUF_MEM_free(b); - a->ptr = NULL; - } - } - return (1); -} - -static int mem_read(BIO *b, char *out, int outl) -{ - int ret = -1; - BUF_MEM *bm; - - bm = (BUF_MEM *)b->ptr; - BIO_clear_retry_flags(b); - ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl; - if ((out != NULL) && (ret > 0)) { - memcpy(out, bm->data, ret); - bm->length -= ret; - if (b->flags & BIO_FLAGS_MEM_RDONLY) - bm->data += ret; - else { - memmove(&(bm->data[0]), &(bm->data[ret]), bm->length); - } - } else if (bm->length == 0) { - ret = b->num; - if (ret != 0) - BIO_set_retry_read(b); - } - return (ret); -} - -static int mem_write(BIO *b, const char *in, int inl) -{ - int ret = -1; - int blen; - BUF_MEM *bm; - - bm = (BUF_MEM *)b->ptr; - if (in == NULL) { - BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER); - goto end; - } - - if (b->flags & BIO_FLAGS_MEM_RDONLY) { - BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO); - goto end; - } - - BIO_clear_retry_flags(b); - if (inl == 0) - return 0; - blen = bm->length; - if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl)) - goto end; - memcpy(&(bm->data[blen]), in, inl); - ret = inl; - end: - return (ret); -} - -static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret = 1; - char **pptr; - - BUF_MEM *bm = (BUF_MEM *)b->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - if (bm->data != NULL) { - /* For read only case reset to the start again */ - if (b->flags & BIO_FLAGS_MEM_RDONLY) { - bm->data -= bm->max - bm->length; - bm->length = bm->max; - } else { - memset(bm->data, 0, bm->max); - bm->length = 0; - } - } - break; - case BIO_CTRL_EOF: - ret = (long)(bm->length == 0); - break; - case BIO_C_SET_BUF_MEM_EOF_RETURN: - b->num = (int)num; - break; - case BIO_CTRL_INFO: - ret = (long)bm->length; - if (ptr != NULL) { - pptr = (char **)ptr; - *pptr = (char *)&(bm->data[0]); - } - break; - case BIO_C_SET_BUF_MEM: - mem_free(b); - b->shutdown = (int)num; - b->ptr = ptr; - break; - case BIO_C_GET_BUF_MEM_PTR: - if (ptr != NULL) { - pptr = (char **)ptr; - *pptr = (char *)bm; - } - break; - case BIO_CTRL_GET_CLOSE: - ret = (long)b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - - case BIO_CTRL_WPENDING: - ret = 0L; - break; - case BIO_CTRL_PENDING: - ret = (long)bm->length; - break; - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - case BIO_CTRL_PUSH: - case BIO_CTRL_POP: - default: - ret = 0; - break; - } - return (ret); -} - -static int mem_gets(BIO *bp, char *buf, int size) -{ - int i, j; - int ret = -1; - char *p; - BUF_MEM *bm = (BUF_MEM *)bp->ptr; - - BIO_clear_retry_flags(bp); - j = bm->length; - if ((size - 1) < j) - j = size - 1; - if (j <= 0) { - *buf = '\0'; - return 0; - } - p = bm->data; - for (i = 0; i < j; i++) { - if (p[i] == '\n') { - i++; - break; - } - } - - /* - * i is now the max num of bytes to copy, either j or up to - * and including the first newline - */ - - i = mem_read(bp, buf, i); - if (i > 0) - buf[i] = '\0'; - ret = i; - return (ret); -} - -static int mem_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = mem_write(bp, str, n); - /* memory semantics is that it will always work */ - return (ret); -} -/* crypto/bio/bss_null.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "bio.h" - -static int null_write(BIO *h, const char *buf, int num); -static int null_read(BIO *h, char *buf, int size); -static int null_puts(BIO *h, const char *str); -static int null_gets(BIO *h, char *str, int size); -static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int null_new(BIO *h); -static int null_free(BIO *data); -static BIO_METHOD null_method = { - BIO_TYPE_NULL, - "NULL", - null_write, - null_read, - null_puts, - null_gets, - null_ctrl, - null_new, - null_free, - NULL, -}; - -BIO_METHOD *BIO_s_null(void) -{ - return (&null_method); -} - -static int null_new(BIO *bi) -{ - bi->init = 1; - bi->num = 0; - bi->ptr = (NULL); - return (1); -} - -static int null_free(BIO *a) -{ - if (a == NULL) - return (0); - return (1); -} - -static int null_read(BIO *b, char *out, int outl) -{ - return (0); -} - -static int null_write(BIO *b, const char *in, int inl) -{ - return (inl); -} - -static long null_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret = 1; - - switch (cmd) { - case BIO_CTRL_RESET: - case BIO_CTRL_EOF: - case BIO_CTRL_SET: - case BIO_CTRL_SET_CLOSE: - case BIO_CTRL_FLUSH: - case BIO_CTRL_DUP: - ret = 1; - break; - case BIO_CTRL_GET_CLOSE: - case BIO_CTRL_INFO: - case BIO_CTRL_GET: - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - default: - ret = 0; - break; - } - return (ret); -} - -static int null_gets(BIO *bp, char *buf, int size) -{ - return (0); -} - -static int null_puts(BIO *bp, const char *str) -{ - if (str == NULL) - return (0); - return (strlen(str)); -} -/* crypto/bio/bss_sock.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#define USE_SOCKETS -// #include "cryptlib.h" - -#ifndef OPENSSL_NO_SOCK - -# include "bio.h" - -# ifdef WATT32 -# define sock_write SockWrite /* Watt-32 uses same names */ -# define sock_read SockRead -# define sock_puts SockPuts -# endif - -static int sock_write(BIO *h, const char *buf, int num); -static int sock_read(BIO *h, char *buf, int size); -static int sock_puts(BIO *h, const char *str); -static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2); -static int sock_new(BIO *h); -static int sock_free(BIO *data); -int BIO_sock_should_retry(int s); - -static BIO_METHOD methods_sockp = { - BIO_TYPE_SOCKET, - "socket", - sock_write, - sock_read, - sock_puts, - NULL, /* sock_gets, */ - sock_ctrl, - sock_new, - sock_free, - NULL, -}; - -BIO_METHOD *BIO_s_socket(void) -{ - return (&methods_sockp); -} - -BIO *BIO_new_socket(int fd, int close_flag) -{ - BIO *ret; - - ret = BIO_new(BIO_s_socket()); - if (ret == NULL) - return (NULL); - BIO_set_fd(ret, fd, close_flag); - return (ret); -} - -static int sock_new(BIO *bi) -{ - bi->init = 0; - bi->num = 0; - bi->ptr = NULL; - bi->flags = 0; - return (1); -} - -static int sock_free(BIO *a) -{ - if (a == NULL) - return (0); - if (a->shutdown) { - if (a->init) { - SHUTDOWN2(a->num); - } - a->init = 0; - a->flags = 0; - } - return (1); -} - -static int sock_read(BIO *b, char *out, int outl) -{ - int ret = 0; - - if (out != NULL) { - clear_socket_error(); - ret = readsocket(b->num, out, outl); - BIO_clear_retry_flags(b); - if (ret <= 0) { - if (BIO_sock_should_retry(ret)) - BIO_set_retry_read(b); - } - } - return (ret); -} - -static int sock_write(BIO *b, const char *in, int inl) -{ - int ret; - - clear_socket_error(); - ret = writesocket(b->num, in, inl); - BIO_clear_retry_flags(b); - if (ret <= 0) { - if (BIO_sock_should_retry(ret)) - BIO_set_retry_write(b); - } - return (ret); -} - -static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - long ret = 1; - int *ip; - - switch (cmd) { - case BIO_C_SET_FD: - sock_free(b); - b->num = *((int *)ptr); - b->shutdown = (int)num; - b->init = 1; - break; - case BIO_C_GET_FD: - if (b->init) { - ip = (int *)ptr; - if (ip != NULL) - *ip = b->num; - ret = b->num; - } else - ret = -1; - break; - case BIO_CTRL_GET_CLOSE: - ret = b->shutdown; - break; - case BIO_CTRL_SET_CLOSE: - b->shutdown = (int)num; - break; - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - default: - ret = 0; - break; - } - return (ret); -} - -static int sock_puts(BIO *bp, const char *str) -{ - int n, ret; - - n = strlen(str); - ret = sock_write(bp, str, n); - return (ret); -} - -int BIO_sock_should_retry(int i) -{ - int err; - - if ((i == 0) || (i == -1)) { - err = get_last_socket_error(); - -# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps - * not? Ben 4/1/99 */ - if ((i == -1) && (err == 0)) - return (1); -# endif - - return (BIO_sock_non_fatal_error(err)); - } - return (0); -} - -int BIO_sock_non_fatal_error(int err) -{ - switch (err) { -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) -# if defined(WSAEWOULDBLOCK) - case WSAEWOULDBLOCK: -# endif - -# if 0 /* This appears to always be an error */ -# if defined(WSAENOTCONN) - case WSAENOTCONN: -# endif -# endif -# endif - -# ifdef EWOULDBLOCK -# ifdef WSAEWOULDBLOCK -# if WSAEWOULDBLOCK != EWOULDBLOCK - case EWOULDBLOCK: -# endif -# else - case EWOULDBLOCK: -# endif -# endif - -# if defined(ENOTCONN) - case ENOTCONN: -# endif - -# ifdef EINTR - case EINTR: -# endif - -# ifdef EAGAIN -# if EWOULDBLOCK != EAGAIN - case EAGAIN: -# endif -# endif - -# ifdef EPROTO - case EPROTO: -# endif - -# ifdef EINPROGRESS - case EINPROGRESS: -# endif - -# ifdef EALREADY - case EALREADY: -# endif - return (1); - /* break; */ - default: - break; - } - return (0); -} - -#endif /* #ifndef OPENSSL_NO_SOCK */ diff --git a/Sources/COpenSSL/buf_.c b/Sources/COpenSSL/buf_.c deleted file mode 100644 index a2889b81..00000000 --- a/Sources/COpenSSL/buf_.c +++ /dev/null @@ -1,234 +0,0 @@ -/* crypto/buffer/buf_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "buffer.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason) - -static ERR_STRING_DATA BUF_str_functs[] = { - {ERR_FUNC(BUF_F_BUF_MEMDUP), "BUF_memdup"}, - {ERR_FUNC(BUF_F_BUF_MEM_GROW), "BUF_MEM_grow"}, - {ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN), "BUF_MEM_grow_clean"}, - {ERR_FUNC(BUF_F_BUF_MEM_NEW), "BUF_MEM_new"}, - {ERR_FUNC(BUF_F_BUF_STRDUP), "BUF_strdup"}, - {ERR_FUNC(BUF_F_BUF_STRNDUP), "BUF_strndup"}, - {0, NULL} -}; - -static ERR_STRING_DATA BUF_str_reasons[] = { - {0, NULL} -}; - -#endif - -void ERR_load_BUF_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) { - ERR_load_strings(0, BUF_str_functs); - ERR_load_strings(0, BUF_str_reasons); - } -#endif -} -/* crypto/buffer/buffer.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include -// #include "buffer.h" - -size_t BUF_strnlen(const char *str, size_t maxlen) -{ - const char *p; - - for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ; - - return p - str; -} - -char *BUF_strdup(const char *str) -{ - if (str == NULL) - return NULL; - return BUF_strndup(str, strlen(str)); -} - -char *BUF_strndup(const char *str, size_t siz) -{ - char *ret; - - if (str == NULL) - return NULL; - - siz = BUF_strnlen(str, siz); - - if (siz >= INT_MAX) - return NULL; - - ret = OPENSSL_malloc(siz + 1); - if (ret == NULL) { - BUFerr(BUF_F_BUF_STRNDUP, ERR_R_MALLOC_FAILURE); - return NULL; - } - - memcpy(ret, str, siz); - ret[siz] = '\0'; - - return (ret); -} - -void *BUF_memdup(const void *data, size_t siz) -{ - void *ret; - - if (data == NULL || siz >= INT_MAX) - return NULL; - - ret = OPENSSL_malloc(siz); - if (ret == NULL) { - BUFerr(BUF_F_BUF_MEMDUP, ERR_R_MALLOC_FAILURE); - return NULL; - } - return memcpy(ret, data, siz); -} - -size_t BUF_strlcpy(char *dst, const char *src, size_t size) -{ - size_t l = 0; - for (; size > 1 && *src; size--) { - *dst++ = *src++; - l++; - } - if (size) - *dst = '\0'; - return l + strlen(src); -} - -size_t BUF_strlcat(char *dst, const char *src, size_t size) -{ - size_t l = 0; - for (; size > 0 && *dst; size--, dst++) - l++; - return l + BUF_strlcpy(dst, src, size); -} diff --git a/Sources/COpenSSL/buffer.c b/Sources/COpenSSL/buffer.c deleted file mode 100644 index 2a0e7d1a..00000000 --- a/Sources/COpenSSL/buffer.c +++ /dev/null @@ -1,188 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/buffer/buffer.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "buffer.h" - -/* - * LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That - * function is applied in several functions in this file and this limit - * ensures that the result fits in an int. - */ -#define LIMIT_BEFORE_EXPANSION 0x5ffffffc - -BUF_MEM *BUF_MEM_new(void) -{ - BUF_MEM *ret; - - ret = OPENSSL_malloc(sizeof(BUF_MEM)); - if (ret == NULL) { - BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - ret->length = 0; - ret->max = 0; - ret->data = NULL; - return (ret); -} - -void BUF_MEM_free(BUF_MEM *a) -{ - if (a == NULL) - return; - - if (a->data != NULL) { - OPENSSL_cleanse(a->data, a->max); - OPENSSL_free(a->data); - } - OPENSSL_free(a); -} - -int BUF_MEM_grow(BUF_MEM *str, size_t len) -{ - char *ret; - size_t n; - - if (str->length >= len) { - str->length = len; - return (len); - } - if (str->max >= len) { - memset(&str->data[str->length], 0, len - str->length); - str->length = len; - return (len); - } - /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ - if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE); - return 0; - } - n = (len + 3) / 3 * 4; - if (str->data == NULL) - ret = OPENSSL_malloc(n); - else - ret = OPENSSL_realloc(str->data, n); - if (ret == NULL) { - BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE); - len = 0; - } else { - str->data = ret; - str->max = n; - memset(&str->data[str->length], 0, len - str->length); - str->length = len; - } - return (len); -} - -int BUF_MEM_grow_clean(BUF_MEM *str, size_t len) -{ - char *ret; - size_t n; - - if (str->length >= len) { - memset(&str->data[len], 0, str->length - len); - str->length = len; - return (len); - } - if (str->max >= len) { - memset(&str->data[str->length], 0, len - str->length); - str->length = len; - return (len); - } - /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ - if (len > LIMIT_BEFORE_EXPANSION) { - BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); - return 0; - } - n = (len + 3) / 3 * 4; - if (str->data == NULL) - ret = OPENSSL_malloc(n); - else - ret = OPENSSL_realloc_clean(str->data, str->max, n); - if (ret == NULL) { - BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); - len = 0; - } else { - str->data = ret; - str->max = n; - memset(&str->data[str->length], 0, len - str->length); - str->length = len; - } - return (len); -} - -void BUF_reverse(unsigned char *out, const unsigned char *in, size_t size) -{ - size_t i; - if (in) { - out += size - 1; - for (i = 0; i < size; i++) - *out-- = *in++; - } else { - unsigned char *q; - char c; - q = out + size - 1; - for (i = 0; i < size / 2; i++) { - c = *q; - *q-- = *out; - *out++ = c; - } - } -} diff --git a/Sources/COpenSSL/buffer.h b/Sources/COpenSSL/buffer.h deleted file mode 100644 index 546c9ec8..00000000 --- a/Sources/COpenSSL/buffer.h +++ /dev/null @@ -1,125 +0,0 @@ -/* crypto/buffer/buffer.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_BUFFER_H -# define HEADER_BUFFER_H - -# include "ossl_typ.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# include - -# if !defined(NO_SYS_TYPES_H) -# include -# endif - -/* Already declared in ossl_typ.h */ -/* typedef struct buf_mem_st BUF_MEM; */ - -struct buf_mem_st { - size_t length; /* current number of bytes */ - char *data; - size_t max; /* size of buffer */ -}; - -BUF_MEM *BUF_MEM_new(void); -void BUF_MEM_free(BUF_MEM *a); -int BUF_MEM_grow(BUF_MEM *str, size_t len); -int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); -size_t BUF_strnlen(const char *str, size_t maxlen); -char *BUF_strdup(const char *str); - -/* - * Like strndup, but in addition, explicitly guarantees to never read past the - * first |siz| bytes of |str|. - */ -char *BUF_strndup(const char *str, size_t siz); - -void *BUF_memdup(const void *data, size_t siz); -void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); - -/* safe string functions */ -size_t BUF_strlcpy(char *dst, const char *src, size_t siz); -size_t BUF_strlcat(char *dst, const char *src, size_t siz); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_BUF_strings(void); - -/* Error codes for the BUF functions. */ - -/* Function codes. */ -# define BUF_F_BUF_MEMDUP 103 -# define BUF_F_BUF_MEM_GROW 100 -# define BUF_F_BUF_MEM_GROW_CLEAN 105 -# define BUF_F_BUF_MEM_NEW 101 -# define BUF_F_BUF_STRDUP 102 -# define BUF_F_BUF_STRNDUP 104 - -/* Reason codes. */ - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/buildinf.h b/Sources/COpenSSL/buildinf.h deleted file mode 100644 index 2e287c42..00000000 --- a/Sources/COpenSSL/buildinf.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef MK1MF_BUILD -# define CFLAGS "-DB_ENDIAN" -# define PLATFORM "macos" -# define DATE "Sun Feb 27 19:44:16 MET 2000" -#endif diff --git a/Sources/COpenSSL/by_.c b/Sources/COpenSSL/by_.c deleted file mode 100644 index eebf6149..00000000 --- a/Sources/COpenSSL/by_.c +++ /dev/null @@ -1,720 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/x509/by_dir.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include - -#include "cryptlib.h" - -#ifndef NO_SYS_TYPES_H -# include -#endif -#ifndef OPENSSL_NO_POSIX_IO -# include -#endif - -#include "lhash.h" -#include "x509.h" - -typedef struct lookup_dir_hashes_st { - unsigned long hash; - int suffix; -} BY_DIR_HASH; - -typedef struct lookup_dir_entry_st { - char *dir; - int dir_type; - STACK_OF(BY_DIR_HASH) *hashes; -} BY_DIR_ENTRY; - -typedef struct lookup_dir_st { - BUF_MEM *buffer; - STACK_OF(BY_DIR_ENTRY) *dirs; -} BY_DIR; - -DECLARE_STACK_OF(BY_DIR_HASH) -DECLARE_STACK_OF(BY_DIR_ENTRY) - -static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, - char **ret); -static int new_dir(X509_LOOKUP *lu); -static void free_dir(X509_LOOKUP *lu); -static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); -static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, - X509_OBJECT *ret); -X509_LOOKUP_METHOD x509_dir_lookup = { - "Load certs from files in a directory", - new_dir, /* new */ - free_dir, /* free */ - NULL, /* init */ - NULL, /* shutdown */ - dir_ctrl, /* ctrl */ - get_cert_by_subject, /* get_by_subject */ - NULL, /* get_by_issuer_serial */ - NULL, /* get_by_fingerprint */ - NULL, /* get_by_alias */ -}; - -X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) -{ - return (&x509_dir_lookup); -} - -static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, - char **retp) -{ - int ret = 0; - BY_DIR *ld; - char *dir = NULL; - - ld = (BY_DIR *)ctx->method_data; - - switch (cmd) { - case X509_L_ADD_DIR: - if (argl == X509_FILETYPE_DEFAULT) { - dir = (char *)ossl_safe_getenv(X509_get_default_cert_dir_env()); - if (dir) - ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); - else - ret = add_cert_dir(ld, X509_get_default_cert_dir(), - X509_FILETYPE_PEM); - if (!ret) { - X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR); - } - } else - ret = add_cert_dir(ld, argp, (int)argl); - break; - } - return (ret); -} - -static int new_dir(X509_LOOKUP *lu) -{ - BY_DIR *a; - - if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) - return (0); - if ((a->buffer = BUF_MEM_new()) == NULL) { - OPENSSL_free(a); - return (0); - } - a->dirs = NULL; - lu->method_data = (char *)a; - return (1); -} - -static void by_dir_hash_free(BY_DIR_HASH *hash) -{ - OPENSSL_free(hash); -} - -static int by_dir_hash_cmp(const BY_DIR_HASH *const *a, - const BY_DIR_HASH *const *b) -{ - if ((*a)->hash > (*b)->hash) - return 1; - if ((*a)->hash < (*b)->hash) - return -1; - return 0; -} - -static void by_dir_entry_free(BY_DIR_ENTRY *ent) -{ - if (ent->dir) - OPENSSL_free(ent->dir); - if (ent->hashes) - sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); - OPENSSL_free(ent); -} - -static void free_dir(X509_LOOKUP *lu) -{ - BY_DIR *a; - - a = (BY_DIR *)lu->method_data; - if (a->dirs != NULL) - sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); - if (a->buffer != NULL) - BUF_MEM_free(a->buffer); - OPENSSL_free(a); -} - -static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) -{ - int j, len; - const char *s, *ss, *p; - - if (dir == NULL || !*dir) { - X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY); - return 0; - } - - s = dir; - p = s; - do { - if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) { - BY_DIR_ENTRY *ent; - ss = s; - s = p + 1; - len = (int)(p - ss); - if (len == 0) - continue; - for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { - ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); - if (strlen(ent->dir) == (size_t)len && - strncmp(ent->dir, ss, (unsigned int)len) == 0) - break; - } - if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) - continue; - if (ctx->dirs == NULL) { - ctx->dirs = sk_BY_DIR_ENTRY_new_null(); - if (!ctx->dirs) { - X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); - return 0; - } - } - ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY)); - if (!ent) - return 0; - ent->dir_type = type; - ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); - ent->dir = OPENSSL_malloc((unsigned int)len + 1); - if (!ent->dir || !ent->hashes) { - by_dir_entry_free(ent); - return 0; - } - strncpy(ent->dir, ss, (unsigned int)len); - ent->dir[len] = '\0'; - if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { - by_dir_entry_free(ent); - return 0; - } - } - } while (*p++ != '\0'); - return 1; -} - -static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, - X509_OBJECT *ret) -{ - BY_DIR *ctx; - union { - struct { - X509 st_x509; - X509_CINF st_x509_cinf; - } x509; - struct { - X509_CRL st_crl; - X509_CRL_INFO st_crl_info; - } crl; - } data; - int ok = 0; - int i, j, k; - unsigned long h; - BUF_MEM *b = NULL; - X509_OBJECT stmp, *tmp; - const char *postfix = ""; - - if (name == NULL) - return (0); - - stmp.type = type; - if (type == X509_LU_X509) { - data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; - data.x509.st_x509_cinf.subject = name; - stmp.data.x509 = &data.x509.st_x509; - postfix = ""; - } else if (type == X509_LU_CRL) { - data.crl.st_crl.crl = &data.crl.st_crl_info; - data.crl.st_crl_info.issuer = name; - stmp.data.crl = &data.crl.st_crl; - postfix = "r"; - } else { - X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE); - goto finish; - } - - if ((b = BUF_MEM_new()) == NULL) { - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB); - goto finish; - } - - ctx = (BY_DIR *)xl->method_data; - - h = X509_NAME_hash(name); - for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { - BY_DIR_ENTRY *ent; - int idx; - BY_DIR_HASH htmp, *hent; - ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); - j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; - if (!BUF_MEM_grow(b, j)) { - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); - goto finish; - } - if (type == X509_LU_CRL && ent->hashes) { - htmp.hash = h; - CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); - idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); - if (idx >= 0) { - hent = sk_BY_DIR_HASH_value(ent->hashes, idx); - k = hent->suffix; - } else { - hent = NULL; - k = 0; - } - CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); - } else { - k = 0; - hent = NULL; - } - for (;;) { - char c = '/'; -#ifdef OPENSSL_SYS_VMS - c = ent->dir[strlen(ent->dir) - 1]; - if (c != ':' && c != '>' && c != ']') { - /* - * If no separator is present, we assume the directory - * specifier is a logical name, and add a colon. We really - * should use better VMS routines for merging things like - * this, but this will do for now... -- Richard Levitte - */ - c = ':'; - } else { - c = '\0'; - } -#endif - if (c == '\0') { - /* - * This is special. When c == '\0', no directory separator - * should be added. - */ - BIO_snprintf(b->data, b->max, - "%s%08lx.%s%d", ent->dir, h, postfix, k); - } else { - BIO_snprintf(b->data, b->max, - "%s%c%08lx.%s%d", ent->dir, c, h, postfix, k); - } -#ifndef OPENSSL_NO_POSIX_IO -# ifdef _WIN32 -# define stat _stat -# endif - { - struct stat st; - if (stat(b->data, &st) < 0) - break; - } -#endif - /* found one. */ - if (type == X509_LU_X509) { - if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0) - break; - } else if (type == X509_LU_CRL) { - if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) - break; - } - /* else case will caught higher up */ - k++; - } - - /* - * we have added it to the cache so now pull it out again - */ - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp); - if (j != -1) - tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); - else - tmp = NULL; - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - - /* If a CRL, update the last file suffix added for this */ - - if (type == X509_LU_CRL) { - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - /* - * Look for entry again in case another thread added an entry - * first. - */ - if (!hent) { - htmp.hash = h; - idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); - if (idx >= 0) - hent = sk_BY_DIR_HASH_value(ent->hashes, idx); - } - if (!hent) { - hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); - if (hent == NULL) { - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); - goto finish; - } - hent->hash = h; - hent->suffix = k; - if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - OPENSSL_free(hent); - ok = 0; - goto finish; - } - } else if (hent->suffix < k) - hent->suffix = k; - - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - - } - - if (tmp != NULL) { - ok = 1; - ret->type = tmp->type; - memcpy(&ret->data, &tmp->data, sizeof(ret->data)); - /* - * If we were going to up the reference count, we would need to - * do it on a perl 'type' basis - */ - /*- CRYPTO_add(&tmp->data.x509->references,1, - CRYPTO_LOCK_X509);*/ - goto finish; - } - } - finish: - if (b != NULL) - BUF_MEM_free(b); - return (ok); -} -/* crypto/x509/by_file.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include - -// #include "cryptlib.h" -// #include "lhash.h" -#include "buffer.h" -// #include "x509.h" -#include "pem.h" - -#ifndef OPENSSL_NO_STDIO - -static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, - long argl, char **ret); -X509_LOOKUP_METHOD x509_file_lookup = { - "Load file into cache", - NULL, /* new */ - NULL, /* free */ - NULL, /* init */ - NULL, /* shutdown */ - by_file_ctrl, /* ctrl */ - NULL, /* get_by_subject */ - NULL, /* get_by_issuer_serial */ - NULL, /* get_by_fingerprint */ - NULL, /* get_by_alias */ -}; - -X509_LOOKUP_METHOD *X509_LOOKUP_file(void) -{ - return (&x509_file_lookup); -} - -static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, - long argl, char **ret) -{ - int ok = 0; - const char *file; - - switch (cmd) { - case X509_L_FILE_LOAD: - if (argl == X509_FILETYPE_DEFAULT) { - file = ossl_safe_getenv(X509_get_default_cert_file_env()); - - if (file) - ok = (X509_load_cert_crl_file(ctx, file, - X509_FILETYPE_PEM) != 0); - - else - ok = (X509_load_cert_crl_file - (ctx, X509_get_default_cert_file(), - X509_FILETYPE_PEM) != 0); - - if (!ok) { - X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); - } - } else { - if (argl == X509_FILETYPE_PEM) - ok = (X509_load_cert_crl_file(ctx, argp, - X509_FILETYPE_PEM) != 0); - else - ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); - } - break; - } - return (ok); -} - -int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) -{ - int ret = 0; - BIO *in = NULL; - int i, count = 0; - X509 *x = NULL; - - if (file == NULL) - return (1); - in = BIO_new(BIO_s_file_internal()); - - if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); - goto err; - } - - if (type == X509_FILETYPE_PEM) { - for (;;) { - x = PEM_read_bio_X509_AUX(in, NULL, NULL, ""); - if (x == NULL) { - if ((ERR_GET_REASON(ERR_peek_last_error()) == - PEM_R_NO_START_LINE) && (count > 0)) { - ERR_clear_error(); - break; - } else { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); - goto err; - } - } - i = X509_STORE_add_cert(ctx->store_ctx, x); - if (!i) - goto err; - count++; - X509_free(x); - x = NULL; - } - ret = count; - } else if (type == X509_FILETYPE_ASN1) { - x = d2i_X509_bio(in, NULL); - if (x == NULL) { - X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); - goto err; - } - i = X509_STORE_add_cert(ctx->store_ctx, x); - if (!i) - goto err; - ret = i; - } else { - X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); - goto err; - } - err: - if (x != NULL) - X509_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} - -int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) -{ - int ret = 0; - BIO *in = NULL; - int i, count = 0; - X509_CRL *x = NULL; - - if (file == NULL) - return (1); - in = BIO_new(BIO_s_file_internal()); - - if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { - X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); - goto err; - } - - if (type == X509_FILETYPE_PEM) { - for (;;) { - x = PEM_read_bio_X509_CRL(in, NULL, NULL, ""); - if (x == NULL) { - if ((ERR_GET_REASON(ERR_peek_last_error()) == - PEM_R_NO_START_LINE) && (count > 0)) { - ERR_clear_error(); - break; - } else { - X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB); - goto err; - } - } - i = X509_STORE_add_crl(ctx->store_ctx, x); - if (!i) - goto err; - count++; - X509_CRL_free(x); - x = NULL; - } - ret = count; - } else if (type == X509_FILETYPE_ASN1) { - x = d2i_X509_CRL_bio(in, NULL); - if (x == NULL) { - X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); - goto err; - } - i = X509_STORE_add_crl(ctx->store_ctx, x); - if (!i) - goto err; - ret = i; - } else { - X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); - goto err; - } - err: - if (x != NULL) - X509_CRL_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} - -int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) -{ - STACK_OF(X509_INFO) *inf; - X509_INFO *itmp; - BIO *in; - int i, count = 0; - if (type != X509_FILETYPE_PEM) - return X509_load_cert_file(ctx, file, type); - in = BIO_new_file(file, "r"); - if (!in) { - X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); - return 0; - } - inf = PEM_X509_INFO_read_bio(in, NULL, NULL, ""); - BIO_free(in); - if (!inf) { - X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); - return 0; - } - for (i = 0; i < sk_X509_INFO_num(inf); i++) { - itmp = sk_X509_INFO_value(inf, i); - if (itmp->x509) { - X509_STORE_add_cert(ctx->store_ctx, itmp->x509); - count++; - } - if (itmp->crl) { - X509_STORE_add_crl(ctx->store_ctx, itmp->crl); - count++; - } - } - sk_X509_INFO_pop_free(inf, X509_INFO_free); - return count; -} - -#endif /* OPENSSL_NO_STDIO */ diff --git a/Sources/COpenSSL/c_.c b/Sources/COpenSSL/c_.c deleted file mode 100644 index 0e37a8c0..00000000 --- a/Sources/COpenSSL/c_.c +++ /dev/null @@ -1,1958 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/evp/c_all.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -#if 0 -# undef OpenSSL_add_all_algorithms - -void OpenSSL_add_all_algorithms(void) -{ - OPENSSL_add_all_algorithms_noconf(); -} -#endif - -void OPENSSL_add_all_algorithms_noconf(void) -{ - /* - * For the moment OPENSSL_cpuid_setup does something - * only on IA-32, but we reserve the option for all - * platforms... - */ - OPENSSL_cpuid_setup(); - OpenSSL_add_all_ciphers(); - OpenSSL_add_all_digests(); -} -/* crypto/evp/c_allc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -#include "pkcs12.h" -#include "objects.h" - -void OpenSSL_add_all_ciphers(void) -{ - -#ifndef OPENSSL_NO_DES - EVP_add_cipher(EVP_des_cfb()); - EVP_add_cipher(EVP_des_cfb1()); - EVP_add_cipher(EVP_des_cfb8()); - EVP_add_cipher(EVP_des_ede_cfb()); - EVP_add_cipher(EVP_des_ede3_cfb()); - EVP_add_cipher(EVP_des_ede3_cfb1()); - EVP_add_cipher(EVP_des_ede3_cfb8()); - - EVP_add_cipher(EVP_des_ofb()); - EVP_add_cipher(EVP_des_ede_ofb()); - EVP_add_cipher(EVP_des_ede3_ofb()); - - EVP_add_cipher(EVP_desx_cbc()); - EVP_add_cipher_alias(SN_desx_cbc, "DESX"); - EVP_add_cipher_alias(SN_desx_cbc, "desx"); - - EVP_add_cipher(EVP_des_cbc()); - EVP_add_cipher_alias(SN_des_cbc, "DES"); - EVP_add_cipher_alias(SN_des_cbc, "des"); - EVP_add_cipher(EVP_des_ede_cbc()); - EVP_add_cipher(EVP_des_ede3_cbc()); - EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3"); - EVP_add_cipher_alias(SN_des_ede3_cbc, "des3"); - - EVP_add_cipher(EVP_des_ecb()); - EVP_add_cipher(EVP_des_ede()); - EVP_add_cipher(EVP_des_ede3()); - EVP_add_cipher(EVP_des_ede3_wrap()); -#endif - -#ifndef OPENSSL_NO_RC4 - EVP_add_cipher(EVP_rc4()); - EVP_add_cipher(EVP_rc4_40()); -# ifndef OPENSSL_NO_MD5 - EVP_add_cipher(EVP_rc4_hmac_md5()); -# endif -#endif - -#ifndef OPENSSL_NO_IDEA - EVP_add_cipher(EVP_idea_ecb()); - EVP_add_cipher(EVP_idea_cfb()); - EVP_add_cipher(EVP_idea_ofb()); - EVP_add_cipher(EVP_idea_cbc()); - EVP_add_cipher_alias(SN_idea_cbc, "IDEA"); - EVP_add_cipher_alias(SN_idea_cbc, "idea"); -#endif - -#ifndef OPENSSL_NO_SEED - EVP_add_cipher(EVP_seed_ecb()); - EVP_add_cipher(EVP_seed_cfb()); - EVP_add_cipher(EVP_seed_ofb()); - EVP_add_cipher(EVP_seed_cbc()); - EVP_add_cipher_alias(SN_seed_cbc, "SEED"); - EVP_add_cipher_alias(SN_seed_cbc, "seed"); -#endif - -#ifndef OPENSSL_NO_RC2 - EVP_add_cipher(EVP_rc2_ecb()); - EVP_add_cipher(EVP_rc2_cfb()); - EVP_add_cipher(EVP_rc2_ofb()); - EVP_add_cipher(EVP_rc2_cbc()); - EVP_add_cipher(EVP_rc2_40_cbc()); - EVP_add_cipher(EVP_rc2_64_cbc()); - EVP_add_cipher_alias(SN_rc2_cbc, "RC2"); - EVP_add_cipher_alias(SN_rc2_cbc, "rc2"); -#endif - -#ifndef OPENSSL_NO_BF - EVP_add_cipher(EVP_bf_ecb()); - EVP_add_cipher(EVP_bf_cfb()); - EVP_add_cipher(EVP_bf_ofb()); - EVP_add_cipher(EVP_bf_cbc()); - EVP_add_cipher_alias(SN_bf_cbc, "BF"); - EVP_add_cipher_alias(SN_bf_cbc, "bf"); - EVP_add_cipher_alias(SN_bf_cbc, "blowfish"); -#endif - -#ifndef OPENSSL_NO_CAST - EVP_add_cipher(EVP_cast5_ecb()); - EVP_add_cipher(EVP_cast5_cfb()); - EVP_add_cipher(EVP_cast5_ofb()); - EVP_add_cipher(EVP_cast5_cbc()); - EVP_add_cipher_alias(SN_cast5_cbc, "CAST"); - EVP_add_cipher_alias(SN_cast5_cbc, "cast"); - EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc"); - EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc"); -#endif - -#ifndef OPENSSL_NO_RC5 - EVP_add_cipher(EVP_rc5_32_12_16_ecb()); - EVP_add_cipher(EVP_rc5_32_12_16_cfb()); - EVP_add_cipher(EVP_rc5_32_12_16_ofb()); - EVP_add_cipher(EVP_rc5_32_12_16_cbc()); - EVP_add_cipher_alias(SN_rc5_cbc, "rc5"); - EVP_add_cipher_alias(SN_rc5_cbc, "RC5"); -#endif - -#ifndef OPENSSL_NO_AES - EVP_add_cipher(EVP_aes_128_ecb()); - EVP_add_cipher(EVP_aes_128_cbc()); - EVP_add_cipher(EVP_aes_128_cfb()); - EVP_add_cipher(EVP_aes_128_cfb1()); - EVP_add_cipher(EVP_aes_128_cfb8()); - EVP_add_cipher(EVP_aes_128_ofb()); - EVP_add_cipher(EVP_aes_128_ctr()); - EVP_add_cipher(EVP_aes_128_gcm()); - EVP_add_cipher(EVP_aes_128_xts()); - EVP_add_cipher(EVP_aes_128_ccm()); - EVP_add_cipher(EVP_aes_128_wrap()); - EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); - EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); - EVP_add_cipher(EVP_aes_192_ecb()); - EVP_add_cipher(EVP_aes_192_cbc()); - EVP_add_cipher(EVP_aes_192_cfb()); - EVP_add_cipher(EVP_aes_192_cfb1()); - EVP_add_cipher(EVP_aes_192_cfb8()); - EVP_add_cipher(EVP_aes_192_ofb()); - EVP_add_cipher(EVP_aes_192_ctr()); - EVP_add_cipher(EVP_aes_192_gcm()); - EVP_add_cipher(EVP_aes_192_ccm()); - EVP_add_cipher(EVP_aes_192_wrap()); - EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); - EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); - EVP_add_cipher(EVP_aes_256_ecb()); - EVP_add_cipher(EVP_aes_256_cbc()); - EVP_add_cipher(EVP_aes_256_cfb()); - EVP_add_cipher(EVP_aes_256_cfb1()); - EVP_add_cipher(EVP_aes_256_cfb8()); - EVP_add_cipher(EVP_aes_256_ofb()); - EVP_add_cipher(EVP_aes_256_ctr()); - EVP_add_cipher(EVP_aes_256_gcm()); - EVP_add_cipher(EVP_aes_256_xts()); - EVP_add_cipher(EVP_aes_256_ccm()); - EVP_add_cipher(EVP_aes_256_wrap()); - EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); - EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); -# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) - EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); - EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); -# endif -# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) - EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); - EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); -# endif -#endif - -#ifndef OPENSSL_NO_CAMELLIA - EVP_add_cipher(EVP_camellia_128_ecb()); - EVP_add_cipher(EVP_camellia_128_cbc()); - EVP_add_cipher(EVP_camellia_128_cfb()); - EVP_add_cipher(EVP_camellia_128_cfb1()); - EVP_add_cipher(EVP_camellia_128_cfb8()); - EVP_add_cipher(EVP_camellia_128_ofb()); - EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128"); - EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128"); - EVP_add_cipher(EVP_camellia_192_ecb()); - EVP_add_cipher(EVP_camellia_192_cbc()); - EVP_add_cipher(EVP_camellia_192_cfb()); - EVP_add_cipher(EVP_camellia_192_cfb1()); - EVP_add_cipher(EVP_camellia_192_cfb8()); - EVP_add_cipher(EVP_camellia_192_ofb()); - EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192"); - EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192"); - EVP_add_cipher(EVP_camellia_256_ecb()); - EVP_add_cipher(EVP_camellia_256_cbc()); - EVP_add_cipher(EVP_camellia_256_cfb()); - EVP_add_cipher(EVP_camellia_256_cfb1()); - EVP_add_cipher(EVP_camellia_256_cfb8()); - EVP_add_cipher(EVP_camellia_256_ofb()); - EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256"); - EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256"); -#endif -} -/* crypto/evp/c_alld.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "pkcs12.h" -// #include "objects.h" - -void OpenSSL_add_all_digests(void) -{ -#ifndef OPENSSL_NO_MD4 - EVP_add_digest(EVP_md4()); -#endif -#ifndef OPENSSL_NO_MD5 - EVP_add_digest(EVP_md5()); - EVP_add_digest_alias(SN_md5, "ssl2-md5"); - EVP_add_digest_alias(SN_md5, "ssl3-md5"); -#endif -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0) - EVP_add_digest(EVP_sha()); -# ifndef OPENSSL_NO_DSA - EVP_add_digest(EVP_dss()); -# endif -#endif -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) - EVP_add_digest(EVP_sha1()); - EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); - EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); -# ifndef OPENSSL_NO_DSA - EVP_add_digest(EVP_dss1()); - EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); - EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); - EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); -# endif -# ifndef OPENSSL_NO_ECDSA - EVP_add_digest(EVP_ecdsa()); -# endif -#endif -#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES) - EVP_add_digest(EVP_mdc2()); -#endif -#ifndef OPENSSL_NO_RIPEMD - EVP_add_digest(EVP_ripemd160()); - EVP_add_digest_alias(SN_ripemd160, "ripemd"); - EVP_add_digest_alias(SN_ripemd160, "rmd160"); -#endif -#ifndef OPENSSL_NO_SHA256 - EVP_add_digest(EVP_sha224()); - EVP_add_digest(EVP_sha256()); -#endif -#ifndef OPENSSL_NO_SHA512 - EVP_add_digest(EVP_sha384()); - EVP_add_digest(EVP_sha512()); -#endif -#ifndef OPENSSL_NO_WHIRLPOOL - EVP_add_digest(EVP_whirlpool()); -#endif -} -/* crypto/cast/c_cfb64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "cast.h" -#include "cast_lcl.h" - -/* - * The input and output encrypted as though 64bit cfb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ - -void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, const CAST_KEY *schedule, - unsigned char *ivec, int *num, int enc) -{ - register CAST_LONG v0, v1, t; - register int n = *num; - register long l = length; - CAST_LONG ti[2]; - unsigned char *iv, c, cc; - - iv = ivec; - if (enc) { - while (l--) { - if (n == 0) { - n2l(iv, v0); - ti[0] = v0; - n2l(iv, v1); - ti[1] = v1; - CAST_encrypt((CAST_LONG *)ti, schedule); - iv = ivec; - t = ti[0]; - l2n(t, iv); - t = ti[1]; - l2n(t, iv); - iv = ivec; - } - c = *(in++) ^ iv[n]; - *(out++) = c; - iv[n] = c; - n = (n + 1) & 0x07; - } - } else { - while (l--) { - if (n == 0) { - n2l(iv, v0); - ti[0] = v0; - n2l(iv, v1); - ti[1] = v1; - CAST_encrypt((CAST_LONG *)ti, schedule); - iv = ivec; - t = ti[0]; - l2n(t, iv); - t = ti[1]; - l2n(t, iv); - iv = ivec; - } - cc = *(in++); - c = iv[n]; - iv[n] = cc; - *(out++) = c ^ cc; - n = (n + 1) & 0x07; - } - } - v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; - *num = n; -} -/* crypto/cast/c_ecb.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "cast.h" -// #include "cast_lcl.h" -#include "opensslv.h" - -const char CAST_version[] = "CAST" OPENSSL_VERSION_PTEXT; - -void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, - const CAST_KEY *ks, int enc) -{ - CAST_LONG l, d[2]; - - n2l(in, l); - d[0] = l; - n2l(in, l); - d[1] = l; - if (enc) - CAST_encrypt(d, ks); - else - CAST_decrypt(d, ks); - l = d[0]; - l2n(l, out); - l = d[1]; - l2n(l, out); - l = d[0] = d[1] = 0; -} -/* crypto/cast/c_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "cast.h" -// #include "cast_lcl.h" - -void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key) -{ - register CAST_LONG l, r, t; - const register CAST_LONG *k; - - k = &(key->data[0]); - l = data[0]; - r = data[1]; - - E_CAST(0, k, l, r, +, ^, -); - E_CAST(1, k, r, l, ^, -, +); - E_CAST(2, k, l, r, -, +, ^); - E_CAST(3, k, r, l, +, ^, -); - E_CAST(4, k, l, r, ^, -, +); - E_CAST(5, k, r, l, -, +, ^); - E_CAST(6, k, l, r, +, ^, -); - E_CAST(7, k, r, l, ^, -, +); - E_CAST(8, k, l, r, -, +, ^); - E_CAST(9, k, r, l, +, ^, -); - E_CAST(10, k, l, r, ^, -, +); - E_CAST(11, k, r, l, -, +, ^); - if (!key->short_key) { - E_CAST(12, k, l, r, +, ^, -); - E_CAST(13, k, r, l, ^, -, +); - E_CAST(14, k, l, r, -, +, ^); - E_CAST(15, k, r, l, +, ^, -); - } - - data[1] = l & 0xffffffffL; - data[0] = r & 0xffffffffL; -} - -void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key) -{ - register CAST_LONG l, r, t; - const register CAST_LONG *k; - - k = &(key->data[0]); - l = data[0]; - r = data[1]; - - if (!key->short_key) { - E_CAST(15, k, l, r, +, ^, -); - E_CAST(14, k, r, l, -, +, ^); - E_CAST(13, k, l, r, ^, -, +); - E_CAST(12, k, r, l, +, ^, -); - } - E_CAST(11, k, l, r, -, +, ^); - E_CAST(10, k, r, l, ^, -, +); - E_CAST(9, k, l, r, +, ^, -); - E_CAST(8, k, r, l, -, +, ^); - E_CAST(7, k, l, r, ^, -, +); - E_CAST(6, k, r, l, +, ^, -); - E_CAST(5, k, l, r, -, +, ^); - E_CAST(4, k, r, l, ^, -, +); - E_CAST(3, k, l, r, +, ^, -); - E_CAST(2, k, r, l, -, +, ^); - E_CAST(1, k, l, r, ^, -, +); - E_CAST(0, k, r, l, +, ^, -); - - data[1] = l & 0xffffffffL; - data[0] = r & 0xffffffffL; -} - -void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, - long length, const CAST_KEY *ks, unsigned char *iv, - int enc) -{ - register CAST_LONG tin0, tin1; - register CAST_LONG tout0, tout1, xor0, xor1; - register long l = length; - CAST_LONG tin[2]; - - if (enc) { - n2l(iv, tout0); - n2l(iv, tout1); - iv -= 8; - for (l -= 8; l >= 0; l -= 8) { - n2l(in, tin0); - n2l(in, tin1); - tin0 ^= tout0; - tin1 ^= tout1; - tin[0] = tin0; - tin[1] = tin1; - CAST_encrypt(tin, ks); - tout0 = tin[0]; - tout1 = tin[1]; - l2n(tout0, out); - l2n(tout1, out); - } - if (l != -8) { - n2ln(in, tin0, tin1, l + 8); - tin0 ^= tout0; - tin1 ^= tout1; - tin[0] = tin0; - tin[1] = tin1; - CAST_encrypt(tin, ks); - tout0 = tin[0]; - tout1 = tin[1]; - l2n(tout0, out); - l2n(tout1, out); - } - l2n(tout0, iv); - l2n(tout1, iv); - } else { - n2l(iv, xor0); - n2l(iv, xor1); - iv -= 8; - for (l -= 8; l >= 0; l -= 8) { - n2l(in, tin0); - n2l(in, tin1); - tin[0] = tin0; - tin[1] = tin1; - CAST_decrypt(tin, ks); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2n(tout0, out); - l2n(tout1, out); - xor0 = tin0; - xor1 = tin1; - } - if (l != -8) { - n2l(in, tin0); - n2l(in, tin1); - tin[0] = tin0; - tin[1] = tin1; - CAST_decrypt(tin, ks); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2nn(tout0, tout1, out, l + 8); - xor0 = tin0; - xor1 = tin1; - } - l2n(xor0, iv); - l2n(xor1, iv); - } - tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; - tin[0] = tin[1] = 0; -} -/* crypto/cast/c_ofb64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "cast.h" -// #include "cast_lcl.h" - -/* - * The input and output encrypted as though 64bit ofb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ -void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, const CAST_KEY *schedule, - unsigned char *ivec, int *num) -{ - register CAST_LONG v0, v1, t; - register int n = *num; - register long l = length; - unsigned char d[8]; - register char *dp; - CAST_LONG ti[2]; - unsigned char *iv; - int save = 0; - - iv = ivec; - n2l(iv, v0); - n2l(iv, v1); - ti[0] = v0; - ti[1] = v1; - dp = (char *)d; - l2n(v0, dp); - l2n(v1, dp); - while (l--) { - if (n == 0) { - CAST_encrypt((CAST_LONG *)ti, schedule); - dp = (char *)d; - t = ti[0]; - l2n(t, dp); - t = ti[1]; - l2n(t, dp); - save++; - } - *(out++) = *(in++) ^ d[n]; - n = (n + 1) & 0x07; - } - if (save) { - v0 = ti[0]; - v1 = ti[1]; - iv = ivec; - l2n(v0, iv); - l2n(v1, iv); - } - t = v0 = v1 = ti[0] = ti[1] = 0; - *num = n; -} -#include -#include -#include -// #include "objects.h" -#include "comp.h" - -static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen); -static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen); - -static COMP_METHOD rle_method = { - NID_rle_compression, - LN_rle_compression, - NULL, - NULL, - rle_compress_block, - rle_expand_block, - NULL, - NULL, -}; - -COMP_METHOD *COMP_rle(void) -{ - return (&rle_method); -} - -static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen) -{ - if (ilen == 0) - return 0; - - if (olen <= ilen) - return -1; - - *(out++) = 0; - memcpy(out, in, ilen); - return (ilen + 1); -} - -static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen) -{ - int i; - - if (ilen == 0) - return 0; - - if (olen < (ilen - 1)) - return -1; - - i = *(in++); - if (i != 0) - return -1; - - memcpy(out, in, ilen - 1); - return (ilen - 1); -} -/* crypto/cast/c_skey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "crypto.h" -// #include "cast.h" -// #include "cast_lcl.h" -#include "cast_s.h" - -#define CAST_exp(l,A,a,n) \ - A[n/4]=l; \ - a[n+3]=(l )&0xff; \ - a[n+2]=(l>> 8)&0xff; \ - a[n+1]=(l>>16)&0xff; \ - a[n+0]=(l>>24)&0xff; - -#define S4 CAST_S_table4 -#define S5 CAST_S_table5 -#define S6 CAST_S_table6 -#define S7 CAST_S_table7 -void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) -#ifdef OPENSSL_FIPS -{ - fips_cipher_abort(CAST); - private_CAST_set_key(key, len, data); -} - -void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) -#endif -{ - CAST_LONG x[16]; - CAST_LONG z[16]; - CAST_LONG k[32]; - CAST_LONG X[4], Z[4]; - CAST_LONG l, *K; - int i; - - for (i = 0; i < 16; i++) - x[i] = 0; - if (len > 16) - len = 16; - for (i = 0; i < len; i++) - x[i] = data[i]; - if (len <= 10) - key->short_key = 1; - else - key->short_key = 0; - - K = &k[0]; - X[0] = ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]) & 0xffffffffL; - X[1] = ((x[4] << 24) | (x[5] << 16) | (x[6] << 8) | x[7]) & 0xffffffffL; - X[2] = ((x[8] << 24) | (x[9] << 16) | (x[10] << 8) | x[11]) & 0xffffffffL; - X[3] = - ((x[12] << 24) | (x[13] << 16) | (x[14] << 8) | x[15]) & 0xffffffffL; - - for (;;) { - l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; - CAST_exp(l, Z, z, 0); - l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; - CAST_exp(l, Z, z, 4); - l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; - CAST_exp(l, Z, z, 8); - l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; - CAST_exp(l, Z, z, 12); - - K[0] = S4[z[8]] ^ S5[z[9]] ^ S6[z[7]] ^ S7[z[6]] ^ S4[z[2]]; - K[1] = S4[z[10]] ^ S5[z[11]] ^ S6[z[5]] ^ S7[z[4]] ^ S5[z[6]]; - K[2] = S4[z[12]] ^ S5[z[13]] ^ S6[z[3]] ^ S7[z[2]] ^ S6[z[9]]; - K[3] = S4[z[14]] ^ S5[z[15]] ^ S6[z[1]] ^ S7[z[0]] ^ S7[z[12]]; - - l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; - CAST_exp(l, X, x, 0); - l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; - CAST_exp(l, X, x, 4); - l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; - CAST_exp(l, X, x, 8); - l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; - CAST_exp(l, X, x, 12); - - K[4] = S4[x[3]] ^ S5[x[2]] ^ S6[x[12]] ^ S7[x[13]] ^ S4[x[8]]; - K[5] = S4[x[1]] ^ S5[x[0]] ^ S6[x[14]] ^ S7[x[15]] ^ S5[x[13]]; - K[6] = S4[x[7]] ^ S5[x[6]] ^ S6[x[8]] ^ S7[x[9]] ^ S6[x[3]]; - K[7] = S4[x[5]] ^ S5[x[4]] ^ S6[x[10]] ^ S7[x[11]] ^ S7[x[7]]; - - l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; - CAST_exp(l, Z, z, 0); - l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; - CAST_exp(l, Z, z, 4); - l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; - CAST_exp(l, Z, z, 8); - l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; - CAST_exp(l, Z, z, 12); - - K[8] = S4[z[3]] ^ S5[z[2]] ^ S6[z[12]] ^ S7[z[13]] ^ S4[z[9]]; - K[9] = S4[z[1]] ^ S5[z[0]] ^ S6[z[14]] ^ S7[z[15]] ^ S5[z[12]]; - K[10] = S4[z[7]] ^ S5[z[6]] ^ S6[z[8]] ^ S7[z[9]] ^ S6[z[2]]; - K[11] = S4[z[5]] ^ S5[z[4]] ^ S6[z[10]] ^ S7[z[11]] ^ S7[z[6]]; - - l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; - CAST_exp(l, X, x, 0); - l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; - CAST_exp(l, X, x, 4); - l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; - CAST_exp(l, X, x, 8); - l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; - CAST_exp(l, X, x, 12); - - K[12] = S4[x[8]] ^ S5[x[9]] ^ S6[x[7]] ^ S7[x[6]] ^ S4[x[3]]; - K[13] = S4[x[10]] ^ S5[x[11]] ^ S6[x[5]] ^ S7[x[4]] ^ S5[x[7]]; - K[14] = S4[x[12]] ^ S5[x[13]] ^ S6[x[3]] ^ S7[x[2]] ^ S6[x[8]]; - K[15] = S4[x[14]] ^ S5[x[15]] ^ S6[x[1]] ^ S7[x[0]] ^ S7[x[13]]; - if (K != k) - break; - K += 16; - } - - for (i = 0; i < 16; i++) { - key->data[i * 2] = k[i]; - key->data[i * 2 + 1] = ((k[i + 16]) + 16) & 0x1f; - } -} -#include -#include -#include -// #include "objects.h" -// #include "comp.h" -#include "err.h" - -COMP_METHOD *COMP_zlib(void); - -static COMP_METHOD zlib_method_nozlib = { - NID_undef, - "(undef)", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, -}; - -#ifndef ZLIB -# undef ZLIB_SHARED -#else - -# include - -static int zlib_stateful_init(COMP_CTX *ctx); -static void zlib_stateful_finish(COMP_CTX *ctx); -static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen); -static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen); - -/* memory allocations functions for zlib intialization */ -static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size) -{ - void *p; - - p = OPENSSL_malloc(no * size); - if (p) - memset(p, 0, no * size); - return p; -} - -static void zlib_zfree(void *opaque, void *address) -{ - OPENSSL_free(address); -} - -# if 0 -static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen); -static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen); - -static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source, - uLong sourceLen); - -static COMP_METHOD zlib_stateless_method = { - NID_zlib_compression, - LN_zlib_compression, - NULL, - NULL, - zlib_compress_block, - zlib_expand_block, - NULL, - NULL, -}; -# endif - -static COMP_METHOD zlib_stateful_method = { - NID_zlib_compression, - LN_zlib_compression, - zlib_stateful_init, - zlib_stateful_finish, - zlib_stateful_compress_block, - zlib_stateful_expand_block, - NULL, - NULL, -}; - -/* - * When OpenSSL is built on Windows, we do not want to require that - * the ZLIB.DLL be available in order for the OpenSSL DLLs to - * work. Therefore, all ZLIB routines are loaded at run time - * and we do not link to a .LIB file when ZLIB_SHARED is set. - */ -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) -# include -# endif /* !(OPENSSL_SYS_WINDOWS || - * OPENSSL_SYS_WIN32) */ - -# ifdef ZLIB_SHARED -# include "dso.h" - -/* Function pointers */ -typedef int (*compress_ft) (Bytef *dest, uLongf * destLen, - const Bytef *source, uLong sourceLen); -typedef int (*inflateEnd_ft) (z_streamp strm); -typedef int (*inflate_ft) (z_streamp strm, int flush); -typedef int (*inflateInit__ft) (z_streamp strm, - const char *version, int stream_size); -typedef int (*deflateEnd_ft) (z_streamp strm); -typedef int (*deflate_ft) (z_streamp strm, int flush); -typedef int (*deflateInit__ft) (z_streamp strm, int level, - const char *version, int stream_size); -typedef const char *(*zError__ft) (int err); -static compress_ft p_compress = NULL; -static inflateEnd_ft p_inflateEnd = NULL; -static inflate_ft p_inflate = NULL; -static inflateInit__ft p_inflateInit_ = NULL; -static deflateEnd_ft p_deflateEnd = NULL; -static deflate_ft p_deflate = NULL; -static deflateInit__ft p_deflateInit_ = NULL; -static zError__ft p_zError = NULL; - -static int zlib_loaded = 0; /* only attempt to init func pts once */ -static DSO *zlib_dso = NULL; - -# define compress p_compress -# define inflateEnd p_inflateEnd -# define inflate p_inflate -# define inflateInit_ p_inflateInit_ -# define deflateEnd p_deflateEnd -# define deflate p_deflate -# define deflateInit_ p_deflateInit_ -# define zError p_zError -# endif /* ZLIB_SHARED */ - -struct zlib_state { - z_stream istream; - z_stream ostream; -}; - -static int zlib_stateful_ex_idx = -1; - -static int zlib_stateful_init(COMP_CTX *ctx) -{ - int err; - struct zlib_state *state = - (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state)); - - if (state == NULL) - goto err; - - state->istream.zalloc = zlib_zalloc; - state->istream.zfree = zlib_zfree; - state->istream.opaque = Z_NULL; - state->istream.next_in = Z_NULL; - state->istream.next_out = Z_NULL; - state->istream.avail_in = 0; - state->istream.avail_out = 0; - err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream)); - if (err != Z_OK) - goto err; - - state->ostream.zalloc = zlib_zalloc; - state->ostream.zfree = zlib_zfree; - state->ostream.opaque = Z_NULL; - state->ostream.next_in = Z_NULL; - state->ostream.next_out = Z_NULL; - state->ostream.avail_in = 0; - state->ostream.avail_out = 0; - err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION, - ZLIB_VERSION, sizeof(z_stream)); - if (err != Z_OK) - goto err; - - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data); - CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state); - return 1; - err: - if (state) - OPENSSL_free(state); - return 0; -} - -static void zlib_stateful_finish(COMP_CTX *ctx) -{ - struct zlib_state *state = - (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, - zlib_stateful_ex_idx); - inflateEnd(&state->istream); - deflateEnd(&state->ostream); - OPENSSL_free(state); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data); -} - -static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen) -{ - int err = Z_OK; - struct zlib_state *state = - (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, - zlib_stateful_ex_idx); - - if (state == NULL) - return -1; - - state->ostream.next_in = in; - state->ostream.avail_in = ilen; - state->ostream.next_out = out; - state->ostream.avail_out = olen; - if (ilen > 0) - err = deflate(&state->ostream, Z_SYNC_FLUSH); - if (err != Z_OK) - return -1; -# ifdef DEBUG_ZLIB - fprintf(stderr, "compress(%4d)->%4d %s\n", - ilen, olen - state->ostream.avail_out, - (ilen != olen - state->ostream.avail_out) ? "zlib" : "clear"); -# endif - return olen - state->ostream.avail_out; -} - -static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen) -{ - int err = Z_OK; - - struct zlib_state *state = - (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, - zlib_stateful_ex_idx); - - if (state == NULL) - return 0; - - state->istream.next_in = in; - state->istream.avail_in = ilen; - state->istream.next_out = out; - state->istream.avail_out = olen; - if (ilen > 0) - err = inflate(&state->istream, Z_SYNC_FLUSH); - if (err != Z_OK) - return -1; -# ifdef DEBUG_ZLIB - fprintf(stderr, "expand(%4d)->%4d %s\n", - ilen, olen - state->istream.avail_out, - (ilen != olen - state->istream.avail_out) ? "zlib" : "clear"); -# endif - return olen - state->istream.avail_out; -} - -# if 0 -static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen) -{ - unsigned long l; - int i; - int clear = 1; - - if (ilen > 128) { - out[0] = 1; - l = olen - 1; - i = compress(&(out[1]), &l, in, (unsigned long)ilen); - if (i != Z_OK) - return (-1); - if (ilen > l) { - clear = 0; - l++; - } - } - if (clear) { - out[0] = 0; - memcpy(&(out[1]), in, ilen); - l = ilen + 1; - } -# ifdef DEBUG_ZLIB - fprintf(stderr, "compress(%4d)->%4d %s\n", - ilen, (int)l, (clear) ? "clear" : "zlib"); -# endif - return ((int)l); -} - -static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, - unsigned int olen, unsigned char *in, - unsigned int ilen) -{ - unsigned long l; - int i; - - if (in[0]) { - l = olen; - i = zz_uncompress(out, &l, &(in[1]), (unsigned long)ilen - 1); - if (i != Z_OK) - return (-1); - } else { - memcpy(out, &(in[1]), ilen - 1); - l = ilen - 1; - } -# ifdef DEBUG_ZLIB - fprintf(stderr, "expand (%4d)->%4d %s\n", - ilen, (int)l, in[0] ? "zlib" : "clear"); -# endif - return ((int)l); -} - -static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source, - uLong sourceLen) -{ - z_stream stream; - int err; - - stream.next_in = (Bytef *)source; - stream.avail_in = (uInt) sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong) stream.avail_in != sourceLen) - return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt) * destLen; - if ((uLong) stream.avail_out != *destLen) - return Z_BUF_ERROR; - - stream.zalloc = (alloc_func) 0; - stream.zfree = (free_func) 0; - - err = inflateInit_(&stream, ZLIB_VERSION, sizeof(z_stream)); - if (err != Z_OK) - return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} -# endif - -#endif - -COMP_METHOD *COMP_zlib(void) -{ - COMP_METHOD *meth = &zlib_method_nozlib; - -#ifdef ZLIB_SHARED - if (!zlib_loaded) { -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) - zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0); -# else - zlib_dso = DSO_load(NULL, "z", NULL, 0); -# endif - if (zlib_dso != NULL) { - p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); - p_inflateEnd - = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd"); - p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate"); - p_inflateInit_ - = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); - p_deflateEnd - = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd"); - p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate"); - p_deflateInit_ - = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_"); - p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError"); - - if (p_compress && p_inflateEnd && p_inflate - && p_inflateInit_ && p_deflateEnd - && p_deflate && p_deflateInit_ && p_zError) - zlib_loaded++; - } - } -#endif -#ifdef ZLIB_SHARED - if (zlib_loaded) -#endif -#if defined(ZLIB) || defined(ZLIB_SHARED) - { - /* - * init zlib_stateful_ex_idx here so that in a multi-process - * application it's enough to intialize openssl before forking (idx - * will be inherited in all the children) - */ - if (zlib_stateful_ex_idx == -1) { - CRYPTO_w_lock(CRYPTO_LOCK_COMP); - if (zlib_stateful_ex_idx == -1) - zlib_stateful_ex_idx = - CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP, - 0, NULL, NULL, NULL, NULL); - CRYPTO_w_unlock(CRYPTO_LOCK_COMP); - if (zlib_stateful_ex_idx == -1) - goto err; - } - - meth = &zlib_stateful_method; - } - err: -#endif - - return (meth); -} - -void COMP_zlib_cleanup(void) -{ -#ifdef ZLIB_SHARED - if (zlib_dso != NULL) - DSO_free(zlib_dso); - zlib_dso = NULL; -#endif -} - -#ifdef ZLIB - -/* Zlib based compression/decompression filter BIO */ - -typedef struct { - unsigned char *ibuf; /* Input buffer */ - int ibufsize; /* Buffer size */ - z_stream zin; /* Input decompress context */ - unsigned char *obuf; /* Output buffer */ - int obufsize; /* Output buffer size */ - unsigned char *optr; /* Position in output buffer */ - int ocount; /* Amount of data in output buffer */ - int odone; /* deflate EOF */ - int comp_level; /* Compression level to use */ - z_stream zout; /* Output compression context */ -} BIO_ZLIB_CTX; - -# define ZLIB_DEFAULT_BUFSIZE 1024 - -static int bio_zlib_new(BIO *bi); -static int bio_zlib_free(BIO *bi); -static int bio_zlib_read(BIO *b, char *out, int outl); -static int bio_zlib_write(BIO *b, const char *in, int inl); -static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr); -static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp); - -static BIO_METHOD bio_meth_zlib = { - BIO_TYPE_COMP, - "zlib", - bio_zlib_write, - bio_zlib_read, - NULL, - NULL, - bio_zlib_ctrl, - bio_zlib_new, - bio_zlib_free, - bio_zlib_callback_ctrl -}; - -BIO_METHOD *BIO_f_zlib(void) -{ - return &bio_meth_zlib; -} - -static int bio_zlib_new(BIO *bi) -{ - BIO_ZLIB_CTX *ctx; -# ifdef ZLIB_SHARED - (void)COMP_zlib(); - if (!zlib_loaded) { - COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); - return 0; - } -# endif - ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX)); - if (!ctx) { - COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); - return 0; - } - ctx->ibuf = NULL; - ctx->obuf = NULL; - ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; - ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; - ctx->zin.zalloc = Z_NULL; - ctx->zin.zfree = Z_NULL; - ctx->zin.next_in = NULL; - ctx->zin.avail_in = 0; - ctx->zin.next_out = NULL; - ctx->zin.avail_out = 0; - ctx->zout.zalloc = Z_NULL; - ctx->zout.zfree = Z_NULL; - ctx->zout.next_in = NULL; - ctx->zout.avail_in = 0; - ctx->zout.next_out = NULL; - ctx->zout.avail_out = 0; - ctx->odone = 0; - ctx->comp_level = Z_DEFAULT_COMPRESSION; - bi->init = 1; - bi->ptr = (char *)ctx; - bi->flags = 0; - return 1; -} - -static int bio_zlib_free(BIO *bi) -{ - BIO_ZLIB_CTX *ctx; - if (!bi) - return 0; - ctx = (BIO_ZLIB_CTX *) bi->ptr; - if (ctx->ibuf) { - /* Destroy decompress context */ - inflateEnd(&ctx->zin); - OPENSSL_free(ctx->ibuf); - } - if (ctx->obuf) { - /* Destroy compress context */ - deflateEnd(&ctx->zout); - OPENSSL_free(ctx->obuf); - } - OPENSSL_free(ctx); - bi->ptr = NULL; - bi->init = 0; - bi->flags = 0; - return 1; -} - -static int bio_zlib_read(BIO *b, char *out, int outl) -{ - BIO_ZLIB_CTX *ctx; - int ret; - z_stream *zin; - if (!out || !outl) - return 0; - ctx = (BIO_ZLIB_CTX *) b->ptr; - zin = &ctx->zin; - BIO_clear_retry_flags(b); - if (!ctx->ibuf) { - ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); - if (!ctx->ibuf) { - COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); - return 0; - } - inflateInit(zin); - zin->next_in = ctx->ibuf; - zin->avail_in = 0; - } - - /* Copy output data directly to supplied buffer */ - zin->next_out = (unsigned char *)out; - zin->avail_out = (unsigned int)outl; - for (;;) { - /* Decompress while data available */ - while (zin->avail_in) { - ret = inflate(zin, 0); - if ((ret != Z_OK) && (ret != Z_STREAM_END)) { - COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR); - ERR_add_error_data(2, "zlib error:", zError(ret)); - return 0; - } - /* If EOF or we've read everything then return */ - if ((ret == Z_STREAM_END) || !zin->avail_out) - return outl - zin->avail_out; - } - - /* - * No data in input buffer try to read some in, if an error then - * return the total data read. - */ - ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize); - if (ret <= 0) { - /* Total data read */ - int tot = outl - zin->avail_out; - BIO_copy_next_retry(b); - if (ret < 0) - return (tot > 0) ? tot : ret; - return tot; - } - zin->avail_in = ret; - zin->next_in = ctx->ibuf; - } -} - -static int bio_zlib_write(BIO *b, const char *in, int inl) -{ - BIO_ZLIB_CTX *ctx; - int ret; - z_stream *zout; - if (!in || !inl) - return 0; - ctx = (BIO_ZLIB_CTX *) b->ptr; - if (ctx->odone) - return 0; - zout = &ctx->zout; - BIO_clear_retry_flags(b); - if (!ctx->obuf) { - ctx->obuf = OPENSSL_malloc(ctx->obufsize); - /* Need error here */ - if (!ctx->obuf) { - COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); - return 0; - } - ctx->optr = ctx->obuf; - ctx->ocount = 0; - deflateInit(zout, ctx->comp_level); - zout->next_out = ctx->obuf; - zout->avail_out = ctx->obufsize; - } - /* Obtain input data directly from supplied buffer */ - zout->next_in = (void *)in; - zout->avail_in = inl; - for (;;) { - /* If data in output buffer write it first */ - while (ctx->ocount) { - ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); - if (ret <= 0) { - /* Total data written */ - int tot = inl - zout->avail_in; - BIO_copy_next_retry(b); - if (ret < 0) - return (tot > 0) ? tot : ret; - return tot; - } - ctx->optr += ret; - ctx->ocount -= ret; - } - - /* Have we consumed all supplied data? */ - if (!zout->avail_in) - return inl; - - /* Compress some more */ - - /* Reset buffer */ - ctx->optr = ctx->obuf; - zout->next_out = ctx->obuf; - zout->avail_out = ctx->obufsize; - /* Compress some more */ - ret = deflate(zout, 0); - if (ret != Z_OK) { - COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR); - ERR_add_error_data(2, "zlib error:", zError(ret)); - return 0; - } - ctx->ocount = ctx->obufsize - zout->avail_out; - } -} - -static int bio_zlib_flush(BIO *b) -{ - BIO_ZLIB_CTX *ctx; - int ret; - z_stream *zout; - ctx = (BIO_ZLIB_CTX *) b->ptr; - /* If no data written or already flush show success */ - if (!ctx->obuf || (ctx->odone && !ctx->ocount)) - return 1; - zout = &ctx->zout; - BIO_clear_retry_flags(b); - /* No more input data */ - zout->next_in = NULL; - zout->avail_in = 0; - for (;;) { - /* If data in output buffer write it first */ - while (ctx->ocount) { - ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); - if (ret <= 0) { - BIO_copy_next_retry(b); - return ret; - } - ctx->optr += ret; - ctx->ocount -= ret; - } - if (ctx->odone) - return 1; - - /* Compress some more */ - - /* Reset buffer */ - ctx->optr = ctx->obuf; - zout->next_out = ctx->obuf; - zout->avail_out = ctx->obufsize; - /* Compress some more */ - ret = deflate(zout, Z_FINISH); - if (ret == Z_STREAM_END) - ctx->odone = 1; - else if (ret != Z_OK) { - COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR); - ERR_add_error_data(2, "zlib error:", zError(ret)); - return 0; - } - ctx->ocount = ctx->obufsize - zout->avail_out; - } -} - -static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) -{ - BIO_ZLIB_CTX *ctx; - int ret, *ip; - int ibs, obs; - if (!b->next_bio) - return 0; - ctx = (BIO_ZLIB_CTX *) b->ptr; - switch (cmd) { - - case BIO_CTRL_RESET: - ctx->ocount = 0; - ctx->odone = 0; - ret = 1; - break; - - case BIO_CTRL_FLUSH: - ret = bio_zlib_flush(b); - if (ret > 0) - ret = BIO_flush(b->next_bio); - break; - - case BIO_C_SET_BUFF_SIZE: - ibs = -1; - obs = -1; - if (ptr != NULL) { - ip = ptr; - if (*ip == 0) - ibs = (int)num; - else - obs = (int)num; - } else { - ibs = (int)num; - obs = ibs; - } - - if (ibs != -1) { - if (ctx->ibuf) { - OPENSSL_free(ctx->ibuf); - ctx->ibuf = NULL; - } - ctx->ibufsize = ibs; - } - - if (obs != -1) { - if (ctx->obuf) { - OPENSSL_free(ctx->obuf); - ctx->obuf = NULL; - } - ctx->obufsize = obs; - } - ret = 1; - break; - - case BIO_C_DO_STATE_MACHINE: - BIO_clear_retry_flags(b); - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - BIO_copy_next_retry(b); - break; - - default: - ret = BIO_ctrl(b->next_bio, cmd, num, ptr); - break; - - } - - return ret; -} - -static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) -{ - if (!b->next_bio) - return 0; - return BIO_callback_ctrl(b->next_bio, cmd, fp); -} - -#endif diff --git a/Sources/COpenSSL/camellia.c b/Sources/COpenSSL/camellia.c deleted file mode 100644 index 719fa61c..00000000 --- a/Sources/COpenSSL/camellia.c +++ /dev/null @@ -1,584 +0,0 @@ -/* crypto/camellia/camellia.c */ -/* ==================================================================== - * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . - * ALL RIGHTS RESERVED. - * - * Intellectual Property information for Camellia: - * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html - * - * News Release for Announcement of Camellia open source: - * http://www.ntt.co.jp/news/news06e/0604/060413a.html - * - * The Camellia Code included herein is developed by - * NTT (Nippon Telegraph and Telephone Corporation), and is contributed - * to the OpenSSL project. - * - * The Camellia Code is licensed pursuant to the OpenSSL open source - * license provided below. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -/* - * Algorithm Specification - * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html - */ - -/* - * This release balances code size and performance. In particular key - * schedule setup is fully unrolled, because doing so *significantly* - * reduces amount of instructions per setup round and code increase is - * justifiable. In block functions on the other hand only inner loops - * are unrolled, as full unroll gives only nominal performance boost, - * while code size grows 4 or 7 times. Also, unlike previous versions - * this one "encourages" compiler to keep intermediate variables in - * registers, which should give better "all round" results, in other - * words reasonable performance even with not so modern compilers. - */ - -#include "camellia.h" -#include "cmll_locl.h" -#include -#include - -/* 32-bit rotations */ -#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) -# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) -# define RightRotate(x, s) _lrotr(x, s) -# define LeftRotate(x, s) _lrotl(x, s) -# if _MSC_VER >= 1400 -# define SWAP(x) _byteswap_ulong(x) -# else -# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) -# endif -# define GETU32(p) SWAP(*((u32 *)(p))) -# define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v))) -# elif defined(__GNUC__) && __GNUC__>=2 -# if defined(__i386) || defined(__x86_64) -# define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) -# define LeftRotate(x,s) ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) -# if defined(B_ENDIAN) /* stratus.com does it */ -# define GETU32(p) (*(u32 *)(p)) -# define PUTU32(p,v) (*(u32 *)(p)=(v)) -# else -# define GETU32(p) ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; }) -# define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; }) -# endif -# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ - defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) -# define LeftRotate(x,s) ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; }) -# define RightRotate(x,s) LeftRotate(x,(32-s)) -# elif defined(__s390x__) -# define LeftRotate(x,s) ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; }) -# define RightRotate(x,s) LeftRotate(x,(32-s)) -# define GETU32(p) (*(u32 *)(p)) -# define PUTU32(p,v) (*(u32 *)(p)=(v)) -# endif -# endif -#endif - -#if !defined(RightRotate) && !defined(LeftRotate) -# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) ) -# define LeftRotate(x, s) ( ((x) << (s)) + ((x) >> (32 - s)) ) -#endif - -#if !defined(GETU32) && !defined(PUTU32) -# define GETU32(p) (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] << 8) ^ ((u32)(p)[3])) -# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >> 8), (p)[3] = (u8)(v)) -#endif - -/* S-box data */ -#define SBOX1_1110 Camellia_SBOX[0] -#define SBOX4_4404 Camellia_SBOX[1] -#define SBOX2_0222 Camellia_SBOX[2] -#define SBOX3_3033 Camellia_SBOX[3] -static const u32 Camellia_SBOX[][256] = { - {0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, - 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, - 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, - 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, - 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, - 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, - 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, - 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, - 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, - 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, - 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, - 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, - 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, - 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, - 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, - 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, - 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, - 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, - 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, - 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, - 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, - 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, - 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, - 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, - 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, - 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, - 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, - 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, - 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, - 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, - 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, - 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, - 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, - 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, - 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, - 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, - 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, - 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, - 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, - 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, - 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, - 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, - 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00}, - {0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, - 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, - 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, - 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, - 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, - 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, - 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, - 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, - 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, - 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, - 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, - 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, - 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, - 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, - 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, - 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, - 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, - 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, - 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, - 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, - 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, - 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, - 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, - 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, - 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, - 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, - 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, - 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, - 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, - 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, - 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, - 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, - 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, - 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, - 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, - 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, - 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, - 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, - 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, - 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, - 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, - 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, - 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e}, - {0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, - 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, - 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, - 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, - 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, - 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, - 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, - 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, - 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, - 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, - 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, - 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, - 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, - 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, - 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, - 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, - 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, - 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, - 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, - 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, - 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, - 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, - 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, - 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, - 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, - 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, - 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, - 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, - 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, - 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, - 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, - 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, - 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, - 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, - 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, - 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, - 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, - 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, - 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, - 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, - 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, - 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, - 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d}, - {0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, - 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, - 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, - 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, - 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, - 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, - 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, - 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, - 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, - 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, - 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, - 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, - 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, - 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, - 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, - 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, - 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, - 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, - 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, - 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, - 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, - 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, - 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, - 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, - 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, - 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, - 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, - 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, - 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, - 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, - 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, - 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, - 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, - 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, - 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, - 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, - 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, - 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, - 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, - 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, - 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, - 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, - 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f} -}; - -/* Key generation constants */ -static const u32 SIGMA[] = { - 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, - 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd -}; - -/* The phi algorithm given in C.2.7 of the Camellia spec document. */ -/* - * This version does not attempt to minimize amount of temporary - * variables, but instead explicitly exposes algorithm's parallelism. - * It is therefore most appropriate for platforms with not less than - * ~16 registers. For platforms with less registers [well, x86 to be - * specific] assembler version should be/is provided anyway... - */ -#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\ - register u32 _t0,_t1,_t2,_t3;\ -\ - _t0 = _s0 ^ (_key)[0];\ - _t3 = SBOX4_4404[_t0&0xff];\ - _t1 = _s1 ^ (_key)[1];\ - _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\ - _t2 = SBOX1_1110[_t1&0xff];\ - _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\ - _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\ - _t3 ^= SBOX1_1110[(_t0 >> 24)];\ - _t2 ^= _t3;\ - _t3 = RightRotate(_t3,8);\ - _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\ - _s3 ^= _t3;\ - _t2 ^= SBOX2_0222[(_t1 >> 24)];\ - _s2 ^= _t2; \ - _s3 ^= _t2;\ -} while(0) - -/* - * Note that n has to be less than 32. Rotations for larger amount - * of bits are achieved by "rotating" order of s-elements and - * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32). - */ -#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\ - u32 _t0=_s0>>(32-_n);\ - _s0 = (_s0<<_n) | (_s1>>(32-_n));\ - _s1 = (_s1<<_n) | (_s2>>(32-_n));\ - _s2 = (_s2<<_n) | (_s3>>(32-_n));\ - _s3 = (_s3<<_n) | _t0;\ -} while (0) - -int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k) -{ - register u32 s0, s1, s2, s3; - - k[0] = s0 = GETU32(rawKey); - k[1] = s1 = GETU32(rawKey + 4); - k[2] = s2 = GETU32(rawKey + 8); - k[3] = s3 = GETU32(rawKey + 12); - - if (keyBitLength != 128) { - k[8] = s0 = GETU32(rawKey + 16); - k[9] = s1 = GETU32(rawKey + 20); - if (keyBitLength == 192) { - k[10] = s2 = ~s0; - k[11] = s3 = ~s1; - } else { - k[10] = s2 = GETU32(rawKey + 24); - k[11] = s3 = GETU32(rawKey + 28); - } - s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; - } - - /* Use the Feistel routine to scramble the key material */ - Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0); - Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2); - - s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; - Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4); - Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6); - - /* Fill the keyTable. Requires many block rotations. */ - if (keyBitLength == 128) { - k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3; - RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ - k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; - RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 30 */ - k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; - RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 45 */ - k[24] = s0, k[25] = s1; - RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 60 */ - k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; - RotLeft128(s1, s2, s3, s0, 2); /* KA <<< 94 */ - k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0; - RotLeft128(s1, s2, s3, s0, 17); /* KA <<<111 */ - k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; - - s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3]; - RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 15 */ - k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3; - RotLeft128(s0, s1, s2, s3, 30); /* KL <<< 45 */ - k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; - RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 60 */ - k[26] = s2, k[27] = s3; - RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 77 */ - k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3; - RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 94 */ - k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; - RotLeft128(s0, s1, s2, s3, 17); /* KL <<<111 */ - k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3; - - return 3; /* grand rounds */ - } else { - k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; - s0 ^= k[8], s1 ^= k[9], s2 ^= k[10], s3 ^= k[11]; - Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8)); - Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10)); - - k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3; - RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 30 */ - k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; - RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 60 */ - k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3; - RotLeft128(s1, s2, s3, s0, 19); /* KB <<<111 */ - k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0; - - s0 = k[8], s1 = k[9], s2 = k[10], s3 = k[11]; - RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 15 */ - k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3; - RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 30 */ - k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; - RotLeft128(s0, s1, s2, s3, 30); /* KR <<< 60 */ - k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; - RotLeft128(s1, s2, s3, s0, 2); /* KR <<< 94 */ - k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0; - - s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15]; - RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ - k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; - RotLeft128(s0, s1, s2, s3, 30); /* KA <<< 45 */ - k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; - /* KA <<< 77 */ - k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; - RotLeft128(s1, s2, s3, s0, 17); /* KA <<< 94 */ - k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0; - - s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3]; - RotLeft128(s1, s2, s3, s0, 13); /* KL <<< 45 */ - k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0; - RotLeft128(s1, s2, s3, s0, 15); /* KL <<< 60 */ - k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0; - RotLeft128(s1, s2, s3, s0, 17); /* KL <<< 77 */ - k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0; - RotLeft128(s2, s3, s0, s1, 2); /* KL <<<111 */ - k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1; - - return 4; /* grand rounds */ - } - /* - * It is possible to perform certain precalculations, which - * would spare few cycles in block procedure. It's not done, - * because it upsets the performance balance between key - * setup and block procedures, negatively affecting overall - * throughput in applications operating on short messages - * and volatile keys. - */ -} - -void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], - const KEY_TABLE_TYPE keyTable, - u8 ciphertext[]) -{ - register u32 s0, s1, s2, s3; - const u32 *k = keyTable, *kend = keyTable + grandRounds * 16; - - s0 = GETU32(plaintext) ^ k[0]; - s1 = GETU32(plaintext + 4) ^ k[1]; - s2 = GETU32(plaintext + 8) ^ k[2]; - s3 = GETU32(plaintext + 12) ^ k[3]; - k += 4; - - while (1) { - /* Camellia makes 6 Feistel rounds */ - Camellia_Feistel(s0, s1, s2, s3, k + 0); - Camellia_Feistel(s2, s3, s0, s1, k + 2); - Camellia_Feistel(s0, s1, s2, s3, k + 4); - Camellia_Feistel(s2, s3, s0, s1, k + 6); - Camellia_Feistel(s0, s1, s2, s3, k + 8); - Camellia_Feistel(s2, s3, s0, s1, k + 10); - k += 12; - - if (k == kend) - break; - - /* - * This is the same function as the diffusion function D of the - * accompanying documentation. See section 3.2 for properties of the - * FLlayer function. - */ - s1 ^= LeftRotate(s0 & k[0], 1); - s2 ^= s3 | k[3]; - s0 ^= s1 | k[1]; - s3 ^= LeftRotate(s2 & k[2], 1); - k += 4; - } - - s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; - - PUTU32(ciphertext, s2); - PUTU32(ciphertext + 4, s3); - PUTU32(ciphertext + 8, s0); - PUTU32(ciphertext + 12, s1); -} - -void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], - const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) -{ - Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, - plaintext, keyTable, ciphertext); -} - -void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], - const KEY_TABLE_TYPE keyTable, - u8 plaintext[]) -{ - u32 s0, s1, s2, s3; - const u32 *k = keyTable + grandRounds * 16, *kend = keyTable + 4; - - s0 = GETU32(ciphertext) ^ k[0]; - s1 = GETU32(ciphertext + 4) ^ k[1]; - s2 = GETU32(ciphertext + 8) ^ k[2]; - s3 = GETU32(ciphertext + 12) ^ k[3]; - - while (1) { - /* Camellia makes 6 Feistel rounds */ - k -= 12; - Camellia_Feistel(s0, s1, s2, s3, k + 10); - Camellia_Feistel(s2, s3, s0, s1, k + 8); - Camellia_Feistel(s0, s1, s2, s3, k + 6); - Camellia_Feistel(s2, s3, s0, s1, k + 4); - Camellia_Feistel(s0, s1, s2, s3, k + 2); - Camellia_Feistel(s2, s3, s0, s1, k + 0); - - if (k == kend) - break; - - /* - * This is the same function as the diffusion function D of the - * accompanying documentation. See section 3.2 for properties of the - * FLlayer function. - */ - k -= 4; - s1 ^= LeftRotate(s0 & k[2], 1); - s2 ^= s3 | k[1]; - s0 ^= s1 | k[3]; - s3 ^= LeftRotate(s2 & k[0], 1); - } - - k -= 4; - s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; - - PUTU32(plaintext, s2); - PUTU32(plaintext + 4, s3); - PUTU32(plaintext + 8, s0); - PUTU32(plaintext + 12, s1); -} - -void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], - const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) -{ - Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, - plaintext, keyTable, ciphertext); -} diff --git a/Sources/COpenSSL/camellia.h b/Sources/COpenSSL/camellia.h deleted file mode 100644 index d13dda99..00000000 --- a/Sources/COpenSSL/camellia.h +++ /dev/null @@ -1,132 +0,0 @@ -/* crypto/camellia/camellia.h */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#ifndef HEADER_CAMELLIA_H -# define HEADER_CAMELLIA_H - -# include "opensslconf.h" - -# ifdef OPENSSL_NO_CAMELLIA -# error CAMELLIA is disabled. -# endif - -# include - -# define CAMELLIA_ENCRYPT 1 -# define CAMELLIA_DECRYPT 0 - -/* - * Because array size can't be a const in C, the following two are macros. - * Both sizes are in bytes. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* This should be a hidden type, but EVP requires that the size be known */ - -# define CAMELLIA_BLOCK_SIZE 16 -# define CAMELLIA_TABLE_BYTE_LEN 272 -# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) - -typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match - * with WORD */ - -struct camellia_key_st { - union { - double d; /* ensures 64-bit align */ - KEY_TABLE_TYPE rd_key; - } u; - int grand_rounds; -}; -typedef struct camellia_key_st CAMELLIA_KEY; - -# ifdef OPENSSL_FIPS -int private_Camellia_set_key(const unsigned char *userKey, const int bits, - CAMELLIA_KEY *key); -# endif -int Camellia_set_key(const unsigned char *userKey, const int bits, - CAMELLIA_KEY *key); - -void Camellia_encrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key); -void Camellia_decrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key); - -void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key, const int enc); -void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, const int enc); -void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, int *num, const int enc); -void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, int *num, const int enc); -void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, int *num, const int enc); -void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, int *num); -void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char ivec[CAMELLIA_BLOCK_SIZE], - unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], - unsigned int *num); - -#ifdef __cplusplus -} -#endif - -#endif /* !HEADER_Camellia_H */ diff --git a/Sources/COpenSSL/cast.h b/Sources/COpenSSL/cast.h deleted file mode 100644 index c3da7ae8..00000000 --- a/Sources/COpenSSL/cast.h +++ /dev/null @@ -1,107 +0,0 @@ -/* crypto/cast/cast.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_CAST_H -# define HEADER_CAST_H - -#ifdef __cplusplus -extern "C" { -#endif - -# include "opensslconf.h" - -# ifdef OPENSSL_NO_CAST -# error CAST is disabled. -# endif - -# define CAST_ENCRYPT 1 -# define CAST_DECRYPT 0 - -# define CAST_LONG unsigned int - -# define CAST_BLOCK 8 -# define CAST_KEY_LENGTH 16 - -typedef struct cast_key_st { - CAST_LONG data[32]; - int short_key; /* Use reduced rounds for short key */ -} CAST_KEY; - -# ifdef OPENSSL_FIPS -void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); -# endif -void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); -void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, - const CAST_KEY *key, int enc); -void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); -void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); -void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, - long length, const CAST_KEY *ks, unsigned char *iv, - int enc); -void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, const CAST_KEY *schedule, - unsigned char *ivec, int *num, int enc); -void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, const CAST_KEY *schedule, - unsigned char *ivec, int *num); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/cast_lcl.h b/Sources/COpenSSL/cast_lcl.h deleted file mode 100644 index b0f08294..00000000 --- a/Sources/COpenSSL/cast_lcl.h +++ /dev/null @@ -1,227 +0,0 @@ -/* crypto/cast/cast_lcl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "e_os.h" - -#ifdef OPENSSL_SYS_WIN32 -# include -#endif - -#undef c2l -#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<<24L) - -/* NOTE - c is not incremented as per c2l */ -#undef c2ln -#define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ - } \ - } - -#undef l2c -#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24L)&0xff)) - -/* NOTE - c is not incremented as per l2c */ -#undef l2cn -#define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -/* NOTE - c is not incremented as per n2l */ -#define n2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c)))) ; \ - case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 6: l2|=((unsigned long)(*(--(c))))<<16; \ - case 5: l2|=((unsigned long)(*(--(c))))<<24; \ - case 4: l1 =((unsigned long)(*(--(c)))) ; \ - case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 2: l1|=((unsigned long)(*(--(c))))<<16; \ - case 1: l1|=((unsigned long)(*(--(c))))<<24; \ - } \ - } - -/* NOTE - c is not incremented as per l2n */ -#define l2nn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - } \ - } - -#undef n2l -#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))) - -#undef l2n -#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER) -# define ROTL(a,n) (_lrotl(a,n)) -#elif defined(PEDANTIC) -# define ROTL(a,n) ((((a)<<(n))&0xffffffffL)|((a)>>((32-(n))&31))) -#else -# define ROTL(a,n) ((((a)<<(n))&0xffffffffL)|((a)>>(32-(n)))) -#endif - -#define C_M 0x3fc -#define C_0 22L -#define C_1 14L -#define C_2 6L -#define C_3 2L /* left shift */ - -/* The rotate has an extra 16 added to it to help the x86 asm */ -#if defined(CAST_PTR) -# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ - { \ - int i; \ - t=(key[n*2] OP1 R)&0xffffffffL; \ - i=key[n*2+1]; \ - t=ROTL(t,i); \ - L^= (((((*(CAST_LONG *)((unsigned char *) \ - CAST_S_table0+((t>>C_2)&C_M)) OP2 \ - *(CAST_LONG *)((unsigned char *) \ - CAST_S_table1+((t<>C_0)&C_M)))&0xffffffffL) OP1 \ - *(CAST_LONG *)((unsigned char *) \ - CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \ - } -#elif defined(CAST_PTR2) -# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ - { \ - int i; \ - CAST_LONG u,v,w; \ - w=(key[n*2] OP1 R)&0xffffffffL; \ - i=key[n*2+1]; \ - w=ROTL(w,i); \ - u=w>>C_2; \ - v=w<>C_0; \ - t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\ - v=w>>C_1; \ - u&=C_M; \ - v&=C_M; \ - t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\ - t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\ - L^=(t&0xffffffff); \ - } -#else -# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ - { \ - CAST_LONG a,b,c,d; \ - t=(key[n*2] OP1 R)&0xffffffff; \ - t=ROTL(t,(key[n*2+1])); \ - a=CAST_S_table0[(t>> 8)&0xff]; \ - b=CAST_S_table1[(t )&0xff]; \ - c=CAST_S_table2[(t>>24)&0xff]; \ - d=CAST_S_table3[(t>>16)&0xff]; \ - L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \ - } -#endif - -extern const CAST_LONG CAST_S_table0[256]; -extern const CAST_LONG CAST_S_table1[256]; -extern const CAST_LONG CAST_S_table2[256]; -extern const CAST_LONG CAST_S_table3[256]; -extern const CAST_LONG CAST_S_table4[256]; -extern const CAST_LONG CAST_S_table5[256]; -extern const CAST_LONG CAST_S_table6[256]; -extern const CAST_LONG CAST_S_table7[256]; diff --git a/Sources/COpenSSL/cast_s.h b/Sources/COpenSSL/cast_s.h deleted file mode 100644 index 380dc81a..00000000 --- a/Sources/COpenSSL/cast_s.h +++ /dev/null @@ -1,592 +0,0 @@ -/* crypto/cast/cast_s.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -OPENSSL_GLOBAL const CAST_LONG CAST_S_table0[256] = { - 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, - 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, - 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, - 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, - 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, - 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, - 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, - 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, - 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, - 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, - 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, - 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, - 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, - 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, - 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, - 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, - 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, - 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, - 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, - 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, - 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, - 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, - 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, - 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, - 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, - 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, - 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, - 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, - 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, - 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, - 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, - 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, - 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, - 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, - 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, - 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, - 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, - 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, - 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, - 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, - 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, - 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, - 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, - 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, - 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, - 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, - 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, - 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, - 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, - 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, - 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, - 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, - 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, - 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, - 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, - 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, - 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, - 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, - 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, - 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, - 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, - 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, - 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, - 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf, -}; - -OPENSSL_GLOBAL const CAST_LONG CAST_S_table1[256] = { - 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, - 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, - 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, - 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, - 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, - 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, - 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, - 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, - 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, - 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, - 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, - 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, - 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, - 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, - 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, - 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, - 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, - 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, - 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, - 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, - 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, - 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, - 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, - 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, - 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, - 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, - 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, - 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, - 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, - 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, - 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, - 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, - 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, - 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, - 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, - 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, - 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, - 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, - 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, - 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, - 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, - 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, - 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, - 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, - 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, - 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, - 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, - 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, - 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, - 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, - 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, - 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, - 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, - 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, - 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, - 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, - 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, - 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, - 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, - 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, - 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, - 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, - 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, - 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1, -}; - -OPENSSL_GLOBAL const CAST_LONG CAST_S_table2[256] = { - 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, - 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, - 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, - 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, - 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, - 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, - 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, - 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, - 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, - 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, - 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, - 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, - 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, - 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, - 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, - 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, - 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, - 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, - 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, - 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, - 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, - 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, - 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, - 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, - 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, - 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, - 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, - 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, - 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, - 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, - 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, - 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, - 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, - 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, - 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, - 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, - 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, - 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, - 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, - 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, - 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, - 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, - 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, - 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, - 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, - 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, - 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, - 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, - 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, - 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, - 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, - 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, - 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, - 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, - 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, - 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, - 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, - 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, - 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, - 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, - 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, - 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, - 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, - 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783, -}; - -OPENSSL_GLOBAL const CAST_LONG CAST_S_table3[256] = { - 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, - 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, - 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, - 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, - 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, - 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, - 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, - 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, - 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, - 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, - 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, - 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, - 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, - 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, - 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, - 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, - 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, - 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, - 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, - 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, - 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, - 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, - 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, - 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, - 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, - 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, - 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, - 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, - 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, - 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, - 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, - 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, - 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, - 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, - 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, - 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, - 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, - 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, - 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, - 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, - 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, - 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, - 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, - 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, - 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, - 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, - 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, - 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, - 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, - 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, - 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, - 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, - 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, - 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, - 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, - 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, - 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, - 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, - 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, - 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, - 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, - 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, - 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, - 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2, -}; - -OPENSSL_GLOBAL const CAST_LONG CAST_S_table4[256] = { - 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, - 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, - 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, - 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, - 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, - 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, - 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, - 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, - 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, - 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, - 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, - 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, - 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, - 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, - 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, - 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, - 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, - 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, - 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, - 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, - 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, - 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, - 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, - 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, - 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, - 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, - 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, - 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, - 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, - 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, - 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, - 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, - 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, - 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, - 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, - 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, - 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, - 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, - 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, - 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, - 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, - 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, - 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, - 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, - 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, - 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, - 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, - 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, - 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, - 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, - 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, - 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, - 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, - 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, - 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, - 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, - 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, - 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, - 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, - 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, - 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, - 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, - 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, - 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4, -}; - -OPENSSL_GLOBAL const CAST_LONG CAST_S_table5[256] = { - 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, - 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, - 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, - 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, - 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, - 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, - 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, - 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, - 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, - 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, - 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, - 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, - 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, - 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, - 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, - 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, - 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, - 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, - 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, - 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, - 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, - 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, - 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, - 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, - 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, - 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, - 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, - 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, - 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, - 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, - 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, - 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, - 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, - 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, - 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, - 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, - 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, - 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, - 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, - 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, - 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, - 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, - 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, - 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, - 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, - 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, - 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, - 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, - 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, - 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, - 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, - 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, - 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, - 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, - 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, - 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, - 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, - 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, - 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, - 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, - 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, - 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, - 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, - 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f, -}; - -OPENSSL_GLOBAL const CAST_LONG CAST_S_table6[256] = { - 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, - 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, - 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, - 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, - 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, - 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, - 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, - 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, - 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, - 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, - 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, - 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, - 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, - 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, - 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, - 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, - 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, - 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, - 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, - 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, - 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, - 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, - 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, - 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, - 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, - 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, - 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, - 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, - 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, - 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, - 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, - 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, - 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, - 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, - 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, - 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, - 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, - 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, - 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, - 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, - 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, - 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, - 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, - 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, - 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, - 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, - 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, - 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, - 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, - 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, - 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, - 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, - 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, - 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, - 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, - 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, - 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, - 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, - 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, - 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, - 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, - 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, - 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, - 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3, -}; - -OPENSSL_GLOBAL const CAST_LONG CAST_S_table7[256] = { - 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, - 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, - 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, - 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, - 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, - 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, - 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, - 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, - 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, - 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, - 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, - 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, - 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, - 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, - 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, - 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, - 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, - 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, - 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, - 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, - 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, - 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, - 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, - 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, - 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, - 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, - 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, - 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, - 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, - 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, - 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, - 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, - 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, - 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, - 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, - 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, - 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, - 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, - 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, - 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, - 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, - 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, - 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, - 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, - 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, - 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, - 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, - 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, - 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, - 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, - 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, - 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, - 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, - 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, - 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, - 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, - 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, - 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, - 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, - 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, - 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, - 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, - 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, - 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e, -}; diff --git a/Sources/COpenSSL/cbc128.c b/Sources/COpenSSL/cbc128.c deleted file mode 100644 index 31c76a36..00000000 --- a/Sources/COpenSSL/cbc128.c +++ /dev/null @@ -1,207 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "crypto.h" -#include "modes_lcl.h" -#include - -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -#if !defined(STRICT_ALIGNMENT) && !defined(PEDANTIC) -# define STRICT_ALIGNMENT 0 -#endif - -void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], block128_f block) -{ - size_t n; - const unsigned char *iv = ivec; - - assert(in && out && key && ivec); - -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (STRICT_ALIGNMENT && - ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { - while (len >= 16) { - for (n = 0; n < 16; ++n) - out[n] = in[n] ^ iv[n]; - (*block) (out, out, key); - iv = out; - len -= 16; - in += 16; - out += 16; - } - } else { - while (len >= 16) { - for (n = 0; n < 16; n += sizeof(size_t)) - *(size_t *)(out + n) = - *(size_t *)(in + n) ^ *(size_t *)(iv + n); - (*block) (out, out, key); - iv = out; - len -= 16; - in += 16; - out += 16; - } - } -#endif - while (len) { - for (n = 0; n < 16 && n < len; ++n) - out[n] = in[n] ^ iv[n]; - for (; n < 16; ++n) - out[n] = iv[n]; - (*block) (out, out, key); - iv = out; - if (len <= 16) - break; - len -= 16; - in += 16; - out += 16; - } - memcpy(ivec, iv, 16); -} - -void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], block128_f block) -{ - size_t n; - union { - size_t t[16 / sizeof(size_t)]; - unsigned char c[16]; - } tmp; - - assert(in && out && key && ivec); - -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (in != out) { - const unsigned char *iv = ivec; - - if (STRICT_ALIGNMENT && - ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { - while (len >= 16) { - (*block) (in, out, key); - for (n = 0; n < 16; ++n) - out[n] ^= iv[n]; - iv = in; - len -= 16; - in += 16; - out += 16; - } - } else if (16 % sizeof(size_t) == 0) { /* always true */ - while (len >= 16) { - size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv; - - (*block) (in, out, key); - for (n = 0; n < 16 / sizeof(size_t); n++) - out_t[n] ^= iv_t[n]; - iv = in; - len -= 16; - in += 16; - out += 16; - } - } - memcpy(ivec, iv, 16); - } else { - if (STRICT_ALIGNMENT && - ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { - unsigned char c; - while (len >= 16) { - (*block) (in, tmp.c, key); - for (n = 0; n < 16; ++n) { - c = in[n]; - out[n] = tmp.c[n] ^ ivec[n]; - ivec[n] = c; - } - len -= 16; - in += 16; - out += 16; - } - } else if (16 % sizeof(size_t) == 0) { /* always true */ - while (len >= 16) { - size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec; - const size_t *in_t = (const size_t *)in; - - (*block) (in, tmp.c, key); - for (n = 0; n < 16 / sizeof(size_t); n++) { - c = in_t[n]; - out_t[n] = tmp.t[n] ^ ivec_t[n]; - ivec_t[n] = c; - } - len -= 16; - in += 16; - out += 16; - } - } - } -#endif - while (len) { - unsigned char c; - (*block) (in, tmp.c, key); - for (n = 0; n < 16 && n < len; ++n) { - c = in[n]; - out[n] = tmp.c[n] ^ ivec[n]; - ivec[n] = c; - } - if (len <= 16) { - for (; n < 16; ++n) - ivec[n] = in[n]; - break; - } - len -= 16; - in += 16; - out += 16; - } -} diff --git a/Sources/COpenSSL/cbc3_enc.c b/Sources/COpenSSL/cbc3_enc.c deleted file mode 100644 index 249518a6..00000000 --- a/Sources/COpenSSL/cbc3_enc.c +++ /dev/null @@ -1,95 +0,0 @@ -/* crypto/des/cbc3_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -/* HAS BUGS! DON'T USE - this is only present for use in des.c */ -void DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length, - DES_key_schedule ks1, DES_key_schedule ks2, - DES_cblock *iv1, DES_cblock *iv2, int enc) -{ - int off = ((int)length - 1) / 8; - long l8 = ((length + 7) / 8) * 8; - DES_cblock niv1, niv2; - - if (enc == DES_ENCRYPT) { - DES_cbc_encrypt((unsigned char *)input, - (unsigned char *)output, length, &ks1, iv1, enc); - if (length >= sizeof(DES_cblock)) - memcpy(niv1, output[off], sizeof(DES_cblock)); - DES_cbc_encrypt((unsigned char *)output, - (unsigned char *)output, l8, &ks2, iv1, !enc); - DES_cbc_encrypt((unsigned char *)output, - (unsigned char *)output, l8, &ks1, iv2, enc); - if (length >= sizeof(DES_cblock)) - memcpy(niv2, output[off], sizeof(DES_cblock)); - } else { - if (length >= sizeof(DES_cblock)) - memcpy(niv2, input[off], sizeof(DES_cblock)); - DES_cbc_encrypt((unsigned char *)input, - (unsigned char *)output, l8, &ks1, iv2, enc); - DES_cbc_encrypt((unsigned char *)output, - (unsigned char *)output, l8, &ks2, iv1, !enc); - if (length >= sizeof(DES_cblock)) - memcpy(niv1, output[off], sizeof(DES_cblock)); - DES_cbc_encrypt((unsigned char *)output, - (unsigned char *)output, length, &ks1, iv1, enc); - } - memcpy(*iv1, niv1, sizeof(DES_cblock)); - memcpy(*iv2, niv2, sizeof(DES_cblock)); -} diff --git a/Sources/COpenSSL/cbc_.c b/Sources/COpenSSL/cbc_.c deleted file mode 100644 index 5ef2e8f6..00000000 --- a/Sources/COpenSSL/cbc_.c +++ /dev/null @@ -1,164 +0,0 @@ -/* crypto/des/cbc_cksm.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output, - long length, DES_key_schedule *schedule, - const_DES_cblock *ivec) -{ - register DES_LONG tout0, tout1, tin0, tin1; - register long l = length; - DES_LONG tin[2]; - unsigned char *out = &(*output)[0]; - const unsigned char *iv = &(*ivec)[0]; - - c2l(iv, tout0); - c2l(iv, tout1); - for (; l > 0; l -= 8) { - if (l >= 8) { - c2l(in, tin0); - c2l(in, tin1); - } else - c2ln(in, tin0, tin1, l); - - tin0 ^= tout0; - tin[0] = tin0; - tin1 ^= tout1; - tin[1] = tin1; - DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); - /* fix 15/10/91 eay - thanks to keithr@sco.COM */ - tout0 = tin[0]; - tout1 = tin[1]; - } - if (out != NULL) { - l2c(tout0, out); - l2c(tout1, out); - } - tout0 = tin0 = tin1 = tin[0] = tin[1] = 0; - /* - * Transform the data in tout1 so that it will match the return value - * that the MIT Kerberos mit_des_cbc_cksum API returns. - */ - tout1 = ((tout1 >> 24L) & 0x000000FF) - | ((tout1 >> 8L) & 0x0000FF00) - | ((tout1 << 8L) & 0x00FF0000) - | ((tout1 << 24L) & 0xFF000000); - return (tout1); -} -/* crypto/des/cbc_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#define CBC_ENC_C__DONT_UPDATE_IV - -#include "ncbc_enc.h" /* des_cbc_encrypt */ diff --git a/Sources/COpenSSL/ccm128.c b/Sources/COpenSSL/ccm128.c deleted file mode 100644 index 1a1ad54b..00000000 --- a/Sources/COpenSSL/ccm128.c +++ /dev/null @@ -1,479 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "crypto.h" -#include "modes_lcl.h" -#include - -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -/* - * First you setup M and L parameters and pass the key schedule. This is - * called once per session setup... - */ -void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, - unsigned int M, unsigned int L, void *key, - block128_f block) -{ - memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c)); - ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3; - ctx->blocks = 0; - ctx->block = block; - ctx->key = key; -} - -/* !!! Following interfaces are to be called *once* per packet !!! */ - -/* Then you setup per-message nonce and pass the length of the message */ -int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, - const unsigned char *nonce, size_t nlen, size_t mlen) -{ - unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */ - - if (nlen < (14 - L)) - return -1; /* nonce is too short */ - - if (sizeof(mlen) == 8 && L >= 3) { - ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8))); - ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8))); - ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8))); - ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8))); - } else - ctx->nonce.u[1] = 0; - - ctx->nonce.c[12] = (u8)(mlen >> 24); - ctx->nonce.c[13] = (u8)(mlen >> 16); - ctx->nonce.c[14] = (u8)(mlen >> 8); - ctx->nonce.c[15] = (u8)mlen; - - ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ - memcpy(&ctx->nonce.c[1], nonce, 14 - L); - - return 0; -} - -/* Then you pass additional authentication data, this is optional */ -void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, - const unsigned char *aad, size_t alen) -{ - unsigned int i; - block128_f block = ctx->block; - - if (alen == 0) - return; - - ctx->nonce.c[0] |= 0x40; /* set Adata flag */ - (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++; - - if (alen < (0x10000 - 0x100)) { - ctx->cmac.c[0] ^= (u8)(alen >> 8); - ctx->cmac.c[1] ^= (u8)alen; - i = 2; - } else if (sizeof(alen) == 8 - && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) { - ctx->cmac.c[0] ^= 0xFF; - ctx->cmac.c[1] ^= 0xFF; - ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8))); - ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8))); - ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8))); - ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8))); - ctx->cmac.c[6] ^= (u8)(alen >> 24); - ctx->cmac.c[7] ^= (u8)(alen >> 16); - ctx->cmac.c[8] ^= (u8)(alen >> 8); - ctx->cmac.c[9] ^= (u8)alen; - i = 10; - } else { - ctx->cmac.c[0] ^= 0xFF; - ctx->cmac.c[1] ^= 0xFE; - ctx->cmac.c[2] ^= (u8)(alen >> 24); - ctx->cmac.c[3] ^= (u8)(alen >> 16); - ctx->cmac.c[4] ^= (u8)(alen >> 8); - ctx->cmac.c[5] ^= (u8)alen; - i = 6; - } - - do { - for (; i < 16 && alen; ++i, ++aad, --alen) - ctx->cmac.c[i] ^= *aad; - (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++; - i = 0; - } while (alen); -} - -/* Finally you encrypt or decrypt the message */ - -/* - * counter part of nonce may not be larger than L*8 bits, L is not larger - * than 8, therefore 64-bit counter... - */ -static void ctr64_inc(unsigned char *counter) -{ - unsigned int n = 8; - u8 c; - - counter += 8; - do { - --n; - c = counter[n]; - ++c; - counter[n] = c; - if (c) - return; - } while (n); -} - -int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, - const unsigned char *inp, unsigned char *out, - size_t len) -{ - size_t n; - unsigned int i, L; - unsigned char flags0 = ctx->nonce.c[0]; - block128_f block = ctx->block; - void *key = ctx->key; - union { - u64 u[2]; - u8 c[16]; - } scratch; - - if (!(flags0 & 0x40)) - (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++; - - ctx->nonce.c[0] = L = flags0 & 7; - for (n = 0, i = 15 - L; i < 15; ++i) { - n |= ctx->nonce.c[i]; - ctx->nonce.c[i] = 0; - n <<= 8; - } - n |= ctx->nonce.c[15]; /* reconstructed length */ - ctx->nonce.c[15] = 1; - - if (n != len) - return -1; /* length mismatch */ - - ctx->blocks += ((len + 15) >> 3) | 1; - if (ctx->blocks > (U64(1) << 61)) - return -2; /* too much data */ - - while (len >= 16) { -#if defined(STRICT_ALIGNMENT) - union { - u64 u[2]; - u8 c[16]; - } temp; - - memcpy(temp.c, inp, 16); - ctx->cmac.u[0] ^= temp.u[0]; - ctx->cmac.u[1] ^= temp.u[1]; -#else - ctx->cmac.u[0] ^= ((u64 *)inp)[0]; - ctx->cmac.u[1] ^= ((u64 *)inp)[1]; -#endif - (*block) (ctx->cmac.c, ctx->cmac.c, key); - (*block) (ctx->nonce.c, scratch.c, key); - ctr64_inc(ctx->nonce.c); -#if defined(STRICT_ALIGNMENT) - temp.u[0] ^= scratch.u[0]; - temp.u[1] ^= scratch.u[1]; - memcpy(out, temp.c, 16); -#else - ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]; - ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]; -#endif - inp += 16; - out += 16; - len -= 16; - } - - if (len) { - for (i = 0; i < len; ++i) - ctx->cmac.c[i] ^= inp[i]; - (*block) (ctx->cmac.c, ctx->cmac.c, key); - (*block) (ctx->nonce.c, scratch.c, key); - for (i = 0; i < len; ++i) - out[i] = scratch.c[i] ^ inp[i]; - } - - for (i = 15 - L; i < 16; ++i) - ctx->nonce.c[i] = 0; - - (*block) (ctx->nonce.c, scratch.c, key); - ctx->cmac.u[0] ^= scratch.u[0]; - ctx->cmac.u[1] ^= scratch.u[1]; - - ctx->nonce.c[0] = flags0; - - return 0; -} - -int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, - const unsigned char *inp, unsigned char *out, - size_t len) -{ - size_t n; - unsigned int i, L; - unsigned char flags0 = ctx->nonce.c[0]; - block128_f block = ctx->block; - void *key = ctx->key; - union { - u64 u[2]; - u8 c[16]; - } scratch; - - if (!(flags0 & 0x40)) - (*block) (ctx->nonce.c, ctx->cmac.c, key); - - ctx->nonce.c[0] = L = flags0 & 7; - for (n = 0, i = 15 - L; i < 15; ++i) { - n |= ctx->nonce.c[i]; - ctx->nonce.c[i] = 0; - n <<= 8; - } - n |= ctx->nonce.c[15]; /* reconstructed length */ - ctx->nonce.c[15] = 1; - - if (n != len) - return -1; - - while (len >= 16) { -#if defined(STRICT_ALIGNMENT) - union { - u64 u[2]; - u8 c[16]; - } temp; -#endif - (*block) (ctx->nonce.c, scratch.c, key); - ctr64_inc(ctx->nonce.c); -#if defined(STRICT_ALIGNMENT) - memcpy(temp.c, inp, 16); - ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); - ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); - memcpy(out, scratch.c, 16); -#else - ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]); - ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]); -#endif - (*block) (ctx->cmac.c, ctx->cmac.c, key); - - inp += 16; - out += 16; - len -= 16; - } - - if (len) { - (*block) (ctx->nonce.c, scratch.c, key); - for (i = 0; i < len; ++i) - ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); - (*block) (ctx->cmac.c, ctx->cmac.c, key); - } - - for (i = 15 - L; i < 16; ++i) - ctx->nonce.c[i] = 0; - - (*block) (ctx->nonce.c, scratch.c, key); - ctx->cmac.u[0] ^= scratch.u[0]; - ctx->cmac.u[1] ^= scratch.u[1]; - - ctx->nonce.c[0] = flags0; - - return 0; -} - -static void ctr64_add(unsigned char *counter, size_t inc) -{ - size_t n = 8, val = 0; - - counter += 8; - do { - --n; - val += counter[n] + (inc & 0xff); - counter[n] = (unsigned char)val; - val >>= 8; /* carry bit */ - inc >>= 8; - } while (n && (inc || val)); -} - -int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, - const unsigned char *inp, unsigned char *out, - size_t len, ccm128_f stream) -{ - size_t n; - unsigned int i, L; - unsigned char flags0 = ctx->nonce.c[0]; - block128_f block = ctx->block; - void *key = ctx->key; - union { - u64 u[2]; - u8 c[16]; - } scratch; - - if (!(flags0 & 0x40)) - (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++; - - ctx->nonce.c[0] = L = flags0 & 7; - for (n = 0, i = 15 - L; i < 15; ++i) { - n |= ctx->nonce.c[i]; - ctx->nonce.c[i] = 0; - n <<= 8; - } - n |= ctx->nonce.c[15]; /* reconstructed length */ - ctx->nonce.c[15] = 1; - - if (n != len) - return -1; /* length mismatch */ - - ctx->blocks += ((len + 15) >> 3) | 1; - if (ctx->blocks > (U64(1) << 61)) - return -2; /* too much data */ - - if ((n = len / 16)) { - (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c); - n *= 16; - inp += n; - out += n; - len -= n; - if (len) - ctr64_add(ctx->nonce.c, n / 16); - } - - if (len) { - for (i = 0; i < len; ++i) - ctx->cmac.c[i] ^= inp[i]; - (*block) (ctx->cmac.c, ctx->cmac.c, key); - (*block) (ctx->nonce.c, scratch.c, key); - for (i = 0; i < len; ++i) - out[i] = scratch.c[i] ^ inp[i]; - } - - for (i = 15 - L; i < 16; ++i) - ctx->nonce.c[i] = 0; - - (*block) (ctx->nonce.c, scratch.c, key); - ctx->cmac.u[0] ^= scratch.u[0]; - ctx->cmac.u[1] ^= scratch.u[1]; - - ctx->nonce.c[0] = flags0; - - return 0; -} - -int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, - const unsigned char *inp, unsigned char *out, - size_t len, ccm128_f stream) -{ - size_t n; - unsigned int i, L; - unsigned char flags0 = ctx->nonce.c[0]; - block128_f block = ctx->block; - void *key = ctx->key; - union { - u64 u[2]; - u8 c[16]; - } scratch; - - if (!(flags0 & 0x40)) - (*block) (ctx->nonce.c, ctx->cmac.c, key); - - ctx->nonce.c[0] = L = flags0 & 7; - for (n = 0, i = 15 - L; i < 15; ++i) { - n |= ctx->nonce.c[i]; - ctx->nonce.c[i] = 0; - n <<= 8; - } - n |= ctx->nonce.c[15]; /* reconstructed length */ - ctx->nonce.c[15] = 1; - - if (n != len) - return -1; - - if ((n = len / 16)) { - (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c); - n *= 16; - inp += n; - out += n; - len -= n; - if (len) - ctr64_add(ctx->nonce.c, n / 16); - } - - if (len) { - (*block) (ctx->nonce.c, scratch.c, key); - for (i = 0; i < len; ++i) - ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); - (*block) (ctx->cmac.c, ctx->cmac.c, key); - } - - for (i = 15 - L; i < 16; ++i) - ctx->nonce.c[i] = 0; - - (*block) (ctx->nonce.c, scratch.c, key); - ctx->cmac.u[0] ^= scratch.u[0]; - ctx->cmac.u[1] ^= scratch.u[1]; - - ctx->nonce.c[0] = flags0; - - return 0; -} - -size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len) -{ - unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */ - - M *= 2; - M += 2; - if (len < M) - return 0; - memcpy(tag, ctx->cmac.c, M); - return M; -} diff --git a/Sources/COpenSSL/cfb128.c b/Sources/COpenSSL/cfb128.c deleted file mode 100644 index b55c3576..00000000 --- a/Sources/COpenSSL/cfb128.c +++ /dev/null @@ -1,254 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "crypto.h" -#include "modes_lcl.h" -#include - -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -/* - * The input and output encrypted as though 128bit cfb mode is being used. - * The extra state information to record how much of the 128bit block we have - * used is contained in *num; - */ -void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], int *num, - int enc, block128_f block) -{ - unsigned int n; - size_t l = 0; - - assert(in && out && key && ivec && num); - - n = *num; - - if (enc) { -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (16 % sizeof(size_t) == 0) { /* always true actually */ - do { - while (n && len) { - *(out++) = ivec[n] ^= *(in++); - --len; - n = (n + 1) % 16; - } -# if defined(STRICT_ALIGNMENT) - if (((size_t)in | (size_t)out | (size_t)ivec) % - sizeof(size_t) != 0) - break; -# endif - while (len >= 16) { - (*block) (ivec, ivec, key); - for (; n < 16; n += sizeof(size_t)) { - *(size_t *)(out + n) = - *(size_t *)(ivec + n) ^= *(size_t *)(in + n); - } - len -= 16; - out += 16; - in += 16; - n = 0; - } - if (len) { - (*block) (ivec, ivec, key); - while (len--) { - out[n] = ivec[n] ^= in[n]; - ++n; - } - } - *num = n; - return; - } while (0); - } - /* the rest would be commonly eliminated by x86* compiler */ -#endif - while (l < len) { - if (n == 0) { - (*block) (ivec, ivec, key); - } - out[l] = ivec[n] ^= in[l]; - ++l; - n = (n + 1) % 16; - } - *num = n; - } else { -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (16 % sizeof(size_t) == 0) { /* always true actually */ - do { - while (n && len) { - unsigned char c; - *(out++) = ivec[n] ^ (c = *(in++)); - ivec[n] = c; - --len; - n = (n + 1) % 16; - } -# if defined(STRICT_ALIGNMENT) - if (((size_t)in | (size_t)out | (size_t)ivec) % - sizeof(size_t) != 0) - break; -# endif - while (len >= 16) { - (*block) (ivec, ivec, key); - for (; n < 16; n += sizeof(size_t)) { - size_t t = *(size_t *)(in + n); - *(size_t *)(out + n) = *(size_t *)(ivec + n) ^ t; - *(size_t *)(ivec + n) = t; - } - len -= 16; - out += 16; - in += 16; - n = 0; - } - if (len) { - (*block) (ivec, ivec, key); - while (len--) { - unsigned char c; - out[n] = ivec[n] ^ (c = in[n]); - ivec[n] = c; - ++n; - } - } - *num = n; - return; - } while (0); - } - /* the rest would be commonly eliminated by x86* compiler */ -#endif - while (l < len) { - unsigned char c; - if (n == 0) { - (*block) (ivec, ivec, key); - } - out[l] = ivec[n] ^ (c = in[l]); - ivec[n] = c; - ++l; - n = (n + 1) % 16; - } - *num = n; - } -} - -/* - * This expects a single block of size nbits for both in and out. Note that - * it corrupts any extra bits in the last byte of out - */ -static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out, - int nbits, const void *key, - unsigned char ivec[16], int enc, - block128_f block) -{ - int n, rem, num; - unsigned char ovec[16 * 2 + 1]; /* +1 because we dererefence (but don't - * use) one byte off the end */ - - if (nbits <= 0 || nbits > 128) - return; - - /* fill in the first half of the new IV with the current IV */ - memcpy(ovec, ivec, 16); - /* construct the new IV */ - (*block) (ivec, ivec, key); - num = (nbits + 7) / 8; - if (enc) /* encrypt the input */ - for (n = 0; n < num; ++n) - out[n] = (ovec[16 + n] = in[n] ^ ivec[n]); - else /* decrypt the input */ - for (n = 0; n < num; ++n) - out[n] = (ovec[16 + n] = in[n]) ^ ivec[n]; - /* shift ovec left... */ - rem = nbits % 8; - num = nbits / 8; - if (rem == 0) - memcpy(ivec, ovec + num, 16); - else - for (n = 0; n < 16; ++n) - ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem); - - /* it is not necessary to cleanse ovec, since the IV is not secret */ -} - -/* N.B. This expects the input to be packed, MS bit first */ -void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, - size_t bits, const void *key, - unsigned char ivec[16], int *num, - int enc, block128_f block) -{ - size_t n; - unsigned char c[1], d[1]; - - assert(in && out && key && ivec && num); - assert(*num == 0); - - for (n = 0; n < bits; ++n) { - c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; - cfbr_encrypt_block(c, d, 1, key, ivec, enc, block); - out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) | - ((d[0] & 0x80) >> (unsigned int)(n % 8)); - } -} - -void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const void *key, - unsigned char ivec[16], int *num, - int enc, block128_f block) -{ - size_t n; - - assert(in && out && key && ivec && num); - assert(*num == 0); - - for (n = 0; n < length; ++n) - cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block); -} diff --git a/Sources/COpenSSL/cfb64ede.c b/Sources/COpenSSL/cfb64ede.c deleted file mode 100644 index 5d709c12..00000000 --- a/Sources/COpenSSL/cfb64ede.c +++ /dev/null @@ -1,249 +0,0 @@ -/* crypto/des/cfb64ede.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" -#include "e_os.h" - -/* - * The input and output encrypted as though 64bit cfb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ - -void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *ivec, int *num, int enc) -{ - register DES_LONG v0, v1; - register long l = length; - register int n = *num; - DES_LONG ti[2]; - unsigned char *iv, c, cc; - - iv = &(*ivec)[0]; - if (enc) { - while (l--) { - if (n == 0) { - c2l(iv, v0); - c2l(iv, v1); - - ti[0] = v0; - ti[1] = v1; - DES_encrypt3(ti, ks1, ks2, ks3); - v0 = ti[0]; - v1 = ti[1]; - - iv = &(*ivec)[0]; - l2c(v0, iv); - l2c(v1, iv); - iv = &(*ivec)[0]; - } - c = *(in++) ^ iv[n]; - *(out++) = c; - iv[n] = c; - n = (n + 1) & 0x07; - } - } else { - while (l--) { - if (n == 0) { - c2l(iv, v0); - c2l(iv, v1); - - ti[0] = v0; - ti[1] = v1; - DES_encrypt3(ti, ks1, ks2, ks3); - v0 = ti[0]; - v1 = ti[1]; - - iv = &(*ivec)[0]; - l2c(v0, iv); - l2c(v1, iv); - iv = &(*ivec)[0]; - } - cc = *(in++); - c = iv[n]; - iv[n] = cc; - *(out++) = c ^ cc; - n = (n + 1) & 0x07; - } - } - v0 = v1 = ti[0] = ti[1] = c = cc = 0; - *num = n; -} - -#ifdef undef /* MACRO */ -void DES_ede2_cfb64_encrypt(unsigned char *in, unsigned char *out, - long length, DES_key_schedule ks1, - DES_key_schedule ks2, DES_cblock (*ivec), - int *num, int enc) -{ - DES_ede3_cfb64_encrypt(in, out, length, ks1, ks2, ks1, ivec, num, enc); -} -#endif - -/* - * This is compatible with the single key CFB-r for DES, even thought that's - * not what EVP needs. - */ - -void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, - int numbits, long length, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *ivec, int enc) -{ - register DES_LONG d0, d1, v0, v1; - register unsigned long l = length, n = ((unsigned int)numbits + 7) / 8; - register int num = numbits, i; - DES_LONG ti[2]; - unsigned char *iv; - unsigned char ovec[16]; - - if (num > 64) - return; - iv = &(*ivec)[0]; - c2l(iv, v0); - c2l(iv, v1); - if (enc) { - while (l >= n) { - l -= n; - ti[0] = v0; - ti[1] = v1; - DES_encrypt3(ti, ks1, ks2, ks3); - c2ln(in, d0, d1, n); - in += n; - d0 ^= ti[0]; - d1 ^= ti[1]; - l2cn(d0, d1, out, n); - out += n; - /* - * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under - * gcc :-( - */ - if (num == 32) { - v0 = v1; - v1 = d0; - } else if (num == 64) { - v0 = d0; - v1 = d1; - } else { - iv = &ovec[0]; - l2c(v0, iv); - l2c(v1, iv); - l2c(d0, iv); - l2c(d1, iv); - /* shift ovec left most of the bits... */ - memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0)); - /* now the remaining bits */ - if (num % 8 != 0) - for (i = 0; i < 8; ++i) { - ovec[i] <<= num % 8; - ovec[i] |= ovec[i + 1] >> (8 - num % 8); - } - iv = &ovec[0]; - c2l(iv, v0); - c2l(iv, v1); - } - } - } else { - while (l >= n) { - l -= n; - ti[0] = v0; - ti[1] = v1; - DES_encrypt3(ti, ks1, ks2, ks3); - c2ln(in, d0, d1, n); - in += n; - /* - * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under - * gcc :-( - */ - if (num == 32) { - v0 = v1; - v1 = d0; - } else if (num == 64) { - v0 = d0; - v1 = d1; - } else { - iv = &ovec[0]; - l2c(v0, iv); - l2c(v1, iv); - l2c(d0, iv); - l2c(d1, iv); - /* shift ovec left most of the bits... */ - memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0)); - /* now the remaining bits */ - if (num % 8 != 0) - for (i = 0; i < 8; ++i) { - ovec[i] <<= num % 8; - ovec[i] |= ovec[i + 1] >> (8 - num % 8); - } - iv = &ovec[0]; - c2l(iv, v0); - c2l(iv, v1); - } - d0 ^= ti[0]; - d1 ^= ti[1]; - l2cn(d0, d1, out, n); - out += n; - } - } - iv = &(*ivec)[0]; - l2c(v0, iv); - l2c(v1, iv); - v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; -} diff --git a/Sources/COpenSSL/cfb64enc.c b/Sources/COpenSSL/cfb64enc.c deleted file mode 100644 index 7346774e..00000000 --- a/Sources/COpenSSL/cfb64enc.c +++ /dev/null @@ -1,122 +0,0 @@ -/* crypto/des/cfb64enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -/* - * The input and output encrypted as though 64bit cfb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ - -void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int *num, int enc) -{ - register DES_LONG v0, v1; - register long l = length; - register int n = *num; - DES_LONG ti[2]; - unsigned char *iv, c, cc; - - iv = &(*ivec)[0]; - if (enc) { - while (l--) { - if (n == 0) { - c2l(iv, v0); - ti[0] = v0; - c2l(iv, v1); - ti[1] = v1; - DES_encrypt1(ti, schedule, DES_ENCRYPT); - iv = &(*ivec)[0]; - v0 = ti[0]; - l2c(v0, iv); - v0 = ti[1]; - l2c(v0, iv); - iv = &(*ivec)[0]; - } - c = *(in++) ^ iv[n]; - *(out++) = c; - iv[n] = c; - n = (n + 1) & 0x07; - } - } else { - while (l--) { - if (n == 0) { - c2l(iv, v0); - ti[0] = v0; - c2l(iv, v1); - ti[1] = v1; - DES_encrypt1(ti, schedule, DES_ENCRYPT); - iv = &(*ivec)[0]; - v0 = ti[0]; - l2c(v0, iv); - v0 = ti[1]; - l2c(v0, iv); - iv = &(*ivec)[0]; - } - cc = *(in++); - c = iv[n]; - iv[n] = cc; - *(out++) = c ^ cc; - n = (n + 1) & 0x07; - } - } - v0 = v1 = ti[0] = ti[1] = c = cc = 0; - *num = n; -} diff --git a/Sources/COpenSSL/cfb_enc.c b/Sources/COpenSSL/cfb_enc.c deleted file mode 100644 index bd0e2997..00000000 --- a/Sources/COpenSSL/cfb_enc.c +++ /dev/null @@ -1,199 +0,0 @@ -/* crypto/des/cfb_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "e_os.h" -#include "des_locl.h" -#include - -/* - * The input and output are loaded in multiples of 8 bits. What this means is - * that if you hame numbits=12 and length=2 the first 12 bits will be - * retrieved from the first byte and half the second. The second 12 bits - * will come from the 3rd and half the 4th byte. - */ -/* - * Until Aug 1 2003 this function did not correctly implement CFB-r, so it - * will not be compatible with any encryption prior to that date. Ben. - */ -void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int enc) -{ - register DES_LONG d0, d1, v0, v1; - register unsigned long l = length; - register int num = numbits / 8, n = (numbits + 7) / 8, i, rem = - numbits % 8; - DES_LONG ti[2]; - unsigned char *iv; -#ifndef L_ENDIAN - unsigned char ovec[16]; -#else - unsigned int sh[4]; - unsigned char *ovec = (unsigned char *)sh; - - /* I kind of count that compiler optimizes away this assertioni, */ - assert(sizeof(sh[0]) == 4); /* as this holds true for all, */ - /* but 16-bit platforms... */ - -#endif - - if (numbits <= 0 || numbits > 64) - return; - iv = &(*ivec)[0]; - c2l(iv, v0); - c2l(iv, v1); - if (enc) { - while (l >= (unsigned long)n) { - l -= n; - ti[0] = v0; - ti[1] = v1; - DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); - c2ln(in, d0, d1, n); - in += n; - d0 ^= ti[0]; - d1 ^= ti[1]; - l2cn(d0, d1, out, n); - out += n; - /* - * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under - * gcc :-( - */ - if (numbits == 32) { - v0 = v1; - v1 = d0; - } else if (numbits == 64) { - v0 = d0; - v1 = d1; - } else { -#ifndef L_ENDIAN - iv = &ovec[0]; - l2c(v0, iv); - l2c(v1, iv); - l2c(d0, iv); - l2c(d1, iv); -#else - sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; -#endif - if (rem == 0) - memmove(ovec, ovec + num, 8); - else - for (i = 0; i < 8; ++i) - ovec[i] = ovec[i + num] << rem | - ovec[i + num + 1] >> (8 - rem); -#ifdef L_ENDIAN - v0 = sh[0], v1 = sh[1]; -#else - iv = &ovec[0]; - c2l(iv, v0); - c2l(iv, v1); -#endif - } - } - } else { - while (l >= (unsigned long)n) { - l -= n; - ti[0] = v0; - ti[1] = v1; - DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); - c2ln(in, d0, d1, n); - in += n; - /* - * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under - * gcc :-( - */ - if (numbits == 32) { - v0 = v1; - v1 = d0; - } else if (numbits == 64) { - v0 = d0; - v1 = d1; - } else { -#ifndef L_ENDIAN - iv = &ovec[0]; - l2c(v0, iv); - l2c(v1, iv); - l2c(d0, iv); - l2c(d1, iv); -#else - sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; -#endif - if (rem == 0) - memmove(ovec, ovec + num, 8); - else - for (i = 0; i < 8; ++i) - ovec[i] = ovec[i + num] << rem | - ovec[i + num + 1] >> (8 - rem); -#ifdef L_ENDIAN - v0 = sh[0], v1 = sh[1]; -#else - iv = &ovec[0]; - c2l(iv, v0); - c2l(iv, v1); -#endif - } - d0 ^= ti[0]; - d1 ^= ti[1]; - l2cn(d0, d1, out, n); - out += n; - } - } - iv = &(*ivec)[0]; - l2c(v0, iv); - l2c(v1, iv); - v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; -} diff --git a/Sources/COpenSSL/charmap.h b/Sources/COpenSSL/charmap.h deleted file mode 100644 index 3305ad14..00000000 --- a/Sources/COpenSSL/charmap.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Auto generated with chartype.pl script. Mask of various character - * properties - */ - -static const unsigned char char_type[] = { - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0, - 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2 -}; diff --git a/Sources/COpenSSL/cm_.c b/Sources/COpenSSL/cm_.c deleted file mode 100644 index ce66d1fd..00000000 --- a/Sources/COpenSSL/cm_.c +++ /dev/null @@ -1,313 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2010. - */ -/* ==================================================================== - * Copyright (c) 2010 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "cmac.h" -#include "asn1_locl.h" - -/* - * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output - * length and to free up a CMAC key. - */ - -static int cmac_size(const EVP_PKEY *pkey) -{ - return EVP_MAX_BLOCK_LENGTH; -} - -static void cmac_key_free(EVP_PKEY *pkey) -{ - CMAC_CTX *cmctx = (CMAC_CTX *)pkey->pkey.ptr; - if (cmctx) - CMAC_CTX_free(cmctx); -} - -const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { - EVP_PKEY_CMAC, - EVP_PKEY_CMAC, - 0, - - "CMAC", - "OpenSSL CMAC method", - - 0, 0, 0, 0, - - 0, 0, 0, - - cmac_size, - 0, - 0, 0, 0, 0, 0, 0, 0, - - cmac_key_free, - 0, - 0, 0 -}; -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2010. - */ -/* ==================================================================== - * Copyright (c) 2010 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include -// #include "cryptlib.h" -#include "x509.h" -#include "x509v3.h" -// #include "evp.h" -// #include "cmac.h" -#include "evp_locl.h" - -/* The context structure and "key" is simply a CMAC_CTX */ - -static int pkey_cmac_init(EVP_PKEY_CTX *ctx) -{ - ctx->data = CMAC_CTX_new(); - if (!ctx->data) - return 0; - ctx->keygen_info_count = 0; - return 1; -} - -static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - if (!pkey_cmac_init(dst)) - return 0; - if (!CMAC_CTX_copy(dst->data, src->data)) - return 0; - return 1; -} - -static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) -{ - CMAC_CTX_free(ctx->data); -} - -static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - CMAC_CTX *cmkey = CMAC_CTX_new(); - CMAC_CTX *cmctx = ctx->data; - if (!cmkey) - return 0; - if (!CMAC_CTX_copy(cmkey, cmctx)) { - CMAC_CTX_free(cmkey); - return 0; - } - EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); - - return 1; -} - -static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - if (!CMAC_Update(ctx->pctx->data, data, count)) - return 0; - return 1; -} - -static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); - mctx->update = int_update; - return 1; -} - -static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - EVP_MD_CTX *mctx) -{ - return CMAC_Final(ctx->data, sig, siglen); -} - -static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - CMAC_CTX *cmctx = ctx->data; - switch (type) { - - case EVP_PKEY_CTRL_SET_MAC_KEY: - if (!p2 || p1 < 0) - return 0; - if (!CMAC_Init(cmctx, p2, p1, NULL, NULL)) - return 0; - break; - - case EVP_PKEY_CTRL_CIPHER: - if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine)) - return 0; - break; - - case EVP_PKEY_CTRL_MD: - if (ctx->pkey && !CMAC_CTX_copy(ctx->data, - (CMAC_CTX *)ctx->pkey->pkey.ptr)) - return 0; - if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL)) - return 0; - break; - - default: - return -2; - - } - return 1; -} - -static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!value) { - return 0; - } - if (!strcmp(type, "key")) { - void *p = (void *)value; - return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, strlen(p), p); - } - if (!strcmp(type, "cipher")) { - const EVP_CIPHER *c; - c = EVP_get_cipherbyname(value); - if (!c) - return 0; - return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c); - } - if (!strcmp(type, "hexkey")) { - unsigned char *key; - int r; - long keylen; - key = string_to_hex(value, &keylen); - if (!key) - return 0; - r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); - OPENSSL_free(key); - return r; - } - return -2; -} - -const EVP_PKEY_METHOD cmac_pkey_meth = { - EVP_PKEY_CMAC, - EVP_PKEY_FLAG_SIGCTX_CUSTOM, - pkey_cmac_init, - pkey_cmac_copy, - pkey_cmac_cleanup, - - 0, 0, - - 0, - pkey_cmac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - cmac_signctx_init, - cmac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_cmac_ctrl, - pkey_cmac_ctrl_str -}; diff --git a/Sources/COpenSSL/cmac.c b/Sources/COpenSSL/cmac.c deleted file mode 100644 index 6d9aafa3..00000000 --- a/Sources/COpenSSL/cmac.c +++ /dev/null @@ -1,307 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/cmac/cmac.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2010 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include -#include -#include -#include "cryptlib.h" -#include "cmac.h" - -#ifdef OPENSSL_FIPS -# include -#endif - -struct CMAC_CTX_st { - /* Cipher context to use */ - EVP_CIPHER_CTX cctx; - /* Keys k1 and k2 */ - unsigned char k1[EVP_MAX_BLOCK_LENGTH]; - unsigned char k2[EVP_MAX_BLOCK_LENGTH]; - /* Temporary block */ - unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; - /* Last (possibly partial) block */ - unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; - /* Number of bytes in last block: -1 means context not initialised */ - int nlast_block; -}; - -/* Make temporary keys K1 and K2 */ - -static void make_kn(unsigned char *k1, unsigned char *l, int bl) -{ - int i; - /* Shift block to left, including carry */ - for (i = 0; i < bl; i++) { - k1[i] = l[i] << 1; - if (i < bl - 1 && l[i + 1] & 0x80) - k1[i] |= 1; - } - /* If MSB set fixup with R */ - if (l[0] & 0x80) - k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; -} - -CMAC_CTX *CMAC_CTX_new(void) -{ - CMAC_CTX *ctx; - ctx = OPENSSL_malloc(sizeof(CMAC_CTX)); - if (!ctx) - return NULL; - EVP_CIPHER_CTX_init(&ctx->cctx); - ctx->nlast_block = -1; - return ctx; -} - -void CMAC_CTX_cleanup(CMAC_CTX *ctx) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) { - FIPS_cmac_ctx_cleanup(ctx); - return; - } -#endif - EVP_CIPHER_CTX_cleanup(&ctx->cctx); - OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); - OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); - OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH); - OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH); - ctx->nlast_block = -1; -} - -EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) -{ - return &ctx->cctx; -} - -void CMAC_CTX_free(CMAC_CTX *ctx) -{ - if (!ctx) - return; - CMAC_CTX_cleanup(ctx); - OPENSSL_free(ctx); -} - -int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) -{ - int bl; - if (in->nlast_block == -1) - return 0; - if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx)) - return 0; - bl = EVP_CIPHER_CTX_block_size(&in->cctx); - memcpy(out->k1, in->k1, bl); - memcpy(out->k2, in->k2, bl); - memcpy(out->tbl, in->tbl, bl); - memcpy(out->last_block, in->last_block, bl); - out->nlast_block = in->nlast_block; - return 1; -} - -int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, - const EVP_CIPHER *cipher, ENGINE *impl) -{ - static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; -#ifdef OPENSSL_FIPS - if (FIPS_mode()) { - /* If we have an ENGINE need to allow non FIPS */ - if ((impl || ctx->cctx.engine) - && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { - EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS); - return 0; - } - - /* Switch to FIPS cipher implementation if possible */ - if (cipher != NULL) { - const EVP_CIPHER *fcipher; - fcipher = FIPS_get_cipherbynid(EVP_CIPHER_nid(cipher)); - if (fcipher != NULL) - cipher = fcipher; - } - /* - * Other algorithm blocking will be done in FIPS_cmac_init, via - * FIPS_cipherinit(). - */ - if (!impl && !ctx->cctx.engine) - return FIPS_cmac_init(ctx, key, keylen, cipher, NULL); - } -#endif - /* All zeros means restart */ - if (!key && !cipher && !impl && keylen == 0) { - /* Not initialised */ - if (ctx->nlast_block == -1) - return 0; - if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) - return 0; - memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx)); - ctx->nlast_block = 0; - return 1; - } - /* Initialiase context */ - if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) - return 0; - /* Non-NULL key means initialisation complete */ - if (key) { - int bl; - if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) - return 0; - if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) - return 0; - if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) - return 0; - bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); - if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) - return 0; - make_kn(ctx->k1, ctx->tbl, bl); - make_kn(ctx->k2, ctx->k1, bl); - OPENSSL_cleanse(ctx->tbl, bl); - /* Reset context again ready for first data block */ - if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) - return 0; - /* Zero tbl so resume works */ - memset(ctx->tbl, 0, bl); - ctx->nlast_block = 0; - } - return 1; -} - -int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) -{ - const unsigned char *data = in; - size_t bl; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) - return FIPS_cmac_update(ctx, in, dlen); -#endif - if (ctx->nlast_block == -1) - return 0; - if (dlen == 0) - return 1; - bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); - /* Copy into partial block if we need to */ - if (ctx->nlast_block > 0) { - size_t nleft; - nleft = bl - ctx->nlast_block; - if (dlen < nleft) - nleft = dlen; - memcpy(ctx->last_block + ctx->nlast_block, data, nleft); - dlen -= nleft; - ctx->nlast_block += nleft; - /* If no more to process return */ - if (dlen == 0) - return 1; - data += nleft; - /* Else not final block so encrypt it */ - if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl)) - return 0; - } - /* Encrypt all but one of the complete blocks left */ - while (dlen > bl) { - if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl)) - return 0; - dlen -= bl; - data += bl; - } - /* Copy any data left to last block buffer */ - memcpy(ctx->last_block, data, dlen); - ctx->nlast_block = dlen; - return 1; - -} - -int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) -{ - int i, bl, lb; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->cctx.engine) - return FIPS_cmac_final(ctx, out, poutlen); -#endif - if (ctx->nlast_block == -1) - return 0; - bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); - *poutlen = (size_t)bl; - if (!out) - return 1; - lb = ctx->nlast_block; - /* Is last block complete? */ - if (lb == bl) { - for (i = 0; i < bl; i++) - out[i] = ctx->last_block[i] ^ ctx->k1[i]; - } else { - ctx->last_block[lb] = 0x80; - if (bl - lb > 1) - memset(ctx->last_block + lb + 1, 0, bl - lb - 1); - for (i = 0; i < bl; i++) - out[i] = ctx->last_block[i] ^ ctx->k2[i]; - } - if (!EVP_Cipher(&ctx->cctx, out, out, bl)) { - OPENSSL_cleanse(out, bl); - return 0; - } - return 1; -} - -int CMAC_resume(CMAC_CTX *ctx) -{ - if (ctx->nlast_block == -1) - return 0; - /* - * The buffer "tbl" containes the last fully encrypted block which is the - * last IV (or all zeroes if no last encrypted block). The last block has - * not been modified since CMAC_final(). So reinitliasing using the last - * decrypted block will allow CMAC to continue after calling - * CMAC_Final(). - */ - return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl); -} diff --git a/Sources/COpenSSL/cmac.h b/Sources/COpenSSL/cmac.h deleted file mode 100644 index 74b74bea..00000000 --- a/Sources/COpenSSL/cmac.h +++ /dev/null @@ -1,82 +0,0 @@ -/* crypto/cmac/cmac.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2010 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#ifndef HEADER_CMAC_H -# define HEADER_CMAC_H - -#ifdef __cplusplus -extern "C" { -#endif - -# include "evp.h" - -/* Opaque */ -typedef struct CMAC_CTX_st CMAC_CTX; - -CMAC_CTX *CMAC_CTX_new(void); -void CMAC_CTX_cleanup(CMAC_CTX *ctx); -void CMAC_CTX_free(CMAC_CTX *ctx); -EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); -int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); - -int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, - const EVP_CIPHER *cipher, ENGINE *impl); -int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); -int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); -int CMAC_resume(CMAC_CTX *ctx); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/cmll_.c b/Sources/COpenSSL/cmll_.c deleted file mode 100644 index 1479c311..00000000 --- a/Sources/COpenSSL/cmll_.c +++ /dev/null @@ -1,610 +0,0 @@ -/* crypto/camellia/camellia_cbc.c */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "camellia.h" -#include "modes.h" - -void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec, const int enc) -{ - - if (enc) - CRYPTO_cbc128_encrypt(in, out, len, key, ivec, - (block128_f) Camellia_encrypt); - else - CRYPTO_cbc128_decrypt(in, out, len, key, ivec, - (block128_f) Camellia_decrypt); -} -/* crypto/camellia/camellia_cfb.c */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "camellia.h" -// #include "modes.h" - -/* - * The input and output encrypted as though 128bit cfb mode is being used. - * The extra state information to record how much of the 128bit block we have - * used is contained in *num; - */ - -void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, int *num, const int enc) -{ - - CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) Camellia_encrypt); -} - -/* N.B. This expects the input to be packed, MS bit first */ -void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, int *num, const int enc) -{ - CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) Camellia_encrypt); -} - -void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, int *num, const int enc) -{ - CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, - (block128_f) Camellia_encrypt); -} -/* crypto/camellia/camellia_ctr.c */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "camellia.h" -// #include "modes.h" - -void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char ivec[CAMELLIA_BLOCK_SIZE], - unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], - unsigned int *num) -{ - - CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, - (block128_f) Camellia_encrypt); -} -/* crypto/camellia/camellia_ecb.c */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#ifndef CAMELLIA_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -// #include "camellia.h" -#include "cmll_locl.h" - -void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key, const int enc) -{ - - assert(in && out && key); - assert((CAMELLIA_ENCRYPT == enc) || (CAMELLIA_DECRYPT == enc)); - - if (CAMELLIA_ENCRYPT == enc) - Camellia_encrypt(in, out, key); - else - Camellia_decrypt(in, out, key); -} -/* crypto/camellia/camellia_misc.c */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "opensslv.h" -#include "crypto.h" -// #include "camellia.h" -// #include "cmll_locl.h" - -const char CAMELLIA_version[] = "CAMELLIA" OPENSSL_VERSION_PTEXT; - -int private_Camellia_set_key(const unsigned char *userKey, const int bits, - CAMELLIA_KEY *key) -{ - if (!userKey || !key) - return -1; - if (bits != 128 && bits != 192 && bits != 256) - return -2; - key->grand_rounds = Camellia_Ekeygen(bits, userKey, key->u.rd_key); - return 0; -} - -void Camellia_encrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key) -{ - Camellia_EncryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out); -} - -void Camellia_decrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key) -{ - Camellia_DecryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out); -} -/* crypto/camellia/camellia_ofb.c */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "camellia.h" -// #include "modes.h" - -/* - * The input and output encrypted as though 128bit ofb mode is being used. - * The extra state information to record how much of the 128bit block we have - * used is contained in *num; - */ -void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const CAMELLIA_KEY *key, - unsigned char *ivec, int *num) -{ - CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, - (block128_f) Camellia_encrypt); -} -/* crypto/camellia/cmll_utl.c */ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "opensslv.h" -// #include "crypto.h" -// #include "camellia.h" -// #include "cmll_locl.h" - -int Camellia_set_key(const unsigned char *userKey, const int bits, - CAMELLIA_KEY *key) -{ -#ifdef OPENSSL_FIPS - fips_cipher_abort(Camellia); -#endif - return private_Camellia_set_key(userKey, bits, key); -} diff --git a/Sources/COpenSSL/cmll_locl.h b/Sources/COpenSSL/cmll_locl.h deleted file mode 100644 index 2bd79b8c..00000000 --- a/Sources/COpenSSL/cmll_locl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* crypto/camellia/camellia_locl.h */ -/* ==================================================================== - * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . - * ALL RIGHTS RESERVED. - * - * Intellectual Property information for Camellia: - * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html - * - * News Release for Announcement of Camellia open source: - * http://www.ntt.co.jp/news/news06e/0604/060413a.html - * - * The Camellia Code included herein is developed by - * NTT (Nippon Telegraph and Telephone Corporation), and is contributed - * to the OpenSSL project. - * - * The Camellia Code is licensed pursuant to the OpenSSL open source - * license provided below. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#ifndef HEADER_CAMELLIA_LOCL_H -# define HEADER_CAMELLIA_LOCL_H - -typedef unsigned int u32; -typedef unsigned char u8; - -int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, - KEY_TABLE_TYPE keyTable); -void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], - const KEY_TABLE_TYPE keyTable, - u8 ciphertext[]); -void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], - const KEY_TABLE_TYPE keyTable, - u8 plaintext[]); -void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], - const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); -void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], - const KEY_TABLE_TYPE keyTable, u8 plaintext[]); -int private_Camellia_set_key(const unsigned char *userKey, const int bits, - CAMELLIA_KEY *key); -#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ diff --git a/Sources/COpenSSL/cms.h b/Sources/COpenSSL/cms.h deleted file mode 100644 index a098795c..00000000 --- a/Sources/COpenSSL/cms.h +++ /dev/null @@ -1,555 +0,0 @@ -/* crypto/cms/cms.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#ifndef HEADER_CMS_H -# define HEADER_CMS_H - -# include "x509.h" - -# ifdef OPENSSL_NO_CMS -# error CMS is disabled. -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct CMS_ContentInfo_st CMS_ContentInfo; -typedef struct CMS_SignerInfo_st CMS_SignerInfo; -typedef struct CMS_CertificateChoices CMS_CertificateChoices; -typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; -typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; -typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; -typedef struct CMS_Receipt_st CMS_Receipt; -typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; -typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; - -DECLARE_STACK_OF(CMS_SignerInfo) -DECLARE_STACK_OF(GENERAL_NAMES) -DECLARE_STACK_OF(CMS_RecipientEncryptedKey) -DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) -DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) -DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) - -# define CMS_SIGNERINFO_ISSUER_SERIAL 0 -# define CMS_SIGNERINFO_KEYIDENTIFIER 1 - -# define CMS_RECIPINFO_NONE -1 -# define CMS_RECIPINFO_TRANS 0 -# define CMS_RECIPINFO_AGREE 1 -# define CMS_RECIPINFO_KEK 2 -# define CMS_RECIPINFO_PASS 3 -# define CMS_RECIPINFO_OTHER 4 - -/* S/MIME related flags */ - -# define CMS_TEXT 0x1 -# define CMS_NOCERTS 0x2 -# define CMS_NO_CONTENT_VERIFY 0x4 -# define CMS_NO_ATTR_VERIFY 0x8 -# define CMS_NOSIGS \ - (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) -# define CMS_NOINTERN 0x10 -# define CMS_NO_SIGNER_CERT_VERIFY 0x20 -# define CMS_NOVERIFY 0x20 -# define CMS_DETACHED 0x40 -# define CMS_BINARY 0x80 -# define CMS_NOATTR 0x100 -# define CMS_NOSMIMECAP 0x200 -# define CMS_NOOLDMIMETYPE 0x400 -# define CMS_CRLFEOL 0x800 -# define CMS_STREAM 0x1000 -# define CMS_NOCRL 0x2000 -# define CMS_PARTIAL 0x4000 -# define CMS_REUSE_DIGEST 0x8000 -# define CMS_USE_KEYID 0x10000 -# define CMS_DEBUG_DECRYPT 0x20000 -# define CMS_KEY_PARAM 0x40000 - -const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); - -BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); -int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); - -ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); -int CMS_is_detached(CMS_ContentInfo *cms); -int CMS_set_detached(CMS_ContentInfo *cms, int detached); - -# ifdef HEADER_PEM_H -DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) -# endif -int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); -CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); -int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); - -BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); -int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); -int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, - int flags); -CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); -int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); - -int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, - unsigned int flags); - -CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, - STACK_OF(X509) *certs, BIO *data, - unsigned int flags); - -CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, - X509 *signcert, EVP_PKEY *pkey, - STACK_OF(X509) *certs, unsigned int flags); - -int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); -CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); - -int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, - unsigned int flags); -CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, - unsigned int flags); - -int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, - const unsigned char *key, size_t keylen, - BIO *dcont, BIO *out, unsigned int flags); - -CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, - const unsigned char *key, - size_t keylen, unsigned int flags); - -int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, - const unsigned char *key, size_t keylen); - -int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, - X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); - -int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, - STACK_OF(X509) *certs, - X509_STORE *store, unsigned int flags); - -STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); - -CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, - const EVP_CIPHER *cipher, unsigned int flags); - -int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, - BIO *dcont, BIO *out, unsigned int flags); - -int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); -int CMS_decrypt_set1_key(CMS_ContentInfo *cms, - unsigned char *key, size_t keylen, - unsigned char *id, size_t idlen); -int CMS_decrypt_set1_password(CMS_ContentInfo *cms, - unsigned char *pass, ossl_ssize_t passlen); - -STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); -int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); -EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri); -CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); -CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, - X509 *recip, unsigned int flags); -int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); -int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); -int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, - EVP_PKEY **pk, X509 **recip, - X509_ALGOR **palg); -int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, - ASN1_INTEGER **sno); - -CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, - unsigned char *key, size_t keylen, - unsigned char *id, size_t idlen, - ASN1_GENERALIZEDTIME *date, - ASN1_OBJECT *otherTypeId, - ASN1_TYPE *otherType); - -int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, - X509_ALGOR **palg, - ASN1_OCTET_STRING **pid, - ASN1_GENERALIZEDTIME **pdate, - ASN1_OBJECT **potherid, - ASN1_TYPE **pothertype); - -int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, - unsigned char *key, size_t keylen); - -int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, - const unsigned char *id, size_t idlen); - -int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, - unsigned char *pass, - ossl_ssize_t passlen); - -CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, - int iter, int wrap_nid, - int pbe_nid, - unsigned char *pass, - ossl_ssize_t passlen, - const EVP_CIPHER *kekciph); - -int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); -int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); - -int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, - unsigned int flags); -CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); - -int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); -const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); - -CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); -int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); -int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); -STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); - -CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); -int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); -int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); -STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); - -int CMS_SignedData_init(CMS_ContentInfo *cms); -CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, - X509 *signer, EVP_PKEY *pk, const EVP_MD *md, - unsigned int flags); -EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si); -EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); -STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); - -void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); -int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, ASN1_INTEGER **sno); -int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); -int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, - unsigned int flags); -void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, - X509 **signer, X509_ALGOR **pdig, - X509_ALGOR **psig); -ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); -int CMS_SignerInfo_sign(CMS_SignerInfo *si); -int CMS_SignerInfo_verify(CMS_SignerInfo *si); -int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); - -int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); -int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, - int algnid, int keysize); -int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); - -int CMS_signed_get_attr_count(const CMS_SignerInfo *si); -int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, - int lastpos); -int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, - int lastpos); -X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); -X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); -int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); -int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, - const ASN1_OBJECT *obj, int type, - const void *bytes, int len); -int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, - int nid, int type, - const void *bytes, int len); -int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, - const char *attrname, int type, - const void *bytes, int len); -void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, - int lastpos, int type); - -int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); -int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, - int lastpos); -int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, - int lastpos); -X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); -X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); -int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); -int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, - const ASN1_OBJECT *obj, int type, - const void *bytes, int len); -int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, - int nid, int type, - const void *bytes, int len); -int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, - const char *attrname, int type, - const void *bytes, int len); -void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, - int lastpos, int type); - -# ifdef HEADER_X509V3_H - -int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); -CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, - int allorfirst, - STACK_OF(GENERAL_NAMES) - *receiptList, STACK_OF(GENERAL_NAMES) - *receiptsTo); -int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); -void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, - ASN1_STRING **pcid, - int *pallorfirst, - STACK_OF(GENERAL_NAMES) **plist, - STACK_OF(GENERAL_NAMES) **prto); -# endif -int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, - X509_ALGOR **palg, - ASN1_OCTET_STRING **pukm); -STACK_OF(CMS_RecipientEncryptedKey) -*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri); - -int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, - X509_ALGOR **pubalg, - ASN1_BIT_STRING **pubkey, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, - ASN1_INTEGER **sno); - -int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert); - -int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, - ASN1_OCTET_STRING **keyid, - ASN1_GENERALIZEDTIME **tm, - CMS_OtherKeyAttribute **other, - X509_NAME **issuer, ASN1_INTEGER **sno); -int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, - X509 *cert); -int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk); -EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri); -int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri, - CMS_RecipientEncryptedKey *rek); - -int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, - ASN1_OCTET_STRING *ukm, int keylen); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_CMS_strings(void); - -/* Error codes for the CMS functions. */ - -/* Function codes. */ -# define CMS_F_CHECK_CONTENT 99 -# define CMS_F_CMS_ADD0_CERT 164 -# define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 -# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 -# define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 -# define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 -# define CMS_F_CMS_ADD1_SIGNER 102 -# define CMS_F_CMS_ADD1_SIGNINGTIME 103 -# define CMS_F_CMS_COMPRESS 104 -# define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 -# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 -# define CMS_F_CMS_COPY_CONTENT 107 -# define CMS_F_CMS_COPY_MESSAGEDIGEST 108 -# define CMS_F_CMS_DATA 109 -# define CMS_F_CMS_DATAFINAL 110 -# define CMS_F_CMS_DATAINIT 111 -# define CMS_F_CMS_DECRYPT 112 -# define CMS_F_CMS_DECRYPT_SET1_KEY 113 -# define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 -# define CMS_F_CMS_DECRYPT_SET1_PKEY 114 -# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 -# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 -# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 -# define CMS_F_CMS_DIGEST_VERIFY 118 -# define CMS_F_CMS_ENCODE_RECEIPT 161 -# define CMS_F_CMS_ENCRYPT 119 -# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 -# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 -# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 -# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 -# define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 -# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 -# define CMS_F_CMS_ENVELOPED_DATA_INIT 126 -# define CMS_F_CMS_ENV_ASN1_CTRL 171 -# define CMS_F_CMS_FINAL 127 -# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 -# define CMS_F_CMS_GET0_CONTENT 129 -# define CMS_F_CMS_GET0_ECONTENT_TYPE 130 -# define CMS_F_CMS_GET0_ENVELOPED 131 -# define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 -# define CMS_F_CMS_GET0_SIGNED 133 -# define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 -# define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 -# define CMS_F_CMS_RECEIPT_VERIFY 160 -# define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 -# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT 169 -# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT 178 -# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG 175 -# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID 173 -# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS 172 -# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP 174 -# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 -# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 -# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 -# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 -# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 -# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 -# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 -# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 -# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 -# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 -# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 -# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 -# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 -# define CMS_F_CMS_SD_ASN1_CTRL 170 -# define CMS_F_CMS_SET1_IAS 176 -# define CMS_F_CMS_SET1_KEYID 177 -# define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 -# define CMS_F_CMS_SET_DETACHED 147 -# define CMS_F_CMS_SIGN 148 -# define CMS_F_CMS_SIGNED_DATA_INIT 149 -# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 -# define CMS_F_CMS_SIGNERINFO_SIGN 151 -# define CMS_F_CMS_SIGNERINFO_VERIFY 152 -# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 -# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 -# define CMS_F_CMS_SIGN_RECEIPT 163 -# define CMS_F_CMS_STREAM 155 -# define CMS_F_CMS_UNCOMPRESS 156 -# define CMS_F_CMS_VERIFY 157 - -/* Reason codes. */ -# define CMS_R_ADD_SIGNER_ERROR 99 -# define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 -# define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 -# define CMS_R_CERTIFICATE_VERIFY_ERROR 100 -# define CMS_R_CIPHER_INITIALISATION_ERROR 101 -# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 -# define CMS_R_CMS_DATAFINAL_ERROR 103 -# define CMS_R_CMS_LIB 104 -# define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 -# define CMS_R_CONTENT_NOT_FOUND 105 -# define CMS_R_CONTENT_TYPE_MISMATCH 171 -# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 -# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 -# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 -# define CMS_R_CONTENT_VERIFY_ERROR 109 -# define CMS_R_CTRL_ERROR 110 -# define CMS_R_CTRL_FAILURE 111 -# define CMS_R_DECRYPT_ERROR 112 -# define CMS_R_DIGEST_ERROR 161 -# define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 -# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 -# define CMS_R_ERROR_SETTING_KEY 115 -# define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 -# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 -# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 -# define CMS_R_INVALID_KEY_LENGTH 118 -# define CMS_R_MD_BIO_INIT_ERROR 119 -# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 -# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 -# define CMS_R_MSGSIGDIGEST_ERROR 172 -# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 -# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 -# define CMS_R_NEED_ONE_SIGNER 164 -# define CMS_R_NOT_A_SIGNED_RECEIPT 165 -# define CMS_R_NOT_ENCRYPTED_DATA 122 -# define CMS_R_NOT_KEK 123 -# define CMS_R_NOT_KEY_AGREEMENT 181 -# define CMS_R_NOT_KEY_TRANSPORT 124 -# define CMS_R_NOT_PWRI 177 -# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 -# define CMS_R_NO_CIPHER 126 -# define CMS_R_NO_CONTENT 127 -# define CMS_R_NO_CONTENT_TYPE 173 -# define CMS_R_NO_DEFAULT_DIGEST 128 -# define CMS_R_NO_DIGEST_SET 129 -# define CMS_R_NO_KEY 130 -# define CMS_R_NO_KEY_OR_CERT 174 -# define CMS_R_NO_MATCHING_DIGEST 131 -# define CMS_R_NO_MATCHING_RECIPIENT 132 -# define CMS_R_NO_MATCHING_SIGNATURE 166 -# define CMS_R_NO_MSGSIGDIGEST 167 -# define CMS_R_NO_PASSWORD 178 -# define CMS_R_NO_PRIVATE_KEY 133 -# define CMS_R_NO_PUBLIC_KEY 134 -# define CMS_R_NO_RECEIPT_REQUEST 168 -# define CMS_R_NO_SIGNERS 135 -# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 -# define CMS_R_RECEIPT_DECODE_ERROR 169 -# define CMS_R_RECIPIENT_ERROR 137 -# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 -# define CMS_R_SIGNFINAL_ERROR 139 -# define CMS_R_SMIME_TEXT_ERROR 140 -# define CMS_R_STORE_INIT_ERROR 141 -# define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 -# define CMS_R_TYPE_NOT_DATA 143 -# define CMS_R_TYPE_NOT_DIGESTED_DATA 144 -# define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 -# define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 -# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 -# define CMS_R_UNKNOWN_CIPHER 148 -# define CMS_R_UNKNOWN_DIGEST_ALGORIHM 149 -# define CMS_R_UNKNOWN_ID 150 -# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 -# define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 -# define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 -# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 -# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 -# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE 155 -# define CMS_R_UNSUPPORTED_TYPE 156 -# define CMS_R_UNWRAP_ERROR 157 -# define CMS_R_UNWRAP_FAILURE 180 -# define CMS_R_VERIFICATION_FAILURE 158 -# define CMS_R_WRAP_ERROR 159 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/cms_.c b/Sources/COpenSSL/cms_.c deleted file mode 100644 index bd1bc961..00000000 --- a/Sources/COpenSSL/cms_.c +++ /dev/null @@ -1,6362 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/cms/cms_asn1.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "asn1t.h" -#include "pem.h" -#include "x509v3.h" -#include "cms.h" -#include "cms_lcl.h" - - -ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = { - ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME), - ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER) -} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber) - -ASN1_SEQUENCE(CMS_OtherCertificateFormat) = { - ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT), - ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY) -} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat) - -ASN1_CHOICE(CMS_CertificateChoices) = { - ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509), - ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0), - ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1), - ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2), - ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3) -} ASN1_CHOICE_END(CMS_CertificateChoices) - -ASN1_CHOICE(CMS_SignerIdentifier) = { - ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), - ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0) -} ASN1_CHOICE_END(CMS_SignerIdentifier) - -ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = { - ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT), - ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0) -} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo) - -/* Minor tweak to operation: free up signer key, cert */ -static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_FREE_POST) { - CMS_SignerInfo *si = (CMS_SignerInfo *)*pval; - if (si->pkey) - EVP_PKEY_free(si->pkey); - if (si->signer) - X509_free(si->signer); - if (si->pctx) - EVP_MD_CTX_cleanup(&si->mctx); - } - return 1; -} - -ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = { - ASN1_SIMPLE(CMS_SignerInfo, version, LONG), - ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier), - ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR), - ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0), - ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR), - ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING), - ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1) -} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo) - -ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = { - ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT), - ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY) -} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat) - -ASN1_CHOICE(CMS_RevocationInfoChoice) = { - ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL), - ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1) -} ASN1_CHOICE_END(CMS_RevocationInfoChoice) - -ASN1_NDEF_SEQUENCE(CMS_SignedData) = { - ASN1_SIMPLE(CMS_SignedData, version, LONG), - ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR), - ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo), - ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0), - ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1), - ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo) -} ASN1_NDEF_SEQUENCE_END(CMS_SignedData) - -ASN1_SEQUENCE(CMS_OriginatorInfo) = { - ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0), - ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1) -} ASN1_SEQUENCE_END(CMS_OriginatorInfo) - -ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { - ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT), - ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR), - ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0) -} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo) - -ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = { - ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG), - ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier), - ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), - ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo) - -ASN1_SEQUENCE(CMS_OtherKeyAttribute) = { - ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT), - ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY) -} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute) - -ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = { - ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING), - ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME), - ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute) -} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier) - -ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = { - ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), - ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0) -} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier) - -static int cms_rek_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - CMS_RecipientEncryptedKey *rek = (CMS_RecipientEncryptedKey *)*pval; - if (operation == ASN1_OP_FREE_POST) { - if (rek->pkey) - EVP_PKEY_free(rek->pkey); - } - return 1; -} - -ASN1_SEQUENCE_cb(CMS_RecipientEncryptedKey, cms_rek_cb) = { - ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier), - ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END_cb(CMS_RecipientEncryptedKey, CMS_RecipientEncryptedKey) - -ASN1_SEQUENCE(CMS_OriginatorPublicKey) = { - ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR), - ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey) - -ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = { - ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), - ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0), - ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1) -} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey) - -static int cms_kari_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - CMS_KeyAgreeRecipientInfo *kari = (CMS_KeyAgreeRecipientInfo *)*pval; - if (operation == ASN1_OP_NEW_POST) { - EVP_CIPHER_CTX_init(&kari->ctx); - EVP_CIPHER_CTX_set_flags(&kari->ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); - kari->pctx = NULL; - } else if (operation == ASN1_OP_FREE_POST) { - if (kari->pctx) - EVP_PKEY_CTX_free(kari->pctx); - EVP_CIPHER_CTX_cleanup(&kari->ctx); - } - return 1; -} - -ASN1_SEQUENCE_cb(CMS_KeyAgreeRecipientInfo, cms_kari_cb) = { - ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG), - ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0), - ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1), - ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), - ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey) -} ASN1_SEQUENCE_END_cb(CMS_KeyAgreeRecipientInfo, CMS_KeyAgreeRecipientInfo) - -ASN1_SEQUENCE(CMS_KEKIdentifier) = { - ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING), - ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME), - ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute) -} ASN1_SEQUENCE_END(CMS_KEKIdentifier) - -ASN1_SEQUENCE(CMS_KEKRecipientInfo) = { - ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG), - ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier), - ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), - ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo) - -ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = { - ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG), - ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0), - ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), - ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo) - -ASN1_SEQUENCE(CMS_OtherRecipientInfo) = { - ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT), - ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY) -} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo) - -/* Free up RecipientInfo additional data */ -static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_FREE_PRE) { - CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval; - if (ri->type == CMS_RECIPINFO_TRANS) { - CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; - if (ktri->pkey) - EVP_PKEY_free(ktri->pkey); - if (ktri->recip) - X509_free(ktri->recip); - if (ktri->pctx) - EVP_PKEY_CTX_free(ktri->pctx); - } else if (ri->type == CMS_RECIPINFO_KEK) { - CMS_KEKRecipientInfo *kekri = ri->d.kekri; - if (kekri->key) { - OPENSSL_cleanse(kekri->key, kekri->keylen); - OPENSSL_free(kekri->key); - } - } else if (ri->type == CMS_RECIPINFO_PASS) { - CMS_PasswordRecipientInfo *pwri = ri->d.pwri; - if (pwri->pass) { - OPENSSL_cleanse(pwri->pass, pwri->passlen); - OPENSSL_free(pwri->pass); - } - } - } - return 1; -} - -ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = { - ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo), - ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1), - ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2), - ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3), - ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4) -} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type) - -ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = { - ASN1_SIMPLE(CMS_EnvelopedData, version, LONG), - ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0), - ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo), - ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo), - ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1) -} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData) - -ASN1_NDEF_SEQUENCE(CMS_DigestedData) = { - ASN1_SIMPLE(CMS_DigestedData, version, LONG), - ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR), - ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo), - ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING) -} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData) - -ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = { - ASN1_SIMPLE(CMS_EncryptedData, version, LONG), - ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo), - ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1) -} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData) - -ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = { - ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG), - ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0), - ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo), - ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR), - ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1), - ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo), - ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2), - ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING), - ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3) -} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData) - -ASN1_NDEF_SEQUENCE(CMS_CompressedData) = { - ASN1_SIMPLE(CMS_CompressedData, version, LONG), - ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR), - ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo), -} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData) - -/* This is the ANY DEFINED BY table for the top level ContentInfo structure */ - -ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0); - -ASN1_ADB(CMS_ContentInfo) = { - ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)), - ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)), - ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)), - ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)), - ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)), - ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)), - ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), -} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); - -/* CMS streaming support */ -static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - ASN1_STREAM_ARG *sarg = exarg; - CMS_ContentInfo *cms = NULL; - if (pval) - cms = (CMS_ContentInfo *)*pval; - else - return 1; - switch (operation) { - - case ASN1_OP_STREAM_PRE: - if (CMS_stream(&sarg->boundary, cms) <= 0) - return 0; - case ASN1_OP_DETACHED_PRE: - sarg->ndef_bio = CMS_dataInit(cms, sarg->out); - if (!sarg->ndef_bio) - return 0; - break; - - case ASN1_OP_STREAM_POST: - case ASN1_OP_DETACHED_POST: - if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0) - return 0; - break; - - } - return 1; -} - -ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = { - ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT), - ASN1_ADB_OBJECT(CMS_ContentInfo) -} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo) - -/* Specials for signed attributes */ - -/* - * When signing attributes we want to reorder them to match the sorted - * encoding. - */ - -ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE) -ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign) - -/* - * When verifying attributes we need to use the received order. So we use - * SEQUENCE OF and tag it to SET OF - */ - -ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, - V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE) -ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify) - - - -ASN1_CHOICE(CMS_ReceiptsFrom) = { - ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0), - ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1) -} ASN1_CHOICE_END(CMS_ReceiptsFrom) - -ASN1_SEQUENCE(CMS_ReceiptRequest) = { - ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING), - ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom), - ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES) -} ASN1_SEQUENCE_END(CMS_ReceiptRequest) - -ASN1_SEQUENCE(CMS_Receipt) = { - ASN1_SIMPLE(CMS_Receipt, version, LONG), - ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT), - ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING), - ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(CMS_Receipt) - -/* - * Utilities to encode the CMS_SharedInfo structure used during key - * derivation. - */ - -typedef struct { - X509_ALGOR *keyInfo; - ASN1_OCTET_STRING *entityUInfo; - ASN1_OCTET_STRING *suppPubInfo; -} CMS_SharedInfo; - -ASN1_SEQUENCE(CMS_SharedInfo) = { - ASN1_SIMPLE(CMS_SharedInfo, keyInfo, X509_ALGOR), - ASN1_EXP_OPT(CMS_SharedInfo, entityUInfo, ASN1_OCTET_STRING, 0), - ASN1_EXP_OPT(CMS_SharedInfo, suppPubInfo, ASN1_OCTET_STRING, 2), -} ASN1_SEQUENCE_END(CMS_SharedInfo) - -int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg, - ASN1_OCTET_STRING *ukm, int keylen) -{ - union { - CMS_SharedInfo *pecsi; - ASN1_VALUE *a; - } intsi = { - NULL - }; - - ASN1_OCTET_STRING oklen; - unsigned char kl[4]; - CMS_SharedInfo ecsi; - - keylen <<= 3; - kl[0] = (keylen >> 24) & 0xff; - kl[1] = (keylen >> 16) & 0xff; - kl[2] = (keylen >> 8) & 0xff; - kl[3] = keylen & 0xff; - oklen.length = 4; - oklen.data = kl; - oklen.type = V_ASN1_OCTET_STRING; - oklen.flags = 0; - ecsi.keyInfo = kekalg; - ecsi.entityUInfo = ukm; - ecsi.suppPubInfo = &oklen; - intsi.pecsi = &ecsi; - return ASN1_item_i2d(intsi.a, pder, ASN1_ITEM_rptr(CMS_SharedInfo)); -} -/* crypto/cms/cms_att.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "asn1t.h" -// #include "pem.h" -// #include "x509v3.h" -#include "err.h" -// #include "cms.h" -// #include "cms_lcl.h" - -/* CMS SignedData Attribute utilities */ - -int CMS_signed_get_attr_count(const CMS_SignerInfo *si) -{ - return X509at_get_attr_count(si->signedAttrs); -} - -int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos) -{ - return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos); -} - -int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, - int lastpos) -{ - return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos); -} - -X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc) -{ - return X509at_get_attr(si->signedAttrs, loc); -} - -X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc) -{ - return X509at_delete_attr(si->signedAttrs, loc); -} - -int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) -{ - if (X509at_add1_attr(&si->signedAttrs, attr)) - return 1; - return 0; -} - -int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, - const ASN1_OBJECT *obj, int type, - const void *bytes, int len) -{ - if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len)) - return 1; - return 0; -} - -int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, - int nid, int type, const void *bytes, int len) -{ - if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len)) - return 1; - return 0; -} - -int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, - const char *attrname, int type, - const void *bytes, int len) -{ - if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len)) - return 1; - return 0; -} - -void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, - int lastpos, int type) -{ - return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type); -} - -int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si) -{ - return X509at_get_attr_count(si->unsignedAttrs); -} - -int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, - int lastpos) -{ - return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos); -} - -int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, - int lastpos) -{ - return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos); -} - -X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc) -{ - return X509at_get_attr(si->unsignedAttrs, loc); -} - -X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc) -{ - return X509at_delete_attr(si->unsignedAttrs, loc); -} - -int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) -{ - if (X509at_add1_attr(&si->unsignedAttrs, attr)) - return 1; - return 0; -} - -int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, - const ASN1_OBJECT *obj, int type, - const void *bytes, int len) -{ - if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len)) - return 1; - return 0; -} - -int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, - int nid, int type, - const void *bytes, int len) -{ - if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len)) - return 1; - return 0; -} - -int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, - const char *attrname, int type, - const void *bytes, int len) -{ - if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname, - type, bytes, len)) - return 1; - return 0; -} - -void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, - int lastpos, int type) -{ - return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type); -} - -/* Specific attribute cases */ -/* crypto/cms/cms_cd.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "cryptlib.h" -// #include "asn1t.h" -// #include "pem.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -#include "bio.h" -#ifndef OPENSSL_NO_COMP -# include "comp.h" -#endif -// #include "cms_lcl.h" - -DECLARE_ASN1_ITEM(CMS_CompressedData) - -#ifdef ZLIB - -/* CMS CompressedData Utilities */ - -CMS_ContentInfo *cms_CompressedData_create(int comp_nid) -{ - CMS_ContentInfo *cms; - CMS_CompressedData *cd; - /* - * Will need something cleverer if there is ever more than one - * compression algorithm or parameters have some meaning... - */ - if (comp_nid != NID_zlib_compression) { - CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE, - CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); - return NULL; - } - cms = CMS_ContentInfo_new(); - if (!cms) - return NULL; - - cd = M_ASN1_new_of(CMS_CompressedData); - - if (!cd) - goto err; - - cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData); - cms->d.compressedData = cd; - - cd->version = 0; - - X509_ALGOR_set0(cd->compressionAlgorithm, - OBJ_nid2obj(NID_zlib_compression), V_ASN1_UNDEF, NULL); - - cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); - - return cms; - - err: - - if (cms) - CMS_ContentInfo_free(cms); - - return NULL; -} - -BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms) -{ - CMS_CompressedData *cd; - ASN1_OBJECT *compoid; - if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) { - CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, - CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA); - return NULL; - } - cd = cms->d.compressedData; - X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm); - if (OBJ_obj2nid(compoid) != NID_zlib_compression) { - CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, - CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); - return NULL; - } - return BIO_new(BIO_f_zlib()); -} - -#endif -/* crypto/cms/cms_dd.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "pem.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -// #include "cms_lcl.h" - -DECLARE_ASN1_ITEM(CMS_DigestedData) - -/* CMS DigestedData Utilities */ - -CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md) -{ - CMS_ContentInfo *cms; - CMS_DigestedData *dd; - cms = CMS_ContentInfo_new(); - if (!cms) - return NULL; - - dd = M_ASN1_new_of(CMS_DigestedData); - - if (!dd) - goto err; - - cms->contentType = OBJ_nid2obj(NID_pkcs7_digest); - cms->d.digestedData = dd; - - dd->version = 0; - dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); - - cms_DigestAlgorithm_set(dd->digestAlgorithm, md); - - return cms; - - err: - - if (cms) - CMS_ContentInfo_free(cms); - - return NULL; -} - -BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms) -{ - CMS_DigestedData *dd; - dd = cms->d.digestedData; - return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm); -} - -int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify) -{ - EVP_MD_CTX mctx; - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int mdlen; - int r = 0; - CMS_DigestedData *dd; - EVP_MD_CTX_init(&mctx); - - dd = cms->d.digestedData; - - if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm)) - goto err; - - if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0) - goto err; - - if (verify) { - if (mdlen != (unsigned int)dd->digest->length) { - CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, - CMS_R_MESSAGEDIGEST_WRONG_LENGTH); - goto err; - } - - if (memcmp(md, dd->digest->data, mdlen)) - CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, - CMS_R_VERIFICATION_FAILURE); - else - r = 1; - } else { - if (!ASN1_STRING_set(dd->digest, md, mdlen)) - goto err; - r = 1; - } - - err: - EVP_MD_CTX_cleanup(&mctx); - - return r; - -} -/* crypto/cms/cms_enc.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "pem.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -#include "rand.h" -// #include "cms_lcl.h" - -/* CMS EncryptedData Utilities */ - -DECLARE_ASN1_ITEM(CMS_EncryptedData) - -/* Return BIO based on EncryptedContentInfo and key */ - -BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) -{ - BIO *b; - EVP_CIPHER_CTX *ctx; - const EVP_CIPHER *ciph; - X509_ALGOR *calg = ec->contentEncryptionAlgorithm; - unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; - unsigned char *tkey = NULL; - size_t tkeylen = 0; - - int ok = 0; - - int enc, keep_key = 0; - - enc = ec->cipher ? 1 : 0; - - b = BIO_new(BIO_f_cipher()); - if (!b) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); - return NULL; - } - - BIO_get_cipher_ctx(b, &ctx); - - if (enc) { - ciph = ec->cipher; - /* - * If not keeping key set cipher to NULL so subsequent calls decrypt. - */ - if (ec->key) - ec->cipher = NULL; - } else { - ciph = EVP_get_cipherbyobj(calg->algorithm); - - if (!ciph) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); - goto err; - } - } - - if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_INITIALISATION_ERROR); - goto err; - } - - if (enc) { - int ivlen; - calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); - /* Generate a random IV if we need one */ - ivlen = EVP_CIPHER_CTX_iv_length(ctx); - if (ivlen > 0) { - if (RAND_bytes(iv, ivlen) <= 0) - goto err; - piv = iv; - } - } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); - goto err; - } - tkeylen = EVP_CIPHER_CTX_key_length(ctx); - /* Generate random session key */ - if (!enc || !ec->key) { - tkey = OPENSSL_malloc(tkeylen); - if (!tkey) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) - goto err; - } - - if (!ec->key) { - ec->key = tkey; - ec->keylen = tkeylen; - tkey = NULL; - if (enc) - keep_key = 1; - else - ERR_clear_error(); - - } - - if (ec->keylen != tkeylen) { - /* If necessary set key length */ - if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { - /* - * Only reveal failure if debugging so we don't leak information - * which may be useful in MMA. - */ - if (enc || ec->debug) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_INVALID_KEY_LENGTH); - goto err; - } else { - /* Use random key */ - OPENSSL_cleanse(ec->key, ec->keylen); - OPENSSL_free(ec->key); - ec->key = tkey; - ec->keylen = tkeylen; - tkey = NULL; - ERR_clear_error(); - } - } - } - - if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_INITIALISATION_ERROR); - goto err; - } - if (enc) { - calg->parameter = ASN1_TYPE_new(); - if (calg->parameter == NULL) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { - CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); - goto err; - } - /* If parameter type not set omit parameter */ - if (calg->parameter->type == V_ASN1_UNDEF) { - ASN1_TYPE_free(calg->parameter); - calg->parameter = NULL; - } - } - ok = 1; - - err: - if (ec->key && (!keep_key || !ok)) { - OPENSSL_cleanse(ec->key, ec->keylen); - OPENSSL_free(ec->key); - ec->key = NULL; - } - if (tkey) { - OPENSSL_cleanse(tkey, tkeylen); - OPENSSL_free(tkey); - } - if (ok) - return b; - BIO_free(b); - return NULL; -} - -int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, - const EVP_CIPHER *cipher, - const unsigned char *key, size_t keylen) -{ - ec->cipher = cipher; - if (key) { - ec->key = OPENSSL_malloc(keylen); - if (!ec->key) - return 0; - memcpy(ec->key, key, keylen); - } - ec->keylen = keylen; - if (cipher) - ec->contentType = OBJ_nid2obj(NID_pkcs7_data); - return 1; -} - -int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, - const unsigned char *key, size_t keylen) -{ - CMS_EncryptedContentInfo *ec; - if (!key || !keylen) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY); - return 0; - } - if (ciph) { - cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData); - if (!cms->d.encryptedData) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE); - return 0; - } - cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); - cms->d.encryptedData->version = 0; - } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA); - return 0; - } - ec = cms->d.encryptedData->encryptedContentInfo; - return cms_EncryptedContent_init(ec, ciph, key, keylen); -} - -BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) -{ - CMS_EncryptedData *enc = cms->d.encryptedData; - if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) - enc->version = 2; - return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); -} -/* crypto/cms/cms_env.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "pem.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -// #include "rand.h" -#include "aes.h" -// #include "cms_lcl.h" -#include "asn1_locl.h" - -/* CMS EnvelopedData Utilities */ - -DECLARE_ASN1_ITEM(CMS_EnvelopedData) -DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) -DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) -DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) - -DECLARE_STACK_OF(CMS_RecipientInfo) - -CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) -{ - if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { - CMSerr(CMS_F_CMS_GET0_ENVELOPED, - CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); - return NULL; - } - return cms->d.envelopedData; -} - -static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) -{ - if (cms->d.other == NULL) { - cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); - if (!cms->d.envelopedData) { - CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE); - return NULL; - } - cms->d.envelopedData->version = 0; - cms->d.envelopedData->encryptedContentInfo->contentType = - OBJ_nid2obj(NID_pkcs7_data); - ASN1_OBJECT_free(cms->contentType); - cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); - return cms->d.envelopedData; - } - return cms_get0_enveloped(cms); -} - -int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd) -{ - EVP_PKEY *pkey; - int i; - if (ri->type == CMS_RECIPINFO_TRANS) - pkey = ri->d.ktri->pkey; - else if (ri->type == CMS_RECIPINFO_AGREE) { - EVP_PKEY_CTX *pctx = ri->d.kari->pctx; - if (!pctx) - return 0; - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!pkey) - return 0; - } else - return 0; - if (!pkey->ameth || !pkey->ameth->pkey_ctrl) - return 1; - i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri); - if (i == -2) { - CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - return 0; - } - if (i <= 0) { - CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE); - return 0; - } - return 1; -} - -STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) -{ - CMS_EnvelopedData *env; - env = cms_get0_enveloped(cms); - if (!env) - return NULL; - return env->recipientInfos; -} - -int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) -{ - return ri->type; -} - -EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri) -{ - if (ri->type == CMS_RECIPINFO_TRANS) - return ri->d.ktri->pctx; - else if (ri->type == CMS_RECIPINFO_AGREE) - return ri->d.kari->pctx; - return NULL; -} - -CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) -{ - CMS_ContentInfo *cms; - CMS_EnvelopedData *env; - cms = CMS_ContentInfo_new(); - if (!cms) - goto merr; - env = cms_enveloped_data_init(cms); - if (!env) - goto merr; - if (!cms_EncryptedContent_init(env->encryptedContentInfo, - cipher, NULL, 0)) - goto merr; - return cms; - merr: - if (cms) - CMS_ContentInfo_free(cms); - CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); - return NULL; -} - -/* Key Transport Recipient Info (KTRI) routines */ - -/* Initialise a ktri based on passed certificate and key */ - -static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip, - EVP_PKEY *pk, unsigned int flags) -{ - CMS_KeyTransRecipientInfo *ktri; - int idtype; - - ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); - if (!ri->d.ktri) - return 0; - ri->type = CMS_RECIPINFO_TRANS; - - ktri = ri->d.ktri; - - if (flags & CMS_USE_KEYID) { - ktri->version = 2; - idtype = CMS_RECIPINFO_KEYIDENTIFIER; - } else { - ktri->version = 0; - idtype = CMS_RECIPINFO_ISSUER_SERIAL; - } - - /* - * Not a typo: RecipientIdentifier and SignerIdentifier are the same - * structure. - */ - - if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype)) - return 0; - - CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); - CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); - ktri->pkey = pk; - ktri->recip = recip; - - if (flags & CMS_KEY_PARAM) { - ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); - if (!ktri->pctx) - return 0; - if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0) - return 0; - } else if (!cms_env_asn1_ctrl(ri, 0)) - return 0; - return 1; -} - -/* - * Add a recipient certificate using appropriate type of RecipientInfo - */ - -CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, - X509 *recip, unsigned int flags) -{ - CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; - EVP_PKEY *pk = NULL; - env = cms_get0_enveloped(cms); - if (!env) - goto err; - - /* Initialize recipient info */ - ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) - goto merr; - - pk = X509_get_pubkey(recip); - if (!pk) { - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY); - goto err; - } - - switch (cms_pkey_get_ri_type(pk)) { - - case CMS_RECIPINFO_TRANS: - if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags)) - goto err; - break; - - case CMS_RECIPINFO_AGREE: - if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags)) - goto err; - break; - - default: - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; - - } - - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) - goto merr; - - EVP_PKEY_free(pk); - - return ri; - - merr: - CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); - err: - if (ri) - M_ASN1_free_of(ri, CMS_RecipientInfo); - if (pk) - EVP_PKEY_free(pk); - return NULL; - -} - -int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, - EVP_PKEY **pk, X509 **recip, - X509_ALGOR **palg) -{ - CMS_KeyTransRecipientInfo *ktri; - if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, - CMS_R_NOT_KEY_TRANSPORT); - return 0; - } - - ktri = ri->d.ktri; - - if (pk) - *pk = ktri->pkey; - if (recip) - *recip = ktri->recip; - if (palg) - *palg = ktri->keyEncryptionAlgorithm; - return 1; -} - -int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, - ASN1_INTEGER **sno) -{ - CMS_KeyTransRecipientInfo *ktri; - if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, - CMS_R_NOT_KEY_TRANSPORT); - return 0; - } - ktri = ri->d.ktri; - - return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno); -} - -int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) -{ - if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, - CMS_R_NOT_KEY_TRANSPORT); - return -2; - } - return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); -} - -int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) -{ - if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT); - return 0; - } - ri->d.ktri->pkey = pkey; - return 1; -} - -/* Encrypt content key in key transport recipient info */ - -static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) -{ - CMS_KeyTransRecipientInfo *ktri; - CMS_EncryptedContentInfo *ec; - EVP_PKEY_CTX *pctx; - unsigned char *ek = NULL; - size_t eklen; - - int ret = 0; - - if (ri->type != CMS_RECIPINFO_TRANS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT); - return 0; - } - ktri = ri->d.ktri; - ec = cms->d.envelopedData->encryptedContentInfo; - - pctx = ktri->pctx; - - if (pctx) { - if (!cms_env_asn1_ctrl(ri, 0)) - goto err; - } else { - pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); - if (!pctx) - return 0; - - if (EVP_PKEY_encrypt_init(pctx) <= 0) - goto err; - } - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); - goto err; - } - - if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) - goto err; - - ek = OPENSSL_malloc(eklen); - - if (ek == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) - goto err; - - ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); - ek = NULL; - - ret = 1; - - err: - if (pctx) { - EVP_PKEY_CTX_free(pctx); - ktri->pctx = NULL; - } - if (ek) - OPENSSL_free(ek); - return ret; - -} - -/* Decrypt content key from KTRI */ - -static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) -{ - CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; - EVP_PKEY *pkey = ktri->pkey; - unsigned char *ek = NULL; - size_t eklen; - int ret = 0; - CMS_EncryptedContentInfo *ec; - ec = cms->d.envelopedData->encryptedContentInfo; - - if (ktri->pkey == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY); - return 0; - } - - ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!ktri->pctx) - return 0; - - if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0) - goto err; - - if (!cms_env_asn1_ctrl(ri, 1)) - goto err; - - if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT, - EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); - goto err; - } - - if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen, - ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0) - goto err; - - ek = OPENSSL_malloc(eklen); - - if (ek == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen, - ktri->encryptedKey->data, - ktri->encryptedKey->length) <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); - goto err; - } - - ret = 1; - - if (ec->key) { - OPENSSL_cleanse(ec->key, ec->keylen); - OPENSSL_free(ec->key); - } - - ec->key = ek; - ec->keylen = eklen; - - err: - if (ktri->pctx) { - EVP_PKEY_CTX_free(ktri->pctx); - ktri->pctx = NULL; - } - if (!ret && ek) - OPENSSL_free(ek); - - return ret; -} - -/* Key Encrypted Key (KEK) RecipientInfo routines */ - -int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, - const unsigned char *id, size_t idlen) -{ - ASN1_OCTET_STRING tmp_os; - CMS_KEKRecipientInfo *kekri; - if (ri->type != CMS_RECIPINFO_KEK) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK); - return -2; - } - kekri = ri->d.kekri; - tmp_os.type = V_ASN1_OCTET_STRING; - tmp_os.flags = 0; - tmp_os.data = (unsigned char *)id; - tmp_os.length = (int)idlen; - return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); -} - -/* For now hard code AES key wrap info */ - -static size_t aes_wrap_keylen(int nid) -{ - switch (nid) { - case NID_id_aes128_wrap: - return 16; - - case NID_id_aes192_wrap: - return 24; - - case NID_id_aes256_wrap: - return 32; - - default: - return 0; - } -} - -CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, - unsigned char *key, size_t keylen, - unsigned char *id, size_t idlen, - ASN1_GENERALIZEDTIME *date, - ASN1_OBJECT *otherTypeId, - ASN1_TYPE *otherType) -{ - CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; - CMS_KEKRecipientInfo *kekri; - env = cms_get0_enveloped(cms); - if (!env) - goto err; - - if (nid == NID_undef) { - switch (keylen) { - case 16: - nid = NID_id_aes128_wrap; - break; - - case 24: - nid = NID_id_aes192_wrap; - break; - - case 32: - nid = NID_id_aes256_wrap; - break; - - default: - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); - goto err; - } - - } else { - - size_t exp_keylen = aes_wrap_keylen(nid); - - if (!exp_keylen) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, - CMS_R_UNSUPPORTED_KEK_ALGORITHM); - goto err; - } - - if (keylen != exp_keylen) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); - goto err; - } - - } - - /* Initialize recipient info */ - ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) - goto merr; - - ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); - if (!ri->d.kekri) - goto merr; - ri->type = CMS_RECIPINFO_KEK; - - kekri = ri->d.kekri; - - if (otherTypeId) { - kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); - if (kekri->kekid->other == NULL) - goto merr; - } - - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) - goto merr; - - /* After this point no calls can fail */ - - kekri->version = 4; - - kekri->key = key; - kekri->keylen = keylen; - - ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); - - kekri->kekid->date = date; - - if (kekri->kekid->other) { - kekri->kekid->other->keyAttrId = otherTypeId; - kekri->kekid->other->keyAttr = otherType; - } - - X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, - OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); - - return ri; - - merr: - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE); - err: - if (ri) - M_ASN1_free_of(ri, CMS_RecipientInfo); - return NULL; - -} - -int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, - X509_ALGOR **palg, - ASN1_OCTET_STRING **pid, - ASN1_GENERALIZEDTIME **pdate, - ASN1_OBJECT **potherid, - ASN1_TYPE **pothertype) -{ - CMS_KEKIdentifier *rkid; - if (ri->type != CMS_RECIPINFO_KEK) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK); - return 0; - } - rkid = ri->d.kekri->kekid; - if (palg) - *palg = ri->d.kekri->keyEncryptionAlgorithm; - if (pid) - *pid = rkid->keyIdentifier; - if (pdate) - *pdate = rkid->date; - if (potherid) { - if (rkid->other) - *potherid = rkid->other->keyAttrId; - else - *potherid = NULL; - } - if (pothertype) { - if (rkid->other) - *pothertype = rkid->other->keyAttr; - else - *pothertype = NULL; - } - return 1; -} - -int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, - unsigned char *key, size_t keylen) -{ - CMS_KEKRecipientInfo *kekri; - if (ri->type != CMS_RECIPINFO_KEK) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK); - return 0; - } - - kekri = ri->d.kekri; - kekri->key = key; - kekri->keylen = keylen; - return 1; -} - -/* Encrypt content key in KEK recipient info */ - -static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) -{ - CMS_EncryptedContentInfo *ec; - CMS_KEKRecipientInfo *kekri; - AES_KEY actx; - unsigned char *wkey = NULL; - int wkeylen; - int r = 0; - - ec = cms->d.envelopedData->encryptedContentInfo; - - kekri = ri->d.kekri; - - if (!kekri->key) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); - return 0; - } - - if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, - CMS_R_ERROR_SETTING_KEY); - goto err; - } - - wkey = OPENSSL_malloc(ec->keylen + 8); - - if (!wkey) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); - - if (wkeylen <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); - goto err; - } - - ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); - - r = 1; - - err: - - if (!r && wkey) - OPENSSL_free(wkey); - OPENSSL_cleanse(&actx, sizeof(actx)); - - return r; - -} - -/* Decrypt content key in KEK recipient info */ - -static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) -{ - CMS_EncryptedContentInfo *ec; - CMS_KEKRecipientInfo *kekri; - AES_KEY actx; - unsigned char *ukey = NULL; - int ukeylen; - int r = 0, wrap_nid; - - ec = cms->d.envelopedData->encryptedContentInfo; - - kekri = ri->d.kekri; - - if (!kekri->key) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); - return 0; - } - - wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); - if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_INVALID_KEY_LENGTH); - return 0; - } - - /* If encrypted key length is invalid don't bother */ - - if (kekri->encryptedKey->length < 16) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); - goto err; - } - - if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, - CMS_R_ERROR_SETTING_KEY); - goto err; - } - - ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); - - if (!ukey) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - ukeylen = AES_unwrap_key(&actx, NULL, ukey, - kekri->encryptedKey->data, - kekri->encryptedKey->length); - - if (ukeylen <= 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR); - goto err; - } - - ec->key = ukey; - ec->keylen = ukeylen; - - r = 1; - - err: - - if (!r && ukey) - OPENSSL_free(ukey); - OPENSSL_cleanse(&actx, sizeof(actx)); - - return r; - -} - -int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) -{ - switch (ri->type) { - case CMS_RECIPINFO_TRANS: - return cms_RecipientInfo_ktri_decrypt(cms, ri); - - case CMS_RECIPINFO_KEK: - return cms_RecipientInfo_kekri_decrypt(cms, ri); - - case CMS_RECIPINFO_PASS: - return cms_RecipientInfo_pwri_crypt(cms, ri, 0); - - default: - CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, - CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); - return 0; - } -} - -int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) -{ - switch (ri->type) { - case CMS_RECIPINFO_TRANS: - return cms_RecipientInfo_ktri_encrypt(cms, ri); - - case CMS_RECIPINFO_AGREE: - return cms_RecipientInfo_kari_encrypt(cms, ri); - - case CMS_RECIPINFO_KEK: - return cms_RecipientInfo_kekri_encrypt(cms, ri); - break; - - case CMS_RECIPINFO_PASS: - return cms_RecipientInfo_pwri_crypt(cms, ri, 1); - break; - - default: - CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT, - CMS_R_UNSUPPORTED_RECIPIENT_TYPE); - return 0; - } -} - -/* Check structures and fixup version numbers (if necessary) */ - -static void cms_env_set_originfo_version(CMS_EnvelopedData *env) -{ - CMS_OriginatorInfo *org = env->originatorInfo; - int i; - if (org == NULL) - return; - for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) { - CMS_CertificateChoices *cch; - cch = sk_CMS_CertificateChoices_value(org->certificates, i); - if (cch->type == CMS_CERTCHOICE_OTHER) { - env->version = 4; - return; - } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { - if (env->version < 3) - env->version = 3; - } - } - - for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) { - CMS_RevocationInfoChoice *rch; - rch = sk_CMS_RevocationInfoChoice_value(org->crls, i); - if (rch->type == CMS_REVCHOICE_OTHER) { - env->version = 4; - return; - } - } -} - -static void cms_env_set_version(CMS_EnvelopedData *env) -{ - int i; - CMS_RecipientInfo *ri; - - /* - * Can't set version higher than 4 so if 4 or more already nothing to do. - */ - if (env->version >= 4) - return; - - cms_env_set_originfo_version(env); - - if (env->version >= 3) - return; - - for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) { - ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i); - if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) { - env->version = 3; - return; - } else if (ri->type != CMS_RECIPINFO_TRANS - || ri->d.ktri->version != 0) { - env->version = 2; - } - } - if (env->version == 2) - return; - if (env->originatorInfo || env->unprotectedAttrs) - env->version = 2; - env->version = 0; -} - -BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) -{ - CMS_EncryptedContentInfo *ec; - STACK_OF(CMS_RecipientInfo) *rinfos; - CMS_RecipientInfo *ri; - int i, ok = 0; - BIO *ret; - - /* Get BIO first to set up key */ - - ec = cms->d.envelopedData->encryptedContentInfo; - ret = cms_EncryptedContent_init_bio(ec); - - /* If error or no cipher end of processing */ - - if (!ret || !ec->cipher) - return ret; - - /* Now encrypt content key according to each RecipientInfo type */ - - rinfos = cms->d.envelopedData->recipientInfos; - - for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { - ri = sk_CMS_RecipientInfo_value(rinfos, i); - if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) { - CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, - CMS_R_ERROR_SETTING_RECIPIENTINFO); - goto err; - } - } - cms_env_set_version(cms->d.envelopedData); - - ok = 1; - - err: - ec->cipher = NULL; - if (ec->key) { - OPENSSL_cleanse(ec->key, ec->keylen); - OPENSSL_free(ec->key); - ec->key = NULL; - ec->keylen = 0; - } - if (ok) - return ret; - BIO_free(ret); - return NULL; - -} - -/* - * Get RecipientInfo type (if any) supported by a key (public or private). To - * retain compatibility with previous behaviour if the ctrl value isn't - * supported we assume key transport. - */ -int cms_pkey_get_ri_type(EVP_PKEY *pk) -{ - if (pk->ameth && pk->ameth->pkey_ctrl) { - int i, r; - i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r); - if (i > 0) - return r; - } - return CMS_RECIPINFO_TRANS; -} -/* crypto/cms/cms_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -// #include "err.h" -// #include "cms.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason) - -static ERR_STRING_DATA CMS_str_functs[] = { - {ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"}, - {ERR_FUNC(CMS_F_CMS_ADD0_CERT), "CMS_add0_cert"}, - {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"}, - {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD), - "CMS_add0_recipient_password"}, - {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"}, - {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"}, - {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"}, - {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"}, - {ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"}, - {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "cms_CompressedData_create"}, - {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO), - "cms_CompressedData_init_bio"}, - {ERR_FUNC(CMS_F_CMS_COPY_CONTENT), "CMS_COPY_CONTENT"}, - {ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST), "CMS_COPY_MESSAGEDIGEST"}, - {ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"}, - {ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"}, - {ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"}, - {ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"}, - {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"}, - {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD), "CMS_decrypt_set1_password"}, - {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"}, - {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX), - "cms_DigestAlgorithm_find_ctx"}, - {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO), - "cms_DigestAlgorithm_init_bio"}, - {ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "cms_DigestedData_do_final"}, - {ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"}, - {ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT), "cms_encode_Receipt"}, - {ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"}, - {ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO), - "cms_EncryptedContent_init_bio"}, - {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"}, - {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT), "CMS_EncryptedData_encrypt"}, - {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY), - "CMS_EncryptedData_set1_key"}, - {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"}, - {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO), - "cms_EnvelopedData_init_bio"}, - {ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"}, - {ERR_FUNC(CMS_F_CMS_ENV_ASN1_CTRL), "cms_env_asn1_ctrl"}, - {ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"}, - {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), - "CMS_GET0_CERTIFICATE_CHOICES"}, - {ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"}, - {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "CMS_GET0_ECONTENT_TYPE"}, - {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "cms_get0_enveloped"}, - {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES), - "CMS_GET0_REVOCATION_CHOICES"}, - {ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"}, - {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "cms_msgSigDigest_add1"}, - {ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0), - "CMS_ReceiptRequest_create0"}, - {ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY), "cms_Receipt_verify"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_ENCRYPT), "CMS_RecipientInfo_encrypt"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT), - "cms_RecipientInfo_kari_encrypt"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG), - "CMS_RecipientInfo_kari_get0_alg"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID), - "CMS_RecipientInfo_kari_get0_orig_id"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS), - "CMS_RecipientInfo_kari_get0_reks"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP), - "CMS_RecipientInfo_kari_orig_id_cmp"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT), - "CMS_RECIPIENTINFO_KEKRI_DECRYPT"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT), - "CMS_RECIPIENTINFO_KEKRI_ENCRYPT"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID), - "CMS_RecipientInfo_kekri_get0_id"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP), - "CMS_RecipientInfo_kekri_id_cmp"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), - "CMS_RecipientInfo_ktri_cert_cmp"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT), - "CMS_RECIPIENTINFO_KTRI_DECRYPT"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT), - "CMS_RECIPIENTINFO_KTRI_ENCRYPT"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS), - "CMS_RecipientInfo_ktri_get0_algs"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID), - "CMS_RecipientInfo_ktri_get0_signer_id"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT), - "cms_RecipientInfo_pwri_crypt"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY), - "CMS_RecipientInfo_set0_key"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD), - "CMS_RecipientInfo_set0_password"}, - {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY), - "CMS_RecipientInfo_set0_pkey"}, - {ERR_FUNC(CMS_F_CMS_SD_ASN1_CTRL), "CMS_SD_ASN1_CTRL"}, - {ERR_FUNC(CMS_F_CMS_SET1_IAS), "cms_set1_ias"}, - {ERR_FUNC(CMS_F_CMS_SET1_KEYID), "cms_set1_keyid"}, - {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"}, - {ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"}, - {ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"}, - {ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT), "CMS_SIGNED_DATA_INIT"}, - {ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN), - "CMS_SIGNERINFO_CONTENT_SIGN"}, - {ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN), "CMS_SignerInfo_sign"}, - {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY), "CMS_SignerInfo_verify"}, - {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), - "CMS_SIGNERINFO_VERIFY_CERT"}, - {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), - "CMS_SignerInfo_verify_content"}, - {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"}, - {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"}, - {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"}, - {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"}, - {0, NULL} -}; - -static ERR_STRING_DATA CMS_str_reasons[] = { - {ERR_REASON(CMS_R_ADD_SIGNER_ERROR), "add signer error"}, - {ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT), - "certificate already present"}, - {ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID), "certificate has no keyid"}, - {ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, - {ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR), - "cipher initialisation error"}, - {ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR), - "cipher parameter initialisation error"}, - {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR), "cms datafinal error"}, - {ERR_REASON(CMS_R_CMS_LIB), "cms lib"}, - {ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH), - "contentidentifier mismatch"}, - {ERR_REASON(CMS_R_CONTENT_NOT_FOUND), "content not found"}, - {ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH), "content type mismatch"}, - {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA), - "content type not compressed data"}, - {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA), - "content type not enveloped data"}, - {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA), - "content type not signed data"}, - {ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR), "content verify error"}, - {ERR_REASON(CMS_R_CTRL_ERROR), "ctrl error"}, - {ERR_REASON(CMS_R_CTRL_FAILURE), "ctrl failure"}, - {ERR_REASON(CMS_R_DECRYPT_ERROR), "decrypt error"}, - {ERR_REASON(CMS_R_DIGEST_ERROR), "digest error"}, - {ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY), "error getting public key"}, - {ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE), - "error reading messagedigest attribute"}, - {ERR_REASON(CMS_R_ERROR_SETTING_KEY), "error setting key"}, - {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO), - "error setting recipientinfo"}, - {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH), - "invalid encrypted key length"}, - {ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER), - "invalid key encryption parameter"}, - {ERR_REASON(CMS_R_INVALID_KEY_LENGTH), "invalid key length"}, - {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR), "md bio init error"}, - {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH), - "messagedigest attribute wrong length"}, - {ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH), - "messagedigest wrong length"}, - {ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"}, - {ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE), - "msgsigdigest verification failure"}, - {ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH), - "msgsigdigest wrong length"}, - {ERR_REASON(CMS_R_NEED_ONE_SIGNER), "need one signer"}, - {ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT), "not a signed receipt"}, - {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"}, - {ERR_REASON(CMS_R_NOT_KEK), "not kek"}, - {ERR_REASON(CMS_R_NOT_KEY_AGREEMENT), "not key agreement"}, - {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT), "not key transport"}, - {ERR_REASON(CMS_R_NOT_PWRI), "not pwri"}, - {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), - "not supported for this key type"}, - {ERR_REASON(CMS_R_NO_CIPHER), "no cipher"}, - {ERR_REASON(CMS_R_NO_CONTENT), "no content"}, - {ERR_REASON(CMS_R_NO_CONTENT_TYPE), "no content type"}, - {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST), "no default digest"}, - {ERR_REASON(CMS_R_NO_DIGEST_SET), "no digest set"}, - {ERR_REASON(CMS_R_NO_KEY), "no key"}, - {ERR_REASON(CMS_R_NO_KEY_OR_CERT), "no key or cert"}, - {ERR_REASON(CMS_R_NO_MATCHING_DIGEST), "no matching digest"}, - {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT), "no matching recipient"}, - {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE), "no matching signature"}, - {ERR_REASON(CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"}, - {ERR_REASON(CMS_R_NO_PASSWORD), "no password"}, - {ERR_REASON(CMS_R_NO_PRIVATE_KEY), "no private key"}, - {ERR_REASON(CMS_R_NO_PUBLIC_KEY), "no public key"}, - {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST), "no receipt request"}, - {ERR_REASON(CMS_R_NO_SIGNERS), "no signers"}, - {ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), - "private key does not match certificate"}, - {ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR), "receipt decode error"}, - {ERR_REASON(CMS_R_RECIPIENT_ERROR), "recipient error"}, - {ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND), - "signer certificate not found"}, - {ERR_REASON(CMS_R_SIGNFINAL_ERROR), "signfinal error"}, - {ERR_REASON(CMS_R_SMIME_TEXT_ERROR), "smime text error"}, - {ERR_REASON(CMS_R_STORE_INIT_ERROR), "store init error"}, - {ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA), "type not compressed data"}, - {ERR_REASON(CMS_R_TYPE_NOT_DATA), "type not data"}, - {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA), "type not digested data"}, - {ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA), "type not encrypted data"}, - {ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA), "type not enveloped data"}, - {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT), - "unable to finalize context"}, - {ERR_REASON(CMS_R_UNKNOWN_CIPHER), "unknown cipher"}, - {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM), "unknown digest algorihm"}, - {ERR_REASON(CMS_R_UNKNOWN_ID), "unknown id"}, - {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM), - "unsupported compression algorithm"}, - {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"}, - {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM), - "unsupported kek algorithm"}, - {ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM), - "unsupported key encryption algorithm"}, - {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE), - "unsupported recipient type"}, - {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE), - "unsupported recpientinfo type"}, - {ERR_REASON(CMS_R_UNSUPPORTED_TYPE), "unsupported type"}, - {ERR_REASON(CMS_R_UNWRAP_ERROR), "unwrap error"}, - {ERR_REASON(CMS_R_UNWRAP_FAILURE), "unwrap failure"}, - {ERR_REASON(CMS_R_VERIFICATION_FAILURE), "verification failure"}, - {ERR_REASON(CMS_R_WRAP_ERROR), "wrap error"}, - {0, NULL} -}; - -#endif - -void ERR_load_CMS_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) { - ERR_load_strings(0, CMS_str_functs); - ERR_load_strings(0, CMS_str_reasons); - } -#endif -} -/* crypto/cms/cms_ess.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "pem.h" -// #include "rand.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -// #include "cms_lcl.h" - -DECLARE_ASN1_ITEM(CMS_ReceiptRequest) -DECLARE_ASN1_ITEM(CMS_Receipt) - -IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) - -/* ESS services: for now just Signed Receipt related */ - -int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) -{ - ASN1_STRING *str; - CMS_ReceiptRequest *rr = NULL; - if (prr) - *prr = NULL; - str = CMS_signed_get0_data_by_OBJ(si, - OBJ_nid2obj - (NID_id_smime_aa_receiptRequest), -3, - V_ASN1_SEQUENCE); - if (!str) - return 0; - - rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); - if (!rr) - return -1; - if (prr) - *prr = rr; - else - CMS_ReceiptRequest_free(rr); - return 1; -} - -CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, - int allorfirst, - STACK_OF(GENERAL_NAMES) - *receiptList, STACK_OF(GENERAL_NAMES) - *receiptsTo) -{ - CMS_ReceiptRequest *rr = NULL; - - rr = CMS_ReceiptRequest_new(); - if (!rr) - goto merr; - if (id) - ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); - else { - if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) - goto merr; - if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0) - goto err; - } - - sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); - rr->receiptsTo = receiptsTo; - - if (receiptList) { - rr->receiptsFrom->type = 1; - rr->receiptsFrom->d.receiptList = receiptList; - } else { - rr->receiptsFrom->type = 0; - rr->receiptsFrom->d.allOrFirstTier = allorfirst; - } - - return rr; - - merr: - CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE); - - err: - if (rr) - CMS_ReceiptRequest_free(rr); - - return NULL; - -} - -int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) -{ - unsigned char *rrder = NULL; - int rrderlen, r = 0; - - rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder); - if (rrderlen < 0) - goto merr; - - if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest, - V_ASN1_SEQUENCE, rrder, rrderlen)) - goto merr; - - r = 1; - - merr: - if (!r) - CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE); - - if (rrder) - OPENSSL_free(rrder); - - return r; - -} - -void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, - ASN1_STRING **pcid, - int *pallorfirst, - STACK_OF(GENERAL_NAMES) **plist, - STACK_OF(GENERAL_NAMES) **prto) -{ - if (pcid) - *pcid = rr->signedContentIdentifier; - if (rr->receiptsFrom->type == 0) { - if (pallorfirst) - *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; - if (plist) - *plist = NULL; - } else { - if (pallorfirst) - *pallorfirst = -1; - if (plist) - *plist = rr->receiptsFrom->d.receiptList; - } - if (prto) - *prto = rr->receiptsTo; -} - -/* Digest a SignerInfo structure for msgSigDigest attribute processing */ - -static int cms_msgSigDigest(CMS_SignerInfo *si, - unsigned char *dig, unsigned int *diglen) -{ - const EVP_MD *md; - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) - return 0; - if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, - si->signedAttrs, dig, diglen)) - return 0; - return 1; -} - -/* Add a msgSigDigest attribute to a SignerInfo */ - -int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) -{ - unsigned char dig[EVP_MAX_MD_SIZE]; - unsigned int diglen; - if (!cms_msgSigDigest(src, dig, &diglen)) { - CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); - return 0; - } - if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, - V_ASN1_OCTET_STRING, dig, diglen)) { - CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE); - return 0; - } - return 1; -} - -/* Verify signed receipt after it has already passed normal CMS verify */ - -int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) -{ - int r = 0, i; - CMS_ReceiptRequest *rr = NULL; - CMS_Receipt *rct = NULL; - STACK_OF(CMS_SignerInfo) *sis, *osis; - CMS_SignerInfo *si, *osi = NULL; - ASN1_OCTET_STRING *msig, **pcont; - ASN1_OBJECT *octype; - unsigned char dig[EVP_MAX_MD_SIZE]; - unsigned int diglen; - - /* Get SignerInfos, also checks SignedData content type */ - osis = CMS_get0_SignerInfos(req_cms); - sis = CMS_get0_SignerInfos(cms); - if (!osis || !sis) - goto err; - - if (sk_CMS_SignerInfo_num(sis) != 1) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER); - goto err; - } - - /* Check receipt content type */ - if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT); - goto err; - } - - /* Extract and decode receipt content */ - pcont = CMS_get0_content(cms); - if (!pcont || !*pcont) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT); - goto err; - } - - rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt)); - - if (!rct) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR); - goto err; - } - - /* Locate original request */ - - for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) { - osi = sk_CMS_SignerInfo_value(osis, i); - if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue)) - break; - } - - if (i == sk_CMS_SignerInfo_num(osis)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE); - goto err; - } - - si = sk_CMS_SignerInfo_value(sis, 0); - - /* Get msgSigDigest value and compare */ - - msig = CMS_signed_get0_data_by_OBJ(si, - OBJ_nid2obj - (NID_id_smime_aa_msgSigDigest), -3, - V_ASN1_OCTET_STRING); - - if (!msig) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST); - goto err; - } - - if (!cms_msgSigDigest(osi, dig, &diglen)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR); - goto err; - } - - if (diglen != (unsigned int)msig->length) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH); - goto err; - } - - if (memcmp(dig, msig->data, diglen)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, - CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); - goto err; - } - - /* Compare content types */ - - octype = CMS_signed_get0_data_by_OBJ(osi, - OBJ_nid2obj(NID_pkcs9_contentType), - -3, V_ASN1_OBJECT); - if (!octype) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE); - goto err; - } - - /* Compare details in receipt request */ - - if (OBJ_cmp(octype, rct->contentType)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH); - goto err; - } - - /* Get original receipt request details */ - - if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); - goto err; - } - - if (ASN1_STRING_cmp(rr->signedContentIdentifier, - rct->signedContentIdentifier)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH); - goto err; - } - - r = 1; - - err: - if (rr) - CMS_ReceiptRequest_free(rr); - if (rct) - M_ASN1_free_of(rct, CMS_Receipt); - - return r; - -} - -/* - * Encode a Receipt into an OCTET STRING read for including into content of a - * SignedData ContentInfo. - */ - -ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) -{ - CMS_Receipt rct; - CMS_ReceiptRequest *rr = NULL; - ASN1_OBJECT *ctype; - ASN1_OCTET_STRING *os = NULL; - - /* Get original receipt request */ - - /* Get original receipt request details */ - - if (CMS_get1_ReceiptRequest(si, &rr) <= 0) { - CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); - goto err; - } - - /* Get original content type */ - - ctype = CMS_signed_get0_data_by_OBJ(si, - OBJ_nid2obj(NID_pkcs9_contentType), - -3, V_ASN1_OBJECT); - if (!ctype) { - CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE); - goto err; - } - - rct.version = 1; - rct.contentType = ctype; - rct.signedContentIdentifier = rr->signedContentIdentifier; - rct.originatorSignatureValue = si->signature; - - os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL); - - err: - if (rr) - CMS_ReceiptRequest_free(rr); - - return os; - -} -/* crypto/cms/cms_io.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "asn1t.h" -#include "x509.h" -// #include "err.h" -// #include "pem.h" -// #include "cms.h" -// #include "cms_lcl.h" - -int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) -{ - ASN1_OCTET_STRING **pos; - pos = CMS_get0_content(cms); - if (!pos) - return 0; - if (!*pos) - *pos = ASN1_OCTET_STRING_new(); - if (*pos) { - (*pos)->flags |= ASN1_STRING_FLAG_NDEF; - (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; - *boundary = &(*pos)->data; - return 1; - } - CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE); - return 0; -} - -CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); -} - -int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); -} - -IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) - -BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) -{ - return BIO_new_NDEF(out, (ASN1_VALUE *)cms, - ASN1_ITEM_rptr(CMS_ContentInfo)); -} - -/* CMS wrappers round generalised stream and MIME routines */ - -int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) -{ - return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags, - ASN1_ITEM_rptr(CMS_ContentInfo)); -} - -int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, - int flags) -{ - return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags, - "CMS", ASN1_ITEM_rptr(CMS_ContentInfo)); -} - -int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) -{ - STACK_OF(X509_ALGOR) *mdalgs; - int ctype_nid = OBJ_obj2nid(cms->contentType); - int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms)); - if (ctype_nid == NID_pkcs7_signed) - mdalgs = cms->d.signedData->digestAlgorithms; - else - mdalgs = NULL; - - return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, - ctype_nid, econt_nid, mdalgs, - ASN1_ITEM_rptr(CMS_ContentInfo)); -} - -CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont) -{ - return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, - ASN1_ITEM_rptr - (CMS_ContentInfo)); -} -/* crypto/cms/cms_kari.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "pem.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -// #include "rand.h" -// #include "aes.h" -// #include "cms_lcl.h" -// #include "asn1_locl.h" - -DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo) -DECLARE_ASN1_ITEM(CMS_RecipientEncryptedKey) -DECLARE_ASN1_ITEM(CMS_OriginatorPublicKey) -DECLARE_ASN1_ITEM(CMS_RecipientKeyIdentifier) - -/* Key Agreement Recipient Info (KARI) routines */ - -int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri, - X509_ALGOR **palg, - ASN1_OCTET_STRING **pukm) -{ - if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG, - CMS_R_NOT_KEY_AGREEMENT); - return 0; - } - if (palg) - *palg = ri->d.kari->keyEncryptionAlgorithm; - if (pukm) - *pukm = ri->d.kari->ukm; - return 1; -} - -/* Retrieve recipient encrypted keys from a kari */ - -STACK_OF(CMS_RecipientEncryptedKey) -*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri) -{ - if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS, - CMS_R_NOT_KEY_AGREEMENT); - return NULL; - } - return ri->d.kari->recipientEncryptedKeys; -} - -int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri, - X509_ALGOR **pubalg, - ASN1_BIT_STRING **pubkey, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, - ASN1_INTEGER **sno) -{ - CMS_OriginatorIdentifierOrKey *oik; - if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID, - CMS_R_NOT_KEY_AGREEMENT); - return 0; - } - oik = ri->d.kari->originator; - if (issuer) - *issuer = NULL; - if (sno) - *sno = NULL; - if (keyid) - *keyid = NULL; - if (pubalg) - *pubalg = NULL; - if (pubkey) - *pubkey = NULL; - if (oik->type == CMS_OIK_ISSUER_SERIAL) { - if (issuer) - *issuer = oik->d.issuerAndSerialNumber->issuer; - if (sno) - *sno = oik->d.issuerAndSerialNumber->serialNumber; - } else if (oik->type == CMS_OIK_KEYIDENTIFIER) { - if (keyid) - *keyid = oik->d.subjectKeyIdentifier; - } else if (oik->type == CMS_OIK_PUBKEY) { - if (pubalg) - *pubalg = oik->d.originatorKey->algorithm; - if (pubkey) - *pubkey = oik->d.originatorKey->publicKey; - } else - return 0; - return 1; -} - -int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert) -{ - CMS_OriginatorIdentifierOrKey *oik; - if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP, - CMS_R_NOT_KEY_AGREEMENT); - return -2; - } - oik = ri->d.kari->originator; - if (oik->type == CMS_OIK_ISSUER_SERIAL) - return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert); - else if (oik->type == CMS_OIK_KEYIDENTIFIER) - return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert); - return -1; -} - -int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek, - ASN1_OCTET_STRING **keyid, - ASN1_GENERALIZEDTIME **tm, - CMS_OtherKeyAttribute **other, - X509_NAME **issuer, ASN1_INTEGER **sno) -{ - CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; - if (rid->type == CMS_REK_ISSUER_SERIAL) { - if (issuer) - *issuer = rid->d.issuerAndSerialNumber->issuer; - if (sno) - *sno = rid->d.issuerAndSerialNumber->serialNumber; - if (keyid) - *keyid = NULL; - if (tm) - *tm = NULL; - if (other) - *other = NULL; - } else if (rid->type == CMS_REK_KEYIDENTIFIER) { - if (keyid) - *keyid = rid->d.rKeyId->subjectKeyIdentifier; - if (tm) - *tm = rid->d.rKeyId->date; - if (other) - *other = rid->d.rKeyId->other; - if (issuer) - *issuer = NULL; - if (sno) - *sno = NULL; - } else - return 0; - return 1; -} - -int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek, - X509 *cert) -{ - CMS_KeyAgreeRecipientIdentifier *rid = rek->rid; - if (rid->type == CMS_REK_ISSUER_SERIAL) - return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert); - else if (rid->type == CMS_REK_KEYIDENTIFIER) - return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert); - else - return -1; -} - -int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk) -{ - EVP_PKEY_CTX *pctx; - CMS_KeyAgreeRecipientInfo *kari = ri->d.kari; - if (kari->pctx) { - EVP_PKEY_CTX_free(kari->pctx); - kari->pctx = NULL; - } - if (!pk) - return 1; - pctx = EVP_PKEY_CTX_new(pk, NULL); - if (!pctx || !EVP_PKEY_derive_init(pctx)) - goto err; - kari->pctx = pctx; - return 1; - err: - if (pctx) - EVP_PKEY_CTX_free(pctx); - return 0; -} - -EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri) -{ - if (ri->type == CMS_RECIPINFO_AGREE) - return &ri->d.kari->ctx; - return NULL; -} - -/* - * Derive KEK and decrypt/encrypt with it to produce either the original CEK - * or the encrypted CEK. - */ - -static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, - const unsigned char *in, size_t inlen, - CMS_KeyAgreeRecipientInfo *kari, int enc) -{ - /* Key encryption key */ - unsigned char kek[EVP_MAX_KEY_LENGTH]; - size_t keklen; - int rv = 0; - unsigned char *out = NULL; - int outlen; - keklen = EVP_CIPHER_CTX_key_length(&kari->ctx); - if (keklen > EVP_MAX_KEY_LENGTH) - return 0; - /* Derive KEK */ - if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0) - goto err; - /* Set KEK in context */ - if (!EVP_CipherInit_ex(&kari->ctx, NULL, NULL, kek, NULL, enc)) - goto err; - /* obtain output length of ciphered key */ - if (!EVP_CipherUpdate(&kari->ctx, NULL, &outlen, in, inlen)) - goto err; - out = OPENSSL_malloc(outlen); - if (!out) - goto err; - if (!EVP_CipherUpdate(&kari->ctx, out, &outlen, in, inlen)) - goto err; - *pout = out; - *poutlen = (size_t)outlen; - rv = 1; - - err: - OPENSSL_cleanse(kek, keklen); - if (!rv && out) - OPENSSL_free(out); - EVP_CIPHER_CTX_cleanup(&kari->ctx); - EVP_PKEY_CTX_free(kari->pctx); - kari->pctx = NULL; - return rv; -} - -int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri, - CMS_RecipientEncryptedKey *rek) -{ - int rv = 0; - unsigned char *enckey = NULL, *cek = NULL; - size_t enckeylen; - size_t ceklen; - CMS_EncryptedContentInfo *ec; - enckeylen = rek->encryptedKey->length; - enckey = rek->encryptedKey->data; - /* Setup all parameters to derive KEK */ - if (!cms_env_asn1_ctrl(ri, 1)) - goto err; - /* Attempt to decrypt CEK */ - if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0)) - goto err; - ec = cms->d.envelopedData->encryptedContentInfo; - if (ec->key) { - OPENSSL_cleanse(ec->key, ec->keylen); - OPENSSL_free(ec->key); - } - ec->key = cek; - ec->keylen = ceklen; - cek = NULL; - rv = 1; - err: - if (cek) - OPENSSL_free(cek); - return rv; -} - -/* Create ephemeral key and initialise context based on it */ -static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari, - EVP_PKEY *pk) -{ - EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY *ekey = NULL; - int rv = 0; - pctx = EVP_PKEY_CTX_new(pk, NULL); - if (!pctx) - goto err; - if (EVP_PKEY_keygen_init(pctx) <= 0) - goto err; - if (EVP_PKEY_keygen(pctx, &ekey) <= 0) - goto err; - EVP_PKEY_CTX_free(pctx); - pctx = EVP_PKEY_CTX_new(ekey, NULL); - if (!pctx) - goto err; - if (EVP_PKEY_derive_init(pctx) <= 0) - goto err; - kari->pctx = pctx; - rv = 1; - err: - if (!rv && pctx) - EVP_PKEY_CTX_free(pctx); - if (ekey) - EVP_PKEY_free(ekey); - return rv; -} - -/* Initialise a ktri based on passed certificate and key */ - -int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, - EVP_PKEY *pk, unsigned int flags) -{ - CMS_KeyAgreeRecipientInfo *kari; - CMS_RecipientEncryptedKey *rek = NULL; - - ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo); - if (!ri->d.kari) - return 0; - ri->type = CMS_RECIPINFO_AGREE; - - kari = ri->d.kari; - kari->version = 3; - - rek = M_ASN1_new_of(CMS_RecipientEncryptedKey); - if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) { - M_ASN1_free_of(rek, CMS_RecipientEncryptedKey); - return 0; - } - - if (flags & CMS_USE_KEYID) { - rek->rid->type = CMS_REK_KEYIDENTIFIER; - rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier); - if (rek->rid->d.rKeyId == NULL) - return 0; - if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip)) - return 0; - } else { - rek->rid->type = CMS_REK_ISSUER_SERIAL; - if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip)) - return 0; - } - - /* Create ephemeral key */ - if (!cms_kari_create_ephemeral_key(kari, pk)) - return 0; - - CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); - rek->pkey = pk; - return 1; -} - -static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari, - const EVP_CIPHER *cipher) -{ - EVP_CIPHER_CTX *ctx = &kari->ctx; - const EVP_CIPHER *kekcipher; - int keylen = EVP_CIPHER_key_length(cipher); - /* If a suitable wrap algorithm is already set nothing to do */ - kekcipher = EVP_CIPHER_CTX_cipher(ctx); - - if (kekcipher) { - if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE) - return 0; - return 1; - } - /* - * Pick a cipher based on content encryption cipher. If it is DES3 use - * DES3 wrap otherwise use AES wrap similar to key size. - */ -#ifndef OPENSSL_NO_DES - if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc) - kekcipher = EVP_des_ede3_wrap(); - else -#endif - if (keylen <= 16) - kekcipher = EVP_aes_128_wrap(); - else if (keylen <= 24) - kekcipher = EVP_aes_192_wrap(); - else - kekcipher = EVP_aes_256_wrap(); - return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL); -} - -/* Encrypt content key in key agreement recipient info */ - -int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri) -{ - CMS_KeyAgreeRecipientInfo *kari; - CMS_EncryptedContentInfo *ec; - CMS_RecipientEncryptedKey *rek; - STACK_OF(CMS_RecipientEncryptedKey) *reks; - int i; - - if (ri->type != CMS_RECIPINFO_AGREE) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT); - return 0; - } - kari = ri->d.kari; - reks = kari->recipientEncryptedKeys; - ec = cms->d.envelopedData->encryptedContentInfo; - /* Initialise wrap algorithm parameters */ - if (!cms_wrap_init(kari, ec->cipher)) - return 0; - /* - * If no orignator key set up initialise for ephemeral key the public key - * ASN1 structure will set the actual public key value. - */ - if (kari->originator->type == -1) { - CMS_OriginatorIdentifierOrKey *oik = kari->originator; - oik->type = CMS_OIK_PUBKEY; - oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey); - if (!oik->d.originatorKey) - return 0; - } - /* Initialise KDF algorithm */ - if (!cms_env_asn1_ctrl(ri, 0)) - return 0; - /* For each rek, derive KEK, encrypt CEK */ - for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { - unsigned char *enckey; - size_t enckeylen; - rek = sk_CMS_RecipientEncryptedKey_value(reks, i); - if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0) - return 0; - if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen, - kari, 1)) - return 0; - ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen); - } - - return 1; - -} -/* crypto/cms/cms_lib.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "asn1t.h" -// #include "x509v3.h" -// #include "err.h" -// #include "pem.h" -// #include "bio.h" -#include "asn1.h" -// #include "cms.h" -// #include "cms_lcl.h" - -IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo) -IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) - -DECLARE_ASN1_ITEM(CMS_CertificateChoices) -DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) -DECLARE_STACK_OF(CMS_CertificateChoices) -DECLARE_STACK_OF(CMS_RevocationInfoChoice) - -const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms) -{ - return cms->contentType; -} - -CMS_ContentInfo *cms_Data_create(void) -{ - CMS_ContentInfo *cms; - cms = CMS_ContentInfo_new(); - if (cms) { - cms->contentType = OBJ_nid2obj(NID_pkcs7_data); - /* Never detached */ - CMS_set_detached(cms, 0); - } - return cms; -} - -BIO *cms_content_bio(CMS_ContentInfo *cms) -{ - ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos) - return NULL; - /* If content detached data goes nowhere: create NULL BIO */ - if (!*pos) - return BIO_new(BIO_s_null()); - /* - * If content not detached and created return memory BIO - */ - if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) - return BIO_new(BIO_s_mem()); - /* Else content was read in: return read only BIO for it */ - return BIO_new_mem_buf((*pos)->data, (*pos)->length); -} - -BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) -{ - BIO *cmsbio, *cont; - if (icont) - cont = icont; - else - cont = cms_content_bio(cms); - if (!cont) { - CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT); - return NULL; - } - switch (OBJ_obj2nid(cms->contentType)) { - - case NID_pkcs7_data: - return cont; - - case NID_pkcs7_signed: - cmsbio = cms_SignedData_init_bio(cms); - break; - - case NID_pkcs7_digest: - cmsbio = cms_DigestedData_init_bio(cms); - break; -#ifdef ZLIB - case NID_id_smime_ct_compressedData: - cmsbio = cms_CompressedData_init_bio(cms); - break; -#endif - - case NID_pkcs7_encrypted: - cmsbio = cms_EncryptedData_init_bio(cms); - break; - - case NID_pkcs7_enveloped: - cmsbio = cms_EnvelopedData_init_bio(cms); - break; - - default: - CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); - return NULL; - } - - if (cmsbio) - return BIO_push(cmsbio, cont); - - if (!icont) - BIO_free(cont); - return NULL; - -} - -int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) -{ - ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos) - return 0; - /* If ebmedded content find memory BIO and set content */ - if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { - BIO *mbio; - unsigned char *cont; - long contlen; - mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); - if (!mbio) { - CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); - return 0; - } - contlen = BIO_get_mem_data(mbio, &cont); - /* Set bio as read only so its content can't be clobbered */ - BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); - BIO_set_mem_eof_return(mbio, 0); - ASN1_STRING_set0(*pos, cont, contlen); - (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; - } - - switch (OBJ_obj2nid(cms->contentType)) { - - case NID_pkcs7_data: - case NID_pkcs7_enveloped: - case NID_pkcs7_encrypted: - case NID_id_smime_ct_compressedData: - /* Nothing to do */ - return 1; - - case NID_pkcs7_signed: - return cms_SignedData_final(cms, cmsbio); - - case NID_pkcs7_digest: - return cms_DigestedData_do_final(cms, cmsbio, 0); - - default: - CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); - return 0; - } -} - -/* - * Return an OCTET STRING pointer to content. This allows it to be accessed - * or set later. - */ - -ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) -{ - switch (OBJ_obj2nid(cms->contentType)) { - - case NID_pkcs7_data: - return &cms->d.data; - - case NID_pkcs7_signed: - return &cms->d.signedData->encapContentInfo->eContent; - - case NID_pkcs7_enveloped: - return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; - - case NID_pkcs7_digest: - return &cms->d.digestedData->encapContentInfo->eContent; - - case NID_pkcs7_encrypted: - return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; - - case NID_id_smime_ct_authData: - return &cms->d.authenticatedData->encapContentInfo->eContent; - - case NID_id_smime_ct_compressedData: - return &cms->d.compressedData->encapContentInfo->eContent; - - default: - if (cms->d.other->type == V_ASN1_OCTET_STRING) - return &cms->d.other->value.octet_string; - CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE); - return NULL; - - } -} - -/* - * Return an ASN1_OBJECT pointer to content type. This allows it to be - * accessed or set later. - */ - -static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) -{ - switch (OBJ_obj2nid(cms->contentType)) { - - case NID_pkcs7_signed: - return &cms->d.signedData->encapContentInfo->eContentType; - - case NID_pkcs7_enveloped: - return &cms->d.envelopedData->encryptedContentInfo->contentType; - - case NID_pkcs7_digest: - return &cms->d.digestedData->encapContentInfo->eContentType; - - case NID_pkcs7_encrypted: - return &cms->d.encryptedData->encryptedContentInfo->contentType; - - case NID_id_smime_ct_authData: - return &cms->d.authenticatedData->encapContentInfo->eContentType; - - case NID_id_smime_ct_compressedData: - return &cms->d.compressedData->encapContentInfo->eContentType; - - default: - CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE); - return NULL; - - } -} - -const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms) -{ - ASN1_OBJECT **petype; - petype = cms_get0_econtent_type(cms); - if (petype) - return *petype; - return NULL; -} - -int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) -{ - ASN1_OBJECT **petype, *etype; - petype = cms_get0_econtent_type(cms); - if (!petype) - return 0; - if (!oid) - return 1; - etype = OBJ_dup(oid); - if (!etype) - return 0; - ASN1_OBJECT_free(*petype); - *petype = etype; - return 1; -} - -int CMS_is_detached(CMS_ContentInfo *cms) -{ - ASN1_OCTET_STRING **pos; - pos = CMS_get0_content(cms); - if (!pos) - return -1; - if (*pos) - return 0; - return 1; -} - -int CMS_set_detached(CMS_ContentInfo *cms, int detached) -{ - ASN1_OCTET_STRING **pos; - pos = CMS_get0_content(cms); - if (!pos) - return 0; - if (detached) { - if (*pos) { - ASN1_OCTET_STRING_free(*pos); - *pos = NULL; - } - return 1; - } - if (!*pos) - *pos = ASN1_OCTET_STRING_new(); - if (*pos) { - /* - * NB: special flag to show content is created and not read in. - */ - (*pos)->flags |= ASN1_STRING_FLAG_CONT; - return 1; - } - CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE); - return 0; -} - -/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ - -void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) -{ - int param_type; - - if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) - param_type = V_ASN1_UNDEF; - else - param_type = V_ASN1_NULL; - - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); - -} - -/* Create a digest BIO from an X509_ALGOR structure */ - -BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) -{ - BIO *mdbio = NULL; - ASN1_OBJECT *digestoid; - const EVP_MD *digest; - X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); - digest = EVP_get_digestbyobj(digestoid); - if (!digest) { - CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, - CMS_R_UNKNOWN_DIGEST_ALGORIHM); - goto err; - } - mdbio = BIO_new(BIO_f_md()); - if (!mdbio || !BIO_set_md(mdbio, digest)) { - CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR); - goto err; - } - return mdbio; - err: - if (mdbio) - BIO_free(mdbio); - return NULL; -} - -/* Locate a message digest content from a BIO chain based on SignerInfo */ - -int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, - X509_ALGOR *mdalg) -{ - int nid; - ASN1_OBJECT *mdoid; - X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); - nid = OBJ_obj2nid(mdoid); - /* Look for digest type to match signature */ - for (;;) { - EVP_MD_CTX *mtmp; - chain = BIO_find_type(chain, BIO_TYPE_MD); - if (chain == NULL) { - CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, - CMS_R_NO_MATCHING_DIGEST); - return 0; - } - BIO_get_md_ctx(chain, &mtmp); - if (EVP_MD_CTX_type(mtmp) == nid - /* - * Workaround for broken implementations that use signature - * algorithm OID instead of digest. - */ - || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) - return EVP_MD_CTX_copy_ex(mctx, mtmp); - chain = BIO_next(chain); - } -} - -static STACK_OF(CMS_CertificateChoices) -**cms_get0_certificate_choices(CMS_ContentInfo *cms) -{ - switch (OBJ_obj2nid(cms->contentType)) { - - case NID_pkcs7_signed: - return &cms->d.signedData->certificates; - - case NID_pkcs7_enveloped: - if (cms->d.envelopedData->originatorInfo == NULL) - return NULL; - return &cms->d.envelopedData->originatorInfo->certificates; - - default: - CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, - CMS_R_UNSUPPORTED_CONTENT_TYPE); - return NULL; - - } -} - -CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) -{ - STACK_OF(CMS_CertificateChoices) **pcerts; - CMS_CertificateChoices *cch; - pcerts = cms_get0_certificate_choices(cms); - if (!pcerts) - return NULL; - if (!*pcerts) - *pcerts = sk_CMS_CertificateChoices_new_null(); - if (!*pcerts) - return NULL; - cch = M_ASN1_new_of(CMS_CertificateChoices); - if (!cch) - return NULL; - if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) { - M_ASN1_free_of(cch, CMS_CertificateChoices); - return NULL; - } - return cch; -} - -int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) -{ - CMS_CertificateChoices *cch; - STACK_OF(CMS_CertificateChoices) **pcerts; - int i; - pcerts = cms_get0_certificate_choices(cms); - if (!pcerts) - return 0; - for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { - cch = sk_CMS_CertificateChoices_value(*pcerts, i); - if (cch->type == CMS_CERTCHOICE_CERT) { - if (!X509_cmp(cch->d.certificate, cert)) { - CMSerr(CMS_F_CMS_ADD0_CERT, - CMS_R_CERTIFICATE_ALREADY_PRESENT); - return 0; - } - } - } - cch = CMS_add0_CertificateChoices(cms); - if (!cch) - return 0; - cch->type = CMS_CERTCHOICE_CERT; - cch->d.certificate = cert; - return 1; -} - -int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) -{ - int r; - r = CMS_add0_cert(cms, cert); - if (r > 0) - CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); - return r; -} - -static STACK_OF(CMS_RevocationInfoChoice) -**cms_get0_revocation_choices(CMS_ContentInfo *cms) -{ - switch (OBJ_obj2nid(cms->contentType)) { - - case NID_pkcs7_signed: - return &cms->d.signedData->crls; - - case NID_pkcs7_enveloped: - if (cms->d.envelopedData->originatorInfo == NULL) - return NULL; - return &cms->d.envelopedData->originatorInfo->crls; - - default: - CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, - CMS_R_UNSUPPORTED_CONTENT_TYPE); - return NULL; - - } -} - -CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) -{ - STACK_OF(CMS_RevocationInfoChoice) **pcrls; - CMS_RevocationInfoChoice *rch; - pcrls = cms_get0_revocation_choices(cms); - if (!pcrls) - return NULL; - if (!*pcrls) - *pcrls = sk_CMS_RevocationInfoChoice_new_null(); - if (!*pcrls) - return NULL; - rch = M_ASN1_new_of(CMS_RevocationInfoChoice); - if (!rch) - return NULL; - if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { - M_ASN1_free_of(rch, CMS_RevocationInfoChoice); - return NULL; - } - return rch; -} - -int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) -{ - CMS_RevocationInfoChoice *rch; - rch = CMS_add0_RevocationInfoChoice(cms); - if (!rch) - return 0; - rch->type = CMS_REVCHOICE_CRL; - rch->d.crl = crl; - return 1; -} - -int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) -{ - int r; - r = CMS_add0_crl(cms, crl); - if (r > 0) - CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); - return r; -} - -STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) -{ - STACK_OF(X509) *certs = NULL; - CMS_CertificateChoices *cch; - STACK_OF(CMS_CertificateChoices) **pcerts; - int i; - pcerts = cms_get0_certificate_choices(cms); - if (!pcerts) - return NULL; - for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { - cch = sk_CMS_CertificateChoices_value(*pcerts, i); - if (cch->type == 0) { - if (!certs) { - certs = sk_X509_new_null(); - if (!certs) - return NULL; - } - if (!sk_X509_push(certs, cch->d.certificate)) { - sk_X509_pop_free(certs, X509_free); - return NULL; - } - CRYPTO_add(&cch->d.certificate->references, 1, CRYPTO_LOCK_X509); - } - } - return certs; - -} - -STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) -{ - STACK_OF(X509_CRL) *crls = NULL; - STACK_OF(CMS_RevocationInfoChoice) **pcrls; - CMS_RevocationInfoChoice *rch; - int i; - pcrls = cms_get0_revocation_choices(cms); - if (!pcrls) - return NULL; - for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { - rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); - if (rch->type == 0) { - if (!crls) { - crls = sk_X509_CRL_new_null(); - if (!crls) - return NULL; - } - if (!sk_X509_CRL_push(crls, rch->d.crl)) { - sk_X509_CRL_pop_free(crls, X509_CRL_free); - return NULL; - } - CRYPTO_add(&rch->d.crl->references, 1, CRYPTO_LOCK_X509_CRL); - } - } - return crls; -} - -int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert) -{ - int ret; - ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert)); - if (ret) - return ret; - return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert)); -} - -int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert) -{ - X509_check_purpose(cert, -1, -1); - if (!cert->skid) - return -1; - return ASN1_OCTET_STRING_cmp(keyid, cert->skid); -} - -int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert) -{ - CMS_IssuerAndSerialNumber *ias; - ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber); - if (!ias) - goto err; - if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert))) - goto err; - if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert))) - goto err; - if (*pias) - M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber); - *pias = ias; - return 1; - err: - if (ias) - M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber); - CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE); - return 0; -} - -int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert) -{ - ASN1_OCTET_STRING *keyid = NULL; - X509_check_purpose(cert, -1, -1); - if (!cert->skid) { - CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID); - return 0; - } - keyid = ASN1_STRING_dup(cert->skid); - if (!keyid) { - CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE); - return 0; - } - if (*pkeyid) - ASN1_OCTET_STRING_free(*pkeyid); - *pkeyid = keyid; - return 1; -} -/* crypto/cms/cms_pwri.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2009 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "pem.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -// #include "rand.h" -// #include "aes.h" -// #include "cms_lcl.h" -// #include "asn1_locl.h" - -int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, - unsigned char *pass, ossl_ssize_t passlen) -{ - CMS_PasswordRecipientInfo *pwri; - if (ri->type != CMS_RECIPINFO_PASS) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); - return 0; - } - - pwri = ri->d.pwri; - pwri->pass = pass; - if (pass && passlen < 0) - passlen = strlen((char *)pass); - pwri->passlen = passlen; - return 1; -} - -CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, - int iter, int wrap_nid, - int pbe_nid, - unsigned char *pass, - ossl_ssize_t passlen, - const EVP_CIPHER *kekciph) -{ - CMS_RecipientInfo *ri = NULL; - CMS_EnvelopedData *env; - CMS_PasswordRecipientInfo *pwri; - EVP_CIPHER_CTX ctx; - X509_ALGOR *encalg = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH]; - int ivlen; - - env = cms_get0_enveloped(cms); - if (!env) - return NULL; - - if (wrap_nid <= 0) - wrap_nid = NID_id_alg_PWRI_KEK; - - if (pbe_nid <= 0) - pbe_nid = NID_id_pbkdf2; - - /* Get from enveloped data */ - if (kekciph == NULL) - kekciph = env->encryptedContentInfo->cipher; - - if (kekciph == NULL) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); - return NULL; - } - if (wrap_nid != NID_id_alg_PWRI_KEK) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, - CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); - return NULL; - } - - /* Setup algorithm identifier for cipher */ - encalg = X509_ALGOR_new(); - if (encalg == NULL) { - goto merr; - } - EVP_CIPHER_CTX_init(&ctx); - - if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); - goto err; - } - - ivlen = EVP_CIPHER_CTX_iv_length(&ctx); - - if (ivlen > 0) { - if (RAND_bytes(iv, ivlen) <= 0) - goto err; - if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); - goto err; - } - encalg->parameter = ASN1_TYPE_new(); - if (!encalg->parameter) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); - goto err; - } - if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) { - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); - goto err; - } - } - - encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx)); - - EVP_CIPHER_CTX_cleanup(&ctx); - - /* Initialize recipient info */ - ri = M_ASN1_new_of(CMS_RecipientInfo); - if (!ri) - goto merr; - - ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo); - if (!ri->d.pwri) - goto merr; - ri->type = CMS_RECIPINFO_PASS; - - pwri = ri->d.pwri; - /* Since this is overwritten, free up empty structure already there */ - X509_ALGOR_free(pwri->keyEncryptionAlgorithm); - pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); - if (!pwri->keyEncryptionAlgorithm) - goto merr; - pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); - pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); - if (!pwri->keyEncryptionAlgorithm->parameter) - goto merr; - - if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), - &pwri->keyEncryptionAlgorithm->parameter-> - value.sequence)) - goto merr; - pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; - - X509_ALGOR_free(encalg); - encalg = NULL; - - /* Setup PBE algorithm */ - - pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); - - if (!pwri->keyDerivationAlgorithm) - goto err; - - CMS_RecipientInfo_set0_password(ri, pass, passlen); - pwri->version = 0; - - if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) - goto merr; - - return ri; - - merr: - CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); - err: - EVP_CIPHER_CTX_cleanup(&ctx); - if (ri) - M_ASN1_free_of(ri, CMS_RecipientInfo); - if (encalg) - X509_ALGOR_free(encalg); - return NULL; - -} - -/* - * This is an implementation of the key wrapping mechanism in RFC3211, at - * some point this should go into EVP. - */ - -static int kek_unwrap_key(unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen, - EVP_CIPHER_CTX *ctx) -{ - size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); - unsigned char *tmp; - int outl, rv = 0; - if (inlen < 2 * blocklen) { - /* too small */ - return 0; - } - if (inlen % blocklen) { - /* Invalid size */ - return 0; - } - tmp = OPENSSL_malloc(inlen); - if (!tmp) - return 0; - /* setup IV by decrypting last two blocks */ - EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, - in + inlen - 2 * blocklen, blocklen * 2); - /* - * Do a decrypt of last decrypted block to set IV to correct value output - * it to start of buffer so we don't corrupt decrypted block this works - * because buffer is at least two block lengths long. - */ - EVP_DecryptUpdate(ctx, tmp, &outl, tmp + inlen - blocklen, blocklen); - /* Can now decrypt first n - 1 blocks */ - EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen); - - /* Reset IV to original value */ - EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); - /* Decrypt again */ - EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen); - /* Check check bytes */ - if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) { - /* Check byte failure */ - goto err; - } - if (inlen < (size_t)(tmp[0] - 4)) { - /* Invalid length value */ - goto err; - } - *outlen = (size_t)tmp[0]; - memcpy(out, tmp + 4, *outlen); - rv = 1; - err: - OPENSSL_cleanse(tmp, inlen); - OPENSSL_free(tmp); - return rv; - -} - -static int kek_wrap_key(unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen, - EVP_CIPHER_CTX *ctx) -{ - size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); - size_t olen; - int dummy; - /* - * First decide length of output buffer: need header and round up to - * multiple of block length. - */ - olen = (inlen + 4 + blocklen - 1) / blocklen; - olen *= blocklen; - if (olen < 2 * blocklen) { - /* Key too small */ - return 0; - } - if (inlen > 0xFF) { - /* Key too large */ - return 0; - } - if (out) { - /* Set header */ - out[0] = (unsigned char)inlen; - out[1] = in[0] ^ 0xFF; - out[2] = in[1] ^ 0xFF; - out[3] = in[2] ^ 0xFF; - memcpy(out + 4, in, inlen); - /* Add random padding to end */ - if (olen > inlen + 4 - && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0) - return 0; - /* Encrypt twice */ - EVP_EncryptUpdate(ctx, out, &dummy, out, olen); - EVP_EncryptUpdate(ctx, out, &dummy, out, olen); - } - - *outlen = olen; - - return 1; -} - -/* Encrypt/Decrypt content key in PWRI recipient info */ - -int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - int en_de) -{ - CMS_EncryptedContentInfo *ec; - CMS_PasswordRecipientInfo *pwri; - const unsigned char *p = NULL; - int plen; - int r = 0; - X509_ALGOR *algtmp, *kekalg = NULL; - EVP_CIPHER_CTX kekctx; - const EVP_CIPHER *kekcipher; - unsigned char *key = NULL; - size_t keylen; - - ec = cms->d.envelopedData->encryptedContentInfo; - - pwri = ri->d.pwri; - EVP_CIPHER_CTX_init(&kekctx); - - if (!pwri->pass) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); - return 0; - } - algtmp = pwri->keyEncryptionAlgorithm; - - if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, - CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); - return 0; - } - - if (algtmp->parameter->type == V_ASN1_SEQUENCE) { - p = algtmp->parameter->value.sequence->data; - plen = algtmp->parameter->value.sequence->length; - kekalg = d2i_X509_ALGOR(NULL, &p, plen); - } - if (kekalg == NULL) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, - CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); - return 0; - } - - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); - - if (!kekcipher) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); - goto err; - } - - /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ - if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de)) - goto err; - EVP_CIPHER_CTX_set_padding(&kekctx, 0); - if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, - CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); - goto err; - } - - algtmp = pwri->keyDerivationAlgorithm; - - /* Finish password based key derivation to setup key in "ctx" */ - - if (EVP_PBE_CipherInit(algtmp->algorithm, - (char *)pwri->pass, pwri->passlen, - algtmp->parameter, &kekctx, en_de) < 0) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); - goto err; - } - - /* Finally wrap/unwrap the key */ - - if (en_de) { - - if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx)) - goto err; - - key = OPENSSL_malloc(keylen); - - if (!key) - goto err; - - if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx)) - goto err; - pwri->encryptedKey->data = key; - pwri->encryptedKey->length = keylen; - } else { - key = OPENSSL_malloc(pwri->encryptedKey->length); - - if (!key) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!kek_unwrap_key(key, &keylen, - pwri->encryptedKey->data, - pwri->encryptedKey->length, &kekctx)) { - CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); - goto err; - } - - ec->key = key; - ec->keylen = keylen; - - } - - r = 1; - - err: - - EVP_CIPHER_CTX_cleanup(&kekctx); - - if (!r && key) - OPENSSL_free(key); - X509_ALGOR_free(kekalg); - - return r; - -} -/* crypto/cms/cms_sd.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "pem.h" -// #include "x509.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -// #include "cms_lcl.h" -// #include "asn1_locl.h" - -/* CMS SignedData Utilities */ - -DECLARE_ASN1_ITEM(CMS_SignedData) - -static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms) -{ - if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { - CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); - return NULL; - } - return cms->d.signedData; -} - -static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) -{ - if (cms->d.other == NULL) { - cms->d.signedData = M_ASN1_new_of(CMS_SignedData); - if (!cms->d.signedData) { - CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); - return NULL; - } - cms->d.signedData->version = 1; - cms->d.signedData->encapContentInfo->eContentType = - OBJ_nid2obj(NID_pkcs7_data); - cms->d.signedData->encapContentInfo->partial = 1; - ASN1_OBJECT_free(cms->contentType); - cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); - return cms->d.signedData; - } - return cms_get0_signed(cms); -} - -/* Just initialize SignedData e.g. for certs only structure */ - -int CMS_SignedData_init(CMS_ContentInfo *cms) -{ - if (cms_signed_data_init(cms)) - return 1; - else - return 0; -} - -/* Check structures and fixup version numbers (if necessary) */ - -static void cms_sd_set_version(CMS_SignedData *sd) -{ - int i; - CMS_CertificateChoices *cch; - CMS_RevocationInfoChoice *rch; - CMS_SignerInfo *si; - - for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) { - cch = sk_CMS_CertificateChoices_value(sd->certificates, i); - if (cch->type == CMS_CERTCHOICE_OTHER) { - if (sd->version < 5) - sd->version = 5; - } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { - if (sd->version < 4) - sd->version = 4; - } else if (cch->type == CMS_CERTCHOICE_V1ACERT) { - if (sd->version < 3) - sd->version = 3; - } - } - - for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) { - rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); - if (rch->type == CMS_REVCHOICE_OTHER) { - if (sd->version < 5) - sd->version = 5; - } - } - - if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) - && (sd->version < 3)) - sd->version = 3; - - for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { - si = sk_CMS_SignerInfo_value(sd->signerInfos, i); - if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { - if (si->version < 3) - si->version = 3; - if (sd->version < 3) - sd->version = 3; - } else if (si->version < 1) - si->version = 1; - } - - if (sd->version < 1) - sd->version = 1; - -} - -/* Copy an existing messageDigest value */ - -static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) -{ - STACK_OF(CMS_SignerInfo) *sinfos; - CMS_SignerInfo *sitmp; - int i; - sinfos = CMS_get0_SignerInfos(cms); - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { - ASN1_OCTET_STRING *messageDigest; - sitmp = sk_CMS_SignerInfo_value(sinfos, i); - if (sitmp == si) - continue; - if (CMS_signed_get_attr_count(sitmp) < 0) - continue; - if (OBJ_cmp(si->digestAlgorithm->algorithm, - sitmp->digestAlgorithm->algorithm)) - continue; - messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, - OBJ_nid2obj - (NID_pkcs9_messageDigest), - -3, V_ASN1_OCTET_STRING); - if (!messageDigest) { - CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, - CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); - return 0; - } - - if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, - V_ASN1_OCTET_STRING, - messageDigest, -1)) - return 1; - else - return 0; - } - CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST); - return 0; -} - -int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) -{ - switch (type) { - case CMS_SIGNERINFO_ISSUER_SERIAL: - if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert)) - return 0; - break; - - case CMS_SIGNERINFO_KEYIDENTIFIER: - if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert)) - return 0; - break; - - default: - CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); - return 0; - } - - sid->type = type; - - return 1; -} - -int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, - ASN1_INTEGER **sno) -{ - if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { - if (issuer) - *issuer = sid->d.issuerAndSerialNumber->issuer; - if (sno) - *sno = sid->d.issuerAndSerialNumber->serialNumber; - } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { - if (keyid) - *keyid = sid->d.subjectKeyIdentifier; - } else - return 0; - return 1; -} - -int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) -{ - if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) - return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert); - else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) - return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert); - else - return -1; -} - -static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd) -{ - EVP_PKEY *pkey = si->pkey; - int i; - if (!pkey->ameth || !pkey->ameth->pkey_ctrl) - return 1; - i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si); - if (i == -2) { - CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - return 0; - } - if (i <= 0) { - CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE); - return 0; - } - return 1; -} - -CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, - X509 *signer, EVP_PKEY *pk, const EVP_MD *md, - unsigned int flags) -{ - CMS_SignedData *sd; - CMS_SignerInfo *si = NULL; - X509_ALGOR *alg; - int i, type; - if (!X509_check_private_key(signer, pk)) { - CMSerr(CMS_F_CMS_ADD1_SIGNER, - CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); - return NULL; - } - sd = cms_signed_data_init(cms); - if (!sd) - goto err; - si = M_ASN1_new_of(CMS_SignerInfo); - if (!si) - goto merr; - X509_check_purpose(signer, -1, -1); - - CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); - CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); - - si->pkey = pk; - si->signer = signer; - EVP_MD_CTX_init(&si->mctx); - si->pctx = NULL; - - if (flags & CMS_USE_KEYID) { - si->version = 3; - if (sd->version < 3) - sd->version = 3; - type = CMS_SIGNERINFO_KEYIDENTIFIER; - } else { - type = CMS_SIGNERINFO_ISSUER_SERIAL; - si->version = 1; - } - - if (!cms_set1_SignerIdentifier(si->sid, signer, type)) - goto err; - - if (md == NULL) { - int def_nid; - if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) - goto err; - md = EVP_get_digestbynid(def_nid); - if (md == NULL) { - CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); - goto err; - } - } - - if (!md) { - CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); - goto err; - } - - cms_DigestAlgorithm_set(si->digestAlgorithm, md); - - /* See if digest is present in digestAlgorithms */ - for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { - ASN1_OBJECT *aoid; - alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); - X509_ALGOR_get0(&aoid, NULL, NULL, alg); - if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) - break; - } - - if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { - alg = X509_ALGOR_new(); - if (!alg) - goto merr; - cms_DigestAlgorithm_set(alg, md); - if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { - X509_ALGOR_free(alg); - goto merr; - } - } - - if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) - goto err; - if (!(flags & CMS_NOATTR)) { - /* - * Initialialize signed attributes strutucture so other attributes - * such as signing time etc are added later even if we add none here. - */ - if (!si->signedAttrs) { - si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); - if (!si->signedAttrs) - goto merr; - } - - if (!(flags & CMS_NOSMIMECAP)) { - STACK_OF(X509_ALGOR) *smcap = NULL; - i = CMS_add_standard_smimecap(&smcap); - if (i) - i = CMS_add_smimecap(si, smcap); - sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); - if (!i) - goto merr; - } - if (flags & CMS_REUSE_DIGEST) { - if (!cms_copy_messageDigest(cms, si)) - goto err; - if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && - !CMS_SignerInfo_sign(si)) - goto err; - } - } - - if (!(flags & CMS_NOCERTS)) { - /* NB ignore -1 return for duplicate cert */ - if (!CMS_add1_cert(cms, signer)) - goto merr; - } - - if (flags & CMS_KEY_PARAM) { - if (flags & CMS_NOATTR) { - si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL); - if (!si->pctx) - goto err; - if (EVP_PKEY_sign_init(si->pctx) <= 0) - goto err; - if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0) - goto err; - } else if (EVP_DigestSignInit(&si->mctx, &si->pctx, md, NULL, pk) <= - 0) - goto err; - } - - if (!sd->signerInfos) - sd->signerInfos = sk_CMS_SignerInfo_new_null(); - if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) - goto merr; - - return si; - - merr: - CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); - err: - if (si) - M_ASN1_free_of(si, CMS_SignerInfo); - return NULL; - -} - -static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) -{ - ASN1_TIME *tt; - int r = 0; - if (t) - tt = t; - else - tt = X509_gmtime_adj(NULL, 0); - - if (!tt) - goto merr; - - if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, - tt->type, tt, -1) <= 0) - goto merr; - - r = 1; - - merr: - - if (!t) - ASN1_TIME_free(tt); - - if (!r) - CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE); - - return r; - -} - -EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si) -{ - return si->pctx; -} - -EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si) -{ - return &si->mctx; -} - -STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) -{ - CMS_SignedData *sd; - sd = cms_get0_signed(cms); - if (!sd) - return NULL; - return sd->signerInfos; -} - -STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) -{ - STACK_OF(X509) *signers = NULL; - STACK_OF(CMS_SignerInfo) *sinfos; - CMS_SignerInfo *si; - int i; - sinfos = CMS_get0_SignerInfos(cms); - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { - si = sk_CMS_SignerInfo_value(sinfos, i); - if (si->signer) { - if (!signers) { - signers = sk_X509_new_null(); - if (!signers) - return NULL; - } - if (!sk_X509_push(signers, si->signer)) { - sk_X509_free(signers); - return NULL; - } - } - } - return signers; -} - -void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) -{ - if (signer) { - CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); - if (si->pkey) - EVP_PKEY_free(si->pkey); - si->pkey = X509_get_pubkey(signer); - } - if (si->signer) - X509_free(si->signer); - si->signer = signer; -} - -int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, ASN1_INTEGER **sno) -{ - return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); -} - -int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) -{ - return cms_SignerIdentifier_cert_cmp(si->sid, cert); -} - -int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, - unsigned int flags) -{ - CMS_SignedData *sd; - CMS_SignerInfo *si; - CMS_CertificateChoices *cch; - STACK_OF(CMS_CertificateChoices) *certs; - X509 *x; - int i, j; - int ret = 0; - sd = cms_get0_signed(cms); - if (!sd) - return -1; - certs = sd->certificates; - for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { - si = sk_CMS_SignerInfo_value(sd->signerInfos, i); - if (si->signer) - continue; - - for (j = 0; j < sk_X509_num(scerts); j++) { - x = sk_X509_value(scerts, j); - if (CMS_SignerInfo_cert_cmp(si, x) == 0) { - CMS_SignerInfo_set1_signer_cert(si, x); - ret++; - break; - } - } - - if (si->signer || (flags & CMS_NOINTERN)) - continue; - - for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { - cch = sk_CMS_CertificateChoices_value(certs, j); - if (cch->type != 0) - continue; - x = cch->d.certificate; - if (CMS_SignerInfo_cert_cmp(si, x) == 0) { - CMS_SignerInfo_set1_signer_cert(si, x); - ret++; - break; - } - } - } - return ret; -} - -void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, - X509 **signer, X509_ALGOR **pdig, - X509_ALGOR **psig) -{ - if (pk) - *pk = si->pkey; - if (signer) - *signer = si->signer; - if (pdig) - *pdig = si->digestAlgorithm; - if (psig) - *psig = si->signatureAlgorithm; -} - -ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si) -{ - return si->signature; -} - -static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, - CMS_SignerInfo *si, BIO *chain) -{ - EVP_MD_CTX mctx; - int r = 0; - EVP_PKEY_CTX *pctx = NULL; - EVP_MD_CTX_init(&mctx); - - if (!si->pkey) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); - return 0; - } - - if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) - goto err; - /* Set SignerInfo algortihm details if we used custom parametsr */ - if (si->pctx && !cms_sd_asn1_ctrl(si, 0)) - goto err; - - /* - * If any signed attributes calculate and add messageDigest attribute - */ - - if (CMS_signed_get_attr_count(si) >= 0) { - ASN1_OBJECT *ctype = - cms->d.signedData->encapContentInfo->eContentType; - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int mdlen; - if (!EVP_DigestFinal_ex(&mctx, md, &mdlen)) - goto err; - if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, - V_ASN1_OCTET_STRING, md, mdlen)) - goto err; - /* Copy content type across */ - if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, - V_ASN1_OBJECT, ctype, -1) <= 0) - goto err; - if (!CMS_SignerInfo_sign(si)) - goto err; - } else if (si->pctx) { - unsigned char *sig; - size_t siglen; - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int mdlen; - pctx = si->pctx; - if (!EVP_DigestFinal_ex(&mctx, md, &mdlen)) - goto err; - siglen = EVP_PKEY_size(si->pkey); - sig = OPENSSL_malloc(siglen); - if (!sig) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) - goto err; - ASN1_STRING_set0(si->signature, sig, siglen); - } else { - unsigned char *sig; - unsigned int siglen; - sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); - if (!sig) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) { - CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR); - OPENSSL_free(sig); - goto err; - } - ASN1_STRING_set0(si->signature, sig, siglen); - } - - r = 1; - - err: - EVP_MD_CTX_cleanup(&mctx); - if (pctx) - EVP_PKEY_CTX_free(pctx); - return r; - -} - -int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) -{ - STACK_OF(CMS_SignerInfo) *sinfos; - CMS_SignerInfo *si; - int i; - sinfos = CMS_get0_SignerInfos(cms); - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { - si = sk_CMS_SignerInfo_value(sinfos, i); - if (!cms_SignerInfo_content_sign(cms, si, chain)) - return 0; - } - cms->d.signedData->encapContentInfo->partial = 0; - return 1; -} - -int CMS_SignerInfo_sign(CMS_SignerInfo *si) -{ - EVP_MD_CTX *mctx = &si->mctx; - EVP_PKEY_CTX *pctx; - unsigned char *abuf = NULL; - int alen; - size_t siglen; - const EVP_MD *md = NULL; - - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) - return 0; - - if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { - if (!cms_add1_signingTime(si, NULL)) - goto err; - } - - if (si->pctx) - pctx = si->pctx; - else { - EVP_MD_CTX_init(mctx); - if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0) - goto err; - } - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { - CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); - goto err; - } - - alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, - ASN1_ITEM_rptr(CMS_Attributes_Sign)); - if (!abuf) - goto err; - if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0) - goto err; - if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0) - goto err; - OPENSSL_free(abuf); - abuf = OPENSSL_malloc(siglen); - if (!abuf) - goto err; - if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0) - goto err; - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { - CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); - goto err; - } - - EVP_MD_CTX_cleanup(mctx); - - ASN1_STRING_set0(si->signature, abuf, siglen); - - return 1; - - err: - if (abuf) - OPENSSL_free(abuf); - EVP_MD_CTX_cleanup(mctx); - return 0; - -} - -int CMS_SignerInfo_verify(CMS_SignerInfo *si) -{ - EVP_MD_CTX *mctx = &si->mctx; - unsigned char *abuf = NULL; - int alen, r = -1; - const EVP_MD *md = NULL; - - if (!si->pkey) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); - return -1; - } - - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); - if (md == NULL) - return -1; - EVP_MD_CTX_init(mctx); - if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0) - goto err; - - if (!cms_sd_asn1_ctrl(si, 1)) - goto err; - - alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, - ASN1_ITEM_rptr(CMS_Attributes_Verify)); - if (!abuf) - goto err; - r = EVP_DigestVerifyUpdate(mctx, abuf, alen); - OPENSSL_free(abuf); - if (r <= 0) { - r = -1; - goto err; - } - r = EVP_DigestVerifyFinal(mctx, - si->signature->data, si->signature->length); - if (r <= 0) - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); - err: - EVP_MD_CTX_cleanup(mctx); - return r; -} - -/* Create a chain of digest BIOs from a CMS ContentInfo */ - -BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) -{ - int i; - CMS_SignedData *sd; - BIO *chain = NULL; - sd = cms_get0_signed(cms); - if (!sd) - return NULL; - if (cms->d.signedData->encapContentInfo->partial) - cms_sd_set_version(sd); - for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { - X509_ALGOR *digestAlgorithm; - BIO *mdbio; - digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); - mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); - if (!mdbio) - goto err; - if (chain) - BIO_push(chain, mdbio); - else - chain = mdbio; - } - return chain; - err: - if (chain) - BIO_free_all(chain); - return NULL; -} - -int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) -{ - ASN1_OCTET_STRING *os = NULL; - EVP_MD_CTX mctx; - EVP_PKEY_CTX *pkctx = NULL; - int r = -1; - unsigned char mval[EVP_MAX_MD_SIZE]; - unsigned int mlen; - EVP_MD_CTX_init(&mctx); - /* If we have any signed attributes look for messageDigest value */ - if (CMS_signed_get_attr_count(si) >= 0) { - os = CMS_signed_get0_data_by_OBJ(si, - OBJ_nid2obj(NID_pkcs9_messageDigest), - -3, V_ASN1_OCTET_STRING); - if (!os) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); - goto err; - } - } - - if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) - goto err; - - if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_UNABLE_TO_FINALIZE_CONTEXT); - goto err; - } - - /* If messageDigest found compare it */ - - if (os) { - if (mlen != (unsigned int)os->length) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); - goto err; - } - - if (memcmp(mval, os->data, mlen)) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_VERIFICATION_FAILURE); - r = 0; - } else - r = 1; - } else { - const EVP_MD *md = EVP_MD_CTX_md(&mctx); - pkctx = EVP_PKEY_CTX_new(si->pkey, NULL); - if (pkctx == NULL) - goto err; - if (EVP_PKEY_verify_init(pkctx) <= 0) - goto err; - if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0) - goto err; - si->pctx = pkctx; - if (!cms_sd_asn1_ctrl(si, 1)) - goto err; - r = EVP_PKEY_verify(pkctx, si->signature->data, - si->signature->length, mval, mlen); - if (r <= 0) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, - CMS_R_VERIFICATION_FAILURE); - r = 0; - } - } - - err: - if (pkctx) - EVP_PKEY_CTX_free(pkctx); - EVP_MD_CTX_cleanup(&mctx); - return r; - -} - -int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) -{ - unsigned char *smder = NULL; - int smderlen, r; - smderlen = i2d_X509_ALGORS(algs, &smder); - if (smderlen <= 0) - return 0; - r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, - V_ASN1_SEQUENCE, smder, smderlen); - OPENSSL_free(smder); - return r; -} - -int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, - int algnid, int keysize) -{ - X509_ALGOR *alg; - ASN1_INTEGER *key = NULL; - if (keysize > 0) { - key = ASN1_INTEGER_new(); - if (!key || !ASN1_INTEGER_set(key, keysize)) - return 0; - } - alg = X509_ALGOR_new(); - if (!alg) { - if (key) - ASN1_INTEGER_free(key); - return 0; - } - - X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), - key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); - if (!*algs) - *algs = sk_X509_ALGOR_new_null(); - if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) { - X509_ALGOR_free(alg); - return 0; - } - return 1; -} - -/* Check to see if a cipher exists and if so add S/MIME capabilities */ - -static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) -{ - if (EVP_get_cipherbynid(nid)) - return CMS_add_simple_smimecap(sk, nid, arg); - return 1; -} - -static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) -{ - if (EVP_get_digestbynid(nid)) - return CMS_add_simple_smimecap(sk, nid, arg); - return 1; -} - -int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) -{ - if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) - || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) - || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) - || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) - || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) - || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) - || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) - || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) - || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) - || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) - return 0; - return 1; -} -/* crypto/cms/cms_smime.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" -// #include "x509v3.h" -// #include "err.h" -// #include "cms.h" -// #include "cms_lcl.h" -// #include "asn1_locl.h" - -static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) -{ - unsigned char buf[4096]; - int r = 0, i; - BIO *tmpout = NULL; - - if (out == NULL) - tmpout = BIO_new(BIO_s_null()); - else if (flags & CMS_TEXT) { - tmpout = BIO_new(BIO_s_mem()); - BIO_set_mem_eof_return(tmpout, 0); - } else - tmpout = out; - - if (!tmpout) { - CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Read all content through chain to process digest, decrypt etc */ - for (;;) { - i = BIO_read(in, buf, sizeof(buf)); - if (i <= 0) { - if (BIO_method_type(in) == BIO_TYPE_CIPHER) { - if (!BIO_get_cipher_status(in)) - goto err; - } - if (i < 0) - goto err; - break; - } - - if (tmpout && (BIO_write(tmpout, buf, i) != i)) - goto err; - } - - if (flags & CMS_TEXT) { - if (!SMIME_text(tmpout, out)) { - CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR); - goto err; - } - } - - r = 1; - - err: - if (tmpout && (tmpout != out)) - BIO_free(tmpout); - return r; - -} - -static int check_content(CMS_ContentInfo *cms) -{ - ASN1_OCTET_STRING **pos = CMS_get0_content(cms); - if (!pos || !*pos) { - CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); - return 0; - } - return 1; -} - -static void do_free_upto(BIO *f, BIO *upto) -{ - if (upto) { - BIO *tbio; - do { - tbio = BIO_pop(f); - BIO_free(f); - f = tbio; - } - while (f && f != upto); - } else - BIO_free_all(f); -} - -int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) -{ - BIO *cont; - int r; - if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { - CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); - return 0; - } - cont = CMS_dataInit(cms, NULL); - if (!cont) - return 0; - r = cms_copy_content(out, cont, flags); - BIO_free_all(cont); - return r; -} - -CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) -{ - CMS_ContentInfo *cms; - cms = cms_Data_create(); - if (!cms) - return NULL; - - if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) - return cms; - - CMS_ContentInfo_free(cms); - - return NULL; -} - -int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, - unsigned int flags) -{ - BIO *cont; - int r; - if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { - CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); - return 0; - } - - if (!dcont && !check_content(cms)) - return 0; - - cont = CMS_dataInit(cms, dcont); - if (!cont) - return 0; - r = cms_copy_content(out, cont, flags); - if (r) - r = cms_DigestedData_do_final(cms, cont, 1); - do_free_upto(cont, dcont); - return r; -} - -CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, - unsigned int flags) -{ - CMS_ContentInfo *cms; - if (!md) - md = EVP_sha1(); - cms = cms_DigestedData_create(md); - if (!cms) - return NULL; - - if (!(flags & CMS_DETACHED)) - CMS_set_detached(cms, 0); - - if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) - return cms; - - CMS_ContentInfo_free(cms); - return NULL; -} - -int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, - const unsigned char *key, size_t keylen, - BIO *dcont, BIO *out, unsigned int flags) -{ - BIO *cont; - int r; - if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, - CMS_R_TYPE_NOT_ENCRYPTED_DATA); - return 0; - } - - if (!dcont && !check_content(cms)) - return 0; - - if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) - return 0; - cont = CMS_dataInit(cms, dcont); - if (!cont) - return 0; - r = cms_copy_content(out, cont, flags); - do_free_upto(cont, dcont); - return r; -} - -CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, - const unsigned char *key, - size_t keylen, unsigned int flags) -{ - CMS_ContentInfo *cms; - if (!cipher) { - CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); - return NULL; - } - cms = CMS_ContentInfo_new(); - if (!cms) - return NULL; - if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) - return NULL; - - if (!(flags & CMS_DETACHED)) - CMS_set_detached(cms, 0); - - if ((flags & (CMS_STREAM | CMS_PARTIAL)) - || CMS_final(cms, in, NULL, flags)) - return cms; - - CMS_ContentInfo_free(cms); - return NULL; -} - -static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, - X509_STORE *store, - STACK_OF(X509) *certs, - STACK_OF(X509_CRL) *crls, - unsigned int flags) -{ - X509_STORE_CTX ctx; - X509 *signer; - int i, j, r = 0; - CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); - if (!X509_STORE_CTX_init(&ctx, store, signer, certs)) { - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR); - goto err; - } - X509_STORE_CTX_set_default(&ctx, "smime_sign"); - if (crls) - X509_STORE_CTX_set0_crls(&ctx, crls); - - i = X509_verify_cert(&ctx); - if (i <= 0) { - j = X509_STORE_CTX_get_error(&ctx); - CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, - CMS_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(j)); - goto err; - } - r = 1; - err: - X509_STORE_CTX_cleanup(&ctx); - return r; - -} - -int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, - X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags) -{ - CMS_SignerInfo *si; - STACK_OF(CMS_SignerInfo) *sinfos; - STACK_OF(X509) *cms_certs = NULL; - STACK_OF(X509_CRL) *crls = NULL; - X509 *signer; - int i, scount = 0, ret = 0; - BIO *cmsbio = NULL, *tmpin = NULL; - - if (!dcont && !check_content(cms)) - return 0; - - /* Attempt to find all signer certificates */ - - sinfos = CMS_get0_SignerInfos(cms); - - if (sk_CMS_SignerInfo_num(sinfos) <= 0) { - CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS); - goto err; - } - - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { - si = sk_CMS_SignerInfo_value(sinfos, i); - CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); - if (signer) - scount++; - } - - if (scount != sk_CMS_SignerInfo_num(sinfos)) - scount += CMS_set1_signers_certs(cms, certs, flags); - - if (scount != sk_CMS_SignerInfo_num(sinfos)) { - CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); - goto err; - } - - /* Attempt to verify all signers certs */ - - if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { - cms_certs = CMS_get1_certs(cms); - if (!(flags & CMS_NOCRL)) - crls = CMS_get1_crls(cms); - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { - si = sk_CMS_SignerInfo_value(sinfos, i); - if (!cms_signerinfo_verify_cert(si, store, - cms_certs, crls, flags)) - goto err; - } - } - - /* Attempt to verify all SignerInfo signed attribute signatures */ - - if (!(flags & CMS_NO_ATTR_VERIFY)) { - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { - si = sk_CMS_SignerInfo_value(sinfos, i); - if (CMS_signed_get_attr_count(si) < 0) - continue; - if (CMS_SignerInfo_verify(si) <= 0) - goto err; - } - } - - /* - * Performance optimization: if the content is a memory BIO then store - * its contents in a temporary read only memory BIO. This avoids - * potentially large numbers of slow copies of data which will occur when - * reading from a read write memory BIO when signatures are calculated. - */ - - if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { - char *ptr; - long len; - len = BIO_get_mem_data(dcont, &ptr); - tmpin = BIO_new_mem_buf(ptr, len); - if (tmpin == NULL) { - CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); - goto err2; - } - } else - tmpin = dcont; - - cmsbio = CMS_dataInit(cms, tmpin); - if (!cmsbio) - goto err; - - if (!cms_copy_content(out, cmsbio, flags)) - goto err; - - if (!(flags & CMS_NO_CONTENT_VERIFY)) { - for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { - si = sk_CMS_SignerInfo_value(sinfos, i); - if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { - CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR); - goto err; - } - } - } - - ret = 1; - - err: - - if (dcont && (tmpin == dcont)) - do_free_upto(cmsbio, dcont); - else - BIO_free_all(cmsbio); - - err2: - if (cms_certs) - sk_X509_pop_free(cms_certs, X509_free); - if (crls) - sk_X509_CRL_pop_free(crls, X509_CRL_free); - - return ret; -} - -int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, - STACK_OF(X509) *certs, - X509_STORE *store, unsigned int flags) -{ - int r; - flags &= ~(CMS_DETACHED | CMS_TEXT); - r = CMS_verify(rcms, certs, store, NULL, NULL, flags); - if (r <= 0) - return r; - return cms_Receipt_verify(rcms, ocms); -} - -CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, - STACK_OF(X509) *certs, BIO *data, - unsigned int flags) -{ - CMS_ContentInfo *cms; - int i; - - cms = CMS_ContentInfo_new(); - if (!cms || !CMS_SignedData_init(cms)) - goto merr; - - if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { - CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); - goto err; - } - - for (i = 0; i < sk_X509_num(certs); i++) { - X509 *x = sk_X509_value(certs, i); - if (!CMS_add1_cert(cms, x)) - goto merr; - } - - if (!(flags & CMS_DETACHED)) - CMS_set_detached(cms, 0); - - if ((flags & (CMS_STREAM | CMS_PARTIAL)) - || CMS_final(cms, data, NULL, flags)) - return cms; - else - goto err; - - merr: - CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); - - err: - if (cms) - CMS_ContentInfo_free(cms); - return NULL; -} - -CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, - X509 *signcert, EVP_PKEY *pkey, - STACK_OF(X509) *certs, unsigned int flags) -{ - CMS_SignerInfo *rct_si; - CMS_ContentInfo *cms = NULL; - ASN1_OCTET_STRING **pos, *os; - BIO *rct_cont = NULL; - int r = 0; - - flags &= ~(CMS_STREAM | CMS_TEXT); - /* Not really detached but avoids content being allocated */ - flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED; - if (!pkey || !signcert) { - CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT); - return NULL; - } - - /* Initialize signed data */ - - cms = CMS_sign(NULL, NULL, certs, NULL, flags); - if (!cms) - goto err; - - /* Set inner content type to signed receipt */ - if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) - goto err; - - rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); - if (!rct_si) { - CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR); - goto err; - } - - os = cms_encode_Receipt(si); - - if (!os) - goto err; - - /* Set content to digest */ - rct_cont = BIO_new_mem_buf(os->data, os->length); - if (!rct_cont) - goto err; - - /* Add msgSigDigest attribute */ - - if (!cms_msgSigDigest_add1(rct_si, si)) - goto err; - - /* Finalize structure */ - if (!CMS_final(cms, rct_cont, NULL, flags)) - goto err; - - /* Set embedded content */ - pos = CMS_get0_content(cms); - *pos = os; - - r = 1; - - err: - if (rct_cont) - BIO_free(rct_cont); - if (r) - return cms; - CMS_ContentInfo_free(cms); - return NULL; - -} - -CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, - const EVP_CIPHER *cipher, unsigned int flags) -{ - CMS_ContentInfo *cms; - int i; - X509 *recip; - cms = CMS_EnvelopedData_create(cipher); - if (!cms) - goto merr; - for (i = 0; i < sk_X509_num(certs); i++) { - recip = sk_X509_value(certs, i); - if (!CMS_add1_recipient_cert(cms, recip, flags)) { - CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); - goto err; - } - } - - if (!(flags & CMS_DETACHED)) - CMS_set_detached(cms, 0); - - if ((flags & (CMS_STREAM | CMS_PARTIAL)) - || CMS_final(cms, data, NULL, flags)) - return cms; - else - goto err; - - merr: - CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); - err: - if (cms) - CMS_ContentInfo_free(cms); - return NULL; -} - -static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - EVP_PKEY *pk, X509 *cert) -{ - int i; - STACK_OF(CMS_RecipientEncryptedKey) *reks; - CMS_RecipientEncryptedKey *rek; - reks = CMS_RecipientInfo_kari_get0_reks(ri); - if (!cert) - return 0; - for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { - int rv; - rek = sk_CMS_RecipientEncryptedKey_value(reks, i); - if (CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) - continue; - CMS_RecipientInfo_kari_set0_pkey(ri, pk); - rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); - CMS_RecipientInfo_kari_set0_pkey(ri, NULL); - if (rv > 0) - return 1; - return -1; - } - return 0; -} - -int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) -{ - STACK_OF(CMS_RecipientInfo) *ris; - CMS_RecipientInfo *ri; - int i, r, ri_type; - int debug = 0, match_ri = 0; - ris = CMS_get0_RecipientInfos(cms); - if (ris) - debug = cms->d.envelopedData->encryptedContentInfo->debug; - ri_type = cms_pkey_get_ri_type(pk); - if (ri_type == CMS_RECIPINFO_NONE) { - CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, - CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - return 0; - } - - for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { - ri = sk_CMS_RecipientInfo_value(ris, i); - if (CMS_RecipientInfo_type(ri) != ri_type) - continue; - match_ri = 1; - if (ri_type == CMS_RECIPINFO_AGREE) { - r = cms_kari_set1_pkey(cms, ri, pk, cert); - if (r > 0) - return 1; - if (r < 0) - return 0; - } - /* - * If we have a cert try matching RecipientInfo otherwise try them - * all. - */ - else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { - CMS_RecipientInfo_set0_pkey(ri, pk); - r = CMS_RecipientInfo_decrypt(cms, ri); - CMS_RecipientInfo_set0_pkey(ri, NULL); - if (cert) { - /* - * If not debugging clear any error and return success to - * avoid leaking of information useful to MMA - */ - if (!debug) { - ERR_clear_error(); - return 1; - } - if (r > 0) - return 1; - CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR); - return 0; - } - /* - * If no cert and not debugging don't leave loop after first - * successful decrypt. Always attempt to decrypt all recipients - * to avoid leaking timing of a successful decrypt. - */ - else if (r > 0 && debug) - return 1; - } - } - /* If no cert and not debugging always return success */ - if (match_ri && !cert && !debug) { - ERR_clear_error(); - return 1; - } - - CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); - return 0; - -} - -int CMS_decrypt_set1_key(CMS_ContentInfo *cms, - unsigned char *key, size_t keylen, - unsigned char *id, size_t idlen) -{ - STACK_OF(CMS_RecipientInfo) *ris; - CMS_RecipientInfo *ri; - int i, r; - ris = CMS_get0_RecipientInfos(cms); - for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { - ri = sk_CMS_RecipientInfo_value(ris, i); - if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) - continue; - - /* - * If we have an id try matching RecipientInfo otherwise try them - * all. - */ - if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { - CMS_RecipientInfo_set0_key(ri, key, keylen); - r = CMS_RecipientInfo_decrypt(cms, ri); - CMS_RecipientInfo_set0_key(ri, NULL, 0); - if (r > 0) - return 1; - if (id) { - CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR); - return 0; - } - ERR_clear_error(); - } - } - - CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT); - return 0; - -} - -int CMS_decrypt_set1_password(CMS_ContentInfo *cms, - unsigned char *pass, ossl_ssize_t passlen) -{ - STACK_OF(CMS_RecipientInfo) *ris; - CMS_RecipientInfo *ri; - int i, r; - ris = CMS_get0_RecipientInfos(cms); - for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { - ri = sk_CMS_RecipientInfo_value(ris, i); - if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) - continue; - CMS_RecipientInfo_set0_password(ri, pass, passlen); - r = CMS_RecipientInfo_decrypt(cms, ri); - CMS_RecipientInfo_set0_password(ri, NULL, 0); - if (r > 0) - return 1; - } - - CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT); - return 0; - -} - -int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, - BIO *dcont, BIO *out, unsigned int flags) -{ - int r; - BIO *cont; - if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { - CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); - return 0; - } - if (!dcont && !check_content(cms)) - return 0; - if (flags & CMS_DEBUG_DECRYPT) - cms->d.envelopedData->encryptedContentInfo->debug = 1; - else - cms->d.envelopedData->encryptedContentInfo->debug = 0; - if (!pk && !cert && !dcont && !out) - return 1; - if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) - return 0; - cont = CMS_dataInit(cms, dcont); - if (!cont) - return 0; - r = cms_copy_content(out, cont, flags); - do_free_upto(cont, dcont); - return r; -} - -int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) -{ - BIO *cmsbio; - int ret = 0; - if (!(cmsbio = CMS_dataInit(cms, dcont))) { - CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB); - return 0; - } - - SMIME_crlf_copy(data, cmsbio, flags); - - (void)BIO_flush(cmsbio); - - if (!CMS_dataFinal(cms, cmsbio)) { - CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR); - goto err; - } - - ret = 1; - - err: - do_free_upto(cmsbio, dcont); - - return ret; - -} - -#ifdef ZLIB - -int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, - unsigned int flags) -{ - BIO *cont; - int r; - if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { - CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA); - return 0; - } - - if (!dcont && !check_content(cms)) - return 0; - - cont = CMS_dataInit(cms, dcont); - if (!cont) - return 0; - r = cms_copy_content(out, cont, flags); - do_free_upto(cont, dcont); - return r; -} - -CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) -{ - CMS_ContentInfo *cms; - if (comp_nid <= 0) - comp_nid = NID_zlib_compression; - cms = cms_CompressedData_create(comp_nid); - if (!cms) - return NULL; - - if (!(flags & CMS_DETACHED)) - CMS_set_detached(cms, 0); - - if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) - return cms; - - CMS_ContentInfo_free(cms); - return NULL; -} - -#else - -int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, - unsigned int flags) -{ - CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); - return 0; -} - -CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) -{ - CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); - return NULL; -} - -#endif diff --git a/Sources/COpenSSL/cms_lcl.h b/Sources/COpenSSL/cms_lcl.h deleted file mode 100644 index 537ec685..00000000 --- a/Sources/COpenSSL/cms_lcl.h +++ /dev/null @@ -1,471 +0,0 @@ -/* crypto/cms/cms_lcl.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#ifndef HEADER_CMS_LCL_H -# define HEADER_CMS_LCL_H - -#ifdef __cplusplus -extern "C" { -#endif - -# include "x509.h" - -/* - * Cryptographic message syntax (CMS) structures: taken from RFC3852 - */ - -/* Forward references */ - -typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber; -typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo; -typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier; -typedef struct CMS_SignedData_st CMS_SignedData; -typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat; -typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo; -typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo; -typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; -typedef struct CMS_DigestedData_st CMS_DigestedData; -typedef struct CMS_EncryptedData_st CMS_EncryptedData; -typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData; -typedef struct CMS_CompressedData_st CMS_CompressedData; -typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat; -typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo; -typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey; -typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey; -typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo; -typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier; -typedef struct CMS_KeyAgreeRecipientIdentifier_st - CMS_KeyAgreeRecipientIdentifier; -typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier; -typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo; -typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo; -typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo; -typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom; - -struct CMS_ContentInfo_st { - ASN1_OBJECT *contentType; - union { - ASN1_OCTET_STRING *data; - CMS_SignedData *signedData; - CMS_EnvelopedData *envelopedData; - CMS_DigestedData *digestedData; - CMS_EncryptedData *encryptedData; - CMS_AuthenticatedData *authenticatedData; - CMS_CompressedData *compressedData; - ASN1_TYPE *other; - /* Other types ... */ - void *otherData; - } d; -}; - -struct CMS_SignedData_st { - long version; - STACK_OF(X509_ALGOR) *digestAlgorithms; - CMS_EncapsulatedContentInfo *encapContentInfo; - STACK_OF(CMS_CertificateChoices) *certificates; - STACK_OF(CMS_RevocationInfoChoice) *crls; - STACK_OF(CMS_SignerInfo) *signerInfos; -}; - -struct CMS_EncapsulatedContentInfo_st { - ASN1_OBJECT *eContentType; - ASN1_OCTET_STRING *eContent; - /* Set to 1 if incomplete structure only part set up */ - int partial; -}; - -struct CMS_SignerInfo_st { - long version; - CMS_SignerIdentifier *sid; - X509_ALGOR *digestAlgorithm; - STACK_OF(X509_ATTRIBUTE) *signedAttrs; - X509_ALGOR *signatureAlgorithm; - ASN1_OCTET_STRING *signature; - STACK_OF(X509_ATTRIBUTE) *unsignedAttrs; - /* Signing certificate and key */ - X509 *signer; - EVP_PKEY *pkey; - /* Digest and public key context for alternative parameters */ - EVP_MD_CTX mctx; - EVP_PKEY_CTX *pctx; -}; - -struct CMS_SignerIdentifier_st { - int type; - union { - CMS_IssuerAndSerialNumber *issuerAndSerialNumber; - ASN1_OCTET_STRING *subjectKeyIdentifier; - } d; -}; - -struct CMS_EnvelopedData_st { - long version; - CMS_OriginatorInfo *originatorInfo; - STACK_OF(CMS_RecipientInfo) *recipientInfos; - CMS_EncryptedContentInfo *encryptedContentInfo; - STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; -}; - -struct CMS_OriginatorInfo_st { - STACK_OF(CMS_CertificateChoices) *certificates; - STACK_OF(CMS_RevocationInfoChoice) *crls; -}; - -struct CMS_EncryptedContentInfo_st { - ASN1_OBJECT *contentType; - X509_ALGOR *contentEncryptionAlgorithm; - ASN1_OCTET_STRING *encryptedContent; - /* Content encryption algorithm and key */ - const EVP_CIPHER *cipher; - unsigned char *key; - size_t keylen; - /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ - int debug; -}; - -struct CMS_RecipientInfo_st { - int type; - union { - CMS_KeyTransRecipientInfo *ktri; - CMS_KeyAgreeRecipientInfo *kari; - CMS_KEKRecipientInfo *kekri; - CMS_PasswordRecipientInfo *pwri; - CMS_OtherRecipientInfo *ori; - } d; -}; - -typedef CMS_SignerIdentifier CMS_RecipientIdentifier; - -struct CMS_KeyTransRecipientInfo_st { - long version; - CMS_RecipientIdentifier *rid; - X509_ALGOR *keyEncryptionAlgorithm; - ASN1_OCTET_STRING *encryptedKey; - /* Recipient Key and cert */ - X509 *recip; - EVP_PKEY *pkey; - /* Public key context for this operation */ - EVP_PKEY_CTX *pctx; -}; - -struct CMS_KeyAgreeRecipientInfo_st { - long version; - CMS_OriginatorIdentifierOrKey *originator; - ASN1_OCTET_STRING *ukm; - X509_ALGOR *keyEncryptionAlgorithm; - STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys; - /* Public key context associated with current operation */ - EVP_PKEY_CTX *pctx; - /* Cipher context for CEK wrapping */ - EVP_CIPHER_CTX ctx; -}; - -struct CMS_OriginatorIdentifierOrKey_st { - int type; - union { - CMS_IssuerAndSerialNumber *issuerAndSerialNumber; - ASN1_OCTET_STRING *subjectKeyIdentifier; - CMS_OriginatorPublicKey *originatorKey; - } d; -}; - -struct CMS_OriginatorPublicKey_st { - X509_ALGOR *algorithm; - ASN1_BIT_STRING *publicKey; -}; - -struct CMS_RecipientEncryptedKey_st { - CMS_KeyAgreeRecipientIdentifier *rid; - ASN1_OCTET_STRING *encryptedKey; - /* Public key associated with this recipient */ - EVP_PKEY *pkey; -}; - -struct CMS_KeyAgreeRecipientIdentifier_st { - int type; - union { - CMS_IssuerAndSerialNumber *issuerAndSerialNumber; - CMS_RecipientKeyIdentifier *rKeyId; - } d; -}; - -struct CMS_RecipientKeyIdentifier_st { - ASN1_OCTET_STRING *subjectKeyIdentifier; - ASN1_GENERALIZEDTIME *date; - CMS_OtherKeyAttribute *other; -}; - -struct CMS_KEKRecipientInfo_st { - long version; - CMS_KEKIdentifier *kekid; - X509_ALGOR *keyEncryptionAlgorithm; - ASN1_OCTET_STRING *encryptedKey; - /* Extra info: symmetric key to use */ - unsigned char *key; - size_t keylen; -}; - -struct CMS_KEKIdentifier_st { - ASN1_OCTET_STRING *keyIdentifier; - ASN1_GENERALIZEDTIME *date; - CMS_OtherKeyAttribute *other; -}; - -struct CMS_PasswordRecipientInfo_st { - long version; - X509_ALGOR *keyDerivationAlgorithm; - X509_ALGOR *keyEncryptionAlgorithm; - ASN1_OCTET_STRING *encryptedKey; - /* Extra info: password to use */ - unsigned char *pass; - size_t passlen; -}; - -struct CMS_OtherRecipientInfo_st { - ASN1_OBJECT *oriType; - ASN1_TYPE *oriValue; -}; - -struct CMS_DigestedData_st { - long version; - X509_ALGOR *digestAlgorithm; - CMS_EncapsulatedContentInfo *encapContentInfo; - ASN1_OCTET_STRING *digest; -}; - -struct CMS_EncryptedData_st { - long version; - CMS_EncryptedContentInfo *encryptedContentInfo; - STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; -}; - -struct CMS_AuthenticatedData_st { - long version; - CMS_OriginatorInfo *originatorInfo; - STACK_OF(CMS_RecipientInfo) *recipientInfos; - X509_ALGOR *macAlgorithm; - X509_ALGOR *digestAlgorithm; - CMS_EncapsulatedContentInfo *encapContentInfo; - STACK_OF(X509_ATTRIBUTE) *authAttrs; - ASN1_OCTET_STRING *mac; - STACK_OF(X509_ATTRIBUTE) *unauthAttrs; -}; - -struct CMS_CompressedData_st { - long version; - X509_ALGOR *compressionAlgorithm; - STACK_OF(CMS_RecipientInfo) *recipientInfos; - CMS_EncapsulatedContentInfo *encapContentInfo; -}; - -struct CMS_RevocationInfoChoice_st { - int type; - union { - X509_CRL *crl; - CMS_OtherRevocationInfoFormat *other; - } d; -}; - -# define CMS_REVCHOICE_CRL 0 -# define CMS_REVCHOICE_OTHER 1 - -struct CMS_OtherRevocationInfoFormat_st { - ASN1_OBJECT *otherRevInfoFormat; - ASN1_TYPE *otherRevInfo; -}; - -struct CMS_CertificateChoices { - int type; - union { - X509 *certificate; - ASN1_STRING *extendedCertificate; /* Obsolete */ - ASN1_STRING *v1AttrCert; /* Left encoded for now */ - ASN1_STRING *v2AttrCert; /* Left encoded for now */ - CMS_OtherCertificateFormat *other; - } d; -}; - -# define CMS_CERTCHOICE_CERT 0 -# define CMS_CERTCHOICE_EXCERT 1 -# define CMS_CERTCHOICE_V1ACERT 2 -# define CMS_CERTCHOICE_V2ACERT 3 -# define CMS_CERTCHOICE_OTHER 4 - -struct CMS_OtherCertificateFormat_st { - ASN1_OBJECT *otherCertFormat; - ASN1_TYPE *otherCert; -}; - -/* - * This is also defined in pkcs7.h but we duplicate it to allow the CMS code - * to be independent of PKCS#7 - */ - -struct CMS_IssuerAndSerialNumber_st { - X509_NAME *issuer; - ASN1_INTEGER *serialNumber; -}; - -struct CMS_OtherKeyAttribute_st { - ASN1_OBJECT *keyAttrId; - ASN1_TYPE *keyAttr; -}; - -/* ESS structures */ - -# ifdef HEADER_X509V3_H - -struct CMS_ReceiptRequest_st { - ASN1_OCTET_STRING *signedContentIdentifier; - CMS_ReceiptsFrom *receiptsFrom; - STACK_OF(GENERAL_NAMES) *receiptsTo; -}; - -struct CMS_ReceiptsFrom_st { - int type; - union { - long allOrFirstTier; - STACK_OF(GENERAL_NAMES) *receiptList; - } d; -}; -# endif - -struct CMS_Receipt_st { - long version; - ASN1_OBJECT *contentType; - ASN1_OCTET_STRING *signedContentIdentifier; - ASN1_OCTET_STRING *originatorSignatureValue; -}; - -DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) -DECLARE_ASN1_ITEM(CMS_SignerInfo) -DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) -DECLARE_ASN1_ITEM(CMS_Attributes_Sign) -DECLARE_ASN1_ITEM(CMS_Attributes_Verify) -DECLARE_ASN1_ITEM(CMS_RecipientInfo) -DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo) -DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber) - -# define CMS_SIGNERINFO_ISSUER_SERIAL 0 -# define CMS_SIGNERINFO_KEYIDENTIFIER 1 - -# define CMS_RECIPINFO_ISSUER_SERIAL 0 -# define CMS_RECIPINFO_KEYIDENTIFIER 1 - -# define CMS_REK_ISSUER_SERIAL 0 -# define CMS_REK_KEYIDENTIFIER 1 - -# define CMS_OIK_ISSUER_SERIAL 0 -# define CMS_OIK_KEYIDENTIFIER 1 -# define CMS_OIK_PUBKEY 2 - -BIO *cms_content_bio(CMS_ContentInfo *cms); - -CMS_ContentInfo *cms_Data_create(void); - -CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md); -BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms); -int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify); - -BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms); -int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); -int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, - int type); -int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, - ASN1_OCTET_STRING **keyid, - X509_NAME **issuer, - ASN1_INTEGER **sno); -int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert); - -CMS_ContentInfo *cms_CompressedData_create(int comp_nid); -BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms); - -void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md); -BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm); -int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, - X509_ALGOR *mdalg); - -int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert); -int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert); -int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert); -int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert); - -BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec); -BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms); -int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, - const EVP_CIPHER *cipher, - const unsigned char *key, size_t keylen); - -int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms); -int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); -ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); - -BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); -CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); -int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd); -int cms_pkey_get_ri_type(EVP_PKEY *pk); -/* KARI routines */ -int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip, - EVP_PKEY *pk, unsigned int flags); -int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms, - CMS_RecipientInfo *ri); - -/* PWRI routines */ -int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, - int en_de); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/comp.h b/Sources/COpenSSL/comp.h deleted file mode 100644 index f8af56a9..00000000 --- a/Sources/COpenSSL/comp.h +++ /dev/null @@ -1,83 +0,0 @@ - -#ifndef HEADER_COMP_H -# define HEADER_COMP_H - -# include "crypto.h" - -# ifdef OPENSSL_NO_COMP -# error COMP is disabled. -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct comp_ctx_st COMP_CTX; - -struct comp_method_st { - int type; /* NID for compression library */ - const char *name; /* A text string to identify the library */ - int (*init) (COMP_CTX *ctx); - void (*finish) (COMP_CTX *ctx); - int (*compress) (COMP_CTX *ctx, - unsigned char *out, unsigned int olen, - unsigned char *in, unsigned int ilen); - int (*expand) (COMP_CTX *ctx, - unsigned char *out, unsigned int olen, - unsigned char *in, unsigned int ilen); - /* - * The following two do NOTHING, but are kept for backward compatibility - */ - long (*ctrl) (void); - long (*callback_ctrl) (void); -}; - -struct comp_ctx_st { - COMP_METHOD *meth; - unsigned long compress_in; - unsigned long compress_out; - unsigned long expand_in; - unsigned long expand_out; - CRYPTO_EX_DATA ex_data; -}; - -COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); -void COMP_CTX_free(COMP_CTX *ctx); -int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, - unsigned char *in, int ilen); -int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, - unsigned char *in, int ilen); -COMP_METHOD *COMP_rle(void); -COMP_METHOD *COMP_zlib(void); -void COMP_zlib_cleanup(void); - -# ifdef HEADER_BIO_H -# ifdef ZLIB -BIO_METHOD *BIO_f_zlib(void); -# endif -# endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_COMP_strings(void); - -/* Error codes for the COMP functions. */ - -/* Function codes. */ -# define COMP_F_BIO_ZLIB_FLUSH 99 -# define COMP_F_BIO_ZLIB_NEW 100 -# define COMP_F_BIO_ZLIB_READ 101 -# define COMP_F_BIO_ZLIB_WRITE 102 - -/* Reason codes. */ -# define COMP_R_ZLIB_DEFLATE_ERROR 99 -# define COMP_R_ZLIB_INFLATE_ERROR 100 -# define COMP_R_ZLIB_NOT_SUPPORTED 101 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/comp_.c b/Sources/COpenSSL/comp_.c deleted file mode 100644 index ee710ecb..00000000 --- a/Sources/COpenSSL/comp_.c +++ /dev/null @@ -1,164 +0,0 @@ -/* crypto/comp/comp_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "comp.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason) - -static ERR_STRING_DATA COMP_str_functs[] = { - {ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH), "BIO_ZLIB_FLUSH"}, - {ERR_FUNC(COMP_F_BIO_ZLIB_NEW), "BIO_ZLIB_NEW"}, - {ERR_FUNC(COMP_F_BIO_ZLIB_READ), "BIO_ZLIB_READ"}, - {ERR_FUNC(COMP_F_BIO_ZLIB_WRITE), "BIO_ZLIB_WRITE"}, - {0, NULL} -}; - -static ERR_STRING_DATA COMP_str_reasons[] = { - {ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR), "zlib deflate error"}, - {ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR), "zlib inflate error"}, - {ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED), "zlib not supported"}, - {0, NULL} -}; - -#endif - -void ERR_load_COMP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) { - ERR_load_strings(0, COMP_str_functs); - ERR_load_strings(0, COMP_str_reasons); - } -#endif -} -#include -#include -#include -#include "objects.h" -// #include "comp.h" - -COMP_CTX *COMP_CTX_new(COMP_METHOD *meth) -{ - COMP_CTX *ret; - - if ((ret = (COMP_CTX *)OPENSSL_malloc(sizeof(COMP_CTX))) == NULL) { - /* ZZZZZZZZZZZZZZZZ */ - return (NULL); - } - memset(ret, 0, sizeof(COMP_CTX)); - ret->meth = meth; - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - OPENSSL_free(ret); - ret = NULL; - } - return (ret); -} - -void COMP_CTX_free(COMP_CTX *ctx) -{ - if (ctx == NULL) - return; - - if (ctx->meth->finish != NULL) - ctx->meth->finish(ctx); - - OPENSSL_free(ctx); -} - -int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, - unsigned char *in, int ilen) -{ - int ret; - if (ctx->meth->compress == NULL) { - /* ZZZZZZZZZZZZZZZZZ */ - return (-1); - } - ret = ctx->meth->compress(ctx, out, olen, in, ilen); - if (ret > 0) { - ctx->compress_in += ilen; - ctx->compress_out += ret; - } - return (ret); -} - -int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, - unsigned char *in, int ilen) -{ - int ret; - - if (ctx->meth->expand == NULL) { - /* ZZZZZZZZZZZZZZZZZ */ - return (-1); - } - ret = ctx->meth->expand(ctx, out, olen, in, ilen); - if (ret > 0) { - ctx->expand_in += ilen; - ctx->expand_out += ret; - } - return (ret); -} diff --git a/Sources/COpenSSL/conf.h b/Sources/COpenSSL/conf.h deleted file mode 100644 index a7ded85c..00000000 --- a/Sources/COpenSSL/conf.h +++ /dev/null @@ -1,268 +0,0 @@ -/* crypto/conf/conf.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_CONF_H -# define HEADER_CONF_H - -# include "bio.h" -# include "lhash.h" -# include "stack.h" -# include "safestack.h" -# include "e_os2.h" - -# include "ossl_typ.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - char *section; - char *name; - char *value; -} CONF_VALUE; - -DECLARE_STACK_OF(CONF_VALUE) -DECLARE_LHASH_OF(CONF_VALUE); - -struct conf_st; -struct conf_method_st; -typedef struct conf_method_st CONF_METHOD; - -struct conf_method_st { - const char *name; - CONF *(*create) (CONF_METHOD *meth); - int (*init) (CONF *conf); - int (*destroy) (CONF *conf); - int (*destroy_data) (CONF *conf); - int (*load_bio) (CONF *conf, BIO *bp, long *eline); - int (*dump) (const CONF *conf, BIO *bp); - int (*is_number) (const CONF *conf, char c); - int (*to_int) (const CONF *conf, char c); - int (*load) (CONF *conf, const char *name, long *eline); -}; - -/* Module definitions */ - -typedef struct conf_imodule_st CONF_IMODULE; -typedef struct conf_module_st CONF_MODULE; - -DECLARE_STACK_OF(CONF_MODULE) -DECLARE_STACK_OF(CONF_IMODULE) - -/* DSO module function typedefs */ -typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf); -typedef void conf_finish_func (CONF_IMODULE *md); - -# define CONF_MFLAGS_IGNORE_ERRORS 0x1 -# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 -# define CONF_MFLAGS_SILENT 0x4 -# define CONF_MFLAGS_NO_DSO 0x8 -# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 -# define CONF_MFLAGS_DEFAULT_SECTION 0x20 - -int CONF_set_default_method(CONF_METHOD *meth); -void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); -LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, - long *eline); -# ifndef OPENSSL_NO_FP_API -LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, - long *eline); -# endif -LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, - long *eline); -STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, - const char *section); -char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, - const char *name); -long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, - const char *name); -void CONF_free(LHASH_OF(CONF_VALUE) *conf); -int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); -int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); - -void OPENSSL_config(const char *config_name); -void OPENSSL_no_config(void); - -/* - * New conf code. The semantics are different from the functions above. If - * that wasn't the case, the above functions would have been replaced - */ - -struct conf_st { - CONF_METHOD *meth; - void *meth_data; - LHASH_OF(CONF_VALUE) *data; -}; - -CONF *NCONF_new(CONF_METHOD *meth); -CONF_METHOD *NCONF_default(void); -CONF_METHOD *NCONF_WIN32(void); -# if 0 /* Just to give you an idea of what I have in - * mind */ -CONF_METHOD *NCONF_XML(void); -# endif -void NCONF_free(CONF *conf); -void NCONF_free_data(CONF *conf); - -int NCONF_load(CONF *conf, const char *file, long *eline); -# ifndef OPENSSL_NO_FP_API -int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); -# endif -int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); -STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, - const char *section); -char *NCONF_get_string(const CONF *conf, const char *group, const char *name); -int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, - long *result); -int NCONF_dump_fp(const CONF *conf, FILE *out); -int NCONF_dump_bio(const CONF *conf, BIO *out); - -# if 0 /* The following function has no error - * checking, and should therefore be avoided */ -long NCONF_get_number(CONF *conf, char *group, char *name); -# else -# define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) -# endif - -/* Module functions */ - -int CONF_modules_load(const CONF *cnf, const char *appname, - unsigned long flags); -int CONF_modules_load_file(const char *filename, const char *appname, - unsigned long flags); -void CONF_modules_unload(int all); -void CONF_modules_finish(void); -void CONF_modules_free(void); -int CONF_module_add(const char *name, conf_init_func *ifunc, - conf_finish_func *ffunc); - -const char *CONF_imodule_get_name(const CONF_IMODULE *md); -const char *CONF_imodule_get_value(const CONF_IMODULE *md); -void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); -void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); -CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); -unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); -void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); -void *CONF_module_get_usr_data(CONF_MODULE *pmod); -void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); - -char *CONF_get1_default_config_file(void); - -int CONF_parse_list(const char *list, int sep, int nospc, - int (*list_cb) (const char *elem, int len, void *usr), - void *arg); - -void OPENSSL_load_builtin_modules(void); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_CONF_strings(void); - -/* Error codes for the CONF functions. */ - -/* Function codes. */ -# define CONF_F_CONF_DUMP_FP 104 -# define CONF_F_CONF_LOAD 100 -# define CONF_F_CONF_LOAD_BIO 102 -# define CONF_F_CONF_LOAD_FP 103 -# define CONF_F_CONF_MODULES_LOAD 116 -# define CONF_F_CONF_PARSE_LIST 119 -# define CONF_F_DEF_LOAD 120 -# define CONF_F_DEF_LOAD_BIO 121 -# define CONF_F_MODULE_INIT 115 -# define CONF_F_MODULE_LOAD_DSO 117 -# define CONF_F_MODULE_RUN 118 -# define CONF_F_NCONF_DUMP_BIO 105 -# define CONF_F_NCONF_DUMP_FP 106 -# define CONF_F_NCONF_GET_NUMBER 107 -# define CONF_F_NCONF_GET_NUMBER_E 112 -# define CONF_F_NCONF_GET_SECTION 108 -# define CONF_F_NCONF_GET_STRING 109 -# define CONF_F_NCONF_LOAD 113 -# define CONF_F_NCONF_LOAD_BIO 110 -# define CONF_F_NCONF_LOAD_FP 114 -# define CONF_F_NCONF_NEW 111 -# define CONF_F_STR_COPY 101 - -/* Reason codes. */ -# define CONF_R_ERROR_LOADING_DSO 110 -# define CONF_R_LIST_CANNOT_BE_NULL 115 -# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 -# define CONF_R_MISSING_EQUAL_SIGN 101 -# define CONF_R_MISSING_FINISH_FUNCTION 111 -# define CONF_R_MISSING_INIT_FUNCTION 112 -# define CONF_R_MODULE_INITIALIZATION_ERROR 109 -# define CONF_R_NO_CLOSE_BRACE 102 -# define CONF_R_NO_CONF 105 -# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 -# define CONF_R_NO_SECTION 107 -# define CONF_R_NO_SUCH_FILE 114 -# define CONF_R_NO_VALUE 108 -# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 -# define CONF_R_UNKNOWN_MODULE_NAME 113 -# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 -# define CONF_R_VARIABLE_HAS_NO_VALUE 104 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/conf_.c b/Sources/COpenSSL/conf_.c deleted file mode 100644 index 1548dd8c..00000000 --- a/Sources/COpenSSL/conf_.c +++ /dev/null @@ -1,2334 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* conf_api.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* Part of the code in here was originally in conf.c, which is now removed */ - -#ifndef CONF_DEBUG -# undef NDEBUG /* avoid conflicting definitions */ -# define NDEBUG -#endif - -#include -#include -#include -#include "cryptlib.h" -#include "conf.h" -#include "conf_api.h" -#include "e_os.h" - -static void value_free_hash_doall_arg(CONF_VALUE *a, - LHASH_OF(CONF_VALUE) *conf); -static void value_free_stack_doall(CONF_VALUE *a); -static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE, - LHASH_OF(CONF_VALUE)) -static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE) - -/* Up until OpenSSL 0.9.5a, this was get_section */ -CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) -{ - CONF_VALUE *v, vv; - - if ((conf == NULL) || (section == NULL)) - return (NULL); - vv.name = NULL; - vv.section = (char *)section; - v = lh_CONF_VALUE_retrieve(conf->data, &vv); - return (v); -} - -/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ -STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, - const char *section) -{ - CONF_VALUE *v; - - v = _CONF_get_section(conf, section); - if (v != NULL) - return ((STACK_OF(CONF_VALUE) *)v->value); - else - return (NULL); -} - -int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) -{ - CONF_VALUE *v = NULL; - STACK_OF(CONF_VALUE) *ts; - - ts = (STACK_OF(CONF_VALUE) *)section->value; - - value->section = section->section; - if (!sk_CONF_VALUE_push(ts, value)) { - return 0; - } - - v = lh_CONF_VALUE_insert(conf->data, value); - if (v != NULL) { - (void)sk_CONF_VALUE_delete_ptr(ts, v); - OPENSSL_free(v->name); - OPENSSL_free(v->value); - OPENSSL_free(v); - } - return 1; -} - -char *_CONF_get_string(const CONF *conf, const char *section, - const char *name) -{ - CONF_VALUE *v, vv; - char *p; - - if (name == NULL) - return (NULL); - if (conf != NULL) { - if (section != NULL) { - vv.name = (char *)name; - vv.section = (char *)section; - v = lh_CONF_VALUE_retrieve(conf->data, &vv); - if (v != NULL) - return (v->value); - if (strcmp(section, "ENV") == 0) { - p = ossl_safe_getenv(name); - if (p != NULL) - return (p); - } - } - vv.section = "default"; - vv.name = (char *)name; - v = lh_CONF_VALUE_retrieve(conf->data, &vv); - if (v != NULL) - return (v->value); - else - return (NULL); - } else - return (ossl_safe_getenv(name)); -} - -#if 0 /* There's no way to provide error checking - * with this function, so force implementors - * of the higher levels to get a string and - * read the number themselves. */ -long _CONF_get_number(CONF *conf, char *section, char *name) -{ - char *str; - long ret = 0; - - str = _CONF_get_string(conf, section, name); - if (str == NULL) - return (0); - for (;;) { - if (conf->meth->is_number(conf, *str)) - ret = ret * 10 + conf->meth->to_int(conf, *str); - else - return (ret); - str++; - } -} -#endif - -static unsigned long conf_value_hash(const CONF_VALUE *v) -{ - return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); -} - -static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) - -static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) -{ - int i; - - if (a->section != b->section) { - i = strcmp(a->section, b->section); - if (i) - return (i); - } - - if ((a->name != NULL) && (b->name != NULL)) { - i = strcmp(a->name, b->name); - return (i); - } else if (a->name == b->name) - return (0); - else - return ((a->name == NULL) ? -1 : 1); -} - -static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) - -int _CONF_new_data(CONF *conf) -{ - if (conf == NULL) { - return 0; - } - if (conf->data == NULL) - if ((conf->data = lh_CONF_VALUE_new()) == NULL) { - return 0; - } - return 1; -} - -void _CONF_free_data(CONF *conf) -{ - if (conf == NULL || conf->data == NULL) - return; - - lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make * sure the - * 'OPENSSL_free()' works as * - * expected */ - lh_CONF_VALUE_doall_arg(conf->data, - LHASH_DOALL_ARG_FN(value_free_hash), - LHASH_OF(CONF_VALUE), conf->data); - - /* - * We now have only 'section' entries in the hash table. Due to problems - * with - */ - - lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); - lh_CONF_VALUE_free(conf->data); -} - -static void value_free_hash_doall_arg(CONF_VALUE *a, - LHASH_OF(CONF_VALUE) *conf) -{ - if (a->name != NULL) - (void)lh_CONF_VALUE_delete(conf, a); -} - -static void value_free_stack_doall(CONF_VALUE *a) -{ - CONF_VALUE *vv; - STACK_OF(CONF_VALUE) *sk; - int i; - - if (a->name != NULL) - return; - - sk = (STACK_OF(CONF_VALUE) *)a->value; - for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { - vv = sk_CONF_VALUE_value(sk, i); - OPENSSL_free(vv->value); - OPENSSL_free(vv->name); - OPENSSL_free(vv); - } - if (sk != NULL) - sk_CONF_VALUE_free(sk); - OPENSSL_free(a->section); - OPENSSL_free(a); -} - -/* Up until OpenSSL 0.9.5a, this was new_section */ -CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) -{ - STACK_OF(CONF_VALUE) *sk = NULL; - int ok = 0, i; - CONF_VALUE *v = NULL, *vv; - - if ((sk = sk_CONF_VALUE_new_null()) == NULL) - goto err; - if ((v = OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) - goto err; - i = strlen(section) + 1; - if ((v->section = OPENSSL_malloc(i)) == NULL) - goto err; - - memcpy(v->section, section, i); - v->name = NULL; - v->value = (char *)sk; - - vv = lh_CONF_VALUE_insert(conf->data, v); - OPENSSL_assert(vv == NULL); - if (lh_CONF_VALUE_error(conf->data) > 0) - goto err; - ok = 1; - err: - if (!ok) { - if (sk != NULL) - sk_CONF_VALUE_free(sk); - if (v != NULL) - OPENSSL_free(v); - v = NULL; - } - return (v); -} - -IMPLEMENT_STACK_OF(CONF_VALUE) -/* crypto/conf/conf.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* Part of the code in here was originally in conf.c, which is now removed */ - -#include -#include -// #include "cryptlib.h" -#include "stack.h" -#include "lhash.h" -// #include "conf.h" -// #include "conf_api.h" -#include "conf_def.h" -#include "buffer.h" -#include "err.h" - -/* - * The maximum length we can grow a value to after variable expansion. 64k - * should be more than enough for all reasonable uses. - */ -#define MAX_CONF_VALUE_LENGTH 65536 - -static char *eat_ws(CONF *conf, char *p); -static char *eat_alpha_numeric(CONF *conf, char *p); -static void clear_comments(CONF *conf, char *p); -static int str_copy(CONF *conf, char *section, char **to, char *from); -static char *scan_quote(CONF *conf, char *p); -static char *scan_dquote(CONF *conf, char *p); -#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) - -static CONF *def_create(CONF_METHOD *meth); -static int def_init_default(CONF *conf); -static int def_init_WIN32(CONF *conf); -static int def_destroy(CONF *conf); -static int def_destroy_data(CONF *conf); -static int def_load(CONF *conf, const char *name, long *eline); -static int def_load_bio(CONF *conf, BIO *bp, long *eline); -static int def_dump(const CONF *conf, BIO *bp); -static int def_is_number(const CONF *conf, char c); -static int def_to_int(const CONF *conf, char c); - -const char CONF_def_version[] = "CONF_def" OPENSSL_VERSION_PTEXT; - -static CONF_METHOD default_method = { - "OpenSSL default", - def_create, - def_init_default, - def_destroy, - def_destroy_data, - def_load_bio, - def_dump, - def_is_number, - def_to_int, - def_load -}; - -static CONF_METHOD WIN32_method = { - "WIN32", - def_create, - def_init_WIN32, - def_destroy, - def_destroy_data, - def_load_bio, - def_dump, - def_is_number, - def_to_int, - def_load -}; - -CONF_METHOD *NCONF_default() -{ - return &default_method; -} - -CONF_METHOD *NCONF_WIN32() -{ - return &WIN32_method; -} - -static CONF *def_create(CONF_METHOD *meth) -{ - CONF *ret; - - ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); - if (ret) - if (meth->init(ret) == 0) { - OPENSSL_free(ret); - ret = NULL; - } - return ret; -} - -static int def_init_default(CONF *conf) -{ - if (conf == NULL) - return 0; - - conf->meth = &default_method; - conf->meth_data = CONF_type_default; - conf->data = NULL; - - return 1; -} - -static int def_init_WIN32(CONF *conf) -{ - if (conf == NULL) - return 0; - - conf->meth = &WIN32_method; - conf->meth_data = (void *)CONF_type_win32; - conf->data = NULL; - - return 1; -} - -static int def_destroy(CONF *conf) -{ - if (def_destroy_data(conf)) { - OPENSSL_free(conf); - return 1; - } - return 0; -} - -static int def_destroy_data(CONF *conf) -{ - if (conf == NULL) - return 0; - _CONF_free_data(conf); - return 1; -} - -static int def_load(CONF *conf, const char *name, long *line) -{ - int ret; - BIO *in = NULL; - -#ifdef OPENSSL_SYS_VMS - in = BIO_new_file(name, "r"); -#else - in = BIO_new_file(name, "rb"); -#endif - if (in == NULL) { - if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) - CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE); - else - CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB); - return 0; - } - - ret = def_load_bio(conf, in, line); - BIO_free(in); - - return ret; -} - -static int def_load_bio(CONF *conf, BIO *in, long *line) -{ -/* The macro BUFSIZE conflicts with a system macro in VxWorks */ -#define CONFBUFSIZE 512 - int bufnum = 0, i, ii; - BUF_MEM *buff = NULL; - char *s, *p, *end; - int again; - long eline = 0; - char btmp[DECIMAL_SIZE(eline) + 1]; - CONF_VALUE *v = NULL, *tv; - CONF_VALUE *sv = NULL; - char *section = NULL, *buf; - char *start, *psection, *pname; - void *h = (void *)(conf->data); - - if ((buff = BUF_MEM_new()) == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); - goto err; - } - - section = BUF_strdup("default"); - if (section == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (_CONF_new_data(conf) == 0) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - - sv = _CONF_new_section(conf, section); - if (sv == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); - goto err; - } - - bufnum = 0; - again = 0; - for (;;) { - if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); - goto err; - } - p = &(buff->data[bufnum]); - *p = '\0'; - BIO_gets(in, p, CONFBUFSIZE - 1); - p[CONFBUFSIZE - 1] = '\0'; - ii = i = strlen(p); - if (i == 0 && !again) - break; - again = 0; - while (i > 0) { - if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) - break; - else - i--; - } - /* - * we removed some trailing stuff so there is a new line on the end. - */ - if (ii && i == ii) - again = 1; /* long line */ - else { - p[i] = '\0'; - eline++; /* another input line */ - } - - /* we now have a line with trailing \r\n removed */ - - /* i is the number of bytes */ - bufnum += i; - - v = NULL; - /* check for line continuation */ - if (bufnum >= 1) { - /* - * If we have bytes and the last char '\\' and second last char - * is not '\\' - */ - p = &(buff->data[bufnum - 1]); - if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { - bufnum--; - again = 1; - } - } - if (again) - continue; - bufnum = 0; - buf = buff->data; - - clear_comments(conf, buf); - s = eat_ws(conf, buf); - if (IS_EOF(conf, *s)) - continue; /* blank line */ - if (*s == '[') { - char *ss; - - s++; - start = eat_ws(conf, s); - ss = start; - again: - end = eat_alpha_numeric(conf, ss); - p = eat_ws(conf, end); - if (*p != ']') { - if (*p != '\0' && ss != p) { - ss = p; - goto again; - } - CONFerr(CONF_F_DEF_LOAD_BIO, - CONF_R_MISSING_CLOSE_SQUARE_BRACKET); - goto err; - } - *end = '\0'; - if (!str_copy(conf, NULL, §ion, start)) - goto err; - if ((sv = _CONF_get_section(conf, section)) == NULL) - sv = _CONF_new_section(conf, section); - if (sv == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, - CONF_R_UNABLE_TO_CREATE_NEW_SECTION); - goto err; - } - continue; - } else { - pname = s; - psection = NULL; - end = eat_alpha_numeric(conf, s); - if ((end[0] == ':') && (end[1] == ':')) { - *end = '\0'; - end += 2; - psection = pname; - pname = end; - end = eat_alpha_numeric(conf, end); - } - p = eat_ws(conf, end); - if (*p != '=') { - CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); - goto err; - } - *end = '\0'; - p++; - start = eat_ws(conf, p); - while (!IS_EOF(conf, *p)) - p++; - p--; - while ((p != start) && (IS_WS(conf, *p))) - p--; - p++; - *p = '\0'; - - if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - if (psection == NULL) - psection = section; - v->name = (char *)OPENSSL_malloc(strlen(pname) + 1); - v->value = NULL; - if (v->name == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - BUF_strlcpy(v->name, pname, strlen(pname) + 1); - if (!str_copy(conf, psection, &(v->value), start)) - goto err; - - if (strcmp(psection, section) != 0) { - if ((tv = _CONF_get_section(conf, psection)) - == NULL) - tv = _CONF_new_section(conf, psection); - if (tv == NULL) { - CONFerr(CONF_F_DEF_LOAD_BIO, - CONF_R_UNABLE_TO_CREATE_NEW_SECTION); - goto err; - } - } else - tv = sv; -#if 1 - if (_CONF_add_string(conf, tv, v) == 0) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } -#else - v->section = tv->section; - if (!sk_CONF_VALUE_push(ts, v)) { - CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - vv = (CONF_VALUE *)lh_insert(conf->data, v); - if (vv != NULL) { - sk_CONF_VALUE_delete_ptr(ts, vv); - OPENSSL_free(vv->name); - OPENSSL_free(vv->value); - OPENSSL_free(vv); - } -#endif - v = NULL; - } - } - if (buff != NULL) - BUF_MEM_free(buff); - if (section != NULL) - OPENSSL_free(section); - return (1); - err: - if (buff != NULL) - BUF_MEM_free(buff); - if (section != NULL) - OPENSSL_free(section); - if (line != NULL) - *line = eline; - BIO_snprintf(btmp, sizeof(btmp), "%ld", eline); - ERR_add_error_data(2, "line ", btmp); - if ((h != conf->data) && (conf->data != NULL)) { - CONF_free(conf->data); - conf->data = NULL; - } - if (v != NULL) { - if (v->name != NULL) - OPENSSL_free(v->name); - if (v->value != NULL) - OPENSSL_free(v->value); - if (v != NULL) - OPENSSL_free(v); - } - return (0); -} - -static void clear_comments(CONF *conf, char *p) -{ - for (;;) { - if (IS_FCOMMENT(conf, *p)) { - *p = '\0'; - return; - } - if (!IS_WS(conf, *p)) { - break; - } - p++; - } - - for (;;) { - if (IS_COMMENT(conf, *p)) { - *p = '\0'; - return; - } - if (IS_DQUOTE(conf, *p)) { - p = scan_dquote(conf, p); - continue; - } - if (IS_QUOTE(conf, *p)) { - p = scan_quote(conf, p); - continue; - } - if (IS_ESC(conf, *p)) { - p = scan_esc(conf, p); - continue; - } - if (IS_EOF(conf, *p)) - return; - else - p++; - } -} - -static int str_copy(CONF *conf, char *section, char **pto, char *from) -{ - int q, r, rr = 0, to = 0, len = 0; - char *s, *e, *rp, *p, *rrp, *np, *cp, v; - BUF_MEM *buf; - - if ((buf = BUF_MEM_new()) == NULL) - return (0); - - len = strlen(from) + 1; - if (!BUF_MEM_grow(buf, len)) - goto err; - - for (;;) { - if (IS_QUOTE(conf, *from)) { - q = *from; - from++; - while (!IS_EOF(conf, *from) && (*from != q)) { - if (IS_ESC(conf, *from)) { - from++; - if (IS_EOF(conf, *from)) - break; - } - buf->data[to++] = *(from++); - } - if (*from == q) - from++; - } else if (IS_DQUOTE(conf, *from)) { - q = *from; - from++; - while (!IS_EOF(conf, *from)) { - if (*from == q) { - if (*(from + 1) == q) { - from++; - } else { - break; - } - } - buf->data[to++] = *(from++); - } - if (*from == q) - from++; - } else if (IS_ESC(conf, *from)) { - from++; - v = *(from++); - if (IS_EOF(conf, v)) - break; - else if (v == 'r') - v = '\r'; - else if (v == 'n') - v = '\n'; - else if (v == 'b') - v = '\b'; - else if (v == 't') - v = '\t'; - buf->data[to++] = v; - } else if (IS_EOF(conf, *from)) - break; - else if (*from == '$') { - size_t newsize; - - /* try to expand it */ - rrp = NULL; - s = &(from[1]); - if (*s == '{') - q = '}'; - else if (*s == '(') - q = ')'; - else - q = 0; - - if (q) - s++; - cp = section; - e = np = s; - while (IS_ALPHA_NUMERIC(conf, *e)) - e++; - if ((e[0] == ':') && (e[1] == ':')) { - cp = np; - rrp = e; - rr = *e; - *rrp = '\0'; - e += 2; - np = e; - while (IS_ALPHA_NUMERIC(conf, *e)) - e++; - } - r = *e; - *e = '\0'; - rp = e; - if (q) { - if (r != q) { - CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE); - goto err; - } - e++; - } - /*- - * So at this point we have - * np which is the start of the name string which is - * '\0' terminated. - * cp which is the start of the section string which is - * '\0' terminated. - * e is the 'next point after'. - * r and rr are the chars replaced by the '\0' - * rp and rrp is where 'r' and 'rr' came from. - */ - p = _CONF_get_string(conf, cp, np); - if (rrp != NULL) - *rrp = rr; - *rp = r; - if (p == NULL) { - CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE); - goto err; - } - newsize = strlen(p) + buf->length - (e - from); - if (newsize > MAX_CONF_VALUE_LENGTH) { - CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG); - goto err; - } - if (!BUF_MEM_grow_clean(buf, newsize)) { - CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE); - goto err; - } - while (*p) - buf->data[to++] = *(p++); - - /* - * Since we change the pointer 'from', we also have to change the - * perceived length of the string it points at. /RL - */ - len -= e - from; - from = e; - - /* - * In case there were no braces or parenthesis around the - * variable reference, we have to put back the character that was - * replaced with a '\0'. /RL - */ - *rp = r; - } else - buf->data[to++] = *(from++); - } - buf->data[to] = '\0'; - if (*pto != NULL) - OPENSSL_free(*pto); - *pto = buf->data; - OPENSSL_free(buf); - return (1); - err: - if (buf != NULL) - BUF_MEM_free(buf); - return (0); -} - -static char *eat_ws(CONF *conf, char *p) -{ - while (IS_WS(conf, *p) && (!IS_EOF(conf, *p))) - p++; - return (p); -} - -static char *eat_alpha_numeric(CONF *conf, char *p) -{ - for (;;) { - if (IS_ESC(conf, *p)) { - p = scan_esc(conf, p); - continue; - } - if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) - return (p); - p++; - } -} - -static char *scan_quote(CONF *conf, char *p) -{ - int q = *p; - - p++; - while (!(IS_EOF(conf, *p)) && (*p != q)) { - if (IS_ESC(conf, *p)) { - p++; - if (IS_EOF(conf, *p)) - return (p); - } - p++; - } - if (*p == q) - p++; - return (p); -} - -static char *scan_dquote(CONF *conf, char *p) -{ - int q = *p; - - p++; - while (!(IS_EOF(conf, *p))) { - if (*p == q) { - if (*(p + 1) == q) { - p++; - } else { - break; - } - } - p++; - } - if (*p == q) - p++; - return (p); -} - -static void dump_value_doall_arg(CONF_VALUE *a, BIO *out) -{ - if (a->name) - BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); - else - BIO_printf(out, "[[%s]]\n", a->section); -} - -static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO) - -static int def_dump(const CONF *conf, BIO *out) -{ - lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), - BIO, out); - return 1; -} - -static int def_is_number(const CONF *conf, char c) -{ - return IS_NUMBER(conf, c); -} - -static int def_to_int(const CONF *conf, char c) -{ - return c - '0'; -} -/* crypto/conf/conf_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -// #include "err.h" -// #include "conf.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason) - -static ERR_STRING_DATA CONF_str_functs[] = { - {ERR_FUNC(CONF_F_CONF_DUMP_FP), "CONF_dump_fp"}, - {ERR_FUNC(CONF_F_CONF_LOAD), "CONF_load"}, - {ERR_FUNC(CONF_F_CONF_LOAD_BIO), "CONF_load_bio"}, - {ERR_FUNC(CONF_F_CONF_LOAD_FP), "CONF_load_fp"}, - {ERR_FUNC(CONF_F_CONF_MODULES_LOAD), "CONF_modules_load"}, - {ERR_FUNC(CONF_F_CONF_PARSE_LIST), "CONF_parse_list"}, - {ERR_FUNC(CONF_F_DEF_LOAD), "DEF_LOAD"}, - {ERR_FUNC(CONF_F_DEF_LOAD_BIO), "DEF_LOAD_BIO"}, - {ERR_FUNC(CONF_F_MODULE_INIT), "MODULE_INIT"}, - {ERR_FUNC(CONF_F_MODULE_LOAD_DSO), "MODULE_LOAD_DSO"}, - {ERR_FUNC(CONF_F_MODULE_RUN), "MODULE_RUN"}, - {ERR_FUNC(CONF_F_NCONF_DUMP_BIO), "NCONF_dump_bio"}, - {ERR_FUNC(CONF_F_NCONF_DUMP_FP), "NCONF_dump_fp"}, - {ERR_FUNC(CONF_F_NCONF_GET_NUMBER), "NCONF_get_number"}, - {ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E), "NCONF_get_number_e"}, - {ERR_FUNC(CONF_F_NCONF_GET_SECTION), "NCONF_get_section"}, - {ERR_FUNC(CONF_F_NCONF_GET_STRING), "NCONF_get_string"}, - {ERR_FUNC(CONF_F_NCONF_LOAD), "NCONF_load"}, - {ERR_FUNC(CONF_F_NCONF_LOAD_BIO), "NCONF_load_bio"}, - {ERR_FUNC(CONF_F_NCONF_LOAD_FP), "NCONF_load_fp"}, - {ERR_FUNC(CONF_F_NCONF_NEW), "NCONF_new"}, - {ERR_FUNC(CONF_F_STR_COPY), "STR_COPY"}, - {0, NULL} -}; - -static ERR_STRING_DATA CONF_str_reasons[] = { - {ERR_REASON(CONF_R_ERROR_LOADING_DSO), "error loading dso"}, - {ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL), "list cannot be null"}, - {ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET), - "missing close square bracket"}, - {ERR_REASON(CONF_R_MISSING_EQUAL_SIGN), "missing equal sign"}, - {ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION), "missing finish function"}, - {ERR_REASON(CONF_R_MISSING_INIT_FUNCTION), "missing init function"}, - {ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR), - "module initialization error"}, - {ERR_REASON(CONF_R_NO_CLOSE_BRACE), "no close brace"}, - {ERR_REASON(CONF_R_NO_CONF), "no conf"}, - {ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE), - "no conf or environment variable"}, - {ERR_REASON(CONF_R_NO_SECTION), "no section"}, - {ERR_REASON(CONF_R_NO_SUCH_FILE), "no such file"}, - {ERR_REASON(CONF_R_NO_VALUE), "no value"}, - {ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION), - "unable to create new section"}, - {ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"}, - {ERR_REASON(CONF_R_VARIABLE_EXPANSION_TOO_LONG), - "variable expansion too long"}, - {ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"}, - {0, NULL} -}; - -#endif - -void ERR_load_CONF_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) { - ERR_load_strings(0, CONF_str_functs); - ERR_load_strings(0, CONF_str_reasons); - } -#endif -} -/* conf_lib.c */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "crypto.h" -// #include "err.h" -// #include "conf.h" -// #include "conf_api.h" -// #include "lhash.h" - -const char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT; - -static CONF_METHOD *default_CONF_method = NULL; - -/* Init a 'CONF' structure from an old LHASH */ - -void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) -{ - if (default_CONF_method == NULL) - default_CONF_method = NCONF_default(); - - default_CONF_method->init(conf); - conf->data = hash; -} - -/* - * The following section contains the "CONF classic" functions, rewritten in - * terms of the new CONF interface. - */ - -int CONF_set_default_method(CONF_METHOD *meth) -{ - default_CONF_method = meth; - return 1; -} - -LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, - long *eline) -{ - LHASH_OF(CONF_VALUE) *ltmp; - BIO *in = NULL; - -#ifdef OPENSSL_SYS_VMS - in = BIO_new_file(file, "r"); -#else - in = BIO_new_file(file, "rb"); -#endif - if (in == NULL) { - CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); - return NULL; - } - - ltmp = CONF_load_bio(conf, in, eline); - BIO_free(in); - - return ltmp; -} - -#ifndef OPENSSL_NO_FP_API -LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, - long *eline) -{ - BIO *btmp; - LHASH_OF(CONF_VALUE) *ltmp; - if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { - CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); - return NULL; - } - ltmp = CONF_load_bio(conf, btmp, eline); - BIO_free(btmp); - return ltmp; -} -#endif - -LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, - long *eline) -{ - CONF ctmp; - int ret; - - CONF_set_nconf(&ctmp, conf); - - ret = NCONF_load_bio(&ctmp, bp, eline); - if (ret) - return ctmp.data; - return NULL; -} - -STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, - const char *section) -{ - if (conf == NULL) { - return NULL; - } else { - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return NCONF_get_section(&ctmp, section); - } -} - -char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, - const char *name) -{ - if (conf == NULL) { - return NCONF_get_string(NULL, group, name); - } else { - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return NCONF_get_string(&ctmp, group, name); - } -} - -long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, - const char *name) -{ - int status; - long result = 0; - - if (conf == NULL) { - status = NCONF_get_number_e(NULL, group, name, &result); - } else { - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - status = NCONF_get_number_e(&ctmp, group, name, &result); - } - - if (status == 0) { - /* This function does not believe in errors... */ - ERR_clear_error(); - } - return result; -} - -void CONF_free(LHASH_OF(CONF_VALUE) *conf) -{ - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - NCONF_free_data(&ctmp); -} - -#ifndef OPENSSL_NO_FP_API -int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) -{ - BIO *btmp; - int ret; - - if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { - CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); - return 0; - } - ret = CONF_dump_bio(conf, btmp); - BIO_free(btmp); - return ret; -} -#endif - -int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) -{ - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return NCONF_dump_bio(&ctmp, out); -} - -/* - * The following section contains the "New CONF" functions. They are - * completely centralised around a new CONF structure that may contain - * basically anything, but at least a method pointer and a table of data. - * These functions are also written in terms of the bridge functions used by - * the "CONF classic" functions, for consistency. - */ - -CONF *NCONF_new(CONF_METHOD *meth) -{ - CONF *ret; - - if (meth == NULL) - meth = NCONF_default(); - - ret = meth->create(meth); - if (ret == NULL) { - CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - return ret; -} - -void NCONF_free(CONF *conf) -{ - if (conf == NULL) - return; - conf->meth->destroy(conf); -} - -void NCONF_free_data(CONF *conf) -{ - if (conf == NULL) - return; - conf->meth->destroy_data(conf); -} - -int NCONF_load(CONF *conf, const char *file, long *eline) -{ - if (conf == NULL) { - CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); - return 0; - } - - return conf->meth->load(conf, file, eline); -} - -#ifndef OPENSSL_NO_FP_API -int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) -{ - BIO *btmp; - int ret; - if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { - CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); - return 0; - } - ret = NCONF_load_bio(conf, btmp, eline); - BIO_free(btmp); - return ret; -} -#endif - -int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) -{ - if (conf == NULL) { - CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); - return 0; - } - - return conf->meth->load_bio(conf, bp, eline); -} - -STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) -{ - if (conf == NULL) { - CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); - return NULL; - } - - if (section == NULL) { - CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); - return NULL; - } - - return _CONF_get_section_values(conf, section); -} - -char *NCONF_get_string(const CONF *conf, const char *group, const char *name) -{ - char *s = _CONF_get_string(conf, group, name); - - /* - * Since we may get a value from an environment variable even if conf is - * NULL, let's check the value first - */ - if (s) - return s; - - if (conf == NULL) { - CONFerr(CONF_F_NCONF_GET_STRING, - CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); - return NULL; - } - CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); - ERR_add_error_data(4, "group=", group, " name=", name); - return NULL; -} - -int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, - long *result) -{ - char *str; - - if (result == NULL) { - CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - str = NCONF_get_string(conf, group, name); - - if (str == NULL) - return 0; - - for (*result = 0; conf->meth->is_number(conf, *str);) { - *result = (*result) * 10 + conf->meth->to_int(conf, *str); - str++; - } - - return 1; -} - -#ifndef OPENSSL_NO_FP_API -int NCONF_dump_fp(const CONF *conf, FILE *out) -{ - BIO *btmp; - int ret; - if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { - CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); - return 0; - } - ret = NCONF_dump_bio(conf, btmp); - BIO_free(btmp); - return ret; -} -#endif - -int NCONF_dump_bio(const CONF *conf, BIO *out) -{ - if (conf == NULL) { - CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); - return 0; - } - - return conf->meth->dump(conf, out); -} - -/* This function should be avoided */ -#if 0 -long NCONF_get_number(CONF *conf, char *group, char *name) -{ - int status; - long ret = 0; - - status = NCONF_get_number_e(conf, group, name, &ret); - if (status == 0) { - /* This function does not believe in errors... */ - ERR_get_error(); - } - return ret; -} -#endif -/* conf_mall.c */ -/* - * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "crypto.h" -// #include "cryptlib.h" -// #include "conf.h" -#include "dso.h" -#include "x509.h" -#include "asn1.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -/* Load all OpenSSL builtin modules */ - -void OPENSSL_load_builtin_modules(void) -{ - /* Add builtin modules here */ - ASN1_add_oid_module(); -#ifndef OPENSSL_NO_ENGINE - ENGINE_add_conf_module(); -#endif - EVP_add_alg_module(); -} -/* conf_mod.c */ -/* - * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "crypto.h" -// #include "cryptlib.h" -// #include "conf.h" -// #include "dso.h" -// #include "x509.h" - -#define DSO_mod_init_name "OPENSSL_init" -#define DSO_mod_finish_name "OPENSSL_finish" - -/* - * This structure contains a data about supported modules. entries in this - * table correspond to either dynamic or static modules. - */ - -struct conf_module_st { - /* DSO of this module or NULL if static */ - DSO *dso; - /* Name of the module */ - char *name; - /* Init function */ - conf_init_func *init; - /* Finish function */ - conf_finish_func *finish; - /* Number of successfully initialized modules */ - int links; - void *usr_data; -}; - -/* - * This structure contains information about modules that have been - * successfully initialized. There may be more than one entry for a given - * module. - */ - -struct conf_imodule_st { - CONF_MODULE *pmod; - char *name; - char *value; - unsigned long flags; - void *usr_data; -}; - -static STACK_OF(CONF_MODULE) *supported_modules = NULL; -static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; - -static void module_free(CONF_MODULE *md); -static void module_finish(CONF_IMODULE *imod); -static int module_run(const CONF *cnf, char *name, char *value, - unsigned long flags); -static CONF_MODULE *module_add(DSO *dso, const char *name, - conf_init_func *ifunc, - conf_finish_func *ffunc); -static CONF_MODULE *module_find(char *name); -static int module_init(CONF_MODULE *pmod, char *name, char *value, - const CONF *cnf); -static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value, - unsigned long flags); - -/* Main function: load modules from a CONF structure */ - -int CONF_modules_load(const CONF *cnf, const char *appname, - unsigned long flags) -{ - STACK_OF(CONF_VALUE) *values; - CONF_VALUE *vl; - char *vsection = NULL; - - int ret, i; - - if (!cnf) - return 1; - - if (appname) - vsection = NCONF_get_string(cnf, NULL, appname); - - if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION))) - vsection = NCONF_get_string(cnf, NULL, "openssl_conf"); - - if (!vsection) { - ERR_clear_error(); - return 1; - } - - values = NCONF_get_section(cnf, vsection); - - if (!values) - return 0; - - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - vl = sk_CONF_VALUE_value(values, i); - ret = module_run(cnf, vl->name, vl->value, flags); - if (ret <= 0) - if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) - return ret; - } - - return 1; - -} - -int CONF_modules_load_file(const char *filename, const char *appname, - unsigned long flags) -{ - char *file = NULL; - CONF *conf = NULL; - int ret = 0; - conf = NCONF_new(NULL); - if (!conf) - goto err; - - if (filename == NULL) { - file = CONF_get1_default_config_file(); - if (!file) - goto err; - } else - file = (char *)filename; - - if (NCONF_load(conf, file, NULL) <= 0) { - if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) && - (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) { - ERR_clear_error(); - ret = 1; - } - goto err; - } - - ret = CONF_modules_load(conf, appname, flags); - - err: - if (filename == NULL) - OPENSSL_free(file); - NCONF_free(conf); - - return ret; -} - -static int module_run(const CONF *cnf, char *name, char *value, - unsigned long flags) -{ - CONF_MODULE *md; - int ret; - - md = module_find(name); - - /* Module not found: try to load DSO */ - if (!md && !(flags & CONF_MFLAGS_NO_DSO)) - md = module_load_dso(cnf, name, value, flags); - - if (!md) { - if (!(flags & CONF_MFLAGS_SILENT)) { - CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME); - ERR_add_error_data(2, "module=", name); - } - return -1; - } - - ret = module_init(md, name, value, cnf); - - if (ret <= 0) { - if (!(flags & CONF_MFLAGS_SILENT)) { - char rcode[DECIMAL_SIZE(ret) + 1]; - CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR); - BIO_snprintf(rcode, sizeof(rcode), "%-8d", ret); - ERR_add_error_data(6, "module=", name, ", value=", value, - ", retcode=", rcode); - } - } - - return ret; -} - -/* Load a module from a DSO */ -static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value, - unsigned long flags) -{ - DSO *dso = NULL; - conf_init_func *ifunc; - conf_finish_func *ffunc; - char *path = NULL; - int errcode = 0; - CONF_MODULE *md; - /* Look for alternative path in module section */ - path = NCONF_get_string(cnf, value, "path"); - if (!path) { - ERR_clear_error(); - path = name; - } - dso = DSO_load(NULL, path, NULL, 0); - if (!dso) { - errcode = CONF_R_ERROR_LOADING_DSO; - goto err; - } - ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name); - if (!ifunc) { - errcode = CONF_R_MISSING_INIT_FUNCTION; - goto err; - } - ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name); - /* All OK, add module */ - md = module_add(dso, name, ifunc, ffunc); - - if (!md) - goto err; - - return md; - - err: - if (dso) - DSO_free(dso); - CONFerr(CONF_F_MODULE_LOAD_DSO, errcode); - ERR_add_error_data(4, "module=", name, ", path=", path); - return NULL; -} - -/* add module to list */ -static CONF_MODULE *module_add(DSO *dso, const char *name, - conf_init_func *ifunc, conf_finish_func *ffunc) -{ - CONF_MODULE *tmod = NULL; - if (supported_modules == NULL) - supported_modules = sk_CONF_MODULE_new_null(); - if (supported_modules == NULL) - return NULL; - tmod = OPENSSL_malloc(sizeof(CONF_MODULE)); - if (tmod == NULL) - return NULL; - - tmod->dso = dso; - tmod->name = BUF_strdup(name); - if (tmod->name == NULL) { - OPENSSL_free(tmod); - return NULL; - } - tmod->init = ifunc; - tmod->finish = ffunc; - tmod->links = 0; - - if (!sk_CONF_MODULE_push(supported_modules, tmod)) { - OPENSSL_free(tmod); - return NULL; - } - - return tmod; -} - -/* - * Find a module from the list. We allow module names of the form - * modname.XXXX to just search for modname to allow the same module to be - * initialized more than once. - */ - -static CONF_MODULE *module_find(char *name) -{ - CONF_MODULE *tmod; - int i, nchar; - char *p; - p = strrchr(name, '.'); - - if (p) - nchar = p - name; - else - nchar = strlen(name); - - for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) { - tmod = sk_CONF_MODULE_value(supported_modules, i); - if (!strncmp(tmod->name, name, nchar)) - return tmod; - } - - return NULL; - -} - -/* initialize a module */ -static int module_init(CONF_MODULE *pmod, char *name, char *value, - const CONF *cnf) -{ - int ret = 1; - int init_called = 0; - CONF_IMODULE *imod = NULL; - - /* Otherwise add initialized module to list */ - imod = OPENSSL_malloc(sizeof(CONF_IMODULE)); - if (!imod) - goto err; - - imod->pmod = pmod; - imod->name = BUF_strdup(name); - imod->value = BUF_strdup(value); - imod->usr_data = NULL; - - if (!imod->name || !imod->value) - goto memerr; - - /* Try to initialize module */ - if (pmod->init) { - ret = pmod->init(imod, cnf); - init_called = 1; - /* Error occurred, exit */ - if (ret <= 0) - goto err; - } - - if (initialized_modules == NULL) { - initialized_modules = sk_CONF_IMODULE_new_null(); - if (!initialized_modules) { - CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (!sk_CONF_IMODULE_push(initialized_modules, imod)) { - CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); - goto err; - } - - pmod->links++; - - return ret; - - err: - - /* We've started the module so we'd better finish it */ - if (pmod->finish && init_called) - pmod->finish(imod); - - memerr: - if (imod) { - if (imod->name) - OPENSSL_free(imod->name); - if (imod->value) - OPENSSL_free(imod->value); - OPENSSL_free(imod); - } - - return -1; - -} - -/* - * Unload any dynamic modules that have a link count of zero: i.e. have no - * active initialized modules. If 'all' is set then all modules are unloaded - * including static ones. - */ - -void CONF_modules_unload(int all) -{ - int i; - CONF_MODULE *md; - CONF_modules_finish(); - /* unload modules in reverse order */ - for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) { - md = sk_CONF_MODULE_value(supported_modules, i); - /* If static or in use and 'all' not set ignore it */ - if (((md->links > 0) || !md->dso) && !all) - continue; - /* Since we're working in reverse this is OK */ - (void)sk_CONF_MODULE_delete(supported_modules, i); - module_free(md); - } - if (sk_CONF_MODULE_num(supported_modules) == 0) { - sk_CONF_MODULE_free(supported_modules); - supported_modules = NULL; - } -} - -/* unload a single module */ -static void module_free(CONF_MODULE *md) -{ - if (md->dso) - DSO_free(md->dso); - OPENSSL_free(md->name); - OPENSSL_free(md); -} - -/* finish and free up all modules instances */ - -void CONF_modules_finish(void) -{ - CONF_IMODULE *imod; - while (sk_CONF_IMODULE_num(initialized_modules) > 0) { - imod = sk_CONF_IMODULE_pop(initialized_modules); - module_finish(imod); - } - sk_CONF_IMODULE_free(initialized_modules); - initialized_modules = NULL; -} - -/* finish a module instance */ - -static void module_finish(CONF_IMODULE *imod) -{ - if (imod->pmod->finish) - imod->pmod->finish(imod); - imod->pmod->links--; - OPENSSL_free(imod->name); - OPENSSL_free(imod->value); - OPENSSL_free(imod); -} - -/* Add a static module to OpenSSL */ - -int CONF_module_add(const char *name, conf_init_func *ifunc, - conf_finish_func *ffunc) -{ - if (module_add(NULL, name, ifunc, ffunc)) - return 1; - else - return 0; -} - -void CONF_modules_free(void) -{ - CONF_modules_finish(); - CONF_modules_unload(1); -} - -/* Utility functions */ - -const char *CONF_imodule_get_name(const CONF_IMODULE *md) -{ - return md->name; -} - -const char *CONF_imodule_get_value(const CONF_IMODULE *md) -{ - return md->value; -} - -void *CONF_imodule_get_usr_data(const CONF_IMODULE *md) -{ - return md->usr_data; -} - -void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data) -{ - md->usr_data = usr_data; -} - -CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md) -{ - return md->pmod; -} - -unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md) -{ - return md->flags; -} - -void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags) -{ - md->flags = flags; -} - -void *CONF_module_get_usr_data(CONF_MODULE *pmod) -{ - return pmod->usr_data; -} - -void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data) -{ - pmod->usr_data = usr_data; -} - -/* Return default config file name */ - -char *CONF_get1_default_config_file(void) -{ - char *file; - int len; - - file = ossl_safe_getenv("OPENSSL_CONF"); - if (file) - return BUF_strdup(file); - - len = strlen(X509_get_default_cert_area()); -#ifndef OPENSSL_SYS_VMS - len++; -#endif - len += strlen(OPENSSL_CONF); - - file = OPENSSL_malloc(len + 1); - - if (!file) - return NULL; - BUF_strlcpy(file, X509_get_default_cert_area(), len + 1); -#ifndef OPENSSL_SYS_VMS - BUF_strlcat(file, "/", len + 1); -#endif - BUF_strlcat(file, OPENSSL_CONF, len + 1); - - return file; -} - -/* - * This function takes a list separated by 'sep' and calls the callback - * function giving the start and length of each member optionally stripping - * leading and trailing whitespace. This can be used to parse comma separated - * lists for example. - */ - -int CONF_parse_list(const char *list_, int sep, int nospc, - int (*list_cb) (const char *elem, int len, void *usr), - void *arg) -{ - int ret; - const char *lstart, *tmpend, *p; - - if (list_ == NULL) { - CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL); - return 0; - } - - lstart = list_; - for (;;) { - if (nospc) { - while (*lstart && isspace((unsigned char)*lstart)) - lstart++; - } - p = strchr(lstart, sep); - if (p == lstart || !*lstart) - ret = list_cb(NULL, 0, arg); - else { - if (p) - tmpend = p - 1; - else - tmpend = lstart + strlen(lstart) - 1; - if (nospc) { - while (isspace((unsigned char)*tmpend)) - tmpend--; - } - ret = list_cb(lstart, tmpend - lstart + 1, arg); - } - if (ret <= 0) - return ret; - if (p == NULL) - return 1; - lstart = p + 1; - } -} -/* conf_sap.c */ -/* - * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "crypto.h" -// #include "cryptlib.h" -// #include "conf.h" -// #include "dso.h" -// #include "x509.h" -// #include "asn1.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -/* - * This is the automatic configuration loader: it is called automatically by - * OpenSSL when any of a number of standard initialisation functions are - * called, unless this is overridden by calling OPENSSL_no_config() - */ - -static int openssl_configured = 0; - -void OPENSSL_config(const char *config_name) -{ - if (openssl_configured) - return; - - OPENSSL_load_builtin_modules(); -#ifndef OPENSSL_NO_ENGINE - /* Need to load ENGINEs */ - ENGINE_load_builtin_engines(); -#endif - ERR_clear_error(); - CONF_modules_load_file(NULL, config_name, - CONF_MFLAGS_DEFAULT_SECTION | - CONF_MFLAGS_IGNORE_MISSING_FILE); - openssl_configured = 1; -} - -void OPENSSL_no_config() -{ - openssl_configured = 1; -} diff --git a/Sources/COpenSSL/conf_api.h b/Sources/COpenSSL/conf_api.h deleted file mode 100644 index 66a0eeac..00000000 --- a/Sources/COpenSSL/conf_api.h +++ /dev/null @@ -1,89 +0,0 @@ -/* conf_api.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_CONF_API_H -# define HEADER_CONF_API_H - -# include "lhash.h" -# include "conf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Up until OpenSSL 0.9.5a, this was new_section */ -CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); -/* Up until OpenSSL 0.9.5a, this was get_section */ -CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); -/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ -STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, - const char *section); - -int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); -char *_CONF_get_string(const CONF *conf, const char *section, - const char *name); -long _CONF_get_number(const CONF *conf, const char *section, - const char *name); - -int _CONF_new_data(CONF *conf); -void _CONF_free_data(CONF *conf); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/conf_def.h b/Sources/COpenSSL/conf_def.h deleted file mode 100644 index 48b34421..00000000 --- a/Sources/COpenSSL/conf_def.h +++ /dev/null @@ -1,181 +0,0 @@ -/* crypto/conf/conf_def.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * THIS FILE WAS AUTOMAGICALLY GENERATED! Please modify and use keysets.pl to - * regenerate it. - */ - -#define CONF_NUMBER 1 -#define CONF_UPPER 2 -#define CONF_LOWER 4 -#define CONF_UNDER 256 -#define CONF_PUNCTUATION 512 -#define CONF_WS 16 -#define CONF_ESC 32 -#define CONF_QUOTE 64 -#define CONF_DQUOTE 1024 -#define CONF_COMMENT 128 -#define CONF_FCOMMENT 2048 -#define CONF_EOF 8 -#define CONF_HIGHBIT 4096 -#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) -#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) -#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \ - CONF_PUNCTUATION) - -#define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) -#ifndef CHARSET_EBCDIC -# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) -# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) -# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) -# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) -# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) -# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) -# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) -# define IS_ALPHA_NUMERIC_PUNCT(c,a) \ - (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) -# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) -# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) -# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) - -#else /*CHARSET_EBCDIC*/ - -# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT) -# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT) -# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF) -# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC) -# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER) -# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS) -# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC) -# define IS_ALPHA_NUMERIC_PUNCT(c,a) \ - (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT) -# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE) -# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE) -# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT) -#endif /*CHARSET_EBCDIC*/ - -static unsigned short CONF_type_default[256] = { - 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040, - 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, - 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100, - 0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, -}; - -static unsigned short CONF_type_win32[256] = { - 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000, - 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200, - 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100, - 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, - 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, -}; diff --git a/Sources/COpenSSL/constant_time_locl.h b/Sources/COpenSSL/constant_time_locl.h deleted file mode 100644 index c786aea9..00000000 --- a/Sources/COpenSSL/constant_time_locl.h +++ /dev/null @@ -1,211 +0,0 @@ -/* crypto/constant_time_locl.h */ -/*- - * Utilities for constant-time cryptography. - * - * Author: Emilia Kasper (emilia@openssl.org) - * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley - * (Google). - * ==================================================================== - * Copyright (c) 2014 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_CONSTANT_TIME_LOCL_H -# define HEADER_CONSTANT_TIME_LOCL_H - -# include "e_os.h" /* For 'inline' */ - -#ifdef __cplusplus -extern "C" { -#endif - -/*- - * The boolean methods return a bitmask of all ones (0xff...f) for true - * and 0 for false. This is useful for choosing a value based on the result - * of a conditional in constant time. For example, - * - * if (a < b) { - * c = a; - * } else { - * c = b; - * } - * - * can be written as - * - * unsigned int lt = constant_time_lt(a, b); - * c = constant_time_select(lt, a, b); - */ - -/* - * Returns the given value with the MSB copied to all the other - * bits. Uses the fact that arithmetic shift shifts-in the sign bit. - * However, this is not ensured by the C standard so you may need to - * replace this with something else on odd CPUs. - */ -static inline unsigned int constant_time_msb(unsigned int a); - -/* - * Returns 0xff..f if a < b and 0 otherwise. - */ -static inline unsigned int constant_time_lt(unsigned int a, unsigned int b); -/* Convenience method for getting an 8-bit mask. */ -static inline unsigned char constant_time_lt_8(unsigned int a, - unsigned int b); - -/* - * Returns 0xff..f if a >= b and 0 otherwise. - */ -static inline unsigned int constant_time_ge(unsigned int a, unsigned int b); -/* Convenience method for getting an 8-bit mask. */ -static inline unsigned char constant_time_ge_8(unsigned int a, - unsigned int b); - -/* - * Returns 0xff..f if a == 0 and 0 otherwise. - */ -static inline unsigned int constant_time_is_zero(unsigned int a); -/* Convenience method for getting an 8-bit mask. */ -static inline unsigned char constant_time_is_zero_8(unsigned int a); - -/* - * Returns 0xff..f if a == b and 0 otherwise. - */ -static inline unsigned int constant_time_eq(unsigned int a, unsigned int b); -/* Convenience method for getting an 8-bit mask. */ -static inline unsigned char constant_time_eq_8(unsigned int a, - unsigned int b); -/* Signed integers. */ -static inline unsigned int constant_time_eq_int(int a, int b); -/* Convenience method for getting an 8-bit mask. */ -static inline unsigned char constant_time_eq_int_8(int a, int b); - -/*- - * Returns (mask & a) | (~mask & b). - * - * When |mask| is all 1s or all 0s (as returned by the methods above), - * the select methods return either |a| (if |mask| is nonzero) or |b| - * (if |mask| is zero). - */ -static inline unsigned int constant_time_select(unsigned int mask, - unsigned int a, - unsigned int b); -/* Convenience method for unsigned chars. */ -static inline unsigned char constant_time_select_8(unsigned char mask, - unsigned char a, - unsigned char b); -/* Convenience method for signed integers. */ -static inline int constant_time_select_int(unsigned int mask, int a, int b); - -static inline unsigned int constant_time_msb(unsigned int a) -{ - return 0 - (a >> (sizeof(a) * 8 - 1)); -} - -static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) -{ - return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); -} - -static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) -{ - return (unsigned char)(constant_time_lt(a, b)); -} - -static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) -{ - return ~constant_time_lt(a, b); -} - -static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) -{ - return (unsigned char)(constant_time_ge(a, b)); -} - -static inline unsigned int constant_time_is_zero(unsigned int a) -{ - return constant_time_msb(~a & (a - 1)); -} - -static inline unsigned char constant_time_is_zero_8(unsigned int a) -{ - return (unsigned char)(constant_time_is_zero(a)); -} - -static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) -{ - return constant_time_is_zero(a ^ b); -} - -static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b) -{ - return (unsigned char)(constant_time_eq(a, b)); -} - -static inline unsigned int constant_time_eq_int(int a, int b) -{ - return constant_time_eq((unsigned)(a), (unsigned)(b)); -} - -static inline unsigned char constant_time_eq_int_8(int a, int b) -{ - return constant_time_eq_8((unsigned)(a), (unsigned)(b)); -} - -static inline unsigned int constant_time_select(unsigned int mask, - unsigned int a, - unsigned int b) -{ - return (mask & a) | (~mask & b); -} - -static inline unsigned char constant_time_select_8(unsigned char mask, - unsigned char a, - unsigned char b) -{ - return (unsigned char)(constant_time_select(mask, a, b)); -} - -static inline int constant_time_select_int(unsigned int mask, int a, int b) -{ - return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); -} - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_CONSTANT_TIME_LOCL_H */ diff --git a/Sources/COpenSSL/cpt_err.c b/Sources/COpenSSL/cpt_err.c deleted file mode 100644 index 71d6385a..00000000 --- a/Sources/COpenSSL/cpt_err.c +++ /dev/null @@ -1,104 +0,0 @@ -/* crypto/cpt_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "crypto.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason) - -static ERR_STRING_DATA CRYPTO_str_functs[] = { - {ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX), "CRYPTO_get_ex_new_index"}, - {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID), "CRYPTO_get_new_dynlockid"}, - {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_LOCKID), "CRYPTO_get_new_lockid"}, - {ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA), "CRYPTO_set_ex_data"}, - {ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX), "DEF_ADD_INDEX"}, - {ERR_FUNC(CRYPTO_F_DEF_GET_CLASS), "DEF_GET_CLASS"}, - {ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"}, - {ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA), "INT_DUP_EX_DATA"}, - {ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA), "INT_FREE_EX_DATA"}, - {ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA), "INT_NEW_EX_DATA"}, - {0, NULL} -}; - -static ERR_STRING_DATA CRYPTO_str_reasons[] = { - {ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, - {ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK), - "no dynlock create callback"}, - {0, NULL} -}; - -#endif - -void ERR_load_CRYPTO_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) { - ERR_load_strings(0, CRYPTO_str_functs); - ERR_load_strings(0, CRYPTO_str_reasons); - } -#endif -} diff --git a/Sources/COpenSSL/cryptlib.c b/Sources/COpenSSL/cryptlib.c deleted file mode 100644 index e85e1ba0..00000000 --- a/Sources/COpenSSL/cryptlib.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* crypto/cryptlib.c */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include "cryptlib.h" -#include "safestack.h" - -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) -static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */ -#endif - -DECLARE_STACK_OF(CRYPTO_dynlock) - -/* real #defines in crypto.h, keep these upto date */ -static const char *const lock_names[CRYPTO_NUM_LOCKS] = { - "<>", - "err", - "ex_data", - "x509", - "x509_info", - "x509_pkey", - "x509_crl", - "x509_req", - "dsa", - "rsa", - "evp_pkey", - "x509_store", - "ssl_ctx", - "ssl_cert", - "ssl_session", - "ssl_sess_cert", - "ssl", - "ssl_method", - "rand", - "rand2", - "debug_malloc", - "BIO", - "gethostbyname", - "getservbyname", - "readdir", - "RSA_blinding", - "dh", - "debug_malloc2", - "dso", - "dynlock", - "engine", - "ui", - "ecdsa", - "ec", - "ecdh", - "bn", - "ec_pre_comp", - "store", - "comp", - "fips", - "fips2", -#if CRYPTO_NUM_LOCKS != 41 -# error "Inconsistency between crypto.h and cryptlib.c" -#endif -}; - -/* - * This is for applications to allocate new type names in the non-dynamic - * array of lock names. These are numbered with positive numbers. - */ -static STACK_OF(OPENSSL_STRING) *app_locks = NULL; - -/* - * For applications that want a more dynamic way of handling threads, the - * following stack is used. These are externally numbered with negative - * numbers. - */ -static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL; - -static void (MS_FAR *locking_callback) (int mode, int type, - const char *file, int line) = 0; -static int (MS_FAR *add_lock_callback) (int *pointer, int amount, - int type, const char *file, - int line) = 0; -#ifndef OPENSSL_NO_DEPRECATED -static unsigned long (MS_FAR *id_callback) (void) = 0; -#endif -static void (MS_FAR *threadid_callback) (CRYPTO_THREADID *) = 0; -static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) - (const char *file, int line) = 0; -static void (MS_FAR *dynlock_lock_callback) (int mode, - struct CRYPTO_dynlock_value *l, - const char *file, int line) = 0; -static void (MS_FAR *dynlock_destroy_callback) (struct CRYPTO_dynlock_value - *l, const char *file, - int line) = 0; - -int CRYPTO_get_new_lockid(char *name) -{ - char *str; - int i; - -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) - /* - * A hack to make Visual C++ 5.0 work correctly when linking as a DLL - * using /MT. Without this, the application cannot use any floating point - * printf's. It also seems to be needed for Visual C 1.5 (win16) - */ - SSLeay_MSVC5_hack = (double)name[0] * (double)name[1]; -#endif - - if ((app_locks == NULL) - && ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE); - return (0); - } - if ((str = BUF_strdup(name)) == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE); - return (0); - } - i = sk_OPENSSL_STRING_push(app_locks, str); - if (!i) - OPENSSL_free(str); - else - i += CRYPTO_NUM_LOCKS; /* gap of one :-) */ - return (i); -} - -int CRYPTO_num_locks(void) -{ - return CRYPTO_NUM_LOCKS; -} - -int CRYPTO_get_new_dynlockid(void) -{ - int i = 0; - CRYPTO_dynlock *pointer = NULL; - - if (dynlock_create_callback == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, - CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); - return (0); - } - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - if ((dyn_locks == NULL) - && ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) { - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); - return (0); - } - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - pointer = (CRYPTO_dynlock *) OPENSSL_malloc(sizeof(CRYPTO_dynlock)); - if (pointer == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); - return (0); - } - pointer->references = 1; - pointer->data = dynlock_create_callback(__FILE__, __LINE__); - if (pointer->data == NULL) { - OPENSSL_free(pointer); - CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); - return (0); - } - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - /* First, try to find an existing empty slot */ - i = sk_CRYPTO_dynlock_find(dyn_locks, NULL); - /* If there was none, push, thereby creating a new one */ - if (i == -1) - /* - * Since sk_push() returns the number of items on the stack, not the - * location of the pushed item, we need to transform the returned - * number into a position, by decreasing it. - */ - i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1; - else - /* - * If we found a place with a NULL pointer, put our pointer in it. - */ - (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer); - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (i == -1) { - dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); - OPENSSL_free(pointer); - } else - i += 1; /* to avoid 0 */ - return -i; -} - -void CRYPTO_destroy_dynlockid(int i) -{ - CRYPTO_dynlock *pointer = NULL; - if (i) - i = -i - 1; - if (dynlock_destroy_callback == NULL) - return; - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - - if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) { - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - return; - } - pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); - if (pointer != NULL) { - --pointer->references; -#ifdef REF_CHECK - if (pointer->references < 0) { - fprintf(stderr, - "CRYPTO_destroy_dynlockid, bad reference count\n"); - abort(); - } else -#endif - if (pointer->references <= 0) { - (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); - } else - pointer = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) { - dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); - OPENSSL_free(pointer); - } -} - -struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) -{ - CRYPTO_dynlock *pointer = NULL; - if (i) - i = -i - 1; - - CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); - - if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) - pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); - if (pointer) - pointer->references++; - - CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); - - if (pointer) - return pointer->data; - return NULL; -} - -struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) - (const char *file, int line) { - return (dynlock_create_callback); -} - -void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode, - struct CRYPTO_dynlock_value - *l, const char *file, - int line) { - return (dynlock_lock_callback); -} - -void (*CRYPTO_get_dynlock_destroy_callback(void)) - (struct CRYPTO_dynlock_value *l, const char *file, int line) { - return (dynlock_destroy_callback); -} - -void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) - (const char *file, int line)) -{ - dynlock_create_callback = func; -} - -void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode, - struct - CRYPTO_dynlock_value *l, - const char *file, - int line)) -{ - dynlock_lock_callback = func; -} - -void CRYPTO_set_dynlock_destroy_callback(void (*func) - (struct CRYPTO_dynlock_value *l, - const char *file, int line)) -{ - dynlock_destroy_callback = func; -} - -void (*CRYPTO_get_locking_callback(void)) (int mode, int type, - const char *file, int line) { - return (locking_callback); -} - -int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type, - const char *file, int line) { - return (add_lock_callback); -} - -void CRYPTO_set_locking_callback(void (*func) (int mode, int type, - const char *file, int line)) -{ - /* - * Calling this here ensures initialisation before any threads are - * started. - */ - OPENSSL_init(); - locking_callback = func; -} - -void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type, - const char *file, int line)) -{ - add_lock_callback = func; -} - -/* - * the memset() here and in set_pointer() seem overkill, but for the sake of - * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause - * two "equal" THREADID structs to not be memcmp()-identical. - */ -void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) -{ - memset(id, 0, sizeof(*id)); - id->val = val; -} - -static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 }; - -void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) -{ - unsigned char *dest = (void *)&id->val; - unsigned int accum = 0; - unsigned char dnum = sizeof(id->val); - - memset(id, 0, sizeof(*id)); - id->ptr = ptr; - if (sizeof(id->val) >= sizeof(id->ptr)) { - /* - * 'ptr' can be embedded in 'val' without loss of uniqueness - */ - id->val = (unsigned long)id->ptr; - return; - } - /* - * hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a - * linear function over the bytes in 'ptr', the co-efficients of which - * are a sequence of low-primes (hash_coeffs is an 8-element cycle) - the - * starting prime for the sequence varies for each byte of 'val' (unique - * polynomials unless pointers are >64-bit). For added spice, the totals - * accumulate rather than restarting from zero, and the index of the - * 'val' byte is added each time (position dependence). If I was a - * black-belt, I'd scan big-endian pointers in reverse to give low-order - * bits more play, but this isn't crypto and I'd prefer nobody mistake it - * as such. Plus I'm lazy. - */ - while (dnum--) { - const unsigned char *src = (void *)&id->ptr; - unsigned char snum = sizeof(id->ptr); - while (snum--) - accum += *(src++) * hash_coeffs[(snum + dnum) & 7]; - accum += dnum; - *(dest++) = accum & 255; - } -} - -#ifdef OPENSSL_FIPS -extern int FIPS_crypto_threadid_set_callback(void (*func) (CRYPTO_THREADID *)); -#endif - -int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *)) -{ - if (threadid_callback) - return 0; - threadid_callback = func; -#ifdef OPENSSL_FIPS - FIPS_crypto_threadid_set_callback(func); -#endif - return 1; -} - -void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *) { - return threadid_callback; -} - -void CRYPTO_THREADID_current(CRYPTO_THREADID *id) -{ - if (threadid_callback) { - threadid_callback(id); - return; - } -#ifndef OPENSSL_NO_DEPRECATED - /* If the deprecated callback was set, fall back to that */ - if (id_callback) { - CRYPTO_THREADID_set_numeric(id, id_callback()); - return; - } -#endif - /* Else pick a backup */ -#ifdef OPENSSL_SYS_WIN16 - CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask()); -#elif defined(OPENSSL_SYS_WIN32) - CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId()); -#elif defined(OPENSSL_SYS_BEOS) - CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL)); -#else - /* For everything else, default to using the address of 'errno' */ - CRYPTO_THREADID_set_pointer(id, (void *)&errno); -#endif -} - -int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b) -{ - return memcmp(a, b, sizeof(*a)); -} - -void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src) -{ - memcpy(dest, src, sizeof(*src)); -} - -unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) -{ - return id->val; -} - -#ifndef OPENSSL_NO_DEPRECATED -unsigned long (*CRYPTO_get_id_callback(void)) (void) { - return (id_callback); -} - -void CRYPTO_set_id_callback(unsigned long (*func) (void)) -{ - id_callback = func; -} - -unsigned long CRYPTO_thread_id(void) -{ - unsigned long ret = 0; - - if (id_callback == NULL) { -# ifdef OPENSSL_SYS_WIN16 - ret = (unsigned long)GetCurrentTask(); -# elif defined(OPENSSL_SYS_WIN32) - ret = (unsigned long)GetCurrentThreadId(); -# elif defined(GETPID_IS_MEANINGLESS) - ret = 1L; -# elif defined(OPENSSL_SYS_BEOS) - ret = (unsigned long)find_thread(NULL); -# else - ret = (unsigned long)getpid(); -# endif - } else - ret = id_callback(); - return (ret); -} -#endif - -void CRYPTO_lock(int mode, int type, const char *file, int line) -{ -#ifdef LOCK_DEBUG - { - CRYPTO_THREADID id; - char *rw_text, *operation_text; - - if (mode & CRYPTO_LOCK) - operation_text = "lock "; - else if (mode & CRYPTO_UNLOCK) - operation_text = "unlock"; - else - operation_text = "ERROR "; - - if (mode & CRYPTO_READ) - rw_text = "r"; - else if (mode & CRYPTO_WRITE) - rw_text = "w"; - else - rw_text = "ERROR"; - - CRYPTO_THREADID_current(&id); - fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n", - CRYPTO_THREADID_hash(&id), rw_text, operation_text, - CRYPTO_get_lock_name(type), file, line); - } -#endif - if (type < 0) { - if (dynlock_lock_callback != NULL) { - struct CRYPTO_dynlock_value *pointer - = CRYPTO_get_dynlock_value(type); - - OPENSSL_assert(pointer != NULL); - - dynlock_lock_callback(mode, pointer, file, line); - - CRYPTO_destroy_dynlockid(type); - } - } else if (locking_callback != NULL) - locking_callback(mode, type, file, line); -} - -int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, - int line) -{ - int ret = 0; - - if (add_lock_callback != NULL) { -#ifdef LOCK_DEBUG - int before = *pointer; -#endif - - ret = add_lock_callback(pointer, amount, type, file, line); -#ifdef LOCK_DEBUG - { - CRYPTO_THREADID id; - CRYPTO_THREADID_current(&id); - fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", - CRYPTO_THREADID_hash(&id), before, amount, ret, - CRYPTO_get_lock_name(type), file, line); - } -#endif - } else { - CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line); - - ret = *pointer + amount; -#ifdef LOCK_DEBUG - { - CRYPTO_THREADID id; - CRYPTO_THREADID_current(&id); - fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", - CRYPTO_THREADID_hash(&id), - *pointer, amount, ret, - CRYPTO_get_lock_name(type), file, line); - } -#endif - *pointer = ret; - CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line); - } - return (ret); -} - -const char *CRYPTO_get_lock_name(int type) -{ - if (type < 0) - return ("dynamic"); - else if (type < CRYPTO_NUM_LOCKS) - return (lock_names[type]); - else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks)) - return ("ERROR"); - else - return (sk_OPENSSL_STRING_value(app_locks, type - CRYPTO_NUM_LOCKS)); -} - -#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__INTEL__) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) - -extern unsigned int OPENSSL_ia32cap_P[4]; -unsigned long *OPENSSL_ia32cap_loc(void) -{ - if (sizeof(long) == 4) - /* - * If 32-bit application pulls address of OPENSSL_ia32cap_P[0] - * clear second element to maintain the illusion that vector - * is 32-bit. - */ - OPENSSL_ia32cap_P[1] = 0; - - OPENSSL_ia32cap_P[2] = 0; - - return (unsigned long *)OPENSSL_ia32cap_P; -} - -# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) -# define OPENSSL_CPUID_SETUP -# if defined(_WIN32) -typedef unsigned __int64 IA32CAP; -# else -typedef unsigned long long IA32CAP; -# endif -void OPENSSL_cpuid_setup(void) -{ - static int trigger = 0; - IA32CAP OPENSSL_ia32_cpuid(unsigned int *); - IA32CAP vec; - char *env; - - if (trigger) - return; - - trigger = 1; - if ((env = getenv("OPENSSL_ia32cap"))) { - int off = (env[0] == '~') ? 1 : 0; -# if defined(_WIN32) - if (!sscanf(env + off, "%I64i", &vec)) - vec = strtoul(env + off, NULL, 0); -# else - if (!sscanf(env + off, "%lli", (long long *)&vec)) - vec = strtoul(env + off, NULL, 0); -# endif - if (off) - vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec; - else if (env[0] == ':') - vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); - - OPENSSL_ia32cap_P[2] = 0; - if ((env = strchr(env, ':'))) { - unsigned int vecx; - env++; - off = (env[0] == '~') ? 1 : 0; - vecx = strtoul(env + off, NULL, 0); - if (off) - OPENSSL_ia32cap_P[2] &= ~vecx; - else - OPENSSL_ia32cap_P[2] = vecx; - } - } else - vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P); - - /* - * |(1<<10) sets a reserved bit to signal that variable - * was initialized already... This is to avoid interference - * with cpuid snippets in ELF .init segment. - */ - OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10); - OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32); -} -# else -unsigned int OPENSSL_ia32cap_P[4]; -# endif - -#else -unsigned long *OPENSSL_ia32cap_loc(void) -{ - return NULL; -} -#endif -int OPENSSL_NONPIC_relocated = 0; -#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) -void OPENSSL_cpuid_setup(void) -{ -} -#endif - -#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) -# ifdef __CYGWIN__ -/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ -# include -/* - * this has side-effect of _WIN32 getting defined, which otherwise is - * mutually exclusive with __CYGWIN__... - */ -# endif - -/* - * All we really need to do is remove the 'error' state when a thread - * detaches - */ - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) { - case DLL_PROCESS_ATTACH: - OPENSSL_cpuid_setup(); -# if defined(_WIN32_WINNT) - { - IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL; - IMAGE_NT_HEADERS *nt_headers; - - if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) { - nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header - + dos_header->e_lfanew); - if (nt_headers->Signature == IMAGE_NT_SIGNATURE && - hinstDLL != - (HINSTANCE) (nt_headers->OptionalHeader.ImageBase)) - OPENSSL_NONPIC_relocated = 1; - } - } -# endif - break; - case DLL_THREAD_ATTACH: - break; - case DLL_THREAD_DETACH: - break; - case DLL_PROCESS_DETACH: - break; - } - return (TRUE); -} -#endif - -#if defined(_WIN32) && !defined(__CYGWIN__) -# include -# include -# ifdef __WATCOMC__ -# if defined(_UNICODE) || defined(__UNICODE__) -# define _vsntprintf _vsnwprintf -# else -# define _vsntprintf _vsnprintf -# endif -# endif -# ifdef _MSC_VER -# define alloca _alloca -# endif - -# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 -int OPENSSL_isservice(void) -{ - HWINSTA h; - DWORD len; - WCHAR *name; - static union { - void *p; - int (*f) (void); - } _OPENSSL_isservice = { - NULL - }; - - if (_OPENSSL_isservice.p == NULL) { - HANDLE h = GetModuleHandle(NULL); - if (h != NULL) - _OPENSSL_isservice.p = GetProcAddress(h, "_OPENSSL_isservice"); - if (_OPENSSL_isservice.p == NULL) - _OPENSSL_isservice.p = (void *)-1; - } - - if (_OPENSSL_isservice.p != (void *)-1) - return (*_OPENSSL_isservice.f) (); - - h = GetProcessWindowStation(); - if (h == NULL) - return -1; - - if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) || - GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return -1; - - if (len > 512) - return -1; /* paranoia */ - len++, len &= ~1; /* paranoia */ - name = (WCHAR *)alloca(len + sizeof(WCHAR)); - if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len)) - return -1; - - len++, len &= ~1; /* paranoia */ - name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */ -# if 1 - /* - * This doesn't cover "interactive" services [working with real - * WinSta0's] nor programs started non-interactively by Task Scheduler - * [those are working with SAWinSta]. - */ - if (wcsstr(name, L"Service-0x")) - return 1; -# else - /* This covers all non-interactive programs such as services. */ - if (!wcsstr(name, L"WinSta0")) - return 1; -# endif - else - return 0; -} -# else -int OPENSSL_isservice(void) -{ - return 0; -} -# endif - -void OPENSSL_showfatal(const char *fmta, ...) -{ - va_list ap; - TCHAR buf[256]; - const TCHAR *fmt; -# ifdef STD_ERROR_HANDLE /* what a dirty trick! */ - HANDLE h; - - if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL && - GetFileType(h) != FILE_TYPE_UNKNOWN) { - /* must be console application */ - int len; - DWORD out; - - va_start(ap, fmta); - len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap); - WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL); - va_end(ap); - return; - } -# endif - - if (sizeof(TCHAR) == sizeof(char)) - fmt = (const TCHAR *)fmta; - else - do { - int keepgoing; - size_t len_0 = strlen(fmta) + 1, i; - WCHAR *fmtw; - - fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR)); - if (fmtw == NULL) { - fmt = (const TCHAR *)L"no stack?"; - break; - } -# ifndef OPENSSL_NO_MULTIBYTE - if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0)) -# endif - for (i = 0; i < len_0; i++) - fmtw[i] = (WCHAR)fmta[i]; - - for (i = 0; i < len_0; i++) { - if (fmtw[i] == L'%') - do { - keepgoing = 0; - switch (fmtw[i + 1]) { - case L'0': - case L'1': - case L'2': - case L'3': - case L'4': - case L'5': - case L'6': - case L'7': - case L'8': - case L'9': - case L'.': - case L'*': - case L'-': - i++; - keepgoing = 1; - break; - case L's': - fmtw[i + 1] = L'S'; - break; - case L'S': - fmtw[i + 1] = L's'; - break; - case L'c': - fmtw[i + 1] = L'C'; - break; - case L'C': - fmtw[i + 1] = L'c'; - break; - } - } while (keepgoing); - } - fmt = (const TCHAR *)fmtw; - } while (0); - - va_start(ap, fmta); - _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap); - buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0'); - va_end(ap); - -# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 - /* this -------------v--- guards NT-specific calls */ - if (check_winnt() && OPENSSL_isservice() > 0) { - HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL")); - - if (hEventLog != NULL) { - const TCHAR *pmsg = buf; - - if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL, - 1, 0, &pmsg, NULL)) { -#if defined(DEBUG) - /* - * We are in a situation where we tried to report a critical - * error and this failed for some reason. As a last resort, - * in debug builds, send output to the debugger or any other - * tool like DebugView which can monitor the output. - */ - OutputDebugString(pmsg); -#endif - } - - (void)DeregisterEventSource(hEventLog); - } - } else -# endif - MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR); -} -#else -void OPENSSL_showfatal(const char *fmta, ...) -{ - va_list ap; - - va_start(ap, fmta); - vfprintf(stderr, fmta, ap); - va_end(ap); -} - -int OPENSSL_isservice(void) -{ - return 0; -} -#endif - -void OpenSSLDie(const char *file, int line, const char *assertion) -{ - OPENSSL_showfatal - ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line, - assertion); -#if !defined(_WIN32) || defined(__CYGWIN__) - abort(); -#else - /* - * Win32 abort() customarily shows a dialog, but we just did that... - */ -# if !defined(_WIN32_WCE) - raise(SIGABRT); -# endif - _exit(3); -#endif -} - -void *OPENSSL_stderr(void) -{ - return stderr; -} - -int CRYPTO_memcmp(const volatile void *in_a, const volatile void *in_b, size_t len) -{ - size_t i; - const volatile unsigned char *a = in_a; - const volatile unsigned char *b = in_b; - unsigned char x = 0; - - for (i = 0; i < len; i++) - x |= a[i] ^ b[i]; - - return x; -} diff --git a/Sources/COpenSSL/cryptlib.h b/Sources/COpenSSL/cryptlib.h deleted file mode 100644 index ee9e58c3..00000000 --- a/Sources/COpenSSL/cryptlib.h +++ /dev/null @@ -1,113 +0,0 @@ -/* crypto/cryptlib.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_CRYPTLIB_H -# define HEADER_CRYPTLIB_H - -# include -# include - -# include "e_os.h" - -# ifdef OPENSSL_USE_APPLINK -# define BIO_FLAGS_UPLINK 0x8000 -# include "ms/uplink.h" -# endif - -# include "crypto.h" -# include "buffer.h" -# include "bio.h" -# include "err.h" -# include "opensslconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# ifndef OPENSSL_SYS_VMS -# define X509_CERT_AREA OPENSSLDIR -# define X509_CERT_DIR OPENSSLDIR "/certs" -# define X509_CERT_FILE OPENSSLDIR "/cert.pem" -# define X509_PRIVATE_DIR OPENSSLDIR "/private" -# else -# define X509_CERT_AREA "SSLROOT:[000000]" -# define X509_CERT_DIR "SSLCERTS:" -# define X509_CERT_FILE "SSLCERTS:cert.pem" -# define X509_PRIVATE_DIR "SSLPRIVATE:" -# endif - -# define X509_CERT_DIR_EVP "SSL_CERT_DIR" -# define X509_CERT_FILE_EVP "SSL_CERT_FILE" - -/* size of string representations */ -# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) -# define HEX_SIZE(type) (sizeof(type)*2) - -void OPENSSL_cpuid_setup(void); -extern unsigned int OPENSSL_ia32cap_P[]; -void OPENSSL_showfatal(const char *fmta, ...); -void *OPENSSL_stderr(void); -extern int OPENSSL_NONPIC_relocated; - -char *ossl_safe_getenv(const char *); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/crypto.h b/Sources/COpenSSL/crypto.h deleted file mode 100644 index e962ec3b..00000000 --- a/Sources/COpenSSL/crypto.h +++ /dev/null @@ -1,661 +0,0 @@ -/* crypto/crypto.h */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#ifndef HEADER_CRYPTO_H -# define HEADER_CRYPTO_H - -# include - -# include "e_os2.h" - -# ifndef OPENSSL_NO_FP_API -# include -# endif - -# include "stack.h" -# include "safestack.h" -# include "opensslv.h" -# include "ossl_typ.h" - -# ifdef CHARSET_EBCDIC -# include "ebcdic.h" -# endif - -/* - * Resolve problems on some operating systems with symbol names that clash - * one way or another - */ -# include "symhacks.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Backward compatibility to SSLeay */ -/* - * This is more to be used to check the correct DLL is being used in the MS - * world. - */ -# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER -# define SSLEAY_VERSION 0 -/* #define SSLEAY_OPTIONS 1 no longer supported */ -# define SSLEAY_CFLAGS 2 -# define SSLEAY_BUILT_ON 3 -# define SSLEAY_PLATFORM 4 -# define SSLEAY_DIR 5 - -/* Already declared in ossl_typ.h */ -# if 0 -typedef struct crypto_ex_data_st CRYPTO_EX_DATA; -/* Called when a new object is created */ -typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp); -/* Called when an object is free()ed */ -typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp); -/* Called when we need to dup an object */ -typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, - void *from_d, int idx, long argl, void *argp); -# endif - -/* A generic structure to pass assorted data in a expandable way */ -typedef struct openssl_item_st { - int code; - void *value; /* Not used for flag attributes */ - size_t value_size; /* Max size of value for output, length for - * input */ - size_t *value_length; /* Returned length of value for output */ -} OPENSSL_ITEM; - -/* - * When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock - * names in cryptlib.c - */ - -# define CRYPTO_LOCK_ERR 1 -# define CRYPTO_LOCK_EX_DATA 2 -# define CRYPTO_LOCK_X509 3 -# define CRYPTO_LOCK_X509_INFO 4 -# define CRYPTO_LOCK_X509_PKEY 5 -# define CRYPTO_LOCK_X509_CRL 6 -# define CRYPTO_LOCK_X509_REQ 7 -# define CRYPTO_LOCK_DSA 8 -# define CRYPTO_LOCK_RSA 9 -# define CRYPTO_LOCK_EVP_PKEY 10 -# define CRYPTO_LOCK_X509_STORE 11 -# define CRYPTO_LOCK_SSL_CTX 12 -# define CRYPTO_LOCK_SSL_CERT 13 -# define CRYPTO_LOCK_SSL_SESSION 14 -# define CRYPTO_LOCK_SSL_SESS_CERT 15 -# define CRYPTO_LOCK_SSL 16 -# define CRYPTO_LOCK_SSL_METHOD 17 -# define CRYPTO_LOCK_RAND 18 -# define CRYPTO_LOCK_RAND2 19 -# define CRYPTO_LOCK_MALLOC 20 -# define CRYPTO_LOCK_BIO 21 -# define CRYPTO_LOCK_GETHOSTBYNAME 22 -# define CRYPTO_LOCK_GETSERVBYNAME 23 -# define CRYPTO_LOCK_READDIR 24 -# define CRYPTO_LOCK_RSA_BLINDING 25 -# define CRYPTO_LOCK_DH 26 -# define CRYPTO_LOCK_MALLOC2 27 -# define CRYPTO_LOCK_DSO 28 -# define CRYPTO_LOCK_DYNLOCK 29 -# define CRYPTO_LOCK_ENGINE 30 -# define CRYPTO_LOCK_UI 31 -# define CRYPTO_LOCK_ECDSA 32 -# define CRYPTO_LOCK_EC 33 -# define CRYPTO_LOCK_ECDH 34 -# define CRYPTO_LOCK_BN 35 -# define CRYPTO_LOCK_EC_PRE_COMP 36 -# define CRYPTO_LOCK_STORE 37 -# define CRYPTO_LOCK_COMP 38 -# define CRYPTO_LOCK_FIPS 39 -# define CRYPTO_LOCK_FIPS2 40 -# define CRYPTO_NUM_LOCKS 41 - -# define CRYPTO_LOCK 1 -# define CRYPTO_UNLOCK 2 -# define CRYPTO_READ 4 -# define CRYPTO_WRITE 8 - -# ifndef OPENSSL_NO_LOCKING -# ifndef CRYPTO_w_lock -# define CRYPTO_w_lock(type) \ - CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) -# define CRYPTO_w_unlock(type) \ - CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) -# define CRYPTO_r_lock(type) \ - CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) -# define CRYPTO_r_unlock(type) \ - CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) -# define CRYPTO_add(addr,amount,type) \ - CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) -# endif -# else -# define CRYPTO_w_lock(a) -# define CRYPTO_w_unlock(a) -# define CRYPTO_r_lock(a) -# define CRYPTO_r_unlock(a) -# define CRYPTO_add(a,b,c) ((*(a))+=(b)) -# endif - -/* - * Some applications as well as some parts of OpenSSL need to allocate and - * deallocate locks in a dynamic fashion. The following typedef makes this - * possible in a type-safe manner. - */ -/* struct CRYPTO_dynlock_value has to be defined by the application. */ -typedef struct { - int references; - struct CRYPTO_dynlock_value *data; -} CRYPTO_dynlock; - -/* - * The following can be used to detect memory leaks in the SSLeay library. It - * used, it turns on malloc checking - */ - -# define CRYPTO_MEM_CHECK_OFF 0x0/* an enume */ -# define CRYPTO_MEM_CHECK_ON 0x1/* a bit */ -# define CRYPTO_MEM_CHECK_ENABLE 0x2/* a bit */ -# define CRYPTO_MEM_CHECK_DISABLE 0x3/* an enume */ - -/* - * The following are bit values to turn on or off options connected to the - * malloc checking functionality - */ - -/* Adds time to the memory checking information */ -# define V_CRYPTO_MDEBUG_TIME 0x1/* a bit */ -/* Adds thread number to the memory checking information */ -# define V_CRYPTO_MDEBUG_THREAD 0x2/* a bit */ - -# define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD) - -/* predec of the BIO type */ -typedef struct bio_st BIO_dummy; - -struct crypto_ex_data_st { - STACK_OF(void) *sk; - /* gcc is screwing up this data structure :-( */ - int dummy; -}; -DECLARE_STACK_OF(void) - -/* - * This stuff is basically class callback functions The current classes are - * SSL_CTX, SSL, SSL_SESSION, and a few more - */ - -typedef struct crypto_ex_data_func_st { - long argl; /* Arbitary long */ - void *argp; /* Arbitary void * */ - CRYPTO_EX_new *new_func; - CRYPTO_EX_free *free_func; - CRYPTO_EX_dup *dup_func; -} CRYPTO_EX_DATA_FUNCS; - -DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) - -/* - * Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA - * entry. - */ - -# define CRYPTO_EX_INDEX_BIO 0 -# define CRYPTO_EX_INDEX_SSL 1 -# define CRYPTO_EX_INDEX_SSL_CTX 2 -# define CRYPTO_EX_INDEX_SSL_SESSION 3 -# define CRYPTO_EX_INDEX_X509_STORE 4 -# define CRYPTO_EX_INDEX_X509_STORE_CTX 5 -# define CRYPTO_EX_INDEX_RSA 6 -# define CRYPTO_EX_INDEX_DSA 7 -# define CRYPTO_EX_INDEX_DH 8 -# define CRYPTO_EX_INDEX_ENGINE 9 -# define CRYPTO_EX_INDEX_X509 10 -# define CRYPTO_EX_INDEX_UI 11 -# define CRYPTO_EX_INDEX_ECDSA 12 -# define CRYPTO_EX_INDEX_ECDH 13 -# define CRYPTO_EX_INDEX_COMP 14 -# define CRYPTO_EX_INDEX_STORE 15 - -/* - * Dynamically assigned indexes start from this value (don't use directly, - * use via CRYPTO_ex_data_new_class). - */ -# define CRYPTO_EX_INDEX_USER 100 - -/* - * This is the default callbacks, but we can have others as well: this is - * needed in Win32 where the application malloc and the library malloc may - * not be the same. - */ -# define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\ - malloc, realloc, free) - -# if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD -# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */ -# define CRYPTO_MDEBUG -# endif -# endif - -/* - * Set standard debugging functions (not done by default unless CRYPTO_MDEBUG - * is defined) - */ -# define CRYPTO_malloc_debug_init() do {\ - CRYPTO_set_mem_debug_functions(\ - CRYPTO_dbg_malloc,\ - CRYPTO_dbg_realloc,\ - CRYPTO_dbg_free,\ - CRYPTO_dbg_set_options,\ - CRYPTO_dbg_get_options);\ - } while(0) - -int CRYPTO_mem_ctrl(int mode); -int CRYPTO_is_mem_check_on(void); - -/* for applications */ -# define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) -# define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) - -/* for library-internal use */ -# define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) -# define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) -# define is_MemCheck_on() CRYPTO_is_mem_check_on() - -# define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) -# define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) -# define OPENSSL_realloc(addr,num) \ - CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) -# define OPENSSL_realloc_clean(addr,old_num,num) \ - CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__) -# define OPENSSL_remalloc(addr,num) \ - CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__) -# define OPENSSL_freeFunc CRYPTO_free -# define OPENSSL_free(addr) CRYPTO_free(addr) - -# define OPENSSL_malloc_locked(num) \ - CRYPTO_malloc_locked((int)num,__FILE__,__LINE__) -# define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) - -const char *SSLeay_version(int type); -unsigned long SSLeay(void); - -int OPENSSL_issetugid(void); - -/* An opaque type representing an implementation of "ex_data" support */ -typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL; -/* Return an opaque pointer to the current "ex_data" implementation */ -const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void); -/* Sets the "ex_data" implementation to be used (if it's not too late) */ -int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i); -/* Get a new "ex_data" class, and return the corresponding "class_index" */ -int CRYPTO_ex_data_new_class(void); -/* Within a given class, get/register a new index */ -int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, - CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); -/* - * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a - * given class (invokes whatever per-class callbacks are applicable) - */ -int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); -int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, - CRYPTO_EX_DATA *from); -void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); -/* - * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular - * index (relative to the class type involved) - */ -int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); -void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); -/* - * This function cleans up all "ex_data" state. It mustn't be called under - * potential race-conditions. - */ -void CRYPTO_cleanup_all_ex_data(void); - -int CRYPTO_get_new_lockid(char *name); - -int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */ -void CRYPTO_lock(int mode, int type, const char *file, int line); -void CRYPTO_set_locking_callback(void (*func) (int mode, int type, - const char *file, int line)); -void (*CRYPTO_get_locking_callback(void)) (int mode, int type, - const char *file, int line); -void CRYPTO_set_add_lock_callback(int (*func) - (int *num, int mount, int type, - const char *file, int line)); -int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type, - const char *file, int line); - -/* Don't use this structure directly. */ -typedef struct crypto_threadid_st { - void *ptr; - unsigned long val; -} CRYPTO_THREADID; -/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ -void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); -void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); -int CRYPTO_THREADID_set_callback(void (*threadid_func) (CRYPTO_THREADID *)); -void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *); -void CRYPTO_THREADID_current(CRYPTO_THREADID *id); -int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); -void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); -unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); -# ifndef OPENSSL_NO_DEPRECATED -void CRYPTO_set_id_callback(unsigned long (*func) (void)); -unsigned long (*CRYPTO_get_id_callback(void)) (void); -unsigned long CRYPTO_thread_id(void); -# endif - -const char *CRYPTO_get_lock_name(int type); -int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, - int line); - -int CRYPTO_get_new_dynlockid(void); -void CRYPTO_destroy_dynlockid(int i); -struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); -void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value - *(*dyn_create_function) (const char - *file, - int line)); -void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function) - (int mode, - struct CRYPTO_dynlock_value *l, - const char *file, int line)); -void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function) - (struct CRYPTO_dynlock_value *l, - const char *file, int line)); -struct CRYPTO_dynlock_value -*(*CRYPTO_get_dynlock_create_callback(void)) (const char *file, int line); -void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode, - struct CRYPTO_dynlock_value - *l, const char *file, - int line); -void (*CRYPTO_get_dynlock_destroy_callback(void)) (struct CRYPTO_dynlock_value - *l, const char *file, - int line); - -/* - * CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- call - * the latter last if you need different functions - */ -int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), - void (*f) (void *)); -int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), - void (*free_func) (void *)); -int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), - void *(*r) (void *, size_t, const char *, - int), void (*f) (void *)); -int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), - void (*free_func) (void *)); -int CRYPTO_set_mem_debug_functions(void (*m) - (void *, int, const char *, int, int), - void (*r) (void *, void *, int, - const char *, int, int), - void (*f) (void *, int), void (*so) (long), - long (*go) (void)); -void CRYPTO_get_mem_functions(void *(**m) (size_t), - void *(**r) (void *, size_t), - void (**f) (void *)); -void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), - void (**f) (void *)); -void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), - void *(**r) (void *, size_t, const char *, - int), void (**f) (void *)); -void CRYPTO_get_locked_mem_ex_functions(void - *(**m) (size_t, const char *, int), - void (**f) (void *)); -void CRYPTO_get_mem_debug_functions(void (**m) - (void *, int, const char *, int, int), - void (**r) (void *, void *, int, - const char *, int, int), - void (**f) (void *, int), - void (**so) (long), long (**go) (void)); - -void *CRYPTO_malloc_locked(int num, const char *file, int line); -void CRYPTO_free_locked(void *ptr); -void *CRYPTO_malloc(int num, const char *file, int line); -char *CRYPTO_strdup(const char *str, const char *file, int line); -void CRYPTO_free(void *ptr); -void *CRYPTO_realloc(void *addr, int num, const char *file, int line); -void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file, - int line); -void *CRYPTO_remalloc(void *addr, int num, const char *file, int line); - -void OPENSSL_cleanse(void *ptr, size_t len); - -void CRYPTO_set_mem_debug_options(long bits); -long CRYPTO_get_mem_debug_options(void); - -# define CRYPTO_push_info(info) \ - CRYPTO_push_info_(info, __FILE__, __LINE__); -int CRYPTO_push_info_(const char *info, const char *file, int line); -int CRYPTO_pop_info(void); -int CRYPTO_remove_all_info(void); - -/* - * Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro; - * used as default in CRYPTO_MDEBUG compilations): - */ -/*- - * The last argument has the following significance: - * - * 0: called before the actual memory allocation has taken place - * 1: called after the actual memory allocation has taken place - */ -void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, - int before_p); -void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file, - int line, int before_p); -void CRYPTO_dbg_free(void *addr, int before_p); -/*- - * Tell the debugging code about options. By default, the following values - * apply: - * - * 0: Clear all options. - * V_CRYPTO_MDEBUG_TIME (1): Set the "Show Time" option. - * V_CRYPTO_MDEBUG_THREAD (2): Set the "Show Thread Number" option. - * V_CRYPTO_MDEBUG_ALL (3): 1 + 2 - */ -void CRYPTO_dbg_set_options(long bits); -long CRYPTO_dbg_get_options(void); - -# ifndef OPENSSL_NO_FP_API -void CRYPTO_mem_leaks_fp(FILE *); -# endif -void CRYPTO_mem_leaks(struct bio_st *bio); -/* unsigned long order, char *file, int line, int num_bytes, char *addr */ -typedef void *CRYPTO_MEM_LEAK_CB (unsigned long, const char *, int, int, - void *); -void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); - -/* die if we have to */ -void OpenSSLDie(const char *file, int line, const char *assertion); -# define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1)) - -unsigned long *OPENSSL_ia32cap_loc(void); -# define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) -int OPENSSL_isservice(void); - -int FIPS_mode(void); -int FIPS_mode_set(int r); - -void OPENSSL_init(void); - -# define fips_md_init(alg) fips_md_init_ctx(alg, alg) - -# ifdef OPENSSL_FIPS -# define fips_md_init_ctx(alg, cx) \ - int alg##_Init(cx##_CTX *c) \ - { \ - if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ - "Low level API call to digest " #alg " forbidden in FIPS mode!"); \ - return private_##alg##_Init(c); \ - } \ - int private_##alg##_Init(cx##_CTX *c) - -# define fips_cipher_abort(alg) \ - if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ - "Low level API call to cipher " #alg " forbidden in FIPS mode!") - -# else -# define fips_md_init_ctx(alg, cx) \ - int alg##_Init(cx##_CTX *c) -# define fips_cipher_abort(alg) while(0) -# endif - -/* - * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. - * It takes an amount of time dependent on |len|, but independent of the - * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements - * into a defined order as the return value when a != b is undefined, other - * than to be non-zero. - */ -int CRYPTO_memcmp(const volatile void *a, const volatile void *b, size_t len); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_CRYPTO_strings(void); - -/* Error codes for the CRYPTO functions. */ - -/* Function codes. */ -# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 -# define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID 103 -# define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101 -# define CRYPTO_F_CRYPTO_SET_EX_DATA 102 -# define CRYPTO_F_DEF_ADD_INDEX 104 -# define CRYPTO_F_DEF_GET_CLASS 105 -# define CRYPTO_F_FIPS_MODE_SET 109 -# define CRYPTO_F_INT_DUP_EX_DATA 106 -# define CRYPTO_F_INT_FREE_EX_DATA 107 -# define CRYPTO_F_INT_NEW_EX_DATA 108 - -/* Reason codes. */ -# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 -# define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/cswift.h b/Sources/COpenSSL/cswift.h deleted file mode 100644 index 6dcd5fed..00000000 --- a/Sources/COpenSSL/cswift.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Attribution notice: Rainbow have generously allowed me to reproduce the - * necessary definitions here from their API. This means the support can - * build independently of whether application builders have the API or - * hardware. This will allow developers to easily produce software that has - * latent hardware support for any users that have accelertors installed, - * without the developers themselves needing anything extra. I have only - * clipped the parts from the CryptoSwift header files that are (or seem) - * relevant to the CryptoSwift support code. This is simply to keep the file - * sizes reasonable. [Geoff] - */ - -/* - * NB: These type widths do *not* seem right in general, in particular - * they're not terribly friendly to 64-bit architectures (unsigned long) will - * be 64-bit on IA-64 for a start. I'm leaving these alone as they agree with - * Rainbow's API and this will only be called into question on platforms with - * Rainbow support anyway! ;-) - */ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - typedef long SW_STATUS; /* status */ - typedef unsigned char SW_BYTE; /* 8 bit byte */ - typedef unsigned short SW_U16; /* 16 bit number */ -#if defined(_IRIX) -# include - typedef __uint32_t SW_U32; -#else - typedef unsigned long SW_U32; /* 32 bit integer */ -#endif - -#if defined(OPENSSL_SYS_WIN32) - typedef struct _SW_U64 { - SW_U32 low32; - SW_U32 high32; - } SW_U64; /* 64 bit integer */ -#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC) - typedef longlong SW_U64 -#else /* Unix variants */ - typedef struct _SW_U64 { - SW_U32 low32; - SW_U32 high32; - } SW_U64; /* 64 bit integer */ -#endif - -/* status codes */ -#define SW_OK (0L) -#define SW_ERR_BASE (-10000L) -#define SW_ERR_NO_CARD (SW_ERR_BASE-1) /* The Card is not present */ -#define SW_ERR_CARD_NOT_READY (SW_ERR_BASE-2) /* The card has not powered */ - /* up yet */ -#define SW_ERR_TIME_OUT (SW_ERR_BASE-3) /* Execution of a command */ - /* time out */ -#define SW_ERR_NO_EXECUTE (SW_ERR_BASE-4) /* The Card failed to */ - /* execute the command */ -#define SW_ERR_INPUT_NULL_PTR (SW_ERR_BASE-5) /* a required pointer is */ - /* NULL */ -#define SW_ERR_INPUT_SIZE (SW_ERR_BASE-6) /* size is invalid, too */ - /* small, too large. */ -#define SW_ERR_INVALID_HANDLE (SW_ERR_BASE-7) /* Invalid SW_ACC_CONTEXT */ - /* handle */ -#define SW_ERR_PENDING (SW_ERR_BASE-8) /* A request is already out- */ - /* standing at this */ - /* context handle */ -#define SW_ERR_AVAILABLE (SW_ERR_BASE-9) /* A result is available. */ -#define SW_ERR_NO_PENDING (SW_ERR_BASE-10) /* No request is pending. */ -#define SW_ERR_NO_MEMORY (SW_ERR_BASE-11) /* Not enough memory */ -#define SW_ERR_BAD_ALGORITHM (SW_ERR_BASE-12) /* Invalid algorithm type */ - /* in SW_PARAM structure */ -#define SW_ERR_MISSING_KEY (SW_ERR_BASE-13) /* No key is associated with */ - /* context. */ - /* swAttachKeyParam() is */ - /* not called. */ -#define SW_ERR_KEY_CMD_MISMATCH \ - (SW_ERR_BASE-14) /* Cannot perform requested */ - /* SW_COMMAND_CODE since */ - /* key attached via */ - /* swAttachKeyParam() */ - /* cannot be used for this */ - /* SW_COMMAND_CODE. */ -#define SW_ERR_NOT_IMPLEMENTED \ - (SW_ERR_BASE-15) /* Not implemented */ -#define SW_ERR_BAD_COMMAND (SW_ERR_BASE-16) /* Bad command code */ -#define SW_ERR_BAD_ITEM_SIZE (SW_ERR_BASE-17) /* too small or too large in */ - /* the "initems" or */ - /* "outitems". */ -#define SW_ERR_BAD_ACCNUM (SW_ERR_BASE-18) /* Bad accelerator number */ -#define SW_ERR_SELFTEST_FAIL (SW_ERR_BASE-19) /* At least one of the self */ - /* test fail, look at the */ - /* selfTestBitmap in */ - /* SW_ACCELERATOR_INFO for */ - /* details. */ -#define SW_ERR_MISALIGN (SW_ERR_BASE-20) /* Certain alogrithms require */ - /* key materials aligned */ - /* in certain order, e.g. */ - /* 128 bit for CRT */ -#define SW_ERR_OUTPUT_NULL_PTR \ - (SW_ERR_BASE-21) /* a required pointer is */ - /* NULL */ -#define SW_ERR_OUTPUT_SIZE \ - (SW_ERR_BASE-22) /* size is invalid, too */ - /* small, too large. */ -#define SW_ERR_FIRMWARE_CHECKSUM \ - (SW_ERR_BASE-23) /* firmware checksum mismatch */ - /* download failed. */ -#define SW_ERR_UNKNOWN_FIRMWARE \ - (SW_ERR_BASE-24) /* unknown firmware error */ -#define SW_ERR_INTERRUPT (SW_ERR_BASE-25) /* request is abort when */ - /* it's waiting to be */ - /* completed. */ -#define SW_ERR_NVWRITE_FAIL (SW_ERR_BASE-26) /* error in writing to Non- */ - /* volatile memory */ -#define SW_ERR_NVWRITE_RANGE (SW_ERR_BASE-27) /* out of range error in */ - /* writing to NV memory */ -#define SW_ERR_RNG_ERROR (SW_ERR_BASE-28) /* Random Number Generation */ - /* failure */ -#define SW_ERR_DSS_FAILURE (SW_ERR_BASE-29) /* DSS Sign or Verify failure */ -#define SW_ERR_MODEXP_FAILURE (SW_ERR_BASE-30) /* Failure in various math */ - /* calculations */ -#define SW_ERR_ONBOARD_MEMORY (SW_ERR_BASE-31) /* Error in accessing on - */ - /* board memory */ -#define SW_ERR_FIRMWARE_VERSION \ - (SW_ERR_BASE-32) /* Wrong version in firmware */ - /* update */ -#define SW_ERR_ZERO_WORKING_ACCELERATOR \ - (SW_ERR_BASE-44) /* All accelerators are bad */ - - /* algorithm type */ -#define SW_ALG_CRT 1 -#define SW_ALG_EXP 2 -#define SW_ALG_DSA 3 -#define SW_ALG_NVDATA 4 - - /* command code */ -#define SW_CMD_MODEXP_CRT 1 /* perform Modular Exponentiation using */ - /* Chinese Remainder Theorem (CRT) */ -#define SW_CMD_MODEXP 2 /* perform Modular Exponentiation */ -#define SW_CMD_DSS_SIGN 3 /* perform DSS sign */ -#define SW_CMD_DSS_VERIFY 4 /* perform DSS verify */ -#define SW_CMD_RAND 5 /* perform random number generation */ -#define SW_CMD_NVREAD 6 /* perform read to nonvolatile RAM */ -#define SW_CMD_NVWRITE 7 /* perform write to nonvolatile RAM */ - - typedef SW_U32 SW_ALGTYPE; /* alogrithm type */ - typedef SW_U32 SW_STATE; /* state */ - typedef SW_U32 SW_COMMAND_CODE; /* command code */ - typedef SW_U32 SW_COMMAND_BITMAP[4]; /* bitmap */ - - typedef struct _SW_LARGENUMBER { - SW_U32 nbytes; /* number of bytes in the buffer "value" */ - SW_BYTE *value; /* the large integer as a string of */ - /* bytes in network (big endian) order */ - } SW_LARGENUMBER; - -#if defined(OPENSSL_SYS_WIN32) -# include - typedef HANDLE SW_OSHANDLE; /* handle to kernel object */ -# define SW_OS_INVALID_HANDLE INVALID_HANDLE_VALUE -# define SW_CALLCONV _stdcall -#elif defined(OPENSSL_SYS_MACINTOSH_CLASSIC) - /* async callback mechanisms */ - /* swiftCallbackLevel */ -# define SW_MAC_CALLBACK_LEVEL_NO 0 -# define SW_MAC_CALLBACK_LEVEL_HARDWARE 1/* from the hardware ISR */ -# define SW_MAC_CALLBACK_LEVEL_SECONDARY 2/* as secondary ISR */ - typedef int SW_MAC_CALLBACK_LEVEL; - typedef int SW_OSHANDLE; -# define SW_OS_INVALID_HANDLE (-1) -# define SW_CALLCONV -#else /* Unix variants */ - typedef int SW_OSHANDLE; /* handle to driver */ -# define SW_OS_INVALID_HANDLE (-1) -# define SW_CALLCONV -#endif - - typedef struct _SW_CRT { - SW_LARGENUMBER p; /* prime number p */ - SW_LARGENUMBER q; /* prime number q */ - SW_LARGENUMBER dmp1; /* exponent1 */ - SW_LARGENUMBER dmq1; /* exponent2 */ - SW_LARGENUMBER iqmp; /* CRT coefficient */ - } SW_CRT; - - typedef struct _SW_EXP { - SW_LARGENUMBER modulus; /* modulus */ - SW_LARGENUMBER exponent; /* exponent */ - } SW_EXP; - - typedef struct _SW_DSA { - SW_LARGENUMBER p; /* */ - SW_LARGENUMBER q; /* */ - SW_LARGENUMBER g; /* */ - SW_LARGENUMBER key; /* private/public key */ - } SW_DSA; - - typedef struct _SW_NVDATA { - SW_U32 accnum; /* accelerator board number */ - SW_U32 offset; /* offset in byte */ - } SW_NVDATA; - - typedef struct _SW_PARAM { - SW_ALGTYPE type; /* type of the alogrithm */ - union { - SW_CRT crt; - SW_EXP exp; - SW_DSA dsa; - SW_NVDATA nvdata; - } up; - } SW_PARAM; - - typedef SW_U32 SW_CONTEXT_HANDLE; /* opaque context handle */ - - /* - * Now the OpenSSL bits, these function types are the for the function - * pointers that will bound into the Rainbow shared libraries. - */ - typedef SW_STATUS SW_CALLCONV t_swAcquireAccContext(SW_CONTEXT_HANDLE - *hac); - typedef SW_STATUS SW_CALLCONV t_swAttachKeyParam(SW_CONTEXT_HANDLE hac, - SW_PARAM *key_params); - typedef SW_STATUS SW_CALLCONV t_swSimpleRequest(SW_CONTEXT_HANDLE hac, - SW_COMMAND_CODE cmd, - SW_LARGENUMBER pin[], - SW_U32 pin_count, - SW_LARGENUMBER pout[], - SW_U32 pout_count); - typedef SW_STATUS SW_CALLCONV t_swReleaseAccContext(SW_CONTEXT_HANDLE - hac); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ diff --git a/Sources/COpenSSL/ctr128.c b/Sources/COpenSSL/ctr128.c deleted file mode 100644 index e3d6eb43..00000000 --- a/Sources/COpenSSL/ctr128.c +++ /dev/null @@ -1,263 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "crypto.h" -#include "modes_lcl.h" -#include - -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -/* - * NOTE: the IV/counter CTR mode is big-endian. The code itself is - * endian-neutral. - */ - -/* increment counter (128-bit int) by 1 */ -static void ctr128_inc(unsigned char *counter) -{ - u32 n = 16, c = 1; - - do { - --n; - c += counter[n]; - counter[n] = (u8)c; - c >>= 8; - } while (n); -} - -#if !defined(OPENSSL_SMALL_FOOTPRINT) -static void ctr128_inc_aligned(unsigned char *counter) -{ - size_t *data, c, d, n; - const union { - long one; - char little; - } is_endian = { - 1 - }; - - if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) { - ctr128_inc(counter); - return; - } - - data = (size_t *)counter; - c = 1; - n = 16 / sizeof(size_t); - do { - --n; - d = data[n] += c; - /* did addition carry? */ - c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1); - } while (n); -} -#endif - -/* - * The input encrypted as though 128bit counter mode is being used. The - * extra state information to record how much of the 128bit block we have - * used is contained in *num, and the encrypted counter is kept in - * ecount_buf. Both *num and ecount_buf must be initialised with zeros - * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes - * that the counter is in the x lower bits of the IV (ivec), and that the - * application has full control over overflow and the rest of the IV. This - * implementation takes NO responsability for checking that the counter - * doesn't overflow into the rest of the IV when incremented. - */ -void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], - unsigned char ecount_buf[16], unsigned int *num, - block128_f block) -{ - unsigned int n; - size_t l = 0; - - assert(in && out && key && ecount_buf && num); - assert(*num < 16); - - n = *num; - -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (16 % sizeof(size_t) == 0) { /* always true actually */ - do { - while (n && len) { - *(out++) = *(in++) ^ ecount_buf[n]; - --len; - n = (n + 1) % 16; - } - -# if defined(STRICT_ALIGNMENT) - if (((size_t)in | (size_t)out | (size_t)ecount_buf) - % sizeof(size_t) != 0) - break; -# endif - while (len >= 16) { - (*block) (ivec, ecount_buf, key); - ctr128_inc_aligned(ivec); - for (n = 0; n < 16; n += sizeof(size_t)) - *(size_t *)(out + n) = - *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n); - len -= 16; - out += 16; - in += 16; - n = 0; - } - if (len) { - (*block) (ivec, ecount_buf, key); - ctr128_inc_aligned(ivec); - while (len--) { - out[n] = in[n] ^ ecount_buf[n]; - ++n; - } - } - *num = n; - return; - } while (0); - } - /* the rest would be commonly eliminated by x86* compiler */ -#endif - while (l < len) { - if (n == 0) { - (*block) (ivec, ecount_buf, key); - ctr128_inc(ivec); - } - out[l] = in[l] ^ ecount_buf[n]; - ++l; - n = (n + 1) % 16; - } - - *num = n; -} - -/* increment upper 96 bits of 128-bit counter by 1 */ -static void ctr96_inc(unsigned char *counter) -{ - u32 n = 12, c = 1; - - do { - --n; - c += counter[n]; - counter[n] = (u8)c; - c >>= 8; - } while (n); -} - -void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], - unsigned char ecount_buf[16], - unsigned int *num, ctr128_f func) -{ - unsigned int n, ctr32; - - assert(in && out && key && ecount_buf && num); - assert(*num < 16); - - n = *num; - - while (n && len) { - *(out++) = *(in++) ^ ecount_buf[n]; - --len; - n = (n + 1) % 16; - } - - ctr32 = GETU32(ivec + 12); - while (len >= 16) { - size_t blocks = len / 16; - /* - * 1<<28 is just a not-so-small yet not-so-large number... - * Below condition is practically never met, but it has to - * be checked for code correctness. - */ - if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28)) - blocks = (1U << 28); - /* - * As (*func) operates on 32-bit counter, caller - * has to handle overflow. 'if' below detects the - * overflow, which is then handled by limiting the - * amount of blocks to the exact overflow point... - */ - ctr32 += (u32)blocks; - if (ctr32 < blocks) { - blocks -= ctr32; - ctr32 = 0; - } - (*func) (in, out, blocks, key, ivec); - /* (*ctr) does not update ivec, caller does: */ - PUTU32(ivec + 12, ctr32); - /* ... overflow was detected, propogate carry. */ - if (ctr32 == 0) - ctr96_inc(ivec); - blocks *= 16; - len -= blocks; - out += blocks; - in += blocks; - } - if (len) { - memset(ecount_buf, 0, 16); - (*func) (ecount_buf, ecount_buf, 1, key, ivec); - ++ctr32; - PUTU32(ivec + 12, ctr32); - if (ctr32 == 0) - ctr96_inc(ivec); - while (len--) { - out[n] = in[n] ^ ecount_buf[n]; - ++n; - } - } - - *num = n; -} diff --git a/Sources/COpenSSL/cversion.c b/Sources/COpenSSL/cversion.c deleted file mode 100644 index bfff6995..00000000 --- a/Sources/COpenSSL/cversion.c +++ /dev/null @@ -1,107 +0,0 @@ -/* crypto/cversion.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "cryptlib.h" - -#ifndef NO_WINDOWS_BRAINDEATH -# include "buildinf.h" -#endif - -const char *SSLeay_version(int t) -{ - if (t == SSLEAY_VERSION) - return OPENSSL_VERSION_TEXT; - if (t == SSLEAY_BUILT_ON) { -#ifdef DATE -# ifdef OPENSSL_USE_BUILD_DATE - return (DATE); -# else - return ("built on: reproducible build, date unspecified"); -# endif -#else - return ("built on: date not available"); -#endif - } - if (t == SSLEAY_CFLAGS) { -#ifdef CFLAGS - return (CFLAGS); -#else - return ("compiler: information not available"); -#endif - } - if (t == SSLEAY_PLATFORM) { -#ifdef PLATFORM - return (PLATFORM); -#else - return ("platform: information not available"); -#endif - } - if (t == SSLEAY_DIR) { -#ifdef OPENSSLDIR - return "OPENSSLDIR: \"" OPENSSLDIR "\""; -#else - return "OPENSSLDIR: N/A"; -#endif - } - return ("not available"); -} - -unsigned long SSLeay(void) -{ - return (SSLEAY_VERSION_NUMBER); -} diff --git a/Sources/COpenSSL/d1_.c b/Sources/COpenSSL/d1_.c deleted file mode 100644 index 4bd26443..00000000 --- a/Sources/COpenSSL/d1_.c +++ /dev/null @@ -1,6037 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ssl/d1_both.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include "ssl_locl.h" -#include "buffer.h" -#include "rand.h" -#include "objects.h" -#include "evp.h" -#include "x509.h" - -#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) - -#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ - if ((end) - (start) <= 8) { \ - long ii; \ - for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ - } else { \ - long ii; \ - bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ - for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ - bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ - } } - -#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ - long ii; \ - OPENSSL_assert((msg_len) > 0); \ - is_complete = 1; \ - if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ - if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ - if (bitmask[ii] != 0xff) { is_complete = 0; break; } } - -#if 0 -# define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ - long ii; \ - printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \ - printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \ - printf("\n"); } -#endif - -static unsigned char bitmask_start_values[] = - { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 }; -static unsigned char bitmask_end_values[] = - { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; - -/* XDTLS: figure out the right values */ -static const unsigned int g_probable_mtu[] = { 1500, 512, 256 }; - -static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, - unsigned long frag_len); -static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); -static void dtls1_set_message_header_int(SSL *s, unsigned char mt, - unsigned long len, - unsigned short seq_num, - unsigned long frag_off, - unsigned long frag_len); -static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, - int *ok); - -static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len, - int reassembly) -{ - hm_fragment *frag = NULL; - unsigned char *buf = NULL; - unsigned char *bitmask = NULL; - - frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); - if (frag == NULL) - return NULL; - - if (frag_len) { - buf = (unsigned char *)OPENSSL_malloc(frag_len); - if (buf == NULL) { - OPENSSL_free(frag); - return NULL; - } - } - - /* zero length fragment gets zero frag->fragment */ - frag->fragment = buf; - - /* Initialize reassembly bitmask if necessary */ - if (reassembly) { - bitmask = - (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len)); - if (bitmask == NULL) { - if (buf != NULL) - OPENSSL_free(buf); - OPENSSL_free(frag); - return NULL; - } - memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); - } - - frag->reassembly = bitmask; - - return frag; -} - -void dtls1_hm_fragment_free(hm_fragment *frag) -{ - - if (frag->msg_header.is_ccs) { - EVP_CIPHER_CTX_free(frag->msg_header. - saved_retransmit_state.enc_write_ctx); - EVP_MD_CTX_destroy(frag->msg_header. - saved_retransmit_state.write_hash); - } - if (frag->fragment) - OPENSSL_free(frag->fragment); - if (frag->reassembly) - OPENSSL_free(frag->reassembly); - OPENSSL_free(frag); -} - -static int dtls1_query_mtu(SSL *s) -{ - if (s->d1->link_mtu) { - s->d1->mtu = - s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); - s->d1->link_mtu = 0; - } - - /* AHA! Figure out the MTU, and stick to the right size */ - if (s->d1->mtu < dtls1_min_mtu(s)) { - if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { - s->d1->mtu = - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); - - /* - * I've seen the kernel return bogus numbers when it doesn't know - * (initial write), so just make sure we have a reasonable number - */ - if (s->d1->mtu < dtls1_min_mtu(s)) { - /* Set to min mtu */ - s->d1->mtu = dtls1_min_mtu(s); - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, - s->d1->mtu, NULL); - } - } else - return 0; - } - return 1; -} - -/* - * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or - * SSL3_RT_CHANGE_CIPHER_SPEC) - */ -int dtls1_do_write(SSL *s, int type) -{ - int ret; - unsigned int curr_mtu; - int retry = 1; - unsigned int len, frag_off, mac_size, blocksize, used_len; - - if (!dtls1_query_mtu(s)) - return -1; - - OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something - * reasonable now */ - - if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) - OPENSSL_assert(s->init_num == - (int)s->d1->w_msg_hdr.msg_len + - DTLS1_HM_HEADER_LENGTH); - - if (s->write_hash) { - if (s->enc_write_ctx - && EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_GCM_MODE) - mac_size = 0; - else - mac_size = EVP_MD_CTX_size(s->write_hash); - } else - mac_size = 0; - - if (s->enc_write_ctx && - (EVP_CIPHER_CTX_mode(s->enc_write_ctx) == EVP_CIPH_CBC_MODE)) - blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); - else - blocksize = 0; - - frag_off = 0; - s->rwstate = SSL_NOTHING; - - /* s->init_num shouldn't ever be < 0...but just in case */ - while (s->init_num > 0) { - if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) { - /* We must be writing a fragment other than the first one */ - - if (frag_off > 0) { - /* This is the first attempt at writing out this fragment */ - - if (s->init_off <= DTLS1_HM_HEADER_LENGTH) { - /* - * Each fragment that was already sent must at least have - * contained the message header plus one other byte. - * Therefore |init_off| must have progressed by at least - * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went - * wrong. - */ - return -1; - } - - /* - * Adjust |init_off| and |init_num| to allow room for a new - * message header for this fragment. - */ - s->init_off -= DTLS1_HM_HEADER_LENGTH; - s->init_num += DTLS1_HM_HEADER_LENGTH; - } else { - /* - * We must have been called again after a retry so use the - * fragment offset from our last attempt. We do not need - * to adjust |init_off| and |init_num| as above, because - * that should already have been done before the retry. - */ - frag_off = s->d1->w_msg_hdr.frag_off; - } - } - - used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH - + mac_size + blocksize; - if (s->d1->mtu > used_len) - curr_mtu = s->d1->mtu - used_len; - else - curr_mtu = 0; - - if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) { - /* - * grr.. we could get an error if MTU picked was wrong - */ - ret = BIO_flush(SSL_get_wbio(s)); - if (ret <= 0) { - s->rwstate = SSL_WRITING; - return ret; - } - used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize; - if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) { - curr_mtu = s->d1->mtu - used_len; - } else { - /* Shouldn't happen */ - return -1; - } - } - - /* - * We just checked that s->init_num > 0 so this cast should be safe - */ - if (((unsigned int)s->init_num) > curr_mtu) - len = curr_mtu; - else - len = s->init_num; - - /* Shouldn't ever happen */ - if (len > INT_MAX) - len = INT_MAX; - - /* - * XDTLS: this function is too long. split out the CCS part - */ - if (type == SSL3_RT_HANDSHAKE) { - if (len < DTLS1_HM_HEADER_LENGTH) { - /* - * len is so small that we really can't do anything sensible - * so fail - */ - return -1; - } - dtls1_fix_message_header(s, frag_off, - len - DTLS1_HM_HEADER_LENGTH); - - dtls1_write_message_header(s, - (unsigned char *)&s->init_buf-> - data[s->init_off]); - } - - ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], - len); - if (ret < 0) { - /* - * might need to update MTU here, but we don't know which - * previous packet caused the failure -- so can't really - * retransmit anything. continue as if everything is fine and - * wait for an alert to handle the retransmit - */ - if (retry && BIO_ctrl(SSL_get_wbio(s), - BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) { - if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { - if (!dtls1_query_mtu(s)) - return -1; - /* Have one more go */ - retry = 0; - } else - return -1; - } else { - return (-1); - } - } else { - - /* - * bad if this assert fails, only part of the handshake message - * got sent. but why would this happen? - */ - OPENSSL_assert(len == (unsigned int)ret); - - if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { - /* - * should not be done for 'Hello Request's, but in that case - * we'll ignore the result anyway - */ - unsigned char *p = - (unsigned char *)&s->init_buf->data[s->init_off]; - const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - int xlen; - - if (frag_off == 0 && s->version != DTLS1_BAD_VER) { - /* - * reconstruct message header is if it is being sent in - * single fragment - */ - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); - s2n(msg_hdr->seq, p); - l2n3(0, p); - l2n3(msg_hdr->msg_len, p); - p -= DTLS1_HM_HEADER_LENGTH; - xlen = ret; - } else { - p += DTLS1_HM_HEADER_LENGTH; - xlen = ret - DTLS1_HM_HEADER_LENGTH; - } - - ssl3_finish_mac(s, p, xlen); - } - - if (ret == s->init_num) { - if (s->msg_callback) - s->msg_callback(1, s->version, type, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, - s->msg_callback_arg); - - s->init_off = 0; /* done writing this message */ - s->init_num = 0; - - return (1); - } - s->init_off += ret; - s->init_num -= ret; - ret -= DTLS1_HM_HEADER_LENGTH; - frag_off += ret; - - /* - * We save the fragment offset for the next fragment so we have it - * available in case of an IO retry. We don't know the length of the - * next fragment yet so just set that to 0 for now. It will be - * updated again later. - */ - dtls1_fix_message_header(s, frag_off, 0); - } - } - return (0); -} - -/* - * Obtain handshake message of message type 'mt' (any if mt == -1), maximum - * acceptable body length 'max'. Read an entire handshake message. Handshake - * messages arrive in fragments. - */ -long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) -{ - int i, al; - struct hm_header_st *msg_hdr; - unsigned char *p; - unsigned long msg_len; - - /* - * s3->tmp is used to store messages that are unexpected, caused by the - * absence of an optional handshake message - */ - if (s->s3->tmp.reuse_message) { - s->s3->tmp.reuse_message = 0; - if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - *ok = 1; - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - s->init_num = (int)s->s3->tmp.message_size; - return s->init_num; - } - - msg_hdr = &s->d1->r_msg_hdr; - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - - again: - i = dtls1_get_message_fragment(s, st1, stn, max, ok); - if (i == DTLS1_HM_BAD_FRAGMENT || i == DTLS1_HM_FRAGMENT_RETRY) { - /* bad fragment received */ - goto again; - } else if (i <= 0 && !*ok) { - return i; - } - - /* - * Don't change the *message* read sequence number while listening. For - * the *record* write sequence we reflect the ClientHello sequence number - * when listening. - */ - if (s->d1->listen) - memcpy(s->s3->write_sequence, s->s3->read_sequence, - sizeof(s->s3->write_sequence)); - else - s->d1->handshake_read_seq++; - - if (mt >= 0 && s->s3->tmp.message_type != mt) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - p = (unsigned char *)s->init_buf->data; - msg_len = msg_hdr->msg_len; - - /* reconstruct message header */ - *(p++) = msg_hdr->type; - l2n3(msg_len, p); - s2n(msg_hdr->seq, p); - l2n3(0, p); - l2n3(msg_len, p); - if (s->version != DTLS1_BAD_VER) { - p -= DTLS1_HM_HEADER_LENGTH; - msg_len += DTLS1_HM_HEADER_LENGTH; - } - - ssl3_finish_mac(s, p, msg_len); - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, msg_len, s, s->msg_callback_arg); - - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - return s->init_num; - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - *ok = 0; - return -1; -} - -static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, - int max) -{ - size_t frag_off, frag_len, msg_len; - - msg_len = msg_hdr->msg_len; - frag_off = msg_hdr->frag_off; - frag_len = msg_hdr->frag_len; - - /* sanity checking */ - if ((frag_off + frag_len) > msg_len) { - SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); - return SSL_AD_ILLEGAL_PARAMETER; - } - - if ((frag_off + frag_len) > (unsigned long)max) { - SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); - return SSL_AD_ILLEGAL_PARAMETER; - } - - if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */ - /* - * msg_len is limited to 2^24, but is effectively checked against max - * above - * - * Make buffer slightly larger than message length as a precaution - * against small OOB reads e.g. CVE-2016-6306 - */ - if (!BUF_MEM_grow_clean - (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH + 16)) { - SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB); - return SSL_AD_INTERNAL_ERROR; - } - - s->s3->tmp.message_size = msg_len; - s->d1->r_msg_hdr.msg_len = msg_len; - s->s3->tmp.message_type = msg_hdr->type; - s->d1->r_msg_hdr.type = msg_hdr->type; - s->d1->r_msg_hdr.seq = msg_hdr->seq; - } else if (msg_len != s->d1->r_msg_hdr.msg_len) { - /* - * They must be playing with us! BTW, failure to enforce upper limit - * would open possibility for buffer overrun. - */ - SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); - return SSL_AD_ILLEGAL_PARAMETER; - } - - return 0; /* no error */ -} - -static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) -{ - /*- - * (0) check whether the desired fragment is available - * if so: - * (1) copy over the fragment to s->init_buf->data[] - * (2) update s->init_num - */ - pitem *item; - hm_fragment *frag; - int al; - - *ok = 0; - do { - item = pqueue_peek(s->d1->buffered_messages); - if (item == NULL) - return 0; - - frag = (hm_fragment *)item->data; - - if (frag->msg_header.seq < s->d1->handshake_read_seq) { - /* This is a stale message that has been buffered so clear it */ - pqueue_pop(s->d1->buffered_messages); - dtls1_hm_fragment_free(frag); - pitem_free(item); - item = NULL; - frag = NULL; - } - } while (item == NULL); - - - /* Don't return if reassembly still in progress */ - if (frag->reassembly != NULL) - return 0; - - if (s->d1->handshake_read_seq == frag->msg_header.seq) { - unsigned long frag_len = frag->msg_header.frag_len; - pqueue_pop(s->d1->buffered_messages); - - al = dtls1_preprocess_fragment(s, &frag->msg_header, max); - - /* al will be 0 if no alert */ - if (al == 0 && frag->msg_header.frag_len > 0) { - unsigned char *p = - (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - memcpy(&p[frag->msg_header.frag_off], frag->fragment, - frag->msg_header.frag_len); - } - - dtls1_hm_fragment_free(frag); - pitem_free(item); - - if (al == 0) { - *ok = 1; - return frag_len; - } - - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->init_num = 0; - *ok = 0; - return -1; - } else - return 0; -} - -/* - * dtls1_max_handshake_message_len returns the maximum number of bytes - * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but - * may be greater if the maximum certificate list size requires it. - */ -static unsigned long dtls1_max_handshake_message_len(const SSL *s) -{ - unsigned long max_len = - DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; - if (max_len < (unsigned long)s->max_cert_list) - return s->max_cert_list; - return max_len; -} - -static int -dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok) -{ - hm_fragment *frag = NULL; - pitem *item = NULL; - int i = -1, is_complete; - unsigned char seq64be[8]; - unsigned long frag_len = msg_hdr->frag_len; - - if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || - msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) - goto err; - - if (frag_len == 0) - return DTLS1_HM_FRAGMENT_RETRY; - - /* Try to find item in queue */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); - seq64be[7] = (unsigned char)msg_hdr->seq; - item = pqueue_find(s->d1->buffered_messages, seq64be); - - if (item == NULL) { - frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); - if (frag == NULL) - goto err; - memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); - frag->msg_header.frag_len = frag->msg_header.msg_len; - frag->msg_header.frag_off = 0; - } else { - frag = (hm_fragment *)item->data; - if (frag->msg_header.msg_len != msg_hdr->msg_len) { - item = NULL; - frag = NULL; - goto err; - } - } - - /* - * If message is already reassembled, this must be a retransmit and can - * be dropped. In this case item != NULL and so frag does not need to be - * freed. - */ - if (frag->reassembly == NULL) { - unsigned char devnull[256]; - - while (frag_len) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - devnull, - frag_len > - sizeof(devnull) ? sizeof(devnull) : - frag_len, 0); - if (i <= 0) - goto err; - frag_len -= i; - } - return DTLS1_HM_FRAGMENT_RETRY; - } - - /* read the body of the fragment (header has already been read */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - frag->fragment + msg_hdr->frag_off, - frag_len, 0); - if ((unsigned long)i != frag_len) - i = -1; - if (i <= 0) - goto err; - - RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, - (long)(msg_hdr->frag_off + frag_len)); - - RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, - is_complete); - - if (is_complete) { - OPENSSL_free(frag->reassembly); - frag->reassembly = NULL; - } - - if (item == NULL) { - item = pitem_new(seq64be, frag); - if (item == NULL) { - i = -1; - goto err; - } - - item = pqueue_insert(s->d1->buffered_messages, item); - /* - * pqueue_insert fails iff a duplicate item is inserted. However, - * |item| cannot be a duplicate. If it were, |pqueue_find|, above, - * would have returned it and control would never have reached this - * branch. - */ - OPENSSL_assert(item != NULL); - } - - return DTLS1_HM_FRAGMENT_RETRY; - - err: - if (frag != NULL && item == NULL) - dtls1_hm_fragment_free(frag); - *ok = 0; - return i; -} - -static int -dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr, - int *ok) -{ - int i = -1; - hm_fragment *frag = NULL; - pitem *item = NULL; - unsigned char seq64be[8]; - unsigned long frag_len = msg_hdr->frag_len; - - if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) - goto err; - - /* Try to find item in queue, to prevent duplicate entries */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); - seq64be[7] = (unsigned char)msg_hdr->seq; - item = pqueue_find(s->d1->buffered_messages, seq64be); - - /* - * If we already have an entry and this one is a fragment, don't discard - * it and rather try to reassemble it. - */ - if (item != NULL && frag_len != msg_hdr->msg_len) - item = NULL; - - /* - * Discard the message if sequence number was already there, is too far - * in the future, already in the queue or if we received a FINISHED - * before the SERVER_HELLO, which then must be a stale retransmit. - */ - if (msg_hdr->seq <= s->d1->handshake_read_seq || - msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || - (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) - { - unsigned char devnull[256]; - - while (frag_len) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - devnull, - frag_len > - sizeof(devnull) ? sizeof(devnull) : - frag_len, 0); - if (i <= 0) - goto err; - frag_len -= i; - } - } else { - if (frag_len != msg_hdr->msg_len) - return dtls1_reassemble_fragment(s, msg_hdr, ok); - - if (frag_len > dtls1_max_handshake_message_len(s)) - goto err; - - frag = dtls1_hm_fragment_new(frag_len, 0); - if (frag == NULL) - goto err; - - memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); - - if (frag_len) { - /* - * read the body of the fragment (header has already been read - */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - frag->fragment, frag_len, 0); - if ((unsigned long)i != frag_len) - i = -1; - if (i <= 0) - goto err; - } - - item = pitem_new(seq64be, frag); - if (item == NULL) - goto err; - - item = pqueue_insert(s->d1->buffered_messages, item); - /* - * pqueue_insert fails iff a duplicate item is inserted. However, - * |item| cannot be a duplicate. If it were, |pqueue_find|, above, - * would have returned it. Then, either |frag_len| != - * |msg_hdr->msg_len| in which case |item| is set to NULL and it will - * have been processed with |dtls1_reassemble_fragment|, above, or - * the record will have been discarded. - */ - OPENSSL_assert(item != NULL); - } - - return DTLS1_HM_FRAGMENT_RETRY; - - err: - if (frag != NULL && item == NULL) - dtls1_hm_fragment_free(frag); - *ok = 0; - return i; -} - -static long -dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) -{ - unsigned char wire[DTLS1_HM_HEADER_LENGTH]; - unsigned long len, frag_off, frag_len; - int i, al; - struct hm_header_st msg_hdr; - - redo: - /* see if we have the required fragment already */ - if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) { - if (*ok) - s->init_num = frag_len; - return frag_len; - } - - /* read handshake message header */ - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire, - DTLS1_HM_HEADER_LENGTH, 0); - if (i <= 0) { /* nbio, or an error */ - s->rwstate = SSL_READING; - *ok = 0; - return i; - } - /* Handshake fails if message header is incomplete */ - if (i != DTLS1_HM_HEADER_LENGTH) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - /* parse the message fragment header */ - dtls1_get_message_header(wire, &msg_hdr); - - len = msg_hdr.msg_len; - frag_off = msg_hdr.frag_off; - frag_len = msg_hdr.frag_len; - - /* - * We must have at least frag_len bytes left in the record to be read. - * Fragments must not span records. - */ - if (frag_len > s->s3->rrec.length) { - al = SSL3_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_BAD_LENGTH); - goto f_err; - } - - /* - * if this is a future (or stale) message it gets buffered - * (or dropped)--no further processing at this time - * While listening, we accept seq 1 (ClientHello with cookie) - * although we're still expecting seq 0 (ClientHello) - */ - if (msg_hdr.seq != s->d1->handshake_read_seq - && !(s->d1->listen && msg_hdr.seq == 1)) - return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); - - if (frag_len && frag_len < len) - return dtls1_reassemble_fragment(s, &msg_hdr, ok); - - if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && - wire[0] == SSL3_MT_HELLO_REQUEST) { - /* - * The server may always send 'Hello Request' messages -- we are - * doing a handshake anyway now, so ignore them if their format is - * correct. Does not count for 'Finished' MAC. - */ - if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - wire, DTLS1_HM_HEADER_LENGTH, s, - s->msg_callback_arg); - - s->init_num = 0; - goto redo; - } else { /* Incorrectly formated Hello request */ - - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, - SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - } - - if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max))) - goto f_err; - - if (frag_len > 0) { - unsigned char *p = - (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; - - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - &p[frag_off], frag_len, 0); - - /* - * This shouldn't ever fail due to NBIO because we already checked - * that we have enough data in the record - */ - if (i <= 0) { - s->rwstate = SSL_READING; - *ok = 0; - return i; - } - } else - i = 0; - - /* - * XDTLS: an incorrectly formatted fragment should cause the handshake - * to fail - */ - if (i != (int)frag_len) { - al = SSL3_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL3_AD_ILLEGAL_PARAMETER); - goto f_err; - } - - *ok = 1; - s->state = stn; - - /* - * Note that s->init_num is *not* used as current offset in - * s->init_buf->data, but as a counter summing up fragments' lengths: as - * soon as they sum up to handshake packet length, we assume we have got - * all the fragments. - */ - s->init_num = frag_len; - return frag_len; - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->init_num = 0; - - *ok = 0; - return (-1); -} - -/*- - * for these 2 messages, we need to - * ssl->enc_read_ctx re-init - * ssl->s3->read_sequence zero - * ssl->s3->read_mac_secret re-init - * ssl->session->read_sym_enc assign - * ssl->session->read_compression assign - * ssl->session->read_hash assign - */ -int dtls1_send_change_cipher_spec(SSL *s, int a, int b) -{ - unsigned char *p; - - if (s->state == a) { - p = (unsigned char *)s->init_buf->data; - *p++ = SSL3_MT_CCS; - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - s->init_num = DTLS1_CCS_HEADER_LENGTH; - - if (s->version == DTLS1_BAD_VER) { - s->d1->next_handshake_write_seq++; - s2n(s->d1->handshake_write_seq, p); - s->init_num += 2; - } - - s->init_off = 0; - - dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, - s->d1->handshake_write_seq, 0, 0); - - /* buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 1); - - s->state = b; - } - - /* SSL3_ST_CW_CHANGE_B */ - return (dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); -} - -int dtls1_read_failed(SSL *s, int code) -{ - if (code > 0) { -#ifdef TLS_DEBUG - fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__); -#endif - return 1; - } - - if (!dtls1_is_timer_expired(s)) { - /* - * not a timeout, none of our business, let higher layers handle - * this. in fact it's probably an error - */ - return code; - } -#ifndef OPENSSL_NO_HEARTBEATS - /* done, no need to send a retransmit */ - if (!SSL_in_init(s) && !s->tlsext_hb_pending) -#else - /* done, no need to send a retransmit */ - if (!SSL_in_init(s)) -#endif - { - BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); - return code; - } -#if 0 /* for now, each alert contains only one - * record number */ - item = pqueue_peek(state->rcvd_records); - if (item) { - /* send an alert immediately for all the missing records */ - } else -#endif - -#if 0 /* no more alert sending, just retransmit the - * last set of messages */ - if (state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT) - ssl3_send_alert(s, SSL3_AL_WARNING, - DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); -#endif - - return dtls1_handle_timeout(s); -} - -int dtls1_get_queue_priority(unsigned short seq, int is_ccs) -{ - /* - * The index of the retransmission queue actually is the message sequence - * number, since the queue only contains messages of a single handshake. - * However, the ChangeCipherSpec has no message sequence number and so - * using only the sequence will result in the CCS and Finished having the - * same index. To prevent this, the sequence number is multiplied by 2. - * In case of a CCS 1 is subtracted. This does not only differ CSS and - * Finished, it also maintains the order of the index (important for - * priority queues) and fits in the unsigned short variable. - */ - return seq * 2 - is_ccs; -} - -int dtls1_retransmit_buffered_messages(SSL *s) -{ - pqueue sent = s->d1->sent_messages; - piterator iter; - pitem *item; - hm_fragment *frag; - int found = 0; - - iter = pqueue_iterator(sent); - - for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { - frag = (hm_fragment *)item->data; - if (dtls1_retransmit_message(s, (unsigned short) - dtls1_get_queue_priority - (frag->msg_header.seq, - frag->msg_header.is_ccs), 0, - &found) <= 0 && found) { -#ifdef TLS_DEBUG - fprintf(stderr, "dtls1_retransmit_message() failed\n"); -#endif - return -1; - } - } - - return 1; -} - -int dtls1_buffer_message(SSL *s, int is_ccs) -{ - pitem *item; - hm_fragment *frag; - unsigned char seq64be[8]; - - /* - * this function is called immediately after a message has been - * serialized - */ - OPENSSL_assert(s->init_off == 0); - - frag = dtls1_hm_fragment_new(s->init_num, 0); - if (!frag) - return 0; - - memcpy(frag->fragment, s->init_buf->data, s->init_num); - - if (is_ccs) { - /* For DTLS1_BAD_VER the header length is non-standard */ - OPENSSL_assert(s->d1->w_msg_hdr.msg_len + - ((s->version==DTLS1_BAD_VER)?3:DTLS1_CCS_HEADER_LENGTH) - == (unsigned int)s->init_num); - } else { - OPENSSL_assert(s->d1->w_msg_hdr.msg_len + - DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); - } - - frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.seq = s->d1->w_msg_hdr.seq; - frag->msg_header.type = s->d1->w_msg_hdr.type; - frag->msg_header.frag_off = 0; - frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.is_ccs = is_ccs; - - /* save current state */ - frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx; - frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; - frag->msg_header.saved_retransmit_state.compress = s->compress; - frag->msg_header.saved_retransmit_state.session = s->session; - frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch; - - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = - (unsigned - char)(dtls1_get_queue_priority(frag->msg_header.seq, - frag->msg_header.is_ccs) >> 8); - seq64be[7] = - (unsigned - char)(dtls1_get_queue_priority(frag->msg_header.seq, - frag->msg_header.is_ccs)); - - item = pitem_new(seq64be, frag); - if (item == NULL) { - dtls1_hm_fragment_free(frag); - return 0; - } -#if 0 - fprintf(stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); - fprintf(stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); - fprintf(stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); -#endif - - pqueue_insert(s->d1->sent_messages, item); - return 1; -} - -int -dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, - int *found) -{ - int ret; - /* XDTLS: for now assuming that read/writes are blocking */ - pitem *item; - hm_fragment *frag; - unsigned long header_length; - unsigned char seq64be[8]; - struct dtls1_retransmit_state saved_state; - unsigned char save_write_sequence[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - /*- - OPENSSL_assert(s->init_num == 0); - OPENSSL_assert(s->init_off == 0); - */ - - /* XDTLS: the requested message ought to be found, otherwise error */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(seq >> 8); - seq64be[7] = (unsigned char)seq; - - item = pqueue_find(s->d1->sent_messages, seq64be); - if (item == NULL) { -#ifdef TLS_DEBUG - fprintf(stderr, "retransmit: message %d non-existant\n", seq); -#endif - *found = 0; - return 0; - } - - *found = 1; - frag = (hm_fragment *)item->data; - - if (frag->msg_header.is_ccs) - header_length = DTLS1_CCS_HEADER_LENGTH; - else - header_length = DTLS1_HM_HEADER_LENGTH; - - memcpy(s->init_buf->data, frag->fragment, - frag->msg_header.msg_len + header_length); - s->init_num = frag->msg_header.msg_len + header_length; - - dtls1_set_message_header_int(s, frag->msg_header.type, - frag->msg_header.msg_len, - frag->msg_header.seq, 0, - frag->msg_header.frag_len); - - /* save current state */ - saved_state.enc_write_ctx = s->enc_write_ctx; - saved_state.write_hash = s->write_hash; - saved_state.compress = s->compress; - saved_state.session = s->session; - saved_state.epoch = s->d1->w_epoch; - saved_state.epoch = s->d1->w_epoch; - - s->d1->retransmitting = 1; - - /* restore state in which the message was originally sent */ - s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx; - s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; - s->compress = frag->msg_header.saved_retransmit_state.compress; - s->session = frag->msg_header.saved_retransmit_state.session; - s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch; - - if (frag->msg_header.saved_retransmit_state.epoch == - saved_state.epoch - 1) { - memcpy(save_write_sequence, s->s3->write_sequence, - sizeof(s->s3->write_sequence)); - memcpy(s->s3->write_sequence, s->d1->last_write_sequence, - sizeof(s->s3->write_sequence)); - } - - ret = dtls1_do_write(s, frag->msg_header.is_ccs ? - SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); - - /* restore current state */ - s->enc_write_ctx = saved_state.enc_write_ctx; - s->write_hash = saved_state.write_hash; - s->compress = saved_state.compress; - s->session = saved_state.session; - s->d1->w_epoch = saved_state.epoch; - - if (frag->msg_header.saved_retransmit_state.epoch == - saved_state.epoch - 1) { - memcpy(s->d1->last_write_sequence, s->s3->write_sequence, - sizeof(s->s3->write_sequence)); - memcpy(s->s3->write_sequence, save_write_sequence, - sizeof(s->s3->write_sequence)); - } - - s->d1->retransmitting = 0; - - (void)BIO_flush(SSL_get_wbio(s)); - return ret; -} - -unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, - unsigned char mt, unsigned long len, - unsigned long frag_off, - unsigned long frag_len) -{ - /* Don't change sequence numbers while listening */ - if (frag_off == 0 && !s->d1->listen) { - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - s->d1->next_handshake_write_seq++; - } - - dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, - frag_off, frag_len); - - return p += DTLS1_HM_HEADER_LENGTH; -} - -/* don't actually do the writing, wait till the MTU has been retrieved */ -static void -dtls1_set_message_header_int(SSL *s, unsigned char mt, - unsigned long len, unsigned short seq_num, - unsigned long frag_off, unsigned long frag_len) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - msg_hdr->type = mt; - msg_hdr->msg_len = len; - msg_hdr->seq = seq_num; - msg_hdr->frag_off = frag_off; - msg_hdr->frag_len = frag_len; -} - -static void -dtls1_fix_message_header(SSL *s, unsigned long frag_off, - unsigned long frag_len) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - msg_hdr->frag_off = frag_off; - msg_hdr->frag_len = frag_len; -} - -static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); - - s2n(msg_hdr->seq, p); - l2n3(msg_hdr->frag_off, p); - l2n3(msg_hdr->frag_len, p); - - return p; -} - -unsigned int dtls1_link_min_mtu(void) -{ - return (g_probable_mtu[(sizeof(g_probable_mtu) / - sizeof(g_probable_mtu[0])) - 1]); -} - -unsigned int dtls1_min_mtu(SSL *s) -{ - return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); -} - -void -dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) -{ - memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - msg_hdr->type = *(data++); - n2l3(data, msg_hdr->msg_len); - - n2s(data, msg_hdr->seq); - n2l3(data, msg_hdr->frag_off); - n2l3(data, msg_hdr->frag_len); -} - -void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) -{ - memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); - - ccs_hdr->type = *(data++); -} - -int dtls1_shutdown(SSL *s) -{ - int ret; -#ifndef OPENSSL_NO_SCTP - BIO *wbio; - - wbio = SSL_get_wbio(s); - if (wbio != NULL && BIO_dgram_is_sctp(wbio) && - !(s->shutdown & SSL_SENT_SHUTDOWN)) { - ret = BIO_dgram_sctp_wait_for_dry(wbio); - if (ret < 0) - return -1; - - if (ret == 0) - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, - NULL); - } -#endif - ret = ssl3_shutdown(s); -#ifndef OPENSSL_NO_SCTP - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL); -#endif - return ret; -} - -#ifndef OPENSSL_NO_HEARTBEATS -int dtls1_process_heartbeat(SSL *s) -{ - unsigned char *p = &s->s3->rrec.data[0], *pl; - unsigned short hbtype; - unsigned int payload; - unsigned int padding = 16; /* Use minimum padding */ - - if (s->msg_callback) - s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, - &s->s3->rrec.data[0], s->s3->rrec.length, - s, s->msg_callback_arg); - - /* Read type and payload length first */ - if (1 + 2 + 16 > s->s3->rrec.length) - return 0; /* silently discard */ - if (s->s3->rrec.length > SSL3_RT_MAX_PLAIN_LENGTH) - return 0; /* silently discard per RFC 6520 sec. 4 */ - - hbtype = *p++; - n2s(p, payload); - if (1 + 2 + payload + 16 > s->s3->rrec.length) - return 0; /* silently discard per RFC 6520 sec. 4 */ - pl = p; - - if (hbtype == TLS1_HB_REQUEST) { - unsigned char *buffer, *bp; - unsigned int write_length = 1 /* heartbeat type */ + - 2 /* heartbeat length */ + - payload + padding; - int r; - - if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) - return 0; - - /* - * Allocate memory for the response, size is 1 byte message type, - * plus 2 bytes payload length, plus payload, plus padding - */ - buffer = OPENSSL_malloc(write_length); - if (buffer == NULL) - return -1; - bp = buffer; - - /* Enter response type, length and copy payload */ - *bp++ = TLS1_HB_RESPONSE; - s2n(payload, bp); - memcpy(bp, pl, payload); - bp += payload; - /* Random padding */ - if (RAND_bytes(bp, padding) <= 0) { - OPENSSL_free(buffer); - return -1; - } - - r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); - - if (r >= 0 && s->msg_callback) - s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buffer, write_length, s, s->msg_callback_arg); - - OPENSSL_free(buffer); - - if (r < 0) - return r; - } else if (hbtype == TLS1_HB_RESPONSE) { - unsigned int seq; - - /* - * We only send sequence numbers (2 bytes unsigned int), and 16 - * random bytes, so we just try to read the sequence number - */ - n2s(pl, seq); - - if (payload == 18 && seq == s->tlsext_hb_seq) { - dtls1_stop_timer(s); - s->tlsext_hb_seq++; - s->tlsext_hb_pending = 0; - } - } - - return 0; -} - -int dtls1_heartbeat(SSL *s) -{ - unsigned char *buf, *p; - int ret = -1; - unsigned int payload = 18; /* Sequence number + random bytes */ - unsigned int padding = 16; /* Use minimum padding */ - - /* Only send if peer supports and accepts HB requests... */ - if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || - s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { - SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); - return -1; - } - - /* ...and there is none in flight yet... */ - if (s->tlsext_hb_pending) { - SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); - return -1; - } - - /* ...and no handshake in progress. */ - if (SSL_in_init(s) || s->in_handshake) { - SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); - return -1; - } - - /* - * Check if padding is too long, payload and padding must not exceed 2^14 - * - 3 = 16381 bytes in total. - */ - OPENSSL_assert(payload + padding <= 16381); - - /*- - * Create HeartBeat message, we just use a sequence number - * as payload to distuingish different messages and add - * some random stuff. - * - Message Type, 1 byte - * - Payload Length, 2 bytes (unsigned int) - * - Payload, the sequence number (2 bytes uint) - * - Payload, random bytes (16 bytes uint) - * - Padding - */ - buf = OPENSSL_malloc(1 + 2 + payload + padding); - if (buf == NULL) - goto err; - p = buf; - /* Message Type */ - *p++ = TLS1_HB_REQUEST; - /* Payload length (18 bytes here) */ - s2n(payload, p); - /* Sequence number */ - s2n(s->tlsext_hb_seq, p); - /* 16 random bytes */ - if (RAND_bytes(p, 16) <= 0) - goto err; - p += 16; - /* Random padding */ - if (RAND_bytes(p, padding) <= 0) - goto err; - - ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); - if (ret >= 0) { - if (s->msg_callback) - s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buf, 3 + payload + padding, - s, s->msg_callback_arg); - - dtls1_start_timer(s); - s->tlsext_hb_pending = 1; - } - -err: - OPENSSL_free(buf); - - return ret; -} -#endif -/* ssl/d1_clnt.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "ssl_locl.h" -#ifndef OPENSSL_NO_KRB5 -# include "kssl_lcl.h" -#endif -// #include "buffer.h" -// #include "rand.h" -// #include "objects.h" -// #include "evp.h" -#include "md5.h" -#include "bn.h" -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -static const SSL_METHOD *dtls1_get_client_method(int ver); -static int dtls1_get_hello_verify(SSL *s); - -static const SSL_METHOD *dtls1_get_client_method(int ver) -{ - if (ver == DTLS_ANY_VERSION) - return DTLS_client_method(); - else if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER) - return DTLSv1_client_method(); - else if (ver == DTLS1_2_VERSION) - return DTLSv1_2_client_method(); - else - return NULL; -} - -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, - DTLSv1_client_method, - ssl_undefined_function, - dtls1_connect, - dtls1_get_client_method, DTLSv1_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, - DTLSv1_2_client_method, - ssl_undefined_function, - dtls1_connect, - dtls1_get_client_method, DTLSv1_2_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, - DTLS_client_method, - ssl_undefined_function, - dtls1_connect, - dtls1_get_client_method, DTLSv1_2_enc_data) - -int dtls1_connect(SSL *s) -{ - BUF_MEM *buf = NULL; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state, skip = 0; -#ifndef OPENSSL_NO_SCTP - unsigned char sctpauthkey[64]; - char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; -#endif - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - -#ifndef OPENSSL_NO_SCTP - /* - * Notify SCTP BIO socket to enter handshake mode and prevent stream - * identifier other than 0. Will be ignored if no SCTP is used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, - s->in_handshake, NULL); -#endif - -#ifndef OPENSSL_NO_HEARTBEATS - /* - * If we're awaiting a HeartbeatResponse, pretend we already got and - * don't await it anymore, because Heartbeats don't make sense during - * handshakes anyway. - */ - if (s->tlsext_hb_pending) { - dtls1_stop_timer(s); - s->tlsext_hb_pending = 0; - s->tlsext_hb_seq++; - } -#endif - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_RENEGOTIATE: - s->renegotiate = 1; - s->state = SSL_ST_CONNECT; - s->ctx->stats.sess_connect_renegotiate++; - /* break */ - case SSL_ST_BEFORE: - case SSL_ST_CONNECT: - case SSL_ST_BEFORE | SSL_ST_CONNECT: - case SSL_ST_OK | SSL_ST_CONNECT: - - s->server = 0; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) && - (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) { - SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* s->version=SSL3_VERSION; */ - s->type = SSL_ST_CONNECT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - s->init_buf = buf; - buf = NULL; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* setup buffing BIO */ - if (!ssl_init_wbio_buffer(s, 0)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* don't push the buffering BIO quite yet */ - - s->state = SSL3_ST_CW_CLNT_HELLO_A; - s->ctx->stats.sess_connect++; - s->init_num = 0; - /* mark client_random uninitialized */ - memset(s->s3->client_random, 0, sizeof(s->s3->client_random)); - s->d1->send_cookie = 0; - s->hit = 0; - s->d1->change_cipher_spec_ok = 0; - /* - * Should have been reset by ssl3_get_finished, too. - */ - s->s3->change_cipher_spec = 0; - break; - -#ifndef OPENSSL_NO_SCTP - case DTLS1_SCTP_ST_CR_READ_SOCK: - - if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ret = -1; - goto end; - } - - s->state = s->s3->tmp.next_state; - break; - - case DTLS1_SCTP_ST_CW_WRITE_SOCK: - /* read app data until dry event */ - - ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); - if (ret < 0) - goto end; - - if (ret == 0) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ret = -1; - goto end; - } - - s->state = s->d1->next_state; - break; -#endif - - case SSL3_ST_CW_CLNT_HELLO_A: - s->shutdown = 0; - - /* every DTLS ClientHello resets Finished MAC */ - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* fall thru */ - case SSL3_ST_CW_CLNT_HELLO_B: - dtls1_start_timer(s); - ret = ssl3_client_hello(s); - if (ret <= 0) - goto end; - - if (s->d1->send_cookie) { - s->state = SSL3_ST_CW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; - } else - s->state = SSL3_ST_CR_SRVR_HELLO_A; - - s->init_num = 0; - -#ifndef OPENSSL_NO_SCTP - /* Disable buffering for SCTP */ - if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) { -#endif - /* - * turn on buffering for the next lot of output - */ - if (s->bbio != s->wbio) - s->wbio = BIO_push(s->bbio, s->wbio); -#ifndef OPENSSL_NO_SCTP - } -#endif - - break; - - case SSL3_ST_CR_SRVR_HELLO_A: - case SSL3_ST_CR_SRVR_HELLO_B: - ret = ssl3_get_server_hello(s); - if (ret <= 0) - goto end; - else { - if (s->hit) { -#ifndef OPENSSL_NO_SCTP - /* - * Add new shared key for SCTP-Auth, will be ignored if - * no SCTP used. - */ - snprintf((char *)labelbuffer, - sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); - - if (SSL_export_keying_material(s, sctpauthkey, - sizeof(sctpauthkey), - labelbuffer, - sizeof(labelbuffer), NULL, 0, - 0) <= 0) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - BIO_ctrl(SSL_get_wbio(s), - BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, - sizeof(sctpauthkey), sctpauthkey); -#endif - - s->state = SSL3_ST_CR_FINISHED_A; - if (s->tlsext_ticket_expected) { - /* receive renewed session ticket */ - s->state = SSL3_ST_CR_SESSION_TICKET_A; - } - } else - s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; - } - s->init_num = 0; - break; - - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: - - ret = dtls1_get_hello_verify(s); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - if (s->d1->send_cookie) /* start again, with a cookie */ - s->state = SSL3_ST_CW_CLNT_HELLO_A; - else - s->state = SSL3_ST_CR_CERT_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_CERT_A: - case SSL3_ST_CR_CERT_B: - /* Check if it is anon DH or PSK */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - ret = ssl3_get_server_certificate(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_status_expected) - s->state = SSL3_ST_CR_CERT_STATUS_A; - else - s->state = SSL3_ST_CR_KEY_EXCH_A; - } else { - skip = 1; - s->state = SSL3_ST_CR_KEY_EXCH_A; - } -#else - } else - skip = 1; - - s->state = SSL3_ST_CR_KEY_EXCH_A; -#endif - s->init_num = 0; - break; - - case SSL3_ST_CR_KEY_EXCH_A: - case SSL3_ST_CR_KEY_EXCH_B: - ret = ssl3_get_key_exchange(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_CERT_REQ_A; - s->init_num = 0; - - /* - * at this point we check that we have the required stuff from - * the server - */ - if (!ssl3_check_cert_and_algorithm(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - - case SSL3_ST_CR_CERT_REQ_A: - case SSL3_ST_CR_CERT_REQ_B: - ret = ssl3_get_certificate_request(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_SRVR_DONE_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_SRVR_DONE_A: - case SSL3_ST_CR_SRVR_DONE_B: - ret = ssl3_get_server_done(s); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - if (s->s3->tmp.cert_req) - s->s3->tmp.next_state = SSL3_ST_CW_CERT_A; - else - s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; - -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - state == SSL_ST_RENEGOTIATE) - s->state = DTLS1_SCTP_ST_CR_READ_SOCK; - else -#endif - s->state = s->s3->tmp.next_state; - break; - - case SSL3_ST_CW_CERT_A: - case SSL3_ST_CW_CERT_B: - case SSL3_ST_CW_CERT_C: - case SSL3_ST_CW_CERT_D: - dtls1_start_timer(s); - ret = ssl3_send_client_certificate(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; - break; - - case SSL3_ST_CW_KEY_EXCH_A: - case SSL3_ST_CW_KEY_EXCH_B: - dtls1_start_timer(s); - ret = ssl3_send_client_key_exchange(s); - if (ret <= 0) - goto end; - -#ifndef OPENSSL_NO_SCTP - /* - * Add new shared key for SCTP-Auth, will be ignored if no SCTP - * used. - */ - snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); - - if (SSL_export_keying_material(s, sctpauthkey, - sizeof(sctpauthkey), labelbuffer, - sizeof(labelbuffer), NULL, 0, 0) <= 0) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, - sizeof(sctpauthkey), sctpauthkey); -#endif - - /* - * EAY EAY EAY need to check for DH fix cert sent back - */ - /* - * For TLS, cert_req is set to 2, so a cert chain of nothing is - * sent, but no verify packet is sent - */ - if (s->s3->tmp.cert_req == 1) { - s->state = SSL3_ST_CW_CERT_VRFY_A; - } else { -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL3_ST_CW_CHANGE_A; - s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } else -#endif - s->state = SSL3_ST_CW_CHANGE_A; - } - - s->init_num = 0; - break; - - case SSL3_ST_CW_CERT_VRFY_A: - case SSL3_ST_CW_CERT_VRFY_B: - dtls1_start_timer(s); - ret = ssl3_send_client_verify(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL3_ST_CW_CHANGE_A; - s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } else -#endif - s->state = SSL3_ST_CW_CHANGE_A; - s->init_num = 0; - break; - - case SSL3_ST_CW_CHANGE_A: - case SSL3_ST_CW_CHANGE_B: - if (!s->hit) - dtls1_start_timer(s); - ret = dtls1_send_change_cipher_spec(s, - SSL3_ST_CW_CHANGE_A, - SSL3_ST_CW_CHANGE_B); - if (ret <= 0) - goto end; - - s->state = SSL3_ST_CW_FINISHED_A; - s->init_num = 0; - - s->session->cipher = s->s3->tmp.new_cipher; -#ifdef OPENSSL_NO_COMP - s->session->compress_meth = 0; -#else - if (s->s3->tmp.new_compression == NULL) - s->session->compress_meth = 0; - else - s->session->compress_meth = s->s3->tmp.new_compression->id; -#endif - if (!s->method->ssl3_enc->setup_key_block(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_CLIENT_WRITE)) - { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } -#ifndef OPENSSL_NO_SCTP - if (s->hit) { - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); - } -#endif - - dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); - break; - - case SSL3_ST_CW_FINISHED_A: - case SSL3_ST_CW_FINISHED_B: - if (!s->hit) - dtls1_start_timer(s); - ret = ssl3_send_finished(s, - SSL3_ST_CW_FINISHED_A, - SSL3_ST_CW_FINISHED_B, - s->method-> - ssl3_enc->client_finished_label, - s->method-> - ssl3_enc->client_finished_label_len); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_FLUSH; - - /* clear flags */ - s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; - if (s->hit) { - s->s3->tmp.next_state = SSL_ST_OK; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = s->s3->tmp.next_state; - s->s3->tmp.next_state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } -#endif - if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { - s->state = SSL_ST_OK; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL_ST_OK; - s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } -#endif - s->s3->flags |= SSL3_FLAGS_POP_BUFFER; - s->s3->delay_buf_pop_ret = 0; - } - } else { -#ifndef OPENSSL_NO_SCTP - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); -#endif - -#ifndef OPENSSL_NO_TLSEXT - /* - * Allow NewSessionTicket if ticket expected - */ - if (s->tlsext_ticket_expected) - s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; - else -#endif - - s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; - } - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_CR_SESSION_TICKET_A: - case SSL3_ST_CR_SESSION_TICKET_B: - ret = ssl3_get_new_session_ticket(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_FINISHED_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_CERT_STATUS_A: - case SSL3_ST_CR_CERT_STATUS_B: - ret = ssl3_get_cert_status(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_KEY_EXCH_A; - s->init_num = 0; - break; -#endif - - case SSL3_ST_CR_FINISHED_A: - case SSL3_ST_CR_FINISHED_B: - s->d1->change_cipher_spec_ok = 1; - ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, - SSL3_ST_CR_FINISHED_B); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - - if (s->hit) - s->state = SSL3_ST_CW_CHANGE_A; - else - s->state = SSL_ST_OK; - -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - state == SSL_ST_RENEGOTIATE) { - s->d1->next_state = s->state; - s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; - } -#endif - - s->init_num = 0; - break; - - case SSL3_ST_CW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - /* - * If the write error was fatal, stop trying - */ - if (!BIO_should_retry(s->wbio)) { - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - } - - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - break; - - case SSL_ST_OK: - /* clean a few things up */ - ssl3_cleanup_key_block(s); - -#if 0 - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } -#endif - - /* - * If we are not 'joining' the last two packets, remove the - * buffering now - */ - if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) - ssl_free_wbio_buffer(s); - /* else do it later in ssl3_write */ - - s->init_num = 0; - s->renegotiate = 0; - s->new_session = 0; - - ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); - if (s->hit) - s->ctx->stats.sess_hit++; - - ret = 1; - /* s->server=0; */ - s->handshake_func = dtls1_connect; - s->ctx->stats.sess_connect_good++; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - - /* done with handshaking */ - s->d1->handshake_read_seq = 0; - s->d1->next_handshake_write_seq = 0; - dtls1_clear_received_buffer(s); - goto end; - /* break; */ - - case SSL_ST_ERR: - default: - SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - /* did we do anything */ - if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; - } - } - skip = 0; - } - end: - s->in_handshake--; - -#ifndef OPENSSL_NO_SCTP - /* - * Notify SCTP BIO socket to leave handshake mode and allow stream - * identifier other than 0. Will be ignored if no SCTP is used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, - s->in_handshake, NULL); -#endif - - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s, SSL_CB_CONNECT_EXIT, ret); - return (ret); -} - -static int dtls1_get_hello_verify(SSL *s) -{ - int n, al, ok = 0; - unsigned char *data; - unsigned int cookie_len; - - s->first_packet = 1; - n = s->method->ssl_get_message(s, - DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, - DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, - -1, s->max_cert_list, &ok); - s->first_packet = 0; - - if (!ok) - return ((int)n); - - if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { - s->d1->send_cookie = 0; - s->s3->tmp.reuse_message = 1; - return (1); - } - - data = (unsigned char *)s->init_msg; -#if 0 - if (s->method->version != DTLS_ANY_VERSION && - ((data[0] != (s->version >> 8)) || (data[1] != (s->version & 0xff)))) - { - SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY, SSL_R_WRONG_SSL_VERSION); - s->version = (s->version & 0xff00) | data[1]; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } -#endif - data += 2; - - cookie_len = *(data++); - if (cookie_len > sizeof(s->d1->cookie)) { - al = SSL_AD_ILLEGAL_PARAMETER; - goto f_err; - } - - memcpy(s->d1->cookie, data, cookie_len); - s->d1->cookie_len = cookie_len; - - s->d1->send_cookie = 1; - return 1; - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->state = SSL_ST_ERR; - return -1; -} -/* ssl/d1_meth.h */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "objects.h" -// #include "ssl_locl.h" - -static const SSL_METHOD *dtls1_get_method(int ver); -static const SSL_METHOD *dtls1_get_method(int ver) -{ - if (ver == DTLS_ANY_VERSION) - return DTLS_method(); - else if (ver == DTLS1_VERSION) - return DTLSv1_method(); - else if (ver == DTLS1_2_VERSION) - return DTLSv1_2_method(); - else - return NULL; -} - -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, - DTLSv1_method, - dtls1_accept, - dtls1_connect, dtls1_get_method, DTLSv1_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, - DTLSv1_2_method, - dtls1_accept, - dtls1_connect, dtls1_get_method, DTLSv1_2_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, - DTLS_method, - dtls1_accept, - dtls1_connect, dtls1_get_method, DTLSv1_2_enc_data) -/* ssl/d1_pkt.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#define USE_SOCKETS -// #include "ssl_locl.h" -// #include "evp.h" -// #include "buffer.h" -#include "pqueue.h" -// #include "rand.h" - -/* mod 128 saturating subtract of two 64-bit values in big-endian order */ -static int satsub64be(const unsigned char *v1, const unsigned char *v2) -{ - int ret, i; - - if (sizeof(long) == 8) - do { - const union { - long one; - char little; - } is_endian = { - 1 - }; - long l; - - if (is_endian.little) - break; - /* not reached on little-endians */ - /* - * following test is redundant, because input is always aligned, - * but I take no chances... - */ - if (((size_t)v1 | (size_t)v2) & 0x7) - break; - - l = *((long *)v1); - l -= *((long *)v2); - if (l > 128) - return 128; - else if (l < -128) - return -128; - else - return (int)l; - } while (0); - - ret = 0; - for (i=0; i<7; i++) { - if (v1[i] > v2[i]) { - /* v1 is larger... but by how much? */ - if (v1[i] != v2[i] + 1) - return 128; - while (++i <= 6) { - if (v1[i] != 0x00 || v2[i] != 0xff) - return 128; /* too much */ - } - /* We checked all the way to the penultimate byte, - * so despite higher bytes changing we actually - * know that it only changed from (e.g.) - * ... (xx) ff ff ff ?? - * to ... (xx+1) 00 00 00 ?? - * so we add a 'bias' of 256 for the carry that - * happened, and will eventually return - * 256 + v1[7] - v2[7]. */ - ret = 256; - break; - } else if (v2[i] > v1[i]) { - /* v2 is larger... but by how much? */ - if (v2[i] != v1[i] + 1) - return -128; - while (++i <= 6) { - if (v2[i] != 0x00 || v1[i] != 0xff) - return -128; /* too much */ - } - /* Similar to the case above, we know it changed - * from ... (xx) 00 00 00 ?? - * to ... (xx-1) ff ff ff ?? - * so we add a 'bias' of -256 for the borrow, - * to return -256 + v1[7] - v2[7]. */ - ret = -256; - } - } - - ret += (int)v1[7] - (int)v2[7]; - - if (ret > 128) - return 128; - else if (ret < -128) - return -128; - else - return ret; -} - -static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, - int len, int peek); -static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); -static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); -static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, - unsigned int *is_next_epoch); -#if 0 -static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, - unsigned short *priority, - unsigned long *offset); -#endif -static int dtls1_buffer_record(SSL *s, record_pqueue *q, - unsigned char *priority); -static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); - -/* copy buffered record into SSL structure */ -static int dtls1_copy_record(SSL *s, pitem *item) -{ - DTLS1_RECORD_DATA *rdata; - - rdata = (DTLS1_RECORD_DATA *)item->data; - - if (s->s3->rbuf.buf != NULL) - OPENSSL_free(s->s3->rbuf.buf); - - s->packet = rdata->packet; - s->packet_length = rdata->packet_length; - memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); - - /* Set proper sequence number for mac calculation */ - memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); - - return (1); -} - -static int -dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) -{ - DTLS1_RECORD_DATA *rdata; - pitem *item; - - /* Limit the size of the queue to prevent DOS attacks */ - if (pqueue_size(queue->q) >= 100) - return 0; - - rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); - item = pitem_new(priority, rdata); - if (rdata == NULL || item == NULL) { - if (rdata != NULL) - OPENSSL_free(rdata); - if (item != NULL) - pitem_free(item); - - SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); - return -1; - } - - rdata->packet = s->packet; - rdata->packet_length = s->packet_length; - memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD)); - - item->data = rdata; - -#ifndef OPENSSL_NO_SCTP - /* Store bio_dgram_sctp_rcvinfo struct */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - (s->state == SSL3_ST_SR_FINISHED_A - || s->state == SSL3_ST_CR_FINISHED_A)) { - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, - sizeof(rdata->recordinfo), &rdata->recordinfo); - } -#endif - - s->packet = NULL; - s->packet_length = 0; - memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); - memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD)); - - if (!ssl3_setup_buffers(s)) { - SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); - if (rdata->rbuf.buf != NULL) - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(rdata); - pitem_free(item); - return (-1); - } - - if (pqueue_insert(queue->q, item) == NULL) { - /* Must be a duplicate so ignore it */ - if (rdata->rbuf.buf != NULL) - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(rdata); - pitem_free(item); - } - - return (1); -} - -static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) -{ - pitem *item; - - item = pqueue_pop(queue->q); - if (item) { - dtls1_copy_record(s, item); - - OPENSSL_free(item->data); - pitem_free(item); - - return (1); - } - - return (0); -} - -/* - * retrieve a buffered record that belongs to the new epoch, i.e., not - * processed yet - */ -#define dtls1_get_unprocessed_record(s) \ - dtls1_retrieve_buffered_record((s), \ - &((s)->d1->unprocessed_rcds)) - -/* - * retrieve a buffered record that belongs to the current epoch, ie, - * processed - */ -#define dtls1_get_processed_record(s) \ - dtls1_retrieve_buffered_record((s), \ - &((s)->d1->processed_rcds)) - -static int dtls1_process_buffered_records(SSL *s) -{ - pitem *item; - SSL3_BUFFER *rb; - SSL3_RECORD *rr; - DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; - int replayok = 1; - - item = pqueue_peek(s->d1->unprocessed_rcds.q); - if (item) { - /* Check if epoch is current. */ - if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) - return 1; /* Nothing to do. */ - - rr = &s->s3->rrec; - rb = &s->s3->rbuf; - - if (rb->left > 0) { - /* - * We've still got data from the current packet to read. There could - * be a record from the new epoch in it - so don't overwrite it - * with the unprocessed records yet (we'll do it when we've - * finished reading the current packet). - */ - return 1; - } - - - /* Process all the records. */ - while (pqueue_peek(s->d1->unprocessed_rcds.q)) { - dtls1_get_unprocessed_record(s); - bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); - if (bitmap == NULL) { - /* - * Should not happen. This will only ever be NULL when the - * current record is from a different epoch. But that cannot - * be the case because we already checked the epoch above - */ - SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, - ERR_R_INTERNAL_ERROR); - return 0; - } -#ifndef OPENSSL_NO_SCTP - /* Only do replay check if no SCTP bio */ - if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) -#endif - { - /* - * Check whether this is a repeat, or aged record. We did this - * check once already when we first received the record - but - * we might have updated the window since then due to - * records we subsequently processed. - */ - replayok = dtls1_record_replay_check(s, bitmap); - } - - if (!replayok || !dtls1_process_record(s, bitmap)) { - /* dump this record */ - rr->length = 0; - s->packet_length = 0; - continue; - } - - if (dtls1_buffer_record(s, &(s->d1->processed_rcds), - s->s3->rrec.seq_num) < 0) - return 0; - } - } - - /* - * sync epoch numbers once all the unprocessed records have been - * processed - */ - s->d1->processed_rcds.epoch = s->d1->r_epoch; - s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; - - return 1; -} - -#if 0 - -static int dtls1_get_buffered_record(SSL *s) -{ - pitem *item; - PQ_64BIT priority = - (((PQ_64BIT) s->d1->handshake_read_seq) << 32) | - ((PQ_64BIT) s->d1->r_msg_hdr.frag_off); - - /* if we're not (re)negotiating, nothing buffered */ - if (!SSL_in_init(s)) - return 0; - - item = pqueue_peek(s->d1->rcvd_records); - if (item && item->priority == priority) { - /* - * Check if we've received the record of interest. It must be a - * handshake record, since data records as passed up without - * buffering - */ - DTLS1_RECORD_DATA *rdata; - item = pqueue_pop(s->d1->rcvd_records); - rdata = (DTLS1_RECORD_DATA *)item->data; - - if (s->s3->rbuf.buf != NULL) - OPENSSL_free(s->s3->rbuf.buf); - - s->packet = rdata->packet; - s->packet_length = rdata->packet_length; - memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); - memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); - - OPENSSL_free(item->data); - pitem_free(item); - - /* s->d1->next_expected_seq_num++; */ - return (1); - } - - return 0; -} - -#endif - -static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) -{ - int i, al; - int enc_err; - SSL_SESSION *sess; - SSL3_RECORD *rr; - unsigned int mac_size, orig_len; - unsigned char md[EVP_MAX_MD_SIZE]; - - rr = &(s->s3->rrec); - sess = s->session; - - /* - * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, - * and we have that many bytes in s->packet - */ - rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]); - - /* - * ok, we can now read from 's->packet' data into 'rr' rr->input points - * at rr->length bytes, which need to be copied into rr->data by either - * the decryption or by the decompression When the data is 'copied' into - * the rr->data buffer, rr->input will be pointed at the new buffer - */ - - /* - * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length - * bytes of encrypted compressed stuff. - */ - - /* check is not needed I believe */ - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); - goto f_err; - } - - /* decrypt in place in 'rr->input' */ - rr->data = rr->input; - - enc_err = s->method->ssl3_enc->enc(s, 0); - /*- - * enc_err is: - * 0: (in non-constant time) if the record is publically invalid. - * 1: if the padding is valid - * -1: if the padding is invalid - */ - if (enc_err == 0) { - /* For DTLS we simply ignore bad packets. */ - rr->length = 0; - s->packet_length = 0; - goto err; - } -#ifdef TLS_DEBUG - printf("dec %d\n", rr->length); - { - unsigned int z; - for (z = 0; z < rr->length; z++) - printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\n"); -#endif - - /* r->length is now the compressed data plus mac */ - if ((sess != NULL) && - (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { - /* s->read_hash != NULL => mac_size != -1 */ - unsigned char *mac = NULL; - unsigned char mac_tmp[EVP_MAX_MD_SIZE]; - mac_size = EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); - - /* - * kludge: *_cbc_remove_padding passes padding length in rr->type - */ - orig_len = rr->length + ((unsigned int)rr->type >> 8); - - /* - * orig_len is the length of the record before any padding was - * removed. This is public information, as is the MAC in use, - * therefore we can safely process the record in a different amount - * of time if it's too short to possibly contain a MAC. - */ - if (orig_len < mac_size || - /* CBC records must have a padding length byte too. */ - (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && - orig_len < mac_size + 1)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { - /* - * We update the length so that the TLS header bytes can be - * constructed correctly but we need to extract the MAC in - * constant time from within the record, without leaking the - * contents of the padding bytes. - */ - mac = mac_tmp; - ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); - rr->length -= mac_size; - } else { - /* - * In this case there's no padding, so |orig_len| equals - * |rec->length| and we checked that there's enough bytes for - * |mac_size| above. - */ - rr->length -= mac_size; - mac = &rr->data[rr->length]; - } - - i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); - if (i < 0 || mac == NULL - || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) - enc_err = -1; - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) - enc_err = -1; - } - - if (enc_err < 0) { - /* decryption failed, silently discard message */ - rr->length = 0; - s->packet_length = 0; - goto err; - } - - /* r->length is now just compressed */ - if (s->expand != NULL) { - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, - SSL_R_COMPRESSED_LENGTH_TOO_LONG); - goto f_err; - } - if (!ssl3_do_uncompress(s)) { - al = SSL_AD_DECOMPRESSION_FAILURE; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION); - goto f_err; - } - } - - if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); - goto f_err; - } - - rr->off = 0; - /*- - * So at this point the following is true - * ssl->s3->rrec.type is the type of record - * ssl->s3->rrec.length == number of bytes in record - * ssl->s3->rrec.off == offset to first valid byte - * ssl->s3->rrec.data == where to take bytes from, increment - * after use :-). - */ - - /* we have pulled in a full packet so zero things */ - s->packet_length = 0; - - /* Mark receipt of record. */ - dtls1_record_bitmap_update(s, bitmap); - - return (1); - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (0); -} - -/*- - * Call this to get a new input record. - * It will return <= 0 if more data is needed, normally due to an error - * or non-blocking IO. - * When it finishes, one packet has been decoded and can be found in - * ssl->s3->rrec.type - is the type of record - * ssl->s3->rrec.data, - data - * ssl->s3->rrec.length, - number of bytes - */ -/* used only by dtls1_read_bytes */ -int dtls1_get_record(SSL *s) -{ - int ssl_major, ssl_minor; - int i, n; - SSL3_RECORD *rr; - unsigned char *p = NULL; - unsigned short version; - DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; - - rr = &(s->s3->rrec); - - again: - /* - * The epoch may have changed. If so, process all the pending records. - * This is a non-blocking operation. - */ - if (!dtls1_process_buffered_records(s)) - return -1; - - /* if we're renegotiating, then there may be buffered records */ - if (dtls1_get_processed_record(s)) - return 1; - - /* get something from the wire */ - /* check if we have the header */ - if ((s->rstate != SSL_ST_READ_BODY) || - (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { - n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); - /* read timeout is handled by dtls1_read_bytes */ - if (n <= 0) - return (n); /* error or non-blocking */ - - /* this packet contained a partial record, dump it */ - if (s->packet_length != DTLS1_RT_HEADER_LENGTH) { - s->packet_length = 0; - goto again; - } - - s->rstate = SSL_ST_READ_BODY; - - p = s->packet; - - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, - s, s->msg_callback_arg); - - /* Pull apart the header into the DTLS1_RECORD */ - rr->type = *(p++); - ssl_major = *(p++); - ssl_minor = *(p++); - version = (ssl_major << 8) | ssl_minor; - - /* sequence number is 64 bits, with top 2 bytes = epoch */ - n2s(p, rr->epoch); - - memcpy(&(s->s3->read_sequence[2]), p, 6); - p += 6; - - n2s(p, rr->length); - - /* - * Lets check the version. We tolerate alerts that don't have the exact - * version number (e.g. because of protocol version errors) - */ - if (!s->first_packet && rr->type != SSL3_RT_ALERT) { - if (version != s->version) { - /* unexpected version, silently discard */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - } - - if ((version & 0xff00) != (s->version & 0xff00)) { - /* wrong version, silently discard record */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { - /* record too long, silently discard it */ - rr->length = 0; - s->packet_length = 0; - goto again; - } - - /* now s->rstate == SSL_ST_READ_BODY */ - } - - /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ - - if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) { - /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ - i = rr->length; - n = ssl3_read_n(s, i, i, 1); - /* this packet contained a partial record, dump it */ - if (n != i) { - rr->length = 0; - s->packet_length = 0; - goto again; - } - - /* - * now n == rr->length, and s->packet_length == - * DTLS1_RT_HEADER_LENGTH + rr->length - */ - } - s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ - - /* match epochs. NULL means the packet is dropped on the floor */ - bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); - if (bitmap == NULL) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - /* Only do replay check if no SCTP bio */ - if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) { -#endif - /* - * Check whether this is a repeat, or aged record. Don't check if - * we're listening and this message is a ClientHello. They can look - * as if they're replayed, since they arrive from different - * connections and would be dropped unnecessarily. - */ - if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && - s->packet_length > DTLS1_RT_HEADER_LENGTH && - s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && - !dtls1_record_replay_check(s, bitmap)) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - } -#endif - - /* just read a 0 length packet */ - if (rr->length == 0) - goto again; - - /* - * If this record is from the next epoch (either HM or ALERT), and a - * handshake is currently in progress, buffer it since it cannot be - * processed at this time. However, do not buffer anything while - * listening. - */ - if (is_next_epoch) { - if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { - if (dtls1_buffer_record - (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) - return -1; - } - rr->length = 0; - s->packet_length = 0; - goto again; - } - - if (!dtls1_process_record(s, bitmap)) { - rr->length = 0; - s->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } - - return (1); - -} - -/*- - * Return up to 'len' payload bytes received in 'type' records. - * 'type' is one of the following: - * - * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) - * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) - * - 0 (during a shutdown, no data has to be returned) - * - * If we don't have stored data to work from, read a SSL/TLS record first - * (possibly multiple records if we still don't have anything to return). - * - * This function must handle any surprises the peer may have for us, such as - * Alert records (e.g. close_notify), ChangeCipherSpec records (not really - * a surprise, but handled as if it were), or renegotiation requests. - * Also if record payloads contain fragments too small to process, we store - * them until there is enough for the respective protocol (the record protocol - * may use arbitrary fragmentation and even interleaving): - * Change cipher spec protocol - * just 1 byte needed, no need for keeping anything stored - * Alert protocol - * 2 bytes needed (AlertLevel, AlertDescription) - * Handshake protocol - * 4 bytes needed (HandshakeType, uint24 length) -- we just have - * to detect unexpected Client Hello and Hello Request messages - * here, anything else is handled by higher layers - * Application data protocol - * none of our business - */ -int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) -{ - int al, i, j, ret; - unsigned int n; - SSL3_RECORD *rr; - void (*cb) (const SSL *ssl, int type2, int val) = NULL; - - if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ - if (!ssl3_setup_buffers(s)) - return (-1); - - /* XXX: check what the second '&& type' is about */ - if ((type && (type != SSL3_RT_APPLICATION_DATA) && - (type != SSL3_RT_HANDSHAKE) && type) || - (peek && (type != SSL3_RT_APPLICATION_DATA))) { - SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); - return -1; - } - - /* - * check whether there's a handshake message (client hello?) waiting - */ - if ((ret = have_handshake_fragment(s, type, buf, len, peek))) - return ret; - - /* - * Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. - */ - -#ifndef OPENSSL_NO_SCTP - /* - * Continue handshake if it had to be interrupted to read app data with - * SCTP. - */ - if ((!s->in_handshake && SSL_in_init(s)) || - (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK) - && s->s3->in_read_app_data != 2)) -#else - if (!s->in_handshake && SSL_in_init(s)) -#endif - { - /* type == SSL3_RT_APPLICATION_DATA */ - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - } - - start: - s->rwstate = SSL_NOTHING; - - /*- - * s->s3->rrec.type - is the type of record - * s->s3->rrec.data, - data - * s->s3->rrec.off, - offset into 'data' for next read - * s->s3->rrec.length, - number of bytes. - */ - rr = &(s->s3->rrec); - - /* - * We are not handshaking and have no data yet, so process data buffered - * during the last handshake in advance, if any. - */ - if (s->state == SSL_ST_OK && rr->length == 0) { - pitem *item; - item = pqueue_pop(s->d1->buffered_app_data.q); - if (item) { -#ifndef OPENSSL_NO_SCTP - /* Restore bio_dgram_sctp_rcvinfo struct */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s))) { - DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, - sizeof(rdata->recordinfo), &rdata->recordinfo); - } -#endif - - dtls1_copy_record(s, item); - - OPENSSL_free(item->data); - pitem_free(item); - } - } - - /* Check for timeout */ - if (dtls1_handle_timeout(s) > 0) - goto start; - - /* get new packet if necessary */ - if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { - ret = dtls1_get_record(s); - if (ret <= 0) { - ret = dtls1_read_failed(s, ret); - /* anything other than a timeout is an error */ - if (ret <= 0) - return (ret); - else - goto start; - } - } - - if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) { - rr->length = 0; - goto start; - } - - /* - * Reset the count of consecutive warning alerts if we've got a non-empty - * record that isn't an alert. - */ - if (rr->type != SSL3_RT_ALERT && rr->length != 0) - s->cert->alert_count = 0; - - /* we now have a packet which can be read and processed */ - - if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, - * reset by ssl3_get_finished */ - && (rr->type != SSL3_RT_HANDSHAKE)) { - /* - * We now have application data between CCS and Finished. Most likely - * the packets were reordered on their way, so buffer the application - * data for later processing rather than dropping the connection. - */ - if (dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num) < - 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); - return -1; - } - rr->length = 0; - goto start; - } - - /* - * If the other end has shut down, throw anything we read away (even in - * 'peek' mode) - */ - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - rr->length = 0; - s->rwstate = SSL_NOTHING; - return (0); - } - - if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or - * SSL3_RT_HANDSHAKE */ - /* - * make sure that we are not getting application data when we are - * doing a handshake for the first time - */ - if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && - (s->enc_read_ctx == NULL)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); - goto f_err; - } - - if (len <= 0) - return (len); - - if ((unsigned int)len > rr->length) - n = rr->length; - else - n = (unsigned int)len; - - memcpy(buf, &(rr->data[rr->off]), n); - if (!peek) { - rr->length -= n; - rr->off += n; - if (rr->length == 0) { - s->rstate = SSL_ST_READ_HEADER; - rr->off = 0; - } - } -#ifndef OPENSSL_NO_SCTP - /* - * We were about to renegotiate but had to read belated application - * data first, so retry. - */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - rr->type == SSL3_RT_APPLICATION_DATA && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) { - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - } - - /* - * We might had to delay a close_notify alert because of reordered - * app data. If there was an alert and there is no message to read - * anymore, finally set shutdown. - */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - s->d1->shutdown_received - && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - return (0); - } -#endif - return (n); - } - - /* - * If we get here, then type != rr->type; if we have a handshake message, - * then it was unexpected (Hello Request or Client Hello). - */ - - /* - * In case of record types for which we have 'fragment' storage, fill - * that so that we can process the data at a fixed place. - */ - { - unsigned int k, dest_maxlen = 0; - unsigned char *dest = NULL; - unsigned int *dest_len = NULL; - - if (rr->type == SSL3_RT_HANDSHAKE) { - dest_maxlen = sizeof(s->d1->handshake_fragment); - dest = s->d1->handshake_fragment; - dest_len = &s->d1->handshake_fragment_len; - } else if (rr->type == SSL3_RT_ALERT) { - dest_maxlen = sizeof(s->d1->alert_fragment); - dest = s->d1->alert_fragment; - dest_len = &s->d1->alert_fragment_len; - } -#ifndef OPENSSL_NO_HEARTBEATS - else if (rr->type == TLS1_RT_HEARTBEAT) { - dtls1_process_heartbeat(s); - - /* Exit and notify application to read again */ - rr->length = 0; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - return (-1); - } -#endif - /* else it's a CCS message, or application data or wrong */ - else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) { - /* - * Application data while renegotiating is allowed. Try again - * reading. - */ - if (rr->type == SSL3_RT_APPLICATION_DATA) { - BIO *bio; - s->s3->in_read_app_data = 2; - bio = SSL_get_rbio(s); - s->rwstate = SSL_READING; - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - - /* Not certain if this is the right error handling */ - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - } - - if (dest_maxlen > 0) { - /* - * XDTLS: In a pathalogical case, the Client Hello may be - * fragmented--don't always expect dest_maxlen bytes - */ - if (rr->length < dest_maxlen) { -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE - /* - * for normal alerts rr->length is 2, while - * dest_maxlen is 7 if we were to handle this - * non-existing alert... - */ - FIX ME -#endif - s->rstate = SSL_ST_READ_HEADER; - rr->length = 0; - goto start; - } - - /* now move 'n' bytes: */ - for (k = 0; k < dest_maxlen; k++) { - dest[k] = rr->data[rr->off++]; - rr->length--; - } - *dest_len = dest_maxlen; - } - } - - /*- - * s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; - * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. - * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) - */ - - /* If we are a client, check for an incoming 'Hello Request': */ - if ((!s->server) && - (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && - (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && - (s->session != NULL) && (s->session->cipher != NULL)) { - s->d1->handshake_fragment_len = 0; - - if ((s->d1->handshake_fragment[1] != 0) || - (s->d1->handshake_fragment[2] != 0) || - (s->d1->handshake_fragment[3] != 0)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); - goto f_err; - } - - /* - * no need to check sequence number on HELLO REQUEST messages - */ - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - s->d1->handshake_fragment, 4, s, - s->msg_callback_arg); - - if (SSL_is_init_finished(s) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && - !s->s3->renegotiate) { - s->d1->handshake_read_seq++; - s->new_session = 1; - ssl3_renegotiate(s); - if (ssl3_renegotiate_check(s)) { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ - BIO *bio; - /* - * In the case where we try to read application data, - * but we trigger an SSL handshake, we return -1 with - * the retry option set. Otherwise renegotiation may - * cause nasty problems in the blocking world - */ - s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - } - } - } - /* - * we either finished a handshake or ignored the request, now try - * again to obtain the (application) data we were asked for - */ - goto start; - } - - /* - * If we are a server and get a client hello when renegotiation isn't - * allowed send back a no renegotiation alert and carry on. - */ - if (s->server - && SSL_is_init_finished(s) - && !s->s3->send_connection_binding - && s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH - && s->d1->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO - && s->s3->previous_client_finished_len != 0 - && (s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) == 0) { - s->d1->handshake_fragment_len = 0; - rr->length = 0; - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); - goto start; - } - - - if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) { - int alert_level = s->d1->alert_fragment[0]; - int alert_descr = s->d1->alert_fragment[1]; - - s->d1->alert_fragment_len = 0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_ALERT, - s->d1->alert_fragment, 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (alert_level << 8) | alert_descr; - cb(s, SSL_CB_READ_ALERT, j); - } - - if (alert_level == SSL3_AL_WARNING) { - s->s3->warn_alert = alert_descr; - - s->cert->alert_count++; - if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); - goto f_err; - } - - if (alert_descr == SSL_AD_CLOSE_NOTIFY) { -#ifndef OPENSSL_NO_SCTP - /* - * With SCTP and streams the socket may deliver app data - * after a close_notify alert. We have to check this first so - * that nothing gets discarded. - */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && - BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->d1->shutdown_received = 1; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - return -1; - } -#endif - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - return (0); - } -#if 0 - /* XXX: this is a possible improvement in the future */ - /* now check if it's a missing record */ - if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { - unsigned short seq; - unsigned int frag_off; - unsigned char *p = &(s->d1->alert_fragment[2]); - - n2s(p, seq); - n2l3(p, frag_off); - - dtls1_retransmit_message(s, - dtls1_get_queue_priority - (frag->msg_header.seq, 0), frag_off, - &found); - if (!found && SSL_in_init(s)) { - /* - * fprintf( stderr,"in init = %d\n", SSL_in_init(s)); - */ - /* - * requested a message not yet sent, send an alert - * ourselves - */ - ssl3_send_alert(s, SSL3_AL_WARNING, - DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); - } - } -#endif - } else if (alert_level == SSL3_AL_FATAL) { - char tmp[16]; - - s->rwstate = SSL_NOTHING; - s->s3->fatal_alert = alert_descr; - SSLerr(SSL_F_DTLS1_READ_BYTES, - SSL_AD_REASON_OFFSET + alert_descr); - BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr); - ERR_add_error_data(2, "SSL alert number ", tmp); - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->session_ctx, s->session); - return (0); - } else { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); - goto f_err; - } - - goto start; - } - - if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a - * shutdown */ - s->rwstate = SSL_NOTHING; - rr->length = 0; - return (0); - } - - if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { - struct ccs_header_st ccs_hdr; - unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH; - - dtls1_get_ccs_header(rr->data, &ccs_hdr); - - if (s->version == DTLS1_BAD_VER) - ccs_hdr_len = 3; - - /* - * 'Change Cipher Spec' is just a single byte, so we know exactly - * what the record payload has to look like - */ - /* XDTLS: check that epoch is consistent */ - if ((rr->length != ccs_hdr_len) || - (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto f_err; - } - - rr->length = 0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - rr->data, 1, s, s->msg_callback_arg); - - /* - * We can't process a CCS now, because previous handshake messages - * are still missing, so just drop it. - */ - if (!s->d1->change_cipher_spec_ok) { - goto start; - } - - s->d1->change_cipher_spec_ok = 0; - - s->s3->change_cipher_spec = 1; - if (!ssl3_do_change_cipher_spec(s)) - goto err; - - /* do this whenever CCS is processed */ - dtls1_reset_seq_numbers(s, SSL3_CC_READ); - - if (s->version == DTLS1_BAD_VER) - s->d1->handshake_read_seq++; - -#ifndef OPENSSL_NO_SCTP - /* - * Remember that a CCS has been received, so that an old key of - * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no - * SCTP is used - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); -#endif - - goto start; - } - - /* - * Unexpected handshake message (Client Hello, or protocol violation) - */ - if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && - !s->in_handshake) { - struct hm_header_st msg_hdr; - - /* this may just be a stale retransmit */ - dtls1_get_message_header(rr->data, &msg_hdr); - if (rr->epoch != s->d1->r_epoch) { - rr->length = 0; - goto start; - } - - /* - * If we are server, we may have a repeated FINISHED of the client - * here, then retransmit our CCS and FINISHED. - */ - if (msg_hdr.type == SSL3_MT_FINISHED) { - if (dtls1_check_timeout_num(s) < 0) - return -1; - - dtls1_retransmit_buffered_messages(s); - rr->length = 0; - goto start; - } - - if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { -#if 0 /* worked only because C operator preferences - * are not as expected (and because this is - * not really needed for clients except for - * detecting protocol violations): */ - s->state = SSL_ST_BEFORE | (s->server) - ? SSL_ST_ACCEPT : SSL_ST_CONNECT; -#else - s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; -#endif - s->renegotiate = 1; - s->new_session = 1; - } - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ - BIO *bio; - /* - * In the case where we try to read application data, but we - * trigger an SSL handshake, we return -1 with the retry - * option set. Otherwise renegotiation may cause nasty - * problems in the blocking world - */ - s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - } - goto start; - } - - switch (rr->type) { - default: -#ifndef OPENSSL_NO_TLS - /* TLS just ignores unknown message types */ - if (s->version == TLS1_VERSION) { - rr->length = 0; - goto start; - } -#endif - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - case SSL3_RT_CHANGE_CIPHER_SPEC: - case SSL3_RT_ALERT: - case SSL3_RT_HANDSHAKE: - /* - * we already handled all of these, with the possible exception of - * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not - * happen when type != rr->type - */ - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); - goto f_err; - case SSL3_RT_APPLICATION_DATA: - /* - * At this point, we were expecting handshake data, but have - * application data. If the library was running inside ssl3_read() - * (i.e. in_read_app_data is set) and it makes sense to read - * application data at this point (session renegotiation not yet - * started), we will indulge it. - */ - if (s->s3->in_read_app_data && - (s->s3->total_renegotiations != 0) && - (((s->state & SSL_ST_CONNECT) && - (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && - (s->state <= SSL3_ST_CR_SRVR_HELLO_A) - ) || ((s->state & SSL_ST_ACCEPT) && - (s->state <= SSL3_ST_SW_HELLO_REQ_A) && - (s->state >= SSL3_ST_SR_CLNT_HELLO_A) - ) - )) { - s->s3->in_read_app_data = 2; - return (-1); - } else { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - } - } - /* not reached */ - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (-1); -} - -int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) -{ - int i; - -#ifndef OPENSSL_NO_SCTP - /* - * Check if we have to continue an interrupted handshake for reading - * belated app data with SCTP. - */ - if ((SSL_in_init(s) && !s->in_handshake) || - (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - (s->state == DTLS1_SCTP_ST_SR_READ_SOCK - || s->state == DTLS1_SCTP_ST_CR_READ_SOCK))) -#else - if (SSL_in_init(s) && !s->in_handshake) -#endif - { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); - return -1; - } - } - - if (len > SSL3_RT_MAX_PLAIN_LENGTH) { - SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG); - return -1; - } - - i = dtls1_write_bytes(s, type, buf_, len); - return i; -} - - /* - * this only happens when a client hello is received and a handshake - * is started. - */ -static int -have_handshake_fragment(SSL *s, int type, unsigned char *buf, - int len, int peek) -{ - - if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0)) - /* (partially) satisfy request from storage */ - { - unsigned char *src = s->d1->handshake_fragment; - unsigned char *dst = buf; - unsigned int k, n; - - /* peek == 0 */ - n = 0; - while ((len > 0) && (s->d1->handshake_fragment_len > 0)) { - *dst++ = *src++; - len--; - s->d1->handshake_fragment_len--; - n++; - } - /* move any remaining fragment bytes: */ - for (k = 0; k < s->d1->handshake_fragment_len; k++) - s->d1->handshake_fragment[k] = *src++; - return n; - } - - return 0; -} - -/* - * Call this to write data in records of type 'type' It will return <= 0 if - * not all data has been sent or non-blocking IO. - */ -int dtls1_write_bytes(SSL *s, int type, const void *buf, int len) -{ - int i; - - OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); - s->rwstate = SSL_NOTHING; - i = do_dtls1_write(s, type, buf, len, 0); - return i; -} - -int do_dtls1_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragment) -{ - unsigned char *p, *pseq; - int i, mac_size, clear = 0; - int prefix_len = 0; - int eivlen; - SSL3_RECORD *wr; - SSL3_BUFFER *wb; - SSL_SESSION *sess; - - /* - * first check if there is a SSL3_BUFFER still being written out. This - * will happen with non blocking IO - */ - if (s->s3->wbuf.left != 0) { - OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ - return (ssl3_write_pending(s, type, buf, len)); - } - - /* If we have an alert to send, lets send it */ - if (s->s3->alert_dispatch) { - i = s->method->ssl_dispatch_alert(s); - if (i <= 0) - return (i); - /* if it went, fall through and send more stuff */ - } - - if (len == 0 && !create_empty_fragment) - return 0; - - wr = &(s->s3->wrec); - wb = &(s->s3->wbuf); - sess = s->session; - - if ((sess == NULL) || - (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL)) - clear = 1; - - if (clear) - mac_size = 0; - else { - mac_size = EVP_MD_CTX_size(s->write_hash); - if (mac_size < 0) - goto err; - } - - /* DTLS implements explicit IV, so no need for empty fragments */ -#if 0 - /* - * 'create_empty_fragment' is true only when this function calls itself - */ - if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done - && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER) - { - /* - * countermeasure against known-IV weakness in CBC ciphersuites (see - * http://www.openssl.org/~bodo/tls-cbc.txt) - */ - - if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { - /* - * recursive function call with 'create_empty_fragment' set; this - * prepares and buffers the data for an empty fragment (these - * 'prefix_len' bytes are sent out later together with the actual - * payload) - */ - prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1); - if (prefix_len <= 0) - goto err; - - if (s->s3->wbuf.len < - (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) { - /* insufficient space */ - SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - s->s3->empty_fragment_done = 1; - } -#endif - p = wb->buf + prefix_len; - - /* write the header */ - - *(p++) = type & 0xff; - wr->type = type; - /* - * Special case: for hello verify request, client version 1.0 and we - * haven't decided which version to use yet send back using version 1.0 - * header: otherwise some clients will ignore it. - */ - if (s->method->version == DTLS_ANY_VERSION) { - *(p++) = DTLS1_VERSION >> 8; - *(p++) = DTLS1_VERSION & 0xff; - } else { - *(p++) = s->version >> 8; - *(p++) = s->version & 0xff; - } - - /* field where we are to write out packet epoch, seq num and len */ - pseq = p; - p += 10; - - /* Explicit IV length, block ciphers appropriate version flag */ - if (s->enc_write_ctx) { - int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); - if (mode == EVP_CIPH_CBC_MODE) { - eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); - if (eivlen <= 1) - eivlen = 0; - } - /* Need explicit part of IV for GCM mode */ - else if (mode == EVP_CIPH_GCM_MODE) - eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; - else - eivlen = 0; - } else - eivlen = 0; - - /* lets setup the record stuff. */ - wr->data = p + eivlen; /* make room for IV in case of CBC */ - wr->length = (int)len; - wr->input = (unsigned char *)buf; - - /* - * we now 'read' from wr->input, wr->length bytes into wr->data - */ - - /* first we compress */ - if (s->compress != NULL) { - if (!ssl3_do_compress(s)) { - SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_COMPRESSION_FAILURE); - goto err; - } - } else { - memcpy(wr->data, wr->input, wr->length); - wr->input = wr->data; - } - - /* - * we should still have the output to wr->data and the input from - * wr->input. Length should be wr->length. wr->data still points in the - * wb->buf - */ - - if (mac_size != 0) { - if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0) - goto err; - wr->length += mac_size; - } - - /* this is true regardless of mac size */ - wr->input = p; - wr->data = p; - - if (eivlen) - wr->length += eivlen; - - if (s->method->ssl3_enc->enc(s, 1) < 1) - goto err; - - /* record length after mac and block padding */ - /* - * if (type == SSL3_RT_APPLICATION_DATA || (type == SSL3_RT_ALERT && ! - * SSL_in_init(s))) - */ - - /* there's only one epoch between handshake and app data */ - - s2n(s->d1->w_epoch, pseq); - - /* XDTLS: ?? */ - /* - * else s2n(s->d1->handshake_epoch, pseq); - */ - - memcpy(pseq, &(s->s3->write_sequence[2]), 6); - pseq += 6; - s2n(wr->length, pseq); - - if (s->msg_callback) - s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH, - DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg); - - /* - * we should now have wr->data pointing to the encrypted data, which is - * wr->length long - */ - wr->type = type; /* not needed but helps for debugging */ - wr->length += DTLS1_RT_HEADER_LENGTH; - -#if 0 /* this is now done at the message layer */ - /* buffer the record, making it easy to handle retransmits */ - if (type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC) - dtls1_buffer_record(s, wr->data, wr->length, - *((PQ_64BIT *) & (s->s3->write_sequence[0]))); -#endif - - ssl3_record_sequence_update(&(s->s3->write_sequence[0])); - - if (create_empty_fragment) { - /* - * we are in a recursive call; just return the length, don't write - * out anything here - */ - return wr->length; - } - - /* now let's set up wb */ - wb->left = prefix_len + wr->length; - wb->offset = 0; - - /* - * memorize arguments so that ssl3_write_pending can detect bad write - * retries later - */ - s->s3->wpend_tot = len; - s->s3->wpend_buf = buf; - s->s3->wpend_type = type; - s->s3->wpend_ret = len; - - /* we now just need to write the buffer */ - return ssl3_write_pending(s, type, buf, len); - err: - return -1; -} - -static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) -{ - int cmp; - unsigned int shift; - const unsigned char *seq = s->s3->read_sequence; - - cmp = satsub64be(seq, bitmap->max_seq_num); - if (cmp > 0) { - memcpy(s->s3->rrec.seq_num, seq, 8); - return 1; /* this record in new */ - } - shift = -cmp; - if (shift >= sizeof(bitmap->map) * 8) - return 0; /* stale, outside the window */ - else if (bitmap->map & (1UL << shift)) - return 0; /* record previously received */ - - memcpy(s->s3->rrec.seq_num, seq, 8); - return 1; -} - -static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) -{ - int cmp; - unsigned int shift; - const unsigned char *seq = s->s3->read_sequence; - - cmp = satsub64be(seq, bitmap->max_seq_num); - if (cmp > 0) { - shift = cmp; - if (shift < sizeof(bitmap->map) * 8) - bitmap->map <<= shift, bitmap->map |= 1UL; - else - bitmap->map = 1UL; - memcpy(bitmap->max_seq_num, seq, 8); - } else { - shift = -cmp; - if (shift < sizeof(bitmap->map) * 8) - bitmap->map |= 1UL << shift; - } -} - -int dtls1_dispatch_alert(SSL *s) -{ - int i, j; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - unsigned char buf[DTLS1_AL_HEADER_LENGTH]; - unsigned char *ptr = &buf[0]; - - s->s3->alert_dispatch = 0; - - memset(buf, 0x00, sizeof(buf)); - *ptr++ = s->s3->send_alert[0]; - *ptr++ = s->s3->send_alert[1]; - -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE - if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { - s2n(s->d1->handshake_read_seq, ptr); -# if 0 - if (s->d1->r_msg_hdr.frag_off == 0) - /* - * waiting for a new msg - */ - else - s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */ -# endif - -# if 0 - fprintf(stderr, - "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n", - s->d1->handshake_read_seq, s->d1->r_msg_hdr.seq); -# endif - l2n3(s->d1->r_msg_hdr.frag_off, ptr); - } -#endif - - i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); - if (i <= 0) { - s->s3->alert_dispatch = 1; - /* fprintf( stderr, "not done with alert\n" ); */ - } else { - if (s->s3->send_alert[0] == SSL3_AL_FATAL -#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE - || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE -#endif - ) - (void)BIO_flush(s->wbio); - - if (s->msg_callback) - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, - 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; - cb(s, SSL_CB_WRITE_ALERT, j); - } - } - return (i); -} - -static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, - unsigned int *is_next_epoch) -{ - - *is_next_epoch = 0; - - /* In current epoch, accept HM, CCS, DATA, & ALERT */ - if (rr->epoch == s->d1->r_epoch) - return &s->d1->bitmap; - - /* - * Only HM and ALERT messages can be from the next epoch and only if we - * have already processed all of the unprocessed records from the last - * epoch - */ - else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && - s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && - (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { - *is_next_epoch = 1; - return &s->d1->next_bitmap; - } - - return NULL; -} - -#if 0 -static int -dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, - unsigned short *priority, unsigned long *offset) -{ - - /* alerts are passed up immediately */ - if (rr->type == SSL3_RT_APPLICATION_DATA || rr->type == SSL3_RT_ALERT) - return 0; - - /* - * Only need to buffer if a handshake is underway. (this implies that - * Hello Request and Client Hello are passed up immediately) - */ - if (SSL_in_init(s)) { - unsigned char *data = rr->data; - /* need to extract the HM/CCS sequence number here */ - if (rr->type == SSL3_RT_HANDSHAKE || - rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { - unsigned short seq_num; - struct hm_header_st msg_hdr; - struct ccs_header_st ccs_hdr; - - if (rr->type == SSL3_RT_HANDSHAKE) { - dtls1_get_message_header(data, &msg_hdr); - seq_num = msg_hdr.seq; - *offset = msg_hdr.frag_off; - } else { - dtls1_get_ccs_header(data, &ccs_hdr); - seq_num = ccs_hdr.seq; - *offset = 0; - } - - /* - * this is either a record we're waiting for, or a retransmit of - * something we happened to previously receive (higher layers - * will drop the repeat silently - */ - if (seq_num < s->d1->handshake_read_seq) - return 0; - if (rr->type == SSL3_RT_HANDSHAKE && - seq_num == s->d1->handshake_read_seq && - msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off) - return 0; - else if (seq_num == s->d1->handshake_read_seq && - (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC || - msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off)) - return 0; - else { - *priority = seq_num; - return 1; - } - } else /* unknown record type */ - return 0; - } - - return 0; -} -#endif - -void dtls1_reset_seq_numbers(SSL *s, int rw) -{ - unsigned char *seq; - unsigned int seq_bytes = sizeof(s->s3->read_sequence); - - if (rw & SSL3_CC_READ) { - seq = s->s3->read_sequence; - s->d1->r_epoch++; - memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); - memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); - - /* - * We must not use any buffered messages received from the previous - * epoch - */ - dtls1_clear_received_buffer(s); - } else { - seq = s->s3->write_sequence; - memcpy(s->d1->last_write_sequence, seq, - sizeof(s->s3->write_sequence)); - s->d1->w_epoch++; - } - - memset(seq, 0x00, seq_bytes); -} -/* ssl/t1_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* - * DTLS code by Eric Rescorla - * - * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. - */ - -#include -// #include "objects.h" -// #include "ssl_locl.h" -#include "srtp.h" - -#ifndef OPENSSL_NO_SRTP - -static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { - { - "SRTP_AES128_CM_SHA1_80", - SRTP_AES128_CM_SHA1_80, - }, - { - "SRTP_AES128_CM_SHA1_32", - SRTP_AES128_CM_SHA1_32, - }, -# if 0 - { - "SRTP_NULL_SHA1_80", - SRTP_NULL_SHA1_80, - }, - { - "SRTP_NULL_SHA1_32", - SRTP_NULL_SHA1_32, - }, -# endif - {0} -}; - -static int find_profile_by_name(char *profile_name, - SRTP_PROTECTION_PROFILE **pptr, unsigned len) -{ - SRTP_PROTECTION_PROFILE *p; - - p = srtp_known_profiles; - while (p->name) { - if ((len == strlen(p->name)) && !strncmp(p->name, profile_name, len)) { - *pptr = p; - return 0; - } - - p++; - } - - return 1; -} - -static int ssl_ctx_make_profiles(const char *profiles_string, - STACK_OF(SRTP_PROTECTION_PROFILE) **out) -{ - STACK_OF(SRTP_PROTECTION_PROFILE) *profiles; - - char *col; - char *ptr = (char *)profiles_string; - - SRTP_PROTECTION_PROFILE *p; - - if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); - return 1; - } - - do { - col = strchr(ptr, ':'); - - if (!find_profile_by_name(ptr, &p, - col ? col - ptr : (int)strlen(ptr))) { - if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - sk_SRTP_PROTECTION_PROFILE_free(profiles); - return 1; - } - - sk_SRTP_PROTECTION_PROFILE_push(profiles, p); - } else { - SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, - SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); - sk_SRTP_PROTECTION_PROFILE_free(profiles); - return 1; - } - - if (col) - ptr = col + 1; - } while (col); - - *out = profiles; - - return 0; -} - -int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) -{ - return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); -} - -int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) -{ - return ssl_ctx_make_profiles(profiles, &s->srtp_profiles); -} - -STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) -{ - if (s != NULL) { - if (s->srtp_profiles != NULL) { - return s->srtp_profiles; - } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) { - return s->ctx->srtp_profiles; - } - } - - return NULL; -} - -SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) -{ - return s->srtp_profile; -} - -/* - * Note: this function returns 0 length if there are no profiles specified - */ -int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, - int maxlen) -{ - int ct = 0; - int i; - STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0; - SRTP_PROTECTION_PROFILE *prof; - - clnt = SSL_get_srtp_profiles(s); - ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */ - - if (p) { - if (ct == 0) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); - return 1; - } - - if ((2 + ct * 2 + 1) > maxlen) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); - return 1; - } - - /* Add the length */ - s2n(ct * 2, p); - for (i = 0; i < ct; i++) { - prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); - s2n(prof->id, p); - } - - /* Add an empty use_mki value */ - *p++ = 0; - } - - *len = 2 + ct * 2 + 1; - - return 0; -} - -int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len, - int *al) -{ - SRTP_PROTECTION_PROFILE *sprof; - STACK_OF(SRTP_PROTECTION_PROFILE) *srvr; - int ct; - int mki_len; - int i, srtp_pref; - unsigned int id; - - /* Length value + the MKI length */ - if (len < 3) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - /* Pull off the length of the cipher suite list */ - n2s(d, ct); - len -= 2; - - /* Check that it is even */ - if (ct % 2) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - /* Check that lengths are consistent */ - if (len < (ct + 1)) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - srvr = SSL_get_srtp_profiles(s); - s->srtp_profile = NULL; - /* Search all profiles for a match initially */ - srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr); - - while (ct) { - n2s(d, id); - ct -= 2; - len -= 2; - - /* - * Only look for match in profiles of higher preference than - * current match. - * If no profiles have been have been configured then this - * does nothing. - */ - for (i = 0; i < srtp_pref; i++) { - sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i); - if (sprof->id == id) { - s->srtp_profile = sprof; - srtp_pref = i; - break; - } - } - } - - /* - * Now extract the MKI value as a sanity check, but discard it for now - */ - mki_len = *d; - d++; - len--; - - if (mki_len != len) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_MKI_VALUE); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - return 0; -} - -int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, - int maxlen) -{ - if (p) { - if (maxlen < 5) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, - SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); - return 1; - } - - if (s->srtp_profile == 0) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, - SSL_R_USE_SRTP_NOT_NEGOTIATED); - return 1; - } - s2n(2, p); - s2n(s->srtp_profile->id, p); - *p++ = 0; - } - *len = 5; - - return 0; -} - -int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len, - int *al) -{ - unsigned id; - int i; - int ct; - - STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; - SRTP_PROTECTION_PROFILE *prof; - - if (len != 5) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - n2s(d, ct); - if (ct != 2) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - n2s(d, id); - if (*d) { /* Must be no MKI, since we never offer one */ - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_MKI_VALUE); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 1; - } - - clnt = SSL_get_srtp_profiles(s); - - /* Throw an error if the server gave us an unsolicited extension */ - if (clnt == NULL) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_NO_SRTP_PROFILES); - *al = SSL_AD_DECODE_ERROR; - return 1; - } - - /* - * Check to see if the server gave us something we support (and - * presumably offered) - */ - for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { - prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); - - if (prof->id == id) { - s->srtp_profile = prof; - *al = 0; - return 0; - } - } - - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, - SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); - *al = SSL_AD_DECODE_ERROR; - return 1; -} - -#endif -/* ssl/d1_srvr.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "ssl_locl.h" -// #include "buffer.h" -// #include "rand.h" -// #include "objects.h" -// #include "evp.h" -// #include "x509.h" -// #include "md5.h" -// #include "bn.h" -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -static const SSL_METHOD *dtls1_get_server_method(int ver); -static int dtls1_send_hello_verify_request(SSL *s); - -static const SSL_METHOD *dtls1_get_server_method(int ver) -{ - if (ver == DTLS_ANY_VERSION) - return DTLS_server_method(); - else if (ver == DTLS1_VERSION) - return DTLSv1_server_method(); - else if (ver == DTLS1_2_VERSION) - return DTLSv1_2_server_method(); - else - return NULL; -} - -IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, - DTLSv1_server_method, - dtls1_accept, - ssl_undefined_function, - dtls1_get_server_method, DTLSv1_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, - DTLSv1_2_server_method, - dtls1_accept, - ssl_undefined_function, - dtls1_get_server_method, DTLSv1_2_enc_data) - -IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, - DTLS_server_method, - dtls1_accept, - ssl_undefined_function, - dtls1_get_server_method, DTLSv1_2_enc_data) - -int dtls1_accept(SSL *s) -{ - BUF_MEM *buf; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - unsigned long alg_k; - int ret = -1; - int new_state, state, skip = 0; - int listen; -#ifndef OPENSSL_NO_SCTP - unsigned char sctpauthkey[64]; - char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; -#endif - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - listen = s->d1->listen; - - /* init things to blank */ - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - s->d1->listen = listen; -#ifndef OPENSSL_NO_SCTP - /* - * Notify SCTP BIO socket to enter handshake mode and prevent stream - * identifier other than 0. Will be ignored if no SCTP is used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, - s->in_handshake, NULL); -#endif - - if (s->cert == NULL) { - SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_NO_CERTIFICATE_SET); - return (-1); - } -#ifndef OPENSSL_NO_HEARTBEATS - /* - * If we're awaiting a HeartbeatResponse, pretend we already got and - * don't await it anymore, because Heartbeats don't make sense during - * handshakes anyway. - */ - if (s->tlsext_hb_pending) { - dtls1_stop_timer(s); - s->tlsext_hb_pending = 0; - s->tlsext_hb_seq++; - } -#endif - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_RENEGOTIATE: - s->renegotiate = 1; - /* s->state=SSL_ST_ACCEPT; */ - - case SSL_ST_BEFORE: - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - case SSL_ST_OK | SSL_ST_ACCEPT: - - s->server = 1; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { - SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); - return -1; - } - s->type = SSL_ST_ACCEPT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - BUF_MEM_free(buf); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - s->init_buf = buf; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->init_num = 0; - s->d1->change_cipher_spec_ok = 0; - /* - * Should have been reset by ssl3_get_finished, too. - */ - s->s3->change_cipher_spec = 0; - - if (s->state != SSL_ST_RENEGOTIATE) { - /* - * Ok, we now need to push on a buffering BIO so that the - * output is sent in a way that TCP likes :-) ...but not with - * SCTP :-) - */ -#ifndef OPENSSL_NO_SCTP - if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) -#endif - if (!ssl_init_wbio_buffer(s, 1)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->state = SSL3_ST_SR_CLNT_HELLO_A; - s->ctx->stats.sess_accept++; - } else if (!s->s3->send_connection_binding && - !(s->options & - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - /* - * Server attempting to renegotiate with client that doesn't - * support secure renegotiation. - */ - SSLerr(SSL_F_DTLS1_ACCEPT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } else { - /* - * s->state == SSL_ST_RENEGOTIATE, we will just send a - * HelloRequest - */ - s->ctx->stats.sess_accept_renegotiate++; - s->state = SSL3_ST_SW_HELLO_REQ_A; - } - - break; - - case SSL3_ST_SW_HELLO_REQ_A: - case SSL3_ST_SW_HELLO_REQ_B: - - s->shutdown = 0; - dtls1_clear_sent_buffer(s); - dtls1_start_timer(s); - ret = ssl3_send_hello_request(s); - if (ret <= 0) - goto end; - s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - - case SSL3_ST_SW_HELLO_REQ_C: - s->state = SSL_ST_OK; - break; - - case SSL3_ST_SR_CLNT_HELLO_A: - case SSL3_ST_SR_CLNT_HELLO_B: - case SSL3_ST_SR_CLNT_HELLO_C: - - s->shutdown = 0; - ret = ssl3_get_client_hello(s); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - - if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) - s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; - else - s->state = SSL3_ST_SW_SRVR_HELLO_A; - - s->init_num = 0; - - /* If we're just listening, stop here */ - if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { - ret = 2; - s->d1->listen = 0; - /* - * Set expected sequence numbers to continue the handshake. - */ - s->d1->handshake_read_seq = 2; - s->d1->handshake_write_seq = 1; - s->d1->next_handshake_write_seq = 1; - goto end; - } - - break; - - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: - - ret = dtls1_send_hello_verify_request(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; - - /* HelloVerifyRequest resets Finished MAC */ - if (s->version != DTLS1_BAD_VER) - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - -#ifndef OPENSSL_NO_SCTP - case DTLS1_SCTP_ST_SR_READ_SOCK: - - if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ret = -1; - goto end; - } - - s->state = SSL3_ST_SR_FINISHED_A; - break; - - case DTLS1_SCTP_ST_SW_WRITE_SOCK: - ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); - if (ret < 0) - goto end; - - if (ret == 0) { - if (s->d1->next_state != SSL_ST_OK) { - s->s3->in_read_app_data = 2; - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - ret = -1; - goto end; - } - } - - s->state = s->d1->next_state; - break; -#endif - - case SSL3_ST_SW_SRVR_HELLO_A: - case SSL3_ST_SW_SRVR_HELLO_B: - s->renegotiate = 2; - dtls1_start_timer(s); - ret = ssl3_send_server_hello(s); - if (ret <= 0) - goto end; - - if (s->hit) { -#ifndef OPENSSL_NO_SCTP - /* - * Add new shared key for SCTP-Auth, will be ignored if no - * SCTP used. - */ - snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); - - if (SSL_export_keying_material(s, sctpauthkey, - sizeof(sctpauthkey), labelbuffer, - sizeof(labelbuffer), NULL, 0, 0) <= 0) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, - sizeof(sctpauthkey), sctpauthkey); -#endif -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_ticket_expected) - s->state = SSL3_ST_SW_SESSION_TICKET_A; - else - s->state = SSL3_ST_SW_CHANGE_A; -#else - s->state = SSL3_ST_SW_CHANGE_A; -#endif - } else - s->state = SSL3_ST_SW_CERT_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_A: - case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH or normal PSK */ - if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - dtls1_start_timer(s); - ret = ssl3_send_server_certificate(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_status_expected) - s->state = SSL3_ST_SW_CERT_STATUS_A; - else - s->state = SSL3_ST_SW_KEY_EXCH_A; - } else { - skip = 1; - s->state = SSL3_ST_SW_KEY_EXCH_A; - } -#else - } else - skip = 1; - - s->state = SSL3_ST_SW_KEY_EXCH_A; -#endif - s->init_num = 0; - break; - - case SSL3_ST_SW_KEY_EXCH_A: - case SSL3_ST_SW_KEY_EXCH_B: - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - - /* - * clear this, it may get reset by - * send_server_key_exchange - */ - s->s3->tmp.use_rsa_tmp = 0; - - /* - * only send if a DH key exchange or RSA but we have a sign only - * certificate - */ - if (0 - /* - * PSK: send ServerKeyExchange if PSK identity hint if - * provided - */ -#ifndef OPENSSL_NO_PSK - || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) -#endif - || (alg_k & SSL_kDHE) - || (alg_k & SSL_kEECDH) - || ((alg_k & SSL_kRSA) - && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL - || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) - && EVP_PKEY_size(s->cert->pkeys - [SSL_PKEY_RSA_ENC].privatekey) * - 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) - ) - ) - ) - ) { - dtls1_start_timer(s); - ret = ssl3_send_server_key_exchange(s); - if (ret <= 0) - goto end; - } else - skip = 1; - - s->state = SSL3_ST_SW_CERT_REQ_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_REQ_A: - case SSL3_ST_SW_CERT_REQ_B: - if ( /* don't request cert unless asked for it: */ - !(s->verify_mode & SSL_VERIFY_PEER) || - /* - * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert - * during re-negotiation: - */ - ((s->session->peer != NULL) && - (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || - /* - * never request cert in anonymous ciphersuites (see - * section "Certificate request" in SSL 3 drafts and in - * RFC 2246): - */ - ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - /* - * ... except when the application insists on - * verification (against the specs, but s3_clnt.c accepts - * this for SSL 3) - */ - !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - /* - * never request cert in Kerberos ciphersuites - */ - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) - /* - * With normal PSK Certificates and Certificate Requests - * are omitted - */ - || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - /* no cert request */ - skip = 1; - s->s3->tmp.cert_request = 0; - s->state = SSL3_ST_SW_SRVR_DONE_A; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; - s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; - } -#endif - } else { - s->s3->tmp.cert_request = 1; - dtls1_start_timer(s); - ret = ssl3_send_certificate_request(s); - if (ret <= 0) - goto end; -#ifndef NETSCAPE_HANG_BUG - s->state = SSL3_ST_SW_SRVR_DONE_A; -# ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; - s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; - } -# endif -#else - s->state = SSL3_ST_SW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; -# ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = s->s3->tmp.next_state; - s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK; - } -# endif -#endif - s->init_num = 0; - } - break; - - case SSL3_ST_SW_SRVR_DONE_A: - case SSL3_ST_SW_SRVR_DONE_B: - dtls1_start_timer(s); - ret = ssl3_send_server_done(s); - if (ret <= 0) - goto end; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - break; - - case SSL3_ST_SW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - /* - * If the write error was fatal, stop trying - */ - if (!BIO_should_retry(s->wbio)) { - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - } - - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - break; - - case SSL3_ST_SR_CERT_A: - case SSL3_ST_SR_CERT_B: - if (s->s3->tmp.cert_request) { - ret = ssl3_get_client_certificate(s); - if (ret <= 0) - goto end; - } - s->init_num = 0; - s->state = SSL3_ST_SR_KEY_EXCH_A; - break; - - case SSL3_ST_SR_KEY_EXCH_A: - case SSL3_ST_SR_KEY_EXCH_B: - ret = ssl3_get_client_key_exchange(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SCTP - /* - * Add new shared key for SCTP-Auth, will be ignored if no SCTP - * used. - */ - snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), - DTLS1_SCTP_AUTH_LABEL); - - if (SSL_export_keying_material(s, sctpauthkey, - sizeof(sctpauthkey), labelbuffer, - sizeof(labelbuffer), NULL, 0, 0) <= 0) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, - sizeof(sctpauthkey), sctpauthkey); -#endif - - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - - if (ret == 2) { - /* - * For the ECDH ciphersuites when the client sends its ECDH - * pub key in a certificate, the CertificateVerify message is - * not sent. - */ - s->state = SSL3_ST_SR_FINISHED_A; - s->init_num = 0; - } else if (SSL_USE_SIGALGS(s)) { - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - if (!s->session->peer) - break; - /* - * For sigalgs freeze the handshake buffer at this point and - * digest cached records. - */ - if (!s->s3->handshake_buffer) { - SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } - s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; - if (!ssl3_digest_cached_records(s)) { - s->state = SSL_ST_ERR; - return -1; - } - } else { - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - - /* - * We need to get hashes here so if there is a client cert, - * it can be verified - */ - s->method->ssl3_enc->cert_verify_mac(s, - NID_md5, - &(s->s3-> - tmp.cert_verify_md - [0])); - s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, - &(s->s3-> - tmp.cert_verify_md - [MD5_DIGEST_LENGTH])); - } - break; - - case SSL3_ST_SR_CERT_VRFY_A: - case SSL3_ST_SR_CERT_VRFY_B: - ret = ssl3_get_cert_verify(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && - state == SSL_ST_RENEGOTIATE) - s->state = DTLS1_SCTP_ST_SR_READ_SOCK; - else -#endif - s->state = SSL3_ST_SR_FINISHED_A; - s->init_num = 0; - break; - - case SSL3_ST_SR_FINISHED_A: - case SSL3_ST_SR_FINISHED_B: - /* - * Enable CCS. Receiving a CCS clears the flag, so make - * sure not to re-enable it to ban duplicates. This *should* be the - * first time we have received one - but we check anyway to be - * cautious. - * s->s3->change_cipher_spec is set when a CCS is - * processed in d1_pkt.c, and remains set until - * the client's Finished message is read. - */ - if (!s->s3->change_cipher_spec) - s->d1->change_cipher_spec_ok = 1; - ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, - SSL3_ST_SR_FINISHED_B); - if (ret <= 0) - goto end; - dtls1_stop_timer(s); - if (s->hit) - s->state = SSL_ST_OK; -#ifndef OPENSSL_NO_TLSEXT - else if (s->tlsext_ticket_expected) - s->state = SSL3_ST_SW_SESSION_TICKET_A; -#endif - else - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_SW_SESSION_TICKET_A: - case SSL3_ST_SW_SESSION_TICKET_B: - ret = ssl3_send_newsession_ticket(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_STATUS_A: - case SSL3_ST_SW_CERT_STATUS_B: - ret = ssl3_send_cert_status(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_KEY_EXCH_A; - s->init_num = 0; - break; - -#endif - - case SSL3_ST_SW_CHANGE_A: - case SSL3_ST_SW_CHANGE_B: - - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->method->ssl3_enc->setup_key_block(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - ret = dtls1_send_change_cipher_spec(s, - SSL3_ST_SW_CHANGE_A, - SSL3_ST_SW_CHANGE_B); - - if (ret <= 0) - goto end; - -#ifndef OPENSSL_NO_SCTP - if (!s->hit) { - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); - } -#endif - - s->state = SSL3_ST_SW_FINISHED_A; - s->init_num = 0; - - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_SERVER_WRITE)) - { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); - break; - - case SSL3_ST_SW_FINISHED_A: - case SSL3_ST_SW_FINISHED_B: - ret = ssl3_send_finished(s, - SSL3_ST_SW_FINISHED_A, - SSL3_ST_SW_FINISHED_B, - s->method-> - ssl3_enc->server_finished_label, - s->method-> - ssl3_enc->server_finished_label_len); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_FLUSH; - if (s->hit) { - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; - -#ifndef OPENSSL_NO_SCTP - /* - * Change to new shared key of SCTP-Auth, will be ignored if - * no SCTP used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, - 0, NULL); -#endif - } else { - s->s3->tmp.next_state = SSL_ST_OK; -#ifndef OPENSSL_NO_SCTP - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - s->d1->next_state = s->s3->tmp.next_state; - s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK; - } -#endif - } - s->init_num = 0; - break; - - case SSL_ST_OK: - /* clean a few things up */ - ssl3_cleanup_key_block(s); - -#if 0 - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; -#endif - - /* remove buffering on output */ - ssl_free_wbio_buffer(s); - - s->init_num = 0; - - if (s->renegotiate == 2) { /* skipped if we just sent a - * HelloRequest */ - s->renegotiate = 0; - s->new_session = 0; - - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); - - s->ctx->stats.sess_accept_good++; - /* s->server=1; */ - s->handshake_func = dtls1_accept; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - } - - ret = 1; - - /* done handshaking, next message is client hello */ - s->d1->handshake_read_seq = 0; - /* next message is server hello */ - s->d1->handshake_write_seq = 0; - s->d1->next_handshake_write_seq = 0; - dtls1_clear_received_buffer(s); - goto end; - /* break; */ - - case SSL_ST_ERR: - default: - SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; - } - } - skip = 0; - } - end: - /* BIO_flush(s->wbio); */ - - s->in_handshake--; -#ifndef OPENSSL_NO_SCTP - /* - * Notify SCTP BIO socket to leave handshake mode and prevent stream - * identifier other than 0. Will be ignored if no SCTP is used. - */ - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, - s->in_handshake, NULL); -#endif - - if (cb != NULL) - cb(s, SSL_CB_ACCEPT_EXIT, ret); - return (ret); -} - -int dtls1_send_hello_verify_request(SSL *s) -{ - unsigned int msg_len; - unsigned char *msg, *buf, *p; - - if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) { - buf = (unsigned char *)s->init_buf->data; - - msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); - /* Always use DTLS 1.0 version: see RFC 6347 */ - *(p++) = DTLS1_VERSION >> 8; - *(p++) = DTLS1_VERSION & 0xFF; - - if (s->ctx->app_gen_cookie_cb == NULL || - s->ctx->app_gen_cookie_cb(s, s->d1->cookie, - &(s->d1->cookie_len)) == 0) { - SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST, - ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return 0; - } - - *(p++) = (unsigned char)s->d1->cookie_len; - memcpy(p, s->d1->cookie, s->d1->cookie_len); - p += s->d1->cookie_len; - msg_len = p - msg; - - dtls1_set_message_header(s, buf, - DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, - msg_len); - - s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B; - /* number of bytes to write */ - s->init_num = p - buf; - s->init_off = 0; - } - - /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ - return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); -} diff --git a/Sources/COpenSSL/d1_lib.c b/Sources/COpenSSL/d1_lib.c deleted file mode 100644 index cb2656ac..00000000 --- a/Sources/COpenSSL/d1_lib.c +++ /dev/null @@ -1,589 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ssl/d1_lib.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#define USE_SOCKETS -#include "objects.h" -#include "ssl_locl.h" - -#if defined(OPENSSL_SYS_VMS) -# include -#endif - -static void get_current_time(struct timeval *t); -static void dtls1_set_handshake_header(SSL *s, int type, unsigned long len); -static int dtls1_handshake_write(SSL *s); -const char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT; -int dtls1_listen(SSL *s, struct sockaddr *client); - -SSL3_ENC_METHOD DTLSv1_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV, - DTLS1_HM_HEADER_LENGTH, - dtls1_set_handshake_header, - dtls1_handshake_write -}; - -SSL3_ENC_METHOD DTLSv1_2_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS - | SSL_ENC_FLAG_SHA256_PRF | SSL_ENC_FLAG_TLS1_2_CIPHERS, - DTLS1_HM_HEADER_LENGTH, - dtls1_set_handshake_header, - dtls1_handshake_write -}; - -long dtls1_default_timeout(void) -{ - /* - * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for - * http, the cache would over fill - */ - return (60 * 60 * 2); -} - -int dtls1_new(SSL *s) -{ - DTLS1_STATE *d1; - - if (!ssl3_new(s)) - return (0); - if ((d1 = OPENSSL_malloc(sizeof(*d1))) == NULL) - return (0); - memset(d1, 0, sizeof(*d1)); - - /* d1->handshake_epoch=0; */ - - d1->unprocessed_rcds.q = pqueue_new(); - d1->processed_rcds.q = pqueue_new(); - d1->buffered_messages = pqueue_new(); - d1->sent_messages = pqueue_new(); - d1->buffered_app_data.q = pqueue_new(); - - if (s->server) { - d1->cookie_len = sizeof(s->d1->cookie); - } - - d1->link_mtu = 0; - d1->mtu = 0; - - if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q - || !d1->buffered_messages || !d1->sent_messages - || !d1->buffered_app_data.q) { - if (d1->unprocessed_rcds.q) - pqueue_free(d1->unprocessed_rcds.q); - if (d1->processed_rcds.q) - pqueue_free(d1->processed_rcds.q); - if (d1->buffered_messages) - pqueue_free(d1->buffered_messages); - if (d1->sent_messages) - pqueue_free(d1->sent_messages); - if (d1->buffered_app_data.q) - pqueue_free(d1->buffered_app_data.q); - OPENSSL_free(d1); - return (0); - } - - s->d1 = d1; - s->method->ssl_clear(s); - return (1); -} - -static void dtls1_clear_queues(SSL *s) -{ - pitem *item = NULL; - DTLS1_RECORD_DATA *rdata; - - while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } - OPENSSL_free(item->data); - pitem_free(item); - } - - while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } - OPENSSL_free(item->data); - pitem_free(item); - } - - while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } - OPENSSL_free(item->data); - pitem_free(item); - } - - dtls1_clear_received_buffer(s); - dtls1_clear_sent_buffer(s); -} - -void dtls1_clear_received_buffer(SSL *s) -{ - pitem *item = NULL; - hm_fragment *frag = NULL; - - while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { - frag = (hm_fragment *)item->data; - dtls1_hm_fragment_free(frag); - pitem_free(item); - } -} - -void dtls1_clear_sent_buffer(SSL *s) -{ - pitem *item = NULL; - hm_fragment *frag = NULL; - - while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { - frag = (hm_fragment *)item->data; - dtls1_hm_fragment_free(frag); - pitem_free(item); - } -} - - -void dtls1_free(SSL *s) -{ - ssl3_free(s); - - dtls1_clear_queues(s); - - pqueue_free(s->d1->unprocessed_rcds.q); - pqueue_free(s->d1->processed_rcds.q); - pqueue_free(s->d1->buffered_messages); - pqueue_free(s->d1->sent_messages); - pqueue_free(s->d1->buffered_app_data.q); - - OPENSSL_free(s->d1); - s->d1 = NULL; -} - -void dtls1_clear(SSL *s) -{ - pqueue unprocessed_rcds; - pqueue processed_rcds; - pqueue buffered_messages; - pqueue sent_messages; - pqueue buffered_app_data; - unsigned int mtu; - unsigned int link_mtu; - - if (s->d1) { - unprocessed_rcds = s->d1->unprocessed_rcds.q; - processed_rcds = s->d1->processed_rcds.q; - buffered_messages = s->d1->buffered_messages; - sent_messages = s->d1->sent_messages; - buffered_app_data = s->d1->buffered_app_data.q; - mtu = s->d1->mtu; - link_mtu = s->d1->link_mtu; - - dtls1_clear_queues(s); - - memset(s->d1, 0, sizeof(*(s->d1))); - - if (s->server) { - s->d1->cookie_len = sizeof(s->d1->cookie); - } - - if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { - s->d1->mtu = mtu; - s->d1->link_mtu = link_mtu; - } - - s->d1->unprocessed_rcds.q = unprocessed_rcds; - s->d1->processed_rcds.q = processed_rcds; - s->d1->buffered_messages = buffered_messages; - s->d1->sent_messages = sent_messages; - s->d1->buffered_app_data.q = buffered_app_data; - } - - ssl3_clear(s); - if (s->options & SSL_OP_CISCO_ANYCONNECT) - s->client_version = s->version = DTLS1_BAD_VER; - else if (s->method->version == DTLS_ANY_VERSION) - s->version = DTLS1_2_VERSION; - else - s->version = s->method->version; -} - -long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) -{ - int ret = 0; - - switch (cmd) { - case DTLS_CTRL_GET_TIMEOUT: - if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) { - ret = 1; - } - break; - case DTLS_CTRL_HANDLE_TIMEOUT: - ret = dtls1_handle_timeout(s); - break; - case DTLS_CTRL_LISTEN: - ret = dtls1_listen(s, parg); - break; - case SSL_CTRL_CHECK_PROTO_VERSION: - /* - * For library-internal use; checks that the current protocol is the - * highest enabled version (according to s->ctx->method, as version - * negotiation may have changed s->method). - */ - if (s->version == s->ctx->method->version) - return 1; - /* - * Apparently we're using a version-flexible SSL_METHOD (not at its - * highest protocol version). - */ - if (s->ctx->method->version == DTLS_method()->version) { -#if DTLS_MAX_VERSION != DTLS1_2_VERSION -# error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. -#endif - if (!(s->options & SSL_OP_NO_DTLSv1_2)) - return s->version == DTLS1_2_VERSION; - if (!(s->options & SSL_OP_NO_DTLSv1)) - return s->version == DTLS1_VERSION; - } - return 0; /* Unexpected state; fail closed. */ - case DTLS_CTRL_SET_LINK_MTU: - if (larg < (long)dtls1_link_min_mtu()) - return 0; - s->d1->link_mtu = larg; - return 1; - case DTLS_CTRL_GET_LINK_MIN_MTU: - return (long)dtls1_link_min_mtu(); - case SSL_CTRL_SET_MTU: - /* - * We may not have a BIO set yet so can't call dtls1_min_mtu() - * We'll have to make do with dtls1_link_min_mtu() and max overhead - */ - if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD) - return 0; - s->d1->mtu = larg; - return larg; - default: - ret = ssl3_ctrl(s, cmd, larg, parg); - break; - } - return (ret); -} - -/* - * As it's impossible to use stream ciphers in "datagram" mode, this - * simple filter is designed to disengage them in DTLS. Unfortunately - * there is no universal way to identify stream SSL_CIPHER, so we have - * to explicitly list their SSL_* codes. Currently RC4 is the only one - * available, but if new ones emerge, they will have to be added... - */ -const SSL_CIPHER *dtls1_get_cipher(unsigned int u) -{ - const SSL_CIPHER *ciph = ssl3_get_cipher(u); - - if (ciph != NULL) { - if (ciph->algorithm_enc == SSL_RC4) - return NULL; - } - - return ciph; -} - -void dtls1_start_timer(SSL *s) -{ -#ifndef OPENSSL_NO_SCTP - /* Disable timer for SCTP */ - if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { - memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); - return; - } -#endif - - /* If timer is not set, initialize duration with 1 second */ - if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - s->d1->timeout_duration = 1; - } - - /* Set timeout to current time */ - get_current_time(&(s->d1->next_timeout)); - - /* Add duration to current time */ - s->d1->next_timeout.tv_sec += s->d1->timeout_duration; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, - &(s->d1->next_timeout)); -} - -struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft) -{ - struct timeval timenow; - - /* If no timeout is set, just return NULL */ - if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { - return NULL; - } - - /* Get current time */ - get_current_time(&timenow); - - /* If timer already expired, set remaining time to 0 */ - if (s->d1->next_timeout.tv_sec < timenow.tv_sec || - (s->d1->next_timeout.tv_sec == timenow.tv_sec && - s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { - memset(timeleft, 0, sizeof(struct timeval)); - return timeleft; - } - - /* Calculate time left until timer expires */ - memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); - timeleft->tv_sec -= timenow.tv_sec; - timeleft->tv_usec -= timenow.tv_usec; - if (timeleft->tv_usec < 0) { - timeleft->tv_sec--; - timeleft->tv_usec += 1000000; - } - - /* - * If remaining time is less than 15 ms, set it to 0 to prevent issues - * because of small devergences with socket timeouts. - */ - if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { - memset(timeleft, 0, sizeof(struct timeval)); - } - - return timeleft; -} - -int dtls1_is_timer_expired(SSL *s) -{ - struct timeval timeleft; - - /* Get time left until timeout, return false if no timer running */ - if (dtls1_get_timeout(s, &timeleft) == NULL) { - return 0; - } - - /* Return false if timer is not expired yet */ - if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { - return 0; - } - - /* Timer expired, so return true */ - return 1; -} - -void dtls1_double_timeout(SSL *s) -{ - s->d1->timeout_duration *= 2; - if (s->d1->timeout_duration > 60) - s->d1->timeout_duration = 60; - dtls1_start_timer(s); -} - -void dtls1_stop_timer(SSL *s) -{ - /* Reset everything */ - memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); - memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); - s->d1->timeout_duration = 1; - BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, - &(s->d1->next_timeout)); - /* Clear retransmission buffer */ - dtls1_clear_sent_buffer(s); -} - -int dtls1_check_timeout_num(SSL *s) -{ - unsigned int mtu; - - s->d1->timeout.num_alerts++; - - /* Reduce MTU after 2 unsuccessful retransmissions */ - if (s->d1->timeout.num_alerts > 2 - && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { - mtu = - BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, - NULL); - if (mtu < s->d1->mtu) - s->d1->mtu = mtu; - } - - if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { - /* fail the connection, enough alerts have been sent */ - SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED); - return -1; - } - - return 0; -} - -int dtls1_handle_timeout(SSL *s) -{ - /* if no timer is expired, don't do anything */ - if (!dtls1_is_timer_expired(s)) { - return 0; - } - - dtls1_double_timeout(s); - - if (dtls1_check_timeout_num(s) < 0) - return -1; - - s->d1->timeout.read_timeouts++; - if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { - s->d1->timeout.read_timeouts = 1; - } -#ifndef OPENSSL_NO_HEARTBEATS - if (s->tlsext_hb_pending) { - s->tlsext_hb_pending = 0; - return dtls1_heartbeat(s); - } -#endif - - dtls1_start_timer(s); - return dtls1_retransmit_buffered_messages(s); -} - -static void get_current_time(struct timeval *t) -{ -#if defined(_WIN32) - SYSTEMTIME st; - union { - unsigned __int64 ul; - FILETIME ft; - } now; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &now.ft); -# ifdef __MINGW32__ - now.ul -= 116444736000000000ULL; -# else - now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ -# endif - t->tv_sec = (long)(now.ul / 10000000); - t->tv_usec = ((int)(now.ul % 10000000)) / 10; -#elif defined(OPENSSL_SYS_VMS) - struct timeb tb; - ftime(&tb); - t->tv_sec = (long)tb.time; - t->tv_usec = (long)tb.millitm * 1000; -#else - gettimeofday(t, NULL); -#endif -} - -int dtls1_listen(SSL *s, struct sockaddr *client) -{ - int ret; - - /* Ensure there is no state left over from a previous invocation */ - SSL_clear(s); - - SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); - s->d1->listen = 1; - - ret = SSL_accept(s); - if (ret <= 0) - return ret; - - (void)BIO_dgram_get_peer(SSL_get_rbio(s), client); - return 1; -} - -static void dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) -{ - unsigned char *p = (unsigned char *)s->init_buf->data; - dtls1_set_message_header(s, p, htype, len, 0, len); - s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH; - s->init_off = 0; - /* Buffer the message to handle re-xmits */ - dtls1_buffer_message(s, 0); -} - -static int dtls1_handshake_write(SSL *s) -{ - return dtls1_do_write(s, SSL3_RT_HANDSHAKE); -} diff --git a/Sources/COpenSSL/d2i_.c b/Sources/COpenSSL/d2i_.c deleted file mode 100644 index 63aaafbe..00000000 --- a/Sources/COpenSSL/d2i_.c +++ /dev/null @@ -1,314 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/asn1/d2i_pr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "bn.h" -#include "evp.h" -#include "objects.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -#include "x509.h" -#include "asn1.h" -#include "asn1_locl.h" - -EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, - long length) -{ - EVP_PKEY *ret; - const unsigned char *p = *pp; - - if ((a == NULL) || (*a == NULL)) { - if ((ret = EVP_PKEY_new()) == NULL) { - ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB); - return (NULL); - } - } else { - ret = *a; -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) { - ENGINE_finish(ret->engine); - ret->engine = NULL; - } -#endif - } - - if (!EVP_PKEY_set_type(ret, type)) { - ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); - goto err; - } - - if (!ret->ameth->old_priv_decode || - !ret->ameth->old_priv_decode(ret, &p, length)) { - if (ret->ameth->priv_decode) { - EVP_PKEY *tmp; - PKCS8_PRIV_KEY_INFO *p8 = NULL; - p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); - if (!p8) - goto err; - tmp = EVP_PKCS82PKEY(p8); - PKCS8_PRIV_KEY_INFO_free(p8); - if (tmp == NULL) - goto err; - EVP_PKEY_free(ret); - ret = tmp; - } else { - ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); - goto err; - } - } - *pp = p; - if (a != NULL) - (*a) = ret; - return (ret); - err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - EVP_PKEY_free(ret); - return (NULL); -} - -/* - * This works like d2i_PrivateKey() except it automatically works out the - * type - */ - -EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, - long length) -{ - STACK_OF(ASN1_TYPE) *inkey; - const unsigned char *p; - int keytype; - p = *pp; - /* - * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by - * analyzing it we can determine the passed structure: this assumes the - * input is surrounded by an ASN1 SEQUENCE. - */ - inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); - p = *pp; - /* - * Since we only need to discern "traditional format" RSA and DSA keys we - * can just count the elements. - */ - if (sk_ASN1_TYPE_num(inkey) == 6) - keytype = EVP_PKEY_DSA; - else if (sk_ASN1_TYPE_num(inkey) == 4) - keytype = EVP_PKEY_EC; - else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not - * traditional format */ - PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); - EVP_PKEY *ret; - - sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); - if (!p8) { - ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, - ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return NULL; - } - ret = EVP_PKCS82PKEY(p8); - PKCS8_PRIV_KEY_INFO_free(p8); - if (ret == NULL) - return NULL; - *pp = p; - if (a) { - *a = ret; - } - return ret; - } else - keytype = EVP_PKEY_RSA; - sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); - return d2i_PrivateKey(keytype, a, pp, length); -} -/* crypto/asn1/d2i_pu.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "evp.h" -// #include "objects.h" -// #include "asn1.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_EC -# include "ec.h" -#endif - -EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, - long length) -{ - EVP_PKEY *ret; - - if ((a == NULL) || (*a == NULL)) { - if ((ret = EVP_PKEY_new()) == NULL) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); - return (NULL); - } - } else - ret = *a; - - if (!EVP_PKEY_set_type(ret, type)) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); - goto err; - } - - switch (EVP_PKEY_id(ret)) { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - /* TMP UGLY CAST */ - if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, - (const unsigned char **)pp, - length)) == NULL) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); - goto err; - } - break; -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - /* TMP UGLY CAST */ - if (!d2i_DSAPublicKey(&(ret->pkey.dsa), - (const unsigned char **)pp, length)) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); - goto err; - } - break; -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - if (!o2i_ECPublicKey(&(ret->pkey.ec), - (const unsigned char **)pp, length)) { - ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); - goto err; - } - break; -#endif - default: - ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); - goto err; - /* break; */ - } - if (a != NULL) - (*a) = ret; - return (ret); - err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) - EVP_PKEY_free(ret); - return (NULL); -} diff --git a/Sources/COpenSSL/des.h b/Sources/COpenSSL/des.h deleted file mode 100644 index 7e91d13c..00000000 --- a/Sources/COpenSSL/des.h +++ /dev/null @@ -1,257 +0,0 @@ -/* crypto/des/des.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_NEW_DES_H -# define HEADER_NEW_DES_H - -# include "e_os2.h" /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG - * (via openssl/opensslconf.h */ - -# ifdef OPENSSL_NO_DES -# error DES is disabled. -# endif - -# ifdef OPENSSL_BUILD_SHLIBCRYPTO -# undef OPENSSL_EXTERN -# define OPENSSL_EXTERN OPENSSL_EXPORT -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned char DES_cblock[8]; -typedef /* const */ unsigned char const_DES_cblock[8]; -/* - * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and - * const_DES_cblock * are incompatible pointer types. - */ - -typedef struct DES_ks { - union { - DES_cblock cblock; - /* - * make sure things are correct size on machines with 8 byte longs - */ - DES_LONG deslong[2]; - } ks[16]; -} DES_key_schedule; - -# ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT -# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT -# define OPENSSL_ENABLE_OLD_DES_SUPPORT -# endif -# endif - -# ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT -# include "des_old.h" -# endif - -# define DES_KEY_SZ (sizeof(DES_cblock)) -# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) - -# define DES_ENCRYPT 1 -# define DES_DECRYPT 0 - -# define DES_CBC_MODE 0 -# define DES_PCBC_MODE 1 - -# define DES_ecb2_encrypt(i,o,k1,k2,e) \ - DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) - -# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ - DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) - -# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ - DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) - -# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ - DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) - -OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */ -# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key) -OPENSSL_DECLARE_GLOBAL(int, DES_rw_mode); /* defaults to DES_PCBC_MODE */ -# define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode) - -const char *DES_options(void); -void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, - DES_key_schedule *ks1, DES_key_schedule *ks2, - DES_key_schedule *ks3, int enc); -DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, - long length, DES_key_schedule *schedule, - const_DES_cblock *ivec); -/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ -void DES_cbc_encrypt(const unsigned char *input, unsigned char *output, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int enc); -void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int enc); -void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, const_DES_cblock *inw, - const_DES_cblock *outw, int enc); -void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int enc); -void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, - DES_key_schedule *ks, int enc); - -/* - * This is the DES encryption function that gets called by just about every - * other DES routine in the library. You should not use this function except - * to implement 'modes' of DES. I say this because the functions that call - * this routine do the conversion from 'char *' to long, and this needs to be - * done to make sure 'non-aligned' memory access do not occur. The - * characters are loaded 'little endian'. Data is a pointer to 2 unsigned - * long's and ks is the DES_key_schedule to use. enc, is non zero specifies - * encryption, zero if decryption. - */ -void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc); - -/* - * This functions is the same as DES_encrypt1() except that the DES initial - * permutation (IP) and final permutation (FP) have been left out. As for - * DES_encrypt1(), you should not use this function. It is used by the - * routines in the library that implement triple DES. IP() DES_encrypt2() - * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1() - * DES_encrypt1() DES_encrypt1() except faster :-). - */ -void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc); - -void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3); -void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3); -void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, - long length, - DES_key_schedule *ks1, DES_key_schedule *ks2, - DES_key_schedule *ks3, DES_cblock *ivec, int enc); -void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, - long length, - DES_key_schedule *ks1, DES_key_schedule *ks2, - DES_key_schedule *ks3, - DES_cblock *ivec1, DES_cblock *ivec2, int enc); -void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *ivec, int *num, int enc); -void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, - int numbits, long length, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *ivec, int enc); -void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *ivec, int *num); -# if 0 -void DES_xwhite_in2out(const_DES_cblock *DES_key, const_DES_cblock *in_white, - DES_cblock *out_white); -# endif - -int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, - DES_cblock *iv); -int DES_enc_write(int fd, const void *buf, int len, DES_key_schedule *sched, - DES_cblock *iv); -char *DES_fcrypt(const char *buf, const char *salt, char *ret); -char *DES_crypt(const char *buf, const char *salt); -void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, - long length, DES_key_schedule *schedule, - DES_cblock *ivec); -void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int enc); -DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], - long length, int out_count, DES_cblock *seed); -int DES_random_key(DES_cblock *ret); -void DES_set_odd_parity(DES_cblock *key); -int DES_check_key_parity(const_DES_cblock *key); -int DES_is_weak_key(const_DES_cblock *key); -/* - * DES_set_key (= set_key = DES_key_sched = key_sched) calls - * DES_set_key_checked if global variable DES_check_key is set, - * DES_set_key_unchecked otherwise. - */ -int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); -int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); -int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); -void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); -# ifdef OPENSSL_FIPS -void private_DES_set_key_unchecked(const_DES_cblock *key, - DES_key_schedule *schedule); -# endif -void DES_string_to_key(const char *str, DES_cblock *key); -void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); -void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int *num, int enc); -void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int *num); - -int DES_read_password(DES_cblock *key, const char *prompt, int verify); -int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, - const char *prompt, int verify); - -# define DES_fixup_key_parity DES_set_odd_parity - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/des_enc.c b/Sources/COpenSSL/des_enc.c deleted file mode 100644 index 21bdcb30..00000000 --- a/Sources/COpenSSL/des_enc.c +++ /dev/null @@ -1,389 +0,0 @@ -/* crypto/des/des_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" -#include "spr.h" - -void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) -{ - register DES_LONG l, r, t, u; -#ifdef DES_PTR - register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; -#endif -#ifndef DES_UNROLL - register int i; -#endif - register DES_LONG *s; - - r = data[0]; - l = data[1]; - - IP(r, l); - /* - * Things have been modified so that the initial rotate is done outside - * the loop. This required the DES_SPtrans values in sp.h to be rotated - * 1 bit to the right. One perl script later and things have a 5% speed - * up on a sparc2. Thanks to Richard Outerbridge - * <71755.204@CompuServe.COM> for pointing this out. - */ - /* clear the top bits on machines with 8byte longs */ - /* shift left by 2 */ - r = ROTATE(r, 29) & 0xffffffffL; - l = ROTATE(l, 29) & 0xffffffffL; - - s = ks->ks->deslong; - /* - * I don't know if it is worth the effort of loop unrolling the inner - * loop - */ - if (enc) { -#ifdef DES_UNROLL - D_ENCRYPT(l, r, 0); /* 1 */ - D_ENCRYPT(r, l, 2); /* 2 */ - D_ENCRYPT(l, r, 4); /* 3 */ - D_ENCRYPT(r, l, 6); /* 4 */ - D_ENCRYPT(l, r, 8); /* 5 */ - D_ENCRYPT(r, l, 10); /* 6 */ - D_ENCRYPT(l, r, 12); /* 7 */ - D_ENCRYPT(r, l, 14); /* 8 */ - D_ENCRYPT(l, r, 16); /* 9 */ - D_ENCRYPT(r, l, 18); /* 10 */ - D_ENCRYPT(l, r, 20); /* 11 */ - D_ENCRYPT(r, l, 22); /* 12 */ - D_ENCRYPT(l, r, 24); /* 13 */ - D_ENCRYPT(r, l, 26); /* 14 */ - D_ENCRYPT(l, r, 28); /* 15 */ - D_ENCRYPT(r, l, 30); /* 16 */ -#else - for (i = 0; i < 32; i += 4) { - D_ENCRYPT(l, r, i + 0); /* 1 */ - D_ENCRYPT(r, l, i + 2); /* 2 */ - } -#endif - } else { -#ifdef DES_UNROLL - D_ENCRYPT(l, r, 30); /* 16 */ - D_ENCRYPT(r, l, 28); /* 15 */ - D_ENCRYPT(l, r, 26); /* 14 */ - D_ENCRYPT(r, l, 24); /* 13 */ - D_ENCRYPT(l, r, 22); /* 12 */ - D_ENCRYPT(r, l, 20); /* 11 */ - D_ENCRYPT(l, r, 18); /* 10 */ - D_ENCRYPT(r, l, 16); /* 9 */ - D_ENCRYPT(l, r, 14); /* 8 */ - D_ENCRYPT(r, l, 12); /* 7 */ - D_ENCRYPT(l, r, 10); /* 6 */ - D_ENCRYPT(r, l, 8); /* 5 */ - D_ENCRYPT(l, r, 6); /* 4 */ - D_ENCRYPT(r, l, 4); /* 3 */ - D_ENCRYPT(l, r, 2); /* 2 */ - D_ENCRYPT(r, l, 0); /* 1 */ -#else - for (i = 30; i > 0; i -= 4) { - D_ENCRYPT(l, r, i - 0); /* 16 */ - D_ENCRYPT(r, l, i - 2); /* 15 */ - } -#endif - } - - /* rotate and clear the top bits on machines with 8byte longs */ - l = ROTATE(l, 3) & 0xffffffffL; - r = ROTATE(r, 3) & 0xffffffffL; - - FP(r, l); - data[0] = l; - data[1] = r; - l = r = t = u = 0; -} - -void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc) -{ - register DES_LONG l, r, t, u; -#ifdef DES_PTR - register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; -#endif -#ifndef DES_UNROLL - register int i; -#endif - register DES_LONG *s; - - r = data[0]; - l = data[1]; - - /* - * Things have been modified so that the initial rotate is done outside - * the loop. This required the DES_SPtrans values in sp.h to be rotated - * 1 bit to the right. One perl script later and things have a 5% speed - * up on a sparc2. Thanks to Richard Outerbridge - * <71755.204@CompuServe.COM> for pointing this out. - */ - /* clear the top bits on machines with 8byte longs */ - r = ROTATE(r, 29) & 0xffffffffL; - l = ROTATE(l, 29) & 0xffffffffL; - - s = ks->ks->deslong; - /* - * I don't know if it is worth the effort of loop unrolling the inner - * loop - */ - if (enc) { -#ifdef DES_UNROLL - D_ENCRYPT(l, r, 0); /* 1 */ - D_ENCRYPT(r, l, 2); /* 2 */ - D_ENCRYPT(l, r, 4); /* 3 */ - D_ENCRYPT(r, l, 6); /* 4 */ - D_ENCRYPT(l, r, 8); /* 5 */ - D_ENCRYPT(r, l, 10); /* 6 */ - D_ENCRYPT(l, r, 12); /* 7 */ - D_ENCRYPT(r, l, 14); /* 8 */ - D_ENCRYPT(l, r, 16); /* 9 */ - D_ENCRYPT(r, l, 18); /* 10 */ - D_ENCRYPT(l, r, 20); /* 11 */ - D_ENCRYPT(r, l, 22); /* 12 */ - D_ENCRYPT(l, r, 24); /* 13 */ - D_ENCRYPT(r, l, 26); /* 14 */ - D_ENCRYPT(l, r, 28); /* 15 */ - D_ENCRYPT(r, l, 30); /* 16 */ -#else - for (i = 0; i < 32; i += 4) { - D_ENCRYPT(l, r, i + 0); /* 1 */ - D_ENCRYPT(r, l, i + 2); /* 2 */ - } -#endif - } else { -#ifdef DES_UNROLL - D_ENCRYPT(l, r, 30); /* 16 */ - D_ENCRYPT(r, l, 28); /* 15 */ - D_ENCRYPT(l, r, 26); /* 14 */ - D_ENCRYPT(r, l, 24); /* 13 */ - D_ENCRYPT(l, r, 22); /* 12 */ - D_ENCRYPT(r, l, 20); /* 11 */ - D_ENCRYPT(l, r, 18); /* 10 */ - D_ENCRYPT(r, l, 16); /* 9 */ - D_ENCRYPT(l, r, 14); /* 8 */ - D_ENCRYPT(r, l, 12); /* 7 */ - D_ENCRYPT(l, r, 10); /* 6 */ - D_ENCRYPT(r, l, 8); /* 5 */ - D_ENCRYPT(l, r, 6); /* 4 */ - D_ENCRYPT(r, l, 4); /* 3 */ - D_ENCRYPT(l, r, 2); /* 2 */ - D_ENCRYPT(r, l, 0); /* 1 */ -#else - for (i = 30; i > 0; i -= 4) { - D_ENCRYPT(l, r, i - 0); /* 16 */ - D_ENCRYPT(r, l, i - 2); /* 15 */ - } -#endif - } - /* rotate and clear the top bits on machines with 8byte longs */ - data[0] = ROTATE(l, 3) & 0xffffffffL; - data[1] = ROTATE(r, 3) & 0xffffffffL; - l = r = t = u = 0; -} - -void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3) -{ - register DES_LONG l, r; - - l = data[0]; - r = data[1]; - IP(l, r); - data[0] = l; - data[1] = r; - DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT); - DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT); - DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT); - l = data[0]; - r = data[1]; - FP(r, l); - data[0] = l; - data[1] = r; -} - -void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3) -{ - register DES_LONG l, r; - - l = data[0]; - r = data[1]; - IP(l, r); - data[0] = l; - data[1] = r; - DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT); - DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT); - DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT); - l = data[0]; - r = data[1]; - FP(r, l); - data[0] = l; - data[1] = r; -} - -#ifndef DES_DEFAULT_OPTIONS - -# undef CBC_ENC_C__DONT_UPDATE_IV -# include "ncbc_enc.h" /* DES_ncbc_encrypt */ - -void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, - long length, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *ivec, int enc) -{ - register DES_LONG tin0, tin1; - register DES_LONG tout0, tout1, xor0, xor1; - register const unsigned char *in; - unsigned char *out; - register long l = length; - DES_LONG tin[2]; - unsigned char *iv; - - in = input; - out = output; - iv = &(*ivec)[0]; - - if (enc) { - c2l(iv, tout0); - c2l(iv, tout1); - for (l -= 8; l >= 0; l -= 8) { - c2l(in, tin0); - c2l(in, tin1); - tin0 ^= tout0; - tin1 ^= tout1; - - tin[0] = tin0; - tin[1] = tin1; - DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); - tout0 = tin[0]; - tout1 = tin[1]; - - l2c(tout0, out); - l2c(tout1, out); - } - if (l != -8) { - c2ln(in, tin0, tin1, l + 8); - tin0 ^= tout0; - tin1 ^= tout1; - - tin[0] = tin0; - tin[1] = tin1; - DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); - tout0 = tin[0]; - tout1 = tin[1]; - - l2c(tout0, out); - l2c(tout1, out); - } - iv = &(*ivec)[0]; - l2c(tout0, iv); - l2c(tout1, iv); - } else { - register DES_LONG t0, t1; - - c2l(iv, xor0); - c2l(iv, xor1); - for (l -= 8; l >= 0; l -= 8) { - c2l(in, tin0); - c2l(in, tin1); - - t0 = tin0; - t1 = tin1; - - tin[0] = tin0; - tin[1] = tin1; - DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); - tout0 = tin[0]; - tout1 = tin[1]; - - tout0 ^= xor0; - tout1 ^= xor1; - l2c(tout0, out); - l2c(tout1, out); - xor0 = t0; - xor1 = t1; - } - if (l != -8) { - c2l(in, tin0); - c2l(in, tin1); - - t0 = tin0; - t1 = tin1; - - tin[0] = tin0; - tin[1] = tin1; - DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); - tout0 = tin[0]; - tout1 = tin[1]; - - tout0 ^= xor0; - tout1 ^= xor1; - l2cn(tout0, tout1, out, l + 8); - xor0 = t0; - xor1 = t1; - } - - iv = &(*ivec)[0]; - l2c(xor0, iv); - l2c(xor1, iv); - } - tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; - tin[0] = tin[1] = 0; -} - -#endif /* DES_DEFAULT_OPTIONS */ diff --git a/Sources/COpenSSL/des_locl.h b/Sources/COpenSSL/des_locl.h deleted file mode 100644 index ae7127f5..00000000 --- a/Sources/COpenSSL/des_locl.h +++ /dev/null @@ -1,443 +0,0 @@ -/* crypto/des/des_locl.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_DES_LOCL_H -# define HEADER_DES_LOCL_H - -# include "e_os2.h" - -# if defined(OPENSSL_SYS_WIN32) -# ifndef OPENSSL_SYS_MSDOS -# define OPENSSL_SYS_MSDOS -# endif -# endif - -# include -# include - -# ifndef OPENSSL_SYS_MSDOS -# if !defined(OPENSSL_SYS_VMS) || defined(__DECC) -# ifdef OPENSSL_UNISTD -# include OPENSSL_UNISTD -# else -# include -# endif -# include -# endif -# endif -# include "des.h" - -# ifdef OPENSSL_SYS_MSDOS /* Visual C++ 2.1 (Windows NT/95) */ -# include -# include -# include -# include -# endif - -# if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS) -# include -# endif - -# ifdef OPENSSL_BUILD_SHLIBCRYPTO -# undef OPENSSL_EXTERN -# define OPENSSL_EXTERN OPENSSL_EXPORT -# endif - -# define ITERATIONS 16 -# define HALF_ITERATIONS 8 - -/* used in des_read and des_write */ -# define MAXWRITE (1024*16) -# define BSIZE (MAXWRITE+4) - -# define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ - l|=((DES_LONG)(*((c)++)))<< 8L, \ - l|=((DES_LONG)(*((c)++)))<<16L, \ - l|=((DES_LONG)(*((c)++)))<<24L) - -/* NOTE - c is not incremented as per c2l */ -# define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ - case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ - case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ - case 5: l2|=((DES_LONG)(*(--(c)))); \ - case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ - case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ - case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ - case 1: l1|=((DES_LONG)(*(--(c)))); \ - } \ - } - -# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24L)&0xff)) - -/* - * replacements for htonl and ntohl since I have no idea what to do when - * faced with machines with 8 byte longs. - */ -# define HDRSIZE 4 - -# define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ - l|=((DES_LONG)(*((c)++)))<<16L, \ - l|=((DES_LONG)(*((c)++)))<< 8L, \ - l|=((DES_LONG)(*((c)++)))) - -# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -/* NOTE - c is not incremented as per l2c */ -# define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -# if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) -# define ROTATE(a,n) (_lrotr(a,n)) -# elif defined(__ICC) -# define ROTATE(a,n) (_rotr(a,n)) -# elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) -# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) -# define ROTATE(a,n) ({ register unsigned int ret; \ - asm ("rorl %1,%0" \ - : "=r"(ret) \ - : "I"(n),"0"(a) \ - : "cc"); \ - ret; \ - }) -# endif -# endif -# ifndef ROTATE -# define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) -# endif - -/* - * Don't worry about the LOAD_DATA() stuff, that is used by fcrypt() to add - * it's little bit to the front - */ - -# ifdef DES_FCRYPT - -# define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ - { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } - -# define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ - t=R^(R>>16L); \ - u=t&E0; t&=E1; \ - tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ - tmp=(t<<16); t^=R^s[S+1]; t^=tmp -# else -# define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) -# define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ - u=R^s[S ]; \ - t=R^s[S+1] -# endif - -/* - * The changes to this macro may help or hinder, depending on the compiler - * and the architecture. gcc2 always seems to do well :-). Inspired by Dana - * How DO NOT use the alternative version on machines - * with 8 byte longs. It does not seem to work on the Alpha, even when - * DES_LONG is 4 bytes, probably an issue of accessing non-word aligned - * objects :-( - */ -# ifdef DES_PTR - -/* - * It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there is no reason - * to not xor all the sub items together. This potentially saves a register - * since things can be xored directly into L - */ - -# if defined(DES_RISC1) || defined(DES_RISC2) -# ifdef DES_RISC1 -# define D_ENCRYPT(LL,R,S) { \ - unsigned int u1,u2,u3; \ - LOAD_DATA(R,S,u,t,E0,E1,u1); \ - u2=(int)u>>8L; \ - u1=(int)u&0xfc; \ - u2&=0xfc; \ - t=ROTATE(t,4); \ - u>>=16L; \ - LL^= *(const DES_LONG *)(des_SP +u1); \ - LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ - u3=(int)(u>>8L); \ - u1=(int)u&0xfc; \ - u3&=0xfc; \ - LL^= *(const DES_LONG *)(des_SP+0x400+u1); \ - LL^= *(const DES_LONG *)(des_SP+0x600+u3); \ - u2=(int)t>>8L; \ - u1=(int)t&0xfc; \ - u2&=0xfc; \ - t>>=16L; \ - LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ - LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ - u3=(int)t>>8L; \ - u1=(int)t&0xfc; \ - u3&=0xfc; \ - LL^= *(const DES_LONG *)(des_SP+0x500+u1); \ - LL^= *(const DES_LONG *)(des_SP+0x700+u3); } -# endif -# ifdef DES_RISC2 -# define D_ENCRYPT(LL,R,S) { \ - unsigned int u1,u2,s1,s2; \ - LOAD_DATA(R,S,u,t,E0,E1,u1); \ - u2=(int)u>>8L; \ - u1=(int)u&0xfc; \ - u2&=0xfc; \ - t=ROTATE(t,4); \ - LL^= *(const DES_LONG *)(des_SP +u1); \ - LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ - s1=(int)(u>>16L); \ - s2=(int)(u>>24L); \ - s1&=0xfc; \ - s2&=0xfc; \ - LL^= *(const DES_LONG *)(des_SP+0x400+s1); \ - LL^= *(const DES_LONG *)(des_SP+0x600+s2); \ - u2=(int)t>>8L; \ - u1=(int)t&0xfc; \ - u2&=0xfc; \ - LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ - LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ - s1=(int)(t>>16L); \ - s2=(int)(t>>24L); \ - s1&=0xfc; \ - s2&=0xfc; \ - LL^= *(const DES_LONG *)(des_SP+0x500+s1); \ - LL^= *(const DES_LONG *)(des_SP+0x700+s2); } -# endif -# else -# define D_ENCRYPT(LL,R,S) { \ - LOAD_DATA_tmp(R,S,u,t,E0,E1); \ - t=ROTATE(t,4); \ - LL^= \ - *(const DES_LONG *)(des_SP +((u )&0xfc))^ \ - *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \ - *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \ - *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \ - *(const DES_LONG *)(des_SP+0x100+((t )&0xfc))^ \ - *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \ - *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \ - *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); } -# endif - -# else /* original version */ - -# if defined(DES_RISC1) || defined(DES_RISC2) -# ifdef DES_RISC1 -# define D_ENCRYPT(LL,R,S) {\ - unsigned int u1,u2,u3; \ - LOAD_DATA(R,S,u,t,E0,E1,u1); \ - u>>=2L; \ - t=ROTATE(t,6); \ - u2=(int)u>>8L; \ - u1=(int)u&0x3f; \ - u2&=0x3f; \ - u>>=16L; \ - LL^=DES_SPtrans[0][u1]; \ - LL^=DES_SPtrans[2][u2]; \ - u3=(int)u>>8L; \ - u1=(int)u&0x3f; \ - u3&=0x3f; \ - LL^=DES_SPtrans[4][u1]; \ - LL^=DES_SPtrans[6][u3]; \ - u2=(int)t>>8L; \ - u1=(int)t&0x3f; \ - u2&=0x3f; \ - t>>=16L; \ - LL^=DES_SPtrans[1][u1]; \ - LL^=DES_SPtrans[3][u2]; \ - u3=(int)t>>8L; \ - u1=(int)t&0x3f; \ - u3&=0x3f; \ - LL^=DES_SPtrans[5][u1]; \ - LL^=DES_SPtrans[7][u3]; } -# endif -# ifdef DES_RISC2 -# define D_ENCRYPT(LL,R,S) {\ - unsigned int u1,u2,s1,s2; \ - LOAD_DATA(R,S,u,t,E0,E1,u1); \ - u>>=2L; \ - t=ROTATE(t,6); \ - u2=(int)u>>8L; \ - u1=(int)u&0x3f; \ - u2&=0x3f; \ - LL^=DES_SPtrans[0][u1]; \ - LL^=DES_SPtrans[2][u2]; \ - s1=(int)u>>16L; \ - s2=(int)u>>24L; \ - s1&=0x3f; \ - s2&=0x3f; \ - LL^=DES_SPtrans[4][s1]; \ - LL^=DES_SPtrans[6][s2]; \ - u2=(int)t>>8L; \ - u1=(int)t&0x3f; \ - u2&=0x3f; \ - LL^=DES_SPtrans[1][u1]; \ - LL^=DES_SPtrans[3][u2]; \ - s1=(int)t>>16; \ - s2=(int)t>>24L; \ - s1&=0x3f; \ - s2&=0x3f; \ - LL^=DES_SPtrans[5][s1]; \ - LL^=DES_SPtrans[7][s2]; } -# endif - -# else - -# define D_ENCRYPT(LL,R,S) {\ - LOAD_DATA_tmp(R,S,u,t,E0,E1); \ - t=ROTATE(t,4); \ - LL^=\ - DES_SPtrans[0][(u>> 2L)&0x3f]^ \ - DES_SPtrans[2][(u>>10L)&0x3f]^ \ - DES_SPtrans[4][(u>>18L)&0x3f]^ \ - DES_SPtrans[6][(u>>26L)&0x3f]^ \ - DES_SPtrans[1][(t>> 2L)&0x3f]^ \ - DES_SPtrans[3][(t>>10L)&0x3f]^ \ - DES_SPtrans[5][(t>>18L)&0x3f]^ \ - DES_SPtrans[7][(t>>26L)&0x3f]; } -# endif -# endif - - /*- - * IP and FP - * The problem is more of a geometric problem that random bit fiddling. - 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 - 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 - 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 - 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 - - 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 - 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 - 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 - 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 - - The output has been subject to swaps of the form - 0 1 -> 3 1 but the odd and even bits have been put into - 2 3 2 0 - different words. The main trick is to remember that - t=((l>>size)^r)&(mask); - r^=t; - l^=(t<>(n))^(b))&(m)),\ - (b)^=(t),\ - (a)^=((t)<<(n))) - -# define IP(l,r) \ - { \ - register DES_LONG tt; \ - PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ - PERM_OP(l,r,tt,16,0x0000ffffL); \ - PERM_OP(r,l,tt, 2,0x33333333L); \ - PERM_OP(l,r,tt, 8,0x00ff00ffL); \ - PERM_OP(r,l,tt, 1,0x55555555L); \ - } - -# define FP(l,r) \ - { \ - register DES_LONG tt; \ - PERM_OP(l,r,tt, 1,0x55555555L); \ - PERM_OP(r,l,tt, 8,0x00ff00ffL); \ - PERM_OP(l,r,tt, 2,0x33333333L); \ - PERM_OP(r,l,tt,16,0x0000ffffL); \ - PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ - } - -extern const DES_LONG DES_SPtrans[8][64]; - -void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, - DES_LONG Eswap0, DES_LONG Eswap1); - -# ifdef OPENSSL_SMALL_FOOTPRINT -# undef DES_UNROLL -# endif -#endif diff --git a/Sources/COpenSSL/des_old.c b/Sources/COpenSSL/des_old.c deleted file mode 100644 index e03aec4d..00000000 --- a/Sources/COpenSSL/des_old.c +++ /dev/null @@ -1,345 +0,0 @@ -/* crypto/des/des_old.c */ - -/*- - * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - * - * The function names in here are deprecated and are only present to - * provide an interface compatible with libdes. OpenSSL now provides - * functions where "des_" has been replaced with "DES_" in the names, - * to make it possible to make incompatible changes that are needed - * for C type security and other stuff. - * - * Please consider starting to use the DES_ functions rather than the - * des_ ones. The des_ functions will dissapear completely before - * OpenSSL 1.0! - * - * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - */ - -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#define OPENSSL_DES_LIBDES_COMPATIBILITY -#include "des.h" -#include "rand.h" - -const char *_ossl_old_des_options(void) -{ - return DES_options(); -} - -void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, - des_key_schedule ks1, des_key_schedule ks2, - des_key_schedule ks3, int enc) -{ - DES_ecb3_encrypt((const_DES_cblock *)input, output, - (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, - (DES_key_schedule *)ks3, enc); -} - -DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - des_key_schedule schedule, - _ossl_old_des_cblock *ivec) -{ - return DES_cbc_cksum((unsigned char *)input, output, length, - (DES_key_schedule *)schedule, ivec); -} - -void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int enc) -{ - DES_cbc_encrypt((unsigned char *)input, (unsigned char *)output, - length, (DES_key_schedule *)schedule, ivec, enc); -} - -void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int enc) -{ - DES_ncbc_encrypt((unsigned char *)input, (unsigned char *)output, - length, (DES_key_schedule *)schedule, ivec, enc); -} - -void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - des_key_schedule schedule, - _ossl_old_des_cblock *ivec, - _ossl_old_des_cblock *inw, - _ossl_old_des_cblock *outw, int enc) -{ - DES_xcbc_encrypt((unsigned char *)input, (unsigned char *)output, - length, (DES_key_schedule *)schedule, ivec, inw, outw, - enc); -} - -void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out, - int numbits, long length, - des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int enc) -{ - DES_cfb_encrypt(in, out, numbits, length, - (DES_key_schedule *)schedule, ivec, enc); -} - -void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, - des_key_schedule ks, int enc) -{ - DES_ecb_encrypt(input, output, (DES_key_schedule *)ks, enc); -} - -void _ossl_old_des_encrypt(DES_LONG *data, des_key_schedule ks, int enc) -{ - DES_encrypt1(data, (DES_key_schedule *)ks, enc); -} - -void _ossl_old_des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc) -{ - DES_encrypt2(data, (DES_key_schedule *)ks, enc); -} - -void _ossl_old_des_encrypt3(DES_LONG *data, des_key_schedule ks1, - des_key_schedule ks2, des_key_schedule ks3) -{ - DES_encrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, - (DES_key_schedule *)ks3); -} - -void _ossl_old_des_decrypt3(DES_LONG *data, des_key_schedule ks1, - des_key_schedule ks2, des_key_schedule ks3) -{ - DES_decrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, - (DES_key_schedule *)ks3); -} - -void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - des_key_schedule ks1, - des_key_schedule ks2, - des_key_schedule ks3, - _ossl_old_des_cblock *ivec, int enc) -{ - DES_ede3_cbc_encrypt((unsigned char *)input, (unsigned char *)output, - length, (DES_key_schedule *)ks1, - (DES_key_schedule *)ks2, (DES_key_schedule *)ks3, - ivec, enc); -} - -void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, - long length, des_key_schedule ks1, - des_key_schedule ks2, - des_key_schedule ks3, - _ossl_old_des_cblock *ivec, int *num, - int enc) -{ - DES_ede3_cfb64_encrypt(in, out, length, - (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, - (DES_key_schedule *)ks3, ivec, num, enc); -} - -void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, - long length, des_key_schedule ks1, - des_key_schedule ks2, - des_key_schedule ks3, - _ossl_old_des_cblock *ivec, int *num) -{ - DES_ede3_ofb64_encrypt(in, out, length, - (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, - (DES_key_schedule *)ks3, ivec, num); -} - -#if 0 /* broken code, preserved just in case anyone - * specifically looks for this */ -void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), - _ossl_old_des_cblock (*in_white), - _ossl_old_des_cblock (*out_white)) -{ - DES_xwhite_in2out(des_key, in_white, out_white); -} -#endif - -int _ossl_old_des_enc_read(int fd, char *buf, int len, des_key_schedule sched, - _ossl_old_des_cblock *iv) -{ - return DES_enc_read(fd, buf, len, (DES_key_schedule *)sched, iv); -} - -int _ossl_old_des_enc_write(int fd, char *buf, int len, - des_key_schedule sched, _ossl_old_des_cblock *iv) -{ - return DES_enc_write(fd, buf, len, (DES_key_schedule *)sched, iv); -} - -char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret) -{ - return DES_fcrypt(buf, salt, ret); -} - -char *_ossl_old_des_crypt(const char *buf, const char *salt) -{ - return DES_crypt(buf, salt); -} - -char *_ossl_old_crypt(const char *buf, const char *salt) -{ - return DES_crypt(buf, salt); -} - -void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out, - int numbits, long length, - des_key_schedule schedule, - _ossl_old_des_cblock *ivec) -{ - DES_ofb_encrypt(in, out, numbits, length, (DES_key_schedule *)schedule, - ivec); -} - -void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int enc) -{ - DES_pcbc_encrypt((unsigned char *)input, (unsigned char *)output, - length, (DES_key_schedule *)schedule, ivec, enc); -} - -DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - int out_count, _ossl_old_des_cblock *seed) -{ - return DES_quad_cksum((unsigned char *)input, output, length, - out_count, seed); -} - -void _ossl_old_des_random_seed(_ossl_old_des_cblock key) -{ - RAND_seed(key, sizeof(_ossl_old_des_cblock)); -} - -void _ossl_old_des_random_key(_ossl_old_des_cblock ret) -{ - DES_random_key((DES_cblock *)ret); -} - -int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt, - int verify) -{ - return DES_read_password(key, prompt, verify); -} - -int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, - _ossl_old_des_cblock *key2, - const char *prompt, int verify) -{ - return DES_read_2passwords(key1, key2, prompt, verify); -} - -void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key) -{ - DES_set_odd_parity(key); -} - -int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key) -{ - return DES_is_weak_key(key); -} - -int _ossl_old_des_set_key(_ossl_old_des_cblock *key, - des_key_schedule schedule) -{ - return DES_set_key(key, (DES_key_schedule *)schedule); -} - -int _ossl_old_des_key_sched(_ossl_old_des_cblock *key, - des_key_schedule schedule) -{ - return DES_key_sched(key, (DES_key_schedule *)schedule); -} - -void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key) -{ - DES_string_to_key(str, key); -} - -void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1, - _ossl_old_des_cblock *key2) -{ - DES_string_to_2keys(str, key1, key2); -} - -void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, - long length, des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int *num, - int enc) -{ - DES_cfb64_encrypt(in, out, length, (DES_key_schedule *)schedule, - ivec, num, enc); -} - -void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, - long length, des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int *num) -{ - DES_ofb64_encrypt(in, out, length, (DES_key_schedule *)schedule, - ivec, num); -} diff --git a/Sources/COpenSSL/des_old.h b/Sources/COpenSSL/des_old.h deleted file mode 100644 index 3a98695c..00000000 --- a/Sources/COpenSSL/des_old.h +++ /dev/null @@ -1,497 +0,0 @@ -/* crypto/des/des_old.h */ - -/*- - * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - * - * The function names in here are deprecated and are only present to - * provide an interface compatible with openssl 0.9.6 and older as - * well as libdes. OpenSSL now provides functions where "des_" has - * been replaced with "DES_" in the names, to make it possible to - * make incompatible changes that are needed for C type security and - * other stuff. - * - * This include files has two compatibility modes: - * - * - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API - * that is compatible with libdes and SSLeay. - * - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an - * API that is compatible with OpenSSL 0.9.5x to 0.9.6x. - * - * Note that these modes break earlier snapshots of OpenSSL, where - * libdes compatibility was the only available mode or (later on) the - * prefered compatibility mode. However, after much consideration - * (and more or less violent discussions with external parties), it - * was concluded that OpenSSL should be compatible with earlier versions - * of itself before anything else. Also, in all honesty, libdes is - * an old beast that shouldn't really be used any more. - * - * Please consider starting to use the DES_ functions rather than the - * des_ ones. The des_ functions will disappear completely before - * OpenSSL 1.0! - * - * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING - */ - -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_DES_H -# define HEADER_DES_H - -# include "e_os2.h" /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */ - -# ifdef OPENSSL_NO_DES -# error DES is disabled. -# endif - -# ifndef HEADER_NEW_DES_H -# error You must include des.h, not des_old.h directly. -# endif - -# ifdef _KERBEROS_DES_H -# error replaces . -# endif - -# include "symhacks.h" - -# ifdef OPENSSL_BUILD_SHLIBCRYPTO -# undef OPENSSL_EXTERN -# define OPENSSL_EXTERN OPENSSL_EXPORT -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef _ -# undef _ -# endif - -typedef unsigned char _ossl_old_des_cblock[8]; -typedef struct _ossl_old_des_ks_struct { - union { - _ossl_old_des_cblock _; - /* - * make sure things are correct size on machines with 8 byte longs - */ - DES_LONG pad[2]; - } ks; -} _ossl_old_des_key_schedule[16]; - -# ifndef OPENSSL_DES_LIBDES_COMPATIBILITY -# define des_cblock DES_cblock -# define const_des_cblock const_DES_cblock -# define des_key_schedule DES_key_schedule -# define des_ecb3_encrypt(i,o,k1,k2,k3,e)\ - DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e)) -# define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\ - DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e)) -# define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\ - DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e)) -# define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\ - DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e)) -# define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\ - DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n)) -# define des_options()\ - DES_options() -# define des_cbc_cksum(i,o,l,k,iv)\ - DES_cbc_cksum((i),(o),(l),&(k),(iv)) -# define des_cbc_encrypt(i,o,l,k,iv,e)\ - DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e)) -# define des_ncbc_encrypt(i,o,l,k,iv,e)\ - DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e)) -# define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\ - DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e)) -# define des_cfb_encrypt(i,o,n,l,k,iv,e)\ - DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e)) -# define des_ecb_encrypt(i,o,k,e)\ - DES_ecb_encrypt((i),(o),&(k),(e)) -# define des_encrypt1(d,k,e)\ - DES_encrypt1((d),&(k),(e)) -# define des_encrypt2(d,k,e)\ - DES_encrypt2((d),&(k),(e)) -# define des_encrypt3(d,k1,k2,k3)\ - DES_encrypt3((d),&(k1),&(k2),&(k3)) -# define des_decrypt3(d,k1,k2,k3)\ - DES_decrypt3((d),&(k1),&(k2),&(k3)) -# define des_xwhite_in2out(k,i,o)\ - DES_xwhite_in2out((k),(i),(o)) -# define des_enc_read(f,b,l,k,iv)\ - DES_enc_read((f),(b),(l),&(k),(iv)) -# define des_enc_write(f,b,l,k,iv)\ - DES_enc_write((f),(b),(l),&(k),(iv)) -# define des_fcrypt(b,s,r)\ - DES_fcrypt((b),(s),(r)) -# if 0 -# define des_crypt(b,s)\ - DES_crypt((b),(s)) -# if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__) -# define crypt(b,s)\ - DES_crypt((b),(s)) -# endif -# endif -# define des_ofb_encrypt(i,o,n,l,k,iv)\ - DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv)) -# define des_pcbc_encrypt(i,o,l,k,iv,e)\ - DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e)) -# define des_quad_cksum(i,o,l,c,s)\ - DES_quad_cksum((i),(o),(l),(c),(s)) -# define des_random_seed(k)\ - _ossl_096_des_random_seed((k)) -# define des_random_key(r)\ - DES_random_key((r)) -# define des_read_password(k,p,v) \ - DES_read_password((k),(p),(v)) -# define des_read_2passwords(k1,k2,p,v) \ - DES_read_2passwords((k1),(k2),(p),(v)) -# define des_set_odd_parity(k)\ - DES_set_odd_parity((k)) -# define des_check_key_parity(k)\ - DES_check_key_parity((k)) -# define des_is_weak_key(k)\ - DES_is_weak_key((k)) -# define des_set_key(k,ks)\ - DES_set_key((k),&(ks)) -# define des_key_sched(k,ks)\ - DES_key_sched((k),&(ks)) -# define des_set_key_checked(k,ks)\ - DES_set_key_checked((k),&(ks)) -# define des_set_key_unchecked(k,ks)\ - DES_set_key_unchecked((k),&(ks)) -# define des_string_to_key(s,k)\ - DES_string_to_key((s),(k)) -# define des_string_to_2keys(s,k1,k2)\ - DES_string_to_2keys((s),(k1),(k2)) -# define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\ - DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e)) -# define des_ofb64_encrypt(i,o,l,ks,iv,n)\ - DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n)) - -# define des_ecb2_encrypt(i,o,k1,k2,e) \ - des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) - -# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ - des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) - -# define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ - des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) - -# define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ - des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) - -# define des_check_key DES_check_key -# define des_rw_mode DES_rw_mode -# else /* libdes compatibility */ -/* - * Map all symbol names to _ossl_old_des_* form, so we avoid all clashes with - * libdes - */ -# define des_cblock _ossl_old_des_cblock -# define des_key_schedule _ossl_old_des_key_schedule -# define des_ecb3_encrypt(i,o,k1,k2,k3,e)\ - _ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e)) -# define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\ - _ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e)) -# define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\ - _ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e)) -# define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\ - _ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n)) -# define des_options()\ - _ossl_old_des_options() -# define des_cbc_cksum(i,o,l,k,iv)\ - _ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv)) -# define des_cbc_encrypt(i,o,l,k,iv,e)\ - _ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e)) -# define des_ncbc_encrypt(i,o,l,k,iv,e)\ - _ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e)) -# define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\ - _ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e)) -# define des_cfb_encrypt(i,o,n,l,k,iv,e)\ - _ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e)) -# define des_ecb_encrypt(i,o,k,e)\ - _ossl_old_des_ecb_encrypt((i),(o),(k),(e)) -# define des_encrypt(d,k,e)\ - _ossl_old_des_encrypt((d),(k),(e)) -# define des_encrypt2(d,k,e)\ - _ossl_old_des_encrypt2((d),(k),(e)) -# define des_encrypt3(d,k1,k2,k3)\ - _ossl_old_des_encrypt3((d),(k1),(k2),(k3)) -# define des_decrypt3(d,k1,k2,k3)\ - _ossl_old_des_decrypt3((d),(k1),(k2),(k3)) -# define des_xwhite_in2out(k,i,o)\ - _ossl_old_des_xwhite_in2out((k),(i),(o)) -# define des_enc_read(f,b,l,k,iv)\ - _ossl_old_des_enc_read((f),(b),(l),(k),(iv)) -# define des_enc_write(f,b,l,k,iv)\ - _ossl_old_des_enc_write((f),(b),(l),(k),(iv)) -# define des_fcrypt(b,s,r)\ - _ossl_old_des_fcrypt((b),(s),(r)) -# define des_crypt(b,s)\ - _ossl_old_des_crypt((b),(s)) -# if 0 -# define crypt(b,s)\ - _ossl_old_crypt((b),(s)) -# endif -# define des_ofb_encrypt(i,o,n,l,k,iv)\ - _ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv)) -# define des_pcbc_encrypt(i,o,l,k,iv,e)\ - _ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e)) -# define des_quad_cksum(i,o,l,c,s)\ - _ossl_old_des_quad_cksum((i),(o),(l),(c),(s)) -# define des_random_seed(k)\ - _ossl_old_des_random_seed((k)) -# define des_random_key(r)\ - _ossl_old_des_random_key((r)) -# define des_read_password(k,p,v) \ - _ossl_old_des_read_password((k),(p),(v)) -# define des_read_2passwords(k1,k2,p,v) \ - _ossl_old_des_read_2passwords((k1),(k2),(p),(v)) -# define des_set_odd_parity(k)\ - _ossl_old_des_set_odd_parity((k)) -# define des_is_weak_key(k)\ - _ossl_old_des_is_weak_key((k)) -# define des_set_key(k,ks)\ - _ossl_old_des_set_key((k),(ks)) -# define des_key_sched(k,ks)\ - _ossl_old_des_key_sched((k),(ks)) -# define des_string_to_key(s,k)\ - _ossl_old_des_string_to_key((s),(k)) -# define des_string_to_2keys(s,k1,k2)\ - _ossl_old_des_string_to_2keys((s),(k1),(k2)) -# define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\ - _ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e)) -# define des_ofb64_encrypt(i,o,l,ks,iv,n)\ - _ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n)) - -# define des_ecb2_encrypt(i,o,k1,k2,e) \ - des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) - -# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ - des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) - -# define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ - des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) - -# define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ - des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) - -# define des_check_key DES_check_key -# define des_rw_mode DES_rw_mode -# endif - -const char *_ossl_old_des_options(void); -void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, - _ossl_old_des_key_schedule ks1, - _ossl_old_des_key_schedule ks2, - _ossl_old_des_key_schedule ks3, int enc); -DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec); -void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int enc); -void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int enc); -void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec, - _ossl_old_des_cblock *inw, - _ossl_old_des_cblock *outw, int enc); -void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out, - int numbits, long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int enc); -void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, - _ossl_old_des_key_schedule ks, int enc); -void _ossl_old_des_encrypt(DES_LONG *data, _ossl_old_des_key_schedule ks, - int enc); -void _ossl_old_des_encrypt2(DES_LONG *data, _ossl_old_des_key_schedule ks, - int enc); -void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1, - _ossl_old_des_key_schedule ks2, - _ossl_old_des_key_schedule ks3); -void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1, - _ossl_old_des_key_schedule ks2, - _ossl_old_des_key_schedule ks3); -void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - _ossl_old_des_key_schedule ks1, - _ossl_old_des_key_schedule ks2, - _ossl_old_des_key_schedule ks3, - _ossl_old_des_cblock *ivec, int enc); -void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, - long length, - _ossl_old_des_key_schedule ks1, - _ossl_old_des_key_schedule ks2, - _ossl_old_des_key_schedule ks3, - _ossl_old_des_cblock *ivec, int *num, - int enc); -void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, - long length, - _ossl_old_des_key_schedule ks1, - _ossl_old_des_key_schedule ks2, - _ossl_old_des_key_schedule ks3, - _ossl_old_des_cblock *ivec, int *num); -# if 0 -void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), - _ossl_old_des_cblock (*in_white), - _ossl_old_des_cblock (*out_white)); -# endif - -int _ossl_old_des_enc_read(int fd, char *buf, int len, - _ossl_old_des_key_schedule sched, - _ossl_old_des_cblock *iv); -int _ossl_old_des_enc_write(int fd, char *buf, int len, - _ossl_old_des_key_schedule sched, - _ossl_old_des_cblock *iv); -char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret); -char *_ossl_old_des_crypt(const char *buf, const char *salt); -# if !defined(PERL5) && !defined(NeXT) -char *_ossl_old_crypt(const char *buf, const char *salt); -# endif -void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out, - int numbits, long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec); -void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int enc); -DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input, - _ossl_old_des_cblock *output, long length, - int out_count, _ossl_old_des_cblock *seed); -void _ossl_old_des_random_seed(_ossl_old_des_cblock key); -void _ossl_old_des_random_key(_ossl_old_des_cblock ret); -int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt, - int verify); -int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, - _ossl_old_des_cblock *key2, - const char *prompt, int verify); -void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key); -int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key); -int _ossl_old_des_set_key(_ossl_old_des_cblock *key, - _ossl_old_des_key_schedule schedule); -int _ossl_old_des_key_sched(_ossl_old_des_cblock *key, - _ossl_old_des_key_schedule schedule); -void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key); -void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1, - _ossl_old_des_cblock *key2); -void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, - long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int *num, - int enc); -void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, - long length, - _ossl_old_des_key_schedule schedule, - _ossl_old_des_cblock *ivec, int *num); - -void _ossl_096_des_random_seed(des_cblock *key); - -/* - * The following definitions provide compatibility with the MIT Kerberos - * library. The _ossl_old_des_key_schedule structure is not binary - * compatible. - */ - -# define _KERBEROS_DES_H - -# define KRBDES_ENCRYPT DES_ENCRYPT -# define KRBDES_DECRYPT DES_DECRYPT - -# ifdef KERBEROS -# define ENCRYPT DES_ENCRYPT -# define DECRYPT DES_DECRYPT -# endif - -# ifndef NCOMPAT -# define C_Block des_cblock -# define Key_schedule des_key_schedule -# define KEY_SZ DES_KEY_SZ -# define string_to_key des_string_to_key -# define read_pw_string des_read_pw_string -# define random_key des_random_key -# define pcbc_encrypt des_pcbc_encrypt -# define set_key des_set_key -# define key_sched des_key_sched -# define ecb_encrypt des_ecb_encrypt -# define cbc_encrypt des_cbc_encrypt -# define ncbc_encrypt des_ncbc_encrypt -# define xcbc_encrypt des_xcbc_encrypt -# define cbc_cksum des_cbc_cksum -# define quad_cksum des_quad_cksum -# define check_parity des_check_key_parity -# endif - -# define des_fixup_key_parity DES_fixup_key_parity - -#ifdef __cplusplus -} -#endif - -/* for DES_read_pw_string et al */ -# include "ui_compat.h" - -#endif diff --git a/Sources/COpenSSL/des_old2.c b/Sources/COpenSSL/des_old2.c deleted file mode 100644 index 6f06d996..00000000 --- a/Sources/COpenSSL/des_old2.c +++ /dev/null @@ -1,80 +0,0 @@ -/* crypto/des/des_old.c */ - -/* - * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING The - * function names in here are deprecated and are only present to provide an - * interface compatible with OpenSSL 0.9.6c. OpenSSL now provides functions - * where "des_" has been replaced with "DES_" in the names, to make it - * possible to make incompatible changes that are needed for C type security - * and other stuff. Please consider starting to use the DES_ functions - * rather than the des_ ones. The des_ functions will dissapear completely - * before OpenSSL 1.0! WARNING WARNING WARNING WARNING WARNING WARNING - * WARNING WARNING - */ - -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#undef OPENSSL_DES_LIBDES_COMPATIBILITY -#include "des.h" -#include "rand.h" - -void _ossl_096_des_random_seed(DES_cblock *key) -{ - RAND_seed(key, sizeof(DES_cblock)); -} diff --git a/Sources/COpenSSL/des_ver.h b/Sources/COpenSSL/des_ver.h deleted file mode 100644 index 5ad82d02..00000000 --- a/Sources/COpenSSL/des_ver.h +++ /dev/null @@ -1,73 +0,0 @@ -/* crypto/des/des_ver.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "e_os2.h" - -#ifdef OPENSSL_BUILD_SHLIBCRYPTO -# undef OPENSSL_EXTERN -# define OPENSSL_EXTERN OPENSSL_EXPORT -#endif - -/* The following macros make sure the names are different from libdes names */ -#define DES_version OSSL_DES_version -#define libdes_version OSSL_libdes_version - -/* SSLeay version string */ -OPENSSL_EXTERN const char OSSL_DES_version[]; -/* old libdes version string */ -OPENSSL_EXTERN const char OSSL_libdes_version[]; diff --git a/Sources/COpenSSL/dh.h b/Sources/COpenSSL/dh.h deleted file mode 100644 index d610c7b8..00000000 --- a/Sources/COpenSSL/dh.h +++ /dev/null @@ -1,412 +0,0 @@ -/* crypto/dh/dh.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_DH_H -# define HEADER_DH_H - -# include "e_os2.h" - -# ifdef OPENSSL_NO_DH -# error DH is disabled. -# endif - -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# include "ossl_typ.h" -# ifndef OPENSSL_NO_DEPRECATED -# include "bn.h" -# endif - -# ifndef OPENSSL_DH_MAX_MODULUS_BITS -# define OPENSSL_DH_MAX_MODULUS_BITS 10000 -# endif - -# define DH_FLAG_CACHE_MONT_P 0x01 - -/* - * new with 0.9.7h; the built-in DH - * implementation now uses constant time - * modular exponentiation for secret exponents - * by default. This flag causes the - * faster variable sliding window method to - * be used for all exponents. - */ -# define DH_FLAG_NO_EXP_CONSTTIME 0x02 - -/* - * If this flag is set the DH method is FIPS compliant and can be used in - * FIPS mode. This is set in the validated module method. If an application - * sets this flag in its own methods it is its reposibility to ensure the - * result is compliant. - */ - -# define DH_FLAG_FIPS_METHOD 0x0400 - -/* - * If this flag is set the operations normally disabled in FIPS mode are - * permitted it is then the applications responsibility to ensure that the - * usage is compliant. - */ - -# define DH_FLAG_NON_FIPS_ALLOW 0x0400 - -#ifdef __cplusplus -extern "C" { -#endif - -/* Already defined in ossl_typ.h */ -/* typedef struct dh_st DH; */ -/* typedef struct dh_method DH_METHOD; */ - -struct dh_method { - const char *name; - /* Methods here */ - int (*generate_key) (DH *dh); - int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh); - /* Can be null */ - int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); - int (*init) (DH *dh); - int (*finish) (DH *dh); - int flags; - char *app_data; - /* If this is non-NULL, it will be used to generate parameters */ - int (*generate_params) (DH *dh, int prime_len, int generator, - BN_GENCB *cb); -}; - -struct dh_st { - /* - * This first argument is used to pick up errors when a DH is passed - * instead of a EVP_PKEY - */ - int pad; - int version; - BIGNUM *p; - BIGNUM *g; - long length; /* optional */ - BIGNUM *pub_key; /* g^x % p */ - BIGNUM *priv_key; /* x */ - int flags; - BN_MONT_CTX *method_mont_p; - /* Place holders if we want to do X9.42 DH */ - BIGNUM *q; - BIGNUM *j; - unsigned char *seed; - int seedlen; - BIGNUM *counter; - int references; - CRYPTO_EX_DATA ex_data; - const DH_METHOD *meth; - ENGINE *engine; -}; - -# define DH_GENERATOR_2 2 -/* #define DH_GENERATOR_3 3 */ -# define DH_GENERATOR_5 5 - -/* DH_check error codes */ -# define DH_CHECK_P_NOT_PRIME 0x01 -# define DH_CHECK_P_NOT_SAFE_PRIME 0x02 -# define DH_UNABLE_TO_CHECK_GENERATOR 0x04 -# define DH_NOT_SUITABLE_GENERATOR 0x08 -# define DH_CHECK_Q_NOT_PRIME 0x10 -# define DH_CHECK_INVALID_Q_VALUE 0x20 -# define DH_CHECK_INVALID_J_VALUE 0x40 - -/* DH_check_pub_key error codes */ -# define DH_CHECK_PUBKEY_TOO_SMALL 0x01 -# define DH_CHECK_PUBKEY_TOO_LARGE 0x02 -# define DH_CHECK_PUBKEY_INVALID 0x04 - -/* - * primes p where (p-1)/2 is prime too are called "safe"; we define this for - * backward compatibility: - */ -# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME - -# define d2i_DHparams_fp(fp,x) \ - (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ - (char *(*)())d2i_DHparams, \ - (fp), \ - (unsigned char **)(x)) -# define i2d_DHparams_fp(fp,x) \ - ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x)) -# define d2i_DHparams_bio(bp,x) \ - ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x) -# define i2d_DHparams_bio(bp,x) \ - ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) - -# define d2i_DHxparams_fp(fp,x) \ - (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ - (char *(*)())d2i_DHxparams, \ - (fp), \ - (unsigned char **)(x)) -# define i2d_DHxparams_fp(fp,x) \ - ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x)) -# define d2i_DHxparams_bio(bp,x) \ - ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x) -# define i2d_DHxparams_bio(bp,x) \ - ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x) - -DH *DHparams_dup(DH *); - -const DH_METHOD *DH_OpenSSL(void); - -void DH_set_default_method(const DH_METHOD *meth); -const DH_METHOD *DH_get_default_method(void); -int DH_set_method(DH *dh, const DH_METHOD *meth); -DH *DH_new_method(ENGINE *engine); - -DH *DH_new(void); -void DH_free(DH *dh); -int DH_up_ref(DH *dh); -int DH_size(const DH *dh); -int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int DH_set_ex_data(DH *d, int idx, void *arg); -void *DH_get_ex_data(DH *d, int idx); - -/* Deprecated version */ -# ifndef OPENSSL_NO_DEPRECATED -DH *DH_generate_parameters(int prime_len, int generator, - void (*callback) (int, int, void *), void *cb_arg); -# endif /* !defined(OPENSSL_NO_DEPRECATED) */ - -/* New version */ -int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, - BN_GENCB *cb); - -int DH_check(const DH *dh, int *codes); -int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes); -int DH_generate_key(DH *dh); -int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); -int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh); -DH *d2i_DHparams(DH **a, const unsigned char **pp, long length); -int i2d_DHparams(const DH *a, unsigned char **pp); -DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length); -int i2d_DHxparams(const DH *a, unsigned char **pp); -# ifndef OPENSSL_NO_FP_API -int DHparams_print_fp(FILE *fp, const DH *x); -# endif -# ifndef OPENSSL_NO_BIO -int DHparams_print(BIO *bp, const DH *x); -# else -int DHparams_print(char *bp, const DH *x); -# endif - -/* RFC 5114 parameters */ -DH *DH_get_1024_160(void); -DH *DH_get_2048_224(void); -DH *DH_get_2048_256(void); - -# ifndef OPENSSL_NO_CMS -/* RFC2631 KDF */ -int DH_KDF_X9_42(unsigned char *out, size_t outlen, - const unsigned char *Z, size_t Zlen, - ASN1_OBJECT *key_oid, - const unsigned char *ukm, size_t ukmlen, const EVP_MD *md); -# endif - -# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) - -# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL) - -# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL) - -# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) - -# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) - -# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DH_RFC5114, gen, NULL) - -# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL) - -# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL) - -# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)oid) - -# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)poid) - -# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)md) - -# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)pmd) - -# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL) - -# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)plen) - -# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)p) - -# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)p) - -# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) -# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) -# define EVP_PKEY_CTRL_DH_RFC5114 (EVP_PKEY_ALG_CTRL + 3) -# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN (EVP_PKEY_ALG_CTRL + 4) -# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE (EVP_PKEY_ALG_CTRL + 5) -# define EVP_PKEY_CTRL_DH_KDF_TYPE (EVP_PKEY_ALG_CTRL + 6) -# define EVP_PKEY_CTRL_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 7) -# define EVP_PKEY_CTRL_GET_DH_KDF_MD (EVP_PKEY_ALG_CTRL + 8) -# define EVP_PKEY_CTRL_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 9) -# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 10) -# define EVP_PKEY_CTRL_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 11) -# define EVP_PKEY_CTRL_GET_DH_KDF_UKM (EVP_PKEY_ALG_CTRL + 12) -# define EVP_PKEY_CTRL_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 13) -# define EVP_PKEY_CTRL_GET_DH_KDF_OID (EVP_PKEY_ALG_CTRL + 14) - -/* KDF types */ -# define EVP_PKEY_DH_KDF_NONE 1 -# define EVP_PKEY_DH_KDF_X9_42 2 - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_DH_strings(void); - -/* Error codes for the DH functions. */ - -/* Function codes. */ -# define DH_F_COMPUTE_KEY 102 -# define DH_F_DHPARAMS_PRINT_FP 101 -# define DH_F_DH_BUILTIN_GENPARAMS 106 -# define DH_F_DH_CMS_DECRYPT 117 -# define DH_F_DH_CMS_SET_PEERKEY 118 -# define DH_F_DH_CMS_SET_SHARED_INFO 119 -# define DH_F_DH_COMPUTE_KEY 114 -# define DH_F_DH_GENERATE_KEY 115 -# define DH_F_DH_GENERATE_PARAMETERS_EX 116 -# define DH_F_DH_NEW_METHOD 105 -# define DH_F_DH_PARAM_DECODE 107 -# define DH_F_DH_PRIV_DECODE 110 -# define DH_F_DH_PRIV_ENCODE 111 -# define DH_F_DH_PUB_DECODE 108 -# define DH_F_DH_PUB_ENCODE 109 -# define DH_F_DO_DH_PRINT 100 -# define DH_F_GENERATE_KEY 103 -# define DH_F_GENERATE_PARAMETERS 104 -# define DH_F_PKEY_DH_DERIVE 112 -# define DH_F_PKEY_DH_KEYGEN 113 - -/* Reason codes. */ -# define DH_R_BAD_GENERATOR 101 -# define DH_R_BN_DECODE_ERROR 109 -# define DH_R_BN_ERROR 106 -# define DH_R_DECODE_ERROR 104 -# define DH_R_INVALID_PUBKEY 102 -# define DH_R_KDF_PARAMETER_ERROR 112 -# define DH_R_KEYS_NOT_SET 108 -# define DH_R_KEY_SIZE_TOO_SMALL 110 -# define DH_R_MODULUS_TOO_LARGE 103 -# define DH_R_NON_FIPS_METHOD 111 -# define DH_R_NO_PARAMETERS_SET 107 -# define DH_R_NO_PRIVATE_VALUE 100 -# define DH_R_PARAMETER_ENCODING_ERROR 105 -# define DH_R_PEER_KEY_ERROR 113 -# define DH_R_SHARED_INFO_ERROR 114 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/dh_.c b/Sources/COpenSSL/dh_.c deleted file mode 100644 index 8a993724..00000000 --- a/Sources/COpenSSL/dh_.c +++ /dev/null @@ -1,3418 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "x509.h" -#include "asn1.h" -#include "dh.h" -#include "bn.h" -#include "asn1_locl.h" -#ifndef OPENSSL_NO_CMS -# include "cms.h" -#endif - -extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth; - -/* - * i2d/d2i like DH parameter functions which use the appropriate routine for - * PKCS#3 DH or X9.42 DH. - */ - -static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp, - long length) -{ - if (pkey->ameth == &dhx_asn1_meth) - return d2i_DHxparams(NULL, pp, length); - return d2i_DHparams(NULL, pp, length); -} - -static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp) -{ - if (pkey->ameth == &dhx_asn1_meth) - return i2d_DHxparams(a, pp); - return i2d_DHparams(a, pp); -} - -static void int_dh_free(EVP_PKEY *pkey) -{ - DH_free(pkey->pkey.dh); -} - -static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) -{ - const unsigned char *p, *pm; - int pklen, pmlen; - int ptype; - void *pval; - ASN1_STRING *pstr; - X509_ALGOR *palg; - ASN1_INTEGER *public_key = NULL; - - DH *dh = NULL; - - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - if (ptype != V_ASN1_SEQUENCE) { - DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); - goto err; - } - - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; - - if (!(dh = d2i_dhp(pkey, &pm, pmlen))) { - DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); - goto err; - } - - if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) { - DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); - goto err; - } - - /* We have parameters now set public key */ - if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { - DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR); - goto err; - } - - ASN1_INTEGER_free(public_key); - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); - return 1; - - err: - if (public_key) - ASN1_INTEGER_free(public_key); - if (dh) - DH_free(dh); - return 0; - -} - -static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) -{ - DH *dh; - int ptype; - unsigned char *penc = NULL; - int penclen; - ASN1_STRING *str; - ASN1_INTEGER *pub_key = NULL; - - dh = pkey->pkey.dh; - - str = ASN1_STRING_new(); - if (!str) { - DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - str->length = i2d_dhp(pkey, dh, &str->data); - if (str->length <= 0) { - DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - ptype = V_ASN1_SEQUENCE; - - pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); - if (!pub_key) - goto err; - - penclen = i2d_ASN1_INTEGER(pub_key, &penc); - - ASN1_INTEGER_free(pub_key); - - if (penclen <= 0) { - DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id), - ptype, str, penc, penclen)) - return 1; - - err: - if (penc) - OPENSSL_free(penc); - if (str) - ASN1_STRING_free(str); - - return 0; -} - -/* - * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in that - * the AlgorithmIdentifier contains the paramaters, the private key is - * explcitly included and the pubkey must be recalculated. - */ - -static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) -{ - const unsigned char *p, *pm; - int pklen, pmlen; - int ptype; - void *pval; - ASN1_STRING *pstr; - X509_ALGOR *palg; - ASN1_INTEGER *privkey = NULL; - - DH *dh = NULL; - - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - if (ptype != V_ASN1_SEQUENCE) - goto decerr; - - if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen))) - goto decerr; - - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; - if (!(dh = d2i_dhp(pkey, &pm, pmlen))) - goto decerr; - /* We have parameters now set private key */ - if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { - DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR); - goto dherr; - } - /* Calculate public key */ - if (!DH_generate_key(dh)) - goto dherr; - - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); - - ASN1_STRING_clear_free(privkey); - - return 1; - - decerr: - DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); - dherr: - DH_free(dh); - ASN1_STRING_clear_free(privkey); - return 0; -} - -static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) -{ - ASN1_STRING *params = NULL; - ASN1_INTEGER *prkey = NULL; - unsigned char *dp = NULL; - int dplen; - - params = ASN1_STRING_new(); - - if (!params) { - DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - - params->length = i2d_dhp(pkey, pkey->pkey.dh, ¶ms->data); - if (params->length <= 0) { - DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - params->type = V_ASN1_SEQUENCE; - - /* Get private key into integer */ - prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL); - - if (!prkey) { - DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR); - goto err; - } - - dplen = i2d_ASN1_INTEGER(prkey, &dp); - - ASN1_STRING_clear_free(prkey); - prkey = NULL; - - if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0, - V_ASN1_SEQUENCE, params, dp, dplen)) - goto err; - - return 1; - - err: - if (dp != NULL) - OPENSSL_free(dp); - if (params != NULL) - ASN1_STRING_free(params); - if (prkey != NULL) - ASN1_STRING_clear_free(prkey); - return 0; -} - -static void update_buflen(const BIGNUM *b, size_t *pbuflen) -{ - size_t i; - if (!b) - return; - if (*pbuflen < (i = (size_t)BN_num_bytes(b))) - *pbuflen = i; -} - -static int dh_param_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) -{ - DH *dh; - if (!(dh = d2i_dhp(pkey, pder, derlen))) { - DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); - return 0; - } - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); - return 1; -} - -static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - return i2d_dhp(pkey, pkey->pkey.dh, pder); -} - -static int do_dh_print(BIO *bp, const DH *x, int indent, - ASN1_PCTX *ctx, int ptype) -{ - unsigned char *m = NULL; - int reason = ERR_R_BUF_LIB, ret = 0; - size_t buf_len = 0; - - const char *ktype = NULL; - - BIGNUM *priv_key, *pub_key; - - if (ptype == 2) - priv_key = x->priv_key; - else - priv_key = NULL; - - if (ptype > 0) - pub_key = x->pub_key; - else - pub_key = NULL; - - update_buflen(x->p, &buf_len); - - if (buf_len == 0) { - reason = ERR_R_PASSED_NULL_PARAMETER; - goto err; - } - - update_buflen(x->g, &buf_len); - update_buflen(x->q, &buf_len); - update_buflen(x->j, &buf_len); - update_buflen(x->counter, &buf_len); - update_buflen(pub_key, &buf_len); - update_buflen(priv_key, &buf_len); - - if (ptype == 2) - ktype = "DH Private-Key"; - else if (ptype == 1) - ktype = "DH Public-Key"; - else - ktype = "DH Parameters"; - - m = OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - BIO_indent(bp, indent, 128); - if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) - goto err; - indent += 4; - - if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent)) - goto err; - if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent)) - goto err; - - if (!ASN1_bn_print(bp, "prime:", x->p, m, indent)) - goto err; - if (!ASN1_bn_print(bp, "generator:", x->g, m, indent)) - goto err; - if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, m, indent)) - goto err; - if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, m, indent)) - goto err; - if (x->seed) { - int i; - BIO_indent(bp, indent, 128); - BIO_puts(bp, "seed:"); - for (i = 0; i < x->seedlen; i++) { - if ((i % 15) == 0) { - if (BIO_puts(bp, "\n") <= 0 - || !BIO_indent(bp, indent + 4, 128)) - goto err; - } - if (BIO_printf(bp, "%02x%s", x->seed[i], - ((i + 1) == x->seedlen) ? "" : ":") <= 0) - goto err; - } - if (BIO_write(bp, "\n", 1) <= 0) - return (0); - } - if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, m, indent)) - goto err; - if (x->length != 0) { - BIO_indent(bp, indent, 128); - if (BIO_printf(bp, "recommended-private-length: %d bits\n", - (int)x->length) <= 0) - goto err; - } - - ret = 1; - if (0) { - err: - DHerr(DH_F_DO_DH_PRINT, reason); - } - if (m != NULL) - OPENSSL_free(m); - return (ret); -} - -static int int_dh_size(const EVP_PKEY *pkey) -{ - return (DH_size(pkey->pkey.dh)); -} - -static int dh_bits(const EVP_PKEY *pkey) -{ - return BN_num_bits(pkey->pkey.dh->p); -} - -static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) -{ - if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) || - BN_cmp(a->pkey.dh->g, b->pkey.dh->g)) - return 0; - else if (a->ameth == &dhx_asn1_meth) { - if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q)) - return 0; - } - return 1; -} - -static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) -{ - BIGNUM *a; - if (src) { - a = BN_dup(src); - if (!a) - return 0; - } else - a = NULL; - if (*dst) - BN_free(*dst); - *dst = a; - return 1; -} - -static int int_dh_param_copy(DH *to, const DH *from, int is_x942) -{ - if (is_x942 == -1) - is_x942 = ! !from->q; - if (!int_dh_bn_cpy(&to->p, from->p)) - return 0; - if (!int_dh_bn_cpy(&to->g, from->g)) - return 0; - if (is_x942) { - if (!int_dh_bn_cpy(&to->q, from->q)) - return 0; - if (!int_dh_bn_cpy(&to->j, from->j)) - return 0; - if (to->seed) { - OPENSSL_free(to->seed); - to->seed = NULL; - to->seedlen = 0; - } - if (from->seed) { - to->seed = BUF_memdup(from->seed, from->seedlen); - if (!to->seed) - return 0; - to->seedlen = from->seedlen; - } - } else - to->length = from->length; - return 1; -} - -DH *DHparams_dup(DH *dh) -{ - DH *ret; - ret = DH_new(); - if (!ret) - return NULL; - if (!int_dh_param_copy(ret, dh, -1)) { - DH_free(ret); - return NULL; - } - return ret; -} - -static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) -{ - return int_dh_param_copy(to->pkey.dh, from->pkey.dh, - from->ameth == &dhx_asn1_meth); -} - -static int dh_missing_parameters(const EVP_PKEY *a) -{ - if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL) - return 1; - return 0; -} - -static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - if (dh_cmp_parameters(a, b) == 0) - return 0; - if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0) - return 0; - else - return 1; -} - -static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0); -} - -static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1); -} - -static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2); -} - -int DHparams_print(BIO *bp, const DH *x) -{ - return do_dh_print(bp, x, 4, NULL, 0); -} - -#ifndef OPENSSL_NO_CMS -static int dh_cms_decrypt(CMS_RecipientInfo *ri); -static int dh_cms_encrypt(CMS_RecipientInfo *ri); -#endif - -static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - switch (op) { -#ifndef OPENSSL_NO_CMS - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (arg1 == 1) - return dh_cms_decrypt(arg2); - else if (arg1 == 0) - return dh_cms_encrypt(arg2); - return -2; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_AGREE; - return 1; -#endif - default: - return -2; - } - -} - -const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { - EVP_PKEY_DH, - EVP_PKEY_DH, - 0, - - "DH", - "OpenSSL PKCS#3 DH method", - - dh_pub_decode, - dh_pub_encode, - dh_pub_cmp, - dh_public_print, - - dh_priv_decode, - dh_priv_encode, - dh_private_print, - - int_dh_size, - dh_bits, - - dh_param_decode, - dh_param_encode, - dh_missing_parameters, - dh_copy_parameters, - dh_cmp_parameters, - dh_param_print, - 0, - - int_dh_free, - 0 -}; - -const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = { - EVP_PKEY_DHX, - EVP_PKEY_DHX, - 0, - - "X9.42 DH", - "OpenSSL X9.42 DH method", - - dh_pub_decode, - dh_pub_encode, - dh_pub_cmp, - dh_public_print, - - dh_priv_decode, - dh_priv_encode, - dh_private_print, - - int_dh_size, - dh_bits, - - dh_param_decode, - dh_param_encode, - dh_missing_parameters, - dh_copy_parameters, - dh_cmp_parameters, - dh_param_print, - 0, - - int_dh_free, - dh_pkey_ctrl -}; - -#ifndef OPENSSL_NO_CMS - -static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, - X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) -{ - ASN1_OBJECT *aoid; - int atype; - void *aval; - ASN1_INTEGER *public_key = NULL; - int rv = 0; - EVP_PKEY *pkpeer = NULL, *pk = NULL; - DH *dhpeer = NULL; - const unsigned char *p; - int plen; - - X509_ALGOR_get0(&aoid, &atype, &aval, alg); - if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) - goto err; - /* Only absent parameters allowed in RFC XXXX */ - if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL) - goto err; - - pk = EVP_PKEY_CTX_get0_pkey(pctx); - if (!pk) - goto err; - if (pk->type != EVP_PKEY_DHX) - goto err; - /* Get parameters from parent key */ - dhpeer = DHparams_dup(pk->pkey.dh); - /* We have parameters now set public key */ - plen = ASN1_STRING_length(pubkey); - p = ASN1_STRING_data(pubkey); - if (!p || !plen) - goto err; - - if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, plen))) { - DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR); - goto err; - } - - /* We have parameters now set public key */ - if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { - DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR); - goto err; - } - - pkpeer = EVP_PKEY_new(); - if (!pkpeer) - goto err; - EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer); - dhpeer = NULL; - if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) - rv = 1; - err: - if (public_key) - ASN1_INTEGER_free(public_key); - if (pkpeer) - EVP_PKEY_free(pkpeer); - if (dhpeer) - DH_free(dhpeer); - return rv; -} - -static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) -{ - int rv = 0; - - X509_ALGOR *alg, *kekalg = NULL; - ASN1_OCTET_STRING *ukm; - const unsigned char *p; - unsigned char *dukm = NULL; - size_t dukmlen = 0; - int keylen, plen; - const EVP_CIPHER *kekcipher; - EVP_CIPHER_CTX *kekctx; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) - goto err; - - /* - * For DH we only have one OID permissible. If ever any more get defined - * we will need something cleverer. - */ - if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) { - DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR); - goto err; - } - - if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0) - goto err; - - if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0) - goto err; - - if (alg->parameter->type != V_ASN1_SEQUENCE) - goto err; - - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - kekalg = d2i_X509_ALGOR(NULL, &p, plen); - if (!kekalg) - goto err; - kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); - if (!kekctx) - goto err; - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); - if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) - goto err; - if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) - goto err; - if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) - goto err; - - keylen = EVP_CIPHER_CTX_key_length(kekctx); - if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) - goto err; - /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */ - if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, - OBJ_nid2obj(EVP_CIPHER_type(kekcipher))) - <= 0) - goto err; - - if (ukm) { - dukmlen = ASN1_STRING_length(ukm); - dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); - if (!dukm) - goto err; - } - - if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) - goto err; - dukm = NULL; - - rv = 1; - err: - if (kekalg) - X509_ALGOR_free(kekalg); - if (dukm) - OPENSSL_free(dukm); - return rv; -} - -static int dh_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* See if we need to set peer key */ - if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { - X509_ALGOR *alg; - ASN1_BIT_STRING *pubkey; - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, - NULL, NULL, NULL)) - return 0; - if (!alg || !pubkey) - return 0; - if (!dh_cms_set_peerkey(pctx, alg, pubkey)) { - DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR); - return 0; - } - } - /* Set DH derivation parameters and initialise unwrap context */ - if (!dh_cms_set_shared_info(pctx, ri)) { - DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR); - return 0; - } - return 1; -} - -static int dh_cms_encrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - EVP_PKEY *pkey; - EVP_CIPHER_CTX *ctx; - int keylen; - X509_ALGOR *talg, *wrap_alg = NULL; - ASN1_OBJECT *aoid; - ASN1_BIT_STRING *pubkey; - ASN1_STRING *wrap_str; - ASN1_OCTET_STRING *ukm; - unsigned char *penc = NULL, *dukm = NULL; - int penclen; - size_t dukmlen = 0; - int rv = 0; - int kdf_type, wrap_nid; - const EVP_MD *kdf_md; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* Get ephemeral key */ - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, - NULL, NULL, NULL)) - goto err; - X509_ALGOR_get0(&aoid, NULL, NULL, talg); - /* Is everything uninitialised? */ - if (aoid == OBJ_nid2obj(NID_undef)) { - ASN1_INTEGER *pubk; - pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL); - if (!pubk) - goto err; - /* Set the key */ - - penclen = i2d_ASN1_INTEGER(pubk, &penc); - ASN1_INTEGER_free(pubk); - if (penclen <= 0) - goto err; - ASN1_STRING_set0(pubkey, penc, penclen); - pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; - - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber), - V_ASN1_UNDEF, NULL); - } - - /* See if custom paraneters set */ - kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx); - if (kdf_type <= 0) - goto err; - if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md)) - goto err; - - if (kdf_type == EVP_PKEY_DH_KDF_NONE) { - kdf_type = EVP_PKEY_DH_KDF_X9_42; - if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0) - goto err; - } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42) - /* Unknown KDF */ - goto err; - if (kdf_md == NULL) { - /* Only SHA1 supported */ - kdf_md = EVP_sha1(); - if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0) - goto err; - } else if (EVP_MD_type(kdf_md) != NID_sha1) - /* Unsupported digest */ - goto err; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) - goto err; - - /* Get wrap NID */ - ctx = CMS_RecipientInfo_kari_get0_ctx(ri); - wrap_nid = EVP_CIPHER_CTX_type(ctx); - if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0) - goto err; - keylen = EVP_CIPHER_CTX_key_length(ctx); - - /* Package wrap algorithm in an AlgorithmIdentifier */ - - wrap_alg = X509_ALGOR_new(); - if (!wrap_alg) - goto err; - wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); - wrap_alg->parameter = ASN1_TYPE_new(); - if (!wrap_alg->parameter) - goto err; - if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) - goto err; - if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { - ASN1_TYPE_free(wrap_alg->parameter); - wrap_alg->parameter = NULL; - } - - if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - if (ukm) { - dukmlen = ASN1_STRING_length(ukm); - dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen); - if (!dukm) - goto err; - } - - if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) - goto err; - dukm = NULL; - - /* - * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter - * of another AlgorithmIdentifier. - */ - penc = NULL; - penclen = i2d_X509_ALGOR(wrap_alg, &penc); - if (!penc || !penclen) - goto err; - wrap_str = ASN1_STRING_new(); - if (!wrap_str) - goto err; - ASN1_STRING_set0(wrap_str, penc, penclen); - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH), - V_ASN1_SEQUENCE, wrap_str); - - rv = 1; - - err: - if (penc) - OPENSSL_free(penc); - if (wrap_alg) - X509_ALGOR_free(wrap_alg); - return rv; -} - -#endif -/* dh_asn1.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "dh.h" -#include "objects.h" -#include "asn1t.h" - -/* Override the default free and new methods */ -static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_NEW_PRE) { - *pval = (ASN1_VALUE *)DH_new(); - if (*pval) - return 2; - return 0; - } else if (operation == ASN1_OP_FREE_PRE) { - DH_free((DH *)*pval); - *pval = NULL; - return 2; - } - return 1; -} - -ASN1_SEQUENCE_cb(DHparams, dh_cb) = { - ASN1_SIMPLE(DH, p, BIGNUM), - ASN1_SIMPLE(DH, g, BIGNUM), - ASN1_OPT(DH, length, ZLONG), -} ASN1_SEQUENCE_END_cb(DH, DHparams) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams) - -/* - * Internal only structures for handling X9.42 DH: this gets translated to or - * from a DH structure straight away. - */ - -typedef struct { - ASN1_BIT_STRING *seed; - BIGNUM *counter; -} int_dhvparams; - -typedef struct { - BIGNUM *p; - BIGNUM *q; - BIGNUM *g; - BIGNUM *j; - int_dhvparams *vparams; -} int_dhx942_dh; - -ASN1_SEQUENCE(DHvparams) = { - ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING), - ASN1_SIMPLE(int_dhvparams, counter, BIGNUM) -} ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams) - -ASN1_SEQUENCE(DHxparams) = { - ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM), - ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM), - ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM), - ASN1_OPT(int_dhx942_dh, j, BIGNUM), - ASN1_OPT(int_dhx942_dh, vparams, DHvparams), -} ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams) - -int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a, - const unsigned char **pp, long length); -int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp); - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx) - -/* Application leve function: read in X9.42 DH parameters into DH structure */ - -DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length) -{ - int_dhx942_dh *dhx = NULL; - DH *dh = NULL; - dh = DH_new(); - if (!dh) - return NULL; - dhx = d2i_int_dhx(NULL, pp, length); - if (!dhx) { - DH_free(dh); - return NULL; - } - - if (a) { - if (*a) - DH_free(*a); - *a = dh; - } - - dh->p = dhx->p; - dh->q = dhx->q; - dh->g = dhx->g; - dh->j = dhx->j; - - if (dhx->vparams) { - dh->seed = dhx->vparams->seed->data; - dh->seedlen = dhx->vparams->seed->length; - dh->counter = dhx->vparams->counter; - dhx->vparams->seed->data = NULL; - ASN1_BIT_STRING_free(dhx->vparams->seed); - OPENSSL_free(dhx->vparams); - dhx->vparams = NULL; - } - - OPENSSL_free(dhx); - return dh; -} - -int i2d_DHxparams(const DH *dh, unsigned char **pp) -{ - int_dhx942_dh dhx; - int_dhvparams dhv; - ASN1_BIT_STRING bs; - dhx.p = dh->p; - dhx.g = dh->g; - dhx.q = dh->q; - dhx.j = dh->j; - if (dh->counter && dh->seed && dh->seedlen > 0) { - bs.flags = ASN1_STRING_FLAG_BITS_LEFT; - bs.data = dh->seed; - bs.length = dh->seedlen; - dhv.seed = &bs; - dhv.counter = dh->counter; - dhx.vparams = &dhv; - } else - dhx.vparams = NULL; - - return i2d_int_dhx(&dhx, pp); -} -/* crypto/dh/dh_check.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "dh.h" - -/*- - * Check that p is a safe prime and - * if g is 2, 3 or 5, check that it is a suitable generator - * where - * for 2, p mod 24 == 11 - * for 3, p mod 12 == 5 - * for 5, p mod 10 == 3 or 7 - * should hold. - */ - -int DH_check(const DH *dh, int *ret) -{ - int ok = 0; - BN_CTX *ctx = NULL; - BN_ULONG l; - BIGNUM *t1 = NULL, *t2 = NULL; - - *ret = 0; - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - if (t1 == NULL) - goto err; - t2 = BN_CTX_get(ctx); - if (t2 == NULL) - goto err; - - if (dh->q) { - if (BN_cmp(dh->g, BN_value_one()) <= 0) - *ret |= DH_NOT_SUITABLE_GENERATOR; - else if (BN_cmp(dh->g, dh->p) >= 0) - *ret |= DH_NOT_SUITABLE_GENERATOR; - else { - /* Check g^q == 1 mod p */ - if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx)) - goto err; - if (!BN_is_one(t1)) - *ret |= DH_NOT_SUITABLE_GENERATOR; - } - if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL)) - *ret |= DH_CHECK_Q_NOT_PRIME; - /* Check p == 1 mod q i.e. q divides p - 1 */ - if (!BN_div(t1, t2, dh->p, dh->q, ctx)) - goto err; - if (!BN_is_one(t2)) - *ret |= DH_CHECK_INVALID_Q_VALUE; - if (dh->j && BN_cmp(dh->j, t1)) - *ret |= DH_CHECK_INVALID_J_VALUE; - - } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { - l = BN_mod_word(dh->p, 24); - if (l != 11) - *ret |= DH_NOT_SUITABLE_GENERATOR; - } -#if 0 - else if (BN_is_word(dh->g, DH_GENERATOR_3)) { - l = BN_mod_word(dh->p, 12); - if (l != 5) - *ret |= DH_NOT_SUITABLE_GENERATOR; - } -#endif - else if (BN_is_word(dh->g, DH_GENERATOR_5)) { - l = BN_mod_word(dh->p, 10); - if ((l != 3) && (l != 7)) - *ret |= DH_NOT_SUITABLE_GENERATOR; - } else - *ret |= DH_UNABLE_TO_CHECK_GENERATOR; - - if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL)) - *ret |= DH_CHECK_P_NOT_PRIME; - else if (!dh->q) { - if (!BN_rshift1(t1, dh->p)) - goto err; - if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL)) - *ret |= DH_CHECK_P_NOT_SAFE_PRIME; - } - ok = 1; - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return (ok); -} - -int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) -{ - int ok = 0; - BIGNUM *tmp = NULL; - BN_CTX *ctx = NULL; - - *ret = 0; - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - if (tmp == NULL || !BN_set_word(tmp, 1)) - goto err; - if (BN_cmp(pub_key, tmp) <= 0) - *ret |= DH_CHECK_PUBKEY_TOO_SMALL; - if (BN_copy(tmp, dh->p) == NULL || !BN_sub_word(tmp, 1)) - goto err; - if (BN_cmp(pub_key, tmp) >= 0) - *ret |= DH_CHECK_PUBKEY_TOO_LARGE; - - if (dh->q != NULL) { - /* Check pub_key^q == 1 mod p */ - if (!BN_mod_exp(tmp, pub_key, dh->q, dh->p, ctx)) - goto err; - if (!BN_is_one(tmp)) - *ret |= DH_CHECK_PUBKEY_INVALID; - } - - ok = 1; - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return (ok); -} -/* crypto/dh/dh_depr.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* This file contains deprecated functions as wrappers to the new ones */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "dh.h" - -static void *dummy = &dummy; - -#ifndef OPENSSL_NO_DEPRECATED -DH *DH_generate_parameters(int prime_len, int generator, - void (*callback) (int, int, void *), void *cb_arg) -{ - BN_GENCB cb; - DH *ret = NULL; - - if ((ret = DH_new()) == NULL) - return NULL; - - BN_GENCB_set_old(&cb, callback, cb_arg); - - if (DH_generate_parameters_ex(ret, prime_len, generator, &cb)) - return ret; - DH_free(ret); - return NULL; -} -#endif -/* crypto/dh/dh_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "dh.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason) - -static ERR_STRING_DATA DH_str_functs[] = { - {ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"}, - {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"}, - {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, - {ERR_FUNC(DH_F_DH_CMS_DECRYPT), "DH_CMS_DECRYPT"}, - {ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "DH_CMS_SET_PEERKEY"}, - {ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "DH_CMS_SET_SHARED_INFO"}, - {ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"}, - {ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"}, - {ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS_EX), "DH_generate_parameters_ex"}, - {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"}, - {ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"}, - {ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"}, - {ERR_FUNC(DH_F_DH_PRIV_ENCODE), "DH_PRIV_ENCODE"}, - {ERR_FUNC(DH_F_DH_PUB_DECODE), "DH_PUB_DECODE"}, - {ERR_FUNC(DH_F_DH_PUB_ENCODE), "DH_PUB_ENCODE"}, - {ERR_FUNC(DH_F_DO_DH_PRINT), "DO_DH_PRINT"}, - {ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"}, - {ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"}, - {ERR_FUNC(DH_F_PKEY_DH_DERIVE), "PKEY_DH_DERIVE"}, - {ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "PKEY_DH_KEYGEN"}, - {0, NULL} -}; - -static ERR_STRING_DATA DH_str_reasons[] = { - {ERR_REASON(DH_R_BAD_GENERATOR), "bad generator"}, - {ERR_REASON(DH_R_BN_DECODE_ERROR), "bn decode error"}, - {ERR_REASON(DH_R_BN_ERROR), "bn error"}, - {ERR_REASON(DH_R_DECODE_ERROR), "decode error"}, - {ERR_REASON(DH_R_INVALID_PUBKEY), "invalid public key"}, - {ERR_REASON(DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, - {ERR_REASON(DH_R_KEYS_NOT_SET), "keys not set"}, - {ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL), "key size too small"}, - {ERR_REASON(DH_R_MODULUS_TOO_LARGE), "modulus too large"}, - {ERR_REASON(DH_R_NON_FIPS_METHOD), "non fips method"}, - {ERR_REASON(DH_R_NO_PARAMETERS_SET), "no parameters set"}, - {ERR_REASON(DH_R_NO_PRIVATE_VALUE), "no private value"}, - {ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, - {ERR_REASON(DH_R_PEER_KEY_ERROR), "peer key error"}, - {ERR_REASON(DH_R_SHARED_INFO_ERROR), "shared info error"}, - {0, NULL} -}; - -#endif - -void ERR_load_DH_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(DH_str_functs[0].error) == NULL) { - ERR_load_strings(0, DH_str_functs); - ERR_load_strings(0, DH_str_reasons); - } -#endif -} -/* crypto/dh/dh_gen.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * NB: These functions have been upgraded - the previous prototypes are in - * dh_depr.c as wrappers to these ones. - Geoff - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "dh.h" - -#ifdef OPENSSL_FIPS -# include -#endif - -static int dh_builtin_genparams(DH *ret, int prime_len, int generator, - BN_GENCB *cb); - -int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, - BN_GENCB *cb) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(ret->meth->flags & DH_FLAG_FIPS_METHOD) - && !(ret->flags & DH_FLAG_NON_FIPS_ALLOW)) { - DHerr(DH_F_DH_GENERATE_PARAMETERS_EX, DH_R_NON_FIPS_METHOD); - return 0; - } -#endif - if (ret->meth->generate_params) - return ret->meth->generate_params(ret, prime_len, generator, cb); -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dh_generate_parameters_ex(ret, prime_len, generator, cb); -#endif - return dh_builtin_genparams(ret, prime_len, generator, cb); -} - -/*- - * We generate DH parameters as follows - * find a prime q which is prime_len/2 bits long. - * p=(2*q)+1 or (p-1)/2 = q - * For this case, g is a generator if - * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. - * Since the factors of p-1 are q and 2, we just need to check - * g^2 mod p != 1 and g^q mod p != 1. - * - * Having said all that, - * there is another special case method for the generators 2, 3 and 5. - * for 2, p mod 24 == 11 - * for 3, p mod 12 == 5 <<<<< does not work for safe primes. - * for 5, p mod 10 == 3 or 7 - * - * Thanks to Phil Karn for the pointers about the - * special generators and for answering some of my questions. - * - * I've implemented the second simple method :-). - * Since DH should be using a safe prime (both p and q are prime), - * this generator function can take a very very long time to run. - */ -/* - * Actually there is no reason to insist that 'generator' be a generator. - * It's just as OK (and in some sense better) to use a generator of the - * order-q subgroup. - */ -static int dh_builtin_genparams(DH *ret, int prime_len, int generator, - BN_GENCB *cb) -{ - BIGNUM *t1, *t2; - int g, ok = -1; - BN_CTX *ctx = NULL; - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - t2 = BN_CTX_get(ctx); - if (t1 == NULL || t2 == NULL) - goto err; - - /* Make sure 'ret' has the necessary elements */ - if (!ret->p && ((ret->p = BN_new()) == NULL)) - goto err; - if (!ret->g && ((ret->g = BN_new()) == NULL)) - goto err; - - if (generator <= 1) { - DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); - goto err; - } - if (generator == DH_GENERATOR_2) { - if (!BN_set_word(t1, 24)) - goto err; - if (!BN_set_word(t2, 11)) - goto err; - g = 2; - } -#if 0 /* does not work for safe primes */ - else if (generator == DH_GENERATOR_3) { - if (!BN_set_word(t1, 12)) - goto err; - if (!BN_set_word(t2, 5)) - goto err; - g = 3; - } -#endif - else if (generator == DH_GENERATOR_5) { - if (!BN_set_word(t1, 10)) - goto err; - if (!BN_set_word(t2, 3)) - goto err; - /* - * BN_set_word(t3,7); just have to miss out on these ones :-( - */ - g = 5; - } else { - /* - * in the general case, don't worry if 'generator' is a generator or - * not: since we are using safe primes, it will generate either an - * order-q or an order-2q group, which both is OK - */ - if (!BN_set_word(t1, 2)) - goto err; - if (!BN_set_word(t2, 1)) - goto err; - g = generator; - } - - if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb)) - goto err; - if (!BN_GENCB_call(cb, 3, 0)) - goto err; - if (!BN_set_word(ret->g, g)) - goto err; - ok = 1; - err: - if (ok == -1) { - DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB); - ok = 0; - } - - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return ok; -} -/* crypto/dh/dh_kdf.c */ -/* - * Written by Stephen Henson for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "e_os.h" - -#ifndef OPENSSL_NO_CMS -#include -// #include "dh.h" -#include "evp.h" -// #include "asn1.h" -#include "cms.h" - -/* Key derivation from X9.42/RFC2631 */ - -#define DH_KDF_MAX (1L << 30) - -/* Skip past an ASN1 structure: for OBJECT skip content octets too */ - -static int skip_asn1(unsigned char **pp, long *plen, int exptag) -{ - const unsigned char *q = *pp; - int i, tag, xclass; - long tmplen; - i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen); - if (i & 0x80) - return 0; - if (tag != exptag || xclass != V_ASN1_UNIVERSAL) - return 0; - if (tag == V_ASN1_OBJECT) - q += tmplen; - *plen -= q - *pp; - *pp = (unsigned char *)q; - return 1; -} - -/* - * Encode the DH shared info structure, return an offset to the counter value - * so we can update the structure without reencoding it. - */ - -static int dh_sharedinfo_encode(unsigned char **pder, unsigned char **pctr, - ASN1_OBJECT *key_oid, size_t outlen, - const unsigned char *ukm, size_t ukmlen) -{ - unsigned char *p; - int derlen; - long tlen; - /* "magic" value to check offset is sane */ - static unsigned char ctr[4] = { 0xF3, 0x17, 0x22, 0x53 }; - X509_ALGOR atmp; - ASN1_OCTET_STRING ctr_oct, ukm_oct, *pukm_oct; - ASN1_TYPE ctr_atype; - if (ukmlen > DH_KDF_MAX || outlen > DH_KDF_MAX) - return 0; - ctr_oct.data = ctr; - ctr_oct.length = 4; - ctr_oct.flags = 0; - ctr_oct.type = V_ASN1_OCTET_STRING; - ctr_atype.type = V_ASN1_OCTET_STRING; - ctr_atype.value.octet_string = &ctr_oct; - atmp.algorithm = key_oid; - atmp.parameter = &ctr_atype; - if (ukm) { - ukm_oct.type = V_ASN1_OCTET_STRING; - ukm_oct.flags = 0; - ukm_oct.data = (unsigned char *)ukm; - ukm_oct.length = ukmlen; - pukm_oct = &ukm_oct; - } else - pukm_oct = NULL; - derlen = CMS_SharedInfo_encode(pder, &atmp, pukm_oct, outlen); - if (derlen <= 0) - return 0; - p = *pder; - tlen = derlen; - if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)) - return 0; - if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE)) - return 0; - if (!skip_asn1(&p, &tlen, V_ASN1_OBJECT)) - return 0; - if (!skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING)) - return 0; - if (CRYPTO_memcmp(p, ctr, 4)) - return 0; - *pctr = p; - return derlen; -} - -int DH_KDF_X9_42(unsigned char *out, size_t outlen, - const unsigned char *Z, size_t Zlen, - ASN1_OBJECT *key_oid, - const unsigned char *ukm, size_t ukmlen, const EVP_MD *md) -{ - EVP_MD_CTX mctx; - int rv = 0; - unsigned int i; - size_t mdlen; - unsigned char *der = NULL, *ctr; - int derlen; - if (Zlen > DH_KDF_MAX) - return 0; - mdlen = EVP_MD_size(md); - EVP_MD_CTX_init(&mctx); - derlen = dh_sharedinfo_encode(&der, &ctr, key_oid, outlen, ukm, ukmlen); - if (derlen == 0) - goto err; - for (i = 1;; i++) { - unsigned char mtmp[EVP_MAX_MD_SIZE]; - EVP_DigestInit_ex(&mctx, md, NULL); - if (!EVP_DigestUpdate(&mctx, Z, Zlen)) - goto err; - ctr[3] = i & 0xFF; - ctr[2] = (i >> 8) & 0xFF; - ctr[1] = (i >> 16) & 0xFF; - ctr[0] = (i >> 24) & 0xFF; - if (!EVP_DigestUpdate(&mctx, der, derlen)) - goto err; - if (outlen >= mdlen) { - if (!EVP_DigestFinal(&mctx, out, NULL)) - goto err; - outlen -= mdlen; - if (outlen == 0) - break; - out += mdlen; - } else { - if (!EVP_DigestFinal(&mctx, mtmp, NULL)) - goto err; - memcpy(out, mtmp, outlen); - OPENSSL_cleanse(mtmp, mdlen); - break; - } - } - rv = 1; - err: - if (der) - OPENSSL_free(der); - EVP_MD_CTX_cleanup(&mctx); - return rv; -} -#endif -/* crypto/dh/dh_key.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -#include "rand.h" -// #include "dh.h" - -static int generate_key(DH *dh); -static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); -static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -static int dh_init(DH *dh); -static int dh_finish(DH *dh); - -int DH_generate_key(DH *dh) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) - && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { - DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD); - return 0; - } -#endif - return dh->meth->generate_key(dh); -} - -int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) - && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { - DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD); - return 0; - } -#endif - return dh->meth->compute_key(key, pub_key, dh); -} - -int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh) -{ - int rv, pad; - rv = dh->meth->compute_key(key, pub_key, dh); - if (rv <= 0) - return rv; - pad = BN_num_bytes(dh->p) - rv; - if (pad > 0) { - memmove(key + pad, key, rv); - memset(key, 0, pad); - } - return rv + pad; -} - -static DH_METHOD dh_ossl = { - "OpenSSL DH Method", - generate_key, - compute_key, - dh_bn_mod_exp, - dh_init, - dh_finish, - 0, - NULL, - NULL -}; - -const DH_METHOD *DH_OpenSSL(void) -{ - return &dh_ossl; -} - -static int generate_key(DH *dh) -{ - int ok = 0; - int generate_new_key = 0; - unsigned l; - BN_CTX *ctx = NULL; - BN_MONT_CTX *mont = NULL; - BIGNUM *pub_key = NULL, *priv_key = NULL; - - if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { - DHerr(DH_F_GENERATE_KEY, DH_R_MODULUS_TOO_LARGE); - return 0; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - - if (dh->priv_key == NULL) { - priv_key = BN_new(); - if (priv_key == NULL) - goto err; - generate_new_key = 1; - } else - priv_key = dh->priv_key; - - if (dh->pub_key == NULL) { - pub_key = BN_new(); - if (pub_key == NULL) - goto err; - } else - pub_key = dh->pub_key; - - if (dh->flags & DH_FLAG_CACHE_MONT_P) { - mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, - CRYPTO_LOCK_DH, dh->p, ctx); - if (!mont) - goto err; - } - - if (generate_new_key) { - if (dh->q) { - do { - if (!BN_rand_range(priv_key, dh->q)) - goto err; - } - while (BN_is_zero(priv_key) || BN_is_one(priv_key)); - } else { - /* secret exponent length */ - l = dh->length ? dh->length : BN_num_bits(dh->p) - 1; - if (!BN_rand(priv_key, l, 0, 0)) - goto err; - } - } - - { - BIGNUM local_prk; - BIGNUM *prk; - - if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { - BN_init(&local_prk); - prk = &local_prk; - BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); - } else - prk = priv_key; - - if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) - goto err; - } - - dh->pub_key = pub_key; - dh->priv_key = priv_key; - ok = 1; - err: - if (ok != 1) - DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB); - - if ((pub_key != NULL) && (dh->pub_key == NULL)) - BN_free(pub_key); - if ((priv_key != NULL) && (dh->priv_key == NULL)) - BN_free(priv_key); - BN_CTX_free(ctx); - return (ok); -} - -static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) -{ - BN_CTX *ctx = NULL; - BN_MONT_CTX *mont = NULL; - BIGNUM *tmp; - int ret = -1; - int check_result; - - if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { - DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); - goto err; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - if (tmp == NULL) - goto err; - - if (dh->priv_key == NULL) { - DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE); - goto err; - } - - if (dh->flags & DH_FLAG_CACHE_MONT_P) { - mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, - CRYPTO_LOCK_DH, dh->p, ctx); - if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { - /* XXX */ - BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); - } - if (!mont) - goto err; - } - - if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) { - DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY); - goto err; - } - - if (!dh-> - meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) { - DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB); - goto err; - } - - ret = BN_bn2bin(tmp, key); - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return (ret); -} - -static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - /* - * If a is only one word long and constant time is false, use the faster - * exponenentiation function. - */ - if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0)) { - BN_ULONG A = a->d[0]; - return BN_mod_exp_mont_word(r, A, p, m, ctx, m_ctx); - } else - return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); -} - -static int dh_init(DH *dh) -{ - dh->flags |= DH_FLAG_CACHE_MONT_P; - return (1); -} - -static int dh_finish(DH *dh) -{ - if (dh->method_mont_p) - BN_MONT_CTX_free(dh->method_mont_p); - return (1); -} -/* crypto/dh/dh_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "dh.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -#ifdef OPENSSL_FIPS -# include -#endif - -const char DH_version[] = "Diffie-Hellman" OPENSSL_VERSION_PTEXT; - -static const DH_METHOD *default_DH_method = NULL; - -void DH_set_default_method(const DH_METHOD *meth) -{ - default_DH_method = meth; -} - -const DH_METHOD *DH_get_default_method(void) -{ - if (!default_DH_method) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dh_openssl(); - else - return DH_OpenSSL(); -#else - default_DH_method = DH_OpenSSL(); -#endif - } - return default_DH_method; -} - -int DH_set_method(DH *dh, const DH_METHOD *meth) -{ - /* - * NB: The caller is specifically setting a method, so it's not up to us - * to deal with which ENGINE it comes from. - */ - const DH_METHOD *mtmp; - mtmp = dh->meth; - if (mtmp->finish) - mtmp->finish(dh); -#ifndef OPENSSL_NO_ENGINE - if (dh->engine) { - ENGINE_finish(dh->engine); - dh->engine = NULL; - } -#endif - dh->meth = meth; - if (meth->init) - meth->init(dh); - return 1; -} - -DH *DH_new(void) -{ - return DH_new_method(NULL); -} - -DH *DH_new_method(ENGINE *engine) -{ - DH *ret; - - ret = (DH *)OPENSSL_malloc(sizeof(DH)); - if (ret == NULL) { - DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - ret->meth = DH_get_default_method(); -#ifndef OPENSSL_NO_ENGINE - if (engine) { - if (!ENGINE_init(engine)) { - DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); - OPENSSL_free(ret); - return NULL; - } - ret->engine = engine; - } else - ret->engine = ENGINE_get_default_DH(); - if (ret->engine) { - ret->meth = ENGINE_get_DH(ret->engine); - if (!ret->meth) { - DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); - ENGINE_finish(ret->engine); - OPENSSL_free(ret); - return NULL; - } - } -#endif - - ret->pad = 0; - ret->version = 0; - ret->p = NULL; - ret->g = NULL; - ret->length = 0; - ret->pub_key = NULL; - ret->priv_key = NULL; - ret->q = NULL; - ret->j = NULL; - ret->seed = NULL; - ret->seedlen = 0; - ret->counter = NULL; - ret->method_mont_p = NULL; - ret->references = 1; - ret->flags = ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW; - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); - OPENSSL_free(ret); - ret = NULL; - } - return (ret); -} - -void DH_free(DH *r) -{ - int i; - if (r == NULL) - return; - i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH); -#ifdef REF_PRINT - REF_PRINT("DH", r); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "DH_free, bad reference count\n"); - abort(); - } -#endif - - if (r->meth->finish) - r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE - if (r->engine) - ENGINE_finish(r->engine); -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); - - if (r->p != NULL) - BN_clear_free(r->p); - if (r->g != NULL) - BN_clear_free(r->g); - if (r->q != NULL) - BN_clear_free(r->q); - if (r->j != NULL) - BN_clear_free(r->j); - if (r->seed) - OPENSSL_free(r->seed); - if (r->counter != NULL) - BN_clear_free(r->counter); - if (r->pub_key != NULL) - BN_clear_free(r->pub_key); - if (r->priv_key != NULL) - BN_clear_free(r->priv_key); - OPENSSL_free(r); -} - -int DH_up_ref(DH *r) -{ - int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH); -#ifdef REF_PRINT - REF_PRINT("DH", r); -#endif -#ifdef REF_CHECK - if (i < 2) { - fprintf(stderr, "DH_up, bad reference count\n"); - abort(); - } -#endif - return ((i > 1) ? 1 : 0); -} - -int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp, - new_func, dup_func, free_func); -} - -int DH_set_ex_data(DH *d, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&d->ex_data, idx, arg)); -} - -void *DH_get_ex_data(DH *d, int idx) -{ - return (CRYPTO_get_ex_data(&d->ex_data, idx)); -} - -int DH_size(const DH *dh) -{ - return (BN_num_bytes(dh->p)); -} -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" -// #include "evp.h" -// #include "dh.h" -// #include "bn.h" -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -// #include "objects.h" -#include "evp_locl.h" - -/* DH pkey context structure */ - -typedef struct { - /* Parameter gen parameters */ - int prime_len; - int generator; - int use_dsa; - int subprime_len; - /* message digest used for parameter generation */ - const EVP_MD *md; - int rfc5114_param; - /* Keygen callback info */ - int gentmp[2]; - /* KDF (if any) to use for DH */ - char kdf_type; - /* OID to use for KDF */ - ASN1_OBJECT *kdf_oid; - /* Message digest to use for key derivation */ - const EVP_MD *kdf_md; - /* User key material */ - unsigned char *kdf_ukm; - size_t kdf_ukmlen; - /* KDF output length */ - size_t kdf_outlen; -} DH_PKEY_CTX; - -static int pkey_dh_init(EVP_PKEY_CTX *ctx) -{ - DH_PKEY_CTX *dctx; - dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX)); - if (!dctx) - return 0; - dctx->prime_len = 1024; - dctx->subprime_len = -1; - dctx->generator = 2; - dctx->use_dsa = 0; - dctx->md = NULL; - dctx->rfc5114_param = 0; - - dctx->kdf_type = EVP_PKEY_DH_KDF_NONE; - dctx->kdf_oid = NULL; - dctx->kdf_md = NULL; - dctx->kdf_ukm = NULL; - dctx->kdf_ukmlen = 0; - dctx->kdf_outlen = 0; - - ctx->data = dctx; - ctx->keygen_info = dctx->gentmp; - ctx->keygen_info_count = 2; - - return 1; -} - -static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - DH_PKEY_CTX *dctx, *sctx; - if (!pkey_dh_init(dst)) - return 0; - sctx = src->data; - dctx = dst->data; - dctx->prime_len = sctx->prime_len; - dctx->subprime_len = sctx->subprime_len; - dctx->generator = sctx->generator; - dctx->use_dsa = sctx->use_dsa; - dctx->md = sctx->md; - dctx->rfc5114_param = sctx->rfc5114_param; - - dctx->kdf_type = sctx->kdf_type; - dctx->kdf_oid = OBJ_dup(sctx->kdf_oid); - if (!dctx->kdf_oid) - return 0; - dctx->kdf_md = sctx->kdf_md; - if (dctx->kdf_ukm) { - dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); - dctx->kdf_ukmlen = sctx->kdf_ukmlen; - } - dctx->kdf_outlen = sctx->kdf_outlen; - return 1; -} - -static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) -{ - DH_PKEY_CTX *dctx = ctx->data; - if (dctx) { - if (dctx->kdf_ukm) - OPENSSL_free(dctx->kdf_ukm); - if (dctx->kdf_oid) - ASN1_OBJECT_free(dctx->kdf_oid); - OPENSSL_free(dctx); - } -} - -static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - DH_PKEY_CTX *dctx = ctx->data; - switch (type) { - case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: - if (p1 < 256) - return -2; - dctx->prime_len = p1; - return 1; - - case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN: - if (dctx->use_dsa == 0) - return -2; - dctx->subprime_len = p1; - return 1; - - case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: - if (dctx->use_dsa) - return -2; - dctx->generator = p1; - return 1; - - case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE: -#ifdef OPENSSL_NO_DSA - if (p1 != 0) - return -2; -#else - if (p1 < 0 || p1 > 2) - return -2; -#endif - dctx->use_dsa = p1; - return 1; - - case EVP_PKEY_CTRL_DH_RFC5114: - if (p1 < 1 || p1 > 3) - return -2; - dctx->rfc5114_param = p1; - return 1; - - case EVP_PKEY_CTRL_PEER_KEY: - /* Default behaviour is OK */ - return 1; - - case EVP_PKEY_CTRL_DH_KDF_TYPE: - if (p1 == -2) - return dctx->kdf_type; -#ifdef OPENSSL_NO_CMS - if (p1 != EVP_PKEY_DH_KDF_NONE) -#else - if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42) -#endif - return -2; - dctx->kdf_type = p1; - return 1; - - case EVP_PKEY_CTRL_DH_KDF_MD: - dctx->kdf_md = p2; - return 1; - - case EVP_PKEY_CTRL_GET_DH_KDF_MD: - *(const EVP_MD **)p2 = dctx->kdf_md; - return 1; - - case EVP_PKEY_CTRL_DH_KDF_OUTLEN: - if (p1 <= 0) - return -2; - dctx->kdf_outlen = (size_t)p1; - return 1; - - case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN: - *(int *)p2 = dctx->kdf_outlen; - return 1; - - case EVP_PKEY_CTRL_DH_KDF_UKM: - if (dctx->kdf_ukm) - OPENSSL_free(dctx->kdf_ukm); - dctx->kdf_ukm = p2; - if (p2) - dctx->kdf_ukmlen = p1; - else - dctx->kdf_ukmlen = 0; - return 1; - - case EVP_PKEY_CTRL_GET_DH_KDF_UKM: - *(unsigned char **)p2 = dctx->kdf_ukm; - return dctx->kdf_ukmlen; - - case EVP_PKEY_CTRL_DH_KDF_OID: - if (dctx->kdf_oid) - ASN1_OBJECT_free(dctx->kdf_oid); - dctx->kdf_oid = p2; - return 1; - - case EVP_PKEY_CTRL_GET_DH_KDF_OID: - *(ASN1_OBJECT **)p2 = dctx->kdf_oid; - return 1; - - default: - return -2; - - } -} - -static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!strcmp(type, "dh_paramgen_prime_len")) { - int len; - len = atoi(value); - return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); - } - if (!strcmp(type, "dh_rfc5114")) { - DH_PKEY_CTX *dctx = ctx->data; - int len; - len = atoi(value); - if (len < 0 || len > 3) - return -2; - dctx->rfc5114_param = len; - return 1; - } - if (!strcmp(type, "dh_paramgen_generator")) { - int len; - len = atoi(value); - return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len); - } - if (!strcmp(type, "dh_paramgen_subprime_len")) { - int len; - len = atoi(value); - return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len); - } - if (!strcmp(type, "dh_paramgen_type")) { - int typ; - typ = atoi(value); - return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ); - } - return -2; -} - -#ifndef OPENSSL_NO_DSA - -extern int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, - const EVP_MD *evpmd, - const unsigned char *seed_in, size_t seed_len, - unsigned char *seed_out, int *counter_ret, - unsigned long *h_ret, BN_GENCB *cb); - -extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, - const unsigned char *seed_in, - size_t seed_len, int idx, - unsigned char *seed_out, int *counter_ret, - unsigned long *h_ret, BN_GENCB *cb); - -static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb) -{ - DSA *ret; - int rv = 0; - int prime_len = dctx->prime_len; - int subprime_len = dctx->subprime_len; - const EVP_MD *md = dctx->md; - if (dctx->use_dsa > 2) - return NULL; - ret = DSA_new(); - if (!ret) - return NULL; - if (subprime_len == -1) { - if (prime_len >= 2048) - subprime_len = 256; - else - subprime_len = 160; - } - if (md == NULL) { - if (prime_len >= 2048) - md = EVP_sha256(); - else - md = EVP_sha1(); - } - if (dctx->use_dsa == 1) - rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md, - NULL, 0, NULL, NULL, NULL, pcb); - else if (dctx->use_dsa == 2) - rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md, - NULL, 0, -1, NULL, NULL, NULL, pcb); - if (rv <= 0) { - DSA_free(ret); - return NULL; - } - return ret; -} - -#endif - -static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - DH *dh = NULL; - DH_PKEY_CTX *dctx = ctx->data; - BN_GENCB *pcb, cb; - int ret; - if (dctx->rfc5114_param) { - switch (dctx->rfc5114_param) { - case 1: - dh = DH_get_1024_160(); - break; - - case 2: - dh = DH_get_2048_224(); - break; - - case 3: - dh = DH_get_2048_256(); - break; - - default: - return -2; - } - EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); - return 1; - } - - if (ctx->pkey_gencb) { - pcb = &cb; - evp_pkey_set_cb_translate(pcb, ctx); - } else - pcb = NULL; -#ifndef OPENSSL_NO_DSA - if (dctx->use_dsa) { - DSA *dsa_dh; - dsa_dh = dsa_dh_generate(dctx, pcb); - if (!dsa_dh) - return 0; - dh = DSA_dup_DH(dsa_dh); - DSA_free(dsa_dh); - if (!dh) - return 0; - EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh); - return 1; - } -#endif - dh = DH_new(); - if (!dh) - return 0; - ret = DH_generate_parameters_ex(dh, - dctx->prime_len, dctx->generator, pcb); - - if (ret) - EVP_PKEY_assign_DH(pkey, dh); - else - DH_free(dh); - return ret; -} - -static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - DH *dh = NULL; - if (ctx->pkey == NULL) { - DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); - return 0; - } - dh = DH_new(); - if (!dh) - return 0; - EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh); - /* Note: if error return, pkey is freed by parent routine */ - if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) - return 0; - return DH_generate_key(pkey->pkey.dh); -} - -static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) -{ - int ret; - DH *dh; - DH_PKEY_CTX *dctx = ctx->data; - BIGNUM *dhpub; - if (!ctx->pkey || !ctx->peerkey) { - DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); - return 0; - } - dh = ctx->pkey->pkey.dh; - dhpub = ctx->peerkey->pkey.dh->pub_key; - if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) { - if (key == NULL) { - *keylen = DH_size(dh); - return 1; - } - ret = DH_compute_key(key, dhpub, dh); - if (ret < 0) - return ret; - *keylen = ret; - return 1; - } -#ifndef OPENSSL_NO_CMS - else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) { - unsigned char *Z = NULL; - size_t Zlen = 0; - if (!dctx->kdf_outlen || !dctx->kdf_oid) - return 0; - if (key == NULL) { - *keylen = dctx->kdf_outlen; - return 1; - } - if (*keylen != dctx->kdf_outlen) - return 0; - ret = 0; - Zlen = DH_size(dh); - Z = OPENSSL_malloc(Zlen); - if (!Z) { - goto err; - } - if (DH_compute_key_padded(Z, dhpub, dh) <= 0) - goto err; - if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid, - dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) - goto err; - *keylen = dctx->kdf_outlen; - ret = 1; - err: - if (Z) { - OPENSSL_cleanse(Z, Zlen); - OPENSSL_free(Z); - } - return ret; - } -#endif - return 0; -} - -const EVP_PKEY_METHOD dh_pkey_meth = { - EVP_PKEY_DH, - 0, - pkey_dh_init, - pkey_dh_copy, - pkey_dh_cleanup, - - 0, - pkey_dh_paramgen, - - 0, - pkey_dh_keygen, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, - pkey_dh_derive, - - pkey_dh_ctrl, - pkey_dh_ctrl_str -}; - -const EVP_PKEY_METHOD dhx_pkey_meth = { - EVP_PKEY_DHX, - 0, - pkey_dh_init, - pkey_dh_copy, - pkey_dh_cleanup, - - 0, - pkey_dh_paramgen, - - 0, - pkey_dh_keygen, - - 0, - 0, - - 0, - 0, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, - pkey_dh_derive, - - pkey_dh_ctrl, - pkey_dh_ctrl_str -}; -/* crypto/asn1/t_pkey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "dh.h" - -#ifndef OPENSSL_NO_FP_API -int DHparams_print_fp(FILE *fp, const DH *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = DHparams_print(b, x); - BIO_free(b); - return (ret); -} -#endif -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2011. - */ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "dh.h" -// #include "bn.h" - -/* DH parameters from RFC5114 */ - -#if BN_BITS2 == 64 -static const BN_ULONG dh1024_160_p[] = { - 0xDF1FB2BC2E4A4371ULL, 0xE68CFDA76D4DA708ULL, 0x45BF37DF365C1A65ULL, - 0xA151AF5F0DC8B4BDULL, 0xFAA31A4FF55BCCC0ULL, 0x4EFFD6FAE5644738ULL, - 0x98488E9C219A7372ULL, 0xACCBDD7D90C4BD70ULL, 0x24975C3CD49B83BFULL, - 0x13ECB4AEA9061123ULL, 0x9838EF1E2EE652C0ULL, 0x6073E28675A23D18ULL, - 0x9A6A9DCA52D23B61ULL, 0x52C99FBCFB06A3C6ULL, 0xDE92DE5EAE5D54ECULL, - 0xB10B8F96A080E01DULL -}; - -static const BN_ULONG dh1024_160_g[] = { - 0x855E6EEB22B3B2E5ULL, 0x858F4DCEF97C2A24ULL, 0x2D779D5918D08BC8ULL, - 0xD662A4D18E73AFA3ULL, 0x1DBF0A0169B6A28AULL, 0xA6A24C087A091F53ULL, - 0x909D0D2263F80A76ULL, 0xD7FBD7D3B9A92EE1ULL, 0x5E91547F9E2749F4ULL, - 0x160217B4B01B886AULL, 0x777E690F5504F213ULL, 0x266FEA1E5C41564BULL, - 0xD6406CFF14266D31ULL, 0xF8104DD258AC507FULL, 0x6765A442EFB99905ULL, - 0xA4D1CBD5C3FD3412ULL -}; - -static const BN_ULONG dh1024_160_q[] = { - 0x64B7CB9D49462353ULL, 0x81A8DF278ABA4E7DULL, 0x00000000F518AA87ULL -}; - -static const BN_ULONG dh2048_224_p[] = { - 0x0AC4DFFE0C10E64FULL, 0xCF9DE5384E71B81CULL, 0x7EF363E2FFA31F71ULL, - 0xE3FB73C16B8E75B9ULL, 0xC9B53DCF4BA80A29ULL, 0x23F10B0E16E79763ULL, - 0xC52172E413042E9BULL, 0xBE60E69CC928B2B9ULL, 0x80CD86A1B9E587E8ULL, - 0x315D75E198C641A4ULL, 0xCDF93ACC44328387ULL, 0x15987D9ADC0A486DULL, - 0x7310F7121FD5A074ULL, 0x278273C7DE31EFDCULL, 0x1602E714415D9330ULL, - 0x81286130BC8985DBULL, 0xB3BF8A3170918836ULL, 0x6A00E0A0B9C49708ULL, - 0xC6BA0B2C8BBC27BEULL, 0xC9F98D11ED34DBF6ULL, 0x7AD5B7D0B6C12207ULL, - 0xD91E8FEF55B7394BULL, 0x9037C9EDEFDA4DF8ULL, 0x6D3F8152AD6AC212ULL, - 0x1DE6B85A1274A0A6ULL, 0xEB3D688A309C180EULL, 0xAF9A3C407BA1DF15ULL, - 0xE6FA141DF95A56DBULL, 0xB54B1597B61D0A75ULL, 0xA20D64E5683B9FD1ULL, - 0xD660FAA79559C51FULL, 0xAD107E1E9123A9D0ULL -}; - -static const BN_ULONG dh2048_224_g[] = { - 0x84B890D3191F2BFAULL, 0x81BC087F2A7065B3ULL, 0x19C418E1F6EC0179ULL, - 0x7B5A0F1C71CFFF4CULL, 0xEDFE72FE9B6AA4BDULL, 0x81E1BCFE94B30269ULL, - 0x566AFBB48D6C0191ULL, 0xB539CCE3409D13CDULL, 0x6AA21E7F5F2FF381ULL, - 0xD9E263E4770589EFULL, 0x10E183EDD19963DDULL, 0xB70A8137150B8EEBULL, - 0x051AE3D428C8F8ACULL, 0xBB77A86F0C1AB15BULL, 0x6E3025E316A330EFULL, - 0x19529A45D6F83456ULL, 0xF180EB34118E98D1ULL, 0xB5F6C6B250717CBEULL, - 0x09939D54DA7460CDULL, 0xE247150422EA1ED4ULL, 0xB8A762D0521BC98AULL, - 0xF4D027275AC1348BULL, 0xC17669101999024AULL, 0xBE5E9001A8D66AD7ULL, - 0xC57DB17C620A8652ULL, 0xAB739D7700C29F52ULL, 0xDD921F01A70C4AFAULL, - 0xA6824A4E10B9A6F0ULL, 0x74866A08CFE4FFE3ULL, 0x6CDEBE7B89998CAFULL, - 0x9DF30B5C8FFDAC50ULL, 0xAC4032EF4F2D9AE3ULL -}; - -static const BN_ULONG dh2048_224_q[] = { - 0xBF389A99B36371EBULL, 0x1F80535A4738CEBCULL, 0xC58D93FE99717710ULL, - 0x00000000801C0D34ULL -}; - -static const BN_ULONG dh2048_256_p[] = { - 0xDB094AE91E1A1597ULL, 0x693877FAD7EF09CAULL, 0x6116D2276E11715FULL, - 0xA4B54330C198AF12ULL, 0x75F26375D7014103ULL, 0xC3A3960A54E710C3ULL, - 0xDED4010ABD0BE621ULL, 0xC0B857F689962856ULL, 0xB3CA3F7971506026ULL, - 0x1CCACB83E6B486F6ULL, 0x67E144E514056425ULL, 0xF6A167B5A41825D9ULL, - 0x3AD8347796524D8EULL, 0xF13C6D9A51BFA4ABULL, 0x2D52526735488A0EULL, - 0xB63ACAE1CAA6B790ULL, 0x4FDB70C581B23F76ULL, 0xBC39A0BF12307F5CULL, - 0xB941F54EB1E59BB8ULL, 0x6C5BFC11D45F9088ULL, 0x22E0B1EF4275BF7BULL, - 0x91F9E6725B4758C0ULL, 0x5A8A9D306BCF67EDULL, 0x209E0C6497517ABDULL, - 0x3BF4296D830E9A7CULL, 0x16C3D91134096FAAULL, 0xFAF7DF4561B2AA30ULL, - 0xE00DF8F1D61957D4ULL, 0x5D2CEED4435E3B00ULL, 0x8CEEF608660DD0F2ULL, - 0xFFBBD19C65195999ULL, 0x87A8E61DB4B6663CULL -}; - -static const BN_ULONG dh2048_256_g[] = { - 0x664B4C0F6CC41659ULL, 0x5E2327CFEF98C582ULL, 0xD647D148D4795451ULL, - 0x2F63078490F00EF8ULL, 0x184B523D1DB246C3ULL, 0xC7891428CDC67EB6ULL, - 0x7FD028370DF92B52ULL, 0xB3353BBB64E0EC37ULL, 0xECD06E1557CD0915ULL, - 0xB7D2BBD2DF016199ULL, 0xC8484B1E052588B9ULL, 0xDB2A3B7313D3FE14ULL, - 0xD052B985D182EA0AULL, 0xA4BD1BFFE83B9C80ULL, 0xDFC967C1FB3F2E55ULL, - 0xB5045AF2767164E1ULL, 0x1D14348F6F2F9193ULL, 0x64E67982428EBC83ULL, - 0x8AC376D282D6ED38ULL, 0x777DE62AAAB8A862ULL, 0xDDF463E5E9EC144BULL, - 0x0196F931C77A57F2ULL, 0xA55AE31341000A65ULL, 0x901228F8C28CBB18ULL, - 0xBC3773BF7E8C6F62ULL, 0xBE3A6C1B0C6B47B1ULL, 0xFF4FED4AAC0BB555ULL, - 0x10DBC15077BE463FULL, 0x07F4793A1A0BA125ULL, 0x4CA7B18F21EF2054ULL, - 0x2E77506660EDBD48ULL, 0x3FB32C9B73134D0BULL -}; - -static const BN_ULONG dh2048_256_q[] = { - 0xA308B0FE64F5FBD3ULL, 0x99B1A47D1EB3750BULL, 0xB447997640129DA2ULL, - 0x8CF83642A709A097ULL -}; - -#elif BN_BITS2 == 32 - -static const BN_ULONG dh1024_160_p[] = { - 0x2E4A4371, 0xDF1FB2BC, 0x6D4DA708, 0xE68CFDA7, 0x365C1A65, 0x45BF37DF, - 0x0DC8B4BD, 0xA151AF5F, 0xF55BCCC0, 0xFAA31A4F, 0xE5644738, 0x4EFFD6FA, - 0x219A7372, 0x98488E9C, 0x90C4BD70, 0xACCBDD7D, 0xD49B83BF, 0x24975C3C, - 0xA9061123, 0x13ECB4AE, 0x2EE652C0, 0x9838EF1E, 0x75A23D18, 0x6073E286, - 0x52D23B61, 0x9A6A9DCA, 0xFB06A3C6, 0x52C99FBC, 0xAE5D54EC, 0xDE92DE5E, - 0xA080E01D, 0xB10B8F96 -}; - -static const BN_ULONG dh1024_160_g[] = { - 0x22B3B2E5, 0x855E6EEB, 0xF97C2A24, 0x858F4DCE, 0x18D08BC8, 0x2D779D59, - 0x8E73AFA3, 0xD662A4D1, 0x69B6A28A, 0x1DBF0A01, 0x7A091F53, 0xA6A24C08, - 0x63F80A76, 0x909D0D22, 0xB9A92EE1, 0xD7FBD7D3, 0x9E2749F4, 0x5E91547F, - 0xB01B886A, 0x160217B4, 0x5504F213, 0x777E690F, 0x5C41564B, 0x266FEA1E, - 0x14266D31, 0xD6406CFF, 0x58AC507F, 0xF8104DD2, 0xEFB99905, 0x6765A442, - 0xC3FD3412, 0xA4D1CBD5 -}; - -static const BN_ULONG dh1024_160_q[] = { - 0x49462353, 0x64B7CB9D, 0x8ABA4E7D, 0x81A8DF27, 0xF518AA87 -}; - -static const BN_ULONG dh2048_224_p[] = { - 0x0C10E64F, 0x0AC4DFFE, 0x4E71B81C, 0xCF9DE538, 0xFFA31F71, 0x7EF363E2, - 0x6B8E75B9, 0xE3FB73C1, 0x4BA80A29, 0xC9B53DCF, 0x16E79763, 0x23F10B0E, - 0x13042E9B, 0xC52172E4, 0xC928B2B9, 0xBE60E69C, 0xB9E587E8, 0x80CD86A1, - 0x98C641A4, 0x315D75E1, 0x44328387, 0xCDF93ACC, 0xDC0A486D, 0x15987D9A, - 0x1FD5A074, 0x7310F712, 0xDE31EFDC, 0x278273C7, 0x415D9330, 0x1602E714, - 0xBC8985DB, 0x81286130, 0x70918836, 0xB3BF8A31, 0xB9C49708, 0x6A00E0A0, - 0x8BBC27BE, 0xC6BA0B2C, 0xED34DBF6, 0xC9F98D11, 0xB6C12207, 0x7AD5B7D0, - 0x55B7394B, 0xD91E8FEF, 0xEFDA4DF8, 0x9037C9ED, 0xAD6AC212, 0x6D3F8152, - 0x1274A0A6, 0x1DE6B85A, 0x309C180E, 0xEB3D688A, 0x7BA1DF15, 0xAF9A3C40, - 0xF95A56DB, 0xE6FA141D, 0xB61D0A75, 0xB54B1597, 0x683B9FD1, 0xA20D64E5, - 0x9559C51F, 0xD660FAA7, 0x9123A9D0, 0xAD107E1E -}; - -static const BN_ULONG dh2048_224_g[] = { - 0x191F2BFA, 0x84B890D3, 0x2A7065B3, 0x81BC087F, 0xF6EC0179, 0x19C418E1, - 0x71CFFF4C, 0x7B5A0F1C, 0x9B6AA4BD, 0xEDFE72FE, 0x94B30269, 0x81E1BCFE, - 0x8D6C0191, 0x566AFBB4, 0x409D13CD, 0xB539CCE3, 0x5F2FF381, 0x6AA21E7F, - 0x770589EF, 0xD9E263E4, 0xD19963DD, 0x10E183ED, 0x150B8EEB, 0xB70A8137, - 0x28C8F8AC, 0x051AE3D4, 0x0C1AB15B, 0xBB77A86F, 0x16A330EF, 0x6E3025E3, - 0xD6F83456, 0x19529A45, 0x118E98D1, 0xF180EB34, 0x50717CBE, 0xB5F6C6B2, - 0xDA7460CD, 0x09939D54, 0x22EA1ED4, 0xE2471504, 0x521BC98A, 0xB8A762D0, - 0x5AC1348B, 0xF4D02727, 0x1999024A, 0xC1766910, 0xA8D66AD7, 0xBE5E9001, - 0x620A8652, 0xC57DB17C, 0x00C29F52, 0xAB739D77, 0xA70C4AFA, 0xDD921F01, - 0x10B9A6F0, 0xA6824A4E, 0xCFE4FFE3, 0x74866A08, 0x89998CAF, 0x6CDEBE7B, - 0x8FFDAC50, 0x9DF30B5C, 0x4F2D9AE3, 0xAC4032EF -}; - -static const BN_ULONG dh2048_224_q[] = { - 0xB36371EB, 0xBF389A99, 0x4738CEBC, 0x1F80535A, 0x99717710, 0xC58D93FE, - 0x801C0D34 -}; - -static const BN_ULONG dh2048_256_p[] = { - 0x1E1A1597, 0xDB094AE9, 0xD7EF09CA, 0x693877FA, 0x6E11715F, 0x6116D227, - 0xC198AF12, 0xA4B54330, 0xD7014103, 0x75F26375, 0x54E710C3, 0xC3A3960A, - 0xBD0BE621, 0xDED4010A, 0x89962856, 0xC0B857F6, 0x71506026, 0xB3CA3F79, - 0xE6B486F6, 0x1CCACB83, 0x14056425, 0x67E144E5, 0xA41825D9, 0xF6A167B5, - 0x96524D8E, 0x3AD83477, 0x51BFA4AB, 0xF13C6D9A, 0x35488A0E, 0x2D525267, - 0xCAA6B790, 0xB63ACAE1, 0x81B23F76, 0x4FDB70C5, 0x12307F5C, 0xBC39A0BF, - 0xB1E59BB8, 0xB941F54E, 0xD45F9088, 0x6C5BFC11, 0x4275BF7B, 0x22E0B1EF, - 0x5B4758C0, 0x91F9E672, 0x6BCF67ED, 0x5A8A9D30, 0x97517ABD, 0x209E0C64, - 0x830E9A7C, 0x3BF4296D, 0x34096FAA, 0x16C3D911, 0x61B2AA30, 0xFAF7DF45, - 0xD61957D4, 0xE00DF8F1, 0x435E3B00, 0x5D2CEED4, 0x660DD0F2, 0x8CEEF608, - 0x65195999, 0xFFBBD19C, 0xB4B6663C, 0x87A8E61D -}; - -static const BN_ULONG dh2048_256_g[] = { - 0x6CC41659, 0x664B4C0F, 0xEF98C582, 0x5E2327CF, 0xD4795451, 0xD647D148, - 0x90F00EF8, 0x2F630784, 0x1DB246C3, 0x184B523D, 0xCDC67EB6, 0xC7891428, - 0x0DF92B52, 0x7FD02837, 0x64E0EC37, 0xB3353BBB, 0x57CD0915, 0xECD06E15, - 0xDF016199, 0xB7D2BBD2, 0x052588B9, 0xC8484B1E, 0x13D3FE14, 0xDB2A3B73, - 0xD182EA0A, 0xD052B985, 0xE83B9C80, 0xA4BD1BFF, 0xFB3F2E55, 0xDFC967C1, - 0x767164E1, 0xB5045AF2, 0x6F2F9193, 0x1D14348F, 0x428EBC83, 0x64E67982, - 0x82D6ED38, 0x8AC376D2, 0xAAB8A862, 0x777DE62A, 0xE9EC144B, 0xDDF463E5, - 0xC77A57F2, 0x0196F931, 0x41000A65, 0xA55AE313, 0xC28CBB18, 0x901228F8, - 0x7E8C6F62, 0xBC3773BF, 0x0C6B47B1, 0xBE3A6C1B, 0xAC0BB555, 0xFF4FED4A, - 0x77BE463F, 0x10DBC150, 0x1A0BA125, 0x07F4793A, 0x21EF2054, 0x4CA7B18F, - 0x60EDBD48, 0x2E775066, 0x73134D0B, 0x3FB32C9B -}; - -static const BN_ULONG dh2048_256_q[] = { - 0x64F5FBD3, 0xA308B0FE, 0x1EB3750B, 0x99B1A47D, 0x40129DA2, 0xB4479976, - 0xA709A097, 0x8CF83642 -}; - -#else -# error "unsupported BN_BITS2" -#endif - -/* Macro to make a BIGNUM from static data */ - -#define make_dh_bn(x) static const BIGNUM _bignum_##x = { (BN_ULONG *) x, \ - sizeof(x)/sizeof(BN_ULONG),\ - sizeof(x)/sizeof(BN_ULONG),\ - 0, BN_FLG_STATIC_DATA } - -/* - * Macro to make a DH structure from BIGNUM data. NB: although just copying - * the BIGNUM static pointers would be more efficient we can't as they get - * wiped using BN_clear_free() when DH_free() is called. - */ - -#define make_dh(x) \ -DH * DH_get_##x(void) \ - { \ - DH *dh; \ - make_dh_bn(dh##x##_p); \ - make_dh_bn(dh##x##_q); \ - make_dh_bn(dh##x##_g); \ - dh = DH_new(); \ - if (!dh) \ - return NULL; \ - dh->p = BN_dup(&_bignum_dh##x##_p); \ - dh->g = BN_dup(&_bignum_dh##x##_g); \ - dh->q = BN_dup(&_bignum_dh##x##_q); \ - if (!dh->p || !dh->q || !dh->g) \ - { \ - DH_free(dh); \ - return NULL; \ - } \ - return dh; \ - } - -make_dh(1024_160) -make_dh(2048_224) -make_dh(2048_256) diff --git a/Sources/COpenSSL/digest.c b/Sources/COpenSSL/digest.c deleted file mode 100644 index e2c7af91..00000000 --- a/Sources/COpenSSL/digest.c +++ /dev/null @@ -1,408 +0,0 @@ -/* crypto/evp/digest.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "objects.h" -#include "evp.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -#ifdef OPENSSL_FIPS -# include -# include "evp_locl.h" -#endif - -void EVP_MD_CTX_init(EVP_MD_CTX *ctx) -{ - memset(ctx, '\0', sizeof(*ctx)); -} - -EVP_MD_CTX *EVP_MD_CTX_create(void) -{ - EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); - - if (ctx) - EVP_MD_CTX_init(ctx); - - return ctx; -} - -int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) -{ - EVP_MD_CTX_init(ctx); - return EVP_DigestInit_ex(ctx, type, NULL); -} - -int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) -{ - EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); -#ifdef OPENSSL_FIPS - /* If FIPS mode switch to approved implementation if possible */ - if (FIPS_mode()) { - const EVP_MD *fipsmd; - if (type) { - fipsmd = evp_get_fips_md(type); - if (fipsmd) - type = fipsmd; - } - } -#endif -#ifndef OPENSSL_NO_ENGINE - /* - * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so - * this context may already have an ENGINE! Try to avoid releasing the - * previous handle, re-querying for an ENGINE, and having a - * reinitialisation, when it may all be unecessary. - */ - if (ctx->engine && ctx->digest && (!type || - (type - && (type->type == - ctx->digest->type)))) - goto skip_to_init; - if (type) { - /* - * Ensure an ENGINE left lying around from last time is cleared (the - * previous check attempted to avoid this if the same ENGINE and - * EVP_MD could be used). - */ - if (ctx->engine) - ENGINE_finish(ctx->engine); - if (impl) { - if (!ENGINE_init(impl)) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); - return 0; - } - } else - /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_digest_engine(type->type); - if (impl) { - /* There's an ENGINE for this job ... (apparently) */ - const EVP_MD *d = ENGINE_get_digest(impl, type->type); - if (!d) { - /* Same comment from evp_enc.c */ - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); - ENGINE_finish(impl); - return 0; - } - /* We'll use the ENGINE's private digest definition */ - type = d; - /* - * Store the ENGINE functional reference so we know 'type' came - * from an ENGINE and we need to release it when done. - */ - ctx->engine = impl; - } else - ctx->engine = NULL; - } else { - if (!ctx->digest) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET); - return 0; - } - type = ctx->digest; - } -#endif - if (ctx->digest != type) { - if (ctx->digest && ctx->digest->ctx_size) { - OPENSSL_free(ctx->md_data); - ctx->md_data = NULL; - } - ctx->digest = type; - if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { - ctx->update = type->update; - ctx->md_data = OPENSSL_malloc(type->ctx_size); - if (ctx->md_data == NULL) { - EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE); - return 0; - } - } - } -#ifndef OPENSSL_NO_ENGINE - skip_to_init: -#endif - if (ctx->pctx) { - int r; - r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, - EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); - if (r <= 0 && (r != -2)) - return 0; - } - if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) - return 1; -#ifdef OPENSSL_FIPS - if (FIPS_mode()) { - if (FIPS_digestinit(ctx, type)) - return 1; - OPENSSL_free(ctx->md_data); - ctx->md_data = NULL; - return 0; - } -#endif - return ctx->digest->init(ctx); -} - -int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_digestupdate(ctx, data, count); -#endif - return ctx->update(ctx, data, count); -} - -/* The caller can assume that this removes any secret data from the context */ -int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) -{ - int ret; - ret = EVP_DigestFinal_ex(ctx, md, size); - EVP_MD_CTX_cleanup(ctx); - return ret; -} - -/* The caller can assume that this removes any secret data from the context */ -int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) -{ - int ret; -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_digestfinal(ctx, md, size); -#endif - - OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); - ret = ctx->digest->final(ctx, md); - if (size != NULL) - *size = ctx->digest->md_size; - if (ctx->digest->cleanup) { - ctx->digest->cleanup(ctx); - EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); - } - OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); - return ret; -} - -int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) -{ - EVP_MD_CTX_init(out); - return EVP_MD_CTX_copy_ex(out, in); -} - -int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) -{ - unsigned char *tmp_buf; - if ((in == NULL) || (in->digest == NULL)) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED); - return 0; - } -#ifndef OPENSSL_NO_ENGINE - /* Make sure it's safe to copy a digest context using an ENGINE */ - if (in->engine && !ENGINE_init(in->engine)) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB); - return 0; - } -#endif - - if (out->digest == in->digest) { - tmp_buf = out->md_data; - EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); - } else - tmp_buf = NULL; - EVP_MD_CTX_cleanup(out); - memcpy(out, in, sizeof(*out)); - - if (in->md_data && out->digest->ctx_size) { - if (tmp_buf) - out->md_data = tmp_buf; - else { - out->md_data = OPENSSL_malloc(out->digest->ctx_size); - if (!out->md_data) { - EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE); - return 0; - } - } - memcpy(out->md_data, in->md_data, out->digest->ctx_size); - } - - out->update = in->update; - - if (in->pctx) { - out->pctx = EVP_PKEY_CTX_dup(in->pctx); - if (!out->pctx) { - EVP_MD_CTX_cleanup(out); - return 0; - } - } - - if (out->digest->copy) - return out->digest->copy(out, in); - - return 1; -} - -int EVP_Digest(const void *data, size_t count, - unsigned char *md, unsigned int *size, const EVP_MD *type, - ENGINE *impl) -{ - EVP_MD_CTX ctx; - int ret; - - EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT); - ret = EVP_DigestInit_ex(&ctx, type, impl) - && EVP_DigestUpdate(&ctx, data, count) - && EVP_DigestFinal_ex(&ctx, md, size); - EVP_MD_CTX_cleanup(&ctx); - - return ret; -} - -void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) -{ - if (ctx) { - EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(ctx); - } -} - -/* This call frees resources associated with the context */ -int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) -{ -#ifndef OPENSSL_FIPS - /* - * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because - * sometimes only copies of the context are ever finalised. - */ - if (ctx->digest && ctx->digest->cleanup - && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) - ctx->digest->cleanup(ctx); - if (ctx->digest && ctx->digest->ctx_size && ctx->md_data - && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { - OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); - OPENSSL_free(ctx->md_data); - } -#endif - if (ctx->pctx) - EVP_PKEY_CTX_free(ctx->pctx); -#ifndef OPENSSL_NO_ENGINE - if (ctx->engine) - /* - * The EVP_MD we used belongs to an ENGINE, release the functional - * reference we held for this reason. - */ - ENGINE_finish(ctx->engine); -#endif -#ifdef OPENSSL_FIPS - FIPS_md_ctx_cleanup(ctx); -#endif - memset(ctx, '\0', sizeof(*ctx)); - - return 1; -} diff --git a/Sources/COpenSSL/dsa.h b/Sources/COpenSSL/dsa.h deleted file mode 100644 index 985c0cd9..00000000 --- a/Sources/COpenSSL/dsa.h +++ /dev/null @@ -1,335 +0,0 @@ -/* crypto/dsa/dsa.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * The DSS routines are based on patches supplied by - * Steven Schoch . He basically did the - * work and I have just tweaked them a little to fit into my - * stylistic vision for SSLeay :-) */ - -#ifndef HEADER_DSA_H -# define HEADER_DSA_H - -# include "e_os2.h" - -# ifdef OPENSSL_NO_DSA -# error DSA is disabled. -# endif - -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# include "crypto.h" -# include "ossl_typ.h" - -# ifndef OPENSSL_NO_DEPRECATED -# include "bn.h" -# ifndef OPENSSL_NO_DH -# include "dh.h" -# endif -# endif - -# ifndef OPENSSL_DSA_MAX_MODULUS_BITS -# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 -# endif - -# define DSA_FLAG_CACHE_MONT_P 0x01 -/* - * new with 0.9.7h; the built-in DSA implementation now uses constant time - * modular exponentiation for secret exponents by default. This flag causes - * the faster variable sliding window method to be used for all exponents. - */ -# define DSA_FLAG_NO_EXP_CONSTTIME 0x02 - -/* - * If this flag is set the DSA method is FIPS compliant and can be used in - * FIPS mode. This is set in the validated module method. If an application - * sets this flag in its own methods it is its reposibility to ensure the - * result is compliant. - */ - -# define DSA_FLAG_FIPS_METHOD 0x0400 - -/* - * If this flag is set the operations normally disabled in FIPS mode are - * permitted it is then the applications responsibility to ensure that the - * usage is compliant. - */ - -# define DSA_FLAG_NON_FIPS_ALLOW 0x0400 - -#ifdef __cplusplus -extern "C" { -#endif - -/* Already defined in ossl_typ.h */ -/* typedef struct dsa_st DSA; */ -/* typedef struct dsa_method DSA_METHOD; */ - -typedef struct DSA_SIG_st { - BIGNUM *r; - BIGNUM *s; -} DSA_SIG; - -struct dsa_method { - const char *name; - DSA_SIG *(*dsa_do_sign) (const unsigned char *dgst, int dlen, DSA *dsa); - int (*dsa_sign_setup) (DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp); - int (*dsa_do_verify) (const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa); - int (*dsa_mod_exp) (DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, - BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *in_mont); - /* Can be null */ - int (*bn_mod_exp) (DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); - int (*init) (DSA *dsa); - int (*finish) (DSA *dsa); - int flags; - char *app_data; - /* If this is non-NULL, it is used to generate DSA parameters */ - int (*dsa_paramgen) (DSA *dsa, int bits, - const unsigned char *seed, int seed_len, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb); - /* If this is non-NULL, it is used to generate DSA keys */ - int (*dsa_keygen) (DSA *dsa); -}; - -struct dsa_st { - /* - * This first variable is used to pick up errors where a DSA is passed - * instead of of a EVP_PKEY - */ - int pad; - long version; - int write_params; - BIGNUM *p; - BIGNUM *q; /* == 20 */ - BIGNUM *g; - BIGNUM *pub_key; /* y public key */ - BIGNUM *priv_key; /* x private key */ - BIGNUM *kinv; /* Signing pre-calc */ - BIGNUM *r; /* Signing pre-calc */ - int flags; - /* Normally used to cache montgomery values */ - BN_MONT_CTX *method_mont_p; - int references; - CRYPTO_EX_DATA ex_data; - const DSA_METHOD *meth; - /* functional reference if 'meth' is ENGINE-provided */ - ENGINE *engine; -}; - -# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ - (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) -# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ - (unsigned char *)(x)) -# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) -# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) - -DSA *DSAparams_dup(DSA *x); -DSA_SIG *DSA_SIG_new(void); -void DSA_SIG_free(DSA_SIG *a); -int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); -DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); - -DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); -int DSA_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa); - -const DSA_METHOD *DSA_OpenSSL(void); - -void DSA_set_default_method(const DSA_METHOD *); -const DSA_METHOD *DSA_get_default_method(void); -int DSA_set_method(DSA *dsa, const DSA_METHOD *); - -DSA *DSA_new(void); -DSA *DSA_new_method(ENGINE *engine); -void DSA_free(DSA *r); -/* "up" the DSA object's reference count */ -int DSA_up_ref(DSA *r); -int DSA_size(const DSA *); - /* next 4 return -1 on error */ -int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); -int DSA_sign(int type, const unsigned char *dgst, int dlen, - unsigned char *sig, unsigned int *siglen, DSA *dsa); -int DSA_verify(int type, const unsigned char *dgst, int dgst_len, - const unsigned char *sigbuf, int siglen, DSA *dsa); -int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int DSA_set_ex_data(DSA *d, int idx, void *arg); -void *DSA_get_ex_data(DSA *d, int idx); - -DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); -DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); -DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); - -/* Deprecated version */ -# ifndef OPENSSL_NO_DEPRECATED -DSA *DSA_generate_parameters(int bits, - unsigned char *seed, int seed_len, - int *counter_ret, unsigned long *h_ret, void - (*callback) (int, int, void *), void *cb_arg); -# endif /* !defined(OPENSSL_NO_DEPRECATED) */ - -/* New version */ -int DSA_generate_parameters_ex(DSA *dsa, int bits, - const unsigned char *seed, int seed_len, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb); - -int DSA_generate_key(DSA *a); -int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); -int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); -int i2d_DSAparams(const DSA *a, unsigned char **pp); - -# ifndef OPENSSL_NO_BIO -int DSAparams_print(BIO *bp, const DSA *x); -int DSA_print(BIO *bp, const DSA *x, int off); -# endif -# ifndef OPENSSL_NO_FP_API -int DSAparams_print_fp(FILE *fp, const DSA *x); -int DSA_print_fp(FILE *bp, const DSA *x, int off); -# endif - -# define DSS_prime_checks 64 -/* - * Primality test according to FIPS PUB 186-4, Appendix C.3. Since we only - * have one value here we set the number of checks to 64 which is the 128 bit - * security level that is the highest level and valid for creating a 3072 bit - * DSA key. - */ -# define DSA_is_prime(n, callback, cb_arg) \ - BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) - -# ifndef OPENSSL_NO_DH -/* - * Convert DSA structure (key or just parameters) into DH structure (be - * careful to avoid small subgroup attacks when using this!) - */ -DH *DSA_dup_DH(const DSA *r); -# endif - -# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ - EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) - -# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) -# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) -# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_DSA_strings(void); - -/* Error codes for the DSA functions. */ - -/* Function codes. */ -# define DSA_F_D2I_DSA_SIG 110 -# define DSA_F_DO_DSA_PRINT 104 -# define DSA_F_DSAPARAMS_PRINT 100 -# define DSA_F_DSAPARAMS_PRINT_FP 101 -# define DSA_F_DSA_BUILTIN_PARAMGEN2 126 -# define DSA_F_DSA_DO_SIGN 112 -# define DSA_F_DSA_DO_VERIFY 113 -# define DSA_F_DSA_GENERATE_KEY 124 -# define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 -# define DSA_F_DSA_NEW_METHOD 103 -# define DSA_F_DSA_PARAM_DECODE 119 -# define DSA_F_DSA_PRINT_FP 105 -# define DSA_F_DSA_PRIV_DECODE 115 -# define DSA_F_DSA_PRIV_ENCODE 116 -# define DSA_F_DSA_PUB_DECODE 117 -# define DSA_F_DSA_PUB_ENCODE 118 -# define DSA_F_DSA_SIGN 106 -# define DSA_F_DSA_SIGN_SETUP 107 -# define DSA_F_DSA_SIG_NEW 109 -# define DSA_F_DSA_SIG_PRINT 125 -# define DSA_F_DSA_VERIFY 108 -# define DSA_F_I2D_DSA_SIG 111 -# define DSA_F_OLD_DSA_PRIV_DECODE 122 -# define DSA_F_PKEY_DSA_CTRL 120 -# define DSA_F_PKEY_DSA_CTRL_STR 127 -# define DSA_F_PKEY_DSA_KEYGEN 121 -# define DSA_F_SIG_CB 114 - -/* Reason codes. */ -# define DSA_R_BAD_Q_VALUE 102 -# define DSA_R_BN_DECODE_ERROR 108 -# define DSA_R_BN_ERROR 109 -# define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 -# define DSA_R_DECODE_ERROR 104 -# define DSA_R_INVALID_DIGEST_TYPE 106 -# define DSA_R_INVALID_PARAMETERS 112 -# define DSA_R_MISSING_PARAMETERS 101 -# define DSA_R_MODULUS_TOO_LARGE 103 -# define DSA_R_NEED_NEW_SETUP_VALUES 110 -# define DSA_R_NON_FIPS_DSA_METHOD 111 -# define DSA_R_NO_PARAMETERS_SET 107 -# define DSA_R_PARAMETER_ENCODING_ERROR 105 -# define DSA_R_Q_NOT_PRIME 113 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/dsa_.c b/Sources/COpenSSL/dsa_.c deleted file mode 100644 index 07f39f79..00000000 --- a/Sources/COpenSSL/dsa_.c +++ /dev/null @@ -1,3495 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "x509.h" -#include "asn1.h" -#include "dsa.h" -#include "bn.h" -#ifndef OPENSSL_NO_CMS -# include "cms.h" -#endif -#include "asn1_locl.h" - -static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) -{ - const unsigned char *p, *pm; - int pklen, pmlen; - int ptype; - void *pval; - ASN1_STRING *pstr; - X509_ALGOR *palg; - ASN1_INTEGER *public_key = NULL; - - DSA *dsa = NULL; - - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - if (ptype == V_ASN1_SEQUENCE) { - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; - - if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); - goto err; - } - - } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) { - if (!(dsa = DSA_new())) { - DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); - goto err; - } - } else { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); - goto err; - } - - if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); - goto err; - } - - if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { - DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); - goto err; - } - - ASN1_INTEGER_free(public_key); - EVP_PKEY_assign_DSA(pkey, dsa); - return 1; - - err: - if (public_key) - ASN1_INTEGER_free(public_key); - if (dsa) - DSA_free(dsa); - return 0; - -} - -static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) -{ - DSA *dsa; - int ptype; - unsigned char *penc = NULL; - int penclen; - ASN1_STRING *str = NULL; - ASN1_OBJECT *aobj; - - dsa = pkey->pkey.dsa; - if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { - str = ASN1_STRING_new(); - if (!str) { - DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - str->length = i2d_DSAparams(dsa, &str->data); - if (str->length <= 0) { - DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - ptype = V_ASN1_SEQUENCE; - } else - ptype = V_ASN1_UNDEF; - - dsa->write_params = 0; - - penclen = i2d_DSAPublicKey(dsa, &penc); - - if (penclen <= 0) { - DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - - aobj = OBJ_nid2obj(EVP_PKEY_DSA); - if (aobj == NULL) - goto err; - - if (X509_PUBKEY_set0_param(pk, aobj, ptype, str, penc, penclen)) - return 1; - - err: - if (penc) - OPENSSL_free(penc); - if (str) - ASN1_STRING_free(str); - - return 0; -} - -/* - * In PKCS#8 DSA: you just get a private key integer and parameters in the - * AlgorithmIdentifier the pubkey must be recalculated. - */ - -static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) -{ - const unsigned char *p, *pm; - int pklen, pmlen; - int ptype; - void *pval; - ASN1_STRING *pstr; - X509_ALGOR *palg; - ASN1_INTEGER *privkey = NULL; - BN_CTX *ctx = NULL; - - STACK_OF(ASN1_TYPE) *ndsa = NULL; - DSA *dsa = NULL; - - int ret = 0; - - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - /* Check for broken DSA PKCS#8, UGH! */ - if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { - ASN1_TYPE *t1, *t2; - if (!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) - goto decerr; - if (sk_ASN1_TYPE_num(ndsa) != 2) - goto decerr; - /*- - * Handle Two broken types: - * SEQUENCE {parameters, priv_key} - * SEQUENCE {pub_key, priv_key} - */ - - t1 = sk_ASN1_TYPE_value(ndsa, 0); - t2 = sk_ASN1_TYPE_value(ndsa, 1); - if (t1->type == V_ASN1_SEQUENCE) { - p8->broken = PKCS8_EMBEDDED_PARAM; - pval = t1->value.ptr; - } else if (ptype == V_ASN1_SEQUENCE) - p8->broken = PKCS8_NS_DB; - else - goto decerr; - - if (t2->type != V_ASN1_INTEGER) - goto decerr; - - privkey = t2->value.integer; - } else { - const unsigned char *q = p; - if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen))) - goto decerr; - if (privkey->type == V_ASN1_NEG_INTEGER) { - p8->broken = PKCS8_NEG_PRIVKEY; - ASN1_STRING_clear_free(privkey); - if (!(privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen))) - goto decerr; - } - if (ptype != V_ASN1_SEQUENCE) - goto decerr; - } - - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; - if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) - goto decerr; - /* We have parameters now set private key */ - if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { - DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); - goto dsaerr; - } - /* Calculate public key */ - if (!(dsa->pub_key = BN_new())) { - DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); - goto dsaerr; - } - if (!(ctx = BN_CTX_new())) { - DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); - goto dsaerr; - } - - BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME); - if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { - DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); - goto dsaerr; - } - - EVP_PKEY_assign_DSA(pkey, dsa); - - ret = 1; - goto done; - - decerr: - DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_DECODE_ERROR); - dsaerr: - DSA_free(dsa); - done: - BN_CTX_free(ctx); - if (ndsa) - sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); - else - ASN1_STRING_clear_free(privkey); - return ret; -} - -static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) -{ - ASN1_STRING *params = NULL; - ASN1_INTEGER *prkey = NULL; - unsigned char *dp = NULL; - int dplen; - - if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) { - DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS); - goto err; - } - - params = ASN1_STRING_new(); - - if (!params) { - DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - - params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); - if (params->length <= 0) { - DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - goto err; - } - params->type = V_ASN1_SEQUENCE; - - /* Get private key into integer */ - prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); - - if (!prkey) { - DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR); - goto err; - } - - dplen = i2d_ASN1_INTEGER(prkey, &dp); - - ASN1_STRING_clear_free(prkey); - prkey = NULL; - - if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, - V_ASN1_SEQUENCE, params, dp, dplen)) - goto err; - - return 1; - - err: - if (dp != NULL) - OPENSSL_free(dp); - if (params != NULL) - ASN1_STRING_free(params); - if (prkey != NULL) - ASN1_STRING_clear_free(prkey); - return 0; -} - -static int int_dsa_size(const EVP_PKEY *pkey) -{ - return (DSA_size(pkey->pkey.dsa)); -} - -static int dsa_bits(const EVP_PKEY *pkey) -{ - return BN_num_bits(pkey->pkey.dsa->p); -} - -static int dsa_missing_parameters(const EVP_PKEY *pkey) -{ - DSA *dsa; - dsa = pkey->pkey.dsa; - if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) - return 1; - return 0; -} - -static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) -{ - BIGNUM *a; - - if ((a = BN_dup(from->pkey.dsa->p)) == NULL) - return 0; - if (to->pkey.dsa->p != NULL) - BN_free(to->pkey.dsa->p); - to->pkey.dsa->p = a; - - if ((a = BN_dup(from->pkey.dsa->q)) == NULL) - return 0; - if (to->pkey.dsa->q != NULL) - BN_free(to->pkey.dsa->q); - to->pkey.dsa->q = a; - - if ((a = BN_dup(from->pkey.dsa->g)) == NULL) - return 0; - if (to->pkey.dsa->g != NULL) - BN_free(to->pkey.dsa->g); - to->pkey.dsa->g = a; - return 1; -} - -static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) -{ - if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) || - BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) || - BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g)) - return 0; - else - return 1; -} - -static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0) - return 0; - else - return 1; -} - -static void int_dsa_free(EVP_PKEY *pkey) -{ - DSA_free(pkey->pkey.dsa); -} - -static void update_buflen(const BIGNUM *b, size_t *pbuflen) -{ - size_t i; - if (!b) - return; - if (*pbuflen < (i = (size_t)BN_num_bytes(b))) - *pbuflen = i; -} - -static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) -{ - unsigned char *m = NULL; - int ret = 0; - size_t buf_len = 0; - const char *ktype = NULL; - - const BIGNUM *priv_key, *pub_key; - - if (ptype == 2) - priv_key = x->priv_key; - else - priv_key = NULL; - - if (ptype > 0) - pub_key = x->pub_key; - else - pub_key = NULL; - - if (ptype == 2) - ktype = "Private-Key"; - else if (ptype == 1) - ktype = "Public-Key"; - else - ktype = "DSA-Parameters"; - - update_buflen(x->p, &buf_len); - update_buflen(x->q, &buf_len); - update_buflen(x->g, &buf_len); - update_buflen(priv_key, &buf_len); - update_buflen(pub_key, &buf_len); - - m = (unsigned char *)OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (priv_key) { - if (!BIO_indent(bp, off, 128)) - goto err; - if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) - <= 0) - goto err; - } - - if (!ASN1_bn_print(bp, "priv:", priv_key, m, off)) - goto err; - if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off)) - goto err; - if (!ASN1_bn_print(bp, "P: ", x->p, m, off)) - goto err; - if (!ASN1_bn_print(bp, "Q: ", x->q, m, off)) - goto err; - if (!ASN1_bn_print(bp, "G: ", x->g, m, off)) - goto err; - ret = 1; - err: - if (m != NULL) - OPENSSL_free(m); - return (ret); -} - -static int dsa_param_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) -{ - DSA *dsa; - if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) { - DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); - return 0; - } - EVP_PKEY_assign_DSA(pkey, dsa); - return 1; -} - -static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - return i2d_DSAparams(pkey->pkey.dsa, pder); -} - -static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); -} - -static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); -} - -static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); -} - -static int old_dsa_priv_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) -{ - DSA *dsa; - if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) { - DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); - return 0; - } - EVP_PKEY_assign_DSA(pkey, dsa); - return 1; -} - -static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); -} - -static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, - const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) -{ - DSA_SIG *dsa_sig; - const unsigned char *p; - if (!sig) { - if (BIO_puts(bp, "\n") <= 0) - return 0; - else - return 1; - } - p = sig->data; - dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); - if (dsa_sig) { - int rv = 0; - size_t buf_len = 0; - unsigned char *m = NULL; - update_buflen(dsa_sig->r, &buf_len); - update_buflen(dsa_sig->s, &buf_len); - m = OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (BIO_write(bp, "\n", 1) != 1) - goto err; - - if (!ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent)) - goto err; - if (!ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) - goto err; - rv = 1; - err: - if (m) - OPENSSL_free(m); - DSA_SIG_free(dsa_sig); - return rv; - } - return X509_signature_dump(bp, sig, indent); -} - -static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - switch (op) { - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_NONE; - return 1; -#endif - - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_sha256; - return 2; - - default: - return -2; - - } - -} - -/* NB these are sorted in pkey_id order, lowest first */ - -const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = { - - { - EVP_PKEY_DSA2, - EVP_PKEY_DSA, - ASN1_PKEY_ALIAS}, - - { - EVP_PKEY_DSA1, - EVP_PKEY_DSA, - ASN1_PKEY_ALIAS}, - - { - EVP_PKEY_DSA4, - EVP_PKEY_DSA, - ASN1_PKEY_ALIAS}, - - { - EVP_PKEY_DSA3, - EVP_PKEY_DSA, - ASN1_PKEY_ALIAS}, - - { - EVP_PKEY_DSA, - EVP_PKEY_DSA, - 0, - - "DSA", - "OpenSSL DSA method", - - dsa_pub_decode, - dsa_pub_encode, - dsa_pub_cmp, - dsa_pub_print, - - dsa_priv_decode, - dsa_priv_encode, - dsa_priv_print, - - int_dsa_size, - dsa_bits, - - dsa_param_decode, - dsa_param_encode, - dsa_missing_parameters, - dsa_copy_parameters, - dsa_cmp_parameters, - dsa_param_print, - dsa_sig_print, - - int_dsa_free, - dsa_pkey_ctrl, - old_dsa_priv_decode, - old_dsa_priv_encode} -}; -/* dsa_asn1.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "dsa.h" -// #include "asn1.h" -#include "asn1t.h" -#include "rand.h" - -/* Override the default new methods */ -static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_NEW_PRE) { - DSA_SIG *sig; - sig = OPENSSL_malloc(sizeof(DSA_SIG)); - if (!sig) { - DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE); - return 0; - } - sig->r = NULL; - sig->s = NULL; - *pval = (ASN1_VALUE *)sig; - return 2; - } - return 1; -} - -ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = { - ASN1_SIMPLE(DSA_SIG, r, CBIGNUM), - ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) -} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG) - -/* Override the default free and new methods */ -static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_NEW_PRE) { - *pval = (ASN1_VALUE *)DSA_new(); - if (*pval) - return 2; - return 0; - } else if (operation == ASN1_OP_FREE_PRE) { - DSA_free((DSA *)*pval); - *pval = NULL; - return 2; - } - return 1; -} - -ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = { - ASN1_SIMPLE(DSA, version, LONG), - ASN1_SIMPLE(DSA, p, BIGNUM), - ASN1_SIMPLE(DSA, q, BIGNUM), - ASN1_SIMPLE(DSA, g, BIGNUM), - ASN1_SIMPLE(DSA, pub_key, BIGNUM), - ASN1_SIMPLE(DSA, priv_key, BIGNUM) -} ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey) - -ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = { - ASN1_SIMPLE(DSA, p, BIGNUM), - ASN1_SIMPLE(DSA, q, BIGNUM), - ASN1_SIMPLE(DSA, g, BIGNUM), -} ASN1_SEQUENCE_END_cb(DSA, DSAparams) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams) - -/* - * DSA public key is a bit trickier... its effectively a CHOICE type decided - * by a field called write_params which can either write out just the public - * key as an INTEGER or the parameters and public key in a SEQUENCE - */ - -ASN1_SEQUENCE(dsa_pub_internal) = { - ASN1_SIMPLE(DSA, pub_key, BIGNUM), - ASN1_SIMPLE(DSA, p, BIGNUM), - ASN1_SIMPLE(DSA, q, BIGNUM), - ASN1_SIMPLE(DSA, g, BIGNUM) -} ASN1_SEQUENCE_END_name(DSA, dsa_pub_internal) - -ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = { - ASN1_SIMPLE(DSA, pub_key, BIGNUM), - ASN1_EX_COMBINE(0, 0, dsa_pub_internal) -} ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) - -DSA *DSAparams_dup(DSA *dsa) -{ - return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); -} - -int DSA_sign(int type, const unsigned char *dgst, int dlen, - unsigned char *sig, unsigned int *siglen, DSA *dsa) -{ - DSA_SIG *s; - RAND_seed(dgst, dlen); - s = DSA_do_sign(dgst, dlen, dsa); - if (s == NULL) { - *siglen = 0; - return (0); - } - *siglen = i2d_DSA_SIG(s, &sig); - DSA_SIG_free(s); - return (1); -} - -/* data has already been hashed (probably with SHA or SHA-1). */ -/*- - * returns - * 1: correct signature - * 0: incorrect signature - * -1: error - */ -int DSA_verify(int type, const unsigned char *dgst, int dgst_len, - const unsigned char *sigbuf, int siglen, DSA *dsa) -{ - DSA_SIG *s; - const unsigned char *p = sigbuf; - unsigned char *der = NULL; - int derlen = -1; - int ret = -1; - - s = DSA_SIG_new(); - if (s == NULL) - return (ret); - if (d2i_DSA_SIG(&s, &p, siglen) == NULL) - goto err; - /* Ensure signature uses DER and doesn't have trailing garbage */ - derlen = i2d_DSA_SIG(s, &der); - if (derlen != siglen || memcmp(sigbuf, der, derlen)) - goto err; - ret = DSA_do_verify(dgst, dgst_len, s, dsa); - err: - if (derlen > 0) { - OPENSSL_cleanse(der, derlen); - OPENSSL_free(der); - } - DSA_SIG_free(s); - return (ret); -} -/* crypto/dsa/dsa_depr.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * This file contains deprecated function(s) that are now wrappers to the new - * version(s). - */ - -#undef GENUINE_DSA - -#ifdef GENUINE_DSA -/* - * Parameter generation follows the original release of FIPS PUB 186, - * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) - */ -# define HASH EVP_sha() -#else -/* - * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, - * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB - * 180-1) - */ -# define HASH EVP_sha1() -#endif - -static void *dummy = &dummy; - -#ifndef OPENSSL_NO_SHA - -# include -# include -# include "cryptlib.h" -# include "evp.h" -# include "bn.h" -# include "dsa.h" -# include "rand.h" -# include "sha.h" - -# ifndef OPENSSL_NO_DEPRECATED -DSA *DSA_generate_parameters(int bits, - unsigned char *seed_in, int seed_len, - int *counter_ret, unsigned long *h_ret, - void (*callback) (int, int, void *), - void *cb_arg) -{ - BN_GENCB cb; - DSA *ret; - - if ((ret = DSA_new()) == NULL) - return NULL; - - BN_GENCB_set_old(&cb, callback, cb_arg); - - if (DSA_generate_parameters_ex(ret, bits, seed_in, seed_len, - counter_ret, h_ret, &cb)) - return ret; - DSA_free(ret); - return NULL; -} -# endif -#endif -/* crypto/dsa/dsa_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "dsa.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason) - -static ERR_STRING_DATA DSA_str_functs[] = { - {ERR_FUNC(DSA_F_D2I_DSA_SIG), "d2i_DSA_SIG"}, - {ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"}, - {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"}, - {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, - {ERR_FUNC(DSA_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"}, - {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, - {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, - {ERR_FUNC(DSA_F_DSA_GENERATE_KEY), "DSA_generate_key"}, - {ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX), - "DSA_generate_parameters_ex"}, - {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"}, - {ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "DSA_PARAM_DECODE"}, - {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"}, - {ERR_FUNC(DSA_F_DSA_PRIV_DECODE), "DSA_PRIV_DECODE"}, - {ERR_FUNC(DSA_F_DSA_PRIV_ENCODE), "DSA_PRIV_ENCODE"}, - {ERR_FUNC(DSA_F_DSA_PUB_DECODE), "DSA_PUB_DECODE"}, - {ERR_FUNC(DSA_F_DSA_PUB_ENCODE), "DSA_PUB_ENCODE"}, - {ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"}, - {ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"}, - {ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"}, - {ERR_FUNC(DSA_F_DSA_SIG_PRINT), "DSA_SIG_PRINT"}, - {ERR_FUNC(DSA_F_DSA_VERIFY), "DSA_verify"}, - {ERR_FUNC(DSA_F_I2D_DSA_SIG), "i2d_DSA_SIG"}, - {ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "OLD_DSA_PRIV_DECODE"}, - {ERR_FUNC(DSA_F_PKEY_DSA_CTRL), "PKEY_DSA_CTRL"}, - {ERR_FUNC(DSA_F_PKEY_DSA_CTRL_STR), "PKEY_DSA_CTRL_STR"}, - {ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN), "PKEY_DSA_KEYGEN"}, - {ERR_FUNC(DSA_F_SIG_CB), "SIG_CB"}, - {0, NULL} -}; - -static ERR_STRING_DATA DSA_str_reasons[] = { - {ERR_REASON(DSA_R_BAD_Q_VALUE), "bad q value"}, - {ERR_REASON(DSA_R_BN_DECODE_ERROR), "bn decode error"}, - {ERR_REASON(DSA_R_BN_ERROR), "bn error"}, - {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), - "data too large for key size"}, - {ERR_REASON(DSA_R_DECODE_ERROR), "decode error"}, - {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE), "invalid digest type"}, - {ERR_REASON(DSA_R_INVALID_PARAMETERS), "invalid parameters"}, - {ERR_REASON(DSA_R_MISSING_PARAMETERS), "missing parameters"}, - {ERR_REASON(DSA_R_MODULUS_TOO_LARGE), "modulus too large"}, - {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, - {ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD), "non fips dsa method"}, - {ERR_REASON(DSA_R_NO_PARAMETERS_SET), "no parameters set"}, - {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, - {ERR_REASON(DSA_R_Q_NOT_PRIME), "q not prime"}, - {0, NULL} -}; - -#endif - -void ERR_load_DSA_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(DSA_str_functs[0].error) == NULL) { - ERR_load_strings(0, DSA_str_functs); - ERR_load_strings(0, DSA_str_reasons); - } -#endif -} -/* crypto/dsa/dsa_gen.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#undef GENUINE_DSA - -#ifdef GENUINE_DSA -/* - * Parameter generation follows the original release of FIPS PUB 186, - * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) - */ -# define HASH EVP_sha() -#else -/* - * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, - * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB - * 180-1) - */ -# define HASH EVP_sha1() -#endif - -#include "opensslconf.h" /* To see if OPENSSL_NO_SHA is defined */ - -#ifndef OPENSSL_NO_SHA - -# include -# include "cryptlib.h" -# include "evp.h" -# include "bn.h" -# include "rand.h" -# include "sha.h" -# include "dsa_locl.h" - -# ifdef OPENSSL_FIPS -/* Workaround bug in prototype */ -# define fips_dsa_builtin_paramgen2 fips_dsa_paramgen_bad -# include -# endif - -int DSA_generate_parameters_ex(DSA *ret, int bits, - const unsigned char *seed_in, int seed_len, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb) -{ -# ifdef OPENSSL_FIPS - if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD) - && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) { - DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD); - return 0; - } -# endif - if (ret->meth->dsa_paramgen) - return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, - counter_ret, h_ret, cb); -# ifdef OPENSSL_FIPS - else if (FIPS_mode()) { - return FIPS_dsa_generate_parameters_ex(ret, bits, - seed_in, seed_len, - counter_ret, h_ret, cb); - } -# endif - else { - const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1(); - size_t qbits = EVP_MD_size(evpmd) * 8; - - return dsa_builtin_paramgen(ret, bits, qbits, evpmd, - seed_in, seed_len, NULL, counter_ret, - h_ret, cb); - } -} - -int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, - const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) -{ - int ok = 0; - unsigned char seed[SHA256_DIGEST_LENGTH]; - unsigned char md[SHA256_DIGEST_LENGTH]; - unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; - BIGNUM *r0, *W, *X, *c, *test; - BIGNUM *g = NULL, *q = NULL, *p = NULL; - BN_MONT_CTX *mont = NULL; - int i, k, n = 0, m = 0, qsize = qbits >> 3; - int counter = 0; - int r = 0; - BN_CTX *ctx = NULL; - unsigned int h = 2; - - if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && - qsize != SHA256_DIGEST_LENGTH) - /* invalid q size */ - return 0; - - if (evpmd == NULL) { - if (qsize == SHA_DIGEST_LENGTH) - evpmd = EVP_sha1(); - else if (qsize == SHA224_DIGEST_LENGTH) - evpmd = EVP_sha224(); - else - evpmd = EVP_sha256(); - } else { - qsize = EVP_MD_size(evpmd); - } - - if (bits < 512) - bits = 512; - - bits = (bits + 63) / 64 * 64; - - /* - * NB: seed_len == 0 is special case: copy generated seed to seed_in if - * it is not NULL. - */ - if (seed_len && (seed_len < (size_t)qsize)) - seed_in = NULL; /* seed buffer too small -- ignore */ - if (seed_len > (size_t)qsize) - seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger - * SEED, but our internal buffers are - * restricted to 160 bits */ - if (seed_in != NULL) - memcpy(seed, seed_in, seed_len); - - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - BN_CTX_start(ctx); - - r0 = BN_CTX_get(ctx); - g = BN_CTX_get(ctx); - W = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - c = BN_CTX_get(ctx); - p = BN_CTX_get(ctx); - test = BN_CTX_get(ctx); - - if (test == NULL) - goto err; - - if (!BN_lshift(test, BN_value_one(), bits - 1)) - goto err; - - for (;;) { - for (;;) { /* find q */ - int seed_is_random; - - /* step 1 */ - if (!BN_GENCB_call(cb, 0, m++)) - goto err; - - if (!seed_len || !seed_in) { - if (RAND_bytes(seed, qsize) <= 0) - goto err; - seed_is_random = 1; - } else { - seed_is_random = 0; - seed_len = 0; /* use random seed if 'seed_in' turns out to - * be bad */ - } - memcpy(buf, seed, qsize); - memcpy(buf2, seed, qsize); - /* precompute "SEED + 1" for step 7: */ - for (i = qsize - 1; i >= 0; i--) { - buf[i]++; - if (buf[i] != 0) - break; - } - - /* step 2 */ - if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) - goto err; - if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) - goto err; - for (i = 0; i < qsize; i++) - md[i] ^= buf2[i]; - - /* step 3 */ - md[0] |= 0x80; - md[qsize - 1] |= 0x01; - if (!BN_bin2bn(md, qsize, q)) - goto err; - - /* step 4 */ - r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, - seed_is_random, cb); - if (r > 0) - break; - if (r != 0) - goto err; - - /* do a callback call */ - /* step 5 */ - } - - if (!BN_GENCB_call(cb, 2, 0)) - goto err; - if (!BN_GENCB_call(cb, 3, 0)) - goto err; - - /* step 6 */ - counter = 0; - /* "offset = 2" */ - - n = (bits - 1) / 160; - - for (;;) { - if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) - goto err; - - /* step 7 */ - BN_zero(W); - /* now 'buf' contains "SEED + offset - 1" */ - for (k = 0; k <= n; k++) { - /* - * obtain "SEED + offset + k" by incrementing: - */ - for (i = qsize - 1; i >= 0; i--) { - buf[i]++; - if (buf[i] != 0) - break; - } - - if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) - goto err; - - /* step 8 */ - if (!BN_bin2bn(md, qsize, r0)) - goto err; - if (!BN_lshift(r0, r0, (qsize << 3) * k)) - goto err; - if (!BN_add(W, W, r0)) - goto err; - } - - /* more of step 8 */ - if (!BN_mask_bits(W, bits - 1)) - goto err; - if (!BN_copy(X, W)) - goto err; - if (!BN_add(X, X, test)) - goto err; - - /* step 9 */ - if (!BN_lshift1(r0, q)) - goto err; - if (!BN_mod(c, X, r0, ctx)) - goto err; - if (!BN_sub(r0, c, BN_value_one())) - goto err; - if (!BN_sub(p, X, r0)) - goto err; - - /* step 10 */ - if (BN_cmp(p, test) >= 0) { - /* step 11 */ - r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); - if (r > 0) - goto end; /* found it */ - if (r != 0) - goto err; - } - - /* step 13 */ - counter++; - /* "offset = offset + n + 1" */ - - /* step 14 */ - if (counter >= 4096) - break; - } - } - end: - if (!BN_GENCB_call(cb, 2, 1)) - goto err; - - /* We now need to generate g */ - /* Set r0=(p-1)/q */ - if (!BN_sub(test, p, BN_value_one())) - goto err; - if (!BN_div(r0, NULL, test, q, ctx)) - goto err; - - if (!BN_set_word(test, h)) - goto err; - if (!BN_MONT_CTX_set(mont, p, ctx)) - goto err; - - for (;;) { - /* g=test^r0%p */ - if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) - goto err; - if (!BN_is_one(g)) - break; - if (!BN_add(test, test, BN_value_one())) - goto err; - h++; - } - - if (!BN_GENCB_call(cb, 3, 1)) - goto err; - - ok = 1; - err: - if (ok) { - if (ret->p) - BN_free(ret->p); - if (ret->q) - BN_free(ret->q); - if (ret->g) - BN_free(ret->g); - ret->p = BN_dup(p); - ret->q = BN_dup(q); - ret->g = BN_dup(g); - if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { - ok = 0; - goto err; - } - if (counter_ret != NULL) - *counter_ret = counter; - if (h_ret != NULL) - *h_ret = h; - if (seed_out) - memcpy(seed_out, seed, qsize); - } - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (mont != NULL) - BN_MONT_CTX_free(mont); - return ok; -} - -# ifdef OPENSSL_FIPS -# undef fips_dsa_builtin_paramgen2 -extern int fips_dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, - const unsigned char *seed_in, - size_t seed_len, int idx, - unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb); -# endif - -/* - * This is a parameter generation algorithm for the DSA2 algorithm as - * described in FIPS 186-3. - */ - -int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, int idx, unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb) -{ - int ok = -1; - unsigned char *seed = NULL, *seed_tmp = NULL; - unsigned char md[EVP_MAX_MD_SIZE]; - int mdsize; - BIGNUM *r0, *W, *X, *c, *test; - BIGNUM *g = NULL, *q = NULL, *p = NULL; - BN_MONT_CTX *mont = NULL; - int i, k, n = 0, m = 0, qsize = N >> 3; - int counter = 0; - int r = 0; - BN_CTX *ctx = NULL; - EVP_MD_CTX mctx; - unsigned int h = 2; - -# ifdef OPENSSL_FIPS - - if (FIPS_mode()) - return fips_dsa_builtin_paramgen2(ret, L, N, evpmd, - seed_in, seed_len, idx, - seed_out, counter_ret, h_ret, cb); -# endif - - EVP_MD_CTX_init(&mctx); - - /* make sure L > N, otherwise we'll get trapped in an infinite loop */ - if (L <= N) { - DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); - goto err; - } - - if (evpmd == NULL) { - if (N == 160) - evpmd = EVP_sha1(); - else if (N == 224) - evpmd = EVP_sha224(); - else - evpmd = EVP_sha256(); - } - - mdsize = EVP_MD_size(evpmd); - /* If unverificable g generation only don't need seed */ - if (!ret->p || !ret->q || idx >= 0) { - if (seed_len == 0) - seed_len = mdsize; - - seed = OPENSSL_malloc(seed_len); - - if (seed_out) - seed_tmp = seed_out; - else - seed_tmp = OPENSSL_malloc(seed_len); - - if (!seed || !seed_tmp) - goto err; - - if (seed_in) - memcpy(seed, seed_in, seed_len); - - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - - BN_CTX_start(ctx); - r0 = BN_CTX_get(ctx); - g = BN_CTX_get(ctx); - W = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - c = BN_CTX_get(ctx); - test = BN_CTX_get(ctx); - - /* if p, q already supplied generate g only */ - if (ret->p && ret->q) { - p = ret->p; - q = ret->q; - if (idx >= 0) - memcpy(seed_tmp, seed, seed_len); - goto g_only; - } else { - p = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - if (q == NULL) - goto err; - } - - if (!BN_lshift(test, BN_value_one(), L - 1)) - goto err; - for (;;) { - for (;;) { /* find q */ - unsigned char *pmd; - /* step 1 */ - if (!BN_GENCB_call(cb, 0, m++)) - goto err; - - if (!seed_in) { - if (RAND_bytes(seed, seed_len) <= 0) - goto err; - } - /* step 2 */ - if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL)) - goto err; - /* Take least significant bits of md */ - if (mdsize > qsize) - pmd = md + mdsize - qsize; - else - pmd = md; - - if (mdsize < qsize) - memset(md + mdsize, 0, qsize - mdsize); - - /* step 3 */ - pmd[0] |= 0x80; - pmd[qsize - 1] |= 0x01; - if (!BN_bin2bn(pmd, qsize, q)) - goto err; - - /* step 4 */ - r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, - seed_in ? 1 : 0, cb); - if (r > 0) - break; - if (r != 0) - goto err; - /* Provided seed didn't produce a prime: error */ - if (seed_in) { - ok = 0; - DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_Q_NOT_PRIME); - goto err; - } - - /* do a callback call */ - /* step 5 */ - } - /* Copy seed to seed_out before we mess with it */ - if (seed_out) - memcpy(seed_out, seed, seed_len); - - if (!BN_GENCB_call(cb, 2, 0)) - goto err; - if (!BN_GENCB_call(cb, 3, 0)) - goto err; - - /* step 6 */ - counter = 0; - /* "offset = 1" */ - - n = (L - 1) / (mdsize << 3); - - for (;;) { - if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) - goto err; - - /* step 7 */ - BN_zero(W); - /* now 'buf' contains "SEED + offset - 1" */ - for (k = 0; k <= n; k++) { - /* - * obtain "SEED + offset + k" by incrementing: - */ - for (i = seed_len - 1; i >= 0; i--) { - seed[i]++; - if (seed[i] != 0) - break; - } - - if (!EVP_Digest(seed, seed_len, md, NULL, evpmd, NULL)) - goto err; - - /* step 8 */ - if (!BN_bin2bn(md, mdsize, r0)) - goto err; - if (!BN_lshift(r0, r0, (mdsize << 3) * k)) - goto err; - if (!BN_add(W, W, r0)) - goto err; - } - - /* more of step 8 */ - if (!BN_mask_bits(W, L - 1)) - goto err; - if (!BN_copy(X, W)) - goto err; - if (!BN_add(X, X, test)) - goto err; - - /* step 9 */ - if (!BN_lshift1(r0, q)) - goto err; - if (!BN_mod(c, X, r0, ctx)) - goto err; - if (!BN_sub(r0, c, BN_value_one())) - goto err; - if (!BN_sub(p, X, r0)) - goto err; - - /* step 10 */ - if (BN_cmp(p, test) >= 0) { - /* step 11 */ - r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); - if (r > 0) - goto end; /* found it */ - if (r != 0) - goto err; - } - - /* step 13 */ - counter++; - /* "offset = offset + n + 1" */ - - /* step 14 */ - if (counter >= (int)(4 * L)) - break; - } - if (seed_in) { - ok = 0; - DSAerr(DSA_F_DSA_BUILTIN_PARAMGEN2, DSA_R_INVALID_PARAMETERS); - goto err; - } - } - end: - if (!BN_GENCB_call(cb, 2, 1)) - goto err; - - g_only: - - /* We now need to generate g */ - /* Set r0=(p-1)/q */ - if (!BN_sub(test, p, BN_value_one())) - goto err; - if (!BN_div(r0, NULL, test, q, ctx)) - goto err; - - if (idx < 0) { - if (!BN_set_word(test, h)) - goto err; - } else - h = 1; - if (!BN_MONT_CTX_set(mont, p, ctx)) - goto err; - - for (;;) { - static const unsigned char ggen[4] = { 0x67, 0x67, 0x65, 0x6e }; - if (idx >= 0) { - md[0] = idx & 0xff; - md[1] = (h >> 8) & 0xff; - md[2] = h & 0xff; - if (!EVP_DigestInit_ex(&mctx, evpmd, NULL)) - goto err; - if (!EVP_DigestUpdate(&mctx, seed_tmp, seed_len)) - goto err; - if (!EVP_DigestUpdate(&mctx, ggen, sizeof(ggen))) - goto err; - if (!EVP_DigestUpdate(&mctx, md, 3)) - goto err; - if (!EVP_DigestFinal_ex(&mctx, md, NULL)) - goto err; - if (!BN_bin2bn(md, mdsize, test)) - goto err; - } - /* g=test^r0%p */ - if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) - goto err; - if (!BN_is_one(g)) - break; - if (idx < 0 && !BN_add(test, test, BN_value_one())) - goto err; - h++; - if (idx >= 0 && h > 0xffff) - goto err; - } - - if (!BN_GENCB_call(cb, 3, 1)) - goto err; - - ok = 1; - err: - if (ok == 1) { - if (p != ret->p) { - if (ret->p) - BN_free(ret->p); - ret->p = BN_dup(p); - } - if (q != ret->q) { - if (ret->q) - BN_free(ret->q); - ret->q = BN_dup(q); - } - if (ret->g) - BN_free(ret->g); - ret->g = BN_dup(g); - if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { - ok = -1; - goto err; - } - if (counter_ret != NULL) - *counter_ret = counter; - if (h_ret != NULL) - *h_ret = h; - } - if (seed) - OPENSSL_free(seed); - if (seed_out != seed_tmp) - OPENSSL_free(seed_tmp); - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (mont != NULL) - BN_MONT_CTX_free(mont); - EVP_MD_CTX_cleanup(&mctx); - return ok; -} - -int dsa_paramgen_check_g(DSA *dsa) -{ - BN_CTX *ctx; - BIGNUM *tmp; - BN_MONT_CTX *mont = NULL; - int rv = -1; - ctx = BN_CTX_new(); - if (!ctx) - return -1; - BN_CTX_start(ctx); - if (BN_cmp(dsa->g, BN_value_one()) <= 0) - return 0; - if (BN_cmp(dsa->g, dsa->p) >= 0) - return 0; - tmp = BN_CTX_get(ctx); - if (!tmp) - goto err; - if ((mont = BN_MONT_CTX_new()) == NULL) - goto err; - if (!BN_MONT_CTX_set(mont, dsa->p, ctx)) - goto err; - /* Work out g^q mod p */ - if (!BN_mod_exp_mont(tmp, dsa->g, dsa->q, dsa->p, ctx, mont)) - goto err; - if (!BN_cmp(tmp, BN_value_one())) - rv = 1; - else - rv = 0; - err: - BN_CTX_end(ctx); - if (mont) - BN_MONT_CTX_free(mont); - BN_CTX_free(ctx); - return rv; - -} -#endif -/* crypto/dsa/dsa_key.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -#ifndef OPENSSL_NO_SHA -# include "bn.h" -# include "dsa.h" -# include "rand.h" - -# ifdef OPENSSL_FIPS -# include -# endif - -static int dsa_builtin_keygen(DSA *dsa); - -int DSA_generate_key(DSA *dsa) -{ -# ifdef OPENSSL_FIPS - if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) - && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { - DSAerr(DSA_F_DSA_GENERATE_KEY, DSA_R_NON_FIPS_DSA_METHOD); - return 0; - } -# endif - if (dsa->meth->dsa_keygen) - return dsa->meth->dsa_keygen(dsa); -# ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dsa_generate_key(dsa); -# endif - return dsa_builtin_keygen(dsa); -} - -static int dsa_builtin_keygen(DSA *dsa) -{ - int ok = 0; - BN_CTX *ctx = NULL; - BIGNUM *pub_key = NULL, *priv_key = NULL; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - if (dsa->priv_key == NULL) { - if ((priv_key = BN_new()) == NULL) - goto err; - } else - priv_key = dsa->priv_key; - - do - if (!BN_rand_range(priv_key, dsa->q)) - goto err; - while (BN_is_zero(priv_key)) ; - - if (dsa->pub_key == NULL) { - if ((pub_key = BN_new()) == NULL) - goto err; - } else - pub_key = dsa->pub_key; - - { - BIGNUM local_prk; - BIGNUM *prk; - - if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { - BN_init(&local_prk); - prk = &local_prk; - BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); - } else - prk = priv_key; - - if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) - goto err; - } - - dsa->priv_key = priv_key; - dsa->pub_key = pub_key; - ok = 1; - - err: - if ((pub_key != NULL) && (dsa->pub_key == NULL)) - BN_free(pub_key); - if ((priv_key != NULL) && (dsa->priv_key == NULL)) - BN_free(priv_key); - if (ctx != NULL) - BN_CTX_free(ctx); - return (ok); -} -#endif -/* crypto/dsa/dsa_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* Original version from Steven Schoch */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "dsa.h" -// #include "asn1.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -#ifdef OPENSSL_FIPS -# include -#endif - -const char DSA_version[] = "DSA" OPENSSL_VERSION_PTEXT; - -static const DSA_METHOD *default_DSA_method = NULL; - -void DSA_set_default_method(const DSA_METHOD *meth) -{ - default_DSA_method = meth; -} - -const DSA_METHOD *DSA_get_default_method(void) -{ - if (!default_DSA_method) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_dsa_openssl(); - else - return DSA_OpenSSL(); -#else - default_DSA_method = DSA_OpenSSL(); -#endif - } - return default_DSA_method; -} - -DSA *DSA_new(void) -{ - return DSA_new_method(NULL); -} - -int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) -{ - /* - * NB: The caller is specifically setting a method, so it's not up to us - * to deal with which ENGINE it comes from. - */ - const DSA_METHOD *mtmp; - mtmp = dsa->meth; - if (mtmp->finish) - mtmp->finish(dsa); -#ifndef OPENSSL_NO_ENGINE - if (dsa->engine) { - ENGINE_finish(dsa->engine); - dsa->engine = NULL; - } -#endif - dsa->meth = meth; - if (meth->init) - meth->init(dsa); - return 1; -} - -DSA *DSA_new_method(ENGINE *engine) -{ - DSA *ret; - - ret = (DSA *)OPENSSL_malloc(sizeof(DSA)); - if (ret == NULL) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return (NULL); - } - ret->meth = DSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE - if (engine) { - if (!ENGINE_init(engine)) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); - OPENSSL_free(ret); - return NULL; - } - ret->engine = engine; - } else - ret->engine = ENGINE_get_default_DSA(); - if (ret->engine) { - ret->meth = ENGINE_get_DSA(ret->engine); - if (!ret->meth) { - DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); - ENGINE_finish(ret->engine); - OPENSSL_free(ret); - return NULL; - } - } -#endif - - ret->pad = 0; - ret->version = 0; - ret->write_params = 1; - ret->p = NULL; - ret->q = NULL; - ret->g = NULL; - - ret->pub_key = NULL; - ret->priv_key = NULL; - - ret->kinv = NULL; - ret->r = NULL; - ret->method_mont_p = NULL; - - ret->references = 1; - ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); - OPENSSL_free(ret); - ret = NULL; - } - - return (ret); -} - -void DSA_free(DSA *r) -{ - int i; - - if (r == NULL) - return; - - i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DSA); -#ifdef REF_PRINT - REF_PRINT("DSA", r); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "DSA_free, bad reference count\n"); - abort(); - } -#endif - - if (r->meth->finish) - r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE - if (r->engine) - ENGINE_finish(r->engine); -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); - - if (r->p != NULL) - BN_clear_free(r->p); - if (r->q != NULL) - BN_clear_free(r->q); - if (r->g != NULL) - BN_clear_free(r->g); - if (r->pub_key != NULL) - BN_clear_free(r->pub_key); - if (r->priv_key != NULL) - BN_clear_free(r->priv_key); - if (r->kinv != NULL) - BN_clear_free(r->kinv); - if (r->r != NULL) - BN_clear_free(r->r); - OPENSSL_free(r); -} - -int DSA_up_ref(DSA *r) -{ - int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA); -#ifdef REF_PRINT - REF_PRINT("DSA", r); -#endif -#ifdef REF_CHECK - if (i < 2) { - fprintf(stderr, "DSA_up_ref, bad reference count\n"); - abort(); - } -#endif - return ((i > 1) ? 1 : 0); -} - -int DSA_size(const DSA *r) -{ - int ret, i; - ASN1_INTEGER bs; - unsigned char buf[4]; /* 4 bytes looks really small. However, - * i2d_ASN1_INTEGER() will not look beyond - * the first byte, as long as the second - * parameter is NULL. */ - - i = BN_num_bits(r->q); - bs.length = (i + 7) / 8; - bs.data = buf; - bs.type = V_ASN1_INTEGER; - /* If the top bit is set the asn1 encoding is 1 larger. */ - buf[0] = 0xff; - - i = i2d_ASN1_INTEGER(&bs, NULL); - i += i; /* r and s */ - ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); - return (ret); -} - -int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp, - new_func, dup_func, free_func); -} - -int DSA_set_ex_data(DSA *d, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&d->ex_data, idx, arg)); -} - -void *DSA_get_ex_data(DSA *d, int idx) -{ - return (CRYPTO_get_ex_data(&d->ex_data, idx)); -} - -#ifndef OPENSSL_NO_DH -DH *DSA_dup_DH(const DSA *r) -{ - /* - * DSA has p, q, g, optional pub_key, optional priv_key. DH has p, - * optional length, g, optional pub_key, optional priv_key, optional q. - */ - - DH *ret = NULL; - - if (r == NULL) - goto err; - ret = DH_new(); - if (ret == NULL) - goto err; - if (r->p != NULL) - if ((ret->p = BN_dup(r->p)) == NULL) - goto err; - if (r->q != NULL) { - ret->length = BN_num_bits(r->q); - if ((ret->q = BN_dup(r->q)) == NULL) - goto err; - } - if (r->g != NULL) - if ((ret->g = BN_dup(r->g)) == NULL) - goto err; - if (r->pub_key != NULL) - if ((ret->pub_key = BN_dup(r->pub_key)) == NULL) - goto err; - if (r->priv_key != NULL) - if ((ret->priv_key = BN_dup(r->priv_key)) == NULL) - goto err; - - return ret; - - err: - if (ret != NULL) - DH_free(ret); - return NULL; -} -#endif -/* crypto/dsa/dsa_ossl.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* Original version from Steven Schoch */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -#include "sha.h" -// #include "dsa.h" -// #include "rand.h" -// #include "asn1.h" - -static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); -static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp); -static int dsa_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa); -static int dsa_init(DSA *dsa); -static int dsa_finish(DSA *dsa); -static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, - BN_CTX *ctx); - -static DSA_METHOD openssl_dsa_meth = { - "OpenSSL DSA method", - dsa_do_sign, - dsa_sign_setup, - dsa_do_verify, - NULL, /* dsa_mod_exp, */ - NULL, /* dsa_bn_mod_exp, */ - dsa_init, - dsa_finish, - 0, - NULL, - NULL, - NULL -}; - -/*- - * These macro wrappers replace attempts to use the dsa_mod_exp() and - * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of - * having a the macro work as an expression by bundling an "err_instr". So; - * - * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx, - * dsa->method_mont_p)) goto err; - * - * can be replaced by; - * - * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx, - * dsa->method_mont_p); - */ - -#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \ - do { \ - int _tmp_res53; \ - if ((dsa)->meth->dsa_mod_exp) \ - _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \ - (a2), (p2), (m), (ctx), (in_mont)); \ - else \ - _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \ - (m), (ctx), (in_mont)); \ - if (!_tmp_res53) err_instr; \ - } while(0) -#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \ - do { \ - int _tmp_res53; \ - if ((dsa)->meth->bn_mod_exp) \ - _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \ - (m), (ctx), (m_ctx)); \ - else \ - _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \ - if (!_tmp_res53) err_instr; \ - } while(0) - -const DSA_METHOD *DSA_OpenSSL(void) -{ - return &openssl_dsa_meth; -} - -static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) -{ - BIGNUM *kinv = NULL, *r = NULL, *s = NULL; - BIGNUM *m, *blind, *blindm, *tmp; - BN_CTX *ctx = NULL; - int reason = ERR_R_BN_LIB; - DSA_SIG *ret = NULL; - int noredo = 0; - - if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { - reason = DSA_R_MISSING_PARAMETERS; - goto err; - } - - s = BN_new(); - if (s == NULL) - goto err; - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - m = BN_CTX_get(ctx); - blind = BN_CTX_get(ctx); - blindm = BN_CTX_get(ctx); - tmp = BN_CTX_get(ctx); - if (tmp == NULL) - goto err; - - redo: - if ((dsa->kinv == NULL) || (dsa->r == NULL)) { - if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) - goto err; - } else { - kinv = dsa->kinv; - dsa->kinv = NULL; - r = dsa->r; - dsa->r = NULL; - noredo = 1; - } - - if (dlen > BN_num_bytes(dsa->q)) - /* - * if the digest length is greater than the size of q use the - * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3, - * 4.2 - */ - dlen = BN_num_bytes(dsa->q); - if (BN_bin2bn(dgst, dlen, m) == NULL) - goto err; - - /* - * The normal signature calculation is: - * - * s := k^-1 * (m + r * priv_key) mod q - * - * We will blind this to protect against side channel attacks - * - * s := blind^-1 * k^-1 * (blind * m + blind * r * priv_key) mod q - */ - - /* Generate a blinding value */ - do { - if (!BN_rand(blind, BN_num_bits(dsa->q) - 1, -1, 0)) - goto err; - } while (BN_is_zero(blind)); - BN_set_flags(blind, BN_FLG_CONSTTIME); - BN_set_flags(blindm, BN_FLG_CONSTTIME); - BN_set_flags(tmp, BN_FLG_CONSTTIME); - - /* tmp := blind * priv_key * r mod q */ - if (!BN_mod_mul(tmp, blind, dsa->priv_key, dsa->q, ctx)) - goto err; - if (!BN_mod_mul(tmp, tmp, r, dsa->q, ctx)) - goto err; - - /* blindm := blind * m mod q */ - if (!BN_mod_mul(blindm, blind, m, dsa->q, ctx)) - goto err; - - /* s : = (blind * priv_key * r) + (blind * m) mod q */ - if (!BN_mod_add_quick(s, tmp, blindm, dsa->q)) - goto err; - - /* s := s * k^-1 mod q */ - if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) - goto err; - - /* s:= s * blind^-1 mod q */ - if (BN_mod_inverse(blind, blind, dsa->q, ctx) == NULL) - goto err; - if (!BN_mod_mul(s, s, blind, dsa->q, ctx)) - goto err; - - /* - * Redo if r or s is zero as required by FIPS 186-3: this is very - * unlikely. - */ - if (BN_is_zero(r) || BN_is_zero(s)) { - if (noredo) { - reason = DSA_R_NEED_NEW_SETUP_VALUES; - goto err; - } - goto redo; - } - ret = DSA_SIG_new(); - if (ret == NULL) - goto err; - ret->r = r; - ret->s = s; - - err: - if (ret == NULL) { - DSAerr(DSA_F_DSA_DO_SIGN, reason); - BN_free(r); - BN_free(s); - } - BN_CTX_free(ctx); - BN_clear_free(kinv); - return ret; -} - -static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp) -{ - BN_CTX *ctx; - BIGNUM k, kq, *K, *kinv = NULL, *r = NULL; - BIGNUM l, m; - int ret = 0; - int q_bits; - - if (!dsa->p || !dsa->q || !dsa->g) { - DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); - return 0; - } - - BN_init(&k); - BN_init(&kq); - BN_init(&l); - BN_init(&m); - - if (ctx_in == NULL) { - if ((ctx = BN_CTX_new()) == NULL) - goto err; - } else - ctx = ctx_in; - - if ((r = BN_new()) == NULL) - goto err; - - /* Preallocate space */ - q_bits = BN_num_bits(dsa->q) + sizeof(dsa->q->d[0]) * 16; - if (!BN_set_bit(&k, q_bits) - || !BN_set_bit(&l, q_bits) - || !BN_set_bit(&m, q_bits)) - goto err; - - /* Get random k */ - do - if (!BN_rand_range(&k, dsa->q)) - goto err; - while (BN_is_zero(&k)); - - if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { - BN_set_flags(&k, BN_FLG_CONSTTIME); - BN_set_flags(&l, BN_FLG_CONSTTIME); - } - - if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { - if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, - CRYPTO_LOCK_DSA, dsa->p, ctx)) - goto err; - } - - /* Compute r = (g^k mod p) mod q */ - - if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { - /* - * We do not want timing information to leak the length of k, so we - * compute G^k using an equivalent scalar of fixed bit-length. - * - * We unconditionally perform both of these additions to prevent a - * small timing information leakage. We then choose the sum that is - * one bit longer than the modulus. - * - * TODO: revisit the BN_copy aiming for a memory access agnostic - * conditional copy. - */ - if (!BN_add(&l, &k, dsa->q) - || !BN_add(&m, &l, dsa->q) - || !BN_copy(&kq, BN_num_bits(&l) > q_bits ? &l : &m)) - goto err; - - BN_set_flags(&kq, BN_FLG_CONSTTIME); - - K = &kq; - } else { - K = &k; - } - - DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, - dsa->method_mont_p); - if (!BN_mod(r, r, dsa->q, ctx)) - goto err; - - /* Compute part of 's = inv(k) (m + xr) mod q' */ - if ((kinv = dsa_mod_inverse_fermat(&k, dsa->q, ctx)) == NULL) - goto err; - - if (*kinvp != NULL) - BN_clear_free(*kinvp); - *kinvp = kinv; - kinv = NULL; - if (*rp != NULL) - BN_clear_free(*rp); - *rp = r; - ret = 1; - err: - if (!ret) { - DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB); - if (r != NULL) - BN_clear_free(r); - } - if (ctx_in == NULL) - BN_CTX_free(ctx); - BN_clear_free(&k); - BN_clear_free(&kq); - BN_clear_free(&l); - BN_clear_free(&m); - return ret; -} - -static int dsa_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa) -{ - BN_CTX *ctx; - BIGNUM u1, u2, t1; - BN_MONT_CTX *mont = NULL; - int ret = -1, i; - if (!dsa->p || !dsa->q || !dsa->g) { - DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS); - return -1; - } - - i = BN_num_bits(dsa->q); - /* fips 186-3 allows only different sizes for q */ - if (i != 160 && i != 224 && i != 256) { - DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE); - return -1; - } - - if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { - DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE); - return -1; - } - BN_init(&u1); - BN_init(&u2); - BN_init(&t1); - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || - BN_ucmp(sig->r, dsa->q) >= 0) { - ret = 0; - goto err; - } - if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || - BN_ucmp(sig->s, dsa->q) >= 0) { - ret = 0; - goto err; - } - - /* - * Calculate W = inv(S) mod Q save W in u2 - */ - if ((BN_mod_inverse(&u2, sig->s, dsa->q, ctx)) == NULL) - goto err; - - /* save M in u1 */ - if (dgst_len > (i >> 3)) - /* - * if the digest length is greater than the size of q use the - * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3, - * 4.2 - */ - dgst_len = (i >> 3); - if (BN_bin2bn(dgst, dgst_len, &u1) == NULL) - goto err; - - /* u1 = M * w mod q */ - if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) - goto err; - - /* u2 = r * w mod q */ - if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) - goto err; - - if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { - mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p, - CRYPTO_LOCK_DSA, dsa->p, ctx); - if (!mont) - goto err; - } - - DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, - ctx, mont); - /* BN_copy(&u1,&t1); */ - /* let u1 = u1 mod q */ - if (!BN_mod(&u1, &t1, dsa->q, ctx)) - goto err; - - /* - * V is now in u1. If the signature is correct, it will be equal to R. - */ - ret = (BN_ucmp(&u1, sig->r) == 0); - - err: - if (ret < 0) - DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB); - if (ctx != NULL) - BN_CTX_free(ctx); - BN_free(&u1); - BN_free(&u2); - BN_free(&t1); - return (ret); -} - -static int dsa_init(DSA *dsa) -{ - dsa->flags |= DSA_FLAG_CACHE_MONT_P; - return (1); -} - -static int dsa_finish(DSA *dsa) -{ - if (dsa->method_mont_p) - BN_MONT_CTX_free(dsa->method_mont_p); - return (1); -} - -/* - * Compute the inverse of k modulo q. - * Since q is prime, Fermat's Little Theorem applies, which reduces this to - * mod-exp operation. Both the exponent and modulus are public information - * so a mod-exp that doesn't leak the base is sufficient. A newly allocated - * BIGNUM is returned which the caller must free. - */ -static BIGNUM *dsa_mod_inverse_fermat(const BIGNUM *k, const BIGNUM *q, - BN_CTX *ctx) -{ - BIGNUM *res = NULL; - BIGNUM *r, e; - - if ((r = BN_new()) == NULL) - return NULL; - - BN_init(&e); - - if (BN_set_word(r, 2) - && BN_sub(&e, q, r) - && BN_mod_exp_mont(r, k, &e, q, ctx, NULL)) - res = r; - else - BN_free(r); - BN_free(&e); - return res; -} -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" -#include "evp.h" -// #include "bn.h" -#include "evp_locl.h" -#include "dsa_locl.h" - -/* DSA pkey context structure */ - -typedef struct { - /* Parameter gen parameters */ - int nbits; /* size of p in bits (default: 1024) */ - int qbits; /* size of q in bits (default: 160) */ - const EVP_MD *pmd; /* MD for parameter generation */ - /* Keygen callback info */ - int gentmp[2]; - /* message digest */ - const EVP_MD *md; /* MD for the signature */ -} DSA_PKEY_CTX; - -static int pkey_dsa_init(EVP_PKEY_CTX *ctx) -{ - DSA_PKEY_CTX *dctx; - dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX)); - if (!dctx) - return 0; - dctx->nbits = 1024; - dctx->qbits = 160; - dctx->pmd = NULL; - dctx->md = NULL; - - ctx->data = dctx; - ctx->keygen_info = dctx->gentmp; - ctx->keygen_info_count = 2; - - return 1; -} - -static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - DSA_PKEY_CTX *dctx, *sctx; - if (!pkey_dsa_init(dst)) - return 0; - sctx = src->data; - dctx = dst->data; - dctx->nbits = sctx->nbits; - dctx->qbits = sctx->qbits; - dctx->pmd = sctx->pmd; - dctx->md = sctx->md; - return 1; -} - -static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) -{ - DSA_PKEY_CTX *dctx = ctx->data; - if (dctx) - OPENSSL_free(dctx); -} - -static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbslen) -{ - int ret, type; - unsigned int sltmp; - DSA_PKEY_CTX *dctx = ctx->data; - DSA *dsa = ctx->pkey->pkey.dsa; - - if (dctx->md) - type = EVP_MD_type(dctx->md); - else - type = NID_sha1; - - ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa); - - if (ret <= 0) - return ret; - *siglen = sltmp; - return 1; -} - -static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) -{ - int ret, type; - DSA_PKEY_CTX *dctx = ctx->data; - DSA *dsa = ctx->pkey->pkey.dsa; - - if (dctx->md) - type = EVP_MD_type(dctx->md); - else - type = NID_sha1; - - ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa); - - return ret; -} - -static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - DSA_PKEY_CTX *dctx = ctx->data; - switch (type) { - case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: - if (p1 < 256) - return -2; - dctx->nbits = p1; - return 1; - - case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: - if (p1 != 160 && p1 != 224 && p1 && p1 != 256) - return -2; - dctx->qbits = p1; - return 1; - - case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: - if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha256) { - DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); - return 0; - } - dctx->pmd = p2; - return 1; - - case EVP_PKEY_CTRL_MD: - if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && - EVP_MD_type((const EVP_MD *)p2) != NID_dsa && - EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA && - EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { - DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); - return 0; - } - dctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_GET_MD: - *(const EVP_MD **)p2 = dctx->md; - return 1; - - case EVP_PKEY_CTRL_DIGESTINIT: - case EVP_PKEY_CTRL_PKCS7_SIGN: - case EVP_PKEY_CTRL_CMS_SIGN: - return 1; - - case EVP_PKEY_CTRL_PEER_KEY: - DSAerr(DSA_F_PKEY_DSA_CTRL, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - default: - return -2; - - } -} - -static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!strcmp(type, "dsa_paramgen_bits")) { - int nbits; - nbits = atoi(value); - return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); - } - if (!strcmp(type, "dsa_paramgen_q_bits")) { - int qbits = atoi(value); - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, - NULL); - } - if (strcmp(type, "dsa_paramgen_md") == 0) { - const EVP_MD *md = EVP_get_digestbyname(value); - - if (md == NULL) { - DSAerr(DSA_F_PKEY_DSA_CTRL_STR, DSA_R_INVALID_DIGEST_TYPE); - return 0; - } - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, - EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, - (void *)md); - } - return -2; -} - -static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - DSA *dsa = NULL; - DSA_PKEY_CTX *dctx = ctx->data; - BN_GENCB *pcb, cb; - int ret; - if (ctx->pkey_gencb) { - pcb = &cb; - evp_pkey_set_cb_translate(pcb, ctx); - } else - pcb = NULL; - dsa = DSA_new(); - if (!dsa) - return 0; - ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, - NULL, 0, NULL, NULL, NULL, pcb); - if (ret) - EVP_PKEY_assign_DSA(pkey, dsa); - else - DSA_free(dsa); - return ret; -} - -static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - DSA *dsa = NULL; - if (ctx->pkey == NULL) { - DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); - return 0; - } - dsa = DSA_new(); - if (!dsa) - return 0; - EVP_PKEY_assign_DSA(pkey, dsa); - /* Note: if error return, pkey is freed by parent routine */ - if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) - return 0; - return DSA_generate_key(pkey->pkey.dsa); -} - -const EVP_PKEY_METHOD dsa_pkey_meth = { - EVP_PKEY_DSA, - EVP_PKEY_FLAG_AUTOARGLEN, - pkey_dsa_init, - pkey_dsa_copy, - pkey_dsa_cleanup, - - 0, - pkey_dsa_paramgen, - - 0, - pkey_dsa_keygen, - - 0, - pkey_dsa_sign, - - 0, - pkey_dsa_verify, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_dsa_ctrl, - pkey_dsa_ctrl_str -}; -/* crypto/dsa/dsa_prn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "dsa.h" - -#ifndef OPENSSL_NO_FP_API -int DSA_print_fp(FILE *fp, const DSA *x, int off) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = DSA_print(b, x, off); - BIO_free(b); - return (ret); -} - -int DSAparams_print_fp(FILE *fp, const DSA *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = DSAparams_print(b, x); - BIO_free(b); - return (ret); -} -#endif - -int DSA_print(BIO *bp, const DSA *x, int off) -{ - EVP_PKEY *pk; - int ret; - pk = EVP_PKEY_new(); - if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) - return 0; - ret = EVP_PKEY_print_private(bp, pk, off, NULL); - EVP_PKEY_free(pk); - return ret; -} - -int DSAparams_print(BIO *bp, const DSA *x) -{ - EVP_PKEY *pk; - int ret; - pk = EVP_PKEY_new(); - if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) - return 0; - ret = EVP_PKEY_print_params(bp, pk, 4, NULL); - EVP_PKEY_free(pk); - return ret; -} -/* crypto/dsa/dsa_sign.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* Original version from Steven Schoch */ - -// #include "cryptlib.h" -// #include "dsa.h" -// #include "rand.h" -// #include "bn.h" - -DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) - && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { - DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD); - return NULL; - } -#endif - return dsa->meth->dsa_do_sign(dgst, dlen, dsa); -} - -int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) - && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { - DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD); - return 0; - } -#endif - return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); -} - -DSA_SIG *DSA_SIG_new(void) -{ - DSA_SIG *sig; - sig = OPENSSL_malloc(sizeof(DSA_SIG)); - if (!sig) - return NULL; - sig->r = NULL; - sig->s = NULL; - return sig; -} - -void DSA_SIG_free(DSA_SIG *sig) -{ - if (sig) { - if (sig->r) - BN_free(sig->r); - if (sig->s) - BN_free(sig->s); - OPENSSL_free(sig); - } -} -/* crypto/dsa/dsa_vrf.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* Original version from Steven Schoch */ - -// #include "cryptlib.h" -// #include "dsa.h" - -int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, - DSA *dsa) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) - && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { - DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD); - return -1; - } -#endif - return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa); -} diff --git a/Sources/COpenSSL/dsa_locl.h b/Sources/COpenSSL/dsa_locl.h deleted file mode 100644 index 1594ee40..00000000 --- a/Sources/COpenSSL/dsa_locl.h +++ /dev/null @@ -1,69 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "dsa.h" - -int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, - const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb); - -int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N, - const EVP_MD *evpmd, const unsigned char *seed_in, - size_t seed_len, int idx, unsigned char *seed_out, - int *counter_ret, unsigned long *h_ret, - BN_GENCB *cb); - -int dsa_paramgen_check_g(DSA *dsa); diff --git a/Sources/COpenSSL/dso.h b/Sources/COpenSSL/dso.h deleted file mode 100644 index 5072f212..00000000 --- a/Sources/COpenSSL/dso.h +++ /dev/null @@ -1,451 +0,0 @@ -/* dso.h */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_DSO_H -# define HEADER_DSO_H - -# include "crypto.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* These values are used as commands to DSO_ctrl() */ -# define DSO_CTRL_GET_FLAGS 1 -# define DSO_CTRL_SET_FLAGS 2 -# define DSO_CTRL_OR_FLAGS 3 - -/* - * By default, DSO_load() will translate the provided filename into a form - * typical for the platform (more specifically the DSO_METHOD) using the - * dso_name_converter function of the method. Eg. win32 will transform "blah" - * into "blah.dll", and dlfcn will transform it into "libblah.so". The - * behaviour can be overriden by setting the name_converter callback in the - * DSO object (using DSO_set_name_converter()). This callback could even - * utilise the DSO_METHOD's converter too if it only wants to override - * behaviour for one or two possible DSO methods. However, the following flag - * can be set in a DSO to prevent *any* native name-translation at all - eg. - * if the caller has prompted the user for a path to a driver library so the - * filename should be interpreted as-is. - */ -# define DSO_FLAG_NO_NAME_TRANSLATION 0x01 -/* - * An extra flag to give if only the extension should be added as - * translation. This is obviously only of importance on Unix and other - * operating systems where the translation also may prefix the name with - * something, like 'lib', and ignored everywhere else. This flag is also - * ignored if DSO_FLAG_NO_NAME_TRANSLATION is used at the same time. - */ -# define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY 0x02 - -/* - * The following flag controls the translation of symbol names to upper case. - * This is currently only being implemented for OpenVMS. - */ -# define DSO_FLAG_UPCASE_SYMBOL 0x10 - -/* - * This flag loads the library with public symbols. Meaning: The exported - * symbols of this library are public to all libraries loaded after this - * library. At the moment only implemented in unix. - */ -# define DSO_FLAG_GLOBAL_SYMBOLS 0x20 - -typedef void (*DSO_FUNC_TYPE) (void); - -typedef struct dso_st DSO; - -/* - * The function prototype used for method functions (or caller-provided - * callbacks) that transform filenames. They are passed a DSO structure - * pointer (or NULL if they are to be used independantly of a DSO object) and - * a filename to transform. They should either return NULL (if there is an - * error condition) or a newly allocated string containing the transformed - * form that the caller will need to free with OPENSSL_free() when done. - */ -typedef char *(*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *); -/* - * The function prototype used for method functions (or caller-provided - * callbacks) that merge two file specifications. They are passed a DSO - * structure pointer (or NULL if they are to be used independantly of a DSO - * object) and two file specifications to merge. They should either return - * NULL (if there is an error condition) or a newly allocated string - * containing the result of merging that the caller will need to free with - * OPENSSL_free() when done. Here, merging means that bits and pieces are - * taken from each of the file specifications and added together in whatever - * fashion that is sensible for the DSO method in question. The only rule - * that really applies is that if the two specification contain pieces of the - * same type, the copy from the first string takes priority. One could see - * it as the first specification is the one given by the user and the second - * being a bunch of defaults to add on if they're missing in the first. - */ -typedef char *(*DSO_MERGER_FUNC)(DSO *, const char *, const char *); - -typedef struct dso_meth_st { - const char *name; - /* - * Loads a shared library, NB: new DSO_METHODs must ensure that a - * successful load populates the loaded_filename field, and likewise a - * successful unload OPENSSL_frees and NULLs it out. - */ - int (*dso_load) (DSO *dso); - /* Unloads a shared library */ - int (*dso_unload) (DSO *dso); - /* Binds a variable */ - void *(*dso_bind_var) (DSO *dso, const char *symname); - /* - * Binds a function - assumes a return type of DSO_FUNC_TYPE. This should - * be cast to the real function prototype by the caller. Platforms that - * don't have compatible representations for different prototypes (this - * is possible within ANSI C) are highly unlikely to have shared - * libraries at all, let alone a DSO_METHOD implemented for them. - */ - DSO_FUNC_TYPE (*dso_bind_func) (DSO *dso, const char *symname); -/* I don't think this would actually be used in any circumstances. */ -# if 0 - /* Unbinds a variable */ - int (*dso_unbind_var) (DSO *dso, char *symname, void *symptr); - /* Unbinds a function */ - int (*dso_unbind_func) (DSO *dso, char *symname, DSO_FUNC_TYPE symptr); -# endif - /* - * The generic (yuck) "ctrl()" function. NB: Negative return values - * (rather than zero) indicate errors. - */ - long (*dso_ctrl) (DSO *dso, int cmd, long larg, void *parg); - /* - * The default DSO_METHOD-specific function for converting filenames to a - * canonical native form. - */ - DSO_NAME_CONVERTER_FUNC dso_name_converter; - /* - * The default DSO_METHOD-specific function for converting filenames to a - * canonical native form. - */ - DSO_MERGER_FUNC dso_merger; - /* [De]Initialisation handlers. */ - int (*init) (DSO *dso); - int (*finish) (DSO *dso); - /* Return pathname of the module containing location */ - int (*pathbyaddr) (void *addr, char *path, int sz); - /* Perform global symbol lookup, i.e. among *all* modules */ - void *(*globallookup) (const char *symname); -} DSO_METHOD; - -/**********************************************************************/ -/* The low-level handle type used to refer to a loaded shared library */ - -struct dso_st { - DSO_METHOD *meth; - /* - * Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use - * anything but will need to cache the filename for use in the dso_bind - * handler. All in all, let each method control its own destiny. - * "Handles" and such go in a STACK. - */ - STACK_OF(void) *meth_data; - int references; - int flags; - /* - * For use by applications etc ... use this for your bits'n'pieces, don't - * touch meth_data! - */ - CRYPTO_EX_DATA ex_data; - /* - * If this callback function pointer is set to non-NULL, then it will be - * used in DSO_load() in place of meth->dso_name_converter. NB: This - * should normally set using DSO_set_name_converter(). - */ - DSO_NAME_CONVERTER_FUNC name_converter; - /* - * If this callback function pointer is set to non-NULL, then it will be - * used in DSO_load() in place of meth->dso_merger. NB: This should - * normally set using DSO_set_merger(). - */ - DSO_MERGER_FUNC merger; - /* - * This is populated with (a copy of) the platform-independant filename - * used for this DSO. - */ - char *filename; - /* - * This is populated with (a copy of) the translated filename by which - * the DSO was actually loaded. It is NULL iff the DSO is not currently - * loaded. NB: This is here because the filename translation process may - * involve a callback being invoked more than once not only to convert to - * a platform-specific form, but also to try different filenames in the - * process of trying to perform a load. As such, this variable can be - * used to indicate (a) whether this DSO structure corresponds to a - * loaded library or not, and (b) the filename with which it was actually - * loaded. - */ - char *loaded_filename; -}; - -DSO *DSO_new(void); -DSO *DSO_new_method(DSO_METHOD *method); -int DSO_free(DSO *dso); -int DSO_flags(DSO *dso); -int DSO_up_ref(DSO *dso); -long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg); - -/* - * This function sets the DSO's name_converter callback. If it is non-NULL, - * then it will be used instead of the associated DSO_METHOD's function. If - * oldcb is non-NULL then it is set to the function pointer value being - * replaced. Return value is non-zero for success. - */ -int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb, - DSO_NAME_CONVERTER_FUNC *oldcb); -/* - * These functions can be used to get/set the platform-independant filename - * used for a DSO. NB: set will fail if the DSO is already loaded. - */ -const char *DSO_get_filename(DSO *dso); -int DSO_set_filename(DSO *dso, const char *filename); -/* - * This function will invoke the DSO's name_converter callback to translate a - * filename, or if the callback isn't set it will instead use the DSO_METHOD's - * converter. If "filename" is NULL, the "filename" in the DSO itself will be - * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is - * simply duplicated. NB: This function is usually called from within a - * DSO_METHOD during the processing of a DSO_load() call, and is exposed so - * that caller-created DSO_METHODs can do the same thing. A non-NULL return - * value will need to be OPENSSL_free()'d. - */ -char *DSO_convert_filename(DSO *dso, const char *filename); -/* - * This function will invoke the DSO's merger callback to merge two file - * specifications, or if the callback isn't set it will instead use the - * DSO_METHOD's merger. A non-NULL return value will need to be - * OPENSSL_free()'d. - */ -char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2); -/* - * If the DSO is currently loaded, this returns the filename that it was - * loaded under, otherwise it returns NULL. So it is also useful as a test as - * to whether the DSO is currently loaded. NB: This will not necessarily - * return the same value as DSO_convert_filename(dso, dso->filename), because - * the DSO_METHOD's load function may have tried a variety of filenames (with - * and/or without the aid of the converters) before settling on the one it - * actually loaded. - */ -const char *DSO_get_loaded_filename(DSO *dso); - -void DSO_set_default_method(DSO_METHOD *meth); -DSO_METHOD *DSO_get_default_method(void); -DSO_METHOD *DSO_get_method(DSO *dso); -DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth); - -/* - * The all-singing all-dancing load function, you normally pass NULL for the - * first and third parameters. Use DSO_up and DSO_free for subsequent - * reference count handling. Any flags passed in will be set in the - * constructed DSO after its init() function but before the load operation. - * If 'dso' is non-NULL, 'flags' is ignored. - */ -DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags); - -/* This function binds to a variable inside a shared library. */ -void *DSO_bind_var(DSO *dso, const char *symname); - -/* This function binds to a function inside a shared library. */ -DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname); - -/* - * This method is the default, but will beg, borrow, or steal whatever method - * should be the default on any particular platform (including - * DSO_METH_null() if necessary). - */ -DSO_METHOD *DSO_METHOD_openssl(void); - -/* - * This method is defined for all platforms - if a platform has no DSO - * support then this will be the only method! - */ -DSO_METHOD *DSO_METHOD_null(void); - -/* - * If DSO_DLFCN is defined, the standard dlfcn.h-style functions (dlopen, - * dlclose, dlsym, etc) will be used and incorporated into this method. If - * not, this method will return NULL. - */ -DSO_METHOD *DSO_METHOD_dlfcn(void); - -/* - * If DSO_DL is defined, the standard dl.h-style functions (shl_load, - * shl_unload, shl_findsym, etc) will be used and incorporated into this - * method. If not, this method will return NULL. - */ -DSO_METHOD *DSO_METHOD_dl(void); - -/* If WIN32 is defined, use DLLs. If not, return NULL. */ -DSO_METHOD *DSO_METHOD_win32(void); - -/* If VMS is defined, use shared images. If not, return NULL. */ -DSO_METHOD *DSO_METHOD_vms(void); - -/* - * This function writes null-terminated pathname of DSO module containing - * 'addr' into 'sz' large caller-provided 'path' and returns the number of - * characters [including trailing zero] written to it. If 'sz' is 0 or - * negative, 'path' is ignored and required amount of charachers [including - * trailing zero] to accomodate pathname is returned. If 'addr' is NULL, then - * pathname of cryptolib itself is returned. Negative or zero return value - * denotes error. - */ -int DSO_pathbyaddr(void *addr, char *path, int sz); - -/* - * This function should be used with caution! It looks up symbols in *all* - * loaded modules and if module gets unloaded by somebody else attempt to - * dereference the pointer is doomed to have fatal consequences. Primary - * usage for this function is to probe *core* system functionality, e.g. - * check if getnameinfo(3) is available at run-time without bothering about - * OS-specific details such as libc.so.versioning or where does it actually - * reside: in libc itself or libsocket. - */ -void *DSO_global_lookup(const char *name); - -/* If BeOS is defined, use shared images. If not, return NULL. */ -DSO_METHOD *DSO_METHOD_beos(void); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_DSO_strings(void); - -/* Error codes for the DSO functions. */ - -/* Function codes. */ -# define DSO_F_BEOS_BIND_FUNC 144 -# define DSO_F_BEOS_BIND_VAR 145 -# define DSO_F_BEOS_LOAD 146 -# define DSO_F_BEOS_NAME_CONVERTER 147 -# define DSO_F_BEOS_UNLOAD 148 -# define DSO_F_DLFCN_BIND_FUNC 100 -# define DSO_F_DLFCN_BIND_VAR 101 -# define DSO_F_DLFCN_LOAD 102 -# define DSO_F_DLFCN_MERGER 130 -# define DSO_F_DLFCN_NAME_CONVERTER 123 -# define DSO_F_DLFCN_UNLOAD 103 -# define DSO_F_DL_BIND_FUNC 104 -# define DSO_F_DL_BIND_VAR 105 -# define DSO_F_DL_LOAD 106 -# define DSO_F_DL_MERGER 131 -# define DSO_F_DL_NAME_CONVERTER 124 -# define DSO_F_DL_UNLOAD 107 -# define DSO_F_DSO_BIND_FUNC 108 -# define DSO_F_DSO_BIND_VAR 109 -# define DSO_F_DSO_CONVERT_FILENAME 126 -# define DSO_F_DSO_CTRL 110 -# define DSO_F_DSO_FREE 111 -# define DSO_F_DSO_GET_FILENAME 127 -# define DSO_F_DSO_GET_LOADED_FILENAME 128 -# define DSO_F_DSO_GLOBAL_LOOKUP 139 -# define DSO_F_DSO_LOAD 112 -# define DSO_F_DSO_MERGE 132 -# define DSO_F_DSO_NEW_METHOD 113 -# define DSO_F_DSO_PATHBYADDR 140 -# define DSO_F_DSO_SET_FILENAME 129 -# define DSO_F_DSO_SET_NAME_CONVERTER 122 -# define DSO_F_DSO_UP_REF 114 -# define DSO_F_GLOBAL_LOOKUP_FUNC 138 -# define DSO_F_PATHBYADDR 137 -# define DSO_F_VMS_BIND_SYM 115 -# define DSO_F_VMS_LOAD 116 -# define DSO_F_VMS_MERGER 133 -# define DSO_F_VMS_UNLOAD 117 -# define DSO_F_WIN32_BIND_FUNC 118 -# define DSO_F_WIN32_BIND_VAR 119 -# define DSO_F_WIN32_GLOBALLOOKUP 142 -# define DSO_F_WIN32_GLOBALLOOKUP_FUNC 143 -# define DSO_F_WIN32_JOINER 135 -# define DSO_F_WIN32_LOAD 120 -# define DSO_F_WIN32_MERGER 134 -# define DSO_F_WIN32_NAME_CONVERTER 125 -# define DSO_F_WIN32_PATHBYADDR 141 -# define DSO_F_WIN32_SPLITTER 136 -# define DSO_F_WIN32_UNLOAD 121 - -/* Reason codes. */ -# define DSO_R_CTRL_FAILED 100 -# define DSO_R_DSO_ALREADY_LOADED 110 -# define DSO_R_EMPTY_FILE_STRUCTURE 113 -# define DSO_R_FAILURE 114 -# define DSO_R_FILENAME_TOO_BIG 101 -# define DSO_R_FINISH_FAILED 102 -# define DSO_R_INCORRECT_FILE_SYNTAX 115 -# define DSO_R_LOAD_FAILED 103 -# define DSO_R_NAME_TRANSLATION_FAILED 109 -# define DSO_R_NO_FILENAME 111 -# define DSO_R_NO_FILE_SPECIFICATION 116 -# define DSO_R_NULL_HANDLE 104 -# define DSO_R_SET_FILENAME_FAILED 112 -# define DSO_R_STACK_ERROR 105 -# define DSO_R_SYM_FAILURE 106 -# define DSO_R_UNLOAD_FAILED 107 -# define DSO_R_UNSUPPORTED 108 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/dso_.c b/Sources/COpenSSL/dso_.c deleted file mode 100644 index 52445f45..00000000 --- a/Sources/COpenSSL/dso_.c +++ /dev/null @@ -1,3214 +0,0 @@ -/* dso_beos.c */ -/* - * Written by Marcin Konicki (ahwayakchih@neoni.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "cryptlib.h" -#include "dso.h" - -#if !defined(OPENSSL_SYS_BEOS) -DSO_METHOD *DSO_METHOD_beos(void) -{ - return NULL; -} -#else - -# include - -static int beos_load(DSO *dso); -static int beos_unload(DSO *dso); -static void *beos_bind_var(DSO *dso, const char *symname); -static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname); -# if 0 -static int beos_unbind_var(DSO *dso, char *symname, void *symptr); -static int beos_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); -static int beos_init(DSO *dso); -static int beos_finish(DSO *dso); -static long beos_ctrl(DSO *dso, int cmd, long larg, void *parg); -# endif -static char *beos_name_converter(DSO *dso, const char *filename); - -static DSO_METHOD dso_meth_beos = { - "OpenSSL 'beos' shared library method", - beos_load, - beos_unload, - beos_bind_var, - beos_bind_func, -/* For now, "unbind" doesn't exist */ -# if 0 - NULL, /* unbind_var */ - NULL, /* unbind_func */ -# endif - NULL, /* ctrl */ - beos_name_converter, - NULL, /* init */ - NULL /* finish */ -}; - -DSO_METHOD *DSO_METHOD_beos(void) -{ - return (&dso_meth_beos); -} - -/* - * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to - * the handle (image_id) returned from load_add_on(). - */ - -static int beos_load(DSO *dso) -{ - image_id id; - /* See applicable comments from dso_dl.c */ - char *filename = DSO_convert_filename(dso, NULL); - - if (filename == NULL) { - DSOerr(DSO_F_BEOS_LOAD, DSO_R_NO_FILENAME); - goto err; - } - id = load_add_on(filename); - if (id < 1) { - DSOerr(DSO_F_BEOS_LOAD, DSO_R_LOAD_FAILED); - ERR_add_error_data(3, "filename(", filename, ")"); - goto err; - } - if (!sk_push(dso->meth_data, (char *)id)) { - DSOerr(DSO_F_BEOS_LOAD, DSO_R_STACK_ERROR); - goto err; - } - /* Success */ - dso->loaded_filename = filename; - return (1); - err: - /* Cleanup ! */ - if (filename != NULL) - OPENSSL_free(filename); - if (id > 0) - unload_add_on(id); - return (0); -} - -static int beos_unload(DSO *dso) -{ - image_id id; - if (dso == NULL) { - DSOerr(DSO_F_BEOS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (sk_num(dso->meth_data) < 1) - return (1); - id = (image_id) sk_pop(dso->meth_data); - if (id < 1) { - DSOerr(DSO_F_BEOS_UNLOAD, DSO_R_NULL_HANDLE); - return (0); - } - if (unload_add_on(id) != B_OK) { - DSOerr(DSO_F_BEOS_UNLOAD, DSO_R_UNLOAD_FAILED); - /* - * We should push the value back onto the stack in case of a retry. - */ - sk_push(dso->meth_data, (char *)id); - return (0); - } - return (1); -} - -static void *beos_bind_var(DSO *dso, const char *symname) -{ - image_id id; - void *sym; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_BEOS_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (sk_num(dso->meth_data) < 1) { - DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_STACK_ERROR); - return (NULL); - } - id = (image_id) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); - if (id < 1) { - DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_NULL_HANDLE); - return (NULL); - } - if (get_image_symbol(id, symname, B_SYMBOL_TYPE_DATA, &sym) != B_OK) { - DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_SYM_FAILURE); - ERR_add_error_data(3, "symname(", symname, ")"); - return (NULL); - } - return (sym); -} - -static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname) -{ - image_id id; - void *sym; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_BEOS_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (sk_num(dso->meth_data) < 1) { - DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_STACK_ERROR); - return (NULL); - } - id = (image_id) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); - if (id < 1) { - DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_NULL_HANDLE); - return (NULL); - } - if (get_image_symbol(id, symname, B_SYMBOL_TYPE_TEXT, &sym) != B_OK) { - DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_SYM_FAILURE); - ERR_add_error_data(3, "symname(", symname, ")"); - return (NULL); - } - return ((DSO_FUNC_TYPE)sym); -} - -/* This one is the same as the one in dlfcn */ -static char *beos_name_converter(DSO *dso, const char *filename) -{ - char *translated; - int len, rsize, transform; - - len = strlen(filename); - rsize = len + 1; - transform = (strstr(filename, "/") == NULL); - if (transform) { - /* We will convert this to "%s.so" or "lib%s.so" */ - rsize += 3; /* The length of ".so" */ - if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) - rsize += 3; /* The length of "lib" */ - } - translated = OPENSSL_malloc(rsize); - if (translated == NULL) { - DSOerr(DSO_F_BEOS_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); - return (NULL); - } - if (transform) { - if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) - sprintf(translated, "lib%s.so", filename); - else - sprintf(translated, "%s.so", filename); - } else - sprintf(translated, "%s", filename); - return (translated); -} - -#endif -/* dso_dl.c */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "dso.h" - -#ifndef DSO_DL -DSO_METHOD *DSO_METHOD_dl(void) -{ - return NULL; -} -#else - -# include - -/* Part of the hack in "dl_load" ... */ -# define DSO_MAX_TRANSLATED_SIZE 256 - -static int dl_load(DSO *dso); -static int dl_unload(DSO *dso); -static void *dl_bind_var(DSO *dso, const char *symname); -static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname); -# if 0 -static int dl_unbind_var(DSO *dso, char *symname, void *symptr); -static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); -static int dl_init(DSO *dso); -static int dl_finish(DSO *dso); -static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); -# endif -static char *dl_name_converter(DSO *dso, const char *filename); -static char *dl_merger(DSO *dso, const char *filespec1, - const char *filespec2); -static int dl_pathbyaddr(void *addr, char *path, int sz); -static void *dl_globallookup(const char *name); - -static DSO_METHOD dso_meth_dl = { - "OpenSSL 'dl' shared library method", - dl_load, - dl_unload, - dl_bind_var, - dl_bind_func, -/* For now, "unbind" doesn't exist */ -# if 0 - NULL, /* unbind_var */ - NULL, /* unbind_func */ -# endif - NULL, /* ctrl */ - dl_name_converter, - dl_merger, - NULL, /* init */ - NULL, /* finish */ - dl_pathbyaddr, - dl_globallookup -}; - -DSO_METHOD *DSO_METHOD_dl(void) -{ - return (&dso_meth_dl); -} - -/* - * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle - * (shl_t) returned from shl_load(). NB: I checked on HPUX11 and shl_t is - * itself a pointer type so the cast is safe. - */ - -static int dl_load(DSO *dso) -{ - shl_t ptr = NULL; - /* - * We don't do any fancy retries or anything, just take the method's (or - * DSO's if it has the callback set) best translation of the - * platform-independant filename and try once with that. - */ - char *filename = DSO_convert_filename(dso, NULL); - - if (filename == NULL) { - DSOerr(DSO_F_DL_LOAD, DSO_R_NO_FILENAME); - goto err; - } - ptr = shl_load(filename, BIND_IMMEDIATE | - (dso->flags & DSO_FLAG_NO_NAME_TRANSLATION ? 0 : - DYNAMIC_PATH), 0L); - if (ptr == NULL) { - DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED); - ERR_add_error_data(4, "filename(", filename, "): ", strerror(errno)); - goto err; - } - if (!sk_push(dso->meth_data, (char *)ptr)) { - DSOerr(DSO_F_DL_LOAD, DSO_R_STACK_ERROR); - goto err; - } - /* - * Success, stick the converted filename we've loaded under into the DSO - * (it also serves as the indicator that we are currently loaded). - */ - dso->loaded_filename = filename; - return (1); - err: - /* Cleanup! */ - if (filename != NULL) - OPENSSL_free(filename); - if (ptr != NULL) - shl_unload(ptr); - return (0); -} - -static int dl_unload(DSO *dso) -{ - shl_t ptr; - if (dso == NULL) { - DSOerr(DSO_F_DL_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (sk_num(dso->meth_data) < 1) - return (1); - /* Is this statement legal? */ - ptr = (shl_t) sk_pop(dso->meth_data); - if (ptr == NULL) { - DSOerr(DSO_F_DL_UNLOAD, DSO_R_NULL_HANDLE); - /* - * Should push the value back onto the stack in case of a retry. - */ - sk_push(dso->meth_data, (char *)ptr); - return (0); - } - shl_unload(ptr); - return (1); -} - -static void *dl_bind_var(DSO *dso, const char *symname) -{ - shl_t ptr; - void *sym; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DL_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (sk_num(dso->meth_data) < 1) { - DSOerr(DSO_F_DL_BIND_VAR, DSO_R_STACK_ERROR); - return (NULL); - } - ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); - if (ptr == NULL) { - DSOerr(DSO_F_DL_BIND_VAR, DSO_R_NULL_HANDLE); - return (NULL); - } - if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) { - DSOerr(DSO_F_DL_BIND_VAR, DSO_R_SYM_FAILURE); - ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno)); - return (NULL); - } - return (sym); -} - -static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname) -{ - shl_t ptr; - void *sym; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DL_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (sk_num(dso->meth_data) < 1) { - DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_STACK_ERROR); - return (NULL); - } - ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); - if (ptr == NULL) { - DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_NULL_HANDLE); - return (NULL); - } - if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) { - DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE); - ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno)); - return (NULL); - } - return ((DSO_FUNC_TYPE)sym); -} - -static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) -{ - char *merged; - - if (!filespec1 && !filespec2) { - DSOerr(DSO_F_DL_MERGER, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - /* - * If the first file specification is a rooted path, it rules. same goes - * if the second file specification is missing. - */ - if (!filespec2 || filespec1[0] == '/') { - merged = OPENSSL_malloc(strlen(filespec1) + 1); - if (!merged) { - DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - strcpy(merged, filespec1); - } - /* - * If the first file specification is missing, the second one rules. - */ - else if (!filespec1) { - merged = OPENSSL_malloc(strlen(filespec2) + 1); - if (!merged) { - DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - strcpy(merged, filespec2); - } else - /* - * This part isn't as trivial as it looks. It assumes that the - * second file specification really is a directory, and makes no - * checks whatsoever. Therefore, the result becomes the - * concatenation of filespec2 followed by a slash followed by - * filespec1. - */ - { - int spec2len, len; - - spec2len = (filespec2 ? strlen(filespec2) : 0); - len = spec2len + (filespec1 ? strlen(filespec1) : 0); - - if (filespec2 && filespec2[spec2len - 1] == '/') { - spec2len--; - len--; - } - merged = OPENSSL_malloc(len + 2); - if (!merged) { - DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - strcpy(merged, filespec2); - merged[spec2len] = '/'; - strcpy(&merged[spec2len + 1], filespec1); - } - return (merged); -} - -/* - * This function is identical to the one in dso_dlfcn.c, but as it is highly - * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at - * the same time, there's no great duplicating the code. Figuring out an - * elegant way to share one copy of the code would be more difficult and - * would not leave the implementations independant. - */ -# if defined(__hpux) -static const char extension[] = ".sl"; -# else -static const char extension[] = ".so"; -# endif -static char *dl_name_converter(DSO *dso, const char *filename) -{ - char *translated; - int len, rsize, transform; - - len = strlen(filename); - rsize = len + 1; - transform = (strstr(filename, "/") == NULL); - { - /* We will convert this to "%s.s?" or "lib%s.s?" */ - rsize += strlen(extension); /* The length of ".s?" */ - if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) - rsize += 3; /* The length of "lib" */ - } - translated = OPENSSL_malloc(rsize); - if (translated == NULL) { - DSOerr(DSO_F_DL_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); - return (NULL); - } - if (transform) { - if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) - sprintf(translated, "lib%s%s", filename, extension); - else - sprintf(translated, "%s%s", filename, extension); - } else - sprintf(translated, "%s", filename); - return (translated); -} - -static int dl_pathbyaddr(void *addr, char *path, int sz) -{ - struct shl_descriptor inf; - int i, len; - - if (addr == NULL) { - union { - int (*f) (void *, char *, int); - void *p; - } t = { - dl_pathbyaddr - }; - addr = t.p; - } - - for (i = -1; shl_get_r(i, &inf) == 0; i++) { - if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) || - ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) { - len = (int)strlen(inf.filename); - if (sz <= 0) - return len + 1; - if (len >= sz) - len = sz - 1; - memcpy(path, inf.filename, len); - path[len++] = 0; - return len; - } - } - - return -1; -} - -static void *dl_globallookup(const char *name) -{ - void *ret; - shl_t h = NULL; - - return shl_findsym(&h, name, TYPE_UNDEFINED, &ret) ? NULL : ret; -} -#endif /* DSO_DL */ -/* dso_dlfcn.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * We need to do this early, because stdio.h includes the header files that - * handle _GNU_SOURCE and other similar macros. Defining it later is simply - * too late, because those headers are protected from re- inclusion. - */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE /* make sure dladdr is declared */ -#endif - -#include -// #include "cryptlib.h" -// #include "dso.h" - -#ifndef DSO_DLFCN -DSO_METHOD *DSO_METHOD_dlfcn(void) -{ - return NULL; -} -#else - -# ifdef HAVE_DLFCN_H -# ifdef __osf__ -# define __EXTENSIONS__ -# endif -# include -# define HAVE_DLINFO 1 -# if defined(_AIX) || defined(__CYGWIN__) || \ - defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ - (defined(__osf__) && !defined(RTLD_NEXT)) || \ - (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \ - defined(__ANDROID__) -# undef HAVE_DLINFO -# endif -# endif - -/* Part of the hack in "dlfcn_load" ... */ -# define DSO_MAX_TRANSLATED_SIZE 256 - -static int dlfcn_load(DSO *dso); -static int dlfcn_unload(DSO *dso); -static void *dlfcn_bind_var(DSO *dso, const char *symname); -static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname); -# if 0 -static int dlfcn_unbind(DSO *dso, char *symname, void *symptr); -static int dlfcn_init(DSO *dso); -static int dlfcn_finish(DSO *dso); -static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); -# endif -static char *dlfcn_name_converter(DSO *dso, const char *filename); -static char *dlfcn_merger(DSO *dso, const char *filespec1, - const char *filespec2); -static int dlfcn_pathbyaddr(void *addr, char *path, int sz); -static void *dlfcn_globallookup(const char *name); - -static DSO_METHOD dso_meth_dlfcn = { - "OpenSSL 'dlfcn' shared library method", - dlfcn_load, - dlfcn_unload, - dlfcn_bind_var, - dlfcn_bind_func, -/* For now, "unbind" doesn't exist */ -# if 0 - NULL, /* unbind_var */ - NULL, /* unbind_func */ -# endif - NULL, /* ctrl */ - dlfcn_name_converter, - dlfcn_merger, - NULL, /* init */ - NULL, /* finish */ - dlfcn_pathbyaddr, - dlfcn_globallookup -}; - -DSO_METHOD *DSO_METHOD_dlfcn(void) -{ - return (&dso_meth_dlfcn); -} - -/* - * Prior to using the dlopen() function, we should decide on the flag we - * send. There's a few different ways of doing this and it's a messy - * venn-diagram to match up which platforms support what. So as we don't have - * autoconf yet, I'm implementing a hack that could be hacked further - * relatively easily to deal with cases as we find them. Initially this is to - * cope with OpenBSD. - */ -# if defined(__OpenBSD__) || defined(__NetBSD__) -# ifdef DL_LAZY -# define DLOPEN_FLAG DL_LAZY -# else -# ifdef RTLD_NOW -# define DLOPEN_FLAG RTLD_NOW -# else -# define DLOPEN_FLAG 0 -# endif -# endif -# else -# ifdef OPENSSL_SYS_SUNOS -# define DLOPEN_FLAG 1 -# else -# define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */ -# endif -# endif - -/* - * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle - * (void*) returned from dlopen(). - */ - -static int dlfcn_load(DSO *dso) -{ - void *ptr = NULL; - /* See applicable comments in dso_dl.c */ - char *filename = DSO_convert_filename(dso, NULL); - int flags = DLOPEN_FLAG; - - if (filename == NULL) { - DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME); - goto err; - } -# ifdef RTLD_GLOBAL - if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS) - flags |= RTLD_GLOBAL; -# endif - ptr = dlopen(filename, flags); - if (ptr == NULL) { - DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED); - ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); - goto err; - } - if (!sk_void_push(dso->meth_data, (char *)ptr)) { - DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR); - goto err; - } - /* Success */ - dso->loaded_filename = filename; - return (1); - err: - /* Cleanup! */ - if (filename != NULL) - OPENSSL_free(filename); - if (ptr != NULL) - dlclose(ptr); - return (0); -} - -static int dlfcn_unload(DSO *dso) -{ - void *ptr; - if (dso == NULL) { - DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (sk_void_num(dso->meth_data) < 1) - return (1); - ptr = sk_void_pop(dso->meth_data); - if (ptr == NULL) { - DSOerr(DSO_F_DLFCN_UNLOAD, DSO_R_NULL_HANDLE); - /* - * Should push the value back onto the stack in case of a retry. - */ - sk_void_push(dso->meth_data, ptr); - return (0); - } - /* For now I'm not aware of any errors associated with dlclose() */ - dlclose(ptr); - return (1); -} - -static void *dlfcn_bind_var(DSO *dso, const char *symname) -{ - void *ptr, *sym; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DLFCN_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (sk_void_num(dso->meth_data) < 1) { - DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_STACK_ERROR); - return (NULL); - } - ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); - if (ptr == NULL) { - DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_NULL_HANDLE); - return (NULL); - } - sym = dlsym(ptr, symname); - if (sym == NULL) { - DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_SYM_FAILURE); - ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); - return (NULL); - } - return (sym); -} - -static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) -{ - void *ptr; - union { - DSO_FUNC_TYPE sym; - void *dlret; - } u; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (sk_void_num(dso->meth_data) < 1) { - DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR); - return (NULL); - } - ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); - if (ptr == NULL) { - DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_NULL_HANDLE); - return (NULL); - } - u.dlret = dlsym(ptr, symname); - if (u.dlret == NULL) { - DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE); - ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); - return (NULL); - } - return u.sym; -} - -static char *dlfcn_merger(DSO *dso, const char *filespec1, - const char *filespec2) -{ - char *merged; - - if (!filespec1 && !filespec2) { - DSOerr(DSO_F_DLFCN_MERGER, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - /* - * If the first file specification is a rooted path, it rules. same goes - * if the second file specification is missing. - */ - if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) { - merged = OPENSSL_malloc(strlen(filespec1) + 1); - if (!merged) { - DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - strcpy(merged, filespec1); - } - /* - * If the first file specification is missing, the second one rules. - */ - else if (!filespec1) { - merged = OPENSSL_malloc(strlen(filespec2) + 1); - if (!merged) { - DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - strcpy(merged, filespec2); - } else { - /* - * This part isn't as trivial as it looks. It assumes that the - * second file specification really is a directory, and makes no - * checks whatsoever. Therefore, the result becomes the - * concatenation of filespec2 followed by a slash followed by - * filespec1. - */ - int spec2len, len; - - spec2len = strlen(filespec2); - len = spec2len + strlen(filespec1); - - if (spec2len && filespec2[spec2len - 1] == '/') { - spec2len--; - len--; - } - merged = OPENSSL_malloc(len + 2); - if (!merged) { - DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - strcpy(merged, filespec2); - merged[spec2len] = '/'; - strcpy(&merged[spec2len + 1], filespec1); - } - return (merged); -} - -# ifdef OPENSSL_SYS_MACOSX -# define DSO_ext ".dylib" -# define DSO_extlen 6 -# else -# define DSO_ext ".so" -# define DSO_extlen 3 -# endif - -static char *dlfcn_name_converter(DSO *dso, const char *filename) -{ - char *translated; - int len, rsize, transform; - - len = strlen(filename); - rsize = len + 1; - transform = (strstr(filename, "/") == NULL); - if (transform) { - /* We will convert this to "%s.so" or "lib%s.so" etc */ - rsize += DSO_extlen; /* The length of ".so" */ - if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) - rsize += 3; /* The length of "lib" */ - } - translated = OPENSSL_malloc(rsize); - if (translated == NULL) { - DSOerr(DSO_F_DLFCN_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); - return (NULL); - } - if (transform) { - if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) - sprintf(translated, "lib%s" DSO_ext, filename); - else - sprintf(translated, "%s" DSO_ext, filename); - } else - sprintf(translated, "%s", filename); - return (translated); -} - -# ifdef __sgi -/*- -This is a quote from IRIX manual for dladdr(3c): - - does not contain a prototype for dladdr or definition of - Dl_info. The #include in the SYNOPSIS line is traditional, - but contains no dladdr prototype and no IRIX library contains an - implementation. Write your own declaration based on the code below. - - The following code is dependent on internal interfaces that are not - part of the IRIX compatibility guarantee; however, there is no future - intention to change this interface, so on a practical level, the code - below is safe to use on IRIX. -*/ -# include -# ifndef _RLD_INTERFACE_DLFCN_H_DLADDR -# define _RLD_INTERFACE_DLFCN_H_DLADDR -typedef struct Dl_info { - const char *dli_fname; - void *dli_fbase; - const char *dli_sname; - void *dli_saddr; - int dli_version; - int dli_reserved1; - long dli_reserved[4]; -} Dl_info; -# else -typedef struct Dl_info Dl_info; -# endif -# define _RLD_DLADDR 14 - -static int dladdr(void *address, Dl_info *dl) -{ - void *v; - v = _rld_new_interface(_RLD_DLADDR, address, dl); - return (int)v; -} -# endif /* __sgi */ - -static int dlfcn_pathbyaddr(void *addr, char *path, int sz) -{ -# ifdef HAVE_DLINFO - Dl_info dli; - int len; - - if (addr == NULL) { - union { - int (*f) (void *, char *, int); - void *p; - } t = { - dlfcn_pathbyaddr - }; - addr = t.p; - } - - if (dladdr(addr, &dli)) { - len = (int)strlen(dli.dli_fname); - if (sz <= 0) - return len + 1; - if (len >= sz) - len = sz - 1; - memcpy(path, dli.dli_fname, len); - path[len++] = 0; - return len; - } - - ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror()); -# endif - return -1; -} - -static void *dlfcn_globallookup(const char *name) -{ - void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY); - - if (handle) { - ret = dlsym(handle, name); - dlclose(handle); - } - - return ret; -} -#endif /* DSO_DLFCN */ -/* crypto/dso/dso_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "dso.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason) - -static ERR_STRING_DATA DSO_str_functs[] = { - {ERR_FUNC(DSO_F_BEOS_BIND_FUNC), "BEOS_BIND_FUNC"}, - {ERR_FUNC(DSO_F_BEOS_BIND_VAR), "BEOS_BIND_VAR"}, - {ERR_FUNC(DSO_F_BEOS_LOAD), "BEOS_LOAD"}, - {ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER), "BEOS_NAME_CONVERTER"}, - {ERR_FUNC(DSO_F_BEOS_UNLOAD), "BEOS_UNLOAD"}, - {ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"}, - {ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"}, - {ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"}, - {ERR_FUNC(DSO_F_DLFCN_MERGER), "DLFCN_MERGER"}, - {ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "DLFCN_NAME_CONVERTER"}, - {ERR_FUNC(DSO_F_DLFCN_UNLOAD), "DLFCN_UNLOAD"}, - {ERR_FUNC(DSO_F_DL_BIND_FUNC), "DL_BIND_FUNC"}, - {ERR_FUNC(DSO_F_DL_BIND_VAR), "DL_BIND_VAR"}, - {ERR_FUNC(DSO_F_DL_LOAD), "DL_LOAD"}, - {ERR_FUNC(DSO_F_DL_MERGER), "DL_MERGER"}, - {ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "DL_NAME_CONVERTER"}, - {ERR_FUNC(DSO_F_DL_UNLOAD), "DL_UNLOAD"}, - {ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"}, - {ERR_FUNC(DSO_F_DSO_BIND_VAR), "DSO_bind_var"}, - {ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME), "DSO_convert_filename"}, - {ERR_FUNC(DSO_F_DSO_CTRL), "DSO_ctrl"}, - {ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"}, - {ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"}, - {ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"}, - {ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP), "DSO_global_lookup"}, - {ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"}, - {ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"}, - {ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"}, - {ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"}, - {ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"}, - {ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"}, - {ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"}, - {ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC), "GLOBAL_LOOKUP_FUNC"}, - {ERR_FUNC(DSO_F_PATHBYADDR), "PATHBYADDR"}, - {ERR_FUNC(DSO_F_VMS_BIND_SYM), "VMS_BIND_SYM"}, - {ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"}, - {ERR_FUNC(DSO_F_VMS_MERGER), "VMS_MERGER"}, - {ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"}, - {ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"}, - {ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"}, - {ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP), "WIN32_GLOBALLOOKUP"}, - {ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC), "WIN32_GLOBALLOOKUP_FUNC"}, - {ERR_FUNC(DSO_F_WIN32_JOINER), "WIN32_JOINER"}, - {ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"}, - {ERR_FUNC(DSO_F_WIN32_MERGER), "WIN32_MERGER"}, - {ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"}, - {ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "WIN32_PATHBYADDR"}, - {ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"}, - {ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"}, - {0, NULL} -}; - -static ERR_STRING_DATA DSO_str_reasons[] = { - {ERR_REASON(DSO_R_CTRL_FAILED), "control command failed"}, - {ERR_REASON(DSO_R_DSO_ALREADY_LOADED), "dso already loaded"}, - {ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE), "empty file structure"}, - {ERR_REASON(DSO_R_FAILURE), "failure"}, - {ERR_REASON(DSO_R_FILENAME_TOO_BIG), "filename too big"}, - {ERR_REASON(DSO_R_FINISH_FAILED), "cleanup method function failed"}, - {ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX), "incorrect file syntax"}, - {ERR_REASON(DSO_R_LOAD_FAILED), "could not load the shared library"}, - {ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED), "name translation failed"}, - {ERR_REASON(DSO_R_NO_FILENAME), "no filename"}, - {ERR_REASON(DSO_R_NO_FILE_SPECIFICATION), "no file specification"}, - {ERR_REASON(DSO_R_NULL_HANDLE), "a null shared library handle was used"}, - {ERR_REASON(DSO_R_SET_FILENAME_FAILED), "set filename failed"}, - {ERR_REASON(DSO_R_STACK_ERROR), "the meth_data stack is corrupt"}, - {ERR_REASON(DSO_R_SYM_FAILURE), - "could not bind to the requested symbol name"}, - {ERR_REASON(DSO_R_UNLOAD_FAILED), "could not unload the shared library"}, - {ERR_REASON(DSO_R_UNSUPPORTED), "functionality not supported"}, - {0, NULL} -}; - -#endif - -void ERR_load_DSO_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) { - ERR_load_strings(0, DSO_str_functs); - ERR_load_strings(0, DSO_str_reasons); - } -#endif -} -/* dso_lib.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "crypto.h" -// #include "cryptlib.h" -// #include "dso.h" - -static DSO_METHOD *default_DSO_meth = NULL; - -DSO *DSO_new(void) -{ - return (DSO_new_method(NULL)); -} - -void DSO_set_default_method(DSO_METHOD *meth) -{ - default_DSO_meth = meth; -} - -DSO_METHOD *DSO_get_default_method(void) -{ - return (default_DSO_meth); -} - -DSO_METHOD *DSO_get_method(DSO *dso) -{ - return (dso->meth); -} - -DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth) -{ - DSO_METHOD *mtmp; - mtmp = dso->meth; - dso->meth = meth; - return (mtmp); -} - -DSO *DSO_new_method(DSO_METHOD *meth) -{ - DSO *ret; - - if (default_DSO_meth == NULL) - /* - * We default to DSO_METH_openssl() which in turn defaults to - * stealing the "best available" method. Will fallback to - * DSO_METH_null() in the worst case. - */ - default_DSO_meth = DSO_METHOD_openssl(); - ret = (DSO *)OPENSSL_malloc(sizeof(DSO)); - if (ret == NULL) { - DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return (NULL); - } - memset(ret, 0, sizeof(DSO)); - ret->meth_data = sk_void_new_null(); - if (ret->meth_data == NULL) { - /* sk_new doesn't generate any errors so we do */ - DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); - OPENSSL_free(ret); - return (NULL); - } - if (meth == NULL) - ret->meth = default_DSO_meth; - else - ret->meth = meth; - ret->references = 1; - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - sk_void_free(ret->meth_data); - OPENSSL_free(ret); - ret = NULL; - } - return (ret); -} - -int DSO_free(DSO *dso) -{ - int i; - - if (dso == NULL) { - DSOerr(DSO_F_DSO_FREE, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - - i = CRYPTO_add(&dso->references, -1, CRYPTO_LOCK_DSO); -#ifdef REF_PRINT - REF_PRINT("DSO", dso); -#endif - if (i > 0) - return (1); -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "DSO_free, bad reference count\n"); - abort(); - } -#endif - - if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) { - DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED); - return (0); - } - - if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) { - DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED); - return (0); - } - - sk_void_free(dso->meth_data); - if (dso->filename != NULL) - OPENSSL_free(dso->filename); - if (dso->loaded_filename != NULL) - OPENSSL_free(dso->loaded_filename); - - OPENSSL_free(dso); - return (1); -} - -int DSO_flags(DSO *dso) -{ - return ((dso == NULL) ? 0 : dso->flags); -} - -int DSO_up_ref(DSO *dso) -{ - if (dso == NULL) { - DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - - CRYPTO_add(&dso->references, 1, CRYPTO_LOCK_DSO); - return (1); -} - -DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) -{ - DSO *ret; - int allocated = 0; - - if (dso == NULL) { - ret = DSO_new_method(meth); - if (ret == NULL) { - DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE); - goto err; - } - allocated = 1; - /* Pass the provided flags to the new DSO object */ - if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED); - goto err; - } - } else - ret = dso; - /* Don't load if we're currently already loaded */ - if (ret->filename != NULL) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED); - goto err; - } - /* - * filename can only be NULL if we were passed a dso that already has one - * set. - */ - if (filename != NULL) - if (!DSO_set_filename(ret, filename)) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED); - goto err; - } - filename = ret->filename; - if (filename == NULL) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME); - goto err; - } - if (ret->meth->dso_load == NULL) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED); - goto err; - } - if (!ret->meth->dso_load(ret)) { - DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED); - goto err; - } - /* Load succeeded */ - return (ret); - err: - if (allocated) - DSO_free(ret); - return (NULL); -} - -void *DSO_bind_var(DSO *dso, const char *symname) -{ - void *ret = NULL; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DSO_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (dso->meth->dso_bind_var == NULL) { - DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_UNSUPPORTED); - return (NULL); - } - if ((ret = dso->meth->dso_bind_var(dso, symname)) == NULL) { - DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_SYM_FAILURE); - return (NULL); - } - /* Success */ - return (ret); -} - -DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname) -{ - DSO_FUNC_TYPE ret = NULL; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (dso->meth->dso_bind_func == NULL) { - DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED); - return (NULL); - } - if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) { - DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE); - return (NULL); - } - /* Success */ - return (ret); -} - -/* - * I don't really like these *_ctrl functions very much to be perfectly - * honest. For one thing, I think I have to return a negative value for any - * error because possible DSO_ctrl() commands may return values such as - * "size"s that can legitimately be zero (making the standard - * "if (DSO_cmd(...))" form that works almost everywhere else fail at odd - * times. I'd prefer "output" values to be passed by reference and the return - * value as success/failure like usual ... but we conform when we must... :-) - */ -long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg) -{ - if (dso == NULL) { - DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return (-1); - } - /* - * We should intercept certain generic commands and only pass control to - * the method-specific ctrl() function if it's something we don't handle. - */ - switch (cmd) { - case DSO_CTRL_GET_FLAGS: - return dso->flags; - case DSO_CTRL_SET_FLAGS: - dso->flags = (int)larg; - return (0); - case DSO_CTRL_OR_FLAGS: - dso->flags |= (int)larg; - return (0); - default: - break; - } - if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) { - DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED); - return (-1); - } - return (dso->meth->dso_ctrl(dso, cmd, larg, parg)); -} - -int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb, - DSO_NAME_CONVERTER_FUNC *oldcb) -{ - if (dso == NULL) { - DSOerr(DSO_F_DSO_SET_NAME_CONVERTER, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (oldcb) - *oldcb = dso->name_converter; - dso->name_converter = cb; - return (1); -} - -const char *DSO_get_filename(DSO *dso) -{ - if (dso == NULL) { - DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - return (dso->filename); -} - -int DSO_set_filename(DSO *dso, const char *filename) -{ - char *copied; - - if ((dso == NULL) || (filename == NULL)) { - DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (dso->loaded_filename) { - DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED); - return (0); - } - /* We'll duplicate filename */ - copied = OPENSSL_malloc(strlen(filename) + 1); - if (copied == NULL) { - DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE); - return (0); - } - BUF_strlcpy(copied, filename, strlen(filename) + 1); - if (dso->filename) - OPENSSL_free(dso->filename); - dso->filename = copied; - return (1); -} - -char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2) -{ - char *result = NULL; - - if (dso == NULL || filespec1 == NULL) { - DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { - if (dso->merger != NULL) - result = dso->merger(dso, filespec1, filespec2); - else if (dso->meth->dso_merger != NULL) - result = dso->meth->dso_merger(dso, filespec1, filespec2); - } - return (result); -} - -char *DSO_convert_filename(DSO *dso, const char *filename) -{ - char *result = NULL; - - if (dso == NULL) { - DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (filename == NULL) - filename = dso->filename; - if (filename == NULL) { - DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME); - return (NULL); - } - if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { - if (dso->name_converter != NULL) - result = dso->name_converter(dso, filename); - else if (dso->meth->dso_name_converter != NULL) - result = dso->meth->dso_name_converter(dso, filename); - } - if (result == NULL) { - result = OPENSSL_malloc(strlen(filename) + 1); - if (result == NULL) { - DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE); - return (NULL); - } - BUF_strlcpy(result, filename, strlen(filename) + 1); - } - return (result); -} - -const char *DSO_get_loaded_filename(DSO *dso) -{ - if (dso == NULL) { - DSOerr(DSO_F_DSO_GET_LOADED_FILENAME, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - return (dso->loaded_filename); -} - -int DSO_pathbyaddr(void *addr, char *path, int sz) -{ - DSO_METHOD *meth = default_DSO_meth; - if (meth == NULL) - meth = DSO_METHOD_openssl(); - if (meth->pathbyaddr == NULL) { - DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED); - return -1; - } - return (*meth->pathbyaddr) (addr, path, sz); -} - -void *DSO_global_lookup(const char *name) -{ - DSO_METHOD *meth = default_DSO_meth; - if (meth == NULL) - meth = DSO_METHOD_openssl(); - if (meth->globallookup == NULL) { - DSOerr(DSO_F_DSO_GLOBAL_LOOKUP, DSO_R_UNSUPPORTED); - return NULL; - } - return (*meth->globallookup) (name); -} -/* dso_null.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * This "NULL" method is provided as the fallback for systems that have no - * appropriate support for "shared-libraries". - */ - -#include -// #include "cryptlib.h" -// #include "dso.h" - -static DSO_METHOD dso_meth_null = { - "NULL shared library method", - NULL, /* load */ - NULL, /* unload */ - NULL, /* bind_var */ - NULL, /* bind_func */ -/* For now, "unbind" doesn't exist */ -#if 0 - NULL, /* unbind_var */ - NULL, /* unbind_func */ -#endif - NULL, /* ctrl */ - NULL, /* dso_name_converter */ - NULL, /* dso_merger */ - NULL, /* init */ - NULL, /* finish */ - NULL, /* pathbyaddr */ - NULL /* globallookup */ -}; - -DSO_METHOD *DSO_METHOD_null(void) -{ - return (&dso_meth_null); -} -/* dso_openssl.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "dso.h" - -/* We just pinch the method from an appropriate "default" method. */ - -DSO_METHOD *DSO_METHOD_openssl(void) -{ -#ifdef DEF_DSO_METHOD - return (DEF_DSO_METHOD()); -#elif defined(DSO_DLFCN) - return (DSO_METHOD_dlfcn()); -#elif defined(DSO_DL) - return (DSO_METHOD_dl()); -#elif defined(DSO_WIN32) - return (DSO_METHOD_win32()); -#elif defined(DSO_VMS) - return (DSO_METHOD_vms()); -#elif defined(DSO_BEOS) - return (DSO_METHOD_beos()); -#else - return (DSO_METHOD_null()); -#endif -} -/* dso_vms.c */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -// #include "cryptlib.h" -// #include "dso.h" - -#ifndef OPENSSL_SYS_VMS -DSO_METHOD *DSO_METHOD_vms(void) -{ - return NULL; -} -#else - -# pragma message disable DOLLARID -# include -# include -# include -# include -# include -# include "vms_rms.h" - -/* Some compiler options may mask the declaration of "_malloc32". */ -# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE -# if __INITIAL_POINTER_SIZE == 64 -# pragma pointer_size save -# pragma pointer_size 32 -void *_malloc32(__size_t); -# pragma pointer_size restore -# endif /* __INITIAL_POINTER_SIZE == 64 */ -# endif /* __INITIAL_POINTER_SIZE && defined - * _ANSI_C_SOURCE */ - -# pragma message disable DOLLARID - -static int vms_load(DSO *dso); -static int vms_unload(DSO *dso); -static void *vms_bind_var(DSO *dso, const char *symname); -static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname); -# if 0 -static int vms_unbind_var(DSO *dso, char *symname, void *symptr); -static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); -static int vms_init(DSO *dso); -static int vms_finish(DSO *dso); -static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg); -# endif -static char *vms_name_converter(DSO *dso, const char *filename); -static char *vms_merger(DSO *dso, const char *filespec1, - const char *filespec2); - -static DSO_METHOD dso_meth_vms = { - "OpenSSL 'VMS' shared library method", - vms_load, - NULL, /* unload */ - vms_bind_var, - vms_bind_func, -/* For now, "unbind" doesn't exist */ -# if 0 - NULL, /* unbind_var */ - NULL, /* unbind_func */ -# endif - NULL, /* ctrl */ - vms_name_converter, - vms_merger, - NULL, /* init */ - NULL /* finish */ -}; - -/* - * On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends - * on the reference to the file name being the same for all calls regarding - * one shared image, so we'll just store it in an instance of the following - * structure and put a pointer to that instance in the meth_data stack. - */ -typedef struct dso_internal_st { - /* - * This should contain the name only, no directory, no extension, nothing - * but a name. - */ - struct dsc$descriptor_s filename_dsc; - char filename[NAMX_MAXRSS + 1]; - /* - * This contains whatever is not in filename, if needed. Normally not - * defined. - */ - struct dsc$descriptor_s imagename_dsc; - char imagename[NAMX_MAXRSS + 1]; -} DSO_VMS_INTERNAL; - -DSO_METHOD *DSO_METHOD_vms(void) -{ - return (&dso_meth_vms); -} - -static int vms_load(DSO *dso) -{ - void *ptr = NULL; - /* See applicable comments in dso_dl.c */ - char *filename = DSO_convert_filename(dso, NULL); - -/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */ -# if __INITIAL_POINTER_SIZE == 64 -# define DSO_MALLOC _malloc32 -# pragma pointer_size save -# pragma pointer_size 32 -# else /* __INITIAL_POINTER_SIZE == 64 */ -# define DSO_MALLOC OPENSSL_malloc -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ - - DSO_VMS_INTERNAL *p = NULL; - -# if __INITIAL_POINTER_SIZE == 64 -# pragma pointer_size restore -# endif /* __INITIAL_POINTER_SIZE == 64 */ - - const char *sp1, *sp2; /* Search result */ - const char *ext = NULL; /* possible extension to add */ - - if (filename == NULL) { - DSOerr(DSO_F_VMS_LOAD, DSO_R_NO_FILENAME); - goto err; - } - - /*- - * A file specification may look like this: - * - * node::dev:[dir-spec]name.type;ver - * - * or (for compatibility with TOPS-20): - * - * node::dev:name.type;ver - * - * and the dir-spec uses '.' as separator. Also, a dir-spec - * may consist of several parts, with mixed use of [] and <>: - * - * [dir1.] - * - * We need to split the file specification into the name and - * the rest (both before and after the name itself). - */ - /* - * Start with trying to find the end of a dir-spec, and save the position - * of the byte after in sp1 - */ - sp1 = strrchr(filename, ']'); - sp2 = strrchr(filename, '>'); - if (sp1 == NULL) - sp1 = sp2; - if (sp2 != NULL && sp2 > sp1) - sp1 = sp2; - if (sp1 == NULL) - sp1 = strrchr(filename, ':'); - if (sp1 == NULL) - sp1 = filename; - else - sp1++; /* The byte after the found character */ - /* Now, let's see if there's a type, and save the position in sp2 */ - sp2 = strchr(sp1, '.'); - /* - * If there is a period and the next character is a semi-colon, - * we need to add an extension - */ - if (sp2 != NULL && sp2[1] == ';') - ext = ".EXE"; - /* - * If we found it, that's where we'll cut. Otherwise, look for a version - * number and save the position in sp2 - */ - if (sp2 == NULL) { - sp2 = strchr(sp1, ';'); - ext = ".EXE"; - } - /* - * If there was still nothing to find, set sp2 to point at the end of the - * string - */ - if (sp2 == NULL) - sp2 = sp1 + strlen(sp1); - - /* Check that we won't get buffer overflows */ - if (sp2 - sp1 > FILENAME_MAX - || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) { - DSOerr(DSO_F_VMS_LOAD, DSO_R_FILENAME_TOO_BIG); - goto err; - } - - p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL)); - if (p == NULL) { - DSOerr(DSO_F_VMS_LOAD, ERR_R_MALLOC_FAILURE); - goto err; - } - - strncpy(p->filename, sp1, sp2 - sp1); - p->filename[sp2 - sp1] = '\0'; - - strncpy(p->imagename, filename, sp1 - filename); - p->imagename[sp1 - filename] = '\0'; - if (ext) { - strcat(p->imagename, ext); - if (*sp2 == '.') - sp2++; - } - strcat(p->imagename, sp2); - - p->filename_dsc.dsc$w_length = strlen(p->filename); - p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - p->filename_dsc.dsc$b_class = DSC$K_CLASS_S; - p->filename_dsc.dsc$a_pointer = p->filename; - p->imagename_dsc.dsc$w_length = strlen(p->imagename); - p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S; - p->imagename_dsc.dsc$a_pointer = p->imagename; - - if (!sk_void_push(dso->meth_data, (char *)p)) { - DSOerr(DSO_F_VMS_LOAD, DSO_R_STACK_ERROR); - goto err; - } - - /* Success (for now, we lie. We actually do not know...) */ - dso->loaded_filename = filename; - return (1); - err: - /* Cleanup! */ - if (p != NULL) - OPENSSL_free(p); - if (filename != NULL) - OPENSSL_free(filename); - return (0); -} - -/* - * Note that this doesn't actually unload the shared image, as there is no - * such thing in VMS. Next time it get loaded again, a new copy will - * actually be loaded. - */ -static int vms_unload(DSO *dso) -{ - DSO_VMS_INTERNAL *p; - if (dso == NULL) { - DSOerr(DSO_F_VMS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (sk_void_num(dso->meth_data) < 1) - return (1); - p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data); - if (p == NULL) { - DSOerr(DSO_F_VMS_UNLOAD, DSO_R_NULL_HANDLE); - return (0); - } - /* Cleanup */ - OPENSSL_free(p); - return (1); -} - -/* - * We must do this in a separate function because of the way the exception - * handler works (it makes this function return - */ -static int do_find_symbol(DSO_VMS_INTERNAL *ptr, - struct dsc$descriptor_s *symname_dsc, void **sym, - unsigned long flags) -{ - /* - * Make sure that signals are caught and returned instead of aborting the - * program. The exception handler gets unestablished automatically on - * return from this function. - */ - lib$establish(lib$sig_to_ret); - - if (ptr->imagename_dsc.dsc$w_length) - return lib$find_image_symbol(&ptr->filename_dsc, - symname_dsc, sym, - &ptr->imagename_dsc, flags); - else - return lib$find_image_symbol(&ptr->filename_dsc, - symname_dsc, sym, 0, flags); -} - -void vms_bind_sym(DSO *dso, const char *symname, void **sym) -{ - DSO_VMS_INTERNAL *ptr; - int status; -# if 0 - int flags = (1 << 4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't - * defined in VMS older than 7.0 or so */ -# else - int flags = 0; -# endif - struct dsc$descriptor_s symname_dsc; - -/* Arrange 32-bit pointer to (copied) string storage, if needed. */ -# if __INITIAL_POINTER_SIZE == 64 -# define SYMNAME symname_32p -# pragma pointer_size save -# pragma pointer_size 32 - char *symname_32p; -# pragma pointer_size restore - char symname_32[NAMX_MAXRSS + 1]; -# else /* __INITIAL_POINTER_SIZE == 64 */ -# define SYMNAME ((char *) symname) -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ - - *sym = NULL; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_VMS_BIND_SYM, ERR_R_PASSED_NULL_PARAMETER); - return; - } -# if __INITIAL_POINTER_SIZE == 64 - /* Copy the symbol name to storage with a 32-bit pointer. */ - symname_32p = symname_32; - strcpy(symname_32p, symname); -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ - - symname_dsc.dsc$w_length = strlen(SYMNAME); - symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - symname_dsc.dsc$b_class = DSC$K_CLASS_S; - symname_dsc.dsc$a_pointer = SYMNAME; - - if (sk_void_num(dso->meth_data) < 1) { - DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_STACK_ERROR); - return; - } - ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data, - sk_void_num(dso->meth_data) - 1); - if (ptr == NULL) { - DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_NULL_HANDLE); - return; - } - - if (dso->flags & DSO_FLAG_UPCASE_SYMBOL) - flags = 0; - - status = do_find_symbol(ptr, &symname_dsc, sym, flags); - - if (!$VMS_STATUS_SUCCESS(status)) { - unsigned short length; - char errstring[257]; - struct dsc$descriptor_s errstring_dsc; - - errstring_dsc.dsc$w_length = sizeof(errstring); - errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - errstring_dsc.dsc$b_class = DSC$K_CLASS_S; - errstring_dsc.dsc$a_pointer = errstring; - - *sym = NULL; - - status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); - - if (!$VMS_STATUS_SUCCESS(status)) - lib$signal(status); /* This is really bad. Abort! */ - else { - errstring[length] = '\0'; - - DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_SYM_FAILURE); - if (ptr->imagename_dsc.dsc$w_length) - ERR_add_error_data(9, - "Symbol ", symname, - " in ", ptr->filename, - " (", ptr->imagename, ")", - ": ", errstring); - else - ERR_add_error_data(6, - "Symbol ", symname, - " in ", ptr->filename, ": ", errstring); - } - return; - } - return; -} - -static void *vms_bind_var(DSO *dso, const char *symname) -{ - void *sym = 0; - vms_bind_sym(dso, symname, &sym); - return sym; -} - -static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname) -{ - DSO_FUNC_TYPE sym = 0; - vms_bind_sym(dso, symname, (void **)&sym); - return sym; -} - -static char *vms_merger(DSO *dso, const char *filespec1, - const char *filespec2) -{ - int status; - int filespec1len, filespec2len; - struct FAB fab; - struct NAMX_STRUCT nam; - char esa[NAMX_MAXRSS + 1]; - char *merged; - -/* Arrange 32-bit pointer to (copied) string storage, if needed. */ -# if __INITIAL_POINTER_SIZE == 64 -# define FILESPEC1 filespec1_32p; -# define FILESPEC2 filespec2_32p; -# pragma pointer_size save -# pragma pointer_size 32 - char *filespec1_32p; - char *filespec2_32p; -# pragma pointer_size restore - char filespec1_32[NAMX_MAXRSS + 1]; - char filespec2_32[NAMX_MAXRSS + 1]; -# else /* __INITIAL_POINTER_SIZE == 64 */ -# define FILESPEC1 ((char *) filespec1) -# define FILESPEC2 ((char *) filespec2) -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ - - if (!filespec1) - filespec1 = ""; - if (!filespec2) - filespec2 = ""; - filespec1len = strlen(filespec1); - filespec2len = strlen(filespec2); - -# if __INITIAL_POINTER_SIZE == 64 - /* Copy the file names to storage with a 32-bit pointer. */ - filespec1_32p = filespec1_32; - filespec2_32p = filespec2_32; - strcpy(filespec1_32p, filespec1); - strcpy(filespec2_32p, filespec2); -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ - - fab = cc$rms_fab; - nam = CC_RMS_NAMX; - - FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNA = FILESPEC1; - FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNS = filespec1len; - FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNA = FILESPEC2; - FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNS = filespec2len; - NAMX_DNA_FNA_SET(fab) - - nam.NAMX_ESA = esa; - nam.NAMX_ESS = NAMX_MAXRSS; - nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD; - SET_NAMX_NO_SHORT_UPCASE(nam); - - fab.FAB_NAMX = &nam; - - status = sys$parse(&fab, 0, 0); - - if (!$VMS_STATUS_SUCCESS(status)) { - unsigned short length; - char errstring[257]; - struct dsc$descriptor_s errstring_dsc; - - errstring_dsc.dsc$w_length = sizeof(errstring); - errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; - errstring_dsc.dsc$b_class = DSC$K_CLASS_S; - errstring_dsc.dsc$a_pointer = errstring; - - status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); - - if (!$VMS_STATUS_SUCCESS(status)) - lib$signal(status); /* This is really bad. Abort! */ - else { - errstring[length] = '\0'; - - DSOerr(DSO_F_VMS_MERGER, DSO_R_FAILURE); - ERR_add_error_data(7, - "filespec \"", filespec1, "\", ", - "defaults \"", filespec2, "\": ", errstring); - } - return (NULL); - } - - merged = OPENSSL_malloc(nam.NAMX_ESL + 1); - if (!merged) - goto malloc_err; - strncpy(merged, nam.NAMX_ESA, nam.NAMX_ESL); - merged[nam.NAMX_ESL] = '\0'; - return (merged); - malloc_err: - DSOerr(DSO_F_VMS_MERGER, ERR_R_MALLOC_FAILURE); -} - -static char *vms_name_converter(DSO *dso, const char *filename) -{ - int len = strlen(filename); - char *not_translated = OPENSSL_malloc(len + 1); - if (not_translated) - strcpy(not_translated, filename); - return (not_translated); -} - -#endif /* OPENSSL_SYS_VMS */ -/* dso_win32.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "dso.h" - -#if !defined(DSO_WIN32) -DSO_METHOD *DSO_METHOD_win32(void) -{ - return NULL; -} -#else - -# ifdef _WIN32_WCE -# if _WIN32_WCE < 300 -static FARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName) -{ - WCHAR lpProcNameW[64]; - int i; - - for (i = 0; lpProcName[i] && i < 64; i++) - lpProcNameW[i] = (WCHAR)lpProcName[i]; - if (i == 64) - return NULL; - lpProcNameW[i] = 0; - - return GetProcAddressW(hModule, lpProcNameW); -} -# endif -# undef GetProcAddress -# define GetProcAddress GetProcAddressA - -static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName) -{ - WCHAR *fnamw; - size_t len_0 = strlen(lpLibFileName) + 1, i; - -# ifdef _MSC_VER - fnamw = (WCHAR *)_alloca(len_0 * sizeof(WCHAR)); -# else - fnamw = (WCHAR *)alloca(len_0 * sizeof(WCHAR)); -# endif - if (fnamw == NULL) { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } -# if defined(_WIN32_WCE) && _WIN32_WCE>=101 - if (!MultiByteToWideChar(CP_ACP, 0, lpLibFileName, len_0, fnamw, len_0)) -# endif - for (i = 0; i < len_0; i++) - fnamw[i] = (WCHAR)lpLibFileName[i]; - - return LoadLibraryW(fnamw); -} -# endif - -/* Part of the hack in "win32_load" ... */ -# define DSO_MAX_TRANSLATED_SIZE 256 - -static int win32_load(DSO *dso); -static int win32_unload(DSO *dso); -static void *win32_bind_var(DSO *dso, const char *symname); -static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname); -# if 0 -static int win32_unbind_var(DSO *dso, char *symname, void *symptr); -static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); -static int win32_init(DSO *dso); -static int win32_finish(DSO *dso); -static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg); -# endif -static char *win32_name_converter(DSO *dso, const char *filename); -static char *win32_merger(DSO *dso, const char *filespec1, - const char *filespec2); -static int win32_pathbyaddr(void *addr, char *path, int sz); -static void *win32_globallookup(const char *name); - -static const char *openssl_strnchr(const char *string, int c, size_t len); - -static DSO_METHOD dso_meth_win32 = { - "OpenSSL 'win32' shared library method", - win32_load, - win32_unload, - win32_bind_var, - win32_bind_func, -/* For now, "unbind" doesn't exist */ -# if 0 - NULL, /* unbind_var */ - NULL, /* unbind_func */ -# endif - NULL, /* ctrl */ - win32_name_converter, - win32_merger, - NULL, /* init */ - NULL, /* finish */ - win32_pathbyaddr, - win32_globallookup -}; - -DSO_METHOD *DSO_METHOD_win32(void) -{ - return (&dso_meth_win32); -} - -/* - * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to - * the handle (HINSTANCE) returned from LoadLibrary(), and copied. - */ - -static int win32_load(DSO *dso) -{ - HINSTANCE h = NULL, *p = NULL; - /* See applicable comments from dso_dl.c */ - char *filename = DSO_convert_filename(dso, NULL); - - if (filename == NULL) { - DSOerr(DSO_F_WIN32_LOAD, DSO_R_NO_FILENAME); - goto err; - } - h = LoadLibraryA(filename); - if (h == NULL) { - DSOerr(DSO_F_WIN32_LOAD, DSO_R_LOAD_FAILED); - ERR_add_error_data(3, "filename(", filename, ")"); - goto err; - } - p = (HINSTANCE *) OPENSSL_malloc(sizeof(HINSTANCE)); - if (p == NULL) { - DSOerr(DSO_F_WIN32_LOAD, ERR_R_MALLOC_FAILURE); - goto err; - } - *p = h; - if (!sk_void_push(dso->meth_data, p)) { - DSOerr(DSO_F_WIN32_LOAD, DSO_R_STACK_ERROR); - goto err; - } - /* Success */ - dso->loaded_filename = filename; - return (1); - err: - /* Cleanup ! */ - if (filename != NULL) - OPENSSL_free(filename); - if (p != NULL) - OPENSSL_free(p); - if (h != NULL) - FreeLibrary(h); - return (0); -} - -static int win32_unload(DSO *dso) -{ - HINSTANCE *p; - if (dso == NULL) { - DSOerr(DSO_F_WIN32_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (sk_void_num(dso->meth_data) < 1) - return (1); - p = sk_void_pop(dso->meth_data); - if (p == NULL) { - DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_NULL_HANDLE); - return (0); - } - if (!FreeLibrary(*p)) { - DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_UNLOAD_FAILED); - /* - * We should push the value back onto the stack in case of a retry. - */ - sk_void_push(dso->meth_data, p); - return (0); - } - /* Cleanup */ - OPENSSL_free(p); - return (1); -} - -/* - * Using GetProcAddress for variables? TODO: Check this out in the Win32 API - * docs, there's probably a variant for variables. - */ -static void *win32_bind_var(DSO *dso, const char *symname) -{ - HINSTANCE *ptr; - void *sym; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_WIN32_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (sk_void_num(dso->meth_data) < 1) { - DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_STACK_ERROR); - return (NULL); - } - ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); - if (ptr == NULL) { - DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_NULL_HANDLE); - return (NULL); - } - sym = GetProcAddress(*ptr, symname); - if (sym == NULL) { - DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_SYM_FAILURE); - ERR_add_error_data(3, "symname(", symname, ")"); - return (NULL); - } - return (sym); -} - -static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname) -{ - HINSTANCE *ptr; - void *sym; - - if ((dso == NULL) || (symname == NULL)) { - DSOerr(DSO_F_WIN32_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (sk_void_num(dso->meth_data) < 1) { - DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_STACK_ERROR); - return (NULL); - } - ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); - if (ptr == NULL) { - DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_NULL_HANDLE); - return (NULL); - } - sym = GetProcAddress(*ptr, symname); - if (sym == NULL) { - DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_SYM_FAILURE); - ERR_add_error_data(3, "symname(", symname, ")"); - return (NULL); - } - return ((DSO_FUNC_TYPE)sym); -} - -struct file_st { - const char *node; - int nodelen; - const char *device; - int devicelen; - const char *predir; - int predirlen; - const char *dir; - int dirlen; - const char *file; - int filelen; -}; - -static struct file_st *win32_splitter(DSO *dso, const char *filename, - int assume_last_is_dir) -{ - struct file_st *result = NULL; - enum { IN_NODE, IN_DEVICE, IN_FILE } position; - const char *start = filename; - char last; - - if (!filename) { - DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_NO_FILENAME); - /* - * goto err; - */ - return (NULL); - } - - result = OPENSSL_malloc(sizeof(struct file_st)); - if (result == NULL) { - DSOerr(DSO_F_WIN32_SPLITTER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - memset(result, 0, sizeof(struct file_st)); - position = IN_DEVICE; - - if ((filename[0] == '\\' && filename[1] == '\\') - || (filename[0] == '/' && filename[1] == '/')) { - position = IN_NODE; - filename += 2; - start = filename; - result->node = start; - } - - do { - last = filename[0]; - switch (last) { - case ':': - if (position != IN_DEVICE) { - DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_INCORRECT_FILE_SYNTAX); - /* - * goto err; - */ - OPENSSL_free(result); - return (NULL); - } - result->device = start; - result->devicelen = (int)(filename - start); - position = IN_FILE; - start = ++filename; - result->dir = start; - break; - case '\\': - case '/': - if (position == IN_NODE) { - result->nodelen = (int)(filename - start); - position = IN_FILE; - start = ++filename; - result->dir = start; - } else if (position == IN_DEVICE) { - position = IN_FILE; - filename++; - result->dir = start; - result->dirlen = (int)(filename - start); - start = filename; - } else { - filename++; - result->dirlen += (int)(filename - start); - start = filename; - } - break; - case '\0': - if (position == IN_NODE) { - result->nodelen = (int)(filename - start); - } else { - if (filename - start > 0) { - if (assume_last_is_dir) { - if (position == IN_DEVICE) { - result->dir = start; - result->dirlen = 0; - } - result->dirlen += (int)(filename - start); - } else { - result->file = start; - result->filelen = (int)(filename - start); - } - } - } - break; - default: - filename++; - break; - } - } - while (last); - - if (!result->nodelen) - result->node = NULL; - if (!result->devicelen) - result->device = NULL; - if (!result->dirlen) - result->dir = NULL; - if (!result->filelen) - result->file = NULL; - - return (result); -} - -static char *win32_joiner(DSO *dso, const struct file_st *file_split) -{ - int len = 0, offset = 0; - char *result = NULL; - const char *start; - - if (!file_split) { - DSOerr(DSO_F_WIN32_JOINER, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (file_split->node) { - len += 2 + file_split->nodelen; /* 2 for starting \\ */ - if (file_split->predir || file_split->dir || file_split->file) - len++; /* 1 for ending \ */ - } else if (file_split->device) { - len += file_split->devicelen + 1; /* 1 for ending : */ - } - len += file_split->predirlen; - if (file_split->predir && (file_split->dir || file_split->file)) { - len++; /* 1 for ending \ */ - } - len += file_split->dirlen; - if (file_split->dir && file_split->file) { - len++; /* 1 for ending \ */ - } - len += file_split->filelen; - - if (!len) { - DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE); - return (NULL); - } - - result = OPENSSL_malloc(len + 1); - if (!result) { - DSOerr(DSO_F_WIN32_JOINER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - if (file_split->node) { - strcpy(&result[offset], "\\\\"); - offset += 2; - strncpy(&result[offset], file_split->node, file_split->nodelen); - offset += file_split->nodelen; - if (file_split->predir || file_split->dir || file_split->file) { - result[offset] = '\\'; - offset++; - } - } else if (file_split->device) { - strncpy(&result[offset], file_split->device, file_split->devicelen); - offset += file_split->devicelen; - result[offset] = ':'; - offset++; - } - start = file_split->predir; - while (file_split->predirlen > (start - file_split->predir)) { - const char *end = openssl_strnchr(start, '/', - file_split->predirlen - (start - - file_split->predir)); - if (!end) - end = start - + file_split->predirlen - (start - file_split->predir); - strncpy(&result[offset], start, end - start); - offset += (int)(end - start); - result[offset] = '\\'; - offset++; - start = end + 1; - } -# if 0 /* Not needed, since the directory converter - * above already appeneded a backslash */ - if (file_split->predir && (file_split->dir || file_split->file)) { - result[offset] = '\\'; - offset++; - } -# endif - start = file_split->dir; - while (file_split->dirlen > (start - file_split->dir)) { - const char *end = openssl_strnchr(start, '/', - file_split->dirlen - (start - - file_split->dir)); - if (!end) - end = start + file_split->dirlen - (start - file_split->dir); - strncpy(&result[offset], start, end - start); - offset += (int)(end - start); - result[offset] = '\\'; - offset++; - start = end + 1; - } -# if 0 /* Not needed, since the directory converter - * above already appeneded a backslash */ - if (file_split->dir && file_split->file) { - result[offset] = '\\'; - offset++; - } -# endif - strncpy(&result[offset], file_split->file, file_split->filelen); - offset += file_split->filelen; - result[offset] = '\0'; - return (result); -} - -static char *win32_merger(DSO *dso, const char *filespec1, - const char *filespec2) -{ - char *merged = NULL; - struct file_st *filespec1_split = NULL; - struct file_st *filespec2_split = NULL; - - if (!filespec1 && !filespec2) { - DSOerr(DSO_F_WIN32_MERGER, ERR_R_PASSED_NULL_PARAMETER); - return (NULL); - } - if (!filespec2) { - merged = OPENSSL_malloc(strlen(filespec1) + 1); - if (!merged) { - DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - strcpy(merged, filespec1); - } else if (!filespec1) { - merged = OPENSSL_malloc(strlen(filespec2) + 1); - if (!merged) { - DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - strcpy(merged, filespec2); - } else { - filespec1_split = win32_splitter(dso, filespec1, 0); - if (!filespec1_split) { - DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); - return (NULL); - } - filespec2_split = win32_splitter(dso, filespec2, 1); - if (!filespec2_split) { - DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); - OPENSSL_free(filespec1_split); - return (NULL); - } - - /* Fill in into filespec1_split */ - if (!filespec1_split->node && !filespec1_split->device) { - filespec1_split->node = filespec2_split->node; - filespec1_split->nodelen = filespec2_split->nodelen; - filespec1_split->device = filespec2_split->device; - filespec1_split->devicelen = filespec2_split->devicelen; - } - if (!filespec1_split->dir) { - filespec1_split->dir = filespec2_split->dir; - filespec1_split->dirlen = filespec2_split->dirlen; - } else if (filespec1_split->dir[0] != '\\' - && filespec1_split->dir[0] != '/') { - filespec1_split->predir = filespec2_split->dir; - filespec1_split->predirlen = filespec2_split->dirlen; - } - if (!filespec1_split->file) { - filespec1_split->file = filespec2_split->file; - filespec1_split->filelen = filespec2_split->filelen; - } - - merged = win32_joiner(dso, filespec1_split); - } - OPENSSL_free(filespec1_split); - OPENSSL_free(filespec2_split); - return (merged); -} - -static char *win32_name_converter(DSO *dso, const char *filename) -{ - char *translated; - int len, transform; - - len = strlen(filename); - transform = ((strstr(filename, "/") == NULL) && - (strstr(filename, "\\") == NULL) && - (strstr(filename, ":") == NULL)); - if (transform) - /* We will convert this to "%s.dll" */ - translated = OPENSSL_malloc(len + 5); - else - /* We will simply duplicate filename */ - translated = OPENSSL_malloc(len + 1); - if (translated == NULL) { - DSOerr(DSO_F_WIN32_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); - return (NULL); - } - if (transform) - sprintf(translated, "%s.dll", filename); - else - sprintf(translated, "%s", filename); - return (translated); -} - -static const char *openssl_strnchr(const char *string, int c, size_t len) -{ - size_t i; - const char *p; - for (i = 0, p = string; i < len && *p; i++, p++) { - if (*p == c) - return p; - } - return NULL; -} - -# include -# ifdef _WIN32_WCE -# define DLLNAME "TOOLHELP.DLL" -# else -# ifdef MODULEENTRY32 -# undef MODULEENTRY32 /* unmask the ASCII version! */ -# endif -# define DLLNAME "KERNEL32.DLL" -# endif - -typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD); -typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE); -typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *); - -static int win32_pathbyaddr(void *addr, char *path, int sz) -{ - HMODULE dll; - HANDLE hModuleSnap = INVALID_HANDLE_VALUE; - MODULEENTRY32 me32; - CREATETOOLHELP32SNAPSHOT create_snap; - CLOSETOOLHELP32SNAPSHOT close_snap; - MODULE32 module_first, module_next; - - if (addr == NULL) { - union { - int (*f) (void *, char *, int); - void *p; - } t = { - win32_pathbyaddr - }; - addr = t.p; - } - - dll = LoadLibrary(TEXT(DLLNAME)); - if (dll == NULL) { - DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); - return -1; - } - - create_snap = (CREATETOOLHELP32SNAPSHOT) - GetProcAddress(dll, "CreateToolhelp32Snapshot"); - if (create_snap == NULL) { - FreeLibrary(dll); - DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); - return -1; - } - /* We take the rest for granted... */ -# ifdef _WIN32_WCE - close_snap = (CLOSETOOLHELP32SNAPSHOT) - GetProcAddress(dll, "CloseToolhelp32Snapshot"); -# else - close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle; -# endif - module_first = (MODULE32) GetProcAddress(dll, "Module32First"); - module_next = (MODULE32) GetProcAddress(dll, "Module32Next"); - - hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0); - if (hModuleSnap == INVALID_HANDLE_VALUE) { - FreeLibrary(dll); - DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); - return -1; - } - - me32.dwSize = sizeof(me32); - - if (!(*module_first) (hModuleSnap, &me32)) { - (*close_snap) (hModuleSnap); - FreeLibrary(dll); - DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_FAILURE); - return -1; - } - - do { - if ((BYTE *) addr >= me32.modBaseAddr && - (BYTE *) addr < me32.modBaseAddr + me32.modBaseSize) { - (*close_snap) (hModuleSnap); - FreeLibrary(dll); -# ifdef _WIN32_WCE -# if _WIN32_WCE >= 101 - return WideCharToMultiByte(CP_ACP, 0, me32.szExePath, -1, - path, sz, NULL, NULL); -# else - { - int i, len = (int)wcslen(me32.szExePath); - if (sz <= 0) - return len + 1; - if (len >= sz) - len = sz - 1; - for (i = 0; i < len; i++) - path[i] = (char)me32.szExePath[i]; - path[len++] = 0; - return len; - } -# endif -# else - { - int len = (int)strlen(me32.szExePath); - if (sz <= 0) - return len + 1; - if (len >= sz) - len = sz - 1; - memcpy(path, me32.szExePath, len); - path[len++] = 0; - return len; - } -# endif - } - } while ((*module_next) (hModuleSnap, &me32)); - - (*close_snap) (hModuleSnap); - FreeLibrary(dll); - return 0; -} - -static void *win32_globallookup(const char *name) -{ - HMODULE dll; - HANDLE hModuleSnap = INVALID_HANDLE_VALUE; - MODULEENTRY32 me32; - CREATETOOLHELP32SNAPSHOT create_snap; - CLOSETOOLHELP32SNAPSHOT close_snap; - MODULE32 module_first, module_next; - FARPROC ret = NULL; - - dll = LoadLibrary(TEXT(DLLNAME)); - if (dll == NULL) { - DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); - return NULL; - } - - create_snap = (CREATETOOLHELP32SNAPSHOT) - GetProcAddress(dll, "CreateToolhelp32Snapshot"); - if (create_snap == NULL) { - FreeLibrary(dll); - DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); - return NULL; - } - /* We take the rest for granted... */ -# ifdef _WIN32_WCE - close_snap = (CLOSETOOLHELP32SNAPSHOT) - GetProcAddress(dll, "CloseToolhelp32Snapshot"); -# else - close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle; -# endif - module_first = (MODULE32) GetProcAddress(dll, "Module32First"); - module_next = (MODULE32) GetProcAddress(dll, "Module32Next"); - - hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0); - if (hModuleSnap == INVALID_HANDLE_VALUE) { - FreeLibrary(dll); - DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); - return NULL; - } - - me32.dwSize = sizeof(me32); - - if (!(*module_first) (hModuleSnap, &me32)) { - (*close_snap) (hModuleSnap); - FreeLibrary(dll); - return NULL; - } - - do { - if ((ret = GetProcAddress(me32.hModule, name))) { - (*close_snap) (hModuleSnap); - FreeLibrary(dll); - return ret; - } - } while ((*module_next) (hModuleSnap, &me32)); - - (*close_snap) (hModuleSnap); - FreeLibrary(dll); - return NULL; -} -#endif /* DSO_WIN32 */ diff --git a/Sources/COpenSSL/dtls1.h b/Sources/COpenSSL/dtls1.h deleted file mode 100644 index 0af2fb5b..00000000 --- a/Sources/COpenSSL/dtls1.h +++ /dev/null @@ -1,272 +0,0 @@ -/* ssl/dtls1.h */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_DTLS1_H -# define HEADER_DTLS1_H - -# include "buffer.h" -# include "pqueue.h" -# ifdef OPENSSL_SYS_VMS -# include -# include -# endif -# ifdef OPENSSL_SYS_WIN32 -/* Needed for struct timeval */ -# include -# elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_) -# include -# else -# if defined(OPENSSL_SYS_VXWORKS) -# include -# else -# include -# endif -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -# define DTLS1_VERSION 0xFEFF -# define DTLS1_2_VERSION 0xFEFD -# define DTLS_MAX_VERSION DTLS1_2_VERSION -# define DTLS1_VERSION_MAJOR 0xFE - -# define DTLS1_BAD_VER 0x0100 - -/* Special value for method supporting multiple versions */ -# define DTLS_ANY_VERSION 0x1FFFF - -# if 0 -/* this alert description is not specified anywhere... */ -# define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 -# endif - -/* lengths of messages */ -# define DTLS1_COOKIE_LENGTH 256 - -# define DTLS1_RT_HEADER_LENGTH 13 - -# define DTLS1_HM_HEADER_LENGTH 12 - -# define DTLS1_HM_BAD_FRAGMENT -2 -# define DTLS1_HM_FRAGMENT_RETRY -3 - -# define DTLS1_CCS_HEADER_LENGTH 1 - -# ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE -# define DTLS1_AL_HEADER_LENGTH 7 -# else -# define DTLS1_AL_HEADER_LENGTH 2 -# endif - -# ifndef OPENSSL_NO_SSL_INTERN - -# ifndef OPENSSL_NO_SCTP -# define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP" -# endif - -/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */ -# define DTLS1_MAX_MTU_OVERHEAD 48 - -typedef struct dtls1_bitmap_st { - unsigned long map; /* track 32 packets on 32-bit systems and 64 - * - on 64-bit systems */ - unsigned char max_seq_num[8]; /* max record number seen so far, 64-bit - * value in big-endian encoding */ -} DTLS1_BITMAP; - -struct dtls1_retransmit_state { - EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ - EVP_MD_CTX *write_hash; /* used for mac generation */ -# ifndef OPENSSL_NO_COMP - COMP_CTX *compress; /* compression */ -# else - char *compress; -# endif - SSL_SESSION *session; - unsigned short epoch; -}; - -struct hm_header_st { - unsigned char type; - unsigned long msg_len; - unsigned short seq; - unsigned long frag_off; - unsigned long frag_len; - unsigned int is_ccs; - struct dtls1_retransmit_state saved_retransmit_state; -}; - -struct ccs_header_st { - unsigned char type; - unsigned short seq; -}; - -struct dtls1_timeout_st { - /* Number of read timeouts so far */ - unsigned int read_timeouts; - /* Number of write timeouts so far */ - unsigned int write_timeouts; - /* Number of alerts received so far */ - unsigned int num_alerts; -}; - -typedef struct record_pqueue_st { - unsigned short epoch; - pqueue q; -} record_pqueue; - -typedef struct hm_fragment_st { - struct hm_header_st msg_header; - unsigned char *fragment; - unsigned char *reassembly; -} hm_fragment; - -typedef struct dtls1_state_st { - unsigned int send_cookie; - unsigned char cookie[DTLS1_COOKIE_LENGTH]; - unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; - unsigned int cookie_len; - /* - * The current data and handshake epoch. This is initially - * undefined, and starts at zero once the initial handshake is - * completed - */ - unsigned short r_epoch; - unsigned short w_epoch; - /* records being received in the current epoch */ - DTLS1_BITMAP bitmap; - /* renegotiation starts a new set of sequence numbers */ - DTLS1_BITMAP next_bitmap; - /* handshake message numbers */ - unsigned short handshake_write_seq; - unsigned short next_handshake_write_seq; - unsigned short handshake_read_seq; - /* save last sequence number for retransmissions */ - unsigned char last_write_sequence[8]; - /* Received handshake records (processed and unprocessed) */ - record_pqueue unprocessed_rcds; - record_pqueue processed_rcds; - /* Buffered handshake messages */ - pqueue buffered_messages; - /* Buffered (sent) handshake records */ - pqueue sent_messages; - /* - * Buffered application records. Only for records between CCS and - * Finished to prevent either protocol violation or unnecessary message - * loss. - */ - record_pqueue buffered_app_data; - /* Is set when listening for new connections with dtls1_listen() */ - unsigned int listen; - unsigned int link_mtu; /* max on-the-wire DTLS packet size */ - unsigned int mtu; /* max DTLS packet size */ - struct hm_header_st w_msg_hdr; - struct hm_header_st r_msg_hdr; - struct dtls1_timeout_st timeout; - /* - * Indicates when the last handshake msg or heartbeat sent will timeout - */ - struct timeval next_timeout; - /* Timeout duration */ - unsigned short timeout_duration; - /* - * storage for Alert/Handshake protocol data received but not yet - * processed by ssl3_read_bytes: - */ - unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; - unsigned int alert_fragment_len; - unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; - unsigned int handshake_fragment_len; - unsigned int retransmitting; - /* - * Set when the handshake is ready to process peer's ChangeCipherSpec message. - * Cleared after the message has been processed. - */ - unsigned int change_cipher_spec_ok; -# ifndef OPENSSL_NO_SCTP - /* used when SSL_ST_XX_FLUSH is entered */ - int next_state; - int shutdown_received; -# endif -} DTLS1_STATE; - -typedef struct dtls1_record_data_st { - unsigned char *packet; - unsigned int packet_length; - SSL3_BUFFER rbuf; - SSL3_RECORD rrec; -# ifndef OPENSSL_NO_SCTP - struct bio_dgram_sctp_rcvinfo recordinfo; -# endif -} DTLS1_RECORD_DATA; - -# endif - -/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ -# define DTLS1_TMO_READ_COUNT 2 -# define DTLS1_TMO_WRITE_COUNT 2 - -# define DTLS1_TMO_ALERT_COUNT 12 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_4758cca.c b/Sources/COpenSSL/e_4758cca.c deleted file mode 100644 index a5e5e04e..00000000 --- a/Sources/COpenSSL/e_4758cca.c +++ /dev/null @@ -1,961 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* Author: Maurice Gittens */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "crypto.h" -#include "dso.h" -#include "x509.h" -#include "objects.h" -#include "engine.h" -#include "rand.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#include "bn.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_4758_CCA - -# ifdef FLAT_INC -# include "hw_4758_cca.h" -# else -# include "hw_4758_cca.h" -# endif - -# include "e_4758cca_err.c" - -static int ibm_4758_cca_destroy(ENGINE *e); -static int ibm_4758_cca_init(ENGINE *e); -static int ibm_4758_cca_finish(ENGINE *e); -static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, - void (*f) (void)); - -/* rsa functions */ -/* -------------*/ -# ifndef OPENSSL_NO_RSA -static int cca_rsa_pub_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int cca_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, - const RSA *rsa); -static int cca_rsa_verify(int dtype, const unsigned char *m, - unsigned int m_len, const unsigned char *sigbuf, - unsigned int siglen, const RSA *rsa); - -/* utility functions */ -/* ---------------------*/ -static EVP_PKEY *ibm_4758_load_privkey(ENGINE *, const char *, - UI_METHOD *ui_method, - void *callback_data); -static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *, const char *, - UI_METHOD *ui_method, - void *callback_data); - -static int getModulusAndExponent(const unsigned char *token, - long *exponentLength, - unsigned char *exponent, long *modulusLength, - long *modulusFieldLength, - unsigned char *modulus); -# endif - -/* RAND number functions */ -/* ---------------------*/ -static int cca_get_random_bytes(unsigned char *, int); -static int cca_random_status(void); - -# ifndef OPENSSL_NO_RSA -static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp); -# endif - -/* Function pointers for CCA verbs */ -/* -------------------------------*/ -# ifndef OPENSSL_NO_RSA -static F_KEYRECORDREAD keyRecordRead; -static F_DIGITALSIGNATUREGENERATE digitalSignatureGenerate; -static F_DIGITALSIGNATUREVERIFY digitalSignatureVerify; -static F_PUBLICKEYEXTRACT publicKeyExtract; -static F_PKAENCRYPT pkaEncrypt; -static F_PKADECRYPT pkaDecrypt; -# endif -static F_RANDOMNUMBERGENERATE randomNumberGenerate; - -/* static variables */ -/* ----------------*/ -static const char *CCA4758_LIB_NAME = NULL; -static const char *get_CCA4758_LIB_NAME(void) -{ - if (CCA4758_LIB_NAME) - return CCA4758_LIB_NAME; - return CCA_LIB_NAME; -} - -static void free_CCA4758_LIB_NAME(void) -{ - if (CCA4758_LIB_NAME) - OPENSSL_free((void *)CCA4758_LIB_NAME); - CCA4758_LIB_NAME = NULL; -} - -static long set_CCA4758_LIB_NAME(const char *name) -{ - free_CCA4758_LIB_NAME(); - return (((CCA4758_LIB_NAME = BUF_strdup(name)) != NULL) ? 1 : 0); -} - -# ifndef OPENSSL_NO_RSA -static const char *n_keyRecordRead = CSNDKRR; -static const char *n_digitalSignatureGenerate = CSNDDSG; -static const char *n_digitalSignatureVerify = CSNDDSV; -static const char *n_publicKeyExtract = CSNDPKX; -static const char *n_pkaEncrypt = CSNDPKE; -static const char *n_pkaDecrypt = CSNDPKD; -# endif -static const char *n_randomNumberGenerate = CSNBRNG; - -# ifndef OPENSSL_NO_RSA -static int hndidx = -1; -# endif -static DSO *dso = NULL; - -/* openssl engine initialization structures */ -/* ----------------------------------------*/ - -# define CCA4758_CMD_SO_PATH ENGINE_CMD_BASE -static const ENGINE_CMD_DEFN cca4758_cmd_defns[] = { - {CCA4758_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the '4758cca' shared library", - ENGINE_CMD_FLAG_STRING}, - {0, NULL, NULL, 0} -}; - -# ifndef OPENSSL_NO_RSA -static RSA_METHOD ibm_4758_cca_rsa = { - "IBM 4758 CCA RSA method", - cca_rsa_pub_enc, - NULL, - NULL, - cca_rsa_priv_dec, - NULL, /* rsa_mod_exp, */ - NULL, /* mod_exp_mont, */ - NULL, /* init */ - NULL, /* finish */ - RSA_FLAG_SIGN_VER, /* flags */ - NULL, /* app_data */ - cca_rsa_sign, /* rsa_sign */ - cca_rsa_verify, /* rsa_verify */ - NULL /* rsa_keygen */ -}; -# endif - -static RAND_METHOD ibm_4758_cca_rand = { - /* "IBM 4758 RAND method", */ - NULL, /* seed */ - cca_get_random_bytes, /* get random bytes from the card */ - NULL, /* cleanup */ - NULL, /* add */ - cca_get_random_bytes, /* pseudo rand */ - cca_random_status, /* status */ -}; - -static const char *engine_4758_cca_id = "4758cca"; -static const char *engine_4758_cca_name = - "IBM 4758 CCA hardware engine support"; -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -/* Compatibility hack, the dynamic library uses this form in the path */ -static const char *engine_4758_cca_id_alt = "4758_cca"; -# endif - -/* engine implementation */ -/* ---------------------*/ -static int bind_helper(ENGINE *e) -{ - if (!ENGINE_set_id(e, engine_4758_cca_id) || - !ENGINE_set_name(e, engine_4758_cca_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &ibm_4758_cca_rsa) || -# endif - !ENGINE_set_RAND(e, &ibm_4758_cca_rand) || - !ENGINE_set_destroy_function(e, ibm_4758_cca_destroy) || - !ENGINE_set_init_function(e, ibm_4758_cca_init) || - !ENGINE_set_finish_function(e, ibm_4758_cca_finish) || - !ENGINE_set_ctrl_function(e, ibm_4758_cca_ctrl) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_load_privkey_function(e, ibm_4758_load_privkey) || - !ENGINE_set_load_pubkey_function(e, ibm_4758_load_pubkey) || -# endif - !ENGINE_set_cmd_defns(e, cca4758_cmd_defns)) - return 0; - /* Ensure the error handling is set up */ - ERR_load_CCA4758_strings(); - return 1; -} - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE -static ENGINE *engine_4758_cca(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_4758cca(void) -{ - ENGINE *e_4758 = engine_4758_cca(); - if (!e_4758) - return; - ENGINE_add(e_4758); - ENGINE_free(e_4758); - ERR_clear_error(); -} -# endif - -static int ibm_4758_cca_destroy(ENGINE *e) -{ - ERR_unload_CCA4758_strings(); - free_CCA4758_LIB_NAME(); - return 1; -} - -static int ibm_4758_cca_init(ENGINE *e) -{ - if (dso) { - CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_ALREADY_LOADED); - goto err; - } - - dso = DSO_load(NULL, get_CCA4758_LIB_NAME(), NULL, 0); - if (!dso) { - CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); - goto err; - } -# ifndef OPENSSL_NO_RSA - if (!(keyRecordRead = (F_KEYRECORDREAD) - DSO_bind_func(dso, n_keyRecordRead)) || - !(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) - DSO_bind_func(dso, n_randomNumberGenerate)) || - !(digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) - DSO_bind_func(dso, n_digitalSignatureGenerate)) || - !(digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY) - DSO_bind_func(dso, n_digitalSignatureVerify)) || - !(publicKeyExtract = (F_PUBLICKEYEXTRACT) - DSO_bind_func(dso, n_publicKeyExtract)) || - !(pkaEncrypt = (F_PKAENCRYPT) - DSO_bind_func(dso, n_pkaEncrypt)) || !(pkaDecrypt = (F_PKADECRYPT) - DSO_bind_func(dso, - n_pkaDecrypt))) - { - CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); - goto err; - } -# else - if (!(randomNumberGenerate = (F_RANDOMNUMBERGENERATE) - DSO_bind_func(dso, n_randomNumberGenerate))) { - CCA4758err(CCA4758_F_IBM_4758_CCA_INIT, CCA4758_R_DSO_FAILURE); - goto err; - } -# endif - -# ifndef OPENSSL_NO_RSA - hndidx = RSA_get_ex_new_index(0, "IBM 4758 CCA RSA key handle", - NULL, NULL, cca_ex_free); -# endif - - return 1; - err: - if (dso) - DSO_free(dso); - dso = NULL; - -# ifndef OPENSSL_NO_RSA - keyRecordRead = (F_KEYRECORDREAD) 0; - digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; - digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; - publicKeyExtract = (F_PUBLICKEYEXTRACT)0; - pkaEncrypt = (F_PKAENCRYPT) 0; - pkaDecrypt = (F_PKADECRYPT) 0; -# endif - randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; - return 0; -} - -static int ibm_4758_cca_finish(ENGINE *e) -{ - free_CCA4758_LIB_NAME(); - if (!dso) { - CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_NOT_LOADED); - return 0; - } - if (!DSO_free(dso)) { - CCA4758err(CCA4758_F_IBM_4758_CCA_FINISH, CCA4758_R_UNIT_FAILURE); - return 0; - } - dso = NULL; -# ifndef OPENSSL_NO_RSA - keyRecordRead = (F_KEYRECORDREAD) 0; - randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; - digitalSignatureGenerate = (F_DIGITALSIGNATUREGENERATE) 0; - digitalSignatureVerify = (F_DIGITALSIGNATUREVERIFY)0; - publicKeyExtract = (F_PUBLICKEYEXTRACT)0; - pkaEncrypt = (F_PKAENCRYPT) 0; - pkaDecrypt = (F_PKADECRYPT) 0; -# endif - randomNumberGenerate = (F_RANDOMNUMBERGENERATE) 0; - return 1; -} - -static int ibm_4758_cca_ctrl(ENGINE *e, int cmd, long i, void *p, - void (*f) (void)) -{ - int initialised = ((dso == NULL) ? 0 : 1); - switch (cmd) { - case CCA4758_CMD_SO_PATH: - if (p == NULL) { - CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (initialised) { - CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, CCA4758_R_ALREADY_LOADED); - return 0; - } - return set_CCA4758_LIB_NAME((const char *)p); - default: - break; - } - CCA4758err(CCA4758_F_IBM_4758_CCA_CTRL, - CCA4758_R_COMMAND_NOT_IMPLEMENTED); - return 0; -} - -# ifndef OPENSSL_NO_RSA - -# define MAX_CCA_PKA_TOKEN_SIZE 2500 - -static EVP_PKEY *ibm_4758_load_privkey(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, - void *callback_data) -{ - RSA *rtmp = NULL; - EVP_PKEY *res = NULL; - unsigned char *keyToken = NULL; - unsigned char pubKeyToken[MAX_CCA_PKA_TOKEN_SIZE]; - long pubKeyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; - long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; - long returnCode; - long reasonCode; - long exitDataLength = 0; - long ruleArrayLength = 0; - unsigned char exitData[8]; - unsigned char ruleArray[8]; - unsigned char keyLabel[64]; - unsigned long keyLabelLength = strlen(key_id); - unsigned char modulus[256]; - long modulusFieldLength = sizeof(modulus); - long modulusLength = 0; - unsigned char exponent[256]; - long exponentLength = sizeof(exponent); - - if (keyLabelLength > sizeof(keyLabel)) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, - CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return NULL; - } - - memset(keyLabel, ' ', sizeof(keyLabel)); - memcpy(keyLabel, key_id, keyLabelLength); - - keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); - if (!keyToken) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - keyRecordRead(&returnCode, &reasonCode, &exitDataLength, - exitData, &ruleArrayLength, ruleArray, keyLabel, - &keyTokenLength, keyToken + sizeof(long)); - - if (returnCode) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, - CCA4758_R_FAILED_LOADING_PRIVATE_KEY); - goto err; - } - - publicKeyExtract(&returnCode, &reasonCode, &exitDataLength, - exitData, &ruleArrayLength, ruleArray, &keyTokenLength, - keyToken + sizeof(long), &pubKeyTokenLength, - pubKeyToken); - - if (returnCode) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, - CCA4758_R_FAILED_LOADING_PRIVATE_KEY); - goto err; - } - - if (!getModulusAndExponent(pubKeyToken, &exponentLength, - exponent, &modulusLength, &modulusFieldLength, - modulus)) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, - CCA4758_R_FAILED_LOADING_PRIVATE_KEY); - goto err; - } - - (*(long *)keyToken) = keyTokenLength; - rtmp = RSA_new_method(e); - if (rtmp == NULL) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); - - rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); - rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); - rtmp->flags |= RSA_FLAG_EXT_PKEY; - - res = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(res, rtmp); - - return res; - err: - if (keyToken) - OPENSSL_free(keyToken); - return NULL; -} - -static EVP_PKEY *ibm_4758_load_pubkey(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, - void *callback_data) -{ - RSA *rtmp = NULL; - EVP_PKEY *res = NULL; - unsigned char *keyToken = NULL; - long keyTokenLength = MAX_CCA_PKA_TOKEN_SIZE; - long returnCode; - long reasonCode; - long exitDataLength = 0; - long ruleArrayLength = 0; - unsigned char exitData[8]; - unsigned char ruleArray[8]; - unsigned char keyLabel[64]; - unsigned long keyLabelLength = strlen(key_id); - unsigned char modulus[512]; - long modulusFieldLength = sizeof(modulus); - long modulusLength = 0; - unsigned char exponent[512]; - long exponentLength = sizeof(exponent); - - if (keyLabelLength > sizeof(keyLabel)) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, - CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return NULL; - } - - memset(keyLabel, ' ', sizeof(keyLabel)); - memcpy(keyLabel, key_id, keyLabelLength); - - keyToken = OPENSSL_malloc(MAX_CCA_PKA_TOKEN_SIZE + sizeof(long)); - if (!keyToken) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - keyRecordRead(&returnCode, &reasonCode, &exitDataLength, exitData, - &ruleArrayLength, ruleArray, keyLabel, &keyTokenLength, - keyToken + sizeof(long)); - - if (returnCode) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!getModulusAndExponent(keyToken + sizeof(long), &exponentLength, - exponent, &modulusLength, &modulusFieldLength, - modulus)) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, - CCA4758_R_FAILED_LOADING_PUBLIC_KEY); - goto err; - } - - (*(long *)keyToken) = keyTokenLength; - rtmp = RSA_new_method(e); - if (rtmp == NULL) { - CCA4758err(CCA4758_F_IBM_4758_LOAD_PUBKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - RSA_set_ex_data(rtmp, hndidx, (char *)keyToken); - rtmp->e = BN_bin2bn(exponent, exponentLength, NULL); - rtmp->n = BN_bin2bn(modulus, modulusFieldLength, NULL); - rtmp->flags |= RSA_FLAG_EXT_PKEY; - res = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(res, rtmp); - - return res; - err: - if (keyToken) - OPENSSL_free(keyToken); - return NULL; -} - -static int cca_rsa_pub_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - long returnCode; - long reasonCode; - long lflen = flen; - long exitDataLength = 0; - unsigned char exitData[8]; - long ruleArrayLength = 1; - unsigned char ruleArray[8] = "PKCS-1.2"; - long dataStructureLength = 0; - unsigned char dataStructure[8]; - long outputLength = RSA_size(rsa); - long keyTokenLength; - unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); - - keyTokenLength = *(long *)keyToken; - keyToken += sizeof(long); - - pkaEncrypt(&returnCode, &reasonCode, &exitDataLength, exitData, - &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, - &dataStructureLength, dataStructure, &keyTokenLength, - keyToken, &outputLength, to); - - if (returnCode || reasonCode) - return -(returnCode << 16 | reasonCode); - return outputLength; -} - -static int cca_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - long returnCode; - long reasonCode; - long lflen = flen; - long exitDataLength = 0; - unsigned char exitData[8]; - long ruleArrayLength = 1; - unsigned char ruleArray[8] = "PKCS-1.2"; - long dataStructureLength = 0; - unsigned char dataStructure[8]; - long outputLength = RSA_size(rsa); - long keyTokenLength; - unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); - - keyTokenLength = *(long *)keyToken; - keyToken += sizeof(long); - - pkaDecrypt(&returnCode, &reasonCode, &exitDataLength, exitData, - &ruleArrayLength, ruleArray, &lflen, (unsigned char *)from, - &dataStructureLength, dataStructure, &keyTokenLength, - keyToken, &outputLength, to); - - return (returnCode | reasonCode) ? 0 : 1; -} - -# define SSL_SIG_LEN 36 - -static int cca_rsa_verify(int type, const unsigned char *m, - unsigned int m_len, const unsigned char *sigbuf, - unsigned int siglen, const RSA *rsa) -{ - long returnCode; - long reasonCode; - long lsiglen = siglen; - long exitDataLength = 0; - unsigned char exitData[8]; - long ruleArrayLength = 1; - unsigned char ruleArray[8] = "PKCS-1.1"; - long keyTokenLength; - unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); - long length = SSL_SIG_LEN; - long keyLength; - unsigned char *hashBuffer = NULL; - X509_SIG sig; - ASN1_TYPE parameter; - X509_ALGOR algorithm; - ASN1_OCTET_STRING digest; - - keyTokenLength = *(long *)keyToken; - keyToken += sizeof(long); - - if (type == NID_md5 || type == NID_sha1) { - sig.algor = &algorithm; - algorithm.algorithm = OBJ_nid2obj(type); - - if (!algorithm.algorithm) { - CCA4758err(CCA4758_F_CCA_RSA_VERIFY, - CCA4758_R_UNKNOWN_ALGORITHM_TYPE); - return 0; - } - - if (!algorithm.algorithm->length) { - CCA4758err(CCA4758_F_CCA_RSA_VERIFY, - CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); - return 0; - } - - parameter.type = V_ASN1_NULL; - parameter.value.ptr = NULL; - algorithm.parameter = ¶meter; - - sig.digest = &digest; - sig.digest->data = (unsigned char *)m; - sig.digest->length = m_len; - - length = i2d_X509_SIG(&sig, NULL); - } - - keyLength = RSA_size(rsa); - - if (length - RSA_PKCS1_PADDING > keyLength) { - CCA4758err(CCA4758_F_CCA_RSA_VERIFY, - CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return 0; - } - - switch (type) { - case NID_md5_sha1: - if (m_len != SSL_SIG_LEN) { - CCA4758err(CCA4758_F_CCA_RSA_VERIFY, - CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return 0; - } - - hashBuffer = (unsigned char *)m; - length = m_len; - break; - case NID_md5: - { - unsigned char *ptr; - ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); - if (!hashBuffer) { - CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); - return 0; - } - - i2d_X509_SIG(&sig, &ptr); - } - break; - case NID_sha1: - { - unsigned char *ptr; - ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); - if (!hashBuffer) { - CCA4758err(CCA4758_F_CCA_RSA_VERIFY, ERR_R_MALLOC_FAILURE); - return 0; - } - i2d_X509_SIG(&sig, &ptr); - } - break; - default: - return 0; - } - - digitalSignatureVerify(&returnCode, &reasonCode, &exitDataLength, - exitData, &ruleArrayLength, ruleArray, - &keyTokenLength, keyToken, &length, hashBuffer, - &lsiglen, (unsigned char *)sigbuf); - - if (type == NID_sha1 || type == NID_md5) { - OPENSSL_cleanse(hashBuffer, keyLength + 1); - OPENSSL_free(hashBuffer); - } - - return ((returnCode || reasonCode) ? 0 : 1); -} - -# define SSL_SIG_LEN 36 - -static int cca_rsa_sign(int type, const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, - const RSA *rsa) -{ - long returnCode; - long reasonCode; - long exitDataLength = 0; - unsigned char exitData[8]; - long ruleArrayLength = 1; - unsigned char ruleArray[8] = "PKCS-1.1"; - long outputLength = 256; - long outputBitLength; - long keyTokenLength; - unsigned char *hashBuffer = NULL; - unsigned char *keyToken = (unsigned char *)RSA_get_ex_data(rsa, hndidx); - long length = SSL_SIG_LEN; - long keyLength; - X509_SIG sig; - ASN1_TYPE parameter; - X509_ALGOR algorithm; - ASN1_OCTET_STRING digest; - - keyTokenLength = *(long *)keyToken; - keyToken += sizeof(long); - - if (type == NID_md5 || type == NID_sha1) { - sig.algor = &algorithm; - algorithm.algorithm = OBJ_nid2obj(type); - - if (!algorithm.algorithm) { - CCA4758err(CCA4758_F_CCA_RSA_SIGN, - CCA4758_R_UNKNOWN_ALGORITHM_TYPE); - return 0; - } - - if (!algorithm.algorithm->length) { - CCA4758err(CCA4758_F_CCA_RSA_SIGN, - CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD); - return 0; - } - - parameter.type = V_ASN1_NULL; - parameter.value.ptr = NULL; - algorithm.parameter = ¶meter; - - sig.digest = &digest; - sig.digest->data = (unsigned char *)m; - sig.digest->length = m_len; - - length = i2d_X509_SIG(&sig, NULL); - } - - keyLength = RSA_size(rsa); - - if (length - RSA_PKCS1_PADDING > keyLength) { - CCA4758err(CCA4758_F_CCA_RSA_SIGN, - CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return 0; - } - - switch (type) { - case NID_md5_sha1: - if (m_len != SSL_SIG_LEN) { - CCA4758err(CCA4758_F_CCA_RSA_SIGN, - CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return 0; - } - hashBuffer = (unsigned char *)m; - length = m_len; - break; - case NID_md5: - { - unsigned char *ptr; - ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); - if (!hashBuffer) { - CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); - return 0; - } - i2d_X509_SIG(&sig, &ptr); - } - break; - case NID_sha1: - { - unsigned char *ptr; - ptr = hashBuffer = OPENSSL_malloc((unsigned int)keyLength + 1); - if (!hashBuffer) { - CCA4758err(CCA4758_F_CCA_RSA_SIGN, ERR_R_MALLOC_FAILURE); - return 0; - } - i2d_X509_SIG(&sig, &ptr); - } - break; - default: - return 0; - } - - digitalSignatureGenerate(&returnCode, &reasonCode, &exitDataLength, - exitData, &ruleArrayLength, ruleArray, - &keyTokenLength, keyToken, &length, hashBuffer, - &outputLength, &outputBitLength, sigret); - - if (type == NID_sha1 || type == NID_md5) { - OPENSSL_cleanse(hashBuffer, keyLength + 1); - OPENSSL_free(hashBuffer); - } - - *siglen = outputLength; - - return ((returnCode || reasonCode) ? 0 : 1); -} - -static int getModulusAndExponent(const unsigned char *token, - long *exponentLength, - unsigned char *exponent, long *modulusLength, - long *modulusFieldLength, - unsigned char *modulus) -{ - unsigned long len; - - if (*token++ != (char)0x1E) /* internal PKA token? */ - return 0; - - if (*token++) /* token version must be zero */ - return 0; - - len = *token++; - len = len << 8; - len |= (unsigned char)*token++; - - token += 4; /* skip reserved bytes */ - - if (*token++ == (char)0x04) { - if (*token++) /* token version must be zero */ - return 0; - - len = *token++; - len = len << 8; - len |= (unsigned char)*token++; - - token += 2; /* skip reserved section */ - - len = *token++; - len = len << 8; - len |= (unsigned char)*token++; - - *exponentLength = len; - - len = *token++; - len = len << 8; - len |= (unsigned char)*token++; - - *modulusLength = len; - - len = *token++; - len = len << 8; - len |= (unsigned char)*token++; - - *modulusFieldLength = len; - - memcpy(exponent, token, *exponentLength); - token += *exponentLength; - - memcpy(modulus, token, *modulusFieldLength); - return 1; - } - return 0; -} - -# endif /* OPENSSL_NO_RSA */ - -static int cca_random_status(void) -{ - return 1; -} - -static int cca_get_random_bytes(unsigned char *buf, int num) -{ - long ret_code; - long reason_code; - long exit_data_length; - unsigned char exit_data[4]; - unsigned char form[] = "RANDOM "; - unsigned char rand_buf[8]; - - while (num >= (int)sizeof(rand_buf)) { - randomNumberGenerate(&ret_code, &reason_code, &exit_data_length, - exit_data, form, rand_buf); - if (ret_code) - return 0; - num -= sizeof(rand_buf); - memcpy(buf, rand_buf, sizeof(rand_buf)); - buf += sizeof(rand_buf); - } - - if (num) { - randomNumberGenerate(&ret_code, &reason_code, NULL, NULL, - form, rand_buf); - if (ret_code) - return 0; - memcpy(buf, rand_buf, num); - } - - return 1; -} - -# ifndef OPENSSL_NO_RSA -static void cca_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, int idx, - long argl, void *argp) -{ - if (item) - OPENSSL_free(item); -} -# endif - -/* Goo to handle building as a dynamic engine */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_4758_cca_id) != 0) && - (strcmp(id, engine_4758_cca_id_alt) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ -# endif /* !OPENSSL_NO_HW_4758_CCA */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_4758cca_err.c b/Sources/COpenSSL/e_4758cca_err.c deleted file mode 100644 index f9d9fe90..00000000 --- a/Sources/COpenSSL/e_4758cca_err.c +++ /dev/null @@ -1,153 +0,0 @@ -/* e_4758cca_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_4758cca_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA CCA4758_str_functs[] = { - {ERR_FUNC(CCA4758_F_CCA_RSA_SIGN), "CCA_RSA_SIGN"}, - {ERR_FUNC(CCA4758_F_CCA_RSA_VERIFY), "CCA_RSA_VERIFY"}, - {ERR_FUNC(CCA4758_F_IBM_4758_CCA_CTRL), "IBM_4758_CCA_CTRL"}, - {ERR_FUNC(CCA4758_F_IBM_4758_CCA_FINISH), "IBM_4758_CCA_FINISH"}, - {ERR_FUNC(CCA4758_F_IBM_4758_CCA_INIT), "IBM_4758_CCA_INIT"}, - {ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PRIVKEY), "IBM_4758_LOAD_PRIVKEY"}, - {ERR_FUNC(CCA4758_F_IBM_4758_LOAD_PUBKEY), "IBM_4758_LOAD_PUBKEY"}, - {0, NULL} -}; - -static ERR_STRING_DATA CCA4758_str_reasons[] = { - {ERR_REASON(CCA4758_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD), - "asn1 oid unknown for md"}, - {ERR_REASON(CCA4758_R_COMMAND_NOT_IMPLEMENTED), - "command not implemented"}, - {ERR_REASON(CCA4758_R_DSO_FAILURE), "dso failure"}, - {ERR_REASON(CCA4758_R_FAILED_LOADING_PRIVATE_KEY), - "failed loading private key"}, - {ERR_REASON(CCA4758_R_FAILED_LOADING_PUBLIC_KEY), - "failed loading public key"}, - {ERR_REASON(CCA4758_R_NOT_LOADED), "not loaded"}, - {ERR_REASON(CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL), - "size too large or too small"}, - {ERR_REASON(CCA4758_R_UNIT_FAILURE), "unit failure"}, - {ERR_REASON(CCA4758_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"}, - {0, NULL} -}; - -#endif - -#ifdef CCA4758_LIB_NAME -static ERR_STRING_DATA CCA4758_lib_name[] = { - {0, CCA4758_LIB_NAME}, - {0, NULL} -}; -#endif - -static int CCA4758_lib_error_code = 0; -static int CCA4758_error_init = 1; - -static void ERR_load_CCA4758_strings(void) -{ - if (CCA4758_lib_error_code == 0) - CCA4758_lib_error_code = ERR_get_next_error_library(); - - if (CCA4758_error_init) { - CCA4758_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(CCA4758_lib_error_code, CCA4758_str_functs); - ERR_load_strings(CCA4758_lib_error_code, CCA4758_str_reasons); -#endif - -#ifdef CCA4758_LIB_NAME - CCA4758_lib_name->error = ERR_PACK(CCA4758_lib_error_code, 0, 0); - ERR_load_strings(0, CCA4758_lib_name); -#endif - } -} - -static void ERR_unload_CCA4758_strings(void) -{ - if (CCA4758_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(CCA4758_lib_error_code, CCA4758_str_functs); - ERR_unload_strings(CCA4758_lib_error_code, CCA4758_str_reasons); -#endif - -#ifdef CCA4758_LIB_NAME - ERR_unload_strings(0, CCA4758_lib_name); -#endif - CCA4758_error_init = 1; - } -} - -static void ERR_CCA4758_error(int function, int reason, char *file, int line) -{ - if (CCA4758_lib_error_code == 0) - CCA4758_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(CCA4758_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_4758cca_err.h b/Sources/COpenSSL/e_4758cca_err.h deleted file mode 100644 index 2f29d96f..00000000 --- a/Sources/COpenSSL/e_4758cca_err.h +++ /dev/null @@ -1,98 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_CCA4758_ERR_H -# define HEADER_CCA4758_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_CCA4758_strings(void); -static void ERR_unload_CCA4758_strings(void); -static void ERR_CCA4758_error(int function, int reason, char *file, int line); -# define CCA4758err(f,r) ERR_CCA4758_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the CCA4758 functions. */ - -/* Function codes. */ -# define CCA4758_F_CCA_RSA_SIGN 105 -# define CCA4758_F_CCA_RSA_VERIFY 106 -# define CCA4758_F_IBM_4758_CCA_CTRL 100 -# define CCA4758_F_IBM_4758_CCA_FINISH 101 -# define CCA4758_F_IBM_4758_CCA_INIT 102 -# define CCA4758_F_IBM_4758_LOAD_PRIVKEY 103 -# define CCA4758_F_IBM_4758_LOAD_PUBKEY 104 - -/* Reason codes. */ -# define CCA4758_R_ALREADY_LOADED 100 -# define CCA4758_R_ASN1_OID_UNKNOWN_FOR_MD 101 -# define CCA4758_R_COMMAND_NOT_IMPLEMENTED 102 -# define CCA4758_R_DSO_FAILURE 103 -# define CCA4758_R_FAILED_LOADING_PRIVATE_KEY 104 -# define CCA4758_R_FAILED_LOADING_PUBLIC_KEY 105 -# define CCA4758_R_NOT_LOADED 106 -# define CCA4758_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107 -# define CCA4758_R_UNIT_FAILURE 108 -# define CCA4758_R_UNKNOWN_ALGORITHM_TYPE 109 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_aep.c b/Sources/COpenSSL/e_aep.c deleted file mode 100644 index 0f433ec7..00000000 --- a/Sources/COpenSSL/e_aep.c +++ /dev/null @@ -1,1168 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "bn.h" -#include - -#include "e_os2.h" -#if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) || defined(__MINGW32__) -# include -# include -#else -# include -typedef int pid_t; -#endif - -#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) -# define getpid GetThreadID -extern int GetThreadID(void); -#elif defined(_WIN32) && !defined(__WATCOMC__) -# define getpid _getpid -#endif - -#include "crypto.h" -#include "dso.h" -#include "engine.h" -#include "buffer.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_AEP -# ifdef FLAT_INC -# include "aep.h" -# else -# include "aep.h" -# endif - -# define AEP_LIB_NAME "aep engine" -# define FAIL_TO_SW 0x10101010 - -# include "e_aep_err.c" - -static int aep_init(ENGINE *e); -static int aep_finish(ENGINE *e); -static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); -static int aep_destroy(ENGINE *e); - -static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR hConnection); -static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection); -static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection); -static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use); - -/* BIGNUM stuff */ -# ifndef OPENSSL_NO_RSA -static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); - -static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *q, const BIGNUM *dmp1, - const BIGNUM *dmq1, const BIGNUM *iqmp, - BN_CTX *ctx); -# endif - -/* RSA stuff */ -# ifndef OPENSSL_NO_RSA -static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -# endif - -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -# ifndef OPENSSL_NO_RSA -static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -# endif - -/* DSA stuff */ -# ifndef OPENSSL_NO_DSA -static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, - BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *in_mont); - -static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -/* DH stuff */ -/* This function is aliased to mod_exp (with the DH and mont dropped). */ -# ifndef OPENSSL_NO_DH -static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -/* rand stuff */ -# ifdef AEPRAND -static int aep_rand(unsigned char *buf, int num); -static int aep_rand_status(void); -# endif - -/* Bignum conversion stuff */ -static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32 *BigNumSize); -static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize, - unsigned char *AEP_BigNum); -static AEP_RV ConvertAEPBigNum(void *ArbBigNum, AEP_U32 BigNumSize, - unsigned char *AEP_BigNum); - -/* The definitions for control commands specific to this engine */ -# define AEP_CMD_SO_PATH ENGINE_CMD_BASE -static const ENGINE_CMD_DEFN aep_cmd_defns[] = { - {AEP_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'aep' shared library", - ENGINE_CMD_FLAG_STRING}, - {0, NULL, NULL, 0} -}; - -# ifndef OPENSSL_NO_RSA -/* Our internal RSA_METHOD that we provide pointers to */ -static RSA_METHOD aep_rsa = { - "Aep RSA method", - NULL, /* rsa_pub_encrypt */ - NULL, /* rsa_pub_decrypt */ - NULL, /* rsa_priv_encrypt */ - NULL, /* rsa_priv_encrypt */ - aep_rsa_mod_exp, /* rsa_mod_exp */ - aep_mod_exp_mont, /* bn_mod_exp */ - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - NULL, /* rsa_sign */ - NULL, /* rsa_verify */ - NULL /* rsa_keygen */ -}; -# endif - -# ifndef OPENSSL_NO_DSA -/* Our internal DSA_METHOD that we provide pointers to */ -static DSA_METHOD aep_dsa = { - "Aep DSA method", - NULL, /* dsa_do_sign */ - NULL, /* dsa_sign_setup */ - NULL, /* dsa_do_verify */ - aep_dsa_mod_exp, /* dsa_mod_exp */ - aep_mod_exp_dsa, /* bn_mod_exp */ - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - NULL, /* dsa_paramgen */ - NULL /* dsa_keygen */ -}; -# endif - -# ifndef OPENSSL_NO_DH -/* Our internal DH_METHOD that we provide pointers to */ -static DH_METHOD aep_dh = { - "Aep DH method", - NULL, - NULL, - aep_mod_exp_dh, - NULL, - NULL, - 0, - NULL, - NULL -}; -# endif - -# ifdef AEPRAND -/* our internal RAND_method that we provide pointers to */ -static RAND_METHOD aep_random = { - /* - * "AEP RAND method", - */ - NULL, - aep_rand, - NULL, - NULL, - aep_rand, - aep_rand_status, -}; -# endif - -/* - * Define an array of structures to hold connections - */ -static AEP_CONNECTION_ENTRY aep_app_conn_table[MAX_PROCESS_CONNECTIONS]; - -/* - * Used to determine if this is a new process - */ -static pid_t recorded_pid = 0; - -# ifdef AEPRAND -static AEP_U8 rand_block[RAND_BLK_SIZE]; -static AEP_U32 rand_block_bytes = 0; -# endif - -/* Constants used when creating the ENGINE */ -static const char *engine_aep_id = "aep"; -static const char *engine_aep_name = "Aep hardware engine support"; - -static int max_key_len = 2176; - -/* - * This internal function is used by ENGINE_aep() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_aep(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif -# ifndef OPENSSL_NO_DSA - const DSA_METHOD *meth2; -# endif -# ifndef OPENSSL_NO_DH - const DH_METHOD *meth3; -# endif - - if (!ENGINE_set_id(e, engine_aep_id) || - !ENGINE_set_name(e, engine_aep_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &aep_rsa) || -# endif -# ifndef OPENSSL_NO_DSA - !ENGINE_set_DSA(e, &aep_dsa) || -# endif -# ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &aep_dh) || -# endif -# ifdef AEPRAND - !ENGINE_set_RAND(e, &aep_random) || -# endif - !ENGINE_set_init_function(e, aep_init) || - !ENGINE_set_destroy_function(e, aep_destroy) || - !ENGINE_set_finish_function(e, aep_finish) || - !ENGINE_set_ctrl_function(e, aep_ctrl) || - !ENGINE_set_cmd_defns(e, aep_cmd_defns)) - return 0; - -# ifndef OPENSSL_NO_RSA - /* - * We know that the "PKCS1_SSLeay()" functions hook properly to the - * aep-specific mod_exp and mod_exp_crt so we use those functions. NB: We - * don't use ENGINE_openssl() or anything "more generic" because - * something like the RSAref code may not hook properly, and if you own - * one of these cards then you have the right to do RSA operations on it - * anyway! - */ - meth1 = RSA_PKCS1_SSLeay(); - aep_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - aep_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - aep_rsa.rsa_priv_enc = meth1->rsa_priv_enc; - aep_rsa.rsa_priv_dec = meth1->rsa_priv_dec; -# endif - -# ifndef OPENSSL_NO_DSA - /* - * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits. - */ - meth2 = DSA_OpenSSL(); - aep_dsa.dsa_do_sign = meth2->dsa_do_sign; - aep_dsa.dsa_sign_setup = meth2->dsa_sign_setup; - aep_dsa.dsa_do_verify = meth2->dsa_do_verify; - - aep_dsa = *DSA_get_default_method(); - aep_dsa.dsa_mod_exp = aep_dsa_mod_exp; - aep_dsa.bn_mod_exp = aep_mod_exp_dsa; -# endif - -# ifndef OPENSSL_NO_DH - /* Much the same for Diffie-Hellman */ - meth3 = DH_OpenSSL(); - aep_dh.generate_key = meth3->generate_key; - aep_dh.compute_key = meth3->compute_key; - aep_dh.bn_mod_exp = meth3->bn_mod_exp; -# endif - - /* Ensure the aep error handling is set up */ - ERR_load_AEPHK_strings(); - - return 1; -} - -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_helper(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_aep_id) != 0)) - return 0; - if (!bind_aep(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) -# else -static ENGINE *engine_aep(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_aep(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_aep(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_aep(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -/* - * This is a process-global DSO handle used for loading and unloading the Aep - * library. NB: This is only set (or unset) during an init() or finish() call - * (reference counts permitting) and they're operating with global locks, so - * this should be thread-safe implicitly. - */ -static DSO *aep_dso = NULL; - -/* - * These are the static string constants for the DSO file name and the - * function symbol names to bind to. - */ -static const char *AEP_LIBNAME = NULL; -static const char *get_AEP_LIBNAME(void) -{ - if (AEP_LIBNAME) - return AEP_LIBNAME; - return "aep"; -} - -static void free_AEP_LIBNAME(void) -{ - if (AEP_LIBNAME) - OPENSSL_free((void *)AEP_LIBNAME); - AEP_LIBNAME = NULL; -} - -static long set_AEP_LIBNAME(const char *name) -{ - free_AEP_LIBNAME(); - return ((AEP_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0); -} - -static const char *AEP_F1 = "AEP_ModExp"; -static const char *AEP_F2 = "AEP_ModExpCrt"; -# ifdef AEPRAND -static const char *AEP_F3 = "AEP_GenRandom"; -# endif -static const char *AEP_F4 = "AEP_Finalize"; -static const char *AEP_F5 = "AEP_Initialize"; -static const char *AEP_F6 = "AEP_OpenConnection"; -static const char *AEP_F7 = "AEP_SetBNCallBacks"; -static const char *AEP_F8 = "AEP_CloseConnection"; - -/* - * These are the function pointers that are (un)set when the library has - * successfully (un)loaded. - */ -static t_AEP_OpenConnection *p_AEP_OpenConnection = NULL; -static t_AEP_CloseConnection *p_AEP_CloseConnection = NULL; -static t_AEP_ModExp *p_AEP_ModExp = NULL; -static t_AEP_ModExpCrt *p_AEP_ModExpCrt = NULL; -# ifdef AEPRAND -static t_AEP_GenRandom *p_AEP_GenRandom = NULL; -# endif -static t_AEP_Initialize *p_AEP_Initialize = NULL; -static t_AEP_Finalize *p_AEP_Finalize = NULL; -static t_AEP_SetBNCallBacks *p_AEP_SetBNCallBacks = NULL; - -/* (de)initialisation functions. */ -static int aep_init(ENGINE *e) -{ - t_AEP_ModExp *p1; - t_AEP_ModExpCrt *p2; -# ifdef AEPRAND - t_AEP_GenRandom *p3; -# endif - t_AEP_Finalize *p4; - t_AEP_Initialize *p5; - t_AEP_OpenConnection *p6; - t_AEP_SetBNCallBacks *p7; - t_AEP_CloseConnection *p8; - - int to_return = 0; - - if (aep_dso != NULL) { - AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_ALREADY_LOADED); - goto err; - } - /* Attempt to load libaep.so. */ - - aep_dso = DSO_load(NULL, get_AEP_LIBNAME(), NULL, 0); - - if (aep_dso == NULL) { - AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_NOT_LOADED); - goto err; - } - - if (!(p1 = (t_AEP_ModExp *) DSO_bind_func(aep_dso, AEP_F1)) || - !(p2 = (t_AEP_ModExpCrt *) DSO_bind_func(aep_dso, AEP_F2)) || -# ifdef AEPRAND - !(p3 = (t_AEP_GenRandom *) DSO_bind_func(aep_dso, AEP_F3)) || -# endif - !(p4 = (t_AEP_Finalize *) DSO_bind_func(aep_dso, AEP_F4)) || - !(p5 = (t_AEP_Initialize *) DSO_bind_func(aep_dso, AEP_F5)) || - !(p6 = (t_AEP_OpenConnection *) DSO_bind_func(aep_dso, AEP_F6)) || - !(p7 = (t_AEP_SetBNCallBacks *) DSO_bind_func(aep_dso, AEP_F7)) || - !(p8 = (t_AEP_CloseConnection *) DSO_bind_func(aep_dso, AEP_F8))) { - AEPHKerr(AEPHK_F_AEP_INIT, AEPHK_R_NOT_LOADED); - goto err; - } - - /* Copy the pointers */ - - p_AEP_ModExp = p1; - p_AEP_ModExpCrt = p2; -# ifdef AEPRAND - p_AEP_GenRandom = p3; -# endif - p_AEP_Finalize = p4; - p_AEP_Initialize = p5; - p_AEP_OpenConnection = p6; - p_AEP_SetBNCallBacks = p7; - p_AEP_CloseConnection = p8; - - to_return = 1; - - return to_return; - - err: - - if (aep_dso) - DSO_free(aep_dso); - aep_dso = NULL; - - p_AEP_OpenConnection = NULL; - p_AEP_ModExp = NULL; - p_AEP_ModExpCrt = NULL; -# ifdef AEPRAND - p_AEP_GenRandom = NULL; -# endif - p_AEP_Initialize = NULL; - p_AEP_Finalize = NULL; - p_AEP_SetBNCallBacks = NULL; - p_AEP_CloseConnection = NULL; - - return to_return; -} - -/* Destructor (complements the "ENGINE_aep()" constructor) */ -static int aep_destroy(ENGINE *e) -{ - free_AEP_LIBNAME(); - ERR_unload_AEPHK_strings(); - return 1; -} - -static int aep_finish(ENGINE *e) -{ - int to_return = 0, in_use; - AEP_RV rv; - - if (aep_dso == NULL) { - AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_NOT_LOADED); - goto err; - } - - rv = aep_close_all_connections(0, &in_use); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_CLOSE_HANDLES_FAILED); - goto err; - } - if (in_use) { - AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_CONNECTIONS_IN_USE); - goto err; - } - - rv = p_AEP_Finalize(); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_FINALIZE_FAILED); - goto err; - } - - if (!DSO_free(aep_dso)) { - AEPHKerr(AEPHK_F_AEP_FINISH, AEPHK_R_UNIT_FAILURE); - goto err; - } - - aep_dso = NULL; - p_AEP_CloseConnection = NULL; - p_AEP_OpenConnection = NULL; - p_AEP_ModExp = NULL; - p_AEP_ModExpCrt = NULL; -# ifdef AEPRAND - p_AEP_GenRandom = NULL; -# endif - p_AEP_Initialize = NULL; - p_AEP_Finalize = NULL; - p_AEP_SetBNCallBacks = NULL; - - to_return = 1; - err: - return to_return; -} - -static int aep_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int initialised = ((aep_dso == NULL) ? 0 : 1); - switch (cmd) { - case AEP_CMD_SO_PATH: - if (p == NULL) { - AEPHKerr(AEPHK_F_AEP_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (initialised) { - AEPHKerr(AEPHK_F_AEP_CTRL, AEPHK_R_ALREADY_LOADED); - return 0; - } - return set_AEP_LIBNAME((const char *)p); - default: - break; - } - AEPHKerr(AEPHK_F_AEP_CTRL, AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); - return 0; -} - -static int aep_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - int to_return = 0; - int r_len = 0; - AEP_CONNECTION_HNDL hConnection; - AEP_RV rv; - - r_len = BN_num_bits(m); - - /* Perform in software if modulus is too large for hardware. */ - - if (r_len > max_key_len) { - AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return BN_mod_exp(r, a, p, m, ctx); - } - - /* - * Grab a connection from the pool - */ - rv = aep_get_connection(&hConnection); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_GET_HANDLE_FAILED); - return BN_mod_exp(r, a, p, m, ctx); - } - - /* - * To the card with the mod exp - */ - rv = p_AEP_ModExp(hConnection, (void *)a, (void *)p, (void *)m, (void *)r, - NULL); - - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_MOD_EXP_FAILED); - rv = aep_close_connection(hConnection); - return BN_mod_exp(r, a, p, m, ctx); - } - - /* - * Return the connection to the pool - */ - rv = aep_return_connection(hConnection); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_MOD_EXP, AEPHK_R_RETURN_CONNECTION_FAILED); - goto err; - } - - to_return = 1; - err: - return to_return; -} - -# ifndef OPENSSL_NO_RSA -static AEP_RV aep_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *q, const BIGNUM *dmp1, - const BIGNUM *dmq1, const BIGNUM *iqmp, - BN_CTX *ctx) -{ - AEP_RV rv = AEP_R_OK; - AEP_CONNECTION_HNDL hConnection; - - /* - * Grab a connection from the pool - */ - rv = aep_get_connection(&hConnection); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_GET_HANDLE_FAILED); - return FAIL_TO_SW; - } - - /* - * To the card with the mod exp - */ - rv = p_AEP_ModExpCrt(hConnection, (void *)a, (void *)p, (void *)q, - (void *)dmp1, (void *)dmq1, (void *)iqmp, (void *)r, - NULL); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_MOD_EXP_CRT_FAILED); - rv = aep_close_connection(hConnection); - return FAIL_TO_SW; - } - - /* - * Return the connection to the pool - */ - rv = aep_return_connection(hConnection); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_MOD_EXP_CRT, AEPHK_R_RETURN_CONNECTION_FAILED); - goto err; - } - - err: - return rv; -} -# endif - -# ifdef AEPRAND -static int aep_rand(unsigned char *buf, int len) -{ - AEP_RV rv = AEP_R_OK; - AEP_CONNECTION_HNDL hConnection; - - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - - /* - * Can the request be serviced with what's already in the buffer? - */ - if (len <= rand_block_bytes) { - memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len); - rand_block_bytes -= len; - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - } else - /* - * If not the get another block of random bytes - */ - { - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - - rv = aep_get_connection(&hConnection); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_HANDLE_FAILED); - goto err_nounlock; - } - - if (len > RAND_BLK_SIZE) { - rv = p_AEP_GenRandom(hConnection, len, 2, buf, NULL); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_RANDOM_FAILED); - goto err_nounlock; - } - } else { - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - - rv = p_AEP_GenRandom(hConnection, RAND_BLK_SIZE, 2, - &rand_block[0], NULL); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_GET_RANDOM_FAILED); - - goto err; - } - - rand_block_bytes = RAND_BLK_SIZE; - - memcpy(buf, &rand_block[RAND_BLK_SIZE - rand_block_bytes], len); - rand_block_bytes -= len; - - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - } - - rv = aep_return_connection(hConnection); - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_RAND, AEPHK_R_RETURN_CONNECTION_FAILED); - - goto err_nounlock; - } - } - - return 1; - err: - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - err_nounlock: - return 0; -} - -static int aep_rand_status(void) -{ - return 1; -} -# endif - -# ifndef OPENSSL_NO_RSA -static int aep_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) -{ - int to_return = 0; - AEP_RV rv = AEP_R_OK; - - if (!aep_dso) { - AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP, AEPHK_R_NOT_LOADED); - goto err; - } - - /* - * See if we have all the necessary bits for a crt - */ - if (rsa->q && rsa->dmp1 && rsa->dmq1 && rsa->iqmp) { - rv = aep_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, rsa->dmq1, - rsa->iqmp, ctx); - - if (rv == FAIL_TO_SW) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); - goto err; - } else if (rv != AEP_R_OK) - goto err; - } else { - if (!rsa->d || !rsa->n) { - AEPHKerr(AEPHK_F_AEP_RSA_MOD_EXP, AEPHK_R_MISSING_KEY_COMPONENTS); - goto err; - } - - rv = aep_mod_exp(r0, I, rsa->d, rsa->n, ctx); - if (rv != AEP_R_OK) - goto err; - - } - - to_return = 1; - - err: - return to_return; -} -# endif - -# ifndef OPENSSL_NO_DSA -static int aep_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, - BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *in_mont) -{ - BIGNUM t; - int to_return = 0; - BN_init(&t); - - /* let rr = a1 ^ p1 mod m */ - if (!aep_mod_exp(rr, a1, p1, m, ctx)) - goto end; - /* let t = a2 ^ p2 mod m */ - if (!aep_mod_exp(&t, a2, p2, m, ctx)) - goto end; - /* let rr = rr * t mod m */ - if (!BN_mod_mul(rr, rr, &t, m, ctx)) - goto end; - to_return = 1; - end: - BN_free(&t); - return to_return; -} - -static int aep_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return aep_mod_exp(r, a, p, m, ctx); -} -# endif - -# ifndef OPENSSL_NO_RSA -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int aep_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return aep_mod_exp(r, a, p, m, ctx); -} -# endif - -# ifndef OPENSSL_NO_DH -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int aep_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return aep_mod_exp(r, a, p, m, ctx); -} -# endif - -static AEP_RV aep_get_connection(AEP_CONNECTION_HNDL_PTR phConnection) -{ - int count; - AEP_RV rv = AEP_R_OK; - - /* - * Get the current process id - */ - pid_t curr_pid; - - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - - curr_pid = getpid(); - - /* - * Check if this is the first time this is being called from the current - * process - */ - if (recorded_pid != curr_pid) { - /* - * Remember our pid so we can check if we're in a new process - */ - recorded_pid = curr_pid; - - /* - * Call Finalize to make sure we have not inherited some data from a - * parent process - */ - p_AEP_Finalize(); - - /* - * Initialise the AEP API - */ - rv = p_AEP_Initialize(NULL); - - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_INIT_FAILURE); - recorded_pid = 0; - goto end; - } - - /* - * Set the AEP big num call back functions - */ - rv = p_AEP_SetBNCallBacks(&GetBigNumSize, &MakeAEPBigNum, - &ConvertAEPBigNum); - - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, - AEPHK_R_SETBNCALLBACK_FAILURE); - recorded_pid = 0; - goto end; - } -# ifdef AEPRAND - /* - * Reset the rand byte count - */ - rand_block_bytes = 0; -# endif - - /* - * Init the structures - */ - for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { - aep_app_conn_table[count].conn_state = NotConnected; - aep_app_conn_table[count].conn_hndl = 0; - } - - /* - * Open a connection - */ - rv = p_AEP_OpenConnection(phConnection); - - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_UNIT_FAILURE); - recorded_pid = 0; - goto end; - } - - aep_app_conn_table[0].conn_state = InUse; - aep_app_conn_table[0].conn_hndl = *phConnection; - goto end; - } - /* - * Check the existing connections to see if we can find a free one - */ - for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { - if (aep_app_conn_table[count].conn_state == Connected) { - aep_app_conn_table[count].conn_state = InUse; - *phConnection = aep_app_conn_table[count].conn_hndl; - goto end; - } - } - /* - * If no connections available, we're going to have to try to open a new - * one - */ - for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { - if (aep_app_conn_table[count].conn_state == NotConnected) { - /* - * Open a connection - */ - rv = p_AEP_OpenConnection(phConnection); - - if (rv != AEP_R_OK) { - AEPHKerr(AEPHK_F_AEP_GET_CONNECTION, AEPHK_R_UNIT_FAILURE); - goto end; - } - - aep_app_conn_table[count].conn_state = InUse; - aep_app_conn_table[count].conn_hndl = *phConnection; - goto end; - } - } - rv = AEP_R_GENERAL_ERROR; - end: - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return rv; -} - -static AEP_RV aep_return_connection(AEP_CONNECTION_HNDL hConnection) -{ - int count; - - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - - /* - * Find the connection item that matches this connection handle - */ - for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { - if (aep_app_conn_table[count].conn_hndl == hConnection) { - aep_app_conn_table[count].conn_state = Connected; - break; - } - } - - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - - return AEP_R_OK; -} - -static AEP_RV aep_close_connection(AEP_CONNECTION_HNDL hConnection) -{ - int count; - AEP_RV rv = AEP_R_OK; - - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - - /* - * Find the connection item that matches this connection handle - */ - for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { - if (aep_app_conn_table[count].conn_hndl == hConnection) { - rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl); - if (rv != AEP_R_OK) - goto end; - aep_app_conn_table[count].conn_state = NotConnected; - aep_app_conn_table[count].conn_hndl = 0; - break; - } - } - - end: - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return rv; -} - -static AEP_RV aep_close_all_connections(int use_engine_lock, int *in_use) -{ - int count; - AEP_RV rv = AEP_R_OK; - - *in_use = 0; - if (use_engine_lock) - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - for (count = 0; count < MAX_PROCESS_CONNECTIONS; count++) { - switch (aep_app_conn_table[count].conn_state) { - case Connected: - rv = p_AEP_CloseConnection(aep_app_conn_table[count].conn_hndl); - if (rv != AEP_R_OK) - goto end; - aep_app_conn_table[count].conn_state = NotConnected; - aep_app_conn_table[count].conn_hndl = 0; - break; - case InUse: - (*in_use)++; - break; - case NotConnected: - break; - } - } - end: - if (use_engine_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return rv; -} - -/* - * BigNum call back functions, used to convert OpenSSL bignums into AEP - * bignums. Note only 32bit Openssl build support - */ - -static AEP_RV GetBigNumSize(AEP_VOID_PTR ArbBigNum, AEP_U32 *BigNumSize) -{ - BIGNUM *bn; - - /* - * Cast the ArbBigNum pointer to our BIGNUM struct - */ - bn = (BIGNUM *)ArbBigNum; - -# ifdef SIXTY_FOUR_BIT_LONG - *BigNumSize = bn->top << 3; -# else - /* - * Size of the bignum in bytes is equal to the bn->top (no of 32 bit - * words) multiplies by 4 - */ - *BigNumSize = bn->top << 2; -# endif - - return AEP_R_OK; -} - -static AEP_RV MakeAEPBigNum(AEP_VOID_PTR ArbBigNum, AEP_U32 BigNumSize, - unsigned char *AEP_BigNum) -{ - BIGNUM *bn; - -# ifndef SIXTY_FOUR_BIT_LONG - unsigned char *buf; - int i; -# endif - - /* - * Cast the ArbBigNum pointer to our BIGNUM struct - */ - bn = (BIGNUM *)ArbBigNum; - -# ifdef SIXTY_FOUR_BIT_LONG - memcpy(AEP_BigNum, bn->d, BigNumSize); -# else - /* - * Must copy data into a (monotone) least significant byte first format - * performing endian conversion if necessary - */ - for (i = 0; i < bn->top; i++) { - buf = (unsigned char *)&bn->d[i]; - - *((AEP_U32 *)AEP_BigNum) = (AEP_U32) - ((unsigned)buf[1] << 8 | buf[0]) | - ((unsigned)buf[3] << 8 | buf[2]) << 16; - - AEP_BigNum += 4; - } -# endif - - return AEP_R_OK; -} - -/* - * Turn an AEP Big Num back to a user big num - */ -static AEP_RV ConvertAEPBigNum(void *ArbBigNum, AEP_U32 BigNumSize, - unsigned char *AEP_BigNum) -{ - BIGNUM *bn; -# ifndef SIXTY_FOUR_BIT_LONG - int i; -# endif - - bn = (BIGNUM *)ArbBigNum; - - /* - * Expand the result bn so that it can hold our big num. Size is in bits - */ - if (bn_expand(bn, (int)(BigNumSize << 3)) == NULL) - return AEP_R_HOST_MEMORY; - -# ifdef SIXTY_FOUR_BIT_LONG - bn->top = BigNumSize >> 3; - - if ((BigNumSize & 7) != 0) - bn->top++; - - memset(bn->d, 0, bn->top << 3); - - memcpy(bn->d, AEP_BigNum, BigNumSize); -# else - bn->top = BigNumSize >> 2; - - for (i = 0; i < bn->top; i++) { - bn->d[i] = (AEP_U32) - ((unsigned)AEP_BigNum[3] << 8 | AEP_BigNum[2]) << 16 | - ((unsigned)AEP_BigNum[1] << 8 | AEP_BigNum[0]); - AEP_BigNum += 4; - } -# endif - - return AEP_R_OK; -} - -# endif /* !OPENSSL_NO_HW_AEP */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_aep_err.c b/Sources/COpenSSL/e_aep_err.c deleted file mode 100644 index 9023f043..00000000 --- a/Sources/COpenSSL/e_aep_err.c +++ /dev/null @@ -1,159 +0,0 @@ -/* e_aep_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_aep_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA AEPHK_str_functs[] = { - {ERR_FUNC(AEPHK_F_AEP_CTRL), "AEP_CTRL"}, - {ERR_FUNC(AEPHK_F_AEP_FINISH), "AEP_FINISH"}, - {ERR_FUNC(AEPHK_F_AEP_GET_CONNECTION), "AEP_GET_CONNECTION"}, - {ERR_FUNC(AEPHK_F_AEP_INIT), "AEP_INIT"}, - {ERR_FUNC(AEPHK_F_AEP_MOD_EXP), "AEP_MOD_EXP"}, - {ERR_FUNC(AEPHK_F_AEP_MOD_EXP_CRT), "AEP_MOD_EXP_CRT"}, - {ERR_FUNC(AEPHK_F_AEP_RAND), "AEP_RAND"}, - {ERR_FUNC(AEPHK_F_AEP_RSA_MOD_EXP), "AEP_RSA_MOD_EXP"}, - {0, NULL} -}; - -static ERR_STRING_DATA AEPHK_str_reasons[] = { - {ERR_REASON(AEPHK_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(AEPHK_R_CLOSE_HANDLES_FAILED), "close handles failed"}, - {ERR_REASON(AEPHK_R_CONNECTIONS_IN_USE), "connections in use"}, - {ERR_REASON(AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(AEPHK_R_FINALIZE_FAILED), "finalize failed"}, - {ERR_REASON(AEPHK_R_GET_HANDLE_FAILED), "get handle failed"}, - {ERR_REASON(AEPHK_R_GET_RANDOM_FAILED), "get random failed"}, - {ERR_REASON(AEPHK_R_INIT_FAILURE), "init failure"}, - {ERR_REASON(AEPHK_R_MISSING_KEY_COMPONENTS), "missing key components"}, - {ERR_REASON(AEPHK_R_MOD_EXP_CRT_FAILED), "mod exp crt failed"}, - {ERR_REASON(AEPHK_R_MOD_EXP_FAILED), "mod exp failed"}, - {ERR_REASON(AEPHK_R_NOT_LOADED), "not loaded"}, - {ERR_REASON(AEPHK_R_OK), "ok"}, - {ERR_REASON(AEPHK_R_RETURN_CONNECTION_FAILED), - "return connection failed"}, - {ERR_REASON(AEPHK_R_SETBNCALLBACK_FAILURE), "setbncallback failure"}, - {ERR_REASON(AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL), - "size too large or too small"}, - {ERR_REASON(AEPHK_R_UNIT_FAILURE), "unit failure"}, - {0, NULL} -}; - -#endif - -#ifdef AEPHK_LIB_NAME -static ERR_STRING_DATA AEPHK_lib_name[] = { - {0, AEPHK_LIB_NAME}, - {0, NULL} -}; -#endif - -static int AEPHK_lib_error_code = 0; -static int AEPHK_error_init = 1; - -static void ERR_load_AEPHK_strings(void) -{ - if (AEPHK_lib_error_code == 0) - AEPHK_lib_error_code = ERR_get_next_error_library(); - - if (AEPHK_error_init) { - AEPHK_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(AEPHK_lib_error_code, AEPHK_str_functs); - ERR_load_strings(AEPHK_lib_error_code, AEPHK_str_reasons); -#endif - -#ifdef AEPHK_LIB_NAME - AEPHK_lib_name->error = ERR_PACK(AEPHK_lib_error_code, 0, 0); - ERR_load_strings(0, AEPHK_lib_name); -#endif - } -} - -static void ERR_unload_AEPHK_strings(void) -{ - if (AEPHK_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(AEPHK_lib_error_code, AEPHK_str_functs); - ERR_unload_strings(AEPHK_lib_error_code, AEPHK_str_reasons); -#endif - -#ifdef AEPHK_LIB_NAME - ERR_unload_strings(0, AEPHK_lib_name); -#endif - AEPHK_error_init = 1; - } -} - -static void ERR_AEPHK_error(int function, int reason, char *file, int line) -{ - if (AEPHK_lib_error_code == 0) - AEPHK_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(AEPHK_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_aep_err.h b/Sources/COpenSSL/e_aep_err.h deleted file mode 100644 index 2ed01147..00000000 --- a/Sources/COpenSSL/e_aep_err.h +++ /dev/null @@ -1,106 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_AEPHK_ERR_H -# define HEADER_AEPHK_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_AEPHK_strings(void); -static void ERR_unload_AEPHK_strings(void); -static void ERR_AEPHK_error(int function, int reason, char *file, int line); -# define AEPHKerr(f,r) ERR_AEPHK_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the AEPHK functions. */ - -/* Function codes. */ -# define AEPHK_F_AEP_CTRL 100 -# define AEPHK_F_AEP_FINISH 101 -# define AEPHK_F_AEP_GET_CONNECTION 102 -# define AEPHK_F_AEP_INIT 103 -# define AEPHK_F_AEP_MOD_EXP 104 -# define AEPHK_F_AEP_MOD_EXP_CRT 105 -# define AEPHK_F_AEP_RAND 106 -# define AEPHK_F_AEP_RSA_MOD_EXP 107 - -/* Reason codes. */ -# define AEPHK_R_ALREADY_LOADED 100 -# define AEPHK_R_CLOSE_HANDLES_FAILED 101 -# define AEPHK_R_CONNECTIONS_IN_USE 102 -# define AEPHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 -# define AEPHK_R_FINALIZE_FAILED 104 -# define AEPHK_R_GET_HANDLE_FAILED 105 -# define AEPHK_R_GET_RANDOM_FAILED 106 -# define AEPHK_R_INIT_FAILURE 107 -# define AEPHK_R_MISSING_KEY_COMPONENTS 108 -# define AEPHK_R_MOD_EXP_CRT_FAILED 109 -# define AEPHK_R_MOD_EXP_FAILED 110 -# define AEPHK_R_NOT_LOADED 111 -# define AEPHK_R_OK 112 -# define AEPHK_R_RETURN_CONNECTION_FAILED 113 -# define AEPHK_R_SETBNCALLBACK_FAILURE 114 -# define AEPHK_R_SIZE_TOO_LARGE_OR_TOO_SMALL 116 -# define AEPHK_R_UNIT_FAILURE 115 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_aes.c b/Sources/COpenSSL/e_aes.c deleted file mode 100644 index 5a55b18d..00000000 --- a/Sources/COpenSSL/e_aes.c +++ /dev/null @@ -1,2034 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ==================================================================== - * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "opensslconf.h" -#ifndef OPENSSL_NO_AES -#include "crypto.h" -# include "evp.h" -# include "err.h" -# include -# include -# include "aes.h" -# include "evp_locl.h" -# include "modes_lcl.h" -# include "rand.h" - -# undef EVP_CIPH_FLAG_FIPS -# define EVP_CIPH_FLAG_FIPS 0 - -typedef struct { - union { - double align; - AES_KEY ks; - } ks; - block128_f block; - union { - cbc128_f cbc; - ctr128_f ctr; - } stream; -} EVP_AES_KEY; - -typedef struct { - union { - double align; - AES_KEY ks; - } ks; /* AES key schedule to use */ - int key_set; /* Set if key initialised */ - int iv_set; /* Set if an iv is set */ - GCM128_CONTEXT gcm; - unsigned char *iv; /* Temporary IV store */ - int ivlen; /* IV length */ - int taglen; - int iv_gen; /* It is OK to generate IVs */ - int tls_aad_len; /* TLS AAD length */ - ctr128_f ctr; -} EVP_AES_GCM_CTX; - -typedef struct { - union { - double align; - AES_KEY ks; - } ks1, ks2; /* AES key schedules to use */ - XTS128_CONTEXT xts; - void (*stream) (const unsigned char *in, - unsigned char *out, size_t length, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); -} EVP_AES_XTS_CTX; - -typedef struct { - union { - double align; - AES_KEY ks; - } ks; /* AES key schedule to use */ - int key_set; /* Set if key initialised */ - int iv_set; /* Set if an iv is set */ - int tag_set; /* Set if tag is valid */ - int len_set; /* Set if message length set */ - int L, M; /* L and M parameters from RFC3610 */ - CCM128_CONTEXT ccm; - ccm128_f str; -} EVP_AES_CCM_CTX; - -# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) - -# ifdef VPAES_ASM -int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); -int vpaes_set_decrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); - -void vpaes_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void vpaes_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); - -void vpaes_cbc_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key, unsigned char *ivec, int enc); -# endif -# ifdef BSAES_ASM -void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char ivec[16], int enc); -void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - const unsigned char ivec[16]); -void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, - size_t len, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char iv[16]); -# endif -# ifdef AES_CTR_ASM -void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - const unsigned char ivec[AES_BLOCK_SIZE]); -# endif -# ifdef AES_XTS_ASM -void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); -void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); -# endif - -# if defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) -# include "ppc_arch.h" -# ifdef VPAES_ASM -# define VPAES_CAPABLE (OPENSSL_ppccap_P & PPC_ALTIVEC) -# endif -# define HWAES_CAPABLE (OPENSSL_ppccap_P & PPC_CRYPTO207) -# define HWAES_set_encrypt_key aes_p8_set_encrypt_key -# define HWAES_set_decrypt_key aes_p8_set_decrypt_key -# define HWAES_encrypt aes_p8_encrypt -# define HWAES_decrypt aes_p8_decrypt -# define HWAES_cbc_encrypt aes_p8_cbc_encrypt -# define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks -# endif - -# if defined(AES_ASM) && !defined(I386_ONLY) && ( \ - ((defined(__i386) || defined(__i386__) || \ - defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) || \ - defined(__INTEL__) ) - -extern unsigned int OPENSSL_ia32cap_P[]; - -# ifdef VPAES_ASM -# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) -# endif -# ifdef BSAES_ASM -# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) -# endif -/* - * AES-NI section - */ -# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) - -int aesni_set_encrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); -int aesni_set_decrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); - -void aesni_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void aesni_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); - -void aesni_ecb_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, const AES_KEY *key, int enc); -void aesni_cbc_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key, unsigned char *ivec, int enc); - -void aesni_ctr32_encrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, const unsigned char *ivec); - -void aesni_xts_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); - -void aesni_xts_decrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key1, const AES_KEY *key2, - const unsigned char iv[16]); - -void aesni_ccm64_encrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, - const unsigned char ivec[16], - unsigned char cmac[16]); - -void aesni_ccm64_decrypt_blocks(const unsigned char *in, - unsigned char *out, - size_t blocks, - const void *key, - const unsigned char ivec[16], - unsigned char cmac[16]); - -# if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) -size_t aesni_gcm_encrypt(const unsigned char *in, - unsigned char *out, - size_t len, - const void *key, unsigned char ivec[16], u64 *Xi); -# define AES_gcm_encrypt aesni_gcm_encrypt -size_t aesni_gcm_decrypt(const unsigned char *in, - unsigned char *out, - size_t len, - const void *key, unsigned char ivec[16], u64 *Xi); -# define AES_gcm_decrypt aesni_gcm_decrypt -void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *in, - size_t len); -# define AES_GCM_ASM(gctx) (gctx->ctr==aesni_ctr32_encrypt_blocks && \ - gctx->gcm.ghash==gcm_ghash_avx) -# define AES_GCM_ASM2(gctx) (gctx->gcm.block==(block128_f)aesni_encrypt && \ - gctx->gcm.ghash==gcm_ghash_avx) -# undef AES_GCM_ASM2 /* minor size optimization */ -# endif - -static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - int ret, mode; - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - mode = ctx->cipher->flags & EVP_CIPH_MODE; - if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) - && !enc) { - ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data); - dat->block = (block128_f) aesni_decrypt; - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) aesni_cbc_encrypt : NULL; - } else { - ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data); - dat->block = (block128_f) aesni_encrypt; - if (mode == EVP_CIPH_CBC_MODE) - dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt; - else if (mode == EVP_CIPH_CTR_MODE) - dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; - else - dat->stream.cbc = NULL; - } - - if (ret < 0) { - EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); - return 0; - } - - return 1; -} - -static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, ctx->encrypt); - - return 1; -} - -static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - size_t bl = ctx->cipher->block_size; - - if (len < bl) - return 1; - - aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt); - - return 1; -} - -# define aesni_ofb_cipher aes_ofb_cipher -static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aesni_cfb_cipher aes_cfb_cipher -static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aesni_cfb8_cipher aes_cfb8_cipher -static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aesni_cfb1_cipher aes_cfb1_cipher -static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aesni_ctr_cipher aes_ctr_cipher -static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_GCM_CTX *gctx = ctx->cipher_data; - if (!iv && !key) - return 1; - if (key) { - aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); - CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt); - gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; - /* - * If we have an iv can set it directly, otherwise use saved IV. - */ - if (iv == NULL && gctx->iv_set) - iv = gctx->iv; - if (iv) { - CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); - gctx->iv_set = 1; - } - gctx->key_set = 1; - } else { - /* If key set use IV, otherwise copy */ - if (gctx->key_set) - CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); - else - memcpy(gctx->iv, iv, gctx->ivlen); - gctx->iv_set = 1; - gctx->iv_gen = 0; - } - return 1; -} - -# define aesni_gcm_cipher aes_gcm_cipher -static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_XTS_CTX *xctx = ctx->cipher_data; - if (!iv && !key) - return 1; - - if (key) { - /* key_len is two AES keys */ - if (enc) { - aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) aesni_encrypt; - xctx->stream = aesni_xts_encrypt; - } else { - aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) aesni_decrypt; - xctx->stream = aesni_xts_decrypt; - } - - aesni_set_encrypt_key(key + ctx->key_len / 2, - ctx->key_len * 4, &xctx->ks2.ks); - xctx->xts.block2 = (block128_f) aesni_encrypt; - - xctx->xts.key1 = &xctx->ks1; - } - - if (iv) { - xctx->xts.key2 = &xctx->ks2; - memcpy(ctx->iv, iv, 16); - } - - return 1; -} - -# define aesni_xts_cipher aes_xts_cipher -static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_CCM_CTX *cctx = ctx->cipher_data; - if (!iv && !key) - return 1; - if (key) { - aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks); - CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, - &cctx->ks, (block128_f) aesni_encrypt); - cctx->str = enc ? (ccm128_f) aesni_ccm64_encrypt_blocks : - (ccm128_f) aesni_ccm64_decrypt_blocks; - cctx->key_set = 1; - } - if (iv) { - memcpy(ctx->iv, iv, 15 - cctx->L); - cctx->iv_set = 1; - } - return 1; -} - -# define aesni_ccm_cipher aes_ccm_cipher -static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ -static const EVP_CIPHER aesni_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aesni_init_key, \ - aesni_##mode##_cipher, \ - NULL, \ - sizeof(EVP_AES_KEY), \ - NULL,NULL,NULL,NULL }; \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize, \ - keylen/8,ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aes_init_key, \ - aes_##mode##_cipher, \ - NULL, \ - sizeof(EVP_AES_KEY), \ - NULL,NULL,NULL,NULL }; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } - -# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ -static const EVP_CIPHER aesni_##keylen##_##mode = { \ - nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aesni_##mode##_init_key, \ - aesni_##mode##_cipher, \ - aes_##mode##_cleanup, \ - sizeof(EVP_AES_##MODE##_CTX), \ - NULL,NULL,aes_##mode##_ctrl,NULL }; \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aes_##mode##_init_key, \ - aes_##mode##_cipher, \ - aes_##mode##_cleanup, \ - sizeof(EVP_AES_##MODE##_CTX), \ - NULL,NULL,aes_##mode##_ctrl,NULL }; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } - -# elif defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) - -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; - -# define SPARC_AES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_AES) - -void aes_t4_set_encrypt_key(const unsigned char *key, int bits, AES_KEY *ks); -void aes_t4_set_decrypt_key(const unsigned char *key, int bits, AES_KEY *ks); -void aes_t4_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void aes_t4_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -/* - * Key-length specific subroutines were chosen for following reason. - * Each SPARC T4 core can execute up to 8 threads which share core's - * resources. Loading as much key material to registers allows to - * minimize references to shared memory interface, as well as amount - * of instructions in inner loops [much needed on T4]. But then having - * non-key-length specific routines would require conditional branches - * either in inner loops or on subroutines' entries. Former is hardly - * acceptable, while latter means code size increase to size occupied - * by multiple key-length specfic subroutines, so why fight? - */ -void aes128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes192_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes192_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - unsigned char *ivec); -void aes128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes192_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key, - unsigned char *ivec); -void aes128_t4_xts_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes128_t4_xts_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes256_t4_xts_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); -void aes256_t4_xts_decrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const AES_KEY *key1, - const AES_KEY *key2, const unsigned char *ivec); - -static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - int ret, mode, bits; - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - mode = ctx->cipher->flags & EVP_CIPH_MODE; - bits = ctx->key_len * 8; - if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) - && !enc) { - ret = 0; - aes_t4_set_decrypt_key(key, bits, ctx->cipher_data); - dat->block = (block128_f) aes_t4_decrypt; - switch (bits) { - case 128: - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) aes128_t4_cbc_decrypt : NULL; - break; - case 192: - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) aes192_t4_cbc_decrypt : NULL; - break; - case 256: - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) aes256_t4_cbc_decrypt : NULL; - break; - default: - ret = -1; - } - } else { - ret = 0; - aes_t4_set_encrypt_key(key, bits, ctx->cipher_data); - dat->block = (block128_f) aes_t4_encrypt; - switch (bits) { - case 128: - if (mode == EVP_CIPH_CBC_MODE) - dat->stream.cbc = (cbc128_f) aes128_t4_cbc_encrypt; - else if (mode == EVP_CIPH_CTR_MODE) - dat->stream.ctr = (ctr128_f) aes128_t4_ctr32_encrypt; - else - dat->stream.cbc = NULL; - break; - case 192: - if (mode == EVP_CIPH_CBC_MODE) - dat->stream.cbc = (cbc128_f) aes192_t4_cbc_encrypt; - else if (mode == EVP_CIPH_CTR_MODE) - dat->stream.ctr = (ctr128_f) aes192_t4_ctr32_encrypt; - else - dat->stream.cbc = NULL; - break; - case 256: - if (mode == EVP_CIPH_CBC_MODE) - dat->stream.cbc = (cbc128_f) aes256_t4_cbc_encrypt; - else if (mode == EVP_CIPH_CTR_MODE) - dat->stream.ctr = (ctr128_f) aes256_t4_ctr32_encrypt; - else - dat->stream.cbc = NULL; - break; - default: - ret = -1; - } - } - - if (ret < 0) { - EVPerr(EVP_F_AES_T4_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); - return 0; - } - - return 1; -} - -# define aes_t4_cbc_cipher aes_cbc_cipher -static int aes_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aes_t4_ecb_cipher aes_ecb_cipher -static int aes_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aes_t4_ofb_cipher aes_ofb_cipher -static int aes_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aes_t4_cfb_cipher aes_cfb_cipher -static int aes_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aes_t4_cfb8_cipher aes_cfb8_cipher -static int aes_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aes_t4_cfb1_cipher aes_cfb1_cipher -static int aes_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define aes_t4_ctr_cipher aes_ctr_cipher -static int aes_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -static int aes_t4_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_GCM_CTX *gctx = ctx->cipher_data; - if (!iv && !key) - return 1; - if (key) { - int bits = ctx->key_len * 8; - aes_t4_set_encrypt_key(key, bits, &gctx->ks.ks); - CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, - (block128_f) aes_t4_encrypt); - switch (bits) { - case 128: - gctx->ctr = (ctr128_f) aes128_t4_ctr32_encrypt; - break; - case 192: - gctx->ctr = (ctr128_f) aes192_t4_ctr32_encrypt; - break; - case 256: - gctx->ctr = (ctr128_f) aes256_t4_ctr32_encrypt; - break; - default: - return 0; - } - /* - * If we have an iv can set it directly, otherwise use saved IV. - */ - if (iv == NULL && gctx->iv_set) - iv = gctx->iv; - if (iv) { - CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); - gctx->iv_set = 1; - } - gctx->key_set = 1; - } else { - /* If key set use IV, otherwise copy */ - if (gctx->key_set) - CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); - else - memcpy(gctx->iv, iv, gctx->ivlen); - gctx->iv_set = 1; - gctx->iv_gen = 0; - } - return 1; -} - -# define aes_t4_gcm_cipher aes_gcm_cipher -static int aes_t4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -static int aes_t4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_XTS_CTX *xctx = ctx->cipher_data; - if (!iv && !key) - return 1; - - if (key) { - int bits = ctx->key_len * 4; - xctx->stream = NULL; - /* key_len is two AES keys */ - if (enc) { - aes_t4_set_encrypt_key(key, bits, &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) aes_t4_encrypt; - switch (bits) { - case 128: - xctx->stream = aes128_t4_xts_encrypt; - break; -# if 0 /* not yet */ - case 192: - xctx->stream = aes192_t4_xts_encrypt; - break; -# endif - case 256: - xctx->stream = aes256_t4_xts_encrypt; - break; - default: - return 0; - } - } else { - aes_t4_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) aes_t4_decrypt; - switch (bits) { - case 128: - xctx->stream = aes128_t4_xts_decrypt; - break; -# if 0 /* not yet */ - case 192: - xctx->stream = aes192_t4_xts_decrypt; - break; -# endif - case 256: - xctx->stream = aes256_t4_xts_decrypt; - break; - default: - return 0; - } - } - - aes_t4_set_encrypt_key(key + ctx->key_len / 2, - ctx->key_len * 4, &xctx->ks2.ks); - xctx->xts.block2 = (block128_f) aes_t4_encrypt; - - xctx->xts.key1 = &xctx->ks1; - } - - if (iv) { - xctx->xts.key2 = &xctx->ks2; - memcpy(ctx->iv, iv, 16); - } - - return 1; -} - -# define aes_t4_xts_cipher aes_xts_cipher -static int aes_t4_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -static int aes_t4_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_CCM_CTX *cctx = ctx->cipher_data; - if (!iv && !key) - return 1; - if (key) { - int bits = ctx->key_len * 8; - aes_t4_set_encrypt_key(key, bits, &cctx->ks.ks); - CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, - &cctx->ks, (block128_f) aes_t4_encrypt); -# if 0 /* not yet */ - switch (bits) { - case 128: - cctx->str = enc ? (ccm128_f) aes128_t4_ccm64_encrypt : - (ccm128_f) ae128_t4_ccm64_decrypt; - break; - case 192: - cctx->str = enc ? (ccm128_f) aes192_t4_ccm64_encrypt : - (ccm128_f) ae192_t4_ccm64_decrypt; - break; - case 256: - cctx->str = enc ? (ccm128_f) aes256_t4_ccm64_encrypt : - (ccm128_f) ae256_t4_ccm64_decrypt; - break; - default: - return 0; - } -# else - cctx->str = NULL; -# endif - cctx->key_set = 1; - } - if (iv) { - memcpy(ctx->iv, iv, 15 - cctx->L); - cctx->iv_set = 1; - } - return 1; -} - -# define aes_t4_ccm_cipher aes_ccm_cipher -static int aes_t4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ -static const EVP_CIPHER aes_t4_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aes_t4_init_key, \ - aes_t4_##mode##_cipher, \ - NULL, \ - sizeof(EVP_AES_KEY), \ - NULL,NULL,NULL,NULL }; \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize, \ - keylen/8,ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aes_init_key, \ - aes_##mode##_cipher, \ - NULL, \ - sizeof(EVP_AES_KEY), \ - NULL,NULL,NULL,NULL }; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; } - -# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ -static const EVP_CIPHER aes_t4_##keylen##_##mode = { \ - nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aes_t4_##mode##_init_key, \ - aes_t4_##mode##_cipher, \ - aes_##mode##_cleanup, \ - sizeof(EVP_AES_##MODE##_CTX), \ - NULL,NULL,aes_##mode##_ctrl,NULL }; \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aes_##mode##_init_key, \ - aes_##mode##_cipher, \ - aes_##mode##_cleanup, \ - sizeof(EVP_AES_##MODE##_CTX), \ - NULL,NULL,aes_##mode##_ctrl,NULL }; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; } - -# else - -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aes_init_key, \ - aes_##mode##_cipher, \ - NULL, \ - sizeof(EVP_AES_KEY), \ - NULL,NULL,NULL,NULL }; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ return &aes_##keylen##_##mode; } - -# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ -static const EVP_CIPHER aes_##keylen##_##mode = { \ - nid##_##keylen##_##mode,blocksize, \ - (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - aes_##mode##_init_key, \ - aes_##mode##_cipher, \ - aes_##mode##_cleanup, \ - sizeof(EVP_AES_##MODE##_CTX), \ - NULL,NULL,aes_##mode##_ctrl,NULL }; \ -const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ -{ return &aes_##keylen##_##mode; } -# endif - -# if defined(OPENSSL_CPUID_OBJ) && (defined(__arm__) || defined(__arm) || defined(__aarch64__)) -# include "arm_arch.h" -# if __ARM_MAX_ARCH__>=7 -# if defined(BSAES_ASM) -# define BSAES_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) -# endif -# define HWAES_CAPABLE (OPENSSL_armcap_P & ARMV8_AES) -# define HWAES_set_encrypt_key aes_v8_set_encrypt_key -# define HWAES_set_decrypt_key aes_v8_set_decrypt_key -# define HWAES_encrypt aes_v8_encrypt -# define HWAES_decrypt aes_v8_decrypt -# define HWAES_cbc_encrypt aes_v8_cbc_encrypt -# define HWAES_ctr32_encrypt_blocks aes_v8_ctr32_encrypt_blocks -# endif -# endif - -# if defined(HWAES_CAPABLE) -int HWAES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); -int HWAES_set_decrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); -void HWAES_encrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void HWAES_decrypt(const unsigned char *in, unsigned char *out, - const AES_KEY *key); -void HWAES_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const AES_KEY *key, - unsigned char *ivec, const int enc); -void HWAES_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, - size_t len, const AES_KEY *key, - const unsigned char ivec[16]); -# endif - -# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ - BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ - BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags) - -static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - int ret, mode; - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - mode = ctx->cipher->flags & EVP_CIPH_MODE; - if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) - && !enc) -# ifdef HWAES_CAPABLE - if (HWAES_CAPABLE) { - ret = HWAES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); - dat->block = (block128_f) HWAES_decrypt; - dat->stream.cbc = NULL; -# ifdef HWAES_cbc_encrypt - if (mode == EVP_CIPH_CBC_MODE) - dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt; -# endif - } else -# endif -# ifdef BSAES_CAPABLE - if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) { - ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); - dat->block = (block128_f) AES_decrypt; - dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt; - } else -# endif -# ifdef VPAES_CAPABLE - if (VPAES_CAPABLE) { - ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); - dat->block = (block128_f) vpaes_decrypt; - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) vpaes_cbc_encrypt : NULL; - } else -# endif - { - ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); - dat->block = (block128_f) AES_decrypt; - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) AES_cbc_encrypt : NULL; - } else -# ifdef HWAES_CAPABLE - if (HWAES_CAPABLE) { - ret = HWAES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); - dat->block = (block128_f) HWAES_encrypt; - dat->stream.cbc = NULL; -# ifdef HWAES_cbc_encrypt - if (mode == EVP_CIPH_CBC_MODE) - dat->stream.cbc = (cbc128_f) HWAES_cbc_encrypt; - else -# endif -# ifdef HWAES_ctr32_encrypt_blocks - if (mode == EVP_CIPH_CTR_MODE) - dat->stream.ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks; - else -# endif - (void)0; /* terminate potentially open 'else' */ - } else -# endif -# ifdef BSAES_CAPABLE - if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) { - ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); - dat->block = (block128_f) AES_encrypt; - dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; - } else -# endif -# ifdef VPAES_CAPABLE - if (VPAES_CAPABLE) { - ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); - dat->block = (block128_f) vpaes_encrypt; - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) vpaes_cbc_encrypt : NULL; - } else -# endif - { - ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); - dat->block = (block128_f) AES_encrypt; - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) AES_cbc_encrypt : NULL; -# ifdef AES_CTR_ASM - if (mode == EVP_CIPH_CTR_MODE) - dat->stream.ctr = (ctr128_f) AES_ctr32_encrypt; -# endif - } - - if (ret < 0) { - EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); - return 0; - } - - return 1; -} - -static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - if (dat->stream.cbc) - (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt); - else if (ctx->encrypt) - CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); - else - CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block); - - return 1; -} - -static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - size_t bl = ctx->cipher->block_size; - size_t i; - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - if (len < bl) - return 1; - - for (i = 0, len -= bl; i <= len; i += bl) - (*dat->block) (in + i, out + i, &dat->ks); - - return 1; -} - -static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, - ctx->iv, &ctx->num, dat->block); - return 1; -} - -static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - return 1; -} - -static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - return 1; -} - -static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) { - CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - return 1; - } - - while (len >= MAXBITCHUNK) { - CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - len -= MAXBITCHUNK; - out += MAXBITCHUNK; - in += MAXBITCHUNK; - } - if (len) - CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - - return 1; -} - -static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - unsigned int num = ctx->num; - EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; - - if (dat->stream.ctr) - CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, - ctx->iv, ctx->buf, &num, dat->stream.ctr); - else - CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - ctx->iv, ctx->buf, &num, dat->block); - ctx->num = (size_t)num; - return 1; -} - -BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS) - BLOCK_CIPHER_generic_pack(NID_aes, 192, EVP_CIPH_FLAG_FIPS) - BLOCK_CIPHER_generic_pack(NID_aes, 256, EVP_CIPH_FLAG_FIPS) - -static int aes_gcm_cleanup(EVP_CIPHER_CTX *c) -{ - EVP_AES_GCM_CTX *gctx = c->cipher_data; - if (gctx == NULL) - return 0; - OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); - if (gctx->iv != c->iv) - OPENSSL_free(gctx->iv); - return 1; -} - -/* increment counter (64-bit int) by 1 */ -static void ctr64_inc(unsigned char *counter) -{ - int n = 8; - unsigned char c; - - do { - --n; - c = counter[n]; - ++c; - counter[n] = c; - if (c) - return; - } while (n); -} - -static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) -{ - EVP_AES_GCM_CTX *gctx = c->cipher_data; - switch (type) { - case EVP_CTRL_INIT: - gctx->key_set = 0; - gctx->iv_set = 0; - gctx->ivlen = c->cipher->iv_len; - gctx->iv = c->iv; - gctx->taglen = -1; - gctx->iv_gen = 0; - gctx->tls_aad_len = -1; - return 1; - - case EVP_CTRL_GCM_SET_IVLEN: - if (arg <= 0) - return 0; - /* Allocate memory for IV if needed */ - if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { - if (gctx->iv != c->iv) - OPENSSL_free(gctx->iv); - gctx->iv = OPENSSL_malloc(arg); - if (!gctx->iv) - return 0; - } - gctx->ivlen = arg; - return 1; - - case EVP_CTRL_GCM_SET_TAG: - if (arg <= 0 || arg > 16 || c->encrypt) - return 0; - memcpy(c->buf, ptr, arg); - gctx->taglen = arg; - return 1; - - case EVP_CTRL_GCM_GET_TAG: - if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) - return 0; - memcpy(ptr, c->buf, arg); - return 1; - - case EVP_CTRL_GCM_SET_IV_FIXED: - /* Special case: -1 length restores whole IV */ - if (arg == -1) { - memcpy(gctx->iv, ptr, gctx->ivlen); - gctx->iv_gen = 1; - return 1; - } - /* - * Fixed field must be at least 4 bytes and invocation field at least - * 8. - */ - if ((arg < 4) || (gctx->ivlen - arg) < 8) - return 0; - if (arg) - memcpy(gctx->iv, ptr, arg); - if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) - return 0; - gctx->iv_gen = 1; - return 1; - - case EVP_CTRL_GCM_IV_GEN: - if (gctx->iv_gen == 0 || gctx->key_set == 0) - return 0; - CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); - if (arg <= 0 || arg > gctx->ivlen) - arg = gctx->ivlen; - memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); - /* - * Invocation field will be at least 8 bytes in size and so no need - * to check wrap around or increment more than last 8 bytes. - */ - ctr64_inc(gctx->iv + gctx->ivlen - 8); - gctx->iv_set = 1; - return 1; - - case EVP_CTRL_GCM_SET_IV_INV: - if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) - return 0; - memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); - CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); - gctx->iv_set = 1; - return 1; - - case EVP_CTRL_AEAD_TLS1_AAD: - /* Save the AAD for later use */ - if (arg != EVP_AEAD_TLS1_AAD_LEN) - return 0; - memcpy(c->buf, ptr, arg); - gctx->tls_aad_len = arg; - { - unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; - /* Correct length for explicit IV */ - if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN) - return 0; - len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; - /* If decrypting correct for tag too */ - if (!c->encrypt) { - if (len < EVP_GCM_TLS_TAG_LEN) - return 0; - len -= EVP_GCM_TLS_TAG_LEN; - } - c->buf[arg - 2] = len >> 8; - c->buf[arg - 1] = len & 0xff; - } - /* Extra padding: tag appended to record */ - return EVP_GCM_TLS_TAG_LEN; - - case EVP_CTRL_COPY: - { - EVP_CIPHER_CTX *out = ptr; - EVP_AES_GCM_CTX *gctx_out = out->cipher_data; - if (gctx->gcm.key) { - if (gctx->gcm.key != &gctx->ks) - return 0; - gctx_out->gcm.key = &gctx_out->ks; - } - if (gctx->iv == c->iv) - gctx_out->iv = out->iv; - else { - gctx_out->iv = OPENSSL_malloc(gctx->ivlen); - if (!gctx_out->iv) - return 0; - memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); - } - return 1; - } - - default: - return -1; - - } -} - -static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_GCM_CTX *gctx = ctx->cipher_data; - if (!iv && !key) - return 1; - if (key) { - do { -# ifdef HWAES_CAPABLE - if (HWAES_CAPABLE) { - HWAES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); - CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, - (block128_f) HWAES_encrypt); -# ifdef HWAES_ctr32_encrypt_blocks - gctx->ctr = (ctr128_f) HWAES_ctr32_encrypt_blocks; -# else - gctx->ctr = NULL; -# endif - break; - } else -# endif -# ifdef BSAES_CAPABLE - if (BSAES_CAPABLE) { - AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); - CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, - (block128_f) AES_encrypt); - gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; - break; - } else -# endif -# ifdef VPAES_CAPABLE - if (VPAES_CAPABLE) { - vpaes_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); - CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, - (block128_f) vpaes_encrypt); - gctx->ctr = NULL; - break; - } else -# endif - (void)0; /* terminate potentially open 'else' */ - - AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks); - CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, - (block128_f) AES_encrypt); -# ifdef AES_CTR_ASM - gctx->ctr = (ctr128_f) AES_ctr32_encrypt; -# else - gctx->ctr = NULL; -# endif - } while (0); - - /* - * If we have an iv can set it directly, otherwise use saved IV. - */ - if (iv == NULL && gctx->iv_set) - iv = gctx->iv; - if (iv) { - CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); - gctx->iv_set = 1; - } - gctx->key_set = 1; - } else { - /* If key set use IV, otherwise copy */ - if (gctx->key_set) - CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); - else - memcpy(gctx->iv, iv, gctx->ivlen); - gctx->iv_set = 1; - gctx->iv_gen = 0; - } - return 1; -} - -/* - * Handle TLS GCM packet format. This consists of the last portion of the IV - * followed by the payload and finally the tag. On encrypt generate IV, - * encrypt payload and write the tag. On verify retrieve IV, decrypt payload - * and verify tag. - */ - -static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_GCM_CTX *gctx = ctx->cipher_data; - int rv = -1; - /* Encrypt/decrypt must be performed in place */ - if (out != in - || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) - return -1; - /* - * Set IV from start of buffer or generate IV and write to start of - * buffer. - */ - if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? - EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, - EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) - goto err; - /* Use saved AAD */ - if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) - goto err; - /* Fix buffer and length to point to payload */ - in += EVP_GCM_TLS_EXPLICIT_IV_LEN; - out += EVP_GCM_TLS_EXPLICIT_IV_LEN; - len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; - if (ctx->encrypt) { - /* Encrypt payload */ - if (gctx->ctr) { - size_t bulk = 0; -# if defined(AES_GCM_ASM) - if (len >= 32 && AES_GCM_ASM(gctx)) { - if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0)) - return -1; - - bulk = AES_gcm_encrypt(in, out, len, - gctx->gcm.key, - gctx->gcm.Yi.c, gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - } -# endif - if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, - in + bulk, - out + bulk, - len - bulk, gctx->ctr)) - goto err; - } else { - size_t bulk = 0; -# if defined(AES_GCM_ASM2) - if (len >= 32 && AES_GCM_ASM2(gctx)) { - if (CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0)) - return -1; - - bulk = AES_gcm_encrypt(in, out, len, - gctx->gcm.key, - gctx->gcm.Yi.c, gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - } -# endif - if (CRYPTO_gcm128_encrypt(&gctx->gcm, - in + bulk, out + bulk, len - bulk)) - goto err; - } - out += len; - /* Finally write tag */ - CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); - rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; - } else { - /* Decrypt */ - if (gctx->ctr) { - size_t bulk = 0; -# if defined(AES_GCM_ASM) - if (len >= 16 && AES_GCM_ASM(gctx)) { - if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0)) - return -1; - - bulk = AES_gcm_decrypt(in, out, len, - gctx->gcm.key, - gctx->gcm.Yi.c, gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - } -# endif - if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, - in + bulk, - out + bulk, - len - bulk, gctx->ctr)) - goto err; - } else { - size_t bulk = 0; -# if defined(AES_GCM_ASM2) - if (len >= 16 && AES_GCM_ASM2(gctx)) { - if (CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0)) - return -1; - - bulk = AES_gcm_decrypt(in, out, len, - gctx->gcm.key, - gctx->gcm.Yi.c, gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - } -# endif - if (CRYPTO_gcm128_decrypt(&gctx->gcm, - in + bulk, out + bulk, len - bulk)) - goto err; - } - /* Retrieve tag */ - CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); - /* If tag mismatch wipe buffer */ - if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { - OPENSSL_cleanse(out, len); - goto err; - } - rv = len; - } - - err: - gctx->iv_set = 0; - gctx->tls_aad_len = -1; - return rv; -} - -static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_GCM_CTX *gctx = ctx->cipher_data; - /* If not set up, return error */ - if (!gctx->key_set) - return -1; - - if (gctx->tls_aad_len >= 0) - return aes_gcm_tls_cipher(ctx, out, in, len); - - if (!gctx->iv_set) - return -1; - if (in) { - if (out == NULL) { - if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) - return -1; - } else if (ctx->encrypt) { - if (gctx->ctr) { - size_t bulk = 0; -# if defined(AES_GCM_ASM) - if (len >= 32 && AES_GCM_ASM(gctx)) { - size_t res = (16 - gctx->gcm.mres) % 16; - - if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res)) - return -1; - - bulk = AES_gcm_encrypt(in + res, - out + res, len - res, - gctx->gcm.key, gctx->gcm.Yi.c, - gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - bulk += res; - } -# endif - if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, - in + bulk, - out + bulk, - len - bulk, gctx->ctr)) - return -1; - } else { - size_t bulk = 0; -# if defined(AES_GCM_ASM2) - if (len >= 32 && AES_GCM_ASM2(gctx)) { - size_t res = (16 - gctx->gcm.mres) % 16; - - if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, res)) - return -1; - - bulk = AES_gcm_encrypt(in + res, - out + res, len - res, - gctx->gcm.key, gctx->gcm.Yi.c, - gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - bulk += res; - } -# endif - if (CRYPTO_gcm128_encrypt(&gctx->gcm, - in + bulk, out + bulk, len - bulk)) - return -1; - } - } else { - if (gctx->ctr) { - size_t bulk = 0; -# if defined(AES_GCM_ASM) - if (len >= 16 && AES_GCM_ASM(gctx)) { - size_t res = (16 - gctx->gcm.mres) % 16; - - if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res)) - return -1; - - bulk = AES_gcm_decrypt(in + res, - out + res, len - res, - gctx->gcm.key, - gctx->gcm.Yi.c, gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - bulk += res; - } -# endif - if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, - in + bulk, - out + bulk, - len - bulk, gctx->ctr)) - return -1; - } else { - size_t bulk = 0; -# if defined(AES_GCM_ASM2) - if (len >= 16 && AES_GCM_ASM2(gctx)) { - size_t res = (16 - gctx->gcm.mres) % 16; - - if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, res)) - return -1; - - bulk = AES_gcm_decrypt(in + res, - out + res, len - res, - gctx->gcm.key, - gctx->gcm.Yi.c, gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - bulk += res; - } -# endif - if (CRYPTO_gcm128_decrypt(&gctx->gcm, - in + bulk, out + bulk, len - bulk)) - return -1; - } - } - return len; - } else { - if (!ctx->encrypt) { - if (gctx->taglen < 0) - return -1; - if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) - return -1; - gctx->iv_set = 0; - return 0; - } - CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); - gctx->taglen = 16; - /* Don't reuse the IV */ - gctx->iv_set = 0; - return 0; - } - -} - -# define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ - | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ - | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ - | EVP_CIPH_CUSTOM_COPY) - -BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM, - EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | - CUSTOM_FLAGS) - BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM, - EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | - CUSTOM_FLAGS) - BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM, - EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | - CUSTOM_FLAGS) - -static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) -{ - EVP_AES_XTS_CTX *xctx = c->cipher_data; - if (type == EVP_CTRL_COPY) { - EVP_CIPHER_CTX *out = ptr; - EVP_AES_XTS_CTX *xctx_out = out->cipher_data; - if (xctx->xts.key1) { - if (xctx->xts.key1 != &xctx->ks1) - return 0; - xctx_out->xts.key1 = &xctx_out->ks1; - } - if (xctx->xts.key2) { - if (xctx->xts.key2 != &xctx->ks2) - return 0; - xctx_out->xts.key2 = &xctx_out->ks2; - } - return 1; - } else if (type != EVP_CTRL_INIT) - return -1; - /* key1 and key2 are used as an indicator both key and IV are set */ - xctx->xts.key1 = NULL; - xctx->xts.key2 = NULL; - return 1; -} - -static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_XTS_CTX *xctx = ctx->cipher_data; - if (!iv && !key) - return 1; - - if (key) - do { -# ifdef AES_XTS_ASM - xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; -# else - xctx->stream = NULL; -# endif - /* key_len is two AES keys */ -# ifdef HWAES_CAPABLE - if (HWAES_CAPABLE) { - if (enc) { - HWAES_set_encrypt_key(key, ctx->key_len * 4, - &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) HWAES_encrypt; - } else { - HWAES_set_decrypt_key(key, ctx->key_len * 4, - &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) HWAES_decrypt; - } - - HWAES_set_encrypt_key(key + ctx->key_len / 2, - ctx->key_len * 4, &xctx->ks2.ks); - xctx->xts.block2 = (block128_f) HWAES_encrypt; - - xctx->xts.key1 = &xctx->ks1; - break; - } else -# endif -# ifdef BSAES_CAPABLE - if (BSAES_CAPABLE) - xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt; - else -# endif -# ifdef VPAES_CAPABLE - if (VPAES_CAPABLE) { - if (enc) { - vpaes_set_encrypt_key(key, ctx->key_len * 4, - &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) vpaes_encrypt; - } else { - vpaes_set_decrypt_key(key, ctx->key_len * 4, - &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) vpaes_decrypt; - } - - vpaes_set_encrypt_key(key + ctx->key_len / 2, - ctx->key_len * 4, &xctx->ks2.ks); - xctx->xts.block2 = (block128_f) vpaes_encrypt; - - xctx->xts.key1 = &xctx->ks1; - break; - } else -# endif - (void)0; /* terminate potentially open 'else' */ - - if (enc) { - AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) AES_encrypt; - } else { - AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks); - xctx->xts.block1 = (block128_f) AES_decrypt; - } - - AES_set_encrypt_key(key + ctx->key_len / 2, - ctx->key_len * 4, &xctx->ks2.ks); - xctx->xts.block2 = (block128_f) AES_encrypt; - - xctx->xts.key1 = &xctx->ks1; - } while (0); - - if (iv) { - xctx->xts.key2 = &xctx->ks2; - memcpy(ctx->iv, iv, 16); - } - - return 1; -} - -static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_XTS_CTX *xctx = ctx->cipher_data; - if (!xctx->xts.key1 || !xctx->xts.key2) - return 0; - if (!out || !in || len < AES_BLOCK_SIZE) - return 0; - if (xctx->stream) - (*xctx->stream) (in, out, len, - xctx->xts.key1, xctx->xts.key2, ctx->iv); - else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, - ctx->encrypt)) - return 0; - return 1; -} - -# define aes_xts_cleanup NULL - -# define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \ - | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ - | EVP_CIPH_CUSTOM_COPY) - -BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, - EVP_CIPH_FLAG_FIPS | XTS_FLAGS) - BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, - EVP_CIPH_FLAG_FIPS | XTS_FLAGS) - -static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) -{ - EVP_AES_CCM_CTX *cctx = c->cipher_data; - switch (type) { - case EVP_CTRL_INIT: - cctx->key_set = 0; - cctx->iv_set = 0; - cctx->L = 8; - cctx->M = 12; - cctx->tag_set = 0; - cctx->len_set = 0; - return 1; - - case EVP_CTRL_CCM_SET_IVLEN: - arg = 15 - arg; - case EVP_CTRL_CCM_SET_L: - if (arg < 2 || arg > 8) - return 0; - cctx->L = arg; - return 1; - - case EVP_CTRL_CCM_SET_TAG: - if ((arg & 1) || arg < 4 || arg > 16) - return 0; - if (c->encrypt && ptr) - return 0; - if (ptr) { - cctx->tag_set = 1; - memcpy(c->buf, ptr, arg); - } - cctx->M = arg; - return 1; - - case EVP_CTRL_CCM_GET_TAG: - if (!c->encrypt || !cctx->tag_set) - return 0; - if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) - return 0; - cctx->tag_set = 0; - cctx->iv_set = 0; - cctx->len_set = 0; - return 1; - - case EVP_CTRL_COPY: - { - EVP_CIPHER_CTX *out = ptr; - EVP_AES_CCM_CTX *cctx_out = out->cipher_data; - if (cctx->ccm.key) { - if (cctx->ccm.key != &cctx->ks) - return 0; - cctx_out->ccm.key = &cctx_out->ks; - } - return 1; - } - - default: - return -1; - - } -} - -static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_CCM_CTX *cctx = ctx->cipher_data; - if (!iv && !key) - return 1; - if (key) - do { -# ifdef HWAES_CAPABLE - if (HWAES_CAPABLE) { - HWAES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks); - - CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, - &cctx->ks, (block128_f) HWAES_encrypt); - cctx->str = NULL; - cctx->key_set = 1; - break; - } else -# endif -# ifdef VPAES_CAPABLE - if (VPAES_CAPABLE) { - vpaes_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks); - CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, - &cctx->ks, (block128_f) vpaes_encrypt); - cctx->str = NULL; - cctx->key_set = 1; - break; - } -# endif - AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks); - CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, - &cctx->ks, (block128_f) AES_encrypt); - cctx->str = NULL; - cctx->key_set = 1; - } while (0); - if (iv) { - memcpy(ctx->iv, iv, 15 - cctx->L); - cctx->iv_set = 1; - } - return 1; -} - -static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_CCM_CTX *cctx = ctx->cipher_data; - CCM128_CONTEXT *ccm = &cctx->ccm; - /* If not set up, return error */ - if (!cctx->iv_set && !cctx->key_set) - return -1; - if (!ctx->encrypt && !cctx->tag_set) - return -1; - if (!out) { - if (!in) { - if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) - return -1; - cctx->len_set = 1; - return len; - } - /* If have AAD need message length */ - if (!cctx->len_set && len) - return -1; - CRYPTO_ccm128_aad(ccm, in, len); - return len; - } - /* EVP_*Final() doesn't return any data */ - if (!in) - return 0; - /* If not set length yet do it */ - if (!cctx->len_set) { - if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) - return -1; - cctx->len_set = 1; - } - if (ctx->encrypt) { - if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, - cctx->str) : - CRYPTO_ccm128_encrypt(ccm, in, out, len)) - return -1; - cctx->tag_set = 1; - return len; - } else { - int rv = -1; - if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, - cctx->str) : - !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { - unsigned char tag[16]; - if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { - if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M)) - rv = len; - } - } - if (rv == -1) - OPENSSL_cleanse(out, len); - cctx->iv_set = 0; - cctx->tag_set = 0; - cctx->len_set = 0; - return rv; - } - -} - -# define aes_ccm_cleanup NULL - -BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, - EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) - BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, - EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) - BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, - EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) -#endif -typedef struct { - union { - double align; - AES_KEY ks; - } ks; - /* Indicates if IV has been set */ - unsigned char *iv; -} EVP_AES_WRAP_CTX; - -static int aes_wrap_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - EVP_AES_WRAP_CTX *wctx = ctx->cipher_data; - if (!iv && !key) - return 1; - if (key) { - if (ctx->encrypt) - AES_set_encrypt_key(key, ctx->key_len * 8, &wctx->ks.ks); - else - AES_set_decrypt_key(key, ctx->key_len * 8, &wctx->ks.ks); - if (!iv) - wctx->iv = NULL; - } - if (iv) { - memcpy(ctx->iv, iv, 8); - wctx->iv = ctx->iv; - } - return 1; -} - -static int aes_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inlen) -{ - EVP_AES_WRAP_CTX *wctx = ctx->cipher_data; - size_t rv; - if (!in) - return 0; - if (inlen % 8) - return -1; - if (ctx->encrypt && inlen < 8) - return -1; - if (!ctx->encrypt && inlen < 16) - return -1; - if (!out) { - if (ctx->encrypt) - return inlen + 8; - else - return inlen - 8; - } - if (ctx->encrypt) - rv = CRYPTO_128_wrap(&wctx->ks.ks, wctx->iv, out, in, inlen, - (block128_f) AES_encrypt); - else - rv = CRYPTO_128_unwrap(&wctx->ks.ks, wctx->iv, out, in, inlen, - (block128_f) AES_decrypt); - return rv ? (int)rv : -1; -} - -#define WRAP_FLAGS (EVP_CIPH_WRAP_MODE \ - | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ - | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_FLAG_DEFAULT_ASN1) - -static const EVP_CIPHER aes_128_wrap = { - NID_id_aes128_wrap, - 8, 16, 8, WRAP_FLAGS, - aes_wrap_init_key, aes_wrap_cipher, - NULL, - sizeof(EVP_AES_WRAP_CTX), - NULL, NULL, NULL, NULL -}; - -const EVP_CIPHER *EVP_aes_128_wrap(void) -{ - return &aes_128_wrap; -} - -static const EVP_CIPHER aes_192_wrap = { - NID_id_aes192_wrap, - 8, 24, 8, WRAP_FLAGS, - aes_wrap_init_key, aes_wrap_cipher, - NULL, - sizeof(EVP_AES_WRAP_CTX), - NULL, NULL, NULL, NULL -}; - -const EVP_CIPHER *EVP_aes_192_wrap(void) -{ - return &aes_192_wrap; -} - -static const EVP_CIPHER aes_256_wrap = { - NID_id_aes256_wrap, - 8, 32, 8, WRAP_FLAGS, - aes_wrap_init_key, aes_wrap_cipher, - NULL, - sizeof(EVP_AES_WRAP_CTX), - NULL, NULL, NULL, NULL -}; - -const EVP_CIPHER *EVP_aes_256_wrap(void) -{ - return &aes_256_wrap; -} diff --git a/Sources/COpenSSL/e_aes_cbc_hmac_sha1.c b/Sources/COpenSSL/e_aes_cbc_hmac_sha1.c deleted file mode 100644 index 79ba5257..00000000 --- a/Sources/COpenSSL/e_aes_cbc_hmac_sha1.c +++ /dev/null @@ -1,1015 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "opensslconf.h" - -#include -#include - -#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1) - -# include "evp.h" -# include "objects.h" -# include "aes.h" -# include "sha.h" -# include "rand.h" -# include "modes_lcl.h" -# include "constant_time_locl.h" - -# ifndef EVP_CIPH_FLAG_AEAD_CIPHER -# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 -# define EVP_CTRL_AEAD_TLS1_AAD 0x16 -# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 -# endif - -# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1) -# define EVP_CIPH_FLAG_DEFAULT_ASN1 0 -# endif - -# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) -# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 -# endif - -# define TLS1_1_VERSION 0x0302 - -typedef struct { - AES_KEY ks; - SHA_CTX head, tail, md; - size_t payload_length; /* AAD length in decrypt case */ - union { - unsigned int tls_ver; - unsigned char tls_aad[16]; /* 13 used */ - } aux; -} EVP_AES_HMAC_SHA1; - -# define NO_PAYLOAD_LENGTH ((size_t)-1) - -# if defined(AES_ASM) && ( \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) || \ - defined(__INTEL__) ) - -extern unsigned int OPENSSL_ia32cap_P[]; -# define AESNI_CAPABLE (1<<(57-32)) - -int aesni_set_encrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); -int aesni_set_decrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); - -void aesni_cbc_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key, unsigned char *ivec, int enc); - -void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks, - const AES_KEY *key, unsigned char iv[16], - SHA_CTX *ctx, const void *in0); - -void aesni256_cbc_sha1_dec(const void *inp, void *out, size_t blocks, - const AES_KEY *key, unsigned char iv[16], - SHA_CTX *ctx, const void *in0); - -# define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data) - -static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *inkey, - const unsigned char *iv, int enc) -{ - EVP_AES_HMAC_SHA1 *key = data(ctx); - int ret; - - if (enc) - ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks); - else - ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks); - - SHA1_Init(&key->head); /* handy when benchmarking */ - key->tail = key->head; - key->md = key->head; - - key->payload_length = NO_PAYLOAD_LENGTH; - - return ret < 0 ? 0 : 1; -} - -# define STITCHED_CALL -# undef STITCHED_DECRYPT_CALL - -# if !defined(STITCHED_CALL) -# define aes_off 0 -# endif - -void sha1_block_data_order(void *c, const void *p, size_t len); - -static void sha1_update(SHA_CTX *c, const void *data, size_t len) -{ - const unsigned char *ptr = data; - size_t res; - - if ((res = c->num)) { - res = SHA_CBLOCK - res; - if (len < res) - res = len; - SHA1_Update(c, ptr, res); - ptr += res; - len -= res; - } - - res = len % SHA_CBLOCK; - len -= res; - - if (len) { - sha1_block_data_order(c, ptr, len / SHA_CBLOCK); - - ptr += len; - c->Nh += len >> 29; - c->Nl += len <<= 3; - if (c->Nl < (unsigned int)len) - c->Nh++; - } - - if (res) - SHA1_Update(c, ptr, res); -} - -# ifdef SHA1_Update -# undef SHA1_Update -# endif -# define SHA1_Update sha1_update - -# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - -typedef struct { - unsigned int A[8], B[8], C[8], D[8], E[8]; -} SHA1_MB_CTX; -typedef struct { - const unsigned char *ptr; - int blocks; -} HASH_DESC; - -void sha1_multi_block(SHA1_MB_CTX *, const HASH_DESC *, int); - -typedef struct { - const unsigned char *inp; - unsigned char *out; - int blocks; - u64 iv[2]; -} CIPH_DESC; - -void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int); - -static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA1 *key, - unsigned char *out, - const unsigned char *inp, - size_t inp_len, int n4x) -{ /* n4x is 1 or 2 */ - HASH_DESC hash_d[8], edges[8]; - CIPH_DESC ciph_d[8]; - unsigned char storage[sizeof(SHA1_MB_CTX) + 32]; - union { - u64 q[16]; - u32 d[32]; - u8 c[128]; - } blocks[8]; - SHA1_MB_CTX *ctx; - unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed = - 0; - size_t ret = 0; - u8 *IVs; -# if defined(BSWAP8) - u64 seqnum; -# endif - - /* ask for IVs in bulk */ - if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0) - return 0; - - ctx = (SHA1_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); /* align */ - - frag = (unsigned int)inp_len >> (1 + n4x); - last = (unsigned int)inp_len + frag - (frag << (1 + n4x)); - if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) { - frag++; - last -= x4 - 1; - } - - packlen = 5 + 16 + ((frag + 20 + 16) & -16); - - /* populate descriptors with pointers and IVs */ - hash_d[0].ptr = inp; - ciph_d[0].inp = inp; - /* 5+16 is place for header and explicit IV */ - ciph_d[0].out = out + 5 + 16; - memcpy(ciph_d[0].out - 16, IVs, 16); - memcpy(ciph_d[0].iv, IVs, 16); - IVs += 16; - - for (i = 1; i < x4; i++) { - ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag; - ciph_d[i].out = ciph_d[i - 1].out + packlen; - memcpy(ciph_d[i].out - 16, IVs, 16); - memcpy(ciph_d[i].iv, IVs, 16); - IVs += 16; - } - -# if defined(BSWAP8) - memcpy(blocks[0].c, key->md.data, 8); - seqnum = BSWAP8(blocks[0].q[0]); -# endif - for (i = 0; i < x4; i++) { - unsigned int len = (i == (x4 - 1) ? last : frag); -# if !defined(BSWAP8) - unsigned int carry, j; -# endif - - ctx->A[i] = key->md.h0; - ctx->B[i] = key->md.h1; - ctx->C[i] = key->md.h2; - ctx->D[i] = key->md.h3; - ctx->E[i] = key->md.h4; - - /* fix seqnum */ -# if defined(BSWAP8) - blocks[i].q[0] = BSWAP8(seqnum + i); -# else - for (carry = i, j = 8; j--;) { - blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry; - carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1); - } -# endif - blocks[i].c[8] = ((u8 *)key->md.data)[8]; - blocks[i].c[9] = ((u8 *)key->md.data)[9]; - blocks[i].c[10] = ((u8 *)key->md.data)[10]; - /* fix length */ - blocks[i].c[11] = (u8)(len >> 8); - blocks[i].c[12] = (u8)(len); - - memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13); - hash_d[i].ptr += 64 - 13; - hash_d[i].blocks = (len - (64 - 13)) / 64; - - edges[i].ptr = blocks[i].c; - edges[i].blocks = 1; - } - - /* hash 13-byte headers and first 64-13 bytes of inputs */ - sha1_multi_block(ctx, edges, n4x); - /* hash bulk inputs */ -# define MAXCHUNKSIZE 2048 -# if MAXCHUNKSIZE%64 -# error "MAXCHUNKSIZE is not divisible by 64" -# elif MAXCHUNKSIZE - /* - * goal is to minimize pressure on L1 cache by moving in shorter steps, - * so that hashed data is still in the cache by the time we encrypt it - */ - minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64; - if (minblocks > MAXCHUNKSIZE / 64) { - for (i = 0; i < x4; i++) { - edges[i].ptr = hash_d[i].ptr; - edges[i].blocks = MAXCHUNKSIZE / 64; - ciph_d[i].blocks = MAXCHUNKSIZE / 16; - } - do { - sha1_multi_block(ctx, edges, n4x); - aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); - - for (i = 0; i < x4; i++) { - edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE; - hash_d[i].blocks -= MAXCHUNKSIZE / 64; - edges[i].blocks = MAXCHUNKSIZE / 64; - ciph_d[i].inp += MAXCHUNKSIZE; - ciph_d[i].out += MAXCHUNKSIZE; - ciph_d[i].blocks = MAXCHUNKSIZE / 16; - memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16); - } - processed += MAXCHUNKSIZE; - minblocks -= MAXCHUNKSIZE / 64; - } while (minblocks > MAXCHUNKSIZE / 64); - } -# endif -# undef MAXCHUNKSIZE - sha1_multi_block(ctx, hash_d, n4x); - - memset(blocks, 0, sizeof(blocks)); - for (i = 0; i < x4; i++) { - unsigned int len = (i == (x4 - 1) ? last : frag), - off = hash_d[i].blocks * 64; - const unsigned char *ptr = hash_d[i].ptr + off; - - off = (len - processed) - (64 - 13) - off; /* remainder actually */ - memcpy(blocks[i].c, ptr, off); - blocks[i].c[off] = 0x80; - len += 64 + 13; /* 64 is HMAC header */ - len *= 8; /* convert to bits */ - if (off < (64 - 8)) { -# ifdef BSWAP4 - blocks[i].d[15] = BSWAP4(len); -# else - PUTU32(blocks[i].c + 60, len); -# endif - edges[i].blocks = 1; - } else { -# ifdef BSWAP4 - blocks[i].d[31] = BSWAP4(len); -# else - PUTU32(blocks[i].c + 124, len); -# endif - edges[i].blocks = 2; - } - edges[i].ptr = blocks[i].c; - } - - /* hash input tails and finalize */ - sha1_multi_block(ctx, edges, n4x); - - memset(blocks, 0, sizeof(blocks)); - for (i = 0; i < x4; i++) { -# ifdef BSWAP4 - blocks[i].d[0] = BSWAP4(ctx->A[i]); - ctx->A[i] = key->tail.h0; - blocks[i].d[1] = BSWAP4(ctx->B[i]); - ctx->B[i] = key->tail.h1; - blocks[i].d[2] = BSWAP4(ctx->C[i]); - ctx->C[i] = key->tail.h2; - blocks[i].d[3] = BSWAP4(ctx->D[i]); - ctx->D[i] = key->tail.h3; - blocks[i].d[4] = BSWAP4(ctx->E[i]); - ctx->E[i] = key->tail.h4; - blocks[i].c[20] = 0x80; - blocks[i].d[15] = BSWAP4((64 + 20) * 8); -# else - PUTU32(blocks[i].c + 0, ctx->A[i]); - ctx->A[i] = key->tail.h0; - PUTU32(blocks[i].c + 4, ctx->B[i]); - ctx->B[i] = key->tail.h1; - PUTU32(blocks[i].c + 8, ctx->C[i]); - ctx->C[i] = key->tail.h2; - PUTU32(blocks[i].c + 12, ctx->D[i]); - ctx->D[i] = key->tail.h3; - PUTU32(blocks[i].c + 16, ctx->E[i]); - ctx->E[i] = key->tail.h4; - blocks[i].c[20] = 0x80; - PUTU32(blocks[i].c + 60, (64 + 20) * 8); -# endif - edges[i].ptr = blocks[i].c; - edges[i].blocks = 1; - } - - /* finalize MACs */ - sha1_multi_block(ctx, edges, n4x); - - for (i = 0; i < x4; i++) { - unsigned int len = (i == (x4 - 1) ? last : frag), pad, j; - unsigned char *out0 = out; - - memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed); - ciph_d[i].inp = ciph_d[i].out; - - out += 5 + 16 + len; - - /* write MAC */ - PUTU32(out + 0, ctx->A[i]); - PUTU32(out + 4, ctx->B[i]); - PUTU32(out + 8, ctx->C[i]); - PUTU32(out + 12, ctx->D[i]); - PUTU32(out + 16, ctx->E[i]); - out += 20; - len += 20; - - /* pad */ - pad = 15 - len % 16; - for (j = 0; j <= pad; j++) - *(out++) = pad; - len += pad + 1; - - ciph_d[i].blocks = (len - processed) / 16; - len += 16; /* account for explicit iv */ - - /* arrange header */ - out0[0] = ((u8 *)key->md.data)[8]; - out0[1] = ((u8 *)key->md.data)[9]; - out0[2] = ((u8 *)key->md.data)[10]; - out0[3] = (u8)(len >> 8); - out0[4] = (u8)(len); - - ret += len + 5; - inp += frag; - } - - aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); - - OPENSSL_cleanse(blocks, sizeof(blocks)); - OPENSSL_cleanse(ctx, sizeof(*ctx)); - - return ret; -} -# endif - -static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_HMAC_SHA1 *key = data(ctx); - unsigned int l; - size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and - * later */ - sha_off = 0; -# if defined(STITCHED_CALL) - size_t aes_off = 0, blocks; - - sha_off = SHA_CBLOCK - key->md.num; -# endif - - key->payload_length = NO_PAYLOAD_LENGTH; - - if (len % AES_BLOCK_SIZE) - return 0; - - if (ctx->encrypt) { - if (plen == NO_PAYLOAD_LENGTH) - plen = len; - else if (len != - ((plen + SHA_DIGEST_LENGTH + - AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)) - return 0; - else if (key->aux.tls_ver >= TLS1_1_VERSION) - iv = AES_BLOCK_SIZE; - -# if defined(STITCHED_CALL) - if (plen > (sha_off + iv) - && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) { - SHA1_Update(&key->md, in + iv, sha_off); - - aesni_cbc_sha1_enc(in, out, blocks, &key->ks, - ctx->iv, &key->md, in + iv + sha_off); - blocks *= SHA_CBLOCK; - aes_off += blocks; - sha_off += blocks; - key->md.Nh += blocks >> 29; - key->md.Nl += blocks <<= 3; - if (key->md.Nl < (unsigned int)blocks) - key->md.Nh++; - } else { - sha_off = 0; - } -# endif - sha_off += iv; - SHA1_Update(&key->md, in + sha_off, plen - sha_off); - - if (plen != len) { /* "TLS" mode of operation */ - if (in != out) - memcpy(out + aes_off, in + aes_off, plen - aes_off); - - /* calculate HMAC and append it to payload */ - SHA1_Final(out + plen, &key->md); - key->md = key->tail; - SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH); - SHA1_Final(out + plen, &key->md); - - /* pad the payload|hmac */ - plen += SHA_DIGEST_LENGTH; - for (l = len - plen - 1; plen < len; plen++) - out[plen] = l; - /* encrypt HMAC|padding at once */ - aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, - &key->ks, ctx->iv, 1); - } else { - aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, - &key->ks, ctx->iv, 1); - } - } else { - union { - unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)]; - unsigned char c[32 + SHA_DIGEST_LENGTH]; - } mac, *pmac; - - /* arrange cache line alignment */ - pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32)); - - if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ - size_t inp_len, mask, j, i; - unsigned int res, maxpad, pad, bitlen; - int ret = 1; - union { - unsigned int u[SHA_LBLOCK]; - unsigned char c[SHA_CBLOCK]; - } *data = (void *)key->md.data; -# if defined(STITCHED_DECRYPT_CALL) - unsigned char tail_iv[AES_BLOCK_SIZE]; - int stitch = 0; -# endif - - if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3]) - >= TLS1_1_VERSION) { - if (len < (AES_BLOCK_SIZE + SHA_DIGEST_LENGTH + 1)) - return 0; - - /* omit explicit iv */ - memcpy(ctx->iv, in, AES_BLOCK_SIZE); - in += AES_BLOCK_SIZE; - out += AES_BLOCK_SIZE; - len -= AES_BLOCK_SIZE; - } else if (len < (SHA_DIGEST_LENGTH + 1)) - return 0; - -# if defined(STITCHED_DECRYPT_CALL) - if (len >= 1024 && ctx->key_len == 32) { - /* decrypt last block */ - memcpy(tail_iv, in + len - 2 * AES_BLOCK_SIZE, - AES_BLOCK_SIZE); - aesni_cbc_encrypt(in + len - AES_BLOCK_SIZE, - out + len - AES_BLOCK_SIZE, AES_BLOCK_SIZE, - &key->ks, tail_iv, 0); - stitch = 1; - } else -# endif - /* decrypt HMAC|padding at once */ - aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); - - /* figure out payload length */ - pad = out[len - 1]; - maxpad = len - (SHA_DIGEST_LENGTH + 1); - maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); - maxpad &= 255; - - mask = constant_time_ge(maxpad, pad); - ret &= mask; - /* - * If pad is invalid then we will fail the above test but we must - * continue anyway because we are in constant time code. However, - * we'll use the maxpad value instead of the supplied pad to make - * sure we perform well defined pointer arithmetic. - */ - pad = constant_time_select(mask, pad, maxpad); - - inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); - - key->aux.tls_aad[plen - 2] = inp_len >> 8; - key->aux.tls_aad[plen - 1] = inp_len; - - /* calculate HMAC */ - key->md = key->head; - SHA1_Update(&key->md, key->aux.tls_aad, plen); - -# if defined(STITCHED_DECRYPT_CALL) - if (stitch) { - blocks = (len - (256 + 32 + SHA_CBLOCK)) / SHA_CBLOCK; - aes_off = len - AES_BLOCK_SIZE - blocks * SHA_CBLOCK; - sha_off = SHA_CBLOCK - plen; - - aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0); - - SHA1_Update(&key->md, out, sha_off); - aesni256_cbc_sha1_dec(in + aes_off, - out + aes_off, blocks, &key->ks, - ctx->iv, &key->md, out + sha_off); - - sha_off += blocks *= SHA_CBLOCK; - out += sha_off; - len -= sha_off; - inp_len -= sha_off; - - key->md.Nl += (blocks << 3); /* at most 18 bits */ - memcpy(ctx->iv, tail_iv, AES_BLOCK_SIZE); - } -# endif - -# if 1 - len -= SHA_DIGEST_LENGTH; /* amend mac */ - if (len >= (256 + SHA_CBLOCK)) { - j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK); - j += SHA_CBLOCK - key->md.num; - SHA1_Update(&key->md, out, j); - out += j; - len -= j; - inp_len -= j; - } - - /* but pretend as if we hashed padded payload */ - bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */ -# ifdef BSWAP4 - bitlen = BSWAP4(bitlen); -# else - mac.c[0] = 0; - mac.c[1] = (unsigned char)(bitlen >> 16); - mac.c[2] = (unsigned char)(bitlen >> 8); - mac.c[3] = (unsigned char)bitlen; - bitlen = mac.u[0]; -# endif - - pmac->u[0] = 0; - pmac->u[1] = 0; - pmac->u[2] = 0; - pmac->u[3] = 0; - pmac->u[4] = 0; - - for (res = key->md.num, j = 0; j < len; j++) { - size_t c = out[j]; - mask = (j - inp_len) >> (sizeof(j) * 8 - 8); - c &= mask; - c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8)); - data->c[res++] = (unsigned char)c; - - if (res != SHA_CBLOCK) - continue; - - /* j is not incremented yet */ - mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1)); - data->u[SHA_LBLOCK - 1] |= bitlen & mask; - sha1_block_data_order(&key->md, data, 1); - mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1)); - pmac->u[0] |= key->md.h0 & mask; - pmac->u[1] |= key->md.h1 & mask; - pmac->u[2] |= key->md.h2 & mask; - pmac->u[3] |= key->md.h3 & mask; - pmac->u[4] |= key->md.h4 & mask; - res = 0; - } - - for (i = res; i < SHA_CBLOCK; i++, j++) - data->c[i] = 0; - - if (res > SHA_CBLOCK - 8) { - mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1)); - data->u[SHA_LBLOCK - 1] |= bitlen & mask; - sha1_block_data_order(&key->md, data, 1); - mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); - pmac->u[0] |= key->md.h0 & mask; - pmac->u[1] |= key->md.h1 & mask; - pmac->u[2] |= key->md.h2 & mask; - pmac->u[3] |= key->md.h3 & mask; - pmac->u[4] |= key->md.h4 & mask; - - memset(data, 0, SHA_CBLOCK); - j += 64; - } - data->u[SHA_LBLOCK - 1] = bitlen; - sha1_block_data_order(&key->md, data, 1); - mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); - pmac->u[0] |= key->md.h0 & mask; - pmac->u[1] |= key->md.h1 & mask; - pmac->u[2] |= key->md.h2 & mask; - pmac->u[3] |= key->md.h3 & mask; - pmac->u[4] |= key->md.h4 & mask; - -# ifdef BSWAP4 - pmac->u[0] = BSWAP4(pmac->u[0]); - pmac->u[1] = BSWAP4(pmac->u[1]); - pmac->u[2] = BSWAP4(pmac->u[2]); - pmac->u[3] = BSWAP4(pmac->u[3]); - pmac->u[4] = BSWAP4(pmac->u[4]); -# else - for (i = 0; i < 5; i++) { - res = pmac->u[i]; - pmac->c[4 * i + 0] = (unsigned char)(res >> 24); - pmac->c[4 * i + 1] = (unsigned char)(res >> 16); - pmac->c[4 * i + 2] = (unsigned char)(res >> 8); - pmac->c[4 * i + 3] = (unsigned char)res; - } -# endif - len += SHA_DIGEST_LENGTH; -# else - SHA1_Update(&key->md, out, inp_len); - res = key->md.num; - SHA1_Final(pmac->c, &key->md); - - { - unsigned int inp_blocks, pad_blocks; - - /* but pretend as if we hashed padded payload */ - inp_blocks = - 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); - res += (unsigned int)(len - inp_len); - pad_blocks = res / SHA_CBLOCK; - res %= SHA_CBLOCK; - pad_blocks += - 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); - for (; inp_blocks < pad_blocks; inp_blocks++) - sha1_block_data_order(&key->md, data, 1); - } -# endif - key->md = key->tail; - SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH); - SHA1_Final(pmac->c, &key->md); - - /* verify HMAC */ - out += inp_len; - len -= inp_len; -# if 1 - { - unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH; - size_t off = out - p; - unsigned int c, cmask; - - maxpad += SHA_DIGEST_LENGTH; - for (res = 0, i = 0, j = 0; j < maxpad; j++) { - c = p[j]; - cmask = - ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) * - 8 - 1); - res |= (c ^ pad) & ~cmask; /* ... and padding */ - cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1); - res |= (c ^ pmac->c[i]) & cmask; - i += 1 & cmask; - } - maxpad -= SHA_DIGEST_LENGTH; - - res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); - ret &= (int)~res; - } -# else - for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++) - res |= out[i] ^ pmac->c[i]; - res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); - ret &= (int)~res; - - /* verify padding */ - pad = (pad & ~res) | (maxpad & res); - out = out + len - 1 - pad; - for (res = 0, i = 0; i < pad; i++) - res |= out[i] ^ pad; - - res = (0 - res) >> (sizeof(res) * 8 - 1); - ret &= (int)~res; -# endif - return ret; - } else { -# if defined(STITCHED_DECRYPT_CALL) - if (len >= 1024 && ctx->key_len == 32) { - if (sha_off %= SHA_CBLOCK) - blocks = (len - 3 * SHA_CBLOCK) / SHA_CBLOCK; - else - blocks = (len - 2 * SHA_CBLOCK) / SHA_CBLOCK; - aes_off = len - blocks * SHA_CBLOCK; - - aesni_cbc_encrypt(in, out, aes_off, &key->ks, ctx->iv, 0); - SHA1_Update(&key->md, out, sha_off); - aesni256_cbc_sha1_dec(in + aes_off, - out + aes_off, blocks, &key->ks, - ctx->iv, &key->md, out + sha_off); - - sha_off += blocks *= SHA_CBLOCK; - out += sha_off; - len -= sha_off; - - key->md.Nh += blocks >> 29; - key->md.Nl += blocks <<= 3; - if (key->md.Nl < (unsigned int)blocks) - key->md.Nh++; - } else -# endif - /* decrypt HMAC|padding at once */ - aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); - - SHA1_Update(&key->md, out, len); - } - } - - return 1; -} - -static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr) -{ - EVP_AES_HMAC_SHA1 *key = data(ctx); - - switch (type) { - case EVP_CTRL_AEAD_SET_MAC_KEY: - { - unsigned int i; - unsigned char hmac_key[64]; - - memset(hmac_key, 0, sizeof(hmac_key)); - - if (arg > (int)sizeof(hmac_key)) { - SHA1_Init(&key->head); - SHA1_Update(&key->head, ptr, arg); - SHA1_Final(hmac_key, &key->head); - } else { - memcpy(hmac_key, ptr, arg); - } - - for (i = 0; i < sizeof(hmac_key); i++) - hmac_key[i] ^= 0x36; /* ipad */ - SHA1_Init(&key->head); - SHA1_Update(&key->head, hmac_key, sizeof(hmac_key)); - - for (i = 0; i < sizeof(hmac_key); i++) - hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ - SHA1_Init(&key->tail); - SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key)); - - OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); - - return 1; - } - case EVP_CTRL_AEAD_TLS1_AAD: - { - unsigned char *p = ptr; - unsigned int len; - - if (arg != EVP_AEAD_TLS1_AAD_LEN) - return -1; - - len = p[arg - 2] << 8 | p[arg - 1]; - - if (ctx->encrypt) { - key->payload_length = len; - if ((key->aux.tls_ver = - p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { - if (len < AES_BLOCK_SIZE) - return 0; - len -= AES_BLOCK_SIZE; - p[arg - 2] = len >> 8; - p[arg - 1] = len; - } - key->md = key->head; - SHA1_Update(&key->md, p, arg); - - return (int)(((len + SHA_DIGEST_LENGTH + - AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) - - len); - } else { - memcpy(key->aux.tls_aad, ptr, arg); - key->payload_length = arg; - - return SHA_DIGEST_LENGTH; - } - } -# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: - return (int)(5 + 16 + ((arg + 20 + 16) & -16)); - case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: - { - EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = - (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; - unsigned int n4x = 1, x4; - unsigned int frag, last, packlen, inp_len; - - if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) - return -1; - - inp_len = param->inp[11] << 8 | param->inp[12]; - - if (ctx->encrypt) { - if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION) - return -1; - - if (inp_len) { - if (inp_len < 4096) - return 0; /* too short */ - - if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5)) - n4x = 2; /* AVX2 */ - } else if ((n4x = param->interleave / 4) && n4x <= 2) - inp_len = param->len; - else - return -1; - - key->md = key->head; - SHA1_Update(&key->md, param->inp, 13); - - x4 = 4 * n4x; - n4x += 1; - - frag = inp_len >> n4x; - last = inp_len + frag - (frag << n4x); - if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) { - frag++; - last -= x4 - 1; - } - - packlen = 5 + 16 + ((frag + 20 + 16) & -16); - packlen = (packlen << n4x) - packlen; - packlen += 5 + 16 + ((last + 20 + 16) & -16); - - param->interleave = x4; - - return (int)packlen; - } else - return -1; /* not yet */ - } - case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: - { - EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = - (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; - - return (int)tls1_1_multi_block_encrypt(key, param->out, - param->inp, param->len, - param->interleave / 4); - } - case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT: -# endif - default: - return -1; - } -} - -static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = { -# ifdef NID_aes_128_cbc_hmac_sha1 - NID_aes_128_cbc_hmac_sha1, -# else - NID_undef, -# endif - 16, 16, 16, - EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | - EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, - aesni_cbc_hmac_sha1_init_key, - aesni_cbc_hmac_sha1_cipher, - NULL, - sizeof(EVP_AES_HMAC_SHA1), - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, - aesni_cbc_hmac_sha1_ctrl, - NULL -}; - -static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = { -# ifdef NID_aes_256_cbc_hmac_sha1 - NID_aes_256_cbc_hmac_sha1, -# else - NID_undef, -# endif - 16, 32, 16, - EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | - EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, - aesni_cbc_hmac_sha1_init_key, - aesni_cbc_hmac_sha1_cipher, - NULL, - sizeof(EVP_AES_HMAC_SHA1), - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, - aesni_cbc_hmac_sha1_ctrl, - NULL -}; - -const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) -{ - return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? - &aesni_128_cbc_hmac_sha1_cipher : NULL); -} - -const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) -{ - return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? - &aesni_256_cbc_hmac_sha1_cipher : NULL); -} -# else -const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) -{ - return NULL; -} - -const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) -{ - return NULL; -} -# endif -#endif diff --git a/Sources/COpenSSL/e_aes_cbc_hmac_sha256.c b/Sources/COpenSSL/e_aes_cbc_hmac_sha256.c deleted file mode 100644 index 33614040..00000000 --- a/Sources/COpenSSL/e_aes_cbc_hmac_sha256.c +++ /dev/null @@ -1,996 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "opensslconf.h" - -#include -#include - -#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA256) - -# include "evp.h" -# include "objects.h" -# include "aes.h" -# include "sha.h" -# include "rand.h" -# include "modes_lcl.h" -# include "constant_time_locl.h" - -# ifndef EVP_CIPH_FLAG_AEAD_CIPHER -# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 -# define EVP_CTRL_AEAD_TLS1_AAD 0x16 -# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 -# endif - -# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1) -# define EVP_CIPH_FLAG_DEFAULT_ASN1 0 -# endif - -# if !defined(EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) -# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 -# endif - -# define TLS1_1_VERSION 0x0302 - -typedef struct { - AES_KEY ks; - SHA256_CTX head, tail, md; - size_t payload_length; /* AAD length in decrypt case */ - union { - unsigned int tls_ver; - unsigned char tls_aad[16]; /* 13 used */ - } aux; -} EVP_AES_HMAC_SHA256; - -# define NO_PAYLOAD_LENGTH ((size_t)-1) - -# if defined(AES_ASM) && ( \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) || \ - defined(__INTEL__) ) - -extern unsigned int OPENSSL_ia32cap_P[]; -# define AESNI_CAPABLE (1<<(57-32)) - -int aesni_set_encrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); -int aesni_set_decrypt_key(const unsigned char *userKey, int bits, - AES_KEY *key); - -void aesni_cbc_encrypt(const unsigned char *in, - unsigned char *out, - size_t length, - const AES_KEY *key, unsigned char *ivec, int enc); - -int aesni_cbc_sha256_enc(const void *inp, void *out, size_t blocks, - const AES_KEY *key, unsigned char iv[16], - SHA256_CTX *ctx, const void *in0); - -# define data(ctx) ((EVP_AES_HMAC_SHA256 *)(ctx)->cipher_data) - -static int aesni_cbc_hmac_sha256_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *inkey, - const unsigned char *iv, int enc) -{ - EVP_AES_HMAC_SHA256 *key = data(ctx); - int ret; - - if (enc) - memset(&key->ks, 0, sizeof(key->ks.rd_key)), - ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks); - else - ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks); - - SHA256_Init(&key->head); /* handy when benchmarking */ - key->tail = key->head; - key->md = key->head; - - key->payload_length = NO_PAYLOAD_LENGTH; - - return ret < 0 ? 0 : 1; -} - -# define STITCHED_CALL - -# if !defined(STITCHED_CALL) -# define aes_off 0 -# endif - -void sha256_block_data_order(void *c, const void *p, size_t len); - -static void sha256_update(SHA256_CTX *c, const void *data, size_t len) -{ - const unsigned char *ptr = data; - size_t res; - - if ((res = c->num)) { - res = SHA256_CBLOCK - res; - if (len < res) - res = len; - SHA256_Update(c, ptr, res); - ptr += res; - len -= res; - } - - res = len % SHA256_CBLOCK; - len -= res; - - if (len) { - sha256_block_data_order(c, ptr, len / SHA256_CBLOCK); - - ptr += len; - c->Nh += len >> 29; - c->Nl += len <<= 3; - if (c->Nl < (unsigned int)len) - c->Nh++; - } - - if (res) - SHA256_Update(c, ptr, res); -} - -# ifdef SHA256_Update -# undef SHA256_Update -# endif -# define SHA256_Update sha256_update - -# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - -typedef struct { - unsigned int A[8], B[8], C[8], D[8], E[8], F[8], G[8], H[8]; -} SHA256_MB_CTX; -typedef struct { - const unsigned char *ptr; - int blocks; -} HASH_DESC; - -void sha256_multi_block(SHA256_MB_CTX *, const HASH_DESC *, int); - -typedef struct { - const unsigned char *inp; - unsigned char *out; - int blocks; - u64 iv[2]; -} CIPH_DESC; - -void aesni_multi_cbc_encrypt(CIPH_DESC *, void *, int); - -static size_t tls1_1_multi_block_encrypt(EVP_AES_HMAC_SHA256 *key, - unsigned char *out, - const unsigned char *inp, - size_t inp_len, int n4x) -{ /* n4x is 1 or 2 */ - HASH_DESC hash_d[8], edges[8]; - CIPH_DESC ciph_d[8]; - unsigned char storage[sizeof(SHA256_MB_CTX) + 32]; - union { - u64 q[16]; - u32 d[32]; - u8 c[128]; - } blocks[8]; - SHA256_MB_CTX *ctx; - unsigned int frag, last, packlen, i, x4 = 4 * n4x, minblocks, processed = - 0; - size_t ret = 0; - u8 *IVs; -# if defined(BSWAP8) - u64 seqnum; -# endif - - /* ask for IVs in bulk */ - if (RAND_bytes((IVs = blocks[0].c), 16 * x4) <= 0) - return 0; - - /* align */ - ctx = (SHA256_MB_CTX *) (storage + 32 - ((size_t)storage % 32)); - - frag = (unsigned int)inp_len >> (1 + n4x); - last = (unsigned int)inp_len + frag - (frag << (1 + n4x)); - if (last > frag && ((last + 13 + 9) % 64) < (x4 - 1)) { - frag++; - last -= x4 - 1; - } - - packlen = 5 + 16 + ((frag + 32 + 16) & -16); - - /* populate descriptors with pointers and IVs */ - hash_d[0].ptr = inp; - ciph_d[0].inp = inp; - /* 5+16 is place for header and explicit IV */ - ciph_d[0].out = out + 5 + 16; - memcpy(ciph_d[0].out - 16, IVs, 16); - memcpy(ciph_d[0].iv, IVs, 16); - IVs += 16; - - for (i = 1; i < x4; i++) { - ciph_d[i].inp = hash_d[i].ptr = hash_d[i - 1].ptr + frag; - ciph_d[i].out = ciph_d[i - 1].out + packlen; - memcpy(ciph_d[i].out - 16, IVs, 16); - memcpy(ciph_d[i].iv, IVs, 16); - IVs += 16; - } - -# if defined(BSWAP8) - memcpy(blocks[0].c, key->md.data, 8); - seqnum = BSWAP8(blocks[0].q[0]); -# endif - for (i = 0; i < x4; i++) { - unsigned int len = (i == (x4 - 1) ? last : frag); -# if !defined(BSWAP8) - unsigned int carry, j; -# endif - - ctx->A[i] = key->md.h[0]; - ctx->B[i] = key->md.h[1]; - ctx->C[i] = key->md.h[2]; - ctx->D[i] = key->md.h[3]; - ctx->E[i] = key->md.h[4]; - ctx->F[i] = key->md.h[5]; - ctx->G[i] = key->md.h[6]; - ctx->H[i] = key->md.h[7]; - - /* fix seqnum */ -# if defined(BSWAP8) - blocks[i].q[0] = BSWAP8(seqnum + i); -# else - for (carry = i, j = 8; j--;) { - blocks[i].c[j] = ((u8 *)key->md.data)[j] + carry; - carry = (blocks[i].c[j] - carry) >> (sizeof(carry) * 8 - 1); - } -# endif - blocks[i].c[8] = ((u8 *)key->md.data)[8]; - blocks[i].c[9] = ((u8 *)key->md.data)[9]; - blocks[i].c[10] = ((u8 *)key->md.data)[10]; - /* fix length */ - blocks[i].c[11] = (u8)(len >> 8); - blocks[i].c[12] = (u8)(len); - - memcpy(blocks[i].c + 13, hash_d[i].ptr, 64 - 13); - hash_d[i].ptr += 64 - 13; - hash_d[i].blocks = (len - (64 - 13)) / 64; - - edges[i].ptr = blocks[i].c; - edges[i].blocks = 1; - } - - /* hash 13-byte headers and first 64-13 bytes of inputs */ - sha256_multi_block(ctx, edges, n4x); - /* hash bulk inputs */ -# define MAXCHUNKSIZE 2048 -# if MAXCHUNKSIZE%64 -# error "MAXCHUNKSIZE is not divisible by 64" -# elif MAXCHUNKSIZE - /* - * goal is to minimize pressure on L1 cache by moving in shorter steps, - * so that hashed data is still in the cache by the time we encrypt it - */ - minblocks = ((frag <= last ? frag : last) - (64 - 13)) / 64; - if (minblocks > MAXCHUNKSIZE / 64) { - for (i = 0; i < x4; i++) { - edges[i].ptr = hash_d[i].ptr; - edges[i].blocks = MAXCHUNKSIZE / 64; - ciph_d[i].blocks = MAXCHUNKSIZE / 16; - } - do { - sha256_multi_block(ctx, edges, n4x); - aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); - - for (i = 0; i < x4; i++) { - edges[i].ptr = hash_d[i].ptr += MAXCHUNKSIZE; - hash_d[i].blocks -= MAXCHUNKSIZE / 64; - edges[i].blocks = MAXCHUNKSIZE / 64; - ciph_d[i].inp += MAXCHUNKSIZE; - ciph_d[i].out += MAXCHUNKSIZE; - ciph_d[i].blocks = MAXCHUNKSIZE / 16; - memcpy(ciph_d[i].iv, ciph_d[i].out - 16, 16); - } - processed += MAXCHUNKSIZE; - minblocks -= MAXCHUNKSIZE / 64; - } while (minblocks > MAXCHUNKSIZE / 64); - } -# endif -# undef MAXCHUNKSIZE - sha256_multi_block(ctx, hash_d, n4x); - - memset(blocks, 0, sizeof(blocks)); - for (i = 0; i < x4; i++) { - unsigned int len = (i == (x4 - 1) ? last : frag), - off = hash_d[i].blocks * 64; - const unsigned char *ptr = hash_d[i].ptr + off; - - off = (len - processed) - (64 - 13) - off; /* remainder actually */ - memcpy(blocks[i].c, ptr, off); - blocks[i].c[off] = 0x80; - len += 64 + 13; /* 64 is HMAC header */ - len *= 8; /* convert to bits */ - if (off < (64 - 8)) { -# ifdef BSWAP4 - blocks[i].d[15] = BSWAP4(len); -# else - PUTU32(blocks[i].c + 60, len); -# endif - edges[i].blocks = 1; - } else { -# ifdef BSWAP4 - blocks[i].d[31] = BSWAP4(len); -# else - PUTU32(blocks[i].c + 124, len); -# endif - edges[i].blocks = 2; - } - edges[i].ptr = blocks[i].c; - } - - /* hash input tails and finalize */ - sha256_multi_block(ctx, edges, n4x); - - memset(blocks, 0, sizeof(blocks)); - for (i = 0; i < x4; i++) { -# ifdef BSWAP4 - blocks[i].d[0] = BSWAP4(ctx->A[i]); - ctx->A[i] = key->tail.h[0]; - blocks[i].d[1] = BSWAP4(ctx->B[i]); - ctx->B[i] = key->tail.h[1]; - blocks[i].d[2] = BSWAP4(ctx->C[i]); - ctx->C[i] = key->tail.h[2]; - blocks[i].d[3] = BSWAP4(ctx->D[i]); - ctx->D[i] = key->tail.h[3]; - blocks[i].d[4] = BSWAP4(ctx->E[i]); - ctx->E[i] = key->tail.h[4]; - blocks[i].d[5] = BSWAP4(ctx->F[i]); - ctx->F[i] = key->tail.h[5]; - blocks[i].d[6] = BSWAP4(ctx->G[i]); - ctx->G[i] = key->tail.h[6]; - blocks[i].d[7] = BSWAP4(ctx->H[i]); - ctx->H[i] = key->tail.h[7]; - blocks[i].c[32] = 0x80; - blocks[i].d[15] = BSWAP4((64 + 32) * 8); -# else - PUTU32(blocks[i].c + 0, ctx->A[i]); - ctx->A[i] = key->tail.h[0]; - PUTU32(blocks[i].c + 4, ctx->B[i]); - ctx->B[i] = key->tail.h[1]; - PUTU32(blocks[i].c + 8, ctx->C[i]); - ctx->C[i] = key->tail.h[2]; - PUTU32(blocks[i].c + 12, ctx->D[i]); - ctx->D[i] = key->tail.h[3]; - PUTU32(blocks[i].c + 16, ctx->E[i]); - ctx->E[i] = key->tail.h[4]; - PUTU32(blocks[i].c + 20, ctx->F[i]); - ctx->F[i] = key->tail.h[5]; - PUTU32(blocks[i].c + 24, ctx->G[i]); - ctx->G[i] = key->tail.h[6]; - PUTU32(blocks[i].c + 28, ctx->H[i]); - ctx->H[i] = key->tail.h[7]; - blocks[i].c[32] = 0x80; - PUTU32(blocks[i].c + 60, (64 + 32) * 8); -# endif - edges[i].ptr = blocks[i].c; - edges[i].blocks = 1; - } - - /* finalize MACs */ - sha256_multi_block(ctx, edges, n4x); - - for (i = 0; i < x4; i++) { - unsigned int len = (i == (x4 - 1) ? last : frag), pad, j; - unsigned char *out0 = out; - - memcpy(ciph_d[i].out, ciph_d[i].inp, len - processed); - ciph_d[i].inp = ciph_d[i].out; - - out += 5 + 16 + len; - - /* write MAC */ - PUTU32(out + 0, ctx->A[i]); - PUTU32(out + 4, ctx->B[i]); - PUTU32(out + 8, ctx->C[i]); - PUTU32(out + 12, ctx->D[i]); - PUTU32(out + 16, ctx->E[i]); - PUTU32(out + 20, ctx->F[i]); - PUTU32(out + 24, ctx->G[i]); - PUTU32(out + 28, ctx->H[i]); - out += 32; - len += 32; - - /* pad */ - pad = 15 - len % 16; - for (j = 0; j <= pad; j++) - *(out++) = pad; - len += pad + 1; - - ciph_d[i].blocks = (len - processed) / 16; - len += 16; /* account for explicit iv */ - - /* arrange header */ - out0[0] = ((u8 *)key->md.data)[8]; - out0[1] = ((u8 *)key->md.data)[9]; - out0[2] = ((u8 *)key->md.data)[10]; - out0[3] = (u8)(len >> 8); - out0[4] = (u8)(len); - - ret += len + 5; - inp += frag; - } - - aesni_multi_cbc_encrypt(ciph_d, &key->ks, n4x); - - OPENSSL_cleanse(blocks, sizeof(blocks)); - OPENSSL_cleanse(ctx, sizeof(*ctx)); - - return ret; -} -# endif - -static int aesni_cbc_hmac_sha256_cipher(EVP_CIPHER_CTX *ctx, - unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_AES_HMAC_SHA256 *key = data(ctx); - unsigned int l; - size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and - * later */ - sha_off = 0; -# if defined(STITCHED_CALL) - size_t aes_off = 0, blocks; - - sha_off = SHA256_CBLOCK - key->md.num; -# endif - - key->payload_length = NO_PAYLOAD_LENGTH; - - if (len % AES_BLOCK_SIZE) - return 0; - - if (ctx->encrypt) { - if (plen == NO_PAYLOAD_LENGTH) - plen = len; - else if (len != - ((plen + SHA256_DIGEST_LENGTH + - AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)) - return 0; - else if (key->aux.tls_ver >= TLS1_1_VERSION) - iv = AES_BLOCK_SIZE; - -# if defined(STITCHED_CALL) - /* - * Assembly stitch handles AVX-capable processors, but its - * performance is not optimal on AMD Jaguar, ~40% worse, for - * unknown reasons. Incidentally processor in question supports - * AVX, but not AMD-specific XOP extension, which can be used - * to identify it and avoid stitch invocation. So that after we - * establish that current CPU supports AVX, we even see if it's - * either even XOP-capable Bulldozer-based or GenuineIntel one. - * But SHAEXT-capable go ahead... - */ - if (((OPENSSL_ia32cap_P[2] & (1 << 29)) || /* SHAEXT? */ - ((OPENSSL_ia32cap_P[1] & (1 << (60 - 32))) && /* AVX? */ - ((OPENSSL_ia32cap_P[1] & (1 << (43 - 32))) /* XOP? */ - | (OPENSSL_ia32cap_P[0] & (1 << 30))))) && /* "Intel CPU"? */ - plen > (sha_off + iv) && - (blocks = (plen - (sha_off + iv)) / SHA256_CBLOCK)) { - SHA256_Update(&key->md, in + iv, sha_off); - - (void)aesni_cbc_sha256_enc(in, out, blocks, &key->ks, - ctx->iv, &key->md, in + iv + sha_off); - blocks *= SHA256_CBLOCK; - aes_off += blocks; - sha_off += blocks; - key->md.Nh += blocks >> 29; - key->md.Nl += blocks <<= 3; - if (key->md.Nl < (unsigned int)blocks) - key->md.Nh++; - } else { - sha_off = 0; - } -# endif - sha_off += iv; - SHA256_Update(&key->md, in + sha_off, plen - sha_off); - - if (plen != len) { /* "TLS" mode of operation */ - if (in != out) - memcpy(out + aes_off, in + aes_off, plen - aes_off); - - /* calculate HMAC and append it to payload */ - SHA256_Final(out + plen, &key->md); - key->md = key->tail; - SHA256_Update(&key->md, out + plen, SHA256_DIGEST_LENGTH); - SHA256_Final(out + plen, &key->md); - - /* pad the payload|hmac */ - plen += SHA256_DIGEST_LENGTH; - for (l = len - plen - 1; plen < len; plen++) - out[plen] = l; - /* encrypt HMAC|padding at once */ - aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, - &key->ks, ctx->iv, 1); - } else { - aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, - &key->ks, ctx->iv, 1); - } - } else { - union { - unsigned int u[SHA256_DIGEST_LENGTH / sizeof(unsigned int)]; - unsigned char c[64 + SHA256_DIGEST_LENGTH]; - } mac, *pmac; - - /* arrange cache line alignment */ - pmac = (void *)(((size_t)mac.c + 63) & ((size_t)0 - 64)); - - /* decrypt HMAC|padding at once */ - aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); - - if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ - size_t inp_len, mask, j, i; - unsigned int res, maxpad, pad, bitlen; - int ret = 1; - union { - unsigned int u[SHA_LBLOCK]; - unsigned char c[SHA256_CBLOCK]; - } *data = (void *)key->md.data; - - if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3]) - >= TLS1_1_VERSION) - iv = AES_BLOCK_SIZE; - - if (len < (iv + SHA256_DIGEST_LENGTH + 1)) - return 0; - - /* omit explicit iv */ - out += iv; - len -= iv; - - /* figure out payload length */ - pad = out[len - 1]; - maxpad = len - (SHA256_DIGEST_LENGTH + 1); - maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); - maxpad &= 255; - - mask = constant_time_ge(maxpad, pad); - ret &= mask; - /* - * If pad is invalid then we will fail the above test but we must - * continue anyway because we are in constant time code. However, - * we'll use the maxpad value instead of the supplied pad to make - * sure we perform well defined pointer arithmetic. - */ - pad = constant_time_select(mask, pad, maxpad); - - inp_len = len - (SHA256_DIGEST_LENGTH + pad + 1); - - key->aux.tls_aad[plen - 2] = inp_len >> 8; - key->aux.tls_aad[plen - 1] = inp_len; - - /* calculate HMAC */ - key->md = key->head; - SHA256_Update(&key->md, key->aux.tls_aad, plen); - -# if 1 - len -= SHA256_DIGEST_LENGTH; /* amend mac */ - if (len >= (256 + SHA256_CBLOCK)) { - j = (len - (256 + SHA256_CBLOCK)) & (0 - SHA256_CBLOCK); - j += SHA256_CBLOCK - key->md.num; - SHA256_Update(&key->md, out, j); - out += j; - len -= j; - inp_len -= j; - } - - /* but pretend as if we hashed padded payload */ - bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */ -# ifdef BSWAP4 - bitlen = BSWAP4(bitlen); -# else - mac.c[0] = 0; - mac.c[1] = (unsigned char)(bitlen >> 16); - mac.c[2] = (unsigned char)(bitlen >> 8); - mac.c[3] = (unsigned char)bitlen; - bitlen = mac.u[0]; -# endif - - pmac->u[0] = 0; - pmac->u[1] = 0; - pmac->u[2] = 0; - pmac->u[3] = 0; - pmac->u[4] = 0; - pmac->u[5] = 0; - pmac->u[6] = 0; - pmac->u[7] = 0; - - for (res = key->md.num, j = 0; j < len; j++) { - size_t c = out[j]; - mask = (j - inp_len) >> (sizeof(j) * 8 - 8); - c &= mask; - c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8)); - data->c[res++] = (unsigned char)c; - - if (res != SHA256_CBLOCK) - continue; - - /* j is not incremented yet */ - mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1)); - data->u[SHA_LBLOCK - 1] |= bitlen & mask; - sha256_block_data_order(&key->md, data, 1); - mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1)); - pmac->u[0] |= key->md.h[0] & mask; - pmac->u[1] |= key->md.h[1] & mask; - pmac->u[2] |= key->md.h[2] & mask; - pmac->u[3] |= key->md.h[3] & mask; - pmac->u[4] |= key->md.h[4] & mask; - pmac->u[5] |= key->md.h[5] & mask; - pmac->u[6] |= key->md.h[6] & mask; - pmac->u[7] |= key->md.h[7] & mask; - res = 0; - } - - for (i = res; i < SHA256_CBLOCK; i++, j++) - data->c[i] = 0; - - if (res > SHA256_CBLOCK - 8) { - mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1)); - data->u[SHA_LBLOCK - 1] |= bitlen & mask; - sha256_block_data_order(&key->md, data, 1); - mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); - pmac->u[0] |= key->md.h[0] & mask; - pmac->u[1] |= key->md.h[1] & mask; - pmac->u[2] |= key->md.h[2] & mask; - pmac->u[3] |= key->md.h[3] & mask; - pmac->u[4] |= key->md.h[4] & mask; - pmac->u[5] |= key->md.h[5] & mask; - pmac->u[6] |= key->md.h[6] & mask; - pmac->u[7] |= key->md.h[7] & mask; - - memset(data, 0, SHA256_CBLOCK); - j += 64; - } - data->u[SHA_LBLOCK - 1] = bitlen; - sha256_block_data_order(&key->md, data, 1); - mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); - pmac->u[0] |= key->md.h[0] & mask; - pmac->u[1] |= key->md.h[1] & mask; - pmac->u[2] |= key->md.h[2] & mask; - pmac->u[3] |= key->md.h[3] & mask; - pmac->u[4] |= key->md.h[4] & mask; - pmac->u[5] |= key->md.h[5] & mask; - pmac->u[6] |= key->md.h[6] & mask; - pmac->u[7] |= key->md.h[7] & mask; - -# ifdef BSWAP4 - pmac->u[0] = BSWAP4(pmac->u[0]); - pmac->u[1] = BSWAP4(pmac->u[1]); - pmac->u[2] = BSWAP4(pmac->u[2]); - pmac->u[3] = BSWAP4(pmac->u[3]); - pmac->u[4] = BSWAP4(pmac->u[4]); - pmac->u[5] = BSWAP4(pmac->u[5]); - pmac->u[6] = BSWAP4(pmac->u[6]); - pmac->u[7] = BSWAP4(pmac->u[7]); -# else - for (i = 0; i < 8; i++) { - res = pmac->u[i]; - pmac->c[4 * i + 0] = (unsigned char)(res >> 24); - pmac->c[4 * i + 1] = (unsigned char)(res >> 16); - pmac->c[4 * i + 2] = (unsigned char)(res >> 8); - pmac->c[4 * i + 3] = (unsigned char)res; - } -# endif - len += SHA256_DIGEST_LENGTH; -# else - SHA256_Update(&key->md, out, inp_len); - res = key->md.num; - SHA256_Final(pmac->c, &key->md); - - { - unsigned int inp_blocks, pad_blocks; - - /* but pretend as if we hashed padded payload */ - inp_blocks = - 1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); - res += (unsigned int)(len - inp_len); - pad_blocks = res / SHA256_CBLOCK; - res %= SHA256_CBLOCK; - pad_blocks += - 1 + ((SHA256_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); - for (; inp_blocks < pad_blocks; inp_blocks++) - sha1_block_data_order(&key->md, data, 1); - } -# endif - key->md = key->tail; - SHA256_Update(&key->md, pmac->c, SHA256_DIGEST_LENGTH); - SHA256_Final(pmac->c, &key->md); - - /* verify HMAC */ - out += inp_len; - len -= inp_len; -# if 1 - { - unsigned char *p = - out + len - 1 - maxpad - SHA256_DIGEST_LENGTH; - size_t off = out - p; - unsigned int c, cmask; - - maxpad += SHA256_DIGEST_LENGTH; - for (res = 0, i = 0, j = 0; j < maxpad; j++) { - c = p[j]; - cmask = - ((int)(j - off - SHA256_DIGEST_LENGTH)) >> - (sizeof(int) * 8 - 1); - res |= (c ^ pad) & ~cmask; /* ... and padding */ - cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1); - res |= (c ^ pmac->c[i]) & cmask; - i += 1 & cmask; - } - maxpad -= SHA256_DIGEST_LENGTH; - - res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); - ret &= (int)~res; - } -# else - for (res = 0, i = 0; i < SHA256_DIGEST_LENGTH; i++) - res |= out[i] ^ pmac->c[i]; - res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); - ret &= (int)~res; - - /* verify padding */ - pad = (pad & ~res) | (maxpad & res); - out = out + len - 1 - pad; - for (res = 0, i = 0; i < pad; i++) - res |= out[i] ^ pad; - - res = (0 - res) >> (sizeof(res) * 8 - 1); - ret &= (int)~res; -# endif - return ret; - } else { - SHA256_Update(&key->md, out, len); - } - } - - return 1; -} - -static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr) -{ - EVP_AES_HMAC_SHA256 *key = data(ctx); - - switch (type) { - case EVP_CTRL_AEAD_SET_MAC_KEY: - { - unsigned int i; - unsigned char hmac_key[64]; - - memset(hmac_key, 0, sizeof(hmac_key)); - - if (arg > (int)sizeof(hmac_key)) { - SHA256_Init(&key->head); - SHA256_Update(&key->head, ptr, arg); - SHA256_Final(hmac_key, &key->head); - } else { - memcpy(hmac_key, ptr, arg); - } - - for (i = 0; i < sizeof(hmac_key); i++) - hmac_key[i] ^= 0x36; /* ipad */ - SHA256_Init(&key->head); - SHA256_Update(&key->head, hmac_key, sizeof(hmac_key)); - - for (i = 0; i < sizeof(hmac_key); i++) - hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ - SHA256_Init(&key->tail); - SHA256_Update(&key->tail, hmac_key, sizeof(hmac_key)); - - OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); - - return 1; - } - case EVP_CTRL_AEAD_TLS1_AAD: - { - unsigned char *p = ptr; - unsigned int len; - - if (arg != EVP_AEAD_TLS1_AAD_LEN) - return -1; - - len = p[arg - 2] << 8 | p[arg - 1]; - - if (ctx->encrypt) { - key->payload_length = len; - if ((key->aux.tls_ver = - p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { - if (len < AES_BLOCK_SIZE) - return 0; - len -= AES_BLOCK_SIZE; - p[arg - 2] = len >> 8; - p[arg - 1] = len; - } - key->md = key->head; - SHA256_Update(&key->md, p, arg); - - return (int)(((len + SHA256_DIGEST_LENGTH + - AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) - - len); - } else { - memcpy(key->aux.tls_aad, ptr, arg); - key->payload_length = arg; - - return SHA256_DIGEST_LENGTH; - } - } -# if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - case EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE: - return (int)(5 + 16 + ((arg + 32 + 16) & -16)); - case EVP_CTRL_TLS1_1_MULTIBLOCK_AAD: - { - EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = - (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; - unsigned int n4x = 1, x4; - unsigned int frag, last, packlen, inp_len; - - if (arg < (int)sizeof(EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM)) - return -1; - - inp_len = param->inp[11] << 8 | param->inp[12]; - - if (ctx->encrypt) { - if ((param->inp[9] << 8 | param->inp[10]) < TLS1_1_VERSION) - return -1; - - if (inp_len) { - if (inp_len < 4096) - return 0; /* too short */ - - if (inp_len >= 8192 && OPENSSL_ia32cap_P[2] & (1 << 5)) - n4x = 2; /* AVX2 */ - } else if ((n4x = param->interleave / 4) && n4x <= 2) - inp_len = param->len; - else - return -1; - - key->md = key->head; - SHA256_Update(&key->md, param->inp, 13); - - x4 = 4 * n4x; - n4x += 1; - - frag = inp_len >> n4x; - last = inp_len + frag - (frag << n4x); - if (last > frag && ((last + 13 + 9) % 64 < (x4 - 1))) { - frag++; - last -= x4 - 1; - } - - packlen = 5 + 16 + ((frag + 32 + 16) & -16); - packlen = (packlen << n4x) - packlen; - packlen += 5 + 16 + ((last + 32 + 16) & -16); - - param->interleave = x4; - - return (int)packlen; - } else - return -1; /* not yet */ - } - case EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT: - { - EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *param = - (EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM *) ptr; - - return (int)tls1_1_multi_block_encrypt(key, param->out, - param->inp, param->len, - param->interleave / 4); - } - case EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT: -# endif - default: - return -1; - } -} - -static EVP_CIPHER aesni_128_cbc_hmac_sha256_cipher = { -# ifdef NID_aes_128_cbc_hmac_sha256 - NID_aes_128_cbc_hmac_sha256, -# else - NID_undef, -# endif - 16, 16, 16, - EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | - EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, - aesni_cbc_hmac_sha256_init_key, - aesni_cbc_hmac_sha256_cipher, - NULL, - sizeof(EVP_AES_HMAC_SHA256), - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, - aesni_cbc_hmac_sha256_ctrl, - NULL -}; - -static EVP_CIPHER aesni_256_cbc_hmac_sha256_cipher = { -# ifdef NID_aes_256_cbc_hmac_sha256 - NID_aes_256_cbc_hmac_sha256, -# else - NID_undef, -# endif - 16, 32, 16, - EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | - EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK, - aesni_cbc_hmac_sha256_init_key, - aesni_cbc_hmac_sha256_cipher, - NULL, - sizeof(EVP_AES_HMAC_SHA256), - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, - EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, - aesni_cbc_hmac_sha256_ctrl, - NULL -}; - -const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void) -{ - return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) && - aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ? - &aesni_128_cbc_hmac_sha256_cipher : NULL); -} - -const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void) -{ - return ((OPENSSL_ia32cap_P[1] & AESNI_CAPABLE) && - aesni_cbc_sha256_enc(NULL, NULL, 0, NULL, NULL, NULL, NULL) ? - &aesni_256_cbc_hmac_sha256_cipher : NULL); -} -# else -const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void) -{ - return NULL; -} - -const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void) -{ - return NULL; -} -# endif -#endif diff --git a/Sources/COpenSSL/e_atalla.c b/Sources/COpenSSL/e_atalla.c deleted file mode 100644 index b3b03e2d..00000000 --- a/Sources/COpenSSL/e_atalla.c +++ /dev/null @@ -1,627 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/engine/hw_atalla.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "crypto.h" -#include "buffer.h" -#include "dso.h" -#include "engine.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#include "bn.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_ATALLA - -# ifdef FLAT_INC -# include "atalla.h" -# else -# include "atalla.h" -# endif - -# define ATALLA_LIB_NAME "atalla engine" -# include "e_atalla_err.c" - -static int atalla_destroy(ENGINE *e); -static int atalla_init(ENGINE *e); -static int atalla_finish(ENGINE *e); -static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); - -/* BIGNUM stuff */ -static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); - -# ifndef OPENSSL_NO_RSA -/* RSA stuff */ -static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -# ifndef OPENSSL_NO_DSA -/* DSA stuff */ -static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, - BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *in_mont); -static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -# ifndef OPENSSL_NO_DH -/* DH stuff */ -/* This function is alised to mod_exp (with the DH and mont dropped). */ -static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -/* The definitions for control commands specific to this engine */ -# define ATALLA_CMD_SO_PATH ENGINE_CMD_BASE -static const ENGINE_CMD_DEFN atalla_cmd_defns[] = { - {ATALLA_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'atasi' shared library", - ENGINE_CMD_FLAG_STRING}, - {0, NULL, NULL, 0} -}; - -# ifndef OPENSSL_NO_RSA -/* Our internal RSA_METHOD that we provide pointers to */ -static RSA_METHOD atalla_rsa = { - "Atalla RSA method", - NULL, - NULL, - NULL, - NULL, - atalla_rsa_mod_exp, - atalla_mod_exp_mont, - NULL, - NULL, - 0, - NULL, - NULL, - NULL, - NULL -}; -# endif - -# ifndef OPENSSL_NO_DSA -/* Our internal DSA_METHOD that we provide pointers to */ -static DSA_METHOD atalla_dsa = { - "Atalla DSA method", - NULL, /* dsa_do_sign */ - NULL, /* dsa_sign_setup */ - NULL, /* dsa_do_verify */ - atalla_dsa_mod_exp, /* dsa_mod_exp */ - atalla_mod_exp_dsa, /* bn_mod_exp */ - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - NULL, /* dsa_paramgen */ - NULL /* dsa_keygen */ -}; -# endif - -# ifndef OPENSSL_NO_DH -/* Our internal DH_METHOD that we provide pointers to */ -static DH_METHOD atalla_dh = { - "Atalla DH method", - NULL, - NULL, - atalla_mod_exp_dh, - NULL, - NULL, - 0, - NULL, - NULL -}; -# endif - -/* Constants used when creating the ENGINE */ -static const char *engine_atalla_id = "atalla"; -static const char *engine_atalla_name = "Atalla hardware engine support"; - -/* - * This internal function is used by ENGINE_atalla() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_helper(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif -# ifndef OPENSSL_NO_DSA - const DSA_METHOD *meth2; -# endif -# ifndef OPENSSL_NO_DH - const DH_METHOD *meth3; -# endif - if (!ENGINE_set_id(e, engine_atalla_id) || - !ENGINE_set_name(e, engine_atalla_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &atalla_rsa) || -# endif -# ifndef OPENSSL_NO_DSA - !ENGINE_set_DSA(e, &atalla_dsa) || -# endif -# ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &atalla_dh) || -# endif - !ENGINE_set_destroy_function(e, atalla_destroy) || - !ENGINE_set_init_function(e, atalla_init) || - !ENGINE_set_finish_function(e, atalla_finish) || - !ENGINE_set_ctrl_function(e, atalla_ctrl) || - !ENGINE_set_cmd_defns(e, atalla_cmd_defns)) - return 0; - -# ifndef OPENSSL_NO_RSA - /* - * We know that the "PKCS1_SSLeay()" functions hook properly to the - * atalla-specific mod_exp and mod_exp_crt so we use those functions. NB: - * We don't use ENGINE_openssl() or anything "more generic" because - * something like the RSAref code may not hook properly, and if you own - * one of these cards then you have the right to do RSA operations on it - * anyway! - */ - meth1 = RSA_PKCS1_SSLeay(); - atalla_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - atalla_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - atalla_rsa.rsa_priv_enc = meth1->rsa_priv_enc; - atalla_rsa.rsa_priv_dec = meth1->rsa_priv_dec; -# endif - -# ifndef OPENSSL_NO_DSA - /* - * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits. - */ - meth2 = DSA_OpenSSL(); - atalla_dsa.dsa_do_sign = meth2->dsa_do_sign; - atalla_dsa.dsa_sign_setup = meth2->dsa_sign_setup; - atalla_dsa.dsa_do_verify = meth2->dsa_do_verify; -# endif - -# ifndef OPENSSL_NO_DH - /* Much the same for Diffie-Hellman */ - meth3 = DH_OpenSSL(); - atalla_dh.generate_key = meth3->generate_key; - atalla_dh.compute_key = meth3->compute_key; -# endif - - /* Ensure the atalla error handling is set up */ - ERR_load_ATALLA_strings(); - return 1; -} - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE -static ENGINE *engine_atalla(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_atalla(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_atalla(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -/* - * This is a process-global DSO handle used for loading and unloading the - * Atalla library. NB: This is only set (or unset) during an init() or - * finish() call (reference counts permitting) and they're operating with - * global locks, so this should be thread-safe implicitly. - */ -static DSO *atalla_dso = NULL; - -/* - * These are the function pointers that are (un)set when the library has - * successfully (un)loaded. - */ -static tfnASI_GetHardwareConfig *p_Atalla_GetHardwareConfig = NULL; -static tfnASI_RSAPrivateKeyOpFn *p_Atalla_RSAPrivateKeyOpFn = NULL; -static tfnASI_GetPerformanceStatistics *p_Atalla_GetPerformanceStatistics = - NULL; - -/* - * These are the static string constants for the DSO file name and the - * function symbol names to bind to. Regrettably, the DSO name on *nix - * appears to be "atasi.so" rather than something more consistent like - * "libatasi.so". At the time of writing, I'm not sure what the file name on - * win32 is but clearly native name translation is not possible (eg - * libatasi.so on *nix, and atasi.dll on win32). For the purposes of testing, - * I have created a symbollic link called "libatasi.so" so that we can use - * native name-translation - a better solution will be needed. - */ -static const char *ATALLA_LIBNAME = NULL; -static const char *get_ATALLA_LIBNAME(void) -{ - if (ATALLA_LIBNAME) - return ATALLA_LIBNAME; - return "atasi"; -} - -static void free_ATALLA_LIBNAME(void) -{ - if (ATALLA_LIBNAME) - OPENSSL_free((void *)ATALLA_LIBNAME); - ATALLA_LIBNAME = NULL; -} - -static long set_ATALLA_LIBNAME(const char *name) -{ - free_ATALLA_LIBNAME(); - return (((ATALLA_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); -} - -static const char *ATALLA_F1 = "ASI_GetHardwareConfig"; -static const char *ATALLA_F2 = "ASI_RSAPrivateKeyOpFn"; -static const char *ATALLA_F3 = "ASI_GetPerformanceStatistics"; - -/* Destructor (complements the "ENGINE_atalla()" constructor) */ -static int atalla_destroy(ENGINE *e) -{ - free_ATALLA_LIBNAME(); - /* - * Unload the atalla error strings so any error state including our - * functs or reasons won't lead to a segfault (they simply get displayed - * without corresponding string data because none will be found). - */ - ERR_unload_ATALLA_strings(); - return 1; -} - -/* (de)initialisation functions. */ -static int atalla_init(ENGINE *e) -{ - tfnASI_GetHardwareConfig *p1; - tfnASI_RSAPrivateKeyOpFn *p2; - tfnASI_GetPerformanceStatistics *p3; - /* - * Not sure of the origin of this magic value, but Ben's code had it and - * it seemed to have been working for a few people. :-) - */ - unsigned int config_buf[1024]; - - if (atalla_dso != NULL) { - ATALLAerr(ATALLA_F_ATALLA_INIT, ATALLA_R_ALREADY_LOADED); - goto err; - } - /* - * Attempt to load libatasi.so/atasi.dll/whatever. Needs to be changed - * unfortunately because the Atalla drivers don't have standard library - * names that can be platform-translated well. - */ - /* - * TODO: Work out how to actually map to the names the Atalla drivers - * really use - for now a symbollic link needs to be created on the host - * system from libatasi.so to atasi.so on unix variants. - */ - atalla_dso = DSO_load(NULL, get_ATALLA_LIBNAME(), NULL, 0); - if (atalla_dso == NULL) { - ATALLAerr(ATALLA_F_ATALLA_INIT, ATALLA_R_NOT_LOADED); - goto err; - } - if (! - (p1 = - (tfnASI_GetHardwareConfig *) DSO_bind_func(atalla_dso, ATALLA_F1)) -|| !(p2 = (tfnASI_RSAPrivateKeyOpFn *) DSO_bind_func(atalla_dso, ATALLA_F2)) -|| !(p3 = - (tfnASI_GetPerformanceStatistics *) DSO_bind_func(atalla_dso, - ATALLA_F3))) { - ATALLAerr(ATALLA_F_ATALLA_INIT, ATALLA_R_NOT_LOADED); - goto err; - } - /* Copy the pointers */ - p_Atalla_GetHardwareConfig = p1; - p_Atalla_RSAPrivateKeyOpFn = p2; - p_Atalla_GetPerformanceStatistics = p3; - /* - * Perform a basic test to see if there's actually any unit running. - */ - if (p1(0L, config_buf) != 0) { - ATALLAerr(ATALLA_F_ATALLA_INIT, ATALLA_R_UNIT_FAILURE); - goto err; - } - /* Everything's fine. */ - return 1; - err: - if (atalla_dso) - DSO_free(atalla_dso); - atalla_dso = NULL; - p_Atalla_GetHardwareConfig = NULL; - p_Atalla_RSAPrivateKeyOpFn = NULL; - p_Atalla_GetPerformanceStatistics = NULL; - return 0; -} - -static int atalla_finish(ENGINE *e) -{ - free_ATALLA_LIBNAME(); - if (atalla_dso == NULL) { - ATALLAerr(ATALLA_F_ATALLA_FINISH, ATALLA_R_NOT_LOADED); - return 0; - } - if (!DSO_free(atalla_dso)) { - ATALLAerr(ATALLA_F_ATALLA_FINISH, ATALLA_R_UNIT_FAILURE); - return 0; - } - atalla_dso = NULL; - p_Atalla_GetHardwareConfig = NULL; - p_Atalla_RSAPrivateKeyOpFn = NULL; - p_Atalla_GetPerformanceStatistics = NULL; - return 1; -} - -static int atalla_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int initialised = ((atalla_dso == NULL) ? 0 : 1); - switch (cmd) { - case ATALLA_CMD_SO_PATH: - if (p == NULL) { - ATALLAerr(ATALLA_F_ATALLA_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (initialised) { - ATALLAerr(ATALLA_F_ATALLA_CTRL, ATALLA_R_ALREADY_LOADED); - return 0; - } - return set_ATALLA_LIBNAME((const char *)p); - default: - break; - } - ATALLAerr(ATALLA_F_ATALLA_CTRL, ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED); - return 0; -} - -static int atalla_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - /* - * I need somewhere to store temporary serialised values for use with the - * Atalla API calls. A neat cheat - I'll use BIGNUMs from the BN_CTX but - * access their arrays directly as byte arrays . This way I don't - * have to clean anything up. - */ - BIGNUM *modulus; - BIGNUM *exponent; - BIGNUM *argument; - BIGNUM *result; - RSAPrivateKey keydata; - int to_return, numbytes; - - modulus = exponent = argument = result = NULL; - to_return = 0; /* expect failure */ - - if (!atalla_dso) { - ATALLAerr(ATALLA_F_ATALLA_MOD_EXP, ATALLA_R_NOT_LOADED); - goto err; - } - /* Prepare the params */ - BN_CTX_start(ctx); - modulus = BN_CTX_get(ctx); - exponent = BN_CTX_get(ctx); - argument = BN_CTX_get(ctx); - result = BN_CTX_get(ctx); - if (!result) { - ATALLAerr(ATALLA_F_ATALLA_MOD_EXP, ATALLA_R_BN_CTX_FULL); - goto err; - } - if (!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, m->top) || - !bn_wexpand(argument, m->top) || !bn_wexpand(result, m->top)) { - ATALLAerr(ATALLA_F_ATALLA_MOD_EXP, ATALLA_R_BN_EXPAND_FAIL); - goto err; - } - /* Prepare the key-data */ - memset(&keydata, 0, sizeof(keydata)); - numbytes = BN_num_bytes(m); - memset(exponent->d, 0, numbytes); - memset(modulus->d, 0, numbytes); - BN_bn2bin(p, (unsigned char *)exponent->d + numbytes - BN_num_bytes(p)); - BN_bn2bin(m, (unsigned char *)modulus->d + numbytes - BN_num_bytes(m)); - keydata.privateExponent.data = (unsigned char *)exponent->d; - keydata.privateExponent.len = numbytes; - keydata.modulus.data = (unsigned char *)modulus->d; - keydata.modulus.len = numbytes; - /* Prepare the argument */ - memset(argument->d, 0, numbytes); - memset(result->d, 0, numbytes); - BN_bn2bin(a, (unsigned char *)argument->d + numbytes - BN_num_bytes(a)); - /* Perform the operation */ - if (p_Atalla_RSAPrivateKeyOpFn(&keydata, (unsigned char *)result->d, - (unsigned char *)argument->d, - keydata.modulus.len) != 0) { - ATALLAerr(ATALLA_F_ATALLA_MOD_EXP, ATALLA_R_REQUEST_FAILED); - goto err; - } - /* Convert the response */ - BN_bin2bn((unsigned char *)result->d, numbytes, r); - to_return = 1; - err: - BN_CTX_end(ctx); - return to_return; -} - -# ifndef OPENSSL_NO_RSA -static int atalla_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx) -{ - int to_return = 0; - - if (!atalla_dso) { - ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP, ATALLA_R_NOT_LOADED); - goto err; - } - if (!rsa->d || !rsa->n) { - ATALLAerr(ATALLA_F_ATALLA_RSA_MOD_EXP, - ATALLA_R_MISSING_KEY_COMPONENTS); - goto err; - } - to_return = atalla_mod_exp(r0, I, rsa->d, rsa->n, ctx); - err: - return to_return; -} -# endif - -# ifndef OPENSSL_NO_DSA -/* - * This code was liberated and adapted from the commented-out code in - * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration (it - * doesn't have a CRT form for RSA), this function means that an Atalla - * system running with a DSA server certificate can handshake around 5 or 6 - * times faster/more than an equivalent system running with RSA. Just check - * out the "signs" statistics from the RSA and DSA parts of "openssl speed - * -engine atalla dsa1024 rsa1024". - */ -static int atalla_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, - BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *in_mont) -{ - BIGNUM t; - int to_return = 0; - - BN_init(&t); - /* let rr = a1 ^ p1 mod m */ - if (!atalla_mod_exp(rr, a1, p1, m, ctx)) - goto end; - /* let t = a2 ^ p2 mod m */ - if (!atalla_mod_exp(&t, a2, p2, m, ctx)) - goto end; - /* let rr = rr * t mod m */ - if (!BN_mod_mul(rr, rr, &t, m, ctx)) - goto end; - to_return = 1; - end: - BN_free(&t); - return to_return; -} - -static int atalla_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return atalla_mod_exp(r, a, p, m, ctx); -} -# endif - -# ifndef OPENSSL_NO_RSA -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int atalla_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return atalla_mod_exp(r, a, p, m, ctx); -} -# endif - -# ifndef OPENSSL_NO_DH -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int atalla_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return atalla_mod_exp(r, a, p, m, ctx); -} -# endif - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_atalla_id) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ -# endif /* !OPENSSL_NO_HW_ATALLA */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_atalla_err.c b/Sources/COpenSSL/e_atalla_err.c deleted file mode 100644 index de8cfce7..00000000 --- a/Sources/COpenSSL/e_atalla_err.c +++ /dev/null @@ -1,145 +0,0 @@ -/* e_atalla_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_atalla_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA ATALLA_str_functs[] = { - {ERR_FUNC(ATALLA_F_ATALLA_CTRL), "ATALLA_CTRL"}, - {ERR_FUNC(ATALLA_F_ATALLA_FINISH), "ATALLA_FINISH"}, - {ERR_FUNC(ATALLA_F_ATALLA_INIT), "ATALLA_INIT"}, - {ERR_FUNC(ATALLA_F_ATALLA_MOD_EXP), "ATALLA_MOD_EXP"}, - {ERR_FUNC(ATALLA_F_ATALLA_RSA_MOD_EXP), "ATALLA_RSA_MOD_EXP"}, - {0, NULL} -}; - -static ERR_STRING_DATA ATALLA_str_reasons[] = { - {ERR_REASON(ATALLA_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(ATALLA_R_BN_CTX_FULL), "bn ctx full"}, - {ERR_REASON(ATALLA_R_BN_EXPAND_FAIL), "bn expand fail"}, - {ERR_REASON(ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(ATALLA_R_MISSING_KEY_COMPONENTS), "missing key components"}, - {ERR_REASON(ATALLA_R_NOT_LOADED), "not loaded"}, - {ERR_REASON(ATALLA_R_REQUEST_FAILED), "request failed"}, - {ERR_REASON(ATALLA_R_UNIT_FAILURE), "unit failure"}, - {0, NULL} -}; - -#endif - -#ifdef ATALLA_LIB_NAME -static ERR_STRING_DATA ATALLA_lib_name[] = { - {0, ATALLA_LIB_NAME}, - {0, NULL} -}; -#endif - -static int ATALLA_lib_error_code = 0; -static int ATALLA_error_init = 1; - -static void ERR_load_ATALLA_strings(void) -{ - if (ATALLA_lib_error_code == 0) - ATALLA_lib_error_code = ERR_get_next_error_library(); - - if (ATALLA_error_init) { - ATALLA_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(ATALLA_lib_error_code, ATALLA_str_functs); - ERR_load_strings(ATALLA_lib_error_code, ATALLA_str_reasons); -#endif - -#ifdef ATALLA_LIB_NAME - ATALLA_lib_name->error = ERR_PACK(ATALLA_lib_error_code, 0, 0); - ERR_load_strings(0, ATALLA_lib_name); -#endif - } -} - -static void ERR_unload_ATALLA_strings(void) -{ - if (ATALLA_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(ATALLA_lib_error_code, ATALLA_str_functs); - ERR_unload_strings(ATALLA_lib_error_code, ATALLA_str_reasons); -#endif - -#ifdef ATALLA_LIB_NAME - ERR_unload_strings(0, ATALLA_lib_name); -#endif - ATALLA_error_init = 1; - } -} - -static void ERR_ATALLA_error(int function, int reason, char *file, int line) -{ - if (ATALLA_lib_error_code == 0) - ATALLA_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(ATALLA_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_atalla_err.h b/Sources/COpenSSL/e_atalla_err.h deleted file mode 100644 index 7b71eff4..00000000 --- a/Sources/COpenSSL/e_atalla_err.h +++ /dev/null @@ -1,94 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_ATALLA_ERR_H -# define HEADER_ATALLA_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_ATALLA_strings(void); -static void ERR_unload_ATALLA_strings(void); -static void ERR_ATALLA_error(int function, int reason, char *file, int line); -# define ATALLAerr(f,r) ERR_ATALLA_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the ATALLA functions. */ - -/* Function codes. */ -# define ATALLA_F_ATALLA_CTRL 100 -# define ATALLA_F_ATALLA_FINISH 101 -# define ATALLA_F_ATALLA_INIT 102 -# define ATALLA_F_ATALLA_MOD_EXP 103 -# define ATALLA_F_ATALLA_RSA_MOD_EXP 104 - -/* Reason codes. */ -# define ATALLA_R_ALREADY_LOADED 100 -# define ATALLA_R_BN_CTX_FULL 101 -# define ATALLA_R_BN_EXPAND_FAIL 102 -# define ATALLA_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 -# define ATALLA_R_MISSING_KEY_COMPONENTS 104 -# define ATALLA_R_NOT_LOADED 105 -# define ATALLA_R_REQUEST_FAILED 106 -# define ATALLA_R_UNIT_FAILURE 107 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_bf.c b/Sources/COpenSSL/e_bf.c deleted file mode 100644 index 2117651f..00000000 --- a/Sources/COpenSSL/e_bf.c +++ /dev/null @@ -1,87 +0,0 @@ -/* crypto/evp/e_bf.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#ifndef OPENSSL_NO_BF -# include "evp.h" -# include "evp_locl.h" -# include "objects.h" -# include "blowfish.h" - -static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - -typedef struct { - BF_KEY ks; -} EVP_BF_KEY; - -# define data(ctx) EVP_C_DATA(EVP_BF_KEY,ctx) - -IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64, - EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL, - EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) - -static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); - return 1; -} - -#endif diff --git a/Sources/COpenSSL/e_camellia.c b/Sources/COpenSSL/e_camellia.c deleted file mode 100644 index d896f7a1..00000000 --- a/Sources/COpenSSL/e_camellia.c +++ /dev/null @@ -1,396 +0,0 @@ -/* crypto/evp/e_camellia.c */ -/* ==================================================================== - * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "opensslconf.h" -#ifndef OPENSSL_NO_CAMELLIA -# include "evp.h" -# include "err.h" -# include -# include -# include "camellia.h" -# include "evp_locl.h" -# include "modes_lcl.h" - -static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - -/* Camellia subkey Structure */ -typedef struct { - CAMELLIA_KEY ks; - block128_f block; - union { - cbc128_f cbc; - ctr128_f ctr; - } stream; -} EVP_CAMELLIA_KEY; - -# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) - -/* Attribute operation for Camellia */ -# define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx) - -# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) -/* ---------^^^ this is not a typo, just a way to detect that - * assembler support was in general requested... */ -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; - -# define SPARC_CMLL_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_CAMELLIA) - -void cmll_t4_set_key(const unsigned char *key, int bits, CAMELLIA_KEY *ks); -void cmll_t4_encrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key); -void cmll_t4_decrypt(const unsigned char *in, unsigned char *out, - const CAMELLIA_KEY *key); - -void cmll128_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll128_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll256_t4_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll256_t4_cbc_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll128_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const CAMELLIA_KEY *key, - unsigned char *ivec); -void cmll256_t4_ctr32_encrypt(const unsigned char *in, unsigned char *out, - size_t blocks, const CAMELLIA_KEY *key, - unsigned char *ivec); - -static int cmll_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - int ret, mode, bits; - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - mode = ctx->cipher->flags & EVP_CIPH_MODE; - bits = ctx->key_len * 8; - - cmll_t4_set_key(key, bits, &dat->ks); - - if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) - && !enc) { - ret = 0; - dat->block = (block128_f) cmll_t4_decrypt; - switch (bits) { - case 128: - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) cmll128_t4_cbc_decrypt : NULL; - break; - case 192: - case 256: - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) cmll256_t4_cbc_decrypt : NULL; - break; - default: - ret = -1; - } - } else { - ret = 0; - dat->block = (block128_f) cmll_t4_encrypt; - switch (bits) { - case 128: - if (mode == EVP_CIPH_CBC_MODE) - dat->stream.cbc = (cbc128_f) cmll128_t4_cbc_encrypt; - else if (mode == EVP_CIPH_CTR_MODE) - dat->stream.ctr = (ctr128_f) cmll128_t4_ctr32_encrypt; - else - dat->stream.cbc = NULL; - break; - case 192: - case 256: - if (mode == EVP_CIPH_CBC_MODE) - dat->stream.cbc = (cbc128_f) cmll256_t4_cbc_encrypt; - else if (mode == EVP_CIPH_CTR_MODE) - dat->stream.ctr = (ctr128_f) cmll256_t4_ctr32_encrypt; - else - dat->stream.cbc = NULL; - break; - default: - ret = -1; - } - } - - if (ret < 0) { - EVPerr(EVP_F_CMLL_T4_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED); - return 0; - } - - return 1; -} - -# define cmll_t4_cbc_cipher camellia_cbc_cipher -static int cmll_t4_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define cmll_t4_ecb_cipher camellia_ecb_cipher -static int cmll_t4_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define cmll_t4_ofb_cipher camellia_ofb_cipher -static int cmll_t4_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define cmll_t4_cfb_cipher camellia_cfb_cipher -static int cmll_t4_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define cmll_t4_cfb8_cipher camellia_cfb8_cipher -static int cmll_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define cmll_t4_cfb1_cipher camellia_cfb1_cipher -static int cmll_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define cmll_t4_ctr_cipher camellia_ctr_cipher -static int cmll_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len); - -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ -static const EVP_CIPHER cmll_t4_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - cmll_t4_init_key, \ - cmll_t4_##mode##_cipher, \ - NULL, \ - sizeof(EVP_CAMELLIA_KEY), \ - NULL,NULL,NULL,NULL }; \ -static const EVP_CIPHER camellia_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize, \ - keylen/8,ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - camellia_init_key, \ - camellia_##mode##_cipher, \ - NULL, \ - sizeof(EVP_CAMELLIA_KEY), \ - NULL,NULL,NULL,NULL }; \ -const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \ -{ return SPARC_CMLL_CAPABLE?&cmll_t4_##keylen##_##mode:&camellia_##keylen##_##mode; } - -# else - -# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ -static const EVP_CIPHER camellia_##keylen##_##mode = { \ - nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ - flags|EVP_CIPH_##MODE##_MODE, \ - camellia_init_key, \ - camellia_##mode##_cipher, \ - NULL, \ - sizeof(EVP_CAMELLIA_KEY), \ - NULL,NULL,NULL,NULL }; \ -const EVP_CIPHER *EVP_camellia_##keylen##_##mode(void) \ -{ return &camellia_##keylen##_##mode; } - -# endif - -# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ - BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ - BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \ - BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) -# if 0 /* not yet, missing NID */ -BLOCK_CIPHER_generic(nid, keylen, 1, 16, ctr, ctr, CTR, flags) -# endif -/* The subkey for Camellia is generated. */ -static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - int ret, mode; - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - ret = Camellia_set_key(key, ctx->key_len * 8, &dat->ks); - if (ret < 0) { - EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED); - return 0; - } - - mode = ctx->cipher->flags & EVP_CIPH_MODE; - if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) - && !enc) { - dat->block = (block128_f) Camellia_decrypt; - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) Camellia_cbc_encrypt : NULL; - } else { - dat->block = (block128_f) Camellia_encrypt; - dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? - (cbc128_f) Camellia_cbc_encrypt : NULL; - } - - return 1; -} - -static int camellia_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - if (dat->stream.cbc) - (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt); - else if (ctx->encrypt) - CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); - else - CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block); - - return 1; -} - -static int camellia_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - size_t bl = ctx->cipher->block_size; - size_t i; - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - if (len < bl) - return 1; - - for (i = 0, len -= bl; i <= len; i += bl) - (*dat->block) (in + i, out + i, &dat->ks); - - return 1; -} - -static int camellia_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, - ctx->iv, &ctx->num, dat->block); - return 1; -} - -static int camellia_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - return 1; -} - -static int camellia_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - return 1; -} - -static int camellia_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) { - CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - return 1; - } - - while (len >= MAXBITCHUNK) { - CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - len -= MAXBITCHUNK; - out += MAXBITCHUNK; - in += MAXBITCHUNK; - } - if (len) - CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, - ctx->iv, &ctx->num, ctx->encrypt, dat->block); - - return 1; -} - -# if 0 /* not yet, missing NID */ -static int camellia_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - unsigned int num = ctx->num; - EVP_CAMELLIA_KEY *dat = (EVP_CAMELLIA_KEY *) ctx->cipher_data; - - if (dat->stream.ctr) - CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, - ctx->iv, ctx->buf, &num, dat->stream.ctr); - else - CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, - ctx->iv, ctx->buf, &num, dat->block); - ctx->num = (size_t)num; - return 1; -} -# endif - -BLOCK_CIPHER_generic_pack(NID_camellia, 128, 0) - BLOCK_CIPHER_generic_pack(NID_camellia, 192, 0) - BLOCK_CIPHER_generic_pack(NID_camellia, 256, 0) -#else - -# ifdef PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/Sources/COpenSSL/e_capi.c b/Sources/COpenSSL/e_capi.c deleted file mode 100644 index c02bd6b0..00000000 --- a/Sources/COpenSSL/e_capi.c +++ /dev/null @@ -1,1909 +0,0 @@ -/* engines/e_capi.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2008-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include -#include -#include - -#include "crypto.h" - -#ifdef OPENSSL_SYS_WIN32 -# ifndef OPENSSL_NO_CAPIENG - -# include "buffer.h" -# include "bn.h" -# include "rsa.h" - -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -# endif - -# include -# include -# include -# ifndef alloca -# define alloca _alloca -# endif - -/* - * This module uses several "new" interfaces, among which is - * CertGetCertificateContextProperty. CERT_KEY_PROV_INFO_PROP_ID is - * one of possible values you can pass to function in question. By - * checking if it's defined we can see if wincrypt.h and accompanying - * crypt32.lib are in shape. The native MingW32 headers up to and - * including __W32API_VERSION 3.14 lack of struct DSSPUBKEY and the - * defines CERT_STORE_PROV_SYSTEM_A and CERT_STORE_READONLY_FLAG, - * so we check for these too and avoid compiling. - * Yes, it's rather "weak" test and if compilation fails, - * then re-configure with -DOPENSSL_NO_CAPIENG. - */ -# if defined(CERT_KEY_PROV_INFO_PROP_ID) && \ - defined(CERT_STORE_PROV_SYSTEM_A) && \ - defined(CERT_STORE_READONLY_FLAG) -# define __COMPILE_CAPIENG -# endif /* CERT_KEY_PROV_INFO_PROP_ID */ -# endif /* OPENSSL_NO_CAPIENG */ -#endif /* OPENSSL_SYS_WIN32 */ - -#ifdef __COMPILE_CAPIENG - -# undef X509_EXTENSIONS -# undef X509_CERT_PAIR - -/* Definitions which may be missing from earlier version of headers */ -# ifndef CERT_STORE_OPEN_EXISTING_FLAG -# define CERT_STORE_OPEN_EXISTING_FLAG 0x00004000 -# endif - -# ifndef CERT_STORE_CREATE_NEW_FLAG -# define CERT_STORE_CREATE_NEW_FLAG 0x00002000 -# endif - -# ifndef CERT_SYSTEM_STORE_CURRENT_USER -# define CERT_SYSTEM_STORE_CURRENT_USER 0x00010000 -# endif - -# ifndef ALG_SID_SHA_256 -# define ALG_SID_SHA_256 12 -# endif -# ifndef ALG_SID_SHA_384 -# define ALG_SID_SHA_384 13 -# endif -# ifndef ALG_SID_SHA_512 -# define ALG_SID_SHA_512 14 -# endif - -# ifndef CALG_SHA_256 -# define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256) -# endif -# ifndef CALG_SHA_384 -# define CALG_SHA_384 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_384) -# endif -# ifndef CALG_SHA_512 -# define CALG_SHA_512 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_512) -# endif - -# include "engine.h" -# include "pem.h" -# include "x509v3.h" - -# include "e_capi_err.h" -# include "e_capi_err.c" - -static const char *engine_capi_id = "capi"; -static const char *engine_capi_name = "CryptoAPI ENGINE"; - -typedef struct CAPI_CTX_st CAPI_CTX; -typedef struct CAPI_KEY_st CAPI_KEY; - -static void capi_addlasterror(void); -static void capi_adderror(DWORD err); - -static void CAPI_trace(CAPI_CTX * ctx, char *format, ...); - -static int capi_list_providers(CAPI_CTX * ctx, BIO *out); -static int capi_list_containers(CAPI_CTX * ctx, BIO *out); -int capi_list_certs(CAPI_CTX * ctx, BIO *out, char *storename); -void capi_free_key(CAPI_KEY * key); - -static PCCERT_CONTEXT capi_find_cert(CAPI_CTX * ctx, const char *id, - HCERTSTORE hstore); - -CAPI_KEY *capi_find_key(CAPI_CTX * ctx, const char *id); - -static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, void *callback_data); -static int capi_rsa_sign(int dtype, const unsigned char *m, - unsigned int m_len, unsigned char *sigret, - unsigned int *siglen, const RSA *rsa); -static int capi_rsa_priv_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int capi_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int capi_rsa_free(RSA *rsa); - -static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, - DSA *dsa); -static int capi_dsa_free(DSA *dsa); - -static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, - STACK_OF(X509_NAME) *ca_dn, X509 **pcert, - EVP_PKEY **pkey, STACK_OF(X509) **pother, - UI_METHOD *ui_method, - void *callback_data); - -static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); -# ifdef OPENSSL_CAPIENG_DIALOG -static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); -# endif - -typedef PCCERT_CONTEXT(WINAPI *CERTDLG) (HCERTSTORE, HWND, LPCWSTR, - LPCWSTR, DWORD, DWORD, void *); -typedef HWND(WINAPI *GETCONSWIN) (void); - -/* - * This structure contains CAPI ENGINE specific data: it contains various - * global options and affects how other functions behave. - */ - -# define CAPI_DBG_TRACE 2 -# define CAPI_DBG_ERROR 1 - -struct CAPI_CTX_st { - int debug_level; - char *debug_file; - /* Parameters to use for container lookup */ - DWORD keytype; - LPSTR cspname; - DWORD csptype; - /* Certificate store name to use */ - LPSTR storename; - LPSTR ssl_client_store; - /* System store flags */ - DWORD store_flags; -/* Lookup string meanings in load_private_key */ -/* Substring of subject: uses "storename" */ -# define CAPI_LU_SUBSTR 1 -/* Friendly name: uses storename */ -# define CAPI_LU_FNAME 2 -/* Container name: uses cspname, keytype */ -# define CAPI_LU_CONTNAME 3 - int lookup_method; -/* Info to dump with dumpcerts option */ -/* Issuer and serial name strings */ -# define CAPI_DMP_SUMMARY 0x1 -/* Friendly name */ -# define CAPI_DMP_FNAME 0x2 -/* Full X509_print dump */ -# define CAPI_DMP_FULL 0x4 -/* Dump PEM format certificate */ -# define CAPI_DMP_PEM 0x8 -/* Dump pseudo key (if possible) */ -# define CAPI_DMP_PSKEY 0x10 -/* Dump key info (if possible) */ -# define CAPI_DMP_PKEYINFO 0x20 - DWORD dump_flags; - int (*client_cert_select) (ENGINE *e, SSL *ssl, STACK_OF(X509) *certs); - CERTDLG certselectdlg; - GETCONSWIN getconswindow; -}; - -static CAPI_CTX *capi_ctx_new(); -static void capi_ctx_free(CAPI_CTX * ctx); -static int capi_ctx_set_provname(CAPI_CTX * ctx, LPSTR pname, DWORD type, - int check); -static int capi_ctx_set_provname_idx(CAPI_CTX * ctx, int idx); - -# define CAPI_CMD_LIST_CERTS ENGINE_CMD_BASE -# define CAPI_CMD_LOOKUP_CERT (ENGINE_CMD_BASE + 1) -# define CAPI_CMD_DEBUG_LEVEL (ENGINE_CMD_BASE + 2) -# define CAPI_CMD_DEBUG_FILE (ENGINE_CMD_BASE + 3) -# define CAPI_CMD_KEYTYPE (ENGINE_CMD_BASE + 4) -# define CAPI_CMD_LIST_CSPS (ENGINE_CMD_BASE + 5) -# define CAPI_CMD_SET_CSP_IDX (ENGINE_CMD_BASE + 6) -# define CAPI_CMD_SET_CSP_NAME (ENGINE_CMD_BASE + 7) -# define CAPI_CMD_SET_CSP_TYPE (ENGINE_CMD_BASE + 8) -# define CAPI_CMD_LIST_CONTAINERS (ENGINE_CMD_BASE + 9) -# define CAPI_CMD_LIST_OPTIONS (ENGINE_CMD_BASE + 10) -# define CAPI_CMD_LOOKUP_METHOD (ENGINE_CMD_BASE + 11) -# define CAPI_CMD_STORE_NAME (ENGINE_CMD_BASE + 12) -# define CAPI_CMD_STORE_FLAGS (ENGINE_CMD_BASE + 13) - -static const ENGINE_CMD_DEFN capi_cmd_defns[] = { - {CAPI_CMD_LIST_CERTS, - "list_certs", - "List all certificates in store", - ENGINE_CMD_FLAG_NO_INPUT}, - {CAPI_CMD_LOOKUP_CERT, - "lookup_cert", - "Lookup and output certificates", - ENGINE_CMD_FLAG_STRING}, - {CAPI_CMD_DEBUG_LEVEL, - "debug_level", - "debug level (1=errors, 2=trace)", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_DEBUG_FILE, - "debug_file", - "debugging filename)", - ENGINE_CMD_FLAG_STRING}, - {CAPI_CMD_KEYTYPE, - "key_type", - "Key type: 1=AT_KEYEXCHANGE (default), 2=AT_SIGNATURE", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_LIST_CSPS, - "list_csps", - "List all CSPs", - ENGINE_CMD_FLAG_NO_INPUT}, - {CAPI_CMD_SET_CSP_IDX, - "csp_idx", - "Set CSP by index", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_SET_CSP_NAME, - "csp_name", - "Set CSP name, (default CSP used if not specified)", - ENGINE_CMD_FLAG_STRING}, - {CAPI_CMD_SET_CSP_TYPE, - "csp_type", - "Set CSP type, (default RSA_PROV_FULL)", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_LIST_CONTAINERS, - "list_containers", - "list container names", - ENGINE_CMD_FLAG_NO_INPUT}, - {CAPI_CMD_LIST_OPTIONS, - "list_options", - "Set list options (1=summary,2=friendly name, 4=full printout, 8=PEM output, 16=XXX, " - "32=private key info)", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_LOOKUP_METHOD, - "lookup_method", - "Set key lookup method (1=substring, 2=friendlyname, 3=container name)", - ENGINE_CMD_FLAG_NUMERIC}, - {CAPI_CMD_STORE_NAME, - "store_name", - "certificate store name, default \"MY\"", - ENGINE_CMD_FLAG_STRING}, - {CAPI_CMD_STORE_FLAGS, - "store_flags", - "Certificate store flags: 1 = system store", - ENGINE_CMD_FLAG_NUMERIC}, - - {0, NULL, NULL, 0} -}; - -static int capi_idx = -1; -static int rsa_capi_idx = -1; -static int dsa_capi_idx = -1; -static int cert_capi_idx = -1; - -static int capi_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int ret = 1; - CAPI_CTX *ctx; - BIO *out; - if (capi_idx == -1) { - CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_ENGINE_NOT_INITIALIZED); - return 0; - } - ctx = ENGINE_get_ex_data(e, capi_idx); - out = BIO_new_fp(stdout, BIO_NOCLOSE); - switch (cmd) { - case CAPI_CMD_LIST_CSPS: - ret = capi_list_providers(ctx, out); - break; - - case CAPI_CMD_LIST_CERTS: - ret = capi_list_certs(ctx, out, NULL); - break; - - case CAPI_CMD_LOOKUP_CERT: - ret = capi_list_certs(ctx, out, p); - break; - - case CAPI_CMD_LIST_CONTAINERS: - ret = capi_list_containers(ctx, out); - break; - - case CAPI_CMD_STORE_NAME: - if (ctx->storename) - OPENSSL_free(ctx->storename); - ctx->storename = BUF_strdup(p); - CAPI_trace(ctx, "Setting store name to %s\n", p); - break; - - case CAPI_CMD_STORE_FLAGS: - if (i & 1) { - ctx->store_flags |= CERT_SYSTEM_STORE_LOCAL_MACHINE; - ctx->store_flags &= ~CERT_SYSTEM_STORE_CURRENT_USER; - } else { - ctx->store_flags |= CERT_SYSTEM_STORE_CURRENT_USER; - ctx->store_flags &= ~CERT_SYSTEM_STORE_LOCAL_MACHINE; - } - CAPI_trace(ctx, "Setting flags to %d\n", i); - break; - - case CAPI_CMD_DEBUG_LEVEL: - ctx->debug_level = (int)i; - CAPI_trace(ctx, "Setting debug level to %d\n", ctx->debug_level); - break; - - case CAPI_CMD_DEBUG_FILE: - ctx->debug_file = BUF_strdup(p); - CAPI_trace(ctx, "Setting debug file to %s\n", ctx->debug_file); - break; - - case CAPI_CMD_KEYTYPE: - ctx->keytype = i; - CAPI_trace(ctx, "Setting key type to %d\n", ctx->keytype); - break; - - case CAPI_CMD_SET_CSP_IDX: - ret = capi_ctx_set_provname_idx(ctx, i); - break; - - case CAPI_CMD_LIST_OPTIONS: - ctx->dump_flags = i; - break; - - case CAPI_CMD_LOOKUP_METHOD: - if (i < 1 || i > 3) { - CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_INVALID_LOOKUP_METHOD); - return 0; - } - ctx->lookup_method = i; - break; - - case CAPI_CMD_SET_CSP_NAME: - ret = capi_ctx_set_provname(ctx, p, ctx->csptype, 1); - break; - - case CAPI_CMD_SET_CSP_TYPE: - ctx->csptype = i; - break; - - default: - CAPIerr(CAPI_F_CAPI_CTRL, CAPI_R_UNKNOWN_COMMAND); - ret = 0; - } - - BIO_free(out); - return ret; - -} - -static RSA_METHOD capi_rsa_method = { - "CryptoAPI RSA method", - 0, /* pub_enc */ - 0, /* pub_dec */ - capi_rsa_priv_enc, /* priv_enc */ - capi_rsa_priv_dec, /* priv_dec */ - 0, /* rsa_mod_exp */ - 0, /* bn_mod_exp */ - 0, /* init */ - capi_rsa_free, /* finish */ - RSA_FLAG_SIGN_VER, /* flags */ - NULL, /* app_data */ - capi_rsa_sign, /* rsa_sign */ - 0 /* rsa_verify */ -}; - -static DSA_METHOD capi_dsa_method = { - "CryptoAPI DSA method", - capi_dsa_do_sign, /* dsa_do_sign */ - 0, /* dsa_sign_setup */ - 0, /* dsa_do_verify */ - 0, /* dsa_mod_exp */ - 0, /* bn_mod_exp */ - 0, /* init */ - capi_dsa_free, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - 0, /* dsa_paramgen */ - 0 /* dsa_keygen */ -}; - -static int capi_init(ENGINE *e) -{ - CAPI_CTX *ctx; - const RSA_METHOD *ossl_rsa_meth; - const DSA_METHOD *ossl_dsa_meth; - - if (capi_idx < 0) { - capi_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, 0); - if (capi_idx < 0) - goto memerr; - - cert_capi_idx = X509_get_ex_new_index(0, NULL, NULL, NULL, 0); - - /* Setup RSA_METHOD */ - rsa_capi_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, 0); - ossl_rsa_meth = RSA_PKCS1_SSLeay(); - capi_rsa_method.rsa_pub_enc = ossl_rsa_meth->rsa_pub_enc; - capi_rsa_method.rsa_pub_dec = ossl_rsa_meth->rsa_pub_dec; - capi_rsa_method.rsa_mod_exp = ossl_rsa_meth->rsa_mod_exp; - capi_rsa_method.bn_mod_exp = ossl_rsa_meth->bn_mod_exp; - - /* Setup DSA Method */ - dsa_capi_idx = DSA_get_ex_new_index(0, NULL, NULL, NULL, 0); - ossl_dsa_meth = DSA_OpenSSL(); - capi_dsa_method.dsa_do_verify = ossl_dsa_meth->dsa_do_verify; - capi_dsa_method.dsa_mod_exp = ossl_dsa_meth->dsa_mod_exp; - capi_dsa_method.bn_mod_exp = ossl_dsa_meth->bn_mod_exp; - } - - ctx = capi_ctx_new(); - if (!ctx) - goto memerr; - - ENGINE_set_ex_data(e, capi_idx, ctx); - -# ifdef OPENSSL_CAPIENG_DIALOG - { - HMODULE cryptui = LoadLibrary(TEXT("CRYPTUI.DLL")); - HMODULE kernel = GetModuleHandle(TEXT("KERNEL32.DLL")); - if (cryptui) - ctx->certselectdlg = - (CERTDLG) GetProcAddress(cryptui, - "CryptUIDlgSelectCertificateFromStore"); - if (kernel) - ctx->getconswindow = - (GETCONSWIN) GetProcAddress(kernel, "GetConsoleWindow"); - if (cryptui && !OPENSSL_isservice()) - ctx->client_cert_select = cert_select_dialog; - } -# endif - - return 1; - - memerr: - CAPIerr(CAPI_F_CAPI_INIT, ERR_R_MALLOC_FAILURE); - return 0; - - return 1; -} - -static int capi_destroy(ENGINE *e) -{ - ERR_unload_CAPI_strings(); - return 1; -} - -static int capi_finish(ENGINE *e) -{ - CAPI_CTX *ctx; - ctx = ENGINE_get_ex_data(e, capi_idx); - capi_ctx_free(ctx); - ENGINE_set_ex_data(e, capi_idx, NULL); - return 1; -} - -/* - * CryptoAPI key application data. This contains a handle to the private key - * container (for sign operations) and a handle to the key (for decrypt - * operations). - */ - -struct CAPI_KEY_st { - /* Associated certificate context (if any) */ - PCCERT_CONTEXT pcert; - HCRYPTPROV hprov; - HCRYPTKEY key; - DWORD keyspec; -}; - -static int bind_capi(ENGINE *e) -{ - if (!ENGINE_set_id(e, engine_capi_id) - || !ENGINE_set_name(e, engine_capi_name) - || !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) - || !ENGINE_set_init_function(e, capi_init) - || !ENGINE_set_finish_function(e, capi_finish) - || !ENGINE_set_destroy_function(e, capi_destroy) - || !ENGINE_set_RSA(e, &capi_rsa_method) - || !ENGINE_set_DSA(e, &capi_dsa_method) - || !ENGINE_set_load_privkey_function(e, capi_load_privkey) - || !ENGINE_set_load_ssl_client_cert_function(e, - capi_load_ssl_client_cert) - || !ENGINE_set_cmd_defns(e, capi_cmd_defns) - || !ENGINE_set_ctrl_function(e, capi_ctrl)) - return 0; - ERR_load_CAPI_strings(); - - return 1; - -} - -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_helper(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_capi_id) != 0)) - return 0; - if (!bind_capi(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) -# else -static ENGINE *engine_capi(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_capi(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_capi(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_capi(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -static int lend_tobn(BIGNUM *bn, unsigned char *bin, int binlen) -{ - int i; - /* - * Reverse buffer in place: since this is a keyblob structure that will - * be freed up after conversion anyway it doesn't matter if we change - * it. - */ - for (i = 0; i < binlen / 2; i++) { - unsigned char c; - c = bin[i]; - bin[i] = bin[binlen - i - 1]; - bin[binlen - i - 1] = c; - } - - if (!BN_bin2bn(bin, binlen, bn)) - return 0; - return 1; -} - -/* Given a CAPI_KEY get an EVP_PKEY structure */ - -static EVP_PKEY *capi_get_pkey(ENGINE *eng, CAPI_KEY * key) -{ - unsigned char *pubkey = NULL; - DWORD len; - BLOBHEADER *bh; - RSA *rkey = NULL; - DSA *dkey = NULL; - EVP_PKEY *ret = NULL; - if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, NULL, &len)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR); - capi_addlasterror(); - return NULL; - } - - pubkey = OPENSSL_malloc(len); - - if (!pubkey) - goto memerr; - - if (!CryptExportKey(key->key, 0, PUBLICKEYBLOB, 0, pubkey, &len)) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_PUBKEY_EXPORT_ERROR); - capi_addlasterror(); - goto err; - } - - bh = (BLOBHEADER *) pubkey; - if (bh->bType != PUBLICKEYBLOB) { - CAPIerr(CAPI_F_CAPI_GET_PKEY, CAPI_R_INVALID_PUBLIC_KEY_BLOB); - goto err; - } - if (bh->aiKeyAlg == CALG_RSA_SIGN || bh->aiKeyAlg == CALG_RSA_KEYX) { - RSAPUBKEY *rp; - DWORD rsa_modlen; - unsigned char *rsa_modulus; - rp = (RSAPUBKEY *) (bh + 1); - if (rp->magic != 0x31415352) { - char magstr[10]; - BIO_snprintf(magstr, 10, "%lx", rp->magic); - CAPIerr(CAPI_F_CAPI_GET_PKEY, - CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); - ERR_add_error_data(2, "magic=0x", magstr); - goto err; - } - rsa_modulus = (unsigned char *)(rp + 1); - rkey = RSA_new_method(eng); - if (!rkey) - goto memerr; - - rkey->e = BN_new(); - rkey->n = BN_new(); - - if (!rkey->e || !rkey->n) - goto memerr; - - if (!BN_set_word(rkey->e, rp->pubexp)) - goto memerr; - - rsa_modlen = rp->bitlen / 8; - if (!lend_tobn(rkey->n, rsa_modulus, rsa_modlen)) - goto memerr; - - RSA_set_ex_data(rkey, rsa_capi_idx, key); - - if (!(ret = EVP_PKEY_new())) - goto memerr; - - EVP_PKEY_assign_RSA(ret, rkey); - rkey = NULL; - - } else if (bh->aiKeyAlg == CALG_DSS_SIGN) { - DSSPUBKEY *dp; - DWORD dsa_plen; - unsigned char *btmp; - dp = (DSSPUBKEY *) (bh + 1); - if (dp->magic != 0x31535344) { - char magstr[10]; - BIO_snprintf(magstr, 10, "%lx", dp->magic); - CAPIerr(CAPI_F_CAPI_GET_PKEY, - CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER); - ERR_add_error_data(2, "magic=0x", magstr); - goto err; - } - dsa_plen = dp->bitlen / 8; - btmp = (unsigned char *)(dp + 1); - dkey = DSA_new_method(eng); - if (!dkey) - goto memerr; - dkey->p = BN_new(); - dkey->q = BN_new(); - dkey->g = BN_new(); - dkey->pub_key = BN_new(); - if (!dkey->p || !dkey->q || !dkey->g || !dkey->pub_key) - goto memerr; - if (!lend_tobn(dkey->p, btmp, dsa_plen)) - goto memerr; - btmp += dsa_plen; - if (!lend_tobn(dkey->q, btmp, 20)) - goto memerr; - btmp += 20; - if (!lend_tobn(dkey->g, btmp, dsa_plen)) - goto memerr; - btmp += dsa_plen; - if (!lend_tobn(dkey->pub_key, btmp, dsa_plen)) - goto memerr; - btmp += dsa_plen; - - DSA_set_ex_data(dkey, dsa_capi_idx, key); - - if (!(ret = EVP_PKEY_new())) - goto memerr; - - EVP_PKEY_assign_DSA(ret, dkey); - dkey = NULL; - } else { - char algstr[10]; - BIO_snprintf(algstr, 10, "%lx", bh->aiKeyAlg); - CAPIerr(CAPI_F_CAPI_GET_PKEY, - CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM); - ERR_add_error_data(2, "aiKeyAlg=0x", algstr); - goto err; - } - - err: - if (pubkey) - OPENSSL_free(pubkey); - if (!ret) { - if (rkey) - RSA_free(rkey); - if (dkey) - DSA_free(dkey); - } - - return ret; - - memerr: - CAPIerr(CAPI_F_CAPI_GET_PKEY, ERR_R_MALLOC_FAILURE); - goto err; - -} - -static EVP_PKEY *capi_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, void *callback_data) -{ - CAPI_CTX *ctx; - CAPI_KEY *key; - EVP_PKEY *ret; - ctx = ENGINE_get_ex_data(eng, capi_idx); - - if (!ctx) { - CAPIerr(CAPI_F_CAPI_LOAD_PRIVKEY, CAPI_R_CANT_FIND_CAPI_CONTEXT); - return NULL; - } - - key = capi_find_key(ctx, key_id); - - if (!key) - return NULL; - - ret = capi_get_pkey(eng, key); - - if (!ret) - capi_free_key(key); - return ret; - -} - -/* CryptoAPI RSA operations */ - -int capi_rsa_priv_enc(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - CAPIerr(CAPI_F_CAPI_RSA_PRIV_ENC, CAPI_R_FUNCTION_NOT_SUPPORTED); - return -1; -} - -int capi_rsa_sign(int dtype, const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, const RSA *rsa) -{ - ALG_ID alg; - HCRYPTHASH hash; - DWORD slen; - unsigned int i; - int ret = -1; - CAPI_KEY *capi_key; - CAPI_CTX *ctx; - - ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); - - CAPI_trace(ctx, "Called CAPI_rsa_sign()\n"); - - capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); - if (!capi_key) { - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_GET_KEY); - return -1; - } -/* Convert the signature type to a CryptoAPI algorithm ID */ - switch (dtype) { - case NID_sha256: - alg = CALG_SHA_256; - break; - - case NID_sha384: - alg = CALG_SHA_384; - break; - - case NID_sha512: - alg = CALG_SHA_512; - break; - - case NID_sha1: - alg = CALG_SHA1; - break; - - case NID_md5: - alg = CALG_MD5; - break; - - case NID_md5_sha1: - alg = CALG_SSL3_SHAMD5; - break; - default: - { - char algstr[10]; - BIO_snprintf(algstr, 10, "%lx", dtype); - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_UNSUPPORTED_ALGORITHM_NID); - ERR_add_error_data(2, "NID=0x", algstr); - return -1; - } - } - -/* Create the hash object */ - if (!CryptCreateHash(capi_key->hprov, alg, 0, 0, &hash)) { - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); - capi_addlasterror(); - return -1; - } -/* Set the hash value to the value passed */ - - if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)m, 0)) { - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_CANT_SET_HASH_VALUE); - capi_addlasterror(); - goto err; - } - -/* Finally sign it */ - slen = RSA_size(rsa); - if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, sigret, &slen)) { - CAPIerr(CAPI_F_CAPI_RSA_SIGN, CAPI_R_ERROR_SIGNING_HASH); - capi_addlasterror(); - goto err; - } else { - ret = 1; - /* Inplace byte reversal of signature */ - for (i = 0; i < slen / 2; i++) { - unsigned char c; - c = sigret[i]; - sigret[i] = sigret[slen - i - 1]; - sigret[slen - i - 1] = c; - } - *siglen = slen; - } - - /* Now cleanup */ - - err: - CryptDestroyHash(hash); - - return ret; -} - -int capi_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - int i; - unsigned char *tmpbuf; - CAPI_KEY *capi_key; - CAPI_CTX *ctx; - DWORD flags = 0; - - ctx = ENGINE_get_ex_data(rsa->engine, capi_idx); - - CAPI_trace(ctx, "Called capi_rsa_priv_dec()\n"); - - capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); - if (!capi_key) { - CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_CANT_GET_KEY); - return -1; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - /* Nothing to do */ - break; -#ifdef CRYPT_DECRYPT_RSA_NO_PADDING_CHECK - case RSA_NO_PADDING: - flags = CRYPT_DECRYPT_RSA_NO_PADDING_CHECK; - break; -#endif - default: - { - char errstr[10]; - BIO_snprintf(errstr, 10, "%d", padding); - CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_UNSUPPORTED_PADDING); - ERR_add_error_data(2, "padding=", errstr); - return -1; - } - } - - /* Create temp reverse order version of input */ - if (!(tmpbuf = OPENSSL_malloc(flen))) { - CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, ERR_R_MALLOC_FAILURE); - return -1; - } - for (i = 0; i < flen; i++) - tmpbuf[flen - i - 1] = from[i]; - - /* Finally decrypt it */ - if (!CryptDecrypt(capi_key->key, 0, TRUE, flags, tmpbuf, &flen)) { - CAPIerr(CAPI_F_CAPI_RSA_PRIV_DEC, CAPI_R_DECRYPT_ERROR); - capi_addlasterror(); - OPENSSL_cleanse(tmpbuf, flen); - OPENSSL_free(tmpbuf); - return -1; - } else { - memcpy(to, tmpbuf, flen); - } - - OPENSSL_cleanse(tmpbuf, flen); - OPENSSL_free(tmpbuf); - - return flen; -} - -static int capi_rsa_free(RSA *rsa) -{ - CAPI_KEY *capi_key; - capi_key = RSA_get_ex_data(rsa, rsa_capi_idx); - capi_free_key(capi_key); - RSA_set_ex_data(rsa, rsa_capi_idx, 0); - return 1; -} - -/* CryptoAPI DSA operations */ - -static DSA_SIG *capi_dsa_do_sign(const unsigned char *digest, int dlen, - DSA *dsa) -{ - HCRYPTHASH hash; - DWORD slen; - DSA_SIG *ret = NULL; - CAPI_KEY *capi_key; - CAPI_CTX *ctx; - unsigned char csigbuf[40]; - - ctx = ENGINE_get_ex_data(dsa->engine, capi_idx); - - CAPI_trace(ctx, "Called CAPI_dsa_do_sign()\n"); - - capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); - - if (!capi_key) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_GET_KEY); - return NULL; - } - - if (dlen != 20) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_INVALID_DIGEST_LENGTH); - return NULL; - } - - /* Create the hash object */ - if (!CryptCreateHash(capi_key->hprov, CALG_SHA1, 0, 0, &hash)) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_CREATE_HASH_OBJECT); - capi_addlasterror(); - return NULL; - } - - /* Set the hash value to the value passed */ - if (!CryptSetHashParam(hash, HP_HASHVAL, (unsigned char *)digest, 0)) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_CANT_SET_HASH_VALUE); - capi_addlasterror(); - goto err; - } - - /* Finally sign it */ - slen = sizeof(csigbuf); - if (!CryptSignHash(hash, capi_key->keyspec, NULL, 0, csigbuf, &slen)) { - CAPIerr(CAPI_F_CAPI_DSA_DO_SIGN, CAPI_R_ERROR_SIGNING_HASH); - capi_addlasterror(); - goto err; - } else { - ret = DSA_SIG_new(); - if (!ret) - goto err; - ret->r = BN_new(); - ret->s = BN_new(); - if (!ret->r || !ret->s) - goto err; - if (!lend_tobn(ret->r, csigbuf, 20) - || !lend_tobn(ret->s, csigbuf + 20, 20)) { - DSA_SIG_free(ret); - ret = NULL; - goto err; - } - } - - /* Now cleanup */ - - err: - OPENSSL_cleanse(csigbuf, 40); - CryptDestroyHash(hash); - return ret; -} - -static int capi_dsa_free(DSA *dsa) -{ - CAPI_KEY *capi_key; - capi_key = DSA_get_ex_data(dsa, dsa_capi_idx); - capi_free_key(capi_key); - DSA_set_ex_data(dsa, dsa_capi_idx, 0); - return 1; -} - -static void capi_vtrace(CAPI_CTX * ctx, int level, char *format, - va_list argptr) -{ - BIO *out; - - if (!ctx || (ctx->debug_level < level) || (!ctx->debug_file)) - return; - out = BIO_new_file(ctx->debug_file, "a+"); - BIO_vprintf(out, format, argptr); - BIO_free(out); -} - -static void CAPI_trace(CAPI_CTX * ctx, char *format, ...) -{ - va_list args; - va_start(args, format); - capi_vtrace(ctx, CAPI_DBG_TRACE, format, args); - va_end(args); -} - -static void capi_addlasterror(void) -{ - capi_adderror(GetLastError()); -} - -static void capi_adderror(DWORD err) -{ - char errstr[10]; - BIO_snprintf(errstr, 10, "%lX", err); - ERR_add_error_data(2, "Error code= 0x", errstr); -} - -static char *wide_to_asc(LPCWSTR wstr) -{ - char *str; - int len_0, sz; - - if (!wstr) - return NULL; - len_0 = (int)wcslen(wstr) + 1; /* WideCharToMultiByte expects int */ - sz = WideCharToMultiByte(CP_ACP, 0, wstr, len_0, NULL, 0, NULL, NULL); - if (!sz) { - CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); - return NULL; - } - str = OPENSSL_malloc(sz); - if (!str) { - CAPIerr(CAPI_F_WIDE_TO_ASC, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (!WideCharToMultiByte(CP_ACP, 0, wstr, len_0, str, sz, NULL, NULL)) { - OPENSSL_free(str); - CAPIerr(CAPI_F_WIDE_TO_ASC, CAPI_R_WIN32_ERROR); - return NULL; - } - return str; -} - -static int capi_get_provname(CAPI_CTX * ctx, LPSTR * pname, DWORD * ptype, - DWORD idx) -{ - DWORD len, err; - LPTSTR name; - CAPI_trace(ctx, "capi_get_provname, index=%d\n", idx); - if (!CryptEnumProviders(idx, NULL, 0, ptype, NULL, &len)) { - err = GetLastError(); - if (err == ERROR_NO_MORE_ITEMS) - return 2; - CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); - capi_adderror(err); - return 0; - } - if (sizeof(TCHAR) != sizeof(char)) - name = alloca(len); - else - name = OPENSSL_malloc(len); - if (name == NULL) { - CAPIerr(CAPI_F_CAPI_GET_PROVNAME, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!CryptEnumProviders(idx, NULL, 0, ptype, name, &len)) { - err = GetLastError(); - if (err == ERROR_NO_MORE_ITEMS) - return 2; - CAPIerr(CAPI_F_CAPI_GET_PROVNAME, CAPI_R_CRYPTENUMPROVIDERS_ERROR); - capi_adderror(err); - return 0; - } - if (sizeof(TCHAR) != sizeof(char)) - *pname = wide_to_asc((WCHAR *)name); - else - *pname = (char *)name; - CAPI_trace(ctx, "capi_get_provname, returned name=%s, type=%d\n", *pname, - *ptype); - - return 1; -} - -static int capi_list_providers(CAPI_CTX * ctx, BIO *out) -{ - DWORD idx, ptype; - int ret; - LPSTR provname = NULL; - CAPI_trace(ctx, "capi_list_providers\n"); - BIO_printf(out, "Available CSPs:\n"); - for (idx = 0;; idx++) { - ret = capi_get_provname(ctx, &provname, &ptype, idx); - if (ret == 2) - break; - if (ret == 0) - break; - BIO_printf(out, "%d. %s, type %d\n", idx, provname, ptype); - OPENSSL_free(provname); - } - return 1; -} - -static int capi_list_containers(CAPI_CTX * ctx, BIO *out) -{ - int ret = 1; - HCRYPTPROV hprov; - DWORD err, idx, flags, buflen = 0, clen; - LPSTR cname; - LPTSTR cspname = NULL; - - CAPI_trace(ctx, "Listing containers CSP=%s, type = %d\n", ctx->cspname, - ctx->csptype); - if (ctx->cspname && sizeof(TCHAR) != sizeof(char)) { - if ((clen = - MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, NULL, 0))) { - cspname = alloca(clen * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, (WCHAR *)cspname, - clen); - } - if (!cspname) { - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); - capi_addlasterror(); - return 0; - } - } else - cspname = (TCHAR *)ctx->cspname; - if (!CryptAcquireContext - (&hprov, NULL, cspname, ctx->csptype, CRYPT_VERIFYCONTEXT)) { - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, - CAPI_R_CRYPTACQUIRECONTEXT_ERROR); - capi_addlasterror(); - return 0; - } - if (!CryptGetProvParam - (hprov, PP_ENUMCONTAINERS, NULL, &buflen, CRYPT_FIRST)) { - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); - capi_addlasterror(); - CryptReleaseContext(hprov, 0); - return 0; - } - CAPI_trace(ctx, "Got max container len %d\n", buflen); - if (buflen == 0) - buflen = 1024; - cname = OPENSSL_malloc(buflen); - if (!cname) { - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, ERR_R_MALLOC_FAILURE); - goto err; - } - - for (idx = 0;; idx++) { - clen = buflen; - cname[0] = 0; - - if (idx == 0) - flags = CRYPT_FIRST; - else - flags = 0; - if (!CryptGetProvParam - (hprov, PP_ENUMCONTAINERS, (BYTE *) cname, &clen, flags)) { - err = GetLastError(); - if (err == ERROR_NO_MORE_ITEMS) - goto done; - CAPIerr(CAPI_F_CAPI_LIST_CONTAINERS, CAPI_R_ENUMCONTAINERS_ERROR); - capi_adderror(err); - goto err; - } - CAPI_trace(ctx, "Container name %s, len=%d, index=%d, flags=%d\n", - cname, clen, idx, flags); - if (!cname[0] && (clen == buflen)) { - CAPI_trace(ctx, "Enumerate bug: using workaround\n"); - goto done; - } - BIO_printf(out, "%d. %s\n", idx, cname); - } - err: - - ret = 0; - - done: - if (cname) - OPENSSL_free(cname); - CryptReleaseContext(hprov, 0); - - return ret; -} - -CRYPT_KEY_PROV_INFO *capi_get_prov_info(CAPI_CTX * ctx, PCCERT_CONTEXT cert) -{ - DWORD len; - CRYPT_KEY_PROV_INFO *pinfo; - - if (!CertGetCertificateContextProperty - (cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) - return NULL; - pinfo = OPENSSL_malloc(len); - if (!pinfo) { - CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (!CertGetCertificateContextProperty - (cert, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) { - CAPIerr(CAPI_F_CAPI_GET_PROV_INFO, - CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO); - capi_addlasterror(); - OPENSSL_free(pinfo); - return NULL; - } - return pinfo; -} - -static void capi_dump_prov_info(CAPI_CTX * ctx, BIO *out, - CRYPT_KEY_PROV_INFO * pinfo) -{ - char *provname = NULL, *contname = NULL; - if (!pinfo) { - BIO_printf(out, " No Private Key\n"); - return; - } - provname = wide_to_asc(pinfo->pwszProvName); - contname = wide_to_asc(pinfo->pwszContainerName); - if (!provname || !contname) - goto err; - - BIO_printf(out, " Private Key Info:\n"); - BIO_printf(out, " Provider Name: %s, Provider Type %d\n", provname, - pinfo->dwProvType); - BIO_printf(out, " Container Name: %s, Key Type %d\n", contname, - pinfo->dwKeySpec); - err: - if (provname) - OPENSSL_free(provname); - if (contname) - OPENSSL_free(contname); -} - -char *capi_cert_get_fname(CAPI_CTX * ctx, PCCERT_CONTEXT cert) -{ - LPWSTR wfname; - DWORD dlen; - - CAPI_trace(ctx, "capi_cert_get_fname\n"); - if (!CertGetCertificateContextProperty - (cert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dlen)) - return NULL; - wfname = OPENSSL_malloc(dlen); - if (wfname == NULL) { - CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (CertGetCertificateContextProperty - (cert, CERT_FRIENDLY_NAME_PROP_ID, wfname, &dlen)) { - char *fname = wide_to_asc(wfname); - OPENSSL_free(wfname); - return fname; - } - CAPIerr(CAPI_F_CAPI_CERT_GET_FNAME, CAPI_R_ERROR_GETTING_FRIENDLY_NAME); - capi_addlasterror(); - - OPENSSL_free(wfname); - return NULL; -} - -void capi_dump_cert(CAPI_CTX * ctx, BIO *out, PCCERT_CONTEXT cert) -{ - X509 *x; - unsigned char *p; - unsigned long flags = ctx->dump_flags; - if (flags & CAPI_DMP_FNAME) { - char *fname; - fname = capi_cert_get_fname(ctx, cert); - if (fname) { - BIO_printf(out, " Friendly Name \"%s\"\n", fname); - OPENSSL_free(fname); - } else - BIO_printf(out, " \n"); - } - - p = cert->pbCertEncoded; - x = d2i_X509(NULL, &p, cert->cbCertEncoded); - if (!x) - BIO_printf(out, " \n"); - if (flags & CAPI_DMP_SUMMARY) { - BIO_printf(out, " Subject: "); - X509_NAME_print_ex(out, X509_get_subject_name(x), 0, XN_FLAG_ONELINE); - BIO_printf(out, "\n Issuer: "); - X509_NAME_print_ex(out, X509_get_issuer_name(x), 0, XN_FLAG_ONELINE); - BIO_printf(out, "\n"); - } - if (flags & CAPI_DMP_FULL) - X509_print_ex(out, x, XN_FLAG_ONELINE, 0); - - if (flags & CAPI_DMP_PKEYINFO) { - CRYPT_KEY_PROV_INFO *pinfo; - pinfo = capi_get_prov_info(ctx, cert); - capi_dump_prov_info(ctx, out, pinfo); - if (pinfo) - OPENSSL_free(pinfo); - } - - if (flags & CAPI_DMP_PEM) - PEM_write_bio_X509(out, x); - X509_free(x); -} - -HCERTSTORE capi_open_store(CAPI_CTX * ctx, char *storename) -{ - HCERTSTORE hstore; - - if (!storename) - storename = ctx->storename; - if (!storename) - storename = "MY"; - CAPI_trace(ctx, "Opening certificate store %s\n", storename); - - hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, - ctx->store_flags, storename); - if (!hstore) { - CAPIerr(CAPI_F_CAPI_OPEN_STORE, CAPI_R_ERROR_OPENING_STORE); - capi_addlasterror(); - } - return hstore; -} - -int capi_list_certs(CAPI_CTX * ctx, BIO *out, char *id) -{ - char *storename; - int idx; - int ret = 1; - HCERTSTORE hstore; - PCCERT_CONTEXT cert = NULL; - - storename = ctx->storename; - if (!storename) - storename = "MY"; - CAPI_trace(ctx, "Listing certs for store %s\n", storename); - - hstore = capi_open_store(ctx, storename); - if (!hstore) - return 0; - if (id) { - cert = capi_find_cert(ctx, id, hstore); - if (!cert) { - ret = 0; - goto err; - } - capi_dump_cert(ctx, out, cert); - CertFreeCertificateContext(cert); - } else { - for (idx = 0;; idx++) { - cert = CertEnumCertificatesInStore(hstore, cert); - if (!cert) - break; - BIO_printf(out, "Certificate %d\n", idx); - capi_dump_cert(ctx, out, cert); - } - } - err: - CertCloseStore(hstore, 0); - return ret; -} - -static PCCERT_CONTEXT capi_find_cert(CAPI_CTX * ctx, const char *id, - HCERTSTORE hstore) -{ - PCCERT_CONTEXT cert = NULL; - char *fname = NULL; - int match; - switch (ctx->lookup_method) { - case CAPI_LU_SUBSTR: - return CertFindCertificateInStore(hstore, - X509_ASN_ENCODING, 0, - CERT_FIND_SUBJECT_STR_A, id, NULL); - case CAPI_LU_FNAME: - for (;;) { - cert = CertEnumCertificatesInStore(hstore, cert); - if (!cert) - return NULL; - fname = capi_cert_get_fname(ctx, cert); - if (fname) { - if (strcmp(fname, id)) - match = 0; - else - match = 1; - OPENSSL_free(fname); - if (match) - return cert; - } - } - default: - return NULL; - } -} - -static CAPI_KEY *capi_get_key(CAPI_CTX * ctx, const TCHAR *contname, - TCHAR *provname, DWORD ptype, DWORD keyspec) -{ - CAPI_KEY *key; - DWORD dwFlags = 0; - key = OPENSSL_malloc(sizeof(CAPI_KEY)); - if (key == NULL) { - CAPIerr(CAPI_F_CAPI_GET_KEY, ERR_R_MALLOC_FAILURE); - capi_addlasterror(); - goto err; - } - if (sizeof(TCHAR) == sizeof(char)) - CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", - contname, provname, ptype); - else if (ctx && ctx->debug_level >= CAPI_DBG_TRACE && ctx->debug_file) { - /* above 'if' is optimization to minimize malloc-ations */ - char *_contname = wide_to_asc((WCHAR *)contname); - char *_provname = wide_to_asc((WCHAR *)provname); - - CAPI_trace(ctx, "capi_get_key, contname=%s, provname=%s, type=%d\n", - _contname, _provname, ptype); - if (_provname) - OPENSSL_free(_provname); - if (_contname) - OPENSSL_free(_contname); - } - if (ctx->store_flags & CERT_SYSTEM_STORE_LOCAL_MACHINE) - dwFlags = CRYPT_MACHINE_KEYSET; - if (!CryptAcquireContext(&key->hprov, contname, provname, ptype, dwFlags)) { - CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_CRYPTACQUIRECONTEXT_ERROR); - capi_addlasterror(); - goto err; - } - if (!CryptGetUserKey(key->hprov, keyspec, &key->key)) { - CAPIerr(CAPI_F_CAPI_GET_KEY, CAPI_R_GETUSERKEY_ERROR); - capi_addlasterror(); - CryptReleaseContext(key->hprov, 0); - goto err; - } - key->keyspec = keyspec; - key->pcert = NULL; - return key; - - err: - OPENSSL_free(key); - return NULL; -} - -static CAPI_KEY *capi_get_cert_key(CAPI_CTX * ctx, PCCERT_CONTEXT cert) -{ - CAPI_KEY *key = NULL; - CRYPT_KEY_PROV_INFO *pinfo = NULL; - char *provname = NULL, *contname = NULL; - pinfo = capi_get_prov_info(ctx, cert); - if (!pinfo) - goto err; - if (sizeof(TCHAR) != sizeof(char)) - key = capi_get_key(ctx, (TCHAR *)pinfo->pwszContainerName, - (TCHAR *)pinfo->pwszProvName, - pinfo->dwProvType, pinfo->dwKeySpec); - else { - provname = wide_to_asc(pinfo->pwszProvName); - contname = wide_to_asc(pinfo->pwszContainerName); - if (!provname || !contname) - goto err; - key = capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname, - pinfo->dwProvType, pinfo->dwKeySpec); - } - - err: - if (pinfo) - OPENSSL_free(pinfo); - if (provname) - OPENSSL_free(provname); - if (contname) - OPENSSL_free(contname); - return key; -} - -CAPI_KEY *capi_find_key(CAPI_CTX * ctx, const char *id) -{ - PCCERT_CONTEXT cert; - HCERTSTORE hstore; - CAPI_KEY *key = NULL; - switch (ctx->lookup_method) { - case CAPI_LU_SUBSTR: - case CAPI_LU_FNAME: - hstore = capi_open_store(ctx, NULL); - if (!hstore) - return NULL; - cert = capi_find_cert(ctx, id, hstore); - if (cert) { - key = capi_get_cert_key(ctx, cert); - CertFreeCertificateContext(cert); - } - CertCloseStore(hstore, 0); - break; - - case CAPI_LU_CONTNAME: - if (sizeof(TCHAR) != sizeof(char)) { - WCHAR *contname, *provname; - DWORD len; - - if ((len = MultiByteToWideChar(CP_ACP, 0, id, -1, NULL, 0)) && - (contname = alloca(len * sizeof(WCHAR)), - MultiByteToWideChar(CP_ACP, 0, id, -1, contname, len)) && - (len = - MultiByteToWideChar(CP_ACP, 0, ctx->cspname, -1, NULL, 0)) - && (provname = - alloca(len * sizeof(WCHAR)), MultiByteToWideChar(CP_ACP, - 0, - ctx->cspname, - -1, - provname, - len))) - key = - capi_get_key(ctx, (TCHAR *)contname, (TCHAR *)provname, - ctx->csptype, ctx->keytype); - } else - key = capi_get_key(ctx, (TCHAR *)id, - (TCHAR *)ctx->cspname, - ctx->csptype, ctx->keytype); - break; - } - - return key; -} - -void capi_free_key(CAPI_KEY * key) -{ - if (!key) - return; - CryptDestroyKey(key->key); - CryptReleaseContext(key->hprov, 0); - if (key->pcert) - CertFreeCertificateContext(key->pcert); - OPENSSL_free(key); -} - -/* Initialize a CAPI_CTX structure */ - -static CAPI_CTX *capi_ctx_new() -{ - CAPI_CTX *ctx; - ctx = OPENSSL_malloc(sizeof(CAPI_CTX)); - if (!ctx) { - CAPIerr(CAPI_F_CAPI_CTX_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - ctx->cspname = NULL; - ctx->csptype = PROV_RSA_FULL; - ctx->dump_flags = CAPI_DMP_SUMMARY | CAPI_DMP_FNAME; - ctx->keytype = AT_KEYEXCHANGE; - ctx->storename = NULL; - ctx->ssl_client_store = NULL; - ctx->store_flags = CERT_STORE_OPEN_EXISTING_FLAG | - CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER; - ctx->lookup_method = CAPI_LU_SUBSTR; - ctx->debug_level = 0; - ctx->debug_file = NULL; - ctx->client_cert_select = cert_select_simple; - return ctx; -} - -static void capi_ctx_free(CAPI_CTX * ctx) -{ - CAPI_trace(ctx, "Calling capi_ctx_free with %lx\n", ctx); - if (!ctx) - return; - if (ctx->cspname) - OPENSSL_free(ctx->cspname); - if (ctx->debug_file) - OPENSSL_free(ctx->debug_file); - if (ctx->storename) - OPENSSL_free(ctx->storename); - if (ctx->ssl_client_store) - OPENSSL_free(ctx->ssl_client_store); - OPENSSL_free(ctx); -} - -static int capi_ctx_set_provname(CAPI_CTX * ctx, LPSTR pname, DWORD type, - int check) -{ - CAPI_trace(ctx, "capi_ctx_set_provname, name=%s, type=%d\n", pname, type); - if (check) { - HCRYPTPROV hprov; - LPTSTR name = NULL; - - if (sizeof(TCHAR) != sizeof(char)) { - DWORD len; - if ((len = MultiByteToWideChar(CP_ACP, 0, pname, -1, NULL, 0))) { - name = alloca(len * sizeof(WCHAR)); - MultiByteToWideChar(CP_ACP, 0, pname, -1, (WCHAR *)name, len); - } - } else - name = (TCHAR *)pname; - - if (!name || !CryptAcquireContext(&hprov, NULL, name, type, - CRYPT_VERIFYCONTEXT)) { - CAPIerr(CAPI_F_CAPI_CTX_SET_PROVNAME, - CAPI_R_CRYPTACQUIRECONTEXT_ERROR); - capi_addlasterror(); - return 0; - } - CryptReleaseContext(hprov, 0); - } - if (ctx->cspname) - OPENSSL_free(ctx->cspname); - ctx->cspname = BUF_strdup(pname); - ctx->csptype = type; - return 1; -} - -static int capi_ctx_set_provname_idx(CAPI_CTX * ctx, int idx) -{ - LPSTR pname; - DWORD type; - int res; - if (capi_get_provname(ctx, &pname, &type, idx) != 1) - return 0; - res = capi_ctx_set_provname(ctx, pname, type, 0); - OPENSSL_free(pname); - return res; -} - -static int cert_issuer_match(STACK_OF(X509_NAME) *ca_dn, X509 *x) -{ - int i; - X509_NAME *nm; - /* Special case: empty list: match anything */ - if (sk_X509_NAME_num(ca_dn) <= 0) - return 1; - for (i = 0; i < sk_X509_NAME_num(ca_dn); i++) { - nm = sk_X509_NAME_value(ca_dn, i); - if (!X509_NAME_cmp(nm, X509_get_issuer_name(x))) - return 1; - } - return 0; -} - -static int capi_load_ssl_client_cert(ENGINE *e, SSL *ssl, - STACK_OF(X509_NAME) *ca_dn, X509 **pcert, - EVP_PKEY **pkey, STACK_OF(X509) **pother, - UI_METHOD *ui_method, - void *callback_data) -{ - STACK_OF(X509) *certs = NULL; - X509 *x; - char *storename; - const char *p; - int i, client_cert_idx; - HCERTSTORE hstore; - PCCERT_CONTEXT cert = NULL, excert = NULL; - CAPI_CTX *ctx; - CAPI_KEY *key; - ctx = ENGINE_get_ex_data(e, capi_idx); - - *pcert = NULL; - *pkey = NULL; - - storename = ctx->ssl_client_store; - if (!storename) - storename = "MY"; - - hstore = capi_open_store(ctx, storename); - if (!hstore) - return 0; - /* Enumerate all certificates collect any matches */ - for (i = 0;; i++) { - cert = CertEnumCertificatesInStore(hstore, cert); - if (!cert) - break; - p = cert->pbCertEncoded; - x = d2i_X509(NULL, &p, cert->cbCertEncoded); - if (!x) { - CAPI_trace(ctx, "Can't Parse Certificate %d\n", i); - continue; - } - if (cert_issuer_match(ca_dn, x) - && X509_check_purpose(x, X509_PURPOSE_SSL_CLIENT, 0)) { - key = capi_get_cert_key(ctx, cert); - if (!key) { - X509_free(x); - continue; - } - /* - * Match found: attach extra data to it so we can retrieve the - * key later. - */ - excert = CertDuplicateCertificateContext(cert); - key->pcert = excert; - X509_set_ex_data(x, cert_capi_idx, key); - - if (!certs) - certs = sk_X509_new_null(); - - sk_X509_push(certs, x); - } else - X509_free(x); - - } - - if (cert) - CertFreeCertificateContext(cert); - if (hstore) - CertCloseStore(hstore, 0); - - if (!certs) - return 0; - - /* Select the appropriate certificate */ - - client_cert_idx = ctx->client_cert_select(e, ssl, certs); - - /* Set the selected certificate and free the rest */ - - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - if (i == client_cert_idx) - *pcert = x; - else { - key = X509_get_ex_data(x, cert_capi_idx); - capi_free_key(key); - X509_free(x); - } - } - - sk_X509_free(certs); - - if (!*pcert) - return 0; - - /* Setup key for selected certificate */ - - key = X509_get_ex_data(*pcert, cert_capi_idx); - *pkey = capi_get_pkey(e, key); - X509_set_ex_data(*pcert, cert_capi_idx, NULL); - - return 1; - -} - -/* Simple client cert selection function: always select first */ - -static int cert_select_simple(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) -{ - return 0; -} - -# ifdef OPENSSL_CAPIENG_DIALOG - -/* - * More complex cert selection function, using standard function - * CryptUIDlgSelectCertificateFromStore() to produce a dialog box. - */ - -/* - * Definitions which are in cryptuiapi.h but this is not present in older - * versions of headers. - */ - -# ifndef CRYPTUI_SELECT_LOCATION_COLUMN -# define CRYPTUI_SELECT_LOCATION_COLUMN 0x000000010 -# define CRYPTUI_SELECT_INTENDEDUSE_COLUMN 0x000000004 -# endif - -# define dlg_title L"OpenSSL Application SSL Client Certificate Selection" -# define dlg_prompt L"Select a certificate to use for authentication" -# define dlg_columns CRYPTUI_SELECT_LOCATION_COLUMN \ - |CRYPTUI_SELECT_INTENDEDUSE_COLUMN - -static int cert_select_dialog(ENGINE *e, SSL *ssl, STACK_OF(X509) *certs) -{ - X509 *x; - HCERTSTORE dstore; - PCCERT_CONTEXT cert; - CAPI_CTX *ctx; - CAPI_KEY *key; - HWND hwnd; - int i, idx = -1; - if (sk_X509_num(certs) == 1) - return 0; - ctx = ENGINE_get_ex_data(e, capi_idx); - /* Create an in memory store of certificates */ - dstore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, - CERT_STORE_CREATE_NEW_FLAG, NULL); - if (!dstore) { - CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_CREATING_STORE); - capi_addlasterror(); - goto err; - } - /* Add all certificates to store */ - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - key = X509_get_ex_data(x, cert_capi_idx); - - if (!CertAddCertificateContextToStore(dstore, key->pcert, - CERT_STORE_ADD_NEW, NULL)) { - CAPIerr(CAPI_F_CERT_SELECT_DIALOG, CAPI_R_ERROR_ADDING_CERT); - capi_addlasterror(); - goto err; - } - - } - hwnd = GetForegroundWindow(); - if (!hwnd) - hwnd = GetActiveWindow(); - if (!hwnd && ctx->getconswindow) - hwnd = ctx->getconswindow(); - /* Call dialog to select one */ - cert = ctx->certselectdlg(dstore, hwnd, dlg_title, dlg_prompt, - dlg_columns, 0, NULL); - - /* Find matching cert from list */ - if (cert) { - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - key = X509_get_ex_data(x, cert_capi_idx); - if (CertCompareCertificate - (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert->pCertInfo, - key->pcert->pCertInfo)) { - idx = i; - break; - } - } - } - - err: - if (dstore) - CertCloseStore(dstore, 0); - return idx; - -} -# endif - -#else /* !__COMPILE_CAPIENG */ -# include "engine.h" -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -OPENSSL_EXPORT - int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); -OPENSSL_EXPORT - int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) -{ - return 0; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() -# else -void ENGINE_load_capi(void) -{ -} -# endif -#endif diff --git a/Sources/COpenSSL/e_capi_err.c b/Sources/COpenSSL/e_capi_err.c deleted file mode 100644 index 8eb2089a..00000000 --- a/Sources/COpenSSL/e_capi_err.c +++ /dev/null @@ -1,187 +0,0 @@ -/* e_capi_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_capi_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA CAPI_str_functs[] = { - {ERR_FUNC(CAPI_F_CAPI_CERT_GET_FNAME), "CAPI_CERT_GET_FNAME"}, - {ERR_FUNC(CAPI_F_CAPI_CTRL), "CAPI_CTRL"}, - {ERR_FUNC(CAPI_F_CAPI_CTX_NEW), "CAPI_CTX_NEW"}, - {ERR_FUNC(CAPI_F_CAPI_CTX_SET_PROVNAME), "CAPI_CTX_SET_PROVNAME"}, - {ERR_FUNC(CAPI_F_CAPI_DSA_DO_SIGN), "CAPI_DSA_DO_SIGN"}, - {ERR_FUNC(CAPI_F_CAPI_GET_KEY), "CAPI_GET_KEY"}, - {ERR_FUNC(CAPI_F_CAPI_GET_PKEY), "CAPI_GET_PKEY"}, - {ERR_FUNC(CAPI_F_CAPI_GET_PROVNAME), "CAPI_GET_PROVNAME"}, - {ERR_FUNC(CAPI_F_CAPI_GET_PROV_INFO), "CAPI_GET_PROV_INFO"}, - {ERR_FUNC(CAPI_F_CAPI_INIT), "CAPI_INIT"}, - {ERR_FUNC(CAPI_F_CAPI_LIST_CONTAINERS), "CAPI_LIST_CONTAINERS"}, - {ERR_FUNC(CAPI_F_CAPI_LOAD_PRIVKEY), "CAPI_LOAD_PRIVKEY"}, - {ERR_FUNC(CAPI_F_CAPI_OPEN_STORE), "CAPI_OPEN_STORE"}, - {ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_DEC), "CAPI_RSA_PRIV_DEC"}, - {ERR_FUNC(CAPI_F_CAPI_RSA_PRIV_ENC), "CAPI_RSA_PRIV_ENC"}, - {ERR_FUNC(CAPI_F_CAPI_RSA_SIGN), "CAPI_RSA_SIGN"}, - {ERR_FUNC(CAPI_F_CERT_SELECT_DIALOG), "CERT_SELECT_DIALOG"}, - {ERR_FUNC(CAPI_F_CLIENT_CERT_SELECT), "CLIENT_CERT_SELECT"}, - {ERR_FUNC(CAPI_F_WIDE_TO_ASC), "WIDE_TO_ASC"}, - {0, NULL} -}; - -static ERR_STRING_DATA CAPI_str_reasons[] = { - {ERR_REASON(CAPI_R_CANT_CREATE_HASH_OBJECT), "cant create hash object"}, - {ERR_REASON(CAPI_R_CANT_FIND_CAPI_CONTEXT), "cant find capi context"}, - {ERR_REASON(CAPI_R_CANT_GET_KEY), "cant get key"}, - {ERR_REASON(CAPI_R_CANT_SET_HASH_VALUE), "cant set hash value"}, - {ERR_REASON(CAPI_R_CRYPTACQUIRECONTEXT_ERROR), - "cryptacquirecontext error"}, - {ERR_REASON(CAPI_R_CRYPTENUMPROVIDERS_ERROR), "cryptenumproviders error"}, - {ERR_REASON(CAPI_R_DECRYPT_ERROR), "decrypt error"}, - {ERR_REASON(CAPI_R_ENGINE_NOT_INITIALIZED), "engine not initialized"}, - {ERR_REASON(CAPI_R_ENUMCONTAINERS_ERROR), "enumcontainers error"}, - {ERR_REASON(CAPI_R_ERROR_ADDING_CERT), "error adding cert"}, - {ERR_REASON(CAPI_R_ERROR_CREATING_STORE), "error creating store"}, - {ERR_REASON(CAPI_R_ERROR_GETTING_FRIENDLY_NAME), - "error getting friendly name"}, - {ERR_REASON(CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO), - "error getting key provider info"}, - {ERR_REASON(CAPI_R_ERROR_OPENING_STORE), "error opening store"}, - {ERR_REASON(CAPI_R_ERROR_SIGNING_HASH), "error signing hash"}, - {ERR_REASON(CAPI_R_FUNCTION_NOT_SUPPORTED), "function not supported"}, - {ERR_REASON(CAPI_R_GETUSERKEY_ERROR), "getuserkey error"}, - {ERR_REASON(CAPI_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, - {ERR_REASON(CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER), - "invalid dsa public key blob magic number"}, - {ERR_REASON(CAPI_R_INVALID_LOOKUP_METHOD), "invalid lookup method"}, - {ERR_REASON(CAPI_R_INVALID_PUBLIC_KEY_BLOB), "invalid public key blob"}, - {ERR_REASON(CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER), - "invalid rsa public key blob magic number"}, - {ERR_REASON(CAPI_R_PUBKEY_EXPORT_ERROR), "pubkey export error"}, - {ERR_REASON(CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR), - "pubkey export length error"}, - {ERR_REASON(CAPI_R_UNKNOWN_COMMAND), "unknown command"}, - {ERR_REASON(CAPI_R_UNSUPPORTED_ALGORITHM_NID), - "unsupported algorithm nid"}, - {ERR_REASON(CAPI_R_UNSUPPORTED_PADDING), "unsupported padding"}, - {ERR_REASON(CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM), - "unsupported public key algorithm"}, - {ERR_REASON(CAPI_R_WIN32_ERROR), "win32 error"}, - {0, NULL} -}; - -#endif - -#ifdef CAPI_LIB_NAME -static ERR_STRING_DATA CAPI_lib_name[] = { - {0, CAPI_LIB_NAME}, - {0, NULL} -}; -#endif - -static int CAPI_lib_error_code = 0; -static int CAPI_error_init = 1; - -static void ERR_load_CAPI_strings(void) -{ - if (CAPI_lib_error_code == 0) - CAPI_lib_error_code = ERR_get_next_error_library(); - - if (CAPI_error_init) { - CAPI_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(CAPI_lib_error_code, CAPI_str_functs); - ERR_load_strings(CAPI_lib_error_code, CAPI_str_reasons); -#endif - -#ifdef CAPI_LIB_NAME - CAPI_lib_name->error = ERR_PACK(CAPI_lib_error_code, 0, 0); - ERR_load_strings(0, CAPI_lib_name); -#endif - } -} - -static void ERR_unload_CAPI_strings(void) -{ - if (CAPI_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(CAPI_lib_error_code, CAPI_str_functs); - ERR_unload_strings(CAPI_lib_error_code, CAPI_str_reasons); -#endif - -#ifdef CAPI_LIB_NAME - ERR_unload_strings(0, CAPI_lib_name); -#endif - CAPI_error_init = 1; - } -} - -static void ERR_CAPI_error(int function, int reason, char *file, int line) -{ - if (CAPI_lib_error_code == 0) - CAPI_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(CAPI_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_capi_err.h b/Sources/COpenSSL/e_capi_err.h deleted file mode 100644 index b5d06dce..00000000 --- a/Sources/COpenSSL/e_capi_err.h +++ /dev/null @@ -1,129 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001-2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_CAPI_ERR_H -# define HEADER_CAPI_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_CAPI_strings(void); -static void ERR_unload_CAPI_strings(void); -static void ERR_CAPI_error(int function, int reason, char *file, int line); -# define CAPIerr(f,r) ERR_CAPI_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the CAPI functions. */ - -/* Function codes. */ -# define CAPI_F_CAPI_CERT_GET_FNAME 99 -# define CAPI_F_CAPI_CTRL 100 -# define CAPI_F_CAPI_CTX_NEW 101 -# define CAPI_F_CAPI_CTX_SET_PROVNAME 102 -# define CAPI_F_CAPI_DSA_DO_SIGN 114 -# define CAPI_F_CAPI_GET_KEY 103 -# define CAPI_F_CAPI_GET_PKEY 115 -# define CAPI_F_CAPI_GET_PROVNAME 104 -# define CAPI_F_CAPI_GET_PROV_INFO 105 -# define CAPI_F_CAPI_INIT 106 -# define CAPI_F_CAPI_LIST_CONTAINERS 107 -# define CAPI_F_CAPI_LOAD_PRIVKEY 108 -# define CAPI_F_CAPI_OPEN_STORE 109 -# define CAPI_F_CAPI_RSA_PRIV_DEC 110 -# define CAPI_F_CAPI_RSA_PRIV_ENC 111 -# define CAPI_F_CAPI_RSA_SIGN 112 -# define CAPI_F_CERT_SELECT_DIALOG 117 -# define CAPI_F_CLIENT_CERT_SELECT 116 -# define CAPI_F_WIDE_TO_ASC 113 - -/* Reason codes. */ -# define CAPI_R_CANT_CREATE_HASH_OBJECT 99 -# define CAPI_R_CANT_FIND_CAPI_CONTEXT 100 -# define CAPI_R_CANT_GET_KEY 101 -# define CAPI_R_CANT_SET_HASH_VALUE 102 -# define CAPI_R_CRYPTACQUIRECONTEXT_ERROR 103 -# define CAPI_R_CRYPTENUMPROVIDERS_ERROR 104 -# define CAPI_R_DECRYPT_ERROR 105 -# define CAPI_R_ENGINE_NOT_INITIALIZED 106 -# define CAPI_R_ENUMCONTAINERS_ERROR 107 -# define CAPI_R_ERROR_ADDING_CERT 125 -# define CAPI_R_ERROR_CREATING_STORE 126 -# define CAPI_R_ERROR_GETTING_FRIENDLY_NAME 108 -# define CAPI_R_ERROR_GETTING_KEY_PROVIDER_INFO 109 -# define CAPI_R_ERROR_OPENING_STORE 110 -# define CAPI_R_ERROR_SIGNING_HASH 111 -# define CAPI_R_FUNCTION_NOT_SUPPORTED 112 -# define CAPI_R_GETUSERKEY_ERROR 113 -# define CAPI_R_INVALID_DIGEST_LENGTH 124 -# define CAPI_R_INVALID_DSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 122 -# define CAPI_R_INVALID_LOOKUP_METHOD 114 -# define CAPI_R_INVALID_PUBLIC_KEY_BLOB 115 -# define CAPI_R_INVALID_RSA_PUBLIC_KEY_BLOB_MAGIC_NUMBER 123 -# define CAPI_R_PUBKEY_EXPORT_ERROR 116 -# define CAPI_R_PUBKEY_EXPORT_LENGTH_ERROR 117 -# define CAPI_R_UNKNOWN_COMMAND 118 -# define CAPI_R_UNSUPPORTED_ALGORITHM_NID 119 -# define CAPI_R_UNSUPPORTED_PADDING 120 -# define CAPI_R_UNSUPPORTED_PUBLIC_KEY_ALGORITHM 121 -# define CAPI_R_WIN32_ERROR 127 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_cast.c b/Sources/COpenSSL/e_cast.c deleted file mode 100644 index c777c36e..00000000 --- a/Sources/COpenSSL/e_cast.c +++ /dev/null @@ -1,89 +0,0 @@ -/* crypto/evp/e_cast.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_CAST -# include "evp.h" -# include "objects.h" -# include "evp_locl.h" -# include "cast.h" - -static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - -typedef struct { - CAST_KEY ks; -} EVP_CAST_KEY; - -# define data(ctx) EVP_C_DATA(EVP_CAST_KEY,ctx) - -IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY, - NID_cast5, 8, CAST_KEY_LENGTH, 8, 64, - EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL, - EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) - -static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); - return 1; -} - -#endif diff --git a/Sources/COpenSSL/e_chil.c b/Sources/COpenSSL/e_chil.c deleted file mode 100644 index fb6af219..00000000 --- a/Sources/COpenSSL/e_chil.c +++ /dev/null @@ -1,1367 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/engine/e_chil.c */ -/* - * Written by Richard Levitte (richard@levitte.org), Geoff Thorpe - * (geoff@geoffthorpe.net) and Dr Stephen N Henson (steve@openssl.org) for - * the OpenSSL project 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "crypto.h" -#include "pem.h" -#include "dso.h" -#include "engine.h" -#include "ui.h" -#include "rand.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#include "bn.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_CHIL - -/*- - * Attribution notice: nCipher have said several times that it's OK for - * us to implement a general interface to their boxes, and recently declared - * their HWCryptoHook to be public, and therefore available for us to use. - * Thanks, nCipher. - * - * The hwcryptohook.h included here is from May 2000. - * [Richard Levitte] - */ -# ifdef FLAT_INC -# include "hwcryptohook.h" -# else -# include "hwcryptohook.h" -# endif - -# define HWCRHK_LIB_NAME "CHIL engine" -# include "e_chil_err.c" - -static int hwcrhk_destroy(ENGINE *e); -static int hwcrhk_init(ENGINE *e); -static int hwcrhk_finish(ENGINE *e); -static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); - -/* Functions to handle mutexes */ -static int hwcrhk_mutex_init(HWCryptoHook_Mutex *, - HWCryptoHook_CallerContext *); -static int hwcrhk_mutex_lock(HWCryptoHook_Mutex *); -static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex *); -static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex *); - -/* BIGNUM stuff */ -static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); - -# ifndef OPENSSL_NO_RSA -/* RSA stuff */ -static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -static int hwcrhk_rsa_finish(RSA *rsa); -# endif - -# ifndef OPENSSL_NO_DH -/* DH stuff */ -/* This function is alised to mod_exp (with the DH and mont dropped). */ -static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -/* RAND stuff */ -static int hwcrhk_rand_bytes(unsigned char *buf, int num); -static int hwcrhk_rand_status(void); - -/* KM stuff */ -static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, - void *callback_data); -static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, - void *callback_data); - -/* Interaction stuff */ -static int hwcrhk_insert_card(const char *prompt_info, - const char *wrong_info, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx); -static int hwcrhk_get_pass(const char *prompt_info, - int *len_io, char *buf, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx); -static void hwcrhk_log_message(void *logstr, const char *message); - -/* The definitions for control commands specific to this engine */ -# define HWCRHK_CMD_SO_PATH ENGINE_CMD_BASE -# define HWCRHK_CMD_FORK_CHECK (ENGINE_CMD_BASE + 1) -# define HWCRHK_CMD_THREAD_LOCKING (ENGINE_CMD_BASE + 2) -# define HWCRHK_CMD_SET_USER_INTERFACE (ENGINE_CMD_BASE + 3) -# define HWCRHK_CMD_SET_CALLBACK_DATA (ENGINE_CMD_BASE + 4) -static const ENGINE_CMD_DEFN hwcrhk_cmd_defns[] = { - {HWCRHK_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'hwcrhk' shared library", - ENGINE_CMD_FLAG_STRING}, - {HWCRHK_CMD_FORK_CHECK, - "FORK_CHECK", - "Turns fork() checking on (non-zero) or off (zero)", - ENGINE_CMD_FLAG_NUMERIC}, - {HWCRHK_CMD_THREAD_LOCKING, - "THREAD_LOCKING", - "Turns thread-safe locking on (zero) or off (non-zero)", - ENGINE_CMD_FLAG_NUMERIC}, - {HWCRHK_CMD_SET_USER_INTERFACE, - "SET_USER_INTERFACE", - "Set the global user interface (internal)", - ENGINE_CMD_FLAG_INTERNAL}, - {HWCRHK_CMD_SET_CALLBACK_DATA, - "SET_CALLBACK_DATA", - "Set the global user interface extra data (internal)", - ENGINE_CMD_FLAG_INTERNAL}, - {0, NULL, NULL, 0} -}; - -# ifndef OPENSSL_NO_RSA -/* Our internal RSA_METHOD that we provide pointers to */ -static RSA_METHOD hwcrhk_rsa = { - "CHIL RSA method", - NULL, - NULL, - NULL, - NULL, - hwcrhk_rsa_mod_exp, - hwcrhk_mod_exp_mont, - NULL, - hwcrhk_rsa_finish, - 0, - NULL, - NULL, - NULL, - NULL -}; -# endif - -# ifndef OPENSSL_NO_DH -/* Our internal DH_METHOD that we provide pointers to */ -static DH_METHOD hwcrhk_dh = { - "CHIL DH method", - NULL, - NULL, - hwcrhk_mod_exp_dh, - NULL, - NULL, - 0, - NULL, - NULL -}; -# endif - -static RAND_METHOD hwcrhk_rand = { - /* "CHIL RAND method", */ - NULL, - hwcrhk_rand_bytes, - NULL, - NULL, - hwcrhk_rand_bytes, - hwcrhk_rand_status, -}; - -/* Constants used when creating the ENGINE */ -static const char *engine_hwcrhk_id = "chil"; -static const char *engine_hwcrhk_name = "CHIL hardware engine support"; -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -/* Compatibility hack, the dynamic library uses this form in the path */ -static const char *engine_hwcrhk_id_alt = "ncipher"; -# endif - -/* Internal stuff for HWCryptoHook */ - -/* Some structures needed for proper use of thread locks */ -/* - * hwcryptohook.h has some typedefs that turn struct HWCryptoHook_MutexValue - * into HWCryptoHook_Mutex - */ -struct HWCryptoHook_MutexValue { - int lockid; -}; - -/* - * hwcryptohook.h has some typedefs that turn struct - * HWCryptoHook_PassphraseContextValue into HWCryptoHook_PassphraseContext - */ -struct HWCryptoHook_PassphraseContextValue { - UI_METHOD *ui_method; - void *callback_data; -}; - -/* - * hwcryptohook.h has some typedefs that turn struct - * HWCryptoHook_CallerContextValue into HWCryptoHook_CallerContext - */ -struct HWCryptoHook_CallerContextValue { - pem_password_cb *password_callback; /* Deprecated! Only present for - * backward compatibility! */ - UI_METHOD *ui_method; - void *callback_data; -}; - -/* - * The MPI structure in HWCryptoHook is pretty compatible with OpenSSL - * BIGNUM's, so lets define a couple of conversion macros - */ -# define BN2MPI(mp, bn) \ - {mp.size = bn->top * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} -# define MPI2BN(bn, mp) \ - {mp.size = bn->dmax * sizeof(BN_ULONG); mp.buf = (unsigned char *)bn->d;} - -static BIO *logstream = NULL; -static int disable_mutex_callbacks = 0; - -/* - * One might wonder why these are needed, since one can pass down at least a - * UI_METHOD and a pointer to callback data to the key-loading functions. The - * thing is that the ModExp and RSAImmed functions can load keys as well, if - * the data they get is in a special, nCipher-defined format (hint: if you - * look at the private exponent of the RSA data as a string, you'll see this - * string: "nCipher KM tool key id", followed by some bytes, followed a key - * identity string, followed by more bytes. This happens when you use - * "embed" keys instead of "hwcrhk" keys). Unfortunately, those functions do - * not take any passphrase or caller context, and our functions can't really - * take any callback data either. Still, the "insert_card" and - * "get_passphrase" callbacks may be called down the line, and will need to - * know what user interface callbacks to call, and having callback data from - * the application may be a nice thing as well, so we need to keep track of - * that globally. - */ -static HWCryptoHook_CallerContext password_context = { NULL, NULL, NULL }; - -/* Stuff to pass to the HWCryptoHook library */ -static HWCryptoHook_InitInfo hwcrhk_globals = { - HWCryptoHook_InitFlags_SimpleForkCheck, /* Flags */ - &logstream, /* logstream */ - sizeof(BN_ULONG), /* limbsize */ - 0, /* mslimb first: false for BNs */ - -1, /* msbyte first: use native */ - 0, /* Max mutexes, 0 = no small limit */ - 0, /* Max simultaneous, 0 = default */ - - /* - * The next few are mutex stuff: we write wrapper functions around the OS - * mutex functions. We initialise them to 0 here, and change that to - * actual function pointers in hwcrhk_init() if dynamic locks are - * supported (that is, if the application programmer has made sure of - * setting up callbacks bafore starting this engine) *and* if - * disable_mutex_callbacks hasn't been set by a call to - * ENGINE_ctrl(ENGINE_CTRL_CHIL_NO_LOCKING). - */ - sizeof(HWCryptoHook_Mutex), - 0, - 0, - 0, - 0, - - /* - * The next few are condvar stuff: we write wrapper functions round the - * OS functions. Currently not implemented and not and absolute - * necessity even in threaded programs, therefore 0'ed. Will hopefully - * be implemented some day, since it enhances the efficiency of - * HWCryptoHook. - */ - 0, /* sizeof(HWCryptoHook_CondVar), */ - 0, /* hwcrhk_cv_init, */ - 0, /* hwcrhk_cv_wait, */ - 0, /* hwcrhk_cv_signal, */ - 0, /* hwcrhk_cv_broadcast, */ - 0, /* hwcrhk_cv_destroy, */ - - hwcrhk_get_pass, /* pass phrase */ - hwcrhk_insert_card, /* insert a card */ - hwcrhk_log_message /* Log message */ -}; - -/* Now, to our own code */ - -/* - * This internal function is used by ENGINE_chil() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_helper(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif -# ifndef OPENSSL_NO_DH - const DH_METHOD *meth2; -# endif - if (!ENGINE_set_id(e, engine_hwcrhk_id) || - !ENGINE_set_name(e, engine_hwcrhk_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &hwcrhk_rsa) || -# endif -# ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &hwcrhk_dh) || -# endif - !ENGINE_set_RAND(e, &hwcrhk_rand) || - !ENGINE_set_destroy_function(e, hwcrhk_destroy) || - !ENGINE_set_init_function(e, hwcrhk_init) || - !ENGINE_set_finish_function(e, hwcrhk_finish) || - !ENGINE_set_ctrl_function(e, hwcrhk_ctrl) || - !ENGINE_set_load_privkey_function(e, hwcrhk_load_privkey) || - !ENGINE_set_load_pubkey_function(e, hwcrhk_load_pubkey) || - !ENGINE_set_cmd_defns(e, hwcrhk_cmd_defns)) - return 0; - -# ifndef OPENSSL_NO_RSA - /* - * We know that the "PKCS1_SSLeay()" functions hook properly to the - * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: - * We don't use ENGINE_openssl() or anything "more generic" because - * something like the RSAref code may not hook properly, and if you own - * one of these cards then you have the right to do RSA operations on it - * anyway! - */ - meth1 = RSA_PKCS1_SSLeay(); - hwcrhk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - hwcrhk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - hwcrhk_rsa.rsa_priv_enc = meth1->rsa_priv_enc; - hwcrhk_rsa.rsa_priv_dec = meth1->rsa_priv_dec; -# endif - -# ifndef OPENSSL_NO_DH - /* Much the same for Diffie-Hellman */ - meth2 = DH_OpenSSL(); - hwcrhk_dh.generate_key = meth2->generate_key; - hwcrhk_dh.compute_key = meth2->compute_key; -# endif - - /* Ensure the hwcrhk error handling is set up */ - ERR_load_HWCRHK_strings(); - return 1; -} - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE -static ENGINE *engine_chil(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_chil(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_chil(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -/* - * This is a process-global DSO handle used for loading and unloading the - * HWCryptoHook library. NB: This is only set (or unset) during an init() or - * finish() call (reference counts permitting) and they're operating with - * global locks, so this should be thread-safe implicitly. - */ -static DSO *hwcrhk_dso = NULL; -static HWCryptoHook_ContextHandle hwcrhk_context = 0; -# ifndef OPENSSL_NO_RSA -/* Index for KM handle. Not really used yet. */ -static int hndidx_rsa = -1; -# endif - -/* - * These are the function pointers that are (un)set when the library has - * successfully (un)loaded. - */ -static HWCryptoHook_Init_t *p_hwcrhk_Init = NULL; -static HWCryptoHook_Finish_t *p_hwcrhk_Finish = NULL; -static HWCryptoHook_ModExp_t *p_hwcrhk_ModExp = NULL; -# ifndef OPENSSL_NO_RSA -static HWCryptoHook_RSA_t *p_hwcrhk_RSA = NULL; -# endif -static HWCryptoHook_RandomBytes_t *p_hwcrhk_RandomBytes = NULL; -# ifndef OPENSSL_NO_RSA -static HWCryptoHook_RSALoadKey_t *p_hwcrhk_RSALoadKey = NULL; -static HWCryptoHook_RSAGetPublicKey_t *p_hwcrhk_RSAGetPublicKey = NULL; -static HWCryptoHook_RSAUnloadKey_t *p_hwcrhk_RSAUnloadKey = NULL; -# endif -static HWCryptoHook_ModExpCRT_t *p_hwcrhk_ModExpCRT = NULL; - -/* Used in the DSO operations. */ -static const char *HWCRHK_LIBNAME = NULL; -static void free_HWCRHK_LIBNAME(void) -{ - if (HWCRHK_LIBNAME) - OPENSSL_free((void *)HWCRHK_LIBNAME); - HWCRHK_LIBNAME = NULL; -} - -static const char *get_HWCRHK_LIBNAME(void) -{ - if (HWCRHK_LIBNAME) - return HWCRHK_LIBNAME; - return "nfhwcrhk"; -} - -static long set_HWCRHK_LIBNAME(const char *name) -{ - free_HWCRHK_LIBNAME(); - return (((HWCRHK_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); -} - -static const char *n_hwcrhk_Init = "HWCryptoHook_Init"; -static const char *n_hwcrhk_Finish = "HWCryptoHook_Finish"; -static const char *n_hwcrhk_ModExp = "HWCryptoHook_ModExp"; -# ifndef OPENSSL_NO_RSA -static const char *n_hwcrhk_RSA = "HWCryptoHook_RSA"; -# endif -static const char *n_hwcrhk_RandomBytes = "HWCryptoHook_RandomBytes"; -# ifndef OPENSSL_NO_RSA -static const char *n_hwcrhk_RSALoadKey = "HWCryptoHook_RSALoadKey"; -static const char *n_hwcrhk_RSAGetPublicKey = "HWCryptoHook_RSAGetPublicKey"; -static const char *n_hwcrhk_RSAUnloadKey = "HWCryptoHook_RSAUnloadKey"; -# endif -static const char *n_hwcrhk_ModExpCRT = "HWCryptoHook_ModExpCRT"; - -/* - * HWCryptoHook library functions and mechanics - these are used by the - * higher-level functions further down. NB: As and where there's no error - * checking, take a look lower down where these functions are called, the - * checking and error handling is probably down there. - */ - -/* utility function to obtain a context */ -static int get_context(HWCryptoHook_ContextHandle * hac, - HWCryptoHook_CallerContext * cac) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - - *hac = p_hwcrhk_Init(&hwcrhk_globals, sizeof(hwcrhk_globals), &rmsg, cac); - if (!*hac) - return 0; - return 1; -} - -/* similarly to release one. */ -static void release_context(HWCryptoHook_ContextHandle hac) -{ - p_hwcrhk_Finish(hac); -} - -/* Destructor (complements the "ENGINE_chil()" constructor) */ -static int hwcrhk_destroy(ENGINE *e) -{ - free_HWCRHK_LIBNAME(); - ERR_unload_HWCRHK_strings(); - return 1; -} - -/* (de)initialisation functions. */ -static int hwcrhk_init(ENGINE *e) -{ - HWCryptoHook_Init_t *p1; - HWCryptoHook_Finish_t *p2; - HWCryptoHook_ModExp_t *p3; -# ifndef OPENSSL_NO_RSA - HWCryptoHook_RSA_t *p4; - HWCryptoHook_RSALoadKey_t *p5; - HWCryptoHook_RSAGetPublicKey_t *p6; - HWCryptoHook_RSAUnloadKey_t *p7; -# endif - HWCryptoHook_RandomBytes_t *p8; - HWCryptoHook_ModExpCRT_t *p9; - - if (hwcrhk_dso != NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_ALREADY_LOADED); - goto err; - } - /* Attempt to load libnfhwcrhk.so/nfhwcrhk.dll/whatever. */ - hwcrhk_dso = DSO_load(NULL, get_HWCRHK_LIBNAME(), NULL, 0); - if (hwcrhk_dso == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE); - goto err; - } - if (!(p1 = (HWCryptoHook_Init_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_Init)) || - !(p2 = (HWCryptoHook_Finish_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_Finish)) || - !(p3 = (HWCryptoHook_ModExp_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExp)) || -# ifndef OPENSSL_NO_RSA - !(p4 = (HWCryptoHook_RSA_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSA)) || - !(p5 = (HWCryptoHook_RSALoadKey_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSALoadKey)) || - !(p6 = (HWCryptoHook_RSAGetPublicKey_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAGetPublicKey)) || - !(p7 = (HWCryptoHook_RSAUnloadKey_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_RSAUnloadKey)) || -# endif - !(p8 = (HWCryptoHook_RandomBytes_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_RandomBytes)) || - !(p9 = (HWCryptoHook_ModExpCRT_t *) - DSO_bind_func(hwcrhk_dso, n_hwcrhk_ModExpCRT))) { - HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_DSO_FAILURE); - goto err; - } - /* Copy the pointers */ - p_hwcrhk_Init = p1; - p_hwcrhk_Finish = p2; - p_hwcrhk_ModExp = p3; -# ifndef OPENSSL_NO_RSA - p_hwcrhk_RSA = p4; - p_hwcrhk_RSALoadKey = p5; - p_hwcrhk_RSAGetPublicKey = p6; - p_hwcrhk_RSAUnloadKey = p7; -# endif - p_hwcrhk_RandomBytes = p8; - p_hwcrhk_ModExpCRT = p9; - - /* - * Check if the application decided to support dynamic locks, and if it - * does, use them. - */ - if (disable_mutex_callbacks == 0) { - if (CRYPTO_get_dynlock_create_callback() != NULL && - CRYPTO_get_dynlock_lock_callback() != NULL && - CRYPTO_get_dynlock_destroy_callback() != NULL) { - hwcrhk_globals.mutex_init = hwcrhk_mutex_init; - hwcrhk_globals.mutex_acquire = hwcrhk_mutex_lock; - hwcrhk_globals.mutex_release = hwcrhk_mutex_unlock; - hwcrhk_globals.mutex_destroy = hwcrhk_mutex_destroy; - } - } - - /* - * Try and get a context - if not, we may have a DSO but no accelerator! - */ - if (!get_context(&hwcrhk_context, &password_context)) { - HWCRHKerr(HWCRHK_F_HWCRHK_INIT, HWCRHK_R_UNIT_FAILURE); - goto err; - } - /* Everything's fine. */ -# ifndef OPENSSL_NO_RSA - if (hndidx_rsa == -1) - hndidx_rsa = RSA_get_ex_new_index(0, - "nFast HWCryptoHook RSA key handle", - NULL, NULL, NULL); -# endif - return 1; - err: - if (hwcrhk_dso) - DSO_free(hwcrhk_dso); - hwcrhk_dso = NULL; - p_hwcrhk_Init = NULL; - p_hwcrhk_Finish = NULL; - p_hwcrhk_ModExp = NULL; -# ifndef OPENSSL_NO_RSA - p_hwcrhk_RSA = NULL; - p_hwcrhk_RSALoadKey = NULL; - p_hwcrhk_RSAGetPublicKey = NULL; - p_hwcrhk_RSAUnloadKey = NULL; -# endif - p_hwcrhk_ModExpCRT = NULL; - p_hwcrhk_RandomBytes = NULL; - return 0; -} - -static int hwcrhk_finish(ENGINE *e) -{ - int to_return = 1; - free_HWCRHK_LIBNAME(); - if (hwcrhk_dso == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_NOT_LOADED); - to_return = 0; - goto err; - } - release_context(hwcrhk_context); - if (!DSO_free(hwcrhk_dso)) { - HWCRHKerr(HWCRHK_F_HWCRHK_FINISH, HWCRHK_R_DSO_FAILURE); - to_return = 0; - goto err; - } - err: - if (logstream) - BIO_free(logstream); - hwcrhk_dso = NULL; - p_hwcrhk_Init = NULL; - p_hwcrhk_Finish = NULL; - p_hwcrhk_ModExp = NULL; -# ifndef OPENSSL_NO_RSA - p_hwcrhk_RSA = NULL; - p_hwcrhk_RSALoadKey = NULL; - p_hwcrhk_RSAGetPublicKey = NULL; - p_hwcrhk_RSAUnloadKey = NULL; -# endif - p_hwcrhk_ModExpCRT = NULL; - p_hwcrhk_RandomBytes = NULL; - return to_return; -} - -static int hwcrhk_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int to_return = 1; - - switch (cmd) { - case HWCRHK_CMD_SO_PATH: - if (hwcrhk_dso) { - HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_ALREADY_LOADED); - return 0; - } - if (p == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - return set_HWCRHK_LIBNAME((const char *)p); - case ENGINE_CTRL_SET_LOGSTREAM: - { - BIO *bio = (BIO *)p; - - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (logstream) { - BIO_free(logstream); - logstream = NULL; - } - if (CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO) > 1) - logstream = bio; - else - HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, HWCRHK_R_BIO_WAS_FREED); - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - case ENGINE_CTRL_SET_PASSWORD_CALLBACK: - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - password_context.password_callback = (pem_password_cb *)f; - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - case ENGINE_CTRL_SET_USER_INTERFACE: - case HWCRHK_CMD_SET_USER_INTERFACE: - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - password_context.ui_method = (UI_METHOD *)p; - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - case ENGINE_CTRL_SET_CALLBACK_DATA: - case HWCRHK_CMD_SET_CALLBACK_DATA: - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - password_context.callback_data = p; - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - /* - * this enables or disables the "SimpleForkCheck" flag used in the - * initialisation structure. - */ - case ENGINE_CTRL_CHIL_SET_FORKCHECK: - case HWCRHK_CMD_FORK_CHECK: - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (i) - hwcrhk_globals.flags |= HWCryptoHook_InitFlags_SimpleForkCheck; - else - hwcrhk_globals.flags &= ~HWCryptoHook_InitFlags_SimpleForkCheck; - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - /* - * This will prevent the initialisation function from "installing" - * the mutex-handling callbacks, even if they are available from - * within the library (or were provided to the library from the - * calling application). This is to remove any baggage for - * applications not using multithreading. - */ - case ENGINE_CTRL_CHIL_NO_LOCKING: - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - disable_mutex_callbacks = 1; - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - case HWCRHK_CMD_THREAD_LOCKING: - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - disable_mutex_callbacks = ((i == 0) ? 0 : 1); - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - - /* The command isn't understood by this engine */ - default: - HWCRHKerr(HWCRHK_F_HWCRHK_CTRL, - HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); - to_return = 0; - break; - } - - return to_return; -} - -static EVP_PKEY *hwcrhk_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, - void *callback_data) -{ -# ifndef OPENSSL_NO_RSA - RSA *rtmp = NULL; -# endif - EVP_PKEY *res = NULL; -# ifndef OPENSSL_NO_RSA - HWCryptoHook_MPI e, n; - HWCryptoHook_RSAKeyHandle *hptr; -# endif -# if !defined(OPENSSL_NO_RSA) - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - HWCryptoHook_PassphraseContext ppctx; -# endif - -# if !defined(OPENSSL_NO_RSA) - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); -# endif - - if (!hwcrhk_context) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NOT_INITIALISED); - goto err; - } -# ifndef OPENSSL_NO_RSA - hptr = OPENSSL_malloc(sizeof(HWCryptoHook_RSAKeyHandle)); - if (!hptr) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - ppctx.ui_method = ui_method; - ppctx.callback_data = callback_data; - if (p_hwcrhk_RSALoadKey(hwcrhk_context, key_id, hptr, &rmsg, &ppctx)) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); - ERR_add_error_data(1, rmsg.buf); - goto err; - } - if (!*hptr) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_NO_KEY); - goto err; - } -# endif -# ifndef OPENSSL_NO_RSA - rtmp = RSA_new_method(eng); - if (rtmp == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - RSA_set_ex_data(rtmp, hndidx_rsa, (char *)hptr); - rtmp->e = BN_new(); - rtmp->n = BN_new(); - if (rtmp->e == NULL || rtmp->n == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - rtmp->flags |= RSA_FLAG_EXT_PKEY; - MPI2BN(rtmp->e, e); - MPI2BN(rtmp->n, n); - if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg) - != HWCRYPTOHOOK_ERROR_MPISIZE) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); - ERR_add_error_data(1, rmsg.buf); - goto err; - } - - if (bn_expand2(rtmp->e, e.size / sizeof(BN_ULONG)) == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - if (bn_expand2(rtmp->n, n.size / sizeof(BN_ULONG)) == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - MPI2BN(rtmp->e, e); - MPI2BN(rtmp->n, n); - - if (p_hwcrhk_RSAGetPublicKey(*hptr, &n, &e, &rmsg)) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); - ERR_add_error_data(1, rmsg.buf); - goto err; - } - rtmp->e->top = e.size / sizeof(BN_ULONG); - bn_fix_top(rtmp->e); - rtmp->n->top = n.size / sizeof(BN_ULONG); - bn_fix_top(rtmp->n); - - res = EVP_PKEY_new(); - if (res == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, HWCRHK_R_CHIL_ERROR); - goto err; - } - EVP_PKEY_assign_RSA(res, rtmp); -# endif - - if (!res) - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PRIVKEY, - HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED); - - return res; - err: -# ifndef OPENSSL_NO_RSA - if (rtmp) - RSA_free(rtmp); -# endif - return NULL; -} - -static EVP_PKEY *hwcrhk_load_pubkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, void *callback_data) -{ - EVP_PKEY *res = NULL; - -# ifndef OPENSSL_NO_RSA - res = hwcrhk_load_privkey(eng, key_id, ui_method, callback_data); -# endif - - if (res) - switch (res->type) { -# ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - { - RSA *rsa = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); - rsa = res->pkey.rsa; - res->pkey.rsa = RSA_new(); - res->pkey.rsa->n = rsa->n; - res->pkey.rsa->e = rsa->e; - rsa->n = NULL; - rsa->e = NULL; - CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); - RSA_free(rsa); - } - break; -# endif - default: - HWCRHKerr(HWCRHK_F_HWCRHK_LOAD_PUBKEY, - HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED); - goto err; - } - - return res; - err: - if (res) - EVP_PKEY_free(res); - return NULL; -} - -/* A little mod_exp */ -static int hwcrhk_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - /* - * Since HWCryptoHook_MPI is pretty compatible with BIGNUM's, we use them - * directly, plus a little macro magic. We only thing we need to make - * sure of is that enough space is allocated. - */ - HWCryptoHook_MPI m_a, m_p, m_n, m_r; - int to_return, ret; - - to_return = 0; /* expect failure */ - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - - if (!hwcrhk_context) { - HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_NOT_INITIALISED); - goto err; - } - /* Prepare the params */ - if (bn_expand2(r, m->top) == NULL) { /* Check for error !! */ - HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, ERR_R_MALLOC_FAILURE); - goto err; - } - BN2MPI(m_a, a); - BN2MPI(m_p, p); - BN2MPI(m_n, m); - MPI2BN(r, m_r); - - /* Perform the operation */ - ret = p_hwcrhk_ModExp(hwcrhk_context, m_a, m_p, m_n, &m_r, &rmsg); - - /* Convert the response */ - r->top = m_r.size / sizeof(BN_ULONG); - bn_fix_top(r); - - if (ret < 0) { - /* - * FIXME: When this error is returned, HWCryptoHook is telling us - * that falling back to software computation might be a good thing. - */ - if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FALLBACK); - } else { - HWCRHKerr(HWCRHK_F_HWCRHK_MOD_EXP, HWCRHK_R_REQUEST_FAILED); - } - ERR_add_error_data(1, rmsg.buf); - goto err; - } - - to_return = 1; - err: - return to_return; -} - -# ifndef OPENSSL_NO_RSA -static int hwcrhk_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - HWCryptoHook_RSAKeyHandle *hptr; - int to_return = 0, ret; - - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - - if (!hwcrhk_context) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, HWCRHK_R_NOT_INITIALISED); - goto err; - } - - /* - * This provides support for nForce keys. Since that's opaque data all - * we do is provide a handle to the proper key and let HWCryptoHook take - * care of the rest. - */ - if ((hptr = - (HWCryptoHook_RSAKeyHandle *) RSA_get_ex_data(rsa, hndidx_rsa)) - != NULL) { - HWCryptoHook_MPI m_a, m_r; - - if (!rsa->n) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_MISSING_KEY_COMPONENTS); - goto err; - } - - /* Prepare the params */ - if (bn_expand2(r, rsa->n->top) == NULL) { /* Check for error !! */ - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, ERR_R_MALLOC_FAILURE); - goto err; - } - BN2MPI(m_a, I); - MPI2BN(r, m_r); - - /* Perform the operation */ - ret = p_hwcrhk_RSA(m_a, *hptr, &m_r, &rmsg); - - /* Convert the response */ - r->top = m_r.size / sizeof(BN_ULONG); - bn_fix_top(r); - - if (ret < 0) { - /* - * FIXME: When this error is returned, HWCryptoHook is telling us - * that falling back to software computation might be a good - * thing. - */ - if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_REQUEST_FALLBACK); - } else { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_REQUEST_FAILED); - } - ERR_add_error_data(1, rmsg.buf); - goto err; - } - } else { - HWCryptoHook_MPI m_a, m_p, m_q, m_dmp1, m_dmq1, m_iqmp, m_r; - - if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_MISSING_KEY_COMPONENTS); - goto err; - } - - /* Prepare the params */ - if (bn_expand2(r, rsa->n->top) == NULL) { /* Check for error !! */ - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, ERR_R_MALLOC_FAILURE); - goto err; - } - BN2MPI(m_a, I); - BN2MPI(m_p, rsa->p); - BN2MPI(m_q, rsa->q); - BN2MPI(m_dmp1, rsa->dmp1); - BN2MPI(m_dmq1, rsa->dmq1); - BN2MPI(m_iqmp, rsa->iqmp); - MPI2BN(r, m_r); - - /* Perform the operation */ - ret = p_hwcrhk_ModExpCRT(hwcrhk_context, m_a, m_p, m_q, - m_dmp1, m_dmq1, m_iqmp, &m_r, &rmsg); - - /* Convert the response */ - r->top = m_r.size / sizeof(BN_ULONG); - bn_fix_top(r); - - if (ret < 0) { - /* - * FIXME: When this error is returned, HWCryptoHook is telling us - * that falling back to software computation might be a good - * thing. - */ - if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_REQUEST_FALLBACK); - } else { - HWCRHKerr(HWCRHK_F_HWCRHK_RSA_MOD_EXP, - HWCRHK_R_REQUEST_FAILED); - } - ERR_add_error_data(1, rmsg.buf); - goto err; - } - } - /* - * If we're here, we must be here with some semblance of success :-) - */ - to_return = 1; - err: - return to_return; -} -# endif - -# ifndef OPENSSL_NO_RSA -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int hwcrhk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return hwcrhk_mod_exp(r, a, p, m, ctx); -} - -static int hwcrhk_rsa_finish(RSA *rsa) -{ - HWCryptoHook_RSAKeyHandle *hptr; - - hptr = RSA_get_ex_data(rsa, hndidx_rsa); - if (hptr) { - p_hwcrhk_RSAUnloadKey(*hptr, NULL); - OPENSSL_free(hptr); - RSA_set_ex_data(rsa, hndidx_rsa, NULL); - } - return 1; -} - -# endif - -# ifndef OPENSSL_NO_DH -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int hwcrhk_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return hwcrhk_mod_exp(r, a, p, m, ctx); -} -# endif - -/* Random bytes are good */ -static int hwcrhk_rand_bytes(unsigned char *buf, int num) -{ - char tempbuf[1024]; - HWCryptoHook_ErrMsgBuf rmsg; - int to_return = 0; /* assume failure */ - int ret; - - rmsg.buf = tempbuf; - rmsg.size = sizeof(tempbuf); - - if (!hwcrhk_context) { - HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_NOT_INITIALISED); - goto err; - } - - ret = p_hwcrhk_RandomBytes(hwcrhk_context, buf, num, &rmsg); - if (ret < 0) { - /* - * FIXME: When this error is returned, HWCryptoHook is telling us - * that falling back to software computation might be a good thing. - */ - if (ret == HWCRYPTOHOOK_ERROR_FALLBACK) { - HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FALLBACK); - } else { - HWCRHKerr(HWCRHK_F_HWCRHK_RAND_BYTES, HWCRHK_R_REQUEST_FAILED); - } - ERR_add_error_data(1, rmsg.buf); - goto err; - } - to_return = 1; - err: - return to_return; -} - -static int hwcrhk_rand_status(void) -{ - return 1; -} - -/* - * Mutex calls: since the HWCryptoHook model closely follows the POSIX model - * these just wrap the POSIX functions and add some logging. - */ - -static int hwcrhk_mutex_init(HWCryptoHook_Mutex * mt, - HWCryptoHook_CallerContext * cactx) -{ - mt->lockid = CRYPTO_get_new_dynlockid(); - if (mt->lockid == 0) - return 1; /* failure */ - return 0; /* success */ -} - -static int hwcrhk_mutex_lock(HWCryptoHook_Mutex * mt) -{ - CRYPTO_w_lock(mt->lockid); - return 0; -} - -static void hwcrhk_mutex_unlock(HWCryptoHook_Mutex * mt) -{ - CRYPTO_w_unlock(mt->lockid); -} - -static void hwcrhk_mutex_destroy(HWCryptoHook_Mutex * mt) -{ - CRYPTO_destroy_dynlockid(mt->lockid); -} - -static int hwcrhk_get_pass(const char *prompt_info, - int *len_io, char *buf, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx) -{ - pem_password_cb *callback = NULL; - void *callback_data = NULL; - UI_METHOD *ui_method = NULL; - /* - * Despite what the documentation says prompt_info can be an empty - * string. - */ - if (prompt_info && !*prompt_info) - prompt_info = NULL; - - if (cactx) { - if (cactx->ui_method) - ui_method = cactx->ui_method; - if (cactx->password_callback) - callback = cactx->password_callback; - if (cactx->callback_data) - callback_data = cactx->callback_data; - } - if (ppctx) { - if (ppctx->ui_method) { - ui_method = ppctx->ui_method; - callback = NULL; - } - if (ppctx->callback_data) - callback_data = ppctx->callback_data; - } - if (callback == NULL && ui_method == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_GET_PASS, HWCRHK_R_NO_CALLBACK); - return -1; - } - - if (ui_method) { - UI *ui = UI_new_method(ui_method); - if (ui) { - int ok; - char *prompt = UI_construct_prompt(ui, - "pass phrase", prompt_info); - - ok = UI_add_input_string(ui, prompt, - UI_INPUT_FLAG_DEFAULT_PWD, - buf, 0, (*len_io) - 1); - UI_add_user_data(ui, callback_data); - UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0); - - if (ok >= 0) - do { - ok = UI_process(ui); - } - while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0)); - - if (ok >= 0) - *len_io = strlen(buf); - - UI_free(ui); - OPENSSL_free(prompt); - } - } else { - *len_io = callback(buf, *len_io, 0, callback_data); - } - if (!*len_io) - return -1; - return 0; -} - -static int hwcrhk_insert_card(const char *prompt_info, - const char *wrong_info, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx) -{ - int ok = -1; - UI *ui; - void *callback_data = NULL; - UI_METHOD *ui_method = NULL; - - if (cactx) { - if (cactx->ui_method) - ui_method = cactx->ui_method; - if (cactx->callback_data) - callback_data = cactx->callback_data; - } - if (ppctx) { - if (ppctx->ui_method) - ui_method = ppctx->ui_method; - if (ppctx->callback_data) - callback_data = ppctx->callback_data; - } - if (ui_method == NULL) { - HWCRHKerr(HWCRHK_F_HWCRHK_INSERT_CARD, HWCRHK_R_NO_CALLBACK); - return -1; - } - - ui = UI_new_method(ui_method); - - if (ui) { - char answer = '\0'; - char buf[BUFSIZ]; - /* - * Despite what the documentation says wrong_info can be an empty - * string. - */ - if (wrong_info && *wrong_info) - BIO_snprintf(buf, sizeof(buf) - 1, - "Current card: \"%s\"\n", wrong_info); - else - buf[0] = 0; - ok = UI_dup_info_string(ui, buf); - if (ok >= 0 && prompt_info) { - BIO_snprintf(buf, sizeof(buf) - 1, - "Insert card \"%s\"", prompt_info); - ok = UI_dup_input_boolean(ui, buf, - "\n then hit or C to cancel\n", - "\r\n", "Cc", UI_INPUT_FLAG_ECHO, - &answer); - } - UI_add_user_data(ui, callback_data); - - if (ok >= 0) - ok = UI_process(ui); - UI_free(ui); - - if (ok == -2 || (ok >= 0 && answer == 'C')) - ok = 1; - else if (ok < 0) - ok = -1; - else - ok = 0; - } - return ok; -} - -static void hwcrhk_log_message(void *logstr, const char *message) -{ - BIO *lstream = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_BIO); - if (logstr) - lstream = *(BIO **)logstr; - if (lstream) { - BIO_printf(lstream, "%s\n", message); - } - CRYPTO_w_unlock(CRYPTO_LOCK_BIO); -} - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_hwcrhk_id) != 0) && - (strcmp(id, engine_hwcrhk_id_alt) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ -# endif /* !OPENSSL_NO_HW_CHIL */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_chil_err.c b/Sources/COpenSSL/e_chil_err.c deleted file mode 100644 index f341cc3c..00000000 --- a/Sources/COpenSSL/e_chil_err.c +++ /dev/null @@ -1,157 +0,0 @@ -/* e_chil_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_chil_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA HWCRHK_str_functs[] = { - {ERR_FUNC(HWCRHK_F_HWCRHK_CTRL), "HWCRHK_CTRL"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_FINISH), "HWCRHK_FINISH"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_GET_PASS), "HWCRHK_GET_PASS"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_INIT), "HWCRHK_INIT"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_INSERT_CARD), "HWCRHK_INSERT_CARD"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PRIVKEY), "HWCRHK_LOAD_PRIVKEY"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_LOAD_PUBKEY), "HWCRHK_LOAD_PUBKEY"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_MOD_EXP), "HWCRHK_MOD_EXP"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_RAND_BYTES), "HWCRHK_RAND_BYTES"}, - {ERR_FUNC(HWCRHK_F_HWCRHK_RSA_MOD_EXP), "HWCRHK_RSA_MOD_EXP"}, - {0, NULL} -}; - -static ERR_STRING_DATA HWCRHK_str_reasons[] = { - {ERR_REASON(HWCRHK_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(HWCRHK_R_BIO_WAS_FREED), "bio was freed"}, - {ERR_REASON(HWCRHK_R_CHIL_ERROR), "chil error"}, - {ERR_REASON(HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(HWCRHK_R_DSO_FAILURE), "dso failure"}, - {ERR_REASON(HWCRHK_R_MISSING_KEY_COMPONENTS), "missing key components"}, - {ERR_REASON(HWCRHK_R_NOT_INITIALISED), "not initialised"}, - {ERR_REASON(HWCRHK_R_NOT_LOADED), "not loaded"}, - {ERR_REASON(HWCRHK_R_NO_CALLBACK), "no callback"}, - {ERR_REASON(HWCRHK_R_NO_KEY), "no key"}, - {ERR_REASON(HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED), - "private key algorithms disabled"}, - {ERR_REASON(HWCRHK_R_REQUEST_FAILED), "request failed"}, - {ERR_REASON(HWCRHK_R_REQUEST_FALLBACK), "request fallback"}, - {ERR_REASON(HWCRHK_R_UNIT_FAILURE), "unit failure"}, - {0, NULL} -}; - -#endif - -#ifdef HWCRHK_LIB_NAME -static ERR_STRING_DATA HWCRHK_lib_name[] = { - {0, HWCRHK_LIB_NAME}, - {0, NULL} -}; -#endif - -static int HWCRHK_lib_error_code = 0; -static int HWCRHK_error_init = 1; - -static void ERR_load_HWCRHK_strings(void) -{ - if (HWCRHK_lib_error_code == 0) - HWCRHK_lib_error_code = ERR_get_next_error_library(); - - if (HWCRHK_error_init) { - HWCRHK_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(HWCRHK_lib_error_code, HWCRHK_str_functs); - ERR_load_strings(HWCRHK_lib_error_code, HWCRHK_str_reasons); -#endif - -#ifdef HWCRHK_LIB_NAME - HWCRHK_lib_name->error = ERR_PACK(HWCRHK_lib_error_code, 0, 0); - ERR_load_strings(0, HWCRHK_lib_name); -#endif - } -} - -static void ERR_unload_HWCRHK_strings(void) -{ - if (HWCRHK_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(HWCRHK_lib_error_code, HWCRHK_str_functs); - ERR_unload_strings(HWCRHK_lib_error_code, HWCRHK_str_reasons); -#endif - -#ifdef HWCRHK_LIB_NAME - ERR_unload_strings(0, HWCRHK_lib_name); -#endif - HWCRHK_error_init = 1; - } -} - -static void ERR_HWCRHK_error(int function, int reason, char *file, int line) -{ - if (HWCRHK_lib_error_code == 0) - HWCRHK_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(HWCRHK_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_chil_err.h b/Sources/COpenSSL/e_chil_err.h deleted file mode 100644 index d86a4ce9..00000000 --- a/Sources/COpenSSL/e_chil_err.h +++ /dev/null @@ -1,105 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_HWCRHK_ERR_H -# define HEADER_HWCRHK_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_HWCRHK_strings(void); -static void ERR_unload_HWCRHK_strings(void); -static void ERR_HWCRHK_error(int function, int reason, char *file, int line); -# define HWCRHKerr(f,r) ERR_HWCRHK_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the HWCRHK functions. */ - -/* Function codes. */ -# define HWCRHK_F_HWCRHK_CTRL 100 -# define HWCRHK_F_HWCRHK_FINISH 101 -# define HWCRHK_F_HWCRHK_GET_PASS 102 -# define HWCRHK_F_HWCRHK_INIT 103 -# define HWCRHK_F_HWCRHK_INSERT_CARD 104 -# define HWCRHK_F_HWCRHK_LOAD_PRIVKEY 105 -# define HWCRHK_F_HWCRHK_LOAD_PUBKEY 106 -# define HWCRHK_F_HWCRHK_MOD_EXP 107 -# define HWCRHK_F_HWCRHK_RAND_BYTES 108 -# define HWCRHK_F_HWCRHK_RSA_MOD_EXP 109 - -/* Reason codes. */ -# define HWCRHK_R_ALREADY_LOADED 100 -# define HWCRHK_R_BIO_WAS_FREED 101 -# define HWCRHK_R_CHIL_ERROR 102 -# define HWCRHK_R_CTRL_COMMAND_NOT_IMPLEMENTED 103 -# define HWCRHK_R_DSO_FAILURE 104 -# define HWCRHK_R_MISSING_KEY_COMPONENTS 105 -# define HWCRHK_R_NOT_INITIALISED 106 -# define HWCRHK_R_NOT_LOADED 107 -# define HWCRHK_R_NO_CALLBACK 108 -# define HWCRHK_R_NO_KEY 109 -# define HWCRHK_R_PRIVATE_KEY_ALGORITHMS_DISABLED 110 -# define HWCRHK_R_REQUEST_FAILED 111 -# define HWCRHK_R_REQUEST_FALLBACK 112 -# define HWCRHK_R_UNIT_FAILURE 113 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_cswift.c b/Sources/COpenSSL/e_cswift.c deleted file mode 100644 index aff8bb7a..00000000 --- a/Sources/COpenSSL/e_cswift.c +++ /dev/null @@ -1,1104 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/engine/hw_cswift.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "crypto.h" -#include "buffer.h" -#include "dso.h" -#include "engine.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#include "rand.h" -#include "bn.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_CSWIFT - -/* - * Attribution notice: Rainbow have generously allowed me to reproduce the - * necessary definitions here from their API. This means the support can - * build independently of whether application builders have the API or - * hardware. This will allow developers to easily produce software that has - * latent hardware support for any users that have accelerators installed, - * without the developers themselves needing anything extra. I have only - * clipped the parts from the CryptoSwift header files that are (or seem) - * relevant to the CryptoSwift support code. This is simply to keep the file - * sizes reasonable. [Geoff] - */ -# ifdef FLAT_INC -# include "cswift.h" -# else -# include "cswift.h" -# endif - -# define CSWIFT_LIB_NAME "cswift engine" -# include "e_cswift_err.c" - -# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) - -static int cswift_destroy(ENGINE *e); -static int cswift_init(ENGINE *e); -static int cswift_finish(ENGINE *e); -static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); -# ifndef OPENSSL_NO_RSA -static int cswift_bn_32copy(SW_LARGENUMBER *out, const BIGNUM *in); -# endif - -/* BIGNUM stuff */ -static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); -# ifndef OPENSSL_NO_RSA -static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *q, const BIGNUM *dmp1, - const BIGNUM *dmq1, const BIGNUM *iqmp, - BN_CTX *ctx); -# endif - -# ifndef OPENSSL_NO_RSA -/* RSA stuff */ -static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -# ifndef OPENSSL_NO_DSA -/* DSA stuff */ -static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, - DSA *dsa); -static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa); -# endif - -# ifndef OPENSSL_NO_DH -/* DH stuff */ -/* This function is alised to mod_exp (with the DH and mont dropped). */ -static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif - -/* RAND stuff */ -static int cswift_rand_bytes(unsigned char *buf, int num); -static int cswift_rand_status(void); - -/* The definitions for control commands specific to this engine */ -# define CSWIFT_CMD_SO_PATH ENGINE_CMD_BASE -static const ENGINE_CMD_DEFN cswift_cmd_defns[] = { - {CSWIFT_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'cswift' shared library", - ENGINE_CMD_FLAG_STRING}, - {0, NULL, NULL, 0} -}; - -# ifndef OPENSSL_NO_RSA -/* Our internal RSA_METHOD that we provide pointers to */ -static RSA_METHOD cswift_rsa = { - "CryptoSwift RSA method", - NULL, - NULL, - NULL, - NULL, - cswift_rsa_mod_exp, - cswift_mod_exp_mont, - NULL, - NULL, - 0, - NULL, - NULL, - NULL, - NULL -}; -# endif - -# ifndef OPENSSL_NO_DSA -/* Our internal DSA_METHOD that we provide pointers to */ -static DSA_METHOD cswift_dsa = { - "CryptoSwift DSA method", - cswift_dsa_sign, - NULL, /* dsa_sign_setup */ - cswift_dsa_verify, - NULL, /* dsa_mod_exp */ - NULL, /* bn_mod_exp */ - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - NULL, /* dsa_paramgen */ - NULL /* dsa_keygen */ -}; -# endif - -# ifndef OPENSSL_NO_DH -/* Our internal DH_METHOD that we provide pointers to */ -static DH_METHOD cswift_dh = { - "CryptoSwift DH method", - NULL, - NULL, - cswift_mod_exp_dh, - NULL, - NULL, - 0, - NULL, - NULL -}; -# endif - -static RAND_METHOD cswift_random = { - /* "CryptoSwift RAND method", */ - NULL, - cswift_rand_bytes, - NULL, - NULL, - cswift_rand_bytes, - cswift_rand_status, -}; - -/* Constants used when creating the ENGINE */ -static const char *engine_cswift_id = "cswift"; -static const char *engine_cswift_name = "CryptoSwift hardware engine support"; - -/* - * This internal function is used by ENGINE_cswift() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_helper(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif -# ifndef OPENSSL_NO_DH - const DH_METHOD *meth2; -# endif - if (!ENGINE_set_id(e, engine_cswift_id) || - !ENGINE_set_name(e, engine_cswift_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &cswift_rsa) || -# endif -# ifndef OPENSSL_NO_DSA - !ENGINE_set_DSA(e, &cswift_dsa) || -# endif -# ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &cswift_dh) || -# endif - !ENGINE_set_RAND(e, &cswift_random) || - !ENGINE_set_destroy_function(e, cswift_destroy) || - !ENGINE_set_init_function(e, cswift_init) || - !ENGINE_set_finish_function(e, cswift_finish) || - !ENGINE_set_ctrl_function(e, cswift_ctrl) || - !ENGINE_set_cmd_defns(e, cswift_cmd_defns)) - return 0; - -# ifndef OPENSSL_NO_RSA - /* - * We know that the "PKCS1_SSLeay()" functions hook properly to the - * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: - * We don't use ENGINE_openssl() or anything "more generic" because - * something like the RSAref code may not hook properly, and if you own - * one of these cards then you have the right to do RSA operations on it - * anyway! - */ - meth1 = RSA_PKCS1_SSLeay(); - cswift_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - cswift_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - cswift_rsa.rsa_priv_enc = meth1->rsa_priv_enc; - cswift_rsa.rsa_priv_dec = meth1->rsa_priv_dec; -# endif - -# ifndef OPENSSL_NO_DH - /* Much the same for Diffie-Hellman */ - meth2 = DH_OpenSSL(); - cswift_dh.generate_key = meth2->generate_key; - cswift_dh.compute_key = meth2->compute_key; -# endif - - /* Ensure the cswift error handling is set up */ - ERR_load_CSWIFT_strings(); - return 1; -} - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE -static ENGINE *engine_cswift(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_cswift(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_cswift(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -/* - * This is a process-global DSO handle used for loading and unloading the - * CryptoSwift library. NB: This is only set (or unset) during an init() or - * finish() call (reference counts permitting) and they're operating with - * global locks, so this should be thread-safe implicitly. - */ -static DSO *cswift_dso = NULL; - -/* - * These are the function pointers that are (un)set when the library has - * successfully (un)loaded. - */ -t_swAcquireAccContext *p_CSwift_AcquireAccContext = NULL; -t_swAttachKeyParam *p_CSwift_AttachKeyParam = NULL; -t_swSimpleRequest *p_CSwift_SimpleRequest = NULL; -t_swReleaseAccContext *p_CSwift_ReleaseAccContext = NULL; - -/* Used in the DSO operations. */ -static const char *CSWIFT_LIBNAME = NULL; -static const char *get_CSWIFT_LIBNAME(void) -{ - if (CSWIFT_LIBNAME) - return CSWIFT_LIBNAME; - return "swift"; -} - -static void free_CSWIFT_LIBNAME(void) -{ - if (CSWIFT_LIBNAME) - OPENSSL_free((void *)CSWIFT_LIBNAME); - CSWIFT_LIBNAME = NULL; -} - -static long set_CSWIFT_LIBNAME(const char *name) -{ - free_CSWIFT_LIBNAME(); - return (((CSWIFT_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); -} - -static const char *CSWIFT_F1 = "swAcquireAccContext"; -static const char *CSWIFT_F2 = "swAttachKeyParam"; -static const char *CSWIFT_F3 = "swSimpleRequest"; -static const char *CSWIFT_F4 = "swReleaseAccContext"; - -/* - * CryptoSwift library functions and mechanics - these are used by the - * higher-level functions further down. NB: As and where there's no error - * checking, take a look lower down where these functions are called, the - * checking and error handling is probably down there. - */ - -/* utility function to obtain a context */ -static int get_context(SW_CONTEXT_HANDLE *hac) -{ - SW_STATUS status; - - status = p_CSwift_AcquireAccContext(hac); - if (status != SW_OK) - return 0; - return 1; -} - -/* similarly to release one. */ -static void release_context(SW_CONTEXT_HANDLE hac) -{ - p_CSwift_ReleaseAccContext(hac); -} - -/* Destructor (complements the "ENGINE_cswift()" constructor) */ -static int cswift_destroy(ENGINE *e) -{ - free_CSWIFT_LIBNAME(); - ERR_unload_CSWIFT_strings(); - return 1; -} - -/* (de)initialisation functions. */ -static int cswift_init(ENGINE *e) -{ - SW_CONTEXT_HANDLE hac; - t_swAcquireAccContext *p1; - t_swAttachKeyParam *p2; - t_swSimpleRequest *p3; - t_swReleaseAccContext *p4; - - if (cswift_dso != NULL) { - CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_ALREADY_LOADED); - goto err; - } - /* Attempt to load libswift.so/swift.dll/whatever. */ - cswift_dso = DSO_load(NULL, get_CSWIFT_LIBNAME(), NULL, 0); - if (cswift_dso == NULL) { - CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_NOT_LOADED); - goto err; - } - if (!(p1 = (t_swAcquireAccContext *) - DSO_bind_func(cswift_dso, CSWIFT_F1)) || - !(p2 = (t_swAttachKeyParam *) - DSO_bind_func(cswift_dso, CSWIFT_F2)) || - !(p3 = (t_swSimpleRequest *) - DSO_bind_func(cswift_dso, CSWIFT_F3)) || - !(p4 = (t_swReleaseAccContext *) - DSO_bind_func(cswift_dso, CSWIFT_F4))) { - CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_NOT_LOADED); - goto err; - } - /* Copy the pointers */ - p_CSwift_AcquireAccContext = p1; - p_CSwift_AttachKeyParam = p2; - p_CSwift_SimpleRequest = p3; - p_CSwift_ReleaseAccContext = p4; - /* - * Try and get a context - if not, we may have a DSO but no accelerator! - */ - if (!get_context(&hac)) { - CSWIFTerr(CSWIFT_F_CSWIFT_INIT, CSWIFT_R_UNIT_FAILURE); - goto err; - } - release_context(hac); - /* Everything's fine. */ - return 1; - err: - if (cswift_dso) { - DSO_free(cswift_dso); - cswift_dso = NULL; - } - p_CSwift_AcquireAccContext = NULL; - p_CSwift_AttachKeyParam = NULL; - p_CSwift_SimpleRequest = NULL; - p_CSwift_ReleaseAccContext = NULL; - return 0; -} - -static int cswift_finish(ENGINE *e) -{ - free_CSWIFT_LIBNAME(); - if (cswift_dso == NULL) { - CSWIFTerr(CSWIFT_F_CSWIFT_FINISH, CSWIFT_R_NOT_LOADED); - return 0; - } - if (!DSO_free(cswift_dso)) { - CSWIFTerr(CSWIFT_F_CSWIFT_FINISH, CSWIFT_R_UNIT_FAILURE); - return 0; - } - cswift_dso = NULL; - p_CSwift_AcquireAccContext = NULL; - p_CSwift_AttachKeyParam = NULL; - p_CSwift_SimpleRequest = NULL; - p_CSwift_ReleaseAccContext = NULL; - return 1; -} - -static int cswift_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int initialised = ((cswift_dso == NULL) ? 0 : 1); - switch (cmd) { - case CSWIFT_CMD_SO_PATH: - if (p == NULL) { - CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (initialised) { - CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_ALREADY_LOADED); - return 0; - } - return set_CSWIFT_LIBNAME((const char *)p); - default: - break; - } - CSWIFTerr(CSWIFT_F_CSWIFT_CTRL, CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED); - return 0; -} - -/* Un petit mod_exp */ -static int cswift_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - /* - * I need somewhere to store temporary serialised values for use with the - * CryptoSwift API calls. A neat cheat - I'll use BIGNUMs from the BN_CTX - * but access their arrays directly as byte arrays . This way I - * don't have to clean anything up. - */ - BIGNUM *modulus; - BIGNUM *exponent; - BIGNUM *argument; - BIGNUM *result; - SW_STATUS sw_status; - SW_LARGENUMBER arg, res; - SW_PARAM sw_param; - SW_CONTEXT_HANDLE hac; - int to_return, acquired; - - modulus = exponent = argument = result = NULL; - to_return = 0; /* expect failure */ - acquired = 0; - - if (!get_context(&hac)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_UNIT_FAILURE); - goto err; - } - acquired = 1; - /* Prepare the params */ - BN_CTX_start(ctx); - modulus = BN_CTX_get(ctx); - exponent = BN_CTX_get(ctx); - argument = BN_CTX_get(ctx); - result = BN_CTX_get(ctx); - if (!result) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BN_CTX_FULL); - goto err; - } - if (!bn_wexpand(modulus, m->top) || !bn_wexpand(exponent, p->top) || - !bn_wexpand(argument, a->top) || !bn_wexpand(result, m->top)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - sw_param.type = SW_ALG_EXP; - sw_param.up.exp.modulus.nbytes = BN_bn2bin(m, - (unsigned char *)modulus->d); - sw_param.up.exp.modulus.value = (unsigned char *)modulus->d; - sw_param.up.exp.exponent.nbytes = BN_bn2bin(p, - (unsigned char *)exponent->d); - sw_param.up.exp.exponent.value = (unsigned char *)exponent->d; - /* Attach the key params */ - sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); - switch (sw_status) { - case SW_OK: - break; - case SW_ERR_INPUT_SIZE: - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_BAD_KEY_SIZE); - goto err; - default: - { - char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", sw_status); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - } - goto err; - } - /* Prepare the argument and response */ - arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); - arg.value = (unsigned char *)argument->d; - res.nbytes = BN_num_bytes(m); - memset(result->d, 0, res.nbytes); - res.value = (unsigned char *)result->d; - /* Perform the operation */ - if ((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP, &arg, 1, - &res, 1)) != SW_OK) { - char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", sw_status); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - goto err; - } - /* Convert the response */ - BN_bin2bn((unsigned char *)result->d, res.nbytes, r); - to_return = 1; - err: - if (acquired) - release_context(hac); - BN_CTX_end(ctx); - return to_return; -} - -# ifndef OPENSSL_NO_RSA -int cswift_bn_32copy(SW_LARGENUMBER *out, const BIGNUM *in) -{ - int mod; - int numbytes = BN_num_bytes(in); - - mod = 0; - while (((out->nbytes = (numbytes + mod)) % 32)) { - mod++; - } - out->value = (unsigned char *)OPENSSL_malloc(out->nbytes); - if (!out->value) { - return 0; - } - BN_bn2bin(in, &out->value[mod]); - if (mod) - memset(out->value, 0, mod); - - return 1; -} -# endif - -# ifndef OPENSSL_NO_RSA -/* Un petit mod_exp chinois */ -static int cswift_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *q, const BIGNUM *dmp1, - const BIGNUM *dmq1, const BIGNUM *iqmp, - BN_CTX *ctx) -{ - SW_STATUS sw_status; - SW_LARGENUMBER arg, res; - SW_PARAM sw_param; - SW_CONTEXT_HANDLE hac; - BIGNUM *result = NULL; - BIGNUM *argument = NULL; - int to_return = 0; /* expect failure */ - int acquired = 0; - - sw_param.up.crt.p.value = NULL; - sw_param.up.crt.q.value = NULL; - sw_param.up.crt.dmp1.value = NULL; - sw_param.up.crt.dmq1.value = NULL; - sw_param.up.crt.iqmp.value = NULL; - - if (!get_context(&hac)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_UNIT_FAILURE); - goto err; - } - acquired = 1; - - /* Prepare the params */ - argument = BN_new(); - result = BN_new(); - if (!result || !argument) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_CTX_FULL); - goto err; - } - - sw_param.type = SW_ALG_CRT; - /************************************************************************/ - /* - * 04/02/2003 - */ - /* - * Modified by Frederic Giudicelli (deny-all.com) to overcome the - */ - /* - * limitation of cswift with values not a multiple of 32 - */ - /************************************************************************/ - if (!cswift_bn_32copy(&sw_param.up.crt.p, p)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - if (!cswift_bn_32copy(&sw_param.up.crt.q, q)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - if (!cswift_bn_32copy(&sw_param.up.crt.dmp1, dmp1)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - if (!cswift_bn_32copy(&sw_param.up.crt.dmq1, dmq1)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - if (!cswift_bn_32copy(&sw_param.up.crt.iqmp, iqmp)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - if (!bn_wexpand(argument, a->top) || !bn_wexpand(result, p->top + q->top)) { - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - - /* Attach the key params */ - sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); - switch (sw_status) { - case SW_OK: - break; - case SW_ERR_INPUT_SIZE: - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_BAD_KEY_SIZE); - goto err; - default: - { - char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", sw_status); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - } - goto err; - } - /* Prepare the argument and response */ - arg.nbytes = BN_bn2bin(a, (unsigned char *)argument->d); - arg.value = (unsigned char *)argument->d; - res.nbytes = 2 * BN_num_bytes(p); - memset(result->d, 0, res.nbytes); - res.value = (unsigned char *)result->d; - /* Perform the operation */ - if ((sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_MODEXP_CRT, &arg, 1, - &res, 1)) != SW_OK) { - char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; - CSWIFTerr(CSWIFT_F_CSWIFT_MOD_EXP_CRT, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", sw_status); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - goto err; - } - /* Convert the response */ - BN_bin2bn((unsigned char *)result->d, res.nbytes, r); - to_return = 1; - err: - if (sw_param.up.crt.p.value) - OPENSSL_free(sw_param.up.crt.p.value); - if (sw_param.up.crt.q.value) - OPENSSL_free(sw_param.up.crt.q.value); - if (sw_param.up.crt.dmp1.value) - OPENSSL_free(sw_param.up.crt.dmp1.value); - if (sw_param.up.crt.dmq1.value) - OPENSSL_free(sw_param.up.crt.dmq1.value); - if (sw_param.up.crt.iqmp.value) - OPENSSL_free(sw_param.up.crt.iqmp.value); - if (result) - BN_free(result); - if (argument) - BN_free(argument); - if (acquired) - release_context(hac); - return to_return; -} -# endif - -# ifndef OPENSSL_NO_RSA -static int cswift_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx) -{ - int to_return = 0; - const RSA_METHOD *def_rsa_method; - - if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { - CSWIFTerr(CSWIFT_F_CSWIFT_RSA_MOD_EXP, - CSWIFT_R_MISSING_KEY_COMPONENTS); - goto err; - } - - /* Try the limits of RSA (2048 bits) */ - if (BN_num_bytes(rsa->p) > 128 || - BN_num_bytes(rsa->q) > 128 || - BN_num_bytes(rsa->dmp1) > 128 || - BN_num_bytes(rsa->dmq1) > 128 || BN_num_bytes(rsa->iqmp) > 128) { -# ifdef RSA_NULL - def_rsa_method = RSA_null_method(); -# else -# if 0 - def_rsa_method = RSA_PKCS1_RSAref(); -# else - def_rsa_method = RSA_PKCS1_SSLeay(); -# endif -# endif - if (def_rsa_method) - return def_rsa_method->rsa_mod_exp(r0, I, rsa, ctx); - } - - to_return = cswift_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, - rsa->dmq1, rsa->iqmp, ctx); - err: - return to_return; -} - -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int cswift_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - const RSA_METHOD *def_rsa_method; - - /* Try the limits of RSA (2048 bits) */ - if (BN_num_bytes(r) > 256 || - BN_num_bytes(a) > 256 || BN_num_bytes(m) > 256) { -# ifdef RSA_NULL - def_rsa_method = RSA_null_method(); -# else -# if 0 - def_rsa_method = RSA_PKCS1_RSAref(); -# else - def_rsa_method = RSA_PKCS1_SSLeay(); -# endif -# endif - if (def_rsa_method) - return def_rsa_method->bn_mod_exp(r, a, p, m, ctx, m_ctx); - } - - return cswift_mod_exp(r, a, p, m, ctx); -} -# endif /* OPENSSL_NO_RSA */ - -# ifndef OPENSSL_NO_DSA -static DSA_SIG *cswift_dsa_sign(const unsigned char *dgst, int dlen, DSA *dsa) -{ - SW_CONTEXT_HANDLE hac; - SW_PARAM sw_param; - SW_STATUS sw_status; - SW_LARGENUMBER arg, res; - BN_CTX *ctx; - BIGNUM *dsa_p = NULL; - BIGNUM *dsa_q = NULL; - BIGNUM *dsa_g = NULL; - BIGNUM *dsa_key = NULL; - BIGNUM *result = NULL; - DSA_SIG *to_return = NULL; - int acquired = 0; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - if (!get_context(&hac)) { - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_UNIT_FAILURE); - goto err; - } - acquired = 1; - /* Prepare the params */ - BN_CTX_start(ctx); - dsa_p = BN_CTX_get(ctx); - dsa_q = BN_CTX_get(ctx); - dsa_g = BN_CTX_get(ctx); - dsa_key = BN_CTX_get(ctx); - result = BN_CTX_get(ctx); - if (!result) { - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BN_CTX_FULL); - goto err; - } - if (!bn_wexpand(dsa_p, dsa->p->top) || - !bn_wexpand(dsa_q, dsa->q->top) || - !bn_wexpand(dsa_g, dsa->g->top) || - !bn_wexpand(dsa_key, dsa->priv_key->top) || - !bn_wexpand(result, dsa->p->top)) { - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - sw_param.type = SW_ALG_DSA; - sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, (unsigned char *)dsa_p->d); - sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; - sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, (unsigned char *)dsa_q->d); - sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; - sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, (unsigned char *)dsa_g->d); - sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; - sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->priv_key, - (unsigned char *)dsa_key->d); - sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; - /* Attach the key params */ - sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); - switch (sw_status) { - case SW_OK: - break; - case SW_ERR_INPUT_SIZE: - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_BAD_KEY_SIZE); - goto err; - default: - { - char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", sw_status); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - } - goto err; - } - /* Prepare the argument and response */ - arg.nbytes = dlen; - arg.value = (unsigned char *)dgst; - res.nbytes = BN_num_bytes(dsa->p); - memset(result->d, 0, res.nbytes); - res.value = (unsigned char *)result->d; - /* Perform the operation */ - sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_SIGN, &arg, 1, - &res, 1); - if (sw_status != SW_OK) { - char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_SIGN, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", sw_status); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - goto err; - } - /* Convert the response */ - if ((to_return = DSA_SIG_new()) == NULL) - goto err; - to_return->r = BN_bin2bn((unsigned char *)result->d, 20, NULL); - to_return->s = BN_bin2bn((unsigned char *)result->d + 20, 20, NULL); - - err: - if (acquired) - release_context(hac); - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return to_return; -} - -static int cswift_dsa_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa) -{ - SW_CONTEXT_HANDLE hac; - SW_PARAM sw_param; - SW_STATUS sw_status; - SW_LARGENUMBER arg[2], res; - unsigned long sig_result; - BN_CTX *ctx; - BIGNUM *dsa_p = NULL; - BIGNUM *dsa_q = NULL; - BIGNUM *dsa_g = NULL; - BIGNUM *dsa_key = NULL; - BIGNUM *argument = NULL; - int to_return = -1; - int acquired = 0; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - if (!get_context(&hac)) { - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_UNIT_FAILURE); - goto err; - } - acquired = 1; - /* Prepare the params */ - BN_CTX_start(ctx); - dsa_p = BN_CTX_get(ctx); - dsa_q = BN_CTX_get(ctx); - dsa_g = BN_CTX_get(ctx); - dsa_key = BN_CTX_get(ctx); - argument = BN_CTX_get(ctx); - if (!argument) { - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BN_CTX_FULL); - goto err; - } - if (!bn_wexpand(dsa_p, dsa->p->top) || - !bn_wexpand(dsa_q, dsa->q->top) || - !bn_wexpand(dsa_g, dsa->g->top) || - !bn_wexpand(dsa_key, dsa->pub_key->top) || - !bn_wexpand(argument, 40)) { - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BN_EXPAND_FAIL); - goto err; - } - sw_param.type = SW_ALG_DSA; - sw_param.up.dsa.p.nbytes = BN_bn2bin(dsa->p, (unsigned char *)dsa_p->d); - sw_param.up.dsa.p.value = (unsigned char *)dsa_p->d; - sw_param.up.dsa.q.nbytes = BN_bn2bin(dsa->q, (unsigned char *)dsa_q->d); - sw_param.up.dsa.q.value = (unsigned char *)dsa_q->d; - sw_param.up.dsa.g.nbytes = BN_bn2bin(dsa->g, (unsigned char *)dsa_g->d); - sw_param.up.dsa.g.value = (unsigned char *)dsa_g->d; - sw_param.up.dsa.key.nbytes = BN_bn2bin(dsa->pub_key, - (unsigned char *)dsa_key->d); - sw_param.up.dsa.key.value = (unsigned char *)dsa_key->d; - /* Attach the key params */ - sw_status = p_CSwift_AttachKeyParam(hac, &sw_param); - switch (sw_status) { - case SW_OK: - break; - case SW_ERR_INPUT_SIZE: - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_BAD_KEY_SIZE); - goto err; - default: - { - char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", sw_status); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - } - goto err; - } - /* Prepare the argument and response */ - arg[0].nbytes = dgst_len; - arg[0].value = (unsigned char *)dgst; - arg[1].nbytes = 40; - arg[1].value = (unsigned char *)argument->d; - memset(arg[1].value, 0, 40); - BN_bn2bin(sig->r, arg[1].value + 20 - BN_num_bytes(sig->r)); - BN_bn2bin(sig->s, arg[1].value + 40 - BN_num_bytes(sig->s)); - res.nbytes = 4; /* unsigned long */ - res.value = (unsigned char *)(&sig_result); - /* Perform the operation */ - sw_status = p_CSwift_SimpleRequest(hac, SW_CMD_DSS_VERIFY, arg, 2, - &res, 1); - if (sw_status != SW_OK) { - char tmpbuf[DECIMAL_SIZE(sw_status) + 1]; - CSWIFTerr(CSWIFT_F_CSWIFT_DSA_VERIFY, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", sw_status); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - goto err; - } - /* Convert the response */ - to_return = ((sig_result == 0) ? 0 : 1); - - err: - if (acquired) - release_context(hac); - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return to_return; -} -# endif - -# ifndef OPENSSL_NO_DH -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int cswift_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return cswift_mod_exp(r, a, p, m, ctx); -} -# endif - -/* Random bytes are good */ -static int cswift_rand_bytes(unsigned char *buf, int num) -{ - SW_CONTEXT_HANDLE hac; - SW_STATUS swrc; - SW_LARGENUMBER largenum; - int acquired = 0; - int to_return = 0; /* assume failure */ - unsigned char buf32[1024]; - - if (!get_context(&hac)) { - CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_UNIT_FAILURE); - goto err; - } - acquired = 1; - - /************************************************************************/ - /* - * 04/02/2003 - */ - /* - * Modified by Frederic Giudicelli (deny-all.com) to overcome the - */ - /* - * limitation of cswift with values not a multiple of 32 - */ - /************************************************************************/ - - while (num >= (int)sizeof(buf32)) { - largenum.value = buf; - largenum.nbytes = sizeof(buf32); - /*- - * tell CryptoSwift how many bytes we want and where we want it. - * Note: - CryptoSwift cannot do more than 4096 bytes at a time. - * - CryptoSwift can only do multiple of 32-bits. - */ - swrc = - p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1); - if (swrc != SW_OK) { - char tmpbuf[20]; - CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", swrc); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - goto err; - } - buf += sizeof(buf32); - num -= sizeof(buf32); - } - if (num) { - largenum.nbytes = sizeof(buf32); - largenum.value = buf32; - swrc = - p_CSwift_SimpleRequest(hac, SW_CMD_RAND, NULL, 0, &largenum, 1); - if (swrc != SW_OK) { - char tmpbuf[20]; - CSWIFTerr(CSWIFT_F_CSWIFT_RAND_BYTES, CSWIFT_R_REQUEST_FAILED); - sprintf(tmpbuf, "%ld", swrc); - ERR_add_error_data(2, "CryptoSwift error number is ", tmpbuf); - goto err; - } - memcpy(buf, largenum.value, num); - } - - to_return = 1; /* success */ - err: - if (acquired) - release_context(hac); - - return to_return; -} - -static int cswift_rand_status(void) -{ - return 1; -} - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_cswift_id) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ -# endif /* !OPENSSL_NO_HW_CSWIFT */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_cswift_err.c b/Sources/COpenSSL/e_cswift_err.c deleted file mode 100644 index 73baaf89..00000000 --- a/Sources/COpenSSL/e_cswift_err.c +++ /dev/null @@ -1,150 +0,0 @@ -/* e_cswift_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_cswift_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA CSWIFT_str_functs[] = { - {ERR_FUNC(CSWIFT_F_CSWIFT_CTRL), "CSWIFT_CTRL"}, - {ERR_FUNC(CSWIFT_F_CSWIFT_DSA_SIGN), "CSWIFT_DSA_SIGN"}, - {ERR_FUNC(CSWIFT_F_CSWIFT_DSA_VERIFY), "CSWIFT_DSA_VERIFY"}, - {ERR_FUNC(CSWIFT_F_CSWIFT_FINISH), "CSWIFT_FINISH"}, - {ERR_FUNC(CSWIFT_F_CSWIFT_INIT), "CSWIFT_INIT"}, - {ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP), "CSWIFT_MOD_EXP"}, - {ERR_FUNC(CSWIFT_F_CSWIFT_MOD_EXP_CRT), "CSWIFT_MOD_EXP_CRT"}, - {ERR_FUNC(CSWIFT_F_CSWIFT_RAND_BYTES), "CSWIFT_RAND_BYTES"}, - {ERR_FUNC(CSWIFT_F_CSWIFT_RSA_MOD_EXP), "CSWIFT_RSA_MOD_EXP"}, - {0, NULL} -}; - -static ERR_STRING_DATA CSWIFT_str_reasons[] = { - {ERR_REASON(CSWIFT_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(CSWIFT_R_BAD_KEY_SIZE), "bad key size"}, - {ERR_REASON(CSWIFT_R_BN_CTX_FULL), "bn ctx full"}, - {ERR_REASON(CSWIFT_R_BN_EXPAND_FAIL), "bn expand fail"}, - {ERR_REASON(CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(CSWIFT_R_MISSING_KEY_COMPONENTS), "missing key components"}, - {ERR_REASON(CSWIFT_R_NOT_LOADED), "not loaded"}, - {ERR_REASON(CSWIFT_R_REQUEST_FAILED), "request failed"}, - {ERR_REASON(CSWIFT_R_UNIT_FAILURE), "unit failure"}, - {0, NULL} -}; - -#endif - -#ifdef CSWIFT_LIB_NAME -static ERR_STRING_DATA CSWIFT_lib_name[] = { - {0, CSWIFT_LIB_NAME}, - {0, NULL} -}; -#endif - -static int CSWIFT_lib_error_code = 0; -static int CSWIFT_error_init = 1; - -static void ERR_load_CSWIFT_strings(void) -{ - if (CSWIFT_lib_error_code == 0) - CSWIFT_lib_error_code = ERR_get_next_error_library(); - - if (CSWIFT_error_init) { - CSWIFT_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(CSWIFT_lib_error_code, CSWIFT_str_functs); - ERR_load_strings(CSWIFT_lib_error_code, CSWIFT_str_reasons); -#endif - -#ifdef CSWIFT_LIB_NAME - CSWIFT_lib_name->error = ERR_PACK(CSWIFT_lib_error_code, 0, 0); - ERR_load_strings(0, CSWIFT_lib_name); -#endif - } -} - -static void ERR_unload_CSWIFT_strings(void) -{ - if (CSWIFT_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(CSWIFT_lib_error_code, CSWIFT_str_functs); - ERR_unload_strings(CSWIFT_lib_error_code, CSWIFT_str_reasons); -#endif - -#ifdef CSWIFT_LIB_NAME - ERR_unload_strings(0, CSWIFT_lib_name); -#endif - CSWIFT_error_init = 1; - } -} - -static void ERR_CSWIFT_error(int function, int reason, char *file, int line) -{ - if (CSWIFT_lib_error_code == 0) - CSWIFT_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(CSWIFT_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_cswift_err.h b/Sources/COpenSSL/e_cswift_err.h deleted file mode 100644 index fde3a827..00000000 --- a/Sources/COpenSSL/e_cswift_err.h +++ /dev/null @@ -1,99 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_CSWIFT_ERR_H -# define HEADER_CSWIFT_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_CSWIFT_strings(void); -static void ERR_unload_CSWIFT_strings(void); -static void ERR_CSWIFT_error(int function, int reason, char *file, int line); -# define CSWIFTerr(f,r) ERR_CSWIFT_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the CSWIFT functions. */ - -/* Function codes. */ -# define CSWIFT_F_CSWIFT_CTRL 100 -# define CSWIFT_F_CSWIFT_DSA_SIGN 101 -# define CSWIFT_F_CSWIFT_DSA_VERIFY 102 -# define CSWIFT_F_CSWIFT_FINISH 103 -# define CSWIFT_F_CSWIFT_INIT 104 -# define CSWIFT_F_CSWIFT_MOD_EXP 105 -# define CSWIFT_F_CSWIFT_MOD_EXP_CRT 106 -# define CSWIFT_F_CSWIFT_RAND_BYTES 108 -# define CSWIFT_F_CSWIFT_RSA_MOD_EXP 107 - -/* Reason codes. */ -# define CSWIFT_R_ALREADY_LOADED 100 -# define CSWIFT_R_BAD_KEY_SIZE 101 -# define CSWIFT_R_BN_CTX_FULL 102 -# define CSWIFT_R_BN_EXPAND_FAIL 103 -# define CSWIFT_R_CTRL_COMMAND_NOT_IMPLEMENTED 104 -# define CSWIFT_R_MISSING_KEY_COMPONENTS 105 -# define CSWIFT_R_NOT_LOADED 106 -# define CSWIFT_R_REQUEST_FAILED 107 -# define CSWIFT_R_UNIT_FAILURE 108 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_des.c b/Sources/COpenSSL/e_des.c deleted file mode 100644 index 4bb830dd..00000000 --- a/Sources/COpenSSL/e_des.c +++ /dev/null @@ -1,269 +0,0 @@ -/* crypto/evp/e_des.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#ifndef OPENSSL_NO_DES -# include "evp.h" -# include "objects.h" -# include "evp_locl.h" -# include "des.h" -# include "rand.h" - -typedef struct { - union { - double align; - DES_key_schedule ks; - } ks; - union { - void (*cbc) (const void *, void *, size_t, - const DES_key_schedule *, unsigned char *); - } stream; -} EVP_DES_KEY; - -# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) -/* ----------^^^ this is not a typo, just a way to detect that - * assembler support was in general requested... */ -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; - -# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) - -void des_t4_key_expand(const void *key, DES_key_schedule *ks); -void des_t4_cbc_encrypt(const void *inp, void *out, size_t len, - const DES_key_schedule *ks, unsigned char iv[8]); -void des_t4_cbc_decrypt(const void *inp, void *out, size_t len, - const DES_key_schedule *ks, unsigned char iv[8]); -# endif - -static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); - -/* - * Because of various casts and different names can't use - * IMPLEMENT_BLOCK_CIPHER - */ - -static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - BLOCK_CIPHER_ecb_loop() - DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), - ctx->cipher_data, ctx->encrypt); - return 1; -} - -static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - while (inl >= EVP_MAXCHUNK) { - DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, - (DES_cblock *)ctx->iv, &ctx->num); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, - (DES_cblock *)ctx->iv, &ctx->num); - return 1; -} - -static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; - - if (dat->stream.cbc != NULL) { - (*dat->stream.cbc) (in, out, inl, &dat->ks.ks, ctx->iv); - return 1; - } - while (inl >= EVP_MAXCHUNK) { - DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, - (DES_cblock *)ctx->iv, ctx->encrypt); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, - (DES_cblock *)ctx->iv, ctx->encrypt); - return 1; -} - -static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - while (inl >= EVP_MAXCHUNK) { - DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, - (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, - (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); - return 1; -} - -/* - * Although we have a CFB-r implementation for DES, it doesn't pack the right - * way, so wrap it here - */ -static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - size_t n, chunk = EVP_MAXCHUNK / 8; - unsigned char c[1], d[1]; - - if (inl < chunk) - chunk = inl; - - while (inl && inl >= chunk) { - for (n = 0; n < chunk * 8; ++n) { - c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; - DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data, - (DES_cblock *)ctx->iv, ctx->encrypt); - out[n / 8] = - (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | - ((d[0] & 0x80) >> (unsigned int)(n % 8)); - } - inl -= chunk; - in += chunk; - out += chunk; - if (inl < chunk) - chunk = inl; - } - - return 1; -} - -static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - while (inl >= EVP_MAXCHUNK) { - DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, ctx->cipher_data, - (DES_cblock *)ctx->iv, ctx->encrypt); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data, - (DES_cblock *)ctx->iv, ctx->encrypt); - return 1; -} - -BLOCK_CIPHER_defs(des, EVP_DES_KEY, NID_des, 8, 8, 8, 64, - EVP_CIPH_RAND_KEY, des_init_key, NULL, - EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) - - BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 1, - EVP_CIPH_RAND_KEY, des_init_key, NULL, - EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) - - BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, NID_des, 8, 8, 8, - EVP_CIPH_RAND_KEY, des_init_key, NULL, - EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) - -static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - DES_cblock *deskey = (DES_cblock *)key; - EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; - - dat->stream.cbc = NULL; -# if defined(SPARC_DES_CAPABLE) - if (SPARC_DES_CAPABLE) { - int mode = ctx->cipher->flags & EVP_CIPH_MODE; - - if (mode == EVP_CIPH_CBC_MODE) { - des_t4_key_expand(key, &dat->ks.ks); - dat->stream.cbc = enc ? des_t4_cbc_encrypt : des_t4_cbc_decrypt; - return 1; - } - } -# endif -# ifdef EVP_CHECK_DES_KEY - if (DES_set_key_checked(deskey, dat->ks.ks) != 0) - return 0; -# else - DES_set_key_unchecked(deskey, ctx->cipher_data); -# endif - return 1; -} - -static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) -{ - - switch (type) { - case EVP_CTRL_RAND_KEY: - if (RAND_bytes(ptr, 8) <= 0) - return 0; - DES_set_odd_parity((DES_cblock *)ptr); - return 1; - - default: - return -1; - } -} - -#endif diff --git a/Sources/COpenSSL/e_des3.c b/Sources/COpenSSL/e_des3.c deleted file mode 100644 index 63e341f1..00000000 --- a/Sources/COpenSSL/e_des3.c +++ /dev/null @@ -1,498 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/evp/e_des3.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#ifndef OPENSSL_NO_DES -# include "evp.h" -# include "objects.h" -# include "evp_locl.h" -# include "des.h" -# include "rand.h" - -/* Block use of implementations in FIPS mode */ -# undef EVP_CIPH_FLAG_FIPS -# define EVP_CIPH_FLAG_FIPS 0 - -typedef struct { - union { - double align; - DES_key_schedule ks[3]; - } ks; - union { - void (*cbc) (const void *, void *, size_t, - const DES_key_schedule *, unsigned char *); - } stream; -} DES_EDE_KEY; -# define ks1 ks.ks[0] -# define ks2 ks.ks[1] -# define ks3 ks.ks[2] - -# if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__)) -/* ---------^^^ this is not a typo, just a way to detect that - * assembler support was in general requested... */ -# include "sparc_arch.h" - -extern unsigned int OPENSSL_sparcv9cap_P[]; - -# define SPARC_DES_CAPABLE (OPENSSL_sparcv9cap_P[1] & CFR_DES) - -void des_t4_key_expand(const void *key, DES_key_schedule *ks); -void des_t4_ede3_cbc_encrypt(const void *inp, void *out, size_t len, - const DES_key_schedule ks[3], unsigned char iv[8]); -void des_t4_ede3_cbc_decrypt(const void *inp, void *out, size_t len, - const DES_key_schedule ks[3], unsigned char iv[8]); -# endif - -static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - -static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - -static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); - -# define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data) - -/* - * Because of various casts and different args can't use - * IMPLEMENT_BLOCK_CIPHER - */ - -static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - BLOCK_CIPHER_ecb_loop() - DES_ecb3_encrypt((const_DES_cblock *)(in + i), - (DES_cblock *)(out + i), - &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, ctx->encrypt); - return 1; -} - -static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - while (inl >= EVP_MAXCHUNK) { - DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, - &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, (DES_cblock *)ctx->iv, - &ctx->num); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_ede3_ofb64_encrypt(in, out, (long)inl, - &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, (DES_cblock *)ctx->iv, - &ctx->num); - - return 1; -} - -static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - DES_EDE_KEY *dat = data(ctx); - -# ifdef KSSL_DEBUG - { - int i; - fprintf(stderr, "des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx, - ctx->buf_len); - fprintf(stderr, "\t iv= "); - for (i = 0; i < 8; i++) - fprintf(stderr, "%02X", ctx->iv[i]); - fprintf(stderr, "\n"); - } -# endif /* KSSL_DEBUG */ - if (dat->stream.cbc) { - (*dat->stream.cbc) (in, out, inl, dat->ks.ks, ctx->iv); - return 1; - } - - while (inl >= EVP_MAXCHUNK) { - DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, - &dat->ks1, &dat->ks2, &dat->ks3, - (DES_cblock *)ctx->iv, ctx->encrypt); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_ede3_cbc_encrypt(in, out, (long)inl, - &dat->ks1, &dat->ks2, &dat->ks3, - (DES_cblock *)ctx->iv, ctx->encrypt); - return 1; -} - -static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - while (inl >= EVP_MAXCHUNK) { - DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, - &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, (DES_cblock *)ctx->iv, - &ctx->num, ctx->encrypt); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_ede3_cfb64_encrypt(in, out, (long)inl, - &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, (DES_cblock *)ctx->iv, - &ctx->num, ctx->encrypt); - return 1; -} - -/* - * Although we have a CFB-r implementation for 3-DES, it doesn't pack the - * right way, so wrap it here - */ -static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - size_t n; - unsigned char c[1], d[1]; - - if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) - inl *= 8; - for (n = 0; n < inl; ++n) { - c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; - DES_ede3_cfb_encrypt(c, d, 1, 1, - &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, (DES_cblock *)ctx->iv, - ctx->encrypt); - out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) - | ((d[0] & 0x80) >> (unsigned int)(n % 8)); - } - - return 1; -} - -static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - while (inl >= EVP_MAXCHUNK) { - DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, - &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, (DES_cblock *)ctx->iv, - ctx->encrypt); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_ede3_cfb_encrypt(in, out, 8, (long)inl, - &data(ctx)->ks1, &data(ctx)->ks2, - &data(ctx)->ks3, (DES_cblock *)ctx->iv, - ctx->encrypt); - return 1; -} - -BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, - EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_DEFAULT_ASN1, - des_ede_init_key, NULL, NULL, NULL, des3_ctrl) -# define des_ede3_cfb64_cipher des_ede_cfb64_cipher -# define des_ede3_ofb_cipher des_ede_ofb_cipher -# define des_ede3_cbc_cipher des_ede_cbc_cipher -# define des_ede3_ecb_cipher des_ede_ecb_cipher - BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, - EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | - EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, NULL, - des3_ctrl) - - BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1, - EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | - EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, - NULL, des3_ctrl) - - BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8, - EVP_CIPH_RAND_KEY | EVP_CIPH_FLAG_FIPS | - EVP_CIPH_FLAG_DEFAULT_ASN1, des_ede3_init_key, NULL, NULL, - NULL, des3_ctrl) - -static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - DES_cblock *deskey = (DES_cblock *)key; - DES_EDE_KEY *dat = data(ctx); - - dat->stream.cbc = NULL; -# if defined(SPARC_DES_CAPABLE) - if (SPARC_DES_CAPABLE) { - int mode = ctx->cipher->flags & EVP_CIPH_MODE; - - if (mode == EVP_CIPH_CBC_MODE) { - des_t4_key_expand(&deskey[0], &dat->ks1); - des_t4_key_expand(&deskey[1], &dat->ks2); - memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1)); - dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt : - des_t4_ede3_cbc_decrypt; - return 1; - } - } -# endif -# ifdef EVP_CHECK_DES_KEY - if (DES_set_key_checked(&deskey[0], &dat->ks1) - || DES_set_key_checked(&deskey[1], &dat->ks2)) - return 0; -# else - DES_set_key_unchecked(&deskey[0], &dat->ks1); - DES_set_key_unchecked(&deskey[1], &dat->ks2); -# endif - memcpy(&dat->ks3, &dat->ks1, sizeof(dat->ks1)); - return 1; -} - -static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - DES_cblock *deskey = (DES_cblock *)key; - DES_EDE_KEY *dat = data(ctx); - -# ifdef KSSL_DEBUG - { - int i; - fprintf(stderr, "des_ede3_init_key(ctx=%p)\n", ctx); - fprintf(stderr, "\tKEY= "); - for (i = 0; i < 24; i++) - fprintf(stderr, "%02X", key[i]); - fprintf(stderr, "\n"); - if (iv) { - fprintf(stderr, "\t IV= "); - for (i = 0; i < 8; i++) - fprintf(stderr, "%02X", iv[i]); - fprintf(stderr, "\n"); - } - } -# endif /* KSSL_DEBUG */ - - dat->stream.cbc = NULL; -# if defined(SPARC_DES_CAPABLE) - if (SPARC_DES_CAPABLE) { - int mode = ctx->cipher->flags & EVP_CIPH_MODE; - - if (mode == EVP_CIPH_CBC_MODE) { - des_t4_key_expand(&deskey[0], &dat->ks1); - des_t4_key_expand(&deskey[1], &dat->ks2); - des_t4_key_expand(&deskey[2], &dat->ks3); - dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt : - des_t4_ede3_cbc_decrypt; - return 1; - } - } -# endif -# ifdef EVP_CHECK_DES_KEY - if (DES_set_key_checked(&deskey[0], &dat->ks1) - || DES_set_key_checked(&deskey[1], &dat->ks2) - || DES_set_key_checked(&deskey[2], &dat->ks3)) - return 0; -# else - DES_set_key_unchecked(&deskey[0], &dat->ks1); - DES_set_key_unchecked(&deskey[1], &dat->ks2); - DES_set_key_unchecked(&deskey[2], &dat->ks3); -# endif - return 1; -} - -static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) -{ - - DES_cblock *deskey = ptr; - - switch (type) { - case EVP_CTRL_RAND_KEY: - if (RAND_bytes(ptr, c->key_len) <= 0) - return 0; - DES_set_odd_parity(deskey); - if (c->key_len >= 16) - DES_set_odd_parity(deskey + 1); - if (c->key_len >= 24) - DES_set_odd_parity(deskey + 2); - return 1; - - default: - return -1; - } -} - -const EVP_CIPHER *EVP_des_ede(void) -{ - return &des_ede_ecb; -} - -const EVP_CIPHER *EVP_des_ede3(void) -{ - return &des_ede3_ecb; -} - -# ifndef OPENSSL_NO_SHA - -# include "sha.h" - -static const unsigned char wrap_iv[8] = - { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 }; - -static int des_ede3_unwrap(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - unsigned char icv[8], iv[8], sha1tmp[SHA_DIGEST_LENGTH]; - int rv = -1; - if (inl < 24) - return -1; - if (out == NULL) - return inl - 16; - memcpy(ctx->iv, wrap_iv, 8); - /* Decrypt first block which will end up as icv */ - des_ede_cbc_cipher(ctx, icv, in, 8); - /* Decrypt central blocks */ - /* - * If decrypting in place move whole output along a block so the next - * des_ede_cbc_cipher is in place. - */ - if (out == in) { - memmove(out, out + 8, inl - 8); - in -= 8; - } - des_ede_cbc_cipher(ctx, out, in + 8, inl - 16); - /* Decrypt final block which will be IV */ - des_ede_cbc_cipher(ctx, iv, in + inl - 8, 8); - /* Reverse order of everything */ - BUF_reverse(icv, NULL, 8); - BUF_reverse(out, NULL, inl - 16); - BUF_reverse(ctx->iv, iv, 8); - /* Decrypt again using new IV */ - des_ede_cbc_cipher(ctx, out, out, inl - 16); - des_ede_cbc_cipher(ctx, icv, icv, 8); - /* Work out SHA1 hash of first portion */ - SHA1(out, inl - 16, sha1tmp); - - if (!CRYPTO_memcmp(sha1tmp, icv, 8)) - rv = inl - 16; - OPENSSL_cleanse(icv, 8); - OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); - OPENSSL_cleanse(iv, 8); - OPENSSL_cleanse(ctx->iv, 8); - if (rv == -1) - OPENSSL_cleanse(out, inl - 16); - - return rv; -} - -static int des_ede3_wrap(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - unsigned char sha1tmp[SHA_DIGEST_LENGTH]; - if (out == NULL) - return inl + 16; - /* Copy input to output buffer + 8 so we have space for IV */ - memmove(out + 8, in, inl); - /* Work out ICV */ - SHA1(in, inl, sha1tmp); - memcpy(out + inl + 8, sha1tmp, 8); - OPENSSL_cleanse(sha1tmp, SHA_DIGEST_LENGTH); - /* Generate random IV */ - if (RAND_bytes(ctx->iv, 8) <= 0) - return -1; - memcpy(out, ctx->iv, 8); - /* Encrypt everything after IV in place */ - des_ede_cbc_cipher(ctx, out + 8, out + 8, inl + 8); - BUF_reverse(out, NULL, inl + 16); - memcpy(ctx->iv, wrap_iv, 8); - des_ede_cbc_cipher(ctx, out, out, inl + 16); - return inl + 16; -} - -static int des_ede3_wrap_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - /* - * Sanity check input length: we typically only wrap keys so EVP_MAXCHUNK - * is more than will ever be needed. Also input length must be a multiple - * of 8 bits. - */ - if (inl >= EVP_MAXCHUNK || inl % 8) - return -1; - if (ctx->encrypt) - return des_ede3_wrap(ctx, out, in, inl); - else - return des_ede3_unwrap(ctx, out, in, inl); -} - -static const EVP_CIPHER des3_wrap = { - NID_id_smime_alg_CMS3DESwrap, - 8, 24, 0, - EVP_CIPH_WRAP_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER - | EVP_CIPH_FLAG_DEFAULT_ASN1, - des_ede3_init_key, des_ede3_wrap_cipher, - NULL, - sizeof(DES_EDE_KEY), - NULL, NULL, NULL, NULL -}; - -const EVP_CIPHER *EVP_des_ede3_wrap(void) -{ - return &des3_wrap; -} - -# endif -#endif diff --git a/Sources/COpenSSL/e_gmp.c b/Sources/COpenSSL/e_gmp.c deleted file mode 100644 index 5720d41c..00000000 --- a/Sources/COpenSSL/e_gmp.c +++ /dev/null @@ -1,492 +0,0 @@ -/* crypto/engine/e_gmp.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2003. - */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * This engine is not (currently) compiled in by default. Do enable it, - * reconfigure OpenSSL with "enable-gmp -lgmp". The GMP libraries and headers - * must reside in one of the paths searched by the compiler/linker, otherwise - * paths must be specified - eg. try configuring with "enable-gmp - * -I -L -lgmp". YMMV. - */ - -/*- - * As for what this does - it's a largely unoptimised implementation of an - * ENGINE that uses the GMP library to perform RSA private key operations. To - * obtain more information about what "unoptimised" means, see my original mail - * on the subject (though ignore the build instructions which have since - * changed); - * - * http://www.mail-archive.com/openssl-dev@openssl.org/msg12227.html - * - * On my athlon system at least, it appears the builtin OpenSSL code is now - * slightly faster, which is to say that the RSA-related MPI performance - * between OpenSSL's BIGNUM and GMP's mpz implementations is probably pretty - * balanced for this chip, and so the performance degradation in this ENGINE by - * having to convert to/from GMP formats (and not being able to cache - * montgomery forms) is probably the difference. However, if some unconfirmed - * reports from users is anything to go by, the situation on some other - * chipsets might be a good deal more favourable to the GMP version (eg. PPC). - * Feedback welcome. */ - -#include -#include -#include "crypto.h" -#include "buffer.h" -#include "engine.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#include "bn.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_GMP - -# include - -# define E_GMP_LIB_NAME "gmp engine" -# include "e_gmp_err.c" - -static int e_gmp_destroy(ENGINE *e); -static int e_gmp_init(ENGINE *e); -static int e_gmp_finish(ENGINE *e); -static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); - -# ifndef OPENSSL_NO_RSA -/* RSA stuff */ -static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -static int e_gmp_rsa_finish(RSA *r); -# endif - -/* The definitions for control commands specific to this engine */ -/* #define E_GMP_CMD_SO_PATH ENGINE_CMD_BASE */ -static const ENGINE_CMD_DEFN e_gmp_cmd_defns[] = { -# if 0 - {E_GMP_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'e_gmp' shared library", - ENGINE_CMD_FLAG_STRING}, -# endif - {0, NULL, NULL, 0} -}; - -# ifndef OPENSSL_NO_RSA -/* Our internal RSA_METHOD that we provide pointers to */ -static RSA_METHOD e_gmp_rsa = { - "GMP RSA method", - NULL, - NULL, - NULL, - NULL, - e_gmp_rsa_mod_exp, - NULL, - NULL, - e_gmp_rsa_finish, - /* - * These flags initialise montgomery crud that GMP ignores, however it - * makes sure the public key ops (which are done in openssl) don't seem - * *slower* than usual :-) - */ - RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE, - NULL, - NULL, - NULL -}; -# endif - -/* Constants used when creating the ENGINE */ -static const char *engine_e_gmp_id = "gmp"; -static const char *engine_e_gmp_name = "GMP engine support"; - -/* - * This internal function is used by ENGINE_gmp() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_helper(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif - if (!ENGINE_set_id(e, engine_e_gmp_id) || - !ENGINE_set_name(e, engine_e_gmp_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &e_gmp_rsa) || -# endif - !ENGINE_set_destroy_function(e, e_gmp_destroy) || - !ENGINE_set_init_function(e, e_gmp_init) || - !ENGINE_set_finish_function(e, e_gmp_finish) || - !ENGINE_set_ctrl_function(e, e_gmp_ctrl) || - !ENGINE_set_cmd_defns(e, e_gmp_cmd_defns)) - return 0; - -# ifndef OPENSSL_NO_RSA - meth1 = RSA_PKCS1_SSLeay(); - e_gmp_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - e_gmp_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - e_gmp_rsa.rsa_priv_enc = meth1->rsa_priv_enc; - e_gmp_rsa.rsa_priv_dec = meth1->rsa_priv_dec; - e_gmp_rsa.bn_mod_exp = meth1->bn_mod_exp; -# endif - - /* Ensure the e_gmp error handling is set up */ - ERR_load_GMP_strings(); - return 1; -} - -static ENGINE *engine_gmp(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_gmp(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_gmp(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} - -# ifndef OPENSSL_NO_RSA -/* Used to attach our own key-data to an RSA structure */ -static int hndidx_rsa = -1; -# endif - -static int e_gmp_destroy(ENGINE *e) -{ - ERR_unload_GMP_strings(); - return 1; -} - -/* (de)initialisation functions. */ -static int e_gmp_init(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - if (hndidx_rsa == -1) - hndidx_rsa = RSA_get_ex_new_index(0, - "GMP-based RSA key handle", - NULL, NULL, NULL); -# endif - if (hndidx_rsa == -1) - return 0; - return 1; -} - -static int e_gmp_finish(ENGINE *e) -{ - return 1; -} - -static int e_gmp_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int to_return = 1; - - switch (cmd) { -# if 0 - case E_GMP_CMD_SO_PATH: - /* ... */ -# endif - /* The command isn't understood by this engine */ - default: - GMPerr(GMP_F_E_GMP_CTRL, GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED); - to_return = 0; - break; - } - - return to_return; -} - -/* - * Most often limb sizes will be the same. If not, we use hex conversion - * which is neat, but extremely inefficient. - */ -static int bn2gmp(const BIGNUM *bn, mpz_t g) -{ - bn_check_top(bn); - if (((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && - (BN_BITS2 == GMP_NUMB_BITS)) { - /* The common case */ - if (!_mpz_realloc(g, bn->top)) - return 0; - memcpy(&g->_mp_d[0], &bn->d[0], bn->top * sizeof(bn->d[0])); - g->_mp_size = bn->top; - if (bn->neg) - g->_mp_size = -g->_mp_size; - return 1; - } else { - int toret; - char *tmpchar = BN_bn2hex(bn); - if (!tmpchar) - return 0; - toret = (mpz_set_str(g, tmpchar, 16) == 0 ? 1 : 0); - OPENSSL_free(tmpchar); - return toret; - } -} - -static int gmp2bn(mpz_t g, BIGNUM *bn) -{ - if (((sizeof(bn->d[0]) * 8) == GMP_NUMB_BITS) && - (BN_BITS2 == GMP_NUMB_BITS)) { - /* The common case */ - int s = (g->_mp_size >= 0) ? g->_mp_size : -g->_mp_size; - BN_zero(bn); - if (bn_expand2(bn, s) == NULL) - return 0; - bn->top = s; - memcpy(&bn->d[0], &g->_mp_d[0], s * sizeof(bn->d[0])); - bn_correct_top(bn); - bn->neg = g->_mp_size >= 0 ? 0 : 1; - return 1; - } else { - int toret; - char *tmpchar = OPENSSL_malloc(mpz_sizeinbase(g, 16) + 10); - if (!tmpchar) - return 0; - mpz_get_str(tmpchar, 16, g); - toret = BN_hex2bn(&bn, tmpchar); - OPENSSL_free(tmpchar); - return toret; - } -} - -# ifndef OPENSSL_NO_RSA -typedef struct st_e_gmp_rsa_ctx { - int public_only; - mpz_t n; - mpz_t d; - mpz_t e; - mpz_t p; - mpz_t q; - mpz_t dmp1; - mpz_t dmq1; - mpz_t iqmp; - mpz_t r0, r1, I0, m1; -} E_GMP_RSA_CTX; - -static E_GMP_RSA_CTX *e_gmp_get_rsa(RSA *rsa) -{ - E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa); - if (hptr) - return hptr; - hptr = OPENSSL_malloc(sizeof(E_GMP_RSA_CTX)); - if (!hptr) - return NULL; - /* - * These inits could probably be replaced by more intelligent mpz_init2() - * versions, to reduce malloc-thrashing. - */ - mpz_init(hptr->n); - mpz_init(hptr->d); - mpz_init(hptr->e); - mpz_init(hptr->p); - mpz_init(hptr->q); - mpz_init(hptr->dmp1); - mpz_init(hptr->dmq1); - mpz_init(hptr->iqmp); - mpz_init(hptr->r0); - mpz_init(hptr->r1); - mpz_init(hptr->I0); - mpz_init(hptr->m1); - if (!bn2gmp(rsa->n, hptr->n) || !bn2gmp(rsa->e, hptr->e)) - goto err; - if (!rsa->p || !rsa->q || !rsa->d || !rsa->dmp1 || !rsa->dmq1 - || !rsa->iqmp) { - hptr->public_only = 1; - return hptr; - } - if (!bn2gmp(rsa->d, hptr->d) || !bn2gmp(rsa->p, hptr->p) || - !bn2gmp(rsa->q, hptr->q) || !bn2gmp(rsa->dmp1, hptr->dmp1) || - !bn2gmp(rsa->dmq1, hptr->dmq1) || !bn2gmp(rsa->iqmp, hptr->iqmp)) - goto err; - hptr->public_only = 0; - RSA_set_ex_data(rsa, hndidx_rsa, hptr); - return hptr; - err: - mpz_clear(hptr->n); - mpz_clear(hptr->d); - mpz_clear(hptr->e); - mpz_clear(hptr->p); - mpz_clear(hptr->q); - mpz_clear(hptr->dmp1); - mpz_clear(hptr->dmq1); - mpz_clear(hptr->iqmp); - mpz_clear(hptr->r0); - mpz_clear(hptr->r1); - mpz_clear(hptr->I0); - mpz_clear(hptr->m1); - OPENSSL_free(hptr); - return NULL; -} - -static int e_gmp_rsa_finish(RSA *rsa) -{ - E_GMP_RSA_CTX *hptr = RSA_get_ex_data(rsa, hndidx_rsa); - if (!hptr) - return 0; - mpz_clear(hptr->n); - mpz_clear(hptr->d); - mpz_clear(hptr->e); - mpz_clear(hptr->p); - mpz_clear(hptr->q); - mpz_clear(hptr->dmp1); - mpz_clear(hptr->dmq1); - mpz_clear(hptr->iqmp); - mpz_clear(hptr->r0); - mpz_clear(hptr->r1); - mpz_clear(hptr->I0); - mpz_clear(hptr->m1); - OPENSSL_free(hptr); - RSA_set_ex_data(rsa, hndidx_rsa, NULL); - return 1; -} - -static int e_gmp_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx) -{ - E_GMP_RSA_CTX *hptr; - int to_return = 0; - - hptr = e_gmp_get_rsa(rsa); - if (!hptr) { - GMPerr(GMP_F_E_GMP_RSA_MOD_EXP, GMP_R_KEY_CONTEXT_ERROR); - return 0; - } - if (hptr->public_only) { - GMPerr(GMP_F_E_GMP_RSA_MOD_EXP, GMP_R_MISSING_KEY_COMPONENTS); - return 0; - } - - /* ugh!!! */ - if (!bn2gmp(I, hptr->I0)) - return 0; - - /* - * This is basically the CRT logic in crypto/rsa/rsa_eay.c reworded into - * GMP-speak. It may be that GMP's API facilitates cleaner formulations - * of this stuff, eg. better handling of negatives, or functions that - * combine operations. - */ - - mpz_mod(hptr->r1, hptr->I0, hptr->q); - mpz_powm(hptr->m1, hptr->r1, hptr->dmq1, hptr->q); - - mpz_mod(hptr->r1, hptr->I0, hptr->p); - mpz_powm(hptr->r0, hptr->r1, hptr->dmp1, hptr->p); - - mpz_sub(hptr->r0, hptr->r0, hptr->m1); - - if (mpz_sgn(hptr->r0) < 0) - mpz_add(hptr->r0, hptr->r0, hptr->p); - mpz_mul(hptr->r1, hptr->r0, hptr->iqmp); - mpz_mod(hptr->r0, hptr->r1, hptr->p); - - if (mpz_sgn(hptr->r0) < 0) - mpz_add(hptr->r0, hptr->r0, hptr->p); - mpz_mul(hptr->r1, hptr->r0, hptr->q); - mpz_add(hptr->r0, hptr->r1, hptr->m1); - - /* ugh!!! */ - if (gmp2bn(hptr->r0, r)) - to_return = 1; - - return 1; -} -# endif - -# endif /* !OPENSSL_NO_GMP */ - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -IMPLEMENT_DYNAMIC_CHECK_FN() -# ifndef OPENSSL_NO_GMP -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_e_gmp_id) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -# else -OPENSSL_EXPORT - int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); -OPENSSL_EXPORT - int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) -{ - return 0; -} -# endif -# endif /* !OPENSSL_NO_DYNAMIC_ENGINE */ - -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_gmp_err.c b/Sources/COpenSSL/e_gmp_err.c deleted file mode 100644 index 02f9f1d7..00000000 --- a/Sources/COpenSSL/e_gmp_err.c +++ /dev/null @@ -1,137 +0,0 @@ -/* e_gmp_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_gmp_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA GMP_str_functs[] = { - {ERR_FUNC(GMP_F_E_GMP_CTRL), "E_GMP_CTRL"}, - {ERR_FUNC(GMP_F_E_GMP_RSA_MOD_EXP), "E_GMP_RSA_MOD_EXP"}, - {0, NULL} -}; - -static ERR_STRING_DATA GMP_str_reasons[] = { - {ERR_REASON(GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(GMP_R_KEY_CONTEXT_ERROR), "key context error"}, - {ERR_REASON(GMP_R_MISSING_KEY_COMPONENTS), "missing key components"}, - {0, NULL} -}; - -#endif - -#ifdef GMP_LIB_NAME -static ERR_STRING_DATA GMP_lib_name[] = { - {0, GMP_LIB_NAME}, - {0, NULL} -}; -#endif - -static int GMP_lib_error_code = 0; -static int GMP_error_init = 1; - -static void ERR_load_GMP_strings(void) -{ - if (GMP_lib_error_code == 0) - GMP_lib_error_code = ERR_get_next_error_library(); - - if (GMP_error_init) { - GMP_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(GMP_lib_error_code, GMP_str_functs); - ERR_load_strings(GMP_lib_error_code, GMP_str_reasons); -#endif - -#ifdef GMP_LIB_NAME - GMP_lib_name->error = ERR_PACK(GMP_lib_error_code, 0, 0); - ERR_load_strings(0, GMP_lib_name); -#endif - } -} - -static void ERR_unload_GMP_strings(void) -{ - if (GMP_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(GMP_lib_error_code, GMP_str_functs); - ERR_unload_strings(GMP_lib_error_code, GMP_str_reasons); -#endif - -#ifdef GMP_LIB_NAME - ERR_unload_strings(0, GMP_lib_name); -#endif - GMP_error_init = 1; - } -} - -static void ERR_GMP_error(int function, int reason, char *file, int line) -{ - if (GMP_lib_error_code == 0) - GMP_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(GMP_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_gmp_err.h b/Sources/COpenSSL/e_gmp_err.h deleted file mode 100644 index 637abbc9..00000000 --- a/Sources/COpenSSL/e_gmp_err.h +++ /dev/null @@ -1,86 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_GMP_ERR_H -# define HEADER_GMP_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_GMP_strings(void); -static void ERR_unload_GMP_strings(void); -static void ERR_GMP_error(int function, int reason, char *file, int line); -# define GMPerr(f,r) ERR_GMP_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the GMP functions. */ - -/* Function codes. */ -# define GMP_F_E_GMP_CTRL 100 -# define GMP_F_E_GMP_RSA_MOD_EXP 101 - -/* Reason codes. */ -# define GMP_R_CTRL_COMMAND_NOT_IMPLEMENTED 100 -# define GMP_R_KEY_CONTEXT_ERROR 101 -# define GMP_R_MISSING_KEY_COMPONENTS 102 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_gost_err.c b/Sources/COpenSSL/e_gost_err.c deleted file mode 100644 index b2abfec7..00000000 --- a/Sources/COpenSSL/e_gost_err.c +++ /dev/null @@ -1,221 +0,0 @@ -/* e_gost_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_gost_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA GOST_str_functs[] = { - {ERR_FUNC(GOST_F_DECODE_GOST_ALGOR_PARAMS), "DECODE_GOST_ALGOR_PARAMS"}, - {ERR_FUNC(GOST_F_ENCODE_GOST_ALGOR_PARAMS), "ENCODE_GOST_ALGOR_PARAMS"}, - {ERR_FUNC(GOST_F_FILL_GOST2001_PARAMS), "FILL_GOST2001_PARAMS"}, - {ERR_FUNC(GOST_F_FILL_GOST94_PARAMS), "FILL_GOST94_PARAMS"}, - {ERR_FUNC(GOST_F_GET_ENCRYPTION_PARAMS), "GET_ENCRYPTION_PARAMS"}, - {ERR_FUNC(GOST_F_GOST2001_COMPUTE_PUBLIC), "GOST2001_COMPUTE_PUBLIC"}, - {ERR_FUNC(GOST_F_GOST2001_DO_SIGN), "GOST2001_DO_SIGN"}, - {ERR_FUNC(GOST_F_GOST2001_DO_VERIFY), "GOST2001_DO_VERIFY"}, - {ERR_FUNC(GOST_F_GOST2001_KEYGEN), "GOST2001_KEYGEN"}, - {ERR_FUNC(GOST_F_GOST89_GET_ASN1_PARAMETERS), - "GOST89_GET_ASN1_PARAMETERS"}, - {ERR_FUNC(GOST_F_GOST89_SET_ASN1_PARAMETERS), - "GOST89_SET_ASN1_PARAMETERS"}, - {ERR_FUNC(GOST_F_GOST94_COMPUTE_PUBLIC), "GOST94_COMPUTE_PUBLIC"}, - {ERR_FUNC(GOST_F_GOST_CIPHER_CTL), "GOST_CIPHER_CTL"}, - {ERR_FUNC(GOST_F_GOST_DO_SIGN), "GOST_DO_SIGN"}, - {ERR_FUNC(GOST_F_GOST_DO_VERIFY), "GOST_DO_VERIFY"}, - {ERR_FUNC(GOST_F_GOST_IMIT_CTRL), "GOST_IMIT_CTRL"}, - {ERR_FUNC(GOST_F_GOST_IMIT_FINAL), "GOST_IMIT_FINAL"}, - {ERR_FUNC(GOST_F_GOST_IMIT_UPDATE), "GOST_IMIT_UPDATE"}, - {ERR_FUNC(GOST_F_GOST_SIGN_KEYGEN), "GOST_SIGN_KEYGEN"}, - {ERR_FUNC(GOST_F_PARAM_COPY_GOST01), "PARAM_COPY_GOST01"}, - {ERR_FUNC(GOST_F_PARAM_COPY_GOST94), "PARAM_COPY_GOST94"}, - {ERR_FUNC(GOST_F_PKEY_GOST01CP_DECRYPT), "PKEY_GOST01CP_DECRYPT"}, - {ERR_FUNC(GOST_F_PKEY_GOST01CP_ENCRYPT), "PKEY_GOST01CP_ENCRYPT"}, - {ERR_FUNC(GOST_F_PKEY_GOST01CP_KEYGEN), "PKEY_GOST01CP_KEYGEN"}, - {ERR_FUNC(GOST_F_PKEY_GOST01_PARAMGEN), "PKEY_GOST01_PARAMGEN"}, - {ERR_FUNC(GOST_F_PKEY_GOST2001_DERIVE), "PKEY_GOST2001_DERIVE"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CP_DECRYPT), "PKEY_GOST94CP_DECRYPT"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CP_ENCRYPT), "PKEY_GOST94CP_ENCRYPT"}, - {ERR_FUNC(GOST_F_PKEY_GOST94CP_KEYGEN), "PKEY_GOST94CP_KEYGEN"}, - {ERR_FUNC(GOST_F_PKEY_GOST94_PARAMGEN), "PKEY_GOST94_PARAMGEN"}, - {ERR_FUNC(GOST_F_PKEY_GOST_CTRL), "PKEY_GOST_CTRL"}, - {ERR_FUNC(GOST_F_PKEY_GOST_CTRL01_STR), "PKEY_GOST_CTRL01_STR"}, - {ERR_FUNC(GOST_F_PKEY_GOST_CTRL94_STR), "PKEY_GOST_CTRL94_STR"}, - {ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL), "PKEY_GOST_MAC_CTRL"}, - {ERR_FUNC(GOST_F_PKEY_GOST_MAC_CTRL_STR), "PKEY_GOST_MAC_CTRL_STR"}, - {ERR_FUNC(GOST_F_PKEY_GOST_MAC_KEYGEN), "PKEY_GOST_MAC_KEYGEN"}, - {ERR_FUNC(GOST_F_PRINT_GOST_01), "PRINT_GOST_01"}, - {ERR_FUNC(GOST_F_PRIV_DECODE_GOST), "PRIV_DECODE_GOST"}, - {ERR_FUNC(GOST_F_PUB_DECODE_GOST01), "PUB_DECODE_GOST01"}, - {ERR_FUNC(GOST_F_PUB_DECODE_GOST94), "PUB_DECODE_GOST94"}, - {ERR_FUNC(GOST_F_PUB_ENCODE_GOST01), "PUB_ENCODE_GOST01"}, - {ERR_FUNC(GOST_F_UNPACK_CC_SIGNATURE), "UNPACK_CC_SIGNATURE"}, - {ERR_FUNC(GOST_F_UNPACK_CP_SIGNATURE), "UNPACK_CP_SIGNATURE"}, - {0, NULL} -}; - -static ERR_STRING_DATA GOST_str_reasons[] = { - {ERR_REASON(GOST_R_BAD_KEY_PARAMETERS_FORMAT), - "bad key parameters format"}, - {ERR_REASON(GOST_R_BAD_PKEY_PARAMETERS_FORMAT), - "bad pkey parameters format"}, - {ERR_REASON(GOST_R_CANNOT_PACK_EPHEMERAL_KEY), - "cannot pack ephemeral key"}, - {ERR_REASON(GOST_R_CTRL_CALL_FAILED), "ctrl call failed"}, - {ERR_REASON(GOST_R_ERROR_COMPUTING_SHARED_KEY), - "error computing shared key"}, - {ERR_REASON(GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO), - "error packing key transport info"}, - {ERR_REASON(GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO), - "error parsing key transport info"}, - {ERR_REASON(GOST_R_INCOMPATIBLE_ALGORITHMS), "incompatible algorithms"}, - {ERR_REASON(GOST_R_INCOMPATIBLE_PEER_KEY), "incompatible peer key"}, - {ERR_REASON(GOST_R_INVALID_CIPHER_PARAMS), "invalid cipher params"}, - {ERR_REASON(GOST_R_INVALID_CIPHER_PARAM_OID), "invalid cipher param oid"}, - {ERR_REASON(GOST_R_INVALID_DIGEST_TYPE), "invalid digest type"}, - {ERR_REASON(GOST_R_INVALID_GOST94_PARMSET), "invalid gost94 parmset"}, - {ERR_REASON(GOST_R_INVALID_IV_LENGTH), "invalid iv length"}, - {ERR_REASON(GOST_R_INVALID_MAC_KEY_LENGTH), "invalid mac key length"}, - {ERR_REASON(GOST_R_INVALID_PARAMSET), "invalid paramset"}, - {ERR_REASON(GOST_R_KEY_IS_NOT_INITALIZED), "key is not initalized"}, - {ERR_REASON(GOST_R_KEY_IS_NOT_INITIALIZED), "key is not initialized"}, - {ERR_REASON(GOST_R_KEY_PARAMETERS_MISSING), "key parameters missing"}, - {ERR_REASON(GOST_R_MAC_KEY_NOT_SET), "mac key not set"}, - {ERR_REASON(GOST_R_MALLOC_FAILURE), "malloc failure"}, - {ERR_REASON(GOST_R_NO_MEMORY), "no memory"}, - {ERR_REASON(GOST_R_NO_PARAMETERS_SET), "no parameters set"}, - {ERR_REASON(GOST_R_NO_PEER_KEY), "no peer key"}, - {ERR_REASON(GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR), - "no private part of non ephemeral keypair"}, - {ERR_REASON(GOST_R_PUBLIC_KEY_UNDEFINED), "public key undefined"}, - {ERR_REASON(GOST_R_RANDOM_GENERATOR_ERROR), "random generator error"}, - {ERR_REASON(GOST_R_RANDOM_GENERATOR_FAILURE), "random generator failure"}, - {ERR_REASON(GOST_R_RANDOM_NUMBER_GENERATOR_FAILED), - "random number generator failed"}, - {ERR_REASON(GOST_R_SIGNATURE_MISMATCH), "signature mismatch"}, - {ERR_REASON(GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q), - "signature parts greater than q"}, - {ERR_REASON(GOST_R_UKM_NOT_SET), "ukm not set"}, - {ERR_REASON(GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND), - "unsupported cipher ctl command"}, - {ERR_REASON(GOST_R_UNSUPPORTED_PARAMETER_SET), - "unsupported parameter set"}, - {0, NULL} -}; - -#endif - -#ifdef GOST_LIB_NAME -static ERR_STRING_DATA GOST_lib_name[] = { - {0, GOST_LIB_NAME}, - {0, NULL} -}; -#endif - -static int GOST_lib_error_code = 0; -static int GOST_error_init = 1; - -void ERR_load_GOST_strings(void) -{ - if (GOST_lib_error_code == 0) - GOST_lib_error_code = ERR_get_next_error_library(); - - if (GOST_error_init) { - GOST_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(GOST_lib_error_code, GOST_str_functs); - ERR_load_strings(GOST_lib_error_code, GOST_str_reasons); -#endif - -#ifdef GOST_LIB_NAME - GOST_lib_name->error = ERR_PACK(GOST_lib_error_code, 0, 0); - ERR_load_strings(0, GOST_lib_name); -#endif - } -} - -void ERR_unload_GOST_strings(void) -{ - if (GOST_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(GOST_lib_error_code, GOST_str_functs); - ERR_unload_strings(GOST_lib_error_code, GOST_str_reasons); -#endif - -#ifdef GOST_LIB_NAME - ERR_unload_strings(0, GOST_lib_name); -#endif - GOST_error_init = 1; - } -} - -void ERR_GOST_error(int function, int reason, char *file, int line) -{ - if (GOST_lib_error_code == 0) - GOST_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(GOST_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_gost_err.h b/Sources/COpenSSL/e_gost_err.h deleted file mode 100644 index a2018ec4..00000000 --- a/Sources/COpenSSL/e_gost_err.h +++ /dev/null @@ -1,158 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_GOST_ERR_H -# define HEADER_GOST_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_GOST_strings(void); -void ERR_unload_GOST_strings(void); -void ERR_GOST_error(int function, int reason, char *file, int line); -# define GOSTerr(f,r) ERR_GOST_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the GOST functions. */ - -/* Function codes. */ -# define GOST_F_DECODE_GOST_ALGOR_PARAMS 99 -# define GOST_F_ENCODE_GOST_ALGOR_PARAMS 100 -# define GOST_F_FILL_GOST2001_PARAMS 101 -# define GOST_F_FILL_GOST94_PARAMS 102 -# define GOST_F_GET_ENCRYPTION_PARAMS 103 -# define GOST_F_GOST2001_COMPUTE_PUBLIC 104 -# define GOST_F_GOST2001_DO_SIGN 105 -# define GOST_F_GOST2001_DO_VERIFY 106 -# define GOST_F_GOST2001_KEYGEN 107 -# define GOST_F_GOST89_GET_ASN1_PARAMETERS 108 -# define GOST_F_GOST89_SET_ASN1_PARAMETERS 109 -# define GOST_F_GOST94_COMPUTE_PUBLIC 110 -# define GOST_F_GOST_CIPHER_CTL 111 -# define GOST_F_GOST_DO_SIGN 112 -# define GOST_F_GOST_DO_VERIFY 113 -# define GOST_F_GOST_IMIT_CTRL 114 -# define GOST_F_GOST_IMIT_FINAL 140 -# define GOST_F_GOST_IMIT_UPDATE 115 -# define GOST_F_GOST_SIGN_KEYGEN 142 -# define GOST_F_PARAM_COPY_GOST01 116 -# define GOST_F_PARAM_COPY_GOST94 117 -# define GOST_F_PKEY_GOST01CP_DECRYPT 118 -# define GOST_F_PKEY_GOST01CP_ENCRYPT 119 -# define GOST_F_PKEY_GOST01CP_KEYGEN 120 -# define GOST_F_PKEY_GOST01_PARAMGEN 138 -# define GOST_F_PKEY_GOST2001_DERIVE 121 -# define GOST_F_PKEY_GOST94CP_DECRYPT 122 -# define GOST_F_PKEY_GOST94CP_ENCRYPT 123 -# define GOST_F_PKEY_GOST94CP_KEYGEN 124 -# define GOST_F_PKEY_GOST94_PARAMGEN 139 -# define GOST_F_PKEY_GOST_CTRL 125 -# define GOST_F_PKEY_GOST_CTRL01_STR 126 -# define GOST_F_PKEY_GOST_CTRL94_STR 127 -# define GOST_F_PKEY_GOST_MAC_CTRL 128 -# define GOST_F_PKEY_GOST_MAC_CTRL_STR 129 -# define GOST_F_PKEY_GOST_MAC_KEYGEN 130 -# define GOST_F_PRINT_GOST_01 131 -# define GOST_F_PRIV_DECODE_GOST 132 -# define GOST_F_PUB_DECODE_GOST01 133 -# define GOST_F_PUB_DECODE_GOST94 134 -# define GOST_F_PUB_ENCODE_GOST01 135 -# define GOST_F_UNPACK_CC_SIGNATURE 136 -# define GOST_F_UNPACK_CP_SIGNATURE 137 - -/* Reason codes. */ -# define GOST_R_BAD_KEY_PARAMETERS_FORMAT 99 -# define GOST_R_BAD_PKEY_PARAMETERS_FORMAT 100 -# define GOST_R_CANNOT_PACK_EPHEMERAL_KEY 101 -# define GOST_R_CTRL_CALL_FAILED 132 -# define GOST_R_ERROR_COMPUTING_SHARED_KEY 102 -# define GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO 103 -# define GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO 104 -# define GOST_R_INCOMPATIBLE_ALGORITHMS 105 -# define GOST_R_INCOMPATIBLE_PEER_KEY 131 -# define GOST_R_INVALID_CIPHER_PARAMS 106 -# define GOST_R_INVALID_CIPHER_PARAM_OID 107 -# define GOST_R_INVALID_DIGEST_TYPE 108 -# define GOST_R_INVALID_GOST94_PARMSET 109 -# define GOST_R_INVALID_IV_LENGTH 110 -# define GOST_R_INVALID_MAC_KEY_LENGTH 111 -# define GOST_R_INVALID_PARAMSET 112 -# define GOST_R_KEY_IS_NOT_INITALIZED 113 -# define GOST_R_KEY_IS_NOT_INITIALIZED 114 -# define GOST_R_KEY_PARAMETERS_MISSING 115 -# define GOST_R_MAC_KEY_NOT_SET 116 -# define GOST_R_MALLOC_FAILURE 117 -# define GOST_R_NO_MEMORY 118 -# define GOST_R_NO_PARAMETERS_SET 119 -# define GOST_R_NO_PEER_KEY 120 -# define GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR 121 -# define GOST_R_PUBLIC_KEY_UNDEFINED 122 -# define GOST_R_RANDOM_GENERATOR_ERROR 123 -# define GOST_R_RANDOM_GENERATOR_FAILURE 124 -# define GOST_R_RANDOM_NUMBER_GENERATOR_FAILED 125 -# define GOST_R_SIGNATURE_MISMATCH 126 -# define GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q 127 -# define GOST_R_UKM_NOT_SET 128 -# define GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND 129 -# define GOST_R_UNSUPPORTED_PARAMETER_SET 130 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_idea.c b/Sources/COpenSSL/e_idea.c deleted file mode 100644 index bd01a781..00000000 --- a/Sources/COpenSSL/e_idea.c +++ /dev/null @@ -1,119 +0,0 @@ -/* crypto/evp/e_idea.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_IDEA -# include "evp.h" -# include "objects.h" -# include "evp_locl.h" -# include "idea.h" - -static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - -/* - * NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a - * special case - */ - -static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - BLOCK_CIPHER_ecb_loop() - idea_ecb_encrypt(in + i, out + i, ctx->cipher_data); - return 1; -} - -/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */ - -typedef struct { - IDEA_KEY_SCHEDULE ks; -} EVP_IDEA_KEY; - -BLOCK_CIPHER_func_cbc(idea, idea, EVP_IDEA_KEY, ks) - BLOCK_CIPHER_func_ofb(idea, idea, 64, EVP_IDEA_KEY, ks) - BLOCK_CIPHER_func_cfb(idea, idea, 64, EVP_IDEA_KEY, ks) - - BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64, - 0, idea_init_key, NULL, - EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) - -static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - if (!enc) { - if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) - enc = 1; - else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) - enc = 1; - } - if (enc) - idea_set_encrypt_key(key, ctx->cipher_data); - else { - IDEA_KEY_SCHEDULE tmp; - - idea_set_encrypt_key(key, &tmp); - idea_set_decrypt_key(&tmp, ctx->cipher_data); - OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE)); - } - return 1; -} - -#endif diff --git a/Sources/COpenSSL/e_null.c b/Sources/COpenSSL/e_null.c deleted file mode 100644 index 33320a6d..00000000 --- a/Sources/COpenSSL/e_null.c +++ /dev/null @@ -1,100 +0,0 @@ -/* crypto/evp/e_null.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "objects.h" - -static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -static const EVP_CIPHER n_cipher = { - NID_undef, - 1, 0, 0, - 0, - null_init_key, - null_cipher, - NULL, - 0, - NULL, - NULL, - NULL, - NULL -}; - -const EVP_CIPHER *EVP_enc_null(void) -{ - return (&n_cipher); -} - -static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - /* memset(&(ctx->c),0,sizeof(ctx->c)); */ - return 1; -} - -static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - if (in != out) - memcpy((char *)out, (const char *)in, inl); - return 1; -} diff --git a/Sources/COpenSSL/e_nuron.c b/Sources/COpenSSL/e_nuron.c deleted file mode 100644 index 2dd3f5a2..00000000 --- a/Sources/COpenSSL/e_nuron.c +++ /dev/null @@ -1,437 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/engine/hw_nuron.c */ -/* - * Written by Ben Laurie for the OpenSSL Project, leaning heavily on Geoff - * Thorpe's Atalla implementation. - */ -/* ==================================================================== - * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "crypto.h" -#include "buffer.h" -#include "dso.h" -#include "engine.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#include "bn.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_NURON - -# define NURON_LIB_NAME "nuron engine" -# include "e_nuron_err.c" - -static const char *NURON_LIBNAME = NULL; -static const char *get_NURON_LIBNAME(void) -{ - if (NURON_LIBNAME) - return NURON_LIBNAME; - return "nuronssl"; -} - -static void free_NURON_LIBNAME(void) -{ - if (NURON_LIBNAME) - OPENSSL_free((void *)NURON_LIBNAME); - NURON_LIBNAME = NULL; -} - -static long set_NURON_LIBNAME(const char *name) -{ - free_NURON_LIBNAME(); - return (((NURON_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); -} - -static const char *NURON_F1 = "nuron_mod_exp"; - -/* The definitions for control commands specific to this engine */ -# define NURON_CMD_SO_PATH ENGINE_CMD_BASE -static const ENGINE_CMD_DEFN nuron_cmd_defns[] = { - {NURON_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'nuronssl' shared library", - ENGINE_CMD_FLAG_STRING}, - {0, NULL, NULL, 0} -}; - -typedef int tfnModExp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m); -static tfnModExp *pfnModExp = NULL; - -static DSO *pvDSOHandle = NULL; - -static int nuron_destroy(ENGINE *e) -{ - free_NURON_LIBNAME(); - ERR_unload_NURON_strings(); - return 1; -} - -static int nuron_init(ENGINE *e) -{ - if (pvDSOHandle != NULL) { - NURONerr(NURON_F_NURON_INIT, NURON_R_ALREADY_LOADED); - return 0; - } - - pvDSOHandle = DSO_load(NULL, get_NURON_LIBNAME(), NULL, - DSO_FLAG_NAME_TRANSLATION_EXT_ONLY); - if (!pvDSOHandle) { - NURONerr(NURON_F_NURON_INIT, NURON_R_DSO_NOT_FOUND); - return 0; - } - - pfnModExp = (tfnModExp *) DSO_bind_func(pvDSOHandle, NURON_F1); - if (!pfnModExp) { - NURONerr(NURON_F_NURON_INIT, NURON_R_DSO_FUNCTION_NOT_FOUND); - return 0; - } - - return 1; -} - -static int nuron_finish(ENGINE *e) -{ - free_NURON_LIBNAME(); - if (pvDSOHandle == NULL) { - NURONerr(NURON_F_NURON_FINISH, NURON_R_NOT_LOADED); - return 0; - } - if (!DSO_free(pvDSOHandle)) { - NURONerr(NURON_F_NURON_FINISH, NURON_R_DSO_FAILURE); - return 0; - } - pvDSOHandle = NULL; - pfnModExp = NULL; - return 1; -} - -static int nuron_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int initialised = ((pvDSOHandle == NULL) ? 0 : 1); - switch (cmd) { - case NURON_CMD_SO_PATH: - if (p == NULL) { - NURONerr(NURON_F_NURON_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (initialised) { - NURONerr(NURON_F_NURON_CTRL, NURON_R_ALREADY_LOADED); - return 0; - } - return set_NURON_LIBNAME((const char *)p); - default: - break; - } - NURONerr(NURON_F_NURON_CTRL, NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED); - return 0; -} - -static int nuron_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - if (!pvDSOHandle) { - NURONerr(NURON_F_NURON_MOD_EXP, NURON_R_NOT_LOADED); - return 0; - } - return pfnModExp(r, a, p, m); -} - -# ifndef OPENSSL_NO_RSA -static int nuron_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx) -{ - return nuron_mod_exp(r0, I, rsa->d, rsa->n, ctx); -} -# endif - -# ifndef OPENSSL_NO_DSA -/* - * This code was liberated and adapted from the commented-out code in - * dsa_ossl.c. Because of the unoptimised form of the Atalla acceleration (it - * doesn't have a CRT form for RSA), this function means that an Atalla - * system running with a DSA server certificate can handshake around 5 or 6 - * times faster/more than an equivalent system running with RSA. Just check - * out the "signs" statistics from the RSA and DSA parts of "openssl speed - * -engine atalla dsa1024 rsa1024". - */ -static int nuron_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, - BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *in_mont) -{ - BIGNUM t; - int to_return = 0; - - BN_init(&t); - /* let rr = a1 ^ p1 mod m */ - if (!nuron_mod_exp(rr, a1, p1, m, ctx)) - goto end; - /* let t = a2 ^ p2 mod m */ - if (!nuron_mod_exp(&t, a2, p2, m, ctx)) - goto end; - /* let rr = rr * t mod m */ - if (!BN_mod_mul(rr, rr, &t, m, ctx)) - goto end; - to_return = 1; - end: - BN_free(&t); - return to_return; -} - -static int nuron_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return nuron_mod_exp(r, a, p, m, ctx); -} -# endif - -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -# ifndef OPENSSL_NO_RSA -static int nuron_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return nuron_mod_exp(r, a, p, m, ctx); -} -# endif - -# ifndef OPENSSL_NO_DH -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int nuron_mod_exp_dh(const DH *dh, BIGNUM *r, - const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return nuron_mod_exp(r, a, p, m, ctx); -} -# endif - -# ifndef OPENSSL_NO_RSA -static RSA_METHOD nuron_rsa = { - "Nuron RSA method", - NULL, - NULL, - NULL, - NULL, - nuron_rsa_mod_exp, - nuron_mod_exp_mont, - NULL, - NULL, - 0, - NULL, - NULL, - NULL, - NULL -}; -# endif - -# ifndef OPENSSL_NO_DSA -static DSA_METHOD nuron_dsa = { - "Nuron DSA method", - NULL, /* dsa_do_sign */ - NULL, /* dsa_sign_setup */ - NULL, /* dsa_do_verify */ - nuron_dsa_mod_exp, /* dsa_mod_exp */ - nuron_mod_exp_dsa, /* bn_mod_exp */ - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - NULL, /* dsa_paramgen */ - NULL /* dsa_keygen */ -}; -# endif - -# ifndef OPENSSL_NO_DH -static DH_METHOD nuron_dh = { - "Nuron DH method", - NULL, - NULL, - nuron_mod_exp_dh, - NULL, - NULL, - 0, - NULL, - NULL -}; -# endif - -/* Constants used when creating the ENGINE */ -static const char *engine_nuron_id = "nuron"; -static const char *engine_nuron_name = "Nuron hardware engine support"; - -/* - * This internal function is used by ENGINE_nuron() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_helper(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif -# ifndef OPENSSL_NO_DSA - const DSA_METHOD *meth2; -# endif -# ifndef OPENSSL_NO_DH - const DH_METHOD *meth3; -# endif - if (!ENGINE_set_id(e, engine_nuron_id) || - !ENGINE_set_name(e, engine_nuron_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &nuron_rsa) || -# endif -# ifndef OPENSSL_NO_DSA - !ENGINE_set_DSA(e, &nuron_dsa) || -# endif -# ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &nuron_dh) || -# endif - !ENGINE_set_destroy_function(e, nuron_destroy) || - !ENGINE_set_init_function(e, nuron_init) || - !ENGINE_set_finish_function(e, nuron_finish) || - !ENGINE_set_ctrl_function(e, nuron_ctrl) || - !ENGINE_set_cmd_defns(e, nuron_cmd_defns)) - return 0; - -# ifndef OPENSSL_NO_RSA - /* - * We know that the "PKCS1_SSLeay()" functions hook properly to the - * nuron-specific mod_exp and mod_exp_crt so we use those functions. NB: - * We don't use ENGINE_openssl() or anything "more generic" because - * something like the RSAref code may not hook properly, and if you own - * one of these cards then you have the right to do RSA operations on it - * anyway! - */ - meth1 = RSA_PKCS1_SSLeay(); - nuron_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - nuron_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - nuron_rsa.rsa_priv_enc = meth1->rsa_priv_enc; - nuron_rsa.rsa_priv_dec = meth1->rsa_priv_dec; -# endif - -# ifndef OPENSSL_NO_DSA - /* - * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits. - */ - meth2 = DSA_OpenSSL(); - nuron_dsa.dsa_do_sign = meth2->dsa_do_sign; - nuron_dsa.dsa_sign_setup = meth2->dsa_sign_setup; - nuron_dsa.dsa_do_verify = meth2->dsa_do_verify; -# endif - -# ifndef OPENSSL_NO_DH - /* Much the same for Diffie-Hellman */ - meth3 = DH_OpenSSL(); - nuron_dh.generate_key = meth3->generate_key; - nuron_dh.compute_key = meth3->compute_key; -# endif - - /* Ensure the nuron error handling is set up */ - ERR_load_NURON_strings(); - return 1; -} - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE -static ENGINE *engine_nuron(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_nuron(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_nuron(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_nuron_id) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ -# endif /* !OPENSSL_NO_HW_NURON */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_nuron_err.c b/Sources/COpenSSL/e_nuron_err.c deleted file mode 100644 index 649525cc..00000000 --- a/Sources/COpenSSL/e_nuron_err.c +++ /dev/null @@ -1,142 +0,0 @@ -/* e_nuron_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_nuron_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA NURON_str_functs[] = { - {ERR_FUNC(NURON_F_NURON_CTRL), "NURON_CTRL"}, - {ERR_FUNC(NURON_F_NURON_FINISH), "NURON_FINISH"}, - {ERR_FUNC(NURON_F_NURON_INIT), "NURON_INIT"}, - {ERR_FUNC(NURON_F_NURON_MOD_EXP), "NURON_MOD_EXP"}, - {0, NULL} -}; - -static ERR_STRING_DATA NURON_str_reasons[] = { - {ERR_REASON(NURON_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(NURON_R_DSO_FAILURE), "dso failure"}, - {ERR_REASON(NURON_R_DSO_FUNCTION_NOT_FOUND), "dso function not found"}, - {ERR_REASON(NURON_R_DSO_NOT_FOUND), "dso not found"}, - {ERR_REASON(NURON_R_NOT_LOADED), "not loaded"}, - {0, NULL} -}; - -#endif - -#ifdef NURON_LIB_NAME -static ERR_STRING_DATA NURON_lib_name[] = { - {0, NURON_LIB_NAME}, - {0, NULL} -}; -#endif - -static int NURON_lib_error_code = 0; -static int NURON_error_init = 1; - -static void ERR_load_NURON_strings(void) -{ - if (NURON_lib_error_code == 0) - NURON_lib_error_code = ERR_get_next_error_library(); - - if (NURON_error_init) { - NURON_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(NURON_lib_error_code, NURON_str_functs); - ERR_load_strings(NURON_lib_error_code, NURON_str_reasons); -#endif - -#ifdef NURON_LIB_NAME - NURON_lib_name->error = ERR_PACK(NURON_lib_error_code, 0, 0); - ERR_load_strings(0, NURON_lib_name); -#endif - } -} - -static void ERR_unload_NURON_strings(void) -{ - if (NURON_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(NURON_lib_error_code, NURON_str_functs); - ERR_unload_strings(NURON_lib_error_code, NURON_str_reasons); -#endif - -#ifdef NURON_LIB_NAME - ERR_unload_strings(0, NURON_lib_name); -#endif - NURON_error_init = 1; - } -} - -static void ERR_NURON_error(int function, int reason, char *file, int line) -{ - if (NURON_lib_error_code == 0) - NURON_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(NURON_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_nuron_err.h b/Sources/COpenSSL/e_nuron_err.h deleted file mode 100644 index aa7849c6..00000000 --- a/Sources/COpenSSL/e_nuron_err.h +++ /dev/null @@ -1,91 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_NURON_ERR_H -# define HEADER_NURON_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_NURON_strings(void); -static void ERR_unload_NURON_strings(void); -static void ERR_NURON_error(int function, int reason, char *file, int line); -# define NURONerr(f,r) ERR_NURON_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the NURON functions. */ - -/* Function codes. */ -# define NURON_F_NURON_CTRL 100 -# define NURON_F_NURON_FINISH 101 -# define NURON_F_NURON_INIT 102 -# define NURON_F_NURON_MOD_EXP 103 - -/* Reason codes. */ -# define NURON_R_ALREADY_LOADED 100 -# define NURON_R_CTRL_COMMAND_NOT_IMPLEMENTED 101 -# define NURON_R_DSO_FAILURE 102 -# define NURON_R_DSO_FUNCTION_NOT_FOUND 103 -# define NURON_R_DSO_NOT_FOUND 104 -# define NURON_R_NOT_LOADED 105 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_old.c b/Sources/COpenSSL/e_old.c deleted file mode 100644 index 93e5a4c3..00000000 --- a/Sources/COpenSSL/e_old.c +++ /dev/null @@ -1,164 +0,0 @@ -/* crypto/evp/e_old.c */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifdef OPENSSL_NO_DEPRECATED -static void *dummy = &dummy; -#else - -# include "evp.h" - -/* - * Define some deprecated functions, so older programs don't crash and burn - * too quickly. On Windows and VMS, these will never be used, since - * functions and variables in shared libraries are selected by entry point - * location, not by name. - */ - -# ifndef OPENSSL_NO_BF -# undef EVP_bf_cfb -const EVP_CIPHER *EVP_bf_cfb(void); -const EVP_CIPHER *EVP_bf_cfb(void) -{ - return EVP_bf_cfb64(); -} -# endif - -# ifndef OPENSSL_NO_DES -# undef EVP_des_cfb -const EVP_CIPHER *EVP_des_cfb(void); -const EVP_CIPHER *EVP_des_cfb(void) -{ - return EVP_des_cfb64(); -} - -# undef EVP_des_ede3_cfb -const EVP_CIPHER *EVP_des_ede3_cfb(void); -const EVP_CIPHER *EVP_des_ede3_cfb(void) -{ - return EVP_des_ede3_cfb64(); -} - -# undef EVP_des_ede_cfb -const EVP_CIPHER *EVP_des_ede_cfb(void); -const EVP_CIPHER *EVP_des_ede_cfb(void) -{ - return EVP_des_ede_cfb64(); -} -# endif - -# ifndef OPENSSL_NO_IDEA -# undef EVP_idea_cfb -const EVP_CIPHER *EVP_idea_cfb(void); -const EVP_CIPHER *EVP_idea_cfb(void) -{ - return EVP_idea_cfb64(); -} -# endif - -# ifndef OPENSSL_NO_RC2 -# undef EVP_rc2_cfb -const EVP_CIPHER *EVP_rc2_cfb(void); -const EVP_CIPHER *EVP_rc2_cfb(void) -{ - return EVP_rc2_cfb64(); -} -# endif - -# ifndef OPENSSL_NO_CAST -# undef EVP_cast5_cfb -const EVP_CIPHER *EVP_cast5_cfb(void); -const EVP_CIPHER *EVP_cast5_cfb(void) -{ - return EVP_cast5_cfb64(); -} -# endif - -# ifndef OPENSSL_NO_RC5 -# undef EVP_rc5_32_12_16_cfb -const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void); -const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) -{ - return EVP_rc5_32_12_16_cfb64(); -} -# endif - -# ifndef OPENSSL_NO_AES -# undef EVP_aes_128_cfb -const EVP_CIPHER *EVP_aes_128_cfb(void); -const EVP_CIPHER *EVP_aes_128_cfb(void) -{ - return EVP_aes_128_cfb128(); -} - -# undef EVP_aes_192_cfb -const EVP_CIPHER *EVP_aes_192_cfb(void); -const EVP_CIPHER *EVP_aes_192_cfb(void) -{ - return EVP_aes_192_cfb128(); -} - -# undef EVP_aes_256_cfb -const EVP_CIPHER *EVP_aes_256_cfb(void); -const EVP_CIPHER *EVP_aes_256_cfb(void) -{ - return EVP_aes_256_cfb128(); -} -# endif - -#endif diff --git a/Sources/COpenSSL/e_os.h b/Sources/COpenSSL/e_os.h deleted file mode 100644 index ffc7772f..00000000 --- a/Sources/COpenSSL/e_os.h +++ /dev/null @@ -1,782 +0,0 @@ -/* e_os.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_E_OS_H -# define HEADER_E_OS_H - -# include "opensslconf.h" - -# include "e_os2.h" -/* - * contains what we can justify to make visible to the - * outside; this file e_os.h is not part of the exported interface. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Used to checking reference counts, most while doing perl5 stuff :-) */ -# ifdef REF_PRINT -# undef REF_PRINT -# define REF_PRINT(a,b) fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a) -# endif - -# ifndef DEVRANDOM -/* - * set this to a comma-separated list of 'random' device files to try out. My - * default, we will try to read at least one of these files - */ -# define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom" -# endif -# ifndef DEVRANDOM_EGD -/* - * set this to a comma-seperated list of 'egd' sockets to try out. These - * sockets will be tried in the order listed in case accessing the device - * files listed in DEVRANDOM did not return enough entropy. - */ -# define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy" -# endif - -# if defined(OPENSSL_SYS_VXWORKS) -# define NO_SYS_PARAM_H -# define NO_CHMOD -# define NO_SYSLOG -# endif - -# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) -# if macintosh==1 -# ifndef MAC_OS_GUSI_SOURCE -# define MAC_OS_pre_X -# define NO_SYS_TYPES_H -# endif -# define NO_SYS_PARAM_H -# define NO_CHMOD -# define NO_SYSLOG -# undef DEVRANDOM -# define GETPID_IS_MEANINGLESS -# endif -# endif - -/******************************************************************** - The Microsoft section - ********************************************************************/ -/* - * The following is used because of the small stack in some Microsoft - * operating systems - */ -# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32) -# define MS_STATIC static -# else -# define MS_STATIC -# endif - -# if defined(OPENSSL_SYS_WIN32) && !defined(WIN32) -# define WIN32 -# endif -# if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -# endif -# if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS) -# define MSDOS -# endif - -# if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS) -# define GETPID_IS_MEANINGLESS -# endif - -# ifdef WIN32 -# define get_last_sys_error() GetLastError() -# define clear_sys_error() SetLastError(0) -# if !defined(WINNT) -# define WIN_CONSOLE_BUG -# endif -# else -# define get_last_sys_error() errno -# define clear_sys_error() errno=0 -# endif - -# if defined(WINDOWS) -# define get_last_socket_error() WSAGetLastError() -# define clear_socket_error() WSASetLastError(0) -# define readsocket(s,b,n) recv((s),(b),(n),0) -# define writesocket(s,b,n) send((s),(b),(n),0) -# elif defined(__DJGPP__) -# define WATT32 -# define get_last_socket_error() errno -# define clear_socket_error() errno=0 -# define closesocket(s) close_s(s) -# define readsocket(s,b,n) read_s(s,b,n) -# define writesocket(s,b,n) send(s,b,n,0) -# elif defined(MAC_OS_pre_X) -# define get_last_socket_error() errno -# define clear_socket_error() errno=0 -# define closesocket(s) MacSocket_close(s) -# define readsocket(s,b,n) MacSocket_recv((s),(b),(n),true) -# define writesocket(s,b,n) MacSocket_send((s),(b),(n)) -# elif defined(OPENSSL_SYS_VMS) -# define get_last_socket_error() errno -# define clear_socket_error() errno=0 -# define ioctlsocket(a,b,c) ioctl(a,b,c) -# define closesocket(s) close(s) -# define readsocket(s,b,n) recv((s),(b),(n),0) -# define writesocket(s,b,n) send((s),(b),(n),0) -# elif defined(OPENSSL_SYS_VXWORKS) -# define get_last_socket_error() errno -# define clear_socket_error() errno=0 -# define ioctlsocket(a,b,c) ioctl((a),(b),(int)(c)) -# define closesocket(s) close(s) -# define readsocket(s,b,n) read((s),(b),(n)) -# define writesocket(s,b,n) write((s),(char *)(b),(n)) -# elif defined(OPENSSL_SYS_BEOS_R5) -# define get_last_socket_error() errno -# define clear_socket_error() errno=0 -# define FIONBIO SO_NONBLOCK -# define ioctlsocket(a,b,c) setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c))) -# define readsocket(s,b,n) recv((s),(b),(n),0) -# define writesocket(s,b,n) send((s),(b),(n),0) -# elif defined(OPENSSL_SYS_NETWARE) -# if defined(NETWARE_BSDSOCK) -# define get_last_socket_error() errno -# define clear_socket_error() errno=0 -# define closesocket(s) close(s) -# define ioctlsocket(a,b,c) ioctl(a,b,c) -# if defined(NETWARE_LIBC) -# define readsocket(s,b,n) recv((s),(b),(n),0) -# define writesocket(s,b,n) send((s),(b),(n),0) -# else -# define readsocket(s,b,n) recv((s),(char*)(b),(n),0) -# define writesocket(s,b,n) send((s),(char*)(b),(n),0) -# endif -# else -# define get_last_socket_error() WSAGetLastError() -# define clear_socket_error() WSASetLastError(0) -# define readsocket(s,b,n) recv((s),(b),(n),0) -# define writesocket(s,b,n) send((s),(b),(n),0) -# endif -# else -# define get_last_socket_error() errno -# define clear_socket_error() errno=0 -# define ioctlsocket(a,b,c) ioctl(a,b,c) -# define closesocket(s) close(s) -# define readsocket(s,b,n) read((s),(b),(n)) -# define writesocket(s,b,n) write((s),(b),(n)) -# endif - -# ifdef WIN16 /* never the case */ -# define MS_CALLBACK _far _loadds -# define MS_FAR _far -# else -# define MS_CALLBACK -# define MS_FAR -# endif - -# ifdef OPENSSL_NO_STDIO -# undef OPENSSL_NO_FP_API -# define OPENSSL_NO_FP_API -# endif - -# if (defined(WINDOWS) || defined(MSDOS)) - -# ifdef __DJGPP__ -# include -# include -# include -# include -# include -# define _setmode setmode -# define _O_TEXT O_TEXT -# define _O_BINARY O_BINARY -# undef DEVRANDOM -# define DEVRANDOM "/dev/urandom\x24" -# endif /* __DJGPP__ */ - -# ifndef S_IFDIR -# define S_IFDIR _S_IFDIR -# endif - -# ifndef S_IFMT -# define S_IFMT _S_IFMT -# endif - -# if !defined(WINNT) && !defined(__DJGPP__) -# define NO_SYSLOG -# endif -# define NO_DIRENT - -# ifdef WINDOWS -# if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT) - /* - * Defining _WIN32_WINNT here in e_os.h implies certain "discipline." - * Most notably we ought to check for availability of each specific - * routine with GetProcAddress() and/or guard NT-specific calls with - * GetVersion() < 0x80000000. One can argue that in latter "or" case - * we ought to /DELAYLOAD some .DLLs in order to protect ourselves - * against run-time link errors. This doesn't seem to be necessary, - * because it turned out that already Windows 95, first non-NT Win32 - * implementation, is equipped with at least NT 3.51 stubs, dummy - * routines with same name, but which do nothing. Meaning that it's - * apparently sufficient to guard "vanilla" NT calls with GetVersion - * alone, while NT 4.0 and above interfaces ought to be linked with - * GetProcAddress at run-time. - */ -# define _WIN32_WINNT 0x0400 -# endif -# if !defined(OPENSSL_NO_SOCK) && (defined(_WIN32_WINNT) || defined(_WIN32_WCE)) - /* - * Just like defining _WIN32_WINNT including winsock2.h implies - * certain "discipline" for maintaining [broad] binary compatibility. - * As long as structures are invariant among Winsock versions, - * it's sufficient to check for specific Winsock2 API availability - * at run-time [DSO_global_lookup is recommended]... - */ -# include -# include - /* yes, they have to be #included prior to */ -# endif -# include -# include -# include -# include -# if defined(_WIN32_WCE) && !defined(EACCES) -# define EACCES 13 -# endif -# include -# ifdef _WIN64 -# define strlen(s) _strlen31(s) -/* cut strings to 2GB */ -static __inline unsigned int _strlen31(const char *str) -{ - unsigned int len = 0; - while (*str && len < 0x80000000U) - str++, len++; - return len & 0x7FFFFFFF; -} -# endif -# include -# if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace) - /* compensate for bug in VC6 ctype.h */ -# undef isspace -# undef isdigit -# undef isalnum -# undef isupper -# undef isxdigit -# endif -# if defined(_MSC_VER) && !defined(_WIN32_WCE) && !defined(_DLL) && defined(stdin) -# if _MSC_VER>=1300 && _MSC_VER<1600 -# undef stdin -# undef stdout -# undef stderr -FILE *__iob_func(); -# define stdin (&__iob_func()[0]) -# define stdout (&__iob_func()[1]) -# define stderr (&__iob_func()[2]) -# elif _MSC_VER<1300 && defined(I_CAN_LIVE_WITH_LNK4049) -# undef stdin -# undef stdout -# undef stderr - /* - * pre-1300 has __p__iob(), but it's available only in msvcrt.lib, - * or in other words with /MD. Declaring implicit import, i.e. with - * _imp_ prefix, works correctly with all compiler options, but - * without /MD results in LINK warning LNK4049: 'locally defined - * symbol "__iob" imported'. - */ -extern FILE *_imp___iob; -# define stdin (&_imp___iob[0]) -# define stdout (&_imp___iob[1]) -# define stderr (&_imp___iob[2]) -# endif -# endif -# endif -# include -# include - -# ifdef OPENSSL_SYS_WINCE -# define OPENSSL_NO_POSIX_IO -# endif - -# if defined (__BORLANDC__) -# define _setmode setmode -# define _O_TEXT O_TEXT -# define _O_BINARY O_BINARY -# define _int64 __int64 -# define _kbhit kbhit -# endif - -# define EXIT(n) exit(n) -# define LIST_SEPARATOR_CHAR ';' -# ifndef X_OK -# define X_OK 0 -# endif -# ifndef W_OK -# define W_OK 2 -# endif -# ifndef R_OK -# define R_OK 4 -# endif -# define OPENSSL_CONF "openssl.cnf" -# define SSLEAY_CONF OPENSSL_CONF -# define NUL_DEV "nul" -# define RFILE ".rnd" -# ifdef OPENSSL_SYS_WINCE -# define DEFAULT_HOME "" -# else -# define DEFAULT_HOME "C:" -# endif - -/* Avoid Visual Studio 13 GetVersion deprecated problems */ -# if defined(_MSC_VER) && _MSC_VER>=1800 -# define check_winnt() (1) -# define check_win_minplat(x) (1) -# else -# define check_winnt() (GetVersion() < 0x80000000) -# define check_win_minplat(x) (LOBYTE(LOWORD(GetVersion())) >= (x)) -# endif - -# else /* The non-microsoft world */ - -# ifdef OPENSSL_SYS_VMS -# define VMS 1 - /* - * some programs don't include stdlib, so exit() and others give implicit - * function warnings - */ -# include -# if defined(__DECC) -# include -# else -# include -# endif -# define OPENSSL_CONF "openssl.cnf" -# define SSLEAY_CONF OPENSSL_CONF -# define RFILE ".rnd" -# define LIST_SEPARATOR_CHAR ',' -# define NUL_DEV "NLA0:" - /* We don't have any well-defined random devices on VMS, yet... */ -# undef DEVRANDOM - /*- - We need to do this since VMS has the following coding on status codes: - - Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ... - The important thing to know is that odd numbers are considered - good, while even ones are considered errors. - Bits 3-15: actual status number - Bits 16-27: facility number. 0 is considered "unknown" - Bits 28-31: control bits. If bit 28 is set, the shell won't try to - output the message (which, for random codes, just looks ugly) - - So, what we do here is to change 0 to 1 to get the default success status, - and everything else is shifted up to fit into the status number field, and - the status is tagged as an error, which I believe is what is wanted here. - -- Richard Levitte - */ -# define EXIT(n) do { int __VMS_EXIT = n; \ - if (__VMS_EXIT == 0) \ - __VMS_EXIT = 1; \ - else \ - __VMS_EXIT = (n << 3) | 2; \ - __VMS_EXIT |= 0x10000000; \ - exit(__VMS_EXIT); } while(0) -# define NO_SYS_PARAM_H - -# elif defined(OPENSSL_SYS_NETWARE) -# include -# include -# define NO_SYS_TYPES_H -# undef DEVRANDOM -# ifdef NETWARE_CLIB -# define getpid GetThreadID -extern int GetThreadID(void); -/* # include */ -extern int kbhit(void); -# else -# include -# endif -# define NO_SYSLOG -# define _setmode setmode -# define _kbhit kbhit -# define _O_TEXT O_TEXT -# define _O_BINARY O_BINARY -# define OPENSSL_CONF "openssl.cnf" -# define SSLEAY_CONF OPENSSL_CONF -# define RFILE ".rnd" -# define LIST_SEPARATOR_CHAR ';' -# define EXIT(n) { if (n) printf("ERROR: %d\n", (int)n); exit(n); } - -# else - /* !defined VMS */ -# ifdef OPENSSL_SYS_MPE -# define NO_SYS_PARAM_H -# endif -# ifdef OPENSSL_UNISTD -# include OPENSSL_UNISTD -# else -# include -# endif -# ifndef NO_SYS_TYPES_H -# include -# endif -# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) -# define pid_t int /* pid_t is missing on NEXTSTEP/OPENSTEP - * (unless when compiling with - * -D_POSIX_SOURCE, which doesn't work for - * us) */ -# endif -# ifdef OPENSSL_SYS_NEWS4 /* setvbuf is missing on mips-sony-bsd */ -# define setvbuf(a, b, c, d) setbuffer((a), (b), (d)) -typedef unsigned long clock_t; -# endif -# ifdef OPENSSL_SYS_WIN32_CYGWIN -# include -# include -# endif - -# define OPENSSL_CONF "openssl.cnf" -# define SSLEAY_CONF OPENSSL_CONF -# define RFILE ".rnd" -# define LIST_SEPARATOR_CHAR ':' -# define NUL_DEV "/dev/null" -# define EXIT(n) exit(n) -# endif - -# define SSLeay_getpid() getpid() - -# endif - -/*************/ - -# if defined(OPENSSL_NO_SOCK) && !defined(OPENSSL_NO_DGRAM) -# define OPENSSL_NO_DGRAM -# endif - -# ifdef USE_SOCKETS -# if defined(WINDOWS) || defined(MSDOS) - /* windows world */ - -# ifdef OPENSSL_NO_SOCK -# define SSLeay_Write(a,b,c) (-1) -# define SSLeay_Read(a,b,c) (-1) -# define SHUTDOWN(fd) close(fd) -# define SHUTDOWN2(fd) close(fd) -# elif !defined(__DJGPP__) -# if defined(_WIN32_WCE) && _WIN32_WCE<410 -# define getservbyname _masked_declaration_getservbyname -# endif -# if !defined(IPPROTO_IP) - /* winsock[2].h was included already? */ -# include -# endif -# ifdef getservbyname -# undef getservbyname - /* this is used to be wcecompat/include/winsock_extras.h */ -struct servent *PASCAL getservbyname(const char *, const char *); -# endif - -# ifdef _WIN64 -/* - * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because - * the value constitutes an index in per-process table of limited size - * and not a real pointer. - */ -# define socket(d,t,p) ((int)socket(d,t,p)) -# define accept(s,f,l) ((int)accept(s,f,l)) -# endif -# define SSLeay_Write(a,b,c) send((a),(b),(c),0) -# define SSLeay_Read(a,b,c) recv((a),(b),(c),0) -# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); } -# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); } -# else -# define SSLeay_Write(a,b,c) write_s(a,b,c,0) -# define SSLeay_Read(a,b,c) read_s(a,b,c) -# define SHUTDOWN(fd) close_s(fd) -# define SHUTDOWN2(fd) close_s(fd) -# endif - -# elif defined(MAC_OS_pre_X) - -# include "MacSocket.h" -# define SSLeay_Write(a,b,c) MacSocket_send((a),(b),(c)) -# define SSLeay_Read(a,b,c) MacSocket_recv((a),(b),(c),true) -# define SHUTDOWN(fd) MacSocket_close(fd) -# define SHUTDOWN2(fd) MacSocket_close(fd) - -# elif defined(OPENSSL_SYS_NETWARE) - /* - * NetWare uses the WinSock2 interfaces by default, but can be - * configured for BSD - */ -# if defined(NETWARE_BSDSOCK) -# include -# include -# include -# if defined(NETWARE_CLIB) -# include -# else -# include -# endif -# define INVALID_SOCKET (int)(~0) -# else -# include -# endif -# define SSLeay_Write(a,b,c) send((a),(b),(c),0) -# define SSLeay_Read(a,b,c) recv((a),(b),(c),0) -# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); } -# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); } - -# else - -# ifndef NO_SYS_PARAM_H -# include -# endif -# ifdef OPENSSL_SYS_VXWORKS -# include -# elif !defined(OPENSSL_SYS_MPE) -# include /* Needed under linux for FD_XXX */ -# endif - -# include -# if defined(OPENSSL_SYS_VMS_NODECC) -# include -# include -# include -# else -# include -# ifdef FILIO_H -# include /* Added for FIONBIO under unixware */ -# endif -# include -# if !defined(OPENSSL_SYS_BEOS_R5) -# include -# endif -# endif - -# if defined(NeXT) || defined(_NEXT_SOURCE) -# include -# include -# endif - -# ifdef OPENSSL_SYS_AIX -# include -# endif - -# ifdef __QNX__ -# include -# endif - -# if defined(__sun) || defined(sun) -# include -# else -# ifndef VMS -# include -# else - /* ioctl is only in VMS > 7.0 and when socketshr is not used */ -# if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000) -# include -# endif -# endif -# endif - -# ifdef VMS -# include -# if defined(TCPIP_TYPE_SOCKETSHR) -# include -# endif -# endif - -# define SSLeay_Read(a,b,c) read((a),(b),(c)) -# define SSLeay_Write(a,b,c) write((a),(b),(c)) -# define SHUTDOWN(fd) { shutdown((fd),0); closesocket((fd)); } -# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket((fd)); } -# ifndef INVALID_SOCKET -# define INVALID_SOCKET (-1) -# endif /* INVALID_SOCKET */ -# endif - -/* - * Some IPv6 implementations are broken, disable them in known bad versions. - */ -# if !defined(OPENSSL_USE_IPV6) -# if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB) -# define OPENSSL_USE_IPV6 1 -# else -# define OPENSSL_USE_IPV6 0 -# endif -# endif - -# endif - -# if (defined(__sun) || defined(sun)) && !defined(__svr4__) && !defined(__SVR4) - /* include headers first, so our defines don't break it */ -# include -# include - /* bcopy can handle overlapping moves according to SunOS 4.1.4 manpage */ -# define memmove(s1,s2,n) bcopy((s2),(s1),(n)) -# define strtoul(s,e,b) ((unsigned long int)strtol((s),(e),(b))) -extern char *sys_errlist[]; -extern int sys_nerr; -# define strerror(errnum) \ - (((errnum)<0 || (errnum)>=sys_nerr) ? NULL : sys_errlist[errnum]) - /* Being signed SunOS 4.x memcpy breaks ASN1_OBJECT table lookup */ -# include "crypto/o_str.h" -# define memcmp OPENSSL_memcmp -# endif - -# ifndef OPENSSL_EXIT -# if defined(MONOLITH) && !defined(OPENSSL_C) -# define OPENSSL_EXIT(n) return(n) -# else -# define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0) -# endif -# endif - -/***********************************************/ - -# define DG_GCC_BUG /* gcc < 2.6.3 on DGUX */ - -# ifdef sgi -# define IRIX_CC_BUG /* all version of IRIX I've tested (4.* 5.*) */ -# endif -# ifdef OPENSSL_SYS_SNI -# define IRIX_CC_BUG /* CDS++ up to V2.0Bsomething suffered from - * the same bug. */ -# endif - -# if defined(OPENSSL_SYS_WINDOWS) -# define strcasecmp _stricmp -# define strncasecmp _strnicmp -# elif defined(OPENSSL_SYS_VMS) -/* VMS below version 7.0 doesn't have strcasecmp() */ -# include "o_str.h" -# define strcasecmp OPENSSL_strcasecmp -# define strncasecmp OPENSSL_strncasecmp -# define OPENSSL_IMPLEMENTS_strncasecmp -# elif defined(OPENSSL_SYS_OS2) && defined(__EMX__) -# define strcasecmp stricmp -# define strncasecmp strnicmp -# elif defined(OPENSSL_SYS_NETWARE) -# include -# if defined(NETWARE_CLIB) -# define strcasecmp stricmp -# define strncasecmp strnicmp -# endif /* NETWARE_CLIB */ -# endif - -# if defined(OPENSSL_SYS_OS2) && defined(__EMX__) -# include -# include -# define NO_SYSLOG -# endif - -/* vxworks */ -# if defined(OPENSSL_SYS_VXWORKS) -# include -# include -# include - -# define TTY_STRUCT int - -# define sleep(a) taskDelay((a) * sysClkRateGet()) - -# include -# include -# include - -# define getpid taskIdSelf - -/* - * NOTE: these are implemented by helpers in database app! if the database is - * not linked, we need to implement them elswhere - */ -struct hostent *gethostbyname(const char *name); -struct hostent *gethostbyaddr(const char *addr, int length, int type); -struct servent *getservbyname(const char *name, const char *proto); - -# endif -/* end vxworks */ - -/* beos */ -# if defined(OPENSSL_SYS_BEOS_R5) -# define SO_ERROR 0 -# define NO_SYS_UN -# define IPPROTO_IP 0 -# include -# endif - -# if !defined(inline) && !defined(__cplusplus) -# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L - /* do nothing, inline works */ -# elif defined(__GNUC__) && __GNUC__>=2 -# define inline __inline__ -# elif defined(_MSC_VER) - /* - * Visual Studio: inline is available in C++ only, however - * __inline is available for C, see - * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx - */ -# define inline __inline -# else -# define inline -# endif -# endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/e_os2.h b/Sources/COpenSSL/e_os2.h deleted file mode 100644 index c5b50c92..00000000 --- a/Sources/COpenSSL/e_os2.h +++ /dev/null @@ -1,328 +0,0 @@ -/* e_os2.h */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "opensslconf.h" - -#ifndef HEADER_E_OS2_H -# define HEADER_E_OS2_H - -#ifdef __cplusplus -extern "C" { -#endif - -/****************************************************************************** - * Detect operating systems. This probably needs completing. - * The result is that at least one OPENSSL_SYS_os macro should be defined. - * However, if none is defined, Unix is assumed. - **/ - -# define OPENSSL_SYS_UNIX - -/* ---------------------- Macintosh, before MacOS X ----------------------- */ -# if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_MACINTOSH_CLASSIC -# endif - -/* ---------------------- NetWare ----------------------------------------- */ -# if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_NETWARE -# endif - -/* --------------------- Microsoft operating systems ---------------------- */ - -/* - * Note that MSDOS actually denotes 32-bit environments running on top of - * MS-DOS, such as DJGPP one. - */ -# if defined(OPENSSL_SYSNAME_MSDOS) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_MSDOS -# endif - -/* - * For 32 bit environment, there seems to be the CygWin environment and then - * all the others that try to do the same thing Microsoft does... - */ -# if defined(OPENSSL_SYSNAME_UWIN) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_WIN32_UWIN -# else -# if defined(__CYGWIN__) || defined(OPENSSL_SYSNAME_CYGWIN) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_WIN32_CYGWIN -# else -# if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_WIN32 -# endif -# if defined(_WIN64) || defined(OPENSSL_SYSNAME_WIN64) -# undef OPENSSL_SYS_UNIX -# if !defined(OPENSSL_SYS_WIN64) -# define OPENSSL_SYS_WIN64 -# endif -# endif -# if defined(OPENSSL_SYSNAME_WINNT) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_WINNT -# endif -# if defined(OPENSSL_SYSNAME_WINCE) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_WINCE -# endif -# endif -# endif - -/* Anything that tries to look like Microsoft is "Windows" */ -# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_WINDOWS -# ifndef OPENSSL_SYS_MSDOS -# define OPENSSL_SYS_MSDOS -# endif -# endif - -/* - * DLL settings. This part is a bit tough, because it's up to the - * application implementor how he or she will link the application, so it - * requires some macro to be used. - */ -# ifdef OPENSSL_SYS_WINDOWS -# ifndef OPENSSL_OPT_WINDLL -# if defined(_WINDLL) /* This is used when building OpenSSL to - * indicate that DLL linkage should be used */ -# define OPENSSL_OPT_WINDLL -# endif -# endif -# endif - -/* ------------------------------- OpenVMS -------------------------------- */ -# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_VMS -# if defined(__DECC) -# define OPENSSL_SYS_VMS_DECC -# elif defined(__DECCXX) -# define OPENSSL_SYS_VMS_DECC -# define OPENSSL_SYS_VMS_DECCXX -# else -# define OPENSSL_SYS_VMS_NODECC -# endif -# endif - -/* -------------------------------- OS/2 ---------------------------------- */ -# if defined(__EMX__) || defined(__OS2__) -# undef OPENSSL_SYS_UNIX -# define OPENSSL_SYS_OS2 -# endif - -/* -------------------------------- Unix ---------------------------------- */ -# ifdef OPENSSL_SYS_UNIX -# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX) -# define OPENSSL_SYS_LINUX -# endif -# ifdef OPENSSL_SYSNAME_MPE -# define OPENSSL_SYS_MPE -# endif -# ifdef OPENSSL_SYSNAME_SNI -# define OPENSSL_SYS_SNI -# endif -# ifdef OPENSSL_SYSNAME_ULTRASPARC -# define OPENSSL_SYS_ULTRASPARC -# endif -# ifdef OPENSSL_SYSNAME_NEWS4 -# define OPENSSL_SYS_NEWS4 -# endif -# ifdef OPENSSL_SYSNAME_MACOSX -# define OPENSSL_SYS_MACOSX -# endif -# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY -# define OPENSSL_SYS_MACOSX_RHAPSODY -# define OPENSSL_SYS_MACOSX -# endif -# ifdef OPENSSL_SYSNAME_SUNOS -# define OPENSSL_SYS_SUNOS -# endif -# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY) -# define OPENSSL_SYS_CRAY -# endif -# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX) -# define OPENSSL_SYS_AIX -# endif -# endif - -/* -------------------------------- VOS ----------------------------------- */ -# if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS) -# define OPENSSL_SYS_VOS -# ifdef __HPPA__ -# define OPENSSL_SYS_VOS_HPPA -# endif -# ifdef __IA32__ -# define OPENSSL_SYS_VOS_IA32 -# endif -# endif - -/* ------------------------------ VxWorks --------------------------------- */ -# ifdef OPENSSL_SYSNAME_VXWORKS -# define OPENSSL_SYS_VXWORKS -# endif - -/* -------------------------------- BeOS ---------------------------------- */ -# if defined(__BEOS__) -# define OPENSSL_SYS_BEOS -# include -# if defined(BONE_VERSION) -# define OPENSSL_SYS_BEOS_BONE -# else -# define OPENSSL_SYS_BEOS_R5 -# endif -# endif - -/** - * That's it for OS-specific stuff - *****************************************************************************/ - -/* Specials for I/O an exit */ -# ifdef OPENSSL_SYS_MSDOS -# define OPENSSL_UNISTD_IO -# define OPENSSL_DECLARE_EXIT extern void exit(int); -# else -# define OPENSSL_UNISTD_IO OPENSSL_UNISTD -# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */ -# endif - -/*- - * Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare - * certain global symbols that, with some compilers under VMS, have to be - * defined and declared explicitely with globaldef and globalref. - * Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare - * DLL exports and imports for compilers under Win32. These are a little - * more complicated to use. Basically, for any library that exports some - * global variables, the following code must be present in the header file - * that declares them, before OPENSSL_EXTERN is used: - * - * #ifdef SOME_BUILD_FLAG_MACRO - * # undef OPENSSL_EXTERN - * # define OPENSSL_EXTERN OPENSSL_EXPORT - * #endif - * - * The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL - * have some generally sensible values, and for OPENSSL_EXTERN to have the - * value OPENSSL_IMPORT. - */ - -# if defined(OPENSSL_SYS_VMS_NODECC) -# define OPENSSL_EXPORT globalref -# define OPENSSL_IMPORT globalref -# define OPENSSL_GLOBAL globaldef -# elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL) -# define OPENSSL_EXPORT extern __declspec(dllexport) -# define OPENSSL_IMPORT extern __declspec(dllimport) -# define OPENSSL_GLOBAL -# else -# define OPENSSL_EXPORT extern -# define OPENSSL_IMPORT extern -# define OPENSSL_GLOBAL -# endif -# define OPENSSL_EXTERN OPENSSL_IMPORT - -/*- - * Macros to allow global variables to be reached through function calls when - * required (if a shared library version requires it, for example. - * The way it's done allows definitions like this: - * - * // in foobar.c - * OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) - * // in foobar.h - * OPENSSL_DECLARE_GLOBAL(int,foobar); - * #define foobar OPENSSL_GLOBAL_REF(foobar) - */ -# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION -# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ - type *_shadow_##name(void) \ - { static type _hide_##name=value; return &_hide_##name; } -# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) -# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) -# else -# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value; -# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name -# define OPENSSL_GLOBAL_REF(name) _shadow_##name -# endif - -# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE) -# define ossl_ssize_t long -# endif - -# ifdef OPENSSL_SYS_MSDOS -# define ossl_ssize_t long -# endif - -# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS) -# define ssize_t int -# endif - -# if defined(__ultrix) && !defined(ssize_t) -# define ossl_ssize_t int -# endif - -# ifndef ossl_ssize_t -# define ossl_ssize_t ssize_t -# endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_padlock.c b/Sources/COpenSSL/e_padlock.c deleted file mode 100644 index fbc3f1c4..00000000 --- a/Sources/COpenSSL/e_padlock.c +++ /dev/null @@ -1,1266 +0,0 @@ -/*- - * Support for VIA PadLock Advanced Cryptography Engine (ACE) - * Written by Michal Ludvig - * http://www.logix.cz/michal - * - * Big thanks to Andy Polyakov for a help with optimization, - * assembler fixes, port to MS Windows and a lot of other - * valuable work on this engine! - */ - -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include "opensslconf.h" -#include "crypto.h" -#include "dso.h" -#include "engine.h" -#include "evp.h" -#ifndef OPENSSL_NO_AES -# include "aes.h" -#endif -#include "rand.h" -#include "err.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_PADLOCK - -/* Attempt to have a single source for both 0.9.7 and 0.9.8 :-) */ -# if (OPENSSL_VERSION_NUMBER >= 0x00908000L) -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -# define DYNAMIC_ENGINE -# endif -# elif (OPENSSL_VERSION_NUMBER >= 0x00907000L) -# ifdef ENGINE_DYNAMIC_SUPPORT -# define DYNAMIC_ENGINE -# endif -# else -# error "Only OpenSSL >= 0.9.7 is supported" -# endif - -/* - * VIA PadLock AES is available *ONLY* on some x86 CPUs. Not only that it - * doesn't exist elsewhere, but it even can't be compiled on other platforms! - * - * In addition, because of the heavy use of inline assembler, compiler choice - * is limited to GCC and Microsoft C. - */ -# undef COMPILE_HW_PADLOCK -# if !defined(I386_ONLY) && !defined(OPENSSL_NO_INLINE_ASM) -# if (defined(__GNUC__) && (defined(__i386__) || defined(__i386))) || \ - (defined(_MSC_VER) && defined(_M_IX86)) -# define COMPILE_HW_PADLOCK -# endif -# endif - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE -# ifdef COMPILE_HW_PADLOCK -static ENGINE *ENGINE_padlock(void); -# endif - -void ENGINE_load_padlock(void) -{ -/* On non-x86 CPUs it just returns. */ -# ifdef COMPILE_HW_PADLOCK - ENGINE *toadd = ENGINE_padlock(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -# endif -} - -# endif - -# ifdef COMPILE_HW_PADLOCK -/* - * We do these includes here to avoid header problems on platforms that do - * not have the VIA padlock anyway... - */ -# include -# ifdef _WIN32 -# include -# ifndef alloca -# define alloca _alloca -# endif -# elif defined(__GNUC__) -# ifndef alloca -# define alloca(s) __builtin_alloca(s) -# endif -# endif - -/* Function for ENGINE detection and control */ -static int padlock_available(void); -static int padlock_init(ENGINE *e); - -/* RNG Stuff */ -static RAND_METHOD padlock_rand; - -/* Cipher Stuff */ -# ifndef OPENSSL_NO_AES -static int padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid); -# endif - -/* Engine names */ -static const char *padlock_id = "padlock"; -static char padlock_name[100]; - -/* Available features */ -static int padlock_use_ace = 0; /* Advanced Cryptography Engine */ -static int padlock_use_rng = 0; /* Random Number Generator */ -# ifndef OPENSSL_NO_AES -static int padlock_aes_align_required = 1; -# endif - -/* ===== Engine "management" functions ===== */ - -/* Prepare the ENGINE structure for registration */ -static int padlock_bind_helper(ENGINE *e) -{ - /* Check available features */ - padlock_available(); - -# if 1 /* disable RNG for now, see commentary in - * vicinity of RNG code */ - padlock_use_rng = 0; -# endif - - /* Generate a nice engine name with available features */ - BIO_snprintf(padlock_name, sizeof(padlock_name), - "VIA PadLock (%s, %s)", - padlock_use_rng ? "RNG" : "no-RNG", - padlock_use_ace ? "ACE" : "no-ACE"); - - /* Register everything or return with an error */ - if (!ENGINE_set_id(e, padlock_id) || - !ENGINE_set_name(e, padlock_name) || - !ENGINE_set_init_function(e, padlock_init) || -# ifndef OPENSSL_NO_AES - (padlock_use_ace && !ENGINE_set_ciphers(e, padlock_ciphers)) || -# endif - (padlock_use_rng && !ENGINE_set_RAND(e, &padlock_rand))) { - return 0; - } - - /* Everything looks good */ - return 1; -} - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE - -/* Constructor */ -static ENGINE *ENGINE_padlock(void) -{ - ENGINE *eng = ENGINE_new(); - - if (!eng) { - return NULL; - } - - if (!padlock_bind_helper(eng)) { - ENGINE_free(eng); - return NULL; - } - - return eng; -} - -# endif - -/* Check availability of the engine */ -static int padlock_init(ENGINE *e) -{ - return (padlock_use_rng || padlock_use_ace); -} - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -# ifdef DYNAMIC_ENGINE -static int padlock_bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, padlock_id) != 0)) { - return 0; - } - - if (!padlock_bind_helper(e)) { - return 0; - } - - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(padlock_bind_fn) -# endif /* DYNAMIC_ENGINE */ -/* ===== Here comes the "real" engine ===== */ -# ifndef OPENSSL_NO_AES -/* Some AES-related constants */ -# define AES_BLOCK_SIZE 16 -# define AES_KEY_SIZE_128 16 -# define AES_KEY_SIZE_192 24 -# define AES_KEY_SIZE_256 32 - /* - * Here we store the status information relevant to the current context. - */ - /* - * BIG FAT WARNING: Inline assembler in PADLOCK_XCRYPT_ASM() depends on - * the order of items in this structure. Don't blindly modify, reorder, - * etc! - */ -struct padlock_cipher_data { - unsigned char iv[AES_BLOCK_SIZE]; /* Initialization vector */ - union { - unsigned int pad[4]; - struct { - int rounds:4; - int dgst:1; /* n/a in C3 */ - int align:1; /* n/a in C3 */ - int ciphr:1; /* n/a in C3 */ - unsigned int keygen:1; - int interm:1; - unsigned int encdec:1; - int ksize:2; - } b; - } cword; /* Control word */ - AES_KEY ks; /* Encryption key */ -}; - -/* - * Essentially this variable belongs in thread local storage. - * Having this variable global on the other hand can only cause - * few bogus key reloads [if any at all on single-CPU system], - * so we accept the penatly... - */ -static volatile struct padlock_cipher_data *padlock_saved_context; -# endif - -/*- - * ======================================================= - * Inline assembler section(s). - * ======================================================= - * Order of arguments is chosen to facilitate Windows port - * using __fastcall calling convention. If you wish to add - * more routines, keep in mind that first __fastcall - * argument is passed in %ecx and second - in %edx. - * ======================================================= - */ -# if defined(__GNUC__) && __GNUC__>=2 -/* - * As for excessive "push %ebx"/"pop %ebx" found all over. - * When generating position-independent code GCC won't let - * us use "b" in assembler templates nor even respect "ebx" - * in "clobber description." Therefore the trouble... - */ - -/* - * Helper function - check if a CPUID instruction is available on this CPU - */ -static int padlock_insn_cpuid_available(void) -{ - int result = -1; - - /* - * We're checking if the bit #21 of EFLAGS can be toggled. If yes = - * CPUID is available. - */ - asm volatile ("pushf\n" - "popl %%eax\n" - "xorl $0x200000, %%eax\n" - "movl %%eax, %%ecx\n" - "andl $0x200000, %%ecx\n" - "pushl %%eax\n" - "popf\n" - "pushf\n" - "popl %%eax\n" - "andl $0x200000, %%eax\n" - "xorl %%eax, %%ecx\n" - "movl %%ecx, %0\n":"=r" (result)::"eax", "ecx"); - - return (result == 0); -} - -/* - * Load supported features of the CPU to see if the PadLock is available. - */ -static int padlock_available(void) -{ - char vendor_string[16]; - unsigned int eax, edx; - - /* First check if the CPUID instruction is available at all... */ - if (!padlock_insn_cpuid_available()) - return 0; - - /* Are we running on the Centaur (VIA) CPU? */ - eax = 0x00000000; - vendor_string[12] = 0; - asm volatile ("pushl %%ebx\n" - "cpuid\n" - "movl %%ebx,(%%edi)\n" - "movl %%edx,4(%%edi)\n" - "movl %%ecx,8(%%edi)\n" - "popl %%ebx":"+a" (eax):"D"(vendor_string):"ecx", "edx"); - if (strcmp(vendor_string, "CentaurHauls") != 0) - return 0; - - /* Check for Centaur Extended Feature Flags presence */ - eax = 0xC0000000; - asm volatile ("pushl %%ebx; cpuid; popl %%ebx":"+a" (eax)::"ecx", "edx"); - if (eax < 0xC0000001) - return 0; - - /* Read the Centaur Extended Feature Flags */ - eax = 0xC0000001; - asm volatile ("pushl %%ebx; cpuid; popl %%ebx":"+a" (eax), - "=d"(edx)::"ecx"); - - /* Fill up some flags */ - padlock_use_ace = ((edx & (0x3 << 6)) == (0x3 << 6)); - padlock_use_rng = ((edx & (0x3 << 2)) == (0x3 << 2)); - - return padlock_use_ace + padlock_use_rng; -} - -# ifndef OPENSSL_NO_AES -# ifndef AES_ASM -/* Our own htonl()/ntohl() */ -static inline void padlock_bswapl(AES_KEY *ks) -{ - size_t i = sizeof(ks->rd_key) / sizeof(ks->rd_key[0]); - unsigned int *key = ks->rd_key; - - while (i--) { - asm volatile ("bswapl %0":"+r" (*key)); - key++; - } -} -# endif -# endif - -/* - * Force key reload from memory to the CPU microcode. Loading EFLAGS from the - * stack clears EFLAGS[30] which does the trick. - */ -static inline void padlock_reload_key(void) -{ - asm volatile ("pushfl; popfl"); -} - -# ifndef OPENSSL_NO_AES -/* - * This is heuristic key context tracing. At first one - * believes that one should use atomic swap instructions, - * but it's not actually necessary. Point is that if - * padlock_saved_context was changed by another thread - * after we've read it and before we compare it with cdata, - * our key *shall* be reloaded upon thread context switch - * and we are therefore set in either case... - */ -static inline void padlock_verify_context(struct padlock_cipher_data *cdata) -{ - asm volatile ("pushfl\n" - " btl $30,(%%esp)\n" - " jnc 1f\n" - " cmpl %2,%1\n" - " je 1f\n" - " popfl\n" - " subl $4,%%esp\n" - "1: addl $4,%%esp\n" - " movl %2,%0":"+m" (padlock_saved_context) - :"r"(padlock_saved_context), "r"(cdata):"cc"); -} - -/* Template for padlock_xcrypt_* modes */ -/* - * BIG FAT WARNING: The offsets used with 'leal' instructions describe items - * of the 'padlock_cipher_data' structure. - */ -# define PADLOCK_XCRYPT_ASM(name,rep_xcrypt) \ -static inline void *name(size_t cnt, \ - struct padlock_cipher_data *cdata, \ - void *out, const void *inp) \ -{ void *iv; \ - asm volatile ( "pushl %%ebx\n" \ - " leal 16(%0),%%edx\n" \ - " leal 32(%0),%%ebx\n" \ - rep_xcrypt "\n" \ - " popl %%ebx" \ - : "=a"(iv), "=c"(cnt), "=D"(out), "=S"(inp) \ - : "0"(cdata), "1"(cnt), "2"(out), "3"(inp) \ - : "edx", "cc", "memory"); \ - return iv; \ -} - -/* Generate all functions with appropriate opcodes */ -/* rep xcryptecb */ -PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb, ".byte 0xf3,0x0f,0xa7,0xc8") -/* rep xcryptcbc */ - PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc, ".byte 0xf3,0x0f,0xa7,0xd0") -/* rep xcryptcfb */ - PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb, ".byte 0xf3,0x0f,0xa7,0xe0") -/* rep xcryptofb */ - PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb, ".byte 0xf3,0x0f,0xa7,0xe8") -# endif -/* The RNG call itself */ -static inline unsigned int padlock_xstore(void *addr, unsigned int edx_in) -{ - unsigned int eax_out; - - asm volatile (".byte 0x0f,0xa7,0xc0" /* xstore */ - :"=a" (eax_out), "=m"(*(unsigned *)addr) - :"D"(addr), "d"(edx_in) - ); - - return eax_out; -} - -/* - * Why not inline 'rep movsd'? I failed to find information on what value in - * Direction Flag one can expect and consequently have to apply - * "better-safe-than-sorry" approach and assume "undefined." I could - * explicitly clear it and restore the original value upon return from - * padlock_aes_cipher, but it's presumably too much trouble for too little - * gain... In case you wonder 'rep xcrypt*' instructions above are *not* - * affected by the Direction Flag and pointers advance toward larger - * addresses unconditionally. - */ -static inline unsigned char *padlock_memcpy(void *dst, const void *src, - size_t n) -{ - long *d = dst; - const long *s = src; - - n /= sizeof(*d); - do { - *d++ = *s++; - } while (--n); - - return dst; -} - -# elif defined(_MSC_VER) -/* - * Unlike GCC these are real functions. In order to minimize impact - * on performance we adhere to __fastcall calling convention in - * order to get two first arguments passed through %ecx and %edx. - * Which kind of suits very well, as instructions in question use - * both %ecx and %edx as input:-) - */ -# define REP_XCRYPT(code) \ - _asm _emit 0xf3 \ - _asm _emit 0x0f _asm _emit 0xa7 \ - _asm _emit code - -/* - * BIG FAT WARNING: The offsets used with 'lea' instructions describe items - * of the 'padlock_cipher_data' structure. - */ -# define PADLOCK_XCRYPT_ASM(name,code) \ -static void * __fastcall \ - name (size_t cnt, void *cdata, \ - void *outp, const void *inp) \ -{ _asm mov eax,edx \ - _asm lea edx,[eax+16] \ - _asm lea ebx,[eax+32] \ - _asm mov edi,outp \ - _asm mov esi,inp \ - REP_XCRYPT(code) \ -} - -PADLOCK_XCRYPT_ASM(padlock_xcrypt_ecb,0xc8) -PADLOCK_XCRYPT_ASM(padlock_xcrypt_cbc,0xd0) -PADLOCK_XCRYPT_ASM(padlock_xcrypt_cfb,0xe0) -PADLOCK_XCRYPT_ASM(padlock_xcrypt_ofb,0xe8) - -static int __fastcall padlock_xstore(void *outp, unsigned int code) -{ - _asm mov edi,ecx - _asm _emit 0x0f _asm _emit 0xa7 _asm _emit 0xc0 -} - -static void __fastcall padlock_reload_key(void) -{ - _asm pushfd - _asm popfd -} - -static void __fastcall padlock_verify_context(void *cdata) -{ - _asm { - pushfd - bt DWORD PTR[esp],30 - jnc skip - cmp ecx,padlock_saved_context - je skip - popfd - sub esp,4 - skip: add esp,4 - mov padlock_saved_context,ecx - } -} - -static int -padlock_available(void) -{ - _asm { - pushfd - pop eax - mov ecx,eax - xor eax,1<<21 - push eax - popfd - pushfd - pop eax - xor eax,ecx - bt eax,21 - jnc noluck - mov eax,0 - cpuid - xor eax,eax - cmp ebx,'tneC' - jne noluck - cmp edx,'Hrua' - jne noluck - cmp ecx,'slua' - jne noluck - mov eax,0xC0000000 - cpuid - mov edx,eax - xor eax,eax - cmp edx,0xC0000001 - jb noluck - mov eax,0xC0000001 - cpuid - xor eax,eax - bt edx,6 - jnc skip_a - bt edx,7 - jnc skip_a - mov padlock_use_ace,1 - inc eax - skip_a: bt edx,2 - jnc skip_r - bt edx,3 - jnc skip_r - mov padlock_use_rng,1 - inc eax - skip_r: - noluck: - } -} - -static void __fastcall padlock_bswapl(void *key) -{ - _asm { - pushfd - cld - mov esi,ecx - mov edi,ecx - mov ecx,60 - up: lodsd - bswap eax - stosd - loop up - popfd - } -} - -/* - * MS actually specifies status of Direction Flag and compiler even manages - * to compile following as 'rep movsd' all by itself... - */ -# define padlock_memcpy(o,i,n) ((unsigned char *)memcpy((o),(i),(n)&~3U)) -# endif -/* ===== AES encryption/decryption ===== */ -# ifndef OPENSSL_NO_AES -# if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb) -# define NID_aes_128_cfb NID_aes_128_cfb128 -# endif -# if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb) -# define NID_aes_128_ofb NID_aes_128_ofb128 -# endif -# if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb) -# define NID_aes_192_cfb NID_aes_192_cfb128 -# endif -# if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb) -# define NID_aes_192_ofb NID_aes_192_ofb128 -# endif -# if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb) -# define NID_aes_256_cfb NID_aes_256_cfb128 -# endif -# if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb) -# define NID_aes_256_ofb NID_aes_256_ofb128 -# endif -/* - * List of supported ciphers. - */ static int padlock_cipher_nids[] = { - NID_aes_128_ecb, - NID_aes_128_cbc, - NID_aes_128_cfb, - NID_aes_128_ofb, - - NID_aes_192_ecb, - NID_aes_192_cbc, - NID_aes_192_cfb, - NID_aes_192_ofb, - - NID_aes_256_ecb, - NID_aes_256_cbc, - NID_aes_256_cfb, - NID_aes_256_ofb, -}; - -static int padlock_cipher_nids_num = (sizeof(padlock_cipher_nids) / - sizeof(padlock_cipher_nids[0])); - -/* Function prototypes ... */ -static int padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t nbytes); - -# define NEAREST_ALIGNED(ptr) ( (unsigned char *)(ptr) + \ - ( (0x10 - ((size_t)(ptr) & 0x0F)) & 0x0F ) ) -# define ALIGNED_CIPHER_DATA(ctx) ((struct padlock_cipher_data *)\ - NEAREST_ALIGNED(ctx->cipher_data)) - -# define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE -# define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE -# define EVP_CIPHER_block_size_OFB 1 -# define EVP_CIPHER_block_size_CFB 1 - -/* - * Declaring so many ciphers by hand would be a pain. Instead introduce a bit - * of preprocessor magic :-) - */ -# define DECLARE_AES_EVP(ksize,lmode,umode) \ -static const EVP_CIPHER padlock_aes_##ksize##_##lmode = { \ - NID_aes_##ksize##_##lmode, \ - EVP_CIPHER_block_size_##umode, \ - AES_KEY_SIZE_##ksize, \ - AES_BLOCK_SIZE, \ - 0 | EVP_CIPH_##umode##_MODE, \ - padlock_aes_init_key, \ - padlock_aes_cipher, \ - NULL, \ - sizeof(struct padlock_cipher_data) + 16, \ - EVP_CIPHER_set_asn1_iv, \ - EVP_CIPHER_get_asn1_iv, \ - NULL, \ - NULL \ -} - -DECLARE_AES_EVP(128, ecb, ECB); -DECLARE_AES_EVP(128, cbc, CBC); -DECLARE_AES_EVP(128, cfb, CFB); -DECLARE_AES_EVP(128, ofb, OFB); - -DECLARE_AES_EVP(192, ecb, ECB); -DECLARE_AES_EVP(192, cbc, CBC); -DECLARE_AES_EVP(192, cfb, CFB); -DECLARE_AES_EVP(192, ofb, OFB); - -DECLARE_AES_EVP(256, ecb, ECB); -DECLARE_AES_EVP(256, cbc, CBC); -DECLARE_AES_EVP(256, cfb, CFB); -DECLARE_AES_EVP(256, ofb, OFB); - -static int -padlock_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, - int nid) -{ - /* No specific cipher => return a list of supported nids ... */ - if (!cipher) { - *nids = padlock_cipher_nids; - return padlock_cipher_nids_num; - } - - /* ... or the requested "cipher" otherwise */ - switch (nid) { - case NID_aes_128_ecb: - *cipher = &padlock_aes_128_ecb; - break; - case NID_aes_128_cbc: - *cipher = &padlock_aes_128_cbc; - break; - case NID_aes_128_cfb: - *cipher = &padlock_aes_128_cfb; - break; - case NID_aes_128_ofb: - *cipher = &padlock_aes_128_ofb; - break; - - case NID_aes_192_ecb: - *cipher = &padlock_aes_192_ecb; - break; - case NID_aes_192_cbc: - *cipher = &padlock_aes_192_cbc; - break; - case NID_aes_192_cfb: - *cipher = &padlock_aes_192_cfb; - break; - case NID_aes_192_ofb: - *cipher = &padlock_aes_192_ofb; - break; - - case NID_aes_256_ecb: - *cipher = &padlock_aes_256_ecb; - break; - case NID_aes_256_cbc: - *cipher = &padlock_aes_256_cbc; - break; - case NID_aes_256_cfb: - *cipher = &padlock_aes_256_cfb; - break; - case NID_aes_256_ofb: - *cipher = &padlock_aes_256_ofb; - break; - - default: - /* Sorry, we don't support this NID */ - *cipher = NULL; - return 0; - } - - return 1; -} - -/* Prepare the encryption key for PadLock usage */ -static int -padlock_aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - struct padlock_cipher_data *cdata; - int key_len = EVP_CIPHER_CTX_key_length(ctx) * 8; - - if (key == NULL) - return 0; /* ERROR */ - - cdata = ALIGNED_CIPHER_DATA(ctx); - memset(cdata, 0, sizeof(struct padlock_cipher_data)); - - /* Prepare Control word. */ - if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) - cdata->cword.b.encdec = 0; - else - cdata->cword.b.encdec = (ctx->encrypt == 0); - cdata->cword.b.rounds = 10 + (key_len - 128) / 32; - cdata->cword.b.ksize = (key_len - 128) / 64; - - switch (key_len) { - case 128: - /* - * PadLock can generate an extended key for AES128 in hardware - */ - memcpy(cdata->ks.rd_key, key, AES_KEY_SIZE_128); - cdata->cword.b.keygen = 0; - break; - - case 192: - case 256: - /* - * Generate an extended AES key in software. Needed for AES192/AES256 - */ - /* - * Well, the above applies to Stepping 8 CPUs and is listed as - * hardware errata. They most likely will fix it at some point and - * then a check for stepping would be due here. - */ - if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE || - EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE || enc) - AES_set_encrypt_key(key, key_len, &cdata->ks); - else - AES_set_decrypt_key(key, key_len, &cdata->ks); -# ifndef AES_ASM - /* - * OpenSSL C functions use byte-swapped extended key. - */ - padlock_bswapl(&cdata->ks); -# endif - cdata->cword.b.keygen = 1; - break; - - default: - /* ERROR */ - return 0; - } - - /* - * This is done to cover for cases when user reuses the - * context for new key. The catch is that if we don't do - * this, padlock_eas_cipher might proceed with old key... - */ - padlock_reload_key(); - - return 1; -} - -/*- - * Simplified version of padlock_aes_cipher() used when - * 1) both input and output buffers are at aligned addresses. - * or when - * 2) running on a newer CPU that doesn't require aligned buffers. - */ -static int -padlock_aes_cipher_omnivorous(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, - const unsigned char *in_arg, size_t nbytes) -{ - struct padlock_cipher_data *cdata; - void *iv; - - cdata = ALIGNED_CIPHER_DATA(ctx); - padlock_verify_context(cdata); - - switch (EVP_CIPHER_CTX_mode(ctx)) { - case EVP_CIPH_ECB_MODE: - padlock_xcrypt_ecb(nbytes / AES_BLOCK_SIZE, cdata, out_arg, in_arg); - break; - - case EVP_CIPH_CBC_MODE: - memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); - iv = padlock_xcrypt_cbc(nbytes / AES_BLOCK_SIZE, cdata, out_arg, - in_arg); - memcpy(ctx->iv, iv, AES_BLOCK_SIZE); - break; - - case EVP_CIPH_CFB_MODE: - memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); - iv = padlock_xcrypt_cfb(nbytes / AES_BLOCK_SIZE, cdata, out_arg, - in_arg); - memcpy(ctx->iv, iv, AES_BLOCK_SIZE); - break; - - case EVP_CIPH_OFB_MODE: - memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); - padlock_xcrypt_ofb(nbytes / AES_BLOCK_SIZE, cdata, out_arg, in_arg); - memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE); - break; - - default: - return 0; - } - - memset(cdata->iv, 0, AES_BLOCK_SIZE); - - return 1; -} - -# ifndef PADLOCK_CHUNK -# define PADLOCK_CHUNK 512 /* Must be a power of 2 larger than 16 */ -# endif -# if PADLOCK_CHUNK<16 || PADLOCK_CHUNK&(PADLOCK_CHUNK-1) -# error "insane PADLOCK_CHUNK..." -# endif - -/* - * Re-align the arguments to 16-Bytes boundaries and run the encryption - * function itself. This function is not AES-specific. - */ -static int -padlock_aes_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out_arg, - const unsigned char *in_arg, size_t nbytes) -{ - struct padlock_cipher_data *cdata; - const void *inp; - unsigned char *out; - void *iv; - int inp_misaligned, out_misaligned, realign_in_loop; - size_t chunk, allocated = 0; - - /* - * ctx->num is maintained in byte-oriented modes, such as CFB and OFB... - */ - if ((chunk = ctx->num)) { /* borrow chunk variable */ - unsigned char *ivp = ctx->iv; - - switch (EVP_CIPHER_CTX_mode(ctx)) { - case EVP_CIPH_CFB_MODE: - if (chunk >= AES_BLOCK_SIZE) - return 0; /* bogus value */ - - if (ctx->encrypt) - while (chunk < AES_BLOCK_SIZE && nbytes != 0) { - ivp[chunk] = *(out_arg++) = *(in_arg++) ^ ivp[chunk]; - chunk++, nbytes--; - } else - while (chunk < AES_BLOCK_SIZE && nbytes != 0) { - unsigned char c = *(in_arg++); - *(out_arg++) = c ^ ivp[chunk]; - ivp[chunk++] = c, nbytes--; - } - - ctx->num = chunk % AES_BLOCK_SIZE; - break; - case EVP_CIPH_OFB_MODE: - if (chunk >= AES_BLOCK_SIZE) - return 0; /* bogus value */ - - while (chunk < AES_BLOCK_SIZE && nbytes != 0) { - *(out_arg++) = *(in_arg++) ^ ivp[chunk]; - chunk++, nbytes--; - } - - ctx->num = chunk % AES_BLOCK_SIZE; - break; - } - } - - if (nbytes == 0) - return 1; -# if 0 - if (nbytes % AES_BLOCK_SIZE) - return 0; /* are we expected to do tail processing? */ -# else - /* - * nbytes is always multiple of AES_BLOCK_SIZE in ECB and CBC modes and - * arbitrary value in byte-oriented modes, such as CFB and OFB... - */ -# endif - - /* - * VIA promises CPUs that won't require alignment in the future. For now - * padlock_aes_align_required is initialized to 1 and the condition is - * never met... - */ - /* - * C7 core is capable to manage unaligned input in non-ECB[!] mode, but - * performance penalties appear to be approximately same as for software - * alignment below or ~3x. They promise to improve it in the future, but - * for now we can just as well pretend that it can only handle aligned - * input... - */ - if (!padlock_aes_align_required && (nbytes % AES_BLOCK_SIZE) == 0) - return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); - - inp_misaligned = (((size_t)in_arg) & 0x0F); - out_misaligned = (((size_t)out_arg) & 0x0F); - - /* - * Note that even if output is aligned and input not, I still prefer to - * loop instead of copy the whole input and then encrypt in one stroke. - * This is done in order to improve L1 cache utilization... - */ - realign_in_loop = out_misaligned | inp_misaligned; - - if (!realign_in_loop && (nbytes % AES_BLOCK_SIZE) == 0) - return padlock_aes_cipher_omnivorous(ctx, out_arg, in_arg, nbytes); - - /* this takes one "if" out of the loops */ - chunk = nbytes; - chunk %= PADLOCK_CHUNK; - if (chunk == 0) - chunk = PADLOCK_CHUNK; - - if (out_misaligned) { - /* optmize for small input */ - allocated = (chunk < nbytes ? PADLOCK_CHUNK : nbytes); - out = alloca(0x10 + allocated); - out = NEAREST_ALIGNED(out); - } else - out = out_arg; - - cdata = ALIGNED_CIPHER_DATA(ctx); - padlock_verify_context(cdata); - - switch (EVP_CIPHER_CTX_mode(ctx)) { - case EVP_CIPH_ECB_MODE: - do { - if (inp_misaligned) - inp = padlock_memcpy(out, in_arg, chunk); - else - inp = in_arg; - in_arg += chunk; - - padlock_xcrypt_ecb(chunk / AES_BLOCK_SIZE, cdata, out, inp); - - if (out_misaligned) - out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; - else - out = out_arg += chunk; - - nbytes -= chunk; - chunk = PADLOCK_CHUNK; - } while (nbytes); - break; - - case EVP_CIPH_CBC_MODE: - memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); - goto cbc_shortcut; - do { - if (iv != cdata->iv) - memcpy(cdata->iv, iv, AES_BLOCK_SIZE); - chunk = PADLOCK_CHUNK; - cbc_shortcut: /* optimize for small input */ - if (inp_misaligned) - inp = padlock_memcpy(out, in_arg, chunk); - else - inp = in_arg; - in_arg += chunk; - - iv = padlock_xcrypt_cbc(chunk / AES_BLOCK_SIZE, cdata, out, inp); - - if (out_misaligned) - out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; - else - out = out_arg += chunk; - - } while (nbytes -= chunk); - memcpy(ctx->iv, iv, AES_BLOCK_SIZE); - break; - - case EVP_CIPH_CFB_MODE: - memcpy(iv = cdata->iv, ctx->iv, AES_BLOCK_SIZE); - chunk &= ~(AES_BLOCK_SIZE - 1); - if (chunk) - goto cfb_shortcut; - else - goto cfb_skiploop; - do { - if (iv != cdata->iv) - memcpy(cdata->iv, iv, AES_BLOCK_SIZE); - chunk = PADLOCK_CHUNK; - cfb_shortcut: /* optimize for small input */ - if (inp_misaligned) - inp = padlock_memcpy(out, in_arg, chunk); - else - inp = in_arg; - in_arg += chunk; - - iv = padlock_xcrypt_cfb(chunk / AES_BLOCK_SIZE, cdata, out, inp); - - if (out_misaligned) - out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; - else - out = out_arg += chunk; - - nbytes -= chunk; - } while (nbytes >= AES_BLOCK_SIZE); - - cfb_skiploop: - if (nbytes) { - unsigned char *ivp = cdata->iv; - - if (iv != ivp) { - memcpy(ivp, iv, AES_BLOCK_SIZE); - iv = ivp; - } - ctx->num = nbytes; - if (cdata->cword.b.encdec) { - cdata->cword.b.encdec = 0; - padlock_reload_key(); - padlock_xcrypt_ecb(1, cdata, ivp, ivp); - cdata->cword.b.encdec = 1; - padlock_reload_key(); - while (nbytes) { - unsigned char c = *(in_arg++); - *(out_arg++) = c ^ *ivp; - *(ivp++) = c, nbytes--; - } - } else { - padlock_reload_key(); - padlock_xcrypt_ecb(1, cdata, ivp, ivp); - padlock_reload_key(); - while (nbytes) { - *ivp = *(out_arg++) = *(in_arg++) ^ *ivp; - ivp++, nbytes--; - } - } - } - - memcpy(ctx->iv, iv, AES_BLOCK_SIZE); - break; - - case EVP_CIPH_OFB_MODE: - memcpy(cdata->iv, ctx->iv, AES_BLOCK_SIZE); - chunk &= ~(AES_BLOCK_SIZE - 1); - if (chunk) - do { - if (inp_misaligned) - inp = padlock_memcpy(out, in_arg, chunk); - else - inp = in_arg; - in_arg += chunk; - - padlock_xcrypt_ofb(chunk / AES_BLOCK_SIZE, cdata, out, inp); - - if (out_misaligned) - out_arg = padlock_memcpy(out_arg, out, chunk) + chunk; - else - out = out_arg += chunk; - - nbytes -= chunk; - chunk = PADLOCK_CHUNK; - } while (nbytes >= AES_BLOCK_SIZE); - - if (nbytes) { - unsigned char *ivp = cdata->iv; - - ctx->num = nbytes; - padlock_reload_key(); /* empirically found */ - padlock_xcrypt_ecb(1, cdata, ivp, ivp); - padlock_reload_key(); /* empirically found */ - while (nbytes) { - *(out_arg++) = *(in_arg++) ^ *ivp; - ivp++, nbytes--; - } - } - - memcpy(ctx->iv, cdata->iv, AES_BLOCK_SIZE); - break; - - default: - return 0; - } - - /* Clean the realign buffer if it was used */ - if (out_misaligned) { - volatile unsigned long *p = (void *)out; - size_t n = allocated / sizeof(*p); - while (n--) - *p++ = 0; - } - - memset(cdata->iv, 0, AES_BLOCK_SIZE); - - return 1; -} - -# endif /* OPENSSL_NO_AES */ - -/* ===== Random Number Generator ===== */ -/* - * This code is not engaged. The reason is that it does not comply - * with recommendations for VIA RNG usage for secure applications - * (posted at http://www.via.com.tw/en/viac3/c3.jsp) nor does it - * provide meaningful error control... - */ -/* - * Wrapper that provides an interface between the API and the raw PadLock - * RNG - */ -static int padlock_rand_bytes(unsigned char *output, int count) -{ - unsigned int eax, buf; - - while (count >= 8) { - eax = padlock_xstore(output, 0); - if (!(eax & (1 << 6))) - return 0; /* RNG disabled */ - /* this ---vv--- covers DC bias, Raw Bits and String Filter */ - if (eax & (0x1F << 10)) - return 0; - if ((eax & 0x1F) == 0) - continue; /* no data, retry... */ - if ((eax & 0x1F) != 8) - return 0; /* fatal failure... */ - output += 8; - count -= 8; - } - while (count > 0) { - eax = padlock_xstore(&buf, 3); - if (!(eax & (1 << 6))) - return 0; /* RNG disabled */ - /* this ---vv--- covers DC bias, Raw Bits and String Filter */ - if (eax & (0x1F << 10)) - return 0; - if ((eax & 0x1F) == 0) - continue; /* no data, retry... */ - if ((eax & 0x1F) != 1) - return 0; /* fatal failure... */ - *output++ = (unsigned char)buf; - count--; - } - *(volatile unsigned int *)&buf = 0; - - return 1; -} - -/* Dummy but necessary function */ -static int padlock_rand_status(void) -{ - return 1; -} - -/* Prepare structure for registration */ -static RAND_METHOD padlock_rand = { - NULL, /* seed */ - padlock_rand_bytes, /* bytes */ - NULL, /* cleanup */ - NULL, /* add */ - padlock_rand_bytes, /* pseudorand */ - padlock_rand_status, /* rand status */ -}; - -# else /* !COMPILE_HW_PADLOCK */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -OPENSSL_EXPORT - int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); -OPENSSL_EXPORT - int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) -{ - return 0; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() -# endif -# endif /* COMPILE_HW_PADLOCK */ -# endif /* !OPENSSL_NO_HW_PADLOCK */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_rc2.c b/Sources/COpenSSL/e_rc2.c deleted file mode 100644 index 9e033597..00000000 --- a/Sources/COpenSSL/e_rc2.c +++ /dev/null @@ -1,235 +0,0 @@ -/* crypto/evp/e_rc2.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_RC2 - -# include "evp.h" -# include "objects.h" -# include "evp_locl.h" -# include "rc2.h" - -static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); -static int rc2_magic_to_meth(int i); -static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); -static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); -static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); - -typedef struct { - int key_bits; /* effective key bits */ - RC2_KEY ks; /* key schedule */ -} EVP_RC2_KEY; - -# define data(ctx) ((EVP_RC2_KEY *)(ctx)->cipher_data) - -IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2, - 8, - RC2_KEY_LENGTH, 8, 64, - EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, - rc2_init_key, NULL, - rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, - rc2_ctrl) -# define RC2_40_MAGIC 0xa0 -# define RC2_64_MAGIC 0x78 -# define RC2_128_MAGIC 0x3a -static const EVP_CIPHER r2_64_cbc_cipher = { - NID_rc2_64_cbc, - 8, 8 /* 64 bit */ , 8, - EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, - rc2_init_key, - rc2_cbc_cipher, - NULL, - sizeof(EVP_RC2_KEY), - rc2_set_asn1_type_and_iv, - rc2_get_asn1_type_and_iv, - rc2_ctrl, - NULL -}; - -static const EVP_CIPHER r2_40_cbc_cipher = { - NID_rc2_40_cbc, - 8, 5 /* 40 bit */ , 8, - EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, - rc2_init_key, - rc2_cbc_cipher, - NULL, - sizeof(EVP_RC2_KEY), - rc2_set_asn1_type_and_iv, - rc2_get_asn1_type_and_iv, - rc2_ctrl, - NULL -}; - -const EVP_CIPHER *EVP_rc2_64_cbc(void) -{ - return (&r2_64_cbc_cipher); -} - -const EVP_CIPHER *EVP_rc2_40_cbc(void) -{ - return (&r2_40_cbc_cipher); -} - -static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), - key, data(ctx)->key_bits); - return 1; -} - -static int rc2_meth_to_magic(EVP_CIPHER_CTX *e) -{ - int i; - - EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i); - if (i == 128) - return (RC2_128_MAGIC); - else if (i == 64) - return (RC2_64_MAGIC); - else if (i == 40) - return (RC2_40_MAGIC); - else - return (0); -} - -static int rc2_magic_to_meth(int i) -{ - if (i == RC2_128_MAGIC) - return 128; - else if (i == RC2_64_MAGIC) - return 64; - else if (i == RC2_40_MAGIC) - return 40; - else { - EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE); - return (0); - } -} - -static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - long num = 0; - int i = 0; - int key_bits; - unsigned int l; - unsigned char iv[EVP_MAX_IV_LENGTH]; - - if (type != NULL) { - l = EVP_CIPHER_CTX_iv_length(c); - OPENSSL_assert(l <= sizeof(iv)); - i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l); - if (i != (int)l) - return (-1); - key_bits = rc2_magic_to_meth((int)num); - if (!key_bits) - return (-1); - if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) - return -1; - EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); - EVP_CIPHER_CTX_set_key_length(c, key_bits / 8); - } - return (i); -} - -static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - long num; - int i = 0, j; - - if (type != NULL) { - num = rc2_meth_to_magic(c); - j = EVP_CIPHER_CTX_iv_length(c); - i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); - } - return (i); -} - -static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) -{ - switch (type) { - case EVP_CTRL_INIT: - data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8; - return 1; - - case EVP_CTRL_GET_RC2_KEY_BITS: - *(int *)ptr = data(c)->key_bits; - return 1; - - case EVP_CTRL_SET_RC2_KEY_BITS: - if (arg > 0) { - data(c)->key_bits = arg; - return 1; - } - return 0; -# ifdef PBE_PRF_TEST - case EVP_CTRL_PBE_PRF_NID: - *(int *)ptr = NID_hmacWithMD5; - return 1; -# endif - - default: - return -1; - } -} - -#endif diff --git a/Sources/COpenSSL/e_rc4.c b/Sources/COpenSSL/e_rc4.c deleted file mode 100644 index dee323d2..00000000 --- a/Sources/COpenSSL/e_rc4.c +++ /dev/null @@ -1,133 +0,0 @@ -/* crypto/evp/e_rc4.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_RC4 - -# include "evp.h" -# include "evp_locl.h" -# include "objects.h" -# include "rc4.h" - -/* FIXME: surely this is available elsewhere? */ -# define EVP_RC4_KEY_SIZE 16 - -typedef struct { - RC4_KEY ks; /* working key */ -} EVP_RC4_KEY; - -# define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data) - -static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -static const EVP_CIPHER r4_cipher = { - NID_rc4, - 1, EVP_RC4_KEY_SIZE, 0, - EVP_CIPH_VARIABLE_LENGTH, - rc4_init_key, - rc4_cipher, - NULL, - sizeof(EVP_RC4_KEY), - NULL, - NULL, - NULL, - NULL -}; - -static const EVP_CIPHER r4_40_cipher = { - NID_rc4_40, - 1, 5 /* 40 bit */ , 0, - EVP_CIPH_VARIABLE_LENGTH, - rc4_init_key, - rc4_cipher, - NULL, - sizeof(EVP_RC4_KEY), - NULL, - NULL, - NULL, - NULL -}; - -const EVP_CIPHER *EVP_rc4(void) -{ - return (&r4_cipher); -} - -const EVP_CIPHER *EVP_rc4_40(void) -{ - return (&r4_40_cipher); -} - -static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); - return 1; -} - -static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - RC4(&data(ctx)->ks, inl, in, out); - return 1; -} -#endif diff --git a/Sources/COpenSSL/e_rc4_hmac_md5.c b/Sources/COpenSSL/e_rc4_hmac_md5.c deleted file mode 100644 index d517c122..00000000 --- a/Sources/COpenSSL/e_rc4_hmac_md5.c +++ /dev/null @@ -1,312 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "opensslconf.h" - -#include -#include - -#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5) - -# include "crypto.h" -# include "evp.h" -# include "objects.h" -# include "rc4.h" -# include "md5.h" - -# ifndef EVP_CIPH_FLAG_AEAD_CIPHER -# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 -# define EVP_CTRL_AEAD_TLS1_AAD 0x16 -# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 -# endif - -/* FIXME: surely this is available elsewhere? */ -# define EVP_RC4_KEY_SIZE 16 - -typedef struct { - RC4_KEY ks; - MD5_CTX head, tail, md; - size_t payload_length; -} EVP_RC4_HMAC_MD5; - -# define NO_PAYLOAD_LENGTH ((size_t)-1) - -void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out, - MD5_CTX *ctx, const void *inp, size_t blocks); - -# define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data) - -static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *inkey, - const unsigned char *iv, int enc) -{ - EVP_RC4_HMAC_MD5 *key = data(ctx); - - RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey); - - MD5_Init(&key->head); /* handy when benchmarking */ - key->tail = key->head; - key->md = key->head; - - key->payload_length = NO_PAYLOAD_LENGTH; - - return 1; -} - -# if defined(RC4_ASM) && defined(MD5_ASM) && ( \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) || \ - defined(__INTEL__) ) && \ - !(defined(__APPLE__) && defined(__MACH__)) -# define STITCHED_CALL -# endif - -# if !defined(STITCHED_CALL) -# define rc4_off 0 -# define md5_off 0 -# endif - -static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_RC4_HMAC_MD5 *key = data(ctx); -# if defined(STITCHED_CALL) - size_t rc4_off = 32 - 1 - (key->ks.x & (32 - 1)), /* 32 is $MOD from - * rc4_md5-x86_64.pl */ - md5_off = MD5_CBLOCK - key->md.num, blocks; - unsigned int l; - extern unsigned int OPENSSL_ia32cap_P[]; -# endif - size_t plen = key->payload_length; - - if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH)) - return 0; - - if (ctx->encrypt) { - if (plen == NO_PAYLOAD_LENGTH) - plen = len; -# if defined(STITCHED_CALL) - /* cipher has to "fall behind" */ - if (rc4_off > md5_off) - md5_off += MD5_CBLOCK; - - if (plen > md5_off && (blocks = (plen - md5_off) / MD5_CBLOCK) && - (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) { - MD5_Update(&key->md, in, md5_off); - RC4(&key->ks, rc4_off, in, out); - - rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off, - &key->md, in + md5_off, blocks); - blocks *= MD5_CBLOCK; - rc4_off += blocks; - md5_off += blocks; - key->md.Nh += blocks >> 29; - key->md.Nl += blocks <<= 3; - if (key->md.Nl < (unsigned int)blocks) - key->md.Nh++; - } else { - rc4_off = 0; - md5_off = 0; - } -# endif - MD5_Update(&key->md, in + md5_off, plen - md5_off); - - if (plen != len) { /* "TLS" mode of operation */ - if (in != out) - memcpy(out + rc4_off, in + rc4_off, plen - rc4_off); - - /* calculate HMAC and append it to payload */ - MD5_Final(out + plen, &key->md); - key->md = key->tail; - MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH); - MD5_Final(out + plen, &key->md); - /* encrypt HMAC at once */ - RC4(&key->ks, len - rc4_off, out + rc4_off, out + rc4_off); - } else { - RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off); - } - } else { - unsigned char mac[MD5_DIGEST_LENGTH]; -# if defined(STITCHED_CALL) - /* digest has to "fall behind" */ - if (md5_off > rc4_off) - rc4_off += 2 * MD5_CBLOCK; - else - rc4_off += MD5_CBLOCK; - - if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) && - (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) { - RC4(&key->ks, rc4_off, in, out); - MD5_Update(&key->md, out, md5_off); - - rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off, - &key->md, out + md5_off, blocks); - blocks *= MD5_CBLOCK; - rc4_off += blocks; - md5_off += blocks; - l = (key->md.Nl + (blocks << 3)) & 0xffffffffU; - if (l < key->md.Nl) - key->md.Nh++; - key->md.Nl = l; - key->md.Nh += blocks >> 29; - } else { - md5_off = 0; - rc4_off = 0; - } -# endif - /* decrypt HMAC at once */ - RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off); - if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ - MD5_Update(&key->md, out + md5_off, plen - md5_off); - - /* calculate HMAC and verify it */ - MD5_Final(mac, &key->md); - key->md = key->tail; - MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH); - MD5_Final(mac, &key->md); - - if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH)) - return 0; - } else { - MD5_Update(&key->md, out + md5_off, len - md5_off); - } - } - - key->payload_length = NO_PAYLOAD_LENGTH; - - return 1; -} - -static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr) -{ - EVP_RC4_HMAC_MD5 *key = data(ctx); - - switch (type) { - case EVP_CTRL_AEAD_SET_MAC_KEY: - { - unsigned int i; - unsigned char hmac_key[64]; - - memset(hmac_key, 0, sizeof(hmac_key)); - - if (arg > (int)sizeof(hmac_key)) { - MD5_Init(&key->head); - MD5_Update(&key->head, ptr, arg); - MD5_Final(hmac_key, &key->head); - } else { - memcpy(hmac_key, ptr, arg); - } - - for (i = 0; i < sizeof(hmac_key); i++) - hmac_key[i] ^= 0x36; /* ipad */ - MD5_Init(&key->head); - MD5_Update(&key->head, hmac_key, sizeof(hmac_key)); - - for (i = 0; i < sizeof(hmac_key); i++) - hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ - MD5_Init(&key->tail); - MD5_Update(&key->tail, hmac_key, sizeof(hmac_key)); - - OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); - - return 1; - } - case EVP_CTRL_AEAD_TLS1_AAD: - { - unsigned char *p = ptr; - unsigned int len; - - if (arg != EVP_AEAD_TLS1_AAD_LEN) - return -1; - - len = p[arg - 2] << 8 | p[arg - 1]; - - if (!ctx->encrypt) { - if (len < MD5_DIGEST_LENGTH) - return -1; - len -= MD5_DIGEST_LENGTH; - p[arg - 2] = len >> 8; - p[arg - 1] = len; - } - key->payload_length = len; - key->md = key->head; - MD5_Update(&key->md, p, arg); - - return MD5_DIGEST_LENGTH; - } - default: - return -1; - } -} - -static EVP_CIPHER r4_hmac_md5_cipher = { -# ifdef NID_rc4_hmac_md5 - NID_rc4_hmac_md5, -# else - NID_undef, -# endif - 1, EVP_RC4_KEY_SIZE, 0, - EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH | - EVP_CIPH_FLAG_AEAD_CIPHER, - rc4_hmac_md5_init_key, - rc4_hmac_md5_cipher, - NULL, - sizeof(EVP_RC4_HMAC_MD5), - NULL, - NULL, - rc4_hmac_md5_ctrl, - NULL -}; - -const EVP_CIPHER *EVP_rc4_hmac_md5(void) -{ - return (&r4_hmac_md5_cipher); -} -#endif diff --git a/Sources/COpenSSL/e_rc5.c b/Sources/COpenSSL/e_rc5.c deleted file mode 100644 index c108774d..00000000 --- a/Sources/COpenSSL/e_rc5.c +++ /dev/null @@ -1,122 +0,0 @@ -/* crypto/evp/e_rc5.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_RC5 - -# include "evp.h" -# include "objects.h" -# include "evp_locl.h" -# include - -static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); - -typedef struct { - int rounds; /* number of rounds */ - RC5_32_KEY ks; /* key schedule */ -} EVP_RC5_KEY; - -# define data(ctx) EVP_C_DATA(EVP_RC5_KEY,ctx) - -IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5, - 8, RC5_32_KEY_LENGTH, 8, 64, - EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, - r_32_12_16_init_key, NULL, NULL, NULL, rc5_ctrl) - -static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) -{ - switch (type) { - case EVP_CTRL_INIT: - data(c)->rounds = RC5_12_ROUNDS; - return 1; - - case EVP_CTRL_GET_RC5_ROUNDS: - *(int *)ptr = data(c)->rounds; - return 1; - - case EVP_CTRL_SET_RC5_ROUNDS: - switch (arg) { - case RC5_8_ROUNDS: - case RC5_12_ROUNDS: - case RC5_16_ROUNDS: - data(c)->rounds = arg; - return 1; - - default: - EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS); - return 0; - } - - default: - return -1; - } -} - -static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), - key, data(ctx)->rounds); - return 1; -} - -#endif diff --git a/Sources/COpenSSL/e_seed.c b/Sources/COpenSSL/e_seed.c deleted file mode 100644 index 74867e45..00000000 --- a/Sources/COpenSSL/e_seed.c +++ /dev/null @@ -1,83 +0,0 @@ -/* crypto/evp/e_seed.c */ -/* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "opensslconf.h" -#ifndef OPENSSL_NO_SEED -# include "evp.h" -# include "err.h" -# include -# include -# include "seed.h" -# include "evp_locl.h" - -static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - -typedef struct { - SEED_KEY_SCHEDULE ks; -} EVP_SEED_KEY; - -IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed, - 16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1, - seed_init_key, 0, 0, 0, 0) - -static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - SEED_set_key(key, ctx->cipher_data); - return 1; -} - -#endif diff --git a/Sources/COpenSSL/e_sureware.c b/Sources/COpenSSL/e_sureware.c deleted file mode 100644 index d1bd6709..00000000 --- a/Sources/COpenSSL/e_sureware.c +++ /dev/null @@ -1,1102 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/*- -* Written by Corinne Dive-Reclus(cdive@baltimore.com) -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided with the -* distribution. -* -* 3. All advertising materials mentioning features or use of this -* software must display the following acknowledgment: -* "This product includes software developed by the OpenSSL Project -* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" -* -* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to -* endorse or promote products derived from this software without -* prior written permission. For written permission, please contact -* licensing@OpenSSL.org. -* -* 5. Products derived from this software may not be called "OpenSSL" -* nor may "OpenSSL" appear in their names without prior written -* permission of the OpenSSL Project. -* -* 6. Redistributions of any form whatsoever must retain the following -* acknowledgment: -* "This product includes software developed by the OpenSSL Project -* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" -* -* Written by Corinne Dive-Reclus(cdive@baltimore.com) -* -* Copyright@2001 Baltimore Technologies Ltd. -* All right Reserved. -* * -* THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND * -* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * -* ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE * -* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * -* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * -* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * -* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * -* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * -* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * -* SUCH DAMAGE. * -====================================================================*/ - -#include -#include -#include "crypto.h" -#include "pem.h" -#include "dso.h" -#include "engine.h" -#include "rand.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#include "bn.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_SUREWARE - -# ifdef FLAT_INC -# include "sureware.h" -# else -# include "sureware.h" -# endif - -# define SUREWARE_LIB_NAME "sureware engine" -# include "e_sureware_err.c" - -static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, - void (*f) (void)); -static int surewarehk_destroy(ENGINE *e); -static int surewarehk_init(ENGINE *e); -static int surewarehk_finish(ENGINE *e); -static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); - -/* RSA stuff */ -# ifndef OPENSSL_NO_RSA -static int surewarehk_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int surewarehk_rsa_sign(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -# endif - -/* RAND stuff */ -static int surewarehk_rand_bytes(unsigned char *buf, int num); -static void surewarehk_rand_seed(const void *buf, int num); -static void surewarehk_rand_add(const void *buf, int num, double entropy); - -/* KM stuff */ -static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, - void *callback_data); -static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, - void *callback_data); -static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp); -# if 0 -static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp); -# endif - -# ifndef OPENSSL_NO_RSA -/* This function is aliased to mod_exp (with the mont stuff dropped). */ -static int surewarehk_mod_exp_mont(BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return surewarehk_modexp(r, a, p, m, ctx); -} - -/* Our internal RSA_METHOD that we provide pointers to */ -static RSA_METHOD surewarehk_rsa = { - "SureWare RSA method", - NULL, /* pub_enc */ - NULL, /* pub_dec */ - surewarehk_rsa_sign, /* our rsa_sign is OpenSSL priv_enc */ - surewarehk_rsa_priv_dec, /* priv_dec */ - NULL, /* mod_exp */ - surewarehk_mod_exp_mont, /* mod_exp_mongomery */ - NULL, /* init */ - NULL, /* finish */ - 0, /* RSA flag */ - NULL, - NULL, /* OpenSSL sign */ - NULL, /* OpenSSL verify */ - NULL /* keygen */ -}; -# endif - -# ifndef OPENSSL_NO_DH -/* Our internal DH_METHOD that we provide pointers to */ -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int surewarehk_modexp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return surewarehk_modexp(r, a, p, m, ctx); -} - -static DH_METHOD surewarehk_dh = { - "SureWare DH method", - NULL, /* gen_key */ - NULL, /* agree, */ - surewarehk_modexp_dh, /* dh mod exp */ - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, - NULL -}; -# endif - -static RAND_METHOD surewarehk_rand = { - /* "SureWare RAND method", */ - surewarehk_rand_seed, - surewarehk_rand_bytes, - NULL, /* cleanup */ - surewarehk_rand_add, - surewarehk_rand_bytes, - NULL, /* rand_status */ -}; - -# ifndef OPENSSL_NO_DSA -/* DSA stuff */ -static DSA_SIG *surewarehk_dsa_do_sign(const unsigned char *dgst, int dlen, - DSA *dsa); -static int surewarehk_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, - BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, - BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *in_mont) -{ - BIGNUM t; - int to_return = 0; - BN_init(&t); - /* let rr = a1 ^ p1 mod m */ - if (!surewarehk_modexp(rr, a1, p1, m, ctx)) - goto end; - /* let t = a2 ^ p2 mod m */ - if (!surewarehk_modexp(&t, a2, p2, m, ctx)) - goto end; - /* let rr = rr * t mod m */ - if (!BN_mod_mul(rr, rr, &t, m, ctx)) - goto end; - to_return = 1; - end: - BN_free(&t); - return to_return; -} - -static DSA_METHOD surewarehk_dsa = { - "SureWare DSA method", - surewarehk_dsa_do_sign, - NULL, /* sign setup */ - NULL, /* verify, */ - surewarehk_dsa_mod_exp, /* mod exp */ - NULL, /* bn mod exp */ - NULL, /* init */ - NULL, /* finish */ - 0, - NULL, - NULL, - NULL -}; -# endif - -static const char *engine_sureware_id = "sureware"; -static const char *engine_sureware_name = "SureWare hardware engine support"; - -/* Now, to our own code */ - -/* - * As this is only ever called once, there's no need for locking (indeed - - * the lock will already be held by our caller!!!) - */ -static int bind_sureware(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif -# ifndef OPENSSL_NO_DSA - const DSA_METHOD *meth2; -# endif -# ifndef OPENSSL_NO_DH - const DH_METHOD *meth3; -# endif - - if (!ENGINE_set_id(e, engine_sureware_id) || - !ENGINE_set_name(e, engine_sureware_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &surewarehk_rsa) || -# endif -# ifndef OPENSSL_NO_DSA - !ENGINE_set_DSA(e, &surewarehk_dsa) || -# endif -# ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &surewarehk_dh) || -# endif - !ENGINE_set_RAND(e, &surewarehk_rand) || - !ENGINE_set_destroy_function(e, surewarehk_destroy) || - !ENGINE_set_init_function(e, surewarehk_init) || - !ENGINE_set_finish_function(e, surewarehk_finish) || - !ENGINE_set_ctrl_function(e, surewarehk_ctrl) || - !ENGINE_set_load_privkey_function(e, surewarehk_load_privkey) || - !ENGINE_set_load_pubkey_function(e, surewarehk_load_pubkey)) - return 0; - -# ifndef OPENSSL_NO_RSA - /* - * We know that the "PKCS1_SSLeay()" functions hook properly to the - * cswift-specific mod_exp and mod_exp_crt so we use those functions. NB: - * We don't use ENGINE_openssl() or anything "more generic" because - * something like the RSAref code may not hook properly, and if you own - * one of these cards then you have the right to do RSA operations on it - * anyway! - */ - meth1 = RSA_PKCS1_SSLeay(); - if (meth1) { - surewarehk_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - surewarehk_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - } -# endif - -# ifndef OPENSSL_NO_DSA - /* - * Use the DSA_OpenSSL() method and just hook the mod_exp-ish bits. - */ - meth2 = DSA_OpenSSL(); - if (meth2) { - surewarehk_dsa.dsa_do_verify = meth2->dsa_do_verify; - } -# endif - -# ifndef OPENSSL_NO_DH - /* Much the same for Diffie-Hellman */ - meth3 = DH_OpenSSL(); - if (meth3) { - surewarehk_dh.generate_key = meth3->generate_key; - surewarehk_dh.compute_key = meth3->compute_key; - } -# endif - - /* Ensure the sureware error handling is set up */ - ERR_load_SUREWARE_strings(); - return 1; -} - -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_helper(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_sureware_id) != 0)) - return 0; - if (!bind_sureware(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) -# else -static ENGINE *engine_sureware(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_sureware(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_sureware(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_sureware(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -/* - * This is a process-global DSO handle used for loading and unloading the - * SureWareHook library. NB: This is only set (or unset) during an init() or - * finish() call (reference counts permitting) and they're operating with - * global locks, so this should be thread-safe implicitly. - */ -static DSO *surewarehk_dso = NULL; -# ifndef OPENSSL_NO_RSA -/* Index for KM handle. Not really used yet. */ -static int rsaHndidx = -1; -# endif -# ifndef OPENSSL_NO_DSA -/* Index for KM handle. Not really used yet. */ -static int dsaHndidx = -1; -# endif - -/* - * These are the function pointers that are (un)set when the library has - * successfully (un)loaded. - */ -static SureWareHook_Init_t *p_surewarehk_Init = NULL; -static SureWareHook_Finish_t *p_surewarehk_Finish = NULL; -static SureWareHook_Rand_Bytes_t *p_surewarehk_Rand_Bytes = NULL; -static SureWareHook_Rand_Seed_t *p_surewarehk_Rand_Seed = NULL; -static SureWareHook_Load_Privkey_t *p_surewarehk_Load_Privkey = NULL; -static SureWareHook_Info_Pubkey_t *p_surewarehk_Info_Pubkey = NULL; -static SureWareHook_Load_Rsa_Pubkey_t *p_surewarehk_Load_Rsa_Pubkey = NULL; -static SureWareHook_Load_Dsa_Pubkey_t *p_surewarehk_Load_Dsa_Pubkey = NULL; -static SureWareHook_Free_t *p_surewarehk_Free = NULL; -static SureWareHook_Rsa_Priv_Dec_t *p_surewarehk_Rsa_Priv_Dec = NULL; -static SureWareHook_Rsa_Sign_t *p_surewarehk_Rsa_Sign = NULL; -static SureWareHook_Dsa_Sign_t *p_surewarehk_Dsa_Sign = NULL; -static SureWareHook_Mod_Exp_t *p_surewarehk_Mod_Exp = NULL; - -/* Used in the DSO operations. */ -static const char *surewarehk_LIBNAME = "SureWareHook"; -static const char *n_surewarehk_Init = "SureWareHook_Init"; -static const char *n_surewarehk_Finish = "SureWareHook_Finish"; -static const char *n_surewarehk_Rand_Bytes = "SureWareHook_Rand_Bytes"; -static const char *n_surewarehk_Rand_Seed = "SureWareHook_Rand_Seed"; -static const char *n_surewarehk_Load_Privkey = "SureWareHook_Load_Privkey"; -static const char *n_surewarehk_Info_Pubkey = "SureWareHook_Info_Pubkey"; -static const char *n_surewarehk_Load_Rsa_Pubkey = - "SureWareHook_Load_Rsa_Pubkey"; -static const char *n_surewarehk_Load_Dsa_Pubkey = - "SureWareHook_Load_Dsa_Pubkey"; -static const char *n_surewarehk_Free = "SureWareHook_Free"; -static const char *n_surewarehk_Rsa_Priv_Dec = "SureWareHook_Rsa_Priv_Dec"; -static const char *n_surewarehk_Rsa_Sign = "SureWareHook_Rsa_Sign"; -static const char *n_surewarehk_Dsa_Sign = "SureWareHook_Dsa_Sign"; -static const char *n_surewarehk_Mod_Exp = "SureWareHook_Mod_Exp"; -static BIO *logstream = NULL; - -/* - * SureWareHook library functions and mechanics - these are used by the - * higher-level functions further down. NB: As and where there's no error - * checking, take a look lower down where these functions are called, the - * checking and error handling is probably down there. - */ -static int threadsafe = 1; -static int surewarehk_ctrl(ENGINE *e, int cmd, long i, void *p, - void (*f) (void)) -{ - int to_return = 1; - - switch (cmd) { - case ENGINE_CTRL_SET_LOGSTREAM: - { - BIO *bio = (BIO *)p; - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (logstream) { - BIO_free(logstream); - logstream = NULL; - } - if (CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO) > 1) - logstream = bio; - else - SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL, - SUREWARE_R_BIO_WAS_FREED); - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - /* - * This will prevent the initialisation function from "installing" - * the mutex-handling callbacks, even if they are available from - * within the library (or were provided to the library from the - * calling application). This is to remove any baggage for - * applications not using multithreading. - */ - case ENGINE_CTRL_CHIL_NO_LOCKING: - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - threadsafe = 0; - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - break; - - /* The command isn't understood by this engine */ - default: - SUREWAREerr(SUREWARE_F_SUREWAREHK_CTRL, - ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); - to_return = 0; - break; - } - - return to_return; -} - -/* Destructor (complements the "ENGINE_surewarehk()" constructor) */ -static int surewarehk_destroy(ENGINE *e) -{ - ERR_unload_SUREWARE_strings(); - return 1; -} - -/* (de)initialisation functions. */ -static int surewarehk_init(ENGINE *e) -{ - char msg[64] = "ENGINE_init"; - SureWareHook_Init_t *p1 = NULL; - SureWareHook_Finish_t *p2 = NULL; - SureWareHook_Rand_Bytes_t *p3 = NULL; - SureWareHook_Rand_Seed_t *p4 = NULL; - SureWareHook_Load_Privkey_t *p5 = NULL; - SureWareHook_Load_Rsa_Pubkey_t *p6 = NULL; - SureWareHook_Free_t *p7 = NULL; - SureWareHook_Rsa_Priv_Dec_t *p8 = NULL; - SureWareHook_Rsa_Sign_t *p9 = NULL; - SureWareHook_Dsa_Sign_t *p12 = NULL; - SureWareHook_Info_Pubkey_t *p13 = NULL; - SureWareHook_Load_Dsa_Pubkey_t *p14 = NULL; - SureWareHook_Mod_Exp_t *p15 = NULL; - - if (surewarehk_dso != NULL) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_ALREADY_LOADED); - goto err; - } - /* Attempt to load libsurewarehk.so/surewarehk.dll/whatever. */ - surewarehk_dso = DSO_load(NULL, surewarehk_LIBNAME, NULL, 0); - if (surewarehk_dso == NULL) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_DSO_FAILURE); - goto err; - } - if (! - (p1 = - (SureWareHook_Init_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Init)) -|| !(p2 = - (SureWareHook_Finish_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Finish)) -|| !(p3 = - (SureWareHook_Rand_Bytes_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Rand_Bytes)) -|| !(p4 = - (SureWareHook_Rand_Seed_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Rand_Seed)) -|| !(p5 = - (SureWareHook_Load_Privkey_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Load_Privkey)) -|| !(p6 = - (SureWareHook_Load_Rsa_Pubkey_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Load_Rsa_Pubkey)) -|| !(p7 = - (SureWareHook_Free_t *) DSO_bind_func(surewarehk_dso, n_surewarehk_Free)) -|| !(p8 = - (SureWareHook_Rsa_Priv_Dec_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Rsa_Priv_Dec)) -|| !(p9 = - (SureWareHook_Rsa_Sign_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Rsa_Sign)) -|| !(p12 = - (SureWareHook_Dsa_Sign_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Dsa_Sign)) -|| !(p13 = - (SureWareHook_Info_Pubkey_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Info_Pubkey)) -|| !(p14 = - (SureWareHook_Load_Dsa_Pubkey_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Load_Dsa_Pubkey)) -|| !(p15 = - (SureWareHook_Mod_Exp_t *) DSO_bind_func(surewarehk_dso, - n_surewarehk_Mod_Exp))) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, ENGINE_R_DSO_FAILURE); - goto err; - } - /* Copy the pointers */ - p_surewarehk_Init = p1; - p_surewarehk_Finish = p2; - p_surewarehk_Rand_Bytes = p3; - p_surewarehk_Rand_Seed = p4; - p_surewarehk_Load_Privkey = p5; - p_surewarehk_Load_Rsa_Pubkey = p6; - p_surewarehk_Free = p7; - p_surewarehk_Rsa_Priv_Dec = p8; - p_surewarehk_Rsa_Sign = p9; - p_surewarehk_Dsa_Sign = p12; - p_surewarehk_Info_Pubkey = p13; - p_surewarehk_Load_Dsa_Pubkey = p14; - p_surewarehk_Mod_Exp = p15; - /* Contact the hardware and initialises it. */ - if (p_surewarehk_Init(msg, threadsafe) == SUREWAREHOOK_ERROR_UNIT_FAILURE) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, SUREWARE_R_UNIT_FAILURE); - goto err; - } - if (p_surewarehk_Init(msg, threadsafe) == SUREWAREHOOK_ERROR_UNIT_FAILURE) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_INIT, SUREWARE_R_UNIT_FAILURE); - goto err; - } - /* - * try to load the default private key, if failed does not return a - * failure but wait for an explicit ENGINE_load_privakey - */ - surewarehk_load_privkey(e, NULL, NULL, NULL); - - /* Everything's fine. */ -# ifndef OPENSSL_NO_RSA - if (rsaHndidx == -1) - rsaHndidx = RSA_get_ex_new_index(0, - "SureWareHook RSA key handle", - NULL, NULL, surewarehk_ex_free); -# endif -# ifndef OPENSSL_NO_DSA - if (dsaHndidx == -1) - dsaHndidx = DSA_get_ex_new_index(0, - "SureWareHook DSA key handle", - NULL, NULL, surewarehk_ex_free); -# endif - - return 1; - err: - if (surewarehk_dso) - DSO_free(surewarehk_dso); - surewarehk_dso = NULL; - p_surewarehk_Init = NULL; - p_surewarehk_Finish = NULL; - p_surewarehk_Rand_Bytes = NULL; - p_surewarehk_Rand_Seed = NULL; - p_surewarehk_Load_Privkey = NULL; - p_surewarehk_Load_Rsa_Pubkey = NULL; - p_surewarehk_Free = NULL; - p_surewarehk_Rsa_Priv_Dec = NULL; - p_surewarehk_Rsa_Sign = NULL; - p_surewarehk_Dsa_Sign = NULL; - p_surewarehk_Info_Pubkey = NULL; - p_surewarehk_Load_Dsa_Pubkey = NULL; - p_surewarehk_Mod_Exp = NULL; - return 0; -} - -static int surewarehk_finish(ENGINE *e) -{ - int to_return = 1; - if (surewarehk_dso == NULL) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH, ENGINE_R_NOT_LOADED); - to_return = 0; - goto err; - } - p_surewarehk_Finish(); - if (!DSO_free(surewarehk_dso)) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_FINISH, ENGINE_R_DSO_FAILURE); - to_return = 0; - goto err; - } - err: - if (logstream) - BIO_free(logstream); - surewarehk_dso = NULL; - p_surewarehk_Init = NULL; - p_surewarehk_Finish = NULL; - p_surewarehk_Rand_Bytes = NULL; - p_surewarehk_Rand_Seed = NULL; - p_surewarehk_Load_Privkey = NULL; - p_surewarehk_Load_Rsa_Pubkey = NULL; - p_surewarehk_Free = NULL; - p_surewarehk_Rsa_Priv_Dec = NULL; - p_surewarehk_Rsa_Sign = NULL; - p_surewarehk_Dsa_Sign = NULL; - p_surewarehk_Info_Pubkey = NULL; - p_surewarehk_Load_Dsa_Pubkey = NULL; - p_surewarehk_Mod_Exp = NULL; - return to_return; -} - -static void surewarehk_error_handling(char *const msg, int func, int ret) -{ - switch (ret) { - case SUREWAREHOOK_ERROR_UNIT_FAILURE: - ENGINEerr(func, SUREWARE_R_UNIT_FAILURE); - break; - case SUREWAREHOOK_ERROR_FALLBACK: - ENGINEerr(func, SUREWARE_R_REQUEST_FALLBACK); - break; - case SUREWAREHOOK_ERROR_DATA_SIZE: - ENGINEerr(func, SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - break; - case SUREWAREHOOK_ERROR_INVALID_PAD: - ENGINEerr(func, SUREWARE_R_PADDING_CHECK_FAILED); - break; - default: - ENGINEerr(func, SUREWARE_R_REQUEST_FAILED); - break; - case 1: /* nothing */ - msg[0] = '\0'; - } - if (*msg) { - ERR_add_error_data(1, msg); - if (logstream) { - CRYPTO_w_lock(CRYPTO_LOCK_BIO); - BIO_write(logstream, msg, strlen(msg)); - CRYPTO_w_unlock(CRYPTO_LOCK_BIO); - } - } -} - -static int surewarehk_rand_bytes(unsigned char *buf, int num) -{ - int ret = 0; - char msg[64] = "ENGINE_rand_bytes"; - if (!p_surewarehk_Rand_Bytes) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_BYTES, - ENGINE_R_NOT_INITIALISED); - } else { - ret = p_surewarehk_Rand_Bytes(msg, buf, num); - surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RAND_BYTES, ret); - } - return ret == 1 ? 1 : 0; -} - -static void surewarehk_rand_seed(const void *buf, int num) -{ - int ret = 0; - char msg[64] = "ENGINE_rand_seed"; - if (!p_surewarehk_Rand_Seed) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_RAND_SEED, - ENGINE_R_NOT_INITIALISED); - } else { - ret = p_surewarehk_Rand_Seed(msg, buf, num); - surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RAND_SEED, ret); - } -} - -static void surewarehk_rand_add(const void *buf, int num, double entropy) -{ - surewarehk_rand_seed(buf, num); -} - -static EVP_PKEY *sureware_load_public(ENGINE *e, const char *key_id, - char *hptr, unsigned long el, - char keytype) -{ - EVP_PKEY *res = NULL; -# ifndef OPENSSL_NO_RSA - RSA *rsatmp = NULL; -# endif -# ifndef OPENSSL_NO_DSA - DSA *dsatmp = NULL; -# endif - char msg[64] = "sureware_load_public"; - int ret = 0; - if (!p_surewarehk_Load_Rsa_Pubkey || !p_surewarehk_Load_Dsa_Pubkey) { - SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC, - ENGINE_R_NOT_INITIALISED); - goto err; - } - switch (keytype) { -# ifndef OPENSSL_NO_RSA - case 1: - /*RSA*/ - /* set private external reference */ - rsatmp = RSA_new_method(e); - RSA_set_ex_data(rsatmp, rsaHndidx, hptr); - rsatmp->flags |= RSA_FLAG_EXT_PKEY; - - /* set public big nums */ - rsatmp->e = BN_new(); - rsatmp->n = BN_new(); - if(!rsatmp->e || !rsatmp->n) - goto err; - bn_expand2(rsatmp->e, el / sizeof(BN_ULONG)); - bn_expand2(rsatmp->n, el / sizeof(BN_ULONG)); - if (rsatmp->e->dmax != (int)(el / sizeof(BN_ULONG)) || - rsatmp->n->dmax != (int)(el / sizeof(BN_ULONG))) - goto err; - ret = p_surewarehk_Load_Rsa_Pubkey(msg, key_id, el, - (unsigned long *)rsatmp->n->d, - (unsigned long *)rsatmp->e->d); - surewarehk_error_handling(msg, SUREWARE_F_SUREWARE_LOAD_PUBLIC, ret); - if (ret != 1) { - SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC, - ENGINE_R_FAILED_LOADING_PUBLIC_KEY); - goto err; - } - /* normalise pub e and pub n */ - rsatmp->e->top = el / sizeof(BN_ULONG); - bn_fix_top(rsatmp->e); - rsatmp->n->top = el / sizeof(BN_ULONG); - bn_fix_top(rsatmp->n); - /* create an EVP object: engine + rsa key */ - res = EVP_PKEY_new(); - EVP_PKEY_assign_RSA(res, rsatmp); - break; -# endif - -# ifndef OPENSSL_NO_DSA - case 2: - /*DSA*/ - /* set private/public external reference */ - dsatmp = DSA_new_method(e); - DSA_set_ex_data(dsatmp, dsaHndidx, hptr); - /* - * dsatmp->flags |= DSA_FLAG_EXT_PKEY; - */ - - /* set public key */ - dsatmp->pub_key = BN_new(); - dsatmp->p = BN_new(); - dsatmp->q = BN_new(); - dsatmp->g = BN_new(); - if(!dsatmp->pub_key || !dsatmp->p || !dsatmp->q || !dsatmp->g) - goto err; - bn_expand2(dsatmp->pub_key, el / sizeof(BN_ULONG)); - bn_expand2(dsatmp->p, el / sizeof(BN_ULONG)); - bn_expand2(dsatmp->q, 20 / sizeof(BN_ULONG)); - bn_expand2(dsatmp->g, el / sizeof(BN_ULONG)); - if (dsatmp->pub_key->dmax != (int)(el / sizeof(BN_ULONG)) - || dsatmp->p->dmax != (int)(el / sizeof(BN_ULONG)) - || dsatmp->q->dmax != 20 / sizeof(BN_ULONG) - || dsatmp->g->dmax != (int)(el / sizeof(BN_ULONG))) - goto err; - - ret = p_surewarehk_Load_Dsa_Pubkey(msg, key_id, el, - (unsigned long *)dsatmp-> - pub_key->d, - (unsigned long *)dsatmp->p->d, - (unsigned long *)dsatmp->q->d, - (unsigned long *)dsatmp->g->d); - surewarehk_error_handling(msg, SUREWARE_F_SUREWARE_LOAD_PUBLIC, ret); - if (ret != 1) { - SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC, - ENGINE_R_FAILED_LOADING_PUBLIC_KEY); - goto err; - } - /* set parameters */ - /* normalise pubkey and parameters in case of */ - dsatmp->pub_key->top = el / sizeof(BN_ULONG); - bn_fix_top(dsatmp->pub_key); - dsatmp->p->top = el / sizeof(BN_ULONG); - bn_fix_top(dsatmp->p); - dsatmp->q->top = 20 / sizeof(BN_ULONG); - bn_fix_top(dsatmp->q); - dsatmp->g->top = el / sizeof(BN_ULONG); - bn_fix_top(dsatmp->g); - - /* create an EVP object: engine + rsa key */ - res = EVP_PKEY_new(); - EVP_PKEY_assign_DSA(res, dsatmp); - break; -# endif - - default: - SUREWAREerr(SUREWARE_F_SUREWARE_LOAD_PUBLIC, - ENGINE_R_FAILED_LOADING_PRIVATE_KEY); - goto err; - } - return res; - err: -# ifndef OPENSSL_NO_RSA - if (rsatmp) - RSA_free(rsatmp); -# endif -# ifndef OPENSSL_NO_DSA - if (dsatmp) - DSA_free(dsatmp); -# endif - return NULL; -} - -static EVP_PKEY *surewarehk_load_privkey(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, - void *callback_data) -{ - EVP_PKEY *res = NULL; - int ret = 0; - unsigned long el = 0; - char *hptr = NULL; - char keytype = 0; - char msg[64] = "ENGINE_load_privkey"; - - if (!p_surewarehk_Load_Privkey) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY, - ENGINE_R_NOT_INITIALISED); - } else { - ret = p_surewarehk_Load_Privkey(msg, key_id, &hptr, &el, &keytype); - if (ret != 1) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY, - ENGINE_R_FAILED_LOADING_PRIVATE_KEY); - ERR_add_error_data(1, msg); - } else - res = sureware_load_public(e, key_id, hptr, el, keytype); - } - return res; -} - -static EVP_PKEY *surewarehk_load_pubkey(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, - void *callback_data) -{ - EVP_PKEY *res = NULL; - int ret = 0; - unsigned long el = 0; - char *hptr = NULL; - char keytype = 0; - char msg[64] = "ENGINE_load_pubkey"; - - if (!p_surewarehk_Info_Pubkey) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY, - ENGINE_R_NOT_INITIALISED); - } else { - /* call once to identify if DSA or RSA */ - ret = p_surewarehk_Info_Pubkey(msg, key_id, &el, &keytype); - if (ret != 1) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY, - ENGINE_R_FAILED_LOADING_PUBLIC_KEY); - ERR_add_error_data(1, msg); - } else - res = sureware_load_public(e, key_id, hptr, el, keytype); - } - return res; -} - -/* - * This cleans up an RSA/DSA KM key(do not destroy the key into the hardware) - * , called when ex_data is freed - */ -static void surewarehk_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp) -{ - if (!p_surewarehk_Free) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_EX_FREE, ENGINE_R_NOT_INITIALISED); - } else - p_surewarehk_Free((char *)item, 0); -} - -# if 0 -/* not currently used (bug?) */ -/* - * This cleans up an DH KM key (destroys the key into hardware), called when - * ex_data is freed - */ -static void surewarehk_dh_ex_free(void *obj, void *item, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp) -{ - if (!p_surewarehk_Free) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_DH_EX_FREE, - ENGINE_R_NOT_INITIALISED); - } else - p_surewarehk_Free((char *)item, 1); -} -# endif - -/* - * return number of decrypted bytes - */ -# ifndef OPENSSL_NO_RSA -static int surewarehk_rsa_priv_dec(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - int ret = 0, tlen; - char *buf = NULL, *hptr = NULL; - char msg[64] = "ENGINE_rsa_priv_dec"; - if (!p_surewarehk_Rsa_Priv_Dec) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, - ENGINE_R_NOT_INITIALISED); - } - /* extract ref to private key */ - else if (!(hptr = RSA_get_ex_data(rsa, rsaHndidx))) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, - SUREWARE_R_MISSING_KEY_COMPONENTS); - goto err; - } - /* analyse what padding we can do into the hardware */ - if (padding == RSA_PKCS1_PADDING) { - /* do it one shot */ - ret = - p_surewarehk_Rsa_Priv_Dec(msg, flen, (unsigned char *)from, &tlen, - to, hptr, SUREWARE_PKCS1_PAD); - surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, - ret); - if (ret != 1) - goto err; - ret = tlen; - } else { /* do with no padding into hardware */ - - ret = - p_surewarehk_Rsa_Priv_Dec(msg, flen, (unsigned char *)from, &tlen, - to, hptr, SUREWARE_NO_PAD); - surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, - ret); - if (ret != 1) - goto err; - /* intermediate buffer for padding */ - if ((buf = OPENSSL_malloc(tlen)) == NULL) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, - ERR_R_MALLOC_FAILURE); - goto err; - } - memcpy(buf, to, tlen); /* transfert to into buf */ - switch (padding) { /* check padding in software */ -# ifndef OPENSSL_NO_SHA - case RSA_PKCS1_OAEP_PADDING: - ret = - RSA_padding_check_PKCS1_OAEP(to, tlen, (unsigned char *)buf, - tlen, tlen, NULL, 0); - break; -# endif - case RSA_SSLV23_PADDING: - ret = - RSA_padding_check_SSLv23(to, tlen, (unsigned char *)buf, flen, - tlen); - break; - case RSA_NO_PADDING: - ret = - RSA_padding_check_none(to, tlen, (unsigned char *)buf, flen, - tlen); - break; - default: - SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, - SUREWARE_R_UNKNOWN_PADDING_TYPE); - goto err; - } - if (ret < 0) - SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC, - SUREWARE_R_PADDING_CHECK_FAILED); - } - err: - if (buf) { - OPENSSL_cleanse(buf, tlen); - OPENSSL_free(buf); - } - return ret; -} - -/* - * Does what OpenSSL rsa_priv_enc does. - */ -static int surewarehk_rsa_sign(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - int ret = 0, tlen; - char *hptr = NULL; - char msg[64] = "ENGINE_rsa_sign"; - if (!p_surewarehk_Rsa_Sign) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN, ENGINE_R_NOT_INITIALISED); - } - /* extract ref to private key */ - else if (!(hptr = RSA_get_ex_data(rsa, rsaHndidx))) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN, - SUREWARE_R_MISSING_KEY_COMPONENTS); - } else { - switch (padding) { - case RSA_PKCS1_PADDING: /* do it in one shot */ - ret = - p_surewarehk_Rsa_Sign(msg, flen, (unsigned char *)from, &tlen, - to, hptr, SUREWARE_PKCS1_PAD); - surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_RSA_SIGN, - ret); - break; - case RSA_NO_PADDING: - default: - SUREWAREerr(SUREWARE_F_SUREWAREHK_RSA_SIGN, - SUREWARE_R_UNKNOWN_PADDING_TYPE); - } - } - return ret == 1 ? tlen : ret; -} - -# endif - -# ifndef OPENSSL_NO_DSA -/* DSA sign and verify */ -static DSA_SIG *surewarehk_dsa_do_sign(const unsigned char *from, int flen, - DSA *dsa) -{ - int ret = 0; - char *hptr = NULL; - DSA_SIG *psign = NULL; - char msg[64] = "ENGINE_dsa_do_sign"; - if (!p_surewarehk_Dsa_Sign) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN, - ENGINE_R_NOT_INITIALISED); - goto err; - } - /* extract ref to private key */ - else if (!(hptr = DSA_get_ex_data(dsa, dsaHndidx))) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN, - SUREWARE_R_MISSING_KEY_COMPONENTS); - goto err; - } else { - if ((psign = DSA_SIG_new()) == NULL) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN, - ERR_R_MALLOC_FAILURE); - goto err; - } - psign->r = BN_new(); - psign->s = BN_new(); - if(!psign->r || !psign->s) - goto err; - bn_expand2(psign->r, 20 / sizeof(BN_ULONG)); - bn_expand2(psign->s, 20 / sizeof(BN_ULONG)); - if (psign->r->dmax != 20 / sizeof(BN_ULONG) || - psign->s->dmax != 20 / sizeof(BN_ULONG)) - goto err; - ret = p_surewarehk_Dsa_Sign(msg, flen, from, - (unsigned long *)psign->r->d, - (unsigned long *)psign->s->d, hptr); - surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_DSA_DO_SIGN, - ret); - } - psign->r->top = 20 / sizeof(BN_ULONG); - bn_fix_top(psign->r); - psign->s->top = 20 / sizeof(BN_ULONG); - bn_fix_top(psign->s); - - err: - if (psign) { - DSA_SIG_free(psign); - psign = NULL; - } - return psign; -} -# endif - -static int surewarehk_modexp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - int ret = 0; - char msg[64] = "ENGINE_modexp"; - if (!p_surewarehk_Mod_Exp) { - SUREWAREerr(SUREWARE_F_SUREWAREHK_MODEXP, ENGINE_R_NOT_INITIALISED); - } else if (r) { - bn_expand2(r, m->top); - if (r->dmax == m->top) { - /* do it */ - ret = p_surewarehk_Mod_Exp(msg, - m->top * sizeof(BN_ULONG), - (unsigned long *)m->d, - p->top * sizeof(BN_ULONG), - (unsigned long *)p->d, - a->top * sizeof(BN_ULONG), - (unsigned long *)a->d, - (unsigned long *)r->d); - surewarehk_error_handling(msg, SUREWARE_F_SUREWAREHK_MODEXP, ret); - if (ret == 1) { - /* normalise result */ - r->top = m->top; - bn_fix_top(r); - } - } - } - return ret; -} -# endif /* !OPENSSL_NO_HW_SureWare */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_sureware_err.c b/Sources/COpenSSL/e_sureware_err.c deleted file mode 100644 index 7551f181..00000000 --- a/Sources/COpenSSL/e_sureware_err.c +++ /dev/null @@ -1,154 +0,0 @@ -/* e_sureware_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_sureware_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA SUREWARE_str_functs[] = { - {ERR_FUNC(SUREWARE_F_SUREWAREHK_CTRL), "SUREWAREHK_CTRL"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_DH_EX_FREE), "SUREWAREHK_DH_EX_FREE"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_DSA_DO_SIGN), "SUREWAREHK_DSA_DO_SIGN"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_EX_FREE), "SUREWAREHK_EX_FREE"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_FINISH), "SUREWAREHK_FINISH"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_INIT), "SUREWAREHK_INIT"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY), "SUREWAREHK_LOAD_PRIVKEY"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_LOAD_PUBKEY), "SUREWAREHK_LOAD_PUBKEY"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_MODEXP), "SUREWAREHK_MODEXP"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_BYTES), "SUREWAREHK_RAND_BYTES"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_RAND_SEED), "SUREWAREHK_RAND_SEED"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC), "SUREWAREHK_RSA_PRIV_DEC"}, - {ERR_FUNC(SUREWARE_F_SUREWAREHK_RSA_SIGN), "SUREWAREHK_RSA_SIGN"}, - {ERR_FUNC(SUREWARE_F_SUREWARE_LOAD_PUBLIC), "SUREWARE_LOAD_PUBLIC"}, - {0, NULL} -}; - -static ERR_STRING_DATA SUREWARE_str_reasons[] = { - {ERR_REASON(SUREWARE_R_BIO_WAS_FREED), "bio was freed"}, - {ERR_REASON(SUREWARE_R_MISSING_KEY_COMPONENTS), "missing key components"}, - {ERR_REASON(SUREWARE_R_PADDING_CHECK_FAILED), "padding check failed"}, - {ERR_REASON(SUREWARE_R_REQUEST_FAILED), "request failed"}, - {ERR_REASON(SUREWARE_R_REQUEST_FALLBACK), "request fallback"}, - {ERR_REASON(SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL), - "size too large or too small"}, - {ERR_REASON(SUREWARE_R_UNIT_FAILURE), "unit failure"}, - {ERR_REASON(SUREWARE_R_UNKNOWN_PADDING_TYPE), "unknown padding type"}, - {0, NULL} -}; - -#endif - -#ifdef SUREWARE_LIB_NAME -static ERR_STRING_DATA SUREWARE_lib_name[] = { - {0, SUREWARE_LIB_NAME}, - {0, NULL} -}; -#endif - -static int SUREWARE_lib_error_code = 0; -static int SUREWARE_error_init = 1; - -static void ERR_load_SUREWARE_strings(void) -{ - if (SUREWARE_lib_error_code == 0) - SUREWARE_lib_error_code = ERR_get_next_error_library(); - - if (SUREWARE_error_init) { - SUREWARE_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(SUREWARE_lib_error_code, SUREWARE_str_functs); - ERR_load_strings(SUREWARE_lib_error_code, SUREWARE_str_reasons); -#endif - -#ifdef SUREWARE_LIB_NAME - SUREWARE_lib_name->error = ERR_PACK(SUREWARE_lib_error_code, 0, 0); - ERR_load_strings(0, SUREWARE_lib_name); -#endif - } -} - -static void ERR_unload_SUREWARE_strings(void) -{ - if (SUREWARE_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(SUREWARE_lib_error_code, SUREWARE_str_functs); - ERR_unload_strings(SUREWARE_lib_error_code, SUREWARE_str_reasons); -#endif - -#ifdef SUREWARE_LIB_NAME - ERR_unload_strings(0, SUREWARE_lib_name); -#endif - SUREWARE_error_init = 1; - } -} - -static void ERR_SUREWARE_error(int function, int reason, char *file, int line) -{ - if (SUREWARE_lib_error_code == 0) - SUREWARE_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(SUREWARE_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_sureware_err.h b/Sources/COpenSSL/e_sureware_err.h deleted file mode 100644 index bef86239..00000000 --- a/Sources/COpenSSL/e_sureware_err.h +++ /dev/null @@ -1,104 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_SUREWARE_ERR_H -# define HEADER_SUREWARE_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_SUREWARE_strings(void); -static void ERR_unload_SUREWARE_strings(void); -static void ERR_SUREWARE_error(int function, int reason, char *file, - int line); -# define SUREWAREerr(f,r) ERR_SUREWARE_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the SUREWARE functions. */ - -/* Function codes. */ -# define SUREWARE_F_SUREWAREHK_CTRL 100 -# define SUREWARE_F_SUREWAREHK_DH_EX_FREE 112 -# define SUREWARE_F_SUREWAREHK_DSA_DO_SIGN 101 -# define SUREWARE_F_SUREWAREHK_EX_FREE 102 -# define SUREWARE_F_SUREWAREHK_FINISH 103 -# define SUREWARE_F_SUREWAREHK_INIT 104 -# define SUREWARE_F_SUREWAREHK_LOAD_PRIVKEY 105 -# define SUREWARE_F_SUREWAREHK_LOAD_PUBKEY 113 -# define SUREWARE_F_SUREWAREHK_MODEXP 107 -# define SUREWARE_F_SUREWAREHK_RAND_BYTES 108 -# define SUREWARE_F_SUREWAREHK_RAND_SEED 109 -# define SUREWARE_F_SUREWAREHK_RSA_PRIV_DEC 110 -# define SUREWARE_F_SUREWAREHK_RSA_SIGN 111 -# define SUREWARE_F_SUREWARE_LOAD_PUBLIC 106 - -/* Reason codes. */ -# define SUREWARE_R_BIO_WAS_FREED 100 -# define SUREWARE_R_MISSING_KEY_COMPONENTS 105 -# define SUREWARE_R_PADDING_CHECK_FAILED 106 -# define SUREWARE_R_REQUEST_FAILED 101 -# define SUREWARE_R_REQUEST_FALLBACK 102 -# define SUREWARE_R_SIZE_TOO_LARGE_OR_TOO_SMALL 103 -# define SUREWARE_R_UNIT_FAILURE 104 -# define SUREWARE_R_UNKNOWN_PADDING_TYPE 107 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_ubsec.c b/Sources/COpenSSL/e_ubsec.c deleted file mode 100644 index ba20fbc5..00000000 --- a/Sources/COpenSSL/e_ubsec.c +++ /dev/null @@ -1,1086 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/engine/hw_ubsec.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. Cloned shamelessly by Joe Tardo. - */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "crypto.h" -#include "buffer.h" -#include "dso.h" -#include "engine.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#include "bn.h" - -#ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_UBSEC - -# ifdef FLAT_INC -# include "hw_ubsec.h" -# else -# include "hw_ubsec.h" -# endif - -# define UBSEC_LIB_NAME "ubsec engine" -# include "e_ubsec_err.c" - -# define FAIL_TO_SOFTWARE -15 - -static int ubsec_destroy(ENGINE *e); -static int ubsec_init(ENGINE *e); -static int ubsec_finish(ENGINE *e); -static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); -static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx); -# ifndef OPENSSL_NO_RSA -static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *q, const BIGNUM *dp, - const BIGNUM *dq, const BIGNUM *qinv, - BN_CTX *ctx); -static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif -# ifndef OPENSSL_NO_DSA -# ifdef NOT_USED -static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, - BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *in_mont); -static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -# endif -static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, - DSA *dsa); -static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa); -# endif -# ifndef OPENSSL_NO_DH -static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -static int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, - DH *dh); -static int ubsec_dh_generate_key(DH *dh); -# endif - -# ifdef NOT_USED -static int ubsec_rand_bytes(unsigned char *buf, int num); -static int ubsec_rand_status(void); -# endif - -# define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE -static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = { - {UBSEC_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'ubsec' shared library", - ENGINE_CMD_FLAG_STRING}, - {0, NULL, NULL, 0} -}; - -# ifndef OPENSSL_NO_RSA -/* Our internal RSA_METHOD that we provide pointers to */ -static RSA_METHOD ubsec_rsa = { - "UBSEC RSA method", - NULL, - NULL, - NULL, - NULL, - ubsec_rsa_mod_exp, - ubsec_mod_exp_mont, - NULL, - NULL, - 0, - NULL, - NULL, - NULL, - NULL -}; -# endif - -# ifndef OPENSSL_NO_DSA -/* Our internal DSA_METHOD that we provide pointers to */ -static DSA_METHOD ubsec_dsa = { - "UBSEC DSA method", - ubsec_dsa_do_sign, /* dsa_do_sign */ - NULL, /* dsa_sign_setup */ - ubsec_dsa_verify, /* dsa_do_verify */ - NULL, /* ubsec_dsa_mod_exp *//* dsa_mod_exp */ - NULL, /* ubsec_mod_exp_dsa *//* bn_mod_exp */ - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - NULL, /* dsa_paramgen */ - NULL /* dsa_keygen */ -}; -# endif - -# ifndef OPENSSL_NO_DH -/* Our internal DH_METHOD that we provide pointers to */ -static DH_METHOD ubsec_dh = { - "UBSEC DH method", - ubsec_dh_generate_key, - ubsec_dh_compute_key, - ubsec_mod_exp_dh, - NULL, - NULL, - 0, - NULL, - NULL -}; -# endif - -/* Constants used when creating the ENGINE */ -static const char *engine_ubsec_id = "ubsec"; -static const char *engine_ubsec_name = "UBSEC hardware engine support"; - -/* - * This internal function is used by ENGINE_ubsec() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_helper(ENGINE *e) -{ -# ifndef OPENSSL_NO_RSA - const RSA_METHOD *meth1; -# endif -# ifndef OPENSSL_NO_DH -# ifndef HAVE_UBSEC_DH - const DH_METHOD *meth3; -# endif /* HAVE_UBSEC_DH */ -# endif - if (!ENGINE_set_id(e, engine_ubsec_id) || - !ENGINE_set_name(e, engine_ubsec_name) || -# ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &ubsec_rsa) || -# endif -# ifndef OPENSSL_NO_DSA - !ENGINE_set_DSA(e, &ubsec_dsa) || -# endif -# ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &ubsec_dh) || -# endif - !ENGINE_set_destroy_function(e, ubsec_destroy) || - !ENGINE_set_init_function(e, ubsec_init) || - !ENGINE_set_finish_function(e, ubsec_finish) || - !ENGINE_set_ctrl_function(e, ubsec_ctrl) || - !ENGINE_set_cmd_defns(e, ubsec_cmd_defns)) - return 0; - -# ifndef OPENSSL_NO_RSA - /* - * We know that the "PKCS1_SSLeay()" functions hook properly to the - * Broadcom-specific mod_exp and mod_exp_crt so we use those functions. - * NB: We don't use ENGINE_openssl() or anything "more generic" because - * something like the RSAref code may not hook properly, and if you own - * one of these cards then you have the right to do RSA operations on it - * anyway! - */ - meth1 = RSA_PKCS1_SSLeay(); - ubsec_rsa.rsa_pub_enc = meth1->rsa_pub_enc; - ubsec_rsa.rsa_pub_dec = meth1->rsa_pub_dec; - ubsec_rsa.rsa_priv_enc = meth1->rsa_priv_enc; - ubsec_rsa.rsa_priv_dec = meth1->rsa_priv_dec; -# endif - -# ifndef OPENSSL_NO_DH -# ifndef HAVE_UBSEC_DH - /* Much the same for Diffie-Hellman */ - meth3 = DH_OpenSSL(); - ubsec_dh.generate_key = meth3->generate_key; - ubsec_dh.compute_key = meth3->compute_key; -# endif /* HAVE_UBSEC_DH */ -# endif - - /* Ensure the ubsec error handling is set up */ - ERR_load_UBSEC_strings(); - return 1; -} - -# ifdef OPENSSL_NO_DYNAMIC_ENGINE -static ENGINE *engine_ubsec(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_ubsec(void) -{ - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_ubsec(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -# endif - -/* - * This is a process-global DSO handle used for loading and unloading the - * UBSEC library. NB: This is only set (or unset) during an init() or - * finish() call (reference counts permitting) and they're operating with - * global locks, so this should be thread-safe implicitly. - */ - -static DSO *ubsec_dso = NULL; - -/* - * These are the function pointers that are (un)set when the library has - * successfully (un)loaded. - */ - -static t_UBSEC_ubsec_bytes_to_bits *p_UBSEC_ubsec_bytes_to_bits = NULL; -static t_UBSEC_ubsec_bits_to_bytes *p_UBSEC_ubsec_bits_to_bytes = NULL; -static t_UBSEC_ubsec_open *p_UBSEC_ubsec_open = NULL; -static t_UBSEC_ubsec_close *p_UBSEC_ubsec_close = NULL; -# ifndef OPENSSL_NO_DH -static t_UBSEC_diffie_hellman_generate_ioctl - * p_UBSEC_diffie_hellman_generate_ioctl = NULL; -static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl - = NULL; -# endif -# ifndef OPENSSL_NO_RSA -static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL; -static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; -# endif -# ifndef OPENSSL_NO_DSA -static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL; -static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL; -# endif -static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL; -static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL; -static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL; - -static int max_key_len = 1024; /* ??? */ - -/* - * These are the static string constants for the DSO file name and the function - * symbol names to bind to. - */ - -static const char *UBSEC_LIBNAME = NULL; -static const char *get_UBSEC_LIBNAME(void) -{ - if (UBSEC_LIBNAME) - return UBSEC_LIBNAME; - return "ubsec"; -} - -static void free_UBSEC_LIBNAME(void) -{ - if (UBSEC_LIBNAME) - OPENSSL_free((void *)UBSEC_LIBNAME); - UBSEC_LIBNAME = NULL; -} - -static long set_UBSEC_LIBNAME(const char *name) -{ - free_UBSEC_LIBNAME(); - return (((UBSEC_LIBNAME = BUF_strdup(name)) != NULL) ? 1 : 0); -} - -static const char *UBSEC_F1 = "ubsec_bytes_to_bits"; -static const char *UBSEC_F2 = "ubsec_bits_to_bytes"; -static const char *UBSEC_F3 = "ubsec_open"; -static const char *UBSEC_F4 = "ubsec_close"; -# ifndef OPENSSL_NO_DH -static const char *UBSEC_F5 = "diffie_hellman_generate_ioctl"; -static const char *UBSEC_F6 = "diffie_hellman_agree_ioctl"; -# endif -/* #ifndef OPENSSL_NO_RSA */ -static const char *UBSEC_F7 = "rsa_mod_exp_ioctl"; -static const char *UBSEC_F8 = "rsa_mod_exp_crt_ioctl"; -/* #endif */ -# ifndef OPENSSL_NO_DSA -static const char *UBSEC_F9 = "dsa_sign_ioctl"; -static const char *UBSEC_F10 = "dsa_verify_ioctl"; -# endif -static const char *UBSEC_F11 = "math_accelerate_ioctl"; -static const char *UBSEC_F12 = "rng_ioctl"; -static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl"; - -/* Destructor (complements the "ENGINE_ubsec()" constructor) */ -static int ubsec_destroy(ENGINE *e) -{ - free_UBSEC_LIBNAME(); - ERR_unload_UBSEC_strings(); - return 1; -} - -/* (de)initialisation functions. */ -static int ubsec_init(ENGINE *e) -{ - t_UBSEC_ubsec_bytes_to_bits *p1; - t_UBSEC_ubsec_bits_to_bytes *p2; - t_UBSEC_ubsec_open *p3; - t_UBSEC_ubsec_close *p4; -# ifndef OPENSSL_NO_DH - t_UBSEC_diffie_hellman_generate_ioctl *p5; - t_UBSEC_diffie_hellman_agree_ioctl *p6; -# endif -/* #ifndef OPENSSL_NO_RSA */ - t_UBSEC_rsa_mod_exp_ioctl *p7; - t_UBSEC_rsa_mod_exp_crt_ioctl *p8; -/* #endif */ -# ifndef OPENSSL_NO_DSA - t_UBSEC_dsa_sign_ioctl *p9; - t_UBSEC_dsa_verify_ioctl *p10; -# endif - t_UBSEC_math_accelerate_ioctl *p11; - t_UBSEC_rng_ioctl *p12; - t_UBSEC_max_key_len_ioctl *p13; - int fd = 0; - - if (ubsec_dso != NULL) { - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED); - goto err; - } - /* - * Attempt to load libubsec.so/ubsec.dll/whatever. - */ - ubsec_dso = DSO_load(NULL, get_UBSEC_LIBNAME(), NULL, 0); - if (ubsec_dso == NULL) { - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); - goto err; - } - - if (!(p1 = (t_UBSEC_ubsec_bytes_to_bits *) - DSO_bind_func(ubsec_dso, UBSEC_F1)) - || !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) - DSO_bind_func(ubsec_dso, UBSEC_F2)) - || !(p3 = (t_UBSEC_ubsec_open *) - DSO_bind_func(ubsec_dso, UBSEC_F3)) - || !(p4 = (t_UBSEC_ubsec_close *) - DSO_bind_func(ubsec_dso, UBSEC_F4)) -# ifndef OPENSSL_NO_DH - || !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F5)) - || !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F6)) -# endif -/* #ifndef OPENSSL_NO_RSA */ - || !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F7)) - || !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F8)) -/* #endif */ -# ifndef OPENSSL_NO_DSA - || !(p9 = (t_UBSEC_dsa_sign_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F9)) - || !(p10 = (t_UBSEC_dsa_verify_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F10)) -# endif - || !(p11 = (t_UBSEC_math_accelerate_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F11)) - || !(p12 = (t_UBSEC_rng_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F12)) - || !(p13 = (t_UBSEC_max_key_len_ioctl *) - DSO_bind_func(ubsec_dso, UBSEC_F13))) { - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); - goto err; - } - - /* Copy the pointers */ - p_UBSEC_ubsec_bytes_to_bits = p1; - p_UBSEC_ubsec_bits_to_bytes = p2; - p_UBSEC_ubsec_open = p3; - p_UBSEC_ubsec_close = p4; -# ifndef OPENSSL_NO_DH - p_UBSEC_diffie_hellman_generate_ioctl = p5; - p_UBSEC_diffie_hellman_agree_ioctl = p6; -# endif -# ifndef OPENSSL_NO_RSA - p_UBSEC_rsa_mod_exp_ioctl = p7; - p_UBSEC_rsa_mod_exp_crt_ioctl = p8; -# endif -# ifndef OPENSSL_NO_DSA - p_UBSEC_dsa_sign_ioctl = p9; - p_UBSEC_dsa_verify_ioctl = p10; -# endif - p_UBSEC_math_accelerate_ioctl = p11; - p_UBSEC_rng_ioctl = p12; - p_UBSEC_max_key_len_ioctl = p13; - - /* Perform an open to see if there's actually any unit running. */ - if (((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) - && (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) == 0)) { - p_UBSEC_ubsec_close(fd); - return 1; - } else { - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); - } - - err: - if (ubsec_dso) - DSO_free(ubsec_dso); - ubsec_dso = NULL; - p_UBSEC_ubsec_bytes_to_bits = NULL; - p_UBSEC_ubsec_bits_to_bytes = NULL; - p_UBSEC_ubsec_open = NULL; - p_UBSEC_ubsec_close = NULL; -# ifndef OPENSSL_NO_DH - p_UBSEC_diffie_hellman_generate_ioctl = NULL; - p_UBSEC_diffie_hellman_agree_ioctl = NULL; -# endif -# ifndef OPENSSL_NO_RSA - p_UBSEC_rsa_mod_exp_ioctl = NULL; - p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; -# endif -# ifndef OPENSSL_NO_DSA - p_UBSEC_dsa_sign_ioctl = NULL; - p_UBSEC_dsa_verify_ioctl = NULL; -# endif - p_UBSEC_math_accelerate_ioctl = NULL; - p_UBSEC_rng_ioctl = NULL; - p_UBSEC_max_key_len_ioctl = NULL; - - return 0; -} - -static int ubsec_finish(ENGINE *e) -{ - free_UBSEC_LIBNAME(); - if (ubsec_dso == NULL) { - UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED); - return 0; - } - if (!DSO_free(ubsec_dso)) { - UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE); - return 0; - } - ubsec_dso = NULL; - p_UBSEC_ubsec_bytes_to_bits = NULL; - p_UBSEC_ubsec_bits_to_bytes = NULL; - p_UBSEC_ubsec_open = NULL; - p_UBSEC_ubsec_close = NULL; -# ifndef OPENSSL_NO_DH - p_UBSEC_diffie_hellman_generate_ioctl = NULL; - p_UBSEC_diffie_hellman_agree_ioctl = NULL; -# endif -# ifndef OPENSSL_NO_RSA - p_UBSEC_rsa_mod_exp_ioctl = NULL; - p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; -# endif -# ifndef OPENSSL_NO_DSA - p_UBSEC_dsa_sign_ioctl = NULL; - p_UBSEC_dsa_verify_ioctl = NULL; -# endif - p_UBSEC_math_accelerate_ioctl = NULL; - p_UBSEC_rng_ioctl = NULL; - p_UBSEC_max_key_len_ioctl = NULL; - return 1; -} - -static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int initialised = ((ubsec_dso == NULL) ? 0 : 1); - switch (cmd) { - case UBSEC_CMD_SO_PATH: - if (p == NULL) { - UBSECerr(UBSEC_F_UBSEC_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (initialised) { - UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_ALREADY_LOADED); - return 0; - } - return set_UBSEC_LIBNAME((const char *)p); - default: - break; - } - UBSECerr(UBSEC_F_UBSEC_CTRL, UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED); - return 0; -} - -static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx) -{ - int y_len = 0; - int fd; - - if (ubsec_dso == NULL) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED); - return 0; - } - - /* Check if hardware can't handle this argument. */ - y_len = BN_num_bits(m); - if (y_len > max_key_len) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return BN_mod_exp(r, a, p, m, ctx); - } - - if (!bn_wexpand(r, m->top)) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL); - return 0; - } - - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - fd = 0; - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_UNIT_FAILURE); - return BN_mod_exp(r, a, p, m, ctx); - } - - if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a), - (unsigned char *)m->d, BN_num_bits(m), - (unsigned char *)p->d, BN_num_bits(p), - (unsigned char *)r->d, &y_len) != 0) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED); - p_UBSEC_ubsec_close(fd); - - return BN_mod_exp(r, a, p, m, ctx); - } - - p_UBSEC_ubsec_close(fd); - - r->top = (BN_num_bits(m) + BN_BITS2 - 1) / BN_BITS2; - return 1; -} - -# ifndef OPENSSL_NO_RSA -static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx) -{ - int to_return = 0; - - if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { - UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS); - goto err; - } - - to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, - rsa->dmq1, rsa->iqmp, ctx); - if (to_return == FAIL_TO_SOFTWARE) { - /* - * Do in software as hardware failed. - */ - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - to_return = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); - } - err: - return to_return; -} - -static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *q, const BIGNUM *dp, - const BIGNUM *dq, const BIGNUM *qinv, - BN_CTX *ctx) -{ - int y_len, fd; - - y_len = BN_num_bits(p) + BN_num_bits(q); - - /* Check if hardware can't handle this argument. */ - if (y_len > max_key_len) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, - UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return FAIL_TO_SOFTWARE; - } - - if (!bn_wexpand(r, p->top + q->top + 1)) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL); - return 0; - } - - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - fd = 0; - UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_UNIT_FAILURE); - return FAIL_TO_SOFTWARE; - } - - if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd, - (unsigned char *)a->d, BN_num_bits(a), - (unsigned char *)qinv->d, - BN_num_bits(qinv), - (unsigned char *)dp->d, BN_num_bits(dp), - (unsigned char *)p->d, BN_num_bits(p), - (unsigned char *)dq->d, BN_num_bits(dq), - (unsigned char *)q->d, BN_num_bits(q), - (unsigned char *)r->d, &y_len) != 0) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP_CRT, UBSEC_R_REQUEST_FAILED); - p_UBSEC_ubsec_close(fd); - return FAIL_TO_SOFTWARE; - } - - p_UBSEC_ubsec_close(fd); - - r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1) / BN_BITS2; - return 1; -} -# endif - -# ifndef OPENSSL_NO_DSA -# ifdef NOT_USED -static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, - BIGNUM *p1, BIGNUM *a2, BIGNUM *p2, BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *in_mont) -{ - BIGNUM t; - int to_return = 0; - - BN_init(&t); - /* let rr = a1 ^ p1 mod m */ - if (!ubsec_mod_exp(rr, a1, p1, m, ctx)) - goto end; - /* let t = a2 ^ p2 mod m */ - if (!ubsec_mod_exp(&t, a2, p2, m, ctx)) - goto end; - /* let rr = rr * t mod m */ - if (!BN_mod_mul(rr, rr, &t, m, ctx)) - goto end; - to_return = 1; - end: - BN_free(&t); - return to_return; -} - -static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return ubsec_mod_exp(r, a, p, m, ctx); -} -# endif -# endif - -# ifndef OPENSSL_NO_RSA - -/* - * This function is aliased to mod_exp (with the mont stuff dropped). - */ -static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - int ret = 0; - - /* Do in software if the key is too large for the hardware. */ - if (BN_num_bits(m) > max_key_len) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - ret = (*meth->bn_mod_exp) (r, a, p, m, ctx, m_ctx); - } else { - ret = ubsec_mod_exp(r, a, p, m, ctx); - } - - return ret; -} -# endif - -# ifndef OPENSSL_NO_DH -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return ubsec_mod_exp(r, a, p, m, ctx); -} -# endif - -# ifndef OPENSSL_NO_DSA -static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, - DSA *dsa) -{ - DSA_SIG *to_return = NULL; - int s_len = 160, r_len = 160, d_len, fd; - BIGNUM m, *r = NULL, *s = NULL; - - BN_init(&m); - - s = BN_new(); - r = BN_new(); - if ((s == NULL) || (r == NULL)) - goto err; - - d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen); - - if (!bn_wexpand(r, (160 + BN_BITS2 - 1) / BN_BITS2) || - (!bn_wexpand(s, (160 + BN_BITS2 - 1) / BN_BITS2))) { - UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); - goto err; - } - - if (BN_bin2bn(dgst, dlen, &m) == NULL) { - UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); - goto err; - } - - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - const DSA_METHOD *meth; - fd = 0; - UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_UNIT_FAILURE); - meth = DSA_OpenSSL(); - to_return = meth->dsa_do_sign(dgst, dlen, dsa); - goto err; - } - - if (p_UBSEC_dsa_sign_ioctl(fd, - /* compute hash before signing */ - 0, (unsigned char *)dgst, d_len, NULL, - /* compute random value */ - 0, - (unsigned char *)dsa->p->d, - BN_num_bits(dsa->p), - (unsigned char *)dsa->q->d, - BN_num_bits(dsa->q), - (unsigned char *)dsa->g->d, - BN_num_bits(dsa->g), - (unsigned char *)dsa->priv_key->d, - BN_num_bits(dsa->priv_key), - (unsigned char *)r->d, &r_len, - (unsigned char *)s->d, &s_len) != 0) { - const DSA_METHOD *meth; - - UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_REQUEST_FAILED); - p_UBSEC_ubsec_close(fd); - meth = DSA_OpenSSL(); - to_return = meth->dsa_do_sign(dgst, dlen, dsa); - - goto err; - } - - p_UBSEC_ubsec_close(fd); - - r->top = (160 + BN_BITS2 - 1) / BN_BITS2; - s->top = (160 + BN_BITS2 - 1) / BN_BITS2; - - to_return = DSA_SIG_new(); - if (to_return == NULL) { - UBSECerr(UBSEC_F_UBSEC_DSA_DO_SIGN, UBSEC_R_BN_EXPAND_FAIL); - goto err; - } - - to_return->r = r; - to_return->s = s; - - err: - if (!to_return) { - if (r) - BN_free(r); - if (s) - BN_free(s); - } - BN_clear_free(&m); - return to_return; -} - -static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa) -{ - int v_len, d_len; - int to_return = 0; - int fd; - BIGNUM v, *pv = &v; - - BN_init(&v); - - if (!bn_wexpand(pv, dsa->p->top)) { - UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_BN_EXPAND_FAIL); - goto err; - } - - v_len = BN_num_bits(dsa->p); - - d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len); - - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - const DSA_METHOD *meth; - fd = 0; - UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_UNIT_FAILURE); - meth = DSA_OpenSSL(); - to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); - goto err; - } - - if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */ - (unsigned char *)dgst, d_len, - (unsigned char *)dsa->p->d, - BN_num_bits(dsa->p), - (unsigned char *)dsa->q->d, - BN_num_bits(dsa->q), - (unsigned char *)dsa->g->d, - BN_num_bits(dsa->g), - (unsigned char *)dsa->pub_key->d, - BN_num_bits(dsa->pub_key), - (unsigned char *)sig->r->d, - BN_num_bits(sig->r), - (unsigned char *)sig->s->d, - BN_num_bits(sig->s), (unsigned char *)v.d, - &v_len) != 0) { - const DSA_METHOD *meth; - UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY, UBSEC_R_REQUEST_FAILED); - p_UBSEC_ubsec_close(fd); - - meth = DSA_OpenSSL(); - to_return = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); - - goto err; - } - - p_UBSEC_ubsec_close(fd); - - to_return = 1; - err: - BN_clear_free(&v); - return to_return; -} -# endif - -# ifndef OPENSSL_NO_DH -static int ubsec_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, - DH *dh) -{ - int ret = -1, k_len, fd; - - k_len = BN_num_bits(dh->p); - - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - const DH_METHOD *meth; - UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_UNIT_FAILURE); - meth = DH_OpenSSL(); - ret = meth->compute_key(key, pub_key, dh); - goto err; - } - - if (p_UBSEC_diffie_hellman_agree_ioctl(fd, - (unsigned char *)dh->priv_key->d, - BN_num_bits(dh->priv_key), - (unsigned char *)pub_key->d, - BN_num_bits(pub_key), - (unsigned char *)dh->p->d, - BN_num_bits(dh->p), key, - &k_len) != 0) { - /* Hardware's a no go, failover to software */ - const DH_METHOD *meth; - UBSECerr(UBSEC_F_UBSEC_DH_COMPUTE_KEY, UBSEC_R_REQUEST_FAILED); - p_UBSEC_ubsec_close(fd); - - meth = DH_OpenSSL(); - ret = meth->compute_key(key, pub_key, dh); - - goto err; - } - - p_UBSEC_ubsec_close(fd); - - ret = p_UBSEC_ubsec_bits_to_bytes(k_len); - err: - return ret; -} - -static int ubsec_dh_generate_key(DH *dh) -{ - int ret = 0, random_bits = 0, pub_key_len = 0, priv_key_len = 0, fd; - BIGNUM *pub_key = NULL; - BIGNUM *priv_key = NULL; - - /* - * How many bits should Random x be? dh_key.c - * sets the range from 0 to num_bits(modulus) ??? - */ - - if (dh->priv_key == NULL) { - priv_key = BN_new(); - if (priv_key == NULL) - goto err; - priv_key_len = BN_num_bits(dh->p); - if (bn_wexpand(priv_key, dh->p->top) == NULL) - goto err; - do - if (!BN_rand_range(priv_key, dh->p)) - goto err; - while (BN_is_zero(priv_key)) ; - random_bits = BN_num_bits(priv_key); - } else { - priv_key = dh->priv_key; - } - - if (dh->pub_key == NULL) { - pub_key = BN_new(); - if (pub_key == NULL) - goto err; - pub_key_len = BN_num_bits(dh->p); - if (bn_wexpand(pub_key, dh->p->top) == NULL) - goto err; - } else { - pub_key = dh->pub_key; - } - - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - const DH_METHOD *meth; - UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_UNIT_FAILURE); - meth = DH_OpenSSL(); - ret = meth->generate_key(dh); - goto err; - } - - if (p_UBSEC_diffie_hellman_generate_ioctl(fd, - (unsigned char *)priv_key->d, - &priv_key_len, - (unsigned char *)pub_key->d, - &pub_key_len, - (unsigned char *)dh->g->d, - BN_num_bits(dh->g), - (unsigned char *)dh->p->d, - BN_num_bits(dh->p), 0, 0, - random_bits) != 0) { - /* Hardware's a no go, failover to software */ - const DH_METHOD *meth; - - UBSECerr(UBSEC_F_UBSEC_DH_GENERATE_KEY, UBSEC_R_REQUEST_FAILED); - p_UBSEC_ubsec_close(fd); - - meth = DH_OpenSSL(); - ret = meth->generate_key(dh); - - goto err; - } - - p_UBSEC_ubsec_close(fd); - - dh->pub_key = pub_key; - dh->pub_key->top = (pub_key_len + BN_BITS2 - 1) / BN_BITS2; - dh->priv_key = priv_key; - dh->priv_key->top = (priv_key_len + BN_BITS2 - 1) / BN_BITS2; - - ret = 1; - err: - return ret; -} -# endif - -# ifdef NOT_USED -static int ubsec_rand_bytes(unsigned char *buf, int num) -{ - int ret = 0, fd; - - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - const RAND_METHOD *meth; - UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_UNIT_FAILURE); - num = p_UBSEC_ubsec_bits_to_bytes(num); - meth = RAND_SSLeay(); - meth->seed(buf, num); - ret = meth->bytes(buf, num); - goto err; - } - - num *= 8; /* bytes to bits */ - - if (p_UBSEC_rng_ioctl(fd, UBSEC_RNG_DIRECT, buf, &num) != 0) { - /* Hardware's a no go, failover to software */ - const RAND_METHOD *meth; - - UBSECerr(UBSEC_F_UBSEC_RAND_BYTES, UBSEC_R_REQUEST_FAILED); - p_UBSEC_ubsec_close(fd); - - num = p_UBSEC_ubsec_bits_to_bytes(num); - meth = RAND_SSLeay(); - meth->seed(buf, num); - ret = meth->bytes(buf, num); - - goto err; - } - - p_UBSEC_ubsec_close(fd); - - ret = 1; - err: - return (ret); -} - -static int ubsec_rand_status(void) -{ - return 0; -} -# endif - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -# ifndef OPENSSL_NO_DYNAMIC_ENGINE -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_ubsec_id) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -# endif /* OPENSSL_NO_DYNAMIC_ENGINE */ -# endif /* !OPENSSL_NO_HW_UBSEC */ -#endif /* !OPENSSL_NO_HW */ diff --git a/Sources/COpenSSL/e_ubsec_err.c b/Sources/COpenSSL/e_ubsec_err.c deleted file mode 100644 index 948b87f7..00000000 --- a/Sources/COpenSSL/e_ubsec_err.c +++ /dev/null @@ -1,154 +0,0 @@ -/* e_ubsec_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "e_ubsec_err.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(0,func,0) -# define ERR_REASON(reason) ERR_PACK(0,0,reason) - -static ERR_STRING_DATA UBSEC_str_functs[] = { - {ERR_FUNC(UBSEC_F_UBSEC_CTRL), "UBSEC_CTRL"}, - {ERR_FUNC(UBSEC_F_UBSEC_DH_COMPUTE_KEY), "UBSEC_DH_COMPUTE_KEY"}, - {ERR_FUNC(UBSEC_F_UBSEC_DH_GENERATE_KEY), "UBSEC_DH_GENERATE_KEY"}, - {ERR_FUNC(UBSEC_F_UBSEC_DSA_DO_SIGN), "UBSEC_DSA_DO_SIGN"}, - {ERR_FUNC(UBSEC_F_UBSEC_DSA_VERIFY), "UBSEC_DSA_VERIFY"}, - {ERR_FUNC(UBSEC_F_UBSEC_FINISH), "UBSEC_FINISH"}, - {ERR_FUNC(UBSEC_F_UBSEC_INIT), "UBSEC_INIT"}, - {ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP), "UBSEC_MOD_EXP"}, - {ERR_FUNC(UBSEC_F_UBSEC_MOD_EXP_CRT), "UBSEC_MOD_EXP_CRT"}, - {ERR_FUNC(UBSEC_F_UBSEC_RAND_BYTES), "UBSEC_RAND_BYTES"}, - {ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP), "UBSEC_RSA_MOD_EXP"}, - {ERR_FUNC(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT), "UBSEC_RSA_MOD_EXP_CRT"}, - {0, NULL} -}; - -static ERR_STRING_DATA UBSEC_str_reasons[] = { - {ERR_REASON(UBSEC_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(UBSEC_R_BN_EXPAND_FAIL), "bn expand fail"}, - {ERR_REASON(UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(UBSEC_R_DSO_FAILURE), "dso failure"}, - {ERR_REASON(UBSEC_R_MISSING_KEY_COMPONENTS), "missing key components"}, - {ERR_REASON(UBSEC_R_NOT_LOADED), "not loaded"}, - {ERR_REASON(UBSEC_R_REQUEST_FAILED), "request failed"}, - {ERR_REASON(UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL), - "size too large or too small"}, - {ERR_REASON(UBSEC_R_UNIT_FAILURE), "unit failure"}, - {0, NULL} -}; - -#endif - -#ifdef UBSEC_LIB_NAME -static ERR_STRING_DATA UBSEC_lib_name[] = { - {0, UBSEC_LIB_NAME}, - {0, NULL} -}; -#endif - -static int UBSEC_lib_error_code = 0; -static int UBSEC_error_init = 1; - -static void ERR_load_UBSEC_strings(void) -{ - if (UBSEC_lib_error_code == 0) - UBSEC_lib_error_code = ERR_get_next_error_library(); - - if (UBSEC_error_init) { - UBSEC_error_init = 0; -#ifndef OPENSSL_NO_ERR - ERR_load_strings(UBSEC_lib_error_code, UBSEC_str_functs); - ERR_load_strings(UBSEC_lib_error_code, UBSEC_str_reasons); -#endif - -#ifdef UBSEC_LIB_NAME - UBSEC_lib_name->error = ERR_PACK(UBSEC_lib_error_code, 0, 0); - ERR_load_strings(0, UBSEC_lib_name); -#endif - } -} - -static void ERR_unload_UBSEC_strings(void) -{ - if (UBSEC_error_init == 0) { -#ifndef OPENSSL_NO_ERR - ERR_unload_strings(UBSEC_lib_error_code, UBSEC_str_functs); - ERR_unload_strings(UBSEC_lib_error_code, UBSEC_str_reasons); -#endif - -#ifdef UBSEC_LIB_NAME - ERR_unload_strings(0, UBSEC_lib_name); -#endif - UBSEC_error_init = 1; - } -} - -static void ERR_UBSEC_error(int function, int reason, char *file, int line) -{ - if (UBSEC_lib_error_code == 0) - UBSEC_lib_error_code = ERR_get_next_error_library(); - ERR_PUT_error(UBSEC_lib_error_code, function, reason, file, line); -} diff --git a/Sources/COpenSSL/e_ubsec_err.h b/Sources/COpenSSL/e_ubsec_err.h deleted file mode 100644 index c8aec7c3..00000000 --- a/Sources/COpenSSL/e_ubsec_err.h +++ /dev/null @@ -1,102 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_UBSEC_ERR_H -# define HEADER_UBSEC_ERR_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -static void ERR_load_UBSEC_strings(void); -static void ERR_unload_UBSEC_strings(void); -static void ERR_UBSEC_error(int function, int reason, char *file, int line); -# define UBSECerr(f,r) ERR_UBSEC_error((f),(r),__FILE__,__LINE__) - -/* Error codes for the UBSEC functions. */ - -/* Function codes. */ -# define UBSEC_F_UBSEC_CTRL 100 -# define UBSEC_F_UBSEC_DH_COMPUTE_KEY 101 -# define UBSEC_F_UBSEC_DH_GENERATE_KEY 111 -# define UBSEC_F_UBSEC_DSA_DO_SIGN 102 -# define UBSEC_F_UBSEC_DSA_VERIFY 103 -# define UBSEC_F_UBSEC_FINISH 104 -# define UBSEC_F_UBSEC_INIT 105 -# define UBSEC_F_UBSEC_MOD_EXP 106 -# define UBSEC_F_UBSEC_MOD_EXP_CRT 110 -# define UBSEC_F_UBSEC_RAND_BYTES 107 -# define UBSEC_F_UBSEC_RSA_MOD_EXP 108 -# define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT 109 - -/* Reason codes. */ -# define UBSEC_R_ALREADY_LOADED 100 -# define UBSEC_R_BN_EXPAND_FAIL 101 -# define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED 102 -# define UBSEC_R_DSO_FAILURE 103 -# define UBSEC_R_MISSING_KEY_COMPONENTS 104 -# define UBSEC_R_NOT_LOADED 105 -# define UBSEC_R_REQUEST_FAILED 106 -# define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL 107 -# define UBSEC_R_UNIT_FAILURE 108 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/e_xcbc_d.c b/Sources/COpenSSL/e_xcbc_d.c deleted file mode 100644 index 61bb071a..00000000 --- a/Sources/COpenSSL/e_xcbc_d.c +++ /dev/null @@ -1,130 +0,0 @@ -/* crypto/evp/e_xcbc_d.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_DES - -# include "evp.h" -# include "objects.h" -# include "evp_locl.h" -# include "des.h" - -static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); - -typedef struct { - DES_key_schedule ks; /* key schedule */ - DES_cblock inw; - DES_cblock outw; -} DESX_CBC_KEY; - -# define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data) - -static const EVP_CIPHER d_xcbc_cipher = { - NID_desx_cbc, - 8, 24, 8, - EVP_CIPH_CBC_MODE, - desx_cbc_init_key, - desx_cbc_cipher, - NULL, - sizeof(DESX_CBC_KEY), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL, - NULL -}; - -const EVP_CIPHER *EVP_desx_cbc(void) -{ - return (&d_xcbc_cipher); -} - -static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - DES_cblock *deskey = (DES_cblock *)key; - - DES_set_key_unchecked(deskey, &data(ctx)->ks); - memcpy(&data(ctx)->inw[0], &key[8], 8); - memcpy(&data(ctx)->outw[0], &key[16], 8); - - return 1; -} - -static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - while (inl >= EVP_MAXCHUNK) { - DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks, - (DES_cblock *)&(ctx->iv[0]), - &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt); - inl -= EVP_MAXCHUNK; - in += EVP_MAXCHUNK; - out += EVP_MAXCHUNK; - } - if (inl) - DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks, - (DES_cblock *)&(ctx->iv[0]), - &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt); - return 1; -} -#endif diff --git a/Sources/COpenSSL/ebcdic.c b/Sources/COpenSSL/ebcdic.c deleted file mode 100644 index ce7ab64e..00000000 --- a/Sources/COpenSSL/ebcdic.c +++ /dev/null @@ -1,284 +0,0 @@ -/* crypto/ebcdic.c */ - -#ifndef CHARSET_EBCDIC - -# include "e_os2.h" -# if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) || defined(__clang__) -static void *dummy = &dummy; -# endif - -#else /* CHARSET_EBCDIC */ - -# include "ebcdic.h" -/*- - * Initial Port for Apache-1.3 by - * Adapted for OpenSSL-0.9.4 by - */ - -# ifdef _OSD_POSIX -/* - * "BS2000 OSD" is a POSIX subsystem on a main frame. It is made by Siemens - * AG, Germany, for their BS2000 mainframe machines. Within the POSIX - * subsystem, the same character set was chosen as in "native BS2000", namely - * EBCDIC. (EDF04) - * - * The name "ASCII" in these routines is misleading: actually, conversion is - * not between EBCDIC and ASCII, but EBCDIC(EDF04) and ISO-8859.1; that means - * that (western european) national characters are preserved. - * - * This table is identical to the one used by rsh/rcp/ftp and other POSIX - * tools. - */ - -/* Here's the bijective ebcdic-to-ascii table: */ -const unsigned char os_toascii[256] = { - /* - * 00 - */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, - 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ - /* - * 10 - */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, - 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ - /* - * 20 - */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */ - /* - * 30 - */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, - 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */ - /* - * 40 - */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, - 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+| */ - /* - * 50 - */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, - 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /* &.........!$*);. */ - /* - * 60 - */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, - 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/ - /* - * 70 - */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, - 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* ..........:#@'=" */ - /* - * 80 - */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */ - /* - * 90 - */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, - 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */ - /* - * a0 - */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /* ..stuvwxyz...... */ - /* - * b0 - */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, - 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /* ...........[\].. */ - /* - * c0 - */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* .ABCDEFGHI...... */ - /* - * d0 - */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, - 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /* .JKLMNOPQR...... */ - /* - * e0 - */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* ..STUVWXYZ...... */ - /* - * f0 - */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /* 0123456789.{.}.~ */ -}; - -/* The ascii-to-ebcdic table: */ -const unsigned char os_toebcdic[256] = { - /* - * 00 - */ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, - 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ - /* - * 10 - */ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, - 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ - /* - * 20 - */ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, - 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */ - /* - * 30 - */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, - 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */ - /* - * 40 - */ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, - 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */ - /* - * 50 - */ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, - 0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d, /* PQRSTUVWXYZ[\]^_ */ - /* - * 60 - */ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */ - /* - * 70 - */ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, - 0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07, /* pqrstuvwxyz{|}~. */ - /* - * 80 - */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */ - /* - * 90 - */ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, - 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f, /* ................ */ - /* - * a0 - */ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5, - 0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1, /* ................ */ - /* - * b0 - */ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, - 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */ - /* - * c0 - */ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, - 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */ - /* - * d0 - */ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, - 0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59, /* ................ */ - /* - * e0 - */ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, - 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */ - /* - * f0 - */ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, - 0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */ -}; - -# else /*_OSD_POSIX*/ - -/* - * This code does basic character mapping for IBM's TPF and OS/390 operating - * systems. It is a modified version of the BS2000 table. - * - * Bijective EBCDIC (character set IBM-1047) to US-ASCII table: This table is - * bijective - there are no ambigous or duplicate characters. - */ -const unsigned char os_toascii[256] = { - 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */ - 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ - 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */ - 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ - 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */ - 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */ - 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */ - 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */ - 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */ - 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */ - 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */ - 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */ - 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */ - 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */ - 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */ - 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */ - 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */ - 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */ - 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */ - 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */ - 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */ - 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */ - 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */ - 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */ - 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */ - 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */ - 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */ - 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */ - 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */ - 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */ - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */ - 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */ -}; - -/* - * The US-ASCII to EBCDIC (character set IBM-1047) table: This table is - * bijective (no ambiguous or duplicate characters) - */ -const unsigned char os_toebcdic[256] = { - 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f: */ - 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ - 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f: */ - 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ - 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f: */ - 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */ - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f: */ - 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */ - 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f: */ - 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */ - 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f: */ - 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */ - 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f: */ - 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */ - 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f: */ - 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */ - 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f: */ - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */ - 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f: */ - 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */ - 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af: */ - 0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */ - 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf: */ - 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */ - 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf: */ - 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */ - 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df: */ - 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */ - 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef: */ - 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */ - 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff: */ - 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */ -}; -# endif/*_OSD_POSIX*/ - -/* - * Translate a memory block from EBCDIC (host charset) to ASCII (net charset) - * dest and srce may be identical, or separate memory blocks, but should not - * overlap. These functions intentionally have an interface compatible to - * memcpy(3). - */ - -void *ebcdic2ascii(void *dest, const void *srce, size_t count) -{ - unsigned char *udest = dest; - const unsigned char *usrce = srce; - - while (count-- != 0) { - *udest++ = os_toascii[*usrce++]; - } - - return dest; -} - -void *ascii2ebcdic(void *dest, const void *srce, size_t count) -{ - unsigned char *udest = dest; - const unsigned char *usrce = srce; - - while (count-- != 0) { - *udest++ = os_toebcdic[*usrce++]; - } - - return dest; -} - -#endif diff --git a/Sources/COpenSSL/ebcdic.h b/Sources/COpenSSL/ebcdic.h deleted file mode 100644 index 4cbdfeb7..00000000 --- a/Sources/COpenSSL/ebcdic.h +++ /dev/null @@ -1,26 +0,0 @@ -/* crypto/ebcdic.h */ - -#ifndef HEADER_EBCDIC_H -# define HEADER_EBCDIC_H - -# include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Avoid name clashes with other applications */ -# define os_toascii _openssl_os_toascii -# define os_toebcdic _openssl_os_toebcdic -# define ebcdic2ascii _openssl_ebcdic2ascii -# define ascii2ebcdic _openssl_ascii2ebcdic - -extern const unsigned char os_toascii[256]; -extern const unsigned char os_toebcdic[256]; -void *ebcdic2ascii(void *dest, const void *srce, size_t count); -void *ascii2ebcdic(void *dest, const void *srce, size_t count); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ec.h b/Sources/COpenSSL/ec.h deleted file mode 100644 index e490c7aa..00000000 --- a/Sources/COpenSSL/ec.h +++ /dev/null @@ -1,1282 +0,0 @@ -/* crypto/ec/ec.h */ -/* - * Originally written by Bodo Moeller for the OpenSSL project. - */ -/** - * \file crypto/ec/ec.h Include file for the OpenSSL EC functions - * \author Originally written by Bodo Moeller for the OpenSSL project - */ -/* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * The elliptic curve binary polynomial software is originally written by - * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. - * - */ - -#ifndef HEADER_EC_H -# define HEADER_EC_H - -# include "opensslconf.h" - -# ifdef OPENSSL_NO_EC -# error EC is disabled. -# endif - -# include "asn1.h" -# include "symhacks.h" -# ifndef OPENSSL_NO_DEPRECATED -# include "bn.h" -# endif - -# ifdef __cplusplus -extern "C" { -# elif defined(__SUNPRO_C) -# if __SUNPRO_C >= 0x520 -# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) -# endif -# endif - -# ifndef OPENSSL_ECC_MAX_FIELD_BITS -# define OPENSSL_ECC_MAX_FIELD_BITS 661 -# endif - -/** Enum for the point conversion form as defined in X9.62 (ECDSA) - * for the encoding of a elliptic curve point (x,y) */ -typedef enum { - /** the point is encoded as z||x, where the octet z specifies - * which solution of the quadratic equation y is */ - POINT_CONVERSION_COMPRESSED = 2, - /** the point is encoded as z||x||y, where z is the octet 0x04 */ - POINT_CONVERSION_UNCOMPRESSED = 4, - /** the point is encoded as z||x||y, where the octet z specifies - * which solution of the quadratic equation y is */ - POINT_CONVERSION_HYBRID = 6 -} point_conversion_form_t; - -typedef struct ec_method_st EC_METHOD; - -typedef struct ec_group_st - /*- - EC_METHOD *meth; - -- field definition - -- curve coefficients - -- optional generator with associated information (order, cofactor) - -- optional extra data (precomputed table for fast computation of multiples of generator) - -- ASN1 stuff - */ - EC_GROUP; - -typedef struct ec_point_st EC_POINT; - -/********************************************************************/ -/* EC_METHODs for curves over GF(p) */ -/********************************************************************/ - -/** Returns the basic GFp ec methods which provides the basis for the - * optimized methods. - * \return EC_METHOD object - */ -const EC_METHOD *EC_GFp_simple_method(void); - -/** Returns GFp methods using montgomery multiplication. - * \return EC_METHOD object - */ -const EC_METHOD *EC_GFp_mont_method(void); - -/** Returns GFp methods using optimized methods for NIST recommended curves - * \return EC_METHOD object - */ -const EC_METHOD *EC_GFp_nist_method(void); - -# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 -/** Returns 64-bit optimized methods for nistp224 - * \return EC_METHOD object - */ -const EC_METHOD *EC_GFp_nistp224_method(void); - -/** Returns 64-bit optimized methods for nistp256 - * \return EC_METHOD object - */ -const EC_METHOD *EC_GFp_nistp256_method(void); - -/** Returns 64-bit optimized methods for nistp521 - * \return EC_METHOD object - */ -const EC_METHOD *EC_GFp_nistp521_method(void); -# endif - -# ifndef OPENSSL_NO_EC2M -/********************************************************************/ -/* EC_METHOD for curves over GF(2^m) */ -/********************************************************************/ - -/** Returns the basic GF2m ec method - * \return EC_METHOD object - */ -const EC_METHOD *EC_GF2m_simple_method(void); - -# endif - -/********************************************************************/ -/* EC_GROUP functions */ -/********************************************************************/ - -/** Creates a new EC_GROUP object - * \param meth EC_METHOD to use - * \return newly created EC_GROUP object or NULL in case of an error. - */ -EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); - -/** Frees a EC_GROUP object - * \param group EC_GROUP object to be freed. - */ -void EC_GROUP_free(EC_GROUP *group); - -/** Clears and frees a EC_GROUP object - * \param group EC_GROUP object to be cleared and freed. - */ -void EC_GROUP_clear_free(EC_GROUP *group); - -/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. - * \param dst destination EC_GROUP object - * \param src source EC_GROUP object - * \return 1 on success and 0 if an error occurred. - */ -int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); - -/** Creates a new EC_GROUP object and copies the copies the content - * form src to the newly created EC_KEY object - * \param src source EC_GROUP object - * \return newly created EC_GROUP object or NULL in case of an error. - */ -EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); - -/** Returns the EC_METHOD of the EC_GROUP object. - * \param group EC_GROUP object - * \return EC_METHOD used in this EC_GROUP object. - */ -const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); - -/** Returns the field type of the EC_METHOD. - * \param meth EC_METHOD object - * \return NID of the underlying field type OID. - */ -int EC_METHOD_get_field_type(const EC_METHOD *meth); - -/** Sets the generator and it's order/cofactor of a EC_GROUP object. - * \param group EC_GROUP object - * \param generator EC_POINT object with the generator. - * \param order the order of the group generated by the generator. - * \param cofactor the index of the sub-group generated by the generator - * in the group of all points on the elliptic curve. - * \return 1 on success and 0 if an error occured - */ -int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, - const BIGNUM *order, const BIGNUM *cofactor); - -/** Returns the generator of a EC_GROUP object. - * \param group EC_GROUP object - * \return the currently used generator (possibly NULL). - */ -const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); - -/** Returns the montgomery data for order(Generator) - * \param group EC_GROUP object - * \return the currently used generator (possibly NULL). -*/ -BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group); - -/** Gets the order of a EC_GROUP - * \param group EC_GROUP object - * \param order BIGNUM to which the order is copied - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); - -/** Gets the cofactor of a EC_GROUP - * \param group EC_GROUP object - * \param cofactor BIGNUM to which the cofactor is copied - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, - BN_CTX *ctx); - -/** Sets the name of a EC_GROUP object - * \param group EC_GROUP object - * \param nid NID of the curve name OID - */ -void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); - -/** Returns the curve name of a EC_GROUP object - * \param group EC_GROUP object - * \return NID of the curve name OID or 0 if not set. - */ -int EC_GROUP_get_curve_name(const EC_GROUP *group); - -void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); -int EC_GROUP_get_asn1_flag(const EC_GROUP *group); - -void EC_GROUP_set_point_conversion_form(EC_GROUP *group, - point_conversion_form_t form); -point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); - -unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); -size_t EC_GROUP_get_seed_len(const EC_GROUP *); -size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); - -/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b - * \param group EC_GROUP object - * \param p BIGNUM with the prime number - * \param a BIGNUM with parameter a of the equation - * \param b BIGNUM with parameter b of the equation - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx); - -/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b - * \param group EC_GROUP object - * \param p BIGNUM for the prime number - * \param a BIGNUM for parameter a of the equation - * \param b BIGNUM for parameter b of the equation - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *ctx); - -# ifndef OPENSSL_NO_EC2M -/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b - * \param group EC_GROUP object - * \param p BIGNUM with the polynomial defining the underlying field - * \param a BIGNUM with parameter a of the equation - * \param b BIGNUM with parameter b of the equation - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx); - -/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b - * \param group EC_GROUP object - * \param p BIGNUM for the polynomial defining the underlying field - * \param a BIGNUM for parameter a of the equation - * \param b BIGNUM for parameter b of the equation - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *ctx); -# endif -/** Returns the number of bits needed to represent a field element - * \param group EC_GROUP object - * \return number of bits needed to represent a field element - */ -int EC_GROUP_get_degree(const EC_GROUP *group); - -/** Checks whether the parameter in the EC_GROUP define a valid ec group - * \param group EC_GROUP object - * \param ctx BN_CTX object (optional) - * \return 1 if group is a valid ec group and 0 otherwise - */ -int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); - -/** Checks whether the discriminant of the elliptic curve is zero or not - * \param group EC_GROUP object - * \param ctx BN_CTX object (optional) - * \return 1 if the discriminant is not zero and 0 otherwise - */ -int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); - -/** Compares two EC_GROUP objects - * \param a first EC_GROUP object - * \param b second EC_GROUP object - * \param ctx BN_CTX object (optional) - * \return 0 if both groups are equal and 1 otherwise - */ -int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); - -/* - * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after - * choosing an appropriate EC_METHOD - */ - -/** Creates a new EC_GROUP object with the specified parameters defined - * over GFp (defined by the equation y^2 = x^3 + a*x + b) - * \param p BIGNUM with the prime number - * \param a BIGNUM with the parameter a of the equation - * \param b BIGNUM with the parameter b of the equation - * \param ctx BN_CTX object (optional) - * \return newly created EC_GROUP object with the specified parameters - */ -EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx); -# ifndef OPENSSL_NO_EC2M -/** Creates a new EC_GROUP object with the specified parameters defined - * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) - * \param p BIGNUM with the polynomial defining the underlying field - * \param a BIGNUM with the parameter a of the equation - * \param b BIGNUM with the parameter b of the equation - * \param ctx BN_CTX object (optional) - * \return newly created EC_GROUP object with the specified parameters - */ -EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx); -# endif -/** Creates a EC_GROUP object with a curve specified by a NID - * \param nid NID of the OID of the curve name - * \return newly created EC_GROUP object with specified curve or NULL - * if an error occurred - */ -EC_GROUP *EC_GROUP_new_by_curve_name(int nid); - -/********************************************************************/ -/* handling of internal curves */ -/********************************************************************/ - -typedef struct { - int nid; - const char *comment; -} EC_builtin_curve; - -/* - * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all - * available curves or zero if a error occurred. In case r ist not zero - * nitems EC_builtin_curve structures are filled with the data of the first - * nitems internal groups - */ -size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); - -const char *EC_curve_nid2nist(int nid); -int EC_curve_nist2nid(const char *name); - -/********************************************************************/ -/* EC_POINT functions */ -/********************************************************************/ - -/** Creates a new EC_POINT object for the specified EC_GROUP - * \param group EC_GROUP the underlying EC_GROUP object - * \return newly created EC_POINT object or NULL if an error occurred - */ -EC_POINT *EC_POINT_new(const EC_GROUP *group); - -/** Frees a EC_POINT object - * \param point EC_POINT object to be freed - */ -void EC_POINT_free(EC_POINT *point); - -/** Clears and frees a EC_POINT object - * \param point EC_POINT object to be cleared and freed - */ -void EC_POINT_clear_free(EC_POINT *point); - -/** Copies EC_POINT object - * \param dst destination EC_POINT object - * \param src source EC_POINT object - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); - -/** Creates a new EC_POINT object and copies the content of the supplied - * EC_POINT - * \param src source EC_POINT object - * \param group underlying the EC_GROUP object - * \return newly created EC_POINT object or NULL if an error occurred - */ -EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); - -/** Returns the EC_METHOD used in EC_POINT object - * \param point EC_POINT object - * \return the EC_METHOD used - */ -const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); - -/** Sets a point to infinity (neutral element) - * \param group underlying EC_GROUP object - * \param point EC_POINT to set to infinity - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); - -/** Sets the jacobian projective coordinates of a EC_POINT over GFp - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param x BIGNUM with the x-coordinate - * \param y BIGNUM with the y-coordinate - * \param z BIGNUM with the z-coordinate - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, - EC_POINT *p, const BIGNUM *x, - const BIGNUM *y, const BIGNUM *z, - BN_CTX *ctx); - -/** Gets the jacobian projective coordinates of a EC_POINT over GFp - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param x BIGNUM for the x-coordinate - * \param y BIGNUM for the y-coordinate - * \param z BIGNUM for the z-coordinate - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, - const EC_POINT *p, BIGNUM *x, - BIGNUM *y, BIGNUM *z, - BN_CTX *ctx); - -/** Sets the affine coordinates of a EC_POINT over GFp - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param x BIGNUM with the x-coordinate - * \param y BIGNUM with the y-coordinate - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, - const BIGNUM *x, const BIGNUM *y, - BN_CTX *ctx); - -/** Gets the affine coordinates of a EC_POINT over GFp - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param x BIGNUM for the x-coordinate - * \param y BIGNUM for the y-coordinate - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, - const EC_POINT *p, BIGNUM *x, - BIGNUM *y, BN_CTX *ctx); - -/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param x BIGNUM with x-coordinate - * \param y_bit integer with the y-Bit (either 0 or 1) - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, - EC_POINT *p, const BIGNUM *x, - int y_bit, BN_CTX *ctx); -# ifndef OPENSSL_NO_EC2M -/** Sets the affine coordinates of a EC_POINT over GF2m - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param x BIGNUM with the x-coordinate - * \param y BIGNUM with the y-coordinate - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, - const BIGNUM *x, const BIGNUM *y, - BN_CTX *ctx); - -/** Gets the affine coordinates of a EC_POINT over GF2m - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param x BIGNUM for the x-coordinate - * \param y BIGNUM for the y-coordinate - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, - const EC_POINT *p, BIGNUM *x, - BIGNUM *y, BN_CTX *ctx); - -/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param x BIGNUM with x-coordinate - * \param y_bit integer with the y-Bit (either 0 or 1) - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, - EC_POINT *p, const BIGNUM *x, - int y_bit, BN_CTX *ctx); -# endif -/** Encodes a EC_POINT object to a octet string - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param form point conversion form - * \param buf memory buffer for the result. If NULL the function returns - * required buffer size. - * \param len length of the memory buffer - * \param ctx BN_CTX object (optional) - * \return the length of the encoded octet string or 0 if an error occurred - */ -size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *ctx); - -/** Decodes a EC_POINT from a octet string - * \param group underlying EC_GROUP object - * \param p EC_POINT object - * \param buf memory buffer with the encoded ec point - * \param len length of the encoded ec point - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, - const unsigned char *buf, size_t len, BN_CTX *ctx); - -/* other interfaces to point2oct/oct2point: */ -BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, BIGNUM *, BN_CTX *); -EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, - EC_POINT *, BN_CTX *); -char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, BN_CTX *); -EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, - EC_POINT *, BN_CTX *); - -/********************************************************************/ -/* functions for doing EC_POINT arithmetic */ -/********************************************************************/ - -/** Computes the sum of two EC_POINT - * \param group underlying EC_GROUP object - * \param r EC_POINT object for the result (r = a + b) - * \param a EC_POINT object with the first summand - * \param b EC_POINT object with the second summand - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx); - -/** Computes the double of a EC_POINT - * \param group underlying EC_GROUP object - * \param r EC_POINT object for the result (r = 2 * a) - * \param a EC_POINT object - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - BN_CTX *ctx); - -/** Computes the inverse of a EC_POINT - * \param group underlying EC_GROUP object - * \param a EC_POINT object to be inverted (it's used for the result as well) - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); - -/** Checks whether the point is the neutral element of the group - * \param group the underlying EC_GROUP object - * \param p EC_POINT object - * \return 1 if the point is the neutral element and 0 otherwise - */ -int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); - -/** Checks whether the point is on the curve - * \param group underlying EC_GROUP object - * \param point EC_POINT object to check - * \param ctx BN_CTX object (optional) - * \return 1 if point if on the curve and 0 otherwise - */ -int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, - BN_CTX *ctx); - -/** Compares two EC_POINTs - * \param group underlying EC_GROUP object - * \param a first EC_POINT object - * \param b second EC_POINT object - * \param ctx BN_CTX object (optional) - * \return 0 if both points are equal and a value != 0 otherwise - */ -int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, - BN_CTX *ctx); - -int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); -int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, - EC_POINT *points[], BN_CTX *ctx); - -/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i] - * \param group underlying EC_GROUP object - * \param r EC_POINT object for the result - * \param n BIGNUM with the multiplier for the group generator (optional) - * \param num number futher summands - * \param p array of size num of EC_POINT objects - * \param m array of size num of BIGNUM objects - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, - size_t num, const EC_POINT *p[], const BIGNUM *m[], - BN_CTX *ctx); - -/** Computes r = generator * n + q * m - * \param group underlying EC_GROUP object - * \param r EC_POINT object for the result - * \param n BIGNUM with the multiplier for the group generator (optional) - * \param q EC_POINT object with the first factor of the second summand - * \param m BIGNUM with the second factor of the second summand - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, - const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); - -/** Stores multiples of generator for faster point multiplication - * \param group EC_GROUP object - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occured - */ -int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); - -/** Reports whether a precomputation has been done - * \param group EC_GROUP object - * \return 1 if a pre-computation has been done and 0 otherwise - */ -int EC_GROUP_have_precompute_mult(const EC_GROUP *group); - -/********************************************************************/ -/* ASN1 stuff */ -/********************************************************************/ - -/* - * EC_GROUP_get_basis_type() returns the NID of the basis type used to - * represent the field elements - */ -int EC_GROUP_get_basis_type(const EC_GROUP *); -# ifndef OPENSSL_NO_EC2M -int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); -int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, - unsigned int *k2, unsigned int *k3); -# endif - -# define OPENSSL_EC_NAMED_CURVE 0x001 - -typedef struct ecpk_parameters_st ECPKPARAMETERS; - -EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); -int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); - -# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) -# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) -# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ - (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) -# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ - (unsigned char *)(x)) - -# ifndef OPENSSL_NO_BIO -int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); -# endif -# ifndef OPENSSL_NO_FP_API -int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); -# endif - -/********************************************************************/ -/* EC_KEY functions */ -/********************************************************************/ - -typedef struct ec_key_st EC_KEY; - -/* some values for the encoding_flag */ -# define EC_PKEY_NO_PARAMETERS 0x001 -# define EC_PKEY_NO_PUBKEY 0x002 - -/* some values for the flags field */ -# define EC_FLAG_NON_FIPS_ALLOW 0x1 -# define EC_FLAG_FIPS_CHECKED 0x2 - -/** Creates a new EC_KEY object. - * \return EC_KEY object or NULL if an error occurred. - */ -EC_KEY *EC_KEY_new(void); - -int EC_KEY_get_flags(const EC_KEY *key); - -void EC_KEY_set_flags(EC_KEY *key, int flags); - -void EC_KEY_clear_flags(EC_KEY *key, int flags); - -/** Creates a new EC_KEY object using a named curve as underlying - * EC_GROUP object. - * \param nid NID of the named curve. - * \return EC_KEY object or NULL if an error occurred. - */ -EC_KEY *EC_KEY_new_by_curve_name(int nid); - -/** Frees a EC_KEY object. - * \param key EC_KEY object to be freed. - */ -void EC_KEY_free(EC_KEY *key); - -/** Copies a EC_KEY object. - * \param dst destination EC_KEY object - * \param src src EC_KEY object - * \return dst or NULL if an error occurred. - */ -EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); - -/** Creates a new EC_KEY object and copies the content from src to it. - * \param src the source EC_KEY object - * \return newly created EC_KEY object or NULL if an error occurred. - */ -EC_KEY *EC_KEY_dup(const EC_KEY *src); - -/** Increases the internal reference count of a EC_KEY object. - * \param key EC_KEY object - * \return 1 on success and 0 if an error occurred. - */ -int EC_KEY_up_ref(EC_KEY *key); - -/** Returns the EC_GROUP object of a EC_KEY object - * \param key EC_KEY object - * \return the EC_GROUP object (possibly NULL). - */ -const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); - -/** Sets the EC_GROUP of a EC_KEY object. - * \param key EC_KEY object - * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY - * object will use an own copy of the EC_GROUP). - * \return 1 on success and 0 if an error occurred. - */ -int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); - -/** Returns the private key of a EC_KEY object. - * \param key EC_KEY object - * \return a BIGNUM with the private key (possibly NULL). - */ -const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); - -/** Sets the private key of a EC_KEY object. - * \param key EC_KEY object - * \param prv BIGNUM with the private key (note: the EC_KEY object - * will use an own copy of the BIGNUM). - * \return 1 on success and 0 if an error occurred. - */ -int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); - -/** Returns the public key of a EC_KEY object. - * \param key the EC_KEY object - * \return a EC_POINT object with the public key (possibly NULL) - */ -const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); - -/** Sets the public key of a EC_KEY object. - * \param key EC_KEY object - * \param pub EC_POINT object with the public key (note: the EC_KEY object - * will use an own copy of the EC_POINT object). - * \return 1 on success and 0 if an error occurred. - */ -int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); - -unsigned EC_KEY_get_enc_flags(const EC_KEY *key); -void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); -point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); -void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); -/* functions to set/get method specific data */ -void *EC_KEY_get_key_method_data(EC_KEY *key, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)); -/** Sets the key method data of an EC_KEY object, if none has yet been set. - * \param key EC_KEY object - * \param data opaque data to install. - * \param dup_func a function that duplicates |data|. - * \param free_func a function that frees |data|. - * \param clear_free_func a function that wipes and frees |data|. - * \return the previously set data pointer, or NULL if |data| was inserted. - */ -void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)); -/* wrapper functions for the underlying EC_GROUP object */ -void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); - -/** Creates a table of pre-computed multiples of the generator to - * accelerate further EC_KEY operations. - * \param key EC_KEY object - * \param ctx BN_CTX object (optional) - * \return 1 on success and 0 if an error occurred. - */ -int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); - -/** Creates a new ec private (and optional a new public) key. - * \param key EC_KEY object - * \return 1 on success and 0 if an error occurred. - */ -int EC_KEY_generate_key(EC_KEY *key); - -/** Verifies that a private and/or public key is valid. - * \param key the EC_KEY object - * \return 1 on success and 0 otherwise. - */ -int EC_KEY_check_key(const EC_KEY *key); - -/** Sets a public key from affine coordindates performing - * neccessary NIST PKV tests. - * \param key the EC_KEY object - * \param x public key x coordinate - * \param y public key y coordinate - * \return 1 on success and 0 otherwise. - */ -int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, - BIGNUM *y); - -/********************************************************************/ -/* de- and encoding functions for SEC1 ECPrivateKey */ -/********************************************************************/ - -/** Decodes a private key from a memory buffer. - * \param key a pointer to a EC_KEY object which should be used (or NULL) - * \param in pointer to memory with the DER encoded private key - * \param len length of the DER encoded private key - * \return the decoded private key or NULL if an error occurred. - */ -EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); - -/** Encodes a private key object and stores the result in a buffer. - * \param key the EC_KEY object to encode - * \param out the buffer for the result (if NULL the function returns number - * of bytes needed). - * \return 1 on success and 0 if an error occurred. - */ -int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); - -/********************************************************************/ -/* de- and encoding functions for EC parameters */ -/********************************************************************/ - -/** Decodes ec parameter from a memory buffer. - * \param key a pointer to a EC_KEY object which should be used (or NULL) - * \param in pointer to memory with the DER encoded ec parameters - * \param len length of the DER encoded ec parameters - * \return a EC_KEY object with the decoded parameters or NULL if an error - * occurred. - */ -EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); - -/** Encodes ec parameter and stores the result in a buffer. - * \param key the EC_KEY object with ec paramters to encode - * \param out the buffer for the result (if NULL the function returns number - * of bytes needed). - * \return 1 on success and 0 if an error occurred. - */ -int i2d_ECParameters(EC_KEY *key, unsigned char **out); - -/********************************************************************/ -/* de- and encoding functions for EC public key */ -/* (octet string, not DER -- hence 'o2i' and 'i2o') */ -/********************************************************************/ - -/** Decodes a ec public key from a octet string. - * \param key a pointer to a EC_KEY object which should be used - * \param in memory buffer with the encoded public key - * \param len length of the encoded public key - * \return EC_KEY object with decoded public key or NULL if an error - * occurred. - */ -EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); - -/** Encodes a ec public key in an octet string. - * \param key the EC_KEY object with the public key - * \param out the buffer for the result (if NULL the function returns number - * of bytes needed). - * \return 1 on success and 0 if an error occurred - */ -int i2o_ECPublicKey(EC_KEY *key, unsigned char **out); - -# ifndef OPENSSL_NO_BIO -/** Prints out the ec parameters on human readable form. - * \param bp BIO object to which the information is printed - * \param key EC_KEY object - * \return 1 on success and 0 if an error occurred - */ -int ECParameters_print(BIO *bp, const EC_KEY *key); - -/** Prints out the contents of a EC_KEY object - * \param bp BIO object to which the information is printed - * \param key EC_KEY object - * \param off line offset - * \return 1 on success and 0 if an error occurred - */ -int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); - -# endif -# ifndef OPENSSL_NO_FP_API -/** Prints out the ec parameters on human readable form. - * \param fp file descriptor to which the information is printed - * \param key EC_KEY object - * \return 1 on success and 0 if an error occurred - */ -int ECParameters_print_fp(FILE *fp, const EC_KEY *key); - -/** Prints out the contents of a EC_KEY object - * \param fp file descriptor to which the information is printed - * \param key EC_KEY object - * \param off line offset - * \return 1 on success and 0 if an error occurred - */ -int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); - -# endif - -# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) - -# ifndef __cplusplus -# if defined(__SUNPRO_C) -# if __SUNPRO_C >= 0x520 -# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) -# endif -# endif -# endif - -# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ - EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) - -# define EVP_PKEY_CTX_set_ec_param_enc(ctx, flag) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_PARAMGEN|EVP_PKEY_OP_KEYGEN, \ - EVP_PKEY_CTRL_EC_PARAM_ENC, flag, NULL) - -# define EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, flag) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_EC_ECDH_COFACTOR, flag, NULL) - -# define EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_EC_ECDH_COFACTOR, -2, NULL) - -# define EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, kdf) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_EC_KDF_TYPE, kdf, NULL) - -# define EVP_PKEY_CTX_get_ecdh_kdf_type(ctx) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_EC_KDF_TYPE, -2, NULL) - -# define EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_EC_KDF_MD, 0, (void *)md) - -# define EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, pmd) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_EC_KDF_MD, 0, (void *)pmd) - -# define EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, len) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_EC_KDF_OUTLEN, len, NULL) - -# define EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, plen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN, 0, (void *)plen) - -# define EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p, plen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_EC_KDF_UKM, plen, (void *)p) - -# define EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, \ - EVP_PKEY_OP_DERIVE, \ - EVP_PKEY_CTRL_GET_EC_KDF_UKM, 0, (void *)p) - -# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) -# define EVP_PKEY_CTRL_EC_PARAM_ENC (EVP_PKEY_ALG_CTRL + 2) -# define EVP_PKEY_CTRL_EC_ECDH_COFACTOR (EVP_PKEY_ALG_CTRL + 3) -# define EVP_PKEY_CTRL_EC_KDF_TYPE (EVP_PKEY_ALG_CTRL + 4) -# define EVP_PKEY_CTRL_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 5) -# define EVP_PKEY_CTRL_GET_EC_KDF_MD (EVP_PKEY_ALG_CTRL + 6) -# define EVP_PKEY_CTRL_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 7) -# define EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN (EVP_PKEY_ALG_CTRL + 8) -# define EVP_PKEY_CTRL_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 9) -# define EVP_PKEY_CTRL_GET_EC_KDF_UKM (EVP_PKEY_ALG_CTRL + 10) -/* KDF types */ -# define EVP_PKEY_ECDH_KDF_NONE 1 -# define EVP_PKEY_ECDH_KDF_X9_62 2 - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_EC_strings(void); - -/* Error codes for the EC functions. */ - -/* Function codes. */ -# define EC_F_BN_TO_FELEM 224 -# define EC_F_COMPUTE_WNAF 143 -# define EC_F_D2I_ECPARAMETERS 144 -# define EC_F_D2I_ECPKPARAMETERS 145 -# define EC_F_D2I_ECPRIVATEKEY 146 -# define EC_F_DO_EC_KEY_PRINT 221 -# define EC_F_ECDH_CMS_DECRYPT 238 -# define EC_F_ECDH_CMS_SET_SHARED_INFO 239 -# define EC_F_ECKEY_PARAM2TYPE 223 -# define EC_F_ECKEY_PARAM_DECODE 212 -# define EC_F_ECKEY_PRIV_DECODE 213 -# define EC_F_ECKEY_PRIV_ENCODE 214 -# define EC_F_ECKEY_PUB_DECODE 215 -# define EC_F_ECKEY_PUB_ENCODE 216 -# define EC_F_ECKEY_TYPE2PARAM 220 -# define EC_F_ECPARAMETERS_PRINT 147 -# define EC_F_ECPARAMETERS_PRINT_FP 148 -# define EC_F_ECPKPARAMETERS_PRINT 149 -# define EC_F_ECPKPARAMETERS_PRINT_FP 150 -# define EC_F_ECP_NISTZ256_GET_AFFINE 240 -# define EC_F_ECP_NISTZ256_MULT_PRECOMPUTE 243 -# define EC_F_ECP_NISTZ256_POINTS_MUL 241 -# define EC_F_ECP_NISTZ256_PRE_COMP_NEW 244 -# define EC_F_ECP_NISTZ256_SET_WORDS 245 -# define EC_F_ECP_NISTZ256_WINDOWED_MUL 242 -# define EC_F_ECP_NIST_MOD_192 203 -# define EC_F_ECP_NIST_MOD_224 204 -# define EC_F_ECP_NIST_MOD_256 205 -# define EC_F_ECP_NIST_MOD_521 206 -# define EC_F_EC_ASN1_GROUP2CURVE 153 -# define EC_F_EC_ASN1_GROUP2FIELDID 154 -# define EC_F_EC_ASN1_GROUP2PARAMETERS 155 -# define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156 -# define EC_F_EC_ASN1_PARAMETERS2GROUP 157 -# define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158 -# define EC_F_EC_EX_DATA_SET_DATA 211 -# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 -# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 -# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 -# define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 -# define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 -# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 -# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 -# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 -# define EC_F_EC_GFP_MONT_FIELD_DECODE 133 -# define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 -# define EC_F_EC_GFP_MONT_FIELD_MUL 131 -# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 -# define EC_F_EC_GFP_MONT_FIELD_SQR 132 -# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 -# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135 -# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 -# define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 -# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 -# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 -# define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 -# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 -# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 -# define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 -# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 -# define EC_F_EC_GFP_NIST_FIELD_MUL 200 -# define EC_F_EC_GFP_NIST_FIELD_SQR 201 -# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 -# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 -# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 -# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 -# define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 -# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 -# define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 -# define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 -# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 -# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 -# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 -# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 -# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 -# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 -# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 -# define EC_F_EC_GROUP_CHECK 170 -# define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 -# define EC_F_EC_GROUP_COPY 106 -# define EC_F_EC_GROUP_GET0_GENERATOR 139 -# define EC_F_EC_GROUP_GET_COFACTOR 140 -# define EC_F_EC_GROUP_GET_CURVE_GF2M 172 -# define EC_F_EC_GROUP_GET_CURVE_GFP 130 -# define EC_F_EC_GROUP_GET_DEGREE 173 -# define EC_F_EC_GROUP_GET_ORDER 141 -# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 -# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 -# define EC_F_EC_GROUP_NEW 108 -# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 -# define EC_F_EC_GROUP_NEW_FROM_DATA 175 -# define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 -# define EC_F_EC_GROUP_SET_CURVE_GF2M 176 -# define EC_F_EC_GROUP_SET_CURVE_GFP 109 -# define EC_F_EC_GROUP_SET_EXTRA_DATA 110 -# define EC_F_EC_GROUP_SET_GENERATOR 111 -# define EC_F_EC_KEY_CHECK_KEY 177 -# define EC_F_EC_KEY_COPY 178 -# define EC_F_EC_KEY_GENERATE_KEY 179 -# define EC_F_EC_KEY_NEW 182 -# define EC_F_EC_KEY_PRINT 180 -# define EC_F_EC_KEY_PRINT_FP 181 -# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 -# define EC_F_EC_POINTS_MAKE_AFFINE 136 -# define EC_F_EC_POINT_ADD 112 -# define EC_F_EC_POINT_CMP 113 -# define EC_F_EC_POINT_COPY 114 -# define EC_F_EC_POINT_DBL 115 -# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 -# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 -# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 -# define EC_F_EC_POINT_INVERT 210 -# define EC_F_EC_POINT_IS_AT_INFINITY 118 -# define EC_F_EC_POINT_IS_ON_CURVE 119 -# define EC_F_EC_POINT_MAKE_AFFINE 120 -# define EC_F_EC_POINT_MUL 184 -# define EC_F_EC_POINT_NEW 121 -# define EC_F_EC_POINT_OCT2POINT 122 -# define EC_F_EC_POINT_POINT2OCT 123 -# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 -# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 -# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 -# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 -# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 -# define EC_F_EC_POINT_SET_TO_INFINITY 127 -# define EC_F_EC_PRE_COMP_DUP 207 -# define EC_F_EC_PRE_COMP_NEW 196 -# define EC_F_EC_WNAF_MUL 187 -# define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 -# define EC_F_I2D_ECPARAMETERS 190 -# define EC_F_I2D_ECPKPARAMETERS 191 -# define EC_F_I2D_ECPRIVATEKEY 192 -# define EC_F_I2O_ECPUBLICKEY 151 -# define EC_F_NISTP224_PRE_COMP_NEW 227 -# define EC_F_NISTP256_PRE_COMP_NEW 236 -# define EC_F_NISTP521_PRE_COMP_NEW 237 -# define EC_F_O2I_ECPUBLICKEY 152 -# define EC_F_OLD_EC_PRIV_DECODE 222 -# define EC_F_PKEY_EC_CTRL 197 -# define EC_F_PKEY_EC_CTRL_STR 198 -# define EC_F_PKEY_EC_DERIVE 217 -# define EC_F_PKEY_EC_KEYGEN 199 -# define EC_F_PKEY_EC_PARAMGEN 219 -# define EC_F_PKEY_EC_SIGN 218 - -/* Reason codes. */ -# define EC_R_ASN1_ERROR 115 -# define EC_R_ASN1_UNKNOWN_FIELD 116 -# define EC_R_BIGNUM_OUT_OF_RANGE 144 -# define EC_R_BUFFER_TOO_SMALL 100 -# define EC_R_COORDINATES_OUT_OF_RANGE 146 -# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 -# define EC_R_DECODE_ERROR 142 -# define EC_R_DISCRIMINANT_IS_ZERO 118 -# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 -# define EC_R_FIELD_TOO_LARGE 143 -# define EC_R_GF2M_NOT_SUPPORTED 147 -# define EC_R_GROUP2PKPARAMETERS_FAILURE 120 -# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 -# define EC_R_INCOMPATIBLE_OBJECTS 101 -# define EC_R_INVALID_ARGUMENT 112 -# define EC_R_INVALID_COMPRESSED_POINT 110 -# define EC_R_INVALID_COMPRESSION_BIT 109 -# define EC_R_INVALID_CURVE 141 -# define EC_R_INVALID_DIGEST 151 -# define EC_R_INVALID_DIGEST_TYPE 138 -# define EC_R_INVALID_ENCODING 102 -# define EC_R_INVALID_FIELD 103 -# define EC_R_INVALID_FORM 104 -# define EC_R_INVALID_GROUP_ORDER 122 -# define EC_R_INVALID_PENTANOMIAL_BASIS 132 -# define EC_R_INVALID_PRIVATE_KEY 123 -# define EC_R_INVALID_TRINOMIAL_BASIS 137 -# define EC_R_KDF_PARAMETER_ERROR 148 -# define EC_R_KEYS_NOT_SET 140 -# define EC_R_MISSING_PARAMETERS 124 -# define EC_R_MISSING_PRIVATE_KEY 125 -# define EC_R_NOT_A_NIST_PRIME 135 -# define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136 -# define EC_R_NOT_IMPLEMENTED 126 -# define EC_R_NOT_INITIALIZED 111 -# define EC_R_NO_FIELD_MOD 133 -# define EC_R_NO_PARAMETERS_SET 139 -# define EC_R_PASSED_NULL_PARAMETER 134 -# define EC_R_PEER_KEY_ERROR 149 -# define EC_R_PKPARAMETERS2GROUP_FAILURE 127 -# define EC_R_POINT_AT_INFINITY 106 -# define EC_R_POINT_IS_NOT_ON_CURVE 107 -# define EC_R_SHARED_INFO_ERROR 150 -# define EC_R_SLOT_FULL 108 -# define EC_R_UNDEFINED_GENERATOR 113 -# define EC_R_UNDEFINED_ORDER 128 -# define EC_R_UNKNOWN_GROUP 129 -# define EC_R_UNKNOWN_ORDER 114 -# define EC_R_UNSUPPORTED_FIELD 131 -# define EC_R_WRONG_CURVE_PARAMETERS 145 -# define EC_R_WRONG_ORDER 130 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ec2_.c b/Sources/COpenSSL/ec2_.c deleted file mode 100644 index 5dcc7db9..00000000 --- a/Sources/COpenSSL/ec2_.c +++ /dev/null @@ -1,1667 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/ec/ec2_mult.c */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * The software is originally written by Sheueling Chang Shantz and - * Douglas Stebila of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "err.h" - -#include "ec_lcl.h" - -#ifndef OPENSSL_NO_EC2M - -/*- - * Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective - * coordinates. - * Uses algorithm Mdouble in appendix of - * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation" (CHES '99, LNCS 1717). - * modified to not require precomputation of c=b^{2^{m-1}}. - */ -static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, - BN_CTX *ctx) -{ - BIGNUM *t1; - int ret = 0; - - /* Since Mdouble is static we can guarantee that ctx != NULL. */ - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - if (t1 == NULL) - goto err; - - if (!group->meth->field_sqr(group, x, x, ctx)) - goto err; - if (!group->meth->field_sqr(group, t1, z, ctx)) - goto err; - if (!group->meth->field_mul(group, z, x, t1, ctx)) - goto err; - if (!group->meth->field_sqr(group, x, x, ctx)) - goto err; - if (!group->meth->field_sqr(group, t1, t1, ctx)) - goto err; - if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) - goto err; - if (!BN_GF2m_add(x, x, t1)) - goto err; - - ret = 1; - - err: - BN_CTX_end(ctx); - return ret; -} - -/*- - * Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery - * projective coordinates. - * Uses algorithm Madd in appendix of - * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation" (CHES '99, LNCS 1717). - */ -static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, - BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2, - BN_CTX *ctx) -{ - BIGNUM *t1, *t2; - int ret = 0; - - /* Since Madd is static we can guarantee that ctx != NULL. */ - BN_CTX_start(ctx); - t1 = BN_CTX_get(ctx); - t2 = BN_CTX_get(ctx); - if (t2 == NULL) - goto err; - - if (!BN_copy(t1, x)) - goto err; - if (!group->meth->field_mul(group, x1, x1, z2, ctx)) - goto err; - if (!group->meth->field_mul(group, z1, z1, x2, ctx)) - goto err; - if (!group->meth->field_mul(group, t2, x1, z1, ctx)) - goto err; - if (!BN_GF2m_add(z1, z1, x1)) - goto err; - if (!group->meth->field_sqr(group, z1, z1, ctx)) - goto err; - if (!group->meth->field_mul(group, x1, z1, t1, ctx)) - goto err; - if (!BN_GF2m_add(x1, x1, t2)) - goto err; - - ret = 1; - - err: - BN_CTX_end(ctx); - return ret; -} - -/*- - * Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) - * using Montgomery point multiplication algorithm Mxy() in appendix of - * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation" (CHES '99, LNCS 1717). - * Returns: - * 0 on error - * 1 if return value should be the point at infinity - * 2 otherwise - */ -static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, - BIGNUM *x1, BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, - BN_CTX *ctx) -{ - BIGNUM *t3, *t4, *t5; - int ret = 0; - - if (BN_is_zero(z1)) { - BN_zero(x2); - BN_zero(z2); - return 1; - } - - if (BN_is_zero(z2)) { - if (!BN_copy(x2, x)) - return 0; - if (!BN_GF2m_add(z2, x, y)) - return 0; - return 2; - } - - /* Since Mxy is static we can guarantee that ctx != NULL. */ - BN_CTX_start(ctx); - t3 = BN_CTX_get(ctx); - t4 = BN_CTX_get(ctx); - t5 = BN_CTX_get(ctx); - if (t5 == NULL) - goto err; - - if (!BN_one(t5)) - goto err; - - if (!group->meth->field_mul(group, t3, z1, z2, ctx)) - goto err; - - if (!group->meth->field_mul(group, z1, z1, x, ctx)) - goto err; - if (!BN_GF2m_add(z1, z1, x1)) - goto err; - if (!group->meth->field_mul(group, z2, z2, x, ctx)) - goto err; - if (!group->meth->field_mul(group, x1, z2, x1, ctx)) - goto err; - if (!BN_GF2m_add(z2, z2, x2)) - goto err; - - if (!group->meth->field_mul(group, z2, z2, z1, ctx)) - goto err; - if (!group->meth->field_sqr(group, t4, x, ctx)) - goto err; - if (!BN_GF2m_add(t4, t4, y)) - goto err; - if (!group->meth->field_mul(group, t4, t4, t3, ctx)) - goto err; - if (!BN_GF2m_add(t4, t4, z2)) - goto err; - - if (!group->meth->field_mul(group, t3, t3, x, ctx)) - goto err; - if (!group->meth->field_div(group, t3, t5, t3, ctx)) - goto err; - if (!group->meth->field_mul(group, t4, t3, t4, ctx)) - goto err; - if (!group->meth->field_mul(group, x2, x1, t3, ctx)) - goto err; - if (!BN_GF2m_add(z2, x2, x)) - goto err; - - if (!group->meth->field_mul(group, z2, z2, t4, ctx)) - goto err; - if (!BN_GF2m_add(z2, z2, y)) - goto err; - - ret = 2; - - err: - BN_CTX_end(ctx); - return ret; -} - -/*- - * Computes scalar*point and stores the result in r. - * point can not equal r. - * Uses a modified algorithm 2P of - * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over - * GF(2^m) without precomputation" (CHES '99, LNCS 1717). - * - * To protect against side-channel attack the function uses constant time swap, - * avoiding conditional branches. - */ -static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, - EC_POINT *r, - const BIGNUM *scalar, - const EC_POINT *point, - BN_CTX *ctx) -{ - BIGNUM *x1, *x2, *z1, *z2; - int ret = 0, i, group_top; - BN_ULONG mask, word; - - if (r == point) { - ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT); - return 0; - } - - /* if result should be point at infinity */ - if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) || - EC_POINT_is_at_infinity(group, point)) { - return EC_POINT_set_to_infinity(group, r); - } - - /* only support affine coordinates */ - if (!point->Z_is_one) - return 0; - - /* - * Since point_multiply is static we can guarantee that ctx != NULL. - */ - BN_CTX_start(ctx); - x1 = BN_CTX_get(ctx); - z1 = BN_CTX_get(ctx); - if (z1 == NULL) - goto err; - - x2 = &r->X; - z2 = &r->Y; - - group_top = group->field.top; - if (bn_wexpand(x1, group_top) == NULL - || bn_wexpand(z1, group_top) == NULL - || bn_wexpand(x2, group_top) == NULL - || bn_wexpand(z2, group_top) == NULL) - goto err; - - if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) - goto err; /* x1 = x */ - if (!BN_one(z1)) - goto err; /* z1 = 1 */ - if (!group->meth->field_sqr(group, z2, x1, ctx)) - goto err; /* z2 = x1^2 = x^2 */ - if (!group->meth->field_sqr(group, x2, z2, ctx)) - goto err; - if (!BN_GF2m_add(x2, x2, &group->b)) - goto err; /* x2 = x^4 + b */ - - /* find top most bit and go one past it */ - i = scalar->top - 1; - mask = BN_TBIT; - word = scalar->d[i]; - while (!(word & mask)) - mask >>= 1; - mask >>= 1; - /* if top most bit was at word break, go to next word */ - if (!mask) { - i--; - mask = BN_TBIT; - } - - for (; i >= 0; i--) { - word = scalar->d[i]; - while (mask) { - BN_consttime_swap(word & mask, x1, x2, group_top); - BN_consttime_swap(word & mask, z1, z2, group_top); - if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) - goto err; - if (!gf2m_Mdouble(group, x1, z1, ctx)) - goto err; - BN_consttime_swap(word & mask, x1, x2, group_top); - BN_consttime_swap(word & mask, z1, z2, group_top); - mask >>= 1; - } - mask = BN_TBIT; - } - - /* convert out of "projective" coordinates */ - i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx); - if (i == 0) - goto err; - else if (i == 1) { - if (!EC_POINT_set_to_infinity(group, r)) - goto err; - } else { - if (!BN_one(&r->Z)) - goto err; - r->Z_is_one = 1; - } - - /* GF(2^m) field elements should always have BIGNUM::neg = 0 */ - BN_set_negative(&r->X, 0); - BN_set_negative(&r->Y, 0); - - ret = 1; - - err: - BN_CTX_end(ctx); - return ret; -} - -/*- - * Computes the sum - * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1] - * gracefully ignoring NULL scalar values. - */ -int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - int ret = 0; - size_t i; - EC_POINT *p = NULL; - EC_POINT *acc = NULL; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - /* - * This implementation is more efficient than the wNAF implementation for - * 2 or fewer points. Use the ec_wNAF_mul implementation for 3 or more - * points, or if we can perform a fast multiplication based on - * precomputation. - */ - if ((scalar && (num > 1)) || (num > 2) - || (num == 0 && EC_GROUP_have_precompute_mult(group))) { - ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); - goto err; - } - - if ((p = EC_POINT_new(group)) == NULL) - goto err; - if ((acc = EC_POINT_new(group)) == NULL) - goto err; - - if (!EC_POINT_set_to_infinity(group, acc)) - goto err; - - if (scalar) { - if (!ec_GF2m_montgomery_point_multiply - (group, p, scalar, group->generator, ctx)) - goto err; - if (BN_is_negative(scalar)) - if (!group->meth->invert(group, p, ctx)) - goto err; - if (!group->meth->add(group, acc, acc, p, ctx)) - goto err; - } - - for (i = 0; i < num; i++) { - if (!ec_GF2m_montgomery_point_multiply - (group, p, scalars[i], points[i], ctx)) - goto err; - if (BN_is_negative(scalars[i])) - if (!group->meth->invert(group, p, ctx)) - goto err; - if (!group->meth->add(group, acc, acc, p, ctx)) - goto err; - } - - if (!EC_POINT_copy(r, acc)) - goto err; - - ret = 1; - - err: - if (p) - EC_POINT_free(p); - if (acc) - EC_POINT_free(acc); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -/* - * Precomputation for point multiplication: fall back to wNAF methods because - * ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate - */ - -int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx) -{ - return ec_wNAF_precompute_mult(group, ctx); -} - -int ec_GF2m_have_precompute_mult(const EC_GROUP *group) -{ - return ec_wNAF_have_precompute_mult(group); -} - -#endif -/* crypto/ec/ec2_oct.c */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * The software is originally written by Sheueling Chang Shantz and - * Douglas Stebila of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "err.h" - -// #include "ec_lcl.h" - -#ifndef OPENSSL_NO_EC2M - -/*- - * Calculates and sets the affine coordinates of an EC_POINT from the given - * compressed coordinates. Uses algorithm 2.3.4 of SEC 1. - * Note that the simple implementation only uses affine coordinates. - * - * The method is from the following publication: - * - * Harper, Menezes, Vanstone: - * "Public-Key Cryptosystems with Very Small Key Lengths", - * EUROCRYPT '92, Springer-Verlag LNCS 658, - * published February 1993 - * - * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe - * the same method, but claim no priority date earlier than July 29, 1994 - * (and additionally fail to cite the EUROCRYPT '92 publication as prior art). - */ -int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x_, int y_bit, - BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - BIGNUM *tmp, *x, *y, *z; - int ret = 0, z0; - - /* clear error queue */ - ERR_clear_error(); - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - y_bit = (y_bit != 0) ? 1 : 0; - - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - z = BN_CTX_get(ctx); - if (z == NULL) - goto err; - - if (!BN_GF2m_mod_arr(x, x_, group->poly)) - goto err; - if (BN_is_zero(x)) { - if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) - goto err; - } else { - if (!group->meth->field_sqr(group, tmp, x, ctx)) - goto err; - if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) - goto err; - if (!BN_GF2m_add(tmp, &group->a, tmp)) - goto err; - if (!BN_GF2m_add(tmp, x, tmp)) - goto err; - if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) { - unsigned long err = ERR_peek_last_error(); - - if (ERR_GET_LIB(err) == ERR_LIB_BN - && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) { - ERR_clear_error(); - ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, - EC_R_INVALID_COMPRESSED_POINT); - } else - ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, - ERR_R_BN_LIB); - goto err; - } - z0 = (BN_is_odd(z)) ? 1 : 0; - if (!group->meth->field_mul(group, y, x, z, ctx)) - goto err; - if (z0 != y_bit) { - if (!BN_GF2m_add(y, y, x)) - goto err; - } - } - - if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) - goto err; - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -/* - * Converts an EC_POINT to an octet string. If buf is NULL, the encoded - * length will be returned. If the length len of buf is smaller than required - * an error will be returned. - */ -size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *ctx) -{ - size_t ret; - BN_CTX *new_ctx = NULL; - int used_ctx = 0; - BIGNUM *x, *y, *yxi; - size_t field_len, i, skip; - - if ((form != POINT_CONVERSION_COMPRESSED) - && (form != POINT_CONVERSION_UNCOMPRESSED) - && (form != POINT_CONVERSION_HYBRID)) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); - goto err; - } - - if (EC_POINT_is_at_infinity(group, point)) { - /* encodes to a single 0 octet */ - if (buf != NULL) { - if (len < 1) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); - return 0; - } - buf[0] = 0; - } - return 1; - } - - /* ret := required output buffer length */ - field_len = (EC_GROUP_get_degree(group) + 7) / 8; - ret = - (form == - POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; - - /* if 'buf' is NULL, just return required length */ - if (buf != NULL) { - if (len < ret) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); - goto err; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - used_ctx = 1; - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - yxi = BN_CTX_get(ctx); - if (yxi == NULL) - goto err; - - if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) - goto err; - - buf[0] = form; - if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) { - if (!group->meth->field_div(group, yxi, y, x, ctx)) - goto err; - if (BN_is_odd(yxi)) - buf[0]++; - } - - i = 1; - - skip = field_len - BN_num_bytes(x); - if (skip > field_len) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); - goto err; - } - while (skip > 0) { - buf[i++] = 0; - skip--; - } - skip = BN_bn2bin(x, buf + i); - i += skip; - if (i != 1 + field_len) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (form == POINT_CONVERSION_UNCOMPRESSED - || form == POINT_CONVERSION_HYBRID) { - skip = field_len - BN_num_bytes(y); - if (skip > field_len) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); - goto err; - } - while (skip > 0) { - buf[i++] = 0; - skip--; - } - skip = BN_bn2bin(y, buf + i); - i += skip; - } - - if (i != ret) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - if (used_ctx) - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; - - err: - if (used_ctx) - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return 0; -} - -/* - * Converts an octet string representation to an EC_POINT. Note that the - * simple implementation only uses affine coordinates. - */ -int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, - const unsigned char *buf, size_t len, - BN_CTX *ctx) -{ - point_conversion_form_t form; - int y_bit; - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y, *yxi; - size_t field_len, enc_len; - int ret = 0; - - if (len == 0) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); - return 0; - } - form = buf[0]; - y_bit = form & 1; - form = form & ~1U; - if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) - && (form != POINT_CONVERSION_UNCOMPRESSED) - && (form != POINT_CONVERSION_HYBRID)) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - return 0; - } - if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - return 0; - } - - if (form == 0) { - if (len != 1) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - return 0; - } - - return EC_POINT_set_to_infinity(group, point); - } - - field_len = (EC_GROUP_get_degree(group) + 7) / 8; - enc_len = - (form == - POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; - - if (len != enc_len) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - return 0; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - yxi = BN_CTX_get(ctx); - if (yxi == NULL) - goto err; - - if (!BN_bin2bn(buf + 1, field_len, x)) - goto err; - if (BN_ucmp(x, &group->field) >= 0) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - goto err; - } - - if (form == POINT_CONVERSION_COMPRESSED) { - if (!EC_POINT_set_compressed_coordinates_GF2m - (group, point, x, y_bit, ctx)) - goto err; - } else { - if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) - goto err; - if (BN_ucmp(y, &group->field) >= 0) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - goto err; - } - if (form == POINT_CONVERSION_HYBRID) { - if (!group->meth->field_div(group, yxi, y, x, ctx)) - goto err; - if (y_bit != BN_is_odd(yxi)) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - goto err; - } - } - - if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) - goto err; - } - - /* test required by X9.62 */ - if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { - ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); - goto err; - } - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} -#endif -/* crypto/ec/ec2_smpl.c */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * The software is originally written by Sheueling Chang Shantz and - * Douglas Stebila of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "err.h" - -// #include "ec_lcl.h" - -#ifndef OPENSSL_NO_EC2M - -# ifdef OPENSSL_FIPS -# include -# endif - -const EC_METHOD *EC_GF2m_simple_method(void) -{ - static const EC_METHOD ret = { - EC_FLAGS_DEFAULT_OCT, - NID_X9_62_characteristic_two_field, - ec_GF2m_simple_group_init, - ec_GF2m_simple_group_finish, - ec_GF2m_simple_group_clear_finish, - ec_GF2m_simple_group_copy, - ec_GF2m_simple_group_set_curve, - ec_GF2m_simple_group_get_curve, - ec_GF2m_simple_group_get_degree, - ec_GF2m_simple_group_check_discriminant, - ec_GF2m_simple_point_init, - ec_GF2m_simple_point_finish, - ec_GF2m_simple_point_clear_finish, - ec_GF2m_simple_point_copy, - ec_GF2m_simple_point_set_to_infinity, - 0 /* set_Jprojective_coordinates_GFp */ , - 0 /* get_Jprojective_coordinates_GFp */ , - ec_GF2m_simple_point_set_affine_coordinates, - ec_GF2m_simple_point_get_affine_coordinates, - 0, 0, 0, - ec_GF2m_simple_add, - ec_GF2m_simple_dbl, - ec_GF2m_simple_invert, - ec_GF2m_simple_is_at_infinity, - ec_GF2m_simple_is_on_curve, - ec_GF2m_simple_cmp, - ec_GF2m_simple_make_affine, - ec_GF2m_simple_points_make_affine, - - /* - * the following three method functions are defined in ec2_mult.c - */ - ec_GF2m_simple_mul, - ec_GF2m_precompute_mult, - ec_GF2m_have_precompute_mult, - - ec_GF2m_simple_field_mul, - ec_GF2m_simple_field_sqr, - ec_GF2m_simple_field_div, - 0 /* field_encode */ , - 0 /* field_decode */ , - 0 /* field_set_to_one */ - }; - -# ifdef OPENSSL_FIPS - if (FIPS_mode()) - return fips_ec_gf2m_simple_method(); -# endif - - return &ret; -} - -/* - * Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members - * are handled by EC_GROUP_new. - */ -int ec_GF2m_simple_group_init(EC_GROUP *group) -{ - BN_init(&group->field); - BN_init(&group->a); - BN_init(&group->b); - return 1; -} - -/* - * Free a GF(2^m)-based EC_GROUP structure. Note that all other members are - * handled by EC_GROUP_free. - */ -void ec_GF2m_simple_group_finish(EC_GROUP *group) -{ - BN_free(&group->field); - BN_free(&group->a); - BN_free(&group->b); -} - -/* - * Clear and free a GF(2^m)-based EC_GROUP structure. Note that all other - * members are handled by EC_GROUP_clear_free. - */ -void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) -{ - BN_clear_free(&group->field); - BN_clear_free(&group->a); - BN_clear_free(&group->b); - group->poly[0] = 0; - group->poly[1] = 0; - group->poly[2] = 0; - group->poly[3] = 0; - group->poly[4] = 0; - group->poly[5] = -1; -} - -/* - * Copy a GF(2^m)-based EC_GROUP structure. Note that all other members are - * handled by EC_GROUP_copy. - */ -int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) -{ - int i; - if (!BN_copy(&dest->field, &src->field)) - return 0; - if (!BN_copy(&dest->a, &src->a)) - return 0; - if (!BN_copy(&dest->b, &src->b)) - return 0; - dest->poly[0] = src->poly[0]; - dest->poly[1] = src->poly[1]; - dest->poly[2] = src->poly[2]; - dest->poly[3] = src->poly[3]; - dest->poly[4] = src->poly[4]; - dest->poly[5] = src->poly[5]; - if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) - == NULL) - return 0; - if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) - == NULL) - return 0; - for (i = dest->a.top; i < dest->a.dmax; i++) - dest->a.d[i] = 0; - for (i = dest->b.top; i < dest->b.dmax; i++) - dest->b.d[i] = 0; - return 1; -} - -/* Set the curve parameters of an EC_GROUP structure. */ -int ec_GF2m_simple_group_set_curve(EC_GROUP *group, - const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - int ret = 0, i; - - /* group->field */ - if (!BN_copy(&group->field, p)) - goto err; - i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1; - if ((i != 5) && (i != 3)) { - ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); - goto err; - } - - /* group->a */ - if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) - goto err; - if (bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) - == NULL) - goto err; - for (i = group->a.top; i < group->a.dmax; i++) - group->a.d[i] = 0; - - /* group->b */ - if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) - goto err; - if (bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) - == NULL) - goto err; - for (i = group->b.top; i < group->b.dmax; i++) - group->b.d[i] = 0; - - ret = 1; - err: - return ret; -} - -/* - * Get the curve parameters of an EC_GROUP structure. If p, a, or b are NULL - * then there values will not be set but the method will return with success. - */ -int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, - BIGNUM *a, BIGNUM *b, BN_CTX *ctx) -{ - int ret = 0; - - if (p != NULL) { - if (!BN_copy(p, &group->field)) - return 0; - } - - if (a != NULL) { - if (!BN_copy(a, &group->a)) - goto err; - } - - if (b != NULL) { - if (!BN_copy(b, &group->b)) - goto err; - } - - ret = 1; - - err: - return ret; -} - -/* - * Gets the degree of the field. For a curve over GF(2^m) this is the value - * m. - */ -int ec_GF2m_simple_group_get_degree(const EC_GROUP *group) -{ - return BN_num_bits(&group->field) - 1; -} - -/* - * Checks the discriminant of the curve. y^2 + x*y = x^3 + a*x^2 + b is an - * elliptic curve <=> b != 0 (mod p) - */ -int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, - BN_CTX *ctx) -{ - int ret = 0; - BIGNUM *b; - BN_CTX *new_ctx = NULL; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) { - ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, - ERR_R_MALLOC_FAILURE); - goto err; - } - } - BN_CTX_start(ctx); - b = BN_CTX_get(ctx); - if (b == NULL) - goto err; - - if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) - goto err; - - /* - * check the discriminant: y^2 + x*y = x^3 + a*x^2 + b is an elliptic - * curve <=> b != 0 (mod p) - */ - if (BN_is_zero(b)) - goto err; - - ret = 1; - - err: - if (ctx != NULL) - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -/* Initializes an EC_POINT. */ -int ec_GF2m_simple_point_init(EC_POINT *point) -{ - BN_init(&point->X); - BN_init(&point->Y); - BN_init(&point->Z); - return 1; -} - -/* Frees an EC_POINT. */ -void ec_GF2m_simple_point_finish(EC_POINT *point) -{ - BN_free(&point->X); - BN_free(&point->Y); - BN_free(&point->Z); -} - -/* Clears and frees an EC_POINT. */ -void ec_GF2m_simple_point_clear_finish(EC_POINT *point) -{ - BN_clear_free(&point->X); - BN_clear_free(&point->Y); - BN_clear_free(&point->Z); - point->Z_is_one = 0; -} - -/* - * Copy the contents of one EC_POINT into another. Assumes dest is - * initialized. - */ -int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) -{ - if (!BN_copy(&dest->X, &src->X)) - return 0; - if (!BN_copy(&dest->Y, &src->Y)) - return 0; - if (!BN_copy(&dest->Z, &src->Z)) - return 0; - dest->Z_is_one = src->Z_is_one; - - return 1; -} - -/* - * Set an EC_POINT to the point at infinity. A point at infinity is - * represented by having Z=0. - */ -int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, - EC_POINT *point) -{ - point->Z_is_one = 0; - BN_zero(&point->Z); - return 1; -} - -/* - * Set the coordinates of an EC_POINT using affine coordinates. Note that - * the simple implementation only uses affine coordinates. - */ -int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x, - const BIGNUM *y, BN_CTX *ctx) -{ - int ret = 0; - if (x == NULL || y == NULL) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (!BN_copy(&point->X, x)) - goto err; - BN_set_negative(&point->X, 0); - if (!BN_copy(&point->Y, y)) - goto err; - BN_set_negative(&point->Y, 0); - if (!BN_copy(&point->Z, BN_value_one())) - goto err; - BN_set_negative(&point->Z, 0); - point->Z_is_one = 1; - ret = 1; - - err: - return ret; -} - -/* - * Gets the affine coordinates of an EC_POINT. Note that the simple - * implementation only uses affine coordinates. - */ -int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) -{ - int ret = 0; - - if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); - return 0; - } - - if (BN_cmp(&point->Z, BN_value_one())) { - ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (x != NULL) { - if (!BN_copy(x, &point->X)) - goto err; - BN_set_negative(x, 0); - } - if (y != NULL) { - if (!BN_copy(y, &point->Y)) - goto err; - BN_set_negative(y, 0); - } - ret = 1; - - err: - return ret; -} - -/* - * Computes a + b and stores the result in r. r could be a or b, a could be - * b. Uses algorithm A.10.2 of IEEE P1363. - */ -int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; - int ret = 0; - - if (EC_POINT_is_at_infinity(group, a)) { - if (!EC_POINT_copy(r, b)) - return 0; - return 1; - } - - if (EC_POINT_is_at_infinity(group, b)) { - if (!EC_POINT_copy(r, a)) - return 0; - return 1; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - x0 = BN_CTX_get(ctx); - y0 = BN_CTX_get(ctx); - x1 = BN_CTX_get(ctx); - y1 = BN_CTX_get(ctx); - x2 = BN_CTX_get(ctx); - y2 = BN_CTX_get(ctx); - s = BN_CTX_get(ctx); - t = BN_CTX_get(ctx); - if (t == NULL) - goto err; - - if (a->Z_is_one) { - if (!BN_copy(x0, &a->X)) - goto err; - if (!BN_copy(y0, &a->Y)) - goto err; - } else { - if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) - goto err; - } - if (b->Z_is_one) { - if (!BN_copy(x1, &b->X)) - goto err; - if (!BN_copy(y1, &b->Y)) - goto err; - } else { - if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) - goto err; - } - - if (BN_GF2m_cmp(x0, x1)) { - if (!BN_GF2m_add(t, x0, x1)) - goto err; - if (!BN_GF2m_add(s, y0, y1)) - goto err; - if (!group->meth->field_div(group, s, s, t, ctx)) - goto err; - if (!group->meth->field_sqr(group, x2, s, ctx)) - goto err; - if (!BN_GF2m_add(x2, x2, &group->a)) - goto err; - if (!BN_GF2m_add(x2, x2, s)) - goto err; - if (!BN_GF2m_add(x2, x2, t)) - goto err; - } else { - if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) { - if (!EC_POINT_set_to_infinity(group, r)) - goto err; - ret = 1; - goto err; - } - if (!group->meth->field_div(group, s, y1, x1, ctx)) - goto err; - if (!BN_GF2m_add(s, s, x1)) - goto err; - - if (!group->meth->field_sqr(group, x2, s, ctx)) - goto err; - if (!BN_GF2m_add(x2, x2, s)) - goto err; - if (!BN_GF2m_add(x2, x2, &group->a)) - goto err; - } - - if (!BN_GF2m_add(y2, x1, x2)) - goto err; - if (!group->meth->field_mul(group, y2, y2, s, ctx)) - goto err; - if (!BN_GF2m_add(y2, y2, x2)) - goto err; - if (!BN_GF2m_add(y2, y2, y1)) - goto err; - - if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) - goto err; - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -/* - * Computes 2 * a and stores the result in r. r could be a. Uses algorithm - * A.10.2 of IEEE P1363. - */ -int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - BN_CTX *ctx) -{ - return ec_GF2m_simple_add(group, r, a, a, ctx); -} - -int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) -{ - if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) - /* point is its own inverse */ - return 1; - - if (!EC_POINT_make_affine(group, point, ctx)) - return 0; - return BN_GF2m_add(&point->Y, &point->X, &point->Y); -} - -/* Indicates whether the given point is the point at infinity. */ -int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, - const EC_POINT *point) -{ - return BN_is_zero(&point->Z); -} - -/*- - * Determines whether the given EC_POINT is an actual point on the curve defined - * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation: - * y^2 + x*y = x^3 + a*x^2 + b. - */ -int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, - BN_CTX *ctx) -{ - int ret = -1; - BN_CTX *new_ctx = NULL; - BIGNUM *lh, *y2; - int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, - const BIGNUM *, BN_CTX *); - int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); - - if (EC_POINT_is_at_infinity(group, point)) - return 1; - - field_mul = group->meth->field_mul; - field_sqr = group->meth->field_sqr; - - /* only support affine coordinates */ - if (!point->Z_is_one) - return -1; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - } - - BN_CTX_start(ctx); - y2 = BN_CTX_get(ctx); - lh = BN_CTX_get(ctx); - if (lh == NULL) - goto err; - - /*- - * We have a curve defined by a Weierstrass equation - * y^2 + x*y = x^3 + a*x^2 + b. - * <=> x^3 + a*x^2 + x*y + b + y^2 = 0 - * <=> ((x + a) * x + y ) * x + b + y^2 = 0 - */ - if (!BN_GF2m_add(lh, &point->X, &group->a)) - goto err; - if (!field_mul(group, lh, lh, &point->X, ctx)) - goto err; - if (!BN_GF2m_add(lh, lh, &point->Y)) - goto err; - if (!field_mul(group, lh, lh, &point->X, ctx)) - goto err; - if (!BN_GF2m_add(lh, lh, &group->b)) - goto err; - if (!field_sqr(group, y2, &point->Y, ctx)) - goto err; - if (!BN_GF2m_add(lh, lh, y2)) - goto err; - ret = BN_is_zero(lh); - err: - if (ctx) - BN_CTX_end(ctx); - if (new_ctx) - BN_CTX_free(new_ctx); - return ret; -} - -/*- - * Indicates whether two points are equal. - * Return values: - * -1 error - * 0 equal (in affine coordinates) - * 1 not equal - */ -int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) -{ - BIGNUM *aX, *aY, *bX, *bY; - BN_CTX *new_ctx = NULL; - int ret = -1; - - if (EC_POINT_is_at_infinity(group, a)) { - return EC_POINT_is_at_infinity(group, b) ? 0 : 1; - } - - if (EC_POINT_is_at_infinity(group, b)) - return 1; - - if (a->Z_is_one && b->Z_is_one) { - return ((BN_cmp(&a->X, &b->X) == 0) - && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - } - - BN_CTX_start(ctx); - aX = BN_CTX_get(ctx); - aY = BN_CTX_get(ctx); - bX = BN_CTX_get(ctx); - bY = BN_CTX_get(ctx); - if (bY == NULL) - goto err; - - if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) - goto err; - if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) - goto err; - ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1; - - err: - if (ctx) - BN_CTX_end(ctx); - if (new_ctx) - BN_CTX_free(new_ctx); - return ret; -} - -/* Forces the given EC_POINT to internally use affine coordinates. */ -int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, - BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y; - int ret = 0; - - if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) - return 1; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - if (y == NULL) - goto err; - - if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) - goto err; - if (!BN_copy(&point->X, x)) - goto err; - if (!BN_copy(&point->Y, y)) - goto err; - if (!BN_one(&point->Z)) - goto err; - point->Z_is_one = 1; - - ret = 1; - - err: - if (ctx) - BN_CTX_end(ctx); - if (new_ctx) - BN_CTX_free(new_ctx); - return ret; -} - -/* - * Forces each of the EC_POINTs in the given array to use affine coordinates. - */ -int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, - EC_POINT *points[], BN_CTX *ctx) -{ - size_t i; - - for (i = 0; i < num; i++) { - if (!group->meth->make_affine(group, points[i], ctx)) - return 0; - } - - return 1; -} - -/* Wrapper to simple binary polynomial field multiplication implementation. */ -int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -{ - return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx); -} - -/* Wrapper to simple binary polynomial field squaring implementation. */ -int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, BN_CTX *ctx) -{ - return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx); -} - -/* Wrapper to simple binary polynomial field division implementation. */ -int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -{ - return BN_GF2m_mod_div(r, a, b, &group->field, ctx); -} - -#endif diff --git a/Sources/COpenSSL/ec_.c b/Sources/COpenSSL/ec_.c deleted file mode 100644 index ab3e9446..00000000 --- a/Sources/COpenSSL/ec_.c +++ /dev/null @@ -1,9962 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "x509.h" -#include "ec.h" -#include "bn.h" -#ifndef OPENSSL_NO_CMS -# include "cms.h" -#endif -#include "asn1t.h" -#include "asn1_locl.h" -#include "ec_lcl.h" - -#ifndef OPENSSL_NO_CMS -static int ecdh_cms_decrypt(CMS_RecipientInfo *ri); -static int ecdh_cms_encrypt(CMS_RecipientInfo *ri); -#endif - -static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) -{ - const EC_GROUP *group; - int nid; - if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { - ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); - return 0; - } - if (EC_GROUP_get_asn1_flag(group) - && (nid = EC_GROUP_get_curve_name(group))) - /* we have a 'named curve' => just set the OID */ - { - *ppval = OBJ_nid2obj(nid); - *pptype = V_ASN1_OBJECT; - } else { /* explicit parameters */ - - ASN1_STRING *pstr = NULL; - pstr = ASN1_STRING_new(); - if (!pstr) - return 0; - pstr->length = i2d_ECParameters(ec_key, &pstr->data); - if (pstr->length <= 0) { - ASN1_STRING_free(pstr); - ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); - return 0; - } - *ppval = pstr; - *pptype = V_ASN1_SEQUENCE; - } - return 1; -} - -static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) -{ - EC_KEY *ec_key = pkey->pkey.ec; - void *pval = NULL; - int ptype; - unsigned char *penc = NULL, *p; - int penclen; - - if (!eckey_param2type(&ptype, &pval, ec_key)) { - ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); - return 0; - } - penclen = i2o_ECPublicKey(ec_key, NULL); - if (penclen <= 0) - goto err; - penc = OPENSSL_malloc(penclen); - if (!penc) - goto err; - p = penc; - penclen = i2o_ECPublicKey(ec_key, &p); - if (penclen <= 0) - goto err; - if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), - ptype, pval, penc, penclen)) - return 1; - err: - if (ptype == V_ASN1_OBJECT) - ASN1_OBJECT_free(pval); - else - ASN1_STRING_free(pval); - if (penc) - OPENSSL_free(penc); - return 0; -} - -static EC_KEY *eckey_type2param(int ptype, void *pval) -{ - EC_KEY *eckey = NULL; - EC_GROUP *group = NULL; - - if (ptype == V_ASN1_SEQUENCE) { - const ASN1_STRING *pstr = pval; - const unsigned char *pm = pstr->data; - int pmlen = pstr->length; - - if ((eckey = d2i_ECParameters(NULL, &pm, pmlen)) == NULL) { - ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); - goto ecerr; - } - } else if (ptype == V_ASN1_OBJECT) { - const ASN1_OBJECT *poid = pval; - - /* - * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID - */ - if ((eckey = EC_KEY_new()) == NULL) { - ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); - goto ecerr; - } - group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); - if (group == NULL) - goto ecerr; - EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_set_group(eckey, group) == 0) - goto ecerr; - EC_GROUP_free(group); - } else { - ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); - goto ecerr; - } - - return eckey; - - ecerr: - EC_KEY_free(eckey); - EC_GROUP_free(group); - return NULL; -} - -static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) -{ - const unsigned char *p = NULL; - void *pval; - int ptype, pklen; - EC_KEY *eckey = NULL; - X509_ALGOR *palg; - - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - eckey = eckey_type2param(ptype, pval); - - if (!eckey) { - ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); - return 0; - } - - /* We have parameters now set public key */ - if (!o2i_ECPublicKey(&eckey, &p, pklen)) { - ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); - goto ecerr; - } - - EVP_PKEY_assign_EC_KEY(pkey, eckey); - return 1; - - ecerr: - if (eckey) - EC_KEY_free(eckey); - return 0; -} - -static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - int r; - const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); - const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), - *pb = EC_KEY_get0_public_key(b->pkey.ec); - if (group == NULL || pa == NULL || pb == NULL) - return -2; - r = EC_POINT_cmp(group, pa, pb, NULL); - if (r == 0) - return 1; - if (r == 1) - return 0; - return -2; -} - -static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) -{ - const unsigned char *p = NULL; - void *pval; - int ptype, pklen; - EC_KEY *eckey = NULL; - X509_ALGOR *palg; - - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - eckey = eckey_type2param(ptype, pval); - - if (!eckey) - goto ecliberr; - - /* We have parameters now set private key */ - if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { - ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); - goto ecerr; - } - - /* calculate public key (if necessary) */ - if (EC_KEY_get0_public_key(eckey) == NULL) { - const BIGNUM *priv_key; - const EC_GROUP *group; - EC_POINT *pub_key; - /* - * the public key was not included in the SEC1 private key => - * calculate the public key - */ - group = EC_KEY_get0_group(eckey); - pub_key = EC_POINT_new(group); - if (pub_key == NULL) { - ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); - goto ecliberr; - } - if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { - EC_POINT_free(pub_key); - ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); - goto ecliberr; - } - priv_key = EC_KEY_get0_private_key(eckey); - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { - EC_POINT_free(pub_key); - ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); - goto ecliberr; - } - if (EC_KEY_set_public_key(eckey, pub_key) == 0) { - EC_POINT_free(pub_key); - ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); - goto ecliberr; - } - EC_POINT_free(pub_key); - } - - EVP_PKEY_assign_EC_KEY(pkey, eckey); - return 1; - - ecliberr: - ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); - ecerr: - if (eckey) - EC_KEY_free(eckey); - return 0; -} - -static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) -{ - EC_KEY ec_key = *(pkey->pkey.ec); - unsigned char *ep, *p; - int eplen, ptype; - void *pval; - unsigned int old_flags; - - if (!eckey_param2type(&ptype, &pval, &ec_key)) { - ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); - return 0; - } - - /* set the private key */ - - /* - * do not include the parameters in the SEC1 private key see PKCS#11 - * 12.11 - */ - old_flags = EC_KEY_get_enc_flags(&ec_key); - EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS); - - eplen = i2d_ECPrivateKey(&ec_key, NULL); - if (!eplen) { - ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); - return 0; - } - ep = (unsigned char *)OPENSSL_malloc(eplen); - if (!ep) { - ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - return 0; - } - p = ep; - if (!i2d_ECPrivateKey(&ec_key, &p)) { - OPENSSL_free(ep); - ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); - return 0; - } - - if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, - ptype, pval, ep, eplen)) { - OPENSSL_free(ep); - return 0; - } - - return 1; -} - -static int int_ec_size(const EVP_PKEY *pkey) -{ - return ECDSA_size(pkey->pkey.ec); -} - -static int ec_bits(const EVP_PKEY *pkey) -{ - BIGNUM *order = BN_new(); - const EC_GROUP *group; - int ret; - - if (!order) { - ERR_clear_error(); - return 0; - } - group = EC_KEY_get0_group(pkey->pkey.ec); - if (!EC_GROUP_get_order(group, order, NULL)) { - ERR_clear_error(); - return 0; - } - - ret = BN_num_bits(order); - BN_free(order); - return ret; -} - -static int ec_missing_parameters(const EVP_PKEY *pkey) -{ - if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL) - return 1; - return 0; -} - -static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) -{ - EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); - if (group == NULL) - return 0; - if (EC_KEY_set_group(to->pkey.ec, group) == 0) - return 0; - EC_GROUP_free(group); - return 1; -} - -static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) -{ - const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), - *group_b = EC_KEY_get0_group(b->pkey.ec); - if (group_a == NULL || group_b == NULL) - return -2; - if (EC_GROUP_cmp(group_a, group_b, NULL)) - return 0; - else - return 1; -} - -static void int_ec_free(EVP_PKEY *pkey) -{ - EC_KEY_free(pkey->pkey.ec); -} - -static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) -{ - unsigned char *buffer = NULL; - const char *ecstr; - size_t buf_len = 0, i; - int ret = 0, reason = ERR_R_BIO_LIB; - BIGNUM *pub_key = NULL, *order = NULL; - BN_CTX *ctx = NULL; - const EC_GROUP *group; - const EC_POINT *public_key; - const BIGNUM *priv_key; - - if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { - reason = ERR_R_PASSED_NULL_PARAMETER; - goto err; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (ktype > 0) { - public_key = EC_KEY_get0_public_key(x); - if (public_key != NULL) { - if ((pub_key = EC_POINT_point2bn(group, public_key, - EC_KEY_get_conv_form(x), NULL, - ctx)) == NULL) { - reason = ERR_R_EC_LIB; - goto err; - } - buf_len = (size_t)BN_num_bytes(pub_key); - } - } - - if (ktype == 2) { - priv_key = EC_KEY_get0_private_key(x); - if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) - buf_len = i; - } else - priv_key = NULL; - - if (ktype > 0) { - buf_len += 10; - if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - } - if (ktype == 2) - ecstr = "Private-Key"; - else if (ktype == 1) - ecstr = "Public-Key"; - else - ecstr = "ECDSA-Parameters"; - - if (!BIO_indent(bp, off, 128)) - goto err; - if ((order = BN_new()) == NULL) - goto err; - if (!EC_GROUP_get_order(group, order, NULL)) - goto err; - if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) - goto err; - - if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, - buffer, off)) - goto err; - if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, - buffer, off)) - goto err; - if (!ECPKParameters_print(bp, group, off)) - goto err; - ret = 1; - err: - if (!ret) - ECerr(EC_F_DO_EC_KEY_PRINT, reason); - if (pub_key) - BN_free(pub_key); - if (order) - BN_free(order); - if (ctx) - BN_CTX_free(ctx); - if (buffer != NULL) - OPENSSL_free(buffer); - return (ret); -} - -static int eckey_param_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) -{ - EC_KEY *eckey; - if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { - ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); - return 0; - } - EVP_PKEY_assign_EC_KEY(pkey, eckey); - return 1; -} - -static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - return i2d_ECParameters(pkey->pkey.ec, pder); -} - -static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); -} - -static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); -} - -static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); -} - -static int old_ec_priv_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) -{ - EC_KEY *ec; - if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { - ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); - return 0; - } - EVP_PKEY_assign_EC_KEY(pkey, ec); - return 1; -} - -static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - return i2d_ECPrivateKey(pkey->pkey.ec, pder); -} - -static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - switch (op) { - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - int snid, hnid; - X509_ALGOR *alg1, *alg2; - CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); - if (alg1 == NULL || alg1->algorithm == NULL) - return -1; - hnid = OBJ_obj2nid(alg1->algorithm); - if (hnid == NID_undef) - return -1; - if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) - return -1; - X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); - } - return 1; - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (arg1 == 1) - return ecdh_cms_decrypt(arg2); - else if (arg1 == 0) - return ecdh_cms_encrypt(arg2); - return -2; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_AGREE; - return 1; -#endif - - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_sha256; - return 2; - - default: - return -2; - - } - -} - -const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { - EVP_PKEY_EC, - EVP_PKEY_EC, - 0, - "EC", - "OpenSSL EC algorithm", - - eckey_pub_decode, - eckey_pub_encode, - eckey_pub_cmp, - eckey_pub_print, - - eckey_priv_decode, - eckey_priv_encode, - eckey_priv_print, - - int_ec_size, - ec_bits, - - eckey_param_decode, - eckey_param_encode, - ec_missing_parameters, - ec_copy_parameters, - ec_cmp_parameters, - eckey_param_print, - 0, - - int_ec_free, - ec_pkey_ctrl, - old_ec_priv_decode, - old_ec_priv_encode -}; - -#ifndef OPENSSL_NO_CMS - -static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, - X509_ALGOR *alg, ASN1_BIT_STRING *pubkey) -{ - ASN1_OBJECT *aoid; - int atype; - void *aval; - int rv = 0; - EVP_PKEY *pkpeer = NULL; - EC_KEY *ecpeer = NULL; - const unsigned char *p; - int plen; - X509_ALGOR_get0(&aoid, &atype, &aval, alg); - if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) - goto err; - /* If absent parameters get group from main key */ - if (atype == V_ASN1_UNDEF || atype == V_ASN1_NULL) { - const EC_GROUP *grp; - EVP_PKEY *pk; - pk = EVP_PKEY_CTX_get0_pkey(pctx); - if (!pk) - goto err; - grp = EC_KEY_get0_group(pk->pkey.ec); - ecpeer = EC_KEY_new(); - if (!ecpeer) - goto err; - if (!EC_KEY_set_group(ecpeer, grp)) - goto err; - } else { - ecpeer = eckey_type2param(atype, aval); - if (!ecpeer) - goto err; - } - /* We have parameters now set public key */ - plen = ASN1_STRING_length(pubkey); - p = ASN1_STRING_data(pubkey); - if (!p || !plen) - goto err; - if (!o2i_ECPublicKey(&ecpeer, &p, plen)) - goto err; - pkpeer = EVP_PKEY_new(); - if (!pkpeer) - goto err; - EVP_PKEY_set1_EC_KEY(pkpeer, ecpeer); - if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) - rv = 1; - err: - if (ecpeer) - EC_KEY_free(ecpeer); - if (pkpeer) - EVP_PKEY_free(pkpeer); - return rv; -} - -/* Set KDF parameters based on KDF NID */ -static int ecdh_cms_set_kdf_param(EVP_PKEY_CTX *pctx, int eckdf_nid) -{ - int kdf_nid, kdfmd_nid, cofactor; - const EVP_MD *kdf_md; - if (eckdf_nid == NID_undef) - return 0; - - /* Lookup KDF type, cofactor mode and digest */ - if (!OBJ_find_sigid_algs(eckdf_nid, &kdfmd_nid, &kdf_nid)) - return 0; - - if (kdf_nid == NID_dh_std_kdf) - cofactor = 0; - else if (kdf_nid == NID_dh_cofactor_kdf) - cofactor = 1; - else - return 0; - - if (EVP_PKEY_CTX_set_ecdh_cofactor_mode(pctx, cofactor) <= 0) - return 0; - - if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, EVP_PKEY_ECDH_KDF_X9_62) <= 0) - return 0; - - kdf_md = EVP_get_digestbynid(kdfmd_nid); - if (!kdf_md) - return 0; - - if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) - return 0; - return 1; -} - -static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) -{ - int rv = 0; - - X509_ALGOR *alg, *kekalg = NULL; - ASN1_OCTET_STRING *ukm; - const unsigned char *p; - unsigned char *der = NULL; - int plen, keylen; - const EVP_CIPHER *kekcipher; - EVP_CIPHER_CTX *kekctx; - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm)) - return 0; - - if (!ecdh_cms_set_kdf_param(pctx, OBJ_obj2nid(alg->algorithm))) { - ECerr(EC_F_ECDH_CMS_SET_SHARED_INFO, EC_R_KDF_PARAMETER_ERROR); - return 0; - } - - if (alg->parameter->type != V_ASN1_SEQUENCE) - return 0; - - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - kekalg = d2i_X509_ALGOR(NULL, &p, plen); - if (!kekalg) - goto err; - kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); - if (!kekctx) - goto err; - kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); - if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE) - goto err; - if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL)) - goto err; - if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0) - goto err; - - keylen = EVP_CIPHER_CTX_key_length(kekctx); - if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); - - if (!plen) - goto err; - - if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) - goto err; - der = NULL; - - rv = 1; - err: - if (kekalg) - X509_ALGOR_free(kekalg); - if (der) - OPENSSL_free(der); - return rv; -} - -static int ecdh_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* See if we need to set peer key */ - if (!EVP_PKEY_CTX_get0_peerkey(pctx)) { - X509_ALGOR *alg; - ASN1_BIT_STRING *pubkey; - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey, - NULL, NULL, NULL)) - return 0; - if (!alg || !pubkey) - return 0; - if (!ecdh_cms_set_peerkey(pctx, alg, pubkey)) { - ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_PEER_KEY_ERROR); - return 0; - } - } - /* Set ECDH derivation parameters and initialise unwrap context */ - if (!ecdh_cms_set_shared_info(pctx, ri)) { - ECerr(EC_F_ECDH_CMS_DECRYPT, EC_R_SHARED_INFO_ERROR); - return 0; - } - return 1; -} - -static int ecdh_cms_encrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pctx; - EVP_PKEY *pkey; - EVP_CIPHER_CTX *ctx; - int keylen; - X509_ALGOR *talg, *wrap_alg = NULL; - ASN1_OBJECT *aoid; - ASN1_BIT_STRING *pubkey; - ASN1_STRING *wrap_str; - ASN1_OCTET_STRING *ukm; - unsigned char *penc = NULL; - int penclen; - int rv = 0; - int ecdh_nid, kdf_type, kdf_nid, wrap_nid; - const EVP_MD *kdf_md; - pctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pctx) - return 0; - /* Get ephemeral key */ - pkey = EVP_PKEY_CTX_get0_pkey(pctx); - if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey, - NULL, NULL, NULL)) - goto err; - X509_ALGOR_get0(&aoid, NULL, NULL, talg); - /* Is everything uninitialised? */ - if (aoid == OBJ_nid2obj(NID_undef)) { - - EC_KEY *eckey = pkey->pkey.ec; - /* Set the key */ - unsigned char *p; - - penclen = i2o_ECPublicKey(eckey, NULL); - if (penclen <= 0) - goto err; - penc = OPENSSL_malloc(penclen); - if (!penc) - goto err; - p = penc; - penclen = i2o_ECPublicKey(eckey, &p); - if (penclen <= 0) - goto err; - ASN1_STRING_set0(pubkey, penc, penclen); - pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT; - - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), - V_ASN1_UNDEF, NULL); - } - - /* See if custom paraneters set */ - kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx); - if (kdf_type <= 0) - goto err; - if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md)) - goto err; - ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx); - if (ecdh_nid < 0) - goto err; - else if (ecdh_nid == 0) - ecdh_nid = NID_dh_std_kdf; - else if (ecdh_nid == 1) - ecdh_nid = NID_dh_cofactor_kdf; - - if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) { - kdf_type = EVP_PKEY_ECDH_KDF_X9_62; - if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0) - goto err; - } else - /* Uknown KDF */ - goto err; - if (kdf_md == NULL) { - /* Fixme later for better MD */ - kdf_md = EVP_sha1(); - if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0) - goto err; - } - - if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm)) - goto err; - - /* Lookup NID for KDF+cofactor+digest */ - - if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid)) - goto err; - /* Get wrap NID */ - ctx = CMS_RecipientInfo_kari_get0_ctx(ri); - wrap_nid = EVP_CIPHER_CTX_type(ctx); - keylen = EVP_CIPHER_CTX_key_length(ctx); - - /* Package wrap algorithm in an AlgorithmIdentifier */ - - wrap_alg = X509_ALGOR_new(); - if (!wrap_alg) - goto err; - wrap_alg->algorithm = OBJ_nid2obj(wrap_nid); - wrap_alg->parameter = ASN1_TYPE_new(); - if (!wrap_alg->parameter) - goto err; - if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0) - goto err; - if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) { - ASN1_TYPE_free(wrap_alg->parameter); - wrap_alg->parameter = NULL; - } - - if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) - goto err; - - penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen); - - if (!penclen) - goto err; - - if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0) - goto err; - penc = NULL; - - /* - * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter - * of another AlgorithmIdentifier. - */ - penclen = i2d_X509_ALGOR(wrap_alg, &penc); - if (!penc || !penclen) - goto err; - wrap_str = ASN1_STRING_new(); - if (!wrap_str) - goto err; - ASN1_STRING_set0(wrap_str, penc, penclen); - penc = NULL; - X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str); - - rv = 1; - - err: - if (penc) - OPENSSL_free(penc); - if (wrap_alg) - X509_ALGOR_free(wrap_alg); - return rv; -} - -#endif -/* crypto/ec/ec_asn1.c */ -/* - * Written by Nils Larsch for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "ec_lcl.h" -#include "err.h" -// #include "asn1t.h" -#include "objects.h" - -#define OSSL_NELEM(x) (sizeof(x)/sizeof(x[0])) - -int EC_GROUP_get_basis_type(const EC_GROUP *group) -{ - int i; - - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field) - /* everything else is currently not supported */ - return 0; - - /* Find the last non-zero element of group->poly[] */ - for (i = 0; - i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; - i++) - continue; - - if (i == 4) - return NID_X9_62_ppBasis; - else if (i == 2) - return NID_X9_62_tpBasis; - else - /* everything else is currently not supported */ - return 0; -} - -#ifndef OPENSSL_NO_EC2M -int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) -{ - if (group == NULL) - return 0; - - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field - || !((group->poly[0] != 0) && (group->poly[1] != 0) - && (group->poly[2] == 0))) { - ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - if (k) - *k = group->poly[1]; - - return 1; -} - -int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, - unsigned int *k2, unsigned int *k3) -{ - if (group == NULL) - return 0; - - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != - NID_X9_62_characteristic_two_field - || !((group->poly[0] != 0) && (group->poly[1] != 0) - && (group->poly[2] != 0) && (group->poly[3] != 0) - && (group->poly[4] == 0))) { - ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - - if (k1) - *k1 = group->poly[3]; - if (k2) - *k2 = group->poly[2]; - if (k3) - *k3 = group->poly[1]; - - return 1; -} -#endif - -/* some structures needed for the asn1 encoding */ -typedef struct x9_62_pentanomial_st { - long k1; - long k2; - long k3; -} X9_62_PENTANOMIAL; - -typedef struct x9_62_characteristic_two_st { - long m; - ASN1_OBJECT *type; - union { - char *ptr; - /* NID_X9_62_onBasis */ - ASN1_NULL *onBasis; - /* NID_X9_62_tpBasis */ - ASN1_INTEGER *tpBasis; - /* NID_X9_62_ppBasis */ - X9_62_PENTANOMIAL *ppBasis; - /* anything else */ - ASN1_TYPE *other; - } p; -} X9_62_CHARACTERISTIC_TWO; - -typedef struct x9_62_fieldid_st { - ASN1_OBJECT *fieldType; - union { - char *ptr; - /* NID_X9_62_prime_field */ - ASN1_INTEGER *prime; - /* NID_X9_62_characteristic_two_field */ - X9_62_CHARACTERISTIC_TWO *char_two; - /* anything else */ - ASN1_TYPE *other; - } p; -} X9_62_FIELDID; - -typedef struct x9_62_curve_st { - ASN1_OCTET_STRING *a; - ASN1_OCTET_STRING *b; - ASN1_BIT_STRING *seed; -} X9_62_CURVE; - -typedef struct ec_parameters_st { - long version; - X9_62_FIELDID *fieldID; - X9_62_CURVE *curve; - ASN1_OCTET_STRING *base; - ASN1_INTEGER *order; - ASN1_INTEGER *cofactor; -} ECPARAMETERS; - -struct ecpk_parameters_st { - int type; - union { - ASN1_OBJECT *named_curve; - ECPARAMETERS *parameters; - ASN1_NULL *implicitlyCA; - } value; -} /* ECPKPARAMETERS */ ; - -/* SEC1 ECPrivateKey */ -typedef struct ec_privatekey_st { - long version; - ASN1_OCTET_STRING *privateKey; - ECPKPARAMETERS *parameters; - ASN1_BIT_STRING *publicKey; -} EC_PRIVATEKEY; - -/* the OpenSSL ASN.1 definitions */ -ASN1_SEQUENCE(X9_62_PENTANOMIAL) = { - ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG), - ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG), - ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG) -} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL) - -DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) - -ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY); - -ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = { - ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), - ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), - ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL)) -} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL); - -ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = { - ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG), - ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), - ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO) -} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO) - -DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) - -ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); - -ASN1_ADB(X9_62_FIELDID) = { - ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), - ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO)) -} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); - -ASN1_SEQUENCE(X9_62_FIELDID) = { - ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), - ASN1_ADB_OBJECT(X9_62_FIELDID) -} ASN1_SEQUENCE_END(X9_62_FIELDID) - -ASN1_SEQUENCE(X9_62_CURVE) = { - ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), - ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), - ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END(X9_62_CURVE) - -ASN1_SEQUENCE(ECPARAMETERS) = { - ASN1_SIMPLE(ECPARAMETERS, version, LONG), - ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), - ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), - ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), - ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), - ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) -} ASN1_SEQUENCE_END(ECPARAMETERS) - -DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) - -ASN1_CHOICE(ECPKPARAMETERS) = { - ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), - ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), - ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) -} ASN1_CHOICE_END(ECPKPARAMETERS) - -DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS) -IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS) - -ASN1_SEQUENCE(EC_PRIVATEKEY) = { - ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), - ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), - ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), - ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) -} ASN1_SEQUENCE_END(EC_PRIVATEKEY) - -DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY) -IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) - -/* some declarations of internal function */ - -/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ -static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); -/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ -static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); -/* - * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS - * object - */ -static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); -/* - * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP - * object - */ -static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, - ECPARAMETERS *); -/* - * ec_asn1_pkparameters2group() creates a EC_GROUP object from a - * ECPKPARAMETERS object - */ -static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); -/* - * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a - * EC_GROUP object - */ -static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, - ECPKPARAMETERS *); - -/* the function definitions */ - -static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) -{ - int ok = 0, nid; - BIGNUM *tmp = NULL; - - if (group == NULL || field == NULL) - return 0; - - /* clear the old values (if necessary) */ - if (field->fieldType != NULL) - ASN1_OBJECT_free(field->fieldType); - if (field->p.other != NULL) - ASN1_TYPE_free(field->p.other); - - nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); - /* set OID for the field */ - if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); - goto err; - } - - if (nid == NID_X9_62_prime_field) { - if ((tmp = BN_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); - goto err; - } - /* the parameters are specified by the prime number p */ - if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); - goto err; - } - /* set the prime number */ - field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); - if (field->p.prime == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); - goto err; - } - } else /* nid == NID_X9_62_characteristic_two_field */ -#ifdef OPENSSL_NO_EC2M - { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED); - goto err; - } -#else - { - int field_type; - X9_62_CHARACTERISTIC_TWO *char_two; - - field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); - char_two = field->p.char_two; - - if (char_two == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); - goto err; - } - - char_two->m = (long)EC_GROUP_get_degree(group); - - field_type = EC_GROUP_get_basis_type(group); - - if (field_type == 0) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); - goto err; - } - /* set base type OID */ - if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); - goto err; - } - - if (field_type == NID_X9_62_tpBasis) { - unsigned int k; - - if (!EC_GROUP_get_trinomial_basis(group, &k)) - goto err; - - char_two->p.tpBasis = ASN1_INTEGER_new(); - if (!char_two->p.tpBasis) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); - goto err; - } - } else if (field_type == NID_X9_62_ppBasis) { - unsigned int k1, k2, k3; - - if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) - goto err; - - char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); - if (!char_two->p.ppBasis) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* set k? values */ - char_two->p.ppBasis->k1 = (long)k1; - char_two->p.ppBasis->k2 = (long)k2; - char_two->p.ppBasis->k3 = (long)k3; - } else { /* field_type == NID_X9_62_onBasis */ - - /* for ONB the parameters are (asn1) NULL */ - char_two->p.onBasis = ASN1_NULL_new(); - if (!char_two->p.onBasis) { - ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); - goto err; - } - } - } -#endif - - ok = 1; - - err:if (tmp) - BN_free(tmp); - return (ok); -} - -static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) -{ - int ok = 0, nid; - BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; - unsigned char *buffer_1 = NULL, *buffer_2 = NULL, - *a_buf = NULL, *b_buf = NULL; - size_t len_1, len_2; - unsigned char char_zero = 0; - - if (!group || !curve || !curve->a || !curve->b) - return 0; - - if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); - goto err; - } - - nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); - - /* get a and b */ - if (nid == NID_X9_62_prime_field) { - if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); - goto err; - } - } -#ifndef OPENSSL_NO_EC2M - else { /* nid == NID_X9_62_characteristic_two_field */ - - if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); - goto err; - } - } -#endif - len_1 = (size_t)BN_num_bytes(tmp_1); - len_2 = (size_t)BN_num_bytes(tmp_2); - - if (len_1 == 0) { - /* len_1 == 0 => a == 0 */ - a_buf = &char_zero; - len_1 = 1; - } else { - if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); - goto err; - } - if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); - goto err; - } - a_buf = buffer_1; - } - - if (len_2 == 0) { - /* len_2 == 0 => b == 0 */ - b_buf = &char_zero; - len_2 = 1; - } else { - if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); - goto err; - } - if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); - goto err; - } - b_buf = buffer_2; - } - - /* set a and b */ - if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) || - !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); - goto err; - } - - /* set the seed (optional) */ - if (group->seed) { - if (!curve->seed) - if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); - goto err; - } - curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; - if (!ASN1_BIT_STRING_set(curve->seed, group->seed, - (int)group->seed_len)) { - ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); - goto err; - } - } else { - if (curve->seed) { - ASN1_BIT_STRING_free(curve->seed); - curve->seed = NULL; - } - } - - ok = 1; - - err:if (buffer_1) - OPENSSL_free(buffer_1); - if (buffer_2) - OPENSSL_free(buffer_2); - if (tmp_1) - BN_free(tmp_1); - if (tmp_2) - BN_free(tmp_2); - return (ok); -} - -static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, - ECPARAMETERS *param) -{ - int ok = 0; - size_t len = 0; - ECPARAMETERS *ret = NULL; - BIGNUM *tmp = NULL; - unsigned char *buffer = NULL; - const EC_POINT *point = NULL; - point_conversion_form_t form; - - if ((tmp = BN_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (param == NULL) { - if ((ret = ECPARAMETERS_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); - goto err; - } - } else - ret = param; - - /* set the version (always one) */ - ret->version = (long)0x1; - - /* set the fieldID */ - if (!ec_asn1_group2fieldid(group, ret->fieldID)) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); - goto err; - } - - /* set the curve */ - if (!ec_asn1_group2curve(group, ret->curve)) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); - goto err; - } - - /* set the base point */ - if ((point = EC_GROUP_get0_generator(group)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR); - goto err; - } - - form = EC_GROUP_get_point_conversion_form(group); - - len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); - if (len == 0) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); - goto err; - } - if ((buffer = OPENSSL_malloc(len)) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); - goto err; - } - if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); - goto err; - } - - /* set the order */ - if (!EC_GROUP_get_order(group, tmp, NULL)) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); - goto err; - } - ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); - if (ret->order == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); - goto err; - } - - /* set the cofactor (optional) */ - if (EC_GROUP_get_cofactor(group, tmp, NULL)) { - ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); - if (ret->cofactor == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); - goto err; - } - } - - ok = 1; - - err:if (!ok) { - if (ret && !param) - ECPARAMETERS_free(ret); - ret = NULL; - } - if (tmp) - BN_free(tmp); - if (buffer) - OPENSSL_free(buffer); - return (ret); -} - -ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, - ECPKPARAMETERS *params) -{ - int ok = 1, tmp; - ECPKPARAMETERS *ret = params; - - if (ret == NULL) { - if ((ret = ECPKPARAMETERS_new()) == NULL) { - ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE); - return NULL; - } - } else { - if (ret->type == 0 && ret->value.named_curve) - ASN1_OBJECT_free(ret->value.named_curve); - else if (ret->type == 1 && ret->value.parameters) - ECPARAMETERS_free(ret->value.parameters); - } - - if (EC_GROUP_get_asn1_flag(group)) { - /* - * use the asn1 OID to describe the the elliptic curve parameters - */ - tmp = EC_GROUP_get_curve_name(group); - if (tmp) { - ret->type = 0; - if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) - ok = 0; - } else - /* we don't kmow the nid => ERROR */ - ok = 0; - } else { - /* use the ECPARAMETERS structure */ - ret->type = 1; - if ((ret->value.parameters = - ec_asn1_group2parameters(group, NULL)) == NULL) - ok = 0; - } - - if (!ok) { - ECPKPARAMETERS_free(ret); - return NULL; - } - return ret; -} - -static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) -{ - int ok = 0, tmp; - EC_GROUP *ret = NULL; - BIGNUM *p = NULL, *a = NULL, *b = NULL; - EC_POINT *point = NULL; - long field_bits; - - if (!params->fieldID || !params->fieldID->fieldType || - !params->fieldID->p.ptr) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); - goto err; - } - - /* now extract the curve parameters a and b */ - if (!params->curve || !params->curve->a || - !params->curve->a->data || !params->curve->b || - !params->curve->b->data) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); - goto err; - } - a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); - if (a == NULL) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); - goto err; - } - b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); - if (b == NULL) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); - goto err; - } - - /* get the field parameters */ - tmp = OBJ_obj2nid(params->fieldID->fieldType); - if (tmp == NID_X9_62_characteristic_two_field) -#ifdef OPENSSL_NO_EC2M - { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED); - goto err; - } -#else - { - X9_62_CHARACTERISTIC_TWO *char_two; - - char_two = params->fieldID->p.char_two; - - field_bits = char_two->m; - if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); - goto err; - } - - if ((p = BN_new()) == NULL) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* get the base type */ - tmp = OBJ_obj2nid(char_two->type); - - if (tmp == NID_X9_62_tpBasis) { - long tmp_long; - - if (!char_two->p.tpBasis) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); - goto err; - } - - tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); - - if (!(char_two->m > tmp_long && tmp_long > 0)) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, - EC_R_INVALID_TRINOMIAL_BASIS); - goto err; - } - - /* create the polynomial */ - if (!BN_set_bit(p, (int)char_two->m)) - goto err; - if (!BN_set_bit(p, (int)tmp_long)) - goto err; - if (!BN_set_bit(p, 0)) - goto err; - } else if (tmp == NID_X9_62_ppBasis) { - X9_62_PENTANOMIAL *penta; - - penta = char_two->p.ppBasis; - if (!penta) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); - goto err; - } - - if (! - (char_two->m > penta->k3 && penta->k3 > penta->k2 - && penta->k2 > penta->k1 && penta->k1 > 0)) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, - EC_R_INVALID_PENTANOMIAL_BASIS); - goto err; - } - - /* create the polynomial */ - if (!BN_set_bit(p, (int)char_two->m)) - goto err; - if (!BN_set_bit(p, (int)penta->k1)) - goto err; - if (!BN_set_bit(p, (int)penta->k2)) - goto err; - if (!BN_set_bit(p, (int)penta->k3)) - goto err; - if (!BN_set_bit(p, 0)) - goto err; - } else if (tmp == NID_X9_62_onBasis) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED); - goto err; - } else { /* error */ - - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); - goto err; - } - - /* create the EC_GROUP structure */ - ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); - } -#endif - else if (tmp == NID_X9_62_prime_field) { - /* we have a curve over a prime field */ - /* extract the prime number */ - if (!params->fieldID->p.prime) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); - goto err; - } - p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); - if (p == NULL) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); - goto err; - } - - if (BN_is_negative(p) || BN_is_zero(p)) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); - goto err; - } - - field_bits = BN_num_bits(p); - if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); - goto err; - } - - /* create the EC_GROUP structure */ - ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); - } else { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); - goto err; - } - - if (ret == NULL) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); - goto err; - } - - /* extract seed (optional) */ - if (params->curve->seed != NULL) { - if (ret->seed != NULL) - OPENSSL_free(ret->seed); - if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); - goto err; - } - memcpy(ret->seed, params->curve->seed->data, - params->curve->seed->length); - ret->seed_len = params->curve->seed->length; - } - - if (!params->order || !params->base || !params->base->data) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); - goto err; - } - - if ((point = EC_POINT_new(ret)) == NULL) - goto err; - - /* set the point conversion form */ - EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) - (params->base->data[0] & ~0x01)); - - /* extract the ec point */ - if (!EC_POINT_oct2point(ret, point, params->base->data, - params->base->length, NULL)) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); - goto err; - } - - /* extract the order */ - if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); - goto err; - } - if (BN_is_negative(a) || BN_is_zero(a)) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); - goto err; - } - if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */ - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); - goto err; - } - - /* extract the cofactor (optional) */ - if (params->cofactor == NULL) { - if (b) { - BN_free(b); - b = NULL; - } - } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); - goto err; - } - /* set the generator, order and cofactor (if present) */ - if (!EC_GROUP_set_generator(ret, point, a, b)) { - ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); - goto err; - } - - ok = 1; - - err:if (!ok) { - if (ret) - EC_GROUP_clear_free(ret); - ret = NULL; - } - - if (p) - BN_free(p); - if (a) - BN_free(a); - if (b) - BN_free(b); - if (point) - EC_POINT_free(point); - return (ret); -} - -EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) -{ - EC_GROUP *ret = NULL; - int tmp = 0; - - if (params == NULL) { - ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS); - return NULL; - } - - if (params->type == 0) { /* the curve is given by an OID */ - tmp = OBJ_obj2nid(params->value.named_curve); - if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { - ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, - EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); - return NULL; - } - EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); - } else if (params->type == 1) { /* the parameters are given by a - * ECPARAMETERS structure */ - ret = ec_asn1_parameters2group(params->value.parameters); - if (!ret) { - ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB); - return NULL; - } - EC_GROUP_set_asn1_flag(ret, 0x0); - } else if (params->type == 2) { /* implicitlyCA */ - return NULL; - } else { - ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR); - return NULL; - } - - return ret; -} - -/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ - -EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) -{ - EC_GROUP *group = NULL; - ECPKPARAMETERS *params = NULL; - const unsigned char *p = *in; - - if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) { - ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); - ECPKPARAMETERS_free(params); - return NULL; - } - - if ((group = ec_asn1_pkparameters2group(params)) == NULL) { - ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); - ECPKPARAMETERS_free(params); - return NULL; - } - - if (a && *a) - EC_GROUP_clear_free(*a); - if (a) - *a = group; - - ECPKPARAMETERS_free(params); - *in = p; - return (group); -} - -int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) -{ - int ret = 0; - ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); - if (tmp == NULL) { - ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); - return 0; - } - if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { - ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); - ECPKPARAMETERS_free(tmp); - return 0; - } - ECPKPARAMETERS_free(tmp); - return (ret); -} - -/* some EC_KEY functions */ - -EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) -{ - int ok = 0; - EC_KEY *ret = NULL; - EC_PRIVATEKEY *priv_key = NULL; - const unsigned char *p = *in; - - if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); - return NULL; - } - - if (a == NULL || *a == NULL) { - if ((ret = EC_KEY_new()) == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - } else - ret = *a; - - if (priv_key->parameters) { - if (ret->group) - EC_GROUP_clear_free(ret->group); - ret->group = ec_asn1_pkparameters2group(priv_key->parameters); - } - - if (ret->group == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); - goto err; - } - - ret->version = priv_key->version; - - if (priv_key->privateKey) { - ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey), - M_ASN1_STRING_length(priv_key->privateKey), - ret->priv_key); - if (ret->priv_key == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB); - goto err; - } - } else { - ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY); - goto err; - } - - if (ret->pub_key) - EC_POINT_clear_free(ret->pub_key); - ret->pub_key = EC_POINT_new(ret->group); - if (ret->pub_key == NULL) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); - goto err; - } - - if (priv_key->publicKey) { - const unsigned char *pub_oct; - int pub_oct_len; - - pub_oct = M_ASN1_STRING_data(priv_key->publicKey); - pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); - /* - * The first byte - point conversion form - must be present. - */ - if (pub_oct_len <= 0) { - ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); - goto err; - } - /* Save the point conversion form. */ - ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); - if (!EC_POINT_oct2point(ret->group, ret->pub_key, - pub_oct, (size_t)(pub_oct_len), NULL)) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); - goto err; - } - } else { - if (!EC_POINT_mul - (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) { - ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); - goto err; - } - /* Remember the original private-key-only encoding. */ - ret->enc_flag |= EC_PKEY_NO_PUBKEY; - } - - if (a) - *a = ret; - *in = p; - ok = 1; - err: - if (!ok) { - if (ret && (a == NULL || *a != ret)) - EC_KEY_free(ret); - ret = NULL; - } - - if (priv_key) - EC_PRIVATEKEY_free(priv_key); - - return (ret); -} - -int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) -{ - int ret = 0, ok = 0; - unsigned char *buffer = NULL; - size_t buf_len = 0, tmp_len, bn_len; - EC_PRIVATEKEY *priv_key = NULL; - - if (a == NULL || a->group == NULL || a->priv_key == NULL || - (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - goto err; - } - - if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - priv_key->version = a->version; - - bn_len = (size_t)BN_num_bytes(a->priv_key); - - /* Octetstring may need leading zeros if BN is to short */ - - buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8; - - if (bn_len > buf_len) { - ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); - goto err; - } - - buffer = OPENSSL_malloc(buf_len); - if (buffer == NULL) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); - goto err; - } - - if (buf_len - bn_len > 0) { - memset(buffer, 0, buf_len - bn_len); - } - - if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); - goto err; - } - - if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { - if ((priv_key->parameters = - ec_asn1_group2pkparameters(a->group, - priv_key->parameters)) == NULL) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); - goto err; - } - } - - if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { - priv_key->publicKey = M_ASN1_BIT_STRING_new(); - if (priv_key->publicKey == NULL) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - tmp_len = EC_POINT_point2oct(a->group, a->pub_key, - a->conv_form, NULL, 0, NULL); - - if (tmp_len > buf_len) { - unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); - if (!tmp_buffer) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); - goto err; - } - buffer = tmp_buffer; - buf_len = tmp_len; - } - - if (!EC_POINT_point2oct(a->group, a->pub_key, - a->conv_form, buffer, buf_len, NULL)) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); - goto err; - } - - priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; - if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); - goto err; - } - } - - if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { - ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); - goto err; - } - ok = 1; - err: - if (buffer) - OPENSSL_free(buffer); - if (priv_key) - EC_PRIVATEKEY_free(priv_key); - return (ok ? ret : 0); -} - -int i2d_ECParameters(EC_KEY *a, unsigned char **out) -{ - if (a == NULL) { - ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - return i2d_ECPKParameters(a->group, out); -} - -EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) -{ - EC_KEY *ret; - - if (in == NULL || *in == NULL) { - ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - if (a == NULL || *a == NULL) { - if ((ret = EC_KEY_new()) == NULL) { - ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); - return NULL; - } - } else - ret = *a; - - if (!d2i_ECPKParameters(&ret->group, in, len)) { - ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); - if (a == NULL || *a != ret) - EC_KEY_free(ret); - return NULL; - } - - if (a) - *a = ret; - - return ret; -} - -EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) -{ - EC_KEY *ret = NULL; - - if (a == NULL || (*a) == NULL || (*a)->group == NULL) { - /* - * sorry, but a EC_GROUP-structur is necessary to set the public key - */ - ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - ret = *a; - if (ret->pub_key == NULL && - (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { - ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { - ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); - return 0; - } - /* save the point conversion form */ - ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01); - *in += len; - return ret; -} - -int i2o_ECPublicKey(EC_KEY *a, unsigned char **out) -{ - size_t buf_len = 0; - int new_buffer = 0; - - if (a == NULL) { - ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - buf_len = EC_POINT_point2oct(a->group, a->pub_key, - a->conv_form, NULL, 0, NULL); - - if (out == NULL || buf_len == 0) - /* out == NULL => just return the length of the octet string */ - return buf_len; - - if (*out == NULL) { - if ((*out = OPENSSL_malloc(buf_len)) == NULL) { - ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); - return 0; - } - new_buffer = 1; - } - if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, - *out, buf_len, NULL)) { - ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); - if (new_buffer) { - OPENSSL_free(*out); - *out = NULL; - } - return 0; - } - if (!new_buffer) - *out += buf_len; - return buf_len; -} -/* crypto/ec/ec_check.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ec_lcl.h" -// #include "err.h" - -int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) -{ - int ret = 0; - BIGNUM *order; - BN_CTX *new_ctx = NULL; - EC_POINT *point = NULL; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) { - ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE); - goto err; - } - } - BN_CTX_start(ctx); - if ((order = BN_CTX_get(ctx)) == NULL) - goto err; - - /* check the discriminant */ - if (!EC_GROUP_check_discriminant(group, ctx)) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO); - goto err; - } - - /* check the generator */ - if (group->generator == NULL) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR); - goto err; - } - if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE); - goto err; - } - - /* check the order of the generator */ - if ((point = EC_POINT_new(group)) == NULL) - goto err; - if (!EC_GROUP_get_order(group, order, ctx)) - goto err; - if (BN_is_zero(order)) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER); - goto err; - } - - if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) - goto err; - if (!EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER); - goto err; - } - - ret = 1; - - err: - if (ctx != NULL) - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (point) - EC_POINT_free(point); - return ret; -} -/* crypto/ec/ec_curve.c */ -/* - * Written by Nils Larsch for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * The elliptic curve binary polynomial software is originally written by - * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. - * - */ - -#include -// #include "ec_lcl.h" -// #include "err.h" -// #include "obj_mac.h" -#include "opensslconf.h" - -#ifdef OPENSSL_FIPS -# include -#endif - -typedef struct { - int field_type, /* either NID_X9_62_prime_field or - * NID_X9_62_characteristic_two_field */ - seed_len, param_len; - unsigned int cofactor; /* promoted to BN_ULONG */ -} EC_CURVE_DATA; - -/* the nist prime curves */ -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 24 * 6]; -} _EC_NIST_PRIME_192 = { - { - NID_X9_62_prime_field, 20, 24, 1 - }, - { - /* seed */ - 0x30, 0x45, 0xAE, 0x6F, 0xC8, 0x42, 0x2F, 0x64, 0xED, 0x57, 0x95, 0x28, - 0xD3, 0x81, 0x20, 0xEA, 0xE1, 0x21, 0x96, 0xD5, - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB, - 0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1, - /* x */ - 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB, - 0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12, - /* y */ - 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed, - 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 28 * 6]; -} _EC_NIST_PRIME_224 = { - { - NID_X9_62_prime_field, 20, 28, 1 - }, - { - /* seed */ - 0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45, 0xB5, 0x9F, - 0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5, - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - /* a */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, - /* b */ - 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, - 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, - 0x23, 0x55, 0xFF, 0xB4, - /* x */ - 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, - 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, - 0x11, 0x5C, 0x1D, 0x21, - /* y */ - 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, - 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, - 0x85, 0x00, 0x7e, 0x34, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, - 0x5C, 0x5C, 0x2A, 0x3D - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 48 * 6]; -} _EC_NIST_PRIME_384 = { - { - NID_X9_62_prime_field, 20, 48, 1 - }, - { - /* seed */ - 0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, 0x89, 0x6A, - 0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73, - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, - 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, - 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, - 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF, - /* x */ - 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, - 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, - 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, - 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, - /* y */ - 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, - 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, - 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, - 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, - 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 66 * 6]; -} _EC_NIST_PRIME_521 = { - { - NID_X9_62_prime_field, 20, 66, 1 - }, - { - /* seed */ - 0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, 0x67, 0x17, - 0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA, - /* p */ - 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, - 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, - 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, - 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, - 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, - 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00, - /* x */ - 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, - 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, - 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, - 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, - 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, - 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, - /* y */ - 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, - 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, - 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, - 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, - 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, - 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, - /* order */ - 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, - 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, - 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, - 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 - } -}; - -/* the x9.62 prime curves (minus the nist prime curves) */ -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 24 * 6]; -} _EC_X9_62_PRIME_192V2 = { - { - NID_X9_62_prime_field, 20, 24, 1 - }, - { - /* seed */ - 0x31, 0xA9, 0x2E, 0xE2, 0x02, 0x9F, 0xD1, 0x0D, 0x90, 0x1B, 0x11, 0x3E, - 0x99, 0x07, 0x10, 0xF0, 0xD2, 0x1A, 0xC6, 0xB6, - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0xCC, 0x22, 0xD6, 0xDF, 0xB9, 0x5C, 0x6B, 0x25, 0xE4, 0x9C, 0x0D, 0x63, - 0x64, 0xA4, 0xE5, 0x98, 0x0C, 0x39, 0x3A, 0xA2, 0x16, 0x68, 0xD9, 0x53, - /* x */ - 0xEE, 0xA2, 0xBA, 0xE7, 0xE1, 0x49, 0x78, 0x42, 0xF2, 0xDE, 0x77, 0x69, - 0xCF, 0xE9, 0xC9, 0x89, 0xC0, 0x72, 0xAD, 0x69, 0x6F, 0x48, 0x03, 0x4A, - /* y */ - 0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b, 0xb8, 0x2a, - 0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9, 0x70, 0xb2, 0xde, 0x15, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, - 0x5F, 0xB1, 0xA7, 0x24, 0xDC, 0x80, 0x41, 0x86, 0x48, 0xD8, 0xDD, 0x31 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 24 * 6]; -} _EC_X9_62_PRIME_192V3 = { - { - NID_X9_62_prime_field, 20, 24, 1 - }, - { - /* seed */ - 0xC4, 0x69, 0x68, 0x44, 0x35, 0xDE, 0xB3, 0x78, 0xC4, 0xB6, 0x5C, 0xA9, - 0x59, 0x1E, 0x2A, 0x57, 0x63, 0x05, 0x9A, 0x2E, - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0x22, 0x12, 0x3D, 0xC2, 0x39, 0x5A, 0x05, 0xCA, 0xA7, 0x42, 0x3D, 0xAE, - 0xCC, 0xC9, 0x47, 0x60, 0xA7, 0xD4, 0x62, 0x25, 0x6B, 0xD5, 0x69, 0x16, - /* x */ - 0x7D, 0x29, 0x77, 0x81, 0x00, 0xC6, 0x5A, 0x1D, 0xA1, 0x78, 0x37, 0x16, - 0x58, 0x8D, 0xCE, 0x2B, 0x8B, 0x4A, 0xEE, 0x8E, 0x22, 0x8F, 0x18, 0x96, - /* y */ - 0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49, 0xdc, 0xb6, - 0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76, 0x48, 0xa9, 0x43, 0xb0, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7A, 0x62, 0xD0, 0x31, 0xC8, 0x3F, 0x42, 0x94, 0xF6, 0x40, 0xEC, 0x13 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 30 * 6]; -} _EC_X9_62_PRIME_239V1 = { - { - NID_X9_62_prime_field, 20, 30, 1 - }, - { - /* seed */ - 0xE4, 0x3B, 0xB4, 0x60, 0xF0, 0xB8, 0x0C, 0xC0, 0xC0, 0xB0, 0x75, 0x79, - 0x8E, 0x94, 0x80, 0x60, 0xF8, 0x32, 0x1B, 0x7D, - /* p */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0x6B, 0x01, 0x6C, 0x3B, 0xDC, 0xF1, 0x89, 0x41, 0xD0, 0xD6, 0x54, 0x92, - 0x14, 0x75, 0xCA, 0x71, 0xA9, 0xDB, 0x2F, 0xB2, 0x7D, 0x1D, 0x37, 0x79, - 0x61, 0x85, 0xC2, 0x94, 0x2C, 0x0A, - /* x */ - 0x0F, 0xFA, 0x96, 0x3C, 0xDC, 0xA8, 0x81, 0x6C, 0xCC, 0x33, 0xB8, 0x64, - 0x2B, 0xED, 0xF9, 0x05, 0xC3, 0xD3, 0x58, 0x57, 0x3D, 0x3F, 0x27, 0xFB, - 0xBD, 0x3B, 0x3C, 0xB9, 0xAA, 0xAF, - /* y */ - 0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40, 0x54, 0xca, - 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18, 0xce, 0x22, 0x6b, 0x39, - 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae, - /* order */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7F, 0xFF, 0xFF, 0x9E, 0x5E, 0x9A, 0x9F, 0x5D, 0x90, 0x71, 0xFB, 0xD1, - 0x52, 0x26, 0x88, 0x90, 0x9D, 0x0B - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 30 * 6]; -} _EC_X9_62_PRIME_239V2 = { - { - NID_X9_62_prime_field, 20, 30, 1 - }, - { - /* seed */ - 0xE8, 0xB4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xCA, 0x3B, 0x80, 0x99, - 0x98, 0x2B, 0xE0, 0x9F, 0xCB, 0x9A, 0xE6, 0x16, - /* p */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0x61, 0x7F, 0xAB, 0x68, 0x32, 0x57, 0x6C, 0xBB, 0xFE, 0xD5, 0x0D, 0x99, - 0xF0, 0x24, 0x9C, 0x3F, 0xEE, 0x58, 0xB9, 0x4B, 0xA0, 0x03, 0x8C, 0x7A, - 0xE8, 0x4C, 0x8C, 0x83, 0x2F, 0x2C, - /* x */ - 0x38, 0xAF, 0x09, 0xD9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xC9, 0x21, 0xBB, - 0x5E, 0x9E, 0x26, 0x29, 0x6A, 0x3C, 0xDC, 0xF2, 0xF3, 0x57, 0x57, 0xA0, - 0xEA, 0xFD, 0x87, 0xB8, 0x30, 0xE7, - /* y */ - 0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d, 0xa0, 0xfc, - 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55, 0xde, 0x6e, 0xf4, 0x60, - 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba, - /* order */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x80, 0x00, 0x00, 0xCF, 0xA7, 0xE8, 0x59, 0x43, 0x77, 0xD4, 0x14, 0xC0, - 0x38, 0x21, 0xBC, 0x58, 0x20, 0x63 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 30 * 6]; -} _EC_X9_62_PRIME_239V3 = { - { - NID_X9_62_prime_field, 20, 30, 1 - }, - { - /* seed */ - 0x7D, 0x73, 0x74, 0x16, 0x8F, 0xFE, 0x34, 0x71, 0xB6, 0x0A, 0x85, 0x76, - 0x86, 0xA1, 0x94, 0x75, 0xD3, 0xBF, 0xA2, 0xFF, - /* p */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0x25, 0x57, 0x05, 0xFA, 0x2A, 0x30, 0x66, 0x54, 0xB1, 0xF4, 0xCB, 0x03, - 0xD6, 0xA7, 0x50, 0xA3, 0x0C, 0x25, 0x01, 0x02, 0xD4, 0x98, 0x87, 0x17, - 0xD9, 0xBA, 0x15, 0xAB, 0x6D, 0x3E, - /* x */ - 0x67, 0x68, 0xAE, 0x8E, 0x18, 0xBB, 0x92, 0xCF, 0xCF, 0x00, 0x5C, 0x94, - 0x9A, 0xA2, 0xC6, 0xD9, 0x48, 0x53, 0xD0, 0xE6, 0x60, 0xBB, 0xF8, 0x54, - 0xB1, 0xC9, 0x50, 0x5F, 0xE9, 0x5A, - /* y */ - 0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d, 0x55, 0x2b, - 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b, 0x6e, 0x81, 0x84, 0x99, - 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3, - /* order */ - 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x7F, 0xFF, 0xFF, 0x97, 0x5D, 0xEB, 0x41, 0xB3, 0xA6, 0x05, 0x7C, 0x3C, - 0x43, 0x21, 0x46, 0x52, 0x65, 0x51 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 32 * 6]; -} _EC_X9_62_PRIME_256V1 = { - { - NID_X9_62_prime_field, 20, 32, 1 - }, - { - /* seed */ - 0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, 0x78, 0xE1, - 0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90, - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, - 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, - 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B, - /* x */ - 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, - 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, - 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, - /* y */ - 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, - 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, - 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, - 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 - } -}; - -/* the secg prime curves (minus the nist and x9.62 prime curves) */ -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 14 * 6]; -} _EC_SECG_PRIME_112R1 = { - { - NID_X9_62_prime_field, 20, 14, 1 - }, - { - /* seed */ - 0x00, 0xF5, 0x0B, 0x02, 0x8E, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, - 0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3F, 0xB1, - /* p */ - 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, - 0x20, 0x8B, - /* a */ - 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, - 0x20, 0x88, - /* b */ - 0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, 0x11, 0x70, - 0x2B, 0x22, - /* x */ - 0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, 0xF9, 0xC2, - 0xF0, 0x98, - /* y */ - 0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e, 0x0f, 0xf7, - 0x75, 0x00, - /* order */ - 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, 0xAC, 0x65, - 0x61, 0xC5 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 14 * 6]; -} _EC_SECG_PRIME_112R2 = { - { - NID_X9_62_prime_field, 20, 14, 4 - }, - { - /* seed */ - 0x00, 0x27, 0x57, 0xA1, 0x11, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, - 0x51, 0x75, 0x53, 0x16, 0xC0, 0x5E, 0x0B, 0xD4, - /* p */ - 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, - 0x20, 0x8B, - /* a */ - 0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, 0x5C, 0x0E, - 0xF0, 0x2C, - /* b */ - 0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, 0x4C, 0x85, - 0xD7, 0x09, - /* x */ - 0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, 0xD0, 0x92, - 0x86, 0x43, - /* y */ - 0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3, 0x6e, 0x95, - 0x6e, 0x97, - /* order */ - 0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, 0x05, 0x20, - 0xD0, 0x4B - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 16 * 6]; -} _EC_SECG_PRIME_128R1 = { - { - NID_X9_62_prime_field, 20, 16, 1 - }, - { - /* seed */ - 0x00, 0x0E, 0x0D, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, - 0x0C, 0xC0, 0x3A, 0x44, 0x73, 0xD0, 0x36, 0x79, - /* p */ - 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFC, - /* b */ - 0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, 0x99, 0x3C, - 0x2C, 0xEE, 0x5E, 0xD3, - /* x */ - 0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, 0x60, 0x7C, - 0xA5, 0x2C, 0x5B, 0x86, - /* y */ - 0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d, 0xa2, 0x92, - 0xdd, 0xed, 0x7a, 0x83, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, 0x0D, 0x1B, - 0x90, 0x38, 0xA1, 0x15 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 16 * 6]; -} _EC_SECG_PRIME_128R2 = { - { - NID_X9_62_prime_field, 20, 16, 4 - }, - { - /* seed */ - 0x00, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x12, 0xD8, - 0xF0, 0x34, 0x31, 0xFC, 0xE6, 0x3B, 0x88, 0xF4, - /* p */ - 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, - /* a */ - 0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, 0xCC, 0x9B, - 0xBF, 0xF9, 0xAE, 0xE1, - /* b */ - 0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, 0x65, 0x58, - 0xBB, 0x6D, 0x8A, 0x5D, - /* x */ - 0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, 0x32, 0xA7, - 0xCD, 0xEB, 0xC1, 0x40, - /* y */ - 0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06, 0xfe, 0x80, - 0x5f, 0xc3, 0x4b, 0x44, - /* order */ - 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, 0x24, 0x72, - 0x06, 0x13, 0xB5, 0xA3 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 21 * 6]; -} _EC_SECG_PRIME_160K1 = { - { - NID_X9_62_prime_field, 0, 21, 1 - }, - { - /* no seed */ - /* p */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - /* x */ - 0x00, 0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, 0x01, 0x9E, - 0x76, 0x30, 0x36, 0xF4, 0xF5, 0xDD, 0x4D, 0x7E, 0xBB, - /* y */ - 0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b, 0xc2, 0x82, - 0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f, 0xee, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, - 0xFA, 0x16, 0xDF, 0xAB, 0x9A, 0xCA, 0x16, 0xB6, 0xB3 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 21 * 6]; -} _EC_SECG_PRIME_160R1 = { - { - NID_X9_62_prime_field, 20, 21, 1 - }, - { - /* seed */ - 0x10, 0x53, 0xCD, 0xE4, 0x2C, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, - 0x15, 0x17, 0x53, 0x3B, 0xF3, 0xF8, 0x33, 0x45, - /* p */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, - /* a */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFC, - /* b */ - 0x00, 0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, 0xAC, 0xF8, - 0x9F, 0x81, 0xD4, 0xD4, 0xAD, 0xC5, 0x65, 0xFA, 0x45, - /* x */ - 0x00, 0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, 0x64, 0x69, - 0x89, 0x68, 0xC3, 0x8B, 0xB9, 0x13, 0xCB, 0xFC, 0x82, - /* y */ - 0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59, 0xdc, 0xc9, - 0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb, 0x32, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4, - 0xC8, 0xF9, 0x27, 0xAE, 0xD3, 0xCA, 0x75, 0x22, 0x57 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 21 * 6]; -} _EC_SECG_PRIME_160R2 = { - { - NID_X9_62_prime_field, 20, 21, 1 - }, - { - /* seed */ - 0xB9, 0x9B, 0x99, 0xB0, 0x99, 0xB3, 0x23, 0xE0, 0x27, 0x09, 0xA4, 0xD6, - 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51, - /* p */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73, - /* a */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x70, - /* b */ - 0x00, 0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, 0x57, 0x27, - 0x49, 0x04, 0x66, 0x4D, 0x5A, 0xF5, 0x03, 0x88, 0xBA, - /* x */ - 0x00, 0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, 0x4F, 0xF1, - 0x1B, 0x30, 0xF7, 0x19, 0x9D, 0x31, 0x44, 0xCE, 0x6D, - /* y */ - 0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0, 0x71, 0xfa, - 0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f, 0x2e, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, - 0x1E, 0xE7, 0x86, 0xA8, 0x18, 0xF3, 0xA1, 0xA1, 0x6B - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 24 * 6]; -} _EC_SECG_PRIME_192K1 = { - { - NID_X9_62_prime_field, 0, 24, 1 - }, - { - /* no seed */ - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEE, 0x37, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - /* x */ - 0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, 0x7D, 0x02, - 0x80, 0xB7, 0xF4, 0x34, 0x1D, 0xA5, 0xD1, 0xB1, 0xEA, 0xE0, 0x6C, 0x7D, - /* y */ - 0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41, 0x63, 0xd0, - 0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88, 0xd9, 0x5e, 0x2f, 0x9d, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, - 0x26, 0xF2, 0xFC, 0x17, 0x0F, 0x69, 0x46, 0x6A, 0x74, 0xDE, 0xFD, 0x8D - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 29 * 6]; -} _EC_SECG_PRIME_224K1 = { - { - NID_X9_62_prime_field, 0, 29, 1 - }, - { - /* no seed */ - /* p */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFE, 0xFF, 0xFF, 0xE5, 0x6D, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, - /* x */ - 0x00, 0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, 0xFC, 0x28, - 0xA1, 0x69, 0xA4, 0x67, 0xE9, 0xE4, 0x70, 0x75, 0xA9, 0x0F, 0x7E, 0x65, - 0x0E, 0xB6, 0xB7, 0xA4, 0x5C, - /* y */ - 0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82, 0xca, 0xfb, - 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd, 0x59, 0xe2, 0xca, 0x4b, - 0xdb, 0x55, 0x6d, 0x61, 0xa5, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0xDC, 0xE8, 0xD2, 0xEC, 0x61, 0x84, 0xCA, 0xF0, 0xA9, - 0x71, 0x76, 0x9F, 0xB1, 0xF7 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 32 * 6]; -} _EC_SECG_PRIME_256K1 = { - { - NID_X9_62_prime_field, 0, 32, 1 - }, - { - /* no seed */ - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - /* x */ - 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, - 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, - 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, - /* y */ - 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, - 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, - 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, - 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 - } -}; - -/* some wap/wtls curves */ -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 15 * 6]; -} _EC_WTLS_8 = { - { - NID_X9_62_prime_field, 0, 15, 1 - }, - { - /* no seed */ - /* p */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFD, 0xE7, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x03, - /* x */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, - /* y */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x02, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEC, 0xEA, 0x55, 0x1A, - 0xD8, 0x37, 0xE9 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 21 * 6]; -} _EC_WTLS_9 = { - { - NID_X9_62_prime_field, 0, 21, 1 - }, - { - /* no seed */ - /* p */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x8F, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, - /* x */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* y */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCD, - 0xC9, 0x8A, 0xE0, 0xE2, 0xDE, 0x57, 0x4A, 0xBF, 0x33 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 28 * 6]; -} _EC_WTLS_12 = { - { - NID_X9_62_prime_field, 0, 28, 1 - }, - { - /* no seed */ - /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - /* a */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFE, - /* b */ - 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, - 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, - 0x23, 0x55, 0xFF, 0xB4, - /* x */ - 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, - 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, - 0x11, 0x5C, 0x1D, 0x21, - /* y */ - 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, - 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, - 0x85, 0x00, 0x7e, 0x34, - /* order */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, - 0x5C, 0x5C, 0x2A, 0x3D - } -}; - -#ifndef OPENSSL_NO_EC2M - -/* characteristic two curves */ -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 15 * 6]; -} _EC_SECG_CHAR2_113R1 = { - { - NID_X9_62_characteristic_two_field, 20, 15, 2 - }, - { - /* seed */ - 0x10, 0xE7, 0x23, 0xAB, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, - 0x17, 0x56, 0xFE, 0xBF, 0x8F, 0xCB, 0x49, 0xA9, - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, - /* a */ - 0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64, 0x9C, 0xE8, - 0x58, 0x20, 0xF7, - /* b */ - 0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18, 0x8B, 0xE0, - 0xE9, 0xC7, 0x23, - /* x */ - 0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07, 0xD7, 0x35, - 0x62, 0xC1, 0x0F, - /* y */ - 0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1, 0x31, 0x5E, - 0xD3, 0x18, 0x86, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC, 0xEC, 0x8A, - 0x39, 0xE5, 0x6F - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 15 * 6]; -} _EC_SECG_CHAR2_113R2 = { - { - NID_X9_62_characteristic_two_field, 20, 15, 2 - }, - { - /* seed */ - 0x10, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6, - 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x5D, - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, - /* a */ - 0x00, 0x68, 0x99, 0x18, 0xDB, 0xEC, 0x7E, 0x5A, 0x0D, 0xD6, 0xDF, 0xC0, - 0xAA, 0x55, 0xC7, - /* b */ - 0x00, 0x95, 0xE9, 0xA9, 0xEC, 0x9B, 0x29, 0x7B, 0xD4, 0xBF, 0x36, 0xE0, - 0x59, 0x18, 0x4F, - /* x */ - 0x01, 0xA5, 0x7A, 0x6A, 0x7B, 0x26, 0xCA, 0x5E, 0xF5, 0x2F, 0xCD, 0xB8, - 0x16, 0x47, 0x97, - /* y */ - 0x00, 0xB3, 0xAD, 0xC9, 0x4E, 0xD1, 0xFE, 0x67, 0x4C, 0x06, 0xE6, 0x95, - 0xBA, 0xBA, 0x1D, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x78, 0x9B, 0x24, - 0x96, 0xAF, 0x93 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 17 * 6]; -} _EC_SECG_CHAR2_131R1 = { - { - NID_X9_62_characteristic_two_field, 20, 17, 2 - }, - { - /* seed */ - 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x98, 0x5B, 0xD3, - 0xAD, 0xBA, 0xDA, 0x21, 0xB4, 0x3A, 0x97, 0xE2, - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x0D, - /* a */ - 0x07, 0xA1, 0x1B, 0x09, 0xA7, 0x6B, 0x56, 0x21, 0x44, 0x41, 0x8F, 0xF3, - 0xFF, 0x8C, 0x25, 0x70, 0xB8, - /* b */ - 0x02, 0x17, 0xC0, 0x56, 0x10, 0x88, 0x4B, 0x63, 0xB9, 0xC6, 0xC7, 0x29, - 0x16, 0x78, 0xF9, 0xD3, 0x41, - /* x */ - 0x00, 0x81, 0xBA, 0xF9, 0x1F, 0xDF, 0x98, 0x33, 0xC4, 0x0F, 0x9C, 0x18, - 0x13, 0x43, 0x63, 0x83, 0x99, - /* y */ - 0x07, 0x8C, 0x6E, 0x7E, 0xA3, 0x8C, 0x00, 0x1F, 0x73, 0xC8, 0x13, 0x4B, - 0x1B, 0x4E, 0xF9, 0xE1, 0x50, - /* order */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x23, 0x95, - 0x3A, 0x94, 0x64, 0xB5, 0x4D - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 17 * 6]; -} _EC_SECG_CHAR2_131R2 = { - { - NID_X9_62_characteristic_two_field, 20, 17, 2 - }, - { - /* seed */ - 0x98, 0x5B, 0xD3, 0xAD, 0xBA, 0xD4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, - 0x15, 0x17, 0x5A, 0x21, 0xB4, 0x3A, 0x97, 0xE3, - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x0D, - /* a */ - 0x03, 0xE5, 0xA8, 0x89, 0x19, 0xD7, 0xCA, 0xFC, 0xBF, 0x41, 0x5F, 0x07, - 0xC2, 0x17, 0x65, 0x73, 0xB2, - /* b */ - 0x04, 0xB8, 0x26, 0x6A, 0x46, 0xC5, 0x56, 0x57, 0xAC, 0x73, 0x4C, 0xE3, - 0x8F, 0x01, 0x8F, 0x21, 0x92, - /* x */ - 0x03, 0x56, 0xDC, 0xD8, 0xF2, 0xF9, 0x50, 0x31, 0xAD, 0x65, 0x2D, 0x23, - 0x95, 0x1B, 0xB3, 0x66, 0xA8, - /* y */ - 0x06, 0x48, 0xF0, 0x6D, 0x86, 0x79, 0x40, 0xA5, 0x36, 0x6D, 0x9E, 0x26, - 0x5D, 0xE9, 0xEB, 0x24, 0x0F, - /* order */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, 0x54, 0xA2, - 0x33, 0x04, 0x9B, 0xA9, 0x8F - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 21 * 6]; -} _EC_NIST_CHAR2_163K = { - { - NID_X9_62_characteristic_two_field, 0, 21, 2 - }, - { - /* no seed */ - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* x */ - 0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA, 0x07, 0xD7, - 0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE, 0xE8, - /* y */ - 0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38, 0xFF, 0x58, 0x32, 0x1F, 0x2E, - 0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3, 0xD9, - /* order */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, - 0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5, 0xEF - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 21 * 6]; -} _EC_SECG_CHAR2_163R1 = { - { - NID_X9_62_characteristic_two_field, 0, 21, 2 - }, - { - /* no seed */ -# if 0 - /* - * The algorithm used to derive the curve parameters from the seed - * used here is slightly different than the algorithm described in - * X9.62 . - */ - 0x24, 0xB7, 0xB1, 0x37, 0xC8, 0xA1, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, - 0x61, 0x51, 0x75, 0x6F, 0xD0, 0xDA, 0x2E, 0x5C, -# endif - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, - /* a */ - 0x07, 0xB6, 0x88, 0x2C, 0xAA, 0xEF, 0xA8, 0x4F, 0x95, 0x54, 0xFF, 0x84, - 0x28, 0xBD, 0x88, 0xE2, 0x46, 0xD2, 0x78, 0x2A, 0xE2, - /* b */ - 0x07, 0x13, 0x61, 0x2D, 0xCD, 0xDC, 0xB4, 0x0A, 0xAB, 0x94, 0x6B, 0xDA, - 0x29, 0xCA, 0x91, 0xF7, 0x3A, 0xF9, 0x58, 0xAF, 0xD9, - /* x */ - 0x03, 0x69, 0x97, 0x96, 0x97, 0xAB, 0x43, 0x89, 0x77, 0x89, 0x56, 0x67, - 0x89, 0x56, 0x7F, 0x78, 0x7A, 0x78, 0x76, 0xA6, 0x54, - /* y */ - 0x00, 0x43, 0x5E, 0xDB, 0x42, 0xEF, 0xAF, 0xB2, 0x98, 0x9D, 0x51, 0xFE, - 0xFC, 0xE3, 0xC8, 0x09, 0x88, 0xF4, 0x1F, 0xF8, 0x83, - /* order */ - 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, - 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27, 0x9B - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 21 * 6]; -} _EC_NIST_CHAR2_163B = { - { - NID_X9_62_characteristic_two_field, 0, 21, 2 - }, - { - /* no seed */ -# if 0 - /* - * The seed here was used to created the curve parameters in normal - * basis representation (and not the polynomial representation used - * here) - */ - 0x85, 0xE2, 0x5B, 0xFE, 0x5C, 0x86, 0x22, 0x6C, 0xDB, 0x12, 0x01, 0x6F, - 0x75, 0x53, 0xF9, 0xD0, 0xE6, 0x93, 0xA2, 0x68, -# endif - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* b */ - 0x02, 0x0A, 0x60, 0x19, 0x07, 0xB8, 0xC9, 0x53, 0xCA, 0x14, 0x81, 0xEB, - 0x10, 0x51, 0x2F, 0x78, 0x74, 0x4A, 0x32, 0x05, 0xFD, - /* x */ - 0x03, 0xF0, 0xEB, 0xA1, 0x62, 0x86, 0xA2, 0xD5, 0x7E, 0xA0, 0x99, 0x11, - 0x68, 0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E, 0x36, - /* y */ - 0x00, 0xD5, 0x1F, 0xBC, 0x6C, 0x71, 0xA0, 0x09, 0x4F, 0xA2, 0xCD, 0xD5, - 0x45, 0xB1, 0x1C, 0x5C, 0x0C, 0x79, 0x73, 0x24, 0xF1, - /* order */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, - 0xFE, 0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C, 0x33 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 25 * 6]; -} _EC_SECG_CHAR2_193R1 = { - { - NID_X9_62_characteristic_two_field, 20, 25, 2 - }, - { - /* seed */ - 0x10, 0x3F, 0xAE, 0xC7, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, - 0x75, 0x77, 0x7F, 0xC5, 0xB1, 0x91, 0xEF, 0x30, - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x01, - /* a */ - 0x00, 0x17, 0x85, 0x8F, 0xEB, 0x7A, 0x98, 0x97, 0x51, 0x69, 0xE1, 0x71, - 0xF7, 0x7B, 0x40, 0x87, 0xDE, 0x09, 0x8A, 0xC8, 0xA9, 0x11, 0xDF, 0x7B, - 0x01, - /* b */ - 0x00, 0xFD, 0xFB, 0x49, 0xBF, 0xE6, 0xC3, 0xA8, 0x9F, 0xAC, 0xAD, 0xAA, - 0x7A, 0x1E, 0x5B, 0xBC, 0x7C, 0xC1, 0xC2, 0xE5, 0xD8, 0x31, 0x47, 0x88, - 0x14, - /* x */ - 0x01, 0xF4, 0x81, 0xBC, 0x5F, 0x0F, 0xF8, 0x4A, 0x74, 0xAD, 0x6C, 0xDF, - 0x6F, 0xDE, 0xF4, 0xBF, 0x61, 0x79, 0x62, 0x53, 0x72, 0xD8, 0xC0, 0xC5, - 0xE1, - /* y */ - 0x00, 0x25, 0xE3, 0x99, 0xF2, 0x90, 0x37, 0x12, 0xCC, 0xF3, 0xEA, 0x9E, - 0x3A, 0x1A, 0xD1, 0x7F, 0xB0, 0xB3, 0x20, 0x1B, 0x6A, 0xF7, 0xCE, 0x1B, - 0x05, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xC7, 0xF3, 0x4A, 0x77, 0x8F, 0x44, 0x3A, 0xCC, 0x92, 0x0E, 0xBA, - 0x49 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 25 * 6]; -} _EC_SECG_CHAR2_193R2 = { - { - NID_X9_62_characteristic_two_field, 20, 25, 2 - }, - { - /* seed */ - 0x10, 0xB7, 0xB4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51, - 0x37, 0xC8, 0xA1, 0x6F, 0xD0, 0xDA, 0x22, 0x11, - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, - 0x01, - /* a */ - 0x01, 0x63, 0xF3, 0x5A, 0x51, 0x37, 0xC2, 0xCE, 0x3E, 0xA6, 0xED, 0x86, - 0x67, 0x19, 0x0B, 0x0B, 0xC4, 0x3E, 0xCD, 0x69, 0x97, 0x77, 0x02, 0x70, - 0x9B, - /* b */ - 0x00, 0xC9, 0xBB, 0x9E, 0x89, 0x27, 0xD4, 0xD6, 0x4C, 0x37, 0x7E, 0x2A, - 0xB2, 0x85, 0x6A, 0x5B, 0x16, 0xE3, 0xEF, 0xB7, 0xF6, 0x1D, 0x43, 0x16, - 0xAE, - /* x */ - 0x00, 0xD9, 0xB6, 0x7D, 0x19, 0x2E, 0x03, 0x67, 0xC8, 0x03, 0xF3, 0x9E, - 0x1A, 0x7E, 0x82, 0xCA, 0x14, 0xA6, 0x51, 0x35, 0x0A, 0xAE, 0x61, 0x7E, - 0x8F, - /* y */ - 0x01, 0xCE, 0x94, 0x33, 0x56, 0x07, 0xC3, 0x04, 0xAC, 0x29, 0xE7, 0xDE, - 0xFB, 0xD9, 0xCA, 0x01, 0xF5, 0x96, 0xF9, 0x27, 0x22, 0x4C, 0xDE, 0xCF, - 0x6C, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x5A, 0xAB, 0x56, 0x1B, 0x00, 0x54, 0x13, 0xCC, 0xD4, 0xEE, 0x99, - 0xD5 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 30 * 6]; -} _EC_NIST_CHAR2_233K = { - { - NID_X9_62_characteristic_two_field, 0, 30, 4 - }, - { - /* no seed */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* x */ - 0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2, - 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C, - 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26, - /* y */ - 0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A, - 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0, - 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3, - /* order */ - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB, - 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 30 * 6]; -} _EC_NIST_CHAR2_233B = { - { - NID_X9_62_characteristic_two_field, 20, 30, 2 - }, - { - /* seed */ - 0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1, 0x4B, 0x34, - 0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3, - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* b */ - 0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C, 0x09, 0x23, - 0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9, 0xCE, 0x42, 0x81, 0xFE, - 0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD, - /* x */ - 0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21, 0x39, 0xF1, - 0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F, 0x8B, 0x36, 0xF8, 0xF8, - 0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B, - /* y */ - 0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78, 0xE5, 0x85, - 0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67, 0xA7, 0xCA, 0x36, 0x71, - 0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F, 0x8A, 0x69, 0x22, 0x03, - 0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 30 * 6]; -} _EC_SECG_CHAR2_239K1 = { - { - NID_X9_62_characteristic_two_field, 0, 30, 4 - }, - { - /* no seed */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* x */ - 0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09, 0x88, 0xA6, - 0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C, 0xC2, 0xCC, 0x7B, 0x2A, - 0x65, 0x55, 0x19, 0x30, 0x35, 0xDC, - /* y */ - 0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01, 0x1C, 0x10, - 0x30, 0x89, 0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75, 0xFC, 0x31, 0x2A, 0x5D, - 0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA, - /* order */ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C, 0xB6, 0xE9, 0x1F, 0x1C, - 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 36 * 6]; -} _EC_NIST_CHAR2_283K = { - { - NID_X9_62_characteristic_two_field, 0, 36, 4 - }, - { - /* no seed */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* x */ - 0x05, 0x03, 0x21, 0x3F, 0x78, 0xCA, 0x44, 0x88, 0x3F, 0x1A, 0x3B, 0x81, - 0x62, 0xF1, 0x88, 0xE5, 0x53, 0xCD, 0x26, 0x5F, 0x23, 0xC1, 0x56, 0x7A, - 0x16, 0x87, 0x69, 0x13, 0xB0, 0xC2, 0xAC, 0x24, 0x58, 0x49, 0x28, 0x36, - /* y */ - 0x01, 0xCC, 0xDA, 0x38, 0x0F, 0x1C, 0x9E, 0x31, 0x8D, 0x90, 0xF9, 0x5D, - 0x07, 0xE5, 0x42, 0x6F, 0xE8, 0x7E, 0x45, 0xC0, 0xE8, 0x18, 0x46, 0x98, - 0xE4, 0x59, 0x62, 0x36, 0x4E, 0x34, 0x11, 0x61, 0x77, 0xDD, 0x22, 0x59, - /* order */ - 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xAE, 0x2E, 0xD0, 0x75, 0x77, - 0x26, 0x5D, 0xFF, 0x7F, 0x94, 0x45, 0x1E, 0x06, 0x1E, 0x16, 0x3C, 0x61 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 36 * 6]; -} _EC_NIST_CHAR2_283B = { - { - NID_X9_62_characteristic_two_field, 20, 36, 2 - }, - { - /* no seed */ - 0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, 0xD5, 0xB6, - 0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE, - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* b */ - 0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A, - 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2, - 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5, - /* x */ - 0x05, 0xF9, 0x39, 0x25, 0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93, 0x4F, 0x8C, - 0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8, 0x55, 0x7E, 0xAC, 0x9C, - 0x80, 0xE2, 0xE1, 0x98, 0xF8, 0xCD, 0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53, - /* y */ - 0x03, 0x67, 0x68, 0x54, 0xFE, 0x24, 0x14, 0x1C, 0xB9, 0x8F, 0xE6, 0xD4, - 0xB2, 0x0D, 0x02, 0xB4, 0x51, 0x6F, 0xF7, 0x02, 0x35, 0x0E, 0xDD, 0xB0, - 0x82, 0x67, 0x79, 0xC8, 0x13, 0xF0, 0xDF, 0x45, 0xBE, 0x81, 0x12, 0xF4, - /* order */ - 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90, 0x39, 0x96, 0x60, 0xFC, - 0x93, 0x8A, 0x90, 0x16, 0x5B, 0x04, 0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 52 * 6]; -} _EC_NIST_CHAR2_409K = { - { - NID_X9_62_characteristic_two_field, 0, 52, 4 - }, - { - /* no seed */ - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - /* x */ - 0x00, 0x60, 0xF0, 0x5F, 0x65, 0x8F, 0x49, 0xC1, 0xAD, 0x3A, 0xB1, 0x89, - 0x0F, 0x71, 0x84, 0x21, 0x0E, 0xFD, 0x09, 0x87, 0xE3, 0x07, 0xC8, 0x4C, - 0x27, 0xAC, 0xCF, 0xB8, 0xF9, 0xF6, 0x7C, 0xC2, 0xC4, 0x60, 0x18, 0x9E, - 0xB5, 0xAA, 0xAA, 0x62, 0xEE, 0x22, 0x2E, 0xB1, 0xB3, 0x55, 0x40, 0xCF, - 0xE9, 0x02, 0x37, 0x46, - /* y */ - 0x01, 0xE3, 0x69, 0x05, 0x0B, 0x7C, 0x4E, 0x42, 0xAC, 0xBA, 0x1D, 0xAC, - 0xBF, 0x04, 0x29, 0x9C, 0x34, 0x60, 0x78, 0x2F, 0x91, 0x8E, 0xA4, 0x27, - 0xE6, 0x32, 0x51, 0x65, 0xE9, 0xEA, 0x10, 0xE3, 0xDA, 0x5F, 0x6C, 0x42, - 0xE9, 0xC5, 0x52, 0x15, 0xAA, 0x9C, 0xA2, 0x7A, 0x58, 0x63, 0xEC, 0x48, - 0xD8, 0xE0, 0x28, 0x6B, - /* order */ - 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFE, 0x5F, 0x83, 0xB2, 0xD4, 0xEA, 0x20, 0x40, 0x0E, 0xC4, - 0x55, 0x7D, 0x5E, 0xD3, 0xE3, 0xE7, 0xCA, 0x5B, 0x4B, 0x5C, 0x83, 0xB8, - 0xE0, 0x1E, 0x5F, 0xCF - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 52 * 6]; -} _EC_NIST_CHAR2_409B = { - { - NID_X9_62_characteristic_two_field, 20, 52, 2 - }, - { - /* seed */ - 0x40, 0x99, 0xB5, 0xA4, 0x57, 0xF9, 0xD6, 0x9F, 0x79, 0x21, 0x3D, 0x09, - 0x4C, 0x4B, 0xCD, 0x4D, 0x42, 0x62, 0x21, 0x0B, - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, - /* b */ - 0x00, 0x21, 0xA5, 0xC2, 0xC8, 0xEE, 0x9F, 0xEB, 0x5C, 0x4B, 0x9A, 0x75, - 0x3B, 0x7B, 0x47, 0x6B, 0x7F, 0xD6, 0x42, 0x2E, 0xF1, 0xF3, 0xDD, 0x67, - 0x47, 0x61, 0xFA, 0x99, 0xD6, 0xAC, 0x27, 0xC8, 0xA9, 0xA1, 0x97, 0xB2, - 0x72, 0x82, 0x2F, 0x6C, 0xD5, 0x7A, 0x55, 0xAA, 0x4F, 0x50, 0xAE, 0x31, - 0x7B, 0x13, 0x54, 0x5F, - /* x */ - 0x01, 0x5D, 0x48, 0x60, 0xD0, 0x88, 0xDD, 0xB3, 0x49, 0x6B, 0x0C, 0x60, - 0x64, 0x75, 0x62, 0x60, 0x44, 0x1C, 0xDE, 0x4A, 0xF1, 0x77, 0x1D, 0x4D, - 0xB0, 0x1F, 0xFE, 0x5B, 0x34, 0xE5, 0x97, 0x03, 0xDC, 0x25, 0x5A, 0x86, - 0x8A, 0x11, 0x80, 0x51, 0x56, 0x03, 0xAE, 0xAB, 0x60, 0x79, 0x4E, 0x54, - 0xBB, 0x79, 0x96, 0xA7, - /* y */ - 0x00, 0x61, 0xB1, 0xCF, 0xAB, 0x6B, 0xE5, 0xF3, 0x2B, 0xBF, 0xA7, 0x83, - 0x24, 0xED, 0x10, 0x6A, 0x76, 0x36, 0xB9, 0xC5, 0xA7, 0xBD, 0x19, 0x8D, - 0x01, 0x58, 0xAA, 0x4F, 0x54, 0x88, 0xD0, 0x8F, 0x38, 0x51, 0x4F, 0x1F, - 0xDF, 0x4B, 0x4F, 0x40, 0xD2, 0x18, 0x1B, 0x36, 0x81, 0xC3, 0x64, 0xBA, - 0x02, 0x73, 0xC7, 0x06, - /* order */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0xE2, 0xAA, 0xD6, 0xA6, 0x12, 0xF3, 0x33, 0x07, 0xBE, - 0x5F, 0xA4, 0x7C, 0x3C, 0x9E, 0x05, 0x2F, 0x83, 0x81, 0x64, 0xCD, 0x37, - 0xD9, 0xA2, 0x11, 0x73 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 72 * 6]; -} _EC_NIST_CHAR2_571K = { - { - NID_X9_62_characteristic_two_field, 0, 72, 4 - }, - { - /* no seed */ - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* x */ - 0x02, 0x6E, 0xB7, 0xA8, 0x59, 0x92, 0x3F, 0xBC, 0x82, 0x18, 0x96, 0x31, - 0xF8, 0x10, 0x3F, 0xE4, 0xAC, 0x9C, 0xA2, 0x97, 0x00, 0x12, 0xD5, 0xD4, - 0x60, 0x24, 0x80, 0x48, 0x01, 0x84, 0x1C, 0xA4, 0x43, 0x70, 0x95, 0x84, - 0x93, 0xB2, 0x05, 0xE6, 0x47, 0xDA, 0x30, 0x4D, 0xB4, 0xCE, 0xB0, 0x8C, - 0xBB, 0xD1, 0xBA, 0x39, 0x49, 0x47, 0x76, 0xFB, 0x98, 0x8B, 0x47, 0x17, - 0x4D, 0xCA, 0x88, 0xC7, 0xE2, 0x94, 0x52, 0x83, 0xA0, 0x1C, 0x89, 0x72, - /* y */ - 0x03, 0x49, 0xDC, 0x80, 0x7F, 0x4F, 0xBF, 0x37, 0x4F, 0x4A, 0xEA, 0xDE, - 0x3B, 0xCA, 0x95, 0x31, 0x4D, 0xD5, 0x8C, 0xEC, 0x9F, 0x30, 0x7A, 0x54, - 0xFF, 0xC6, 0x1E, 0xFC, 0x00, 0x6D, 0x8A, 0x2C, 0x9D, 0x49, 0x79, 0xC0, - 0xAC, 0x44, 0xAE, 0xA7, 0x4F, 0xBE, 0xBB, 0xB9, 0xF7, 0x72, 0xAE, 0xDC, - 0xB6, 0x20, 0xB0, 0x1A, 0x7B, 0xA7, 0xAF, 0x1B, 0x32, 0x04, 0x30, 0xC8, - 0x59, 0x19, 0x84, 0xF6, 0x01, 0xCD, 0x4C, 0x14, 0x3E, 0xF1, 0xC7, 0xA3, - /* order */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x13, 0x18, 0x50, 0xE1, 0xF1, 0x9A, 0x63, 0xE4, 0xB3, 0x91, 0xA8, 0xDB, - 0x91, 0x7F, 0x41, 0x38, 0xB6, 0x30, 0xD8, 0x4B, 0xE5, 0xD6, 0x39, 0x38, - 0x1E, 0x91, 0xDE, 0xB4, 0x5C, 0xFE, 0x77, 0x8F, 0x63, 0x7C, 0x10, 0x01 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 72 * 6]; -} _EC_NIST_CHAR2_571B = { - { - NID_X9_62_characteristic_two_field, 20, 72, 2 - }, - { - /* seed */ - 0x2A, 0xA0, 0x58, 0xF7, 0x3A, 0x0E, 0x33, 0xAB, 0x48, 0x6B, 0x0F, 0x61, - 0x04, 0x10, 0xC5, 0x3A, 0x7F, 0x13, 0x23, 0x10, - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* b */ - 0x02, 0xF4, 0x0E, 0x7E, 0x22, 0x21, 0xF2, 0x95, 0xDE, 0x29, 0x71, 0x17, - 0xB7, 0xF3, 0xD6, 0x2F, 0x5C, 0x6A, 0x97, 0xFF, 0xCB, 0x8C, 0xEF, 0xF1, - 0xCD, 0x6B, 0xA8, 0xCE, 0x4A, 0x9A, 0x18, 0xAD, 0x84, 0xFF, 0xAB, 0xBD, - 0x8E, 0xFA, 0x59, 0x33, 0x2B, 0xE7, 0xAD, 0x67, 0x56, 0xA6, 0x6E, 0x29, - 0x4A, 0xFD, 0x18, 0x5A, 0x78, 0xFF, 0x12, 0xAA, 0x52, 0x0E, 0x4D, 0xE7, - 0x39, 0xBA, 0xCA, 0x0C, 0x7F, 0xFE, 0xFF, 0x7F, 0x29, 0x55, 0x72, 0x7A, - /* x */ - 0x03, 0x03, 0x00, 0x1D, 0x34, 0xB8, 0x56, 0x29, 0x6C, 0x16, 0xC0, 0xD4, - 0x0D, 0x3C, 0xD7, 0x75, 0x0A, 0x93, 0xD1, 0xD2, 0x95, 0x5F, 0xA8, 0x0A, - 0xA5, 0xF4, 0x0F, 0xC8, 0xDB, 0x7B, 0x2A, 0xBD, 0xBD, 0xE5, 0x39, 0x50, - 0xF4, 0xC0, 0xD2, 0x93, 0xCD, 0xD7, 0x11, 0xA3, 0x5B, 0x67, 0xFB, 0x14, - 0x99, 0xAE, 0x60, 0x03, 0x86, 0x14, 0xF1, 0x39, 0x4A, 0xBF, 0xA3, 0xB4, - 0xC8, 0x50, 0xD9, 0x27, 0xE1, 0xE7, 0x76, 0x9C, 0x8E, 0xEC, 0x2D, 0x19, - /* y */ - 0x03, 0x7B, 0xF2, 0x73, 0x42, 0xDA, 0x63, 0x9B, 0x6D, 0xCC, 0xFF, 0xFE, - 0xB7, 0x3D, 0x69, 0xD7, 0x8C, 0x6C, 0x27, 0xA6, 0x00, 0x9C, 0xBB, 0xCA, - 0x19, 0x80, 0xF8, 0x53, 0x39, 0x21, 0xE8, 0xA6, 0x84, 0x42, 0x3E, 0x43, - 0xBA, 0xB0, 0x8A, 0x57, 0x62, 0x91, 0xAF, 0x8F, 0x46, 0x1B, 0xB2, 0xA8, - 0xB3, 0x53, 0x1D, 0x2F, 0x04, 0x85, 0xC1, 0x9B, 0x16, 0xE2, 0xF1, 0x51, - 0x6E, 0x23, 0xDD, 0x3C, 0x1A, 0x48, 0x27, 0xAF, 0x1B, 0x8A, 0xC1, 0x5B, - /* order */ - 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xE6, 0x61, 0xCE, 0x18, 0xFF, 0x55, 0x98, 0x73, 0x08, 0x05, 0x9B, 0x18, - 0x68, 0x23, 0x85, 0x1E, 0xC7, 0xDD, 0x9C, 0xA1, 0x16, 0x1D, 0xE9, 0x3D, - 0x51, 0x74, 0xD6, 0x6E, 0x83, 0x82, 0xE9, 0xBB, 0x2F, 0xE8, 0x4E, 0x47 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 21 * 6]; -} _EC_X9_62_CHAR2_163V1 = { - { - NID_X9_62_characteristic_two_field, 20, 21, 2 - }, - { - /* seed */ - 0xD2, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6, - 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x54, - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, - /* a */ - 0x07, 0x25, 0x46, 0xB5, 0x43, 0x52, 0x34, 0xA4, 0x22, 0xE0, 0x78, 0x96, - 0x75, 0xF4, 0x32, 0xC8, 0x94, 0x35, 0xDE, 0x52, 0x42, - /* b */ - 0x00, 0xC9, 0x51, 0x7D, 0x06, 0xD5, 0x24, 0x0D, 0x3C, 0xFF, 0x38, 0xC7, - 0x4B, 0x20, 0xB6, 0xCD, 0x4D, 0x6F, 0x9D, 0xD4, 0xD9, - /* x */ - 0x07, 0xAF, 0x69, 0x98, 0x95, 0x46, 0x10, 0x3D, 0x79, 0x32, 0x9F, 0xCC, - 0x3D, 0x74, 0x88, 0x0F, 0x33, 0xBB, 0xE8, 0x03, 0xCB, - /* y */ - 0x01, 0xEC, 0x23, 0x21, 0x1B, 0x59, 0x66, 0xAD, 0xEA, 0x1D, 0x3F, 0x87, - 0xF7, 0xEA, 0x58, 0x48, 0xAE, 0xF0, 0xB7, 0xCA, 0x9F, - /* order */ - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE6, - 0x0F, 0xC8, 0x82, 0x1C, 0xC7, 0x4D, 0xAE, 0xAF, 0xC1 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 21 * 6]; -} _EC_X9_62_CHAR2_163V2 = { - { - NID_X9_62_characteristic_two_field, 20, 21, 2 - }, - { - /* seed */ - 0x53, 0x81, 0x4C, 0x05, 0x0D, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, - 0x15, 0x17, 0x58, 0x0C, 0xA4, 0xE2, 0x9F, 0xFD, - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, - /* a */ - 0x01, 0x08, 0xB3, 0x9E, 0x77, 0xC4, 0xB1, 0x08, 0xBE, 0xD9, 0x81, 0xED, - 0x0E, 0x89, 0x0E, 0x11, 0x7C, 0x51, 0x1C, 0xF0, 0x72, - /* b */ - 0x06, 0x67, 0xAC, 0xEB, 0x38, 0xAF, 0x4E, 0x48, 0x8C, 0x40, 0x74, 0x33, - 0xFF, 0xAE, 0x4F, 0x1C, 0x81, 0x16, 0x38, 0xDF, 0x20, - /* x */ - 0x00, 0x24, 0x26, 0x6E, 0x4E, 0xB5, 0x10, 0x6D, 0x0A, 0x96, 0x4D, 0x92, - 0xC4, 0x86, 0x0E, 0x26, 0x71, 0xDB, 0x9B, 0x6C, 0xC5, - /* y */ - 0x07, 0x9F, 0x68, 0x4D, 0xDF, 0x66, 0x84, 0xC5, 0xCD, 0x25, 0x8B, 0x38, - 0x90, 0x02, 0x1B, 0x23, 0x86, 0xDF, 0xD1, 0x9F, 0xC5, - /* order */ - 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF6, - 0x4D, 0xE1, 0x15, 0x1A, 0xDB, 0xB7, 0x8F, 0x10, 0xA7 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 21 * 6]; -} _EC_X9_62_CHAR2_163V3 = { - { - NID_X9_62_characteristic_two_field, 20, 21, 2 - }, - { - /* seed */ - 0x50, 0xCB, 0xF1, 0xD9, 0x5C, 0xA9, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, - 0x61, 0x51, 0x75, 0xF1, 0x6A, 0x36, 0xA3, 0xB8, - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, - /* a */ - 0x07, 0xA5, 0x26, 0xC6, 0x3D, 0x3E, 0x25, 0xA2, 0x56, 0xA0, 0x07, 0x69, - 0x9F, 0x54, 0x47, 0xE3, 0x2A, 0xE4, 0x56, 0xB5, 0x0E, - /* b */ - 0x03, 0xF7, 0x06, 0x17, 0x98, 0xEB, 0x99, 0xE2, 0x38, 0xFD, 0x6F, 0x1B, - 0xF9, 0x5B, 0x48, 0xFE, 0xEB, 0x48, 0x54, 0x25, 0x2B, - /* x */ - 0x02, 0xF9, 0xF8, 0x7B, 0x7C, 0x57, 0x4D, 0x0B, 0xDE, 0xCF, 0x8A, 0x22, - 0xE6, 0x52, 0x47, 0x75, 0xF9, 0x8C, 0xDE, 0xBD, 0xCB, - /* y */ - 0x05, 0xB9, 0x35, 0x59, 0x0C, 0x15, 0x5E, 0x17, 0xEA, 0x48, 0xEB, 0x3F, - 0xF3, 0x71, 0x8B, 0x89, 0x3D, 0xF5, 0x9A, 0x05, 0xD0, - /* order */ - 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1A, - 0xEE, 0x14, 0x0F, 0x11, 0x0A, 0xFF, 0x96, 0x13, 0x09 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 23 * 6]; -} _EC_X9_62_CHAR2_176V1 = { - { - NID_X9_62_characteristic_two_field, 0, 23, 0xFF6E - }, - { - /* no seed */ - /* p */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, - /* a */ - 0x00, 0xE4, 0xE6, 0xDB, 0x29, 0x95, 0x06, 0x5C, 0x40, 0x7D, 0x9D, 0x39, - 0xB8, 0xD0, 0x96, 0x7B, 0x96, 0x70, 0x4B, 0xA8, 0xE9, 0xC9, 0x0B, - /* b */ - 0x00, 0x5D, 0xDA, 0x47, 0x0A, 0xBE, 0x64, 0x14, 0xDE, 0x8E, 0xC1, 0x33, - 0xAE, 0x28, 0xE9, 0xBB, 0xD7, 0xFC, 0xEC, 0x0A, 0xE0, 0xFF, 0xF2, - /* x */ - 0x00, 0x8D, 0x16, 0xC2, 0x86, 0x67, 0x98, 0xB6, 0x00, 0xF9, 0xF0, 0x8B, - 0xB4, 0xA8, 0xE8, 0x60, 0xF3, 0x29, 0x8C, 0xE0, 0x4A, 0x57, 0x98, - /* y */ - 0x00, 0x6F, 0xA4, 0x53, 0x9C, 0x2D, 0xAD, 0xDD, 0xD6, 0xBA, 0xB5, 0x16, - 0x7D, 0x61, 0xB4, 0x36, 0xE1, 0xD9, 0x2B, 0xB1, 0x6A, 0x56, 0x2C, - /* order */ - 0x00, 0x00, 0x01, 0x00, 0x92, 0x53, 0x73, 0x97, 0xEC, 0xA4, 0xF6, 0x14, - 0x57, 0x99, 0xD6, 0x2B, 0x0A, 0x19, 0xCE, 0x06, 0xFE, 0x26, 0xAD - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 24 * 6]; -} _EC_X9_62_CHAR2_191V1 = { - { - NID_X9_62_characteristic_two_field, 20, 24, 2 - }, - { - /* seed */ - 0x4E, 0x13, 0xCA, 0x54, 0x27, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, - 0x15, 0x17, 0x55, 0x2F, 0x27, 0x9A, 0x8C, 0x84, - /* p */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, - /* a */ - 0x28, 0x66, 0x53, 0x7B, 0x67, 0x67, 0x52, 0x63, 0x6A, 0x68, 0xF5, 0x65, - 0x54, 0xE1, 0x26, 0x40, 0x27, 0x6B, 0x64, 0x9E, 0xF7, 0x52, 0x62, 0x67, - /* b */ - 0x2E, 0x45, 0xEF, 0x57, 0x1F, 0x00, 0x78, 0x6F, 0x67, 0xB0, 0x08, 0x1B, - 0x94, 0x95, 0xA3, 0xD9, 0x54, 0x62, 0xF5, 0xDE, 0x0A, 0xA1, 0x85, 0xEC, - /* x */ - 0x36, 0xB3, 0xDA, 0xF8, 0xA2, 0x32, 0x06, 0xF9, 0xC4, 0xF2, 0x99, 0xD7, - 0xB2, 0x1A, 0x9C, 0x36, 0x91, 0x37, 0xF2, 0xC8, 0x4A, 0xE1, 0xAA, 0x0D, - /* y */ - 0x76, 0x5B, 0xE7, 0x34, 0x33, 0xB3, 0xF9, 0x5E, 0x33, 0x29, 0x32, 0xE7, - 0x0E, 0xA2, 0x45, 0xCA, 0x24, 0x18, 0xEA, 0x0E, 0xF9, 0x80, 0x18, 0xFB, - /* order */ - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0xA2, 0x0E, 0x90, 0xC3, 0x90, 0x67, 0xC8, 0x93, 0xBB, 0xB9, 0xA5 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 24 * 6]; -} _EC_X9_62_CHAR2_191V2 = { - { - NID_X9_62_characteristic_two_field, 20, 24, 4 - }, - { - /* seed */ - 0x08, 0x71, 0xEF, 0x2F, 0xEF, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, - 0x15, 0x17, 0x58, 0xBE, 0xE0, 0xD9, 0x5C, 0x15, - /* p */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, - /* a */ - 0x40, 0x10, 0x28, 0x77, 0x4D, 0x77, 0x77, 0xC7, 0xB7, 0x66, 0x6D, 0x13, - 0x66, 0xEA, 0x43, 0x20, 0x71, 0x27, 0x4F, 0x89, 0xFF, 0x01, 0xE7, 0x18, - /* b */ - 0x06, 0x20, 0x04, 0x8D, 0x28, 0xBC, 0xBD, 0x03, 0xB6, 0x24, 0x9C, 0x99, - 0x18, 0x2B, 0x7C, 0x8C, 0xD1, 0x97, 0x00, 0xC3, 0x62, 0xC4, 0x6A, 0x01, - /* x */ - 0x38, 0x09, 0xB2, 0xB7, 0xCC, 0x1B, 0x28, 0xCC, 0x5A, 0x87, 0x92, 0x6A, - 0xAD, 0x83, 0xFD, 0x28, 0x78, 0x9E, 0x81, 0xE2, 0xC9, 0xE3, 0xBF, 0x10, - /* y */ - 0x17, 0x43, 0x43, 0x86, 0x62, 0x6D, 0x14, 0xF3, 0xDB, 0xF0, 0x17, 0x60, - 0xD9, 0x21, 0x3A, 0x3E, 0x1C, 0xF3, 0x7A, 0xEC, 0x43, 0x7D, 0x66, 0x8A, - /* order */ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x50, 0x50, 0x8C, 0xB8, 0x9F, 0x65, 0x28, 0x24, 0xE0, 0x6B, 0x81, 0x73 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 24 * 6]; -} _EC_X9_62_CHAR2_191V3 = { - { - NID_X9_62_characteristic_two_field, 20, 24, 6 - }, - { - /* seed */ - 0xE0, 0x53, 0x51, 0x2D, 0xC6, 0x84, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, - 0x15, 0x17, 0x50, 0x67, 0xAE, 0x78, 0x6D, 0x1F, - /* p */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, - /* a */ - 0x6C, 0x01, 0x07, 0x47, 0x56, 0x09, 0x91, 0x22, 0x22, 0x10, 0x56, 0x91, - 0x1C, 0x77, 0xD7, 0x7E, 0x77, 0xA7, 0x77, 0xE7, 0xE7, 0xE7, 0x7F, 0xCB, - /* b */ - 0x71, 0xFE, 0x1A, 0xF9, 0x26, 0xCF, 0x84, 0x79, 0x89, 0xEF, 0xEF, 0x8D, - 0xB4, 0x59, 0xF6, 0x63, 0x94, 0xD9, 0x0F, 0x32, 0xAD, 0x3F, 0x15, 0xE8, - /* x */ - 0x37, 0x5D, 0x4C, 0xE2, 0x4F, 0xDE, 0x43, 0x44, 0x89, 0xDE, 0x87, 0x46, - 0xE7, 0x17, 0x86, 0x01, 0x50, 0x09, 0xE6, 0x6E, 0x38, 0xA9, 0x26, 0xDD, - /* y */ - 0x54, 0x5A, 0x39, 0x17, 0x61, 0x96, 0x57, 0x5D, 0x98, 0x59, 0x99, 0x36, - 0x6E, 0x6A, 0xD3, 0x4C, 0xE0, 0xA7, 0x7C, 0xD7, 0x12, 0x7B, 0x06, 0xBE, - /* order */ - 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x61, 0x0C, 0x0B, 0x19, 0x68, 0x12, 0xBF, 0xB6, 0x28, 0x8A, 0x3E, 0xA3 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 27 * 6]; -} _EC_X9_62_CHAR2_208W1 = { - { - NID_X9_62_characteristic_two_field, 0, 27, 0xFE48 - }, - { - /* no seed */ - /* p */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x07, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, - /* b */ - 0x00, 0xC8, 0x61, 0x9E, 0xD4, 0x5A, 0x62, 0xE6, 0x21, 0x2E, 0x11, 0x60, - 0x34, 0x9E, 0x2B, 0xFA, 0x84, 0x44, 0x39, 0xFA, 0xFC, 0x2A, 0x3F, 0xD1, - 0x63, 0x8F, 0x9E, - /* x */ - 0x00, 0x89, 0xFD, 0xFB, 0xE4, 0xAB, 0xE1, 0x93, 0xDF, 0x95, 0x59, 0xEC, - 0xF0, 0x7A, 0xC0, 0xCE, 0x78, 0x55, 0x4E, 0x27, 0x84, 0xEB, 0x8C, 0x1E, - 0xD1, 0xA5, 0x7A, - /* y */ - 0x00, 0x0F, 0x55, 0xB5, 0x1A, 0x06, 0xE7, 0x8E, 0x9A, 0xC3, 0x8A, 0x03, - 0x5F, 0xF5, 0x20, 0xD8, 0xB0, 0x17, 0x81, 0xBE, 0xB1, 0xA6, 0xBB, 0x08, - 0x61, 0x7D, 0xE3, - /* order */ - 0x00, 0x00, 0x01, 0x01, 0xBA, 0xF9, 0x5C, 0x97, 0x23, 0xC5, 0x7B, 0x6C, - 0x21, 0xDA, 0x2E, 0xFF, 0x2D, 0x5E, 0xD5, 0x88, 0xBD, 0xD5, 0x71, 0x7E, - 0x21, 0x2F, 0x9D - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 30 * 6]; -} _EC_X9_62_CHAR2_239V1 = { - { - NID_X9_62_characteristic_two_field, 20, 30, 4 - }, - { - /* seed */ - 0xD3, 0x4B, 0x9A, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, - 0xCA, 0x71, 0xB9, 0x20, 0xBF, 0xEF, 0xB0, 0x5D, - /* p */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x32, 0x01, 0x08, 0x57, 0x07, 0x7C, 0x54, 0x31, 0x12, 0x3A, 0x46, 0xB8, - 0x08, 0x90, 0x67, 0x56, 0xF5, 0x43, 0x42, 0x3E, 0x8D, 0x27, 0x87, 0x75, - 0x78, 0x12, 0x57, 0x78, 0xAC, 0x76, - /* b */ - 0x79, 0x04, 0x08, 0xF2, 0xEE, 0xDA, 0xF3, 0x92, 0xB0, 0x12, 0xED, 0xEF, - 0xB3, 0x39, 0x2F, 0x30, 0xF4, 0x32, 0x7C, 0x0C, 0xA3, 0xF3, 0x1F, 0xC3, - 0x83, 0xC4, 0x22, 0xAA, 0x8C, 0x16, - /* x */ - 0x57, 0x92, 0x70, 0x98, 0xFA, 0x93, 0x2E, 0x7C, 0x0A, 0x96, 0xD3, 0xFD, - 0x5B, 0x70, 0x6E, 0xF7, 0xE5, 0xF5, 0xC1, 0x56, 0xE1, 0x6B, 0x7E, 0x7C, - 0x86, 0x03, 0x85, 0x52, 0xE9, 0x1D, - /* y */ - 0x61, 0xD8, 0xEE, 0x50, 0x77, 0xC3, 0x3F, 0xEC, 0xF6, 0xF1, 0xA1, 0x6B, - 0x26, 0x8D, 0xE4, 0x69, 0xC3, 0xC7, 0x74, 0x4E, 0xA9, 0xA9, 0x71, 0x64, - 0x9F, 0xC7, 0xA9, 0x61, 0x63, 0x05, - /* order */ - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x42, 0xFF, 0xE1, 0x49, 0x2A, 0x49, 0x93, - 0xF1, 0xCA, 0xD6, 0x66, 0xE4, 0x47 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 30 * 6]; -} _EC_X9_62_CHAR2_239V2 = { - { - NID_X9_62_characteristic_two_field, 20, 30, 6 - }, - { - /* seed */ - 0x2A, 0xA6, 0x98, 0x2F, 0xDF, 0xA4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, - 0x15, 0x17, 0x5D, 0x26, 0x67, 0x27, 0x27, 0x7D, - /* p */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x42, 0x30, 0x01, 0x77, 0x57, 0xA7, 0x67, 0xFA, 0xE4, 0x23, 0x98, 0x56, - 0x9B, 0x74, 0x63, 0x25, 0xD4, 0x53, 0x13, 0xAF, 0x07, 0x66, 0x26, 0x64, - 0x79, 0xB7, 0x56, 0x54, 0xE6, 0x5F, - /* b */ - 0x50, 0x37, 0xEA, 0x65, 0x41, 0x96, 0xCF, 0xF0, 0xCD, 0x82, 0xB2, 0xC1, - 0x4A, 0x2F, 0xCF, 0x2E, 0x3F, 0xF8, 0x77, 0x52, 0x85, 0xB5, 0x45, 0x72, - 0x2F, 0x03, 0xEA, 0xCD, 0xB7, 0x4B, - /* x */ - 0x28, 0xF9, 0xD0, 0x4E, 0x90, 0x00, 0x69, 0xC8, 0xDC, 0x47, 0xA0, 0x85, - 0x34, 0xFE, 0x76, 0xD2, 0xB9, 0x00, 0xB7, 0xD7, 0xEF, 0x31, 0xF5, 0x70, - 0x9F, 0x20, 0x0C, 0x4C, 0xA2, 0x05, - /* y */ - 0x56, 0x67, 0x33, 0x4C, 0x45, 0xAF, 0xF3, 0xB5, 0xA0, 0x3B, 0xAD, 0x9D, - 0xD7, 0x5E, 0x2C, 0x71, 0xA9, 0x93, 0x62, 0x56, 0x7D, 0x54, 0x53, 0xF7, - 0xFA, 0x6E, 0x22, 0x7E, 0xC8, 0x33, - /* order */ - 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, - 0x55, 0x55, 0x55, 0x3C, 0x6F, 0x28, 0x85, 0x25, 0x9C, 0x31, 0xE3, 0xFC, - 0xDF, 0x15, 0x46, 0x24, 0x52, 0x2D - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 30 * 6]; -} _EC_X9_62_CHAR2_239V3 = { - { - NID_X9_62_characteristic_two_field, 20, 30, 0xA - }, - { - /* seed */ - 0x9E, 0x07, 0x6F, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, - 0xE1, 0x1E, 0x9F, 0xDD, 0x77, 0xF9, 0x20, 0x41, - /* p */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x01, 0x23, 0x87, 0x74, 0x66, 0x6A, 0x67, 0x76, 0x6D, 0x66, 0x76, 0xF7, - 0x78, 0xE6, 0x76, 0xB6, 0x69, 0x99, 0x17, 0x66, 0x66, 0xE6, 0x87, 0x66, - 0x6D, 0x87, 0x66, 0xC6, 0x6A, 0x9F, - /* b */ - 0x6A, 0x94, 0x19, 0x77, 0xBA, 0x9F, 0x6A, 0x43, 0x51, 0x99, 0xAC, 0xFC, - 0x51, 0x06, 0x7E, 0xD5, 0x87, 0xF5, 0x19, 0xC5, 0xEC, 0xB5, 0x41, 0xB8, - 0xE4, 0x41, 0x11, 0xDE, 0x1D, 0x40, - /* x */ - 0x70, 0xF6, 0xE9, 0xD0, 0x4D, 0x28, 0x9C, 0x4E, 0x89, 0x91, 0x3C, 0xE3, - 0x53, 0x0B, 0xFD, 0xE9, 0x03, 0x97, 0x7D, 0x42, 0xB1, 0x46, 0xD5, 0x39, - 0xBF, 0x1B, 0xDE, 0x4E, 0x9C, 0x92, - /* y */ - 0x2E, 0x5A, 0x0E, 0xAF, 0x6E, 0x5E, 0x13, 0x05, 0xB9, 0x00, 0x4D, 0xCE, - 0x5C, 0x0E, 0xD7, 0xFE, 0x59, 0xA3, 0x56, 0x08, 0xF3, 0x38, 0x37, 0xC8, - 0x16, 0xD8, 0x0B, 0x79, 0xF4, 0x61, - /* order */ - 0x0C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, - 0xCC, 0xCC, 0xCC, 0xAC, 0x49, 0x12, 0xD2, 0xD9, 0xDF, 0x90, 0x3E, 0xF9, - 0x88, 0x8B, 0x8A, 0x0E, 0x4C, 0xFF - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 35 * 6]; -} _EC_X9_62_CHAR2_272W1 = { - { - NID_X9_62_characteristic_two_field, 0, 35, 0xFF06 - }, - { - /* no seed */ - /* p */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, - /* a */ - 0x00, 0x91, 0xA0, 0x91, 0xF0, 0x3B, 0x5F, 0xBA, 0x4A, 0xB2, 0xCC, 0xF4, - 0x9C, 0x4E, 0xDD, 0x22, 0x0F, 0xB0, 0x28, 0x71, 0x2D, 0x42, 0xBE, 0x75, - 0x2B, 0x2C, 0x40, 0x09, 0x4D, 0xBA, 0xCD, 0xB5, 0x86, 0xFB, 0x20, - /* b */ - 0x00, 0x71, 0x67, 0xEF, 0xC9, 0x2B, 0xB2, 0xE3, 0xCE, 0x7C, 0x8A, 0xAA, - 0xFF, 0x34, 0xE1, 0x2A, 0x9C, 0x55, 0x70, 0x03, 0xD7, 0xC7, 0x3A, 0x6F, - 0xAF, 0x00, 0x3F, 0x99, 0xF6, 0xCC, 0x84, 0x82, 0xE5, 0x40, 0xF7, - /* x */ - 0x00, 0x61, 0x08, 0xBA, 0xBB, 0x2C, 0xEE, 0xBC, 0xF7, 0x87, 0x05, 0x8A, - 0x05, 0x6C, 0xBE, 0x0C, 0xFE, 0x62, 0x2D, 0x77, 0x23, 0xA2, 0x89, 0xE0, - 0x8A, 0x07, 0xAE, 0x13, 0xEF, 0x0D, 0x10, 0xD1, 0x71, 0xDD, 0x8D, - /* y */ - 0x00, 0x10, 0xC7, 0x69, 0x57, 0x16, 0x85, 0x1E, 0xEF, 0x6B, 0xA7, 0xF6, - 0x87, 0x2E, 0x61, 0x42, 0xFB, 0xD2, 0x41, 0xB8, 0x30, 0xFF, 0x5E, 0xFC, - 0xAC, 0xEC, 0xCA, 0xB0, 0x5E, 0x02, 0x00, 0x5D, 0xDE, 0x9D, 0x23, - /* order */ - 0x00, 0x00, 0x01, 0x00, 0xFA, 0xF5, 0x13, 0x54, 0xE0, 0xE3, 0x9E, 0x48, - 0x92, 0xDF, 0x6E, 0x31, 0x9C, 0x72, 0xC8, 0x16, 0x16, 0x03, 0xFA, 0x45, - 0xAA, 0x7B, 0x99, 0x8A, 0x16, 0x7B, 0x8F, 0x1E, 0x62, 0x95, 0x21 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 39 * 6]; -} _EC_X9_62_CHAR2_304W1 = { - { - NID_X9_62_characteristic_two_field, 0, 39, 0xFE2E - }, - { - /* no seed */ - /* p */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x08, 0x07, - /* a */ - 0x00, 0xFD, 0x0D, 0x69, 0x31, 0x49, 0xA1, 0x18, 0xF6, 0x51, 0xE6, 0xDC, - 0xE6, 0x80, 0x20, 0x85, 0x37, 0x7E, 0x5F, 0x88, 0x2D, 0x1B, 0x51, 0x0B, - 0x44, 0x16, 0x00, 0x74, 0xC1, 0x28, 0x80, 0x78, 0x36, 0x5A, 0x03, 0x96, - 0xC8, 0xE6, 0x81, - /* b */ - 0x00, 0xBD, 0xDB, 0x97, 0xE5, 0x55, 0xA5, 0x0A, 0x90, 0x8E, 0x43, 0xB0, - 0x1C, 0x79, 0x8E, 0xA5, 0xDA, 0xA6, 0x78, 0x8F, 0x1E, 0xA2, 0x79, 0x4E, - 0xFC, 0xF5, 0x71, 0x66, 0xB8, 0xC1, 0x40, 0x39, 0x60, 0x1E, 0x55, 0x82, - 0x73, 0x40, 0xBE, - /* x */ - 0x00, 0x19, 0x7B, 0x07, 0x84, 0x5E, 0x9B, 0xE2, 0xD9, 0x6A, 0xDB, 0x0F, - 0x5F, 0x3C, 0x7F, 0x2C, 0xFF, 0xBD, 0x7A, 0x3E, 0xB8, 0xB6, 0xFE, 0xC3, - 0x5C, 0x7F, 0xD6, 0x7F, 0x26, 0xDD, 0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74, - 0x0A, 0x26, 0x14, - /* y */ - 0x00, 0xE1, 0x9F, 0xBE, 0xB7, 0x6E, 0x0D, 0xA1, 0x71, 0x51, 0x7E, 0xCF, - 0x40, 0x1B, 0x50, 0x28, 0x9B, 0xF0, 0x14, 0x10, 0x32, 0x88, 0x52, 0x7A, - 0x9B, 0x41, 0x6A, 0x10, 0x5E, 0x80, 0x26, 0x0B, 0x54, 0x9F, 0xDC, 0x1B, - 0x92, 0xC0, 0x3B, - /* order */ - 0x00, 0x00, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01, - 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01, 0x02, 0x2D, 0x5C, - 0x91, 0xDD, 0x17, 0x3F, 0x8F, 0xB5, 0x61, 0xDA, 0x68, 0x99, 0x16, 0x44, - 0x43, 0x05, 0x1D - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[20 + 45 * 6]; -} _EC_X9_62_CHAR2_359V1 = { - { - NID_X9_62_characteristic_two_field, 20, 45, 0x4C - }, - { - /* seed */ - 0x2B, 0x35, 0x49, 0x20, 0xB7, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, - 0x15, 0x17, 0x58, 0x5B, 0xA1, 0x33, 0x2D, 0xC6, - /* p */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x56, 0x67, 0x67, 0x6A, 0x65, 0x4B, 0x20, 0x75, 0x4F, 0x35, 0x6E, 0xA9, - 0x20, 0x17, 0xD9, 0x46, 0x56, 0x7C, 0x46, 0x67, 0x55, 0x56, 0xF1, 0x95, - 0x56, 0xA0, 0x46, 0x16, 0xB5, 0x67, 0xD2, 0x23, 0xA5, 0xE0, 0x56, 0x56, - 0xFB, 0x54, 0x90, 0x16, 0xA9, 0x66, 0x56, 0xA5, 0x57, - /* b */ - 0x24, 0x72, 0xE2, 0xD0, 0x19, 0x7C, 0x49, 0x36, 0x3F, 0x1F, 0xE7, 0xF5, - 0xB6, 0xDB, 0x07, 0x5D, 0x52, 0xB6, 0x94, 0x7D, 0x13, 0x5D, 0x8C, 0xA4, - 0x45, 0x80, 0x5D, 0x39, 0xBC, 0x34, 0x56, 0x26, 0x08, 0x96, 0x87, 0x74, - 0x2B, 0x63, 0x29, 0xE7, 0x06, 0x80, 0x23, 0x19, 0x88, - /* x */ - 0x3C, 0x25, 0x8E, 0xF3, 0x04, 0x77, 0x67, 0xE7, 0xED, 0xE0, 0xF1, 0xFD, - 0xAA, 0x79, 0xDA, 0xEE, 0x38, 0x41, 0x36, 0x6A, 0x13, 0x2E, 0x16, 0x3A, - 0xCE, 0xD4, 0xED, 0x24, 0x01, 0xDF, 0x9C, 0x6B, 0xDC, 0xDE, 0x98, 0xE8, - 0xE7, 0x07, 0xC0, 0x7A, 0x22, 0x39, 0xB1, 0xB0, 0x97, - /* y */ - 0x53, 0xD7, 0xE0, 0x85, 0x29, 0x54, 0x70, 0x48, 0x12, 0x1E, 0x9C, 0x95, - 0xF3, 0x79, 0x1D, 0xD8, 0x04, 0x96, 0x39, 0x48, 0xF3, 0x4F, 0xAE, 0x7B, - 0xF4, 0x4E, 0xA8, 0x23, 0x65, 0xDC, 0x78, 0x68, 0xFE, 0x57, 0xE4, 0xAE, - 0x2D, 0xE2, 0x11, 0x30, 0x5A, 0x40, 0x71, 0x04, 0xBD, - /* order */ - 0x01, 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28, - 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28, 0x6B, 0xC9, 0xFB, - 0x8F, 0x6B, 0x85, 0xC5, 0x56, 0x89, 0x2C, 0x20, 0xA7, 0xEB, 0x96, 0x4F, - 0xE7, 0x71, 0x9E, 0x74, 0xF4, 0x90, 0x75, 0x8D, 0x3B - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 47 * 6]; -} _EC_X9_62_CHAR2_368W1 = { - { - NID_X9_62_characteristic_two_field, 0, 47, 0xFF70 - }, - { - /* no seed */ - /* p */ - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, - /* a */ - 0x00, 0xE0, 0xD2, 0xEE, 0x25, 0x09, 0x52, 0x06, 0xF5, 0xE2, 0xA4, 0xF9, - 0xED, 0x22, 0x9F, 0x1F, 0x25, 0x6E, 0x79, 0xA0, 0xE2, 0xB4, 0x55, 0x97, - 0x0D, 0x8D, 0x0D, 0x86, 0x5B, 0xD9, 0x47, 0x78, 0xC5, 0x76, 0xD6, 0x2F, - 0x0A, 0xB7, 0x51, 0x9C, 0xCD, 0x2A, 0x1A, 0x90, 0x6A, 0xE3, 0x0D, - /* b */ - 0x00, 0xFC, 0x12, 0x17, 0xD4, 0x32, 0x0A, 0x90, 0x45, 0x2C, 0x76, 0x0A, - 0x58, 0xED, 0xCD, 0x30, 0xC8, 0xDD, 0x06, 0x9B, 0x3C, 0x34, 0x45, 0x38, - 0x37, 0xA3, 0x4E, 0xD5, 0x0C, 0xB5, 0x49, 0x17, 0xE1, 0xC2, 0x11, 0x2D, - 0x84, 0xD1, 0x64, 0xF4, 0x44, 0xF8, 0xF7, 0x47, 0x86, 0x04, 0x6A, - /* x */ - 0x00, 0x10, 0x85, 0xE2, 0x75, 0x53, 0x81, 0xDC, 0xCC, 0xE3, 0xC1, 0x55, - 0x7A, 0xFA, 0x10, 0xC2, 0xF0, 0xC0, 0xC2, 0x82, 0x56, 0x46, 0xC5, 0xB3, - 0x4A, 0x39, 0x4C, 0xBC, 0xFA, 0x8B, 0xC1, 0x6B, 0x22, 0xE7, 0xE7, 0x89, - 0xE9, 0x27, 0xBE, 0x21, 0x6F, 0x02, 0xE1, 0xFB, 0x13, 0x6A, 0x5F, - /* y */ - 0x00, 0x7B, 0x3E, 0xB1, 0xBD, 0xDC, 0xBA, 0x62, 0xD5, 0xD8, 0xB2, 0x05, - 0x9B, 0x52, 0x57, 0x97, 0xFC, 0x73, 0x82, 0x2C, 0x59, 0x05, 0x9C, 0x62, - 0x3A, 0x45, 0xFF, 0x38, 0x43, 0xCE, 0xE8, 0xF8, 0x7C, 0xD1, 0x85, 0x5A, - 0xDA, 0xA8, 0x1E, 0x2A, 0x07, 0x50, 0xB8, 0x0F, 0xDA, 0x23, 0x10, - /* order */ - 0x00, 0x00, 0x01, 0x00, 0x90, 0x51, 0x2D, 0xA9, 0xAF, 0x72, 0xB0, 0x83, - 0x49, 0xD9, 0x8A, 0x5D, 0xD4, 0xC7, 0xB0, 0x53, 0x2E, 0xCA, 0x51, 0xCE, - 0x03, 0xE2, 0xD1, 0x0F, 0x3B, 0x7A, 0xC5, 0x79, 0xBD, 0x87, 0xE9, 0x09, - 0xAE, 0x40, 0xA6, 0xF1, 0x31, 0xE9, 0xCF, 0xCE, 0x5B, 0xD9, 0x67 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 54 * 6]; -} _EC_X9_62_CHAR2_431R1 = { - { - NID_X9_62_characteristic_two_field, 0, 54, 0x2760 - }, - { - /* no seed */ - /* p */ - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x1A, 0x82, 0x7E, 0xF0, 0x0D, 0xD6, 0xFC, 0x0E, 0x23, 0x4C, 0xAF, 0x04, - 0x6C, 0x6A, 0x5D, 0x8A, 0x85, 0x39, 0x5B, 0x23, 0x6C, 0xC4, 0xAD, 0x2C, - 0xF3, 0x2A, 0x0C, 0xAD, 0xBD, 0xC9, 0xDD, 0xF6, 0x20, 0xB0, 0xEB, 0x99, - 0x06, 0xD0, 0x95, 0x7F, 0x6C, 0x6F, 0xEA, 0xCD, 0x61, 0x54, 0x68, 0xDF, - 0x10, 0x4D, 0xE2, 0x96, 0xCD, 0x8F, - /* b */ - 0x10, 0xD9, 0xB4, 0xA3, 0xD9, 0x04, 0x7D, 0x8B, 0x15, 0x43, 0x59, 0xAB, - 0xFB, 0x1B, 0x7F, 0x54, 0x85, 0xB0, 0x4C, 0xEB, 0x86, 0x82, 0x37, 0xDD, - 0xC9, 0xDE, 0xDA, 0x98, 0x2A, 0x67, 0x9A, 0x5A, 0x91, 0x9B, 0x62, 0x6D, - 0x4E, 0x50, 0xA8, 0xDD, 0x73, 0x1B, 0x10, 0x7A, 0x99, 0x62, 0x38, 0x1F, - 0xB5, 0xD8, 0x07, 0xBF, 0x26, 0x18, - /* x */ - 0x12, 0x0F, 0xC0, 0x5D, 0x3C, 0x67, 0xA9, 0x9D, 0xE1, 0x61, 0xD2, 0xF4, - 0x09, 0x26, 0x22, 0xFE, 0xCA, 0x70, 0x1B, 0xE4, 0xF5, 0x0F, 0x47, 0x58, - 0x71, 0x4E, 0x8A, 0x87, 0xBB, 0xF2, 0xA6, 0x58, 0xEF, 0x8C, 0x21, 0xE7, - 0xC5, 0xEF, 0xE9, 0x65, 0x36, 0x1F, 0x6C, 0x29, 0x99, 0xC0, 0xC2, 0x47, - 0xB0, 0xDB, 0xD7, 0x0C, 0xE6, 0xB7, - /* y */ - 0x20, 0xD0, 0xAF, 0x89, 0x03, 0xA9, 0x6F, 0x8D, 0x5F, 0xA2, 0xC2, 0x55, - 0x74, 0x5D, 0x3C, 0x45, 0x1B, 0x30, 0x2C, 0x93, 0x46, 0xD9, 0xB7, 0xE4, - 0x85, 0xE7, 0xBC, 0xE4, 0x1F, 0x6B, 0x59, 0x1F, 0x3E, 0x8F, 0x6A, 0xDD, - 0xCB, 0xB0, 0xBC, 0x4C, 0x2F, 0x94, 0x7A, 0x7D, 0xE1, 0xA8, 0x9B, 0x62, - 0x5D, 0x6A, 0x59, 0x8B, 0x37, 0x60, - /* order */ - 0x00, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, - 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, - 0x34, 0x03, 0x40, 0x34, 0x03, 0x23, 0xC3, 0x13, 0xFA, 0xB5, 0x05, 0x89, - 0x70, 0x3B, 0x5E, 0xC6, 0x8D, 0x35, 0x87, 0xFE, 0xC6, 0x0D, 0x16, 0x1C, - 0xC1, 0x49, 0xC1, 0xAD, 0x4A, 0x91 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 15 * 6]; -} _EC_WTLS_1 = { - { - NID_X9_62_characteristic_two_field, 0, 15, 2 - }, - { - /* no seed */ - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x01, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, - /* x */ - 0x01, 0x66, 0x79, 0x79, 0xA4, 0x0B, 0xA4, 0x97, 0xE5, 0xD5, 0xC2, 0x70, - 0x78, 0x06, 0x17, - /* y */ - 0x00, 0xF4, 0x4B, 0x4A, 0xF1, 0xEC, 0xC2, 0x63, 0x0E, 0x08, 0x78, 0x5C, - 0xEB, 0xCC, 0x15, - /* order */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBF, 0x91, 0xAF, - 0x6D, 0xEA, 0x73 - } -}; - -/* IPSec curves */ -/* - * NOTE: The of curves over a extension field of non prime degree is not - * recommended (Weil-descent). As the group order is not a prime this curve - * is not suitable for ECDSA. - */ -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 20 * 6]; -} _EC_IPSEC_155_ID3 = { - { - NID_X9_62_characteristic_two_field, 0, 20, 3 - }, - { - /* no seed */ - /* p */ - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f, - /* x */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, - /* y */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8, - /* order */ - 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xC7, 0xF3, - 0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C - } -}; - -/* - * NOTE: The of curves over a extension field of non prime degree is not - * recommended (Weil-descent). As the group order is not a prime this curve - * is not suitable for ECDSA. - */ -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 24 * 6]; -} _EC_IPSEC_185_ID4 = { - { - NID_X9_62_characteristic_two_field, 0, 24, 2 - }, - { - /* no seed */ - /* p */ - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - /* a */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - /* b */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xe9, - /* x */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, - /* y */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, - /* order */ - 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E - } -}; - -#endif - -/* - * These curves were added by Annie Yousar - * For the definition of RFC 5639 curves see - * http://www.ietf.org/rfc/rfc5639.txt These curves are generated verifiable - * at random, nevertheless the seed is omitted as parameter because the - * generation mechanism is different from those defined in ANSI X9.62. - */ - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 20 * 6]; -} _EC_brainpoolP160r1 = { - { - NID_X9_62_prime_field, 0, 20, 1 - }, - { - /* no seed */ - /* p */ - 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, - 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F, - /* a */ - 0x34, 0x0E, 0x7B, 0xE2, 0xA2, 0x80, 0xEB, 0x74, 0xE2, 0xBE, 0x61, 0xBA, - 0xDA, 0x74, 0x5D, 0x97, 0xE8, 0xF7, 0xC3, 0x00, - /* b */ - 0x1E, 0x58, 0x9A, 0x85, 0x95, 0x42, 0x34, 0x12, 0x13, 0x4F, 0xAA, 0x2D, - 0xBD, 0xEC, 0x95, 0xC8, 0xD8, 0x67, 0x5E, 0x58, - /* x */ - 0xBE, 0xD5, 0xAF, 0x16, 0xEA, 0x3F, 0x6A, 0x4F, 0x62, 0x93, 0x8C, 0x46, - 0x31, 0xEB, 0x5A, 0xF7, 0xBD, 0xBC, 0xDB, 0xC3, - /* y */ - 0x16, 0x67, 0xCB, 0x47, 0x7A, 0x1A, 0x8E, 0xC3, 0x38, 0xF9, 0x47, 0x41, - 0x66, 0x9C, 0x97, 0x63, 0x16, 0xDA, 0x63, 0x21, - /* order */ - 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91, - 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 20 * 6]; -} _EC_brainpoolP160t1 = { - { - NID_X9_62_prime_field, 0, 20, 1 - }, - { - /* no seed */ - /* p */ - 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, - 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0F, - /* a */ - 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0xC7, 0xAD, - 0x95, 0xB3, 0xD8, 0x13, 0x95, 0x15, 0x62, 0x0C, - /* b */ - 0x7A, 0x55, 0x6B, 0x6D, 0xAE, 0x53, 0x5B, 0x7B, 0x51, 0xED, 0x2C, 0x4D, - 0x7D, 0xAA, 0x7A, 0x0B, 0x5C, 0x55, 0xF3, 0x80, - /* x */ - 0xB1, 0x99, 0xB1, 0x3B, 0x9B, 0x34, 0xEF, 0xC1, 0x39, 0x7E, 0x64, 0xBA, - 0xEB, 0x05, 0xAC, 0xC2, 0x65, 0xFF, 0x23, 0x78, - /* y */ - 0xAD, 0xD6, 0x71, 0x8B, 0x7C, 0x7C, 0x19, 0x61, 0xF0, 0x99, 0x1B, 0x84, - 0x24, 0x43, 0x77, 0x21, 0x52, 0xC9, 0xE0, 0xAD, - /* order */ - 0xE9, 0x5E, 0x4A, 0x5F, 0x73, 0x70, 0x59, 0xDC, 0x60, 0xDF, 0x59, 0x91, - 0xD4, 0x50, 0x29, 0x40, 0x9E, 0x60, 0xFC, 0x09 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 24 * 6]; -} _EC_brainpoolP192r1 = { - { - NID_X9_62_prime_field, 0, 24, 1 - }, - { - /* no seed */ - /* p */ - 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, - 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97, - /* a */ - 0x6A, 0x91, 0x17, 0x40, 0x76, 0xB1, 0xE0, 0xE1, 0x9C, 0x39, 0xC0, 0x31, - 0xFE, 0x86, 0x85, 0xC1, 0xCA, 0xE0, 0x40, 0xE5, 0xC6, 0x9A, 0x28, 0xEF, - /* b */ - 0x46, 0x9A, 0x28, 0xEF, 0x7C, 0x28, 0xCC, 0xA3, 0xDC, 0x72, 0x1D, 0x04, - 0x4F, 0x44, 0x96, 0xBC, 0xCA, 0x7E, 0xF4, 0x14, 0x6F, 0xBF, 0x25, 0xC9, - /* x */ - 0xC0, 0xA0, 0x64, 0x7E, 0xAA, 0xB6, 0xA4, 0x87, 0x53, 0xB0, 0x33, 0xC5, - 0x6C, 0xB0, 0xF0, 0x90, 0x0A, 0x2F, 0x5C, 0x48, 0x53, 0x37, 0x5F, 0xD6, - /* y */ - 0x14, 0xB6, 0x90, 0x86, 0x6A, 0xBD, 0x5B, 0xB8, 0x8B, 0x5F, 0x48, 0x28, - 0xC1, 0x49, 0x00, 0x02, 0xE6, 0x77, 0x3F, 0xA2, 0xFA, 0x29, 0x9B, 0x8F, - /* order */ - 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F, - 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 24 * 6]; -} _EC_brainpoolP192t1 = { - { - NID_X9_62_prime_field, 0, 24, 1 - }, - { - /* no seed */ - /* p */ - 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, - 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x97, - /* a */ - 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x30, - 0x93, 0xD1, 0x8D, 0xB7, 0x8F, 0xCE, 0x47, 0x6D, 0xE1, 0xA8, 0x62, 0x94, - /* b */ - 0x13, 0xD5, 0x6F, 0xFA, 0xEC, 0x78, 0x68, 0x1E, 0x68, 0xF9, 0xDE, 0xB4, - 0x3B, 0x35, 0xBE, 0xC2, 0xFB, 0x68, 0x54, 0x2E, 0x27, 0x89, 0x7B, 0x79, - /* x */ - 0x3A, 0xE9, 0xE5, 0x8C, 0x82, 0xF6, 0x3C, 0x30, 0x28, 0x2E, 0x1F, 0xE7, - 0xBB, 0xF4, 0x3F, 0xA7, 0x2C, 0x44, 0x6A, 0xF6, 0xF4, 0x61, 0x81, 0x29, - /* y */ - 0x09, 0x7E, 0x2C, 0x56, 0x67, 0xC2, 0x22, 0x3A, 0x90, 0x2A, 0xB5, 0xCA, - 0x44, 0x9D, 0x00, 0x84, 0xB7, 0xE5, 0xB3, 0xDE, 0x7C, 0xCC, 0x01, 0xC9, - /* order */ - 0xC3, 0x02, 0xF4, 0x1D, 0x93, 0x2A, 0x36, 0xCD, 0xA7, 0xA3, 0x46, 0x2F, - 0x9E, 0x9E, 0x91, 0x6B, 0x5B, 0xE8, 0xF1, 0x02, 0x9A, 0xC4, 0xAC, 0xC1 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 28 * 6]; -} _EC_brainpoolP224r1 = { - { - NID_X9_62_prime_field, 0, 28, 1 - }, - { - /* no seed */ - /* p */ - 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, - 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, - 0x7E, 0xC8, 0xC0, 0xFF, - /* a */ - 0x68, 0xA5, 0xE6, 0x2C, 0xA9, 0xCE, 0x6C, 0x1C, 0x29, 0x98, 0x03, 0xA6, - 0xC1, 0x53, 0x0B, 0x51, 0x4E, 0x18, 0x2A, 0xD8, 0xB0, 0x04, 0x2A, 0x59, - 0xCA, 0xD2, 0x9F, 0x43, - /* b */ - 0x25, 0x80, 0xF6, 0x3C, 0xCF, 0xE4, 0x41, 0x38, 0x87, 0x07, 0x13, 0xB1, - 0xA9, 0x23, 0x69, 0xE3, 0x3E, 0x21, 0x35, 0xD2, 0x66, 0xDB, 0xB3, 0x72, - 0x38, 0x6C, 0x40, 0x0B, - /* x */ - 0x0D, 0x90, 0x29, 0xAD, 0x2C, 0x7E, 0x5C, 0xF4, 0x34, 0x08, 0x23, 0xB2, - 0xA8, 0x7D, 0xC6, 0x8C, 0x9E, 0x4C, 0xE3, 0x17, 0x4C, 0x1E, 0x6E, 0xFD, - 0xEE, 0x12, 0xC0, 0x7D, - /* y */ - 0x58, 0xAA, 0x56, 0xF7, 0x72, 0xC0, 0x72, 0x6F, 0x24, 0xC6, 0xB8, 0x9E, - 0x4E, 0xCD, 0xAC, 0x24, 0x35, 0x4B, 0x9E, 0x99, 0xCA, 0xA3, 0xF6, 0xD3, - 0x76, 0x14, 0x02, 0xCD, - /* order */ - 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, - 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3, - 0xA5, 0xA7, 0x93, 0x9F - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 28 * 6]; -} _EC_brainpoolP224t1 = { - { - NID_X9_62_prime_field, 0, 28, 1 - }, - { - /* no seed */ - /* p */ - 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, - 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, - 0x7E, 0xC8, 0xC0, 0xFF, - /* a */ - 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, - 0x75, 0xD1, 0xD7, 0x87, 0xB0, 0x9F, 0x07, 0x57, 0x97, 0xDA, 0x89, 0xF5, - 0x7E, 0xC8, 0xC0, 0xFC, - /* b */ - 0x4B, 0x33, 0x7D, 0x93, 0x41, 0x04, 0xCD, 0x7B, 0xEF, 0x27, 0x1B, 0xF6, - 0x0C, 0xED, 0x1E, 0xD2, 0x0D, 0xA1, 0x4C, 0x08, 0xB3, 0xBB, 0x64, 0xF1, - 0x8A, 0x60, 0x88, 0x8D, - /* x */ - 0x6A, 0xB1, 0xE3, 0x44, 0xCE, 0x25, 0xFF, 0x38, 0x96, 0x42, 0x4E, 0x7F, - 0xFE, 0x14, 0x76, 0x2E, 0xCB, 0x49, 0xF8, 0x92, 0x8A, 0xC0, 0xC7, 0x60, - 0x29, 0xB4, 0xD5, 0x80, - /* y */ - 0x03, 0x74, 0xE9, 0xF5, 0x14, 0x3E, 0x56, 0x8C, 0xD2, 0x3F, 0x3F, 0x4D, - 0x7C, 0x0D, 0x4B, 0x1E, 0x41, 0xC8, 0xCC, 0x0D, 0x1C, 0x6A, 0xBD, 0x5F, - 0x1A, 0x46, 0xDB, 0x4C, - /* order */ - 0xD7, 0xC1, 0x34, 0xAA, 0x26, 0x43, 0x66, 0x86, 0x2A, 0x18, 0x30, 0x25, - 0x75, 0xD0, 0xFB, 0x98, 0xD1, 0x16, 0xBC, 0x4B, 0x6D, 0xDE, 0xBC, 0xA3, - 0xA5, 0xA7, 0x93, 0x9F - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 32 * 6]; -} _EC_brainpoolP256r1 = { - { - NID_X9_62_prime_field, 0, 32, 1 - }, - { - /* no seed */ - /* p */ - 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, - 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, - 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77, - /* a */ - 0x7D, 0x5A, 0x09, 0x75, 0xFC, 0x2C, 0x30, 0x57, 0xEE, 0xF6, 0x75, 0x30, - 0x41, 0x7A, 0xFF, 0xE7, 0xFB, 0x80, 0x55, 0xC1, 0x26, 0xDC, 0x5C, 0x6C, - 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9, - /* b */ - 0x26, 0xDC, 0x5C, 0x6C, 0xE9, 0x4A, 0x4B, 0x44, 0xF3, 0x30, 0xB5, 0xD9, - 0xBB, 0xD7, 0x7C, 0xBF, 0x95, 0x84, 0x16, 0x29, 0x5C, 0xF7, 0xE1, 0xCE, - 0x6B, 0xCC, 0xDC, 0x18, 0xFF, 0x8C, 0x07, 0xB6, - /* x */ - 0x8B, 0xD2, 0xAE, 0xB9, 0xCB, 0x7E, 0x57, 0xCB, 0x2C, 0x4B, 0x48, 0x2F, - 0xFC, 0x81, 0xB7, 0xAF, 0xB9, 0xDE, 0x27, 0xE1, 0xE3, 0xBD, 0x23, 0xC2, - 0x3A, 0x44, 0x53, 0xBD, 0x9A, 0xCE, 0x32, 0x62, - /* y */ - 0x54, 0x7E, 0xF8, 0x35, 0xC3, 0xDA, 0xC4, 0xFD, 0x97, 0xF8, 0x46, 0x1A, - 0x14, 0x61, 0x1D, 0xC9, 0xC2, 0x77, 0x45, 0x13, 0x2D, 0xED, 0x8E, 0x54, - 0x5C, 0x1D, 0x54, 0xC7, 0x2F, 0x04, 0x69, 0x97, - /* order */ - 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, - 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, - 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 32 * 6]; -} _EC_brainpoolP256t1 = { - { - NID_X9_62_prime_field, 0, 32, 1 - }, - { - /* no seed */ - /* p */ - 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, - 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, - 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x77, - /* a */ - 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, - 0x9D, 0x83, 0x8D, 0x72, 0x6E, 0x3B, 0xF6, 0x23, 0xD5, 0x26, 0x20, 0x28, - 0x20, 0x13, 0x48, 0x1D, 0x1F, 0x6E, 0x53, 0x74, - /* b */ - 0x66, 0x2C, 0x61, 0xC4, 0x30, 0xD8, 0x4E, 0xA4, 0xFE, 0x66, 0xA7, 0x73, - 0x3D, 0x0B, 0x76, 0xB7, 0xBF, 0x93, 0xEB, 0xC4, 0xAF, 0x2F, 0x49, 0x25, - 0x6A, 0xE5, 0x81, 0x01, 0xFE, 0xE9, 0x2B, 0x04, - /* x */ - 0xA3, 0xE8, 0xEB, 0x3C, 0xC1, 0xCF, 0xE7, 0xB7, 0x73, 0x22, 0x13, 0xB2, - 0x3A, 0x65, 0x61, 0x49, 0xAF, 0xA1, 0x42, 0xC4, 0x7A, 0xAF, 0xBC, 0x2B, - 0x79, 0xA1, 0x91, 0x56, 0x2E, 0x13, 0x05, 0xF4, - /* y */ - 0x2D, 0x99, 0x6C, 0x82, 0x34, 0x39, 0xC5, 0x6D, 0x7F, 0x7B, 0x22, 0xE1, - 0x46, 0x44, 0x41, 0x7E, 0x69, 0xBC, 0xB6, 0xDE, 0x39, 0xD0, 0x27, 0x00, - 0x1D, 0xAB, 0xE8, 0xF3, 0x5B, 0x25, 0xC9, 0xBE, - /* order */ - 0xA9, 0xFB, 0x57, 0xDB, 0xA1, 0xEE, 0xA9, 0xBC, 0x3E, 0x66, 0x0A, 0x90, - 0x9D, 0x83, 0x8D, 0x71, 0x8C, 0x39, 0x7A, 0xA3, 0xB5, 0x61, 0xA6, 0xF7, - 0x90, 0x1E, 0x0E, 0x82, 0x97, 0x48, 0x56, 0xA7 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 40 * 6]; -} _EC_brainpoolP320r1 = { - { - NID_X9_62_prime_field, 0, 40, 1 - }, - { - /* no seed */ - /* p */ - 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, - 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, - 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, - 0xF1, 0xB3, 0x2E, 0x27, - /* a */ - 0x3E, 0xE3, 0x0B, 0x56, 0x8F, 0xBA, 0xB0, 0xF8, 0x83, 0xCC, 0xEB, 0xD4, - 0x6D, 0x3F, 0x3B, 0xB8, 0xA2, 0xA7, 0x35, 0x13, 0xF5, 0xEB, 0x79, 0xDA, - 0x66, 0x19, 0x0E, 0xB0, 0x85, 0xFF, 0xA9, 0xF4, 0x92, 0xF3, 0x75, 0xA9, - 0x7D, 0x86, 0x0E, 0xB4, - /* b */ - 0x52, 0x08, 0x83, 0x94, 0x9D, 0xFD, 0xBC, 0x42, 0xD3, 0xAD, 0x19, 0x86, - 0x40, 0x68, 0x8A, 0x6F, 0xE1, 0x3F, 0x41, 0x34, 0x95, 0x54, 0xB4, 0x9A, - 0xCC, 0x31, 0xDC, 0xCD, 0x88, 0x45, 0x39, 0x81, 0x6F, 0x5E, 0xB4, 0xAC, - 0x8F, 0xB1, 0xF1, 0xA6, - /* x */ - 0x43, 0xBD, 0x7E, 0x9A, 0xFB, 0x53, 0xD8, 0xB8, 0x52, 0x89, 0xBC, 0xC4, - 0x8E, 0xE5, 0xBF, 0xE6, 0xF2, 0x01, 0x37, 0xD1, 0x0A, 0x08, 0x7E, 0xB6, - 0xE7, 0x87, 0x1E, 0x2A, 0x10, 0xA5, 0x99, 0xC7, 0x10, 0xAF, 0x8D, 0x0D, - 0x39, 0xE2, 0x06, 0x11, - /* y */ - 0x14, 0xFD, 0xD0, 0x55, 0x45, 0xEC, 0x1C, 0xC8, 0xAB, 0x40, 0x93, 0x24, - 0x7F, 0x77, 0x27, 0x5E, 0x07, 0x43, 0xFF, 0xED, 0x11, 0x71, 0x82, 0xEA, - 0xA9, 0xC7, 0x78, 0x77, 0xAA, 0xAC, 0x6A, 0xC7, 0xD3, 0x52, 0x45, 0xD1, - 0x69, 0x2E, 0x8E, 0xE1, - /* order */ - 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, - 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3, - 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, - 0x44, 0xC5, 0x93, 0x11 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 40 * 6]; -} _EC_brainpoolP320t1 = { - { - NID_X9_62_prime_field, 0, 40, 1 - }, - { - /* no seed */ - /* p */ - 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, - 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, - 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, - 0xF1, 0xB3, 0x2E, 0x27, - /* a */ - 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, - 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA6, 0xF6, 0xF4, 0x0D, 0xEF, - 0x4F, 0x92, 0xB9, 0xEC, 0x78, 0x93, 0xEC, 0x28, 0xFC, 0xD4, 0x12, 0xB1, - 0xF1, 0xB3, 0x2E, 0x24, - /* b */ - 0xA7, 0xF5, 0x61, 0xE0, 0x38, 0xEB, 0x1E, 0xD5, 0x60, 0xB3, 0xD1, 0x47, - 0xDB, 0x78, 0x20, 0x13, 0x06, 0x4C, 0x19, 0xF2, 0x7E, 0xD2, 0x7C, 0x67, - 0x80, 0xAA, 0xF7, 0x7F, 0xB8, 0xA5, 0x47, 0xCE, 0xB5, 0xB4, 0xFE, 0xF4, - 0x22, 0x34, 0x03, 0x53, - /* x */ - 0x92, 0x5B, 0xE9, 0xFB, 0x01, 0xAF, 0xC6, 0xFB, 0x4D, 0x3E, 0x7D, 0x49, - 0x90, 0x01, 0x0F, 0x81, 0x34, 0x08, 0xAB, 0x10, 0x6C, 0x4F, 0x09, 0xCB, - 0x7E, 0xE0, 0x78, 0x68, 0xCC, 0x13, 0x6F, 0xFF, 0x33, 0x57, 0xF6, 0x24, - 0xA2, 0x1B, 0xED, 0x52, - /* y */ - 0x63, 0xBA, 0x3A, 0x7A, 0x27, 0x48, 0x3E, 0xBF, 0x66, 0x71, 0xDB, 0xEF, - 0x7A, 0xBB, 0x30, 0xEB, 0xEE, 0x08, 0x4E, 0x58, 0xA0, 0xB0, 0x77, 0xAD, - 0x42, 0xA5, 0xA0, 0x98, 0x9D, 0x1E, 0xE7, 0x1B, 0x1B, 0x9B, 0xC0, 0x45, - 0x5F, 0xB0, 0xD2, 0xC3, - /* order */ - 0xD3, 0x5E, 0x47, 0x20, 0x36, 0xBC, 0x4F, 0xB7, 0xE1, 0x3C, 0x78, 0x5E, - 0xD2, 0x01, 0xE0, 0x65, 0xF9, 0x8F, 0xCF, 0xA5, 0xB6, 0x8F, 0x12, 0xA3, - 0x2D, 0x48, 0x2E, 0xC7, 0xEE, 0x86, 0x58, 0xE9, 0x86, 0x91, 0x55, 0x5B, - 0x44, 0xC5, 0x93, 0x11 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 48 * 6]; -} _EC_brainpoolP384r1 = { - { - NID_X9_62_prime_field, 0, 48, 1 - }, - { - /* no seed */ - /* p */ - 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, - 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, - 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, - 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53, - /* a */ - 0x7B, 0xC3, 0x82, 0xC6, 0x3D, 0x8C, 0x15, 0x0C, 0x3C, 0x72, 0x08, 0x0A, - 0xCE, 0x05, 0xAF, 0xA0, 0xC2, 0xBE, 0xA2, 0x8E, 0x4F, 0xB2, 0x27, 0x87, - 0x13, 0x91, 0x65, 0xEF, 0xBA, 0x91, 0xF9, 0x0F, 0x8A, 0xA5, 0x81, 0x4A, - 0x50, 0x3A, 0xD4, 0xEB, 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, - /* b */ - 0x04, 0xA8, 0xC7, 0xDD, 0x22, 0xCE, 0x28, 0x26, 0x8B, 0x39, 0xB5, 0x54, - 0x16, 0xF0, 0x44, 0x7C, 0x2F, 0xB7, 0x7D, 0xE1, 0x07, 0xDC, 0xD2, 0xA6, - 0x2E, 0x88, 0x0E, 0xA5, 0x3E, 0xEB, 0x62, 0xD5, 0x7C, 0xB4, 0x39, 0x02, - 0x95, 0xDB, 0xC9, 0x94, 0x3A, 0xB7, 0x86, 0x96, 0xFA, 0x50, 0x4C, 0x11, - /* x */ - 0x1D, 0x1C, 0x64, 0xF0, 0x68, 0xCF, 0x45, 0xFF, 0xA2, 0xA6, 0x3A, 0x81, - 0xB7, 0xC1, 0x3F, 0x6B, 0x88, 0x47, 0xA3, 0xE7, 0x7E, 0xF1, 0x4F, 0xE3, - 0xDB, 0x7F, 0xCA, 0xFE, 0x0C, 0xBD, 0x10, 0xE8, 0xE8, 0x26, 0xE0, 0x34, - 0x36, 0xD6, 0x46, 0xAA, 0xEF, 0x87, 0xB2, 0xE2, 0x47, 0xD4, 0xAF, 0x1E, - /* y */ - 0x8A, 0xBE, 0x1D, 0x75, 0x20, 0xF9, 0xC2, 0xA4, 0x5C, 0xB1, 0xEB, 0x8E, - 0x95, 0xCF, 0xD5, 0x52, 0x62, 0xB7, 0x0B, 0x29, 0xFE, 0xEC, 0x58, 0x64, - 0xE1, 0x9C, 0x05, 0x4F, 0xF9, 0x91, 0x29, 0x28, 0x0E, 0x46, 0x46, 0x21, - 0x77, 0x91, 0x81, 0x11, 0x42, 0x82, 0x03, 0x41, 0x26, 0x3C, 0x53, 0x15, - /* order */ - 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, - 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, - 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, - 0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 48 * 6]; -} _EC_brainpoolP384t1 = { - { - NID_X9_62_prime_field, 0, 48, 1 - }, - { - /* no seed */ - /* p */ - 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, - 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, - 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, - 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x53, - /* a */ - 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, - 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB4, - 0x12, 0xB1, 0xDA, 0x19, 0x7F, 0xB7, 0x11, 0x23, 0xAC, 0xD3, 0xA7, 0x29, - 0x90, 0x1D, 0x1A, 0x71, 0x87, 0x47, 0x00, 0x13, 0x31, 0x07, 0xEC, 0x50, - /* b */ - 0x7F, 0x51, 0x9E, 0xAD, 0xA7, 0xBD, 0xA8, 0x1B, 0xD8, 0x26, 0xDB, 0xA6, - 0x47, 0x91, 0x0F, 0x8C, 0x4B, 0x93, 0x46, 0xED, 0x8C, 0xCD, 0xC6, 0x4E, - 0x4B, 0x1A, 0xBD, 0x11, 0x75, 0x6D, 0xCE, 0x1D, 0x20, 0x74, 0xAA, 0x26, - 0x3B, 0x88, 0x80, 0x5C, 0xED, 0x70, 0x35, 0x5A, 0x33, 0xB4, 0x71, 0xEE, - /* x */ - 0x18, 0xDE, 0x98, 0xB0, 0x2D, 0xB9, 0xA3, 0x06, 0xF2, 0xAF, 0xCD, 0x72, - 0x35, 0xF7, 0x2A, 0x81, 0x9B, 0x80, 0xAB, 0x12, 0xEB, 0xD6, 0x53, 0x17, - 0x24, 0x76, 0xFE, 0xCD, 0x46, 0x2A, 0xAB, 0xFF, 0xC4, 0xFF, 0x19, 0x1B, - 0x94, 0x6A, 0x5F, 0x54, 0xD8, 0xD0, 0xAA, 0x2F, 0x41, 0x88, 0x08, 0xCC, - /* y */ - 0x25, 0xAB, 0x05, 0x69, 0x62, 0xD3, 0x06, 0x51, 0xA1, 0x14, 0xAF, 0xD2, - 0x75, 0x5A, 0xD3, 0x36, 0x74, 0x7F, 0x93, 0x47, 0x5B, 0x7A, 0x1F, 0xCA, - 0x3B, 0x88, 0xF2, 0xB6, 0xA2, 0x08, 0xCC, 0xFE, 0x46, 0x94, 0x08, 0x58, - 0x4D, 0xC2, 0xB2, 0x91, 0x26, 0x75, 0xBF, 0x5B, 0x9E, 0x58, 0x29, 0x28, - /* order */ - 0x8C, 0xB9, 0x1E, 0x82, 0xA3, 0x38, 0x6D, 0x28, 0x0F, 0x5D, 0x6F, 0x7E, - 0x50, 0xE6, 0x41, 0xDF, 0x15, 0x2F, 0x71, 0x09, 0xED, 0x54, 0x56, 0xB3, - 0x1F, 0x16, 0x6E, 0x6C, 0xAC, 0x04, 0x25, 0xA7, 0xCF, 0x3A, 0xB6, 0xAF, - 0x6B, 0x7F, 0xC3, 0x10, 0x3B, 0x88, 0x32, 0x02, 0xE9, 0x04, 0x65, 0x65 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 64 * 6]; -} _EC_brainpoolP512r1 = { - { - NID_X9_62_prime_field, 0, 64, 1 - }, - { - /* no seed */ - /* p */ - 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, - 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, - 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, - 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, - 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, - 0x58, 0x3A, 0x48, 0xF3, - /* a */ - 0x78, 0x30, 0xA3, 0x31, 0x8B, 0x60, 0x3B, 0x89, 0xE2, 0x32, 0x71, 0x45, - 0xAC, 0x23, 0x4C, 0xC5, 0x94, 0xCB, 0xDD, 0x8D, 0x3D, 0xF9, 0x16, 0x10, - 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, 0x2D, 0xED, 0x5D, 0x5A, - 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, 0x8B, 0x9A, 0xC8, 0xB5, - 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, 0xE7, 0xC1, 0xAC, 0x4D, - 0x77, 0xFC, 0x94, 0xCA, - /* b */ - 0x3D, 0xF9, 0x16, 0x10, 0xA8, 0x34, 0x41, 0xCA, 0xEA, 0x98, 0x63, 0xBC, - 0x2D, 0xED, 0x5D, 0x5A, 0xA8, 0x25, 0x3A, 0xA1, 0x0A, 0x2E, 0xF1, 0xC9, - 0x8B, 0x9A, 0xC8, 0xB5, 0x7F, 0x11, 0x17, 0xA7, 0x2B, 0xF2, 0xC7, 0xB9, - 0xE7, 0xC1, 0xAC, 0x4D, 0x77, 0xFC, 0x94, 0xCA, 0xDC, 0x08, 0x3E, 0x67, - 0x98, 0x40, 0x50, 0xB7, 0x5E, 0xBA, 0xE5, 0xDD, 0x28, 0x09, 0xBD, 0x63, - 0x80, 0x16, 0xF7, 0x23, - /* x */ - 0x81, 0xAE, 0xE4, 0xBD, 0xD8, 0x2E, 0xD9, 0x64, 0x5A, 0x21, 0x32, 0x2E, - 0x9C, 0x4C, 0x6A, 0x93, 0x85, 0xED, 0x9F, 0x70, 0xB5, 0xD9, 0x16, 0xC1, - 0xB4, 0x3B, 0x62, 0xEE, 0xF4, 0xD0, 0x09, 0x8E, 0xFF, 0x3B, 0x1F, 0x78, - 0xE2, 0xD0, 0xD4, 0x8D, 0x50, 0xD1, 0x68, 0x7B, 0x93, 0xB9, 0x7D, 0x5F, - 0x7C, 0x6D, 0x50, 0x47, 0x40, 0x6A, 0x5E, 0x68, 0x8B, 0x35, 0x22, 0x09, - 0xBC, 0xB9, 0xF8, 0x22, - /* y */ - 0x7D, 0xDE, 0x38, 0x5D, 0x56, 0x63, 0x32, 0xEC, 0xC0, 0xEA, 0xBF, 0xA9, - 0xCF, 0x78, 0x22, 0xFD, 0xF2, 0x09, 0xF7, 0x00, 0x24, 0xA5, 0x7B, 0x1A, - 0xA0, 0x00, 0xC5, 0x5B, 0x88, 0x1F, 0x81, 0x11, 0xB2, 0xDC, 0xDE, 0x49, - 0x4A, 0x5F, 0x48, 0x5E, 0x5B, 0xCA, 0x4B, 0xD8, 0x8A, 0x27, 0x63, 0xAE, - 0xD1, 0xCA, 0x2B, 0x2F, 0xA8, 0xF0, 0x54, 0x06, 0x78, 0xCD, 0x1E, 0x0F, - 0x3A, 0xD8, 0x08, 0x92, - /* order */ - 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, - 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, - 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, - 0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, - 0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82, - 0x9C, 0xA9, 0x00, 0x69 - } -}; - -static const struct { - EC_CURVE_DATA h; - unsigned char data[0 + 64 * 6]; -} _EC_brainpoolP512t1 = { - { - NID_X9_62_prime_field, 0, 64, 1 - }, - { - /* no seed */ - /* p */ - 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, - 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, - 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, - 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, - 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, - 0x58, 0x3A, 0x48, 0xF3, - /* a */ - 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, - 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, - 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x71, 0x7D, 0x4D, 0x9B, 0x00, - 0x9B, 0xC6, 0x68, 0x42, 0xAE, 0xCD, 0xA1, 0x2A, 0xE6, 0xA3, 0x80, 0xE6, - 0x28, 0x81, 0xFF, 0x2F, 0x2D, 0x82, 0xC6, 0x85, 0x28, 0xAA, 0x60, 0x56, - 0x58, 0x3A, 0x48, 0xF0, - /* b */ - 0x7C, 0xBB, 0xBC, 0xF9, 0x44, 0x1C, 0xFA, 0xB7, 0x6E, 0x18, 0x90, 0xE4, - 0x68, 0x84, 0xEA, 0xE3, 0x21, 0xF7, 0x0C, 0x0B, 0xCB, 0x49, 0x81, 0x52, - 0x78, 0x97, 0x50, 0x4B, 0xEC, 0x3E, 0x36, 0xA6, 0x2B, 0xCD, 0xFA, 0x23, - 0x04, 0x97, 0x65, 0x40, 0xF6, 0x45, 0x00, 0x85, 0xF2, 0xDA, 0xE1, 0x45, - 0xC2, 0x25, 0x53, 0xB4, 0x65, 0x76, 0x36, 0x89, 0x18, 0x0E, 0xA2, 0x57, - 0x18, 0x67, 0x42, 0x3E, - /* x */ - 0x64, 0x0E, 0xCE, 0x5C, 0x12, 0x78, 0x87, 0x17, 0xB9, 0xC1, 0xBA, 0x06, - 0xCB, 0xC2, 0xA6, 0xFE, 0xBA, 0x85, 0x84, 0x24, 0x58, 0xC5, 0x6D, 0xDE, - 0x9D, 0xB1, 0x75, 0x8D, 0x39, 0xC0, 0x31, 0x3D, 0x82, 0xBA, 0x51, 0x73, - 0x5C, 0xDB, 0x3E, 0xA4, 0x99, 0xAA, 0x77, 0xA7, 0xD6, 0x94, 0x3A, 0x64, - 0xF7, 0xA3, 0xF2, 0x5F, 0xE2, 0x6F, 0x06, 0xB5, 0x1B, 0xAA, 0x26, 0x96, - 0xFA, 0x90, 0x35, 0xDA, - /* y */ - 0x5B, 0x53, 0x4B, 0xD5, 0x95, 0xF5, 0xAF, 0x0F, 0xA2, 0xC8, 0x92, 0x37, - 0x6C, 0x84, 0xAC, 0xE1, 0xBB, 0x4E, 0x30, 0x19, 0xB7, 0x16, 0x34, 0xC0, - 0x11, 0x31, 0x15, 0x9C, 0xAE, 0x03, 0xCE, 0xE9, 0xD9, 0x93, 0x21, 0x84, - 0xBE, 0xEF, 0x21, 0x6B, 0xD7, 0x1D, 0xF2, 0xDA, 0xDF, 0x86, 0xA6, 0x27, - 0x30, 0x6E, 0xCF, 0xF9, 0x6D, 0xBB, 0x8B, 0xAC, 0xE1, 0x98, 0xB6, 0x1E, - 0x00, 0xF8, 0xB3, 0x32, - /* order */ - 0xAA, 0xDD, 0x9D, 0xB8, 0xDB, 0xE9, 0xC4, 0x8B, 0x3F, 0xD4, 0xE6, 0xAE, - 0x33, 0xC9, 0xFC, 0x07, 0xCB, 0x30, 0x8D, 0xB3, 0xB3, 0xC9, 0xD2, 0x0E, - 0xD6, 0x63, 0x9C, 0xCA, 0x70, 0x33, 0x08, 0x70, 0x55, 0x3E, 0x5C, 0x41, - 0x4C, 0xA9, 0x26, 0x19, 0x41, 0x86, 0x61, 0x19, 0x7F, 0xAC, 0x10, 0x47, - 0x1D, 0xB1, 0xD3, 0x81, 0x08, 0x5D, 0xDA, 0xDD, 0xB5, 0x87, 0x96, 0x82, - 0x9C, 0xA9, 0x00, 0x69 - } -}; - -typedef struct _ec_list_element_st { - int nid; - const EC_CURVE_DATA *data; - const EC_METHOD *(*meth) (void); - const char *comment; -} ec_list_element; - -static const ec_list_element curve_list[] = { - /* prime field curves */ - /* secg curves */ - {NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, - "SECG/WTLS curve over a 112 bit prime field"}, - {NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, - "SECG curve over a 112 bit prime field"}, - {NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, - "SECG curve over a 128 bit prime field"}, - {NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, - "SECG curve over a 128 bit prime field"}, - {NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, - "SECG curve over a 160 bit prime field"}, - {NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, - "SECG curve over a 160 bit prime field"}, - {NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, - "SECG/WTLS curve over a 160 bit prime field"}, - /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ - {NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, - "SECG curve over a 192 bit prime field"}, - {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, - "SECG curve over a 224 bit prime field"}, -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, - "NIST/SECG curve over a 224 bit prime field"}, -#else - {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, - "NIST/SECG curve over a 224 bit prime field"}, -#endif - {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, - "SECG curve over a 256 bit prime field"}, - /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ - {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, - "NIST/SECG curve over a 384 bit prime field"}, -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, - "NIST/SECG curve over a 521 bit prime field"}, -#else - {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, - "NIST/SECG curve over a 521 bit prime field"}, -#endif - /* X9.62 curves */ - {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, - "NIST/X9.62/SECG curve over a 192 bit prime field"}, - {NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, - "X9.62 curve over a 192 bit prime field"}, - {NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, - "X9.62 curve over a 192 bit prime field"}, - {NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, - "X9.62 curve over a 239 bit prime field"}, - {NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, - "X9.62 curve over a 239 bit prime field"}, - {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, - "X9.62 curve over a 239 bit prime field"}, - {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, -#if defined(ECP_NISTZ256_ASM) - EC_GFp_nistz256_method, -#elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128) - EC_GFp_nistp256_method, -#else - 0, -#endif - "X9.62/SECG curve over a 256 bit prime field"}, -#ifndef OPENSSL_NO_EC2M - /* characteristic two field curves */ - /* NIST/SECG curves */ - {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, - "SECG curve over a 113 bit binary field"}, - {NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, - "SECG curve over a 113 bit binary field"}, - {NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, - "SECG/WTLS curve over a 131 bit binary field"}, - {NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, - "SECG curve over a 131 bit binary field"}, - {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, - "NIST/SECG/WTLS curve over a 163 bit binary field"}, - {NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, - "SECG curve over a 163 bit binary field"}, - {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, - "NIST/SECG curve over a 163 bit binary field"}, - {NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, - "SECG curve over a 193 bit binary field"}, - {NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, - "SECG curve over a 193 bit binary field"}, - {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, - "NIST/SECG/WTLS curve over a 233 bit binary field"}, - {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, - "NIST/SECG/WTLS curve over a 233 bit binary field"}, - {NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, - "SECG curve over a 239 bit binary field"}, - {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, - "NIST/SECG curve over a 283 bit binary field"}, - {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, - "NIST/SECG curve over a 283 bit binary field"}, - {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, - "NIST/SECG curve over a 409 bit binary field"}, - {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, - "NIST/SECG curve over a 409 bit binary field"}, - {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, - "NIST/SECG curve over a 571 bit binary field"}, - {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, - "NIST/SECG curve over a 571 bit binary field"}, - /* X9.62 curves */ - {NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, - "X9.62 curve over a 163 bit binary field"}, - {NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, - "X9.62 curve over a 163 bit binary field"}, - {NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, - "X9.62 curve over a 163 bit binary field"}, - {NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, - "X9.62 curve over a 176 bit binary field"}, - {NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, - "X9.62 curve over a 191 bit binary field"}, - {NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, - "X9.62 curve over a 191 bit binary field"}, - {NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, - "X9.62 curve over a 191 bit binary field"}, - {NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, - "X9.62 curve over a 208 bit binary field"}, - {NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, - "X9.62 curve over a 239 bit binary field"}, - {NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, - "X9.62 curve over a 239 bit binary field"}, - {NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, - "X9.62 curve over a 239 bit binary field"}, - {NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, - "X9.62 curve over a 272 bit binary field"}, - {NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, - "X9.62 curve over a 304 bit binary field"}, - {NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, - "X9.62 curve over a 359 bit binary field"}, - {NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, - "X9.62 curve over a 368 bit binary field"}, - {NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, - "X9.62 curve over a 431 bit binary field"}, - /* - * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves - * from X9.62] - */ - {NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, - "WTLS curve over a 113 bit binary field"}, - {NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, - "NIST/SECG/WTLS curve over a 163 bit binary field"}, - {NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, - "SECG curve over a 113 bit binary field"}, - {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, - "X9.62 curve over a 163 bit binary field"}, -#endif - {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, - "SECG/WTLS curve over a 112 bit prime field"}, - {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, - "SECG/WTLS curve over a 160 bit prime field"}, - {NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, - "WTLS curve over a 112 bit prime field"}, - {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, - "WTLS curve over a 160 bit prime field"}, -#ifndef OPENSSL_NO_EC2M - {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, - "NIST/SECG/WTLS curve over a 233 bit binary field"}, - {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, - "NIST/SECG/WTLS curve over a 233 bit binary field"}, -#endif - {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, - "WTLS curvs over a 224 bit prime field"}, -#ifndef OPENSSL_NO_EC2M - /* IPSec curves */ - {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, - "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" - "\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, - {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, - "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" - "\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, -#endif - /* brainpool curves */ - {NID_brainpoolP160r1, &_EC_brainpoolP160r1.h, 0, - "RFC 5639 curve over a 160 bit prime field"}, - {NID_brainpoolP160t1, &_EC_brainpoolP160t1.h, 0, - "RFC 5639 curve over a 160 bit prime field"}, - {NID_brainpoolP192r1, &_EC_brainpoolP192r1.h, 0, - "RFC 5639 curve over a 192 bit prime field"}, - {NID_brainpoolP192t1, &_EC_brainpoolP192t1.h, 0, - "RFC 5639 curve over a 192 bit prime field"}, - {NID_brainpoolP224r1, &_EC_brainpoolP224r1.h, 0, - "RFC 5639 curve over a 224 bit prime field"}, - {NID_brainpoolP224t1, &_EC_brainpoolP224t1.h, 0, - "RFC 5639 curve over a 224 bit prime field"}, - {NID_brainpoolP256r1, &_EC_brainpoolP256r1.h, 0, - "RFC 5639 curve over a 256 bit prime field"}, - {NID_brainpoolP256t1, &_EC_brainpoolP256t1.h, 0, - "RFC 5639 curve over a 256 bit prime field"}, - {NID_brainpoolP320r1, &_EC_brainpoolP320r1.h, 0, - "RFC 5639 curve over a 320 bit prime field"}, - {NID_brainpoolP320t1, &_EC_brainpoolP320t1.h, 0, - "RFC 5639 curve over a 320 bit prime field"}, - {NID_brainpoolP384r1, &_EC_brainpoolP384r1.h, 0, - "RFC 5639 curve over a 384 bit prime field"}, - {NID_brainpoolP384t1, &_EC_brainpoolP384t1.h, 0, - "RFC 5639 curve over a 384 bit prime field"}, - {NID_brainpoolP512r1, &_EC_brainpoolP512r1.h, 0, - "RFC 5639 curve over a 512 bit prime field"}, - {NID_brainpoolP512t1, &_EC_brainpoolP512t1.h, 0, - "RFC 5639 curve over a 512 bit prime field"}, -}; - -#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element)) - -static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) -{ - EC_GROUP *group = NULL; - EC_POINT *P = NULL; - BN_CTX *ctx = NULL; - BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = - NULL; - int ok = 0; - int seed_len, param_len; - const EC_METHOD *meth; - const EC_CURVE_DATA *data; - const unsigned char *params; - - if ((ctx = BN_CTX_new()) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); - goto err; - } - - data = curve.data; - seed_len = data->seed_len; - param_len = data->param_len; - params = (const unsigned char *)(data + 1); /* skip header */ - params += seed_len; /* skip seed */ - - if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) - || !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) - || !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); - goto err; - } - - if (curve.meth != 0) { - meth = curve.meth(); - if (((group = EC_GROUP_new(meth)) == NULL) || - (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); - goto err; - } - } else if (data->field_type == NID_X9_62_prime_field) { - if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); - goto err; - } - } -#ifndef OPENSSL_NO_EC2M - else { /* field_type == - * NID_X9_62_characteristic_two_field */ - - if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); - goto err; - } - } -#endif - - if ((P = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); - goto err; - } - - if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) - || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); - goto err; - } - if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); - goto err; - } - if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) - || !BN_set_word(x, (BN_ULONG)data->cofactor)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); - goto err; - } - if (!EC_GROUP_set_generator(group, P, order, x)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); - goto err; - } - if (seed_len) { - if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) { - ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); - goto err; - } - } - ok = 1; - err: - if (!ok) { - EC_GROUP_free(group); - group = NULL; - } - if (P) - EC_POINT_free(P); - if (ctx) - BN_CTX_free(ctx); - if (p) - BN_free(p); - if (a) - BN_free(a); - if (b) - BN_free(b); - if (order) - BN_free(order); - if (x) - BN_free(x); - if (y) - BN_free(y); - return group; -} - -EC_GROUP *EC_GROUP_new_by_curve_name(int nid) -{ - size_t i; - EC_GROUP *ret = NULL; - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_ec_group_new_by_curve_name(nid); -#endif - if (nid <= 0) - return NULL; - - for (i = 0; i < curve_list_length; i++) - if (curve_list[i].nid == nid) { - ret = ec_group_new_from_data(curve_list[i]); - break; - } - - if (ret == NULL) { - ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP); - return NULL; - } - - EC_GROUP_set_curve_name(ret, nid); - - return ret; -} - -size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) -{ - size_t i, min; - - if (r == NULL || nitems == 0) - return curve_list_length; - - min = nitems < curve_list_length ? nitems : curve_list_length; - - for (i = 0; i < min; i++) { - r[i].nid = curve_list[i].nid; - r[i].comment = curve_list[i].comment; - } - - return curve_list_length; -} - -/* Functions to translate between common NIST curve names and NIDs */ - -typedef struct { - const char *name; /* NIST Name of curve */ - int nid; /* Curve NID */ -} EC_NIST_NAME; - -static EC_NIST_NAME nist_curves[] = { - {"B-163", NID_sect163r2}, - {"B-233", NID_sect233r1}, - {"B-283", NID_sect283r1}, - {"B-409", NID_sect409r1}, - {"B-571", NID_sect571r1}, - {"K-163", NID_sect163k1}, - {"K-233", NID_sect233k1}, - {"K-283", NID_sect283k1}, - {"K-409", NID_sect409k1}, - {"K-571", NID_sect571k1}, - {"P-192", NID_X9_62_prime192v1}, - {"P-224", NID_secp224r1}, - {"P-256", NID_X9_62_prime256v1}, - {"P-384", NID_secp384r1}, - {"P-521", NID_secp521r1} -}; - -const char *EC_curve_nid2nist(int nid) -{ - size_t i; - for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) { - if (nist_curves[i].nid == nid) - return nist_curves[i].name; - } - return NULL; -} - -int EC_curve_nist2nid(const char *name) -{ - size_t i; - for (i = 0; i < sizeof(nist_curves) / sizeof(EC_NIST_NAME); i++) { - if (!strcmp(nist_curves[i].name, name)) - return nist_curves[i].nid; - } - return NID_undef; -} -/* crypto/ec/ec_cvt.c */ -/* - * Originally written by Bodo Moeller for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * The elliptic curve binary polynomial software is originally written by - * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. - * - */ - -// #include "err.h" -// #include "ec_lcl.h" - -#ifdef OPENSSL_FIPS -# include -#endif - -EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - const EC_METHOD *meth; - EC_GROUP *ret; - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_ec_group_new_curve_gfp(p, a, b, ctx); -#endif -#if defined(OPENSSL_BN_ASM_MONT) - /* - * This might appear controversial, but the fact is that generic - * prime method was observed to deliver better performance even - * for NIST primes on a range of platforms, e.g.: 60%-15% - * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25% - * in 32-bit build and 35%--12% in 64-bit build on Core2... - * Coefficients are relative to optimized bn_nist.c for most - * intensive ECDSA verify and ECDH operations for 192- and 521- - * bit keys respectively. Choice of these boundary values is - * arguable, because the dependency of improvement coefficient - * from key length is not a "monotone" curve. For example while - * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's - * generally faster, sometimes "respectfully" faster, sometimes - * "tolerably" slower... What effectively happens is that loop - * with bn_mul_add_words is put against bn_mul_mont, and the - * latter "wins" on short vectors. Correct solution should be - * implementing dedicated NxN multiplication subroutines for - * small N. But till it materializes, let's stick to generic - * prime method... - * - */ - meth = EC_GFp_mont_method(); -#else - meth = EC_GFp_nist_method(); -#endif - - ret = EC_GROUP_new(meth); - if (ret == NULL) - return NULL; - - if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { - unsigned long err; - - err = ERR_peek_last_error(); - - if (!(ERR_GET_LIB(err) == ERR_LIB_EC && - ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) || - (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) { - /* real error */ - - EC_GROUP_clear_free(ret); - return NULL; - } - - /* - * not an actual error, we just cannot use EC_GFp_nist_method - */ - - ERR_clear_error(); - - EC_GROUP_clear_free(ret); - meth = EC_GFp_mont_method(); - - ret = EC_GROUP_new(meth); - if (ret == NULL) - return NULL; - - if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { - EC_GROUP_clear_free(ret); - return NULL; - } - } - - return ret; -} - -#ifndef OPENSSL_NO_EC2M -EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - const EC_METHOD *meth; - EC_GROUP *ret; - -# ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_ec_group_new_curve_gf2m(p, a, b, ctx); -# endif - meth = EC_GF2m_simple_method(); - - ret = EC_GROUP_new(meth); - if (ret == NULL) - return NULL; - - if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) { - EC_GROUP_clear_free(ret); - return NULL; - } - - return ret; -} -#endif -/* crypto/ec/ec_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -// #include "err.h" -// #include "ec.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason) - -static ERR_STRING_DATA EC_str_functs[] = { - {ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"}, - {ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"}, - {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"}, - {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"}, - {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"}, - {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"}, - {ERR_FUNC(EC_F_ECDH_CMS_DECRYPT), "ECDH_CMS_DECRYPT"}, - {ERR_FUNC(EC_F_ECDH_CMS_SET_SHARED_INFO), "ECDH_CMS_SET_SHARED_INFO"}, - {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"}, - {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"}, - {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"}, - {ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"}, - {ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"}, - {ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"}, - {ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"}, - {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"}, - {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"}, - {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"}, - {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"}, - {ERR_FUNC(EC_F_ECP_NISTZ256_GET_AFFINE), "ecp_nistz256_get_affine"}, - {ERR_FUNC(EC_F_ECP_NISTZ256_MULT_PRECOMPUTE), - "ecp_nistz256_mult_precompute"}, - {ERR_FUNC(EC_F_ECP_NISTZ256_POINTS_MUL), "ecp_nistz256_points_mul"}, - {ERR_FUNC(EC_F_ECP_NISTZ256_PRE_COMP_NEW), "ecp_nistz256_pre_comp_new"}, - {ERR_FUNC(EC_F_ECP_NISTZ256_SET_WORDS), "ecp_nistz256_set_words"}, - {ERR_FUNC(EC_F_ECP_NISTZ256_WINDOWED_MUL), "ecp_nistz256_windowed_mul"}, - {ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"}, - {ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"}, - {ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"}, - {ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"}, - {ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"}, - {ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"}, - {ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"}, - {ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"}, - {ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"}, - {ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"}, - {ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"}, - {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), - "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"}, - {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), - "ec_GF2m_simple_group_check_discriminant"}, - {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), - "ec_GF2m_simple_group_set_curve"}, - {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"}, - {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"}, - {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), - "ec_GF2m_simple_point_get_affine_coordinates"}, - {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), - "ec_GF2m_simple_point_set_affine_coordinates"}, - {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), - "ec_GF2m_simple_set_compressed_coordinates"}, - {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"}, - {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"}, - {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"}, - {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), - "ec_GFp_mont_field_set_to_one"}, - {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"}, - {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), - "ec_GFp_mont_group_set_curve"}, - {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), - "EC_GFP_MONT_GROUP_SET_CURVE_GFP"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE), - "ec_GFp_nistp224_group_set_curve"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES), - "ec_GFp_nistp224_point_get_affine_coordinates"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE), - "ec_GFp_nistp256_group_set_curve"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES), - "ec_GFp_nistp256_point_get_affine_coordinates"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE), - "ec_GFp_nistp521_group_set_curve"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"}, - {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES), - "ec_GFp_nistp521_point_get_affine_coordinates"}, - {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"}, - {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"}, - {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), - "ec_GFp_nist_group_set_curve"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), - "ec_GFp_simple_group_check_discriminant"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), - "ec_GFp_simple_group_set_curve"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), - "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), - "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), - "ec_GFp_simple_points_make_affine"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), - "ec_GFp_simple_point_get_affine_coordinates"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), - "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), - "ec_GFp_simple_point_set_affine_coordinates"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), - "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), - "ec_GFp_simple_set_compressed_coordinates"}, - {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), - "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"}, - {ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"}, - {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), - "EC_GROUP_check_discriminant"}, - {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"}, - {ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"}, - {ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"}, - {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"}, - {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"}, - {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"}, - {ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"}, - {ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), - "EC_GROUP_get_pentanomial_basis"}, - {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), - "EC_GROUP_get_trinomial_basis"}, - {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"}, - {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"}, - {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"}, - {ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"}, - {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"}, - {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"}, - {ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"}, - {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"}, - {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"}, - {ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"}, - {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"}, - {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"}, - {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"}, - {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"}, - {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES), - "EC_KEY_set_public_key_affine_coordinates"}, - {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"}, - {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, - {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, - {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"}, - {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"}, - {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), - "EC_POINT_get_affine_coordinates_GF2m"}, - {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), - "EC_POINT_get_affine_coordinates_GFp"}, - {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), - "EC_POINT_get_Jprojective_coordinates_GFp"}, - {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"}, - {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"}, - {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"}, - {ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"}, - {ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"}, - {ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"}, - {ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"}, - {ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"}, - {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), - "EC_POINT_set_affine_coordinates_GF2m"}, - {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), - "EC_POINT_set_affine_coordinates_GFp"}, - {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), - "EC_POINT_set_compressed_coordinates_GF2m"}, - {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), - "EC_POINT_set_compressed_coordinates_GFp"}, - {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), - "EC_POINT_set_Jprojective_coordinates_GFp"}, - {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"}, - {ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"}, - {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"}, - {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"}, - {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"}, - {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"}, - {ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"}, - {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"}, - {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"}, - {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"}, - {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"}, - {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"}, - {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"}, - {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"}, - {ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"}, - {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"}, - {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"}, - {ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"}, - {ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"}, - {ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"}, - {0, NULL} -}; - -static ERR_STRING_DATA EC_str_reasons[] = { - {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"}, - {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"}, - {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"}, - {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"}, - {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"}, - {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE), - "d2i ecpkparameters failure"}, - {ERR_REASON(EC_R_DECODE_ERROR), "decode error"}, - {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"}, - {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), - "ec group new by name failure"}, - {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"}, - {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"}, - {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), - "group2pkparameters failure"}, - {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE), - "i2d ecpkparameters failure"}, - {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"}, - {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"}, - {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"}, - {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"}, - {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"}, - {ERR_REASON(EC_R_INVALID_DIGEST), "invalid digest"}, - {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"}, - {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"}, - {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"}, - {ERR_REASON(EC_R_INVALID_FORM), "invalid form"}, - {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"}, - {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, - {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, - {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, - {ERR_REASON(EC_R_KDF_PARAMETER_ERROR), "kdf parameter error"}, - {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"}, - {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"}, - {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"}, - {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"}, - {ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME), - "not a supported NIST prime"}, - {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"}, - {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"}, - {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"}, - {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"}, - {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"}, - {ERR_REASON(EC_R_PEER_KEY_ERROR), "peer key error"}, - {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), - "pkparameters2group failure"}, - {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"}, - {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"}, - {ERR_REASON(EC_R_SHARED_INFO_ERROR), "shared info error"}, - {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, - {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, - {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, - {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, - {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, - {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, - {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"}, - {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"}, - {0, NULL} -}; - -#endif - -void ERR_load_EC_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(EC_str_functs[0].error) == NULL) { - ERR_load_strings(0, EC_str_functs); - ERR_load_strings(0, EC_str_reasons); - } -#endif -} -/* crypto/ec/ec_key.c */ -/* - * Written by Nils Larsch for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Portions originally developed by SUN MICROSYSTEMS, INC., and - * contributed to the OpenSSL project. - */ - -#include -// #include "ec_lcl.h" -// #include "err.h" -#ifdef OPENSSL_FIPS -# include -#endif - -EC_KEY *EC_KEY_new(void) -{ - EC_KEY *ret; - - ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); - if (ret == NULL) { - ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - ret->version = 1; - ret->flags = 0; - ret->group = NULL; - ret->pub_key = NULL; - ret->priv_key = NULL; - ret->enc_flag = 0; - ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; - ret->references = 1; - ret->method_data = NULL; - return (ret); -} - -EC_KEY *EC_KEY_new_by_curve_name(int nid) -{ - EC_KEY *ret = EC_KEY_new(); - if (ret == NULL) - return NULL; - ret->group = EC_GROUP_new_by_curve_name(nid); - if (ret->group == NULL) { - EC_KEY_free(ret); - return NULL; - } - return ret; -} - -void EC_KEY_free(EC_KEY *r) -{ - int i; - - if (r == NULL) - return; - - i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); -#ifdef REF_PRINT - REF_PRINT("EC_KEY", r); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "EC_KEY_free, bad reference count\n"); - abort(); - } -#endif - - if (r->group != NULL) - EC_GROUP_free(r->group); - if (r->pub_key != NULL) - EC_POINT_free(r->pub_key); - if (r->priv_key != NULL) - BN_clear_free(r->priv_key); - - EC_EX_DATA_free_all_data(&r->method_data); - - OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); - - OPENSSL_free(r); -} - -EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) -{ - EC_EXTRA_DATA *d; - - if (dest == NULL || src == NULL) { - ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - /* copy the parameters */ - if (src->group) { - const EC_METHOD *meth = EC_GROUP_method_of(src->group); - /* clear the old group */ - if (dest->group) - EC_GROUP_free(dest->group); - dest->group = EC_GROUP_new(meth); - if (dest->group == NULL) - return NULL; - if (!EC_GROUP_copy(dest->group, src->group)) - return NULL; - } - /* copy the public key */ - if (src->pub_key && src->group) { - if (dest->pub_key) - EC_POINT_free(dest->pub_key); - dest->pub_key = EC_POINT_new(src->group); - if (dest->pub_key == NULL) - return NULL; - if (!EC_POINT_copy(dest->pub_key, src->pub_key)) - return NULL; - } - /* copy the private key */ - if (src->priv_key) { - if (dest->priv_key == NULL) { - dest->priv_key = BN_new(); - if (dest->priv_key == NULL) - return NULL; - } - if (!BN_copy(dest->priv_key, src->priv_key)) - return NULL; - } - /* copy method/extra data */ - EC_EX_DATA_free_all_data(&dest->method_data); - - for (d = src->method_data; d != NULL; d = d->next) { - void *t = d->dup_func(d->data); - - if (t == NULL) - return 0; - if (!EC_EX_DATA_set_data - (&dest->method_data, t, d->dup_func, d->free_func, - d->clear_free_func)) - return 0; - } - - /* copy the rest */ - dest->enc_flag = src->enc_flag; - dest->conv_form = src->conv_form; - dest->version = src->version; - dest->flags = src->flags; - - return dest; -} - -EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) -{ - EC_KEY *ret = EC_KEY_new(); - if (ret == NULL) - return NULL; - if (EC_KEY_copy(ret, ec_key) == NULL) { - EC_KEY_free(ret); - return NULL; - } - return ret; -} - -int EC_KEY_up_ref(EC_KEY *r) -{ - int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); -#ifdef REF_PRINT - REF_PRINT("EC_KEY", r); -#endif -#ifdef REF_CHECK - if (i < 2) { - fprintf(stderr, "EC_KEY_up, bad reference count\n"); - abort(); - } -#endif - return ((i > 1) ? 1 : 0); -} - -int EC_KEY_generate_key(EC_KEY *eckey) -{ - int ok = 0; - BN_CTX *ctx = NULL; - BIGNUM *priv_key = NULL, *order = NULL; - EC_POINT *pub_key = NULL; - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_ec_key_generate_key(eckey); -#endif - - if (!eckey || !eckey->group) { - ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if ((order = BN_new()) == NULL) - goto err; - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - if (eckey->priv_key == NULL) { - priv_key = BN_new(); - if (priv_key == NULL) - goto err; - } else - priv_key = eckey->priv_key; - - if (!EC_GROUP_get_order(eckey->group, order, ctx)) - goto err; - - do - if (!BN_rand_range(priv_key, order)) - goto err; - while (BN_is_zero(priv_key)) ; - - if (eckey->pub_key == NULL) { - pub_key = EC_POINT_new(eckey->group); - if (pub_key == NULL) - goto err; - } else - pub_key = eckey->pub_key; - - if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) - goto err; - - eckey->priv_key = priv_key; - eckey->pub_key = pub_key; - - ok = 1; - - err: - if (order) - BN_free(order); - if (pub_key != NULL && eckey->pub_key == NULL) - EC_POINT_free(pub_key); - if (priv_key != NULL && eckey->priv_key == NULL) - BN_free(priv_key); - if (ctx != NULL) - BN_CTX_free(ctx); - return (ok); -} - -int EC_KEY_check_key(const EC_KEY *eckey) -{ - int ok = 0; - BN_CTX *ctx = NULL; - const BIGNUM *order = NULL; - EC_POINT *point = NULL; - - if (!eckey || !eckey->group || !eckey->pub_key) { - ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { - ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); - goto err; - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - if ((point = EC_POINT_new(eckey->group)) == NULL) - goto err; - - /* testing whether the pub_key is on the elliptic curve */ - if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { - ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); - goto err; - } - /* testing whether pub_key * order is the point at infinity */ - order = &eckey->group->order; - if (BN_is_zero(order)) { - ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); - goto err; - } - if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { - ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); - goto err; - } - if (!EC_POINT_is_at_infinity(eckey->group, point)) { - ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); - goto err; - } - /* - * in case the priv_key is present : check if generator * priv_key == - * pub_key - */ - if (eckey->priv_key) { - if (BN_cmp(eckey->priv_key, order) >= 0) { - ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); - goto err; - } - if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, - NULL, NULL, ctx)) { - ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); - goto err; - } - if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { - ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); - goto err; - } - } - ok = 1; - err: - if (ctx != NULL) - BN_CTX_free(ctx); - if (point != NULL) - EC_POINT_free(point); - return (ok); -} - -int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, - BIGNUM *y) -{ - BN_CTX *ctx = NULL; - BIGNUM *tx, *ty; - EC_POINT *point = NULL; - int ok = 0; -#ifndef OPENSSL_NO_EC2M - int tmp_nid, is_char_two = 0; -#endif - - if (!key || !key->group || !x || !y) { - ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - BN_CTX_start(ctx); - point = EC_POINT_new(key->group); - - if (!point) - goto err; - - tx = BN_CTX_get(ctx); - ty = BN_CTX_get(ctx); - if (ty == NULL) - goto err; - -#ifndef OPENSSL_NO_EC2M - tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group)); - - if (tmp_nid == NID_X9_62_characteristic_two_field) - is_char_two = 1; - - if (is_char_two) { - if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point, - x, y, ctx)) - goto err; - if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point, - tx, ty, ctx)) - goto err; - } else -#endif - { - if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, - x, y, ctx)) - goto err; - if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, - tx, ty, ctx)) - goto err; - } - /* - * Check if retrieved coordinates match originals: if not values are out - * of range. - */ - if (BN_cmp(x, tx) || BN_cmp(y, ty)) { - ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, - EC_R_COORDINATES_OUT_OF_RANGE); - goto err; - } - - if (!EC_KEY_set_public_key(key, point)) - goto err; - - if (EC_KEY_check_key(key) == 0) - goto err; - - ok = 1; - - err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - EC_POINT_free(point); - return ok; - -} - -const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) -{ - return key->group; -} - -int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) -{ - if (key->group != NULL) - EC_GROUP_free(key->group); - key->group = EC_GROUP_dup(group); - return (key->group == NULL) ? 0 : 1; -} - -const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) -{ - return key->priv_key; -} - -int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) -{ - if (key->priv_key) - BN_clear_free(key->priv_key); - key->priv_key = BN_dup(priv_key); - return (key->priv_key == NULL) ? 0 : 1; -} - -const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) -{ - return key->pub_key; -} - -int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) -{ - if (key->pub_key != NULL) - EC_POINT_free(key->pub_key); - key->pub_key = EC_POINT_dup(pub_key, key->group); - return (key->pub_key == NULL) ? 0 : 1; -} - -unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) -{ - return key->enc_flag; -} - -void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) -{ - key->enc_flag = flags; -} - -point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) -{ - return key->conv_form; -} - -void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) -{ - key->conv_form = cform; - if (key->group != NULL) - EC_GROUP_set_point_conversion_form(key->group, cform); -} - -void *EC_KEY_get_key_method_data(EC_KEY *key, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)) -{ - void *ret; - - CRYPTO_r_lock(CRYPTO_LOCK_EC); - ret = - EC_EX_DATA_get_data(key->method_data, dup_func, free_func, - clear_free_func); - CRYPTO_r_unlock(CRYPTO_LOCK_EC); - - return ret; -} - -void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)) -{ - EC_EXTRA_DATA *ex_data; - - CRYPTO_w_lock(CRYPTO_LOCK_EC); - ex_data = - EC_EX_DATA_get_data(key->method_data, dup_func, free_func, - clear_free_func); - if (ex_data == NULL) - EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, - clear_free_func); - CRYPTO_w_unlock(CRYPTO_LOCK_EC); - - return ex_data; -} - -void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) -{ - if (key->group != NULL) - EC_GROUP_set_asn1_flag(key->group, flag); -} - -int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) -{ - if (key->group == NULL) - return 0; - return EC_GROUP_precompute_mult(key->group, ctx); -} - -int EC_KEY_get_flags(const EC_KEY *key) -{ - return key->flags; -} - -void EC_KEY_set_flags(EC_KEY *key, int flags) -{ - key->flags |= flags; -} - -void EC_KEY_clear_flags(EC_KEY *key, int flags) -{ - key->flags &= ~flags; -} -/* crypto/ec/ec_lib.c */ -/* - * Originally written by Bodo Moeller for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Binary polynomial ECC support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include - -// #include "err.h" -#include "opensslv.h" - -// #include "ec_lcl.h" - -const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; - -/* local function prototypes */ - -static int ec_precompute_mont_data(EC_GROUP *group); - -/* functions for EC_GROUP objects */ - -EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) -{ - EC_GROUP *ret; - - if (meth == NULL) { - ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL); - return NULL; - } - if (meth->group_init == 0) { - ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return NULL; - } - - ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - - ret->meth = meth; - - ret->extra_data = NULL; - ret->mont_data = NULL; - - ret->generator = NULL; - BN_init(&ret->order); - BN_init(&ret->cofactor); - - ret->curve_name = 0; - ret->asn1_flag = ~EC_GROUP_ASN1_FLAG_MASK; - ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; - - ret->seed = NULL; - ret->seed_len = 0; - - if (!meth->group_init(ret)) { - OPENSSL_free(ret); - return NULL; - } - - return ret; -} - -void EC_GROUP_free(EC_GROUP *group) -{ - if (!group) - return; - - if (group->meth->group_finish != 0) - group->meth->group_finish(group); - - EC_EX_DATA_free_all_data(&group->extra_data); - - if (EC_GROUP_VERSION(group) && group->mont_data) - BN_MONT_CTX_free(group->mont_data); - - if (group->generator != NULL) - EC_POINT_free(group->generator); - BN_free(&group->order); - BN_free(&group->cofactor); - - if (group->seed) - OPENSSL_free(group->seed); - - OPENSSL_free(group); -} - -void EC_GROUP_clear_free(EC_GROUP *group) -{ - if (!group) - return; - - if (group->meth->group_clear_finish != 0) - group->meth->group_clear_finish(group); - else if (group->meth->group_finish != 0) - group->meth->group_finish(group); - - EC_EX_DATA_clear_free_all_data(&group->extra_data); - - if (EC_GROUP_VERSION(group) && group->mont_data) - BN_MONT_CTX_free(group->mont_data); - - if (group->generator != NULL) - EC_POINT_clear_free(group->generator); - BN_clear_free(&group->order); - BN_clear_free(&group->cofactor); - - if (group->seed) { - OPENSSL_cleanse(group->seed, group->seed_len); - OPENSSL_free(group->seed); - } - - OPENSSL_cleanse(group, sizeof(*group)); - OPENSSL_free(group); -} - -int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) -{ - EC_EXTRA_DATA *d; - - if (dest->meth->group_copy == 0) { - ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (dest->meth != src->meth) { - ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - if (dest == src) - return 1; - - EC_EX_DATA_free_all_data(&dest->extra_data); - - for (d = src->extra_data; d != NULL; d = d->next) { - void *t = d->dup_func(d->data); - - if (t == NULL) - return 0; - if (!EC_EX_DATA_set_data - (&dest->extra_data, t, d->dup_func, d->free_func, - d->clear_free_func)) - return 0; - } - - if (EC_GROUP_VERSION(src) && src->mont_data != NULL) { - if (dest->mont_data == NULL) { - dest->mont_data = BN_MONT_CTX_new(); - if (dest->mont_data == NULL) - return 0; - } - if (!BN_MONT_CTX_copy(dest->mont_data, src->mont_data)) - return 0; - } else { - /* src->generator == NULL */ - if (EC_GROUP_VERSION(dest) && dest->mont_data != NULL) { - BN_MONT_CTX_free(dest->mont_data); - dest->mont_data = NULL; - } - } - - if (src->generator != NULL) { - if (dest->generator == NULL) { - dest->generator = EC_POINT_new(dest); - if (dest->generator == NULL) - return 0; - } - if (!EC_POINT_copy(dest->generator, src->generator)) - return 0; - } else { - /* src->generator == NULL */ - if (dest->generator != NULL) { - EC_POINT_clear_free(dest->generator); - dest->generator = NULL; - } - } - - if (!BN_copy(&dest->order, &src->order)) - return 0; - if (!BN_copy(&dest->cofactor, &src->cofactor)) - return 0; - - dest->curve_name = src->curve_name; - dest->asn1_flag = src->asn1_flag; - dest->asn1_form = src->asn1_form; - - if (src->seed) { - if (dest->seed) - OPENSSL_free(dest->seed); - dest->seed = OPENSSL_malloc(src->seed_len); - if (dest->seed == NULL) - return 0; - if (!memcpy(dest->seed, src->seed, src->seed_len)) - return 0; - dest->seed_len = src->seed_len; - } else { - if (dest->seed) - OPENSSL_free(dest->seed); - dest->seed = NULL; - dest->seed_len = 0; - } - - return dest->meth->group_copy(dest, src); -} - -EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) -{ - EC_GROUP *t = NULL; - int ok = 0; - - if (a == NULL) - return NULL; - - if ((t = EC_GROUP_new(a->meth)) == NULL) - return (NULL); - if (!EC_GROUP_copy(t, a)) - goto err; - - ok = 1; - - err: - if (!ok) { - if (t) - EC_GROUP_free(t); - return NULL; - } else - return t; -} - -const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) -{ - return group->meth; -} - -int EC_METHOD_get_field_type(const EC_METHOD *meth) -{ - return meth->field_type; -} - -int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, - const BIGNUM *order, const BIGNUM *cofactor) -{ - if (generator == NULL) { - ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (group->generator == NULL) { - group->generator = EC_POINT_new(group); - if (group->generator == NULL) - return 0; - } - if (!EC_POINT_copy(group->generator, generator)) - return 0; - - if (order != NULL) { - if (!BN_copy(&group->order, order)) - return 0; - } else - BN_zero(&group->order); - - if (cofactor != NULL) { - if (!BN_copy(&group->cofactor, cofactor)) - return 0; - } else - BN_zero(&group->cofactor); - - /*- - * Access to the `mont_data` field of an EC_GROUP struct should always be - * guarded by an EC_GROUP_VERSION(group) check to avoid OOB accesses, as the - * group might come from the FIPS module, which does not define the - * `mont_data` field inside the EC_GROUP structure. - */ - if (EC_GROUP_VERSION(group)) { - /*- - * Some groups have an order with - * factors of two, which makes the Montgomery setup fail. - * |group->mont_data| will be NULL in this case. - */ - if (BN_is_odd(&group->order)) - return ec_precompute_mont_data(group); - - BN_MONT_CTX_free(group->mont_data); - group->mont_data = NULL; - } - - return 1; -} - -const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) -{ - return group->generator; -} - -BN_MONT_CTX *EC_GROUP_get_mont_data(const EC_GROUP *group) -{ - return EC_GROUP_VERSION(group) ? group->mont_data : NULL; -} - -int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) -{ - if (!BN_copy(order, &group->order)) - return 0; - - return !BN_is_zero(order); -} - -int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, - BN_CTX *ctx) -{ - if (!BN_copy(cofactor, &group->cofactor)) - return 0; - - return !BN_is_zero(&group->cofactor); -} - -void EC_GROUP_set_curve_name(EC_GROUP *group, int nid) -{ - group->curve_name = nid; -} - -int EC_GROUP_get_curve_name(const EC_GROUP *group) -{ - return group->curve_name; -} - -void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) -{ - group->asn1_flag &= ~EC_GROUP_ASN1_FLAG_MASK; - group->asn1_flag |= flag & EC_GROUP_ASN1_FLAG_MASK; -} - -int EC_GROUP_get_asn1_flag(const EC_GROUP *group) -{ - return group->asn1_flag & EC_GROUP_ASN1_FLAG_MASK; -} - -void EC_GROUP_set_point_conversion_form(EC_GROUP *group, - point_conversion_form_t form) -{ - group->asn1_form = form; -} - -point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP - *group) -{ - return group->asn1_form; -} - -size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) -{ - if (group->seed) { - OPENSSL_free(group->seed); - group->seed = NULL; - group->seed_len = 0; - } - - if (!len || !p) - return 1; - - if ((group->seed = OPENSSL_malloc(len)) == NULL) - return 0; - memcpy(group->seed, p, len); - group->seed_len = len; - - return len; -} - -unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group) -{ - return group->seed; -} - -size_t EC_GROUP_get_seed_len(const EC_GROUP *group) -{ - return group->seed_len; -} - -int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - if (group->meth->group_set_curve == 0) { - ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_set_curve(group, p, a, b, ctx); -} - -int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *ctx) -{ - if (group->meth->group_get_curve == 0) { - ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_get_curve(group, p, a, b, ctx); -} - -#ifndef OPENSSL_NO_EC2M -int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - if (group->meth->group_set_curve == 0) { - ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_set_curve(group, p, a, b, ctx); -} - -int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *ctx) -{ - if (group->meth->group_get_curve == 0) { - ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_get_curve(group, p, a, b, ctx); -} -#endif - -int EC_GROUP_get_degree(const EC_GROUP *group) -{ - if (group->meth->group_get_degree == 0) { - ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_get_degree(group); -} - -int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) -{ - if (group->meth->group_check_discriminant == 0) { - ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - return group->meth->group_check_discriminant(group, ctx); -} - -int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) -{ - int r = 0; - BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; - BN_CTX *ctx_new = NULL; - - /* compare the field types */ - if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != - EC_METHOD_get_field_type(EC_GROUP_method_of(b))) - return 1; - /* compare the curve name (if present in both) */ - if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && - EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) - return 1; - - if (!ctx) - ctx_new = ctx = BN_CTX_new(); - if (!ctx) - return -1; - - BN_CTX_start(ctx); - a1 = BN_CTX_get(ctx); - a2 = BN_CTX_get(ctx); - a3 = BN_CTX_get(ctx); - b1 = BN_CTX_get(ctx); - b2 = BN_CTX_get(ctx); - b3 = BN_CTX_get(ctx); - if (!b3) { - BN_CTX_end(ctx); - if (ctx_new) - BN_CTX_free(ctx); - return -1; - } - - /* - * XXX This approach assumes that the external representation of curves - * over the same field type is the same. - */ - if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || - !b->meth->group_get_curve(b, b1, b2, b3, ctx)) - r = 1; - - if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) - r = 1; - - /* XXX EC_POINT_cmp() assumes that the methods are equal */ - if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), - EC_GROUP_get0_generator(b), ctx)) - r = 1; - - if (!r) { - /* compare the order and cofactor */ - if (!EC_GROUP_get_order(a, a1, ctx) || - !EC_GROUP_get_order(b, b1, ctx) || - !EC_GROUP_get_cofactor(a, a2, ctx) || - !EC_GROUP_get_cofactor(b, b2, ctx)) { - BN_CTX_end(ctx); - if (ctx_new) - BN_CTX_free(ctx); - return -1; - } - if (BN_cmp(a1, b1) || BN_cmp(a2, b2)) - r = 1; - } - - BN_CTX_end(ctx); - if (ctx_new) - BN_CTX_free(ctx); - - return r; -} - -/* this has 'package' visibility */ -int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)) -{ - EC_EXTRA_DATA *d; - - if (ex_data == NULL) - return 0; - - for (d = *ex_data; d != NULL; d = d->next) { - if (d->dup_func == dup_func && d->free_func == free_func - && d->clear_free_func == clear_free_func) { - ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL); - return 0; - } - } - - if (data == NULL) - /* no explicit entry needed */ - return 1; - - d = OPENSSL_malloc(sizeof(*d)); - if (d == NULL) - return 0; - - d->data = data; - d->dup_func = dup_func; - d->free_func = free_func; - d->clear_free_func = clear_free_func; - - d->next = *ex_data; - *ex_data = d; - - return 1; -} - -/* this has 'package' visibility */ -void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)) -{ - const EC_EXTRA_DATA *d; - - for (d = ex_data; d != NULL; d = d->next) { - if (d->dup_func == dup_func && d->free_func == free_func - && d->clear_free_func == clear_free_func) - return d->data; - } - - return NULL; -} - -/* this has 'package' visibility */ -void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)) -{ - EC_EXTRA_DATA **p; - - if (ex_data == NULL) - return; - - for (p = ex_data; *p != NULL; p = &((*p)->next)) { - if ((*p)->dup_func == dup_func && (*p)->free_func == free_func - && (*p)->clear_free_func == clear_free_func) { - EC_EXTRA_DATA *next = (*p)->next; - - (*p)->free_func((*p)->data); - OPENSSL_free(*p); - - *p = next; - return; - } - } -} - -/* this has 'package' visibility */ -void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)) -{ - EC_EXTRA_DATA **p; - - if (ex_data == NULL) - return; - - for (p = ex_data; *p != NULL; p = &((*p)->next)) { - if ((*p)->dup_func == dup_func && (*p)->free_func == free_func - && (*p)->clear_free_func == clear_free_func) { - EC_EXTRA_DATA *next = (*p)->next; - - (*p)->clear_free_func((*p)->data); - OPENSSL_free(*p); - - *p = next; - return; - } - } -} - -/* this has 'package' visibility */ -void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data) -{ - EC_EXTRA_DATA *d; - - if (ex_data == NULL) - return; - - d = *ex_data; - while (d) { - EC_EXTRA_DATA *next = d->next; - - d->free_func(d->data); - OPENSSL_free(d); - - d = next; - } - *ex_data = NULL; -} - -/* this has 'package' visibility */ -void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data) -{ - EC_EXTRA_DATA *d; - - if (ex_data == NULL) - return; - - d = *ex_data; - while (d) { - EC_EXTRA_DATA *next = d->next; - - d->clear_free_func(d->data); - OPENSSL_free(d); - - d = next; - } - *ex_data = NULL; -} - -/* functions for EC_POINT objects */ - -EC_POINT *EC_POINT_new(const EC_GROUP *group) -{ - EC_POINT *ret; - - if (group == NULL) { - ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - if (group->meth->point_init == 0) { - ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return NULL; - } - - ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - - ret->meth = group->meth; - - if (!ret->meth->point_init(ret)) { - OPENSSL_free(ret); - return NULL; - } - - return ret; -} - -void EC_POINT_free(EC_POINT *point) -{ - if (!point) - return; - - if (point->meth->point_finish != 0) - point->meth->point_finish(point); - OPENSSL_free(point); -} - -void EC_POINT_clear_free(EC_POINT *point) -{ - if (!point) - return; - - if (point->meth->point_clear_finish != 0) - point->meth->point_clear_finish(point); - else if (point->meth->point_finish != 0) - point->meth->point_finish(point); - OPENSSL_cleanse(point, sizeof(*point)); - OPENSSL_free(point); -} - -int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) -{ - if (dest->meth->point_copy == 0) { - ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (dest->meth != src->meth) { - ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - if (dest == src) - return 1; - return dest->meth->point_copy(dest, src); -} - -EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) -{ - EC_POINT *t; - int r; - - if (a == NULL) - return NULL; - - t = EC_POINT_new(group); - if (t == NULL) - return (NULL); - r = EC_POINT_copy(t, a); - if (!r) { - EC_POINT_free(t); - return NULL; - } else - return t; -} - -const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) -{ - return point->meth; -} - -int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) -{ - if (group->meth->point_set_to_infinity == 0) { - ECerr(EC_F_EC_POINT_SET_TO_INFINITY, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->point_set_to_infinity(group, point); -} - -int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, - EC_POINT *point, const BIGNUM *x, - const BIGNUM *y, const BIGNUM *z, - BN_CTX *ctx) -{ - if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { - ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, - EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, - y, z, ctx); -} - -int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, - const EC_POINT *point, BIGNUM *x, - BIGNUM *y, BIGNUM *z, - BN_CTX *ctx) -{ - if (group->meth->point_get_Jprojective_coordinates_GFp == 0) { - ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, - EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, - y, z, ctx); -} - -int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, - EC_POINT *point, const BIGNUM *x, - const BIGNUM *y, BN_CTX *ctx) -{ - if (group->meth->point_set_affine_coordinates == 0) { - ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, - EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); -} - -#ifndef OPENSSL_NO_EC2M -int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, - EC_POINT *point, const BIGNUM *x, - const BIGNUM *y, BN_CTX *ctx) -{ - if (group->meth->point_set_affine_coordinates == 0) { - ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, - EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); -} -#endif - -int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, - const EC_POINT *point, BIGNUM *x, - BIGNUM *y, BN_CTX *ctx) -{ - if (group->meth->point_get_affine_coordinates == 0) { - ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, - EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); -} - -#ifndef OPENSSL_NO_EC2M -int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, - const EC_POINT *point, BIGNUM *x, - BIGNUM *y, BN_CTX *ctx) -{ - if (group->meth->point_get_affine_coordinates == 0) { - ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, - EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); -} -#endif - -int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) -{ - if (group->meth->add == 0) { - ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if ((group->meth != r->meth) || (r->meth != a->meth) - || (a->meth != b->meth)) { - ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->add(group, r, a, b, ctx); -} - -int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - BN_CTX *ctx) -{ - if (group->meth->dbl == 0) { - ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if ((group->meth != r->meth) || (r->meth != a->meth)) { - ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->dbl(group, r, a, ctx); -} - -int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) -{ - if (group->meth->invert == 0) { - ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != a->meth) { - ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->invert(group, a, ctx); -} - -int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) -{ - if (group->meth->is_at_infinity == 0) { - ECerr(EC_F_EC_POINT_IS_AT_INFINITY, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->is_at_infinity(group, point); -} - -/* - * Check whether an EC_POINT is on the curve or not. Note that the return - * value for this function should NOT be treated as a boolean. Return values: - * 1: The point is on the curve - * 0: The point is not on the curve - * -1: An error occurred - */ -int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, - BN_CTX *ctx) -{ - if (group->meth->is_on_curve == 0) { - ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->is_on_curve(group, point, ctx); -} - -int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, - BN_CTX *ctx) -{ - if (group->meth->point_cmp == 0) { - ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return -1; - } - if ((group->meth != a->meth) || (a->meth != b->meth)) { - ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); - return -1; - } - return group->meth->point_cmp(group, a, b, ctx); -} - -int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) -{ - if (group->meth->make_affine == 0) { - ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - return group->meth->make_affine(group, point, ctx); -} - -int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, - EC_POINT *points[], BN_CTX *ctx) -{ - size_t i; - - if (group->meth->points_make_affine == 0) { - ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - for (i = 0; i < num; i++) { - if (group->meth != points[i]->meth) { - ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - } - return group->meth->points_make_affine(group, num, points, ctx); -} - -/* - * Functions for point multiplication. If group->meth->mul is 0, we use the - * wNAF-based implementations in ec_mult.c; otherwise we dispatch through - * methods. - */ - -int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) -{ - if (group->meth->mul == 0) - /* use default */ - return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); - - return group->meth->mul(group, r, scalar, num, points, scalars, ctx); -} - -int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, - const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) -{ - /* just a convenient interface to EC_POINTs_mul() */ - - const EC_POINT *points[1]; - const BIGNUM *scalars[1]; - - points[0] = point; - scalars[0] = p_scalar; - - return EC_POINTs_mul(group, r, g_scalar, - (point != NULL - && p_scalar != NULL), points, scalars, ctx); -} - -int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) -{ - if (group->meth->mul == 0) - /* use default */ - return ec_wNAF_precompute_mult(group, ctx); - - if (group->meth->precompute_mult != 0) - return group->meth->precompute_mult(group, ctx); - else - return 1; /* nothing to do, so report success */ -} - -int EC_GROUP_have_precompute_mult(const EC_GROUP *group) -{ - if (group->meth->mul == 0) - /* use default */ - return ec_wNAF_have_precompute_mult(group); - - if (group->meth->have_precompute_mult != 0) - return group->meth->have_precompute_mult(group); - else - return 0; /* cannot tell whether precomputation has - * been performed */ -} - -/*- - * ec_precompute_mont_data sets |group->mont_data| from |group->order| and - * returns one on success. On error it returns zero. - * - * Note: this function must be called only after verifying that - * EC_GROUP_VERSION(group) returns true. - * The reason for this is that access to the `mont_data` field of an EC_GROUP - * struct should always be guarded by an EC_GROUP_VERSION(group) check to avoid - * OOB accesses, as the group might come from the FIPS module, which does not - * define the `mont_data` field inside the EC_GROUP structure. - */ -static -int ec_precompute_mont_data(EC_GROUP *group) -{ - BN_CTX *ctx = BN_CTX_new(); - int ret = 0; - - if (group->mont_data) { - BN_MONT_CTX_free(group->mont_data); - group->mont_data = NULL; - } - - if (ctx == NULL) - goto err; - - group->mont_data = BN_MONT_CTX_new(); - if (!group->mont_data) - goto err; - - if (!BN_MONT_CTX_set(group->mont_data, &group->order, ctx)) { - BN_MONT_CTX_free(group->mont_data); - group->mont_data = NULL; - goto err; - } - - ret = 1; - - err: - - if (ctx) - BN_CTX_free(ctx); - return ret; -} -/* crypto/ec/ec_mult.c */ -/* - * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Portions of this software developed by SUN MICROSYSTEMS, INC., - * and contributed to the OpenSSL project. - */ - -#include - -// #include "err.h" - -// #include "ec_lcl.h" - -/* - * This file implements the wNAF-based interleaving multi-exponentiation method - * Formerly at: - * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp - * You might now find it here: - * http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13 - * http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf - * For multiplication with precomputation, we use wNAF splitting, formerly at: - * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp - */ - -/* structure for precomputed multiples of the generator */ -typedef struct ec_pre_comp_st { - const EC_GROUP *group; /* parent EC_GROUP object */ - size_t blocksize; /* block size for wNAF splitting */ - size_t numblocks; /* max. number of blocks for which we have - * precomputation */ - size_t w; /* window size */ - EC_POINT **points; /* array with pre-calculated multiples of - * generator: 'num' pointers to EC_POINT - * objects followed by a NULL */ - size_t num; /* numblocks * 2^(w-1) */ - int references; -} EC_PRE_COMP; - -/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */ -static void *ec_pre_comp_dup(void *); -static void ec_pre_comp_free(void *); -static void ec_pre_comp_clear_free(void *); - -static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) -{ - EC_PRE_COMP *ret = NULL; - - if (!group) - return NULL; - - ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP)); - if (!ret) { - ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); - return ret; - } - ret->group = group; - ret->blocksize = 8; /* default */ - ret->numblocks = 0; - ret->w = 4; /* default */ - ret->points = NULL; - ret->num = 0; - ret->references = 1; - return ret; -} - -static void *ec_pre_comp_dup(void *src_) -{ - EC_PRE_COMP *src = src_; - - /* no need to actually copy, these objects never change! */ - - CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); - - return src_; -} - -static void ec_pre_comp_free(void *pre_) -{ - int i; - EC_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - if (pre->points) { - EC_POINT **p; - - for (p = pre->points; *p != NULL; p++) - EC_POINT_free(*p); - OPENSSL_free(pre->points); - } - OPENSSL_free(pre); -} - -static void ec_pre_comp_clear_free(void *pre_) -{ - int i; - EC_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - if (pre->points) { - EC_POINT **p; - - for (p = pre->points; *p != NULL; p++) { - EC_POINT_clear_free(*p); - OPENSSL_cleanse(p, sizeof(*p)); - } - OPENSSL_free(pre->points); - } - OPENSSL_cleanse(pre, sizeof(*pre)); - OPENSSL_free(pre); -} - -/*- - * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. - * This is an array r[] of values that are either zero or odd with an - * absolute value less than 2^w satisfying - * scalar = \sum_j r[j]*2^j - * where at most one of any w+1 consecutive digits is non-zero - * with the exception that the most significant digit may be only - * w-1 zeros away from that next non-zero digit. - */ -static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) -{ - int window_val; - int ok = 0; - signed char *r = NULL; - int sign = 1; - int bit, next_bit, mask; - size_t len = 0, j; - - if (BN_is_zero(scalar)) { - r = OPENSSL_malloc(1); - if (!r) { - ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); - goto err; - } - r[0] = 0; - *ret_len = 1; - return r; - } - - if (w <= 0 || w > 7) { /* 'signed char' can represent integers with - * absolute values less than 2^7 */ - ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); - goto err; - } - bit = 1 << w; /* at most 128 */ - next_bit = bit << 1; /* at most 256 */ - mask = next_bit - 1; /* at most 255 */ - - if (BN_is_negative(scalar)) { - sign = -1; - } - - if (scalar->d == NULL || scalar->top == 0) { - ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); - goto err; - } - - len = BN_num_bits(scalar); - r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer - * than binary representation (*ret_len will - * be set to the actual length, i.e. at most - * BN_num_bits(scalar) + 1) */ - if (r == NULL) { - ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); - goto err; - } - window_val = scalar->d[0] & mask; - j = 0; - while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len, - * window_val will not - * increase */ - int digit = 0; - - /* 0 <= window_val <= 2^(w+1) */ - - if (window_val & 1) { - /* 0 < window_val < 2^(w+1) */ - - if (window_val & bit) { - digit = window_val - next_bit; /* -2^w < digit < 0 */ - -#if 1 /* modified wNAF */ - if (j + w + 1 >= len) { - /* - * special case for generating modified wNAFs: no new - * bits will be added into window_val, so using a - * positive digit here will decrease the total length of - * the representation - */ - - digit = window_val & (mask >> 1); /* 0 < digit < 2^w */ - } -#endif - } else { - digit = window_val; /* 0 < digit < 2^w */ - } - - if (digit <= -bit || digit >= bit || !(digit & 1)) { - ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); - goto err; - } - - window_val -= digit; - - /* - * now window_val is 0 or 2^(w+1) in standard wNAF generation; - * for modified window NAFs, it may also be 2^w - */ - if (window_val != 0 && window_val != next_bit - && window_val != bit) { - ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - r[j++] = sign * digit; - - window_val >>= 1; - window_val += bit * BN_is_bit_set(scalar, j + w); - - if (window_val > next_bit) { - ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - if (j > len + 1) { - ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); - goto err; - } - len = j; - ok = 1; - - err: - if (!ok) { - OPENSSL_free(r); - r = NULL; - } - if (ok) - *ret_len = len; - return r; -} - -#define EC_POINT_BN_set_flags(P, flags) do { \ - BN_set_flags(&(P)->X, (flags)); \ - BN_set_flags(&(P)->Y, (flags)); \ - BN_set_flags(&(P)->Z, (flags)); \ -} while(0) - -/*- - * This functions computes (in constant time) a point multiplication over the - * EC group. - * - * At a high level, it is Montgomery ladder with conditional swaps. - * - * It performs either a fixed scalar point multiplication - * (scalar * generator) - * when point is NULL, or a generic scalar point multiplication - * (scalar * point) - * when point is not NULL. - * - * scalar should be in the range [0,n) otherwise all constant time bets are off. - * - * NB: This says nothing about EC_POINT_add and EC_POINT_dbl, - * which of course are not constant time themselves. - * - * The product is stored in r. - * - * Returns 1 on success, 0 otherwise. - */ -static int ec_mul_consttime(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, const EC_POINT *point, - BN_CTX *ctx) -{ - int i, cardinality_bits, group_top, kbit, pbit, Z_is_one; - EC_POINT *s = NULL; - BIGNUM *k = NULL; - BIGNUM *lambda = NULL; - BIGNUM *cardinality = NULL; - BN_CTX *new_ctx = NULL; - int ret = 0; - - if (ctx == NULL && (ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - - BN_CTX_start(ctx); - - s = EC_POINT_new(group); - if (s == NULL) - goto err; - - if (point == NULL) { - if (!EC_POINT_copy(s, group->generator)) - goto err; - } else { - if (!EC_POINT_copy(s, point)) - goto err; - } - - EC_POINT_BN_set_flags(s, BN_FLG_CONSTTIME); - - cardinality = BN_CTX_get(ctx); - lambda = BN_CTX_get(ctx); - k = BN_CTX_get(ctx); - if (k == NULL || !BN_mul(cardinality, &group->order, &group->cofactor, ctx)) - goto err; - - /* - * Group cardinalities are often on a word boundary. - * So when we pad the scalar, some timing diff might - * pop if it needs to be expanded due to carries. - * So expand ahead of time. - */ - cardinality_bits = BN_num_bits(cardinality); - group_top = cardinality->top; - if ((bn_wexpand(k, group_top + 2) == NULL) - || (bn_wexpand(lambda, group_top + 2) == NULL)) - goto err; - - if (!BN_copy(k, scalar)) - goto err; - - BN_set_flags(k, BN_FLG_CONSTTIME); - - if ((BN_num_bits(k) > cardinality_bits) || (BN_is_negative(k))) { - /*- - * this is an unusual input, and we don't guarantee - * constant-timeness - */ - if (!BN_nnmod(k, k, cardinality, ctx)) - goto err; - } - - if (!BN_add(lambda, k, cardinality)) - goto err; - BN_set_flags(lambda, BN_FLG_CONSTTIME); - if (!BN_add(k, lambda, cardinality)) - goto err; - /* - * lambda := scalar + cardinality - * k := scalar + 2*cardinality - */ - kbit = BN_is_bit_set(lambda, cardinality_bits); - BN_consttime_swap(kbit, k, lambda, group_top + 2); - - group_top = group->field.top; - if ((bn_wexpand(&s->X, group_top) == NULL) - || (bn_wexpand(&s->Y, group_top) == NULL) - || (bn_wexpand(&s->Z, group_top) == NULL) - || (bn_wexpand(&r->X, group_top) == NULL) - || (bn_wexpand(&r->Y, group_top) == NULL) - || (bn_wexpand(&r->Z, group_top) == NULL)) - goto err; - - /* top bit is a 1, in a fixed pos */ - if (!EC_POINT_copy(r, s)) - goto err; - - EC_POINT_BN_set_flags(r, BN_FLG_CONSTTIME); - - if (!EC_POINT_dbl(group, s, s, ctx)) - goto err; - - pbit = 0; - -#define EC_POINT_CSWAP(c, a, b, w, t) do { \ - BN_consttime_swap(c, &(a)->X, &(b)->X, w); \ - BN_consttime_swap(c, &(a)->Y, &(b)->Y, w); \ - BN_consttime_swap(c, &(a)->Z, &(b)->Z, w); \ - t = ((a)->Z_is_one ^ (b)->Z_is_one) & (c); \ - (a)->Z_is_one ^= (t); \ - (b)->Z_is_one ^= (t); \ -} while(0) - - /*- - * The ladder step, with branches, is - * - * k[i] == 0: S = add(R, S), R = dbl(R) - * k[i] == 1: R = add(S, R), S = dbl(S) - * - * Swapping R, S conditionally on k[i] leaves you with state - * - * k[i] == 0: T, U = R, S - * k[i] == 1: T, U = S, R - * - * Then perform the ECC ops. - * - * U = add(T, U) - * T = dbl(T) - * - * Which leaves you with state - * - * k[i] == 0: U = add(R, S), T = dbl(R) - * k[i] == 1: U = add(S, R), T = dbl(S) - * - * Swapping T, U conditionally on k[i] leaves you with state - * - * k[i] == 0: R, S = T, U - * k[i] == 1: R, S = U, T - * - * Which leaves you with state - * - * k[i] == 0: S = add(R, S), R = dbl(R) - * k[i] == 1: R = add(S, R), S = dbl(S) - * - * So we get the same logic, but instead of a branch it's a - * conditional swap, followed by ECC ops, then another conditional swap. - * - * Optimization: The end of iteration i and start of i-1 looks like - * - * ... - * CSWAP(k[i], R, S) - * ECC - * CSWAP(k[i], R, S) - * (next iteration) - * CSWAP(k[i-1], R, S) - * ECC - * CSWAP(k[i-1], R, S) - * ... - * - * So instead of two contiguous swaps, you can merge the condition - * bits and do a single swap. - * - * k[i] k[i-1] Outcome - * 0 0 No Swap - * 0 1 Swap - * 1 0 Swap - * 1 1 No Swap - * - * This is XOR. pbit tracks the previous bit of k. - */ - - for (i = cardinality_bits - 1; i >= 0; i--) { - kbit = BN_is_bit_set(k, i) ^ pbit; - EC_POINT_CSWAP(kbit, r, s, group_top, Z_is_one); - if (!EC_POINT_add(group, s, r, s, ctx)) - goto err; - if (!EC_POINT_dbl(group, r, r, ctx)) - goto err; - /* - * pbit logic merges this cswap with that of the - * next iteration - */ - pbit ^= kbit; - } - /* one final cswap to move the right value into r */ - EC_POINT_CSWAP(pbit, r, s, group_top, Z_is_one); -#undef EC_POINT_CSWAP - - ret = 1; - - err: - EC_POINT_free(s); - BN_CTX_end(ctx); - BN_CTX_free(new_ctx); - - return ret; -} - -#undef EC_POINT_BN_set_flags - -/* - * TODO: table should be optimised for the wNAF-based implementation, - * sometimes smaller windows will give better performance (thus the - * boundaries should be increased) - */ -#define EC_window_bits_for_scalar_size(b) \ - ((size_t) \ - ((b) >= 2000 ? 6 : \ - (b) >= 800 ? 5 : \ - (b) >= 300 ? 4 : \ - (b) >= 70 ? 3 : \ - (b) >= 20 ? 2 : \ - 1)) - -/*- - * Compute - * \sum scalars[i]*points[i], - * also including - * scalar*generator - * in the addition if scalar != NULL - */ -int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - const EC_POINT *generator = NULL; - EC_POINT *tmp = NULL; - size_t totalnum; - size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ - size_t pre_points_per_block = 0; - size_t i, j; - int k; - int r_is_inverted = 0; - int r_is_at_infinity = 1; - size_t *wsize = NULL; /* individual window sizes */ - signed char **wNAF = NULL; /* individual wNAFs */ - size_t *wNAF_len = NULL; - size_t max_len = 0; - size_t num_val; - EC_POINT **val = NULL; /* precomputation */ - EC_POINT **v; - EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or - * 'pre_comp->points' */ - const EC_PRE_COMP *pre_comp = NULL; - int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be - * treated like other scalars, i.e. - * precomputation is not available */ - int ret = 0; - - if (group->meth != r->meth) { - ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - - if ((scalar == NULL) && (num == 0)) { - return EC_POINT_set_to_infinity(group, r); - } - - if (!BN_is_zero(&group->order) && !BN_is_zero(&group->cofactor)) { - /*- - * Handle the common cases where the scalar is secret, enforcing a constant - * time scalar multiplication algorithm. - */ - if ((scalar != NULL) && (num == 0)) { - /*- - * In this case we want to compute scalar * GeneratorPoint: this - * codepath is reached most prominently by (ephemeral) key generation - * of EC cryptosystems (i.e. ECDSA keygen and sign setup, ECDH - * keygen/first half), where the scalar is always secret. This is why - * we ignore if BN_FLG_CONSTTIME is actually set and we always call the - * constant time version. - */ - return ec_mul_consttime(group, r, scalar, NULL, ctx); - } - if ((scalar == NULL) && (num == 1)) { - /*- - * In this case we want to compute scalar * GenericPoint: this codepath - * is reached most prominently by the second half of ECDH, where the - * secret scalar is multiplied by the peer's public point. To protect - * the secret scalar, we ignore if BN_FLG_CONSTTIME is actually set and - * we always call the constant time version. - */ - return ec_mul_consttime(group, r, scalars[0], points[0], ctx); - } - } - - for (i = 0; i < num; i++) { - if (group->meth != points[i]->meth) { - ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - } - - if (scalar != NULL) { - generator = EC_GROUP_get0_generator(group); - if (generator == NULL) { - ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR); - goto err; - } - - /* look if we can use precomputed multiples of generator */ - - pre_comp = - EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, - ec_pre_comp_free, ec_pre_comp_clear_free); - - if (pre_comp && pre_comp->numblocks - && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == - 0)) { - blocksize = pre_comp->blocksize; - - /* - * determine maximum number of blocks that wNAF splitting may - * yield (NB: maximum wNAF length is bit length plus one) - */ - numblocks = (BN_num_bits(scalar) / blocksize) + 1; - - /* - * we cannot use more blocks than we have precomputation for - */ - if (numblocks > pre_comp->numblocks) - numblocks = pre_comp->numblocks; - - pre_points_per_block = (size_t)1 << (pre_comp->w - 1); - - /* check that pre_comp looks sane */ - if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); - goto err; - } - } else { - /* can't use precomputation */ - pre_comp = NULL; - numblocks = 1; - num_scalar = 1; /* treat 'scalar' like 'num'-th element of - * 'scalars' */ - } - } - - totalnum = num + numblocks; - - wsize = OPENSSL_malloc(totalnum * sizeof(wsize[0])); - wNAF_len = OPENSSL_malloc(totalnum * sizeof(wNAF_len[0])); - /* include space for pivot */ - wNAF = OPENSSL_malloc((totalnum + 1) * sizeof(wNAF[0])); - val_sub = OPENSSL_malloc(totalnum * sizeof(val_sub[0])); - - /* Ensure wNAF is initialised in case we end up going to err */ - if (wNAF) - wNAF[0] = NULL; /* preliminary pivot */ - - if (!wsize || !wNAF_len || !wNAF || !val_sub) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * num_val will be the total number of temporarily precomputed points - */ - num_val = 0; - - for (i = 0; i < num + num_scalar; i++) { - size_t bits; - - bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); - wsize[i] = EC_window_bits_for_scalar_size(bits); - num_val += (size_t)1 << (wsize[i] - 1); - wNAF[i + 1] = NULL; /* make sure we always have a pivot */ - wNAF[i] = - compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], - &wNAF_len[i]); - if (wNAF[i] == NULL) - goto err; - if (wNAF_len[i] > max_len) - max_len = wNAF_len[i]; - } - - if (numblocks) { - /* we go here iff scalar != NULL */ - - if (pre_comp == NULL) { - if (num_scalar != 1) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); - goto err; - } - /* we have already generated a wNAF for 'scalar' */ - } else { - signed char *tmp_wNAF = NULL; - size_t tmp_len = 0; - - if (num_scalar != 0) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); - goto err; - } - - /* - * use the window size for which we have precomputation - */ - wsize[num] = pre_comp->w; - tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len); - if (!tmp_wNAF) - goto err; - - if (tmp_len <= max_len) { - /* - * One of the other wNAFs is at least as long as the wNAF - * belonging to the generator, so wNAF splitting will not buy - * us anything. - */ - - numblocks = 1; - totalnum = num + 1; /* don't use wNAF splitting */ - wNAF[num] = tmp_wNAF; - wNAF[num + 1] = NULL; - wNAF_len[num] = tmp_len; - if (tmp_len > max_len) - max_len = tmp_len; - /* - * pre_comp->points starts with the points that we need here: - */ - val_sub[num] = pre_comp->points; - } else { - /* - * don't include tmp_wNAF directly into wNAF array - use wNAF - * splitting and include the blocks - */ - - signed char *pp; - EC_POINT **tmp_points; - - if (tmp_len < numblocks * blocksize) { - /* - * possibly we can do with fewer blocks than estimated - */ - numblocks = (tmp_len + blocksize - 1) / blocksize; - if (numblocks > pre_comp->numblocks) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); - goto err; - } - totalnum = num + numblocks; - } - - /* split wNAF in 'numblocks' parts */ - pp = tmp_wNAF; - tmp_points = pre_comp->points; - - for (i = num; i < totalnum; i++) { - if (i < totalnum - 1) { - wNAF_len[i] = blocksize; - if (tmp_len < blocksize) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); - goto err; - } - tmp_len -= blocksize; - } else - /* - * last block gets whatever is left (this could be - * more or less than 'blocksize'!) - */ - wNAF_len[i] = tmp_len; - - wNAF[i + 1] = NULL; - wNAF[i] = OPENSSL_malloc(wNAF_len[i]); - if (wNAF[i] == NULL) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); - OPENSSL_free(tmp_wNAF); - goto err; - } - memcpy(wNAF[i], pp, wNAF_len[i]); - if (wNAF_len[i] > max_len) - max_len = wNAF_len[i]; - - if (*tmp_points == NULL) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); - OPENSSL_free(tmp_wNAF); - goto err; - } - val_sub[i] = tmp_points; - tmp_points += pre_points_per_block; - pp += blocksize; - } - OPENSSL_free(tmp_wNAF); - } - } - } - - /* - * All points we precompute now go into a single array 'val'. - * 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a - * subarray of 'pre_comp->points' if we already have precomputation. - */ - val = OPENSSL_malloc((num_val + 1) * sizeof(val[0])); - if (val == NULL) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); - goto err; - } - val[num_val] = NULL; /* pivot element */ - - /* allocate points for precomputation */ - v = val; - for (i = 0; i < num + num_scalar; i++) { - val_sub[i] = v; - for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) { - *v = EC_POINT_new(group); - if (*v == NULL) - goto err; - v++; - } - } - if (!(v == val + num_val)) { - ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!(tmp = EC_POINT_new(group))) - goto err; - - /*- - * prepare precomputed values: - * val_sub[i][0] := points[i] - * val_sub[i][1] := 3 * points[i] - * val_sub[i][2] := 5 * points[i] - * ... - */ - for (i = 0; i < num + num_scalar; i++) { - if (i < num) { - if (!EC_POINT_copy(val_sub[i][0], points[i])) - goto err; - } else { - if (!EC_POINT_copy(val_sub[i][0], generator)) - goto err; - } - - if (wsize[i] > 1) { - if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) - goto err; - for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) { - if (!EC_POINT_add - (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) - goto err; - } - } - } - -#if 1 /* optional; EC_window_bits_for_scalar_size - * assumes we do this step */ - if (!EC_POINTs_make_affine(group, num_val, val, ctx)) - goto err; -#endif - - r_is_at_infinity = 1; - - for (k = max_len - 1; k >= 0; k--) { - if (!r_is_at_infinity) { - if (!EC_POINT_dbl(group, r, r, ctx)) - goto err; - } - - for (i = 0; i < totalnum; i++) { - if (wNAF_len[i] > (size_t)k) { - int digit = wNAF[i][k]; - int is_neg; - - if (digit) { - is_neg = digit < 0; - - if (is_neg) - digit = -digit; - - if (is_neg != r_is_inverted) { - if (!r_is_at_infinity) { - if (!EC_POINT_invert(group, r, ctx)) - goto err; - } - r_is_inverted = !r_is_inverted; - } - - /* digit > 0 */ - - if (r_is_at_infinity) { - if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) - goto err; - r_is_at_infinity = 0; - } else { - if (!EC_POINT_add - (group, r, r, val_sub[i][digit >> 1], ctx)) - goto err; - } - } - } - } - } - - if (r_is_at_infinity) { - if (!EC_POINT_set_to_infinity(group, r)) - goto err; - } else { - if (r_is_inverted) - if (!EC_POINT_invert(group, r, ctx)) - goto err; - } - - ret = 1; - - err: - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (tmp != NULL) - EC_POINT_free(tmp); - if (wsize != NULL) - OPENSSL_free(wsize); - if (wNAF_len != NULL) - OPENSSL_free(wNAF_len); - if (wNAF != NULL) { - signed char **w; - - for (w = wNAF; *w != NULL; w++) - OPENSSL_free(*w); - - OPENSSL_free(wNAF); - } - if (val != NULL) { - for (v = val; *v != NULL; v++) - EC_POINT_clear_free(*v); - - OPENSSL_free(val); - } - if (val_sub != NULL) { - OPENSSL_free(val_sub); - } - return ret; -} - -/*- - * ec_wNAF_precompute_mult() - * creates an EC_PRE_COMP object with preprecomputed multiples of the generator - * for use with wNAF splitting as implemented in ec_wNAF_mul(). - * - * 'pre_comp->points' is an array of multiples of the generator - * of the following form: - * points[0] = generator; - * points[1] = 3 * generator; - * ... - * points[2^(w-1)-1] = (2^(w-1)-1) * generator; - * points[2^(w-1)] = 2^blocksize * generator; - * points[2^(w-1)+1] = 3 * 2^blocksize * generator; - * ... - * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator - * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator - * ... - * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator - * points[2^(w-1)*numblocks] = NULL - */ -int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) -{ - const EC_POINT *generator; - EC_POINT *tmp_point = NULL, *base = NULL, **var; - BN_CTX *new_ctx = NULL; - BIGNUM *order; - size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; - EC_POINT **points = NULL; - EC_PRE_COMP *pre_comp; - int ret = 0; - - /* if there is an old EC_PRE_COMP object, throw it away */ - EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, - ec_pre_comp_free, ec_pre_comp_clear_free); - - if ((pre_comp = ec_pre_comp_new(group)) == NULL) - return 0; - - generator = EC_GROUP_get0_generator(group); - if (generator == NULL) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR); - goto err; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - } - - BN_CTX_start(ctx); - order = BN_CTX_get(ctx); - if (order == NULL) - goto err; - - if (!EC_GROUP_get_order(group, order, ctx)) - goto err; - if (BN_is_zero(order)) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); - goto err; - } - - bits = BN_num_bits(order); - /* - * The following parameters mean we precompute (approximately) one point - * per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other - * bit lengths, other parameter combinations might provide better - * efficiency. - */ - blocksize = 8; - w = 4; - if (EC_window_bits_for_scalar_size(bits) > w) { - /* let's not make the window too small ... */ - w = EC_window_bits_for_scalar_size(bits); - } - - numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks - * to use for wNAF - * splitting */ - - pre_points_per_block = (size_t)1 << (w - 1); - num = pre_points_per_block * numblocks; /* number of points to compute - * and store */ - - points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1)); - if (!points) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); - goto err; - } - - var = points; - var[num] = NULL; /* pivot */ - for (i = 0; i < num; i++) { - if ((var[i] = EC_POINT_new(group)) == NULL) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_POINT_copy(base, generator)) - goto err; - - /* do the precomputation */ - for (i = 0; i < numblocks; i++) { - size_t j; - - if (!EC_POINT_dbl(group, tmp_point, base, ctx)) - goto err; - - if (!EC_POINT_copy(*var++, base)) - goto err; - - for (j = 1; j < pre_points_per_block; j++, var++) { - /* - * calculate odd multiples of the current base point - */ - if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) - goto err; - } - - if (i < numblocks - 1) { - /* - * get the next base (multiply current one by 2^blocksize) - */ - size_t k; - - if (blocksize <= 2) { - ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!EC_POINT_dbl(group, base, tmp_point, ctx)) - goto err; - for (k = 2; k < blocksize; k++) { - if (!EC_POINT_dbl(group, base, base, ctx)) - goto err; - } - } - } - - if (!EC_POINTs_make_affine(group, num, points, ctx)) - goto err; - - pre_comp->group = group; - pre_comp->blocksize = blocksize; - pre_comp->numblocks = numblocks; - pre_comp->w = w; - pre_comp->points = points; - points = NULL; - pre_comp->num = num; - - if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp, - ec_pre_comp_dup, ec_pre_comp_free, - ec_pre_comp_clear_free)) - goto err; - pre_comp = NULL; - - ret = 1; - err: - if (ctx != NULL) - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (pre_comp) - ec_pre_comp_free(pre_comp); - if (points) { - EC_POINT **p; - - for (p = points; *p != NULL; p++) - EC_POINT_free(*p); - OPENSSL_free(points); - } - if (tmp_point) - EC_POINT_free(tmp_point); - if (base) - EC_POINT_free(base); - return ret; -} - -int ec_wNAF_have_precompute_mult(const EC_GROUP *group) -{ - if (EC_EX_DATA_get_data - (group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, - ec_pre_comp_clear_free) != NULL) - return 1; - else - return 0; -} -/* crypto/ec/ec_lib.c */ -/* - * Originally written by Bodo Moeller for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Binary polynomial ECC support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include - -// #include "err.h" -// #include "opensslv.h" - -// #include "ec_lcl.h" - -int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, - EC_POINT *point, const BIGNUM *x, - int y_bit, BN_CTX *ctx) -{ - if (group->meth->point_set_compressed_coordinates == 0 - && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { - ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, - EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { - if (group->meth->field_type == NID_X9_62_prime_field) - return ec_GFp_simple_set_compressed_coordinates(group, point, x, - y_bit, ctx); - else -#ifdef OPENSSL_NO_EC2M - { - ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, - EC_R_GF2M_NOT_SUPPORTED); - return 0; - } -#else - return ec_GF2m_simple_set_compressed_coordinates(group, point, x, - y_bit, ctx); -#endif - } - return group->meth->point_set_compressed_coordinates(group, point, x, - y_bit, ctx); -} - -#ifndef OPENSSL_NO_EC2M -int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, - EC_POINT *point, const BIGNUM *x, - int y_bit, BN_CTX *ctx) -{ - if (group->meth->point_set_compressed_coordinates == 0 - && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { - ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, - EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { - if (group->meth->field_type == NID_X9_62_prime_field) - return ec_GFp_simple_set_compressed_coordinates(group, point, x, - y_bit, ctx); - else - return ec_GF2m_simple_set_compressed_coordinates(group, point, x, - y_bit, ctx); - } - return group->meth->point_set_compressed_coordinates(group, point, x, - y_bit, ctx); -} -#endif - -size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, - point_conversion_form_t form, unsigned char *buf, - size_t len, BN_CTX *ctx) -{ - if (group->meth->point2oct == 0 - && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { - ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { - if (group->meth->field_type == NID_X9_62_prime_field) - return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); - else -#ifdef OPENSSL_NO_EC2M - { - ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED); - return 0; - } -#else - return ec_GF2m_simple_point2oct(group, point, - form, buf, len, ctx); -#endif - } - - return group->meth->point2oct(group, point, form, buf, len, ctx); -} - -int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, - const unsigned char *buf, size_t len, BN_CTX *ctx) -{ - if (group->meth->oct2point == 0 - && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { - ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - if (group->meth != point->meth) { - ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); - return 0; - } - if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { - if (group->meth->field_type == NID_X9_62_prime_field) - return ec_GFp_simple_oct2point(group, point, buf, len, ctx); - else -#ifdef OPENSSL_NO_EC2M - { - ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED); - return 0; - } -#else - return ec_GF2m_simple_oct2point(group, point, buf, len, ctx); -#endif - } - return group->meth->oct2point(group, point, buf, len, ctx); -} -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" -// #include "ec.h" -// #include "ec_lcl.h" -#include "ecdsa.h" -#include "evp.h" -#include "evp_locl.h" - -/* EC pkey context structure */ - -typedef struct { - /* Key and paramgen group */ - EC_GROUP *gen_group; - /* message digest */ - const EVP_MD *md; - /* Duplicate key if custom cofactor needed */ - EC_KEY *co_key; - /* Cofactor mode */ - signed char cofactor_mode; - /* KDF (if any) to use for ECDH */ - char kdf_type; - /* Message digest to use for key derivation */ - const EVP_MD *kdf_md; - /* User key material */ - unsigned char *kdf_ukm; - size_t kdf_ukmlen; - /* KDF output length */ - size_t kdf_outlen; -} EC_PKEY_CTX; - -static int pkey_ec_init(EVP_PKEY_CTX *ctx) -{ - EC_PKEY_CTX *dctx; - dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); - if (!dctx) - return 0; - dctx->gen_group = NULL; - dctx->md = NULL; - - dctx->cofactor_mode = -1; - dctx->co_key = NULL; - dctx->kdf_type = EVP_PKEY_ECDH_KDF_NONE; - dctx->kdf_md = NULL; - dctx->kdf_outlen = 0; - dctx->kdf_ukm = NULL; - dctx->kdf_ukmlen = 0; - - ctx->data = dctx; - - return 1; -} - -static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - EC_PKEY_CTX *dctx, *sctx; - if (!pkey_ec_init(dst)) - return 0; - sctx = src->data; - dctx = dst->data; - if (sctx->gen_group) { - dctx->gen_group = EC_GROUP_dup(sctx->gen_group); - if (!dctx->gen_group) - return 0; - } - dctx->md = sctx->md; - - if (sctx->co_key) { - dctx->co_key = EC_KEY_dup(sctx->co_key); - if (!dctx->co_key) - return 0; - } - dctx->kdf_type = sctx->kdf_type; - dctx->kdf_md = sctx->kdf_md; - dctx->kdf_outlen = sctx->kdf_outlen; - if (sctx->kdf_ukm) { - dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen); - if (!dctx->kdf_ukm) - return 0; - } else - dctx->kdf_ukm = NULL; - dctx->kdf_ukmlen = sctx->kdf_ukmlen; - return 1; -} - -static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) -{ - EC_PKEY_CTX *dctx = ctx->data; - if (dctx) { - if (dctx->gen_group) - EC_GROUP_free(dctx->gen_group); - if (dctx->co_key) - EC_KEY_free(dctx->co_key); - if (dctx->kdf_ukm) - OPENSSL_free(dctx->kdf_ukm); - OPENSSL_free(dctx); - } -} - -static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbslen) -{ - int ret, type; - unsigned int sltmp; - EC_PKEY_CTX *dctx = ctx->data; - EC_KEY *ec = ctx->pkey->pkey.ec; - - if (!sig) { - *siglen = ECDSA_size(ec); - return 1; - } else if (*siglen < (size_t)ECDSA_size(ec)) { - ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); - return 0; - } - - if (dctx->md) - type = EVP_MD_type(dctx->md); - else - type = NID_sha1; - - ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); - - if (ret <= 0) - return ret; - *siglen = (size_t)sltmp; - return 1; -} - -static int pkey_ec_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) -{ - int ret, type; - EC_PKEY_CTX *dctx = ctx->data; - EC_KEY *ec = ctx->pkey->pkey.ec; - - if (dctx->md) - type = EVP_MD_type(dctx->md); - else - type = NID_sha1; - - ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); - - return ret; -} - -#ifndef OPENSSL_NO_ECDH -static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) -{ - int ret; - size_t outlen; - const EC_POINT *pubkey = NULL; - EC_KEY *eckey; - EC_PKEY_CTX *dctx = ctx->data; - if (!ctx->pkey || !ctx->peerkey) { - ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET); - return 0; - } - - eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec; - - if (!key) { - const EC_GROUP *group; - group = EC_KEY_get0_group(eckey); - *keylen = (EC_GROUP_get_degree(group) + 7) / 8; - return 1; - } - pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); - - /* - * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not - * an error, the result is truncated. - */ - - outlen = *keylen; - - ret = ECDH_compute_key(key, outlen, pubkey, eckey, 0); - if (ret <= 0) - return 0; - *keylen = ret; - return 1; -} - -static int pkey_ec_kdf_derive(EVP_PKEY_CTX *ctx, - unsigned char *key, size_t *keylen) -{ - EC_PKEY_CTX *dctx = ctx->data; - unsigned char *ktmp = NULL; - size_t ktmplen; - int rv = 0; - if (dctx->kdf_type == EVP_PKEY_ECDH_KDF_NONE) - return pkey_ec_derive(ctx, key, keylen); - if (!key) { - *keylen = dctx->kdf_outlen; - return 1; - } - if (*keylen != dctx->kdf_outlen) - return 0; - if (!pkey_ec_derive(ctx, NULL, &ktmplen)) - return 0; - ktmp = OPENSSL_malloc(ktmplen); - if (!ktmp) - return 0; - if (!pkey_ec_derive(ctx, ktmp, &ktmplen)) - goto err; - /* Do KDF stuff */ - if (!ECDH_KDF_X9_62(key, *keylen, ktmp, ktmplen, - dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md)) - goto err; - rv = 1; - - err: - if (ktmp) { - OPENSSL_cleanse(ktmp, ktmplen); - OPENSSL_free(ktmp); - } - return rv; -} -#endif - -static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - EC_PKEY_CTX *dctx = ctx->data; - EC_GROUP *group; - switch (type) { - case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: - group = EC_GROUP_new_by_curve_name(p1); - if (group == NULL) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); - return 0; - } - if (dctx->gen_group) - EC_GROUP_free(dctx->gen_group); - dctx->gen_group = group; - return 1; - - case EVP_PKEY_CTRL_EC_PARAM_ENC: - if (!dctx->gen_group) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_NO_PARAMETERS_SET); - return 0; - } - EC_GROUP_set_asn1_flag(dctx->gen_group, p1); - return 1; - -#ifndef OPENSSL_NO_ECDH - case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: - if (p1 == -2) { - if (dctx->cofactor_mode != -1) - return dctx->cofactor_mode; - else { - EC_KEY *ec_key = ctx->pkey->pkey.ec; - return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : - 0; - } - } else if (p1 < -1 || p1 > 1) - return -2; - dctx->cofactor_mode = p1; - if (p1 != -1) { - EC_KEY *ec_key = ctx->pkey->pkey.ec; - if (!ec_key->group) - return -2; - /* If cofactor is 1 cofactor mode does nothing */ - if (BN_is_one(&ec_key->group->cofactor)) - return 1; - if (!dctx->co_key) { - dctx->co_key = EC_KEY_dup(ec_key); - if (!dctx->co_key) - return 0; - } - if (p1) - EC_KEY_set_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); - else - EC_KEY_clear_flags(dctx->co_key, EC_FLAG_COFACTOR_ECDH); - } else if (dctx->co_key) { - EC_KEY_free(dctx->co_key); - dctx->co_key = NULL; - } - return 1; -#endif - - case EVP_PKEY_CTRL_EC_KDF_TYPE: - if (p1 == -2) - return dctx->kdf_type; - if (p1 != EVP_PKEY_ECDH_KDF_NONE && p1 != EVP_PKEY_ECDH_KDF_X9_62) - return -2; - dctx->kdf_type = p1; - return 1; - - case EVP_PKEY_CTRL_EC_KDF_MD: - dctx->kdf_md = p2; - return 1; - - case EVP_PKEY_CTRL_GET_EC_KDF_MD: - *(const EVP_MD **)p2 = dctx->kdf_md; - return 1; - - case EVP_PKEY_CTRL_EC_KDF_OUTLEN: - if (p1 <= 0) - return -2; - dctx->kdf_outlen = (size_t)p1; - return 1; - - case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: - *(int *)p2 = dctx->kdf_outlen; - return 1; - - case EVP_PKEY_CTRL_EC_KDF_UKM: - if (dctx->kdf_ukm) - OPENSSL_free(dctx->kdf_ukm); - dctx->kdf_ukm = p2; - if (p2) - dctx->kdf_ukmlen = p1; - else - dctx->kdf_ukmlen = 0; - return 1; - - case EVP_PKEY_CTRL_GET_EC_KDF_UKM: - *(unsigned char **)p2 = dctx->kdf_ukm; - return dctx->kdf_ukmlen; - - case EVP_PKEY_CTRL_MD: - if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && - EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && - EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { - ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); - return 0; - } - dctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_GET_MD: - *(const EVP_MD **)p2 = dctx->md; - return 1; - - case EVP_PKEY_CTRL_PEER_KEY: - /* Default behaviour is OK */ - case EVP_PKEY_CTRL_DIGESTINIT: - case EVP_PKEY_CTRL_PKCS7_SIGN: - case EVP_PKEY_CTRL_CMS_SIGN: - return 1; - - default: - return -2; - - } -} - -static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!strcmp(type, "ec_paramgen_curve")) { - int nid; - nid = EC_curve_nist2nid(value); - if (nid == NID_undef) - nid = OBJ_sn2nid(value); - if (nid == NID_undef) - nid = OBJ_ln2nid(value); - if (nid == NID_undef) { - ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); - return 0; - } - return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); - } else if (!strcmp(type, "ec_param_enc")) { - int param_enc; - if (!strcmp(value, "explicit")) - param_enc = 0; - else if (!strcmp(value, "named_curve")) - param_enc = OPENSSL_EC_NAMED_CURVE; - else - return -2; - return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc); - } else if (!strcmp(type, "ecdh_kdf_md")) { - const EVP_MD *md; - if (!(md = EVP_get_digestbyname(value))) { - ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_DIGEST); - return 0; - } - return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, md); - } else if (!strcmp(type, "ecdh_cofactor_mode")) { - int co_mode; - co_mode = atoi(value); - return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, co_mode); - } - - return -2; -} - -static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - EC_KEY *ec = NULL; - EC_PKEY_CTX *dctx = ctx->data; - int ret = 0; - if (dctx->gen_group == NULL) { - ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); - return 0; - } - ec = EC_KEY_new(); - if (!ec) - return 0; - ret = EC_KEY_set_group(ec, dctx->gen_group); - if (ret) - EVP_PKEY_assign_EC_KEY(pkey, ec); - else - EC_KEY_free(ec); - return ret; -} - -static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - EC_KEY *ec = NULL; - EC_PKEY_CTX *dctx = ctx->data; - if (ctx->pkey == NULL && dctx->gen_group == NULL) { - ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); - return 0; - } - ec = EC_KEY_new(); - if (!ec) - return 0; - EVP_PKEY_assign_EC_KEY(pkey, ec); - if (ctx->pkey) { - /* Note: if error return, pkey is freed by parent routine */ - if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) - return 0; - } else { - if (!EC_KEY_set_group(ec, dctx->gen_group)) - return 0; - } - return EC_KEY_generate_key(pkey->pkey.ec); -} - -const EVP_PKEY_METHOD ec_pkey_meth = { - EVP_PKEY_EC, - 0, - pkey_ec_init, - pkey_ec_copy, - pkey_ec_cleanup, - - 0, - pkey_ec_paramgen, - - 0, - pkey_ec_keygen, - - 0, - pkey_ec_sign, - - 0, - pkey_ec_verify, - - 0, 0, - - 0, 0, 0, 0, - - 0, 0, - - 0, 0, - - 0, -#ifndef OPENSSL_NO_ECDH - pkey_ec_kdf_derive, -#else - 0, -#endif - - pkey_ec_ctrl, - pkey_ec_ctrl_str -}; -/* crypto/ec/ec_print.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "crypto.h" -// #include "ec_lcl.h" - -BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, - const EC_POINT *point, - point_conversion_form_t form, - BIGNUM *ret, BN_CTX *ctx) -{ - size_t buf_len = 0; - unsigned char *buf; - - buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); - if (buf_len == 0) - return NULL; - - if ((buf = OPENSSL_malloc(buf_len)) == NULL) - return NULL; - - if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { - OPENSSL_free(buf); - return NULL; - } - - ret = BN_bin2bn(buf, buf_len, ret); - - OPENSSL_free(buf); - - return ret; -} - -EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, - const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx) -{ - size_t buf_len = 0; - unsigned char *buf; - EC_POINT *ret; - - if ((buf_len = BN_num_bytes(bn)) == 0) - return NULL; - buf = OPENSSL_malloc(buf_len); - if (buf == NULL) - return NULL; - - if (!BN_bn2bin(bn, buf)) { - OPENSSL_free(buf); - return NULL; - } - - if (point == NULL) { - if ((ret = EC_POINT_new(group)) == NULL) { - OPENSSL_free(buf); - return NULL; - } - } else - ret = point; - - if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) { - if (point == NULL) - EC_POINT_clear_free(ret); - OPENSSL_free(buf); - return NULL; - } - - OPENSSL_free(buf); - return ret; -} - -static const char *HEX_DIGITS = "0123456789ABCDEF"; - -/* the return value must be freed (using OPENSSL_free()) */ -char *EC_POINT_point2hex(const EC_GROUP *group, - const EC_POINT *point, - point_conversion_form_t form, BN_CTX *ctx) -{ - char *ret, *p; - size_t buf_len = 0, i; - unsigned char *buf, *pbuf; - - buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); - if (buf_len == 0) - return NULL; - - if ((buf = OPENSSL_malloc(buf_len)) == NULL) - return NULL; - - if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { - OPENSSL_free(buf); - return NULL; - } - - ret = (char *)OPENSSL_malloc(buf_len * 2 + 2); - if (ret == NULL) { - OPENSSL_free(buf); - return NULL; - } - p = ret; - pbuf = buf; - for (i = buf_len; i > 0; i--) { - int v = (int)*(pbuf++); - *(p++) = HEX_DIGITS[v >> 4]; - *(p++) = HEX_DIGITS[v & 0x0F]; - } - *p = '\0'; - - OPENSSL_free(buf); - - return ret; -} - -EC_POINT *EC_POINT_hex2point(const EC_GROUP *group, - const char *buf, EC_POINT *point, BN_CTX *ctx) -{ - EC_POINT *ret = NULL; - BIGNUM *tmp_bn = NULL; - - if (!BN_hex2bn(&tmp_bn, buf)) - return NULL; - - ret = EC_POINT_bn2point(group, tmp_bn, point, ctx); - - BN_clear_free(tmp_bn); - - return ret; -} diff --git a/Sources/COpenSSL/ec_lcl.h b/Sources/COpenSSL/ec_lcl.h deleted file mode 100644 index bda6e9f2..00000000 --- a/Sources/COpenSSL/ec_lcl.h +++ /dev/null @@ -1,567 +0,0 @@ -/* crypto/ec/ec_lcl.h */ -/* - * Originally written by Bodo Moeller for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * The elliptic curve binary polynomial software is originally written by - * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. - * - */ - -#include - -#include "obj_mac.h" -#include "ec.h" -#include "bn.h" - -#if defined(__SUNPRO_C) -# if __SUNPRO_C >= 0x520 -# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) -# endif -#endif - -/* Use default functions for poin2oct, oct2point and compressed coordinates */ -#define EC_FLAGS_DEFAULT_OCT 0x1 - -/* - * Structure details are not part of the exported interface, so all this may - * change in future versions. - */ - -struct ec_method_st { - /* Various method flags */ - int flags; - /* used by EC_METHOD_get_field_type: */ - int field_type; /* a NID */ - /* - * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, - * EC_GROUP_copy: - */ - int (*group_init) (EC_GROUP *); - void (*group_finish) (EC_GROUP *); - void (*group_clear_finish) (EC_GROUP *); - int (*group_copy) (EC_GROUP *, const EC_GROUP *); - /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */ - /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */ - int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); - int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, - BN_CTX *); - /* used by EC_GROUP_get_degree: */ - int (*group_get_degree) (const EC_GROUP *); - /* used by EC_GROUP_check: */ - int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *); - /* - * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, - * EC_POINT_copy: - */ - int (*point_init) (EC_POINT *); - void (*point_finish) (EC_POINT *); - void (*point_clear_finish) (EC_POINT *); - int (*point_copy) (EC_POINT *, const EC_POINT *); - /*- - * used by EC_POINT_set_to_infinity, - * EC_POINT_set_Jprojective_coordinates_GFp, - * EC_POINT_get_Jprojective_coordinates_GFp, - * EC_POINT_set_affine_coordinates_GFp, ..._GF2m, - * EC_POINT_get_affine_coordinates_GFp, ..._GF2m, - * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m: - */ - int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *); - int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *, - EC_POINT *, const BIGNUM *x, - const BIGNUM *y, - const BIGNUM *z, BN_CTX *); - int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *, - const EC_POINT *, BIGNUM *x, - BIGNUM *y, BIGNUM *z, - BN_CTX *); - int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *, - const BIGNUM *x, const BIGNUM *y, - BN_CTX *); - int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *, - BIGNUM *x, BIGNUM *y, BN_CTX *); - int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *, - const BIGNUM *x, int y_bit, - BN_CTX *); - /* used by EC_POINT_point2oct, EC_POINT_oct2point: */ - size_t (*point2oct) (const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, unsigned char *buf, - size_t len, BN_CTX *); - int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf, - size_t len, BN_CTX *); - /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */ - int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *); - int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); - int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *); - /* - * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: - */ - int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *); - int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *); - int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, - BN_CTX *); - /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */ - int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *); - int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[], - BN_CTX *); - /* - * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, - * EC_POINT_have_precompute_mult (default implementations are used if the - * 'mul' pointer is 0): - */ - int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); - int (*precompute_mult) (EC_GROUP *group, BN_CTX *); - int (*have_precompute_mult) (const EC_GROUP *group); - /* internal functions */ - /* - * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and - * 'dbl' so that the same implementations of point operations can be used - * with different optimized implementations of expensive field - * operations: - */ - int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); - int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); - int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); - /* e.g. to Montgomery */ - int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); - /* e.g. from Montgomery */ - int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); - int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *); -} /* EC_METHOD */ ; - -typedef struct ec_extra_data_st { - struct ec_extra_data_st *next; - void *data; - void *(*dup_func) (void *); - void (*free_func) (void *); - void (*clear_free_func) (void *); -} EC_EXTRA_DATA; /* used in EC_GROUP */ - -struct ec_group_st { - const EC_METHOD *meth; - EC_POINT *generator; /* optional */ - BIGNUM order, cofactor; - int curve_name; /* optional NID for named curve */ - int asn1_flag; /* flag to control the asn1 encoding */ - /* - * Kludge: upper bit of ans1_flag is used to denote structure - * version. If set, then last field is present. This is done - * for interoperation with FIPS code. - */ -#define EC_GROUP_ASN1_FLAG_MASK 0x7fffffff -#define EC_GROUP_VERSION(p) (p->asn1_flag&~EC_GROUP_ASN1_FLAG_MASK) - point_conversion_form_t asn1_form; - unsigned char *seed; /* optional seed for parameters (appears in - * ASN1) */ - size_t seed_len; - EC_EXTRA_DATA *extra_data; /* linked list */ - /* - * The following members are handled by the method functions, even if - * they appear generic - */ - /* - * Field specification. For curves over GF(p), this is the modulus; for - * curves over GF(2^m), this is the irreducible polynomial defining the - * field. - */ - BIGNUM field; - /* - * Field specification for curves over GF(2^m). The irreducible f(t) is - * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m = - * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with - * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero - * terms. - */ - int poly[6]; - /* - * Curve coefficients. (Here the assumption is that BIGNUMs can be used - * or abused for all kinds of fields, not just GF(p).) For characteristic - * > 3, the curve is defined by a Weierstrass equation of the form y^2 = - * x^3 + a*x + b. For characteristic 2, the curve is defined by an - * equation of the form y^2 + x*y = x^3 + a*x^2 + b. - */ - BIGNUM a, b; - /* enable optimized point arithmetics for special case */ - int a_is_minus3; - /* method-specific (e.g., Montgomery structure) */ - void *field_data1; - /* method-specific */ - void *field_data2; - /* method-specific */ - int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *, - BN_CTX *); - BN_MONT_CTX *mont_data; /* data for ECDSA inverse */ -} /* EC_GROUP */ ; - -struct ec_key_st { - int version; - EC_GROUP *group; - EC_POINT *pub_key; - BIGNUM *priv_key; - unsigned int enc_flag; - point_conversion_form_t conv_form; - int references; - int flags; - EC_EXTRA_DATA *method_data; -} /* EC_KEY */ ; - -/* - * Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs - * only (with visibility limited to 'package' level for now). We use the - * function pointers as index for retrieval; this obviates global - * ex_data-style index tables. - */ -int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data, - void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)); -void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *, void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)); -void EC_EX_DATA_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)); -void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *), - void (*free_func) (void *), - void (*clear_free_func) (void *)); -void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **); -void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **); - -struct ec_point_st { - const EC_METHOD *meth; - /* - * All members except 'meth' are handled by the method functions, even if - * they appear generic - */ - BIGNUM X; - BIGNUM Y; - BIGNUM Z; /* Jacobian projective coordinates: (X, Y, Z) - * represents (X/Z^2, Y/Z^3) if Z != 0 */ - int Z_is_one; /* enable optimized point arithmetics for - * special case */ -} /* EC_POINT */ ; - -/* - * method functions in ec_mult.c (ec_lib.c uses these as defaults if - * group->method->mul is 0) - */ -int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, - size_t num, const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *); -int ec_wNAF_have_precompute_mult(const EC_GROUP *group); - -/* method functions in ecp_smpl.c */ -int ec_GFp_simple_group_init(EC_GROUP *); -void ec_GFp_simple_group_finish(EC_GROUP *); -void ec_GFp_simple_group_clear_finish(EC_GROUP *); -int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); -int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, BN_CTX *); -int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *); -int ec_GFp_simple_group_get_degree(const EC_GROUP *); -int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); -int ec_GFp_simple_point_init(EC_POINT *); -void ec_GFp_simple_point_finish(EC_POINT *); -void ec_GFp_simple_point_clear_finish(EC_POINT *); -int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); -int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); -int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, - EC_POINT *, const BIGNUM *x, - const BIGNUM *y, - const BIGNUM *z, BN_CTX *); -int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, - const EC_POINT *, BIGNUM *x, - BIGNUM *y, BIGNUM *z, - BN_CTX *); -int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, - const BIGNUM *y, BN_CTX *); -int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, - const EC_POINT *, BIGNUM *x, - BIGNUM *y, BN_CTX *); -int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, int y_bit, - BN_CTX *); -size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *); -int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, - const unsigned char *buf, size_t len, BN_CTX *); -int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *); -int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - BN_CTX *); -int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); -int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); -int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); -int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, - BN_CTX *); -int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); -int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, - EC_POINT *[], BN_CTX *); -int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); - -/* method functions in ecp_mont.c */ -int ec_GFp_mont_group_init(EC_GROUP *); -int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -void ec_GFp_mont_group_finish(EC_GROUP *); -void ec_GFp_mont_group_clear_finish(EC_GROUP *); -int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *); -int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); - -/* method functions in ecp_nist.c */ -int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); -int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); - -/* method functions in ec2_smpl.c */ -int ec_GF2m_simple_group_init(EC_GROUP *); -void ec_GF2m_simple_group_finish(EC_GROUP *); -void ec_GF2m_simple_group_clear_finish(EC_GROUP *); -int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *); -int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, - BN_CTX *); -int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *); -int ec_GF2m_simple_group_get_degree(const EC_GROUP *); -int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); -int ec_GF2m_simple_point_init(EC_POINT *); -void ec_GF2m_simple_point_finish(EC_POINT *); -void ec_GF2m_simple_point_clear_finish(EC_POINT *); -int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *); -int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); -int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, - const BIGNUM *y, BN_CTX *); -int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, - const EC_POINT *, BIGNUM *x, - BIGNUM *y, BN_CTX *); -int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, - const BIGNUM *x, int y_bit, - BN_CTX *); -size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *); -int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *, - const unsigned char *buf, size_t len, BN_CTX *); -int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *); -int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, - BN_CTX *); -int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); -int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); -int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); -int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, - BN_CTX *); -int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); -int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, - EC_POINT *[], BN_CTX *); -int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); -int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - BN_CTX *); -int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *); - -/* method functions in ec2_mult.c */ -int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); -int ec_GF2m_have_precompute_mult(const EC_GROUP *group); - -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 -/* method functions in ecp_nistp224.c */ -int ec_GFp_nistp224_group_init(EC_GROUP *group); -int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *n, - BN_CTX *); -int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx); -int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx); -int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx); -int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group); - -/* method functions in ecp_nistp256.c */ -int ec_GFp_nistp256_group_init(EC_GROUP *group); -int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *n, - BN_CTX *); -int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx); -int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx); -int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx); -int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group); - -/* method functions in ecp_nistp521.c */ -int ec_GFp_nistp521_group_init(EC_GROUP *group); -int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *n, - BN_CTX *); -int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx); -int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], const BIGNUM *scalars[], - BN_CTX *); -int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx); -int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx); -int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group); - -/* utility functions in ecp_nistputil.c */ -void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, - size_t felem_size, - void *tmp_felems, - void (*felem_one) (void *out), - int (*felem_is_zero) (const void - *in), - void (*felem_assign) (void *out, - const void - *in), - void (*felem_square) (void *out, - const void - *in), - void (*felem_mul) (void *out, - const void - *in1, - const void - *in2), - void (*felem_inv) (void *out, - const void - *in), - void (*felem_contract) (void - *out, - const - void - *in)); -void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, - unsigned char *digit, unsigned char in); -#endif - -#ifdef ECP_NISTZ256_ASM -/** Returns GFp methods using montgomery multiplication, with x86-64 optimized - * P256. See http://eprint.iacr.org/2013/816. - * \return EC_METHOD object - */ -const EC_METHOD *EC_GFp_nistz256_method(void); -#endif - -#ifdef OPENSSL_FIPS -EC_GROUP *FIPS_ec_group_new_curve_gfp(const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx); -EC_GROUP *FIPS_ec_group_new_curve_gf2m(const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx); -EC_GROUP *FIPS_ec_group_new_by_curve_name(int nid); -#endif diff --git a/Sources/COpenSSL/ecb3_enc.c b/Sources/COpenSSL/ecb3_enc.c deleted file mode 100644 index c49fbd41..00000000 --- a/Sources/COpenSSL/ecb3_enc.c +++ /dev/null @@ -1,82 +0,0 @@ -/* crypto/des/ecb3_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, - DES_key_schedule *ks1, DES_key_schedule *ks2, - DES_key_schedule *ks3, int enc) -{ - register DES_LONG l0, l1; - DES_LONG ll[2]; - const unsigned char *in = &(*input)[0]; - unsigned char *out = &(*output)[0]; - - c2l(in, l0); - c2l(in, l1); - ll[0] = l0; - ll[1] = l1; - if (enc) - DES_encrypt3(ll, ks1, ks2, ks3); - else - DES_decrypt3(ll, ks1, ks2, ks3); - l0 = ll[0]; - l1 = ll[1]; - l2c(l0, out); - l2c(l1, out); -} diff --git a/Sources/COpenSSL/ecb_enc.c b/Sources/COpenSSL/ecb_enc.c deleted file mode 100644 index 1f3627b0..00000000 --- a/Sources/COpenSSL/ecb_enc.c +++ /dev/null @@ -1,124 +0,0 @@ -/* crypto/des/ecb_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" -#include "des_ver.h" -#include "opensslv.h" -#include "bio.h" - -OPENSSL_GLOBAL const char libdes_version[] = "libdes" OPENSSL_VERSION_PTEXT; -OPENSSL_GLOBAL const char DES_version[] = "DES" OPENSSL_VERSION_PTEXT; - -const char *DES_options(void) -{ - static int init = 1; - static char buf[32]; - - if (init) { - const char *ptr, *unroll, *risc, *size; - -#ifdef DES_PTR - ptr = "ptr"; -#else - ptr = "idx"; -#endif -#if defined(DES_RISC1) || defined(DES_RISC2) -# ifdef DES_RISC1 - risc = "risc1"; -# endif -# ifdef DES_RISC2 - risc = "risc2"; -# endif -#else - risc = "cisc"; -#endif -#ifdef DES_UNROLL - unroll = "16"; -#else - unroll = "2"; -#endif - if (sizeof(DES_LONG) != sizeof(long)) - size = "int"; - else - size = "long"; - BIO_snprintf(buf, sizeof(buf), "des(%s,%s,%s,%s)", ptr, risc, unroll, - size); - init = 0; - } - return (buf); -} - -void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, - DES_key_schedule *ks, int enc) -{ - register DES_LONG l; - DES_LONG ll[2]; - const unsigned char *in = &(*input)[0]; - unsigned char *out = &(*output)[0]; - - c2l(in, l); - ll[0] = l; - c2l(in, l); - ll[1] = l; - DES_encrypt1(ll, ks, enc); - l = ll[0]; - l2c(l, out); - l = ll[1]; - l2c(l, out); - l = ll[0] = ll[1] = 0; -} diff --git a/Sources/COpenSSL/ecdh.h b/Sources/COpenSSL/ecdh.h deleted file mode 100644 index 85e20860..00000000 --- a/Sources/COpenSSL/ecdh.h +++ /dev/null @@ -1,134 +0,0 @@ -/* crypto/ecdh/ecdh.h */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * The ECDH software is originally written by Douglas Stebila of - * Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef HEADER_ECDH_H -# define HEADER_ECDH_H - -# include "opensslconf.h" - -# ifdef OPENSSL_NO_ECDH -# error ECDH is disabled. -# endif - -# include "ec.h" -# include "ossl_typ.h" -# ifndef OPENSSL_NO_DEPRECATED -# include "bn.h" -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -# define EC_FLAG_COFACTOR_ECDH 0x1000 - -const ECDH_METHOD *ECDH_OpenSSL(void); - -void ECDH_set_default_method(const ECDH_METHOD *); -const ECDH_METHOD *ECDH_get_default_method(void); -int ECDH_set_method(EC_KEY *, const ECDH_METHOD *); - -int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, - EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen, - void *out, size_t *outlen)); - -int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new - *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); -int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg); -void *ECDH_get_ex_data(EC_KEY *d, int idx); - -int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, - const unsigned char *Z, size_t Zlen, - const unsigned char *sinfo, size_t sinfolen, - const EVP_MD *md); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_ECDH_strings(void); - -/* Error codes for the ECDH functions. */ - -/* Function codes. */ -# define ECDH_F_ECDH_CHECK 102 -# define ECDH_F_ECDH_COMPUTE_KEY 100 -# define ECDH_F_ECDH_DATA_NEW_METHOD 101 - -/* Reason codes. */ -# define ECDH_R_KDF_FAILED 102 -# define ECDH_R_NON_FIPS_METHOD 103 -# define ECDH_R_NO_PRIVATE_VALUE 100 -# define ECDH_R_POINT_ARITHMETIC_FAILURE 101 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ecdsa.h b/Sources/COpenSSL/ecdsa.h deleted file mode 100644 index 3814095c..00000000 --- a/Sources/COpenSSL/ecdsa.h +++ /dev/null @@ -1,335 +0,0 @@ -/* crypto/ecdsa/ecdsa.h */ -/** - * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions - * \author Written by Nils Larsch for the OpenSSL project - */ -/* ==================================================================== - * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef HEADER_ECDSA_H -# define HEADER_ECDSA_H - -# include "opensslconf.h" - -# ifdef OPENSSL_NO_ECDSA -# error ECDSA is disabled. -# endif - -# include "ec.h" -# include "ossl_typ.h" -# ifndef OPENSSL_NO_DEPRECATED -# include "bn.h" -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct ECDSA_SIG_st { - BIGNUM *r; - BIGNUM *s; -} ECDSA_SIG; - -/** Allocates and initialize a ECDSA_SIG structure - * \return pointer to a ECDSA_SIG structure or NULL if an error occurred - */ -ECDSA_SIG *ECDSA_SIG_new(void); - -/** frees a ECDSA_SIG structure - * \param sig pointer to the ECDSA_SIG structure - */ -void ECDSA_SIG_free(ECDSA_SIG *sig); - -/** DER encode content of ECDSA_SIG object (note: this function modifies *pp - * (*pp += length of the DER encoded signature)). - * \param sig pointer to the ECDSA_SIG object - * \param pp pointer to a unsigned char pointer for the output or NULL - * \return the length of the DER encoded ECDSA_SIG object or 0 - */ -int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); - -/** Decodes a DER encoded ECDSA signature (note: this function changes *pp - * (*pp += len)). - * \param sig pointer to ECDSA_SIG pointer (may be NULL) - * \param pp memory buffer with the DER encoded signature - * \param len length of the buffer - * \return pointer to the decoded ECDSA_SIG structure (or NULL) - */ -ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); - -/** Computes the ECDSA signature of the given hash value using - * the supplied private key and returns the created signature. - * \param dgst pointer to the hash value - * \param dgst_len length of the hash value - * \param eckey EC_KEY object containing a private EC key - * \return pointer to a ECDSA_SIG structure or NULL if an error occurred - */ -ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len, - EC_KEY *eckey); - -/** Computes ECDSA signature of a given hash value using the supplied - * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). - * \param dgst pointer to the hash value to sign - * \param dgstlen length of the hash value - * \param kinv BIGNUM with a pre-computed inverse k (optional) - * \param rp BIGNUM with a pre-computed rp value (optioanl), - * see ECDSA_sign_setup - * \param eckey EC_KEY object containing a private EC key - * \return pointer to a ECDSA_SIG structure or NULL if an error occurred - */ -ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, - const BIGNUM *kinv, const BIGNUM *rp, - EC_KEY *eckey); - -/** Verifies that the supplied signature is a valid ECDSA - * signature of the supplied hash value using the supplied public key. - * \param dgst pointer to the hash value - * \param dgst_len length of the hash value - * \param sig ECDSA_SIG structure - * \param eckey EC_KEY object containing a public EC key - * \return 1 if the signature is valid, 0 if the signature is invalid - * and -1 on error - */ -int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, - const ECDSA_SIG *sig, EC_KEY *eckey); - -const ECDSA_METHOD *ECDSA_OpenSSL(void); - -/** Sets the default ECDSA method - * \param meth new default ECDSA_METHOD - */ -void ECDSA_set_default_method(const ECDSA_METHOD *meth); - -/** Returns the default ECDSA method - * \return pointer to ECDSA_METHOD structure containing the default method - */ -const ECDSA_METHOD *ECDSA_get_default_method(void); - -/** Sets method to be used for the ECDSA operations - * \param eckey EC_KEY object - * \param meth new method - * \return 1 on success and 0 otherwise - */ -int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); - -/** Returns the maximum length of the DER encoded signature - * \param eckey EC_KEY object - * \return numbers of bytes required for the DER encoded signature - */ -int ECDSA_size(const EC_KEY *eckey); - -/** Precompute parts of the signing operation - * \param eckey EC_KEY object containing a private EC key - * \param ctx BN_CTX object (optional) - * \param kinv BIGNUM pointer for the inverse of k - * \param rp BIGNUM pointer for x coordinate of k * generator - * \return 1 on success and 0 otherwise - */ -int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp); - -/** Computes ECDSA signature of a given hash value using the supplied - * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). - * \param type this parameter is ignored - * \param dgst pointer to the hash value to sign - * \param dgstlen length of the hash value - * \param sig memory for the DER encoded created signature - * \param siglen pointer to the length of the returned signature - * \param eckey EC_KEY object containing a private EC key - * \return 1 on success and 0 otherwise - */ -int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, - unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); - -/** Computes ECDSA signature of a given hash value using the supplied - * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). - * \param type this parameter is ignored - * \param dgst pointer to the hash value to sign - * \param dgstlen length of the hash value - * \param sig buffer to hold the DER encoded signature - * \param siglen pointer to the length of the returned signature - * \param kinv BIGNUM with a pre-computed inverse k (optional) - * \param rp BIGNUM with a pre-computed rp value (optioanl), - * see ECDSA_sign_setup - * \param eckey EC_KEY object containing a private EC key - * \return 1 on success and 0 otherwise - */ -int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, - unsigned char *sig, unsigned int *siglen, - const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); - -/** Verifies that the given signature is valid ECDSA signature - * of the supplied hash value using the specified public key. - * \param type this parameter is ignored - * \param dgst pointer to the hash value - * \param dgstlen length of the hash value - * \param sig pointer to the DER encoded signature - * \param siglen length of the DER encoded signature - * \param eckey EC_KEY object containing a public EC key - * \return 1 if the signature is valid, 0 if the signature is invalid - * and -1 on error - */ -int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, - const unsigned char *sig, int siglen, EC_KEY *eckey); - -/* the standard ex_data functions */ -int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new - *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); -int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); -void *ECDSA_get_ex_data(EC_KEY *d, int idx); - -/** Allocates and initialize a ECDSA_METHOD structure - * \param ecdsa_method pointer to ECDSA_METHOD to copy. (May be NULL) - * \return pointer to a ECDSA_METHOD structure or NULL if an error occurred - */ - -ECDSA_METHOD *ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_method); - -/** frees a ECDSA_METHOD structure - * \param ecdsa_method pointer to the ECDSA_METHOD structure - */ -void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method); - -/** Sets application specific data in the ECDSA_METHOD - * \param ecdsa_method pointer to existing ECDSA_METHOD - * \param app application specific data to set - */ - -void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app); - -/** Returns application specific data from a ECDSA_METHOD structure - * \param ecdsa_method pointer to ECDSA_METHOD structure - * \return pointer to application specific data. - */ - -void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method); - -/** Set the ECDSA_do_sign function in the ECDSA_METHOD - * \param ecdsa_method pointer to existing ECDSA_METHOD - * \param ecdsa_do_sign a funtion of type ECDSA_do_sign - */ - -void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method, - ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char - *dgst, int dgst_len, - const BIGNUM *inv, - const BIGNUM *rp, - EC_KEY *eckey)); - -/** Set the ECDSA_sign_setup function in the ECDSA_METHOD - * \param ecdsa_method pointer to existing ECDSA_METHOD - * \param ecdsa_sign_setup a funtion of type ECDSA_sign_setup - */ - -void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method, - int (*ecdsa_sign_setup) (EC_KEY *eckey, - BN_CTX *ctx, - BIGNUM **kinv, - BIGNUM **r)); - -/** Set the ECDSA_do_verify function in the ECDSA_METHOD - * \param ecdsa_method pointer to existing ECDSA_METHOD - * \param ecdsa_do_verify a funtion of type ECDSA_do_verify - */ - -void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method, - int (*ecdsa_do_verify) (const unsigned char - *dgst, int dgst_len, - const ECDSA_SIG *sig, - EC_KEY *eckey)); - -void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags); - -/** Set the flags field in the ECDSA_METHOD - * \param ecdsa_method pointer to existing ECDSA_METHOD - * \param flags flags value to set - */ - -void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name); - -/** Set the name field in the ECDSA_METHOD - * \param ecdsa_method pointer to existing ECDSA_METHOD - * \param name name to set - */ - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_ECDSA_strings(void); - -/* Error codes for the ECDSA functions. */ - -/* Function codes. */ -# define ECDSA_F_ECDSA_CHECK 104 -# define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 -# define ECDSA_F_ECDSA_DO_SIGN 101 -# define ECDSA_F_ECDSA_DO_VERIFY 102 -# define ECDSA_F_ECDSA_METHOD_NEW 105 -# define ECDSA_F_ECDSA_SIGN_SETUP 103 - -/* Reason codes. */ -# define ECDSA_R_BAD_SIGNATURE 100 -# define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101 -# define ECDSA_R_ERR_EC_LIB 102 -# define ECDSA_R_MISSING_PARAMETERS 103 -# define ECDSA_R_NEED_NEW_SETUP_VALUES 106 -# define ECDSA_R_NON_FIPS_METHOD 107 -# define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 -# define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ech_.c b/Sources/COpenSSL/ech_.c deleted file mode 100644 index 6538b6c2..00000000 --- a/Sources/COpenSSL/ech_.c +++ /dev/null @@ -1,783 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/ecdh/ech_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "ecdh.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason) - -static ERR_STRING_DATA ECDH_str_functs[] = { - {ERR_FUNC(ECDH_F_ECDH_CHECK), "ECDH_CHECK"}, - {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, - {ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"}, - {0, NULL} -}; - -static ERR_STRING_DATA ECDH_str_reasons[] = { - {ERR_REASON(ECDH_R_KDF_FAILED), "KDF failed"}, - {ERR_REASON(ECDH_R_NON_FIPS_METHOD), "non fips method"}, - {ERR_REASON(ECDH_R_NO_PRIVATE_VALUE), "no private value"}, - {ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"}, - {0, NULL} -}; - -#endif - -void ERR_load_ECDH_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL) { - ERR_load_strings(0, ECDH_str_functs); - ERR_load_strings(0, ECDH_str_reasons); - } -#endif -} -/* crypto/ecdh/ec_kdf.c */ -/* - * Written by Stephen Henson for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#define OPENSSL_FIPSAPI - -#include -// #include "ecdh.h" -#include "evp.h" - -/* Key derivation function from X9.62/SECG */ -/* Way more than we will ever need */ -#define ECDH_KDF_MAX (1 << 30) - -int ECDH_KDF_X9_62(unsigned char *out, size_t outlen, - const unsigned char *Z, size_t Zlen, - const unsigned char *sinfo, size_t sinfolen, - const EVP_MD *md) -{ - EVP_MD_CTX mctx; - int rv = 0; - unsigned int i; - size_t mdlen; - unsigned char ctr[4]; - if (sinfolen > ECDH_KDF_MAX || outlen > ECDH_KDF_MAX - || Zlen > ECDH_KDF_MAX) - return 0; - mdlen = EVP_MD_size(md); - EVP_MD_CTX_init(&mctx); - for (i = 1;; i++) { - unsigned char mtmp[EVP_MAX_MD_SIZE]; - EVP_DigestInit_ex(&mctx, md, NULL); - ctr[3] = i & 0xFF; - ctr[2] = (i >> 8) & 0xFF; - ctr[1] = (i >> 16) & 0xFF; - ctr[0] = (i >> 24) & 0xFF; - if (!EVP_DigestUpdate(&mctx, Z, Zlen)) - goto err; - if (!EVP_DigestUpdate(&mctx, ctr, sizeof(ctr))) - goto err; - if (!EVP_DigestUpdate(&mctx, sinfo, sinfolen)) - goto err; - if (outlen >= mdlen) { - if (!EVP_DigestFinal(&mctx, out, NULL)) - goto err; - outlen -= mdlen; - if (outlen == 0) - break; - out += mdlen; - } else { - if (!EVP_DigestFinal(&mctx, mtmp, NULL)) - goto err; - memcpy(out, mtmp, outlen); - OPENSSL_cleanse(mtmp, mdlen); - break; - } - } - rv = 1; - err: - EVP_MD_CTX_cleanup(&mctx); - return rv; -} -/* crypto/ecdh/ecdh_key.c */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * The ECDH software is originally written by Douglas Stebila of - * Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "ech_locl.h" - -int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, - EC_KEY *eckey, - void *(*KDF) (const void *in, size_t inlen, void *out, - size_t *outlen)) -{ - ECDH_DATA *ecdh = ecdh_check(eckey); - if (ecdh == NULL) - return 0; - return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF); -} -/* crypto/ecdh/ech_lib.c */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * The ECDH software is originally written by Douglas Stebila of - * Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ech_locl.h" -#include -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -// #include "err.h" -#ifdef OPENSSL_FIPS -# include -#endif - -const char ECDH_version[] = "ECDH" OPENSSL_VERSION_PTEXT; - -static const ECDH_METHOD *default_ECDH_method = NULL; - -static void *ecdh_data_new(void); -static void *ecdh_data_dup(void *); -static void ecdh_data_free(void *); - -void ECDH_set_default_method(const ECDH_METHOD *meth) -{ - default_ECDH_method = meth; -} - -const ECDH_METHOD *ECDH_get_default_method(void) -{ - if (!default_ECDH_method) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_ecdh_openssl(); - else - return ECDH_OpenSSL(); -#else - default_ECDH_method = ECDH_OpenSSL(); -#endif - } - return default_ECDH_method; -} - -int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth) -{ - ECDH_DATA *ecdh; - - ecdh = ecdh_check(eckey); - - if (ecdh == NULL) - return 0; - -#if 0 - mtmp = ecdh->meth; - if (mtmp->finish) - mtmp->finish(eckey); -#endif -#ifndef OPENSSL_NO_ENGINE - if (ecdh->engine) { - ENGINE_finish(ecdh->engine); - ecdh->engine = NULL; - } -#endif - ecdh->meth = meth; -#if 0 - if (meth->init) - meth->init(eckey); -#endif - return 1; -} - -static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine) -{ - ECDH_DATA *ret; - - ret = (ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA)); - if (ret == NULL) { - ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - ret->init = NULL; - - ret->meth = ECDH_get_default_method(); - ret->engine = engine; -#ifndef OPENSSL_NO_ENGINE - if (!ret->engine) - ret->engine = ENGINE_get_default_ECDH(); - if (ret->engine) { - ret->meth = ENGINE_get_ECDH(ret->engine); - if (!ret->meth) { - ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); - ENGINE_finish(ret->engine); - OPENSSL_free(ret); - return NULL; - } - } -#endif - - ret->flags = ret->meth->flags; - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); -#if 0 - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); - OPENSSL_free(ret); - ret = NULL; - } -#endif - return (ret); -} - -static void *ecdh_data_new(void) -{ - return (void *)ECDH_DATA_new_method(NULL); -} - -static void *ecdh_data_dup(void *data) -{ - ECDH_DATA *r = (ECDH_DATA *)data; - - /* XXX: dummy operation */ - if (r == NULL) - return NULL; - - return (void *)ecdh_data_new(); -} - -void ecdh_data_free(void *data) -{ - ECDH_DATA *r = (ECDH_DATA *)data; - -#ifndef OPENSSL_NO_ENGINE - if (r->engine) - ENGINE_finish(r->engine); -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data); - - OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA)); - - OPENSSL_free(r); -} - -ECDH_DATA *ecdh_check(EC_KEY *key) -{ - ECDH_DATA *ecdh_data; - - void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup, - ecdh_data_free, ecdh_data_free); - if (data == NULL) { - ecdh_data = (ECDH_DATA *)ecdh_data_new(); - if (ecdh_data == NULL) - return NULL; - data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data, - ecdh_data_dup, ecdh_data_free, - ecdh_data_free); - if (data != NULL) { - /* - * Another thread raced us to install the key_method data and - * won. - */ - ecdh_data_free(ecdh_data); - ecdh_data = (ECDH_DATA *)data; - } else if (EC_KEY_get_key_method_data(key, ecdh_data_dup, - ecdh_data_free, - ecdh_data_free) != ecdh_data) { - /* Or an out of memory error in EC_KEY_insert_key_method_data. */ - ecdh_data_free(ecdh_data); - return NULL; - } - } else { - ecdh_data = (ECDH_DATA *)data; - } -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD) - && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { - ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD); - return NULL; - } -#endif - - return ecdh_data; -} - -int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp, - new_func, dup_func, free_func); -} - -int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg) -{ - ECDH_DATA *ecdh; - ecdh = ecdh_check(d); - if (ecdh == NULL) - return 0; - return (CRYPTO_set_ex_data(&ecdh->ex_data, idx, arg)); -} - -void *ECDH_get_ex_data(EC_KEY *d, int idx) -{ - ECDH_DATA *ecdh; - ecdh = ecdh_check(d); - if (ecdh == NULL) - return NULL; - return (CRYPTO_get_ex_data(&ecdh->ex_data, idx)); -} -/* crypto/ecdh/ech_ossl.c */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * The ECDH software is originally written by Douglas Stebila of - * Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include - -#include "cryptlib.h" - -// #include "ech_locl.h" -// #include "err.h" -#include "sha.h" -#include "obj_mac.h" -#include "bn.h" - -static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key, - EC_KEY *ecdh, - void *(*KDF) (const void *in, size_t inlen, - void *out, size_t *outlen)); - -static ECDH_METHOD openssl_ecdh_meth = { - "OpenSSL ECDH method", - ecdh_compute_key, -#if 0 - NULL, /* init */ - NULL, /* finish */ -#endif - 0, /* flags */ - NULL /* app_data */ -}; - -const ECDH_METHOD *ECDH_OpenSSL(void) -{ - return &openssl_ecdh_meth; -} - -/*- - * This implementation is based on the following primitives in the IEEE 1363 standard: - * - ECKAS-DH1 - * - ECSVDP-DH - * Finally an optional KDF is applied. - */ -static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, - EC_KEY *ecdh, - void *(*KDF) (const void *in, size_t inlen, - void *out, size_t *outlen)) -{ - BN_CTX *ctx; - EC_POINT *tmp = NULL; - BIGNUM *x = NULL, *y = NULL; - const BIGNUM *priv_key; - const EC_GROUP *group; - int ret = -1; - size_t buflen, len; - unsigned char *buf = NULL; - - if (outlen > INT_MAX) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); /* sort of, - * anyway */ - return -1; - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - - priv_key = EC_KEY_get0_private_key(ecdh); - if (priv_key == NULL) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_NO_PRIVATE_VALUE); - goto err; - } - - group = EC_KEY_get0_group(ecdh); - - if (EC_KEY_get_flags(ecdh) & EC_FLAG_COFACTOR_ECDH) { - if (!EC_GROUP_get_cofactor(group, x, ctx) || - !BN_mul(x, x, priv_key, ctx)) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); - goto err; - } - priv_key = x; - } - - if ((tmp = EC_POINT_new(group)) == NULL) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); - goto err; - } - - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == - NID_X9_62_prime_field) { - if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); - goto err; - } - } -#ifndef OPENSSL_NO_EC2M - else { - if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); - goto err; - } - } -#endif - - buflen = (EC_GROUP_get_degree(group) + 7) / 8; - len = BN_num_bytes(x); - if (len > buflen) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); - goto err; - } - if ((buf = OPENSSL_malloc(buflen)) == NULL) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - memset(buf, 0, buflen - len); - if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB); - goto err; - } - - if (KDF != 0) { - if (KDF(buf, buflen, out, &outlen) == NULL) { - ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KDF_FAILED); - goto err; - } - ret = outlen; - } else { - /* no KDF, just copy as much as we can */ - if (outlen > buflen) - outlen = buflen; - memcpy(out, buf, outlen); - ret = outlen; - } - - err: - if (tmp) - EC_POINT_free(tmp); - if (ctx) - BN_CTX_end(ctx); - if (ctx) - BN_CTX_free(ctx); - if (buf) { - OPENSSL_cleanse(buf, buflen); - OPENSSL_free(buf); - } - return (ret); -} diff --git a/Sources/COpenSSL/ech_locl.h b/Sources/COpenSSL/ech_locl.h deleted file mode 100644 index 68349f8c..00000000 --- a/Sources/COpenSSL/ech_locl.h +++ /dev/null @@ -1,104 +0,0 @@ -/* crypto/ecdh/ech_locl.h */ -/* ==================================================================== - * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_ECH_LOCL_H -# define HEADER_ECH_LOCL_H - -# include "ecdh.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct ecdh_method { - const char *name; - int (*compute_key) (void *key, size_t outlen, const EC_POINT *pub_key, - EC_KEY *ecdh, void *(*KDF) (const void *in, - size_t inlen, void *out, - size_t *outlen)); -# if 0 - int (*init) (EC_KEY *eckey); - int (*finish) (EC_KEY *eckey); -# endif - int flags; - char *app_data; -}; - -/* - * If this flag is set the ECDH method is FIPS compliant and can be used in - * FIPS mode. This is set in the validated module method. If an application - * sets this flag in its own methods it is its responsibility to ensure the - * result is compliant. - */ - -# define ECDH_FLAG_FIPS_METHOD 0x1 - -typedef struct ecdh_data_st { - /* EC_KEY_METH_DATA part */ - int (*init) (EC_KEY *); - /* method specific part */ - ENGINE *engine; - int flags; - const ECDH_METHOD *meth; - CRYPTO_EX_DATA ex_data; -} ECDH_DATA; - -ECDH_DATA *ecdh_check(EC_KEY *); - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_ECH_LOCL_H */ diff --git a/Sources/COpenSSL/eck_prn.c b/Sources/COpenSSL/eck_prn.c deleted file mode 100644 index 958b965a..00000000 --- a/Sources/COpenSSL/eck_prn.c +++ /dev/null @@ -1,377 +0,0 @@ -/* crypto/ec/eck_prn.c */ -/* - * Written by Nils Larsch for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Portions originally developed by SUN MICROSYSTEMS, INC., and - * contributed to the OpenSSL project. - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "ec.h" -#include "bn.h" - -#ifndef OPENSSL_NO_FP_API -int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = ECPKParameters_print(b, x, off); - BIO_free(b); - return (ret); -} - -int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = EC_KEY_print(b, x, off); - BIO_free(b); - return (ret); -} - -int ECParameters_print_fp(FILE *fp, const EC_KEY *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = ECParameters_print(b, x); - BIO_free(b); - return (ret); -} -#endif - -int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) -{ - EVP_PKEY *pk; - int ret; - pk = EVP_PKEY_new(); - if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) - return 0; - ret = EVP_PKEY_print_private(bp, pk, off, NULL); - EVP_PKEY_free(pk); - return ret; -} - -int ECParameters_print(BIO *bp, const EC_KEY *x) -{ - EVP_PKEY *pk; - int ret; - pk = EVP_PKEY_new(); - if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) - return 0; - ret = EVP_PKEY_print_params(bp, pk, 4, NULL); - EVP_PKEY_free(pk); - return ret; -} - -static int print_bin(BIO *fp, const char *str, const unsigned char *num, - size_t len, int off); - -int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) -{ - unsigned char *buffer = NULL; - size_t buf_len = 0, i; - int ret = 0, reason = ERR_R_BIO_LIB; - BN_CTX *ctx = NULL; - const EC_POINT *point = NULL; - BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, - *order = NULL, *cofactor = NULL; - const unsigned char *seed; - size_t seed_len = 0; - - static const char *gen_compressed = "Generator (compressed):"; - static const char *gen_uncompressed = "Generator (uncompressed):"; - static const char *gen_hybrid = "Generator (hybrid):"; - - if (!x) { - reason = ERR_R_PASSED_NULL_PARAMETER; - goto err; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (EC_GROUP_get_asn1_flag(x)) { - /* the curve parameter are given by an asn1 OID */ - int nid; - const char *nname; - - if (!BIO_indent(bp, off, 128)) - goto err; - - nid = EC_GROUP_get_curve_name(x); - if (nid == 0) - goto err; - - if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) - goto err; - if (BIO_printf(bp, "\n") <= 0) - goto err; - nname = EC_curve_nid2nist(nid); - if (nname) { - if (!BIO_indent(bp, off, 128)) - goto err; - if (BIO_printf(bp, "NIST CURVE: %s\n", nname) <= 0) - goto err; - } - } else { - /* explicit parameters */ - int is_char_two = 0; - point_conversion_form_t form; - int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); - - if (tmp_nid == NID_X9_62_characteristic_two_field) - is_char_two = 1; - - if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || - (b = BN_new()) == NULL || (order = BN_new()) == NULL || - (cofactor = BN_new()) == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } -#ifndef OPENSSL_NO_EC2M - if (is_char_two) { - if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) { - reason = ERR_R_EC_LIB; - goto err; - } - } else /* prime field */ -#endif - { - if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) { - reason = ERR_R_EC_LIB; - goto err; - } - } - - if ((point = EC_GROUP_get0_generator(x)) == NULL) { - reason = ERR_R_EC_LIB; - goto err; - } - if (!EC_GROUP_get_order(x, order, NULL) || - !EC_GROUP_get_cofactor(x, cofactor, NULL)) { - reason = ERR_R_EC_LIB; - goto err; - } - - form = EC_GROUP_get_point_conversion_form(x); - - if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) { - reason = ERR_R_EC_LIB; - goto err; - } - - buf_len = (size_t)BN_num_bytes(p); - if (buf_len < (i = (size_t)BN_num_bytes(a))) - buf_len = i; - if (buf_len < (i = (size_t)BN_num_bytes(b))) - buf_len = i; - if (buf_len < (i = (size_t)BN_num_bytes(gen))) - buf_len = i; - if (buf_len < (i = (size_t)BN_num_bytes(order))) - buf_len = i; - if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) - buf_len = i; - - if ((seed = EC_GROUP_get0_seed(x)) != NULL) - seed_len = EC_GROUP_get_seed_len(x); - - buf_len += 10; - if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - if (!BIO_indent(bp, off, 128)) - goto err; - - /* print the 'short name' of the field type */ - if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) - <= 0) - goto err; - - if (is_char_two) { - /* print the 'short name' of the base type OID */ - int basis_type = EC_GROUP_get_basis_type(x); - if (basis_type == 0) - goto err; - - if (!BIO_indent(bp, off, 128)) - goto err; - - if (BIO_printf(bp, "Basis Type: %s\n", - OBJ_nid2sn(basis_type)) <= 0) - goto err; - - /* print the polynomial */ - if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, - off)) - goto err; - } else { - if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off)) - goto err; - } - if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) - goto err; - if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) - goto err; - if (form == POINT_CONVERSION_COMPRESSED) { - if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, - buffer, off)) - goto err; - } else if (form == POINT_CONVERSION_UNCOMPRESSED) { - if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, - buffer, off)) - goto err; - } else { /* form == POINT_CONVERSION_HYBRID */ - - if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, - buffer, off)) - goto err; - } - if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, - buffer, off)) - goto err; - if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, - buffer, off)) - goto err; - if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) - goto err; - } - ret = 1; - err: - if (!ret) - ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); - if (p) - BN_free(p); - if (a) - BN_free(a); - if (b) - BN_free(b); - if (gen) - BN_free(gen); - if (order) - BN_free(order); - if (cofactor) - BN_free(cofactor); - if (ctx) - BN_CTX_free(ctx); - if (buffer != NULL) - OPENSSL_free(buffer); - return (ret); -} - -static int print_bin(BIO *fp, const char *name, const unsigned char *buf, - size_t len, int off) -{ - size_t i; - char str[128 + 1 + 4]; - - if (buf == NULL) - return 1; - if (off > 0) { - if (off > 128) - off = 128; - memset(str, ' ', off); - if (BIO_write(fp, str, off) <= 0) - return 0; - } else { - off = 0; - } - - if (BIO_printf(fp, "%s", name) <= 0) - return 0; - - for (i = 0; i < len; i++) { - if ((i % 15) == 0) { - str[0] = '\n'; - memset(&(str[1]), ' ', off + 4); - if (BIO_write(fp, str, off + 1 + 4) <= 0) - return 0; - } - if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= - 0) - return 0; - } - if (BIO_write(fp, "\n", 1) <= 0) - return 0; - - return 1; -} diff --git a/Sources/COpenSSL/ecp_mont.c b/Sources/COpenSSL/ecp_mont.c deleted file mode 100644 index 19922347..00000000 --- a/Sources/COpenSSL/ecp_mont.c +++ /dev/null @@ -1,310 +0,0 @@ -/* crypto/ec/ecp_mont.c */ -/* - * Originally written by Bodo Moeller for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Portions of this software developed by SUN MICROSYSTEMS, INC., - * and contributed to the OpenSSL project. - */ - -#include "err.h" - -#ifdef OPENSSL_FIPS -# include -#endif - -#include "ec_lcl.h" - -const EC_METHOD *EC_GFp_mont_method(void) -{ - static const EC_METHOD ret = { - EC_FLAGS_DEFAULT_OCT, - NID_X9_62_prime_field, - ec_GFp_mont_group_init, - ec_GFp_mont_group_finish, - ec_GFp_mont_group_clear_finish, - ec_GFp_mont_group_copy, - ec_GFp_mont_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_simple_point_get_affine_coordinates, - 0, 0, 0, - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - 0 /* mul */ , - 0 /* precompute_mult */ , - 0 /* have_precompute_mult */ , - ec_GFp_mont_field_mul, - ec_GFp_mont_field_sqr, - 0 /* field_div */ , - ec_GFp_mont_field_encode, - ec_GFp_mont_field_decode, - ec_GFp_mont_field_set_to_one - }; - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return fips_ec_gfp_mont_method(); -#endif - - return &ret; -} - -int ec_GFp_mont_group_init(EC_GROUP *group) -{ - int ok; - - ok = ec_GFp_simple_group_init(group); - group->field_data1 = NULL; - group->field_data2 = NULL; - return ok; -} - -void ec_GFp_mont_group_finish(EC_GROUP *group) -{ - if (group->field_data1 != NULL) { - BN_MONT_CTX_free(group->field_data1); - group->field_data1 = NULL; - } - if (group->field_data2 != NULL) { - BN_free(group->field_data2); - group->field_data2 = NULL; - } - ec_GFp_simple_group_finish(group); -} - -void ec_GFp_mont_group_clear_finish(EC_GROUP *group) -{ - if (group->field_data1 != NULL) { - BN_MONT_CTX_free(group->field_data1); - group->field_data1 = NULL; - } - if (group->field_data2 != NULL) { - BN_clear_free(group->field_data2); - group->field_data2 = NULL; - } - ec_GFp_simple_group_clear_finish(group); -} - -int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) -{ - if (dest->field_data1 != NULL) { - BN_MONT_CTX_free(dest->field_data1); - dest->field_data1 = NULL; - } - if (dest->field_data2 != NULL) { - BN_clear_free(dest->field_data2); - dest->field_data2 = NULL; - } - - if (!ec_GFp_simple_group_copy(dest, src)) - return 0; - - if (src->field_data1 != NULL) { - dest->field_data1 = BN_MONT_CTX_new(); - if (dest->field_data1 == NULL) - return 0; - if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) - goto err; - } - if (src->field_data2 != NULL) { - dest->field_data2 = BN_dup(src->field_data2); - if (dest->field_data2 == NULL) - goto err; - } - - return 1; - - err: - if (dest->field_data1 != NULL) { - BN_MONT_CTX_free(dest->field_data1); - dest->field_data1 = NULL; - } - return 0; -} - -int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - BN_MONT_CTX *mont = NULL; - BIGNUM *one = NULL; - int ret = 0; - - if (group->field_data1 != NULL) { - BN_MONT_CTX_free(group->field_data1); - group->field_data1 = NULL; - } - if (group->field_data2 != NULL) { - BN_free(group->field_data2); - group->field_data2 = NULL; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - mont = BN_MONT_CTX_new(); - if (mont == NULL) - goto err; - if (!BN_MONT_CTX_set(mont, p, ctx)) { - ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB); - goto err; - } - one = BN_new(); - if (one == NULL) - goto err; - if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) - goto err; - - group->field_data1 = mont; - mont = NULL; - group->field_data2 = one; - one = NULL; - - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); - - if (!ret) { - BN_MONT_CTX_free(group->field_data1); - group->field_data1 = NULL; - BN_free(group->field_data2); - group->field_data2 = NULL; - } - - err: - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (mont != NULL) - BN_MONT_CTX_free(mont); - if (one != NULL) - BN_free(one); - return ret; -} - -int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - if (group->field_data1 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED); - return 0; - } - - return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx); -} - -int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - BN_CTX *ctx) -{ - if (group->field_data1 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED); - return 0; - } - - return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx); -} - -int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, BN_CTX *ctx) -{ - if (group->field_data1 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED); - return 0; - } - - return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx); -} - -int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, - const BIGNUM *a, BN_CTX *ctx) -{ - if (group->field_data1 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED); - return 0; - } - - return BN_from_montgomery(r, a, group->field_data1, ctx); -} - -int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, - BN_CTX *ctx) -{ - if (group->field_data2 == NULL) { - ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED); - return 0; - } - - if (!BN_copy(r, group->field_data2)) - return 0; - return 1; -} diff --git a/Sources/COpenSSL/ecp_nist.c b/Sources/COpenSSL/ecp_nist.c deleted file mode 100644 index d174eac4..00000000 --- a/Sources/COpenSSL/ecp_nist.c +++ /dev/null @@ -1,220 +0,0 @@ -/* crypto/ec/ecp_nist.c */ -/* - * Written by Nils Larsch for the OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Portions of this software developed by SUN MICROSYSTEMS, INC., - * and contributed to the OpenSSL project. - */ - -#include - -#include "err.h" -#include "obj_mac.h" -#include "ec_lcl.h" - -#ifdef OPENSSL_FIPS -# include -#endif - -const EC_METHOD *EC_GFp_nist_method(void) -{ - static const EC_METHOD ret = { - EC_FLAGS_DEFAULT_OCT, - NID_X9_62_prime_field, - ec_GFp_simple_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_nist_group_copy, - ec_GFp_nist_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_simple_point_get_affine_coordinates, - 0, 0, 0, - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - 0 /* mul */ , - 0 /* precompute_mult */ , - 0 /* have_precompute_mult */ , - ec_GFp_nist_field_mul, - ec_GFp_nist_field_sqr, - 0 /* field_div */ , - 0 /* field_encode */ , - 0 /* field_decode */ , - 0 /* field_set_to_one */ - }; - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return fips_ec_gfp_nist_method(); -#endif - - return &ret; -} - -int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) -{ - dest->field_mod_func = src->field_mod_func; - - return ec_GFp_simple_group_copy(dest, src); -} - -int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) -{ - int ret = 0; - BN_CTX *new_ctx = NULL; - BIGNUM *tmp_bn; - - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - - BN_CTX_start(ctx); - if ((tmp_bn = BN_CTX_get(ctx)) == NULL) - goto err; - - if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) - group->field_mod_func = BN_nist_mod_192; - else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) - group->field_mod_func = BN_nist_mod_224; - else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0) - group->field_mod_func = BN_nist_mod_256; - else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0) - group->field_mod_func = BN_nist_mod_384; - else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0) - group->field_mod_func = BN_nist_mod_521; - else { - ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME); - goto err; - } - - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - int ret = 0; - BN_CTX *ctx_new = NULL; - - if (!group || !r || !a || !b) { - ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER); - goto err; - } - if (!ctx) - if ((ctx_new = ctx = BN_CTX_new()) == NULL) - goto err; - - if (!BN_mul(r, a, b, ctx)) - goto err; - if (!group->field_mod_func(r, r, &group->field, ctx)) - goto err; - - ret = 1; - err: - if (ctx_new) - BN_CTX_free(ctx_new); - return ret; -} - -int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - BN_CTX *ctx) -{ - int ret = 0; - BN_CTX *ctx_new = NULL; - - if (!group || !r || !a) { - ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER); - goto err; - } - if (!ctx) - if ((ctx_new = ctx = BN_CTX_new()) == NULL) - goto err; - - if (!BN_sqr(r, a, ctx)) - goto err; - if (!group->field_mod_func(r, r, &group->field, ctx)) - goto err; - - ret = 1; - err: - if (ctx_new) - BN_CTX_free(ctx_new); - return ret; -} diff --git a/Sources/COpenSSL/ecp_nistp224.c b/Sources/COpenSSL/ecp_nistp224.c deleted file mode 100644 index ea89e552..00000000 --- a/Sources/COpenSSL/ecp_nistp224.c +++ /dev/null @@ -1,1767 +0,0 @@ -/* crypto/ec/ecp_nistp224.c */ -/* - * Written by Emilia Kasper (Google) for the OpenSSL project. - */ -/* Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication - * - * Inspired by Daniel J. Bernstein's public domain nistp224 implementation - * and Adam Langley's public domain 64-bit C implementation of curve25519 - */ - -#include "opensslconf.h" -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - -# ifndef OPENSSL_SYS_VMS -# include -# else -# include -# endif - -# include -# include "err.h" -# include "ec_lcl.h" - -# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) - /* even with gcc, the typedef won't work for 32-bit platforms */ -typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit - * platforms */ -# else -# error "Need GCC 3.1 or later to define type uint128_t" -# endif - -typedef uint8_t u8; -typedef uint64_t u64; - -/******************************************************************************/ -/*- - * INTERNAL REPRESENTATION OF FIELD ELEMENTS - * - * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3 - * using 64-bit coefficients called 'limbs', - * and sometimes (for multiplication results) as - * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6 - * using 128-bit coefficients called 'widelimbs'. - * A 4-limb representation is an 'felem'; - * a 7-widelimb representation is a 'widefelem'. - * Even within felems, bits of adjacent limbs overlap, and we don't always - * reduce the representations: we ensure that inputs to each felem - * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60, - * and fit into a 128-bit word without overflow. The coefficients are then - * again partially reduced to obtain an felem satisfying a_i < 2^57. - * We only reduce to the unique minimal representation at the end of the - * computation. - */ - -typedef uint64_t limb; -typedef uint128_t widelimb; - -typedef limb felem[4]; -typedef widelimb widefelem[7]; - -/* - * Field element represented as a byte arrary. 28*8 = 224 bits is also the - * group order size for the elliptic curve, and we also use this type for - * scalars for point multiplication. - */ -typedef u8 felem_bytearray[28]; - -static const felem_bytearray nistp224_curve_params[5] = { - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, - {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */ - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}, - {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */ - 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, - 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4}, - {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */ - 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, - 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21}, - {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */ - 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, - 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34} -}; - -/*- - * Precomputed multiples of the standard generator - * Points are given in coordinates (X, Y, Z) where Z normally is 1 - * (0 for the point at infinity). - * For each field element, slice a_0 is word 0, etc. - * - * The table has 2 * 16 elements, starting with the following: - * index | bits | point - * ------+---------+------------------------------ - * 0 | 0 0 0 0 | 0G - * 1 | 0 0 0 1 | 1G - * 2 | 0 0 1 0 | 2^56G - * 3 | 0 0 1 1 | (2^56 + 1)G - * 4 | 0 1 0 0 | 2^112G - * 5 | 0 1 0 1 | (2^112 + 1)G - * 6 | 0 1 1 0 | (2^112 + 2^56)G - * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G - * 8 | 1 0 0 0 | 2^168G - * 9 | 1 0 0 1 | (2^168 + 1)G - * 10 | 1 0 1 0 | (2^168 + 2^56)G - * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G - * 12 | 1 1 0 0 | (2^168 + 2^112)G - * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G - * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G - * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G - * followed by a copy of this with each element multiplied by 2^28. - * - * The reason for this is so that we can clock bits into four different - * locations when doing simple scalar multiplies against the base point, - * and then another four locations using the second 16 elements. - */ -static const felem gmul[2][16][3] = { {{{0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - {{0x3280d6115c1d21, 0xc1d356c2112234, - 0x7f321390b94a03, 0xb70e0cbd6bb4bf}, - {0xd5819985007e34, 0x75a05a07476444, - 0xfb4c22dfe6cd43, 0xbd376388b5f723}, - {1, 0, 0, 0}}, - {{0xfd9675666ebbe9, 0xbca7664d40ce5e, - 0x2242df8d8a2a43, 0x1f49bbb0f99bc5}, - {0x29e0b892dc9c43, 0xece8608436e662, - 0xdc858f185310d0, 0x9812dd4eb8d321}, - {1, 0, 0, 0}}, - {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, - 0x16e9a3bbce8a3f, 0xeedcccd8c2a748}, - {0xf19f90ed50266d, 0xabf2b4bf65f9df, - 0x313865468fafec, 0x5cb379ba910a17}, - {1, 0, 0, 0}}, - {{0x0641966cab26e3, 0x91fb2991fab0a0, - 0xefec27a4e13a0b, 0x0499aa8a5f8ebe}, - {0x7510407766af5d, 0x84d929610d5450, - 0x81d77aae82f706, 0x6916f6d4338c5b}, - {1, 0, 0, 0}}, - {{0xea95ac3b1f15c6, 0x086000905e82d4, - 0xdd323ae4d1c8b1, 0x932b56be7685a3}, - {0x9ef93dea25dbbf, 0x41665960f390f0, - 0xfdec76dbe2a8a7, 0x523e80f019062a}, - {1, 0, 0, 0}}, - {{0x822fdd26732c73, 0xa01c83531b5d0f, - 0x363f37347c1ba4, 0xc391b45c84725c}, - {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, - 0xc393da7e222a7f, 0x1efb7890ede244}, - {1, 0, 0, 0}}, - {{0x4c9e90ca217da1, 0xd11beca79159bb, - 0xff8d33c2c98b7c, 0x2610b39409f849}, - {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, - 0x966c079b753c89, 0xfe67e4e820b112}, - {1, 0, 0, 0}}, - {{0xe28cae2df5312d, 0xc71b61d16f5c6e, - 0x79b7619a3e7c4c, 0x05c73240899b47}, - {0x9f7f6382c73e3a, 0x18615165c56bda, - 0x641fab2116fd56, 0x72855882b08394}, - {1, 0, 0, 0}}, - {{0x0469182f161c09, 0x74a98ca8d00fb5, - 0xb89da93489a3e0, 0x41c98768fb0c1d}, - {0xe5ea05fb32da81, 0x3dce9ffbca6855, - 0x1cfe2d3fbf59e6, 0x0e5e03408738a7}, - {1, 0, 0, 0}}, - {{0xdab22b2333e87f, 0x4430137a5dd2f6, - 0xe03ab9f738beb8, 0xcb0c5d0dc34f24}, - {0x764a7df0c8fda5, 0x185ba5c3fa2044, - 0x9281d688bcbe50, 0xc40331df893881}, - {1, 0, 0, 0}}, - {{0xb89530796f0f60, 0xade92bd26909a3, - 0x1a0c83fb4884da, 0x1765bf22a5a984}, - {0x772a9ee75db09e, 0x23bc6c67cec16f, - 0x4c1edba8b14e2f, 0xe2a215d9611369}, - {1, 0, 0, 0}}, - {{0x571e509fb5efb3, 0xade88696410552, - 0xc8ae85fada74fe, 0x6c7e4be83bbde3}, - {0xff9f51160f4652, 0xb47ce2495a6539, - 0xa2946c53b582f4, 0x286d2db3ee9a60}, - {1, 0, 0, 0}}, - {{0x40bbd5081a44af, 0x0995183b13926c, - 0xbcefba6f47f6d0, 0x215619e9cc0057}, - {0x8bc94d3b0df45e, 0xf11c54a3694f6f, - 0x8631b93cdfe8b5, 0xe7e3f4b0982db9}, - {1, 0, 0, 0}}, - {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, - 0x1c29819435d2c6, 0xc813132f4c07e9}, - {0x2891425503b11f, 0x08781030579fea, - 0xf5426ba5cc9674, 0x1e28ebf18562bc}, - {1, 0, 0, 0}}, - {{0x9f31997cc864eb, 0x06cd91d28b5e4c, - 0xff17036691a973, 0xf1aef351497c58}, - {0xdd1f2d600564ff, 0xdead073b1402db, - 0x74a684435bd693, 0xeea7471f962558}, - {1, 0, 0, 0}}}, -{{{0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31}, - {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d}, - {1, 0, 0, 0}}, - {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3}, - {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a}, - {1, 0, 0, 0}}, - {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33}, - {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100}, - {1, 0, 0, 0}}, - {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5}, - {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea}, - {1, 0, 0, 0}}, - {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be}, - {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51}, - {1, 0, 0, 0}}, - {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1}, - {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb}, - {1, 0, 0, 0}}, - {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233}, - {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def}, - {1, 0, 0, 0}}, - {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae}, - {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45}, - {1, 0, 0, 0}}, - {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e}, - {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb}, - {1, 0, 0, 0}}, - {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de}, - {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3}, - {1, 0, 0, 0}}, - {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05}, - {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58}, - {1, 0, 0, 0}}, - {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb}, - {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0}, - {1, 0, 0, 0}}, - {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9}, - {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea}, - {1, 0, 0, 0}}, - {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba}, - {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405}, - {1, 0, 0, 0}}, - {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e}, - {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e}, - {1, 0, 0, 0}}} -}; - -/* Precomputation for the group generator. */ -typedef struct { - felem g_pre_comp[2][16][3]; - int references; -} NISTP224_PRE_COMP; - -const EC_METHOD *EC_GFp_nistp224_method(void) -{ - static const EC_METHOD ret = { - EC_FLAGS_DEFAULT_OCT, - NID_X9_62_prime_field, - ec_GFp_nistp224_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_nist_group_copy, - ec_GFp_nistp224_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_nistp224_point_get_affine_coordinates, - 0 /* point_set_compressed_coordinates */ , - 0 /* point2oct */ , - 0 /* oct2point */ , - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - ec_GFp_nistp224_points_mul, - ec_GFp_nistp224_precompute_mult, - ec_GFp_nistp224_have_precompute_mult, - ec_GFp_nist_field_mul, - ec_GFp_nist_field_sqr, - 0 /* field_div */ , - 0 /* field_encode */ , - 0 /* field_decode */ , - 0 /* field_set_to_one */ - }; - - return &ret; -} - -/* - * Helper functions to convert field elements to/from internal representation - */ -static void bin28_to_felem(felem out, const u8 in[28]) -{ - out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff; - out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff; - out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff; - out[3] = (*((const uint64_t *)(in+20))) >> 8; -} - -static void felem_to_bin28(u8 out[28], const felem in) -{ - unsigned i; - for (i = 0; i < 7; ++i) { - out[i] = in[0] >> (8 * i); - out[i + 7] = in[1] >> (8 * i); - out[i + 14] = in[2] >> (8 * i); - out[i + 21] = in[3] >> (8 * i); - } -} - -/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ -static void flip_endian(u8 *out, const u8 *in, unsigned len) -{ - unsigned i; - for (i = 0; i < len; ++i) - out[i] = in[len - 1 - i]; -} - -/* From OpenSSL BIGNUM to internal representation */ -static int BN_to_felem(felem out, const BIGNUM *bn) -{ - felem_bytearray b_in; - felem_bytearray b_out; - unsigned num_bytes; - - /* BN_bn2bin eats leading zeroes */ - memset(b_out, 0, sizeof(b_out)); - num_bytes = BN_num_bytes(bn); - if (num_bytes > sizeof(b_out)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } - if (BN_is_negative(bn)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } - num_bytes = BN_bn2bin(bn, b_in); - flip_endian(b_out, b_in, num_bytes); - bin28_to_felem(out, b_out); - return 1; -} - -/* From internal representation to OpenSSL BIGNUM */ -static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) -{ - felem_bytearray b_in, b_out; - felem_to_bin28(b_in, in); - flip_endian(b_out, b_in, sizeof(b_out)); - return BN_bin2bn(b_out, sizeof(b_out), out); -} - -/******************************************************************************/ -/*- - * FIELD OPERATIONS - * - * Field operations, using the internal representation of field elements. - * NB! These operations are specific to our point multiplication and cannot be - * expected to be correct in general - e.g., multiplication with a large scalar - * will cause an overflow. - * - */ - -static void felem_one(felem out) -{ - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; -} - -static void felem_assign(felem out, const felem in) -{ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -/* Sum two field elements: out += in */ -static void felem_sum(felem out, const felem in) -{ - out[0] += in[0]; - out[1] += in[1]; - out[2] += in[2]; - out[3] += in[3]; -} - -/* Get negative value: out = -in */ -/* Assumes in[i] < 2^57 */ -static void felem_neg(felem out, const felem in) -{ - static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2); - static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2); - static const limb two58m42m2 = (((limb) 1) << 58) - - (((limb) 1) << 42) - (((limb) 1) << 2); - - /* Set to 0 mod 2^224-2^96+1 to ensure out > in */ - out[0] = two58p2 - in[0]; - out[1] = two58m42m2 - in[1]; - out[2] = two58m2 - in[2]; - out[3] = two58m2 - in[3]; -} - -/* Subtract field elements: out -= in */ -/* Assumes in[i] < 2^57 */ -static void felem_diff(felem out, const felem in) -{ - static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2); - static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2); - static const limb two58m42m2 = (((limb) 1) << 58) - - (((limb) 1) << 42) - (((limb) 1) << 2); - - /* Add 0 mod 2^224-2^96+1 to ensure out > in */ - out[0] += two58p2; - out[1] += two58m42m2; - out[2] += two58m2; - out[3] += two58m2; - - out[0] -= in[0]; - out[1] -= in[1]; - out[2] -= in[2]; - out[3] -= in[3]; -} - -/* Subtract in unreduced 128-bit mode: out -= in */ -/* Assumes in[i] < 2^119 */ -static void widefelem_diff(widefelem out, const widefelem in) -{ - static const widelimb two120 = ((widelimb) 1) << 120; - static const widelimb two120m64 = (((widelimb) 1) << 120) - - (((widelimb) 1) << 64); - static const widelimb two120m104m64 = (((widelimb) 1) << 120) - - (((widelimb) 1) << 104) - (((widelimb) 1) << 64); - - /* Add 0 mod 2^224-2^96+1 to ensure out > in */ - out[0] += two120; - out[1] += two120m64; - out[2] += two120m64; - out[3] += two120; - out[4] += two120m104m64; - out[5] += two120m64; - out[6] += two120m64; - - out[0] -= in[0]; - out[1] -= in[1]; - out[2] -= in[2]; - out[3] -= in[3]; - out[4] -= in[4]; - out[5] -= in[5]; - out[6] -= in[6]; -} - -/* Subtract in mixed mode: out128 -= in64 */ -/* in[i] < 2^63 */ -static void felem_diff_128_64(widefelem out, const felem in) -{ - static const widelimb two64p8 = (((widelimb) 1) << 64) + - (((widelimb) 1) << 8); - static const widelimb two64m8 = (((widelimb) 1) << 64) - - (((widelimb) 1) << 8); - static const widelimb two64m48m8 = (((widelimb) 1) << 64) - - (((widelimb) 1) << 48) - (((widelimb) 1) << 8); - - /* Add 0 mod 2^224-2^96+1 to ensure out > in */ - out[0] += two64p8; - out[1] += two64m48m8; - out[2] += two64m8; - out[3] += two64m8; - - out[0] -= in[0]; - out[1] -= in[1]; - out[2] -= in[2]; - out[3] -= in[3]; -} - -/* - * Multiply a field element by a scalar: out = out * scalar The scalars we - * actually use are small, so results fit without overflow - */ -static void felem_scalar(felem out, const limb scalar) -{ - out[0] *= scalar; - out[1] *= scalar; - out[2] *= scalar; - out[3] *= scalar; -} - -/* - * Multiply an unreduced field element by a scalar: out = out * scalar The - * scalars we actually use are small, so results fit without overflow - */ -static void widefelem_scalar(widefelem out, const widelimb scalar) -{ - out[0] *= scalar; - out[1] *= scalar; - out[2] *= scalar; - out[3] *= scalar; - out[4] *= scalar; - out[5] *= scalar; - out[6] *= scalar; -} - -/* Square a field element: out = in^2 */ -static void felem_square(widefelem out, const felem in) -{ - limb tmp0, tmp1, tmp2; - tmp0 = 2 * in[0]; - tmp1 = 2 * in[1]; - tmp2 = 2 * in[2]; - out[0] = ((widelimb) in[0]) * in[0]; - out[1] = ((widelimb) in[0]) * tmp1; - out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1]; - out[3] = ((widelimb) in[3]) * tmp0 + ((widelimb) in[1]) * tmp2; - out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2]; - out[5] = ((widelimb) in[3]) * tmp2; - out[6] = ((widelimb) in[3]) * in[3]; -} - -/* Multiply two field elements: out = in1 * in2 */ -static void felem_mul(widefelem out, const felem in1, const felem in2) -{ - out[0] = ((widelimb) in1[0]) * in2[0]; - out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0]; - out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] + - ((widelimb) in1[2]) * in2[0]; - out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] + - ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0]; - out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] + - ((widelimb) in1[3]) * in2[1]; - out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2]; - out[6] = ((widelimb) in1[3]) * in2[3]; -} - -/*- - * Reduce seven 128-bit coefficients to four 64-bit coefficients. - * Requires in[i] < 2^126, - * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */ -static void felem_reduce(felem out, const widefelem in) -{ - static const widelimb two127p15 = (((widelimb) 1) << 127) + - (((widelimb) 1) << 15); - static const widelimb two127m71 = (((widelimb) 1) << 127) - - (((widelimb) 1) << 71); - static const widelimb two127m71m55 = (((widelimb) 1) << 127) - - (((widelimb) 1) << 71) - (((widelimb) 1) << 55); - widelimb output[5]; - - /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */ - output[0] = in[0] + two127p15; - output[1] = in[1] + two127m71m55; - output[2] = in[2] + two127m71; - output[3] = in[3]; - output[4] = in[4]; - - /* Eliminate in[4], in[5], in[6] */ - output[4] += in[6] >> 16; - output[3] += (in[6] & 0xffff) << 40; - output[2] -= in[6]; - - output[3] += in[5] >> 16; - output[2] += (in[5] & 0xffff) << 40; - output[1] -= in[5]; - - output[2] += output[4] >> 16; - output[1] += (output[4] & 0xffff) << 40; - output[0] -= output[4]; - - /* Carry 2 -> 3 -> 4 */ - output[3] += output[2] >> 56; - output[2] &= 0x00ffffffffffffff; - - output[4] = output[3] >> 56; - output[3] &= 0x00ffffffffffffff; - - /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */ - - /* Eliminate output[4] */ - output[2] += output[4] >> 16; - /* output[2] < 2^56 + 2^56 = 2^57 */ - output[1] += (output[4] & 0xffff) << 40; - output[0] -= output[4]; - - /* Carry 0 -> 1 -> 2 -> 3 */ - output[1] += output[0] >> 56; - out[0] = output[0] & 0x00ffffffffffffff; - - output[2] += output[1] >> 56; - /* output[2] < 2^57 + 2^72 */ - out[1] = output[1] & 0x00ffffffffffffff; - output[3] += output[2] >> 56; - /* output[3] <= 2^56 + 2^16 */ - out[2] = output[2] & 0x00ffffffffffffff; - - /*- - * out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, - * out[3] <= 2^56 + 2^16 (due to final carry), - * so out < 2*p - */ - out[3] = output[3]; -} - -static void felem_square_reduce(felem out, const felem in) -{ - widefelem tmp; - felem_square(tmp, in); - felem_reduce(out, tmp); -} - -static void felem_mul_reduce(felem out, const felem in1, const felem in2) -{ - widefelem tmp; - felem_mul(tmp, in1, in2); - felem_reduce(out, tmp); -} - -/* - * Reduce to unique minimal representation. Requires 0 <= in < 2*p (always - * call felem_reduce first) - */ -static void felem_contract(felem out, const felem in) -{ - static const int64_t two56 = ((limb) 1) << 56; - /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */ - /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */ - int64_t tmp[4], a; - tmp[0] = in[0]; - tmp[1] = in[1]; - tmp[2] = in[2]; - tmp[3] = in[3]; - /* Case 1: a = 1 iff in >= 2^224 */ - a = (in[3] >> 56); - tmp[0] -= a; - tmp[1] += a << 40; - tmp[3] &= 0x00ffffffffffffff; - /* - * Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 - * and the lower part is non-zero - */ - a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) | - (((int64_t) (in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63); - a &= 0x00ffffffffffffff; - /* turn a into an all-one mask (if a = 0) or an all-zero mask */ - a = (a - 1) >> 63; - /* subtract 2^224 - 2^96 + 1 if a is all-one */ - tmp[3] &= a ^ 0xffffffffffffffff; - tmp[2] &= a ^ 0xffffffffffffffff; - tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff; - tmp[0] -= 1 & a; - - /* - * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be - * non-zero, so we only need one step - */ - a = tmp[0] >> 63; - tmp[0] += two56 & a; - tmp[1] -= 1 & a; - - /* carry 1 -> 2 -> 3 */ - tmp[2] += tmp[1] >> 56; - tmp[1] &= 0x00ffffffffffffff; - - tmp[3] += tmp[2] >> 56; - tmp[2] &= 0x00ffffffffffffff; - - /* Now 0 <= out < p */ - out[0] = tmp[0]; - out[1] = tmp[1]; - out[2] = tmp[2]; - out[3] = tmp[3]; -} - -/* - * Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field - * elements are reduced to in < 2^225, so we only need to check three cases: - * 0, 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2 - */ -static limb felem_is_zero(const felem in) -{ - limb zero, two224m96p1, two225m97p2; - - zero = in[0] | in[1] | in[2] | in[3]; - zero = (((int64_t) (zero) - 1) >> 63) & 1; - two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) - | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff); - two224m96p1 = (((int64_t) (two224m96p1) - 1) >> 63) & 1; - two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) - | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff); - two225m97p2 = (((int64_t) (two225m97p2) - 1) >> 63) & 1; - return (zero | two224m96p1 | two225m97p2); -} - -static int felem_is_zero_int(const void *in) -{ - return (int)(felem_is_zero(in) & ((limb) 1)); -} - -/* Invert a field element */ -/* Computation chain copied from djb's code */ -static void felem_inv(felem out, const felem in) -{ - felem ftmp, ftmp2, ftmp3, ftmp4; - widefelem tmp; - unsigned i; - - felem_square(tmp, in); - felem_reduce(ftmp, tmp); /* 2 */ - felem_mul(tmp, in, ftmp); - felem_reduce(ftmp, tmp); /* 2^2 - 1 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^3 - 2 */ - felem_mul(tmp, in, ftmp); - felem_reduce(ftmp, tmp); /* 2^3 - 1 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp2, tmp); /* 2^4 - 2 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); /* 2^5 - 4 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); /* 2^6 - 8 */ - felem_mul(tmp, ftmp2, ftmp); - felem_reduce(ftmp, tmp); /* 2^6 - 1 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp2, tmp); /* 2^7 - 2 */ - for (i = 0; i < 5; ++i) { /* 2^12 - 2^6 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); - } - felem_mul(tmp, ftmp2, ftmp); - felem_reduce(ftmp2, tmp); /* 2^12 - 1 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^13 - 2 */ - for (i = 0; i < 11; ++i) { /* 2^24 - 2^12 */ - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); - } - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp2, tmp); /* 2^24 - 1 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^25 - 2 */ - for (i = 0; i < 23; ++i) { /* 2^48 - 2^24 */ - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); - } - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^48 - 1 */ - felem_square(tmp, ftmp3); - felem_reduce(ftmp4, tmp); /* 2^49 - 2 */ - for (i = 0; i < 47; ++i) { /* 2^96 - 2^48 */ - felem_square(tmp, ftmp4); - felem_reduce(ftmp4, tmp); - } - felem_mul(tmp, ftmp3, ftmp4); - felem_reduce(ftmp3, tmp); /* 2^96 - 1 */ - felem_square(tmp, ftmp3); - felem_reduce(ftmp4, tmp); /* 2^97 - 2 */ - for (i = 0; i < 23; ++i) { /* 2^120 - 2^24 */ - felem_square(tmp, ftmp4); - felem_reduce(ftmp4, tmp); - } - felem_mul(tmp, ftmp2, ftmp4); - felem_reduce(ftmp2, tmp); /* 2^120 - 1 */ - for (i = 0; i < 6; ++i) { /* 2^126 - 2^6 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); - } - felem_mul(tmp, ftmp2, ftmp); - felem_reduce(ftmp, tmp); /* 2^126 - 1 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^127 - 2 */ - felem_mul(tmp, ftmp, in); - felem_reduce(ftmp, tmp); /* 2^127 - 1 */ - for (i = 0; i < 97; ++i) { /* 2^224 - 2^97 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); - } - felem_mul(tmp, ftmp, ftmp3); - felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */ -} - -/* - * Copy in constant time: if icopy == 1, copy in to out, if icopy == 0, copy - * out to itself. - */ -static void copy_conditional(felem out, const felem in, limb icopy) -{ - unsigned i; - /* - * icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one - */ - const limb copy = -icopy; - for (i = 0; i < 4; ++i) { - const limb tmp = copy & (in[i] ^ out[i]); - out[i] ^= tmp; - } -} - -/******************************************************************************/ -/*- - * ELLIPTIC CURVE POINT OPERATIONS - * - * Points are represented in Jacobian projective coordinates: - * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3), - * or to the point at infinity if Z == 0. - * - */ - -/*- - * Double an elliptic curve point: - * (X', Y', Z') = 2 * (X, Y, Z), where - * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2 - * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2 - * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z - * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed, - * while x_out == y_in is not (maybe this works, but it's not tested). - */ -static void -point_double(felem x_out, felem y_out, felem z_out, - const felem x_in, const felem y_in, const felem z_in) -{ - widefelem tmp, tmp2; - felem delta, gamma, beta, alpha, ftmp, ftmp2; - - felem_assign(ftmp, x_in); - felem_assign(ftmp2, x_in); - - /* delta = z^2 */ - felem_square(tmp, z_in); - felem_reduce(delta, tmp); - - /* gamma = y^2 */ - felem_square(tmp, y_in); - felem_reduce(gamma, tmp); - - /* beta = x*gamma */ - felem_mul(tmp, x_in, gamma); - felem_reduce(beta, tmp); - - /* alpha = 3*(x-delta)*(x+delta) */ - felem_diff(ftmp, delta); - /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */ - felem_sum(ftmp2, delta); - /* ftmp2[i] < 2^57 + 2^57 = 2^58 */ - felem_scalar(ftmp2, 3); - /* ftmp2[i] < 3 * 2^58 < 2^60 */ - felem_mul(tmp, ftmp, ftmp2); - /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */ - felem_reduce(alpha, tmp); - - /* x' = alpha^2 - 8*beta */ - felem_square(tmp, alpha); - /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ - felem_assign(ftmp, beta); - felem_scalar(ftmp, 8); - /* ftmp[i] < 8 * 2^57 = 2^60 */ - felem_diff_128_64(tmp, ftmp); - /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ - felem_reduce(x_out, tmp); - - /* z' = (y + z)^2 - gamma - delta */ - felem_sum(delta, gamma); - /* delta[i] < 2^57 + 2^57 = 2^58 */ - felem_assign(ftmp, y_in); - felem_sum(ftmp, z_in); - /* ftmp[i] < 2^57 + 2^57 = 2^58 */ - felem_square(tmp, ftmp); - /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */ - felem_diff_128_64(tmp, delta); - /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */ - felem_reduce(z_out, tmp); - - /* y' = alpha*(4*beta - x') - 8*gamma^2 */ - felem_scalar(beta, 4); - /* beta[i] < 4 * 2^57 = 2^59 */ - felem_diff(beta, x_out); - /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */ - felem_mul(tmp, alpha, beta); - /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */ - felem_square(tmp2, gamma); - /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */ - widefelem_scalar(tmp2, 8); - /* tmp2[i] < 8 * 2^116 = 2^119 */ - widefelem_diff(tmp, tmp2); - /* tmp[i] < 2^119 + 2^120 < 2^121 */ - felem_reduce(y_out, tmp); -} - -/*- - * Add two elliptic curve points: - * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where - * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 - - * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) - - * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3 - * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2) - * - * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0. - */ - -/* - * This function is not entirely constant-time: it includes a branch for - * checking whether the two input points are equal, (while not equal to the - * point at infinity). This case never happens during single point - * multiplication, so there is no timing leak for ECDH or ECDSA signing. - */ -static void point_add(felem x3, felem y3, felem z3, - const felem x1, const felem y1, const felem z1, - const int mixed, const felem x2, const felem y2, - const felem z2) -{ - felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out; - widefelem tmp, tmp2; - limb z1_is_zero, z2_is_zero, x_equal, y_equal; - - if (!mixed) { - /* ftmp2 = z2^2 */ - felem_square(tmp, z2); - felem_reduce(ftmp2, tmp); - - /* ftmp4 = z2^3 */ - felem_mul(tmp, ftmp2, z2); - felem_reduce(ftmp4, tmp); - - /* ftmp4 = z2^3*y1 */ - felem_mul(tmp2, ftmp4, y1); - felem_reduce(ftmp4, tmp2); - - /* ftmp2 = z2^2*x1 */ - felem_mul(tmp2, ftmp2, x1); - felem_reduce(ftmp2, tmp2); - } else { - /* - * We'll assume z2 = 1 (special case z2 = 0 is handled later) - */ - - /* ftmp4 = z2^3*y1 */ - felem_assign(ftmp4, y1); - - /* ftmp2 = z2^2*x1 */ - felem_assign(ftmp2, x1); - } - - /* ftmp = z1^2 */ - felem_square(tmp, z1); - felem_reduce(ftmp, tmp); - - /* ftmp3 = z1^3 */ - felem_mul(tmp, ftmp, z1); - felem_reduce(ftmp3, tmp); - - /* tmp = z1^3*y2 */ - felem_mul(tmp, ftmp3, y2); - /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ - - /* ftmp3 = z1^3*y2 - z2^3*y1 */ - felem_diff_128_64(tmp, ftmp4); - /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ - felem_reduce(ftmp3, tmp); - - /* tmp = z1^2*x2 */ - felem_mul(tmp, ftmp, x2); - /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ - - /* ftmp = z1^2*x2 - z2^2*x1 */ - felem_diff_128_64(tmp, ftmp2); - /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ - felem_reduce(ftmp, tmp); - - /* - * the formulae are incorrect if the points are equal so we check for - * this and do doubling if this happens - */ - x_equal = felem_is_zero(ftmp); - y_equal = felem_is_zero(ftmp3); - z1_is_zero = felem_is_zero(z1); - z2_is_zero = felem_is_zero(z2); - /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */ - if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { - point_double(x3, y3, z3, x1, y1, z1); - return; - } - - /* ftmp5 = z1*z2 */ - if (!mixed) { - felem_mul(tmp, z1, z2); - felem_reduce(ftmp5, tmp); - } else { - /* special case z2 = 0 is handled later */ - felem_assign(ftmp5, z1); - } - - /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */ - felem_mul(tmp, ftmp, ftmp5); - felem_reduce(z_out, tmp); - - /* ftmp = (z1^2*x2 - z2^2*x1)^2 */ - felem_assign(ftmp5, ftmp); - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); - - /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */ - felem_mul(tmp, ftmp, ftmp5); - felem_reduce(ftmp5, tmp); - - /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */ - felem_mul(tmp, ftmp2, ftmp); - felem_reduce(ftmp2, tmp); - - /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */ - felem_mul(tmp, ftmp4, ftmp5); - /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ - - /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */ - felem_square(tmp2, ftmp3); - /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */ - - /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */ - felem_diff_128_64(tmp2, ftmp5); - /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */ - - /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */ - felem_assign(ftmp5, ftmp2); - felem_scalar(ftmp5, 2); - /* ftmp5[i] < 2 * 2^57 = 2^58 */ - - /*- - * x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 - - * 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - */ - felem_diff_128_64(tmp2, ftmp5); - /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */ - felem_reduce(x_out, tmp2); - - /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */ - felem_diff(ftmp2, x_out); - /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */ - - /* - * tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) - */ - felem_mul(tmp2, ftmp3, ftmp2); - /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */ - - /*- - * y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) - - * z2^3*y1*(z1^2*x2 - z2^2*x1)^3 - */ - widefelem_diff(tmp2, tmp); - /* tmp2[i] < 2^118 + 2^120 < 2^121 */ - felem_reduce(y_out, tmp2); - - /* - * the result (x_out, y_out, z_out) is incorrect if one of the inputs is - * the point at infinity, so we need to check for this separately - */ - - /* - * if point 1 is at infinity, copy point 2 to output, and vice versa - */ - copy_conditional(x_out, x2, z1_is_zero); - copy_conditional(x_out, x1, z2_is_zero); - copy_conditional(y_out, y2, z1_is_zero); - copy_conditional(y_out, y1, z2_is_zero); - copy_conditional(z_out, z2, z1_is_zero); - copy_conditional(z_out, z1, z2_is_zero); - felem_assign(x3, x_out); - felem_assign(y3, y_out); - felem_assign(z3, z_out); -} - -/* - * select_point selects the |idx|th point from a precomputation table and - * copies it to out. - * The pre_comp array argument should be size of |size| argument - */ -static void select_point(const u64 idx, unsigned int size, - const felem pre_comp[][3], felem out[3]) -{ - unsigned i, j; - limb *outlimbs = &out[0][0]; - memset(outlimbs, 0, 3 * sizeof(felem)); - - for (i = 0; i < size; i++) { - const limb *inlimbs = &pre_comp[i][0][0]; - u64 mask = i ^ idx; - mask |= mask >> 4; - mask |= mask >> 2; - mask |= mask >> 1; - mask &= 1; - mask--; - for (j = 0; j < 4 * 3; j++) - outlimbs[j] |= inlimbs[j] & mask; - } -} - -/* get_bit returns the |i|th bit in |in| */ -static char get_bit(const felem_bytearray in, unsigned i) -{ - if (i >= 224) - return 0; - return (in[i >> 3] >> (i & 7)) & 1; -} - -/* - * Interleaved point multiplication using precomputed point multiples: The - * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars - * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the - * generator, using certain (large) precomputed multiples in g_pre_comp. - * Output point (X, Y, Z) is stored in x_out, y_out, z_out - */ -static void batch_mul(felem x_out, felem y_out, felem z_out, - const felem_bytearray scalars[], - const unsigned num_points, const u8 *g_scalar, - const int mixed, const felem pre_comp[][17][3], - const felem g_pre_comp[2][16][3]) -{ - int i, skip; - unsigned num; - unsigned gen_mul = (g_scalar != NULL); - felem nq[3], tmp[4]; - u64 bits; - u8 sign, digit; - - /* set nq to the point at infinity */ - memset(nq, 0, 3 * sizeof(felem)); - - /* - * Loop over all scalars msb-to-lsb, interleaving additions of multiples - * of the generator (two in each of the last 28 rounds) and additions of - * other points multiples (every 5th round). - */ - skip = 1; /* save two point operations in the first - * round */ - for (i = (num_points ? 220 : 27); i >= 0; --i) { - /* double */ - if (!skip) - point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); - - /* add multiples of the generator */ - if (gen_mul && (i <= 27)) { - /* first, look 28 bits upwards */ - bits = get_bit(g_scalar, i + 196) << 3; - bits |= get_bit(g_scalar, i + 140) << 2; - bits |= get_bit(g_scalar, i + 84) << 1; - bits |= get_bit(g_scalar, i + 28); - /* select the point to add, in constant time */ - select_point(bits, 16, g_pre_comp[1], tmp); - - if (!skip) { - /* value 1 below is argument for "mixed" */ - point_add(nq[0], nq[1], nq[2], - nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); - } else { - memcpy(nq, tmp, 3 * sizeof(felem)); - skip = 0; - } - - /* second, look at the current position */ - bits = get_bit(g_scalar, i + 168) << 3; - bits |= get_bit(g_scalar, i + 112) << 2; - bits |= get_bit(g_scalar, i + 56) << 1; - bits |= get_bit(g_scalar, i); - /* select the point to add, in constant time */ - select_point(bits, 16, g_pre_comp[0], tmp); - point_add(nq[0], nq[1], nq[2], - nq[0], nq[1], nq[2], - 1 /* mixed */ , tmp[0], tmp[1], tmp[2]); - } - - /* do other additions every 5 doublings */ - if (num_points && (i % 5 == 0)) { - /* loop over all scalars */ - for (num = 0; num < num_points; ++num) { - bits = get_bit(scalars[num], i + 4) << 5; - bits |= get_bit(scalars[num], i + 3) << 4; - bits |= get_bit(scalars[num], i + 2) << 3; - bits |= get_bit(scalars[num], i + 1) << 2; - bits |= get_bit(scalars[num], i) << 1; - bits |= get_bit(scalars[num], i - 1); - ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); - - /* select the point to add or subtract */ - select_point(digit, 17, pre_comp[num], tmp); - felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative - * point */ - copy_conditional(tmp[1], tmp[3], sign); - - if (!skip) { - point_add(nq[0], nq[1], nq[2], - nq[0], nq[1], nq[2], - mixed, tmp[0], tmp[1], tmp[2]); - } else { - memcpy(nq, tmp, 3 * sizeof(felem)); - skip = 0; - } - } - } - } - felem_assign(x_out, nq[0]); - felem_assign(y_out, nq[1]); - felem_assign(z_out, nq[2]); -} - -/******************************************************************************/ -/* - * FUNCTIONS TO MANAGE PRECOMPUTATION - */ - -static NISTP224_PRE_COMP *nistp224_pre_comp_new() -{ - NISTP224_PRE_COMP *ret = NULL; - ret = (NISTP224_PRE_COMP *) OPENSSL_malloc(sizeof(*ret)); - if (!ret) { - ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); - return ret; - } - memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); - ret->references = 1; - return ret; -} - -static void *nistp224_pre_comp_dup(void *src_) -{ - NISTP224_PRE_COMP *src = src_; - - /* no need to actually copy, these objects never change! */ - CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); - - return src_; -} - -static void nistp224_pre_comp_free(void *pre_) -{ - int i; - NISTP224_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - OPENSSL_free(pre); -} - -static void nistp224_pre_comp_clear_free(void *pre_) -{ - int i; - NISTP224_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - OPENSSL_cleanse(pre, sizeof(*pre)); - OPENSSL_free(pre); -} - -/******************************************************************************/ -/* - * OPENSSL EC_METHOD FUNCTIONS - */ - -int ec_GFp_nistp224_group_init(EC_GROUP *group) -{ - int ret; - ret = ec_GFp_simple_group_init(group); - group->a_is_minus3 = 1; - return ret; -} - -int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, - BN_CTX *ctx) -{ - int ret = 0; - BN_CTX *new_ctx = NULL; - BIGNUM *curve_p, *curve_a, *curve_b; - - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((curve_p = BN_CTX_get(ctx)) == NULL) || - ((curve_a = BN_CTX_get(ctx)) == NULL) || - ((curve_b = BN_CTX_get(ctx)) == NULL)) - goto err; - BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p); - BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a); - BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b); - if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { - ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, - EC_R_WRONG_CURVE_PARAMETERS); - goto err; - } - group->field_mod_func = BN_nist_mod_224; - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -/* - * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = - * (X/Z^2, Y/Z^3) - */ -int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) -{ - felem z1, z2, x_in, y_in, x_out, y_out; - widefelem tmp; - - if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); - return 0; - } - if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || - (!BN_to_felem(z1, &point->Z))) - return 0; - felem_inv(z2, z1); - felem_square(tmp, z2); - felem_reduce(z1, tmp); - felem_mul(tmp, x_in, z1); - felem_reduce(x_in, tmp); - felem_contract(x_out, x_in); - if (x != NULL) { - if (!felem_to_BN(x, x_out)) { - ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); - return 0; - } - } - felem_mul(tmp, z1, z2); - felem_reduce(z1, tmp); - felem_mul(tmp, y_in, z1); - felem_reduce(y_in, tmp); - felem_contract(y_out, y_in); - if (y != NULL) { - if (!felem_to_BN(y, y_out)) { - ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); - return 0; - } - } - return 1; -} - -static void make_points_affine(size_t num, felem points[ /* num */ ][3], - felem tmp_felems[ /* num+1 */ ]) -{ - /* - * Runs in constant time, unless an input is the point at infinity (which - * normally shouldn't happen). - */ - ec_GFp_nistp_points_make_affine_internal(num, - points, - sizeof(felem), - tmp_felems, - (void (*)(void *))felem_one, - felem_is_zero_int, - (void (*)(void *, const void *)) - felem_assign, - (void (*)(void *, const void *)) - felem_square_reduce, (void (*) - (void *, - const void - *, - const void - *)) - felem_mul_reduce, - (void (*)(void *, const void *)) - felem_inv, - (void (*)(void *, const void *)) - felem_contract); -} - -/* - * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL - * values Result is stored in r (r can equal one of the inputs). - */ -int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) -{ - int ret = 0; - int j; - unsigned i; - int mixed = 0; - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y, *z, *tmp_scalar; - felem_bytearray g_secret; - felem_bytearray *secrets = NULL; - felem(*pre_comp)[17][3] = NULL; - felem *tmp_felems = NULL; - felem_bytearray tmp; - unsigned num_bytes; - int have_pre_comp = 0; - size_t num_points = num; - felem x_in, y_in, z_in, x_out, y_out, z_out; - NISTP224_PRE_COMP *pre = NULL; - const felem(*g_pre_comp)[16][3] = NULL; - EC_POINT *generator = NULL; - const EC_POINT *p = NULL; - const BIGNUM *p_scalar = NULL; - - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((x = BN_CTX_get(ctx)) == NULL) || - ((y = BN_CTX_get(ctx)) == NULL) || - ((z = BN_CTX_get(ctx)) == NULL) || - ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) - goto err; - - if (scalar != NULL) { - pre = EC_EX_DATA_get_data(group->extra_data, - nistp224_pre_comp_dup, - nistp224_pre_comp_free, - nistp224_pre_comp_clear_free); - if (pre) - /* we have precomputation, try to use it */ - g_pre_comp = (const felem(*)[16][3])pre->g_pre_comp; - else - /* try to use the standard precomputation */ - g_pre_comp = &gmul[0]; - generator = EC_POINT_new(group); - if (generator == NULL) - goto err; - /* get the generator from precomputation */ - if (!felem_to_BN(x, g_pre_comp[0][1][0]) || - !felem_to_BN(y, g_pre_comp[0][1][1]) || - !felem_to_BN(z, g_pre_comp[0][1][2])) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - if (!EC_POINT_set_Jprojective_coordinates_GFp(group, - generator, x, y, z, - ctx)) - goto err; - if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) - /* precomputation matches generator */ - have_pre_comp = 1; - else - /* - * we don't have valid precomputation: treat the generator as a - * random point - */ - num_points = num_points + 1; - } - - if (num_points > 0) { - if (num_points >= 3) { - /* - * unless we precompute multiples for just one or two points, - * converting those into affine form is time well spent - */ - mixed = 1; - } - secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); - pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem)); - if (mixed) - tmp_felems = - OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem)); - if ((secrets == NULL) || (pre_comp == NULL) - || (mixed && (tmp_felems == NULL))) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * we treat NULL scalars as 0, and NULL points as points at infinity, - * i.e., they contribute nothing to the linear combination - */ - memset(secrets, 0, num_points * sizeof(felem_bytearray)); - memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem)); - for (i = 0; i < num_points; ++i) { - if (i == num) - /* the generator */ - { - p = EC_GROUP_get0_generator(group); - p_scalar = scalar; - } else - /* the i^th point */ - { - p = points[i]; - p_scalar = scalars[i]; - } - if ((p_scalar != NULL) && (p != NULL)) { - /* reduce scalar to 0 <= scalar < 2^224 */ - if ((BN_num_bits(p_scalar) > 224) - || (BN_is_negative(p_scalar))) { - /* - * this is an unusual input, and we don't guarantee - * constant-timeness - */ - if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(p_scalar, tmp); - flip_endian(secrets[i], tmp, num_bytes); - /* precompute multiples */ - if ((!BN_to_felem(x_out, &p->X)) || - (!BN_to_felem(y_out, &p->Y)) || - (!BN_to_felem(z_out, &p->Z))) - goto err; - felem_assign(pre_comp[i][1][0], x_out); - felem_assign(pre_comp[i][1][1], y_out); - felem_assign(pre_comp[i][1][2], z_out); - for (j = 2; j <= 16; ++j) { - if (j & 1) { - point_add(pre_comp[i][j][0], pre_comp[i][j][1], - pre_comp[i][j][2], pre_comp[i][1][0], - pre_comp[i][1][1], pre_comp[i][1][2], 0, - pre_comp[i][j - 1][0], - pre_comp[i][j - 1][1], - pre_comp[i][j - 1][2]); - } else { - point_double(pre_comp[i][j][0], pre_comp[i][j][1], - pre_comp[i][j][2], pre_comp[i][j / 2][0], - pre_comp[i][j / 2][1], - pre_comp[i][j / 2][2]); - } - } - } - } - if (mixed) - make_points_affine(num_points * 17, pre_comp[0], tmp_felems); - } - - /* the scalar for the generator */ - if ((scalar != NULL) && (have_pre_comp)) { - memset(g_secret, 0, sizeof(g_secret)); - /* reduce scalar to 0 <= scalar < 2^224 */ - if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar))) { - /* - * this is an unusual input, and we don't guarantee - * constant-timeness - */ - if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(scalar, tmp); - flip_endian(g_secret, tmp, num_bytes); - /* do the multiplication with generator precomputation */ - batch_mul(x_out, y_out, z_out, - (const felem_bytearray(*))secrets, num_points, - g_secret, - mixed, (const felem(*)[17][3])pre_comp, g_pre_comp); - } else - /* do the multiplication without generator precomputation */ - batch_mul(x_out, y_out, z_out, - (const felem_bytearray(*))secrets, num_points, - NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); - /* reduce the output to its unique minimal representation */ - felem_contract(x_in, x_out); - felem_contract(y_in, y_out); - felem_contract(z_in, z_out); - if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || - (!felem_to_BN(z, z_in))) { - ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); - - err: - BN_CTX_end(ctx); - if (generator != NULL) - EC_POINT_free(generator); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (secrets != NULL) - OPENSSL_free(secrets); - if (pre_comp != NULL) - OPENSSL_free(pre_comp); - if (tmp_felems != NULL) - OPENSSL_free(tmp_felems); - return ret; -} - -int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) -{ - int ret = 0; - NISTP224_PRE_COMP *pre = NULL; - int i, j; - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y; - EC_POINT *generator = NULL; - felem tmp_felems[32]; - - /* throw away old precomputation */ - EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup, - nistp224_pre_comp_free, - nistp224_pre_comp_clear_free); - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) - goto err; - /* get the generator */ - if (group->generator == NULL) - goto err; - generator = EC_POINT_new(group); - if (generator == NULL) - goto err; - BN_bin2bn(nistp224_curve_params[3], sizeof(felem_bytearray), x); - BN_bin2bn(nistp224_curve_params[4], sizeof(felem_bytearray), y); - if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) - goto err; - if ((pre = nistp224_pre_comp_new()) == NULL) - goto err; - /* - * if the generator is the standard one, use built-in precomputation - */ - if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { - memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); - goto done; - } - if ((!BN_to_felem(pre->g_pre_comp[0][1][0], &group->generator->X)) || - (!BN_to_felem(pre->g_pre_comp[0][1][1], &group->generator->Y)) || - (!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z))) - goto err; - /* - * compute 2^56*G, 2^112*G, 2^168*G for the first table, 2^28*G, 2^84*G, - * 2^140*G, 2^196*G for the second one - */ - for (i = 1; i <= 8; i <<= 1) { - point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], - pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0], - pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]); - for (j = 0; j < 27; ++j) { - point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], - pre->g_pre_comp[1][i][2], pre->g_pre_comp[1][i][0], - pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]); - } - if (i == 8) - break; - point_double(pre->g_pre_comp[0][2 * i][0], - pre->g_pre_comp[0][2 * i][1], - pre->g_pre_comp[0][2 * i][2], pre->g_pre_comp[1][i][0], - pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]); - for (j = 0; j < 27; ++j) { - point_double(pre->g_pre_comp[0][2 * i][0], - pre->g_pre_comp[0][2 * i][1], - pre->g_pre_comp[0][2 * i][2], - pre->g_pre_comp[0][2 * i][0], - pre->g_pre_comp[0][2 * i][1], - pre->g_pre_comp[0][2 * i][2]); - } - } - for (i = 0; i < 2; i++) { - /* g_pre_comp[i][0] is the point at infinity */ - memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0])); - /* the remaining multiples */ - /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */ - point_add(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], - pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0], - pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2], - 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], - pre->g_pre_comp[i][2][2]); - /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */ - point_add(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], - pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0], - pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], - 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], - pre->g_pre_comp[i][2][2]); - /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */ - point_add(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], - pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0], - pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], - 0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], - pre->g_pre_comp[i][4][2]); - /* - * 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G - */ - point_add(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], - pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0], - pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2], - 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], - pre->g_pre_comp[i][2][2]); - for (j = 1; j < 8; ++j) { - /* odd multiples: add G resp. 2^28*G */ - point_add(pre->g_pre_comp[i][2 * j + 1][0], - pre->g_pre_comp[i][2 * j + 1][1], - pre->g_pre_comp[i][2 * j + 1][2], - pre->g_pre_comp[i][2 * j][0], - pre->g_pre_comp[i][2 * j][1], - pre->g_pre_comp[i][2 * j][2], 0, - pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1], - pre->g_pre_comp[i][1][2]); - } - } - make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems); - - done: - if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup, - nistp224_pre_comp_free, - nistp224_pre_comp_clear_free)) - goto err; - ret = 1; - pre = NULL; - err: - BN_CTX_end(ctx); - if (generator != NULL) - EC_POINT_free(generator); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (pre) - nistp224_pre_comp_free(pre); - return ret; -} - -int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group) -{ - if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup, - nistp224_pre_comp_free, - nistp224_pre_comp_clear_free) - != NULL) - return 1; - else - return 0; -} - -#else -static void *dummy = &dummy; -#endif diff --git a/Sources/COpenSSL/ecp_nistp256.c b/Sources/COpenSSL/ecp_nistp256.c deleted file mode 100644 index bacb006a..00000000 --- a/Sources/COpenSSL/ecp_nistp256.c +++ /dev/null @@ -1,2369 +0,0 @@ -/* crypto/ec/ecp_nistp256.c */ -/* - * Written by Adam Langley (Google) for the OpenSSL project - */ -/* Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication - * - * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c. - * Otherwise based on Emilia's P224 work, which was inspired by my curve25519 - * work which got its smarts from Daniel J. Bernstein's work on the same. - */ - -#include "opensslconf.h" -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - -# ifndef OPENSSL_SYS_VMS -# include -# else -# include -# endif - -# include -# include "err.h" -# include "ec_lcl.h" - -# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) - /* even with gcc, the typedef won't work for 32-bit platforms */ -typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit - * platforms */ -typedef __int128_t int128_t; -# else -# error "Need GCC 3.1 or later to define type uint128_t" -# endif - -typedef uint8_t u8; -typedef uint32_t u32; -typedef uint64_t u64; - -/* - * The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We - * can serialise an element of this field into 32 bytes. We call this an - * felem_bytearray. - */ - -typedef u8 felem_bytearray[32]; - -/* - * These are the parameters of P256, taken from FIPS 186-3, page 86. These - * values are big-endian. - */ -static const felem_bytearray nistp256_curve_params[5] = { - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */ - {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, - 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, - 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, - 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b}, - {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */ - 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, - 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, - 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96}, - {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */ - 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, - 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, - 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5} -}; - -/*- - * The representation of field elements. - * ------------------------------------ - * - * We represent field elements with either four 128-bit values, eight 128-bit - * values, or four 64-bit values. The field element represented is: - * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p) - * or: - * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p) - * - * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits - * apart, but are 128-bits wide, the most significant bits of each limb overlap - * with the least significant bits of the next. - * - * A field element with four limbs is an 'felem'. One with eight limbs is a - * 'longfelem' - * - * A field element with four, 64-bit values is called a 'smallfelem'. Small - * values are used as intermediate values before multiplication. - */ - -# define NLIMBS 4 - -typedef uint128_t limb; -typedef limb felem[NLIMBS]; -typedef limb longfelem[NLIMBS * 2]; -typedef u64 smallfelem[NLIMBS]; - -/* This is the value of the prime as four 64-bit words, little-endian. */ -static const u64 kPrime[4] = - { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul }; -static const u64 bottom63bits = 0x7ffffffffffffffful; - -/* - * bin32_to_felem takes a little-endian byte array and converts it into felem - * form. This assumes that the CPU is little-endian. - */ -static void bin32_to_felem(felem out, const u8 in[32]) -{ - out[0] = *((u64 *)&in[0]); - out[1] = *((u64 *)&in[8]); - out[2] = *((u64 *)&in[16]); - out[3] = *((u64 *)&in[24]); -} - -/* - * smallfelem_to_bin32 takes a smallfelem and serialises into a little - * endian, 32 byte array. This assumes that the CPU is little-endian. - */ -static void smallfelem_to_bin32(u8 out[32], const smallfelem in) -{ - *((u64 *)&out[0]) = in[0]; - *((u64 *)&out[8]) = in[1]; - *((u64 *)&out[16]) = in[2]; - *((u64 *)&out[24]) = in[3]; -} - -/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ -static void flip_endian(u8 *out, const u8 *in, unsigned len) -{ - unsigned i; - for (i = 0; i < len; ++i) - out[i] = in[len - 1 - i]; -} - -/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ -static int BN_to_felem(felem out, const BIGNUM *bn) -{ - felem_bytearray b_in; - felem_bytearray b_out; - unsigned num_bytes; - - /* BN_bn2bin eats leading zeroes */ - memset(b_out, 0, sizeof(b_out)); - num_bytes = BN_num_bytes(bn); - if (num_bytes > sizeof(b_out)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } - if (BN_is_negative(bn)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } - num_bytes = BN_bn2bin(bn, b_in); - flip_endian(b_out, b_in, num_bytes); - bin32_to_felem(out, b_out); - return 1; -} - -/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ -static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in) -{ - felem_bytearray b_in, b_out; - smallfelem_to_bin32(b_in, in); - flip_endian(b_out, b_in, sizeof(b_out)); - return BN_bin2bn(b_out, sizeof(b_out), out); -} - -/*- - * Field operations - * ---------------- - */ - -static void smallfelem_one(smallfelem out) -{ - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; -} - -static void smallfelem_assign(smallfelem out, const smallfelem in) -{ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -static void felem_assign(felem out, const felem in) -{ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -/* felem_sum sets out = out + in. */ -static void felem_sum(felem out, const felem in) -{ - out[0] += in[0]; - out[1] += in[1]; - out[2] += in[2]; - out[3] += in[3]; -} - -/* felem_small_sum sets out = out + in. */ -static void felem_small_sum(felem out, const smallfelem in) -{ - out[0] += in[0]; - out[1] += in[1]; - out[2] += in[2]; - out[3] += in[3]; -} - -/* felem_scalar sets out = out * scalar */ -static void felem_scalar(felem out, const u64 scalar) -{ - out[0] *= scalar; - out[1] *= scalar; - out[2] *= scalar; - out[3] *= scalar; -} - -/* longfelem_scalar sets out = out * scalar */ -static void longfelem_scalar(longfelem out, const u64 scalar) -{ - out[0] *= scalar; - out[1] *= scalar; - out[2] *= scalar; - out[3] *= scalar; - out[4] *= scalar; - out[5] *= scalar; - out[6] *= scalar; - out[7] *= scalar; -} - -# define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9) -# define two105 (((limb)1) << 105) -# define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9) - -/* zero105 is 0 mod p */ -static const felem zero105 = - { two105m41m9, two105, two105m41p9, two105m41p9 }; - -/*- - * smallfelem_neg sets |out| to |-small| - * On exit: - * out[i] < out[i] + 2^105 - */ -static void smallfelem_neg(felem out, const smallfelem small) -{ - /* In order to prevent underflow, we subtract from 0 mod p. */ - out[0] = zero105[0] - small[0]; - out[1] = zero105[1] - small[1]; - out[2] = zero105[2] - small[2]; - out[3] = zero105[3] - small[3]; -} - -/*- - * felem_diff subtracts |in| from |out| - * On entry: - * in[i] < 2^104 - * On exit: - * out[i] < out[i] + 2^105 - */ -static void felem_diff(felem out, const felem in) -{ - /* - * In order to prevent underflow, we add 0 mod p before subtracting. - */ - out[0] += zero105[0]; - out[1] += zero105[1]; - out[2] += zero105[2]; - out[3] += zero105[3]; - - out[0] -= in[0]; - out[1] -= in[1]; - out[2] -= in[2]; - out[3] -= in[3]; -} - -# define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11) -# define two107 (((limb)1) << 107) -# define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11) - -/* zero107 is 0 mod p */ -static const felem zero107 = - { two107m43m11, two107, two107m43p11, two107m43p11 }; - -/*- - * An alternative felem_diff for larger inputs |in| - * felem_diff_zero107 subtracts |in| from |out| - * On entry: - * in[i] < 2^106 - * On exit: - * out[i] < out[i] + 2^107 - */ -static void felem_diff_zero107(felem out, const felem in) -{ - /* - * In order to prevent underflow, we add 0 mod p before subtracting. - */ - out[0] += zero107[0]; - out[1] += zero107[1]; - out[2] += zero107[2]; - out[3] += zero107[3]; - - out[0] -= in[0]; - out[1] -= in[1]; - out[2] -= in[2]; - out[3] -= in[3]; -} - -/*- - * longfelem_diff subtracts |in| from |out| - * On entry: - * in[i] < 7*2^67 - * On exit: - * out[i] < out[i] + 2^70 + 2^40 - */ -static void longfelem_diff(longfelem out, const longfelem in) -{ - static const limb two70m8p6 = - (((limb) 1) << 70) - (((limb) 1) << 8) + (((limb) 1) << 6); - static const limb two70p40 = (((limb) 1) << 70) + (((limb) 1) << 40); - static const limb two70 = (((limb) 1) << 70); - static const limb two70m40m38p6 = - (((limb) 1) << 70) - (((limb) 1) << 40) - (((limb) 1) << 38) + - (((limb) 1) << 6); - static const limb two70m6 = (((limb) 1) << 70) - (((limb) 1) << 6); - - /* add 0 mod p to avoid underflow */ - out[0] += two70m8p6; - out[1] += two70p40; - out[2] += two70; - out[3] += two70m40m38p6; - out[4] += two70m6; - out[5] += two70m6; - out[6] += two70m6; - out[7] += two70m6; - - /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */ - out[0] -= in[0]; - out[1] -= in[1]; - out[2] -= in[2]; - out[3] -= in[3]; - out[4] -= in[4]; - out[5] -= in[5]; - out[6] -= in[6]; - out[7] -= in[7]; -} - -# define two64m0 (((limb)1) << 64) - 1 -# define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1 -# define two64m46 (((limb)1) << 64) - (((limb)1) << 46) -# define two64m32 (((limb)1) << 64) - (((limb)1) << 32) - -/* zero110 is 0 mod p */ -static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 }; - -/*- - * felem_shrink converts an felem into a smallfelem. The result isn't quite - * minimal as the value may be greater than p. - * - * On entry: - * in[i] < 2^109 - * On exit: - * out[i] < 2^64 - */ -static void felem_shrink(smallfelem out, const felem in) -{ - felem tmp; - u64 a, b, mask; - u64 high, low; - static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */ - - /* Carry 2->3 */ - tmp[3] = zero110[3] + in[3] + ((u64)(in[2] >> 64)); - /* tmp[3] < 2^110 */ - - tmp[2] = zero110[2] + (u64)in[2]; - tmp[0] = zero110[0] + in[0]; - tmp[1] = zero110[1] + in[1]; - /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */ - - /* - * We perform two partial reductions where we eliminate the high-word of - * tmp[3]. We don't update the other words till the end. - */ - a = tmp[3] >> 64; /* a < 2^46 */ - tmp[3] = (u64)tmp[3]; - tmp[3] -= a; - tmp[3] += ((limb) a) << 32; - /* tmp[3] < 2^79 */ - - b = a; - a = tmp[3] >> 64; /* a < 2^15 */ - b += a; /* b < 2^46 + 2^15 < 2^47 */ - tmp[3] = (u64)tmp[3]; - tmp[3] -= a; - tmp[3] += ((limb) a) << 32; - /* tmp[3] < 2^64 + 2^47 */ - - /* - * This adjusts the other two words to complete the two partial - * reductions. - */ - tmp[0] += b; - tmp[1] -= (((limb) b) << 32); - - /* - * In order to make space in tmp[3] for the carry from 2 -> 3, we - * conditionally subtract kPrime if tmp[3] is large enough. - */ - high = (u64)(tmp[3] >> 64); - /* As tmp[3] < 2^65, high is either 1 or 0 */ - high = 0 - high; - /*- - * high is: - * all ones if the high word of tmp[3] is 1 - * all zeros if the high word of tmp[3] if 0 - */ - low = (u64)tmp[3]; - mask = 0 - (low >> 63); - /*- - * mask is: - * all ones if the MSB of low is 1 - * all zeros if the MSB of low if 0 - */ - low &= bottom63bits; - low -= kPrime3Test; - /* if low was greater than kPrime3Test then the MSB is zero */ - low = ~low; - low = 0 - (low >> 63); - /*- - * low is: - * all ones if low was > kPrime3Test - * all zeros if low was <= kPrime3Test - */ - mask = (mask & low) | high; - tmp[0] -= mask & kPrime[0]; - tmp[1] -= mask & kPrime[1]; - /* kPrime[2] is zero, so omitted */ - tmp[3] -= mask & kPrime[3]; - /* tmp[3] < 2**64 - 2**32 + 1 */ - - tmp[1] += ((u64)(tmp[0] >> 64)); - tmp[0] = (u64)tmp[0]; - tmp[2] += ((u64)(tmp[1] >> 64)); - tmp[1] = (u64)tmp[1]; - tmp[3] += ((u64)(tmp[2] >> 64)); - tmp[2] = (u64)tmp[2]; - /* tmp[i] < 2^64 */ - - out[0] = tmp[0]; - out[1] = tmp[1]; - out[2] = tmp[2]; - out[3] = tmp[3]; -} - -/* smallfelem_expand converts a smallfelem to an felem */ -static void smallfelem_expand(felem out, const smallfelem in) -{ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; -} - -/*- - * smallfelem_square sets |out| = |small|^2 - * On entry: - * small[i] < 2^64 - * On exit: - * out[i] < 7 * 2^64 < 2^67 - */ -static void smallfelem_square(longfelem out, const smallfelem small) -{ - limb a; - u64 high, low; - - a = ((uint128_t) small[0]) * small[0]; - low = a; - high = a >> 64; - out[0] = low; - out[1] = high; - - a = ((uint128_t) small[0]) * small[1]; - low = a; - high = a >> 64; - out[1] += low; - out[1] += low; - out[2] = high; - - a = ((uint128_t) small[0]) * small[2]; - low = a; - high = a >> 64; - out[2] += low; - out[2] *= 2; - out[3] = high; - - a = ((uint128_t) small[0]) * small[3]; - low = a; - high = a >> 64; - out[3] += low; - out[4] = high; - - a = ((uint128_t) small[1]) * small[2]; - low = a; - high = a >> 64; - out[3] += low; - out[3] *= 2; - out[4] += high; - - a = ((uint128_t) small[1]) * small[1]; - low = a; - high = a >> 64; - out[2] += low; - out[3] += high; - - a = ((uint128_t) small[1]) * small[3]; - low = a; - high = a >> 64; - out[4] += low; - out[4] *= 2; - out[5] = high; - - a = ((uint128_t) small[2]) * small[3]; - low = a; - high = a >> 64; - out[5] += low; - out[5] *= 2; - out[6] = high; - out[6] += high; - - a = ((uint128_t) small[2]) * small[2]; - low = a; - high = a >> 64; - out[4] += low; - out[5] += high; - - a = ((uint128_t) small[3]) * small[3]; - low = a; - high = a >> 64; - out[6] += low; - out[7] = high; -} - -/*- - * felem_square sets |out| = |in|^2 - * On entry: - * in[i] < 2^109 - * On exit: - * out[i] < 7 * 2^64 < 2^67 - */ -static void felem_square(longfelem out, const felem in) -{ - u64 small[4]; - felem_shrink(small, in); - smallfelem_square(out, small); -} - -/*- - * smallfelem_mul sets |out| = |small1| * |small2| - * On entry: - * small1[i] < 2^64 - * small2[i] < 2^64 - * On exit: - * out[i] < 7 * 2^64 < 2^67 - */ -static void smallfelem_mul(longfelem out, const smallfelem small1, - const smallfelem small2) -{ - limb a; - u64 high, low; - - a = ((uint128_t) small1[0]) * small2[0]; - low = a; - high = a >> 64; - out[0] = low; - out[1] = high; - - a = ((uint128_t) small1[0]) * small2[1]; - low = a; - high = a >> 64; - out[1] += low; - out[2] = high; - - a = ((uint128_t) small1[1]) * small2[0]; - low = a; - high = a >> 64; - out[1] += low; - out[2] += high; - - a = ((uint128_t) small1[0]) * small2[2]; - low = a; - high = a >> 64; - out[2] += low; - out[3] = high; - - a = ((uint128_t) small1[1]) * small2[1]; - low = a; - high = a >> 64; - out[2] += low; - out[3] += high; - - a = ((uint128_t) small1[2]) * small2[0]; - low = a; - high = a >> 64; - out[2] += low; - out[3] += high; - - a = ((uint128_t) small1[0]) * small2[3]; - low = a; - high = a >> 64; - out[3] += low; - out[4] = high; - - a = ((uint128_t) small1[1]) * small2[2]; - low = a; - high = a >> 64; - out[3] += low; - out[4] += high; - - a = ((uint128_t) small1[2]) * small2[1]; - low = a; - high = a >> 64; - out[3] += low; - out[4] += high; - - a = ((uint128_t) small1[3]) * small2[0]; - low = a; - high = a >> 64; - out[3] += low; - out[4] += high; - - a = ((uint128_t) small1[1]) * small2[3]; - low = a; - high = a >> 64; - out[4] += low; - out[5] = high; - - a = ((uint128_t) small1[2]) * small2[2]; - low = a; - high = a >> 64; - out[4] += low; - out[5] += high; - - a = ((uint128_t) small1[3]) * small2[1]; - low = a; - high = a >> 64; - out[4] += low; - out[5] += high; - - a = ((uint128_t) small1[2]) * small2[3]; - low = a; - high = a >> 64; - out[5] += low; - out[6] = high; - - a = ((uint128_t) small1[3]) * small2[2]; - low = a; - high = a >> 64; - out[5] += low; - out[6] += high; - - a = ((uint128_t) small1[3]) * small2[3]; - low = a; - high = a >> 64; - out[6] += low; - out[7] = high; -} - -/*- - * felem_mul sets |out| = |in1| * |in2| - * On entry: - * in1[i] < 2^109 - * in2[i] < 2^109 - * On exit: - * out[i] < 7 * 2^64 < 2^67 - */ -static void felem_mul(longfelem out, const felem in1, const felem in2) -{ - smallfelem small1, small2; - felem_shrink(small1, in1); - felem_shrink(small2, in2); - smallfelem_mul(out, small1, small2); -} - -/*- - * felem_small_mul sets |out| = |small1| * |in2| - * On entry: - * small1[i] < 2^64 - * in2[i] < 2^109 - * On exit: - * out[i] < 7 * 2^64 < 2^67 - */ -static void felem_small_mul(longfelem out, const smallfelem small1, - const felem in2) -{ - smallfelem small2; - felem_shrink(small2, in2); - smallfelem_mul(out, small1, small2); -} - -# define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4) -# define two100 (((limb)1) << 100) -# define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4) -/* zero100 is 0 mod p */ -static const felem zero100 = - { two100m36m4, two100, two100m36p4, two100m36p4 }; - -/*- - * Internal function for the different flavours of felem_reduce. - * felem_reduce_ reduces the higher coefficients in[4]-in[7]. - * On entry: - * out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7] - * out[1] >= in[7] + 2^32*in[4] - * out[2] >= in[5] + 2^32*in[5] - * out[3] >= in[4] + 2^32*in[5] + 2^32*in[6] - * On exit: - * out[0] <= out[0] + in[4] + 2^32*in[5] - * out[1] <= out[1] + in[5] + 2^33*in[6] - * out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7] - * out[3] <= out[3] + 2^32*in[4] + 3*in[7] - */ -static void felem_reduce_(felem out, const longfelem in) -{ - int128_t c; - /* combine common terms from below */ - c = in[4] + (in[5] << 32); - out[0] += c; - out[3] -= c; - - c = in[5] - in[7]; - out[1] += c; - out[2] -= c; - - /* the remaining terms */ - /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */ - out[1] -= (in[4] << 32); - out[3] += (in[4] << 32); - - /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */ - out[2] -= (in[5] << 32); - - /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */ - out[0] -= in[6]; - out[0] -= (in[6] << 32); - out[1] += (in[6] << 33); - out[2] += (in[6] * 2); - out[3] -= (in[6] << 32); - - /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */ - out[0] -= in[7]; - out[0] -= (in[7] << 32); - out[2] += (in[7] << 33); - out[3] += (in[7] * 3); -} - -/*- - * felem_reduce converts a longfelem into an felem. - * To be called directly after felem_square or felem_mul. - * On entry: - * in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64 - * in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64 - * On exit: - * out[i] < 2^101 - */ -static void felem_reduce(felem out, const longfelem in) -{ - out[0] = zero100[0] + in[0]; - out[1] = zero100[1] + in[1]; - out[2] = zero100[2] + in[2]; - out[3] = zero100[3] + in[3]; - - felem_reduce_(out, in); - - /*- - * out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0 - * out[1] > 2^100 - 2^64 - 7*2^96 > 0 - * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0 - * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0 - * - * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101 - * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101 - * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101 - * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101 - */ -} - -/*- - * felem_reduce_zero105 converts a larger longfelem into an felem. - * On entry: - * in[0] < 2^71 - * On exit: - * out[i] < 2^106 - */ -static void felem_reduce_zero105(felem out, const longfelem in) -{ - out[0] = zero105[0] + in[0]; - out[1] = zero105[1] + in[1]; - out[2] = zero105[2] + in[2]; - out[3] = zero105[3] + in[3]; - - felem_reduce_(out, in); - - /*- - * out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0 - * out[1] > 2^105 - 2^71 - 2^103 > 0 - * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0 - * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0 - * - * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106 - * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106 - * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106 - * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106 - */ -} - -/* - * subtract_u64 sets *result = *result - v and *carry to one if the - * subtraction underflowed. - */ -static void subtract_u64(u64 *result, u64 *carry, u64 v) -{ - uint128_t r = *result; - r -= v; - *carry = (r >> 64) & 1; - *result = (u64)r; -} - -/* - * felem_contract converts |in| to its unique, minimal representation. On - * entry: in[i] < 2^109 - */ -static void felem_contract(smallfelem out, const felem in) -{ - unsigned i; - u64 all_equal_so_far = 0, result = 0, carry; - - felem_shrink(out, in); - /* small is minimal except that the value might be > p */ - - all_equal_so_far--; - /* - * We are doing a constant time test if out >= kPrime. We need to compare - * each u64, from most-significant to least significant. For each one, if - * all words so far have been equal (m is all ones) then a non-equal - * result is the answer. Otherwise we continue. - */ - for (i = 3; i < 4; i--) { - u64 equal; - uint128_t a = ((uint128_t) kPrime[i]) - out[i]; - /* - * if out[i] > kPrime[i] then a will underflow and the high 64-bits - * will all be set. - */ - result |= all_equal_so_far & ((u64)(a >> 64)); - - /* - * if kPrime[i] == out[i] then |equal| will be all zeros and the - * decrement will make it all ones. - */ - equal = kPrime[i] ^ out[i]; - equal--; - equal &= equal << 32; - equal &= equal << 16; - equal &= equal << 8; - equal &= equal << 4; - equal &= equal << 2; - equal &= equal << 1; - equal = 0 - (equal >> 63); - - all_equal_so_far &= equal; - } - - /* - * if all_equal_so_far is still all ones then the two values are equal - * and so out >= kPrime is true. - */ - result |= all_equal_so_far; - - /* if out >= kPrime then we subtract kPrime. */ - subtract_u64(&out[0], &carry, result & kPrime[0]); - subtract_u64(&out[1], &carry, carry); - subtract_u64(&out[2], &carry, carry); - subtract_u64(&out[3], &carry, carry); - - subtract_u64(&out[1], &carry, result & kPrime[1]); - subtract_u64(&out[2], &carry, carry); - subtract_u64(&out[3], &carry, carry); - - subtract_u64(&out[2], &carry, result & kPrime[2]); - subtract_u64(&out[3], &carry, carry); - - subtract_u64(&out[3], &carry, result & kPrime[3]); -} - -static void smallfelem_square_contract(smallfelem out, const smallfelem in) -{ - longfelem longtmp; - felem tmp; - - smallfelem_square(longtmp, in); - felem_reduce(tmp, longtmp); - felem_contract(out, tmp); -} - -static void smallfelem_mul_contract(smallfelem out, const smallfelem in1, - const smallfelem in2) -{ - longfelem longtmp; - felem tmp; - - smallfelem_mul(longtmp, in1, in2); - felem_reduce(tmp, longtmp); - felem_contract(out, tmp); -} - -/*- - * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0 - * otherwise. - * On entry: - * small[i] < 2^64 - */ -static limb smallfelem_is_zero(const smallfelem small) -{ - limb result; - u64 is_p; - - u64 is_zero = small[0] | small[1] | small[2] | small[3]; - is_zero--; - is_zero &= is_zero << 32; - is_zero &= is_zero << 16; - is_zero &= is_zero << 8; - is_zero &= is_zero << 4; - is_zero &= is_zero << 2; - is_zero &= is_zero << 1; - is_zero = 0 - (is_zero >> 63); - - is_p = (small[0] ^ kPrime[0]) | - (small[1] ^ kPrime[1]) | - (small[2] ^ kPrime[2]) | (small[3] ^ kPrime[3]); - is_p--; - is_p &= is_p << 32; - is_p &= is_p << 16; - is_p &= is_p << 8; - is_p &= is_p << 4; - is_p &= is_p << 2; - is_p &= is_p << 1; - is_p = 0 - (is_p >> 63); - - is_zero |= is_p; - - result = is_zero; - result |= ((limb) is_zero) << 64; - return result; -} - -static int smallfelem_is_zero_int(const void *small) -{ - return (int)(smallfelem_is_zero(small) & ((limb) 1)); -} - -/*- - * felem_inv calculates |out| = |in|^{-1} - * - * Based on Fermat's Little Theorem: - * a^p = a (mod p) - * a^{p-1} = 1 (mod p) - * a^{p-2} = a^{-1} (mod p) - */ -static void felem_inv(felem out, const felem in) -{ - felem ftmp, ftmp2; - /* each e_I will hold |in|^{2^I - 1} */ - felem e2, e4, e8, e16, e32, e64; - longfelem tmp; - unsigned i; - - felem_square(tmp, in); - felem_reduce(ftmp, tmp); /* 2^1 */ - felem_mul(tmp, in, ftmp); - felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */ - felem_assign(e2, ftmp); - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^4 - 2^2 */ - felem_mul(tmp, ftmp, e2); - felem_reduce(ftmp, tmp); /* 2^4 - 2^0 */ - felem_assign(e4, ftmp); - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^5 - 2^1 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^6 - 2^2 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^7 - 2^3 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^8 - 2^4 */ - felem_mul(tmp, ftmp, e4); - felem_reduce(ftmp, tmp); /* 2^8 - 2^0 */ - felem_assign(e8, ftmp); - for (i = 0; i < 8; i++) { - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); - } /* 2^16 - 2^8 */ - felem_mul(tmp, ftmp, e8); - felem_reduce(ftmp, tmp); /* 2^16 - 2^0 */ - felem_assign(e16, ftmp); - for (i = 0; i < 16; i++) { - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); - } /* 2^32 - 2^16 */ - felem_mul(tmp, ftmp, e16); - felem_reduce(ftmp, tmp); /* 2^32 - 2^0 */ - felem_assign(e32, ftmp); - for (i = 0; i < 32; i++) { - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); - } /* 2^64 - 2^32 */ - felem_assign(e64, ftmp); - felem_mul(tmp, ftmp, in); - felem_reduce(ftmp, tmp); /* 2^64 - 2^32 + 2^0 */ - for (i = 0; i < 192; i++) { - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); - } /* 2^256 - 2^224 + 2^192 */ - - felem_mul(tmp, e64, e32); - felem_reduce(ftmp2, tmp); /* 2^64 - 2^0 */ - for (i = 0; i < 16; i++) { - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); - } /* 2^80 - 2^16 */ - felem_mul(tmp, ftmp2, e16); - felem_reduce(ftmp2, tmp); /* 2^80 - 2^0 */ - for (i = 0; i < 8; i++) { - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); - } /* 2^88 - 2^8 */ - felem_mul(tmp, ftmp2, e8); - felem_reduce(ftmp2, tmp); /* 2^88 - 2^0 */ - for (i = 0; i < 4; i++) { - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); - } /* 2^92 - 2^4 */ - felem_mul(tmp, ftmp2, e4); - felem_reduce(ftmp2, tmp); /* 2^92 - 2^0 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); /* 2^93 - 2^1 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); /* 2^94 - 2^2 */ - felem_mul(tmp, ftmp2, e2); - felem_reduce(ftmp2, tmp); /* 2^94 - 2^0 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); /* 2^95 - 2^1 */ - felem_square(tmp, ftmp2); - felem_reduce(ftmp2, tmp); /* 2^96 - 2^2 */ - felem_mul(tmp, ftmp2, in); - felem_reduce(ftmp2, tmp); /* 2^96 - 3 */ - - felem_mul(tmp, ftmp2, ftmp); - felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */ -} - -static void smallfelem_inv_contract(smallfelem out, const smallfelem in) -{ - felem tmp; - - smallfelem_expand(tmp, in); - felem_inv(tmp, tmp); - felem_contract(out, tmp); -} - -/*- - * Group operations - * ---------------- - * - * Building on top of the field operations we have the operations on the - * elliptic curve group itself. Points on the curve are represented in Jacobian - * coordinates - */ - -/*- - * point_double calculates 2*(x_in, y_in, z_in) - * - * The method is taken from: - * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b - * - * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. - * while x_out == y_in is not (maybe this works, but it's not tested). - */ -static void -point_double(felem x_out, felem y_out, felem z_out, - const felem x_in, const felem y_in, const felem z_in) -{ - longfelem tmp, tmp2; - felem delta, gamma, beta, alpha, ftmp, ftmp2; - smallfelem small1, small2; - - felem_assign(ftmp, x_in); - /* ftmp[i] < 2^106 */ - felem_assign(ftmp2, x_in); - /* ftmp2[i] < 2^106 */ - - /* delta = z^2 */ - felem_square(tmp, z_in); - felem_reduce(delta, tmp); - /* delta[i] < 2^101 */ - - /* gamma = y^2 */ - felem_square(tmp, y_in); - felem_reduce(gamma, tmp); - /* gamma[i] < 2^101 */ - felem_shrink(small1, gamma); - - /* beta = x*gamma */ - felem_small_mul(tmp, small1, x_in); - felem_reduce(beta, tmp); - /* beta[i] < 2^101 */ - - /* alpha = 3*(x-delta)*(x+delta) */ - felem_diff(ftmp, delta); - /* ftmp[i] < 2^105 + 2^106 < 2^107 */ - felem_sum(ftmp2, delta); - /* ftmp2[i] < 2^105 + 2^106 < 2^107 */ - felem_scalar(ftmp2, 3); - /* ftmp2[i] < 3 * 2^107 < 2^109 */ - felem_mul(tmp, ftmp, ftmp2); - felem_reduce(alpha, tmp); - /* alpha[i] < 2^101 */ - felem_shrink(small2, alpha); - - /* x' = alpha^2 - 8*beta */ - smallfelem_square(tmp, small2); - felem_reduce(x_out, tmp); - felem_assign(ftmp, beta); - felem_scalar(ftmp, 8); - /* ftmp[i] < 8 * 2^101 = 2^104 */ - felem_diff(x_out, ftmp); - /* x_out[i] < 2^105 + 2^101 < 2^106 */ - - /* z' = (y + z)^2 - gamma - delta */ - felem_sum(delta, gamma); - /* delta[i] < 2^101 + 2^101 = 2^102 */ - felem_assign(ftmp, y_in); - felem_sum(ftmp, z_in); - /* ftmp[i] < 2^106 + 2^106 = 2^107 */ - felem_square(tmp, ftmp); - felem_reduce(z_out, tmp); - felem_diff(z_out, delta); - /* z_out[i] < 2^105 + 2^101 < 2^106 */ - - /* y' = alpha*(4*beta - x') - 8*gamma^2 */ - felem_scalar(beta, 4); - /* beta[i] < 4 * 2^101 = 2^103 */ - felem_diff_zero107(beta, x_out); - /* beta[i] < 2^107 + 2^103 < 2^108 */ - felem_small_mul(tmp, small2, beta); - /* tmp[i] < 7 * 2^64 < 2^67 */ - smallfelem_square(tmp2, small1); - /* tmp2[i] < 7 * 2^64 */ - longfelem_scalar(tmp2, 8); - /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */ - longfelem_diff(tmp, tmp2); - /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */ - felem_reduce_zero105(y_out, tmp); - /* y_out[i] < 2^106 */ -} - -/* - * point_double_small is the same as point_double, except that it operates on - * smallfelems - */ -static void -point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out, - const smallfelem x_in, const smallfelem y_in, - const smallfelem z_in) -{ - felem felem_x_out, felem_y_out, felem_z_out; - felem felem_x_in, felem_y_in, felem_z_in; - - smallfelem_expand(felem_x_in, x_in); - smallfelem_expand(felem_y_in, y_in); - smallfelem_expand(felem_z_in, z_in); - point_double(felem_x_out, felem_y_out, felem_z_out, - felem_x_in, felem_y_in, felem_z_in); - felem_shrink(x_out, felem_x_out); - felem_shrink(y_out, felem_y_out); - felem_shrink(z_out, felem_z_out); -} - -/* copy_conditional copies in to out iff mask is all ones. */ -static void copy_conditional(felem out, const felem in, limb mask) -{ - unsigned i; - for (i = 0; i < NLIMBS; ++i) { - const limb tmp = mask & (in[i] ^ out[i]); - out[i] ^= tmp; - } -} - -/* copy_small_conditional copies in to out iff mask is all ones. */ -static void copy_small_conditional(felem out, const smallfelem in, limb mask) -{ - unsigned i; - const u64 mask64 = mask; - for (i = 0; i < NLIMBS; ++i) { - out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask); - } -} - -/*- - * point_add calcuates (x1, y1, z1) + (x2, y2, z2) - * - * The method is taken from: - * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, - * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). - * - * This function includes a branch for checking whether the two input points - * are equal, (while not equal to the point at infinity). This case never - * happens during single point multiplication, so there is no timing leak for - * ECDH or ECDSA signing. - */ -static void point_add(felem x3, felem y3, felem z3, - const felem x1, const felem y1, const felem z1, - const int mixed, const smallfelem x2, - const smallfelem y2, const smallfelem z2) -{ - felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out; - longfelem tmp, tmp2; - smallfelem small1, small2, small3, small4, small5; - limb x_equal, y_equal, z1_is_zero, z2_is_zero; - - felem_shrink(small3, z1); - - z1_is_zero = smallfelem_is_zero(small3); - z2_is_zero = smallfelem_is_zero(z2); - - /* ftmp = z1z1 = z1**2 */ - smallfelem_square(tmp, small3); - felem_reduce(ftmp, tmp); - /* ftmp[i] < 2^101 */ - felem_shrink(small1, ftmp); - - if (!mixed) { - /* ftmp2 = z2z2 = z2**2 */ - smallfelem_square(tmp, z2); - felem_reduce(ftmp2, tmp); - /* ftmp2[i] < 2^101 */ - felem_shrink(small2, ftmp2); - - felem_shrink(small5, x1); - - /* u1 = ftmp3 = x1*z2z2 */ - smallfelem_mul(tmp, small5, small2); - felem_reduce(ftmp3, tmp); - /* ftmp3[i] < 2^101 */ - - /* ftmp5 = z1 + z2 */ - felem_assign(ftmp5, z1); - felem_small_sum(ftmp5, z2); - /* ftmp5[i] < 2^107 */ - - /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */ - felem_square(tmp, ftmp5); - felem_reduce(ftmp5, tmp); - /* ftmp2 = z2z2 + z1z1 */ - felem_sum(ftmp2, ftmp); - /* ftmp2[i] < 2^101 + 2^101 = 2^102 */ - felem_diff(ftmp5, ftmp2); - /* ftmp5[i] < 2^105 + 2^101 < 2^106 */ - - /* ftmp2 = z2 * z2z2 */ - smallfelem_mul(tmp, small2, z2); - felem_reduce(ftmp2, tmp); - - /* s1 = ftmp2 = y1 * z2**3 */ - felem_mul(tmp, y1, ftmp2); - felem_reduce(ftmp6, tmp); - /* ftmp6[i] < 2^101 */ - } else { - /* - * We'll assume z2 = 1 (special case z2 = 0 is handled later) - */ - - /* u1 = ftmp3 = x1*z2z2 */ - felem_assign(ftmp3, x1); - /* ftmp3[i] < 2^106 */ - - /* ftmp5 = 2z1z2 */ - felem_assign(ftmp5, z1); - felem_scalar(ftmp5, 2); - /* ftmp5[i] < 2*2^106 = 2^107 */ - - /* s1 = ftmp2 = y1 * z2**3 */ - felem_assign(ftmp6, y1); - /* ftmp6[i] < 2^106 */ - } - - /* u2 = x2*z1z1 */ - smallfelem_mul(tmp, x2, small1); - felem_reduce(ftmp4, tmp); - - /* h = ftmp4 = u2 - u1 */ - felem_diff_zero107(ftmp4, ftmp3); - /* ftmp4[i] < 2^107 + 2^101 < 2^108 */ - felem_shrink(small4, ftmp4); - - x_equal = smallfelem_is_zero(small4); - - /* z_out = ftmp5 * h */ - felem_small_mul(tmp, small4, ftmp5); - felem_reduce(z_out, tmp); - /* z_out[i] < 2^101 */ - - /* ftmp = z1 * z1z1 */ - smallfelem_mul(tmp, small1, small3); - felem_reduce(ftmp, tmp); - - /* s2 = tmp = y2 * z1**3 */ - felem_small_mul(tmp, y2, ftmp); - felem_reduce(ftmp5, tmp); - - /* r = ftmp5 = (s2 - s1)*2 */ - felem_diff_zero107(ftmp5, ftmp6); - /* ftmp5[i] < 2^107 + 2^107 = 2^108 */ - felem_scalar(ftmp5, 2); - /* ftmp5[i] < 2^109 */ - felem_shrink(small1, ftmp5); - y_equal = smallfelem_is_zero(small1); - - if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { - point_double(x3, y3, z3, x1, y1, z1); - return; - } - - /* I = ftmp = (2h)**2 */ - felem_assign(ftmp, ftmp4); - felem_scalar(ftmp, 2); - /* ftmp[i] < 2*2^108 = 2^109 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); - - /* J = ftmp2 = h * I */ - felem_mul(tmp, ftmp4, ftmp); - felem_reduce(ftmp2, tmp); - - /* V = ftmp4 = U1 * I */ - felem_mul(tmp, ftmp3, ftmp); - felem_reduce(ftmp4, tmp); - - /* x_out = r**2 - J - 2V */ - smallfelem_square(tmp, small1); - felem_reduce(x_out, tmp); - felem_assign(ftmp3, ftmp4); - felem_scalar(ftmp4, 2); - felem_sum(ftmp4, ftmp2); - /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */ - felem_diff(x_out, ftmp4); - /* x_out[i] < 2^105 + 2^101 */ - - /* y_out = r(V-x_out) - 2 * s1 * J */ - felem_diff_zero107(ftmp3, x_out); - /* ftmp3[i] < 2^107 + 2^101 < 2^108 */ - felem_small_mul(tmp, small1, ftmp3); - felem_mul(tmp2, ftmp6, ftmp2); - longfelem_scalar(tmp2, 2); - /* tmp2[i] < 2*2^67 = 2^68 */ - longfelem_diff(tmp, tmp2); - /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */ - felem_reduce_zero105(y_out, tmp); - /* y_out[i] < 2^106 */ - - copy_small_conditional(x_out, x2, z1_is_zero); - copy_conditional(x_out, x1, z2_is_zero); - copy_small_conditional(y_out, y2, z1_is_zero); - copy_conditional(y_out, y1, z2_is_zero); - copy_small_conditional(z_out, z2, z1_is_zero); - copy_conditional(z_out, z1, z2_is_zero); - felem_assign(x3, x_out); - felem_assign(y3, y_out); - felem_assign(z3, z_out); -} - -/* - * point_add_small is the same as point_add, except that it operates on - * smallfelems - */ -static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3, - smallfelem x1, smallfelem y1, smallfelem z1, - smallfelem x2, smallfelem y2, smallfelem z2) -{ - felem felem_x3, felem_y3, felem_z3; - felem felem_x1, felem_y1, felem_z1; - smallfelem_expand(felem_x1, x1); - smallfelem_expand(felem_y1, y1); - smallfelem_expand(felem_z1, z1); - point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0, - x2, y2, z2); - felem_shrink(x3, felem_x3); - felem_shrink(y3, felem_y3); - felem_shrink(z3, felem_z3); -} - -/*- - * Base point pre computation - * -------------------------- - * - * Two different sorts of precomputed tables are used in the following code. - * Each contain various points on the curve, where each point is three field - * elements (x, y, z). - * - * For the base point table, z is usually 1 (0 for the point at infinity). - * This table has 2 * 16 elements, starting with the following: - * index | bits | point - * ------+---------+------------------------------ - * 0 | 0 0 0 0 | 0G - * 1 | 0 0 0 1 | 1G - * 2 | 0 0 1 0 | 2^64G - * 3 | 0 0 1 1 | (2^64 + 1)G - * 4 | 0 1 0 0 | 2^128G - * 5 | 0 1 0 1 | (2^128 + 1)G - * 6 | 0 1 1 0 | (2^128 + 2^64)G - * 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G - * 8 | 1 0 0 0 | 2^192G - * 9 | 1 0 0 1 | (2^192 + 1)G - * 10 | 1 0 1 0 | (2^192 + 2^64)G - * 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G - * 12 | 1 1 0 0 | (2^192 + 2^128)G - * 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G - * 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G - * 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G - * followed by a copy of this with each element multiplied by 2^32. - * - * The reason for this is so that we can clock bits into four different - * locations when doing simple scalar multiplies against the base point, - * and then another four locations using the second 16 elements. - * - * Tables for other points have table[i] = iG for i in 0 .. 16. */ - -/* gmul is the table of precomputed base points */ -static const smallfelem gmul[2][16][3] = { - {{{0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, - 0x6b17d1f2e12c4247}, - {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16, - 0x4fe342e2fe1a7f9b}, - {1, 0, 0, 0}}, - {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de, - 0x0fa822bc2811aaa5}, - {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b, - 0xbff44ae8f5dba80d}, - {1, 0, 0, 0}}, - {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789, - 0x300a4bbc89d6726f}, - {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f, - 0x72aac7e0d09b4644}, - {1, 0, 0, 0}}, - {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e, - 0x447d739beedb5e67}, - {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7, - 0x2d4825ab834131ee}, - {1, 0, 0, 0}}, - {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60, - 0xef9519328a9c72ff}, - {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c, - 0x611e9fc37dbb2c9b}, - {1, 0, 0, 0}}, - {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf, - 0x550663797b51f5d8}, - {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5, - 0x157164848aecb851}, - {1, 0, 0, 0}}, - {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391, - 0xeb5d7745b21141ea}, - {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee, - 0xeafd72ebdbecc17b}, - {1, 0, 0, 0}}, - {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5, - 0xa6d39677a7849276}, - {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf, - 0x674f84749b0b8816}, - {1, 0, 0, 0}}, - {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb, - 0x4e769e7672c9ddad}, - {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281, - 0x42b99082de830663}, - {1, 0, 0, 0}}, - {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478, - 0x78878ef61c6ce04d}, - {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def, - 0xb6cb3f5d7b72c321}, - {1, 0, 0, 0}}, - {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae, - 0x0c88bc4d716b1287}, - {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa, - 0xdd5ddea3f3901dc6}, - {1, 0, 0, 0}}, - {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3, - 0x68f344af6b317466}, - {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3, - 0x31b9c405f8540a20}, - {1, 0, 0, 0}}, - {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0, - 0x4052bf4b6f461db9}, - {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8, - 0xfecf4d5190b0fc61}, - {1, 0, 0, 0}}, - {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a, - 0x1eddbae2c802e41a}, - {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0, - 0x43104d86560ebcfc}, - {1, 0, 0, 0}}, - {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a, - 0xb48e26b484f7a21c}, - {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668, - 0xfac015404d4d3dab}, - {1, 0, 0, 0}}}, - {{{0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}}, - {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da, - 0x7fe36b40af22af89}, - {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1, - 0xe697d45825b63624}, - {1, 0, 0, 0}}, - {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902, - 0x4a5b506612a677a6}, - {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40, - 0xeb13461ceac089f1}, - {1, 0, 0, 0}}, - {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857, - 0x0781b8291c6a220a}, - {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434, - 0x690cde8df0151593}, - {1, 0, 0, 0}}, - {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326, - 0x8a535f566ec73617}, - {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf, - 0x0455c08468b08bd7}, - {1, 0, 0, 0}}, - {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279, - 0x06bada7ab77f8276}, - {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70, - 0x5b476dfd0e6cb18a}, - {1, 0, 0, 0}}, - {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8, - 0x3e29864e8a2ec908}, - {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed, - 0x239b90ea3dc31e7e}, - {1, 0, 0, 0}}, - {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4, - 0x820f4dd949f72ff7}, - {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3, - 0x140406ec783a05ec}, - {1, 0, 0, 0}}, - {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe, - 0x68f6b8542783dfee}, - {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028, - 0xcbe1feba92e40ce6}, - {1, 0, 0, 0}}, - {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927, - 0xd0b2f94d2f420109}, - {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a, - 0x971459828b0719e5}, - {1, 0, 0, 0}}, - {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687, - 0x961610004a866aba}, - {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c, - 0x7acb9fadcee75e44}, - {1, 0, 0, 0}}, - {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea, - 0x24eb9acca333bf5b}, - {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d, - 0x69f891c5acd079cc}, - {1, 0, 0, 0}}, - {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514, - 0xe51f547c5972a107}, - {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06, - 0x1c309a2b25bb1387}, - {1, 0, 0, 0}}, - {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828, - 0x20b87b8aa2c4e503}, - {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044, - 0xf5c6fa49919776be}, - {1, 0, 0, 0}}, - {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56, - 0x1ed7d1b9332010b9}, - {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24, - 0x3a2b03f03217257a}, - {1, 0, 0, 0}}, - {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b, - 0x15fee545c78dd9f6}, - {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, - 0x4ab5b6b2b8753f81}, - {1, 0, 0, 0}}} -}; - -/* - * select_point selects the |idx|th point from a precomputation table and - * copies it to out. - */ -static void select_point(const u64 idx, unsigned int size, - const smallfelem pre_comp[16][3], smallfelem out[3]) -{ - unsigned i, j; - u64 *outlimbs = &out[0][0]; - memset(outlimbs, 0, 3 * sizeof(smallfelem)); - - for (i = 0; i < size; i++) { - const u64 *inlimbs = (u64 *)&pre_comp[i][0][0]; - u64 mask = i ^ idx; - mask |= mask >> 4; - mask |= mask >> 2; - mask |= mask >> 1; - mask &= 1; - mask--; - for (j = 0; j < NLIMBS * 3; j++) - outlimbs[j] |= inlimbs[j] & mask; - } -} - -/* get_bit returns the |i|th bit in |in| */ -static char get_bit(const felem_bytearray in, int i) -{ - if ((i < 0) || (i >= 256)) - return 0; - return (in[i >> 3] >> (i & 7)) & 1; -} - -/* - * Interleaved point multiplication using precomputed point multiples: The - * small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[], the scalars - * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the - * generator, using certain (large) precomputed multiples in g_pre_comp. - * Output point (X, Y, Z) is stored in x_out, y_out, z_out - */ -static void batch_mul(felem x_out, felem y_out, felem z_out, - const felem_bytearray scalars[], - const unsigned num_points, const u8 *g_scalar, - const int mixed, const smallfelem pre_comp[][17][3], - const smallfelem g_pre_comp[2][16][3]) -{ - int i, skip; - unsigned num, gen_mul = (g_scalar != NULL); - felem nq[3], ftmp; - smallfelem tmp[3]; - u64 bits; - u8 sign, digit; - - /* set nq to the point at infinity */ - memset(nq, 0, 3 * sizeof(felem)); - - /* - * Loop over all scalars msb-to-lsb, interleaving additions of multiples - * of the generator (two in each of the last 32 rounds) and additions of - * other points multiples (every 5th round). - */ - skip = 1; /* save two point operations in the first - * round */ - for (i = (num_points ? 255 : 31); i >= 0; --i) { - /* double */ - if (!skip) - point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); - - /* add multiples of the generator */ - if (gen_mul && (i <= 31)) { - /* first, look 32 bits upwards */ - bits = get_bit(g_scalar, i + 224) << 3; - bits |= get_bit(g_scalar, i + 160) << 2; - bits |= get_bit(g_scalar, i + 96) << 1; - bits |= get_bit(g_scalar, i + 32); - /* select the point to add, in constant time */ - select_point(bits, 16, g_pre_comp[1], tmp); - - if (!skip) { - /* Arg 1 below is for "mixed" */ - point_add(nq[0], nq[1], nq[2], - nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); - } else { - smallfelem_expand(nq[0], tmp[0]); - smallfelem_expand(nq[1], tmp[1]); - smallfelem_expand(nq[2], tmp[2]); - skip = 0; - } - - /* second, look at the current position */ - bits = get_bit(g_scalar, i + 192) << 3; - bits |= get_bit(g_scalar, i + 128) << 2; - bits |= get_bit(g_scalar, i + 64) << 1; - bits |= get_bit(g_scalar, i); - /* select the point to add, in constant time */ - select_point(bits, 16, g_pre_comp[0], tmp); - /* Arg 1 below is for "mixed" */ - point_add(nq[0], nq[1], nq[2], - nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); - } - - /* do other additions every 5 doublings */ - if (num_points && (i % 5 == 0)) { - /* loop over all scalars */ - for (num = 0; num < num_points; ++num) { - bits = get_bit(scalars[num], i + 4) << 5; - bits |= get_bit(scalars[num], i + 3) << 4; - bits |= get_bit(scalars[num], i + 2) << 3; - bits |= get_bit(scalars[num], i + 1) << 2; - bits |= get_bit(scalars[num], i) << 1; - bits |= get_bit(scalars[num], i - 1); - ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); - - /* - * select the point to add or subtract, in constant time - */ - select_point(digit, 17, pre_comp[num], tmp); - smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative - * point */ - copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1)); - felem_contract(tmp[1], ftmp); - - if (!skip) { - point_add(nq[0], nq[1], nq[2], - nq[0], nq[1], nq[2], - mixed, tmp[0], tmp[1], tmp[2]); - } else { - smallfelem_expand(nq[0], tmp[0]); - smallfelem_expand(nq[1], tmp[1]); - smallfelem_expand(nq[2], tmp[2]); - skip = 0; - } - } - } - } - felem_assign(x_out, nq[0]); - felem_assign(y_out, nq[1]); - felem_assign(z_out, nq[2]); -} - -/* Precomputation for the group generator. */ -typedef struct { - smallfelem g_pre_comp[2][16][3]; - int references; -} NISTP256_PRE_COMP; - -const EC_METHOD *EC_GFp_nistp256_method(void) -{ - static const EC_METHOD ret = { - EC_FLAGS_DEFAULT_OCT, - NID_X9_62_prime_field, - ec_GFp_nistp256_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_nist_group_copy, - ec_GFp_nistp256_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_nistp256_point_get_affine_coordinates, - 0 /* point_set_compressed_coordinates */ , - 0 /* point2oct */ , - 0 /* oct2point */ , - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - ec_GFp_nistp256_points_mul, - ec_GFp_nistp256_precompute_mult, - ec_GFp_nistp256_have_precompute_mult, - ec_GFp_nist_field_mul, - ec_GFp_nist_field_sqr, - 0 /* field_div */ , - 0 /* field_encode */ , - 0 /* field_decode */ , - 0 /* field_set_to_one */ - }; - - return &ret; -} - -/******************************************************************************/ -/* - * FUNCTIONS TO MANAGE PRECOMPUTATION - */ - -static NISTP256_PRE_COMP *nistp256_pre_comp_new() -{ - NISTP256_PRE_COMP *ret = NULL; - ret = (NISTP256_PRE_COMP *) OPENSSL_malloc(sizeof(*ret)); - if (!ret) { - ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); - return ret; - } - memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); - ret->references = 1; - return ret; -} - -static void *nistp256_pre_comp_dup(void *src_) -{ - NISTP256_PRE_COMP *src = src_; - - /* no need to actually copy, these objects never change! */ - CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); - - return src_; -} - -static void nistp256_pre_comp_free(void *pre_) -{ - int i; - NISTP256_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - OPENSSL_free(pre); -} - -static void nistp256_pre_comp_clear_free(void *pre_) -{ - int i; - NISTP256_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - OPENSSL_cleanse(pre, sizeof(*pre)); - OPENSSL_free(pre); -} - -/******************************************************************************/ -/* - * OPENSSL EC_METHOD FUNCTIONS - */ - -int ec_GFp_nistp256_group_init(EC_GROUP *group) -{ - int ret; - ret = ec_GFp_simple_group_init(group); - group->a_is_minus3 = 1; - return ret; -} - -int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, - BN_CTX *ctx) -{ - int ret = 0; - BN_CTX *new_ctx = NULL; - BIGNUM *curve_p, *curve_a, *curve_b; - - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((curve_p = BN_CTX_get(ctx)) == NULL) || - ((curve_a = BN_CTX_get(ctx)) == NULL) || - ((curve_b = BN_CTX_get(ctx)) == NULL)) - goto err; - BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p); - BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a); - BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b); - if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { - ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, - EC_R_WRONG_CURVE_PARAMETERS); - goto err; - } - group->field_mod_func = BN_nist_mod_256; - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -/* - * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = - * (X/Z^2, Y/Z^3) - */ -int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) -{ - felem z1, z2, x_in, y_in; - smallfelem x_out, y_out; - longfelem tmp; - - if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); - return 0; - } - if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || - (!BN_to_felem(z1, &point->Z))) - return 0; - felem_inv(z2, z1); - felem_square(tmp, z2); - felem_reduce(z1, tmp); - felem_mul(tmp, x_in, z1); - felem_reduce(x_in, tmp); - felem_contract(x_out, x_in); - if (x != NULL) { - if (!smallfelem_to_BN(x, x_out)) { - ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); - return 0; - } - } - felem_mul(tmp, z1, z2); - felem_reduce(z1, tmp); - felem_mul(tmp, y_in, z1); - felem_reduce(y_in, tmp); - felem_contract(y_out, y_in); - if (y != NULL) { - if (!smallfelem_to_BN(y, y_out)) { - ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); - return 0; - } - } - return 1; -} - -/* points below is of size |num|, and tmp_smallfelems is of size |num+1| */ -static void make_points_affine(size_t num, smallfelem points[][3], - smallfelem tmp_smallfelems[]) -{ - /* - * Runs in constant time, unless an input is the point at infinity (which - * normally shouldn't happen). - */ - ec_GFp_nistp_points_make_affine_internal(num, - points, - sizeof(smallfelem), - tmp_smallfelems, - (void (*)(void *))smallfelem_one, - smallfelem_is_zero_int, - (void (*)(void *, const void *)) - smallfelem_assign, - (void (*)(void *, const void *)) - smallfelem_square_contract, - (void (*) - (void *, const void *, - const void *)) - smallfelem_mul_contract, - (void (*)(void *, const void *)) - smallfelem_inv_contract, - /* nothing to contract */ - (void (*)(void *, const void *)) - smallfelem_assign); -} - -/* - * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL - * values Result is stored in r (r can equal one of the inputs). - */ -int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) -{ - int ret = 0; - int j; - int mixed = 0; - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y, *z, *tmp_scalar; - felem_bytearray g_secret; - felem_bytearray *secrets = NULL; - smallfelem(*pre_comp)[17][3] = NULL; - smallfelem *tmp_smallfelems = NULL; - felem_bytearray tmp; - unsigned i, num_bytes; - int have_pre_comp = 0; - size_t num_points = num; - smallfelem x_in, y_in, z_in; - felem x_out, y_out, z_out; - NISTP256_PRE_COMP *pre = NULL; - const smallfelem(*g_pre_comp)[16][3] = NULL; - EC_POINT *generator = NULL; - const EC_POINT *p = NULL; - const BIGNUM *p_scalar = NULL; - - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((x = BN_CTX_get(ctx)) == NULL) || - ((y = BN_CTX_get(ctx)) == NULL) || - ((z = BN_CTX_get(ctx)) == NULL) || - ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) - goto err; - - if (scalar != NULL) { - pre = EC_EX_DATA_get_data(group->extra_data, - nistp256_pre_comp_dup, - nistp256_pre_comp_free, - nistp256_pre_comp_clear_free); - if (pre) - /* we have precomputation, try to use it */ - g_pre_comp = (const smallfelem(*)[16][3])pre->g_pre_comp; - else - /* try to use the standard precomputation */ - g_pre_comp = &gmul[0]; - generator = EC_POINT_new(group); - if (generator == NULL) - goto err; - /* get the generator from precomputation */ - if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) || - !smallfelem_to_BN(y, g_pre_comp[0][1][1]) || - !smallfelem_to_BN(z, g_pre_comp[0][1][2])) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - if (!EC_POINT_set_Jprojective_coordinates_GFp(group, - generator, x, y, z, - ctx)) - goto err; - if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) - /* precomputation matches generator */ - have_pre_comp = 1; - else - /* - * we don't have valid precomputation: treat the generator as a - * random point - */ - num_points++; - } - if (num_points > 0) { - if (num_points >= 3) { - /* - * unless we precompute multiples for just one or two points, - * converting those into affine form is time well spent - */ - mixed = 1; - } - secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); - pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem)); - if (mixed) - tmp_smallfelems = - OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem)); - if ((secrets == NULL) || (pre_comp == NULL) - || (mixed && (tmp_smallfelems == NULL))) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * we treat NULL scalars as 0, and NULL points as points at infinity, - * i.e., they contribute nothing to the linear combination - */ - memset(secrets, 0, num_points * sizeof(felem_bytearray)); - memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem)); - for (i = 0; i < num_points; ++i) { - if (i == num) - /* - * we didn't have a valid precomputation, so we pick the - * generator - */ - { - p = EC_GROUP_get0_generator(group); - p_scalar = scalar; - } else - /* the i^th point */ - { - p = points[i]; - p_scalar = scalars[i]; - } - if ((p_scalar != NULL) && (p != NULL)) { - /* reduce scalar to 0 <= scalar < 2^256 */ - if ((BN_num_bits(p_scalar) > 256) - || (BN_is_negative(p_scalar))) { - /* - * this is an unusual input, and we don't guarantee - * constant-timeness - */ - if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(p_scalar, tmp); - flip_endian(secrets[i], tmp, num_bytes); - /* precompute multiples */ - if ((!BN_to_felem(x_out, &p->X)) || - (!BN_to_felem(y_out, &p->Y)) || - (!BN_to_felem(z_out, &p->Z))) - goto err; - felem_shrink(pre_comp[i][1][0], x_out); - felem_shrink(pre_comp[i][1][1], y_out); - felem_shrink(pre_comp[i][1][2], z_out); - for (j = 2; j <= 16; ++j) { - if (j & 1) { - point_add_small(pre_comp[i][j][0], pre_comp[i][j][1], - pre_comp[i][j][2], pre_comp[i][1][0], - pre_comp[i][1][1], pre_comp[i][1][2], - pre_comp[i][j - 1][0], - pre_comp[i][j - 1][1], - pre_comp[i][j - 1][2]); - } else { - point_double_small(pre_comp[i][j][0], - pre_comp[i][j][1], - pre_comp[i][j][2], - pre_comp[i][j / 2][0], - pre_comp[i][j / 2][1], - pre_comp[i][j / 2][2]); - } - } - } - } - if (mixed) - make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems); - } - - /* the scalar for the generator */ - if ((scalar != NULL) && (have_pre_comp)) { - memset(g_secret, 0, sizeof(g_secret)); - /* reduce scalar to 0 <= scalar < 2^256 */ - if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar))) { - /* - * this is an unusual input, and we don't guarantee - * constant-timeness - */ - if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(scalar, tmp); - flip_endian(g_secret, tmp, num_bytes); - /* do the multiplication with generator precomputation */ - batch_mul(x_out, y_out, z_out, - (const felem_bytearray(*))secrets, num_points, - g_secret, - mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp); - } else - /* do the multiplication without generator precomputation */ - batch_mul(x_out, y_out, z_out, - (const felem_bytearray(*))secrets, num_points, - NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL); - /* reduce the output to its unique minimal representation */ - felem_contract(x_in, x_out); - felem_contract(y_in, y_out); - felem_contract(z_in, z_out); - if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) || - (!smallfelem_to_BN(z, z_in))) { - ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); - - err: - BN_CTX_end(ctx); - if (generator != NULL) - EC_POINT_free(generator); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (secrets != NULL) - OPENSSL_free(secrets); - if (pre_comp != NULL) - OPENSSL_free(pre_comp); - if (tmp_smallfelems != NULL) - OPENSSL_free(tmp_smallfelems); - return ret; -} - -int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) -{ - int ret = 0; - NISTP256_PRE_COMP *pre = NULL; - int i, j; - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y; - EC_POINT *generator = NULL; - smallfelem tmp_smallfelems[32]; - felem x_tmp, y_tmp, z_tmp; - - /* throw away old precomputation */ - EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup, - nistp256_pre_comp_free, - nistp256_pre_comp_clear_free); - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) - goto err; - /* get the generator */ - if (group->generator == NULL) - goto err; - generator = EC_POINT_new(group); - if (generator == NULL) - goto err; - BN_bin2bn(nistp256_curve_params[3], sizeof(felem_bytearray), x); - BN_bin2bn(nistp256_curve_params[4], sizeof(felem_bytearray), y); - if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) - goto err; - if ((pre = nistp256_pre_comp_new()) == NULL) - goto err; - /* - * if the generator is the standard one, use built-in precomputation - */ - if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { - memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); - goto done; - } - if ((!BN_to_felem(x_tmp, &group->generator->X)) || - (!BN_to_felem(y_tmp, &group->generator->Y)) || - (!BN_to_felem(z_tmp, &group->generator->Z))) - goto err; - felem_shrink(pre->g_pre_comp[0][1][0], x_tmp); - felem_shrink(pre->g_pre_comp[0][1][1], y_tmp); - felem_shrink(pre->g_pre_comp[0][1][2], z_tmp); - /* - * compute 2^64*G, 2^128*G, 2^192*G for the first table, 2^32*G, 2^96*G, - * 2^160*G, 2^224*G for the second one - */ - for (i = 1; i <= 8; i <<= 1) { - point_double_small(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], - pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0], - pre->g_pre_comp[0][i][1], - pre->g_pre_comp[0][i][2]); - for (j = 0; j < 31; ++j) { - point_double_small(pre->g_pre_comp[1][i][0], - pre->g_pre_comp[1][i][1], - pre->g_pre_comp[1][i][2], - pre->g_pre_comp[1][i][0], - pre->g_pre_comp[1][i][1], - pre->g_pre_comp[1][i][2]); - } - if (i == 8) - break; - point_double_small(pre->g_pre_comp[0][2 * i][0], - pre->g_pre_comp[0][2 * i][1], - pre->g_pre_comp[0][2 * i][2], - pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], - pre->g_pre_comp[1][i][2]); - for (j = 0; j < 31; ++j) { - point_double_small(pre->g_pre_comp[0][2 * i][0], - pre->g_pre_comp[0][2 * i][1], - pre->g_pre_comp[0][2 * i][2], - pre->g_pre_comp[0][2 * i][0], - pre->g_pre_comp[0][2 * i][1], - pre->g_pre_comp[0][2 * i][2]); - } - } - for (i = 0; i < 2; i++) { - /* g_pre_comp[i][0] is the point at infinity */ - memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0])); - /* the remaining multiples */ - /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */ - point_add_small(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], - pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0], - pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2], - pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], - pre->g_pre_comp[i][2][2]); - /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */ - point_add_small(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], - pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0], - pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], - pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], - pre->g_pre_comp[i][2][2]); - /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */ - point_add_small(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], - pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0], - pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], - pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], - pre->g_pre_comp[i][4][2]); - /* - * 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G - */ - point_add_small(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], - pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0], - pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2], - pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], - pre->g_pre_comp[i][2][2]); - for (j = 1; j < 8; ++j) { - /* odd multiples: add G resp. 2^32*G */ - point_add_small(pre->g_pre_comp[i][2 * j + 1][0], - pre->g_pre_comp[i][2 * j + 1][1], - pre->g_pre_comp[i][2 * j + 1][2], - pre->g_pre_comp[i][2 * j][0], - pre->g_pre_comp[i][2 * j][1], - pre->g_pre_comp[i][2 * j][2], - pre->g_pre_comp[i][1][0], - pre->g_pre_comp[i][1][1], - pre->g_pre_comp[i][1][2]); - } - } - make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems); - - done: - if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup, - nistp256_pre_comp_free, - nistp256_pre_comp_clear_free)) - goto err; - ret = 1; - pre = NULL; - err: - BN_CTX_end(ctx); - if (generator != NULL) - EC_POINT_free(generator); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (pre) - nistp256_pre_comp_free(pre); - return ret; -} - -int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group) -{ - if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup, - nistp256_pre_comp_free, - nistp256_pre_comp_clear_free) - != NULL) - return 1; - else - return 0; -} -#else -static void *dummy = &dummy; -#endif diff --git a/Sources/COpenSSL/ecp_nistp521.c b/Sources/COpenSSL/ecp_nistp521.c deleted file mode 100644 index 27cab28b..00000000 --- a/Sources/COpenSSL/ecp_nistp521.c +++ /dev/null @@ -1,2146 +0,0 @@ -/* crypto/ec/ecp_nistp521.c */ -/* - * Written by Adam Langley (Google) for the OpenSSL project - */ -/* Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication - * - * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c. - * Otherwise based on Emilia's P224 work, which was inspired by my curve25519 - * work which got its smarts from Daniel J. Bernstein's work on the same. - */ - -#include "opensslconf.h" -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - -# ifndef OPENSSL_SYS_VMS -# include -# else -# include -# endif - -# include -# include "err.h" -# include "ec_lcl.h" - -# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) - /* even with gcc, the typedef won't work for 32-bit platforms */ -typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit - * platforms */ -# else -# error "Need GCC 3.1 or later to define type uint128_t" -# endif - -typedef uint8_t u8; -typedef uint64_t u64; - -/* - * The underlying field. P521 operates over GF(2^521-1). We can serialise an - * element of this field into 66 bytes where the most significant byte - * contains only a single bit. We call this an felem_bytearray. - */ - -typedef u8 felem_bytearray[66]; - -/* - * These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5. - * These values are big-endian. - */ -static const felem_bytearray nistp521_curve_params[5] = { - {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff}, - {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xfc}, - {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */ - 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, - 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, - 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, - 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, - 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, - 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, - 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, - 0x3f, 0x00}, - {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */ - 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, - 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, - 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, - 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, - 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, - 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, - 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, - 0xbd, 0x66}, - {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */ - 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, - 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, - 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, - 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, - 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, - 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, - 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, - 0x66, 0x50} -}; - -/*- - * The representation of field elements. - * ------------------------------------ - * - * We represent field elements with nine values. These values are either 64 or - * 128 bits and the field element represented is: - * v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464 (mod p) - * Each of the nine values is called a 'limb'. Since the limbs are spaced only - * 58 bits apart, but are greater than 58 bits in length, the most significant - * bits of each limb overlap with the least significant bits of the next. - * - * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a - * 'largefelem' */ - -# define NLIMBS 9 - -typedef uint64_t limb; -typedef limb felem[NLIMBS]; -typedef uint128_t largefelem[NLIMBS]; - -static const limb bottom57bits = 0x1ffffffffffffff; -static const limb bottom58bits = 0x3ffffffffffffff; - -/* - * bin66_to_felem takes a little-endian byte array and converts it into felem - * form. This assumes that the CPU is little-endian. - */ -static void bin66_to_felem(felem out, const u8 in[66]) -{ - out[0] = (*((limb *) & in[0])) & bottom58bits; - out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits; - out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits; - out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits; - out[4] = (*((limb *) & in[29])) & bottom58bits; - out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits; - out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits; - out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits; - out[8] = (*((limb *) & in[58])) & bottom57bits; -} - -/* - * felem_to_bin66 takes an felem and serialises into a little endian, 66 byte - * array. This assumes that the CPU is little-endian. - */ -static void felem_to_bin66(u8 out[66], const felem in) -{ - memset(out, 0, 66); - (*((limb *) & out[0])) = in[0]; - (*((limb *) & out[7])) |= in[1] << 2; - (*((limb *) & out[14])) |= in[2] << 4; - (*((limb *) & out[21])) |= in[3] << 6; - (*((limb *) & out[29])) = in[4]; - (*((limb *) & out[36])) |= in[5] << 2; - (*((limb *) & out[43])) |= in[6] << 4; - (*((limb *) & out[50])) |= in[7] << 6; - (*((limb *) & out[58])) = in[8]; -} - -/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ -static void flip_endian(u8 *out, const u8 *in, unsigned len) -{ - unsigned i; - for (i = 0; i < len; ++i) - out[i] = in[len - 1 - i]; -} - -/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ -static int BN_to_felem(felem out, const BIGNUM *bn) -{ - felem_bytearray b_in; - felem_bytearray b_out; - unsigned num_bytes; - - /* BN_bn2bin eats leading zeroes */ - memset(b_out, 0, sizeof(b_out)); - num_bytes = BN_num_bytes(bn); - if (num_bytes > sizeof(b_out)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } - if (BN_is_negative(bn)) { - ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); - return 0; - } - num_bytes = BN_bn2bin(bn, b_in); - flip_endian(b_out, b_in, num_bytes); - bin66_to_felem(out, b_out); - return 1; -} - -/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ -static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) -{ - felem_bytearray b_in, b_out; - felem_to_bin66(b_in, in); - flip_endian(b_out, b_in, sizeof(b_out)); - return BN_bin2bn(b_out, sizeof(b_out), out); -} - -/*- - * Field operations - * ---------------- - */ - -static void felem_one(felem out) -{ - out[0] = 1; - out[1] = 0; - out[2] = 0; - out[3] = 0; - out[4] = 0; - out[5] = 0; - out[6] = 0; - out[7] = 0; - out[8] = 0; -} - -static void felem_assign(felem out, const felem in) -{ - out[0] = in[0]; - out[1] = in[1]; - out[2] = in[2]; - out[3] = in[3]; - out[4] = in[4]; - out[5] = in[5]; - out[6] = in[6]; - out[7] = in[7]; - out[8] = in[8]; -} - -/* felem_sum64 sets out = out + in. */ -static void felem_sum64(felem out, const felem in) -{ - out[0] += in[0]; - out[1] += in[1]; - out[2] += in[2]; - out[3] += in[3]; - out[4] += in[4]; - out[5] += in[5]; - out[6] += in[6]; - out[7] += in[7]; - out[8] += in[8]; -} - -/* felem_scalar sets out = in * scalar */ -static void felem_scalar(felem out, const felem in, limb scalar) -{ - out[0] = in[0] * scalar; - out[1] = in[1] * scalar; - out[2] = in[2] * scalar; - out[3] = in[3] * scalar; - out[4] = in[4] * scalar; - out[5] = in[5] * scalar; - out[6] = in[6] * scalar; - out[7] = in[7] * scalar; - out[8] = in[8] * scalar; -} - -/* felem_scalar64 sets out = out * scalar */ -static void felem_scalar64(felem out, limb scalar) -{ - out[0] *= scalar; - out[1] *= scalar; - out[2] *= scalar; - out[3] *= scalar; - out[4] *= scalar; - out[5] *= scalar; - out[6] *= scalar; - out[7] *= scalar; - out[8] *= scalar; -} - -/* felem_scalar128 sets out = out * scalar */ -static void felem_scalar128(largefelem out, limb scalar) -{ - out[0] *= scalar; - out[1] *= scalar; - out[2] *= scalar; - out[3] *= scalar; - out[4] *= scalar; - out[5] *= scalar; - out[6] *= scalar; - out[7] *= scalar; - out[8] *= scalar; -} - -/*- - * felem_neg sets |out| to |-in| - * On entry: - * in[i] < 2^59 + 2^14 - * On exit: - * out[i] < 2^62 - */ -static void felem_neg(felem out, const felem in) -{ - /* In order to prevent underflow, we subtract from 0 mod p. */ - static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5); - static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4); - - out[0] = two62m3 - in[0]; - out[1] = two62m2 - in[1]; - out[2] = two62m2 - in[2]; - out[3] = two62m2 - in[3]; - out[4] = two62m2 - in[4]; - out[5] = two62m2 - in[5]; - out[6] = two62m2 - in[6]; - out[7] = two62m2 - in[7]; - out[8] = two62m2 - in[8]; -} - -/*- - * felem_diff64 subtracts |in| from |out| - * On entry: - * in[i] < 2^59 + 2^14 - * On exit: - * out[i] < out[i] + 2^62 - */ -static void felem_diff64(felem out, const felem in) -{ - /* - * In order to prevent underflow, we add 0 mod p before subtracting. - */ - static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5); - static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4); - - out[0] += two62m3 - in[0]; - out[1] += two62m2 - in[1]; - out[2] += two62m2 - in[2]; - out[3] += two62m2 - in[3]; - out[4] += two62m2 - in[4]; - out[5] += two62m2 - in[5]; - out[6] += two62m2 - in[6]; - out[7] += two62m2 - in[7]; - out[8] += two62m2 - in[8]; -} - -/*- - * felem_diff_128_64 subtracts |in| from |out| - * On entry: - * in[i] < 2^62 + 2^17 - * On exit: - * out[i] < out[i] + 2^63 - */ -static void felem_diff_128_64(largefelem out, const felem in) -{ - /* - * In order to prevent underflow, we add 0 mod p before subtracting. - */ - static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5); - static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4); - - out[0] += two63m6 - in[0]; - out[1] += two63m5 - in[1]; - out[2] += two63m5 - in[2]; - out[3] += two63m5 - in[3]; - out[4] += two63m5 - in[4]; - out[5] += two63m5 - in[5]; - out[6] += two63m5 - in[6]; - out[7] += two63m5 - in[7]; - out[8] += two63m5 - in[8]; -} - -/*- - * felem_diff_128_64 subtracts |in| from |out| - * On entry: - * in[i] < 2^126 - * On exit: - * out[i] < out[i] + 2^127 - 2^69 - */ -static void felem_diff128(largefelem out, const largefelem in) -{ - /* - * In order to prevent underflow, we add 0 mod p before subtracting. - */ - static const uint128_t two127m70 = - (((uint128_t) 1) << 127) - (((uint128_t) 1) << 70); - static const uint128_t two127m69 = - (((uint128_t) 1) << 127) - (((uint128_t) 1) << 69); - - out[0] += (two127m70 - in[0]); - out[1] += (two127m69 - in[1]); - out[2] += (two127m69 - in[2]); - out[3] += (two127m69 - in[3]); - out[4] += (two127m69 - in[4]); - out[5] += (two127m69 - in[5]); - out[6] += (two127m69 - in[6]); - out[7] += (two127m69 - in[7]); - out[8] += (two127m69 - in[8]); -} - -/*- - * felem_square sets |out| = |in|^2 - * On entry: - * in[i] < 2^62 - * On exit: - * out[i] < 17 * max(in[i]) * max(in[i]) - */ -static void felem_square(largefelem out, const felem in) -{ - felem inx2, inx4; - felem_scalar(inx2, in, 2); - felem_scalar(inx4, in, 4); - - /*- - * We have many cases were we want to do - * in[x] * in[y] + - * in[y] * in[x] - * This is obviously just - * 2 * in[x] * in[y] - * However, rather than do the doubling on the 128 bit result, we - * double one of the inputs to the multiplication by reading from - * |inx2| - */ - - out[0] = ((uint128_t) in[0]) * in[0]; - out[1] = ((uint128_t) in[0]) * inx2[1]; - out[2] = ((uint128_t) in[0]) * inx2[2] + ((uint128_t) in[1]) * in[1]; - out[3] = ((uint128_t) in[0]) * inx2[3] + ((uint128_t) in[1]) * inx2[2]; - out[4] = ((uint128_t) in[0]) * inx2[4] + - ((uint128_t) in[1]) * inx2[3] + ((uint128_t) in[2]) * in[2]; - out[5] = ((uint128_t) in[0]) * inx2[5] + - ((uint128_t) in[1]) * inx2[4] + ((uint128_t) in[2]) * inx2[3]; - out[6] = ((uint128_t) in[0]) * inx2[6] + - ((uint128_t) in[1]) * inx2[5] + - ((uint128_t) in[2]) * inx2[4] + ((uint128_t) in[3]) * in[3]; - out[7] = ((uint128_t) in[0]) * inx2[7] + - ((uint128_t) in[1]) * inx2[6] + - ((uint128_t) in[2]) * inx2[5] + ((uint128_t) in[3]) * inx2[4]; - out[8] = ((uint128_t) in[0]) * inx2[8] + - ((uint128_t) in[1]) * inx2[7] + - ((uint128_t) in[2]) * inx2[6] + - ((uint128_t) in[3]) * inx2[5] + ((uint128_t) in[4]) * in[4]; - - /* - * The remaining limbs fall above 2^521, with the first falling at 2^522. - * They correspond to locations one bit up from the limbs produced above - * so we would have to multiply by two to align them. Again, rather than - * operate on the 128-bit result, we double one of the inputs to the - * multiplication. If we want to double for both this reason, and the - * reason above, then we end up multiplying by four. - */ - - /* 9 */ - out[0] += ((uint128_t) in[1]) * inx4[8] + - ((uint128_t) in[2]) * inx4[7] + - ((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[4]) * inx4[5]; - - /* 10 */ - out[1] += ((uint128_t) in[2]) * inx4[8] + - ((uint128_t) in[3]) * inx4[7] + - ((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[5]) * inx2[5]; - - /* 11 */ - out[2] += ((uint128_t) in[3]) * inx4[8] + - ((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[5]) * inx4[6]; - - /* 12 */ - out[3] += ((uint128_t) in[4]) * inx4[8] + - ((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[6]) * inx2[6]; - - /* 13 */ - out[4] += ((uint128_t) in[5]) * inx4[8] + ((uint128_t) in[6]) * inx4[7]; - - /* 14 */ - out[5] += ((uint128_t) in[6]) * inx4[8] + ((uint128_t) in[7]) * inx2[7]; - - /* 15 */ - out[6] += ((uint128_t) in[7]) * inx4[8]; - - /* 16 */ - out[7] += ((uint128_t) in[8]) * inx2[8]; -} - -/*- - * felem_mul sets |out| = |in1| * |in2| - * On entry: - * in1[i] < 2^64 - * in2[i] < 2^63 - * On exit: - * out[i] < 17 * max(in1[i]) * max(in2[i]) - */ -static void felem_mul(largefelem out, const felem in1, const felem in2) -{ - felem in2x2; - felem_scalar(in2x2, in2, 2); - - out[0] = ((uint128_t) in1[0]) * in2[0]; - - out[1] = ((uint128_t) in1[0]) * in2[1] + ((uint128_t) in1[1]) * in2[0]; - - out[2] = ((uint128_t) in1[0]) * in2[2] + - ((uint128_t) in1[1]) * in2[1] + ((uint128_t) in1[2]) * in2[0]; - - out[3] = ((uint128_t) in1[0]) * in2[3] + - ((uint128_t) in1[1]) * in2[2] + - ((uint128_t) in1[2]) * in2[1] + ((uint128_t) in1[3]) * in2[0]; - - out[4] = ((uint128_t) in1[0]) * in2[4] + - ((uint128_t) in1[1]) * in2[3] + - ((uint128_t) in1[2]) * in2[2] + - ((uint128_t) in1[3]) * in2[1] + ((uint128_t) in1[4]) * in2[0]; - - out[5] = ((uint128_t) in1[0]) * in2[5] + - ((uint128_t) in1[1]) * in2[4] + - ((uint128_t) in1[2]) * in2[3] + - ((uint128_t) in1[3]) * in2[2] + - ((uint128_t) in1[4]) * in2[1] + ((uint128_t) in1[5]) * in2[0]; - - out[6] = ((uint128_t) in1[0]) * in2[6] + - ((uint128_t) in1[1]) * in2[5] + - ((uint128_t) in1[2]) * in2[4] + - ((uint128_t) in1[3]) * in2[3] + - ((uint128_t) in1[4]) * in2[2] + - ((uint128_t) in1[5]) * in2[1] + ((uint128_t) in1[6]) * in2[0]; - - out[7] = ((uint128_t) in1[0]) * in2[7] + - ((uint128_t) in1[1]) * in2[6] + - ((uint128_t) in1[2]) * in2[5] + - ((uint128_t) in1[3]) * in2[4] + - ((uint128_t) in1[4]) * in2[3] + - ((uint128_t) in1[5]) * in2[2] + - ((uint128_t) in1[6]) * in2[1] + ((uint128_t) in1[7]) * in2[0]; - - out[8] = ((uint128_t) in1[0]) * in2[8] + - ((uint128_t) in1[1]) * in2[7] + - ((uint128_t) in1[2]) * in2[6] + - ((uint128_t) in1[3]) * in2[5] + - ((uint128_t) in1[4]) * in2[4] + - ((uint128_t) in1[5]) * in2[3] + - ((uint128_t) in1[6]) * in2[2] + - ((uint128_t) in1[7]) * in2[1] + ((uint128_t) in1[8]) * in2[0]; - - /* See comment in felem_square about the use of in2x2 here */ - - out[0] += ((uint128_t) in1[1]) * in2x2[8] + - ((uint128_t) in1[2]) * in2x2[7] + - ((uint128_t) in1[3]) * in2x2[6] + - ((uint128_t) in1[4]) * in2x2[5] + - ((uint128_t) in1[5]) * in2x2[4] + - ((uint128_t) in1[6]) * in2x2[3] + - ((uint128_t) in1[7]) * in2x2[2] + ((uint128_t) in1[8]) * in2x2[1]; - - out[1] += ((uint128_t) in1[2]) * in2x2[8] + - ((uint128_t) in1[3]) * in2x2[7] + - ((uint128_t) in1[4]) * in2x2[6] + - ((uint128_t) in1[5]) * in2x2[5] + - ((uint128_t) in1[6]) * in2x2[4] + - ((uint128_t) in1[7]) * in2x2[3] + ((uint128_t) in1[8]) * in2x2[2]; - - out[2] += ((uint128_t) in1[3]) * in2x2[8] + - ((uint128_t) in1[4]) * in2x2[7] + - ((uint128_t) in1[5]) * in2x2[6] + - ((uint128_t) in1[6]) * in2x2[5] + - ((uint128_t) in1[7]) * in2x2[4] + ((uint128_t) in1[8]) * in2x2[3]; - - out[3] += ((uint128_t) in1[4]) * in2x2[8] + - ((uint128_t) in1[5]) * in2x2[7] + - ((uint128_t) in1[6]) * in2x2[6] + - ((uint128_t) in1[7]) * in2x2[5] + ((uint128_t) in1[8]) * in2x2[4]; - - out[4] += ((uint128_t) in1[5]) * in2x2[8] + - ((uint128_t) in1[6]) * in2x2[7] + - ((uint128_t) in1[7]) * in2x2[6] + ((uint128_t) in1[8]) * in2x2[5]; - - out[5] += ((uint128_t) in1[6]) * in2x2[8] + - ((uint128_t) in1[7]) * in2x2[7] + ((uint128_t) in1[8]) * in2x2[6]; - - out[6] += ((uint128_t) in1[7]) * in2x2[8] + - ((uint128_t) in1[8]) * in2x2[7]; - - out[7] += ((uint128_t) in1[8]) * in2x2[8]; -} - -static const limb bottom52bits = 0xfffffffffffff; - -/*- - * felem_reduce converts a largefelem to an felem. - * On entry: - * in[i] < 2^128 - * On exit: - * out[i] < 2^59 + 2^14 - */ -static void felem_reduce(felem out, const largefelem in) -{ - u64 overflow1, overflow2; - - out[0] = ((limb) in[0]) & bottom58bits; - out[1] = ((limb) in[1]) & bottom58bits; - out[2] = ((limb) in[2]) & bottom58bits; - out[3] = ((limb) in[3]) & bottom58bits; - out[4] = ((limb) in[4]) & bottom58bits; - out[5] = ((limb) in[5]) & bottom58bits; - out[6] = ((limb) in[6]) & bottom58bits; - out[7] = ((limb) in[7]) & bottom58bits; - out[8] = ((limb) in[8]) & bottom58bits; - - /* out[i] < 2^58 */ - - out[1] += ((limb) in[0]) >> 58; - out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6; - /*- - * out[1] < 2^58 + 2^6 + 2^58 - * = 2^59 + 2^6 - */ - out[2] += ((limb) (in[0] >> 64)) >> 52; - - out[2] += ((limb) in[1]) >> 58; - out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6; - out[3] += ((limb) (in[1] >> 64)) >> 52; - - out[3] += ((limb) in[2]) >> 58; - out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6; - out[4] += ((limb) (in[2] >> 64)) >> 52; - - out[4] += ((limb) in[3]) >> 58; - out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6; - out[5] += ((limb) (in[3] >> 64)) >> 52; - - out[5] += ((limb) in[4]) >> 58; - out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6; - out[6] += ((limb) (in[4] >> 64)) >> 52; - - out[6] += ((limb) in[5]) >> 58; - out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6; - out[7] += ((limb) (in[5] >> 64)) >> 52; - - out[7] += ((limb) in[6]) >> 58; - out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6; - out[8] += ((limb) (in[6] >> 64)) >> 52; - - out[8] += ((limb) in[7]) >> 58; - out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6; - /*- - * out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12 - * < 2^59 + 2^13 - */ - overflow1 = ((limb) (in[7] >> 64)) >> 52; - - overflow1 += ((limb) in[8]) >> 58; - overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6; - overflow2 = ((limb) (in[8] >> 64)) >> 52; - - overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */ - overflow2 <<= 1; /* overflow2 < 2^13 */ - - out[0] += overflow1; /* out[0] < 2^60 */ - out[1] += overflow2; /* out[1] < 2^59 + 2^6 + 2^13 */ - - out[1] += out[0] >> 58; - out[0] &= bottom58bits; - /*- - * out[0] < 2^58 - * out[1] < 2^59 + 2^6 + 2^13 + 2^2 - * < 2^59 + 2^14 - */ -} - -static void felem_square_reduce(felem out, const felem in) -{ - largefelem tmp; - felem_square(tmp, in); - felem_reduce(out, tmp); -} - -static void felem_mul_reduce(felem out, const felem in1, const felem in2) -{ - largefelem tmp; - felem_mul(tmp, in1, in2); - felem_reduce(out, tmp); -} - -/*- - * felem_inv calculates |out| = |in|^{-1} - * - * Based on Fermat's Little Theorem: - * a^p = a (mod p) - * a^{p-1} = 1 (mod p) - * a^{p-2} = a^{-1} (mod p) - */ -static void felem_inv(felem out, const felem in) -{ - felem ftmp, ftmp2, ftmp3, ftmp4; - largefelem tmp; - unsigned i; - - felem_square(tmp, in); - felem_reduce(ftmp, tmp); /* 2^1 */ - felem_mul(tmp, in, ftmp); - felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */ - felem_assign(ftmp2, ftmp); - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */ - felem_mul(tmp, in, ftmp); - felem_reduce(ftmp, tmp); /* 2^3 - 2^0 */ - felem_square(tmp, ftmp); - felem_reduce(ftmp, tmp); /* 2^4 - 2^1 */ - - felem_square(tmp, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^3 - 2^1 */ - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^4 - 2^2 */ - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^4 - 2^0 */ - - felem_assign(ftmp2, ftmp3); - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^5 - 2^1 */ - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^6 - 2^2 */ - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^7 - 2^3 */ - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^8 - 2^4 */ - felem_assign(ftmp4, ftmp3); - felem_mul(tmp, ftmp3, ftmp); - felem_reduce(ftmp4, tmp); /* 2^8 - 2^1 */ - felem_square(tmp, ftmp4); - felem_reduce(ftmp4, tmp); /* 2^9 - 2^2 */ - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^8 - 2^0 */ - felem_assign(ftmp2, ftmp3); - - for (i = 0; i < 8; i++) { - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */ - } - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^16 - 2^0 */ - felem_assign(ftmp2, ftmp3); - - for (i = 0; i < 16; i++) { - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */ - } - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^32 - 2^0 */ - felem_assign(ftmp2, ftmp3); - - for (i = 0; i < 32; i++) { - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */ - } - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^64 - 2^0 */ - felem_assign(ftmp2, ftmp3); - - for (i = 0; i < 64; i++) { - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */ - } - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^128 - 2^0 */ - felem_assign(ftmp2, ftmp3); - - for (i = 0; i < 128; i++) { - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */ - } - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^256 - 2^0 */ - felem_assign(ftmp2, ftmp3); - - for (i = 0; i < 256; i++) { - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */ - } - felem_mul(tmp, ftmp3, ftmp2); - felem_reduce(ftmp3, tmp); /* 2^512 - 2^0 */ - - for (i = 0; i < 9; i++) { - felem_square(tmp, ftmp3); - felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */ - } - felem_mul(tmp, ftmp3, ftmp4); - felem_reduce(ftmp3, tmp); /* 2^512 - 2^2 */ - felem_mul(tmp, ftmp3, in); - felem_reduce(out, tmp); /* 2^512 - 3 */ -} - -/* This is 2^521-1, expressed as an felem */ -static const felem kPrime = { - 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff, - 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff, - 0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff -}; - -/*- - * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0 - * otherwise. - * On entry: - * in[i] < 2^59 + 2^14 - */ -static limb felem_is_zero(const felem in) -{ - felem ftmp; - limb is_zero, is_p; - felem_assign(ftmp, in); - - ftmp[0] += ftmp[8] >> 57; - ftmp[8] &= bottom57bits; - /* ftmp[8] < 2^57 */ - ftmp[1] += ftmp[0] >> 58; - ftmp[0] &= bottom58bits; - ftmp[2] += ftmp[1] >> 58; - ftmp[1] &= bottom58bits; - ftmp[3] += ftmp[2] >> 58; - ftmp[2] &= bottom58bits; - ftmp[4] += ftmp[3] >> 58; - ftmp[3] &= bottom58bits; - ftmp[5] += ftmp[4] >> 58; - ftmp[4] &= bottom58bits; - ftmp[6] += ftmp[5] >> 58; - ftmp[5] &= bottom58bits; - ftmp[7] += ftmp[6] >> 58; - ftmp[6] &= bottom58bits; - ftmp[8] += ftmp[7] >> 58; - ftmp[7] &= bottom58bits; - /* ftmp[8] < 2^57 + 4 */ - - /* - * The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is greater - * than our bound for ftmp[8]. Therefore we only have to check if the - * zero is zero or 2^521-1. - */ - - is_zero = 0; - is_zero |= ftmp[0]; - is_zero |= ftmp[1]; - is_zero |= ftmp[2]; - is_zero |= ftmp[3]; - is_zero |= ftmp[4]; - is_zero |= ftmp[5]; - is_zero |= ftmp[6]; - is_zero |= ftmp[7]; - is_zero |= ftmp[8]; - - is_zero--; - /* - * We know that ftmp[i] < 2^63, therefore the only way that the top bit - * can be set is if is_zero was 0 before the decrement. - */ - is_zero = 0 - (is_zero >> 63); - - is_p = ftmp[0] ^ kPrime[0]; - is_p |= ftmp[1] ^ kPrime[1]; - is_p |= ftmp[2] ^ kPrime[2]; - is_p |= ftmp[3] ^ kPrime[3]; - is_p |= ftmp[4] ^ kPrime[4]; - is_p |= ftmp[5] ^ kPrime[5]; - is_p |= ftmp[6] ^ kPrime[6]; - is_p |= ftmp[7] ^ kPrime[7]; - is_p |= ftmp[8] ^ kPrime[8]; - - is_p--; - is_p = 0 - (is_p >> 63); - - is_zero |= is_p; - return is_zero; -} - -static int felem_is_zero_int(const void *in) -{ - return (int)(felem_is_zero(in) & ((limb) 1)); -} - -/*- - * felem_contract converts |in| to its unique, minimal representation. - * On entry: - * in[i] < 2^59 + 2^14 - */ -static void felem_contract(felem out, const felem in) -{ - limb is_p, is_greater, sign; - static const limb two58 = ((limb) 1) << 58; - - felem_assign(out, in); - - out[0] += out[8] >> 57; - out[8] &= bottom57bits; - /* out[8] < 2^57 */ - out[1] += out[0] >> 58; - out[0] &= bottom58bits; - out[2] += out[1] >> 58; - out[1] &= bottom58bits; - out[3] += out[2] >> 58; - out[2] &= bottom58bits; - out[4] += out[3] >> 58; - out[3] &= bottom58bits; - out[5] += out[4] >> 58; - out[4] &= bottom58bits; - out[6] += out[5] >> 58; - out[5] &= bottom58bits; - out[7] += out[6] >> 58; - out[6] &= bottom58bits; - out[8] += out[7] >> 58; - out[7] &= bottom58bits; - /* out[8] < 2^57 + 4 */ - - /* - * If the value is greater than 2^521-1 then we have to subtract 2^521-1 - * out. See the comments in felem_is_zero regarding why we don't test for - * other multiples of the prime. - */ - - /* - * First, if |out| is equal to 2^521-1, we subtract it out to get zero. - */ - - is_p = out[0] ^ kPrime[0]; - is_p |= out[1] ^ kPrime[1]; - is_p |= out[2] ^ kPrime[2]; - is_p |= out[3] ^ kPrime[3]; - is_p |= out[4] ^ kPrime[4]; - is_p |= out[5] ^ kPrime[5]; - is_p |= out[6] ^ kPrime[6]; - is_p |= out[7] ^ kPrime[7]; - is_p |= out[8] ^ kPrime[8]; - - is_p--; - is_p &= is_p << 32; - is_p &= is_p << 16; - is_p &= is_p << 8; - is_p &= is_p << 4; - is_p &= is_p << 2; - is_p &= is_p << 1; - is_p = 0 - (is_p >> 63); - is_p = ~is_p; - - /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */ - - out[0] &= is_p; - out[1] &= is_p; - out[2] &= is_p; - out[3] &= is_p; - out[4] &= is_p; - out[5] &= is_p; - out[6] &= is_p; - out[7] &= is_p; - out[8] &= is_p; - - /* - * In order to test that |out| >= 2^521-1 we need only test if out[8] >> - * 57 is greater than zero as (2^521-1) + x >= 2^522 - */ - is_greater = out[8] >> 57; - is_greater |= is_greater << 32; - is_greater |= is_greater << 16; - is_greater |= is_greater << 8; - is_greater |= is_greater << 4; - is_greater |= is_greater << 2; - is_greater |= is_greater << 1; - is_greater = 0 - (is_greater >> 63); - - out[0] -= kPrime[0] & is_greater; - out[1] -= kPrime[1] & is_greater; - out[2] -= kPrime[2] & is_greater; - out[3] -= kPrime[3] & is_greater; - out[4] -= kPrime[4] & is_greater; - out[5] -= kPrime[5] & is_greater; - out[6] -= kPrime[6] & is_greater; - out[7] -= kPrime[7] & is_greater; - out[8] -= kPrime[8] & is_greater; - - /* Eliminate negative coefficients */ - sign = -(out[0] >> 63); - out[0] += (two58 & sign); - out[1] -= (1 & sign); - sign = -(out[1] >> 63); - out[1] += (two58 & sign); - out[2] -= (1 & sign); - sign = -(out[2] >> 63); - out[2] += (two58 & sign); - out[3] -= (1 & sign); - sign = -(out[3] >> 63); - out[3] += (two58 & sign); - out[4] -= (1 & sign); - sign = -(out[4] >> 63); - out[4] += (two58 & sign); - out[5] -= (1 & sign); - sign = -(out[0] >> 63); - out[5] += (two58 & sign); - out[6] -= (1 & sign); - sign = -(out[6] >> 63); - out[6] += (two58 & sign); - out[7] -= (1 & sign); - sign = -(out[7] >> 63); - out[7] += (two58 & sign); - out[8] -= (1 & sign); - sign = -(out[5] >> 63); - out[5] += (two58 & sign); - out[6] -= (1 & sign); - sign = -(out[6] >> 63); - out[6] += (two58 & sign); - out[7] -= (1 & sign); - sign = -(out[7] >> 63); - out[7] += (two58 & sign); - out[8] -= (1 & sign); -} - -/*- - * Group operations - * ---------------- - * - * Building on top of the field operations we have the operations on the - * elliptic curve group itself. Points on the curve are represented in Jacobian - * coordinates */ - -/*- - * point_double calcuates 2*(x_in, y_in, z_in) - * - * The method is taken from: - * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b - * - * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. - * while x_out == y_in is not (maybe this works, but it's not tested). */ -static void -point_double(felem x_out, felem y_out, felem z_out, - const felem x_in, const felem y_in, const felem z_in) -{ - largefelem tmp, tmp2; - felem delta, gamma, beta, alpha, ftmp, ftmp2; - - felem_assign(ftmp, x_in); - felem_assign(ftmp2, x_in); - - /* delta = z^2 */ - felem_square(tmp, z_in); - felem_reduce(delta, tmp); /* delta[i] < 2^59 + 2^14 */ - - /* gamma = y^2 */ - felem_square(tmp, y_in); - felem_reduce(gamma, tmp); /* gamma[i] < 2^59 + 2^14 */ - - /* beta = x*gamma */ - felem_mul(tmp, x_in, gamma); - felem_reduce(beta, tmp); /* beta[i] < 2^59 + 2^14 */ - - /* alpha = 3*(x-delta)*(x+delta) */ - felem_diff64(ftmp, delta); - /* ftmp[i] < 2^61 */ - felem_sum64(ftmp2, delta); - /* ftmp2[i] < 2^60 + 2^15 */ - felem_scalar64(ftmp2, 3); - /* ftmp2[i] < 3*2^60 + 3*2^15 */ - felem_mul(tmp, ftmp, ftmp2); - /*- - * tmp[i] < 17(3*2^121 + 3*2^76) - * = 61*2^121 + 61*2^76 - * < 64*2^121 + 64*2^76 - * = 2^127 + 2^82 - * < 2^128 - */ - felem_reduce(alpha, tmp); - - /* x' = alpha^2 - 8*beta */ - felem_square(tmp, alpha); - /* - * tmp[i] < 17*2^120 < 2^125 - */ - felem_assign(ftmp, beta); - felem_scalar64(ftmp, 8); - /* ftmp[i] < 2^62 + 2^17 */ - felem_diff_128_64(tmp, ftmp); - /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */ - felem_reduce(x_out, tmp); - - /* z' = (y + z)^2 - gamma - delta */ - felem_sum64(delta, gamma); - /* delta[i] < 2^60 + 2^15 */ - felem_assign(ftmp, y_in); - felem_sum64(ftmp, z_in); - /* ftmp[i] < 2^60 + 2^15 */ - felem_square(tmp, ftmp); - /* - * tmp[i] < 17(2^122) < 2^127 - */ - felem_diff_128_64(tmp, delta); - /* tmp[i] < 2^127 + 2^63 */ - felem_reduce(z_out, tmp); - - /* y' = alpha*(4*beta - x') - 8*gamma^2 */ - felem_scalar64(beta, 4); - /* beta[i] < 2^61 + 2^16 */ - felem_diff64(beta, x_out); - /* beta[i] < 2^61 + 2^60 + 2^16 */ - felem_mul(tmp, alpha, beta); - /*- - * tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16)) - * = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30) - * = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30) - * < 2^128 - */ - felem_square(tmp2, gamma); - /*- - * tmp2[i] < 17*(2^59 + 2^14)^2 - * = 17*(2^118 + 2^74 + 2^28) - */ - felem_scalar128(tmp2, 8); - /*- - * tmp2[i] < 8*17*(2^118 + 2^74 + 2^28) - * = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31 - * < 2^126 - */ - felem_diff128(tmp, tmp2); - /*- - * tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30) - * = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 + - * 2^74 + 2^69 + 2^34 + 2^30 - * < 2^128 - */ - felem_reduce(y_out, tmp); -} - -/* copy_conditional copies in to out iff mask is all ones. */ -static void copy_conditional(felem out, const felem in, limb mask) -{ - unsigned i; - for (i = 0; i < NLIMBS; ++i) { - const limb tmp = mask & (in[i] ^ out[i]); - out[i] ^= tmp; - } -} - -/*- - * point_add calcuates (x1, y1, z1) + (x2, y2, z2) - * - * The method is taken from - * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, - * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). - * - * This function includes a branch for checking whether the two input points - * are equal (while not equal to the point at infinity). This case never - * happens during single point multiplication, so there is no timing leak for - * ECDH or ECDSA signing. */ -static void point_add(felem x3, felem y3, felem z3, - const felem x1, const felem y1, const felem z1, - const int mixed, const felem x2, const felem y2, - const felem z2) -{ - felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out; - largefelem tmp, tmp2; - limb x_equal, y_equal, z1_is_zero, z2_is_zero; - - z1_is_zero = felem_is_zero(z1); - z2_is_zero = felem_is_zero(z2); - - /* ftmp = z1z1 = z1**2 */ - felem_square(tmp, z1); - felem_reduce(ftmp, tmp); - - if (!mixed) { - /* ftmp2 = z2z2 = z2**2 */ - felem_square(tmp, z2); - felem_reduce(ftmp2, tmp); - - /* u1 = ftmp3 = x1*z2z2 */ - felem_mul(tmp, x1, ftmp2); - felem_reduce(ftmp3, tmp); - - /* ftmp5 = z1 + z2 */ - felem_assign(ftmp5, z1); - felem_sum64(ftmp5, z2); - /* ftmp5[i] < 2^61 */ - - /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */ - felem_square(tmp, ftmp5); - /* tmp[i] < 17*2^122 */ - felem_diff_128_64(tmp, ftmp); - /* tmp[i] < 17*2^122 + 2^63 */ - felem_diff_128_64(tmp, ftmp2); - /* tmp[i] < 17*2^122 + 2^64 */ - felem_reduce(ftmp5, tmp); - - /* ftmp2 = z2 * z2z2 */ - felem_mul(tmp, ftmp2, z2); - felem_reduce(ftmp2, tmp); - - /* s1 = ftmp6 = y1 * z2**3 */ - felem_mul(tmp, y1, ftmp2); - felem_reduce(ftmp6, tmp); - } else { - /* - * We'll assume z2 = 1 (special case z2 = 0 is handled later) - */ - - /* u1 = ftmp3 = x1*z2z2 */ - felem_assign(ftmp3, x1); - - /* ftmp5 = 2*z1z2 */ - felem_scalar(ftmp5, z1, 2); - - /* s1 = ftmp6 = y1 * z2**3 */ - felem_assign(ftmp6, y1); - } - - /* u2 = x2*z1z1 */ - felem_mul(tmp, x2, ftmp); - /* tmp[i] < 17*2^120 */ - - /* h = ftmp4 = u2 - u1 */ - felem_diff_128_64(tmp, ftmp3); - /* tmp[i] < 17*2^120 + 2^63 */ - felem_reduce(ftmp4, tmp); - - x_equal = felem_is_zero(ftmp4); - - /* z_out = ftmp5 * h */ - felem_mul(tmp, ftmp5, ftmp4); - felem_reduce(z_out, tmp); - - /* ftmp = z1 * z1z1 */ - felem_mul(tmp, ftmp, z1); - felem_reduce(ftmp, tmp); - - /* s2 = tmp = y2 * z1**3 */ - felem_mul(tmp, y2, ftmp); - /* tmp[i] < 17*2^120 */ - - /* r = ftmp5 = (s2 - s1)*2 */ - felem_diff_128_64(tmp, ftmp6); - /* tmp[i] < 17*2^120 + 2^63 */ - felem_reduce(ftmp5, tmp); - y_equal = felem_is_zero(ftmp5); - felem_scalar64(ftmp5, 2); - /* ftmp5[i] < 2^61 */ - - if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { - point_double(x3, y3, z3, x1, y1, z1); - return; - } - - /* I = ftmp = (2h)**2 */ - felem_assign(ftmp, ftmp4); - felem_scalar64(ftmp, 2); - /* ftmp[i] < 2^61 */ - felem_square(tmp, ftmp); - /* tmp[i] < 17*2^122 */ - felem_reduce(ftmp, tmp); - - /* J = ftmp2 = h * I */ - felem_mul(tmp, ftmp4, ftmp); - felem_reduce(ftmp2, tmp); - - /* V = ftmp4 = U1 * I */ - felem_mul(tmp, ftmp3, ftmp); - felem_reduce(ftmp4, tmp); - - /* x_out = r**2 - J - 2V */ - felem_square(tmp, ftmp5); - /* tmp[i] < 17*2^122 */ - felem_diff_128_64(tmp, ftmp2); - /* tmp[i] < 17*2^122 + 2^63 */ - felem_assign(ftmp3, ftmp4); - felem_scalar64(ftmp4, 2); - /* ftmp4[i] < 2^61 */ - felem_diff_128_64(tmp, ftmp4); - /* tmp[i] < 17*2^122 + 2^64 */ - felem_reduce(x_out, tmp); - - /* y_out = r(V-x_out) - 2 * s1 * J */ - felem_diff64(ftmp3, x_out); - /* - * ftmp3[i] < 2^60 + 2^60 = 2^61 - */ - felem_mul(tmp, ftmp5, ftmp3); - /* tmp[i] < 17*2^122 */ - felem_mul(tmp2, ftmp6, ftmp2); - /* tmp2[i] < 17*2^120 */ - felem_scalar128(tmp2, 2); - /* tmp2[i] < 17*2^121 */ - felem_diff128(tmp, tmp2); - /*- - * tmp[i] < 2^127 - 2^69 + 17*2^122 - * = 2^126 - 2^122 - 2^6 - 2^2 - 1 - * < 2^127 - */ - felem_reduce(y_out, tmp); - - copy_conditional(x_out, x2, z1_is_zero); - copy_conditional(x_out, x1, z2_is_zero); - copy_conditional(y_out, y2, z1_is_zero); - copy_conditional(y_out, y1, z2_is_zero); - copy_conditional(z_out, z2, z1_is_zero); - copy_conditional(z_out, z1, z2_is_zero); - felem_assign(x3, x_out); - felem_assign(y3, y_out); - felem_assign(z3, z_out); -} - -/*- - * Base point pre computation - * -------------------------- - * - * Two different sorts of precomputed tables are used in the following code. - * Each contain various points on the curve, where each point is three field - * elements (x, y, z). - * - * For the base point table, z is usually 1 (0 for the point at infinity). - * This table has 16 elements: - * index | bits | point - * ------+---------+------------------------------ - * 0 | 0 0 0 0 | 0G - * 1 | 0 0 0 1 | 1G - * 2 | 0 0 1 0 | 2^130G - * 3 | 0 0 1 1 | (2^130 + 1)G - * 4 | 0 1 0 0 | 2^260G - * 5 | 0 1 0 1 | (2^260 + 1)G - * 6 | 0 1 1 0 | (2^260 + 2^130)G - * 7 | 0 1 1 1 | (2^260 + 2^130 + 1)G - * 8 | 1 0 0 0 | 2^390G - * 9 | 1 0 0 1 | (2^390 + 1)G - * 10 | 1 0 1 0 | (2^390 + 2^130)G - * 11 | 1 0 1 1 | (2^390 + 2^130 + 1)G - * 12 | 1 1 0 0 | (2^390 + 2^260)G - * 13 | 1 1 0 1 | (2^390 + 2^260 + 1)G - * 14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G - * 15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G - * - * The reason for this is so that we can clock bits into four different - * locations when doing simple scalar multiplies against the base point. - * - * Tables for other points have table[i] = iG for i in 0 .. 16. */ - -/* gmul is the table of precomputed base points */ -static const felem gmul[16][3] = { {{0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334, - 0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8, - 0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404}, - {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353, - 0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45, - 0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad, - 0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e, - 0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5}, - {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58, - 0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c, - 0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873, - 0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c, - 0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9}, - {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52, - 0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e, - 0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2, - 0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561, - 0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065}, - {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a, - 0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e, - 0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6, - 0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51, - 0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe}, - {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d, - 0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c, - 0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27, - 0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f, - 0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256}, - {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa, - 0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2, - 0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890, - 0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74, - 0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23}, - {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516, - 0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1, - 0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce, - 0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7, - 0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5}, - {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318, - 0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83, - 0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae, - 0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef, - 0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203}, - {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447, - 0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283, - 0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5, - 0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c, - 0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a}, - {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df, - 0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645, - 0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292, - 0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422, - 0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b}, - {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30, - 0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb, - 0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767, - 0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3, - 0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf}, - {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2, - 0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692, - 0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3, - 0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade, - 0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684}, - {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8, - 0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a, - 0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608, - 0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610, - 0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d}, - {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006, - 0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86, - 0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}}, -{{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c, - 0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9, - 0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f}, - {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7, - 0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c, - 0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055}, - {1, 0, 0, 0, 0, 0, 0, 0, 0}} -}; - -/* - * select_point selects the |idx|th point from a precomputation table and - * copies it to out. - */ - /* pre_comp below is of the size provided in |size| */ -static void select_point(const limb idx, unsigned int size, - const felem pre_comp[][3], felem out[3]) -{ - unsigned i, j; - limb *outlimbs = &out[0][0]; - memset(outlimbs, 0, 3 * sizeof(felem)); - - for (i = 0; i < size; i++) { - const limb *inlimbs = &pre_comp[i][0][0]; - limb mask = i ^ idx; - mask |= mask >> 4; - mask |= mask >> 2; - mask |= mask >> 1; - mask &= 1; - mask--; - for (j = 0; j < NLIMBS * 3; j++) - outlimbs[j] |= inlimbs[j] & mask; - } -} - -/* get_bit returns the |i|th bit in |in| */ -static char get_bit(const felem_bytearray in, int i) -{ - if (i < 0) - return 0; - return (in[i >> 3] >> (i & 7)) & 1; -} - -/* - * Interleaved point multiplication using precomputed point multiples: The - * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars - * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the - * generator, using certain (large) precomputed multiples in g_pre_comp. - * Output point (X, Y, Z) is stored in x_out, y_out, z_out - */ -static void batch_mul(felem x_out, felem y_out, felem z_out, - const felem_bytearray scalars[], - const unsigned num_points, const u8 *g_scalar, - const int mixed, const felem pre_comp[][17][3], - const felem g_pre_comp[16][3]) -{ - int i, skip; - unsigned num, gen_mul = (g_scalar != NULL); - felem nq[3], tmp[4]; - limb bits; - u8 sign, digit; - - /* set nq to the point at infinity */ - memset(nq, 0, 3 * sizeof(felem)); - - /* - * Loop over all scalars msb-to-lsb, interleaving additions of multiples - * of the generator (last quarter of rounds) and additions of other - * points multiples (every 5th round). - */ - skip = 1; /* save two point operations in the first - * round */ - for (i = (num_points ? 520 : 130); i >= 0; --i) { - /* double */ - if (!skip) - point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); - - /* add multiples of the generator */ - if (gen_mul && (i <= 130)) { - bits = get_bit(g_scalar, i + 390) << 3; - if (i < 130) { - bits |= get_bit(g_scalar, i + 260) << 2; - bits |= get_bit(g_scalar, i + 130) << 1; - bits |= get_bit(g_scalar, i); - } - /* select the point to add, in constant time */ - select_point(bits, 16, g_pre_comp, tmp); - if (!skip) { - /* The 1 argument below is for "mixed" */ - point_add(nq[0], nq[1], nq[2], - nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); - } else { - memcpy(nq, tmp, 3 * sizeof(felem)); - skip = 0; - } - } - - /* do other additions every 5 doublings */ - if (num_points && (i % 5 == 0)) { - /* loop over all scalars */ - for (num = 0; num < num_points; ++num) { - bits = get_bit(scalars[num], i + 4) << 5; - bits |= get_bit(scalars[num], i + 3) << 4; - bits |= get_bit(scalars[num], i + 2) << 3; - bits |= get_bit(scalars[num], i + 1) << 2; - bits |= get_bit(scalars[num], i) << 1; - bits |= get_bit(scalars[num], i - 1); - ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); - - /* - * select the point to add or subtract, in constant time - */ - select_point(digit, 17, pre_comp[num], tmp); - felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative - * point */ - copy_conditional(tmp[1], tmp[3], (-(limb) sign)); - - if (!skip) { - point_add(nq[0], nq[1], nq[2], - nq[0], nq[1], nq[2], - mixed, tmp[0], tmp[1], tmp[2]); - } else { - memcpy(nq, tmp, 3 * sizeof(felem)); - skip = 0; - } - } - } - } - felem_assign(x_out, nq[0]); - felem_assign(y_out, nq[1]); - felem_assign(z_out, nq[2]); -} - -/* Precomputation for the group generator. */ -typedef struct { - felem g_pre_comp[16][3]; - int references; -} NISTP521_PRE_COMP; - -const EC_METHOD *EC_GFp_nistp521_method(void) -{ - static const EC_METHOD ret = { - EC_FLAGS_DEFAULT_OCT, - NID_X9_62_prime_field, - ec_GFp_nistp521_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_nist_group_copy, - ec_GFp_nistp521_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_nistp521_point_get_affine_coordinates, - 0 /* point_set_compressed_coordinates */ , - 0 /* point2oct */ , - 0 /* oct2point */ , - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - ec_GFp_nistp521_points_mul, - ec_GFp_nistp521_precompute_mult, - ec_GFp_nistp521_have_precompute_mult, - ec_GFp_nist_field_mul, - ec_GFp_nist_field_sqr, - 0 /* field_div */ , - 0 /* field_encode */ , - 0 /* field_decode */ , - 0 /* field_set_to_one */ - }; - - return &ret; -} - -/******************************************************************************/ -/* - * FUNCTIONS TO MANAGE PRECOMPUTATION - */ - -static NISTP521_PRE_COMP *nistp521_pre_comp_new() -{ - NISTP521_PRE_COMP *ret = NULL; - ret = (NISTP521_PRE_COMP *) OPENSSL_malloc(sizeof(NISTP521_PRE_COMP)); - if (!ret) { - ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); - return ret; - } - memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); - ret->references = 1; - return ret; -} - -static void *nistp521_pre_comp_dup(void *src_) -{ - NISTP521_PRE_COMP *src = src_; - - /* no need to actually copy, these objects never change! */ - CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); - - return src_; -} - -static void nistp521_pre_comp_free(void *pre_) -{ - int i; - NISTP521_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - OPENSSL_free(pre); -} - -static void nistp521_pre_comp_clear_free(void *pre_) -{ - int i; - NISTP521_PRE_COMP *pre = pre_; - - if (!pre) - return; - - i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); - if (i > 0) - return; - - OPENSSL_cleanse(pre, sizeof(*pre)); - OPENSSL_free(pre); -} - -/******************************************************************************/ -/* - * OPENSSL EC_METHOD FUNCTIONS - */ - -int ec_GFp_nistp521_group_init(EC_GROUP *group) -{ - int ret; - ret = ec_GFp_simple_group_init(group); - group->a_is_minus3 = 1; - return ret; -} - -int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, - const BIGNUM *a, const BIGNUM *b, - BN_CTX *ctx) -{ - int ret = 0; - BN_CTX *new_ctx = NULL; - BIGNUM *curve_p, *curve_a, *curve_b; - - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((curve_p = BN_CTX_get(ctx)) == NULL) || - ((curve_a = BN_CTX_get(ctx)) == NULL) || - ((curve_b = BN_CTX_get(ctx)) == NULL)) - goto err; - BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p); - BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a); - BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b); - if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { - ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, - EC_R_WRONG_CURVE_PARAMETERS); - goto err; - } - group->field_mod_func = BN_nist_mod_521; - ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -/* - * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = - * (X/Z^2, Y/Z^3) - */ -int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) -{ - felem z1, z2, x_in, y_in, x_out, y_out; - largefelem tmp; - - if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); - return 0; - } - if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || - (!BN_to_felem(z1, &point->Z))) - return 0; - felem_inv(z2, z1); - felem_square(tmp, z2); - felem_reduce(z1, tmp); - felem_mul(tmp, x_in, z1); - felem_reduce(x_in, tmp); - felem_contract(x_out, x_in); - if (x != NULL) { - if (!felem_to_BN(x, x_out)) { - ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); - return 0; - } - } - felem_mul(tmp, z1, z2); - felem_reduce(z1, tmp); - felem_mul(tmp, y_in, z1); - felem_reduce(y_in, tmp); - felem_contract(y_out, y_in); - if (y != NULL) { - if (!felem_to_BN(y, y_out)) { - ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); - return 0; - } - } - return 1; -} - -/* points below is of size |num|, and tmp_felems is of size |num+1/ */ -static void make_points_affine(size_t num, felem points[][3], - felem tmp_felems[]) -{ - /* - * Runs in constant time, unless an input is the point at infinity (which - * normally shouldn't happen). - */ - ec_GFp_nistp_points_make_affine_internal(num, - points, - sizeof(felem), - tmp_felems, - (void (*)(void *))felem_one, - felem_is_zero_int, - (void (*)(void *, const void *)) - felem_assign, - (void (*)(void *, const void *)) - felem_square_reduce, (void (*) - (void *, - const void - *, - const void - *)) - felem_mul_reduce, - (void (*)(void *, const void *)) - felem_inv, - (void (*)(void *, const void *)) - felem_contract); -} - -/* - * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL - * values Result is stored in r (r can equal one of the inputs). - */ -int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, - const BIGNUM *scalar, size_t num, - const EC_POINT *points[], - const BIGNUM *scalars[], BN_CTX *ctx) -{ - int ret = 0; - int j; - int mixed = 0; - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y, *z, *tmp_scalar; - felem_bytearray g_secret; - felem_bytearray *secrets = NULL; - felem(*pre_comp)[17][3] = NULL; - felem *tmp_felems = NULL; - felem_bytearray tmp; - unsigned i, num_bytes; - int have_pre_comp = 0; - size_t num_points = num; - felem x_in, y_in, z_in, x_out, y_out, z_out; - NISTP521_PRE_COMP *pre = NULL; - felem(*g_pre_comp)[3] = NULL; - EC_POINT *generator = NULL; - const EC_POINT *p = NULL; - const BIGNUM *p_scalar = NULL; - - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((x = BN_CTX_get(ctx)) == NULL) || - ((y = BN_CTX_get(ctx)) == NULL) || - ((z = BN_CTX_get(ctx)) == NULL) || - ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) - goto err; - - if (scalar != NULL) { - pre = EC_EX_DATA_get_data(group->extra_data, - nistp521_pre_comp_dup, - nistp521_pre_comp_free, - nistp521_pre_comp_clear_free); - if (pre) - /* we have precomputation, try to use it */ - g_pre_comp = &pre->g_pre_comp[0]; - else - /* try to use the standard precomputation */ - g_pre_comp = (felem(*)[3]) gmul; - generator = EC_POINT_new(group); - if (generator == NULL) - goto err; - /* get the generator from precomputation */ - if (!felem_to_BN(x, g_pre_comp[1][0]) || - !felem_to_BN(y, g_pre_comp[1][1]) || - !felem_to_BN(z, g_pre_comp[1][2])) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - if (!EC_POINT_set_Jprojective_coordinates_GFp(group, - generator, x, y, z, - ctx)) - goto err; - if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) - /* precomputation matches generator */ - have_pre_comp = 1; - else - /* - * we don't have valid precomputation: treat the generator as a - * random point - */ - num_points++; - } - - if (num_points > 0) { - if (num_points >= 2) { - /* - * unless we precompute multiples for just one point, converting - * those into affine form is time well spent - */ - mixed = 1; - } - secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); - pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem)); - if (mixed) - tmp_felems = - OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem)); - if ((secrets == NULL) || (pre_comp == NULL) - || (mixed && (tmp_felems == NULL))) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * we treat NULL scalars as 0, and NULL points as points at infinity, - * i.e., they contribute nothing to the linear combination - */ - memset(secrets, 0, num_points * sizeof(felem_bytearray)); - memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem)); - for (i = 0; i < num_points; ++i) { - if (i == num) - /* - * we didn't have a valid precomputation, so we pick the - * generator - */ - { - p = EC_GROUP_get0_generator(group); - p_scalar = scalar; - } else - /* the i^th point */ - { - p = points[i]; - p_scalar = scalars[i]; - } - if ((p_scalar != NULL) && (p != NULL)) { - /* reduce scalar to 0 <= scalar < 2^521 */ - if ((BN_num_bits(p_scalar) > 521) - || (BN_is_negative(p_scalar))) { - /* - * this is an unusual input, and we don't guarantee - * constant-timeness - */ - if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(p_scalar, tmp); - flip_endian(secrets[i], tmp, num_bytes); - /* precompute multiples */ - if ((!BN_to_felem(x_out, &p->X)) || - (!BN_to_felem(y_out, &p->Y)) || - (!BN_to_felem(z_out, &p->Z))) - goto err; - memcpy(pre_comp[i][1][0], x_out, sizeof(felem)); - memcpy(pre_comp[i][1][1], y_out, sizeof(felem)); - memcpy(pre_comp[i][1][2], z_out, sizeof(felem)); - for (j = 2; j <= 16; ++j) { - if (j & 1) { - point_add(pre_comp[i][j][0], pre_comp[i][j][1], - pre_comp[i][j][2], pre_comp[i][1][0], - pre_comp[i][1][1], pre_comp[i][1][2], 0, - pre_comp[i][j - 1][0], - pre_comp[i][j - 1][1], - pre_comp[i][j - 1][2]); - } else { - point_double(pre_comp[i][j][0], pre_comp[i][j][1], - pre_comp[i][j][2], pre_comp[i][j / 2][0], - pre_comp[i][j / 2][1], - pre_comp[i][j / 2][2]); - } - } - } - } - if (mixed) - make_points_affine(num_points * 17, pre_comp[0], tmp_felems); - } - - /* the scalar for the generator */ - if ((scalar != NULL) && (have_pre_comp)) { - memset(g_secret, 0, sizeof(g_secret)); - /* reduce scalar to 0 <= scalar < 2^521 */ - if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar))) { - /* - * this is an unusual input, and we don't guarantee - * constant-timeness - */ - if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - num_bytes = BN_bn2bin(tmp_scalar, tmp); - } else - num_bytes = BN_bn2bin(scalar, tmp); - flip_endian(g_secret, tmp, num_bytes); - /* do the multiplication with generator precomputation */ - batch_mul(x_out, y_out, z_out, - (const felem_bytearray(*))secrets, num_points, - g_secret, - mixed, (const felem(*)[17][3])pre_comp, - (const felem(*)[3])g_pre_comp); - } else - /* do the multiplication without generator precomputation */ - batch_mul(x_out, y_out, z_out, - (const felem_bytearray(*))secrets, num_points, - NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); - /* reduce the output to its unique minimal representation */ - felem_contract(x_in, x_out); - felem_contract(y_in, y_out); - felem_contract(z_in, z_out); - if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || - (!felem_to_BN(z, z_in))) { - ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); - goto err; - } - ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); - - err: - BN_CTX_end(ctx); - if (generator != NULL) - EC_POINT_free(generator); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (secrets != NULL) - OPENSSL_free(secrets); - if (pre_comp != NULL) - OPENSSL_free(pre_comp); - if (tmp_felems != NULL) - OPENSSL_free(tmp_felems); - return ret; -} - -int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx) -{ - int ret = 0; - NISTP521_PRE_COMP *pre = NULL; - int i, j; - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y; - EC_POINT *generator = NULL; - felem tmp_felems[16]; - - /* throw away old precomputation */ - EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup, - nistp521_pre_comp_free, - nistp521_pre_comp_clear_free); - if (ctx == NULL) - if ((ctx = new_ctx = BN_CTX_new()) == NULL) - return 0; - BN_CTX_start(ctx); - if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) - goto err; - /* get the generator */ - if (group->generator == NULL) - goto err; - generator = EC_POINT_new(group); - if (generator == NULL) - goto err; - BN_bin2bn(nistp521_curve_params[3], sizeof(felem_bytearray), x); - BN_bin2bn(nistp521_curve_params[4], sizeof(felem_bytearray), y); - if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) - goto err; - if ((pre = nistp521_pre_comp_new()) == NULL) - goto err; - /* - * if the generator is the standard one, use built-in precomputation - */ - if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { - memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); - goto done; - } - if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) || - (!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) || - (!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z))) - goto err; - /* compute 2^130*G, 2^260*G, 2^390*G */ - for (i = 1; i <= 4; i <<= 1) { - point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], - pre->g_pre_comp[2 * i][2], pre->g_pre_comp[i][0], - pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]); - for (j = 0; j < 129; ++j) { - point_double(pre->g_pre_comp[2 * i][0], - pre->g_pre_comp[2 * i][1], - pre->g_pre_comp[2 * i][2], - pre->g_pre_comp[2 * i][0], - pre->g_pre_comp[2 * i][1], - pre->g_pre_comp[2 * i][2]); - } - } - /* g_pre_comp[0] is the point at infinity */ - memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0])); - /* the remaining multiples */ - /* 2^130*G + 2^260*G */ - point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1], - pre->g_pre_comp[6][2], pre->g_pre_comp[4][0], - pre->g_pre_comp[4][1], pre->g_pre_comp[4][2], - 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], - pre->g_pre_comp[2][2]); - /* 2^130*G + 2^390*G */ - point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1], - pre->g_pre_comp[10][2], pre->g_pre_comp[8][0], - pre->g_pre_comp[8][1], pre->g_pre_comp[8][2], - 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], - pre->g_pre_comp[2][2]); - /* 2^260*G + 2^390*G */ - point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1], - pre->g_pre_comp[12][2], pre->g_pre_comp[8][0], - pre->g_pre_comp[8][1], pre->g_pre_comp[8][2], - 0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1], - pre->g_pre_comp[4][2]); - /* 2^130*G + 2^260*G + 2^390*G */ - point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1], - pre->g_pre_comp[14][2], pre->g_pre_comp[12][0], - pre->g_pre_comp[12][1], pre->g_pre_comp[12][2], - 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], - pre->g_pre_comp[2][2]); - for (i = 1; i < 8; ++i) { - /* odd multiples: add G */ - point_add(pre->g_pre_comp[2 * i + 1][0], - pre->g_pre_comp[2 * i + 1][1], - pre->g_pre_comp[2 * i + 1][2], pre->g_pre_comp[2 * i][0], - pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], 0, - pre->g_pre_comp[1][0], pre->g_pre_comp[1][1], - pre->g_pre_comp[1][2]); - } - make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems); - - done: - if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup, - nistp521_pre_comp_free, - nistp521_pre_comp_clear_free)) - goto err; - ret = 1; - pre = NULL; - err: - BN_CTX_end(ctx); - if (generator != NULL) - EC_POINT_free(generator); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (pre) - nistp521_pre_comp_free(pre); - return ret; -} - -int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group) -{ - if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup, - nistp521_pre_comp_free, - nistp521_pre_comp_clear_free) - != NULL) - return 1; - else - return 0; -} - -#else -static void *dummy = &dummy; -#endif diff --git a/Sources/COpenSSL/ecp_nistputil.c b/Sources/COpenSSL/ecp_nistputil.c deleted file mode 100644 index 41ea2858..00000000 --- a/Sources/COpenSSL/ecp_nistputil.c +++ /dev/null @@ -1,218 +0,0 @@ -/* crypto/ec/ecp_nistputil.c */ -/* - * Written by Bodo Moeller for the OpenSSL project. - */ -/* Copyright 2011 Google Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "opensslconf.h" -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 - -/* - * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c. - */ - -# include -# include "ec_lcl.h" - -/* - * Convert an array of points into affine coordinates. (If the point at - * infinity is found (Z = 0), it remains unchanged.) This function is - * essentially an equivalent to EC_POINTs_make_affine(), but works with the - * internal representation of points as used by ecp_nistp###.c rather than - * with (BIGNUM-based) EC_POINT data structures. point_array is the - * input/output buffer ('num' points in projective form, i.e. three - * coordinates each), based on an internal representation of field elements - * of size 'felem_size'. tmp_felems needs to point to a temporary array of - * 'num'+1 field elements for storage of intermediate values. - */ -void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, - size_t felem_size, - void *tmp_felems, - void (*felem_one) (void *out), - int (*felem_is_zero) (const void - *in), - void (*felem_assign) (void *out, - const void - *in), - void (*felem_square) (void *out, - const void - *in), - void (*felem_mul) (void *out, - const void - *in1, - const void - *in2), - void (*felem_inv) (void *out, - const void - *in), - void (*felem_contract) (void - *out, - const - void - *in)) -{ - int i = 0; - -# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size]) -# define X(I) (&((char *)point_array)[3*(I) * felem_size]) -# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size]) -# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size]) - - if (!felem_is_zero(Z(0))) - felem_assign(tmp_felem(0), Z(0)); - else - felem_one(tmp_felem(0)); - for (i = 1; i < (int)num; i++) { - if (!felem_is_zero(Z(i))) - felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i)); - else - felem_assign(tmp_felem(i), tmp_felem(i - 1)); - } - /* - * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any - * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1 - */ - - felem_inv(tmp_felem(num - 1), tmp_felem(num - 1)); - for (i = num - 1; i >= 0; i--) { - if (i > 0) - /* - * tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i) - * is the inverse of the product of Z(0) .. Z(i) - */ - /* 1/Z(i) */ - felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i)); - else - felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */ - - if (!felem_is_zero(Z(i))) { - if (i > 0) - /* - * For next iteration, replace tmp_felem(i-1) by its inverse - */ - felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i)); - - /* - * Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) - */ - felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */ - felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */ - felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */ - felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */ - felem_contract(X(i), X(i)); - felem_contract(Y(i), Y(i)); - felem_one(Z(i)); - } else { - if (i > 0) - /* - * For next iteration, replace tmp_felem(i-1) by its inverse - */ - felem_assign(tmp_felem(i - 1), tmp_felem(i)); - } - } -} - -/*- - * This function looks at 5+1 scalar bits (5 current, 1 adjacent less - * significant bit), and recodes them into a signed digit for use in fast point - * multiplication: the use of signed rather than unsigned digits means that - * fewer points need to be precomputed, given that point inversion is easy - * (a precomputed point dP makes -dP available as well). - * - * BACKGROUND: - * - * Signed digits for multiplication were introduced by Booth ("A signed binary - * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV, - * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers. - * Booth's original encoding did not generally improve the density of nonzero - * digits over the binary representation, and was merely meant to simplify the - * handling of signed factors given in two's complement; but it has since been - * shown to be the basis of various signed-digit representations that do have - * further advantages, including the wNAF, using the following general approach: - * - * (1) Given a binary representation - * - * b_k ... b_2 b_1 b_0, - * - * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1 - * by using bit-wise subtraction as follows: - * - * b_k b_(k-1) ... b_2 b_1 b_0 - * - b_k ... b_3 b_2 b_1 b_0 - * ------------------------------------- - * s_k b_(k-1) ... s_3 s_2 s_1 s_0 - * - * A left-shift followed by subtraction of the original value yields a new - * representation of the same value, using signed bits s_i = b_(i+1) - b_i. - * This representation from Booth's paper has since appeared in the - * literature under a variety of different names including "reversed binary - * form", "alternating greedy expansion", "mutual opposite form", and - * "sign-alternating {+-1}-representation". - * - * An interesting property is that among the nonzero bits, values 1 and -1 - * strictly alternate. - * - * (2) Various window schemes can be applied to the Booth representation of - * integers: for example, right-to-left sliding windows yield the wNAF - * (a signed-digit encoding independently discovered by various researchers - * in the 1990s), and left-to-right sliding windows yield a left-to-right - * equivalent of the wNAF (independently discovered by various researchers - * around 2004). - * - * To prevent leaking information through side channels in point multiplication, - * we need to recode the given integer into a regular pattern: sliding windows - * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few - * decades older: we'll be using the so-called "modified Booth encoding" due to - * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49 - * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five - * signed bits into a signed digit: - * - * s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j) - * - * The sign-alternating property implies that the resulting digit values are - * integers from -16 to 16. - * - * Of course, we don't actually need to compute the signed digits s_i as an - * intermediate step (that's just a nice way to see how this scheme relates - * to the wNAF): a direct computation obtains the recoded digit from the - * six bits b_(4j + 4) ... b_(4j - 1). - * - * This function takes those five bits as an integer (0 .. 63), writing the - * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute - * value, in the range 0 .. 8). Note that this integer essentially provides the - * input bits "shifted to the left" by one position: for example, the input to - * compute the least significant recoded digit, given that there's no bit b_-1, - * has to be b_4 b_3 b_2 b_1 b_0 0. - * - */ -void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, - unsigned char *digit, unsigned char in) -{ - unsigned char s, d; - - s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as - * 6-bit value */ - d = (1 << 6) - in - 1; - d = (d & s) | (in & ~s); - d = (d >> 1) + (d & 1); - - *sign = s & 1; - *digit = d; -} -#else -static void *dummy = &dummy; -#endif diff --git a/Sources/COpenSSL/ecp_oct.c b/Sources/COpenSSL/ecp_oct.c deleted file mode 100644 index dbc143e6..00000000 --- a/Sources/COpenSSL/ecp_oct.c +++ /dev/null @@ -1,429 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/ec/ecp_oct.c */ -/* - * Includes code written by Lenka Fibikova - * for the OpenSSL project. Includes code written by Bodo Moeller for the - * OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Portions of this software developed by SUN MICROSYSTEMS, INC., - * and contributed to the OpenSSL project. - */ - -#include "err.h" -#include "symhacks.h" - -#include "ec_lcl.h" - -int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x_, int y_bit, - BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - BIGNUM *tmp1, *tmp2, *x, *y; - int ret = 0; - - /* clear error queue */ - ERR_clear_error(); - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - y_bit = (y_bit != 0); - - BN_CTX_start(ctx); - tmp1 = BN_CTX_get(ctx); - tmp2 = BN_CTX_get(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - if (y == NULL) - goto err; - - /*- - * Recover y. We have a Weierstrass equation - * y^2 = x^3 + a*x + b, - * so y is one of the square roots of x^3 + a*x + b. - */ - - /* tmp1 := x^3 */ - if (!BN_nnmod(x, x_, &group->field, ctx)) - goto err; - if (group->meth->field_decode == 0) { - /* field_{sqr,mul} work on standard representation */ - if (!group->meth->field_sqr(group, tmp2, x_, ctx)) - goto err; - if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) - goto err; - } else { - if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) - goto err; - if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) - goto err; - } - - /* tmp1 := tmp1 + a*x */ - if (group->a_is_minus3) { - if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) - goto err; - if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) - goto err; - if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) - goto err; - } else { - if (group->meth->field_decode) { - if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) - goto err; - if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) - goto err; - } else { - /* field_mul works on standard representation */ - if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) - goto err; - } - - if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) - goto err; - } - - /* tmp1 := tmp1 + b */ - if (group->meth->field_decode) { - if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) - goto err; - if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) - goto err; - } else { - if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) - goto err; - } - - if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { - unsigned long err = ERR_peek_last_error(); - - if (ERR_GET_LIB(err) == ERR_LIB_BN - && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { - ERR_clear_error(); - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - EC_R_INVALID_COMPRESSED_POINT); - } else - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - ERR_R_BN_LIB); - goto err; - } - - if (y_bit != BN_is_odd(y)) { - if (BN_is_zero(y)) { - int kron; - - kron = BN_kronecker(x, &group->field, ctx); - if (kron == -2) - goto err; - - if (kron == 1) - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - EC_R_INVALID_COMPRESSION_BIT); - else - /* - * BN_mod_sqrt() should have cought this error (not a square) - */ - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - EC_R_INVALID_COMPRESSED_POINT); - goto err; - } - if (!BN_usub(y, &group->field, y)) - goto err; - } - if (y_bit != BN_is_odd(y)) { - ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, - ERR_R_INTERNAL_ERROR); - goto err; - } - - if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) - goto err; - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, - point_conversion_form_t form, - unsigned char *buf, size_t len, BN_CTX *ctx) -{ - size_t ret; - BN_CTX *new_ctx = NULL; - int used_ctx = 0; - BIGNUM *x, *y; - size_t field_len, i, skip; - - if ((form != POINT_CONVERSION_COMPRESSED) - && (form != POINT_CONVERSION_UNCOMPRESSED) - && (form != POINT_CONVERSION_HYBRID)) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); - goto err; - } - - if (EC_POINT_is_at_infinity(group, point)) { - /* encodes to a single 0 octet */ - if (buf != NULL) { - if (len < 1) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); - return 0; - } - buf[0] = 0; - } - return 1; - } - - /* ret := required output buffer length */ - field_len = BN_num_bytes(&group->field); - ret = - (form == - POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; - - /* if 'buf' is NULL, just return required length */ - if (buf != NULL) { - if (len < ret) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); - goto err; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - used_ctx = 1; - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - if (y == NULL) - goto err; - - if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) - goto err; - - if ((form == POINT_CONVERSION_COMPRESSED - || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) - buf[0] = form + 1; - else - buf[0] = form; - - i = 1; - - skip = field_len - BN_num_bytes(x); - if (skip > field_len) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); - goto err; - } - while (skip > 0) { - buf[i++] = 0; - skip--; - } - skip = BN_bn2bin(x, buf + i); - i += skip; - if (i != 1 + field_len) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (form == POINT_CONVERSION_UNCOMPRESSED - || form == POINT_CONVERSION_HYBRID) { - skip = field_len - BN_num_bytes(y); - if (skip > field_len) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); - goto err; - } - while (skip > 0) { - buf[i++] = 0; - skip--; - } - skip = BN_bn2bin(y, buf + i); - i += skip; - } - - if (i != ret) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - if (used_ctx) - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; - - err: - if (used_ctx) - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return 0; -} - -int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, - const unsigned char *buf, size_t len, BN_CTX *ctx) -{ - point_conversion_form_t form; - int y_bit; - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y; - size_t field_len, enc_len; - int ret = 0; - - if (len == 0) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); - return 0; - } - form = buf[0]; - y_bit = form & 1; - form = form & ~1U; - if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) - && (form != POINT_CONVERSION_UNCOMPRESSED) - && (form != POINT_CONVERSION_HYBRID)) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - return 0; - } - if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - return 0; - } - - if (form == 0) { - if (len != 1) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - return 0; - } - - return EC_POINT_set_to_infinity(group, point); - } - - field_len = BN_num_bytes(&group->field); - enc_len = - (form == - POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; - - if (len != enc_len) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - return 0; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - if (y == NULL) - goto err; - - if (!BN_bin2bn(buf + 1, field_len, x)) - goto err; - if (BN_ucmp(x, &group->field) >= 0) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - goto err; - } - - if (form == POINT_CONVERSION_COMPRESSED) { - if (!EC_POINT_set_compressed_coordinates_GFp - (group, point, x, y_bit, ctx)) - goto err; - } else { - if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) - goto err; - if (BN_ucmp(y, &group->field) >= 0) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - goto err; - } - if (form == POINT_CONVERSION_HYBRID) { - if (y_bit != BN_is_odd(y)) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); - goto err; - } - } - - if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) - goto err; - } - - /* test required by X9.62 */ - if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { - ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); - goto err; - } - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} diff --git a/Sources/COpenSSL/ecp_smpl.c b/Sources/COpenSSL/ecp_smpl.c deleted file mode 100644 index 2b9a7054..00000000 --- a/Sources/COpenSSL/ecp_smpl.c +++ /dev/null @@ -1,1418 +0,0 @@ -/* crypto/ec/ecp_smpl.c */ -/* - * Includes code written by Lenka Fibikova - * for the OpenSSL project. Includes code written by Bodo Moeller for the - * OpenSSL project. - */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * Portions of this software developed by SUN MICROSYSTEMS, INC., - * and contributed to the OpenSSL project. - */ - -#include "err.h" -#include "symhacks.h" - -#ifdef OPENSSL_FIPS -# include -#endif - -#include "ec_lcl.h" - -const EC_METHOD *EC_GFp_simple_method(void) -{ - static const EC_METHOD ret = { - EC_FLAGS_DEFAULT_OCT, - NID_X9_62_prime_field, - ec_GFp_simple_group_init, - ec_GFp_simple_group_finish, - ec_GFp_simple_group_clear_finish, - ec_GFp_simple_group_copy, - ec_GFp_simple_group_set_curve, - ec_GFp_simple_group_get_curve, - ec_GFp_simple_group_get_degree, - ec_GFp_simple_group_check_discriminant, - ec_GFp_simple_point_init, - ec_GFp_simple_point_finish, - ec_GFp_simple_point_clear_finish, - ec_GFp_simple_point_copy, - ec_GFp_simple_point_set_to_infinity, - ec_GFp_simple_set_Jprojective_coordinates_GFp, - ec_GFp_simple_get_Jprojective_coordinates_GFp, - ec_GFp_simple_point_set_affine_coordinates, - ec_GFp_simple_point_get_affine_coordinates, - 0, 0, 0, - ec_GFp_simple_add, - ec_GFp_simple_dbl, - ec_GFp_simple_invert, - ec_GFp_simple_is_at_infinity, - ec_GFp_simple_is_on_curve, - ec_GFp_simple_cmp, - ec_GFp_simple_make_affine, - ec_GFp_simple_points_make_affine, - 0 /* mul */ , - 0 /* precompute_mult */ , - 0 /* have_precompute_mult */ , - ec_GFp_simple_field_mul, - ec_GFp_simple_field_sqr, - 0 /* field_div */ , - 0 /* field_encode */ , - 0 /* field_decode */ , - 0 /* field_set_to_one */ - }; - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return fips_ec_gfp_simple_method(); -#endif - - return &ret; -} - -/* - * Most method functions in this file are designed to work with - * non-trivial representations of field elements if necessary - * (see ecp_mont.c): while standard modular addition and subtraction - * are used, the field_mul and field_sqr methods will be used for - * multiplication, and field_encode and field_decode (if defined) - * will be used for converting between representations. - * - * Functions ec_GFp_simple_points_make_affine() and - * ec_GFp_simple_point_get_affine_coordinates() specifically assume - * that if a non-trivial representation is used, it is a Montgomery - * representation (i.e. 'encoding' means multiplying by some factor R). - */ - -int ec_GFp_simple_group_init(EC_GROUP *group) -{ - BN_init(&group->field); - BN_init(&group->a); - BN_init(&group->b); - group->a_is_minus3 = 0; - return 1; -} - -void ec_GFp_simple_group_finish(EC_GROUP *group) -{ - BN_free(&group->field); - BN_free(&group->a); - BN_free(&group->b); -} - -void ec_GFp_simple_group_clear_finish(EC_GROUP *group) -{ - BN_clear_free(&group->field); - BN_clear_free(&group->a); - BN_clear_free(&group->b); -} - -int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) -{ - if (!BN_copy(&dest->field, &src->field)) - return 0; - if (!BN_copy(&dest->a, &src->a)) - return 0; - if (!BN_copy(&dest->b, &src->b)) - return 0; - - dest->a_is_minus3 = src->a_is_minus3; - - return 1; -} - -int ec_GFp_simple_group_set_curve(EC_GROUP *group, - const BIGNUM *p, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - int ret = 0; - BN_CTX *new_ctx = NULL; - BIGNUM *tmp_a; - - /* p must be a prime > 3 */ - if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { - ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD); - return 0; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - tmp_a = BN_CTX_get(ctx); - if (tmp_a == NULL) - goto err; - - /* group->field */ - if (!BN_copy(&group->field, p)) - goto err; - BN_set_negative(&group->field, 0); - - /* group->a */ - if (!BN_nnmod(tmp_a, a, p, ctx)) - goto err; - if (group->meth->field_encode) { - if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) - goto err; - } else if (!BN_copy(&group->a, tmp_a)) - goto err; - - /* group->b */ - if (!BN_nnmod(&group->b, b, p, ctx)) - goto err; - if (group->meth->field_encode) - if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) - goto err; - - /* group->a_is_minus3 */ - if (!BN_add_word(tmp_a, 3)) - goto err; - group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field)); - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, - BIGNUM *b, BN_CTX *ctx) -{ - int ret = 0; - BN_CTX *new_ctx = NULL; - - if (p != NULL) { - if (!BN_copy(p, &group->field)) - return 0; - } - - if (a != NULL || b != NULL) { - if (group->meth->field_decode) { - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - if (a != NULL) { - if (!group->meth->field_decode(group, a, &group->a, ctx)) - goto err; - } - if (b != NULL) { - if (!group->meth->field_decode(group, b, &group->b, ctx)) - goto err; - } - } else { - if (a != NULL) { - if (!BN_copy(a, &group->a)) - goto err; - } - if (b != NULL) { - if (!BN_copy(b, &group->b)) - goto err; - } - } - } - - ret = 1; - - err: - if (new_ctx) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_group_get_degree(const EC_GROUP *group) -{ - return BN_num_bits(&group->field); -} - -int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) -{ - int ret = 0; - BIGNUM *a, *b, *order, *tmp_1, *tmp_2; - const BIGNUM *p = &group->field; - BN_CTX *new_ctx = NULL; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) { - ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, - ERR_R_MALLOC_FAILURE); - goto err; - } - } - BN_CTX_start(ctx); - a = BN_CTX_get(ctx); - b = BN_CTX_get(ctx); - tmp_1 = BN_CTX_get(ctx); - tmp_2 = BN_CTX_get(ctx); - order = BN_CTX_get(ctx); - if (order == NULL) - goto err; - - if (group->meth->field_decode) { - if (!group->meth->field_decode(group, a, &group->a, ctx)) - goto err; - if (!group->meth->field_decode(group, b, &group->b, ctx)) - goto err; - } else { - if (!BN_copy(a, &group->a)) - goto err; - if (!BN_copy(b, &group->b)) - goto err; - } - - /*- - * check the discriminant: - * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p) - * 0 =< a, b < p - */ - if (BN_is_zero(a)) { - if (BN_is_zero(b)) - goto err; - } else if (!BN_is_zero(b)) { - if (!BN_mod_sqr(tmp_1, a, p, ctx)) - goto err; - if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) - goto err; - if (!BN_lshift(tmp_1, tmp_2, 2)) - goto err; - /* tmp_1 = 4*a^3 */ - - if (!BN_mod_sqr(tmp_2, b, p, ctx)) - goto err; - if (!BN_mul_word(tmp_2, 27)) - goto err; - /* tmp_2 = 27*b^2 */ - - if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) - goto err; - if (BN_is_zero(a)) - goto err; - } - ret = 1; - - err: - if (ctx != NULL) - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_point_init(EC_POINT *point) -{ - BN_init(&point->X); - BN_init(&point->Y); - BN_init(&point->Z); - point->Z_is_one = 0; - - return 1; -} - -void ec_GFp_simple_point_finish(EC_POINT *point) -{ - BN_free(&point->X); - BN_free(&point->Y); - BN_free(&point->Z); -} - -void ec_GFp_simple_point_clear_finish(EC_POINT *point) -{ - BN_clear_free(&point->X); - BN_clear_free(&point->Y); - BN_clear_free(&point->Z); - point->Z_is_one = 0; -} - -int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) -{ - if (!BN_copy(&dest->X, &src->X)) - return 0; - if (!BN_copy(&dest->Y, &src->Y)) - return 0; - if (!BN_copy(&dest->Z, &src->Z)) - return 0; - dest->Z_is_one = src->Z_is_one; - - return 1; -} - -int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, - EC_POINT *point) -{ - point->Z_is_one = 0; - BN_zero(&point->Z); - return 1; -} - -int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x, - const BIGNUM *y, - const BIGNUM *z, - BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - int ret = 0; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - if (x != NULL) { - if (!BN_nnmod(&point->X, x, &group->field, ctx)) - goto err; - if (group->meth->field_encode) { - if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) - goto err; - } - } - - if (y != NULL) { - if (!BN_nnmod(&point->Y, y, &group->field, ctx)) - goto err; - if (group->meth->field_encode) { - if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) - goto err; - } - } - - if (z != NULL) { - int Z_is_one; - - if (!BN_nnmod(&point->Z, z, &group->field, ctx)) - goto err; - Z_is_one = BN_is_one(&point->Z); - if (group->meth->field_encode) { - if (Z_is_one && (group->meth->field_set_to_one != 0)) { - if (!group->meth->field_set_to_one(group, &point->Z, ctx)) - goto err; - } else { - if (!group-> - meth->field_encode(group, &point->Z, &point->Z, ctx)) - goto err; - } - } - point->Z_is_one = Z_is_one; - } - - ret = 1; - - err: - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BIGNUM *z, BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - int ret = 0; - - if (group->meth->field_decode != 0) { - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - if (x != NULL) { - if (!group->meth->field_decode(group, x, &point->X, ctx)) - goto err; - } - if (y != NULL) { - if (!group->meth->field_decode(group, y, &point->Y, ctx)) - goto err; - } - if (z != NULL) { - if (!group->meth->field_decode(group, z, &point->Z, ctx)) - goto err; - } - } else { - if (x != NULL) { - if (!BN_copy(x, &point->X)) - goto err; - } - if (y != NULL) { - if (!BN_copy(y, &point->Y)) - goto err; - } - if (z != NULL) { - if (!BN_copy(z, &point->Z)) - goto err; - } - } - - ret = 1; - - err: - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, - EC_POINT *point, - const BIGNUM *x, - const BIGNUM *y, BN_CTX *ctx) -{ - if (x == NULL || y == NULL) { - /* - * unlike for projective coordinates, we do not tolerate this - */ - ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, - BN_value_one(), ctx); -} - -int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, - const EC_POINT *point, - BIGNUM *x, BIGNUM *y, - BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - BIGNUM *Z, *Z_1, *Z_2, *Z_3; - const BIGNUM *Z_; - int ret = 0; - - if (EC_POINT_is_at_infinity(group, point)) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, - EC_R_POINT_AT_INFINITY); - return 0; - } - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - Z = BN_CTX_get(ctx); - Z_1 = BN_CTX_get(ctx); - Z_2 = BN_CTX_get(ctx); - Z_3 = BN_CTX_get(ctx); - if (Z_3 == NULL) - goto err; - - /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */ - - if (group->meth->field_decode) { - if (!group->meth->field_decode(group, Z, &point->Z, ctx)) - goto err; - Z_ = Z; - } else { - Z_ = &point->Z; - } - - if (BN_is_one(Z_)) { - if (group->meth->field_decode) { - if (x != NULL) { - if (!group->meth->field_decode(group, x, &point->X, ctx)) - goto err; - } - if (y != NULL) { - if (!group->meth->field_decode(group, y, &point->Y, ctx)) - goto err; - } - } else { - if (x != NULL) { - if (!BN_copy(x, &point->X)) - goto err; - } - if (y != NULL) { - if (!BN_copy(y, &point->Y)) - goto err; - } - } - } else { - if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) { - ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, - ERR_R_BN_LIB); - goto err; - } - - if (group->meth->field_encode == 0) { - /* field_sqr works on standard representation */ - if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) - goto err; - } else { - if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) - goto err; - } - - if (x != NULL) { - /* - * in the Montgomery case, field_mul will cancel out Montgomery - * factor in X: - */ - if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) - goto err; - } - - if (y != NULL) { - if (group->meth->field_encode == 0) { - /* - * field_mul works on standard representation - */ - if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) - goto err; - } else { - if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) - goto err; - } - - /* - * in the Montgomery case, field_mul will cancel out Montgomery - * factor in Y: - */ - if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) - goto err; - } - } - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) -{ - int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, - const BIGNUM *, BN_CTX *); - int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); - const BIGNUM *p; - BN_CTX *new_ctx = NULL; - BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; - int ret = 0; - - if (a == b) - return EC_POINT_dbl(group, r, a, ctx); - if (EC_POINT_is_at_infinity(group, a)) - return EC_POINT_copy(r, b); - if (EC_POINT_is_at_infinity(group, b)) - return EC_POINT_copy(r, a); - - field_mul = group->meth->field_mul; - field_sqr = group->meth->field_sqr; - p = &group->field; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - n0 = BN_CTX_get(ctx); - n1 = BN_CTX_get(ctx); - n2 = BN_CTX_get(ctx); - n3 = BN_CTX_get(ctx); - n4 = BN_CTX_get(ctx); - n5 = BN_CTX_get(ctx); - n6 = BN_CTX_get(ctx); - if (n6 == NULL) - goto end; - - /* - * Note that in this function we must not read components of 'a' or 'b' - * once we have written the corresponding components of 'r'. ('r' might - * be one of 'a' or 'b'.) - */ - - /* n1, n2 */ - if (b->Z_is_one) { - if (!BN_copy(n1, &a->X)) - goto end; - if (!BN_copy(n2, &a->Y)) - goto end; - /* n1 = X_a */ - /* n2 = Y_a */ - } else { - if (!field_sqr(group, n0, &b->Z, ctx)) - goto end; - if (!field_mul(group, n1, &a->X, n0, ctx)) - goto end; - /* n1 = X_a * Z_b^2 */ - - if (!field_mul(group, n0, n0, &b->Z, ctx)) - goto end; - if (!field_mul(group, n2, &a->Y, n0, ctx)) - goto end; - /* n2 = Y_a * Z_b^3 */ - } - - /* n3, n4 */ - if (a->Z_is_one) { - if (!BN_copy(n3, &b->X)) - goto end; - if (!BN_copy(n4, &b->Y)) - goto end; - /* n3 = X_b */ - /* n4 = Y_b */ - } else { - if (!field_sqr(group, n0, &a->Z, ctx)) - goto end; - if (!field_mul(group, n3, &b->X, n0, ctx)) - goto end; - /* n3 = X_b * Z_a^2 */ - - if (!field_mul(group, n0, n0, &a->Z, ctx)) - goto end; - if (!field_mul(group, n4, &b->Y, n0, ctx)) - goto end; - /* n4 = Y_b * Z_a^3 */ - } - - /* n5, n6 */ - if (!BN_mod_sub_quick(n5, n1, n3, p)) - goto end; - if (!BN_mod_sub_quick(n6, n2, n4, p)) - goto end; - /* n5 = n1 - n3 */ - /* n6 = n2 - n4 */ - - if (BN_is_zero(n5)) { - if (BN_is_zero(n6)) { - /* a is the same point as b */ - BN_CTX_end(ctx); - ret = EC_POINT_dbl(group, r, a, ctx); - ctx = NULL; - goto end; - } else { - /* a is the inverse of b */ - BN_zero(&r->Z); - r->Z_is_one = 0; - ret = 1; - goto end; - } - } - - /* 'n7', 'n8' */ - if (!BN_mod_add_quick(n1, n1, n3, p)) - goto end; - if (!BN_mod_add_quick(n2, n2, n4, p)) - goto end; - /* 'n7' = n1 + n3 */ - /* 'n8' = n2 + n4 */ - - /* Z_r */ - if (a->Z_is_one && b->Z_is_one) { - if (!BN_copy(&r->Z, n5)) - goto end; - } else { - if (a->Z_is_one) { - if (!BN_copy(n0, &b->Z)) - goto end; - } else if (b->Z_is_one) { - if (!BN_copy(n0, &a->Z)) - goto end; - } else { - if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) - goto end; - } - if (!field_mul(group, &r->Z, n0, n5, ctx)) - goto end; - } - r->Z_is_one = 0; - /* Z_r = Z_a * Z_b * n5 */ - - /* X_r */ - if (!field_sqr(group, n0, n6, ctx)) - goto end; - if (!field_sqr(group, n4, n5, ctx)) - goto end; - if (!field_mul(group, n3, n1, n4, ctx)) - goto end; - if (!BN_mod_sub_quick(&r->X, n0, n3, p)) - goto end; - /* X_r = n6^2 - n5^2 * 'n7' */ - - /* 'n9' */ - if (!BN_mod_lshift1_quick(n0, &r->X, p)) - goto end; - if (!BN_mod_sub_quick(n0, n3, n0, p)) - goto end; - /* n9 = n5^2 * 'n7' - 2 * X_r */ - - /* Y_r */ - if (!field_mul(group, n0, n0, n6, ctx)) - goto end; - if (!field_mul(group, n5, n4, n5, ctx)) - goto end; /* now n5 is n5^3 */ - if (!field_mul(group, n1, n2, n5, ctx)) - goto end; - if (!BN_mod_sub_quick(n0, n0, n1, p)) - goto end; - if (BN_is_odd(n0)) - if (!BN_add(n0, n0, p)) - goto end; - /* now 0 <= n0 < 2*p, and n0 is even */ - if (!BN_rshift1(&r->Y, n0)) - goto end; - /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ - - ret = 1; - - end: - if (ctx) /* otherwise we already called BN_CTX_end */ - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, - BN_CTX *ctx) -{ - int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, - const BIGNUM *, BN_CTX *); - int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); - const BIGNUM *p; - BN_CTX *new_ctx = NULL; - BIGNUM *n0, *n1, *n2, *n3; - int ret = 0; - - if (EC_POINT_is_at_infinity(group, a)) { - BN_zero(&r->Z); - r->Z_is_one = 0; - return 1; - } - - field_mul = group->meth->field_mul; - field_sqr = group->meth->field_sqr; - p = &group->field; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - n0 = BN_CTX_get(ctx); - n1 = BN_CTX_get(ctx); - n2 = BN_CTX_get(ctx); - n3 = BN_CTX_get(ctx); - if (n3 == NULL) - goto err; - - /* - * Note that in this function we must not read components of 'a' once we - * have written the corresponding components of 'r'. ('r' might the same - * as 'a'.) - */ - - /* n1 */ - if (a->Z_is_one) { - if (!field_sqr(group, n0, &a->X, ctx)) - goto err; - if (!BN_mod_lshift1_quick(n1, n0, p)) - goto err; - if (!BN_mod_add_quick(n0, n0, n1, p)) - goto err; - if (!BN_mod_add_quick(n1, n0, &group->a, p)) - goto err; - /* n1 = 3 * X_a^2 + a_curve */ - } else if (group->a_is_minus3) { - if (!field_sqr(group, n1, &a->Z, ctx)) - goto err; - if (!BN_mod_add_quick(n0, &a->X, n1, p)) - goto err; - if (!BN_mod_sub_quick(n2, &a->X, n1, p)) - goto err; - if (!field_mul(group, n1, n0, n2, ctx)) - goto err; - if (!BN_mod_lshift1_quick(n0, n1, p)) - goto err; - if (!BN_mod_add_quick(n1, n0, n1, p)) - goto err; - /*- - * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) - * = 3 * X_a^2 - 3 * Z_a^4 - */ - } else { - if (!field_sqr(group, n0, &a->X, ctx)) - goto err; - if (!BN_mod_lshift1_quick(n1, n0, p)) - goto err; - if (!BN_mod_add_quick(n0, n0, n1, p)) - goto err; - if (!field_sqr(group, n1, &a->Z, ctx)) - goto err; - if (!field_sqr(group, n1, n1, ctx)) - goto err; - if (!field_mul(group, n1, n1, &group->a, ctx)) - goto err; - if (!BN_mod_add_quick(n1, n1, n0, p)) - goto err; - /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */ - } - - /* Z_r */ - if (a->Z_is_one) { - if (!BN_copy(n0, &a->Y)) - goto err; - } else { - if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) - goto err; - } - if (!BN_mod_lshift1_quick(&r->Z, n0, p)) - goto err; - r->Z_is_one = 0; - /* Z_r = 2 * Y_a * Z_a */ - - /* n2 */ - if (!field_sqr(group, n3, &a->Y, ctx)) - goto err; - if (!field_mul(group, n2, &a->X, n3, ctx)) - goto err; - if (!BN_mod_lshift_quick(n2, n2, 2, p)) - goto err; - /* n2 = 4 * X_a * Y_a^2 */ - - /* X_r */ - if (!BN_mod_lshift1_quick(n0, n2, p)) - goto err; - if (!field_sqr(group, &r->X, n1, ctx)) - goto err; - if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) - goto err; - /* X_r = n1^2 - 2 * n2 */ - - /* n3 */ - if (!field_sqr(group, n0, n3, ctx)) - goto err; - if (!BN_mod_lshift_quick(n3, n0, 3, p)) - goto err; - /* n3 = 8 * Y_a^4 */ - - /* Y_r */ - if (!BN_mod_sub_quick(n0, n2, &r->X, p)) - goto err; - if (!field_mul(group, n0, n1, n0, ctx)) - goto err; - if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) - goto err; - /* Y_r = n1 * (n2 - X_r) - n3 */ - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) -{ - if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) - /* point is its own inverse */ - return 1; - - return BN_usub(&point->Y, &group->field, &point->Y); -} - -int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) -{ - return BN_is_zero(&point->Z); -} - -int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, - BN_CTX *ctx) -{ - int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, - const BIGNUM *, BN_CTX *); - int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); - const BIGNUM *p; - BN_CTX *new_ctx = NULL; - BIGNUM *rh, *tmp, *Z4, *Z6; - int ret = -1; - - if (EC_POINT_is_at_infinity(group, point)) - return 1; - - field_mul = group->meth->field_mul; - field_sqr = group->meth->field_sqr; - p = &group->field; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - } - - BN_CTX_start(ctx); - rh = BN_CTX_get(ctx); - tmp = BN_CTX_get(ctx); - Z4 = BN_CTX_get(ctx); - Z6 = BN_CTX_get(ctx); - if (Z6 == NULL) - goto err; - - /*- - * We have a curve defined by a Weierstrass equation - * y^2 = x^3 + a*x + b. - * The point to consider is given in Jacobian projective coordinates - * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). - * Substituting this and multiplying by Z^6 transforms the above equation into - * Y^2 = X^3 + a*X*Z^4 + b*Z^6. - * To test this, we add up the right-hand side in 'rh'. - */ - - /* rh := X^2 */ - if (!field_sqr(group, rh, &point->X, ctx)) - goto err; - - if (!point->Z_is_one) { - if (!field_sqr(group, tmp, &point->Z, ctx)) - goto err; - if (!field_sqr(group, Z4, tmp, ctx)) - goto err; - if (!field_mul(group, Z6, Z4, tmp, ctx)) - goto err; - - /* rh := (rh + a*Z^4)*X */ - if (group->a_is_minus3) { - if (!BN_mod_lshift1_quick(tmp, Z4, p)) - goto err; - if (!BN_mod_add_quick(tmp, tmp, Z4, p)) - goto err; - if (!BN_mod_sub_quick(rh, rh, tmp, p)) - goto err; - if (!field_mul(group, rh, rh, &point->X, ctx)) - goto err; - } else { - if (!field_mul(group, tmp, Z4, &group->a, ctx)) - goto err; - if (!BN_mod_add_quick(rh, rh, tmp, p)) - goto err; - if (!field_mul(group, rh, rh, &point->X, ctx)) - goto err; - } - - /* rh := rh + b*Z^6 */ - if (!field_mul(group, tmp, &group->b, Z6, ctx)) - goto err; - if (!BN_mod_add_quick(rh, rh, tmp, p)) - goto err; - } else { - /* point->Z_is_one */ - - /* rh := (rh + a)*X */ - if (!BN_mod_add_quick(rh, rh, &group->a, p)) - goto err; - if (!field_mul(group, rh, rh, &point->X, ctx)) - goto err; - /* rh := rh + b */ - if (!BN_mod_add_quick(rh, rh, &group->b, p)) - goto err; - } - - /* 'lh' := Y^2 */ - if (!field_sqr(group, tmp, &point->Y, ctx)) - goto err; - - ret = (0 == BN_ucmp(tmp, rh)); - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, - const EC_POINT *b, BN_CTX *ctx) -{ - /*- - * return values: - * -1 error - * 0 equal (in affine coordinates) - * 1 not equal - */ - - int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, - const BIGNUM *, BN_CTX *); - int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); - BN_CTX *new_ctx = NULL; - BIGNUM *tmp1, *tmp2, *Za23, *Zb23; - const BIGNUM *tmp1_, *tmp2_; - int ret = -1; - - if (EC_POINT_is_at_infinity(group, a)) { - return EC_POINT_is_at_infinity(group, b) ? 0 : 1; - } - - if (EC_POINT_is_at_infinity(group, b)) - return 1; - - if (a->Z_is_one && b->Z_is_one) { - return ((BN_cmp(&a->X, &b->X) == 0) - && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; - } - - field_mul = group->meth->field_mul; - field_sqr = group->meth->field_sqr; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return -1; - } - - BN_CTX_start(ctx); - tmp1 = BN_CTX_get(ctx); - tmp2 = BN_CTX_get(ctx); - Za23 = BN_CTX_get(ctx); - Zb23 = BN_CTX_get(ctx); - if (Zb23 == NULL) - goto end; - - /*- - * We have to decide whether - * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), - * or equivalently, whether - * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). - */ - - if (!b->Z_is_one) { - if (!field_sqr(group, Zb23, &b->Z, ctx)) - goto end; - if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) - goto end; - tmp1_ = tmp1; - } else - tmp1_ = &a->X; - if (!a->Z_is_one) { - if (!field_sqr(group, Za23, &a->Z, ctx)) - goto end; - if (!field_mul(group, tmp2, &b->X, Za23, ctx)) - goto end; - tmp2_ = tmp2; - } else - tmp2_ = &b->X; - - /* compare X_a*Z_b^2 with X_b*Z_a^2 */ - if (BN_cmp(tmp1_, tmp2_) != 0) { - ret = 1; /* points differ */ - goto end; - } - - if (!b->Z_is_one) { - if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) - goto end; - if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) - goto end; - /* tmp1_ = tmp1 */ - } else - tmp1_ = &a->Y; - if (!a->Z_is_one) { - if (!field_mul(group, Za23, Za23, &a->Z, ctx)) - goto end; - if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) - goto end; - /* tmp2_ = tmp2 */ - } else - tmp2_ = &b->Y; - - /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ - if (BN_cmp(tmp1_, tmp2_) != 0) { - ret = 1; /* points differ */ - goto end; - } - - /* points are equal */ - ret = 0; - - end: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, - BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - BIGNUM *x, *y; - int ret = 0; - - if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) - return 1; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - if (y == NULL) - goto err; - - if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) - goto err; - if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) - goto err; - if (!point->Z_is_one) { - ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR); - goto err; - } - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - return ret; -} - -int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, - EC_POINT *points[], BN_CTX *ctx) -{ - BN_CTX *new_ctx = NULL; - BIGNUM *tmp, *tmp_Z; - BIGNUM **prod_Z = NULL; - size_t i; - int ret = 0; - - if (num == 0) - return 1; - - if (ctx == NULL) { - ctx = new_ctx = BN_CTX_new(); - if (ctx == NULL) - return 0; - } - - BN_CTX_start(ctx); - tmp = BN_CTX_get(ctx); - tmp_Z = BN_CTX_get(ctx); - if (tmp == NULL || tmp_Z == NULL) - goto err; - - prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0])); - if (prod_Z == NULL) - goto err; - for (i = 0; i < num; i++) { - prod_Z[i] = BN_new(); - if (prod_Z[i] == NULL) - goto err; - } - - /* - * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z, - * skipping any zero-valued inputs (pretend that they're 1). - */ - - if (!BN_is_zero(&points[0]->Z)) { - if (!BN_copy(prod_Z[0], &points[0]->Z)) - goto err; - } else { - if (group->meth->field_set_to_one != 0) { - if (!group->meth->field_set_to_one(group, prod_Z[0], ctx)) - goto err; - } else { - if (!BN_one(prod_Z[0])) - goto err; - } - } - - for (i = 1; i < num; i++) { - if (!BN_is_zero(&points[i]->Z)) { - if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1], - &points[i]->Z, ctx)) - goto err; - } else { - if (!BN_copy(prod_Z[i], prod_Z[i - 1])) - goto err; - } - } - - /* - * Now use a single explicit inversion to replace every non-zero - * points[i]->Z by its inverse. - */ - - if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) { - ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); - goto err; - } - if (group->meth->field_encode != 0) { - /* - * In the Montgomery case, we just turned R*H (representing H) into - * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to - * multiply by the Montgomery factor twice. - */ - if (!group->meth->field_encode(group, tmp, tmp, ctx)) - goto err; - if (!group->meth->field_encode(group, tmp, tmp, ctx)) - goto err; - } - - for (i = num - 1; i > 0; --i) { - /* - * Loop invariant: tmp is the product of the inverses of points[0]->Z - * .. points[i]->Z (zero-valued inputs skipped). - */ - if (!BN_is_zero(&points[i]->Z)) { - /* - * Set tmp_Z to the inverse of points[i]->Z (as product of Z - * inverses 0 .. i, Z values 0 .. i - 1). - */ - if (!group-> - meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx)) - goto err; - /* - * Update tmp to satisfy the loop invariant for i - 1. - */ - if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx)) - goto err; - /* Replace points[i]->Z by its inverse. */ - if (!BN_copy(&points[i]->Z, tmp_Z)) - goto err; - } - } - - if (!BN_is_zero(&points[0]->Z)) { - /* Replace points[0]->Z by its inverse. */ - if (!BN_copy(&points[0]->Z, tmp)) - goto err; - } - - /* Finally, fix up the X and Y coordinates for all points. */ - - for (i = 0; i < num; i++) { - EC_POINT *p = points[i]; - - if (!BN_is_zero(&p->Z)) { - /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ - - if (!group->meth->field_sqr(group, tmp, &p->Z, ctx)) - goto err; - if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx)) - goto err; - - if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx)) - goto err; - if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) - goto err; - - if (group->meth->field_set_to_one != 0) { - if (!group->meth->field_set_to_one(group, &p->Z, ctx)) - goto err; - } else { - if (!BN_one(&p->Z)) - goto err; - } - p->Z_is_one = 1; - } - } - - ret = 1; - - err: - BN_CTX_end(ctx); - if (new_ctx != NULL) - BN_CTX_free(new_ctx); - if (prod_Z != NULL) { - for (i = 0; i < num; i++) { - if (prod_Z[i] == NULL) - break; - BN_clear_free(prod_Z[i]); - } - OPENSSL_free(prod_Z); - } - return ret; -} - -int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - const BIGNUM *b, BN_CTX *ctx) -{ - return BN_mod_mul(r, a, b, &group->field, ctx); -} - -int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, - BN_CTX *ctx) -{ - return BN_mod_sqr(r, a, &group->field, ctx); -} diff --git a/Sources/COpenSSL/ecs_.c b/Sources/COpenSSL/ecs_.c deleted file mode 100644 index 5ea16937..00000000 --- a/Sources/COpenSSL/ecs_.c +++ /dev/null @@ -1,1245 +0,0 @@ -/* crypto/ecdsa/ecs_asn1.c */ -/* ==================================================================== - * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "ecs_locl.h" -#include "err.h" -#include "asn1t.h" - -ASN1_SEQUENCE(ECDSA_SIG) = { - ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), - ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) -} ASN1_SEQUENCE_END(ECDSA_SIG) - -DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG) -IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG) -/* crypto/ecdsa/ecs_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -// #include "err.h" -#include "ecdsa.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason) - -static ERR_STRING_DATA ECDSA_str_functs[] = { - {ERR_FUNC(ECDSA_F_ECDSA_CHECK), "ECDSA_CHECK"}, - {ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"}, - {ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"}, - {ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"}, - {ERR_FUNC(ECDSA_F_ECDSA_METHOD_NEW), "ECDSA_METHOD_new"}, - {ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"}, - {0, NULL} -}; - -static ERR_STRING_DATA ECDSA_str_reasons[] = { - {ERR_REASON(ECDSA_R_BAD_SIGNATURE), "bad signature"}, - {ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), - "data too large for key size"}, - {ERR_REASON(ECDSA_R_ERR_EC_LIB), "err ec lib"}, - {ERR_REASON(ECDSA_R_MISSING_PARAMETERS), "missing parameters"}, - {ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, - {ERR_REASON(ECDSA_R_NON_FIPS_METHOD), "non fips method"}, - {ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED), - "random number generation failed"}, - {ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED), "signature malloc failed"}, - {0, NULL} -}; - -#endif - -void ERR_load_ECDSA_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL) { - ERR_load_strings(0, ECDSA_str_functs); - ERR_load_strings(0, ECDSA_str_reasons); - } -#endif -} -/* crypto/ecdsa/ecs_lib.c */ -/* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "ecs_locl.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -// #include "err.h" -#include "bn.h" -#ifdef OPENSSL_FIPS -# include -#endif - -const char ECDSA_version[] = "ECDSA" OPENSSL_VERSION_PTEXT; - -static const ECDSA_METHOD *default_ECDSA_method = NULL; - -static void *ecdsa_data_new(void); -static void *ecdsa_data_dup(void *); -static void ecdsa_data_free(void *); - -void ECDSA_set_default_method(const ECDSA_METHOD *meth) -{ - default_ECDSA_method = meth; -} - -const ECDSA_METHOD *ECDSA_get_default_method(void) -{ - if (!default_ECDSA_method) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_ecdsa_openssl(); - else - return ECDSA_OpenSSL(); -#else - default_ECDSA_method = ECDSA_OpenSSL(); -#endif - } - return default_ECDSA_method; -} - -int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth) -{ - ECDSA_DATA *ecdsa; - - ecdsa = ecdsa_check(eckey); - - if (ecdsa == NULL) - return 0; - -#ifndef OPENSSL_NO_ENGINE - if (ecdsa->engine) { - ENGINE_finish(ecdsa->engine); - ecdsa->engine = NULL; - } -#endif - ecdsa->meth = meth; - - return 1; -} - -static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine) -{ - ECDSA_DATA *ret; - - ret = (ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA)); - if (ret == NULL) { - ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - ret->init = NULL; - - ret->meth = ECDSA_get_default_method(); - ret->engine = engine; -#ifndef OPENSSL_NO_ENGINE - if (!ret->engine) - ret->engine = ENGINE_get_default_ECDSA(); - if (ret->engine) { - ret->meth = ENGINE_get_ECDSA(ret->engine); - if (!ret->meth) { - ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); - ENGINE_finish(ret->engine); - OPENSSL_free(ret); - return NULL; - } - } -#endif - - ret->flags = ret->meth->flags; - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); -#if 0 - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); - OPENSSL_free(ret); - ret = NULL; - } -#endif - return (ret); -} - -static void *ecdsa_data_new(void) -{ - return (void *)ECDSA_DATA_new_method(NULL); -} - -static void *ecdsa_data_dup(void *data) -{ - ECDSA_DATA *r = (ECDSA_DATA *)data; - - /* XXX: dummy operation */ - if (r == NULL) - return NULL; - - return ecdsa_data_new(); -} - -static void ecdsa_data_free(void *data) -{ - ECDSA_DATA *r = (ECDSA_DATA *)data; - -#ifndef OPENSSL_NO_ENGINE - if (r->engine) - ENGINE_finish(r->engine); -#endif - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data); - - OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA)); - - OPENSSL_free(r); -} - -ECDSA_DATA *ecdsa_check(EC_KEY *key) -{ - ECDSA_DATA *ecdsa_data; - - void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup, - ecdsa_data_free, ecdsa_data_free); - if (data == NULL) { - ecdsa_data = (ECDSA_DATA *)ecdsa_data_new(); - if (ecdsa_data == NULL) - return NULL; - data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data, - ecdsa_data_dup, ecdsa_data_free, - ecdsa_data_free); - if (data != NULL) { - /* - * Another thread raced us to install the key_method data and - * won. - */ - ecdsa_data_free(ecdsa_data); - ecdsa_data = (ECDSA_DATA *)data; - } else if (EC_KEY_get_key_method_data(key, ecdsa_data_dup, - ecdsa_data_free, - ecdsa_data_free) != ecdsa_data) { - /* Or an out of memory error in EC_KEY_insert_key_method_data. */ - ecdsa_data_free(ecdsa_data); - return NULL; - } - } else { - ecdsa_data = (ECDSA_DATA *)data; - } -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD) - && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { - ECDSAerr(ECDSA_F_ECDSA_CHECK, ECDSA_R_NON_FIPS_METHOD); - return NULL; - } -#endif - - return ecdsa_data; -} - -int ECDSA_size(const EC_KEY *r) -{ - int ret, i; - ASN1_INTEGER bs; - BIGNUM *order = NULL; - unsigned char buf[4]; - const EC_GROUP *group; - - if (r == NULL) - return 0; - group = EC_KEY_get0_group(r); - if (group == NULL) - return 0; - - if ((order = BN_new()) == NULL) - return 0; - if (!EC_GROUP_get_order(group, order, NULL)) { - BN_clear_free(order); - return 0; - } - i = BN_num_bits(order); - bs.length = (i + 7) / 8; - bs.data = buf; - bs.type = V_ASN1_INTEGER; - /* If the top bit is set the asn1 encoding is 1 larger. */ - buf[0] = 0xff; - - i = i2d_ASN1_INTEGER(&bs, NULL); - i += i; /* r and s */ - ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); - BN_clear_free(order); - return (ret); -} - -int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp, - new_func, dup_func, free_func); -} - -int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg) -{ - ECDSA_DATA *ecdsa; - ecdsa = ecdsa_check(d); - if (ecdsa == NULL) - return 0; - return (CRYPTO_set_ex_data(&ecdsa->ex_data, idx, arg)); -} - -void *ECDSA_get_ex_data(EC_KEY *d, int idx) -{ - ECDSA_DATA *ecdsa; - ecdsa = ecdsa_check(d); - if (ecdsa == NULL) - return NULL; - return (CRYPTO_get_ex_data(&ecdsa->ex_data, idx)); -} - -ECDSA_METHOD *ECDSA_METHOD_new(const ECDSA_METHOD *ecdsa_meth) -{ - ECDSA_METHOD *ret; - - ret = OPENSSL_malloc(sizeof(ECDSA_METHOD)); - if (ret == NULL) { - ECDSAerr(ECDSA_F_ECDSA_METHOD_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (ecdsa_meth) - *ret = *ecdsa_meth; - else { - ret->ecdsa_sign_setup = 0; - ret->ecdsa_do_sign = 0; - ret->ecdsa_do_verify = 0; - ret->name = NULL; - ret->flags = 0; - } - ret->flags |= ECDSA_METHOD_FLAG_ALLOCATED; - return ret; -} - -void ECDSA_METHOD_set_sign(ECDSA_METHOD *ecdsa_method, - ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char - *dgst, int dgst_len, - const BIGNUM *inv, - const BIGNUM *rp, - EC_KEY *eckey)) -{ - ecdsa_method->ecdsa_do_sign = ecdsa_do_sign; -} - -void ECDSA_METHOD_set_sign_setup(ECDSA_METHOD *ecdsa_method, - int (*ecdsa_sign_setup) (EC_KEY *eckey, - BN_CTX *ctx, - BIGNUM **kinv, - BIGNUM **r)) -{ - ecdsa_method->ecdsa_sign_setup = ecdsa_sign_setup; -} - -void ECDSA_METHOD_set_verify(ECDSA_METHOD *ecdsa_method, - int (*ecdsa_do_verify) (const unsigned char - *dgst, int dgst_len, - const ECDSA_SIG *sig, - EC_KEY *eckey)) -{ - ecdsa_method->ecdsa_do_verify = ecdsa_do_verify; -} - -void ECDSA_METHOD_set_flags(ECDSA_METHOD *ecdsa_method, int flags) -{ - ecdsa_method->flags = flags | ECDSA_METHOD_FLAG_ALLOCATED; -} - -void ECDSA_METHOD_set_name(ECDSA_METHOD *ecdsa_method, char *name) -{ - ecdsa_method->name = name; -} - -void ECDSA_METHOD_free(ECDSA_METHOD *ecdsa_method) -{ - if (ecdsa_method->flags & ECDSA_METHOD_FLAG_ALLOCATED) - OPENSSL_free(ecdsa_method); -} - -void ECDSA_METHOD_set_app_data(ECDSA_METHOD *ecdsa_method, void *app) -{ - ecdsa_method->app_data = app; -} - -void *ECDSA_METHOD_get_app_data(ECDSA_METHOD *ecdsa_method) -{ - return ecdsa_method->app_data; -} -/* crypto/ecdsa/ecs_ossl.c */ -/* - * Written by Nils Larsch for the OpenSSL project - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ecs_locl.h" -// #include "err.h" -#include "obj_mac.h" -// #include "bn.h" -#include "bn_int.h" - -static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, - const BIGNUM *, const BIGNUM *, - EC_KEY *eckey); -static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp); -static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, - const ECDSA_SIG *sig, EC_KEY *eckey); - -static ECDSA_METHOD openssl_ecdsa_meth = { - "OpenSSL ECDSA method", - ecdsa_do_sign, - ecdsa_sign_setup, - ecdsa_do_verify, -#if 0 - NULL, /* init */ - NULL, /* finish */ -#endif - 0, /* flags */ - NULL /* app_data */ -}; - -const ECDSA_METHOD *ECDSA_OpenSSL(void) -{ - return &openssl_ecdsa_meth; -} - -static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp) -{ - BN_CTX *ctx = NULL; - BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; - EC_POINT *tmp_point = NULL; - const EC_GROUP *group; - int ret = 0; - int order_bits; - - if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - - if (ctx_in == NULL) { - if ((ctx = BN_CTX_new()) == NULL) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); - return 0; - } - } else - ctx = ctx_in; - - k = BN_new(); /* this value is later returned in *kinvp */ - r = BN_new(); /* this value is later returned in *rp */ - order = BN_new(); - X = BN_new(); - if (!k || !r || !order || !X) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); - goto err; - } - if ((tmp_point = EC_POINT_new(group)) == NULL) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); - goto err; - } - if (!EC_GROUP_get_order(group, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); - goto err; - } - - /* Preallocate space */ - order_bits = BN_num_bits(order); - if (!BN_set_bit(k, order_bits) - || !BN_set_bit(r, order_bits) - || !BN_set_bit(X, order_bits)) - goto err; - - do { - /* get random k */ - do - if (!BN_rand_range(k, order)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, - ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); - goto err; - } - while (BN_is_zero(k)) ; - - /* - * We do not want timing information to leak the length of k, so we - * compute G*k using an equivalent scalar of fixed bit-length. - * - * We unconditionally perform both of these additions to prevent a - * small timing information leakage. We then choose the sum that is - * one bit longer than the order. This guarantees the code - * path used in the constant time implementations elsewhere. - * - * TODO: revisit the BN_copy aiming for a memory access agnostic - * conditional copy. - */ - if (!BN_add(r, k, order) - || !BN_add(X, r, order) - || !BN_copy(k, BN_num_bits(r) > order_bits ? r : X)) - goto err; - - /* compute r the x-coordinate of generator * k */ - if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); - goto err; - } - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == - NID_X9_62_prime_field) { - if (!EC_POINT_get_affine_coordinates_GFp - (group, tmp_point, X, NULL, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); - goto err; - } - } -#ifndef OPENSSL_NO_EC2M - else { /* NID_X9_62_characteristic_two_field */ - - if (!EC_POINT_get_affine_coordinates_GF2m(group, - tmp_point, X, NULL, - ctx)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); - goto err; - } - } -#endif - if (!BN_nnmod(r, X, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); - goto err; - } - } - while (BN_is_zero(r)); - - /* compute the inverse of k */ - if (EC_GROUP_get_mont_data(group) != NULL) { - /* - * We want inverse in constant time, therefore we utilize the fact - * order must be prime and use Fermats Little Theorem instead. - */ - if (!BN_set_word(X, 2)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); - goto err; - } - if (!BN_mod_sub(X, order, X, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); - goto err; - } - BN_set_flags(X, BN_FLG_CONSTTIME); - if (!BN_mod_exp_mont_consttime - (k, k, X, order, ctx, EC_GROUP_get_mont_data(group))) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); - goto err; - } - } else { - if (!BN_mod_inverse(k, k, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); - goto err; - } - } - - /* clear old values if necessary */ - if (*rp != NULL) - BN_clear_free(*rp); - if (*kinvp != NULL) - BN_clear_free(*kinvp); - /* save the pre-computed values */ - *rp = r; - *kinvp = k; - ret = 1; - err: - if (!ret) { - if (k != NULL) - BN_clear_free(k); - if (r != NULL) - BN_clear_free(r); - } - if (ctx_in == NULL) - BN_CTX_free(ctx); - if (order != NULL) - BN_free(order); - if (tmp_point != NULL) - EC_POINT_free(tmp_point); - if (X) - BN_clear_free(X); - return (ret); -} - -static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, - const BIGNUM *in_kinv, const BIGNUM *in_r, - EC_KEY *eckey) -{ - int ok = 0, i; - BIGNUM *kinv = NULL, *s, *m = NULL, *order = NULL; - const BIGNUM *ckinv; - BN_CTX *ctx = NULL; - const EC_GROUP *group; - ECDSA_SIG *ret; - ECDSA_DATA *ecdsa; - const BIGNUM *priv_key; - BN_MONT_CTX *mont_data; - - ecdsa = ecdsa_check(eckey); - group = EC_KEY_get0_group(eckey); - priv_key = EC_KEY_get0_private_key(eckey); - - if (group == NULL || priv_key == NULL || ecdsa == NULL) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - - ret = ECDSA_SIG_new(); - if (!ret) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); - return NULL; - } - s = ret->s; - - if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || - (m = BN_new()) == NULL) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_GROUP_get_order(group, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); - goto err; - } - mont_data = EC_GROUP_get_mont_data(group); - - i = BN_num_bits(order); - /* - * Need to truncate digest if it is too long: first truncate whole bytes. - */ - if (8 * dgst_len > i) - dgst_len = (i + 7) / 8; - if (!BN_bin2bn(dgst, dgst_len, m)) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); - goto err; - } - /* If still too long truncate remaining bits with a shift */ - if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); - goto err; - } - do { - if (in_kinv == NULL || in_r == NULL) { - if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_ECDSA_LIB); - goto err; - } - ckinv = kinv; - } else { - ckinv = in_kinv; - if (BN_copy(ret->r, in_r) == NULL) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - /* - * With only one multiplicant being in Montgomery domain - * multiplication yields real result without post-conversion. - * Also note that all operations but last are performed with - * zero-padded vectors. Last operation, BN_mod_mul_montgomery - * below, returns user-visible value with removed zero padding. - */ - if (!bn_to_mont_fixed_top(s, ret->r, mont_data, ctx) - || !bn_mul_mont_fixed_top(s, s, priv_key, mont_data, ctx)) { - goto err; - } - if (!bn_mod_add_fixed_top(s, s, m, order)) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); - goto err; - } - /* - * |s| can still be larger than modulus, because |m| can be. In - * such case we count on Montgomery reduction to tie it up. - */ - if (!bn_to_mont_fixed_top(s, s, mont_data, ctx) - || !BN_mod_mul_montgomery(s, s, ckinv, mont_data, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); - goto err; - } - if (BN_is_zero(s)) { - /* - * if kinv and r have been supplied by the caller don't to - * generate new kinv and r values - */ - if (in_kinv != NULL && in_r != NULL) { - ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, - ECDSA_R_NEED_NEW_SETUP_VALUES); - goto err; - } - } else - /* s != 0 => we have a valid signature */ - break; - } - while (1); - - ok = 1; - err: - if (!ok) { - ECDSA_SIG_free(ret); - ret = NULL; - } - if (ctx) - BN_CTX_free(ctx); - if (m) - BN_clear_free(m); - if (order) - BN_free(order); - if (kinv) - BN_clear_free(kinv); - return ret; -} - -static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, - const ECDSA_SIG *sig, EC_KEY *eckey) -{ - int ret = -1, i; - BN_CTX *ctx; - BIGNUM *order, *u1, *u2, *m, *X; - EC_POINT *point = NULL; - const EC_GROUP *group; - const EC_POINT *pub_key; - - /* check input values */ - if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || - (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); - return -1; - } - - ctx = BN_CTX_new(); - if (!ctx) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); - return -1; - } - BN_CTX_start(ctx); - order = BN_CTX_get(ctx); - u1 = BN_CTX_get(ctx); - u2 = BN_CTX_get(ctx); - m = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - if (!X) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); - goto err; - } - - if (!EC_GROUP_get_order(group, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); - goto err; - } - - if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || - BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || - BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); - ret = 0; /* signature is invalid */ - goto err; - } - /* calculate tmp1 = inv(S) mod order */ - if (!BN_mod_inverse(u2, sig->s, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); - goto err; - } - /* digest -> m */ - i = BN_num_bits(order); - /* - * Need to truncate digest if it is too long: first truncate whole bytes. - */ - if (8 * dgst_len > i) - dgst_len = (i + 7) / 8; - if (!BN_bin2bn(dgst, dgst_len, m)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); - goto err; - } - /* If still too long truncate remaining bits with a shift */ - if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); - goto err; - } - /* u1 = m * tmp mod order */ - if (!BN_mod_mul(u1, m, u2, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); - goto err; - } - /* u2 = r * w mod q */ - if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); - goto err; - } - - if ((point = EC_POINT_new(group)) == NULL) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); - goto err; - } - if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == - NID_X9_62_prime_field) { - if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); - goto err; - } - } -#ifndef OPENSSL_NO_EC2M - else { /* NID_X9_62_characteristic_two_field */ - - if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); - goto err; - } - } -#endif - if (!BN_nnmod(u1, X, order, ctx)) { - ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); - goto err; - } - /* if the signature is correct u1 is equal to sig->r */ - ret = (BN_ucmp(u1, sig->r) == 0); - err: - BN_CTX_end(ctx); - BN_CTX_free(ctx); - if (point) - EC_POINT_free(point); - return ret; -} -/* crypto/ecdsa/ecdsa_sign.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ecs_locl.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -#include "rand.h" - -ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) -{ - return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey); -} - -ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, - const BIGNUM *kinv, const BIGNUM *rp, - EC_KEY *eckey) -{ - ECDSA_DATA *ecdsa = ecdsa_check(eckey); - if (ecdsa == NULL) - return NULL; - return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey); -} - -int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char - *sig, unsigned int *siglen, EC_KEY *eckey) -{ - return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey); -} - -int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char - *sig, unsigned int *siglen, const BIGNUM *kinv, - const BIGNUM *r, EC_KEY *eckey) -{ - ECDSA_SIG *s; - RAND_seed(dgst, dlen); - s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); - if (s == NULL) { - *siglen = 0; - return 0; - } - *siglen = i2d_ECDSA_SIG(s, &sig); - ECDSA_SIG_free(s); - return 1; -} - -int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, - BIGNUM **rp) -{ - ECDSA_DATA *ecdsa = ecdsa_check(eckey); - if (ecdsa == NULL) - return 0; - return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); -} -/* crypto/ecdsa/ecdsa_vrf.c */ -/* - * Written by Nils Larsch for the OpenSSL project - */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ecs_locl.h" -#include -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -/*- - * returns - * 1: correct signature - * 0: incorrect signature - * -1: error - */ -int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, - const ECDSA_SIG *sig, EC_KEY *eckey) -{ - ECDSA_DATA *ecdsa = ecdsa_check(eckey); - if (ecdsa == NULL) - return 0; - return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey); -} - -/*- - * returns - * 1: correct signature - * 0: incorrect signature - * -1: error - */ -int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, - const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) -{ - ECDSA_SIG *s; - const unsigned char *p = sigbuf; - unsigned char *der = NULL; - int derlen = -1; - int ret = -1; - - s = ECDSA_SIG_new(); - if (s == NULL) - return (ret); - if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) - goto err; - /* Ensure signature uses DER and doesn't have trailing garbage */ - derlen = i2d_ECDSA_SIG(s, &der); - if (derlen != sig_len || memcmp(sigbuf, der, derlen)) - goto err; - ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); - err: - if (derlen > 0) { - OPENSSL_cleanse(der, derlen); - OPENSSL_free(der); - } - ECDSA_SIG_free(s); - return (ret); -} diff --git a/Sources/COpenSSL/ecs_locl.h b/Sources/COpenSSL/ecs_locl.h deleted file mode 100644 index 08f7c56e..00000000 --- a/Sources/COpenSSL/ecs_locl.h +++ /dev/null @@ -1,120 +0,0 @@ -/* crypto/ecdsa/ecs_locl.h */ -/* - * Written by Nils Larsch for the OpenSSL project - */ -/* ==================================================================== - * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_ECS_LOCL_H -# define HEADER_ECS_LOCL_H - -# include "ecdsa.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct ecdsa_method { - const char *name; - ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char *dgst, int dgst_len, - const BIGNUM *inv, const BIGNUM *rp, - EC_KEY *eckey); - int (*ecdsa_sign_setup) (EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, - BIGNUM **r); - int (*ecdsa_do_verify) (const unsigned char *dgst, int dgst_len, - const ECDSA_SIG *sig, EC_KEY *eckey); -# if 0 - int (*init) (EC_KEY *eckey); - int (*finish) (EC_KEY *eckey); -# endif - int flags; - void *app_data; -}; - -/* The ECDSA_METHOD was allocated and can be freed */ - -# define ECDSA_METHOD_FLAG_ALLOCATED 0x2 - -/* - * If this flag is set the ECDSA method is FIPS compliant and can be used in - * FIPS mode. This is set in the validated module method. If an application - * sets this flag in its own methods it is its responsibility to ensure the - * result is compliant. - */ - -# define ECDSA_FLAG_FIPS_METHOD 0x1 - -typedef struct ecdsa_data_st { - /* EC_KEY_METH_DATA part */ - int (*init) (EC_KEY *); - /* method (ECDSA) specific part */ - ENGINE *engine; - int flags; - const ECDSA_METHOD *meth; - CRYPTO_EX_DATA ex_data; -} ECDSA_DATA; - -/** ecdsa_check - * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure - * and if not it removes the old meth_data and creates a ECDSA_DATA structure. - * \param eckey pointer to a EC_KEY object - * \return pointer to a ECDSA_DATA structure - */ -ECDSA_DATA *ecdsa_check(EC_KEY *eckey); - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_ECS_LOCL_H */ diff --git a/Sources/COpenSSL/ede_cbcm_enc.c b/Sources/COpenSSL/ede_cbcm_enc.c deleted file mode 100644 index 72ef639b..00000000 --- a/Sources/COpenSSL/ede_cbcm_enc.c +++ /dev/null @@ -1,189 +0,0 @@ -/* ede_cbcm_enc.c */ -/* - * Written by Ben Laurie for the OpenSSL project 13 Feb - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * - * This is an implementation of Triple DES Cipher Block Chaining with Output - * Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom). - * - * Note that there is a known attack on this by Biham and Knudsen but it - * takes a lot of work: - * - * http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz - * - */ - -#include "opensslconf.h" /* To see if OPENSSL_NO_DESCBCM is defined */ - -#ifndef OPENSSL_NO_DESCBCM -# include "des_locl.h" - -void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *ks1, - DES_key_schedule *ks2, DES_key_schedule *ks3, - DES_cblock *ivec1, DES_cblock *ivec2, int enc) -{ - register DES_LONG tin0, tin1; - register DES_LONG tout0, tout1, xor0, xor1, m0, m1; - register long l = length; - DES_LONG tin[2]; - unsigned char *iv1, *iv2; - - iv1 = &(*ivec1)[0]; - iv2 = &(*ivec2)[0]; - - if (enc) { - c2l(iv1, m0); - c2l(iv1, m1); - c2l(iv2, tout0); - c2l(iv2, tout1); - for (l -= 8; l >= -7; l -= 8) { - tin[0] = m0; - tin[1] = m1; - DES_encrypt1(tin, ks3, 1); - m0 = tin[0]; - m1 = tin[1]; - - if (l < 0) { - c2ln(in, tin0, tin1, l + 8); - } else { - c2l(in, tin0); - c2l(in, tin1); - } - tin0 ^= tout0; - tin1 ^= tout1; - - tin[0] = tin0; - tin[1] = tin1; - DES_encrypt1(tin, ks1, 1); - tin[0] ^= m0; - tin[1] ^= m1; - DES_encrypt1(tin, ks2, 0); - tin[0] ^= m0; - tin[1] ^= m1; - DES_encrypt1(tin, ks1, 1); - tout0 = tin[0]; - tout1 = tin[1]; - - l2c(tout0, out); - l2c(tout1, out); - } - iv1 = &(*ivec1)[0]; - l2c(m0, iv1); - l2c(m1, iv1); - - iv2 = &(*ivec2)[0]; - l2c(tout0, iv2); - l2c(tout1, iv2); - } else { - register DES_LONG t0, t1; - - c2l(iv1, m0); - c2l(iv1, m1); - c2l(iv2, xor0); - c2l(iv2, xor1); - for (l -= 8; l >= -7; l -= 8) { - tin[0] = m0; - tin[1] = m1; - DES_encrypt1(tin, ks3, 1); - m0 = tin[0]; - m1 = tin[1]; - - c2l(in, tin0); - c2l(in, tin1); - - t0 = tin0; - t1 = tin1; - - tin[0] = tin0; - tin[1] = tin1; - DES_encrypt1(tin, ks1, 0); - tin[0] ^= m0; - tin[1] ^= m1; - DES_encrypt1(tin, ks2, 1); - tin[0] ^= m0; - tin[1] ^= m1; - DES_encrypt1(tin, ks1, 0); - tout0 = tin[0]; - tout1 = tin[1]; - - tout0 ^= xor0; - tout1 ^= xor1; - if (l < 0) { - l2cn(tout0, tout1, out, l + 8); - } else { - l2c(tout0, out); - l2c(tout1, out); - } - xor0 = t0; - xor1 = t1; - } - - iv1 = &(*ivec1)[0]; - l2c(m0, iv1); - l2c(m1, iv1); - - iv2 = &(*ivec2)[0]; - l2c(xor0, iv2); - l2c(xor1, iv2); - } - tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; - tin[0] = tin[1] = 0; -} -#endif diff --git a/Sources/COpenSSL/enc_.c b/Sources/COpenSSL/enc_.c deleted file mode 100644 index 3efa8dec..00000000 --- a/Sources/COpenSSL/enc_.c +++ /dev/null @@ -1,418 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/des/enc_read.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "cryptlib.h" -#include "des_locl.h" - -/* This has some uglies in it but it works - even over sockets. */ -/* - * extern int errno; - */ -OPENSSL_IMPLEMENT_GLOBAL(int, DES_rw_mode, DES_PCBC_MODE) - -/*- - * WARNINGS: - * - * - The data format used by DES_enc_write() and DES_enc_read() - * has a cryptographic weakness: When asked to write more - * than MAXWRITE bytes, DES_enc_write will split the data - * into several chunks that are all encrypted - * using the same IV. So don't use these functions unless you - * are sure you know what you do (in which case you might - * not want to use them anyway). - * - * - This code cannot handle non-blocking sockets. - * - * - This function uses an internal state and thus cannot be - * used on multiple files. - */ -int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, - DES_cblock *iv) -{ -#if defined(OPENSSL_NO_POSIX_IO) - return (0); -#else - /* data to be unencrypted */ - int net_num = 0; - static unsigned char *net = NULL; - /* - * extra unencrypted data for when a block of 100 comes in but is - * des_read one byte at a time. - */ - static unsigned char *unnet = NULL; - static int unnet_start = 0; - static int unnet_left = 0; - static unsigned char *tmpbuf = NULL; - int i; - long num = 0, rnum; - unsigned char *p; - - if (tmpbuf == NULL) { - tmpbuf = OPENSSL_malloc(BSIZE); - if (tmpbuf == NULL) - return (-1); - } - if (net == NULL) { - net = OPENSSL_malloc(BSIZE); - if (net == NULL) - return (-1); - } - if (unnet == NULL) { - unnet = OPENSSL_malloc(BSIZE); - if (unnet == NULL) - return (-1); - } - /* left over data from last decrypt */ - if (unnet_left != 0) { - if (unnet_left < len) { - /* - * we still still need more data but will return with the number - * of bytes we have - should always check the return value - */ - memcpy(buf, &(unnet[unnet_start]), unnet_left); - /* - * eay 26/08/92 I had the next 2 lines reversed :-( - */ - i = unnet_left; - unnet_start = unnet_left = 0; - } else { - memcpy(buf, &(unnet[unnet_start]), len); - unnet_start += len; - unnet_left -= len; - i = len; - } - return (i); - } - - /* We need to get more data. */ - if (len > MAXWRITE) - len = MAXWRITE; - - /* first - get the length */ - while (net_num < HDRSIZE) { -# ifndef OPENSSL_SYS_WIN32 - i = read(fd, (void *)&(net[net_num]), HDRSIZE - net_num); -# else - i = _read(fd, (void *)&(net[net_num]), HDRSIZE - net_num); -# endif -# ifdef EINTR - if ((i == -1) && (errno == EINTR)) - continue; -# endif - if (i <= 0) - return (0); - net_num += i; - } - - /* we now have at net_num bytes in net */ - p = net; - /* num=0; */ - n2l(p, num); - /* - * num should be rounded up to the next group of eight we make sure that - * we have read a multiple of 8 bytes from the net. - */ - if ((num > MAXWRITE) || (num < 0)) /* error */ - return (-1); - rnum = (num < 8) ? 8 : ((num + 7) / 8 * 8); - - net_num = 0; - while (net_num < rnum) { -# ifndef OPENSSL_SYS_WIN32 - i = read(fd, (void *)&(net[net_num]), rnum - net_num); -# else - i = _read(fd, (void *)&(net[net_num]), rnum - net_num); -# endif -# ifdef EINTR - if ((i == -1) && (errno == EINTR)) - continue; -# endif - if (i <= 0) - return (0); - net_num += i; - } - - /* Check if there will be data left over. */ - if (len < num) { - if (DES_rw_mode & DES_PCBC_MODE) - DES_pcbc_encrypt(net, unnet, num, sched, iv, DES_DECRYPT); - else - DES_cbc_encrypt(net, unnet, num, sched, iv, DES_DECRYPT); - memcpy(buf, unnet, len); - unnet_start = len; - unnet_left = num - len; - - /* - * The following line is done because we return num as the number of - * bytes read. - */ - num = len; - } else { - /*- - * >output is a multiple of 8 byes, if len < rnum - * >we must be careful. The user must be aware that this - * >routine will write more bytes than he asked for. - * >The length of the buffer must be correct. - * FIXED - Should be ok now 18-9-90 - eay */ - if (len < rnum) { - - if (DES_rw_mode & DES_PCBC_MODE) - DES_pcbc_encrypt(net, tmpbuf, num, sched, iv, DES_DECRYPT); - else - DES_cbc_encrypt(net, tmpbuf, num, sched, iv, DES_DECRYPT); - - /* - * eay 26/08/92 fix a bug that returned more bytes than you asked - * for (returned len bytes :-( - */ - memcpy(buf, tmpbuf, num); - } else { - if (DES_rw_mode & DES_PCBC_MODE) - DES_pcbc_encrypt(net, buf, num, sched, iv, DES_DECRYPT); - else - DES_cbc_encrypt(net, buf, num, sched, iv, DES_DECRYPT); - } - } - return num; -#endif /* OPENSSL_NO_POSIX_IO */ -} -/* crypto/des/enc_writ.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -// #include "cryptlib.h" -// #include "des_locl.h" -#include "rand.h" - -/*- - * WARNINGS: - * - * - The data format used by DES_enc_write() and DES_enc_read() - * has a cryptographic weakness: When asked to write more - * than MAXWRITE bytes, DES_enc_write will split the data - * into several chunks that are all encrypted - * using the same IV. So don't use these functions unless you - * are sure you know what you do (in which case you might - * not want to use them anyway). - * - * - This code cannot handle non-blocking sockets. - */ - -int DES_enc_write(int fd, const void *_buf, int len, - DES_key_schedule *sched, DES_cblock *iv) -{ -#if defined(OPENSSL_NO_POSIX_IO) - return (-1); -#else -# ifdef _LIBC - extern unsigned long time(); - extern int write(); -# endif - const unsigned char *buf = _buf; - long rnum; - int i, j, k, outnum; - static unsigned char *outbuf = NULL; - unsigned char shortbuf[8]; - unsigned char *p; - const unsigned char *cp; - static int start = 1; - - if (len < 0) - return -1; - - if (outbuf == NULL) { - outbuf = OPENSSL_malloc(BSIZE + HDRSIZE); - if (outbuf == NULL) - return (-1); - } - /* - * If we are sending less than 8 bytes, the same char will look the same - * if we don't pad it out with random bytes - */ - if (start) { - start = 0; - } - - /* lets recurse if we want to send the data in small chunks */ - if (len > MAXWRITE) { - j = 0; - for (i = 0; i < len; i += k) { - k = DES_enc_write(fd, &(buf[i]), - ((len - i) > MAXWRITE) ? MAXWRITE : (len - i), - sched, iv); - if (k < 0) - return (k); - else - j += k; - } - return (j); - } - - /* write length first */ - p = outbuf; - l2n(len, p); - - /* pad short strings */ - if (len < 8) { - cp = shortbuf; - memcpy(shortbuf, buf, len); - if (RAND_bytes(shortbuf + len, 8 - len) <= 0) { - return -1; - } - rnum = 8; - } else { - cp = buf; - rnum = ((len + 7) / 8 * 8); /* round up to nearest eight */ - } - - if (DES_rw_mode & DES_PCBC_MODE) - DES_pcbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched, - iv, DES_ENCRYPT); - else - DES_cbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched, - iv, DES_ENCRYPT); - - /* output */ - outnum = rnum + HDRSIZE; - - for (j = 0; j < outnum; j += i) { - /* - * eay 26/08/92 I was not doing writing from where we got up to. - */ -# ifndef _WIN32 - i = write(fd, (void *)&(outbuf[j]), outnum - j); -# else - i = _write(fd, (void *)&(outbuf[j]), outnum - j); -# endif - if (i == -1) { -# ifdef EINTR - if (errno == EINTR) - i = 0; - else -# endif - /* - * This is really a bad error - very bad It will stuff-up - * both ends. - */ - return (-1); - } - } - - return (len); -#endif /* OPENSSL_NO_POSIX_IO */ -} diff --git a/Sources/COpenSSL/encode.c b/Sources/COpenSSL/encode.c deleted file mode 100644 index 61786587..00000000 --- a/Sources/COpenSSL/encode.c +++ /dev/null @@ -1,461 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/evp/encode.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "cryptlib.h" -#include "evp.h" - -static unsigned char conv_ascii2bin(unsigned char a); -#ifndef CHARSET_EBCDIC -# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) -#else -/* - * We assume that PEM encoded files are EBCDIC files (i.e., printable text - * files). Convert them here while decoding. When encoding, output is EBCDIC - * (text) format again. (No need for conversion in the conv_bin2ascii macro, - * as the underlying textstring data_bin2ascii[] is already EBCDIC) - */ -# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) -#endif - -/*- - * 64 char lines - * pad input with 0 - * left over chars are set to = - * 1 byte => xx== - * 2 bytes => xxx= - * 3 bytes => xxxx - */ -#define BIN_PER_LINE (64/4*3) -#define CHUNKS_PER_LINE (64/4) -#define CHAR_PER_LINE (64+1) - -static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\ -abcdefghijklmnopqrstuvwxyz0123456789+/"; - -/*- - * 0xF0 is a EOLN - * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). - * 0xF2 is EOF - * 0xE0 is ignore at start of line. - * 0xFF is error - */ - -#define B64_EOLN 0xF0 -#define B64_CR 0xF1 -#define B64_EOF 0xF2 -#define B64_WS 0xE0 -#define B64_ERROR 0xFF -#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) -#define B64_BASE64(a) !B64_NOT_BASE64(a) - -static const unsigned char data_ascii2bin[128] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, - 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, - 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, - 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, - 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -}; - -#ifndef CHARSET_EBCDIC -static unsigned char conv_ascii2bin(unsigned char a) -{ - if (a & 0x80) - return B64_ERROR; - return data_ascii2bin[a]; -} -#else -static unsigned char conv_ascii2bin(unsigned char a) -{ - a = os_toascii[a]; - if (a & 0x80) - return B64_ERROR; - return data_ascii2bin[a]; -} -#endif - -void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) -{ - ctx->length = 48; - ctx->num = 0; - ctx->line_num = 0; -} - -void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl) -{ - int i, j; - size_t total = 0; - - *outl = 0; - if (inl <= 0) - return; - OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); - if (ctx->length - ctx->num > inl) { - memcpy(&(ctx->enc_data[ctx->num]), in, inl); - ctx->num += inl; - return; - } - if (ctx->num != 0) { - i = ctx->length - ctx->num; - memcpy(&(ctx->enc_data[ctx->num]), in, i); - in += i; - inl -= i; - j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length); - ctx->num = 0; - out += j; - *(out++) = '\n'; - *out = '\0'; - total = j + 1; - } - while (inl >= ctx->length && total <= INT_MAX) { - j = EVP_EncodeBlock(out, in, ctx->length); - in += ctx->length; - inl -= ctx->length; - out += j; - *(out++) = '\n'; - *out = '\0'; - total += j + 1; - } - if (total > INT_MAX) { - /* Too much output data! */ - *outl = 0; - return; - } - if (inl != 0) - memcpy(&(ctx->enc_data[0]), in, inl); - ctx->num = inl; - *outl = total; -} - -void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) -{ - unsigned int ret = 0; - - if (ctx->num != 0) { - ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num); - out[ret++] = '\n'; - out[ret] = '\0'; - ctx->num = 0; - } - *outl = ret; -} - -int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen) -{ - int i, ret = 0; - unsigned long l; - - for (i = dlen; i > 0; i -= 3) { - if (i >= 3) { - l = (((unsigned long)f[0]) << 16L) | - (((unsigned long)f[1]) << 8L) | f[2]; - *(t++) = conv_bin2ascii(l >> 18L); - *(t++) = conv_bin2ascii(l >> 12L); - *(t++) = conv_bin2ascii(l >> 6L); - *(t++) = conv_bin2ascii(l); - } else { - l = ((unsigned long)f[0]) << 16L; - if (i == 2) - l |= ((unsigned long)f[1] << 8L); - - *(t++) = conv_bin2ascii(l >> 18L); - *(t++) = conv_bin2ascii(l >> 12L); - *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L); - *(t++) = '='; - } - ret += 4; - f += 3; - } - - *t = '\0'; - return (ret); -} - -void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) -{ - /* Only ctx->num is used during decoding. */ - ctx->num = 0; - ctx->length = 0; - ctx->line_num = 0; - ctx->expect_nl = 0; -} - -/*- - * -1 for error - * 0 for last line - * 1 for full line - * - * Note: even though EVP_DecodeUpdate attempts to detect and report end of - * content, the context doesn't currently remember it and will accept more data - * in the next call. Therefore, the caller is responsible for checking and - * rejecting a 0 return value in the middle of content. - * - * Note: even though EVP_DecodeUpdate has historically tried to detect end of - * content based on line length, this has never worked properly. Therefore, - * we now return 0 when one of the following is true: - * - Padding or B64_EOF was detected and the last block is complete. - * - Input has zero-length. - * -1 is returned if: - * - Invalid characters are detected. - * - There is extra trailing padding, or data after padding. - * - B64_EOF is detected after an incomplete base64 block. - */ -int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl) -{ - int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len; - unsigned char *d; - - n = ctx->num; - d = ctx->enc_data; - - if (n > 0 && d[n - 1] == '=') { - eof++; - if (n > 1 && d[n - 2] == '=') - eof++; - } - - /* Legacy behaviour: an empty input chunk signals end of input. */ - if (inl == 0) { - rv = 0; - goto end; - } - - for (i = 0; i < inl; i++) { - tmp = *(in++); - v = conv_ascii2bin(tmp); - if (v == B64_ERROR) { - rv = -1; - goto end; - } - - if (tmp == '=') { - eof++; - } else if (eof > 0 && B64_BASE64(v)) { - /* More data after padding. */ - rv = -1; - goto end; - } - - if (eof > 2) { - rv = -1; - goto end; - } - - if (v == B64_EOF) { - seof = 1; - goto tail; - } - - /* Only save valid base64 characters. */ - if (B64_BASE64(v)) { - if (n >= 64) { - /* - * We increment n once per loop, and empty the buffer as soon as - * we reach 64 characters, so this can only happen if someone's - * manually messed with the ctx. Refuse to write any more data. - */ - rv = -1; - goto end; - } - OPENSSL_assert(n < (int)sizeof(ctx->enc_data)); - d[n++] = tmp; - } - - if (n == 64) { - decoded_len = EVP_DecodeBlock(out, d, n); - n = 0; - if (decoded_len < 0 || eof > decoded_len) { - rv = -1; - goto end; - } - ret += decoded_len - eof; - out += decoded_len - eof; - } - } - - /* - * Legacy behaviour: if the current line is a full base64-block (i.e., has - * 0 mod 4 base64 characters), it is processed immediately. We keep this - * behaviour as applications may not be calling EVP_DecodeFinal properly. - */ -tail: - if (n > 0) { - if ((n & 3) == 0) { - decoded_len = EVP_DecodeBlock(out, d, n); - n = 0; - if (decoded_len < 0 || eof > decoded_len) { - rv = -1; - goto end; - } - ret += (decoded_len - eof); - } else if (seof) { - /* EOF in the middle of a base64 block. */ - rv = -1; - goto end; - } - } - - rv = seof || (n == 0 && eof) ? 0 : 1; -end: - /* Legacy behaviour. This should probably rather be zeroed on error. */ - *outl = ret; - ctx->num = n; - return (rv); -} - -int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n) -{ - int i, ret = 0, a, b, c, d; - unsigned long l; - - /* trim white space from the start of the line. */ - while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) { - f++; - n--; - } - - /* - * strip off stuff at the end of the line ascii2bin values B64_WS, - * B64_EOLN, B64_EOLN and B64_EOF - */ - while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1])))) - n--; - - if (n % 4 != 0) - return (-1); - - for (i = 0; i < n; i += 4) { - a = conv_ascii2bin(*(f++)); - b = conv_ascii2bin(*(f++)); - c = conv_ascii2bin(*(f++)); - d = conv_ascii2bin(*(f++)); - if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) - return (-1); - l = ((((unsigned long)a) << 18L) | - (((unsigned long)b) << 12L) | - (((unsigned long)c) << 6L) | (((unsigned long)d))); - *(t++) = (unsigned char)(l >> 16L) & 0xff; - *(t++) = (unsigned char)(l >> 8L) & 0xff; - *(t++) = (unsigned char)(l) & 0xff; - ret += 3; - } - return (ret); -} - -int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) -{ - int i; - - *outl = 0; - if (ctx->num != 0) { - i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num); - if (i < 0) - return (-1); - ctx->num = 0; - *outl = i; - return (1); - } else - return (1); -} - -#ifdef undef -int EVP_DecodeValid(unsigned char *buf, int len) -{ - int i, num = 0, bad = 0; - - if (len == 0) - return (-1); - while (conv_ascii2bin(*buf) == B64_WS) { - buf++; - len--; - if (len == 0) - return (-1); - } - - for (i = len; i >= 4; i -= 4) { - if ((conv_ascii2bin(buf[0]) >= 0x40) || - (conv_ascii2bin(buf[1]) >= 0x40) || - (conv_ascii2bin(buf[2]) >= 0x40) || - (conv_ascii2bin(buf[3]) >= 0x40)) - return (-1); - buf += 4; - num += 1 + (buf[2] != '=') + (buf[3] != '='); - } - if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN)) - return (num); - if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) && - (conv_ascii2bin(buf[0]) == B64_EOLN)) - return (num); - return (1); -} -#endif diff --git a/Sources/COpenSSL/eng_.c b/Sources/COpenSSL/eng_.c deleted file mode 100644 index b5c2000c..00000000 --- a/Sources/COpenSSL/eng_.c +++ /dev/null @@ -1,5258 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/engine/eng_all.c */ -/* - * Written by Richard Levitte for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "cryptlib.h" -#include "eng_int.h" - -void ENGINE_load_builtin_engines(void) -{ - /* Some ENGINEs need this */ - OPENSSL_cpuid_setup(); -#if 0 - /* - * There's no longer any need for an "openssl" ENGINE unless, one day, it - * is the *only* way for standard builtin implementations to be be - * accessed (ie. it would be possible to statically link binaries with - * *no* builtin implementations). - */ - ENGINE_load_openssl(); -#endif -#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) - ENGINE_load_cryptodev(); -#endif -#ifndef OPENSSL_NO_RDRAND - ENGINE_load_rdrand(); -#endif - ENGINE_load_dynamic(); -#ifndef OPENSSL_NO_STATIC_ENGINE -# ifndef OPENSSL_NO_HW -# ifndef OPENSSL_NO_HW_4758_CCA - ENGINE_load_4758cca(); -# endif -# ifndef OPENSSL_NO_HW_AEP - ENGINE_load_aep(); -# endif -# ifndef OPENSSL_NO_HW_ATALLA - ENGINE_load_atalla(); -# endif -# ifndef OPENSSL_NO_HW_CSWIFT - ENGINE_load_cswift(); -# endif -# ifndef OPENSSL_NO_HW_NCIPHER - ENGINE_load_chil(); -# endif -# ifndef OPENSSL_NO_HW_NURON - ENGINE_load_nuron(); -# endif -# ifndef OPENSSL_NO_HW_SUREWARE - ENGINE_load_sureware(); -# endif -# ifndef OPENSSL_NO_HW_UBSEC - ENGINE_load_ubsec(); -# endif -# ifndef OPENSSL_NO_HW_PADLOCK - ENGINE_load_padlock(); -# endif -# endif -# ifndef OPENSSL_NO_GOST - ENGINE_load_gost(); -# endif -# ifndef OPENSSL_NO_GMP - ENGINE_load_gmp(); -# endif -# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) - ENGINE_load_capi(); -# endif -#endif - ENGINE_register_all_complete(); -} - -#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) -void ENGINE_setup_bsd_cryptodev(void) -{ - static int bsd_cryptodev_default_loaded = 0; - if (!bsd_cryptodev_default_loaded) { - ENGINE_load_cryptodev(); - ENGINE_register_all_complete(); - } - bsd_cryptodev_default_loaded = 1; -} -#endif -/* eng_cnf.c */ -/* - * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "eng_int.h" -#include "conf.h" - -/* #define ENGINE_CONF_DEBUG */ - -/* ENGINE config module */ - -static char *skip_dot(char *name) -{ - char *p; - p = strchr(name, '.'); - if (p) - return p + 1; - return name; -} - -static STACK_OF(ENGINE) *initialized_engines = NULL; - -static int int_engine_init(ENGINE *e) -{ - if (!ENGINE_init(e)) - return 0; - if (!initialized_engines) - initialized_engines = sk_ENGINE_new_null(); - if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) { - ENGINE_finish(e); - return 0; - } - return 1; -} - -static int int_engine_configure(char *name, char *value, const CONF *cnf) -{ - int i; - int ret = 0; - long do_init = -1; - STACK_OF(CONF_VALUE) *ecmds; - CONF_VALUE *ecmd = NULL; - char *ctrlname, *ctrlvalue; - ENGINE *e = NULL; - int soft = 0; - - name = skip_dot(name); -#ifdef ENGINE_CONF_DEBUG - fprintf(stderr, "Configuring engine %s\n", name); -#endif - /* Value is a section containing ENGINE commands */ - ecmds = NCONF_get_section(cnf, value); - - if (!ecmds) { - ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, - ENGINE_R_ENGINE_SECTION_ERROR); - return 0; - } - - for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) { - ecmd = sk_CONF_VALUE_value(ecmds, i); - ctrlname = skip_dot(ecmd->name); - ctrlvalue = ecmd->value; -#ifdef ENGINE_CONF_DEBUG - fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, - ctrlvalue); -#endif - - /* First handle some special pseudo ctrls */ - - /* Override engine name to use */ - if (!strcmp(ctrlname, "engine_id")) - name = ctrlvalue; - else if (!strcmp(ctrlname, "soft_load")) - soft = 1; - /* Load a dynamic ENGINE */ - else if (!strcmp(ctrlname, "dynamic_path")) { - e = ENGINE_by_id("dynamic"); - if (!e) - goto err; - if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0)) - goto err; - if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0)) - goto err; - if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) - goto err; - } - /* ... add other pseudos here ... */ - else { - /* - * At this point we need an ENGINE structural reference if we - * don't already have one. - */ - if (!e) { - e = ENGINE_by_id(name); - if (!e && soft) { - ERR_clear_error(); - return 1; - } - if (!e) - goto err; - } - /* - * Allow "EMPTY" to mean no value: this allows a valid "value" to - * be passed to ctrls of type NO_INPUT - */ - if (!strcmp(ctrlvalue, "EMPTY")) - ctrlvalue = NULL; - if (!strcmp(ctrlname, "init")) { - if (!NCONF_get_number_e(cnf, value, "init", &do_init)) - goto err; - if (do_init == 1) { - if (!int_engine_init(e)) - goto err; - } else if (do_init != 0) { - ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, - ENGINE_R_INVALID_INIT_VALUE); - goto err; - } - } else if (!strcmp(ctrlname, "default_algorithms")) { - if (!ENGINE_set_default_string(e, ctrlvalue)) - goto err; - } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0)) - goto err; - } - - } - if (e && (do_init == -1) && !int_engine_init(e)) { - ecmd = NULL; - goto err; - } - ret = 1; - err: - if (ret != 1) { - ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, - ENGINE_R_ENGINE_CONFIGURATION_ERROR); - if (ecmd) - ERR_add_error_data(6, "section=", ecmd->section, - ", name=", ecmd->name, - ", value=", ecmd->value); - } - if (e) - ENGINE_free(e); - return ret; -} - -static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) -{ - STACK_OF(CONF_VALUE) *elist; - CONF_VALUE *cval; - int i; -#ifdef ENGINE_CONF_DEBUG - fprintf(stderr, "Called engine module: name %s, value %s\n", - CONF_imodule_get_name(md), CONF_imodule_get_value(md)); -#endif - /* Value is a section containing ENGINEs to configure */ - elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); - - if (!elist) { - ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, - ENGINE_R_ENGINES_SECTION_ERROR); - return 0; - } - - for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { - cval = sk_CONF_VALUE_value(elist, i); - if (!int_engine_configure(cval->name, cval->value, cnf)) - return 0; - } - - return 1; -} - -static void int_engine_module_finish(CONF_IMODULE *md) -{ - ENGINE *e; - while ((e = sk_ENGINE_pop(initialized_engines))) - ENGINE_finish(e); - sk_ENGINE_free(initialized_engines); - initialized_engines = NULL; -} - -void ENGINE_add_conf_module(void) -{ - CONF_module_add("engines", - int_engine_module_init, int_engine_module_finish); -} -/* - * Copyright (c) 2002 Bob Beck - * Copyright (c) 2002 Theo de Raadt - * Copyright (c) 2002 Markus Friedl - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include "objects.h" -#include "engine.h" -#include "evp.h" -#include "bn.h" - -#if (defined(__unix__) || defined(unix)) && !defined(USG) && \ - (defined(OpenBSD) || defined(__FreeBSD__)) -# include -# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) -# define HAVE_CRYPTODEV -# endif -# if (OpenBSD >= 200110) -# define HAVE_SYSLOG_R -# endif -#endif - -#ifndef HAVE_CRYPTODEV - -void ENGINE_load_cryptodev(void) -{ - /* This is a NOP on platforms without /dev/crypto */ - return; -} - -#else - -# include -# include -# include "dh.h" -# include "dsa.h" -# include "err.h" -# include "rsa.h" -# include -# include -# include -# include -# include -# include -# include -# include -# include - -struct dev_crypto_state { - struct session_op d_sess; - int d_fd; -# ifdef USE_CRYPTODEV_DIGESTS - char dummy_mac_key[HASH_MAX_LEN]; - unsigned char digest_res[HASH_MAX_LEN]; - char *mac_data; - int mac_len; -# endif -}; - -static u_int32_t cryptodev_asymfeat = 0; - -static int get_asym_dev_crypto(void); -static int open_dev_crypto(void); -static int get_dev_crypto(void); -static int get_cryptodev_ciphers(const int **cnids); -# ifdef USE_CRYPTODEV_DIGESTS -static int get_cryptodev_digests(const int **cnids); -# endif -static int cryptodev_usable_ciphers(const int **nids); -static int cryptodev_usable_digests(const int **nids); -static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); -static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid); -static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid); -static int bn2crparam(const BIGNUM *a, struct crparam *crp); -static int crparam2bn(struct crparam *crp, BIGNUM *a); -static void zapparams(struct crypt_kop *kop); -static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, - int slen, BIGNUM *s); - -static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx); -static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, - BN_CTX *ctx, BN_MONT_CTX *m_ctx); -static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, - BIGNUM *p, BN_CTX *ctx, - BN_MONT_CTX *mont); -static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, - DSA *dsa); -static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa); -static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx); -static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, - DH *dh); -static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, - void (*f) (void)); -void ENGINE_load_cryptodev(void); - -static const ENGINE_CMD_DEFN cryptodev_defns[] = { - {0, NULL, NULL, 0} -}; - -static struct { - int id; - int nid; - int ivmax; - int keylen; -} ciphers[] = { - { - CRYPTO_ARC4, NID_rc4, 0, 16, - }, - { - CRYPTO_DES_CBC, NID_des_cbc, 8, 8, - }, - { - CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, - }, - { - CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, - }, - { - CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, - }, - { - CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, - }, -# ifdef CRYPTO_AES_CTR - { - CRYPTO_AES_CTR, NID_aes_128_ctr, 14, 16, - }, - { - CRYPTO_AES_CTR, NID_aes_192_ctr, 14, 24, - }, - { - CRYPTO_AES_CTR, NID_aes_256_ctr, 14, 32, - }, -# endif - { - CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, - }, - { - CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, - }, - { - CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, - }, - { - 0, NID_undef, 0, 0, - }, -}; - -# ifdef USE_CRYPTODEV_DIGESTS -static struct { - int id; - int nid; - int keylen; -} digests[] = { - { - CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16 - }, - { - CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20 - }, - { - CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16 - /* ? */ - }, - { - CRYPTO_MD5_KPDK, NID_undef, 0 - }, - { - CRYPTO_SHA1_KPDK, NID_undef, 0 - }, - { - CRYPTO_MD5, NID_md5, 16 - }, - { - CRYPTO_SHA1, NID_sha1, 20 - }, - { - 0, NID_undef, 0 - }, -}; -# endif - -/* - * Return a fd if /dev/crypto seems usable, 0 otherwise. - */ -static int open_dev_crypto(void) -{ - static int fd = -1; - - if (fd == -1) { - if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) - return (-1); - /* close on exec */ - if (fcntl(fd, F_SETFD, 1) == -1) { - close(fd); - fd = -1; - return (-1); - } - } - return (fd); -} - -static int get_dev_crypto(void) -{ - int fd, retfd; - - if ((fd = open_dev_crypto()) == -1) - return (-1); -# ifndef CRIOGET_NOT_NEEDED - if (ioctl(fd, CRIOGET, &retfd) == -1) - return (-1); - - /* close on exec */ - if (fcntl(retfd, F_SETFD, 1) == -1) { - close(retfd); - return (-1); - } -# else - retfd = fd; -# endif - return (retfd); -} - -static void put_dev_crypto(int fd) -{ -# ifndef CRIOGET_NOT_NEEDED - close(fd); -# endif -} - -/* Caching version for asym operations */ -static int get_asym_dev_crypto(void) -{ - static int fd = -1; - - if (fd == -1) - fd = get_dev_crypto(); - return fd; -} - -/* - * Find out what ciphers /dev/crypto will let us have a session for. - * XXX note, that some of these openssl doesn't deal with yet! - * returning them here is harmless, as long as we return NULL - * when asked for a handler in the cryptodev_engine_ciphers routine - */ -static int get_cryptodev_ciphers(const int **cnids) -{ - static int nids[CRYPTO_ALGORITHM_MAX]; - struct session_op sess; - int fd, i, count = 0; - - if ((fd = get_dev_crypto()) < 0) { - *cnids = NULL; - return (0); - } - memset(&sess, 0, sizeof(sess)); - sess.key = (caddr_t) "123456789abcdefghijklmno"; - - for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { - if (ciphers[i].nid == NID_undef) - continue; - sess.cipher = ciphers[i].id; - sess.keylen = ciphers[i].keylen; - sess.mac = 0; - if (ioctl(fd, CIOCGSESSION, &sess) != -1 && - ioctl(fd, CIOCFSESSION, &sess.ses) != -1) - nids[count++] = ciphers[i].nid; - } - put_dev_crypto(fd); - - if (count > 0) - *cnids = nids; - else - *cnids = NULL; - return (count); -} - -# ifdef USE_CRYPTODEV_DIGESTS -/* - * Find out what digests /dev/crypto will let us have a session for. - * XXX note, that some of these openssl doesn't deal with yet! - * returning them here is harmless, as long as we return NULL - * when asked for a handler in the cryptodev_engine_digests routine - */ -static int get_cryptodev_digests(const int **cnids) -{ - static int nids[CRYPTO_ALGORITHM_MAX]; - struct session_op sess; - int fd, i, count = 0; - - if ((fd = get_dev_crypto()) < 0) { - *cnids = NULL; - return (0); - } - memset(&sess, 0, sizeof(sess)); - sess.mackey = (caddr_t) "123456789abcdefghijklmno"; - for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { - if (digests[i].nid == NID_undef) - continue; - sess.mac = digests[i].id; - sess.mackeylen = digests[i].keylen; - sess.cipher = 0; - if (ioctl(fd, CIOCGSESSION, &sess) != -1 && - ioctl(fd, CIOCFSESSION, &sess.ses) != -1) - nids[count++] = digests[i].nid; - } - put_dev_crypto(fd); - - if (count > 0) - *cnids = nids; - else - *cnids = NULL; - return (count); -} -# endif /* 0 */ - -/* - * Find the useable ciphers|digests from dev/crypto - this is the first - * thing called by the engine init crud which determines what it - * can use for ciphers from this engine. We want to return - * only what we can do, anythine else is handled by software. - * - * If we can't initialize the device to do anything useful for - * any reason, we want to return a NULL array, and 0 length, - * which forces everything to be done is software. By putting - * the initalization of the device in here, we ensure we can - * use this engine as the default, and if for whatever reason - * /dev/crypto won't do what we want it will just be done in - * software - * - * This can (should) be greatly expanded to perhaps take into - * account speed of the device, and what we want to do. - * (although the disabling of particular alg's could be controlled - * by the device driver with sysctl's.) - this is where we - * want most of the decisions made about what we actually want - * to use from /dev/crypto. - */ -static int cryptodev_usable_ciphers(const int **nids) -{ - return (get_cryptodev_ciphers(nids)); -} - -static int cryptodev_usable_digests(const int **nids) -{ -# ifdef USE_CRYPTODEV_DIGESTS - return (get_cryptodev_digests(nids)); -# else - /* - * XXXX just disable all digests for now, because it sucks. - * we need a better way to decide this - i.e. I may not - * want digests on slow cards like hifn on fast machines, - * but might want them on slow or loaded machines, etc. - * will also want them when using crypto cards that don't - * suck moose gonads - would be nice to be able to decide something - * as reasonable default without having hackery that's card dependent. - * of course, the default should probably be just do everything, - * with perhaps a sysctl to turn algoritms off (or have them off - * by default) on cards that generally suck like the hifn. - */ - *nids = NULL; - return (0); -# endif -} - -static int -cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - struct crypt_op cryp; - struct dev_crypto_state *state = ctx->cipher_data; - struct session_op *sess = &state->d_sess; - const void *iiv; - unsigned char save_iv[EVP_MAX_IV_LENGTH]; - - if (state->d_fd < 0) - return (0); - if (!inl) - return (1); - if ((inl % ctx->cipher->block_size) != 0) - return (0); - - memset(&cryp, 0, sizeof(cryp)); - - cryp.ses = sess->ses; - cryp.flags = 0; - cryp.len = inl; - cryp.src = (caddr_t) in; - cryp.dst = (caddr_t) out; - cryp.mac = 0; - - cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; - - if (ctx->cipher->iv_len) { - cryp.iv = (caddr_t) ctx->iv; - if (!ctx->encrypt) { - iiv = in + inl - ctx->cipher->iv_len; - memcpy(save_iv, iiv, ctx->cipher->iv_len); - } - } else - cryp.iv = NULL; - - if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { - /* - * XXX need better errror handling this can fail for a number of - * different reasons. - */ - return (0); - } - - if (ctx->cipher->iv_len) { - if (ctx->encrypt) - iiv = out + inl - ctx->cipher->iv_len; - else - iiv = save_iv; - memcpy(ctx->iv, iiv, ctx->cipher->iv_len); - } - return (1); -} - -static int -cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - struct dev_crypto_state *state = ctx->cipher_data; - struct session_op *sess = &state->d_sess; - int cipher = -1, i; - - for (i = 0; ciphers[i].id; i++) - if (ctx->cipher->nid == ciphers[i].nid && - ctx->cipher->iv_len <= ciphers[i].ivmax && - ctx->key_len == ciphers[i].keylen) { - cipher = ciphers[i].id; - break; - } - - if (!ciphers[i].id) { - state->d_fd = -1; - return (0); - } - - memset(sess, 0, sizeof(struct session_op)); - - if ((state->d_fd = get_dev_crypto()) < 0) - return (0); - - sess->key = (caddr_t) key; - sess->keylen = ctx->key_len; - sess->cipher = cipher; - - if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { - put_dev_crypto(state->d_fd); - state->d_fd = -1; - return (0); - } - return (1); -} - -/* - * free anything we allocated earlier when initting a - * session, and close the session. - */ -static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx) -{ - int ret = 0; - struct dev_crypto_state *state = ctx->cipher_data; - struct session_op *sess = &state->d_sess; - - if (state->d_fd < 0) - return (0); - - /* - * XXX if this ioctl fails, someting's wrong. the invoker may have called - * us with a bogus ctx, or we could have a device that for whatever - * reason just doesn't want to play ball - it's not clear what's right - * here - should this be an error? should it just increase a counter, - * hmm. For right now, we return 0 - I don't believe that to be "right". - * we could call the gorpy openssl lib error handlers that print messages - * to users of the library. hmm.. - */ - - if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { - ret = 0; - } else { - ret = 1; - } - put_dev_crypto(state->d_fd); - state->d_fd = -1; - - return (ret); -} - -/* - * libcrypto EVP stuff - this is how we get wired to EVP so the engine - * gets called when libcrypto requests a cipher NID. - */ - -/* RC4 */ -const EVP_CIPHER cryptodev_rc4 = { - NID_rc4, - 1, 16, 0, - EVP_CIPH_VARIABLE_LENGTH, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - NULL, - NULL, - NULL -}; - -/* DES CBC EVP */ -const EVP_CIPHER cryptodev_des_cbc = { - NID_des_cbc, - 8, 8, 8, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -/* 3DES CBC EVP */ -const EVP_CIPHER cryptodev_3des_cbc = { - NID_des_ede3_cbc, - 8, 24, 8, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -const EVP_CIPHER cryptodev_bf_cbc = { - NID_bf_cbc, - 8, 16, 8, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -const EVP_CIPHER cryptodev_cast_cbc = { - NID_cast5_cbc, - 8, 16, 8, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -const EVP_CIPHER cryptodev_aes_cbc = { - NID_aes_128_cbc, - 16, 16, 16, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -const EVP_CIPHER cryptodev_aes_192_cbc = { - NID_aes_192_cbc, - 16, 24, 16, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -const EVP_CIPHER cryptodev_aes_256_cbc = { - NID_aes_256_cbc, - 16, 32, 16, - EVP_CIPH_CBC_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -# ifdef CRYPTO_AES_CTR -const EVP_CIPHER cryptodev_aes_ctr = { - NID_aes_128_ctr, - 16, 16, 14, - EVP_CIPH_CTR_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -const EVP_CIPHER cryptodev_aes_ctr_192 = { - NID_aes_192_ctr, - 16, 24, 14, - EVP_CIPH_CTR_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; - -const EVP_CIPHER cryptodev_aes_ctr_256 = { - NID_aes_256_ctr, - 16, 32, 14, - EVP_CIPH_CTR_MODE, - cryptodev_init_key, - cryptodev_cipher, - cryptodev_cleanup, - sizeof(struct dev_crypto_state), - EVP_CIPHER_set_asn1_iv, - EVP_CIPHER_get_asn1_iv, - NULL -}; -# endif -/* - * Registered by the ENGINE when used to find out how to deal with - * a particular NID in the ENGINE. this says what we'll do at the - * top level - note, that list is restricted by what we answer with - */ -static int -cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid) -{ - if (!cipher) - return (cryptodev_usable_ciphers(nids)); - - switch (nid) { - case NID_rc4: - *cipher = &cryptodev_rc4; - break; - case NID_des_ede3_cbc: - *cipher = &cryptodev_3des_cbc; - break; - case NID_des_cbc: - *cipher = &cryptodev_des_cbc; - break; - case NID_bf_cbc: - *cipher = &cryptodev_bf_cbc; - break; - case NID_cast5_cbc: - *cipher = &cryptodev_cast_cbc; - break; - case NID_aes_128_cbc: - *cipher = &cryptodev_aes_cbc; - break; - case NID_aes_192_cbc: - *cipher = &cryptodev_aes_192_cbc; - break; - case NID_aes_256_cbc: - *cipher = &cryptodev_aes_256_cbc; - break; -# ifdef CRYPTO_AES_CTR - case NID_aes_128_ctr: - *cipher = &cryptodev_aes_ctr; - break; - case NID_aes_192_ctr: - *cipher = &cryptodev_aes_ctr_192; - break; - case NID_aes_256_ctr: - *cipher = &cryptodev_aes_ctr_256; - break; -# endif - default: - *cipher = NULL; - break; - } - return (*cipher != NULL); -} - -# ifdef USE_CRYPTODEV_DIGESTS - -/* convert digest type to cryptodev */ -static int digest_nid_to_cryptodev(int nid) -{ - int i; - - for (i = 0; digests[i].id; i++) - if (digests[i].nid == nid) - return (digests[i].id); - return (0); -} - -static int digest_key_length(int nid) -{ - int i; - - for (i = 0; digests[i].id; i++) - if (digests[i].nid == nid) - return digests[i].keylen; - return (0); -} - -static int cryptodev_digest_init(EVP_MD_CTX *ctx) -{ - struct dev_crypto_state *state = ctx->md_data; - struct session_op *sess = &state->d_sess; - int digest; - - if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef) { - printf("cryptodev_digest_init: Can't get digest \n"); - return (0); - } - - memset(state, 0, sizeof(struct dev_crypto_state)); - - if ((state->d_fd = get_dev_crypto()) < 0) { - printf("cryptodev_digest_init: Can't get Dev \n"); - return (0); - } - - sess->mackey = state->dummy_mac_key; - sess->mackeylen = digest_key_length(ctx->digest->type); - sess->mac = digest; - - if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { - put_dev_crypto(state->d_fd); - state->d_fd = -1; - printf("cryptodev_digest_init: Open session failed\n"); - return (0); - } - - return (1); -} - -static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, - size_t count) -{ - struct crypt_op cryp; - struct dev_crypto_state *state = ctx->md_data; - struct session_op *sess = &state->d_sess; - - if (!data || state->d_fd < 0) { - printf("cryptodev_digest_update: illegal inputs \n"); - return (0); - } - - if (!count) { - return (0); - } - - if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { - /* if application doesn't support one buffer */ - char *mac_data = - OPENSSL_realloc(state->mac_data, state->mac_len + count); - - if (mac_data == NULL) { - printf("cryptodev_digest_update: realloc failed\n"); - return (0); - } - - state->mac_data = mac_data; - memcpy(state->mac_data + state->mac_len, data, count); - state->mac_len += count; - - return (1); - } - - memset(&cryp, 0, sizeof(cryp)); - - cryp.ses = sess->ses; - cryp.flags = 0; - cryp.len = count; - cryp.src = (caddr_t) data; - cryp.dst = NULL; - cryp.mac = (caddr_t) state->digest_res; - if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { - printf("cryptodev_digest_update: digest failed\n"); - return (0); - } - return (1); -} - -static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - struct crypt_op cryp; - struct dev_crypto_state *state = ctx->md_data; - struct session_op *sess = &state->d_sess; - - int ret = 1; - - if (!md || state->d_fd < 0) { - printf("cryptodev_digest_final: illegal input\n"); - return (0); - } - - if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { - /* if application doesn't support one buffer */ - memset(&cryp, 0, sizeof(cryp)); - cryp.ses = sess->ses; - cryp.flags = 0; - cryp.len = state->mac_len; - cryp.src = state->mac_data; - cryp.dst = NULL; - cryp.mac = (caddr_t) md; - if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { - printf("cryptodev_digest_final: digest failed\n"); - return (0); - } - - return 1; - } - - memcpy(md, state->digest_res, ctx->digest->md_size); - - return (ret); -} - -static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) -{ - int ret = 1; - struct dev_crypto_state *state = ctx->md_data; - struct session_op *sess = &state->d_sess; - - if (state == NULL) - return 0; - - if (state->d_fd < 0) { - printf("cryptodev_digest_cleanup: illegal input\n"); - return (0); - } - - if (state->mac_data) { - OPENSSL_free(state->mac_data); - state->mac_data = NULL; - state->mac_len = 0; - } - - if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { - printf("cryptodev_digest_cleanup: failed to close session\n"); - ret = 0; - } else { - ret = 1; - } - put_dev_crypto(state->d_fd); - state->d_fd = -1; - - return (ret); -} - -static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) -{ - struct dev_crypto_state *fstate = from->md_data; - struct dev_crypto_state *dstate = to->md_data; - struct session_op *sess; - int digest; - - if (dstate == NULL || fstate == NULL) - return 1; - - memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); - - sess = &dstate->d_sess; - - digest = digest_nid_to_cryptodev(to->digest->type); - - sess->mackey = dstate->dummy_mac_key; - sess->mackeylen = digest_key_length(to->digest->type); - sess->mac = digest; - - dstate->d_fd = get_dev_crypto(); - - if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) { - put_dev_crypto(dstate->d_fd); - dstate->d_fd = -1; - printf("cryptodev_digest_init: Open session failed\n"); - return (0); - } - - dstate->mac_len = fstate->mac_len; - if (fstate->mac_len != 0) { - if (fstate->mac_data != NULL) { - dstate->mac_data = OPENSSL_malloc(fstate->mac_len); - if (dstate->mac_data == NULL) { - printf("cryptodev_digest_init: malloc failed\n"); - return 0; - } - memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); - } - } - - return 1; -} - -const EVP_MD cryptodev_sha1 = { - NID_sha1, - NID_undef, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_ONESHOT, - cryptodev_digest_init, - cryptodev_digest_update, - cryptodev_digest_final, - cryptodev_digest_copy, - cryptodev_digest_cleanup, - EVP_PKEY_NULL_method, - SHA_CBLOCK, - sizeof(struct dev_crypto_state), -}; - -const EVP_MD cryptodev_md5 = { - NID_md5, - NID_undef, - 16 /* MD5_DIGEST_LENGTH */ , - EVP_MD_FLAG_ONESHOT, - cryptodev_digest_init, - cryptodev_digest_update, - cryptodev_digest_final, - cryptodev_digest_copy, - cryptodev_digest_cleanup, - EVP_PKEY_NULL_method, - 64 /* MD5_CBLOCK */ , - sizeof(struct dev_crypto_state), -}; - -# endif /* USE_CRYPTODEV_DIGESTS */ - -static int -cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid) -{ - if (!digest) - return (cryptodev_usable_digests(nids)); - - switch (nid) { -# ifdef USE_CRYPTODEV_DIGESTS - case NID_md5: - *digest = &cryptodev_md5; - break; - case NID_sha1: - *digest = &cryptodev_sha1; - break; - default: -# endif /* USE_CRYPTODEV_DIGESTS */ - *digest = NULL; - break; - } - return (*digest != NULL); -} - -/* - * Convert a BIGNUM to the representation that /dev/crypto needs. - * Upon completion of use, the caller is responsible for freeing - * crp->crp_p. - */ -static int bn2crparam(const BIGNUM *a, struct crparam *crp) -{ - int i, j, k; - ssize_t bytes, bits; - u_char *b; - - crp->crp_p = NULL; - crp->crp_nbits = 0; - - bits = BN_num_bits(a); - bytes = (bits + 7) / 8; - - b = malloc(bytes); - if (b == NULL) - return (1); - memset(b, 0, bytes); - - crp->crp_p = (caddr_t) b; - crp->crp_nbits = bits; - - for (i = 0, j = 0; i < a->top; i++) { - for (k = 0; k < BN_BITS2 / 8; k++) { - if ((j + k) >= bytes) - return (0); - b[j + k] = a->d[i] >> (k * 8); - } - j += BN_BITS2 / 8; - } - return (0); -} - -/* Convert a /dev/crypto parameter to a BIGNUM */ -static int crparam2bn(struct crparam *crp, BIGNUM *a) -{ - u_int8_t *pd; - int i, bytes; - - bytes = (crp->crp_nbits + 7) / 8; - - if (bytes == 0) - return (-1); - - if ((pd = (u_int8_t *) malloc(bytes)) == NULL) - return (-1); - - for (i = 0; i < bytes; i++) - pd[i] = ((char *)crp->crp_p)[bytes - i - 1]; - - BN_bin2bn(pd, bytes, a); - free(pd); - - return (0); -} - -static void zapparams(struct crypt_kop *kop) -{ - int i; - - for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { - OPENSSL_free(kop->crk_param[i].crp_p); - kop->crk_param[i].crp_p = NULL; - kop->crk_param[i].crp_nbits = 0; - } -} - -static int -cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, - BIGNUM *s) -{ - int fd, ret = -1; - - if ((fd = get_asym_dev_crypto()) < 0) - return ret; - - if (r) { - kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_malloc(rlen); - if (kop->crk_param[kop->crk_iparams].crp_p == NULL) - return ret; - memset(kop->crk_param[kop->crk_iparams].crp_p, 0, (size_t)rlen); - kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; - kop->crk_oparams++; - } - if (s) { - kop->crk_param[kop->crk_iparams + 1].crp_p = OPENSSL_malloc(slen); - /* No need to free the kop->crk_iparams parameter if it was allocated, - * callers of this routine have to free allocated parameters through - * zapparams both in case of success and failure - */ - if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL) - return ret; - memset(kop->crk_param[kop->crk_iparams + 1].crp_p, 0, (size_t)slen); - kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8; - kop->crk_oparams++; - } - - if (ioctl(fd, CIOCKEY, kop) == 0) { - if (r) - crparam2bn(&kop->crk_param[kop->crk_iparams], r); - if (s) - crparam2bn(&kop->crk_param[kop->crk_iparams + 1], s); - ret = 0; - } - - return ret; -} - -static int -cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) -{ - struct crypt_kop kop; - int ret = 1; - - /* - * Currently, we know we can do mod exp iff we can do any asymmetric - * operations at all. - */ - if (cryptodev_asymfeat == 0) { - ret = BN_mod_exp(r, a, p, m, ctx); - return (ret); - } - - memset(&kop, 0, sizeof(kop)); - kop.crk_op = CRK_MOD_EXP; - - /* inputs: a^p % m */ - if (bn2crparam(a, &kop.crk_param[0])) - goto err; - if (bn2crparam(p, &kop.crk_param[1])) - goto err; - if (bn2crparam(m, &kop.crk_param[2])) - goto err; - kop.crk_iparams = 3; - - if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - printf("OCF asym process failed, Running in software\n"); - ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); - - } else if (ECANCELED == kop.crk_status) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - printf("OCF hardware operation cancelled. Running in Software\n"); - ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); - } - /* else cryptodev operation worked ok ==> ret = 1 */ - - err: - zapparams(&kop); - return (ret); -} - -static int -cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, - BN_CTX *ctx) -{ - int r; - ctx = BN_CTX_new(); - r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); - BN_CTX_free(ctx); - return (r); -} - -static int -cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) -{ - struct crypt_kop kop; - int ret = 1; - - if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { - /* XXX 0 means failure?? */ - return (0); - } - - memset(&kop, 0, sizeof(kop)); - kop.crk_op = CRK_MOD_EXP_CRT; - /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ - if (bn2crparam(rsa->p, &kop.crk_param[0])) - goto err; - if (bn2crparam(rsa->q, &kop.crk_param[1])) - goto err; - if (bn2crparam(I, &kop.crk_param[2])) - goto err; - if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) - goto err; - if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) - goto err; - if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) - goto err; - kop.crk_iparams = 6; - - if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - printf("OCF asym process failed, running in Software\n"); - ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); - - } else if (ECANCELED == kop.crk_status) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - printf("OCF hardware operation cancelled. Running in Software\n"); - ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); - } - /* else cryptodev operation worked ok ==> ret = 1 */ - - err: - zapparams(&kop); - return (ret); -} - -static RSA_METHOD cryptodev_rsa = { - "cryptodev RSA method", - NULL, /* rsa_pub_enc */ - NULL, /* rsa_pub_dec */ - NULL, /* rsa_priv_enc */ - NULL, /* rsa_priv_dec */ - NULL, - NULL, - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL, /* app_data */ - NULL, /* rsa_sign */ - NULL /* rsa_verify */ -}; - -static int -cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) -{ - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); -} - -static int -cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, - BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, - BN_CTX *ctx, BN_MONT_CTX *mont) -{ - BIGNUM t2; - int ret = 0; - - BN_init(&t2); - - /* v = ( g^u1 * y^u2 mod p ) mod q */ - /* let t1 = g ^ u1 mod p */ - ret = 0; - - if (!dsa->meth->bn_mod_exp(dsa, t1, dsa->g, u1, dsa->p, ctx, mont)) - goto err; - - /* let t2 = y ^ u2 mod p */ - if (!dsa->meth->bn_mod_exp(dsa, &t2, dsa->pub_key, u2, dsa->p, ctx, mont)) - goto err; - /* let u1 = t1 * t2 mod p */ - if (!BN_mod_mul(u1, t1, &t2, dsa->p, ctx)) - goto err; - - BN_copy(t1, u1); - - ret = 1; - err: - BN_free(&t2); - return (ret); -} - -static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, - DSA *dsa) -{ - struct crypt_kop kop; - BIGNUM *r = NULL, *s = NULL; - DSA_SIG *dsaret = NULL; - - if ((r = BN_new()) == NULL) - goto err; - if ((s = BN_new()) == NULL) { - BN_free(r); - goto err; - } - - memset(&kop, 0, sizeof(kop)); - kop.crk_op = CRK_DSA_SIGN; - - /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ - kop.crk_param[0].crp_p = (caddr_t) dgst; - kop.crk_param[0].crp_nbits = dlen * 8; - if (bn2crparam(dsa->p, &kop.crk_param[1])) - goto err; - if (bn2crparam(dsa->q, &kop.crk_param[2])) - goto err; - if (bn2crparam(dsa->g, &kop.crk_param[3])) - goto err; - if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) - goto err; - kop.crk_iparams = 5; - - if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, - BN_num_bytes(dsa->q), s) == 0) { - dsaret = DSA_SIG_new(); - if (dsaret == NULL) - goto err; - dsaret->r = r; - dsaret->s = s; - r = s = NULL; - } else { - const DSA_METHOD *meth = DSA_OpenSSL(); - dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa); - } - err: - BN_free(r); - BN_free(s); - kop.crk_param[0].crp_p = NULL; - zapparams(&kop); - return (dsaret); -} - -static int -cryptodev_dsa_verify(const unsigned char *dgst, int dlen, - DSA_SIG *sig, DSA *dsa) -{ - struct crypt_kop kop; - int dsaret = 1; - - memset(&kop, 0, sizeof(kop)); - kop.crk_op = CRK_DSA_VERIFY; - - /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ - kop.crk_param[0].crp_p = (caddr_t) dgst; - kop.crk_param[0].crp_nbits = dlen * 8; - if (bn2crparam(dsa->p, &kop.crk_param[1])) - goto err; - if (bn2crparam(dsa->q, &kop.crk_param[2])) - goto err; - if (bn2crparam(dsa->g, &kop.crk_param[3])) - goto err; - if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) - goto err; - if (bn2crparam(sig->r, &kop.crk_param[5])) - goto err; - if (bn2crparam(sig->s, &kop.crk_param[6])) - goto err; - kop.crk_iparams = 7; - - if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { - /* - * OCF success value is 0, if not zero, change dsaret to fail - */ - if (0 != kop.crk_status) - dsaret = 0; - } else { - const DSA_METHOD *meth = DSA_OpenSSL(); - - dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa); - } - err: - kop.crk_param[0].crp_p = NULL; - zapparams(&kop); - return (dsaret); -} - -static DSA_METHOD cryptodev_dsa = { - "cryptodev DSA method", - NULL, - NULL, /* dsa_sign_setup */ - NULL, - NULL, /* dsa_mod_exp */ - NULL, - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL /* app_data */ -}; - -static int -cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) -{ - return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); -} - -static int -cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) -{ - struct crypt_kop kop; - int dhret = 1; - int fd, keylen; - - if ((fd = get_asym_dev_crypto()) < 0) { - const DH_METHOD *meth = DH_OpenSSL(); - - return ((meth->compute_key) (key, pub_key, dh)); - } - - keylen = BN_num_bits(dh->p); - - memset(&kop, 0, sizeof(kop)); - kop.crk_op = CRK_DH_COMPUTE_KEY; - - /* inputs: dh->priv_key pub_key dh->p key */ - if (bn2crparam(dh->priv_key, &kop.crk_param[0])) - goto err; - if (bn2crparam(pub_key, &kop.crk_param[1])) - goto err; - if (bn2crparam(dh->p, &kop.crk_param[2])) - goto err; - kop.crk_iparams = 3; - - kop.crk_param[3].crp_p = (caddr_t) key; - kop.crk_param[3].crp_nbits = keylen * 8; - kop.crk_oparams = 1; - - if (ioctl(fd, CIOCKEY, &kop) == -1) { - const DH_METHOD *meth = DH_OpenSSL(); - - dhret = (meth->compute_key) (key, pub_key, dh); - } - err: - kop.crk_param[3].crp_p = NULL; - zapparams(&kop); - return (dhret); -} - -static DH_METHOD cryptodev_dh = { - "cryptodev DH method", - NULL, /* cryptodev_dh_generate_key */ - NULL, - NULL, - NULL, - NULL, - 0, /* flags */ - NULL /* app_data */ -}; - -/* - * ctrl right now is just a wrapper that doesn't do much - * but I expect we'll want some options soon. - */ -static int -cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ -# ifdef HAVE_SYSLOG_R - struct syslog_data sd = SYSLOG_DATA_INIT; -# endif - - switch (cmd) { - default: -# ifdef HAVE_SYSLOG_R - syslog_r(LOG_ERR, &sd, "cryptodev_ctrl: unknown command %d", cmd); -# else - syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd); -# endif - break; - } - return (1); -} - -void ENGINE_load_cryptodev(void) -{ - ENGINE *engine = ENGINE_new(); - int fd; - - if (engine == NULL) - return; - if ((fd = get_dev_crypto()) < 0) { - ENGINE_free(engine); - return; - } - - /* - * find out what asymmetric crypto algorithms we support - */ - if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { - put_dev_crypto(fd); - ENGINE_free(engine); - return; - } - put_dev_crypto(fd); - - if (!ENGINE_set_id(engine, "cryptodev") || - !ENGINE_set_name(engine, "BSD cryptodev engine") || - !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || - !ENGINE_set_digests(engine, cryptodev_engine_digests) || - !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || - !ENGINE_set_cmd_defns(engine, cryptodev_defns)) { - ENGINE_free(engine); - return; - } - - if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { - const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); - - cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; - cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; - cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; - cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; - cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; - cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; - if (cryptodev_asymfeat & CRF_MOD_EXP) { - cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; - if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) - cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_mod_exp; - else - cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_nocrt_mod_exp; - } - } - - if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { - const DSA_METHOD *meth = DSA_OpenSSL(); - - memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); - if (cryptodev_asymfeat & CRF_DSA_SIGN) - cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; - if (cryptodev_asymfeat & CRF_MOD_EXP) { - cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; - cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; - } - if (cryptodev_asymfeat & CRF_DSA_VERIFY) - cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; - } - - if (ENGINE_set_DH(engine, &cryptodev_dh)) { - const DH_METHOD *dh_meth = DH_OpenSSL(); - - cryptodev_dh.generate_key = dh_meth->generate_key; - cryptodev_dh.compute_key = dh_meth->compute_key; - cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; - if (cryptodev_asymfeat & CRF_MOD_EXP) { - cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; - if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) - cryptodev_dh.compute_key = cryptodev_dh_compute_key; - } - } - - ENGINE_add(engine); - ENGINE_free(engine); - ERR_clear_error(); -} - -#endif /* HAVE_CRYPTODEV */ -/* crypto/engine/eng_ctrl.c */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "eng_int.h" - -/* - * When querying a ENGINE-specific control command's 'description', this - * string is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. - */ -static const char *int_no_description = ""; - -/* - * These internal functions handle 'CMD'-related control commands when the - * ENGINE in question has asked us to take care of it (ie. the ENGINE did not - * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. - */ - -static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn) -{ - if ((defn->cmd_num == 0) || (defn->cmd_name == NULL)) - return 1; - return 0; -} - -static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s) -{ - int idx = 0; - while (!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0)) { - idx++; - defn++; - } - if (int_ctrl_cmd_is_null(defn)) - /* The given name wasn't found */ - return -1; - return idx; -} - -static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num) -{ - int idx = 0; - /* - * NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So - * our searches don't need to take any longer than necessary. - */ - while (!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) { - idx++; - defn++; - } - if (defn->cmd_num == num) - return idx; - /* The given cmd_num wasn't found */ - return -1; -} - -static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, - void (*f) (void)) -{ - int idx; - char *s = (char *)p; - /* Take care of the easy one first (eg. it requires no searches) */ - if (cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) { - if ((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns)) - return 0; - return e->cmd_defns->cmd_num; - } - /* One or two commands require that "p" be a valid string buffer */ - if ((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) || - (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) || - (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) { - if (s == NULL) { - ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ERR_R_PASSED_NULL_PARAMETER); - return -1; - } - } - /* Now handle cmd_name -> cmd_num conversion */ - if (cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) { - if ((e->cmd_defns == NULL) - || ((idx = int_ctrl_cmd_by_name(e->cmd_defns, s)) < 0)) { - ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NAME); - return -1; - } - return e->cmd_defns[idx].cmd_num; - } - /* - * For the rest of the commands, the 'long' argument must specify a valie - * command number - so we need to conduct a search. - */ - if ((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns, - (unsigned int) - i)) < 0)) { - ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NUMBER); - return -1; - } - /* Now the logic splits depending on command type */ - switch (cmd) { - case ENGINE_CTRL_GET_NEXT_CMD_TYPE: - idx++; - if (int_ctrl_cmd_is_null(e->cmd_defns + idx)) - /* end-of-list */ - return 0; - else - return e->cmd_defns[idx].cmd_num; - case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: - return strlen(e->cmd_defns[idx].cmd_name); - case ENGINE_CTRL_GET_NAME_FROM_CMD: - return BIO_snprintf(s, strlen(e->cmd_defns[idx].cmd_name) + 1, - "%s", e->cmd_defns[idx].cmd_name); - case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: - if (e->cmd_defns[idx].cmd_desc) - return strlen(e->cmd_defns[idx].cmd_desc); - return strlen(int_no_description); - case ENGINE_CTRL_GET_DESC_FROM_CMD: - if (e->cmd_defns[idx].cmd_desc) - return BIO_snprintf(s, - strlen(e->cmd_defns[idx].cmd_desc) + 1, - "%s", e->cmd_defns[idx].cmd_desc); - return BIO_snprintf(s, strlen(int_no_description) + 1, "%s", - int_no_description); - case ENGINE_CTRL_GET_CMD_FLAGS: - return e->cmd_defns[idx].cmd_flags; - } - /* Shouldn't really be here ... */ - ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INTERNAL_LIST_ERROR); - return -1; -} - -int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int ctrl_exists, ref_exists; - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - ref_exists = ((e->struct_ref > 0) ? 1 : 0); - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); - if (!ref_exists) { - ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_REFERENCE); - return 0; - } - /* - * Intercept any "root-level" commands before trying to hand them on to - * ctrl() handlers. - */ - switch (cmd) { - case ENGINE_CTRL_HAS_CTRL_FUNCTION: - return ctrl_exists; - case ENGINE_CTRL_GET_FIRST_CMD_TYPE: - case ENGINE_CTRL_GET_NEXT_CMD_TYPE: - case ENGINE_CTRL_GET_CMD_FROM_NAME: - case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: - case ENGINE_CTRL_GET_NAME_FROM_CMD: - case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: - case ENGINE_CTRL_GET_DESC_FROM_CMD: - case ENGINE_CTRL_GET_CMD_FLAGS: - if (ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL)) - return int_ctrl_helper(e, cmd, i, p, f); - if (!ctrl_exists) { - ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION); - /* - * For these cmd-related functions, failure is indicated by a -1 - * return value (because 0 is used as a valid return in some - * places). - */ - return -1; - } - default: - break; - } - /* Anything else requires a ctrl() handler to exist. */ - if (!ctrl_exists) { - ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION); - return 0; - } - return e->ctrl(e, cmd, i, p, f); -} - -int ENGINE_cmd_is_executable(ENGINE *e, int cmd) -{ - int flags; - if ((flags = - ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) { - ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, - ENGINE_R_INVALID_CMD_NUMBER); - return 0; - } - if (!(flags & ENGINE_CMD_FLAG_NO_INPUT) && - !(flags & ENGINE_CMD_FLAG_NUMERIC) && - !(flags & ENGINE_CMD_FLAG_STRING)) - return 0; - return 1; -} - -int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, - long i, void *p, void (*f) (void), int cmd_optional) -{ - int num; - - if ((e == NULL) || (cmd_name == NULL)) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if ((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, - ENGINE_CTRL_GET_CMD_FROM_NAME, - 0, (void *)cmd_name, - NULL)) <= 0)) { - /* - * If the command didn't *have* to be supported, we fake success. - * This allows certain settings to be specified for multiple ENGINEs - * and only require a change of ENGINE id (without having to - * selectively apply settings). Eg. changing from a hardware device - * back to the regular software ENGINE without editing the config - * file, etc. - */ - if (cmd_optional) { - ERR_clear_error(); - return 1; - } - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ENGINE_R_INVALID_CMD_NAME); - return 0; - } - /* - * Force the result of the control command to 0 or 1, for the reasons - * mentioned before. - */ - if (ENGINE_ctrl(e, num, i, p, f) > 0) - return 1; - return 0; -} - -int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, - int cmd_optional) -{ - int num, flags; - long l; - char *ptr; - if ((e == NULL) || (cmd_name == NULL)) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if ((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, - ENGINE_CTRL_GET_CMD_FROM_NAME, - 0, (void *)cmd_name, - NULL)) <= 0)) { - /* - * If the command didn't *have* to be supported, we fake success. - * This allows certain settings to be specified for multiple ENGINEs - * and only require a change of ENGINE id (without having to - * selectively apply settings). Eg. changing from a hardware device - * back to the regular software ENGINE without editing the config - * file, etc. - */ - if (cmd_optional) { - ERR_clear_error(); - return 1; - } - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ENGINE_R_INVALID_CMD_NAME); - return 0; - } - if (!ENGINE_cmd_is_executable(e, num)) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_CMD_NOT_EXECUTABLE); - return 0; - } - if ((flags = - ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0) { - /* - * Shouldn't happen, given that ENGINE_cmd_is_executable() returned - * success. - */ - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_INTERNAL_LIST_ERROR); - return 0; - } - /* - * If the command takes no input, there must be no input. And vice versa. - */ - if (flags & ENGINE_CMD_FLAG_NO_INPUT) { - if (arg != NULL) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_COMMAND_TAKES_NO_INPUT); - return 0; - } - /* - * We deliberately force the result of ENGINE_ctrl() to 0 or 1 rather - * than returning it as "return data". This is to ensure usage of - * these commands is consistent across applications and that certain - * applications don't understand it one way, and others another. - */ - if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0) - return 1; - return 0; - } - /* So, we require input */ - if (arg == NULL) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_COMMAND_TAKES_INPUT); - return 0; - } - /* If it takes string input, that's easy */ - if (flags & ENGINE_CMD_FLAG_STRING) { - /* Same explanation as above */ - if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0) - return 1; - return 0; - } - /* - * If it doesn't take numeric either, then it is unsupported for use in a - * config-setting situation, which is what this function is for. This - * should never happen though, because ENGINE_cmd_is_executable() was - * used. - */ - if (!(flags & ENGINE_CMD_FLAG_NUMERIC)) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_INTERNAL_LIST_ERROR); - return 0; - } - l = strtol(arg, &ptr, 10); - if ((arg == ptr) || (*ptr != '\0')) { - ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, - ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); - return 0; - } - /* - * Force the result of the control command to 0 or 1, for the reasons - * mentioned before. - */ - if (ENGINE_ctrl(e, num, l, NULL, NULL) > 0) - return 1; - return 0; -} -/* crypto/engine/eng_dyn.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "eng_int.h" -#include "dso.h" - -/* - * Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE - * loader should implement the hook-up functions with the following - * prototypes. - */ - -/* Our ENGINE handlers */ -static int dynamic_init(ENGINE *e); -static int dynamic_finish(ENGINE *e); -static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, - void (*f) (void)); -/* Predeclare our context type */ -typedef struct st_dynamic_data_ctx dynamic_data_ctx; -/* The implementation for the important control command */ -static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx); - -#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE -#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) -#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) -#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) -#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4) -#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5) -#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6) - -/* The constants used when creating the ENGINE */ -static const char *engine_dynamic_id = "dynamic"; -static const char *engine_dynamic_name = "Dynamic engine loading support"; -static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = { - {DYNAMIC_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the new ENGINE shared library", - ENGINE_CMD_FLAG_STRING}, - {DYNAMIC_CMD_NO_VCHECK, - "NO_VCHECK", - "Specifies to continue even if version checking fails (boolean)", - ENGINE_CMD_FLAG_NUMERIC}, - {DYNAMIC_CMD_ID, - "ID", - "Specifies an ENGINE id name for loading", - ENGINE_CMD_FLAG_STRING}, - {DYNAMIC_CMD_LIST_ADD, - "LIST_ADD", - "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", - ENGINE_CMD_FLAG_NUMERIC}, - {DYNAMIC_CMD_DIR_LOAD, - "DIR_LOAD", - "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)", - ENGINE_CMD_FLAG_NUMERIC}, - {DYNAMIC_CMD_DIR_ADD, - "DIR_ADD", - "Adds a directory from which ENGINEs can be loaded", - ENGINE_CMD_FLAG_STRING}, - {DYNAMIC_CMD_LOAD, - "LOAD", - "Load up the ENGINE specified by other settings", - ENGINE_CMD_FLAG_NO_INPUT}, - {0, NULL, NULL, 0} -}; - -/* - * Loading code stores state inside the ENGINE structure via the "ex_data" - * element. We load all our state into a single structure and use that as a - * single context in the "ex_data" stack. - */ -struct st_dynamic_data_ctx { - /* The DSO object we load that supplies the ENGINE code */ - DSO *dynamic_dso; - /* - * The function pointer to the version checking shared library function - */ - dynamic_v_check_fn v_check; - /* - * The function pointer to the engine-binding shared library function - */ - dynamic_bind_engine bind_engine; - /* The default name/path for loading the shared library */ - const char *DYNAMIC_LIBNAME; - /* Whether to continue loading on a version check failure */ - int no_vcheck; - /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */ - const char *engine_id; - /* - * If non-zero, a successfully loaded ENGINE should be added to the - * internal ENGINE list. If 2, the add must succeed or the entire load - * should fail. - */ - int list_add_value; - /* The symbol name for the version checking function */ - const char *DYNAMIC_F1; - /* The symbol name for the "initialise ENGINE structure" function */ - const char *DYNAMIC_F2; - /* - * Whether to never use 'dirs', use 'dirs' as a fallback, or only use - * 'dirs' for loading. Default is to use 'dirs' as a fallback. - */ - int dir_load; - /* A stack of directories from which ENGINEs could be loaded */ - STACK_OF(OPENSSL_STRING) *dirs; -}; - -/* - * This is the "ex_data" index we obtain and reserve for use with our context - * structure. - */ -static int dynamic_ex_data_idx = -1; - -static void int_free_str(char *s) -{ - OPENSSL_free(s); -} - -/* - * Because our ex_data element may or may not get allocated depending on - * whether a "first-use" occurs before the ENGINE is freed, we have a memory - * leak problem to solve. We can't declare a "new" handler for the ex_data as - * we don't want a dynamic_data_ctx in *all* ENGINE structures of all types - * (this is a bug in the design of CRYPTO_EX_DATA). As such, we just declare - * a "free" handler and that will get called if an ENGINE is being destroyed - * and there was an ex_data element corresponding to our context type. - */ -static void dynamic_data_ctx_free_func(void *parent, void *ptr, - CRYPTO_EX_DATA *ad, int idx, long argl, - void *argp) -{ - if (ptr) { - dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr; - if (ctx->dynamic_dso) - DSO_free(ctx->dynamic_dso); - if (ctx->DYNAMIC_LIBNAME) - OPENSSL_free((void *)ctx->DYNAMIC_LIBNAME); - if (ctx->engine_id) - OPENSSL_free((void *)ctx->engine_id); - if (ctx->dirs) - sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str); - OPENSSL_free(ctx); - } -} - -/* - * Construct the per-ENGINE context. We create it blindly and then use a lock - * to check for a race - if so, all but one of the threads "racing" will have - * wasted their time. The alternative involves creating everything inside the - * lock which is far worse. - */ -static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) -{ - dynamic_data_ctx *c; - c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); - if (!c) { - ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); - return 0; - } - memset(c, 0, sizeof(dynamic_data_ctx)); - c->dynamic_dso = NULL; - c->v_check = NULL; - c->bind_engine = NULL; - c->DYNAMIC_LIBNAME = NULL; - c->no_vcheck = 0; - c->engine_id = NULL; - c->list_add_value = 0; - c->DYNAMIC_F1 = "v_check"; - c->DYNAMIC_F2 = "bind_engine"; - c->dir_load = 1; - c->dirs = sk_OPENSSL_STRING_new_null(); - if (!c->dirs) { - ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); - OPENSSL_free(c); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, - dynamic_ex_data_idx)) - == NULL) { - /* Good, we're the first */ - ENGINE_set_ex_data(e, dynamic_ex_data_idx, c); - *ctx = c; - c = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - /* - * If we lost the race to set the context, c is non-NULL and *ctx is the - * context of the thread that won. - */ - if (c) { - sk_OPENSSL_STRING_free(c->dirs); - OPENSSL_free(c); - } - return 1; -} - -/* - * This function retrieves the context structure from an ENGINE's "ex_data", - * or if it doesn't exist yet, sets it up. - */ -static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e) -{ - dynamic_data_ctx *ctx; - if (dynamic_ex_data_idx < 0) { - /* - * Create and register the ENGINE ex_data, and associate our "free" - * function with it to ensure any allocated contexts get freed when - * an ENGINE goes underground. - */ - int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, - dynamic_data_ctx_free_func); - if (new_idx == -1) { - ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX, ENGINE_R_NO_INDEX); - return NULL; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - /* Avoid a race by checking again inside this lock */ - if (dynamic_ex_data_idx < 0) { - /* Good, someone didn't beat us to it */ - dynamic_ex_data_idx = new_idx; - new_idx = -1; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - /* - * In theory we could "give back" the index here if (new_idx>-1), but - * it's not possible and wouldn't gain us much if it were. - */ - } - ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx); - /* Check if the context needs to be created */ - if ((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx)) - /* "set_data" will set errors if necessary */ - return NULL; - return ctx; -} - -static ENGINE *engine_dynamic(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!ENGINE_set_id(ret, engine_dynamic_id) || - !ENGINE_set_name(ret, engine_dynamic_name) || - !ENGINE_set_init_function(ret, dynamic_init) || - !ENGINE_set_finish_function(ret, dynamic_finish) || - !ENGINE_set_ctrl_function(ret, dynamic_ctrl) || - !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) || - !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_dynamic(void) -{ - ENGINE *toadd = engine_dynamic(); - if (!toadd) - return; - ENGINE_add(toadd); - /* - * If the "add" worked, it gets a structural reference. So either way, we - * release our just-created reference. - */ - ENGINE_free(toadd); - /* - * If the "add" didn't work, it was probably a conflict because it was - * already added (eg. someone calling ENGINE_load_blah then calling - * ENGINE_load_builtin_engines() perhaps). - */ - ERR_clear_error(); -} - -static int dynamic_init(ENGINE *e) -{ - /* - * We always return failure - the "dyanamic" engine itself can't be used - * for anything. - */ - return 0; -} - -static int dynamic_finish(ENGINE *e) -{ - /* - * This should never be called on account of "dynamic_init" always - * failing. - */ - return 0; -} - -static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); - int initialised; - - if (!ctx) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_NOT_LOADED); - return 0; - } - initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1); - /* All our control commands require the ENGINE to be uninitialised */ - if (initialised) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_ALREADY_LOADED); - return 0; - } - switch (cmd) { - case DYNAMIC_CMD_SO_PATH: - /* a NULL 'p' or a string of zero-length is the same thing */ - if (p && (strlen((const char *)p) < 1)) - p = NULL; - if (ctx->DYNAMIC_LIBNAME) - OPENSSL_free((void *)ctx->DYNAMIC_LIBNAME); - if (p) - ctx->DYNAMIC_LIBNAME = BUF_strdup(p); - else - ctx->DYNAMIC_LIBNAME = NULL; - return (ctx->DYNAMIC_LIBNAME ? 1 : 0); - case DYNAMIC_CMD_NO_VCHECK: - ctx->no_vcheck = ((i == 0) ? 0 : 1); - return 1; - case DYNAMIC_CMD_ID: - /* a NULL 'p' or a string of zero-length is the same thing */ - if (p && (strlen((const char *)p) < 1)) - p = NULL; - if (ctx->engine_id) - OPENSSL_free((void *)ctx->engine_id); - if (p) - ctx->engine_id = BUF_strdup(p); - else - ctx->engine_id = NULL; - return (ctx->engine_id ? 1 : 0); - case DYNAMIC_CMD_LIST_ADD: - if ((i < 0) || (i > 2)) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); - return 0; - } - ctx->list_add_value = (int)i; - return 1; - case DYNAMIC_CMD_LOAD: - return dynamic_load(e, ctx); - case DYNAMIC_CMD_DIR_LOAD: - if ((i < 0) || (i > 2)) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); - return 0; - } - ctx->dir_load = (int)i; - return 1; - case DYNAMIC_CMD_DIR_ADD: - /* a NULL 'p' or a string of zero-length is the same thing */ - if (!p || (strlen((const char *)p) < 1)) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); - return 0; - } - { - char *tmp_str = BUF_strdup(p); - if (!tmp_str) { - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE); - return 0; - } - sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1); - } - return 1; - default: - break; - } - ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); - return 0; -} - -static int int_load(dynamic_data_ctx *ctx) -{ - int num, loop; - /* Unless told not to, try a direct load */ - if ((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso, - ctx->DYNAMIC_LIBNAME, NULL, - 0)) != NULL) - return 1; - /* If we're not allowed to use 'dirs' or we have none, fail */ - if (!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1) - return 0; - for (loop = 0; loop < num; loop++) { - const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop); - char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s); - if (!merge) - return 0; - if (DSO_load(ctx->dynamic_dso, merge, NULL, 0)) { - /* Found what we're looking for */ - OPENSSL_free(merge); - return 1; - } - OPENSSL_free(merge); - } - return 0; -} - -static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) -{ - ENGINE cpy; - dynamic_fns fns; - - if (!ctx->dynamic_dso) - ctx->dynamic_dso = DSO_new(); - if (!ctx->DYNAMIC_LIBNAME) { - if (!ctx->engine_id) - return 0; - ctx->DYNAMIC_LIBNAME = - DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id); - } - if (!int_load(ctx)) { - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_NOT_FOUND); - DSO_free(ctx->dynamic_dso); - ctx->dynamic_dso = NULL; - return 0; - } - /* We have to find a bind function otherwise it'll always end badly */ - if (! - (ctx->bind_engine = - (dynamic_bind_engine) DSO_bind_func(ctx->dynamic_dso, - ctx->DYNAMIC_F2))) { - ctx->bind_engine = NULL; - DSO_free(ctx->dynamic_dso); - ctx->dynamic_dso = NULL; - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_FAILURE); - return 0; - } - /* Do we perform version checking? */ - if (!ctx->no_vcheck) { - unsigned long vcheck_res = 0; - /* - * Now we try to find a version checking function and decide how to - * cope with failure if/when it fails. - */ - ctx->v_check = - (dynamic_v_check_fn) DSO_bind_func(ctx->dynamic_dso, - ctx->DYNAMIC_F1); - if (ctx->v_check) - vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION); - /* - * We fail if the version checker veto'd the load *or* if it is - * deferring to us (by returning its version) and we think it is too - * old. - */ - if (vcheck_res < OSSL_DYNAMIC_OLDEST) { - /* Fail */ - ctx->bind_engine = NULL; - ctx->v_check = NULL; - DSO_free(ctx->dynamic_dso); - ctx->dynamic_dso = NULL; - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, - ENGINE_R_VERSION_INCOMPATIBILITY); - return 0; - } - } - /* - * First binary copy the ENGINE structure so that we can roll back if the - * hand-over fails - */ - memcpy(&cpy, e, sizeof(ENGINE)); - /* - * Provide the ERR, "ex_data", memory, and locking callbacks so the - * loaded library uses our state rather than its own. FIXME: As noted in - * engine.h, much of this would be simplified if each area of code - * provided its own "summary" structure of all related callbacks. It - * would also increase opaqueness. - */ - fns.static_state = ENGINE_get_static_state(); - fns.err_fns = ERR_get_implementation(); - fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); - CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, - &fns.mem_fns.realloc_cb, &fns.mem_fns.free_cb); - fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback(); - fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback(); - fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback(); - fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback(); - fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback(); - /* - * Now that we've loaded the dynamic engine, make sure no "dynamic" - * ENGINE elements will show through. - */ - engine_set_all_null(e); - - /* Try to bind the ENGINE onto our own ENGINE structure */ - if (!ctx->bind_engine(e, ctx->engine_id, &fns)) { - ctx->bind_engine = NULL; - ctx->v_check = NULL; - DSO_free(ctx->dynamic_dso); - ctx->dynamic_dso = NULL; - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED); - /* Copy the original ENGINE structure back */ - memcpy(e, &cpy, sizeof(ENGINE)); - return 0; - } - /* Do we try to add this ENGINE to the internal list too? */ - if (ctx->list_add_value > 0) { - if (!ENGINE_add(e)) { - /* Do we tolerate this or fail? */ - if (ctx->list_add_value > 1) { - /* - * Fail - NB: By this time, it's too late to rollback, and - * trying to do so allows the bind_engine() code to have - * created leaks. We just have to fail where we are, after - * the ENGINE has changed. - */ - ENGINEerr(ENGINE_F_DYNAMIC_LOAD, - ENGINE_R_CONFLICTING_ENGINE_ID); - return 0; - } - /* Tolerate */ - ERR_clear_error(); - } - } - return 1; -} -/* crypto/engine/eng_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "engine.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason) - -static ERR_STRING_DATA ENGINE_str_functs[] = { - {ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"}, - {ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"}, - {ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"}, - {ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "DYNAMIC_SET_DATA_CTX"}, - {ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"}, - {ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"}, - {ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"}, - {ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"}, - {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"}, - {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"}, - {ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"}, - {ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL), "ENGINE_FREE_UTIL"}, - {ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"}, - {ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"}, - {ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"}, - {ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"}, - {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), - "ENGINE_get_pkey_asn1_meth"}, - {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"}, - {ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"}, - {ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"}, - {ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"}, - {ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"}, - {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"}, - {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"}, - {ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT), - "ENGINE_load_ssl_client_cert"}, - {ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"}, - {ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"}, - {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), - "ENGINE_set_default_string"}, - {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE), "ENGINE_SET_DEFAULT_TYPE"}, - {ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"}, - {ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"}, - {ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"}, - {ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"}, - {ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "ENGINE_UNLOCKED_FINISH"}, - {ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"}, - {ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"}, - {ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"}, - {ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "INT_ENGINE_MODULE_INIT"}, - {ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"}, - {0, NULL} -}; - -static ERR_STRING_DATA ENGINE_str_reasons[] = { - {ERR_REASON(ENGINE_R_ALREADY_LOADED), "already loaded"}, - {ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER), - "argument is not a number"}, - {ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE), "cmd not executable"}, - {ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT), "command takes input"}, - {ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT), "command takes no input"}, - {ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID), "conflicting engine id"}, - {ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED), - "ctrl command not implemented"}, - {ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED), "dh not implemented"}, - {ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED), "dsa not implemented"}, - {ERR_REASON(ENGINE_R_DSO_FAILURE), "DSO failure"}, - {ERR_REASON(ENGINE_R_DSO_NOT_FOUND), "dso not found"}, - {ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR), "engines section error"}, - {ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR), - "engine configuration error"}, - {ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST), "engine is not in the list"}, - {ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR), "engine section error"}, - {ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY), - "failed loading private key"}, - {ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY), - "failed loading public key"}, - {ERR_REASON(ENGINE_R_FINISH_FAILED), "finish failed"}, - {ERR_REASON(ENGINE_R_GET_HANDLE_FAILED), - "could not obtain hardware handle"}, - {ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING), "'id' or 'name' missing"}, - {ERR_REASON(ENGINE_R_INIT_FAILED), "init failed"}, - {ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR), "internal list error"}, - {ERR_REASON(ENGINE_R_INVALID_ARGUMENT), "invalid argument"}, - {ERR_REASON(ENGINE_R_INVALID_CMD_NAME), "invalid cmd name"}, - {ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER), "invalid cmd number"}, - {ERR_REASON(ENGINE_R_INVALID_INIT_VALUE), "invalid init value"}, - {ERR_REASON(ENGINE_R_INVALID_STRING), "invalid string"}, - {ERR_REASON(ENGINE_R_NOT_INITIALISED), "not initialised"}, - {ERR_REASON(ENGINE_R_NOT_LOADED), "not loaded"}, - {ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION), "no control function"}, - {ERR_REASON(ENGINE_R_NO_INDEX), "no index"}, - {ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION), "no load function"}, - {ERR_REASON(ENGINE_R_NO_REFERENCE), "no reference"}, - {ERR_REASON(ENGINE_R_NO_SUCH_ENGINE), "no such engine"}, - {ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION), "no unload function"}, - {ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS), "provide parameters"}, - {ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED), "rsa not implemented"}, - {ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER), "unimplemented cipher"}, - {ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST), "unimplemented digest"}, - {ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD), - "unimplemented public key method"}, - {ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY), "version incompatibility"}, - {0, NULL} -}; - -#endif - -void ERR_load_ENGINE_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) { - ERR_load_strings(0, ENGINE_str_functs); - ERR_load_strings(0, ENGINE_str_reasons); - } -#endif -} -/* crypto/engine/eng_fat.c */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -// #include "eng_int.h" -// #include "conf.h" - -int ENGINE_set_default(ENGINE *e, unsigned int flags) -{ - if ((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e)) - return 0; - if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) - return 0; -#ifndef OPENSSL_NO_RSA - if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e)) - return 0; -#endif -#ifndef OPENSSL_NO_DSA - if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e)) - return 0; -#endif -#ifndef OPENSSL_NO_DH - if ((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e)) - return 0; -#endif -#ifndef OPENSSL_NO_ECDH - if ((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e)) - return 0; -#endif -#ifndef OPENSSL_NO_ECDSA - if ((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e)) - return 0; -#endif - if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) - return 0; - if ((flags & ENGINE_METHOD_PKEY_METHS) - && !ENGINE_set_default_pkey_meths(e)) - return 0; - if ((flags & ENGINE_METHOD_PKEY_ASN1_METHS) - && !ENGINE_set_default_pkey_asn1_meths(e)) - return 0; - return 1; -} - -/* Set default algorithms using a string */ - -static int int_def_cb(const char *alg, int len, void *arg) -{ - unsigned int *pflags = arg; - if (alg == NULL) - return 0; - if (!strncmp(alg, "ALL", len)) - *pflags |= ENGINE_METHOD_ALL; - else if (!strncmp(alg, "RSA", len)) - *pflags |= ENGINE_METHOD_RSA; - else if (!strncmp(alg, "DSA", len)) - *pflags |= ENGINE_METHOD_DSA; - else if (!strncmp(alg, "ECDH", len)) - *pflags |= ENGINE_METHOD_ECDH; - else if (!strncmp(alg, "ECDSA", len)) - *pflags |= ENGINE_METHOD_ECDSA; - else if (!strncmp(alg, "DH", len)) - *pflags |= ENGINE_METHOD_DH; - else if (!strncmp(alg, "RAND", len)) - *pflags |= ENGINE_METHOD_RAND; - else if (!strncmp(alg, "CIPHERS", len)) - *pflags |= ENGINE_METHOD_CIPHERS; - else if (!strncmp(alg, "DIGESTS", len)) - *pflags |= ENGINE_METHOD_DIGESTS; - else if (!strncmp(alg, "PKEY", len)) - *pflags |= ENGINE_METHOD_PKEY_METHS | ENGINE_METHOD_PKEY_ASN1_METHS; - else if (!strncmp(alg, "PKEY_CRYPTO", len)) - *pflags |= ENGINE_METHOD_PKEY_METHS; - else if (!strncmp(alg, "PKEY_ASN1", len)) - *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS; - else - return 0; - return 1; -} - -int ENGINE_set_default_string(ENGINE *e, const char *def_list) -{ - unsigned int flags = 0; - if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags)) { - ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING, - ENGINE_R_INVALID_STRING); - ERR_add_error_data(2, "str=", def_list); - return 0; - } - return ENGINE_set_default(e, flags); -} - -int ENGINE_register_complete(ENGINE *e) -{ - ENGINE_register_ciphers(e); - ENGINE_register_digests(e); -#ifndef OPENSSL_NO_RSA - ENGINE_register_RSA(e); -#endif -#ifndef OPENSSL_NO_DSA - ENGINE_register_DSA(e); -#endif -#ifndef OPENSSL_NO_DH - ENGINE_register_DH(e); -#endif -#ifndef OPENSSL_NO_ECDH - ENGINE_register_ECDH(e); -#endif -#ifndef OPENSSL_NO_ECDSA - ENGINE_register_ECDSA(e); -#endif - ENGINE_register_RAND(e); - ENGINE_register_pkey_meths(e); - ENGINE_register_pkey_asn1_meths(e); - return 1; -} - -int ENGINE_register_all_complete(void) -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL)) - ENGINE_register_complete(e); - return 1; -} -/* crypto/engine/eng_init.c */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "eng_int.h" - -/* - * Initialise a engine type for use (or up its functional reference count if - * it's already in use). This version is only used internally. - */ -int engine_unlocked_init(ENGINE *e) -{ - int to_return = 1; - - if ((e->funct_ref == 0) && e->init) - /* - * This is the first functional reference and the engine requires - * initialisation so we do it now. - */ - to_return = e->init(e); - if (to_return) { - /* - * OK, we return a functional reference which is also a structural - * reference. - */ - e->struct_ref++; - e->funct_ref++; - engine_ref_debug(e, 0, 1) - engine_ref_debug(e, 1, 1) - } - return to_return; -} - -/* - * Free a functional reference to a engine type. This version is only used - * internally. - */ -int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers) -{ - int to_return = 1; - - /* - * Reduce the functional reference count here so if it's the terminating - * case, we can release the lock safely and call the finish() handler - * without risk of a race. We get a race if we leave the count until - * after and something else is calling "finish" at the same time - - * there's a chance that both threads will together take the count from 2 - * to 0 without either calling finish(). - */ - e->funct_ref--; - engine_ref_debug(e, 1, -1); - if ((e->funct_ref == 0) && e->finish) { - if (unlock_for_handlers) - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - to_return = e->finish(e); - if (unlock_for_handlers) - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (!to_return) - return 0; - } -#ifdef REF_CHECK - if (e->funct_ref < 0) { - fprintf(stderr, "ENGINE_finish, bad functional reference count\n"); - abort(); - } -#endif - /* Release the structural reference too */ - if (!engine_free_util(e, 0)) { - ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH, ENGINE_R_FINISH_FAILED); - return 0; - } - return to_return; -} - -/* The API (locked) version of "init" */ -int ENGINE_init(ENGINE *e) -{ - int ret; - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - ret = engine_unlocked_init(e); - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return ret; -} - -/* The API (locked) version of "finish" */ -int ENGINE_finish(ENGINE *e) -{ - int to_return = 1; - - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_FINISH, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - to_return = engine_unlocked_finish(e, 1); - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - if (!to_return) { - ENGINEerr(ENGINE_F_ENGINE_FINISH, ENGINE_R_FINISH_FAILED); - return 0; - } - return to_return; -} -/* crypto/engine/eng_lib.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "eng_int.h" -#include "rand.h" - -/* The "new"/"free" stuff first */ - -ENGINE *ENGINE_new(void) -{ - ENGINE *ret; - - ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE)); - if (ret == NULL) { - ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - memset(ret, 0, sizeof(ENGINE)); - ret->struct_ref = 1; - engine_ref_debug(ret, 0, 1) - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data); - return ret; -} - -/* - * Placed here (close proximity to ENGINE_new) so that modifications to the - * elements of the ENGINE structure are more likely to be caught and changed - * here. - */ -void engine_set_all_null(ENGINE *e) -{ - e->id = NULL; - e->name = NULL; - e->rsa_meth = NULL; - e->dsa_meth = NULL; - e->dh_meth = NULL; - e->rand_meth = NULL; - e->store_meth = NULL; - e->ciphers = NULL; - e->digests = NULL; - e->destroy = NULL; - e->init = NULL; - e->finish = NULL; - e->ctrl = NULL; - e->load_privkey = NULL; - e->load_pubkey = NULL; - e->cmd_defns = NULL; - e->flags = 0; -} - -int engine_free_util(ENGINE *e, int locked) -{ - int i; - - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (locked) - i = CRYPTO_add(&e->struct_ref, -1, CRYPTO_LOCK_ENGINE); - else - i = --e->struct_ref; - engine_ref_debug(e, 0, -1) - if (i > 0) - return 1; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "ENGINE_free, bad structural reference count\n"); - abort(); - } -#endif - /* Free up any dynamically allocated public key methods */ - engine_pkey_meths_free(e); - engine_pkey_asn1_meths_free(e); - /* - * Give the ENGINE a chance to do any structural cleanup corresponding to - * allocation it did in its constructor (eg. unload error strings) - */ - if (e->destroy) - e->destroy(e); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data); - OPENSSL_free(e); - return 1; -} - -int ENGINE_free(ENGINE *e) -{ - return engine_free_util(e, 1); -} - -/* Cleanup stuff */ - -/* - * ENGINE_cleanup() is coded such that anything that does work that will need - * cleanup can register a "cleanup" callback here. That way we don't get - * linker bloat by referring to all *possible* cleanups, but any linker bloat - * into code "X" will cause X's cleanup function to end up here. - */ -static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL; -static int int_cleanup_check(int create) -{ - if (cleanup_stack) - return 1; - if (!create) - return 0; - cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null(); - return (cleanup_stack ? 1 : 0); -} - -static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb) -{ - ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(ENGINE_CLEANUP_ITEM)); - if (!item) - return NULL; - item->cb = cb; - return item; -} - -void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb) -{ - ENGINE_CLEANUP_ITEM *item; - if (!int_cleanup_check(1)) - return; - item = int_cleanup_item(cb); - if (item) - sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0); -} - -void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb) -{ - ENGINE_CLEANUP_ITEM *item; - if (!int_cleanup_check(1)) - return; - item = int_cleanup_item(cb); - if (item != NULL) { - if (sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item) <= 0) - OPENSSL_free(item); - } -} - -/* The API function that performs all cleanup */ -static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item) -{ - (*(item->cb)) (); - OPENSSL_free(item); -} - -void ENGINE_cleanup(void) -{ - if (int_cleanup_check(0)) { - sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack, - engine_cleanup_cb_free); - cleanup_stack = NULL; - } - /* - * FIXME: This should be handled (somehow) through RAND, eg. by it - * registering a cleanup callback. - */ - RAND_set_rand_method(NULL); -} - -/* Now the "ex_data" support */ - -int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp, - new_func, dup_func, free_func); -} - -int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&e->ex_data, idx, arg)); -} - -void *ENGINE_get_ex_data(const ENGINE *e, int idx) -{ - return (CRYPTO_get_ex_data(&e->ex_data, idx)); -} - -/* - * Functions to get/set an ENGINE's elements - mainly to avoid exposing the - * ENGINE structure itself. - */ - -int ENGINE_set_id(ENGINE *e, const char *id) -{ - if (id == NULL) { - ENGINEerr(ENGINE_F_ENGINE_SET_ID, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - e->id = id; - return 1; -} - -int ENGINE_set_name(ENGINE *e, const char *name) -{ - if (name == NULL) { - ENGINEerr(ENGINE_F_ENGINE_SET_NAME, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - e->name = name; - return 1; -} - -int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f) -{ - e->destroy = destroy_f; - return 1; -} - -int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f) -{ - e->init = init_f; - return 1; -} - -int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f) -{ - e->finish = finish_f; - return 1; -} - -int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f) -{ - e->ctrl = ctrl_f; - return 1; -} - -int ENGINE_set_flags(ENGINE *e, int flags) -{ - e->flags = flags; - return 1; -} - -int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns) -{ - e->cmd_defns = defns; - return 1; -} - -const char *ENGINE_get_id(const ENGINE *e) -{ - return e->id; -} - -const char *ENGINE_get_name(const ENGINE *e) -{ - return e->name; -} - -ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e) -{ - return e->destroy; -} - -ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e) -{ - return e->init; -} - -ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e) -{ - return e->finish; -} - -ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e) -{ - return e->ctrl; -} - -int ENGINE_get_flags(const ENGINE *e) -{ - return e->flags; -} - -const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e) -{ - return e->cmd_defns; -} - -/* - * eng_lib.o is pretty much linked into anything that touches ENGINE already, - * so put the "static_state" hack here. - */ - -static int internal_static_hack = 0; - -void *ENGINE_get_static_state(void) -{ - return &internal_static_hack; -} -/* crypto/engine/eng_list.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -// #include "cryptlib.h" -// #include "eng_int.h" - -/* - * The linked-list of pointers to engine types. engine_list_head incorporates - * an implicit structural reference but engine_list_tail does not - the - * latter is a computational niceity and only points to something that is - * already pointed to by its predecessor in the list (or engine_list_head - * itself). In the same way, the use of the "prev" pointer in each ENGINE is - * to save excessive list iteration, it doesn't correspond to an extra - * structural reference. Hence, engine_list_head, and each non-null "next" - * pointer account for the list itself assuming exactly 1 structural - * reference on each list member. - */ -static ENGINE *engine_list_head = NULL; -static ENGINE *engine_list_tail = NULL; - -/* - * This cleanup function is only needed internally. If it should be called, - * we register it with the "ENGINE_cleanup()" stack to be called during - * cleanup. - */ - -static void engine_list_cleanup(void) -{ - ENGINE *iterator = engine_list_head; - - while (iterator != NULL) { - ENGINE_remove(iterator); - iterator = engine_list_head; - } - return; -} - -/* - * These static functions starting with a lower case "engine_" always take - * place when CRYPTO_LOCK_ENGINE has been locked up. - */ -static int engine_list_add(ENGINE *e) -{ - int conflict = 0; - ENGINE *iterator = NULL; - - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - iterator = engine_list_head; - while (iterator && !conflict) { - conflict = (strcmp(iterator->id, e->id) == 0); - iterator = iterator->next; - } - if (conflict) { - ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_CONFLICTING_ENGINE_ID); - return 0; - } - if (engine_list_head == NULL) { - /* We are adding to an empty list. */ - if (engine_list_tail) { - ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR); - return 0; - } - engine_list_head = e; - e->prev = NULL; - /* - * The first time the list allocates, we should register the cleanup. - */ - engine_cleanup_add_last(engine_list_cleanup); - } else { - /* We are adding to the tail of an existing list. */ - if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) { - ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR); - return 0; - } - engine_list_tail->next = e; - e->prev = engine_list_tail; - } - /* - * Having the engine in the list assumes a structural reference. - */ - e->struct_ref++; - engine_ref_debug(e, 0, 1) - /* However it came to be, e is the last item in the list. */ - engine_list_tail = e; - e->next = NULL; - return 1; -} - -static int engine_list_remove(ENGINE *e) -{ - ENGINE *iterator; - - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - /* We need to check that e is in our linked list! */ - iterator = engine_list_head; - while (iterator && (iterator != e)) - iterator = iterator->next; - if (iterator == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, - ENGINE_R_ENGINE_IS_NOT_IN_LIST); - return 0; - } - /* un-link e from the chain. */ - if (e->next) - e->next->prev = e->prev; - if (e->prev) - e->prev->next = e->next; - /* Correct our head/tail if necessary. */ - if (engine_list_head == e) - engine_list_head = e->next; - if (engine_list_tail == e) - engine_list_tail = e->prev; - engine_free_util(e, 0); - return 1; -} - -/* Get the first/last "ENGINE" type available. */ -ENGINE *ENGINE_get_first(void) -{ - ENGINE *ret; - - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - ret = engine_list_head; - if (ret) { - ret->struct_ref++; - engine_ref_debug(ret, 0, 1) - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return ret; -} - -ENGINE *ENGINE_get_last(void) -{ - ENGINE *ret; - - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - ret = engine_list_tail; - if (ret) { - ret->struct_ref++; - engine_ref_debug(ret, 0, 1) - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return ret; -} - -/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ -ENGINE *ENGINE_get_next(ENGINE *e) -{ - ENGINE *ret = NULL; - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - ret = e->next; - if (ret) { - /* Return a valid structural refernce to the next ENGINE */ - ret->struct_ref++; - engine_ref_debug(ret, 0, 1) - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - /* Release the structural reference to the previous ENGINE */ - ENGINE_free(e); - return ret; -} - -ENGINE *ENGINE_get_prev(ENGINE *e) -{ - ENGINE *ret = NULL; - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_GET_PREV, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - ret = e->prev; - if (ret) { - /* Return a valid structural reference to the next ENGINE */ - ret->struct_ref++; - engine_ref_debug(ret, 0, 1) - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - /* Release the structural reference to the previous ENGINE */ - ENGINE_free(e); - return ret; -} - -/* Add another "ENGINE" type into the list. */ -int ENGINE_add(ENGINE *e) -{ - int to_return = 1; - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_ADD, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if ((e->id == NULL) || (e->name == NULL)) { - ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_ID_OR_NAME_MISSING); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (!engine_list_add(e)) { - ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_INTERNAL_LIST_ERROR); - to_return = 0; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return to_return; -} - -/* Remove an existing "ENGINE" type from the array. */ -int ENGINE_remove(ENGINE *e) -{ - int to_return = 1; - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_REMOVE, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (!engine_list_remove(e)) { - ENGINEerr(ENGINE_F_ENGINE_REMOVE, ENGINE_R_INTERNAL_LIST_ERROR); - to_return = 0; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return to_return; -} - -static void engine_cpy(ENGINE *dest, const ENGINE *src) -{ - dest->id = src->id; - dest->name = src->name; -#ifndef OPENSSL_NO_RSA - dest->rsa_meth = src->rsa_meth; -#endif -#ifndef OPENSSL_NO_DSA - dest->dsa_meth = src->dsa_meth; -#endif -#ifndef OPENSSL_NO_DH - dest->dh_meth = src->dh_meth; -#endif -#ifndef OPENSSL_NO_ECDH - dest->ecdh_meth = src->ecdh_meth; -#endif -#ifndef OPENSSL_NO_ECDSA - dest->ecdsa_meth = src->ecdsa_meth; -#endif - dest->rand_meth = src->rand_meth; - dest->store_meth = src->store_meth; - dest->ciphers = src->ciphers; - dest->digests = src->digests; - dest->pkey_meths = src->pkey_meths; - dest->destroy = src->destroy; - dest->init = src->init; - dest->finish = src->finish; - dest->ctrl = src->ctrl; - dest->load_privkey = src->load_privkey; - dest->load_pubkey = src->load_pubkey; - dest->cmd_defns = src->cmd_defns; - dest->flags = src->flags; -} - -ENGINE *ENGINE_by_id(const char *id) -{ - ENGINE *iterator; - char *load_dir = NULL; - if (id == NULL) { - ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_PASSED_NULL_PARAMETER); - return NULL; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - iterator = engine_list_head; - while (iterator && (strcmp(id, iterator->id) != 0)) - iterator = iterator->next; - if (iterator) { - /* - * We need to return a structural reference. If this is an ENGINE - * type that returns copies, make a duplicate - otherwise increment - * the existing ENGINE's reference count. - */ - if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) { - ENGINE *cp = ENGINE_new(); - if (!cp) - iterator = NULL; - else { - engine_cpy(cp, iterator); - iterator = cp; - } - } else { - iterator->struct_ref++; - engine_ref_debug(iterator, 0, 1) - } - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); -#if 0 - if (iterator == NULL) { - ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE); - ERR_add_error_data(2, "id=", id); - } - return iterator; -#else - /* EEK! Experimental code starts */ - if (iterator) - return iterator; - /* - * Prevent infinite recusrion if we're looking for the dynamic engine. - */ - if (strcmp(id, "dynamic")) { -# ifdef OPENSSL_SYS_VMS - if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == 0) - load_dir = "SSLROOT:[ENGINES]"; -# else - if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == 0) - load_dir = ENGINESDIR; -# endif - iterator = ENGINE_by_id("dynamic"); - if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) || - !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) || - !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD", - load_dir, 0) || - !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) || - !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0)) - goto notfound; - return iterator; - } - notfound: - ENGINE_free(iterator); - ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE); - ERR_add_error_data(2, "id=", id); - return NULL; - /* EEK! Experimental code ends */ -#endif -} - -int ENGINE_up_ref(ENGINE *e) -{ - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_add(&e->struct_ref, 1, CRYPTO_LOCK_ENGINE); - return 1; -} -/* crypto/engine/eng_openssl.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include -#include "crypto.h" -// #include "cryptlib.h" -// #include "engine.h" -// #include "dso.h" -#include "pem.h" -// #include "evp.h" -// #include "rand.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -/* - * This testing gunk is implemented (and explained) lower down. It also - * assumes the application explicitly calls "ENGINE_load_openssl()" because - * this is no longer automatic in ENGINE_load_builtin_engines(). - */ -#define TEST_ENG_OPENSSL_RC4 -#define TEST_ENG_OPENSSL_PKEY -/* #define TEST_ENG_OPENSSL_RC4_OTHERS */ -#define TEST_ENG_OPENSSL_RC4_P_INIT -/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */ -#define TEST_ENG_OPENSSL_SHA -/* #define TEST_ENG_OPENSSL_SHA_OTHERS */ -/* #define TEST_ENG_OPENSSL_SHA_P_INIT */ -/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */ -/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */ - -/* Now check what of those algorithms are actually enabled */ -#ifdef OPENSSL_NO_RC4 -# undef TEST_ENG_OPENSSL_RC4 -# undef TEST_ENG_OPENSSL_RC4_OTHERS -# undef TEST_ENG_OPENSSL_RC4_P_INIT -# undef TEST_ENG_OPENSSL_RC4_P_CIPHER -#endif -#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1) -# undef TEST_ENG_OPENSSL_SHA -# undef TEST_ENG_OPENSSL_SHA_OTHERS -# undef TEST_ENG_OPENSSL_SHA_P_INIT -# undef TEST_ENG_OPENSSL_SHA_P_UPDATE -# undef TEST_ENG_OPENSSL_SHA_P_FINAL -#endif - -#ifdef TEST_ENG_OPENSSL_RC4 -static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid); -#endif -#ifdef TEST_ENG_OPENSSL_SHA -static int openssl_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid); -#endif - -#ifdef TEST_ENG_OPENSSL_PKEY -static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, - void *callback_data); -#endif - -/* The constants used when creating the ENGINE */ -static const char *engine_openssl_id = "openssl"; -static const char *engine_openssl_name = "Software engine support"; - -/* - * This internal function is used by ENGINE_openssl() and possibly by the - * "dynamic" ENGINE support too - */ -static int bind_helper(ENGINE *e) -{ - if (!ENGINE_set_id(e, engine_openssl_id) - || !ENGINE_set_name(e, engine_openssl_name) -#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS -# ifndef OPENSSL_NO_RSA - || !ENGINE_set_RSA(e, RSA_get_default_method()) -# endif -# ifndef OPENSSL_NO_DSA - || !ENGINE_set_DSA(e, DSA_get_default_method()) -# endif -# ifndef OPENSSL_NO_ECDH - || !ENGINE_set_ECDH(e, ECDH_OpenSSL()) -# endif -# ifndef OPENSSL_NO_ECDSA - || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL()) -# endif -# ifndef OPENSSL_NO_DH - || !ENGINE_set_DH(e, DH_get_default_method()) -# endif - || !ENGINE_set_RAND(e, RAND_SSLeay()) -# ifdef TEST_ENG_OPENSSL_RC4 - || !ENGINE_set_ciphers(e, openssl_ciphers) -# endif -# ifdef TEST_ENG_OPENSSL_SHA - || !ENGINE_set_digests(e, openssl_digests) -# endif -#endif -#ifdef TEST_ENG_OPENSSL_PKEY - || !ENGINE_set_load_privkey_function(e, openssl_load_privkey) -#endif - ) - return 0; - /* - * If we add errors to this ENGINE, ensure the error handling is setup - * here - */ - /* openssl_load_error_strings(); */ - return 1; -} - -static ENGINE *engine_openssl(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_openssl(void) -{ - ENGINE *toadd = engine_openssl(); - if (!toadd) - return; - ENGINE_add(toadd); - /* - * If the "add" worked, it gets a structural reference. So either way, we - * release our just-created reference. - */ - ENGINE_free(toadd); - ERR_clear_error(); -} - -/* - * This stuff is needed if this ENGINE is being compiled into a - * self-contained shared-library. - */ -#ifdef ENGINE_DYNAMIC_SUPPORT -static int bind_fn(ENGINE *e, const char *id) -{ - if (id && (strcmp(id, engine_openssl_id) != 0)) - return 0; - if (!bind_helper(e)) - return 0; - return 1; -} - -IMPLEMENT_DYNAMIC_CHECK_FN() - IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -#endif /* ENGINE_DYNAMIC_SUPPORT */ -#ifdef TEST_ENG_OPENSSL_RC4 -/*- - * This section of code compiles an "alternative implementation" of two modes of - * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4" - * should under normal circumstances go via this support rather than the default - * EVP support. There are other symbols to tweak the testing; - * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time - * we're asked for a cipher we don't support (should not happen). - * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time - * the "init_key" handler is called. - * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler. - */ -# include "rc4.h" -# define TEST_RC4_KEY_SIZE 16 -static int test_cipher_nids[] = { NID_rc4, NID_rc4_40 }; - -static int test_cipher_nids_number = 2; -typedef struct { - unsigned char key[TEST_RC4_KEY_SIZE]; - RC4_KEY ks; -} TEST_RC4_KEY; -# define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data) -static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ -# ifdef TEST_ENG_OPENSSL_RC4_P_INIT - fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n"); -# endif - memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx)); - RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), - test(ctx)->key); - return 1; -} - -static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ -# ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER - fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n"); -# endif - RC4(&test(ctx)->ks, inl, in, out); - return 1; -} - -static const EVP_CIPHER test_r4_cipher = { - NID_rc4, - 1, TEST_RC4_KEY_SIZE, 0, - EVP_CIPH_VARIABLE_LENGTH, - test_rc4_init_key, - test_rc4_cipher, - NULL, - sizeof(TEST_RC4_KEY), - NULL, - NULL, - NULL, - NULL -}; - -static const EVP_CIPHER test_r4_40_cipher = { - NID_rc4_40, - 1, 5 /* 40 bit */ , 0, - EVP_CIPH_VARIABLE_LENGTH, - test_rc4_init_key, - test_rc4_cipher, - NULL, - sizeof(TEST_RC4_KEY), - NULL, - NULL, - NULL, - NULL -}; - -static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid) -{ - if (!cipher) { - /* We are returning a list of supported nids */ - *nids = test_cipher_nids; - return test_cipher_nids_number; - } - /* We are being asked for a specific cipher */ - if (nid == NID_rc4) - *cipher = &test_r4_cipher; - else if (nid == NID_rc4_40) - *cipher = &test_r4_40_cipher; - else { -# ifdef TEST_ENG_OPENSSL_RC4_OTHERS - fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for " - "nid %d\n", nid); -# endif - *cipher = NULL; - return 0; - } - return 1; -} -#endif - -#ifdef TEST_ENG_OPENSSL_SHA -/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */ -# include "sha.h" -static int test_digest_nids[] = { NID_sha1 }; - -static int test_digest_nids_number = 1; -static int test_sha1_init(EVP_MD_CTX *ctx) -{ -# ifdef TEST_ENG_OPENSSL_SHA_P_INIT - fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n"); -# endif - return SHA1_Init(ctx->md_data); -} - -static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ -# ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE - fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n"); -# endif - return SHA1_Update(ctx->md_data, data, count); -} - -static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) -{ -# ifdef TEST_ENG_OPENSSL_SHA_P_FINAL - fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n"); -# endif - return SHA1_Final(md, ctx->md_data); -} - -static const EVP_MD test_sha_md = { - NID_sha1, - NID_sha1WithRSAEncryption, - SHA_DIGEST_LENGTH, - 0, - test_sha1_init, - test_sha1_update, - test_sha1_final, - NULL, - NULL, - EVP_PKEY_RSA_method, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; - -static int openssl_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid) -{ - if (!digest) { - /* We are returning a list of supported nids */ - *nids = test_digest_nids; - return test_digest_nids_number; - } - /* We are being asked for a specific digest */ - if (nid == NID_sha1) - *digest = &test_sha_md; - else { -# ifdef TEST_ENG_OPENSSL_SHA_OTHERS - fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for " - "nid %d\n", nid); -# endif - *digest = NULL; - return 0; - } - return 1; -} -#endif - -#ifdef TEST_ENG_OPENSSL_PKEY -static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, - UI_METHOD *ui_method, - void *callback_data) -{ - BIO *in; - EVP_PKEY *key; - fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", - key_id); - in = BIO_new_file(key_id, "r"); - if (!in) - return NULL; - key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL); - BIO_free(in); - return key; -} -#endif -/* crypto/engine/eng_pkey.c */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "eng_int.h" - -/* Basic get/set stuff */ - -int ENGINE_set_load_privkey_function(ENGINE *e, - ENGINE_LOAD_KEY_PTR loadpriv_f) -{ - e->load_privkey = loadpriv_f; - return 1; -} - -int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f) -{ - e->load_pubkey = loadpub_f; - return 1; -} - -int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, - ENGINE_SSL_CLIENT_CERT_PTR - loadssl_f) -{ - e->load_ssl_client_cert = loadssl_f; - return 1; -} - -ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e) -{ - return e->load_privkey; -} - -ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e) -{ - return e->load_pubkey; -} - -ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE - *e) -{ - return e->load_ssl_client_cert; -} - -/* API functions to load public/private keys */ - -EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, void *callback_data) -{ - EVP_PKEY *pkey; - - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (e->funct_ref == 0) { - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, ENGINE_R_NOT_INITIALISED); - return 0; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - if (!e->load_privkey) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, - ENGINE_R_NO_LOAD_FUNCTION); - return 0; - } - pkey = e->load_privkey(e, key_id, ui_method, callback_data); - if (!pkey) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, - ENGINE_R_FAILED_LOADING_PRIVATE_KEY); - return 0; - } - return pkey; -} - -EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, void *callback_data) -{ - EVP_PKEY *pkey; - - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (e->funct_ref == 0) { - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NOT_INITIALISED); - return 0; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - if (!e->load_pubkey) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NO_LOAD_FUNCTION); - return 0; - } - pkey = e->load_pubkey(e, key_id, ui_method, callback_data); - if (!pkey) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, - ENGINE_R_FAILED_LOADING_PUBLIC_KEY); - return 0; - } - return pkey; -} - -int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, - STACK_OF(X509_NAME) *ca_dn, X509 **pcert, - EVP_PKEY **ppkey, STACK_OF(X509) **pother, - UI_METHOD *ui_method, void *callback_data) -{ - - if (e == NULL) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, - ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (e->funct_ref == 0) { - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, - ENGINE_R_NOT_INITIALISED); - return 0; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - if (!e->load_ssl_client_cert) { - ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, - ENGINE_R_NO_LOAD_FUNCTION); - return 0; - } - return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother, - ui_method, callback_data); -} -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "opensslconf.h" - -#include -#include -// #include "engine.h" -// #include "rand.h" -// #include "err.h" - -#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ) - -size_t OPENSSL_ia32_rdrand(void); - -static int get_random_bytes(unsigned char *buf, int num) -{ - size_t rnd; - - while (num >= (int)sizeof(size_t)) { - if ((rnd = OPENSSL_ia32_rdrand()) == 0) - return 0; - - *((size_t *)buf) = rnd; - buf += sizeof(size_t); - num -= sizeof(size_t); - } - if (num) { - if ((rnd = OPENSSL_ia32_rdrand()) == 0) - return 0; - - memcpy(buf, &rnd, num); - } - - return 1; -} - -static int random_status(void) -{ - return 1; -} - -static RAND_METHOD rdrand_meth = { - NULL, /* seed */ - get_random_bytes, - NULL, /* cleanup */ - NULL, /* add */ - get_random_bytes, - random_status, -}; - -static int rdrand_init(ENGINE *e) -{ - return 1; -} - -static const char *engine_e_rdrand_id = "rdrand"; -static const char *engine_e_rdrand_name = "Intel RDRAND engine"; - -static int bind_helper(ENGINE *e) -{ - if (!ENGINE_set_id(e, engine_e_rdrand_id) || - !ENGINE_set_name(e, engine_e_rdrand_name) || - !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) || - !ENGINE_set_init_function(e, rdrand_init) || - !ENGINE_set_RAND(e, &rdrand_meth)) - return 0; - - return 1; -} - -static ENGINE *ENGINE_rdrand(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_helper(ret)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_rdrand(void) -{ - extern unsigned int OPENSSL_ia32cap_P[]; - - if (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) { - ENGINE *toadd = ENGINE_rdrand(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); - } -} -#else -void ENGINE_load_rdrand(void) -{ -} -#endif -/* ==================================================================== - * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "evp.h" -#include "lhash.h" -// #include "eng_int.h" - -/* The type of the items in the table */ -typedef struct st_engine_pile { - /* The 'nid' of this algorithm/mode */ - int nid; - /* ENGINEs that implement this algorithm/mode. */ - STACK_OF(ENGINE) *sk; - /* The default ENGINE to perform this algorithm/mode. */ - ENGINE *funct; - /* - * Zero if 'sk' is newer than the cached 'funct', non-zero otherwise - */ - int uptodate; -} ENGINE_PILE; - -DECLARE_LHASH_OF(ENGINE_PILE); - -/* The type exposed in eng_int.h */ -struct st_engine_table { - LHASH_OF(ENGINE_PILE) piles; -}; /* ENGINE_TABLE */ - -typedef struct st_engine_pile_doall { - engine_table_doall_cb *cb; - void *arg; -} ENGINE_PILE_DOALL; - -/* Global flags (ENGINE_TABLE_FLAG_***). */ -static unsigned int table_flags = 0; - -/* API function manipulating 'table_flags' */ -unsigned int ENGINE_get_table_flags(void) -{ - return table_flags; -} - -void ENGINE_set_table_flags(unsigned int flags) -{ - table_flags = flags; -} - -/* Internal functions for the "piles" hash table */ -static unsigned long engine_pile_hash(const ENGINE_PILE *c) -{ - return c->nid; -} - -static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) -{ - return a->nid - b->nid; -} - -static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE) -static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE) - -static int int_table_check(ENGINE_TABLE **t, int create) -{ - LHASH_OF(ENGINE_PILE) *lh; - - if (*t) - return 1; - if (!create) - return 0; - if ((lh = lh_ENGINE_PILE_new()) == NULL) - return 0; - *t = (ENGINE_TABLE *)lh; - return 1; -} - -/* - * Privately exposed (via eng_int.h) functions for adding and/or removing - * ENGINEs from the implementation table - */ -int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, - ENGINE *e, const int *nids, int num_nids, - int setdefault) -{ - int ret = 0, added = 0; - ENGINE_PILE tmplate, *fnd; - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (!(*table)) - added = 1; - if (!int_table_check(table, 1)) - goto end; - if (added) - /* The cleanup callback needs to be added */ - engine_cleanup_add_first(cleanup); - while (num_nids--) { - tmplate.nid = *nids; - fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); - if (!fnd) { - fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); - if (!fnd) - goto end; - fnd->uptodate = 1; - fnd->nid = *nids; - fnd->sk = sk_ENGINE_new_null(); - if (!fnd->sk) { - OPENSSL_free(fnd); - goto end; - } - fnd->funct = NULL; - (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd); - if (lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate) != fnd) { - sk_ENGINE_free(fnd->sk); - OPENSSL_free(fnd); - goto end; - } - } - /* A registration shouldn't add duplciate entries */ - (void)sk_ENGINE_delete_ptr(fnd->sk, e); - /* - * if 'setdefault', this ENGINE goes to the head of the list - */ - if (!sk_ENGINE_push(fnd->sk, e)) - goto end; - /* "touch" this ENGINE_PILE */ - fnd->uptodate = 0; - if (setdefault) { - if (!engine_unlocked_init(e)) { - ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, - ENGINE_R_INIT_FAILED); - goto end; - } - if (fnd->funct) - engine_unlocked_finish(fnd->funct, 0); - fnd->funct = e; - fnd->uptodate = 1; - } - nids++; - } - ret = 1; - end: - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return ret; -} - -static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e) -{ - int n; - /* Iterate the 'c->sk' stack removing any occurance of 'e' */ - while ((n = sk_ENGINE_find(pile->sk, e)) >= 0) { - (void)sk_ENGINE_delete(pile->sk, n); - pile->uptodate = 0; - } - if (pile->funct == e) { - engine_unlocked_finish(e, 0); - pile->funct = NULL; - } -} - -static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE) - -void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) -{ - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (int_table_check(table, 0)) - lh_ENGINE_PILE_doall_arg(&(*table)->piles, - LHASH_DOALL_ARG_FN(int_unregister_cb), - ENGINE, e); - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); -} - -static void int_cleanup_cb_doall(ENGINE_PILE *p) -{ - sk_ENGINE_free(p->sk); - if (p->funct) - engine_unlocked_finish(p->funct, 0); - OPENSSL_free(p); -} - -static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE) - -void engine_table_cleanup(ENGINE_TABLE **table) -{ - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - if (*table) { - lh_ENGINE_PILE_doall(&(*table)->piles, - LHASH_DOALL_FN(int_cleanup_cb)); - lh_ENGINE_PILE_free(&(*table)->piles); - *table = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); -} - -/* return a functional reference for a given 'nid' */ -#ifndef ENGINE_TABLE_DEBUG -ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) -#else -ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, - int l) -#endif -{ - ENGINE *ret = NULL; - ENGINE_PILE tmplate, *fnd = NULL; - int initres, loop = 0; - - if (!(*table)) { -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing " - "registered!\n", f, l, nid); -#endif - return NULL; - } - ERR_set_mark(); - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - /* - * Check again inside the lock otherwise we could race against cleanup - * operations. But don't worry about a fprintf(stderr). - */ - if (!int_table_check(table, 0)) - goto end; - tmplate.nid = nid; - fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); - if (!fnd) - goto end; - if (fnd->funct && engine_unlocked_init(fnd->funct)) { -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " - "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); -#endif - ret = fnd->funct; - goto end; - } - if (fnd->uptodate) { - ret = fnd->funct; - goto end; - } - trynext: - ret = sk_ENGINE_value(fnd->sk, loop++); - if (!ret) { -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " - "registered implementations would initialise\n", f, l, nid); -#endif - goto end; - } - /* Try to initialise the ENGINE? */ - if ((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) - initres = engine_unlocked_init(ret); - else - initres = 0; - if (initres) { - /* Update 'funct' */ - if ((fnd->funct != ret) && engine_unlocked_init(ret)) { - /* If there was a previous default we release it. */ - if (fnd->funct) - engine_unlocked_finish(fnd->funct, 0); - fnd->funct = ret; -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " - "setting default to '%s'\n", f, l, nid, ret->id); -#endif - } -#ifdef ENGINE_TABLE_DEBUG - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " - "newly initialised '%s'\n", f, l, nid, ret->id); -#endif - goto end; - } - goto trynext; - end: - /* - * If it failed, it is unlikely to succeed again until some future - * registrations have taken place. In all cases, we cache. - */ - if (fnd) - fnd->uptodate = 1; -#ifdef ENGINE_TABLE_DEBUG - if (ret) - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " - "ENGINE '%s'\n", f, l, nid, ret->id); - else - fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " - "'no matching ENGINE'\n", f, l, nid); -#endif - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - /* - * Whatever happened, any failed init()s are not failures in this - * context, so clear our error state. - */ - ERR_pop_to_mark(); - return ret; -} - -/* Table enumeration */ - -static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall) -{ - dall->cb(pile->nid, pile->sk, pile->funct, dall->arg); -} - -static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE, ENGINE_PILE_DOALL) - -void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, - void *arg) -{ - ENGINE_PILE_DOALL dall; - dall.cb = cb; - dall.arg = arg; - if (table) - lh_ENGINE_PILE_doall_arg(&table->piles, - LHASH_DOALL_ARG_FN(int_cb), - ENGINE_PILE_DOALL, &dall); -} diff --git a/Sources/COpenSSL/eng_int.h b/Sources/COpenSSL/eng_int.h deleted file mode 100644 index a47cff19..00000000 --- a/Sources/COpenSSL/eng_int.h +++ /dev/null @@ -1,224 +0,0 @@ -/* crypto/engine/eng_int.h */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#ifndef HEADER_ENGINE_INT_H -# define HEADER_ENGINE_INT_H - -# include "cryptlib.h" -/* Take public definitions from engine.h */ -# include "engine.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * If we compile with this symbol defined, then both reference counts in the - * ENGINE structure will be monitored with a line of output on stderr for - * each change. This prints the engine's pointer address (truncated to - * unsigned int), "struct" or "funct" to indicate the reference type, the - * before and after reference count, and the file:line-number pair. The - * "engine_ref_debug" statements must come *after* the change. - */ -# ifdef ENGINE_REF_COUNT_DEBUG - -# define engine_ref_debug(e, isfunct, diff) \ - fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \ - (unsigned int)(e), (isfunct ? "funct" : "struct"), \ - ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \ - ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ - (__FILE__), (__LINE__)); - -# else - -# define engine_ref_debug(e, isfunct, diff) - -# endif - -/* - * Any code that will need cleanup operations should use these functions to - * register callbacks. ENGINE_cleanup() will call all registered callbacks in - * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be - * held (in "write" mode). - */ -typedef void (ENGINE_CLEANUP_CB) (void); -typedef struct st_engine_cleanup_item { - ENGINE_CLEANUP_CB *cb; -} ENGINE_CLEANUP_ITEM; -DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM) -void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb); -void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb); - -/* We need stacks of ENGINEs for use in eng_table.c */ -DECLARE_STACK_OF(ENGINE) - -/* - * If this symbol is defined then engine_table_select(), the function that is - * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults - * and functional references (etc), will display debugging summaries to - * stderr. - */ -/* #define ENGINE_TABLE_DEBUG */ - -/* - * This represents an implementation table. Dependent code should instantiate - * it as a (ENGINE_TABLE *) pointer value set initially to NULL. - */ -typedef struct st_engine_table ENGINE_TABLE; -int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, - ENGINE *e, const int *nids, int num_nids, - int setdefault); -void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e); -void engine_table_cleanup(ENGINE_TABLE **table); -# ifndef ENGINE_TABLE_DEBUG -ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); -# else -ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, - int l); -# define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) -# endif -typedef void (engine_table_doall_cb) (int nid, STACK_OF(ENGINE) *sk, - ENGINE *def, void *arg); -void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, - void *arg); - -/* - * Internal versions of API functions that have control over locking. These - * are used between C files when functionality needs to be shared but the - * caller may already be controlling of the CRYPTO_LOCK_ENGINE lock. - */ -int engine_unlocked_init(ENGINE *e); -int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers); -int engine_free_util(ENGINE *e, int locked); - -/* - * This function will reset all "set"able values in an ENGINE to NULL. This - * won't touch reference counts or ex_data, but is equivalent to calling all - * the ENGINE_set_***() functions with a NULL value. - */ -void engine_set_all_null(ENGINE *e); - -/* - * NB: Bitwise OR-able values for the "flags" variable in ENGINE are now - * exposed in engine.h. - */ - -/* Free up dynamically allocated public key methods associated with ENGINE */ - -void engine_pkey_meths_free(ENGINE *e); -void engine_pkey_asn1_meths_free(ENGINE *e); - -/* - * This is a structure for storing implementations of various crypto - * algorithms and functions. - */ -struct engine_st { - const char *id; - const char *name; - const RSA_METHOD *rsa_meth; - const DSA_METHOD *dsa_meth; - const DH_METHOD *dh_meth; - const ECDH_METHOD *ecdh_meth; - const ECDSA_METHOD *ecdsa_meth; - const RAND_METHOD *rand_meth; - const STORE_METHOD *store_meth; - /* Cipher handling is via this callback */ - ENGINE_CIPHERS_PTR ciphers; - /* Digest handling is via this callback */ - ENGINE_DIGESTS_PTR digests; - /* Public key handling via this callback */ - ENGINE_PKEY_METHS_PTR pkey_meths; - /* ASN1 public key handling via this callback */ - ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths; - ENGINE_GEN_INT_FUNC_PTR destroy; - ENGINE_GEN_INT_FUNC_PTR init; - ENGINE_GEN_INT_FUNC_PTR finish; - ENGINE_CTRL_FUNC_PTR ctrl; - ENGINE_LOAD_KEY_PTR load_privkey; - ENGINE_LOAD_KEY_PTR load_pubkey; - ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert; - const ENGINE_CMD_DEFN *cmd_defns; - int flags; - /* reference count on the structure itself */ - int struct_ref; - /* - * reference count on usability of the engine type. NB: This controls the - * loading and initialisation of any functionlity required by this - * engine, whereas the previous count is simply to cope with - * (de)allocation of this structure. Hence, running_ref <= struct_ref at - * all times. - */ - int funct_ref; - /* A place to store per-ENGINE data */ - CRYPTO_EX_DATA ex_data; - /* Used to maintain the linked-list of engines. */ - struct engine_st *prev; - struct engine_st *next; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_ENGINE_INT_H */ diff --git a/Sources/COpenSSL/engine.h b/Sources/COpenSSL/engine.h deleted file mode 100644 index 873464a0..00000000 --- a/Sources/COpenSSL/engine.h +++ /dev/null @@ -1,960 +0,0 @@ -/* openssl/engine.h */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#ifndef HEADER_ENGINE_H -# define HEADER_ENGINE_H - -# include "opensslconf.h" - -# ifdef OPENSSL_NO_ENGINE -# error ENGINE is disabled. -# endif - -# ifndef OPENSSL_NO_DEPRECATED -# include "bn.h" -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif -# ifndef OPENSSL_NO_DSA -# include "dsa.h" -# endif -# ifndef OPENSSL_NO_DH -# include "dh.h" -# endif -# ifndef OPENSSL_NO_ECDH -# include "ecdh.h" -# endif -# ifndef OPENSSL_NO_ECDSA -# include "ecdsa.h" -# endif -# include "rand.h" -# include "ui.h" -# include "err.h" -# endif - -# include "ossl_typ.h" -# include "symhacks.h" - -# include "x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * These flags are used to control combinations of algorithm (methods) by - * bitwise "OR"ing. - */ -# define ENGINE_METHOD_RSA (unsigned int)0x0001 -# define ENGINE_METHOD_DSA (unsigned int)0x0002 -# define ENGINE_METHOD_DH (unsigned int)0x0004 -# define ENGINE_METHOD_RAND (unsigned int)0x0008 -# define ENGINE_METHOD_ECDH (unsigned int)0x0010 -# define ENGINE_METHOD_ECDSA (unsigned int)0x0020 -# define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 -# define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 -# define ENGINE_METHOD_STORE (unsigned int)0x0100 -# define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 -# define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 -/* Obvious all-or-nothing cases. */ -# define ENGINE_METHOD_ALL (unsigned int)0xFFFF -# define ENGINE_METHOD_NONE (unsigned int)0x0000 - -/* - * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used - * internally to control registration of ENGINE implementations, and can be - * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to - * initialise registered ENGINEs if they are not already initialised. - */ -# define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 - -/* ENGINE flags that can be set by ENGINE_set_flags(). */ -/* Not used */ -/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ - -/* - * This flag is for ENGINEs that wish to handle the various 'CMD'-related - * control commands on their own. Without this flag, ENGINE_ctrl() handles - * these control commands on behalf of the ENGINE using their "cmd_defns" - * data. - */ -# define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 - -/* - * This flag is for ENGINEs who return new duplicate structures when found - * via "ENGINE_by_id()". When an ENGINE must store state (eg. if - * ENGINE_ctrl() commands are called in sequence as part of some stateful - * process like key-generation setup and execution), it can set this flag - - * then each attempt to obtain the ENGINE will result in it being copied into - * a new structure. Normally, ENGINEs don't declare this flag so - * ENGINE_by_id() just increments the existing ENGINE's structural reference - * count. - */ -# define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 - -/* - * This flag if for an ENGINE that does not want its methods registered as - * part of ENGINE_register_all_complete() for example if the methods are not - * usable as default methods. - */ - -# define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 - -/* - * ENGINEs can support their own command types, and these flags are used in - * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input - * each command expects. Currently only numeric and string input is - * supported. If a control command supports none of the _NUMERIC, _STRING, or - * _NO_INPUT options, then it is regarded as an "internal" control command - - * and not for use in config setting situations. As such, they're not - * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() - * access. Changes to this list of 'command types' should be reflected - * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). - */ - -/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ -# define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 -/* - * accepts string input (cast from 'void*' to 'const char *', 4th parameter - * to ENGINE_ctrl) - */ -# define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 -/* - * Indicates that the control command takes *no* input. Ie. the control - * command is unparameterised. - */ -# define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 -/* - * Indicates that the control command is internal. This control command won't - * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() - * function. - */ -# define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 - -/* - * NB: These 3 control commands are deprecated and should not be used. - * ENGINEs relying on these commands should compile conditional support for - * compatibility (eg. if these symbols are defined) but should also migrate - * the same functionality to their own ENGINE-specific control functions that - * can be "discovered" by calling applications. The fact these control - * commands wouldn't be "executable" (ie. usable by text-based config) - * doesn't change the fact that application code can find and use them - * without requiring per-ENGINE hacking. - */ - -/* - * These flags are used to tell the ctrl function what should be done. All - * command numbers are shared between all engines, even if some don't make - * sense to some engines. In such a case, they do nothing but return the - * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. - */ -# define ENGINE_CTRL_SET_LOGSTREAM 1 -# define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 -# define ENGINE_CTRL_HUP 3/* Close and reinitialise - * any handles/connections - * etc. */ -# define ENGINE_CTRL_SET_USER_INTERFACE 4/* Alternative to callback */ -# define ENGINE_CTRL_SET_CALLBACK_DATA 5/* User-specific data, used - * when calling the password - * callback and the user - * interface */ -# define ENGINE_CTRL_LOAD_CONFIGURATION 6/* Load a configuration, - * given a string that - * represents a file name - * or so */ -# define ENGINE_CTRL_LOAD_SECTION 7/* Load data from a given - * section in the already - * loaded configuration */ - -/* - * These control commands allow an application to deal with an arbitrary - * engine in a dynamic way. Warn: Negative return values indicate errors FOR - * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other - * commands, including ENGINE-specific command types, return zero for an - * error. An ENGINE can choose to implement these ctrl functions, and can - * internally manage things however it chooses - it does so by setting the - * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise - * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the - * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's - * ctrl() handler need only implement its own commands - the above "meta" - * commands will be taken care of. - */ - -/* - * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", - * then all the remaining control commands will return failure, so it is - * worth checking this first if the caller is trying to "discover" the - * engine's capabilities and doesn't want errors generated unnecessarily. - */ -# define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 -/* - * Returns a positive command number for the first command supported by the - * engine. Returns zero if no ctrl commands are supported. - */ -# define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 -/* - * The 'long' argument specifies a command implemented by the engine, and the - * return value is the next command supported, or zero if there are no more. - */ -# define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 -/* - * The 'void*' argument is a command name (cast from 'const char *'), and the - * return value is the command that corresponds to it. - */ -# define ENGINE_CTRL_GET_CMD_FROM_NAME 13 -/* - * The next two allow a command to be converted into its corresponding string - * form. In each case, the 'long' argument supplies the command. In the - * NAME_LEN case, the return value is the length of the command name (not - * counting a trailing EOL). In the NAME case, the 'void*' argument must be a - * string buffer large enough, and it will be populated with the name of the - * command (WITH a trailing EOL). - */ -# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 -# define ENGINE_CTRL_GET_NAME_FROM_CMD 15 -/* The next two are similar but give a "short description" of a command. */ -# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 -# define ENGINE_CTRL_GET_DESC_FROM_CMD 17 -/* - * With this command, the return value is the OR'd combination of - * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given - * engine-specific ctrl command expects. - */ -# define ENGINE_CTRL_GET_CMD_FLAGS 18 - -/* - * ENGINE implementations should start the numbering of their own control - * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). - */ -# define ENGINE_CMD_BASE 200 - -/* - * NB: These 2 nCipher "chil" control commands are deprecated, and their - * functionality is now available through ENGINE-specific control commands - * (exposed through the above-mentioned 'CMD'-handling). Code using these 2 - * commands should be migrated to the more general command handling before - * these are removed. - */ - -/* Flags specific to the nCipher "chil" engine */ -# define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 - /* - * Depending on the value of the (long)i argument, this sets or - * unsets the SimpleForkCheck flag in the CHIL API to enable or - * disable checking and workarounds for applications that fork(). - */ -# define ENGINE_CTRL_CHIL_NO_LOCKING 101 - /* - * This prevents the initialisation function from providing mutex - * callbacks to the nCipher library. - */ - -/* - * If an ENGINE supports its own specific control commands and wishes the - * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on - * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN - * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl() - * handler that supports the stated commands (ie. the "cmd_num" entries as - * described by the array). NB: The array must be ordered in increasing order - * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element - * has cmd_num set to zero and/or cmd_name set to NULL. - */ -typedef struct ENGINE_CMD_DEFN_st { - unsigned int cmd_num; /* The command number */ - const char *cmd_name; /* The command name itself */ - const char *cmd_desc; /* A short description of the command */ - unsigned int cmd_flags; /* The input the command expects */ -} ENGINE_CMD_DEFN; - -/* Generic function pointer */ -typedef int (*ENGINE_GEN_FUNC_PTR) (void); -/* Generic function pointer taking no arguments */ -typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *); -/* Specific control function pointer */ -typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, - void (*f) (void)); -/* Generic load_key function pointer */ -typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, - UI_METHOD *ui_method, - void *callback_data); -typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, - STACK_OF(X509_NAME) *ca_dn, - X509 **pcert, EVP_PKEY **pkey, - STACK_OF(X509) **pother, - UI_METHOD *ui_method, - void *callback_data); -/*- - * These callback types are for an ENGINE's handler for cipher and digest logic. - * These handlers have these prototypes; - * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); - * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); - * Looking at how to implement these handlers in the case of cipher support, if - * the framework wants the EVP_CIPHER for 'nid', it will call; - * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) - * If the framework wants a list of supported 'nid's, it will call; - * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) - */ -/* - * Returns to a pointer to the array of supported cipher 'nid's. If the - * second parameter is non-NULL it is set to the size of the returned array. - */ -typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **, - const int **, int); -typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **, - int); -typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **, - const int **, int); -typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **, - const int **, int); -/* - * STRUCTURE functions ... all of these functions deal with pointers to - * ENGINE structures where the pointers have a "structural reference". This - * means that their reference is to allowed access to the structure but it - * does not imply that the structure is functional. To simply increment or - * decrement the structural reference count, use ENGINE_by_id and - * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next - * as it will automatically decrement the structural reference count of the - * "current" ENGINE and increment the structural reference count of the - * ENGINE it returns (unless it is NULL). - */ - -/* Get the first/last "ENGINE" type available. */ -ENGINE *ENGINE_get_first(void); -ENGINE *ENGINE_get_last(void); -/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ -ENGINE *ENGINE_get_next(ENGINE *e); -ENGINE *ENGINE_get_prev(ENGINE *e); -/* Add another "ENGINE" type into the array. */ -int ENGINE_add(ENGINE *e); -/* Remove an existing "ENGINE" type from the array. */ -int ENGINE_remove(ENGINE *e); -/* Retrieve an engine from the list by its unique "id" value. */ -ENGINE *ENGINE_by_id(const char *id); -/* Add all the built-in engines. */ -void ENGINE_load_openssl(void); -void ENGINE_load_dynamic(void); -# ifndef OPENSSL_NO_STATIC_ENGINE -void ENGINE_load_4758cca(void); -void ENGINE_load_aep(void); -void ENGINE_load_atalla(void); -void ENGINE_load_chil(void); -void ENGINE_load_cswift(void); -void ENGINE_load_nuron(void); -void ENGINE_load_sureware(void); -void ENGINE_load_ubsec(void); -void ENGINE_load_padlock(void); -void ENGINE_load_capi(void); -# ifndef OPENSSL_NO_GMP -void ENGINE_load_gmp(void); -# endif -# ifndef OPENSSL_NO_GOST -void ENGINE_load_gost(void); -# endif -# endif -void ENGINE_load_cryptodev(void); -void ENGINE_load_rdrand(void); -void ENGINE_load_builtin_engines(void); - -/* - * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation - * "registry" handling. - */ -unsigned int ENGINE_get_table_flags(void); -void ENGINE_set_table_flags(unsigned int flags); - -/*- Manage registration of ENGINEs per "table". For each type, there are 3 - * functions; - * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) - * ENGINE_unregister_***(e) - unregister the implementation from 'e' - * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list - * Cleanup is automatically registered from each table when required, so - * ENGINE_cleanup() will reverse any "register" operations. - */ - -int ENGINE_register_RSA(ENGINE *e); -void ENGINE_unregister_RSA(ENGINE *e); -void ENGINE_register_all_RSA(void); - -int ENGINE_register_DSA(ENGINE *e); -void ENGINE_unregister_DSA(ENGINE *e); -void ENGINE_register_all_DSA(void); - -int ENGINE_register_ECDH(ENGINE *e); -void ENGINE_unregister_ECDH(ENGINE *e); -void ENGINE_register_all_ECDH(void); - -int ENGINE_register_ECDSA(ENGINE *e); -void ENGINE_unregister_ECDSA(ENGINE *e); -void ENGINE_register_all_ECDSA(void); - -int ENGINE_register_DH(ENGINE *e); -void ENGINE_unregister_DH(ENGINE *e); -void ENGINE_register_all_DH(void); - -int ENGINE_register_RAND(ENGINE *e); -void ENGINE_unregister_RAND(ENGINE *e); -void ENGINE_register_all_RAND(void); - -int ENGINE_register_STORE(ENGINE *e); -void ENGINE_unregister_STORE(ENGINE *e); -void ENGINE_register_all_STORE(void); - -int ENGINE_register_ciphers(ENGINE *e); -void ENGINE_unregister_ciphers(ENGINE *e); -void ENGINE_register_all_ciphers(void); - -int ENGINE_register_digests(ENGINE *e); -void ENGINE_unregister_digests(ENGINE *e); -void ENGINE_register_all_digests(void); - -int ENGINE_register_pkey_meths(ENGINE *e); -void ENGINE_unregister_pkey_meths(ENGINE *e); -void ENGINE_register_all_pkey_meths(void); - -int ENGINE_register_pkey_asn1_meths(ENGINE *e); -void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); -void ENGINE_register_all_pkey_asn1_meths(void); - -/* - * These functions register all support from the above categories. Note, use - * of these functions can result in static linkage of code your application - * may not need. If you only need a subset of functionality, consider using - * more selective initialisation. - */ -int ENGINE_register_complete(ENGINE *e); -int ENGINE_register_all_complete(void); - -/* - * Send parametrised control commands to the engine. The possibilities to - * send down an integer, a pointer to data or a function pointer are - * provided. Any of the parameters may or may not be NULL, depending on the - * command number. In actuality, this function only requires a structural - * (rather than functional) reference to an engine, but many control commands - * may require the engine be functional. The caller should be aware of trying - * commands that require an operational ENGINE, and only use functional - * references in such situations. - */ -int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); - -/* - * This function tests if an ENGINE-specific command is usable as a - * "setting". Eg. in an application's config file that gets processed through - * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to - * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). - */ -int ENGINE_cmd_is_executable(ENGINE *e, int cmd); - -/* - * This function works like ENGINE_ctrl() with the exception of taking a - * command name instead of a command number, and can handle optional - * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation - * on how to use the cmd_name and cmd_optional. - */ -int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, - long i, void *p, void (*f) (void), int cmd_optional); - -/* - * This function passes a command-name and argument to an ENGINE. The - * cmd_name is converted to a command number and the control command is - * called using 'arg' as an argument (unless the ENGINE doesn't support such - * a command, in which case no control command is called). The command is - * checked for input flags, and if necessary the argument will be converted - * to a numeric value. If cmd_optional is non-zero, then if the ENGINE - * doesn't support the given cmd_name the return value will be success - * anyway. This function is intended for applications to use so that users - * (or config files) can supply engine-specific config data to the ENGINE at - * run-time to control behaviour of specific engines. As such, it shouldn't - * be used for calling ENGINE_ctrl() functions that return data, deal with - * binary data, or that are otherwise supposed to be used directly through - * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl() - * operation in this function will be lost - the return value is interpreted - * as failure if the return value is zero, success otherwise, and this - * function returns a boolean value as a result. In other words, vendors of - * 'ENGINE'-enabled devices should write ENGINE implementations with - * parameterisations that work in this scheme, so that compliant ENGINE-based - * applications can work consistently with the same configuration for the - * same ENGINE-enabled devices, across applications. - */ -int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, - int cmd_optional); - -/* - * These functions are useful for manufacturing new ENGINE structures. They - * don't address reference counting at all - one uses them to populate an - * ENGINE structure with personalised implementations of things prior to - * using it directly or adding it to the builtin ENGINE list in OpenSSL. - * These are also here so that the ENGINE structure doesn't have to be - * exposed and break binary compatibility! - */ -ENGINE *ENGINE_new(void); -int ENGINE_free(ENGINE *e); -int ENGINE_up_ref(ENGINE *e); -int ENGINE_set_id(ENGINE *e, const char *id); -int ENGINE_set_name(ENGINE *e, const char *name); -int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); -int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); -int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth); -int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth); -int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); -int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); -int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth); -int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); -int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); -int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); -int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); -int ENGINE_set_load_privkey_function(ENGINE *e, - ENGINE_LOAD_KEY_PTR loadpriv_f); -int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); -int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, - ENGINE_SSL_CLIENT_CERT_PTR - loadssl_f); -int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); -int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); -int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); -int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); -int ENGINE_set_flags(ENGINE *e, int flags); -int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); -/* These functions allow control over any per-structure ENGINE data. */ -int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); -int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); -void *ENGINE_get_ex_data(const ENGINE *e, int idx); - -/* - * This function cleans up anything that needs it. Eg. the ENGINE_add() - * function automatically ensures the list cleanup function is registered to - * be called from ENGINE_cleanup(). Similarly, all ENGINE_register_*** - * functions ensure ENGINE_cleanup() will clean up after them. - */ -void ENGINE_cleanup(void); - -/* - * These return values from within the ENGINE structure. These can be useful - * with functional references as well as structural references - it depends - * which you obtained. Using the result for functional purposes if you only - * obtained a structural reference may be problematic! - */ -const char *ENGINE_get_id(const ENGINE *e); -const char *ENGINE_get_name(const ENGINE *e); -const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); -const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); -const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e); -const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e); -const DH_METHOD *ENGINE_get_DH(const ENGINE *e); -const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); -const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e); -ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); -ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); -ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); -ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); -ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); -ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); -ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE - *e); -ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); -ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); -ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); -ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); -const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); -const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); -const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); -const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); -const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, - const char *str, - int len); -const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, - const char *str, - int len); -const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); -int ENGINE_get_flags(const ENGINE *e); - -/* - * FUNCTIONAL functions. These functions deal with ENGINE structures that - * have (or will) be initialised for use. Broadly speaking, the structural - * functions are useful for iterating the list of available engine types, - * creating new engine types, and other "list" operations. These functions - * actually deal with ENGINEs that are to be used. As such these functions - * can fail (if applicable) when particular engines are unavailable - eg. if - * a hardware accelerator is not attached or not functioning correctly. Each - * ENGINE has 2 reference counts; structural and functional. Every time a - * functional reference is obtained or released, a corresponding structural - * reference is automatically obtained or released too. - */ - -/* - * Initialise a engine type for use (or up its reference count if it's - * already in use). This will fail if the engine is not currently operational - * and cannot initialise. - */ -int ENGINE_init(ENGINE *e); -/* - * Free a functional reference to a engine type. This does not require a - * corresponding call to ENGINE_free as it also releases a structural - * reference. - */ -int ENGINE_finish(ENGINE *e); - -/* - * The following functions handle keys that are stored in some secondary - * location, handled by the engine. The storage may be on a card or - * whatever. - */ -EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, void *callback_data); -EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, - UI_METHOD *ui_method, void *callback_data); -int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, - STACK_OF(X509_NAME) *ca_dn, X509 **pcert, - EVP_PKEY **ppkey, STACK_OF(X509) **pother, - UI_METHOD *ui_method, void *callback_data); - -/* - * This returns a pointer for the current ENGINE structure that is (by - * default) performing any RSA operations. The value returned is an - * incremented reference, so it should be free'd (ENGINE_finish) before it is - * discarded. - */ -ENGINE *ENGINE_get_default_RSA(void); -/* Same for the other "methods" */ -ENGINE *ENGINE_get_default_DSA(void); -ENGINE *ENGINE_get_default_ECDH(void); -ENGINE *ENGINE_get_default_ECDSA(void); -ENGINE *ENGINE_get_default_DH(void); -ENGINE *ENGINE_get_default_RAND(void); -/* - * These functions can be used to get a functional reference to perform - * ciphering or digesting corresponding to "nid". - */ -ENGINE *ENGINE_get_cipher_engine(int nid); -ENGINE *ENGINE_get_digest_engine(int nid); -ENGINE *ENGINE_get_pkey_meth_engine(int nid); -ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); - -/* - * This sets a new default ENGINE structure for performing RSA operations. If - * the result is non-zero (success) then the ENGINE structure will have had - * its reference count up'd so the caller should still free their own - * reference 'e'. - */ -int ENGINE_set_default_RSA(ENGINE *e); -int ENGINE_set_default_string(ENGINE *e, const char *def_list); -/* Same for the other "methods" */ -int ENGINE_set_default_DSA(ENGINE *e); -int ENGINE_set_default_ECDH(ENGINE *e); -int ENGINE_set_default_ECDSA(ENGINE *e); -int ENGINE_set_default_DH(ENGINE *e); -int ENGINE_set_default_RAND(ENGINE *e); -int ENGINE_set_default_ciphers(ENGINE *e); -int ENGINE_set_default_digests(ENGINE *e); -int ENGINE_set_default_pkey_meths(ENGINE *e); -int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); - -/* - * The combination "set" - the flags are bitwise "OR"d from the - * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" - * function, this function can result in unnecessary static linkage. If your - * application requires only specific functionality, consider using more - * selective functions. - */ -int ENGINE_set_default(ENGINE *e, unsigned int flags); - -void ENGINE_add_conf_module(void); - -/* Deprecated functions ... */ -/* int ENGINE_clear_defaults(void); */ - -/**************************/ -/* DYNAMIC ENGINE SUPPORT */ -/**************************/ - -/* Binary/behaviour compatibility levels */ -# define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000 -/* - * Binary versions older than this are too old for us (whether we're a loader - * or a loadee) - */ -# define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000 - -/* - * When compiling an ENGINE entirely as an external shared library, loadable - * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' - * structure type provides the calling application's (or library's) error - * functionality and memory management function pointers to the loaded - * library. These should be used/set in the loaded library code so that the - * loading application's 'state' will be used/changed in all operations. The - * 'static_state' pointer allows the loaded library to know if it shares the - * same static data as the calling application (or library), and thus whether - * these callbacks need to be set or not. - */ -typedef void *(*dyn_MEM_malloc_cb) (size_t); -typedef void *(*dyn_MEM_realloc_cb) (void *, size_t); -typedef void (*dyn_MEM_free_cb) (void *); -typedef struct st_dynamic_MEM_fns { - dyn_MEM_malloc_cb malloc_cb; - dyn_MEM_realloc_cb realloc_cb; - dyn_MEM_free_cb free_cb; -} dynamic_MEM_fns; -/* - * FIXME: Perhaps the memory and locking code (crypto.h) should declare and - * use these types so we (and any other dependant code) can simplify a bit?? - */ -typedef void (*dyn_lock_locking_cb) (int, int, const char *, int); -typedef int (*dyn_lock_add_lock_cb) (int *, int, int, const char *, int); -typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb) (const char *, - int); -typedef void (*dyn_dynlock_lock_cb) (int, struct CRYPTO_dynlock_value *, - const char *, int); -typedef void (*dyn_dynlock_destroy_cb) (struct CRYPTO_dynlock_value *, - const char *, int); -typedef struct st_dynamic_LOCK_fns { - dyn_lock_locking_cb lock_locking_cb; - dyn_lock_add_lock_cb lock_add_lock_cb; - dyn_dynlock_create_cb dynlock_create_cb; - dyn_dynlock_lock_cb dynlock_lock_cb; - dyn_dynlock_destroy_cb dynlock_destroy_cb; -} dynamic_LOCK_fns; -/* The top-level structure */ -typedef struct st_dynamic_fns { - void *static_state; - const ERR_FNS *err_fns; - const CRYPTO_EX_DATA_IMPL *ex_data_fns; - dynamic_MEM_fns mem_fns; - dynamic_LOCK_fns lock_fns; -} dynamic_fns; - -/* - * The version checking function should be of this prototype. NB: The - * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading - * code. If this function returns zero, it indicates a (potential) version - * incompatibility and the loaded library doesn't believe it can proceed. - * Otherwise, the returned value is the (latest) version supported by the - * loading library. The loader may still decide that the loaded code's - * version is unsatisfactory and could veto the load. The function is - * expected to be implemented with the symbol name "v_check", and a default - * implementation can be fully instantiated with - * IMPLEMENT_DYNAMIC_CHECK_FN(). - */ -typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version); -# define IMPLEMENT_DYNAMIC_CHECK_FN() \ - OPENSSL_EXPORT unsigned long v_check(unsigned long v); \ - OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \ - if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ - return 0; } - -/* - * This function is passed the ENGINE structure to initialise with its own - * function and command settings. It should not adjust the structural or - * functional reference counts. If this function returns zero, (a) the load - * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto - * the structure, and (c) the shared library will be unloaded. So - * implementations should do their own internal cleanup in failure - * circumstances otherwise they could leak. The 'id' parameter, if non-NULL, - * represents the ENGINE id that the loader is looking for. If this is NULL, - * the shared library can choose to return failure or to initialise a - * 'default' ENGINE. If non-NULL, the shared library must initialise only an - * ENGINE matching the passed 'id'. The function is expected to be - * implemented with the symbol name "bind_engine". A standard implementation - * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter - * 'fn' is a callback function that populates the ENGINE structure and - * returns an int value (zero for failure). 'fn' should have prototype; - * [static] int fn(ENGINE *e, const char *id); - */ -typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, - const dynamic_fns *fns); -# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ - OPENSSL_EXPORT \ - int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ - OPENSSL_EXPORT \ - int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ - if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ - if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ - fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ - return 0; \ - CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \ - CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \ - CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \ - CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \ - CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \ - if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ - return 0; \ - if(!ERR_set_implementation(fns->err_fns)) return 0; \ - skip_cbs: \ - if(!fn(e,id)) return 0; \ - return 1; } - -/* - * If the loading application (or library) and the loaded ENGINE library - * share the same static data (eg. they're both dynamically linked to the - * same libcrypto.so) we need a way to avoid trying to set system callbacks - - * this would fail, and for the same reason that it's unnecessary to try. If - * the loaded ENGINE has (or gets from through the loader) its own copy of - * the libcrypto static data, we will need to set the callbacks. The easiest - * way to detect this is to have a function that returns a pointer to some - * static data and let the loading application and loaded ENGINE compare - * their respective values. - */ -void *ENGINE_get_static_state(void); - -# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) -void ENGINE_setup_bsd_cryptodev(void); -# endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_ENGINE_strings(void); - -/* Error codes for the ENGINE functions. */ - -/* Function codes. */ -# define ENGINE_F_DYNAMIC_CTRL 180 -# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 -# define ENGINE_F_DYNAMIC_LOAD 182 -# define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 -# define ENGINE_F_ENGINE_ADD 105 -# define ENGINE_F_ENGINE_BY_ID 106 -# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 -# define ENGINE_F_ENGINE_CTRL 142 -# define ENGINE_F_ENGINE_CTRL_CMD 178 -# define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 -# define ENGINE_F_ENGINE_FINISH 107 -# define ENGINE_F_ENGINE_FREE_UTIL 108 -# define ENGINE_F_ENGINE_GET_CIPHER 185 -# define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 -# define ENGINE_F_ENGINE_GET_DIGEST 186 -# define ENGINE_F_ENGINE_GET_NEXT 115 -# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 -# define ENGINE_F_ENGINE_GET_PKEY_METH 192 -# define ENGINE_F_ENGINE_GET_PREV 116 -# define ENGINE_F_ENGINE_INIT 119 -# define ENGINE_F_ENGINE_LIST_ADD 120 -# define ENGINE_F_ENGINE_LIST_REMOVE 121 -# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 -# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 -# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 -# define ENGINE_F_ENGINE_NEW 122 -# define ENGINE_F_ENGINE_REMOVE 123 -# define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 -# define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 -# define ENGINE_F_ENGINE_SET_ID 129 -# define ENGINE_F_ENGINE_SET_NAME 130 -# define ENGINE_F_ENGINE_TABLE_REGISTER 184 -# define ENGINE_F_ENGINE_UNLOAD_KEY 152 -# define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 -# define ENGINE_F_ENGINE_UP_REF 190 -# define ENGINE_F_INT_CTRL_HELPER 172 -# define ENGINE_F_INT_ENGINE_CONFIGURE 188 -# define ENGINE_F_INT_ENGINE_MODULE_INIT 187 -# define ENGINE_F_LOG_MESSAGE 141 - -/* Reason codes. */ -# define ENGINE_R_ALREADY_LOADED 100 -# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 -# define ENGINE_R_CMD_NOT_EXECUTABLE 134 -# define ENGINE_R_COMMAND_TAKES_INPUT 135 -# define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 -# define ENGINE_R_CONFLICTING_ENGINE_ID 103 -# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 -# define ENGINE_R_DH_NOT_IMPLEMENTED 139 -# define ENGINE_R_DSA_NOT_IMPLEMENTED 140 -# define ENGINE_R_DSO_FAILURE 104 -# define ENGINE_R_DSO_NOT_FOUND 132 -# define ENGINE_R_ENGINES_SECTION_ERROR 148 -# define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 -# define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 -# define ENGINE_R_ENGINE_SECTION_ERROR 149 -# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 -# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 -# define ENGINE_R_FINISH_FAILED 106 -# define ENGINE_R_GET_HANDLE_FAILED 107 -# define ENGINE_R_ID_OR_NAME_MISSING 108 -# define ENGINE_R_INIT_FAILED 109 -# define ENGINE_R_INTERNAL_LIST_ERROR 110 -# define ENGINE_R_INVALID_ARGUMENT 143 -# define ENGINE_R_INVALID_CMD_NAME 137 -# define ENGINE_R_INVALID_CMD_NUMBER 138 -# define ENGINE_R_INVALID_INIT_VALUE 151 -# define ENGINE_R_INVALID_STRING 150 -# define ENGINE_R_NOT_INITIALISED 117 -# define ENGINE_R_NOT_LOADED 112 -# define ENGINE_R_NO_CONTROL_FUNCTION 120 -# define ENGINE_R_NO_INDEX 144 -# define ENGINE_R_NO_LOAD_FUNCTION 125 -# define ENGINE_R_NO_REFERENCE 130 -# define ENGINE_R_NO_SUCH_ENGINE 116 -# define ENGINE_R_NO_UNLOAD_FUNCTION 126 -# define ENGINE_R_PROVIDE_PARAMETERS 113 -# define ENGINE_R_RSA_NOT_IMPLEMENTED 141 -# define ENGINE_R_UNIMPLEMENTED_CIPHER 146 -# define ENGINE_R_UNIMPLEMENTED_DIGEST 147 -# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 -# define ENGINE_R_VERSION_INCOMPATIBILITY 145 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/err.c b/Sources/COpenSSL/err.c deleted file mode 100644 index 90254493..00000000 --- a/Sources/COpenSSL/err.c +++ /dev/null @@ -1,1158 +0,0 @@ -/* crypto/err/err.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include "cryptlib.h" -#include "lhash.h" -#include "crypto.h" -#include "buffer.h" -#include "bio.h" -#include "err.h" - -DECLARE_LHASH_OF(ERR_STRING_DATA); -DECLARE_LHASH_OF(ERR_STATE); - -static void err_load_strings(int lib, ERR_STRING_DATA *str); - -static void ERR_STATE_free(ERR_STATE *s); -#ifndef OPENSSL_NO_ERR -static ERR_STRING_DATA ERR_str_libraries[] = { - {ERR_PACK(ERR_LIB_NONE, 0, 0), "unknown library"}, - {ERR_PACK(ERR_LIB_SYS, 0, 0), "system library"}, - {ERR_PACK(ERR_LIB_BN, 0, 0), "bignum routines"}, - {ERR_PACK(ERR_LIB_RSA, 0, 0), "rsa routines"}, - {ERR_PACK(ERR_LIB_DH, 0, 0), "Diffie-Hellman routines"}, - {ERR_PACK(ERR_LIB_EVP, 0, 0), "digital envelope routines"}, - {ERR_PACK(ERR_LIB_BUF, 0, 0), "memory buffer routines"}, - {ERR_PACK(ERR_LIB_OBJ, 0, 0), "object identifier routines"}, - {ERR_PACK(ERR_LIB_PEM, 0, 0), "PEM routines"}, - {ERR_PACK(ERR_LIB_DSA, 0, 0), "dsa routines"}, - {ERR_PACK(ERR_LIB_X509, 0, 0), "x509 certificate routines"}, - {ERR_PACK(ERR_LIB_ASN1, 0, 0), "asn1 encoding routines"}, - {ERR_PACK(ERR_LIB_CONF, 0, 0), "configuration file routines"}, - {ERR_PACK(ERR_LIB_CRYPTO, 0, 0), "common libcrypto routines"}, - {ERR_PACK(ERR_LIB_EC, 0, 0), "elliptic curve routines"}, - {ERR_PACK(ERR_LIB_SSL, 0, 0), "SSL routines"}, - {ERR_PACK(ERR_LIB_BIO, 0, 0), "BIO routines"}, - {ERR_PACK(ERR_LIB_PKCS7, 0, 0), "PKCS7 routines"}, - {ERR_PACK(ERR_LIB_X509V3, 0, 0), "X509 V3 routines"}, - {ERR_PACK(ERR_LIB_PKCS12, 0, 0), "PKCS12 routines"}, - {ERR_PACK(ERR_LIB_RAND, 0, 0), "random number generator"}, - {ERR_PACK(ERR_LIB_DSO, 0, 0), "DSO support routines"}, - {ERR_PACK(ERR_LIB_TS, 0, 0), "time stamp routines"}, - {ERR_PACK(ERR_LIB_ENGINE, 0, 0), "engine routines"}, - {ERR_PACK(ERR_LIB_OCSP, 0, 0), "OCSP routines"}, - {ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"}, - {ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"}, - {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"}, - {0, NULL}, -}; - -static ERR_STRING_DATA ERR_str_functs[] = { - {ERR_PACK(0, SYS_F_FOPEN, 0), "fopen"}, - {ERR_PACK(0, SYS_F_CONNECT, 0), "connect"}, - {ERR_PACK(0, SYS_F_GETSERVBYNAME, 0), "getservbyname"}, - {ERR_PACK(0, SYS_F_SOCKET, 0), "socket"}, - {ERR_PACK(0, SYS_F_IOCTLSOCKET, 0), "ioctlsocket"}, - {ERR_PACK(0, SYS_F_BIND, 0), "bind"}, - {ERR_PACK(0, SYS_F_LISTEN, 0), "listen"}, - {ERR_PACK(0, SYS_F_ACCEPT, 0), "accept"}, -# ifdef OPENSSL_SYS_WINDOWS - {ERR_PACK(0, SYS_F_WSASTARTUP, 0), "WSAstartup"}, -# endif - {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"}, - {ERR_PACK(0, SYS_F_FREAD, 0), "fread"}, - {ERR_PACK(0, SYS_F_FFLUSH, 0), "fflush"}, - {0, NULL}, -}; - -static ERR_STRING_DATA ERR_str_reasons[] = { - {ERR_R_SYS_LIB, "system lib"}, - {ERR_R_BN_LIB, "BN lib"}, - {ERR_R_RSA_LIB, "RSA lib"}, - {ERR_R_DH_LIB, "DH lib"}, - {ERR_R_EVP_LIB, "EVP lib"}, - {ERR_R_BUF_LIB, "BUF lib"}, - {ERR_R_OBJ_LIB, "OBJ lib"}, - {ERR_R_PEM_LIB, "PEM lib"}, - {ERR_R_DSA_LIB, "DSA lib"}, - {ERR_R_X509_LIB, "X509 lib"}, - {ERR_R_ASN1_LIB, "ASN1 lib"}, - {ERR_R_CONF_LIB, "CONF lib"}, - {ERR_R_CRYPTO_LIB, "CRYPTO lib"}, - {ERR_R_EC_LIB, "EC lib"}, - {ERR_R_SSL_LIB, "SSL lib"}, - {ERR_R_BIO_LIB, "BIO lib"}, - {ERR_R_PKCS7_LIB, "PKCS7 lib"}, - {ERR_R_X509V3_LIB, "X509V3 lib"}, - {ERR_R_PKCS12_LIB, "PKCS12 lib"}, - {ERR_R_RAND_LIB, "RAND lib"}, - {ERR_R_DSO_LIB, "DSO lib"}, - {ERR_R_ENGINE_LIB, "ENGINE lib"}, - {ERR_R_OCSP_LIB, "OCSP lib"}, - {ERR_R_TS_LIB, "TS lib"}, - - {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"}, - {ERR_R_BAD_ASN1_OBJECT_HEADER, "bad asn1 object header"}, - {ERR_R_BAD_GET_ASN1_OBJECT_CALL, "bad get asn1 object call"}, - {ERR_R_EXPECTING_AN_ASN1_SEQUENCE, "expecting an asn1 sequence"}, - {ERR_R_ASN1_LENGTH_MISMATCH, "asn1 length mismatch"}, - {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"}, - - {ERR_R_FATAL, "fatal"}, - {ERR_R_MALLOC_FAILURE, "malloc failure"}, - {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, - "called a function you should not call"}, - {ERR_R_PASSED_NULL_PARAMETER, "passed a null parameter"}, - {ERR_R_INTERNAL_ERROR, "internal error"}, - {ERR_R_DISABLED, "called a function that was disabled at compile-time"}, - - {0, NULL}, -}; -#endif - -/* Define the predeclared (but externally opaque) "ERR_FNS" type */ -struct st_ERR_FNS { - /* Works on the "error_hash" string table */ - LHASH_OF(ERR_STRING_DATA) *(*cb_err_get) (int create); - void (*cb_err_del) (void); - ERR_STRING_DATA *(*cb_err_get_item) (const ERR_STRING_DATA *); - ERR_STRING_DATA *(*cb_err_set_item) (ERR_STRING_DATA *); - ERR_STRING_DATA *(*cb_err_del_item) (ERR_STRING_DATA *); - /* Works on the "thread_hash" error-state table */ - LHASH_OF(ERR_STATE) *(*cb_thread_get) (int create); - void (*cb_thread_release) (LHASH_OF(ERR_STATE) **hash); - ERR_STATE *(*cb_thread_get_item) (const ERR_STATE *); - ERR_STATE *(*cb_thread_set_item) (ERR_STATE *); - void (*cb_thread_del_item) (const ERR_STATE *); - /* Returns the next available error "library" numbers */ - int (*cb_get_next_lib) (void); -}; - -/* Predeclarations of the "err_defaults" functions */ -static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create); -static void int_err_del(void); -static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); -static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); -static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); -static LHASH_OF(ERR_STATE) *int_thread_get(int create); -static void int_thread_release(LHASH_OF(ERR_STATE) **hash); -static ERR_STATE *int_thread_get_item(const ERR_STATE *); -static ERR_STATE *int_thread_set_item(ERR_STATE *); -static void int_thread_del_item(const ERR_STATE *); -static int int_err_get_next_lib(void); -/* The static ERR_FNS table using these defaults functions */ -static const ERR_FNS err_defaults = { - int_err_get, - int_err_del, - int_err_get_item, - int_err_set_item, - int_err_del_item, - int_thread_get, - int_thread_release, - int_thread_get_item, - int_thread_set_item, - int_thread_del_item, - int_err_get_next_lib -}; - -/* The replacable table of ERR_FNS functions we use at run-time */ -static const ERR_FNS *err_fns = NULL; - -/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */ -#define ERRFN(a) err_fns->cb_##a - -/* - * The internal state used by "err_defaults" - as such, the setting, reading, - * creating, and deleting of this data should only be permitted via the - * "err_defaults" functions. This way, a linked module can completely defer - * all ERR state operation (together with requisite locking) to the - * implementations and state in the loading application. - */ -static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; -static LHASH_OF(ERR_STATE) *int_thread_hash = NULL; -static int int_thread_hash_references = 0; -static int int_err_library_number = ERR_LIB_USER; - -/* - * Internal function that checks whether "err_fns" is set and if not, sets it - * to the defaults. - */ -static void err_fns_check(void) -{ - if (err_fns) - return; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!err_fns) - err_fns = &err_defaults; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); -} - -/* API functions to get or set the underlying ERR functions. */ - -const ERR_FNS *ERR_get_implementation(void) -{ - err_fns_check(); - return err_fns; -} - -int ERR_set_implementation(const ERR_FNS *fns) -{ - int ret = 0; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - /* - * It's too late if 'err_fns' is non-NULL. BTW: not much point setting an - * error is there?! - */ - if (!err_fns) { - err_fns = fns; - ret = 1; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return ret; -} - -/* - * These are the callbacks provided to "lh_new()" when creating the LHASH - * tables internal to the "err_defaults" implementation. - */ - -static unsigned long get_error_values(int inc, int top, const char **file, - int *line, const char **data, - int *flags); - -/* The internal functions used in the "err_defaults" implementation */ - -static unsigned long err_string_data_hash(const ERR_STRING_DATA *a) -{ - unsigned long ret, l; - - l = a->error; - ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l); - return (ret ^ ret % 19 * 13); -} - -static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA) - -static int err_string_data_cmp(const ERR_STRING_DATA *a, - const ERR_STRING_DATA *b) -{ - return (int)(a->error - b->error); -} - -static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA) - -static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create) -{ - LHASH_OF(ERR_STRING_DATA) *ret = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!int_error_hash && create) { - CRYPTO_push_info("int_err_get (err.c)"); - int_error_hash = lh_ERR_STRING_DATA_new(); - CRYPTO_pop_info(); - } - if (int_error_hash) - ret = int_error_hash; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return ret; -} - -static void int_err_del(void) -{ - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (int_error_hash) { - lh_ERR_STRING_DATA_free(int_error_hash); - int_error_hash = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); -} - -static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) -{ - ERR_STRING_DATA *p; - LHASH_OF(ERR_STRING_DATA) *hash; - - err_fns_check(); - hash = ERRFN(err_get) (0); - if (!hash) - return NULL; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - p = lh_ERR_STRING_DATA_retrieve(hash, d); - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - - return p; -} - -static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d) -{ - ERR_STRING_DATA *p; - LHASH_OF(ERR_STRING_DATA) *hash; - - err_fns_check(); - hash = ERRFN(err_get) (1); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = lh_ERR_STRING_DATA_insert(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return p; -} - -static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d) -{ - ERR_STRING_DATA *p; - LHASH_OF(ERR_STRING_DATA) *hash; - - err_fns_check(); - hash = ERRFN(err_get) (0); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = lh_ERR_STRING_DATA_delete(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return p; -} - -static unsigned long err_state_hash(const ERR_STATE *a) -{ - return CRYPTO_THREADID_hash(&a->tid) * 13; -} - -static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE) - -static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b) -{ - return CRYPTO_THREADID_cmp(&a->tid, &b->tid); -} - -static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE) - -static LHASH_OF(ERR_STATE) *int_thread_get(int create) -{ - LHASH_OF(ERR_STATE) *ret = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!int_thread_hash && create) { - CRYPTO_push_info("int_thread_get (err.c)"); - int_thread_hash = lh_ERR_STATE_new(); - CRYPTO_pop_info(); - } - if (int_thread_hash) { - int_thread_hash_references++; - ret = int_thread_hash; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return ret; -} - -static void int_thread_release(LHASH_OF(ERR_STATE) **hash) -{ - int i; - - if (hash == NULL || *hash == NULL) - return; - - i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR); - -#ifdef REF_PRINT - fprintf(stderr, "%4d:%s\n", int_thread_hash_references, "ERR"); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "int_thread_release, bad reference count\n"); - abort(); /* ok */ - } -#endif - *hash = NULL; -} - -static ERR_STATE *int_thread_get_item(const ERR_STATE *d) -{ - ERR_STATE *p; - LHASH_OF(ERR_STATE) *hash; - - err_fns_check(); - hash = ERRFN(thread_get) (0); - if (!hash) - return NULL; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - p = lh_ERR_STATE_retrieve(hash, d); - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release) (&hash); - return p; -} - -static ERR_STATE *int_thread_set_item(ERR_STATE *d) -{ - ERR_STATE *p; - LHASH_OF(ERR_STATE) *hash; - - err_fns_check(); - hash = ERRFN(thread_get) (1); - if (!hash) - return NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = lh_ERR_STATE_insert(hash, d); - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release) (&hash); - return p; -} - -static void int_thread_del_item(const ERR_STATE *d) -{ - ERR_STATE *p; - LHASH_OF(ERR_STATE) *hash; - - err_fns_check(); - hash = ERRFN(thread_get) (0); - if (!hash) - return; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - p = lh_ERR_STATE_delete(hash, d); - /* make sure we don't leak memory */ - if (int_thread_hash_references == 1 - && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) { - lh_ERR_STATE_free(int_thread_hash); - int_thread_hash = NULL; - } - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - ERRFN(thread_release) (&hash); - if (p) - ERR_STATE_free(p); -} - -static int int_err_get_next_lib(void) -{ - int ret; - - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - ret = int_err_library_number++; - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - - return ret; -} - -#ifndef OPENSSL_NO_ERR -# define NUM_SYS_STR_REASONS 127 -# define LEN_SYS_STR_REASON 32 - -static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; -/* - * SYS_str_reasons is filled with copies of strerror() results at - * initialization. 'errno' values up to 127 should cover all usual errors, - * others will be displayed numerically by ERR_error_string. It is crucial - * that we have something for each reason code that occurs in - * ERR_str_reasons, or bogus reason strings will be returned for SYSerr(), - * which always gets an errno value and never one of those 'standard' reason - * codes. - */ - -static void build_SYS_str_reasons(void) -{ - /* OPENSSL_malloc cannot be used here, use static storage instead */ - static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON]; - int i; - static int init = 1; - - CRYPTO_r_lock(CRYPTO_LOCK_ERR); - if (!init) { - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - return; - } - - CRYPTO_r_unlock(CRYPTO_LOCK_ERR); - CRYPTO_w_lock(CRYPTO_LOCK_ERR); - if (!init) { - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); - return; - } - - for (i = 1; i <= NUM_SYS_STR_REASONS; i++) { - ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; - - str->error = (unsigned long)i; - if (str->string == NULL) { - char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]); - char *src = strerror(i); - if (src != NULL) { - strncpy(*dest, src, sizeof(*dest)); - (*dest)[sizeof(*dest) - 1] = '\0'; - str->string = *dest; - } - } - if (str->string == NULL) - str->string = "unknown"; - } - - /* - * Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, as - * required by ERR_load_strings. - */ - - init = 0; - - CRYPTO_w_unlock(CRYPTO_LOCK_ERR); -} -#endif - -#define err_clear_data(p,i) \ - do { \ - if (((p)->err_data[i] != NULL) && \ - (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \ - { \ - OPENSSL_free((p)->err_data[i]); \ - (p)->err_data[i]=NULL; \ - } \ - (p)->err_data_flags[i]=0; \ - } while(0) - -#define err_clear(p,i) \ - do { \ - (p)->err_flags[i]=0; \ - (p)->err_buffer[i]=0; \ - err_clear_data(p,i); \ - (p)->err_file[i]=NULL; \ - (p)->err_line[i]= -1; \ - } while(0) - -static void ERR_STATE_free(ERR_STATE *s) -{ - int i; - - if (s == NULL) - return; - - for (i = 0; i < ERR_NUM_ERRORS; i++) { - err_clear_data(s, i); - } - OPENSSL_free(s); -} - -void ERR_load_ERR_strings(void) -{ - err_fns_check(); -#ifndef OPENSSL_NO_ERR - err_load_strings(0, ERR_str_libraries); - err_load_strings(0, ERR_str_reasons); - err_load_strings(ERR_LIB_SYS, ERR_str_functs); - build_SYS_str_reasons(); - err_load_strings(ERR_LIB_SYS, SYS_str_reasons); -#endif -} - -static void err_load_strings(int lib, ERR_STRING_DATA *str) -{ - while (str->error) { - if (lib) - str->error |= ERR_PACK(lib, 0, 0); - ERRFN(err_set_item) (str); - str++; - } -} - -void ERR_load_strings(int lib, ERR_STRING_DATA *str) -{ - ERR_load_ERR_strings(); - err_load_strings(lib, str); -} - -void ERR_unload_strings(int lib, ERR_STRING_DATA *str) -{ - while (str->error) { - if (lib) - str->error |= ERR_PACK(lib, 0, 0); - ERRFN(err_del_item) (str); - str++; - } -} - -void ERR_free_strings(void) -{ - err_fns_check(); - ERRFN(err_del) (); -} - -/********************************************************/ - -void ERR_put_error(int lib, int func, int reason, const char *file, int line) -{ - ERR_STATE *es; - -#ifdef _OSD_POSIX - /* - * In the BS2000-OSD POSIX subsystem, the compiler generates path names - * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to - * something sensible. @@@ We shouldn't modify a const string, though. - */ - if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) { - char *end; - - /* Skip the "*POSIX(" prefix */ - file += sizeof("*POSIX(") - 1; - end = &file[strlen(file) - 1]; - if (*end == ')') - *end = '\0'; - /* Optional: use the basename of the path only. */ - if ((end = strrchr(file, '/')) != NULL) - file = &end[1]; - } -#endif - es = ERR_get_state(); - if (es == NULL) - return; - - es->top = (es->top + 1) % ERR_NUM_ERRORS; - if (es->top == es->bottom) - es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; - es->err_flags[es->top] = 0; - es->err_buffer[es->top] = ERR_PACK(lib, func, reason); - es->err_file[es->top] = file; - es->err_line[es->top] = line; - err_clear_data(es, es->top); -} - -void ERR_clear_error(void) -{ - int i; - ERR_STATE *es; - - es = ERR_get_state(); - if (es == NULL) - return; - - for (i = 0; i < ERR_NUM_ERRORS; i++) { - err_clear(es, i); - } - es->top = es->bottom = 0; -} - -unsigned long ERR_get_error(void) -{ - return (get_error_values(1, 0, NULL, NULL, NULL, NULL)); -} - -unsigned long ERR_get_error_line(const char **file, int *line) -{ - return (get_error_values(1, 0, file, line, NULL, NULL)); -} - -unsigned long ERR_get_error_line_data(const char **file, int *line, - const char **data, int *flags) -{ - return (get_error_values(1, 0, file, line, data, flags)); -} - -unsigned long ERR_peek_error(void) -{ - return (get_error_values(0, 0, NULL, NULL, NULL, NULL)); -} - -unsigned long ERR_peek_error_line(const char **file, int *line) -{ - return (get_error_values(0, 0, file, line, NULL, NULL)); -} - -unsigned long ERR_peek_error_line_data(const char **file, int *line, - const char **data, int *flags) -{ - return (get_error_values(0, 0, file, line, data, flags)); -} - -unsigned long ERR_peek_last_error(void) -{ - return (get_error_values(0, 1, NULL, NULL, NULL, NULL)); -} - -unsigned long ERR_peek_last_error_line(const char **file, int *line) -{ - return (get_error_values(0, 1, file, line, NULL, NULL)); -} - -unsigned long ERR_peek_last_error_line_data(const char **file, int *line, - const char **data, int *flags) -{ - return (get_error_values(0, 1, file, line, data, flags)); -} - -static unsigned long get_error_values(int inc, int top, const char **file, - int *line, const char **data, - int *flags) -{ - int i = 0; - ERR_STATE *es; - unsigned long ret; - - es = ERR_get_state(); - if (es == NULL) - return 0; - - if (inc && top) { - if (file) - *file = ""; - if (line) - *line = 0; - if (data) - *data = ""; - if (flags) - *flags = 0; - - return ERR_R_INTERNAL_ERROR; - } - - if (es->bottom == es->top) - return 0; - if (top) - i = es->top; /* last error */ - else - i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ - - ret = es->err_buffer[i]; - if (inc) { - es->bottom = i; - es->err_buffer[i] = 0; - } - - if ((file != NULL) && (line != NULL)) { - if (es->err_file[i] == NULL) { - *file = "NA"; - if (line != NULL) - *line = 0; - } else { - *file = es->err_file[i]; - if (line != NULL) - *line = es->err_line[i]; - } - } - - if (data == NULL) { - if (inc) { - err_clear_data(es, i); - } - } else { - if (es->err_data[i] == NULL) { - *data = ""; - if (flags != NULL) - *flags = 0; - } else { - *data = es->err_data[i]; - if (flags != NULL) - *flags = es->err_data_flags[i]; - } - } - return ret; -} - -void ERR_error_string_n(unsigned long e, char *buf, size_t len) -{ - char lsbuf[64], fsbuf[64], rsbuf[64]; - const char *ls, *fs, *rs; - unsigned long l, f, r; - - if (len == 0) - return; - - l = ERR_GET_LIB(e); - f = ERR_GET_FUNC(e); - r = ERR_GET_REASON(e); - - ls = ERR_lib_error_string(e); - fs = ERR_func_error_string(e); - rs = ERR_reason_error_string(e); - - if (ls == NULL) - BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); - if (fs == NULL) - BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); - if (rs == NULL) - BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); - - BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls ? ls : lsbuf, - fs ? fs : fsbuf, rs ? rs : rsbuf); - if (strlen(buf) == len - 1) { - /* - * output may be truncated; make sure we always have 5 - * colon-separated fields, i.e. 4 colons ... - */ -#define NUM_COLONS 4 - if (len > NUM_COLONS) { /* ... if possible */ - int i; - char *s = buf; - - for (i = 0; i < NUM_COLONS; i++) { - char *colon = strchr(s, ':'); - if (colon == NULL || colon > &buf[len - 1] - NUM_COLONS + i) { - /* - * set colon no. i at last possible position (buf[len-1] - * is the terminating 0) - */ - colon = &buf[len - 1] - NUM_COLONS + i; - *colon = ':'; - } - s = colon + 1; - } - } - } -} - -/* BAD for multi-threading: uses a local buffer if ret == NULL */ -/* - * ERR_error_string_n should be used instead for ret != NULL as - * ERR_error_string cannot know how large the buffer is - */ -char *ERR_error_string(unsigned long e, char *ret) -{ - static char buf[256]; - - if (ret == NULL) - ret = buf; - ERR_error_string_n(e, ret, 256); - - return ret; -} - -LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void) -{ - err_fns_check(); - return ERRFN(err_get) (0); -} - -LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void) -{ - err_fns_check(); - return ERRFN(thread_get) (0); -} - -void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash) -{ - err_fns_check(); - ERRFN(thread_release) (hash); -} - -const char *ERR_lib_error_string(unsigned long e) -{ - ERR_STRING_DATA d, *p; - unsigned long l; - - err_fns_check(); - l = ERR_GET_LIB(e); - d.error = ERR_PACK(l, 0, 0); - p = ERRFN(err_get_item) (&d); - return ((p == NULL) ? NULL : p->string); -} - -const char *ERR_func_error_string(unsigned long e) -{ - ERR_STRING_DATA d, *p; - unsigned long l, f; - - err_fns_check(); - l = ERR_GET_LIB(e); - f = ERR_GET_FUNC(e); - d.error = ERR_PACK(l, f, 0); - p = ERRFN(err_get_item) (&d); - return ((p == NULL) ? NULL : p->string); -} - -const char *ERR_reason_error_string(unsigned long e) -{ - ERR_STRING_DATA d, *p = NULL; - unsigned long l, r; - - err_fns_check(); - l = ERR_GET_LIB(e); - r = ERR_GET_REASON(e); - d.error = ERR_PACK(l, 0, r); - p = ERRFN(err_get_item) (&d); - if (!p) { - d.error = ERR_PACK(0, 0, r); - p = ERRFN(err_get_item) (&d); - } - return ((p == NULL) ? NULL : p->string); -} - -void ERR_remove_thread_state(const CRYPTO_THREADID *id) -{ - ERR_STATE tmp; - - if (id) - CRYPTO_THREADID_cpy(&tmp.tid, id); - else - CRYPTO_THREADID_current(&tmp.tid); - err_fns_check(); - /* - * thread_del_item automatically destroys the LHASH if the number of - * items reaches zero. - */ - ERRFN(thread_del_item) (&tmp); -} - -#ifndef OPENSSL_NO_DEPRECATED -void ERR_remove_state(unsigned long pid) -{ - ERR_remove_thread_state(NULL); -} -#endif - -ERR_STATE *ERR_get_state(void) -{ - ERR_STATE *ret, tmp, *tmpp = NULL; - int i; - CRYPTO_THREADID tid; - - err_fns_check(); - CRYPTO_THREADID_current(&tid); - CRYPTO_THREADID_cpy(&tmp.tid, &tid); - ret = ERRFN(thread_get_item) (&tmp); - - /* ret == the error state, if NULL, make a new one */ - if (ret == NULL) { - ret = (ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); - if (ret == NULL) - return NULL; - CRYPTO_THREADID_cpy(&ret->tid, &tid); - ret->top = 0; - ret->bottom = 0; - for (i = 0; i < ERR_NUM_ERRORS; i++) { - ret->err_data[i] = NULL; - ret->err_data_flags[i] = 0; - } - tmpp = ERRFN(thread_set_item) (ret); - /* To check if insertion failed, do a get. */ - if (ERRFN(thread_get_item) (ret) != ret) { - ERR_STATE_free(ret); /* could not insert it */ - return NULL; - } - /* - * If a race occured in this function and we came second, tmpp is the - * first one that we just replaced. - */ - if (tmpp) - ERR_STATE_free(tmpp); - } - return ret; -} - -int ERR_get_next_error_library(void) -{ - err_fns_check(); - return ERRFN(get_next_lib) (); -} - -void ERR_set_error_data(char *data, int flags) -{ - ERR_STATE *es; - int i; - - es = ERR_get_state(); - if (es == NULL) - return; - - i = es->top; - - err_clear_data(es, i); - es->err_data[i] = data; - es->err_data_flags[i] = flags; -} - -void ERR_add_error_data(int num, ...) -{ - va_list args; - va_start(args, num); - ERR_add_error_vdata(num, args); - va_end(args); -} - -void ERR_add_error_vdata(int num, va_list args) -{ - int i, n, s; - char *str, *p, *a; - - s = 80; - str = OPENSSL_malloc(s + 1); - if (str == NULL) - return; - str[0] = '\0'; - - n = 0; - for (i = 0; i < num; i++) { - a = va_arg(args, char *); - /* ignore NULLs, thanks to Bob Beck */ - if (a != NULL) { - n += strlen(a); - if (n > s) { - s = n + 20; - p = OPENSSL_realloc(str, s + 1); - if (p == NULL) { - OPENSSL_free(str); - return; - } else - str = p; - } - BUF_strlcat(str, a, (size_t)s + 1); - } - } - ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING); -} - -int ERR_set_mark(void) -{ - ERR_STATE *es; - - es = ERR_get_state(); - if (es == NULL) - return 0; - - if (es->bottom == es->top) - return 0; - es->err_flags[es->top] |= ERR_FLAG_MARK; - return 1; -} - -int ERR_pop_to_mark(void) -{ - ERR_STATE *es; - - es = ERR_get_state(); - if (es == NULL) - return 0; - - while (es->bottom != es->top - && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { - err_clear(es, es->top); - es->top -= 1; - if (es->top == -1) - es->top = ERR_NUM_ERRORS - 1; - } - - if (es->bottom == es->top) - return 0; - es->err_flags[es->top] &= ~ERR_FLAG_MARK; - return 1; -} diff --git a/Sources/COpenSSL/err.h b/Sources/COpenSSL/err.h deleted file mode 100644 index 250af838..00000000 --- a/Sources/COpenSSL/err.h +++ /dev/null @@ -1,390 +0,0 @@ -/* crypto/err/err.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_ERR_H -# define HEADER_ERR_H - -# include "e_os2.h" - -# ifndef OPENSSL_NO_FP_API -# include -# include -# endif - -# include "ossl_typ.h" -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# ifndef OPENSSL_NO_LHASH -# include "lhash.h" -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -# ifndef OPENSSL_NO_ERR -# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) -# else -# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) -# endif - -# include - -# define ERR_TXT_MALLOCED 0x01 -# define ERR_TXT_STRING 0x02 - -# define ERR_FLAG_MARK 0x01 - -# define ERR_NUM_ERRORS 16 -typedef struct err_state_st { - CRYPTO_THREADID tid; - int err_flags[ERR_NUM_ERRORS]; - unsigned long err_buffer[ERR_NUM_ERRORS]; - char *err_data[ERR_NUM_ERRORS]; - int err_data_flags[ERR_NUM_ERRORS]; - const char *err_file[ERR_NUM_ERRORS]; - int err_line[ERR_NUM_ERRORS]; - int top, bottom; -} ERR_STATE; - -/* library */ -# define ERR_LIB_NONE 1 -# define ERR_LIB_SYS 2 -# define ERR_LIB_BN 3 -# define ERR_LIB_RSA 4 -# define ERR_LIB_DH 5 -# define ERR_LIB_EVP 6 -# define ERR_LIB_BUF 7 -# define ERR_LIB_OBJ 8 -# define ERR_LIB_PEM 9 -# define ERR_LIB_DSA 10 -# define ERR_LIB_X509 11 -/* #define ERR_LIB_METH 12 */ -# define ERR_LIB_ASN1 13 -# define ERR_LIB_CONF 14 -# define ERR_LIB_CRYPTO 15 -# define ERR_LIB_EC 16 -# define ERR_LIB_SSL 20 -/* #define ERR_LIB_SSL23 21 */ -/* #define ERR_LIB_SSL2 22 */ -/* #define ERR_LIB_SSL3 23 */ -/* #define ERR_LIB_RSAREF 30 */ -/* #define ERR_LIB_PROXY 31 */ -# define ERR_LIB_BIO 32 -# define ERR_LIB_PKCS7 33 -# define ERR_LIB_X509V3 34 -# define ERR_LIB_PKCS12 35 -# define ERR_LIB_RAND 36 -# define ERR_LIB_DSO 37 -# define ERR_LIB_ENGINE 38 -# define ERR_LIB_OCSP 39 -# define ERR_LIB_UI 40 -# define ERR_LIB_COMP 41 -# define ERR_LIB_ECDSA 42 -# define ERR_LIB_ECDH 43 -# define ERR_LIB_STORE 44 -# define ERR_LIB_FIPS 45 -# define ERR_LIB_CMS 46 -# define ERR_LIB_TS 47 -# define ERR_LIB_HMAC 48 -# define ERR_LIB_JPAKE 49 - -# define ERR_LIB_USER 128 - -# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__) -# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__) -# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__) -# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__) -# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__) -# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__) -# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__) -# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__) -# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__) -# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__) -# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__) -# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__) -# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__) -# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__) -# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__) -# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__) -# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__) -# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__) -# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__) -# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__) -# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__) -# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__) -# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__) -# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__) -# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__) -# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) -# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) -# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) -# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) -# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) -# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) -# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) -# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) - -/* - * Borland C seems too stupid to be able to shift and do longs in the - * pre-processor :-( - */ -# define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)*0x1000000)| \ - ((((unsigned long)f)&0xfffL)*0x1000)| \ - ((((unsigned long)r)&0xfffL))) -# define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL) -# define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL) -# define ERR_GET_REASON(l) (int)((l)&0xfffL) -# define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL) - -/* OS functions */ -# define SYS_F_FOPEN 1 -# define SYS_F_CONNECT 2 -# define SYS_F_GETSERVBYNAME 3 -# define SYS_F_SOCKET 4 -# define SYS_F_IOCTLSOCKET 5 -# define SYS_F_BIND 6 -# define SYS_F_LISTEN 7 -# define SYS_F_ACCEPT 8 -# define SYS_F_WSASTARTUP 9/* Winsock stuff */ -# define SYS_F_OPENDIR 10 -# define SYS_F_FREAD 11 -# define SYS_F_FFLUSH 18 - -/* reasons */ -# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ -# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */ -# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */ -# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */ -# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */ -# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */ -# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */ -# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */ -# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */ -# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */ -# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */ -# define ERR_R_CONF_LIB ERR_LIB_CONF/* 14 */ -# define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO/* 15 */ -# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */ -# define ERR_R_SSL_LIB ERR_LIB_SSL/* 20 */ -# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */ -# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */ -# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */ -# define ERR_R_PKCS12_LIB ERR_LIB_PKCS12/* 35 */ -# define ERR_R_RAND_LIB ERR_LIB_RAND/* 36 */ -# define ERR_R_DSO_LIB ERR_LIB_DSO/* 37 */ -# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ -# define ERR_R_OCSP_LIB ERR_LIB_OCSP/* 39 */ -# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ -# define ERR_R_COMP_LIB ERR_LIB_COMP/* 41 */ -# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ -# define ERR_R_ECDH_LIB ERR_LIB_ECDH/* 43 */ -# define ERR_R_STORE_LIB ERR_LIB_STORE/* 44 */ -# define ERR_R_TS_LIB ERR_LIB_TS/* 45 */ - -# define ERR_R_NESTED_ASN1_ERROR 58 -# define ERR_R_BAD_ASN1_OBJECT_HEADER 59 -# define ERR_R_BAD_GET_ASN1_OBJECT_CALL 60 -# define ERR_R_EXPECTING_AN_ASN1_SEQUENCE 61 -# define ERR_R_ASN1_LENGTH_MISMATCH 62 -# define ERR_R_MISSING_ASN1_EOS 63 - -/* fatal error */ -# define ERR_R_FATAL 64 -# define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) -# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) -# define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) -# define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) -# define ERR_R_DISABLED (5|ERR_R_FATAL) - -/* - * 99 is the maximum possible ERR_R_... code, higher values are reserved for - * the individual libraries - */ - -typedef struct ERR_string_data_st { - unsigned long error; - const char *string; -} ERR_STRING_DATA; - -void ERR_put_error(int lib, int func, int reason, const char *file, int line); -void ERR_set_error_data(char *data, int flags); - -unsigned long ERR_get_error(void); -unsigned long ERR_get_error_line(const char **file, int *line); -unsigned long ERR_get_error_line_data(const char **file, int *line, - const char **data, int *flags); -unsigned long ERR_peek_error(void); -unsigned long ERR_peek_error_line(const char **file, int *line); -unsigned long ERR_peek_error_line_data(const char **file, int *line, - const char **data, int *flags); -unsigned long ERR_peek_last_error(void); -unsigned long ERR_peek_last_error_line(const char **file, int *line); -unsigned long ERR_peek_last_error_line_data(const char **file, int *line, - const char **data, int *flags); -void ERR_clear_error(void); -char *ERR_error_string(unsigned long e, char *buf); -void ERR_error_string_n(unsigned long e, char *buf, size_t len); -const char *ERR_lib_error_string(unsigned long e); -const char *ERR_func_error_string(unsigned long e); -const char *ERR_reason_error_string(unsigned long e); -void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), - void *u); -# ifndef OPENSSL_NO_FP_API -void ERR_print_errors_fp(FILE *fp); -# endif -# ifndef OPENSSL_NO_BIO -void ERR_print_errors(BIO *bp); -# endif -void ERR_add_error_data(int num, ...); -void ERR_add_error_vdata(int num, va_list args); -void ERR_load_strings(int lib, ERR_STRING_DATA str[]); -void ERR_unload_strings(int lib, ERR_STRING_DATA str[]); -void ERR_load_ERR_strings(void); -void ERR_load_crypto_strings(void); -void ERR_free_strings(void); - -void ERR_remove_thread_state(const CRYPTO_THREADID *tid); -# ifndef OPENSSL_NO_DEPRECATED -void ERR_remove_state(unsigned long pid); /* if zero we look it up */ -# endif -ERR_STATE *ERR_get_state(void); - -# ifndef OPENSSL_NO_LHASH -LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void); -LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void); -void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash); -# endif - -int ERR_get_next_error_library(void); - -int ERR_set_mark(void); -int ERR_pop_to_mark(void); - -/* Already defined in ossl_typ.h */ -/* typedef struct st_ERR_FNS ERR_FNS; */ -/* - * An application can use this function and provide the return value to - * loaded modules that should use the application's ERR state/functionality - */ -const ERR_FNS *ERR_get_implementation(void); -/* - * A loaded module should call this function prior to any ERR operations - * using the application's "ERR_FNS". - */ -int ERR_set_implementation(const ERR_FNS *fns); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/err_.c b/Sources/COpenSSL/err_.c deleted file mode 100644 index 31cddd7b..00000000 --- a/Sources/COpenSSL/err_.c +++ /dev/null @@ -1,282 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/err/err_all.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "asn1.h" -#include "bn.h" -#ifndef OPENSSL_NO_EC -# include "ec.h" -#endif -#include "buffer.h" -#include "bio.h" -#ifndef OPENSSL_NO_COMP -# include "comp.h" -#endif -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_ECDSA -# include "ecdsa.h" -#endif -#ifndef OPENSSL_NO_ECDH -# include "ecdh.h" -#endif -#include "evp.h" -#include "objects.h" -#include "pem2.h" -#include "x509.h" -#include "x509v3.h" -#include "conf.h" -#include "pkcs12.h" -#include "rand.h" -#include "dso.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -#include "ui.h" -#include "ocsp.h" -#include "err.h" -#ifdef OPENSSL_FIPS -# include -#endif -#include "ts.h" -#ifndef OPENSSL_NO_CMS -# include "cms.h" -#endif -#ifndef OPENSSL_NO_JPAKE -# include -#endif - -void ERR_load_crypto_strings(void) -{ -#ifndef OPENSSL_NO_ERR - ERR_load_ERR_strings(); /* include error strings for SYSerr */ - ERR_load_BN_strings(); -# ifndef OPENSSL_NO_RSA - ERR_load_RSA_strings(); -# endif -# ifndef OPENSSL_NO_DH - ERR_load_DH_strings(); -# endif - ERR_load_EVP_strings(); - ERR_load_BUF_strings(); - ERR_load_OBJ_strings(); - ERR_load_PEM_strings(); -# ifndef OPENSSL_NO_DSA - ERR_load_DSA_strings(); -# endif - ERR_load_X509_strings(); - ERR_load_ASN1_strings(); - ERR_load_CONF_strings(); - ERR_load_CRYPTO_strings(); -# ifndef OPENSSL_NO_COMP - ERR_load_COMP_strings(); -# endif -# ifndef OPENSSL_NO_EC - ERR_load_EC_strings(); -# endif -# ifndef OPENSSL_NO_ECDSA - ERR_load_ECDSA_strings(); -# endif -# ifndef OPENSSL_NO_ECDH - ERR_load_ECDH_strings(); -# endif - /* skip ERR_load_SSL_strings() because it is not in this library */ - ERR_load_BIO_strings(); - ERR_load_PKCS7_strings(); - ERR_load_X509V3_strings(); - ERR_load_PKCS12_strings(); - ERR_load_RAND_strings(); - ERR_load_DSO_strings(); - ERR_load_TS_strings(); -# ifndef OPENSSL_NO_ENGINE - ERR_load_ENGINE_strings(); -# endif - ERR_load_OCSP_strings(); - ERR_load_UI_strings(); -# ifdef OPENSSL_FIPS - ERR_load_FIPS_strings(); -# endif -# ifndef OPENSSL_NO_CMS - ERR_load_CMS_strings(); -# endif -# ifndef OPENSSL_NO_JPAKE - ERR_load_JPAKE_strings(); -# endif -#endif -} -/* crypto/err/err_prn.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "lhash.h" -#include "crypto.h" -// #include "buffer.h" -// #include "err.h" - -void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), - void *u) -{ - unsigned long l; - char buf[256]; - char buf2[4096]; - const char *file, *data; - int line, flags; - unsigned long es; - CRYPTO_THREADID cur; - - CRYPTO_THREADID_current(&cur); - es = CRYPTO_THREADID_hash(&cur); - while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { - ERR_error_string_n(l, buf, sizeof(buf)); - BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, buf, - file, line, (flags & ERR_TXT_STRING) ? data : ""); - if (cb(buf2, strlen(buf2), u) <= 0) - break; /* abort outputting the error report */ - } -} - -#ifndef OPENSSL_NO_FP_API -static int print_fp(const char *str, size_t len, void *fp) -{ - BIO bio; - - BIO_set(&bio, BIO_s_file()); - BIO_set_fp(&bio, fp, BIO_NOCLOSE); - - return BIO_printf(&bio, "%s", str); -} - -void ERR_print_errors_fp(FILE *fp) -{ - ERR_print_errors_cb(print_fp, fp); -} -#endif - -static int print_bio(const char *str, size_t len, void *bp) -{ - return BIO_write((BIO *)bp, str, len); -} - -void ERR_print_errors(BIO *bp) -{ - ERR_print_errors_cb(print_bio, bp); -} diff --git a/Sources/COpenSSL/evp.h b/Sources/COpenSSL/evp.h deleted file mode 100644 index 0646db43..00000000 --- a/Sources/COpenSSL/evp.h +++ /dev/null @@ -1,1628 +0,0 @@ -/* crypto/evp/evp.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_ENVELOPE_H -# define HEADER_ENVELOPE_H - -# ifdef OPENSSL_ALGORITHM_DEFINES -# include "opensslconf.h" -# else -# define OPENSSL_ALGORITHM_DEFINES -# include "opensslconf.h" -# undef OPENSSL_ALGORITHM_DEFINES -# endif - -# include "ossl_typ.h" - -# include "symhacks.h" - -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif - -/*- -#define EVP_RC2_KEY_SIZE 16 -#define EVP_RC4_KEY_SIZE 16 -#define EVP_BLOWFISH_KEY_SIZE 16 -#define EVP_CAST5_KEY_SIZE 16 -#define EVP_RC5_32_12_16_KEY_SIZE 16 -*/ -# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ -# define EVP_MAX_KEY_LENGTH 64 -# define EVP_MAX_IV_LENGTH 16 -# define EVP_MAX_BLOCK_LENGTH 32 - -# define PKCS5_SALT_LEN 8 -/* Default PKCS#5 iteration count */ -# define PKCS5_DEFAULT_ITER 2048 - -# include "objects.h" - -# define EVP_PK_RSA 0x0001 -# define EVP_PK_DSA 0x0002 -# define EVP_PK_DH 0x0004 -# define EVP_PK_EC 0x0008 -# define EVP_PKT_SIGN 0x0010 -# define EVP_PKT_ENC 0x0020 -# define EVP_PKT_EXCH 0x0040 -# define EVP_PKS_RSA 0x0100 -# define EVP_PKS_DSA 0x0200 -# define EVP_PKS_EC 0x0400 - -# define EVP_PKEY_NONE NID_undef -# define EVP_PKEY_RSA NID_rsaEncryption -# define EVP_PKEY_RSA2 NID_rsa -# define EVP_PKEY_DSA NID_dsa -# define EVP_PKEY_DSA1 NID_dsa_2 -# define EVP_PKEY_DSA2 NID_dsaWithSHA -# define EVP_PKEY_DSA3 NID_dsaWithSHA1 -# define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 -# define EVP_PKEY_DH NID_dhKeyAgreement -# define EVP_PKEY_DHX NID_dhpublicnumber -# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey -# define EVP_PKEY_HMAC NID_hmac -# define EVP_PKEY_CMAC NID_cmac - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Type needs to be a bit field Sub-type needs to be for variations on the - * method, as in, can it do arbitrary encryption.... - */ -struct evp_pkey_st { - int type; - int save_type; - int references; - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *engine; - union { - char *ptr; -# ifndef OPENSSL_NO_RSA - struct rsa_st *rsa; /* RSA */ -# endif -# ifndef OPENSSL_NO_DSA - struct dsa_st *dsa; /* DSA */ -# endif -# ifndef OPENSSL_NO_DH - struct dh_st *dh; /* DH */ -# endif -# ifndef OPENSSL_NO_EC - struct ec_key_st *ec; /* ECC */ -# endif - } pkey; - int save_parameters; - STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ -} /* EVP_PKEY */ ; - -# define EVP_PKEY_MO_SIGN 0x0001 -# define EVP_PKEY_MO_VERIFY 0x0002 -# define EVP_PKEY_MO_ENCRYPT 0x0004 -# define EVP_PKEY_MO_DECRYPT 0x0008 - -# ifndef EVP_MD -struct env_md_st { - int type; - int pkey_type; - int md_size; - unsigned long flags; - int (*init) (EVP_MD_CTX *ctx); - int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); - int (*final) (EVP_MD_CTX *ctx, unsigned char *md); - int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from); - int (*cleanup) (EVP_MD_CTX *ctx); - /* FIXME: prototype these some day */ - int (*sign) (int type, const unsigned char *m, unsigned int m_length, - unsigned char *sigret, unsigned int *siglen, void *key); - int (*verify) (int type, const unsigned char *m, unsigned int m_length, - const unsigned char *sigbuf, unsigned int siglen, - void *key); - int required_pkey_type[5]; /* EVP_PKEY_xxx */ - int block_size; - int ctx_size; /* how big does the ctx->md_data need to be */ - /* control function */ - int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2); -} /* EVP_MD */ ; - -typedef int evp_sign_method(int type, const unsigned char *m, - unsigned int m_length, unsigned char *sigret, - unsigned int *siglen, void *key); -typedef int evp_verify_method(int type, const unsigned char *m, - unsigned int m_length, - const unsigned char *sigbuf, - unsigned int siglen, void *key); - -/* digest can only handle a single block */ -# define EVP_MD_FLAG_ONESHOT 0x0001 - -/* - * digest is a "clone" digest used - * which is a copy of an existing - * one for a specific public key type. - * EVP_dss1() etc - */ -# define EVP_MD_FLAG_PKEY_DIGEST 0x0002 - -/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */ - -# define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004 - -/* DigestAlgorithmIdentifier flags... */ - -# define EVP_MD_FLAG_DIGALGID_MASK 0x0018 - -/* NULL or absent parameter accepted. Use NULL */ - -# define EVP_MD_FLAG_DIGALGID_NULL 0x0000 - -/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ - -# define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 - -/* Custom handling via ctrl */ - -# define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 - -/* Note if suitable for use in FIPS mode */ -# define EVP_MD_FLAG_FIPS 0x0400 - -/* Digest ctrls */ - -# define EVP_MD_CTRL_DIGALGID 0x1 -# define EVP_MD_CTRL_MICALG 0x2 - -/* Minimum Algorithm specific ctrl value */ - -# define EVP_MD_CTRL_ALG_CTRL 0x1000 - -# define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} - -# ifndef OPENSSL_NO_DSA -# define EVP_PKEY_DSA_method (evp_sign_method *)DSA_sign, \ - (evp_verify_method *)DSA_verify, \ - {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \ - EVP_PKEY_DSA4,0} -# else -# define EVP_PKEY_DSA_method EVP_PKEY_NULL_method -# endif - -# ifndef OPENSSL_NO_ECDSA -# define EVP_PKEY_ECDSA_method (evp_sign_method *)ECDSA_sign, \ - (evp_verify_method *)ECDSA_verify, \ - {EVP_PKEY_EC,0,0,0} -# else -# define EVP_PKEY_ECDSA_method EVP_PKEY_NULL_method -# endif - -# ifndef OPENSSL_NO_RSA -# define EVP_PKEY_RSA_method (evp_sign_method *)RSA_sign, \ - (evp_verify_method *)RSA_verify, \ - {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} -# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \ - (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \ - (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \ - {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} -# else -# define EVP_PKEY_RSA_method EVP_PKEY_NULL_method -# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method -# endif - -# endif /* !EVP_MD */ - -struct env_md_ctx_st { - const EVP_MD *digest; - ENGINE *engine; /* functional reference if 'digest' is - * ENGINE-provided */ - unsigned long flags; - void *md_data; - /* Public key context for sign/verify */ - EVP_PKEY_CTX *pctx; - /* Update function: usually copied from EVP_MD */ - int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); -} /* EVP_MD_CTX */ ; - -/* values for EVP_MD_CTX flags */ - -# define EVP_MD_CTX_FLAG_ONESHOT 0x0001/* digest update will be - * called once only */ -# define EVP_MD_CTX_FLAG_CLEANED 0x0002/* context has already been - * cleaned */ -# define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data - * in EVP_MD_CTX_cleanup */ -/* - * FIPS and pad options are ignored in 1.0.0, definitions are here so we - * don't accidentally reuse the values for other purposes. - */ - -# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS - * digest in FIPS mode */ - -/* - * The following PAD options are also currently ignored in 1.0.0, digest - * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() - * instead. - */ -# define EVP_MD_CTX_FLAG_PAD_MASK 0xF0/* RSA mode to use */ -# define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */ -# define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */ -# define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */ - -# define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */ - -struct evp_cipher_st { - int nid; - int block_size; - /* Default value for variable length ciphers */ - int key_len; - int iv_len; - /* Various flags */ - unsigned long flags; - /* init key */ - int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); - /* encrypt/decrypt data */ - int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); - /* cleanup ctx */ - int (*cleanup) (EVP_CIPHER_CTX *); - /* how big ctx->cipher_data needs to be */ - int ctx_size; - /* Populate a ASN1_TYPE with parameters */ - int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); - /* Get parameters from a ASN1_TYPE */ - int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); - /* Miscellaneous operations */ - int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); - /* Application data */ - void *app_data; -} /* EVP_CIPHER */ ; - -/* Values for cipher flags */ - -/* Modes for ciphers */ - -# define EVP_CIPH_STREAM_CIPHER 0x0 -# define EVP_CIPH_ECB_MODE 0x1 -# define EVP_CIPH_CBC_MODE 0x2 -# define EVP_CIPH_CFB_MODE 0x3 -# define EVP_CIPH_OFB_MODE 0x4 -# define EVP_CIPH_CTR_MODE 0x5 -# define EVP_CIPH_GCM_MODE 0x6 -# define EVP_CIPH_CCM_MODE 0x7 -# define EVP_CIPH_XTS_MODE 0x10001 -# define EVP_CIPH_WRAP_MODE 0x10002 -# define EVP_CIPH_MODE 0xF0007 -/* Set if variable length cipher */ -# define EVP_CIPH_VARIABLE_LENGTH 0x8 -/* Set if the iv handling should be done by the cipher itself */ -# define EVP_CIPH_CUSTOM_IV 0x10 -/* Set if the cipher's init() function should be called if key is NULL */ -# define EVP_CIPH_ALWAYS_CALL_INIT 0x20 -/* Call ctrl() to init cipher parameters */ -# define EVP_CIPH_CTRL_INIT 0x40 -/* Don't use standard key length function */ -# define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 -/* Don't use standard block padding */ -# define EVP_CIPH_NO_PADDING 0x100 -/* cipher handles random key generation */ -# define EVP_CIPH_RAND_KEY 0x200 -/* cipher has its own additional copying logic */ -# define EVP_CIPH_CUSTOM_COPY 0x400 -/* Allow use default ASN1 get/set iv */ -# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 -/* Buffer length in bits not bytes: CFB1 mode only */ -# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 -/* Note if suitable for use in FIPS mode */ -# define EVP_CIPH_FLAG_FIPS 0x4000 -/* Allow non FIPS cipher in FIPS mode */ -# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 -/* - * Cipher handles any and all padding logic as well as finalisation. - */ -# define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 -# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 -# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0x400000 - -/* - * Cipher context flag to indicate we can handle wrap mode: if allowed in - * older applications it could overflow buffers. - */ - -# define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0x1 - -/* ctrl() values */ - -# define EVP_CTRL_INIT 0x0 -# define EVP_CTRL_SET_KEY_LENGTH 0x1 -# define EVP_CTRL_GET_RC2_KEY_BITS 0x2 -# define EVP_CTRL_SET_RC2_KEY_BITS 0x3 -# define EVP_CTRL_GET_RC5_ROUNDS 0x4 -# define EVP_CTRL_SET_RC5_ROUNDS 0x5 -# define EVP_CTRL_RAND_KEY 0x6 -# define EVP_CTRL_PBE_PRF_NID 0x7 -# define EVP_CTRL_COPY 0x8 -# define EVP_CTRL_GCM_SET_IVLEN 0x9 -# define EVP_CTRL_GCM_GET_TAG 0x10 -# define EVP_CTRL_GCM_SET_TAG 0x11 -# define EVP_CTRL_GCM_SET_IV_FIXED 0x12 -# define EVP_CTRL_GCM_IV_GEN 0x13 -# define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN -# define EVP_CTRL_CCM_GET_TAG EVP_CTRL_GCM_GET_TAG -# define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG -# define EVP_CTRL_CCM_SET_L 0x14 -# define EVP_CTRL_CCM_SET_MSGLEN 0x15 -/* - * AEAD cipher deduces payload length and returns number of bytes required to - * store MAC and eventual padding. Subsequent call to EVP_Cipher even - * appends/verifies MAC. - */ -# define EVP_CTRL_AEAD_TLS1_AAD 0x16 -/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ -# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 -/* Set the GCM invocation field, decrypt only */ -# define EVP_CTRL_GCM_SET_IV_INV 0x18 - -# define EVP_CTRL_TLS1_1_MULTIBLOCK_AAD 0x19 -# define EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT 0x1a -# define EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT 0x1b -# define EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE 0x1c - -/* RFC 5246 defines additional data to be 13 bytes in length */ -# define EVP_AEAD_TLS1_AAD_LEN 13 - -typedef struct { - unsigned char *out; - const unsigned char *inp; - size_t len; - unsigned int interleave; -} EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM; - -/* GCM TLS constants */ -/* Length of fixed part of IV derived from PRF */ -# define EVP_GCM_TLS_FIXED_IV_LEN 4 -/* Length of explicit part of IV part of TLS records */ -# define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 -/* Length of tag for TLS */ -# define EVP_GCM_TLS_TAG_LEN 16 - -typedef struct evp_cipher_info_st { - const EVP_CIPHER *cipher; - unsigned char iv[EVP_MAX_IV_LENGTH]; -} EVP_CIPHER_INFO; - -struct evp_cipher_ctx_st { - const EVP_CIPHER *cipher; - ENGINE *engine; /* functional reference if 'cipher' is - * ENGINE-provided */ - int encrypt; /* encrypt or decrypt */ - int buf_len; /* number we have left */ - unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ - unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ - unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */ - int num; /* used by cfb/ofb/ctr mode */ - void *app_data; /* application stuff */ - int key_len; /* May change for variable length cipher */ - unsigned long flags; /* Various flags */ - void *cipher_data; /* per EVP data */ - int final_used; - int block_mask; - unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ -} /* EVP_CIPHER_CTX */ ; - -typedef struct evp_Encode_Ctx_st { - /* number saved in a partial encode/decode */ - int num; - /* - * The length is either the output line length (in input bytes) or the - * shortest input line length that is ok. Once decoding begins, the - * length is adjusted up each time a longer line is decoded - */ - int length; - /* data to encode */ - unsigned char enc_data[80]; - /* number read on current line */ - int line_num; - int expect_nl; -} EVP_ENCODE_CTX; - -/* Password based encryption function */ -typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, - int passlen, ASN1_TYPE *param, - const EVP_CIPHER *cipher, const EVP_MD *md, - int en_de); - -# ifndef OPENSSL_NO_RSA -# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ - (char *)(rsa)) -# endif - -# ifndef OPENSSL_NO_DSA -# define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ - (char *)(dsa)) -# endif - -# ifndef OPENSSL_NO_DH -# define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ - (char *)(dh)) -# endif - -# ifndef OPENSSL_NO_EC -# define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ - (char *)(eckey)) -# endif - -/* Add some extra combinations */ -# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) -# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) -# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) -# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) - -int EVP_MD_type(const EVP_MD *md); -# define EVP_MD_nid(e) EVP_MD_type(e) -# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) -int EVP_MD_pkey_type(const EVP_MD *md); -int EVP_MD_size(const EVP_MD *md); -int EVP_MD_block_size(const EVP_MD *md); -unsigned long EVP_MD_flags(const EVP_MD *md); - -const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); -# define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) -# define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) -# define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) - -int EVP_CIPHER_nid(const EVP_CIPHER *cipher); -# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) -int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); -int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); -int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); -unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); -# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) - -const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); -int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); -int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); -int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); -int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); -int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); -void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); -void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); -# define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) -unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); -# define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) - -# define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) -# define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) - -# define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) -# define EVP_SignInit(a,b) EVP_DigestInit(a,b) -# define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) -# define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) -# define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) -# define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) -# define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) -# define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) -# define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) -# define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) - -# ifdef CONST_STRICT -void BIO_set_md(BIO *, const EVP_MD *md); -# else -# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md) -# endif -# define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp) -# define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp) -# define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp) -# define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) -# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp) - -int EVP_Cipher(EVP_CIPHER_CTX *c, - unsigned char *out, const unsigned char *in, unsigned int inl); - -# define EVP_add_cipher_alias(n,alias) \ - OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) -# define EVP_add_digest_alias(n,alias) \ - OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) -# define EVP_delete_cipher_alias(alias) \ - OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); -# define EVP_delete_digest_alias(alias) \ - OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); - -void EVP_MD_CTX_init(EVP_MD_CTX *ctx); -int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); -EVP_MD_CTX *EVP_MD_CTX_create(void); -void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); -int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); -void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); -void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); -int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); -int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); -int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); -int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); -int EVP_Digest(const void *data, size_t count, - unsigned char *md, unsigned int *size, const EVP_MD *type, - ENGINE *impl); - -int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); -int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); -int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); - -int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); -int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, - const char *prompt, int verify); -void EVP_set_pw_prompt(const char *prompt); -char *EVP_get_pw_prompt(void); - -int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, - const unsigned char *salt, const unsigned char *data, - int datal, int count, unsigned char *key, - unsigned char *iv); - -void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); -void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); -int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); - -int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - const unsigned char *key, const unsigned char *iv); -int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv); -int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl); -int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); -int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); - -int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - const unsigned char *key, const unsigned char *iv); -int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv); -int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl); -int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); -int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); - -int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - const unsigned char *key, const unsigned char *iv, - int enc); -int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv, int enc); -int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl); -int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); -int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); - -int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, - EVP_PKEY *pkey); - -int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, - unsigned int siglen, EVP_PKEY *pkey); - -int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); -int EVP_DigestSignFinal(EVP_MD_CTX *ctx, - unsigned char *sigret, size_t *siglen); - -int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); -int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, - const unsigned char *sig, size_t siglen); - -int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, - const unsigned char *ek, int ekl, const unsigned char *iv, - EVP_PKEY *priv); -int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); - -int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, - unsigned char **ek, int *ekl, unsigned char *iv, - EVP_PKEY **pubk, int npubk); -int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); - -void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); -void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl); -void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); -int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); - -void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); -int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl); -int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned - char *out, int *outl); -int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); - -void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); -int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); -EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); -void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); -int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); -int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); -int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); -int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); - -# ifndef OPENSSL_NO_BIO -BIO_METHOD *BIO_f_md(void); -BIO_METHOD *BIO_f_base64(void); -BIO_METHOD *BIO_f_cipher(void); -BIO_METHOD *BIO_f_reliable(void); -void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, - const unsigned char *i, int enc); -# endif - -const EVP_MD *EVP_md_null(void); -# ifndef OPENSSL_NO_MD2 -const EVP_MD *EVP_md2(void); -# endif -# ifndef OPENSSL_NO_MD4 -const EVP_MD *EVP_md4(void); -# endif -# ifndef OPENSSL_NO_MD5 -const EVP_MD *EVP_md5(void); -# endif -# ifndef OPENSSL_NO_SHA -const EVP_MD *EVP_sha(void); -const EVP_MD *EVP_sha1(void); -const EVP_MD *EVP_dss(void); -const EVP_MD *EVP_dss1(void); -const EVP_MD *EVP_ecdsa(void); -# endif -# ifndef OPENSSL_NO_SHA256 -const EVP_MD *EVP_sha224(void); -const EVP_MD *EVP_sha256(void); -# endif -# ifndef OPENSSL_NO_SHA512 -const EVP_MD *EVP_sha384(void); -const EVP_MD *EVP_sha512(void); -# endif -# ifndef OPENSSL_NO_MDC2 -const EVP_MD *EVP_mdc2(void); -# endif -# ifndef OPENSSL_NO_RIPEMD -const EVP_MD *EVP_ripemd160(void); -# endif -# ifndef OPENSSL_NO_WHIRLPOOL -const EVP_MD *EVP_whirlpool(void); -# endif -const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ -# ifndef OPENSSL_NO_DES -const EVP_CIPHER *EVP_des_ecb(void); -const EVP_CIPHER *EVP_des_ede(void); -const EVP_CIPHER *EVP_des_ede3(void); -const EVP_CIPHER *EVP_des_ede_ecb(void); -const EVP_CIPHER *EVP_des_ede3_ecb(void); -const EVP_CIPHER *EVP_des_cfb64(void); -# define EVP_des_cfb EVP_des_cfb64 -const EVP_CIPHER *EVP_des_cfb1(void); -const EVP_CIPHER *EVP_des_cfb8(void); -const EVP_CIPHER *EVP_des_ede_cfb64(void); -# define EVP_des_ede_cfb EVP_des_ede_cfb64 -# if 0 -const EVP_CIPHER *EVP_des_ede_cfb1(void); -const EVP_CIPHER *EVP_des_ede_cfb8(void); -# endif -const EVP_CIPHER *EVP_des_ede3_cfb64(void); -# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 -const EVP_CIPHER *EVP_des_ede3_cfb1(void); -const EVP_CIPHER *EVP_des_ede3_cfb8(void); -const EVP_CIPHER *EVP_des_ofb(void); -const EVP_CIPHER *EVP_des_ede_ofb(void); -const EVP_CIPHER *EVP_des_ede3_ofb(void); -const EVP_CIPHER *EVP_des_cbc(void); -const EVP_CIPHER *EVP_des_ede_cbc(void); -const EVP_CIPHER *EVP_des_ede3_cbc(void); -const EVP_CIPHER *EVP_desx_cbc(void); -const EVP_CIPHER *EVP_des_ede3_wrap(void); -/* - * This should now be supported through the dev_crypto ENGINE. But also, why - * are rc4 and md5 declarations made here inside a "NO_DES" precompiler - * branch? - */ -# if 0 -# ifdef OPENSSL_OPENBSD_DEV_CRYPTO -const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void); -const EVP_CIPHER *EVP_dev_crypto_rc4(void); -const EVP_MD *EVP_dev_crypto_md5(void); -# endif -# endif -# endif -# ifndef OPENSSL_NO_RC4 -const EVP_CIPHER *EVP_rc4(void); -const EVP_CIPHER *EVP_rc4_40(void); -# ifndef OPENSSL_NO_MD5 -const EVP_CIPHER *EVP_rc4_hmac_md5(void); -# endif -# endif -# ifndef OPENSSL_NO_IDEA -const EVP_CIPHER *EVP_idea_ecb(void); -const EVP_CIPHER *EVP_idea_cfb64(void); -# define EVP_idea_cfb EVP_idea_cfb64 -const EVP_CIPHER *EVP_idea_ofb(void); -const EVP_CIPHER *EVP_idea_cbc(void); -# endif -# ifndef OPENSSL_NO_RC2 -const EVP_CIPHER *EVP_rc2_ecb(void); -const EVP_CIPHER *EVP_rc2_cbc(void); -const EVP_CIPHER *EVP_rc2_40_cbc(void); -const EVP_CIPHER *EVP_rc2_64_cbc(void); -const EVP_CIPHER *EVP_rc2_cfb64(void); -# define EVP_rc2_cfb EVP_rc2_cfb64 -const EVP_CIPHER *EVP_rc2_ofb(void); -# endif -# ifndef OPENSSL_NO_BF -const EVP_CIPHER *EVP_bf_ecb(void); -const EVP_CIPHER *EVP_bf_cbc(void); -const EVP_CIPHER *EVP_bf_cfb64(void); -# define EVP_bf_cfb EVP_bf_cfb64 -const EVP_CIPHER *EVP_bf_ofb(void); -# endif -# ifndef OPENSSL_NO_CAST -const EVP_CIPHER *EVP_cast5_ecb(void); -const EVP_CIPHER *EVP_cast5_cbc(void); -const EVP_CIPHER *EVP_cast5_cfb64(void); -# define EVP_cast5_cfb EVP_cast5_cfb64 -const EVP_CIPHER *EVP_cast5_ofb(void); -# endif -# ifndef OPENSSL_NO_RC5 -const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void); -const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void); -const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void); -# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64 -const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void); -# endif -# ifndef OPENSSL_NO_AES -const EVP_CIPHER *EVP_aes_128_ecb(void); -const EVP_CIPHER *EVP_aes_128_cbc(void); -const EVP_CIPHER *EVP_aes_128_cfb1(void); -const EVP_CIPHER *EVP_aes_128_cfb8(void); -const EVP_CIPHER *EVP_aes_128_cfb128(void); -# define EVP_aes_128_cfb EVP_aes_128_cfb128 -const EVP_CIPHER *EVP_aes_128_ofb(void); -const EVP_CIPHER *EVP_aes_128_ctr(void); -const EVP_CIPHER *EVP_aes_128_ccm(void); -const EVP_CIPHER *EVP_aes_128_gcm(void); -const EVP_CIPHER *EVP_aes_128_xts(void); -const EVP_CIPHER *EVP_aes_128_wrap(void); -const EVP_CIPHER *EVP_aes_192_ecb(void); -const EVP_CIPHER *EVP_aes_192_cbc(void); -const EVP_CIPHER *EVP_aes_192_cfb1(void); -const EVP_CIPHER *EVP_aes_192_cfb8(void); -const EVP_CIPHER *EVP_aes_192_cfb128(void); -# define EVP_aes_192_cfb EVP_aes_192_cfb128 -const EVP_CIPHER *EVP_aes_192_ofb(void); -const EVP_CIPHER *EVP_aes_192_ctr(void); -const EVP_CIPHER *EVP_aes_192_ccm(void); -const EVP_CIPHER *EVP_aes_192_gcm(void); -const EVP_CIPHER *EVP_aes_192_wrap(void); -const EVP_CIPHER *EVP_aes_256_ecb(void); -const EVP_CIPHER *EVP_aes_256_cbc(void); -const EVP_CIPHER *EVP_aes_256_cfb1(void); -const EVP_CIPHER *EVP_aes_256_cfb8(void); -const EVP_CIPHER *EVP_aes_256_cfb128(void); -# define EVP_aes_256_cfb EVP_aes_256_cfb128 -const EVP_CIPHER *EVP_aes_256_ofb(void); -const EVP_CIPHER *EVP_aes_256_ctr(void); -const EVP_CIPHER *EVP_aes_256_ccm(void); -const EVP_CIPHER *EVP_aes_256_gcm(void); -const EVP_CIPHER *EVP_aes_256_xts(void); -const EVP_CIPHER *EVP_aes_256_wrap(void); -# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) -const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); -const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); -# endif -# ifndef OPENSSL_NO_SHA256 -const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha256(void); -const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha256(void); -# endif -# endif -# ifndef OPENSSL_NO_CAMELLIA -const EVP_CIPHER *EVP_camellia_128_ecb(void); -const EVP_CIPHER *EVP_camellia_128_cbc(void); -const EVP_CIPHER *EVP_camellia_128_cfb1(void); -const EVP_CIPHER *EVP_camellia_128_cfb8(void); -const EVP_CIPHER *EVP_camellia_128_cfb128(void); -# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 -const EVP_CIPHER *EVP_camellia_128_ofb(void); -const EVP_CIPHER *EVP_camellia_192_ecb(void); -const EVP_CIPHER *EVP_camellia_192_cbc(void); -const EVP_CIPHER *EVP_camellia_192_cfb1(void); -const EVP_CIPHER *EVP_camellia_192_cfb8(void); -const EVP_CIPHER *EVP_camellia_192_cfb128(void); -# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 -const EVP_CIPHER *EVP_camellia_192_ofb(void); -const EVP_CIPHER *EVP_camellia_256_ecb(void); -const EVP_CIPHER *EVP_camellia_256_cbc(void); -const EVP_CIPHER *EVP_camellia_256_cfb1(void); -const EVP_CIPHER *EVP_camellia_256_cfb8(void); -const EVP_CIPHER *EVP_camellia_256_cfb128(void); -# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 -const EVP_CIPHER *EVP_camellia_256_ofb(void); -# endif - -# ifndef OPENSSL_NO_SEED -const EVP_CIPHER *EVP_seed_ecb(void); -const EVP_CIPHER *EVP_seed_cbc(void); -const EVP_CIPHER *EVP_seed_cfb128(void); -# define EVP_seed_cfb EVP_seed_cfb128 -const EVP_CIPHER *EVP_seed_ofb(void); -# endif - -void OPENSSL_add_all_algorithms_noconf(void); -void OPENSSL_add_all_algorithms_conf(void); - -# ifdef OPENSSL_LOAD_CONF -# define OpenSSL_add_all_algorithms() \ - OPENSSL_add_all_algorithms_conf() -# else -# define OpenSSL_add_all_algorithms() \ - OPENSSL_add_all_algorithms_noconf() -# endif - -void OpenSSL_add_all_ciphers(void); -void OpenSSL_add_all_digests(void); -# define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms() -# define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers() -# define SSLeay_add_all_digests() OpenSSL_add_all_digests() - -int EVP_add_cipher(const EVP_CIPHER *cipher); -int EVP_add_digest(const EVP_MD *digest); - -const EVP_CIPHER *EVP_get_cipherbyname(const char *name); -const EVP_MD *EVP_get_digestbyname(const char *name); -void EVP_cleanup(void); - -void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, - const char *from, const char *to, void *x), - void *arg); -void EVP_CIPHER_do_all_sorted(void (*fn) - (const EVP_CIPHER *ciph, const char *from, - const char *to, void *x), void *arg); - -void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph, - const char *from, const char *to, void *x), - void *arg); -void EVP_MD_do_all_sorted(void (*fn) - (const EVP_MD *ciph, const char *from, - const char *to, void *x), void *arg); - -int EVP_PKEY_decrypt_old(unsigned char *dec_key, - const unsigned char *enc_key, int enc_key_len, - EVP_PKEY *private_key); -int EVP_PKEY_encrypt_old(unsigned char *enc_key, - const unsigned char *key, int key_len, - EVP_PKEY *pub_key); -int EVP_PKEY_type(int type); -int EVP_PKEY_id(const EVP_PKEY *pkey); -int EVP_PKEY_base_id(const EVP_PKEY *pkey); -int EVP_PKEY_bits(EVP_PKEY *pkey); -int EVP_PKEY_size(EVP_PKEY *pkey); -int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); -int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); -int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); -void *EVP_PKEY_get0(EVP_PKEY *pkey); - -# ifndef OPENSSL_NO_RSA -struct rsa_st; -int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); -struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); -# endif -# ifndef OPENSSL_NO_DSA -struct dsa_st; -int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); -struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); -# endif -# ifndef OPENSSL_NO_DH -struct dh_st; -int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); -struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); -# endif -# ifndef OPENSSL_NO_EC -struct ec_key_st; -int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); -struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); -# endif - -EVP_PKEY *EVP_PKEY_new(void); -void EVP_PKEY_free(EVP_PKEY *pkey); - -EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, - long length); -int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); - -EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, - long length); -EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, - long length); -int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); - -int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); -int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); -int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); -int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); - -int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); - -int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx); -int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx); -int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx); - -int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); - -int EVP_CIPHER_type(const EVP_CIPHER *ctx); - -/* calls methods */ -int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); -int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); - -/* These are used by EVP_CIPHER methods */ -int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); -int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); - -/* PKCS5 password based encryption */ -int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *cipher, - const EVP_MD *md, int en_de); -int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, - const unsigned char *salt, int saltlen, int iter, - int keylen, unsigned char *out); -int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, - const unsigned char *salt, int saltlen, int iter, - const EVP_MD *digest, int keylen, unsigned char *out); -int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *cipher, - const EVP_MD *md, int en_de); - -void PKCS5_PBE_add(void); - -int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, - ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); - -/* PBE type */ - -/* Can appear as the outermost AlgorithmIdentifier */ -# define EVP_PBE_TYPE_OUTER 0x0 -/* Is an PRF type OID */ -# define EVP_PBE_TYPE_PRF 0x1 - -int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, - int md_nid, EVP_PBE_KEYGEN *keygen); -int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, - EVP_PBE_KEYGEN *keygen); -int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, - EVP_PBE_KEYGEN **pkeygen); -void EVP_PBE_cleanup(void); - -# define ASN1_PKEY_ALIAS 0x1 -# define ASN1_PKEY_DYNAMIC 0x2 -# define ASN1_PKEY_SIGPARAM_NULL 0x4 - -# define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 -# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 -# define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 -# define ASN1_PKEY_CTRL_CMS_SIGN 0x5 -# define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 -# define ASN1_PKEY_CTRL_CMS_RI_TYPE 0x8 - -int EVP_PKEY_asn1_get_count(void); -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, - const char *str, int len); -int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); -int EVP_PKEY_asn1_add_alias(int to, int from); -int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, - int *ppkey_flags, const char **pinfo, - const char **ppem_str, - const EVP_PKEY_ASN1_METHOD *ameth); - -const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey); -EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, - const char *pem_str, - const char *info); -void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, - const EVP_PKEY_ASN1_METHOD *src); -void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); -void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, - int (*pub_decode) (EVP_PKEY *pk, - X509_PUBKEY *pub), - int (*pub_encode) (X509_PUBKEY *pub, - const EVP_PKEY *pk), - int (*pub_cmp) (const EVP_PKEY *a, - const EVP_PKEY *b), - int (*pub_print) (BIO *out, - const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx), - int (*pkey_size) (const EVP_PKEY *pk), - int (*pkey_bits) (const EVP_PKEY *pk)); -void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, - int (*priv_decode) (EVP_PKEY *pk, - PKCS8_PRIV_KEY_INFO - *p8inf), - int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, - const EVP_PKEY *pk), - int (*priv_print) (BIO *out, - const EVP_PKEY *pkey, - int indent, - ASN1_PCTX *pctx)); -void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, - int (*param_decode) (EVP_PKEY *pkey, - const unsigned char **pder, - int derlen), - int (*param_encode) (const EVP_PKEY *pkey, - unsigned char **pder), - int (*param_missing) (const EVP_PKEY *pk), - int (*param_copy) (EVP_PKEY *to, - const EVP_PKEY *from), - int (*param_cmp) (const EVP_PKEY *a, - const EVP_PKEY *b), - int (*param_print) (BIO *out, - const EVP_PKEY *pkey, - int indent, - ASN1_PCTX *pctx)); - -void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, - void (*pkey_free) (EVP_PKEY *pkey)); -void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, - int (*pkey_ctrl) (EVP_PKEY *pkey, int op, - long arg1, void *arg2)); -void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth, - int (*item_verify) (EVP_MD_CTX *ctx, - const ASN1_ITEM *it, - void *asn, - X509_ALGOR *a, - ASN1_BIT_STRING *sig, - EVP_PKEY *pkey), - int (*item_sign) (EVP_MD_CTX *ctx, - const ASN1_ITEM *it, - void *asn, - X509_ALGOR *alg1, - X509_ALGOR *alg2, - ASN1_BIT_STRING *sig)); - -# define EVP_PKEY_OP_UNDEFINED 0 -# define EVP_PKEY_OP_PARAMGEN (1<<1) -# define EVP_PKEY_OP_KEYGEN (1<<2) -# define EVP_PKEY_OP_SIGN (1<<3) -# define EVP_PKEY_OP_VERIFY (1<<4) -# define EVP_PKEY_OP_VERIFYRECOVER (1<<5) -# define EVP_PKEY_OP_SIGNCTX (1<<6) -# define EVP_PKEY_OP_VERIFYCTX (1<<7) -# define EVP_PKEY_OP_ENCRYPT (1<<8) -# define EVP_PKEY_OP_DECRYPT (1<<9) -# define EVP_PKEY_OP_DERIVE (1<<10) - -# define EVP_PKEY_OP_TYPE_SIG \ - (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ - | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) - -# define EVP_PKEY_OP_TYPE_CRYPT \ - (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) - -# define EVP_PKEY_OP_TYPE_NOGEN \ - (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) - -# define EVP_PKEY_OP_TYPE_GEN \ - (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) - -# define EVP_PKEY_CTX_set_signature_md(ctx, md) \ - EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ - EVP_PKEY_CTRL_MD, 0, (void *)md) - -# define EVP_PKEY_CTX_get_signature_md(ctx, pmd) \ - EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ - EVP_PKEY_CTRL_GET_MD, 0, (void *)pmd) - -# define EVP_PKEY_CTRL_MD 1 -# define EVP_PKEY_CTRL_PEER_KEY 2 - -# define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 -# define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 - -# define EVP_PKEY_CTRL_PKCS7_SIGN 5 - -# define EVP_PKEY_CTRL_SET_MAC_KEY 6 - -# define EVP_PKEY_CTRL_DIGESTINIT 7 - -/* Used by GOST key encryption in TLS */ -# define EVP_PKEY_CTRL_SET_IV 8 - -# define EVP_PKEY_CTRL_CMS_ENCRYPT 9 -# define EVP_PKEY_CTRL_CMS_DECRYPT 10 -# define EVP_PKEY_CTRL_CMS_SIGN 11 - -# define EVP_PKEY_CTRL_CIPHER 12 - -# define EVP_PKEY_CTRL_GET_MD 13 - -# define EVP_PKEY_ALG_CTRL 0x1000 - -# define EVP_PKEY_FLAG_AUTOARGLEN 2 -/* - * Method handles all operations: don't assume any digest related defaults. - */ -# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 - -const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); -EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); -void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, - const EVP_PKEY_METHOD *meth); -void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); -void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); -int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); - -EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); -EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); -EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); -void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); - -int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, - int cmd, int p1, void *p2); -int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, - const char *value); - -int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); -void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); - -EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, - const unsigned char *key, int keylen); - -void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); -void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); -EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); - -EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); - -void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); -void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); - -int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); -int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, - unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbslen); -int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); -int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen); -int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); -int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, - unsigned char *rout, size_t *routlen, - const unsigned char *sig, size_t siglen); -int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); -int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen); -int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); -int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen); - -int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); -int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); -int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); - -typedef int EVP_PKEY_gen_cb (EVP_PKEY_CTX *ctx); - -int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); -int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); -int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); -int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); - -void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); -EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); - -int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); - -void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, - int (*init) (EVP_PKEY_CTX *ctx)); - -void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, - int (*copy) (EVP_PKEY_CTX *dst, - EVP_PKEY_CTX *src)); - -void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, - void (*cleanup) (EVP_PKEY_CTX *ctx)); - -void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, - int (*paramgen_init) (EVP_PKEY_CTX *ctx), - int (*paramgen) (EVP_PKEY_CTX *ctx, - EVP_PKEY *pkey)); - -void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, - int (*keygen_init) (EVP_PKEY_CTX *ctx), - int (*keygen) (EVP_PKEY_CTX *ctx, - EVP_PKEY *pkey)); - -void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, - int (*sign_init) (EVP_PKEY_CTX *ctx), - int (*sign) (EVP_PKEY_CTX *ctx, - unsigned char *sig, size_t *siglen, - const unsigned char *tbs, - size_t tbslen)); - -void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, - int (*verify_init) (EVP_PKEY_CTX *ctx), - int (*verify) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, - size_t siglen, - const unsigned char *tbs, - size_t tbslen)); - -void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, - int (*verify_recover_init) (EVP_PKEY_CTX - *ctx), - int (*verify_recover) (EVP_PKEY_CTX - *ctx, - unsigned char - *sig, - size_t *siglen, - const unsigned - char *tbs, - size_t tbslen)); - -void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, - int (*signctx_init) (EVP_PKEY_CTX *ctx, - EVP_MD_CTX *mctx), - int (*signctx) (EVP_PKEY_CTX *ctx, - unsigned char *sig, - size_t *siglen, - EVP_MD_CTX *mctx)); - -void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, - int (*verifyctx_init) (EVP_PKEY_CTX *ctx, - EVP_MD_CTX *mctx), - int (*verifyctx) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, - int siglen, - EVP_MD_CTX *mctx)); - -void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, - int (*encrypt_init) (EVP_PKEY_CTX *ctx), - int (*encryptfn) (EVP_PKEY_CTX *ctx, - unsigned char *out, - size_t *outlen, - const unsigned char *in, - size_t inlen)); - -void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, - int (*decrypt_init) (EVP_PKEY_CTX *ctx), - int (*decrypt) (EVP_PKEY_CTX *ctx, - unsigned char *out, - size_t *outlen, - const unsigned char *in, - size_t inlen)); - -void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, - int (*derive_init) (EVP_PKEY_CTX *ctx), - int (*derive) (EVP_PKEY_CTX *ctx, - unsigned char *key, - size_t *keylen)); - -void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, - int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, - void *p2), - int (*ctrl_str) (EVP_PKEY_CTX *ctx, - const char *type, - const char *value)); - -void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, - int (**pinit) (EVP_PKEY_CTX *ctx)); - -void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, - int (**pcopy) (EVP_PKEY_CTX *dst, - EVP_PKEY_CTX *src)); - -void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, - void (**pcleanup) (EVP_PKEY_CTX *ctx)); - -void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, - int (**pparamgen_init) (EVP_PKEY_CTX *ctx), - int (**pparamgen) (EVP_PKEY_CTX *ctx, - EVP_PKEY *pkey)); - -void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, - int (**pkeygen_init) (EVP_PKEY_CTX *ctx), - int (**pkeygen) (EVP_PKEY_CTX *ctx, - EVP_PKEY *pkey)); - -void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, - int (**psign_init) (EVP_PKEY_CTX *ctx), - int (**psign) (EVP_PKEY_CTX *ctx, - unsigned char *sig, size_t *siglen, - const unsigned char *tbs, - size_t tbslen)); - -void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, - int (**pverify_init) (EVP_PKEY_CTX *ctx), - int (**pverify) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, - size_t siglen, - const unsigned char *tbs, - size_t tbslen)); - -void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, - int (**pverify_recover_init) (EVP_PKEY_CTX - *ctx), - int (**pverify_recover) (EVP_PKEY_CTX - *ctx, - unsigned char - *sig, - size_t *siglen, - const unsigned - char *tbs, - size_t tbslen)); - -void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, - int (**psignctx_init) (EVP_PKEY_CTX *ctx, - EVP_MD_CTX *mctx), - int (**psignctx) (EVP_PKEY_CTX *ctx, - unsigned char *sig, - size_t *siglen, - EVP_MD_CTX *mctx)); - -void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, - int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, - EVP_MD_CTX *mctx), - int (**pverifyctx) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, - int siglen, - EVP_MD_CTX *mctx)); - -void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, - int (**pencrypt_init) (EVP_PKEY_CTX *ctx), - int (**pencryptfn) (EVP_PKEY_CTX *ctx, - unsigned char *out, - size_t *outlen, - const unsigned char *in, - size_t inlen)); - -void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, - int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), - int (**pdecrypt) (EVP_PKEY_CTX *ctx, - unsigned char *out, - size_t *outlen, - const unsigned char *in, - size_t inlen)); - -void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, - int (**pderive_init) (EVP_PKEY_CTX *ctx), - int (**pderive) (EVP_PKEY_CTX *ctx, - unsigned char *key, - size_t *keylen)); - -void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, - int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, - void *p2), - int (**pctrl_str) (EVP_PKEY_CTX *ctx, - const char *type, - const char *value)); - -void EVP_add_alg_module(void); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ - -void ERR_load_EVP_strings(void); - -/* Error codes for the EVP functions. */ - -/* Function codes. */ -# define EVP_F_AESNI_INIT_KEY 165 -# define EVP_F_AESNI_XTS_CIPHER 176 -# define EVP_F_AES_INIT_KEY 133 -# define EVP_F_AES_T4_INIT_KEY 178 -# define EVP_F_AES_XTS 172 -# define EVP_F_AES_XTS_CIPHER 175 -# define EVP_F_ALG_MODULE_INIT 177 -# define EVP_F_CAMELLIA_INIT_KEY 159 -# define EVP_F_CMAC_INIT 173 -# define EVP_F_CMLL_T4_INIT_KEY 179 -# define EVP_F_D2I_PKEY 100 -# define EVP_F_DO_SIGVER_INIT 161 -# define EVP_F_DSAPKEY2PKCS8 134 -# define EVP_F_DSA_PKEY2PKCS8 135 -# define EVP_F_ECDSA_PKEY2PKCS8 129 -# define EVP_F_ECKEY_PKEY2PKCS8 132 -# define EVP_F_EVP_CIPHERINIT_EX 123 -# define EVP_F_EVP_CIPHER_CTX_COPY 163 -# define EVP_F_EVP_CIPHER_CTX_CTRL 124 -# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 -# define EVP_F_EVP_DECRYPTFINAL_EX 101 -# define EVP_F_EVP_DIGESTINIT_EX 128 -# define EVP_F_EVP_ENCRYPTFINAL_EX 127 -# define EVP_F_EVP_MD_CTX_COPY_EX 110 -# define EVP_F_EVP_MD_SIZE 162 -# define EVP_F_EVP_OPENINIT 102 -# define EVP_F_EVP_PBE_ALG_ADD 115 -# define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 -# define EVP_F_EVP_PBE_CIPHERINIT 116 -# define EVP_F_EVP_PKCS82PKEY 111 -# define EVP_F_EVP_PKCS82PKEY_BROKEN 136 -# define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 -# define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 -# define EVP_F_EVP_PKEY_CTX_CTRL 137 -# define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 -# define EVP_F_EVP_PKEY_CTX_DUP 156 -# define EVP_F_EVP_PKEY_DECRYPT 104 -# define EVP_F_EVP_PKEY_DECRYPT_INIT 138 -# define EVP_F_EVP_PKEY_DECRYPT_OLD 151 -# define EVP_F_EVP_PKEY_DERIVE 153 -# define EVP_F_EVP_PKEY_DERIVE_INIT 154 -# define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 -# define EVP_F_EVP_PKEY_ENCRYPT 105 -# define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 -# define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 -# define EVP_F_EVP_PKEY_GET1_DH 119 -# define EVP_F_EVP_PKEY_GET1_DSA 120 -# define EVP_F_EVP_PKEY_GET1_ECDSA 130 -# define EVP_F_EVP_PKEY_GET1_EC_KEY 131 -# define EVP_F_EVP_PKEY_GET1_RSA 121 -# define EVP_F_EVP_PKEY_KEYGEN 146 -# define EVP_F_EVP_PKEY_KEYGEN_INIT 147 -# define EVP_F_EVP_PKEY_NEW 106 -# define EVP_F_EVP_PKEY_PARAMGEN 148 -# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 -# define EVP_F_EVP_PKEY_SIGN 140 -# define EVP_F_EVP_PKEY_SIGN_INIT 141 -# define EVP_F_EVP_PKEY_VERIFY 142 -# define EVP_F_EVP_PKEY_VERIFY_INIT 143 -# define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 -# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 -# define EVP_F_EVP_RIJNDAEL 126 -# define EVP_F_EVP_SIGNFINAL 107 -# define EVP_F_EVP_VERIFYFINAL 108 -# define EVP_F_FIPS_CIPHERINIT 166 -# define EVP_F_FIPS_CIPHER_CTX_COPY 170 -# define EVP_F_FIPS_CIPHER_CTX_CTRL 167 -# define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171 -# define EVP_F_FIPS_DIGESTINIT 168 -# define EVP_F_FIPS_MD_CTX_COPY 169 -# define EVP_F_HMAC_INIT_EX 174 -# define EVP_F_INT_CTX_NEW 157 -# define EVP_F_PKCS5_PBE_KEYIVGEN 117 -# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 -# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 -# define EVP_F_PKCS8_SET_BROKEN 112 -# define EVP_F_PKEY_SET_TYPE 158 -# define EVP_F_RC2_MAGIC_TO_METH 109 -# define EVP_F_RC5_CTRL 125 - -/* Reason codes. */ -# define EVP_R_AES_IV_SETUP_FAILED 162 -# define EVP_R_AES_KEY_SETUP_FAILED 143 -# define EVP_R_ASN1_LIB 140 -# define EVP_R_BAD_BLOCK_LENGTH 136 -# define EVP_R_BAD_DECRYPT 100 -# define EVP_R_BAD_KEY_LENGTH 137 -# define EVP_R_BN_DECODE_ERROR 112 -# define EVP_R_BN_PUBKEY_ERROR 113 -# define EVP_R_BUFFER_TOO_SMALL 155 -# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 -# define EVP_R_CIPHER_PARAMETER_ERROR 122 -# define EVP_R_COMMAND_NOT_SUPPORTED 147 -# define EVP_R_CTRL_NOT_IMPLEMENTED 132 -# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 -# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 -# define EVP_R_DECODE_ERROR 114 -# define EVP_R_DIFFERENT_KEY_TYPES 101 -# define EVP_R_DIFFERENT_PARAMETERS 153 -# define EVP_R_DISABLED_FOR_FIPS 163 -# define EVP_R_ENCODE_ERROR 115 -# define EVP_R_ERROR_LOADING_SECTION 165 -# define EVP_R_ERROR_SETTING_FIPS_MODE 166 -# define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 -# define EVP_R_EXPECTING_AN_RSA_KEY 127 -# define EVP_R_EXPECTING_A_DH_KEY 128 -# define EVP_R_EXPECTING_A_DSA_KEY 129 -# define EVP_R_EXPECTING_A_ECDSA_KEY 141 -# define EVP_R_EXPECTING_A_EC_KEY 142 -# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 -# define EVP_R_INITIALIZATION_ERROR 134 -# define EVP_R_INPUT_NOT_INITIALIZED 111 -# define EVP_R_INVALID_DIGEST 152 -# define EVP_R_INVALID_FIPS_MODE 168 -# define EVP_R_INVALID_KEY 171 -# define EVP_R_INVALID_KEY_LENGTH 130 -# define EVP_R_INVALID_OPERATION 148 -# define EVP_R_IV_TOO_LARGE 102 -# define EVP_R_KEYGEN_FAILURE 120 -# define EVP_R_MESSAGE_DIGEST_IS_NULL 159 -# define EVP_R_METHOD_NOT_SUPPORTED 144 -# define EVP_R_MISSING_PARAMETERS 103 -# define EVP_R_NO_CIPHER_SET 131 -# define EVP_R_NO_DEFAULT_DIGEST 158 -# define EVP_R_NO_DIGEST_SET 139 -# define EVP_R_NO_DSA_PARAMETERS 116 -# define EVP_R_NO_KEY_SET 154 -# define EVP_R_NO_OPERATION_SET 149 -# define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 -# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 -# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 -# define EVP_R_OPERATON_NOT_INITIALIZED 151 -# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 -# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 -# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 -# define EVP_R_PUBLIC_KEY_NOT_RSA 106 -# define EVP_R_TOO_LARGE 164 -# define EVP_R_UNKNOWN_CIPHER 160 -# define EVP_R_UNKNOWN_DIGEST 161 -# define EVP_R_UNKNOWN_OPTION 169 -# define EVP_R_UNKNOWN_PBE_ALGORITHM 121 -# define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 -# define EVP_R_UNSUPPORTED_ALGORITHM 156 -# define EVP_R_UNSUPPORTED_CIPHER 107 -# define EVP_R_UNSUPPORTED_KEYLENGTH 123 -# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 -# define EVP_R_UNSUPPORTED_KEY_SIZE 108 -# define EVP_R_UNSUPPORTED_PRF 125 -# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 -# define EVP_R_UNSUPPORTED_SALT_TYPE 126 -# define EVP_R_WRAP_MODE_NOT_ALLOWED 170 -# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 -# define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 - -# ifdef __cplusplus -} -# endif -#endif diff --git a/Sources/COpenSSL/evp_.c b/Sources/COpenSSL/evp_.c deleted file mode 100644 index a09db50e..00000000 --- a/Sources/COpenSSL/evp_.c +++ /dev/null @@ -1,2444 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* evp_acnf.c */ -/* - * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "cryptlib.h" -#include "evp.h" -#include "conf.h" - -/* - * Load all algorithms and configure OpenSSL. This function is called - * automatically when OPENSSL_LOAD_CONF is set. - */ - -void OPENSSL_add_all_algorithms_conf(void) -{ - OPENSSL_add_all_algorithms_noconf(); - OPENSSL_config(NULL); -} -/* crypto/asn1/evp_asn1.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "asn1.h" -#include "asn1_mac.h" - -int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) -{ - ASN1_STRING *os; - - if ((os = M_ASN1_OCTET_STRING_new()) == NULL) - return (0); - if (!M_ASN1_OCTET_STRING_set(os, data, len)) { - M_ASN1_OCTET_STRING_free(os); - return 0; - } - ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os); - return (1); -} - -/* int max_len: for returned value */ -int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len) -{ - int ret, num; - unsigned char *p; - - if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) { - ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG); - return (-1); - } - p = M_ASN1_STRING_data(a->value.octet_string); - ret = M_ASN1_STRING_length(a->value.octet_string); - if (ret < max_len) - num = ret; - else - num = max_len; - memcpy(data, p, num); - return (ret); -} - -int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, - int len) -{ - int n, size; - ASN1_OCTET_STRING os, *osp; - ASN1_INTEGER in; - unsigned char *p; - unsigned char buf[32]; /* when they have 256bit longs, I'll be in - * trouble */ - in.data = buf; - in.length = 32; - os.data = data; - os.type = V_ASN1_OCTET_STRING; - os.length = len; - ASN1_INTEGER_set(&in, num); - n = i2d_ASN1_INTEGER(&in, NULL); - n += M_i2d_ASN1_OCTET_STRING(&os, NULL); - - size = ASN1_object_size(1, n, V_ASN1_SEQUENCE); - - if ((osp = ASN1_STRING_new()) == NULL) - return (0); - /* Grow the 'string' */ - if (!ASN1_STRING_set(osp, NULL, size)) { - ASN1_STRING_free(osp); - return (0); - } - - M_ASN1_STRING_length_set(osp, size); - p = M_ASN1_STRING_data(osp); - - ASN1_put_object(&p, 1, n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); - i2d_ASN1_INTEGER(&in, &p); - M_i2d_ASN1_OCTET_STRING(&os, &p); - - ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp); - return (1); -} - -/* - * we return the actual length..., num may be missing, in which case, set it - * to zero - */ -/* int max_len: for returned value */ -int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, - unsigned char *data, int max_len) -{ - int ret = -1, n; - ASN1_INTEGER *ai = NULL; - ASN1_OCTET_STRING *os = NULL; - const unsigned char *p; - long length; - ASN1_const_CTX c; - - if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) { - goto err; - } - p = M_ASN1_STRING_data(a->value.sequence); - length = M_ASN1_STRING_length(a->value.sequence); - - c.pp = &p; - c.p = p; - c.max = p + length; - c.error = ASN1_R_DATA_IS_WRONG; - - M_ASN1_D2I_start_sequence(); - c.q = c.p; - if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL) - goto err; - c.slen -= (c.p - c.q); - c.q = c.p; - if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL) - goto err; - c.slen -= (c.p - c.q); - if (!M_ASN1_D2I_end_sequence()) - goto err; - - if (num != NULL) - *num = ASN1_INTEGER_get(ai); - - ret = M_ASN1_STRING_length(os); - if (max_len > ret) - n = ret; - else - n = max_len; - - if (data != NULL) - memcpy(data, M_ASN1_STRING_data(os), n); - if (0) { - err: - ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG); - } - if (os != NULL) - M_ASN1_OCTET_STRING_free(os); - if (ai != NULL) - M_ASN1_INTEGER_free(ai); - return (ret); -} -/* evp_cnf.c */ -/* - * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project - * 2007. - */ -/* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "crypto.h" -// #include "cryptlib.h" -// #include "conf.h" -#include "dso.h" -#include "x509.h" -#include "x509v3.h" -#ifdef OPENSSL_FIPS -# include -#endif - -/* Algorithm configuration module. */ - -static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) -{ - int i; - const char *oid_section; - STACK_OF(CONF_VALUE) *sktmp; - CONF_VALUE *oval; - oid_section = CONF_imodule_get_value(md); - if (!(sktmp = NCONF_get_section(cnf, oid_section))) { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION); - return 0; - } - for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { - oval = sk_CONF_VALUE_value(sktmp, i); - if (!strcmp(oval->name, "fips_mode")) { - int m; - if (!X509V3_get_value_bool(oval, &m)) { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE); - return 0; - } - if (m > 0) { -#ifdef OPENSSL_FIPS - if (!FIPS_mode() && !FIPS_mode_set(1)) { - EVPerr(EVP_F_ALG_MODULE_INIT, - EVP_R_ERROR_SETTING_FIPS_MODE); - return 0; - } -#else - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED); - return 0; -#endif - } - } else { - EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION); - ERR_add_error_data(4, "name=", oval->name, - ", value=", oval->value); - } - - } - return 1; -} - -void EVP_add_alg_module(void) -{ - CONF_module_add("alg_section", alg_module_init, 0); -} -/* crypto/evp/evp_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -#include "err.h" -#include "rand.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -#ifdef OPENSSL_FIPS -# include -#endif -#include "evp_locl.h" - -#ifdef OPENSSL_FIPS -# define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl) -#else -# define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl) -#endif - -const char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT; - -void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) -{ - memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); - /* ctx->cipher=NULL; */ -} - -EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) -{ - EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); - if (ctx) - EVP_CIPHER_CTX_init(ctx); - return ctx; -} - -int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - const unsigned char *key, const unsigned char *iv, int enc) -{ - if (cipher) - EVP_CIPHER_CTX_init(ctx); - return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); -} - -int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv, int enc) -{ - if (enc == -1) - enc = ctx->encrypt; - else { - if (enc) - enc = 1; - ctx->encrypt = enc; - } -#ifndef OPENSSL_NO_ENGINE - /* - * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so - * this context may already have an ENGINE! Try to avoid releasing the - * previous handle, re-querying for an ENGINE, and having a - * reinitialisation, when it may all be unecessary. - */ - if (ctx->engine && ctx->cipher && (!cipher || - (cipher - && (cipher->nid == - ctx->cipher->nid)))) - goto skip_to_init; -#endif - if (cipher) { - /* - * Ensure a context left lying around from last time is cleared (the - * previous check attempted to avoid this if the same ENGINE and - * EVP_CIPHER could be used). - */ - if (ctx->cipher) { - unsigned long flags = ctx->flags; - EVP_CIPHER_CTX_cleanup(ctx); - /* Restore encrypt and flags */ - ctx->encrypt = enc; - ctx->flags = flags; - } -#ifndef OPENSSL_NO_ENGINE - if (impl) { - if (!ENGINE_init(impl)) { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); - return 0; - } - } else - /* Ask if an ENGINE is reserved for this job */ - impl = ENGINE_get_cipher_engine(cipher->nid); - if (impl) { - /* There's an ENGINE for this job ... (apparently) */ - const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid); - if (!c) { - /* - * One positive side-effect of US's export control history, - * is that we should at least be able to avoid using US - * mispellings of "initialisation"? - */ - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); - return 0; - } - /* We'll use the ENGINE's private cipher definition */ - cipher = c; - /* - * Store the ENGINE functional reference so we know 'cipher' came - * from an ENGINE and we need to release it when done. - */ - ctx->engine = impl; - } else - ctx->engine = NULL; -#endif - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) { - const EVP_CIPHER *fcipher = NULL; - if (cipher) - fcipher = evp_get_fips_cipher(cipher); - if (fcipher) - cipher = fcipher; - return FIPS_cipherinit(ctx, cipher, key, iv, enc); - } -#endif - ctx->cipher = cipher; - if (ctx->cipher->ctx_size) { - ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); - if (!ctx->cipher_data) { - ctx->cipher = NULL; - EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); - return 0; - } - } else { - ctx->cipher_data = NULL; - } - ctx->key_len = cipher->key_len; - /* Preserve wrap enable flag, zero everything else */ - ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; - if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { - if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { - ctx->cipher = NULL; - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); - return 0; - } - } - } else if (!ctx->cipher) { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET); - return 0; - } -#ifndef OPENSSL_NO_ENGINE - skip_to_init: -#endif -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_cipherinit(ctx, cipher, key, iv, enc); -#endif - /* we assume block size is a power of 2 in *cryptUpdate */ - OPENSSL_assert(ctx->cipher->block_size == 1 - || ctx->cipher->block_size == 8 - || ctx->cipher->block_size == 16); - - if (!(ctx->flags & EVP_CIPHER_CTX_FLAG_WRAP_ALLOW) - && EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_WRAP_MODE) { - EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_WRAP_MODE_NOT_ALLOWED); - return 0; - } - - if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { - switch (EVP_CIPHER_CTX_mode(ctx)) { - - case EVP_CIPH_STREAM_CIPHER: - case EVP_CIPH_ECB_MODE: - break; - - case EVP_CIPH_CFB_MODE: - case EVP_CIPH_OFB_MODE: - - ctx->num = 0; - /* fall-through */ - - case EVP_CIPH_CBC_MODE: - - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= - (int)sizeof(ctx->iv)); - if (iv) - memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); - memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); - break; - - case EVP_CIPH_CTR_MODE: - ctx->num = 0; - /* Don't reuse IV for CTR mode */ - if (iv) - memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); - break; - - default: - return 0; - break; - } - } - - if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { - if (!ctx->cipher->init(ctx, key, iv, enc)) - return 0; - } - ctx->buf_len = 0; - ctx->final_used = 0; - ctx->block_mask = ctx->cipher->block_size - 1; - return 1; -} - -int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl) -{ - if (ctx->encrypt) - return EVP_EncryptUpdate(ctx, out, outl, in, inl); - else - return EVP_DecryptUpdate(ctx, out, outl, in, inl); -} - -int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) -{ - if (ctx->encrypt) - return EVP_EncryptFinal_ex(ctx, out, outl); - else - return EVP_DecryptFinal_ex(ctx, out, outl); -} - -int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) -{ - if (ctx->encrypt) - return EVP_EncryptFinal(ctx, out, outl); - else - return EVP_DecryptFinal(ctx, out, outl); -} - -int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - const unsigned char *key, const unsigned char *iv) -{ - return EVP_CipherInit(ctx, cipher, key, iv, 1); -} - -int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv) -{ - return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); -} - -int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - const unsigned char *key, const unsigned char *iv) -{ - return EVP_CipherInit(ctx, cipher, key, iv, 0); -} - -int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv) -{ - return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); -} - -int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl) -{ - int i, j, bl; - - if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { - i = M_do_cipher(ctx, out, in, inl); - if (i < 0) - return 0; - else - *outl = i; - return 1; - } - - if (inl <= 0) { - *outl = 0; - return inl == 0; - } - - if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) { - if (M_do_cipher(ctx, out, in, inl)) { - *outl = inl; - return 1; - } else { - *outl = 0; - return 0; - } - } - i = ctx->buf_len; - bl = ctx->cipher->block_size; - OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); - if (i != 0) { - if (bl - i > inl) { - memcpy(&(ctx->buf[i]), in, inl); - ctx->buf_len += inl; - *outl = 0; - return 1; - } else { - j = bl - i; - memcpy(&(ctx->buf[i]), in, j); - if (!M_do_cipher(ctx, out, ctx->buf, bl)) - return 0; - inl -= j; - in += j; - out += bl; - *outl = bl; - } - } else - *outl = 0; - i = inl & (bl - 1); - inl -= i; - if (inl > 0) { - if (!M_do_cipher(ctx, out, in, inl)) - return 0; - *outl += inl; - } - - if (i != 0) - memcpy(ctx->buf, &(in[inl]), i); - ctx->buf_len = i; - return 1; -} - -int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) -{ - int ret; - ret = EVP_EncryptFinal_ex(ctx, out, outl); - return ret; -} - -int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) -{ - int n, ret; - unsigned int i, b, bl; - - if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { - ret = M_do_cipher(ctx, out, NULL, 0); - if (ret < 0) - return 0; - else - *outl = ret; - return 1; - } - - b = ctx->cipher->block_size; - OPENSSL_assert(b <= sizeof(ctx->buf)); - if (b == 1) { - *outl = 0; - return 1; - } - bl = ctx->buf_len; - if (ctx->flags & EVP_CIPH_NO_PADDING) { - if (bl) { - EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, - EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); - return 0; - } - *outl = 0; - return 1; - } - - n = b - bl; - for (i = bl; i < b; i++) - ctx->buf[i] = n; - ret = M_do_cipher(ctx, out, ctx->buf, b); - - if (ret) - *outl = b; - - return ret; -} - -int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl) -{ - int fix_len; - unsigned int b; - - if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { - fix_len = M_do_cipher(ctx, out, in, inl); - if (fix_len < 0) { - *outl = 0; - return 0; - } else - *outl = fix_len; - return 1; - } - - if (inl <= 0) { - *outl = 0; - return inl == 0; - } - - if (ctx->flags & EVP_CIPH_NO_PADDING) - return EVP_EncryptUpdate(ctx, out, outl, in, inl); - - b = ctx->cipher->block_size; - OPENSSL_assert(b <= sizeof(ctx->final)); - - if (ctx->final_used) { - memcpy(out, ctx->final, b); - out += b; - fix_len = 1; - } else - fix_len = 0; - - if (!EVP_EncryptUpdate(ctx, out, outl, in, inl)) - return 0; - - /* - * if we have 'decrypted' a multiple of block size, make sure we have a - * copy of this last block - */ - if (b > 1 && !ctx->buf_len) { - *outl -= b; - ctx->final_used = 1; - memcpy(ctx->final, &out[*outl], b); - } else - ctx->final_used = 0; - - if (fix_len) - *outl += b; - - return 1; -} - -int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) -{ - int ret; - ret = EVP_DecryptFinal_ex(ctx, out, outl); - return ret; -} - -int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) -{ - int i, n; - unsigned int b; - *outl = 0; - - if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { - i = M_do_cipher(ctx, out, NULL, 0); - if (i < 0) - return 0; - else - *outl = i; - return 1; - } - - b = ctx->cipher->block_size; - if (ctx->flags & EVP_CIPH_NO_PADDING) { - if (ctx->buf_len) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, - EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); - return 0; - } - *outl = 0; - return 1; - } - if (b > 1) { - if (ctx->buf_len || !ctx->final_used) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH); - return (0); - } - OPENSSL_assert(b <= sizeof(ctx->final)); - - /* - * The following assumes that the ciphertext has been authenticated. - * Otherwise it provides a padding oracle. - */ - n = ctx->final[b - 1]; - if (n == 0 || n > (int)b) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); - return (0); - } - for (i = 0; i < n; i++) { - if (ctx->final[--b] != n) { - EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); - return (0); - } - } - n = ctx->cipher->block_size - n; - for (i = 0; i < n; i++) - out[i] = ctx->final[i]; - *outl = n; - } else - *outl = 0; - return (1); -} - -void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) -{ - if (ctx) { - EVP_CIPHER_CTX_cleanup(ctx); - OPENSSL_free(ctx); - } -} - -int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) -{ -#ifndef OPENSSL_FIPS - if (c->cipher != NULL) { - if (c->cipher->cleanup && !c->cipher->cleanup(c)) - return 0; - /* Cleanse cipher context data */ - if (c->cipher_data) - OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); - } - if (c->cipher_data) - OPENSSL_free(c->cipher_data); -#endif -#ifndef OPENSSL_NO_ENGINE - if (c->engine) - /* - * The EVP_CIPHER we used belongs to an ENGINE, release the - * functional reference we held for this reason. - */ - ENGINE_finish(c->engine); -#endif -#ifdef OPENSSL_FIPS - FIPS_cipher_ctx_cleanup(c); -#endif - memset(c, 0, sizeof(EVP_CIPHER_CTX)); - return 1; -} - -int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) -{ - if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) - return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); - if (c->key_len == keylen) - return 1; - if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { - c->key_len = keylen; - return 1; - } - EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH); - return 0; -} - -int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) -{ - if (pad) - ctx->flags &= ~EVP_CIPH_NO_PADDING; - else - ctx->flags |= EVP_CIPH_NO_PADDING; - return 1; -} - -int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) -{ - int ret; - if (!ctx->cipher) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); - return 0; - } - - if (!ctx->cipher->ctrl) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); - return 0; - } - - ret = ctx->cipher->ctrl(ctx, type, arg, ptr); - if (ret == -1) { - EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, - EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); - return 0; - } - return ret; -} - -int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) -{ - if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) - return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); - if (RAND_bytes(key, ctx->key_len) <= 0) - return 0; - return 1; -} - -int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) -{ - if ((in == NULL) || (in->cipher == NULL)) { - EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED); - return 0; - } -#ifndef OPENSSL_NO_ENGINE - /* Make sure it's safe to copy a cipher context using an ENGINE */ - if (in->engine && !ENGINE_init(in->engine)) { - EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_ENGINE_LIB); - return 0; - } -#endif - - EVP_CIPHER_CTX_cleanup(out); - memcpy(out, in, sizeof(*out)); - - if (in->cipher_data && in->cipher->ctx_size) { - out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); - if (!out->cipher_data) { - out->cipher = NULL; - EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE); - return 0; - } - memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); - } - - if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) - if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) { - out->cipher = NULL; - EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INITIALIZATION_ERROR); - return 0; - } - return 1; -} -/* crypto/evp/evp_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -// #include "err.h" -// #include "evp.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason) - -static ERR_STRING_DATA EVP_str_functs[] = { - {ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"}, - {ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"}, - {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"}, - {ERR_FUNC(EVP_F_AES_T4_INIT_KEY), "AES_T4_INIT_KEY"}, - {ERR_FUNC(EVP_F_AES_XTS), "AES_XTS"}, - {ERR_FUNC(EVP_F_AES_XTS_CIPHER), "AES_XTS_CIPHER"}, - {ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"}, - {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"}, - {ERR_FUNC(EVP_F_CMAC_INIT), "CMAC_INIT"}, - {ERR_FUNC(EVP_F_CMLL_T4_INIT_KEY), "CMLL_T4_INIT_KEY"}, - {ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"}, - {ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"}, - {ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"}, - {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"}, - {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"}, - {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"}, - {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, - {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"}, - {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"}, - {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), - "EVP_CIPHER_CTX_set_key_length"}, - {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, - {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, - {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, - {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, - {ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"}, - {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"}, - {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"}, - {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"}, - {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"}, - {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"}, - {ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"}, - {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"}, - {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"}, - {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"}, - {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"}, - {ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"}, - {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"}, - {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"}, - {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"}, - {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"}, - {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"}, - {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"}, - {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"}, - {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"}, - {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"}, - {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH), "EVP_PKEY_get1_DH"}, - {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA), "EVP_PKEY_get1_DSA"}, - {ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"}, - {ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"}, - {ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"}, - {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"}, - {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"}, - {ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"}, - {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"}, - {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"}, - {ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"}, - {ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"}, - {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"}, - {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"}, - {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"}, - {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT), - "EVP_PKEY_verify_recover_init"}, - {ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"}, - {ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"}, - {ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"}, - {ERR_FUNC(EVP_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"}, - {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY), "FIPS_CIPHER_CTX_COPY"}, - {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"}, - {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH), - "FIPS_CIPHER_CTX_SET_KEY_LENGTH"}, - {ERR_FUNC(EVP_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"}, - {ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY), "FIPS_MD_CTX_COPY"}, - {ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"}, - {ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"}, - {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"}, - {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"}, - {ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_KEYIVGEN"}, - {ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"}, - {ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"}, - {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"}, - {ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"}, - {0, NULL} -}; - -static ERR_STRING_DATA EVP_str_reasons[] = { - {ERR_REASON(EVP_R_AES_IV_SETUP_FAILED), "aes iv setup failed"}, - {ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"}, - {ERR_REASON(EVP_R_ASN1_LIB), "asn1 lib"}, - {ERR_REASON(EVP_R_BAD_BLOCK_LENGTH), "bad block length"}, - {ERR_REASON(EVP_R_BAD_DECRYPT), "bad decrypt"}, - {ERR_REASON(EVP_R_BAD_KEY_LENGTH), "bad key length"}, - {ERR_REASON(EVP_R_BN_DECODE_ERROR), "bn decode error"}, - {ERR_REASON(EVP_R_BN_PUBKEY_ERROR), "bn pubkey error"}, - {ERR_REASON(EVP_R_BUFFER_TOO_SMALL), "buffer too small"}, - {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED), - "camellia key setup failed"}, - {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"}, - {ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED), "command not supported"}, - {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED), "ctrl not implemented"}, - {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED), - "ctrl operation not implemented"}, - {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), - "data not multiple of block length"}, - {ERR_REASON(EVP_R_DECODE_ERROR), "decode error"}, - {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES), "different key types"}, - {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS), "different parameters"}, - {ERR_REASON(EVP_R_DISABLED_FOR_FIPS), "disabled for fips"}, - {ERR_REASON(EVP_R_ENCODE_ERROR), "encode error"}, - {ERR_REASON(EVP_R_ERROR_LOADING_SECTION), "error loading section"}, - {ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"}, - {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR), "evp pbe cipherinit error"}, - {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY), "expecting an rsa key"}, - {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"}, - {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"}, - {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY), "expecting a ecdsa key"}, - {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"}, - {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, - {ERR_REASON(EVP_R_INITIALIZATION_ERROR), "initialization error"}, - {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"}, - {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"}, - {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"}, - {ERR_REASON(EVP_R_INVALID_KEY), "invalid key"}, - {ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"}, - {ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"}, - {ERR_REASON(EVP_R_IV_TOO_LARGE), "iv too large"}, - {ERR_REASON(EVP_R_KEYGEN_FAILURE), "keygen failure"}, - {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"}, - {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED), "method not supported"}, - {ERR_REASON(EVP_R_MISSING_PARAMETERS), "missing parameters"}, - {ERR_REASON(EVP_R_NO_CIPHER_SET), "no cipher set"}, - {ERR_REASON(EVP_R_NO_DEFAULT_DIGEST), "no default digest"}, - {ERR_REASON(EVP_R_NO_DIGEST_SET), "no digest set"}, - {ERR_REASON(EVP_R_NO_DSA_PARAMETERS), "no dsa parameters"}, - {ERR_REASON(EVP_R_NO_KEY_SET), "no key set"}, - {ERR_REASON(EVP_R_NO_OPERATION_SET), "no operation set"}, - {ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED), - "no sign function configured"}, - {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED), - "no verify function configured"}, - {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), - "operation not supported for this keytype"}, - {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, - {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), - "pkcs8 unknown broken type"}, - {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"}, - {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"}, - {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, - {ERR_REASON(EVP_R_TOO_LARGE), "too large"}, - {ERR_REASON(EVP_R_UNKNOWN_CIPHER), "unknown cipher"}, - {ERR_REASON(EVP_R_UNKNOWN_DIGEST), "unknown digest"}, - {ERR_REASON(EVP_R_UNKNOWN_OPTION), "unknown option"}, - {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM), "unknown pbe algorithm"}, - {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS), - "unsuported number of rounds"}, - {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, - {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, - {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH), "unsupported keylength"}, - {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION), - "unsupported key derivation function"}, - {ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"}, - {ERR_REASON(EVP_R_UNSUPPORTED_PRF), "unsupported prf"}, - {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM), - "unsupported private key algorithm"}, - {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE), "unsupported salt type"}, - {ERR_REASON(EVP_R_WRAP_MODE_NOT_ALLOWED), "wrap mode not allowed"}, - {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"}, - {ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"}, - {0, NULL} -}; - -#endif - -void ERR_load_EVP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) { - ERR_load_strings(0, EVP_str_functs); - ERR_load_strings(0, EVP_str_reasons); - } -#endif -} -/* crypto/evp/evp_key.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "x509.h" -#include "objects.h" -// #include "evp.h" -#include "ui.h" - -/* should be init to zeros. */ -static char prompt_string[80]; - -void EVP_set_pw_prompt(const char *prompt) -{ - if (prompt == NULL) - prompt_string[0] = '\0'; - else { - strncpy(prompt_string, prompt, 79); - prompt_string[79] = '\0'; - } -} - -char *EVP_get_pw_prompt(void) -{ - if (prompt_string[0] == '\0') - return (NULL); - else - return (prompt_string); -} - -/* - * For historical reasons, the standard function for reading passwords is in - * the DES library -- if someone ever wants to disable DES, this function - * will fail - */ -int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) -{ - return EVP_read_pw_string_min(buf, 0, len, prompt, verify); -} - -int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, - int verify) -{ - int ret = -1; - char buff[BUFSIZ]; - UI *ui; - - if ((prompt == NULL) && (prompt_string[0] != '\0')) - prompt = prompt_string; - ui = UI_new(); - if (ui == NULL) - return ret; - if (UI_add_input_string(ui, prompt, 0, buf, min, - (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0 - || (verify - && UI_add_verify_string(ui, prompt, 0, buff, min, - (len >= BUFSIZ) ? BUFSIZ - 1 : len, - buf) < 0)) - goto end; - ret = UI_process(ui); - OPENSSL_cleanse(buff, BUFSIZ); - end: - UI_free(ui); - return ret; -} - -int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, - const unsigned char *salt, const unsigned char *data, - int datal, int count, unsigned char *key, - unsigned char *iv) -{ - EVP_MD_CTX c; - unsigned char md_buf[EVP_MAX_MD_SIZE]; - int niv, nkey, addmd = 0; - unsigned int mds = 0, i; - int rv = 0; - nkey = type->key_len; - niv = type->iv_len; - OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); - OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); - - if (data == NULL) - return (nkey); - - EVP_MD_CTX_init(&c); - for (;;) { - if (!EVP_DigestInit_ex(&c, md, NULL)) - goto err; - if (addmd++) - if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) - goto err; - if (!EVP_DigestUpdate(&c, data, datal)) - goto err; - if (salt != NULL) - if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN)) - goto err; - if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) - goto err; - - for (i = 1; i < (unsigned int)count; i++) { - if (!EVP_DigestInit_ex(&c, md, NULL)) - goto err; - if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) - goto err; - if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) - goto err; - } - i = 0; - if (nkey) { - for (;;) { - if (nkey == 0) - break; - if (i == mds) - break; - if (key != NULL) - *(key++) = md_buf[i]; - nkey--; - i++; - } - } - if (niv && (i != mds)) { - for (;;) { - if (niv == 0) - break; - if (i == mds) - break; - if (iv != NULL) - *(iv++) = md_buf[i]; - niv--; - i++; - } - } - if ((nkey == 0) && (niv == 0)) - break; - } - rv = type->key_len; - err: - EVP_MD_CTX_cleanup(&c); - OPENSSL_cleanse(md_buf, sizeof(md_buf)); - return rv; -} -/* crypto/evp/evp_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "objects.h" -#ifdef OPENSSL_FIPS -# include -# include "evp_locl.h" -#endif - -int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - int ret; - - if (c->cipher->set_asn1_parameters != NULL) - ret = c->cipher->set_asn1_parameters(c, type); - else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { - switch (EVP_CIPHER_CTX_mode(c)) { - case EVP_CIPH_WRAP_MODE: - if (EVP_CIPHER_CTX_nid(c) == NID_id_smime_alg_CMS3DESwrap) - ASN1_TYPE_set(type, V_ASN1_NULL, NULL); - ret = 1; - break; - - case EVP_CIPH_GCM_MODE: - case EVP_CIPH_CCM_MODE: - case EVP_CIPH_XTS_MODE: - ret = -1; - break; - - default: - ret = EVP_CIPHER_set_asn1_iv(c, type); - } - } else - ret = -1; - return (ret); -} - -int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - int ret; - - if (c->cipher->get_asn1_parameters != NULL) - ret = c->cipher->get_asn1_parameters(c, type); - else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { - switch (EVP_CIPHER_CTX_mode(c)) { - - case EVP_CIPH_WRAP_MODE: - ret = 1; - break; - - case EVP_CIPH_GCM_MODE: - case EVP_CIPH_CCM_MODE: - case EVP_CIPH_XTS_MODE: - ret = -1; - break; - - default: - ret = EVP_CIPHER_get_asn1_iv(c, type); - break; - } - } else - ret = -1; - return (ret); -} - -int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - int i = 0; - unsigned int l; - - if (type != NULL) { - l = EVP_CIPHER_CTX_iv_length(c); - OPENSSL_assert(l <= sizeof(c->iv)); - i = ASN1_TYPE_get_octetstring(type, c->oiv, l); - if (i != (int)l) - return (-1); - else if (i > 0) - memcpy(c->iv, c->oiv, l); - } - return (i); -} - -int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) -{ - int i = 0; - unsigned int j; - - if (type != NULL) { - j = EVP_CIPHER_CTX_iv_length(c); - OPENSSL_assert(j <= sizeof(c->iv)); - i = ASN1_TYPE_set_octetstring(type, c->oiv, j); - } - return (i); -} - -/* Convert the various cipher NIDs and dummies to a proper OID NID */ -int EVP_CIPHER_type(const EVP_CIPHER *ctx) -{ - int nid; - ASN1_OBJECT *otmp; - nid = EVP_CIPHER_nid(ctx); - - switch (nid) { - - case NID_rc2_cbc: - case NID_rc2_64_cbc: - case NID_rc2_40_cbc: - - return NID_rc2_cbc; - - case NID_rc4: - case NID_rc4_40: - - return NID_rc4; - - case NID_aes_128_cfb128: - case NID_aes_128_cfb8: - case NID_aes_128_cfb1: - - return NID_aes_128_cfb128; - - case NID_aes_192_cfb128: - case NID_aes_192_cfb8: - case NID_aes_192_cfb1: - - return NID_aes_192_cfb128; - - case NID_aes_256_cfb128: - case NID_aes_256_cfb8: - case NID_aes_256_cfb1: - - return NID_aes_256_cfb128; - - case NID_des_cfb64: - case NID_des_cfb8: - case NID_des_cfb1: - - return NID_des_cfb64; - - case NID_des_ede3_cfb64: - case NID_des_ede3_cfb8: - case NID_des_ede3_cfb1: - - return NID_des_cfb64; - - default: - /* Check it has an OID and it is valid */ - otmp = OBJ_nid2obj(nid); - if (!otmp || !otmp->data) - nid = NID_undef; - ASN1_OBJECT_free(otmp); - return nid; - } -} - -int EVP_CIPHER_block_size(const EVP_CIPHER *e) -{ - return e->block_size; -} - -int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher->block_size; -} - -int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) -{ - return ctx->cipher->do_cipher(ctx, out, in, inl); -} - -const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher; -} - -unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) -{ -#ifdef OPENSSL_FIPS - const EVP_CIPHER *fcipher; - fcipher = evp_get_fips_cipher(cipher); - if (fcipher && fcipher->flags & EVP_CIPH_FLAG_FIPS) - return cipher->flags | EVP_CIPH_FLAG_FIPS; -#endif - return cipher->flags; -} - -unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) -{ -#ifdef OPENSSL_FIPS - return EVP_CIPHER_flags(ctx->cipher); -#else - return ctx->cipher->flags; -#endif -} - -void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) -{ - return ctx->app_data; -} - -void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) -{ - ctx->app_data = data; -} - -int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) -{ - return cipher->iv_len; -} - -int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher->iv_len; -} - -int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) -{ - return cipher->key_len; -} - -int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) -{ - return ctx->key_len; -} - -int EVP_CIPHER_nid(const EVP_CIPHER *cipher) -{ - return cipher->nid; -} - -int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) -{ - return ctx->cipher->nid; -} - -int EVP_MD_block_size(const EVP_MD *md) -{ - return md->block_size; -} - -int EVP_MD_type(const EVP_MD *md) -{ - return md->type; -} - -int EVP_MD_pkey_type(const EVP_MD *md) -{ - return md->pkey_type; -} - -int EVP_MD_size(const EVP_MD *md) -{ - if (!md) { - EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); - return -1; - } - return md->md_size; -} - -#ifdef OPENSSL_FIPS - -const EVP_MD *evp_get_fips_md(const EVP_MD *md) -{ - int nid = EVP_MD_type(md); - if (nid == NID_dsa) - return FIPS_evp_dss1(); - else if (nid == NID_dsaWithSHA) - return FIPS_evp_dss(); - else if (nid == NID_ecdsa_with_SHA1) - return FIPS_evp_ecdsa(); - else - return FIPS_get_digestbynid(nid); -} - -const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher) -{ - int nid = cipher->nid; - if (nid == NID_undef) - return FIPS_evp_enc_null(); - else - return FIPS_get_cipherbynid(nid); -} - -#endif - -unsigned long EVP_MD_flags(const EVP_MD *md) -{ -#ifdef OPENSSL_FIPS - const EVP_MD *fmd; - fmd = evp_get_fips_md(md); - if (fmd && fmd->flags & EVP_MD_FLAG_FIPS) - return md->flags | EVP_MD_FLAG_FIPS; -#endif - return md->flags; -} - -const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) -{ - if (!ctx) - return NULL; - return ctx->digest; -} - -void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) -{ - ctx->flags |= flags; -} - -void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) -{ - ctx->flags &= ~flags; -} - -int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) -{ - return (ctx->flags & flags); -} - -void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) -{ - ctx->flags |= flags; -} - -void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) -{ - ctx->flags &= ~flags; -} - -int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) -{ - return (ctx->flags & flags); -} -/* evp_pbe.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -#include "pkcs12.h" -// #include "x509.h" -// #include "evp_locl.h" - -/* Password based encryption (PBE) functions */ - -DECLARE_STACK_OF(EVP_PBE_CTL) -static STACK_OF(EVP_PBE_CTL) *pbe_algs; - -/* Setup a cipher context from a PBE algorithm */ - -typedef struct { - int pbe_type; - int pbe_nid; - int cipher_nid; - int md_nid; - EVP_PBE_KEYGEN *keygen; -} EVP_PBE_CTL; - -static const EVP_PBE_CTL builtin_pbe[] = { - {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, - NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, - NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, - NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen}, - -#ifndef OPENSSL_NO_HMAC - {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, -#endif - - {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, - NID_rc4, NID_sha1, PKCS12_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, - NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, - NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, - NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, - NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, - NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen}, - -#ifndef OPENSSL_NO_HMAC - {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen}, -#endif - {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, - NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, - NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen}, - {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, - NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen}, - - {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, - {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0}, - {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0}, - {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0}, - {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, - {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, - {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, -}; - -#ifdef TEST -int main(int argc, char **argv) -{ - int i, nid_md, nid_cipher; - EVP_PBE_CTL *tpbe, *tpbe2; - /* - * OpenSSL_add_all_algorithms(); - */ - - for (i = 0; i < sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL); i++) { - tpbe = builtin_pbe + i; - fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid, - OBJ_nid2sn(tpbe->pbe_nid)); - if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid, - &nid_cipher, &nid_md, 0)) - fprintf(stderr, "Found %s %s\n", - OBJ_nid2sn(nid_cipher), OBJ_nid2sn(nid_md)); - else - fprintf(stderr, "Find ERROR!!\n"); - } - - return 0; -} -#endif - -int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, - ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) -{ - const EVP_CIPHER *cipher; - const EVP_MD *md; - int cipher_nid, md_nid; - EVP_PBE_KEYGEN *keygen; - - if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), - &cipher_nid, &md_nid, &keygen)) { - char obj_tmp[80]; - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM); - if (!pbe_obj) - BUF_strlcpy(obj_tmp, "NULL", sizeof(obj_tmp)); - else - i2t_ASN1_OBJECT(obj_tmp, sizeof(obj_tmp), pbe_obj); - ERR_add_error_data(2, "TYPE=", obj_tmp); - return 0; - } - - if (!pass) - passlen = 0; - else if (passlen == -1) - passlen = strlen(pass); - - if (cipher_nid == -1) - cipher = NULL; - else { - cipher = EVP_get_cipherbynid(cipher_nid); - if (!cipher) { - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER); - return 0; - } - } - - if (md_nid == -1) - md = NULL; - else { - md = EVP_get_digestbynid(md_nid); - if (!md) { - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST); - return 0; - } - } - - if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { - EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE); - return 0; - } - return 1; -} - -DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); - -static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2) -{ - int ret = pbe1->pbe_type - pbe2->pbe_type; - if (ret) - return ret; - else - return pbe1->pbe_nid - pbe2->pbe_nid; -} - -IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); - -static int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b) -{ - int ret = (*a)->pbe_type - (*b)->pbe_type; - if (ret) - return ret; - else - return (*a)->pbe_nid - (*b)->pbe_nid; -} - -/* Add a PBE algorithm */ - -int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, - int md_nid, EVP_PBE_KEYGEN *keygen) -{ - EVP_PBE_CTL *pbe_tmp; - - if (pbe_algs == NULL) { - pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); - if (pbe_algs == NULL) - goto err; - } - - if ((pbe_tmp = OPENSSL_malloc(sizeof(*pbe_tmp))) == NULL) - goto err; - - pbe_tmp->pbe_type = pbe_type; - pbe_tmp->pbe_nid = pbe_nid; - pbe_tmp->cipher_nid = cipher_nid; - pbe_tmp->md_nid = md_nid; - pbe_tmp->keygen = keygen; - - sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp); - return 1; - - err: - EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE); - return 0; -} - -int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, - EVP_PBE_KEYGEN *keygen) -{ - int cipher_nid, md_nid; - if (cipher) - cipher_nid = EVP_CIPHER_nid(cipher); - else - cipher_nid = -1; - if (md) - md_nid = EVP_MD_type(md); - else - md_nid = -1; - - return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid, - cipher_nid, md_nid, keygen); -} - -int EVP_PBE_find(int type, int pbe_nid, - int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) -{ - EVP_PBE_CTL *pbetmp = NULL, pbelu; - int i; - if (pbe_nid == NID_undef) - return 0; - - pbelu.pbe_type = type; - pbelu.pbe_nid = pbe_nid; - - if (pbe_algs) { - i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); - if (i != -1) - pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i); - } - if (pbetmp == NULL) { - pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, - sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL)); - } - if (pbetmp == NULL) - return 0; - if (pcnid) - *pcnid = pbetmp->cipher_nid; - if (pmnid) - *pmnid = pbetmp->md_nid; - if (pkeygen) - *pkeygen = pbetmp->keygen; - return 1; -} - -static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe) -{ - OPENSSL_freeFunc(pbe); -} - -void EVP_PBE_cleanup(void) -{ - sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl); - pbe_algs = NULL; -} -/* evp_pkey.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "x509.h" -// #include "rand.h" -#include "asn1_locl.h" - -/* Extract a private key from a PKCS8 structure */ - -EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) -{ - EVP_PKEY *pkey = NULL; - ASN1_OBJECT *algoid; - char obj_tmp[80]; - - if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) - return NULL; - - if (!(pkey = EVP_PKEY_new())) { - EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); - i2t_ASN1_OBJECT(obj_tmp, 80, algoid); - ERR_add_error_data(2, "TYPE=", obj_tmp); - goto error; - } - - if (pkey->ameth->priv_decode) { - if (!pkey->ameth->priv_decode(pkey, p8)) { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR); - goto error; - } - } else { - EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED); - goto error; - } - - return pkey; - - error: - EVP_PKEY_free(pkey); - return NULL; -} - -PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) -{ - return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK); -} - -/* Turn a private key into a PKCS8 structure */ - -PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) -{ - PKCS8_PRIV_KEY_INFO *p8; - - if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE); - return NULL; - } - p8->broken = broken; - - if (pkey->ameth) { - if (pkey->ameth->priv_encode) { - if (!pkey->ameth->priv_encode(p8, pkey)) { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, - EVP_R_PRIVATE_KEY_ENCODE_ERROR); - goto error; - } - } else { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_METHOD_NOT_SUPPORTED); - goto error; - } - } else { - EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, - EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); - goto error; - } - RAND_add(p8->pkey->value.octet_string->data, - p8->pkey->value.octet_string->length, 0.0); - return p8; - error: - PKCS8_PRIV_KEY_INFO_free(p8); - return NULL; -} - -PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) -{ - switch (broken) { - - case PKCS8_OK: - p8->broken = PKCS8_OK; - return p8; - break; - - case PKCS8_NO_OCTET: - p8->broken = PKCS8_NO_OCTET; - p8->pkey->type = V_ASN1_SEQUENCE; - return p8; - break; - - default: - EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE); - return NULL; - } -} - -/* EVP_PKEY attribute functions */ - -int EVP_PKEY_get_attr_count(const EVP_PKEY *key) -{ - return X509at_get_attr_count(key->attributes); -} - -int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos) -{ - return X509at_get_attr_by_NID(key->attributes, nid, lastpos); -} - -int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, - int lastpos) -{ - return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos); -} - -X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc) -{ - return X509at_get_attr(key->attributes, loc); -} - -X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc) -{ - return X509at_delete_attr(key->attributes, loc); -} - -int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr) -{ - if (X509at_add1_attr(&key->attributes, attr)) - return 1; - return 0; -} - -int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, - const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len)) - return 1; - return 0; -} - -int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, - int nid, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len)) - return 1; - return 0; -} - -int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, - const char *attrname, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len)) - return 1; - return 0; -} diff --git a/Sources/COpenSSL/evp_locl.h b/Sources/COpenSSL/evp_locl.h deleted file mode 100644 index bee7f6d1..00000000 --- a/Sources/COpenSSL/evp_locl.h +++ /dev/null @@ -1,373 +0,0 @@ -/* evp_locl.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* Macros to code block cipher wrappers */ - -/* Wrapper functions for each cipher mode */ - -#define BLOCK_CIPHER_ecb_loop() \ - size_t i, bl; \ - bl = ctx->cipher->block_size;\ - if(inl < bl) return 1;\ - inl -= bl; \ - for(i=0; i <= inl; i+=bl) - -#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \ -static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ -{\ - BLOCK_CIPHER_ecb_loop() \ - cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\ - return 1;\ -} - -#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2)) - -#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \ -static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ -{\ - while(inl>=EVP_MAXCHUNK)\ - {\ - cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ - inl-=EVP_MAXCHUNK;\ - in +=EVP_MAXCHUNK;\ - out+=EVP_MAXCHUNK;\ - }\ - if (inl)\ - cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ - return 1;\ -} - -#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \ -static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ -{\ - while(inl>=EVP_MAXCHUNK) \ - {\ - cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ - inl-=EVP_MAXCHUNK;\ - in +=EVP_MAXCHUNK;\ - out+=EVP_MAXCHUNK;\ - }\ - if (inl)\ - cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ - return 1;\ -} - -#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ -static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ -{\ - size_t chunk=EVP_MAXCHUNK;\ - if (cbits==1) chunk>>=3;\ - if (inl=chunk)\ - {\ - cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?chunk*8:chunk), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ - inl-=chunk;\ - in +=chunk;\ - out+=chunk;\ - if(inlc))+\ - sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ - set_asn1, get_asn1,\ - ctrl, \ - NULL \ -};\ -const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\ -static const EVP_CIPHER cname##_cfb = {\ - nid##_cfb64, 1, key_len, iv_len, \ - flags | EVP_CIPH_CFB_MODE,\ - init_key,\ - cname##_cfb_cipher,\ - cleanup,\ - sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ - sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ - set_asn1, get_asn1,\ - ctrl,\ - NULL \ -};\ -const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\ -static const EVP_CIPHER cname##_ofb = {\ - nid##_ofb64, 1, key_len, iv_len, \ - flags | EVP_CIPH_OFB_MODE,\ - init_key,\ - cname##_ofb_cipher,\ - cleanup,\ - sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ - sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ - set_asn1, get_asn1,\ - ctrl,\ - NULL \ -};\ -const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\ -static const EVP_CIPHER cname##_ecb = {\ - nid##_ecb, block_size, key_len, iv_len, \ - flags | EVP_CIPH_ECB_MODE,\ - init_key,\ - cname##_ecb_cipher,\ - cleanup,\ - sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ - sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ - set_asn1, get_asn1,\ - ctrl,\ - NULL \ -};\ -const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } -*/ - -#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \ - block_size, key_len, iv_len, cbits, \ - flags, init_key, \ - cleanup, set_asn1, get_asn1, ctrl) \ - BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \ - BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \ - cbits, flags, init_key, cleanup, set_asn1, \ - get_asn1, ctrl) - -#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data) - -#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \ - BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ - BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ - NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ - 0, cipher##_init_key, NULL, \ - EVP_CIPHER_set_asn1_iv, \ - EVP_CIPHER_get_asn1_iv, \ - NULL) - -struct evp_pkey_ctx_st { - /* Method associated with this operation */ - const EVP_PKEY_METHOD *pmeth; - /* Engine that implements this method or NULL if builtin */ - ENGINE *engine; - /* Key: may be NULL */ - EVP_PKEY *pkey; - /* Peer key for key agreement, may be NULL */ - EVP_PKEY *peerkey; - /* Actual operation */ - int operation; - /* Algorithm specific data */ - void *data; - /* Application specific data */ - void *app_data; - /* Keygen callback */ - EVP_PKEY_gen_cb *pkey_gencb; - /* implementation specific keygen data */ - int *keygen_info; - int keygen_info_count; -} /* EVP_PKEY_CTX */ ; - -#define EVP_PKEY_FLAG_DYNAMIC 1 - -struct evp_pkey_method_st { - int pkey_id; - int flags; - int (*init) (EVP_PKEY_CTX *ctx); - int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); - void (*cleanup) (EVP_PKEY_CTX *ctx); - int (*paramgen_init) (EVP_PKEY_CTX *ctx); - int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); - int (*keygen_init) (EVP_PKEY_CTX *ctx); - int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); - int (*sign_init) (EVP_PKEY_CTX *ctx); - int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbslen); - int (*verify_init) (EVP_PKEY_CTX *ctx); - int (*verify) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen); - int (*verify_recover_init) (EVP_PKEY_CTX *ctx); - int (*verify_recover) (EVP_PKEY_CTX *ctx, - unsigned char *rout, size_t *routlen, - const unsigned char *sig, size_t siglen); - int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); - int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - EVP_MD_CTX *mctx); - int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); - int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, - EVP_MD_CTX *mctx); - int (*encrypt_init) (EVP_PKEY_CTX *ctx); - int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen); - int (*decrypt_init) (EVP_PKEY_CTX *ctx); - int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen); - int (*derive_init) (EVP_PKEY_CTX *ctx); - int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); - int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); - int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); -} /* EVP_PKEY_METHOD */ ; - -void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); - -int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, - int passlen, ASN1_TYPE *param, - const EVP_CIPHER *c, const EVP_MD *md, - int en_de); - -const EVP_MD *evp_get_fips_md(const EVP_MD *md); -const EVP_CIPHER *evp_get_fips_cipher(const EVP_CIPHER *cipher); - -#ifdef OPENSSL_FIPS - -# ifdef OPENSSL_DOING_MAKEDEPEND -# undef SHA1_Init -# undef SHA1_Update -# undef SHA224_Init -# undef SHA256_Init -# undef SHA384_Init -# undef SHA512_Init -# undef DES_set_key_unchecked -# endif - -# define RIPEMD160_Init private_RIPEMD160_Init -# define WHIRLPOOL_Init private_WHIRLPOOL_Init -# define MD5_Init private_MD5_Init -# define MD4_Init private_MD4_Init -# define MD2_Init private_MD2_Init -# define MDC2_Init private_MDC2_Init -# define SHA_Init private_SHA_Init -# define SHA1_Init private_SHA1_Init -# define SHA224_Init private_SHA224_Init -# define SHA256_Init private_SHA256_Init -# define SHA384_Init private_SHA384_Init -# define SHA512_Init private_SHA512_Init - -# define BF_set_key private_BF_set_key -# define CAST_set_key private_CAST_set_key -# define idea_set_encrypt_key private_idea_set_encrypt_key -# define SEED_set_key private_SEED_set_key -# define RC2_set_key private_RC2_set_key -# define RC4_set_key private_RC4_set_key -# define DES_set_key_unchecked private_DES_set_key_unchecked -# define Camellia_set_key private_Camellia_set_key - -#endif diff --git a/Sources/COpenSSL/ex_data.c b/Sources/COpenSSL/ex_data.c deleted file mode 100644 index e52a5065..00000000 --- a/Sources/COpenSSL/ex_data.c +++ /dev/null @@ -1,660 +0,0 @@ -/* crypto/ex_data.c */ - -/* - * Overhaul notes; - * - * This code is now *mostly* thread-safe. It is now easier to understand in what - * ways it is safe and in what ways it is not, which is an improvement. Firstly, - * all per-class stacks and index-counters for ex_data are stored in the same - * global LHASH table (keyed by class). This hash table uses locking for all - * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be - * called when no other threads can possibly race against it (even if it was - * locked, the race would mean it's possible the hash table might have been - * recreated after the cleanup). As classes can only be added to the hash table, - * and within each class, the stack of methods can only be incremented, the - * locking mechanics are simpler than they would otherwise be. For example, the - * new/dup/free ex_data functions will lock the hash table, copy the method - * pointers it needs from the relevant class, then unlock the hash table before - * actually applying those method pointers to the task of the new/dup/free - * operations. As they can't be removed from the method-stack, only - * supplemented, there's no race conditions associated with using them outside - * the lock. The get/set_ex_data functions are not locked because they do not - * involve this global state at all - they operate directly with a previously - * obtained per-class method index and a particular "ex_data" variable. These - * variables are usually instantiated per-context (eg. each RSA structure has - * one) so locking on read/write access to that variable can be locked locally - * if required (eg. using the "RSA" lock to synchronise access to a - * per-RSA-structure ex_data variable if required). - * [Geoff] - */ - -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "cryptlib.h" -#include "lhash.h" - -/* What an "implementation of ex_data functionality" looks like */ -struct st_CRYPTO_EX_DATA_IMPL { - /*********************/ - /* GLOBAL OPERATIONS */ - /* Return a new class index */ - int (*cb_new_class) (void); - /* Cleanup all state used by the implementation */ - void (*cb_cleanup) (void); - /************************/ - /* PER-CLASS OPERATIONS */ - /* Get a new method index within a class */ - int (*cb_get_new_index) (int class_index, long argl, void *argp, - CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); - /* Initialise a new CRYPTO_EX_DATA of a given class */ - int (*cb_new_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad); - /* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */ - int (*cb_dup_ex_data) (int class_index, CRYPTO_EX_DATA *to, - CRYPTO_EX_DATA *from); - /* Cleanup a CRYPTO_EX_DATA of a given class */ - void (*cb_free_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad); -}; - -/* The implementation we use at run-time */ -static const CRYPTO_EX_DATA_IMPL *impl = NULL; - -/* - * To call "impl" functions, use this macro rather than referring to 'impl' - * directly, eg. EX_IMPL(get_new_index)(...); - */ -#define EX_IMPL(a) impl->cb_##a - -/* Predeclare the "default" ex_data implementation */ -static int int_new_class(void); -static void int_cleanup(void); -static int int_get_new_index(int class_index, long argl, void *argp, - CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); -static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); -static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, - CRYPTO_EX_DATA *from); -static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); -static CRYPTO_EX_DATA_IMPL impl_default = { - int_new_class, - int_cleanup, - int_get_new_index, - int_new_ex_data, - int_dup_ex_data, - int_free_ex_data -}; - -/* - * Internal function that checks whether "impl" is set and if not, sets it to - * the default. - */ -static void impl_check(void) -{ - CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); - if (!impl) - impl = &impl_default; - CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); -} - -/* - * A macro wrapper for impl_check that first uses a non-locked test before - * invoking the function (which checks again inside a lock). - */ -#define IMPL_CHECK if(!impl) impl_check(); - -/* API functions to get/set the "ex_data" implementation */ -const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void) -{ - IMPL_CHECK return impl; -} - -int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i) -{ - int toret = 0; - CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); - if (!impl) { - impl = i; - toret = 1; - } - CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); - return toret; -} - -/****************************************************************************/ -/* - * Interal (default) implementation of "ex_data" support. API functions are - * further down. - */ - -/* - * The type that represents what each "class" used to implement locally. A - * STACK of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is - * the global value representing the class that is used to distinguish these - * items. - */ -typedef struct st_ex_class_item { - int class_index; - STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth; - int meth_num; -} EX_CLASS_ITEM; - -/* When assigning new class indexes, this is our counter */ -static int ex_class = CRYPTO_EX_INDEX_USER; - -/* The global hash table of EX_CLASS_ITEM items */ -DECLARE_LHASH_OF(EX_CLASS_ITEM); -static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL; - -/* The callbacks required in the "ex_data" hash table */ -static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a) -{ - return a->class_index; -} - -static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM) - -static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b) -{ - return a->class_index - b->class_index; -} - -static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM) - -/* - * Internal functions used by the "impl_default" implementation to access the - * state - */ -static int ex_data_check(void) -{ - int toret = 1; - CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); - if (!ex_data && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL) - toret = 0; - CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); - return toret; -} - -/* - * This macros helps reduce the locking from repeated checks because the - * ex_data_check() function checks ex_data again inside a lock. - */ -#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail} - -/* This "inner" callback is used by the callback function that follows it */ -static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs) -{ - OPENSSL_free(funcs); -} - -/* - * This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from - * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't - * do any locking. - */ -static void def_cleanup_cb(void *a_void) -{ - EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void; - sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb); - OPENSSL_free(item); -} - -/* - * Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to - * a given class. Handles locking. - */ -static EX_CLASS_ITEM *def_get_class(int class_index) -{ - EX_CLASS_ITEM d, *p, *gen; - EX_DATA_CHECK(return NULL;) - d.class_index = class_index; - CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); - p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); - if (!p) { - gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM)); - if (gen) { - gen->class_index = class_index; - gen->meth_num = 0; - gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); - if (!gen->meth) - OPENSSL_free(gen); - else { - /* - * Because we're inside the ex_data lock, the return value - * from the insert will be NULL - */ - (void)lh_EX_CLASS_ITEM_insert(ex_data, gen); - p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); - if (p != gen) { - sk_CRYPTO_EX_DATA_FUNCS_free(gen->meth); - OPENSSL_free(gen); - } - } - } - } - CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); - if (!p) - CRYPTOerr(CRYPTO_F_DEF_GET_CLASS, ERR_R_MALLOC_FAILURE); - return p; -} - -/* - * Add a new method to the given EX_CLASS_ITEM and return the corresponding - * index (or -1 for error). Handles locking. - */ -static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp, - CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - int toret = -1; - CRYPTO_EX_DATA_FUNCS *a = - (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); - if (!a) { - CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE); - return -1; - } - a->argl = argl; - a->argp = argp; - a->new_func = new_func; - a->dup_func = dup_func; - a->free_func = free_func; - CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); - while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) { - if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) { - CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE); - OPENSSL_free(a); - goto err; - } - } - toret = item->meth_num++; - (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); - err: - CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); - return toret; -} - -/**************************************************************/ -/* The functions in the default CRYPTO_EX_DATA_IMPL structure */ - -static int int_new_class(void) -{ - int toret; - CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); - toret = ex_class++; - CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); - return toret; -} - -static void int_cleanup(void) -{ - EX_DATA_CHECK(return;) - lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb); - lh_EX_CLASS_ITEM_free(ex_data); - ex_data = NULL; - impl = NULL; -} - -static int int_get_new_index(int class_index, long argl, void *argp, - CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - EX_CLASS_ITEM *item = def_get_class(class_index); - if (!item) - return -1; - return def_add_index(item, argl, argp, new_func, dup_func, free_func); -} - -/* - * Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries - * in the lock, then using them outside the lock. NB: Thread-safety only - * applies to the global "ex_data" state (ie. class definitions), not - * thread-safe on 'ad' itself. - */ -static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) -{ - int mx, i; - void *ptr; - CRYPTO_EX_DATA_FUNCS **storage = NULL; - EX_CLASS_ITEM *item = def_get_class(class_index); - if (!item) - /* error is already set */ - return 0; - ad->sk = NULL; - CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); - mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); - if (mx > 0) { - storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); - if (!storage) - goto skip; - for (i = 0; i < mx; i++) - storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); - } - skip: - CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); - if ((mx > 0) && !storage) { - CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA, ERR_R_MALLOC_FAILURE); - return 0; - } - for (i = 0; i < mx; i++) { - if (storage[i] && storage[i]->new_func) { - ptr = CRYPTO_get_ex_data(ad, i); - storage[i]->new_func(obj, ptr, ad, i, - storage[i]->argl, storage[i]->argp); - } - } - if (storage) - OPENSSL_free(storage); - return 1; -} - -/* Same thread-safety notes as for "int_new_ex_data" */ -static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, - CRYPTO_EX_DATA *from) -{ - int mx, j, i; - void *ptr; - CRYPTO_EX_DATA_FUNCS **storage = NULL; - EX_CLASS_ITEM *item; - if (!from->sk) - /* 'to' should be "blank" which *is* just like 'from' */ - return 1; - if ((item = def_get_class(class_index)) == NULL) - return 0; - CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); - mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); - j = sk_void_num(from->sk); - if (j < mx) - mx = j; - if (mx > 0) { - /* - * Make sure the ex_data stack is at least |mx| elements long to avoid - * issues in the for loop that follows; so go get the |mx|'th element - * (if it does not exist CRYPTO_get_ex_data() returns NULL), and assign - * to itself. This is normally a no-op; but ensures the stack is the - * proper size - */ - if (!CRYPTO_set_ex_data(to, mx - 1, CRYPTO_get_ex_data(to, mx - 1))) - goto skip; - storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); - if (!storage) - goto skip; - for (i = 0; i < mx; i++) - storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); - } - skip: - CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); - if ((mx > 0) && !storage) { - CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA, ERR_R_MALLOC_FAILURE); - return 0; - } - for (i = 0; i < mx; i++) { - ptr = CRYPTO_get_ex_data(from, i); - if (storage[i] && storage[i]->dup_func) - storage[i]->dup_func(to, from, &ptr, i, - storage[i]->argl, storage[i]->argp); - CRYPTO_set_ex_data(to, i, ptr); - } - if (storage) - OPENSSL_free(storage); - return 1; -} - -/* Same thread-safety notes as for "int_new_ex_data" */ -static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) -{ - int mx, i; - EX_CLASS_ITEM *item; - void *ptr; - CRYPTO_EX_DATA_FUNCS *f; - CRYPTO_EX_DATA_FUNCS **storage = NULL; - if (ex_data == NULL) - goto err; - if ((item = def_get_class(class_index)) == NULL) - goto err; - CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); - mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); - if (mx > 0) { - storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); - if (!storage) - goto skip; - for (i = 0; i < mx; i++) - storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); - } - skip: - CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); - for (i = 0; i < mx; i++) { - if (storage != NULL) - f = storage[i]; - else { - CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); - f = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); - CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); - } - if (f != NULL && f->free_func != NULL) { - ptr = CRYPTO_get_ex_data(ad, i); - f->free_func(obj, ptr, ad, i, f->argl, f->argp); - } - } - OPENSSL_free(storage); - err: - sk_void_free(ad->sk); - ad->sk = NULL; -} - -/********************************************************************/ -/* - * API functions that defer all "state" operations to the "ex_data" - * implementation we have set. - */ - -/* - * Obtain an index for a new class (not the same as getting a new index - * within an existing class - this is actually getting a new *class*) - */ -int CRYPTO_ex_data_new_class(void) -{ - IMPL_CHECK return EX_IMPL(new_class) (); -} - -/* - * Release all "ex_data" state to prevent memory leaks. This can't be made - * thread-safe without overhauling a lot of stuff, and shouldn't really be - * called under potential race-conditions anyway (it's for program shutdown - * after all). - */ -void CRYPTO_cleanup_all_ex_data(void) -{ - IMPL_CHECK EX_IMPL(cleanup) (); -} - -/* Inside an existing class, get/register a new index. */ -int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, - CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - int ret = -1; - - IMPL_CHECK - ret = EX_IMPL(get_new_index) (class_index, - argl, argp, new_func, dup_func, - free_func); - return ret; -} - -/* - * Initialise a new CRYPTO_EX_DATA for use in a particular class - including - * calling new() callbacks for each index in the class used by this variable - */ -int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) -{ - IMPL_CHECK return EX_IMPL(new_ex_data) (class_index, obj, ad); -} - -/* - * Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks - * for each index in the class used by this variable - */ -int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, - CRYPTO_EX_DATA *from) -{ - IMPL_CHECK return EX_IMPL(dup_ex_data) (class_index, to, from); -} - -/* - * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for - * each index in the class used by this variable - */ -void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) -{ - IMPL_CHECK EX_IMPL(free_ex_data) (class_index, obj, ad); -} - -/* - * For a given CRYPTO_EX_DATA variable, set the value corresponding to a - * particular index in the class used by this variable - */ -int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) -{ - int i; - - if (ad->sk == NULL) { - if ((ad->sk = sk_void_new_null()) == NULL) { - CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE); - return (0); - } - } - i = sk_void_num(ad->sk); - - while (i <= idx) { - if (!sk_void_push(ad->sk, NULL)) { - CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE); - return (0); - } - i++; - } - sk_void_set(ad->sk, idx, val); - return (1); -} - -/* - * For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a - * particular index in the class used by this variable - */ -void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) -{ - if (ad->sk == NULL) - return (0); - else if (idx >= sk_void_num(ad->sk)) - return (0); - else - return (sk_void_value(ad->sk, idx)); -} - -IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS) diff --git a/Sources/COpenSSL/ext_dat.h b/Sources/COpenSSL/ext_dat.h deleted file mode 100644 index c3a6fce7..00000000 --- a/Sources/COpenSSL/ext_dat.h +++ /dev/null @@ -1,136 +0,0 @@ -/* ext_dat.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* This file contains a table of "standard" extensions */ - -extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; -extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; -extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; -extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; -extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; -extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; -extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; -extern X509V3_EXT_METHOD v3_crl_hold, v3_pci; -extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; -extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; -extern X509V3_EXT_METHOD v3_addr, v3_asid; -extern X509V3_EXT_METHOD v3_ct_scts[]; - -/* - * This table will be searched using OBJ_bsearch so it *must* kept in order - * of the ext_nid values. - */ - -static const X509V3_EXT_METHOD *standard_exts[] = { - &v3_nscert, - &v3_ns_ia5_list[0], - &v3_ns_ia5_list[1], - &v3_ns_ia5_list[2], - &v3_ns_ia5_list[3], - &v3_ns_ia5_list[4], - &v3_ns_ia5_list[5], - &v3_ns_ia5_list[6], - &v3_skey_id, - &v3_key_usage, - &v3_pkey_usage_period, - &v3_alt[0], - &v3_alt[1], - &v3_bcons, - &v3_crl_num, - &v3_cpols, - &v3_akey_id, - &v3_crld, - &v3_ext_ku, - &v3_delta_crl, - &v3_crl_reason, -#ifndef OPENSSL_NO_OCSP - &v3_crl_invdate, -#endif - &v3_sxnet, - &v3_info, -#ifndef OPENSSL_NO_RFC3779 - &v3_addr, - &v3_asid, -#endif -#ifndef OPENSSL_NO_OCSP - &v3_ocsp_nonce, - &v3_ocsp_crlid, - &v3_ocsp_accresp, - &v3_ocsp_nocheck, - &v3_ocsp_acutoff, - &v3_ocsp_serviceloc, -#endif - &v3_sinfo, - &v3_policy_constraints, -#ifndef OPENSSL_NO_OCSP - &v3_crl_hold, -#endif - &v3_pci, - &v3_name_constraints, - &v3_policy_mappings, - &v3_inhibit_anyp, - &v3_idp, - &v3_alt[2], - &v3_freshest_crl, - &v3_ct_scts[0], - &v3_ct_scts[1], -}; - -/* Number of standard extensions */ - -#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) diff --git a/Sources/COpenSSL/f_.c b/Sources/COpenSSL/f_.c deleted file mode 100644 index 48f83c99..00000000 --- a/Sources/COpenSSL/f_.c +++ /dev/null @@ -1,627 +0,0 @@ -/* crypto/asn1/f_enum.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "buffer.h" -#include "asn1.h" - -/* Based on a_int.c: equivalent ENUMERATED functions */ - -int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a) -{ - int i, n = 0; - static const char *h = "0123456789ABCDEF"; - char buf[2]; - - if (a == NULL) - return (0); - - if (a->length == 0) { - if (BIO_write(bp, "00", 2) != 2) - goto err; - n = 2; - } else { - for (i = 0; i < a->length; i++) { - if ((i != 0) && (i % 35 == 0)) { - if (BIO_write(bp, "\\\n", 2) != 2) - goto err; - n += 2; - } - buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; - buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; - if (BIO_write(bp, buf, 2) != 2) - goto err; - n += 2; - } - } - return (n); - err: - return (-1); -} - -int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) -{ - int ret = 0; - int i, j, k, m, n, again, bufsize; - unsigned char *s = NULL, *sp; - unsigned char *bufp; - int num = 0, slen = 0, first = 1; - - bs->type = V_ASN1_ENUMERATED; - - bufsize = BIO_gets(bp, buf, size); - for (;;) { - if (bufsize < 1) - goto err_sl; - i = bufsize; - if (buf[i - 1] == '\n') - buf[--i] = '\0'; - if (i == 0) - goto err_sl; - if (buf[i - 1] == '\r') - buf[--i] = '\0'; - if (i == 0) - goto err_sl; - again = (buf[i - 1] == '\\'); - - for (j = 0; j < i; j++) { - if (!(((buf[j] >= '0') && (buf[j] <= '9')) || - ((buf[j] >= 'a') && (buf[j] <= 'f')) || - ((buf[j] >= 'A') && (buf[j] <= 'F')))) { - i = j; - break; - } - } - buf[i] = '\0'; - /* - * We have now cleared all the crap off the end of the line - */ - if (i < 2) - goto err_sl; - - bufp = (unsigned char *)buf; - if (first) { - first = 0; - if ((bufp[0] == '0') && (bufp[1] == '0')) { - bufp += 2; - i -= 2; - } - } - k = 0; - i -= again; - if (i % 2 != 0) { - ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS); - goto err; - } - i /= 2; - if (num + i > slen) { - if (s == NULL) - sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + - i * 2); - else - sp = (unsigned char *)OPENSSL_realloc(s, - (unsigned int)num + - i * 2); - if (sp == NULL) { - ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); - goto err; - } - s = sp; - slen = num + i * 2; - } - for (j = 0; j < i; j++, k += 2) { - for (n = 0; n < 2; n++) { - m = bufp[k + n]; - if ((m >= '0') && (m <= '9')) - m -= '0'; - else if ((m >= 'a') && (m <= 'f')) - m = m - 'a' + 10; - else if ((m >= 'A') && (m <= 'F')) - m = m - 'A' + 10; - else { - ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, - ASN1_R_NON_HEX_CHARACTERS); - goto err; - } - s[num + j] <<= 4; - s[num + j] |= m; - } - } - num += i; - if (again) - bufsize = BIO_gets(bp, buf, size); - else - break; - } - bs->length = num; - bs->data = s; - ret = 1; - err: - if (0) { - err_sl: - ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE); - } - if (ret != 1) - OPENSSL_free(s); - return (ret); -} -/* crypto/asn1/f_int.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "asn1.h" - -int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a) -{ - int i, n = 0; - static const char *h = "0123456789ABCDEF"; - char buf[2]; - - if (a == NULL) - return (0); - - if (a->type & V_ASN1_NEG) { - if (BIO_write(bp, "-", 1) != 1) - goto err; - n = 1; - } - - if (a->length == 0) { - if (BIO_write(bp, "00", 2) != 2) - goto err; - n += 2; - } else { - for (i = 0; i < a->length; i++) { - if ((i != 0) && (i % 35 == 0)) { - if (BIO_write(bp, "\\\n", 2) != 2) - goto err; - n += 2; - } - buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; - buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; - if (BIO_write(bp, buf, 2) != 2) - goto err; - n += 2; - } - } - return (n); - err: - return (-1); -} - -int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) -{ - int ret = 0; - int i, j, k, m, n, again, bufsize; - unsigned char *s = NULL, *sp; - unsigned char *bufp; - int num = 0, slen = 0, first = 1; - - bs->type = V_ASN1_INTEGER; - - bufsize = BIO_gets(bp, buf, size); - for (;;) { - if (bufsize < 1) - goto err_sl; - i = bufsize; - if (buf[i - 1] == '\n') - buf[--i] = '\0'; - if (i == 0) - goto err_sl; - if (buf[i - 1] == '\r') - buf[--i] = '\0'; - if (i == 0) - goto err_sl; - again = (buf[i - 1] == '\\'); - - for (j = 0; j < i; j++) { -#ifndef CHARSET_EBCDIC - if (!(((buf[j] >= '0') && (buf[j] <= '9')) || - ((buf[j] >= 'a') && (buf[j] <= 'f')) || - ((buf[j] >= 'A') && (buf[j] <= 'F')))) -#else - /* - * This #ifdef is not strictly necessary, since the characters - * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but - * not the whole alphabet). Nevertheless, isxdigit() is faster. - */ - if (!isxdigit(buf[j])) -#endif - { - i = j; - break; - } - } - buf[i] = '\0'; - /* - * We have now cleared all the crap off the end of the line - */ - if (i < 2) - goto err_sl; - - bufp = (unsigned char *)buf; - if (first) { - first = 0; - if ((bufp[0] == '0') && (bufp[1] == '0')) { - bufp += 2; - i -= 2; - } - } - k = 0; - i -= again; - if (i % 2 != 0) { - ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS); - goto err; - } - i /= 2; - if (num + i > slen) { - if (s == NULL) - sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + - i * 2); - else - sp = OPENSSL_realloc_clean(s, slen, num + i * 2); - if (sp == NULL) { - ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); - goto err; - } - s = sp; - slen = num + i * 2; - } - for (j = 0; j < i; j++, k += 2) { - for (n = 0; n < 2; n++) { - m = bufp[k + n]; - if ((m >= '0') && (m <= '9')) - m -= '0'; - else if ((m >= 'a') && (m <= 'f')) - m = m - 'a' + 10; - else if ((m >= 'A') && (m <= 'F')) - m = m - 'A' + 10; - else { - ASN1err(ASN1_F_A2I_ASN1_INTEGER, - ASN1_R_NON_HEX_CHARACTERS); - goto err; - } - s[num + j] <<= 4; - s[num + j] |= m; - } - } - num += i; - if (again) - bufsize = BIO_gets(bp, buf, size); - else - break; - } - bs->length = num; - bs->data = s; - ret = 1; - err: - if (0) { - err_sl: - ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE); - } - if (ret != 1) - OPENSSL_free(s); - return (ret); -} -/* crypto/asn1/f_string.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "asn1.h" - -int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type) -{ - int i, n = 0; - static const char *h = "0123456789ABCDEF"; - char buf[2]; - - if (a == NULL) - return (0); - - if (a->length == 0) { - if (BIO_write(bp, "0", 1) != 1) - goto err; - n = 1; - } else { - for (i = 0; i < a->length; i++) { - if ((i != 0) && (i % 35 == 0)) { - if (BIO_write(bp, "\\\n", 2) != 2) - goto err; - n += 2; - } - buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; - buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; - if (BIO_write(bp, buf, 2) != 2) - goto err; - n += 2; - } - } - return (n); - err: - return (-1); -} - -int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) -{ - int ret = 0; - int i, j, k, m, n, again, bufsize; - unsigned char *s = NULL, *sp; - unsigned char *bufp; - int num = 0, slen = 0, first = 1; - - bufsize = BIO_gets(bp, buf, size); - for (;;) { - if (bufsize < 1) { - if (first) - break; - else - goto err_sl; - } - first = 0; - - i = bufsize; - if (buf[i - 1] == '\n') - buf[--i] = '\0'; - if (i == 0) - goto err_sl; - if (buf[i - 1] == '\r') - buf[--i] = '\0'; - if (i == 0) - goto err_sl; - again = (buf[i - 1] == '\\'); - - for (j = i - 1; j > 0; j--) { -#ifndef CHARSET_EBCDIC - if (!(((buf[j] >= '0') && (buf[j] <= '9')) || - ((buf[j] >= 'a') && (buf[j] <= 'f')) || - ((buf[j] >= 'A') && (buf[j] <= 'F')))) -#else - /* - * This #ifdef is not strictly necessary, since the characters - * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but - * not the whole alphabet). Nevertheless, isxdigit() is faster. - */ - if (!isxdigit(buf[j])) -#endif - { - i = j; - break; - } - } - buf[i] = '\0'; - /* - * We have now cleared all the crap off the end of the line - */ - if (i < 2) - goto err_sl; - - bufp = (unsigned char *)buf; - - k = 0; - i -= again; - if (i % 2 != 0) { - ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS); - goto err; - } - i /= 2; - if (num + i > slen) { - if (s == NULL) - sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + - i * 2); - else - sp = (unsigned char *)OPENSSL_realloc(s, - (unsigned int)num + - i * 2); - if (sp == NULL) { - ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE); - goto err; - } - s = sp; - slen = num + i * 2; - } - for (j = 0; j < i; j++, k += 2) { - for (n = 0; n < 2; n++) { - m = bufp[k + n]; - if ((m >= '0') && (m <= '9')) - m -= '0'; - else if ((m >= 'a') && (m <= 'f')) - m = m - 'a' + 10; - else if ((m >= 'A') && (m <= 'F')) - m = m - 'A' + 10; - else { - ASN1err(ASN1_F_A2I_ASN1_STRING, - ASN1_R_NON_HEX_CHARACTERS); - goto err; - } - s[num + j] <<= 4; - s[num + j] |= m; - } - } - num += i; - if (again) - bufsize = BIO_gets(bp, buf, size); - else - break; - } - bs->length = num; - bs->data = s; - ret = 1; - err: - if (0) { - err_sl: - ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE); - } - if (ret != 1) - OPENSSL_free(s); - return (ret); -} diff --git a/Sources/COpenSSL/fcrypt.c b/Sources/COpenSSL/fcrypt.c deleted file mode 100644 index cb7c5c59..00000000 --- a/Sources/COpenSSL/fcrypt.c +++ /dev/null @@ -1,167 +0,0 @@ -/* NOCW */ -#include -#ifdef _OSD_POSIX -# ifndef CHARSET_EBCDIC -# define CHARSET_EBCDIC 1 -# endif -#endif -#ifdef CHARSET_EBCDIC -# include "ebcdic.h" -#endif - -/* - * This version of crypt has been developed from my MIT compatible DES - * library. Eric Young (eay@cryptsoft.com) - */ - -/* - * Modification by Jens Kupferschmidt (Cu) I have included directive PARA for - * shared memory computers. I have included a directive LONGCRYPT to using - * this routine to cipher passwords with more then 8 bytes like HP-UX 10.x it - * used. The MAXPLEN definition is the maximum of length of password and can - * changed. I have defined 24. - */ - -#include "des_locl.h" - -/* - * Added more values to handle illegal salt values the way normal crypt() - * implementations do. The patch was sent by Bjorn Gronvall - */ -static unsigned const char con_salt[128] = { - 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, - 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, - 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, - 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, - 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, - 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, - 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, - 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, - 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, - 0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, - 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, - 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, - 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, -}; - -static unsigned const char cov_2char[64] = { - 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, - 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, - 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, - 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, - 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, - 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, - 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A -}; - -char *DES_crypt(const char *buf, const char *salt) -{ - static char buff[14]; - -#ifndef CHARSET_EBCDIC - return (DES_fcrypt(buf, salt, buff)); -#else - char e_salt[2 + 1]; - char e_buf[32 + 1]; /* replace 32 by 8 ? */ - char *ret; - - /* Copy at most 2 chars of salt */ - if ((e_salt[0] = salt[0]) != '\0') - e_salt[1] = salt[1]; - - /* Copy at most 32 chars of password */ - strncpy(e_buf, buf, sizeof(e_buf)); - - /* Make sure we have a delimiter */ - e_salt[sizeof(e_salt) - 1] = e_buf[sizeof(e_buf) - 1] = '\0'; - - /* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */ - ebcdic2ascii(e_salt, e_salt, sizeof(e_salt)); - - /* Convert the cleartext password to ASCII */ - ebcdic2ascii(e_buf, e_buf, sizeof(e_buf)); - - /* Encrypt it (from/to ASCII) */ - ret = DES_fcrypt(e_buf, e_salt, buff); - - /* Convert the result back to EBCDIC */ - ascii2ebcdic(ret, ret, strlen(ret)); - - return ret; -#endif -} - -char *DES_fcrypt(const char *buf, const char *salt, char *ret) -{ - unsigned int i, j, x, y; - DES_LONG Eswap0, Eswap1; - DES_LONG out[2], ll; - DES_cblock key; - DES_key_schedule ks; - unsigned char bb[9]; - unsigned char *b = bb; - unsigned char c, u; - - /* - * eay 25/08/92 If you call crypt("pwd","*") as often happens when you - * have * as the pwd field in /etc/passwd, the function returns - * *\0XXXXXXXXX The \0 makes the string look like * so the pwd "*" would - * crypt to "*". This was found when replacing the crypt in our shared - * libraries. People found that the disabled accounts effectively had no - * passwd :-(. - */ -#ifndef CHARSET_EBCDIC - x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]); - Eswap0 = con_salt[x] << 2; - x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]); - Eswap1 = con_salt[x] << 6; -#else - x = ret[0] = ((salt[0] == '\0') ? os_toascii['A'] : salt[0]); - Eswap0 = con_salt[x] << 2; - x = ret[1] = ((salt[1] == '\0') ? os_toascii['A'] : salt[1]); - Eswap1 = con_salt[x] << 6; -#endif - - /* - * EAY r=strlen(buf); r=(r+7)/8; - */ - for (i = 0; i < 8; i++) { - c = *(buf++); - if (!c) - break; - key[i] = (c << 1); - } - for (; i < 8; i++) - key[i] = 0; - - DES_set_key_unchecked(&key, &ks); - fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1); - - ll = out[0]; - l2c(ll, b); - ll = out[1]; - l2c(ll, b); - y = 0; - u = 0x80; - bb[8] = 0; - for (i = 2; i < 13; i++) { - c = 0; - for (j = 0; j < 6; j++) { - c <<= 1; - if (bb[y] & u) - c |= 1; - u >>= 1; - if (!u) { - y++; - u = 0x80; - } - } - ret[i] = cov_2char[c]; - } - ret[13] = '\0'; - return (ret); -} diff --git a/Sources/COpenSSL/fcrypt_b.c b/Sources/COpenSSL/fcrypt_b.c deleted file mode 100644 index b9e87383..00000000 --- a/Sources/COpenSSL/fcrypt_b.c +++ /dev/null @@ -1,140 +0,0 @@ -/* crypto/des/fcrypt_b.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include - -/* - * This version of crypt has been developed from my MIT compatible DES - * library. The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au - * Eric Young (eay@cryptsoft.com) - */ - -#define DES_FCRYPT -#include "des_locl.h" -#undef DES_FCRYPT - -#undef PERM_OP -#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ - (b)^=(t),\ - (a)^=((t)<<(n))) - -#undef HPERM_OP -#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ - (a)=(a)^(t)^(t>>(16-(n))))\ - -void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0, - DES_LONG Eswap1) -{ - register DES_LONG l, r, t, u; -#ifdef DES_PTR - register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; -#endif - register DES_LONG *s; - register int j; - register DES_LONG E0, E1; - - l = 0; - r = 0; - - s = (DES_LONG *)ks; - E0 = Eswap0; - E1 = Eswap1; - - for (j = 0; j < 25; j++) { -#ifndef DES_UNROLL - register int i; - - for (i = 0; i < 32; i += 4) { - D_ENCRYPT(l, r, i + 0); /* 1 */ - D_ENCRYPT(r, l, i + 2); /* 2 */ - } -#else - D_ENCRYPT(l, r, 0); /* 1 */ - D_ENCRYPT(r, l, 2); /* 2 */ - D_ENCRYPT(l, r, 4); /* 3 */ - D_ENCRYPT(r, l, 6); /* 4 */ - D_ENCRYPT(l, r, 8); /* 5 */ - D_ENCRYPT(r, l, 10); /* 6 */ - D_ENCRYPT(l, r, 12); /* 7 */ - D_ENCRYPT(r, l, 14); /* 8 */ - D_ENCRYPT(l, r, 16); /* 9 */ - D_ENCRYPT(r, l, 18); /* 10 */ - D_ENCRYPT(l, r, 20); /* 11 */ - D_ENCRYPT(r, l, 22); /* 12 */ - D_ENCRYPT(l, r, 24); /* 13 */ - D_ENCRYPT(r, l, 26); /* 14 */ - D_ENCRYPT(l, r, 28); /* 15 */ - D_ENCRYPT(r, l, 30); /* 16 */ -#endif - - t = l; - l = r; - r = t; - } - l = ROTATE(l, 3) & 0xffffffffL; - r = ROTATE(r, 3) & 0xffffffffL; - - PERM_OP(l, r, t, 1, 0x55555555L); - PERM_OP(r, l, t, 8, 0x00ff00ffL); - PERM_OP(l, r, t, 2, 0x33333333L); - PERM_OP(r, l, t, 16, 0x0000ffffL); - PERM_OP(l, r, t, 4, 0x0f0f0f0fL); - - out[0] = r; - out[1] = l; -} diff --git a/Sources/COpenSSL/fips_err.h b/Sources/COpenSSL/fips_err.h deleted file mode 100644 index 478cf0e2..00000000 --- a/Sources/COpenSSL/fips_err.h +++ /dev/null @@ -1,223 +0,0 @@ -/* crypto/fips_err.h */ -/* ==================================================================== - * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason) - -static ERR_STRING_DATA FIPS_str_functs[] = { - {ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, - {ERR_FUNC(FIPS_F_DH_INIT), "DH_INIT"}, - {ERR_FUNC(FIPS_F_DRBG_RESEED), "DRBG_RESEED"}, - {ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"}, - {ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"}, - {ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"}, - {ERR_FUNC(FIPS_F_DSA_DO_VERIFY), "DSA_do_verify"}, - {ERR_FUNC(FIPS_F_FIPS_CHECK_DSA), "FIPS_CHECK_DSA"}, - {ERR_FUNC(FIPS_F_FIPS_CHECK_DSA_PRNG), "fips_check_dsa_prng"}, - {ERR_FUNC(FIPS_F_FIPS_CHECK_EC), "FIPS_CHECK_EC"}, - {ERR_FUNC(FIPS_F_FIPS_CHECK_EC_PRNG), "fips_check_ec_prng"}, - {ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT), - "FIPS_check_incore_fingerprint"}, - {ERR_FUNC(FIPS_F_FIPS_CHECK_RSA), "fips_check_rsa"}, - {ERR_FUNC(FIPS_F_FIPS_CHECK_RSA_PRNG), "fips_check_rsa_prng"}, - {ERR_FUNC(FIPS_F_FIPS_CIPHER), "FIPS_cipher"}, - {ERR_FUNC(FIPS_F_FIPS_CIPHERINIT), "FIPS_cipherinit"}, - {ERR_FUNC(FIPS_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"}, - {ERR_FUNC(FIPS_F_FIPS_DIGESTFINAL), "FIPS_digestfinal"}, - {ERR_FUNC(FIPS_F_FIPS_DIGESTINIT), "FIPS_digestinit"}, - {ERR_FUNC(FIPS_F_FIPS_DIGESTUPDATE), "FIPS_digestupdate"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_BYTES), "FIPS_DRBG_BYTES"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_CHECK), "FIPS_DRBG_CHECK"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_CPRNG_TEST), "FIPS_DRBG_CPRNG_TEST"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_ERROR_CHECK), "FIPS_DRBG_ERROR_CHECK"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE), "FIPS_drbg_generate"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_INIT), "FIPS_drbg_init"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE), "FIPS_drbg_instantiate"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_NEW), "FIPS_drbg_new"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_RESEED), "FIPS_drbg_reseed"}, - {ERR_FUNC(FIPS_F_FIPS_DRBG_SINGLE_KAT), "FIPS_DRBG_SINGLE_KAT"}, - {ERR_FUNC(FIPS_F_FIPS_DSA_SIGN_DIGEST), "FIPS_dsa_sign_digest"}, - {ERR_FUNC(FIPS_F_FIPS_DSA_VERIFY_DIGEST), "FIPS_dsa_verify_digest"}, - {ERR_FUNC(FIPS_F_FIPS_GET_ENTROPY), "FIPS_GET_ENTROPY"}, - {ERR_FUNC(FIPS_F_FIPS_MODULE_MODE_SET), "FIPS_module_mode_set"}, - {ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST), "fips_pkey_signature_test"}, - {ERR_FUNC(FIPS_F_FIPS_RAND_ADD), "FIPS_rand_add"}, - {ERR_FUNC(FIPS_F_FIPS_RAND_BYTES), "FIPS_rand_bytes"}, - {ERR_FUNC(FIPS_F_FIPS_RAND_PSEUDO_BYTES), "FIPS_rand_pseudo_bytes"}, - {ERR_FUNC(FIPS_F_FIPS_RAND_SEED), "FIPS_rand_seed"}, - {ERR_FUNC(FIPS_F_FIPS_RAND_SET_METHOD), "FIPS_rand_set_method"}, - {ERR_FUNC(FIPS_F_FIPS_RAND_STATUS), "FIPS_rand_status"}, - {ERR_FUNC(FIPS_F_FIPS_RSA_SIGN_DIGEST), "FIPS_rsa_sign_digest"}, - {ERR_FUNC(FIPS_F_FIPS_RSA_VERIFY_DIGEST), "FIPS_rsa_verify_digest"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_CCM), "FIPS_selftest_aes_ccm"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_GCM), "FIPS_selftest_aes_gcm"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_XTS), "FIPS_selftest_aes_xts"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_CMAC), "FIPS_selftest_cmac"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_ECDSA), "FIPS_selftest_ecdsa"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC), "FIPS_selftest_hmac"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"}, - {ERR_FUNC(FIPS_F_FIPS_SELFTEST_X931), "FIPS_selftest_x931"}, - {ERR_FUNC(FIPS_F_FIPS_SET_PRNG_KEY), "FIPS_SET_PRNG_KEY"}, - {ERR_FUNC(FIPS_F_HASH_FINAL), "HASH_FINAL"}, - {ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, - {ERR_FUNC(FIPS_F_RSA_EAY_INIT), "RSA_EAY_INIT"}, - {ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, - {ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"}, - {ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"}, - {ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"}, - {ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX), "RSA_X931_generate_key_ex"}, - {0, NULL} -}; - -static ERR_STRING_DATA FIPS_str_reasons[] = { - {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED), - "additional input error undetected"}, - {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_TOO_LONG), - "additional input too long"}, - {ERR_REASON(FIPS_R_ALREADY_INSTANTIATED), "already instantiated"}, - {ERR_REASON(FIPS_R_AUTHENTICATION_FAILURE), "authentication failure"}, - {ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE), "contradicting evidence"}, - {ERR_REASON(FIPS_R_DRBG_NOT_INITIALISED), "drbg not initialised"}, - {ERR_REASON(FIPS_R_DRBG_STUCK), "drbg stuck"}, - {ERR_REASON(FIPS_R_ENTROPY_ERROR_UNDETECTED), "entropy error undetected"}, - {ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED), - "entropy not requested for reseed"}, - {ERR_REASON(FIPS_R_ENTROPY_SOURCE_STUCK), "entropy source stuck"}, - {ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, - {ERR_REASON(FIPS_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, - {ERR_REASON(FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT), - "error retrieving additional input"}, - {ERR_REASON(FIPS_R_ERROR_RETRIEVING_ENTROPY), "error retrieving entropy"}, - {ERR_REASON(FIPS_R_ERROR_RETRIEVING_NONCE), "error retrieving nonce"}, - {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH), - "fingerprint does not match"}, - {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED), - "fingerprint does not match nonpic relocated"}, - {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING), - "fingerprint does not match segment aliasing"}, - {ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET), "fips mode already set"}, - {ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED), "fips selftest failed"}, - {ERR_REASON(FIPS_R_FUNCTION_ERROR), "function error"}, - {ERR_REASON(FIPS_R_GENERATE_ERROR), "generate error"}, - {ERR_REASON(FIPS_R_GENERATE_ERROR_UNDETECTED), - "generate error undetected"}, - {ERR_REASON(FIPS_R_INSTANTIATE_ERROR), "instantiate error"}, - {ERR_REASON(FIPS_R_INSUFFICIENT_SECURITY_STRENGTH), - "insufficient security strength"}, - {ERR_REASON(FIPS_R_INTERNAL_ERROR), "internal error"}, - {ERR_REASON(FIPS_R_INVALID_KEY_LENGTH), "invalid key length"}, - {ERR_REASON(FIPS_R_INVALID_PARAMETERS), "invalid parameters"}, - {ERR_REASON(FIPS_R_IN_ERROR_STATE), "in error state"}, - {ERR_REASON(FIPS_R_KEY_TOO_SHORT), "key too short"}, - {ERR_REASON(FIPS_R_NONCE_ERROR_UNDETECTED), "nonce error undetected"}, - {ERR_REASON(FIPS_R_NON_FIPS_METHOD), "non fips method"}, - {ERR_REASON(FIPS_R_NOPR_TEST1_FAILURE), "nopr test1 failure"}, - {ERR_REASON(FIPS_R_NOPR_TEST2_FAILURE), "nopr test2 failure"}, - {ERR_REASON(FIPS_R_NOT_INSTANTIATED), "not instantiated"}, - {ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED), "pairwise test failed"}, - {ERR_REASON(FIPS_R_PERSONALISATION_ERROR_UNDETECTED), - "personalisation error undetected"}, - {ERR_REASON(FIPS_R_PERSONALISATION_STRING_TOO_LONG), - "personalisation string too long"}, - {ERR_REASON(FIPS_R_PRNG_STRENGTH_TOO_LOW), "prng strength too low"}, - {ERR_REASON(FIPS_R_PR_TEST1_FAILURE), "pr test1 failure"}, - {ERR_REASON(FIPS_R_PR_TEST2_FAILURE), "pr test2 failure"}, - {ERR_REASON(FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED), - "request length error undetected"}, - {ERR_REASON(FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG), - "request too large for drbg"}, - {ERR_REASON(FIPS_R_RESEED_COUNTER_ERROR), "reseed counter error"}, - {ERR_REASON(FIPS_R_RESEED_ERROR), "reseed error"}, - {ERR_REASON(FIPS_R_SELFTEST_FAILED), "selftest failed"}, - {ERR_REASON(FIPS_R_SELFTEST_FAILURE), "selftest failure"}, - {ERR_REASON(FIPS_R_STRENGTH_ERROR_UNDETECTED), - "strength error undetected"}, - {ERR_REASON(FIPS_R_TEST_FAILURE), "test failure"}, - {ERR_REASON(FIPS_R_UNINSTANTIATE_ERROR), "uninstantiate error"}, - {ERR_REASON(FIPS_R_UNINSTANTIATE_ZEROISE_ERROR), - "uninstantiate zeroise error"}, - {ERR_REASON(FIPS_R_UNSUPPORTED_DRBG_TYPE), "unsupported drbg type"}, - {ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM), "unsupported platform"}, - {0, NULL} -}; - -#endif - -void ERR_load_FIPS_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL) { - ERR_load_strings(0, FIPS_str_functs); - ERR_load_strings(0, FIPS_str_reasons); - } -#endif -} diff --git a/Sources/COpenSSL/fips_ers.c b/Sources/COpenSSL/fips_ers.c deleted file mode 100644 index 4a030805..00000000 --- a/Sources/COpenSSL/fips_ers.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "opensslconf.h" - -#ifdef OPENSSL_FIPS -# include "fips_err.h" -#else -static void *dummy = &dummy; -#endif diff --git a/Sources/COpenSSL/gcm128.c b/Sources/COpenSSL/gcm128.c deleted file mode 100644 index 71bb8a83..00000000 --- a/Sources/COpenSSL/gcm128.c +++ /dev/null @@ -1,2371 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2010 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#define OPENSSL_FIPSAPI - -#include "crypto.h" -#include "modes_lcl.h" -#include - -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -#if defined(BSWAP4) && defined(STRICT_ALIGNMENT) -/* redefine, because alignment is ensured */ -# undef GETU32 -# define GETU32(p) BSWAP4(*(const u32 *)(p)) -# undef PUTU32 -# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) -#endif - -#define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16)) -#define REDUCE1BIT(V) do { \ - if (sizeof(size_t)==8) { \ - u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \ - V.lo = (V.hi<<63)|(V.lo>>1); \ - V.hi = (V.hi>>1 )^T; \ - } \ - else { \ - u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \ - V.lo = (V.hi<<63)|(V.lo>>1); \ - V.hi = (V.hi>>1 )^((u64)T<<32); \ - } \ -} while(0) - -/*- - * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should - * never be set to 8. 8 is effectively reserved for testing purposes. - * TABLE_BITS>1 are lookup-table-driven implementations referred to as - * "Shoup's" in GCM specification. In other words OpenSSL does not cover - * whole spectrum of possible table driven implementations. Why? In - * non-"Shoup's" case memory access pattern is segmented in such manner, - * that it's trivial to see that cache timing information can reveal - * fair portion of intermediate hash value. Given that ciphertext is - * always available to attacker, it's possible for him to attempt to - * deduce secret parameter H and if successful, tamper with messages - * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's - * not as trivial, but there is no reason to believe that it's resistant - * to cache-timing attack. And the thing about "8-bit" implementation is - * that it consumes 16 (sixteen) times more memory, 4KB per individual - * key + 1KB shared. Well, on pros side it should be twice as fast as - * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version - * was observed to run ~75% faster, closer to 100% for commercial - * compilers... Yet "4-bit" procedure is preferred, because it's - * believed to provide better security-performance balance and adequate - * all-round performance. "All-round" refers to things like: - * - * - shorter setup time effectively improves overall timing for - * handling short messages; - * - larger table allocation can become unbearable because of VM - * subsystem penalties (for example on Windows large enough free - * results in VM working set trimming, meaning that consequent - * malloc would immediately incur working set expansion); - * - larger table has larger cache footprint, which can affect - * performance of other code paths (not necessarily even from same - * thread in Hyper-Threading world); - * - * Value of 1 is not appropriate for performance reasons. - */ -#if TABLE_BITS==8 - -static void gcm_init_8bit(u128 Htable[256], u64 H[2]) -{ - int i, j; - u128 V; - - Htable[0].hi = 0; - Htable[0].lo = 0; - V.hi = H[0]; - V.lo = H[1]; - - for (Htable[128] = V, i = 64; i > 0; i >>= 1) { - REDUCE1BIT(V); - Htable[i] = V; - } - - for (i = 2; i < 256; i <<= 1) { - u128 *Hi = Htable + i, H0 = *Hi; - for (j = 1; j < i; ++j) { - Hi[j].hi = H0.hi ^ Htable[j].hi; - Hi[j].lo = H0.lo ^ Htable[j].lo; - } - } -} - -static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) -{ - u128 Z = { 0, 0 }; - const u8 *xi = (const u8 *)Xi + 15; - size_t rem, n = *xi; - const union { - long one; - char little; - } is_endian = { - 1 - }; - static const size_t rem_8bit[256] = { - PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246), - PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E), - PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56), - PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E), - PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66), - PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E), - PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076), - PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E), - PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06), - PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E), - PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416), - PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E), - PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626), - PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E), - PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836), - PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E), - PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6), - PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE), - PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6), - PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE), - PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6), - PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE), - PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6), - PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE), - PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86), - PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E), - PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496), - PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E), - PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6), - PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE), - PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6), - PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE), - PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346), - PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E), - PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56), - PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E), - PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66), - PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E), - PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176), - PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E), - PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06), - PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E), - PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516), - PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E), - PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726), - PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E), - PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936), - PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E), - PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6), - PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE), - PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6), - PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE), - PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6), - PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE), - PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6), - PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE), - PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86), - PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E), - PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596), - PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E), - PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6), - PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE), - PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6), - PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE) - }; - - while (1) { - Z.hi ^= Htable[n].hi; - Z.lo ^= Htable[n].lo; - - if ((u8 *)Xi == xi) - break; - - n = *(--xi); - - rem = (size_t)Z.lo & 0xff; - Z.lo = (Z.hi << 56) | (Z.lo >> 8); - Z.hi = (Z.hi >> 8); - if (sizeof(size_t) == 8) - Z.hi ^= rem_8bit[rem]; - else - Z.hi ^= (u64)rem_8bit[rem] << 32; - } - - if (is_endian.little) { -# ifdef BSWAP8 - Xi[0] = BSWAP8(Z.hi); - Xi[1] = BSWAP8(Z.lo); -# else - u8 *p = (u8 *)Xi; - u32 v; - v = (u32)(Z.hi >> 32); - PUTU32(p, v); - v = (u32)(Z.hi); - PUTU32(p + 4, v); - v = (u32)(Z.lo >> 32); - PUTU32(p + 8, v); - v = (u32)(Z.lo); - PUTU32(p + 12, v); -# endif - } else { - Xi[0] = Z.hi; - Xi[1] = Z.lo; - } -} - -# define GCM_MUL(ctx,Xi) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable) - -#elif TABLE_BITS==4 - -static void gcm_init_4bit(u128 Htable[16], u64 H[2]) -{ - u128 V; -# if defined(OPENSSL_SMALL_FOOTPRINT) - int i; -# endif - - Htable[0].hi = 0; - Htable[0].lo = 0; - V.hi = H[0]; - V.lo = H[1]; - -# if defined(OPENSSL_SMALL_FOOTPRINT) - for (Htable[8] = V, i = 4; i > 0; i >>= 1) { - REDUCE1BIT(V); - Htable[i] = V; - } - - for (i = 2; i < 16; i <<= 1) { - u128 *Hi = Htable + i; - int j; - for (V = *Hi, j = 1; j < i; ++j) { - Hi[j].hi = V.hi ^ Htable[j].hi; - Hi[j].lo = V.lo ^ Htable[j].lo; - } - } -# else - Htable[8] = V; - REDUCE1BIT(V); - Htable[4] = V; - REDUCE1BIT(V); - Htable[2] = V; - REDUCE1BIT(V); - Htable[1] = V; - Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo; - V = Htable[4]; - Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo; - Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo; - Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo; - V = Htable[8]; - Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo; - Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo; - Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo; - Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo; - Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo; - Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo; - Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo; -# endif -# if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm)) - /* - * ARM assembler expects specific dword order in Htable. - */ - { - int j; - const union { - long one; - char little; - } is_endian = { - 1 - }; - - if (is_endian.little) - for (j = 0; j < 16; ++j) { - V = Htable[j]; - Htable[j].hi = V.lo; - Htable[j].lo = V.hi; - } else - for (j = 0; j < 16; ++j) { - V = Htable[j]; - Htable[j].hi = V.lo << 32 | V.lo >> 32; - Htable[j].lo = V.hi << 32 | V.hi >> 32; - } - } -# endif -} - -# ifndef GHASH_ASM -static const size_t rem_4bit[16] = { - PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460), - PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0), - PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560), - PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) -}; - -static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) -{ - u128 Z; - int cnt = 15; - size_t rem, nlo, nhi; - const union { - long one; - char little; - } is_endian = { - 1 - }; - - nlo = ((const u8 *)Xi)[15]; - nhi = nlo >> 4; - nlo &= 0xf; - - Z.hi = Htable[nlo].hi; - Z.lo = Htable[nlo].lo; - - while (1) { - rem = (size_t)Z.lo & 0xf; - Z.lo = (Z.hi << 60) | (Z.lo >> 4); - Z.hi = (Z.hi >> 4); - if (sizeof(size_t) == 8) - Z.hi ^= rem_4bit[rem]; - else - Z.hi ^= (u64)rem_4bit[rem] << 32; - - Z.hi ^= Htable[nhi].hi; - Z.lo ^= Htable[nhi].lo; - - if (--cnt < 0) - break; - - nlo = ((const u8 *)Xi)[cnt]; - nhi = nlo >> 4; - nlo &= 0xf; - - rem = (size_t)Z.lo & 0xf; - Z.lo = (Z.hi << 60) | (Z.lo >> 4); - Z.hi = (Z.hi >> 4); - if (sizeof(size_t) == 8) - Z.hi ^= rem_4bit[rem]; - else - Z.hi ^= (u64)rem_4bit[rem] << 32; - - Z.hi ^= Htable[nlo].hi; - Z.lo ^= Htable[nlo].lo; - } - - if (is_endian.little) { -# ifdef BSWAP8 - Xi[0] = BSWAP8(Z.hi); - Xi[1] = BSWAP8(Z.lo); -# else - u8 *p = (u8 *)Xi; - u32 v; - v = (u32)(Z.hi >> 32); - PUTU32(p, v); - v = (u32)(Z.hi); - PUTU32(p + 4, v); - v = (u32)(Z.lo >> 32); - PUTU32(p + 8, v); - v = (u32)(Z.lo); - PUTU32(p + 12, v); -# endif - } else { - Xi[0] = Z.hi; - Xi[1] = Z.lo; - } -} - -# if !defined(OPENSSL_SMALL_FOOTPRINT) -/* - * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for - * details... Compiler-generated code doesn't seem to give any - * performance improvement, at least not on x86[_64]. It's here - * mostly as reference and a placeholder for possible future - * non-trivial optimization[s]... - */ -static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], - const u8 *inp, size_t len) -{ - u128 Z; - int cnt; - size_t rem, nlo, nhi; - const union { - long one; - char little; - } is_endian = { - 1 - }; - -# if 1 - do { - cnt = 15; - nlo = ((const u8 *)Xi)[15]; - nlo ^= inp[15]; - nhi = nlo >> 4; - nlo &= 0xf; - - Z.hi = Htable[nlo].hi; - Z.lo = Htable[nlo].lo; - - while (1) { - rem = (size_t)Z.lo & 0xf; - Z.lo = (Z.hi << 60) | (Z.lo >> 4); - Z.hi = (Z.hi >> 4); - if (sizeof(size_t) == 8) - Z.hi ^= rem_4bit[rem]; - else - Z.hi ^= (u64)rem_4bit[rem] << 32; - - Z.hi ^= Htable[nhi].hi; - Z.lo ^= Htable[nhi].lo; - - if (--cnt < 0) - break; - - nlo = ((const u8 *)Xi)[cnt]; - nlo ^= inp[cnt]; - nhi = nlo >> 4; - nlo &= 0xf; - - rem = (size_t)Z.lo & 0xf; - Z.lo = (Z.hi << 60) | (Z.lo >> 4); - Z.hi = (Z.hi >> 4); - if (sizeof(size_t) == 8) - Z.hi ^= rem_4bit[rem]; - else - Z.hi ^= (u64)rem_4bit[rem] << 32; - - Z.hi ^= Htable[nlo].hi; - Z.lo ^= Htable[nlo].lo; - } -# else - /* - * Extra 256+16 bytes per-key plus 512 bytes shared tables - * [should] give ~50% improvement... One could have PACK()-ed - * the rem_8bit even here, but the priority is to minimize - * cache footprint... - */ - u128 Hshr4[16]; /* Htable shifted right by 4 bits */ - u8 Hshl4[16]; /* Htable shifted left by 4 bits */ - static const unsigned short rem_8bit[256] = { - 0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E, - 0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E, - 0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E, - 0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E, - 0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E, - 0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E, - 0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E, - 0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E, - 0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE, - 0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE, - 0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE, - 0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE, - 0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E, - 0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E, - 0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE, - 0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE, - 0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E, - 0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E, - 0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E, - 0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E, - 0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E, - 0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E, - 0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E, - 0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E, - 0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE, - 0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE, - 0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE, - 0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE, - 0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E, - 0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E, - 0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE, - 0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE - }; - /* - * This pre-processing phase slows down procedure by approximately - * same time as it makes each loop spin faster. In other words - * single block performance is approximately same as straightforward - * "4-bit" implementation, and then it goes only faster... - */ - for (cnt = 0; cnt < 16; ++cnt) { - Z.hi = Htable[cnt].hi; - Z.lo = Htable[cnt].lo; - Hshr4[cnt].lo = (Z.hi << 60) | (Z.lo >> 4); - Hshr4[cnt].hi = (Z.hi >> 4); - Hshl4[cnt] = (u8)(Z.lo << 4); - } - - do { - for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) { - nlo = ((const u8 *)Xi)[cnt]; - nlo ^= inp[cnt]; - nhi = nlo >> 4; - nlo &= 0xf; - - Z.hi ^= Htable[nlo].hi; - Z.lo ^= Htable[nlo].lo; - - rem = (size_t)Z.lo & 0xff; - - Z.lo = (Z.hi << 56) | (Z.lo >> 8); - Z.hi = (Z.hi >> 8); - - Z.hi ^= Hshr4[nhi].hi; - Z.lo ^= Hshr4[nhi].lo; - Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48; - } - - nlo = ((const u8 *)Xi)[0]; - nlo ^= inp[0]; - nhi = nlo >> 4; - nlo &= 0xf; - - Z.hi ^= Htable[nlo].hi; - Z.lo ^= Htable[nlo].lo; - - rem = (size_t)Z.lo & 0xf; - - Z.lo = (Z.hi << 60) | (Z.lo >> 4); - Z.hi = (Z.hi >> 4); - - Z.hi ^= Htable[nhi].hi; - Z.lo ^= Htable[nhi].lo; - Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48; -# endif - - if (is_endian.little) { -# ifdef BSWAP8 - Xi[0] = BSWAP8(Z.hi); - Xi[1] = BSWAP8(Z.lo); -# else - u8 *p = (u8 *)Xi; - u32 v; - v = (u32)(Z.hi >> 32); - PUTU32(p, v); - v = (u32)(Z.hi); - PUTU32(p + 4, v); - v = (u32)(Z.lo >> 32); - PUTU32(p + 8, v); - v = (u32)(Z.lo); - PUTU32(p + 12, v); -# endif - } else { - Xi[0] = Z.hi; - Xi[1] = Z.lo; - } - } while (inp += 16, len -= 16); -} -# endif -# else -void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -# endif - -# define GCM_MUL(ctx,Xi) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable) -# if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT) -# define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len) -/* - * GHASH_CHUNK is "stride parameter" missioned to mitigate cache trashing - * effect. In other words idea is to hash data while it's still in L1 cache - * after encryption pass... - */ -# define GHASH_CHUNK (3*1024) -# endif - -#else /* TABLE_BITS */ - -static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) -{ - u128 V, Z = { 0, 0 }; - long X; - int i, j; - const long *xi = (const long *)Xi; - const union { - long one; - char little; - } is_endian = { - 1 - }; - - V.hi = H[0]; /* H is in host byte order, no byte swapping */ - V.lo = H[1]; - - for (j = 0; j < 16 / sizeof(long); ++j) { - if (is_endian.little) { - if (sizeof(long) == 8) { -# ifdef BSWAP8 - X = (long)(BSWAP8(xi[j])); -# else - const u8 *p = (const u8 *)(xi + j); - X = (long)((u64)GETU32(p) << 32 | GETU32(p + 4)); -# endif - } else { - const u8 *p = (const u8 *)(xi + j); - X = (long)GETU32(p); - } - } else - X = xi[j]; - - for (i = 0; i < 8 * sizeof(long); ++i, X <<= 1) { - u64 M = (u64)(X >> (8 * sizeof(long) - 1)); - Z.hi ^= V.hi & M; - Z.lo ^= V.lo & M; - - REDUCE1BIT(V); - } - } - - if (is_endian.little) { -# ifdef BSWAP8 - Xi[0] = BSWAP8(Z.hi); - Xi[1] = BSWAP8(Z.lo); -# else - u8 *p = (u8 *)Xi; - u32 v; - v = (u32)(Z.hi >> 32); - PUTU32(p, v); - v = (u32)(Z.hi); - PUTU32(p + 4, v); - v = (u32)(Z.lo >> 32); - PUTU32(p + 8, v); - v = (u32)(Z.lo); - PUTU32(p + 12, v); -# endif - } else { - Xi[0] = Z.hi; - Xi[1] = Z.lo; - } -} - -# define GCM_MUL(ctx,Xi) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u) - -#endif - -#if TABLE_BITS==4 && (defined(GHASH_ASM) || defined(OPENSSL_CPUID_OBJ)) -# if !defined(I386_ONLY) && \ - (defined(__i386) || defined(__i386__) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) -# define GHASH_ASM_X86_OR_64 -# define GCM_FUNCREF_4BIT -extern unsigned int OPENSSL_ia32cap_P[]; - -void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]); -void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); - -# if defined(__i386) || defined(__i386__) || defined(_M_IX86) -# define gcm_init_avx gcm_init_clmul -# define gcm_gmult_avx gcm_gmult_clmul -# define gcm_ghash_avx gcm_ghash_clmul -# else -void gcm_init_avx(u128 Htable[16], const u64 Xi[2]); -void gcm_gmult_avx(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_avx(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -# endif - -# if defined(__i386) || defined(__i386__) || defined(_M_IX86) -# define GHASH_ASM_X86 -void gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); - -void gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -# endif -# elif defined(__arm__) || defined(__arm) || defined(__aarch64__) -# include "arm_arch.h" -# if __ARM_MAX_ARCH__>=7 -# define GHASH_ASM_ARM -# define GCM_FUNCREF_4BIT -# define PMULL_CAPABLE (OPENSSL_armcap_P & ARMV8_PMULL) -# if defined(__arm__) || defined(__arm) -# define NEON_CAPABLE (OPENSSL_armcap_P & ARMV7_NEON) -# endif -void gcm_init_neon(u128 Htable[16], const u64 Xi[2]); -void gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -void gcm_init_v8(u128 Htable[16], const u64 Xi[2]); -void gcm_gmult_v8(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_v8(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -# endif -# elif defined(__sparc__) || defined(__sparc) -# include "sparc_arch.h" -# define GHASH_ASM_SPARC -# define GCM_FUNCREF_4BIT -extern unsigned int OPENSSL_sparcv9cap_P[]; -void gcm_init_vis3(u128 Htable[16], const u64 Xi[2]); -void gcm_gmult_vis3(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_vis3(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -# elif defined(OPENSSL_CPUID_OBJ) && (defined(__powerpc__) || defined(__ppc__) || defined(_ARCH_PPC)) -# include "ppc_arch.h" -# define GHASH_ASM_PPC -# define GCM_FUNCREF_4BIT -void gcm_init_p8(u128 Htable[16], const u64 Xi[2]); -void gcm_gmult_p8(u64 Xi[2], const u128 Htable[16]); -void gcm_ghash_p8(u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -# endif -#endif - -#ifdef GCM_FUNCREF_4BIT -# undef GCM_MUL -# define GCM_MUL(ctx,Xi) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable) -# ifdef GHASH -# undef GHASH -# define GHASH(ctx,in,len) (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len) -# endif -#endif - -void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - - memset(ctx, 0, sizeof(*ctx)); - ctx->block = block; - ctx->key = key; - - (*block) (ctx->H.c, ctx->H.c, key); - - if (is_endian.little) { - /* H is stored in host byte order */ -#ifdef BSWAP8 - ctx->H.u[0] = BSWAP8(ctx->H.u[0]); - ctx->H.u[1] = BSWAP8(ctx->H.u[1]); -#else - u8 *p = ctx->H.c; - u64 hi, lo; - hi = (u64)GETU32(p) << 32 | GETU32(p + 4); - lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); - ctx->H.u[0] = hi; - ctx->H.u[1] = lo; -#endif - } -#if TABLE_BITS==8 - gcm_init_8bit(ctx->Htable, ctx->H.u); -#elif TABLE_BITS==4 -# if defined(GHASH_ASM_X86_OR_64) -# if !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2) - if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */ - OPENSSL_ia32cap_P[1] & (1 << 1)) { /* check PCLMULQDQ bit */ - if (((OPENSSL_ia32cap_P[1] >> 22) & 0x41) == 0x41) { /* AVX+MOVBE */ - gcm_init_avx(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_avx; - ctx->ghash = gcm_ghash_avx; - } else { - gcm_init_clmul(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_clmul; - ctx->ghash = gcm_ghash_clmul; - } - return; - } -# endif - gcm_init_4bit(ctx->Htable, ctx->H.u); -# if defined(GHASH_ASM_X86) /* x86 only */ -# if defined(OPENSSL_IA32_SSE2) - if (OPENSSL_ia32cap_P[0] & (1 << 25)) { /* check SSE bit */ -# else - if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */ -# endif - ctx->gmult = gcm_gmult_4bit_mmx; - ctx->ghash = gcm_ghash_4bit_mmx; - } else { - ctx->gmult = gcm_gmult_4bit_x86; - ctx->ghash = gcm_ghash_4bit_x86; - } -# else - ctx->gmult = gcm_gmult_4bit; - ctx->ghash = gcm_ghash_4bit; -# endif -# elif defined(GHASH_ASM_ARM) -# ifdef PMULL_CAPABLE - if (PMULL_CAPABLE) { - gcm_init_v8(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_v8; - ctx->ghash = gcm_ghash_v8; - } else -# endif -# ifdef NEON_CAPABLE - if (NEON_CAPABLE) { - gcm_init_neon(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_neon; - ctx->ghash = gcm_ghash_neon; - } else -# endif - { - gcm_init_4bit(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_4bit; -# if defined(GHASH) - ctx->ghash = gcm_ghash_4bit; -# else - ctx->ghash = NULL; -# endif - } -# elif defined(GHASH_ASM_SPARC) - if (OPENSSL_sparcv9cap_P[0] & SPARCV9_VIS3) { - gcm_init_vis3(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_vis3; - ctx->ghash = gcm_ghash_vis3; - } else { - gcm_init_4bit(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_4bit; - ctx->ghash = gcm_ghash_4bit; - } -# elif defined(GHASH_ASM_PPC) - if (OPENSSL_ppccap_P & PPC_CRYPTO207) { - gcm_init_p8(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_p8; - ctx->ghash = gcm_ghash_p8; - } else { - gcm_init_4bit(ctx->Htable, ctx->H.u); - ctx->gmult = gcm_gmult_4bit; -# if defined(GHASH) - ctx->ghash = gcm_ghash_4bit; -# else - ctx->ghash = NULL; -# endif - } -# else - gcm_init_4bit(ctx->Htable, ctx->H.u); -# endif -#endif -} - -void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, - size_t len) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - unsigned int ctr; -#ifdef GCM_FUNCREF_4BIT - void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -#endif - - ctx->Yi.u[0] = 0; - ctx->Yi.u[1] = 0; - ctx->Xi.u[0] = 0; - ctx->Xi.u[1] = 0; - ctx->len.u[0] = 0; /* AAD length */ - ctx->len.u[1] = 0; /* message length */ - ctx->ares = 0; - ctx->mres = 0; - - if (len == 12) { - memcpy(ctx->Yi.c, iv, 12); - ctx->Yi.c[15] = 1; - ctr = 1; - } else { - size_t i; - u64 len0 = len; - - while (len >= 16) { - for (i = 0; i < 16; ++i) - ctx->Yi.c[i] ^= iv[i]; - GCM_MUL(ctx, Yi); - iv += 16; - len -= 16; - } - if (len) { - for (i = 0; i < len; ++i) - ctx->Yi.c[i] ^= iv[i]; - GCM_MUL(ctx, Yi); - } - len0 <<= 3; - if (is_endian.little) { -#ifdef BSWAP8 - ctx->Yi.u[1] ^= BSWAP8(len0); -#else - ctx->Yi.c[8] ^= (u8)(len0 >> 56); - ctx->Yi.c[9] ^= (u8)(len0 >> 48); - ctx->Yi.c[10] ^= (u8)(len0 >> 40); - ctx->Yi.c[11] ^= (u8)(len0 >> 32); - ctx->Yi.c[12] ^= (u8)(len0 >> 24); - ctx->Yi.c[13] ^= (u8)(len0 >> 16); - ctx->Yi.c[14] ^= (u8)(len0 >> 8); - ctx->Yi.c[15] ^= (u8)(len0); -#endif - } else - ctx->Yi.u[1] ^= len0; - - GCM_MUL(ctx, Yi); - - if (is_endian.little) -#ifdef BSWAP4 - ctr = BSWAP4(ctx->Yi.d[3]); -#else - ctr = GETU32(ctx->Yi.c + 12); -#endif - else - ctr = ctx->Yi.d[3]; - } - - (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key); - ++ctr; - if (is_endian.little) -#ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -#else - PUTU32(ctx->Yi.c + 12, ctr); -#endif - else - ctx->Yi.d[3] = ctr; -} - -int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, - size_t len) -{ - size_t i; - unsigned int n; - u64 alen = ctx->len.u[0]; -#ifdef GCM_FUNCREF_4BIT - void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH - void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], - const u8 *inp, size_t len) = ctx->ghash; -# endif -#endif - - if (ctx->len.u[1]) - return -2; - - alen += len; - if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len)) - return -1; - ctx->len.u[0] = alen; - - n = ctx->ares; - if (n) { - while (n && len) { - ctx->Xi.c[n] ^= *(aad++); - --len; - n = (n + 1) % 16; - } - if (n == 0) - GCM_MUL(ctx, Xi); - else { - ctx->ares = n; - return 0; - } - } -#ifdef GHASH - if ((i = (len & (size_t)-16))) { - GHASH(ctx, aad, i); - aad += i; - len -= i; - } -#else - while (len >= 16) { - for (i = 0; i < 16; ++i) - ctx->Xi.c[i] ^= aad[i]; - GCM_MUL(ctx, Xi); - aad += 16; - len -= 16; - } -#endif - if (len) { - n = (unsigned int)len; - for (i = 0; i < len; ++i) - ctx->Xi.c[i] ^= aad[i]; - } - - ctx->ares = n; - return 0; -} - -int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - unsigned int n, ctr; - size_t i; - u64 mlen = ctx->len.u[1]; - block128_f block = ctx->block; - void *key = ctx->key; -#ifdef GCM_FUNCREF_4BIT - void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH - void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], - const u8 *inp, size_t len) = ctx->ghash; -# endif -#endif - -#if 0 - n = (unsigned int)mlen % 16; /* alternative to ctx->mres */ -#endif - mlen += len; - if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) - return -1; - ctx->len.u[1] = mlen; - - if (ctx->ares) { - /* First call to encrypt finalizes GHASH(AAD) */ - GCM_MUL(ctx, Xi); - ctx->ares = 0; - } - - if (is_endian.little) -#ifdef BSWAP4 - ctr = BSWAP4(ctx->Yi.d[3]); -#else - ctr = GETU32(ctx->Yi.c + 12); -#endif - else - ctr = ctx->Yi.d[3]; - - n = ctx->mres; -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (16 % sizeof(size_t) == 0) { /* always true actually */ - do { - if (n) { - while (n && len) { - ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; - --len; - n = (n + 1) % 16; - } - if (n == 0) - GCM_MUL(ctx, Xi); - else { - ctx->mres = n; - return 0; - } - } -# if defined(STRICT_ALIGNMENT) - if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) - break; -# endif -# if defined(GHASH) && defined(GHASH_CHUNK) - while (len >= GHASH_CHUNK) { - size_t j = GHASH_CHUNK; - - while (j) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; - - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - for (i = 0; i < 16 / sizeof(size_t); ++i) - out_t[i] = in_t[i] ^ ctx->EKi.t[i]; - out += 16; - in += 16; - j -= 16; - } - GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); - len -= GHASH_CHUNK; - } - if ((i = (len & (size_t)-16))) { - size_t j = i; - - while (len >= 16) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; - - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - for (i = 0; i < 16 / sizeof(size_t); ++i) - out_t[i] = in_t[i] ^ ctx->EKi.t[i]; - out += 16; - in += 16; - len -= 16; - } - GHASH(ctx, out - j, j); - } -# else - while (len >= 16) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; - - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - for (i = 0; i < 16 / sizeof(size_t); ++i) - ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i]; - GCM_MUL(ctx, Xi); - out += 16; - in += 16; - len -= 16; - } -# endif - if (len) { - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - while (len--) { - ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; - ++n; - } - } - - ctx->mres = n; - return 0; - } while (0); - } -#endif - for (i = 0; i < len; ++i) { - if (n == 0) { - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -#ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -#else - PUTU32(ctx->Yi.c + 12, ctr); -#endif - else - ctx->Yi.d[3] = ctr; - } - ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n]; - n = (n + 1) % 16; - if (n == 0) - GCM_MUL(ctx, Xi); - } - - ctx->mres = n; - return 0; -} - -int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - unsigned int n, ctr; - size_t i; - u64 mlen = ctx->len.u[1]; - block128_f block = ctx->block; - void *key = ctx->key; -#ifdef GCM_FUNCREF_4BIT - void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH - void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], - const u8 *inp, size_t len) = ctx->ghash; -# endif -#endif - - mlen += len; - if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) - return -1; - ctx->len.u[1] = mlen; - - if (ctx->ares) { - /* First call to decrypt finalizes GHASH(AAD) */ - GCM_MUL(ctx, Xi); - ctx->ares = 0; - } - - if (is_endian.little) -#ifdef BSWAP4 - ctr = BSWAP4(ctx->Yi.d[3]); -#else - ctr = GETU32(ctx->Yi.c + 12); -#endif - else - ctr = ctx->Yi.d[3]; - - n = ctx->mres; -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (16 % sizeof(size_t) == 0) { /* always true actually */ - do { - if (n) { - while (n && len) { - u8 c = *(in++); - *(out++) = c ^ ctx->EKi.c[n]; - ctx->Xi.c[n] ^= c; - --len; - n = (n + 1) % 16; - } - if (n == 0) - GCM_MUL(ctx, Xi); - else { - ctx->mres = n; - return 0; - } - } -# if defined(STRICT_ALIGNMENT) - if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) - break; -# endif -# if defined(GHASH) && defined(GHASH_CHUNK) - while (len >= GHASH_CHUNK) { - size_t j = GHASH_CHUNK; - - GHASH(ctx, in, GHASH_CHUNK); - while (j) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; - - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - for (i = 0; i < 16 / sizeof(size_t); ++i) - out_t[i] = in_t[i] ^ ctx->EKi.t[i]; - out += 16; - in += 16; - j -= 16; - } - len -= GHASH_CHUNK; - } - if ((i = (len & (size_t)-16))) { - GHASH(ctx, in, i); - while (len >= 16) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; - - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - for (i = 0; i < 16 / sizeof(size_t); ++i) - out_t[i] = in_t[i] ^ ctx->EKi.t[i]; - out += 16; - in += 16; - len -= 16; - } - } -# else - while (len >= 16) { - size_t *out_t = (size_t *)out; - const size_t *in_t = (const size_t *)in; - - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - for (i = 0; i < 16 / sizeof(size_t); ++i) { - size_t c = in[i]; - out[i] = c ^ ctx->EKi.t[i]; - ctx->Xi.t[i] ^= c; - } - GCM_MUL(ctx, Xi); - out += 16; - in += 16; - len -= 16; - } -# endif - if (len) { - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - while (len--) { - u8 c = in[n]; - ctx->Xi.c[n] ^= c; - out[n] = c ^ ctx->EKi.c[n]; - ++n; - } - } - - ctx->mres = n; - return 0; - } while (0); - } -#endif - for (i = 0; i < len; ++i) { - u8 c; - if (n == 0) { - (*block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -#ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -#else - PUTU32(ctx->Yi.c + 12, ctr); -#endif - else - ctx->Yi.d[3] = ctr; - } - c = in[i]; - out[i] = c ^ ctx->EKi.c[n]; - ctx->Xi.c[n] ^= c; - n = (n + 1) % 16; - if (n == 0) - GCM_MUL(ctx, Xi); - } - - ctx->mres = n; - return 0; -} - -int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len, ctr128_f stream) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - unsigned int n, ctr; - size_t i; - u64 mlen = ctx->len.u[1]; - void *key = ctx->key; -#ifdef GCM_FUNCREF_4BIT - void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH - void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], - const u8 *inp, size_t len) = ctx->ghash; -# endif -#endif - - mlen += len; - if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) - return -1; - ctx->len.u[1] = mlen; - - if (ctx->ares) { - /* First call to encrypt finalizes GHASH(AAD) */ - GCM_MUL(ctx, Xi); - ctx->ares = 0; - } - - if (is_endian.little) -#ifdef BSWAP4 - ctr = BSWAP4(ctx->Yi.d[3]); -#else - ctr = GETU32(ctx->Yi.c + 12); -#endif - else - ctr = ctx->Yi.d[3]; - - n = ctx->mres; - if (n) { - while (n && len) { - ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; - --len; - n = (n + 1) % 16; - } - if (n == 0) - GCM_MUL(ctx, Xi); - else { - ctx->mres = n; - return 0; - } - } -#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) - while (len >= GHASH_CHUNK) { - (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); - ctr += GHASH_CHUNK / 16; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - GHASH(ctx, out, GHASH_CHUNK); - out += GHASH_CHUNK; - in += GHASH_CHUNK; - len -= GHASH_CHUNK; - } -#endif - if ((i = (len & (size_t)-16))) { - size_t j = i / 16; - - (*stream) (in, out, j, key, ctx->Yi.c); - ctr += (unsigned int)j; - if (is_endian.little) -#ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -#else - PUTU32(ctx->Yi.c + 12, ctr); -#endif - else - ctx->Yi.d[3] = ctr; - in += i; - len -= i; -#if defined(GHASH) - GHASH(ctx, out, i); - out += i; -#else - while (j--) { - for (i = 0; i < 16; ++i) - ctx->Xi.c[i] ^= out[i]; - GCM_MUL(ctx, Xi); - out += 16; - } -#endif - } - if (len) { - (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -#ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -#else - PUTU32(ctx->Yi.c + 12, ctr); -#endif - else - ctx->Yi.d[3] = ctr; - while (len--) { - ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; - ++n; - } - } - - ctx->mres = n; - return 0; -} - -int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len, ctr128_f stream) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - unsigned int n, ctr; - size_t i; - u64 mlen = ctx->len.u[1]; - void *key = ctx->key; -#ifdef GCM_FUNCREF_4BIT - void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -# ifdef GHASH - void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], - const u8 *inp, size_t len) = ctx->ghash; -# endif -#endif - - mlen += len; - if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) - return -1; - ctx->len.u[1] = mlen; - - if (ctx->ares) { - /* First call to decrypt finalizes GHASH(AAD) */ - GCM_MUL(ctx, Xi); - ctx->ares = 0; - } - - if (is_endian.little) -#ifdef BSWAP4 - ctr = BSWAP4(ctx->Yi.d[3]); -#else - ctr = GETU32(ctx->Yi.c + 12); -#endif - else - ctr = ctx->Yi.d[3]; - - n = ctx->mres; - if (n) { - while (n && len) { - u8 c = *(in++); - *(out++) = c ^ ctx->EKi.c[n]; - ctx->Xi.c[n] ^= c; - --len; - n = (n + 1) % 16; - } - if (n == 0) - GCM_MUL(ctx, Xi); - else { - ctx->mres = n; - return 0; - } - } -#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) - while (len >= GHASH_CHUNK) { - GHASH(ctx, in, GHASH_CHUNK); - (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); - ctr += GHASH_CHUNK / 16; - if (is_endian.little) -# ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -# else - PUTU32(ctx->Yi.c + 12, ctr); -# endif - else - ctx->Yi.d[3] = ctr; - out += GHASH_CHUNK; - in += GHASH_CHUNK; - len -= GHASH_CHUNK; - } -#endif - if ((i = (len & (size_t)-16))) { - size_t j = i / 16; - -#if defined(GHASH) - GHASH(ctx, in, i); -#else - while (j--) { - size_t k; - for (k = 0; k < 16; ++k) - ctx->Xi.c[k] ^= in[k]; - GCM_MUL(ctx, Xi); - in += 16; - } - j = i / 16; - in -= i; -#endif - (*stream) (in, out, j, key, ctx->Yi.c); - ctr += (unsigned int)j; - if (is_endian.little) -#ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -#else - PUTU32(ctx->Yi.c + 12, ctr); -#endif - else - ctx->Yi.d[3] = ctr; - out += i; - in += i; - len -= i; - } - if (len) { - (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); - ++ctr; - if (is_endian.little) -#ifdef BSWAP4 - ctx->Yi.d[3] = BSWAP4(ctr); -#else - PUTU32(ctx->Yi.c + 12, ctr); -#endif - else - ctx->Yi.d[3] = ctr; - while (len--) { - u8 c = in[n]; - ctx->Xi.c[n] ^= c; - out[n] = c ^ ctx->EKi.c[n]; - ++n; - } - } - - ctx->mres = n; - return 0; -} - -int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, - size_t len) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - u64 alen = ctx->len.u[0] << 3; - u64 clen = ctx->len.u[1] << 3; -#ifdef GCM_FUNCREF_4BIT - void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; -#endif - - if (ctx->mres || ctx->ares) - GCM_MUL(ctx, Xi); - - if (is_endian.little) { -#ifdef BSWAP8 - alen = BSWAP8(alen); - clen = BSWAP8(clen); -#else - u8 *p = ctx->len.c; - - ctx->len.u[0] = alen; - ctx->len.u[1] = clen; - - alen = (u64)GETU32(p) << 32 | GETU32(p + 4); - clen = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); -#endif - } - - ctx->Xi.u[0] ^= alen; - ctx->Xi.u[1] ^= clen; - GCM_MUL(ctx, Xi); - - ctx->Xi.u[0] ^= ctx->EK0.u[0]; - ctx->Xi.u[1] ^= ctx->EK0.u[1]; - - if (tag && len <= sizeof(ctx->Xi)) - return CRYPTO_memcmp(ctx->Xi.c, tag, len); - else - return -1; -} - -void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) -{ - CRYPTO_gcm128_finish(ctx, NULL, 0); - memcpy(tag, ctx->Xi.c, - len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); -} - -GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) -{ - GCM128_CONTEXT *ret; - - if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT)))) - CRYPTO_gcm128_init(ret, key, block); - - return ret; -} - -void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx) -{ - if (ctx) { - OPENSSL_cleanse(ctx, sizeof(*ctx)); - OPENSSL_free(ctx); - } -} - -#if defined(SELFTEST) -# include -# include "aes.h" - -/* Test Case 1 */ -static const u8 K1[16], *P1 = NULL, *A1 = NULL, IV1[12], *C1 = NULL; -static const u8 T1[] = { - 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, - 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a -}; - -/* Test Case 2 */ -# define K2 K1 -# define A2 A1 -# define IV2 IV1 -static const u8 P2[16]; -static const u8 C2[] = { - 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, - 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 -}; - -static const u8 T2[] = { - 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, - 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf -}; - -/* Test Case 3 */ -# define A3 A2 -static const u8 K3[] = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 -}; - -static const u8 P3[] = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 -}; - -static const u8 IV3[] = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 -}; - -static const u8 C3[] = { - 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 -}; - -static const u8 T3[] = { - 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, - 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 -}; - -/* Test Case 4 */ -# define K4 K3 -# define IV4 IV3 -static const u8 P4[] = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 -}; - -static const u8 A4[] = { - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xab, 0xad, 0xda, 0xd2 -}; - -static const u8 C4[] = { - 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, - 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, - 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, - 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, - 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, - 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, - 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, - 0x3d, 0x58, 0xe0, 0x91 -}; - -static const u8 T4[] = { - 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, - 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 -}; - -/* Test Case 5 */ -# define K5 K4 -# define P5 P4 -# define A5 A4 -static const u8 IV5[] = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad -}; - -static const u8 C5[] = { - 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, - 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, - 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, - 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, - 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, - 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, - 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, - 0xc2, 0x3f, 0x45, 0x98 -}; - -static const u8 T5[] = { - 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, - 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb -}; - -/* Test Case 6 */ -# define K6 K5 -# define P6 P5 -# define A6 A5 -static const u8 IV6[] = { - 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, - 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, - 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, - 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, - 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, - 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, - 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, - 0xa6, 0x37, 0xb3, 0x9b -}; - -static const u8 C6[] = { - 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, - 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, - 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, - 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, - 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, - 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, - 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, - 0x4c, 0x34, 0xae, 0xe5 -}; - -static const u8 T6[] = { - 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, - 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 -}; - -/* Test Case 7 */ -static const u8 K7[24], *P7 = NULL, *A7 = NULL, IV7[12], *C7 = NULL; -static const u8 T7[] = { - 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, - 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 -}; - -/* Test Case 8 */ -# define K8 K7 -# define IV8 IV7 -# define A8 A7 -static const u8 P8[16]; -static const u8 C8[] = { - 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, - 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 -}; - -static const u8 T8[] = { - 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, - 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb -}; - -/* Test Case 9 */ -# define A9 A8 -static const u8 K9[] = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c -}; - -static const u8 P9[] = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 -}; - -static const u8 IV9[] = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 -}; - -static const u8 C9[] = { - 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 -}; - -static const u8 T9[] = { - 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, - 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 -}; - -/* Test Case 10 */ -# define K10 K9 -# define IV10 IV9 -static const u8 P10[] = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 -}; - -static const u8 A10[] = { - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xab, 0xad, 0xda, 0xd2 -}; - -static const u8 C10[] = { - 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, - 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, - 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, - 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, - 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, - 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, - 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, - 0xcc, 0xda, 0x27, 0x10 -}; - -static const u8 T10[] = { - 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, - 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c -}; - -/* Test Case 11 */ -# define K11 K10 -# define P11 P10 -# define A11 A10 -static const u8 IV11[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad }; - -static const u8 C11[] = { - 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, - 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, - 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, - 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, - 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, - 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, - 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, - 0xa0, 0xf0, 0x62, 0xf7 -}; - -static const u8 T11[] = { - 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, - 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 -}; - -/* Test Case 12 */ -# define K12 K11 -# define P12 P11 -# define A12 A11 -static const u8 IV12[] = { - 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, - 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, - 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, - 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, - 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, - 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, - 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, - 0xa6, 0x37, 0xb3, 0x9b -}; - -static const u8 C12[] = { - 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, - 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, - 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, - 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, - 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, - 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, - 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, - 0xe9, 0xb7, 0x37, 0x3b -}; - -static const u8 T12[] = { - 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, - 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 -}; - -/* Test Case 13 */ -static const u8 K13[32], *P13 = NULL, *A13 = NULL, IV13[12], *C13 = NULL; -static const u8 T13[] = { - 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, - 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b -}; - -/* Test Case 14 */ -# define K14 K13 -# define A14 A13 -static const u8 P14[16], IV14[12]; -static const u8 C14[] = { - 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, - 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 -}; - -static const u8 T14[] = { - 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, - 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 -}; - -/* Test Case 15 */ -# define A15 A14 -static const u8 K15[] = { - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, - 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, - 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 -}; - -static const u8 P15[] = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 -}; - -static const u8 IV15[] = { - 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, - 0xde, 0xca, 0xf8, 0x88 -}; - -static const u8 C15[] = { - 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad -}; - -static const u8 T15[] = { - 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, - 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c -}; - -/* Test Case 16 */ -# define K16 K15 -# define IV16 IV15 -static const u8 P16[] = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39 -}; - -static const u8 A16[] = { - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, - 0xab, 0xad, 0xda, 0xd2 -}; - -static const u8 C16[] = { - 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62 -}; - -static const u8 T16[] = { - 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, - 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b -}; - -/* Test Case 17 */ -# define K17 K16 -# define P17 P16 -# define A17 A16 -static const u8 IV17[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad }; - -static const u8 C17[] = { - 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, - 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, - 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, - 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, - 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, - 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, - 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, - 0xf4, 0x7c, 0x9b, 0x1f -}; - -static const u8 T17[] = { - 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, - 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 -}; - -/* Test Case 18 */ -# define K18 K17 -# define P18 P17 -# define A18 A17 -static const u8 IV18[] = { - 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, - 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, - 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, - 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, - 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, - 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, - 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, - 0xa6, 0x37, 0xb3, 0x9b -}; - -static const u8 C18[] = { - 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, - 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, - 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, - 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, - 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, - 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, - 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, - 0x44, 0xae, 0x7e, 0x3f -}; - -static const u8 T18[] = { - 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, - 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a -}; - -/* Test Case 19 */ -# define K19 K1 -# define P19 P1 -# define IV19 IV1 -# define C19 C1 -static const u8 A19[] = { - 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, - 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, - 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, - 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, - 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, - 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, - 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, - 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, - 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, - 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, - 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, - 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, - 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, - 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, - 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, - 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad -}; - -static const u8 T19[] = { - 0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d, - 0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92 -}; - -/* Test Case 20 */ -# define K20 K1 -# define A20 A1 -/* this results in 0xff in counter LSB */ -static const u8 IV20[64] = { 0xff, 0xff, 0xff, 0xff }; - -static const u8 P20[288]; -static const u8 C20[] = { - 0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a, - 0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14, - 0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce, - 0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f, - 0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70, - 0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18, - 0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf, - 0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49, - 0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab, - 0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c, - 0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c, - 0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29, - 0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1, - 0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76, - 0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2, - 0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce, - 0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f, - 0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86, - 0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb, - 0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18, - 0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65, - 0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42, - 0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b, - 0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06, - 0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24, - 0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c, - 0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4, - 0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64, - 0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03, - 0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6, - 0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90, - 0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74, - 0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67, - 0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46, - 0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78, - 0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c -}; - -static const u8 T20[] = { - 0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a, - 0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f -}; - -# define TEST_CASE(n) do { \ - u8 out[sizeof(P##n)]; \ - AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key); \ - CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt); \ - CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \ - memset(out,0,sizeof(out)); \ - if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \ - if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out)); \ - if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \ - (C##n && memcmp(out,C##n,sizeof(out)))) \ - ret++, printf ("encrypt test#%d failed.\n",n); \ - CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \ - memset(out,0,sizeof(out)); \ - if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \ - if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out)); \ - if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \ - (P##n && memcmp(out,P##n,sizeof(out)))) \ - ret++, printf ("decrypt test#%d failed.\n",n); \ - } while(0) - -int main() -{ - GCM128_CONTEXT ctx; - AES_KEY key; - int ret = 0; - - TEST_CASE(1); - TEST_CASE(2); - TEST_CASE(3); - TEST_CASE(4); - TEST_CASE(5); - TEST_CASE(6); - TEST_CASE(7); - TEST_CASE(8); - TEST_CASE(9); - TEST_CASE(10); - TEST_CASE(11); - TEST_CASE(12); - TEST_CASE(13); - TEST_CASE(14); - TEST_CASE(15); - TEST_CASE(16); - TEST_CASE(17); - TEST_CASE(18); - TEST_CASE(19); - TEST_CASE(20); - -# ifdef OPENSSL_CPUID_OBJ - { - size_t start, stop, gcm_t, ctr_t, OPENSSL_rdtsc(); - union { - u64 u; - u8 c[1024]; - } buf; - int i; - - AES_set_encrypt_key(K1, sizeof(K1) * 8, &key); - CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt); - CRYPTO_gcm128_setiv(&ctx, IV1, sizeof(IV1)); - - CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf)); - start = OPENSSL_rdtsc(); - CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf)); - gcm_t = OPENSSL_rdtsc() - start; - - CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf), - &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres, - (block128_f) AES_encrypt); - start = OPENSSL_rdtsc(); - CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf), - &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres, - (block128_f) AES_encrypt); - ctr_t = OPENSSL_rdtsc() - start; - - printf("%.2f-%.2f=%.2f\n", - gcm_t / (double)sizeof(buf), - ctr_t / (double)sizeof(buf), - (gcm_t - ctr_t) / (double)sizeof(buf)); -# ifdef GHASH - { - void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], - const u8 *inp, size_t len) = ctx.ghash; - - GHASH((&ctx), buf.c, sizeof(buf)); - start = OPENSSL_rdtsc(); - for (i = 0; i < 100; ++i) - GHASH((&ctx), buf.c, sizeof(buf)); - gcm_t = OPENSSL_rdtsc() - start; - printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i); - } -# endif - } -# endif - - return ret; -} -#endif diff --git a/Sources/COpenSSL/getenv.c b/Sources/COpenSSL/getenv.c deleted file mode 100644 index 53f1dfd4..00000000 --- a/Sources/COpenSSL/getenv.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2018 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the OpenSSL license (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif - -#include -#include "cryptlib.h" - -char *ossl_safe_getenv(const char *name) -{ -#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) -# if __GLIBC_PREREQ(2, 17) -# define SECURE_GETENV - return secure_getenv(name); -# endif -#endif - -#ifndef SECURE_GETENV - if (OPENSSL_issetugid()) - return NULL; - return getenv(name); -#endif -} diff --git a/Sources/COpenSSL/gost2001.c b/Sources/COpenSSL/gost2001.c deleted file mode 100644 index 08a64a08..00000000 --- a/Sources/COpenSSL/gost2001.c +++ /dev/null @@ -1,474 +0,0 @@ -/********************************************************************** - * gost2001.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of GOST R 34.10-2001 * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include "gost_lcl.h" -#include "gost_params.h" -#include -#include "rand.h" -#include "ecdsa.h" -#include "err.h" -#include "e_gost_err.h" -#ifdef DEBUG_SIGN -extern -void dump_signature(const char *message, const unsigned char *buffer, - size_t len); -void dump_dsa_sig(const char *message, DSA_SIG *sig); -#else - -# define dump_signature(a,b,c) -# define dump_dsa_sig(a,b) -#endif - -/* - * Fills EC_KEY structure hidden in the app_data field of DSA structure - * with parameter information, extracted from parameter array in - * params.c file. - * - * Also fils DSA->q field with copy of EC_GROUP order field to make - * DSA_size function work - */ -int fill_GOST2001_params(EC_KEY *eckey, int nid) -{ - R3410_2001_params *params = R3410_2001_paramset; - EC_GROUP *grp = NULL; - BIGNUM *p = NULL, *q = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL; - EC_POINT *P = NULL; - BN_CTX *ctx = BN_CTX_new(); - int ok = 0; - - if(!ctx) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE); - goto err; - } - - BN_CTX_start(ctx); - p = BN_CTX_get(ctx); - a = BN_CTX_get(ctx); - b = BN_CTX_get(ctx); - x = BN_CTX_get(ctx); - y = BN_CTX_get(ctx); - q = BN_CTX_get(ctx); - if(!p || !a || !b || !x || !y || !q) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE); - goto err; - } - while (params->nid != NID_undef && params->nid != nid) - params++; - if (params->nid == NID_undef) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, - GOST_R_UNSUPPORTED_PARAMETER_SET); - goto err; - } - if(!BN_hex2bn(&p, params->p) - || !BN_hex2bn(&a, params->a) - || !BN_hex2bn(&b, params->b)) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, - ERR_R_INTERNAL_ERROR); - goto err; - } - - grp = EC_GROUP_new_curve_GFp(p, a, b, ctx); - if(!grp) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE); - goto err; - } - - P = EC_POINT_new(grp); - if(!P) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_MALLOC_FAILURE); - goto err; - } - - if(!BN_hex2bn(&x, params->x) - || !BN_hex2bn(&y, params->y) - || !EC_POINT_set_affine_coordinates_GFp(grp, P, x, y, ctx) - || !BN_hex2bn(&q, params->q)) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifdef DEBUG_KEYS - fprintf(stderr, "Set params index %d oid %s\nq=", - (params - R3410_2001_paramset), OBJ_nid2sn(params->nid)); - BN_print_fp(stderr, q); - fprintf(stderr, "\n"); -#endif - - if(!EC_GROUP_set_generator(grp, P, q, NULL)) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR); - goto err; - } - EC_GROUP_set_curve_name(grp, params->nid); - if(!EC_KEY_set_group(eckey, grp)) { - GOSTerr(GOST_F_FILL_GOST2001_PARAMS, ERR_R_INTERNAL_ERROR); - goto err; - } - ok = 1; - err: - if (P) EC_POINT_free(P); - if (grp) EC_GROUP_free(grp); - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return ok; -} - -/* - * Computes gost2001 signature as DSA_SIG structure - * - * - */ -DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) -{ - DSA_SIG *newsig = NULL, *ret = NULL; - BIGNUM *md = hashsum2bn(dgst); - BIGNUM *order = NULL; - const EC_GROUP *group; - const BIGNUM *priv_key; - BIGNUM *r = NULL, *s = NULL, *X = NULL, *tmp = NULL, *tmp2 = NULL, *k = - NULL, *e = NULL; - EC_POINT *C = NULL; - BN_CTX *ctx = BN_CTX_new(); - if(!ctx || !md) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - BN_CTX_start(ctx); - OPENSSL_assert(dlen == 32); - newsig = DSA_SIG_new(); - if (!newsig) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, GOST_R_NO_MEMORY); - goto err; - } - group = EC_KEY_get0_group(eckey); - if(!group) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); - goto err; - } - order = BN_CTX_get(ctx); - if(!order || !EC_GROUP_get_order(group, order, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); - goto err; - } - priv_key = EC_KEY_get0_private_key(eckey); - if(!priv_key) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); - goto err; - } - e = BN_CTX_get(ctx); - if(!e || !BN_mod(e, md, order, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifdef DEBUG_SIGN - fprintf(stderr, "digest as bignum="); - BN_print_fp(stderr, md); - fprintf(stderr, "\ndigest mod q="); - BN_print_fp(stderr, e); - fprintf(stderr, "\n"); -#endif - if (BN_is_zero(e)) { - BN_one(e); - } - k = BN_CTX_get(ctx); - C = EC_POINT_new(group); - if(!k || !C) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - do { - do { - if (!BN_rand_range(k, order)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, - GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); - goto err; - } - if (!EC_POINT_mul(group, C, k, NULL, NULL, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); - goto err; - } - if (!X) - X = BN_CTX_get(ctx); - if (!r) - r = BN_CTX_get(ctx); - if (!X || !r) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_EC_LIB); - goto err; - } - - if(!BN_nnmod(r, X, order, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); - goto err; - } - } - while (BN_is_zero(r)); - /* s = (r*priv_key+k*e) mod order */ - if (!tmp) - tmp = BN_CTX_get(ctx); - if (!tmp2) - tmp2 = BN_CTX_get(ctx); - if (!s) - s = BN_CTX_get(ctx); - if (!tmp || !tmp2 || !s) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - - if(!BN_mod_mul(tmp, priv_key, r, order, ctx) - || !BN_mod_mul(tmp2, k, e, order, ctx) - || !BN_mod_add(s, tmp, tmp2, order, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_INTERNAL_ERROR); - goto err; - } - } - while (BN_is_zero(s)); - - newsig->s = BN_dup(s); - newsig->r = BN_dup(r); - if(!newsig->s || !newsig->r) { - GOSTerr(GOST_F_GOST2001_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - - ret = newsig; - err: - if(ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (C) EC_POINT_free(C); - if (md) BN_free(md); - if (!ret && newsig) { - DSA_SIG_free(newsig); - } - return ret; -} - -/* - * Verifies gost 2001 signature - * - */ -int gost2001_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, EC_KEY *ec) -{ - BN_CTX *ctx = BN_CTX_new(); - const EC_GROUP *group = EC_KEY_get0_group(ec); - BIGNUM *order; - BIGNUM *md = NULL, *e = NULL, *R = NULL, *v = NULL, *z1 = NULL, *z2 = - NULL; - BIGNUM *X = NULL, *tmp = NULL; - EC_POINT *C = NULL; - const EC_POINT *pub_key = NULL; - int ok = 0; - - if(!ctx || !group) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - - BN_CTX_start(ctx); - order = BN_CTX_get(ctx); - e = BN_CTX_get(ctx); - z1 = BN_CTX_get(ctx); - z2 = BN_CTX_get(ctx); - tmp = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - R = BN_CTX_get(ctx); - v = BN_CTX_get(ctx); - if(!order || !e || !z1 || !z2 || !tmp || !X || !R || !v) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - - pub_key = EC_KEY_get0_public_key(ec); - if(!pub_key || !EC_GROUP_get_order(group, order, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (BN_is_zero(sig->s) || BN_is_zero(sig->r) || - (BN_cmp(sig->s, order) >= 1) || (BN_cmp(sig->r, order) >= 1)) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, - GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); - goto err; - - } - md = hashsum2bn(dgst); - - if(!md || !BN_mod(e, md, order, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifdef DEBUG_SIGN - fprintf(stderr, "digest as bignum: "); - BN_print_fp(stderr, md); - fprintf(stderr, "\ndigest mod q: "); - BN_print_fp(stderr, e); -#endif - if (BN_is_zero(e) && !BN_one(e)) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - v = BN_mod_inverse(v, e, order, ctx); - if(!v - || !BN_mod_mul(z1, sig->s, v, order, ctx) - || !BN_sub(tmp, order, sig->r) - || !BN_mod_mul(z2, tmp, v, order, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifdef DEBUG_SIGN - fprintf(stderr, "\nInverted digest value: "); - BN_print_fp(stderr, v); - fprintf(stderr, "\nz1: "); - BN_print_fp(stderr, z1); - fprintf(stderr, "\nz2: "); - BN_print_fp(stderr, z2); -#endif - C = EC_POINT_new(group); - if (!C) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_POINT_mul(group, C, z1, pub_key, z2, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); - goto err; - } - if (!EC_POINT_get_affine_coordinates_GFp(group, C, X, NULL, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_EC_LIB); - goto err; - } - if(!BN_mod(R, X, order, ctx)) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifdef DEBUG_SIGN - fprintf(stderr, "\nX="); - BN_print_fp(stderr, X); - fprintf(stderr, "\nX mod q="); - BN_print_fp(stderr, R); - fprintf(stderr, "\n"); -#endif - if (BN_cmp(R, sig->r) != 0) { - GOSTerr(GOST_F_GOST2001_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); - } else { - ok = 1; - } - err: - if (C) EC_POINT_free(C); - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (md) BN_free(md); - return ok; -} - -/* - * Computes GOST R 34.10-2001 public key - * - * - */ -int gost2001_compute_public(EC_KEY *ec) -{ - const EC_GROUP *group = EC_KEY_get0_group(ec); - EC_POINT *pub_key = NULL; - const BIGNUM *priv_key = NULL; - BN_CTX *ctx = NULL; - int ok = 0; - - if (!group) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, - GOST_R_KEY_IS_NOT_INITIALIZED); - return 0; - } - ctx = BN_CTX_new(); - if(!ctx) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); - goto err; - } - BN_CTX_start(ctx); - if (!(priv_key = EC_KEY_get0_private_key(ec))) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); - goto err; - } - - pub_key = EC_POINT_new(group); - if(!pub_key) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); - goto err; - } - if (!EC_KEY_set_public_key(ec, pub_key)) { - GOSTerr(GOST_F_GOST2001_COMPUTE_PUBLIC, ERR_R_EC_LIB); - goto err; - } - ok = 256; - err: - if (pub_key) EC_POINT_free(pub_key); - if (ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return ok; -} - -/* - * - * Generates GOST R 34.10-2001 keypair - * - * - */ -int gost2001_keygen(EC_KEY *ec) -{ - BIGNUM *order = BN_new(), *d = BN_new(); - const EC_GROUP *group = NULL; - - if (order == NULL || d == NULL) { - GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_MALLOC_FAILURE); - BN_free(d); - BN_free(order); - return 0; - } - - group = EC_KEY_get0_group(ec); - if(!group || !EC_GROUP_get_order(group, order, NULL)) { - GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR); - BN_free(d); - BN_free(order); - return 0; - } - - do { - if (!BN_rand_range(d, order)) { - GOSTerr(GOST_F_GOST2001_KEYGEN, - GOST_R_RANDOM_NUMBER_GENERATOR_FAILED); - BN_free(d); - BN_free(order); - return 0; - } - } - while (BN_is_zero(d)); - - if(!EC_KEY_set_private_key(ec, d)) { - GOSTerr(GOST_F_GOST2001_KEYGEN, ERR_R_INTERNAL_ERROR); - BN_free(d); - BN_free(order); - return 0; - } - BN_free(d); - BN_free(order); - return gost2001_compute_public(ec); -} diff --git a/Sources/COpenSSL/gost2001_keyx.c b/Sources/COpenSSL/gost2001_keyx.c deleted file mode 100644 index 1aa8331e..00000000 --- a/Sources/COpenSSL/gost2001_keyx.c +++ /dev/null @@ -1,294 +0,0 @@ -/********************************************************************** - * gost_keyx.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * VK0 34.10-2001 key exchange and GOST R 34.10-2001 * - * based PKCS7/SMIME support * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include "evp.h" -#include "rand.h" -#include -#include "objects.h" -#include "gost89.h" -#include "gosthash.h" -#include "e_gost_err.h" -#include "gost_keywrap.h" -#include "gost_lcl.h" -#include "gost2001_keyx.h" - -/* Implementation of CryptoPro VKO 34.10-2001 algorithm */ -static int VKO_compute_key(unsigned char *shared_key, size_t shared_key_size, - const EC_POINT *pub_key, EC_KEY *priv_key, - const unsigned char *ukm) -{ - unsigned char ukm_be[8], databuf[64], hashbuf[64]; - BIGNUM *UKM = NULL, *p = NULL, *order = NULL, *X = NULL, *Y = NULL; - const BIGNUM *key = EC_KEY_get0_private_key(priv_key); - EC_POINT *pnt = EC_POINT_new(EC_KEY_get0_group(priv_key)); - int i; - gost_hash_ctx hash_ctx; - BN_CTX *ctx = BN_CTX_new(); - - for (i = 0; i < 8; i++) { - ukm_be[7 - i] = ukm[i]; - } - BN_CTX_start(ctx); - UKM = getbnfrombuf(ukm_be, 8); - p = BN_CTX_get(ctx); - order = BN_CTX_get(ctx); - X = BN_CTX_get(ctx); - Y = BN_CTX_get(ctx); - EC_GROUP_get_order(EC_KEY_get0_group(priv_key), order, ctx); - BN_mod_mul(p, key, UKM, order, ctx); - EC_POINT_mul(EC_KEY_get0_group(priv_key), pnt, NULL, pub_key, p, ctx); - EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(priv_key), - pnt, X, Y, ctx); - /* - * Serialize elliptic curve point same way as we do it when saving key - */ - store_bignum(Y, databuf, 32); - store_bignum(X, databuf + 32, 32); - /* And reverse byte order of whole buffer */ - for (i = 0; i < 64; i++) { - hashbuf[63 - i] = databuf[i]; - } - init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet); - start_hash(&hash_ctx); - hash_block(&hash_ctx, hashbuf, 64); - finish_hash(&hash_ctx, shared_key); - done_gost_hash_ctx(&hash_ctx); - BN_free(UKM); - BN_CTX_end(ctx); - BN_CTX_free(ctx); - EC_POINT_free(pnt); - return 32; -} - -/* - * EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-2001 - * algorithm - */ -int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen) -{ - /* - * Public key of peer in the ctx field peerkey Our private key in the ctx - * pkey ukm is in the algorithm specific context data - */ - EVP_PKEY *my_key = EVP_PKEY_CTX_get0_pkey(ctx); - EVP_PKEY *peer_key = EVP_PKEY_CTX_get0_peerkey(ctx); - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - - if (!data->shared_ukm) { - GOSTerr(GOST_F_PKEY_GOST2001_DERIVE, GOST_R_UKM_NOT_SET); - return 0; - } - - if (key == NULL) { - *keylen = 32; - return 32; - } - - *keylen = - VKO_compute_key(key, 32, - EC_KEY_get0_public_key(EVP_PKEY_get0(peer_key)), - (EC_KEY *)EVP_PKEY_get0(my_key), data->shared_ukm); - return 1; -} - -/* - * EVP_PKEY_METHOD callback encrypt - * Implementation of GOST2001 key transport, cryptocom variation - */ -/* - * Generates ephemeral key based on pubk algorithm computes shared key using - * VKO and returns filled up GOST_KEY_TRANSPORT structure - */ - -/* - * EVP_PKEY_METHOD callback encrypt - * Implementation of GOST2001 key transport, cryptopo variation - */ - -int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *pctx, unsigned char *out, - size_t *out_len, const unsigned char *key, - size_t key_len) -{ - GOST_KEY_TRANSPORT *gkt = NULL; - EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(pctx); - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(pctx); - const struct gost_cipher_info *param = get_encryption_params(NULL); - unsigned char ukm[8], shared_key[32], crypted_key[44]; - int ret = 0; - int key_is_ephemeral = 1; - gost_ctx cctx; - EVP_PKEY *sec_key = EVP_PKEY_CTX_get0_peerkey(pctx); - if (data->shared_ukm) { - memcpy(ukm, data->shared_ukm, 8); - } else if (out) { - - if (RAND_bytes(ukm, 8) <= 0) { - GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, - GOST_R_RANDOM_GENERATOR_FAILURE); - return 0; - } - } - /* Check for private key in the peer_key of context */ - if (sec_key) { - key_is_ephemeral = 0; - if (!gost_get0_priv_key(sec_key)) { - GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, - GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); - goto err; - } - } else { - key_is_ephemeral = 1; - if (out) { - sec_key = EVP_PKEY_new(); - if (sec_key == NULL) - goto err; - EVP_PKEY_assign(sec_key, EVP_PKEY_base_id(pubk), EC_KEY_new()); - EVP_PKEY_copy_parameters(sec_key, pubk); - if (!gost2001_keygen(EVP_PKEY_get0(sec_key))) { - goto err; - } - } - } - if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) - && param == gost_cipher_list) { - param = gost_cipher_list + 1; - } - if (out) { - VKO_compute_key(shared_key, 32, - EC_KEY_get0_public_key(EVP_PKEY_get0(pubk)), - EVP_PKEY_get0(sec_key), ukm); - gost_init(&cctx, param->sblock); - keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key); - } - gkt = GOST_KEY_TRANSPORT_new(); - if (!gkt) { - goto err; - } - if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { - goto err; - } - if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { - goto err; - } - if (!ASN1_OCTET_STRING_set - (gkt->key_info->encrypted_key, crypted_key + 8, 32)) { - goto err; - } - if (key_is_ephemeral) { - if (!X509_PUBKEY_set - (&gkt->key_agreement_info->ephem_key, out ? sec_key : pubk)) { - GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, - GOST_R_CANNOT_PACK_EPHEMERAL_KEY); - goto err; - } - } - ASN1_OBJECT_free(gkt->key_agreement_info->cipher); - gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); - if (key_is_ephemeral && sec_key) - EVP_PKEY_free(sec_key); - if (!key_is_ephemeral) { - /* Set control "public key from client certificate used" */ - if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) - <= 0) { - GOSTerr(GOST_F_PKEY_GOST01CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); - goto err; - } - } - if ((*out_len = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL)) > 0) - ret = 1; - GOST_KEY_TRANSPORT_free(gkt); - return ret; - err: - if (key_is_ephemeral && sec_key) - EVP_PKEY_free(sec_key); - GOST_KEY_TRANSPORT_free(gkt); - return -1; -} - -/* - * EVP_PKEY_METHOD callback decrypt - * Implementation of GOST2001 key transport, cryptopo variation - */ -int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *pctx, unsigned char *key, - size_t *key_len, const unsigned char *in, - size_t in_len) -{ - const unsigned char *p = in; - EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(pctx); - GOST_KEY_TRANSPORT *gkt = NULL; - int ret = 0; - unsigned char wrappedKey[44]; - unsigned char sharedKey[32]; - gost_ctx ctx; - const struct gost_cipher_info *param = NULL; - EVP_PKEY *eph_key = NULL, *peerkey = NULL; - - if (!key) { - *key_len = 32; - return 1; - } - gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len); - if (!gkt) { - GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, - GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); - return -1; - } - - /* If key transport structure contains public key, use it */ - eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); - if (eph_key) { - if (EVP_PKEY_derive_set_peer(pctx, eph_key) <= 0) { - GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, - GOST_R_INCOMPATIBLE_PEER_KEY); - goto err; - } - } else { - /* Set control "public key from client certificate used" */ - if (EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) - <= 0) { - GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_CTRL_CALL_FAILED); - goto err; - } - } - peerkey = EVP_PKEY_CTX_get0_peerkey(pctx); - if (!peerkey) { - GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, GOST_R_NO_PEER_KEY); - goto err; - } - - param = get_encryption_params(gkt->key_agreement_info->cipher); - if (!param) { - goto err; - } - - gost_init(&ctx, param->sblock); - OPENSSL_assert(gkt->key_agreement_info->eph_iv->length == 8); - memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8); - OPENSSL_assert(gkt->key_info->encrypted_key->length == 32); - memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); - OPENSSL_assert(gkt->key_info->imit->length == 4); - memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); - VKO_compute_key(sharedKey, 32, - EC_KEY_get0_public_key(EVP_PKEY_get0(peerkey)), - EVP_PKEY_get0(priv), wrappedKey); - if (!keyUnwrapCryptoPro(&ctx, sharedKey, wrappedKey, key)) { - GOSTerr(GOST_F_PKEY_GOST01CP_DECRYPT, - GOST_R_ERROR_COMPUTING_SHARED_KEY); - goto err; - } - - ret = 1; - err: - if (eph_key) - EVP_PKEY_free(eph_key); - if (gkt) - GOST_KEY_TRANSPORT_free(gkt); - return ret; -} diff --git a/Sources/COpenSSL/gost2001_keyx.h b/Sources/COpenSSL/gost2001_keyx.h deleted file mode 100644 index 2d29113a..00000000 --- a/Sources/COpenSSL/gost2001_keyx.h +++ /dev/null @@ -1,10 +0,0 @@ -GOST_KEY_TRANSPORT *make_rfc4490_keytransport_2001(EVP_PKEY *pubk, - BIGNUM *eph_key, - const unsigned char *key, - size_t keylen, - unsigned char *ukm, - size_t ukm_len); - -int decrypt_rfc4490_shared_key_2001(EVP_PKEY *priv, - GOST_KEY_TRANSPORT * gkt, - unsigned char *key_buf, int key_buf_len); diff --git a/Sources/COpenSSL/gost89.c b/Sources/COpenSSL/gost89.c deleted file mode 100644 index 4ff4ddd7..00000000 --- a/Sources/COpenSSL/gost89.c +++ /dev/null @@ -1,576 +0,0 @@ -/********************************************************************** - * gost89.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of GOST 28147-89 encryption algorithm * - * No OpenSSL libraries required to compile and use * - * this code * - **********************************************************************/ -#include -#include "gost89.h" -/*- - Substitution blocks from RFC 4357 - - Note: our implementation of gost 28147-89 algorithm - uses S-box matrix rotated 90 degrees counterclockwise, relative to - examples given in RFC. - - -*/ - -/* Substitution blocks from test examples for GOST R 34.11-94*/ -gost_subst_block GostR3411_94_TestParamSet = { - {0X1, 0XF, 0XD, 0X0, 0X5, 0X7, 0XA, 0X4, 0X9, 0X2, 0X3, 0XE, 0X6, 0XB, - 0X8, 0XC} - , - {0XD, 0XB, 0X4, 0X1, 0X3, 0XF, 0X5, 0X9, 0X0, 0XA, 0XE, 0X7, 0X6, 0X8, - 0X2, 0XC} - , - {0X4, 0XB, 0XA, 0X0, 0X7, 0X2, 0X1, 0XD, 0X3, 0X6, 0X8, 0X5, 0X9, 0XC, - 0XF, 0XE} - , - {0X6, 0XC, 0X7, 0X1, 0X5, 0XF, 0XD, 0X8, 0X4, 0XA, 0X9, 0XE, 0X0, 0X3, - 0XB, 0X2} - , - {0X7, 0XD, 0XA, 0X1, 0X0, 0X8, 0X9, 0XF, 0XE, 0X4, 0X6, 0XC, 0XB, 0X2, - 0X5, 0X3} - , - {0X5, 0X8, 0X1, 0XD, 0XA, 0X3, 0X4, 0X2, 0XE, 0XF, 0XC, 0X7, 0X6, 0X0, - 0X9, 0XB} - , - {0XE, 0XB, 0X4, 0XC, 0X6, 0XD, 0XF, 0XA, 0X2, 0X3, 0X8, 0X1, 0X0, 0X7, - 0X5, 0X9} - , - {0X4, 0XA, 0X9, 0X2, 0XD, 0X8, 0X0, 0XE, 0X6, 0XB, 0X1, 0XC, 0X7, 0XF, - 0X5, 0X3} -}; - -/* Substitution blocks for hash function 1.2.643.2.9.1.6.1 */ -gost_subst_block GostR3411_94_CryptoProParamSet = { - {0x1, 0x3, 0xA, 0x9, 0x5, 0xB, 0x4, 0xF, 0x8, 0x6, 0x7, 0xE, 0xD, 0x0, - 0x2, 0xC} - , - {0xD, 0xE, 0x4, 0x1, 0x7, 0x0, 0x5, 0xA, 0x3, 0xC, 0x8, 0xF, 0x6, 0x2, - 0x9, 0xB} - , - {0x7, 0x6, 0x2, 0x4, 0xD, 0x9, 0xF, 0x0, 0xA, 0x1, 0x5, 0xB, 0x8, 0xE, - 0xC, 0x3} - , - {0x7, 0x6, 0x4, 0xB, 0x9, 0xC, 0x2, 0xA, 0x1, 0x8, 0x0, 0xE, 0xF, 0xD, - 0x3, 0x5} - , - {0x4, 0xA, 0x7, 0xC, 0x0, 0xF, 0x2, 0x8, 0xE, 0x1, 0x6, 0x5, 0xD, 0xB, - 0x9, 0x3} - , - {0x7, 0xF, 0xC, 0xE, 0x9, 0x4, 0x1, 0x0, 0x3, 0xB, 0x5, 0x2, 0x6, 0xA, - 0x8, 0xD} - , - {0x5, 0xF, 0x4, 0x0, 0x2, 0xD, 0xB, 0x9, 0x1, 0x7, 0x6, 0x3, 0xC, 0xE, - 0xA, 0x8} - , - {0xA, 0x4, 0x5, 0x6, 0x8, 0x1, 0x3, 0x7, 0xD, 0xC, 0xE, 0x0, 0x9, 0x2, - 0xB, 0xF} -}; - -/* Test paramset from GOST 28147 */ -gost_subst_block Gost28147_TestParamSet = { - {0xC, 0x6, 0x5, 0x2, 0xB, 0x0, 0x9, 0xD, 0x3, 0xE, 0x7, 0xA, 0xF, 0x4, - 0x1, 0x8} - , - {0x9, 0xB, 0xC, 0x0, 0x3, 0x6, 0x7, 0x5, 0x4, 0x8, 0xE, 0xF, 0x1, 0xA, - 0x2, 0xD} - , - {0x8, 0xF, 0x6, 0xB, 0x1, 0x9, 0xC, 0x5, 0xD, 0x3, 0x7, 0xA, 0x0, 0xE, - 0x2, 0x4} - , - {0x3, 0xE, 0x5, 0x9, 0x6, 0x8, 0x0, 0xD, 0xA, 0xB, 0x7, 0xC, 0x2, 0x1, - 0xF, 0x4} - , - {0xE, 0x9, 0xB, 0x2, 0x5, 0xF, 0x7, 0x1, 0x0, 0xD, 0xC, 0x6, 0xA, 0x4, - 0x3, 0x8} - , - {0xD, 0x8, 0xE, 0xC, 0x7, 0x3, 0x9, 0xA, 0x1, 0x5, 0x2, 0x4, 0x6, 0xF, - 0x0, 0xB} - , - {0xC, 0x9, 0xF, 0xE, 0x8, 0x1, 0x3, 0xA, 0x2, 0x7, 0x4, 0xD, 0x6, 0x0, - 0xB, 0x5} - , - {0x4, 0x2, 0xF, 0x5, 0x9, 0x1, 0x0, 0x8, 0xE, 0x3, 0xB, 0xC, 0xD, 0x7, - 0xA, 0x6} -}; - -/* 1.2.643.2.2.31.1 */ -gost_subst_block Gost28147_CryptoProParamSetA = { - {0xB, 0xA, 0xF, 0x5, 0x0, 0xC, 0xE, 0x8, 0x6, 0x2, 0x3, 0x9, 0x1, 0x7, - 0xD, 0x4} - , - {0x1, 0xD, 0x2, 0x9, 0x7, 0xA, 0x6, 0x0, 0x8, 0xC, 0x4, 0x5, 0xF, 0x3, - 0xB, 0xE} - , - {0x3, 0xA, 0xD, 0xC, 0x1, 0x2, 0x0, 0xB, 0x7, 0x5, 0x9, 0x4, 0x8, 0xF, - 0xE, 0x6} - , - {0xB, 0x5, 0x1, 0x9, 0x8, 0xD, 0xF, 0x0, 0xE, 0x4, 0x2, 0x3, 0xC, 0x7, - 0xA, 0x6} - , - {0xE, 0x7, 0xA, 0xC, 0xD, 0x1, 0x3, 0x9, 0x0, 0x2, 0xB, 0x4, 0xF, 0x8, - 0x5, 0x6} - , - {0xE, 0x4, 0x6, 0x2, 0xB, 0x3, 0xD, 0x8, 0xC, 0xF, 0x5, 0xA, 0x0, 0x7, - 0x1, 0x9} - , - {0x3, 0x7, 0xE, 0x9, 0x8, 0xA, 0xF, 0x0, 0x5, 0x2, 0x6, 0xC, 0xB, 0x4, - 0xD, 0x1} - , - {0x9, 0x6, 0x3, 0x2, 0x8, 0xB, 0x1, 0x7, 0xA, 0x4, 0xE, 0xF, 0xC, 0x0, - 0xD, 0x5} -}; - -/* 1.2.643.2.2.31.2 */ -gost_subst_block Gost28147_CryptoProParamSetB = { - {0x0, 0x4, 0xB, 0xE, 0x8, 0x3, 0x7, 0x1, 0xA, 0x2, 0x9, 0x6, 0xF, 0xD, - 0x5, 0xC} - , - {0x5, 0x2, 0xA, 0xB, 0x9, 0x1, 0xC, 0x3, 0x7, 0x4, 0xD, 0x0, 0x6, 0xF, - 0x8, 0xE} - , - {0x8, 0x3, 0x2, 0x6, 0x4, 0xD, 0xE, 0xB, 0xC, 0x1, 0x7, 0xF, 0xA, 0x0, - 0x9, 0x5} - , - {0x2, 0x7, 0xC, 0xF, 0x9, 0x5, 0xA, 0xB, 0x1, 0x4, 0x0, 0xD, 0x6, 0x8, - 0xE, 0x3} - , - {0x7, 0x5, 0x0, 0xD, 0xB, 0x6, 0x1, 0x2, 0x3, 0xA, 0xC, 0xF, 0x4, 0xE, - 0x9, 0x8} - , - {0xE, 0xC, 0x0, 0xA, 0x9, 0x2, 0xD, 0xB, 0x7, 0x5, 0x8, 0xF, 0x3, 0x6, - 0x1, 0x4} - , - {0x0, 0x1, 0x2, 0xA, 0x4, 0xD, 0x5, 0xC, 0x9, 0x7, 0x3, 0xF, 0xB, 0x8, - 0x6, 0xE} - , - {0x8, 0x4, 0xB, 0x1, 0x3, 0x5, 0x0, 0x9, 0x2, 0xE, 0xA, 0xC, 0xD, 0x6, - 0x7, 0xF} -}; - -/* 1.2.643.2.2.31.3 */ -gost_subst_block Gost28147_CryptoProParamSetC = { - {0x7, 0x4, 0x0, 0x5, 0xA, 0x2, 0xF, 0xE, 0xC, 0x6, 0x1, 0xB, 0xD, 0x9, - 0x3, 0x8} - , - {0xA, 0x9, 0x6, 0x8, 0xD, 0xE, 0x2, 0x0, 0xF, 0x3, 0x5, 0xB, 0x4, 0x1, - 0xC, 0x7} - , - {0xC, 0x9, 0xB, 0x1, 0x8, 0xE, 0x2, 0x4, 0x7, 0x3, 0x6, 0x5, 0xA, 0x0, - 0xF, 0xD} - , - {0x8, 0xD, 0xB, 0x0, 0x4, 0x5, 0x1, 0x2, 0x9, 0x3, 0xC, 0xE, 0x6, 0xF, - 0xA, 0x7} - , - {0x3, 0x6, 0x0, 0x1, 0x5, 0xD, 0xA, 0x8, 0xB, 0x2, 0x9, 0x7, 0xE, 0xF, - 0xC, 0x4} - , - {0x8, 0x2, 0x5, 0x0, 0x4, 0x9, 0xF, 0xA, 0x3, 0x7, 0xC, 0xD, 0x6, 0xE, - 0x1, 0xB} - , - {0x0, 0x1, 0x7, 0xD, 0xB, 0x4, 0x5, 0x2, 0x8, 0xE, 0xF, 0xC, 0x9, 0xA, - 0x6, 0x3} - , - {0x1, 0xB, 0xC, 0x2, 0x9, 0xD, 0x0, 0xF, 0x4, 0x5, 0x8, 0xE, 0xA, 0x7, - 0x6, 0x3} -}; - -/* 1.2.643.2.2.31.4 */ -gost_subst_block Gost28147_CryptoProParamSetD = { - {0x1, 0xA, 0x6, 0x8, 0xF, 0xB, 0x0, 0x4, 0xC, 0x3, 0x5, 0x9, 0x7, 0xD, - 0x2, 0xE} - , - {0x3, 0x0, 0x6, 0xF, 0x1, 0xE, 0x9, 0x2, 0xD, 0x8, 0xC, 0x4, 0xB, 0xA, - 0x5, 0x7} - , - {0x8, 0x0, 0xF, 0x3, 0x2, 0x5, 0xE, 0xB, 0x1, 0xA, 0x4, 0x7, 0xC, 0x9, - 0xD, 0x6} - , - {0x0, 0xC, 0x8, 0x9, 0xD, 0x2, 0xA, 0xB, 0x7, 0x3, 0x6, 0x5, 0x4, 0xE, - 0xF, 0x1} - , - {0x1, 0x5, 0xE, 0xC, 0xA, 0x7, 0x0, 0xD, 0x6, 0x2, 0xB, 0x4, 0x9, 0x3, - 0xF, 0x8} - , - {0x1, 0xC, 0xB, 0x0, 0xF, 0xE, 0x6, 0x5, 0xA, 0xD, 0x4, 0x8, 0x9, 0x3, - 0x7, 0x2} - , - {0xB, 0x6, 0x3, 0x4, 0xC, 0xF, 0xE, 0x2, 0x7, 0xD, 0x8, 0x0, 0x5, 0xA, - 0x9, 0x1} - , - {0xF, 0xC, 0x2, 0xA, 0x6, 0x4, 0x5, 0x0, 0x7, 0x9, 0xE, 0xD, 0x1, 0xB, - 0x8, 0x3} -}; - -const byte CryptoProKeyMeshingKey[] = { - 0x69, 0x00, 0x72, 0x22, 0x64, 0xC9, 0x04, 0x23, - 0x8D, 0x3A, 0xDB, 0x96, 0x46, 0xE9, 0x2A, 0xC4, - 0x18, 0xFE, 0xAC, 0x94, 0x00, 0xED, 0x07, 0x12, - 0xC0, 0x86, 0xDC, 0xC2, 0xEF, 0x4C, 0xA9, 0x2B -}; - -/* Initialization of gost_ctx subst blocks*/ -static void kboxinit(gost_ctx * c, const gost_subst_block * b) -{ - int i; - - for (i = 0; i < 256; i++) { - c->k87[i] = (word32) (b->k8[i >> 4] << 4 | b->k7[i & 15]) << 24; - c->k65[i] = (b->k6[i >> 4] << 4 | b->k5[i & 15]) << 16; - c->k43[i] = (b->k4[i >> 4] << 4 | b->k3[i & 15]) << 8; - c->k21[i] = b->k2[i >> 4] << 4 | b->k1[i & 15]; - - } -} - -/* Part of GOST 28147 algorithm moved into separate function */ -static word32 f(gost_ctx * c, word32 x) -{ - x = c->k87[x >> 24 & 255] | c->k65[x >> 16 & 255] | - c->k43[x >> 8 & 255] | c->k21[x & 255]; - /* Rotate left 11 bits */ - return x << 11 | x >> (32 - 11); -} - -/* Low-level encryption routine - encrypts one 64 bit block*/ -void gostcrypt(gost_ctx * c, const byte * in, byte * out) -{ - register word32 n1, n2; /* As named in the GOST */ - n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24); - n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24); - /* Instead of swapping halves, swap names each round */ - - n2 ^= f(c, n1 + c->k[0]); - n1 ^= f(c, n2 + c->k[1]); - n2 ^= f(c, n1 + c->k[2]); - n1 ^= f(c, n2 + c->k[3]); - n2 ^= f(c, n1 + c->k[4]); - n1 ^= f(c, n2 + c->k[5]); - n2 ^= f(c, n1 + c->k[6]); - n1 ^= f(c, n2 + c->k[7]); - - n2 ^= f(c, n1 + c->k[0]); - n1 ^= f(c, n2 + c->k[1]); - n2 ^= f(c, n1 + c->k[2]); - n1 ^= f(c, n2 + c->k[3]); - n2 ^= f(c, n1 + c->k[4]); - n1 ^= f(c, n2 + c->k[5]); - n2 ^= f(c, n1 + c->k[6]); - n1 ^= f(c, n2 + c->k[7]); - - n2 ^= f(c, n1 + c->k[0]); - n1 ^= f(c, n2 + c->k[1]); - n2 ^= f(c, n1 + c->k[2]); - n1 ^= f(c, n2 + c->k[3]); - n2 ^= f(c, n1 + c->k[4]); - n1 ^= f(c, n2 + c->k[5]); - n2 ^= f(c, n1 + c->k[6]); - n1 ^= f(c, n2 + c->k[7]); - - n2 ^= f(c, n1 + c->k[7]); - n1 ^= f(c, n2 + c->k[6]); - n2 ^= f(c, n1 + c->k[5]); - n1 ^= f(c, n2 + c->k[4]); - n2 ^= f(c, n1 + c->k[3]); - n1 ^= f(c, n2 + c->k[2]); - n2 ^= f(c, n1 + c->k[1]); - n1 ^= f(c, n2 + c->k[0]); - - out[0] = (byte) (n2 & 0xff); - out[1] = (byte) ((n2 >> 8) & 0xff); - out[2] = (byte) ((n2 >> 16) & 0xff); - out[3] = (byte) (n2 >> 24); - out[4] = (byte) (n1 & 0xff); - out[5] = (byte) ((n1 >> 8) & 0xff); - out[6] = (byte) ((n1 >> 16) & 0xff); - out[7] = (byte) (n1 >> 24); -} - -/* Low-level decryption routine. Decrypts one 64-bit block */ -void gostdecrypt(gost_ctx * c, const byte * in, byte * out) -{ - register word32 n1, n2; /* As named in the GOST */ - n1 = in[0] | (in[1] << 8) | (in[2] << 16) | ((word32) in[3] << 24); - n2 = in[4] | (in[5] << 8) | (in[6] << 16) | ((word32) in[7] << 24); - - n2 ^= f(c, n1 + c->k[0]); - n1 ^= f(c, n2 + c->k[1]); - n2 ^= f(c, n1 + c->k[2]); - n1 ^= f(c, n2 + c->k[3]); - n2 ^= f(c, n1 + c->k[4]); - n1 ^= f(c, n2 + c->k[5]); - n2 ^= f(c, n1 + c->k[6]); - n1 ^= f(c, n2 + c->k[7]); - - n2 ^= f(c, n1 + c->k[7]); - n1 ^= f(c, n2 + c->k[6]); - n2 ^= f(c, n1 + c->k[5]); - n1 ^= f(c, n2 + c->k[4]); - n2 ^= f(c, n1 + c->k[3]); - n1 ^= f(c, n2 + c->k[2]); - n2 ^= f(c, n1 + c->k[1]); - n1 ^= f(c, n2 + c->k[0]); - - n2 ^= f(c, n1 + c->k[7]); - n1 ^= f(c, n2 + c->k[6]); - n2 ^= f(c, n1 + c->k[5]); - n1 ^= f(c, n2 + c->k[4]); - n2 ^= f(c, n1 + c->k[3]); - n1 ^= f(c, n2 + c->k[2]); - n2 ^= f(c, n1 + c->k[1]); - n1 ^= f(c, n2 + c->k[0]); - - n2 ^= f(c, n1 + c->k[7]); - n1 ^= f(c, n2 + c->k[6]); - n2 ^= f(c, n1 + c->k[5]); - n1 ^= f(c, n2 + c->k[4]); - n2 ^= f(c, n1 + c->k[3]); - n1 ^= f(c, n2 + c->k[2]); - n2 ^= f(c, n1 + c->k[1]); - n1 ^= f(c, n2 + c->k[0]); - - out[0] = (byte) (n2 & 0xff); - out[1] = (byte) ((n2 >> 8) & 0xff); - out[2] = (byte) ((n2 >> 16) & 0xff); - out[3] = (byte) (n2 >> 24); - out[4] = (byte) (n1 & 0xff); - out[5] = (byte) ((n1 >> 8) & 0xff); - out[6] = (byte) ((n1 >> 16) & 0xff); - out[7] = (byte) (n1 >> 24); -} - -/* Encrypts several blocks in ECB mode */ -void gost_enc(gost_ctx * c, const byte * clear, byte * cipher, int blocks) -{ - int i; - for (i = 0; i < blocks; i++) { - gostcrypt(c, clear, cipher); - clear += 8; - cipher += 8; - } -} - -/* Decrypts several blocks in ECB mode */ -void gost_dec(gost_ctx * c, const byte * cipher, byte * clear, int blocks) -{ - int i; - for (i = 0; i < blocks; i++) { - gostdecrypt(c, cipher, clear); - clear += 8; - cipher += 8; - } -} - -/* Encrypts several full blocks in CFB mode using 8byte IV */ -void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear, - byte * cipher, int blocks) -{ - byte cur_iv[8]; - byte gamma[8]; - int i, j; - const byte *in; - byte *out; - memcpy(cur_iv, iv, 8); - for (i = 0, in = clear, out = cipher; i < blocks; i++, in += 8, out += 8) { - gostcrypt(ctx, cur_iv, gamma); - for (j = 0; j < 8; j++) { - cur_iv[j] = out[j] = in[j] ^ gamma[j]; - } - } -} - -/* Decrypts several full blocks in CFB mode using 8byte IV */ -void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher, - byte * clear, int blocks) -{ - byte cur_iv[8]; - byte gamma[8]; - int i, j; - const byte *in; - byte *out; - memcpy(cur_iv, iv, 8); - for (i = 0, in = cipher, out = clear; i < blocks; i++, in += 8, out += 8) { - gostcrypt(ctx, cur_iv, gamma); - for (j = 0; j < 8; j++) { - out[j] = (cur_iv[j] = in[j]) ^ gamma[j]; - } - } -} - -/* Encrypts one block using specified key */ -void gost_enc_with_key(gost_ctx * c, byte * key, byte * inblock, - byte * outblock) -{ - gost_key(c, key); - gostcrypt(c, inblock, outblock); -} - -/* Set 256 bit key into context */ -void gost_key(gost_ctx * c, const byte * k) -{ - int i, j; - for (i = 0, j = 0; i < 8; i++, j += 4) { - c->k[i] = - k[j] | (k[j + 1] << 8) | (k[j + 2] << 16) | ((word32) k[j + 3] << - 24); - } -} - -/* Retrieve 256-bit key from context */ -void gost_get_key(gost_ctx * c, byte * k) -{ - int i, j; - for (i = 0, j = 0; i < 8; i++, j += 4) { - k[j] = (byte) (c->k[i] & 0xFF); - k[j + 1] = (byte) ((c->k[i] >> 8) & 0xFF); - k[j + 2] = (byte) ((c->k[i] >> 16) & 0xFF); - k[j + 3] = (byte) ((c->k[i] >> 24) & 0xFF); - } -} - -/* Initalize context. Provides default value for subst_block */ -void gost_init(gost_ctx * c, const gost_subst_block * b) -{ - if (!b) { - b = &GostR3411_94_TestParamSet; - } - kboxinit(c, b); -} - -/* Cleans up key from context */ -void gost_destroy(gost_ctx * c) -{ - int i; - for (i = 0; i < 8; i++) - c->k[i] = 0; -} - -/* - * Compute GOST 28147 mac block Parameters gost_ctx *c - context initalized - * with substitution blocks and key buffer - 8-byte mac state buffer block - * 8-byte block to process. - */ -void mac_block(gost_ctx * c, byte * buffer, const byte * block) -{ - register word32 n1, n2; /* As named in the GOST */ - int i; - for (i = 0; i < 8; i++) { - buffer[i] ^= block[i]; - } - n1 = buffer[0] | (buffer[1] << 8) | (buffer[2] << 16) | ((word32) - buffer[3] << 24); - n2 = buffer[4] | (buffer[5] << 8) | (buffer[6] << 16) | ((word32) - buffer[7] << 24); - /* Instead of swapping halves, swap names each round */ - - n2 ^= f(c, n1 + c->k[0]); - n1 ^= f(c, n2 + c->k[1]); - n2 ^= f(c, n1 + c->k[2]); - n1 ^= f(c, n2 + c->k[3]); - n2 ^= f(c, n1 + c->k[4]); - n1 ^= f(c, n2 + c->k[5]); - n2 ^= f(c, n1 + c->k[6]); - n1 ^= f(c, n2 + c->k[7]); - - n2 ^= f(c, n1 + c->k[0]); - n1 ^= f(c, n2 + c->k[1]); - n2 ^= f(c, n1 + c->k[2]); - n1 ^= f(c, n2 + c->k[3]); - n2 ^= f(c, n1 + c->k[4]); - n1 ^= f(c, n2 + c->k[5]); - n2 ^= f(c, n1 + c->k[6]); - n1 ^= f(c, n2 + c->k[7]); - - buffer[0] = (byte) (n1 & 0xff); - buffer[1] = (byte) ((n1 >> 8) & 0xff); - buffer[2] = (byte) ((n1 >> 16) & 0xff); - buffer[3] = (byte) (n1 >> 24); - buffer[4] = (byte) (n2 & 0xff); - buffer[5] = (byte) ((n2 >> 8) & 0xff); - buffer[6] = (byte) ((n2 >> 16) & 0xff); - buffer[7] = (byte) (n2 >> 24); -} - -/* Get mac with specified number of bits from MAC state buffer */ -void get_mac(byte * buffer, int nbits, byte * out) -{ - int nbytes = nbits >> 3; - int rembits = nbits & 7; - int mask = rembits ? ((1 < rembits) - 1) : 0; - int i; - for (i = 0; i < nbytes; i++) - out[i] = buffer[i]; - if (rembits) - out[i] = buffer[i] & mask; -} - -/* - * Compute mac of specified length (in bits) from data. Context should be - * initialized with key and subst blocks - */ -int gost_mac(gost_ctx * ctx, int mac_len, const unsigned char *data, - unsigned int data_len, unsigned char *mac) -{ - byte buffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - byte buf2[8]; - unsigned int i; - for (i = 0; i + 8 <= data_len; i += 8) - mac_block(ctx, buffer, data + i); - if (i < data_len) { - memset(buf2, 0, 8); - memcpy(buf2, data + i, data_len - i); - mac_block(ctx, buffer, buf2); - i += 8; - } - if (i == 8) { - memset(buf2, 0, 8); - mac_block(ctx, buffer, buf2); - } - get_mac(buffer, mac_len, mac); - return 1; -} - -/* Compute MAC with non-zero IV. Used in some RFC 4357 algorithms */ -int gost_mac_iv(gost_ctx * ctx, int mac_len, const unsigned char *iv, - const unsigned char *data, unsigned int data_len, - unsigned char *mac) -{ - byte buffer[8]; - byte buf2[8]; - unsigned int i; - memcpy(buffer, iv, 8); - for (i = 0; i + 8 <= data_len; i += 8) - mac_block(ctx, buffer, data + i); - if (i < data_len) { - memset(buf2, 0, 8); - memcpy(buf2, data + i, data_len - i); - mac_block(ctx, buffer, buf2); - i += 8; - } - if (i == 8) { - memset(buf2, 0, 8); - mac_block(ctx, buffer, buf2); - } - get_mac(buffer, mac_len, mac); - return 1; -} - -/* Implements key meshing algorithm by modifing ctx and IV in place */ -void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv) -{ - unsigned char newkey[32], newiv[8]; - /* Set static keymeshing key */ - /* "Decrypt" key with keymeshing key */ - gost_dec(ctx, CryptoProKeyMeshingKey, newkey, 4); - /* set new key */ - gost_key(ctx, newkey); - /* Encrypt iv with new key */ - gostcrypt(ctx, iv, newiv); - memcpy(iv, newiv, 8); -} diff --git a/Sources/COpenSSL/gost89.h b/Sources/COpenSSL/gost89.h deleted file mode 100644 index e5b877f4..00000000 --- a/Sources/COpenSSL/gost89.h +++ /dev/null @@ -1,98 +0,0 @@ -/********************************************************************** - * gost89.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declarations for GOST 28147-89 encryption algorithm * - * No OpenSSL libraries required to compile and use * - * this code * - **********************************************************************/ -#ifndef GOST89_H -# define GOST89_H - -/* Typedef for unsigned 32-bit integer */ -# if __LONG_MAX__ > 2147483647L -typedef unsigned int u4; -# else -typedef unsigned long u4; -# endif -/* Typedef for unsigned 8-bit integer */ -typedef unsigned char byte; - -/* Internal representation of GOST substitution blocks */ -typedef struct { - byte k8[16]; - byte k7[16]; - byte k6[16]; - byte k5[16]; - byte k4[16]; - byte k3[16]; - byte k2[16]; - byte k1[16]; -} gost_subst_block; - -/* Cipher context includes key and preprocessed substitution block */ -typedef struct { - u4 k[8]; - /* Constant s-boxes -- set up in gost_init(). */ - u4 k87[256], k65[256], k43[256], k21[256]; -} gost_ctx; -/* - * Note: encrypt and decrypt expect full blocks--padding blocks is caller's - * responsibility. All bulk encryption is done in ECB mode by these calls. - * Other modes may be added easily enough. - */ -/* Encrypt several full blocks in ECB mode */ -void gost_enc(gost_ctx * ctx, const byte * clear, byte * cipher, int blocks); -/* Decrypt several full blocks in ECB mode */ -void gost_dec(gost_ctx * ctx, const byte * cipher, byte * clear, int blocks); -/* Encrypts several full blocks in CFB mode using 8byte IV */ -void gost_enc_cfb(gost_ctx * ctx, const byte * iv, const byte * clear, - byte * cipher, int blocks); -/* Decrypts several full blocks in CFB mode using 8byte IV */ -void gost_dec_cfb(gost_ctx * ctx, const byte * iv, const byte * cipher, - byte * clear, int blocks); - -/* Encrypt one block */ -void gostcrypt(gost_ctx * c, const byte * in, byte * out); -/* Decrypt one block */ -void gostdecrypt(gost_ctx * c, const byte * in, byte * out); -/* Set key into context */ -void gost_key(gost_ctx * ctx, const byte * key); -/* Get key from context */ -void gost_get_key(gost_ctx * ctx, byte * key); -/* Set S-blocks into context */ -void gost_init(gost_ctx * ctx, const gost_subst_block * subst_block); -/* Clean up context */ -void gost_destroy(gost_ctx * ctx); -/* Intermediate function used for calculate hash */ -void gost_enc_with_key(gost_ctx *, byte * key, byte * inblock, - byte * outblock); -/* Compute MAC of given length in bits from data */ -int gost_mac(gost_ctx * ctx, int hmac_len, const unsigned char *data, - unsigned int data_len, unsigned char *hmac); -/* - * Compute MAC of given length in bits from data, using non-zero 8-byte IV - * (non-standard, for use in CryptoPro key transport only - */ -int gost_mac_iv(gost_ctx * ctx, int hmac_len, const unsigned char *iv, - const unsigned char *data, unsigned int data_len, - unsigned char *hmac); -/* Perform one step of MAC calculation like gostcrypt */ -void mac_block(gost_ctx * c, byte * buffer, const byte * block); -/* Extracts MAC value from mac state buffer */ -void get_mac(byte * buffer, int nbits, byte * out); -/* Implements cryptopro key meshing algorithm. Expect IV to be 8-byte size*/ -void cryptopro_key_meshing(gost_ctx * ctx, unsigned char *iv); -/* Parameter sets specified in RFC 4357 */ -extern gost_subst_block GostR3411_94_TestParamSet; -extern gost_subst_block GostR3411_94_CryptoProParamSet; -extern gost_subst_block Gost28147_TestParamSet; -extern gost_subst_block Gost28147_CryptoProParamSetA; -extern gost_subst_block Gost28147_CryptoProParamSetB; -extern gost_subst_block Gost28147_CryptoProParamSetC; -extern gost_subst_block Gost28147_CryptoProParamSetD; -extern const byte CryptoProKeyMeshingKey[]; -typedef unsigned int word32; - -#endif diff --git a/Sources/COpenSSL/gost94_keyx.c b/Sources/COpenSSL/gost94_keyx.c deleted file mode 100644 index 94e7f45e..00000000 --- a/Sources/COpenSSL/gost94_keyx.c +++ /dev/null @@ -1,282 +0,0 @@ -/********************************************************************** - * gost94_keyx.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implements generation and parsing of GOST_KEY_TRANSPORT for * - * GOST R 34.10-94 algorithms * - * * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include -#include "dh.h" -#include "rand.h" -#include "evp.h" -#include "objects.h" - -#include "gost89.h" -#include "gosthash.h" -#include "e_gost_err.h" -#include "gost_keywrap.h" -#include "gost_lcl.h" -/* Common functions for both 94 and 2001 key exchange schemes */ -/* - * Implementation of the Diffi-Hellman key agreement scheme based on GOST-94 - * keys - */ - -/* - * Computes Diffie-Hellman key and stores it into buffer in little-endian - * byte order as expected by both versions of GOST 94 algorithm - */ -static int compute_pair_key_le(unsigned char *pair_key, BIGNUM *pub_key, - DH *dh) -{ - unsigned char be_key[128]; - int i, key_size; - key_size = DH_compute_key(be_key, pub_key, dh); - if (!key_size) - return 0; - memset(pair_key, 0, 128); - for (i = 0; i < key_size; i++) { - pair_key[i] = be_key[key_size - 1 - i]; - } - return key_size; -} - -/* - * Computes 256 bit Key exchange key as specified in RFC 4357 - */ -static int make_cp_exchange_key(BIGNUM *priv_key, EVP_PKEY *pubk, - unsigned char *shared_key) -{ - unsigned char dh_key[128]; - int ret; - gost_hash_ctx hash_ctx; - DH *dh = DH_new(); - - if (!dh) - return 0; - memset(dh_key, 0, 128); - dh->g = BN_dup(pubk->pkey.dsa->g); - dh->p = BN_dup(pubk->pkey.dsa->p); - dh->priv_key = BN_dup(priv_key); - ret = - compute_pair_key_le(dh_key, ((DSA *)(EVP_PKEY_get0(pubk)))->pub_key, - dh); - DH_free(dh); - if (!ret) - return 0; - init_gost_hash_ctx(&hash_ctx, &GostR3411_94_CryptoProParamSet); - start_hash(&hash_ctx); - hash_block(&hash_ctx, dh_key, 128); - finish_hash(&hash_ctx, shared_key); - done_gost_hash_ctx(&hash_ctx); - return 1; -} - -/* EVP_PKEY_METHOD callback derive. Implements VKO R 34.10-94 */ - -int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen) -{ - EVP_PKEY *pubk = EVP_PKEY_CTX_get0_peerkey(ctx); - EVP_PKEY *mykey = EVP_PKEY_CTX_get0_pkey(ctx); - *keylen = 32; - if (key == NULL) - return 1; - - return make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, key); -} - -/* - * EVP_PKEY_METHOD callback encrypt for GOST R 34.10-94 cryptopro - * modification - */ - -int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *key, - size_t key_len) -{ - GOST_KEY_TRANSPORT *gkt = NULL; - unsigned char shared_key[32], ukm[8], crypted_key[44]; - const struct gost_cipher_info *param = get_encryption_params(NULL); - EVP_PKEY *pubk = EVP_PKEY_CTX_get0_pkey(ctx); - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - gost_ctx cctx; - int key_is_ephemeral = 1; - int tmp_outlen; - EVP_PKEY *mykey = EVP_PKEY_CTX_get0_peerkey(ctx); - - /* Do not use vizir cipher parameters with cryptopro */ - if (!get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS) - && param == gost_cipher_list) { - param = gost_cipher_list + 1; - } - - if (mykey) { - /* If key already set, it is not ephemeral */ - key_is_ephemeral = 0; - if (!gost_get0_priv_key(mykey)) { - GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, - GOST_R_NO_PRIVATE_PART_OF_NON_EPHEMERAL_KEYPAIR); - goto err; - } - } else { - /* Otherwise generate ephemeral key */ - key_is_ephemeral = 1; - if (out) { - mykey = EVP_PKEY_new(); - if (!mykey) - goto memerr; - EVP_PKEY_assign(mykey, EVP_PKEY_base_id(pubk), DSA_new()); - EVP_PKEY_copy_parameters(mykey, pubk); - if (!gost_sign_keygen(EVP_PKEY_get0(mykey))) { - goto err; - } - } - } - if (out) - make_cp_exchange_key(gost_get0_priv_key(mykey), pubk, shared_key); - if (data->shared_ukm) { - memcpy(ukm, data->shared_ukm, 8); - } else if (out) { - if (RAND_bytes(ukm, 8) <= 0) { - GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, - GOST_R_RANDOM_GENERATOR_FAILURE); - goto err; - } - } - - if (out) { - gost_init(&cctx, param->sblock); - keyWrapCryptoPro(&cctx, shared_key, ukm, key, crypted_key); - } - gkt = GOST_KEY_TRANSPORT_new(); - if (!gkt) { - goto memerr; - } - if (!ASN1_OCTET_STRING_set(gkt->key_agreement_info->eph_iv, ukm, 8)) { - goto memerr; - } - if (!ASN1_OCTET_STRING_set(gkt->key_info->imit, crypted_key + 40, 4)) { - goto memerr; - } - if (!ASN1_OCTET_STRING_set - (gkt->key_info->encrypted_key, crypted_key + 8, 32)) { - goto memerr; - } - if (key_is_ephemeral) { - if (!X509_PUBKEY_set - (&gkt->key_agreement_info->ephem_key, out ? mykey : pubk)) { - GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, - GOST_R_CANNOT_PACK_EPHEMERAL_KEY); - goto err; - } - if (out) - EVP_PKEY_free(mykey); - } - ASN1_OBJECT_free(gkt->key_agreement_info->cipher); - gkt->key_agreement_info->cipher = OBJ_nid2obj(param->nid); - tmp_outlen = i2d_GOST_KEY_TRANSPORT(gkt, out ? &out : NULL); - if (tmp_outlen <= 0) { - GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, - GOST_R_ERROR_PACKING_KEY_TRANSPORT_INFO); - goto err; - } - *outlen = tmp_outlen; - if (!key_is_ephemeral) { - /* Set control "public key from client certificate used" */ - if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= - 0) { - GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_CTRL_CALL_FAILED); - goto err; - } - } - GOST_KEY_TRANSPORT_free(gkt); - return 1; - memerr: - if (key_is_ephemeral) { - EVP_PKEY_free(mykey); - } - GOSTerr(GOST_F_PKEY_GOST94CP_ENCRYPT, GOST_R_MALLOC_FAILURE); - err: - GOST_KEY_TRANSPORT_free(gkt); - return -1; -} - -/* - * EVP_PLEY_METHOD callback decrypt for GOST R 34.10-94 cryptopro - * modification - */ -int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *key_len, const unsigned char *in, - size_t in_len) -{ - const unsigned char *p = in; - GOST_KEY_TRANSPORT *gkt = NULL; - unsigned char wrappedKey[44]; - unsigned char sharedKey[32]; - gost_ctx cctx; - const struct gost_cipher_info *param = NULL; - EVP_PKEY *eph_key = NULL, *peerkey = NULL; - EVP_PKEY *priv = EVP_PKEY_CTX_get0_pkey(ctx); - - if (!key) { - *key_len = 32; - return 1; - } - - gkt = d2i_GOST_KEY_TRANSPORT(NULL, (const unsigned char **)&p, in_len); - if (!gkt) { - GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, - GOST_R_ERROR_PARSING_KEY_TRANSPORT_INFO); - return 0; - } - eph_key = X509_PUBKEY_get(gkt->key_agreement_info->ephem_key); - if (eph_key) { - if (EVP_PKEY_derive_set_peer(ctx, eph_key) <= 0) { - GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, - GOST_R_INCOMPATIBLE_PEER_KEY); - goto err; - } - } else { - /* Set control "public key from client certificate used" */ - if (EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 3, NULL) <= - 0) { - GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, GOST_R_CTRL_CALL_FAILED); - goto err; - } - } - peerkey = EVP_PKEY_CTX_get0_peerkey(ctx); - if (!peerkey) { - GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, GOST_R_NO_PEER_KEY); - goto err; - } - - param = get_encryption_params(gkt->key_agreement_info->cipher); - if (!param) { - goto err; - } - - gost_init(&cctx, param->sblock); - OPENSSL_assert(gkt->key_agreement_info->eph_iv->length == 8); - memcpy(wrappedKey, gkt->key_agreement_info->eph_iv->data, 8); - OPENSSL_assert(gkt->key_info->encrypted_key->length == 32); - memcpy(wrappedKey + 8, gkt->key_info->encrypted_key->data, 32); - OPENSSL_assert(gkt->key_info->imit->length == 4); - memcpy(wrappedKey + 40, gkt->key_info->imit->data, 4); - make_cp_exchange_key(gost_get0_priv_key(priv), peerkey, sharedKey); - if (!keyUnwrapCryptoPro(&cctx, sharedKey, wrappedKey, key)) { - GOSTerr(GOST_F_PKEY_GOST94CP_DECRYPT, - GOST_R_ERROR_COMPUTING_SHARED_KEY); - goto err; - } - - EVP_PKEY_free(eph_key); - GOST_KEY_TRANSPORT_free(gkt); - return 1; - err: - EVP_PKEY_free(eph_key); - GOST_KEY_TRANSPORT_free(gkt); - return -1; -} diff --git a/Sources/COpenSSL/gost_.c b/Sources/COpenSSL/gost_.c deleted file mode 100644 index 904540d7..00000000 --- a/Sources/COpenSSL/gost_.c +++ /dev/null @@ -1,3397 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/********************************************************************** - * gost_ameth.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of RFC 4490/4491 ASN1 method * - * for OpenSSL * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include -#include "crypto.h" -#include "err.h" -#include "engine.h" -#include "evp.h" -#include "asn1.h" -#ifndef OPENSSL_NO_CMS -# include "cms.h" -#endif -#include "gost_params.h" -#include "gost_lcl.h" -#include "e_gost_err.h" - -int gost94_nid_by_params(DSA *p) -{ - R3410_params *gost_params; - BIGNUM *q = BN_new(); - for (gost_params = R3410_paramset; gost_params->q != NULL; gost_params++) { - BN_dec2bn(&q, gost_params->q); - if (!BN_cmp(q, p->q)) { - BN_free(q); - return gost_params->nid; - } - } - BN_free(q); - return NID_undef; -} - -static ASN1_STRING *encode_gost_algor_params(const EVP_PKEY *key) -{ - ASN1_STRING *params = ASN1_STRING_new(); - GOST_KEY_PARAMS *gkp = GOST_KEY_PARAMS_new(); - int pkey_param_nid = NID_undef; - - if (!params || !gkp) { - GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(params); - params = NULL; - goto err; - } - switch (EVP_PKEY_base_id(key)) { - case NID_id_GostR3410_2001: - pkey_param_nid = - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)key))); - break; - case NID_id_GostR3410_94: - pkey_param_nid = - (int)gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)key)); - if (pkey_param_nid == NID_undef) { - GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, - GOST_R_INVALID_GOST94_PARMSET); - ASN1_STRING_free(params); - params = NULL; - goto err; - } - break; - } - gkp->key_params = OBJ_nid2obj(pkey_param_nid); - gkp->hash_params = OBJ_nid2obj(NID_id_GostR3411_94_CryptoProParamSet); - /* - * gkp->cipher_params = OBJ_nid2obj(cipher_param_nid); - */ - params->length = i2d_GOST_KEY_PARAMS(gkp, ¶ms->data); - if (params->length <= 0) { - GOSTerr(GOST_F_ENCODE_GOST_ALGOR_PARAMS, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(params); - params = NULL; - goto err; - } - params->type = V_ASN1_SEQUENCE; - err: - GOST_KEY_PARAMS_free(gkp); - return params; -} - -/* - * Parses GOST algorithm parameters from X509_ALGOR and modifies pkey setting - * NID and parameters - */ -static int decode_gost_algor_params(EVP_PKEY *pkey, X509_ALGOR *palg) -{ - ASN1_OBJECT *palg_obj = NULL; - int ptype = V_ASN1_UNDEF; - int pkey_nid = NID_undef, param_nid = NID_undef; - void *_pval; - ASN1_STRING *pval = NULL; - const unsigned char *p; - GOST_KEY_PARAMS *gkp = NULL; - - X509_ALGOR_get0(&palg_obj, &ptype, &_pval, palg); - pval = _pval; - if (ptype != V_ASN1_SEQUENCE) { - GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, - GOST_R_BAD_KEY_PARAMETERS_FORMAT); - return 0; - } - p = pval->data; - pkey_nid = OBJ_obj2nid(palg_obj); - - gkp = d2i_GOST_KEY_PARAMS(NULL, &p, pval->length); - if (!gkp) { - GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, - GOST_R_BAD_PKEY_PARAMETERS_FORMAT); - return 0; - } - param_nid = OBJ_obj2nid(gkp->key_params); - GOST_KEY_PARAMS_free(gkp); - if(!EVP_PKEY_set_type(pkey, pkey_nid)) { - GOSTerr(GOST_F_DECODE_GOST_ALGOR_PARAMS, ERR_R_INTERNAL_ERROR); - return 0; - } - switch (pkey_nid) { - case NID_id_GostR3410_94: - { - DSA *dsa = EVP_PKEY_get0(pkey); - if (!dsa) { - dsa = DSA_new(); - if (!EVP_PKEY_assign(pkey, pkey_nid, dsa)) - return 0; - } - if (!fill_GOST94_params(dsa, param_nid)) - return 0; - break; - } - case NID_id_GostR3410_2001: - { - EC_KEY *ec = EVP_PKEY_get0(pkey); - if (!ec) { - ec = EC_KEY_new(); - if (!EVP_PKEY_assign(pkey, pkey_nid, ec)) - return 0; - } - if (!fill_GOST2001_params(ec, param_nid)) - return 0; - } - } - - return 1; -} - -static int gost_set_priv_key(EVP_PKEY *pkey, BIGNUM *priv) -{ - switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - { - DSA *dsa = EVP_PKEY_get0(pkey); - if (!dsa) { - dsa = DSA_new(); - EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), dsa); - } - dsa->priv_key = BN_dup(priv); - if (!EVP_PKEY_missing_parameters(pkey)) - gost94_compute_public(dsa); - break; - } - case NID_id_GostR3410_2001: - { - EC_KEY *ec = EVP_PKEY_get0(pkey); - if (!ec) { - ec = EC_KEY_new(); - EVP_PKEY_assign(pkey, EVP_PKEY_base_id(pkey), ec); - } - if (!EC_KEY_set_private_key(ec, priv)) - return 0; - if (!EVP_PKEY_missing_parameters(pkey)) - gost2001_compute_public(ec); - break; - } - } - return 1; -} - -BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey) -{ - switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - { - DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pkey); - if (!dsa) { - return NULL; - } - if (!dsa->priv_key) - return NULL; - return dsa->priv_key; - break; - } - case NID_id_GostR3410_2001: - { - EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pkey); - const BIGNUM *priv; - if (!ec) { - return NULL; - } - if (!(priv = EC_KEY_get0_private_key(ec))) - return NULL; - return (BIGNUM *)priv; - break; - } - } - return NULL; -} - -static int pkey_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - switch (op) { - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) { - X509_ALGOR *alg1 = NULL, *alg2 = NULL; - int nid = EVP_PKEY_base_id(pkey); - PKCS7_SIGNER_INFO_get0_algs((PKCS7_SIGNER_INFO *)arg2, - NULL, &alg1, &alg2); - X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), - V_ASN1_NULL, 0); - if (nid == NID_undef) { - return (-1); - } - X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); - } - return 1; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) { - X509_ALGOR *alg1 = NULL, *alg2 = NULL; - int nid = EVP_PKEY_base_id(pkey); - CMS_SignerInfo_get0_algs((CMS_SignerInfo *)arg2, - NULL, NULL, &alg1, &alg2); - X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_id_GostR3411_94), - V_ASN1_NULL, 0); - if (nid == NID_undef) { - return (-1); - } - X509_ALGOR_set0(alg2, OBJ_nid2obj(nid), V_ASN1_NULL, 0); - } - return 1; -#endif - case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: - if (arg1 == 0) { - X509_ALGOR *alg; - ASN1_STRING *params = encode_gost_algor_params(pkey); - if (!params) { - return -1; - } - PKCS7_RECIP_INFO_get0_alg((PKCS7_RECIP_INFO *)arg2, &alg); - X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), - V_ASN1_SEQUENCE, params); - } - return 1; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (arg1 == 0) { - X509_ALGOR *alg = NULL; - ASN1_STRING *params = encode_gost_algor_params(pkey); - if (!params) { - return -1; - } - CMS_RecipientInfo_ktri_get0_algs((CMS_RecipientInfo *)arg2, NULL, - NULL, &alg); - X509_ALGOR_set0(alg, OBJ_nid2obj(pkey->type), V_ASN1_SEQUENCE, - params); - } - return 1; -#endif - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_id_GostR3411_94; - return 2; - } - - return -2; -} - -/* --------------------- free functions * ------------------------------*/ -static void pkey_free_gost94(EVP_PKEY *key) -{ - if (key->pkey.dsa) { - DSA_free(key->pkey.dsa); - } -} - -static void pkey_free_gost01(EVP_PKEY *key) -{ - if (key->pkey.ec) { - EC_KEY_free(key->pkey.ec); - } -} - -/* ------------------ private key functions -----------------------------*/ -static int priv_decode_gost(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf) -{ - const unsigned char *pkey_buf = NULL, *p = NULL; - int priv_len = 0; - BIGNUM *pk_num = NULL; - int ret = 0; - X509_ALGOR *palg = NULL; - ASN1_OBJECT *palg_obj = NULL; - ASN1_INTEGER *priv_key = NULL; - - if (!PKCS8_pkey_get0(&palg_obj, &pkey_buf, &priv_len, &palg, p8inf)) - return 0; - p = pkey_buf; - if (!decode_gost_algor_params(pk, palg)) { - return 0; - } - if (V_ASN1_OCTET_STRING == *p) { - /* New format - Little endian octet string */ - unsigned char rev_buf[32]; - int i; - ASN1_OCTET_STRING *s = d2i_ASN1_OCTET_STRING(NULL, &p, priv_len); - if (!s || s->length != 32) { - GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); - return 0; - } - for (i = 0; i < 32; i++) { - rev_buf[31 - i] = s->data[i]; - } - ASN1_STRING_free(s); - pk_num = getbnfrombuf(rev_buf, 32); - } else { - priv_key = d2i_ASN1_INTEGER(NULL, &p, priv_len); - if (!priv_key) - return 0; - ret = ((pk_num = ASN1_INTEGER_to_BN(priv_key, NULL)) != NULL); - ASN1_INTEGER_free(priv_key); - if (!ret) { - GOSTerr(GOST_F_PRIV_DECODE_GOST, EVP_R_DECODE_ERROR); - return 0; - } - } - - ret = gost_set_priv_key(pk, pk_num); - BN_free(pk_num); - return ret; -} - -/* ----------------------------------------------------------------------*/ -static int priv_encode_gost(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk) -{ - ASN1_OBJECT *algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); - ASN1_STRING *params = encode_gost_algor_params(pk); - unsigned char *priv_buf = NULL; - int priv_len; - - ASN1_INTEGER *asn1key = NULL; - if (!params) { - return 0; - } - asn1key = BN_to_ASN1_INTEGER(gost_get0_priv_key(pk), NULL); - priv_len = i2d_ASN1_INTEGER(asn1key, &priv_buf); - ASN1_INTEGER_free(asn1key); - return PKCS8_pkey_set0(p8, algobj, 0, V_ASN1_SEQUENCE, params, - priv_buf, priv_len); -} - -/* --------- printing keys --------------------------------*/ -static int print_gost_94(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx, int type) -{ - int param_nid = NID_undef; - - if (type == 2) { - BIGNUM *key; - - if (!BIO_indent(out, indent, 128)) - return 0; - BIO_printf(out, "Private key: "); - key = gost_get0_priv_key(pkey); - if (!key) - BIO_printf(out, ""); - else - BN_print(out, key); - BIO_printf(out, "\n"); - } - if (type >= 1) { - BIGNUM *pubkey; - - pubkey = ((DSA *)EVP_PKEY_get0((EVP_PKEY *)pkey))->pub_key; - BIO_indent(out, indent, 128); - BIO_printf(out, "Public key: "); - BN_print(out, pubkey); - BIO_printf(out, "\n"); - } - - param_nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); - BIO_indent(out, indent, 128); - BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); - return 1; -} - -static int param_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) -{ - return print_gost_94(out, pkey, indent, pctx, 0); -} - -static int pub_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) -{ - return print_gost_94(out, pkey, indent, pctx, 1); -} - -static int priv_print_gost94(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) -{ - return print_gost_94(out, pkey, indent, pctx, 2); -} - -static int print_gost_01(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx, int type) -{ - int param_nid = NID_undef; - if (type == 2) { - BIGNUM *key; - - if (!BIO_indent(out, indent, 128)) - return 0; - BIO_printf(out, "Private key: "); - key = gost_get0_priv_key(pkey); - if (!key) - BIO_printf(out, "= 1) { - BN_CTX *ctx = BN_CTX_new(); - BIGNUM *X, *Y; - const EC_POINT *pubkey; - const EC_GROUP *group; - - if (!ctx) { - GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_MALLOC_FAILURE); - return 0; - } - BN_CTX_start(ctx); - X = BN_CTX_get(ctx); - Y = BN_CTX_get(ctx); - pubkey = - EC_KEY_get0_public_key((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); - group = EC_KEY_get0_group((EC_KEY *)EVP_PKEY_get0((EVP_PKEY *)pkey)); - if (!EC_POINT_get_affine_coordinates_GFp(group, pubkey, X, Y, ctx)) { - GOSTerr(GOST_F_PRINT_GOST_01, ERR_R_EC_LIB); - BN_CTX_free(ctx); - return 0; - } - if (!BIO_indent(out, indent, 128)) - return 0; - BIO_printf(out, "Public key:\n"); - if (!BIO_indent(out, indent + 3, 128)) - return 0; - BIO_printf(out, "X:"); - BN_print(out, X); - BIO_printf(out, "\n"); - BIO_indent(out, indent + 3, 128); - BIO_printf(out, "Y:"); - BN_print(out, Y); - BIO_printf(out, "\n"); - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - - param_nid = - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)pkey))); - if (!BIO_indent(out, indent, 128)) - return 0; - BIO_printf(out, "Parameter set: %s\n", OBJ_nid2ln(param_nid)); - return 1; -} - -static int param_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) -{ - return print_gost_01(out, pkey, indent, pctx, 0); -} - -static int pub_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) -{ - return print_gost_01(out, pkey, indent, pctx, 1); -} - -static int priv_print_gost01(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx) -{ - return print_gost_01(out, pkey, indent, pctx, 2); -} - -/* ---------------------------------------------------------------------*/ -static int param_missing_gost94(const EVP_PKEY *pk) -{ - const DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); - if (!dsa) - return 1; - if (!dsa->q) - return 1; - return 0; -} - -static int param_missing_gost01(const EVP_PKEY *pk) -{ - const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); - if (!ec) - return 1; - if (!EC_KEY_get0_group(ec)) - return 1; - return 0; -} - -static int param_copy_gost94(EVP_PKEY *to, const EVP_PKEY *from) -{ - const DSA *dfrom = EVP_PKEY_get0((EVP_PKEY *)from); - DSA *dto = EVP_PKEY_get0(to); - if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { - GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_INCOMPATIBLE_ALGORITHMS); - return 0; - } - if (!dfrom) { - GOSTerr(GOST_F_PARAM_COPY_GOST94, GOST_R_KEY_PARAMETERS_MISSING); - return 0; - } - if (!dto) { - dto = DSA_new(); - EVP_PKEY_assign(to, EVP_PKEY_base_id(from), dto); - } -#define COPYBIGNUM(a,b,x) if (a->x) BN_free(a->x); a->x=BN_dup(b->x); - COPYBIGNUM(dto, dfrom, p) - COPYBIGNUM(dto, dfrom, q) - COPYBIGNUM(dto, dfrom, g) - - if (dto->priv_key) - gost94_compute_public(dto); - return 1; -} - -static int param_copy_gost01(EVP_PKEY *to, const EVP_PKEY *from) -{ - EC_KEY *eto = EVP_PKEY_get0(to); - const EC_KEY *efrom = EVP_PKEY_get0((EVP_PKEY *)from); - if (EVP_PKEY_base_id(from) != EVP_PKEY_base_id(to)) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_INCOMPATIBLE_ALGORITHMS); - return 0; - } - if (!efrom) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, GOST_R_KEY_PARAMETERS_MISSING); - return 0; - } - if (!eto) { - eto = EC_KEY_new(); - if(!eto) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_MALLOC_FAILURE); - return 0; - } - if(!EVP_PKEY_assign(to, EVP_PKEY_base_id(from), eto)) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); - return 0; - } - } - if(!EC_KEY_set_group(eto, EC_KEY_get0_group(efrom))) { - GOSTerr(GOST_F_PARAM_COPY_GOST01, ERR_R_INTERNAL_ERROR); - return 0; - } - if (EC_KEY_get0_private_key(eto)) { - gost2001_compute_public(eto); - } - return 1; -} - -static int param_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) -{ - const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); - const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); - if (!BN_cmp(da->q, db->q)) - return 1; - return 0; -} - -static int param_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) -{ - if (EC_GROUP_get_curve_name - (EC_KEY_get0_group(EVP_PKEY_get0((EVP_PKEY *)a))) == - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)b)))) { - return 1; - } - return 0; - -} - -/* ---------- Public key functions * --------------------------------------*/ -static int pub_decode_gost94(EVP_PKEY *pk, X509_PUBKEY *pub) -{ - X509_ALGOR *palg = NULL; - const unsigned char *pubkey_buf = NULL; - unsigned char *databuf; - ASN1_OBJECT *palgobj = NULL; - int pub_len, i, j; - DSA *dsa; - ASN1_OCTET_STRING *octet = NULL; - - if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) - return 0; - EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); - if (!decode_gost_algor_params(pk, palg)) - return 0; - octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); - if (!octet) { - GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); - return 0; - } - databuf = OPENSSL_malloc(octet->length); - if (databuf == NULL) { - GOSTerr(GOST_F_PUB_DECODE_GOST94, ERR_R_MALLOC_FAILURE); - return 0; - } - for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { - databuf[j] = octet->data[i]; - } - dsa = EVP_PKEY_get0(pk); - dsa->pub_key = BN_bin2bn(databuf, octet->length, NULL); - ASN1_OCTET_STRING_free(octet); - OPENSSL_free(databuf); - return 1; - -} - -static int pub_encode_gost94(X509_PUBKEY *pub, const EVP_PKEY *pk) -{ - ASN1_OBJECT *algobj = NULL; - ASN1_OCTET_STRING *octet = NULL; - void *pval = NULL; - unsigned char *buf = NULL, *databuf, *sptr; - int i, j, data_len, ret = 0; - - int ptype = V_ASN1_UNDEF; - DSA *dsa = EVP_PKEY_get0((EVP_PKEY *)pk); - algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); - if (pk->save_parameters) { - ASN1_STRING *params = encode_gost_algor_params(pk); - pval = params; - ptype = V_ASN1_SEQUENCE; - } - data_len = BN_num_bytes(dsa->pub_key); - databuf = OPENSSL_malloc(data_len); - if (databuf == NULL) - return 0; - BN_bn2bin(dsa->pub_key, databuf); - octet = ASN1_OCTET_STRING_new(); - ASN1_STRING_set(octet, NULL, data_len); - sptr = ASN1_STRING_data(octet); - for (i = 0, j = data_len - 1; i < data_len; i++, j--) { - sptr[i] = databuf[j]; - } - OPENSSL_free(databuf); - ret = i2d_ASN1_OCTET_STRING(octet, &buf); - ASN1_BIT_STRING_free(octet); - if (ret < 0) - return 0; - return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); -} - -static int pub_decode_gost01(EVP_PKEY *pk, X509_PUBKEY *pub) -{ - X509_ALGOR *palg = NULL; - const unsigned char *pubkey_buf = NULL; - unsigned char *databuf; - ASN1_OBJECT *palgobj = NULL; - int pub_len, i, j; - EC_POINT *pub_key; - BIGNUM *X, *Y; - ASN1_OCTET_STRING *octet = NULL; - int len; - const EC_GROUP *group; - - if (!X509_PUBKEY_get0_param(&palgobj, &pubkey_buf, &pub_len, &palg, pub)) - return 0; - EVP_PKEY_assign(pk, OBJ_obj2nid(palgobj), NULL); - if (!decode_gost_algor_params(pk, palg)) - return 0; - group = EC_KEY_get0_group(EVP_PKEY_get0(pk)); - octet = d2i_ASN1_OCTET_STRING(NULL, &pubkey_buf, pub_len); - if (!octet) { - GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); - return 0; - } - databuf = OPENSSL_malloc(octet->length); - if (databuf == NULL) { - GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_MALLOC_FAILURE); - return 0; - } - for (i = 0, j = octet->length - 1; i < octet->length; i++, j--) { - databuf[j] = octet->data[i]; - } - len = octet->length / 2; - ASN1_OCTET_STRING_free(octet); - - Y = getbnfrombuf(databuf, len); - X = getbnfrombuf(databuf + len, len); - OPENSSL_free(databuf); - pub_key = EC_POINT_new(group); - if (!EC_POINT_set_affine_coordinates_GFp(group, pub_key, X, Y, NULL)) { - GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); - EC_POINT_free(pub_key); - BN_free(X); - BN_free(Y); - return 0; - } - BN_free(X); - BN_free(Y); - if (!EC_KEY_set_public_key(EVP_PKEY_get0(pk), pub_key)) { - GOSTerr(GOST_F_PUB_DECODE_GOST01, ERR_R_EC_LIB); - EC_POINT_free(pub_key); - return 0; - } - EC_POINT_free(pub_key); - return 1; - -} - -static int pub_encode_gost01(X509_PUBKEY *pub, const EVP_PKEY *pk) -{ - ASN1_OBJECT *algobj = NULL; - ASN1_OCTET_STRING *octet = NULL; - void *pval = NULL; - unsigned char *buf = NULL, *databuf, *sptr; - int i, j, data_len, ret = 0; - const EC_POINT *pub_key; - BIGNUM *X, *Y, *order; - const EC_KEY *ec = EVP_PKEY_get0((EVP_PKEY *)pk); - int ptype = V_ASN1_UNDEF; - - algobj = OBJ_nid2obj(EVP_PKEY_base_id(pk)); - if (pk->save_parameters) { - ASN1_STRING *params = encode_gost_algor_params(pk); - pval = params; - ptype = V_ASN1_SEQUENCE; - } - order = BN_new(); - EC_GROUP_get_order(EC_KEY_get0_group(ec), order, NULL); - pub_key = EC_KEY_get0_public_key(ec); - if (!pub_key) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, GOST_R_PUBLIC_KEY_UNDEFINED); - return 0; - } - X = BN_new(); - Y = BN_new(); - if(!X || !Y) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); - if(X) BN_free(X); - if(Y) BN_free(Y); - BN_free(order); - return 0; - } - if(!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec), - pub_key, X, Y, NULL)) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_INTERNAL_ERROR); - BN_free(X); - BN_free(Y); - BN_free(order); - return 0; - } - data_len = 2 * BN_num_bytes(order); - BN_free(order); - databuf = OPENSSL_malloc(data_len); - if (databuf == NULL) { - GOSTerr(GOST_F_PUB_ENCODE_GOST01, ERR_R_MALLOC_FAILURE); - return 0; - } - memset(databuf, 0, data_len); - - store_bignum(X, databuf + data_len / 2, data_len / 2); - store_bignum(Y, databuf, data_len / 2); - - BN_free(X); - BN_free(Y); - octet = ASN1_OCTET_STRING_new(); - ASN1_STRING_set(octet, NULL, data_len); - sptr = ASN1_STRING_data(octet); - for (i = 0, j = data_len - 1; i < data_len; i++, j--) { - sptr[i] = databuf[j]; - } - OPENSSL_free(databuf); - ret = i2d_ASN1_OCTET_STRING(octet, &buf); - ASN1_BIT_STRING_free(octet); - if (ret < 0) - return 0; - return X509_PUBKEY_set0_param(pub, algobj, ptype, pval, buf, ret); -} - -static int pub_cmp_gost94(const EVP_PKEY *a, const EVP_PKEY *b) -{ - const DSA *da = EVP_PKEY_get0((EVP_PKEY *)a); - const DSA *db = EVP_PKEY_get0((EVP_PKEY *)b); - if (da && db && da->pub_key && db->pub_key - && !BN_cmp(da->pub_key, db->pub_key)) { - return 1; - } - return 0; -} - -static int pub_cmp_gost01(const EVP_PKEY *a, const EVP_PKEY *b) -{ - const EC_KEY *ea = EVP_PKEY_get0((EVP_PKEY *)a); - const EC_KEY *eb = EVP_PKEY_get0((EVP_PKEY *)b); - const EC_POINT *ka, *kb; - int ret = 0; - if (!ea || !eb) - return 0; - ka = EC_KEY_get0_public_key(ea); - kb = EC_KEY_get0_public_key(eb); - if (!ka || !kb) - return 0; - ret = (0 == EC_POINT_cmp(EC_KEY_get0_group(ea), ka, kb, NULL)); - return ret; -} - -static int pkey_size_gost(const EVP_PKEY *pk) -{ - return 64; -} - -static int pkey_bits_gost(const EVP_PKEY *pk) -{ - return 256; -} - -/* ---------------------- ASN1 METHOD for GOST MAC -------------------*/ -static void mackey_free_gost(EVP_PKEY *pk) -{ - if (pk->pkey.ptr) { - OPENSSL_free(pk->pkey.ptr); - } -} - -static int mac_ctrl_gost(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - switch (op) { - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_id_Gost28147_89_MAC; - return 2; - } - return -2; -} - -static int gost94_param_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - int nid = gost94_nid_by_params(EVP_PKEY_get0((EVP_PKEY *)pkey)); - return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); -} - -static int gost2001_param_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - int nid = - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)pkey))); - return i2d_ASN1_OBJECT(OBJ_nid2obj(nid), pder); -} - -static int gost94_param_decode(EVP_PKEY *pkey, const unsigned char **pder, - int derlen) -{ - ASN1_OBJECT *obj = NULL; - DSA *dsa = EVP_PKEY_get0(pkey); - int nid; - if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { - return 0; - } - nid = OBJ_obj2nid(obj); - ASN1_OBJECT_free(obj); - if (!dsa) { - dsa = DSA_new(); - if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa)) - return 0; - } - if (!fill_GOST94_params(dsa, nid)) - return 0; - return 1; -} - -static int gost2001_param_decode(EVP_PKEY *pkey, const unsigned char **pder, - int derlen) -{ - ASN1_OBJECT *obj = NULL; - int nid; - EC_KEY *ec = EVP_PKEY_get0(pkey); - if (d2i_ASN1_OBJECT(&obj, pder, derlen) == NULL) { - return 0; - } - nid = OBJ_obj2nid(obj); - ASN1_OBJECT_free(obj); - if (!ec) { - ec = EC_KEY_new(); - if (!EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec)) - return 0; - } - if (!fill_GOST2001_params(ec, nid)) - return 0; - return 1; -} - -/* ----------------------------------------------------------------------*/ -int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, - const char *pemstr, const char *info) -{ - *ameth = EVP_PKEY_asn1_new(nid, ASN1_PKEY_SIGPARAM_NULL, pemstr, info); - if (!*ameth) - return 0; - switch (nid) { - case NID_id_GostR3410_94: - EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost94); - EVP_PKEY_asn1_set_private(*ameth, - priv_decode_gost, priv_encode_gost, - priv_print_gost94); - - EVP_PKEY_asn1_set_param(*ameth, - gost94_param_decode, gost94_param_encode, - param_missing_gost94, param_copy_gost94, - param_cmp_gost94, param_print_gost94); - EVP_PKEY_asn1_set_public(*ameth, - pub_decode_gost94, pub_encode_gost94, - pub_cmp_gost94, pub_print_gost94, - pkey_size_gost, pkey_bits_gost); - - EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); - break; - case NID_id_GostR3410_2001: - EVP_PKEY_asn1_set_free(*ameth, pkey_free_gost01); - EVP_PKEY_asn1_set_private(*ameth, - priv_decode_gost, priv_encode_gost, - priv_print_gost01); - - EVP_PKEY_asn1_set_param(*ameth, - gost2001_param_decode, gost2001_param_encode, - param_missing_gost01, param_copy_gost01, - param_cmp_gost01, param_print_gost01); - EVP_PKEY_asn1_set_public(*ameth, - pub_decode_gost01, pub_encode_gost01, - pub_cmp_gost01, pub_print_gost01, - pkey_size_gost, pkey_bits_gost); - - EVP_PKEY_asn1_set_ctrl(*ameth, pkey_ctrl_gost); - break; - case NID_id_Gost28147_89_MAC: - EVP_PKEY_asn1_set_free(*ameth, mackey_free_gost); - EVP_PKEY_asn1_set_ctrl(*ameth, mac_ctrl_gost); - break; - } - return 1; -} -/********************************************************************** - * gost_keytrans.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * ASN1 structure definition for GOST key transport * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include -#include "asn1t.h" -#include "x509.h" -// #include "gost_lcl.h" - -ASN1_NDEF_SEQUENCE(GOST_KEY_TRANSPORT) = { - ASN1_SIMPLE(GOST_KEY_TRANSPORT, key_info, GOST_KEY_INFO), - ASN1_IMP(GOST_KEY_TRANSPORT, key_agreement_info, GOST_KEY_AGREEMENT_INFO, 0) -} ASN1_NDEF_SEQUENCE_END(GOST_KEY_TRANSPORT) - -IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) - -ASN1_NDEF_SEQUENCE(GOST_KEY_INFO) = { - ASN1_SIMPLE(GOST_KEY_INFO, encrypted_key, ASN1_OCTET_STRING), - ASN1_SIMPLE(GOST_KEY_INFO, imit, ASN1_OCTET_STRING) -} ASN1_NDEF_SEQUENCE_END(GOST_KEY_INFO) - -IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_INFO) - -ASN1_NDEF_SEQUENCE(GOST_KEY_AGREEMENT_INFO) = { - ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, cipher, ASN1_OBJECT), - ASN1_IMP_OPT(GOST_KEY_AGREEMENT_INFO, ephem_key, X509_PUBKEY, 0), - ASN1_SIMPLE(GOST_KEY_AGREEMENT_INFO, eph_iv, ASN1_OCTET_STRING) -} ASN1_NDEF_SEQUENCE_END(GOST_KEY_AGREEMENT_INFO) - -IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) - -ASN1_NDEF_SEQUENCE(GOST_KEY_PARAMS) = { - ASN1_SIMPLE(GOST_KEY_PARAMS, key_params, ASN1_OBJECT), - ASN1_SIMPLE(GOST_KEY_PARAMS, hash_params, ASN1_OBJECT), - ASN1_OPT(GOST_KEY_PARAMS, cipher_params, ASN1_OBJECT), -} ASN1_NDEF_SEQUENCE_END(GOST_KEY_PARAMS) - -IMPLEMENT_ASN1_FUNCTIONS(GOST_KEY_PARAMS) - -ASN1_NDEF_SEQUENCE(GOST_CIPHER_PARAMS) = { - ASN1_SIMPLE(GOST_CIPHER_PARAMS, iv, ASN1_OCTET_STRING), - ASN1_SIMPLE(GOST_CIPHER_PARAMS, enc_param_set, ASN1_OBJECT), -} ASN1_NDEF_SEQUENCE_END(GOST_CIPHER_PARAMS) - -IMPLEMENT_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) - -ASN1_NDEF_SEQUENCE(GOST_CLIENT_KEY_EXCHANGE_PARAMS) = { /* FIXME incomplete */ - ASN1_SIMPLE(GOST_CLIENT_KEY_EXCHANGE_PARAMS, gkt, GOST_KEY_TRANSPORT) -} - -ASN1_NDEF_SEQUENCE_END(GOST_CLIENT_KEY_EXCHANGE_PARAMS) -IMPLEMENT_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) -/********************************************************************** - * gost_crypt.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * OpenSSL interface to GOST 28147-89 cipher functions * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include -#include "gost89.h" -#include "rand.h" -// #include "e_gost_err.h" -// #include "gost_lcl.h" - -#if !defined(CCGOST_DEBUG) && !defined(DEBUG) -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -static int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc); -/* Handles block of data in CFB mode */ -static int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -/* Handles block of data in CNT mode */ -static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl); -/* Cleanup function */ -static int gost_cipher_cleanup(EVP_CIPHER_CTX *); -/* set/get cipher parameters */ -static int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params); -static int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params); -/* Control function */ -static int gost_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); - -EVP_CIPHER cipher_gost = { - NID_id_Gost28147_89, - 1, /* block_size */ - 32, /* key_size */ - 8, /* iv_len */ - EVP_CIPH_CFB_MODE | EVP_CIPH_NO_PADDING | - EVP_CIPH_CUSTOM_IV | EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, - gost_cipher_init, - gost_cipher_do_cfb, - gost_cipher_cleanup, - sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ - gost89_set_asn1_parameters, - gost89_get_asn1_parameters, - gost_cipher_ctl, - NULL, -}; - -EVP_CIPHER cipher_gost_cpacnt = { - NID_gost89_cnt, - 1, /* block_size */ - 32, /* key_size */ - 8, /* iv_len */ - EVP_CIPH_OFB_MODE | EVP_CIPH_NO_PADDING | - EVP_CIPH_CUSTOM_IV | EVP_CIPH_RAND_KEY | EVP_CIPH_ALWAYS_CALL_INIT, - gost_cipher_init_cpa, - gost_cipher_do_cnt, - gost_cipher_cleanup, - sizeof(struct ossl_gost_cipher_ctx), /* ctx_size */ - gost89_set_asn1_parameters, - gost89_get_asn1_parameters, - gost_cipher_ctl, - NULL, -}; - -/* Implementation of GOST 28147-89 in MAC (imitovstavka) mode */ -/* Init functions which set specific parameters */ -static int gost_imit_init_cpa(EVP_MD_CTX *ctx); -/* process block of data */ -static int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count); -/* Return computed value */ -static int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md); -/* Copies context */ -static int gost_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); -static int gost_imit_cleanup(EVP_MD_CTX *ctx); -/* Control function, knows how to set MAC key.*/ -static int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr); - -EVP_MD imit_gost_cpa = { - NID_id_Gost28147_89_MAC, - NID_undef, - 4, - 0, - gost_imit_init_cpa, - gost_imit_update, - gost_imit_final, - gost_imit_copy, - gost_imit_cleanup, - NULL, - NULL, - {0, 0, 0, 0, 0}, - 8, - sizeof(struct ossl_gost_imit_ctx), - gost_imit_ctrl -}; - -/* - * Correspondence between gost parameter OIDs and substitution blocks - * NID field is filed by register_gost_NID function in engine.c - * upon engine initialization - */ - -struct gost_cipher_info gost_cipher_list[] = { - /*- NID *//* - * Subst block - *//* - * Key meshing - */ - /* - * {NID_id_GostR3411_94_CryptoProParamSet,&GostR3411_94_CryptoProParamSet,0}, - */ - {NID_id_Gost28147_89_cc, &GostR3411_94_CryptoProParamSet, 0}, - {NID_id_Gost28147_89_CryptoPro_A_ParamSet, &Gost28147_CryptoProParamSetA, - 1}, - {NID_id_Gost28147_89_CryptoPro_B_ParamSet, &Gost28147_CryptoProParamSetB, - 1}, - {NID_id_Gost28147_89_CryptoPro_C_ParamSet, &Gost28147_CryptoProParamSetC, - 1}, - {NID_id_Gost28147_89_CryptoPro_D_ParamSet, &Gost28147_CryptoProParamSetD, - 1}, - {NID_id_Gost28147_89_TestParamSet, &Gost28147_TestParamSet, 1}, - {NID_undef, NULL, 0} -}; - -/* - * get encryption parameters from crypto network settings FIXME For now we - * use environment var CRYPT_PARAMS as place to store these settings. - * Actually, it is better to use engine control command, read from - * configuration file to set them - */ -const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj) -{ - int nid; - struct gost_cipher_info *param; - if (!obj) { - const char *params = get_gost_engine_param(GOST_PARAM_CRYPT_PARAMS); - if (!params || !strlen(params)) - return &gost_cipher_list[1]; - - nid = OBJ_txt2nid(params); - if (nid == NID_undef) { - GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS, - GOST_R_INVALID_CIPHER_PARAM_OID); - return NULL; - } - } else { - nid = OBJ_obj2nid(obj); - } - for (param = gost_cipher_list; param->sblock != NULL && param->nid != nid; - param++) ; - if (!param->sblock) { - GOSTerr(GOST_F_GET_ENCRYPTION_PARAMS, GOST_R_INVALID_CIPHER_PARAMS); - return NULL; - } - return param; -} - -/* Sets cipher param from paramset NID. */ -static int gost_cipher_set_param(struct ossl_gost_cipher_ctx *c, int nid) -{ - const struct gost_cipher_info *param; - param = - get_encryption_params((nid == NID_undef ? NULL : OBJ_nid2obj(nid))); - if (!param) - return 0; - - c->paramNID = param->nid; - c->key_meshing = param->key_meshing; - c->count = 0; - gost_init(&(c->cctx), param->sblock); - return 1; -} - -/* Initializes EVP_CIPHER_CTX by paramset NID */ -static int gost_cipher_init_param(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, int enc, - int paramNID, int mode) -{ - struct ossl_gost_cipher_ctx *c = ctx->cipher_data; - if (ctx->app_data == NULL) { - if (!gost_cipher_set_param(c, paramNID)) - return 0; - ctx->app_data = ctx->cipher_data; - } - if (key) - gost_key(&(c->cctx), key); - if (iv) - memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); - memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); - return 1; -} - -static int gost_cipher_init_cpa(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - struct ossl_gost_cipher_ctx *c = ctx->cipher_data; - gost_init(&(c->cctx), &Gost28147_CryptoProParamSetA); - c->key_meshing = 1; - c->count = 0; - if (key) - gost_key(&(c->cctx), key); - if (iv) - memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); - memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); - return 1; -} - -/* Initializes EVP_CIPHER_CTX with default values */ -int gost_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, - const unsigned char *iv, int enc) -{ - return gost_cipher_init_param(ctx, key, iv, enc, NID_undef, - EVP_CIPH_CFB_MODE); -} - -/* - * Wrapper around gostcrypt function from gost89.c which perform key meshing - * when nesseccary - */ -static void gost_crypt_mesh(void *ctx, unsigned char *iv, unsigned char *buf) -{ - struct ossl_gost_cipher_ctx *c = ctx; - assert(c->count % 8 == 0 && c->count <= 1024); - if (c->key_meshing && c->count == 1024) { - cryptopro_key_meshing(&(c->cctx), iv); - } - gostcrypt(&(c->cctx), iv, buf); - c->count = c->count % 1024 + 8; -} - -static void gost_cnt_next(void *ctx, unsigned char *iv, unsigned char *buf) -{ - struct ossl_gost_cipher_ctx *c = ctx; - word32 g, go; - unsigned char buf1[8]; - assert(c->count % 8 == 0 && c->count <= 1024); - if (c->key_meshing && c->count == 1024) { - cryptopro_key_meshing(&(c->cctx), iv); - } - if (c->count == 0) { - gostcrypt(&(c->cctx), iv, buf1); - } else { - memcpy(buf1, iv, 8); - } - g = buf1[0] | (buf1[1] << 8) | (buf1[2] << 16) | ((word32) buf1[3] << 24); - g += 0x01010101; - buf1[0] = (unsigned char)(g & 0xff); - buf1[1] = (unsigned char)((g >> 8) & 0xff); - buf1[2] = (unsigned char)((g >> 16) & 0xff); - buf1[3] = (unsigned char)((g >> 24) & 0xff); - g = buf1[4] | (buf1[5] << 8) | (buf1[6] << 16) | ((word32) buf1[7] << 24); - go = g; - g += 0x01010104; - if (go > g) /* overflow */ - g++; - buf1[4] = (unsigned char)(g & 0xff); - buf1[5] = (unsigned char)((g >> 8) & 0xff); - buf1[6] = (unsigned char)((g >> 16) & 0xff); - buf1[7] = (unsigned char)((g >> 24) & 0xff); - memcpy(iv, buf1, 8); - gostcrypt(&(c->cctx), buf1, buf); - c->count = c->count % 1024 + 8; -} - -/* GOST encryption in CFB mode */ -int gost_cipher_do_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - const unsigned char *in_ptr = in; - unsigned char *out_ptr = out; - size_t i = 0; - size_t j = 0; -/* process partial block if any */ - if (ctx->num) { - for (j = ctx->num, i = 0; j < 8 && i < inl; - j++, i++, in_ptr++, out_ptr++) { - if (!ctx->encrypt) - ctx->buf[j + 8] = *in_ptr; - *out_ptr = ctx->buf[j] ^ (*in_ptr); - if (ctx->encrypt) - ctx->buf[j + 8] = *out_ptr; - } - if (j == 8) { - memcpy(ctx->iv, ctx->buf + 8, 8); - ctx->num = 0; - } else { - ctx->num = j; - return 1; - } - } - - for (; i + 8 < inl; i += 8, in_ptr += 8, out_ptr += 8) { - /* - * block cipher current iv - */ - gost_crypt_mesh(ctx->cipher_data, ctx->iv, ctx->buf); - /* - * xor next block of input text with it and output it - */ - /* - * output this block - */ - if (!ctx->encrypt) - memcpy(ctx->iv, in_ptr, 8); - for (j = 0; j < 8; j++) { - out_ptr[j] = ctx->buf[j] ^ in_ptr[j]; - } - /* Encrypt */ - /* Next iv is next block of cipher text */ - if (ctx->encrypt) - memcpy(ctx->iv, out_ptr, 8); - } -/* Process rest of buffer */ - if (i < inl) { - gost_crypt_mesh(ctx->cipher_data, ctx->iv, ctx->buf); - if (!ctx->encrypt) - memcpy(ctx->buf + 8, in_ptr, inl - i); - for (j = 0; i < inl; j++, i++) { - out_ptr[j] = ctx->buf[j] ^ in_ptr[j]; - } - ctx->num = j; - if (ctx->encrypt) - memcpy(ctx->buf + 8, out_ptr, j); - } else { - ctx->num = 0; - } - return 1; -} - -static int gost_cipher_do_cnt(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t inl) -{ - const unsigned char *in_ptr = in; - unsigned char *out_ptr = out; - size_t i = 0; - size_t j; -/* process partial block if any */ - if (ctx->num) { - for (j = ctx->num, i = 0; j < 8 && i < inl; - j++, i++, in_ptr++, out_ptr++) { - *out_ptr = ctx->buf[j] ^ (*in_ptr); - } - if (j == 8) { - ctx->num = 0; - } else { - ctx->num = j; - return 1; - } - } - - for (; i + 8 < inl; i += 8, in_ptr += 8, out_ptr += 8) { - /* - * block cipher current iv - */ - /* Encrypt */ - gost_cnt_next(ctx->cipher_data, ctx->iv, ctx->buf); - /* - * xor next block of input text with it and output it - */ - /* - * output this block - */ - for (j = 0; j < 8; j++) { - out_ptr[j] = ctx->buf[j] ^ in_ptr[j]; - } - } -/* Process rest of buffer */ - if (i < inl) { - gost_cnt_next(ctx->cipher_data, ctx->iv, ctx->buf); - for (j = 0; i < inl; j++, i++) { - out_ptr[j] = ctx->buf[j] ^ in_ptr[j]; - } - ctx->num = j; - } else { - ctx->num = 0; - } - return 1; -} - -/* Cleaning up of EVP_CIPHER_CTX */ -int gost_cipher_cleanup(EVP_CIPHER_CTX *ctx) -{ - gost_destroy(&((struct ossl_gost_cipher_ctx *)ctx->cipher_data)->cctx); - ctx->app_data = NULL; - return 1; -} - -/* Control function for gost cipher */ -int gost_cipher_ctl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) -{ - switch (type) { - case EVP_CTRL_RAND_KEY: - { - if (RAND_bytes((unsigned char *)ptr, ctx->key_len) <= 0) { - GOSTerr(GOST_F_GOST_CIPHER_CTL, - GOST_R_RANDOM_GENERATOR_ERROR); - return -1; - } - break; - } - case EVP_CTRL_PBE_PRF_NID: - if (ptr) { - *((int *)ptr) = NID_id_HMACGostR3411_94; - return 1; - } else { - return 0; - } - - default: - GOSTerr(GOST_F_GOST_CIPHER_CTL, - GOST_R_UNSUPPORTED_CIPHER_CTL_COMMAND); - return -1; - } - return 1; -} - -/* Set cipher parameters from ASN1 structure */ -int gost89_set_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) -{ - int len = 0; - unsigned char *buf = NULL; - unsigned char *p = NULL; - struct ossl_gost_cipher_ctx *c = ctx->cipher_data; - GOST_CIPHER_PARAMS *gcp = GOST_CIPHER_PARAMS_new(); - ASN1_OCTET_STRING *os = NULL; - if (!gcp) { - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); - return 0; - } - if (!ASN1_OCTET_STRING_set(gcp->iv, ctx->iv, ctx->cipher->iv_len)) { - GOST_CIPHER_PARAMS_free(gcp); - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); - return 0; - } - ASN1_OBJECT_free(gcp->enc_param_set); - gcp->enc_param_set = OBJ_nid2obj(c->paramNID); - - len = i2d_GOST_CIPHER_PARAMS(gcp, NULL); - p = buf = (unsigned char *)OPENSSL_malloc(len); - if (!buf) { - GOST_CIPHER_PARAMS_free(gcp); - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); - return 0; - } - i2d_GOST_CIPHER_PARAMS(gcp, &p); - GOST_CIPHER_PARAMS_free(gcp); - - os = ASN1_OCTET_STRING_new(); - - if (!os || !ASN1_OCTET_STRING_set(os, buf, len)) { - OPENSSL_free(buf); - GOSTerr(GOST_F_GOST89_SET_ASN1_PARAMETERS, GOST_R_NO_MEMORY); - return 0; - } - OPENSSL_free(buf); - - ASN1_TYPE_set(params, V_ASN1_SEQUENCE, os); - return 1; -} - -/* Store parameters into ASN1 structure */ -int gost89_get_asn1_parameters(EVP_CIPHER_CTX *ctx, ASN1_TYPE *params) -{ - int ret = -1; - int len; - GOST_CIPHER_PARAMS *gcp = NULL; - unsigned char *p; - struct ossl_gost_cipher_ctx *c = ctx->cipher_data; - if (ASN1_TYPE_get(params) != V_ASN1_SEQUENCE) { - return ret; - } - - p = params->value.sequence->data; - - gcp = d2i_GOST_CIPHER_PARAMS(NULL, (const unsigned char **)&p, - params->value.sequence->length); - - len = gcp->iv->length; - if (len != ctx->cipher->iv_len) { - GOST_CIPHER_PARAMS_free(gcp); - GOSTerr(GOST_F_GOST89_GET_ASN1_PARAMETERS, GOST_R_INVALID_IV_LENGTH); - return -1; - } - if (!gost_cipher_set_param(c, OBJ_obj2nid(gcp->enc_param_set))) { - GOST_CIPHER_PARAMS_free(gcp); - return -1; - } - memcpy(ctx->oiv, gcp->iv->data, len); - - GOST_CIPHER_PARAMS_free(gcp); - - return 1; -} - -int gost_imit_init_cpa(EVP_MD_CTX *ctx) -{ - struct ossl_gost_imit_ctx *c = ctx->md_data; - memset(c->buffer, 0, sizeof(c->buffer)); - memset(c->partial_block, 0, sizeof(c->partial_block)); - c->count = 0; - c->bytes_left = 0; - c->key_meshing = 1; - gost_init(&(c->cctx), &Gost28147_CryptoProParamSetA); - return 1; -} - -static void mac_block_mesh(struct ossl_gost_imit_ctx *c, - const unsigned char *data) -{ - unsigned char buffer[8]; - /* - * We are using local buffer for iv because CryptoPro doesn't interpret - * internal state of MAC algorithm as iv during keymeshing (but does - * initialize internal state from iv in key transport - */ - assert(c->count % 8 == 0 && c->count <= 1024); - if (c->key_meshing && c->count == 1024) { - cryptopro_key_meshing(&(c->cctx), buffer); - } - mac_block(&(c->cctx), c->buffer, data); - c->count = c->count % 1024 + 8; -} - -int gost_imit_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - struct ossl_gost_imit_ctx *c = ctx->md_data; - const unsigned char *p = data; - size_t bytes = count, i; - if (!(c->key_set)) { - GOSTerr(GOST_F_GOST_IMIT_UPDATE, GOST_R_MAC_KEY_NOT_SET); - return 0; - } - if (c->bytes_left) { - for (i = c->bytes_left; i < 8 && bytes > 0; bytes--, i++, p++) { - c->partial_block[i] = *p; - } - if (i == 8) { - mac_block_mesh(c, c->partial_block); - } else { - c->bytes_left = i; - return 1; - } - } - while (bytes > 8) { - mac_block_mesh(c, p); - p += 8; - bytes -= 8; - } - if (bytes > 0) { - memcpy(c->partial_block, p, bytes); - } - c->bytes_left = bytes; - return 1; -} - -int gost_imit_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - struct ossl_gost_imit_ctx *c = ctx->md_data; - if (!c->key_set) { - GOSTerr(GOST_F_GOST_IMIT_FINAL, GOST_R_MAC_KEY_NOT_SET); - return 0; - } - if (c->count == 0 && c->bytes_left) { - unsigned char buffer[8]; - memset(buffer, 0, 8); - gost_imit_update(ctx, buffer, 8); - } - if (c->bytes_left) { - int i; - for (i = c->bytes_left; i < 8; i++) { - c->partial_block[i] = 0; - } - mac_block_mesh(c, c->partial_block); - } - get_mac(c->buffer, 32, md); - return 1; -} - -int gost_imit_ctrl(EVP_MD_CTX *ctx, int type, int arg, void *ptr) -{ - switch (type) { - case EVP_MD_CTRL_KEY_LEN: - *((unsigned int *)(ptr)) = 32; - return 1; - case EVP_MD_CTRL_SET_KEY: - { - if (arg != 32) { - GOSTerr(GOST_F_GOST_IMIT_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH); - return 0; - } - - gost_key(&(((struct ossl_gost_imit_ctx *)(ctx->md_data))->cctx), - ptr); - ((struct ossl_gost_imit_ctx *)(ctx->md_data))->key_set = 1; - return 1; - - } - default: - return 0; - } -} - -int gost_imit_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) -{ - memcpy(to->md_data, from->md_data, sizeof(struct ossl_gost_imit_ctx)); - return 1; -} - -/* Clean up imit ctx */ -int gost_imit_cleanup(EVP_MD_CTX *ctx) -{ - memset(ctx->md_data, 0, sizeof(struct ossl_gost_imit_ctx)); - return 1; -} -/********************************************************************** - * gost_ctl.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of control commands for GOST engine * - * OpenSSL 0.9.9 libraries required * - **********************************************************************/ -#include -#include -// #include "crypto.h" -// #include "err.h" -// #include "engine.h" -#include "buffer.h" -// #include "gost_lcl.h" - -static char *gost_params[GOST_PARAM_MAX + 1] = { NULL }; -static const char *gost_envnames[] = { "CRYPT_PARAMS" }; - -const ENGINE_CMD_DEFN gost_cmds[] = { -/*- { GOST_CTRL_RNG, - "RNG", - "Type of random number generator to use", - ENGINE_CMD_FLAG_STRING - }, - { GOST_CTRL_RNG_PARAMS, - "RNG_PARAMS", - "Parameter for random number generator", - ENGINE_CMD_FLAG_STRING - }, -*/ {GOST_CTRL_CRYPT_PARAMS, - "CRYPT_PARAMS", - "OID of default GOST 28147-89 parameters", - ENGINE_CMD_FLAG_STRING}, - {0, NULL, NULL, 0} -}; - -void gost_param_free() -{ - int i; - for (i = 0; i <= GOST_PARAM_MAX; i++) - if (gost_params[i] != NULL) { - OPENSSL_free(gost_params[i]); - gost_params[i] = NULL; - } - -} - -int gost_control_func(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) -{ - int param = cmd - ENGINE_CMD_BASE; - int ret = 0; - if (param < 0 || param > GOST_PARAM_MAX) - return -1; - ret = gost_set_default_param(param, p); - return ret; -} - -const char *get_gost_engine_param(int param) -{ - char *tmp; - if (param < 0 || param > GOST_PARAM_MAX) - return NULL; - if (gost_params[param] != NULL) { - return gost_params[param]; - } - tmp = getenv(gost_envnames[param]); - if (tmp) { - if (gost_params[param]) - OPENSSL_free(gost_params[param]); - gost_params[param] = BUF_strdup(tmp); - return gost_params[param]; - } - return NULL; -} - -int gost_set_default_param(int param, const char *value) -{ - const char *tmp; - if (param < 0 || param > GOST_PARAM_MAX) - return 0; - tmp = getenv(gost_envnames[param]); - /* - * if there is value in the environment, use it, else -passed string * - */ - if (!tmp) - tmp = value; - if (gost_params[param]) - OPENSSL_free(gost_params[param]); - gost_params[param] = BUF_strdup(tmp); - - return 1; -} -/********************************************************************** - * gost_eng.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Main file of GOST engine * - * for OpenSSL * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include -// #include "crypto.h" -// #include "err.h" -// #include "evp.h" -// #include "engine.h" -#include "obj_mac.h" -// #include "e_gost_err.h" -// #include "gost_lcl.h" -static const char *engine_gost_id = "gost"; -static const char *engine_gost_name = - "Reference implementation of GOST engine"; - -/* Symmetric cipher and digest function registrar */ - -static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid); - -static int gost_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int ind); - -static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, - const int **nids, int nid); - -static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, - const int **nids, int nid); - -static int gost_cipher_nids[] = { NID_id_Gost28147_89, NID_gost89_cnt, 0 }; - -static int gost_digest_nids[] = - { NID_id_GostR3411_94, NID_id_Gost28147_89_MAC, 0 }; - -static int gost_pkey_meth_nids[] = { NID_id_GostR3410_94, - NID_id_GostR3410_2001, NID_id_Gost28147_89_MAC, 0 -}; - -static EVP_PKEY_METHOD *pmeth_GostR3410_94 = NULL, - *pmeth_GostR3410_2001 = NULL, *pmeth_Gost28147_MAC = NULL; - -static EVP_PKEY_ASN1_METHOD *ameth_GostR3410_94 = NULL, - *ameth_GostR3410_2001 = NULL, *ameth_Gost28147_MAC = NULL; - -static int gost_engine_init(ENGINE *e) -{ - return 1; -} - -static int gost_engine_finish(ENGINE *e) -{ - return 1; -} - -static int gost_engine_destroy(ENGINE *e) -{ - gost_param_free(); - - pmeth_GostR3410_94 = NULL; - pmeth_GostR3410_2001 = NULL; - pmeth_Gost28147_MAC = NULL; - ameth_GostR3410_94 = NULL; - ameth_GostR3410_2001 = NULL; - ameth_Gost28147_MAC = NULL; - return 1; -} - -static int bind_gost(ENGINE *e, const char *id) -{ - int ret = 0; - if (id && strcmp(id, engine_gost_id)) - return 0; - if (ameth_GostR3410_94) { - printf("GOST engine already loaded\n"); - goto end; - } - - if (!ENGINE_set_id(e, engine_gost_id)) { - printf("ENGINE_set_id failed\n"); - goto end; - } - if (!ENGINE_set_name(e, engine_gost_name)) { - printf("ENGINE_set_name failed\n"); - goto end; - } - if (!ENGINE_set_digests(e, gost_digests)) { - printf("ENGINE_set_digests failed\n"); - goto end; - } - if (!ENGINE_set_ciphers(e, gost_ciphers)) { - printf("ENGINE_set_ciphers failed\n"); - goto end; - } - if (!ENGINE_set_pkey_meths(e, gost_pkey_meths)) { - printf("ENGINE_set_pkey_meths failed\n"); - goto end; - } - if (!ENGINE_set_pkey_asn1_meths(e, gost_pkey_asn1_meths)) { - printf("ENGINE_set_pkey_asn1_meths failed\n"); - goto end; - } - /* Control function and commands */ - if (!ENGINE_set_cmd_defns(e, gost_cmds)) { - fprintf(stderr, "ENGINE_set_cmd_defns failed\n"); - goto end; - } - if (!ENGINE_set_ctrl_function(e, gost_control_func)) { - fprintf(stderr, "ENGINE_set_ctrl_func failed\n"); - goto end; - } - if (!ENGINE_set_destroy_function(e, gost_engine_destroy) - || !ENGINE_set_init_function(e, gost_engine_init) - || !ENGINE_set_finish_function(e, gost_engine_finish)) { - goto end; - } - - if (!register_ameth_gost - (NID_id_GostR3410_94, &ameth_GostR3410_94, "GOST94", - "GOST R 34.10-94")) - goto end; - if (!register_ameth_gost - (NID_id_GostR3410_2001, &ameth_GostR3410_2001, "GOST2001", - "GOST R 34.10-2001")) - goto end; - if (!register_ameth_gost(NID_id_Gost28147_89_MAC, &ameth_Gost28147_MAC, - "GOST-MAC", "GOST 28147-89 MAC")) - goto end; - - if (!register_pmeth_gost(NID_id_GostR3410_94, &pmeth_GostR3410_94, 0)) - goto end; - if (!register_pmeth_gost(NID_id_GostR3410_2001, &pmeth_GostR3410_2001, 0)) - goto end; - if (!register_pmeth_gost - (NID_id_Gost28147_89_MAC, &pmeth_Gost28147_MAC, 0)) - goto end; - if (!ENGINE_register_ciphers(e) - || !ENGINE_register_digests(e) - || !ENGINE_register_pkey_meths(e) - /* These two actually should go in LIST_ADD command */ - || !EVP_add_cipher(&cipher_gost) - || !EVP_add_cipher(&cipher_gost_cpacnt) - || !EVP_add_digest(&digest_gost) - || !EVP_add_digest(&imit_gost_cpa) - ) { - goto end; - } - - ERR_load_GOST_strings(); - ret = 1; - end: - return ret; -} - -static int gost_digests(ENGINE *e, const EVP_MD **digest, - const int **nids, int nid) -{ - int ok = 1; - if (!digest) { - *nids = gost_digest_nids; - return 2; - } - /* - * printf("Digest no %d requested\n",nid); - */ - if (nid == NID_id_GostR3411_94) { - *digest = &digest_gost; - } else if (nid == NID_id_Gost28147_89_MAC) { - *digest = &imit_gost_cpa; - } else { - ok = 0; - *digest = NULL; - } - return ok; -} - -static int gost_ciphers(ENGINE *e, const EVP_CIPHER **cipher, - const int **nids, int nid) -{ - int ok = 1; - if (!cipher) { - *nids = gost_cipher_nids; - return 2; /* two ciphers are supported */ - } - - if (nid == NID_id_Gost28147_89) { - *cipher = &cipher_gost; - } else if (nid == NID_gost89_cnt) { - *cipher = &cipher_gost_cpacnt; - } else { - ok = 0; - *cipher = NULL; - } - return ok; -} - -static int gost_pkey_meths(ENGINE *e, EVP_PKEY_METHOD **pmeth, - const int **nids, int nid) -{ - if (!pmeth) { - *nids = gost_pkey_meth_nids; - return 3; - } - - switch (nid) { - case NID_id_GostR3410_94: - *pmeth = pmeth_GostR3410_94; - return 1; - case NID_id_GostR3410_2001: - *pmeth = pmeth_GostR3410_2001; - return 1; - case NID_id_Gost28147_89_MAC: - *pmeth = pmeth_Gost28147_MAC; - return 1; - default:; - } - - *pmeth = NULL; - return 0; -} - -static int gost_pkey_asn1_meths(ENGINE *e, EVP_PKEY_ASN1_METHOD **ameth, - const int **nids, int nid) -{ - if (!ameth) { - *nids = gost_pkey_meth_nids; - return 3; - } - switch (nid) { - case NID_id_GostR3410_94: - *ameth = ameth_GostR3410_94; - return 1; - case NID_id_GostR3410_2001: - *ameth = ameth_GostR3410_2001; - return 1; - case NID_id_Gost28147_89_MAC: - *ameth = ameth_Gost28147_MAC; - return 1; - - default:; - } - - *ameth = NULL; - return 0; -} - -#ifdef OPENSSL_NO_DYNAMIC_ENGINE -static ENGINE *engine_gost(void) -{ - ENGINE *ret = ENGINE_new(); - if (!ret) - return NULL; - if (!bind_gost(ret, engine_gost_id)) { - ENGINE_free(ret); - return NULL; - } - return ret; -} - -void ENGINE_load_gost(void) -{ - ENGINE *toadd; - if (pmeth_GostR3410_94) - return; - toadd = engine_gost(); - if (!toadd) - return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); -} -#else -IMPLEMENT_DYNAMIC_BIND_FN(bind_gost) -IMPLEMENT_DYNAMIC_CHECK_FN() -#endif -/********************************************************************** - * keywrap.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of CryptoPro key wrap algorithm, as defined in * - * RFC 4357 p 6.3 and 6.4 * - * Doesn't need OpenSSL * - **********************************************************************/ -#include -// #include "gost89.h" -#include "gost_keywrap.h" - -/*- - * Diversifies key using random UserKey Material - * Implements RFC 4357 p 6.5 key diversification algorithm - * - * inputKey - 32byte key to be diversified - * ukm - 8byte user key material - * outputKey - 32byte buffer to store diversified key - * - */ -void keyDiversifyCryptoPro(gost_ctx * ctx, const unsigned char *inputKey, - const unsigned char *ukm, unsigned char *outputKey) -{ - - u4 k, s1, s2; - int i, j, mask; - unsigned char S[8]; - memcpy(outputKey, inputKey, 32); - for (i = 0; i < 8; i++) { - /* Make array of integers from key */ - /* Compute IV S */ - s1 = 0, s2 = 0; - for (j = 0, mask = 1; j < 8; j++, mask <<= 1) { - k = ((u4) outputKey[4 * j]) | (outputKey[4 * j + 1] << 8) | - (outputKey[4 * j + 2] << 16) | (outputKey[4 * j + 3] << 24); - if (mask & ukm[i]) { - s1 += k; - } else { - s2 += k; - } - } - S[0] = (unsigned char)(s1 & 0xff); - S[1] = (unsigned char)((s1 >> 8) & 0xff); - S[2] = (unsigned char)((s1 >> 16) & 0xff); - S[3] = (unsigned char)((s1 >> 24) & 0xff); - S[4] = (unsigned char)(s2 & 0xff); - S[5] = (unsigned char)((s2 >> 8) & 0xff); - S[6] = (unsigned char)((s2 >> 16) & 0xff); - S[7] = (unsigned char)((s2 >> 24) & 0xff); - gost_key(ctx, outputKey); - gost_enc_cfb(ctx, S, outputKey, outputKey, 4); - } -} - -/*- - * Wraps key using RFC 4357 6.3 - * ctx - gost encryption context, initialized with some S-boxes - * keyExchangeKey (KEK) 32-byte (256-bit) shared key - * ukm - 8 byte (64 bit) user key material, - * sessionKey - 32-byte (256-bit) key to be wrapped - * wrappedKey - 44-byte buffer to store wrapped key - */ - -int keyWrapCryptoPro(gost_ctx * ctx, const unsigned char *keyExchangeKey, - const unsigned char *ukm, - const unsigned char *sessionKey, - unsigned char *wrappedKey) -{ - unsigned char kek_ukm[32]; - keyDiversifyCryptoPro(ctx, keyExchangeKey, ukm, kek_ukm); - gost_key(ctx, kek_ukm); - memcpy(wrappedKey, ukm, 8); - gost_enc(ctx, sessionKey, wrappedKey + 8, 4); - gost_mac_iv(ctx, 32, ukm, sessionKey, 32, wrappedKey + 40); - return 1; -} - -/*- - * Unwraps key using RFC 4357 6.4 - * ctx - gost encryption context, initialized with some S-boxes - * keyExchangeKey 32-byte shared key - * wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM, - * 32 byte encrypted key and 4 byte MAC - * - * sessionKEy - 32byte buffer to store sessionKey in - * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match - */ - -int keyUnwrapCryptoPro(gost_ctx * ctx, const unsigned char *keyExchangeKey, - const unsigned char *wrappedKey, - unsigned char *sessionKey) -{ - unsigned char kek_ukm[32], cek_mac[4]; - keyDiversifyCryptoPro(ctx, keyExchangeKey, wrappedKey - /* First 8 bytes of wrapped Key is ukm */ - , kek_ukm); - gost_key(ctx, kek_ukm); - gost_dec(ctx, wrappedKey + 8, sessionKey, 4); - gost_mac_iv(ctx, 32, wrappedKey, sessionKey, 32, cek_mac); - if (memcmp(cek_mac, wrappedKey + 40, 4)) { - return 0; - } - return 1; -} -/********************************************************************** - * md_gost.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * OpenSSL interface to GOST R 34.11-94 hash functions * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include -// #include "gost_lcl.h" -#include "gosthash.h" -// #include "e_gost_err.h" - -/* implementation of GOST 34.11 hash function See gost_md.c*/ -static int gost_digest_init(EVP_MD_CTX *ctx); -static int gost_digest_update(EVP_MD_CTX *ctx, const void *data, - size_t count); -static int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md); -static int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from); -static int gost_digest_cleanup(EVP_MD_CTX *ctx); - -EVP_MD digest_gost = { - NID_id_GostR3411_94, - NID_undef, - 32, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE, - gost_digest_init, - gost_digest_update, - gost_digest_final, - gost_digest_copy, - gost_digest_cleanup, - NULL, - NULL, - {NID_undef, NID_undef, 0, 0, 0}, - 32, - sizeof(struct ossl_gost_digest_ctx), - NULL -}; - -int gost_digest_init(EVP_MD_CTX *ctx) -{ - struct ossl_gost_digest_ctx *c = ctx->md_data; - memset(&(c->dctx), 0, sizeof(gost_hash_ctx)); - gost_init(&(c->cctx), &GostR3411_94_CryptoProParamSet); - c->dctx.cipher_ctx = &(c->cctx); - return 1; -} - -int gost_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return hash_block((gost_hash_ctx *) ctx->md_data, data, count); -} - -int gost_digest_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return finish_hash((gost_hash_ctx *) ctx->md_data, md); - -} - -int gost_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) -{ - struct ossl_gost_digest_ctx *md_ctx = to->md_data; - if (to->md_data && from->md_data) { - memcpy(to->md_data, from->md_data, - sizeof(struct ossl_gost_digest_ctx)); - md_ctx->dctx.cipher_ctx = &(md_ctx->cctx); - } - return 1; -} - -int gost_digest_cleanup(EVP_MD_CTX *ctx) -{ - if (ctx->md_data) - memset(ctx->md_data, 0, sizeof(struct ossl_gost_digest_ctx)); - return 1; -} -/********************************************************************** - * params.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Definitions of GOST R 34.10 parameter sets, defined in RFC 4357 * - * OpenSSL 0.9.9 libraries required to compile and use * - * this code * - **********************************************************************/ -// #include "gost_params.h" -#include "objects.h" -/* Parameters of GOST 34.10 */ - -R3410_params R3410_paramset[] = { -/* Paramset A */ - {NID_id_GostR3410_94_CryptoPro_A_ParamSet, - "100997906755055304772081815535925224869" - "8410825720534578748235158755771479905292727772441528526992987964833" - "5669968284202797289605274717317548059048560713474685214192868091256" - "1502802222185647539190902656116367847270145019066794290930185446216" - "3997308722217328898303231940973554032134009725883228768509467406639" - "62", - "127021248288932417465907042777176443525" - "7876535089165358128175072657050312609850984974231883334834011809259" - "9999512098893413065920561499672425412104927434935707492031276956145" - "1689224110579311248812610229678534638401693520013288995000362260684" - "2227508135323070045173416336850045410625869714168836867788425378203" - "83", - "683631961449557007844441656118272528951" - "02170888761442055095051287550314083023"} - , - {NID_id_GostR3410_94_CryptoPro_B_ParamSet, - "429418261486158041438734477379555023926" - "7234596860714306679811299408947123142002706038521669956384871995765" - "7284814898909770759462613437669456364882730370838934791080835932647" - "9767786019153434744009610342313166725786869204821949328786333602033" - "8479709268434224762105576023501613261478065276102850944540333865234" - "1", - "139454871199115825601409655107690713107" - "0417070599280317977580014543757653577229840941243685222882398330391" - "1468164807668823692122073732267216074074777170091113455043205380464" - "7694904686120113087816240740184800477047157336662926249423571248823" - "9685422217536601433914856808405203368594584948031873412885804895251" - "63", - "79885141663410976897627118935756323747307951916507639758300472692338873533959"} - , - {NID_id_GostR3410_94_CryptoPro_C_ParamSet, - "816552717970881016017893191415300348226" - "2544051353358162468249467681876621283478212884286545844013955142622" - "2087723485023722868022275009502224827866201744494021697716482008353" - "6398202298024892620480898699335508064332313529725332208819456895108" - "5155178100221003459370588291073071186553005962149936840737128710832" - "3", - "110624679233511963040518952417017040248" - "5862954819831383774196396298584395948970608956170224210628525560327" - "8638246716655439297654402921844747893079518669992827880792192992701" - "1428546551433875806377110443534293554066712653034996277099320715774" - "3542287621283671843703709141350171945045805050291770503634517804938" - "01", - "113468861199819350564868233378875198043" - "267947776488510997961231672532899549103"} - , - {NID_id_GostR3410_94_CryptoPro_D_ParamSet, - "756976611021707301782128757801610628085" - "5283803109571158829574281419208532589041660017017859858216341400371" - "4687551412794400562878935266630754392677014598582103365983119173924" - "4732511225464712252386803315902707727668715343476086350472025298282" - "7271461690125050616858238384366331089777463541013033926723743254833" - "7", - "905457649621929965904290958774625315611" - "3056083907389766971404812524422262512556054474620855996091570786713" - "5849550236741915584185990627801066465809510095784713989819413820871" - "5964648914493053407920737078890520482730623038837767710173664838239" - "8574828787891286471201460474326612697849693665518073864436497893214" - "9", - "108988435796353506912374591498972192620" - "190487557619582334771735390599299211593"} - , - - {NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, - "1335318132727206734338595199483190012179423759678474868994823595993" - "6964252873471246159040332773182141032801252925387191478859899310331" - "0567744136196364803064721377826656898686468463277710150809401182608" - "7702016153249904683329312949209127762411378780302243557466062839716" - "59376426832674269780880061631528163475887", - "14201174159756348119636828602231808974327613839524373876287257344192" - "74593935127189736311660784676003608489466235676257952827747192122419" - "29071046134208380636394084512691828894000571524625445295769349356752" - "72895683154177544176313938445719175509684710784659566254794231229333" - "8483924514339614727760681880609734239", - "91771529896554605945588149018382750217296858393520724172743325725474" - "374979801"} - , - {NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, - "8890864727828423151699995801875757891031463338652579140051973659" - "3048131440685857067369829407947744496306656291505503608252399443" - "7900272386749145996230867832228661977543992816745254823298629859" - "8753575466286051738837854736167685769017780335804511440773337196" - "2538423532919394477873664752824509986617878992443177", - "1028946126624994859676552074360530315217970499989304888248413244" - "8474923022758470167998871003604670704877377286176171227694098633" - "1539089568784129110109512690503345393869871295783467257264868341" - "7200196629860561193666752429682367397084815179752036423595736533" - "68957392061769855284593965042530895046088067160269433", - "9109671391802626916582318050603555673628769498182593088388796888" - "5281641595199"} - , - {NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, - "4430618464297584182473135030809859326863990650118941756995270074" - "8609973181426950235239623239110557450826919295792878938752101867" - "7047181623251027516953100431855964837602657827828194249605561893" - "6965865325513137194483136247773653468410118796740709840825496997" - "9375560722345106704721086025979309968763193072908334", - "1246996366993477513607147265794064436203408861395055989217248455" - "7299870737698999651480662364723992859320868822848751165438350943" - "3276647222625940615560580450040947211826027729977563540237169063" - "0448079715771649447778447000597419032457722226253269698374446528" - "35352729304393746106576383349151001715930924115499549", - "6787876137336591234380295020065682527118129468050147943114675429" - "4748422492761"} - , - - {NID_undef, NULL, NULL, NULL} -}; - -R3410_2001_params R3410_2001_paramset[] = { - /* default_cc_sign01_param 1.2.643.2.9.1.8.1 */ - {NID_id_GostR3410_2001_ParamSet_cc, - /* A */ - "C0000000000000000000000000000000000000000000000000000000000003c4", - /* B */ - "2d06B4265ebc749ff7d0f1f1f88232e81632e9088fd44b7787d5e407e955080c", - /* P */ - "C0000000000000000000000000000000000000000000000000000000000003C7", - /* Q */ - "5fffffffffffffffffffffffffffffff606117a2f4bde428b7458a54b6e87b85", - /* X */ - "2", - /* Y */ - "a20e034bf8813ef5c18d01105e726a17eb248b264ae9706f440bedc8ccb6b22c"} - , - /* 1.2.643.2.2.35.0 */ - {NID_id_GostR3410_2001_TestParamSet, - "7", - "5FBFF498AA938CE739B8E022FBAFEF40563F6E6A3472FC2A514C0CE9DAE23B7E", - "8000000000000000000000000000000000000000000000000000000000000431", - "8000000000000000000000000000000150FE8A1892976154C59CFC193ACCF5B3", - "2", - "08E2A8A0E65147D4BD6316030E16D19C85C97F0A9CA267122B96ABBCEA7E8FC8"} - , - /* - * 1.2.643.2.2.35.1 - */ - {NID_id_GostR3410_2001_CryptoPro_A_ParamSet, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", - "a6", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", - "1", - "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"} - , - /* - * 1.2.643.2.2.35.2 - */ - {NID_id_GostR3410_2001_CryptoPro_B_ParamSet, - "8000000000000000000000000000000000000000000000000000000000000C96", - "3E1AF419A269A5F866A7D3C25C3DF80AE979259373FF2B182F49D4CE7E1BBC8B", - "8000000000000000000000000000000000000000000000000000000000000C99", - "800000000000000000000000000000015F700CFFF1A624E5E497161BCC8A198F", - "1", - "3FA8124359F96680B83D1C3EB2C070E5C545C9858D03ECFB744BF8D717717EFC"} - , - /* - * 1.2.643.2.2.35.3 - */ - {NID_id_GostR3410_2001_CryptoPro_C_ParamSet, - "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598", - "805a", - "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B", - "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", - "0", - "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"} - , - /* - * 1.2.643.2.2.36.0 - */ - {NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94", - "a6", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97", - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893", - "1", - "8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14"} - , - /* - * 1.2.643.2.2.36.1 - */ - {NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, - "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D7598", - "805a", - "9B9F605F5A858107AB1EC85E6B41C8AACF846E86789051D37998F7B9022D759B", - "9B9F605F5A858107AB1EC85E6B41C8AA582CA3511EDDFB74F02F3A6598980BB9", - "0", - "41ECE55743711A8C3CBF3783CD08C0EE4D4DC440D4641A8F366E550DFDB3BB67"} - , - {0, NULL, NULL, NULL, NULL, NULL, NULL} -}; -/********************************************************************** - * gost_pmeth.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of RFC 4357 (GOST R 34.10) Publick key method * - * for OpenSSL * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -// #include "evp.h" -// #include "objects.h" -#include "ec.h" -#include "x509v3.h" /* For string_to_hex */ -#include -#include -#include -// #include "gost_params.h" -// #include "gost_lcl.h" -// #include "e_gost_err.h" -/* -----init, cleanup, copy - uniform for all algs ---------------*/ -/* Allocates new gost_pmeth_data structure and assigns it as data */ -static int pkey_gost_init(EVP_PKEY_CTX *ctx) -{ - struct gost_pmeth_data *data; - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - data = OPENSSL_malloc(sizeof(struct gost_pmeth_data)); - if (!data) - return 0; - memset(data, 0, sizeof(struct gost_pmeth_data)); - if (pkey && EVP_PKEY_get0(pkey)) { - switch (EVP_PKEY_base_id(pkey)) { - case NID_id_GostR3410_94: - data->sign_param_nid = gost94_nid_by_params(EVP_PKEY_get0(pkey)); - break; - case NID_id_GostR3410_2001: - data->sign_param_nid = - EC_GROUP_get_curve_name(EC_KEY_get0_group - (EVP_PKEY_get0((EVP_PKEY *)pkey))); - break; - default: - return 0; - } - } - EVP_PKEY_CTX_set_data(ctx, data); - return 1; -} - -/* Copies contents of gost_pmeth_data structure */ -static int pkey_gost_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - struct gost_pmeth_data *dst_data, *src_data; - if (!pkey_gost_init(dst)) { - return 0; - } - src_data = EVP_PKEY_CTX_get_data(src); - dst_data = EVP_PKEY_CTX_get_data(dst); - *dst_data = *src_data; - if (src_data->shared_ukm) { - dst_data->shared_ukm = NULL; - } - return 1; -} - -/* Frees up gost_pmeth_data structure */ -static void pkey_gost_cleanup(EVP_PKEY_CTX *ctx) -{ - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - if (data->shared_ukm) - OPENSSL_free(data->shared_ukm); - OPENSSL_free(data); -} - -/* --------------------- control functions ------------------------------*/ -static int pkey_gost_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - struct gost_pmeth_data *pctx = - (struct gost_pmeth_data *)EVP_PKEY_CTX_get_data(ctx); - switch (type) { - case EVP_PKEY_CTRL_MD: - { - if (EVP_MD_type((const EVP_MD *)p2) != NID_id_GostR3411_94) { - GOSTerr(GOST_F_PKEY_GOST_CTRL, GOST_R_INVALID_DIGEST_TYPE); - return 0; - } - pctx->md = (EVP_MD *)p2; - return 1; - } - break; - - case EVP_PKEY_CTRL_GET_MD: - *(const EVP_MD **)p2 = pctx->md; - return 1; - - case EVP_PKEY_CTRL_PKCS7_ENCRYPT: - case EVP_PKEY_CTRL_PKCS7_DECRYPT: - case EVP_PKEY_CTRL_PKCS7_SIGN: - case EVP_PKEY_CTRL_DIGESTINIT: -#ifndef OPENSSL_NO_CMS - case EVP_PKEY_CTRL_CMS_ENCRYPT: - case EVP_PKEY_CTRL_CMS_DECRYPT: - case EVP_PKEY_CTRL_CMS_SIGN: -#endif - return 1; - - case EVP_PKEY_CTRL_GOST_PARAMSET: - pctx->sign_param_nid = (int)p1; - return 1; - case EVP_PKEY_CTRL_SET_IV: - pctx->shared_ukm = OPENSSL_malloc((int)p1); - if (pctx->shared_ukm == NULL) - return 0; - memcpy(pctx->shared_ukm, p2, (int)p1); - return 1; - case EVP_PKEY_CTRL_PEER_KEY: - if (p1 == 0 || p1 == 1) /* call from EVP_PKEY_derive_set_peer */ - return 1; - if (p1 == 2) /* TLS: peer key used? */ - return pctx->peer_key_used; - if (p1 == 3) /* TLS: peer key used! */ - return (pctx->peer_key_used = 1); - return -2; - } - return -2; -} - -static int pkey_gost_ctrl94_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - int param_nid = 0; - if (!strcmp(type, param_ctrl_string)) { - if (!value) { - return 0; - } - if (strlen(value) == 1) { - switch (toupper((unsigned char)value[0])) { - case 'A': - param_nid = NID_id_GostR3410_94_CryptoPro_A_ParamSet; - break; - case 'B': - param_nid = NID_id_GostR3410_94_CryptoPro_B_ParamSet; - break; - case 'C': - param_nid = NID_id_GostR3410_94_CryptoPro_C_ParamSet; - break; - case 'D': - param_nid = NID_id_GostR3410_94_CryptoPro_D_ParamSet; - break; - default: - return 0; - break; - } - } else if ((strlen(value) == 2) - && (toupper((unsigned char)value[0]) == 'X')) { - switch (toupper((unsigned char)value[1])) { - case 'A': - param_nid = NID_id_GostR3410_94_CryptoPro_XchA_ParamSet; - break; - case 'B': - param_nid = NID_id_GostR3410_94_CryptoPro_XchB_ParamSet; - break; - case 'C': - param_nid = NID_id_GostR3410_94_CryptoPro_XchC_ParamSet; - break; - default: - return 0; - break; - } - } else { - R3410_params *p = R3410_paramset; - param_nid = OBJ_txt2nid(value); - if (param_nid == NID_undef) { - return 0; - } - for (; p->nid != NID_undef; p++) { - if (p->nid == param_nid) - break; - } - if (p->nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST_CTRL94_STR, GOST_R_INVALID_PARAMSET); - return 0; - } - } - - return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - param_nid, NULL); - } - return -2; -} - -static int pkey_gost_ctrl01_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - int param_nid = 0; - if (!strcmp(type, param_ctrl_string)) { - if (!value) { - return 0; - } - if (strlen(value) == 1) { - switch (toupper((unsigned char)value[0])) { - case 'A': - param_nid = NID_id_GostR3410_2001_CryptoPro_A_ParamSet; - break; - case 'B': - param_nid = NID_id_GostR3410_2001_CryptoPro_B_ParamSet; - break; - case 'C': - param_nid = NID_id_GostR3410_2001_CryptoPro_C_ParamSet; - break; - case '0': - param_nid = NID_id_GostR3410_2001_TestParamSet; - break; - default: - return 0; - break; - } - } else if ((strlen(value) == 2) - && (toupper((unsigned char)value[0]) == 'X')) { - switch (toupper((unsigned char)value[1])) { - case 'A': - param_nid = NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet; - break; - case 'B': - param_nid = NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet; - break; - default: - return 0; - break; - } - } else { - R3410_2001_params *p = R3410_2001_paramset; - param_nid = OBJ_txt2nid(value); - if (param_nid == NID_undef) { - return 0; - } - for (; p->nid != NID_undef; p++) { - if (p->nid == param_nid) - break; - } - if (p->nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST_CTRL01_STR, GOST_R_INVALID_PARAMSET); - return 0; - } - } - - return pkey_gost_ctrl(ctx, EVP_PKEY_CTRL_GOST_PARAMSET, - param_nid, NULL); - } - return -2; -} - -/* --------------------- key generation --------------------------------*/ - -static int pkey_gost_paramgen_init(EVP_PKEY_CTX *ctx) -{ - return 1; -} - -static int pkey_gost94_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - DSA *dsa = NULL; - if (data->sign_param_nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST94_PARAMGEN, GOST_R_NO_PARAMETERS_SET); - return 0; - } - dsa = DSA_new(); - if (!fill_GOST94_params(dsa, data->sign_param_nid)) { - DSA_free(dsa); - return 0; - } - EVP_PKEY_assign(pkey, NID_id_GostR3410_94, dsa); - return 1; -} - -static int pkey_gost01_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - struct gost_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - EC_KEY *ec = NULL; - - if (data->sign_param_nid == NID_undef) { - GOSTerr(GOST_F_PKEY_GOST01_PARAMGEN, GOST_R_NO_PARAMETERS_SET); - return 0; - } - if (!ec) - ec = EC_KEY_new(); - if (!fill_GOST2001_params(ec, data->sign_param_nid)) { - EC_KEY_free(ec); - return 0; - } - EVP_PKEY_assign(pkey, NID_id_GostR3410_2001, ec); - return 1; -} - -/* Generates Gost_R3410_94_cp key */ -static int pkey_gost94cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - DSA *dsa; - if (!pkey_gost94_paramgen(ctx, pkey)) - return 0; - dsa = EVP_PKEY_get0(pkey); - gost_sign_keygen(dsa); - return 1; -} - -/* Generates GOST_R3410 2001 key and assigns it using specified type */ -static int pkey_gost01cp_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - EC_KEY *ec; - if (!pkey_gost01_paramgen(ctx, pkey)) - return 0; - ec = EVP_PKEY_get0(pkey); - gost2001_keygen(ec); - return 1; -} - -/* ----------- sign callbacks --------------------------------------*/ - -static int pkey_gost94_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbs_len) -{ - DSA_SIG *unpacked_sig = NULL; - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - if (!siglen) - return 0; - if (!sig) { - *siglen = 64; /* better to check size of pkey->pkey.dsa-q */ - return 1; - } - unpacked_sig = gost_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey)); - if (!unpacked_sig) { - return 0; - } - return pack_sign_cp(unpacked_sig, 32, sig, siglen); -} - -static int pkey_gost01_cp_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbs_len) -{ - DSA_SIG *unpacked_sig = NULL; - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - if (!siglen) - return 0; - if (!sig) { - *siglen = 64; /* better to check size of curve order */ - return 1; - } - unpacked_sig = gost2001_do_sign(tbs, tbs_len, EVP_PKEY_get0(pkey)); - if (!unpacked_sig) { - return 0; - } - return pack_sign_cp(unpacked_sig, 32, sig, siglen); -} - -/* ------------------- verify callbacks ---------------------------*/ - -static int pkey_gost94_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbs_len) -{ - int ok = 0; - EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); - DSA_SIG *s = unpack_cp_signature(sig, siglen); - if (!s) - return 0; - if (pub_key) - ok = gost_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key)); - DSA_SIG_free(s); - return ok; -} - -static int pkey_gost01_cp_verify(EVP_PKEY_CTX *ctx, const unsigned char *sig, - size_t siglen, const unsigned char *tbs, - size_t tbs_len) -{ - int ok = 0; - EVP_PKEY *pub_key = EVP_PKEY_CTX_get0_pkey(ctx); - DSA_SIG *s = unpack_cp_signature(sig, siglen); - if (!s) - return 0; -#ifdef DEBUG_SIGN - fprintf(stderr, "R="); - BN_print_fp(stderr, s->r); - fprintf(stderr, "\nS="); - BN_print_fp(stderr, s->s); - fprintf(stderr, "\n"); -#endif - if (pub_key) - ok = gost2001_do_verify(tbs, tbs_len, s, EVP_PKEY_get0(pub_key)); - DSA_SIG_free(s); - return ok; -} - -/* ------------- encrypt init -------------------------------------*/ -/* Generates ephermeral key */ -static int pkey_gost_encrypt_init(EVP_PKEY_CTX *ctx) -{ - return 1; -} - -/* --------------- Derive init ------------------------------------*/ -static int pkey_gost_derive_init(EVP_PKEY_CTX *ctx) -{ - return 1; -} - -/* -------- PKEY_METHOD for GOST MAC algorithm --------------------*/ -static int pkey_gost_mac_init(EVP_PKEY_CTX *ctx) -{ - struct gost_mac_pmeth_data *data; - data = OPENSSL_malloc(sizeof(struct gost_mac_pmeth_data)); - if (!data) - return 0; - memset(data, 0, sizeof(struct gost_mac_pmeth_data)); - EVP_PKEY_CTX_set_data(ctx, data); - return 1; -} - -static void pkey_gost_mac_cleanup(EVP_PKEY_CTX *ctx) -{ - struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - OPENSSL_free(data); -} - -static int pkey_gost_mac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - struct gost_mac_pmeth_data *dst_data, *src_data; - if (!pkey_gost_mac_init(dst)) { - return 0; - } - src_data = EVP_PKEY_CTX_get_data(src); - dst_data = EVP_PKEY_CTX_get_data(dst); - *dst_data = *src_data; - return 1; -} - -static int pkey_gost_mac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - struct gost_mac_pmeth_data *data = - (struct gost_mac_pmeth_data *)EVP_PKEY_CTX_get_data(ctx); - - switch (type) { - case EVP_PKEY_CTRL_MD: - { - if (EVP_MD_type((const EVP_MD *)p2) != NID_id_Gost28147_89_MAC) { - GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, - GOST_R_INVALID_DIGEST_TYPE); - return 0; - } - data->md = (EVP_MD *)p2; - return 1; - } - break; - - case EVP_PKEY_CTRL_GET_MD: - *(const EVP_MD **)p2 = data->md; - return 1; - - case EVP_PKEY_CTRL_PKCS7_ENCRYPT: - case EVP_PKEY_CTRL_PKCS7_DECRYPT: - case EVP_PKEY_CTRL_PKCS7_SIGN: - return 1; - case EVP_PKEY_CTRL_SET_MAC_KEY: - if (p1 != 32) { - GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, GOST_R_INVALID_MAC_KEY_LENGTH); - return 0; - } - - memcpy(data->key, p2, 32); - data->key_set = 1; - return 1; - case EVP_PKEY_CTRL_DIGESTINIT: - { - EVP_MD_CTX *mctx = p2; - void *key; - if (!data->key_set) { - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx); - if (!pkey) { - GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, - GOST_R_MAC_KEY_NOT_SET); - return 0; - } - key = EVP_PKEY_get0(pkey); - if (!key) { - GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL, - GOST_R_MAC_KEY_NOT_SET); - return 0; - } - } else { - key = &(data->key); - } - return mctx->digest->md_ctrl(mctx, EVP_MD_CTRL_SET_KEY, 32, key); - } - } - return -2; -} - -static int pkey_gost_mac_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!strcmp(type, key_ctrl_string)) { - if (strlen(value) != 32) { - GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, - GOST_R_INVALID_MAC_KEY_LENGTH); - return 0; - } - return pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, - 32, (char *)value); - } - if (!strcmp(type, hexkey_ctrl_string)) { - long keylen; - int ret; - unsigned char *keybuf = string_to_hex(value, &keylen); - if (!keybuf || keylen != 32) { - GOSTerr(GOST_F_PKEY_GOST_MAC_CTRL_STR, - GOST_R_INVALID_MAC_KEY_LENGTH); - OPENSSL_free(keybuf); - return 0; - } - ret = pkey_gost_mac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, 32, keybuf); - OPENSSL_free(keybuf); - return ret; - - } - return -2; -} - -static int pkey_gost_mac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - struct gost_mac_pmeth_data *data = EVP_PKEY_CTX_get_data(ctx); - unsigned char *keydata; - if (!data->key_set) { - GOSTerr(GOST_F_PKEY_GOST_MAC_KEYGEN, GOST_R_MAC_KEY_NOT_SET); - return 0; - } - keydata = OPENSSL_malloc(32); - if (keydata == NULL) - return 0; - memcpy(keydata, data->key, 32); - EVP_PKEY_assign(pkey, NID_id_Gost28147_89_MAC, keydata); - return 1; -} - -static int pkey_gost_mac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - return 1; -} - -static int pkey_gost_mac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, EVP_MD_CTX *mctx) -{ - unsigned int tmpsiglen = *siglen; /* for platforms where - * sizeof(int)!=sizeof(size_t) */ - int ret; - if (!sig) { - *siglen = 4; - return 1; - } - ret = EVP_DigestFinal_ex(mctx, sig, &tmpsiglen); - *siglen = tmpsiglen; - return ret; -} - -/* ----------------------------------------------------------------*/ -int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags) -{ - *pmeth = EVP_PKEY_meth_new(id, flags); - if (!*pmeth) - return 0; - - switch (id) { - case NID_id_GostR3410_94: - EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ctrl94_str); - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost94cp_keygen); - EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost94_cp_sign); - EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost94_cp_verify); - EVP_PKEY_meth_set_encrypt(*pmeth, - pkey_gost_encrypt_init, - pkey_GOST94cp_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST94cp_decrypt); - EVP_PKEY_meth_set_derive(*pmeth, - pkey_gost_derive_init, pkey_gost94_derive); - EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, - pkey_gost94_paramgen); - break; - case NID_id_GostR3410_2001: - EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_ctrl, pkey_gost_ctrl01_str); - EVP_PKEY_meth_set_sign(*pmeth, NULL, pkey_gost01_cp_sign); - EVP_PKEY_meth_set_verify(*pmeth, NULL, pkey_gost01_cp_verify); - - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost01cp_keygen); - - EVP_PKEY_meth_set_encrypt(*pmeth, - pkey_gost_encrypt_init, - pkey_GOST01cp_encrypt); - EVP_PKEY_meth_set_decrypt(*pmeth, NULL, pkey_GOST01cp_decrypt); - EVP_PKEY_meth_set_derive(*pmeth, - pkey_gost_derive_init, pkey_gost2001_derive); - EVP_PKEY_meth_set_paramgen(*pmeth, pkey_gost_paramgen_init, - pkey_gost01_paramgen); - break; - case NID_id_Gost28147_89_MAC: - EVP_PKEY_meth_set_ctrl(*pmeth, pkey_gost_mac_ctrl, - pkey_gost_mac_ctrl_str); - EVP_PKEY_meth_set_signctx(*pmeth, pkey_gost_mac_signctx_init, - pkey_gost_mac_signctx); - EVP_PKEY_meth_set_keygen(*pmeth, NULL, pkey_gost_mac_keygen); - EVP_PKEY_meth_set_init(*pmeth, pkey_gost_mac_init); - EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_mac_cleanup); - EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_mac_copy); - return 1; - default: /* Unsupported method */ - return 0; - } - EVP_PKEY_meth_set_init(*pmeth, pkey_gost_init); - EVP_PKEY_meth_set_cleanup(*pmeth, pkey_gost_cleanup); - - EVP_PKEY_meth_set_copy(*pmeth, pkey_gost_copy); - /* - * FIXME derive etc... - */ - - return 1; -} -/********************************************************************** - * gost_sign.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of GOST R 34.10-94 signature algorithm * - * for OpenSSL * - * Requires OpenSSL 0.9.9 for compilation * - **********************************************************************/ -#include -// #include "rand.h" -#include "bn.h" -#include "dsa.h" -// #include "evp.h" -// #include "err.h" - -// #include "gost_params.h" -// #include "gost_lcl.h" -// #include "e_gost_err.h" - -#ifdef DEBUG_SIGN -void dump_signature(const char *message, const unsigned char *buffer, - size_t len) -{ - size_t i; - fprintf(stderr, "signature %s Length=%d", message, len); - for (i = 0; i < len; i++) { - if (i % 16 == 0) - fputc('\n', stderr); - fprintf(stderr, " %02x", buffer[i]); - } - fprintf(stderr, "\nEnd of signature\n"); -} - -void dump_dsa_sig(const char *message, DSA_SIG *sig) -{ - fprintf(stderr, "%s\nR=", message); - BN_print_fp(stderr, sig->r); - fprintf(stderr, "\nS="); - BN_print_fp(stderr, sig->s); - fprintf(stderr, "\n"); -} - -#else - -# define dump_signature(a,b,c) -# define dump_dsa_sig(a,b) -#endif - -/* - * Computes signature and returns it as DSA_SIG structure - */ -DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) -{ - BIGNUM *k = NULL, *tmp = NULL, *tmp2 = NULL; - DSA_SIG *newsig = NULL, *ret = NULL; - BIGNUM *md = hashsum2bn(dgst); - /* check if H(M) mod q is zero */ - BN_CTX *ctx = BN_CTX_new(); - if(!ctx) { - GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - BN_CTX_start(ctx); - newsig = DSA_SIG_new(); - if (!newsig) { - GOSTerr(GOST_F_GOST_DO_SIGN, GOST_R_NO_MEMORY); - goto err; - } - tmp = BN_CTX_get(ctx); - k = BN_CTX_get(ctx); - tmp2 = BN_CTX_get(ctx); - if(!tmp || !k || !tmp2) { - GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - BN_mod(tmp, md, dsa->q, ctx); - if (BN_is_zero(tmp)) { - BN_one(md); - } - do { - do { - /* - * Generate random number k less than q - */ - BN_rand_range(k, dsa->q); - /* generate r = (a^x mod p) mod q */ - BN_mod_exp(tmp, dsa->g, k, dsa->p, ctx); - if (!(newsig->r)) { - newsig->r = BN_new(); - if(!newsig->r) { - GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - BN_mod(newsig->r, tmp, dsa->q, ctx); - } - while (BN_is_zero(newsig->r)); - /* generate s = (xr + k(Hm)) mod q */ - BN_mod_mul(tmp, dsa->priv_key, newsig->r, dsa->q, ctx); - BN_mod_mul(tmp2, k, md, dsa->q, ctx); - if (!newsig->s) { - newsig->s = BN_new(); - if(!newsig->s) { - GOSTerr(GOST_F_GOST_DO_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - BN_mod_add(newsig->s, tmp, tmp2, dsa->q, ctx); - } - while (BN_is_zero(newsig->s)); - - ret = newsig; - err: - BN_free(md); - if(ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if(!ret && newsig) { - DSA_SIG_free(newsig); - } - return ret; -} - -/* - * Packs signature according to Cryptocom rules - * and frees up DSA_SIG structure - */ -/*- -int pack_sign_cc(DSA_SIG *s,int order,unsigned char *sig, size_t *siglen) - { - *siglen = 2*order; - memset(sig,0,*siglen); - store_bignum(s->r, sig,order); - store_bignum(s->s, sig + order,order); - dump_signature("serialized",sig,*siglen); - DSA_SIG_free(s); - return 1; - } -*/ -/* - * Packs signature according to Cryptopro rules - * and frees up DSA_SIG structure - */ -int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen) -{ - *siglen = 2 * order; - memset(sig, 0, *siglen); - store_bignum(s->s, sig, order); - store_bignum(s->r, sig + order, order); - dump_signature("serialized", sig, *siglen); - DSA_SIG_free(s); - return 1; -} - -/* - * Verifies signature passed as DSA_SIG structure - * - */ - -int gost_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa) -{ - BIGNUM *md = NULL, *tmp = NULL; - BIGNUM *q2 = NULL; - BIGNUM *u = NULL, *v = NULL, *z1 = NULL, *z2 = NULL; - BIGNUM *tmp2 = NULL, *tmp3 = NULL; - int ok = 0; - BN_CTX *ctx = BN_CTX_new(); - if(!ctx) { - GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - - BN_CTX_start(ctx); - if (BN_cmp(sig->s, dsa->q) >= 1 || BN_cmp(sig->r, dsa->q) >= 1) { - GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_PARTS_GREATER_THAN_Q); - goto err; - } - md = hashsum2bn(dgst); - - tmp = BN_CTX_get(ctx); - v = BN_CTX_get(ctx); - q2 = BN_CTX_get(ctx); - z1 = BN_CTX_get(ctx); - z2 = BN_CTX_get(ctx); - tmp2 = BN_CTX_get(ctx); - tmp3 = BN_CTX_get(ctx); - u = BN_CTX_get(ctx); - if(!tmp || !v || !q2 || !z1 || !z2 || !tmp2 || !tmp3 || !u) { - GOSTerr(GOST_F_GOST_DO_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - - BN_mod(tmp, md, dsa->q, ctx); - if (BN_is_zero(tmp)) { - BN_one(md); - } - BN_copy(q2, dsa->q); - BN_sub_word(q2, 2); - BN_mod_exp(v, md, q2, dsa->q, ctx); - BN_mod_mul(z1, sig->s, v, dsa->q, ctx); - BN_sub(tmp, dsa->q, sig->r); - BN_mod_mul(z2, tmp, v, dsa->p, ctx); - BN_mod_exp(tmp, dsa->g, z1, dsa->p, ctx); - BN_mod_exp(tmp2, dsa->pub_key, z2, dsa->p, ctx); - BN_mod_mul(tmp3, tmp, tmp2, dsa->p, ctx); - BN_mod(u, tmp3, dsa->q, ctx); - ok = (BN_cmp(u, sig->r) == 0); - - if (!ok) { - GOSTerr(GOST_F_GOST_DO_VERIFY, GOST_R_SIGNATURE_MISMATCH); - } -err: - if(md) BN_free(md); - if(ctx) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - return ok; -} - -/* - * Computes public keys for GOST R 34.10-94 algorithm - * - */ -int gost94_compute_public(DSA *dsa) -{ - /* Now fill algorithm parameters with correct values */ - BN_CTX *ctx; - if (!dsa->g) { - GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, GOST_R_KEY_IS_NOT_INITALIZED); - return 0; - } - ctx = BN_CTX_new(); - if(!ctx) { - GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); - return 0; - } - - dsa->pub_key = BN_new(); - if(!dsa->pub_key) { - GOSTerr(GOST_F_GOST94_COMPUTE_PUBLIC, ERR_R_MALLOC_FAILURE); - BN_CTX_free(ctx); - return 0; - } - /* Compute public key y = a^x mod p */ - BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx); - BN_CTX_free(ctx); - return 1; -} - -/* - * Fill GOST 94 params, searching them in R3410_paramset array - * by nid of paramset - * - */ -int fill_GOST94_params(DSA *dsa, int nid) -{ - R3410_params *params = R3410_paramset; - while (params->nid != NID_undef && params->nid != nid) - params++; - if (params->nid == NID_undef) { - GOSTerr(GOST_F_FILL_GOST94_PARAMS, GOST_R_UNSUPPORTED_PARAMETER_SET); - return 0; - } -#define dump_signature(a,b,c) - if (dsa->p) { - BN_free(dsa->p); - } - dsa->p = NULL; - BN_dec2bn(&(dsa->p), params->p); - if (dsa->q) { - BN_free(dsa->q); - } - dsa->q = NULL; - BN_dec2bn(&(dsa->q), params->q); - if (dsa->g) { - BN_free(dsa->g); - } - dsa->g = NULL; - BN_dec2bn(&(dsa->g), params->a); - return 1; -} - -/* - * Generate GOST R 34.10-94 keypair - * - * - */ -int gost_sign_keygen(DSA *dsa) -{ - dsa->priv_key = BN_new(); - if(!dsa->priv_key) { - GOSTerr(GOST_F_GOST_SIGN_KEYGEN, ERR_R_MALLOC_FAILURE); - return 0; - } - BN_rand_range(dsa->priv_key, dsa->q); - return gost94_compute_public(dsa); -} - -/* Unpack signature according to cryptocom rules */ -/*- -DSA_SIG *unpack_cc_signature(const unsigned char *sig,size_t siglen) - { - DSA_SIG *s; - s = DSA_SIG_new(); - if (s == NULL) - { - GOSTerr(GOST_F_UNPACK_CC_SIGNATURE,GOST_R_NO_MEMORY); - return(NULL); - } - s->r = getbnfrombuf(sig, siglen/2); - s->s = getbnfrombuf(sig + siglen/2, siglen/2); - return s; - } -*/ -/* Unpack signature according to cryptopro rules */ -DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen) -{ - DSA_SIG *s; - - s = DSA_SIG_new(); - if (s == NULL) { - GOSTerr(GOST_F_UNPACK_CP_SIGNATURE, GOST_R_NO_MEMORY); - return NULL; - } - s->s = getbnfrombuf(sig, siglen / 2); - s->r = getbnfrombuf(sig + siglen / 2, siglen / 2); - return s; -} - -/* Convert little-endian byte array into bignum */ -BIGNUM *hashsum2bn(const unsigned char *dgst) -{ - unsigned char buf[32]; - int i; - for (i = 0; i < 32; i++) { - buf[31 - i] = dgst[i]; - } - return getbnfrombuf(buf, 32); -} - -/* Convert byte buffer to bignum, skipping leading zeros*/ -BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len) -{ - while (*buf == 0 && len > 0) { - buf++; - len--; - } - if (len) { - return BN_bin2bn(buf, len, NULL); - } else { - BIGNUM *b = BN_new(); - BN_zero(b); - return b; - } -} - -/* - * Pack bignum into byte buffer of given size, filling all leading bytes by - * zeros - */ -int store_bignum(BIGNUM *bn, unsigned char *buf, int len) -{ - int bytes = BN_num_bytes(bn); - if (bytes > len) - return 0; - memset(buf, 0, len); - BN_bn2bin(bn, buf + len - bytes); - return 1; -} diff --git a/Sources/COpenSSL/gost_keywrap.h b/Sources/COpenSSL/gost_keywrap.h deleted file mode 100644 index 7def4c9f..00000000 --- a/Sources/COpenSSL/gost_keywrap.h +++ /dev/null @@ -1,56 +0,0 @@ -/********************************************************************** - * gost_keywrap.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of CryptoPro key wrap algorithm, as defined in * - * RFC 4357 p 6.3 and 6.4 * - * Doesn't need OpenSSL * - **********************************************************************/ -#ifndef GOST_KEYWRAP_H -# define GOST_KEYWRAP_H -# include -# include "gost89.h" -/*- - * Diversifies key using random UserKey Material - * Implements RFC 4357 p 6.5 key diversification algorithm - * - * inputKey - 32byte key to be diversified - * ukm - 8byte user key material - * outputKey - 32byte buffer to store diversified key - * - */ -void keyDiversifyCryptoPro(gost_ctx * ctx, - const unsigned char *inputKey, - const unsigned char *ukm, - unsigned char *outputKey); -/*- - * Wraps key using RFC 4357 6.3 - * ctx - gost encryption context, initialized with some S-boxes - * keyExchangeKey (KEK) 32-byte (256-bit) shared key - * ukm - 8 byte (64 bit) user key material, - * sessionKey - 32-byte (256-bit) key to be wrapped - * wrappedKey - 44-byte buffer to store wrapped key - */ - -int keyWrapCryptoPro(gost_ctx * ctx, - const unsigned char *keyExchangeKey, - const unsigned char *ukm, - const unsigned char *sessionKey, - unsigned char *wrappedKey); -/*- - * Unwraps key using RFC 4357 6.4 - * ctx - gost encryption context, initialized with some S-boxes - * keyExchangeKey 32-byte shared key - * wrappedKey 44 byte key to be unwrapped (concatenation of 8-byte UKM, - * 32 byte encrypted key and 4 byte MAC - * - * sessionKEy - 32byte buffer to store sessionKey in - * Returns 1 if key is decrypted successfully, and 0 if MAC doesn't match - */ - -int keyUnwrapCryptoPro(gost_ctx * ctx, - const unsigned char *keyExchangeKey, - const unsigned char *wrappedKey, - unsigned char *sessionKey); -#endif diff --git a/Sources/COpenSSL/gost_lcl.h b/Sources/COpenSSL/gost_lcl.h deleted file mode 100644 index 67a81523..00000000 --- a/Sources/COpenSSL/gost_lcl.h +++ /dev/null @@ -1,229 +0,0 @@ -#ifndef GOST_TOOLS_H -# define GOST_TOOLS_H -/********************************************************************** - * gost_lcl.h * - * Copyright (c) 2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Internal declarations used in GOST engine * - * OpenSSL 0.9.9 libraries required to compile and use * - * this code * - **********************************************************************/ -# include "bn.h" -# include "evp.h" -# include "dsa.h" -# include "asn1t.h" -# include "x509.h" -# include "engine.h" -# include "ec.h" -# include "gost89.h" -# include "gosthash.h" -/* Control commands */ -# define GOST_PARAM_CRYPT_PARAMS 0 -# define GOST_PARAM_MAX 0 -# define GOST_CTRL_CRYPT_PARAMS (ENGINE_CMD_BASE+GOST_PARAM_CRYPT_PARAMS) - -extern const ENGINE_CMD_DEFN gost_cmds[]; -int gost_control_func(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); -const char *get_gost_engine_param(int param); -int gost_set_default_param(int param, const char *value); -void gost_param_free(void); - -/* method registration */ - -int register_ameth_gost(int nid, EVP_PKEY_ASN1_METHOD **ameth, - const char *pemstr, const char *info); -int register_pmeth_gost(int id, EVP_PKEY_METHOD **pmeth, int flags); - -/* Gost-specific pmeth control-function parameters */ -/* For GOST R34.10 parameters */ -# define param_ctrl_string "paramset" -# define EVP_PKEY_CTRL_GOST_PARAMSET (EVP_PKEY_ALG_CTRL+1) -/* For GOST 28147 MAC */ -# define key_ctrl_string "key" -# define hexkey_ctrl_string "hexkey" -# define EVP_PKEY_CTRL_GOST_MAC_HEXKEY (EVP_PKEY_ALG_CTRL+3) -/* Pmeth internal representation */ -struct gost_pmeth_data { - int sign_param_nid; /* Should be set whenever parameters are - * filled */ - EVP_MD *md; - unsigned char *shared_ukm; - int peer_key_used; -}; - -struct gost_mac_pmeth_data { - int key_set; - EVP_MD *md; - unsigned char key[32]; -}; -/* GOST-specific ASN1 structures */ - -typedef struct { - ASN1_OCTET_STRING *encrypted_key; - ASN1_OCTET_STRING *imit; -} GOST_KEY_INFO; - -DECLARE_ASN1_FUNCTIONS(GOST_KEY_INFO) - -typedef struct { - ASN1_OBJECT *cipher; - X509_PUBKEY *ephem_key; - ASN1_OCTET_STRING *eph_iv; -} GOST_KEY_AGREEMENT_INFO; - -DECLARE_ASN1_FUNCTIONS(GOST_KEY_AGREEMENT_INFO) - -typedef struct { - GOST_KEY_INFO *key_info; - GOST_KEY_AGREEMENT_INFO *key_agreement_info; -} GOST_KEY_TRANSPORT; - -DECLARE_ASN1_FUNCTIONS(GOST_KEY_TRANSPORT) - -typedef struct { /* FIXME incomplete */ - GOST_KEY_TRANSPORT *gkt; -} GOST_CLIENT_KEY_EXCHANGE_PARAMS; - -/* - * Hacks to shorten symbols to 31 characters or less, or OpenVMS. This mimics - * what's done in symhacks.h, but since this is a very local header file, I - * prefered to put this hack directly here. -- Richard Levitte - */ -# ifdef OPENSSL_SYS_VMS -# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_it -# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_it GOST_CLIENT_KEY_EXC_PARAMS_it -# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_new -# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_new GOST_CLIENT_KEY_EXC_PARAMS_new -# undef GOST_CLIENT_KEY_EXCHANGE_PARAMS_free -# define GOST_CLIENT_KEY_EXCHANGE_PARAMS_free GOST_CLIENT_KEY_EXC_PARAMS_free -# undef d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS -# define d2i_GOST_CLIENT_KEY_EXCHANGE_PARAMS d2i_GOST_CLIENT_KEY_EXC_PARAMS -# undef i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS -# define i2d_GOST_CLIENT_KEY_EXCHANGE_PARAMS i2d_GOST_CLIENT_KEY_EXC_PARAMS -# endif /* End of hack */ -DECLARE_ASN1_FUNCTIONS(GOST_CLIENT_KEY_EXCHANGE_PARAMS) -typedef struct { - ASN1_OBJECT *key_params; - ASN1_OBJECT *hash_params; - ASN1_OBJECT *cipher_params; -} GOST_KEY_PARAMS; - -DECLARE_ASN1_FUNCTIONS(GOST_KEY_PARAMS) - -typedef struct { - ASN1_OCTET_STRING *iv; - ASN1_OBJECT *enc_param_set; -} GOST_CIPHER_PARAMS; - -DECLARE_ASN1_FUNCTIONS(GOST_CIPHER_PARAMS) -/*============== Message digest and cipher related structures ==========*/ - /* - * Structure used as EVP_MD_CTX-md_data. It allows to avoid storing - * in the md-data pointers to dynamically allocated memory. I - * cannot invent better way to avoid memory leaks, because openssl - * insist on invoking Init on Final-ed digests, and there is no - * reliable way to find out whether pointer in the passed md_data is - * valid or not. - */ -struct ossl_gost_digest_ctx { - gost_hash_ctx dctx; - gost_ctx cctx; -}; -/* EVP_MD structure for GOST R 34.11 */ -extern EVP_MD digest_gost; -/* EVP_MD structure for GOST 28147 in MAC mode */ -extern EVP_MD imit_gost_cpa; -/* Cipher context used for EVP_CIPHER operation */ -struct ossl_gost_cipher_ctx { - int paramNID; - unsigned int count; - int key_meshing; - gost_ctx cctx; -}; -/* Structure to map parameter NID to S-block */ -struct gost_cipher_info { - int nid; - gost_subst_block *sblock; - int key_meshing; -}; -/* Context for MAC */ -struct ossl_gost_imit_ctx { - gost_ctx cctx; - unsigned char buffer[8]; - unsigned char partial_block[8]; - unsigned int count; - int key_meshing; - int bytes_left; - int key_set; -}; -/* Table which maps parameter NID to S-blocks */ -extern struct gost_cipher_info gost_cipher_list[]; -/* Find encryption params from ASN1_OBJECT */ -const struct gost_cipher_info *get_encryption_params(ASN1_OBJECT *obj); -/* Implementation of GOST 28147-89 cipher in CFB and CNT modes */ -extern EVP_CIPHER cipher_gost; -extern EVP_CIPHER cipher_gost_cpacnt; -# define EVP_MD_CTRL_KEY_LEN (EVP_MD_CTRL_ALG_CTRL+3) -# define EVP_MD_CTRL_SET_KEY (EVP_MD_CTRL_ALG_CTRL+4) -/* EVP_PKEY_METHOD key encryption callbacks */ -/* From gost94_keyx.c */ -int pkey_GOST94cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *key, - size_t key_len); - -int pkey_GOST94cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t in_len); -/* From gost2001_keyx.c */ -int pkey_GOST01cp_encrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *key, - size_t key_len); - -int pkey_GOST01cp_decrypt(EVP_PKEY_CTX *ctx, unsigned char *out, - size_t *outlen, const unsigned char *in, - size_t in_len); -/* derive functions */ -/* From gost2001_keyx.c */ -int pkey_gost2001_derive(EVP_PKEY_CTX *ctx, unsigned char *key, - size_t *keylen); -/* From gost94_keyx.c */ -int pkey_gost94_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); -/* Internal functions for signature algorithms */ -int fill_GOST94_params(DSA *dsa, int nid); -int fill_GOST2001_params(EC_KEY *eckey, int nid); -int gost_sign_keygen(DSA *dsa); -int gost2001_keygen(EC_KEY *ec); - -DSA_SIG *gost_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); -DSA_SIG *gost2001_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey); - -int gost_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, DSA *dsa); -int gost2001_do_verify(const unsigned char *dgst, int dgst_len, - DSA_SIG *sig, EC_KEY *ec); -int gost2001_compute_public(EC_KEY *ec); -int gost94_compute_public(DSA *dsa); -/*============== miscellaneous functions============================= */ -/* from gost_sign.c */ -/* Convert GOST R 34.11 hash sum to bignum according to standard */ -BIGNUM *hashsum2bn(const unsigned char *dgst); -/* - * Store bignum in byte array of given length, prepending by zeros if - * nesseccary - */ -int store_bignum(BIGNUM *bn, unsigned char *buf, int len); -/* Read bignum, which can have few MSB all-zeros from buffer*/ -BIGNUM *getbnfrombuf(const unsigned char *buf, size_t len); -/* Pack GOST R 34.10 signature according to CryptoPro rules */ -int pack_sign_cp(DSA_SIG *s, int order, unsigned char *sig, size_t *siglen); -/* Unpack GOST R 34.10 signature according to CryptoPro rules */ -DSA_SIG *unpack_cp_signature(const unsigned char *sig, size_t siglen); -/* from ameth.c */ -/* Get private key as BIGNUM from both R 34.10-94 and R 34.10-2001 keys*/ -/* Returns pointer into EVP_PKEY structure */ -BIGNUM *gost_get0_priv_key(const EVP_PKEY *pkey); -/* Find NID by GOST 94 parameters */ -int gost94_nid_by_params(DSA *p); - -#endif diff --git a/Sources/COpenSSL/gost_params.h b/Sources/COpenSSL/gost_params.h deleted file mode 100644 index 0773cbfa..00000000 --- a/Sources/COpenSSL/gost_params.h +++ /dev/null @@ -1,34 +0,0 @@ -/********************************************************************** - * gost_params.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declaration of structures used to represent GOST R 34.10 * - * parameter sets, defined in RFC 4357 * - * OpenSSL 0.9.9 libraries required to compile and use * - * this code * - **********************************************************************/ -#ifndef GOST_PARAMSET_H -# define GOST_PARAMSET_H -typedef struct R3410 { - int nid; - char *a; - char *p; - char *q; -} R3410_params; - -extern R3410_params R3410_paramset[]; - -typedef struct R3410_2001 { - int nid; - char *a; - char *b; - char *p; - char *q; - char *x; - char *y; -} R3410_2001_params; - -extern R3410_2001_params R3410_2001_paramset[]; - -#endif diff --git a/Sources/COpenSSL/gosthash.c b/Sources/COpenSSL/gosthash.c deleted file mode 100644 index c2ce919e..00000000 --- a/Sources/COpenSSL/gosthash.c +++ /dev/null @@ -1,269 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/********************************************************************** - * gosthash.c * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Implementation of GOST R 34.11-94 hash function * - * uses on gost89.c and gost89.h Doesn't need OpenSSL * - **********************************************************************/ -#include - -#include "gost89.h" -#include "gosthash.h" - -/* - * Use OPENSSL_malloc for memory allocation if compiled with - * -DOPENSSL_BUILD, and libc malloc otherwise - */ -#ifndef MYALLOC -# ifdef OPENSSL_BUILD -# include "crypto.h" -# define MYALLOC(size) OPENSSL_malloc(size) -# define MYFREE(ptr) OPENSSL_free(ptr) -# else -# define MYALLOC(size) malloc(size) -# define MYFREE(ptr) free(ptr) -# endif -#endif -/* - * Following functions are various bit meshing routines used in GOST R - * 34.11-94 algorithms - */ -static void swap_bytes(byte * w, byte * k) -{ - int i, j; - for (i = 0; i < 4; i++) - for (j = 0; j < 8; j++) - k[i + 4 * j] = w[8 * i + j]; - -} - -/* was A_A */ -static void circle_xor8(const byte * w, byte * k) -{ - byte buf[8]; - int i; - memcpy(buf, w, 8); - memmove(k, w + 8, 24); - for (i = 0; i < 8; i++) - k[i + 24] = buf[i] ^ k[i]; -} - -/* was R_R */ -static void transform_3(byte * data) -{ - unsigned short int acc; - acc = (data[0] ^ data[2] ^ data[4] ^ data[6] ^ data[24] ^ data[30]) | - ((data[1] ^ data[3] ^ data[5] ^ data[7] ^ data[25] ^ data[31]) << 8); - memmove(data, data + 2, 30); - data[30] = acc & 0xff; - data[31] = acc >> 8; -} - -/* Adds blocks of N bytes modulo 2**(8*n). Returns carry*/ -static int add_blocks(int n, byte * left, const byte * right) -{ - int i; - int carry = 0; - int sum; - for (i = 0; i < n; i++) { - sum = (int)left[i] + (int)right[i] + carry; - left[i] = sum & 0xff; - carry = sum >> 8; - } - return carry; -} - -/* Xor two sequences of bytes */ -static void xor_blocks(byte * result, const byte * a, const byte * b, - size_t len) -{ - size_t i; - for (i = 0; i < len; i++) - result[i] = a[i] ^ b[i]; -} - -/* - * Calculate H(i+1) = Hash(Hi,Mi) - * Where H and M are 32 bytes long - */ -static int hash_step(gost_ctx * c, byte * H, const byte * M) -{ - byte U[32], W[32], V[32], S[32], Key[32]; - int i; - /* Compute first key */ - xor_blocks(W, H, M, 32); - swap_bytes(W, Key); - /* Encrypt first 8 bytes of H with first key */ - gost_enc_with_key(c, Key, H, S); - /* Compute second key */ - circle_xor8(H, U); - circle_xor8(M, V); - circle_xor8(V, V); - xor_blocks(W, U, V, 32); - swap_bytes(W, Key); - /* encrypt second 8 bytes of H with second key */ - gost_enc_with_key(c, Key, H + 8, S + 8); - /* compute third key */ - circle_xor8(U, U); - U[31] = ~U[31]; - U[29] = ~U[29]; - U[28] = ~U[28]; - U[24] = ~U[24]; - U[23] = ~U[23]; - U[20] = ~U[20]; - U[18] = ~U[18]; - U[17] = ~U[17]; - U[14] = ~U[14]; - U[12] = ~U[12]; - U[10] = ~U[10]; - U[8] = ~U[8]; - U[7] = ~U[7]; - U[5] = ~U[5]; - U[3] = ~U[3]; - U[1] = ~U[1]; - circle_xor8(V, V); - circle_xor8(V, V); - xor_blocks(W, U, V, 32); - swap_bytes(W, Key); - /* encrypt third 8 bytes of H with third key */ - gost_enc_with_key(c, Key, H + 16, S + 16); - /* Compute fourth key */ - circle_xor8(U, U); - circle_xor8(V, V); - circle_xor8(V, V); - xor_blocks(W, U, V, 32); - swap_bytes(W, Key); - /* Encrypt last 8 bytes with fourth key */ - gost_enc_with_key(c, Key, H + 24, S + 24); - for (i = 0; i < 12; i++) - transform_3(S); - xor_blocks(S, S, M, 32); - transform_3(S); - xor_blocks(S, S, H, 32); - for (i = 0; i < 61; i++) - transform_3(S); - memcpy(H, S, 32); - return 1; -} - -/* - * Initialize gost_hash ctx - cleans up temporary structures and set up - * substitution blocks - */ -int init_gost_hash_ctx(gost_hash_ctx * ctx, - const gost_subst_block * subst_block) -{ - memset(ctx, 0, sizeof(gost_hash_ctx)); - ctx->cipher_ctx = (gost_ctx *) MYALLOC(sizeof(gost_ctx)); - if (!ctx->cipher_ctx) { - return 0; - } - gost_init(ctx->cipher_ctx, subst_block); - return 1; -} - -/* - * Free cipher CTX if it is dynamically allocated. Do not use - * if cipher ctx is statically allocated as in OpenSSL implementation of - * GOST hash algroritm - * - */ -void done_gost_hash_ctx(gost_hash_ctx * ctx) -{ - /* - * No need to use gost_destroy, because cipher keys are not really secret - * when hashing - */ - MYFREE(ctx->cipher_ctx); -} - -/* - * reset state of hash context to begin hashing new message - */ -int start_hash(gost_hash_ctx * ctx) -{ - if (!ctx->cipher_ctx) - return 0; - memset(&(ctx->H), 0, 32); - memset(&(ctx->S), 0, 32); - ctx->len = 0L; - ctx->left = 0; - return 1; -} - -/* - * Hash block of arbitrary length - * - * - */ -int hash_block(gost_hash_ctx * ctx, const byte * block, size_t length) -{ - if (ctx->left) { - /* - * There are some bytes from previous step - */ - unsigned int add_bytes = 32 - ctx->left; - if (add_bytes > length) { - add_bytes = length; - } - memcpy(&(ctx->remainder[ctx->left]), block, add_bytes); - ctx->left += add_bytes; - if (ctx->left < 32) { - return 1; - } - block += add_bytes; - length -= add_bytes; - hash_step(ctx->cipher_ctx, ctx->H, ctx->remainder); - add_blocks(32, ctx->S, ctx->remainder); - ctx->len += 32; - ctx->left = 0; - } - while (length >= 32) { - hash_step(ctx->cipher_ctx, ctx->H, block); - - add_blocks(32, ctx->S, block); - ctx->len += 32; - block += 32; - length -= 32; - } - if (length) { - memcpy(ctx->remainder, block, ctx->left = length); - } - return 1; -} - -/* - * Compute hash value from current state of ctx - * state of hash ctx becomes invalid and cannot be used for further - * hashing. - */ -int finish_hash(gost_hash_ctx * ctx, byte * hashval) -{ - byte buf[32]; - byte H[32]; - byte S[32]; - ghosthash_len fin_len = ctx->len; - byte *bptr; - memcpy(H, ctx->H, 32); - memcpy(S, ctx->S, 32); - if (ctx->left) { - memset(buf, 0, 32); - memcpy(buf, ctx->remainder, ctx->left); - hash_step(ctx->cipher_ctx, H, buf); - add_blocks(32, S, buf); - fin_len += ctx->left; - } - memset(buf, 0, 32); - bptr = buf; - fin_len <<= 3; /* Hash length in BITS!! */ - while (fin_len > 0) { - *(bptr++) = (byte) (fin_len & 0xFF); - fin_len >>= 8; - }; - hash_step(ctx->cipher_ctx, H, buf); - hash_step(ctx->cipher_ctx, H, S); - memcpy(hashval, H, 32); - return 1; -} diff --git a/Sources/COpenSSL/gosthash.h b/Sources/COpenSSL/gosthash.h deleted file mode 100644 index 003e668e..00000000 --- a/Sources/COpenSSL/gosthash.h +++ /dev/null @@ -1,52 +0,0 @@ -/********************************************************************** - * gosthash.h * - * Copyright (c) 2005-2006 Cryptocom LTD * - * This file is distributed under the same license as OpenSSL * - * * - * Declaration of GOST R 34.11-94 hash functions * - * uses and gost89.h Doesn't need OpenSSL * - **********************************************************************/ -#ifndef GOSTHASH_H -# define GOSTHASH_H -# include "gost89.h" -# include - -# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) -typedef __int64 ghosthash_len; -# elif defined(__arch64__) -typedef long ghosthash_len; -# else -typedef long long ghosthash_len; -# endif - -typedef struct gost_hash_ctx { - ghosthash_len len; - gost_ctx *cipher_ctx; - int left; - byte H[32]; - byte S[32]; - byte remainder[32]; -} gost_hash_ctx; - -/* Initalizes gost hash ctx, including creation of gost cipher ctx */ - -int init_gost_hash_ctx(gost_hash_ctx * ctx, - const gost_subst_block * subst_block); -void done_gost_hash_ctx(gost_hash_ctx * ctx); - -/* - * Cleans up all fields, except cipher ctx preparing ctx for computing of new - * hash value - */ -int start_hash(gost_hash_ctx * ctx); - -/* Hashes block of data */ -int hash_block(gost_hash_ctx * ctx, const byte * block, size_t length); - -/* - * Finalizes computation of hash and fills buffer (which should be at least - * 32 bytes long) with value of computed hash. - */ -int finish_hash(gost_hash_ctx * ctx, byte * hashval); - -#endif diff --git a/Sources/COpenSSL/hm_.c b/Sources/COpenSSL/hm_.c deleted file mode 100644 index 90be770a..00000000 --- a/Sources/COpenSSL/hm_.c +++ /dev/null @@ -1,433 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2007. - */ -/* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "asn1_locl.h" - -#define HMAC_TEST_PRIVATE_KEY_FORMAT - -/* - * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output - * length and to free up an HMAC key. - */ - -static int hmac_size(const EVP_PKEY *pkey) -{ - return EVP_MAX_MD_SIZE; -} - -static void hmac_key_free(EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; - if (os) { - if (os->data) - OPENSSL_cleanse(os->data, os->length); - ASN1_OCTET_STRING_free(os); - } -} - -static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - switch (op) { - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_sha256; - return 1; - - default: - return -2; - } -} - -#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT -/* - * A bogus private key format for test purposes. This is simply the HMAC key - * with "HMAC PRIVATE KEY" in the headers. When enabled the genpkey utility - * can be used to "generate" HMAC keys. - */ - -static int old_hmac_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) -{ - ASN1_OCTET_STRING *os; - os = ASN1_OCTET_STRING_new(); - if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen)) - goto err; - if (!EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os)) - goto err; - return 1; - - err: - ASN1_OCTET_STRING_free(os); - return 0; -} - -static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - int inc; - ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; - if (pder) { - if (!*pder) { - *pder = OPENSSL_malloc(os->length); - inc = 0; - } else - inc = 1; - - memcpy(*pder, os->data, os->length); - - if (inc) - *pder += os->length; - } - - return os->length; -} - -#endif - -const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { - EVP_PKEY_HMAC, - EVP_PKEY_HMAC, - 0, - - "HMAC", - "OpenSSL HMAC method", - - 0, 0, 0, 0, - - 0, 0, 0, - - hmac_size, - 0, - 0, 0, 0, 0, 0, 0, 0, - - hmac_key_free, - hmac_pkey_ctrl, -#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT - old_hmac_decode, - old_hmac_encode -#else - 0, 0 -#endif -}; -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2007. - */ -/* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -#include "x509.h" -#include "x509v3.h" -// #include "evp.h" -#include "hmac.h" -#include "evp_locl.h" - -/* HMAC pkey context structure */ - -typedef struct { - const EVP_MD *md; /* MD for HMAC use */ - ASN1_OCTET_STRING ktmp; /* Temp storage for key */ - HMAC_CTX ctx; -} HMAC_PKEY_CTX; - -static int pkey_hmac_init(EVP_PKEY_CTX *ctx) -{ - HMAC_PKEY_CTX *hctx; - hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX)); - if (!hctx) - return 0; - hctx->md = NULL; - hctx->ktmp.data = NULL; - hctx->ktmp.length = 0; - hctx->ktmp.flags = 0; - hctx->ktmp.type = V_ASN1_OCTET_STRING; - HMAC_CTX_init(&hctx->ctx); - - ctx->data = hctx; - ctx->keygen_info_count = 0; - - return 1; -} - -static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - HMAC_PKEY_CTX *sctx, *dctx; - if (!pkey_hmac_init(dst)) - return 0; - sctx = src->data; - dctx = dst->data; - dctx->md = sctx->md; - if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx)) - goto err; - if (sctx->ktmp.data != NULL) { - if (!ASN1_OCTET_STRING_set(&dctx->ktmp, - sctx->ktmp.data, sctx->ktmp.length)) - goto err; - } - return 1; - err: - HMAC_CTX_cleanup(&dctx->ctx); - OPENSSL_free(dctx); - return 0; -} - -static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) -{ - HMAC_PKEY_CTX *hctx = ctx->data; - HMAC_CTX_cleanup(&hctx->ctx); - if (hctx->ktmp.data) { - if (hctx->ktmp.length) - OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length); - OPENSSL_free(hctx->ktmp.data); - hctx->ktmp.data = NULL; - } - OPENSSL_free(hctx); -} - -static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - ASN1_OCTET_STRING *hkey = NULL; - HMAC_PKEY_CTX *hctx = ctx->data; - if (!hctx->ktmp.data) - return 0; - hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); - if (!hkey) - return 0; - EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); - - return 1; -} - -static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - HMAC_PKEY_CTX *hctx = ctx->pctx->data; - if (!HMAC_Update(&hctx->ctx, data, count)) - return 0; - return 1; -} - -static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) -{ - HMAC_PKEY_CTX *hctx = ctx->data; - HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT); - EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); - mctx->update = int_update; - return 1; -} - -static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, - EVP_MD_CTX *mctx) -{ - unsigned int hlen; - HMAC_PKEY_CTX *hctx = ctx->data; - int l = EVP_MD_CTX_size(mctx); - - if (l < 0) - return 0; - *siglen = l; - if (!sig) - return 1; - - if (!HMAC_Final(&hctx->ctx, sig, &hlen)) - return 0; - *siglen = (size_t)hlen; - return 1; -} - -static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - HMAC_PKEY_CTX *hctx = ctx->data; - ASN1_OCTET_STRING *key; - switch (type) { - - case EVP_PKEY_CTRL_SET_MAC_KEY: - if ((!p2 && p1 > 0) || (p1 < -1)) - return 0; - if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) - return 0; - break; - - case EVP_PKEY_CTRL_MD: - hctx->md = p2; - break; - - case EVP_PKEY_CTRL_DIGESTINIT: - key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; - if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, - ctx->engine)) - return 0; - break; - - default: - return -2; - - } - return 1; -} - -static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!value) { - return 0; - } - if (!strcmp(type, "key")) { - void *p = (void *)value; - return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p); - } - if (!strcmp(type, "hexkey")) { - unsigned char *key; - int r; - long keylen; - key = string_to_hex(value, &keylen); - if (!key) - return 0; - r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); - OPENSSL_free(key); - return r; - } - return -2; -} - -const EVP_PKEY_METHOD hmac_pkey_meth = { - EVP_PKEY_HMAC, - 0, - pkey_hmac_init, - pkey_hmac_copy, - pkey_hmac_cleanup, - - 0, 0, - - 0, - pkey_hmac_keygen, - - 0, 0, - - 0, 0, - - 0, 0, - - hmac_signctx_init, - hmac_signctx, - - 0, 0, - - 0, 0, - - 0, 0, - - 0, 0, - - pkey_hmac_ctrl, - pkey_hmac_ctrl_str -}; diff --git a/Sources/COpenSSL/hmac.c b/Sources/COpenSSL/hmac.c deleted file mode 100644 index f1b6d081..00000000 --- a/Sources/COpenSSL/hmac.c +++ /dev/null @@ -1,269 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/hmac/hmac.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -#include -#include -#include -#include "cryptlib.h" -#include "hmac.h" - -#ifdef OPENSSL_FIPS -# include -#endif - -int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, - const EVP_MD *md, ENGINE *impl) -{ - int i, j, reset = 0; - unsigned char pad[HMAC_MAX_MD_CBLOCK]; - -#ifdef OPENSSL_FIPS - /* If FIPS mode switch to approved implementation if possible */ - if (FIPS_mode()) { - const EVP_MD *fipsmd; - if (md) { - fipsmd = FIPS_get_digestbynid(EVP_MD_type(md)); - if (fipsmd) - md = fipsmd; - } - } - - if (FIPS_mode()) { - /* If we have an ENGINE need to allow non FIPS */ - if ((impl || ctx->i_ctx.engine) - && !(ctx->i_ctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { - EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS); - return 0; - } - /* - * Other algorithm blocking will be done in FIPS_cmac_init, via - * FIPS_hmac_init_ex(). - */ - if (!impl && !ctx->i_ctx.engine) - return FIPS_hmac_init_ex(ctx, key, len, md, NULL); - } -#endif - /* If we are changing MD then we must have a key */ - if (md != NULL && md != ctx->md && (key == NULL || len < 0)) - return 0; - - if (md != NULL) { - reset = 1; - ctx->md = md; - } else if (ctx->md) { - md = ctx->md; - } else { - return 0; - } - - if (key != NULL) { - reset = 1; - j = EVP_MD_block_size(md); - OPENSSL_assert(j <= (int)sizeof(ctx->key)); - if (j < len) { - if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl)) - goto err; - if (!EVP_DigestUpdate(&ctx->md_ctx, key, len)) - goto err; - if (!EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key, - &ctx->key_length)) - goto err; - } else { - if (len < 0 || len > (int)sizeof(ctx->key)) - return 0; - memcpy(ctx->key, key, len); - ctx->key_length = len; - } - if (ctx->key_length != HMAC_MAX_MD_CBLOCK) - memset(&ctx->key[ctx->key_length], 0, - HMAC_MAX_MD_CBLOCK - ctx->key_length); - } - - if (reset) { - for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) - pad[i] = 0x36 ^ ctx->key[i]; - if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl)) - goto err; - if (!EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) - goto err; - - for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) - pad[i] = 0x5c ^ ctx->key[i]; - if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl)) - goto err; - if (!EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) - goto err; - } - if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) - goto err; - return 1; - err: - return 0; -} - -int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) -{ - if (key && md) - HMAC_CTX_init(ctx); - return HMAC_Init_ex(ctx, key, len, md, NULL); -} - -int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) - return FIPS_hmac_update(ctx, data, len); -#endif - if (!ctx->md) - return 0; - - return EVP_DigestUpdate(&ctx->md_ctx, data, len); -} - -int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) -{ - unsigned int i; - unsigned char buf[EVP_MAX_MD_SIZE]; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) - return FIPS_hmac_final(ctx, md, len); -#endif - - if (!ctx->md) - goto err; - - if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i)) - goto err; - if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx)) - goto err; - if (!EVP_DigestUpdate(&ctx->md_ctx, buf, i)) - goto err; - if (!EVP_DigestFinal_ex(&ctx->md_ctx, md, len)) - goto err; - return 1; - err: - return 0; -} - -void HMAC_CTX_init(HMAC_CTX *ctx) -{ - EVP_MD_CTX_init(&ctx->i_ctx); - EVP_MD_CTX_init(&ctx->o_ctx); - EVP_MD_CTX_init(&ctx->md_ctx); - ctx->md = NULL; -} - -int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) -{ - if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx)) - goto err; - if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx)) - goto err; - if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx)) - goto err; - memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK); - dctx->key_length = sctx->key_length; - dctx->md = sctx->md; - return 1; - err: - return 0; -} - -void HMAC_CTX_cleanup(HMAC_CTX *ctx) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !ctx->i_ctx.engine) { - FIPS_hmac_ctx_cleanup(ctx); - return; - } -#endif - EVP_MD_CTX_cleanup(&ctx->i_ctx); - EVP_MD_CTX_cleanup(&ctx->o_ctx); - EVP_MD_CTX_cleanup(&ctx->md_ctx); - OPENSSL_cleanse(ctx, sizeof(*ctx)); -} - -unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, - const unsigned char *d, size_t n, unsigned char *md, - unsigned int *md_len) -{ - HMAC_CTX c; - static unsigned char m[EVP_MAX_MD_SIZE]; - - if (md == NULL) - md = m; - HMAC_CTX_init(&c); - if (!HMAC_Init(&c, key, key_len, evp_md)) - goto err; - if (!HMAC_Update(&c, d, n)) - goto err; - if (!HMAC_Final(&c, md, md_len)) - goto err; - HMAC_CTX_cleanup(&c); - return md; - err: - HMAC_CTX_cleanup(&c); - return NULL; -} - -void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) -{ - EVP_MD_CTX_set_flags(&ctx->i_ctx, flags); - EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); - EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); -} diff --git a/Sources/COpenSSL/hmac.h b/Sources/COpenSSL/hmac.h deleted file mode 100644 index b7e0ed1c..00000000 --- a/Sources/COpenSSL/hmac.h +++ /dev/null @@ -1,109 +0,0 @@ -/* crypto/hmac/hmac.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -#ifndef HEADER_HMAC_H -# define HEADER_HMAC_H - -# include "opensslconf.h" - -# ifdef OPENSSL_NO_HMAC -# error HMAC is disabled. -# endif - -# include "evp.h" - -# define HMAC_MAX_MD_CBLOCK 128/* largest known is SHA512 */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct hmac_ctx_st { - const EVP_MD *md; - EVP_MD_CTX md_ctx; - EVP_MD_CTX i_ctx; - EVP_MD_CTX o_ctx; - unsigned int key_length; - unsigned char key[HMAC_MAX_MD_CBLOCK]; -} HMAC_CTX; - -# define HMAC_size(e) (EVP_MD_size((e)->md)) - -void HMAC_CTX_init(HMAC_CTX *ctx); -void HMAC_CTX_cleanup(HMAC_CTX *ctx); - -/* deprecated */ -# define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) - -/* deprecated */ -int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md); -int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, - const EVP_MD *md, ENGINE *impl); -int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); -int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); -unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, - const unsigned char *d, size_t n, unsigned char *md, - unsigned int *md_len); -int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); - -void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/hw_4758_cca.h b/Sources/COpenSSL/hw_4758_cca.h deleted file mode 100644 index 235543ad..00000000 --- a/Sources/COpenSSL/hw_4758_cca.h +++ /dev/null @@ -1,150 +0,0 @@ -/**********************************************************************/ -/* */ -/* Prototypes of the CCA verbs used by the 4758 CCA openssl driver */ -/* */ -/* Maurice Gittens */ -/* */ -/**********************************************************************/ - -#ifndef __HW_4758_CCA__ -# define __HW_4758_CCA__ - -/* - * Only WIN32 support for now - */ -# if defined(WIN32) - -# define CCA_LIB_NAME "CSUNSAPI" - -# define CSNDPKX "CSNDPKX_32" -# define CSNDKRR "CSNDKRR_32" -# define CSNDPKE "CSNDPKE_32" -# define CSNDPKD "CSNDPKD_32" -# define CSNDDSV "CSNDDSV_32" -# define CSNDDSG "CSNDDSG_32" -# define CSNBRNG "CSNBRNG_32" - -# define SECURITYAPI __stdcall -# else - /* - * Fixme!! Find out the values of these constants for other platforms. - */ -# define CCA_LIB_NAME "CSUNSAPI" - -# define CSNDPKX "CSNDPKX" -# define CSNDKRR "CSNDKRR" -# define CSNDPKE "CSNDPKE" -# define CSNDPKD "CSNDPKD" -# define CSNDDSV "CSNDDSV" -# define CSNDDSG "CSNDDSG" -# define CSNBRNG "CSNBRNG" - -# define SECURITYAPI -# endif - -/* - * security API prototypes - */ - -/* PKA Key Record Read */ -typedef void (SECURITYAPI * F_KEYRECORDREAD) - (long *return_code, - long *reason_code, - long *exit_data_length, - unsigned char *exit_data, - long *rule_array_count, - unsigned char *rule_array, - unsigned char *key_label, long *key_token_length, unsigned char *key_token); - -/* Random Number Generate */ -typedef void (SECURITYAPI * F_RANDOMNUMBERGENERATE) - (long *return_code, - long *reason_code, - long *exit_data_length, - unsigned char *exit_data, - unsigned char *form, unsigned char *random_number); - -/* Digital Signature Generate */ -typedef void (SECURITYAPI * F_DIGITALSIGNATUREGENERATE) - (long *return_code, - long *reason_code, - long *exit_data_length, - unsigned char *exit_data, - long *rule_array_count, - unsigned char *rule_array, - long *PKA_private_key_id_length, - unsigned char *PKA_private_key_id, - long *hash_length, - unsigned char *hash, - long *signature_field_length, - long *signature_bit_length, unsigned char *signature_field); - -/* Digital Signature Verify */ -typedef void (SECURITYAPI * F_DIGITALSIGNATUREVERIFY) (long *return_code, - long *reason_code, - long *exit_data_length, - unsigned char - *exit_data, - long *rule_array_count, - unsigned char - *rule_array, - long - *PKA_public_key_id_length, - unsigned char - *PKA_public_key_id, - long *hash_length, - unsigned char *hash, - long - *signature_field_length, - unsigned char - *signature_field); - -/* PKA Public Key Extract */ -typedef void (SECURITYAPI * F_PUBLICKEYEXTRACT) (long *return_code, - long *reason_code, - long *exit_data_length, - unsigned char *exit_data, - long *rule_array_count, - unsigned char *rule_array, - long - *source_key_identifier_length, - unsigned char - *source_key_identifier, - long - *target_key_token_length, - unsigned char - *target_key_token); - -/* PKA Encrypt */ -typedef void (SECURITYAPI * F_PKAENCRYPT) - (long *return_code, - long *reason_code, - long *exit_data_length, - unsigned char *exit_data, - long *rule_array_count, - unsigned char *rule_array, - long *key_value_length, - unsigned char *key_value, - long *data_struct_length, - unsigned char *data_struct, - long *RSA_public_key_length, - unsigned char *RSA_public_key, - long *RSA_encipher_length, unsigned char *RSA_encipher); - -/* PKA Decrypt */ -typedef void (SECURITYAPI * F_PKADECRYPT) - (long *return_code, - long *reason_code, - long *exit_data_length, - unsigned char *exit_data, - long *rule_array_count, - unsigned char *rule_array, - long *enciphered_key_length, - unsigned char *enciphered_key, - long *data_struct_length, - unsigned char *data_struct, - long *RSA_private_key_length, - unsigned char *RSA_private_key, - long *key_value_length, unsigned char *key_value); - -#endif diff --git a/Sources/COpenSSL/hw_ubsec.h b/Sources/COpenSSL/hw_ubsec.h deleted file mode 100644 index a4e67fc5..00000000 --- a/Sources/COpenSSL/hw_ubsec.h +++ /dev/null @@ -1,124 +0,0 @@ -/****************************************************************************** - * - * Copyright 2000 - * Broadcom Corporation - * 16215 Alton Parkway - * PO Box 57013 - * Irvine CA 92619-7013 - * - *****************************************************************************/ -/* - * Broadcom Corporation uBSec SDK - */ -/* - * Character device header file. - */ -/* - * Revision History: - * - * October 2000 JTT Created. - */ - -#define MAX_PUBLIC_KEY_BITS (1024) -#define MAX_PUBLIC_KEY_BYTES (1024/8) -#define SHA_BIT_SIZE (160) -#define MAX_CRYPTO_KEY_LENGTH 24 -#define MAX_MAC_KEY_LENGTH 64 -#define UBSEC_CRYPTO_DEVICE_NAME ((unsigned char *)"/dev/ubscrypt") -#define UBSEC_KEY_DEVICE_NAME ((unsigned char *)"/dev/ubskey") - -/* Math command types. */ -#define UBSEC_MATH_MODADD 0x0001 -#define UBSEC_MATH_MODSUB 0x0002 -#define UBSEC_MATH_MODMUL 0x0004 -#define UBSEC_MATH_MODEXP 0x0008 -#define UBSEC_MATH_MODREM 0x0010 -#define UBSEC_MATH_MODINV 0x0020 - -typedef long ubsec_MathCommand_t; -typedef long ubsec_RNGCommand_t; - -typedef struct ubsec_crypto_context_s { - unsigned int flags; - unsigned char crypto[MAX_CRYPTO_KEY_LENGTH]; - unsigned char auth[MAX_MAC_KEY_LENGTH]; -} ubsec_crypto_context_t, *ubsec_crypto_context_p; - -/* - * Predeclare the function pointer types that we dynamically load from the DSO. - */ - -typedef int t_UBSEC_ubsec_bytes_to_bits(unsigned char *n, int bytes); - -typedef int t_UBSEC_ubsec_bits_to_bytes(int bits); - -typedef int t_UBSEC_ubsec_open(unsigned char *device); - -typedef int t_UBSEC_ubsec_close(int fd); - -typedef int t_UBSEC_diffie_hellman_generate_ioctl(int fd, - unsigned char *x, - int *x_len, - unsigned char *y, - int *y_len, - unsigned char *g, int g_len, - unsigned char *m, int m_len, - unsigned char *userX, - int userX_len, - int random_bits); - -typedef int t_UBSEC_diffie_hellman_agree_ioctl(int fd, - unsigned char *x, int x_len, - unsigned char *y, int y_len, - unsigned char *m, int m_len, - unsigned char *k, int *k_len); - -typedef int t_UBSEC_rsa_mod_exp_ioctl(int fd, - unsigned char *x, int x_len, - unsigned char *m, int m_len, - unsigned char *e, int e_len, - unsigned char *y, int *y_len); - -typedef int t_UBSEC_rsa_mod_exp_crt_ioctl(int fd, - unsigned char *x, int x_len, - unsigned char *qinv, int qinv_len, - unsigned char *edq, int edq_len, - unsigned char *q, int q_len, - unsigned char *edp, int edp_len, - unsigned char *p, int p_len, - unsigned char *y, int *y_len); - -typedef int t_UBSEC_dsa_sign_ioctl(int fd, - int hash, unsigned char *data, - int data_len, unsigned char *rndom, - int random_len, unsigned char *p, - int p_len, unsigned char *q, int q_len, - unsigned char *g, int g_len, - unsigned char *key, int key_len, - unsigned char *r, int *r_len, - unsigned char *s, int *s_len); - -typedef int t_UBSEC_dsa_verify_ioctl(int fd, - int hash, unsigned char *data, - int data_len, unsigned char *p, - int p_len, unsigned char *q, int q_len, - unsigned char *g, int g_len, - unsigned char *key, int key_len, - unsigned char *r, int r_len, - unsigned char *s, int s_len, - unsigned char *v, int *v_len); - -typedef int t_UBSEC_math_accelerate_ioctl(int fd, ubsec_MathCommand_t command, - unsigned char *ModN, int *ModN_len, - unsigned char *ExpE, int *ExpE_len, - unsigned char *ParamA, - int *ParamA_len, - unsigned char *ParamB, - int *ParamB_len, - unsigned char *Result, - int *Result_len); - -typedef int t_UBSEC_rng_ioctl(int fd, ubsec_RNGCommand_t command, - unsigned char *Result, int *Result_len); - -typedef int t_UBSEC_max_key_len_ioctl(int fd, int *max_key_len); diff --git a/Sources/COpenSSL/hwcryptohook.h b/Sources/COpenSSL/hwcryptohook.h deleted file mode 100644 index fa06396a..00000000 --- a/Sources/COpenSSL/hwcryptohook.h +++ /dev/null @@ -1,502 +0,0 @@ -/*- - * ModExp / RSA (with/without KM) plugin API - * - * The application will load a dynamic library which - * exports entrypoint(s) defined in this file. - * - * This set of entrypoints provides only a multithreaded, - * synchronous-within-each-thread, facility. - * - * - * This file is Copyright 1998-2000 nCipher Corporation Limited. - * - * Redistribution and use in source and binary forms, with opr without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the copyright notice, - * this list of conditions, and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions, and the following - * disclaimer, in the documentation and/or other materials provided - * with the distribution - * - * IN NO EVENT SHALL NCIPHER CORPORATION LIMITED (`NCIPHER') AND/OR - * ANY OTHER AUTHORS OR DISTRIBUTORS OF THIS FILE BE LIABLE for any - * damages arising directly or indirectly from this file, its use or - * this licence. Without prejudice to the generality of the - * foregoing: all liability shall be excluded for direct, indirect, - * special, incidental, consequential or other damages or any loss of - * profits, business, revenue goodwill or anticipated savings; - * liability shall be excluded even if nCipher or anyone else has been - * advised of the possibility of damage. In any event, if the - * exclusion of liability is not effective, the liability of nCipher - * or any author or distributor shall be limited to the lesser of the - * price paid and 1,000 pounds sterling. This licence only fails to - * exclude or limit liability for death or personal injury arising out - * of negligence, and only to the extent that such an exclusion or - * limitation is not effective. - * - * NCIPHER AND THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ALL - * AND ANY WARRANTIES (WHETHER EXPRESS OR IMPLIED), including, but not - * limited to, any implied warranties of merchantability, fitness for - * a particular purpose, satisfactory quality, and/or non-infringement - * of any third party rights. - * - * US Government use: This software and documentation is Commercial - * Computer Software and Computer Software Documentation, as defined in - * sub-paragraphs (a)(1) and (a)(5) of DFAR 252.227-7014, "Rights in - * Noncommercial Computer Software and Noncommercial Computer Software - * Documentation." Use, duplication or disclosure by the Government is - * subject to the terms and conditions specified here. - * - * By using or distributing this file you will be accepting these - * terms and conditions, including the limitation of liability and - * lack of warranty. If you do not wish to accept these terms and - * conditions, DO NOT USE THE FILE. - * - * - * The actual dynamically loadable plugin, and the library files for - * static linking, which are also provided in some distributions, are - * not covered by the licence described above. You should have - * received a separate licence with terms and conditions for these - * library files; if you received the library files without a licence, - * please contact nCipher. - * - * - * $Id: hwcryptohook.h,v 1.1 2002/10/11 17:10:59 levitte Exp $ - */ - -#ifndef HWCRYPTOHOOK_H -# define HWCRYPTOHOOK_H - -# include -# include - -# ifndef HWCRYPTOHOOK_DECLARE_APPTYPES -# define HWCRYPTOHOOK_DECLARE_APPTYPES 1 -# endif - -# define HWCRYPTOHOOK_ERROR_FAILED -1 -# define HWCRYPTOHOOK_ERROR_FALLBACK -2 -# define HWCRYPTOHOOK_ERROR_MPISIZE -3 - -# if HWCRYPTOHOOK_DECLARE_APPTYPES - -/*- - * These structs are defined by the application and opaque to the - * crypto plugin. The application may define these as it sees fit. - * Default declarations are provided here, but the application may - * #define HWCRYPTOHOOK_DECLARE_APPTYPES 0 - * to prevent these declarations, and instead provide its own - * declarations of these types. (Pointers to them must still be - * ordinary pointers to structs or unions, or the resulting combined - * program will have a type inconsistency.) - */ -typedef struct HWCryptoHook_MutexValue HWCryptoHook_Mutex; -typedef struct HWCryptoHook_CondVarValue HWCryptoHook_CondVar; -typedef struct HWCryptoHook_PassphraseContextValue - HWCryptoHook_PassphraseContext; -typedef struct HWCryptoHook_CallerContextValue HWCryptoHook_CallerContext; - -# endif /* HWCRYPTOHOOK_DECLARE_APPTYPES */ - -/*- - * These next two structs are opaque to the application. The crypto - * plugin will return pointers to them; the caller simply manipulates - * the pointers. - */ -typedef struct HWCryptoHook_Context *HWCryptoHook_ContextHandle; -typedef struct HWCryptoHook_RSAKey *HWCryptoHook_RSAKeyHandle; - -typedef struct { - char *buf; - size_t size; -} HWCryptoHook_ErrMsgBuf; -/*- - * Used for error reporting. When a HWCryptoHook function fails it - * will return a sentinel value (0 for pointer-valued functions, or a - * negative number, usually HWCRYPTOHOOK_ERROR_FAILED, for - * integer-valued ones). It will, if an ErrMsgBuf is passed, also put - * an error message there. - * - * size is the size of the buffer, and will not be modified. If you - * pass 0 for size you must pass 0 for buf, and nothing will be - * recorded (just as if you passed 0 for the struct pointer). - * Messages written to the buffer will always be null-terminated, even - * when truncated to fit within size bytes. - * - * The contents of the buffer are not defined if there is no error. - */ - -typedef struct HWCryptoHook_MPIStruct { - unsigned char *buf; - size_t size; -} HWCryptoHook_MPI; -/*- - * When one of these is returned, a pointer is passed to the function. - * At call, size is the space available. Afterwards it is updated to - * be set to the actual length (which may be more than the space available, - * if there was not enough room and the result was truncated). - * buf (the pointer) is not updated. - * - * size is in bytes and may be zero at call or return, but must be a - * multiple of the limb size. Zero limbs at the MS end are not - * permitted. - */ - -# define HWCryptoHook_InitFlags_FallbackModExp 0x0002UL -# define HWCryptoHook_InitFlags_FallbackRSAImmed 0x0004UL -/*- - * Enable requesting fallback to software in case of problems with the - * hardware support. This indicates to the crypto provider that the - * application is prepared to fall back to software operation if the - * ModExp* or RSAImmed* functions return HWCRYPTOHOOK_ERROR_FALLBACK. - * Without this flag those calls will never return - * HWCRYPTOHOOK_ERROR_FALLBACK. The flag will also cause the crypto - * provider to avoid repeatedly attempting to contact dead hardware - * within a short interval, if appropriate. - */ - -# define HWCryptoHook_InitFlags_SimpleForkCheck 0x0010UL -/*- - * Without _SimpleForkCheck the library is allowed to assume that the - * application will not fork and call the library in the child(ren). - * - * When it is specified, this is allowed. However, after a fork - * neither parent nor child may unload any loaded keys or call - * _Finish. Instead, they should call exit (or die with a signal) - * without calling _Finish. After all the children have died the - * parent may unload keys or call _Finish. - * - * This flag only has any effect on UN*X platforms. - */ - -typedef struct { - unsigned long flags; - void *logstream; /* usually a FILE*. See below. */ - size_t limbsize; /* bignum format - size of radix type, must - * be power of 2 */ - int mslimbfirst; /* 0 or 1 */ - int msbytefirst; /* 0 or 1; -1 = native */ - /*- - * All the callback functions should return 0 on success, or a - * nonzero integer (whose value will be visible in the error message - * put in the buffer passed to the call). - * - * If a callback is not available pass a null function pointer. - * - * The callbacks may not call down again into the crypto plugin. - */ - /*- - * For thread-safety. Set everything to 0 if you promise only to be - * singlethreaded. maxsimultaneous is the number of calls to - * ModExp[Crt]/RSAImmed{Priv,Pub}/RSA. If you don't know what to - * put there then say 0 and the hook library will use a default. - * - * maxmutexes is a small limit on the number of simultaneous mutexes - * which will be requested by the library. If there is no small - * limit, set it to 0. If the crypto plugin cannot create the - * advertised number of mutexes the calls to its functions may fail. - * If a low number of mutexes is advertised the plugin will try to - * do the best it can. Making larger numbers of mutexes available - * may improve performance and parallelism by reducing contention - * over critical sections. Unavailability of any mutexes, implying - * single-threaded operation, should be indicated by the setting - * mutex_init et al to 0. - */ - int maxmutexes; - int maxsimultaneous; - size_t mutexsize; - int (*mutex_init) (HWCryptoHook_Mutex *, - HWCryptoHook_CallerContext * cactx); - int (*mutex_acquire) (HWCryptoHook_Mutex *); - void (*mutex_release) (HWCryptoHook_Mutex *); - void (*mutex_destroy) (HWCryptoHook_Mutex *); - /*- - * For greater efficiency, can use condition vars internally for - * synchronisation. In this case maxsimultaneous is ignored, but - * the other mutex stuff must be available. In singlethreaded - * programs, set everything to 0. - */ - size_t condvarsize; - int (*condvar_init) (HWCryptoHook_CondVar *, - HWCryptoHook_CallerContext * cactx); - int (*condvar_wait) (HWCryptoHook_CondVar *, HWCryptoHook_Mutex *); - void (*condvar_signal) (HWCryptoHook_CondVar *); - void (*condvar_broadcast) (HWCryptoHook_CondVar *); - void (*condvar_destroy) (HWCryptoHook_CondVar *); - /*- - * The semantics of acquiring and releasing mutexes and broadcasting - * and waiting on condition variables are expected to be those from - * POSIX threads (pthreads). The mutexes may be (in pthread-speak) - * fast mutexes, recursive mutexes, or nonrecursive ones. - * - * The _release/_signal/_broadcast and _destroy functions must - * always succeed when given a valid argument; if they are given an - * invalid argument then the program (crypto plugin + application) - * has an internal error, and they should abort the program. - */ - int (*getpassphrase) (const char *prompt_info, - int *len_io, char *buf, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx); - /*- - * Passphrases and the prompt_info, if they contain high-bit-set - * characters, are UTF-8. The prompt_info may be a null pointer if - * no prompt information is available (it should not be an empty - * string). It will not contain text like `enter passphrase'; - * instead it might say something like `Operator Card for John - * Smith' or `SmartCard in nFast Module #1, Slot #1'. - * - * buf points to a buffer in which to return the passphrase; on - * entry *len_io is the length of the buffer. It should be updated - * by the callback. The returned passphrase should not be - * null-terminated by the callback. - */ - int (*getphystoken) (const char *prompt_info, - const char *wrong_info, - HWCryptoHook_PassphraseContext * ppctx, - HWCryptoHook_CallerContext * cactx); - /*- - * Requests that the human user physically insert a different - * smartcard, DataKey, etc. The plugin should check whether the - * currently inserted token(s) are appropriate, and if they are it - * should not make this call. - * - * prompt_info is as before. wrong_info is a description of the - * currently inserted token(s) so that the user is told what - * something is. wrong_info, like prompt_info, may be null, but - * should not be an empty string. Its contents should be - * syntactically similar to that of prompt_info. - */ - /*- - * Note that a single LoadKey operation might cause several calls to - * getpassphrase and/or requestphystoken. If requestphystoken is - * not provided (ie, a null pointer is passed) then the plugin may - * not support loading keys for which authorisation by several cards - * is required. If getpassphrase is not provided then cards with - * passphrases may not be supported. - * - * getpassphrase and getphystoken do not need to check that the - * passphrase has been entered correctly or the correct token - * inserted; the crypto plugin will do that. If this is not the - * case then the crypto plugin is responsible for calling these - * routines again as appropriate until the correct token(s) and - * passphrase(s) are supplied as required, or until any retry limits - * implemented by the crypto plugin are reached. - * - * In either case, the application must allow the user to say `no' - * or `cancel' to indicate that they do not know the passphrase or - * have the appropriate token; this should cause the callback to - * return nonzero indicating error. - */ - void (*logmessage) (void *logstream, const char *message); - /*- - * A log message will be generated at least every time something goes - * wrong and an ErrMsgBuf is filled in (or would be if one was - * provided). Other diagnostic information may be written there too, - * including more detailed reasons for errors which are reported in an - * ErrMsgBuf. - * - * When a log message is generated, this callback is called. It - * should write a message to the relevant logging arrangements. - * - * The message string passed will be null-terminated and may be of arbitrary - * length. It will not be prefixed by the time and date, nor by the - * name of the library that is generating it - if this is required, - * the logmessage callback must do it. The message will not have a - * trailing newline (though it may contain internal newlines). - * - * If a null pointer is passed for logmessage a default function is - * used. The default function treats logstream as a FILE* which has - * been converted to a void*. If logstream is 0 it does nothing. - * Otherwise it prepends the date and time and library name and - * writes the message to logstream. Each line will be prefixed by a - * descriptive string containing the date, time and identity of the - * crypto plugin. Errors on the logstream are not reported - * anywhere, and the default function doesn't flush the stream, so - * the application must set the buffering how it wants it. - * - * The crypto plugin may also provide a facility to have copies of - * log messages sent elsewhere, and or for adjusting the verbosity - * of the log messages; any such facilities will be configured by - * external means. - */ -} HWCryptoHook_InitInfo; - -typedef -HWCryptoHook_ContextHandle HWCryptoHook_Init_t(const HWCryptoHook_InitInfo * - initinfo, size_t initinfosize, - const HWCryptoHook_ErrMsgBuf * - errors, - HWCryptoHook_CallerContext * - cactx); -extern HWCryptoHook_Init_t HWCryptoHook_Init; - -/*- - * Caller should set initinfosize to the size of the HWCryptoHook struct, - * so it can be extended later. - * - * On success, a message for display or logging by the server, - * including the name and version number of the plugin, will be filled - * in into *errors; on failure *errors is used for error handling, as - * usual. - */ - -/*- - * All these functions return 0 on success, HWCRYPTOHOOK_ERROR_FAILED - * on most failures. HWCRYPTOHOOK_ERROR_MPISIZE means at least one of - * the output MPI buffer(s) was too small; the sizes of all have been - * set to the desired size (and for those where the buffer was large - * enough, the value may have been copied in), and no error message - * has been recorded. - * - * You may pass 0 for the errors struct. In any case, unless you set - * _NoStderr at init time then messages may be reported to stderr. - */ - -/*- - * The RSAImmed* functions (and key managed RSA) only work with - * modules which have an RSA patent licence - currently that means KM - * units; the ModExp* ones work with all modules, so you need a patent - * licence in the software in the US. They are otherwise identical. - */ - -typedef -void HWCryptoHook_Finish_t(HWCryptoHook_ContextHandle hwctx); -extern HWCryptoHook_Finish_t HWCryptoHook_Finish; -/* You must not have any calls going or keys loaded when you call this. */ - -typedef -int HWCryptoHook_RandomBytes_t(HWCryptoHook_ContextHandle hwctx, - unsigned char *buf, size_t len, - const HWCryptoHook_ErrMsgBuf * errors); -extern HWCryptoHook_RandomBytes_t HWCryptoHook_RandomBytes; - -typedef -int HWCryptoHook_ModExp_t(HWCryptoHook_ContextHandle hwctx, - HWCryptoHook_MPI a, - HWCryptoHook_MPI p, - HWCryptoHook_MPI n, - HWCryptoHook_MPI * r, - const HWCryptoHook_ErrMsgBuf * errors); -extern HWCryptoHook_ModExp_t HWCryptoHook_ModExp; - -typedef -int HWCryptoHook_RSAImmedPub_t(HWCryptoHook_ContextHandle hwctx, - HWCryptoHook_MPI m, - HWCryptoHook_MPI e, - HWCryptoHook_MPI n, - HWCryptoHook_MPI * r, - const HWCryptoHook_ErrMsgBuf * errors); -extern HWCryptoHook_RSAImmedPub_t HWCryptoHook_RSAImmedPub; - -typedef -int HWCryptoHook_ModExpCRT_t(HWCryptoHook_ContextHandle hwctx, - HWCryptoHook_MPI a, - HWCryptoHook_MPI p, - HWCryptoHook_MPI q, - HWCryptoHook_MPI dmp1, - HWCryptoHook_MPI dmq1, - HWCryptoHook_MPI iqmp, - HWCryptoHook_MPI * r, - const HWCryptoHook_ErrMsgBuf * errors); -extern HWCryptoHook_ModExpCRT_t HWCryptoHook_ModExpCRT; - -typedef -int HWCryptoHook_RSAImmedPriv_t(HWCryptoHook_ContextHandle hwctx, - HWCryptoHook_MPI m, - HWCryptoHook_MPI p, - HWCryptoHook_MPI q, - HWCryptoHook_MPI dmp1, - HWCryptoHook_MPI dmq1, - HWCryptoHook_MPI iqmp, - HWCryptoHook_MPI * r, - const HWCryptoHook_ErrMsgBuf * errors); -extern HWCryptoHook_RSAImmedPriv_t HWCryptoHook_RSAImmedPriv; - -/*- - * The RSAImmed* and ModExp* functions may return E_FAILED or - * E_FALLBACK for failure. - * - * E_FAILED means the failure is permanent and definite and there - * should be no attempt to fall back to software. (Eg, for some - * applications, which support only the acceleration-only - * functions, the `key material' may actually be an encoded key - * identifier, and doing the operation in software would give wrong - * answers.) - * - * E_FALLBACK means that doing the computation in software would seem - * reasonable. If an application pays attention to this and is - * able to fall back, it should also set the Fallback init flags. - */ - -typedef -int HWCryptoHook_RSALoadKey_t(HWCryptoHook_ContextHandle hwctx, - const char *key_ident, - HWCryptoHook_RSAKeyHandle * keyhandle_r, - const HWCryptoHook_ErrMsgBuf * errors, - HWCryptoHook_PassphraseContext * ppctx); -extern HWCryptoHook_RSALoadKey_t HWCryptoHook_RSALoadKey; -/*- - * The key_ident is a null-terminated string configured by the - * user via the application's usual configuration mechanisms. - * It is provided to the user by the crypto provider's key management - * system. The user must be able to enter at least any string of between - * 1 and 1023 characters inclusive, consisting of printable 7-bit - * ASCII characters. The provider should avoid using - * any characters except alphanumerics and the punctuation - * characters _ - + . / @ ~ (the user is expected to be able - * to enter these without quoting). The string may be case-sensitive. - * The application may allow the user to enter other NULL-terminated strings, - * and the provider must cope (returning an error if the string is not - * valid). - * - * If the key does not exist, no error is recorded and 0 is returned; - * keyhandle_r will be set to 0 instead of to a key handle. - */ - -typedef -int HWCryptoHook_RSAGetPublicKey_t(HWCryptoHook_RSAKeyHandle k, - HWCryptoHook_MPI * n, - HWCryptoHook_MPI * e, - const HWCryptoHook_ErrMsgBuf * errors); -extern HWCryptoHook_RSAGetPublicKey_t HWCryptoHook_RSAGetPublicKey; -/*- - * The crypto plugin will not store certificates. - * - * Although this function for acquiring the public key value is - * provided, it is not the purpose of this API to deal fully with the - * handling of the public key. - * - * It is expected that the crypto supplier's key generation program - * will provide general facilities for producing X.509 - * self-certificates and certificate requests in PEM format. These - * will be given to the user so that they can configure them in the - * application, send them to CAs, or whatever. - * - * In case this kind of certificate handling is not appropriate, the - * crypto supplier's key generation program should be able to be - * configured not to generate such a self-certificate or certificate - * request. Then the application will need to do all of this, and - * will need to store and handle the public key and certificates - * itself. - */ - -typedef -int HWCryptoHook_RSAUnloadKey_t(HWCryptoHook_RSAKeyHandle k, - const HWCryptoHook_ErrMsgBuf * errors); -extern HWCryptoHook_RSAUnloadKey_t HWCryptoHook_RSAUnloadKey; -/* Might fail due to locking problems, or other serious internal problems. */ - -typedef -int HWCryptoHook_RSA_t(HWCryptoHook_MPI m, - HWCryptoHook_RSAKeyHandle k, - HWCryptoHook_MPI * r, - const HWCryptoHook_ErrMsgBuf * errors); -extern HWCryptoHook_RSA_t HWCryptoHook_RSA; -/* RSA private key operation (sign or decrypt) - raw, unpadded. */ - -#endif /* HWCRYPTOHOOK_H */ diff --git a/Sources/COpenSSL/i2d_.c b/Sources/COpenSSL/i2d_.c deleted file mode 100644 index 292daa76..00000000 --- a/Sources/COpenSSL/i2d_.c +++ /dev/null @@ -1,174 +0,0 @@ -/* crypto/asn1/i2d_pr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "x509.h" -#include "asn1_locl.h" - -int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) -{ - if (a->ameth && a->ameth->old_priv_encode) { - return a->ameth->old_priv_encode(a, pp); - } - if (a->ameth && a->ameth->priv_encode) { - PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); - int ret = 0; - if (p8 != NULL) { - ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp); - PKCS8_PRIV_KEY_INFO_free(p8); - } - return ret; - } - ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return -1; -} -/* crypto/asn1/i2d_pu.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "bn.h" -// #include "evp.h" -#include "objects.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_EC -# include "ec.h" -#endif - -int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp) -{ - switch (a->type) { -#ifndef OPENSSL_NO_RSA - case EVP_PKEY_RSA: - return (i2d_RSAPublicKey(a->pkey.rsa, pp)); -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - return (i2d_DSAPublicKey(a->pkey.dsa, pp)); -#endif -#ifndef OPENSSL_NO_EC - case EVP_PKEY_EC: - return (i2o_ECPublicKey(a->pkey.ec, pp)); -#endif - default: - ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return (-1); - } -} diff --git a/Sources/COpenSSL/i_.c b/Sources/COpenSSL/i_.c deleted file mode 100644 index a262c89f..00000000 --- a/Sources/COpenSSL/i_.c +++ /dev/null @@ -1,663 +0,0 @@ -/* crypto/idea/i_cbc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "idea.h" -#include "idea_lcl.h" - -void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, - long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, - int encrypt) -{ - register unsigned long tin0, tin1; - register unsigned long tout0, tout1, xor0, xor1; - register long l = length; - unsigned long tin[2]; - - if (encrypt) { - n2l(iv, tout0); - n2l(iv, tout1); - iv -= 8; - for (l -= 8; l >= 0; l -= 8) { - n2l(in, tin0); - n2l(in, tin1); - tin0 ^= tout0; - tin1 ^= tout1; - tin[0] = tin0; - tin[1] = tin1; - idea_encrypt(tin, ks); - tout0 = tin[0]; - l2n(tout0, out); - tout1 = tin[1]; - l2n(tout1, out); - } - if (l != -8) { - n2ln(in, tin0, tin1, l + 8); - tin0 ^= tout0; - tin1 ^= tout1; - tin[0] = tin0; - tin[1] = tin1; - idea_encrypt(tin, ks); - tout0 = tin[0]; - l2n(tout0, out); - tout1 = tin[1]; - l2n(tout1, out); - } - l2n(tout0, iv); - l2n(tout1, iv); - } else { - n2l(iv, xor0); - n2l(iv, xor1); - iv -= 8; - for (l -= 8; l >= 0; l -= 8) { - n2l(in, tin0); - tin[0] = tin0; - n2l(in, tin1); - tin[1] = tin1; - idea_encrypt(tin, ks); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2n(tout0, out); - l2n(tout1, out); - xor0 = tin0; - xor1 = tin1; - } - if (l != -8) { - n2l(in, tin0); - tin[0] = tin0; - n2l(in, tin1); - tin[1] = tin1; - idea_encrypt(tin, ks); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2nn(tout0, tout1, out, l + 8); - xor0 = tin0; - xor1 = tin1; - } - l2n(xor0, iv); - l2n(xor1, iv); - } - tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; - tin[0] = tin[1] = 0; -} - -void idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key) -{ - register IDEA_INT *p; - register unsigned long x1, x2, x3, x4, t0, t1, ul; - - x2 = d[0]; - x1 = (x2 >> 16); - x4 = d[1]; - x3 = (x4 >> 16); - - p = &(key->data[0][0]); - - E_IDEA(0); - E_IDEA(1); - E_IDEA(2); - E_IDEA(3); - E_IDEA(4); - E_IDEA(5); - E_IDEA(6); - E_IDEA(7); - - x1 &= 0xffff; - idea_mul(x1, x1, *p, ul); - p++; - - t0 = x3 + *(p++); - t1 = x2 + *(p++); - - x4 &= 0xffff; - idea_mul(x4, x4, *p, ul); - - d[0] = (t0 & 0xffff) | ((x1 & 0xffff) << 16); - d[1] = (x4 & 0xffff) | ((t1 & 0xffff) << 16); -} -/* crypto/idea/i_cfb64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "idea.h" -// #include "idea_lcl.h" - -/* - * The input and output encrypted as though 64bit cfb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ - -void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, IDEA_KEY_SCHEDULE *schedule, - unsigned char *ivec, int *num, int encrypt) -{ - register unsigned long v0, v1, t; - register int n = *num; - register long l = length; - unsigned long ti[2]; - unsigned char *iv, c, cc; - - iv = (unsigned char *)ivec; - if (encrypt) { - while (l--) { - if (n == 0) { - n2l(iv, v0); - ti[0] = v0; - n2l(iv, v1); - ti[1] = v1; - idea_encrypt((unsigned long *)ti, schedule); - iv = (unsigned char *)ivec; - t = ti[0]; - l2n(t, iv); - t = ti[1]; - l2n(t, iv); - iv = (unsigned char *)ivec; - } - c = *(in++) ^ iv[n]; - *(out++) = c; - iv[n] = c; - n = (n + 1) & 0x07; - } - } else { - while (l--) { - if (n == 0) { - n2l(iv, v0); - ti[0] = v0; - n2l(iv, v1); - ti[1] = v1; - idea_encrypt((unsigned long *)ti, schedule); - iv = (unsigned char *)ivec; - t = ti[0]; - l2n(t, iv); - t = ti[1]; - l2n(t, iv); - iv = (unsigned char *)ivec; - } - cc = *(in++); - c = iv[n]; - iv[n] = cc; - *(out++) = c ^ cc; - n = (n + 1) & 0x07; - } - } - v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; - *num = n; -} -/* crypto/idea/i_ecb.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "idea.h" -// #include "idea_lcl.h" -#include "opensslv.h" - -const char IDEA_version[] = "IDEA" OPENSSL_VERSION_PTEXT; - -const char *idea_options(void) -{ - if (sizeof(short) != sizeof(IDEA_INT)) - return ("idea(int)"); - else - return ("idea(short)"); -} - -void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, - IDEA_KEY_SCHEDULE *ks) -{ - unsigned long l0, l1, d[2]; - - n2l(in, l0); - d[0] = l0; - n2l(in, l1); - d[1] = l1; - idea_encrypt(d, ks); - l0 = d[0]; - l2n(l0, out); - l1 = d[1]; - l2n(l1, out); - l0 = l1 = d[0] = d[1] = 0; -} -/* crypto/idea/i_ofb64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "idea.h" -// #include "idea_lcl.h" - -/* - * The input and output encrypted as though 64bit ofb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ -void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, IDEA_KEY_SCHEDULE *schedule, - unsigned char *ivec, int *num) -{ - register unsigned long v0, v1, t; - register int n = *num; - register long l = length; - unsigned char d[8]; - register char *dp; - unsigned long ti[2]; - unsigned char *iv; - int save = 0; - - iv = (unsigned char *)ivec; - n2l(iv, v0); - n2l(iv, v1); - ti[0] = v0; - ti[1] = v1; - dp = (char *)d; - l2n(v0, dp); - l2n(v1, dp); - while (l--) { - if (n == 0) { - idea_encrypt((unsigned long *)ti, schedule); - dp = (char *)d; - t = ti[0]; - l2n(t, dp); - t = ti[1]; - l2n(t, dp); - save++; - } - *(out++) = *(in++) ^ d[n]; - n = (n + 1) & 0x07; - } - if (save) { - v0 = ti[0]; - v1 = ti[1]; - iv = (unsigned char *)ivec; - l2n(v0, iv); - l2n(v1, iv); - } - t = v0 = v1 = ti[0] = ti[1] = 0; - *num = n; -} -/* crypto/idea/i_skey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "crypto.h" -// #include "idea.h" -// #include "idea_lcl.h" - -static IDEA_INT inverse(unsigned int xin); -void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) -#ifdef OPENSSL_FIPS -{ - fips_cipher_abort(IDEA); - private_idea_set_encrypt_key(key, ks); -} - -void private_idea_set_encrypt_key(const unsigned char *key, - IDEA_KEY_SCHEDULE *ks) -#endif -{ - int i; - register IDEA_INT *kt, *kf, r0, r1, r2; - - kt = &(ks->data[0][0]); - n2s(key, kt[0]); - n2s(key, kt[1]); - n2s(key, kt[2]); - n2s(key, kt[3]); - n2s(key, kt[4]); - n2s(key, kt[5]); - n2s(key, kt[6]); - n2s(key, kt[7]); - - kf = kt; - kt += 8; - for (i = 0; i < 6; i++) { - r2 = kf[1]; - r1 = kf[2]; - *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff; - r0 = kf[3]; - *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; - r1 = kf[4]; - *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; - r0 = kf[5]; - *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; - r1 = kf[6]; - *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; - r0 = kf[7]; - *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; - r1 = kf[0]; - if (i >= 5) - break; - *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; - *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff; - kf += 8; - } -} - -void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) -{ - int r; - register IDEA_INT *fp, *tp, t; - - tp = &(dk->data[0][0]); - fp = &(ek->data[8][0]); - for (r = 0; r < 9; r++) { - *(tp++) = inverse(fp[0]); - *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff); - *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff); - *(tp++) = inverse(fp[3]); - if (r == 8) - break; - fp -= 6; - *(tp++) = fp[4]; - *(tp++) = fp[5]; - } - - tp = &(dk->data[0][0]); - t = tp[1]; - tp[1] = tp[2]; - tp[2] = t; - - t = tp[49]; - tp[49] = tp[50]; - tp[50] = t; -} - -/* taken directly from the 'paper' I'll have a look at it later */ -static IDEA_INT inverse(unsigned int xin) -{ - long n1, n2, q, r, b1, b2, t; - - if (xin == 0) - b2 = 0; - else { - n1 = 0x10001; - n2 = xin; - b2 = 1; - b1 = 0; - - do { - r = (n1 % n2); - q = (n1 - r) / n2; - if (r == 0) { - if (b2 < 0) - b2 = 0x10001 + b2; - } else { - n1 = n2; - n2 = r; - t = b2; - b2 = b1 - q * b2; - b1 = t; - } - } while (r != 0); - } - return ((IDEA_INT) b2); -} diff --git a/Sources/COpenSSL/idea.h b/Sources/COpenSSL/idea.h deleted file mode 100644 index 7ea2f06c..00000000 --- a/Sources/COpenSSL/idea.h +++ /dev/null @@ -1,105 +0,0 @@ -/* crypto/idea/idea.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_IDEA_H -# define HEADER_IDEA_H - -# include "opensslconf.h"/* IDEA_INT, OPENSSL_NO_IDEA */ - -# ifdef OPENSSL_NO_IDEA -# error IDEA is disabled. -# endif - -# define IDEA_ENCRYPT 1 -# define IDEA_DECRYPT 0 - -# define IDEA_BLOCK 8 -# define IDEA_KEY_LENGTH 16 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct idea_key_st { - IDEA_INT data[9][6]; -} IDEA_KEY_SCHEDULE; - -const char *idea_options(void); -void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, - IDEA_KEY_SCHEDULE *ks); -# ifdef OPENSSL_FIPS -void private_idea_set_encrypt_key(const unsigned char *key, - IDEA_KEY_SCHEDULE *ks); -# endif -void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); -void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); -void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, - long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, - int enc); -void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, - int *num, int enc); -void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, - int *num); -void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/idea_lcl.h b/Sources/COpenSSL/idea_lcl.h deleted file mode 100644 index e4069538..00000000 --- a/Sources/COpenSSL/idea_lcl.h +++ /dev/null @@ -1,216 +0,0 @@ -/* crypto/idea/idea_lcl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * The new form of this macro (check if the a*b == 0) was suggested by Colin - * Plumb - */ -/* Removal of the inner if from from Wei Dai 24/4/96 */ -#define idea_mul(r,a,b,ul) \ -ul=(unsigned long)a*b; \ -if (ul != 0) \ - { \ - r=(ul&0xffff)-(ul>>16); \ - r-=((r)>>16); \ - } \ -else \ - r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ - -#ifdef undef -# define idea_mul(r,a,b,ul,sl) \ -if (a == 0) r=(0x10001-b)&0xffff; \ -else if (b == 0) r=(0x10001-a)&0xffff; \ -else { \ - ul=(unsigned long)a*b; \ - sl=(ul&0xffff)-(ul>>16); \ - if (sl <= 0) sl+=0x10001; \ - r=sl; \ - } -#endif - -/* - * 7/12/95 - Many thanks to Rhys Weatherley for - * pointing out that I was assuming little endian byte order for all - * quantities what idea actually used bigendian. No where in the spec does - * it mention this, it is all in terms of 16 bit numbers and even the example - * does not use byte streams for the input example :-(. If you byte swap each - * pair of input, keys and iv, the functions would produce the output as the - * old version :-(. - */ - -/* NOTE - c is not incremented as per n2l */ -#define n2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c)))) ; \ - case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 6: l2|=((unsigned long)(*(--(c))))<<16; \ - case 5: l2|=((unsigned long)(*(--(c))))<<24; \ - case 4: l1 =((unsigned long)(*(--(c)))) ; \ - case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 2: l1|=((unsigned long)(*(--(c))))<<16; \ - case 1: l1|=((unsigned long)(*(--(c))))<<24; \ - } \ - } - -/* NOTE - c is not incremented as per l2n */ -#define l2nn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - } \ - } - -#undef n2l -#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))) - -#undef l2n -#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -#undef s2n -#define s2n(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff)) - -#undef n2s -#define n2s(c,l) (l =((IDEA_INT)(*((c)++)))<< 8L, \ - l|=((IDEA_INT)(*((c)++))) ) - -#ifdef undef -/* NOTE - c is not incremented as per c2l */ -# define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ - } \ - } - -/* NOTE - c is not incremented as per l2c */ -# define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -# undef c2s -# define c2s(c,l) (l =((unsigned long)(*((c)++))) , \ - l|=((unsigned long)(*((c)++)))<< 8L) - -# undef s2c -# define s2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff)) - -# undef c2l -# define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<<24L) - -# undef l2c -# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24L)&0xff)) -#endif - -#define E_IDEA(num) \ - x1&=0xffff; \ - idea_mul(x1,x1,*p,ul); p++; \ - x2+= *(p++); \ - x3+= *(p++); \ - x4&=0xffff; \ - idea_mul(x4,x4,*p,ul); p++; \ - t0=(x1^x3)&0xffff; \ - idea_mul(t0,t0,*p,ul); p++; \ - t1=(t0+(x2^x4))&0xffff; \ - idea_mul(t1,t1,*p,ul); p++; \ - t0+=t1; \ - x1^=t1; \ - x4^=t0; \ - ul=x2^t0; /* do the swap to x3 */ \ - x2=x3^t1; \ - x3=ul; diff --git a/Sources/COpenSSL/include/module.modulemap b/Sources/COpenSSL/include/module.modulemap deleted file mode 100644 index 989a7c23..00000000 --- a/Sources/COpenSSL/include/module.modulemap +++ /dev/null @@ -1,3 +0,0 @@ -module COpenSSL { - header "openssl.h" -} diff --git a/Sources/COpenSSL/include/openssl.h b/Sources/COpenSSL/include/openssl.h deleted file mode 100644 index c9c50822..00000000 --- a/Sources/COpenSSL/include/openssl.h +++ /dev/null @@ -1,559 +0,0 @@ - -#ifndef _COPENSSL_H_ -#define _COPENSSL_H_ - -#include "../conf.h" -#include "../ssl.h" -#include "../err.h" -#include "../x509.h" -#include "../x509v3.h" -#include "../sha.h" -#include "../md5.h" -#include "../bio.h" -#include "../hmac.h" -#include "../rand.h" -#include "../cms.h" -#include "../evp.h" - -static int copenssl_EVP_MD_size(const EVP_MD *md) { - return EVP_MD_size(md); -} -static int copenssl_EVP_CIPHER_block_size(const EVP_CIPHER *cipher) { - return EVP_CIPHER_block_size(cipher); -} -static int copenssl_EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { - return EVP_CIPHER_key_length(cipher); -} -static int copenssl_EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { - return EVP_CIPHER_iv_length(cipher); -} -static EVP_MD_CTX * copenssl_EVP_MD_CTX_create() { - return EVP_MD_CTX_create(); -} - -static void copenssl_EVP_MD_CTX_destroy(EVP_MD_CTX * ctx) { - EVP_MD_CTX_destroy(ctx); -} - -static void copenssl_SSL_library_init() { - SSL_library_init(); - ERR_load_crypto_strings(); - SSL_load_error_strings(); - OPENSSL_add_all_algorithms_conf(); -} -static size_t copenssl_stack_st_X509_NAME_num(struct stack_st_X509_NAME * p) { - return sk_X509_NAME_num(p); -} - -#if OPENSSL_VERSION_NUMBER < 0x10100000L -static void * copenssl_CRYPTO_malloc(size_t num, const char *file, int line) { - return CRYPTO_malloc((int)num, file, line); -} -static void copenssl_CRYPTO_free(void * obj, const char *file, int line) { - CRYPTO_free(obj); -} -static void copenssl_SSL_CTX_set_options(SSL_CTX * sslCtx) { -#ifdef SSL_CTRL_SET_ECDH_AUTO - SSL_CTX_ctrl(sslCtx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL); -#endif - SSL_CTX_ctrl(sslCtx, SSL_CTRL_MODE, SSL_MODE_AUTO_RETRY, NULL); - SSL_CTX_ctrl(sslCtx, SSL_CTRL_OPTIONS, SSL_OP_ALL, NULL); -} - -#else -static void * copenssl_CRYPTO_malloc(size_t num, const char *file, int line) { - return CRYPTO_malloc(num, file, line); -} -static void copenssl_CRYPTO_free(void * obj, const char *file, int line) { - CRYPTO_free(obj, file, line); -} -static void copenssl_SSL_CTX_set_options(SSL_CTX * sslCtx) { - SSL_CTX_set_options(sslCtx, SSL_OP_ALL); -} -#undef CRYPTO_set_locking_callback -static void CRYPTO_set_locking_callback(void (*func) (int mode, int type, - const char *file, int line)) {} -#undef CRYPTO_num_locks -static int CRYPTO_num_locks(void) { - return 0; -} -#undef CRYPTO_set_id_callback -static void CRYPTO_set_id_callback(unsigned long (*func) (void)) {} -#undef SSL_CTX_get_ex_new_index -static int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) { - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, - new_func, dup_func, free_func); -} -#undef SSL_get_ex_new_index -static int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) { - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, - new_func, dup_func, free_func); -} - -struct bio_method_st {}; -struct asn1_object_st {}; -struct ASN1_ITEM_st {}; -struct asn1_pctx_st {}; -struct asn1_sctx_st {}; -struct dane_st {}; -struct bio_st {}; -struct bignum_st {}; -struct bignum_ctx {}; -struct bn_blinding_st {}; -struct bn_mont_ctx_st {}; -struct bn_recp_ctx_st {}; -struct bn_gencb_st {}; -struct evp_cipher_st {}; -struct evp_cipher_ctx_st {}; -struct evp_md_st {}; -struct evp_md_ctx_st {}; -struct evp_pkey_st {}; -struct evp_pkey_asn1_method_st {}; -struct evp_pkey_method_st {}; -struct evp_pkey_ctx_st {}; -struct evp_Encode_Ctx_st {}; -struct hmac_ctx_st {}; -struct dh_st {}; -struct dh_method {}; -struct dsa_st {}; -struct dsa_method {}; -struct rsa_st {}; -struct rsa_meth_st {}; -struct ec_key_st {}; -struct ec_key_method_st {}; -struct ssl_dane_st {}; -struct x509_st {}; -struct X509_crl_st {}; -struct x509_crl_method_st {}; -struct x509_revoked_st {}; -struct X509_name_st {}; -struct X509_pubkey_st {}; -struct x509_store_st {}; -struct x509_store_ctx_st {}; -struct x509_object_st {}; -struct x509_lookup_st {}; -struct x509_lookup_method_st {}; -struct X509_VERIFY_PARAM_st {}; -struct pkcs8_priv_key_info_st {}; -struct ossl_init_settings_st {}; -struct ui_st {}; -struct ui_method_st {}; -struct engine_st {}; -struct ssl_st {}; -struct ssl_ctx_st {}; -struct comp_ctx_st {}; -struct comp_method_st {}; -struct X509_POLICY_NODE_st {}; -struct X509_POLICY_LEVEL_st {}; -struct X509_POLICY_TREE_st {}; -struct X509_POLICY_CACHE_st {}; -struct ocsp_req_ctx_st {}; -struct ocsp_response_st {}; -struct ocsp_responder_id_st {}; -struct sct_st {}; -struct sct_ctx_st {}; -struct ctlog_st {}; -struct ctlog_store_st {}; -struct ct_policy_eval_ctx_st {}; -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000L - -static void *OPENSSL_zalloc(size_t num) -{ - void *ret = OPENSSL_malloc(num); - - if (ret != NULL) - memset(ret, 0, num); - return ret; -} - -int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) -{ - /* If the fields n and e in r are NULL, the corresponding input - * parameters MUST be non-NULL for n and e. d may be - * left NULL (in case only the public key is used). - */ - if ((r->n == NULL && n == NULL) - || (r->e == NULL && e == NULL)) - return 0; - - if (n != NULL) { - BN_free(r->n); - r->n = n; - } - if (e != NULL) { - BN_free(r->e); - r->e = e; - } - if (d != NULL) { - BN_free(r->d); - r->d = d; - } - - return 1; -} - -int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) -{ - /* If the fields p and q in r are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((r->p == NULL && p == NULL) - || (r->q == NULL && q == NULL)) - return 0; - - if (p != NULL) { - BN_free(r->p); - r->p = p; - } - if (q != NULL) { - BN_free(r->q); - r->q = q; - } - - return 1; -} - -int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) -{ - /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((r->dmp1 == NULL && dmp1 == NULL) - || (r->dmq1 == NULL && dmq1 == NULL) - || (r->iqmp == NULL && iqmp == NULL)) - return 0; - - if (dmp1 != NULL) { - BN_free(r->dmp1); - r->dmp1 = dmp1; - } - if (dmq1 != NULL) { - BN_free(r->dmq1); - r->dmq1 = dmq1; - } - if (iqmp != NULL) { - BN_free(r->iqmp); - r->iqmp = iqmp; - } - - return 1; -} - -void RSA_get0_key(const RSA *r, - const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) -{ - if (n != NULL) - *n = r->n; - if (e != NULL) - *e = r->e; - if (d != NULL) - *d = r->d; -} - -void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) -{ - if (p != NULL) - *p = r->p; - if (q != NULL) - *q = r->q; -} - -void RSA_get0_crt_params(const RSA *r, - const BIGNUM **dmp1, const BIGNUM **dmq1, - const BIGNUM **iqmp) -{ - if (dmp1 != NULL) - *dmp1 = r->dmp1; - if (dmq1 != NULL) - *dmq1 = r->dmq1; - if (iqmp != NULL) - *iqmp = r->iqmp; -} - -void DSA_get0_pqg(const DSA *d, - const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) -{ - if (p != NULL) - *p = d->p; - if (q != NULL) - *q = d->q; - if (g != NULL) - *g = d->g; -} - -int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) -{ - /* If the fields p, q and g in d are NULL, the corresponding input - * parameters MUST be non-NULL. - */ - if ((d->p == NULL && p == NULL) - || (d->q == NULL && q == NULL) - || (d->g == NULL && g == NULL)) - return 0; - - if (p != NULL) { - BN_free(d->p); - d->p = p; - } - if (q != NULL) { - BN_free(d->q); - d->q = q; - } - if (g != NULL) { - BN_free(d->g); - d->g = g; - } - - return 1; -} - -void DSA_get0_key(const DSA *d, - const BIGNUM **pub_key, const BIGNUM **priv_key) -{ - if (pub_key != NULL) - *pub_key = d->pub_key; - if (priv_key != NULL) - *priv_key = d->priv_key; -} - -int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) -{ - /* If the field pub_key in d is NULL, the corresponding input - * parameters MUST be non-NULL. The priv_key field may - * be left NULL. - */ - if (d->pub_key == NULL && pub_key == NULL) - return 0; - - if (pub_key != NULL) { - BN_free(d->pub_key); - d->pub_key = pub_key; - } - if (priv_key != NULL) { - BN_free(d->priv_key); - d->priv_key = priv_key; - } - - return 1; -} - -void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -{ - if (pr != NULL) - *pr = sig->r; - if (ps != NULL) - *ps = sig->s; -} - -int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) -{ - if (r == NULL || s == NULL) - return 0; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - return 1; -} - -void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) -{ - if (pr != NULL) - *pr = sig->r; - if (ps != NULL) - *ps = sig->s; -} - -int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) -{ - if (r == NULL || s == NULL) - return 0; - BN_clear_free(sig->r); - BN_clear_free(sig->s); - sig->r = r; - sig->s = s; - return 1; -} - -void DH_get0_pqg(const DH *dh, - const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) -{ - if (p != NULL) - *p = dh->p; - if (q != NULL) - *q = dh->q; - if (g != NULL) - *g = dh->g; -} - -int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) -{ - /* If the fields p and g in d are NULL, the corresponding input - * parameters MUST be non-NULL. q may remain NULL. - */ - if ((dh->p == NULL && p == NULL) - || (dh->g == NULL && g == NULL)) - return 0; - - if (p != NULL) { - BN_free(dh->p); - dh->p = p; - } - if (q != NULL) { - BN_free(dh->q); - dh->q = q; - } - if (g != NULL) { - BN_free(dh->g); - dh->g = g; - } - - if (q != NULL) { - dh->length = BN_num_bits(q); - } - - return 1; -} - -void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) -{ - if (pub_key != NULL) - *pub_key = dh->pub_key; - if (priv_key != NULL) - *priv_key = dh->priv_key; -} - -int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) -{ - /* If the field pub_key in dh is NULL, the corresponding input - * parameters MUST be non-NULL. The priv_key field may - * be left NULL. - */ - if (dh->pub_key == NULL && pub_key == NULL) - return 0; - - if (pub_key != NULL) { - BN_free(dh->pub_key); - dh->pub_key = pub_key; - } - if (priv_key != NULL) { - BN_free(dh->priv_key); - dh->priv_key = priv_key; - } - - return 1; -} - -int DH_set_length(DH *dh, long length) -{ - dh->length = length; - return 1; -} - -const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx) -{ - return ctx->iv; -} - -unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx) -{ - return ctx->iv; -} - -EVP_MD_CTX *EVP_MD_CTX_new(void) -{ - return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); -} - -void EVP_MD_CTX_free(EVP_MD_CTX *ctx) -{ - EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(ctx); -} - -RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth) -{ - RSA_METHOD *ret; - - ret = OPENSSL_malloc(sizeof(RSA_METHOD)); - - if (ret != NULL) { - memcpy(ret, meth, sizeof(*meth)); - ret->name = OPENSSL_strdup(meth->name); - if (ret->name == NULL) { - OPENSSL_free(ret); - return NULL; - } - } - - return ret; -} - -int RSA_meth_set1_name(RSA_METHOD *meth, const char *name) -{ - char *tmpname; - - tmpname = OPENSSL_strdup(name); - if (tmpname == NULL) { - return 0; - } - - OPENSSL_free((char *)meth->name); - meth->name = tmpname; - - return 1; -} - -int RSA_meth_set_priv_enc(RSA_METHOD *meth, - int (*priv_enc) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, - int padding)) -{ - meth->rsa_priv_enc = priv_enc; - return 1; -} - -int RSA_meth_set_priv_dec(RSA_METHOD *meth, - int (*priv_dec) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, - int padding)) -{ - meth->rsa_priv_dec = priv_dec; - return 1; -} - -int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa)) -{ - meth->finish = finish; - return 1; -} - -void RSA_meth_free(RSA_METHOD *meth) -{ - if (meth != NULL) { - OPENSSL_free((char *)meth->name); - OPENSSL_free(meth); - } -} - -int RSA_bits(const RSA *r) -{ - return (BN_num_bits(r->n)); -} - -RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_RSA) { - return NULL; - } - return pkey->pkey.rsa; -} - -#endif - -#endif diff --git a/Sources/COpenSSL/krb5_asn.c b/Sources/COpenSSL/krb5_asn.c deleted file mode 100644 index 6fa094c2..00000000 --- a/Sources/COpenSSL/krb5_asn.c +++ /dev/null @@ -1,162 +0,0 @@ -/* krb5_asn.c */ -/* - * Written by Vern Staats for the OpenSSL project, ** - * using ocsp/{*.h,*asn*.c} as a starting point - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#include "asn1.h" -#include "asn1t.h" -#include "krb5_asn.h" - - -ASN1_SEQUENCE(KRB5_ENCDATA) = { - ASN1_EXP(KRB5_ENCDATA, etype, ASN1_INTEGER, 0), - ASN1_EXP_OPT(KRB5_ENCDATA, kvno, ASN1_INTEGER, 1), - ASN1_EXP(KRB5_ENCDATA, cipher, ASN1_OCTET_STRING,2) -} ASN1_SEQUENCE_END(KRB5_ENCDATA) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCDATA) - - -ASN1_SEQUENCE(KRB5_PRINCNAME) = { - ASN1_EXP(KRB5_PRINCNAME, nametype, ASN1_INTEGER, 0), - ASN1_EXP_SEQUENCE_OF(KRB5_PRINCNAME, namestring, ASN1_GENERALSTRING, 1) -} ASN1_SEQUENCE_END(KRB5_PRINCNAME) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_PRINCNAME) - -/* [APPLICATION 1] = 0x61 */ -ASN1_SEQUENCE(KRB5_TKTBODY) = { - ASN1_EXP(KRB5_TKTBODY, tktvno, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_TKTBODY, realm, ASN1_GENERALSTRING, 1), - ASN1_EXP(KRB5_TKTBODY, sname, KRB5_PRINCNAME, 2), - ASN1_EXP(KRB5_TKTBODY, encdata, KRB5_ENCDATA, 3) -} ASN1_SEQUENCE_END(KRB5_TKTBODY) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_TKTBODY) - - -ASN1_ITEM_TEMPLATE(KRB5_TICKET) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 1, - KRB5_TICKET, KRB5_TKTBODY) -ASN1_ITEM_TEMPLATE_END(KRB5_TICKET) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_TICKET) - -/* [APPLICATION 14] = 0x6e */ -ASN1_SEQUENCE(KRB5_APREQBODY) = { - ASN1_EXP(KRB5_APREQBODY, pvno, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_APREQBODY, msgtype, ASN1_INTEGER, 1), - ASN1_EXP(KRB5_APREQBODY, apoptions, ASN1_BIT_STRING, 2), - ASN1_EXP(KRB5_APREQBODY, ticket, KRB5_TICKET, 3), - ASN1_EXP(KRB5_APREQBODY, authenticator, KRB5_ENCDATA, 4), -} ASN1_SEQUENCE_END(KRB5_APREQBODY) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQBODY) - -ASN1_ITEM_TEMPLATE(KRB5_APREQ) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 14, - KRB5_APREQ, KRB5_APREQBODY) -ASN1_ITEM_TEMPLATE_END(KRB5_APREQ) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQ) - -/* Authenticator stuff */ - -ASN1_SEQUENCE(KRB5_CHECKSUM) = { - ASN1_EXP(KRB5_CHECKSUM, ctype, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_CHECKSUM, checksum, ASN1_OCTET_STRING,1) -} ASN1_SEQUENCE_END(KRB5_CHECKSUM) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_CHECKSUM) - - -ASN1_SEQUENCE(KRB5_ENCKEY) = { - ASN1_EXP(KRB5_ENCKEY, ktype, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_ENCKEY, keyvalue, ASN1_OCTET_STRING,1) -} ASN1_SEQUENCE_END(KRB5_ENCKEY) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCKEY) - -/* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */ -ASN1_SEQUENCE(KRB5_AUTHDATA) = { - ASN1_EXP(KRB5_AUTHDATA, adtype, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_AUTHDATA, addata, ASN1_OCTET_STRING,1) -} ASN1_SEQUENCE_END(KRB5_AUTHDATA) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHDATA) - -/* [APPLICATION 2] = 0x62 */ -ASN1_SEQUENCE(KRB5_AUTHENTBODY) = { - ASN1_EXP(KRB5_AUTHENTBODY, avno, ASN1_INTEGER, 0), - ASN1_EXP(KRB5_AUTHENTBODY, crealm, ASN1_GENERALSTRING, 1), - ASN1_EXP(KRB5_AUTHENTBODY, cname, KRB5_PRINCNAME, 2), - ASN1_EXP_OPT(KRB5_AUTHENTBODY, cksum, KRB5_CHECKSUM, 3), - ASN1_EXP(KRB5_AUTHENTBODY, cusec, ASN1_INTEGER, 4), - ASN1_EXP(KRB5_AUTHENTBODY, ctime, ASN1_GENERALIZEDTIME, 5), - ASN1_EXP_OPT(KRB5_AUTHENTBODY, subkey, KRB5_ENCKEY, 6), - ASN1_EXP_OPT(KRB5_AUTHENTBODY, seqnum, ASN1_INTEGER, 7), - ASN1_EXP_SEQUENCE_OF_OPT - (KRB5_AUTHENTBODY, authorization, KRB5_AUTHDATA, 8), -} ASN1_SEQUENCE_END(KRB5_AUTHENTBODY) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) - -ASN1_ITEM_TEMPLATE(KRB5_AUTHENT) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 2, - KRB5_AUTHENT, KRB5_AUTHENTBODY) -ASN1_ITEM_TEMPLATE_END(KRB5_AUTHENT) - -IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENT) diff --git a/Sources/COpenSSL/krb5_asn.h b/Sources/COpenSSL/krb5_asn.h deleted file mode 100644 index 9fd6720c..00000000 --- a/Sources/COpenSSL/krb5_asn.h +++ /dev/null @@ -1,240 +0,0 @@ -/* krb5_asn.h */ -/* - * Written by Vern Staats for the OpenSSL project, ** - * using ocsp/{*.h,*asn*.c} as a starting point - */ - -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_KRB5_ASN_H -# define HEADER_KRB5_ASN_H - -/* - * #include - */ -# include "safestack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * ASN.1 from Kerberos RFC 1510 - */ - -/*- EncryptedData ::= SEQUENCE { - * etype[0] INTEGER, -- EncryptionType - * kvno[1] INTEGER OPTIONAL, - * cipher[2] OCTET STRING -- ciphertext - * } - */ -typedef struct krb5_encdata_st { - ASN1_INTEGER *etype; - ASN1_INTEGER *kvno; - ASN1_OCTET_STRING *cipher; -} KRB5_ENCDATA; - -DECLARE_STACK_OF(KRB5_ENCDATA) - -/*- PrincipalName ::= SEQUENCE { - * name-type[0] INTEGER, - * name-string[1] SEQUENCE OF GeneralString - * } - */ -typedef struct krb5_princname_st { - ASN1_INTEGER *nametype; - STACK_OF(ASN1_GENERALSTRING) *namestring; -} KRB5_PRINCNAME; - -DECLARE_STACK_OF(KRB5_PRINCNAME) - -/*- Ticket ::= [APPLICATION 1] SEQUENCE { - * tkt-vno[0] INTEGER, - * realm[1] Realm, - * sname[2] PrincipalName, - * enc-part[3] EncryptedData - * } - */ -typedef struct krb5_tktbody_st { - ASN1_INTEGER *tktvno; - ASN1_GENERALSTRING *realm; - KRB5_PRINCNAME *sname; - KRB5_ENCDATA *encdata; -} KRB5_TKTBODY; - -typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET; -DECLARE_STACK_OF(KRB5_TKTBODY) - -/*- AP-REQ ::= [APPLICATION 14] SEQUENCE { - * pvno[0] INTEGER, - * msg-type[1] INTEGER, - * ap-options[2] APOptions, - * ticket[3] Ticket, - * authenticator[4] EncryptedData - * } - * - * APOptions ::= BIT STRING { - * reserved(0), use-session-key(1), mutual-required(2) } - */ -typedef struct krb5_ap_req_st { - ASN1_INTEGER *pvno; - ASN1_INTEGER *msgtype; - ASN1_BIT_STRING *apoptions; - KRB5_TICKET *ticket; - KRB5_ENCDATA *authenticator; -} KRB5_APREQBODY; - -typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ; -DECLARE_STACK_OF(KRB5_APREQBODY) - -/* Authenticator Stuff */ - -/*- Checksum ::= SEQUENCE { - * cksumtype[0] INTEGER, - * checksum[1] OCTET STRING - * } - */ -typedef struct krb5_checksum_st { - ASN1_INTEGER *ctype; - ASN1_OCTET_STRING *checksum; -} KRB5_CHECKSUM; - -DECLARE_STACK_OF(KRB5_CHECKSUM) - -/*- EncryptionKey ::= SEQUENCE { - * keytype[0] INTEGER, - * keyvalue[1] OCTET STRING - * } - */ -typedef struct krb5_encryptionkey_st { - ASN1_INTEGER *ktype; - ASN1_OCTET_STRING *keyvalue; -} KRB5_ENCKEY; - -DECLARE_STACK_OF(KRB5_ENCKEY) - -/*- AuthorizationData ::= SEQUENCE OF SEQUENCE { - * ad-type[0] INTEGER, - * ad-data[1] OCTET STRING - * } - */ -typedef struct krb5_authorization_st { - ASN1_INTEGER *adtype; - ASN1_OCTET_STRING *addata; -} KRB5_AUTHDATA; - -DECLARE_STACK_OF(KRB5_AUTHDATA) - -/*- -- Unencrypted authenticator - * Authenticator ::= [APPLICATION 2] SEQUENCE { - * authenticator-vno[0] INTEGER, - * crealm[1] Realm, - * cname[2] PrincipalName, - * cksum[3] Checksum OPTIONAL, - * cusec[4] INTEGER, - * ctime[5] KerberosTime, - * subkey[6] EncryptionKey OPTIONAL, - * seq-number[7] INTEGER OPTIONAL, - * authorization-data[8] AuthorizationData OPTIONAL - * } - */ -typedef struct krb5_authenticator_st { - ASN1_INTEGER *avno; - ASN1_GENERALSTRING *crealm; - KRB5_PRINCNAME *cname; - KRB5_CHECKSUM *cksum; - ASN1_INTEGER *cusec; - ASN1_GENERALIZEDTIME *ctime; - KRB5_ENCKEY *subkey; - ASN1_INTEGER *seqnum; - KRB5_AUTHDATA *authorization; -} KRB5_AUTHENTBODY; - -typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT; -DECLARE_STACK_OF(KRB5_AUTHENTBODY) - -/*- DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) = - * type *name##_new(void); - * void name##_free(type *a); - * DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) = - * DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) = - * type *d2i_##name(type **a, const unsigned char **in, long len); - * int i2d_##name(type *a, unsigned char **out); - * DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it - */ - -DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA) -DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME) -DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY) -DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY) -DECLARE_ASN1_FUNCTIONS(KRB5_TICKET) -DECLARE_ASN1_FUNCTIONS(KRB5_APREQ) - -DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM) -DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY) -DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA) -DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) -DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT) - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/kssl.c b/Sources/COpenSSL/kssl.c deleted file mode 100644 index e291c1c4..00000000 --- a/Sources/COpenSSL/kssl.c +++ /dev/null @@ -1,2271 +0,0 @@ -/* ssl/kssl.c */ -/* - * Written by Vern Staats for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/*- - * ssl/kssl.c -- Routines to support (& debug) Kerberos5 auth for openssl - * - * 19990701 VRS Started. - * 200011?? Jeffrey Altman, Richard Levitte - * Generalized for Heimdal, Newer MIT, & Win32. - * Integrated into main OpenSSL 0.9.7 snapshots. - * 20010413 Simon Wilkinson, VRS - * Real RFC2712 KerberosWrapper replaces AP_REQ. - */ - -#include "opensslconf.h" - -#include - -#define KRB5_PRIVATE 1 - -#include "ssl.h" -#include "evp.h" -#include "objects.h" -#include "krb5_asn.h" -#include "o_time.h" -#include "kssl_lcl.h" - -#ifndef OPENSSL_NO_KRB5 - -# ifndef ENOMEM -# define ENOMEM KRB5KRB_ERR_GENERIC -# endif - -/* - * When OpenSSL is built on Windows, we do not want to require that - * the Kerberos DLLs be available in order for the OpenSSL DLLs to - * work. Therefore, all Kerberos routines are loaded at run time - * and we do not link to a .LIB file. - */ - -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) -/* - * The purpose of the following pre-processor statements is to provide - * compatibility with different releases of MIT Kerberos for Windows. - * All versions up to 1.2 used macros. But macros do not allow for - * a binary compatible interface for DLLs. Therefore, all macros are - * being replaced by function calls. The following code will allow - * an OpenSSL DLL built on Windows to work whether or not the macro - * or function form of the routines are utilized. - */ -# ifdef krb5_cc_get_principal -# define NO_DEF_KRB5_CCACHE -# undef krb5_cc_get_principal -# endif -# define krb5_cc_get_principal kssl_krb5_cc_get_principal - -# define krb5_free_data_contents kssl_krb5_free_data_contents -# define krb5_free_context kssl_krb5_free_context -# define krb5_auth_con_free kssl_krb5_auth_con_free -# define krb5_free_principal kssl_krb5_free_principal -# define krb5_mk_req_extended kssl_krb5_mk_req_extended -# define krb5_get_credentials kssl_krb5_get_credentials -# define krb5_cc_default kssl_krb5_cc_default -# define krb5_sname_to_principal kssl_krb5_sname_to_principal -# define krb5_init_context kssl_krb5_init_context -# define krb5_free_ticket kssl_krb5_free_ticket -# define krb5_rd_req kssl_krb5_rd_req -# define krb5_kt_default kssl_krb5_kt_default -# define krb5_kt_resolve kssl_krb5_kt_resolve -/* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */ -# ifndef krb5_kt_close -# define krb5_kt_close kssl_krb5_kt_close -# endif /* krb5_kt_close */ -# ifndef krb5_kt_get_entry -# define krb5_kt_get_entry kssl_krb5_kt_get_entry -# endif /* krb5_kt_get_entry */ -# define krb5_auth_con_init kssl_krb5_auth_con_init - -# define krb5_principal_compare kssl_krb5_principal_compare -# define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part -# define krb5_timeofday kssl_krb5_timeofday -# define krb5_rc_default kssl_krb5_rc_default - -# ifdef krb5_rc_initialize -# undef krb5_rc_initialize -# endif -# define krb5_rc_initialize kssl_krb5_rc_initialize - -# ifdef krb5_rc_get_lifespan -# undef krb5_rc_get_lifespan -# endif -# define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan - -# ifdef krb5_rc_destroy -# undef krb5_rc_destroy -# endif -# define krb5_rc_destroy kssl_krb5_rc_destroy - -# define valid_cksumtype kssl_valid_cksumtype -# define krb5_checksum_size kssl_krb5_checksum_size -# define krb5_kt_free_entry kssl_krb5_kt_free_entry -# define krb5_auth_con_setrcache kssl_krb5_auth_con_setrcache -# define krb5_auth_con_getrcache kssl_krb5_auth_con_getrcache -# define krb5_get_server_rcache kssl_krb5_get_server_rcache - -/* Prototypes for built in stubs */ -void kssl_krb5_free_data_contents(krb5_context, krb5_data *); -void kssl_krb5_free_principal(krb5_context, krb5_principal); -krb5_error_code kssl_krb5_kt_resolve(krb5_context, - krb5_const char *, krb5_keytab *); -krb5_error_code kssl_krb5_kt_default(krb5_context, krb5_keytab *); -krb5_error_code kssl_krb5_free_ticket(krb5_context, krb5_ticket *); -krb5_error_code kssl_krb5_rd_req(krb5_context, krb5_auth_context *, - krb5_const krb5_data *, - krb5_const_principal, krb5_keytab, - krb5_flags *, krb5_ticket **); - -krb5_boolean kssl_krb5_principal_compare(krb5_context, krb5_const_principal, - krb5_const_principal); -krb5_error_code kssl_krb5_mk_req_extended(krb5_context, - krb5_auth_context *, - krb5_const krb5_flags, - krb5_data *, - krb5_creds *, krb5_data *); -krb5_error_code kssl_krb5_init_context(krb5_context *); -void kssl_krb5_free_context(krb5_context); -krb5_error_code kssl_krb5_cc_default(krb5_context, krb5_ccache *); -krb5_error_code kssl_krb5_sname_to_principal(krb5_context, - krb5_const char *, - krb5_const char *, - krb5_int32, krb5_principal *); -krb5_error_code kssl_krb5_get_credentials(krb5_context, - krb5_const krb5_flags, - krb5_ccache, - krb5_creds *, krb5_creds * *); -krb5_error_code kssl_krb5_auth_con_init(krb5_context, krb5_auth_context *); -krb5_error_code kssl_krb5_cc_get_principal(krb5_context context, - krb5_ccache cache, - krb5_principal *principal); -krb5_error_code kssl_krb5_auth_con_free(krb5_context, krb5_auth_context); -size_t kssl_krb5_checksum_size(krb5_context context, krb5_cksumtype ctype); -krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype); -krb5_error_code krb5_kt_free_entry(krb5_context, krb5_keytab_entry FAR *); -krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context, - krb5_auth_context, krb5_rcache); -krb5_error_code kssl_krb5_get_server_rcache(krb5_context, - krb5_const krb5_data *, - krb5_rcache *); -krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context, - krb5_auth_context, - krb5_rcache *); - -/* Function pointers (almost all Kerberos functions are _stdcall) */ -static void (_stdcall *p_krb5_free_data_contents) (krb5_context, krb5_data *) - = NULL; -static void (_stdcall *p_krb5_free_principal) (krb5_context, krb5_principal) - = NULL; -static krb5_error_code(_stdcall *p_krb5_kt_resolve) - (krb5_context, krb5_const char *, krb5_keytab *) = NULL; -static krb5_error_code(_stdcall *p_krb5_kt_default) (krb5_context, - krb5_keytab *) = NULL; -static krb5_error_code(_stdcall *p_krb5_free_ticket) (krb5_context, - krb5_ticket *) = NULL; -static krb5_error_code(_stdcall *p_krb5_rd_req) (krb5_context, - krb5_auth_context *, - krb5_const krb5_data *, - krb5_const_principal, - krb5_keytab, krb5_flags *, - krb5_ticket **) = NULL; -static krb5_error_code(_stdcall *p_krb5_mk_req_extended) - (krb5_context, krb5_auth_context *, - krb5_const krb5_flags, krb5_data *, krb5_creds *, krb5_data *) = NULL; -static krb5_error_code(_stdcall *p_krb5_init_context) (krb5_context *) = NULL; -static void (_stdcall *p_krb5_free_context) (krb5_context) = NULL; -static krb5_error_code(_stdcall *p_krb5_cc_default) (krb5_context, - krb5_ccache *) = NULL; -static krb5_error_code(_stdcall *p_krb5_sname_to_principal) - (krb5_context, krb5_const char *, krb5_const char *, - krb5_int32, krb5_principal *) = NULL; -static krb5_error_code(_stdcall *p_krb5_get_credentials) - (krb5_context, krb5_const krb5_flags, krb5_ccache, - krb5_creds *, krb5_creds **) = NULL; -static krb5_error_code(_stdcall *p_krb5_auth_con_init) - (krb5_context, krb5_auth_context *) = NULL; -static krb5_error_code(_stdcall *p_krb5_cc_get_principal) - (krb5_context context, krb5_ccache cache, krb5_principal *principal) = NULL; -static krb5_error_code(_stdcall *p_krb5_auth_con_free) - (krb5_context, krb5_auth_context) = NULL; -static krb5_error_code(_stdcall *p_krb5_decrypt_tkt_part) - (krb5_context, krb5_const krb5_keyblock *, krb5_ticket *) = NULL; -static krb5_error_code(_stdcall *p_krb5_timeofday) - (krb5_context context, krb5_int32 *timeret) = NULL; -static krb5_error_code(_stdcall *p_krb5_rc_default) - (krb5_context context, krb5_rcache *rc) = NULL; -static krb5_error_code(_stdcall *p_krb5_rc_initialize) - (krb5_context context, krb5_rcache rc, krb5_deltat lifespan) = NULL; -static krb5_error_code(_stdcall *p_krb5_rc_get_lifespan) - (krb5_context context, krb5_rcache rc, krb5_deltat *lifespan) = NULL; -static krb5_error_code(_stdcall *p_krb5_rc_destroy) - (krb5_context context, krb5_rcache rc) = NULL; -static krb5_boolean(_stdcall *p_krb5_principal_compare) - (krb5_context, krb5_const_principal, krb5_const_principal) = NULL; -static size_t (_stdcall *p_krb5_checksum_size) (krb5_context context, - krb5_cksumtype ctype) = NULL; -static krb5_boolean(_stdcall *p_valid_cksumtype) (krb5_cksumtype ctype) = - NULL; -static krb5_error_code(_stdcall *p_krb5_kt_free_entry) - (krb5_context, krb5_keytab_entry *) = NULL; -static krb5_error_code(_stdcall *p_krb5_auth_con_setrcache) (krb5_context, - krb5_auth_context, - krb5_rcache) = - NULL; -static krb5_error_code(_stdcall *p_krb5_get_server_rcache) (krb5_context, - krb5_const - krb5_data *, - krb5_rcache *) = - NULL; -static krb5_error_code(*p_krb5_auth_con_getrcache) (krb5_context, - krb5_auth_context, - krb5_rcache *) = NULL; -static krb5_error_code(_stdcall *p_krb5_kt_close) (krb5_context context, - krb5_keytab keytab) = NULL; -static krb5_error_code(_stdcall *p_krb5_kt_get_entry) (krb5_context context, - krb5_keytab keytab, - krb5_const_principal - principal, - krb5_kvno vno, - krb5_enctype enctype, - krb5_keytab_entry - *entry) = NULL; -static int krb5_loaded = 0; /* only attempt to initialize func ptrs once */ - -/* Function to Load the Kerberos 5 DLL and initialize function pointers */ -void load_krb5_dll(void) -{ - HANDLE hKRB5_32; - - krb5_loaded++; - hKRB5_32 = LoadLibrary(TEXT("KRB5_32")); - if (!hKRB5_32) - return; - - (FARPROC) p_krb5_free_data_contents = - GetProcAddress(hKRB5_32, "krb5_free_data_contents"); - (FARPROC) p_krb5_free_context = - GetProcAddress(hKRB5_32, "krb5_free_context"); - (FARPROC) p_krb5_auth_con_free = - GetProcAddress(hKRB5_32, "krb5_auth_con_free"); - (FARPROC) p_krb5_free_principal = - GetProcAddress(hKRB5_32, "krb5_free_principal"); - (FARPROC) p_krb5_mk_req_extended = - GetProcAddress(hKRB5_32, "krb5_mk_req_extended"); - (FARPROC) p_krb5_get_credentials = - GetProcAddress(hKRB5_32, "krb5_get_credentials"); - (FARPROC) p_krb5_cc_get_principal = - GetProcAddress(hKRB5_32, "krb5_cc_get_principal"); - (FARPROC) p_krb5_cc_default = GetProcAddress(hKRB5_32, "krb5_cc_default"); - (FARPROC) p_krb5_sname_to_principal = - GetProcAddress(hKRB5_32, "krb5_sname_to_principal"); - (FARPROC) p_krb5_init_context = - GetProcAddress(hKRB5_32, "krb5_init_context"); - (FARPROC) p_krb5_free_ticket = - GetProcAddress(hKRB5_32, "krb5_free_ticket"); - (FARPROC) p_krb5_rd_req = GetProcAddress(hKRB5_32, "krb5_rd_req"); - (FARPROC) p_krb5_principal_compare = - GetProcAddress(hKRB5_32, "krb5_principal_compare"); - (FARPROC) p_krb5_decrypt_tkt_part = - GetProcAddress(hKRB5_32, "krb5_decrypt_tkt_part"); - (FARPROC) p_krb5_timeofday = GetProcAddress(hKRB5_32, "krb5_timeofday"); - (FARPROC) p_krb5_rc_default = GetProcAddress(hKRB5_32, "krb5_rc_default"); - (FARPROC) p_krb5_rc_initialize = - GetProcAddress(hKRB5_32, "krb5_rc_initialize"); - (FARPROC) p_krb5_rc_get_lifespan = - GetProcAddress(hKRB5_32, "krb5_rc_get_lifespan"); - (FARPROC) p_krb5_rc_destroy = GetProcAddress(hKRB5_32, "krb5_rc_destroy"); - (FARPROC) p_krb5_kt_default = GetProcAddress(hKRB5_32, "krb5_kt_default"); - (FARPROC) p_krb5_kt_resolve = GetProcAddress(hKRB5_32, "krb5_kt_resolve"); - (FARPROC) p_krb5_auth_con_init = - GetProcAddress(hKRB5_32, "krb5_auth_con_init"); - (FARPROC) p_valid_cksumtype = GetProcAddress(hKRB5_32, "valid_cksumtype"); - (FARPROC) p_krb5_checksum_size = - GetProcAddress(hKRB5_32, "krb5_checksum_size"); - (FARPROC) p_krb5_kt_free_entry = - GetProcAddress(hKRB5_32, "krb5_kt_free_entry"); - (FARPROC) p_krb5_auth_con_setrcache = - GetProcAddress(hKRB5_32, "krb5_auth_con_setrcache"); - (FARPROC) p_krb5_get_server_rcache = - GetProcAddress(hKRB5_32, "krb5_get_server_rcache"); - (FARPROC) p_krb5_auth_con_getrcache = - GetProcAddress(hKRB5_32, "krb5_auth_con_getrcache"); - (FARPROC) p_krb5_kt_close = GetProcAddress(hKRB5_32, "krb5_kt_close"); - (FARPROC) p_krb5_kt_get_entry = - GetProcAddress(hKRB5_32, "krb5_kt_get_entry"); -} - -/* Stubs for each function to be dynamicly loaded */ -void kssl_krb5_free_data_contents(krb5_context CO, krb5_data *data) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_free_data_contents) - p_krb5_free_data_contents(CO, data); -} - -krb5_error_code -kssl_krb5_mk_req_extended(krb5_context CO, - krb5_auth_context *pACO, - krb5_const krb5_flags F, - krb5_data *pD1, krb5_creds *pC, krb5_data *pD2) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_mk_req_extended) - return (p_krb5_mk_req_extended(CO, pACO, F, pD1, pC, pD2)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_auth_con_init(krb5_context CO, krb5_auth_context *pACO) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_auth_con_init) - return (p_krb5_auth_con_init(CO, pACO)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_auth_con_free(krb5_context CO, krb5_auth_context ACO) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_auth_con_free) - return (p_krb5_auth_con_free(CO, ACO)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_get_credentials(krb5_context CO, - krb5_const krb5_flags F, - krb5_ccache CC, krb5_creds *pCR, krb5_creds **ppCR) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_get_credentials) - return (p_krb5_get_credentials(CO, F, CC, pCR, ppCR)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_sname_to_principal(krb5_context CO, - krb5_const char *pC1, - krb5_const char *pC2, - krb5_int32 I, krb5_principal *pPR) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_sname_to_principal) - return (p_krb5_sname_to_principal(CO, pC1, pC2, I, pPR)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_cc_default(krb5_context CO, krb5_ccache *pCC) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_cc_default) - return (p_krb5_cc_default(CO, pCC)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_init_context(krb5_context *pCO) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_init_context) - return (p_krb5_init_context(pCO)); - else - return KRB5KRB_ERR_GENERIC; -} - -void kssl_krb5_free_context(krb5_context CO) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_free_context) - p_krb5_free_context(CO); -} - -void kssl_krb5_free_principal(krb5_context c, krb5_principal p) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_free_principal) - p_krb5_free_principal(c, p); -} - -krb5_error_code -kssl_krb5_kt_resolve(krb5_context con, krb5_const char *sz, krb5_keytab *kt) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_kt_resolve) - return (p_krb5_kt_resolve(con, sz, kt)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_kt_default(krb5_context con, krb5_keytab *kt) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_kt_default) - return (p_krb5_kt_default(con, kt)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_free_ticket(krb5_context con, krb5_ticket *kt) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_free_ticket) - return (p_krb5_free_ticket(con, kt)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_rd_req(krb5_context con, krb5_auth_context *pacon, - krb5_const krb5_data *data, - krb5_const_principal princ, krb5_keytab keytab, - krb5_flags *flags, krb5_ticket **pptkt) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rd_req) - return (p_krb5_rd_req(con, pacon, data, princ, keytab, flags, pptkt)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_boolean -krb5_principal_compare(krb5_context con, krb5_const_principal princ1, - krb5_const_principal princ2) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_principal_compare) - return (p_krb5_principal_compare(con, princ1, princ2)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -krb5_decrypt_tkt_part(krb5_context con, krb5_const krb5_keyblock *keys, - krb5_ticket *ticket) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_decrypt_tkt_part) - return (p_krb5_decrypt_tkt_part(con, keys, ticket)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code krb5_timeofday(krb5_context con, krb5_int32 *timeret) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_timeofday) - return (p_krb5_timeofday(con, timeret)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code krb5_rc_default(krb5_context con, krb5_rcache *rc) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rc_default) - return (p_krb5_rc_default(con, rc)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -krb5_rc_initialize(krb5_context con, krb5_rcache rc, krb5_deltat lifespan) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rc_initialize) - return (p_krb5_rc_initialize(con, rc, lifespan)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -krb5_rc_get_lifespan(krb5_context con, krb5_rcache rc, krb5_deltat *lifespanp) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rc_get_lifespan) - return (p_krb5_rc_get_lifespan(con, rc, lifespanp)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code krb5_rc_destroy(krb5_context con, krb5_rcache rc) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_rc_destroy) - return (p_krb5_rc_destroy(con, rc)); - else - return KRB5KRB_ERR_GENERIC; -} - -size_t krb5_checksum_size(krb5_context context, krb5_cksumtype ctype) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_checksum_size) - return (p_krb5_checksum_size(context, ctype)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_boolean valid_cksumtype(krb5_cksumtype ctype) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_valid_cksumtype) - return (p_valid_cksumtype(ctype)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code krb5_kt_free_entry(krb5_context con, krb5_keytab_entry *entry) -{ - if (!krb5_loaded) - load_krb5_dll(); - - if (p_krb5_kt_free_entry) - return (p_krb5_kt_free_entry(con, entry)); - else - return KRB5KRB_ERR_GENERIC; -} - -/* Structure definitions */ -# ifndef NO_DEF_KRB5_CCACHE -# ifndef krb5_x -# define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1)) -# define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0)) -# endif - -typedef krb5_pointer krb5_cc_cursor; /* cursor for sequential lookup */ - -typedef struct _krb5_ccache { - krb5_magic magic; - struct _krb5_cc_ops FAR *ops; - krb5_pointer data; -} *krb5_ccache; - -typedef struct _krb5_cc_ops { - krb5_magic magic; - char *prefix; - char *(KRB5_CALLCONV *get_name) - (krb5_context, krb5_ccache); - krb5_error_code(KRB5_CALLCONV *resolve) - (krb5_context, krb5_ccache *, const char *); - krb5_error_code(KRB5_CALLCONV *gen_new) - (krb5_context, krb5_ccache *); - krb5_error_code(KRB5_CALLCONV *init) - (krb5_context, krb5_ccache, krb5_principal); - krb5_error_code(KRB5_CALLCONV *destroy) - (krb5_context, krb5_ccache); - krb5_error_code(KRB5_CALLCONV *close) - (krb5_context, krb5_ccache); - krb5_error_code(KRB5_CALLCONV *store) - (krb5_context, krb5_ccache, krb5_creds *); - krb5_error_code(KRB5_CALLCONV *retrieve) - (krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *); - krb5_error_code(KRB5_CALLCONV *get_princ) - (krb5_context, krb5_ccache, krb5_principal *); - krb5_error_code(KRB5_CALLCONV *get_first) - (krb5_context, krb5_ccache, krb5_cc_cursor *); - krb5_error_code(KRB5_CALLCONV *get_next) - (krb5_context, krb5_ccache, krb5_cc_cursor *, krb5_creds *); - krb5_error_code(KRB5_CALLCONV *end_get) - (krb5_context, krb5_ccache, krb5_cc_cursor *); - krb5_error_code(KRB5_CALLCONV *remove_cred) - (krb5_context, krb5_ccache, krb5_flags, krb5_creds *); - krb5_error_code(KRB5_CALLCONV *set_flags) - (krb5_context, krb5_ccache, krb5_flags); -} krb5_cc_ops; -# endif /* NO_DEF_KRB5_CCACHE */ - -krb5_error_code - kssl_krb5_cc_get_principal - (krb5_context context, krb5_ccache cache, krb5_principal *principal) { - if (p_krb5_cc_get_principal) - return (p_krb5_cc_get_principal(context, cache, principal)); - else - return (krb5_x((cache)->ops->get_princ, (context, cache, principal))); -} - -krb5_error_code -kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon, - krb5_rcache rcache) -{ - if (p_krb5_auth_con_setrcache) - return (p_krb5_auth_con_setrcache(con, acon, rcache)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data *data, - krb5_rcache *rcache) -{ - if (p_krb5_get_server_rcache) - return (p_krb5_get_server_rcache(con, data, rcache)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon, - krb5_rcache *prcache) -{ - if (p_krb5_auth_con_getrcache) - return (p_krb5_auth_con_getrcache(con, acon, prcache)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab) -{ - if (p_krb5_kt_close) - return (p_krb5_kt_close(context, keytab)); - else - return KRB5KRB_ERR_GENERIC; -} - -krb5_error_code -kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, - krb5_const_principal principal, krb5_kvno vno, - krb5_enctype enctype, krb5_keytab_entry *entry) -{ - if (p_krb5_kt_get_entry) - return (p_krb5_kt_get_entry - (context, keytab, principal, vno, enctype, entry)); - else - return KRB5KRB_ERR_GENERIC; -} -# endif /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */ - -/* - * memory allocation functions for non-temporary storage (e.g. stuff that - * gets saved into the kssl context) - */ -static void *kssl_calloc(size_t nmemb, size_t size) -{ - void *p; - - p = OPENSSL_malloc(nmemb * size); - if (p) { - memset(p, 0, nmemb * size); - } - return p; -} - -# define kssl_malloc(size) OPENSSL_malloc((size)) -# define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size) -# define kssl_free(ptr) OPENSSL_free((ptr)) - -char -*kstring(char *string) -{ - static char *null = "[NULL]"; - - return ((string == NULL) ? null : string); -} - -/* - * Given KRB5 enctype (basically DES or 3DES), return closest match openssl - * EVP_ encryption algorithm. Return NULL for unknown or problematic - * (krb5_dk_encrypt) enctypes. Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are - * OK. - */ -const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype) -{ - switch (enctype) { - case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */ - case ENCTYPE_DES_CBC_CRC: - case ENCTYPE_DES_CBC_MD4: - case ENCTYPE_DES_CBC_MD5: - case ENCTYPE_DES_CBC_RAW: - return EVP_des_cbc(); - break; - case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ - case ENCTYPE_DES3_CBC_SHA: - case ENCTYPE_DES3_CBC_RAW: - return EVP_des_ede3_cbc(); - break; - default: - return NULL; - break; - } -} - -/* - * Return true:1 if p "looks like" the start of the real authenticator - * described in kssl_skip_confound() below. The ASN.1 pattern is "62 xx 30 - * yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and xx and yy are - * possibly multi-byte length fields. - */ -static int kssl_test_confound(unsigned char *p) -{ - int len = 2; - int xx = 0, yy = 0; - - if (*p++ != 0x62) - return 0; - if (*p > 0x82) - return 0; - switch (*p) { - case 0x82: - p++; - xx = (*p++ << 8); - xx += *p++; - break; - case 0x81: - p++; - xx = *p++; - break; - case 0x80: - return 0; - default: - xx = *p++; - break; - } - if (*p++ != 0x30) - return 0; - if (*p > 0x82) - return 0; - switch (*p) { - case 0x82: - p++; - len += 2; - yy = (*p++ << 8); - yy += *p++; - break; - case 0x81: - p++; - len++; - yy = *p++; - break; - case 0x80: - return 0; - default: - yy = *p++; - break; - } - - return (xx - len == yy) ? 1 : 0; -} - -/* - * Allocate, fill, and return cksumlens array of checksum lengths. This - * array holds just the unique elements from the krb5_cksumarray[]. array[n] - * == 0 signals end of data. The krb5_cksumarray[] was an internal variable - * that has since been replaced by a more general method for storing the - * data. It should not be used. Instead we use real API calls and make a - * guess for what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 - * it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. - */ -static size_t *populate_cksumlens(void) -{ - int i, j, n; - static size_t *cklens = NULL; - -# ifdef KRB5_MIT_OLD11 - n = krb5_max_cksum; -# else - n = 0x0010; -# endif /* KRB5_MIT_OLD11 */ - -# ifdef KRB5CHECKAUTH - if (!cklens && !(cklens = (size_t *)calloc(sizeof(int), n + 1))) - return NULL; - - for (i = 0; i < n; i++) { - if (!valid_cksumtype(i)) - continue; /* array has holes */ - for (j = 0; j < n; j++) { - if (cklens[j] == 0) { - cklens[j] = krb5_checksum_size(NULL, i); - break; /* krb5 elem was new: add */ - } - if (cklens[j] == krb5_checksum_size(NULL, i)) { - break; /* ignore duplicate elements */ - } - } - } -# endif /* KRB5CHECKAUTH */ - - return cklens; -} - -/*- - * Return pointer to start of real authenticator within authenticator, or - * return NULL on error. - * Decrypted authenticator looks like this: - * [0 or 8 byte confounder] [4-24 byte checksum] [real authent'r] - * This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the - * krb5_auth_con_getcksumtype() function advertised in its krb5.h. - */ -unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) -{ - int i, conlen; - size_t cklen; - static size_t *cksumlens = NULL; - unsigned char *test_auth; - - conlen = (etype) ? 8 : 0; - - if (!cksumlens && !(cksumlens = populate_cksumlens())) - return NULL; - for (i = 0; (cklen = cksumlens[i]) != 0; i++) { - test_auth = a + conlen + cklen; - if (kssl_test_confound(test_auth)) - return test_auth; - } - - return NULL; -} - -/* - * Set kssl_err error info when reason text is a simple string kssl_err = - * struct { int reason; char text[KSSL_ERR_MAX+1]; } - */ -void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text) -{ - if (kssl_err == NULL) - return; - - kssl_err->reason = reason; - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text); - return; -} - -/* - * Display contents of krb5_data struct, for debugging - */ -void print_krb5_data(char *label, krb5_data *kdata) -{ - int i; - - fprintf(stderr, "%s[%d] ", label, kdata->length); - for (i = 0; i < (int)kdata->length; i++) { - if (0 && isprint((int)kdata->data[i])) - fprintf(stderr, "%c ", kdata->data[i]); - else - fprintf(stderr, "%02x ", (unsigned char)kdata->data[i]); - } - fprintf(stderr, "\n"); -} - -/* - * Display contents of krb5_authdata struct, for debugging - */ -void print_krb5_authdata(char *label, krb5_authdata **adata) -{ - if (adata == NULL) { - fprintf(stderr, "%s, authdata==0\n", label); - return; - } - fprintf(stderr, "%s [%p]\n", label, (void *)adata); -# if 0 - { - int i; - fprintf(stderr, "%s[at%d:%d] ", label, adata->ad_type, adata->length); - for (i = 0; i < adata->length; i++) { - fprintf(stderr, (isprint(adata->contents[i])) ? "%c " : "%02x", - adata->contents[i]); - } - fprintf(stderr, "\n"); - } -# endif -} - -/* - * Display contents of krb5_keyblock struct, for debugging - */ -void print_krb5_keyblock(char *label, krb5_keyblock *keyblk) -{ - int i; - - if (keyblk == NULL) { - fprintf(stderr, "%s, keyblk==0\n", label); - return; - } -# ifdef KRB5_HEIMDAL - fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->keytype, - keyblk->keyvalue->length); - for (i = 0; i < (int)keyblk->keyvalue->length; i++) { - fprintf(stderr, "%02x", - (unsigned char *)(keyblk->keyvalue->contents)[i]); - } - fprintf(stderr, "\n"); -# else - fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->enctype, - keyblk->length); - for (i = 0; i < (int)keyblk->length; i++) { - fprintf(stderr, "%02x", keyblk->contents[i]); - } - fprintf(stderr, "\n"); -# endif -} - -/* - * Display contents of krb5_principal_data struct, for debugging - * (krb5_principal is typedef'd == krb5_principal_data *) - */ -static void print_krb5_princ(char *label, krb5_principal_data *princ) -{ - int i, ui, uj; - - fprintf(stderr, "%s principal Realm: ", label); - if (princ == NULL) - return; - for (ui = 0; ui < (int)princ->realm.length; ui++) - putchar(princ->realm.data[ui]); - fprintf(stderr, " (nametype %d) has %d strings:\n", princ->type, - princ->length); - for (i = 0; i < (int)princ->length; i++) { - fprintf(stderr, "\t%d [%d]: ", i, princ->data[i].length); - for (uj = 0; uj < (int)princ->data[i].length; uj++) { - putchar(princ->data[i].data[uj]); - } - fprintf(stderr, "\n"); - } - return; -} - -/*- Given krb5 service (typically "kssl") and hostname in kssl_ctx, - * Return encrypted Kerberos ticket for service @ hostname. - * If authenp is non-NULL, also return encrypted authenticator, - * whose data should be freed by caller. - * (Originally was: Create Kerberos AP_REQ message for SSL Client.) - * - * 19990628 VRS Started; Returns Kerberos AP_REQ message. - * 20010409 VRS Modified for RFC2712; Returns enc tkt. - * 20010606 VRS May also return optional authenticator. - */ -krb5_error_code kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, - /* - * OUT - */ krb5_data **enc_ticketp, - /* - * UPDATE - */ krb5_data *authenp, - /* - * OUT - */ KSSL_ERR *kssl_err) -{ - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - krb5_context krb5context = NULL; - krb5_auth_context krb5auth_context = NULL; - krb5_ccache krb5ccdef = NULL; - krb5_creds krb5creds, *krb5credsp = NULL; - krb5_data krb5_app_req; - - kssl_err_set(kssl_err, 0, ""); - memset((char *)&krb5creds, 0, sizeof(krb5creds)); - - if (!kssl_ctx) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n"); - goto err; - } else if (!kssl_ctx->service_host) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "kssl_ctx service_host undefined.\n"); - goto err; - } - - if ((krb5rc = krb5_init_context(&krb5context)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "krb5_init_context() fails: %d\n", krb5rc); - kssl_err->reason = SSL_R_KRB5_C_INIT; - goto err; - } - - if ((krb5rc = krb5_sname_to_principal(krb5context, - kssl_ctx->service_host, - (kssl_ctx->service_name) ? - kssl_ctx->service_name : KRB5SVC, - KRB5_NT_SRV_HST, - &krb5creds.server)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "krb5_sname_to_principal() fails for %s/%s\n", - kssl_ctx->service_host, - (kssl_ctx-> - service_name) ? kssl_ctx->service_name : KRB5SVC); - kssl_err->reason = SSL_R_KRB5_C_INIT; - goto err; - } - - if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, - "krb5_cc_default fails.\n"); - goto err; - } - - if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, - &krb5creds.client)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, - "krb5_cc_get_principal() fails.\n"); - goto err; - } - - if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, - &krb5creds, &krb5credsp)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED, - "krb5_get_credentials() fails.\n"); - goto err; - } - - *enc_ticketp = &krb5credsp->ticket; -# ifdef KRB5_HEIMDAL - kssl_ctx->enctype = krb5credsp->session.keytype; -# else - kssl_ctx->enctype = krb5credsp->keyblock.enctype; -# endif - - krb5rc = KRB5KRB_ERR_GENERIC; - /* caller should free data of krb5_app_req */ - /* - * 20010406 VRS deleted for real KerberosWrapper 20010605 VRS reinstated - * to offer Authenticator to KerberosWrapper - */ - krb5_app_req.length = 0; - if (authenp) { - krb5_data krb5in_data; - const unsigned char *p; - long arlen; - KRB5_APREQBODY *ap_req; - - authenp->length = 0; - krb5in_data.data = NULL; - krb5in_data.length = 0; - if ((krb5rc = krb5_mk_req_extended(krb5context, - &krb5auth_context, 0, &krb5in_data, - krb5credsp, &krb5_app_req)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ, - "krb5_mk_req_extended() fails.\n"); - goto err; - } - - arlen = krb5_app_req.length; - p = (unsigned char *)krb5_app_req.data; - ap_req = (KRB5_APREQBODY *)d2i_KRB5_APREQ(NULL, &p, arlen); - if (ap_req) { - authenp->length = i2d_KRB5_ENCDATA(ap_req->authenticator, NULL); - if (authenp->length && (authenp->data = malloc(authenp->length))) { - unsigned char *adp = (unsigned char *)authenp->data; - authenp->length = - i2d_KRB5_ENCDATA(ap_req->authenticator, &adp); - } - } - - if (ap_req) - KRB5_APREQ_free((KRB5_APREQ *) ap_req); - if (krb5_app_req.length) - kssl_krb5_free_data_contents(krb5context, &krb5_app_req); - } -# ifdef KRB5_HEIMDAL - if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, - "kssl_ctx_setkey() fails.\n"); - } -# else - if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) { - kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, - "kssl_ctx_setkey() fails.\n"); - } -# endif - else - krb5rc = 0; - - err: -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - if (krb5creds.client) - krb5_free_principal(krb5context, krb5creds.client); - if (krb5creds.server) - krb5_free_principal(krb5context, krb5creds.server); - if (krb5auth_context) - krb5_auth_con_free(krb5context, krb5auth_context); - if (krb5context) - krb5_free_context(krb5context); - return (krb5rc); -} - -/*- - * Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. - * Return Kerberos error code and kssl_err struct on error. - * Allocates krb5_ticket and krb5_principal; caller should free these. - * - * 20010410 VRS Implemented krb5_decode_ticket() as - * old_krb5_decode_ticket(). Missing from MIT1.0.6. - * 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. - * Re-used some of the old krb5_decode_ticket() - * code here. This tkt should alloc/free just - * like the real thing. - */ -static krb5_error_code kssl_TKT2tkt( /* IN */ krb5_context krb5context, - /* - * IN - */ KRB5_TKTBODY *asn1ticket, - /* - * OUT - */ krb5_ticket **krb5ticket, - /* - * OUT - */ KSSL_ERR *kssl_err) -{ - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - krb5_ticket *new5ticket = NULL; - ASN1_GENERALSTRING *gstr_svc, *gstr_host; - - *krb5ticket = NULL; - - if (asn1ticket == NULL || asn1ticket->realm == NULL || - asn1ticket->sname == NULL || - sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Null field in asn1ticket.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - return KRB5KRB_ERR_GENERIC; - } - - if ((new5ticket = (krb5_ticket *)calloc(1, sizeof(krb5_ticket))) == NULL) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Unable to allocate new krb5_ticket.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - return ENOMEM; /* or KRB5KRB_ERR_GENERIC; */ - } - - gstr_svc = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0); - gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1); - - if ((krb5rc = kssl_build_principal_2(krb5context, - &new5ticket->server, - asn1ticket->realm->length, - (char *)asn1ticket->realm->data, - gstr_svc->length, - (char *)gstr_svc->data, - gstr_host->length, - (char *)gstr_host->data)) != 0) { - free(new5ticket); - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Error building ticket server principal.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - return krb5rc; /* or KRB5KRB_ERR_GENERIC; */ - } - - krb5_princ_type(krb5context, new5ticket->server) = - asn1ticket->sname->nametype->data[0]; - new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0]; - new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0]; - new5ticket->enc_part.ciphertext.length = - asn1ticket->encdata->cipher->length; - if ((new5ticket->enc_part.ciphertext.data = - calloc(1, asn1ticket->encdata->cipher->length)) == NULL) { - free(new5ticket); - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Error allocating cipher in krb5ticket.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - return KRB5KRB_ERR_GENERIC; - } else { - memcpy(new5ticket->enc_part.ciphertext.data, - asn1ticket->encdata->cipher->data, - asn1ticket->encdata->cipher->length); - } - - *krb5ticket = new5ticket; - return 0; -} - -/*- - * Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), - * and krb5 AP_REQ message & message length, - * Return Kerberos session key and client principle - * to SSL Server in KSSL_CTX *kssl_ctx. - * - * 19990702 VRS Started. - */ -krb5_error_code kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, - /* - * IN - */ krb5_data *indata, - /* - * OUT - */ krb5_ticket_times *ttimes, - /* - * OUT - */ KSSL_ERR *kssl_err) -{ - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - static krb5_context krb5context = NULL; - static krb5_auth_context krb5auth_context = NULL; - krb5_ticket *krb5ticket = NULL; - KRB5_TKTBODY *asn1ticket = NULL; - const unsigned char *p; - krb5_keytab krb5keytab = NULL; - krb5_keytab_entry kt_entry; - krb5_principal krb5server; - krb5_rcache rcache = NULL; - - kssl_err_set(kssl_err, 0, ""); - - if (!kssl_ctx) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n"); - goto err; - } -# ifdef KSSL_DEBUG - fprintf(stderr, "in kssl_sget_tkt(%s)\n", - kstring(kssl_ctx->service_name)); -# endif /* KSSL_DEBUG */ - - if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_init_context() fails.\n"); - goto err; - } - if (krb5auth_context && - (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_auth_con_free() fails.\n"); - goto err; - } else - krb5auth_context = NULL; - if (!krb5auth_context && - (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_auth_con_init() fails.\n"); - goto err; - } - - if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context, - &rcache))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_auth_con_getrcache() fails.\n"); - goto err; - } - - if ((krb5rc = krb5_sname_to_principal(krb5context, NULL, - (kssl_ctx->service_name) ? - kssl_ctx->service_name : KRB5SVC, - KRB5_NT_SRV_HST, - &krb5server)) != 0) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_sname_to_principal() fails.\n"); - goto err; - } - - if (rcache == NULL) { - if ((krb5rc = krb5_get_server_rcache(krb5context, - krb5_princ_component(krb5context, - krb5server, - 0), - &rcache))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_get_server_rcache() fails.\n"); - goto err; - } - } - - if ((krb5rc = - krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache))) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_auth_con_setrcache() fails.\n"); - goto err; - } - - /* - * kssl_ctx->keytab_file == NULL ==> use Kerberos default - */ - if (kssl_ctx->keytab_file) { - krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, - &krb5keytab); - if (krb5rc) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_kt_resolve() fails.\n"); - goto err; - } - } else { - krb5rc = krb5_kt_default(krb5context, &krb5keytab); - if (krb5rc) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "krb5_kt_default() fails.\n"); - goto err; - } - } - - /*- Actual Kerberos5 krb5_recvauth() has initial conversation here - * o check KRB5_SENDAUTH_BADAUTHVERS - * unless KRB5_RECVAUTH_SKIP_VERSION - * o check KRB5_SENDAUTH_BADAPPLVERS - * o send "0" msg if all OK - */ - - /*- - * 20010411 was using AP_REQ instead of true KerberosWrapper - * - * if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, - * &krb5in_data, krb5server, krb5keytab, - * &ap_option, &krb5ticket)) != 0) { Error } - */ - - p = (unsigned char *)indata->data; - if ((asn1ticket = (KRB5_TKTBODY *)d2i_KRB5_TICKET(NULL, &p, - (long)indata->length)) - == NULL) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "d2i_KRB5_TICKET() ASN.1 decode failure.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } - - /* - * Was: krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) - */ - if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket, - kssl_err)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "Error converting ASN.1 ticket to krb5_ticket.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } - - if (!krb5_principal_compare(krb5context, krb5server, krb5ticket->server)) { - krb5rc = KRB5_PRINC_NOMATCH; - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "server principal != ticket principal\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } - if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, - krb5ticket->server, - krb5ticket->enc_part.kvno, - krb5ticket->enc_part.enctype, - &kt_entry)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "krb5_kt_get_entry() fails with %x.\n", krb5rc); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } - if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key, - krb5ticket)) != 0) { - BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, - "krb5_decrypt_tkt_part() failed.\n"); - kssl_err->reason = SSL_R_KRB5_S_RD_REQ; - goto err; - } else { - krb5_kt_free_entry(krb5context, &kt_entry); -# ifdef KSSL_DEBUG - { - int i; - krb5_address **paddr = krb5ticket->enc_part2->caddrs; - fprintf(stderr, "Decrypted ticket fields:\n"); - fprintf(stderr, "\tflags: %X, transit-type: %X", - krb5ticket->enc_part2->flags, - krb5ticket->enc_part2->transited.tr_type); - print_krb5_data("\ttransit-data: ", - &(krb5ticket->enc_part2->transited.tr_contents)); - fprintf(stderr, "\tcaddrs: %p, authdata: %p\n", - krb5ticket->enc_part2->caddrs, - krb5ticket->enc_part2->authorization_data); - if (paddr) { - fprintf(stderr, "\tcaddrs:\n"); - for (i = 0; paddr[i] != NULL; i++) { - krb5_data d; - d.length = paddr[i]->length; - d.data = paddr[i]->contents; - print_krb5_data("\t\tIP: ", &d); - } - } - fprintf(stderr, "\tstart/auth/end times: %d / %d / %d\n", - krb5ticket->enc_part2->times.starttime, - krb5ticket->enc_part2->times.authtime, - krb5ticket->enc_part2->times.endtime); - } -# endif /* KSSL_DEBUG */ - } - - krb5rc = KRB5_NO_TKT_SUPPLIED; - if (!krb5ticket || !krb5ticket->enc_part2 || - !krb5ticket->enc_part2->client || - !krb5ticket->enc_part2->client->data || - !krb5ticket->enc_part2->session) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, - "bad ticket from krb5_rd_req.\n"); - } else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT, - &krb5ticket->enc_part2->client->realm, - krb5ticket->enc_part2->client->data, - krb5ticket->enc_part2->client->length)) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, - "kssl_ctx_setprinc() fails.\n"); - } else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session)) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, - "kssl_ctx_setkey() fails.\n"); - } else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID) { - krb5rc = KRB5KRB_AP_ERR_TKT_INVALID; - kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, - "invalid ticket from krb5_rd_req.\n"); - } else - krb5rc = 0; - - kssl_ctx->enctype = krb5ticket->enc_part.enctype; - ttimes->authtime = krb5ticket->enc_part2->times.authtime; - ttimes->starttime = krb5ticket->enc_part2->times.starttime; - ttimes->endtime = krb5ticket->enc_part2->times.endtime; - ttimes->renew_till = krb5ticket->enc_part2->times.renew_till; - - err: -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - if (asn1ticket) - KRB5_TICKET_free((KRB5_TICKET *) asn1ticket); - if (krb5keytab) - krb5_kt_close(krb5context, krb5keytab); - if (krb5ticket) - krb5_free_ticket(krb5context, krb5ticket); - if (krb5server) - krb5_free_principal(krb5context, krb5server); - return (krb5rc); -} - -/* - * Allocate & return a new kssl_ctx struct. - */ -KSSL_CTX *kssl_ctx_new(void) -{ - return ((KSSL_CTX *)kssl_calloc(1, sizeof(KSSL_CTX))); -} - -/* - * Frees a kssl_ctx struct and any allocated memory it holds. Returns NULL. - */ -KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx) -{ - if (kssl_ctx == NULL) - return kssl_ctx; - - if (kssl_ctx->key) - OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); - if (kssl_ctx->key) - kssl_free(kssl_ctx->key); - if (kssl_ctx->client_princ) - kssl_free(kssl_ctx->client_princ); - if (kssl_ctx->service_host) - kssl_free(kssl_ctx->service_host); - if (kssl_ctx->service_name) - kssl_free(kssl_ctx->service_name); - if (kssl_ctx->keytab_file) - kssl_free(kssl_ctx->keytab_file); - - kssl_free(kssl_ctx); - return (KSSL_CTX *)NULL; -} - -/* - * Given an array of (krb5_data *) entity (and optional realm), set the plain - * (char *) client_princ or service_host member of the kssl_ctx struct. - */ -krb5_error_code -kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, - krb5_data *realm, krb5_data *entity, int nentities) -{ - char **princ; - int length; - int i; - - if (kssl_ctx == NULL || entity == NULL) - return KSSL_CTX_ERR; - - switch (which) { - case KSSL_CLIENT: - princ = &kssl_ctx->client_princ; - break; - case KSSL_SERVER: - princ = &kssl_ctx->service_host; - break; - default: - return KSSL_CTX_ERR; - break; - } - if (*princ) - kssl_free(*princ); - - /* Add up all the entity->lengths */ - length = 0; - for (i = 0; i < nentities; i++) { - length += entity[i].length; - } - /* Add in space for the '/' character(s) (if any) */ - length += nentities - 1; - /* Space for the ('@'+realm+NULL | NULL) */ - length += ((realm) ? realm->length + 2 : 1); - - if ((*princ = kssl_calloc(1, length)) == NULL) - return KSSL_CTX_ERR; - else { - for (i = 0; i < nentities; i++) { - strncat(*princ, entity[i].data, entity[i].length); - if (i < nentities - 1) { - strcat(*princ, "/"); - } - } - if (realm) { - strcat(*princ, "@"); - (void)strncat(*princ, realm->data, realm->length); - } - } - - return KSSL_CTX_OK; -} - -/*- Set one of the plain (char *) string members of the kssl_ctx struct. - * Default values should be: - * which == KSSL_SERVICE => "khost" (KRB5SVC) - * which == KSSL_KEYTAB => "/etc/krb5.keytab" (KRB5KEYTAB) - */ -krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) -{ - char **string; - - if (!kssl_ctx) - return KSSL_CTX_ERR; - - switch (which) { - case KSSL_SERVICE: - string = &kssl_ctx->service_name; - break; - case KSSL_SERVER: - string = &kssl_ctx->service_host; - break; - case KSSL_CLIENT: - string = &kssl_ctx->client_princ; - break; - case KSSL_KEYTAB: - string = &kssl_ctx->keytab_file; - break; - default: - return KSSL_CTX_ERR; - break; - } - if (*string) - kssl_free(*string); - - if (!text) { - *string = '\0'; - return KSSL_CTX_OK; - } - - if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL) - return KSSL_CTX_ERR; - else - strcpy(*string, text); - - return KSSL_CTX_OK; -} - -/* - * Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx - * struct. Clear kssl_ctx->key if Kerberos session key is NULL. - */ -krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) -{ - int length; - krb5_enctype enctype; - krb5_octet FAR *contents = NULL; - - if (!kssl_ctx) - return KSSL_CTX_ERR; - - if (kssl_ctx->key) { - OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); - kssl_free(kssl_ctx->key); - } - - if (session) { - -# ifdef KRB5_HEIMDAL - length = session->keyvalue->length; - enctype = session->keytype; - contents = session->keyvalue->contents; -# else - length = session->length; - enctype = session->enctype; - contents = session->contents; -# endif - kssl_ctx->enctype = enctype; - kssl_ctx->length = length; - } else { - kssl_ctx->enctype = ENCTYPE_UNKNOWN; - kssl_ctx->length = 0; - return KSSL_CTX_OK; - } - - if ((kssl_ctx->key = - (krb5_octet FAR *)kssl_calloc(1, kssl_ctx->length)) == NULL) { - kssl_ctx->length = 0; - return KSSL_CTX_ERR; - } else - memcpy(kssl_ctx->key, contents, length); - - return KSSL_CTX_OK; -} - -/* - * Display contents of kssl_ctx struct - */ -void kssl_ctx_show(KSSL_CTX *kssl_ctx) -{ - int i; - - printf("kssl_ctx: "); - if (kssl_ctx == NULL) { - printf("NULL\n"); - return; - } else - printf("%p\n", (void *)kssl_ctx); - - printf("\tservice:\t%s\n", - (kssl_ctx->service_name) ? kssl_ctx->service_name : "NULL"); - printf("\tclient:\t%s\n", - (kssl_ctx->client_princ) ? kssl_ctx->client_princ : "NULL"); - printf("\tserver:\t%s\n", - (kssl_ctx->service_host) ? kssl_ctx->service_host : "NULL"); - printf("\tkeytab:\t%s\n", - (kssl_ctx->keytab_file) ? kssl_ctx->keytab_file : "NULL"); - printf("\tkey [%d:%d]:\t", kssl_ctx->enctype, kssl_ctx->length); - - for (i = 0; i < kssl_ctx->length && kssl_ctx->key; i++) { - printf("%02x", kssl_ctx->key[i]); - } - printf("\n"); - return; -} - -int kssl_keytab_is_available(KSSL_CTX *kssl_ctx) -{ - krb5_context krb5context = NULL; - krb5_keytab krb5keytab = NULL; - krb5_keytab_entry entry; - krb5_principal princ = NULL; - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - int rc = 0; - - if ((krb5rc = krb5_init_context(&krb5context))) - return (0); - - /* - * kssl_ctx->keytab_file == NULL ==> use Kerberos default - */ - if (kssl_ctx->keytab_file) { - krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, - &krb5keytab); - if (krb5rc) - goto exit; - } else { - krb5rc = krb5_kt_default(krb5context, &krb5keytab); - if (krb5rc) - goto exit; - } - - /* the host key we are looking for */ - krb5rc = krb5_sname_to_principal(krb5context, NULL, - kssl_ctx-> - service_name ? kssl_ctx->service_name : - KRB5SVC, KRB5_NT_SRV_HST, &princ); - - if (krb5rc) - goto exit; - - krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ, - /* IGNORE_VNO */ - 0, - /* IGNORE_ENCTYPE */ - 0, &entry); - if (krb5rc == KRB5_KT_NOTFOUND) { - rc = 1; - goto exit; - } else if (krb5rc) - goto exit; - - krb5_kt_free_entry(krb5context, &entry); - rc = 1; - - exit: - if (krb5keytab) - krb5_kt_close(krb5context, krb5keytab); - if (princ) - krb5_free_principal(krb5context, princ); - if (krb5context) - krb5_free_context(krb5context); - return (rc); -} - -int kssl_tgt_is_available(KSSL_CTX *kssl_ctx) -{ - krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; - krb5_context krb5context = NULL; - krb5_ccache krb5ccdef = NULL; - krb5_creds krb5creds, *krb5credsp = NULL; - int rc = 0; - - memset((char *)&krb5creds, 0, sizeof(krb5creds)); - - if (!kssl_ctx) - return (0); - - if (!kssl_ctx->service_host) - return (0); - - if ((krb5rc = krb5_init_context(&krb5context)) != 0) - goto err; - - if ((krb5rc = krb5_sname_to_principal(krb5context, - kssl_ctx->service_host, - (kssl_ctx->service_name) ? - kssl_ctx->service_name : KRB5SVC, - KRB5_NT_SRV_HST, - &krb5creds.server)) != 0) - goto err; - - if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) - goto err; - - if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, - &krb5creds.client)) != 0) - goto err; - - if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, - &krb5creds, &krb5credsp)) != 0) - goto err; - - rc = 1; - - err: -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - if (krb5creds.client) - krb5_free_principal(krb5context, krb5creds.client); - if (krb5creds.server) - krb5_free_principal(krb5context, krb5creds.server); - if (krb5context) - krb5_free_context(krb5context); - return (rc); -} - -# if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32) -void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) -{ -# ifdef KRB5_HEIMDAL - data->length = 0; - if (data->data) - free(data->data); -# elif defined(KRB5_MIT_OLD11) - if (data->data) { - krb5_xfree(data->data); - data->data = 0; - } -# else - krb5_free_data_contents(NULL, data); -# endif -} -# endif -/* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */ - -/* - * Given pointers to KerberosTime and struct tm structs, convert the - * KerberosTime string to struct tm. Note that KerberosTime is a - * ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional seconds - * as defined in RFC 1510. Return pointer to the (partially) filled in - * struct tm on success, return NULL on failure. - */ -static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) -{ - char c, *p; - - if (!k_tm) - return NULL; - if (gtime == NULL || gtime->length < 14) - return NULL; - if (gtime->data == NULL) - return NULL; - - p = (char *)>ime->data[14]; - - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_sec = atoi(p); - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_min = atoi(p); - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_hour = atoi(p); - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_mday = atoi(p); - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 2; - k_tm->tm_mon = atoi(p) - 1; - *(p + 2) = c; - c = *p; - *p = '\0'; - p -= 4; - k_tm->tm_year = atoi(p) - 1900; - *(p + 4) = c; - - return k_tm; -} - -/* - * Helper function for kssl_validate_times(). We need context->clockskew, - * but krb5_context is an opaque struct. So we try to sneek the clockskew - * out through the replay cache. If that fails just return a likely default - * (300 seconds). - */ -static krb5_deltat get_rc_clockskew(krb5_context context) -{ - krb5_rcache rc; - krb5_deltat clockskew; - - if (krb5_rc_default(context, &rc)) - return KSSL_CLOCKSKEW; - if (krb5_rc_initialize(context, rc, 0)) - return KSSL_CLOCKSKEW; - if (krb5_rc_get_lifespan(context, rc, &clockskew)) { - clockskew = KSSL_CLOCKSKEW; - } - (void)krb5_rc_destroy(context, rc); - return clockskew; -} - -/* - * kssl_validate_times() combines (and more importantly exposes) the MIT KRB5 - * internal function krb5_validate_times() and the in_clock_skew() macro. - * The authenticator client time is checked to be within clockskew secs of - * the current time and the current time is checked to be within the ticket - * start and expire times. Either check may be omitted by supplying a NULL - * value. Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. See - * Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c 20010420 VRS - */ -krb5_error_code kssl_validate_times(krb5_timestamp atime, - krb5_ticket_times *ttimes) -{ - krb5_deltat skew; - krb5_timestamp start, now; - krb5_error_code rc; - krb5_context context; - - if ((rc = krb5_init_context(&context))) - return SSL_R_KRB5_S_BAD_TICKET; - skew = get_rc_clockskew(context); - if ((rc = krb5_timeofday(context, &now))) - return SSL_R_KRB5_S_BAD_TICKET; - krb5_free_context(context); - - if (atime && labs(atime - now) >= skew) - return SSL_R_KRB5_S_TKT_SKEW; - - if (!ttimes) - return 0; - - start = (ttimes->starttime != 0) ? ttimes->starttime : ttimes->authtime; - if (start - now > skew) - return SSL_R_KRB5_S_TKT_NYV; - if ((now - ttimes->endtime) > skew) - return SSL_R_KRB5_S_TKT_EXPIRED; - -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", - start, atime, now, skew, ttimes->endtime); -# endif /* KSSL_DEBUG */ - - return 0; -} - -/* - * Decode and decrypt given DER-encoded authenticator, then pass - * authenticator ctime back in *atimep (or 0 if time unavailable). Returns - * krb5_error_code and kssl_err on error. A NULL authenticator - * (authentp->length == 0) is not considered an error. Note that - * kssl_check_authent() makes use of the KRB5 session key; you must call - * kssl_sget_tkt() to get the key before calling this routine. - */ -krb5_error_code kssl_check_authent( - /* - * IN - */ KSSL_CTX *kssl_ctx, - /* - * IN - */ krb5_data *authentp, - /* - * OUT - */ krb5_timestamp *atimep, - /* - * OUT - */ KSSL_ERR *kssl_err) -{ - krb5_error_code krb5rc = 0; - KRB5_ENCDATA *dec_authent = NULL; - KRB5_AUTHENTBODY *auth = NULL; - krb5_enctype enctype; - EVP_CIPHER_CTX ciph_ctx; - const EVP_CIPHER *enc = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH]; - const unsigned char *p; - unsigned char *unenc_authent; - int outl, unencbufsize; - struct tm tm_time, *tm_l, *tm_g; - time_t now, tl, tg, tr, tz_offset; - struct tm gmt_result = {0}; - struct tm lt_result = {0}; - - EVP_CIPHER_CTX_init(&ciph_ctx); - *atimep = 0; - kssl_err_set(kssl_err, 0, ""); - -# ifndef KRB5CHECKAUTH - authentp = NULL; -# else -# if KRB5CHECKAUTH == 0 - authentp = NULL; -# endif -# endif /* KRB5CHECKAUTH */ - - if (authentp == NULL || authentp->length == 0) - return 0; - -# ifdef KSSL_DEBUG - { - unsigned int ui; - fprintf(stderr, "kssl_check_authent: authenticator[%d]:\n", - authentp->length); - p = authentp->data; - for (ui = 0; ui < authentp->length; ui++) - fprintf(stderr, "%02x ", p[ui]); - fprintf(stderr, "\n"); - } -# endif /* KSSL_DEBUG */ - - unencbufsize = 2 * authentp->length; - if ((unenc_authent = calloc(1, unencbufsize)) == NULL) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "Unable to allocate authenticator buffer.\n"); - krb5rc = KRB5KRB_ERR_GENERIC; - goto err; - } - - p = (unsigned char *)authentp->data; - if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p, - (long)authentp->length)) == NULL) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "Error decoding authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - - enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */ -# if !defined(KRB5_MIT_OLD11) - switch (enctype) { - case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ - case ENCTYPE_DES3_CBC_SHA: - case ENCTYPE_DES3_CBC_RAW: - krb5rc = 0; /* Skip, can't handle derived keys */ - goto err; - } -# endif - enc = kssl_map_enc(enctype); - memset(iv, 0, sizeof(iv)); /* per RFC 1510 */ - - if (enc == NULL) { - /* - * Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. This - * enctype indicates the authenticator was encrypted using key-usage - * derived keys which openssl cannot decrypt. - */ - goto err; - } - - if (!EVP_CipherInit(&ciph_ctx, enc, kssl_ctx->key, iv, 0)) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "EVP_CipherInit error decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - outl = dec_authent->cipher->length; - if (!EVP_Cipher - (&ciph_ctx, unenc_authent, dec_authent->cipher->data, outl)) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "EVP_Cipher error decrypting authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - -# ifdef KSSL_DEBUG - { - int padl; - fprintf(stderr, "kssl_check_authent: decrypted authenticator[%d] =\n", - outl); - for (padl = 0; padl < outl; padl++) - fprintf(stderr, "%02x ", unenc_authent[padl]); - fprintf(stderr, "\n"); - } -# endif /* KSSL_DEBUG */ - - if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "confounded by authenticator.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - outl -= p - unenc_authent; - - if ((auth = (KRB5_AUTHENTBODY *)d2i_KRB5_AUTHENT(NULL, &p, - (long)outl)) == NULL) { - kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, - "Error decoding authenticator body.\n"); - krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; - goto err; - } - - memset(&tm_time, 0, sizeof(struct tm)); - if (k_gmtime(auth->ctime, &tm_time) && - ((tr = mktime(&tm_time)) != (time_t)(-1))) { - now = time(&now); - tm_g = OPENSSL_gmtime(&now, &gmt_result); - -# if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && \ - !defined(OPENSSL_SYS_OS2) && !defined(OPENSSL_SYS_SUNOS) && \ - (!defined(OPENSSL_SYS_VMS) || defined(localtime_r)) - tm_l = localtime_r(&now, <_result); -# else - tm_l = localtime(&now); -# endif - - tl = mktime(tm_l); - tg = mktime(tm_g); - tz_offset = tg - tl; - - *atimep = (krb5_timestamp)(tr - tz_offset); - } -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_check_authent: returns %d for client time ", - *atimep); - if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) - fprintf(stderr, "%.*s\n", auth->ctime->length, auth->ctime->data); - else - fprintf(stderr, "NULL\n"); -# endif /* KSSL_DEBUG */ - - err: - if (auth) - KRB5_AUTHENT_free((KRB5_AUTHENT *) auth); - if (dec_authent) - KRB5_ENCDATA_free(dec_authent); - if (unenc_authent) - free(unenc_authent); - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - return krb5rc; -} - -/* - * Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host), - * because I don't know how to stub varargs. Returns krb5_error_code == - * ENOMEM on alloc error, otherwise passes back newly constructed principal, - * which should be freed by caller. - */ -krb5_error_code kssl_build_principal_2( - /* - * UPDATE - */ krb5_context context, - /* - * OUT - */ krb5_principal *princ, - /* - * IN - */ int rlen, const char *realm, - /* - * IN - */ int slen, const char *svc, - /* - * IN - */ int hlen, const char *host) -{ - krb5_data *p_data = NULL; - krb5_principal new_p = NULL; - char *new_r = NULL; - - if ((p_data = (krb5_data *)calloc(2, sizeof(krb5_data))) == NULL || - (new_p = (krb5_principal)calloc(1, sizeof(krb5_principal_data))) - == NULL) - goto err; - new_p->length = 2; - new_p->data = p_data; - - if ((new_r = calloc(1, rlen + 1)) == NULL) - goto err; - memcpy(new_r, realm, rlen); - krb5_princ_set_realm_length(context, new_p, rlen); - krb5_princ_set_realm_data(context, new_p, new_r); - - if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL) - goto err; - memcpy(new_p->data[0].data, svc, slen); - new_p->data[0].length = slen; - - if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL) - goto err; - memcpy(new_p->data[1].data, host, hlen); - new_p->data[1].length = hlen; - - krb5_princ_type(context, new_p) = KRB5_NT_UNKNOWN; - *princ = new_p; - return 0; - - err: - if (new_p && new_p[0].data) - free(new_p[0].data); - if (new_p && new_p[1].data) - free(new_p[1].data); - if (new_p) - free(new_p); - if (new_r) - free(new_r); - return ENOMEM; -} - -void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx) -{ - s->kssl_ctx = kctx; -} - -KSSL_CTX *SSL_get0_kssl_ctx(SSL *s) -{ - return s->kssl_ctx; -} - -char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx) -{ - if (kctx) - return kctx->client_princ; - return NULL; -} - -#else /* !OPENSSL_NO_KRB5 */ - -# if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS) -static void *dummy = &dummy; -# endif - -#endif /* !OPENSSL_NO_KRB5 */ diff --git a/Sources/COpenSSL/kssl.h b/Sources/COpenSSL/kssl.h deleted file mode 100644 index 048fc592..00000000 --- a/Sources/COpenSSL/kssl.h +++ /dev/null @@ -1,197 +0,0 @@ -/* ssl/kssl.h */ -/* - * Written by Vern Staats for the OpenSSL project - * 2000. project 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - ** 19990701 VRS Started. - */ - -#ifndef KSSL_H -# define KSSL_H - -# include "opensslconf.h" - -# ifndef OPENSSL_NO_KRB5 - -# include -# include -# include -# ifdef OPENSSL_SYS_WIN32 -/* - * These can sometimes get redefined indirectly by krb5 header files after - * they get undefed in ossl_typ.h - */ -# undef X509_NAME -# undef X509_EXTENSIONS -# undef OCSP_REQUEST -# undef OCSP_RESPONSE -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Depending on which KRB5 implementation used, some types from - * the other may be missing. Resolve that here and now - */ -# ifdef KRB5_HEIMDAL -typedef unsigned char krb5_octet; -# define FAR -# else - -# ifndef FAR -# define FAR -# endif - -# endif - -/*- - * Uncomment this to debug kssl problems or - * to trace usage of the Kerberos session key - * - * #define KSSL_DEBUG - */ - -# ifndef KRB5SVC -# define KRB5SVC "host" -# endif - -# ifndef KRB5KEYTAB -# define KRB5KEYTAB "/etc/krb5.keytab" -# endif - -# ifndef KRB5SENDAUTH -# define KRB5SENDAUTH 1 -# endif - -# ifndef KRB5CHECKAUTH -# define KRB5CHECKAUTH 1 -# endif - -# ifndef KSSL_CLOCKSKEW -# define KSSL_CLOCKSKEW 300; -# endif - -# define KSSL_ERR_MAX 255 -typedef struct kssl_err_st { - int reason; - char text[KSSL_ERR_MAX + 1]; -} KSSL_ERR; - -/*- Context for passing - * (1) Kerberos session key to SSL, and - * (2) Config data between application and SSL lib - */ -typedef struct kssl_ctx_st { - /* used by: disposition: */ - char *service_name; /* C,S default ok (kssl) */ - char *service_host; /* C input, REQUIRED */ - char *client_princ; /* S output from krb5 ticket */ - char *keytab_file; /* S NULL (/etc/krb5.keytab) */ - char *cred_cache; /* C NULL (default) */ - krb5_enctype enctype; - int length; - krb5_octet FAR *key; -} KSSL_CTX; - -# define KSSL_CLIENT 1 -# define KSSL_SERVER 2 -# define KSSL_SERVICE 3 -# define KSSL_KEYTAB 4 - -# define KSSL_CTX_OK 0 -# define KSSL_CTX_ERR 1 -# define KSSL_NOMEM 2 - -/* Public (for use by applications that use OpenSSL with Kerberos 5 support */ -krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text); -KSSL_CTX *kssl_ctx_new(void); -KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx); -void kssl_ctx_show(KSSL_CTX *kssl_ctx); -krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, - krb5_data *realm, krb5_data *entity, - int nentities); -krb5_error_code kssl_cget_tkt(KSSL_CTX *kssl_ctx, krb5_data **enc_tktp, - krb5_data *authenp, KSSL_ERR *kssl_err); -krb5_error_code kssl_sget_tkt(KSSL_CTX *kssl_ctx, krb5_data *indata, - krb5_ticket_times *ttimes, KSSL_ERR *kssl_err); -krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session); -void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text); -void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data); -krb5_error_code kssl_build_principal_2(krb5_context context, - krb5_principal *princ, int rlen, - const char *realm, int slen, - const char *svc, int hlen, - const char *host); -krb5_error_code kssl_validate_times(krb5_timestamp atime, - krb5_ticket_times *ttimes); -krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp, - krb5_timestamp *atimep, - KSSL_ERR *kssl_err); -unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn); - -void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx); -KSSL_CTX *SSL_get0_kssl_ctx(SSL *s); -char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx); - -#ifdef __cplusplus -} -#endif -# endif /* OPENSSL_NO_KRB5 */ -#endif /* KSSL_H */ diff --git a/Sources/COpenSSL/kssl_lcl.h b/Sources/COpenSSL/kssl_lcl.h deleted file mode 100644 index 52f49fa5..00000000 --- a/Sources/COpenSSL/kssl_lcl.h +++ /dev/null @@ -1,88 +0,0 @@ -/* ssl/kssl.h */ -/* - * Written by Vern Staats for the OpenSSL project - * 2000. project 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef KSSL_LCL_H -# define KSSL_LCL_H - -# include "kssl.h" - -# ifndef OPENSSL_NO_KRB5 - -#ifdef __cplusplus -extern "C" { -#endif - -/* Private (internal to OpenSSL) */ -void print_krb5_data(char *label, krb5_data *kdata); -void print_krb5_authdata(char *label, krb5_authdata **adata); -void print_krb5_keyblock(char *label, krb5_keyblock *keyblk); - -char *kstring(char *string); -char *knumber(int len, krb5_octet *contents); - -const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype); - -int kssl_keytab_is_available(KSSL_CTX *kssl_ctx); -int kssl_tgt_is_available(KSSL_CTX *kssl_ctx); - -#ifdef __cplusplus -} -#endif -# endif /* OPENSSL_NO_KRB5 */ -#endif /* KSSL_LCL_H */ diff --git a/Sources/COpenSSL/lh_stats.c b/Sources/COpenSSL/lh_stats.c deleted file mode 100644 index e70153a0..00000000 --- a/Sources/COpenSSL/lh_stats.c +++ /dev/null @@ -1,246 +0,0 @@ -/* crypto/lhash/lh_stats.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -/* - * If you wish to build this outside of SSLeay, remove the following lines - * and things should work as expected - */ -#include "cryptlib.h" - -#ifndef OPENSSL_NO_BIO -# include "bio.h" -#endif -#include "lhash.h" - -#ifdef OPENSSL_NO_BIO - -void lh_stats(LHASH *lh, FILE *out) -{ - fprintf(out, "num_items = %lu\n", lh->num_items); - fprintf(out, "num_nodes = %u\n", lh->num_nodes); - fprintf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); - fprintf(out, "num_expands = %lu\n", lh->num_expands); - fprintf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs); - fprintf(out, "num_contracts = %lu\n", lh->num_contracts); - fprintf(out, "num_contract_reallocs = %lu\n", lh->num_contract_reallocs); - fprintf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); - fprintf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); - fprintf(out, "num_insert = %lu\n", lh->num_insert); - fprintf(out, "num_replace = %lu\n", lh->num_replace); - fprintf(out, "num_delete = %lu\n", lh->num_delete); - fprintf(out, "num_no_delete = %lu\n", lh->num_no_delete); - fprintf(out, "num_retrieve = %lu\n", lh->num_retrieve); - fprintf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); - fprintf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); -# if 0 - fprintf(out, "p = %u\n", lh->p); - fprintf(out, "pmax = %u\n", lh->pmax); - fprintf(out, "up_load = %lu\n", lh->up_load); - fprintf(out, "down_load = %lu\n", lh->down_load); -# endif -} - -void lh_node_stats(LHASH *lh, FILE *out) -{ - LHASH_NODE *n; - unsigned int i, num; - - for (i = 0; i < lh->num_nodes; i++) { - for (n = lh->b[i], num = 0; n != NULL; n = n->next) - num++; - fprintf(out, "node %6u -> %3u\n", i, num); - } -} - -void lh_node_usage_stats(LHASH *lh, FILE *out) -{ - LHASH_NODE *n; - unsigned long num; - unsigned int i; - unsigned long total = 0, n_used = 0; - - for (i = 0; i < lh->num_nodes; i++) { - for (n = lh->b[i], num = 0; n != NULL; n = n->next) - num++; - if (num != 0) { - n_used++; - total += num; - } - } - fprintf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes); - fprintf(out, "%lu items\n", total); - if (n_used == 0) - return; - fprintf(out, "load %d.%02d actual load %d.%02d\n", - (int)(total / lh->num_nodes), - (int)((total % lh->num_nodes) * 100 / lh->num_nodes), - (int)(total / n_used), (int)((total % n_used) * 100 / n_used)); -} - -#else - -# ifndef OPENSSL_NO_FP_API -void lh_stats(const _LHASH *lh, FILE *fp) -{ - BIO *bp; - - bp = BIO_new(BIO_s_file()); - if (bp == NULL) - goto end; - BIO_set_fp(bp, fp, BIO_NOCLOSE); - lh_stats_bio(lh, bp); - BIO_free(bp); - end:; -} - -void lh_node_stats(const _LHASH *lh, FILE *fp) -{ - BIO *bp; - - bp = BIO_new(BIO_s_file()); - if (bp == NULL) - goto end; - BIO_set_fp(bp, fp, BIO_NOCLOSE); - lh_node_stats_bio(lh, bp); - BIO_free(bp); - end:; -} - -void lh_node_usage_stats(const _LHASH *lh, FILE *fp) -{ - BIO *bp; - - bp = BIO_new(BIO_s_file()); - if (bp == NULL) - goto end; - BIO_set_fp(bp, fp, BIO_NOCLOSE); - lh_node_usage_stats_bio(lh, bp); - BIO_free(bp); - end:; -} - -# endif - -void lh_stats_bio(const _LHASH *lh, BIO *out) -{ - BIO_printf(out, "num_items = %lu\n", lh->num_items); - BIO_printf(out, "num_nodes = %u\n", lh->num_nodes); - BIO_printf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); - BIO_printf(out, "num_expands = %lu\n", lh->num_expands); - BIO_printf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs); - BIO_printf(out, "num_contracts = %lu\n", lh->num_contracts); - BIO_printf(out, "num_contract_reallocs = %lu\n", - lh->num_contract_reallocs); - BIO_printf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); - BIO_printf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); - BIO_printf(out, "num_insert = %lu\n", lh->num_insert); - BIO_printf(out, "num_replace = %lu\n", lh->num_replace); - BIO_printf(out, "num_delete = %lu\n", lh->num_delete); - BIO_printf(out, "num_no_delete = %lu\n", lh->num_no_delete); - BIO_printf(out, "num_retrieve = %lu\n", lh->num_retrieve); - BIO_printf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); - BIO_printf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); -# if 0 - BIO_printf(out, "p = %u\n", lh->p); - BIO_printf(out, "pmax = %u\n", lh->pmax); - BIO_printf(out, "up_load = %lu\n", lh->up_load); - BIO_printf(out, "down_load = %lu\n", lh->down_load); -# endif -} - -void lh_node_stats_bio(const _LHASH *lh, BIO *out) -{ - LHASH_NODE *n; - unsigned int i, num; - - for (i = 0; i < lh->num_nodes; i++) { - for (n = lh->b[i], num = 0; n != NULL; n = n->next) - num++; - BIO_printf(out, "node %6u -> %3u\n", i, num); - } -} - -void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out) -{ - LHASH_NODE *n; - unsigned long num; - unsigned int i; - unsigned long total = 0, n_used = 0; - - for (i = 0; i < lh->num_nodes; i++) { - for (n = lh->b[i], num = 0; n != NULL; n = n->next) - num++; - if (num != 0) { - n_used++; - total += num; - } - } - BIO_printf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes); - BIO_printf(out, "%lu items\n", total); - if (n_used == 0) - return; - BIO_printf(out, "load %d.%02d actual load %d.%02d\n", - (int)(total / lh->num_nodes), - (int)((total % lh->num_nodes) * 100 / lh->num_nodes), - (int)(total / n_used), (int)((total % n_used) * 100 / n_used)); -} - -#endif diff --git a/Sources/COpenSSL/lhash.c b/Sources/COpenSSL/lhash.c deleted file mode 100644 index cd5d3682..00000000 --- a/Sources/COpenSSL/lhash.c +++ /dev/null @@ -1,477 +0,0 @@ -/* crypto/lhash/lhash.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/*- - * Code for dynamic hash table routines - * Author - Eric Young v 2.0 - * - * 2.2 eay - added #include "crypto.h" so the memory leak checking code is - * present. eay 18-Jun-98 - * - * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98 - * - * 2.0 eay - Fixed a bug that occurred when using lh_delete - * from inside lh_doall(). As entries were deleted, - * the 'table' was 'contract()ed', making some entries - * jump from the end of the table to the start, there by - * skipping the lh_doall() processing. eay - 4/12/95 - * - * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs - * were not being free()ed. 21/11/95 - * - * 1.8 eay - Put the stats routines into a separate file, lh_stats.c - * 19/09/95 - * - * 1.7 eay - Removed the fputs() for realloc failures - the code - * should silently tolerate them. I have also fixed things - * lint complained about 04/05/95 - * - * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92 - * - * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992 - * - * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91 - * - * 1.3 eay - Fixed a few lint problems 19/3/1991 - * - * 1.2 eay - Fixed lh_doall problem 13/3/1991 - * - * 1.1 eay - Added lh_doall - * - * 1.0 eay - First version - */ -#include -#include -#include -#include "crypto.h" -#include "lhash.h" - -/* - * A hashing implementation that appears to be based on the linear hashing - * alogrithm: - * https://en.wikipedia.org/wiki/Linear_hashing - * - * Litwin, Witold (1980), "Linear hashing: A new tool for file and table - * addressing", Proc. 6th Conference on Very Large Databases: 212-223 - * http://hackthology.com/pdfs/Litwin-1980-Linear_Hashing.pdf - * - * From the wikipedia article "Linear hashing is used in the BDB Berkeley - * database system, which in turn is used by many software systems such as - * OpenLDAP, using a C implementation derived from the CACM article and first - * published on the Usenet in 1988 by Esmond Pitt." - * - * The CACM paper is available here: - * https://pdfs.semanticscholar.org/ff4d/1c5deca6269cc316bfd952172284dbf610ee.pdf - */ - -const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; - -#undef MIN_NODES -#define MIN_NODES 16 -#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ -#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ - -static int expand(_LHASH *lh); -static void contract(_LHASH *lh); -static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); - -_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) -{ - _LHASH *ret; - int i; - - if ((ret = OPENSSL_malloc(sizeof(_LHASH))) == NULL) - goto err0; - if ((ret->b = OPENSSL_malloc(sizeof(LHASH_NODE *) * MIN_NODES)) == NULL) - goto err1; - for (i = 0; i < MIN_NODES; i++) - ret->b[i] = NULL; - ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c); - ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h); - ret->num_nodes = MIN_NODES / 2; - ret->num_alloc_nodes = MIN_NODES; - ret->p = 0; - ret->pmax = MIN_NODES / 2; - ret->up_load = UP_LOAD; - ret->down_load = DOWN_LOAD; - ret->num_items = 0; - - ret->num_expands = 0; - ret->num_expand_reallocs = 0; - ret->num_contracts = 0; - ret->num_contract_reallocs = 0; - ret->num_hash_calls = 0; - ret->num_comp_calls = 0; - ret->num_insert = 0; - ret->num_replace = 0; - ret->num_delete = 0; - ret->num_no_delete = 0; - ret->num_retrieve = 0; - ret->num_retrieve_miss = 0; - ret->num_hash_comps = 0; - - ret->error = 0; - return (ret); - err1: - OPENSSL_free(ret); - err0: - return (NULL); -} - -void lh_free(_LHASH *lh) -{ - unsigned int i; - LHASH_NODE *n, *nn; - - if (lh == NULL) - return; - - for (i = 0; i < lh->num_nodes; i++) { - n = lh->b[i]; - while (n != NULL) { - nn = n->next; - OPENSSL_free(n); - n = nn; - } - } - OPENSSL_free(lh->b); - OPENSSL_free(lh); -} - -void *lh_insert(_LHASH *lh, void *data) -{ - unsigned long hash; - LHASH_NODE *nn, **rn; - void *ret; - - lh->error = 0; - if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes) - && !expand(lh)) - return NULL; - - rn = getrn(lh, data, &hash); - - if (*rn == NULL) { - if ((nn = (LHASH_NODE *)OPENSSL_malloc(sizeof(LHASH_NODE))) == NULL) { - lh->error++; - return (NULL); - } - nn->data = data; - nn->next = NULL; -#ifndef OPENSSL_NO_HASH_COMP - nn->hash = hash; -#endif - *rn = nn; - ret = NULL; - lh->num_insert++; - lh->num_items++; - } else { /* replace same key */ - - ret = (*rn)->data; - (*rn)->data = data; - lh->num_replace++; - } - return (ret); -} - -void *lh_delete(_LHASH *lh, const void *data) -{ - unsigned long hash; - LHASH_NODE *nn, **rn; - void *ret; - - lh->error = 0; - rn = getrn(lh, data, &hash); - - if (*rn == NULL) { - lh->num_no_delete++; - return (NULL); - } else { - nn = *rn; - *rn = nn->next; - ret = nn->data; - OPENSSL_free(nn); - lh->num_delete++; - } - - lh->num_items--; - if ((lh->num_nodes > MIN_NODES) && - (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))) - contract(lh); - - return (ret); -} - -void *lh_retrieve(_LHASH *lh, const void *data) -{ - unsigned long hash; - LHASH_NODE **rn; - void *ret; - - lh->error = 0; - rn = getrn(lh, data, &hash); - - if (*rn == NULL) { - lh->num_retrieve_miss++; - return (NULL); - } else { - ret = (*rn)->data; - lh->num_retrieve++; - } - return (ret); -} - -static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, - LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) -{ - int i; - LHASH_NODE *a, *n; - - if (lh == NULL) - return; - - /* - * reverse the order so we search from 'top to bottom' We were having - * memory leaks otherwise - */ - for (i = lh->num_nodes - 1; i >= 0; i--) { - a = lh->b[i]; - while (a != NULL) { - /* - * 28/05/91 - eay - n added so items can be deleted via lh_doall - */ - /* - * 22/05/08 - ben - eh? since a is not passed, this should not be - * needed - */ - n = a->next; - if (use_arg) - func_arg(a->data, arg); - else - func(a->data); - a = n; - } - } -} - -void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) -{ - doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); -} - -void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) -{ - doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); -} - -static int expand(_LHASH *lh) -{ - LHASH_NODE **n, **n1, **n2, *np; - unsigned int p, pmax, nni, j; - unsigned long hash; - - nni = lh->num_alloc_nodes; - p = lh->p; - pmax = lh->pmax; - if (p + 1 >= pmax) { - j = nni * 2; - n = OPENSSL_realloc(lh->b, (int)(sizeof(LHASH_NODE *) * j)); - if (n == NULL) { - lh->error++; - return 0; - } - lh->b = n; - memset(n + nni, 0, sizeof(*n) * (j - nni)); - lh->pmax = nni; - lh->num_alloc_nodes = j; - lh->num_expand_reallocs++; - lh->p = 0; - } else { - lh->p++; - } - - lh->num_nodes++; - lh->num_expands++; - n1 = &(lh->b[p]); - n2 = &(lh->b[p + pmax]); - *n2 = NULL; - - for (np = *n1; np != NULL;) { -#ifndef OPENSSL_NO_HASH_COMP - hash = np->hash; -#else - hash = lh->hash(np->data); - lh->num_hash_calls++; -#endif - if ((hash % nni) != p) { /* move it */ - *n1 = (*n1)->next; - np->next = *n2; - *n2 = np; - } else - n1 = &((*n1)->next); - np = *n1; - } - - return 1; -} - -static void contract(_LHASH *lh) -{ - LHASH_NODE **n, *n1, *np; - - np = lh->b[lh->p + lh->pmax - 1]; - lh->b[lh->p + lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */ - if (lh->p == 0) { - n = (LHASH_NODE **)OPENSSL_realloc(lh->b, - (unsigned int)(sizeof(LHASH_NODE *) - * lh->pmax)); - if (n == NULL) { -/* fputs("realloc error in lhash",stderr); */ - lh->error++; - return; - } - lh->num_contract_reallocs++; - lh->num_alloc_nodes /= 2; - lh->pmax /= 2; - lh->p = lh->pmax - 1; - lh->b = n; - } else - lh->p--; - - lh->num_nodes--; - lh->num_contracts++; - - n1 = lh->b[(int)lh->p]; - if (n1 == NULL) - lh->b[(int)lh->p] = np; - else { - while (n1->next != NULL) - n1 = n1->next; - n1->next = np; - } -} - -static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) -{ - LHASH_NODE **ret, *n1; - unsigned long hash, nn; - LHASH_COMP_FN_TYPE cf; - - hash = (*(lh->hash)) (data); - lh->num_hash_calls++; - *rhash = hash; - - nn = hash % lh->pmax; - if (nn < lh->p) - nn = hash % lh->num_alloc_nodes; - - cf = lh->comp; - ret = &(lh->b[(int)nn]); - for (n1 = *ret; n1 != NULL; n1 = n1->next) { -#ifndef OPENSSL_NO_HASH_COMP - lh->num_hash_comps++; - if (n1->hash != hash) { - ret = &(n1->next); - continue; - } -#endif - lh->num_comp_calls++; - if (cf(n1->data, data) == 0) - break; - ret = &(n1->next); - } - return (ret); -} - -/* - * The following hash seems to work very well on normal text strings no - * collisions on /usr/dict/words and it distributes on %2^n quite well, not - * as good as MD5, but still good. - */ -unsigned long lh_strhash(const char *c) -{ - unsigned long ret = 0; - long n; - unsigned long v; - int r; - - if ((c == NULL) || (*c == '\0')) - return (ret); -/*- - unsigned char b[16]; - MD5(c,strlen(c),b); - return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24)); -*/ - - n = 0x100; - while (*c) { - v = n | (*c); - n += 0x100; - r = (int)((v >> 2) ^ v) & 0x0f; - ret = (ret << r) | (ret >> (32 - r)); - ret &= 0xFFFFFFFFL; - ret ^= v * v; - c++; - } - return ((ret >> 16) ^ ret); -} - -unsigned long lh_num_items(const _LHASH *lh) -{ - return lh ? lh->num_items : 0; -} diff --git a/Sources/COpenSSL/lhash.h b/Sources/COpenSSL/lhash.h deleted file mode 100644 index 14aaa03a..00000000 --- a/Sources/COpenSSL/lhash.h +++ /dev/null @@ -1,240 +0,0 @@ -/* crypto/lhash/lhash.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * Header for dynamic hash table routines Author - Eric Young - */ - -#ifndef HEADER_LHASH_H -# define HEADER_LHASH_H - -# include "e_os2.h" -# ifndef OPENSSL_NO_FP_API -# include -# endif - -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct lhash_node_st { - void *data; - struct lhash_node_st *next; -# ifndef OPENSSL_NO_HASH_COMP - unsigned long hash; -# endif -} LHASH_NODE; - -typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *); -typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *); -typedef void (*LHASH_DOALL_FN_TYPE) (void *); -typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *); - -/* - * Macros for declaring and implementing type-safe wrappers for LHASH - * callbacks. This way, callbacks can be provided to LHASH structures without - * function pointer casting and the macro-defined callbacks provide - * per-variable casting before deferring to the underlying type-specific - * callbacks. NB: It is possible to place a "static" in front of both the - * DECLARE and IMPLEMENT macros if the functions are strictly internal. - */ - -/* First: "hash" functions */ -# define DECLARE_LHASH_HASH_FN(name, o_type) \ - unsigned long name##_LHASH_HASH(const void *); -# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ - unsigned long name##_LHASH_HASH(const void *arg) { \ - const o_type *a = arg; \ - return name##_hash(a); } -# define LHASH_HASH_FN(name) name##_LHASH_HASH - -/* Second: "compare" functions */ -# define DECLARE_LHASH_COMP_FN(name, o_type) \ - int name##_LHASH_COMP(const void *, const void *); -# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ - int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ - const o_type *a = arg1; \ - const o_type *b = arg2; \ - return name##_cmp(a,b); } -# define LHASH_COMP_FN(name) name##_LHASH_COMP - -/* Third: "doall" functions */ -# define DECLARE_LHASH_DOALL_FN(name, o_type) \ - void name##_LHASH_DOALL(void *); -# define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ - void name##_LHASH_DOALL(void *arg) { \ - o_type *a = arg; \ - name##_doall(a); } -# define LHASH_DOALL_FN(name) name##_LHASH_DOALL - -/* Fourth: "doall_arg" functions */ -# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ - void name##_LHASH_DOALL_ARG(void *, void *); -# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ - void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ - o_type *a = arg1; \ - a_type *b = arg2; \ - name##_doall_arg(a, b); } -# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG - -typedef struct lhash_st { - LHASH_NODE **b; - LHASH_COMP_FN_TYPE comp; - LHASH_HASH_FN_TYPE hash; - unsigned int num_nodes; - unsigned int num_alloc_nodes; - unsigned int p; - unsigned int pmax; - unsigned long up_load; /* load times 256 */ - unsigned long down_load; /* load times 256 */ - unsigned long num_items; - unsigned long num_expands; - unsigned long num_expand_reallocs; - unsigned long num_contracts; - unsigned long num_contract_reallocs; - unsigned long num_hash_calls; - unsigned long num_comp_calls; - unsigned long num_insert; - unsigned long num_replace; - unsigned long num_delete; - unsigned long num_no_delete; - unsigned long num_retrieve; - unsigned long num_retrieve_miss; - unsigned long num_hash_comps; - int error; -} _LHASH; /* Do not use _LHASH directly, use LHASH_OF - * and friends */ - -# define LH_LOAD_MULT 256 - -/* - * Indicates a malloc() error in the last call, this is only bad in - * lh_insert(). - */ -# define lh_error(lh) ((lh)->error) - -_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); -void lh_free(_LHASH *lh); -void *lh_insert(_LHASH *lh, void *data); -void *lh_delete(_LHASH *lh, const void *data); -void *lh_retrieve(_LHASH *lh, const void *data); -void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); -void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); -unsigned long lh_strhash(const char *c); -unsigned long lh_num_items(const _LHASH *lh); - -# ifndef OPENSSL_NO_FP_API -void lh_stats(const _LHASH *lh, FILE *out); -void lh_node_stats(const _LHASH *lh, FILE *out); -void lh_node_usage_stats(const _LHASH *lh, FILE *out); -# endif - -# ifndef OPENSSL_NO_BIO -void lh_stats_bio(const _LHASH *lh, BIO *out); -void lh_node_stats_bio(const _LHASH *lh, BIO *out); -void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); -# endif - -/* Type checking... */ - -# define LHASH_OF(type) struct lhash_st_##type - -# define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; } - -# define CHECKED_LHASH_OF(type,lh) \ - ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) - -/* Define wrapper functions. */ -# define LHM_lh_new(type, name) \ - ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name))) -# define LHM_lh_error(type, lh) \ - lh_error(CHECKED_LHASH_OF(type,lh)) -# define LHM_lh_insert(type, lh, inst) \ - ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \ - CHECKED_PTR_OF(type, inst))) -# define LHM_lh_retrieve(type, lh, inst) \ - ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \ - CHECKED_PTR_OF(type, inst))) -# define LHM_lh_delete(type, lh, inst) \ - ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \ - CHECKED_PTR_OF(type, inst))) -# define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn) -# define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ - lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) -# define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh)) -# define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load) -# define LHM_lh_node_stats_bio(type, lh, out) \ - lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out) -# define LHM_lh_node_usage_stats_bio(type, lh, out) \ - lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out) -# define LHM_lh_stats_bio(type, lh, out) \ - lh_stats_bio(CHECKED_LHASH_OF(type, lh), out) -# define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh)) - -DECLARE_LHASH_OF(OPENSSL_STRING); -DECLARE_LHASH_OF(OPENSSL_CSTRING); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/m_dss.c b/Sources/COpenSSL/m_dss.c deleted file mode 100644 index 573497e9..00000000 --- a/Sources/COpenSSL/m_dss.c +++ /dev/null @@ -1,104 +0,0 @@ -/* crypto/evp/m_dss.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "objects.h" -#include "sha.h" -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif - -#ifndef OPENSSL_NO_SHA - -static int init(EVP_MD_CTX *ctx) -{ - return SHA1_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA1_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA1_Final(md, ctx->md_data); -} - -static const EVP_MD dsa_md = { - NID_dsaWithSHA, - NID_dsaWithSHA, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_DSA_method, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; - -const EVP_MD *EVP_dss(void) -{ - return (&dsa_md); -} -#endif diff --git a/Sources/COpenSSL/m_dss1.c b/Sources/COpenSSL/m_dss1.c deleted file mode 100644 index 9ff5c9c2..00000000 --- a/Sources/COpenSSL/m_dss1.c +++ /dev/null @@ -1,105 +0,0 @@ -/* crypto/evp/m_dss1.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_SHA - -# include "evp.h" -# include "objects.h" -# include "sha.h" -# ifndef OPENSSL_NO_DSA -# include "dsa.h" -# endif - -static int init(EVP_MD_CTX *ctx) -{ - return SHA1_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA1_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA1_Final(md, ctx->md_data); -} - -static const EVP_MD dss1_md = { - NID_dsa, - NID_dsaWithSHA1, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_DSA_method, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; - -const EVP_MD *EVP_dss1(void) -{ - return (&dss1_md); -} -#endif diff --git a/Sources/COpenSSL/m_ecdsa.c b/Sources/COpenSSL/m_ecdsa.c deleted file mode 100644 index 5ea47a7c..00000000 --- a/Sources/COpenSSL/m_ecdsa.c +++ /dev/null @@ -1,154 +0,0 @@ -/* crypto/evp/m_ecdsa.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "objects.h" -#include "x509.h" - -#ifndef OPENSSL_NO_SHA - -static int init(EVP_MD_CTX *ctx) -{ - return SHA1_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA1_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA1_Final(md, ctx->md_data); -} - -static const EVP_MD ecdsa_md = { - NID_ecdsa_with_SHA1, - NID_ecdsa_with_SHA1, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_DIGEST, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_ECDSA_method, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; - -const EVP_MD *EVP_ecdsa(void) -{ - return (&ecdsa_md); -} -#endif diff --git a/Sources/COpenSSL/m_md2.c b/Sources/COpenSSL/m_md2.c deleted file mode 100644 index 484fcca8..00000000 --- a/Sources/COpenSSL/m_md2.c +++ /dev/null @@ -1,106 +0,0 @@ -/* crypto/evp/m_md2.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_MD2 - -# include "evp.h" -# include "objects.h" -# include "x509.h" -# include -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif - -static int init(EVP_MD_CTX *ctx) -{ - return MD2_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return MD2_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return MD2_Final(md, ctx->md_data); -} - -static const EVP_MD md2_md = { - NID_md2, - NID_md2WithRSAEncryption, - MD2_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_RSA_method, - MD2_BLOCK, - sizeof(EVP_MD *) + sizeof(MD2_CTX), -}; - -const EVP_MD *EVP_md2(void) -{ - return (&md2_md); -} -#endif diff --git a/Sources/COpenSSL/m_md4.c b/Sources/COpenSSL/m_md4.c deleted file mode 100644 index 7279456f..00000000 --- a/Sources/COpenSSL/m_md4.c +++ /dev/null @@ -1,108 +0,0 @@ -/* crypto/evp/m_md4.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_MD4 - -# include "evp.h" -# include "objects.h" -# include "x509.h" -# include "md4.h" -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif - -# include "evp_locl.h" - -static int init(EVP_MD_CTX *ctx) -{ - return MD4_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return MD4_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return MD4_Final(md, ctx->md_data); -} - -static const EVP_MD md4_md = { - NID_md4, - NID_md4WithRSAEncryption, - MD4_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_RSA_method, - MD4_CBLOCK, - sizeof(EVP_MD *) + sizeof(MD4_CTX), -}; - -const EVP_MD *EVP_md4(void) -{ - return (&md4_md); -} -#endif diff --git a/Sources/COpenSSL/m_md5.c b/Sources/COpenSSL/m_md5.c deleted file mode 100644 index 018892e2..00000000 --- a/Sources/COpenSSL/m_md5.c +++ /dev/null @@ -1,107 +0,0 @@ -/* crypto/evp/m_md5.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_MD5 - -# include "evp.h" -# include "objects.h" -# include "x509.h" -# include "md5.h" -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif -# include "evp_locl.h" - -static int init(EVP_MD_CTX *ctx) -{ - return MD5_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return MD5_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return MD5_Final(md, ctx->md_data); -} - -static const EVP_MD md5_md = { - NID_md5, - NID_md5WithRSAEncryption, - MD5_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_RSA_method, - MD5_CBLOCK, - sizeof(EVP_MD *) + sizeof(MD5_CTX), -}; - -const EVP_MD *EVP_md5(void) -{ - return (&md5_md); -} -#endif diff --git a/Sources/COpenSSL/m_mdc2.c b/Sources/COpenSSL/m_mdc2.c deleted file mode 100644 index 877391af..00000000 --- a/Sources/COpenSSL/m_mdc2.c +++ /dev/null @@ -1,108 +0,0 @@ -/* crypto/evp/m_mdc2.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_MDC2 - -# include "evp.h" -# include "objects.h" -# include "x509.h" -# include "mdc2.h" -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif - -# include "evp_locl.h" - -static int init(EVP_MD_CTX *ctx) -{ - return MDC2_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return MDC2_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return MDC2_Final(md, ctx->md_data); -} - -static const EVP_MD mdc2_md = { - NID_mdc2, - NID_mdc2WithRSA, - MDC2_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_RSA_ASN1_OCTET_STRING_method, - MDC2_BLOCK, - sizeof(EVP_MD *) + sizeof(MDC2_CTX), -}; - -const EVP_MD *EVP_mdc2(void) -{ - return (&mdc2_md); -} -#endif diff --git a/Sources/COpenSSL/m_null.c b/Sources/COpenSSL/m_null.c deleted file mode 100644 index 469afbc9..00000000 --- a/Sources/COpenSSL/m_null.c +++ /dev/null @@ -1,98 +0,0 @@ -/* crypto/evp/m_null.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "objects.h" -#include "x509.h" - -static int init(EVP_MD_CTX *ctx) -{ - return 1; -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return 1; -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return 1; -} - -static const EVP_MD null_md = { - NID_undef, - NID_undef, - 0, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_NULL_method, - 0, - sizeof(EVP_MD *), -}; - -const EVP_MD *EVP_md_null(void) -{ - return (&null_md); -} diff --git a/Sources/COpenSSL/m_ripemd.c b/Sources/COpenSSL/m_ripemd.c deleted file mode 100644 index 211fe7af..00000000 --- a/Sources/COpenSSL/m_ripemd.c +++ /dev/null @@ -1,107 +0,0 @@ -/* crypto/evp/m_ripemd.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_RIPEMD - -# include "ripemd.h" -# include "evp.h" -# include "objects.h" -# include "x509.h" -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif -# include "evp_locl.h" - -static int init(EVP_MD_CTX *ctx) -{ - return RIPEMD160_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return RIPEMD160_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return RIPEMD160_Final(md, ctx->md_data); -} - -static const EVP_MD ripemd160_md = { - NID_ripemd160, - NID_ripemd160WithRSA, - RIPEMD160_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_RSA_method, - RIPEMD160_CBLOCK, - sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX), -}; - -const EVP_MD *EVP_ripemd160(void) -{ - return (&ripemd160_md); -} -#endif diff --git a/Sources/COpenSSL/m_sha.c b/Sources/COpenSSL/m_sha.c deleted file mode 100644 index e952f579..00000000 --- a/Sources/COpenSSL/m_sha.c +++ /dev/null @@ -1,106 +0,0 @@ -/* crypto/evp/m_sha.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0) - -# include "evp.h" -# include "objects.h" -# include "x509.h" -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif -# include "evp_locl.h" - -static int init(EVP_MD_CTX *ctx) -{ - return SHA_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA_Final(md, ctx->md_data); -} - -static const EVP_MD sha_md = { - NID_sha, - NID_shaWithRSAEncryption, - SHA_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_RSA_method, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; - -const EVP_MD *EVP_sha(void) -{ - return (&sha_md); -} -#endif diff --git a/Sources/COpenSSL/m_sha1.c b/Sources/COpenSSL/m_sha1.c deleted file mode 100644 index 9374ca9b..00000000 --- a/Sources/COpenSSL/m_sha1.c +++ /dev/null @@ -1,235 +0,0 @@ -/* crypto/evp/m_sha1.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_SHA - -# include "evp.h" -# include "objects.h" -# include "sha.h" -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif - -static int init(EVP_MD_CTX *ctx) -{ - return SHA1_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA1_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA1_Final(md, ctx->md_data); -} - -static const EVP_MD sha1_md = { - NID_sha1, - NID_sha1WithRSAEncryption, - SHA_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_RSA_method, - SHA_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA_CTX), -}; - -const EVP_MD *EVP_sha1(void) -{ - return (&sha1_md); -} -#endif - -#ifndef OPENSSL_NO_SHA256 -static int init224(EVP_MD_CTX *ctx) -{ - return SHA224_Init(ctx->md_data); -} - -static int init256(EVP_MD_CTX *ctx) -{ - return SHA256_Init(ctx->md_data); -} - -/* - * Even though there're separate SHA224_[Update|Final], we call - * SHA256 functions even in SHA224 context. This is what happens - * there anyway, so we can spare few CPU cycles:-) - */ -static int update256(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA256_Update(ctx->md_data, data, count); -} - -static int final256(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA256_Final(md, ctx->md_data); -} - -static const EVP_MD sha224_md = { - NID_sha224, - NID_sha224WithRSAEncryption, - SHA224_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, - init224, - update256, - final256, - NULL, - NULL, - EVP_PKEY_RSA_method, - SHA256_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA256_CTX), -}; - -const EVP_MD *EVP_sha224(void) -{ - return (&sha224_md); -} - -static const EVP_MD sha256_md = { - NID_sha256, - NID_sha256WithRSAEncryption, - SHA256_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, - init256, - update256, - final256, - NULL, - NULL, - EVP_PKEY_RSA_method, - SHA256_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA256_CTX), -}; - -const EVP_MD *EVP_sha256(void) -{ - return (&sha256_md); -} -#endif /* ifndef OPENSSL_NO_SHA256 */ - -#ifndef OPENSSL_NO_SHA512 -static int init384(EVP_MD_CTX *ctx) -{ - return SHA384_Init(ctx->md_data); -} - -static int init512(EVP_MD_CTX *ctx) -{ - return SHA512_Init(ctx->md_data); -} - -/* See comment in SHA224/256 section */ -static int update512(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return SHA512_Update(ctx->md_data, data, count); -} - -static int final512(EVP_MD_CTX *ctx, unsigned char *md) -{ - return SHA512_Final(md, ctx->md_data); -} - -static const EVP_MD sha384_md = { - NID_sha384, - NID_sha384WithRSAEncryption, - SHA384_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, - init384, - update512, - final512, - NULL, - NULL, - EVP_PKEY_RSA_method, - SHA512_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA512_CTX), -}; - -const EVP_MD *EVP_sha384(void) -{ - return (&sha384_md); -} - -static const EVP_MD sha512_md = { - NID_sha512, - NID_sha512WithRSAEncryption, - SHA512_DIGEST_LENGTH, - EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, - init512, - update512, - final512, - NULL, - NULL, - EVP_PKEY_RSA_method, - SHA512_CBLOCK, - sizeof(EVP_MD *) + sizeof(SHA512_CTX), -}; - -const EVP_MD *EVP_sha512(void) -{ - return (&sha512_md); -} -#endif /* ifndef OPENSSL_NO_SHA512 */ diff --git a/Sources/COpenSSL/m_sigver.c b/Sources/COpenSSL/m_sigver.c deleted file mode 100644 index 36658927..00000000 --- a/Sources/COpenSSL/m_sigver.c +++ /dev/null @@ -1,204 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* m_sigver.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006,2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "objects.h" -#include "x509.h" -#include "evp_locl.h" - -static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, - int ver) -{ - if (ctx->pctx == NULL) - ctx->pctx = EVP_PKEY_CTX_new(pkey, e); - if (ctx->pctx == NULL) - return 0; - - if (!(ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM)) { - - if (type == NULL) { - int def_nid; - if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) - type = EVP_get_digestbynid(def_nid); - } - - if (type == NULL) { - EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); - return 0; - } - } - - if (ver) { - if (ctx->pctx->pmeth->verifyctx_init) { - if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0) - return 0; - ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; - } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) - return 0; - } else { - if (ctx->pctx->pmeth->signctx_init) { - if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) - return 0; - ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; - } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) - return 0; - } - if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) - return 0; - if (pctx) - *pctx = ctx->pctx; - if (ctx->pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) - return 1; - if (!EVP_DigestInit_ex(ctx, type, e)) - return 0; - return 1; -} - -int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) -{ - return do_sigver_init(ctx, pctx, type, e, pkey, 0); -} - -int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, - const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) -{ - return do_sigver_init(ctx, pctx, type, e, pkey, 1); -} - -int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, - size_t *siglen) -{ - int sctx, r = 0; - EVP_PKEY_CTX *pctx = ctx->pctx; - if (pctx->pmeth->flags & EVP_PKEY_FLAG_SIGCTX_CUSTOM) { - EVP_PKEY_CTX *dctx; - if (!sigret) - return pctx->pmeth->signctx(pctx, sigret, siglen, ctx); - dctx = EVP_PKEY_CTX_dup(ctx->pctx); - if (!dctx) - return 0; - r = dctx->pmeth->signctx(dctx, sigret, siglen, ctx); - EVP_PKEY_CTX_free(dctx); - return r; - } - if (pctx->pmeth->signctx) - sctx = 1; - else - sctx = 0; - if (sigret) { - EVP_MD_CTX tmp_ctx; - unsigned char md[EVP_MAX_MD_SIZE]; - unsigned int mdlen; - EVP_MD_CTX_init(&tmp_ctx); - if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) - return 0; - if (sctx) - r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, - sigret, siglen, &tmp_ctx); - else - r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); - EVP_MD_CTX_cleanup(&tmp_ctx); - if (sctx || !r) - return r; - if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) - return 0; - } else { - if (sctx) { - if (pctx->pmeth->signctx(pctx, sigret, siglen, ctx) <= 0) - return 0; - } else { - int s = EVP_MD_size(ctx->digest); - if (s < 0 || EVP_PKEY_sign(pctx, sigret, siglen, NULL, s) <= 0) - return 0; - } - } - return 1; -} - -int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig, - size_t siglen) -{ - EVP_MD_CTX tmp_ctx; - unsigned char md[EVP_MAX_MD_SIZE]; - int r; - unsigned int mdlen; - int vctx; - - if (ctx->pctx->pmeth->verifyctx) - vctx = 1; - else - vctx = 0; - EVP_MD_CTX_init(&tmp_ctx); - if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) - return -1; - if (vctx) { - r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, - sig, siglen, &tmp_ctx); - } else - r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); - EVP_MD_CTX_cleanup(&tmp_ctx); - if (vctx || !r) - return r; - return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); -} diff --git a/Sources/COpenSSL/m_wp.c b/Sources/COpenSSL/m_wp.c deleted file mode 100644 index 7698e0cd..00000000 --- a/Sources/COpenSSL/m_wp.c +++ /dev/null @@ -1,48 +0,0 @@ -/* crypto/evp/m_wp.c */ - -#include -#include "cryptlib.h" - -#ifndef OPENSSL_NO_WHIRLPOOL - -# include "evp.h" -# include "objects.h" -# include "x509.h" -# include "whrlpool.h" -# include "evp_locl.h" - -static int init(EVP_MD_CTX *ctx) -{ - return WHIRLPOOL_Init(ctx->md_data); -} - -static int update(EVP_MD_CTX *ctx, const void *data, size_t count) -{ - return WHIRLPOOL_Update(ctx->md_data, data, count); -} - -static int final(EVP_MD_CTX *ctx, unsigned char *md) -{ - return WHIRLPOOL_Final(md, ctx->md_data); -} - -static const EVP_MD whirlpool_md = { - NID_whirlpool, - 0, - WHIRLPOOL_DIGEST_LENGTH, - 0, - init, - update, - final, - NULL, - NULL, - EVP_PKEY_NULL_method, - WHIRLPOOL_BBLOCK / 8, - sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX), -}; - -const EVP_MD *EVP_whirlpool(void) -{ - return (&whirlpool_md); -} -#endif diff --git a/Sources/COpenSSL/md32_common.h b/Sources/COpenSSL/md32_common.h deleted file mode 100644 index 597e7ba8..00000000 --- a/Sources/COpenSSL/md32_common.h +++ /dev/null @@ -1,437 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/md32_common.h */ -/* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -/*- - * This is a generic 32 bit "collector" for message digest algorithms. - * Whenever needed it collects input character stream into chunks of - * 32 bit values and invokes a block function that performs actual hash - * calculations. - * - * Porting guide. - * - * Obligatory macros: - * - * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN - * this macro defines byte order of input stream. - * HASH_CBLOCK - * size of a unit chunk HASH_BLOCK operates on. - * HASH_LONG - * has to be at lest 32 bit wide, if it's wider, then - * HASH_LONG_LOG2 *has to* be defined along - * HASH_CTX - * context structure that at least contains following - * members: - * typedef struct { - * ... - * HASH_LONG Nl,Nh; - * either { - * HASH_LONG data[HASH_LBLOCK]; - * unsigned char data[HASH_CBLOCK]; - * }; - * unsigned int num; - * ... - * } HASH_CTX; - * data[] vector is expected to be zeroed upon first call to - * HASH_UPDATE. - * HASH_UPDATE - * name of "Update" function, implemented here. - * HASH_TRANSFORM - * name of "Transform" function, implemented here. - * HASH_FINAL - * name of "Final" function, implemented here. - * HASH_BLOCK_DATA_ORDER - * name of "block" function capable of treating *unaligned* input - * message in original (data) byte order, implemented externally. - * HASH_MAKE_STRING - * macro convering context variables to an ASCII hash string. - * - * MD5 example: - * - * #define DATA_ORDER_IS_LITTLE_ENDIAN - * - * #define HASH_LONG MD5_LONG - * #define HASH_LONG_LOG2 MD5_LONG_LOG2 - * #define HASH_CTX MD5_CTX - * #define HASH_CBLOCK MD5_CBLOCK - * #define HASH_UPDATE MD5_Update - * #define HASH_TRANSFORM MD5_Transform - * #define HASH_FINAL MD5_Final - * #define HASH_BLOCK_DATA_ORDER md5_block_data_order - * - * - */ - -#include "crypto.h" - -#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) -# error "DATA_ORDER must be defined!" -#endif - -#ifndef HASH_CBLOCK -# error "HASH_CBLOCK must be defined!" -#endif -#ifndef HASH_LONG -# error "HASH_LONG must be defined!" -#endif -#ifndef HASH_CTX -# error "HASH_CTX must be defined!" -#endif - -#ifndef HASH_UPDATE -# error "HASH_UPDATE must be defined!" -#endif -#ifndef HASH_TRANSFORM -# error "HASH_TRANSFORM must be defined!" -#endif -#ifndef HASH_FINAL -# error "HASH_FINAL must be defined!" -#endif - -#ifndef HASH_BLOCK_DATA_ORDER -# error "HASH_BLOCK_DATA_ORDER must be defined!" -#endif - -/* - * Engage compiler specific rotate intrinsic function if available. - */ -#undef ROTATE -#ifndef PEDANTIC -# if defined(_MSC_VER) -# define ROTATE(a,n) _lrotl(a,n) -# elif defined(__ICC) -# define ROTATE(a,n) _rotl(a,n) -# elif defined(__MWERKS__) -# if defined(__POWERPC__) -# define ROTATE(a,n) __rlwinm(a,n,0,31) -# elif defined(__MC68K__) - /* Motorola specific tweak. */ -# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) -# else -# define ROTATE(a,n) __rol(a,n) -# endif -# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) - /* - * Some GNU C inline assembler templates. Note that these are - * rotates by *constant* number of bits! But that's exactly - * what we need here... - * - */ -# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) -# define ROTATE(a,n) ({ register unsigned int ret; \ - asm ( \ - "roll %1,%0" \ - : "=r"(ret) \ - : "I"(n), "0"((unsigned int)(a)) \ - : "cc"); \ - ret; \ - }) -# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ - defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) -# define ROTATE(a,n) ({ register unsigned int ret; \ - asm ( \ - "rlwinm %0,%1,%2,0,31" \ - : "=r"(ret) \ - : "r"(a), "I"(n)); \ - ret; \ - }) -# elif defined(__s390x__) -# define ROTATE(a,n) ({ register unsigned int ret; \ - asm ("rll %0,%1,%2" \ - : "=r"(ret) \ - : "r"(a), "I"(n)); \ - ret; \ - }) -# endif -# endif -#endif /* PEDANTIC */ - -#ifndef ROTATE -# define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) -#endif - -#if defined(DATA_ORDER_IS_BIG_ENDIAN) - -# ifndef PEDANTIC -# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) -# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \ - (defined(__x86_64) || defined(__x86_64__)) -# if !defined(B_ENDIAN) - /* - * This gives ~30-40% performance improvement in SHA-256 compiled - * with gcc [on P4]. Well, first macro to be frank. We can pull - * this trick on x86* platforms only, because these CPUs can fetch - * unaligned data without raising an exception. - */ -# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \ - asm ("bswapl %0":"=r"(r):"0"(r)); \ - (c)+=4; (l)=r; }) -# define HOST_l2c(l,c) ({ unsigned int r=(l); \ - asm ("bswapl %0":"=r"(r):"0"(r)); \ - *((unsigned int *)(c))=r; (c)+=4; r; }) -# endif -# elif defined(__aarch64__) -# if defined(__BYTE_ORDER__) -# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ -# define HOST_c2l(c,l) ({ unsigned int r; \ - asm ("rev %w0,%w1" \ - :"=r"(r) \ - :"r"(*((const unsigned int *)(c))));\ - (c)+=4; (l)=r; }) -# define HOST_l2c(l,c) ({ unsigned int r; \ - asm ("rev %w0,%w1" \ - :"=r"(r) \ - :"r"((unsigned int)(l)));\ - *((unsigned int *)(c))=r; (c)+=4; r; }) -# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ -# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l)) -# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l)) -# endif -# endif -# endif -# endif -# if defined(__s390__) || defined(__s390x__) -# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l)) -# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l)) -# endif -# endif - -# ifndef HOST_c2l -# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++))) ) ) -# endif -# ifndef HOST_l2c -# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff), \ - l) -# endif - -#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) - -# ifndef PEDANTIC -# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) -# if defined(__s390x__) -# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \ - :"=d"(l) :"m"(*(const unsigned int *)(c)));\ - (c)+=4; (l); }) -# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \ - :"=m"(*(unsigned int *)(c)) :"d"(l));\ - (c)+=4; (l); }) -# endif -# endif -# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) -# ifndef B_ENDIAN - /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ -# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l) -# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l) -# endif -# endif -# endif - -# ifndef HOST_c2l -# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<<24) ) -# endif -# ifndef HOST_l2c -# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - l) -# endif - -#endif - -/* - * Time for some action:-) - */ - -int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) -{ - const unsigned char *data = data_; - unsigned char *p; - HASH_LONG l; - size_t n; - - if (len == 0) - return 1; - - l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL; - /* - * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai - * for pointing it out. - */ - if (l < c->Nl) /* overflow */ - c->Nh++; - c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on - * 16-bit */ - c->Nl = l; - - n = c->num; - if (n != 0) { - p = (unsigned char *)c->data; - - if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { - memcpy(p + n, data, HASH_CBLOCK - n); - HASH_BLOCK_DATA_ORDER(c, p, 1); - n = HASH_CBLOCK - n; - data += n; - len -= n; - c->num = 0; - /* - * We use memset rather than OPENSSL_cleanse() here deliberately. - * Using OPENSSL_cleanse() here could be a performance issue. It - * will get properly cleansed on finalisation so this isn't a - * security problem. - */ - memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ - } else { - memcpy(p + n, data, len); - c->num += (unsigned int)len; - return 1; - } - } - - n = len / HASH_CBLOCK; - if (n > 0) { - HASH_BLOCK_DATA_ORDER(c, data, n); - n *= HASH_CBLOCK; - data += n; - len -= n; - } - - if (len != 0) { - p = (unsigned char *)c->data; - c->num = (unsigned int)len; - memcpy(p, data, len); - } - return 1; -} - -void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data) -{ - HASH_BLOCK_DATA_ORDER(c, data, 1); -} - -int HASH_FINAL(unsigned char *md, HASH_CTX *c) -{ - unsigned char *p = (unsigned char *)c->data; - size_t n = c->num; - - p[n] = 0x80; /* there is always room for one */ - n++; - - if (n > (HASH_CBLOCK - 8)) { - memset(p + n, 0, HASH_CBLOCK - n); - n = 0; - HASH_BLOCK_DATA_ORDER(c, p, 1); - } - memset(p + n, 0, HASH_CBLOCK - 8 - n); - - p += HASH_CBLOCK - 8; -#if defined(DATA_ORDER_IS_BIG_ENDIAN) - (void)HOST_l2c(c->Nh, p); - (void)HOST_l2c(c->Nl, p); -#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) - (void)HOST_l2c(c->Nl, p); - (void)HOST_l2c(c->Nh, p); -#endif - p -= HASH_CBLOCK; - HASH_BLOCK_DATA_ORDER(c, p, 1); - c->num = 0; - OPENSSL_cleanse(p, HASH_CBLOCK); - -#ifndef HASH_MAKE_STRING -# error "HASH_MAKE_STRING must be defined!" -#else - HASH_MAKE_STRING(c, md); -#endif - - return 1; -} - -#ifndef MD32_REG_T -# if defined(__alpha) || defined(__sparcv9) || defined(__mips) -# define MD32_REG_T long -/* - * This comment was originaly written for MD5, which is why it - * discusses A-D. But it basically applies to all 32-bit digests, - * which is why it was moved to common header file. - * - * In case you wonder why A-D are declared as long and not - * as MD5_LONG. Doing so results in slight performance - * boost on LP64 architectures. The catch is we don't - * really care if 32 MSBs of a 64-bit register get polluted - * with eventual overflows as we *save* only 32 LSBs in - * *either* case. Now declaring 'em long excuses the compiler - * from keeping 32 MSBs zeroed resulting in 13% performance - * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. - * Well, to be honest it should say that this *prevents* - * performance degradation. - * - */ -# else -/* - * Above is not absolute and there are LP64 compilers that - * generate better code if MD32_REG_T is defined int. The above - * pre-processor condition reflects the circumstances under which - * the conclusion was made and is subject to further extension. - * - */ -# define MD32_REG_T int -# endif -#endif diff --git a/Sources/COpenSSL/md4.h b/Sources/COpenSSL/md4.h deleted file mode 100644 index 66fa0a6f..00000000 --- a/Sources/COpenSSL/md4.h +++ /dev/null @@ -1,119 +0,0 @@ -/* crypto/md4/md4.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_MD4_H -# define HEADER_MD4_H - -# include "e_os2.h" -# include - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef OPENSSL_NO_MD4 -# error MD4 is disabled. -# endif - -/*- - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then ! - * ! MD4_LONG_LOG2 has to be defined along. ! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - -# if defined(__LP32__) -# define MD4_LONG unsigned long -# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) -# define MD4_LONG unsigned long -# define MD4_LONG_LOG2 3 -/* - * _CRAY note. I could declare short, but I have no idea what impact - * does it have on performance on none-T3E machines. I could declare - * int, but at least on C90 sizeof(int) can be chosen at compile time. - * So I've chosen long... - * - */ -# else -# define MD4_LONG unsigned int -# endif - -# define MD4_CBLOCK 64 -# define MD4_LBLOCK (MD4_CBLOCK/4) -# define MD4_DIGEST_LENGTH 16 - -typedef struct MD4state_st { - MD4_LONG A, B, C, D; - MD4_LONG Nl, Nh; - MD4_LONG data[MD4_LBLOCK]; - unsigned int num; -} MD4_CTX; - -# ifdef OPENSSL_FIPS -int private_MD4_Init(MD4_CTX *c); -# endif -int MD4_Init(MD4_CTX *c); -int MD4_Update(MD4_CTX *c, const void *data, size_t len); -int MD4_Final(unsigned char *md, MD4_CTX *c); -unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); -void MD4_Transform(MD4_CTX *c, const unsigned char *b); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/md4_.c b/Sources/COpenSSL/md4_.c deleted file mode 100644 index fe8c8401..00000000 --- a/Sources/COpenSSL/md4_.c +++ /dev/null @@ -1,295 +0,0 @@ -/* crypto/md4/md4_dgst.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "opensslv.h" -#include "crypto.h" -#include "md4_locl.h" - -const char MD4_version[] = "MD4" OPENSSL_VERSION_PTEXT; - -/* - * Implemented from RFC1186 The MD4 Message-Digest Algorithm - */ - -#define INIT_DATA_A (unsigned long)0x67452301L -#define INIT_DATA_B (unsigned long)0xefcdab89L -#define INIT_DATA_C (unsigned long)0x98badcfeL -#define INIT_DATA_D (unsigned long)0x10325476L - -fips_md_init(MD4) -{ - memset(c, 0, sizeof(*c)); - c->A = INIT_DATA_A; - c->B = INIT_DATA_B; - c->C = INIT_DATA_C; - c->D = INIT_DATA_D; - return 1; -} - -#ifndef md4_block_data_order -# ifdef X -# undef X -# endif -void md4_block_data_order(MD4_CTX *c, const void *data_, size_t num) -{ - const unsigned char *data = data_; - register unsigned MD32_REG_T A, B, C, D, l; -# ifndef MD32_XARRAY - /* See comment in crypto/sha/sha_locl.h for details. */ - unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; -# define X(i) XX##i -# else - MD4_LONG XX[MD4_LBLOCK]; -# define X(i) XX[i] -# endif - - A = c->A; - B = c->B; - C = c->C; - D = c->D; - - for (; num--;) { - (void)HOST_c2l(data, l); - X(0) = l; - (void)HOST_c2l(data, l); - X(1) = l; - /* Round 0 */ - R0(A, B, C, D, X(0), 3, 0); - (void)HOST_c2l(data, l); - X(2) = l; - R0(D, A, B, C, X(1), 7, 0); - (void)HOST_c2l(data, l); - X(3) = l; - R0(C, D, A, B, X(2), 11, 0); - (void)HOST_c2l(data, l); - X(4) = l; - R0(B, C, D, A, X(3), 19, 0); - (void)HOST_c2l(data, l); - X(5) = l; - R0(A, B, C, D, X(4), 3, 0); - (void)HOST_c2l(data, l); - X(6) = l; - R0(D, A, B, C, X(5), 7, 0); - (void)HOST_c2l(data, l); - X(7) = l; - R0(C, D, A, B, X(6), 11, 0); - (void)HOST_c2l(data, l); - X(8) = l; - R0(B, C, D, A, X(7), 19, 0); - (void)HOST_c2l(data, l); - X(9) = l; - R0(A, B, C, D, X(8), 3, 0); - (void)HOST_c2l(data, l); - X(10) = l; - R0(D, A, B, C, X(9), 7, 0); - (void)HOST_c2l(data, l); - X(11) = l; - R0(C, D, A, B, X(10), 11, 0); - (void)HOST_c2l(data, l); - X(12) = l; - R0(B, C, D, A, X(11), 19, 0); - (void)HOST_c2l(data, l); - X(13) = l; - R0(A, B, C, D, X(12), 3, 0); - (void)HOST_c2l(data, l); - X(14) = l; - R0(D, A, B, C, X(13), 7, 0); - (void)HOST_c2l(data, l); - X(15) = l; - R0(C, D, A, B, X(14), 11, 0); - R0(B, C, D, A, X(15), 19, 0); - /* Round 1 */ - R1(A, B, C, D, X(0), 3, 0x5A827999L); - R1(D, A, B, C, X(4), 5, 0x5A827999L); - R1(C, D, A, B, X(8), 9, 0x5A827999L); - R1(B, C, D, A, X(12), 13, 0x5A827999L); - R1(A, B, C, D, X(1), 3, 0x5A827999L); - R1(D, A, B, C, X(5), 5, 0x5A827999L); - R1(C, D, A, B, X(9), 9, 0x5A827999L); - R1(B, C, D, A, X(13), 13, 0x5A827999L); - R1(A, B, C, D, X(2), 3, 0x5A827999L); - R1(D, A, B, C, X(6), 5, 0x5A827999L); - R1(C, D, A, B, X(10), 9, 0x5A827999L); - R1(B, C, D, A, X(14), 13, 0x5A827999L); - R1(A, B, C, D, X(3), 3, 0x5A827999L); - R1(D, A, B, C, X(7), 5, 0x5A827999L); - R1(C, D, A, B, X(11), 9, 0x5A827999L); - R1(B, C, D, A, X(15), 13, 0x5A827999L); - /* Round 2 */ - R2(A, B, C, D, X(0), 3, 0x6ED9EBA1L); - R2(D, A, B, C, X(8), 9, 0x6ED9EBA1L); - R2(C, D, A, B, X(4), 11, 0x6ED9EBA1L); - R2(B, C, D, A, X(12), 15, 0x6ED9EBA1L); - R2(A, B, C, D, X(2), 3, 0x6ED9EBA1L); - R2(D, A, B, C, X(10), 9, 0x6ED9EBA1L); - R2(C, D, A, B, X(6), 11, 0x6ED9EBA1L); - R2(B, C, D, A, X(14), 15, 0x6ED9EBA1L); - R2(A, B, C, D, X(1), 3, 0x6ED9EBA1L); - R2(D, A, B, C, X(9), 9, 0x6ED9EBA1L); - R2(C, D, A, B, X(5), 11, 0x6ED9EBA1L); - R2(B, C, D, A, X(13), 15, 0x6ED9EBA1L); - R2(A, B, C, D, X(3), 3, 0x6ED9EBA1L); - R2(D, A, B, C, X(11), 9, 0x6ED9EBA1L); - R2(C, D, A, B, X(7), 11, 0x6ED9EBA1L); - R2(B, C, D, A, X(15), 15, 0x6ED9EBA1L); - - A = c->A += A; - B = c->B += B; - C = c->C += C; - D = c->D += D; - } -} -#endif -/* crypto/md4/md4_one.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "md4.h" -// #include "crypto.h" - -#ifdef CHARSET_EBCDIC -# include "ebcdic.h" -#endif - -unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md) -{ - MD4_CTX c; - static unsigned char m[MD4_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - if (!MD4_Init(&c)) - return NULL; -#ifndef CHARSET_EBCDIC - MD4_Update(&c, d, n); -#else - { - char temp[1024]; - unsigned long chunk; - - while (n > 0) { - chunk = (n > sizeof(temp)) ? sizeof(temp) : n; - ebcdic2ascii(temp, d, chunk); - MD4_Update(&c, temp, chunk); - n -= chunk; - d += chunk; - } - } -#endif - MD4_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ - return (md); -} diff --git a/Sources/COpenSSL/md4_locl.h b/Sources/COpenSSL/md4_locl.h deleted file mode 100644 index 9d332d24..00000000 --- a/Sources/COpenSSL/md4_locl.h +++ /dev/null @@ -1,113 +0,0 @@ -/* crypto/md4/md4_locl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "opensslconf.h" -#include "md4.h" - -#ifndef MD4_LONG_LOG2 -# define MD4_LONG_LOG2 2 /* default to 32 bits */ -#endif - -void md4_block_data_order(MD4_CTX *c, const void *p, size_t num); - -#define DATA_ORDER_IS_LITTLE_ENDIAN - -#define HASH_LONG MD4_LONG -#define HASH_CTX MD4_CTX -#define HASH_CBLOCK MD4_CBLOCK -#define HASH_UPDATE MD4_Update -#define HASH_TRANSFORM MD4_Transform -#define HASH_FINAL MD4_Final -#define HASH_MAKE_STRING(c,s) do { \ - unsigned long ll; \ - ll=(c)->A; (void)HOST_l2c(ll,(s)); \ - ll=(c)->B; (void)HOST_l2c(ll,(s)); \ - ll=(c)->C; (void)HOST_l2c(ll,(s)); \ - ll=(c)->D; (void)HOST_l2c(ll,(s)); \ - } while (0) -#define HASH_BLOCK_DATA_ORDER md4_block_data_order - -#include "md32_common.h" - -/*- -#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) -#define G(x,y,z) (((x) & (y)) | ((x) & ((z))) | ((y) & ((z)))) -*/ - -/* - * As pointed out by Wei Dai , the above can be simplified - * to the code below. Wei attributes these optimizations to Peter Gutmann's - * SHS code, and he attributes it to Rich Schroeppel. - */ -#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) -#define G(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) -#define H(b,c,d) ((b) ^ (c) ^ (d)) - -#define R0(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+F((b),(c),(d))); \ - a=ROTATE(a,s); }; - -#define R1(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+G((b),(c),(d))); \ - a=ROTATE(a,s); };\ - -#define R2(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+H((b),(c),(d))); \ - a=ROTATE(a,s); }; diff --git a/Sources/COpenSSL/md5.h b/Sources/COpenSSL/md5.h deleted file mode 100644 index 2b8daa1f..00000000 --- a/Sources/COpenSSL/md5.h +++ /dev/null @@ -1,119 +0,0 @@ -/* crypto/md5/md5.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_MD5_H -# define HEADER_MD5_H - -# include "e_os2.h" -# include - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef OPENSSL_NO_MD5 -# error MD5 is disabled. -# endif - -/* - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then ! - * ! MD5_LONG_LOG2 has to be defined along. ! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - -# if defined(__LP32__) -# define MD5_LONG unsigned long -# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) -# define MD5_LONG unsigned long -# define MD5_LONG_LOG2 3 -/* - * _CRAY note. I could declare short, but I have no idea what impact - * does it have on performance on none-T3E machines. I could declare - * int, but at least on C90 sizeof(int) can be chosen at compile time. - * So I've chosen long... - * - */ -# else -# define MD5_LONG unsigned int -# endif - -# define MD5_CBLOCK 64 -# define MD5_LBLOCK (MD5_CBLOCK/4) -# define MD5_DIGEST_LENGTH 16 - -typedef struct MD5state_st { - MD5_LONG A, B, C, D; - MD5_LONG Nl, Nh; - MD5_LONG data[MD5_LBLOCK]; - unsigned int num; -} MD5_CTX; - -# ifdef OPENSSL_FIPS -int private_MD5_Init(MD5_CTX *c); -# endif -int MD5_Init(MD5_CTX *c); -int MD5_Update(MD5_CTX *c, const void *data, size_t len); -int MD5_Final(unsigned char *md, MD5_CTX *c); -unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); -void MD5_Transform(MD5_CTX *c, const unsigned char *b); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/md5_.c b/Sources/COpenSSL/md5_.c deleted file mode 100644 index 1186439c..00000000 --- a/Sources/COpenSSL/md5_.c +++ /dev/null @@ -1,312 +0,0 @@ -/* crypto/md5/md5_dgst.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "md5_locl.h" -#include "opensslv.h" -// #include "crypto.h" - -const char MD5_version[] = "MD5" OPENSSL_VERSION_PTEXT; - -/* - * Implemented from RFC1321 The MD5 Message-Digest Algorithm - */ - -#define INIT_DATA_A (unsigned long)0x67452301L -#define INIT_DATA_B (unsigned long)0xefcdab89L -#define INIT_DATA_C (unsigned long)0x98badcfeL -#define INIT_DATA_D (unsigned long)0x10325476L - -fips_md_init(MD5) -{ - memset(c, 0, sizeof(*c)); - c->A = INIT_DATA_A; - c->B = INIT_DATA_B; - c->C = INIT_DATA_C; - c->D = INIT_DATA_D; - return 1; -} - -#ifndef md5_block_data_order -# ifdef X -# undef X -# endif -void md5_block_data_order(MD5_CTX *c, const void *data_, size_t num) -{ - const unsigned char *data = data_; - register unsigned MD32_REG_T A, B, C, D, l; -# ifndef MD32_XARRAY - /* See comment in crypto/sha/sha_locl.h for details. */ - unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; -# define X(i) XX##i -# else - MD5_LONG XX[MD5_LBLOCK]; -# define X(i) XX[i] -# endif - - A = c->A; - B = c->B; - C = c->C; - D = c->D; - - for (; num--;) { - HOST_c2l(data, l); - X(0) = l; - HOST_c2l(data, l); - X(1) = l; - /* Round 0 */ - R0(A, B, C, D, X(0), 7, 0xd76aa478L); - HOST_c2l(data, l); - X(2) = l; - R0(D, A, B, C, X(1), 12, 0xe8c7b756L); - HOST_c2l(data, l); - X(3) = l; - R0(C, D, A, B, X(2), 17, 0x242070dbL); - HOST_c2l(data, l); - X(4) = l; - R0(B, C, D, A, X(3), 22, 0xc1bdceeeL); - HOST_c2l(data, l); - X(5) = l; - R0(A, B, C, D, X(4), 7, 0xf57c0fafL); - HOST_c2l(data, l); - X(6) = l; - R0(D, A, B, C, X(5), 12, 0x4787c62aL); - HOST_c2l(data, l); - X(7) = l; - R0(C, D, A, B, X(6), 17, 0xa8304613L); - HOST_c2l(data, l); - X(8) = l; - R0(B, C, D, A, X(7), 22, 0xfd469501L); - HOST_c2l(data, l); - X(9) = l; - R0(A, B, C, D, X(8), 7, 0x698098d8L); - HOST_c2l(data, l); - X(10) = l; - R0(D, A, B, C, X(9), 12, 0x8b44f7afL); - HOST_c2l(data, l); - X(11) = l; - R0(C, D, A, B, X(10), 17, 0xffff5bb1L); - HOST_c2l(data, l); - X(12) = l; - R0(B, C, D, A, X(11), 22, 0x895cd7beL); - HOST_c2l(data, l); - X(13) = l; - R0(A, B, C, D, X(12), 7, 0x6b901122L); - HOST_c2l(data, l); - X(14) = l; - R0(D, A, B, C, X(13), 12, 0xfd987193L); - HOST_c2l(data, l); - X(15) = l; - R0(C, D, A, B, X(14), 17, 0xa679438eL); - R0(B, C, D, A, X(15), 22, 0x49b40821L); - /* Round 1 */ - R1(A, B, C, D, X(1), 5, 0xf61e2562L); - R1(D, A, B, C, X(6), 9, 0xc040b340L); - R1(C, D, A, B, X(11), 14, 0x265e5a51L); - R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL); - R1(A, B, C, D, X(5), 5, 0xd62f105dL); - R1(D, A, B, C, X(10), 9, 0x02441453L); - R1(C, D, A, B, X(15), 14, 0xd8a1e681L); - R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L); - R1(A, B, C, D, X(9), 5, 0x21e1cde6L); - R1(D, A, B, C, X(14), 9, 0xc33707d6L); - R1(C, D, A, B, X(3), 14, 0xf4d50d87L); - R1(B, C, D, A, X(8), 20, 0x455a14edL); - R1(A, B, C, D, X(13), 5, 0xa9e3e905L); - R1(D, A, B, C, X(2), 9, 0xfcefa3f8L); - R1(C, D, A, B, X(7), 14, 0x676f02d9L); - R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL); - /* Round 2 */ - R2(A, B, C, D, X(5), 4, 0xfffa3942L); - R2(D, A, B, C, X(8), 11, 0x8771f681L); - R2(C, D, A, B, X(11), 16, 0x6d9d6122L); - R2(B, C, D, A, X(14), 23, 0xfde5380cL); - R2(A, B, C, D, X(1), 4, 0xa4beea44L); - R2(D, A, B, C, X(4), 11, 0x4bdecfa9L); - R2(C, D, A, B, X(7), 16, 0xf6bb4b60L); - R2(B, C, D, A, X(10), 23, 0xbebfbc70L); - R2(A, B, C, D, X(13), 4, 0x289b7ec6L); - R2(D, A, B, C, X(0), 11, 0xeaa127faL); - R2(C, D, A, B, X(3), 16, 0xd4ef3085L); - R2(B, C, D, A, X(6), 23, 0x04881d05L); - R2(A, B, C, D, X(9), 4, 0xd9d4d039L); - R2(D, A, B, C, X(12), 11, 0xe6db99e5L); - R2(C, D, A, B, X(15), 16, 0x1fa27cf8L); - R2(B, C, D, A, X(2), 23, 0xc4ac5665L); - /* Round 3 */ - R3(A, B, C, D, X(0), 6, 0xf4292244L); - R3(D, A, B, C, X(7), 10, 0x432aff97L); - R3(C, D, A, B, X(14), 15, 0xab9423a7L); - R3(B, C, D, A, X(5), 21, 0xfc93a039L); - R3(A, B, C, D, X(12), 6, 0x655b59c3L); - R3(D, A, B, C, X(3), 10, 0x8f0ccc92L); - R3(C, D, A, B, X(10), 15, 0xffeff47dL); - R3(B, C, D, A, X(1), 21, 0x85845dd1L); - R3(A, B, C, D, X(8), 6, 0x6fa87e4fL); - R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L); - R3(C, D, A, B, X(6), 15, 0xa3014314L); - R3(B, C, D, A, X(13), 21, 0x4e0811a1L); - R3(A, B, C, D, X(4), 6, 0xf7537e82L); - R3(D, A, B, C, X(11), 10, 0xbd3af235L); - R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL); - R3(B, C, D, A, X(9), 21, 0xeb86d391L); - - A = c->A += A; - B = c->B += B; - C = c->C += C; - D = c->D += D; - } -} -#endif -/* crypto/md5/md5_one.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "md5.h" -// #include "crypto.h" - -#ifdef CHARSET_EBCDIC -# include "ebcdic.h" -#endif - -unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md) -{ - MD5_CTX c; - static unsigned char m[MD5_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - if (!MD5_Init(&c)) - return NULL; -#ifndef CHARSET_EBCDIC - MD5_Update(&c, d, n); -#else - { - char temp[1024]; - unsigned long chunk; - - while (n > 0) { - chunk = (n > sizeof(temp)) ? sizeof(temp) : n; - ebcdic2ascii(temp, d, chunk); - MD5_Update(&c, temp, chunk); - n -= chunk; - d += chunk; - } - } -#endif - MD5_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ - return (md); -} diff --git a/Sources/COpenSSL/md5_locl.h b/Sources/COpenSSL/md5_locl.h deleted file mode 100644 index 24b52983..00000000 --- a/Sources/COpenSSL/md5_locl.h +++ /dev/null @@ -1,133 +0,0 @@ -/* crypto/md5/md5_locl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "e_os2.h" -#include "md5.h" - -#ifndef MD5_LONG_LOG2 -# define MD5_LONG_LOG2 2 /* default to 32 bits */ -#endif - -#ifdef MD5_ASM -# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \ - defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) -# define md5_block_data_order md5_block_asm_data_order -# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) -# define md5_block_data_order md5_block_asm_data_order -# elif defined(__sparc) || defined(__sparc__) -# define md5_block_data_order md5_block_asm_data_order -# endif -#endif - -void md5_block_data_order(MD5_CTX *c, const void *p, size_t num); - -#define DATA_ORDER_IS_LITTLE_ENDIAN - -#define HASH_LONG MD5_LONG -#define HASH_CTX MD5_CTX -#define HASH_CBLOCK MD5_CBLOCK -#define HASH_UPDATE MD5_Update -#define HASH_TRANSFORM MD5_Transform -#define HASH_FINAL MD5_Final -#define HASH_MAKE_STRING(c,s) do { \ - unsigned long ll; \ - ll=(c)->A; (void)HOST_l2c(ll,(s)); \ - ll=(c)->B; (void)HOST_l2c(ll,(s)); \ - ll=(c)->C; (void)HOST_l2c(ll,(s)); \ - ll=(c)->D; (void)HOST_l2c(ll,(s)); \ - } while (0) -#define HASH_BLOCK_DATA_ORDER md5_block_data_order - -#include "md32_common.h" - -/*- -#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) -#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) -*/ - -/* - * As pointed out by Wei Dai , the above can be simplified - * to the code below. Wei attributes these optimizations to Peter Gutmann's - * SHS code, and he attributes it to Rich Schroeppel. - */ -#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) -#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) -#define H(b,c,d) ((b) ^ (c) ^ (d)) -#define I(b,c,d) (((~(d)) | (b)) ^ (c)) - -#define R0(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+F((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; };\ - -#define R1(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+G((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; - -#define R2(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+H((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; - -#define R3(a,b,c,d,k,s,t) { \ - a+=((k)+(t)+I((b),(c),(d))); \ - a=ROTATE(a,s); \ - a+=b; }; diff --git a/Sources/COpenSSL/md_rand.c b/Sources/COpenSSL/md_rand.c deleted file mode 100644 index 6e1adafe..00000000 --- a/Sources/COpenSSL/md_rand.c +++ /dev/null @@ -1,627 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/rand/md_rand.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#define OPENSSL_FIPSEVP - -#ifdef MD_RAND_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif - -#include -#include -#include - -#include "e_os.h" - -#include "crypto.h" -#include "rand.h" -#include "rand_lcl.h" - -#include "err.h" - -#ifdef BN_DEBUG -# define PREDICT -#endif - -/* #define PREDICT 1 */ - -#define STATE_SIZE 1023 -static size_t state_num = 0, state_index = 0; -static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH]; -static unsigned char md[MD_DIGEST_LENGTH]; -static long md_count[2] = { 0, 0 }; - -static double entropy = 0; -static int initialized = 0; - -static unsigned int crypto_lock_rand = 0; /* may be set only when a thread - * holds CRYPTO_LOCK_RAND (to - * prevent double locking) */ -/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ -/* valid iff crypto_lock_rand is set */ -static CRYPTO_THREADID locking_threadid; - -#ifdef PREDICT -int rand_predictable = 0; -#endif - -const char RAND_version[] = "RAND" OPENSSL_VERSION_PTEXT; - -static void ssleay_rand_cleanup(void); -static void ssleay_rand_seed(const void *buf, int num); -static void ssleay_rand_add(const void *buf, int num, double add_entropy); -static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num); -static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num); -static int ssleay_rand_status(void); - -RAND_METHOD rand_ssleay_meth = { - ssleay_rand_seed, - ssleay_rand_nopseudo_bytes, - ssleay_rand_cleanup, - ssleay_rand_add, - ssleay_rand_pseudo_bytes, - ssleay_rand_status -}; - -RAND_METHOD *RAND_SSLeay(void) -{ - return (&rand_ssleay_meth); -} - -static void ssleay_rand_cleanup(void) -{ - OPENSSL_cleanse(state, sizeof(state)); - state_num = 0; - state_index = 0; - OPENSSL_cleanse(md, MD_DIGEST_LENGTH); - md_count[0] = 0; - md_count[1] = 0; - entropy = 0; - initialized = 0; -} - -static void ssleay_rand_add(const void *buf, int num, double add) -{ - int i, j, k, st_idx; - long md_c[2]; - unsigned char local_md[MD_DIGEST_LENGTH]; - EVP_MD_CTX m; - int do_not_lock; - - if (!num) - return; - - /* - * (Based on the rand(3) manpage) - * - * The input is chopped up into units of 20 bytes (or less for - * the last block). Each of these blocks is run through the hash - * function as follows: The data passed to the hash function - * is the current 'md', the same number of bytes from the 'state' - * (the location determined by in incremented looping index) as - * the current 'block', the new key data 'block', and 'count' - * (which is incremented after each use). - * The result of this is kept in 'md' and also xored into the - * 'state' at the same locations that were used as input into the - * hash function. - */ - - /* check if we already have the lock */ - if (crypto_lock_rand) { - CRYPTO_THREADID cur; - CRYPTO_THREADID_current(&cur); - CRYPTO_r_lock(CRYPTO_LOCK_RAND2); - do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); - CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); - } else - do_not_lock = 0; - - if (!do_not_lock) - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - st_idx = state_index; - - /* - * use our own copies of the counters so that even if a concurrent thread - * seeds with exactly the same data and uses the same subarray there's - * _some_ difference - */ - md_c[0] = md_count[0]; - md_c[1] = md_count[1]; - - memcpy(local_md, md, sizeof(md)); - - /* state_index <= state_num <= STATE_SIZE */ - state_index += num; - if (state_index >= STATE_SIZE) { - state_index %= STATE_SIZE; - state_num = STATE_SIZE; - } else if (state_num < STATE_SIZE) { - if (state_index > state_num) - state_num = state_index; - } - /* state_index <= state_num <= STATE_SIZE */ - - /* - * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we - * will use now, but other threads may use them as well - */ - - md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0); - - if (!do_not_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - - EVP_MD_CTX_init(&m); - for (i = 0; i < num; i += MD_DIGEST_LENGTH) { - j = (num - i); - j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j; - - if (!MD_Init(&m) || - !MD_Update(&m, local_md, MD_DIGEST_LENGTH)) - goto err; - k = (st_idx + j) - STATE_SIZE; - if (k > 0) { - if (!MD_Update(&m, &(state[st_idx]), j - k) || - !MD_Update(&m, &(state[0]), k)) - goto err; - } else - if (!MD_Update(&m, &(state[st_idx]), j)) - goto err; - - /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ - if (!MD_Update(&m, buf, j)) - goto err; - /* - * We know that line may cause programs such as purify and valgrind - * to complain about use of uninitialized data. The problem is not, - * it's with the caller. Removing that line will make sure you get - * really bad randomness and thereby other problems such as very - * insecure keys. - */ - - if (!MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)) || - !MD_Final(&m, local_md)) - goto err; - md_c[1]++; - - buf = (const char *)buf + j; - - for (k = 0; k < j; k++) { - /* - * Parallel threads may interfere with this, but always each byte - * of the new state is the XOR of some previous value of its and - * local_md (itermediate values may be lost). Alway using locking - * could hurt performance more than necessary given that - * conflicts occur only when the total seeding is longer than the - * random state. - */ - state[st_idx++] ^= local_md[k]; - if (st_idx >= STATE_SIZE) - st_idx = 0; - } - } - - if (!do_not_lock) - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - /* - * Don't just copy back local_md into md -- this could mean that other - * thread's seeding remains without effect (except for the incremented - * counter). By XORing it we keep at least as much entropy as fits into - * md. - */ - for (k = 0; k < (int)sizeof(md); k++) { - md[k] ^= local_md[k]; - } - if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */ - entropy += add; - if (!do_not_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - -#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) - assert(md_c[1] == md_count[1]); -#endif - - err: - EVP_MD_CTX_cleanup(&m); -} - -static void ssleay_rand_seed(const void *buf, int num) -{ - ssleay_rand_add(buf, num, (double)num); -} - -int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) -{ - static volatile int stirred_pool = 0; - int i, j, k; - size_t num_ceil, st_idx, st_num; - long md_c[2]; - unsigned char local_md[MD_DIGEST_LENGTH]; - EVP_MD_CTX m; -#ifndef GETPID_IS_MEANINGLESS - pid_t curr_pid = getpid(); -#endif - int do_stir_pool = 0; - -#ifdef PREDICT - if (rand_predictable) { - static unsigned char val = 0; - - for (i = 0; i < num; i++) - buf[i] = val++; - return (1); - } -#endif - - if (num <= 0) - return 1; - - EVP_MD_CTX_init(&m); - /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ - num_ceil = - (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2); - - /* - * (Based on the rand(3) manpage:) - * - * For each group of 10 bytes (or less), we do the following: - * - * Input into the hash function the local 'md' (which is initialized from - * the global 'md' before any bytes are generated), the bytes that are to - * be overwritten by the random bytes, and bytes from the 'state' - * (incrementing looping index). From this digest output (which is kept - * in 'md'), the top (up to) 10 bytes are returned to the caller and the - * bottom 10 bytes are xored into the 'state'. - * - * Finally, after we have finished 'num' random bytes for the - * caller, 'count' (which is incremented) and the local and global 'md' - * are fed into the hash function and the results are kept in the - * global 'md'. - */ - if (lock) - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - - /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ - CRYPTO_w_lock(CRYPTO_LOCK_RAND2); - CRYPTO_THREADID_current(&locking_threadid); - CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); - crypto_lock_rand = 1; - - if (!initialized) { - RAND_poll(); - initialized = (entropy >= ENTROPY_NEEDED); - } - - if (!stirred_pool) - do_stir_pool = 1; - - if (!initialized) { - /* - * If the PRNG state is not yet unpredictable, then seeing the PRNG - * output may help attackers to determine the new state; thus we have - * to decrease the entropy estimate. Once we've had enough initial - * seeding we don't bother to adjust the entropy count, though, - * because we're not ambitious to provide *information-theoretic* - * randomness. NOTE: This approach fails if the program forks before - * we have enough entropy. Entropy should be collected in a separate - * input pool and be transferred to the output pool only when the - * entropy limit has been reached. - */ - entropy -= num; - if (entropy < 0) - entropy = 0; - } - - if (do_stir_pool) { - /* - * In the output function only half of 'md' remains secret, so we - * better make sure that the required entropy gets 'evenly - * distributed' through 'state', our randomness pool. The input - * function (ssleay_rand_add) chains all of 'md', which makes it more - * suitable for this purpose. - */ - - int n = STATE_SIZE; /* so that the complete pool gets accessed */ - while (n > 0) { -#if MD_DIGEST_LENGTH > 20 -# error "Please adjust DUMMY_SEED." -#endif -#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */ - /* - * Note that the seed does not matter, it's just that - * ssleay_rand_add expects to have something to hash. - */ - ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0); - n -= MD_DIGEST_LENGTH; - } - if (initialized) - stirred_pool = 1; - } - - st_idx = state_index; - st_num = state_num; - md_c[0] = md_count[0]; - md_c[1] = md_count[1]; - memcpy(local_md, md, sizeof(md)); - - state_index += num_ceil; - if (state_index > state_num) - state_index %= state_num; - - /* - * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now - * ours (but other threads may use them too) - */ - - md_count[0] += 1; - - /* before unlocking, we must clear 'crypto_lock_rand' */ - crypto_lock_rand = 0; - if (lock) - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - - while (num > 0) { - /* num_ceil -= MD_DIGEST_LENGTH/2 */ - j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num; - num -= j; - if (!MD_Init(&m)) - goto err; -#ifndef GETPID_IS_MEANINGLESS - if (curr_pid) { /* just in the first iteration to save time */ - if (!MD_Update(&m, (unsigned char *)&curr_pid, sizeof(curr_pid))) - goto err; - curr_pid = 0; - } -#endif - if (!MD_Update(&m, local_md, MD_DIGEST_LENGTH) || - !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c))) - goto err; - -#ifndef PURIFY /* purify complains */ - /* - * The following line uses the supplied buffer as a small source of - * entropy: since this buffer is often uninitialised it may cause - * programs such as purify or valgrind to complain. So for those - * builds it is not used: the removal of such a small source of - * entropy has negligible impact on security. - */ - if (!MD_Update(&m, buf, j)) - goto err; -#endif - - k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num; - if (k > 0) { - if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k) || - !MD_Update(&m, &(state[0]), k)) - goto err; - } else { - if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2)) - goto err; - } - if (!MD_Final(&m, local_md)) - goto err; - - for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) { - /* may compete with other threads */ - state[st_idx++] ^= local_md[i]; - if (st_idx >= st_num) - st_idx = 0; - if (i < j) - *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2]; - } - } - - if (!MD_Init(&m) || - !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)) || - !MD_Update(&m, local_md, MD_DIGEST_LENGTH)) - goto err; - if (lock) - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - if (!MD_Update(&m, md, MD_DIGEST_LENGTH) || - !MD_Final(&m, md)) { - if (lock) - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - goto err; - } - if (lock) - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - - EVP_MD_CTX_cleanup(&m); - if (initialized) - return (1); - else if (pseudo) - return 0; - else { - RANDerr(RAND_F_SSLEAY_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED); - ERR_add_error_data(1, "You need to read the OpenSSL FAQ, " - "http://www.openssl.org/support/faq.html"); - return (0); - } - - err: - EVP_MD_CTX_cleanup(&m); - return (0); -} - -/* - * Returns ssleay_rand_bytes(), enforcing a reseeding from the - * system entropy sources using RAND_poll() before generating -`* the random bytes. - */ - -int ssleay_rand_bytes_from_system(unsigned char *buf, int num) -{ - initialized = 0; - return ssleay_rand_bytes(buf, num, 0, 0); -} - -static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num) -{ - return ssleay_rand_bytes(buf, num, 0, 1); -} - -/* - * pseudo-random bytes that are guaranteed to be unique but not unpredictable - */ -static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) -{ - return ssleay_rand_bytes(buf, num, 1, 1); -} - -static int ssleay_rand_status(void) -{ - CRYPTO_THREADID cur; - int ret; - int do_not_lock; - - CRYPTO_THREADID_current(&cur); - /* - * check if we already have the lock (could happen if a RAND_poll() - * implementation calls RAND_status()) - */ - if (crypto_lock_rand) { - CRYPTO_r_lock(CRYPTO_LOCK_RAND2); - do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); - CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); - } else - do_not_lock = 0; - - if (!do_not_lock) { - CRYPTO_w_lock(CRYPTO_LOCK_RAND); - - /* - * prevent ssleay_rand_bytes() from trying to obtain the lock again - */ - CRYPTO_w_lock(CRYPTO_LOCK_RAND2); - CRYPTO_THREADID_cpy(&locking_threadid, &cur); - CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); - crypto_lock_rand = 1; - } - - if (!initialized) { - RAND_poll(); - initialized = (entropy >= ENTROPY_NEEDED); - } - - ret = initialized; - - if (!do_not_lock) { - /* before unlocking, we must clear 'crypto_lock_rand' */ - crypto_lock_rand = 0; - - CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - } - - return ret; -} diff --git a/Sources/COpenSSL/mdc2.h b/Sources/COpenSSL/mdc2.h deleted file mode 100644 index 8b6658ae..00000000 --- a/Sources/COpenSSL/mdc2.h +++ /dev/null @@ -1,94 +0,0 @@ -/* crypto/mdc2/mdc2.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_MDC2_H -# define HEADER_MDC2_H - -# include "des.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef OPENSSL_NO_MDC2 -# error MDC2 is disabled. -# endif - -# define MDC2_BLOCK 8 -# define MDC2_DIGEST_LENGTH 16 - -typedef struct mdc2_ctx_st { - unsigned int num; - unsigned char data[MDC2_BLOCK]; - DES_cblock h, hh; - int pad_type; /* either 1 or 2, default 1 */ -} MDC2_CTX; - -# ifdef OPENSSL_FIPS -int private_MDC2_Init(MDC2_CTX *c); -# endif -int MDC2_Init(MDC2_CTX *c); -int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); -int MDC2_Final(unsigned char *md, MDC2_CTX *c); -unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/mdc2_one.c b/Sources/COpenSSL/mdc2_one.c deleted file mode 100644 index 09c5afaf..00000000 --- a/Sources/COpenSSL/mdc2_one.c +++ /dev/null @@ -1,76 +0,0 @@ -/* crypto/mdc2/mdc2_one.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "mdc2.h" - -unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md) -{ - MDC2_CTX c; - static unsigned char m[MDC2_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - if (!MDC2_Init(&c)) - return NULL; - MDC2_Update(&c, d, n); - MDC2_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ - return (md); -} diff --git a/Sources/COpenSSL/mdc2dgst.c b/Sources/COpenSSL/mdc2dgst.c deleted file mode 100644 index 6fdf2657..00000000 --- a/Sources/COpenSSL/mdc2dgst.c +++ /dev/null @@ -1,196 +0,0 @@ -/* crypto/mdc2/mdc2dgst.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include "crypto.h" -#include "des.h" -#include "mdc2.h" - -#undef c2l -#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ - l|=((DES_LONG)(*((c)++)))<< 8L, \ - l|=((DES_LONG)(*((c)++)))<<16L, \ - l|=((DES_LONG)(*((c)++)))<<24L) - -#undef l2c -#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24L)&0xff)) - -static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); -fips_md_init(MDC2) -{ - c->num = 0; - c->pad_type = 1; - memset(&(c->h[0]), 0x52, MDC2_BLOCK); - memset(&(c->hh[0]), 0x25, MDC2_BLOCK); - return 1; -} - -int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len) -{ - size_t i, j; - - i = c->num; - if (i != 0) { - if (len < MDC2_BLOCK - i) { - /* partial block */ - memcpy(&(c->data[i]), in, len); - c->num += (int)len; - return 1; - } else { - /* filled one */ - j = MDC2_BLOCK - i; - memcpy(&(c->data[i]), in, j); - len -= j; - in += j; - c->num = 0; - mdc2_body(c, &(c->data[0]), MDC2_BLOCK); - } - } - i = len & ~((size_t)MDC2_BLOCK - 1); - if (i > 0) - mdc2_body(c, in, i); - j = len - i; - if (j > 0) { - memcpy(&(c->data[0]), &(in[i]), j); - c->num = (int)j; - } - return 1; -} - -static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len) -{ - register DES_LONG tin0, tin1; - register DES_LONG ttin0, ttin1; - DES_LONG d[2], dd[2]; - DES_key_schedule k; - unsigned char *p; - size_t i; - - for (i = 0; i < len; i += 8) { - c2l(in, tin0); - d[0] = dd[0] = tin0; - c2l(in, tin1); - d[1] = dd[1] = tin1; - c->h[0] = (c->h[0] & 0x9f) | 0x40; - c->hh[0] = (c->hh[0] & 0x9f) | 0x20; - - DES_set_odd_parity(&c->h); - DES_set_key_unchecked(&c->h, &k); - DES_encrypt1(d, &k, 1); - - DES_set_odd_parity(&c->hh); - DES_set_key_unchecked(&c->hh, &k); - DES_encrypt1(dd, &k, 1); - - ttin0 = tin0 ^ dd[0]; - ttin1 = tin1 ^ dd[1]; - tin0 ^= d[0]; - tin1 ^= d[1]; - - p = c->h; - l2c(tin0, p); - l2c(ttin1, p); - p = c->hh; - l2c(ttin0, p); - l2c(tin1, p); - } -} - -int MDC2_Final(unsigned char *md, MDC2_CTX *c) -{ - unsigned int i; - int j; - - i = c->num; - j = c->pad_type; - if ((i > 0) || (j == 2)) { - if (j == 2) - c->data[i++] = 0x80; - memset(&(c->data[i]), 0, MDC2_BLOCK - i); - mdc2_body(c, c->data, MDC2_BLOCK); - } - memcpy(md, (char *)c->h, MDC2_BLOCK); - memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK); - return 1; -} - -#undef TEST - -#ifdef TEST -main() -{ - unsigned char md[MDC2_DIGEST_LENGTH]; - int i; - MDC2_CTX c; - static char *text = "Now is the time for all "; - - MDC2_Init(&c); - MDC2_Update(&c, text, strlen(text)); - MDC2_Final(&(md[0]), &c); - - for (i = 0; i < MDC2_DIGEST_LENGTH; i++) - printf("%02X", md[i]); - printf("\n"); -} - -#endif diff --git a/Sources/COpenSSL/mem.c b/Sources/COpenSSL/mem.c deleted file mode 100644 index 112b21f9..00000000 --- a/Sources/COpenSSL/mem.c +++ /dev/null @@ -1,459 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/mem.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "crypto.h" -#include "cryptlib.h" - -static int allow_customize = 1; /* we provide flexible functions for */ -static int allow_customize_debug = 1; /* exchanging memory-related functions - * at run-time, but this must be done - * before any blocks are actually - * allocated; or we'll run into huge - * problems when malloc/free pairs - * don't match etc. */ - -/* - * the following pointers may be changed as long as 'allow_customize' is set - */ - -static void *(*malloc_func) (size_t) = malloc; -static void *default_malloc_ex(size_t num, const char *file, int line) -{ - return malloc_func(num); -} - -static void *(*malloc_ex_func) (size_t, const char *file, int line) - = default_malloc_ex; - -#ifdef OPENSSL_SYS_VMS -# if __INITIAL_POINTER_SIZE == 64 -# define realloc _realloc64 -# elif __INITIAL_POINTER_SIZE == 32 -# define realloc _realloc32 -# endif -#endif - -static void *(*realloc_func) (void *, size_t) = realloc; -static void *default_realloc_ex(void *str, size_t num, - const char *file, int line) -{ - return realloc_func(str, num); -} - -static void *(*realloc_ex_func) (void *, size_t, const char *file, int line) - = default_realloc_ex; - -#ifdef OPENSSL_SYS_VMS - static void (*free_func) (__void_ptr64) = free; -#else - static void (*free_func) (void *) = free; -#endif - -static void *(*malloc_locked_func) (size_t) = malloc; -static void *default_malloc_locked_ex(size_t num, const char *file, int line) -{ - return malloc_locked_func(num); -} - -static void *(*malloc_locked_ex_func) (size_t, const char *file, int line) - = default_malloc_locked_ex; - -#ifdef OPENSSL_SYS_VMS - static void (*free_locked_func) (__void_ptr64) = free; -#else - static void (*free_locked_func) (void *) = free; -#endif - -/* may be changed as long as 'allow_customize_debug' is set */ -/* XXX use correct function pointer types */ -#ifdef CRYPTO_MDEBUG -/* use default functions from mem_dbg.c */ -static void (*malloc_debug_func) (void *, int, const char *, int, int) - = CRYPTO_dbg_malloc; -static void (*realloc_debug_func) (void *, void *, int, const char *, int, - int) - = CRYPTO_dbg_realloc; -static void (*free_debug_func) (void *, int) = CRYPTO_dbg_free; -static void (*set_debug_options_func) (long) = CRYPTO_dbg_set_options; -static long (*get_debug_options_func) (void) = CRYPTO_dbg_get_options; -#else -/* - * applications can use CRYPTO_malloc_debug_init() to select above case at - * run-time - */ -static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL; -static void (*realloc_debug_func) (void *, void *, int, const char *, int, - int) - = NULL; -static void (*free_debug_func) (void *, int) = NULL; -static void (*set_debug_options_func) (long) = NULL; -static long (*get_debug_options_func) (void) = NULL; -#endif - -int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), - void (*f) (void *)) -{ - if (!allow_customize) - return 0; - if ((m == 0) || (r == 0) || (f == 0)) - return 0; - /* Dummy call just to ensure OPENSSL_init() gets linked in */ - OPENSSL_init(); - malloc_func = m; - malloc_ex_func = default_malloc_ex; - realloc_func = r; - realloc_ex_func = default_realloc_ex; - free_func = f; - malloc_locked_func = m; - malloc_locked_ex_func = default_malloc_locked_ex; - free_locked_func = f; - return 1; -} - -int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), - void *(*r) (void *, size_t, const char *, - int), void (*f) (void *)) -{ - if (!allow_customize) - return 0; - if ((m == 0) || (r == 0) || (f == 0)) - return 0; - malloc_func = 0; - malloc_ex_func = m; - realloc_func = 0; - realloc_ex_func = r; - free_func = f; - malloc_locked_func = 0; - malloc_locked_ex_func = m; - free_locked_func = f; - return 1; -} - -int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *)) -{ - if (!allow_customize) - return 0; - if ((m == NULL) || (f == NULL)) - return 0; - malloc_locked_func = m; - malloc_locked_ex_func = default_malloc_locked_ex; - free_locked_func = f; - return 1; -} - -int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), - void (*f) (void *)) -{ - if (!allow_customize) - return 0; - if ((m == NULL) || (f == NULL)) - return 0; - malloc_locked_func = 0; - malloc_locked_ex_func = m; - free_func = f; - return 1; -} - -int CRYPTO_set_mem_debug_functions(void (*m) - (void *, int, const char *, int, int), - void (*r) (void *, void *, int, - const char *, int, int), - void (*f) (void *, int), void (*so) (long), - long (*go) (void)) -{ - if (!allow_customize_debug) - return 0; - OPENSSL_init(); - malloc_debug_func = m; - realloc_debug_func = r; - free_debug_func = f; - set_debug_options_func = so; - get_debug_options_func = go; - return 1; -} - -void CRYPTO_get_mem_functions(void *(**m) (size_t), - void *(**r) (void *, size_t), - void (**f) (void *)) -{ - if (m != NULL) - *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0; - if (r != NULL) - *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0; - if (f != NULL) - *f = free_func; -} - -void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), - void *(**r) (void *, size_t, const char *, - int), void (**f) (void *)) -{ - if (m != NULL) - *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0; - if (r != NULL) - *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0; - if (f != NULL) - *f = free_func; -} - -void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), - void (**f) (void *)) -{ - if (m != NULL) - *m = (malloc_locked_ex_func == default_malloc_locked_ex) ? - malloc_locked_func : 0; - if (f != NULL) - *f = free_locked_func; -} - -void CRYPTO_get_locked_mem_ex_functions(void - *(**m) (size_t, const char *, int), - void (**f) (void *)) -{ - if (m != NULL) - *m = (malloc_locked_ex_func != default_malloc_locked_ex) ? - malloc_locked_ex_func : 0; - if (f != NULL) - *f = free_locked_func; -} - -void CRYPTO_get_mem_debug_functions(void (**m) - (void *, int, const char *, int, int), - void (**r) (void *, void *, int, - const char *, int, int), - void (**f) (void *, int), - void (**so) (long), long (**go) (void)) -{ - if (m != NULL) - *m = malloc_debug_func; - if (r != NULL) - *r = realloc_debug_func; - if (f != NULL) - *f = free_debug_func; - if (so != NULL) - *so = set_debug_options_func; - if (go != NULL) - *go = get_debug_options_func; -} - -void *CRYPTO_malloc_locked(int num, const char *file, int line) -{ - void *ret = NULL; - - if (num <= 0) - return NULL; - - if (allow_customize) - allow_customize = 0; - if (malloc_debug_func != NULL) { - if (allow_customize_debug) - allow_customize_debug = 0; - malloc_debug_func(NULL, num, file, line, 0); - } - ret = malloc_locked_ex_func(num, file, line); -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); -#endif - if (malloc_debug_func != NULL) - malloc_debug_func(ret, num, file, line, 1); - - return ret; -} - -void CRYPTO_free_locked(void *str) -{ - if (free_debug_func != NULL) - free_debug_func(str, 0); -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); -#endif - free_locked_func(str); - if (free_debug_func != NULL) - free_debug_func(NULL, 1); -} - -void *CRYPTO_malloc(int num, const char *file, int line) -{ - void *ret = NULL; - - if (num <= 0) - return NULL; - - if (allow_customize) - allow_customize = 0; - if (malloc_debug_func != NULL) { - if (allow_customize_debug) - allow_customize_debug = 0; - malloc_debug_func(NULL, num, file, line, 0); - } - ret = malloc_ex_func(num, file, line); -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); -#endif - if (malloc_debug_func != NULL) - malloc_debug_func(ret, num, file, line, 1); - - return ret; -} - -char *CRYPTO_strdup(const char *str, const char *file, int line) -{ - char *ret = CRYPTO_malloc(strlen(str) + 1, file, line); - - if (ret == NULL) - return NULL; - - strcpy(ret, str); - return ret; -} - -void *CRYPTO_realloc(void *str, int num, const char *file, int line) -{ - void *ret = NULL; - - if (str == NULL) - return CRYPTO_malloc(num, file, line); - - if (num <= 0) - return NULL; - - if (realloc_debug_func != NULL) - realloc_debug_func(str, NULL, num, file, line, 0); - ret = realloc_ex_func(str, num, file, line); -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, - ret, num); -#endif - if (realloc_debug_func != NULL) - realloc_debug_func(str, ret, num, file, line, 1); - - return ret; -} - -void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file, - int line) -{ - void *ret = NULL; - - if (str == NULL) - return CRYPTO_malloc(num, file, line); - - if (num <= 0) - return NULL; - - /* - * We don't support shrinking the buffer. Note the memcpy that copies - * |old_len| bytes to the new buffer, below. - */ - if (num < old_len) - return NULL; - - if (realloc_debug_func != NULL) - realloc_debug_func(str, NULL, num, file, line, 0); - ret = malloc_ex_func(num, file, line); - if (ret) { - memcpy(ret, str, old_len); - OPENSSL_cleanse(str, old_len); - free_func(str); - } -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, - "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", - str, ret, num); -#endif - if (realloc_debug_func != NULL) - realloc_debug_func(str, ret, num, file, line, 1); - - return ret; -} - -void CRYPTO_free(void *str) -{ - if (free_debug_func != NULL) - free_debug_func(str, 0); -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); -#endif - free_func(str); - if (free_debug_func != NULL) - free_debug_func(NULL, 1); -} - -void *CRYPTO_remalloc(void *a, int num, const char *file, int line) -{ - if (a != NULL) - OPENSSL_free(a); - a = (char *)OPENSSL_malloc(num); - return (a); -} - -void CRYPTO_set_mem_debug_options(long bits) -{ - if (set_debug_options_func != NULL) - set_debug_options_func(bits); -} - -long CRYPTO_get_mem_debug_options(void) -{ - if (get_debug_options_func != NULL) - return get_debug_options_func(); - return 0; -} diff --git a/Sources/COpenSSL/mem_.c b/Sources/COpenSSL/mem_.c deleted file mode 100644 index d09b787a..00000000 --- a/Sources/COpenSSL/mem_.c +++ /dev/null @@ -1,912 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/mem_clr.c */ -/* - * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "crypto.h" - -/* - * Pointer to memset is volatile so that compiler must de-reference - * the pointer and can't assume that it points to any function in - * particular (such as memset, which it then might further "optimize") - */ -typedef void *(*memset_t)(void *,int,size_t); - -static volatile memset_t memset_func = memset; - -void OPENSSL_cleanse(void *ptr, size_t len) -{ - memset_func(ptr, 0, len); -} -/* crypto/mem_dbg.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include "cryptlib.h" -// #include "crypto.h" -#include "buffer.h" -#include "bio.h" -#include "lhash.h" - -static int mh_mode = CRYPTO_MEM_CHECK_OFF; -/* - * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when - * the application asks for it (usually after library initialisation for - * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only - * temporarily when the library thinks that certain allocations should not be - * checked (e.g. the data structures used for memory checking). It is not - * suitable as an initial state: the library will unexpectedly enable memory - * checking when it executes one of those sections that want to disable - * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes - * no sense whatsoever. - */ - -static unsigned long order = 0; /* number of memory requests */ - -DECLARE_LHASH_OF(MEM); -static LHASH_OF(MEM) *mh = NULL; /* hash-table of memory requests (address as - * key); access requires MALLOC2 lock */ - -typedef struct app_mem_info_st -/*- - * For application-defined information (static C-string `info') - * to be displayed in memory leak list. - * Each thread has its own stack. For applications, there is - * CRYPTO_push_info("...") to push an entry, - * CRYPTO_pop_info() to pop an entry, - * CRYPTO_remove_all_info() to pop all entries. - */ -{ - CRYPTO_THREADID threadid; - const char *file; - int line; - const char *info; - struct app_mem_info_st *next; /* tail of thread's stack */ - int references; -} APP_INFO; - -static void app_info_free(APP_INFO *); - -DECLARE_LHASH_OF(APP_INFO); -static LHASH_OF(APP_INFO) *amih = NULL; /* hash-table with those - * app_mem_info_st's that are at the - * top of their thread's stack (with - * `thread' as key); access requires - * MALLOC2 lock */ - -typedef struct mem_st -/* memory-block description */ -{ - void *addr; - int num; - const char *file; - int line; - CRYPTO_THREADID threadid; - unsigned long order; - time_t time; - APP_INFO *app_info; -} MEM; - -static long options = /* extra information to be recorded */ -#if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL) - V_CRYPTO_MDEBUG_TIME | -#endif -#if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL) - V_CRYPTO_MDEBUG_THREAD | -#endif - 0; - -static unsigned int num_disable = 0; /* num_disable > 0 iff mh_mode == - * CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */ - -/* - * Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this - * case (by the thread named in disabling_thread). - */ -static CRYPTO_THREADID disabling_threadid; - -static void app_info_free(APP_INFO *inf) -{ - if (--(inf->references) <= 0) { - if (inf->next != NULL) { - app_info_free(inf->next); - } - OPENSSL_free(inf); - } -} - -int CRYPTO_mem_ctrl(int mode) -{ - int ret = mh_mode; - - CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); - switch (mode) { - /* - * for applications (not to be called while multiple threads use the - * library): - */ - case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */ - mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE; - num_disable = 0; - break; - case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */ - mh_mode = 0; - num_disable = 0; /* should be true *before* MemCheck_stop is - * used, or there'll be a lot of confusion */ - break; - - /* switch off temporarily (for library-internal use): */ - case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - CRYPTO_THREADID cur; - CRYPTO_THREADID_current(&cur); - /* see if we don't have the MALLOC2 lock already */ - if (!num_disable - || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) { - /* - * Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed - * while we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock - * if somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot - * release it because we block entry to this function). Give - * them a chance, first, and then claim the locks in - * appropriate order (long-time lock first). - */ - CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); - /* - * Note that after we have waited for CRYPTO_LOCK_MALLOC2 and - * CRYPTO_LOCK_MALLOC, we'll still be in the right "case" and - * "if" branch because MemCheck_start and MemCheck_stop may - * never be used while there are multiple OpenSSL threads. - */ - CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); - CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); - mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; - CRYPTO_THREADID_cpy(&disabling_threadid, &cur); - } - num_disable++; - } - break; - case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */ - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - if (num_disable) { /* always true, or something is going wrong */ - num_disable--; - if (num_disable == 0) { - mh_mode |= CRYPTO_MEM_CHECK_ENABLE; - CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); - } - } - } - break; - - default: - break; - } - CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); - return (ret); -} - -int CRYPTO_is_mem_check_on(void) -{ - int ret = 0; - - if (mh_mode & CRYPTO_MEM_CHECK_ON) { - CRYPTO_THREADID cur; - CRYPTO_THREADID_current(&cur); - CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); - - ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) - || CRYPTO_THREADID_cmp(&disabling_threadid, &cur); - - CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC); - } - return (ret); -} - -void CRYPTO_dbg_set_options(long bits) -{ - options = bits; -} - -long CRYPTO_dbg_get_options(void) -{ - return options; -} - -static int mem_cmp(const MEM *a, const MEM *b) -{ -#ifdef _WIN64 - const char *ap = (const char *)a->addr, *bp = (const char *)b->addr; - if (ap == bp) - return 0; - else if (ap > bp) - return 1; - else - return -1; -#else - return (const char *)a->addr - (const char *)b->addr; -#endif -} - -static IMPLEMENT_LHASH_COMP_FN(mem, MEM) - -static unsigned long mem_hash(const MEM *a) -{ - unsigned long ret; - - ret = (unsigned long)a->addr; - - ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251; - return (ret); -} - -static IMPLEMENT_LHASH_HASH_FN(mem, MEM) - -/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */ -static int app_info_cmp(const void *a_void, const void *b_void) -{ - return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid, - &((const APP_INFO *)b_void)->threadid); -} - -static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO) - -static unsigned long app_info_hash(const APP_INFO *a) -{ - unsigned long ret; - - ret = CRYPTO_THREADID_hash(&a->threadid); - /* This is left in as a "who am I to question legacy?" measure */ - ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251; - return (ret); -} - -static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO) - -static APP_INFO *pop_info(void) -{ - APP_INFO tmp; - APP_INFO *ret = NULL; - - if (amih != NULL) { - CRYPTO_THREADID_current(&tmp.threadid); - if ((ret = lh_APP_INFO_delete(amih, &tmp)) != NULL) { - APP_INFO *next = ret->next; - - if (next != NULL) { - next->references++; - (void)lh_APP_INFO_insert(amih, next); - } -#ifdef LEVITTE_DEBUG_MEM - if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid)) { - fprintf(stderr, - "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n", - CRYPTO_THREADID_hash(&ret->threadid), - CRYPTO_THREADID_hash(&tmp.threadid)); - abort(); - } -#endif - if (--(ret->references) <= 0) { - ret->next = NULL; - if (next != NULL) - next->references--; - OPENSSL_free(ret); - } - } - } - return (ret); -} - -int CRYPTO_push_info_(const char *info, const char *file, int line) -{ - APP_INFO *ami, *amim; - int ret = 0; - - if (is_MemCheck_on()) { - MemCheck_off(); /* obtain MALLOC2 lock */ - - if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) { - ret = 0; - goto err; - } - if (amih == NULL) { - if ((amih = lh_APP_INFO_new()) == NULL) { - OPENSSL_free(ami); - ret = 0; - goto err; - } - } - - CRYPTO_THREADID_current(&ami->threadid); - ami->file = file; - ami->line = line; - ami->info = info; - ami->references = 1; - ami->next = NULL; - - if ((amim = lh_APP_INFO_insert(amih, ami)) != NULL) { -#ifdef LEVITTE_DEBUG_MEM - if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid)) { - fprintf(stderr, - "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n", - CRYPTO_THREADID_hash(&amim->threadid), - CRYPTO_THREADID_hash(&ami->threadid)); - abort(); - } -#endif - ami->next = amim; - } - err: - MemCheck_on(); /* release MALLOC2 lock */ - } - - return (ret); -} - -int CRYPTO_pop_info(void) -{ - int ret = 0; - - if (is_MemCheck_on()) { /* _must_ be true, or something went severely - * wrong */ - MemCheck_off(); /* obtain MALLOC2 lock */ - - ret = (pop_info() != NULL); - - MemCheck_on(); /* release MALLOC2 lock */ - } - return (ret); -} - -int CRYPTO_remove_all_info(void) -{ - int ret = 0; - - if (is_MemCheck_on()) { /* _must_ be true */ - MemCheck_off(); /* obtain MALLOC2 lock */ - - while (pop_info() != NULL) - ret++; - - MemCheck_on(); /* release MALLOC2 lock */ - } - return (ret); -} - -static unsigned long break_order_num = 0; -void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, - int before_p) -{ - MEM *m, *mm; - APP_INFO tmp, *amim; - - switch (before_p & 127) { - case 0: - break; - case 1: - if (addr == NULL) - break; - - if (is_MemCheck_on()) { - MemCheck_off(); /* make sure we hold MALLOC2 lock */ - if ((m = (MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) { - OPENSSL_free(addr); - MemCheck_on(); /* release MALLOC2 lock if num_disabled drops - * to 0 */ - return; - } - if (mh == NULL) { - if ((mh = lh_MEM_new()) == NULL) { - OPENSSL_free(addr); - OPENSSL_free(m); - addr = NULL; - goto err; - } - } - - m->addr = addr; - m->file = file; - m->line = line; - m->num = num; - if (options & V_CRYPTO_MDEBUG_THREAD) - CRYPTO_THREADID_current(&m->threadid); - else - memset(&m->threadid, 0, sizeof(m->threadid)); - - if (order == break_order_num) { - /* BREAK HERE */ - m->order = order; - } - m->order = order++; -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n", - m->order, (before_p & 128) ? '*' : '+', m->addr, m->num); -#endif - if (options & V_CRYPTO_MDEBUG_TIME) - m->time = time(NULL); - else - m->time = 0; - - CRYPTO_THREADID_current(&tmp.threadid); - m->app_info = NULL; - if (amih != NULL - && (amim = lh_APP_INFO_retrieve(amih, &tmp)) != NULL) { - m->app_info = amim; - amim->references++; - } - - if ((mm = lh_MEM_insert(mh, m)) != NULL) { - /* Not good, but don't sweat it */ - if (mm->app_info != NULL) { - mm->app_info->references--; - } - OPENSSL_free(mm); - } - err: - MemCheck_on(); /* release MALLOC2 lock if num_disabled drops - * to 0 */ - } - break; - } - return; -} - -void CRYPTO_dbg_free(void *addr, int before_p) -{ - MEM m, *mp; - - switch (before_p) { - case 0: - if (addr == NULL) - break; - - if (is_MemCheck_on() && (mh != NULL)) { - MemCheck_off(); /* make sure we hold MALLOC2 lock */ - - m.addr = addr; - mp = lh_MEM_delete(mh, &m); - if (mp != NULL) { -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n", - mp->order, mp->addr, mp->num); -#endif - if (mp->app_info != NULL) - app_info_free(mp->app_info); - OPENSSL_free(mp); - } - - MemCheck_on(); /* release MALLOC2 lock if num_disabled drops - * to 0 */ - } - break; - case 1: - break; - } -} - -void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, - const char *file, int line, int before_p) -{ - MEM m, *mp; - -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, - "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n", - addr1, addr2, num, file, line, before_p); -#endif - - switch (before_p) { - case 0: - break; - case 1: - if (addr2 == NULL) - break; - - if (addr1 == NULL) { - CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p); - break; - } - - if (is_MemCheck_on()) { - MemCheck_off(); /* make sure we hold MALLOC2 lock */ - - m.addr = addr1; - mp = lh_MEM_delete(mh, &m); - if (mp != NULL) { -#ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, - "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n", - mp->order, mp->addr, mp->num, addr2, num); -#endif - mp->addr = addr2; - mp->num = num; - (void)lh_MEM_insert(mh, mp); - } - - MemCheck_on(); /* release MALLOC2 lock if num_disabled drops - * to 0 */ - } - break; - } - return; -} - -typedef struct mem_leak_st { - BIO *bio; - int chunks; - long bytes; -} MEM_LEAK; - -static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l) -{ - char buf[1024]; - char *bufp = buf; - APP_INFO *amip; - int ami_cnt; - struct tm *lcl = NULL; - struct tm result = {0}; - CRYPTO_THREADID ti; - -#define BUF_REMAIN (sizeof(buf) - (size_t)(bufp - buf)) - - if (m->addr == (char *)l->bio) - return; - - if (options & V_CRYPTO_MDEBUG_TIME) { -# if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && \ - !defined(OPENSSL_SYS_OS2) && !defined(OPENSSL_SYS_SUNOS) && \ - (!defined(OPENSSL_SYS_VMS) || defined(localtime_r)) - lcl = localtime_r(&m->time, &result); -# else - lcl = localtime(&m->time); -# endif - BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ", - lcl->tm_hour, lcl->tm_min, lcl->tm_sec); - bufp += strlen(bufp); - } - - BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ", - m->order, m->file, m->line); - bufp += strlen(bufp); - - if (options & V_CRYPTO_MDEBUG_THREAD) { - BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", - CRYPTO_THREADID_hash(&m->threadid)); - bufp += strlen(bufp); - } - - BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n", - m->num, (unsigned long)m->addr); - bufp += strlen(bufp); - - BIO_puts(l->bio, buf); - - l->chunks++; - l->bytes += m->num; - - amip = m->app_info; - ami_cnt = 0; - if (!amip) - return; - CRYPTO_THREADID_cpy(&ti, &amip->threadid); - - do { - int buf_len; - int info_len; - - ami_cnt++; - memset(buf, '>', ami_cnt); - BIO_snprintf(buf + ami_cnt, sizeof(buf) - ami_cnt, - " thread=%lu, file=%s, line=%d, info=\"", - CRYPTO_THREADID_hash(&amip->threadid), amip->file, - amip->line); - buf_len = strlen(buf); - info_len = strlen(amip->info); - if (128 - buf_len - 3 < info_len) { - memcpy(buf + buf_len, amip->info, 128 - buf_len - 3); - buf_len = 128 - 3; - } else { - BUF_strlcpy(buf + buf_len, amip->info, sizeof(buf) - buf_len); - buf_len = strlen(buf); - } - BIO_snprintf(buf + buf_len, sizeof(buf) - buf_len, "\"\n"); - - BIO_puts(l->bio, buf); - - amip = amip->next; - } - while (amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti)); - -#ifdef LEVITTE_DEBUG_MEM - if (amip) { - fprintf(stderr, "Thread switch detected in backtrace!!!!\n"); - abort(); - } -#endif -} - -static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK) - -void CRYPTO_mem_leaks(BIO *b) -{ - MEM_LEAK ml; - - if (mh == NULL && amih == NULL) - return; - - MemCheck_off(); /* obtain MALLOC2 lock */ - - ml.bio = b; - ml.bytes = 0; - ml.chunks = 0; - if (mh != NULL) - lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK, &ml); - if (ml.chunks != 0) { - BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks); -#ifdef CRYPTO_MDEBUG_ABORT - abort(); -#endif - } else { - /* - * Make sure that, if we found no leaks, memory-leak debugging itself - * does not introduce memory leaks (which might irritate external - * debugging tools). (When someone enables leak checking, but does not - * call this function, we declare it to be their fault.) XXX This - * should be in CRYPTO_mem_leaks_cb, and CRYPTO_mem_leaks should be - * implemented by using CRYPTO_mem_leaks_cb. (Also there should be a - * variant of lh_doall_arg that takes a function pointer instead of a - * void *; this would obviate the ugly and illegal void_fn_to_char - * kludge in CRYPTO_mem_leaks_cb. Otherwise the code police will come - * and get us.) - */ - int old_mh_mode; - - CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); - - /* - * avoid deadlock when lh_free() uses CRYPTO_dbg_free(), which uses - * CRYPTO_is_mem_check_on - */ - old_mh_mode = mh_mode; - mh_mode = CRYPTO_MEM_CHECK_OFF; - - if (mh != NULL) { - lh_MEM_free(mh); - mh = NULL; - } - if (amih != NULL) { - if (lh_APP_INFO_num_items(amih) == 0) { - lh_APP_INFO_free(amih); - amih = NULL; - } - } - - mh_mode = old_mh_mode; - CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); - } - MemCheck_on(); /* release MALLOC2 lock */ -} - -#ifndef OPENSSL_NO_FP_API -void CRYPTO_mem_leaks_fp(FILE *fp) -{ - BIO *b; - - if (mh == NULL) - return; - /* - * Need to turn off memory checking when allocated BIOs ... especially as - * we're creating them at a time when we're trying to check we've not - * left anything un-free()'d!! - */ - MemCheck_off(); - b = BIO_new(BIO_s_file()); - MemCheck_on(); - if (!b) - return; - BIO_set_fp(b, fp, BIO_NOCLOSE); - CRYPTO_mem_leaks(b); - BIO_free(b); -} -#endif - -/* - * FIXME: We really don't allow much to the callback. For example, it has no - * chance of reaching the info stack for the item it processes. Should it - * really be this way? -- Richard Levitte - */ -/* - * NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside - * crypto.h If this code is restructured, remove the callback type if it is - * no longer needed. -- Geoff Thorpe - */ - -/* - * Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it is a - * function pointer and conversion to void * is prohibited. Instead pass its - * address - */ - -typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB; - -static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb) -{ - (*cb) (m->order, m->file, m->line, m->num, m->addr); -} - -static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB) - -void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb) -{ - if (mh == NULL) - return; - CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); - lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB, - &cb); - CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); -} diff --git a/Sources/COpenSSL/modes.h b/Sources/COpenSSL/modes.h deleted file mode 100644 index fd488499..00000000 --- a/Sources/COpenSSL/modes.h +++ /dev/null @@ -1,163 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Rights for redistribution and usage in source and binary - * forms are granted according to the OpenSSL license. - */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif -typedef void (*block128_f) (const unsigned char in[16], - unsigned char out[16], const void *key); - -typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], int enc); - -typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - const unsigned char ivec[16]); - -typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out, - size_t blocks, const void *key, - const unsigned char ivec[16], - unsigned char cmac[16]); - -void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], block128_f block); -void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], block128_f block); - -void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], - unsigned char ecount_buf[16], unsigned int *num, - block128_f block); - -void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], - unsigned char ecount_buf[16], - unsigned int *num, ctr128_f ctr); - -void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], int *num, - block128_f block); - -void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], int *num, - int enc, block128_f block); -void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, - size_t length, const void *key, - unsigned char ivec[16], int *num, - int enc, block128_f block); -void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, - size_t bits, const void *key, - unsigned char ivec[16], int *num, - int enc, block128_f block); - -size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, - unsigned char *out, size_t len, - const void *key, unsigned char ivec[16], - block128_f block); -size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], cbc128_f cbc); -size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, - unsigned char *out, size_t len, - const void *key, unsigned char ivec[16], - block128_f block); -size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], cbc128_f cbc); - -size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, - unsigned char *out, size_t len, - const void *key, - unsigned char ivec[16], - block128_f block); -size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], cbc128_f cbc); -size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, - unsigned char *out, size_t len, - const void *key, - unsigned char ivec[16], - block128_f block); -size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], cbc128_f cbc); - -typedef struct gcm128_context GCM128_CONTEXT; - -GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); -void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); -void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, - size_t len); -int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, - size_t len); -int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len); -int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len); -int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len, ctr128_f stream); -int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, - const unsigned char *in, unsigned char *out, - size_t len, ctr128_f stream); -int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, - size_t len); -void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); -void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); - -typedef struct ccm128_context CCM128_CONTEXT; - -void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, - unsigned int M, unsigned int L, void *key, - block128_f block); -int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce, - size_t nlen, size_t mlen); -void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad, - size_t alen); -int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, - unsigned char *out, size_t len); -int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, - unsigned char *out, size_t len); -int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, - unsigned char *out, size_t len, - ccm128_f stream); -int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, - unsigned char *out, size_t len, - ccm128_f stream); -size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); - -typedef struct xts128_context XTS128_CONTEXT; - -int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, - const unsigned char iv[16], - const unsigned char *inp, unsigned char *out, - size_t len, int enc); - -size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, size_t inlen, - block128_f block); - -size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, size_t inlen, - block128_f block); - -#ifdef __cplusplus -} -#endif diff --git a/Sources/COpenSSL/modes_lcl.h b/Sources/COpenSSL/modes_lcl.h deleted file mode 100644 index 820d5d01..00000000 --- a/Sources/COpenSSL/modes_lcl.h +++ /dev/null @@ -1,143 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2010 The OpenSSL Project. All rights reserved. - * - * Redistribution and use is governed by OpenSSL license. - * ==================================================================== - */ - -#include "modes.h" - -#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) -typedef __int64 i64; -typedef unsigned __int64 u64; -# define U64(C) C##UI64 -#elif defined(__arch64__) -typedef long i64; -typedef unsigned long u64; -# define U64(C) C##UL -#else -typedef long long i64; -typedef unsigned long long u64; -# define U64(C) C##ULL -#endif - -typedef unsigned int u32; -typedef unsigned char u8; - -#define STRICT_ALIGNMENT 1 -#ifndef PEDANTIC -# if defined(__i386) || defined(__i386__) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ - defined(__aarch64__) || \ - defined(__s390__) || defined(__s390x__) -# undef STRICT_ALIGNMENT -# endif -#endif - -#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) -# if defined(__GNUC__) && __GNUC__>=2 -# if defined(__x86_64) || defined(__x86_64__) -# define BSWAP8(x) ({ u64 ret_=(x); \ - asm ("bswapq %0" \ - : "+r"(ret_)); ret_; }) -# define BSWAP4(x) ({ u32 ret_=(x); \ - asm ("bswapl %0" \ - : "+r"(ret_)); ret_; }) -# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) -# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ - asm ("bswapl %0; bswapl %1" \ - : "+r"(hi_),"+r"(lo_)); \ - (u64)hi_<<32|lo_; }) -# define BSWAP4(x) ({ u32 ret_=(x); \ - asm ("bswapl %0" \ - : "+r"(ret_)); ret_; }) -# elif defined(__aarch64__) -# define BSWAP8(x) ({ u64 ret_; \ - asm ("rev %0,%1" \ - : "=r"(ret_) : "r"(x)); ret_; }) -# define BSWAP4(x) ({ u32 ret_; \ - asm ("rev %w0,%w1" \ - : "=r"(ret_) : "r"(x)); ret_; }) -# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) -# define BSWAP8(x) ({ u32 lo_=(u64)(x)>>32,hi_=(x); \ - asm ("rev %0,%0; rev %1,%1" \ - : "+r"(hi_),"+r"(lo_)); \ - (u64)hi_<<32|lo_; }) -# define BSWAP4(x) ({ u32 ret_; \ - asm ("rev %0,%1" \ - : "=r"(ret_) : "r"((u32)(x))); \ - ret_; }) -# endif -# elif defined(_MSC_VER) -# if _MSC_VER>=1300 -# pragma intrinsic(_byteswap_uint64,_byteswap_ulong) -# define BSWAP8(x) _byteswap_uint64((u64)(x)) -# define BSWAP4(x) _byteswap_ulong((u32)(x)) -# elif defined(_M_IX86) -__inline u32 _bswap4(u32 val) -{ -_asm mov eax, val _asm bswap eax} -# define BSWAP4(x) _bswap4(x) -# endif -# endif -#endif -#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) -# define GETU32(p) BSWAP4(*(const u32 *)(p)) -# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) -#else -# define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) -# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) -#endif -/*- GCM definitions */ typedef struct { - u64 hi, lo; -} u128; - -#ifdef TABLE_BITS -# undef TABLE_BITS -#endif -/* - * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should - * never be set to 8 [or 1]. For further information see gcm128.c. - */ -#define TABLE_BITS 4 - -struct gcm128_context { - /* Following 6 names follow names in GCM specification */ - union { - u64 u[2]; - u32 d[4]; - u8 c[16]; - size_t t[16 / sizeof(size_t)]; - } Yi, EKi, EK0, len, Xi, H; - /* - * Relative position of Xi, H and pre-computed Htable is used in some - * assembler modules, i.e. don't change the order! - */ -#if TABLE_BITS==8 - u128 Htable[256]; -#else - u128 Htable[16]; - void (*gmult) (u64 Xi[2], const u128 Htable[16]); - void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, - size_t len); -#endif - unsigned int mres, ares; - block128_f block; - void *key; -}; - -struct xts128_context { - void *key1, *key2; - block128_f block1, block2; -}; - -struct ccm128_context { - union { - u64 u[2]; - u8 c[16]; - } nonce, cmac; - u64 blocks; - block128_f block; - void *key; -}; diff --git a/Sources/COpenSSL/n_pkey.c b/Sources/COpenSSL/n_pkey.c deleted file mode 100644 index 823f9af3..00000000 --- a/Sources/COpenSSL/n_pkey.c +++ /dev/null @@ -1,346 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/asn1/n_pkey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -# include "objects.h" -# include "asn1t.h" -# include "asn1_mac.h" -# include "evp.h" -# include "x509.h" - -# ifndef OPENSSL_NO_RC4 - -typedef struct netscape_pkey_st { - long version; - X509_ALGOR *algor; - ASN1_OCTET_STRING *private_key; -} NETSCAPE_PKEY; - -typedef struct netscape_encrypted_pkey_st { - ASN1_OCTET_STRING *os; - /* - * This is the same structure as DigestInfo so use it: although this - * isn't really anything to do with digests. - */ - X509_SIG *enckey; -} NETSCAPE_ENCRYPTED_PKEY; - - -ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = { - ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING), - ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG) -} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY) - -DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY) -IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY) - -ASN1_SEQUENCE(NETSCAPE_PKEY) = { - ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG), - ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR), - ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(NETSCAPE_PKEY) - -DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY) -IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) - -static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, - int (*cb) (char *buf, int len, const char *prompt, - int verify), int sgckey); - -int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, - int (*cb) (char *buf, int len, const char *prompt, - int verify)) -{ - return i2d_RSA_NET(a, pp, cb, 0); -} - -int i2d_RSA_NET(const RSA *a, unsigned char **pp, - int (*cb) (char *buf, int len, const char *prompt, - int verify), int sgckey) -{ - int i, j, ret = 0; - int rsalen, pkeylen, olen; - NETSCAPE_PKEY *pkey = NULL; - NETSCAPE_ENCRYPTED_PKEY *enckey = NULL; - unsigned char buf[256], *zz; - unsigned char key[EVP_MAX_KEY_LENGTH]; - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - - if (a == NULL) - return (0); - - if ((pkey = NETSCAPE_PKEY_new()) == NULL) - goto err; - if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL) - goto err; - pkey->version = 0; - - pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption); - if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL) - goto err; - pkey->algor->parameter->type = V_ASN1_NULL; - - rsalen = i2d_RSAPrivateKey(a, NULL); - - /* - * Fake some octet strings just for the initial length calculation. - */ - - pkey->private_key->length = rsalen; - - pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL); - - enckey->enckey->digest->length = pkeylen; - - enckey->os->length = 11; /* "private-key" */ - - enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4); - if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL) - goto err; - enckey->enckey->algor->parameter->type = V_ASN1_NULL; - - if (pp == NULL) { - olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL); - NETSCAPE_PKEY_free(pkey); - NETSCAPE_ENCRYPTED_PKEY_free(enckey); - return olen; - } - - /* Since its RC4 encrypted length is actual length */ - if ((zz = (unsigned char *)OPENSSL_malloc(rsalen)) == NULL) { - ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); - goto err; - } - - pkey->private_key->data = zz; - /* Write out private key encoding */ - i2d_RSAPrivateKey(a, &zz); - - if ((zz = OPENSSL_malloc(pkeylen)) == NULL) { - ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!ASN1_STRING_set(enckey->os, "private-key", -1)) { - ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); - goto err; - } - enckey->enckey->digest->data = zz; - i2d_NETSCAPE_PKEY(pkey, &zz); - - /* Wipe the private key encoding */ - OPENSSL_cleanse(pkey->private_key->data, rsalen); - - if (cb == NULL) - cb = EVP_read_pw_string; - i = cb((char *)buf, 256, "Enter Private Key password:", 1); - if (i != 0) { - ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ); - goto err; - } - i = strlen((char *)buf); - /* If the key is used for SGC the algorithm is modified a little. */ - if (sgckey) { - if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL)) - goto err; - memcpy(buf + 16, "SGCKEYSALT", 10); - i = 26; - } - - if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL)) - goto err; - OPENSSL_cleanse(buf, 256); - - /* Encrypt private key in place */ - zz = enckey->enckey->digest->data; - if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL)) - goto err; - if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen)) - goto err; - if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j)) - goto err; - - ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp); - err: - EVP_CIPHER_CTX_cleanup(&ctx); - NETSCAPE_ENCRYPTED_PKEY_free(enckey); - NETSCAPE_PKEY_free(pkey); - return (ret); -} - -RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, - int (*cb) (char *buf, int len, const char *prompt, - int verify)) -{ - return d2i_RSA_NET(a, pp, length, cb, 0); -} - -RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, - int (*cb) (char *buf, int len, const char *prompt, - int verify), int sgckey) -{ - RSA *ret = NULL; - const unsigned char *p; - NETSCAPE_ENCRYPTED_PKEY *enckey = NULL; - - p = *pp; - - enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length); - if (!enckey) { - ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_DECODING_ERROR); - return NULL; - } - - if ((enckey->os->length != 11) || (strncmp("private-key", - (char *)enckey->os->data, - 11) != 0)) { - ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING); - NETSCAPE_ENCRYPTED_PKEY_free(enckey); - return NULL; - } - if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) { - ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM); - goto err; - } - if (cb == NULL) - cb = EVP_read_pw_string; - if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb, sgckey)) == NULL) - goto err; - - *pp = p; - - err: - NETSCAPE_ENCRYPTED_PKEY_free(enckey); - return ret; - -} - -static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, - int (*cb) (char *buf, int len, const char *prompt, - int verify), int sgckey) -{ - NETSCAPE_PKEY *pkey = NULL; - RSA *ret = NULL; - int i, j; - unsigned char buf[256]; - const unsigned char *zz; - unsigned char key[EVP_MAX_KEY_LENGTH]; - EVP_CIPHER_CTX ctx; - EVP_CIPHER_CTX_init(&ctx); - - i = cb((char *)buf, 256, "Enter Private Key password:", 0); - if (i != 0) { - ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_BAD_PASSWORD_READ); - goto err; - } - - i = strlen((char *)buf); - if (sgckey) { - if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL)) - goto err; - memcpy(buf + 16, "SGCKEYSALT", 10); - i = 26; - } - - if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL)) - goto err; - OPENSSL_cleanse(buf, 256); - - if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL)) - goto err; - if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length)) - goto err; - if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j)) - goto err; - os->length = i + j; - - zz = os->data; - - if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) { - ASN1err(ASN1_F_D2I_RSA_NET_2, - ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY); - goto err; - } - - zz = pkey->private_key->data; - if ((ret = d2i_RSAPrivateKey(a, &zz, pkey->private_key->length)) == NULL) { - ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_UNABLE_TO_DECODE_RSA_KEY); - goto err; - } - err: - EVP_CIPHER_CTX_cleanup(&ctx); - NETSCAPE_PKEY_free(pkey); - return (ret); -} - -# endif /* OPENSSL_NO_RC4 */ - -#else /* !OPENSSL_NO_RSA */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/Sources/COpenSSL/names.c b/Sources/COpenSSL/names.c deleted file mode 100644 index c6a73084..00000000 --- a/Sources/COpenSSL/names.c +++ /dev/null @@ -1,215 +0,0 @@ -/* crypto/evp/names.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "objects.h" -#include "x509.h" - -int EVP_add_cipher(const EVP_CIPHER *c) -{ - int r; - - if (c == NULL) - return 0; - - OPENSSL_init(); - - r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH, - (const char *)c); - if (r == 0) - return (0); - check_defer(c->nid); - r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH, - (const char *)c); - return (r); -} - -int EVP_add_digest(const EVP_MD *md) -{ - int r; - const char *name; - OPENSSL_init(); - - name = OBJ_nid2sn(md->type); - r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md); - if (r == 0) - return (0); - check_defer(md->type); - r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH, - (const char *)md); - if (r == 0) - return (0); - - if (md->pkey_type && md->type != md->pkey_type) { - r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type), - OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name); - if (r == 0) - return (0); - check_defer(md->pkey_type); - r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type), - OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name); - } - return (r); -} - -const EVP_CIPHER *EVP_get_cipherbyname(const char *name) -{ - const EVP_CIPHER *cp; - - cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); - return (cp); -} - -const EVP_MD *EVP_get_digestbyname(const char *name) -{ - const EVP_MD *cp; - - cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); - return (cp); -} - -void EVP_cleanup(void) -{ - OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH); - OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH); - /* - * The above calls will only clean out the contents of the name hash - * table, but not the hash table itself. The following line does that - * part. -- Richard Levitte - */ - OBJ_NAME_cleanup(-1); - - EVP_PBE_cleanup(); - if (obj_cleanup_defer == 2) { - obj_cleanup_defer = 0; - OBJ_cleanup(); - } - OBJ_sigid_free(); -} - -struct doall_cipher { - void *arg; - void (*fn) (const EVP_CIPHER *ciph, - const char *from, const char *to, void *arg); -}; - -static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg) -{ - struct doall_cipher *dc = arg; - if (nm->alias) - dc->fn(NULL, nm->name, nm->data, dc->arg); - else - dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg); -} - -void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, - const char *from, const char *to, void *x), - void *arg) -{ - struct doall_cipher dc; - dc.fn = fn; - dc.arg = arg; - OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); -} - -void EVP_CIPHER_do_all_sorted(void (*fn) (const EVP_CIPHER *ciph, - const char *from, const char *to, - void *x), void *arg) -{ - struct doall_cipher dc; - dc.fn = fn; - dc.arg = arg; - OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); -} - -struct doall_md { - void *arg; - void (*fn) (const EVP_MD *ciph, - const char *from, const char *to, void *arg); -}; - -static void do_all_md_fn(const OBJ_NAME *nm, void *arg) -{ - struct doall_md *dc = arg; - if (nm->alias) - dc->fn(NULL, nm->name, nm->data, dc->arg); - else - dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg); -} - -void EVP_MD_do_all(void (*fn) (const EVP_MD *md, - const char *from, const char *to, void *x), - void *arg) -{ - struct doall_md dc; - dc.fn = fn; - dc.arg = arg; - OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); -} - -void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md, - const char *from, const char *to, - void *x), void *arg) -{ - struct doall_md dc; - dc.fn = fn; - dc.arg = arg; - OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); -} diff --git a/Sources/COpenSSL/ncbc_enc.h b/Sources/COpenSSL/ncbc_enc.h deleted file mode 100644 index ab267cbf..00000000 --- a/Sources/COpenSSL/ncbc_enc.h +++ /dev/null @@ -1,154 +0,0 @@ -/* crypto/des/ncbc_enc.c */ -/*- - * #included by: - * cbc_enc.c (DES_cbc_encrypt) - * des_enc.c (DES_ncbc_encrypt) - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -#ifdef CBC_ENC_C__DONT_UPDATE_IV -void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, - DES_key_schedule *_schedule, DES_cblock *ivec, int enc) -#else -void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *_schedule, - DES_cblock *ivec, int enc) -#endif -{ - register DES_LONG tin0, tin1; - register DES_LONG tout0, tout1, xor0, xor1; - register long l = length; - DES_LONG tin[2]; - unsigned char *iv; - - iv = &(*ivec)[0]; - - if (enc) { - c2l(iv, tout0); - c2l(iv, tout1); - for (l -= 8; l >= 0; l -= 8) { - c2l(in, tin0); - c2l(in, tin1); - tin0 ^= tout0; - tin[0] = tin0; - tin1 ^= tout1; - tin[1] = tin1; - DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT); - tout0 = tin[0]; - l2c(tout0, out); - tout1 = tin[1]; - l2c(tout1, out); - } - if (l != -8) { - c2ln(in, tin0, tin1, l + 8); - tin0 ^= tout0; - tin[0] = tin0; - tin1 ^= tout1; - tin[1] = tin1; - DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT); - tout0 = tin[0]; - l2c(tout0, out); - tout1 = tin[1]; - l2c(tout1, out); - } -#ifndef CBC_ENC_C__DONT_UPDATE_IV - iv = &(*ivec)[0]; - l2c(tout0, iv); - l2c(tout1, iv); -#endif - } else { - c2l(iv, xor0); - c2l(iv, xor1); - for (l -= 8; l >= 0; l -= 8) { - c2l(in, tin0); - tin[0] = tin0; - c2l(in, tin1); - tin[1] = tin1; - DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2c(tout0, out); - l2c(tout1, out); - xor0 = tin0; - xor1 = tin1; - } - if (l != -8) { - c2l(in, tin0); - tin[0] = tin0; - c2l(in, tin1); - tin[1] = tin1; - DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2cn(tout0, tout1, out, l + 8); -#ifndef CBC_ENC_C__DONT_UPDATE_IV - xor0 = tin0; - xor1 = tin1; -#endif - } -#ifndef CBC_ENC_C__DONT_UPDATE_IV - iv = &(*ivec)[0]; - l2c(xor0, iv); - l2c(xor1, iv); -#endif - } - tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; - tin[0] = tin[1] = 0; -} diff --git a/Sources/COpenSSL/nsseq.c b/Sources/COpenSSL/nsseq.c deleted file mode 100644 index cbcdb0fa..00000000 --- a/Sources/COpenSSL/nsseq.c +++ /dev/null @@ -1,84 +0,0 @@ -/* nsseq.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "asn1t.h" -#include "x509.h" -#include "objects.h" - -static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_NEW_POST) { - NETSCAPE_CERT_SEQUENCE *nsseq; - nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval; - nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence); - } - return 1; -} - -/* Netscape certificate sequence structure */ - -ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = { - ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT), - ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0) -} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) - -IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) diff --git a/Sources/COpenSSL/o_.c b/Sources/COpenSSL/o_.c deleted file mode 100644 index 5e279834..00000000 --- a/Sources/COpenSSL/o_.c +++ /dev/null @@ -1,1236 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/o_dir.c */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "e_os.h" - -/* - * The routines really come from the Levitte Programming, so to make life - * simple, let's just use the raw files and hack the symbols to fit our - * namespace. - */ -#define LP_DIR_CTX OPENSSL_DIR_CTX -#define LP_dir_context_st OPENSSL_dir_context_st -#define LP_find_file OPENSSL_DIR_read -#define LP_find_file_end OPENSSL_DIR_end - -#include "o_dir.h" - -#define LPDIR_H -#if defined OPENSSL_SYS_UNIX || defined DJGPP \ - || (defined __VMS_VER && __VMS_VER >= 70000000) -# include "LPdir_unix.h" -#elif defined OPENSSL_SYS_VMS -# include "LPdir_vms.c" -#elif defined OPENSSL_SYS_WIN32 -# include "LPdir_win32.c" -#elif defined OPENSSL_SYS_WINCE -# include "LPdir_wince.c" -#else -# include "LPdir_nyi.c" -#endif -/* - * Written by Stephen henson (steve@openssl.org) for the OpenSSL project - * 2011. - */ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "cryptlib.h" -#ifdef OPENSSL_FIPS -# include -# include -# include "rand.h" -#endif - -int FIPS_mode(void) -{ - OPENSSL_init(); -#ifdef OPENSSL_FIPS - return FIPS_module_mode(); -#else - return 0; -#endif -} - -int FIPS_mode_set(int r) -{ - OPENSSL_init(); -#ifdef OPENSSL_FIPS -# ifndef FIPS_AUTH_USER_PASS -# define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password" -# endif - if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS)) - return 0; - if (r) - RAND_set_rand_method(FIPS_rand_get_method()); - else - RAND_set_rand_method(NULL); - return 1; -#else - if (r == 0) - return 1; - CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED); - return 0; -#endif -} -/* o_init.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "e_os.h" -#include "err.h" -#ifdef OPENSSL_FIPS -# include -# include "rand.h" - -# ifndef OPENSSL_NO_DEPRECATED -/* the prototype is missing in */ -void FIPS_crypto_set_id_callback(unsigned long (*func)(void)); -# endif -#endif - -/* - * Perform any essential OpenSSL initialization operations. Currently only - * sets FIPS callbacks - */ - -void OPENSSL_init(void) -{ - static int done = 0; - if (done) - return; - done = 1; -#ifdef OPENSSL_FIPS - FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock); -# ifndef OPENSSL_NO_DEPRECATED - FIPS_crypto_set_id_callback(CRYPTO_thread_id); -# endif - FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); - FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); - RAND_init_fips(); -#endif -#if 0 - fprintf(stderr, "Called OPENSSL_init\n"); -#endif -} -#include -#include -#include - -// #include "err.h" -#include "lhash.h" -#include "objects.h" -#include "safestack.h" -#include "e_os2.h" - -/* - * Later versions of DEC C has started to add lnkage information to certain - * functions, which makes it tricky to use them as values to regular function - * pointers. One way is to define a macro that takes care of casting them - * correctly. - */ -#ifdef OPENSSL_SYS_VMS_DECC -# define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp -#else -# define OPENSSL_strcmp strcmp -#endif - -/* - * I use the ex_data stuff to manage the identifiers for the obj_name_types - * that applications may define. I only really use the free function field. - */ -DECLARE_LHASH_OF(OBJ_NAME); -static LHASH_OF(OBJ_NAME) *names_lh = NULL; -static int names_type_num = OBJ_NAME_TYPE_NUM; - -typedef struct name_funcs_st { - unsigned long (*hash_func) (const char *name); - int (*cmp_func) (const char *a, const char *b); - void (*free_func) (const char *, int, const char *); -} NAME_FUNCS; - -DECLARE_STACK_OF(NAME_FUNCS) -IMPLEMENT_STACK_OF(NAME_FUNCS) - -static STACK_OF(NAME_FUNCS) *name_funcs_stack; - -/* - * The LHASH callbacks now use the raw "void *" prototypes and do - * per-variable casting in the functions. This prevents function pointer - * casting without the need for macro-generated wrapper functions. - */ - -/* static unsigned long obj_name_hash(OBJ_NAME *a); */ -static unsigned long obj_name_hash(const void *a_void); -/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */ -static int obj_name_cmp(const void *a_void, const void *b_void); - -static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME) -static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME) - -int OBJ_NAME_init(void) -{ - if (names_lh != NULL) - return (1); - MemCheck_off(); - names_lh = lh_OBJ_NAME_new(); - MemCheck_on(); - return (names_lh != NULL); -} - -int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), - int (*cmp_func) (const char *, const char *), - void (*free_func) (const char *, int, const char *)) -{ - int ret; - int i; - NAME_FUNCS *name_funcs; - - if (name_funcs_stack == NULL) { - MemCheck_off(); - name_funcs_stack = sk_NAME_FUNCS_new_null(); - MemCheck_on(); - } - if (name_funcs_stack == NULL) { - /* ERROR */ - return (0); - } - ret = names_type_num; - names_type_num++; - for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { - MemCheck_off(); - name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS)); - MemCheck_on(); - if (!name_funcs) { - OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); - return (0); - } - name_funcs->hash_func = lh_strhash; - name_funcs->cmp_func = OPENSSL_strcmp; - name_funcs->free_func = 0; /* NULL is often declared to * ((void - * *)0), which according * to Compaq C is - * not really * compatible with a function - * * pointer. -- Richard Levitte */ - MemCheck_off(); - sk_NAME_FUNCS_push(name_funcs_stack, name_funcs); - MemCheck_on(); - } - name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret); - if (hash_func != NULL) - name_funcs->hash_func = hash_func; - if (cmp_func != NULL) - name_funcs->cmp_func = cmp_func; - if (free_func != NULL) - name_funcs->free_func = free_func; - return (ret); -} - -/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */ -static int obj_name_cmp(const void *a_void, const void *b_void) -{ - int ret; - const OBJ_NAME *a = (const OBJ_NAME *)a_void; - const OBJ_NAME *b = (const OBJ_NAME *)b_void; - - ret = a->type - b->type; - if (ret == 0) { - if ((name_funcs_stack != NULL) - && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { - ret = sk_NAME_FUNCS_value(name_funcs_stack, - a->type)->cmp_func(a->name, b->name); - } else - ret = strcmp(a->name, b->name); - } - return (ret); -} - -/* static unsigned long obj_name_hash(OBJ_NAME *a) */ -static unsigned long obj_name_hash(const void *a_void) -{ - unsigned long ret; - const OBJ_NAME *a = (const OBJ_NAME *)a_void; - - if ((name_funcs_stack != NULL) - && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { - ret = - sk_NAME_FUNCS_value(name_funcs_stack, - a->type)->hash_func(a->name); - } else { - ret = lh_strhash(a->name); - } - ret ^= a->type; - return (ret); -} - -const char *OBJ_NAME_get(const char *name, int type) -{ - OBJ_NAME on, *ret; - int num = 0, alias; - - if (name == NULL) - return (NULL); - if ((names_lh == NULL) && !OBJ_NAME_init()) - return (NULL); - - alias = type & OBJ_NAME_ALIAS; - type &= ~OBJ_NAME_ALIAS; - - on.name = name; - on.type = type; - - for (;;) { - ret = lh_OBJ_NAME_retrieve(names_lh, &on); - if (ret == NULL) - return (NULL); - if ((ret->alias) && !alias) { - if (++num > 10) - return (NULL); - on.name = ret->data; - } else { - return (ret->data); - } - } -} - -int OBJ_NAME_add(const char *name, int type, const char *data) -{ - OBJ_NAME *onp, *ret; - int alias; - - if ((names_lh == NULL) && !OBJ_NAME_init()) - return (0); - - alias = type & OBJ_NAME_ALIAS; - type &= ~OBJ_NAME_ALIAS; - - onp = (OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME)); - if (onp == NULL) { - /* ERROR */ - return 0; - } - - onp->name = name; - onp->alias = alias; - onp->type = type; - onp->data = data; - - ret = lh_OBJ_NAME_insert(names_lh, onp); - if (ret != NULL) { - /* free things */ - if ((name_funcs_stack != NULL) - && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { - /* - * XXX: I'm not sure I understand why the free function should - * get three arguments... -- Richard Levitte - */ - sk_NAME_FUNCS_value(name_funcs_stack, - ret->type)->free_func(ret->name, ret->type, - ret->data); - } - OPENSSL_free(ret); - } else { - if (lh_OBJ_NAME_error(names_lh)) { - /* ERROR */ - OPENSSL_free(onp); - return 0; - } - } - return 1; -} - -int OBJ_NAME_remove(const char *name, int type) -{ - OBJ_NAME on, *ret; - - if (names_lh == NULL) - return (0); - - type &= ~OBJ_NAME_ALIAS; - on.name = name; - on.type = type; - ret = lh_OBJ_NAME_delete(names_lh, &on); - if (ret != NULL) { - /* free things */ - if ((name_funcs_stack != NULL) - && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { - /* - * XXX: I'm not sure I understand why the free function should - * get three arguments... -- Richard Levitte - */ - sk_NAME_FUNCS_value(name_funcs_stack, - ret->type)->free_func(ret->name, ret->type, - ret->data); - } - OPENSSL_free(ret); - return (1); - } else - return (0); -} - -struct doall { - int type; - void (*fn) (const OBJ_NAME *, void *arg); - void *arg; -}; - -static void do_all_fn_doall_arg(const OBJ_NAME *name, struct doall *d) -{ - if (name->type == d->type) - d->fn(name, d->arg); -} - -static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall) - -void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), - void *arg) -{ - struct doall d; - - d.type = type; - d.fn = fn; - d.arg = arg; - - lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn), - struct doall, &d); -} - -struct doall_sorted { - int type; - int n; - const OBJ_NAME **names; -}; - -static void do_all_sorted_fn(const OBJ_NAME *name, void *d_) -{ - struct doall_sorted *d = d_; - - if (name->type != d->type) - return; - - d->names[d->n++] = name; -} - -static int do_all_sorted_cmp(const void *n1_, const void *n2_) -{ - const OBJ_NAME *const *n1 = n1_; - const OBJ_NAME *const *n2 = n2_; - - return strcmp((*n1)->name, (*n2)->name); -} - -void OBJ_NAME_do_all_sorted(int type, - void (*fn) (const OBJ_NAME *, void *arg), - void *arg) -{ - struct doall_sorted d; - int n; - - d.type = type; - d.names = - OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh) * sizeof(*d.names)); - /* Really should return an error if !d.names...but its a void function! */ - if (d.names) { - d.n = 0; - OBJ_NAME_do_all(type, do_all_sorted_fn, &d); - - qsort((void *)d.names, d.n, sizeof(*d.names), do_all_sorted_cmp); - - for (n = 0; n < d.n; ++n) - fn(d.names[n], arg); - - OPENSSL_free((void *)d.names); - } -} - -static int free_type; - -static void names_lh_free_doall(OBJ_NAME *onp) -{ - if (onp == NULL) - return; - - if (free_type < 0 || free_type == onp->type) - OBJ_NAME_remove(onp->name, onp->type); -} - -static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME) - -static void name_funcs_free(NAME_FUNCS *ptr) -{ - OPENSSL_free(ptr); -} - -void OBJ_NAME_cleanup(int type) -{ - unsigned long down_load; - - if (names_lh == NULL) - return; - - free_type = type; - down_load = lh_OBJ_NAME_down_load(names_lh); - lh_OBJ_NAME_down_load(names_lh) = 0; - - lh_OBJ_NAME_doall(names_lh, LHASH_DOALL_FN(names_lh_free)); - if (type < 0) { - lh_OBJ_NAME_free(names_lh); - sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free); - names_lh = NULL; - name_funcs_stack = NULL; - } else - lh_OBJ_NAME_down_load(names_lh) = down_load; -} -/* crypto/o_str.c */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2003. - */ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "e_os.h" -#include "o_str.h" - -#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \ - !defined(OPENSSL_SYSNAME_WIN32) && !defined(OPENSSL_SYSNAME_WINCE) && \ - !defined(NETWARE_CLIB) -# include -#endif - -int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n) -{ -#if defined(OPENSSL_IMPLEMENTS_strncasecmp) - while (*str1 && *str2 && n) { - int res = toupper(*str1) - toupper(*str2); - if (res) - return res < 0 ? -1 : 1; - str1++; - str2++; - n--; - } - if (n == 0) - return 0; - if (*str1) - return 1; - if (*str2) - return -1; - return 0; -#else - /* - * Recursion hazard warning! Whenever strncasecmp is #defined as - * OPENSSL_strncasecmp, OPENSSL_IMPLEMENTS_strncasecmp must be defined as - * well. - */ - return strncasecmp(str1, str2, n); -#endif -} - -int OPENSSL_strcasecmp(const char *str1, const char *str2) -{ -#if defined(OPENSSL_IMPLEMENTS_strncasecmp) - return OPENSSL_strncasecmp(str1, str2, (size_t)-1); -#else - return strcasecmp(str1, str2); -#endif -} - -int OPENSSL_memcmp(const void *v1, const void *v2, size_t n) -{ - const unsigned char *c1 = v1, *c2 = v2; - int ret = 0; - - while (n && (ret = *c1 - *c2) == 0) - n--, c1++, c2++; - - return ret; -} -/* crypto/o_time.c */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2008. - */ -/* ==================================================================== - * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "e_os2.h" -#include -#include "o_time.h" - -#ifdef OPENSSL_SYS_VMS -# if __CRTL_VER >= 70000000 && \ - (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE) -# define VMS_GMTIME_OK -# endif -# ifndef VMS_GMTIME_OK -# include -# include -# include -# include -# include -# include -# endif /* ndef VMS_GMTIME_OK */ - - -/* - * Needed to pick up the correct definitions and declarations in some of the - * DEC C Header Files (*.H). - */ -# define __NEW_STARLET 1 - -# if (defined(__alpha) || defined(__ia64)) -# include -# else - -/* VAX */ -typedef struct _ile3 { /* Copied from ILEDEF.H for Alpha */ -# pragma __nomember_alignment - unsigned short int ile3$w_length; /* Length of buffer in bytes */ - unsigned short int ile3$w_code; /* Item code value */ - void *ile3$ps_bufaddr; /* Buffer address */ - unsigned short int *ile3$ps_retlen_addr; /* Address of word for returned length */ -} ILE3; -# endif /* alpha || ia64 */ -#endif /* OPENSSL_SYS_VMS */ - -struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) -{ - struct tm *ts = NULL; - -#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_SUNOS) - if (gmtime_r(timer, result) == NULL) - return NULL; - ts = result; -#elif defined (OPENSSL_SYS_WINDOWS) && defined(_MSC_VER) && _MSC_VER >= 1400 - if (gmtime_s(result, timer)) - return NULL; - ts = result; -#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK) - ts = gmtime(timer); - if (ts == NULL) - return NULL; - - memcpy(result, ts, sizeof(struct tm)); - ts = result; -#endif -#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK) - if (ts == NULL) { - static $DESCRIPTOR(tabnam, "LNM$DCL_LOGICAL"); - static $DESCRIPTOR(lognam, "SYS$TIMEZONE_DIFFERENTIAL"); - char logvalue[256]; - unsigned int reslen = 0; -# if __INITIAL_POINTER_SIZE == 64 - ILEB_64 itemlist[2], *pitem; -# else - ILE3 itemlist[2], *pitem; -# endif - int status; - time_t t; - - - /* - * Setup an itemlist for the call to $TRNLNM - Translate Logical Name. - */ - pitem = itemlist; - -# if __INITIAL_POINTER_SIZE == 64 - pitem->ileb_64$w_mbo = 1; - pitem->ileb_64$w_code = LNM$_STRING; - pitem->ileb_64$l_mbmo = -1; - pitem->ileb_64$q_length = sizeof(logvalue); - pitem->ileb_64$pq_bufaddr = logvalue; - pitem->ileb_64$pq_retlen_addr = (unsigned __int64 *) &reslen; - pitem++; - /* Last item of the item list is null terminated */ - pitem->ileb_64$q_length = pitem->ileb_64$w_code = 0; -# else - pitem->ile3$w_length = sizeof(logvalue); - pitem->ile3$w_code = LNM$_STRING; - pitem->ile3$ps_bufaddr = logvalue; - pitem->ile3$ps_retlen_addr = (unsigned short int *) &reslen; - pitem++; - /* Last item of the item list is null terminated */ - pitem->ile3$w_length = pitem->ile3$w_code = 0; -# endif - - - /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */ - status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist); - if (!(status & 1)) - return NULL; - logvalue[reslen] = '\0'; - - t = *timer; - - /* The following is extracted from the DEC C header time.h */ - /* - ** Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime - ** have two implementations. One implementation is provided - ** for compatibility and deals with time in terms of local time, - ** the other __utc_* deals with time in terms of UTC. - */ - /* - * We use the same conditions as in said time.h to check if we should - * assume that t contains local time (and should therefore be - * adjusted) or UTC (and should therefore be left untouched). - */ -# if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE - /* Get the numerical value of the equivalence string */ - status = atoi(logvalue); - - /* and use it to move time to GMT */ - t -= status; -# endif - - /* then convert the result to the time structure */ - - /* - * Since there was no gmtime_r() to do this stuff for us, we have to - * do it the hard way. - */ - { - /*- - * The VMS epoch is the astronomical Smithsonian date, - if I remember correctly, which is November 17, 1858. - Furthermore, time is measure in thenths of microseconds - and stored in quadwords (64 bit integers). unix_epoch - below is January 1st 1970 expressed as a VMS time. The - following code was used to get this number: - - #include - #include - #include - #include - - main() - { - unsigned long systime[2]; - unsigned short epoch_values[7] = - { 1970, 1, 1, 0, 0, 0, 0 }; - - lib$cvt_vectim(epoch_values, systime); - - printf("%u %u", systime[0], systime[1]); - } - */ - unsigned long unix_epoch[2] = { 1273708544, 8164711 }; - unsigned long deltatime[2]; - unsigned long systime[2]; - struct vms_vectime { - short year, month, day, hour, minute, second, centi_second; - } time_values; - long operation; - - /* - * Turn the number of seconds since January 1st 1970 to an - * internal delta time. Note that lib$cvt_to_internal_time() will - * assume that t is signed, and will therefore break on 32-bit - * systems some time in 2038. - */ - operation = LIB$K_DELTA_SECONDS; - status = lib$cvt_to_internal_time(&operation, &t, deltatime); - - /* - * Add the delta time with the Unix epoch and we have the current - * UTC time in internal format - */ - status = lib$add_times(unix_epoch, deltatime, systime); - - /* Turn the internal time into a time vector */ - status = sys$numtim(&time_values, systime); - - /* Fill in the struct tm with the result */ - result->tm_sec = time_values.second; - result->tm_min = time_values.minute; - result->tm_hour = time_values.hour; - result->tm_mday = time_values.day; - result->tm_mon = time_values.month - 1; - result->tm_year = time_values.year - 1900; - - operation = LIB$K_DAY_OF_WEEK; - status = lib$cvt_from_internal_time(&operation, - &result->tm_wday, systime); - result->tm_wday %= 7; - - operation = LIB$K_DAY_OF_YEAR; - status = lib$cvt_from_internal_time(&operation, - &result->tm_yday, systime); - result->tm_yday--; - - result->tm_isdst = 0; /* There's no way to know... */ - - ts = result; - } - } -#endif - return ts; -} - -/* - * Take a tm structure and add an offset to it. This avoids any OS issues - * with restricted date types and overflows which cause the year 2038 - * problem. - */ - -#define SECS_PER_DAY (24 * 60 * 60) - -static long date_to_julian(int y, int m, int d); -static void julian_to_date(long jd, int *y, int *m, int *d); -static int julian_adj(const struct tm *tm, int off_day, long offset_sec, - long *pday, int *psec); - -int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) -{ - int time_sec, time_year, time_month, time_day; - long time_jd; - - /* Convert time and offset into julian day and seconds */ - if (!julian_adj(tm, off_day, offset_sec, &time_jd, &time_sec)) - return 0; - - /* Convert Julian day back to date */ - - julian_to_date(time_jd, &time_year, &time_month, &time_day); - - if (time_year < 1900 || time_year > 9999) - return 0; - - /* Update tm structure */ - - tm->tm_year = time_year - 1900; - tm->tm_mon = time_month - 1; - tm->tm_mday = time_day; - - tm->tm_hour = time_sec / 3600; - tm->tm_min = (time_sec / 60) % 60; - tm->tm_sec = time_sec % 60; - - return 1; - -} - -int OPENSSL_gmtime_diff(int *pday, int *psec, - const struct tm *from, const struct tm *to) -{ - int from_sec, to_sec, diff_sec; - long from_jd, to_jd, diff_day; - if (!julian_adj(from, 0, 0, &from_jd, &from_sec)) - return 0; - if (!julian_adj(to, 0, 0, &to_jd, &to_sec)) - return 0; - diff_day = to_jd - from_jd; - diff_sec = to_sec - from_sec; - /* Adjust differences so both positive or both negative */ - if (diff_day > 0 && diff_sec < 0) { - diff_day--; - diff_sec += SECS_PER_DAY; - } - if (diff_day < 0 && diff_sec > 0) { - diff_day++; - diff_sec -= SECS_PER_DAY; - } - - if (pday) - *pday = (int)diff_day; - if (psec) - *psec = diff_sec; - - return 1; - -} - -/* Convert tm structure and offset into julian day and seconds */ -static int julian_adj(const struct tm *tm, int off_day, long offset_sec, - long *pday, int *psec) -{ - int offset_hms, offset_day; - long time_jd; - int time_year, time_month, time_day; - /* split offset into days and day seconds */ - offset_day = offset_sec / SECS_PER_DAY; - /* Avoid sign issues with % operator */ - offset_hms = offset_sec - (offset_day * SECS_PER_DAY); - offset_day += off_day; - /* Add current time seconds to offset */ - offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; - /* Adjust day seconds if overflow */ - if (offset_hms >= SECS_PER_DAY) { - offset_day++; - offset_hms -= SECS_PER_DAY; - } else if (offset_hms < 0) { - offset_day--; - offset_hms += SECS_PER_DAY; - } - - /* - * Convert date of time structure into a Julian day number. - */ - - time_year = tm->tm_year + 1900; - time_month = tm->tm_mon + 1; - time_day = tm->tm_mday; - - time_jd = date_to_julian(time_year, time_month, time_day); - - /* Work out Julian day of new date */ - time_jd += offset_day; - - if (time_jd < 0) - return 0; - - *pday = time_jd; - *psec = offset_hms; - return 1; -} - -/* - * Convert date to and from julian day Uses Fliegel & Van Flandern algorithm - */ -static long date_to_julian(int y, int m, int d) -{ - return (1461 * (y + 4800 + (m - 14) / 12)) / 4 + - (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - - (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075; -} - -static void julian_to_date(long jd, int *y, int *m, int *d) -{ - long L = jd + 68569; - long n = (4 * L) / 146097; - long i, j; - - L = L - (146097 * n + 3) / 4; - i = (4000 * (L + 1)) / 1461001; - L = L - (1461 * i) / 4 + 31; - j = (80 * L) / 2447; - *d = L - (2447 * j) / 80; - L = j / 11; - *m = j + 2 - (12 * L); - *y = 100 * (n - 49) + i + L; -} - -#ifdef OPENSSL_TIME_TEST - -# include - -/* - * Time checking test code. Check times are identical for a wide range of - * offsets. This should be run on a machine with 64 bit time_t or it will - * trigger the very errors the routines fix. - */ - -int main(int argc, char **argv) -{ - long offset; - for (offset = 0; offset < 1000000; offset++) { - check_time(offset); - check_time(-offset); - check_time(offset * 1000); - check_time(-offset * 1000); - } -} - -int check_time(long offset) -{ - struct tm tm1, tm2, o1; - int off_day, off_sec; - long toffset; - time_t t1, t2; - time(&t1); - t2 = t1 + offset; - OPENSSL_gmtime(&t2, &tm2); - OPENSSL_gmtime(&t1, &tm1); - o1 = tm1; - OPENSSL_gmtime_adj(&tm1, 0, offset); - if ((tm1.tm_year != tm2.tm_year) || - (tm1.tm_mon != tm2.tm_mon) || - (tm1.tm_mday != tm2.tm_mday) || - (tm1.tm_hour != tm2.tm_hour) || - (tm1.tm_min != tm2.tm_min) || (tm1.tm_sec != tm2.tm_sec)) { - fprintf(stderr, "TIME ERROR!!\n"); - fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n", - tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900, - tm2.tm_hour, tm2.tm_min, tm2.tm_sec); - fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n", - tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900, - tm1.tm_hour, tm1.tm_min, tm1.tm_sec); - return 0; - } - OPENSSL_gmtime_diff(&o1, &tm1, &off_day, &off_sec); - toffset = (long)off_day *SECS_PER_DAY + off_sec; - if (offset != toffset) { - fprintf(stderr, "TIME OFFSET ERROR!!\n"); - fprintf(stderr, "Expected %ld, Got %ld (%d:%d)\n", - offset, toffset, off_day, off_sec); - return 0; - } - return 1; -} - -#endif diff --git a/Sources/COpenSSL/o_dir.h b/Sources/COpenSSL/o_dir.h deleted file mode 100644 index bf45a14d..00000000 --- a/Sources/COpenSSL/o_dir.h +++ /dev/null @@ -1,55 +0,0 @@ -/* crypto/o_dir.h */ -/* - * Copied from Richard Levitte's (richard@levitte.org) LP library. All - * symbol names have been changed, with permission from the author. - */ - -/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */ -/* - * Copyright (c) 2004, Richard Levitte - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef O_DIR_H -# define O_DIR_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX; - - /* - * returns NULL on error or end-of-directory. If it is end-of-directory, - * errno will be zero - */ -const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory); - /* returns 1 on success, 0 on error */ -int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx); - -#ifdef __cplusplus -} -#endif - -#endif /* LPDIR_H */ diff --git a/Sources/COpenSSL/o_str.h b/Sources/COpenSSL/o_str.h deleted file mode 100644 index fa512eb3..00000000 --- a/Sources/COpenSSL/o_str.h +++ /dev/null @@ -1,69 +0,0 @@ -/* crypto/o_str.h */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2003. - */ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_O_STR_H -# define HEADER_O_STR_H - -# include /* to get size_t */ - -int OPENSSL_strcasecmp(const char *str1, const char *str2); -int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n); -int OPENSSL_memcmp(const void *p1, const void *p2, size_t n); - -#endif diff --git a/Sources/COpenSSL/o_time.h b/Sources/COpenSSL/o_time.h deleted file mode 100644 index f192c6dc..00000000 --- a/Sources/COpenSSL/o_time.h +++ /dev/null @@ -1,70 +0,0 @@ -/* crypto/o_time.h */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_O_TIME_H -# define HEADER_O_TIME_H - -# include - -struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); -int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); -int OPENSSL_gmtime_diff(int *pday, int *psec, - const struct tm *from, const struct tm *to); - -#endif diff --git a/Sources/COpenSSL/obj_.c b/Sources/COpenSSL/obj_.c deleted file mode 100644 index 8896826e..00000000 --- a/Sources/COpenSSL/obj_.c +++ /dev/null @@ -1,1265 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/objects/obj_dat.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include "cryptlib.h" -#include "lhash.h" -#include "asn1.h" -#include "objects.h" -#include "bn.h" - -/* obj_dat.h is generated from objects.h by obj_dat.pl */ -#ifndef OPENSSL_NO_OBJECT -# include "obj_dat.h" -#else -/* You will have to load all the objects needed manually in the application */ -# define NUM_NID 0 -# define NUM_SN 0 -# define NUM_LN 0 -# define NUM_OBJ 0 -static const unsigned char lvalues[1]; -static const ASN1_OBJECT nid_objs[1]; -static const unsigned int sn_objs[1]; -static const unsigned int ln_objs[1]; -static const unsigned int obj_objs[1]; -#endif - -DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); -DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); -DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); - -#define ADDED_DATA 0 -#define ADDED_SNAME 1 -#define ADDED_LNAME 2 -#define ADDED_NID 3 - -typedef struct added_obj_st { - int type; - ASN1_OBJECT *obj; -} ADDED_OBJ; -DECLARE_LHASH_OF(ADDED_OBJ); - -static int new_nid = NUM_NID; -static LHASH_OF(ADDED_OBJ) *added = NULL; - -static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) -{ - return (strcmp((*a)->sn, nid_objs[*b].sn)); -} - -IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); - -static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) -{ - return (strcmp((*a)->ln, nid_objs[*b].ln)); -} - -IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); - -static unsigned long added_obj_hash(const ADDED_OBJ *ca) -{ - const ASN1_OBJECT *a; - int i; - unsigned long ret = 0; - unsigned char *p; - - a = ca->obj; - switch (ca->type) { - case ADDED_DATA: - ret = a->length << 20L; - p = (unsigned char *)a->data; - for (i = 0; i < a->length; i++) - ret ^= p[i] << ((i * 3) % 24); - break; - case ADDED_SNAME: - ret = lh_strhash(a->sn); - break; - case ADDED_LNAME: - ret = lh_strhash(a->ln); - break; - case ADDED_NID: - ret = a->nid; - break; - default: - /* abort(); */ - return 0; - } - ret &= 0x3fffffffL; - ret |= ((unsigned long)ca->type) << 30L; - return (ret); -} - -static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ) - -static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) -{ - ASN1_OBJECT *a, *b; - int i; - - i = ca->type - cb->type; - if (i) - return (i); - a = ca->obj; - b = cb->obj; - switch (ca->type) { - case ADDED_DATA: - i = (a->length - b->length); - if (i) - return (i); - return (memcmp(a->data, b->data, (size_t)a->length)); - case ADDED_SNAME: - if (a->sn == NULL) - return (-1); - else if (b->sn == NULL) - return (1); - else - return (strcmp(a->sn, b->sn)); - case ADDED_LNAME: - if (a->ln == NULL) - return (-1); - else if (b->ln == NULL) - return (1); - else - return (strcmp(a->ln, b->ln)); - case ADDED_NID: - return (a->nid - b->nid); - default: - /* abort(); */ - return 0; - } -} - -static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ) - -static int init_added(void) -{ - if (added != NULL) - return (1); - added = lh_ADDED_OBJ_new(); - return (added != NULL); -} - -static void cleanup1_doall(ADDED_OBJ *a) -{ - a->obj->nid = 0; - a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC | - ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA; -} - -static void cleanup2_doall(ADDED_OBJ *a) -{ - a->obj->nid++; -} - -static void cleanup3_doall(ADDED_OBJ *a) -{ - if (--a->obj->nid == 0) - ASN1_OBJECT_free(a->obj); - OPENSSL_free(a); -} - -static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ) -static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ) -static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ) - -/* - * The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting to - * use freed up OIDs. If neccessary the actual freeing up of OIDs is delayed. - */ -int obj_cleanup_defer = 0; - -void check_defer(int nid) -{ - if (!obj_cleanup_defer && nid >= NUM_NID) - obj_cleanup_defer = 1; -} - -void OBJ_cleanup(void) -{ - if (obj_cleanup_defer) { - obj_cleanup_defer = 2; - return; - } - if (added == NULL) - return; - lh_ADDED_OBJ_down_load(added) = 0; - lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */ - lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */ - lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */ - lh_ADDED_OBJ_free(added); - added = NULL; -} - -int OBJ_new_nid(int num) -{ - int i; - - i = new_nid; - new_nid += num; - return (i); -} - -int OBJ_add_object(const ASN1_OBJECT *obj) -{ - ASN1_OBJECT *o; - ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop; - int i; - - if (added == NULL) - if (!init_added()) - return (0); - if ((o = OBJ_dup(obj)) == NULL) - goto err; - if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) - goto err2; - if ((o->length != 0) && (obj->data != NULL)) - if (! - (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) - goto err2; - if (o->sn != NULL) - if (! - (ao[ADDED_SNAME] = - (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) - goto err2; - if (o->ln != NULL) - if (! - (ao[ADDED_LNAME] = - (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) - goto err2; - - for (i = ADDED_DATA; i <= ADDED_NID; i++) { - if (ao[i] != NULL) { - ao[i]->type = i; - ao[i]->obj = o; - aop = lh_ADDED_OBJ_insert(added, ao[i]); - /* memory leak, buit should not normally matter */ - if (aop != NULL) - OPENSSL_free(aop); - } - } - o->flags &= - ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | - ASN1_OBJECT_FLAG_DYNAMIC_DATA); - - return (o->nid); - err2: - OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE); - err: - for (i = ADDED_DATA; i <= ADDED_NID; i++) - if (ao[i] != NULL) - OPENSSL_free(ao[i]); - ASN1_OBJECT_free(o); - return NID_undef; -} - -ASN1_OBJECT *OBJ_nid2obj(int n) -{ - ADDED_OBJ ad, *adp; - ASN1_OBJECT ob; - - if ((n >= 0) && (n < NUM_NID)) { - if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { - OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); - return (NULL); - } - return ((ASN1_OBJECT *)&(nid_objs[n])); - } else if (added == NULL) - return (NULL); - else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return (adp->obj); - else { - OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); - return (NULL); - } - } -} - -const char *OBJ_nid2sn(int n) -{ - ADDED_OBJ ad, *adp; - ASN1_OBJECT ob; - - if ((n >= 0) && (n < NUM_NID)) { - if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { - OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); - return (NULL); - } - return (nid_objs[n].sn); - } else if (added == NULL) - return (NULL); - else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return (adp->obj->sn); - else { - OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); - return (NULL); - } - } -} - -const char *OBJ_nid2ln(int n) -{ - ADDED_OBJ ad, *adp; - ASN1_OBJECT ob; - - if ((n >= 0) && (n < NUM_NID)) { - if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { - OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); - return (NULL); - } - return (nid_objs[n].ln); - } else if (added == NULL) - return (NULL); - else { - ad.type = ADDED_NID; - ad.obj = &ob; - ob.nid = n; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return (adp->obj->ln); - else { - OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); - return (NULL); - } - } -} - -static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp) -{ - int j; - const ASN1_OBJECT *a = *ap; - const ASN1_OBJECT *b = &nid_objs[*bp]; - - j = (a->length - b->length); - if (j) - return (j); - if (a->length == 0) - return 0; - return (memcmp(a->data, b->data, a->length)); -} - -IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); - -int OBJ_obj2nid(const ASN1_OBJECT *a) -{ - const unsigned int *op; - ADDED_OBJ ad, *adp; - - if (a == NULL) - return (NID_undef); - if (a->nid != 0) - return (a->nid); - - if (a->length == 0) - return NID_undef; - - if (added != NULL) { - ad.type = ADDED_DATA; - ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return (adp->obj->nid); - } - op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); - if (op == NULL) - return (NID_undef); - return (nid_objs[*op].nid); -} - -/* - * Convert an object name into an ASN1_OBJECT if "noname" is not set then - * search for short and long names first. This will convert the "dotted" form - * into an object: unlike OBJ_txt2nid it can be used with any objects, not - * just registered ones. - */ - -ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) -{ - int nid = NID_undef; - ASN1_OBJECT *op = NULL; - unsigned char *buf; - unsigned char *p; - const unsigned char *cp; - int i, j; - - if (!no_name) { - if (((nid = OBJ_sn2nid(s)) != NID_undef) || - ((nid = OBJ_ln2nid(s)) != NID_undef)) - return OBJ_nid2obj(nid); - } - - /* Work out size of content octets */ - i = a2d_ASN1_OBJECT(NULL, 0, s, -1); - if (i <= 0) { - /* Don't clear the error */ - /* - * ERR_clear_error(); - */ - return NULL; - } - /* Work out total size */ - j = ASN1_object_size(0, i, V_ASN1_OBJECT); - - if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL) - return NULL; - - p = buf; - /* Write out tag+length */ - ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); - /* Write out contents */ - a2d_ASN1_OBJECT(p, i, s, -1); - - cp = buf; - op = d2i_ASN1_OBJECT(NULL, &cp, j); - OPENSSL_free(buf); - return op; -} - -int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) -{ - int i, n = 0, len, nid, first, use_bn; - BIGNUM *bl; - unsigned long l; - const unsigned char *p; - char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2]; - - /* Ensure that, at every state, |buf| is NUL-terminated. */ - if (buf && buf_len > 0) - buf[0] = '\0'; - - if ((a == NULL) || (a->data == NULL)) - return (0); - - if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) { - const char *s; - s = OBJ_nid2ln(nid); - if (s == NULL) - s = OBJ_nid2sn(nid); - if (s) { - if (buf) - BUF_strlcpy(buf, s, buf_len); - n = strlen(s); - return n; - } - } - - len = a->length; - p = a->data; - - first = 1; - bl = NULL; - - while (len > 0) { - l = 0; - use_bn = 0; - for (;;) { - unsigned char c = *p++; - len--; - if ((len == 0) && (c & 0x80)) - goto err; - if (use_bn) { - if (!BN_add_word(bl, c & 0x7f)) - goto err; - } else - l |= c & 0x7f; - if (!(c & 0x80)) - break; - if (!use_bn && (l > (ULONG_MAX >> 7L))) { - if (!bl && !(bl = BN_new())) - goto err; - if (!BN_set_word(bl, l)) - goto err; - use_bn = 1; - } - if (use_bn) { - if (!BN_lshift(bl, bl, 7)) - goto err; - } else - l <<= 7L; - } - - if (first) { - first = 0; - if (l >= 80) { - i = 2; - if (use_bn) { - if (!BN_sub_word(bl, 80)) - goto err; - } else - l -= 80; - } else { - i = (int)(l / 40); - l -= (long)(i * 40); - } - if (buf && (buf_len > 1)) { - *buf++ = i + '0'; - *buf = '\0'; - buf_len--; - } - n++; - } - - if (use_bn) { - char *bndec; - bndec = BN_bn2dec(bl); - if (!bndec) - goto err; - i = strlen(bndec); - if (buf) { - if (buf_len > 1) { - *buf++ = '.'; - *buf = '\0'; - buf_len--; - } - BUF_strlcpy(buf, bndec, buf_len); - if (i > buf_len) { - buf += buf_len; - buf_len = 0; - } else { - buf += i; - buf_len -= i; - } - } - n++; - n += i; - OPENSSL_free(bndec); - } else { - BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l); - i = strlen(tbuf); - if (buf && (buf_len > 0)) { - BUF_strlcpy(buf, tbuf, buf_len); - if (i > buf_len) { - buf += buf_len; - buf_len = 0; - } else { - buf += i; - buf_len -= i; - } - } - n += i; - l = 0; - } - } - - if (bl) - BN_free(bl); - return n; - - err: - if (bl) - BN_free(bl); - return -1; -} - -int OBJ_txt2nid(const char *s) -{ - ASN1_OBJECT *obj; - int nid; - obj = OBJ_txt2obj(s, 0); - nid = OBJ_obj2nid(obj); - ASN1_OBJECT_free(obj); - return nid; -} - -int OBJ_ln2nid(const char *s) -{ - ASN1_OBJECT o; - const ASN1_OBJECT *oo = &o; - ADDED_OBJ ad, *adp; - const unsigned int *op; - - o.ln = s; - if (added != NULL) { - ad.type = ADDED_LNAME; - ad.obj = &o; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return (adp->obj->nid); - } - op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); - if (op == NULL) - return (NID_undef); - return (nid_objs[*op].nid); -} - -int OBJ_sn2nid(const char *s) -{ - ASN1_OBJECT o; - const ASN1_OBJECT *oo = &o; - ADDED_OBJ ad, *adp; - const unsigned int *op; - - o.sn = s; - if (added != NULL) { - ad.type = ADDED_SNAME; - ad.obj = &o; - adp = lh_ADDED_OBJ_retrieve(added, &ad); - if (adp != NULL) - return (adp->obj->nid); - } - op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); - if (op == NULL) - return (NID_undef); - return (nid_objs[*op].nid); -} - -const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, - int (*cmp) (const void *, const void *)) -{ - return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); -} - -const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, - int size, - int (*cmp) (const void *, const void *), - int flags) -{ - const char *base = base_; - int l, h, i = 0, c = 0; - const char *p = NULL; - - if (num == 0) - return (NULL); - l = 0; - h = num; - while (l < h) { - i = (l + h) / 2; - p = &(base[i * size]); - c = (*cmp) (key, p); - if (c < 0) - h = i; - else if (c > 0) - l = i + 1; - else - break; - } -#ifdef CHARSET_EBCDIC - /* - * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I - * don't have perl (yet), we revert to a *LINEAR* search when the object - * wasn't found in the binary search. - */ - if (c != 0) { - for (i = 0; i < num; ++i) { - p = &(base[i * size]); - c = (*cmp) (key, p); - if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))) - return p; - } - } -#endif - if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)) - p = NULL; - else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) { - while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0) - i--; - p = &(base[i * size]); - } - return (p); -} - -/* - * Parse a BIO sink to create some extra oid's objects. - * Line format: - */ -int OBJ_create_objects(BIO *in) -{ - MS_STATIC char buf[512]; - int i, num = 0; - char *o, *s, *l = NULL; - - for (;;) { - s = o = NULL; - i = BIO_gets(in, buf, 512); - if (i <= 0) - return (num); - buf[i - 1] = '\0'; - if (!isalnum((unsigned char)buf[0])) - return (num); - o = s = buf; - while (isdigit((unsigned char)*s) || (*s == '.')) - s++; - if (*s != '\0') { - *(s++) = '\0'; - while (isspace((unsigned char)*s)) - s++; - if (*s == '\0') { - s = NULL; - } else { - l = s; - while ((*l != '\0') && !isspace((unsigned char)*l)) - l++; - if (*l != '\0') { - *(l++) = '\0'; - while (isspace((unsigned char)*l)) - l++; - if (*l == '\0') { - l = NULL; - } - } else { - l = NULL; - } - } - } else { - s = NULL; - } - if (*o == '\0') - return num; - if (!OBJ_create(o, s, l)) - return (num); - num++; - } - /* return(num); */ -} - -int OBJ_create(const char *oid, const char *sn, const char *ln) -{ - int ok = 0; - ASN1_OBJECT *op = NULL; - unsigned char *buf; - int i; - - i = a2d_ASN1_OBJECT(NULL, 0, oid, -1); - if (i <= 0) - return (0); - - if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) { - OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE); - return (0); - } - i = a2d_ASN1_OBJECT(buf, i, oid, -1); - if (i == 0) - goto err; - op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln); - if (op == NULL) - goto err; - ok = OBJ_add_object(op); - err: - ASN1_OBJECT_free(op); - OPENSSL_free(buf); - return (ok); -} -/* crypto/objects/obj_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "objects.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason) - -static ERR_STRING_DATA OBJ_str_functs[] = { - {ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT), "OBJ_add_object"}, - {ERR_FUNC(OBJ_F_OBJ_CREATE), "OBJ_create"}, - {ERR_FUNC(OBJ_F_OBJ_DUP), "OBJ_dup"}, - {ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX), "OBJ_NAME_new_index"}, - {ERR_FUNC(OBJ_F_OBJ_NID2LN), "OBJ_nid2ln"}, - {ERR_FUNC(OBJ_F_OBJ_NID2OBJ), "OBJ_nid2obj"}, - {ERR_FUNC(OBJ_F_OBJ_NID2SN), "OBJ_nid2sn"}, - {0, NULL} -}; - -static ERR_STRING_DATA OBJ_str_reasons[] = { - {ERR_REASON(OBJ_R_MALLOC_FAILURE), "malloc failure"}, - {ERR_REASON(OBJ_R_UNKNOWN_NID), "unknown nid"}, - {0, NULL} -}; - -#endif - -void ERR_load_OBJ_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) { - ERR_load_strings(0, OBJ_str_functs); - ERR_load_strings(0, OBJ_str_reasons); - } -#endif -} -/* crypto/objects/obj_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "lhash.h" -// #include "objects.h" -#include "buffer.h" - -ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) -{ - ASN1_OBJECT *r; - int i; - char *ln = NULL, *sn = NULL; - unsigned char *data = NULL; - - if (o == NULL) - return (NULL); - if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) - return ((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of duplication - * is this??? */ - - r = ASN1_OBJECT_new(); - if (r == NULL) { - OBJerr(OBJ_F_OBJ_DUP, ERR_R_ASN1_LIB); - return (NULL); - } - data = OPENSSL_malloc(o->length); - if (data == NULL) - goto err; - if (o->data != NULL) - memcpy(data, o->data, o->length); - /* once data attached to object it remains const */ - r->data = data; - r->length = o->length; - r->nid = o->nid; - r->ln = r->sn = NULL; - if (o->ln != NULL) { - i = strlen(o->ln) + 1; - ln = OPENSSL_malloc(i); - if (ln == NULL) - goto err; - memcpy(ln, o->ln, i); - r->ln = ln; - } - - if (o->sn != NULL) { - i = strlen(o->sn) + 1; - sn = OPENSSL_malloc(i); - if (sn == NULL) - goto err; - memcpy(sn, o->sn, i); - r->sn = sn; - } - r->flags = o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | - ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | - ASN1_OBJECT_FLAG_DYNAMIC_DATA); - return (r); - err: - OBJerr(OBJ_F_OBJ_DUP, ERR_R_MALLOC_FAILURE); - if (ln != NULL) - OPENSSL_free(ln); - if (sn != NULL) - OPENSSL_free(sn); - if (data != NULL) - OPENSSL_free(data); - if (r != NULL) - OPENSSL_free(r); - return (NULL); -} - -int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) -{ - int ret; - - ret = (a->length - b->length); - if (ret) - return (ret); - return (memcmp(a->data, b->data, a->length)); -} -/* crypto/objects/obj_xref.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "objects.h" -#include "obj_xref.h" - -DECLARE_STACK_OF(nid_triple) -STACK_OF(nid_triple) *sig_app, *sigx_app; - -static int sig_cmp(const nid_triple *a, const nid_triple *b) -{ - return a->sign_id - b->sign_id; -} - -DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); -IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); - -static int sig_sk_cmp(const nid_triple *const *a, const nid_triple *const *b) -{ - return (*a)->sign_id - (*b)->sign_id; -} - -DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); - -static int sigx_cmp(const nid_triple *const *a, const nid_triple *const *b) -{ - int ret; - ret = (*a)->hash_id - (*b)->hash_id; - if (ret) - return ret; - return (*a)->pkey_id - (*b)->pkey_id; -} - -IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); - -int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid) -{ - nid_triple tmp; - const nid_triple *rv = NULL; - tmp.sign_id = signid; - - if (sig_app) { - int idx = sk_nid_triple_find(sig_app, &tmp); - if (idx >= 0) - rv = sk_nid_triple_value(sig_app, idx); - } -#ifndef OBJ_XREF_TEST2 - if (rv == NULL) { - rv = OBJ_bsearch_sig(&tmp, sigoid_srt, - sizeof(sigoid_srt) / sizeof(nid_triple)); - } -#endif - if (rv == NULL) - return 0; - if (pdig_nid) - *pdig_nid = rv->hash_id; - if (ppkey_nid) - *ppkey_nid = rv->pkey_id; - return 1; -} - -int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid) -{ - nid_triple tmp; - const nid_triple *t = &tmp; - const nid_triple **rv = NULL; - - tmp.hash_id = dig_nid; - tmp.pkey_id = pkey_nid; - - if (sigx_app) { - int idx = sk_nid_triple_find(sigx_app, &tmp); - if (idx >= 0) { - t = sk_nid_triple_value(sigx_app, idx); - rv = &t; - } - } -#ifndef OBJ_XREF_TEST2 - if (rv == NULL) { - rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, - sizeof(sigoid_srt_xref) / sizeof(nid_triple *) - ); - } -#endif - if (rv == NULL) - return 0; - if (psignid) - *psignid = (*rv)->sign_id; - return 1; -} - -int OBJ_add_sigid(int signid, int dig_id, int pkey_id) -{ - nid_triple *ntr; - if (!sig_app) - sig_app = sk_nid_triple_new(sig_sk_cmp); - if (!sig_app) - return 0; - if (!sigx_app) - sigx_app = sk_nid_triple_new(sigx_cmp); - if (!sigx_app) - return 0; - ntr = OPENSSL_malloc(sizeof(int) * 3); - if (!ntr) - return 0; - ntr->sign_id = signid; - ntr->hash_id = dig_id; - ntr->pkey_id = pkey_id; - - if (!sk_nid_triple_push(sig_app, ntr)) { - OPENSSL_free(ntr); - return 0; - } - - if (!sk_nid_triple_push(sigx_app, ntr)) - return 0; - - sk_nid_triple_sort(sig_app); - sk_nid_triple_sort(sigx_app); - - return 1; -} - -static void sid_free(nid_triple *tt) -{ - OPENSSL_free(tt); -} - -void OBJ_sigid_free(void) -{ - if (sig_app) { - sk_nid_triple_pop_free(sig_app, sid_free); - sig_app = NULL; - } - if (sigx_app) { - sk_nid_triple_free(sigx_app); - sigx_app = NULL; - } -} - -#ifdef OBJ_XREF_TEST - -main() -{ - int n1, n2, n3; - - int i, rv; -# ifdef OBJ_XREF_TEST2 - for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) { - OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1], sigoid_srt[i][2]); - } -# endif - - for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) { - n1 = sigoid_srt[i][0]; - rv = OBJ_find_sigid_algs(n1, &n2, &n3); - printf("Forward: %d, %s %s %s\n", rv, - OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); - n1 = 0; - rv = OBJ_find_sigid_by_algs(&n1, n2, n3); - printf("Reverse: %d, %s %s %s\n", rv, - OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); - } -} - -#endif diff --git a/Sources/COpenSSL/obj_dat.h b/Sources/COpenSSL/obj_dat.h deleted file mode 100644 index b7e3cf28..00000000 --- a/Sources/COpenSSL/obj_dat.h +++ /dev/null @@ -1,5319 +0,0 @@ -/* crypto/objects/obj_dat.h */ - -/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the - * following command: - * perl obj_dat.pl obj_mac.h obj_dat.h - */ - -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#define NUM_NID 958 -#define NUM_SN 951 -#define NUM_LN 951 -#define NUM_OBJ 890 - -static const unsigned char lvalues[6255]={ -0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05, /* [ 21] OBJ_md5 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04, /* [ 29] OBJ_rc4 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,/* [ 37] OBJ_rsaEncryption */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,/* [ 46] OBJ_md2WithRSAEncryption */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,/* [ 55] OBJ_md5WithRSAEncryption */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,/* [ 64] OBJ_pbeWithMD2AndDES_CBC */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,/* [ 73] OBJ_pbeWithMD5AndDES_CBC */ -0x55, /* [ 82] OBJ_X500 */ -0x55,0x04, /* [ 83] OBJ_X509 */ -0x55,0x04,0x03, /* [ 85] OBJ_commonName */ -0x55,0x04,0x06, /* [ 88] OBJ_countryName */ -0x55,0x04,0x07, /* [ 91] OBJ_localityName */ -0x55,0x04,0x08, /* [ 94] OBJ_stateOrProvinceName */ -0x55,0x04,0x0A, /* [ 97] OBJ_organizationName */ -0x55,0x04,0x0B, /* [100] OBJ_organizationalUnitName */ -0x55,0x08,0x01,0x01, /* [103] OBJ_rsa */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07, /* [107] OBJ_pkcs7 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,/* [115] OBJ_pkcs7_data */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,/* [124] OBJ_pkcs7_signed */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,/* [133] OBJ_pkcs7_enveloped */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,/* [142] OBJ_pkcs7_signedAndEnveloped */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,/* [151] OBJ_pkcs7_digest */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,/* [160] OBJ_pkcs7_encrypted */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03, /* [169] OBJ_pkcs3 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,/* [177] OBJ_dhKeyAgreement */ -0x2B,0x0E,0x03,0x02,0x06, /* [186] OBJ_des_ecb */ -0x2B,0x0E,0x03,0x02,0x09, /* [191] OBJ_des_cfb64 */ -0x2B,0x0E,0x03,0x02,0x07, /* [196] OBJ_des_cbc */ -0x2B,0x0E,0x03,0x02,0x11, /* [201] OBJ_des_ede_ecb */ -0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,/* [206] OBJ_idea_cbc */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02, /* [217] OBJ_rc2_cbc */ -0x2B,0x0E,0x03,0x02,0x12, /* [225] OBJ_sha */ -0x2B,0x0E,0x03,0x02,0x0F, /* [230] OBJ_shaWithRSAEncryption */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07, /* [235] OBJ_des_ede3_cbc */ -0x2B,0x0E,0x03,0x02,0x08, /* [243] OBJ_des_ofb64 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09, /* [248] OBJ_pkcs9 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,/* [256] OBJ_pkcs9_emailAddress */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,/* [265] OBJ_pkcs9_unstructuredName */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,/* [274] OBJ_pkcs9_contentType */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,/* [283] OBJ_pkcs9_messageDigest */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,/* [292] OBJ_pkcs9_signingTime */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,/* [301] OBJ_pkcs9_countersignature */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,/* [310] OBJ_pkcs9_challengePassword */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,/* [319] OBJ_pkcs9_unstructuredAddress */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,/* [328] OBJ_pkcs9_extCertAttributes */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42, /* [337] OBJ_netscape */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01, /* [344] OBJ_netscape_cert_extension */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02, /* [352] OBJ_netscape_data_type */ -0x2B,0x0E,0x03,0x02,0x1A, /* [360] OBJ_sha1 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,/* [365] OBJ_sha1WithRSAEncryption */ -0x2B,0x0E,0x03,0x02,0x0D, /* [374] OBJ_dsaWithSHA */ -0x2B,0x0E,0x03,0x02,0x0C, /* [379] OBJ_dsa_2 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,/* [384] OBJ_pbeWithSHA1AndRC2_CBC */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,/* [393] OBJ_id_pbkdf2 */ -0x2B,0x0E,0x03,0x02,0x1B, /* [402] OBJ_dsaWithSHA1_2 */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,/* [407] OBJ_netscape_cert_type */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,/* [416] OBJ_netscape_base_url */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,/* [425] OBJ_netscape_revocation_url */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,/* [434] OBJ_netscape_ca_revocation_url */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,/* [443] OBJ_netscape_renewal_url */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,/* [452] OBJ_netscape_ca_policy_url */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,/* [461] OBJ_netscape_ssl_server_name */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,/* [470] OBJ_netscape_comment */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,/* [479] OBJ_netscape_cert_sequence */ -0x55,0x1D, /* [488] OBJ_id_ce */ -0x55,0x1D,0x0E, /* [490] OBJ_subject_key_identifier */ -0x55,0x1D,0x0F, /* [493] OBJ_key_usage */ -0x55,0x1D,0x10, /* [496] OBJ_private_key_usage_period */ -0x55,0x1D,0x11, /* [499] OBJ_subject_alt_name */ -0x55,0x1D,0x12, /* [502] OBJ_issuer_alt_name */ -0x55,0x1D,0x13, /* [505] OBJ_basic_constraints */ -0x55,0x1D,0x14, /* [508] OBJ_crl_number */ -0x55,0x1D,0x20, /* [511] OBJ_certificate_policies */ -0x55,0x1D,0x23, /* [514] OBJ_authority_key_identifier */ -0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,/* [517] OBJ_bf_cbc */ -0x55,0x08,0x03,0x65, /* [526] OBJ_mdc2 */ -0x55,0x08,0x03,0x64, /* [530] OBJ_mdc2WithRSA */ -0x55,0x04,0x2A, /* [534] OBJ_givenName */ -0x55,0x04,0x04, /* [537] OBJ_surname */ -0x55,0x04,0x2B, /* [540] OBJ_initials */ -0x55,0x1D,0x1F, /* [543] OBJ_crl_distribution_points */ -0x2B,0x0E,0x03,0x02,0x03, /* [546] OBJ_md5WithRSA */ -0x55,0x04,0x05, /* [551] OBJ_serialNumber */ -0x55,0x04,0x0C, /* [554] OBJ_title */ -0x55,0x04,0x0D, /* [557] OBJ_description */ -0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,/* [560] OBJ_cast5_cbc */ -0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,/* [569] OBJ_pbeWithMD5AndCast5_CBC */ -0x2A,0x86,0x48,0xCE,0x38,0x04,0x03, /* [578] OBJ_dsaWithSHA1 */ -0x2B,0x0E,0x03,0x02,0x1D, /* [585] OBJ_sha1WithRSA */ -0x2A,0x86,0x48,0xCE,0x38,0x04,0x01, /* [590] OBJ_dsa */ -0x2B,0x24,0x03,0x02,0x01, /* [597] OBJ_ripemd160 */ -0x2B,0x24,0x03,0x03,0x01,0x02, /* [602] OBJ_ripemd160WithRSA */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08, /* [608] OBJ_rc5_cbc */ -0x29,0x01,0x01,0x85,0x1A,0x01, /* [616] OBJ_rle_compression */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [622] OBJ_zlib_compression */ -0x55,0x1D,0x25, /* [633] OBJ_ext_key_usage */ -0x2B,0x06,0x01,0x05,0x05,0x07, /* [636] OBJ_id_pkix */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03, /* [642] OBJ_id_kp */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, /* [649] OBJ_server_auth */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02, /* [657] OBJ_client_auth */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03, /* [665] OBJ_code_sign */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04, /* [673] OBJ_email_protect */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08, /* [681] OBJ_time_stamp */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [689] OBJ_ms_code_ind */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [699] OBJ_ms_code_com */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [709] OBJ_ms_ctl_sign */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [719] OBJ_ms_sgc */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [729] OBJ_ms_efs */ -0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [739] OBJ_ns_sgc */ -0x55,0x1D,0x1B, /* [748] OBJ_delta_crl */ -0x55,0x1D,0x15, /* [751] OBJ_crl_reason */ -0x55,0x1D,0x18, /* [754] OBJ_invalidity_date */ -0x2B,0x65,0x01,0x04,0x01, /* [757] OBJ_sxnet */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [762] OBJ_pbe_WithSHA1And128BitRC4 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [772] OBJ_pbe_WithSHA1And40BitRC4 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [782] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [792] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [802] OBJ_pbe_WithSHA1And128BitRC2_CBC */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [812] OBJ_pbe_WithSHA1And40BitRC2_CBC */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [822] OBJ_keyBag */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [833] OBJ_pkcs8ShroudedKeyBag */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [844] OBJ_certBag */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [855] OBJ_crlBag */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [866] OBJ_secretBag */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [877] OBJ_safeContentsBag */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [888] OBJ_friendlyName */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [897] OBJ_localKeyID */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [906] OBJ_x509Certificate */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [916] OBJ_sdsiCertificate */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [926] OBJ_x509Crl */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [936] OBJ_pbes2 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [945] OBJ_pbmac1 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07, /* [954] OBJ_hmacWithSHA1 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01, /* [962] OBJ_id_qt_cps */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02, /* [970] OBJ_id_qt_unotice */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [978] OBJ_SMIMECapabilities */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [987] OBJ_pbeWithMD2AndRC2_CBC */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [996] OBJ_pbeWithMD5AndRC2_CBC */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1005] OBJ_pbeWithSHA1AndDES_CBC */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1014] OBJ_ms_ext_req */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1024] OBJ_ext_req */ -0x55,0x04,0x29, /* [1033] OBJ_name */ -0x55,0x04,0x2E, /* [1036] OBJ_dnQualifier */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01, /* [1039] OBJ_id_pe */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30, /* [1046] OBJ_id_ad */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, /* [1053] OBJ_info_access */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, /* [1061] OBJ_ad_OCSP */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, /* [1069] OBJ_ad_ca_issuers */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09, /* [1077] OBJ_OCSP_sign */ -0x2A, /* [1085] OBJ_member_body */ -0x2A,0x86,0x48, /* [1086] OBJ_ISO_US */ -0x2A,0x86,0x48,0xCE,0x38, /* [1089] OBJ_X9_57 */ -0x2A,0x86,0x48,0xCE,0x38,0x04, /* [1094] OBJ_X9cm */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, /* [1100] OBJ_pkcs1 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05, /* [1108] OBJ_pkcs5 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1116] OBJ_SMIME */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1125] OBJ_id_smime_mod */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1135] OBJ_id_smime_ct */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1145] OBJ_id_smime_aa */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1155] OBJ_id_smime_alg */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1165] OBJ_id_smime_cd */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1175] OBJ_id_smime_spq */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1185] OBJ_id_smime_cti */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1195] OBJ_id_smime_mod_cms */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1206] OBJ_id_smime_mod_ess */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1217] OBJ_id_smime_mod_oid */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1228] OBJ_id_smime_mod_msg_v3 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1239] OBJ_id_smime_mod_ets_eSignature_88 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1250] OBJ_id_smime_mod_ets_eSignature_97 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1261] OBJ_id_smime_mod_ets_eSigPolicy_88 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1272] OBJ_id_smime_mod_ets_eSigPolicy_97 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1283] OBJ_id_smime_ct_receipt */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1294] OBJ_id_smime_ct_authData */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1305] OBJ_id_smime_ct_publishCert */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1316] OBJ_id_smime_ct_TSTInfo */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1327] OBJ_id_smime_ct_TDTInfo */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1338] OBJ_id_smime_ct_contentInfo */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1349] OBJ_id_smime_ct_DVCSRequestData */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1360] OBJ_id_smime_ct_DVCSResponseData */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1371] OBJ_id_smime_aa_receiptRequest */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1382] OBJ_id_smime_aa_securityLabel */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1393] OBJ_id_smime_aa_mlExpandHistory */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1404] OBJ_id_smime_aa_contentHint */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1415] OBJ_id_smime_aa_msgSigDigest */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1426] OBJ_id_smime_aa_encapContentType */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1437] OBJ_id_smime_aa_contentIdentifier */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1448] OBJ_id_smime_aa_macValue */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1459] OBJ_id_smime_aa_equivalentLabels */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1470] OBJ_id_smime_aa_contentReference */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1481] OBJ_id_smime_aa_encrypKeyPref */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1492] OBJ_id_smime_aa_signingCertificate */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1503] OBJ_id_smime_aa_smimeEncryptCerts */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1514] OBJ_id_smime_aa_timeStampToken */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1525] OBJ_id_smime_aa_ets_sigPolicyId */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1536] OBJ_id_smime_aa_ets_commitmentType */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1547] OBJ_id_smime_aa_ets_signerLocation */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1558] OBJ_id_smime_aa_ets_signerAttr */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1569] OBJ_id_smime_aa_ets_otherSigCert */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1580] OBJ_id_smime_aa_ets_contentTimestamp */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1591] OBJ_id_smime_aa_ets_CertificateRefs */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1602] OBJ_id_smime_aa_ets_RevocationRefs */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1613] OBJ_id_smime_aa_ets_certValues */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1624] OBJ_id_smime_aa_ets_revocationValues */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1635] OBJ_id_smime_aa_ets_escTimeStamp */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1646] OBJ_id_smime_aa_ets_certCRLTimestamp */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1657] OBJ_id_smime_aa_ets_archiveTimeStamp */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1668] OBJ_id_smime_aa_signatureType */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1679] OBJ_id_smime_aa_dvcs_dvc */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1690] OBJ_id_smime_alg_ESDHwith3DES */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1701] OBJ_id_smime_alg_ESDHwithRC2 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1712] OBJ_id_smime_alg_3DESwrap */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1723] OBJ_id_smime_alg_RC2wrap */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1734] OBJ_id_smime_alg_ESDH */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1745] OBJ_id_smime_alg_CMS3DESwrap */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1756] OBJ_id_smime_alg_CMSRC2wrap */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1767] OBJ_id_smime_cd_ldap */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1778] OBJ_id_smime_spq_ets_sqt_uri */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1789] OBJ_id_smime_spq_ets_sqt_unotice */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1800] OBJ_id_smime_cti_ets_proofOfOrigin */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1811] OBJ_id_smime_cti_ets_proofOfReceipt */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1822] OBJ_id_smime_cti_ets_proofOfDelivery */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1833] OBJ_id_smime_cti_ets_proofOfSender */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1844] OBJ_id_smime_cti_ets_proofOfApproval */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1855] OBJ_id_smime_cti_ets_proofOfCreation */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04, /* [1866] OBJ_md4 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00, /* [1874] OBJ_id_pkix_mod */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x02, /* [1881] OBJ_id_qt */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04, /* [1888] OBJ_id_it */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05, /* [1895] OBJ_id_pkip */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x06, /* [1902] OBJ_id_alg */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07, /* [1909] OBJ_id_cmc */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x08, /* [1916] OBJ_id_on */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x09, /* [1923] OBJ_id_pda */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0A, /* [1930] OBJ_id_aca */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0B, /* [1937] OBJ_id_qcs */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0C, /* [1944] OBJ_id_cct */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01, /* [1951] OBJ_id_pkix1_explicit_88 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02, /* [1959] OBJ_id_pkix1_implicit_88 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03, /* [1967] OBJ_id_pkix1_explicit_93 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04, /* [1975] OBJ_id_pkix1_implicit_93 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05, /* [1983] OBJ_id_mod_crmf */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06, /* [1991] OBJ_id_mod_cmc */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07, /* [1999] OBJ_id_mod_kea_profile_88 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08, /* [2007] OBJ_id_mod_kea_profile_93 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09, /* [2015] OBJ_id_mod_cmp */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A, /* [2023] OBJ_id_mod_qualified_cert_88 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B, /* [2031] OBJ_id_mod_qualified_cert_93 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C, /* [2039] OBJ_id_mod_attribute_cert */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D, /* [2047] OBJ_id_mod_timestamp_protocol */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E, /* [2055] OBJ_id_mod_ocsp */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F, /* [2063] OBJ_id_mod_dvcs */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10, /* [2071] OBJ_id_mod_cmp2000 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02, /* [2079] OBJ_biometricInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03, /* [2087] OBJ_qcStatements */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04, /* [2095] OBJ_ac_auditEntity */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05, /* [2103] OBJ_ac_targeting */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06, /* [2111] OBJ_aaControls */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07, /* [2119] OBJ_sbgp_ipAddrBlock */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08, /* [2127] OBJ_sbgp_autonomousSysNum */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09, /* [2135] OBJ_sbgp_routerIdentifier */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03, /* [2143] OBJ_textNotice */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05, /* [2151] OBJ_ipsecEndSystem */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06, /* [2159] OBJ_ipsecTunnel */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07, /* [2167] OBJ_ipsecUser */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A, /* [2175] OBJ_dvcs */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01, /* [2183] OBJ_id_it_caProtEncCert */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02, /* [2191] OBJ_id_it_signKeyPairTypes */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03, /* [2199] OBJ_id_it_encKeyPairTypes */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04, /* [2207] OBJ_id_it_preferredSymmAlg */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05, /* [2215] OBJ_id_it_caKeyUpdateInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06, /* [2223] OBJ_id_it_currentCRL */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07, /* [2231] OBJ_id_it_unsupportedOIDs */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08, /* [2239] OBJ_id_it_subscriptionRequest */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09, /* [2247] OBJ_id_it_subscriptionResponse */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A, /* [2255] OBJ_id_it_keyPairParamReq */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B, /* [2263] OBJ_id_it_keyPairParamRep */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C, /* [2271] OBJ_id_it_revPassphrase */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D, /* [2279] OBJ_id_it_implicitConfirm */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E, /* [2287] OBJ_id_it_confirmWaitTime */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F, /* [2295] OBJ_id_it_origPKIMessage */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01, /* [2303] OBJ_id_regCtrl */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02, /* [2311] OBJ_id_regInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2319] OBJ_id_regCtrl_regToken */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2328] OBJ_id_regCtrl_authenticator */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2337] OBJ_id_regCtrl_pkiPublicationInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2346] OBJ_id_regCtrl_pkiArchiveOptions */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2355] OBJ_id_regCtrl_oldCertID */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2364] OBJ_id_regCtrl_protocolEncrKey */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2373] OBJ_id_regInfo_utf8Pairs */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2382] OBJ_id_regInfo_certReq */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01, /* [2391] OBJ_id_alg_des40 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02, /* [2399] OBJ_id_alg_noSignature */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03, /* [2407] OBJ_id_alg_dh_sig_hmac_sha1 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04, /* [2415] OBJ_id_alg_dh_pop */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01, /* [2423] OBJ_id_cmc_statusInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02, /* [2431] OBJ_id_cmc_identification */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03, /* [2439] OBJ_id_cmc_identityProof */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04, /* [2447] OBJ_id_cmc_dataReturn */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05, /* [2455] OBJ_id_cmc_transactionId */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06, /* [2463] OBJ_id_cmc_senderNonce */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07, /* [2471] OBJ_id_cmc_recipientNonce */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08, /* [2479] OBJ_id_cmc_addExtensions */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09, /* [2487] OBJ_id_cmc_encryptedPOP */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A, /* [2495] OBJ_id_cmc_decryptedPOP */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B, /* [2503] OBJ_id_cmc_lraPOPWitness */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F, /* [2511] OBJ_id_cmc_getCert */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10, /* [2519] OBJ_id_cmc_getCRL */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11, /* [2527] OBJ_id_cmc_revokeRequest */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12, /* [2535] OBJ_id_cmc_regInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13, /* [2543] OBJ_id_cmc_responseInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15, /* [2551] OBJ_id_cmc_queryPending */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16, /* [2559] OBJ_id_cmc_popLinkRandom */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17, /* [2567] OBJ_id_cmc_popLinkWitness */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18, /* [2575] OBJ_id_cmc_confirmCertAcceptance */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01, /* [2583] OBJ_id_on_personalData */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01, /* [2591] OBJ_id_pda_dateOfBirth */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02, /* [2599] OBJ_id_pda_placeOfBirth */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03, /* [2607] OBJ_id_pda_gender */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04, /* [2615] OBJ_id_pda_countryOfCitizenship */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05, /* [2623] OBJ_id_pda_countryOfResidence */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01, /* [2631] OBJ_id_aca_authenticationInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02, /* [2639] OBJ_id_aca_accessIdentity */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03, /* [2647] OBJ_id_aca_chargingIdentity */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04, /* [2655] OBJ_id_aca_group */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05, /* [2663] OBJ_id_aca_role */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01, /* [2671] OBJ_id_qcs_pkixQCSyntax_v1 */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01, /* [2679] OBJ_id_cct_crs */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02, /* [2687] OBJ_id_cct_PKIData */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03, /* [2695] OBJ_id_cct_PKIResponse */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03, /* [2703] OBJ_ad_timeStamping */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04, /* [2711] OBJ_ad_dvcs */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2719] OBJ_id_pkix_OCSP_basic */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2728] OBJ_id_pkix_OCSP_Nonce */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2737] OBJ_id_pkix_OCSP_CrlID */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2746] OBJ_id_pkix_OCSP_acceptableResponses */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2755] OBJ_id_pkix_OCSP_noCheck */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2764] OBJ_id_pkix_OCSP_archiveCutoff */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2773] OBJ_id_pkix_OCSP_serviceLocator */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2782] OBJ_id_pkix_OCSP_extendedStatus */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2791] OBJ_id_pkix_OCSP_valid */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2800] OBJ_id_pkix_OCSP_path */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2809] OBJ_id_pkix_OCSP_trustRoot */ -0x2B,0x0E,0x03,0x02, /* [2818] OBJ_algorithm */ -0x2B,0x0E,0x03,0x02,0x0B, /* [2822] OBJ_rsaSignature */ -0x55,0x08, /* [2827] OBJ_X500algorithms */ -0x2B, /* [2829] OBJ_org */ -0x2B,0x06, /* [2830] OBJ_dod */ -0x2B,0x06,0x01, /* [2832] OBJ_iana */ -0x2B,0x06,0x01,0x01, /* [2835] OBJ_Directory */ -0x2B,0x06,0x01,0x02, /* [2839] OBJ_Management */ -0x2B,0x06,0x01,0x03, /* [2843] OBJ_Experimental */ -0x2B,0x06,0x01,0x04, /* [2847] OBJ_Private */ -0x2B,0x06,0x01,0x05, /* [2851] OBJ_Security */ -0x2B,0x06,0x01,0x06, /* [2855] OBJ_SNMPv2 */ -0x2B,0x06,0x01,0x07, /* [2859] OBJ_Mail */ -0x2B,0x06,0x01,0x04,0x01, /* [2863] OBJ_Enterprises */ -0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2868] OBJ_dcObject */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2877] OBJ_domainComponent */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2887] OBJ_Domain */ -0x55,0x01,0x05, /* [2897] OBJ_selected_attribute_types */ -0x55,0x01,0x05,0x37, /* [2900] OBJ_clearance */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2904] OBJ_md4WithRSAEncryption */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A, /* [2913] OBJ_ac_proxying */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B, /* [2921] OBJ_sinfo_access */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06, /* [2929] OBJ_id_aca_encAttrs */ -0x55,0x04,0x48, /* [2937] OBJ_role */ -0x55,0x1D,0x24, /* [2940] OBJ_policy_constraints */ -0x55,0x1D,0x37, /* [2943] OBJ_target_information */ -0x55,0x1D,0x38, /* [2946] OBJ_no_rev_avail */ -0x2A,0x86,0x48,0xCE,0x3D, /* [2949] OBJ_ansi_X9_62 */ -0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01, /* [2954] OBJ_X9_62_prime_field */ -0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02, /* [2961] OBJ_X9_62_characteristic_two_field */ -0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, /* [2968] OBJ_X9_62_id_ecPublicKey */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01, /* [2975] OBJ_X9_62_prime192v1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02, /* [2983] OBJ_X9_62_prime192v2 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03, /* [2991] OBJ_X9_62_prime192v3 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04, /* [2999] OBJ_X9_62_prime239v1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05, /* [3007] OBJ_X9_62_prime239v2 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06, /* [3015] OBJ_X9_62_prime239v3 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07, /* [3023] OBJ_X9_62_prime256v1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01, /* [3031] OBJ_ecdsa_with_SHA1 */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3038] OBJ_ms_csp_name */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3047] OBJ_aes_128_ecb */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3056] OBJ_aes_128_cbc */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3065] OBJ_aes_128_ofb128 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3074] OBJ_aes_128_cfb128 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3083] OBJ_aes_192_ecb */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3092] OBJ_aes_192_cbc */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3101] OBJ_aes_192_ofb128 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3110] OBJ_aes_192_cfb128 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3119] OBJ_aes_256_ecb */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3128] OBJ_aes_256_cbc */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3137] OBJ_aes_256_ofb128 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3146] OBJ_aes_256_cfb128 */ -0x55,0x1D,0x17, /* [3155] OBJ_hold_instruction_code */ -0x2A,0x86,0x48,0xCE,0x38,0x02,0x01, /* [3158] OBJ_hold_instruction_none */ -0x2A,0x86,0x48,0xCE,0x38,0x02,0x02, /* [3165] OBJ_hold_instruction_call_issuer */ -0x2A,0x86,0x48,0xCE,0x38,0x02,0x03, /* [3172] OBJ_hold_instruction_reject */ -0x09, /* [3179] OBJ_data */ -0x09,0x92,0x26, /* [3180] OBJ_pss */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C, /* [3183] OBJ_ucl */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64, /* [3190] OBJ_pilot */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3198] OBJ_pilotAttributeType */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3207] OBJ_pilotAttributeSyntax */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3216] OBJ_pilotObjectClass */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3225] OBJ_pilotGroups */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3234] OBJ_iA5StringSyntax */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3244] OBJ_caseIgnoreIA5StringSyntax */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3254] OBJ_pilotObject */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3264] OBJ_pilotPerson */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3274] OBJ_account */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3284] OBJ_document */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3294] OBJ_room */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3304] OBJ_documentSeries */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3314] OBJ_rFC822localPart */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3324] OBJ_dNSDomain */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3334] OBJ_domainRelatedObject */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3344] OBJ_friendlyCountry */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3354] OBJ_simpleSecurityObject */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3364] OBJ_pilotOrganization */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3374] OBJ_pilotDSA */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3384] OBJ_qualityLabelledData */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3394] OBJ_userId */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3404] OBJ_textEncodedORAddress */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3414] OBJ_rfc822Mailbox */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3424] OBJ_info */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3434] OBJ_favouriteDrink */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3444] OBJ_roomNumber */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3454] OBJ_photo */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3464] OBJ_userClass */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3474] OBJ_host */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3484] OBJ_manager */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3494] OBJ_documentIdentifier */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3504] OBJ_documentTitle */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3514] OBJ_documentVersion */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3524] OBJ_documentAuthor */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3534] OBJ_documentLocation */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3544] OBJ_homeTelephoneNumber */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3554] OBJ_secretary */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3564] OBJ_otherMailbox */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3574] OBJ_lastModifiedTime */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3584] OBJ_lastModifiedBy */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3594] OBJ_aRecord */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3604] OBJ_pilotAttributeType27 */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3614] OBJ_mXRecord */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3624] OBJ_nSRecord */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3634] OBJ_sOARecord */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3644] OBJ_cNAMERecord */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3654] OBJ_associatedDomain */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3664] OBJ_associatedName */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3674] OBJ_homePostalAddress */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3684] OBJ_personalTitle */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3694] OBJ_mobileTelephoneNumber */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3704] OBJ_pagerTelephoneNumber */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3714] OBJ_friendlyCountryName */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3724] OBJ_organizationalStatus */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3734] OBJ_janetMailbox */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3744] OBJ_mailPreferenceOption */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3754] OBJ_buildingName */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3764] OBJ_dSAQuality */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3774] OBJ_singleLevelQuality */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3784] OBJ_subtreeMinimumQuality */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3794] OBJ_subtreeMaximumQuality */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3804] OBJ_personalSignature */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3814] OBJ_dITRedirect */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3824] OBJ_audio */ -0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3834] OBJ_documentPublisher */ -0x55,0x04,0x2D, /* [3844] OBJ_x500UniqueIdentifier */ -0x2B,0x06,0x01,0x07,0x01, /* [3847] OBJ_mime_mhs */ -0x2B,0x06,0x01,0x07,0x01,0x01, /* [3852] OBJ_mime_mhs_headings */ -0x2B,0x06,0x01,0x07,0x01,0x02, /* [3858] OBJ_mime_mhs_bodies */ -0x2B,0x06,0x01,0x07,0x01,0x01,0x01, /* [3864] OBJ_id_hex_partial_message */ -0x2B,0x06,0x01,0x07,0x01,0x01,0x02, /* [3871] OBJ_id_hex_multipart_message */ -0x55,0x04,0x2C, /* [3878] OBJ_generationQualifier */ -0x55,0x04,0x41, /* [3881] OBJ_pseudonym */ -0x67,0x2A, /* [3884] OBJ_id_set */ -0x67,0x2A,0x00, /* [3886] OBJ_set_ctype */ -0x67,0x2A,0x01, /* [3889] OBJ_set_msgExt */ -0x67,0x2A,0x03, /* [3892] OBJ_set_attr */ -0x67,0x2A,0x05, /* [3895] OBJ_set_policy */ -0x67,0x2A,0x07, /* [3898] OBJ_set_certExt */ -0x67,0x2A,0x08, /* [3901] OBJ_set_brand */ -0x67,0x2A,0x00,0x00, /* [3904] OBJ_setct_PANData */ -0x67,0x2A,0x00,0x01, /* [3908] OBJ_setct_PANToken */ -0x67,0x2A,0x00,0x02, /* [3912] OBJ_setct_PANOnly */ -0x67,0x2A,0x00,0x03, /* [3916] OBJ_setct_OIData */ -0x67,0x2A,0x00,0x04, /* [3920] OBJ_setct_PI */ -0x67,0x2A,0x00,0x05, /* [3924] OBJ_setct_PIData */ -0x67,0x2A,0x00,0x06, /* [3928] OBJ_setct_PIDataUnsigned */ -0x67,0x2A,0x00,0x07, /* [3932] OBJ_setct_HODInput */ -0x67,0x2A,0x00,0x08, /* [3936] OBJ_setct_AuthResBaggage */ -0x67,0x2A,0x00,0x09, /* [3940] OBJ_setct_AuthRevReqBaggage */ -0x67,0x2A,0x00,0x0A, /* [3944] OBJ_setct_AuthRevResBaggage */ -0x67,0x2A,0x00,0x0B, /* [3948] OBJ_setct_CapTokenSeq */ -0x67,0x2A,0x00,0x0C, /* [3952] OBJ_setct_PInitResData */ -0x67,0x2A,0x00,0x0D, /* [3956] OBJ_setct_PI_TBS */ -0x67,0x2A,0x00,0x0E, /* [3960] OBJ_setct_PResData */ -0x67,0x2A,0x00,0x10, /* [3964] OBJ_setct_AuthReqTBS */ -0x67,0x2A,0x00,0x11, /* [3968] OBJ_setct_AuthResTBS */ -0x67,0x2A,0x00,0x12, /* [3972] OBJ_setct_AuthResTBSX */ -0x67,0x2A,0x00,0x13, /* [3976] OBJ_setct_AuthTokenTBS */ -0x67,0x2A,0x00,0x14, /* [3980] OBJ_setct_CapTokenData */ -0x67,0x2A,0x00,0x15, /* [3984] OBJ_setct_CapTokenTBS */ -0x67,0x2A,0x00,0x16, /* [3988] OBJ_setct_AcqCardCodeMsg */ -0x67,0x2A,0x00,0x17, /* [3992] OBJ_setct_AuthRevReqTBS */ -0x67,0x2A,0x00,0x18, /* [3996] OBJ_setct_AuthRevResData */ -0x67,0x2A,0x00,0x19, /* [4000] OBJ_setct_AuthRevResTBS */ -0x67,0x2A,0x00,0x1A, /* [4004] OBJ_setct_CapReqTBS */ -0x67,0x2A,0x00,0x1B, /* [4008] OBJ_setct_CapReqTBSX */ -0x67,0x2A,0x00,0x1C, /* [4012] OBJ_setct_CapResData */ -0x67,0x2A,0x00,0x1D, /* [4016] OBJ_setct_CapRevReqTBS */ -0x67,0x2A,0x00,0x1E, /* [4020] OBJ_setct_CapRevReqTBSX */ -0x67,0x2A,0x00,0x1F, /* [4024] OBJ_setct_CapRevResData */ -0x67,0x2A,0x00,0x20, /* [4028] OBJ_setct_CredReqTBS */ -0x67,0x2A,0x00,0x21, /* [4032] OBJ_setct_CredReqTBSX */ -0x67,0x2A,0x00,0x22, /* [4036] OBJ_setct_CredResData */ -0x67,0x2A,0x00,0x23, /* [4040] OBJ_setct_CredRevReqTBS */ -0x67,0x2A,0x00,0x24, /* [4044] OBJ_setct_CredRevReqTBSX */ -0x67,0x2A,0x00,0x25, /* [4048] OBJ_setct_CredRevResData */ -0x67,0x2A,0x00,0x26, /* [4052] OBJ_setct_PCertReqData */ -0x67,0x2A,0x00,0x27, /* [4056] OBJ_setct_PCertResTBS */ -0x67,0x2A,0x00,0x28, /* [4060] OBJ_setct_BatchAdminReqData */ -0x67,0x2A,0x00,0x29, /* [4064] OBJ_setct_BatchAdminResData */ -0x67,0x2A,0x00,0x2A, /* [4068] OBJ_setct_CardCInitResTBS */ -0x67,0x2A,0x00,0x2B, /* [4072] OBJ_setct_MeAqCInitResTBS */ -0x67,0x2A,0x00,0x2C, /* [4076] OBJ_setct_RegFormResTBS */ -0x67,0x2A,0x00,0x2D, /* [4080] OBJ_setct_CertReqData */ -0x67,0x2A,0x00,0x2E, /* [4084] OBJ_setct_CertReqTBS */ -0x67,0x2A,0x00,0x2F, /* [4088] OBJ_setct_CertResData */ -0x67,0x2A,0x00,0x30, /* [4092] OBJ_setct_CertInqReqTBS */ -0x67,0x2A,0x00,0x31, /* [4096] OBJ_setct_ErrorTBS */ -0x67,0x2A,0x00,0x32, /* [4100] OBJ_setct_PIDualSignedTBE */ -0x67,0x2A,0x00,0x33, /* [4104] OBJ_setct_PIUnsignedTBE */ -0x67,0x2A,0x00,0x34, /* [4108] OBJ_setct_AuthReqTBE */ -0x67,0x2A,0x00,0x35, /* [4112] OBJ_setct_AuthResTBE */ -0x67,0x2A,0x00,0x36, /* [4116] OBJ_setct_AuthResTBEX */ -0x67,0x2A,0x00,0x37, /* [4120] OBJ_setct_AuthTokenTBE */ -0x67,0x2A,0x00,0x38, /* [4124] OBJ_setct_CapTokenTBE */ -0x67,0x2A,0x00,0x39, /* [4128] OBJ_setct_CapTokenTBEX */ -0x67,0x2A,0x00,0x3A, /* [4132] OBJ_setct_AcqCardCodeMsgTBE */ -0x67,0x2A,0x00,0x3B, /* [4136] OBJ_setct_AuthRevReqTBE */ -0x67,0x2A,0x00,0x3C, /* [4140] OBJ_setct_AuthRevResTBE */ -0x67,0x2A,0x00,0x3D, /* [4144] OBJ_setct_AuthRevResTBEB */ -0x67,0x2A,0x00,0x3E, /* [4148] OBJ_setct_CapReqTBE */ -0x67,0x2A,0x00,0x3F, /* [4152] OBJ_setct_CapReqTBEX */ -0x67,0x2A,0x00,0x40, /* [4156] OBJ_setct_CapResTBE */ -0x67,0x2A,0x00,0x41, /* [4160] OBJ_setct_CapRevReqTBE */ -0x67,0x2A,0x00,0x42, /* [4164] OBJ_setct_CapRevReqTBEX */ -0x67,0x2A,0x00,0x43, /* [4168] OBJ_setct_CapRevResTBE */ -0x67,0x2A,0x00,0x44, /* [4172] OBJ_setct_CredReqTBE */ -0x67,0x2A,0x00,0x45, /* [4176] OBJ_setct_CredReqTBEX */ -0x67,0x2A,0x00,0x46, /* [4180] OBJ_setct_CredResTBE */ -0x67,0x2A,0x00,0x47, /* [4184] OBJ_setct_CredRevReqTBE */ -0x67,0x2A,0x00,0x48, /* [4188] OBJ_setct_CredRevReqTBEX */ -0x67,0x2A,0x00,0x49, /* [4192] OBJ_setct_CredRevResTBE */ -0x67,0x2A,0x00,0x4A, /* [4196] OBJ_setct_BatchAdminReqTBE */ -0x67,0x2A,0x00,0x4B, /* [4200] OBJ_setct_BatchAdminResTBE */ -0x67,0x2A,0x00,0x4C, /* [4204] OBJ_setct_RegFormReqTBE */ -0x67,0x2A,0x00,0x4D, /* [4208] OBJ_setct_CertReqTBE */ -0x67,0x2A,0x00,0x4E, /* [4212] OBJ_setct_CertReqTBEX */ -0x67,0x2A,0x00,0x4F, /* [4216] OBJ_setct_CertResTBE */ -0x67,0x2A,0x00,0x50, /* [4220] OBJ_setct_CRLNotificationTBS */ -0x67,0x2A,0x00,0x51, /* [4224] OBJ_setct_CRLNotificationResTBS */ -0x67,0x2A,0x00,0x52, /* [4228] OBJ_setct_BCIDistributionTBS */ -0x67,0x2A,0x01,0x01, /* [4232] OBJ_setext_genCrypt */ -0x67,0x2A,0x01,0x03, /* [4236] OBJ_setext_miAuth */ -0x67,0x2A,0x01,0x04, /* [4240] OBJ_setext_pinSecure */ -0x67,0x2A,0x01,0x05, /* [4244] OBJ_setext_pinAny */ -0x67,0x2A,0x01,0x07, /* [4248] OBJ_setext_track2 */ -0x67,0x2A,0x01,0x08, /* [4252] OBJ_setext_cv */ -0x67,0x2A,0x05,0x00, /* [4256] OBJ_set_policy_root */ -0x67,0x2A,0x07,0x00, /* [4260] OBJ_setCext_hashedRoot */ -0x67,0x2A,0x07,0x01, /* [4264] OBJ_setCext_certType */ -0x67,0x2A,0x07,0x02, /* [4268] OBJ_setCext_merchData */ -0x67,0x2A,0x07,0x03, /* [4272] OBJ_setCext_cCertRequired */ -0x67,0x2A,0x07,0x04, /* [4276] OBJ_setCext_tunneling */ -0x67,0x2A,0x07,0x05, /* [4280] OBJ_setCext_setExt */ -0x67,0x2A,0x07,0x06, /* [4284] OBJ_setCext_setQualf */ -0x67,0x2A,0x07,0x07, /* [4288] OBJ_setCext_PGWYcapabilities */ -0x67,0x2A,0x07,0x08, /* [4292] OBJ_setCext_TokenIdentifier */ -0x67,0x2A,0x07,0x09, /* [4296] OBJ_setCext_Track2Data */ -0x67,0x2A,0x07,0x0A, /* [4300] OBJ_setCext_TokenType */ -0x67,0x2A,0x07,0x0B, /* [4304] OBJ_setCext_IssuerCapabilities */ -0x67,0x2A,0x03,0x00, /* [4308] OBJ_setAttr_Cert */ -0x67,0x2A,0x03,0x01, /* [4312] OBJ_setAttr_PGWYcap */ -0x67,0x2A,0x03,0x02, /* [4316] OBJ_setAttr_TokenType */ -0x67,0x2A,0x03,0x03, /* [4320] OBJ_setAttr_IssCap */ -0x67,0x2A,0x03,0x00,0x00, /* [4324] OBJ_set_rootKeyThumb */ -0x67,0x2A,0x03,0x00,0x01, /* [4329] OBJ_set_addPolicy */ -0x67,0x2A,0x03,0x02,0x01, /* [4334] OBJ_setAttr_Token_EMV */ -0x67,0x2A,0x03,0x02,0x02, /* [4339] OBJ_setAttr_Token_B0Prime */ -0x67,0x2A,0x03,0x03,0x03, /* [4344] OBJ_setAttr_IssCap_CVM */ -0x67,0x2A,0x03,0x03,0x04, /* [4349] OBJ_setAttr_IssCap_T2 */ -0x67,0x2A,0x03,0x03,0x05, /* [4354] OBJ_setAttr_IssCap_Sig */ -0x67,0x2A,0x03,0x03,0x03,0x01, /* [4359] OBJ_setAttr_GenCryptgrm */ -0x67,0x2A,0x03,0x03,0x04,0x01, /* [4365] OBJ_setAttr_T2Enc */ -0x67,0x2A,0x03,0x03,0x04,0x02, /* [4371] OBJ_setAttr_T2cleartxt */ -0x67,0x2A,0x03,0x03,0x05,0x01, /* [4377] OBJ_setAttr_TokICCsig */ -0x67,0x2A,0x03,0x03,0x05,0x02, /* [4383] OBJ_setAttr_SecDevSig */ -0x67,0x2A,0x08,0x01, /* [4389] OBJ_set_brand_IATA_ATA */ -0x67,0x2A,0x08,0x1E, /* [4393] OBJ_set_brand_Diners */ -0x67,0x2A,0x08,0x22, /* [4397] OBJ_set_brand_AmericanExpress */ -0x67,0x2A,0x08,0x23, /* [4401] OBJ_set_brand_JCB */ -0x67,0x2A,0x08,0x04, /* [4405] OBJ_set_brand_Visa */ -0x67,0x2A,0x08,0x05, /* [4409] OBJ_set_brand_MasterCard */ -0x67,0x2A,0x08,0xAE,0x7B, /* [4413] OBJ_set_brand_Novus */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A, /* [4418] OBJ_des_cdmf */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4426] OBJ_rsaOAEPEncryptionSET */ -0x67, /* [4435] OBJ_international_organizations */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4436] OBJ_ms_smartcard_login */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4446] OBJ_ms_upn */ -0x55,0x04,0x09, /* [4456] OBJ_streetAddress */ -0x55,0x04,0x11, /* [4459] OBJ_postalCode */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x15, /* [4462] OBJ_id_ppl */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E, /* [4469] OBJ_proxyCertInfo */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00, /* [4477] OBJ_id_ppl_anyLanguage */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01, /* [4485] OBJ_id_ppl_inheritAll */ -0x55,0x1D,0x1E, /* [4493] OBJ_name_constraints */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02, /* [4496] OBJ_Independent */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4504] OBJ_sha256WithRSAEncryption */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4513] OBJ_sha384WithRSAEncryption */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4522] OBJ_sha512WithRSAEncryption */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4531] OBJ_sha224WithRSAEncryption */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4540] OBJ_sha256 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4549] OBJ_sha384 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4558] OBJ_sha512 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4567] OBJ_sha224 */ -0x2B, /* [4576] OBJ_identified_organization */ -0x2B,0x81,0x04, /* [4577] OBJ_certicom_arc */ -0x67,0x2B, /* [4580] OBJ_wap */ -0x67,0x2B,0x01, /* [4582] OBJ_wap_wsg */ -0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03, /* [4585] OBJ_X9_62_id_characteristic_two_basis */ -0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4593] OBJ_X9_62_onBasis */ -0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4602] OBJ_X9_62_tpBasis */ -0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4611] OBJ_X9_62_ppBasis */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01, /* [4620] OBJ_X9_62_c2pnb163v1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02, /* [4628] OBJ_X9_62_c2pnb163v2 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03, /* [4636] OBJ_X9_62_c2pnb163v3 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04, /* [4644] OBJ_X9_62_c2pnb176v1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05, /* [4652] OBJ_X9_62_c2tnb191v1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06, /* [4660] OBJ_X9_62_c2tnb191v2 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07, /* [4668] OBJ_X9_62_c2tnb191v3 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08, /* [4676] OBJ_X9_62_c2onb191v4 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09, /* [4684] OBJ_X9_62_c2onb191v5 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A, /* [4692] OBJ_X9_62_c2pnb208w1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B, /* [4700] OBJ_X9_62_c2tnb239v1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C, /* [4708] OBJ_X9_62_c2tnb239v2 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D, /* [4716] OBJ_X9_62_c2tnb239v3 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E, /* [4724] OBJ_X9_62_c2onb239v4 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F, /* [4732] OBJ_X9_62_c2onb239v5 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10, /* [4740] OBJ_X9_62_c2pnb272w1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11, /* [4748] OBJ_X9_62_c2pnb304w1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12, /* [4756] OBJ_X9_62_c2tnb359v1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13, /* [4764] OBJ_X9_62_c2pnb368w1 */ -0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14, /* [4772] OBJ_X9_62_c2tnb431r1 */ -0x2B,0x81,0x04,0x00,0x06, /* [4780] OBJ_secp112r1 */ -0x2B,0x81,0x04,0x00,0x07, /* [4785] OBJ_secp112r2 */ -0x2B,0x81,0x04,0x00,0x1C, /* [4790] OBJ_secp128r1 */ -0x2B,0x81,0x04,0x00,0x1D, /* [4795] OBJ_secp128r2 */ -0x2B,0x81,0x04,0x00,0x09, /* [4800] OBJ_secp160k1 */ -0x2B,0x81,0x04,0x00,0x08, /* [4805] OBJ_secp160r1 */ -0x2B,0x81,0x04,0x00,0x1E, /* [4810] OBJ_secp160r2 */ -0x2B,0x81,0x04,0x00,0x1F, /* [4815] OBJ_secp192k1 */ -0x2B,0x81,0x04,0x00,0x20, /* [4820] OBJ_secp224k1 */ -0x2B,0x81,0x04,0x00,0x21, /* [4825] OBJ_secp224r1 */ -0x2B,0x81,0x04,0x00,0x0A, /* [4830] OBJ_secp256k1 */ -0x2B,0x81,0x04,0x00,0x22, /* [4835] OBJ_secp384r1 */ -0x2B,0x81,0x04,0x00,0x23, /* [4840] OBJ_secp521r1 */ -0x2B,0x81,0x04,0x00,0x04, /* [4845] OBJ_sect113r1 */ -0x2B,0x81,0x04,0x00,0x05, /* [4850] OBJ_sect113r2 */ -0x2B,0x81,0x04,0x00,0x16, /* [4855] OBJ_sect131r1 */ -0x2B,0x81,0x04,0x00,0x17, /* [4860] OBJ_sect131r2 */ -0x2B,0x81,0x04,0x00,0x01, /* [4865] OBJ_sect163k1 */ -0x2B,0x81,0x04,0x00,0x02, /* [4870] OBJ_sect163r1 */ -0x2B,0x81,0x04,0x00,0x0F, /* [4875] OBJ_sect163r2 */ -0x2B,0x81,0x04,0x00,0x18, /* [4880] OBJ_sect193r1 */ -0x2B,0x81,0x04,0x00,0x19, /* [4885] OBJ_sect193r2 */ -0x2B,0x81,0x04,0x00,0x1A, /* [4890] OBJ_sect233k1 */ -0x2B,0x81,0x04,0x00,0x1B, /* [4895] OBJ_sect233r1 */ -0x2B,0x81,0x04,0x00,0x03, /* [4900] OBJ_sect239k1 */ -0x2B,0x81,0x04,0x00,0x10, /* [4905] OBJ_sect283k1 */ -0x2B,0x81,0x04,0x00,0x11, /* [4910] OBJ_sect283r1 */ -0x2B,0x81,0x04,0x00,0x24, /* [4915] OBJ_sect409k1 */ -0x2B,0x81,0x04,0x00,0x25, /* [4920] OBJ_sect409r1 */ -0x2B,0x81,0x04,0x00,0x26, /* [4925] OBJ_sect571k1 */ -0x2B,0x81,0x04,0x00,0x27, /* [4930] OBJ_sect571r1 */ -0x67,0x2B,0x01,0x04,0x01, /* [4935] OBJ_wap_wsg_idm_ecid_wtls1 */ -0x67,0x2B,0x01,0x04,0x03, /* [4940] OBJ_wap_wsg_idm_ecid_wtls3 */ -0x67,0x2B,0x01,0x04,0x04, /* [4945] OBJ_wap_wsg_idm_ecid_wtls4 */ -0x67,0x2B,0x01,0x04,0x05, /* [4950] OBJ_wap_wsg_idm_ecid_wtls5 */ -0x67,0x2B,0x01,0x04,0x06, /* [4955] OBJ_wap_wsg_idm_ecid_wtls6 */ -0x67,0x2B,0x01,0x04,0x07, /* [4960] OBJ_wap_wsg_idm_ecid_wtls7 */ -0x67,0x2B,0x01,0x04,0x08, /* [4965] OBJ_wap_wsg_idm_ecid_wtls8 */ -0x67,0x2B,0x01,0x04,0x09, /* [4970] OBJ_wap_wsg_idm_ecid_wtls9 */ -0x67,0x2B,0x01,0x04,0x0A, /* [4975] OBJ_wap_wsg_idm_ecid_wtls10 */ -0x67,0x2B,0x01,0x04,0x0B, /* [4980] OBJ_wap_wsg_idm_ecid_wtls11 */ -0x67,0x2B,0x01,0x04,0x0C, /* [4985] OBJ_wap_wsg_idm_ecid_wtls12 */ -0x55,0x1D,0x20,0x00, /* [4990] OBJ_any_policy */ -0x55,0x1D,0x21, /* [4994] OBJ_policy_mappings */ -0x55,0x1D,0x36, /* [4997] OBJ_inhibit_any_policy */ -0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5000] OBJ_camellia_128_cbc */ -0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5011] OBJ_camellia_192_cbc */ -0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5022] OBJ_camellia_256_cbc */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01, /* [5033] OBJ_camellia_128_ecb */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15, /* [5041] OBJ_camellia_192_ecb */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29, /* [5049] OBJ_camellia_256_ecb */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04, /* [5057] OBJ_camellia_128_cfb128 */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18, /* [5065] OBJ_camellia_192_cfb128 */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C, /* [5073] OBJ_camellia_256_cfb128 */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03, /* [5081] OBJ_camellia_128_ofb128 */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17, /* [5089] OBJ_camellia_192_ofb128 */ -0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B, /* [5097] OBJ_camellia_256_ofb128 */ -0x55,0x1D,0x09, /* [5105] OBJ_subject_directory_attributes */ -0x55,0x1D,0x1C, /* [5108] OBJ_issuing_distribution_point */ -0x55,0x1D,0x1D, /* [5111] OBJ_certificate_issuer */ -0x2A,0x83,0x1A,0x8C,0x9A,0x44, /* [5114] OBJ_kisa */ -0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03, /* [5120] OBJ_seed_ecb */ -0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04, /* [5128] OBJ_seed_cbc */ -0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06, /* [5136] OBJ_seed_ofb128 */ -0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05, /* [5144] OBJ_seed_cfb128 */ -0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01, /* [5152] OBJ_hmac_md5 */ -0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02, /* [5160] OBJ_hmac_sha1 */ -0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5168] OBJ_id_PasswordBasedMAC */ -0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5177] OBJ_id_DHBasedMac */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10, /* [5186] OBJ_id_it_suppLangTags */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05, /* [5194] OBJ_caRepository */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5202] OBJ_id_smime_ct_compressedData */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5213] OBJ_id_ct_asciiTextWithCRLF */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5224] OBJ_id_aes128_wrap */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5233] OBJ_id_aes192_wrap */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5242] OBJ_id_aes256_wrap */ -0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02, /* [5251] OBJ_ecdsa_with_Recommended */ -0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, /* [5258] OBJ_ecdsa_with_Specified */ -0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01, /* [5265] OBJ_ecdsa_with_SHA224 */ -0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02, /* [5273] OBJ_ecdsa_with_SHA256 */ -0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03, /* [5281] OBJ_ecdsa_with_SHA384 */ -0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04, /* [5289] OBJ_ecdsa_with_SHA512 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06, /* [5297] OBJ_hmacWithMD5 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08, /* [5305] OBJ_hmacWithSHA224 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09, /* [5313] OBJ_hmacWithSHA256 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A, /* [5321] OBJ_hmacWithSHA384 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B, /* [5329] OBJ_hmacWithSHA512 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5337] OBJ_dsa_with_SHA224 */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5346] OBJ_dsa_with_SHA256 */ -0x28,0xCF,0x06,0x03,0x00,0x37, /* [5355] OBJ_whirlpool */ -0x2A,0x85,0x03,0x02,0x02, /* [5361] OBJ_cryptopro */ -0x2A,0x85,0x03,0x02,0x09, /* [5366] OBJ_cryptocom */ -0x2A,0x85,0x03,0x02,0x02,0x03, /* [5371] OBJ_id_GostR3411_94_with_GostR3410_2001 */ -0x2A,0x85,0x03,0x02,0x02,0x04, /* [5377] OBJ_id_GostR3411_94_with_GostR3410_94 */ -0x2A,0x85,0x03,0x02,0x02,0x09, /* [5383] OBJ_id_GostR3411_94 */ -0x2A,0x85,0x03,0x02,0x02,0x0A, /* [5389] OBJ_id_HMACGostR3411_94 */ -0x2A,0x85,0x03,0x02,0x02,0x13, /* [5395] OBJ_id_GostR3410_2001 */ -0x2A,0x85,0x03,0x02,0x02,0x14, /* [5401] OBJ_id_GostR3410_94 */ -0x2A,0x85,0x03,0x02,0x02,0x15, /* [5407] OBJ_id_Gost28147_89 */ -0x2A,0x85,0x03,0x02,0x02,0x16, /* [5413] OBJ_id_Gost28147_89_MAC */ -0x2A,0x85,0x03,0x02,0x02,0x17, /* [5419] OBJ_id_GostR3411_94_prf */ -0x2A,0x85,0x03,0x02,0x02,0x62, /* [5425] OBJ_id_GostR3410_2001DH */ -0x2A,0x85,0x03,0x02,0x02,0x63, /* [5431] OBJ_id_GostR3410_94DH */ -0x2A,0x85,0x03,0x02,0x02,0x0E,0x01, /* [5437] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */ -0x2A,0x85,0x03,0x02,0x02,0x0E,0x00, /* [5444] OBJ_id_Gost28147_89_None_KeyMeshing */ -0x2A,0x85,0x03,0x02,0x02,0x1E,0x00, /* [5451] OBJ_id_GostR3411_94_TestParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1E,0x01, /* [5458] OBJ_id_GostR3411_94_CryptoProParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1F,0x00, /* [5465] OBJ_id_Gost28147_89_TestParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1F,0x01, /* [5472] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1F,0x02, /* [5479] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1F,0x03, /* [5486] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1F,0x04, /* [5493] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1F,0x05, /* [5500] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1F,0x06, /* [5507] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x1F,0x07, /* [5514] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x20,0x00, /* [5521] OBJ_id_GostR3410_94_TestParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x20,0x02, /* [5528] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x20,0x03, /* [5535] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x20,0x04, /* [5542] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x20,0x05, /* [5549] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x21,0x01, /* [5556] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x21,0x02, /* [5563] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x21,0x03, /* [5570] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x23,0x00, /* [5577] OBJ_id_GostR3410_2001_TestParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x23,0x01, /* [5584] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x23,0x02, /* [5591] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x23,0x03, /* [5598] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x24,0x00, /* [5605] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x24,0x01, /* [5612] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */ -0x2A,0x85,0x03,0x02,0x02,0x14,0x01, /* [5619] OBJ_id_GostR3410_94_a */ -0x2A,0x85,0x03,0x02,0x02,0x14,0x02, /* [5626] OBJ_id_GostR3410_94_aBis */ -0x2A,0x85,0x03,0x02,0x02,0x14,0x03, /* [5633] OBJ_id_GostR3410_94_b */ -0x2A,0x85,0x03,0x02,0x02,0x14,0x04, /* [5640] OBJ_id_GostR3410_94_bBis */ -0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01, /* [5647] OBJ_id_Gost28147_89_cc */ -0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03, /* [5655] OBJ_id_GostR3410_94_cc */ -0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04, /* [5663] OBJ_id_GostR3410_2001_cc */ -0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03, /* [5671] OBJ_id_GostR3411_94_with_GostR3410_94_cc */ -0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04, /* [5679] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */ -0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01, /* [5687] OBJ_id_GostR3410_2001_ParamSet_cc */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5695] OBJ_LocalKeySet */ -0x55,0x1D,0x2E, /* [5704] OBJ_freshest_crl */ -0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03, /* [5707] OBJ_id_on_permanentIdentifier */ -0x55,0x04,0x0E, /* [5715] OBJ_searchGuide */ -0x55,0x04,0x0F, /* [5718] OBJ_businessCategory */ -0x55,0x04,0x10, /* [5721] OBJ_postalAddress */ -0x55,0x04,0x12, /* [5724] OBJ_postOfficeBox */ -0x55,0x04,0x13, /* [5727] OBJ_physicalDeliveryOfficeName */ -0x55,0x04,0x14, /* [5730] OBJ_telephoneNumber */ -0x55,0x04,0x15, /* [5733] OBJ_telexNumber */ -0x55,0x04,0x16, /* [5736] OBJ_teletexTerminalIdentifier */ -0x55,0x04,0x17, /* [5739] OBJ_facsimileTelephoneNumber */ -0x55,0x04,0x18, /* [5742] OBJ_x121Address */ -0x55,0x04,0x19, /* [5745] OBJ_internationaliSDNNumber */ -0x55,0x04,0x1A, /* [5748] OBJ_registeredAddress */ -0x55,0x04,0x1B, /* [5751] OBJ_destinationIndicator */ -0x55,0x04,0x1C, /* [5754] OBJ_preferredDeliveryMethod */ -0x55,0x04,0x1D, /* [5757] OBJ_presentationAddress */ -0x55,0x04,0x1E, /* [5760] OBJ_supportedApplicationContext */ -0x55,0x04,0x1F, /* [5763] OBJ_member */ -0x55,0x04,0x20, /* [5766] OBJ_owner */ -0x55,0x04,0x21, /* [5769] OBJ_roleOccupant */ -0x55,0x04,0x22, /* [5772] OBJ_seeAlso */ -0x55,0x04,0x23, /* [5775] OBJ_userPassword */ -0x55,0x04,0x24, /* [5778] OBJ_userCertificate */ -0x55,0x04,0x25, /* [5781] OBJ_cACertificate */ -0x55,0x04,0x26, /* [5784] OBJ_authorityRevocationList */ -0x55,0x04,0x27, /* [5787] OBJ_certificateRevocationList */ -0x55,0x04,0x28, /* [5790] OBJ_crossCertificatePair */ -0x55,0x04,0x2F, /* [5793] OBJ_enhancedSearchGuide */ -0x55,0x04,0x30, /* [5796] OBJ_protocolInformation */ -0x55,0x04,0x31, /* [5799] OBJ_distinguishedName */ -0x55,0x04,0x32, /* [5802] OBJ_uniqueMember */ -0x55,0x04,0x33, /* [5805] OBJ_houseIdentifier */ -0x55,0x04,0x34, /* [5808] OBJ_supportedAlgorithms */ -0x55,0x04,0x35, /* [5811] OBJ_deltaRevocationList */ -0x55,0x04,0x36, /* [5814] OBJ_dmdName */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5817] OBJ_id_alg_PWRI_KEK */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5828] OBJ_aes_128_gcm */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5837] OBJ_aes_128_ccm */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5846] OBJ_id_aes128_wrap_pad */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5855] OBJ_aes_192_gcm */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5864] OBJ_aes_192_ccm */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5873] OBJ_id_aes192_wrap_pad */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5882] OBJ_aes_256_gcm */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5891] OBJ_aes_256_ccm */ -0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5900] OBJ_id_aes256_wrap_pad */ -0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5909] OBJ_id_camellia128_wrap */ -0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5920] OBJ_id_camellia192_wrap */ -0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5931] OBJ_id_camellia256_wrap */ -0x55,0x1D,0x25,0x00, /* [5942] OBJ_anyExtendedKeyUsage */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5946] OBJ_mgf1 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5955] OBJ_rsassaPss */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5964] OBJ_rsaesOaep */ -0x2A,0x86,0x48,0xCE,0x3E,0x02,0x01, /* [5973] OBJ_dhpublicnumber */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01,/* [5980] OBJ_brainpoolP160r1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02,/* [5989] OBJ_brainpoolP160t1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03,/* [5998] OBJ_brainpoolP192r1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04,/* [6007] OBJ_brainpoolP192t1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05,/* [6016] OBJ_brainpoolP224r1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06,/* [6025] OBJ_brainpoolP224t1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07,/* [6034] OBJ_brainpoolP256r1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08,/* [6043] OBJ_brainpoolP256t1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09,/* [6052] OBJ_brainpoolP320r1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A,/* [6061] OBJ_brainpoolP320t1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B,/* [6070] OBJ_brainpoolP384r1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C,/* [6079] OBJ_brainpoolP384t1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D,/* [6088] OBJ_brainpoolP512r1 */ -0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E,/* [6097] OBJ_brainpoolP512t1 */ -0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09,/* [6106] OBJ_pSpecified */ -0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02,/* [6115] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */ -0x2B,0x81,0x04,0x01,0x0B,0x00, /* [6124] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */ -0x2B,0x81,0x04,0x01,0x0B,0x01, /* [6130] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */ -0x2B,0x81,0x04,0x01,0x0B,0x02, /* [6136] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */ -0x2B,0x81,0x04,0x01,0x0B,0x03, /* [6142] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */ -0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03,/* [6148] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */ -0x2B,0x81,0x04,0x01,0x0E,0x00, /* [6157] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */ -0x2B,0x81,0x04,0x01,0x0E,0x01, /* [6163] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */ -0x2B,0x81,0x04,0x01,0x0E,0x02, /* [6169] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */ -0x2B,0x81,0x04,0x01,0x0E,0x03, /* [6175] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */ -0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,/* [6181] OBJ_ct_precert_scts */ -0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x03,/* [6191] OBJ_ct_precert_poison */ -0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x04,/* [6201] OBJ_ct_precert_signer */ -0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x05,/* [6211] OBJ_ct_cert_scts */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01,/* [6221] OBJ_jurisdictionLocalityName */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,/* [6232] OBJ_jurisdictionStateOrProvinceName */ -0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,/* [6243] OBJ_jurisdictionCountryName */ -}; - -static const ASN1_OBJECT nid_objs[NUM_NID]={ -{"UNDEF","undefined",NID_undef,0,NULL,0}, -{"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[0]),0}, -{"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[6]),0}, -{"MD2","md2",NID_md2,8,&(lvalues[13]),0}, -{"MD5","md5",NID_md5,8,&(lvalues[21]),0}, -{"RC4","rc4",NID_rc4,8,&(lvalues[29]),0}, -{"rsaEncryption","rsaEncryption",NID_rsaEncryption,9,&(lvalues[37]),0}, -{"RSA-MD2","md2WithRSAEncryption",NID_md2WithRSAEncryption,9, - &(lvalues[46]),0}, -{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9, - &(lvalues[55]),0}, -{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9, - &(lvalues[64]),0}, -{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9, - &(lvalues[73]),0}, -{"X500","directory services (X.500)",NID_X500,1,&(lvalues[82]),0}, -{"X509","X509",NID_X509,2,&(lvalues[83]),0}, -{"CN","commonName",NID_commonName,3,&(lvalues[85]),0}, -{"C","countryName",NID_countryName,3,&(lvalues[88]),0}, -{"L","localityName",NID_localityName,3,&(lvalues[91]),0}, -{"ST","stateOrProvinceName",NID_stateOrProvinceName,3,&(lvalues[94]),0}, -{"O","organizationName",NID_organizationName,3,&(lvalues[97]),0}, -{"OU","organizationalUnitName",NID_organizationalUnitName,3, - &(lvalues[100]),0}, -{"RSA","rsa",NID_rsa,4,&(lvalues[103]),0}, -{"pkcs7","pkcs7",NID_pkcs7,8,&(lvalues[107]),0}, -{"pkcs7-data","pkcs7-data",NID_pkcs7_data,9,&(lvalues[115]),0}, -{"pkcs7-signedData","pkcs7-signedData",NID_pkcs7_signed,9, - &(lvalues[124]),0}, -{"pkcs7-envelopedData","pkcs7-envelopedData",NID_pkcs7_enveloped,9, - &(lvalues[133]),0}, -{"pkcs7-signedAndEnvelopedData","pkcs7-signedAndEnvelopedData", - NID_pkcs7_signedAndEnveloped,9,&(lvalues[142]),0}, -{"pkcs7-digestData","pkcs7-digestData",NID_pkcs7_digest,9, - &(lvalues[151]),0}, -{"pkcs7-encryptedData","pkcs7-encryptedData",NID_pkcs7_encrypted,9, - &(lvalues[160]),0}, -{"pkcs3","pkcs3",NID_pkcs3,8,&(lvalues[169]),0}, -{"dhKeyAgreement","dhKeyAgreement",NID_dhKeyAgreement,9, - &(lvalues[177]),0}, -{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[186]),0}, -{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[191]),0}, -{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[196]),0}, -{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[201]),0}, -{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL,0}, -{"IDEA-CBC","idea-cbc",NID_idea_cbc,11,&(lvalues[206]),0}, -{"IDEA-CFB","idea-cfb",NID_idea_cfb64,0,NULL,0}, -{"IDEA-ECB","idea-ecb",NID_idea_ecb,0,NULL,0}, -{"RC2-CBC","rc2-cbc",NID_rc2_cbc,8,&(lvalues[217]),0}, -{"RC2-ECB","rc2-ecb",NID_rc2_ecb,0,NULL,0}, -{"RC2-CFB","rc2-cfb",NID_rc2_cfb64,0,NULL,0}, -{"RC2-OFB","rc2-ofb",NID_rc2_ofb64,0,NULL,0}, -{"SHA","sha",NID_sha,5,&(lvalues[225]),0}, -{"RSA-SHA","shaWithRSAEncryption",NID_shaWithRSAEncryption,5, - &(lvalues[230]),0}, -{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL,0}, -{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[235]),0}, -{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[243]),0}, -{"IDEA-OFB","idea-ofb",NID_idea_ofb64,0,NULL,0}, -{"pkcs9","pkcs9",NID_pkcs9,8,&(lvalues[248]),0}, -{"emailAddress","emailAddress",NID_pkcs9_emailAddress,9, - &(lvalues[256]),0}, -{"unstructuredName","unstructuredName",NID_pkcs9_unstructuredName,9, - &(lvalues[265]),0}, -{"contentType","contentType",NID_pkcs9_contentType,9,&(lvalues[274]),0}, -{"messageDigest","messageDigest",NID_pkcs9_messageDigest,9, - &(lvalues[283]),0}, -{"signingTime","signingTime",NID_pkcs9_signingTime,9,&(lvalues[292]),0}, -{"countersignature","countersignature",NID_pkcs9_countersignature,9, - &(lvalues[301]),0}, -{"challengePassword","challengePassword",NID_pkcs9_challengePassword, - 9,&(lvalues[310]),0}, -{"unstructuredAddress","unstructuredAddress", - NID_pkcs9_unstructuredAddress,9,&(lvalues[319]),0}, -{"extendedCertificateAttributes","extendedCertificateAttributes", - NID_pkcs9_extCertAttributes,9,&(lvalues[328]),0}, -{"Netscape","Netscape Communications Corp.",NID_netscape,7, - &(lvalues[337]),0}, -{"nsCertExt","Netscape Certificate Extension", - NID_netscape_cert_extension,8,&(lvalues[344]),0}, -{"nsDataType","Netscape Data Type",NID_netscape_data_type,8, - &(lvalues[352]),0}, -{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL,0}, -{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL,0}, -{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL,0}, -{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL,0}, -{"SHA1","sha1",NID_sha1,5,&(lvalues[360]),0}, -{"RSA-SHA1","sha1WithRSAEncryption",NID_sha1WithRSAEncryption,9, - &(lvalues[365]),0}, -{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[374]),0}, -{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[379]),0}, -{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC, - 9,&(lvalues[384]),0}, -{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[393]),0}, -{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[402]),0}, -{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9, - &(lvalues[407]),0}, -{"nsBaseUrl","Netscape Base Url",NID_netscape_base_url,9, - &(lvalues[416]),0}, -{"nsRevocationUrl","Netscape Revocation Url", - NID_netscape_revocation_url,9,&(lvalues[425]),0}, -{"nsCaRevocationUrl","Netscape CA Revocation Url", - NID_netscape_ca_revocation_url,9,&(lvalues[434]),0}, -{"nsRenewalUrl","Netscape Renewal Url",NID_netscape_renewal_url,9, - &(lvalues[443]),0}, -{"nsCaPolicyUrl","Netscape CA Policy Url",NID_netscape_ca_policy_url, - 9,&(lvalues[452]),0}, -{"nsSslServerName","Netscape SSL Server Name", - NID_netscape_ssl_server_name,9,&(lvalues[461]),0}, -{"nsComment","Netscape Comment",NID_netscape_comment,9,&(lvalues[470]),0}, -{"nsCertSequence","Netscape Certificate Sequence", - NID_netscape_cert_sequence,9,&(lvalues[479]),0}, -{"DESX-CBC","desx-cbc",NID_desx_cbc,0,NULL,0}, -{"id-ce","id-ce",NID_id_ce,2,&(lvalues[488]),0}, -{"subjectKeyIdentifier","X509v3 Subject Key Identifier", - NID_subject_key_identifier,3,&(lvalues[490]),0}, -{"keyUsage","X509v3 Key Usage",NID_key_usage,3,&(lvalues[493]),0}, -{"privateKeyUsagePeriod","X509v3 Private Key Usage Period", - NID_private_key_usage_period,3,&(lvalues[496]),0}, -{"subjectAltName","X509v3 Subject Alternative Name", - NID_subject_alt_name,3,&(lvalues[499]),0}, -{"issuerAltName","X509v3 Issuer Alternative Name",NID_issuer_alt_name, - 3,&(lvalues[502]),0}, -{"basicConstraints","X509v3 Basic Constraints",NID_basic_constraints, - 3,&(lvalues[505]),0}, -{"crlNumber","X509v3 CRL Number",NID_crl_number,3,&(lvalues[508]),0}, -{"certificatePolicies","X509v3 Certificate Policies", - NID_certificate_policies,3,&(lvalues[511]),0}, -{"authorityKeyIdentifier","X509v3 Authority Key Identifier", - NID_authority_key_identifier,3,&(lvalues[514]),0}, -{"BF-CBC","bf-cbc",NID_bf_cbc,9,&(lvalues[517]),0}, -{"BF-ECB","bf-ecb",NID_bf_ecb,0,NULL,0}, -{"BF-CFB","bf-cfb",NID_bf_cfb64,0,NULL,0}, -{"BF-OFB","bf-ofb",NID_bf_ofb64,0,NULL,0}, -{"MDC2","mdc2",NID_mdc2,4,&(lvalues[526]),0}, -{"RSA-MDC2","mdc2WithRSA",NID_mdc2WithRSA,4,&(lvalues[530]),0}, -{"RC4-40","rc4-40",NID_rc4_40,0,NULL,0}, -{"RC2-40-CBC","rc2-40-cbc",NID_rc2_40_cbc,0,NULL,0}, -{"GN","givenName",NID_givenName,3,&(lvalues[534]),0}, -{"SN","surname",NID_surname,3,&(lvalues[537]),0}, -{"initials","initials",NID_initials,3,&(lvalues[540]),0}, -{NULL,NULL,NID_undef,0,NULL,0}, -{"crlDistributionPoints","X509v3 CRL Distribution Points", - NID_crl_distribution_points,3,&(lvalues[543]),0}, -{"RSA-NP-MD5","md5WithRSA",NID_md5WithRSA,5,&(lvalues[546]),0}, -{"serialNumber","serialNumber",NID_serialNumber,3,&(lvalues[551]),0}, -{"title","title",NID_title,3,&(lvalues[554]),0}, -{"description","description",NID_description,3,&(lvalues[557]),0}, -{"CAST5-CBC","cast5-cbc",NID_cast5_cbc,9,&(lvalues[560]),0}, -{"CAST5-ECB","cast5-ecb",NID_cast5_ecb,0,NULL,0}, -{"CAST5-CFB","cast5-cfb",NID_cast5_cfb64,0,NULL,0}, -{"CAST5-OFB","cast5-ofb",NID_cast5_ofb64,0,NULL,0}, -{"pbeWithMD5AndCast5CBC","pbeWithMD5AndCast5CBC", - NID_pbeWithMD5AndCast5_CBC,9,&(lvalues[569]),0}, -{"DSA-SHA1","dsaWithSHA1",NID_dsaWithSHA1,7,&(lvalues[578]),0}, -{"MD5-SHA1","md5-sha1",NID_md5_sha1,0,NULL,0}, -{"RSA-SHA1-2","sha1WithRSA",NID_sha1WithRSA,5,&(lvalues[585]),0}, -{"DSA","dsaEncryption",NID_dsa,7,&(lvalues[590]),0}, -{"RIPEMD160","ripemd160",NID_ripemd160,5,&(lvalues[597]),0}, -{NULL,NULL,NID_undef,0,NULL,0}, -{"RSA-RIPEMD160","ripemd160WithRSA",NID_ripemd160WithRSA,6, - &(lvalues[602]),0}, -{"RC5-CBC","rc5-cbc",NID_rc5_cbc,8,&(lvalues[608]),0}, -{"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0}, -{"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0}, -{"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0}, -{"RLE","run length compression",NID_rle_compression,6,&(lvalues[616]),0}, -{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[622]),0}, -{"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3, - &(lvalues[633]),0}, -{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[636]),0}, -{"id-kp","id-kp",NID_id_kp,7,&(lvalues[642]),0}, -{"serverAuth","TLS Web Server Authentication",NID_server_auth,8, - &(lvalues[649]),0}, -{"clientAuth","TLS Web Client Authentication",NID_client_auth,8, - &(lvalues[657]),0}, -{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[665]),0}, -{"emailProtection","E-mail Protection",NID_email_protect,8, - &(lvalues[673]),0}, -{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[681]),0}, -{"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10, - &(lvalues[689]),0}, -{"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10, - &(lvalues[699]),0}, -{"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10, - &(lvalues[709]),0}, -{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[719]),0}, -{"msEFS","Microsoft Encrypted File System",NID_ms_efs,10, - &(lvalues[729]),0}, -{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[739]),0}, -{"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3, - &(lvalues[748]),0}, -{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[751]),0}, -{"invalidityDate","Invalidity Date",NID_invalidity_date,3, - &(lvalues[754]),0}, -{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[757]),0}, -{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4", - NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[762]),0}, -{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4", - NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[772]),0}, -{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC", - NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[782]),0}, -{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC", - NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[792]),0}, -{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC", - NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[802]),0}, -{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC", - NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[812]),0}, -{"keyBag","keyBag",NID_keyBag,11,&(lvalues[822]),0}, -{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag, - 11,&(lvalues[833]),0}, -{"certBag","certBag",NID_certBag,11,&(lvalues[844]),0}, -{"crlBag","crlBag",NID_crlBag,11,&(lvalues[855]),0}, -{"secretBag","secretBag",NID_secretBag,11,&(lvalues[866]),0}, -{"safeContentsBag","safeContentsBag",NID_safeContentsBag,11, - &(lvalues[877]),0}, -{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[888]),0}, -{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[897]),0}, -{"x509Certificate","x509Certificate",NID_x509Certificate,10, - &(lvalues[906]),0}, -{"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10, - &(lvalues[916]),0}, -{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[926]),0}, -{"PBES2","PBES2",NID_pbes2,9,&(lvalues[936]),0}, -{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[945]),0}, -{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[954]),0}, -{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[962]),0}, -{"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8, - &(lvalues[970]),0}, -{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0}, -{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9, - &(lvalues[978]),0}, -{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9, - &(lvalues[987]),0}, -{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9, - &(lvalues[996]),0}, -{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9, - &(lvalues[1005]),0}, -{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10, - &(lvalues[1014]),0}, -{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1024]),0}, -{"name","name",NID_name,3,&(lvalues[1033]),0}, -{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1036]),0}, -{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1039]),0}, -{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1046]),0}, -{"authorityInfoAccess","Authority Information Access",NID_info_access, - 8,&(lvalues[1053]),0}, -{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1061]),0}, -{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1069]),0}, -{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1077]),0}, -{"ISO","iso",NID_iso,0,NULL,0}, -{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1085]),0}, -{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1086]),0}, -{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1089]),0}, -{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1094]),0}, -{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1100]),0}, -{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1108]),0}, -{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1116]),0}, -{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1125]),0}, -{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1135]),0}, -{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1145]),0}, -{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1155]),0}, -{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1165]),0}, -{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1175]),0}, -{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1185]),0}, -{"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11, - &(lvalues[1195]),0}, -{"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11, - &(lvalues[1206]),0}, -{"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11, - &(lvalues[1217]),0}, -{"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3, - 11,&(lvalues[1228]),0}, -{"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88", - NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1239]),0}, -{"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97", - NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1250]),0}, -{"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88", - NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1261]),0}, -{"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97", - NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1272]),0}, -{"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt, - 11,&(lvalues[1283]),0}, -{"id-smime-ct-authData","id-smime-ct-authData", - NID_id_smime_ct_authData,11,&(lvalues[1294]),0}, -{"id-smime-ct-publishCert","id-smime-ct-publishCert", - NID_id_smime_ct_publishCert,11,&(lvalues[1305]),0}, -{"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo, - 11,&(lvalues[1316]),0}, -{"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo, - 11,&(lvalues[1327]),0}, -{"id-smime-ct-contentInfo","id-smime-ct-contentInfo", - NID_id_smime_ct_contentInfo,11,&(lvalues[1338]),0}, -{"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData", - NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1349]),0}, -{"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData", - NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1360]),0}, -{"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest", - NID_id_smime_aa_receiptRequest,11,&(lvalues[1371]),0}, -{"id-smime-aa-securityLabel","id-smime-aa-securityLabel", - NID_id_smime_aa_securityLabel,11,&(lvalues[1382]),0}, -{"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory", - NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1393]),0}, -{"id-smime-aa-contentHint","id-smime-aa-contentHint", - NID_id_smime_aa_contentHint,11,&(lvalues[1404]),0}, -{"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest", - NID_id_smime_aa_msgSigDigest,11,&(lvalues[1415]),0}, -{"id-smime-aa-encapContentType","id-smime-aa-encapContentType", - NID_id_smime_aa_encapContentType,11,&(lvalues[1426]),0}, -{"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier", - NID_id_smime_aa_contentIdentifier,11,&(lvalues[1437]),0}, -{"id-smime-aa-macValue","id-smime-aa-macValue", - NID_id_smime_aa_macValue,11,&(lvalues[1448]),0}, -{"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels", - NID_id_smime_aa_equivalentLabels,11,&(lvalues[1459]),0}, -{"id-smime-aa-contentReference","id-smime-aa-contentReference", - NID_id_smime_aa_contentReference,11,&(lvalues[1470]),0}, -{"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref", - NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1481]),0}, -{"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate", - NID_id_smime_aa_signingCertificate,11,&(lvalues[1492]),0}, -{"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts", - NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1503]),0}, -{"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken", - NID_id_smime_aa_timeStampToken,11,&(lvalues[1514]),0}, -{"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId", - NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1525]),0}, -{"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType", - NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1536]),0}, -{"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation", - NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1547]),0}, -{"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr", - NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1558]),0}, -{"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert", - NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1569]),0}, -{"id-smime-aa-ets-contentTimestamp", - "id-smime-aa-ets-contentTimestamp", - NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1580]),0}, -{"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs", - NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1591]),0}, -{"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs", - NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1602]),0}, -{"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues", - NID_id_smime_aa_ets_certValues,11,&(lvalues[1613]),0}, -{"id-smime-aa-ets-revocationValues", - "id-smime-aa-ets-revocationValues", - NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1624]),0}, -{"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp", - NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1635]),0}, -{"id-smime-aa-ets-certCRLTimestamp", - "id-smime-aa-ets-certCRLTimestamp", - NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1646]),0}, -{"id-smime-aa-ets-archiveTimeStamp", - "id-smime-aa-ets-archiveTimeStamp", - NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1657]),0}, -{"id-smime-aa-signatureType","id-smime-aa-signatureType", - NID_id_smime_aa_signatureType,11,&(lvalues[1668]),0}, -{"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc", - NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1679]),0}, -{"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES", - NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1690]),0}, -{"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2", - NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1701]),0}, -{"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap", - NID_id_smime_alg_3DESwrap,11,&(lvalues[1712]),0}, -{"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap", - NID_id_smime_alg_RC2wrap,11,&(lvalues[1723]),0}, -{"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11, - &(lvalues[1734]),0}, -{"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap", - NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1745]),0}, -{"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap", - NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1756]),0}, -{"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11, - &(lvalues[1767]),0}, -{"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri", - NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1778]),0}, -{"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice", - NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1789]),0}, -{"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin", - NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1800]),0}, -{"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt", - NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1811]),0}, -{"id-smime-cti-ets-proofOfDelivery", - "id-smime-cti-ets-proofOfDelivery", - NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1822]),0}, -{"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender", - NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1833]),0}, -{"id-smime-cti-ets-proofOfApproval", - "id-smime-cti-ets-proofOfApproval", - NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1844]),0}, -{"id-smime-cti-ets-proofOfCreation", - "id-smime-cti-ets-proofOfCreation", - NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1855]),0}, -{"MD4","md4",NID_md4,8,&(lvalues[1866]),0}, -{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1874]),0}, -{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1881]),0}, -{"id-it","id-it",NID_id_it,7,&(lvalues[1888]),0}, -{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1895]),0}, -{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1902]),0}, -{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1909]),0}, -{"id-on","id-on",NID_id_on,7,&(lvalues[1916]),0}, -{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1923]),0}, -{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1930]),0}, -{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1937]),0}, -{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1944]),0}, -{"id-pkix1-explicit-88","id-pkix1-explicit-88", - NID_id_pkix1_explicit_88,8,&(lvalues[1951]),0}, -{"id-pkix1-implicit-88","id-pkix1-implicit-88", - NID_id_pkix1_implicit_88,8,&(lvalues[1959]),0}, -{"id-pkix1-explicit-93","id-pkix1-explicit-93", - NID_id_pkix1_explicit_93,8,&(lvalues[1967]),0}, -{"id-pkix1-implicit-93","id-pkix1-implicit-93", - NID_id_pkix1_implicit_93,8,&(lvalues[1975]),0}, -{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1983]),0}, -{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1991]),0}, -{"id-mod-kea-profile-88","id-mod-kea-profile-88", - NID_id_mod_kea_profile_88,8,&(lvalues[1999]),0}, -{"id-mod-kea-profile-93","id-mod-kea-profile-93", - NID_id_mod_kea_profile_93,8,&(lvalues[2007]),0}, -{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2015]),0}, -{"id-mod-qualified-cert-88","id-mod-qualified-cert-88", - NID_id_mod_qualified_cert_88,8,&(lvalues[2023]),0}, -{"id-mod-qualified-cert-93","id-mod-qualified-cert-93", - NID_id_mod_qualified_cert_93,8,&(lvalues[2031]),0}, -{"id-mod-attribute-cert","id-mod-attribute-cert", - NID_id_mod_attribute_cert,8,&(lvalues[2039]),0}, -{"id-mod-timestamp-protocol","id-mod-timestamp-protocol", - NID_id_mod_timestamp_protocol,8,&(lvalues[2047]),0}, -{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2055]),0}, -{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2063]),0}, -{"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8, - &(lvalues[2071]),0}, -{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2079]),0}, -{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2087]),0}, -{"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8, - &(lvalues[2095]),0}, -{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2103]),0}, -{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2111]),0}, -{"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8, - &(lvalues[2119]),0}, -{"sbgp-autonomousSysNum","sbgp-autonomousSysNum", - NID_sbgp_autonomousSysNum,8,&(lvalues[2127]),0}, -{"sbgp-routerIdentifier","sbgp-routerIdentifier", - NID_sbgp_routerIdentifier,8,&(lvalues[2135]),0}, -{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2143]),0}, -{"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8, - &(lvalues[2151]),0}, -{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2159]),0}, -{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2167]),0}, -{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2175]),0}, -{"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert, - 8,&(lvalues[2183]),0}, -{"id-it-signKeyPairTypes","id-it-signKeyPairTypes", - NID_id_it_signKeyPairTypes,8,&(lvalues[2191]),0}, -{"id-it-encKeyPairTypes","id-it-encKeyPairTypes", - NID_id_it_encKeyPairTypes,8,&(lvalues[2199]),0}, -{"id-it-preferredSymmAlg","id-it-preferredSymmAlg", - NID_id_it_preferredSymmAlg,8,&(lvalues[2207]),0}, -{"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo", - NID_id_it_caKeyUpdateInfo,8,&(lvalues[2215]),0}, -{"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8, - &(lvalues[2223]),0}, -{"id-it-unsupportedOIDs","id-it-unsupportedOIDs", - NID_id_it_unsupportedOIDs,8,&(lvalues[2231]),0}, -{"id-it-subscriptionRequest","id-it-subscriptionRequest", - NID_id_it_subscriptionRequest,8,&(lvalues[2239]),0}, -{"id-it-subscriptionResponse","id-it-subscriptionResponse", - NID_id_it_subscriptionResponse,8,&(lvalues[2247]),0}, -{"id-it-keyPairParamReq","id-it-keyPairParamReq", - NID_id_it_keyPairParamReq,8,&(lvalues[2255]),0}, -{"id-it-keyPairParamRep","id-it-keyPairParamRep", - NID_id_it_keyPairParamRep,8,&(lvalues[2263]),0}, -{"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase, - 8,&(lvalues[2271]),0}, -{"id-it-implicitConfirm","id-it-implicitConfirm", - NID_id_it_implicitConfirm,8,&(lvalues[2279]),0}, -{"id-it-confirmWaitTime","id-it-confirmWaitTime", - NID_id_it_confirmWaitTime,8,&(lvalues[2287]),0}, -{"id-it-origPKIMessage","id-it-origPKIMessage", - NID_id_it_origPKIMessage,8,&(lvalues[2295]),0}, -{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2303]),0}, -{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2311]),0}, -{"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken, - 9,&(lvalues[2319]),0}, -{"id-regCtrl-authenticator","id-regCtrl-authenticator", - NID_id_regCtrl_authenticator,9,&(lvalues[2328]),0}, -{"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo", - NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2337]),0}, -{"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions", - NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2346]),0}, -{"id-regCtrl-oldCertID","id-regCtrl-oldCertID", - NID_id_regCtrl_oldCertID,9,&(lvalues[2355]),0}, -{"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey", - NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2364]),0}, -{"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs", - NID_id_regInfo_utf8Pairs,9,&(lvalues[2373]),0}, -{"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9, - &(lvalues[2382]),0}, -{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2391]),0}, -{"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8, - &(lvalues[2399]),0}, -{"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1", - NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2407]),0}, -{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2415]),0}, -{"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8, - &(lvalues[2423]),0}, -{"id-cmc-identification","id-cmc-identification", - NID_id_cmc_identification,8,&(lvalues[2431]),0}, -{"id-cmc-identityProof","id-cmc-identityProof", - NID_id_cmc_identityProof,8,&(lvalues[2439]),0}, -{"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8, - &(lvalues[2447]),0}, -{"id-cmc-transactionId","id-cmc-transactionId", - NID_id_cmc_transactionId,8,&(lvalues[2455]),0}, -{"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8, - &(lvalues[2463]),0}, -{"id-cmc-recipientNonce","id-cmc-recipientNonce", - NID_id_cmc_recipientNonce,8,&(lvalues[2471]),0}, -{"id-cmc-addExtensions","id-cmc-addExtensions", - NID_id_cmc_addExtensions,8,&(lvalues[2479]),0}, -{"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP, - 8,&(lvalues[2487]),0}, -{"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP, - 8,&(lvalues[2495]),0}, -{"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness", - NID_id_cmc_lraPOPWitness,8,&(lvalues[2503]),0}, -{"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8, - &(lvalues[2511]),0}, -{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2519]),0}, -{"id-cmc-revokeRequest","id-cmc-revokeRequest", - NID_id_cmc_revokeRequest,8,&(lvalues[2527]),0}, -{"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8, - &(lvalues[2535]),0}, -{"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo, - 8,&(lvalues[2543]),0}, -{"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending, - 8,&(lvalues[2551]),0}, -{"id-cmc-popLinkRandom","id-cmc-popLinkRandom", - NID_id_cmc_popLinkRandom,8,&(lvalues[2559]),0}, -{"id-cmc-popLinkWitness","id-cmc-popLinkWitness", - NID_id_cmc_popLinkWitness,8,&(lvalues[2567]),0}, -{"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance", - NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2575]),0}, -{"id-on-personalData","id-on-personalData",NID_id_on_personalData,8, - &(lvalues[2583]),0}, -{"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8, - &(lvalues[2591]),0}, -{"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth, - 8,&(lvalues[2599]),0}, -{NULL,NULL,NID_undef,0,NULL,0}, -{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2607]),0}, -{"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship", - NID_id_pda_countryOfCitizenship,8,&(lvalues[2615]),0}, -{"id-pda-countryOfResidence","id-pda-countryOfResidence", - NID_id_pda_countryOfResidence,8,&(lvalues[2623]),0}, -{"id-aca-authenticationInfo","id-aca-authenticationInfo", - NID_id_aca_authenticationInfo,8,&(lvalues[2631]),0}, -{"id-aca-accessIdentity","id-aca-accessIdentity", - NID_id_aca_accessIdentity,8,&(lvalues[2639]),0}, -{"id-aca-chargingIdentity","id-aca-chargingIdentity", - NID_id_aca_chargingIdentity,8,&(lvalues[2647]),0}, -{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2655]),0}, -{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2663]),0}, -{"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1", - NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2671]),0}, -{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2679]),0}, -{"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8, - &(lvalues[2687]),0}, -{"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8, - &(lvalues[2695]),0}, -{"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8, - &(lvalues[2703]),0}, -{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2711]),0}, -{"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9, - &(lvalues[2719]),0}, -{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2728]),0}, -{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2737]),0}, -{"acceptableResponses","Acceptable OCSP Responses", - NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2746]),0}, -{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2755]),0}, -{"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff, - 9,&(lvalues[2764]),0}, -{"serviceLocator","OCSP Service Locator", - NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2773]),0}, -{"extendedStatus","Extended OCSP Status", - NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2782]),0}, -{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2791]),0}, -{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2800]),0}, -{"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9, - &(lvalues[2809]),0}, -{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2818]),0}, -{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2822]),0}, -{"X500algorithms","directory services - algorithms", - NID_X500algorithms,2,&(lvalues[2827]),0}, -{"ORG","org",NID_org,1,&(lvalues[2829]),0}, -{"DOD","dod",NID_dod,2,&(lvalues[2830]),0}, -{"IANA","iana",NID_iana,3,&(lvalues[2832]),0}, -{"directory","Directory",NID_Directory,4,&(lvalues[2835]),0}, -{"mgmt","Management",NID_Management,4,&(lvalues[2839]),0}, -{"experimental","Experimental",NID_Experimental,4,&(lvalues[2843]),0}, -{"private","Private",NID_Private,4,&(lvalues[2847]),0}, -{"security","Security",NID_Security,4,&(lvalues[2851]),0}, -{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2855]),0}, -{"Mail","Mail",NID_Mail,4,&(lvalues[2859]),0}, -{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2863]),0}, -{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2868]),0}, -{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2877]),0}, -{"domain","Domain",NID_Domain,10,&(lvalues[2887]),0}, -{"NULL","NULL",NID_joint_iso_ccitt,0,NULL,0}, -{"selected-attribute-types","Selected Attribute Types", - NID_selected_attribute_types,3,&(lvalues[2897]),0}, -{"clearance","clearance",NID_clearance,4,&(lvalues[2900]),0}, -{"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9, - &(lvalues[2904]),0}, -{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2913]),0}, -{"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8, - &(lvalues[2921]),0}, -{"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8, - &(lvalues[2929]),0}, -{"role","role",NID_role,3,&(lvalues[2937]),0}, -{"policyConstraints","X509v3 Policy Constraints", - NID_policy_constraints,3,&(lvalues[2940]),0}, -{"targetInformation","X509v3 AC Targeting",NID_target_information,3, - &(lvalues[2943]),0}, -{"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3, - &(lvalues[2946]),0}, -{"NULL","NULL",NID_ccitt,0,NULL,0}, -{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2949]),0}, -{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2954]),0}, -{"characteristic-two-field","characteristic-two-field", - NID_X9_62_characteristic_two_field,7,&(lvalues[2961]),0}, -{"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7, - &(lvalues[2968]),0}, -{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2975]),0}, -{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2983]),0}, -{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2991]),0}, -{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[2999]),0}, -{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3007]),0}, -{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3015]),0}, -{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3023]),0}, -{"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7, - &(lvalues[3031]),0}, -{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3038]),0}, -{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3047]),0}, -{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3056]),0}, -{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3065]),0}, -{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3074]),0}, -{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3083]),0}, -{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3092]),0}, -{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3101]),0}, -{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3110]),0}, -{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3119]),0}, -{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3128]),0}, -{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3137]),0}, -{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3146]),0}, -{"holdInstructionCode","Hold Instruction Code", - NID_hold_instruction_code,3,&(lvalues[3155]),0}, -{"holdInstructionNone","Hold Instruction None", - NID_hold_instruction_none,7,&(lvalues[3158]),0}, -{"holdInstructionCallIssuer","Hold Instruction Call Issuer", - NID_hold_instruction_call_issuer,7,&(lvalues[3165]),0}, -{"holdInstructionReject","Hold Instruction Reject", - NID_hold_instruction_reject,7,&(lvalues[3172]),0}, -{"data","data",NID_data,1,&(lvalues[3179]),0}, -{"pss","pss",NID_pss,3,&(lvalues[3180]),0}, -{"ucl","ucl",NID_ucl,7,&(lvalues[3183]),0}, -{"pilot","pilot",NID_pilot,8,&(lvalues[3190]),0}, -{"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9, - &(lvalues[3198]),0}, -{"pilotAttributeSyntax","pilotAttributeSyntax", - NID_pilotAttributeSyntax,9,&(lvalues[3207]),0}, -{"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9, - &(lvalues[3216]),0}, -{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3225]),0}, -{"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10, - &(lvalues[3234]),0}, -{"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax", - NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3244]),0}, -{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3254]),0}, -{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3264]),0}, -{"account","account",NID_account,10,&(lvalues[3274]),0}, -{"document","document",NID_document,10,&(lvalues[3284]),0}, -{"room","room",NID_room,10,&(lvalues[3294]),0}, -{"documentSeries","documentSeries",NID_documentSeries,10, - &(lvalues[3304]),0}, -{"rFC822localPart","rFC822localPart",NID_rFC822localPart,10, - &(lvalues[3314]),0}, -{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3324]),0}, -{"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject, - 10,&(lvalues[3334]),0}, -{"friendlyCountry","friendlyCountry",NID_friendlyCountry,10, - &(lvalues[3344]),0}, -{"simpleSecurityObject","simpleSecurityObject", - NID_simpleSecurityObject,10,&(lvalues[3354]),0}, -{"pilotOrganization","pilotOrganization",NID_pilotOrganization,10, - &(lvalues[3364]),0}, -{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3374]),0}, -{"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData, - 10,&(lvalues[3384]),0}, -{"UID","userId",NID_userId,10,&(lvalues[3394]),0}, -{"textEncodedORAddress","textEncodedORAddress", - NID_textEncodedORAddress,10,&(lvalues[3404]),0}, -{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3414]),0}, -{"info","info",NID_info,10,&(lvalues[3424]),0}, -{"favouriteDrink","favouriteDrink",NID_favouriteDrink,10, - &(lvalues[3434]),0}, -{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3444]),0}, -{"photo","photo",NID_photo,10,&(lvalues[3454]),0}, -{"userClass","userClass",NID_userClass,10,&(lvalues[3464]),0}, -{"host","host",NID_host,10,&(lvalues[3474]),0}, -{"manager","manager",NID_manager,10,&(lvalues[3484]),0}, -{"documentIdentifier","documentIdentifier",NID_documentIdentifier,10, - &(lvalues[3494]),0}, -{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3504]),0}, -{"documentVersion","documentVersion",NID_documentVersion,10, - &(lvalues[3514]),0}, -{"documentAuthor","documentAuthor",NID_documentAuthor,10, - &(lvalues[3524]),0}, -{"documentLocation","documentLocation",NID_documentLocation,10, - &(lvalues[3534]),0}, -{"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber, - 10,&(lvalues[3544]),0}, -{"secretary","secretary",NID_secretary,10,&(lvalues[3554]),0}, -{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3564]),0}, -{"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10, - &(lvalues[3574]),0}, -{"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10, - &(lvalues[3584]),0}, -{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3594]),0}, -{"pilotAttributeType27","pilotAttributeType27", - NID_pilotAttributeType27,10,&(lvalues[3604]),0}, -{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3614]),0}, -{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3624]),0}, -{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3634]),0}, -{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3644]),0}, -{"associatedDomain","associatedDomain",NID_associatedDomain,10, - &(lvalues[3654]),0}, -{"associatedName","associatedName",NID_associatedName,10, - &(lvalues[3664]),0}, -{"homePostalAddress","homePostalAddress",NID_homePostalAddress,10, - &(lvalues[3674]),0}, -{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3684]),0}, -{"mobileTelephoneNumber","mobileTelephoneNumber", - NID_mobileTelephoneNumber,10,&(lvalues[3694]),0}, -{"pagerTelephoneNumber","pagerTelephoneNumber", - NID_pagerTelephoneNumber,10,&(lvalues[3704]),0}, -{"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName, - 10,&(lvalues[3714]),0}, -{"organizationalStatus","organizationalStatus", - NID_organizationalStatus,10,&(lvalues[3724]),0}, -{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3734]),0}, -{"mailPreferenceOption","mailPreferenceOption", - NID_mailPreferenceOption,10,&(lvalues[3744]),0}, -{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3754]),0}, -{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3764]),0}, -{"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10, - &(lvalues[3774]),0}, -{"subtreeMinimumQuality","subtreeMinimumQuality", - NID_subtreeMinimumQuality,10,&(lvalues[3784]),0}, -{"subtreeMaximumQuality","subtreeMaximumQuality", - NID_subtreeMaximumQuality,10,&(lvalues[3794]),0}, -{"personalSignature","personalSignature",NID_personalSignature,10, - &(lvalues[3804]),0}, -{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3814]),0}, -{"audio","audio",NID_audio,10,&(lvalues[3824]),0}, -{"documentPublisher","documentPublisher",NID_documentPublisher,10, - &(lvalues[3834]),0}, -{"x500UniqueIdentifier","x500UniqueIdentifier", - NID_x500UniqueIdentifier,3,&(lvalues[3844]),0}, -{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3847]),0}, -{"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6, - &(lvalues[3852]),0}, -{"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6, - &(lvalues[3858]),0}, -{"id-hex-partial-message","id-hex-partial-message", - NID_id_hex_partial_message,7,&(lvalues[3864]),0}, -{"id-hex-multipart-message","id-hex-multipart-message", - NID_id_hex_multipart_message,7,&(lvalues[3871]),0}, -{"generationQualifier","generationQualifier",NID_generationQualifier, - 3,&(lvalues[3878]),0}, -{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3881]),0}, -{NULL,NULL,NID_undef,0,NULL,0}, -{"id-set","Secure Electronic Transactions",NID_id_set,2, - &(lvalues[3884]),0}, -{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3886]),0}, -{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3889]),0}, -{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3892]),0}, -{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3895]),0}, -{"set-certExt","certificate extensions",NID_set_certExt,3, - &(lvalues[3898]),0}, -{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3901]),0}, -{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3904]),0}, -{"setct-PANToken","setct-PANToken",NID_setct_PANToken,4, - &(lvalues[3908]),0}, -{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3912]),0}, -{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3916]),0}, -{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3920]),0}, -{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3924]),0}, -{"setct-PIDataUnsigned","setct-PIDataUnsigned", - NID_setct_PIDataUnsigned,4,&(lvalues[3928]),0}, -{"setct-HODInput","setct-HODInput",NID_setct_HODInput,4, - &(lvalues[3932]),0}, -{"setct-AuthResBaggage","setct-AuthResBaggage", - NID_setct_AuthResBaggage,4,&(lvalues[3936]),0}, -{"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage", - NID_setct_AuthRevReqBaggage,4,&(lvalues[3940]),0}, -{"setct-AuthRevResBaggage","setct-AuthRevResBaggage", - NID_setct_AuthRevResBaggage,4,&(lvalues[3944]),0}, -{"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4, - &(lvalues[3948]),0}, -{"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4, - &(lvalues[3952]),0}, -{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3956]),0}, -{"setct-PResData","setct-PResData",NID_setct_PResData,4, - &(lvalues[3960]),0}, -{"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4, - &(lvalues[3964]),0}, -{"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4, - &(lvalues[3968]),0}, -{"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4, - &(lvalues[3972]),0}, -{"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4, - &(lvalues[3976]),0}, -{"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4, - &(lvalues[3980]),0}, -{"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4, - &(lvalues[3984]),0}, -{"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg", - NID_setct_AcqCardCodeMsg,4,&(lvalues[3988]),0}, -{"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS, - 4,&(lvalues[3992]),0}, -{"setct-AuthRevResData","setct-AuthRevResData", - NID_setct_AuthRevResData,4,&(lvalues[3996]),0}, -{"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS, - 4,&(lvalues[4000]),0}, -{"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4, - &(lvalues[4004]),0}, -{"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4, - &(lvalues[4008]),0}, -{"setct-CapResData","setct-CapResData",NID_setct_CapResData,4, - &(lvalues[4012]),0}, -{"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4, - &(lvalues[4016]),0}, -{"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX, - 4,&(lvalues[4020]),0}, -{"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData, - 4,&(lvalues[4024]),0}, -{"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4, - &(lvalues[4028]),0}, -{"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4, - &(lvalues[4032]),0}, -{"setct-CredResData","setct-CredResData",NID_setct_CredResData,4, - &(lvalues[4036]),0}, -{"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS, - 4,&(lvalues[4040]),0}, -{"setct-CredRevReqTBSX","setct-CredRevReqTBSX", - NID_setct_CredRevReqTBSX,4,&(lvalues[4044]),0}, -{"setct-CredRevResData","setct-CredRevResData", - NID_setct_CredRevResData,4,&(lvalues[4048]),0}, -{"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4, - &(lvalues[4052]),0}, -{"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4, - &(lvalues[4056]),0}, -{"setct-BatchAdminReqData","setct-BatchAdminReqData", - NID_setct_BatchAdminReqData,4,&(lvalues[4060]),0}, -{"setct-BatchAdminResData","setct-BatchAdminResData", - NID_setct_BatchAdminResData,4,&(lvalues[4064]),0}, -{"setct-CardCInitResTBS","setct-CardCInitResTBS", - NID_setct_CardCInitResTBS,4,&(lvalues[4068]),0}, -{"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS", - NID_setct_MeAqCInitResTBS,4,&(lvalues[4072]),0}, -{"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS, - 4,&(lvalues[4076]),0}, -{"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4, - &(lvalues[4080]),0}, -{"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4, - &(lvalues[4084]),0}, -{"setct-CertResData","setct-CertResData",NID_setct_CertResData,4, - &(lvalues[4088]),0}, -{"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS, - 4,&(lvalues[4092]),0}, -{"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4, - &(lvalues[4096]),0}, -{"setct-PIDualSignedTBE","setct-PIDualSignedTBE", - NID_setct_PIDualSignedTBE,4,&(lvalues[4100]),0}, -{"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE, - 4,&(lvalues[4104]),0}, -{"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4, - &(lvalues[4108]),0}, -{"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4, - &(lvalues[4112]),0}, -{"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4, - &(lvalues[4116]),0}, -{"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4, - &(lvalues[4120]),0}, -{"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4, - &(lvalues[4124]),0}, -{"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4, - &(lvalues[4128]),0}, -{"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE", - NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4132]),0}, -{"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE, - 4,&(lvalues[4136]),0}, -{"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE, - 4,&(lvalues[4140]),0}, -{"setct-AuthRevResTBEB","setct-AuthRevResTBEB", - NID_setct_AuthRevResTBEB,4,&(lvalues[4144]),0}, -{"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4, - &(lvalues[4148]),0}, -{"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4, - &(lvalues[4152]),0}, -{"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4, - &(lvalues[4156]),0}, -{"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4, - &(lvalues[4160]),0}, -{"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX, - 4,&(lvalues[4164]),0}, -{"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4, - &(lvalues[4168]),0}, -{"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4, - &(lvalues[4172]),0}, -{"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4, - &(lvalues[4176]),0}, -{"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4, - &(lvalues[4180]),0}, -{"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE, - 4,&(lvalues[4184]),0}, -{"setct-CredRevReqTBEX","setct-CredRevReqTBEX", - NID_setct_CredRevReqTBEX,4,&(lvalues[4188]),0}, -{"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE, - 4,&(lvalues[4192]),0}, -{"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE", - NID_setct_BatchAdminReqTBE,4,&(lvalues[4196]),0}, -{"setct-BatchAdminResTBE","setct-BatchAdminResTBE", - NID_setct_BatchAdminResTBE,4,&(lvalues[4200]),0}, -{"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE, - 4,&(lvalues[4204]),0}, -{"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4, - &(lvalues[4208]),0}, -{"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4, - &(lvalues[4212]),0}, -{"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4, - &(lvalues[4216]),0}, -{"setct-CRLNotificationTBS","setct-CRLNotificationTBS", - NID_setct_CRLNotificationTBS,4,&(lvalues[4220]),0}, -{"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS", - NID_setct_CRLNotificationResTBS,4,&(lvalues[4224]),0}, -{"setct-BCIDistributionTBS","setct-BCIDistributionTBS", - NID_setct_BCIDistributionTBS,4,&(lvalues[4228]),0}, -{"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4, - &(lvalues[4232]),0}, -{"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4, - &(lvalues[4236]),0}, -{"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4, - &(lvalues[4240]),0}, -{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4244]),0}, -{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4248]),0}, -{"setext-cv","additional verification",NID_setext_cv,4, - &(lvalues[4252]),0}, -{"set-policy-root","set-policy-root",NID_set_policy_root,4, - &(lvalues[4256]),0}, -{"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4, - &(lvalues[4260]),0}, -{"setCext-certType","setCext-certType",NID_setCext_certType,4, - &(lvalues[4264]),0}, -{"setCext-merchData","setCext-merchData",NID_setCext_merchData,4, - &(lvalues[4268]),0}, -{"setCext-cCertRequired","setCext-cCertRequired", - NID_setCext_cCertRequired,4,&(lvalues[4272]),0}, -{"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4, - &(lvalues[4276]),0}, -{"setCext-setExt","setCext-setExt",NID_setCext_setExt,4, - &(lvalues[4280]),0}, -{"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4, - &(lvalues[4284]),0}, -{"setCext-PGWYcapabilities","setCext-PGWYcapabilities", - NID_setCext_PGWYcapabilities,4,&(lvalues[4288]),0}, -{"setCext-TokenIdentifier","setCext-TokenIdentifier", - NID_setCext_TokenIdentifier,4,&(lvalues[4292]),0}, -{"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4, - &(lvalues[4296]),0}, -{"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4, - &(lvalues[4300]),0}, -{"setCext-IssuerCapabilities","setCext-IssuerCapabilities", - NID_setCext_IssuerCapabilities,4,&(lvalues[4304]),0}, -{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4308]),0}, -{"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap, - 4,&(lvalues[4312]),0}, -{"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4, - &(lvalues[4316]),0}, -{"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4, - &(lvalues[4320]),0}, -{"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5, - &(lvalues[4324]),0}, -{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4329]),0}, -{"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5, - &(lvalues[4334]),0}, -{"setAttr-Token-B0Prime","setAttr-Token-B0Prime", - NID_setAttr_Token_B0Prime,5,&(lvalues[4339]),0}, -{"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5, - &(lvalues[4344]),0}, -{"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5, - &(lvalues[4349]),0}, -{"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5, - &(lvalues[4354]),0}, -{"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm, - 6,&(lvalues[4359]),0}, -{"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6, - &(lvalues[4365]),0}, -{"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6, - &(lvalues[4371]),0}, -{"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6, - &(lvalues[4377]),0}, -{"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig, - 6,&(lvalues[4383]),0}, -{"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4, - &(lvalues[4389]),0}, -{"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4, - &(lvalues[4393]),0}, -{"set-brand-AmericanExpress","set-brand-AmericanExpress", - NID_set_brand_AmericanExpress,4,&(lvalues[4397]),0}, -{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4401]),0}, -{"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4, - &(lvalues[4405]),0}, -{"set-brand-MasterCard","set-brand-MasterCard", - NID_set_brand_MasterCard,4,&(lvalues[4409]),0}, -{"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5, - &(lvalues[4413]),0}, -{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4418]),0}, -{"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET", - NID_rsaOAEPEncryptionSET,9,&(lvalues[4426]),0}, -{"ITU-T","itu-t",NID_itu_t,0,NULL,0}, -{"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,0,NULL,0}, -{"international-organizations","International Organizations", - NID_international_organizations,1,&(lvalues[4435]),0}, -{"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login, - 10,&(lvalues[4436]),0}, -{"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10, - &(lvalues[4446]),0}, -{"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0}, -{"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0}, -{"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0}, -{"AES-128-CFB8","aes-128-cfb8",NID_aes_128_cfb8,0,NULL,0}, -{"AES-192-CFB8","aes-192-cfb8",NID_aes_192_cfb8,0,NULL,0}, -{"AES-256-CFB8","aes-256-cfb8",NID_aes_256_cfb8,0,NULL,0}, -{"DES-CFB1","des-cfb1",NID_des_cfb1,0,NULL,0}, -{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0}, -{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0}, -{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0}, -{"street","streetAddress",NID_streetAddress,3,&(lvalues[4456]),0}, -{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4459]),0}, -{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4462]),0}, -{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8, - &(lvalues[4469]),0}, -{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8, - &(lvalues[4477]),0}, -{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8, - &(lvalues[4485]),0}, -{"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3, - &(lvalues[4493]),0}, -{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4496]),0}, -{"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9, - &(lvalues[4504]),0}, -{"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9, - &(lvalues[4513]),0}, -{"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9, - &(lvalues[4522]),0}, -{"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9, - &(lvalues[4531]),0}, -{"SHA256","sha256",NID_sha256,9,&(lvalues[4540]),0}, -{"SHA384","sha384",NID_sha384,9,&(lvalues[4549]),0}, -{"SHA512","sha512",NID_sha512,9,&(lvalues[4558]),0}, -{"SHA224","sha224",NID_sha224,9,&(lvalues[4567]),0}, -{"identified-organization","identified-organization", - NID_identified_organization,1,&(lvalues[4576]),0}, -{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4577]),0}, -{"wap","wap",NID_wap,2,&(lvalues[4580]),0}, -{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4582]),0}, -{"id-characteristic-two-basis","id-characteristic-two-basis", - NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4585]),0}, -{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4593]),0}, -{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4602]),0}, -{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4611]),0}, -{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4620]),0}, -{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4628]),0}, -{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4636]),0}, -{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4644]),0}, -{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4652]),0}, -{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4660]),0}, -{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4668]),0}, -{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4676]),0}, -{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4684]),0}, -{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4692]),0}, -{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4700]),0}, -{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4708]),0}, -{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4716]),0}, -{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4724]),0}, -{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4732]),0}, -{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4740]),0}, -{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4748]),0}, -{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4756]),0}, -{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4764]),0}, -{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4772]),0}, -{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4780]),0}, -{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4785]),0}, -{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4790]),0}, -{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4795]),0}, -{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4800]),0}, -{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4805]),0}, -{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4810]),0}, -{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4815]),0}, -{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4820]),0}, -{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4825]),0}, -{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4830]),0}, -{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4835]),0}, -{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4840]),0}, -{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4845]),0}, -{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4850]),0}, -{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4855]),0}, -{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4860]),0}, -{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4865]),0}, -{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4870]),0}, -{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4875]),0}, -{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4880]),0}, -{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4885]),0}, -{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4890]),0}, -{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4895]),0}, -{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4900]),0}, -{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4905]),0}, -{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4910]),0}, -{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4915]),0}, -{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4920]),0}, -{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4925]),0}, -{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4930]),0}, -{"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1", - NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4935]),0}, -{"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3", - NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4940]),0}, -{"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4", - NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4945]),0}, -{"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5", - NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4950]),0}, -{"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6", - NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4955]),0}, -{"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7", - NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4960]),0}, -{"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8", - NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4965]),0}, -{"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9", - NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4970]),0}, -{"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10", - NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4975]),0}, -{"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11", - NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4980]),0}, -{"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12", - NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4985]),0}, -{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4990]),0}, -{"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3, - &(lvalues[4994]),0}, -{"inhibitAnyPolicy","X509v3 Inhibit Any Policy", - NID_inhibit_any_policy,3,&(lvalues[4997]),0}, -{"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0}, -{"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0}, -{"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11, - &(lvalues[5000]),0}, -{"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11, - &(lvalues[5011]),0}, -{"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11, - &(lvalues[5022]),0}, -{"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8, - &(lvalues[5033]),0}, -{"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8, - &(lvalues[5041]),0}, -{"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8, - &(lvalues[5049]),0}, -{"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8, - &(lvalues[5057]),0}, -{"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8, - &(lvalues[5065]),0}, -{"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8, - &(lvalues[5073]),0}, -{"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0}, -{"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0}, -{"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0}, -{"CAMELLIA-128-CFB8","camellia-128-cfb8",NID_camellia_128_cfb8,0,NULL,0}, -{"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0}, -{"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0}, -{"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8, - &(lvalues[5081]),0}, -{"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8, - &(lvalues[5089]),0}, -{"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8, - &(lvalues[5097]),0}, -{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes", - NID_subject_directory_attributes,3,&(lvalues[5105]),0}, -{"issuingDistributionPoint","X509v3 Issuing Distrubution Point", - NID_issuing_distribution_point,3,&(lvalues[5108]),0}, -{"certificateIssuer","X509v3 Certificate Issuer", - NID_certificate_issuer,3,&(lvalues[5111]),0}, -{NULL,NULL,NID_undef,0,NULL,0}, -{"KISA","kisa",NID_kisa,6,&(lvalues[5114]),0}, -{NULL,NULL,NID_undef,0,NULL,0}, -{NULL,NULL,NID_undef,0,NULL,0}, -{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5120]),0}, -{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5128]),0}, -{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5136]),0}, -{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5144]),0}, -{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5152]),0}, -{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5160]),0}, -{"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9, - &(lvalues[5168]),0}, -{"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9, - &(lvalues[5177]),0}, -{"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8, - &(lvalues[5186]),0}, -{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5194]),0}, -{"id-smime-ct-compressedData","id-smime-ct-compressedData", - NID_id_smime_ct_compressedData,11,&(lvalues[5202]),0}, -{"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF", - NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5213]),0}, -{"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9, - &(lvalues[5224]),0}, -{"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9, - &(lvalues[5233]),0}, -{"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9, - &(lvalues[5242]),0}, -{"ecdsa-with-Recommended","ecdsa-with-Recommended", - NID_ecdsa_with_Recommended,7,&(lvalues[5251]),0}, -{"ecdsa-with-Specified","ecdsa-with-Specified", - NID_ecdsa_with_Specified,7,&(lvalues[5258]),0}, -{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8, - &(lvalues[5265]),0}, -{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8, - &(lvalues[5273]),0}, -{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8, - &(lvalues[5281]),0}, -{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8, - &(lvalues[5289]),0}, -{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5297]),0}, -{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8, - &(lvalues[5305]),0}, -{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8, - &(lvalues[5313]),0}, -{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8, - &(lvalues[5321]),0}, -{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8, - &(lvalues[5329]),0}, -{"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9, - &(lvalues[5337]),0}, -{"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9, - &(lvalues[5346]),0}, -{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5355]),0}, -{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5361]),0}, -{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5366]),0}, -{"id-GostR3411-94-with-GostR3410-2001", - "GOST R 34.11-94 with GOST R 34.10-2001", - NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5371]),0}, -{"id-GostR3411-94-with-GostR3410-94", - "GOST R 34.11-94 with GOST R 34.10-94", - NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5377]),0}, -{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5383]),0}, -{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6, - &(lvalues[5389]),0}, -{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6, - &(lvalues[5395]),0}, -{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5401]),0}, -{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5407]),0}, -{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0}, -{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6, - &(lvalues[5413]),0}, -{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6, - &(lvalues[5419]),0}, -{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH, - 6,&(lvalues[5425]),0}, -{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6, - &(lvalues[5431]),0}, -{"id-Gost28147-89-CryptoPro-KeyMeshing", - "id-Gost28147-89-CryptoPro-KeyMeshing", - NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5437]),0}, -{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing", - NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5444]),0}, -{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet", - NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5451]),0}, -{"id-GostR3411-94-CryptoProParamSet", - "id-GostR3411-94-CryptoProParamSet", - NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5458]),0}, -{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet", - NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5465]),0}, -{"id-Gost28147-89-CryptoPro-A-ParamSet", - "id-Gost28147-89-CryptoPro-A-ParamSet", - NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5472]),0}, -{"id-Gost28147-89-CryptoPro-B-ParamSet", - "id-Gost28147-89-CryptoPro-B-ParamSet", - NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5479]),0}, -{"id-Gost28147-89-CryptoPro-C-ParamSet", - "id-Gost28147-89-CryptoPro-C-ParamSet", - NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5486]),0}, -{"id-Gost28147-89-CryptoPro-D-ParamSet", - "id-Gost28147-89-CryptoPro-D-ParamSet", - NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5493]),0}, -{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", - "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", - NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5500]), - 0}, -{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", - "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", - NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5507]), - 0}, -{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", - "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", - NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5514]),0}, -{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet", - NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5521]),0}, -{"id-GostR3410-94-CryptoPro-A-ParamSet", - "id-GostR3410-94-CryptoPro-A-ParamSet", - NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5528]),0}, -{"id-GostR3410-94-CryptoPro-B-ParamSet", - "id-GostR3410-94-CryptoPro-B-ParamSet", - NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5535]),0}, -{"id-GostR3410-94-CryptoPro-C-ParamSet", - "id-GostR3410-94-CryptoPro-C-ParamSet", - NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5542]),0}, -{"id-GostR3410-94-CryptoPro-D-ParamSet", - "id-GostR3410-94-CryptoPro-D-ParamSet", - NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5549]),0}, -{"id-GostR3410-94-CryptoPro-XchA-ParamSet", - "id-GostR3410-94-CryptoPro-XchA-ParamSet", - NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5556]),0}, -{"id-GostR3410-94-CryptoPro-XchB-ParamSet", - "id-GostR3410-94-CryptoPro-XchB-ParamSet", - NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5563]),0}, -{"id-GostR3410-94-CryptoPro-XchC-ParamSet", - "id-GostR3410-94-CryptoPro-XchC-ParamSet", - NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5570]),0}, -{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet", - NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5577]),0}, -{"id-GostR3410-2001-CryptoPro-A-ParamSet", - "id-GostR3410-2001-CryptoPro-A-ParamSet", - NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5584]),0}, -{"id-GostR3410-2001-CryptoPro-B-ParamSet", - "id-GostR3410-2001-CryptoPro-B-ParamSet", - NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5591]),0}, -{"id-GostR3410-2001-CryptoPro-C-ParamSet", - "id-GostR3410-2001-CryptoPro-C-ParamSet", - NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5598]),0}, -{"id-GostR3410-2001-CryptoPro-XchA-ParamSet", - "id-GostR3410-2001-CryptoPro-XchA-ParamSet", - NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5605]),0}, - -{"id-GostR3410-2001-CryptoPro-XchB-ParamSet", - "id-GostR3410-2001-CryptoPro-XchB-ParamSet", - NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5612]),0}, - -{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7, - &(lvalues[5619]),0}, -{"id-GostR3410-94-aBis","id-GostR3410-94-aBis", - NID_id_GostR3410_94_aBis,7,&(lvalues[5626]),0}, -{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7, - &(lvalues[5633]),0}, -{"id-GostR3410-94-bBis","id-GostR3410-94-bBis", - NID_id_GostR3410_94_bBis,7,&(lvalues[5640]),0}, -{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet", - NID_id_Gost28147_89_cc,8,&(lvalues[5647]),0}, -{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8, - &(lvalues[5655]),0}, -{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8, - &(lvalues[5663]),0}, -{"id-GostR3411-94-with-GostR3410-94-cc", - "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom", - NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5671]),0}, -{"id-GostR3411-94-with-GostR3410-2001-cc", - "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom", - NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5679]),0}, -{"id-GostR3410-2001-ParamSet-cc", - "GOST R 3410-2001 Parameter Set Cryptocom", - NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5687]),0}, -{"HMAC","hmac",NID_hmac,0,NULL,0}, -{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9, - &(lvalues[5695]),0}, -{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3, - &(lvalues[5704]),0}, -{"id-on-permanentIdentifier","Permanent Identifier", - NID_id_on_permanentIdentifier,8,&(lvalues[5707]),0}, -{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5715]),0}, -{"businessCategory","businessCategory",NID_businessCategory,3, - &(lvalues[5718]),0}, -{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5721]),0}, -{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5724]),0}, -{"physicalDeliveryOfficeName","physicalDeliveryOfficeName", - NID_physicalDeliveryOfficeName,3,&(lvalues[5727]),0}, -{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3, - &(lvalues[5730]),0}, -{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5733]),0}, -{"teletexTerminalIdentifier","teletexTerminalIdentifier", - NID_teletexTerminalIdentifier,3,&(lvalues[5736]),0}, -{"facsimileTelephoneNumber","facsimileTelephoneNumber", - NID_facsimileTelephoneNumber,3,&(lvalues[5739]),0}, -{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5742]),0}, -{"internationaliSDNNumber","internationaliSDNNumber", - NID_internationaliSDNNumber,3,&(lvalues[5745]),0}, -{"registeredAddress","registeredAddress",NID_registeredAddress,3, - &(lvalues[5748]),0}, -{"destinationIndicator","destinationIndicator", - NID_destinationIndicator,3,&(lvalues[5751]),0}, -{"preferredDeliveryMethod","preferredDeliveryMethod", - NID_preferredDeliveryMethod,3,&(lvalues[5754]),0}, -{"presentationAddress","presentationAddress",NID_presentationAddress, - 3,&(lvalues[5757]),0}, -{"supportedApplicationContext","supportedApplicationContext", - NID_supportedApplicationContext,3,&(lvalues[5760]),0}, -{"member","member",NID_member,3,&(lvalues[5763]),0}, -{"owner","owner",NID_owner,3,&(lvalues[5766]),0}, -{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5769]),0}, -{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5772]),0}, -{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5775]),0}, -{"userCertificate","userCertificate",NID_userCertificate,3, - &(lvalues[5778]),0}, -{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5781]),0}, -{"authorityRevocationList","authorityRevocationList", - NID_authorityRevocationList,3,&(lvalues[5784]),0}, -{"certificateRevocationList","certificateRevocationList", - NID_certificateRevocationList,3,&(lvalues[5787]),0}, -{"crossCertificatePair","crossCertificatePair", - NID_crossCertificatePair,3,&(lvalues[5790]),0}, -{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide, - 3,&(lvalues[5793]),0}, -{"protocolInformation","protocolInformation",NID_protocolInformation, - 3,&(lvalues[5796]),0}, -{"distinguishedName","distinguishedName",NID_distinguishedName,3, - &(lvalues[5799]),0}, -{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5802]),0}, -{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3, - &(lvalues[5805]),0}, -{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms, - 3,&(lvalues[5808]),0}, -{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList, - 3,&(lvalues[5811]),0}, -{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5814]),0}, -{"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11, - &(lvalues[5817]),0}, -{"CMAC","cmac",NID_cmac,0,NULL,0}, -{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5828]),0}, -{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5837]),0}, -{"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9, - &(lvalues[5846]),0}, -{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5855]),0}, -{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5864]),0}, -{"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9, - &(lvalues[5873]),0}, -{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5882]),0}, -{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5891]),0}, -{"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9, - &(lvalues[5900]),0}, -{"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0}, -{"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0}, -{"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0}, -{"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap, - 11,&(lvalues[5909]),0}, -{"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap, - 11,&(lvalues[5920]),0}, -{"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap, - 11,&(lvalues[5931]),0}, -{"anyExtendedKeyUsage","Any Extended Key Usage", - NID_anyExtendedKeyUsage,4,&(lvalues[5942]),0}, -{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5946]),0}, -{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5955]),0}, -{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0}, -{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0}, -{"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0}, -{"AES-128-CBC-HMAC-SHA1","aes-128-cbc-hmac-sha1", - NID_aes_128_cbc_hmac_sha1,0,NULL,0}, -{"AES-192-CBC-HMAC-SHA1","aes-192-cbc-hmac-sha1", - NID_aes_192_cbc_hmac_sha1,0,NULL,0}, -{"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1", - NID_aes_256_cbc_hmac_sha1,0,NULL,0}, -{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5964]),0}, -{"dhpublicnumber","X9.42 DH",NID_dhpublicnumber,7,&(lvalues[5973]),0}, -{"brainpoolP160r1","brainpoolP160r1",NID_brainpoolP160r1,9, - &(lvalues[5980]),0}, -{"brainpoolP160t1","brainpoolP160t1",NID_brainpoolP160t1,9, - &(lvalues[5989]),0}, -{"brainpoolP192r1","brainpoolP192r1",NID_brainpoolP192r1,9, - &(lvalues[5998]),0}, -{"brainpoolP192t1","brainpoolP192t1",NID_brainpoolP192t1,9, - &(lvalues[6007]),0}, -{"brainpoolP224r1","brainpoolP224r1",NID_brainpoolP224r1,9, - &(lvalues[6016]),0}, -{"brainpoolP224t1","brainpoolP224t1",NID_brainpoolP224t1,9, - &(lvalues[6025]),0}, -{"brainpoolP256r1","brainpoolP256r1",NID_brainpoolP256r1,9, - &(lvalues[6034]),0}, -{"brainpoolP256t1","brainpoolP256t1",NID_brainpoolP256t1,9, - &(lvalues[6043]),0}, -{"brainpoolP320r1","brainpoolP320r1",NID_brainpoolP320r1,9, - &(lvalues[6052]),0}, -{"brainpoolP320t1","brainpoolP320t1",NID_brainpoolP320t1,9, - &(lvalues[6061]),0}, -{"brainpoolP384r1","brainpoolP384r1",NID_brainpoolP384r1,9, - &(lvalues[6070]),0}, -{"brainpoolP384t1","brainpoolP384t1",NID_brainpoolP384t1,9, - &(lvalues[6079]),0}, -{"brainpoolP512r1","brainpoolP512r1",NID_brainpoolP512r1,9, - &(lvalues[6088]),0}, -{"brainpoolP512t1","brainpoolP512t1",NID_brainpoolP512t1,9, - &(lvalues[6097]),0}, -{"PSPECIFIED","pSpecified",NID_pSpecified,9,&(lvalues[6106]),0}, -{"dhSinglePass-stdDH-sha1kdf-scheme", - "dhSinglePass-stdDH-sha1kdf-scheme", - NID_dhSinglePass_stdDH_sha1kdf_scheme,9,&(lvalues[6115]),0}, -{"dhSinglePass-stdDH-sha224kdf-scheme", - "dhSinglePass-stdDH-sha224kdf-scheme", - NID_dhSinglePass_stdDH_sha224kdf_scheme,6,&(lvalues[6124]),0}, -{"dhSinglePass-stdDH-sha256kdf-scheme", - "dhSinglePass-stdDH-sha256kdf-scheme", - NID_dhSinglePass_stdDH_sha256kdf_scheme,6,&(lvalues[6130]),0}, -{"dhSinglePass-stdDH-sha384kdf-scheme", - "dhSinglePass-stdDH-sha384kdf-scheme", - NID_dhSinglePass_stdDH_sha384kdf_scheme,6,&(lvalues[6136]),0}, -{"dhSinglePass-stdDH-sha512kdf-scheme", - "dhSinglePass-stdDH-sha512kdf-scheme", - NID_dhSinglePass_stdDH_sha512kdf_scheme,6,&(lvalues[6142]),0}, -{"dhSinglePass-cofactorDH-sha1kdf-scheme", - "dhSinglePass-cofactorDH-sha1kdf-scheme", - NID_dhSinglePass_cofactorDH_sha1kdf_scheme,9,&(lvalues[6148]),0}, -{"dhSinglePass-cofactorDH-sha224kdf-scheme", - "dhSinglePass-cofactorDH-sha224kdf-scheme", - NID_dhSinglePass_cofactorDH_sha224kdf_scheme,6,&(lvalues[6157]),0}, -{"dhSinglePass-cofactorDH-sha256kdf-scheme", - "dhSinglePass-cofactorDH-sha256kdf-scheme", - NID_dhSinglePass_cofactorDH_sha256kdf_scheme,6,&(lvalues[6163]),0}, -{"dhSinglePass-cofactorDH-sha384kdf-scheme", - "dhSinglePass-cofactorDH-sha384kdf-scheme", - NID_dhSinglePass_cofactorDH_sha384kdf_scheme,6,&(lvalues[6169]),0}, -{"dhSinglePass-cofactorDH-sha512kdf-scheme", - "dhSinglePass-cofactorDH-sha512kdf-scheme", - NID_dhSinglePass_cofactorDH_sha512kdf_scheme,6,&(lvalues[6175]),0}, -{"dh-std-kdf","dh-std-kdf",NID_dh_std_kdf,0,NULL,0}, -{"dh-cofactor-kdf","dh-cofactor-kdf",NID_dh_cofactor_kdf,0,NULL,0}, -{"AES-128-CBC-HMAC-SHA256","aes-128-cbc-hmac-sha256", - NID_aes_128_cbc_hmac_sha256,0,NULL,0}, -{"AES-192-CBC-HMAC-SHA256","aes-192-cbc-hmac-sha256", - NID_aes_192_cbc_hmac_sha256,0,NULL,0}, -{"AES-256-CBC-HMAC-SHA256","aes-256-cbc-hmac-sha256", - NID_aes_256_cbc_hmac_sha256,0,NULL,0}, -{"ct_precert_scts","CT Precertificate SCTs",NID_ct_precert_scts,10, - &(lvalues[6181]),0}, -{"ct_precert_poison","CT Precertificate Poison",NID_ct_precert_poison, - 10,&(lvalues[6191]),0}, -{"ct_precert_signer","CT Precertificate Signer",NID_ct_precert_signer, - 10,&(lvalues[6201]),0}, -{"ct_cert_scts","CT Certificate SCTs",NID_ct_cert_scts,10, - &(lvalues[6211]),0}, -{"jurisdictionL","jurisdictionLocalityName", - NID_jurisdictionLocalityName,11,&(lvalues[6221]),0}, -{"jurisdictionST","jurisdictionStateOrProvinceName", - NID_jurisdictionStateOrProvinceName,11,&(lvalues[6232]),0}, -{"jurisdictionC","jurisdictionCountryName", - NID_jurisdictionCountryName,11,&(lvalues[6243]),0}, -}; - -static const unsigned int sn_objs[NUM_SN]={ -364, /* "AD_DVCS" */ -419, /* "AES-128-CBC" */ -916, /* "AES-128-CBC-HMAC-SHA1" */ -948, /* "AES-128-CBC-HMAC-SHA256" */ -421, /* "AES-128-CFB" */ -650, /* "AES-128-CFB1" */ -653, /* "AES-128-CFB8" */ -904, /* "AES-128-CTR" */ -418, /* "AES-128-ECB" */ -420, /* "AES-128-OFB" */ -913, /* "AES-128-XTS" */ -423, /* "AES-192-CBC" */ -917, /* "AES-192-CBC-HMAC-SHA1" */ -949, /* "AES-192-CBC-HMAC-SHA256" */ -425, /* "AES-192-CFB" */ -651, /* "AES-192-CFB1" */ -654, /* "AES-192-CFB8" */ -905, /* "AES-192-CTR" */ -422, /* "AES-192-ECB" */ -424, /* "AES-192-OFB" */ -427, /* "AES-256-CBC" */ -918, /* "AES-256-CBC-HMAC-SHA1" */ -950, /* "AES-256-CBC-HMAC-SHA256" */ -429, /* "AES-256-CFB" */ -652, /* "AES-256-CFB1" */ -655, /* "AES-256-CFB8" */ -906, /* "AES-256-CTR" */ -426, /* "AES-256-ECB" */ -428, /* "AES-256-OFB" */ -914, /* "AES-256-XTS" */ -91, /* "BF-CBC" */ -93, /* "BF-CFB" */ -92, /* "BF-ECB" */ -94, /* "BF-OFB" */ -14, /* "C" */ -751, /* "CAMELLIA-128-CBC" */ -757, /* "CAMELLIA-128-CFB" */ -760, /* "CAMELLIA-128-CFB1" */ -763, /* "CAMELLIA-128-CFB8" */ -754, /* "CAMELLIA-128-ECB" */ -766, /* "CAMELLIA-128-OFB" */ -752, /* "CAMELLIA-192-CBC" */ -758, /* "CAMELLIA-192-CFB" */ -761, /* "CAMELLIA-192-CFB1" */ -764, /* "CAMELLIA-192-CFB8" */ -755, /* "CAMELLIA-192-ECB" */ -767, /* "CAMELLIA-192-OFB" */ -753, /* "CAMELLIA-256-CBC" */ -759, /* "CAMELLIA-256-CFB" */ -762, /* "CAMELLIA-256-CFB1" */ -765, /* "CAMELLIA-256-CFB8" */ -756, /* "CAMELLIA-256-ECB" */ -768, /* "CAMELLIA-256-OFB" */ -108, /* "CAST5-CBC" */ -110, /* "CAST5-CFB" */ -109, /* "CAST5-ECB" */ -111, /* "CAST5-OFB" */ -894, /* "CMAC" */ -13, /* "CN" */ -141, /* "CRLReason" */ -417, /* "CSPName" */ -367, /* "CrlID" */ -391, /* "DC" */ -31, /* "DES-CBC" */ -643, /* "DES-CDMF" */ -30, /* "DES-CFB" */ -656, /* "DES-CFB1" */ -657, /* "DES-CFB8" */ -29, /* "DES-ECB" */ -32, /* "DES-EDE" */ -43, /* "DES-EDE-CBC" */ -60, /* "DES-EDE-CFB" */ -62, /* "DES-EDE-OFB" */ -33, /* "DES-EDE3" */ -44, /* "DES-EDE3-CBC" */ -61, /* "DES-EDE3-CFB" */ -658, /* "DES-EDE3-CFB1" */ -659, /* "DES-EDE3-CFB8" */ -63, /* "DES-EDE3-OFB" */ -45, /* "DES-OFB" */ -80, /* "DESX-CBC" */ -380, /* "DOD" */ -116, /* "DSA" */ -66, /* "DSA-SHA" */ -113, /* "DSA-SHA1" */ -70, /* "DSA-SHA1-old" */ -67, /* "DSA-old" */ -297, /* "DVCS" */ -99, /* "GN" */ -855, /* "HMAC" */ -780, /* "HMAC-MD5" */ -781, /* "HMAC-SHA1" */ -381, /* "IANA" */ -34, /* "IDEA-CBC" */ -35, /* "IDEA-CFB" */ -36, /* "IDEA-ECB" */ -46, /* "IDEA-OFB" */ -181, /* "ISO" */ -183, /* "ISO-US" */ -645, /* "ITU-T" */ -646, /* "JOINT-ISO-ITU-T" */ -773, /* "KISA" */ -15, /* "L" */ -856, /* "LocalKeySet" */ - 3, /* "MD2" */ -257, /* "MD4" */ - 4, /* "MD5" */ -114, /* "MD5-SHA1" */ -95, /* "MDC2" */ -911, /* "MGF1" */ -388, /* "Mail" */ -393, /* "NULL" */ -404, /* "NULL" */ -57, /* "Netscape" */ -366, /* "Nonce" */ -17, /* "O" */ -178, /* "OCSP" */ -180, /* "OCSPSigning" */ -379, /* "ORG" */ -18, /* "OU" */ -749, /* "Oakley-EC2N-3" */ -750, /* "Oakley-EC2N-4" */ - 9, /* "PBE-MD2-DES" */ -168, /* "PBE-MD2-RC2-64" */ -10, /* "PBE-MD5-DES" */ -169, /* "PBE-MD5-RC2-64" */ -147, /* "PBE-SHA1-2DES" */ -146, /* "PBE-SHA1-3DES" */ -170, /* "PBE-SHA1-DES" */ -148, /* "PBE-SHA1-RC2-128" */ -149, /* "PBE-SHA1-RC2-40" */ -68, /* "PBE-SHA1-RC2-64" */ -144, /* "PBE-SHA1-RC4-128" */ -145, /* "PBE-SHA1-RC4-40" */ -161, /* "PBES2" */ -69, /* "PBKDF2" */ -162, /* "PBMAC1" */ -127, /* "PKIX" */ -935, /* "PSPECIFIED" */ -98, /* "RC2-40-CBC" */ -166, /* "RC2-64-CBC" */ -37, /* "RC2-CBC" */ -39, /* "RC2-CFB" */ -38, /* "RC2-ECB" */ -40, /* "RC2-OFB" */ - 5, /* "RC4" */ -97, /* "RC4-40" */ -915, /* "RC4-HMAC-MD5" */ -120, /* "RC5-CBC" */ -122, /* "RC5-CFB" */ -121, /* "RC5-ECB" */ -123, /* "RC5-OFB" */ -117, /* "RIPEMD160" */ -124, /* "RLE" */ -19, /* "RSA" */ - 7, /* "RSA-MD2" */ -396, /* "RSA-MD4" */ - 8, /* "RSA-MD5" */ -96, /* "RSA-MDC2" */ -104, /* "RSA-NP-MD5" */ -119, /* "RSA-RIPEMD160" */ -42, /* "RSA-SHA" */ -65, /* "RSA-SHA1" */ -115, /* "RSA-SHA1-2" */ -671, /* "RSA-SHA224" */ -668, /* "RSA-SHA256" */ -669, /* "RSA-SHA384" */ -670, /* "RSA-SHA512" */ -919, /* "RSAES-OAEP" */ -912, /* "RSASSA-PSS" */ -777, /* "SEED-CBC" */ -779, /* "SEED-CFB" */ -776, /* "SEED-ECB" */ -778, /* "SEED-OFB" */ -41, /* "SHA" */ -64, /* "SHA1" */ -675, /* "SHA224" */ -672, /* "SHA256" */ -673, /* "SHA384" */ -674, /* "SHA512" */ -188, /* "SMIME" */ -167, /* "SMIME-CAPS" */ -100, /* "SN" */ -16, /* "ST" */ -143, /* "SXNetID" */ -458, /* "UID" */ - 0, /* "UNDEF" */ -11, /* "X500" */ -378, /* "X500algorithms" */ -12, /* "X509" */ -184, /* "X9-57" */ -185, /* "X9cm" */ -125, /* "ZLIB" */ -478, /* "aRecord" */ -289, /* "aaControls" */ -287, /* "ac-auditEntity" */ -397, /* "ac-proxying" */ -288, /* "ac-targeting" */ -368, /* "acceptableResponses" */ -446, /* "account" */ -363, /* "ad_timestamping" */ -376, /* "algorithm" */ -405, /* "ansi-X9-62" */ -910, /* "anyExtendedKeyUsage" */ -746, /* "anyPolicy" */ -370, /* "archiveCutoff" */ -484, /* "associatedDomain" */ -485, /* "associatedName" */ -501, /* "audio" */ -177, /* "authorityInfoAccess" */ -90, /* "authorityKeyIdentifier" */ -882, /* "authorityRevocationList" */ -87, /* "basicConstraints" */ -365, /* "basicOCSPResponse" */ -285, /* "biometricInfo" */ -921, /* "brainpoolP160r1" */ -922, /* "brainpoolP160t1" */ -923, /* "brainpoolP192r1" */ -924, /* "brainpoolP192t1" */ -925, /* "brainpoolP224r1" */ -926, /* "brainpoolP224t1" */ -927, /* "brainpoolP256r1" */ -928, /* "brainpoolP256t1" */ -929, /* "brainpoolP320r1" */ -930, /* "brainpoolP320t1" */ -931, /* "brainpoolP384r1" */ -932, /* "brainpoolP384t1" */ -933, /* "brainpoolP512r1" */ -934, /* "brainpoolP512t1" */ -494, /* "buildingName" */ -860, /* "businessCategory" */ -691, /* "c2onb191v4" */ -692, /* "c2onb191v5" */ -697, /* "c2onb239v4" */ -698, /* "c2onb239v5" */ -684, /* "c2pnb163v1" */ -685, /* "c2pnb163v2" */ -686, /* "c2pnb163v3" */ -687, /* "c2pnb176v1" */ -693, /* "c2pnb208w1" */ -699, /* "c2pnb272w1" */ -700, /* "c2pnb304w1" */ -702, /* "c2pnb368w1" */ -688, /* "c2tnb191v1" */ -689, /* "c2tnb191v2" */ -690, /* "c2tnb191v3" */ -694, /* "c2tnb239v1" */ -695, /* "c2tnb239v2" */ -696, /* "c2tnb239v3" */ -701, /* "c2tnb359v1" */ -703, /* "c2tnb431r1" */ -881, /* "cACertificate" */ -483, /* "cNAMERecord" */ -179, /* "caIssuers" */ -785, /* "caRepository" */ -443, /* "caseIgnoreIA5StringSyntax" */ -152, /* "certBag" */ -677, /* "certicom-arc" */ -771, /* "certificateIssuer" */ -89, /* "certificatePolicies" */ -883, /* "certificateRevocationList" */ -54, /* "challengePassword" */ -407, /* "characteristic-two-field" */ -395, /* "clearance" */ -130, /* "clientAuth" */ -131, /* "codeSigning" */ -50, /* "contentType" */ -53, /* "countersignature" */ -153, /* "crlBag" */ -103, /* "crlDistributionPoints" */ -88, /* "crlNumber" */ -884, /* "crossCertificatePair" */ -806, /* "cryptocom" */ -805, /* "cryptopro" */ -954, /* "ct_cert_scts" */ -952, /* "ct_precert_poison" */ -951, /* "ct_precert_scts" */ -953, /* "ct_precert_signer" */ -500, /* "dITRedirect" */ -451, /* "dNSDomain" */ -495, /* "dSAQuality" */ -434, /* "data" */ -390, /* "dcobject" */ -140, /* "deltaCRL" */ -891, /* "deltaRevocationList" */ -107, /* "description" */ -871, /* "destinationIndicator" */ -947, /* "dh-cofactor-kdf" */ -946, /* "dh-std-kdf" */ -28, /* "dhKeyAgreement" */ -941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */ -942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */ -943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */ -944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */ -945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */ -936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */ -937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */ -938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */ -939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */ -940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */ -920, /* "dhpublicnumber" */ -382, /* "directory" */ -887, /* "distinguishedName" */ -892, /* "dmdName" */ -174, /* "dnQualifier" */ -447, /* "document" */ -471, /* "documentAuthor" */ -468, /* "documentIdentifier" */ -472, /* "documentLocation" */ -502, /* "documentPublisher" */ -449, /* "documentSeries" */ -469, /* "documentTitle" */ -470, /* "documentVersion" */ -392, /* "domain" */ -452, /* "domainRelatedObject" */ -802, /* "dsa_with_SHA224" */ -803, /* "dsa_with_SHA256" */ -791, /* "ecdsa-with-Recommended" */ -416, /* "ecdsa-with-SHA1" */ -793, /* "ecdsa-with-SHA224" */ -794, /* "ecdsa-with-SHA256" */ -795, /* "ecdsa-with-SHA384" */ -796, /* "ecdsa-with-SHA512" */ -792, /* "ecdsa-with-Specified" */ -48, /* "emailAddress" */ -132, /* "emailProtection" */ -885, /* "enhancedSearchGuide" */ -389, /* "enterprises" */ -384, /* "experimental" */ -172, /* "extReq" */ -56, /* "extendedCertificateAttributes" */ -126, /* "extendedKeyUsage" */ -372, /* "extendedStatus" */ -867, /* "facsimileTelephoneNumber" */ -462, /* "favouriteDrink" */ -857, /* "freshestCRL" */ -453, /* "friendlyCountry" */ -490, /* "friendlyCountryName" */ -156, /* "friendlyName" */ -509, /* "generationQualifier" */ -815, /* "gost-mac" */ -811, /* "gost2001" */ -851, /* "gost2001cc" */ -813, /* "gost89" */ -814, /* "gost89-cnt" */ -812, /* "gost94" */ -850, /* "gost94cc" */ -797, /* "hmacWithMD5" */ -163, /* "hmacWithSHA1" */ -798, /* "hmacWithSHA224" */ -799, /* "hmacWithSHA256" */ -800, /* "hmacWithSHA384" */ -801, /* "hmacWithSHA512" */ -432, /* "holdInstructionCallIssuer" */ -430, /* "holdInstructionCode" */ -431, /* "holdInstructionNone" */ -433, /* "holdInstructionReject" */ -486, /* "homePostalAddress" */ -473, /* "homeTelephoneNumber" */ -466, /* "host" */ -889, /* "houseIdentifier" */ -442, /* "iA5StringSyntax" */ -783, /* "id-DHBasedMac" */ -824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ -825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ -826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ -827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ -819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ -829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ -828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ -830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ -820, /* "id-Gost28147-89-None-KeyMeshing" */ -823, /* "id-Gost28147-89-TestParamSet" */ -849, /* "id-Gost28147-89-cc" */ -840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ -841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ -842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ -843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ -844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ -854, /* "id-GostR3410-2001-ParamSet-cc" */ -839, /* "id-GostR3410-2001-TestParamSet" */ -817, /* "id-GostR3410-2001DH" */ -832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ -833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ -834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ -835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ -836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ -837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ -838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ -831, /* "id-GostR3410-94-TestParamSet" */ -845, /* "id-GostR3410-94-a" */ -846, /* "id-GostR3410-94-aBis" */ -847, /* "id-GostR3410-94-b" */ -848, /* "id-GostR3410-94-bBis" */ -818, /* "id-GostR3410-94DH" */ -822, /* "id-GostR3411-94-CryptoProParamSet" */ -821, /* "id-GostR3411-94-TestParamSet" */ -807, /* "id-GostR3411-94-with-GostR3410-2001" */ -853, /* "id-GostR3411-94-with-GostR3410-2001-cc" */ -808, /* "id-GostR3411-94-with-GostR3410-94" */ -852, /* "id-GostR3411-94-with-GostR3410-94-cc" */ -810, /* "id-HMACGostR3411-94" */ -782, /* "id-PasswordBasedMAC" */ -266, /* "id-aca" */ -355, /* "id-aca-accessIdentity" */ -354, /* "id-aca-authenticationInfo" */ -356, /* "id-aca-chargingIdentity" */ -399, /* "id-aca-encAttrs" */ -357, /* "id-aca-group" */ -358, /* "id-aca-role" */ -176, /* "id-ad" */ -896, /* "id-aes128-CCM" */ -895, /* "id-aes128-GCM" */ -788, /* "id-aes128-wrap" */ -897, /* "id-aes128-wrap-pad" */ -899, /* "id-aes192-CCM" */ -898, /* "id-aes192-GCM" */ -789, /* "id-aes192-wrap" */ -900, /* "id-aes192-wrap-pad" */ -902, /* "id-aes256-CCM" */ -901, /* "id-aes256-GCM" */ -790, /* "id-aes256-wrap" */ -903, /* "id-aes256-wrap-pad" */ -262, /* "id-alg" */ -893, /* "id-alg-PWRI-KEK" */ -323, /* "id-alg-des40" */ -326, /* "id-alg-dh-pop" */ -325, /* "id-alg-dh-sig-hmac-sha1" */ -324, /* "id-alg-noSignature" */ -907, /* "id-camellia128-wrap" */ -908, /* "id-camellia192-wrap" */ -909, /* "id-camellia256-wrap" */ -268, /* "id-cct" */ -361, /* "id-cct-PKIData" */ -362, /* "id-cct-PKIResponse" */ -360, /* "id-cct-crs" */ -81, /* "id-ce" */ -680, /* "id-characteristic-two-basis" */ -263, /* "id-cmc" */ -334, /* "id-cmc-addExtensions" */ -346, /* "id-cmc-confirmCertAcceptance" */ -330, /* "id-cmc-dataReturn" */ -336, /* "id-cmc-decryptedPOP" */ -335, /* "id-cmc-encryptedPOP" */ -339, /* "id-cmc-getCRL" */ -338, /* "id-cmc-getCert" */ -328, /* "id-cmc-identification" */ -329, /* "id-cmc-identityProof" */ -337, /* "id-cmc-lraPOPWitness" */ -344, /* "id-cmc-popLinkRandom" */ -345, /* "id-cmc-popLinkWitness" */ -343, /* "id-cmc-queryPending" */ -333, /* "id-cmc-recipientNonce" */ -341, /* "id-cmc-regInfo" */ -342, /* "id-cmc-responseInfo" */ -340, /* "id-cmc-revokeRequest" */ -332, /* "id-cmc-senderNonce" */ -327, /* "id-cmc-statusInfo" */ -331, /* "id-cmc-transactionId" */ -787, /* "id-ct-asciiTextWithCRLF" */ -408, /* "id-ecPublicKey" */ -508, /* "id-hex-multipart-message" */ -507, /* "id-hex-partial-message" */ -260, /* "id-it" */ -302, /* "id-it-caKeyUpdateInfo" */ -298, /* "id-it-caProtEncCert" */ -311, /* "id-it-confirmWaitTime" */ -303, /* "id-it-currentCRL" */ -300, /* "id-it-encKeyPairTypes" */ -310, /* "id-it-implicitConfirm" */ -308, /* "id-it-keyPairParamRep" */ -307, /* "id-it-keyPairParamReq" */ -312, /* "id-it-origPKIMessage" */ -301, /* "id-it-preferredSymmAlg" */ -309, /* "id-it-revPassphrase" */ -299, /* "id-it-signKeyPairTypes" */ -305, /* "id-it-subscriptionRequest" */ -306, /* "id-it-subscriptionResponse" */ -784, /* "id-it-suppLangTags" */ -304, /* "id-it-unsupportedOIDs" */ -128, /* "id-kp" */ -280, /* "id-mod-attribute-cert" */ -274, /* "id-mod-cmc" */ -277, /* "id-mod-cmp" */ -284, /* "id-mod-cmp2000" */ -273, /* "id-mod-crmf" */ -283, /* "id-mod-dvcs" */ -275, /* "id-mod-kea-profile-88" */ -276, /* "id-mod-kea-profile-93" */ -282, /* "id-mod-ocsp" */ -278, /* "id-mod-qualified-cert-88" */ -279, /* "id-mod-qualified-cert-93" */ -281, /* "id-mod-timestamp-protocol" */ -264, /* "id-on" */ -858, /* "id-on-permanentIdentifier" */ -347, /* "id-on-personalData" */ -265, /* "id-pda" */ -352, /* "id-pda-countryOfCitizenship" */ -353, /* "id-pda-countryOfResidence" */ -348, /* "id-pda-dateOfBirth" */ -351, /* "id-pda-gender" */ -349, /* "id-pda-placeOfBirth" */ -175, /* "id-pe" */ -261, /* "id-pkip" */ -258, /* "id-pkix-mod" */ -269, /* "id-pkix1-explicit-88" */ -271, /* "id-pkix1-explicit-93" */ -270, /* "id-pkix1-implicit-88" */ -272, /* "id-pkix1-implicit-93" */ -662, /* "id-ppl" */ -664, /* "id-ppl-anyLanguage" */ -667, /* "id-ppl-independent" */ -665, /* "id-ppl-inheritAll" */ -267, /* "id-qcs" */ -359, /* "id-qcs-pkixQCSyntax-v1" */ -259, /* "id-qt" */ -164, /* "id-qt-cps" */ -165, /* "id-qt-unotice" */ -313, /* "id-regCtrl" */ -316, /* "id-regCtrl-authenticator" */ -319, /* "id-regCtrl-oldCertID" */ -318, /* "id-regCtrl-pkiArchiveOptions" */ -317, /* "id-regCtrl-pkiPublicationInfo" */ -320, /* "id-regCtrl-protocolEncrKey" */ -315, /* "id-regCtrl-regToken" */ -314, /* "id-regInfo" */ -322, /* "id-regInfo-certReq" */ -321, /* "id-regInfo-utf8Pairs" */ -512, /* "id-set" */ -191, /* "id-smime-aa" */ -215, /* "id-smime-aa-contentHint" */ -218, /* "id-smime-aa-contentIdentifier" */ -221, /* "id-smime-aa-contentReference" */ -240, /* "id-smime-aa-dvcs-dvc" */ -217, /* "id-smime-aa-encapContentType" */ -222, /* "id-smime-aa-encrypKeyPref" */ -220, /* "id-smime-aa-equivalentLabels" */ -232, /* "id-smime-aa-ets-CertificateRefs" */ -233, /* "id-smime-aa-ets-RevocationRefs" */ -238, /* "id-smime-aa-ets-archiveTimeStamp" */ -237, /* "id-smime-aa-ets-certCRLTimestamp" */ -234, /* "id-smime-aa-ets-certValues" */ -227, /* "id-smime-aa-ets-commitmentType" */ -231, /* "id-smime-aa-ets-contentTimestamp" */ -236, /* "id-smime-aa-ets-escTimeStamp" */ -230, /* "id-smime-aa-ets-otherSigCert" */ -235, /* "id-smime-aa-ets-revocationValues" */ -226, /* "id-smime-aa-ets-sigPolicyId" */ -229, /* "id-smime-aa-ets-signerAttr" */ -228, /* "id-smime-aa-ets-signerLocation" */ -219, /* "id-smime-aa-macValue" */ -214, /* "id-smime-aa-mlExpandHistory" */ -216, /* "id-smime-aa-msgSigDigest" */ -212, /* "id-smime-aa-receiptRequest" */ -213, /* "id-smime-aa-securityLabel" */ -239, /* "id-smime-aa-signatureType" */ -223, /* "id-smime-aa-signingCertificate" */ -224, /* "id-smime-aa-smimeEncryptCerts" */ -225, /* "id-smime-aa-timeStampToken" */ -192, /* "id-smime-alg" */ -243, /* "id-smime-alg-3DESwrap" */ -246, /* "id-smime-alg-CMS3DESwrap" */ -247, /* "id-smime-alg-CMSRC2wrap" */ -245, /* "id-smime-alg-ESDH" */ -241, /* "id-smime-alg-ESDHwith3DES" */ -242, /* "id-smime-alg-ESDHwithRC2" */ -244, /* "id-smime-alg-RC2wrap" */ -193, /* "id-smime-cd" */ -248, /* "id-smime-cd-ldap" */ -190, /* "id-smime-ct" */ -210, /* "id-smime-ct-DVCSRequestData" */ -211, /* "id-smime-ct-DVCSResponseData" */ -208, /* "id-smime-ct-TDTInfo" */ -207, /* "id-smime-ct-TSTInfo" */ -205, /* "id-smime-ct-authData" */ -786, /* "id-smime-ct-compressedData" */ -209, /* "id-smime-ct-contentInfo" */ -206, /* "id-smime-ct-publishCert" */ -204, /* "id-smime-ct-receipt" */ -195, /* "id-smime-cti" */ -255, /* "id-smime-cti-ets-proofOfApproval" */ -256, /* "id-smime-cti-ets-proofOfCreation" */ -253, /* "id-smime-cti-ets-proofOfDelivery" */ -251, /* "id-smime-cti-ets-proofOfOrigin" */ -252, /* "id-smime-cti-ets-proofOfReceipt" */ -254, /* "id-smime-cti-ets-proofOfSender" */ -189, /* "id-smime-mod" */ -196, /* "id-smime-mod-cms" */ -197, /* "id-smime-mod-ess" */ -202, /* "id-smime-mod-ets-eSigPolicy-88" */ -203, /* "id-smime-mod-ets-eSigPolicy-97" */ -200, /* "id-smime-mod-ets-eSignature-88" */ -201, /* "id-smime-mod-ets-eSignature-97" */ -199, /* "id-smime-mod-msg-v3" */ -198, /* "id-smime-mod-oid" */ -194, /* "id-smime-spq" */ -250, /* "id-smime-spq-ets-sqt-unotice" */ -249, /* "id-smime-spq-ets-sqt-uri" */ -676, /* "identified-organization" */ -461, /* "info" */ -748, /* "inhibitAnyPolicy" */ -101, /* "initials" */ -647, /* "international-organizations" */ -869, /* "internationaliSDNNumber" */ -142, /* "invalidityDate" */ -294, /* "ipsecEndSystem" */ -295, /* "ipsecTunnel" */ -296, /* "ipsecUser" */ -86, /* "issuerAltName" */ -770, /* "issuingDistributionPoint" */ -492, /* "janetMailbox" */ -957, /* "jurisdictionC" */ -955, /* "jurisdictionL" */ -956, /* "jurisdictionST" */ -150, /* "keyBag" */ -83, /* "keyUsage" */ -477, /* "lastModifiedBy" */ -476, /* "lastModifiedTime" */ -157, /* "localKeyID" */ -480, /* "mXRecord" */ -460, /* "mail" */ -493, /* "mailPreferenceOption" */ -467, /* "manager" */ -809, /* "md_gost94" */ -875, /* "member" */ -182, /* "member-body" */ -51, /* "messageDigest" */ -383, /* "mgmt" */ -504, /* "mime-mhs" */ -506, /* "mime-mhs-bodies" */ -505, /* "mime-mhs-headings" */ -488, /* "mobileTelephoneNumber" */ -136, /* "msCTLSign" */ -135, /* "msCodeCom" */ -134, /* "msCodeInd" */ -138, /* "msEFS" */ -171, /* "msExtReq" */ -137, /* "msSGC" */ -648, /* "msSmartcardLogin" */ -649, /* "msUPN" */ -481, /* "nSRecord" */ -173, /* "name" */ -666, /* "nameConstraints" */ -369, /* "noCheck" */ -403, /* "noRevAvail" */ -72, /* "nsBaseUrl" */ -76, /* "nsCaPolicyUrl" */ -74, /* "nsCaRevocationUrl" */ -58, /* "nsCertExt" */ -79, /* "nsCertSequence" */ -71, /* "nsCertType" */ -78, /* "nsComment" */ -59, /* "nsDataType" */ -75, /* "nsRenewalUrl" */ -73, /* "nsRevocationUrl" */ -139, /* "nsSGC" */ -77, /* "nsSslServerName" */ -681, /* "onBasis" */ -491, /* "organizationalStatus" */ -475, /* "otherMailbox" */ -876, /* "owner" */ -489, /* "pagerTelephoneNumber" */ -374, /* "path" */ -112, /* "pbeWithMD5AndCast5CBC" */ -499, /* "personalSignature" */ -487, /* "personalTitle" */ -464, /* "photo" */ -863, /* "physicalDeliveryOfficeName" */ -437, /* "pilot" */ -439, /* "pilotAttributeSyntax" */ -438, /* "pilotAttributeType" */ -479, /* "pilotAttributeType27" */ -456, /* "pilotDSA" */ -441, /* "pilotGroups" */ -444, /* "pilotObject" */ -440, /* "pilotObjectClass" */ -455, /* "pilotOrganization" */ -445, /* "pilotPerson" */ - 2, /* "pkcs" */ -186, /* "pkcs1" */ -27, /* "pkcs3" */ -187, /* "pkcs5" */ -20, /* "pkcs7" */ -21, /* "pkcs7-data" */ -25, /* "pkcs7-digestData" */ -26, /* "pkcs7-encryptedData" */ -23, /* "pkcs7-envelopedData" */ -24, /* "pkcs7-signedAndEnvelopedData" */ -22, /* "pkcs7-signedData" */ -151, /* "pkcs8ShroudedKeyBag" */ -47, /* "pkcs9" */ -401, /* "policyConstraints" */ -747, /* "policyMappings" */ -862, /* "postOfficeBox" */ -861, /* "postalAddress" */ -661, /* "postalCode" */ -683, /* "ppBasis" */ -872, /* "preferredDeliveryMethod" */ -873, /* "presentationAddress" */ -816, /* "prf-gostr3411-94" */ -406, /* "prime-field" */ -409, /* "prime192v1" */ -410, /* "prime192v2" */ -411, /* "prime192v3" */ -412, /* "prime239v1" */ -413, /* "prime239v2" */ -414, /* "prime239v3" */ -415, /* "prime256v1" */ -385, /* "private" */ -84, /* "privateKeyUsagePeriod" */ -886, /* "protocolInformation" */ -663, /* "proxyCertInfo" */ -510, /* "pseudonym" */ -435, /* "pss" */ -286, /* "qcStatements" */ -457, /* "qualityLabelledData" */ -450, /* "rFC822localPart" */ -870, /* "registeredAddress" */ -400, /* "role" */ -877, /* "roleOccupant" */ -448, /* "room" */ -463, /* "roomNumber" */ - 6, /* "rsaEncryption" */ -644, /* "rsaOAEPEncryptionSET" */ -377, /* "rsaSignature" */ - 1, /* "rsadsi" */ -482, /* "sOARecord" */ -155, /* "safeContentsBag" */ -291, /* "sbgp-autonomousSysNum" */ -290, /* "sbgp-ipAddrBlock" */ -292, /* "sbgp-routerIdentifier" */ -159, /* "sdsiCertificate" */ -859, /* "searchGuide" */ -704, /* "secp112r1" */ -705, /* "secp112r2" */ -706, /* "secp128r1" */ -707, /* "secp128r2" */ -708, /* "secp160k1" */ -709, /* "secp160r1" */ -710, /* "secp160r2" */ -711, /* "secp192k1" */ -712, /* "secp224k1" */ -713, /* "secp224r1" */ -714, /* "secp256k1" */ -715, /* "secp384r1" */ -716, /* "secp521r1" */ -154, /* "secretBag" */ -474, /* "secretary" */ -717, /* "sect113r1" */ -718, /* "sect113r2" */ -719, /* "sect131r1" */ -720, /* "sect131r2" */ -721, /* "sect163k1" */ -722, /* "sect163r1" */ -723, /* "sect163r2" */ -724, /* "sect193r1" */ -725, /* "sect193r2" */ -726, /* "sect233k1" */ -727, /* "sect233r1" */ -728, /* "sect239k1" */ -729, /* "sect283k1" */ -730, /* "sect283r1" */ -731, /* "sect409k1" */ -732, /* "sect409r1" */ -733, /* "sect571k1" */ -734, /* "sect571r1" */ -386, /* "security" */ -878, /* "seeAlso" */ -394, /* "selected-attribute-types" */ -105, /* "serialNumber" */ -129, /* "serverAuth" */ -371, /* "serviceLocator" */ -625, /* "set-addPolicy" */ -515, /* "set-attr" */ -518, /* "set-brand" */ -638, /* "set-brand-AmericanExpress" */ -637, /* "set-brand-Diners" */ -636, /* "set-brand-IATA-ATA" */ -639, /* "set-brand-JCB" */ -641, /* "set-brand-MasterCard" */ -642, /* "set-brand-Novus" */ -640, /* "set-brand-Visa" */ -517, /* "set-certExt" */ -513, /* "set-ctype" */ -514, /* "set-msgExt" */ -516, /* "set-policy" */ -607, /* "set-policy-root" */ -624, /* "set-rootKeyThumb" */ -620, /* "setAttr-Cert" */ -631, /* "setAttr-GenCryptgrm" */ -623, /* "setAttr-IssCap" */ -628, /* "setAttr-IssCap-CVM" */ -630, /* "setAttr-IssCap-Sig" */ -629, /* "setAttr-IssCap-T2" */ -621, /* "setAttr-PGWYcap" */ -635, /* "setAttr-SecDevSig" */ -632, /* "setAttr-T2Enc" */ -633, /* "setAttr-T2cleartxt" */ -634, /* "setAttr-TokICCsig" */ -627, /* "setAttr-Token-B0Prime" */ -626, /* "setAttr-Token-EMV" */ -622, /* "setAttr-TokenType" */ -619, /* "setCext-IssuerCapabilities" */ -615, /* "setCext-PGWYcapabilities" */ -616, /* "setCext-TokenIdentifier" */ -618, /* "setCext-TokenType" */ -617, /* "setCext-Track2Data" */ -611, /* "setCext-cCertRequired" */ -609, /* "setCext-certType" */ -608, /* "setCext-hashedRoot" */ -610, /* "setCext-merchData" */ -613, /* "setCext-setExt" */ -614, /* "setCext-setQualf" */ -612, /* "setCext-tunneling" */ -540, /* "setct-AcqCardCodeMsg" */ -576, /* "setct-AcqCardCodeMsgTBE" */ -570, /* "setct-AuthReqTBE" */ -534, /* "setct-AuthReqTBS" */ -527, /* "setct-AuthResBaggage" */ -571, /* "setct-AuthResTBE" */ -572, /* "setct-AuthResTBEX" */ -535, /* "setct-AuthResTBS" */ -536, /* "setct-AuthResTBSX" */ -528, /* "setct-AuthRevReqBaggage" */ -577, /* "setct-AuthRevReqTBE" */ -541, /* "setct-AuthRevReqTBS" */ -529, /* "setct-AuthRevResBaggage" */ -542, /* "setct-AuthRevResData" */ -578, /* "setct-AuthRevResTBE" */ -579, /* "setct-AuthRevResTBEB" */ -543, /* "setct-AuthRevResTBS" */ -573, /* "setct-AuthTokenTBE" */ -537, /* "setct-AuthTokenTBS" */ -600, /* "setct-BCIDistributionTBS" */ -558, /* "setct-BatchAdminReqData" */ -592, /* "setct-BatchAdminReqTBE" */ -559, /* "setct-BatchAdminResData" */ -593, /* "setct-BatchAdminResTBE" */ -599, /* "setct-CRLNotificationResTBS" */ -598, /* "setct-CRLNotificationTBS" */ -580, /* "setct-CapReqTBE" */ -581, /* "setct-CapReqTBEX" */ -544, /* "setct-CapReqTBS" */ -545, /* "setct-CapReqTBSX" */ -546, /* "setct-CapResData" */ -582, /* "setct-CapResTBE" */ -583, /* "setct-CapRevReqTBE" */ -584, /* "setct-CapRevReqTBEX" */ -547, /* "setct-CapRevReqTBS" */ -548, /* "setct-CapRevReqTBSX" */ -549, /* "setct-CapRevResData" */ -585, /* "setct-CapRevResTBE" */ -538, /* "setct-CapTokenData" */ -530, /* "setct-CapTokenSeq" */ -574, /* "setct-CapTokenTBE" */ -575, /* "setct-CapTokenTBEX" */ -539, /* "setct-CapTokenTBS" */ -560, /* "setct-CardCInitResTBS" */ -566, /* "setct-CertInqReqTBS" */ -563, /* "setct-CertReqData" */ -595, /* "setct-CertReqTBE" */ -596, /* "setct-CertReqTBEX" */ -564, /* "setct-CertReqTBS" */ -565, /* "setct-CertResData" */ -597, /* "setct-CertResTBE" */ -586, /* "setct-CredReqTBE" */ -587, /* "setct-CredReqTBEX" */ -550, /* "setct-CredReqTBS" */ -551, /* "setct-CredReqTBSX" */ -552, /* "setct-CredResData" */ -588, /* "setct-CredResTBE" */ -589, /* "setct-CredRevReqTBE" */ -590, /* "setct-CredRevReqTBEX" */ -553, /* "setct-CredRevReqTBS" */ -554, /* "setct-CredRevReqTBSX" */ -555, /* "setct-CredRevResData" */ -591, /* "setct-CredRevResTBE" */ -567, /* "setct-ErrorTBS" */ -526, /* "setct-HODInput" */ -561, /* "setct-MeAqCInitResTBS" */ -522, /* "setct-OIData" */ -519, /* "setct-PANData" */ -521, /* "setct-PANOnly" */ -520, /* "setct-PANToken" */ -556, /* "setct-PCertReqData" */ -557, /* "setct-PCertResTBS" */ -523, /* "setct-PI" */ -532, /* "setct-PI-TBS" */ -524, /* "setct-PIData" */ -525, /* "setct-PIDataUnsigned" */ -568, /* "setct-PIDualSignedTBE" */ -569, /* "setct-PIUnsignedTBE" */ -531, /* "setct-PInitResData" */ -533, /* "setct-PResData" */ -594, /* "setct-RegFormReqTBE" */ -562, /* "setct-RegFormResTBS" */ -606, /* "setext-cv" */ -601, /* "setext-genCrypt" */ -602, /* "setext-miAuth" */ -604, /* "setext-pinAny" */ -603, /* "setext-pinSecure" */ -605, /* "setext-track2" */ -52, /* "signingTime" */ -454, /* "simpleSecurityObject" */ -496, /* "singleLevelQuality" */ -387, /* "snmpv2" */ -660, /* "street" */ -85, /* "subjectAltName" */ -769, /* "subjectDirectoryAttributes" */ -398, /* "subjectInfoAccess" */ -82, /* "subjectKeyIdentifier" */ -498, /* "subtreeMaximumQuality" */ -497, /* "subtreeMinimumQuality" */ -890, /* "supportedAlgorithms" */ -874, /* "supportedApplicationContext" */ -402, /* "targetInformation" */ -864, /* "telephoneNumber" */ -866, /* "teletexTerminalIdentifier" */ -865, /* "telexNumber" */ -459, /* "textEncodedORAddress" */ -293, /* "textNotice" */ -133, /* "timeStamping" */ -106, /* "title" */ -682, /* "tpBasis" */ -375, /* "trustRoot" */ -436, /* "ucl" */ -888, /* "uniqueMember" */ -55, /* "unstructuredAddress" */ -49, /* "unstructuredName" */ -880, /* "userCertificate" */ -465, /* "userClass" */ -879, /* "userPassword" */ -373, /* "valid" */ -678, /* "wap" */ -679, /* "wap-wsg" */ -735, /* "wap-wsg-idm-ecid-wtls1" */ -743, /* "wap-wsg-idm-ecid-wtls10" */ -744, /* "wap-wsg-idm-ecid-wtls11" */ -745, /* "wap-wsg-idm-ecid-wtls12" */ -736, /* "wap-wsg-idm-ecid-wtls3" */ -737, /* "wap-wsg-idm-ecid-wtls4" */ -738, /* "wap-wsg-idm-ecid-wtls5" */ -739, /* "wap-wsg-idm-ecid-wtls6" */ -740, /* "wap-wsg-idm-ecid-wtls7" */ -741, /* "wap-wsg-idm-ecid-wtls8" */ -742, /* "wap-wsg-idm-ecid-wtls9" */ -804, /* "whirlpool" */ -868, /* "x121Address" */ -503, /* "x500UniqueIdentifier" */ -158, /* "x509Certificate" */ -160, /* "x509Crl" */ -}; - -static const unsigned int ln_objs[NUM_LN]={ -363, /* "AD Time Stamping" */ -405, /* "ANSI X9.62" */ -368, /* "Acceptable OCSP Responses" */ -910, /* "Any Extended Key Usage" */ -664, /* "Any language" */ -177, /* "Authority Information Access" */ -365, /* "Basic OCSP Response" */ -285, /* "Biometric Info" */ -179, /* "CA Issuers" */ -785, /* "CA Repository" */ -954, /* "CT Certificate SCTs" */ -952, /* "CT Precertificate Poison" */ -951, /* "CT Precertificate SCTs" */ -953, /* "CT Precertificate Signer" */ -131, /* "Code Signing" */ -783, /* "Diffie-Hellman based MAC" */ -382, /* "Directory" */ -392, /* "Domain" */ -132, /* "E-mail Protection" */ -389, /* "Enterprises" */ -384, /* "Experimental" */ -372, /* "Extended OCSP Status" */ -172, /* "Extension Request" */ -813, /* "GOST 28147-89" */ -849, /* "GOST 28147-89 Cryptocom ParamSet" */ -815, /* "GOST 28147-89 MAC" */ -851, /* "GOST 34.10-2001 Cryptocom" */ -850, /* "GOST 34.10-94 Cryptocom" */ -811, /* "GOST R 34.10-2001" */ -817, /* "GOST R 34.10-2001 DH" */ -812, /* "GOST R 34.10-94" */ -818, /* "GOST R 34.10-94 DH" */ -809, /* "GOST R 34.11-94" */ -816, /* "GOST R 34.11-94 PRF" */ -807, /* "GOST R 34.11-94 with GOST R 34.10-2001" */ -853, /* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */ -808, /* "GOST R 34.11-94 with GOST R 34.10-94" */ -852, /* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */ -854, /* "GOST R 3410-2001 Parameter Set Cryptocom" */ -810, /* "HMAC GOST 34.11-94" */ -432, /* "Hold Instruction Call Issuer" */ -430, /* "Hold Instruction Code" */ -431, /* "Hold Instruction None" */ -433, /* "Hold Instruction Reject" */ -634, /* "ICC or token signature" */ -294, /* "IPSec End System" */ -295, /* "IPSec Tunnel" */ -296, /* "IPSec User" */ -182, /* "ISO Member Body" */ -183, /* "ISO US Member Body" */ -667, /* "Independent" */ -665, /* "Inherit all" */ -647, /* "International Organizations" */ -142, /* "Invalidity Date" */ -504, /* "MIME MHS" */ -388, /* "Mail" */ -383, /* "Management" */ -417, /* "Microsoft CSP Name" */ -135, /* "Microsoft Commercial Code Signing" */ -138, /* "Microsoft Encrypted File System" */ -171, /* "Microsoft Extension Request" */ -134, /* "Microsoft Individual Code Signing" */ -856, /* "Microsoft Local Key set" */ -137, /* "Microsoft Server Gated Crypto" */ -648, /* "Microsoft Smartcardlogin" */ -136, /* "Microsoft Trust List Signing" */ -649, /* "Microsoft Universal Principal Name" */ -393, /* "NULL" */ -404, /* "NULL" */ -72, /* "Netscape Base Url" */ -76, /* "Netscape CA Policy Url" */ -74, /* "Netscape CA Revocation Url" */ -71, /* "Netscape Cert Type" */ -58, /* "Netscape Certificate Extension" */ -79, /* "Netscape Certificate Sequence" */ -78, /* "Netscape Comment" */ -57, /* "Netscape Communications Corp." */ -59, /* "Netscape Data Type" */ -75, /* "Netscape Renewal Url" */ -73, /* "Netscape Revocation Url" */ -77, /* "Netscape SSL Server Name" */ -139, /* "Netscape Server Gated Crypto" */ -178, /* "OCSP" */ -370, /* "OCSP Archive Cutoff" */ -367, /* "OCSP CRL ID" */ -369, /* "OCSP No Check" */ -366, /* "OCSP Nonce" */ -371, /* "OCSP Service Locator" */ -180, /* "OCSP Signing" */ -161, /* "PBES2" */ -69, /* "PBKDF2" */ -162, /* "PBMAC1" */ -127, /* "PKIX" */ -858, /* "Permanent Identifier" */ -164, /* "Policy Qualifier CPS" */ -165, /* "Policy Qualifier User Notice" */ -385, /* "Private" */ -663, /* "Proxy Certificate Information" */ - 1, /* "RSA Data Security, Inc." */ - 2, /* "RSA Data Security, Inc. PKCS" */ -188, /* "S/MIME" */ -167, /* "S/MIME Capabilities" */ -387, /* "SNMPv2" */ -512, /* "Secure Electronic Transactions" */ -386, /* "Security" */ -394, /* "Selected Attribute Types" */ -143, /* "Strong Extranet ID" */ -398, /* "Subject Information Access" */ -130, /* "TLS Web Client Authentication" */ -129, /* "TLS Web Server Authentication" */ -133, /* "Time Stamping" */ -375, /* "Trust Root" */ -12, /* "X509" */ -402, /* "X509v3 AC Targeting" */ -746, /* "X509v3 Any Policy" */ -90, /* "X509v3 Authority Key Identifier" */ -87, /* "X509v3 Basic Constraints" */ -103, /* "X509v3 CRL Distribution Points" */ -88, /* "X509v3 CRL Number" */ -141, /* "X509v3 CRL Reason Code" */ -771, /* "X509v3 Certificate Issuer" */ -89, /* "X509v3 Certificate Policies" */ -140, /* "X509v3 Delta CRL Indicator" */ -126, /* "X509v3 Extended Key Usage" */ -857, /* "X509v3 Freshest CRL" */ -748, /* "X509v3 Inhibit Any Policy" */ -86, /* "X509v3 Issuer Alternative Name" */ -770, /* "X509v3 Issuing Distrubution Point" */ -83, /* "X509v3 Key Usage" */ -666, /* "X509v3 Name Constraints" */ -403, /* "X509v3 No Revocation Available" */ -401, /* "X509v3 Policy Constraints" */ -747, /* "X509v3 Policy Mappings" */ -84, /* "X509v3 Private Key Usage Period" */ -85, /* "X509v3 Subject Alternative Name" */ -769, /* "X509v3 Subject Directory Attributes" */ -82, /* "X509v3 Subject Key Identifier" */ -920, /* "X9.42 DH" */ -184, /* "X9.57" */ -185, /* "X9.57 CM ?" */ -478, /* "aRecord" */ -289, /* "aaControls" */ -287, /* "ac-auditEntity" */ -397, /* "ac-proxying" */ -288, /* "ac-targeting" */ -446, /* "account" */ -364, /* "ad dvcs" */ -606, /* "additional verification" */ -419, /* "aes-128-cbc" */ -916, /* "aes-128-cbc-hmac-sha1" */ -948, /* "aes-128-cbc-hmac-sha256" */ -896, /* "aes-128-ccm" */ -421, /* "aes-128-cfb" */ -650, /* "aes-128-cfb1" */ -653, /* "aes-128-cfb8" */ -904, /* "aes-128-ctr" */ -418, /* "aes-128-ecb" */ -895, /* "aes-128-gcm" */ -420, /* "aes-128-ofb" */ -913, /* "aes-128-xts" */ -423, /* "aes-192-cbc" */ -917, /* "aes-192-cbc-hmac-sha1" */ -949, /* "aes-192-cbc-hmac-sha256" */ -899, /* "aes-192-ccm" */ -425, /* "aes-192-cfb" */ -651, /* "aes-192-cfb1" */ -654, /* "aes-192-cfb8" */ -905, /* "aes-192-ctr" */ -422, /* "aes-192-ecb" */ -898, /* "aes-192-gcm" */ -424, /* "aes-192-ofb" */ -427, /* "aes-256-cbc" */ -918, /* "aes-256-cbc-hmac-sha1" */ -950, /* "aes-256-cbc-hmac-sha256" */ -902, /* "aes-256-ccm" */ -429, /* "aes-256-cfb" */ -652, /* "aes-256-cfb1" */ -655, /* "aes-256-cfb8" */ -906, /* "aes-256-ctr" */ -426, /* "aes-256-ecb" */ -901, /* "aes-256-gcm" */ -428, /* "aes-256-ofb" */ -914, /* "aes-256-xts" */ -376, /* "algorithm" */ -484, /* "associatedDomain" */ -485, /* "associatedName" */ -501, /* "audio" */ -882, /* "authorityRevocationList" */ -91, /* "bf-cbc" */ -93, /* "bf-cfb" */ -92, /* "bf-ecb" */ -94, /* "bf-ofb" */ -921, /* "brainpoolP160r1" */ -922, /* "brainpoolP160t1" */ -923, /* "brainpoolP192r1" */ -924, /* "brainpoolP192t1" */ -925, /* "brainpoolP224r1" */ -926, /* "brainpoolP224t1" */ -927, /* "brainpoolP256r1" */ -928, /* "brainpoolP256t1" */ -929, /* "brainpoolP320r1" */ -930, /* "brainpoolP320t1" */ -931, /* "brainpoolP384r1" */ -932, /* "brainpoolP384t1" */ -933, /* "brainpoolP512r1" */ -934, /* "brainpoolP512t1" */ -494, /* "buildingName" */ -860, /* "businessCategory" */ -691, /* "c2onb191v4" */ -692, /* "c2onb191v5" */ -697, /* "c2onb239v4" */ -698, /* "c2onb239v5" */ -684, /* "c2pnb163v1" */ -685, /* "c2pnb163v2" */ -686, /* "c2pnb163v3" */ -687, /* "c2pnb176v1" */ -693, /* "c2pnb208w1" */ -699, /* "c2pnb272w1" */ -700, /* "c2pnb304w1" */ -702, /* "c2pnb368w1" */ -688, /* "c2tnb191v1" */ -689, /* "c2tnb191v2" */ -690, /* "c2tnb191v3" */ -694, /* "c2tnb239v1" */ -695, /* "c2tnb239v2" */ -696, /* "c2tnb239v3" */ -701, /* "c2tnb359v1" */ -703, /* "c2tnb431r1" */ -881, /* "cACertificate" */ -483, /* "cNAMERecord" */ -751, /* "camellia-128-cbc" */ -757, /* "camellia-128-cfb" */ -760, /* "camellia-128-cfb1" */ -763, /* "camellia-128-cfb8" */ -754, /* "camellia-128-ecb" */ -766, /* "camellia-128-ofb" */ -752, /* "camellia-192-cbc" */ -758, /* "camellia-192-cfb" */ -761, /* "camellia-192-cfb1" */ -764, /* "camellia-192-cfb8" */ -755, /* "camellia-192-ecb" */ -767, /* "camellia-192-ofb" */ -753, /* "camellia-256-cbc" */ -759, /* "camellia-256-cfb" */ -762, /* "camellia-256-cfb1" */ -765, /* "camellia-256-cfb8" */ -756, /* "camellia-256-ecb" */ -768, /* "camellia-256-ofb" */ -443, /* "caseIgnoreIA5StringSyntax" */ -108, /* "cast5-cbc" */ -110, /* "cast5-cfb" */ -109, /* "cast5-ecb" */ -111, /* "cast5-ofb" */ -152, /* "certBag" */ -677, /* "certicom-arc" */ -517, /* "certificate extensions" */ -883, /* "certificateRevocationList" */ -54, /* "challengePassword" */ -407, /* "characteristic-two-field" */ -395, /* "clearance" */ -633, /* "cleartext track 2" */ -894, /* "cmac" */ -13, /* "commonName" */ -513, /* "content types" */ -50, /* "contentType" */ -53, /* "countersignature" */ -14, /* "countryName" */ -153, /* "crlBag" */ -884, /* "crossCertificatePair" */ -806, /* "cryptocom" */ -805, /* "cryptopro" */ -500, /* "dITRedirect" */ -451, /* "dNSDomain" */ -495, /* "dSAQuality" */ -434, /* "data" */ -390, /* "dcObject" */ -891, /* "deltaRevocationList" */ -31, /* "des-cbc" */ -643, /* "des-cdmf" */ -30, /* "des-cfb" */ -656, /* "des-cfb1" */ -657, /* "des-cfb8" */ -29, /* "des-ecb" */ -32, /* "des-ede" */ -43, /* "des-ede-cbc" */ -60, /* "des-ede-cfb" */ -62, /* "des-ede-ofb" */ -33, /* "des-ede3" */ -44, /* "des-ede3-cbc" */ -61, /* "des-ede3-cfb" */ -658, /* "des-ede3-cfb1" */ -659, /* "des-ede3-cfb8" */ -63, /* "des-ede3-ofb" */ -45, /* "des-ofb" */ -107, /* "description" */ -871, /* "destinationIndicator" */ -80, /* "desx-cbc" */ -947, /* "dh-cofactor-kdf" */ -946, /* "dh-std-kdf" */ -28, /* "dhKeyAgreement" */ -941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */ -942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */ -943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */ -944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */ -945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */ -936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */ -937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */ -938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */ -939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */ -940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */ -11, /* "directory services (X.500)" */ -378, /* "directory services - algorithms" */ -887, /* "distinguishedName" */ -892, /* "dmdName" */ -174, /* "dnQualifier" */ -447, /* "document" */ -471, /* "documentAuthor" */ -468, /* "documentIdentifier" */ -472, /* "documentLocation" */ -502, /* "documentPublisher" */ -449, /* "documentSeries" */ -469, /* "documentTitle" */ -470, /* "documentVersion" */ -380, /* "dod" */ -391, /* "domainComponent" */ -452, /* "domainRelatedObject" */ -116, /* "dsaEncryption" */ -67, /* "dsaEncryption-old" */ -66, /* "dsaWithSHA" */ -113, /* "dsaWithSHA1" */ -70, /* "dsaWithSHA1-old" */ -802, /* "dsa_with_SHA224" */ -803, /* "dsa_with_SHA256" */ -297, /* "dvcs" */ -791, /* "ecdsa-with-Recommended" */ -416, /* "ecdsa-with-SHA1" */ -793, /* "ecdsa-with-SHA224" */ -794, /* "ecdsa-with-SHA256" */ -795, /* "ecdsa-with-SHA384" */ -796, /* "ecdsa-with-SHA512" */ -792, /* "ecdsa-with-Specified" */ -48, /* "emailAddress" */ -632, /* "encrypted track 2" */ -885, /* "enhancedSearchGuide" */ -56, /* "extendedCertificateAttributes" */ -867, /* "facsimileTelephoneNumber" */ -462, /* "favouriteDrink" */ -453, /* "friendlyCountry" */ -490, /* "friendlyCountryName" */ -156, /* "friendlyName" */ -631, /* "generate cryptogram" */ -509, /* "generationQualifier" */ -601, /* "generic cryptogram" */ -99, /* "givenName" */ -814, /* "gost89-cnt" */ -855, /* "hmac" */ -780, /* "hmac-md5" */ -781, /* "hmac-sha1" */ -797, /* "hmacWithMD5" */ -163, /* "hmacWithSHA1" */ -798, /* "hmacWithSHA224" */ -799, /* "hmacWithSHA256" */ -800, /* "hmacWithSHA384" */ -801, /* "hmacWithSHA512" */ -486, /* "homePostalAddress" */ -473, /* "homeTelephoneNumber" */ -466, /* "host" */ -889, /* "houseIdentifier" */ -442, /* "iA5StringSyntax" */ -381, /* "iana" */ -824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ -825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ -826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ -827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ -819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ -829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ -828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ -830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ -820, /* "id-Gost28147-89-None-KeyMeshing" */ -823, /* "id-Gost28147-89-TestParamSet" */ -840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ -841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ -842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ -843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ -844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ -839, /* "id-GostR3410-2001-TestParamSet" */ -832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ -833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ -834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ -835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ -836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ -837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ -838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ -831, /* "id-GostR3410-94-TestParamSet" */ -845, /* "id-GostR3410-94-a" */ -846, /* "id-GostR3410-94-aBis" */ -847, /* "id-GostR3410-94-b" */ -848, /* "id-GostR3410-94-bBis" */ -822, /* "id-GostR3411-94-CryptoProParamSet" */ -821, /* "id-GostR3411-94-TestParamSet" */ -266, /* "id-aca" */ -355, /* "id-aca-accessIdentity" */ -354, /* "id-aca-authenticationInfo" */ -356, /* "id-aca-chargingIdentity" */ -399, /* "id-aca-encAttrs" */ -357, /* "id-aca-group" */ -358, /* "id-aca-role" */ -176, /* "id-ad" */ -788, /* "id-aes128-wrap" */ -897, /* "id-aes128-wrap-pad" */ -789, /* "id-aes192-wrap" */ -900, /* "id-aes192-wrap-pad" */ -790, /* "id-aes256-wrap" */ -903, /* "id-aes256-wrap-pad" */ -262, /* "id-alg" */ -893, /* "id-alg-PWRI-KEK" */ -323, /* "id-alg-des40" */ -326, /* "id-alg-dh-pop" */ -325, /* "id-alg-dh-sig-hmac-sha1" */ -324, /* "id-alg-noSignature" */ -907, /* "id-camellia128-wrap" */ -908, /* "id-camellia192-wrap" */ -909, /* "id-camellia256-wrap" */ -268, /* "id-cct" */ -361, /* "id-cct-PKIData" */ -362, /* "id-cct-PKIResponse" */ -360, /* "id-cct-crs" */ -81, /* "id-ce" */ -680, /* "id-characteristic-two-basis" */ -263, /* "id-cmc" */ -334, /* "id-cmc-addExtensions" */ -346, /* "id-cmc-confirmCertAcceptance" */ -330, /* "id-cmc-dataReturn" */ -336, /* "id-cmc-decryptedPOP" */ -335, /* "id-cmc-encryptedPOP" */ -339, /* "id-cmc-getCRL" */ -338, /* "id-cmc-getCert" */ -328, /* "id-cmc-identification" */ -329, /* "id-cmc-identityProof" */ -337, /* "id-cmc-lraPOPWitness" */ -344, /* "id-cmc-popLinkRandom" */ -345, /* "id-cmc-popLinkWitness" */ -343, /* "id-cmc-queryPending" */ -333, /* "id-cmc-recipientNonce" */ -341, /* "id-cmc-regInfo" */ -342, /* "id-cmc-responseInfo" */ -340, /* "id-cmc-revokeRequest" */ -332, /* "id-cmc-senderNonce" */ -327, /* "id-cmc-statusInfo" */ -331, /* "id-cmc-transactionId" */ -787, /* "id-ct-asciiTextWithCRLF" */ -408, /* "id-ecPublicKey" */ -508, /* "id-hex-multipart-message" */ -507, /* "id-hex-partial-message" */ -260, /* "id-it" */ -302, /* "id-it-caKeyUpdateInfo" */ -298, /* "id-it-caProtEncCert" */ -311, /* "id-it-confirmWaitTime" */ -303, /* "id-it-currentCRL" */ -300, /* "id-it-encKeyPairTypes" */ -310, /* "id-it-implicitConfirm" */ -308, /* "id-it-keyPairParamRep" */ -307, /* "id-it-keyPairParamReq" */ -312, /* "id-it-origPKIMessage" */ -301, /* "id-it-preferredSymmAlg" */ -309, /* "id-it-revPassphrase" */ -299, /* "id-it-signKeyPairTypes" */ -305, /* "id-it-subscriptionRequest" */ -306, /* "id-it-subscriptionResponse" */ -784, /* "id-it-suppLangTags" */ -304, /* "id-it-unsupportedOIDs" */ -128, /* "id-kp" */ -280, /* "id-mod-attribute-cert" */ -274, /* "id-mod-cmc" */ -277, /* "id-mod-cmp" */ -284, /* "id-mod-cmp2000" */ -273, /* "id-mod-crmf" */ -283, /* "id-mod-dvcs" */ -275, /* "id-mod-kea-profile-88" */ -276, /* "id-mod-kea-profile-93" */ -282, /* "id-mod-ocsp" */ -278, /* "id-mod-qualified-cert-88" */ -279, /* "id-mod-qualified-cert-93" */ -281, /* "id-mod-timestamp-protocol" */ -264, /* "id-on" */ -347, /* "id-on-personalData" */ -265, /* "id-pda" */ -352, /* "id-pda-countryOfCitizenship" */ -353, /* "id-pda-countryOfResidence" */ -348, /* "id-pda-dateOfBirth" */ -351, /* "id-pda-gender" */ -349, /* "id-pda-placeOfBirth" */ -175, /* "id-pe" */ -261, /* "id-pkip" */ -258, /* "id-pkix-mod" */ -269, /* "id-pkix1-explicit-88" */ -271, /* "id-pkix1-explicit-93" */ -270, /* "id-pkix1-implicit-88" */ -272, /* "id-pkix1-implicit-93" */ -662, /* "id-ppl" */ -267, /* "id-qcs" */ -359, /* "id-qcs-pkixQCSyntax-v1" */ -259, /* "id-qt" */ -313, /* "id-regCtrl" */ -316, /* "id-regCtrl-authenticator" */ -319, /* "id-regCtrl-oldCertID" */ -318, /* "id-regCtrl-pkiArchiveOptions" */ -317, /* "id-regCtrl-pkiPublicationInfo" */ -320, /* "id-regCtrl-protocolEncrKey" */ -315, /* "id-regCtrl-regToken" */ -314, /* "id-regInfo" */ -322, /* "id-regInfo-certReq" */ -321, /* "id-regInfo-utf8Pairs" */ -191, /* "id-smime-aa" */ -215, /* "id-smime-aa-contentHint" */ -218, /* "id-smime-aa-contentIdentifier" */ -221, /* "id-smime-aa-contentReference" */ -240, /* "id-smime-aa-dvcs-dvc" */ -217, /* "id-smime-aa-encapContentType" */ -222, /* "id-smime-aa-encrypKeyPref" */ -220, /* "id-smime-aa-equivalentLabels" */ -232, /* "id-smime-aa-ets-CertificateRefs" */ -233, /* "id-smime-aa-ets-RevocationRefs" */ -238, /* "id-smime-aa-ets-archiveTimeStamp" */ -237, /* "id-smime-aa-ets-certCRLTimestamp" */ -234, /* "id-smime-aa-ets-certValues" */ -227, /* "id-smime-aa-ets-commitmentType" */ -231, /* "id-smime-aa-ets-contentTimestamp" */ -236, /* "id-smime-aa-ets-escTimeStamp" */ -230, /* "id-smime-aa-ets-otherSigCert" */ -235, /* "id-smime-aa-ets-revocationValues" */ -226, /* "id-smime-aa-ets-sigPolicyId" */ -229, /* "id-smime-aa-ets-signerAttr" */ -228, /* "id-smime-aa-ets-signerLocation" */ -219, /* "id-smime-aa-macValue" */ -214, /* "id-smime-aa-mlExpandHistory" */ -216, /* "id-smime-aa-msgSigDigest" */ -212, /* "id-smime-aa-receiptRequest" */ -213, /* "id-smime-aa-securityLabel" */ -239, /* "id-smime-aa-signatureType" */ -223, /* "id-smime-aa-signingCertificate" */ -224, /* "id-smime-aa-smimeEncryptCerts" */ -225, /* "id-smime-aa-timeStampToken" */ -192, /* "id-smime-alg" */ -243, /* "id-smime-alg-3DESwrap" */ -246, /* "id-smime-alg-CMS3DESwrap" */ -247, /* "id-smime-alg-CMSRC2wrap" */ -245, /* "id-smime-alg-ESDH" */ -241, /* "id-smime-alg-ESDHwith3DES" */ -242, /* "id-smime-alg-ESDHwithRC2" */ -244, /* "id-smime-alg-RC2wrap" */ -193, /* "id-smime-cd" */ -248, /* "id-smime-cd-ldap" */ -190, /* "id-smime-ct" */ -210, /* "id-smime-ct-DVCSRequestData" */ -211, /* "id-smime-ct-DVCSResponseData" */ -208, /* "id-smime-ct-TDTInfo" */ -207, /* "id-smime-ct-TSTInfo" */ -205, /* "id-smime-ct-authData" */ -786, /* "id-smime-ct-compressedData" */ -209, /* "id-smime-ct-contentInfo" */ -206, /* "id-smime-ct-publishCert" */ -204, /* "id-smime-ct-receipt" */ -195, /* "id-smime-cti" */ -255, /* "id-smime-cti-ets-proofOfApproval" */ -256, /* "id-smime-cti-ets-proofOfCreation" */ -253, /* "id-smime-cti-ets-proofOfDelivery" */ -251, /* "id-smime-cti-ets-proofOfOrigin" */ -252, /* "id-smime-cti-ets-proofOfReceipt" */ -254, /* "id-smime-cti-ets-proofOfSender" */ -189, /* "id-smime-mod" */ -196, /* "id-smime-mod-cms" */ -197, /* "id-smime-mod-ess" */ -202, /* "id-smime-mod-ets-eSigPolicy-88" */ -203, /* "id-smime-mod-ets-eSigPolicy-97" */ -200, /* "id-smime-mod-ets-eSignature-88" */ -201, /* "id-smime-mod-ets-eSignature-97" */ -199, /* "id-smime-mod-msg-v3" */ -198, /* "id-smime-mod-oid" */ -194, /* "id-smime-spq" */ -250, /* "id-smime-spq-ets-sqt-unotice" */ -249, /* "id-smime-spq-ets-sqt-uri" */ -34, /* "idea-cbc" */ -35, /* "idea-cfb" */ -36, /* "idea-ecb" */ -46, /* "idea-ofb" */ -676, /* "identified-organization" */ -461, /* "info" */ -101, /* "initials" */ -869, /* "internationaliSDNNumber" */ -749, /* "ipsec3" */ -750, /* "ipsec4" */ -181, /* "iso" */ -623, /* "issuer capabilities" */ -645, /* "itu-t" */ -492, /* "janetMailbox" */ -646, /* "joint-iso-itu-t" */ -957, /* "jurisdictionCountryName" */ -955, /* "jurisdictionLocalityName" */ -956, /* "jurisdictionStateOrProvinceName" */ -150, /* "keyBag" */ -773, /* "kisa" */ -477, /* "lastModifiedBy" */ -476, /* "lastModifiedTime" */ -157, /* "localKeyID" */ -15, /* "localityName" */ -480, /* "mXRecord" */ -493, /* "mailPreferenceOption" */ -467, /* "manager" */ - 3, /* "md2" */ - 7, /* "md2WithRSAEncryption" */ -257, /* "md4" */ -396, /* "md4WithRSAEncryption" */ - 4, /* "md5" */ -114, /* "md5-sha1" */ -104, /* "md5WithRSA" */ - 8, /* "md5WithRSAEncryption" */ -95, /* "mdc2" */ -96, /* "mdc2WithRSA" */ -875, /* "member" */ -602, /* "merchant initiated auth" */ -514, /* "message extensions" */ -51, /* "messageDigest" */ -911, /* "mgf1" */ -506, /* "mime-mhs-bodies" */ -505, /* "mime-mhs-headings" */ -488, /* "mobileTelephoneNumber" */ -481, /* "nSRecord" */ -173, /* "name" */ -681, /* "onBasis" */ -379, /* "org" */ -17, /* "organizationName" */ -491, /* "organizationalStatus" */ -18, /* "organizationalUnitName" */ -475, /* "otherMailbox" */ -876, /* "owner" */ -935, /* "pSpecified" */ -489, /* "pagerTelephoneNumber" */ -782, /* "password based MAC" */ -374, /* "path" */ -621, /* "payment gateway capabilities" */ - 9, /* "pbeWithMD2AndDES-CBC" */ -168, /* "pbeWithMD2AndRC2-CBC" */ -112, /* "pbeWithMD5AndCast5CBC" */ -10, /* "pbeWithMD5AndDES-CBC" */ -169, /* "pbeWithMD5AndRC2-CBC" */ -148, /* "pbeWithSHA1And128BitRC2-CBC" */ -144, /* "pbeWithSHA1And128BitRC4" */ -147, /* "pbeWithSHA1And2-KeyTripleDES-CBC" */ -146, /* "pbeWithSHA1And3-KeyTripleDES-CBC" */ -149, /* "pbeWithSHA1And40BitRC2-CBC" */ -145, /* "pbeWithSHA1And40BitRC4" */ -170, /* "pbeWithSHA1AndDES-CBC" */ -68, /* "pbeWithSHA1AndRC2-CBC" */ -499, /* "personalSignature" */ -487, /* "personalTitle" */ -464, /* "photo" */ -863, /* "physicalDeliveryOfficeName" */ -437, /* "pilot" */ -439, /* "pilotAttributeSyntax" */ -438, /* "pilotAttributeType" */ -479, /* "pilotAttributeType27" */ -456, /* "pilotDSA" */ -441, /* "pilotGroups" */ -444, /* "pilotObject" */ -440, /* "pilotObjectClass" */ -455, /* "pilotOrganization" */ -445, /* "pilotPerson" */ -186, /* "pkcs1" */ -27, /* "pkcs3" */ -187, /* "pkcs5" */ -20, /* "pkcs7" */ -21, /* "pkcs7-data" */ -25, /* "pkcs7-digestData" */ -26, /* "pkcs7-encryptedData" */ -23, /* "pkcs7-envelopedData" */ -24, /* "pkcs7-signedAndEnvelopedData" */ -22, /* "pkcs7-signedData" */ -151, /* "pkcs8ShroudedKeyBag" */ -47, /* "pkcs9" */ -862, /* "postOfficeBox" */ -861, /* "postalAddress" */ -661, /* "postalCode" */ -683, /* "ppBasis" */ -872, /* "preferredDeliveryMethod" */ -873, /* "presentationAddress" */ -406, /* "prime-field" */ -409, /* "prime192v1" */ -410, /* "prime192v2" */ -411, /* "prime192v3" */ -412, /* "prime239v1" */ -413, /* "prime239v2" */ -414, /* "prime239v3" */ -415, /* "prime256v1" */ -886, /* "protocolInformation" */ -510, /* "pseudonym" */ -435, /* "pss" */ -286, /* "qcStatements" */ -457, /* "qualityLabelledData" */ -450, /* "rFC822localPart" */ -98, /* "rc2-40-cbc" */ -166, /* "rc2-64-cbc" */ -37, /* "rc2-cbc" */ -39, /* "rc2-cfb" */ -38, /* "rc2-ecb" */ -40, /* "rc2-ofb" */ - 5, /* "rc4" */ -97, /* "rc4-40" */ -915, /* "rc4-hmac-md5" */ -120, /* "rc5-cbc" */ -122, /* "rc5-cfb" */ -121, /* "rc5-ecb" */ -123, /* "rc5-ofb" */ -870, /* "registeredAddress" */ -460, /* "rfc822Mailbox" */ -117, /* "ripemd160" */ -119, /* "ripemd160WithRSA" */ -400, /* "role" */ -877, /* "roleOccupant" */ -448, /* "room" */ -463, /* "roomNumber" */ -19, /* "rsa" */ - 6, /* "rsaEncryption" */ -644, /* "rsaOAEPEncryptionSET" */ -377, /* "rsaSignature" */ -919, /* "rsaesOaep" */ -912, /* "rsassaPss" */ -124, /* "run length compression" */ -482, /* "sOARecord" */ -155, /* "safeContentsBag" */ -291, /* "sbgp-autonomousSysNum" */ -290, /* "sbgp-ipAddrBlock" */ -292, /* "sbgp-routerIdentifier" */ -159, /* "sdsiCertificate" */ -859, /* "searchGuide" */ -704, /* "secp112r1" */ -705, /* "secp112r2" */ -706, /* "secp128r1" */ -707, /* "secp128r2" */ -708, /* "secp160k1" */ -709, /* "secp160r1" */ -710, /* "secp160r2" */ -711, /* "secp192k1" */ -712, /* "secp224k1" */ -713, /* "secp224r1" */ -714, /* "secp256k1" */ -715, /* "secp384r1" */ -716, /* "secp521r1" */ -154, /* "secretBag" */ -474, /* "secretary" */ -717, /* "sect113r1" */ -718, /* "sect113r2" */ -719, /* "sect131r1" */ -720, /* "sect131r2" */ -721, /* "sect163k1" */ -722, /* "sect163r1" */ -723, /* "sect163r2" */ -724, /* "sect193r1" */ -725, /* "sect193r2" */ -726, /* "sect233k1" */ -727, /* "sect233r1" */ -728, /* "sect239k1" */ -729, /* "sect283k1" */ -730, /* "sect283r1" */ -731, /* "sect409k1" */ -732, /* "sect409r1" */ -733, /* "sect571k1" */ -734, /* "sect571r1" */ -635, /* "secure device signature" */ -878, /* "seeAlso" */ -777, /* "seed-cbc" */ -779, /* "seed-cfb" */ -776, /* "seed-ecb" */ -778, /* "seed-ofb" */ -105, /* "serialNumber" */ -625, /* "set-addPolicy" */ -515, /* "set-attr" */ -518, /* "set-brand" */ -638, /* "set-brand-AmericanExpress" */ -637, /* "set-brand-Diners" */ -636, /* "set-brand-IATA-ATA" */ -639, /* "set-brand-JCB" */ -641, /* "set-brand-MasterCard" */ -642, /* "set-brand-Novus" */ -640, /* "set-brand-Visa" */ -516, /* "set-policy" */ -607, /* "set-policy-root" */ -624, /* "set-rootKeyThumb" */ -620, /* "setAttr-Cert" */ -628, /* "setAttr-IssCap-CVM" */ -630, /* "setAttr-IssCap-Sig" */ -629, /* "setAttr-IssCap-T2" */ -627, /* "setAttr-Token-B0Prime" */ -626, /* "setAttr-Token-EMV" */ -622, /* "setAttr-TokenType" */ -619, /* "setCext-IssuerCapabilities" */ -615, /* "setCext-PGWYcapabilities" */ -616, /* "setCext-TokenIdentifier" */ -618, /* "setCext-TokenType" */ -617, /* "setCext-Track2Data" */ -611, /* "setCext-cCertRequired" */ -609, /* "setCext-certType" */ -608, /* "setCext-hashedRoot" */ -610, /* "setCext-merchData" */ -613, /* "setCext-setExt" */ -614, /* "setCext-setQualf" */ -612, /* "setCext-tunneling" */ -540, /* "setct-AcqCardCodeMsg" */ -576, /* "setct-AcqCardCodeMsgTBE" */ -570, /* "setct-AuthReqTBE" */ -534, /* "setct-AuthReqTBS" */ -527, /* "setct-AuthResBaggage" */ -571, /* "setct-AuthResTBE" */ -572, /* "setct-AuthResTBEX" */ -535, /* "setct-AuthResTBS" */ -536, /* "setct-AuthResTBSX" */ -528, /* "setct-AuthRevReqBaggage" */ -577, /* "setct-AuthRevReqTBE" */ -541, /* "setct-AuthRevReqTBS" */ -529, /* "setct-AuthRevResBaggage" */ -542, /* "setct-AuthRevResData" */ -578, /* "setct-AuthRevResTBE" */ -579, /* "setct-AuthRevResTBEB" */ -543, /* "setct-AuthRevResTBS" */ -573, /* "setct-AuthTokenTBE" */ -537, /* "setct-AuthTokenTBS" */ -600, /* "setct-BCIDistributionTBS" */ -558, /* "setct-BatchAdminReqData" */ -592, /* "setct-BatchAdminReqTBE" */ -559, /* "setct-BatchAdminResData" */ -593, /* "setct-BatchAdminResTBE" */ -599, /* "setct-CRLNotificationResTBS" */ -598, /* "setct-CRLNotificationTBS" */ -580, /* "setct-CapReqTBE" */ -581, /* "setct-CapReqTBEX" */ -544, /* "setct-CapReqTBS" */ -545, /* "setct-CapReqTBSX" */ -546, /* "setct-CapResData" */ -582, /* "setct-CapResTBE" */ -583, /* "setct-CapRevReqTBE" */ -584, /* "setct-CapRevReqTBEX" */ -547, /* "setct-CapRevReqTBS" */ -548, /* "setct-CapRevReqTBSX" */ -549, /* "setct-CapRevResData" */ -585, /* "setct-CapRevResTBE" */ -538, /* "setct-CapTokenData" */ -530, /* "setct-CapTokenSeq" */ -574, /* "setct-CapTokenTBE" */ -575, /* "setct-CapTokenTBEX" */ -539, /* "setct-CapTokenTBS" */ -560, /* "setct-CardCInitResTBS" */ -566, /* "setct-CertInqReqTBS" */ -563, /* "setct-CertReqData" */ -595, /* "setct-CertReqTBE" */ -596, /* "setct-CertReqTBEX" */ -564, /* "setct-CertReqTBS" */ -565, /* "setct-CertResData" */ -597, /* "setct-CertResTBE" */ -586, /* "setct-CredReqTBE" */ -587, /* "setct-CredReqTBEX" */ -550, /* "setct-CredReqTBS" */ -551, /* "setct-CredReqTBSX" */ -552, /* "setct-CredResData" */ -588, /* "setct-CredResTBE" */ -589, /* "setct-CredRevReqTBE" */ -590, /* "setct-CredRevReqTBEX" */ -553, /* "setct-CredRevReqTBS" */ -554, /* "setct-CredRevReqTBSX" */ -555, /* "setct-CredRevResData" */ -591, /* "setct-CredRevResTBE" */ -567, /* "setct-ErrorTBS" */ -526, /* "setct-HODInput" */ -561, /* "setct-MeAqCInitResTBS" */ -522, /* "setct-OIData" */ -519, /* "setct-PANData" */ -521, /* "setct-PANOnly" */ -520, /* "setct-PANToken" */ -556, /* "setct-PCertReqData" */ -557, /* "setct-PCertResTBS" */ -523, /* "setct-PI" */ -532, /* "setct-PI-TBS" */ -524, /* "setct-PIData" */ -525, /* "setct-PIDataUnsigned" */ -568, /* "setct-PIDualSignedTBE" */ -569, /* "setct-PIUnsignedTBE" */ -531, /* "setct-PInitResData" */ -533, /* "setct-PResData" */ -594, /* "setct-RegFormReqTBE" */ -562, /* "setct-RegFormResTBS" */ -604, /* "setext-pinAny" */ -603, /* "setext-pinSecure" */ -605, /* "setext-track2" */ -41, /* "sha" */ -64, /* "sha1" */ -115, /* "sha1WithRSA" */ -65, /* "sha1WithRSAEncryption" */ -675, /* "sha224" */ -671, /* "sha224WithRSAEncryption" */ -672, /* "sha256" */ -668, /* "sha256WithRSAEncryption" */ -673, /* "sha384" */ -669, /* "sha384WithRSAEncryption" */ -674, /* "sha512" */ -670, /* "sha512WithRSAEncryption" */ -42, /* "shaWithRSAEncryption" */ -52, /* "signingTime" */ -454, /* "simpleSecurityObject" */ -496, /* "singleLevelQuality" */ -16, /* "stateOrProvinceName" */ -660, /* "streetAddress" */ -498, /* "subtreeMaximumQuality" */ -497, /* "subtreeMinimumQuality" */ -890, /* "supportedAlgorithms" */ -874, /* "supportedApplicationContext" */ -100, /* "surname" */ -864, /* "telephoneNumber" */ -866, /* "teletexTerminalIdentifier" */ -865, /* "telexNumber" */ -459, /* "textEncodedORAddress" */ -293, /* "textNotice" */ -106, /* "title" */ -682, /* "tpBasis" */ -436, /* "ucl" */ - 0, /* "undefined" */ -888, /* "uniqueMember" */ -55, /* "unstructuredAddress" */ -49, /* "unstructuredName" */ -880, /* "userCertificate" */ -465, /* "userClass" */ -458, /* "userId" */ -879, /* "userPassword" */ -373, /* "valid" */ -678, /* "wap" */ -679, /* "wap-wsg" */ -735, /* "wap-wsg-idm-ecid-wtls1" */ -743, /* "wap-wsg-idm-ecid-wtls10" */ -744, /* "wap-wsg-idm-ecid-wtls11" */ -745, /* "wap-wsg-idm-ecid-wtls12" */ -736, /* "wap-wsg-idm-ecid-wtls3" */ -737, /* "wap-wsg-idm-ecid-wtls4" */ -738, /* "wap-wsg-idm-ecid-wtls5" */ -739, /* "wap-wsg-idm-ecid-wtls6" */ -740, /* "wap-wsg-idm-ecid-wtls7" */ -741, /* "wap-wsg-idm-ecid-wtls8" */ -742, /* "wap-wsg-idm-ecid-wtls9" */ -804, /* "whirlpool" */ -868, /* "x121Address" */ -503, /* "x500UniqueIdentifier" */ -158, /* "x509Certificate" */ -160, /* "x509Crl" */ -125, /* "zlib compression" */ -}; - -static const unsigned int obj_objs[NUM_OBJ]={ - 0, /* OBJ_undef 0 */ -181, /* OBJ_iso 1 */ -393, /* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */ -404, /* OBJ_ccitt OBJ_itu_t */ -645, /* OBJ_itu_t 0 */ -646, /* OBJ_joint_iso_itu_t 2 */ -434, /* OBJ_data 0 9 */ -182, /* OBJ_member_body 1 2 */ -379, /* OBJ_org 1 3 */ -676, /* OBJ_identified_organization 1 3 */ -11, /* OBJ_X500 2 5 */ -647, /* OBJ_international_organizations 2 23 */ -380, /* OBJ_dod 1 3 6 */ -12, /* OBJ_X509 2 5 4 */ -378, /* OBJ_X500algorithms 2 5 8 */ -81, /* OBJ_id_ce 2 5 29 */ -512, /* OBJ_id_set 2 23 42 */ -678, /* OBJ_wap 2 23 43 */ -435, /* OBJ_pss 0 9 2342 */ -183, /* OBJ_ISO_US 1 2 840 */ -381, /* OBJ_iana 1 3 6 1 */ -677, /* OBJ_certicom_arc 1 3 132 */ -394, /* OBJ_selected_attribute_types 2 5 1 5 */ -13, /* OBJ_commonName 2 5 4 3 */ -100, /* OBJ_surname 2 5 4 4 */ -105, /* OBJ_serialNumber 2 5 4 5 */ -14, /* OBJ_countryName 2 5 4 6 */ -15, /* OBJ_localityName 2 5 4 7 */ -16, /* OBJ_stateOrProvinceName 2 5 4 8 */ -660, /* OBJ_streetAddress 2 5 4 9 */ -17, /* OBJ_organizationName 2 5 4 10 */ -18, /* OBJ_organizationalUnitName 2 5 4 11 */ -106, /* OBJ_title 2 5 4 12 */ -107, /* OBJ_description 2 5 4 13 */ -859, /* OBJ_searchGuide 2 5 4 14 */ -860, /* OBJ_businessCategory 2 5 4 15 */ -861, /* OBJ_postalAddress 2 5 4 16 */ -661, /* OBJ_postalCode 2 5 4 17 */ -862, /* OBJ_postOfficeBox 2 5 4 18 */ -863, /* OBJ_physicalDeliveryOfficeName 2 5 4 19 */ -864, /* OBJ_telephoneNumber 2 5 4 20 */ -865, /* OBJ_telexNumber 2 5 4 21 */ -866, /* OBJ_teletexTerminalIdentifier 2 5 4 22 */ -867, /* OBJ_facsimileTelephoneNumber 2 5 4 23 */ -868, /* OBJ_x121Address 2 5 4 24 */ -869, /* OBJ_internationaliSDNNumber 2 5 4 25 */ -870, /* OBJ_registeredAddress 2 5 4 26 */ -871, /* OBJ_destinationIndicator 2 5 4 27 */ -872, /* OBJ_preferredDeliveryMethod 2 5 4 28 */ -873, /* OBJ_presentationAddress 2 5 4 29 */ -874, /* OBJ_supportedApplicationContext 2 5 4 30 */ -875, /* OBJ_member 2 5 4 31 */ -876, /* OBJ_owner 2 5 4 32 */ -877, /* OBJ_roleOccupant 2 5 4 33 */ -878, /* OBJ_seeAlso 2 5 4 34 */ -879, /* OBJ_userPassword 2 5 4 35 */ -880, /* OBJ_userCertificate 2 5 4 36 */ -881, /* OBJ_cACertificate 2 5 4 37 */ -882, /* OBJ_authorityRevocationList 2 5 4 38 */ -883, /* OBJ_certificateRevocationList 2 5 4 39 */ -884, /* OBJ_crossCertificatePair 2 5 4 40 */ -173, /* OBJ_name 2 5 4 41 */ -99, /* OBJ_givenName 2 5 4 42 */ -101, /* OBJ_initials 2 5 4 43 */ -509, /* OBJ_generationQualifier 2 5 4 44 */ -503, /* OBJ_x500UniqueIdentifier 2 5 4 45 */ -174, /* OBJ_dnQualifier 2 5 4 46 */ -885, /* OBJ_enhancedSearchGuide 2 5 4 47 */ -886, /* OBJ_protocolInformation 2 5 4 48 */ -887, /* OBJ_distinguishedName 2 5 4 49 */ -888, /* OBJ_uniqueMember 2 5 4 50 */ -889, /* OBJ_houseIdentifier 2 5 4 51 */ -890, /* OBJ_supportedAlgorithms 2 5 4 52 */ -891, /* OBJ_deltaRevocationList 2 5 4 53 */ -892, /* OBJ_dmdName 2 5 4 54 */ -510, /* OBJ_pseudonym 2 5 4 65 */ -400, /* OBJ_role 2 5 4 72 */ -769, /* OBJ_subject_directory_attributes 2 5 29 9 */ -82, /* OBJ_subject_key_identifier 2 5 29 14 */ -83, /* OBJ_key_usage 2 5 29 15 */ -84, /* OBJ_private_key_usage_period 2 5 29 16 */ -85, /* OBJ_subject_alt_name 2 5 29 17 */ -86, /* OBJ_issuer_alt_name 2 5 29 18 */ -87, /* OBJ_basic_constraints 2 5 29 19 */ -88, /* OBJ_crl_number 2 5 29 20 */ -141, /* OBJ_crl_reason 2 5 29 21 */ -430, /* OBJ_hold_instruction_code 2 5 29 23 */ -142, /* OBJ_invalidity_date 2 5 29 24 */ -140, /* OBJ_delta_crl 2 5 29 27 */ -770, /* OBJ_issuing_distribution_point 2 5 29 28 */ -771, /* OBJ_certificate_issuer 2 5 29 29 */ -666, /* OBJ_name_constraints 2 5 29 30 */ -103, /* OBJ_crl_distribution_points 2 5 29 31 */ -89, /* OBJ_certificate_policies 2 5 29 32 */ -747, /* OBJ_policy_mappings 2 5 29 33 */ -90, /* OBJ_authority_key_identifier 2 5 29 35 */ -401, /* OBJ_policy_constraints 2 5 29 36 */ -126, /* OBJ_ext_key_usage 2 5 29 37 */ -857, /* OBJ_freshest_crl 2 5 29 46 */ -748, /* OBJ_inhibit_any_policy 2 5 29 54 */ -402, /* OBJ_target_information 2 5 29 55 */ -403, /* OBJ_no_rev_avail 2 5 29 56 */ -513, /* OBJ_set_ctype 2 23 42 0 */ -514, /* OBJ_set_msgExt 2 23 42 1 */ -515, /* OBJ_set_attr 2 23 42 3 */ -516, /* OBJ_set_policy 2 23 42 5 */ -517, /* OBJ_set_certExt 2 23 42 7 */ -518, /* OBJ_set_brand 2 23 42 8 */ -679, /* OBJ_wap_wsg 2 23 43 1 */ -382, /* OBJ_Directory 1 3 6 1 1 */ -383, /* OBJ_Management 1 3 6 1 2 */ -384, /* OBJ_Experimental 1 3 6 1 3 */ -385, /* OBJ_Private 1 3 6 1 4 */ -386, /* OBJ_Security 1 3 6 1 5 */ -387, /* OBJ_SNMPv2 1 3 6 1 6 */ -388, /* OBJ_Mail 1 3 6 1 7 */ -376, /* OBJ_algorithm 1 3 14 3 2 */ -395, /* OBJ_clearance 2 5 1 5 55 */ -19, /* OBJ_rsa 2 5 8 1 1 */ -96, /* OBJ_mdc2WithRSA 2 5 8 3 100 */ -95, /* OBJ_mdc2 2 5 8 3 101 */ -746, /* OBJ_any_policy 2 5 29 32 0 */ -910, /* OBJ_anyExtendedKeyUsage 2 5 29 37 0 */ -519, /* OBJ_setct_PANData 2 23 42 0 0 */ -520, /* OBJ_setct_PANToken 2 23 42 0 1 */ -521, /* OBJ_setct_PANOnly 2 23 42 0 2 */ -522, /* OBJ_setct_OIData 2 23 42 0 3 */ -523, /* OBJ_setct_PI 2 23 42 0 4 */ -524, /* OBJ_setct_PIData 2 23 42 0 5 */ -525, /* OBJ_setct_PIDataUnsigned 2 23 42 0 6 */ -526, /* OBJ_setct_HODInput 2 23 42 0 7 */ -527, /* OBJ_setct_AuthResBaggage 2 23 42 0 8 */ -528, /* OBJ_setct_AuthRevReqBaggage 2 23 42 0 9 */ -529, /* OBJ_setct_AuthRevResBaggage 2 23 42 0 10 */ -530, /* OBJ_setct_CapTokenSeq 2 23 42 0 11 */ -531, /* OBJ_setct_PInitResData 2 23 42 0 12 */ -532, /* OBJ_setct_PI_TBS 2 23 42 0 13 */ -533, /* OBJ_setct_PResData 2 23 42 0 14 */ -534, /* OBJ_setct_AuthReqTBS 2 23 42 0 16 */ -535, /* OBJ_setct_AuthResTBS 2 23 42 0 17 */ -536, /* OBJ_setct_AuthResTBSX 2 23 42 0 18 */ -537, /* OBJ_setct_AuthTokenTBS 2 23 42 0 19 */ -538, /* OBJ_setct_CapTokenData 2 23 42 0 20 */ -539, /* OBJ_setct_CapTokenTBS 2 23 42 0 21 */ -540, /* OBJ_setct_AcqCardCodeMsg 2 23 42 0 22 */ -541, /* OBJ_setct_AuthRevReqTBS 2 23 42 0 23 */ -542, /* OBJ_setct_AuthRevResData 2 23 42 0 24 */ -543, /* OBJ_setct_AuthRevResTBS 2 23 42 0 25 */ -544, /* OBJ_setct_CapReqTBS 2 23 42 0 26 */ -545, /* OBJ_setct_CapReqTBSX 2 23 42 0 27 */ -546, /* OBJ_setct_CapResData 2 23 42 0 28 */ -547, /* OBJ_setct_CapRevReqTBS 2 23 42 0 29 */ -548, /* OBJ_setct_CapRevReqTBSX 2 23 42 0 30 */ -549, /* OBJ_setct_CapRevResData 2 23 42 0 31 */ -550, /* OBJ_setct_CredReqTBS 2 23 42 0 32 */ -551, /* OBJ_setct_CredReqTBSX 2 23 42 0 33 */ -552, /* OBJ_setct_CredResData 2 23 42 0 34 */ -553, /* OBJ_setct_CredRevReqTBS 2 23 42 0 35 */ -554, /* OBJ_setct_CredRevReqTBSX 2 23 42 0 36 */ -555, /* OBJ_setct_CredRevResData 2 23 42 0 37 */ -556, /* OBJ_setct_PCertReqData 2 23 42 0 38 */ -557, /* OBJ_setct_PCertResTBS 2 23 42 0 39 */ -558, /* OBJ_setct_BatchAdminReqData 2 23 42 0 40 */ -559, /* OBJ_setct_BatchAdminResData 2 23 42 0 41 */ -560, /* OBJ_setct_CardCInitResTBS 2 23 42 0 42 */ -561, /* OBJ_setct_MeAqCInitResTBS 2 23 42 0 43 */ -562, /* OBJ_setct_RegFormResTBS 2 23 42 0 44 */ -563, /* OBJ_setct_CertReqData 2 23 42 0 45 */ -564, /* OBJ_setct_CertReqTBS 2 23 42 0 46 */ -565, /* OBJ_setct_CertResData 2 23 42 0 47 */ -566, /* OBJ_setct_CertInqReqTBS 2 23 42 0 48 */ -567, /* OBJ_setct_ErrorTBS 2 23 42 0 49 */ -568, /* OBJ_setct_PIDualSignedTBE 2 23 42 0 50 */ -569, /* OBJ_setct_PIUnsignedTBE 2 23 42 0 51 */ -570, /* OBJ_setct_AuthReqTBE 2 23 42 0 52 */ -571, /* OBJ_setct_AuthResTBE 2 23 42 0 53 */ -572, /* OBJ_setct_AuthResTBEX 2 23 42 0 54 */ -573, /* OBJ_setct_AuthTokenTBE 2 23 42 0 55 */ -574, /* OBJ_setct_CapTokenTBE 2 23 42 0 56 */ -575, /* OBJ_setct_CapTokenTBEX 2 23 42 0 57 */ -576, /* OBJ_setct_AcqCardCodeMsgTBE 2 23 42 0 58 */ -577, /* OBJ_setct_AuthRevReqTBE 2 23 42 0 59 */ -578, /* OBJ_setct_AuthRevResTBE 2 23 42 0 60 */ -579, /* OBJ_setct_AuthRevResTBEB 2 23 42 0 61 */ -580, /* OBJ_setct_CapReqTBE 2 23 42 0 62 */ -581, /* OBJ_setct_CapReqTBEX 2 23 42 0 63 */ -582, /* OBJ_setct_CapResTBE 2 23 42 0 64 */ -583, /* OBJ_setct_CapRevReqTBE 2 23 42 0 65 */ -584, /* OBJ_setct_CapRevReqTBEX 2 23 42 0 66 */ -585, /* OBJ_setct_CapRevResTBE 2 23 42 0 67 */ -586, /* OBJ_setct_CredReqTBE 2 23 42 0 68 */ -587, /* OBJ_setct_CredReqTBEX 2 23 42 0 69 */ -588, /* OBJ_setct_CredResTBE 2 23 42 0 70 */ -589, /* OBJ_setct_CredRevReqTBE 2 23 42 0 71 */ -590, /* OBJ_setct_CredRevReqTBEX 2 23 42 0 72 */ -591, /* OBJ_setct_CredRevResTBE 2 23 42 0 73 */ -592, /* OBJ_setct_BatchAdminReqTBE 2 23 42 0 74 */ -593, /* OBJ_setct_BatchAdminResTBE 2 23 42 0 75 */ -594, /* OBJ_setct_RegFormReqTBE 2 23 42 0 76 */ -595, /* OBJ_setct_CertReqTBE 2 23 42 0 77 */ -596, /* OBJ_setct_CertReqTBEX 2 23 42 0 78 */ -597, /* OBJ_setct_CertResTBE 2 23 42 0 79 */ -598, /* OBJ_setct_CRLNotificationTBS 2 23 42 0 80 */ -599, /* OBJ_setct_CRLNotificationResTBS 2 23 42 0 81 */ -600, /* OBJ_setct_BCIDistributionTBS 2 23 42 0 82 */ -601, /* OBJ_setext_genCrypt 2 23 42 1 1 */ -602, /* OBJ_setext_miAuth 2 23 42 1 3 */ -603, /* OBJ_setext_pinSecure 2 23 42 1 4 */ -604, /* OBJ_setext_pinAny 2 23 42 1 5 */ -605, /* OBJ_setext_track2 2 23 42 1 7 */ -606, /* OBJ_setext_cv 2 23 42 1 8 */ -620, /* OBJ_setAttr_Cert 2 23 42 3 0 */ -621, /* OBJ_setAttr_PGWYcap 2 23 42 3 1 */ -622, /* OBJ_setAttr_TokenType 2 23 42 3 2 */ -623, /* OBJ_setAttr_IssCap 2 23 42 3 3 */ -607, /* OBJ_set_policy_root 2 23 42 5 0 */ -608, /* OBJ_setCext_hashedRoot 2 23 42 7 0 */ -609, /* OBJ_setCext_certType 2 23 42 7 1 */ -610, /* OBJ_setCext_merchData 2 23 42 7 2 */ -611, /* OBJ_setCext_cCertRequired 2 23 42 7 3 */ -612, /* OBJ_setCext_tunneling 2 23 42 7 4 */ -613, /* OBJ_setCext_setExt 2 23 42 7 5 */ -614, /* OBJ_setCext_setQualf 2 23 42 7 6 */ -615, /* OBJ_setCext_PGWYcapabilities 2 23 42 7 7 */ -616, /* OBJ_setCext_TokenIdentifier 2 23 42 7 8 */ -617, /* OBJ_setCext_Track2Data 2 23 42 7 9 */ -618, /* OBJ_setCext_TokenType 2 23 42 7 10 */ -619, /* OBJ_setCext_IssuerCapabilities 2 23 42 7 11 */ -636, /* OBJ_set_brand_IATA_ATA 2 23 42 8 1 */ -640, /* OBJ_set_brand_Visa 2 23 42 8 4 */ -641, /* OBJ_set_brand_MasterCard 2 23 42 8 5 */ -637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ -638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ -639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ -805, /* OBJ_cryptopro 1 2 643 2 2 */ -806, /* OBJ_cryptocom 1 2 643 2 9 */ -184, /* OBJ_X9_57 1 2 840 10040 */ -405, /* OBJ_ansi_X9_62 1 2 840 10045 */ -389, /* OBJ_Enterprises 1 3 6 1 4 1 */ -504, /* OBJ_mime_mhs 1 3 6 1 7 1 */ -104, /* OBJ_md5WithRSA 1 3 14 3 2 3 */ -29, /* OBJ_des_ecb 1 3 14 3 2 6 */ -31, /* OBJ_des_cbc 1 3 14 3 2 7 */ -45, /* OBJ_des_ofb64 1 3 14 3 2 8 */ -30, /* OBJ_des_cfb64 1 3 14 3 2 9 */ -377, /* OBJ_rsaSignature 1 3 14 3 2 11 */ -67, /* OBJ_dsa_2 1 3 14 3 2 12 */ -66, /* OBJ_dsaWithSHA 1 3 14 3 2 13 */ -42, /* OBJ_shaWithRSAEncryption 1 3 14 3 2 15 */ -32, /* OBJ_des_ede_ecb 1 3 14 3 2 17 */ -41, /* OBJ_sha 1 3 14 3 2 18 */ -64, /* OBJ_sha1 1 3 14 3 2 26 */ -70, /* OBJ_dsaWithSHA1_2 1 3 14 3 2 27 */ -115, /* OBJ_sha1WithRSA 1 3 14 3 2 29 */ -117, /* OBJ_ripemd160 1 3 36 3 2 1 */ -143, /* OBJ_sxnet 1 3 101 1 4 1 */ -721, /* OBJ_sect163k1 1 3 132 0 1 */ -722, /* OBJ_sect163r1 1 3 132 0 2 */ -728, /* OBJ_sect239k1 1 3 132 0 3 */ -717, /* OBJ_sect113r1 1 3 132 0 4 */ -718, /* OBJ_sect113r2 1 3 132 0 5 */ -704, /* OBJ_secp112r1 1 3 132 0 6 */ -705, /* OBJ_secp112r2 1 3 132 0 7 */ -709, /* OBJ_secp160r1 1 3 132 0 8 */ -708, /* OBJ_secp160k1 1 3 132 0 9 */ -714, /* OBJ_secp256k1 1 3 132 0 10 */ -723, /* OBJ_sect163r2 1 3 132 0 15 */ -729, /* OBJ_sect283k1 1 3 132 0 16 */ -730, /* OBJ_sect283r1 1 3 132 0 17 */ -719, /* OBJ_sect131r1 1 3 132 0 22 */ -720, /* OBJ_sect131r2 1 3 132 0 23 */ -724, /* OBJ_sect193r1 1 3 132 0 24 */ -725, /* OBJ_sect193r2 1 3 132 0 25 */ -726, /* OBJ_sect233k1 1 3 132 0 26 */ -727, /* OBJ_sect233r1 1 3 132 0 27 */ -706, /* OBJ_secp128r1 1 3 132 0 28 */ -707, /* OBJ_secp128r2 1 3 132 0 29 */ -710, /* OBJ_secp160r2 1 3 132 0 30 */ -711, /* OBJ_secp192k1 1 3 132 0 31 */ -712, /* OBJ_secp224k1 1 3 132 0 32 */ -713, /* OBJ_secp224r1 1 3 132 0 33 */ -715, /* OBJ_secp384r1 1 3 132 0 34 */ -716, /* OBJ_secp521r1 1 3 132 0 35 */ -731, /* OBJ_sect409k1 1 3 132 0 36 */ -732, /* OBJ_sect409r1 1 3 132 0 37 */ -733, /* OBJ_sect571k1 1 3 132 0 38 */ -734, /* OBJ_sect571r1 1 3 132 0 39 */ -624, /* OBJ_set_rootKeyThumb 2 23 42 3 0 0 */ -625, /* OBJ_set_addPolicy 2 23 42 3 0 1 */ -626, /* OBJ_setAttr_Token_EMV 2 23 42 3 2 1 */ -627, /* OBJ_setAttr_Token_B0Prime 2 23 42 3 2 2 */ -628, /* OBJ_setAttr_IssCap_CVM 2 23 42 3 3 3 */ -629, /* OBJ_setAttr_IssCap_T2 2 23 42 3 3 4 */ -630, /* OBJ_setAttr_IssCap_Sig 2 23 42 3 3 5 */ -642, /* OBJ_set_brand_Novus 2 23 42 8 6011 */ -735, /* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 1 4 1 */ -736, /* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 1 4 3 */ -737, /* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 1 4 4 */ -738, /* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 1 4 5 */ -739, /* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 1 4 6 */ -740, /* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 1 4 7 */ -741, /* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 1 4 8 */ -742, /* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 1 4 9 */ -743, /* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ -744, /* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ -745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ -804, /* OBJ_whirlpool 1 0 10118 3 0 55 */ -124, /* OBJ_rle_compression 1 1 1 1 666 1 */ -773, /* OBJ_kisa 1 2 410 200004 */ -807, /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */ -808, /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */ -809, /* OBJ_id_GostR3411_94 1 2 643 2 2 9 */ -810, /* OBJ_id_HMACGostR3411_94 1 2 643 2 2 10 */ -811, /* OBJ_id_GostR3410_2001 1 2 643 2 2 19 */ -812, /* OBJ_id_GostR3410_94 1 2 643 2 2 20 */ -813, /* OBJ_id_Gost28147_89 1 2 643 2 2 21 */ -815, /* OBJ_id_Gost28147_89_MAC 1 2 643 2 2 22 */ -816, /* OBJ_id_GostR3411_94_prf 1 2 643 2 2 23 */ -817, /* OBJ_id_GostR3410_2001DH 1 2 643 2 2 98 */ -818, /* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ - 1, /* OBJ_rsadsi 1 2 840 113549 */ -185, /* OBJ_X9cm 1 2 840 10040 4 */ -127, /* OBJ_id_pkix 1 3 6 1 5 5 7 */ -505, /* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */ -506, /* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */ -119, /* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */ -937, /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */ -938, /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */ -939, /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */ -940, /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */ -942, /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */ -943, /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */ -944, /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */ -945, /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */ -631, /* OBJ_setAttr_GenCryptgrm 2 23 42 3 3 3 1 */ -632, /* OBJ_setAttr_T2Enc 2 23 42 3 3 4 1 */ -633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ -634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ -635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ -436, /* OBJ_ucl 0 9 2342 19200300 */ -820, /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */ -819, /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */ -845, /* OBJ_id_GostR3410_94_a 1 2 643 2 2 20 1 */ -846, /* OBJ_id_GostR3410_94_aBis 1 2 643 2 2 20 2 */ -847, /* OBJ_id_GostR3410_94_b 1 2 643 2 2 20 3 */ -848, /* OBJ_id_GostR3410_94_bBis 1 2 643 2 2 20 4 */ -821, /* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */ -822, /* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */ -823, /* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */ -824, /* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */ -825, /* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */ -826, /* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */ -827, /* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */ -828, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */ -829, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */ -830, /* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */ -831, /* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */ -832, /* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */ -833, /* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */ -834, /* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */ -835, /* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */ -836, /* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */ -837, /* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */ -838, /* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */ -839, /* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */ -840, /* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */ -841, /* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */ -842, /* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */ -843, /* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */ -844, /* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */ - 2, /* OBJ_pkcs 1 2 840 113549 1 */ -431, /* OBJ_hold_instruction_none 1 2 840 10040 2 1 */ -432, /* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */ -433, /* OBJ_hold_instruction_reject 1 2 840 10040 2 3 */ -116, /* OBJ_dsa 1 2 840 10040 4 1 */ -113, /* OBJ_dsaWithSHA1 1 2 840 10040 4 3 */ -406, /* OBJ_X9_62_prime_field 1 2 840 10045 1 1 */ -407, /* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */ -408, /* OBJ_X9_62_id_ecPublicKey 1 2 840 10045 2 1 */ -416, /* OBJ_ecdsa_with_SHA1 1 2 840 10045 4 1 */ -791, /* OBJ_ecdsa_with_Recommended 1 2 840 10045 4 2 */ -792, /* OBJ_ecdsa_with_Specified 1 2 840 10045 4 3 */ -920, /* OBJ_dhpublicnumber 1 2 840 10046 2 1 */ -258, /* OBJ_id_pkix_mod 1 3 6 1 5 5 7 0 */ -175, /* OBJ_id_pe 1 3 6 1 5 5 7 1 */ -259, /* OBJ_id_qt 1 3 6 1 5 5 7 2 */ -128, /* OBJ_id_kp 1 3 6 1 5 5 7 3 */ -260, /* OBJ_id_it 1 3 6 1 5 5 7 4 */ -261, /* OBJ_id_pkip 1 3 6 1 5 5 7 5 */ -262, /* OBJ_id_alg 1 3 6 1 5 5 7 6 */ -263, /* OBJ_id_cmc 1 3 6 1 5 5 7 7 */ -264, /* OBJ_id_on 1 3 6 1 5 5 7 8 */ -265, /* OBJ_id_pda 1 3 6 1 5 5 7 9 */ -266, /* OBJ_id_aca 1 3 6 1 5 5 7 10 */ -267, /* OBJ_id_qcs 1 3 6 1 5 5 7 11 */ -268, /* OBJ_id_cct 1 3 6 1 5 5 7 12 */ -662, /* OBJ_id_ppl 1 3 6 1 5 5 7 21 */ -176, /* OBJ_id_ad 1 3 6 1 5 5 7 48 */ -507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ -508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ -57, /* OBJ_netscape 2 16 840 1 113730 */ -754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ -766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ -757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ -755, /* OBJ_camellia_192_ecb 0 3 4401 5 3 1 9 21 */ -767, /* OBJ_camellia_192_ofb128 0 3 4401 5 3 1 9 23 */ -758, /* OBJ_camellia_192_cfb128 0 3 4401 5 3 1 9 24 */ -756, /* OBJ_camellia_256_ecb 0 3 4401 5 3 1 9 41 */ -768, /* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ -759, /* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ -437, /* OBJ_pilot 0 9 2342 19200300 100 */ -776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ -777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ -779, /* OBJ_seed_cfb128 1 2 410 200004 1 5 */ -778, /* OBJ_seed_ofb128 1 2 410 200004 1 6 */ -852, /* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */ -853, /* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */ -850, /* OBJ_id_GostR3410_94_cc 1 2 643 2 9 1 5 3 */ -851, /* OBJ_id_GostR3410_2001_cc 1 2 643 2 9 1 5 4 */ -849, /* OBJ_id_Gost28147_89_cc 1 2 643 2 9 1 6 1 */ -854, /* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */ -186, /* OBJ_pkcs1 1 2 840 113549 1 1 */ -27, /* OBJ_pkcs3 1 2 840 113549 1 3 */ -187, /* OBJ_pkcs5 1 2 840 113549 1 5 */ -20, /* OBJ_pkcs7 1 2 840 113549 1 7 */ -47, /* OBJ_pkcs9 1 2 840 113549 1 9 */ - 3, /* OBJ_md2 1 2 840 113549 2 2 */ -257, /* OBJ_md4 1 2 840 113549 2 4 */ - 4, /* OBJ_md5 1 2 840 113549 2 5 */ -797, /* OBJ_hmacWithMD5 1 2 840 113549 2 6 */ -163, /* OBJ_hmacWithSHA1 1 2 840 113549 2 7 */ -798, /* OBJ_hmacWithSHA224 1 2 840 113549 2 8 */ -799, /* OBJ_hmacWithSHA256 1 2 840 113549 2 9 */ -800, /* OBJ_hmacWithSHA384 1 2 840 113549 2 10 */ -801, /* OBJ_hmacWithSHA512 1 2 840 113549 2 11 */ -37, /* OBJ_rc2_cbc 1 2 840 113549 3 2 */ - 5, /* OBJ_rc4 1 2 840 113549 3 4 */ -44, /* OBJ_des_ede3_cbc 1 2 840 113549 3 7 */ -120, /* OBJ_rc5_cbc 1 2 840 113549 3 8 */ -643, /* OBJ_des_cdmf 1 2 840 113549 3 10 */ -680, /* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */ -684, /* OBJ_X9_62_c2pnb163v1 1 2 840 10045 3 0 1 */ -685, /* OBJ_X9_62_c2pnb163v2 1 2 840 10045 3 0 2 */ -686, /* OBJ_X9_62_c2pnb163v3 1 2 840 10045 3 0 3 */ -687, /* OBJ_X9_62_c2pnb176v1 1 2 840 10045 3 0 4 */ -688, /* OBJ_X9_62_c2tnb191v1 1 2 840 10045 3 0 5 */ -689, /* OBJ_X9_62_c2tnb191v2 1 2 840 10045 3 0 6 */ -690, /* OBJ_X9_62_c2tnb191v3 1 2 840 10045 3 0 7 */ -691, /* OBJ_X9_62_c2onb191v4 1 2 840 10045 3 0 8 */ -692, /* OBJ_X9_62_c2onb191v5 1 2 840 10045 3 0 9 */ -693, /* OBJ_X9_62_c2pnb208w1 1 2 840 10045 3 0 10 */ -694, /* OBJ_X9_62_c2tnb239v1 1 2 840 10045 3 0 11 */ -695, /* OBJ_X9_62_c2tnb239v2 1 2 840 10045 3 0 12 */ -696, /* OBJ_X9_62_c2tnb239v3 1 2 840 10045 3 0 13 */ -697, /* OBJ_X9_62_c2onb239v4 1 2 840 10045 3 0 14 */ -698, /* OBJ_X9_62_c2onb239v5 1 2 840 10045 3 0 15 */ -699, /* OBJ_X9_62_c2pnb272w1 1 2 840 10045 3 0 16 */ -700, /* OBJ_X9_62_c2pnb304w1 1 2 840 10045 3 0 17 */ -701, /* OBJ_X9_62_c2tnb359v1 1 2 840 10045 3 0 18 */ -702, /* OBJ_X9_62_c2pnb368w1 1 2 840 10045 3 0 19 */ -703, /* OBJ_X9_62_c2tnb431r1 1 2 840 10045 3 0 20 */ -409, /* OBJ_X9_62_prime192v1 1 2 840 10045 3 1 1 */ -410, /* OBJ_X9_62_prime192v2 1 2 840 10045 3 1 2 */ -411, /* OBJ_X9_62_prime192v3 1 2 840 10045 3 1 3 */ -412, /* OBJ_X9_62_prime239v1 1 2 840 10045 3 1 4 */ -413, /* OBJ_X9_62_prime239v2 1 2 840 10045 3 1 5 */ -414, /* OBJ_X9_62_prime239v3 1 2 840 10045 3 1 6 */ -415, /* OBJ_X9_62_prime256v1 1 2 840 10045 3 1 7 */ -793, /* OBJ_ecdsa_with_SHA224 1 2 840 10045 4 3 1 */ -794, /* OBJ_ecdsa_with_SHA256 1 2 840 10045 4 3 2 */ -795, /* OBJ_ecdsa_with_SHA384 1 2 840 10045 4 3 3 */ -796, /* OBJ_ecdsa_with_SHA512 1 2 840 10045 4 3 4 */ -269, /* OBJ_id_pkix1_explicit_88 1 3 6 1 5 5 7 0 1 */ -270, /* OBJ_id_pkix1_implicit_88 1 3 6 1 5 5 7 0 2 */ -271, /* OBJ_id_pkix1_explicit_93 1 3 6 1 5 5 7 0 3 */ -272, /* OBJ_id_pkix1_implicit_93 1 3 6 1 5 5 7 0 4 */ -273, /* OBJ_id_mod_crmf 1 3 6 1 5 5 7 0 5 */ -274, /* OBJ_id_mod_cmc 1 3 6 1 5 5 7 0 6 */ -275, /* OBJ_id_mod_kea_profile_88 1 3 6 1 5 5 7 0 7 */ -276, /* OBJ_id_mod_kea_profile_93 1 3 6 1 5 5 7 0 8 */ -277, /* OBJ_id_mod_cmp 1 3 6 1 5 5 7 0 9 */ -278, /* OBJ_id_mod_qualified_cert_88 1 3 6 1 5 5 7 0 10 */ -279, /* OBJ_id_mod_qualified_cert_93 1 3 6 1 5 5 7 0 11 */ -280, /* OBJ_id_mod_attribute_cert 1 3 6 1 5 5 7 0 12 */ -281, /* OBJ_id_mod_timestamp_protocol 1 3 6 1 5 5 7 0 13 */ -282, /* OBJ_id_mod_ocsp 1 3 6 1 5 5 7 0 14 */ -283, /* OBJ_id_mod_dvcs 1 3 6 1 5 5 7 0 15 */ -284, /* OBJ_id_mod_cmp2000 1 3 6 1 5 5 7 0 16 */ -177, /* OBJ_info_access 1 3 6 1 5 5 7 1 1 */ -285, /* OBJ_biometricInfo 1 3 6 1 5 5 7 1 2 */ -286, /* OBJ_qcStatements 1 3 6 1 5 5 7 1 3 */ -287, /* OBJ_ac_auditEntity 1 3 6 1 5 5 7 1 4 */ -288, /* OBJ_ac_targeting 1 3 6 1 5 5 7 1 5 */ -289, /* OBJ_aaControls 1 3 6 1 5 5 7 1 6 */ -290, /* OBJ_sbgp_ipAddrBlock 1 3 6 1 5 5 7 1 7 */ -291, /* OBJ_sbgp_autonomousSysNum 1 3 6 1 5 5 7 1 8 */ -292, /* OBJ_sbgp_routerIdentifier 1 3 6 1 5 5 7 1 9 */ -397, /* OBJ_ac_proxying 1 3 6 1 5 5 7 1 10 */ -398, /* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ -663, /* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ -164, /* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ -165, /* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ -293, /* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ -129, /* OBJ_server_auth 1 3 6 1 5 5 7 3 1 */ -130, /* OBJ_client_auth 1 3 6 1 5 5 7 3 2 */ -131, /* OBJ_code_sign 1 3 6 1 5 5 7 3 3 */ -132, /* OBJ_email_protect 1 3 6 1 5 5 7 3 4 */ -294, /* OBJ_ipsecEndSystem 1 3 6 1 5 5 7 3 5 */ -295, /* OBJ_ipsecTunnel 1 3 6 1 5 5 7 3 6 */ -296, /* OBJ_ipsecUser 1 3 6 1 5 5 7 3 7 */ -133, /* OBJ_time_stamp 1 3 6 1 5 5 7 3 8 */ -180, /* OBJ_OCSP_sign 1 3 6 1 5 5 7 3 9 */ -297, /* OBJ_dvcs 1 3 6 1 5 5 7 3 10 */ -298, /* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ -299, /* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ -300, /* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ -301, /* OBJ_id_it_preferredSymmAlg 1 3 6 1 5 5 7 4 4 */ -302, /* OBJ_id_it_caKeyUpdateInfo 1 3 6 1 5 5 7 4 5 */ -303, /* OBJ_id_it_currentCRL 1 3 6 1 5 5 7 4 6 */ -304, /* OBJ_id_it_unsupportedOIDs 1 3 6 1 5 5 7 4 7 */ -305, /* OBJ_id_it_subscriptionRequest 1 3 6 1 5 5 7 4 8 */ -306, /* OBJ_id_it_subscriptionResponse 1 3 6 1 5 5 7 4 9 */ -307, /* OBJ_id_it_keyPairParamReq 1 3 6 1 5 5 7 4 10 */ -308, /* OBJ_id_it_keyPairParamRep 1 3 6 1 5 5 7 4 11 */ -309, /* OBJ_id_it_revPassphrase 1 3 6 1 5 5 7 4 12 */ -310, /* OBJ_id_it_implicitConfirm 1 3 6 1 5 5 7 4 13 */ -311, /* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ -312, /* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ -784, /* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ -313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ -314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ -323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ -324, /* OBJ_id_alg_noSignature 1 3 6 1 5 5 7 6 2 */ -325, /* OBJ_id_alg_dh_sig_hmac_sha1 1 3 6 1 5 5 7 6 3 */ -326, /* OBJ_id_alg_dh_pop 1 3 6 1 5 5 7 6 4 */ -327, /* OBJ_id_cmc_statusInfo 1 3 6 1 5 5 7 7 1 */ -328, /* OBJ_id_cmc_identification 1 3 6 1 5 5 7 7 2 */ -329, /* OBJ_id_cmc_identityProof 1 3 6 1 5 5 7 7 3 */ -330, /* OBJ_id_cmc_dataReturn 1 3 6 1 5 5 7 7 4 */ -331, /* OBJ_id_cmc_transactionId 1 3 6 1 5 5 7 7 5 */ -332, /* OBJ_id_cmc_senderNonce 1 3 6 1 5 5 7 7 6 */ -333, /* OBJ_id_cmc_recipientNonce 1 3 6 1 5 5 7 7 7 */ -334, /* OBJ_id_cmc_addExtensions 1 3 6 1 5 5 7 7 8 */ -335, /* OBJ_id_cmc_encryptedPOP 1 3 6 1 5 5 7 7 9 */ -336, /* OBJ_id_cmc_decryptedPOP 1 3 6 1 5 5 7 7 10 */ -337, /* OBJ_id_cmc_lraPOPWitness 1 3 6 1 5 5 7 7 11 */ -338, /* OBJ_id_cmc_getCert 1 3 6 1 5 5 7 7 15 */ -339, /* OBJ_id_cmc_getCRL 1 3 6 1 5 5 7 7 16 */ -340, /* OBJ_id_cmc_revokeRequest 1 3 6 1 5 5 7 7 17 */ -341, /* OBJ_id_cmc_regInfo 1 3 6 1 5 5 7 7 18 */ -342, /* OBJ_id_cmc_responseInfo 1 3 6 1 5 5 7 7 19 */ -343, /* OBJ_id_cmc_queryPending 1 3 6 1 5 5 7 7 21 */ -344, /* OBJ_id_cmc_popLinkRandom 1 3 6 1 5 5 7 7 22 */ -345, /* OBJ_id_cmc_popLinkWitness 1 3 6 1 5 5 7 7 23 */ -346, /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */ -347, /* OBJ_id_on_personalData 1 3 6 1 5 5 7 8 1 */ -858, /* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ -348, /* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ -349, /* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ -351, /* OBJ_id_pda_gender 1 3 6 1 5 5 7 9 3 */ -352, /* OBJ_id_pda_countryOfCitizenship 1 3 6 1 5 5 7 9 4 */ -353, /* OBJ_id_pda_countryOfResidence 1 3 6 1 5 5 7 9 5 */ -354, /* OBJ_id_aca_authenticationInfo 1 3 6 1 5 5 7 10 1 */ -355, /* OBJ_id_aca_accessIdentity 1 3 6 1 5 5 7 10 2 */ -356, /* OBJ_id_aca_chargingIdentity 1 3 6 1 5 5 7 10 3 */ -357, /* OBJ_id_aca_group 1 3 6 1 5 5 7 10 4 */ -358, /* OBJ_id_aca_role 1 3 6 1 5 5 7 10 5 */ -399, /* OBJ_id_aca_encAttrs 1 3 6 1 5 5 7 10 6 */ -359, /* OBJ_id_qcs_pkixQCSyntax_v1 1 3 6 1 5 5 7 11 1 */ -360, /* OBJ_id_cct_crs 1 3 6 1 5 5 7 12 1 */ -361, /* OBJ_id_cct_PKIData 1 3 6 1 5 5 7 12 2 */ -362, /* OBJ_id_cct_PKIResponse 1 3 6 1 5 5 7 12 3 */ -664, /* OBJ_id_ppl_anyLanguage 1 3 6 1 5 5 7 21 0 */ -665, /* OBJ_id_ppl_inheritAll 1 3 6 1 5 5 7 21 1 */ -667, /* OBJ_Independent 1 3 6 1 5 5 7 21 2 */ -178, /* OBJ_ad_OCSP 1 3 6 1 5 5 7 48 1 */ -179, /* OBJ_ad_ca_issuers 1 3 6 1 5 5 7 48 2 */ -363, /* OBJ_ad_timeStamping 1 3 6 1 5 5 7 48 3 */ -364, /* OBJ_ad_dvcs 1 3 6 1 5 5 7 48 4 */ -785, /* OBJ_caRepository 1 3 6 1 5 5 7 48 5 */ -780, /* OBJ_hmac_md5 1 3 6 1 5 5 8 1 1 */ -781, /* OBJ_hmac_sha1 1 3 6 1 5 5 8 1 2 */ -58, /* OBJ_netscape_cert_extension 2 16 840 1 113730 1 */ -59, /* OBJ_netscape_data_type 2 16 840 1 113730 2 */ -438, /* OBJ_pilotAttributeType 0 9 2342 19200300 100 1 */ -439, /* OBJ_pilotAttributeSyntax 0 9 2342 19200300 100 3 */ -440, /* OBJ_pilotObjectClass 0 9 2342 19200300 100 4 */ -441, /* OBJ_pilotGroups 0 9 2342 19200300 100 10 */ -108, /* OBJ_cast5_cbc 1 2 840 113533 7 66 10 */ -112, /* OBJ_pbeWithMD5AndCast5_CBC 1 2 840 113533 7 66 12 */ -782, /* OBJ_id_PasswordBasedMAC 1 2 840 113533 7 66 13 */ -783, /* OBJ_id_DHBasedMac 1 2 840 113533 7 66 30 */ - 6, /* OBJ_rsaEncryption 1 2 840 113549 1 1 1 */ - 7, /* OBJ_md2WithRSAEncryption 1 2 840 113549 1 1 2 */ -396, /* OBJ_md4WithRSAEncryption 1 2 840 113549 1 1 3 */ - 8, /* OBJ_md5WithRSAEncryption 1 2 840 113549 1 1 4 */ -65, /* OBJ_sha1WithRSAEncryption 1 2 840 113549 1 1 5 */ -644, /* OBJ_rsaOAEPEncryptionSET 1 2 840 113549 1 1 6 */ -919, /* OBJ_rsaesOaep 1 2 840 113549 1 1 7 */ -911, /* OBJ_mgf1 1 2 840 113549 1 1 8 */ -935, /* OBJ_pSpecified 1 2 840 113549 1 1 9 */ -912, /* OBJ_rsassaPss 1 2 840 113549 1 1 10 */ -668, /* OBJ_sha256WithRSAEncryption 1 2 840 113549 1 1 11 */ -669, /* OBJ_sha384WithRSAEncryption 1 2 840 113549 1 1 12 */ -670, /* OBJ_sha512WithRSAEncryption 1 2 840 113549 1 1 13 */ -671, /* OBJ_sha224WithRSAEncryption 1 2 840 113549 1 1 14 */ -28, /* OBJ_dhKeyAgreement 1 2 840 113549 1 3 1 */ - 9, /* OBJ_pbeWithMD2AndDES_CBC 1 2 840 113549 1 5 1 */ -10, /* OBJ_pbeWithMD5AndDES_CBC 1 2 840 113549 1 5 3 */ -168, /* OBJ_pbeWithMD2AndRC2_CBC 1 2 840 113549 1 5 4 */ -169, /* OBJ_pbeWithMD5AndRC2_CBC 1 2 840 113549 1 5 6 */ -170, /* OBJ_pbeWithSHA1AndDES_CBC 1 2 840 113549 1 5 10 */ -68, /* OBJ_pbeWithSHA1AndRC2_CBC 1 2 840 113549 1 5 11 */ -69, /* OBJ_id_pbkdf2 1 2 840 113549 1 5 12 */ -161, /* OBJ_pbes2 1 2 840 113549 1 5 13 */ -162, /* OBJ_pbmac1 1 2 840 113549 1 5 14 */ -21, /* OBJ_pkcs7_data 1 2 840 113549 1 7 1 */ -22, /* OBJ_pkcs7_signed 1 2 840 113549 1 7 2 */ -23, /* OBJ_pkcs7_enveloped 1 2 840 113549 1 7 3 */ -24, /* OBJ_pkcs7_signedAndEnveloped 1 2 840 113549 1 7 4 */ -25, /* OBJ_pkcs7_digest 1 2 840 113549 1 7 5 */ -26, /* OBJ_pkcs7_encrypted 1 2 840 113549 1 7 6 */ -48, /* OBJ_pkcs9_emailAddress 1 2 840 113549 1 9 1 */ -49, /* OBJ_pkcs9_unstructuredName 1 2 840 113549 1 9 2 */ -50, /* OBJ_pkcs9_contentType 1 2 840 113549 1 9 3 */ -51, /* OBJ_pkcs9_messageDigest 1 2 840 113549 1 9 4 */ -52, /* OBJ_pkcs9_signingTime 1 2 840 113549 1 9 5 */ -53, /* OBJ_pkcs9_countersignature 1 2 840 113549 1 9 6 */ -54, /* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ -55, /* OBJ_pkcs9_unstructuredAddress 1 2 840 113549 1 9 8 */ -56, /* OBJ_pkcs9_extCertAttributes 1 2 840 113549 1 9 9 */ -172, /* OBJ_ext_req 1 2 840 113549 1 9 14 */ -167, /* OBJ_SMIMECapabilities 1 2 840 113549 1 9 15 */ -188, /* OBJ_SMIME 1 2 840 113549 1 9 16 */ -156, /* OBJ_friendlyName 1 2 840 113549 1 9 20 */ -157, /* OBJ_localKeyID 1 2 840 113549 1 9 21 */ -681, /* OBJ_X9_62_onBasis 1 2 840 10045 1 2 3 1 */ -682, /* OBJ_X9_62_tpBasis 1 2 840 10045 1 2 3 2 */ -683, /* OBJ_X9_62_ppBasis 1 2 840 10045 1 2 3 3 */ -417, /* OBJ_ms_csp_name 1 3 6 1 4 1 311 17 1 */ -856, /* OBJ_LocalKeySet 1 3 6 1 4 1 311 17 2 */ -390, /* OBJ_dcObject 1 3 6 1 4 1 1466 344 */ -91, /* OBJ_bf_cbc 1 3 6 1 4 1 3029 1 2 */ -315, /* OBJ_id_regCtrl_regToken 1 3 6 1 5 5 7 5 1 1 */ -316, /* OBJ_id_regCtrl_authenticator 1 3 6 1 5 5 7 5 1 2 */ -317, /* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */ -318, /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */ -319, /* OBJ_id_regCtrl_oldCertID 1 3 6 1 5 5 7 5 1 5 */ -320, /* OBJ_id_regCtrl_protocolEncrKey 1 3 6 1 5 5 7 5 1 6 */ -321, /* OBJ_id_regInfo_utf8Pairs 1 3 6 1 5 5 7 5 2 1 */ -322, /* OBJ_id_regInfo_certReq 1 3 6 1 5 5 7 5 2 2 */ -365, /* OBJ_id_pkix_OCSP_basic 1 3 6 1 5 5 7 48 1 1 */ -366, /* OBJ_id_pkix_OCSP_Nonce 1 3 6 1 5 5 7 48 1 2 */ -367, /* OBJ_id_pkix_OCSP_CrlID 1 3 6 1 5 5 7 48 1 3 */ -368, /* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */ -369, /* OBJ_id_pkix_OCSP_noCheck 1 3 6 1 5 5 7 48 1 5 */ -370, /* OBJ_id_pkix_OCSP_archiveCutoff 1 3 6 1 5 5 7 48 1 6 */ -371, /* OBJ_id_pkix_OCSP_serviceLocator 1 3 6 1 5 5 7 48 1 7 */ -372, /* OBJ_id_pkix_OCSP_extendedStatus 1 3 6 1 5 5 7 48 1 8 */ -373, /* OBJ_id_pkix_OCSP_valid 1 3 6 1 5 5 7 48 1 9 */ -374, /* OBJ_id_pkix_OCSP_path 1 3 6 1 5 5 7 48 1 10 */ -375, /* OBJ_id_pkix_OCSP_trustRoot 1 3 6 1 5 5 7 48 1 11 */ -921, /* OBJ_brainpoolP160r1 1 3 36 3 3 2 8 1 1 1 */ -922, /* OBJ_brainpoolP160t1 1 3 36 3 3 2 8 1 1 2 */ -923, /* OBJ_brainpoolP192r1 1 3 36 3 3 2 8 1 1 3 */ -924, /* OBJ_brainpoolP192t1 1 3 36 3 3 2 8 1 1 4 */ -925, /* OBJ_brainpoolP224r1 1 3 36 3 3 2 8 1 1 5 */ -926, /* OBJ_brainpoolP224t1 1 3 36 3 3 2 8 1 1 6 */ -927, /* OBJ_brainpoolP256r1 1 3 36 3 3 2 8 1 1 7 */ -928, /* OBJ_brainpoolP256t1 1 3 36 3 3 2 8 1 1 8 */ -929, /* OBJ_brainpoolP320r1 1 3 36 3 3 2 8 1 1 9 */ -930, /* OBJ_brainpoolP320t1 1 3 36 3 3 2 8 1 1 10 */ -931, /* OBJ_brainpoolP384r1 1 3 36 3 3 2 8 1 1 11 */ -932, /* OBJ_brainpoolP384t1 1 3 36 3 3 2 8 1 1 12 */ -933, /* OBJ_brainpoolP512r1 1 3 36 3 3 2 8 1 1 13 */ -934, /* OBJ_brainpoolP512t1 1 3 36 3 3 2 8 1 1 14 */ -936, /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */ -941, /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */ -418, /* OBJ_aes_128_ecb 2 16 840 1 101 3 4 1 1 */ -419, /* OBJ_aes_128_cbc 2 16 840 1 101 3 4 1 2 */ -420, /* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */ -421, /* OBJ_aes_128_cfb128 2 16 840 1 101 3 4 1 4 */ -788, /* OBJ_id_aes128_wrap 2 16 840 1 101 3 4 1 5 */ -895, /* OBJ_aes_128_gcm 2 16 840 1 101 3 4 1 6 */ -896, /* OBJ_aes_128_ccm 2 16 840 1 101 3 4 1 7 */ -897, /* OBJ_id_aes128_wrap_pad 2 16 840 1 101 3 4 1 8 */ -422, /* OBJ_aes_192_ecb 2 16 840 1 101 3 4 1 21 */ -423, /* OBJ_aes_192_cbc 2 16 840 1 101 3 4 1 22 */ -424, /* OBJ_aes_192_ofb128 2 16 840 1 101 3 4 1 23 */ -425, /* OBJ_aes_192_cfb128 2 16 840 1 101 3 4 1 24 */ -789, /* OBJ_id_aes192_wrap 2 16 840 1 101 3 4 1 25 */ -898, /* OBJ_aes_192_gcm 2 16 840 1 101 3 4 1 26 */ -899, /* OBJ_aes_192_ccm 2 16 840 1 101 3 4 1 27 */ -900, /* OBJ_id_aes192_wrap_pad 2 16 840 1 101 3 4 1 28 */ -426, /* OBJ_aes_256_ecb 2 16 840 1 101 3 4 1 41 */ -427, /* OBJ_aes_256_cbc 2 16 840 1 101 3 4 1 42 */ -428, /* OBJ_aes_256_ofb128 2 16 840 1 101 3 4 1 43 */ -429, /* OBJ_aes_256_cfb128 2 16 840 1 101 3 4 1 44 */ -790, /* OBJ_id_aes256_wrap 2 16 840 1 101 3 4 1 45 */ -901, /* OBJ_aes_256_gcm 2 16 840 1 101 3 4 1 46 */ -902, /* OBJ_aes_256_ccm 2 16 840 1 101 3 4 1 47 */ -903, /* OBJ_id_aes256_wrap_pad 2 16 840 1 101 3 4 1 48 */ -672, /* OBJ_sha256 2 16 840 1 101 3 4 2 1 */ -673, /* OBJ_sha384 2 16 840 1 101 3 4 2 2 */ -674, /* OBJ_sha512 2 16 840 1 101 3 4 2 3 */ -675, /* OBJ_sha224 2 16 840 1 101 3 4 2 4 */ -802, /* OBJ_dsa_with_SHA224 2 16 840 1 101 3 4 3 1 */ -803, /* OBJ_dsa_with_SHA256 2 16 840 1 101 3 4 3 2 */ -71, /* OBJ_netscape_cert_type 2 16 840 1 113730 1 1 */ -72, /* OBJ_netscape_base_url 2 16 840 1 113730 1 2 */ -73, /* OBJ_netscape_revocation_url 2 16 840 1 113730 1 3 */ -74, /* OBJ_netscape_ca_revocation_url 2 16 840 1 113730 1 4 */ -75, /* OBJ_netscape_renewal_url 2 16 840 1 113730 1 7 */ -76, /* OBJ_netscape_ca_policy_url 2 16 840 1 113730 1 8 */ -77, /* OBJ_netscape_ssl_server_name 2 16 840 1 113730 1 12 */ -78, /* OBJ_netscape_comment 2 16 840 1 113730 1 13 */ -79, /* OBJ_netscape_cert_sequence 2 16 840 1 113730 2 5 */ -139, /* OBJ_ns_sgc 2 16 840 1 113730 4 1 */ -458, /* OBJ_userId 0 9 2342 19200300 100 1 1 */ -459, /* OBJ_textEncodedORAddress 0 9 2342 19200300 100 1 2 */ -460, /* OBJ_rfc822Mailbox 0 9 2342 19200300 100 1 3 */ -461, /* OBJ_info 0 9 2342 19200300 100 1 4 */ -462, /* OBJ_favouriteDrink 0 9 2342 19200300 100 1 5 */ -463, /* OBJ_roomNumber 0 9 2342 19200300 100 1 6 */ -464, /* OBJ_photo 0 9 2342 19200300 100 1 7 */ -465, /* OBJ_userClass 0 9 2342 19200300 100 1 8 */ -466, /* OBJ_host 0 9 2342 19200300 100 1 9 */ -467, /* OBJ_manager 0 9 2342 19200300 100 1 10 */ -468, /* OBJ_documentIdentifier 0 9 2342 19200300 100 1 11 */ -469, /* OBJ_documentTitle 0 9 2342 19200300 100 1 12 */ -470, /* OBJ_documentVersion 0 9 2342 19200300 100 1 13 */ -471, /* OBJ_documentAuthor 0 9 2342 19200300 100 1 14 */ -472, /* OBJ_documentLocation 0 9 2342 19200300 100 1 15 */ -473, /* OBJ_homeTelephoneNumber 0 9 2342 19200300 100 1 20 */ -474, /* OBJ_secretary 0 9 2342 19200300 100 1 21 */ -475, /* OBJ_otherMailbox 0 9 2342 19200300 100 1 22 */ -476, /* OBJ_lastModifiedTime 0 9 2342 19200300 100 1 23 */ -477, /* OBJ_lastModifiedBy 0 9 2342 19200300 100 1 24 */ -391, /* OBJ_domainComponent 0 9 2342 19200300 100 1 25 */ -478, /* OBJ_aRecord 0 9 2342 19200300 100 1 26 */ -479, /* OBJ_pilotAttributeType27 0 9 2342 19200300 100 1 27 */ -480, /* OBJ_mXRecord 0 9 2342 19200300 100 1 28 */ -481, /* OBJ_nSRecord 0 9 2342 19200300 100 1 29 */ -482, /* OBJ_sOARecord 0 9 2342 19200300 100 1 30 */ -483, /* OBJ_cNAMERecord 0 9 2342 19200300 100 1 31 */ -484, /* OBJ_associatedDomain 0 9 2342 19200300 100 1 37 */ -485, /* OBJ_associatedName 0 9 2342 19200300 100 1 38 */ -486, /* OBJ_homePostalAddress 0 9 2342 19200300 100 1 39 */ -487, /* OBJ_personalTitle 0 9 2342 19200300 100 1 40 */ -488, /* OBJ_mobileTelephoneNumber 0 9 2342 19200300 100 1 41 */ -489, /* OBJ_pagerTelephoneNumber 0 9 2342 19200300 100 1 42 */ -490, /* OBJ_friendlyCountryName 0 9 2342 19200300 100 1 43 */ -491, /* OBJ_organizationalStatus 0 9 2342 19200300 100 1 45 */ -492, /* OBJ_janetMailbox 0 9 2342 19200300 100 1 46 */ -493, /* OBJ_mailPreferenceOption 0 9 2342 19200300 100 1 47 */ -494, /* OBJ_buildingName 0 9 2342 19200300 100 1 48 */ -495, /* OBJ_dSAQuality 0 9 2342 19200300 100 1 49 */ -496, /* OBJ_singleLevelQuality 0 9 2342 19200300 100 1 50 */ -497, /* OBJ_subtreeMinimumQuality 0 9 2342 19200300 100 1 51 */ -498, /* OBJ_subtreeMaximumQuality 0 9 2342 19200300 100 1 52 */ -499, /* OBJ_personalSignature 0 9 2342 19200300 100 1 53 */ -500, /* OBJ_dITRedirect 0 9 2342 19200300 100 1 54 */ -501, /* OBJ_audio 0 9 2342 19200300 100 1 55 */ -502, /* OBJ_documentPublisher 0 9 2342 19200300 100 1 56 */ -442, /* OBJ_iA5StringSyntax 0 9 2342 19200300 100 3 4 */ -443, /* OBJ_caseIgnoreIA5StringSyntax 0 9 2342 19200300 100 3 5 */ -444, /* OBJ_pilotObject 0 9 2342 19200300 100 4 3 */ -445, /* OBJ_pilotPerson 0 9 2342 19200300 100 4 4 */ -446, /* OBJ_account 0 9 2342 19200300 100 4 5 */ -447, /* OBJ_document 0 9 2342 19200300 100 4 6 */ -448, /* OBJ_room 0 9 2342 19200300 100 4 7 */ -449, /* OBJ_documentSeries 0 9 2342 19200300 100 4 9 */ -392, /* OBJ_Domain 0 9 2342 19200300 100 4 13 */ -450, /* OBJ_rFC822localPart 0 9 2342 19200300 100 4 14 */ -451, /* OBJ_dNSDomain 0 9 2342 19200300 100 4 15 */ -452, /* OBJ_domainRelatedObject 0 9 2342 19200300 100 4 17 */ -453, /* OBJ_friendlyCountry 0 9 2342 19200300 100 4 18 */ -454, /* OBJ_simpleSecurityObject 0 9 2342 19200300 100 4 19 */ -455, /* OBJ_pilotOrganization 0 9 2342 19200300 100 4 20 */ -456, /* OBJ_pilotDSA 0 9 2342 19200300 100 4 21 */ -457, /* OBJ_qualityLabelledData 0 9 2342 19200300 100 4 22 */ -189, /* OBJ_id_smime_mod 1 2 840 113549 1 9 16 0 */ -190, /* OBJ_id_smime_ct 1 2 840 113549 1 9 16 1 */ -191, /* OBJ_id_smime_aa 1 2 840 113549 1 9 16 2 */ -192, /* OBJ_id_smime_alg 1 2 840 113549 1 9 16 3 */ -193, /* OBJ_id_smime_cd 1 2 840 113549 1 9 16 4 */ -194, /* OBJ_id_smime_spq 1 2 840 113549 1 9 16 5 */ -195, /* OBJ_id_smime_cti 1 2 840 113549 1 9 16 6 */ -158, /* OBJ_x509Certificate 1 2 840 113549 1 9 22 1 */ -159, /* OBJ_sdsiCertificate 1 2 840 113549 1 9 22 2 */ -160, /* OBJ_x509Crl 1 2 840 113549 1 9 23 1 */ -144, /* OBJ_pbe_WithSHA1And128BitRC4 1 2 840 113549 1 12 1 1 */ -145, /* OBJ_pbe_WithSHA1And40BitRC4 1 2 840 113549 1 12 1 2 */ -146, /* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */ -147, /* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */ -148, /* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */ -149, /* OBJ_pbe_WithSHA1And40BitRC2_CBC 1 2 840 113549 1 12 1 6 */ -171, /* OBJ_ms_ext_req 1 3 6 1 4 1 311 2 1 14 */ -134, /* OBJ_ms_code_ind 1 3 6 1 4 1 311 2 1 21 */ -135, /* OBJ_ms_code_com 1 3 6 1 4 1 311 2 1 22 */ -136, /* OBJ_ms_ctl_sign 1 3 6 1 4 1 311 10 3 1 */ -137, /* OBJ_ms_sgc 1 3 6 1 4 1 311 10 3 3 */ -138, /* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ -648, /* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ -649, /* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ -951, /* OBJ_ct_precert_scts 1 3 6 1 4 1 11129 2 4 2 */ -952, /* OBJ_ct_precert_poison 1 3 6 1 4 1 11129 2 4 3 */ -953, /* OBJ_ct_precert_signer 1 3 6 1 4 1 11129 2 4 4 */ -954, /* OBJ_ct_cert_scts 1 3 6 1 4 1 11129 2 4 5 */ -751, /* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */ -752, /* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */ -753, /* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */ -907, /* OBJ_id_camellia128_wrap 1 2 392 200011 61 1 1 3 2 */ -908, /* OBJ_id_camellia192_wrap 1 2 392 200011 61 1 1 3 3 */ -909, /* OBJ_id_camellia256_wrap 1 2 392 200011 61 1 1 3 4 */ -196, /* OBJ_id_smime_mod_cms 1 2 840 113549 1 9 16 0 1 */ -197, /* OBJ_id_smime_mod_ess 1 2 840 113549 1 9 16 0 2 */ -198, /* OBJ_id_smime_mod_oid 1 2 840 113549 1 9 16 0 3 */ -199, /* OBJ_id_smime_mod_msg_v3 1 2 840 113549 1 9 16 0 4 */ -200, /* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */ -201, /* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */ -202, /* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */ -203, /* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */ -204, /* OBJ_id_smime_ct_receipt 1 2 840 113549 1 9 16 1 1 */ -205, /* OBJ_id_smime_ct_authData 1 2 840 113549 1 9 16 1 2 */ -206, /* OBJ_id_smime_ct_publishCert 1 2 840 113549 1 9 16 1 3 */ -207, /* OBJ_id_smime_ct_TSTInfo 1 2 840 113549 1 9 16 1 4 */ -208, /* OBJ_id_smime_ct_TDTInfo 1 2 840 113549 1 9 16 1 5 */ -209, /* OBJ_id_smime_ct_contentInfo 1 2 840 113549 1 9 16 1 6 */ -210, /* OBJ_id_smime_ct_DVCSRequestData 1 2 840 113549 1 9 16 1 7 */ -211, /* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */ -786, /* OBJ_id_smime_ct_compressedData 1 2 840 113549 1 9 16 1 9 */ -787, /* OBJ_id_ct_asciiTextWithCRLF 1 2 840 113549 1 9 16 1 27 */ -212, /* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ -213, /* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ -214, /* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ -215, /* OBJ_id_smime_aa_contentHint 1 2 840 113549 1 9 16 2 4 */ -216, /* OBJ_id_smime_aa_msgSigDigest 1 2 840 113549 1 9 16 2 5 */ -217, /* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */ -218, /* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */ -219, /* OBJ_id_smime_aa_macValue 1 2 840 113549 1 9 16 2 8 */ -220, /* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */ -221, /* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */ -222, /* OBJ_id_smime_aa_encrypKeyPref 1 2 840 113549 1 9 16 2 11 */ -223, /* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */ -224, /* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */ -225, /* OBJ_id_smime_aa_timeStampToken 1 2 840 113549 1 9 16 2 14 */ -226, /* OBJ_id_smime_aa_ets_sigPolicyId 1 2 840 113549 1 9 16 2 15 */ -227, /* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */ -228, /* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */ -229, /* OBJ_id_smime_aa_ets_signerAttr 1 2 840 113549 1 9 16 2 18 */ -230, /* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */ -231, /* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */ -232, /* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */ -233, /* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */ -234, /* OBJ_id_smime_aa_ets_certValues 1 2 840 113549 1 9 16 2 23 */ -235, /* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */ -236, /* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */ -237, /* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */ -238, /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */ -239, /* OBJ_id_smime_aa_signatureType 1 2 840 113549 1 9 16 2 28 */ -240, /* OBJ_id_smime_aa_dvcs_dvc 1 2 840 113549 1 9 16 2 29 */ -241, /* OBJ_id_smime_alg_ESDHwith3DES 1 2 840 113549 1 9 16 3 1 */ -242, /* OBJ_id_smime_alg_ESDHwithRC2 1 2 840 113549 1 9 16 3 2 */ -243, /* OBJ_id_smime_alg_3DESwrap 1 2 840 113549 1 9 16 3 3 */ -244, /* OBJ_id_smime_alg_RC2wrap 1 2 840 113549 1 9 16 3 4 */ -245, /* OBJ_id_smime_alg_ESDH 1 2 840 113549 1 9 16 3 5 */ -246, /* OBJ_id_smime_alg_CMS3DESwrap 1 2 840 113549 1 9 16 3 6 */ -247, /* OBJ_id_smime_alg_CMSRC2wrap 1 2 840 113549 1 9 16 3 7 */ -125, /* OBJ_zlib_compression 1 2 840 113549 1 9 16 3 8 */ -893, /* OBJ_id_alg_PWRI_KEK 1 2 840 113549 1 9 16 3 9 */ -248, /* OBJ_id_smime_cd_ldap 1 2 840 113549 1 9 16 4 1 */ -249, /* OBJ_id_smime_spq_ets_sqt_uri 1 2 840 113549 1 9 16 5 1 */ -250, /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */ -251, /* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */ -252, /* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */ -253, /* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */ -254, /* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */ -255, /* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */ -256, /* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */ -150, /* OBJ_keyBag 1 2 840 113549 1 12 10 1 1 */ -151, /* OBJ_pkcs8ShroudedKeyBag 1 2 840 113549 1 12 10 1 2 */ -152, /* OBJ_certBag 1 2 840 113549 1 12 10 1 3 */ -153, /* OBJ_crlBag 1 2 840 113549 1 12 10 1 4 */ -154, /* OBJ_secretBag 1 2 840 113549 1 12 10 1 5 */ -155, /* OBJ_safeContentsBag 1 2 840 113549 1 12 10 1 6 */ -34, /* OBJ_idea_cbc 1 3 6 1 4 1 188 7 1 1 2 */ -955, /* OBJ_jurisdictionLocalityName 1 3 6 1 4 1 311 60 2 1 1 */ -956, /* OBJ_jurisdictionStateOrProvinceName 1 3 6 1 4 1 311 60 2 1 2 */ -957, /* OBJ_jurisdictionCountryName 1 3 6 1 4 1 311 60 2 1 3 */ -}; - diff --git a/Sources/COpenSSL/obj_mac.h b/Sources/COpenSSL/obj_mac.h deleted file mode 100644 index 779c309b..00000000 --- a/Sources/COpenSSL/obj_mac.h +++ /dev/null @@ -1,4194 +0,0 @@ -/* crypto/objects/obj_mac.h */ - -/* - * THIS FILE IS GENERATED FROM objects.txt by objects.pl via the following - * command: perl objects.pl objects.txt obj_mac.num obj_mac.h - */ - -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#define SN_undef "UNDEF" -#define LN_undef "undefined" -#define NID_undef 0 -#define OBJ_undef 0L - -#define SN_itu_t "ITU-T" -#define LN_itu_t "itu-t" -#define NID_itu_t 645 -#define OBJ_itu_t 0L - -#define NID_ccitt 404 -#define OBJ_ccitt OBJ_itu_t - -#define SN_iso "ISO" -#define LN_iso "iso" -#define NID_iso 181 -#define OBJ_iso 1L - -#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" -#define LN_joint_iso_itu_t "joint-iso-itu-t" -#define NID_joint_iso_itu_t 646 -#define OBJ_joint_iso_itu_t 2L - -#define NID_joint_iso_ccitt 393 -#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t - -#define SN_member_body "member-body" -#define LN_member_body "ISO Member Body" -#define NID_member_body 182 -#define OBJ_member_body OBJ_iso,2L - -#define SN_identified_organization "identified-organization" -#define NID_identified_organization 676 -#define OBJ_identified_organization OBJ_iso,3L - -#define SN_hmac_md5 "HMAC-MD5" -#define LN_hmac_md5 "hmac-md5" -#define NID_hmac_md5 780 -#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L - -#define SN_hmac_sha1 "HMAC-SHA1" -#define LN_hmac_sha1 "hmac-sha1" -#define NID_hmac_sha1 781 -#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L - -#define SN_certicom_arc "certicom-arc" -#define NID_certicom_arc 677 -#define OBJ_certicom_arc OBJ_identified_organization,132L - -#define SN_international_organizations "international-organizations" -#define LN_international_organizations "International Organizations" -#define NID_international_organizations 647 -#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L - -#define SN_wap "wap" -#define NID_wap 678 -#define OBJ_wap OBJ_international_organizations,43L - -#define SN_wap_wsg "wap-wsg" -#define NID_wap_wsg 679 -#define OBJ_wap_wsg OBJ_wap,1L - -#define SN_selected_attribute_types "selected-attribute-types" -#define LN_selected_attribute_types "Selected Attribute Types" -#define NID_selected_attribute_types 394 -#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L - -#define SN_clearance "clearance" -#define NID_clearance 395 -#define OBJ_clearance OBJ_selected_attribute_types,55L - -#define SN_ISO_US "ISO-US" -#define LN_ISO_US "ISO US Member Body" -#define NID_ISO_US 183 -#define OBJ_ISO_US OBJ_member_body,840L - -#define SN_X9_57 "X9-57" -#define LN_X9_57 "X9.57" -#define NID_X9_57 184 -#define OBJ_X9_57 OBJ_ISO_US,10040L - -#define SN_X9cm "X9cm" -#define LN_X9cm "X9.57 CM ?" -#define NID_X9cm 185 -#define OBJ_X9cm OBJ_X9_57,4L - -#define SN_dsa "DSA" -#define LN_dsa "dsaEncryption" -#define NID_dsa 116 -#define OBJ_dsa OBJ_X9cm,1L - -#define SN_dsaWithSHA1 "DSA-SHA1" -#define LN_dsaWithSHA1 "dsaWithSHA1" -#define NID_dsaWithSHA1 113 -#define OBJ_dsaWithSHA1 OBJ_X9cm,3L - -#define SN_ansi_X9_62 "ansi-X9-62" -#define LN_ansi_X9_62 "ANSI X9.62" -#define NID_ansi_X9_62 405 -#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L - -#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L - -#define SN_X9_62_prime_field "prime-field" -#define NID_X9_62_prime_field 406 -#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L - -#define SN_X9_62_characteristic_two_field "characteristic-two-field" -#define NID_X9_62_characteristic_two_field 407 -#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L - -#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" -#define NID_X9_62_id_characteristic_two_basis 680 -#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L - -#define SN_X9_62_onBasis "onBasis" -#define NID_X9_62_onBasis 681 -#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L - -#define SN_X9_62_tpBasis "tpBasis" -#define NID_X9_62_tpBasis 682 -#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L - -#define SN_X9_62_ppBasis "ppBasis" -#define NID_X9_62_ppBasis 683 -#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L - -#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L - -#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" -#define NID_X9_62_id_ecPublicKey 408 -#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L - -#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L - -#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L - -#define SN_X9_62_c2pnb163v1 "c2pnb163v1" -#define NID_X9_62_c2pnb163v1 684 -#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L - -#define SN_X9_62_c2pnb163v2 "c2pnb163v2" -#define NID_X9_62_c2pnb163v2 685 -#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L - -#define SN_X9_62_c2pnb163v3 "c2pnb163v3" -#define NID_X9_62_c2pnb163v3 686 -#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L - -#define SN_X9_62_c2pnb176v1 "c2pnb176v1" -#define NID_X9_62_c2pnb176v1 687 -#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L - -#define SN_X9_62_c2tnb191v1 "c2tnb191v1" -#define NID_X9_62_c2tnb191v1 688 -#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L - -#define SN_X9_62_c2tnb191v2 "c2tnb191v2" -#define NID_X9_62_c2tnb191v2 689 -#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L - -#define SN_X9_62_c2tnb191v3 "c2tnb191v3" -#define NID_X9_62_c2tnb191v3 690 -#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L - -#define SN_X9_62_c2onb191v4 "c2onb191v4" -#define NID_X9_62_c2onb191v4 691 -#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L - -#define SN_X9_62_c2onb191v5 "c2onb191v5" -#define NID_X9_62_c2onb191v5 692 -#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L - -#define SN_X9_62_c2pnb208w1 "c2pnb208w1" -#define NID_X9_62_c2pnb208w1 693 -#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L - -#define SN_X9_62_c2tnb239v1 "c2tnb239v1" -#define NID_X9_62_c2tnb239v1 694 -#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L - -#define SN_X9_62_c2tnb239v2 "c2tnb239v2" -#define NID_X9_62_c2tnb239v2 695 -#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L - -#define SN_X9_62_c2tnb239v3 "c2tnb239v3" -#define NID_X9_62_c2tnb239v3 696 -#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L - -#define SN_X9_62_c2onb239v4 "c2onb239v4" -#define NID_X9_62_c2onb239v4 697 -#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L - -#define SN_X9_62_c2onb239v5 "c2onb239v5" -#define NID_X9_62_c2onb239v5 698 -#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L - -#define SN_X9_62_c2pnb272w1 "c2pnb272w1" -#define NID_X9_62_c2pnb272w1 699 -#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L - -#define SN_X9_62_c2pnb304w1 "c2pnb304w1" -#define NID_X9_62_c2pnb304w1 700 -#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L - -#define SN_X9_62_c2tnb359v1 "c2tnb359v1" -#define NID_X9_62_c2tnb359v1 701 -#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L - -#define SN_X9_62_c2pnb368w1 "c2pnb368w1" -#define NID_X9_62_c2pnb368w1 702 -#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L - -#define SN_X9_62_c2tnb431r1 "c2tnb431r1" -#define NID_X9_62_c2tnb431r1 703 -#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L - -#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L - -#define SN_X9_62_prime192v1 "prime192v1" -#define NID_X9_62_prime192v1 409 -#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L - -#define SN_X9_62_prime192v2 "prime192v2" -#define NID_X9_62_prime192v2 410 -#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L - -#define SN_X9_62_prime192v3 "prime192v3" -#define NID_X9_62_prime192v3 411 -#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L - -#define SN_X9_62_prime239v1 "prime239v1" -#define NID_X9_62_prime239v1 412 -#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L - -#define SN_X9_62_prime239v2 "prime239v2" -#define NID_X9_62_prime239v2 413 -#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L - -#define SN_X9_62_prime239v3 "prime239v3" -#define NID_X9_62_prime239v3 414 -#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L - -#define SN_X9_62_prime256v1 "prime256v1" -#define NID_X9_62_prime256v1 415 -#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L - -#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L - -#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" -#define NID_ecdsa_with_SHA1 416 -#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L - -#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" -#define NID_ecdsa_with_Recommended 791 -#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L - -#define SN_ecdsa_with_Specified "ecdsa-with-Specified" -#define NID_ecdsa_with_Specified 792 -#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L - -#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" -#define NID_ecdsa_with_SHA224 793 -#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L - -#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" -#define NID_ecdsa_with_SHA256 794 -#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L - -#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" -#define NID_ecdsa_with_SHA384 795 -#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L - -#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" -#define NID_ecdsa_with_SHA512 796 -#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L - -#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L - -#define SN_secp112r1 "secp112r1" -#define NID_secp112r1 704 -#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L - -#define SN_secp112r2 "secp112r2" -#define NID_secp112r2 705 -#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L - -#define SN_secp128r1 "secp128r1" -#define NID_secp128r1 706 -#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L - -#define SN_secp128r2 "secp128r2" -#define NID_secp128r2 707 -#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L - -#define SN_secp160k1 "secp160k1" -#define NID_secp160k1 708 -#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L - -#define SN_secp160r1 "secp160r1" -#define NID_secp160r1 709 -#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L - -#define SN_secp160r2 "secp160r2" -#define NID_secp160r2 710 -#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L - -#define SN_secp192k1 "secp192k1" -#define NID_secp192k1 711 -#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L - -#define SN_secp224k1 "secp224k1" -#define NID_secp224k1 712 -#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L - -#define SN_secp224r1 "secp224r1" -#define NID_secp224r1 713 -#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L - -#define SN_secp256k1 "secp256k1" -#define NID_secp256k1 714 -#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L - -#define SN_secp384r1 "secp384r1" -#define NID_secp384r1 715 -#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L - -#define SN_secp521r1 "secp521r1" -#define NID_secp521r1 716 -#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L - -#define SN_sect113r1 "sect113r1" -#define NID_sect113r1 717 -#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L - -#define SN_sect113r2 "sect113r2" -#define NID_sect113r2 718 -#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L - -#define SN_sect131r1 "sect131r1" -#define NID_sect131r1 719 -#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L - -#define SN_sect131r2 "sect131r2" -#define NID_sect131r2 720 -#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L - -#define SN_sect163k1 "sect163k1" -#define NID_sect163k1 721 -#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L - -#define SN_sect163r1 "sect163r1" -#define NID_sect163r1 722 -#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L - -#define SN_sect163r2 "sect163r2" -#define NID_sect163r2 723 -#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L - -#define SN_sect193r1 "sect193r1" -#define NID_sect193r1 724 -#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L - -#define SN_sect193r2 "sect193r2" -#define NID_sect193r2 725 -#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L - -#define SN_sect233k1 "sect233k1" -#define NID_sect233k1 726 -#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L - -#define SN_sect233r1 "sect233r1" -#define NID_sect233r1 727 -#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L - -#define SN_sect239k1 "sect239k1" -#define NID_sect239k1 728 -#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L - -#define SN_sect283k1 "sect283k1" -#define NID_sect283k1 729 -#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L - -#define SN_sect283r1 "sect283r1" -#define NID_sect283r1 730 -#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L - -#define SN_sect409k1 "sect409k1" -#define NID_sect409k1 731 -#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L - -#define SN_sect409r1 "sect409r1" -#define NID_sect409r1 732 -#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L - -#define SN_sect571k1 "sect571k1" -#define NID_sect571k1 733 -#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L - -#define SN_sect571r1 "sect571r1" -#define NID_sect571r1 734 -#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L - -#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L - -#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" -#define NID_wap_wsg_idm_ecid_wtls1 735 -#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L - -#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" -#define NID_wap_wsg_idm_ecid_wtls3 736 -#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L - -#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" -#define NID_wap_wsg_idm_ecid_wtls4 737 -#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L - -#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" -#define NID_wap_wsg_idm_ecid_wtls5 738 -#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L - -#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" -#define NID_wap_wsg_idm_ecid_wtls6 739 -#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L - -#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" -#define NID_wap_wsg_idm_ecid_wtls7 740 -#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L - -#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" -#define NID_wap_wsg_idm_ecid_wtls8 741 -#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L - -#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" -#define NID_wap_wsg_idm_ecid_wtls9 742 -#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L - -#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" -#define NID_wap_wsg_idm_ecid_wtls10 743 -#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L - -#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" -#define NID_wap_wsg_idm_ecid_wtls11 744 -#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L - -#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" -#define NID_wap_wsg_idm_ecid_wtls12 745 -#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L - -#define SN_cast5_cbc "CAST5-CBC" -#define LN_cast5_cbc "cast5-cbc" -#define NID_cast5_cbc 108 -#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L - -#define SN_cast5_ecb "CAST5-ECB" -#define LN_cast5_ecb "cast5-ecb" -#define NID_cast5_ecb 109 - -#define SN_cast5_cfb64 "CAST5-CFB" -#define LN_cast5_cfb64 "cast5-cfb" -#define NID_cast5_cfb64 110 - -#define SN_cast5_ofb64 "CAST5-OFB" -#define LN_cast5_ofb64 "cast5-ofb" -#define NID_cast5_ofb64 111 - -#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" -#define NID_pbeWithMD5AndCast5_CBC 112 -#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L - -#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" -#define LN_id_PasswordBasedMAC "password based MAC" -#define NID_id_PasswordBasedMAC 782 -#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L - -#define SN_id_DHBasedMac "id-DHBasedMac" -#define LN_id_DHBasedMac "Diffie-Hellman based MAC" -#define NID_id_DHBasedMac 783 -#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L - -#define SN_rsadsi "rsadsi" -#define LN_rsadsi "RSA Data Security, Inc." -#define NID_rsadsi 1 -#define OBJ_rsadsi OBJ_ISO_US,113549L - -#define SN_pkcs "pkcs" -#define LN_pkcs "RSA Data Security, Inc. PKCS" -#define NID_pkcs 2 -#define OBJ_pkcs OBJ_rsadsi,1L - -#define SN_pkcs1 "pkcs1" -#define NID_pkcs1 186 -#define OBJ_pkcs1 OBJ_pkcs,1L - -#define LN_rsaEncryption "rsaEncryption" -#define NID_rsaEncryption 6 -#define OBJ_rsaEncryption OBJ_pkcs1,1L - -#define SN_md2WithRSAEncryption "RSA-MD2" -#define LN_md2WithRSAEncryption "md2WithRSAEncryption" -#define NID_md2WithRSAEncryption 7 -#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L - -#define SN_md4WithRSAEncryption "RSA-MD4" -#define LN_md4WithRSAEncryption "md4WithRSAEncryption" -#define NID_md4WithRSAEncryption 396 -#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L - -#define SN_md5WithRSAEncryption "RSA-MD5" -#define LN_md5WithRSAEncryption "md5WithRSAEncryption" -#define NID_md5WithRSAEncryption 8 -#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L - -#define SN_sha1WithRSAEncryption "RSA-SHA1" -#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" -#define NID_sha1WithRSAEncryption 65 -#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L - -#define SN_rsaesOaep "RSAES-OAEP" -#define LN_rsaesOaep "rsaesOaep" -#define NID_rsaesOaep 919 -#define OBJ_rsaesOaep OBJ_pkcs1,7L - -#define SN_mgf1 "MGF1" -#define LN_mgf1 "mgf1" -#define NID_mgf1 911 -#define OBJ_mgf1 OBJ_pkcs1,8L - -#define SN_pSpecified "PSPECIFIED" -#define LN_pSpecified "pSpecified" -#define NID_pSpecified 935 -#define OBJ_pSpecified OBJ_pkcs1,9L - -#define SN_rsassaPss "RSASSA-PSS" -#define LN_rsassaPss "rsassaPss" -#define NID_rsassaPss 912 -#define OBJ_rsassaPss OBJ_pkcs1,10L - -#define SN_sha256WithRSAEncryption "RSA-SHA256" -#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" -#define NID_sha256WithRSAEncryption 668 -#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L - -#define SN_sha384WithRSAEncryption "RSA-SHA384" -#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" -#define NID_sha384WithRSAEncryption 669 -#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L - -#define SN_sha512WithRSAEncryption "RSA-SHA512" -#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" -#define NID_sha512WithRSAEncryption 670 -#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L - -#define SN_sha224WithRSAEncryption "RSA-SHA224" -#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" -#define NID_sha224WithRSAEncryption 671 -#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L - -#define SN_pkcs3 "pkcs3" -#define NID_pkcs3 27 -#define OBJ_pkcs3 OBJ_pkcs,3L - -#define LN_dhKeyAgreement "dhKeyAgreement" -#define NID_dhKeyAgreement 28 -#define OBJ_dhKeyAgreement OBJ_pkcs3,1L - -#define SN_pkcs5 "pkcs5" -#define NID_pkcs5 187 -#define OBJ_pkcs5 OBJ_pkcs,5L - -#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" -#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" -#define NID_pbeWithMD2AndDES_CBC 9 -#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L - -#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" -#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" -#define NID_pbeWithMD5AndDES_CBC 10 -#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L - -#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" -#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" -#define NID_pbeWithMD2AndRC2_CBC 168 -#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L - -#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" -#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" -#define NID_pbeWithMD5AndRC2_CBC 169 -#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L - -#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" -#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" -#define NID_pbeWithSHA1AndDES_CBC 170 -#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L - -#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" -#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" -#define NID_pbeWithSHA1AndRC2_CBC 68 -#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L - -#define LN_id_pbkdf2 "PBKDF2" -#define NID_id_pbkdf2 69 -#define OBJ_id_pbkdf2 OBJ_pkcs5,12L - -#define LN_pbes2 "PBES2" -#define NID_pbes2 161 -#define OBJ_pbes2 OBJ_pkcs5,13L - -#define LN_pbmac1 "PBMAC1" -#define NID_pbmac1 162 -#define OBJ_pbmac1 OBJ_pkcs5,14L - -#define SN_pkcs7 "pkcs7" -#define NID_pkcs7 20 -#define OBJ_pkcs7 OBJ_pkcs,7L - -#define LN_pkcs7_data "pkcs7-data" -#define NID_pkcs7_data 21 -#define OBJ_pkcs7_data OBJ_pkcs7,1L - -#define LN_pkcs7_signed "pkcs7-signedData" -#define NID_pkcs7_signed 22 -#define OBJ_pkcs7_signed OBJ_pkcs7,2L - -#define LN_pkcs7_enveloped "pkcs7-envelopedData" -#define NID_pkcs7_enveloped 23 -#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L - -#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" -#define NID_pkcs7_signedAndEnveloped 24 -#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L - -#define LN_pkcs7_digest "pkcs7-digestData" -#define NID_pkcs7_digest 25 -#define OBJ_pkcs7_digest OBJ_pkcs7,5L - -#define LN_pkcs7_encrypted "pkcs7-encryptedData" -#define NID_pkcs7_encrypted 26 -#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L - -#define SN_pkcs9 "pkcs9" -#define NID_pkcs9 47 -#define OBJ_pkcs9 OBJ_pkcs,9L - -#define LN_pkcs9_emailAddress "emailAddress" -#define NID_pkcs9_emailAddress 48 -#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L - -#define LN_pkcs9_unstructuredName "unstructuredName" -#define NID_pkcs9_unstructuredName 49 -#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L - -#define LN_pkcs9_contentType "contentType" -#define NID_pkcs9_contentType 50 -#define OBJ_pkcs9_contentType OBJ_pkcs9,3L - -#define LN_pkcs9_messageDigest "messageDigest" -#define NID_pkcs9_messageDigest 51 -#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L - -#define LN_pkcs9_signingTime "signingTime" -#define NID_pkcs9_signingTime 52 -#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L - -#define LN_pkcs9_countersignature "countersignature" -#define NID_pkcs9_countersignature 53 -#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L - -#define LN_pkcs9_challengePassword "challengePassword" -#define NID_pkcs9_challengePassword 54 -#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L - -#define LN_pkcs9_unstructuredAddress "unstructuredAddress" -#define NID_pkcs9_unstructuredAddress 55 -#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L - -#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" -#define NID_pkcs9_extCertAttributes 56 -#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L - -#define SN_ext_req "extReq" -#define LN_ext_req "Extension Request" -#define NID_ext_req 172 -#define OBJ_ext_req OBJ_pkcs9,14L - -#define SN_SMIMECapabilities "SMIME-CAPS" -#define LN_SMIMECapabilities "S/MIME Capabilities" -#define NID_SMIMECapabilities 167 -#define OBJ_SMIMECapabilities OBJ_pkcs9,15L - -#define SN_SMIME "SMIME" -#define LN_SMIME "S/MIME" -#define NID_SMIME 188 -#define OBJ_SMIME OBJ_pkcs9,16L - -#define SN_id_smime_mod "id-smime-mod" -#define NID_id_smime_mod 189 -#define OBJ_id_smime_mod OBJ_SMIME,0L - -#define SN_id_smime_ct "id-smime-ct" -#define NID_id_smime_ct 190 -#define OBJ_id_smime_ct OBJ_SMIME,1L - -#define SN_id_smime_aa "id-smime-aa" -#define NID_id_smime_aa 191 -#define OBJ_id_smime_aa OBJ_SMIME,2L - -#define SN_id_smime_alg "id-smime-alg" -#define NID_id_smime_alg 192 -#define OBJ_id_smime_alg OBJ_SMIME,3L - -#define SN_id_smime_cd "id-smime-cd" -#define NID_id_smime_cd 193 -#define OBJ_id_smime_cd OBJ_SMIME,4L - -#define SN_id_smime_spq "id-smime-spq" -#define NID_id_smime_spq 194 -#define OBJ_id_smime_spq OBJ_SMIME,5L - -#define SN_id_smime_cti "id-smime-cti" -#define NID_id_smime_cti 195 -#define OBJ_id_smime_cti OBJ_SMIME,6L - -#define SN_id_smime_mod_cms "id-smime-mod-cms" -#define NID_id_smime_mod_cms 196 -#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L - -#define SN_id_smime_mod_ess "id-smime-mod-ess" -#define NID_id_smime_mod_ess 197 -#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L - -#define SN_id_smime_mod_oid "id-smime-mod-oid" -#define NID_id_smime_mod_oid 198 -#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L - -#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" -#define NID_id_smime_mod_msg_v3 199 -#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L - -#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" -#define NID_id_smime_mod_ets_eSignature_88 200 -#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L - -#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" -#define NID_id_smime_mod_ets_eSignature_97 201 -#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L - -#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" -#define NID_id_smime_mod_ets_eSigPolicy_88 202 -#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L - -#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" -#define NID_id_smime_mod_ets_eSigPolicy_97 203 -#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L - -#define SN_id_smime_ct_receipt "id-smime-ct-receipt" -#define NID_id_smime_ct_receipt 204 -#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L - -#define SN_id_smime_ct_authData "id-smime-ct-authData" -#define NID_id_smime_ct_authData 205 -#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L - -#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" -#define NID_id_smime_ct_publishCert 206 -#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L - -#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" -#define NID_id_smime_ct_TSTInfo 207 -#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L - -#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" -#define NID_id_smime_ct_TDTInfo 208 -#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L - -#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" -#define NID_id_smime_ct_contentInfo 209 -#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L - -#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" -#define NID_id_smime_ct_DVCSRequestData 210 -#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L - -#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" -#define NID_id_smime_ct_DVCSResponseData 211 -#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L - -#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" -#define NID_id_smime_ct_compressedData 786 -#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L - -#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" -#define NID_id_ct_asciiTextWithCRLF 787 -#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L - -#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" -#define NID_id_smime_aa_receiptRequest 212 -#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L - -#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" -#define NID_id_smime_aa_securityLabel 213 -#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L - -#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" -#define NID_id_smime_aa_mlExpandHistory 214 -#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L - -#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" -#define NID_id_smime_aa_contentHint 215 -#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L - -#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" -#define NID_id_smime_aa_msgSigDigest 216 -#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L - -#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" -#define NID_id_smime_aa_encapContentType 217 -#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L - -#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" -#define NID_id_smime_aa_contentIdentifier 218 -#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L - -#define SN_id_smime_aa_macValue "id-smime-aa-macValue" -#define NID_id_smime_aa_macValue 219 -#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L - -#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" -#define NID_id_smime_aa_equivalentLabels 220 -#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L - -#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" -#define NID_id_smime_aa_contentReference 221 -#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L - -#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" -#define NID_id_smime_aa_encrypKeyPref 222 -#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L - -#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" -#define NID_id_smime_aa_signingCertificate 223 -#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L - -#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" -#define NID_id_smime_aa_smimeEncryptCerts 224 -#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L - -#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" -#define NID_id_smime_aa_timeStampToken 225 -#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L - -#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" -#define NID_id_smime_aa_ets_sigPolicyId 226 -#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L - -#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" -#define NID_id_smime_aa_ets_commitmentType 227 -#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L - -#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" -#define NID_id_smime_aa_ets_signerLocation 228 -#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L - -#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" -#define NID_id_smime_aa_ets_signerAttr 229 -#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L - -#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" -#define NID_id_smime_aa_ets_otherSigCert 230 -#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L - -#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" -#define NID_id_smime_aa_ets_contentTimestamp 231 -#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L - -#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" -#define NID_id_smime_aa_ets_CertificateRefs 232 -#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L - -#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" -#define NID_id_smime_aa_ets_RevocationRefs 233 -#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L - -#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" -#define NID_id_smime_aa_ets_certValues 234 -#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L - -#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" -#define NID_id_smime_aa_ets_revocationValues 235 -#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L - -#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" -#define NID_id_smime_aa_ets_escTimeStamp 236 -#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L - -#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" -#define NID_id_smime_aa_ets_certCRLTimestamp 237 -#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L - -#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" -#define NID_id_smime_aa_ets_archiveTimeStamp 238 -#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L - -#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" -#define NID_id_smime_aa_signatureType 239 -#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L - -#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" -#define NID_id_smime_aa_dvcs_dvc 240 -#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L - -#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" -#define NID_id_smime_alg_ESDHwith3DES 241 -#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L - -#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" -#define NID_id_smime_alg_ESDHwithRC2 242 -#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L - -#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" -#define NID_id_smime_alg_3DESwrap 243 -#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L - -#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" -#define NID_id_smime_alg_RC2wrap 244 -#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L - -#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" -#define NID_id_smime_alg_ESDH 245 -#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L - -#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" -#define NID_id_smime_alg_CMS3DESwrap 246 -#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L - -#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" -#define NID_id_smime_alg_CMSRC2wrap 247 -#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L - -#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" -#define NID_id_alg_PWRI_KEK 893 -#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L - -#define SN_id_smime_cd_ldap "id-smime-cd-ldap" -#define NID_id_smime_cd_ldap 248 -#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L - -#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" -#define NID_id_smime_spq_ets_sqt_uri 249 -#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L - -#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" -#define NID_id_smime_spq_ets_sqt_unotice 250 -#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L - -#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" -#define NID_id_smime_cti_ets_proofOfOrigin 251 -#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L - -#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" -#define NID_id_smime_cti_ets_proofOfReceipt 252 -#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L - -#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" -#define NID_id_smime_cti_ets_proofOfDelivery 253 -#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L - -#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" -#define NID_id_smime_cti_ets_proofOfSender 254 -#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L - -#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" -#define NID_id_smime_cti_ets_proofOfApproval 255 -#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L - -#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" -#define NID_id_smime_cti_ets_proofOfCreation 256 -#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L - -#define LN_friendlyName "friendlyName" -#define NID_friendlyName 156 -#define OBJ_friendlyName OBJ_pkcs9,20L - -#define LN_localKeyID "localKeyID" -#define NID_localKeyID 157 -#define OBJ_localKeyID OBJ_pkcs9,21L - -#define SN_ms_csp_name "CSPName" -#define LN_ms_csp_name "Microsoft CSP Name" -#define NID_ms_csp_name 417 -#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L - -#define SN_LocalKeySet "LocalKeySet" -#define LN_LocalKeySet "Microsoft Local Key set" -#define NID_LocalKeySet 856 -#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L - -#define OBJ_certTypes OBJ_pkcs9,22L - -#define LN_x509Certificate "x509Certificate" -#define NID_x509Certificate 158 -#define OBJ_x509Certificate OBJ_certTypes,1L - -#define LN_sdsiCertificate "sdsiCertificate" -#define NID_sdsiCertificate 159 -#define OBJ_sdsiCertificate OBJ_certTypes,2L - -#define OBJ_crlTypes OBJ_pkcs9,23L - -#define LN_x509Crl "x509Crl" -#define NID_x509Crl 160 -#define OBJ_x509Crl OBJ_crlTypes,1L - -#define OBJ_pkcs12 OBJ_pkcs,12L - -#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L - -#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" -#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" -#define NID_pbe_WithSHA1And128BitRC4 144 -#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L - -#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" -#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" -#define NID_pbe_WithSHA1And40BitRC4 145 -#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L - -#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" -#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" -#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 -#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L - -#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" -#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" -#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 -#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L - -#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" -#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" -#define NID_pbe_WithSHA1And128BitRC2_CBC 148 -#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L - -#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" -#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" -#define NID_pbe_WithSHA1And40BitRC2_CBC 149 -#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L - -#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L - -#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L - -#define LN_keyBag "keyBag" -#define NID_keyBag 150 -#define OBJ_keyBag OBJ_pkcs12_BagIds,1L - -#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" -#define NID_pkcs8ShroudedKeyBag 151 -#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L - -#define LN_certBag "certBag" -#define NID_certBag 152 -#define OBJ_certBag OBJ_pkcs12_BagIds,3L - -#define LN_crlBag "crlBag" -#define NID_crlBag 153 -#define OBJ_crlBag OBJ_pkcs12_BagIds,4L - -#define LN_secretBag "secretBag" -#define NID_secretBag 154 -#define OBJ_secretBag OBJ_pkcs12_BagIds,5L - -#define LN_safeContentsBag "safeContentsBag" -#define NID_safeContentsBag 155 -#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L - -#define SN_md2 "MD2" -#define LN_md2 "md2" -#define NID_md2 3 -#define OBJ_md2 OBJ_rsadsi,2L,2L - -#define SN_md4 "MD4" -#define LN_md4 "md4" -#define NID_md4 257 -#define OBJ_md4 OBJ_rsadsi,2L,4L - -#define SN_md5 "MD5" -#define LN_md5 "md5" -#define NID_md5 4 -#define OBJ_md5 OBJ_rsadsi,2L,5L - -#define SN_md5_sha1 "MD5-SHA1" -#define LN_md5_sha1 "md5-sha1" -#define NID_md5_sha1 114 - -#define LN_hmacWithMD5 "hmacWithMD5" -#define NID_hmacWithMD5 797 -#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L - -#define LN_hmacWithSHA1 "hmacWithSHA1" -#define NID_hmacWithSHA1 163 -#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L - -#define LN_hmacWithSHA224 "hmacWithSHA224" -#define NID_hmacWithSHA224 798 -#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L - -#define LN_hmacWithSHA256 "hmacWithSHA256" -#define NID_hmacWithSHA256 799 -#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L - -#define LN_hmacWithSHA384 "hmacWithSHA384" -#define NID_hmacWithSHA384 800 -#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L - -#define LN_hmacWithSHA512 "hmacWithSHA512" -#define NID_hmacWithSHA512 801 -#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L - -#define SN_rc2_cbc "RC2-CBC" -#define LN_rc2_cbc "rc2-cbc" -#define NID_rc2_cbc 37 -#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L - -#define SN_rc2_ecb "RC2-ECB" -#define LN_rc2_ecb "rc2-ecb" -#define NID_rc2_ecb 38 - -#define SN_rc2_cfb64 "RC2-CFB" -#define LN_rc2_cfb64 "rc2-cfb" -#define NID_rc2_cfb64 39 - -#define SN_rc2_ofb64 "RC2-OFB" -#define LN_rc2_ofb64 "rc2-ofb" -#define NID_rc2_ofb64 40 - -#define SN_rc2_40_cbc "RC2-40-CBC" -#define LN_rc2_40_cbc "rc2-40-cbc" -#define NID_rc2_40_cbc 98 - -#define SN_rc2_64_cbc "RC2-64-CBC" -#define LN_rc2_64_cbc "rc2-64-cbc" -#define NID_rc2_64_cbc 166 - -#define SN_rc4 "RC4" -#define LN_rc4 "rc4" -#define NID_rc4 5 -#define OBJ_rc4 OBJ_rsadsi,3L,4L - -#define SN_rc4_40 "RC4-40" -#define LN_rc4_40 "rc4-40" -#define NID_rc4_40 97 - -#define SN_des_ede3_cbc "DES-EDE3-CBC" -#define LN_des_ede3_cbc "des-ede3-cbc" -#define NID_des_ede3_cbc 44 -#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L - -#define SN_rc5_cbc "RC5-CBC" -#define LN_rc5_cbc "rc5-cbc" -#define NID_rc5_cbc 120 -#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L - -#define SN_rc5_ecb "RC5-ECB" -#define LN_rc5_ecb "rc5-ecb" -#define NID_rc5_ecb 121 - -#define SN_rc5_cfb64 "RC5-CFB" -#define LN_rc5_cfb64 "rc5-cfb" -#define NID_rc5_cfb64 122 - -#define SN_rc5_ofb64 "RC5-OFB" -#define LN_rc5_ofb64 "rc5-ofb" -#define NID_rc5_ofb64 123 - -#define SN_ms_ext_req "msExtReq" -#define LN_ms_ext_req "Microsoft Extension Request" -#define NID_ms_ext_req 171 -#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L - -#define SN_ms_code_ind "msCodeInd" -#define LN_ms_code_ind "Microsoft Individual Code Signing" -#define NID_ms_code_ind 134 -#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L - -#define SN_ms_code_com "msCodeCom" -#define LN_ms_code_com "Microsoft Commercial Code Signing" -#define NID_ms_code_com 135 -#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L - -#define SN_ms_ctl_sign "msCTLSign" -#define LN_ms_ctl_sign "Microsoft Trust List Signing" -#define NID_ms_ctl_sign 136 -#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L - -#define SN_ms_sgc "msSGC" -#define LN_ms_sgc "Microsoft Server Gated Crypto" -#define NID_ms_sgc 137 -#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L - -#define SN_ms_efs "msEFS" -#define LN_ms_efs "Microsoft Encrypted File System" -#define NID_ms_efs 138 -#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L - -#define SN_ms_smartcard_login "msSmartcardLogin" -#define LN_ms_smartcard_login "Microsoft Smartcardlogin" -#define NID_ms_smartcard_login 648 -#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L - -#define SN_ms_upn "msUPN" -#define LN_ms_upn "Microsoft Universal Principal Name" -#define NID_ms_upn 649 -#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L - -#define SN_idea_cbc "IDEA-CBC" -#define LN_idea_cbc "idea-cbc" -#define NID_idea_cbc 34 -#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L - -#define SN_idea_ecb "IDEA-ECB" -#define LN_idea_ecb "idea-ecb" -#define NID_idea_ecb 36 - -#define SN_idea_cfb64 "IDEA-CFB" -#define LN_idea_cfb64 "idea-cfb" -#define NID_idea_cfb64 35 - -#define SN_idea_ofb64 "IDEA-OFB" -#define LN_idea_ofb64 "idea-ofb" -#define NID_idea_ofb64 46 - -#define SN_bf_cbc "BF-CBC" -#define LN_bf_cbc "bf-cbc" -#define NID_bf_cbc 91 -#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L - -#define SN_bf_ecb "BF-ECB" -#define LN_bf_ecb "bf-ecb" -#define NID_bf_ecb 92 - -#define SN_bf_cfb64 "BF-CFB" -#define LN_bf_cfb64 "bf-cfb" -#define NID_bf_cfb64 93 - -#define SN_bf_ofb64 "BF-OFB" -#define LN_bf_ofb64 "bf-ofb" -#define NID_bf_ofb64 94 - -#define SN_id_pkix "PKIX" -#define NID_id_pkix 127 -#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L - -#define SN_id_pkix_mod "id-pkix-mod" -#define NID_id_pkix_mod 258 -#define OBJ_id_pkix_mod OBJ_id_pkix,0L - -#define SN_id_pe "id-pe" -#define NID_id_pe 175 -#define OBJ_id_pe OBJ_id_pkix,1L - -#define SN_id_qt "id-qt" -#define NID_id_qt 259 -#define OBJ_id_qt OBJ_id_pkix,2L - -#define SN_id_kp "id-kp" -#define NID_id_kp 128 -#define OBJ_id_kp OBJ_id_pkix,3L - -#define SN_id_it "id-it" -#define NID_id_it 260 -#define OBJ_id_it OBJ_id_pkix,4L - -#define SN_id_pkip "id-pkip" -#define NID_id_pkip 261 -#define OBJ_id_pkip OBJ_id_pkix,5L - -#define SN_id_alg "id-alg" -#define NID_id_alg 262 -#define OBJ_id_alg OBJ_id_pkix,6L - -#define SN_id_cmc "id-cmc" -#define NID_id_cmc 263 -#define OBJ_id_cmc OBJ_id_pkix,7L - -#define SN_id_on "id-on" -#define NID_id_on 264 -#define OBJ_id_on OBJ_id_pkix,8L - -#define SN_id_pda "id-pda" -#define NID_id_pda 265 -#define OBJ_id_pda OBJ_id_pkix,9L - -#define SN_id_aca "id-aca" -#define NID_id_aca 266 -#define OBJ_id_aca OBJ_id_pkix,10L - -#define SN_id_qcs "id-qcs" -#define NID_id_qcs 267 -#define OBJ_id_qcs OBJ_id_pkix,11L - -#define SN_id_cct "id-cct" -#define NID_id_cct 268 -#define OBJ_id_cct OBJ_id_pkix,12L - -#define SN_id_ppl "id-ppl" -#define NID_id_ppl 662 -#define OBJ_id_ppl OBJ_id_pkix,21L - -#define SN_id_ad "id-ad" -#define NID_id_ad 176 -#define OBJ_id_ad OBJ_id_pkix,48L - -#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" -#define NID_id_pkix1_explicit_88 269 -#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L - -#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" -#define NID_id_pkix1_implicit_88 270 -#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L - -#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" -#define NID_id_pkix1_explicit_93 271 -#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L - -#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" -#define NID_id_pkix1_implicit_93 272 -#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L - -#define SN_id_mod_crmf "id-mod-crmf" -#define NID_id_mod_crmf 273 -#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L - -#define SN_id_mod_cmc "id-mod-cmc" -#define NID_id_mod_cmc 274 -#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L - -#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" -#define NID_id_mod_kea_profile_88 275 -#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L - -#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" -#define NID_id_mod_kea_profile_93 276 -#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L - -#define SN_id_mod_cmp "id-mod-cmp" -#define NID_id_mod_cmp 277 -#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L - -#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" -#define NID_id_mod_qualified_cert_88 278 -#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L - -#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" -#define NID_id_mod_qualified_cert_93 279 -#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L - -#define SN_id_mod_attribute_cert "id-mod-attribute-cert" -#define NID_id_mod_attribute_cert 280 -#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L - -#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" -#define NID_id_mod_timestamp_protocol 281 -#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L - -#define SN_id_mod_ocsp "id-mod-ocsp" -#define NID_id_mod_ocsp 282 -#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L - -#define SN_id_mod_dvcs "id-mod-dvcs" -#define NID_id_mod_dvcs 283 -#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L - -#define SN_id_mod_cmp2000 "id-mod-cmp2000" -#define NID_id_mod_cmp2000 284 -#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L - -#define SN_info_access "authorityInfoAccess" -#define LN_info_access "Authority Information Access" -#define NID_info_access 177 -#define OBJ_info_access OBJ_id_pe,1L - -#define SN_biometricInfo "biometricInfo" -#define LN_biometricInfo "Biometric Info" -#define NID_biometricInfo 285 -#define OBJ_biometricInfo OBJ_id_pe,2L - -#define SN_qcStatements "qcStatements" -#define NID_qcStatements 286 -#define OBJ_qcStatements OBJ_id_pe,3L - -#define SN_ac_auditEntity "ac-auditEntity" -#define NID_ac_auditEntity 287 -#define OBJ_ac_auditEntity OBJ_id_pe,4L - -#define SN_ac_targeting "ac-targeting" -#define NID_ac_targeting 288 -#define OBJ_ac_targeting OBJ_id_pe,5L - -#define SN_aaControls "aaControls" -#define NID_aaControls 289 -#define OBJ_aaControls OBJ_id_pe,6L - -#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" -#define NID_sbgp_ipAddrBlock 290 -#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L - -#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" -#define NID_sbgp_autonomousSysNum 291 -#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L - -#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" -#define NID_sbgp_routerIdentifier 292 -#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L - -#define SN_ac_proxying "ac-proxying" -#define NID_ac_proxying 397 -#define OBJ_ac_proxying OBJ_id_pe,10L - -#define SN_sinfo_access "subjectInfoAccess" -#define LN_sinfo_access "Subject Information Access" -#define NID_sinfo_access 398 -#define OBJ_sinfo_access OBJ_id_pe,11L - -#define SN_proxyCertInfo "proxyCertInfo" -#define LN_proxyCertInfo "Proxy Certificate Information" -#define NID_proxyCertInfo 663 -#define OBJ_proxyCertInfo OBJ_id_pe,14L - -#define SN_id_qt_cps "id-qt-cps" -#define LN_id_qt_cps "Policy Qualifier CPS" -#define NID_id_qt_cps 164 -#define OBJ_id_qt_cps OBJ_id_qt,1L - -#define SN_id_qt_unotice "id-qt-unotice" -#define LN_id_qt_unotice "Policy Qualifier User Notice" -#define NID_id_qt_unotice 165 -#define OBJ_id_qt_unotice OBJ_id_qt,2L - -#define SN_textNotice "textNotice" -#define NID_textNotice 293 -#define OBJ_textNotice OBJ_id_qt,3L - -#define SN_server_auth "serverAuth" -#define LN_server_auth "TLS Web Server Authentication" -#define NID_server_auth 129 -#define OBJ_server_auth OBJ_id_kp,1L - -#define SN_client_auth "clientAuth" -#define LN_client_auth "TLS Web Client Authentication" -#define NID_client_auth 130 -#define OBJ_client_auth OBJ_id_kp,2L - -#define SN_code_sign "codeSigning" -#define LN_code_sign "Code Signing" -#define NID_code_sign 131 -#define OBJ_code_sign OBJ_id_kp,3L - -#define SN_email_protect "emailProtection" -#define LN_email_protect "E-mail Protection" -#define NID_email_protect 132 -#define OBJ_email_protect OBJ_id_kp,4L - -#define SN_ipsecEndSystem "ipsecEndSystem" -#define LN_ipsecEndSystem "IPSec End System" -#define NID_ipsecEndSystem 294 -#define OBJ_ipsecEndSystem OBJ_id_kp,5L - -#define SN_ipsecTunnel "ipsecTunnel" -#define LN_ipsecTunnel "IPSec Tunnel" -#define NID_ipsecTunnel 295 -#define OBJ_ipsecTunnel OBJ_id_kp,6L - -#define SN_ipsecUser "ipsecUser" -#define LN_ipsecUser "IPSec User" -#define NID_ipsecUser 296 -#define OBJ_ipsecUser OBJ_id_kp,7L - -#define SN_time_stamp "timeStamping" -#define LN_time_stamp "Time Stamping" -#define NID_time_stamp 133 -#define OBJ_time_stamp OBJ_id_kp,8L - -#define SN_OCSP_sign "OCSPSigning" -#define LN_OCSP_sign "OCSP Signing" -#define NID_OCSP_sign 180 -#define OBJ_OCSP_sign OBJ_id_kp,9L - -#define SN_dvcs "DVCS" -#define LN_dvcs "dvcs" -#define NID_dvcs 297 -#define OBJ_dvcs OBJ_id_kp,10L - -#define SN_id_it_caProtEncCert "id-it-caProtEncCert" -#define NID_id_it_caProtEncCert 298 -#define OBJ_id_it_caProtEncCert OBJ_id_it,1L - -#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" -#define NID_id_it_signKeyPairTypes 299 -#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L - -#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" -#define NID_id_it_encKeyPairTypes 300 -#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L - -#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" -#define NID_id_it_preferredSymmAlg 301 -#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L - -#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" -#define NID_id_it_caKeyUpdateInfo 302 -#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L - -#define SN_id_it_currentCRL "id-it-currentCRL" -#define NID_id_it_currentCRL 303 -#define OBJ_id_it_currentCRL OBJ_id_it,6L - -#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" -#define NID_id_it_unsupportedOIDs 304 -#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L - -#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" -#define NID_id_it_subscriptionRequest 305 -#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L - -#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" -#define NID_id_it_subscriptionResponse 306 -#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L - -#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" -#define NID_id_it_keyPairParamReq 307 -#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L - -#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" -#define NID_id_it_keyPairParamRep 308 -#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L - -#define SN_id_it_revPassphrase "id-it-revPassphrase" -#define NID_id_it_revPassphrase 309 -#define OBJ_id_it_revPassphrase OBJ_id_it,12L - -#define SN_id_it_implicitConfirm "id-it-implicitConfirm" -#define NID_id_it_implicitConfirm 310 -#define OBJ_id_it_implicitConfirm OBJ_id_it,13L - -#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" -#define NID_id_it_confirmWaitTime 311 -#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L - -#define SN_id_it_origPKIMessage "id-it-origPKIMessage" -#define NID_id_it_origPKIMessage 312 -#define OBJ_id_it_origPKIMessage OBJ_id_it,15L - -#define SN_id_it_suppLangTags "id-it-suppLangTags" -#define NID_id_it_suppLangTags 784 -#define OBJ_id_it_suppLangTags OBJ_id_it,16L - -#define SN_id_regCtrl "id-regCtrl" -#define NID_id_regCtrl 313 -#define OBJ_id_regCtrl OBJ_id_pkip,1L - -#define SN_id_regInfo "id-regInfo" -#define NID_id_regInfo 314 -#define OBJ_id_regInfo OBJ_id_pkip,2L - -#define SN_id_regCtrl_regToken "id-regCtrl-regToken" -#define NID_id_regCtrl_regToken 315 -#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L - -#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" -#define NID_id_regCtrl_authenticator 316 -#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L - -#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" -#define NID_id_regCtrl_pkiPublicationInfo 317 -#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L - -#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" -#define NID_id_regCtrl_pkiArchiveOptions 318 -#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L - -#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" -#define NID_id_regCtrl_oldCertID 319 -#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L - -#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" -#define NID_id_regCtrl_protocolEncrKey 320 -#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L - -#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" -#define NID_id_regInfo_utf8Pairs 321 -#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L - -#define SN_id_regInfo_certReq "id-regInfo-certReq" -#define NID_id_regInfo_certReq 322 -#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L - -#define SN_id_alg_des40 "id-alg-des40" -#define NID_id_alg_des40 323 -#define OBJ_id_alg_des40 OBJ_id_alg,1L - -#define SN_id_alg_noSignature "id-alg-noSignature" -#define NID_id_alg_noSignature 324 -#define OBJ_id_alg_noSignature OBJ_id_alg,2L - -#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" -#define NID_id_alg_dh_sig_hmac_sha1 325 -#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L - -#define SN_id_alg_dh_pop "id-alg-dh-pop" -#define NID_id_alg_dh_pop 326 -#define OBJ_id_alg_dh_pop OBJ_id_alg,4L - -#define SN_id_cmc_statusInfo "id-cmc-statusInfo" -#define NID_id_cmc_statusInfo 327 -#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L - -#define SN_id_cmc_identification "id-cmc-identification" -#define NID_id_cmc_identification 328 -#define OBJ_id_cmc_identification OBJ_id_cmc,2L - -#define SN_id_cmc_identityProof "id-cmc-identityProof" -#define NID_id_cmc_identityProof 329 -#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L - -#define SN_id_cmc_dataReturn "id-cmc-dataReturn" -#define NID_id_cmc_dataReturn 330 -#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L - -#define SN_id_cmc_transactionId "id-cmc-transactionId" -#define NID_id_cmc_transactionId 331 -#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L - -#define SN_id_cmc_senderNonce "id-cmc-senderNonce" -#define NID_id_cmc_senderNonce 332 -#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L - -#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" -#define NID_id_cmc_recipientNonce 333 -#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L - -#define SN_id_cmc_addExtensions "id-cmc-addExtensions" -#define NID_id_cmc_addExtensions 334 -#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L - -#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" -#define NID_id_cmc_encryptedPOP 335 -#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L - -#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" -#define NID_id_cmc_decryptedPOP 336 -#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L - -#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" -#define NID_id_cmc_lraPOPWitness 337 -#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L - -#define SN_id_cmc_getCert "id-cmc-getCert" -#define NID_id_cmc_getCert 338 -#define OBJ_id_cmc_getCert OBJ_id_cmc,15L - -#define SN_id_cmc_getCRL "id-cmc-getCRL" -#define NID_id_cmc_getCRL 339 -#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L - -#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" -#define NID_id_cmc_revokeRequest 340 -#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L - -#define SN_id_cmc_regInfo "id-cmc-regInfo" -#define NID_id_cmc_regInfo 341 -#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L - -#define SN_id_cmc_responseInfo "id-cmc-responseInfo" -#define NID_id_cmc_responseInfo 342 -#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L - -#define SN_id_cmc_queryPending "id-cmc-queryPending" -#define NID_id_cmc_queryPending 343 -#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L - -#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" -#define NID_id_cmc_popLinkRandom 344 -#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L - -#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" -#define NID_id_cmc_popLinkWitness 345 -#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L - -#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" -#define NID_id_cmc_confirmCertAcceptance 346 -#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L - -#define SN_id_on_personalData "id-on-personalData" -#define NID_id_on_personalData 347 -#define OBJ_id_on_personalData OBJ_id_on,1L - -#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" -#define LN_id_on_permanentIdentifier "Permanent Identifier" -#define NID_id_on_permanentIdentifier 858 -#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L - -#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" -#define NID_id_pda_dateOfBirth 348 -#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L - -#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" -#define NID_id_pda_placeOfBirth 349 -#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L - -#define SN_id_pda_gender "id-pda-gender" -#define NID_id_pda_gender 351 -#define OBJ_id_pda_gender OBJ_id_pda,3L - -#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" -#define NID_id_pda_countryOfCitizenship 352 -#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L - -#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" -#define NID_id_pda_countryOfResidence 353 -#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L - -#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" -#define NID_id_aca_authenticationInfo 354 -#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L - -#define SN_id_aca_accessIdentity "id-aca-accessIdentity" -#define NID_id_aca_accessIdentity 355 -#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L - -#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" -#define NID_id_aca_chargingIdentity 356 -#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L - -#define SN_id_aca_group "id-aca-group" -#define NID_id_aca_group 357 -#define OBJ_id_aca_group OBJ_id_aca,4L - -#define SN_id_aca_role "id-aca-role" -#define NID_id_aca_role 358 -#define OBJ_id_aca_role OBJ_id_aca,5L - -#define SN_id_aca_encAttrs "id-aca-encAttrs" -#define NID_id_aca_encAttrs 399 -#define OBJ_id_aca_encAttrs OBJ_id_aca,6L - -#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" -#define NID_id_qcs_pkixQCSyntax_v1 359 -#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L - -#define SN_id_cct_crs "id-cct-crs" -#define NID_id_cct_crs 360 -#define OBJ_id_cct_crs OBJ_id_cct,1L - -#define SN_id_cct_PKIData "id-cct-PKIData" -#define NID_id_cct_PKIData 361 -#define OBJ_id_cct_PKIData OBJ_id_cct,2L - -#define SN_id_cct_PKIResponse "id-cct-PKIResponse" -#define NID_id_cct_PKIResponse 362 -#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L - -#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" -#define LN_id_ppl_anyLanguage "Any language" -#define NID_id_ppl_anyLanguage 664 -#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L - -#define SN_id_ppl_inheritAll "id-ppl-inheritAll" -#define LN_id_ppl_inheritAll "Inherit all" -#define NID_id_ppl_inheritAll 665 -#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L - -#define SN_Independent "id-ppl-independent" -#define LN_Independent "Independent" -#define NID_Independent 667 -#define OBJ_Independent OBJ_id_ppl,2L - -#define SN_ad_OCSP "OCSP" -#define LN_ad_OCSP "OCSP" -#define NID_ad_OCSP 178 -#define OBJ_ad_OCSP OBJ_id_ad,1L - -#define SN_ad_ca_issuers "caIssuers" -#define LN_ad_ca_issuers "CA Issuers" -#define NID_ad_ca_issuers 179 -#define OBJ_ad_ca_issuers OBJ_id_ad,2L - -#define SN_ad_timeStamping "ad_timestamping" -#define LN_ad_timeStamping "AD Time Stamping" -#define NID_ad_timeStamping 363 -#define OBJ_ad_timeStamping OBJ_id_ad,3L - -#define SN_ad_dvcs "AD_DVCS" -#define LN_ad_dvcs "ad dvcs" -#define NID_ad_dvcs 364 -#define OBJ_ad_dvcs OBJ_id_ad,4L - -#define SN_caRepository "caRepository" -#define LN_caRepository "CA Repository" -#define NID_caRepository 785 -#define OBJ_caRepository OBJ_id_ad,5L - -#define OBJ_id_pkix_OCSP OBJ_ad_OCSP - -#define SN_id_pkix_OCSP_basic "basicOCSPResponse" -#define LN_id_pkix_OCSP_basic "Basic OCSP Response" -#define NID_id_pkix_OCSP_basic 365 -#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L - -#define SN_id_pkix_OCSP_Nonce "Nonce" -#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" -#define NID_id_pkix_OCSP_Nonce 366 -#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L - -#define SN_id_pkix_OCSP_CrlID "CrlID" -#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" -#define NID_id_pkix_OCSP_CrlID 367 -#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L - -#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" -#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" -#define NID_id_pkix_OCSP_acceptableResponses 368 -#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L - -#define SN_id_pkix_OCSP_noCheck "noCheck" -#define LN_id_pkix_OCSP_noCheck "OCSP No Check" -#define NID_id_pkix_OCSP_noCheck 369 -#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L - -#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" -#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" -#define NID_id_pkix_OCSP_archiveCutoff 370 -#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L - -#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" -#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" -#define NID_id_pkix_OCSP_serviceLocator 371 -#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L - -#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" -#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" -#define NID_id_pkix_OCSP_extendedStatus 372 -#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L - -#define SN_id_pkix_OCSP_valid "valid" -#define NID_id_pkix_OCSP_valid 373 -#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L - -#define SN_id_pkix_OCSP_path "path" -#define NID_id_pkix_OCSP_path 374 -#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L - -#define SN_id_pkix_OCSP_trustRoot "trustRoot" -#define LN_id_pkix_OCSP_trustRoot "Trust Root" -#define NID_id_pkix_OCSP_trustRoot 375 -#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L - -#define SN_algorithm "algorithm" -#define LN_algorithm "algorithm" -#define NID_algorithm 376 -#define OBJ_algorithm 1L,3L,14L,3L,2L - -#define SN_md5WithRSA "RSA-NP-MD5" -#define LN_md5WithRSA "md5WithRSA" -#define NID_md5WithRSA 104 -#define OBJ_md5WithRSA OBJ_algorithm,3L - -#define SN_des_ecb "DES-ECB" -#define LN_des_ecb "des-ecb" -#define NID_des_ecb 29 -#define OBJ_des_ecb OBJ_algorithm,6L - -#define SN_des_cbc "DES-CBC" -#define LN_des_cbc "des-cbc" -#define NID_des_cbc 31 -#define OBJ_des_cbc OBJ_algorithm,7L - -#define SN_des_ofb64 "DES-OFB" -#define LN_des_ofb64 "des-ofb" -#define NID_des_ofb64 45 -#define OBJ_des_ofb64 OBJ_algorithm,8L - -#define SN_des_cfb64 "DES-CFB" -#define LN_des_cfb64 "des-cfb" -#define NID_des_cfb64 30 -#define OBJ_des_cfb64 OBJ_algorithm,9L - -#define SN_rsaSignature "rsaSignature" -#define NID_rsaSignature 377 -#define OBJ_rsaSignature OBJ_algorithm,11L - -#define SN_dsa_2 "DSA-old" -#define LN_dsa_2 "dsaEncryption-old" -#define NID_dsa_2 67 -#define OBJ_dsa_2 OBJ_algorithm,12L - -#define SN_dsaWithSHA "DSA-SHA" -#define LN_dsaWithSHA "dsaWithSHA" -#define NID_dsaWithSHA 66 -#define OBJ_dsaWithSHA OBJ_algorithm,13L - -#define SN_shaWithRSAEncryption "RSA-SHA" -#define LN_shaWithRSAEncryption "shaWithRSAEncryption" -#define NID_shaWithRSAEncryption 42 -#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L - -#define SN_des_ede_ecb "DES-EDE" -#define LN_des_ede_ecb "des-ede" -#define NID_des_ede_ecb 32 -#define OBJ_des_ede_ecb OBJ_algorithm,17L - -#define SN_des_ede3_ecb "DES-EDE3" -#define LN_des_ede3_ecb "des-ede3" -#define NID_des_ede3_ecb 33 - -#define SN_des_ede_cbc "DES-EDE-CBC" -#define LN_des_ede_cbc "des-ede-cbc" -#define NID_des_ede_cbc 43 - -#define SN_des_ede_cfb64 "DES-EDE-CFB" -#define LN_des_ede_cfb64 "des-ede-cfb" -#define NID_des_ede_cfb64 60 - -#define SN_des_ede3_cfb64 "DES-EDE3-CFB" -#define LN_des_ede3_cfb64 "des-ede3-cfb" -#define NID_des_ede3_cfb64 61 - -#define SN_des_ede_ofb64 "DES-EDE-OFB" -#define LN_des_ede_ofb64 "des-ede-ofb" -#define NID_des_ede_ofb64 62 - -#define SN_des_ede3_ofb64 "DES-EDE3-OFB" -#define LN_des_ede3_ofb64 "des-ede3-ofb" -#define NID_des_ede3_ofb64 63 - -#define SN_desx_cbc "DESX-CBC" -#define LN_desx_cbc "desx-cbc" -#define NID_desx_cbc 80 - -#define SN_sha "SHA" -#define LN_sha "sha" -#define NID_sha 41 -#define OBJ_sha OBJ_algorithm,18L - -#define SN_sha1 "SHA1" -#define LN_sha1 "sha1" -#define NID_sha1 64 -#define OBJ_sha1 OBJ_algorithm,26L - -#define SN_dsaWithSHA1_2 "DSA-SHA1-old" -#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" -#define NID_dsaWithSHA1_2 70 -#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L - -#define SN_sha1WithRSA "RSA-SHA1-2" -#define LN_sha1WithRSA "sha1WithRSA" -#define NID_sha1WithRSA 115 -#define OBJ_sha1WithRSA OBJ_algorithm,29L - -#define SN_ripemd160 "RIPEMD160" -#define LN_ripemd160 "ripemd160" -#define NID_ripemd160 117 -#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L - -#define SN_ripemd160WithRSA "RSA-RIPEMD160" -#define LN_ripemd160WithRSA "ripemd160WithRSA" -#define NID_ripemd160WithRSA 119 -#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L - -#define SN_sxnet "SXNetID" -#define LN_sxnet "Strong Extranet ID" -#define NID_sxnet 143 -#define OBJ_sxnet 1L,3L,101L,1L,4L,1L - -#define SN_X500 "X500" -#define LN_X500 "directory services (X.500)" -#define NID_X500 11 -#define OBJ_X500 2L,5L - -#define SN_X509 "X509" -#define NID_X509 12 -#define OBJ_X509 OBJ_X500,4L - -#define SN_commonName "CN" -#define LN_commonName "commonName" -#define NID_commonName 13 -#define OBJ_commonName OBJ_X509,3L - -#define SN_surname "SN" -#define LN_surname "surname" -#define NID_surname 100 -#define OBJ_surname OBJ_X509,4L - -#define LN_serialNumber "serialNumber" -#define NID_serialNumber 105 -#define OBJ_serialNumber OBJ_X509,5L - -#define SN_countryName "C" -#define LN_countryName "countryName" -#define NID_countryName 14 -#define OBJ_countryName OBJ_X509,6L - -#define SN_localityName "L" -#define LN_localityName "localityName" -#define NID_localityName 15 -#define OBJ_localityName OBJ_X509,7L - -#define SN_stateOrProvinceName "ST" -#define LN_stateOrProvinceName "stateOrProvinceName" -#define NID_stateOrProvinceName 16 -#define OBJ_stateOrProvinceName OBJ_X509,8L - -#define SN_streetAddress "street" -#define LN_streetAddress "streetAddress" -#define NID_streetAddress 660 -#define OBJ_streetAddress OBJ_X509,9L - -#define SN_organizationName "O" -#define LN_organizationName "organizationName" -#define NID_organizationName 17 -#define OBJ_organizationName OBJ_X509,10L - -#define SN_organizationalUnitName "OU" -#define LN_organizationalUnitName "organizationalUnitName" -#define NID_organizationalUnitName 18 -#define OBJ_organizationalUnitName OBJ_X509,11L - -#define SN_title "title" -#define LN_title "title" -#define NID_title 106 -#define OBJ_title OBJ_X509,12L - -#define LN_description "description" -#define NID_description 107 -#define OBJ_description OBJ_X509,13L - -#define LN_searchGuide "searchGuide" -#define NID_searchGuide 859 -#define OBJ_searchGuide OBJ_X509,14L - -#define LN_businessCategory "businessCategory" -#define NID_businessCategory 860 -#define OBJ_businessCategory OBJ_X509,15L - -#define LN_postalAddress "postalAddress" -#define NID_postalAddress 861 -#define OBJ_postalAddress OBJ_X509,16L - -#define LN_postalCode "postalCode" -#define NID_postalCode 661 -#define OBJ_postalCode OBJ_X509,17L - -#define LN_postOfficeBox "postOfficeBox" -#define NID_postOfficeBox 862 -#define OBJ_postOfficeBox OBJ_X509,18L - -#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" -#define NID_physicalDeliveryOfficeName 863 -#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L - -#define LN_telephoneNumber "telephoneNumber" -#define NID_telephoneNumber 864 -#define OBJ_telephoneNumber OBJ_X509,20L - -#define LN_telexNumber "telexNumber" -#define NID_telexNumber 865 -#define OBJ_telexNumber OBJ_X509,21L - -#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" -#define NID_teletexTerminalIdentifier 866 -#define OBJ_teletexTerminalIdentifier OBJ_X509,22L - -#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" -#define NID_facsimileTelephoneNumber 867 -#define OBJ_facsimileTelephoneNumber OBJ_X509,23L - -#define LN_x121Address "x121Address" -#define NID_x121Address 868 -#define OBJ_x121Address OBJ_X509,24L - -#define LN_internationaliSDNNumber "internationaliSDNNumber" -#define NID_internationaliSDNNumber 869 -#define OBJ_internationaliSDNNumber OBJ_X509,25L - -#define LN_registeredAddress "registeredAddress" -#define NID_registeredAddress 870 -#define OBJ_registeredAddress OBJ_X509,26L - -#define LN_destinationIndicator "destinationIndicator" -#define NID_destinationIndicator 871 -#define OBJ_destinationIndicator OBJ_X509,27L - -#define LN_preferredDeliveryMethod "preferredDeliveryMethod" -#define NID_preferredDeliveryMethod 872 -#define OBJ_preferredDeliveryMethod OBJ_X509,28L - -#define LN_presentationAddress "presentationAddress" -#define NID_presentationAddress 873 -#define OBJ_presentationAddress OBJ_X509,29L - -#define LN_supportedApplicationContext "supportedApplicationContext" -#define NID_supportedApplicationContext 874 -#define OBJ_supportedApplicationContext OBJ_X509,30L - -#define SN_member "member" -#define NID_member 875 -#define OBJ_member OBJ_X509,31L - -#define SN_owner "owner" -#define NID_owner 876 -#define OBJ_owner OBJ_X509,32L - -#define LN_roleOccupant "roleOccupant" -#define NID_roleOccupant 877 -#define OBJ_roleOccupant OBJ_X509,33L - -#define SN_seeAlso "seeAlso" -#define NID_seeAlso 878 -#define OBJ_seeAlso OBJ_X509,34L - -#define LN_userPassword "userPassword" -#define NID_userPassword 879 -#define OBJ_userPassword OBJ_X509,35L - -#define LN_userCertificate "userCertificate" -#define NID_userCertificate 880 -#define OBJ_userCertificate OBJ_X509,36L - -#define LN_cACertificate "cACertificate" -#define NID_cACertificate 881 -#define OBJ_cACertificate OBJ_X509,37L - -#define LN_authorityRevocationList "authorityRevocationList" -#define NID_authorityRevocationList 882 -#define OBJ_authorityRevocationList OBJ_X509,38L - -#define LN_certificateRevocationList "certificateRevocationList" -#define NID_certificateRevocationList 883 -#define OBJ_certificateRevocationList OBJ_X509,39L - -#define LN_crossCertificatePair "crossCertificatePair" -#define NID_crossCertificatePair 884 -#define OBJ_crossCertificatePair OBJ_X509,40L - -#define SN_name "name" -#define LN_name "name" -#define NID_name 173 -#define OBJ_name OBJ_X509,41L - -#define SN_givenName "GN" -#define LN_givenName "givenName" -#define NID_givenName 99 -#define OBJ_givenName OBJ_X509,42L - -#define SN_initials "initials" -#define LN_initials "initials" -#define NID_initials 101 -#define OBJ_initials OBJ_X509,43L - -#define LN_generationQualifier "generationQualifier" -#define NID_generationQualifier 509 -#define OBJ_generationQualifier OBJ_X509,44L - -#define LN_x500UniqueIdentifier "x500UniqueIdentifier" -#define NID_x500UniqueIdentifier 503 -#define OBJ_x500UniqueIdentifier OBJ_X509,45L - -#define SN_dnQualifier "dnQualifier" -#define LN_dnQualifier "dnQualifier" -#define NID_dnQualifier 174 -#define OBJ_dnQualifier OBJ_X509,46L - -#define LN_enhancedSearchGuide "enhancedSearchGuide" -#define NID_enhancedSearchGuide 885 -#define OBJ_enhancedSearchGuide OBJ_X509,47L - -#define LN_protocolInformation "protocolInformation" -#define NID_protocolInformation 886 -#define OBJ_protocolInformation OBJ_X509,48L - -#define LN_distinguishedName "distinguishedName" -#define NID_distinguishedName 887 -#define OBJ_distinguishedName OBJ_X509,49L - -#define LN_uniqueMember "uniqueMember" -#define NID_uniqueMember 888 -#define OBJ_uniqueMember OBJ_X509,50L - -#define LN_houseIdentifier "houseIdentifier" -#define NID_houseIdentifier 889 -#define OBJ_houseIdentifier OBJ_X509,51L - -#define LN_supportedAlgorithms "supportedAlgorithms" -#define NID_supportedAlgorithms 890 -#define OBJ_supportedAlgorithms OBJ_X509,52L - -#define LN_deltaRevocationList "deltaRevocationList" -#define NID_deltaRevocationList 891 -#define OBJ_deltaRevocationList OBJ_X509,53L - -#define SN_dmdName "dmdName" -#define NID_dmdName 892 -#define OBJ_dmdName OBJ_X509,54L - -#define LN_pseudonym "pseudonym" -#define NID_pseudonym 510 -#define OBJ_pseudonym OBJ_X509,65L - -#define SN_role "role" -#define LN_role "role" -#define NID_role 400 -#define OBJ_role OBJ_X509,72L - -#define SN_X500algorithms "X500algorithms" -#define LN_X500algorithms "directory services - algorithms" -#define NID_X500algorithms 378 -#define OBJ_X500algorithms OBJ_X500,8L - -#define SN_rsa "RSA" -#define LN_rsa "rsa" -#define NID_rsa 19 -#define OBJ_rsa OBJ_X500algorithms,1L,1L - -#define SN_mdc2WithRSA "RSA-MDC2" -#define LN_mdc2WithRSA "mdc2WithRSA" -#define NID_mdc2WithRSA 96 -#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L - -#define SN_mdc2 "MDC2" -#define LN_mdc2 "mdc2" -#define NID_mdc2 95 -#define OBJ_mdc2 OBJ_X500algorithms,3L,101L - -#define SN_id_ce "id-ce" -#define NID_id_ce 81 -#define OBJ_id_ce OBJ_X500,29L - -#define SN_subject_directory_attributes "subjectDirectoryAttributes" -#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" -#define NID_subject_directory_attributes 769 -#define OBJ_subject_directory_attributes OBJ_id_ce,9L - -#define SN_subject_key_identifier "subjectKeyIdentifier" -#define LN_subject_key_identifier "X509v3 Subject Key Identifier" -#define NID_subject_key_identifier 82 -#define OBJ_subject_key_identifier OBJ_id_ce,14L - -#define SN_key_usage "keyUsage" -#define LN_key_usage "X509v3 Key Usage" -#define NID_key_usage 83 -#define OBJ_key_usage OBJ_id_ce,15L - -#define SN_private_key_usage_period "privateKeyUsagePeriod" -#define LN_private_key_usage_period "X509v3 Private Key Usage Period" -#define NID_private_key_usage_period 84 -#define OBJ_private_key_usage_period OBJ_id_ce,16L - -#define SN_subject_alt_name "subjectAltName" -#define LN_subject_alt_name "X509v3 Subject Alternative Name" -#define NID_subject_alt_name 85 -#define OBJ_subject_alt_name OBJ_id_ce,17L - -#define SN_issuer_alt_name "issuerAltName" -#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" -#define NID_issuer_alt_name 86 -#define OBJ_issuer_alt_name OBJ_id_ce,18L - -#define SN_basic_constraints "basicConstraints" -#define LN_basic_constraints "X509v3 Basic Constraints" -#define NID_basic_constraints 87 -#define OBJ_basic_constraints OBJ_id_ce,19L - -#define SN_crl_number "crlNumber" -#define LN_crl_number "X509v3 CRL Number" -#define NID_crl_number 88 -#define OBJ_crl_number OBJ_id_ce,20L - -#define SN_crl_reason "CRLReason" -#define LN_crl_reason "X509v3 CRL Reason Code" -#define NID_crl_reason 141 -#define OBJ_crl_reason OBJ_id_ce,21L - -#define SN_invalidity_date "invalidityDate" -#define LN_invalidity_date "Invalidity Date" -#define NID_invalidity_date 142 -#define OBJ_invalidity_date OBJ_id_ce,24L - -#define SN_delta_crl "deltaCRL" -#define LN_delta_crl "X509v3 Delta CRL Indicator" -#define NID_delta_crl 140 -#define OBJ_delta_crl OBJ_id_ce,27L - -#define SN_issuing_distribution_point "issuingDistributionPoint" -#define LN_issuing_distribution_point "X509v3 Issuing Distrubution Point" -#define NID_issuing_distribution_point 770 -#define OBJ_issuing_distribution_point OBJ_id_ce,28L - -#define SN_certificate_issuer "certificateIssuer" -#define LN_certificate_issuer "X509v3 Certificate Issuer" -#define NID_certificate_issuer 771 -#define OBJ_certificate_issuer OBJ_id_ce,29L - -#define SN_name_constraints "nameConstraints" -#define LN_name_constraints "X509v3 Name Constraints" -#define NID_name_constraints 666 -#define OBJ_name_constraints OBJ_id_ce,30L - -#define SN_crl_distribution_points "crlDistributionPoints" -#define LN_crl_distribution_points "X509v3 CRL Distribution Points" -#define NID_crl_distribution_points 103 -#define OBJ_crl_distribution_points OBJ_id_ce,31L - -#define SN_certificate_policies "certificatePolicies" -#define LN_certificate_policies "X509v3 Certificate Policies" -#define NID_certificate_policies 89 -#define OBJ_certificate_policies OBJ_id_ce,32L - -#define SN_any_policy "anyPolicy" -#define LN_any_policy "X509v3 Any Policy" -#define NID_any_policy 746 -#define OBJ_any_policy OBJ_certificate_policies,0L - -#define SN_policy_mappings "policyMappings" -#define LN_policy_mappings "X509v3 Policy Mappings" -#define NID_policy_mappings 747 -#define OBJ_policy_mappings OBJ_id_ce,33L - -#define SN_authority_key_identifier "authorityKeyIdentifier" -#define LN_authority_key_identifier "X509v3 Authority Key Identifier" -#define NID_authority_key_identifier 90 -#define OBJ_authority_key_identifier OBJ_id_ce,35L - -#define SN_policy_constraints "policyConstraints" -#define LN_policy_constraints "X509v3 Policy Constraints" -#define NID_policy_constraints 401 -#define OBJ_policy_constraints OBJ_id_ce,36L - -#define SN_ext_key_usage "extendedKeyUsage" -#define LN_ext_key_usage "X509v3 Extended Key Usage" -#define NID_ext_key_usage 126 -#define OBJ_ext_key_usage OBJ_id_ce,37L - -#define SN_freshest_crl "freshestCRL" -#define LN_freshest_crl "X509v3 Freshest CRL" -#define NID_freshest_crl 857 -#define OBJ_freshest_crl OBJ_id_ce,46L - -#define SN_inhibit_any_policy "inhibitAnyPolicy" -#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" -#define NID_inhibit_any_policy 748 -#define OBJ_inhibit_any_policy OBJ_id_ce,54L - -#define SN_target_information "targetInformation" -#define LN_target_information "X509v3 AC Targeting" -#define NID_target_information 402 -#define OBJ_target_information OBJ_id_ce,55L - -#define SN_no_rev_avail "noRevAvail" -#define LN_no_rev_avail "X509v3 No Revocation Available" -#define NID_no_rev_avail 403 -#define OBJ_no_rev_avail OBJ_id_ce,56L - -#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" -#define LN_anyExtendedKeyUsage "Any Extended Key Usage" -#define NID_anyExtendedKeyUsage 910 -#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L - -#define SN_netscape "Netscape" -#define LN_netscape "Netscape Communications Corp." -#define NID_netscape 57 -#define OBJ_netscape 2L,16L,840L,1L,113730L - -#define SN_netscape_cert_extension "nsCertExt" -#define LN_netscape_cert_extension "Netscape Certificate Extension" -#define NID_netscape_cert_extension 58 -#define OBJ_netscape_cert_extension OBJ_netscape,1L - -#define SN_netscape_data_type "nsDataType" -#define LN_netscape_data_type "Netscape Data Type" -#define NID_netscape_data_type 59 -#define OBJ_netscape_data_type OBJ_netscape,2L - -#define SN_netscape_cert_type "nsCertType" -#define LN_netscape_cert_type "Netscape Cert Type" -#define NID_netscape_cert_type 71 -#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L - -#define SN_netscape_base_url "nsBaseUrl" -#define LN_netscape_base_url "Netscape Base Url" -#define NID_netscape_base_url 72 -#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L - -#define SN_netscape_revocation_url "nsRevocationUrl" -#define LN_netscape_revocation_url "Netscape Revocation Url" -#define NID_netscape_revocation_url 73 -#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L - -#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" -#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" -#define NID_netscape_ca_revocation_url 74 -#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L - -#define SN_netscape_renewal_url "nsRenewalUrl" -#define LN_netscape_renewal_url "Netscape Renewal Url" -#define NID_netscape_renewal_url 75 -#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L - -#define SN_netscape_ca_policy_url "nsCaPolicyUrl" -#define LN_netscape_ca_policy_url "Netscape CA Policy Url" -#define NID_netscape_ca_policy_url 76 -#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L - -#define SN_netscape_ssl_server_name "nsSslServerName" -#define LN_netscape_ssl_server_name "Netscape SSL Server Name" -#define NID_netscape_ssl_server_name 77 -#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L - -#define SN_netscape_comment "nsComment" -#define LN_netscape_comment "Netscape Comment" -#define NID_netscape_comment 78 -#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L - -#define SN_netscape_cert_sequence "nsCertSequence" -#define LN_netscape_cert_sequence "Netscape Certificate Sequence" -#define NID_netscape_cert_sequence 79 -#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L - -#define SN_ns_sgc "nsSGC" -#define LN_ns_sgc "Netscape Server Gated Crypto" -#define NID_ns_sgc 139 -#define OBJ_ns_sgc OBJ_netscape,4L,1L - -#define SN_org "ORG" -#define LN_org "org" -#define NID_org 379 -#define OBJ_org OBJ_iso,3L - -#define SN_dod "DOD" -#define LN_dod "dod" -#define NID_dod 380 -#define OBJ_dod OBJ_org,6L - -#define SN_iana "IANA" -#define LN_iana "iana" -#define NID_iana 381 -#define OBJ_iana OBJ_dod,1L - -#define OBJ_internet OBJ_iana - -#define SN_Directory "directory" -#define LN_Directory "Directory" -#define NID_Directory 382 -#define OBJ_Directory OBJ_internet,1L - -#define SN_Management "mgmt" -#define LN_Management "Management" -#define NID_Management 383 -#define OBJ_Management OBJ_internet,2L - -#define SN_Experimental "experimental" -#define LN_Experimental "Experimental" -#define NID_Experimental 384 -#define OBJ_Experimental OBJ_internet,3L - -#define SN_Private "private" -#define LN_Private "Private" -#define NID_Private 385 -#define OBJ_Private OBJ_internet,4L - -#define SN_Security "security" -#define LN_Security "Security" -#define NID_Security 386 -#define OBJ_Security OBJ_internet,5L - -#define SN_SNMPv2 "snmpv2" -#define LN_SNMPv2 "SNMPv2" -#define NID_SNMPv2 387 -#define OBJ_SNMPv2 OBJ_internet,6L - -#define LN_Mail "Mail" -#define NID_Mail 388 -#define OBJ_Mail OBJ_internet,7L - -#define SN_Enterprises "enterprises" -#define LN_Enterprises "Enterprises" -#define NID_Enterprises 389 -#define OBJ_Enterprises OBJ_Private,1L - -#define SN_dcObject "dcobject" -#define LN_dcObject "dcObject" -#define NID_dcObject 390 -#define OBJ_dcObject OBJ_Enterprises,1466L,344L - -#define SN_mime_mhs "mime-mhs" -#define LN_mime_mhs "MIME MHS" -#define NID_mime_mhs 504 -#define OBJ_mime_mhs OBJ_Mail,1L - -#define SN_mime_mhs_headings "mime-mhs-headings" -#define LN_mime_mhs_headings "mime-mhs-headings" -#define NID_mime_mhs_headings 505 -#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L - -#define SN_mime_mhs_bodies "mime-mhs-bodies" -#define LN_mime_mhs_bodies "mime-mhs-bodies" -#define NID_mime_mhs_bodies 506 -#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L - -#define SN_id_hex_partial_message "id-hex-partial-message" -#define LN_id_hex_partial_message "id-hex-partial-message" -#define NID_id_hex_partial_message 507 -#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L - -#define SN_id_hex_multipart_message "id-hex-multipart-message" -#define LN_id_hex_multipart_message "id-hex-multipart-message" -#define NID_id_hex_multipart_message 508 -#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L - -#define SN_rle_compression "RLE" -#define LN_rle_compression "run length compression" -#define NID_rle_compression 124 -#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L - -#define SN_zlib_compression "ZLIB" -#define LN_zlib_compression "zlib compression" -#define NID_zlib_compression 125 -#define OBJ_zlib_compression OBJ_id_smime_alg,8L - -#define OBJ_csor 2L,16L,840L,1L,101L,3L - -#define OBJ_nistAlgorithms OBJ_csor,4L - -#define OBJ_aes OBJ_nistAlgorithms,1L - -#define SN_aes_128_ecb "AES-128-ECB" -#define LN_aes_128_ecb "aes-128-ecb" -#define NID_aes_128_ecb 418 -#define OBJ_aes_128_ecb OBJ_aes,1L - -#define SN_aes_128_cbc "AES-128-CBC" -#define LN_aes_128_cbc "aes-128-cbc" -#define NID_aes_128_cbc 419 -#define OBJ_aes_128_cbc OBJ_aes,2L - -#define SN_aes_128_ofb128 "AES-128-OFB" -#define LN_aes_128_ofb128 "aes-128-ofb" -#define NID_aes_128_ofb128 420 -#define OBJ_aes_128_ofb128 OBJ_aes,3L - -#define SN_aes_128_cfb128 "AES-128-CFB" -#define LN_aes_128_cfb128 "aes-128-cfb" -#define NID_aes_128_cfb128 421 -#define OBJ_aes_128_cfb128 OBJ_aes,4L - -#define SN_id_aes128_wrap "id-aes128-wrap" -#define NID_id_aes128_wrap 788 -#define OBJ_id_aes128_wrap OBJ_aes,5L - -#define SN_aes_128_gcm "id-aes128-GCM" -#define LN_aes_128_gcm "aes-128-gcm" -#define NID_aes_128_gcm 895 -#define OBJ_aes_128_gcm OBJ_aes,6L - -#define SN_aes_128_ccm "id-aes128-CCM" -#define LN_aes_128_ccm "aes-128-ccm" -#define NID_aes_128_ccm 896 -#define OBJ_aes_128_ccm OBJ_aes,7L - -#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" -#define NID_id_aes128_wrap_pad 897 -#define OBJ_id_aes128_wrap_pad OBJ_aes,8L - -#define SN_aes_192_ecb "AES-192-ECB" -#define LN_aes_192_ecb "aes-192-ecb" -#define NID_aes_192_ecb 422 -#define OBJ_aes_192_ecb OBJ_aes,21L - -#define SN_aes_192_cbc "AES-192-CBC" -#define LN_aes_192_cbc "aes-192-cbc" -#define NID_aes_192_cbc 423 -#define OBJ_aes_192_cbc OBJ_aes,22L - -#define SN_aes_192_ofb128 "AES-192-OFB" -#define LN_aes_192_ofb128 "aes-192-ofb" -#define NID_aes_192_ofb128 424 -#define OBJ_aes_192_ofb128 OBJ_aes,23L - -#define SN_aes_192_cfb128 "AES-192-CFB" -#define LN_aes_192_cfb128 "aes-192-cfb" -#define NID_aes_192_cfb128 425 -#define OBJ_aes_192_cfb128 OBJ_aes,24L - -#define SN_id_aes192_wrap "id-aes192-wrap" -#define NID_id_aes192_wrap 789 -#define OBJ_id_aes192_wrap OBJ_aes,25L - -#define SN_aes_192_gcm "id-aes192-GCM" -#define LN_aes_192_gcm "aes-192-gcm" -#define NID_aes_192_gcm 898 -#define OBJ_aes_192_gcm OBJ_aes,26L - -#define SN_aes_192_ccm "id-aes192-CCM" -#define LN_aes_192_ccm "aes-192-ccm" -#define NID_aes_192_ccm 899 -#define OBJ_aes_192_ccm OBJ_aes,27L - -#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" -#define NID_id_aes192_wrap_pad 900 -#define OBJ_id_aes192_wrap_pad OBJ_aes,28L - -#define SN_aes_256_ecb "AES-256-ECB" -#define LN_aes_256_ecb "aes-256-ecb" -#define NID_aes_256_ecb 426 -#define OBJ_aes_256_ecb OBJ_aes,41L - -#define SN_aes_256_cbc "AES-256-CBC" -#define LN_aes_256_cbc "aes-256-cbc" -#define NID_aes_256_cbc 427 -#define OBJ_aes_256_cbc OBJ_aes,42L - -#define SN_aes_256_ofb128 "AES-256-OFB" -#define LN_aes_256_ofb128 "aes-256-ofb" -#define NID_aes_256_ofb128 428 -#define OBJ_aes_256_ofb128 OBJ_aes,43L - -#define SN_aes_256_cfb128 "AES-256-CFB" -#define LN_aes_256_cfb128 "aes-256-cfb" -#define NID_aes_256_cfb128 429 -#define OBJ_aes_256_cfb128 OBJ_aes,44L - -#define SN_id_aes256_wrap "id-aes256-wrap" -#define NID_id_aes256_wrap 790 -#define OBJ_id_aes256_wrap OBJ_aes,45L - -#define SN_aes_256_gcm "id-aes256-GCM" -#define LN_aes_256_gcm "aes-256-gcm" -#define NID_aes_256_gcm 901 -#define OBJ_aes_256_gcm OBJ_aes,46L - -#define SN_aes_256_ccm "id-aes256-CCM" -#define LN_aes_256_ccm "aes-256-ccm" -#define NID_aes_256_ccm 902 -#define OBJ_aes_256_ccm OBJ_aes,47L - -#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" -#define NID_id_aes256_wrap_pad 903 -#define OBJ_id_aes256_wrap_pad OBJ_aes,48L - -#define SN_aes_128_cfb1 "AES-128-CFB1" -#define LN_aes_128_cfb1 "aes-128-cfb1" -#define NID_aes_128_cfb1 650 - -#define SN_aes_192_cfb1 "AES-192-CFB1" -#define LN_aes_192_cfb1 "aes-192-cfb1" -#define NID_aes_192_cfb1 651 - -#define SN_aes_256_cfb1 "AES-256-CFB1" -#define LN_aes_256_cfb1 "aes-256-cfb1" -#define NID_aes_256_cfb1 652 - -#define SN_aes_128_cfb8 "AES-128-CFB8" -#define LN_aes_128_cfb8 "aes-128-cfb8" -#define NID_aes_128_cfb8 653 - -#define SN_aes_192_cfb8 "AES-192-CFB8" -#define LN_aes_192_cfb8 "aes-192-cfb8" -#define NID_aes_192_cfb8 654 - -#define SN_aes_256_cfb8 "AES-256-CFB8" -#define LN_aes_256_cfb8 "aes-256-cfb8" -#define NID_aes_256_cfb8 655 - -#define SN_aes_128_ctr "AES-128-CTR" -#define LN_aes_128_ctr "aes-128-ctr" -#define NID_aes_128_ctr 904 - -#define SN_aes_192_ctr "AES-192-CTR" -#define LN_aes_192_ctr "aes-192-ctr" -#define NID_aes_192_ctr 905 - -#define SN_aes_256_ctr "AES-256-CTR" -#define LN_aes_256_ctr "aes-256-ctr" -#define NID_aes_256_ctr 906 - -#define SN_aes_128_xts "AES-128-XTS" -#define LN_aes_128_xts "aes-128-xts" -#define NID_aes_128_xts 913 - -#define SN_aes_256_xts "AES-256-XTS" -#define LN_aes_256_xts "aes-256-xts" -#define NID_aes_256_xts 914 - -#define SN_des_cfb1 "DES-CFB1" -#define LN_des_cfb1 "des-cfb1" -#define NID_des_cfb1 656 - -#define SN_des_cfb8 "DES-CFB8" -#define LN_des_cfb8 "des-cfb8" -#define NID_des_cfb8 657 - -#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" -#define LN_des_ede3_cfb1 "des-ede3-cfb1" -#define NID_des_ede3_cfb1 658 - -#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" -#define LN_des_ede3_cfb8 "des-ede3-cfb8" -#define NID_des_ede3_cfb8 659 - -#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L - -#define SN_sha256 "SHA256" -#define LN_sha256 "sha256" -#define NID_sha256 672 -#define OBJ_sha256 OBJ_nist_hashalgs,1L - -#define SN_sha384 "SHA384" -#define LN_sha384 "sha384" -#define NID_sha384 673 -#define OBJ_sha384 OBJ_nist_hashalgs,2L - -#define SN_sha512 "SHA512" -#define LN_sha512 "sha512" -#define NID_sha512 674 -#define OBJ_sha512 OBJ_nist_hashalgs,3L - -#define SN_sha224 "SHA224" -#define LN_sha224 "sha224" -#define NID_sha224 675 -#define OBJ_sha224 OBJ_nist_hashalgs,4L - -#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L - -#define SN_dsa_with_SHA224 "dsa_with_SHA224" -#define NID_dsa_with_SHA224 802 -#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L - -#define SN_dsa_with_SHA256 "dsa_with_SHA256" -#define NID_dsa_with_SHA256 803 -#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L - -#define SN_hold_instruction_code "holdInstructionCode" -#define LN_hold_instruction_code "Hold Instruction Code" -#define NID_hold_instruction_code 430 -#define OBJ_hold_instruction_code OBJ_id_ce,23L - -#define OBJ_holdInstruction OBJ_X9_57,2L - -#define SN_hold_instruction_none "holdInstructionNone" -#define LN_hold_instruction_none "Hold Instruction None" -#define NID_hold_instruction_none 431 -#define OBJ_hold_instruction_none OBJ_holdInstruction,1L - -#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" -#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" -#define NID_hold_instruction_call_issuer 432 -#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L - -#define SN_hold_instruction_reject "holdInstructionReject" -#define LN_hold_instruction_reject "Hold Instruction Reject" -#define NID_hold_instruction_reject 433 -#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L - -#define SN_data "data" -#define NID_data 434 -#define OBJ_data OBJ_itu_t,9L - -#define SN_pss "pss" -#define NID_pss 435 -#define OBJ_pss OBJ_data,2342L - -#define SN_ucl "ucl" -#define NID_ucl 436 -#define OBJ_ucl OBJ_pss,19200300L - -#define SN_pilot "pilot" -#define NID_pilot 437 -#define OBJ_pilot OBJ_ucl,100L - -#define LN_pilotAttributeType "pilotAttributeType" -#define NID_pilotAttributeType 438 -#define OBJ_pilotAttributeType OBJ_pilot,1L - -#define LN_pilotAttributeSyntax "pilotAttributeSyntax" -#define NID_pilotAttributeSyntax 439 -#define OBJ_pilotAttributeSyntax OBJ_pilot,3L - -#define LN_pilotObjectClass "pilotObjectClass" -#define NID_pilotObjectClass 440 -#define OBJ_pilotObjectClass OBJ_pilot,4L - -#define LN_pilotGroups "pilotGroups" -#define NID_pilotGroups 441 -#define OBJ_pilotGroups OBJ_pilot,10L - -#define LN_iA5StringSyntax "iA5StringSyntax" -#define NID_iA5StringSyntax 442 -#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L - -#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" -#define NID_caseIgnoreIA5StringSyntax 443 -#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L - -#define LN_pilotObject "pilotObject" -#define NID_pilotObject 444 -#define OBJ_pilotObject OBJ_pilotObjectClass,3L - -#define LN_pilotPerson "pilotPerson" -#define NID_pilotPerson 445 -#define OBJ_pilotPerson OBJ_pilotObjectClass,4L - -#define SN_account "account" -#define NID_account 446 -#define OBJ_account OBJ_pilotObjectClass,5L - -#define SN_document "document" -#define NID_document 447 -#define OBJ_document OBJ_pilotObjectClass,6L - -#define SN_room "room" -#define NID_room 448 -#define OBJ_room OBJ_pilotObjectClass,7L - -#define LN_documentSeries "documentSeries" -#define NID_documentSeries 449 -#define OBJ_documentSeries OBJ_pilotObjectClass,9L - -#define SN_Domain "domain" -#define LN_Domain "Domain" -#define NID_Domain 392 -#define OBJ_Domain OBJ_pilotObjectClass,13L - -#define LN_rFC822localPart "rFC822localPart" -#define NID_rFC822localPart 450 -#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L - -#define LN_dNSDomain "dNSDomain" -#define NID_dNSDomain 451 -#define OBJ_dNSDomain OBJ_pilotObjectClass,15L - -#define LN_domainRelatedObject "domainRelatedObject" -#define NID_domainRelatedObject 452 -#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L - -#define LN_friendlyCountry "friendlyCountry" -#define NID_friendlyCountry 453 -#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L - -#define LN_simpleSecurityObject "simpleSecurityObject" -#define NID_simpleSecurityObject 454 -#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L - -#define LN_pilotOrganization "pilotOrganization" -#define NID_pilotOrganization 455 -#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L - -#define LN_pilotDSA "pilotDSA" -#define NID_pilotDSA 456 -#define OBJ_pilotDSA OBJ_pilotObjectClass,21L - -#define LN_qualityLabelledData "qualityLabelledData" -#define NID_qualityLabelledData 457 -#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L - -#define SN_userId "UID" -#define LN_userId "userId" -#define NID_userId 458 -#define OBJ_userId OBJ_pilotAttributeType,1L - -#define LN_textEncodedORAddress "textEncodedORAddress" -#define NID_textEncodedORAddress 459 -#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L - -#define SN_rfc822Mailbox "mail" -#define LN_rfc822Mailbox "rfc822Mailbox" -#define NID_rfc822Mailbox 460 -#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L - -#define SN_info "info" -#define NID_info 461 -#define OBJ_info OBJ_pilotAttributeType,4L - -#define LN_favouriteDrink "favouriteDrink" -#define NID_favouriteDrink 462 -#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L - -#define LN_roomNumber "roomNumber" -#define NID_roomNumber 463 -#define OBJ_roomNumber OBJ_pilotAttributeType,6L - -#define SN_photo "photo" -#define NID_photo 464 -#define OBJ_photo OBJ_pilotAttributeType,7L - -#define LN_userClass "userClass" -#define NID_userClass 465 -#define OBJ_userClass OBJ_pilotAttributeType,8L - -#define SN_host "host" -#define NID_host 466 -#define OBJ_host OBJ_pilotAttributeType,9L - -#define SN_manager "manager" -#define NID_manager 467 -#define OBJ_manager OBJ_pilotAttributeType,10L - -#define LN_documentIdentifier "documentIdentifier" -#define NID_documentIdentifier 468 -#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L - -#define LN_documentTitle "documentTitle" -#define NID_documentTitle 469 -#define OBJ_documentTitle OBJ_pilotAttributeType,12L - -#define LN_documentVersion "documentVersion" -#define NID_documentVersion 470 -#define OBJ_documentVersion OBJ_pilotAttributeType,13L - -#define LN_documentAuthor "documentAuthor" -#define NID_documentAuthor 471 -#define OBJ_documentAuthor OBJ_pilotAttributeType,14L - -#define LN_documentLocation "documentLocation" -#define NID_documentLocation 472 -#define OBJ_documentLocation OBJ_pilotAttributeType,15L - -#define LN_homeTelephoneNumber "homeTelephoneNumber" -#define NID_homeTelephoneNumber 473 -#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L - -#define SN_secretary "secretary" -#define NID_secretary 474 -#define OBJ_secretary OBJ_pilotAttributeType,21L - -#define LN_otherMailbox "otherMailbox" -#define NID_otherMailbox 475 -#define OBJ_otherMailbox OBJ_pilotAttributeType,22L - -#define LN_lastModifiedTime "lastModifiedTime" -#define NID_lastModifiedTime 476 -#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L - -#define LN_lastModifiedBy "lastModifiedBy" -#define NID_lastModifiedBy 477 -#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L - -#define SN_domainComponent "DC" -#define LN_domainComponent "domainComponent" -#define NID_domainComponent 391 -#define OBJ_domainComponent OBJ_pilotAttributeType,25L - -#define LN_aRecord "aRecord" -#define NID_aRecord 478 -#define OBJ_aRecord OBJ_pilotAttributeType,26L - -#define LN_pilotAttributeType27 "pilotAttributeType27" -#define NID_pilotAttributeType27 479 -#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L - -#define LN_mXRecord "mXRecord" -#define NID_mXRecord 480 -#define OBJ_mXRecord OBJ_pilotAttributeType,28L - -#define LN_nSRecord "nSRecord" -#define NID_nSRecord 481 -#define OBJ_nSRecord OBJ_pilotAttributeType,29L - -#define LN_sOARecord "sOARecord" -#define NID_sOARecord 482 -#define OBJ_sOARecord OBJ_pilotAttributeType,30L - -#define LN_cNAMERecord "cNAMERecord" -#define NID_cNAMERecord 483 -#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L - -#define LN_associatedDomain "associatedDomain" -#define NID_associatedDomain 484 -#define OBJ_associatedDomain OBJ_pilotAttributeType,37L - -#define LN_associatedName "associatedName" -#define NID_associatedName 485 -#define OBJ_associatedName OBJ_pilotAttributeType,38L - -#define LN_homePostalAddress "homePostalAddress" -#define NID_homePostalAddress 486 -#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L - -#define LN_personalTitle "personalTitle" -#define NID_personalTitle 487 -#define OBJ_personalTitle OBJ_pilotAttributeType,40L - -#define LN_mobileTelephoneNumber "mobileTelephoneNumber" -#define NID_mobileTelephoneNumber 488 -#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L - -#define LN_pagerTelephoneNumber "pagerTelephoneNumber" -#define NID_pagerTelephoneNumber 489 -#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L - -#define LN_friendlyCountryName "friendlyCountryName" -#define NID_friendlyCountryName 490 -#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L - -#define LN_organizationalStatus "organizationalStatus" -#define NID_organizationalStatus 491 -#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L - -#define LN_janetMailbox "janetMailbox" -#define NID_janetMailbox 492 -#define OBJ_janetMailbox OBJ_pilotAttributeType,46L - -#define LN_mailPreferenceOption "mailPreferenceOption" -#define NID_mailPreferenceOption 493 -#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L - -#define LN_buildingName "buildingName" -#define NID_buildingName 494 -#define OBJ_buildingName OBJ_pilotAttributeType,48L - -#define LN_dSAQuality "dSAQuality" -#define NID_dSAQuality 495 -#define OBJ_dSAQuality OBJ_pilotAttributeType,49L - -#define LN_singleLevelQuality "singleLevelQuality" -#define NID_singleLevelQuality 496 -#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L - -#define LN_subtreeMinimumQuality "subtreeMinimumQuality" -#define NID_subtreeMinimumQuality 497 -#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L - -#define LN_subtreeMaximumQuality "subtreeMaximumQuality" -#define NID_subtreeMaximumQuality 498 -#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L - -#define LN_personalSignature "personalSignature" -#define NID_personalSignature 499 -#define OBJ_personalSignature OBJ_pilotAttributeType,53L - -#define LN_dITRedirect "dITRedirect" -#define NID_dITRedirect 500 -#define OBJ_dITRedirect OBJ_pilotAttributeType,54L - -#define SN_audio "audio" -#define NID_audio 501 -#define OBJ_audio OBJ_pilotAttributeType,55L - -#define LN_documentPublisher "documentPublisher" -#define NID_documentPublisher 502 -#define OBJ_documentPublisher OBJ_pilotAttributeType,56L - -#define SN_id_set "id-set" -#define LN_id_set "Secure Electronic Transactions" -#define NID_id_set 512 -#define OBJ_id_set OBJ_international_organizations,42L - -#define SN_set_ctype "set-ctype" -#define LN_set_ctype "content types" -#define NID_set_ctype 513 -#define OBJ_set_ctype OBJ_id_set,0L - -#define SN_set_msgExt "set-msgExt" -#define LN_set_msgExt "message extensions" -#define NID_set_msgExt 514 -#define OBJ_set_msgExt OBJ_id_set,1L - -#define SN_set_attr "set-attr" -#define NID_set_attr 515 -#define OBJ_set_attr OBJ_id_set,3L - -#define SN_set_policy "set-policy" -#define NID_set_policy 516 -#define OBJ_set_policy OBJ_id_set,5L - -#define SN_set_certExt "set-certExt" -#define LN_set_certExt "certificate extensions" -#define NID_set_certExt 517 -#define OBJ_set_certExt OBJ_id_set,7L - -#define SN_set_brand "set-brand" -#define NID_set_brand 518 -#define OBJ_set_brand OBJ_id_set,8L - -#define SN_setct_PANData "setct-PANData" -#define NID_setct_PANData 519 -#define OBJ_setct_PANData OBJ_set_ctype,0L - -#define SN_setct_PANToken "setct-PANToken" -#define NID_setct_PANToken 520 -#define OBJ_setct_PANToken OBJ_set_ctype,1L - -#define SN_setct_PANOnly "setct-PANOnly" -#define NID_setct_PANOnly 521 -#define OBJ_setct_PANOnly OBJ_set_ctype,2L - -#define SN_setct_OIData "setct-OIData" -#define NID_setct_OIData 522 -#define OBJ_setct_OIData OBJ_set_ctype,3L - -#define SN_setct_PI "setct-PI" -#define NID_setct_PI 523 -#define OBJ_setct_PI OBJ_set_ctype,4L - -#define SN_setct_PIData "setct-PIData" -#define NID_setct_PIData 524 -#define OBJ_setct_PIData OBJ_set_ctype,5L - -#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" -#define NID_setct_PIDataUnsigned 525 -#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L - -#define SN_setct_HODInput "setct-HODInput" -#define NID_setct_HODInput 526 -#define OBJ_setct_HODInput OBJ_set_ctype,7L - -#define SN_setct_AuthResBaggage "setct-AuthResBaggage" -#define NID_setct_AuthResBaggage 527 -#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L - -#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" -#define NID_setct_AuthRevReqBaggage 528 -#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L - -#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" -#define NID_setct_AuthRevResBaggage 529 -#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L - -#define SN_setct_CapTokenSeq "setct-CapTokenSeq" -#define NID_setct_CapTokenSeq 530 -#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L - -#define SN_setct_PInitResData "setct-PInitResData" -#define NID_setct_PInitResData 531 -#define OBJ_setct_PInitResData OBJ_set_ctype,12L - -#define SN_setct_PI_TBS "setct-PI-TBS" -#define NID_setct_PI_TBS 532 -#define OBJ_setct_PI_TBS OBJ_set_ctype,13L - -#define SN_setct_PResData "setct-PResData" -#define NID_setct_PResData 533 -#define OBJ_setct_PResData OBJ_set_ctype,14L - -#define SN_setct_AuthReqTBS "setct-AuthReqTBS" -#define NID_setct_AuthReqTBS 534 -#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L - -#define SN_setct_AuthResTBS "setct-AuthResTBS" -#define NID_setct_AuthResTBS 535 -#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L - -#define SN_setct_AuthResTBSX "setct-AuthResTBSX" -#define NID_setct_AuthResTBSX 536 -#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L - -#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" -#define NID_setct_AuthTokenTBS 537 -#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L - -#define SN_setct_CapTokenData "setct-CapTokenData" -#define NID_setct_CapTokenData 538 -#define OBJ_setct_CapTokenData OBJ_set_ctype,20L - -#define SN_setct_CapTokenTBS "setct-CapTokenTBS" -#define NID_setct_CapTokenTBS 539 -#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L - -#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" -#define NID_setct_AcqCardCodeMsg 540 -#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L - -#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" -#define NID_setct_AuthRevReqTBS 541 -#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L - -#define SN_setct_AuthRevResData "setct-AuthRevResData" -#define NID_setct_AuthRevResData 542 -#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L - -#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" -#define NID_setct_AuthRevResTBS 543 -#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L - -#define SN_setct_CapReqTBS "setct-CapReqTBS" -#define NID_setct_CapReqTBS 544 -#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L - -#define SN_setct_CapReqTBSX "setct-CapReqTBSX" -#define NID_setct_CapReqTBSX 545 -#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L - -#define SN_setct_CapResData "setct-CapResData" -#define NID_setct_CapResData 546 -#define OBJ_setct_CapResData OBJ_set_ctype,28L - -#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" -#define NID_setct_CapRevReqTBS 547 -#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L - -#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" -#define NID_setct_CapRevReqTBSX 548 -#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L - -#define SN_setct_CapRevResData "setct-CapRevResData" -#define NID_setct_CapRevResData 549 -#define OBJ_setct_CapRevResData OBJ_set_ctype,31L - -#define SN_setct_CredReqTBS "setct-CredReqTBS" -#define NID_setct_CredReqTBS 550 -#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L - -#define SN_setct_CredReqTBSX "setct-CredReqTBSX" -#define NID_setct_CredReqTBSX 551 -#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L - -#define SN_setct_CredResData "setct-CredResData" -#define NID_setct_CredResData 552 -#define OBJ_setct_CredResData OBJ_set_ctype,34L - -#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" -#define NID_setct_CredRevReqTBS 553 -#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L - -#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" -#define NID_setct_CredRevReqTBSX 554 -#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L - -#define SN_setct_CredRevResData "setct-CredRevResData" -#define NID_setct_CredRevResData 555 -#define OBJ_setct_CredRevResData OBJ_set_ctype,37L - -#define SN_setct_PCertReqData "setct-PCertReqData" -#define NID_setct_PCertReqData 556 -#define OBJ_setct_PCertReqData OBJ_set_ctype,38L - -#define SN_setct_PCertResTBS "setct-PCertResTBS" -#define NID_setct_PCertResTBS 557 -#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L - -#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" -#define NID_setct_BatchAdminReqData 558 -#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L - -#define SN_setct_BatchAdminResData "setct-BatchAdminResData" -#define NID_setct_BatchAdminResData 559 -#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L - -#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" -#define NID_setct_CardCInitResTBS 560 -#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L - -#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" -#define NID_setct_MeAqCInitResTBS 561 -#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L - -#define SN_setct_RegFormResTBS "setct-RegFormResTBS" -#define NID_setct_RegFormResTBS 562 -#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L - -#define SN_setct_CertReqData "setct-CertReqData" -#define NID_setct_CertReqData 563 -#define OBJ_setct_CertReqData OBJ_set_ctype,45L - -#define SN_setct_CertReqTBS "setct-CertReqTBS" -#define NID_setct_CertReqTBS 564 -#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L - -#define SN_setct_CertResData "setct-CertResData" -#define NID_setct_CertResData 565 -#define OBJ_setct_CertResData OBJ_set_ctype,47L - -#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" -#define NID_setct_CertInqReqTBS 566 -#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L - -#define SN_setct_ErrorTBS "setct-ErrorTBS" -#define NID_setct_ErrorTBS 567 -#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L - -#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" -#define NID_setct_PIDualSignedTBE 568 -#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L - -#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" -#define NID_setct_PIUnsignedTBE 569 -#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L - -#define SN_setct_AuthReqTBE "setct-AuthReqTBE" -#define NID_setct_AuthReqTBE 570 -#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L - -#define SN_setct_AuthResTBE "setct-AuthResTBE" -#define NID_setct_AuthResTBE 571 -#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L - -#define SN_setct_AuthResTBEX "setct-AuthResTBEX" -#define NID_setct_AuthResTBEX 572 -#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L - -#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" -#define NID_setct_AuthTokenTBE 573 -#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L - -#define SN_setct_CapTokenTBE "setct-CapTokenTBE" -#define NID_setct_CapTokenTBE 574 -#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L - -#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" -#define NID_setct_CapTokenTBEX 575 -#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L - -#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" -#define NID_setct_AcqCardCodeMsgTBE 576 -#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L - -#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" -#define NID_setct_AuthRevReqTBE 577 -#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L - -#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" -#define NID_setct_AuthRevResTBE 578 -#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L - -#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" -#define NID_setct_AuthRevResTBEB 579 -#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L - -#define SN_setct_CapReqTBE "setct-CapReqTBE" -#define NID_setct_CapReqTBE 580 -#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L - -#define SN_setct_CapReqTBEX "setct-CapReqTBEX" -#define NID_setct_CapReqTBEX 581 -#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L - -#define SN_setct_CapResTBE "setct-CapResTBE" -#define NID_setct_CapResTBE 582 -#define OBJ_setct_CapResTBE OBJ_set_ctype,64L - -#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" -#define NID_setct_CapRevReqTBE 583 -#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L - -#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" -#define NID_setct_CapRevReqTBEX 584 -#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L - -#define SN_setct_CapRevResTBE "setct-CapRevResTBE" -#define NID_setct_CapRevResTBE 585 -#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L - -#define SN_setct_CredReqTBE "setct-CredReqTBE" -#define NID_setct_CredReqTBE 586 -#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L - -#define SN_setct_CredReqTBEX "setct-CredReqTBEX" -#define NID_setct_CredReqTBEX 587 -#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L - -#define SN_setct_CredResTBE "setct-CredResTBE" -#define NID_setct_CredResTBE 588 -#define OBJ_setct_CredResTBE OBJ_set_ctype,70L - -#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" -#define NID_setct_CredRevReqTBE 589 -#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L - -#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" -#define NID_setct_CredRevReqTBEX 590 -#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L - -#define SN_setct_CredRevResTBE "setct-CredRevResTBE" -#define NID_setct_CredRevResTBE 591 -#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L - -#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" -#define NID_setct_BatchAdminReqTBE 592 -#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L - -#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" -#define NID_setct_BatchAdminResTBE 593 -#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L - -#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" -#define NID_setct_RegFormReqTBE 594 -#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L - -#define SN_setct_CertReqTBE "setct-CertReqTBE" -#define NID_setct_CertReqTBE 595 -#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L - -#define SN_setct_CertReqTBEX "setct-CertReqTBEX" -#define NID_setct_CertReqTBEX 596 -#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L - -#define SN_setct_CertResTBE "setct-CertResTBE" -#define NID_setct_CertResTBE 597 -#define OBJ_setct_CertResTBE OBJ_set_ctype,79L - -#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" -#define NID_setct_CRLNotificationTBS 598 -#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L - -#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" -#define NID_setct_CRLNotificationResTBS 599 -#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L - -#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" -#define NID_setct_BCIDistributionTBS 600 -#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L - -#define SN_setext_genCrypt "setext-genCrypt" -#define LN_setext_genCrypt "generic cryptogram" -#define NID_setext_genCrypt 601 -#define OBJ_setext_genCrypt OBJ_set_msgExt,1L - -#define SN_setext_miAuth "setext-miAuth" -#define LN_setext_miAuth "merchant initiated auth" -#define NID_setext_miAuth 602 -#define OBJ_setext_miAuth OBJ_set_msgExt,3L - -#define SN_setext_pinSecure "setext-pinSecure" -#define NID_setext_pinSecure 603 -#define OBJ_setext_pinSecure OBJ_set_msgExt,4L - -#define SN_setext_pinAny "setext-pinAny" -#define NID_setext_pinAny 604 -#define OBJ_setext_pinAny OBJ_set_msgExt,5L - -#define SN_setext_track2 "setext-track2" -#define NID_setext_track2 605 -#define OBJ_setext_track2 OBJ_set_msgExt,7L - -#define SN_setext_cv "setext-cv" -#define LN_setext_cv "additional verification" -#define NID_setext_cv 606 -#define OBJ_setext_cv OBJ_set_msgExt,8L - -#define SN_set_policy_root "set-policy-root" -#define NID_set_policy_root 607 -#define OBJ_set_policy_root OBJ_set_policy,0L - -#define SN_setCext_hashedRoot "setCext-hashedRoot" -#define NID_setCext_hashedRoot 608 -#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L - -#define SN_setCext_certType "setCext-certType" -#define NID_setCext_certType 609 -#define OBJ_setCext_certType OBJ_set_certExt,1L - -#define SN_setCext_merchData "setCext-merchData" -#define NID_setCext_merchData 610 -#define OBJ_setCext_merchData OBJ_set_certExt,2L - -#define SN_setCext_cCertRequired "setCext-cCertRequired" -#define NID_setCext_cCertRequired 611 -#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L - -#define SN_setCext_tunneling "setCext-tunneling" -#define NID_setCext_tunneling 612 -#define OBJ_setCext_tunneling OBJ_set_certExt,4L - -#define SN_setCext_setExt "setCext-setExt" -#define NID_setCext_setExt 613 -#define OBJ_setCext_setExt OBJ_set_certExt,5L - -#define SN_setCext_setQualf "setCext-setQualf" -#define NID_setCext_setQualf 614 -#define OBJ_setCext_setQualf OBJ_set_certExt,6L - -#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" -#define NID_setCext_PGWYcapabilities 615 -#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L - -#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" -#define NID_setCext_TokenIdentifier 616 -#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L - -#define SN_setCext_Track2Data "setCext-Track2Data" -#define NID_setCext_Track2Data 617 -#define OBJ_setCext_Track2Data OBJ_set_certExt,9L - -#define SN_setCext_TokenType "setCext-TokenType" -#define NID_setCext_TokenType 618 -#define OBJ_setCext_TokenType OBJ_set_certExt,10L - -#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" -#define NID_setCext_IssuerCapabilities 619 -#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L - -#define SN_setAttr_Cert "setAttr-Cert" -#define NID_setAttr_Cert 620 -#define OBJ_setAttr_Cert OBJ_set_attr,0L - -#define SN_setAttr_PGWYcap "setAttr-PGWYcap" -#define LN_setAttr_PGWYcap "payment gateway capabilities" -#define NID_setAttr_PGWYcap 621 -#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L - -#define SN_setAttr_TokenType "setAttr-TokenType" -#define NID_setAttr_TokenType 622 -#define OBJ_setAttr_TokenType OBJ_set_attr,2L - -#define SN_setAttr_IssCap "setAttr-IssCap" -#define LN_setAttr_IssCap "issuer capabilities" -#define NID_setAttr_IssCap 623 -#define OBJ_setAttr_IssCap OBJ_set_attr,3L - -#define SN_set_rootKeyThumb "set-rootKeyThumb" -#define NID_set_rootKeyThumb 624 -#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L - -#define SN_set_addPolicy "set-addPolicy" -#define NID_set_addPolicy 625 -#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L - -#define SN_setAttr_Token_EMV "setAttr-Token-EMV" -#define NID_setAttr_Token_EMV 626 -#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L - -#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" -#define NID_setAttr_Token_B0Prime 627 -#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L - -#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" -#define NID_setAttr_IssCap_CVM 628 -#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L - -#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" -#define NID_setAttr_IssCap_T2 629 -#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L - -#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" -#define NID_setAttr_IssCap_Sig 630 -#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L - -#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" -#define LN_setAttr_GenCryptgrm "generate cryptogram" -#define NID_setAttr_GenCryptgrm 631 -#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L - -#define SN_setAttr_T2Enc "setAttr-T2Enc" -#define LN_setAttr_T2Enc "encrypted track 2" -#define NID_setAttr_T2Enc 632 -#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L - -#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" -#define LN_setAttr_T2cleartxt "cleartext track 2" -#define NID_setAttr_T2cleartxt 633 -#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L - -#define SN_setAttr_TokICCsig "setAttr-TokICCsig" -#define LN_setAttr_TokICCsig "ICC or token signature" -#define NID_setAttr_TokICCsig 634 -#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L - -#define SN_setAttr_SecDevSig "setAttr-SecDevSig" -#define LN_setAttr_SecDevSig "secure device signature" -#define NID_setAttr_SecDevSig 635 -#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L - -#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" -#define NID_set_brand_IATA_ATA 636 -#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L - -#define SN_set_brand_Diners "set-brand-Diners" -#define NID_set_brand_Diners 637 -#define OBJ_set_brand_Diners OBJ_set_brand,30L - -#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" -#define NID_set_brand_AmericanExpress 638 -#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L - -#define SN_set_brand_JCB "set-brand-JCB" -#define NID_set_brand_JCB 639 -#define OBJ_set_brand_JCB OBJ_set_brand,35L - -#define SN_set_brand_Visa "set-brand-Visa" -#define NID_set_brand_Visa 640 -#define OBJ_set_brand_Visa OBJ_set_brand,4L - -#define SN_set_brand_MasterCard "set-brand-MasterCard" -#define NID_set_brand_MasterCard 641 -#define OBJ_set_brand_MasterCard OBJ_set_brand,5L - -#define SN_set_brand_Novus "set-brand-Novus" -#define NID_set_brand_Novus 642 -#define OBJ_set_brand_Novus OBJ_set_brand,6011L - -#define SN_des_cdmf "DES-CDMF" -#define LN_des_cdmf "des-cdmf" -#define NID_des_cdmf 643 -#define OBJ_des_cdmf OBJ_rsadsi,3L,10L - -#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" -#define NID_rsaOAEPEncryptionSET 644 -#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L - -#define SN_ipsec3 "Oakley-EC2N-3" -#define LN_ipsec3 "ipsec3" -#define NID_ipsec3 749 - -#define SN_ipsec4 "Oakley-EC2N-4" -#define LN_ipsec4 "ipsec4" -#define NID_ipsec4 750 - -#define SN_whirlpool "whirlpool" -#define NID_whirlpool 804 -#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L - -#define SN_cryptopro "cryptopro" -#define NID_cryptopro 805 -#define OBJ_cryptopro OBJ_member_body,643L,2L,2L - -#define SN_cryptocom "cryptocom" -#define NID_cryptocom 806 -#define OBJ_cryptocom OBJ_member_body,643L,2L,9L - -#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" -#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" -#define NID_id_GostR3411_94_with_GostR3410_2001 807 -#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L - -#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" -#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" -#define NID_id_GostR3411_94_with_GostR3410_94 808 -#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L - -#define SN_id_GostR3411_94 "md_gost94" -#define LN_id_GostR3411_94 "GOST R 34.11-94" -#define NID_id_GostR3411_94 809 -#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L - -#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" -#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" -#define NID_id_HMACGostR3411_94 810 -#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L - -#define SN_id_GostR3410_2001 "gost2001" -#define LN_id_GostR3410_2001 "GOST R 34.10-2001" -#define NID_id_GostR3410_2001 811 -#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L - -#define SN_id_GostR3410_94 "gost94" -#define LN_id_GostR3410_94 "GOST R 34.10-94" -#define NID_id_GostR3410_94 812 -#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L - -#define SN_id_Gost28147_89 "gost89" -#define LN_id_Gost28147_89 "GOST 28147-89" -#define NID_id_Gost28147_89 813 -#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L - -#define SN_gost89_cnt "gost89-cnt" -#define NID_gost89_cnt 814 - -#define SN_id_Gost28147_89_MAC "gost-mac" -#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" -#define NID_id_Gost28147_89_MAC 815 -#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L - -#define SN_id_GostR3411_94_prf "prf-gostr3411-94" -#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" -#define NID_id_GostR3411_94_prf 816 -#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L - -#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" -#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" -#define NID_id_GostR3410_2001DH 817 -#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L - -#define SN_id_GostR3410_94DH "id-GostR3410-94DH" -#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" -#define NID_id_GostR3410_94DH 818 -#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L - -#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" -#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 -#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L - -#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" -#define NID_id_Gost28147_89_None_KeyMeshing 820 -#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L - -#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" -#define NID_id_GostR3411_94_TestParamSet 821 -#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L - -#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" -#define NID_id_GostR3411_94_CryptoProParamSet 822 -#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L - -#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" -#define NID_id_Gost28147_89_TestParamSet 823 -#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L - -#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 -#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L - -#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 -#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L - -#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 -#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L - -#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 -#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L - -#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 -#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L - -#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 -#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L - -#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 -#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L - -#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" -#define NID_id_GostR3410_94_TestParamSet 831 -#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L - -#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 -#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L - -#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 -#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L - -#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 -#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L - -#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 -#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L - -#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 -#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L - -#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 -#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L - -#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 -#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L - -#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" -#define NID_id_GostR3410_2001_TestParamSet 839 -#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L - -#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 -#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L - -#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 -#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L - -#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 -#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L - -#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 -#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L - -#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 -#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L - -#define SN_id_GostR3410_94_a "id-GostR3410-94-a" -#define NID_id_GostR3410_94_a 845 -#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L - -#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" -#define NID_id_GostR3410_94_aBis 846 -#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L - -#define SN_id_GostR3410_94_b "id-GostR3410-94-b" -#define NID_id_GostR3410_94_b 847 -#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L - -#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" -#define NID_id_GostR3410_94_bBis 848 -#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L - -#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" -#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" -#define NID_id_Gost28147_89_cc 849 -#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L - -#define SN_id_GostR3410_94_cc "gost94cc" -#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" -#define NID_id_GostR3410_94_cc 850 -#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L - -#define SN_id_GostR3410_2001_cc "gost2001cc" -#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" -#define NID_id_GostR3410_2001_cc 851 -#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L - -#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" -#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" -#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 -#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L - -#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" -#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" -#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 -#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L - -#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" -#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" -#define NID_id_GostR3410_2001_ParamSet_cc 854 -#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L - -#define SN_camellia_128_cbc "CAMELLIA-128-CBC" -#define LN_camellia_128_cbc "camellia-128-cbc" -#define NID_camellia_128_cbc 751 -#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L - -#define SN_camellia_192_cbc "CAMELLIA-192-CBC" -#define LN_camellia_192_cbc "camellia-192-cbc" -#define NID_camellia_192_cbc 752 -#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L - -#define SN_camellia_256_cbc "CAMELLIA-256-CBC" -#define LN_camellia_256_cbc "camellia-256-cbc" -#define NID_camellia_256_cbc 753 -#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L - -#define SN_id_camellia128_wrap "id-camellia128-wrap" -#define NID_id_camellia128_wrap 907 -#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L - -#define SN_id_camellia192_wrap "id-camellia192-wrap" -#define NID_id_camellia192_wrap 908 -#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L - -#define SN_id_camellia256_wrap "id-camellia256-wrap" -#define NID_id_camellia256_wrap 909 -#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L - -#define OBJ_ntt_ds 0L,3L,4401L,5L - -#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L - -#define SN_camellia_128_ecb "CAMELLIA-128-ECB" -#define LN_camellia_128_ecb "camellia-128-ecb" -#define NID_camellia_128_ecb 754 -#define OBJ_camellia_128_ecb OBJ_camellia,1L - -#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" -#define LN_camellia_128_ofb128 "camellia-128-ofb" -#define NID_camellia_128_ofb128 766 -#define OBJ_camellia_128_ofb128 OBJ_camellia,3L - -#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" -#define LN_camellia_128_cfb128 "camellia-128-cfb" -#define NID_camellia_128_cfb128 757 -#define OBJ_camellia_128_cfb128 OBJ_camellia,4L - -#define SN_camellia_192_ecb "CAMELLIA-192-ECB" -#define LN_camellia_192_ecb "camellia-192-ecb" -#define NID_camellia_192_ecb 755 -#define OBJ_camellia_192_ecb OBJ_camellia,21L - -#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" -#define LN_camellia_192_ofb128 "camellia-192-ofb" -#define NID_camellia_192_ofb128 767 -#define OBJ_camellia_192_ofb128 OBJ_camellia,23L - -#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" -#define LN_camellia_192_cfb128 "camellia-192-cfb" -#define NID_camellia_192_cfb128 758 -#define OBJ_camellia_192_cfb128 OBJ_camellia,24L - -#define SN_camellia_256_ecb "CAMELLIA-256-ECB" -#define LN_camellia_256_ecb "camellia-256-ecb" -#define NID_camellia_256_ecb 756 -#define OBJ_camellia_256_ecb OBJ_camellia,41L - -#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" -#define LN_camellia_256_ofb128 "camellia-256-ofb" -#define NID_camellia_256_ofb128 768 -#define OBJ_camellia_256_ofb128 OBJ_camellia,43L - -#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" -#define LN_camellia_256_cfb128 "camellia-256-cfb" -#define NID_camellia_256_cfb128 759 -#define OBJ_camellia_256_cfb128 OBJ_camellia,44L - -#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" -#define LN_camellia_128_cfb1 "camellia-128-cfb1" -#define NID_camellia_128_cfb1 760 - -#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" -#define LN_camellia_192_cfb1 "camellia-192-cfb1" -#define NID_camellia_192_cfb1 761 - -#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" -#define LN_camellia_256_cfb1 "camellia-256-cfb1" -#define NID_camellia_256_cfb1 762 - -#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" -#define LN_camellia_128_cfb8 "camellia-128-cfb8" -#define NID_camellia_128_cfb8 763 - -#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" -#define LN_camellia_192_cfb8 "camellia-192-cfb8" -#define NID_camellia_192_cfb8 764 - -#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" -#define LN_camellia_256_cfb8 "camellia-256-cfb8" -#define NID_camellia_256_cfb8 765 - -#define SN_kisa "KISA" -#define LN_kisa "kisa" -#define NID_kisa 773 -#define OBJ_kisa OBJ_member_body,410L,200004L - -#define SN_seed_ecb "SEED-ECB" -#define LN_seed_ecb "seed-ecb" -#define NID_seed_ecb 776 -#define OBJ_seed_ecb OBJ_kisa,1L,3L - -#define SN_seed_cbc "SEED-CBC" -#define LN_seed_cbc "seed-cbc" -#define NID_seed_cbc 777 -#define OBJ_seed_cbc OBJ_kisa,1L,4L - -#define SN_seed_cfb128 "SEED-CFB" -#define LN_seed_cfb128 "seed-cfb" -#define NID_seed_cfb128 779 -#define OBJ_seed_cfb128 OBJ_kisa,1L,5L - -#define SN_seed_ofb128 "SEED-OFB" -#define LN_seed_ofb128 "seed-ofb" -#define NID_seed_ofb128 778 -#define OBJ_seed_ofb128 OBJ_kisa,1L,6L - -#define SN_hmac "HMAC" -#define LN_hmac "hmac" -#define NID_hmac 855 - -#define SN_cmac "CMAC" -#define LN_cmac "cmac" -#define NID_cmac 894 - -#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" -#define LN_rc4_hmac_md5 "rc4-hmac-md5" -#define NID_rc4_hmac_md5 915 - -#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" -#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" -#define NID_aes_128_cbc_hmac_sha1 916 - -#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" -#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" -#define NID_aes_192_cbc_hmac_sha1 917 - -#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" -#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" -#define NID_aes_256_cbc_hmac_sha1 918 - -#define SN_aes_128_cbc_hmac_sha256 "AES-128-CBC-HMAC-SHA256" -#define LN_aes_128_cbc_hmac_sha256 "aes-128-cbc-hmac-sha256" -#define NID_aes_128_cbc_hmac_sha256 948 - -#define SN_aes_192_cbc_hmac_sha256 "AES-192-CBC-HMAC-SHA256" -#define LN_aes_192_cbc_hmac_sha256 "aes-192-cbc-hmac-sha256" -#define NID_aes_192_cbc_hmac_sha256 949 - -#define SN_aes_256_cbc_hmac_sha256 "AES-256-CBC-HMAC-SHA256" -#define LN_aes_256_cbc_hmac_sha256 "aes-256-cbc-hmac-sha256" -#define NID_aes_256_cbc_hmac_sha256 950 - -#define SN_dhpublicnumber "dhpublicnumber" -#define LN_dhpublicnumber "X9.42 DH" -#define NID_dhpublicnumber 920 -#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L - -#define SN_brainpoolP160r1 "brainpoolP160r1" -#define NID_brainpoolP160r1 921 -#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L - -#define SN_brainpoolP160t1 "brainpoolP160t1" -#define NID_brainpoolP160t1 922 -#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L - -#define SN_brainpoolP192r1 "brainpoolP192r1" -#define NID_brainpoolP192r1 923 -#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L - -#define SN_brainpoolP192t1 "brainpoolP192t1" -#define NID_brainpoolP192t1 924 -#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L - -#define SN_brainpoolP224r1 "brainpoolP224r1" -#define NID_brainpoolP224r1 925 -#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L - -#define SN_brainpoolP224t1 "brainpoolP224t1" -#define NID_brainpoolP224t1 926 -#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L - -#define SN_brainpoolP256r1 "brainpoolP256r1" -#define NID_brainpoolP256r1 927 -#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L - -#define SN_brainpoolP256t1 "brainpoolP256t1" -#define NID_brainpoolP256t1 928 -#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L - -#define SN_brainpoolP320r1 "brainpoolP320r1" -#define NID_brainpoolP320r1 929 -#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L - -#define SN_brainpoolP320t1 "brainpoolP320t1" -#define NID_brainpoolP320t1 930 -#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L - -#define SN_brainpoolP384r1 "brainpoolP384r1" -#define NID_brainpoolP384r1 931 -#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L - -#define SN_brainpoolP384t1 "brainpoolP384t1" -#define NID_brainpoolP384t1 932 -#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L - -#define SN_brainpoolP512r1 "brainpoolP512r1" -#define NID_brainpoolP512r1 933 -#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L - -#define SN_brainpoolP512t1 "brainpoolP512t1" -#define NID_brainpoolP512t1 934 -#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L - -#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L - -#define OBJ_secg_scheme OBJ_certicom_arc,1L - -#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" -#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 -#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L - -#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme" -#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 -#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L - -#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme" -#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938 -#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L - -#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme" -#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939 -#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L - -#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme" -#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940 -#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L - -#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941 -#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L - -#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 -#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L - -#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943 -#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L - -#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944 -#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L - -#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945 -#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L - -#define SN_dh_std_kdf "dh-std-kdf" -#define NID_dh_std_kdf 946 - -#define SN_dh_cofactor_kdf "dh-cofactor-kdf" -#define NID_dh_cofactor_kdf 947 - -#define SN_ct_precert_scts "ct_precert_scts" -#define LN_ct_precert_scts "CT Precertificate SCTs" -#define NID_ct_precert_scts 951 -#define OBJ_ct_precert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L - -#define SN_ct_precert_poison "ct_precert_poison" -#define LN_ct_precert_poison "CT Precertificate Poison" -#define NID_ct_precert_poison 952 -#define OBJ_ct_precert_poison 1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L - -#define SN_ct_precert_signer "ct_precert_signer" -#define LN_ct_precert_signer "CT Precertificate Signer" -#define NID_ct_precert_signer 953 -#define OBJ_ct_precert_signer 1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L - -#define SN_ct_cert_scts "ct_cert_scts" -#define LN_ct_cert_scts "CT Certificate SCTs" -#define NID_ct_cert_scts 954 -#define OBJ_ct_cert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L - -#define SN_jurisdictionLocalityName "jurisdictionL" -#define LN_jurisdictionLocalityName "jurisdictionLocalityName" -#define NID_jurisdictionLocalityName 955 -#define OBJ_jurisdictionLocalityName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,1L - -#define SN_jurisdictionStateOrProvinceName "jurisdictionST" -#define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" -#define NID_jurisdictionStateOrProvinceName 956 -#define OBJ_jurisdictionStateOrProvinceName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,2L - -#define SN_jurisdictionCountryName "jurisdictionC" -#define LN_jurisdictionCountryName "jurisdictionCountryName" -#define NID_jurisdictionCountryName 957 -#define OBJ_jurisdictionCountryName 1L,3L,6L,1L,4L,1L,311L,60L,2L,1L,3L diff --git a/Sources/COpenSSL/obj_xref.h b/Sources/COpenSSL/obj_xref.h deleted file mode 100644 index e453e99f..00000000 --- a/Sources/COpenSSL/obj_xref.h +++ /dev/null @@ -1,99 +0,0 @@ -/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */ - -typedef struct { - int sign_id; - int hash_id; - int pkey_id; -} nid_triple; - -static const nid_triple sigoid_srt[] = { - {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption}, - {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, - {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption}, - {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, - {NID_dsaWithSHA, NID_sha, NID_dsa}, - {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, - {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption}, - {NID_md5WithRSA, NID_md5, NID_rsa}, - {NID_dsaWithSHA1, NID_sha1, NID_dsa}, - {NID_sha1WithRSA, NID_sha1, NID_rsa}, - {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption}, - {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, - {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey}, - {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, - {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, - {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, - {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, - {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey}, - {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, - {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, - {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, - NID_id_GostR3410_2001}, - {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, - NID_id_GostR3410_94}, - {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, - NID_id_GostR3410_94_cc}, - {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, - NID_id_GostR3410_2001_cc}, - {NID_rsassaPss, NID_undef, NID_rsaEncryption}, - {NID_dhSinglePass_stdDH_sha1kdf_scheme, NID_sha1, NID_dh_std_kdf}, - {NID_dhSinglePass_stdDH_sha224kdf_scheme, NID_sha224, NID_dh_std_kdf}, - {NID_dhSinglePass_stdDH_sha256kdf_scheme, NID_sha256, NID_dh_std_kdf}, - {NID_dhSinglePass_stdDH_sha384kdf_scheme, NID_sha384, NID_dh_std_kdf}, - {NID_dhSinglePass_stdDH_sha512kdf_scheme, NID_sha512, NID_dh_std_kdf}, - {NID_dhSinglePass_cofactorDH_sha1kdf_scheme, NID_sha1, - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha224kdf_scheme, NID_sha224, - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha256kdf_scheme, NID_sha256, - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha384kdf_scheme, NID_sha384, - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha512kdf_scheme, NID_sha512, - NID_dh_cofactor_kdf}, -}; - -static const nid_triple *const sigoid_srt_xref[] = { - &sigoid_srt[0], - &sigoid_srt[1], - &sigoid_srt[7], - &sigoid_srt[2], - &sigoid_srt[4], - &sigoid_srt[3], - &sigoid_srt[9], - &sigoid_srt[5], - &sigoid_srt[8], - &sigoid_srt[12], - &sigoid_srt[30], - &sigoid_srt[35], - &sigoid_srt[6], - &sigoid_srt[10], - &sigoid_srt[11], - &sigoid_srt[13], - &sigoid_srt[24], - &sigoid_srt[20], - &sigoid_srt[32], - &sigoid_srt[37], - &sigoid_srt[14], - &sigoid_srt[21], - &sigoid_srt[33], - &sigoid_srt[38], - &sigoid_srt[15], - &sigoid_srt[22], - &sigoid_srt[34], - &sigoid_srt[39], - &sigoid_srt[16], - &sigoid_srt[23], - &sigoid_srt[19], - &sigoid_srt[31], - &sigoid_srt[36], - &sigoid_srt[25], - &sigoid_srt[26], - &sigoid_srt[27], - &sigoid_srt[28], -}; diff --git a/Sources/COpenSSL/objects.h b/Sources/COpenSSL/objects.h deleted file mode 100644 index 3f31429b..00000000 --- a/Sources/COpenSSL/objects.h +++ /dev/null @@ -1,1143 +0,0 @@ -/* crypto/objects/objects.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_OBJECTS_H -# define HEADER_OBJECTS_H - -# define USE_OBJ_MAC - -# ifdef USE_OBJ_MAC -# include "obj_mac.h" -# else -# define SN_undef "UNDEF" -# define LN_undef "undefined" -# define NID_undef 0 -# define OBJ_undef 0L - -# define SN_Algorithm "Algorithm" -# define LN_algorithm "algorithm" -# define NID_algorithm 38 -# define OBJ_algorithm 1L,3L,14L,3L,2L - -# define LN_rsadsi "rsadsi" -# define NID_rsadsi 1 -# define OBJ_rsadsi 1L,2L,840L,113549L - -# define LN_pkcs "pkcs" -# define NID_pkcs 2 -# define OBJ_pkcs OBJ_rsadsi,1L - -# define SN_md2 "MD2" -# define LN_md2 "md2" -# define NID_md2 3 -# define OBJ_md2 OBJ_rsadsi,2L,2L - -# define SN_md5 "MD5" -# define LN_md5 "md5" -# define NID_md5 4 -# define OBJ_md5 OBJ_rsadsi,2L,5L - -# define SN_rc4 "RC4" -# define LN_rc4 "rc4" -# define NID_rc4 5 -# define OBJ_rc4 OBJ_rsadsi,3L,4L - -# define LN_rsaEncryption "rsaEncryption" -# define NID_rsaEncryption 6 -# define OBJ_rsaEncryption OBJ_pkcs,1L,1L - -# define SN_md2WithRSAEncryption "RSA-MD2" -# define LN_md2WithRSAEncryption "md2WithRSAEncryption" -# define NID_md2WithRSAEncryption 7 -# define OBJ_md2WithRSAEncryption OBJ_pkcs,1L,2L - -# define SN_md5WithRSAEncryption "RSA-MD5" -# define LN_md5WithRSAEncryption "md5WithRSAEncryption" -# define NID_md5WithRSAEncryption 8 -# define OBJ_md5WithRSAEncryption OBJ_pkcs,1L,4L - -# define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" -# define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" -# define NID_pbeWithMD2AndDES_CBC 9 -# define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs,5L,1L - -# define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" -# define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" -# define NID_pbeWithMD5AndDES_CBC 10 -# define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs,5L,3L - -# define LN_X500 "X500" -# define NID_X500 11 -# define OBJ_X500 2L,5L - -# define LN_X509 "X509" -# define NID_X509 12 -# define OBJ_X509 OBJ_X500,4L - -# define SN_commonName "CN" -# define LN_commonName "commonName" -# define NID_commonName 13 -# define OBJ_commonName OBJ_X509,3L - -# define SN_countryName "C" -# define LN_countryName "countryName" -# define NID_countryName 14 -# define OBJ_countryName OBJ_X509,6L - -# define SN_localityName "L" -# define LN_localityName "localityName" -# define NID_localityName 15 -# define OBJ_localityName OBJ_X509,7L - -/* Postal Address? PA */ - -/* should be "ST" (rfc1327) but MS uses 'S' */ -# define SN_stateOrProvinceName "ST" -# define LN_stateOrProvinceName "stateOrProvinceName" -# define NID_stateOrProvinceName 16 -# define OBJ_stateOrProvinceName OBJ_X509,8L - -# define SN_organizationName "O" -# define LN_organizationName "organizationName" -# define NID_organizationName 17 -# define OBJ_organizationName OBJ_X509,10L - -# define SN_organizationalUnitName "OU" -# define LN_organizationalUnitName "organizationalUnitName" -# define NID_organizationalUnitName 18 -# define OBJ_organizationalUnitName OBJ_X509,11L - -# define SN_rsa "RSA" -# define LN_rsa "rsa" -# define NID_rsa 19 -# define OBJ_rsa OBJ_X500,8L,1L,1L - -# define LN_pkcs7 "pkcs7" -# define NID_pkcs7 20 -# define OBJ_pkcs7 OBJ_pkcs,7L - -# define LN_pkcs7_data "pkcs7-data" -# define NID_pkcs7_data 21 -# define OBJ_pkcs7_data OBJ_pkcs7,1L - -# define LN_pkcs7_signed "pkcs7-signedData" -# define NID_pkcs7_signed 22 -# define OBJ_pkcs7_signed OBJ_pkcs7,2L - -# define LN_pkcs7_enveloped "pkcs7-envelopedData" -# define NID_pkcs7_enveloped 23 -# define OBJ_pkcs7_enveloped OBJ_pkcs7,3L - -# define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" -# define NID_pkcs7_signedAndEnveloped 24 -# define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L - -# define LN_pkcs7_digest "pkcs7-digestData" -# define NID_pkcs7_digest 25 -# define OBJ_pkcs7_digest OBJ_pkcs7,5L - -# define LN_pkcs7_encrypted "pkcs7-encryptedData" -# define NID_pkcs7_encrypted 26 -# define OBJ_pkcs7_encrypted OBJ_pkcs7,6L - -# define LN_pkcs3 "pkcs3" -# define NID_pkcs3 27 -# define OBJ_pkcs3 OBJ_pkcs,3L - -# define LN_dhKeyAgreement "dhKeyAgreement" -# define NID_dhKeyAgreement 28 -# define OBJ_dhKeyAgreement OBJ_pkcs3,1L - -# define SN_des_ecb "DES-ECB" -# define LN_des_ecb "des-ecb" -# define NID_des_ecb 29 -# define OBJ_des_ecb OBJ_algorithm,6L - -# define SN_des_cfb64 "DES-CFB" -# define LN_des_cfb64 "des-cfb" -# define NID_des_cfb64 30 -/* IV + num */ -# define OBJ_des_cfb64 OBJ_algorithm,9L - -# define SN_des_cbc "DES-CBC" -# define LN_des_cbc "des-cbc" -# define NID_des_cbc 31 -/* IV */ -# define OBJ_des_cbc OBJ_algorithm,7L - -# define SN_des_ede "DES-EDE" -# define LN_des_ede "des-ede" -# define NID_des_ede 32 -/* ?? */ -# define OBJ_des_ede OBJ_algorithm,17L - -# define SN_des_ede3 "DES-EDE3" -# define LN_des_ede3 "des-ede3" -# define NID_des_ede3 33 - -# define SN_idea_cbc "IDEA-CBC" -# define LN_idea_cbc "idea-cbc" -# define NID_idea_cbc 34 -# define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L - -# define SN_idea_cfb64 "IDEA-CFB" -# define LN_idea_cfb64 "idea-cfb" -# define NID_idea_cfb64 35 - -# define SN_idea_ecb "IDEA-ECB" -# define LN_idea_ecb "idea-ecb" -# define NID_idea_ecb 36 - -# define SN_rc2_cbc "RC2-CBC" -# define LN_rc2_cbc "rc2-cbc" -# define NID_rc2_cbc 37 -# define OBJ_rc2_cbc OBJ_rsadsi,3L,2L - -# define SN_rc2_ecb "RC2-ECB" -# define LN_rc2_ecb "rc2-ecb" -# define NID_rc2_ecb 38 - -# define SN_rc2_cfb64 "RC2-CFB" -# define LN_rc2_cfb64 "rc2-cfb" -# define NID_rc2_cfb64 39 - -# define SN_rc2_ofb64 "RC2-OFB" -# define LN_rc2_ofb64 "rc2-ofb" -# define NID_rc2_ofb64 40 - -# define SN_sha "SHA" -# define LN_sha "sha" -# define NID_sha 41 -# define OBJ_sha OBJ_algorithm,18L - -# define SN_shaWithRSAEncryption "RSA-SHA" -# define LN_shaWithRSAEncryption "shaWithRSAEncryption" -# define NID_shaWithRSAEncryption 42 -# define OBJ_shaWithRSAEncryption OBJ_algorithm,15L - -# define SN_des_ede_cbc "DES-EDE-CBC" -# define LN_des_ede_cbc "des-ede-cbc" -# define NID_des_ede_cbc 43 - -# define SN_des_ede3_cbc "DES-EDE3-CBC" -# define LN_des_ede3_cbc "des-ede3-cbc" -# define NID_des_ede3_cbc 44 -# define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L - -# define SN_des_ofb64 "DES-OFB" -# define LN_des_ofb64 "des-ofb" -# define NID_des_ofb64 45 -# define OBJ_des_ofb64 OBJ_algorithm,8L - -# define SN_idea_ofb64 "IDEA-OFB" -# define LN_idea_ofb64 "idea-ofb" -# define NID_idea_ofb64 46 - -# define LN_pkcs9 "pkcs9" -# define NID_pkcs9 47 -# define OBJ_pkcs9 OBJ_pkcs,9L - -# define SN_pkcs9_emailAddress "Email" -# define LN_pkcs9_emailAddress "emailAddress" -# define NID_pkcs9_emailAddress 48 -# define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L - -# define LN_pkcs9_unstructuredName "unstructuredName" -# define NID_pkcs9_unstructuredName 49 -# define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L - -# define LN_pkcs9_contentType "contentType" -# define NID_pkcs9_contentType 50 -# define OBJ_pkcs9_contentType OBJ_pkcs9,3L - -# define LN_pkcs9_messageDigest "messageDigest" -# define NID_pkcs9_messageDigest 51 -# define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L - -# define LN_pkcs9_signingTime "signingTime" -# define NID_pkcs9_signingTime 52 -# define OBJ_pkcs9_signingTime OBJ_pkcs9,5L - -# define LN_pkcs9_countersignature "countersignature" -# define NID_pkcs9_countersignature 53 -# define OBJ_pkcs9_countersignature OBJ_pkcs9,6L - -# define LN_pkcs9_challengePassword "challengePassword" -# define NID_pkcs9_challengePassword 54 -# define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L - -# define LN_pkcs9_unstructuredAddress "unstructuredAddress" -# define NID_pkcs9_unstructuredAddress 55 -# define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L - -# define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" -# define NID_pkcs9_extCertAttributes 56 -# define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L - -# define SN_netscape "Netscape" -# define LN_netscape "Netscape Communications Corp." -# define NID_netscape 57 -# define OBJ_netscape 2L,16L,840L,1L,113730L - -# define SN_netscape_cert_extension "nsCertExt" -# define LN_netscape_cert_extension "Netscape Certificate Extension" -# define NID_netscape_cert_extension 58 -# define OBJ_netscape_cert_extension OBJ_netscape,1L - -# define SN_netscape_data_type "nsDataType" -# define LN_netscape_data_type "Netscape Data Type" -# define NID_netscape_data_type 59 -# define OBJ_netscape_data_type OBJ_netscape,2L - -# define SN_des_ede_cfb64 "DES-EDE-CFB" -# define LN_des_ede_cfb64 "des-ede-cfb" -# define NID_des_ede_cfb64 60 - -# define SN_des_ede3_cfb64 "DES-EDE3-CFB" -# define LN_des_ede3_cfb64 "des-ede3-cfb" -# define NID_des_ede3_cfb64 61 - -# define SN_des_ede_ofb64 "DES-EDE-OFB" -# define LN_des_ede_ofb64 "des-ede-ofb" -# define NID_des_ede_ofb64 62 - -# define SN_des_ede3_ofb64 "DES-EDE3-OFB" -# define LN_des_ede3_ofb64 "des-ede3-ofb" -# define NID_des_ede3_ofb64 63 - -/* I'm not sure about the object ID */ -# define SN_sha1 "SHA1" -# define LN_sha1 "sha1" -# define NID_sha1 64 -# define OBJ_sha1 OBJ_algorithm,26L -/* 28 Jun 1996 - eay */ -/* #define OBJ_sha1 1L,3L,14L,2L,26L,05L <- wrong */ - -# define SN_sha1WithRSAEncryption "RSA-SHA1" -# define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" -# define NID_sha1WithRSAEncryption 65 -# define OBJ_sha1WithRSAEncryption OBJ_pkcs,1L,5L - -# define SN_dsaWithSHA "DSA-SHA" -# define LN_dsaWithSHA "dsaWithSHA" -# define NID_dsaWithSHA 66 -# define OBJ_dsaWithSHA OBJ_algorithm,13L - -# define SN_dsa_2 "DSA-old" -# define LN_dsa_2 "dsaEncryption-old" -# define NID_dsa_2 67 -# define OBJ_dsa_2 OBJ_algorithm,12L - -/* proposed by microsoft to RSA */ -# define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" -# define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" -# define NID_pbeWithSHA1AndRC2_CBC 68 -# define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs,5L,11L - -/* - * proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now defined - * explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something completely - * different. - */ -# define LN_id_pbkdf2 "PBKDF2" -# define NID_id_pbkdf2 69 -# define OBJ_id_pbkdf2 OBJ_pkcs,5L,12L - -# define SN_dsaWithSHA1_2 "DSA-SHA1-old" -# define LN_dsaWithSHA1_2 "dsaWithSHA1-old" -# define NID_dsaWithSHA1_2 70 -/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */ -# define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L - -# define SN_netscape_cert_type "nsCertType" -# define LN_netscape_cert_type "Netscape Cert Type" -# define NID_netscape_cert_type 71 -# define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L - -# define SN_netscape_base_url "nsBaseUrl" -# define LN_netscape_base_url "Netscape Base Url" -# define NID_netscape_base_url 72 -# define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L - -# define SN_netscape_revocation_url "nsRevocationUrl" -# define LN_netscape_revocation_url "Netscape Revocation Url" -# define NID_netscape_revocation_url 73 -# define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L - -# define SN_netscape_ca_revocation_url "nsCaRevocationUrl" -# define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" -# define NID_netscape_ca_revocation_url 74 -# define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L - -# define SN_netscape_renewal_url "nsRenewalUrl" -# define LN_netscape_renewal_url "Netscape Renewal Url" -# define NID_netscape_renewal_url 75 -# define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L - -# define SN_netscape_ca_policy_url "nsCaPolicyUrl" -# define LN_netscape_ca_policy_url "Netscape CA Policy Url" -# define NID_netscape_ca_policy_url 76 -# define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L - -# define SN_netscape_ssl_server_name "nsSslServerName" -# define LN_netscape_ssl_server_name "Netscape SSL Server Name" -# define NID_netscape_ssl_server_name 77 -# define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L - -# define SN_netscape_comment "nsComment" -# define LN_netscape_comment "Netscape Comment" -# define NID_netscape_comment 78 -# define OBJ_netscape_comment OBJ_netscape_cert_extension,13L - -# define SN_netscape_cert_sequence "nsCertSequence" -# define LN_netscape_cert_sequence "Netscape Certificate Sequence" -# define NID_netscape_cert_sequence 79 -# define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L - -# define SN_desx_cbc "DESX-CBC" -# define LN_desx_cbc "desx-cbc" -# define NID_desx_cbc 80 - -# define SN_id_ce "id-ce" -# define NID_id_ce 81 -# define OBJ_id_ce 2L,5L,29L - -# define SN_subject_key_identifier "subjectKeyIdentifier" -# define LN_subject_key_identifier "X509v3 Subject Key Identifier" -# define NID_subject_key_identifier 82 -# define OBJ_subject_key_identifier OBJ_id_ce,14L - -# define SN_key_usage "keyUsage" -# define LN_key_usage "X509v3 Key Usage" -# define NID_key_usage 83 -# define OBJ_key_usage OBJ_id_ce,15L - -# define SN_private_key_usage_period "privateKeyUsagePeriod" -# define LN_private_key_usage_period "X509v3 Private Key Usage Period" -# define NID_private_key_usage_period 84 -# define OBJ_private_key_usage_period OBJ_id_ce,16L - -# define SN_subject_alt_name "subjectAltName" -# define LN_subject_alt_name "X509v3 Subject Alternative Name" -# define NID_subject_alt_name 85 -# define OBJ_subject_alt_name OBJ_id_ce,17L - -# define SN_issuer_alt_name "issuerAltName" -# define LN_issuer_alt_name "X509v3 Issuer Alternative Name" -# define NID_issuer_alt_name 86 -# define OBJ_issuer_alt_name OBJ_id_ce,18L - -# define SN_basic_constraints "basicConstraints" -# define LN_basic_constraints "X509v3 Basic Constraints" -# define NID_basic_constraints 87 -# define OBJ_basic_constraints OBJ_id_ce,19L - -# define SN_crl_number "crlNumber" -# define LN_crl_number "X509v3 CRL Number" -# define NID_crl_number 88 -# define OBJ_crl_number OBJ_id_ce,20L - -# define SN_certificate_policies "certificatePolicies" -# define LN_certificate_policies "X509v3 Certificate Policies" -# define NID_certificate_policies 89 -# define OBJ_certificate_policies OBJ_id_ce,32L - -# define SN_authority_key_identifier "authorityKeyIdentifier" -# define LN_authority_key_identifier "X509v3 Authority Key Identifier" -# define NID_authority_key_identifier 90 -# define OBJ_authority_key_identifier OBJ_id_ce,35L - -# define SN_bf_cbc "BF-CBC" -# define LN_bf_cbc "bf-cbc" -# define NID_bf_cbc 91 -# define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L - -# define SN_bf_ecb "BF-ECB" -# define LN_bf_ecb "bf-ecb" -# define NID_bf_ecb 92 - -# define SN_bf_cfb64 "BF-CFB" -# define LN_bf_cfb64 "bf-cfb" -# define NID_bf_cfb64 93 - -# define SN_bf_ofb64 "BF-OFB" -# define LN_bf_ofb64 "bf-ofb" -# define NID_bf_ofb64 94 - -# define SN_mdc2 "MDC2" -# define LN_mdc2 "mdc2" -# define NID_mdc2 95 -# define OBJ_mdc2 2L,5L,8L,3L,101L -/* An alternative? 1L,3L,14L,3L,2L,19L */ - -# define SN_mdc2WithRSA "RSA-MDC2" -# define LN_mdc2WithRSA "mdc2withRSA" -# define NID_mdc2WithRSA 96 -# define OBJ_mdc2WithRSA 2L,5L,8L,3L,100L - -# define SN_rc4_40 "RC4-40" -# define LN_rc4_40 "rc4-40" -# define NID_rc4_40 97 - -# define SN_rc2_40_cbc "RC2-40-CBC" -# define LN_rc2_40_cbc "rc2-40-cbc" -# define NID_rc2_40_cbc 98 - -# define SN_givenName "G" -# define LN_givenName "givenName" -# define NID_givenName 99 -# define OBJ_givenName OBJ_X509,42L - -# define SN_surname "S" -# define LN_surname "surname" -# define NID_surname 100 -# define OBJ_surname OBJ_X509,4L - -# define SN_initials "I" -# define LN_initials "initials" -# define NID_initials 101 -# define OBJ_initials OBJ_X509,43L - -# define SN_uniqueIdentifier "UID" -# define LN_uniqueIdentifier "uniqueIdentifier" -# define NID_uniqueIdentifier 102 -# define OBJ_uniqueIdentifier OBJ_X509,45L - -# define SN_crl_distribution_points "crlDistributionPoints" -# define LN_crl_distribution_points "X509v3 CRL Distribution Points" -# define NID_crl_distribution_points 103 -# define OBJ_crl_distribution_points OBJ_id_ce,31L - -# define SN_md5WithRSA "RSA-NP-MD5" -# define LN_md5WithRSA "md5WithRSA" -# define NID_md5WithRSA 104 -# define OBJ_md5WithRSA OBJ_algorithm,3L - -# define SN_serialNumber "SN" -# define LN_serialNumber "serialNumber" -# define NID_serialNumber 105 -# define OBJ_serialNumber OBJ_X509,5L - -# define SN_title "T" -# define LN_title "title" -# define NID_title 106 -# define OBJ_title OBJ_X509,12L - -# define SN_description "D" -# define LN_description "description" -# define NID_description 107 -# define OBJ_description OBJ_X509,13L - -/* CAST5 is CAST-128, I'm just sticking with the documentation */ -# define SN_cast5_cbc "CAST5-CBC" -# define LN_cast5_cbc "cast5-cbc" -# define NID_cast5_cbc 108 -# define OBJ_cast5_cbc 1L,2L,840L,113533L,7L,66L,10L - -# define SN_cast5_ecb "CAST5-ECB" -# define LN_cast5_ecb "cast5-ecb" -# define NID_cast5_ecb 109 - -# define SN_cast5_cfb64 "CAST5-CFB" -# define LN_cast5_cfb64 "cast5-cfb" -# define NID_cast5_cfb64 110 - -# define SN_cast5_ofb64 "CAST5-OFB" -# define LN_cast5_ofb64 "cast5-ofb" -# define NID_cast5_ofb64 111 - -# define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" -# define NID_pbeWithMD5AndCast5_CBC 112 -# define OBJ_pbeWithMD5AndCast5_CBC 1L,2L,840L,113533L,7L,66L,12L - -/*- - * This is one sun will soon be using :-( - * id-dsa-with-sha1 ID ::= { - * iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 } - */ -# define SN_dsaWithSHA1 "DSA-SHA1" -# define LN_dsaWithSHA1 "dsaWithSHA1" -# define NID_dsaWithSHA1 113 -# define OBJ_dsaWithSHA1 1L,2L,840L,10040L,4L,3L - -# define NID_md5_sha1 114 -# define SN_md5_sha1 "MD5-SHA1" -# define LN_md5_sha1 "md5-sha1" - -# define SN_sha1WithRSA "RSA-SHA1-2" -# define LN_sha1WithRSA "sha1WithRSA" -# define NID_sha1WithRSA 115 -# define OBJ_sha1WithRSA OBJ_algorithm,29L - -# define SN_dsa "DSA" -# define LN_dsa "dsaEncryption" -# define NID_dsa 116 -# define OBJ_dsa 1L,2L,840L,10040L,4L,1L - -# define SN_ripemd160 "RIPEMD160" -# define LN_ripemd160 "ripemd160" -# define NID_ripemd160 117 -# define OBJ_ripemd160 1L,3L,36L,3L,2L,1L - -/* - * The name should actually be rsaSignatureWithripemd160, but I'm going to - * continue using the convention I'm using with the other ciphers - */ -# define SN_ripemd160WithRSA "RSA-RIPEMD160" -# define LN_ripemd160WithRSA "ripemd160WithRSA" -# define NID_ripemd160WithRSA 119 -# define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L - -/*- - * Taken from rfc2040 - * RC5_CBC_Parameters ::= SEQUENCE { - * version INTEGER (v1_0(16)), - * rounds INTEGER (8..127), - * blockSizeInBits INTEGER (64, 128), - * iv OCTET STRING OPTIONAL - * } - */ -# define SN_rc5_cbc "RC5-CBC" -# define LN_rc5_cbc "rc5-cbc" -# define NID_rc5_cbc 120 -# define OBJ_rc5_cbc OBJ_rsadsi,3L,8L - -# define SN_rc5_ecb "RC5-ECB" -# define LN_rc5_ecb "rc5-ecb" -# define NID_rc5_ecb 121 - -# define SN_rc5_cfb64 "RC5-CFB" -# define LN_rc5_cfb64 "rc5-cfb" -# define NID_rc5_cfb64 122 - -# define SN_rc5_ofb64 "RC5-OFB" -# define LN_rc5_ofb64 "rc5-ofb" -# define NID_rc5_ofb64 123 - -# define SN_rle_compression "RLE" -# define LN_rle_compression "run length compression" -# define NID_rle_compression 124 -# define OBJ_rle_compression 1L,1L,1L,1L,666L,1L - -# define SN_zlib_compression "ZLIB" -# define LN_zlib_compression "zlib compression" -# define NID_zlib_compression 125 -# define OBJ_zlib_compression 1L,1L,1L,1L,666L,2L - -# define SN_ext_key_usage "extendedKeyUsage" -# define LN_ext_key_usage "X509v3 Extended Key Usage" -# define NID_ext_key_usage 126 -# define OBJ_ext_key_usage OBJ_id_ce,37 - -# define SN_id_pkix "PKIX" -# define NID_id_pkix 127 -# define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L - -# define SN_id_kp "id-kp" -# define NID_id_kp 128 -# define OBJ_id_kp OBJ_id_pkix,3L - -/* PKIX extended key usage OIDs */ - -# define SN_server_auth "serverAuth" -# define LN_server_auth "TLS Web Server Authentication" -# define NID_server_auth 129 -# define OBJ_server_auth OBJ_id_kp,1L - -# define SN_client_auth "clientAuth" -# define LN_client_auth "TLS Web Client Authentication" -# define NID_client_auth 130 -# define OBJ_client_auth OBJ_id_kp,2L - -# define SN_code_sign "codeSigning" -# define LN_code_sign "Code Signing" -# define NID_code_sign 131 -# define OBJ_code_sign OBJ_id_kp,3L - -# define SN_email_protect "emailProtection" -# define LN_email_protect "E-mail Protection" -# define NID_email_protect 132 -# define OBJ_email_protect OBJ_id_kp,4L - -# define SN_time_stamp "timeStamping" -# define LN_time_stamp "Time Stamping" -# define NID_time_stamp 133 -# define OBJ_time_stamp OBJ_id_kp,8L - -/* Additional extended key usage OIDs: Microsoft */ - -# define SN_ms_code_ind "msCodeInd" -# define LN_ms_code_ind "Microsoft Individual Code Signing" -# define NID_ms_code_ind 134 -# define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L - -# define SN_ms_code_com "msCodeCom" -# define LN_ms_code_com "Microsoft Commercial Code Signing" -# define NID_ms_code_com 135 -# define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L - -# define SN_ms_ctl_sign "msCTLSign" -# define LN_ms_ctl_sign "Microsoft Trust List Signing" -# define NID_ms_ctl_sign 136 -# define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L - -# define SN_ms_sgc "msSGC" -# define LN_ms_sgc "Microsoft Server Gated Crypto" -# define NID_ms_sgc 137 -# define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L - -# define SN_ms_efs "msEFS" -# define LN_ms_efs "Microsoft Encrypted File System" -# define NID_ms_efs 138 -# define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L - -/* Additional usage: Netscape */ - -# define SN_ns_sgc "nsSGC" -# define LN_ns_sgc "Netscape Server Gated Crypto" -# define NID_ns_sgc 139 -# define OBJ_ns_sgc OBJ_netscape,4L,1L - -# define SN_delta_crl "deltaCRL" -# define LN_delta_crl "X509v3 Delta CRL Indicator" -# define NID_delta_crl 140 -# define OBJ_delta_crl OBJ_id_ce,27L - -# define SN_crl_reason "CRLReason" -# define LN_crl_reason "CRL Reason Code" -# define NID_crl_reason 141 -# define OBJ_crl_reason OBJ_id_ce,21L - -# define SN_invalidity_date "invalidityDate" -# define LN_invalidity_date "Invalidity Date" -# define NID_invalidity_date 142 -# define OBJ_invalidity_date OBJ_id_ce,24L - -# define SN_sxnet "SXNetID" -# define LN_sxnet "Strong Extranet ID" -# define NID_sxnet 143 -# define OBJ_sxnet 1L,3L,101L,1L,4L,1L - -/* PKCS12 and related OBJECT IDENTIFIERS */ - -# define OBJ_pkcs12 OBJ_pkcs,12L -# define OBJ_pkcs12_pbeids OBJ_pkcs12, 1 - -# define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" -# define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" -# define NID_pbe_WithSHA1And128BitRC4 144 -# define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids, 1L - -# define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" -# define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" -# define NID_pbe_WithSHA1And40BitRC4 145 -# define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids, 2L - -# define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" -# define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" -# define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 -# define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L - -# define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" -# define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" -# define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 -# define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L - -# define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" -# define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" -# define NID_pbe_WithSHA1And128BitRC2_CBC 148 -# define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids, 5L - -# define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" -# define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" -# define NID_pbe_WithSHA1And40BitRC2_CBC 149 -# define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L - -# define OBJ_pkcs12_Version1 OBJ_pkcs12, 10L - -# define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1, 1L - -# define LN_keyBag "keyBag" -# define NID_keyBag 150 -# define OBJ_keyBag OBJ_pkcs12_BagIds, 1L - -# define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" -# define NID_pkcs8ShroudedKeyBag 151 -# define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L - -# define LN_certBag "certBag" -# define NID_certBag 152 -# define OBJ_certBag OBJ_pkcs12_BagIds, 3L - -# define LN_crlBag "crlBag" -# define NID_crlBag 153 -# define OBJ_crlBag OBJ_pkcs12_BagIds, 4L - -# define LN_secretBag "secretBag" -# define NID_secretBag 154 -# define OBJ_secretBag OBJ_pkcs12_BagIds, 5L - -# define LN_safeContentsBag "safeContentsBag" -# define NID_safeContentsBag 155 -# define OBJ_safeContentsBag OBJ_pkcs12_BagIds, 6L - -# define LN_friendlyName "friendlyName" -# define NID_friendlyName 156 -# define OBJ_friendlyName OBJ_pkcs9, 20L - -# define LN_localKeyID "localKeyID" -# define NID_localKeyID 157 -# define OBJ_localKeyID OBJ_pkcs9, 21L - -# define OBJ_certTypes OBJ_pkcs9, 22L - -# define LN_x509Certificate "x509Certificate" -# define NID_x509Certificate 158 -# define OBJ_x509Certificate OBJ_certTypes, 1L - -# define LN_sdsiCertificate "sdsiCertificate" -# define NID_sdsiCertificate 159 -# define OBJ_sdsiCertificate OBJ_certTypes, 2L - -# define OBJ_crlTypes OBJ_pkcs9, 23L - -# define LN_x509Crl "x509Crl" -# define NID_x509Crl 160 -# define OBJ_x509Crl OBJ_crlTypes, 1L - -/* PKCS#5 v2 OIDs */ - -# define LN_pbes2 "PBES2" -# define NID_pbes2 161 -# define OBJ_pbes2 OBJ_pkcs,5L,13L - -# define LN_pbmac1 "PBMAC1" -# define NID_pbmac1 162 -# define OBJ_pbmac1 OBJ_pkcs,5L,14L - -# define LN_hmacWithSHA1 "hmacWithSHA1" -# define NID_hmacWithSHA1 163 -# define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L - -/* Policy Qualifier Ids */ - -# define LN_id_qt_cps "Policy Qualifier CPS" -# define SN_id_qt_cps "id-qt-cps" -# define NID_id_qt_cps 164 -# define OBJ_id_qt_cps OBJ_id_pkix,2L,1L - -# define LN_id_qt_unotice "Policy Qualifier User Notice" -# define SN_id_qt_unotice "id-qt-unotice" -# define NID_id_qt_unotice 165 -# define OBJ_id_qt_unotice OBJ_id_pkix,2L,2L - -# define SN_rc2_64_cbc "RC2-64-CBC" -# define LN_rc2_64_cbc "rc2-64-cbc" -# define NID_rc2_64_cbc 166 - -# define SN_SMIMECapabilities "SMIME-CAPS" -# define LN_SMIMECapabilities "S/MIME Capabilities" -# define NID_SMIMECapabilities 167 -# define OBJ_SMIMECapabilities OBJ_pkcs9,15L - -# define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" -# define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" -# define NID_pbeWithMD2AndRC2_CBC 168 -# define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs,5L,4L - -# define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" -# define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" -# define NID_pbeWithMD5AndRC2_CBC 169 -# define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs,5L,6L - -# define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" -# define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" -# define NID_pbeWithSHA1AndDES_CBC 170 -# define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs,5L,10L - -/* Extension request OIDs */ - -# define LN_ms_ext_req "Microsoft Extension Request" -# define SN_ms_ext_req "msExtReq" -# define NID_ms_ext_req 171 -# define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L - -# define LN_ext_req "Extension Request" -# define SN_ext_req "extReq" -# define NID_ext_req 172 -# define OBJ_ext_req OBJ_pkcs9,14L - -# define SN_name "name" -# define LN_name "name" -# define NID_name 173 -# define OBJ_name OBJ_X509,41L - -# define SN_dnQualifier "dnQualifier" -# define LN_dnQualifier "dnQualifier" -# define NID_dnQualifier 174 -# define OBJ_dnQualifier OBJ_X509,46L - -# define SN_id_pe "id-pe" -# define NID_id_pe 175 -# define OBJ_id_pe OBJ_id_pkix,1L - -# define SN_id_ad "id-ad" -# define NID_id_ad 176 -# define OBJ_id_ad OBJ_id_pkix,48L - -# define SN_info_access "authorityInfoAccess" -# define LN_info_access "Authority Information Access" -# define NID_info_access 177 -# define OBJ_info_access OBJ_id_pe,1L - -# define SN_ad_OCSP "OCSP" -# define LN_ad_OCSP "OCSP" -# define NID_ad_OCSP 178 -# define OBJ_ad_OCSP OBJ_id_ad,1L - -# define SN_ad_ca_issuers "caIssuers" -# define LN_ad_ca_issuers "CA Issuers" -# define NID_ad_ca_issuers 179 -# define OBJ_ad_ca_issuers OBJ_id_ad,2L - -# define SN_OCSP_sign "OCSPSigning" -# define LN_OCSP_sign "OCSP Signing" -# define NID_OCSP_sign 180 -# define OBJ_OCSP_sign OBJ_id_kp,9L -# endif /* USE_OBJ_MAC */ - -# include "bio.h" -# include "asn1.h" - -# define OBJ_NAME_TYPE_UNDEF 0x00 -# define OBJ_NAME_TYPE_MD_METH 0x01 -# define OBJ_NAME_TYPE_CIPHER_METH 0x02 -# define OBJ_NAME_TYPE_PKEY_METH 0x03 -# define OBJ_NAME_TYPE_COMP_METH 0x04 -# define OBJ_NAME_TYPE_NUM 0x05 - -# define OBJ_NAME_ALIAS 0x8000 - -# define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 -# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct obj_name_st { - int type; - int alias; - const char *name; - const char *data; -} OBJ_NAME; - -# define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) - -int OBJ_NAME_init(void); -int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), - int (*cmp_func) (const char *, const char *), - void (*free_func) (const char *, int, const char *)); -const char *OBJ_NAME_get(const char *name, int type); -int OBJ_NAME_add(const char *name, int type, const char *data); -int OBJ_NAME_remove(const char *name, int type); -void OBJ_NAME_cleanup(int type); /* -1 for everything */ -void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), - void *arg); -void OBJ_NAME_do_all_sorted(int type, - void (*fn) (const OBJ_NAME *, void *arg), - void *arg); - -ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o); -ASN1_OBJECT *OBJ_nid2obj(int n); -const char *OBJ_nid2ln(int n); -const char *OBJ_nid2sn(int n); -int OBJ_obj2nid(const ASN1_OBJECT *o); -ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name); -int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); -int OBJ_txt2nid(const char *s); -int OBJ_ln2nid(const char *s); -int OBJ_sn2nid(const char *s); -int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); -const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, - int (*cmp) (const void *, const void *)); -const void *OBJ_bsearch_ex_(const void *key, const void *base, int num, - int size, - int (*cmp) (const void *, const void *), - int flags); - -# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ - static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ - static int nm##_cmp(type1 const *, type2 const *); \ - scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) - -# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ - _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) -# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ - type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) - -/*- - * Unsolved problem: if a type is actually a pointer type, like - * nid_triple is, then its impossible to get a const where you need - * it. Consider: - * - * typedef int nid_triple[3]; - * const void *a_; - * const nid_triple const *a = a_; - * - * The assignement discards a const because what you really want is: - * - * const int const * const *a = a_; - * - * But if you do that, you lose the fact that a is an array of 3 ints, - * which breaks comparison functions. - * - * Thus we end up having to cast, sadly, or unpack the - * declarations. Or, as I finally did in this case, delcare nid_triple - * to be a struct, which it should have been in the first place. - * - * Ben, August 2008. - * - * Also, strictly speaking not all types need be const, but handling - * the non-constness means a lot of complication, and in practice - * comparison routines do always not touch their arguments. - */ - -# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ - static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ - { \ - type1 const *a = a_; \ - type2 const *b = b_; \ - return nm##_cmp(a,b); \ - } \ - static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ - { \ - return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ - nm##_cmp_BSEARCH_CMP_FN); \ - } \ - extern void dummy_prototype(void) - -# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ - static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ - { \ - type1 const *a = a_; \ - type2 const *b = b_; \ - return nm##_cmp(a,b); \ - } \ - type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ - { \ - return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ - nm##_cmp_BSEARCH_CMP_FN); \ - } \ - extern void dummy_prototype(void) - -# define OBJ_bsearch(type1,key,type2,base,num,cmp) \ - ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ - num,sizeof(type2), \ - ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ - (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ - cmp##_BSEARCH_CMP_FN))) - -# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ - ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ - num,sizeof(type2), \ - ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ - (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ - cmp##_BSEARCH_CMP_FN)),flags) - -int OBJ_new_nid(int num); -int OBJ_add_object(const ASN1_OBJECT *obj); -int OBJ_create(const char *oid, const char *sn, const char *ln); -void OBJ_cleanup(void); -int OBJ_create_objects(BIO *in); - -int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); -int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); -int OBJ_add_sigid(int signid, int dig_id, int pkey_id); -void OBJ_sigid_free(void); - -extern int obj_cleanup_defer; -void check_defer(int nid); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_OBJ_strings(void); - -/* Error codes for the OBJ functions. */ - -/* Function codes. */ -# define OBJ_F_OBJ_ADD_OBJECT 105 -# define OBJ_F_OBJ_CREATE 100 -# define OBJ_F_OBJ_DUP 101 -# define OBJ_F_OBJ_NAME_NEW_INDEX 106 -# define OBJ_F_OBJ_NID2LN 102 -# define OBJ_F_OBJ_NID2OBJ 103 -# define OBJ_F_OBJ_NID2SN 104 - -/* Reason codes. */ -# define OBJ_R_MALLOC_FAILURE 100 -# define OBJ_R_UNKNOWN_NID 101 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ocsp.h b/Sources/COpenSSL/ocsp.h deleted file mode 100644 index f0b98d34..00000000 --- a/Sources/COpenSSL/ocsp.h +++ /dev/null @@ -1,637 +0,0 @@ -/* ocsp.h */ -/* - * Written by Tom Titchener for the OpenSSL - * project. - */ - -/* - * History: This file was transfered to Richard Levitte from CertCo by Kathy - * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a - * patch kit. - */ - -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_OCSP_H -# define HEADER_OCSP_H - -# include "ossl_typ.h" -# include "x509.h" -# include "x509v3.h" -# include "safestack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Various flags and values */ - -# define OCSP_DEFAULT_NONCE_LENGTH 16 - -# define OCSP_NOCERTS 0x1 -# define OCSP_NOINTERN 0x2 -# define OCSP_NOSIGS 0x4 -# define OCSP_NOCHAIN 0x8 -# define OCSP_NOVERIFY 0x10 -# define OCSP_NOEXPLICIT 0x20 -# define OCSP_NOCASIGN 0x40 -# define OCSP_NODELEGATED 0x80 -# define OCSP_NOCHECKS 0x100 -# define OCSP_TRUSTOTHER 0x200 -# define OCSP_RESPID_KEY 0x400 -# define OCSP_NOTIME 0x800 - -/*- CertID ::= SEQUENCE { - * hashAlgorithm AlgorithmIdentifier, - * issuerNameHash OCTET STRING, -- Hash of Issuer's DN - * issuerKeyHash OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields) - * serialNumber CertificateSerialNumber } - */ -typedef struct ocsp_cert_id_st { - X509_ALGOR *hashAlgorithm; - ASN1_OCTET_STRING *issuerNameHash; - ASN1_OCTET_STRING *issuerKeyHash; - ASN1_INTEGER *serialNumber; -} OCSP_CERTID; - -DECLARE_STACK_OF(OCSP_CERTID) - -/*- Request ::= SEQUENCE { - * reqCert CertID, - * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } - */ -typedef struct ocsp_one_request_st { - OCSP_CERTID *reqCert; - STACK_OF(X509_EXTENSION) *singleRequestExtensions; -} OCSP_ONEREQ; - -DECLARE_STACK_OF(OCSP_ONEREQ) -DECLARE_ASN1_SET_OF(OCSP_ONEREQ) - -/*- TBSRequest ::= SEQUENCE { - * version [0] EXPLICIT Version DEFAULT v1, - * requestorName [1] EXPLICIT GeneralName OPTIONAL, - * requestList SEQUENCE OF Request, - * requestExtensions [2] EXPLICIT Extensions OPTIONAL } - */ -typedef struct ocsp_req_info_st { - ASN1_INTEGER *version; - GENERAL_NAME *requestorName; - STACK_OF(OCSP_ONEREQ) *requestList; - STACK_OF(X509_EXTENSION) *requestExtensions; -} OCSP_REQINFO; - -/*- Signature ::= SEQUENCE { - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING, - * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } - */ -typedef struct ocsp_signature_st { - X509_ALGOR *signatureAlgorithm; - ASN1_BIT_STRING *signature; - STACK_OF(X509) *certs; -} OCSP_SIGNATURE; - -/*- OCSPRequest ::= SEQUENCE { - * tbsRequest TBSRequest, - * optionalSignature [0] EXPLICIT Signature OPTIONAL } - */ -typedef struct ocsp_request_st { - OCSP_REQINFO *tbsRequest; - OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */ -} OCSP_REQUEST; - -/*- OCSPResponseStatus ::= ENUMERATED { - * successful (0), --Response has valid confirmations - * malformedRequest (1), --Illegal confirmation request - * internalError (2), --Internal error in issuer - * tryLater (3), --Try again later - * --(4) is not used - * sigRequired (5), --Must sign the request - * unauthorized (6) --Request unauthorized - * } - */ -# define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 -# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 -# define OCSP_RESPONSE_STATUS_INTERNALERROR 2 -# define OCSP_RESPONSE_STATUS_TRYLATER 3 -# define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 -# define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 - -/*- ResponseBytes ::= SEQUENCE { - * responseType OBJECT IDENTIFIER, - * response OCTET STRING } - */ -typedef struct ocsp_resp_bytes_st { - ASN1_OBJECT *responseType; - ASN1_OCTET_STRING *response; -} OCSP_RESPBYTES; - -/*- OCSPResponse ::= SEQUENCE { - * responseStatus OCSPResponseStatus, - * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } - */ -struct ocsp_response_st { - ASN1_ENUMERATED *responseStatus; - OCSP_RESPBYTES *responseBytes; -}; - -/*- ResponderID ::= CHOICE { - * byName [1] Name, - * byKey [2] KeyHash } - */ -# define V_OCSP_RESPID_NAME 0 -# define V_OCSP_RESPID_KEY 1 -struct ocsp_responder_id_st { - int type; - union { - X509_NAME *byName; - ASN1_OCTET_STRING *byKey; - } value; -}; - -DECLARE_STACK_OF(OCSP_RESPID) -DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) - -/*- KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key - * --(excluding the tag and length fields) - */ - -/*- RevokedInfo ::= SEQUENCE { - * revocationTime GeneralizedTime, - * revocationReason [0] EXPLICIT CRLReason OPTIONAL } - */ -typedef struct ocsp_revoked_info_st { - ASN1_GENERALIZEDTIME *revocationTime; - ASN1_ENUMERATED *revocationReason; -} OCSP_REVOKEDINFO; - -/*- CertStatus ::= CHOICE { - * good [0] IMPLICIT NULL, - * revoked [1] IMPLICIT RevokedInfo, - * unknown [2] IMPLICIT UnknownInfo } - */ -# define V_OCSP_CERTSTATUS_GOOD 0 -# define V_OCSP_CERTSTATUS_REVOKED 1 -# define V_OCSP_CERTSTATUS_UNKNOWN 2 -typedef struct ocsp_cert_status_st { - int type; - union { - ASN1_NULL *good; - OCSP_REVOKEDINFO *revoked; - ASN1_NULL *unknown; - } value; -} OCSP_CERTSTATUS; - -/*- SingleResponse ::= SEQUENCE { - * certID CertID, - * certStatus CertStatus, - * thisUpdate GeneralizedTime, - * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, - * singleExtensions [1] EXPLICIT Extensions OPTIONAL } - */ -typedef struct ocsp_single_response_st { - OCSP_CERTID *certId; - OCSP_CERTSTATUS *certStatus; - ASN1_GENERALIZEDTIME *thisUpdate; - ASN1_GENERALIZEDTIME *nextUpdate; - STACK_OF(X509_EXTENSION) *singleExtensions; -} OCSP_SINGLERESP; - -DECLARE_STACK_OF(OCSP_SINGLERESP) -DECLARE_ASN1_SET_OF(OCSP_SINGLERESP) - -/*- ResponseData ::= SEQUENCE { - * version [0] EXPLICIT Version DEFAULT v1, - * responderID ResponderID, - * producedAt GeneralizedTime, - * responses SEQUENCE OF SingleResponse, - * responseExtensions [1] EXPLICIT Extensions OPTIONAL } - */ -typedef struct ocsp_response_data_st { - ASN1_INTEGER *version; - OCSP_RESPID *responderId; - ASN1_GENERALIZEDTIME *producedAt; - STACK_OF(OCSP_SINGLERESP) *responses; - STACK_OF(X509_EXTENSION) *responseExtensions; -} OCSP_RESPDATA; - -/*- BasicOCSPResponse ::= SEQUENCE { - * tbsResponseData ResponseData, - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING, - * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } - */ - /* - * Note 1: The value for "signature" is specified in the OCSP rfc2560 as - * follows: "The value for the signature SHALL be computed on the hash of - * the DER encoding ResponseData." This means that you must hash the - * DER-encoded tbsResponseData, and then run it through a crypto-signing - * function, which will (at least w/RSA) do a hash-'n'-private-encrypt - * operation. This seems a bit odd, but that's the spec. Also note that - * the data structures do not leave anywhere to independently specify the - * algorithm used for the initial hash. So, we look at the - * signature-specification algorithm, and try to do something intelligent. - * -- Kathy Weinhold, CertCo - */ - /* - * Note 2: It seems that the mentioned passage from RFC 2560 (section - * 4.2.1) is open for interpretation. I've done tests against another - * responder, and found that it doesn't do the double hashing that the RFC - * seems to say one should. Therefore, all relevant functions take a flag - * saying which variant should be used. -- Richard Levitte, OpenSSL team - * and CeloCom - */ -typedef struct ocsp_basic_response_st { - OCSP_RESPDATA *tbsResponseData; - X509_ALGOR *signatureAlgorithm; - ASN1_BIT_STRING *signature; - STACK_OF(X509) *certs; -} OCSP_BASICRESP; - -/*- - * CRLReason ::= ENUMERATED { - * unspecified (0), - * keyCompromise (1), - * cACompromise (2), - * affiliationChanged (3), - * superseded (4), - * cessationOfOperation (5), - * certificateHold (6), - * removeFromCRL (8) } - */ -# define OCSP_REVOKED_STATUS_NOSTATUS -1 -# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 -# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 -# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 -# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 -# define OCSP_REVOKED_STATUS_SUPERSEDED 4 -# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 -# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 -# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 - -/*- - * CrlID ::= SEQUENCE { - * crlUrl [0] EXPLICIT IA5String OPTIONAL, - * crlNum [1] EXPLICIT INTEGER OPTIONAL, - * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL } - */ -typedef struct ocsp_crl_id_st { - ASN1_IA5STRING *crlUrl; - ASN1_INTEGER *crlNum; - ASN1_GENERALIZEDTIME *crlTime; -} OCSP_CRLID; - -/*- - * ServiceLocator ::= SEQUENCE { - * issuer Name, - * locator AuthorityInfoAccessSyntax OPTIONAL } - */ -typedef struct ocsp_service_locator_st { - X509_NAME *issuer; - STACK_OF(ACCESS_DESCRIPTION) *locator; -} OCSP_SERVICELOC; - -# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" -# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" - -# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) - -# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) - -# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ - (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL) - -# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\ - (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL) - -# define PEM_write_bio_OCSP_REQUEST(bp,o) \ - PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ - bp,(char *)o, NULL,NULL,0,NULL,NULL) - -# define PEM_write_bio_OCSP_RESPONSE(bp,o) \ - PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ - bp,(char *)o, NULL,NULL,0,NULL,NULL) - -# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) - -# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) - -# define OCSP_REQUEST_sign(o,pkey,md) \ - ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\ - o->optionalSignature->signatureAlgorithm,NULL,\ - o->optionalSignature->signature,o->tbsRequest,pkey,md) - -# define OCSP_BASICRESP_sign(o,pkey,md,d) \ - ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\ - o->signature,o->tbsResponseData,pkey,md) - -# define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\ - a->optionalSignature->signatureAlgorithm,\ - a->optionalSignature->signature,a->tbsRequest,r) - -# define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\ - a->signatureAlgorithm,a->signature,a->tbsResponseData,r) - -# define ASN1_BIT_STRING_digest(data,type,md,len) \ - ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) - -# define OCSP_CERTSTATUS_dup(cs)\ - (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ - (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) - -OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); - -OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req); -OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, - int maxline); -int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx); -int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); -OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline); -void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); -void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len); -int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, - ASN1_VALUE *val); -int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, ASN1_VALUE **pval, - const ASN1_ITEM *it); -BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx); -int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, - ASN1_VALUE *val); -int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path); -int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); -int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, - const char *name, const char *value); - -OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); - -OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, - X509_NAME *issuerName, - ASN1_BIT_STRING *issuerKey, - ASN1_INTEGER *serialNumber); - -OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); - -int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); -int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); -int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); -int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); - -int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); -int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); - -int OCSP_request_sign(OCSP_REQUEST *req, - X509 *signer, - EVP_PKEY *key, - const EVP_MD *dgst, - STACK_OF(X509) *certs, unsigned long flags); - -int OCSP_response_status(OCSP_RESPONSE *resp); -OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); - -int OCSP_resp_count(OCSP_BASICRESP *bs); -OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); -int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); -int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, - ASN1_GENERALIZEDTIME **revtime, - ASN1_GENERALIZEDTIME **thisupd, - ASN1_GENERALIZEDTIME **nextupd); -int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, - int *reason, - ASN1_GENERALIZEDTIME **revtime, - ASN1_GENERALIZEDTIME **thisupd, - ASN1_GENERALIZEDTIME **nextupd); -int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, - ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); - -int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, - X509_STORE *store, unsigned long flags); - -int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, - int *pssl); - -int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b); -int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); - -int OCSP_request_onereq_count(OCSP_REQUEST *req); -OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); -OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); -int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, - ASN1_OCTET_STRING **pikeyHash, - ASN1_INTEGER **pserial, OCSP_CERTID *cid); -int OCSP_request_is_signed(OCSP_REQUEST *req); -OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); -OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, - OCSP_CERTID *cid, - int status, int reason, - ASN1_TIME *revtime, - ASN1_TIME *thisupd, - ASN1_TIME *nextupd); -int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); -int OCSP_basic_sign(OCSP_BASICRESP *brsp, - X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, - STACK_OF(X509) *certs, unsigned long flags); - -X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); - -X509_EXTENSION *OCSP_accept_responses_new(char **oids); - -X509_EXTENSION *OCSP_archive_cutoff_new(char *tim); - -X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls); - -int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); -int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); -int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, - int lastpos); -int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); -X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); -X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); -void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, - int *idx); -int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, - unsigned long flags); -int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); - -int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); -int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); -int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos); -int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); -X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); -X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); -void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); -int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, - unsigned long flags); -int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); - -int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); -int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); -int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, - int lastpos); -int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, - int lastpos); -X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); -X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); -void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, - int *idx); -int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, - int crit, unsigned long flags); -int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); - -int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); -int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); -int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, - int lastpos); -int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, - int lastpos); -X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); -X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); -void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, - int *idx); -int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, - int crit, unsigned long flags); -int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); - -DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) -DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) -DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) -DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) -DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) -DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) -DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) -DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) -DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) -DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) -DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) -DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) -DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) -DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) -DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) - -const char *OCSP_response_status_str(long s); -const char *OCSP_cert_status_str(long s); -const char *OCSP_crl_reason_str(long s); - -int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags); -int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags); - -int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, - X509_STORE *st, unsigned long flags); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_OCSP_strings(void); - -/* Error codes for the OCSP functions. */ - -/* Function codes. */ -# define OCSP_F_ASN1_STRING_ENCODE 100 -# define OCSP_F_D2I_OCSP_NONCE 102 -# define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 -# define OCSP_F_OCSP_BASIC_SIGN 104 -# define OCSP_F_OCSP_BASIC_VERIFY 105 -# define OCSP_F_OCSP_CERT_ID_NEW 101 -# define OCSP_F_OCSP_CHECK_DELEGATED 106 -# define OCSP_F_OCSP_CHECK_IDS 107 -# define OCSP_F_OCSP_CHECK_ISSUER 108 -# define OCSP_F_OCSP_CHECK_VALIDITY 115 -# define OCSP_F_OCSP_MATCH_ISSUERID 109 -# define OCSP_F_OCSP_PARSE_URL 114 -# define OCSP_F_OCSP_REQUEST_SIGN 110 -# define OCSP_F_OCSP_REQUEST_VERIFY 116 -# define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 -# define OCSP_F_OCSP_SENDREQ_BIO 112 -# define OCSP_F_OCSP_SENDREQ_NBIO 117 -# define OCSP_F_PARSE_HTTP_LINE1 118 -# define OCSP_F_REQUEST_VERIFY 113 - -/* Reason codes. */ -# define OCSP_R_BAD_DATA 100 -# define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 -# define OCSP_R_DIGEST_ERR 102 -# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 -# define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 -# define OCSP_R_ERROR_PARSING_URL 121 -# define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 -# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 -# define OCSP_R_NOT_BASIC_RESPONSE 104 -# define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 -# define OCSP_R_NO_CONTENT 106 -# define OCSP_R_NO_PUBLIC_KEY 107 -# define OCSP_R_NO_RESPONSE_DATA 108 -# define OCSP_R_NO_REVOKED_TIME 109 -# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 -# define OCSP_R_REQUEST_NOT_SIGNED 128 -# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 -# define OCSP_R_ROOT_CA_NOT_TRUSTED 112 -# define OCSP_R_SERVER_READ_ERROR 113 -# define OCSP_R_SERVER_RESPONSE_ERROR 114 -# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 -# define OCSP_R_SERVER_WRITE_ERROR 116 -# define OCSP_R_SIGNATURE_FAILURE 117 -# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 -# define OCSP_R_STATUS_EXPIRED 125 -# define OCSP_R_STATUS_NOT_YET_VALID 126 -# define OCSP_R_STATUS_TOO_OLD 127 -# define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 -# define OCSP_R_UNKNOWN_NID 120 -# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ocsp_.c b/Sources/COpenSSL/ocsp_.c deleted file mode 100644 index 6308d15a..00000000 --- a/Sources/COpenSSL/ocsp_.c +++ /dev/null @@ -1,3155 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ocsp_asn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#include "asn1.h" -#include "asn1t.h" -#include "ocsp.h" - -ASN1_SEQUENCE(OCSP_SIGNATURE) = { - ASN1_SIMPLE(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR), - ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING), - ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0) -} ASN1_SEQUENCE_END(OCSP_SIGNATURE) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE) - -ASN1_SEQUENCE(OCSP_CERTID) = { - ASN1_SIMPLE(OCSP_CERTID, hashAlgorithm, X509_ALGOR), - ASN1_SIMPLE(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING), - ASN1_SIMPLE(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING), - ASN1_SIMPLE(OCSP_CERTID, serialNumber, ASN1_INTEGER) -} ASN1_SEQUENCE_END(OCSP_CERTID) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID) - -ASN1_SEQUENCE(OCSP_ONEREQ) = { - ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID), - ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0) -} ASN1_SEQUENCE_END(OCSP_ONEREQ) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ) - -ASN1_SEQUENCE(OCSP_REQINFO) = { - ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0), - ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1), - ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ), - ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2) -} ASN1_SEQUENCE_END(OCSP_REQINFO) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO) - -ASN1_SEQUENCE(OCSP_REQUEST) = { - ASN1_SIMPLE(OCSP_REQUEST, tbsRequest, OCSP_REQINFO), - ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0) -} ASN1_SEQUENCE_END(OCSP_REQUEST) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST) - -/* OCSP_RESPONSE templates */ - -ASN1_SEQUENCE(OCSP_RESPBYTES) = { - ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT), - ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(OCSP_RESPBYTES) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES) - -ASN1_SEQUENCE(OCSP_RESPONSE) = { - ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED), - ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0) -} ASN1_SEQUENCE_END(OCSP_RESPONSE) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE) - -ASN1_CHOICE(OCSP_RESPID) = { - ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1), - ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2) -} ASN1_CHOICE_END(OCSP_RESPID) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID) - -ASN1_SEQUENCE(OCSP_REVOKEDINFO) = { - ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME), - ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0) -} ASN1_SEQUENCE_END(OCSP_REVOKEDINFO) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) - -ASN1_CHOICE(OCSP_CERTSTATUS) = { - ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0), - ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1), - ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2) -} ASN1_CHOICE_END(OCSP_CERTSTATUS) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS) - -ASN1_SEQUENCE(OCSP_SINGLERESP) = { - ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID), - ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS), - ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME), - ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0), - ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1) -} ASN1_SEQUENCE_END(OCSP_SINGLERESP) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP) - -ASN1_SEQUENCE(OCSP_RESPDATA) = { - ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0), - ASN1_SIMPLE(OCSP_RESPDATA, responderId, OCSP_RESPID), - ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME), - ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP), - ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1) -} ASN1_SEQUENCE_END(OCSP_RESPDATA) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA) - -ASN1_SEQUENCE(OCSP_BASICRESP) = { - ASN1_SIMPLE(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA), - ASN1_SIMPLE(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR), - ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING), - ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0) -} ASN1_SEQUENCE_END(OCSP_BASICRESP) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP) - -ASN1_SEQUENCE(OCSP_CRLID) = { - ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0), - ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1), - ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2) -} ASN1_SEQUENCE_END(OCSP_CRLID) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID) - -ASN1_SEQUENCE(OCSP_SERVICELOC) = { - ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME), - ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION) -} ASN1_SEQUENCE_END(OCSP_SERVICELOC) - -IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC) -/* ocsp_cl.c */ -/* - * Written by Tom Titchener for the OpenSSL - * project. - */ - -/* - * History: This file was transfered to Richard Levitte from CertCo by Kathy - * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a - * patch kit. - */ - -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "cryptlib.h" -#include "objects.h" -#include "rand.h" -#include "x509.h" -#include "pem.h" -#include "x509v3.h" -// #include "ocsp.h" - -/* - * Utility functions related to sending OCSP requests and extracting relevant - * information from the response. - */ - -/* - * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer: - * useful if we want to add extensions. - */ - -OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) -{ - OCSP_ONEREQ *one = NULL; - - if (!(one = OCSP_ONEREQ_new())) - goto err; - if (one->reqCert) - OCSP_CERTID_free(one->reqCert); - one->reqCert = cid; - if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one)) { - one->reqCert = NULL; /* do not free on error */ - goto err; - } - return one; - err: - OCSP_ONEREQ_free(one); - return NULL; -} - -/* Set requestorName from an X509_NAME structure */ - -int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm) -{ - GENERAL_NAME *gen; - gen = GENERAL_NAME_new(); - if (gen == NULL) - return 0; - if (!X509_NAME_set(&gen->d.directoryName, nm)) { - GENERAL_NAME_free(gen); - return 0; - } - gen->type = GEN_DIRNAME; - if (req->tbsRequest->requestorName) - GENERAL_NAME_free(req->tbsRequest->requestorName); - req->tbsRequest->requestorName = gen; - return 1; -} - -/* Add a certificate to an OCSP request */ - -int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) -{ - OCSP_SIGNATURE *sig; - if (!req->optionalSignature) - req->optionalSignature = OCSP_SIGNATURE_new(); - sig = req->optionalSignature; - if (!sig) - return 0; - if (!cert) - return 1; - if (!sig->certs && !(sig->certs = sk_X509_new_null())) - return 0; - - if (!sk_X509_push(sig->certs, cert)) - return 0; - CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); - return 1; -} - -/* - * Sign an OCSP request set the requestorName to the subjec name of an - * optional signers certificate and include one or more optional certificates - * in the request. Behaves like PKCS7_sign(). - */ - -int OCSP_request_sign(OCSP_REQUEST *req, - X509 *signer, - EVP_PKEY *key, - const EVP_MD *dgst, - STACK_OF(X509) *certs, unsigned long flags) -{ - int i; - OCSP_SIGNATURE *sig; - X509 *x; - - if (!OCSP_request_set1_name(req, X509_get_subject_name(signer))) - goto err; - - if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) - goto err; - if (key) { - if (!X509_check_private_key(signer, key)) { - OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, - OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); - goto err; - } - if (!OCSP_REQUEST_sign(req, key, dgst)) - goto err; - } - - if (!(flags & OCSP_NOCERTS)) { - if (!OCSP_request_add1_cert(req, signer)) - goto err; - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - if (!OCSP_request_add1_cert(req, x)) - goto err; - } - } - - return 1; - err: - OCSP_SIGNATURE_free(req->optionalSignature); - req->optionalSignature = NULL; - return 0; -} - -/* Get response status */ - -int OCSP_response_status(OCSP_RESPONSE *resp) -{ - return ASN1_ENUMERATED_get(resp->responseStatus); -} - -/* - * Extract basic response from OCSP_RESPONSE or NULL if no basic response - * present. - */ - -OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp) -{ - OCSP_RESPBYTES *rb; - rb = resp->responseBytes; - if (!rb) { - OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA); - return NULL; - } - if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { - OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE); - return NULL; - } - - return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP)); -} - -/* - * Return number of OCSP_SINGLERESP reponses present in a basic response. - */ - -int OCSP_resp_count(OCSP_BASICRESP *bs) -{ - if (!bs) - return -1; - return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses); -} - -/* Extract an OCSP_SINGLERESP response with a given index */ - -OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx) -{ - if (!bs) - return NULL; - return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx); -} - -/* Look single response matching a given certificate ID */ - -int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) -{ - int i; - STACK_OF(OCSP_SINGLERESP) *sresp; - OCSP_SINGLERESP *single; - if (!bs) - return -1; - if (last < 0) - last = 0; - else - last++; - sresp = bs->tbsResponseData->responses; - for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) { - single = sk_OCSP_SINGLERESP_value(sresp, i); - if (!OCSP_id_cmp(id, single->certId)) - return i; - } - return -1; -} - -/* - * Extract status information from an OCSP_SINGLERESP structure. Note: the - * revtime and reason values are only set if the certificate status is - * revoked. Returns numerical value of status. - */ - -int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, - ASN1_GENERALIZEDTIME **revtime, - ASN1_GENERALIZEDTIME **thisupd, - ASN1_GENERALIZEDTIME **nextupd) -{ - int ret; - OCSP_CERTSTATUS *cst; - if (!single) - return -1; - cst = single->certStatus; - ret = cst->type; - if (ret == V_OCSP_CERTSTATUS_REVOKED) { - OCSP_REVOKEDINFO *rev = cst->value.revoked; - if (revtime) - *revtime = rev->revocationTime; - if (reason) { - if (rev->revocationReason) - *reason = ASN1_ENUMERATED_get(rev->revocationReason); - else - *reason = -1; - } - } - if (thisupd) - *thisupd = single->thisUpdate; - if (nextupd) - *nextupd = single->nextUpdate; - return ret; -} - -/* - * This function combines the previous ones: look up a certificate ID and if - * found extract status information. Return 0 is successful. - */ - -int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, - int *reason, - ASN1_GENERALIZEDTIME **revtime, - ASN1_GENERALIZEDTIME **thisupd, - ASN1_GENERALIZEDTIME **nextupd) -{ - int i; - OCSP_SINGLERESP *single; - i = OCSP_resp_find(bs, id, -1); - /* Maybe check for multiple responses and give an error? */ - if (i < 0) - return 0; - single = OCSP_resp_get0(bs, i); - i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd); - if (status) - *status = i; - return 1; -} - -/* - * Check validity of thisUpdate and nextUpdate fields. It is possible that - * the request will take a few seconds to process and/or the time wont be - * totally accurate. Therefore to avoid rejecting otherwise valid time we - * allow the times to be within 'nsec' of the current time. Also to avoid - * accepting very old responses without a nextUpdate field an optional maxage - * parameter specifies the maximum age the thisUpdate field can be. - */ - -int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, - ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) -{ - int ret = 1; - time_t t_now, t_tmp; - time(&t_now); - /* Check thisUpdate is valid and not more than nsec in the future */ - if (!ASN1_GENERALIZEDTIME_check(thisupd)) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD); - ret = 0; - } else { - t_tmp = t_now + nsec; - if (X509_cmp_time(thisupd, &t_tmp) > 0) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID); - ret = 0; - } - - /* - * If maxsec specified check thisUpdate is not more than maxsec in - * the past - */ - if (maxsec >= 0) { - t_tmp = t_now - maxsec; - if (X509_cmp_time(thisupd, &t_tmp) < 0) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD); - ret = 0; - } - } - } - - if (!nextupd) - return ret; - - /* Check nextUpdate is valid and not more than nsec in the past */ - if (!ASN1_GENERALIZEDTIME_check(nextupd)) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); - ret = 0; - } else { - t_tmp = t_now - nsec; - if (X509_cmp_time(nextupd, &t_tmp) < 0) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED); - ret = 0; - } - } - - /* Also don't allow nextUpdate to precede thisUpdate */ - if (ASN1_STRING_cmp(nextupd, thisupd) < 0) { - OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, - OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); - ret = 0; - } - - return ret; -} -/* crypto/ocsp/ocsp_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "ocsp.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason) - -static ERR_STRING_DATA OCSP_str_functs[] = { - {ERR_FUNC(OCSP_F_ASN1_STRING_ENCODE), "ASN1_STRING_encode"}, - {ERR_FUNC(OCSP_F_D2I_OCSP_NONCE), "D2I_OCSP_NONCE"}, - {ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS), "OCSP_basic_add1_status"}, - {ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN), "OCSP_basic_sign"}, - {ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY), "OCSP_basic_verify"}, - {ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW), "OCSP_cert_id_new"}, - {ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED), "OCSP_CHECK_DELEGATED"}, - {ERR_FUNC(OCSP_F_OCSP_CHECK_IDS), "OCSP_CHECK_IDS"}, - {ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER), "OCSP_CHECK_ISSUER"}, - {ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY), "OCSP_check_validity"}, - {ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID), "OCSP_MATCH_ISSUERID"}, - {ERR_FUNC(OCSP_F_OCSP_PARSE_URL), "OCSP_parse_url"}, - {ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN), "OCSP_request_sign"}, - {ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY), "OCSP_request_verify"}, - {ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC), "OCSP_response_get1_basic"}, - {ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO), "OCSP_sendreq_bio"}, - {ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO), "OCSP_sendreq_nbio"}, - {ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1), "PARSE_HTTP_LINE1"}, - {ERR_FUNC(OCSP_F_REQUEST_VERIFY), "REQUEST_VERIFY"}, - {0, NULL} -}; - -static ERR_STRING_DATA OCSP_str_reasons[] = { - {ERR_REASON(OCSP_R_BAD_DATA), "bad data"}, - {ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, - {ERR_REASON(OCSP_R_DIGEST_ERR), "digest err"}, - {ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD), - "error in nextupdate field"}, - {ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD), - "error in thisupdate field"}, - {ERR_REASON(OCSP_R_ERROR_PARSING_URL), "error parsing url"}, - {ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE), - "missing ocspsigning usage"}, - {ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE), - "nextupdate before thisupdate"}, - {ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE), "not basic response"}, - {ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN), "no certificates in chain"}, - {ERR_REASON(OCSP_R_NO_CONTENT), "no content"}, - {ERR_REASON(OCSP_R_NO_PUBLIC_KEY), "no public key"}, - {ERR_REASON(OCSP_R_NO_RESPONSE_DATA), "no response data"}, - {ERR_REASON(OCSP_R_NO_REVOKED_TIME), "no revoked time"}, - {ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), - "private key does not match certificate"}, - {ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED), "request not signed"}, - {ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA), - "response contains no revocation data"}, - {ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED), "root ca not trusted"}, - {ERR_REASON(OCSP_R_SERVER_READ_ERROR), "server read error"}, - {ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR), "server response error"}, - {ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR), - "server response parse error"}, - {ERR_REASON(OCSP_R_SERVER_WRITE_ERROR), "server write error"}, - {ERR_REASON(OCSP_R_SIGNATURE_FAILURE), "signature failure"}, - {ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND), - "signer certificate not found"}, - {ERR_REASON(OCSP_R_STATUS_EXPIRED), "status expired"}, - {ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID), "status not yet valid"}, - {ERR_REASON(OCSP_R_STATUS_TOO_OLD), "status too old"}, - {ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST), "unknown message digest"}, - {ERR_REASON(OCSP_R_UNKNOWN_NID), "unknown nid"}, - {ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE), - "unsupported requestorname type"}, - {0, NULL} -}; - -#endif - -void ERR_load_OCSP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) { - ERR_load_strings(0, OCSP_str_functs); - ERR_load_strings(0, OCSP_str_reasons); - } -#endif -} -/* ocsp_ext.c */ -/* - * Written by Tom Titchener for the OpenSSL - * project. - */ - -/* - * History: This file was transfered to Richard Levitte from CertCo by Kathy - * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a - * patch kit. - */ - -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "x509.h" -// #include "ocsp.h" -// #include "rand.h" -// #include "x509v3.h" - -/* Standard wrapper functions for extensions */ - -/* OCSP request extensions */ - -int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) -{ - return (X509v3_get_ext_count(x->tbsRequest->requestExtensions)); -} - -int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID - (x->tbsRequest->requestExtensions, nid, lastpos)); -} - -int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, - int lastpos) -{ - return (X509v3_get_ext_by_OBJ - (x->tbsRequest->requestExtensions, obj, lastpos)); -} - -int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) -{ - return (X509v3_get_ext_by_critical - (x->tbsRequest->requestExtensions, crit, lastpos)); -} - -X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) -{ - return (X509v3_get_ext(x->tbsRequest->requestExtensions, loc)); -} - -X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) -{ - return (X509v3_delete_ext(x->tbsRequest->requestExtensions, loc)); -} - -void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); -} - -int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, - crit, flags); -} - -int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, loc) != - NULL); -} - -/* Single extensions */ - -int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) -{ - return (X509v3_get_ext_count(x->singleRequestExtensions)); -} - -int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos)); -} - -int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) -{ - return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos)); -} - -int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) -{ - return (X509v3_get_ext_by_critical - (x->singleRequestExtensions, crit, lastpos)); -} - -X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) -{ - return (X509v3_get_ext(x->singleRequestExtensions, loc)); -} - -X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) -{ - return (X509v3_delete_ext(x->singleRequestExtensions, loc)); -} - -void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); -} - -int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, - flags); -} - -int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL); -} - -/* OCSP Basic response */ - -int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) -{ - return (X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); -} - -int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID - (x->tbsResponseData->responseExtensions, nid, lastpos)); -} - -int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, - int lastpos) -{ - return (X509v3_get_ext_by_OBJ - (x->tbsResponseData->responseExtensions, obj, lastpos)); -} - -int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, - int lastpos) -{ - return (X509v3_get_ext_by_critical - (x->tbsResponseData->responseExtensions, crit, lastpos)); -} - -X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) -{ - return (X509v3_get_ext(x->tbsResponseData->responseExtensions, loc)); -} - -X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) -{ - return (X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc)); -} - -void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, - int *idx) -{ - return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, - idx); -} - -int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, - int crit, unsigned long flags) -{ - return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, - value, crit, flags); -} - -int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, loc) - != NULL); -} - -/* OCSP single response extensions */ - -int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) -{ - return (X509v3_get_ext_count(x->singleExtensions)); -} - -int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos)); -} - -int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, - int lastpos) -{ - return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos)); -} - -int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, - int lastpos) -{ - return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos)); -} - -X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) -{ - return (X509v3_get_ext(x->singleExtensions, loc)); -} - -X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) -{ - return (X509v3_delete_ext(x->singleExtensions, loc)); -} - -void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, - int *idx) -{ - return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); -} - -int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, - int crit, unsigned long flags) -{ - return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); -} - -int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL); -} - -/* also CRL Entry Extensions */ -#if 0 -ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, - void *data, STACK_OF(ASN1_OBJECT) *sk) -{ - int i; - unsigned char *p, *b = NULL; - - if (data) { - if ((i = i2d(data, NULL)) <= 0) - goto err; - if (!(b = p = OPENSSL_malloc((unsigned int)i))) - goto err; - if (i2d(data, &p) <= 0) - goto err; - } else if (sk) { - if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL, - (I2D_OF(ASN1_OBJECT)) i2d, - V_ASN1_SEQUENCE, - V_ASN1_UNIVERSAL, - IS_SEQUENCE)) <= 0) - goto err; - if (!(b = p = OPENSSL_malloc((unsigned int)i))) - goto err; - if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p, (I2D_OF(ASN1_OBJECT)) i2d, - V_ASN1_SEQUENCE, - V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0) - goto err; - } else { - OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA); - goto err; - } - if (!s && !(s = ASN1_STRING_new())) - goto err; - if (!(ASN1_STRING_set(s, b, i))) - goto err; - OPENSSL_free(b); - return s; - err: - if (b) - OPENSSL_free(b); - return NULL; -} -#endif - -/* Nonce handling functions */ - -/* - * Add a nonce to an extension stack. A nonce can be specificed or if NULL a - * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an - * OCTET STRING containing the nonce, previous versions used the raw nonce. - */ - -static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, - unsigned char *val, int len) -{ - unsigned char *tmpval; - ASN1_OCTET_STRING os; - int ret = 0; - if (len <= 0) - len = OCSP_DEFAULT_NONCE_LENGTH; - /* - * Create the OCTET STRING manually by writing out the header and - * appending the content octets. This avoids an extra memory allocation - * operation in some cases. Applications should *NOT* do this because it - * relies on library internals. - */ - os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); - os.data = OPENSSL_malloc(os.length); - if (os.data == NULL) - goto err; - tmpval = os.data; - ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); - if (val) - memcpy(tmpval, val, len); - else if (RAND_bytes(tmpval, len) <= 0) - goto err; - if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, - &os, 0, X509V3_ADD_REPLACE)) - goto err; - ret = 1; - err: - if (os.data) - OPENSSL_free(os.data); - return ret; -} - -/* Add nonce to an OCSP request */ - -int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) -{ - return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); -} - -/* Same as above but for a response */ - -int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) -{ - return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, - len); -} - -/*- - * Check nonce validity in a request and response. - * Return value reflects result: - * 1: nonces present and equal. - * 2: nonces both absent. - * 3: nonce present in response only. - * 0: nonces both present and not equal. - * -1: nonce in request only. - * - * For most responders clients can check return > 0. - * If responder doesn't handle nonces return != 0 may be - * necessary. return == 0 is always an error. - */ - -int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) -{ - /* - * Since we are only interested in the presence or absence of - * the nonce and comparing its value there is no need to use - * the X509V3 routines: this way we can avoid them allocating an - * ASN1_OCTET_STRING structure for the value which would be - * freed immediately anyway. - */ - - int req_idx, resp_idx; - X509_EXTENSION *req_ext, *resp_ext; - req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); - resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); - /* Check both absent */ - if ((req_idx < 0) && (resp_idx < 0)) - return 2; - /* Check in request only */ - if ((req_idx >= 0) && (resp_idx < 0)) - return -1; - /* Check in response but not request */ - if ((req_idx < 0) && (resp_idx >= 0)) - return 3; - /* - * Otherwise nonce in request and response so retrieve the extensions - */ - req_ext = OCSP_REQUEST_get_ext(req, req_idx); - resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); - if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) - return 0; - return 1; -} - -/* - * Copy the nonce value (if any) from an OCSP request to a response. - */ - -int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) -{ - X509_EXTENSION *req_ext; - int req_idx; - /* Check for nonce in request */ - req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); - /* If no nonce that's OK */ - if (req_idx < 0) - return 2; - req_ext = OCSP_REQUEST_get_ext(req, req_idx); - return OCSP_BASICRESP_add_ext(resp, req_ext, -1); -} - -X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) -{ - X509_EXTENSION *x = NULL; - OCSP_CRLID *cid = NULL; - - if (!(cid = OCSP_CRLID_new())) - goto err; - if (url) { - if (!(cid->crlUrl = ASN1_IA5STRING_new())) - goto err; - if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) - goto err; - } - if (n) { - if (!(cid->crlNum = ASN1_INTEGER_new())) - goto err; - if (!(ASN1_INTEGER_set(cid->crlNum, *n))) - goto err; - } - if (tim) { - if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) - goto err; - if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) - goto err; - } - x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); - err: - if (cid) - OCSP_CRLID_free(cid); - return x; -} - -/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ -X509_EXTENSION *OCSP_accept_responses_new(char **oids) -{ - int nid; - STACK_OF(ASN1_OBJECT) *sk = NULL; - ASN1_OBJECT *o = NULL; - X509_EXTENSION *x = NULL; - - if (!(sk = sk_ASN1_OBJECT_new_null())) - goto err; - while (oids && *oids) { - if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid))) - sk_ASN1_OBJECT_push(sk, o); - oids++; - } - x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); - err: - if (sk) - sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); - return x; -} - -/* ArchiveCutoff ::= GeneralizedTime */ -X509_EXTENSION *OCSP_archive_cutoff_new(char *tim) -{ - X509_EXTENSION *x = NULL; - ASN1_GENERALIZEDTIME *gt = NULL; - - if (!(gt = ASN1_GENERALIZEDTIME_new())) - goto err; - if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) - goto err; - x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); - err: - if (gt) - ASN1_GENERALIZEDTIME_free(gt); - return x; -} - -/* - * per ACCESS_DESCRIPTION parameter are oids, of which there are currently - * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method - * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. - */ -X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls) -{ - X509_EXTENSION *x = NULL; - ASN1_IA5STRING *ia5 = NULL; - OCSP_SERVICELOC *sloc = NULL; - ACCESS_DESCRIPTION *ad = NULL; - - if (!(sloc = OCSP_SERVICELOC_new())) - goto err; - if (!(sloc->issuer = X509_NAME_dup(issuer))) - goto err; - if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) - goto err; - while (urls && *urls) { - if (!(ad = ACCESS_DESCRIPTION_new())) - goto err; - if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP))) - goto err; - if (!(ad->location = GENERAL_NAME_new())) - goto err; - if (!(ia5 = ASN1_IA5STRING_new())) - goto err; - if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1)) - goto err; - ad->location->type = GEN_URI; - ad->location->d.ia5 = ia5; - if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) - goto err; - urls++; - } - x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); - err: - if (sloc) - OCSP_SERVICELOC_free(sloc); - return x; -} -/* ocsp_ht.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include -#include "e_os.h" -// #include "asn1.h" -// #include "ocsp.h" -// #include "err.h" -#include "buffer.h" -#ifdef OPENSSL_SYS_SUNOS -# define strtoul (unsigned long)strtol -#endif /* OPENSSL_SYS_SUNOS */ - -/* Stateful OCSP request code, supporting non-blocking I/O */ - -/* Opaque OCSP request status structure */ - -struct ocsp_req_ctx_st { - int state; /* Current I/O state */ - unsigned char *iobuf; /* Line buffer */ - int iobuflen; /* Line buffer length */ - BIO *io; /* BIO to perform I/O with */ - BIO *mem; /* Memory BIO response is built into */ - unsigned long asn1_len; /* ASN1 length of response */ - unsigned long max_resp_len; /* Maximum length of response */ -}; - -#define OCSP_MAX_RESP_LENGTH (100 * 1024) -#define OCSP_MAX_LINE_LEN 4096; - -/* OCSP states */ - -/* If set no reading should be performed */ -#define OHS_NOREAD 0x1000 -/* Error condition */ -#define OHS_ERROR (0 | OHS_NOREAD) -/* First line being read */ -#define OHS_FIRSTLINE 1 -/* MIME headers being read */ -#define OHS_HEADERS 2 -/* OCSP initial header (tag + length) being read */ -#define OHS_ASN1_HEADER 3 -/* OCSP content octets being read */ -#define OHS_ASN1_CONTENT 4 -/* First call: ready to start I/O */ -#define OHS_ASN1_WRITE_INIT (5 | OHS_NOREAD) -/* Request being sent */ -#define OHS_ASN1_WRITE (6 | OHS_NOREAD) -/* Request being flushed */ -#define OHS_ASN1_FLUSH (7 | OHS_NOREAD) -/* Completed */ -#define OHS_DONE (8 | OHS_NOREAD) -/* Headers set, no final \r\n included */ -#define OHS_HTTP_HEADER (9 | OHS_NOREAD) - -static int parse_http_line1(char *line); - -OCSP_REQ_CTX *OCSP_REQ_CTX_new(BIO *io, int maxline) -{ - OCSP_REQ_CTX *rctx; - rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX)); - if (!rctx) - return NULL; - rctx->state = OHS_ERROR; - rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; - rctx->mem = BIO_new(BIO_s_mem()); - rctx->io = io; - rctx->asn1_len = 0; - if (maxline > 0) - rctx->iobuflen = maxline; - else - rctx->iobuflen = OCSP_MAX_LINE_LEN; - rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); - if (!rctx->iobuf || !rctx->mem) { - OCSP_REQ_CTX_free(rctx); - return NULL; - } - return rctx; -} - -void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) -{ - if (rctx->mem) - BIO_free(rctx->mem); - if (rctx->iobuf) - OPENSSL_free(rctx->iobuf); - OPENSSL_free(rctx); -} - -BIO *OCSP_REQ_CTX_get0_mem_bio(OCSP_REQ_CTX *rctx) -{ - return rctx->mem; -} - -void OCSP_set_max_response_length(OCSP_REQ_CTX *rctx, unsigned long len) -{ - if (len == 0) - rctx->max_resp_len = OCSP_MAX_RESP_LENGTH; - else - rctx->max_resp_len = len; -} - -int OCSP_REQ_CTX_i2d(OCSP_REQ_CTX *rctx, const ASN1_ITEM *it, ASN1_VALUE *val) -{ - static const char req_hdr[] = - "Content-Type: application/ocsp-request\r\n" - "Content-Length: %d\r\n\r\n"; - int reqlen = ASN1_item_i2d(val, NULL, it); - if (BIO_printf(rctx->mem, req_hdr, reqlen) <= 0) - return 0; - if (ASN1_item_i2d_bio(it, rctx->mem, val) <= 0) - return 0; - rctx->state = OHS_ASN1_WRITE_INIT; - return 1; -} - -int OCSP_REQ_CTX_nbio_d2i(OCSP_REQ_CTX *rctx, - ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - int rv, len; - const unsigned char *p; - - rv = OCSP_REQ_CTX_nbio(rctx); - if (rv != 1) - return rv; - - len = BIO_get_mem_data(rctx->mem, &p); - *pval = ASN1_item_d2i(NULL, &p, len, it); - if (*pval == NULL) { - rctx->state = OHS_ERROR; - return 0; - } - return 1; -} - -int OCSP_REQ_CTX_http(OCSP_REQ_CTX *rctx, const char *op, const char *path) -{ - static const char http_hdr[] = "%s %s HTTP/1.0\r\n"; - - if (!path) - path = "/"; - - if (BIO_printf(rctx->mem, http_hdr, op, path) <= 0) - return 0; - rctx->state = OHS_HTTP_HEADER; - return 1; -} - -int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) -{ - return OCSP_REQ_CTX_i2d(rctx, ASN1_ITEM_rptr(OCSP_REQUEST), - (ASN1_VALUE *)req); -} - -int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, - const char *name, const char *value) -{ - if (!name) - return 0; - if (BIO_puts(rctx->mem, name) <= 0) - return 0; - if (value) { - if (BIO_write(rctx->mem, ": ", 2) != 2) - return 0; - if (BIO_puts(rctx->mem, value) <= 0) - return 0; - } - if (BIO_write(rctx->mem, "\r\n", 2) != 2) - return 0; - rctx->state = OHS_HTTP_HEADER; - return 1; -} - -OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, const char *path, OCSP_REQUEST *req, - int maxline) -{ - - OCSP_REQ_CTX *rctx = NULL; - rctx = OCSP_REQ_CTX_new(io, maxline); - if (!rctx) - return NULL; - - if (!OCSP_REQ_CTX_http(rctx, "POST", path)) - goto err; - - if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) - goto err; - - return rctx; - - err: - OCSP_REQ_CTX_free(rctx); - return NULL; -} - -/* - * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We - * need to obtain the numeric code and (optional) informational message. - */ - -static int parse_http_line1(char *line) -{ - int retcode; - char *p, *q, *r; - /* Skip to first white space (passed protocol info) */ - - for (p = line; *p && !isspace((unsigned char)*p); p++) - continue; - if (!*p) { - OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Skip past white space to start of response code */ - while (*p && isspace((unsigned char)*p)) - p++; - - if (!*p) { - OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Find end of response code: first whitespace after start of code */ - for (q = p; *q && !isspace((unsigned char)*q); q++) - continue; - - if (!*q) { - OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); - return 0; - } - - /* Set end of response code and start of message */ - *q++ = 0; - - /* Attempt to parse numeric code */ - retcode = strtoul(p, &r, 10); - - if (*r) - return 0; - - /* Skip over any leading white space in message */ - while (*q && isspace((unsigned char)*q)) - q++; - - if (*q) { - /* - * Finally zap any trailing white space in message (include CRLF) - */ - - /* We know q has a non white space character so this is OK */ - for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) - *r = 0; - } - if (retcode != 200) { - OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR); - if (!*q) - ERR_add_error_data(2, "Code=", p); - else - ERR_add_error_data(4, "Code=", p, ",Reason=", q); - return 0; - } - - return 1; - -} - -int OCSP_REQ_CTX_nbio(OCSP_REQ_CTX *rctx) -{ - int i, n; - const unsigned char *p; - next_io: - if (!(rctx->state & OHS_NOREAD)) { - n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen); - - if (n <= 0) { - if (BIO_should_retry(rctx->io)) - return -1; - return 0; - } - - /* Write data to memory BIO */ - - if (BIO_write(rctx->mem, rctx->iobuf, n) != n) - return 0; - } - - switch (rctx->state) { - case OHS_HTTP_HEADER: - /* Last operation was adding headers: need a final \r\n */ - if (BIO_write(rctx->mem, "\r\n", 2) != 2) { - rctx->state = OHS_ERROR; - return 0; - } - rctx->state = OHS_ASN1_WRITE_INIT; - - case OHS_ASN1_WRITE_INIT: - rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); - rctx->state = OHS_ASN1_WRITE; - - case OHS_ASN1_WRITE: - n = BIO_get_mem_data(rctx->mem, &p); - - i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len); - - if (i <= 0) { - if (BIO_should_retry(rctx->io)) - return -1; - rctx->state = OHS_ERROR; - return 0; - } - - rctx->asn1_len -= i; - - if (rctx->asn1_len > 0) - goto next_io; - - rctx->state = OHS_ASN1_FLUSH; - - (void)BIO_reset(rctx->mem); - - case OHS_ASN1_FLUSH: - - i = BIO_flush(rctx->io); - - if (i > 0) { - rctx->state = OHS_FIRSTLINE; - goto next_io; - } - - if (BIO_should_retry(rctx->io)) - return -1; - - rctx->state = OHS_ERROR; - return 0; - - case OHS_ERROR: - return 0; - - case OHS_FIRSTLINE: - case OHS_HEADERS: - - /* Attempt to read a line in */ - - next_line: - /* - * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check - * there's a complete line in there before calling BIO_gets or we'll - * just get a partial read. - */ - n = BIO_get_mem_data(rctx->mem, &p); - if ((n <= 0) || !memchr(p, '\n', n)) { - if (n >= rctx->iobuflen) { - rctx->state = OHS_ERROR; - return 0; - } - goto next_io; - } - n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); - - if (n <= 0) { - if (BIO_should_retry(rctx->mem)) - goto next_io; - rctx->state = OHS_ERROR; - return 0; - } - - /* Don't allow excessive lines */ - if (n == rctx->iobuflen) { - rctx->state = OHS_ERROR; - return 0; - } - - /* First line */ - if (rctx->state == OHS_FIRSTLINE) { - if (parse_http_line1((char *)rctx->iobuf)) { - rctx->state = OHS_HEADERS; - goto next_line; - } else { - rctx->state = OHS_ERROR; - return 0; - } - } else { - /* Look for blank line: end of headers */ - for (p = rctx->iobuf; *p; p++) { - if ((*p != '\r') && (*p != '\n')) - break; - } - if (*p) - goto next_line; - - rctx->state = OHS_ASN1_HEADER; - - } - - /* Fall thru */ - - case OHS_ASN1_HEADER: - /* - * Now reading ASN1 header: can read at least 2 bytes which is enough - * for ASN1 SEQUENCE header and either length field or at least the - * length of the length field. - */ - n = BIO_get_mem_data(rctx->mem, &p); - if (n < 2) - goto next_io; - - /* Check it is an ASN1 SEQUENCE */ - if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { - rctx->state = OHS_ERROR; - return 0; - } - - /* Check out length field */ - if (*p & 0x80) { - /* - * If MSB set on initial length octet we can now always read 6 - * octets: make sure we have them. - */ - if (n < 6) - goto next_io; - n = *p & 0x7F; - /* Not NDEF or excessive length */ - if (!n || (n > 4)) { - rctx->state = OHS_ERROR; - return 0; - } - p++; - rctx->asn1_len = 0; - for (i = 0; i < n; i++) { - rctx->asn1_len <<= 8; - rctx->asn1_len |= *p++; - } - - if (rctx->asn1_len > rctx->max_resp_len) { - rctx->state = OHS_ERROR; - return 0; - } - - rctx->asn1_len += n + 2; - } else - rctx->asn1_len = *p + 2; - - rctx->state = OHS_ASN1_CONTENT; - - /* Fall thru */ - - case OHS_ASN1_CONTENT: - n = BIO_get_mem_data(rctx->mem, NULL); - if (n < (int)rctx->asn1_len) - goto next_io; - - rctx->state = OHS_DONE; - return 1; - - break; - - case OHS_DONE: - return 1; - - } - - return 0; - -} - -int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) -{ - return OCSP_REQ_CTX_nbio_d2i(rctx, - (ASN1_VALUE **)presp, - ASN1_ITEM_rptr(OCSP_RESPONSE)); -} - -/* Blocking OCSP request handler: now a special case of non-blocking I/O */ - -OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, const char *path, OCSP_REQUEST *req) -{ - OCSP_RESPONSE *resp = NULL; - OCSP_REQ_CTX *ctx; - int rv; - - ctx = OCSP_sendreq_new(b, path, req, -1); - - if (!ctx) - return NULL; - - do { - rv = OCSP_sendreq_nbio(&resp, ctx); - } while ((rv == -1) && BIO_should_retry(b)); - - OCSP_REQ_CTX_free(ctx); - - if (rv) - return resp; - - return NULL; -} -/* ocsp_lib.c */ -/* - * Written by Tom Titchener for the OpenSSL - * project. - */ - -/* - * History: This file was transfered to Richard Levitte from CertCo by Kathy - * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a - * patch kit. - */ - -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "rand.h" -// #include "x509.h" -// #include "pem.h" -// #include "x509v3.h" -// #include "ocsp.h" -// #include "asn1t.h" - -/* Convert a certificate and its issuer to an OCSP_CERTID */ - -OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer) -{ - X509_NAME *iname; - ASN1_INTEGER *serial; - ASN1_BIT_STRING *ikey; -#ifndef OPENSSL_NO_SHA1 - if (!dgst) - dgst = EVP_sha1(); -#endif - if (subject) { - iname = X509_get_issuer_name(subject); - serial = X509_get_serialNumber(subject); - } else { - iname = X509_get_subject_name(issuer); - serial = NULL; - } - ikey = X509_get0_pubkey_bitstr(issuer); - return OCSP_cert_id_new(dgst, iname, ikey, serial); -} - -OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, - X509_NAME *issuerName, - ASN1_BIT_STRING *issuerKey, - ASN1_INTEGER *serialNumber) -{ - int nid; - unsigned int i; - X509_ALGOR *alg; - OCSP_CERTID *cid = NULL; - unsigned char md[EVP_MAX_MD_SIZE]; - - if (!(cid = OCSP_CERTID_new())) - goto err; - - alg = cid->hashAlgorithm; - if (alg->algorithm != NULL) - ASN1_OBJECT_free(alg->algorithm); - if ((nid = EVP_MD_type(dgst)) == NID_undef) { - OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID); - goto err; - } - if (!(alg->algorithm = OBJ_nid2obj(nid))) - goto err; - if ((alg->parameter = ASN1_TYPE_new()) == NULL) - goto err; - alg->parameter->type = V_ASN1_NULL; - - if (!X509_NAME_digest(issuerName, dgst, md, &i)) - goto digerr; - if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) - goto err; - - /* Calculate the issuerKey hash, excluding tag and length */ - if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL)) - goto err; - - if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) - goto err; - - if (serialNumber) { - ASN1_INTEGER_free(cid->serialNumber); - if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) - goto err; - } - return cid; - digerr: - OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR); - err: - if (cid) - OCSP_CERTID_free(cid); - return NULL; -} - -int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b) -{ - int ret; - ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm); - if (ret) - return ret; - ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash); - if (ret) - return ret; - return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash); -} - -int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b) -{ - int ret; - ret = OCSP_id_issuer_cmp(a, b); - if (ret) - return ret; - return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber); -} - -/* - * Parse a URL and split it up into host, port and path components and - * whether it is SSL. - */ - -int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath, - int *pssl) -{ - char *p, *buf; - - char *host, *port; - - *phost = NULL; - *pport = NULL; - *ppath = NULL; - - /* dup the buffer since we are going to mess with it */ - buf = BUF_strdup(url); - if (!buf) - goto mem_err; - - /* Check for initial colon */ - p = strchr(buf, ':'); - - if (!p) - goto parse_err; - - *(p++) = '\0'; - - if (!strcmp(buf, "http")) { - *pssl = 0; - port = "80"; - } else if (!strcmp(buf, "https")) { - *pssl = 1; - port = "443"; - } else - goto parse_err; - - /* Check for double slash */ - if ((p[0] != '/') || (p[1] != '/')) - goto parse_err; - - p += 2; - - host = p; - - /* Check for trailing part of path */ - - p = strchr(p, '/'); - - if (!p) - *ppath = BUF_strdup("/"); - else { - *ppath = BUF_strdup(p); - /* Set start of path to 0 so hostname is valid */ - *p = '\0'; - } - - if (!*ppath) - goto mem_err; - - p = host; - if (host[0] == '[') { - /* ipv6 literal */ - host++; - p = strchr(host, ']'); - if (!p) - goto parse_err; - *p = '\0'; - p++; - } - - /* Look for optional ':' for port number */ - if ((p = strchr(p, ':'))) { - *p = 0; - port = p + 1; - } - - *pport = BUF_strdup(port); - if (!*pport) - goto mem_err; - - *phost = BUF_strdup(host); - - if (!*phost) - goto mem_err; - - OPENSSL_free(buf); - - return 1; - - mem_err: - OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE); - goto err; - - parse_err: - OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL); - - err: - if (buf) - OPENSSL_free(buf); - if (*ppath) { - OPENSSL_free(*ppath); - *ppath = NULL; - } - if (*pport) { - OPENSSL_free(*pport); - *pport = NULL; - } - if (*phost) { - OPENSSL_free(*phost); - *phost = NULL; - } - return 0; - -} - -IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID) -/* ocsp_prn.c */ -/* - * Written by Tom Titchener for the OpenSSL - * project. - */ - -/* - * History: This file was originally part of ocsp.c and was transfered to - * Richard Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be - * included in OpenSSL or released as a patch kit. - */ - -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "bio.h" -// #include "err.h" -// #include "ocsp.h" -// #include "pem.h" - -static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent) -{ - BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); - indent += 2; - BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); - i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); - BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); - i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); - BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); - i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); - BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); - i2a_ASN1_INTEGER(bp, a->serialNumber); - BIO_printf(bp, "\n"); - return 1; -} - -typedef struct { - long t; - const char *m; -} OCSP_TBLSTR; - -static const char *table2string(long s, const OCSP_TBLSTR *ts, int len) -{ - const OCSP_TBLSTR *p; - for (p = ts; p < ts + len; p++) - if (p->t == s) - return p->m; - return "(UNKNOWN)"; -} - -const char *OCSP_response_status_str(long s) -{ - static const OCSP_TBLSTR rstat_tbl[] = { - {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"}, - {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"}, - {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"}, - {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"}, - {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"}, - {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"} - }; - return table2string(s, rstat_tbl, 6); -} - -const char *OCSP_cert_status_str(long s) -{ - static const OCSP_TBLSTR cstat_tbl[] = { - {V_OCSP_CERTSTATUS_GOOD, "good"}, - {V_OCSP_CERTSTATUS_REVOKED, "revoked"}, - {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"} - }; - return table2string(s, cstat_tbl, 3); -} - -const char *OCSP_crl_reason_str(long s) -{ - static const OCSP_TBLSTR reason_tbl[] = { - {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"}, - {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"}, - {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"}, - {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"}, - {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"}, - {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"}, - {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"}, - {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"} - }; - return table2string(s, reason_tbl, 8); -} - -int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags) -{ - int i; - long l; - OCSP_CERTID *cid = NULL; - OCSP_ONEREQ *one = NULL; - OCSP_REQINFO *inf = o->tbsRequest; - OCSP_SIGNATURE *sig = o->optionalSignature; - - if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0) - goto err; - l = ASN1_INTEGER_get(inf->version); - if (BIO_printf(bp, " Version: %lu (0x%lx)", l + 1, l) <= 0) - goto err; - if (inf->requestorName != NULL) { - if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0) - goto err; - GENERAL_NAME_print(bp, inf->requestorName); - } - if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0) - goto err; - for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { - one = sk_OCSP_ONEREQ_value(inf->requestList, i); - cid = one->reqCert; - ocsp_certid_print(bp, cid, 8); - if (!X509V3_extensions_print(bp, - "Request Single Extensions", - one->singleRequestExtensions, flags, 8)) - goto err; - } - if (!X509V3_extensions_print(bp, "Request Extensions", - inf->requestExtensions, flags, 4)) - goto err; - if (sig) { - X509_signature_print(bp, sig->signatureAlgorithm, sig->signature); - for (i = 0; i < sk_X509_num(sig->certs); i++) { - X509_print(bp, sk_X509_value(sig->certs, i)); - PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i)); - } - } - return 1; - err: - return 0; -} - -int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags) -{ - int i, ret = 0; - long l; - OCSP_CERTID *cid = NULL; - OCSP_BASICRESP *br = NULL; - OCSP_RESPID *rid = NULL; - OCSP_RESPDATA *rd = NULL; - OCSP_CERTSTATUS *cst = NULL; - OCSP_REVOKEDINFO *rev = NULL; - OCSP_SINGLERESP *single = NULL; - OCSP_RESPBYTES *rb = o->responseBytes; - - if (BIO_puts(bp, "OCSP Response Data:\n") <= 0) - goto err; - l = ASN1_ENUMERATED_get(o->responseStatus); - if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n", - OCSP_response_status_str(l), l) <= 0) - goto err; - if (rb == NULL) - return 1; - if (BIO_puts(bp, " Response Type: ") <= 0) - goto err; - if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) - goto err; - if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { - BIO_puts(bp, " (unknown response type)\n"); - return 1; - } - - if ((br = OCSP_response_get1_basic(o)) == NULL) - goto err; - rd = br->tbsResponseData; - l = ASN1_INTEGER_get(rd->version); - if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l + 1, l) <= 0) - goto err; - if (BIO_puts(bp, " Responder Id: ") <= 0) - goto err; - - rid = rd->responderId; - switch (rid->type) { - case V_OCSP_RESPID_NAME: - X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); - break; - case V_OCSP_RESPID_KEY: - i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); - break; - } - - if (BIO_printf(bp, "\n Produced At: ") <= 0) - goto err; - if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) - goto err; - if (BIO_printf(bp, "\n Responses:\n") <= 0) - goto err; - for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { - if (!sk_OCSP_SINGLERESP_value(rd->responses, i)) - continue; - single = sk_OCSP_SINGLERESP_value(rd->responses, i); - cid = single->certId; - if (ocsp_certid_print(bp, cid, 4) <= 0) - goto err; - cst = single->certStatus; - if (BIO_printf(bp, " Cert Status: %s", - OCSP_cert_status_str(cst->type)) <= 0) - goto err; - if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { - rev = cst->value.revoked; - if (BIO_printf(bp, "\n Revocation Time: ") <= 0) - goto err; - if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime)) - goto err; - if (rev->revocationReason) { - l = ASN1_ENUMERATED_get(rev->revocationReason); - if (BIO_printf(bp, - "\n Revocation Reason: %s (0x%lx)", - OCSP_crl_reason_str(l), l) <= 0) - goto err; - } - } - if (BIO_printf(bp, "\n This Update: ") <= 0) - goto err; - if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) - goto err; - if (single->nextUpdate) { - if (BIO_printf(bp, "\n Next Update: ") <= 0) - goto err; - if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) - goto err; - } - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - if (!X509V3_extensions_print(bp, - "Response Single Extensions", - single->singleExtensions, flags, 8)) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (!X509V3_extensions_print(bp, "Response Extensions", - rd->responseExtensions, flags, 4)) - goto err; - if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) - goto err; - - for (i = 0; i < sk_X509_num(br->certs); i++) { - X509_print(bp, sk_X509_value(br->certs, i)); - PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); - } - - ret = 1; - err: - OCSP_BASICRESP_free(br); - return ret; -} -/* ocsp_srv.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "rand.h" -// #include "x509.h" -// #include "pem.h" -// #include "x509v3.h" -// #include "ocsp.h" - -/* - * Utility functions related to sending OCSP responses and extracting - * relevant information from the request. - */ - -int OCSP_request_onereq_count(OCSP_REQUEST *req) -{ - return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList); -} - -OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i) -{ - return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i); -} - -OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one) -{ - return one->reqCert; -} - -int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, - ASN1_OCTET_STRING **pikeyHash, - ASN1_INTEGER **pserial, OCSP_CERTID *cid) -{ - if (!cid) - return 0; - if (pmd) - *pmd = cid->hashAlgorithm->algorithm; - if (piNameHash) - *piNameHash = cid->issuerNameHash; - if (pikeyHash) - *pikeyHash = cid->issuerKeyHash; - if (pserial) - *pserial = cid->serialNumber; - return 1; -} - -int OCSP_request_is_signed(OCSP_REQUEST *req) -{ - if (req->optionalSignature) - return 1; - return 0; -} - -/* Create an OCSP response and encode an optional basic response */ -OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs) -{ - OCSP_RESPONSE *rsp = NULL; - - if (!(rsp = OCSP_RESPONSE_new())) - goto err; - if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status))) - goto err; - if (!bs) - return rsp; - if (!(rsp->responseBytes = OCSP_RESPBYTES_new())) - goto err; - rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic); - if (!ASN1_item_pack - (bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response)) - goto err; - return rsp; - err: - if (rsp) - OCSP_RESPONSE_free(rsp); - return NULL; -} - -OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, - OCSP_CERTID *cid, - int status, int reason, - ASN1_TIME *revtime, - ASN1_TIME *thisupd, - ASN1_TIME *nextupd) -{ - OCSP_SINGLERESP *single = NULL; - OCSP_CERTSTATUS *cs; - OCSP_REVOKEDINFO *ri; - - if (!rsp->tbsResponseData->responses && - !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null())) - goto err; - - if (!(single = OCSP_SINGLERESP_new())) - goto err; - - if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate)) - goto err; - if (nextupd && - !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate)) - goto err; - - OCSP_CERTID_free(single->certId); - - if (!(single->certId = OCSP_CERTID_dup(cid))) - goto err; - - cs = single->certStatus; - switch (cs->type = status) { - case V_OCSP_CERTSTATUS_REVOKED: - if (!revtime) { - OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS, OCSP_R_NO_REVOKED_TIME); - goto err; - } - if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new())) - goto err; - if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime)) - goto err; - if (reason != OCSP_REVOKED_STATUS_NOSTATUS) { - if (!(ri->revocationReason = ASN1_ENUMERATED_new())) - goto err; - if (!(ASN1_ENUMERATED_set(ri->revocationReason, reason))) - goto err; - } - break; - - case V_OCSP_CERTSTATUS_GOOD: - cs->value.good = ASN1_NULL_new(); - break; - - case V_OCSP_CERTSTATUS_UNKNOWN: - cs->value.unknown = ASN1_NULL_new(); - break; - - default: - goto err; - - } - if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single))) - goto err; - return single; - err: - OCSP_SINGLERESP_free(single); - return NULL; -} - -/* Add a certificate to an OCSP request */ - -int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) -{ - if (!resp->certs && !(resp->certs = sk_X509_new_null())) - return 0; - - if (!sk_X509_push(resp->certs, cert)) - return 0; - CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); - return 1; -} - -int OCSP_basic_sign(OCSP_BASICRESP *brsp, - X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, - STACK_OF(X509) *certs, unsigned long flags) -{ - int i; - OCSP_RESPID *rid; - - if (!X509_check_private_key(signer, key)) { - OCSPerr(OCSP_F_OCSP_BASIC_SIGN, - OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); - goto err; - } - - if (!(flags & OCSP_NOCERTS)) { - if (!OCSP_basic_add1_cert(brsp, signer)) - goto err; - for (i = 0; i < sk_X509_num(certs); i++) { - X509 *tmpcert = sk_X509_value(certs, i); - if (!OCSP_basic_add1_cert(brsp, tmpcert)) - goto err; - } - } - - rid = brsp->tbsResponseData->responderId; - if (flags & OCSP_RESPID_KEY) { - unsigned char md[SHA_DIGEST_LENGTH]; - X509_pubkey_digest(signer, EVP_sha1(), md, NULL); - if (!(rid->value.byKey = ASN1_OCTET_STRING_new())) - goto err; - if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md, SHA_DIGEST_LENGTH))) - goto err; - rid->type = V_OCSP_RESPID_KEY; - } else { - if (!X509_NAME_set(&rid->value.byName, X509_get_subject_name(signer))) - goto err; - rid->type = V_OCSP_RESPID_NAME; - } - - if (!(flags & OCSP_NOTIME) && - !X509_gmtime_adj(brsp->tbsResponseData->producedAt, 0)) - goto err; - - /* - * Right now, I think that not doing double hashing is the right thing. - * -- Richard Levitte - */ - - if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0)) - goto err; - - return 1; - err: - return 0; -} -/* ocsp_vfy.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ocsp.h" -// #include "err.h" -#include - -static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, - STACK_OF(X509) *certs, X509_STORE *st, - unsigned long flags); -static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); -static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, - unsigned long flags); -static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, - OCSP_CERTID **ret); -static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, - STACK_OF(OCSP_SINGLERESP) *sresp); -static int ocsp_check_delegated(X509 *x, int flags); -static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, - X509_NAME *nm, STACK_OF(X509) *certs, - X509_STORE *st, unsigned long flags); - -/* Verify a basic response message */ - -int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, - X509_STORE *st, unsigned long flags) -{ - X509 *signer, *x; - STACK_OF(X509) *chain = NULL; - STACK_OF(X509) *untrusted = NULL; - X509_STORE_CTX ctx; - int i, ret = 0; - ret = ocsp_find_signer(&signer, bs, certs, st, flags); - if (!ret) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, - OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); - goto end; - } - if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) - flags |= OCSP_NOVERIFY; - if (!(flags & OCSP_NOSIGS)) { - EVP_PKEY *skey; - skey = X509_get_pubkey(signer); - if (skey) { - ret = OCSP_BASICRESP_verify(bs, skey, 0); - EVP_PKEY_free(skey); - } - if (!skey || ret <= 0) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); - goto end; - } - } - if (!(flags & OCSP_NOVERIFY)) { - int init_res; - if (flags & OCSP_NOCHAIN) { - untrusted = NULL; - } else if (bs->certs && certs) { - untrusted = sk_X509_dup(bs->certs); - for (i = 0; i < sk_X509_num(certs); i++) { - if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); - goto end; - } - } - } else if (certs != NULL) { - untrusted = certs; - } else { - untrusted = bs->certs; - } - init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted); - if (!init_res) { - ret = -1; - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB); - goto end; - } - - X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); - ret = X509_verify_cert(&ctx); - chain = X509_STORE_CTX_get1_chain(&ctx); - X509_STORE_CTX_cleanup(&ctx); - if (ret <= 0) { - i = X509_STORE_CTX_get_error(&ctx); - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, - OCSP_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(i)); - goto end; - } - if (flags & OCSP_NOCHECKS) { - ret = 1; - goto end; - } - /* - * At this point we have a valid certificate chain need to verify it - * against the OCSP issuer criteria. - */ - ret = ocsp_check_issuer(bs, chain, flags); - - /* If fatal error or valid match then finish */ - if (ret != 0) - goto end; - - /* - * Easy case: explicitly trusted. Get root CA and check for explicit - * trust - */ - if (flags & OCSP_NOEXPLICIT) - goto end; - - x = sk_X509_value(chain, sk_X509_num(chain) - 1); - if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) { - OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED); - goto end; - } - ret = 1; - } - - end: - if (chain) - sk_X509_pop_free(chain, X509_free); - if (bs->certs && certs) - sk_X509_free(untrusted); - return ret; -} - -static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, - STACK_OF(X509) *certs, X509_STORE *st, - unsigned long flags) -{ - X509 *signer; - OCSP_RESPID *rid = bs->tbsResponseData->responderId; - if ((signer = ocsp_find_signer_sk(certs, rid))) { - *psigner = signer; - return 2; - } - if (!(flags & OCSP_NOINTERN) && - (signer = ocsp_find_signer_sk(bs->certs, rid))) { - *psigner = signer; - return 1; - } - /* Maybe lookup from store if by subject name */ - - *psigner = NULL; - return 0; -} - -static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) -{ - int i; - unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; - X509 *x; - - /* Easy if lookup by name */ - if (id->type == V_OCSP_RESPID_NAME) - return X509_find_by_subject(certs, id->value.byName); - - /* Lookup by key hash */ - - /* If key hash isn't SHA1 length then forget it */ - if (id->value.byKey->length != SHA_DIGEST_LENGTH) - return NULL; - keyhash = id->value.byKey->data; - /* Calculate hash of each key and compare */ - for (i = 0; i < sk_X509_num(certs); i++) { - x = sk_X509_value(certs, i); - X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); - if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) - return x; - } - return NULL; -} - -static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, - unsigned long flags) -{ - STACK_OF(OCSP_SINGLERESP) *sresp; - X509 *signer, *sca; - OCSP_CERTID *caid = NULL; - int i; - sresp = bs->tbsResponseData->responses; - - if (sk_X509_num(chain) <= 0) { - OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN); - return -1; - } - - /* See if the issuer IDs match. */ - i = ocsp_check_ids(sresp, &caid); - - /* If ID mismatch or other error then return */ - if (i <= 0) - return i; - - signer = sk_X509_value(chain, 0); - /* Check to see if OCSP responder CA matches request CA */ - if (sk_X509_num(chain) > 1) { - sca = sk_X509_value(chain, 1); - i = ocsp_match_issuerid(sca, caid, sresp); - if (i < 0) - return i; - if (i) { - /* We have a match, if extensions OK then success */ - if (ocsp_check_delegated(signer, flags)) - return 1; - return 0; - } - } - - /* Otherwise check if OCSP request signed directly by request CA */ - return ocsp_match_issuerid(signer, caid, sresp); -} - -/* - * Check the issuer certificate IDs for equality. If there is a mismatch with - * the same algorithm then there's no point trying to match any certificates - * against the issuer. If the issuer IDs all match then we just need to check - * equality against one of them. - */ - -static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) -{ - OCSP_CERTID *tmpid, *cid; - int i, idcount; - - idcount = sk_OCSP_SINGLERESP_num(sresp); - if (idcount <= 0) { - OCSPerr(OCSP_F_OCSP_CHECK_IDS, - OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); - return -1; - } - - cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; - - *ret = NULL; - - for (i = 1; i < idcount; i++) { - tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; - /* Check to see if IDs match */ - if (OCSP_id_issuer_cmp(cid, tmpid)) { - /* If algoritm mismatch let caller deal with it */ - if (OBJ_cmp(tmpid->hashAlgorithm->algorithm, - cid->hashAlgorithm->algorithm)) - return 2; - /* Else mismatch */ - return 0; - } - } - - /* All IDs match: only need to check one ID */ - *ret = cid; - return 1; -} - -static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, - STACK_OF(OCSP_SINGLERESP) *sresp) -{ - /* If only one ID to match then do it */ - if (cid) { - const EVP_MD *dgst; - X509_NAME *iname; - int mdlen; - unsigned char md[EVP_MAX_MD_SIZE]; - if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) { - OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, - OCSP_R_UNKNOWN_MESSAGE_DIGEST); - return -1; - } - - mdlen = EVP_MD_size(dgst); - if (mdlen < 0) - return -1; - if ((cid->issuerNameHash->length != mdlen) || - (cid->issuerKeyHash->length != mdlen)) - return 0; - iname = X509_get_subject_name(cert); - if (!X509_NAME_digest(iname, dgst, md, NULL)) - return -1; - if (memcmp(md, cid->issuerNameHash->data, mdlen)) - return 0; - X509_pubkey_digest(cert, dgst, md, NULL); - if (memcmp(md, cid->issuerKeyHash->data, mdlen)) - return 0; - - return 1; - - } else { - /* We have to match the whole lot */ - int i, ret; - OCSP_CERTID *tmpid; - for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { - tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; - ret = ocsp_match_issuerid(cert, tmpid, NULL); - if (ret <= 0) - return ret; - } - return 1; - } - -} - -static int ocsp_check_delegated(X509 *x, int flags) -{ - X509_check_purpose(x, -1, 0); - if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN)) - return 1; - OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE); - return 0; -} - -/* - * Verify an OCSP request. This is fortunately much easier than OCSP response - * verify. Just find the signers certificate and verify it against a given - * trust value. - */ - -int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, - X509_STORE *store, unsigned long flags) -{ - X509 *signer; - X509_NAME *nm; - GENERAL_NAME *gen; - int ret; - X509_STORE_CTX ctx; - if (!req->optionalSignature) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); - return 0; - } - gen = req->tbsRequest->requestorName; - if (!gen || gen->type != GEN_DIRNAME) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, - OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); - return 0; - } - nm = gen->d.directoryName; - ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags); - if (ret <= 0) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, - OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); - return 0; - } - if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) - flags |= OCSP_NOVERIFY; - if (!(flags & OCSP_NOSIGS)) { - EVP_PKEY *skey; - skey = X509_get_pubkey(signer); - ret = OCSP_REQUEST_verify(req, skey); - EVP_PKEY_free(skey); - if (ret <= 0) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); - return 0; - } - } - if (!(flags & OCSP_NOVERIFY)) { - int init_res; - if (flags & OCSP_NOCHAIN) - init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL); - else - init_res = X509_STORE_CTX_init(&ctx, store, signer, - req->optionalSignature->certs); - if (!init_res) { - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB); - return 0; - } - - X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); - X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST); - ret = X509_verify_cert(&ctx); - X509_STORE_CTX_cleanup(&ctx); - if (ret <= 0) { - ret = X509_STORE_CTX_get_error(&ctx); - OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, - OCSP_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(ret)); - return 0; - } - } - return 1; -} - -static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, - X509_NAME *nm, STACK_OF(X509) *certs, - X509_STORE *st, unsigned long flags) -{ - X509 *signer; - if (!(flags & OCSP_NOINTERN)) { - signer = X509_find_by_subject(req->optionalSignature->certs, nm); - if (signer) { - *psigner = signer; - return 1; - } - } - - signer = X509_find_by_subject(certs, nm); - if (signer) { - *psigner = signer; - return 2; - } - return 0; -} diff --git a/Sources/COpenSSL/ofb128.c b/Sources/COpenSSL/ofb128.c deleted file mode 100644 index ff8e1453..00000000 --- a/Sources/COpenSSL/ofb128.c +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "crypto.h" -#include "modes_lcl.h" -#include - -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -/* - * The input and output encrypted as though 128bit ofb mode is being used. - * The extra state information to record how much of the 128bit block we have - * used is contained in *num; - */ -void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *key, - unsigned char ivec[16], int *num, block128_f block) -{ - unsigned int n; - size_t l = 0; - - assert(in && out && key && ivec && num); - - n = *num; - -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (16 % sizeof(size_t) == 0) { /* always true actually */ - do { - while (n && len) { - *(out++) = *(in++) ^ ivec[n]; - --len; - n = (n + 1) % 16; - } -# if defined(STRICT_ALIGNMENT) - if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != - 0) - break; -# endif - while (len >= 16) { - (*block) (ivec, ivec, key); - for (; n < 16; n += sizeof(size_t)) - *(size_t *)(out + n) = - *(size_t *)(in + n) ^ *(size_t *)(ivec + n); - len -= 16; - out += 16; - in += 16; - n = 0; - } - if (len) { - (*block) (ivec, ivec, key); - while (len--) { - out[n] = in[n] ^ ivec[n]; - ++n; - } - } - *num = n; - return; - } while (0); - } - /* the rest would be commonly eliminated by x86* compiler */ -#endif - while (l < len) { - if (n == 0) { - (*block) (ivec, ivec, key); - } - out[l] = in[l] ^ ivec[n]; - ++l; - n = (n + 1) % 16; - } - - *num = n; -} diff --git a/Sources/COpenSSL/ofb64ede.c b/Sources/COpenSSL/ofb64ede.c deleted file mode 100644 index 45c67505..00000000 --- a/Sources/COpenSSL/ofb64ede.c +++ /dev/null @@ -1,123 +0,0 @@ -/* crypto/des/ofb64ede.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -/* - * The input and output encrypted as though 64bit ofb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ -void DES_ede3_ofb64_encrypt(register const unsigned char *in, - register unsigned char *out, long length, - DES_key_schedule *k1, DES_key_schedule *k2, - DES_key_schedule *k3, DES_cblock *ivec, int *num) -{ - register DES_LONG v0, v1; - register int n = *num; - register long l = length; - DES_cblock d; - register char *dp; - DES_LONG ti[2]; - unsigned char *iv; - int save = 0; - - iv = &(*ivec)[0]; - c2l(iv, v0); - c2l(iv, v1); - ti[0] = v0; - ti[1] = v1; - dp = (char *)d; - l2c(v0, dp); - l2c(v1, dp); - while (l--) { - if (n == 0) { - /* ti[0]=v0; */ - /* ti[1]=v1; */ - DES_encrypt3(ti, k1, k2, k3); - v0 = ti[0]; - v1 = ti[1]; - - dp = (char *)d; - l2c(v0, dp); - l2c(v1, dp); - save++; - } - *(out++) = *(in++) ^ d[n]; - n = (n + 1) & 0x07; - } - if (save) { -/*- v0=ti[0]; - v1=ti[1];*/ - iv = &(*ivec)[0]; - l2c(v0, iv); - l2c(v1, iv); - } - v0 = v1 = ti[0] = ti[1] = 0; - *num = n; -} - -#ifdef undef /* MACRO */ -void DES_ede2_ofb64_encrypt(register unsigned char *in, - register unsigned char *out, long length, - DES_key_schedule k1, DES_key_schedule k2, - DES_cblock (*ivec), int *num) -{ - DES_ede3_ofb64_encrypt(in, out, length, k1, k2, k1, ivec, num); -} -#endif diff --git a/Sources/COpenSSL/ofb64enc.c b/Sources/COpenSSL/ofb64enc.c deleted file mode 100644 index 8e72dece..00000000 --- a/Sources/COpenSSL/ofb64enc.c +++ /dev/null @@ -1,109 +0,0 @@ -/* crypto/des/ofb64enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -/* - * The input and output encrypted as though 64bit ofb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ -void DES_ofb64_encrypt(register const unsigned char *in, - register unsigned char *out, long length, - DES_key_schedule *schedule, DES_cblock *ivec, int *num) -{ - register DES_LONG v0, v1, t; - register int n = *num; - register long l = length; - DES_cblock d; - register unsigned char *dp; - DES_LONG ti[2]; - unsigned char *iv; - int save = 0; - - iv = &(*ivec)[0]; - c2l(iv, v0); - c2l(iv, v1); - ti[0] = v0; - ti[1] = v1; - dp = d; - l2c(v0, dp); - l2c(v1, dp); - while (l--) { - if (n == 0) { - DES_encrypt1(ti, schedule, DES_ENCRYPT); - dp = d; - t = ti[0]; - l2c(t, dp); - t = ti[1]; - l2c(t, dp); - save++; - } - *(out++) = *(in++) ^ d[n]; - n = (n + 1) & 0x07; - } - if (save) { - v0 = ti[0]; - v1 = ti[1]; - iv = &(*ivec)[0]; - l2c(v0, iv); - l2c(v1, iv); - } - t = v0 = v1 = ti[0] = ti[1] = 0; - *num = n; -} diff --git a/Sources/COpenSSL/ofb_enc.c b/Sources/COpenSSL/ofb_enc.c deleted file mode 100644 index 998a3cc9..00000000 --- a/Sources/COpenSSL/ofb_enc.c +++ /dev/null @@ -1,132 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/des/ofb_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -/* - * The input and output are loaded in multiples of 8 bits. What this means is - * that if you hame numbits=12 and length=2 the first 12 bits will be - * retrieved from the first byte and half the second. The second 12 bits - * will come from the 3rd and half the 4th byte. - */ -void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, - long length, DES_key_schedule *schedule, - DES_cblock *ivec) -{ - register DES_LONG d0, d1, vv0, vv1, v0, v1, n = (numbits + 7) / 8; - register DES_LONG mask0, mask1; - register long l = length; - register int num = numbits; - DES_LONG ti[2]; - unsigned char *iv; - - if (num > 64) - return; - if (num > 32) { - mask0 = 0xffffffffL; - if (num >= 64) - mask1 = mask0; - else - mask1 = (1L << (num - 32)) - 1; - } else { - if (num == 32) - mask0 = 0xffffffffL; - else - mask0 = (1L << num) - 1; - mask1 = 0x00000000L; - } - - iv = &(*ivec)[0]; - c2l(iv, v0); - c2l(iv, v1); - ti[0] = v0; - ti[1] = v1; - while (l-- > 0) { - ti[0] = v0; - ti[1] = v1; - DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); - vv0 = ti[0]; - vv1 = ti[1]; - c2ln(in, d0, d1, n); - in += n; - d0 = (d0 ^ vv0) & mask0; - d1 = (d1 ^ vv1) & mask1; - l2cn(d0, d1, out, n); - out += n; - - if (num == 32) { - v0 = v1; - v1 = vv0; - } else if (num == 64) { - v0 = vv0; - v1 = vv1; - } else if (num > 32) { /* && num != 64 */ - v0 = ((v1 >> (num - 32)) | (vv0 << (64 - num))) & 0xffffffffL; - v1 = ((vv0 >> (num - 32)) | (vv1 << (64 - num))) & 0xffffffffL; - } else { /* num < 32 */ - - v0 = ((v0 >> num) | (v1 << (32 - num))) & 0xffffffffL; - v1 = ((v1 >> num) | (vv0 << (32 - num))) & 0xffffffffL; - } - } - iv = &(*ivec)[0]; - l2c(v0, iv); - l2c(v1, iv); - v0 = v1 = d0 = d1 = ti[0] = ti[1] = vv0 = vv1 = 0; -} diff --git a/Sources/COpenSSL/openbsd_hw.c b/Sources/COpenSSL/openbsd_hw.c deleted file mode 100644 index 34b0dd84..00000000 --- a/Sources/COpenSSL/openbsd_hw.c +++ /dev/null @@ -1,453 +0,0 @@ -/* Written by Ben Laurie, 2001 */ -/* - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "evp.h" -#include "objects.h" -#include "rsa.h" -#include "evp_locl.h" - -/* - * This stuff should now all be supported through - * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up - */ -static void *dummy = &dummy; - -#if 0 - -/* check flag after OpenSSL headers to ensure make depend works */ -# ifdef OPENSSL_OPENBSD_DEV_CRYPTO - -# include -# include -# include -# include -# include -# include -# include - -/* longest key supported in hardware */ -# define MAX_HW_KEY 24 -# define MAX_HW_IV 8 - -# define MD5_DIGEST_LENGTH 16 -# define MD5_CBLOCK 64 - -static int fd; -static int dev_failed; - -typedef struct session_op session_op; - -# define CDATA(ctx) EVP_C_DATA(session_op,ctx) - -static void err(const char *str) -{ - fprintf(stderr, "%s: errno %d\n", str, errno); -} - -static int dev_crypto_init(session_op *ses) -{ - if (dev_failed) - return 0; - if (!fd) { - int cryptodev_fd; - - if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) { - err("/dev/crypto"); - dev_failed = 1; - return 0; - } - if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) { - err("CRIOGET failed"); - close(cryptodev_fd); - dev_failed = 1; - return 0; - } - close(cryptodev_fd); - } - assert(ses); - memset(ses, '\0', sizeof(*ses)); - - return 1; -} - -static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx) -{ - if (ioctl(fd, CIOCFSESSION, &CDATA(ctx)->ses) == -1) - err("CIOCFSESSION failed"); - - OPENSSL_free(CDATA(ctx)->key); - - return 1; -} - -static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx, int cipher, - const unsigned char *key, int klen) -{ - if (!dev_crypto_init(CDATA(ctx))) - return 0; - - CDATA(ctx)->key = OPENSSL_malloc(MAX_HW_KEY); - if (CDATA(ctx)->key == NULL { - err("CDATA(ctx)->key memory allocation failed"); - return 0; - } - - assert(ctx->cipher->iv_len <= MAX_HW_IV); - - memcpy(CDATA(ctx)->key, key, klen); - - CDATA(ctx)->cipher = cipher; - CDATA(ctx)->keylen = klen; - - if (ioctl(fd, CIOCGSESSION, CDATA(ctx)) == -1) { - err("CIOCGSESSION failed"); - return 0; - } - return 1; -} - -static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, unsigned int inl) -{ - struct crypt_op cryp; - unsigned char lb[MAX_HW_IV]; - - if (!inl) - return 1; - - assert(CDATA(ctx)); - assert(!dev_failed); - - memset(&cryp, '\0', sizeof(cryp)); - cryp.ses = CDATA(ctx)->ses; - cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; - cryp.flags = 0; - cryp.len = inl; - assert((inl & (ctx->cipher->block_size - 1)) == 0); - cryp.src = (caddr_t) in; - cryp.dst = (caddr_t) out; - cryp.mac = 0; - if (ctx->cipher->iv_len) - cryp.iv = (caddr_t) ctx->iv; - - if (!ctx->encrypt) - memcpy(lb, &in[cryp.len - ctx->cipher->iv_len], ctx->cipher->iv_len); - - if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { - if (errno == EINVAL) { /* buffers are misaligned */ - unsigned int cinl = 0; - char *cin = NULL; - char *cout = NULL; - - /* NB: this can only make cinl != inl with stream ciphers */ - cinl = (inl + 3) / 4 * 4; - - if (((unsigned long)in & 3) || cinl != inl) { - cin = OPENSSL_malloc(cinl); - if (cin == NULL) { - err("cin - memory allocation failed"); - abort(); - return 0; - } - memcpy(cin, in, inl); - cryp.src = cin; - } - - if (((unsigned long)out & 3) || cinl != inl) { - cout = OPENSSL_malloc(cinl); - cryp.dst = cout; - } - - cryp.len = cinl; - - if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { - err("CIOCCRYPT(2) failed"); - printf("src=%p dst=%p\n", cryp.src, cryp.dst); - abort(); - return 0; - } - - if (cout) { - memcpy(out, cout, inl); - OPENSSL_free(cout); - } - if (cin) - OPENSSL_free(cin); - } else { - err("CIOCCRYPT failed"); - abort(); - return 0; - } - } - - if (ctx->encrypt) - memcpy(ctx->iv, &out[cryp.len - ctx->cipher->iv_len], - ctx->cipher->iv_len); - else - memcpy(ctx->iv, lb, ctx->cipher->iv_len); - - return 1; -} - -static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, int enc) -{ - return dev_crypto_init_key(ctx, CRYPTO_3DES_CBC, key, 24); -} - -# define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher - -BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8, - 0, dev_crypto_des_ede3_init_key, - dev_crypto_cleanup, - EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) - -static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *key, - const unsigned char *iv, int enc) -{ - return dev_crypto_init_key(ctx, CRYPTO_ARC4, key, 16); -} - -static const EVP_CIPHER r4_cipher = { - NID_rc4, - 1, 16, 0, /* FIXME: key should be up to 256 bytes */ - EVP_CIPH_VARIABLE_LENGTH, - dev_crypto_rc4_init_key, - dev_crypto_cipher, - dev_crypto_cleanup, - sizeof(session_op), - NULL, - NULL, - NULL -}; - -const EVP_CIPHER *EVP_dev_crypto_rc4(void) -{ - return &r4_cipher; -} - -typedef struct { - session_op sess; - char *data; - int len; - unsigned char md[EVP_MAX_MD_SIZE]; -} MD_DATA; - -static int dev_crypto_init_digest(MD_DATA *md_data, int mac) -{ - if (!dev_crypto_init(&md_data->sess)) - return 0; - - md_data->len = 0; - md_data->data = NULL; - - md_data->sess.mac = mac; - - if (ioctl(fd, CIOCGSESSION, &md_data->sess) == -1) { - err("CIOCGSESSION failed"); - return 0; - } - return 1; -} - -static int dev_crypto_cleanup_digest(MD_DATA *md_data) -{ - if (ioctl(fd, CIOCFSESSION, &md_data->sess.ses) == -1) { - err("CIOCFSESSION failed"); - return 0; - } - - return 1; -} - -/* FIXME: if device can do chained MACs, then don't accumulate */ -/* FIXME: move accumulation to the framework */ -static int dev_crypto_md5_init(EVP_MD_CTX *ctx) -{ - return dev_crypto_init_digest(ctx->md_data, CRYPTO_MD5); -} - -static int do_digest(int ses, unsigned char *md, const void *data, int len) -{ - struct crypt_op cryp; - static unsigned char md5zero[16] = { - 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, - 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e - }; - - /* some cards can't do zero length */ - if (!len) { - memcpy(md, md5zero, 16); - return 1; - } - - memset(&cryp, '\0', sizeof(cryp)); - cryp.ses = ses; - cryp.op = COP_ENCRYPT; /* required to do the MAC rather than check - * it */ - cryp.len = len; - cryp.src = (caddr_t) data; - cryp.dst = (caddr_t) data; // FIXME!!! - cryp.mac = (caddr_t) md; - - if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { - if (errno == EINVAL) { /* buffer is misaligned */ - char *dcopy; - - dcopy = OPENSSL_malloc(len); - if (dcopy == NULL) { - err("dcopy - memory allocation failed"); - abort(); - return 0; - } - memcpy(dcopy, data, len); - cryp.src = dcopy; - cryp.dst = cryp.src; // FIXME!!! - - if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { - err("CIOCCRYPT(MAC2) failed"); - abort(); - return 0; - } - OPENSSL_free(dcopy); - } else { - err("CIOCCRYPT(MAC) failed"); - abort(); - return 0; - } - } - // printf("done\n"); - - return 1; -} - -static int dev_crypto_md5_update(EVP_MD_CTX *ctx, const void *data, - unsigned long len) -{ - MD_DATA *md_data = ctx->md_data; - - if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) - return do_digest(md_data->sess.ses, md_data->md, data, len); - - md_data->data = OPENSSL_realloc(md_data->data, md_data->len + len); - if (md_data->data == NULL) { - err("DEV_CRYPTO_MD5_UPDATE: unable to allocate memory"); - abort(); - } - memcpy(md_data->data + md_data->len, data, len); - md_data->len += len; - - return 1; -} - -static int dev_crypto_md5_final(EVP_MD_CTX *ctx, unsigned char *md) -{ - int ret; - MD_DATA *md_data = ctx->md_data; - - if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) { - memcpy(md, md_data->md, MD5_DIGEST_LENGTH); - ret = 1; - } else { - ret = do_digest(md_data->sess.ses, md, md_data->data, md_data->len); - OPENSSL_free(md_data->data); - md_data->data = NULL; - md_data->len = 0; - } - - return ret; -} - -static int dev_crypto_md5_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) -{ - const MD_DATA *from_md = from->md_data; - MD_DATA *to_md = to->md_data; - - // How do we copy sessions? - assert(from->digest->flags & EVP_MD_FLAG_ONESHOT); - - to_md->data = OPENSSL_malloc(from_md->len); - if (to_md->data == NULL) { - err("DEV_CRYPTO_MD5_COPY: unable to allocate memory"); - abort(); - } - memcpy(to_md->data, from_md->data, from_md->len); - - return 1; -} - -static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx) -{ - return dev_crypto_cleanup_digest(ctx->md_data); -} - -static const EVP_MD md5_md = { - NID_md5, - NID_md5WithRSAEncryption, - MD5_DIGEST_LENGTH, - EVP_MD_FLAG_ONESHOT, // XXX: set according to device info... - dev_crypto_md5_init, - dev_crypto_md5_update, - dev_crypto_md5_final, - dev_crypto_md5_copy, - dev_crypto_md5_cleanup, - EVP_PKEY_RSA_method, - MD5_CBLOCK, - sizeof(MD_DATA), -}; - -const EVP_MD *EVP_dev_crypto_md5(void) -{ - return &md5_md; -} - -# endif -#endif diff --git a/Sources/COpenSSL/opensslconf.h b/Sources/COpenSSL/opensslconf.h deleted file mode 100644 index 64f235ff..00000000 --- a/Sources/COpenSSL/opensslconf.h +++ /dev/null @@ -1,274 +0,0 @@ -/* opensslconf.h */ -/* WARNING: Generated automatically from opensslconf.h.in by Configure. */ - -#ifdef __cplusplus -extern "C" { -#endif -/* OpenSSL was configured with the following options: */ -#ifndef OPENSSL_SYSNAME_MACOSX -# define OPENSSL_SYSNAME_MACOSX -#endif -#ifndef OPENSSL_DOING_MAKEDEPEND - - -#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 -# define OPENSSL_NO_EC_NISTP_64_GCC_128 -#endif -#ifndef OPENSSL_NO_GMP -# define OPENSSL_NO_GMP -#endif -#ifndef OPENSSL_NO_JPAKE -# define OPENSSL_NO_JPAKE -#endif -#ifndef OPENSSL_NO_KRB5 -# define OPENSSL_NO_KRB5 -#endif -#ifndef OPENSSL_NO_LIBUNBOUND -# define OPENSSL_NO_LIBUNBOUND -#endif -#ifndef OPENSSL_NO_MD2 -# define OPENSSL_NO_MD2 -#endif -#ifndef OPENSSL_NO_RC5 -# define OPENSSL_NO_RC5 -#endif -#ifndef OPENSSL_NO_RFC3779 -# define OPENSSL_NO_RFC3779 -#endif -#ifndef OPENSSL_NO_SCTP -# define OPENSSL_NO_SCTP -#endif -#ifndef OPENSSL_NO_SSL_TRACE -# define OPENSSL_NO_SSL_TRACE -#endif -#ifndef OPENSSL_NO_SSL2 -# define OPENSSL_NO_SSL2 -#endif -#ifndef OPENSSL_NO_STORE -# define OPENSSL_NO_STORE -#endif -#ifndef OPENSSL_NO_UNIT_TEST -# define OPENSSL_NO_UNIT_TEST -#endif -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS -# define OPENSSL_NO_WEAK_SSL_CIPHERS -#endif - -#endif /* OPENSSL_DOING_MAKEDEPEND */ - -#ifndef OPENSSL_THREADS -# define OPENSSL_THREADS -#endif -#ifndef OPENSSL_NO_ASM -# define OPENSSL_NO_ASM -#endif -#ifndef OPENSSL_NO_DYNAMIC_ENGINE -# define OPENSSL_NO_DYNAMIC_ENGINE -#endif - -/* The OPENSSL_NO_* macros are also defined as NO_* if the application - asks for it. This is a transient feature that is provided for those - who haven't had the time to do the appropriate changes in their - applications. */ -#ifdef OPENSSL_ALGORITHM_DEFINES -# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128) -# define NO_EC_NISTP_64_GCC_128 -# endif -# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP) -# define NO_GMP -# endif -# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE) -# define NO_JPAKE -# endif -# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) -# define NO_KRB5 -# endif -# if defined(OPENSSL_NO_LIBUNBOUND) && !defined(NO_LIBUNBOUND) -# define NO_LIBUNBOUND -# endif -# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2) -# define NO_MD2 -# endif -# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) -# define NO_RC5 -# endif -# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779) -# define NO_RFC3779 -# endif -# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP) -# define NO_SCTP -# endif -# if defined(OPENSSL_NO_SSL_TRACE) && !defined(NO_SSL_TRACE) -# define NO_SSL_TRACE -# endif -# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2) -# define NO_SSL2 -# endif -# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE) -# define NO_STORE -# endif -# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST) -# define NO_UNIT_TEST -# endif -# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS) -# define NO_WEAK_SSL_CIPHERS -# endif -#endif - -/* crypto/opensslconf.h.in */ - -/* Generate 80386 code? */ -#undef I386_ONLY - -#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ -#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) -#define ENGINESDIR "/usr/local/ssl/lib/engines" -#define OPENSSLDIR "/usr/local/ssl" -#endif -#endif - -#undef OPENSSL_UNISTD -#define OPENSSL_UNISTD - -#undef OPENSSL_EXPORT_VAR_AS_FUNCTION - -#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) -#define IDEA_INT unsigned int -#endif - -#if defined(HEADER_MD2_H) && !defined(MD2_INT) -#define MD2_INT unsigned int -#endif - -#if defined(HEADER_RC2_H) && !defined(RC2_INT) -/* I need to put in a mod for the alpha - eay */ -#define RC2_INT unsigned int -#endif - -#if defined(HEADER_RC4_H) -#if !defined(RC4_INT) -/* using int types make the structure larger but make the code faster - * on most boxes I have tested - up to %20 faster. */ -/* - * I don't know what does "most" mean, but declaring "int" is a must on: - * - Intel P6 because partial register stalls are very expensive; - * - elder Alpha because it lacks byte load/store instructions; - */ -#define RC4_INT unsigned int -#endif -#if !defined(RC4_CHUNK) -/* - * This enables code handling data aligned at natural CPU word - * boundary. See crypto/rc4/rc4_enc.c for further details. - */ -#define RC4_CHUNK unsigned long -#endif -#endif - -#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) -/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a - * %20 speed up (longs are 8 bytes, int's are 4). */ -#ifndef DES_LONG -#define DES_LONG unsigned int -#endif -#endif - -#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) -#define CONFIG_HEADER_BN_H -#undef BN_LLONG - -/* Should we define BN_DIV2W here? */ - -/* Only one for the following should be defined */ -#define SIXTY_FOUR_BIT_LONG -#undef SIXTY_FOUR_BIT -#undef THIRTY_TWO_BIT -#endif - -#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) -#define CONFIG_HEADER_RC4_LOCL_H -/* if this is defined data[i] is used instead of *data, this is a %20 - * speedup on x86 */ -#undef RC4_INDEX -#endif - -#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) -#define CONFIG_HEADER_BF_LOCL_H -#undef BF_PTR -#endif /* HEADER_BF_LOCL_H */ - -#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) -#define CONFIG_HEADER_DES_LOCL_H -#ifndef DES_DEFAULT_OPTIONS -/* the following is tweaked from a config script, that is why it is a - * protected undef/define */ -#ifndef DES_PTR -#undef DES_PTR -#endif - -/* This helps C compiler generate the correct code for multiple functional - * units. It reduces register dependancies at the expense of 2 more - * registers */ -#ifndef DES_RISC1 -#undef DES_RISC1 -#endif - -#ifndef DES_RISC2 -#undef DES_RISC2 -#endif - -#if defined(DES_RISC1) && defined(DES_RISC2) -#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! -#endif - -/* Unroll the inner loop, this sometimes helps, sometimes hinders. - * Very mucy CPU dependant */ -#ifndef DES_UNROLL -#define DES_UNROLL -#endif - -/* These default values were supplied by - * Peter Gutman - * They are only used if nothing else has been defined */ -#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) -/* Special defines which change the way the code is built depending on the - CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find - even newer MIPS CPU's, but at the moment one size fits all for - optimization options. Older Sparc's work better with only UNROLL, but - there's no way to tell at compile time what it is you're running on */ - -#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ -# define DES_PTR -# define DES_RISC1 -# define DES_UNROLL -#elif defined( __ultrix ) /* Older MIPS */ -# define DES_PTR -# define DES_RISC2 -# define DES_UNROLL -#elif defined( __osf1__ ) /* Alpha */ -# define DES_PTR -# define DES_RISC2 -#elif defined ( _AIX ) /* RS6000 */ - /* Unknown */ -#elif defined( __hpux ) /* HP-PA */ - /* Unknown */ -#elif defined( __aux ) /* 68K */ - /* Unknown */ -#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ -# define DES_UNROLL -#elif defined( __sgi ) /* Newer MIPS */ -# define DES_PTR -# define DES_RISC2 -# define DES_UNROLL -#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ -# define DES_PTR -# define DES_RISC1 -# define DES_UNROLL -#endif /* Systems-specific speed defines */ -#endif - -#endif /* DES_DEFAULT_OPTIONS */ -#endif /* HEADER_DES_LOCL_H */ -#ifdef __cplusplus -} -#endif diff --git a/Sources/COpenSSL/opensslv.h b/Sources/COpenSSL/opensslv.h deleted file mode 100644 index 73d22b39..00000000 --- a/Sources/COpenSSL/opensslv.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef HEADER_OPENSSLV_H -# define HEADER_OPENSSLV_H - -#ifdef __cplusplus -extern "C" { -#endif - -/*- - * Numeric release version identifier: - * MNNFFPPS: major minor fix patch status - * The status nibble has one of the values 0 for development, 1 to e for betas - * 1 to 14, and f for release. The patch level is exactly that. - * For example: - * 0.9.3-dev 0x00903000 - * 0.9.3-beta1 0x00903001 - * 0.9.3-beta2-dev 0x00903002 - * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) - * 0.9.3 0x0090300f - * 0.9.3a 0x0090301f - * 0.9.4 0x0090400f - * 1.2.3z 0x102031af - * - * For continuity reasons (because 0.9.5 is already out, and is coded - * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level - * part is slightly different, by setting the highest bit. This means - * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start - * with 0x0090600S... - * - * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) - * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for - * major minor fix final patch/beta) - */ -# define OPENSSL_VERSION_NUMBER 0x1000211fL -# ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2q-fips 20 Nov 2018" -# else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2q 20 Nov 2018" -# endif -# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT - -/*- - * The macros below are to be used for shared library (.so, .dll, ...) - * versioning. That kind of versioning works a bit differently between - * operating systems. The most usual scheme is to set a major and a minor - * number, and have the runtime loader check that the major number is equal - * to what it was at application link time, while the minor number has to - * be greater or equal to what it was at application link time. With this - * scheme, the version number is usually part of the file name, like this: - * - * libcrypto.so.0.9 - * - * Some unixen also make a softlink with the major verson number only: - * - * libcrypto.so.0 - * - * On Tru64 and IRIX 6.x it works a little bit differently. There, the - * shared library version is stored in the file, and is actually a series - * of versions, separated by colons. The rightmost version present in the - * library when linking an application is stored in the application to be - * matched at run time. When the application is run, a check is done to - * see if the library version stored in the application matches any of the - * versions in the version string of the library itself. - * This version string can be constructed in any way, depending on what - * kind of matching is desired. However, to implement the same scheme as - * the one used in the other unixen, all compatible versions, from lowest - * to highest, should be part of the string. Consecutive builds would - * give the following versions strings: - * - * 3.0 - * 3.0:3.1 - * 3.0:3.1:3.2 - * 4.0 - * 4.0:4.1 - * - * Notice how version 4 is completely incompatible with version, and - * therefore give the breach you can see. - * - * There may be other schemes as well that I haven't yet discovered. - * - * So, here's the way it works here: first of all, the library version - * number doesn't need at all to match the overall OpenSSL version. - * However, it's nice and more understandable if it actually does. - * The current library version is stored in the macro SHLIB_VERSION_NUMBER, - * which is just a piece of text in the format "M.m.e" (Major, minor, edit). - * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways, - * we need to keep a history of version numbers, which is done in the - * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and - * should only keep the versions that are binary compatible with the current. - */ -# define SHLIB_VERSION_HISTORY "" -# define SHLIB_VERSION_NUMBER "1.0.0" - - -#ifdef __cplusplus -} -#endif -#endif /* HEADER_OPENSSLV_H */ diff --git a/Sources/COpenSSL/ossl_typ.h b/Sources/COpenSSL/ossl_typ.h deleted file mode 100644 index d5aa651c..00000000 --- a/Sources/COpenSSL/ossl_typ.h +++ /dev/null @@ -1,213 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_OPENSSL_TYPES_H -# define HEADER_OPENSSL_TYPES_H - -#ifdef __cplusplus -extern "C" { -#endif - -# include "e_os2.h" - -# ifdef NO_ASN1_TYPEDEFS -# define ASN1_INTEGER ASN1_STRING -# define ASN1_ENUMERATED ASN1_STRING -# define ASN1_BIT_STRING ASN1_STRING -# define ASN1_OCTET_STRING ASN1_STRING -# define ASN1_PRINTABLESTRING ASN1_STRING -# define ASN1_T61STRING ASN1_STRING -# define ASN1_IA5STRING ASN1_STRING -# define ASN1_UTCTIME ASN1_STRING -# define ASN1_GENERALIZEDTIME ASN1_STRING -# define ASN1_TIME ASN1_STRING -# define ASN1_GENERALSTRING ASN1_STRING -# define ASN1_UNIVERSALSTRING ASN1_STRING -# define ASN1_BMPSTRING ASN1_STRING -# define ASN1_VISIBLESTRING ASN1_STRING -# define ASN1_UTF8STRING ASN1_STRING -# define ASN1_BOOLEAN int -# define ASN1_NULL int -# else -typedef struct asn1_string_st ASN1_INTEGER; -typedef struct asn1_string_st ASN1_ENUMERATED; -typedef struct asn1_string_st ASN1_BIT_STRING; -typedef struct asn1_string_st ASN1_OCTET_STRING; -typedef struct asn1_string_st ASN1_PRINTABLESTRING; -typedef struct asn1_string_st ASN1_T61STRING; -typedef struct asn1_string_st ASN1_IA5STRING; -typedef struct asn1_string_st ASN1_GENERALSTRING; -typedef struct asn1_string_st ASN1_UNIVERSALSTRING; -typedef struct asn1_string_st ASN1_BMPSTRING; -typedef struct asn1_string_st ASN1_UTCTIME; -typedef struct asn1_string_st ASN1_TIME; -typedef struct asn1_string_st ASN1_GENERALIZEDTIME; -typedef struct asn1_string_st ASN1_VISIBLESTRING; -typedef struct asn1_string_st ASN1_UTF8STRING; -typedef struct asn1_string_st ASN1_STRING; -typedef int ASN1_BOOLEAN; -typedef int ASN1_NULL; -# endif - -typedef struct asn1_object_st ASN1_OBJECT; - -typedef struct ASN1_ITEM_st ASN1_ITEM; -typedef struct asn1_pctx_st ASN1_PCTX; - -# ifdef OPENSSL_SYS_WIN32 -# undef X509_NAME -# undef X509_EXTENSIONS -# undef X509_CERT_PAIR -# undef PKCS7_ISSUER_AND_SERIAL -# undef OCSP_REQUEST -# undef OCSP_RESPONSE -# endif - -# ifdef BIGNUM -# undef BIGNUM -# endif -typedef struct bignum_st BIGNUM; -typedef struct bignum_ctx BN_CTX; -typedef struct bn_blinding_st BN_BLINDING; -typedef struct bn_mont_ctx_st BN_MONT_CTX; -typedef struct bn_recp_ctx_st BN_RECP_CTX; -typedef struct bn_gencb_st BN_GENCB; - -typedef struct buf_mem_st BUF_MEM; - -typedef struct evp_cipher_st EVP_CIPHER; -typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; -typedef struct env_md_st EVP_MD; -typedef struct env_md_ctx_st EVP_MD_CTX; -typedef struct evp_pkey_st EVP_PKEY; - -typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; - -typedef struct evp_pkey_method_st EVP_PKEY_METHOD; -typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; - -typedef struct dh_st DH; -typedef struct dh_method DH_METHOD; - -typedef struct dsa_st DSA; -typedef struct dsa_method DSA_METHOD; - -typedef struct rsa_st RSA; -typedef struct rsa_meth_st RSA_METHOD; - -typedef struct rand_meth_st RAND_METHOD; - -typedef struct ecdh_method ECDH_METHOD; -typedef struct ecdsa_method ECDSA_METHOD; - -typedef struct x509_st X509; -typedef struct X509_algor_st X509_ALGOR; -typedef struct X509_crl_st X509_CRL; -typedef struct x509_crl_method_st X509_CRL_METHOD; -typedef struct x509_revoked_st X509_REVOKED; -typedef struct X509_name_st X509_NAME; -typedef struct X509_pubkey_st X509_PUBKEY; -typedef struct x509_store_st X509_STORE; -typedef struct x509_store_ctx_st X509_STORE_CTX; - -typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; - -typedef struct v3_ext_ctx X509V3_CTX; -typedef struct conf_st CONF; - -typedef struct store_st STORE; -typedef struct store_method_st STORE_METHOD; - -typedef struct ui_st UI; -typedef struct ui_method_st UI_METHOD; - -typedef struct st_ERR_FNS ERR_FNS; - -typedef struct engine_st ENGINE; -typedef struct ssl_st SSL; -typedef struct ssl_ctx_st SSL_CTX; - -typedef struct comp_method_st COMP_METHOD; - -typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; -typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; -typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; -typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; - -typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; -typedef struct DIST_POINT_st DIST_POINT; -typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; -typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; - - /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ -# define DECLARE_PKCS12_STACK_OF(type)/* Nothing */ -# define IMPLEMENT_PKCS12_STACK_OF(type)/* Nothing */ - -typedef struct crypto_ex_data_st CRYPTO_EX_DATA; -/* Callback types for crypto.h */ -typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp); -typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, - int idx, long argl, void *argp); -typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, - void *from_d, int idx, long argl, void *argp); - -typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; -typedef struct ocsp_response_st OCSP_RESPONSE; -typedef struct ocsp_responder_id_st OCSP_RESPID; - -#ifdef __cplusplus -} -#endif -#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/Sources/COpenSSL/p12_.c b/Sources/COpenSSL/p12_.c deleted file mode 100644 index 6dd30de6..00000000 --- a/Sources/COpenSSL/p12_.c +++ /dev/null @@ -1,2613 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* p12_add.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "pkcs12.h" - -/* Pack an object into an OCTET STRING and turn into a safebag */ - -PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, - int nid1, int nid2) -{ - PKCS12_BAGS *bag; - PKCS12_SAFEBAG *safebag; - if (!(bag = PKCS12_BAGS_new())) { - PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); - return NULL; - } - bag->type = OBJ_nid2obj(nid1); - if (!ASN1_item_pack(obj, it, &bag->value.octet)) { - PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!(safebag = PKCS12_SAFEBAG_new())) { - PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); - goto err; - } - safebag->value.bag = bag; - safebag->type = OBJ_nid2obj(nid2); - return safebag; - - err: - PKCS12_BAGS_free(bag); - return NULL; -} - -/* Turn PKCS8 object into a keybag */ - -PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8) -{ - PKCS12_SAFEBAG *bag; - if (!(bag = PKCS12_SAFEBAG_new())) { - PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE); - return NULL; - } - bag->type = OBJ_nid2obj(NID_keyBag); - bag->value.keybag = p8; - return bag; -} - -/* Turn PKCS8 object into a shrouded keybag */ - -PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, - int passlen, unsigned char *salt, - int saltlen, int iter, - PKCS8_PRIV_KEY_INFO *p8) -{ - PKCS12_SAFEBAG *bag; - const EVP_CIPHER *pbe_ciph; - - /* Set up the safe bag */ - if (!(bag = PKCS12_SAFEBAG_new())) { - PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); - return NULL; - } - - bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); - - pbe_ciph = EVP_get_cipherbynid(pbe_nid); - - if (pbe_ciph) - pbe_nid = -1; - - if (!(bag->value.shkeybag = - PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter, - p8))) { - PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); - PKCS12_SAFEBAG_free(bag); - return NULL; - } - - return bag; -} - -/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */ -PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) -{ - PKCS7 *p7; - if (!(p7 = PKCS7_new())) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); - return NULL; - } - p7->type = OBJ_nid2obj(NID_pkcs7_data); - if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); - goto err; - } - return p7; - - err: - PKCS7_free(p7); - return NULL; -} - -/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */ -STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) -{ - if (!PKCS7_type_is_data(p7)) { - PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, - PKCS12_R_CONTENT_TYPE_NOT_DATA); - return NULL; - } - return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); -} - -/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ - -PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, - unsigned char *salt, int saltlen, int iter, - STACK_OF(PKCS12_SAFEBAG) *bags) -{ - PKCS7 *p7; - X509_ALGOR *pbe; - const EVP_CIPHER *pbe_ciph; - if (!(p7 = PKCS7_new())) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, - PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); - goto err; - } - - pbe_ciph = EVP_get_cipherbynid(pbe_nid); - - if (pbe_ciph) - pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen); - else - pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); - - if (!pbe) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); - goto err; - } - X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); - p7->d.encrypted->enc_data->algorithm = pbe; - M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); - if (!(p7->d.encrypted->enc_data->enc_data = - PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, - passlen, bags, 1))) { - PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); - goto err; - } - - return p7; - - err: - PKCS7_free(p7); - return NULL; -} - -STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, - int passlen) -{ - if (!PKCS7_type_is_encrypted(p7)) - return NULL; - return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, - ASN1_ITEM_rptr(PKCS12_SAFEBAGS), - pass, passlen, - p7->d.encrypted->enc_data->enc_data, 1); -} - -PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, - const char *pass, int passlen) -{ - return PKCS8_decrypt(bag->value.shkeybag, pass, passlen); -} - -int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) -{ - if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES), - &p12->authsafes->d.data)) - return 1; - return 0; -} - -STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12) -{ - if (!PKCS7_type_is_data(p12->authsafes)) { - PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, - PKCS12_R_CONTENT_TYPE_NOT_DATA); - return NULL; - } - return ASN1_item_unpack(p12->authsafes->d.data, - ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); -} -/* p12_asn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -#include "asn1t.h" -// #include "pkcs12.h" - -/* PKCS#12 ASN1 module */ - -ASN1_SEQUENCE(PKCS12) = { - ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER), - ASN1_SIMPLE(PKCS12, authsafes, PKCS7), - ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA) -} ASN1_SEQUENCE_END(PKCS12) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS12) - -ASN1_SEQUENCE(PKCS12_MAC_DATA) = { - ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG), - ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING), - ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER) -} ASN1_SEQUENCE_END(PKCS12_MAC_DATA) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA) - -ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0); - -ASN1_ADB(PKCS12_BAGS) = { - ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)), - ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)), - ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)), -} ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL); - -ASN1_SEQUENCE(PKCS12_BAGS) = { - ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT), - ASN1_ADB_OBJECT(PKCS12_BAGS), -} ASN1_SEQUENCE_END(PKCS12_BAGS) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS) - -ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0); - -ASN1_ADB(PKCS12_SAFEBAG) = { - ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)), - ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)), - ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SEQUENCE_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)), - ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), - ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), - ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)) -} ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL); - -ASN1_SEQUENCE(PKCS12_SAFEBAG) = { - ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT), - ASN1_ADB_OBJECT(PKCS12_SAFEBAG), - ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE) -} ASN1_SEQUENCE_END(PKCS12_SAFEBAG) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG) - -/* SEQUENCE OF SafeBag */ -ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG) -ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS) - -/* Authsafes: SEQUENCE OF PKCS7 */ -ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7) -ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES) -/* p12_attr.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -/* Add a local keyid to a safebag */ - -int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, - int namelen) -{ - if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID, - V_ASN1_OCTET_STRING, name, namelen)) - return 1; - else - return 0; -} - -/* Add key usage to PKCS#8 structure */ - -int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage) -{ - unsigned char us_val; - us_val = (unsigned char)usage; - if (X509at_add1_attr_by_NID(&p8->attributes, NID_key_usage, - V_ASN1_BIT_STRING, &us_val, 1)) - return 1; - else - return 0; -} - -/* Add a friendlyname to a safebag */ - -int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, - int namelen) -{ - if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, - MBSTRING_ASC, (unsigned char *)name, namelen)) - return 1; - else - return 0; -} - -int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, - const unsigned char *name, int namelen) -{ - if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, - MBSTRING_BMP, name, namelen)) - return 1; - else - return 0; -} - -int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) -{ - if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name, - MBSTRING_ASC, (unsigned char *)name, namelen)) - return 1; - else - return 0; -} - -ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid) -{ - X509_ATTRIBUTE *attrib; - int i; - if (!attrs) - return NULL; - for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { - attrib = sk_X509_ATTRIBUTE_value(attrs, i); - if (OBJ_obj2nid(attrib->object) == attr_nid) { - if (sk_ASN1_TYPE_num(attrib->value.set)) - return sk_ASN1_TYPE_value(attrib->value.set, 0); - else - return NULL; - } - } - return NULL; -} - -char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag) -{ - ASN1_TYPE *atype; - if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) - return NULL; - if (atype->type != V_ASN1_BMPSTRING) - return NULL; - return OPENSSL_uni2asc(atype->value.bmpstring->data, - atype->value.bmpstring->length); -} -/* p12_crpt.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -/* PKCS#12 PBE algorithms now in static table */ - -void PKCS12_PBE_add(void) -{ -} - -int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *cipher, - const EVP_MD *md, int en_de) -{ - PBEPARAM *pbe; - int saltlen, iter, ret; - unsigned char *salt; - const unsigned char *pbuf; - unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; - - if (cipher == NULL) - return 0; - - /* Extract useful info from parameter */ - if (param == NULL || param->type != V_ASN1_SEQUENCE || - param->value.sequence == NULL) { - PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); - return 0; - } - - pbuf = param->value.sequence->data; - if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { - PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); - return 0; - } - - if (!pbe->iter) - iter = 1; - else - iter = ASN1_INTEGER_get(pbe->iter); - salt = pbe->salt->data; - saltlen = pbe->salt->length; - if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_KEY_ID, - iter, EVP_CIPHER_key_length(cipher), key, md)) { - PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR); - PBEPARAM_free(pbe); - return 0; - } - if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_IV_ID, - iter, EVP_CIPHER_iv_length(cipher), iv, md)) { - PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR); - PBEPARAM_free(pbe); - return 0; - } - PBEPARAM_free(pbe); - ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de); - OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); - OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); - return ret; -} -/* p12_crt.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, - PKCS12_SAFEBAG *bag); - -static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) -{ - int idx; - X509_ATTRIBUTE *attr; - idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1); - if (idx < 0) - return 1; - attr = EVP_PKEY_get_attr(pkey, idx); - if (!X509at_add1_attr(&bag->attrib, attr)) - return 0; - return 1; -} - -PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, - STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, - int mac_iter, int keytype) -{ - PKCS12 *p12 = NULL; - STACK_OF(PKCS7) *safes = NULL; - STACK_OF(PKCS12_SAFEBAG) *bags = NULL; - PKCS12_SAFEBAG *bag = NULL; - int i; - unsigned char keyid[EVP_MAX_MD_SIZE]; - unsigned int keyidlen = 0; - - /* Set defaults */ - if (!nid_cert) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; - else -#endif -#ifdef OPENSSL_NO_RC2 - nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -#else - nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; -#endif - } - if (!nid_key) - nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; - if (!iter) - iter = PKCS12_DEFAULT_ITER; - if (!mac_iter) - mac_iter = 1; - - if (!pkey && !cert && !ca) { - PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT); - return NULL; - } - - if (pkey && cert) { - if (!X509_check_private_key(cert, pkey)) - return NULL; - X509_digest(cert, EVP_sha1(), keyid, &keyidlen); - } - - if (cert) { - bag = PKCS12_add_cert(&bags, cert); - if (name && !PKCS12_add_friendlyname(bag, name, -1)) - goto err; - if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) - goto err; - } - - /* Add all other certificates */ - for (i = 0; i < sk_X509_num(ca); i++) { - if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i))) - goto err; - } - - if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass)) - goto err; - - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - bags = NULL; - - if (pkey) { - bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass); - - if (!bag) - goto err; - - if (!copy_bag_attr(bag, pkey, NID_ms_csp_name)) - goto err; - if (!copy_bag_attr(bag, pkey, NID_LocalKeySet)) - goto err; - - if (name && !PKCS12_add_friendlyname(bag, name, -1)) - goto err; - if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) - goto err; - } - - if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL)) - goto err; - - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - bags = NULL; - - p12 = PKCS12_add_safes(safes, 0); - - if (!p12) - goto err; - - sk_PKCS7_pop_free(safes, PKCS7_free); - - safes = NULL; - - if ((mac_iter != -1) && - !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL)) - goto err; - - return p12; - - err: - - if (p12) - PKCS12_free(p12); - if (safes) - sk_PKCS7_pop_free(safes, PKCS7_free); - if (bags) - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - return NULL; - -} - -PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) -{ - PKCS12_SAFEBAG *bag = NULL; - char *name; - int namelen = -1; - unsigned char *keyid; - int keyidlen = -1; - - /* Add user certificate */ - if (!(bag = PKCS12_x5092certbag(cert))) - goto err; - - /* - * Use friendlyName and localKeyID in certificate. (if present) - */ - - name = (char *)X509_alias_get0(cert, &namelen); - - if (name && !PKCS12_add_friendlyname(bag, name, namelen)) - goto err; - - keyid = X509_keyid_get0(cert, &keyidlen); - - if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) - goto err; - - if (!pkcs12_add_bag(pbags, bag)) - goto err; - - return bag; - - err: - - if (bag) - PKCS12_SAFEBAG_free(bag); - - return NULL; - -} - -PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, - EVP_PKEY *key, int key_usage, int iter, - int nid_key, char *pass) -{ - - PKCS12_SAFEBAG *bag = NULL; - PKCS8_PRIV_KEY_INFO *p8 = NULL; - - /* Make a PKCS#8 structure */ - if (!(p8 = EVP_PKEY2PKCS8(key))) - goto err; - if (key_usage && !PKCS8_add_keyusage(p8, key_usage)) - goto err; - if (nid_key != -1) { - bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8); - PKCS8_PRIV_KEY_INFO_free(p8); - } else - bag = PKCS12_MAKE_KEYBAG(p8); - - if (!bag) - goto err; - - if (!pkcs12_add_bag(pbags, bag)) - goto err; - - return bag; - - err: - - if (bag) - PKCS12_SAFEBAG_free(bag); - - return NULL; - -} - -int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, - int nid_safe, int iter, char *pass) -{ - PKCS7 *p7 = NULL; - int free_safes = 0; - - if (!*psafes) { - *psafes = sk_PKCS7_new_null(); - if (!*psafes) - return 0; - free_safes = 1; - } else - free_safes = 0; - - if (nid_safe == 0) -#ifdef OPENSSL_NO_RC2 - nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; -#else - nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC; -#endif - - if (nid_safe == -1) - p7 = PKCS12_pack_p7data(bags); - else - p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags); - if (!p7) - goto err; - - if (!sk_PKCS7_push(*psafes, p7)) - goto err; - - return 1; - - err: - if (free_safes) { - sk_PKCS7_free(*psafes); - *psafes = NULL; - } - - if (p7) - PKCS7_free(p7); - - return 0; - -} - -static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, - PKCS12_SAFEBAG *bag) -{ - int free_bags; - if (!pbags) - return 1; - if (!*pbags) { - *pbags = sk_PKCS12_SAFEBAG_new_null(); - if (!*pbags) - return 0; - free_bags = 1; - } else - free_bags = 0; - - if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) { - if (free_bags) { - sk_PKCS12_SAFEBAG_free(*pbags); - *pbags = NULL; - } - return 0; - } - - return 1; - -} - -PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7) -{ - PKCS12 *p12; - if (nid_p7 <= 0) - nid_p7 = NID_pkcs7_data; - p12 = PKCS12_init(nid_p7); - - if (!p12) - return NULL; - - if (!PKCS12_pack_authsafes(p12, safes)) { - PKCS12_free(p12); - return NULL; - } - - return p12; - -} -/* p12_decr.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -/* Define this to dump decrypted output to files called DERnnn */ -/* - * #define DEBUG_DECRYPT - */ - -/* - * Encrypt/Decrypt a buffer based on password and algor, result in a - * OPENSSL_malloc'ed buffer - */ - -unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, - int passlen, unsigned char *in, int inlen, - unsigned char **data, int *datalen, int en_de) -{ - unsigned char *out; - int outlen, i; - EVP_CIPHER_CTX ctx; - - EVP_CIPHER_CTX_init(&ctx); - /* Decrypt data */ - if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen, - algor->parameter, &ctx, en_de)) { - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, - PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); - return NULL; - } - - if (!(out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) { - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen)) { - OPENSSL_free(out); - out = NULL; - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB); - goto err; - } - - outlen = i; - if (!EVP_CipherFinal_ex(&ctx, out + i, &i)) { - OPENSSL_free(out); - out = NULL; - PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, - PKCS12_R_PKCS12_CIPHERFINAL_ERROR); - goto err; - } - outlen += i; - if (datalen) - *datalen = outlen; - if (data) - *data = out; - err: - EVP_CIPHER_CTX_cleanup(&ctx); - return out; - -} - -/* - * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer - * after use. - */ - -void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, - const char *pass, int passlen, - ASN1_OCTET_STRING *oct, int zbuf) -{ - unsigned char *out; - const unsigned char *p; - void *ret; - int outlen; - - if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length, - &out, &outlen, 0)) { - PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, - PKCS12_R_PKCS12_PBE_CRYPT_ERROR); - return NULL; - } - p = out; -#ifdef DEBUG_DECRYPT - { - FILE *op; - - char fname[30]; - static int fnm = 1; - sprintf(fname, "DER%d", fnm++); - op = fopen(fname, "wb"); - fwrite(p, 1, outlen, op); - fclose(op); - } -#endif - ret = ASN1_item_d2i(NULL, &p, outlen, it); - if (zbuf) - OPENSSL_cleanse(out, outlen); - if (!ret) - PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_DECODE_ERROR); - OPENSSL_free(out); - return ret; -} - -/* - * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero - * encoding. - */ - -ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, - const ASN1_ITEM *it, - const char *pass, int passlen, - void *obj, int zbuf) -{ - ASN1_OCTET_STRING *oct = NULL; - unsigned char *in = NULL; - int inlen; - if (!(oct = M_ASN1_OCTET_STRING_new())) { - PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - inlen = ASN1_item_i2d(obj, &in, it); - if (!in) { - PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR); - goto err; - } - if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data, - &oct->length, 1)) { - PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); - OPENSSL_free(in); - goto err; - } - if (zbuf) - OPENSSL_cleanse(in, inlen); - OPENSSL_free(in); - return oct; - err: - if (oct) - ASN1_OCTET_STRING_free(oct); - return NULL; -} - -IMPLEMENT_PKCS12_STACK_OF(PKCS7) -/* p12_init.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -/* Initialise a PKCS12 structure to take data */ - -PKCS12 *PKCS12_init(int mode) -{ - PKCS12 *pkcs12; - if (!(pkcs12 = PKCS12_new())) { - PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (!ASN1_INTEGER_set(pkcs12->version, 3)) - goto err; - pkcs12->authsafes->type = OBJ_nid2obj(mode); - switch (mode) { - case NID_pkcs7_data: - if (!(pkcs12->authsafes->d.data = M_ASN1_OCTET_STRING_new())) { - PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); - goto err; - } - break; - default: - PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE); - goto err; - } - - return pkcs12; - err: - if (pkcs12 != NULL) - PKCS12_free(pkcs12); - return NULL; -} -/* p12_key.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" -#include "bn.h" - -/* Uncomment out this line to get debugging info about key generation */ -/* - * #define DEBUG_KEYGEN - */ -#ifdef DEBUG_KEYGEN -# include "bio.h" -extern BIO *bio_err; -void h__dump(unsigned char *p, int len); -#endif - -/* PKCS12 compatible key/IV generation */ -#ifndef min -# define min(a,b) ((a) < (b) ? (a) : (b)) -#endif - -int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, - int saltlen, int id, int iter, int n, - unsigned char *out, const EVP_MD *md_type) -{ - int ret; - unsigned char *unipass; - int uniplen; - - if (!pass) { - unipass = NULL; - uniplen = 0; - } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { - PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE); - return 0; - } - ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, - id, iter, n, out, md_type); - if (ret <= 0) - return 0; - if (unipass) { - OPENSSL_cleanse(unipass, uniplen); /* Clear password from memory */ - OPENSSL_free(unipass); - } - return ret; -} - -int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, - int saltlen, int id, int iter, int n, - unsigned char *out, const EVP_MD *md_type) -{ - unsigned char *B, *D, *I, *p, *Ai; - int Slen, Plen, Ilen, Ijlen; - int i, j, u, v; - int ret = 0; - BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */ - EVP_MD_CTX ctx; -#ifdef DEBUG_KEYGEN - unsigned char *tmpout = out; - int tmpn = n; -#endif - -#if 0 - if (!pass) { - PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } -#endif - - EVP_MD_CTX_init(&ctx); -#ifdef DEBUG_KEYGEN - fprintf(stderr, "KEYGEN DEBUG\n"); - fprintf(stderr, "ID %d, ITER %d\n", id, iter); - fprintf(stderr, "Password (length %d):\n", passlen); - h__dump(pass, passlen); - fprintf(stderr, "Salt (length %d):\n", saltlen); - h__dump(salt, saltlen); -#endif - v = EVP_MD_block_size(md_type); - u = EVP_MD_size(md_type); - if (u < 0) - return 0; - D = OPENSSL_malloc(v); - Ai = OPENSSL_malloc(u); - B = OPENSSL_malloc(v + 1); - Slen = v * ((saltlen + v - 1) / v); - if (passlen) - Plen = v * ((passlen + v - 1) / v); - else - Plen = 0; - Ilen = Slen + Plen; - I = OPENSSL_malloc(Ilen); - Ij = BN_new(); - Bpl1 = BN_new(); - if (!D || !Ai || !B || !I || !Ij || !Bpl1) - goto err; - for (i = 0; i < v; i++) - D[i] = id; - p = I; - for (i = 0; i < Slen; i++) - *p++ = salt[i % saltlen]; - for (i = 0; i < Plen; i++) - *p++ = pass[i % passlen]; - for (;;) { - if (!EVP_DigestInit_ex(&ctx, md_type, NULL) - || !EVP_DigestUpdate(&ctx, D, v) - || !EVP_DigestUpdate(&ctx, I, Ilen) - || !EVP_DigestFinal_ex(&ctx, Ai, NULL)) - goto err; - for (j = 1; j < iter; j++) { - if (!EVP_DigestInit_ex(&ctx, md_type, NULL) - || !EVP_DigestUpdate(&ctx, Ai, u) - || !EVP_DigestFinal_ex(&ctx, Ai, NULL)) - goto err; - } - memcpy(out, Ai, min(n, u)); - if (u >= n) { -#ifdef DEBUG_KEYGEN - fprintf(stderr, "Output KEY (length %d)\n", tmpn); - h__dump(tmpout, tmpn); -#endif - ret = 1; - goto end; - } - n -= u; - out += u; - for (j = 0; j < v; j++) - B[j] = Ai[j % u]; - /* Work out B + 1 first then can use B as tmp space */ - if (!BN_bin2bn(B, v, Bpl1)) - goto err; - if (!BN_add_word(Bpl1, 1)) - goto err; - for (j = 0; j < Ilen; j += v) { - if (!BN_bin2bn(I + j, v, Ij)) - goto err; - if (!BN_add(Ij, Ij, Bpl1)) - goto err; - if (!BN_bn2bin(Ij, B)) - goto err; - Ijlen = BN_num_bytes(Ij); - /* If more than 2^(v*8) - 1 cut off MSB */ - if (Ijlen > v) { - if (!BN_bn2bin(Ij, B)) - goto err; - memcpy(I + j, B + 1, v); -#ifndef PKCS12_BROKEN_KEYGEN - /* If less than v bytes pad with zeroes */ - } else if (Ijlen < v) { - memset(I + j, 0, v - Ijlen); - if (!BN_bn2bin(Ij, I + j + v - Ijlen)) - goto err; -#endif - } else if (!BN_bn2bin(Ij, I + j)) - goto err; - } - } - - err: - PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE); - - end: - OPENSSL_free(Ai); - OPENSSL_free(B); - OPENSSL_free(D); - OPENSSL_free(I); - BN_free(Ij); - BN_free(Bpl1); - EVP_MD_CTX_cleanup(&ctx); - return ret; -} - -#ifdef DEBUG_KEYGEN -void h__dump(unsigned char *p, int len) -{ - for (; len--; p++) - fprintf(stderr, "%02X", *p); - fprintf(stderr, "\n"); -} -#endif -/* p12_kiss.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -/* Simplified PKCS#12 routines */ - -static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts); - -static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, - int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); - -static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts); - -/* - * Parse and decrypt a PKCS#12 structure returning user key, user cert and - * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it - * should point to a valid STACK structure. pkey and cert can be passed - * unitialised. - */ - -int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, - STACK_OF(X509) **ca) -{ - STACK_OF(X509) *ocerts = NULL; - X509 *x = NULL; - - if (pkey) - *pkey = NULL; - if (cert) - *cert = NULL; - - /* Check for NULL PKCS12 structure */ - - if (!p12) { - PKCS12err(PKCS12_F_PKCS12_PARSE, - PKCS12_R_INVALID_NULL_PKCS12_POINTER); - return 0; - } - - /* Check the mac */ - - /* - * If password is zero length or NULL then try verifying both cases to - * determine which password is correct. The reason for this is that under - * PKCS#12 password based encryption no password and a zero length - * password are two different things... - */ - - if (!pass || !*pass) { - if (PKCS12_verify_mac(p12, NULL, 0)) - pass = NULL; - else if (PKCS12_verify_mac(p12, "", 0)) - pass = ""; - else { - PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); - goto err; - } - } else if (!PKCS12_verify_mac(p12, pass, -1)) { - PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); - goto err; - } - - /* Allocate stack for other certificates */ - ocerts = sk_X509_new_null(); - - if (!ocerts) { - PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { - PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); - goto err; - } - - while ((x = sk_X509_pop(ocerts))) { - if (pkey && *pkey && cert && !*cert) { - ERR_set_mark(); - if (X509_check_private_key(x, *pkey)) { - *cert = x; - x = NULL; - } - ERR_pop_to_mark(); - } - - if (ca && x) { - if (!*ca) - *ca = sk_X509_new_null(); - if (!*ca) - goto err; - if (!sk_X509_push(*ca, x)) - goto err; - x = NULL; - } - if (x) - X509_free(x); - } - - if (ocerts) - sk_X509_pop_free(ocerts, X509_free); - - return 1; - - err: - - if (pkey) { - EVP_PKEY_free(*pkey); - *pkey = NULL; - } - if (cert) { - X509_free(*cert); - *cert = NULL; - } - if (x) - X509_free(x); - if (ocerts) - sk_X509_pop_free(ocerts, X509_free); - return 0; - -} - -/* Parse the outer PKCS#12 structure */ - -static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts) -{ - STACK_OF(PKCS7) *asafes; - STACK_OF(PKCS12_SAFEBAG) *bags; - int i, bagnid; - PKCS7 *p7; - - if (!(asafes = PKCS12_unpack_authsafes(p12))) - return 0; - for (i = 0; i < sk_PKCS7_num(asafes); i++) { - p7 = sk_PKCS7_value(asafes, i); - bagnid = OBJ_obj2nid(p7->type); - if (bagnid == NID_pkcs7_data) { - bags = PKCS12_unpack_p7data(p7); - } else if (bagnid == NID_pkcs7_encrypted) { - bags = PKCS12_unpack_p7encdata(p7, pass, passlen); - } else - continue; - if (!bags) { - sk_PKCS7_pop_free(asafes, PKCS7_free); - return 0; - } - if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - sk_PKCS7_pop_free(asafes, PKCS7_free); - return 0; - } - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - } - sk_PKCS7_pop_free(asafes, PKCS7_free); - return 1; -} - -static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, - int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) -{ - int i; - for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { - if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), - pass, passlen, pkey, ocerts)) - return 0; - } - return 1; -} - -static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts) -{ - PKCS8_PRIV_KEY_INFO *p8; - X509 *x509; - ASN1_TYPE *attrib; - ASN1_BMPSTRING *fname = NULL; - ASN1_OCTET_STRING *lkid = NULL; - - if ((attrib = PKCS12_get_attr(bag, NID_friendlyName))) - fname = attrib->value.bmpstring; - - if ((attrib = PKCS12_get_attr(bag, NID_localKeyID))) - lkid = attrib->value.octet_string; - - switch (M_PKCS12_bag_type(bag)) { - case NID_keyBag: - if (!pkey || *pkey) - return 1; - if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) - return 0; - break; - - case NID_pkcs8ShroudedKeyBag: - if (!pkey || *pkey) - return 1; - if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) - return 0; - *pkey = EVP_PKCS82PKEY(p8); - PKCS8_PRIV_KEY_INFO_free(p8); - if (!(*pkey)) - return 0; - break; - - case NID_certBag: - if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) - return 1; - if (!(x509 = PKCS12_certbag2x509(bag))) - return 0; - if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { - X509_free(x509); - return 0; - } - if (fname) { - int len, r; - unsigned char *data; - len = ASN1_STRING_to_UTF8(&data, fname); - if (len >= 0) { - r = X509_alias_set1(x509, data, len); - OPENSSL_free(data); - if (!r) { - X509_free(x509); - return 0; - } - } - } - - if (!sk_X509_push(ocerts, x509)) { - X509_free(x509); - return 0; - } - - break; - - case NID_safeContentsBag: - return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts); - break; - - default: - return 1; - break; - } - return 1; -} -/* p12_mutl.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef OPENSSL_NO_HMAC -# include -# include "cryptlib.h" -# include "crypto.h" -# include "hmac.h" -# include "rand.h" -# include "pkcs12.h" - -/* Generate a MAC */ -int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, - unsigned char *mac, unsigned int *maclen) -{ - const EVP_MD *md_type; - HMAC_CTX hmac; - unsigned char key[EVP_MAX_MD_SIZE], *salt; - int saltlen, iter; - int md_size; - - if (!PKCS7_type_is_data(p12->authsafes)) { - PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA); - return 0; - } - - salt = p12->mac->salt->data; - saltlen = p12->mac->salt->length; - if (!p12->mac->iter) - iter = 1; - else - iter = ASN1_INTEGER_get(p12->mac->iter); - if (!(md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm))) { - PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); - return 0; - } - md_size = EVP_MD_size(md_type); - if (md_size < 0) - return 0; - if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, - md_size, key, md_type)) { - PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); - return 0; - } - HMAC_CTX_init(&hmac); - if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) - || !HMAC_Update(&hmac, p12->authsafes->d.data->data, - p12->authsafes->d.data->length) - || !HMAC_Final(&hmac, mac, maclen)) { - HMAC_CTX_cleanup(&hmac); - return 0; - } - HMAC_CTX_cleanup(&hmac); - return 1; -} - -/* Verify the mac */ -int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) -{ - unsigned char mac[EVP_MAX_MD_SIZE]; - unsigned int maclen; - if (p12->mac == NULL) { - PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT); - return 0; - } - if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { - PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR); - return 0; - } - if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) - || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen)) - return 0; - return 1; -} - -/* Set a mac */ - -int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, - unsigned char *salt, int saltlen, int iter, - const EVP_MD *md_type) -{ - unsigned char mac[EVP_MAX_MD_SIZE]; - unsigned int maclen; - - if (!md_type) - md_type = EVP_sha1(); - if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) { - PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR); - return 0; - } - if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { - PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR); - return 0; - } - if (!(M_ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))) { - PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR); - return 0; - } - return 1; -} - -/* Set up a mac structure */ -int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, - const EVP_MD *md_type) -{ - PKCS12_MAC_DATA_free(p12->mac); - p12->mac = NULL; - - if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL) - return PKCS12_ERROR; - if (iter > 1) { - if (!(p12->mac->iter = M_ASN1_INTEGER_new())) { - PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { - PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); - return 0; - } - } - if (!saltlen) - saltlen = PKCS12_SALT_LEN; - if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) { - PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); - return 0; - } - p12->mac->salt->length = saltlen; - if (!salt) { - if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0) - return 0; - } else - memcpy(p12->mac->salt->data, salt, saltlen); - p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type)); - if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { - PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); - return 0; - } - p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; - - return 1; -} -#endif -/* p12_npas.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include "pem.h" -#include "err.h" -// #include "pkcs12.h" - -/* PKCS#12 password change routine */ - -static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass); -static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, - const char *newpass); -static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, - const char *newpass); -static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen); - -/* - * Change the password on a PKCS#12 structure. - */ - -int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass) -{ - /* Check for NULL PKCS12 structure */ - - if (!p12) { - PKCS12err(PKCS12_F_PKCS12_NEWPASS, - PKCS12_R_INVALID_NULL_PKCS12_POINTER); - return 0; - } - - /* Check the mac */ - - if (!PKCS12_verify_mac(p12, oldpass, -1)) { - PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE); - return 0; - } - - if (!newpass_p12(p12, oldpass, newpass)) { - PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR); - return 0; - } - - return 1; -} - -/* Parse the outer PKCS#12 structure */ - -static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) -{ - STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL; - STACK_OF(PKCS12_SAFEBAG) *bags = NULL; - int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; - PKCS7 *p7, *p7new; - ASN1_OCTET_STRING *p12_data_tmp = NULL; - unsigned char mac[EVP_MAX_MD_SIZE]; - unsigned int maclen; - int rv = 0; - - if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) - goto err; - if ((newsafes = sk_PKCS7_new_null()) == NULL) - goto err; - for (i = 0; i < sk_PKCS7_num(asafes); i++) { - p7 = sk_PKCS7_value(asafes, i); - bagnid = OBJ_obj2nid(p7->type); - if (bagnid == NID_pkcs7_data) { - bags = PKCS12_unpack_p7data(p7); - } else if (bagnid == NID_pkcs7_encrypted) { - bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); - if (!alg_get(p7->d.encrypted->enc_data->algorithm, - &pbe_nid, &pbe_iter, &pbe_saltlen)) - goto err; - } else { - continue; - } - if (bags == NULL) - goto err; - if (!newpass_bags(bags, oldpass, newpass)) - goto err; - /* Repack bag in same form with new password */ - if (bagnid == NID_pkcs7_data) - p7new = PKCS12_pack_p7data(bags); - else - p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, - pbe_saltlen, pbe_iter, bags); - if (!p7new || !sk_PKCS7_push(newsafes, p7new)) - goto err; - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - bags = NULL; - } - - /* Repack safe: save old safe in case of error */ - - p12_data_tmp = p12->authsafes->d.data; - if ((p12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL) - goto err; - if (!PKCS12_pack_authsafes(p12, newsafes)) - goto err; - if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) - goto err; - if (!ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen)) - goto err; - - rv = 1; - -err: - /* Restore old safe if necessary */ - if (rv == 1) { - ASN1_OCTET_STRING_free(p12_data_tmp); - } else if (p12_data_tmp != NULL) { - ASN1_OCTET_STRING_free(p12->authsafes->d.data); - p12->authsafes->d.data = p12_data_tmp; - } - sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); - sk_PKCS7_pop_free(asafes, PKCS7_free); - sk_PKCS7_pop_free(newsafes, PKCS7_free); - return rv; -} - -static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass, - const char *newpass) -{ - int i; - for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { - if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass)) - return 0; - } - return 1; -} - -/* Change password of safebag: only needs handle shrouded keybags */ - -static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass, - const char *newpass) -{ - PKCS8_PRIV_KEY_INFO *p8; - X509_SIG *p8new; - int p8_nid, p8_saltlen, p8_iter; - - if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) - return 1; - - if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) - return 0; - if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen)) - return 0; - p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, - p8_iter, p8); - PKCS8_PRIV_KEY_INFO_free(p8); - if (p8new == NULL) - return 0; - X509_SIG_free(bag->value.shkeybag); - bag->value.shkeybag = p8new; - return 1; -} - -static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) -{ - PBEPARAM *pbe; - const unsigned char *p; - - p = alg->parameter->value.sequence->data; - pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); - if (!pbe) - return 0; - *pnid = OBJ_obj2nid(alg->algorithm); - *piter = ASN1_INTEGER_get(pbe->iter); - *psaltlen = pbe->salt->length; - PBEPARAM_free(pbe); - return 1; -} -/* p12_p8d.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, - int passlen) -{ - return PKCS12_item_decrypt_d2i(p8->algor, - ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass, - passlen, p8->digest, 1); -} -/* p12_p8e.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, - const char *pass, int passlen, - unsigned char *salt, int saltlen, int iter, - PKCS8_PRIV_KEY_INFO *p8inf) -{ - X509_SIG *p8 = NULL; - X509_ALGOR *pbe; - - if (!(p8 = X509_SIG_new())) { - PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (pbe_nid == -1) - pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen); - else if (EVP_PBE_find(EVP_PBE_TYPE_PRF, pbe_nid, NULL, NULL, 0)) - pbe = PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, pbe_nid); - else { - ERR_clear_error(); - pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); - } - if (!pbe) { - PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB); - goto err; - } - X509_ALGOR_free(p8->algor); - p8->algor = pbe; - M_ASN1_OCTET_STRING_free(p8->digest); - p8->digest = - PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), - pass, passlen, p8inf, 1); - if (!p8->digest) { - PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); - goto err; - } - - return p8; - - err: - X509_SIG_free(p8); - return NULL; -} -/* p12_utl.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "pkcs12.h" - -/* Cheap and nasty Unicode stuff */ - -unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, - unsigned char **uni, int *unilen) -{ - int ulen, i; - unsigned char *unitmp; - if (asclen == -1) - asclen = strlen(asc); - ulen = asclen * 2 + 2; - if (!(unitmp = OPENSSL_malloc(ulen))) - return NULL; - for (i = 0; i < ulen - 2; i += 2) { - unitmp[i] = 0; - unitmp[i + 1] = asc[i >> 1]; - } - /* Make result double null terminated */ - unitmp[ulen - 2] = 0; - unitmp[ulen - 1] = 0; - if (unilen) - *unilen = ulen; - if (uni) - *uni = unitmp; - return unitmp; -} - -char *OPENSSL_uni2asc(unsigned char *uni, int unilen) -{ - int asclen, i; - char *asctmp; - - /* string must contain an even number of bytes */ - if (unilen & 1) - return NULL; - asclen = unilen / 2; - /* If no terminating zero allow for one */ - if (!unilen || uni[unilen - 1]) - asclen++; - uni++; - if (!(asctmp = OPENSSL_malloc(asclen))) - return NULL; - for (i = 0; i < unilen; i += 2) - asctmp[i >> 1] = uni[i]; - asctmp[asclen - 1] = 0; - return asctmp; -} - -int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12); -} - -#ifndef OPENSSL_NO_FP_API -int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12); -} -#endif - -PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12); -} - -#ifndef OPENSSL_NO_FP_API -PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12); -} -#endif - -PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509) -{ - return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509), - NID_x509Certificate, NID_certBag); -} - -PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl) -{ - return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL), - NID_x509Crl, NID_crlBag); -} - -X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag) -{ - if (M_PKCS12_bag_type(bag) != NID_certBag) - return NULL; - if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) - return NULL; - return ASN1_item_unpack(bag->value.bag->value.octet, - ASN1_ITEM_rptr(X509)); -} - -X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag) -{ - if (M_PKCS12_bag_type(bag) != NID_crlBag) - return NULL; - if (M_PKCS12_cert_bag_type(bag) != NID_x509Crl) - return NULL; - return ASN1_item_unpack(bag->value.bag->value.octet, - ASN1_ITEM_rptr(X509_CRL)); -} diff --git a/Sources/COpenSSL/p5_.c b/Sources/COpenSSL/p5_.c deleted file mode 100644 index 86692df3..00000000 --- a/Sources/COpenSSL/p5_.c +++ /dev/null @@ -1,903 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* p5_crpt.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "cryptlib.h" -#include "x509.h" -#include "evp.h" - -/* - * Doesn't do anything now: Builtin PBE algorithms in static table. - */ - -void PKCS5_PBE_add(void) -{ -} - -int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *cipher, - const EVP_MD *md, int en_de) -{ - EVP_MD_CTX ctx; - unsigned char md_tmp[EVP_MAX_MD_SIZE]; - unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; - int i; - PBEPARAM *pbe; - int saltlen, iter; - unsigned char *salt; - const unsigned char *pbuf; - int mdsize; - int rv = 0; - EVP_MD_CTX_init(&ctx); - - /* Extract useful info from parameter */ - if (param == NULL || param->type != V_ASN1_SEQUENCE || - param->value.sequence == NULL) { - EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); - return 0; - } - - pbuf = param->value.sequence->data; - if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { - EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); - return 0; - } - - if (!pbe->iter) - iter = 1; - else - iter = ASN1_INTEGER_get(pbe->iter); - salt = pbe->salt->data; - saltlen = pbe->salt->length; - - if (!pass) - passlen = 0; - else if (passlen == -1) - passlen = strlen(pass); - - if (!EVP_DigestInit_ex(&ctx, md, NULL)) - goto err; - if (!EVP_DigestUpdate(&ctx, pass, passlen)) - goto err; - if (!EVP_DigestUpdate(&ctx, salt, saltlen)) - goto err; - PBEPARAM_free(pbe); - if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) - goto err; - mdsize = EVP_MD_size(md); - if (mdsize < 0) - return 0; - for (i = 1; i < iter; i++) { - if (!EVP_DigestInit_ex(&ctx, md, NULL)) - goto err; - if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize)) - goto err; - if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) - goto err; - } - OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp)); - memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher)); - OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16); - memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), - EVP_CIPHER_iv_length(cipher)); - if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) - goto err; - OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); - OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); - OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); - rv = 1; - err: - EVP_MD_CTX_cleanup(&ctx); - return rv; -} -/* p5_crpt2.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#include -#include -// #include "cryptlib.h" -#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA) -# include "x509.h" -# include "evp.h" -# include "hmac.h" -# include "evp_locl.h" - -/* set this to print out info about the keygen algorithm */ -/* #define DEBUG_PKCS5V2 */ - -# ifdef DEBUG_PKCS5V2 -static void h__dump(const unsigned char *p, int len); -# endif - -/* - * This is an implementation of PKCS#5 v2.0 password based encryption key - * derivation function PBKDF2. SHA1 version verified against test vectors - * posted by Peter Gutmann to the PKCS-TNG - * mailing list. - */ - -int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, - const unsigned char *salt, int saltlen, int iter, - const EVP_MD *digest, int keylen, unsigned char *out) -{ - unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; - int cplen, j, k, tkeylen, mdlen; - unsigned long i = 1; - HMAC_CTX hctx_tpl, hctx; - - mdlen = EVP_MD_size(digest); - if (mdlen < 0) - return 0; - - HMAC_CTX_init(&hctx_tpl); - p = out; - tkeylen = keylen; - if (!pass) - passlen = 0; - else if (passlen == -1) - passlen = strlen(pass); - if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) { - HMAC_CTX_cleanup(&hctx_tpl); - return 0; - } - while (tkeylen) { - if (tkeylen > mdlen) - cplen = mdlen; - else - cplen = tkeylen; - /* - * We are unlikely to ever use more than 256 blocks (5120 bits!) but - * just in case... - */ - itmp[0] = (unsigned char)((i >> 24) & 0xff); - itmp[1] = (unsigned char)((i >> 16) & 0xff); - itmp[2] = (unsigned char)((i >> 8) & 0xff); - itmp[3] = (unsigned char)(i & 0xff); - if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { - HMAC_CTX_cleanup(&hctx_tpl); - return 0; - } - if (!HMAC_Update(&hctx, salt, saltlen) - || !HMAC_Update(&hctx, itmp, 4) - || !HMAC_Final(&hctx, digtmp, NULL)) { - HMAC_CTX_cleanup(&hctx_tpl); - HMAC_CTX_cleanup(&hctx); - return 0; - } - HMAC_CTX_cleanup(&hctx); - memcpy(p, digtmp, cplen); - for (j = 1; j < iter; j++) { - if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { - HMAC_CTX_cleanup(&hctx_tpl); - return 0; - } - if (!HMAC_Update(&hctx, digtmp, mdlen) - || !HMAC_Final(&hctx, digtmp, NULL)) { - HMAC_CTX_cleanup(&hctx_tpl); - HMAC_CTX_cleanup(&hctx); - return 0; - } - HMAC_CTX_cleanup(&hctx); - for (k = 0; k < cplen; k++) - p[k] ^= digtmp[k]; - } - tkeylen -= cplen; - i++; - p += cplen; - } - HMAC_CTX_cleanup(&hctx_tpl); -# ifdef DEBUG_PKCS5V2 - fprintf(stderr, "Password:\n"); - h__dump(pass, passlen); - fprintf(stderr, "Salt:\n"); - h__dump(salt, saltlen); - fprintf(stderr, "Iteration count %d\n", iter); - fprintf(stderr, "Key:\n"); - h__dump(out, keylen); -# endif - return 1; -} - -int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, - const unsigned char *salt, int saltlen, int iter, - int keylen, unsigned char *out) -{ - return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), - keylen, out); -} - -# ifdef DO_TEST -main() -{ - unsigned char out[4]; - unsigned char salt[] = { 0x12, 0x34, 0x56, 0x78 }; - PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out); - fprintf(stderr, "Out %02X %02X %02X %02X\n", - out[0], out[1], out[2], out[3]); -} - -# endif - -/* - * Now the key derivation function itself. This is a bit evil because it has - * to check the ASN1 parameters are valid: and there are quite a few of - * them... - */ - -int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *c, - const EVP_MD *md, int en_de) -{ - const unsigned char *pbuf; - int plen; - PBE2PARAM *pbe2 = NULL; - const EVP_CIPHER *cipher; - - int rv = 0; - - if (param == NULL || param->type != V_ASN1_SEQUENCE || - param->value.sequence == NULL) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); - goto err; - } - - pbuf = param->value.sequence->data; - plen = param->value.sequence->length; - if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); - goto err; - } - - /* See if we recognise the key derivation function */ - - if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, - EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); - goto err; - } - - /* - * lets see if we recognise the encryption algorithm. - */ - - cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm); - - if (!cipher) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER); - goto err; - } - - /* Fixup cipher based on AlgorithmIdentifier */ - if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de)) - goto err; - if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { - EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR); - goto err; - } - rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen, - pbe2->keyfunc->parameter, c, md, en_de); - err: - PBE2PARAM_free(pbe2); - return rv; -} - -int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, - int passlen, ASN1_TYPE *param, - const EVP_CIPHER *c, const EVP_MD *md, int en_de) -{ - unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; - const unsigned char *pbuf; - int saltlen, iter, plen; - int rv = 0; - unsigned int keylen = 0; - int prf_nid, hmac_md_nid; - PBKDF2PARAM *kdf = NULL; - const EVP_MD *prfmd; - - if (EVP_CIPHER_CTX_cipher(ctx) == NULL) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET); - goto err; - } - keylen = EVP_CIPHER_CTX_key_length(ctx); - OPENSSL_assert(keylen <= sizeof(key)); - - /* Decode parameter */ - - if (!param || (param->type != V_ASN1_SEQUENCE)) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR); - goto err; - } - - pbuf = param->value.sequence->data; - plen = param->value.sequence->length; - - if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen))) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR); - goto err; - } - - keylen = EVP_CIPHER_CTX_key_length(ctx); - - /* Now check the parameters of the kdf */ - - if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH); - goto err; - } - - if (kdf->prf) - prf_nid = OBJ_obj2nid(kdf->prf->algorithm); - else - prf_nid = NID_hmacWithSHA1; - - if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); - goto err; - } - - prfmd = EVP_get_digestbynid(hmac_md_nid); - if (prfmd == NULL) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); - goto err; - } - - if (kdf->salt->type != V_ASN1_OCTET_STRING) { - EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE); - goto err; - } - - /* it seems that its all OK */ - salt = kdf->salt->value.octet_string->data; - saltlen = kdf->salt->value.octet_string->length; - iter = ASN1_INTEGER_get(kdf->iter); - if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, - keylen, key)) - goto err; - rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); - err: - OPENSSL_cleanse(key, keylen); - PBKDF2PARAM_free(kdf); - return rv; -} - -# ifdef DEBUG_PKCS5V2 -static void h__dump(const unsigned char *p, int len) -{ - for (; len--; p++) - fprintf(stderr, "%02X ", *p); - fprintf(stderr, "\n"); -} -# endif -#endif -/* p5_pbe.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -#include "asn1t.h" -// #include "x509.h" -#include "rand.h" - -/* PKCS#5 password based encryption structure */ - -ASN1_SEQUENCE(PBEPARAM) = { - ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING), - ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER) -} ASN1_SEQUENCE_END(PBEPARAM) - -IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM) - -/* Set an algorithm identifier for a PKCS#5 PBE algorithm */ - -int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, - const unsigned char *salt, int saltlen) -{ - PBEPARAM *pbe = NULL; - ASN1_STRING *pbe_str = NULL; - unsigned char *sstr; - - pbe = PBEPARAM_new(); - if (!pbe) { - ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); - goto err; - } - if (iter <= 0) - iter = PKCS5_DEFAULT_ITER; - if (!ASN1_INTEGER_set(pbe->iter, iter)) { - ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!saltlen) - saltlen = PKCS5_SALT_LEN; - if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) { - ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); - goto err; - } - sstr = ASN1_STRING_data(pbe->salt); - if (salt) - memcpy(sstr, salt, saltlen); - else if (RAND_bytes(sstr, saltlen) <= 0) - goto err; - - if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { - ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); - goto err; - } - - PBEPARAM_free(pbe); - pbe = NULL; - - if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) - return 1; - - err: - if (pbe != NULL) - PBEPARAM_free(pbe); - if (pbe_str != NULL) - ASN1_STRING_free(pbe_str); - return 0; -} - -/* Return an algorithm identifier for a PKCS#5 PBE algorithm */ - -X509_ALGOR *PKCS5_pbe_set(int alg, int iter, - const unsigned char *salt, int saltlen) -{ - X509_ALGOR *ret; - ret = X509_ALGOR_new(); - if (!ret) { - ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen)) - return ret; - - X509_ALGOR_free(ret); - return NULL; -} -/* p5_pbev2.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999-2004. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" -// #include "rand.h" - -/* PKCS#5 v2.0 password based encryption structures */ - -ASN1_SEQUENCE(PBE2PARAM) = { - ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR), - ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR) -} ASN1_SEQUENCE_END(PBE2PARAM) - -IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM) - -ASN1_SEQUENCE(PBKDF2PARAM) = { - ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY), - ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER), - ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER), - ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR) -} ASN1_SEQUENCE_END(PBKDF2PARAM) - -IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM) - -/* - * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know - * this is horrible! Extended version to allow application supplied PRF NID - * and IV. - */ - -X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, - unsigned char *salt, int saltlen, - unsigned char *aiv, int prf_nid) -{ - X509_ALGOR *scheme = NULL, *ret = NULL; - int alg_nid, keylen; - EVP_CIPHER_CTX ctx; - unsigned char iv[EVP_MAX_IV_LENGTH]; - PBE2PARAM *pbe2 = NULL; - - alg_nid = EVP_CIPHER_type(cipher); - if (alg_nid == NID_undef) { - ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, - ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); - goto err; - } - - if (!(pbe2 = PBE2PARAM_new())) - goto merr; - - /* Setup the AlgorithmIdentifier for the encryption scheme */ - scheme = pbe2->encryption; - - scheme->algorithm = OBJ_nid2obj(alg_nid); - if (!(scheme->parameter = ASN1_TYPE_new())) - goto merr; - - /* Create random IV */ - if (EVP_CIPHER_iv_length(cipher)) { - if (aiv) - memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); - else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0) - goto err; - } - - EVP_CIPHER_CTX_init(&ctx); - - /* Dummy cipherinit to just setup the IV, and PRF */ - if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0)) - goto err; - if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { - ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); - EVP_CIPHER_CTX_cleanup(&ctx); - goto err; - } - /* - * If prf NID unspecified see if cipher has a preference. An error is OK - * here: just means use default PRF. - */ - if ((prf_nid == -1) && - EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { - ERR_clear_error(); - prf_nid = NID_hmacWithSHA1; - } - EVP_CIPHER_CTX_cleanup(&ctx); - - /* If its RC2 then we'd better setup the key length */ - - if (alg_nid == NID_rc2_cbc) - keylen = EVP_CIPHER_key_length(cipher); - else - keylen = -1; - - /* Setup keyfunc */ - - X509_ALGOR_free(pbe2->keyfunc); - - pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen); - - if (!pbe2->keyfunc) - goto merr; - - /* Now set up top level AlgorithmIdentifier */ - - if (!(ret = X509_ALGOR_new())) - goto merr; - if (!(ret->parameter = ASN1_TYPE_new())) - goto merr; - - ret->algorithm = OBJ_nid2obj(NID_pbes2); - - /* Encode PBE2PARAM into parameter */ - - if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM), - &ret->parameter->value.sequence)) - goto merr; - ret->parameter->type = V_ASN1_SEQUENCE; - - PBE2PARAM_free(pbe2); - pbe2 = NULL; - - return ret; - - merr: - ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE); - - err: - PBE2PARAM_free(pbe2); - /* Note 'scheme' is freed as part of pbe2 */ - X509_ALGOR_free(ret); - - return NULL; -} - -X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, - unsigned char *salt, int saltlen) -{ - return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1); -} - -X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, - int prf_nid, int keylen) -{ - X509_ALGOR *keyfunc = NULL; - PBKDF2PARAM *kdf = NULL; - ASN1_OCTET_STRING *osalt = NULL; - - if (!(kdf = PBKDF2PARAM_new())) - goto merr; - if (!(osalt = M_ASN1_OCTET_STRING_new())) - goto merr; - - kdf->salt->value.octet_string = osalt; - kdf->salt->type = V_ASN1_OCTET_STRING; - - if (!saltlen) - saltlen = PKCS5_SALT_LEN; - if (!(osalt->data = OPENSSL_malloc(saltlen))) - goto merr; - - osalt->length = saltlen; - - if (salt) - memcpy(osalt->data, salt, saltlen); - else if (RAND_bytes(osalt->data, saltlen) <= 0) - goto merr; - - if (iter <= 0) - iter = PKCS5_DEFAULT_ITER; - - if (!ASN1_INTEGER_set(kdf->iter, iter)) - goto merr; - - /* If have a key len set it up */ - - if (keylen > 0) { - if (!(kdf->keylength = M_ASN1_INTEGER_new())) - goto merr; - if (!ASN1_INTEGER_set(kdf->keylength, keylen)) - goto merr; - } - - /* prf can stay NULL if we are using hmacWithSHA1 */ - if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) { - kdf->prf = X509_ALGOR_new(); - if (!kdf->prf) - goto merr; - X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL); - } - - /* Finally setup the keyfunc structure */ - - keyfunc = X509_ALGOR_new(); - if (!keyfunc) - goto merr; - - keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); - - /* Encode PBKDF2PARAM into parameter of pbe2 */ - - if (!(keyfunc->parameter = ASN1_TYPE_new())) - goto merr; - - if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM), - &keyfunc->parameter->value.sequence)) - goto merr; - keyfunc->parameter->type = V_ASN1_SEQUENCE; - - PBKDF2PARAM_free(kdf); - return keyfunc; - - merr: - ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE); - PBKDF2PARAM_free(kdf); - X509_ALGOR_free(keyfunc); - return NULL; -} diff --git a/Sources/COpenSSL/p8_pkey.c b/Sources/COpenSSL/p8_pkey.c deleted file mode 100644 index b7d90ae5..00000000 --- a/Sources/COpenSSL/p8_pkey.c +++ /dev/null @@ -1,145 +0,0 @@ -/* p8_pkey.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "asn1t.h" -#include "x509.h" - -/* Minor tweak to operation: zero private key data */ -static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - /* Since the structure must still be valid use ASN1_OP_FREE_PRE */ - if (operation == ASN1_OP_FREE_PRE) { - PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval; - if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING - && key->pkey->value.octet_string != NULL) - OPENSSL_cleanse(key->pkey->value.octet_string->data, - key->pkey->value.octet_string->length); - } - return 1; -} - -ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = { - ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR), - ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY), - ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0) -} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) - -int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, - int version, - int ptype, void *pval, unsigned char *penc, int penclen) -{ - unsigned char **ppenc = NULL; - if (version >= 0) { - if (!ASN1_INTEGER_set(priv->version, version)) - return 0; - } - if (penc) { - int pmtype; - ASN1_OCTET_STRING *oct; - oct = ASN1_OCTET_STRING_new(); - if (!oct) - return 0; - oct->data = penc; - ppenc = &oct->data; - oct->length = penclen; - if (priv->broken == PKCS8_NO_OCTET) - pmtype = V_ASN1_SEQUENCE; - else - pmtype = V_ASN1_OCTET_STRING; - ASN1_TYPE_set(priv->pkey, pmtype, oct); - } - if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) { - /* If call fails do not swallow 'enc' */ - if (ppenc) - *ppenc = NULL; - return 0; - } - return 1; -} - -int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, - const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8) -{ - if (ppkalg) - *ppkalg = p8->pkeyalg->algorithm; - if (p8->pkey->type == V_ASN1_OCTET_STRING) { - p8->broken = PKCS8_OK; - if (pk) { - *pk = p8->pkey->value.octet_string->data; - *ppklen = p8->pkey->value.octet_string->length; - } - } else if (p8->pkey->type == V_ASN1_SEQUENCE) { - p8->broken = PKCS8_NO_OCTET; - if (pk) { - *pk = p8->pkey->value.sequence->data; - *ppklen = p8->pkey->value.sequence->length; - } - } else - return 0; - if (pa) - *pa = p8->pkeyalg; - return 1; -} diff --git a/Sources/COpenSSL/p_.c b/Sources/COpenSSL/p_.c deleted file mode 100644 index b6d6d274..00000000 --- a/Sources/COpenSSL/p_.c +++ /dev/null @@ -1,1138 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/evp/p_dec.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "rand.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#include "evp.h" -#include "objects.h" -#include "x509.h" - -int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl, - EVP_PKEY *priv) -{ - int ret = -1; - -#ifndef OPENSSL_NO_RSA - if (priv->type != EVP_PKEY_RSA) { -#endif - EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); -#ifndef OPENSSL_NO_RSA - goto err; - } - - ret = - RSA_private_decrypt(ekl, ek, key, priv->pkey.rsa, RSA_PKCS1_PADDING); - err: -#endif - return (ret); -} -/* crypto/evp/p_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "rand.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -// #include "evp.h" -// #include "objects.h" -// #include "x509.h" - -int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, - int key_len, EVP_PKEY *pubk) -{ - int ret = 0; - -#ifndef OPENSSL_NO_RSA - if (pubk->type != EVP_PKEY_RSA) { -#endif - EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); -#ifndef OPENSSL_NO_RSA - goto err; - } - ret = - RSA_public_encrypt(key_len, key, ek, pubk->pkey.rsa, - RSA_PKCS1_PADDING); - err: -#endif - return (ret); -} -/* crypto/evp/p_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "bn.h" -#include "err.h" -// #include "objects.h" -// #include "evp.h" -#include "asn1_mac.h" -// #include "x509.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -#include "asn1_locl.h" - -static void EVP_PKEY_free_it(EVP_PKEY *x); - -int EVP_PKEY_bits(EVP_PKEY *pkey) -{ - if (pkey && pkey->ameth && pkey->ameth->pkey_bits) - return pkey->ameth->pkey_bits(pkey); - return 0; -} - -int EVP_PKEY_size(EVP_PKEY *pkey) -{ - if (pkey && pkey->ameth && pkey->ameth->pkey_size) - return pkey->ameth->pkey_size(pkey); - return 0; -} - -int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) -{ -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) { - int ret = pkey->save_parameters; - - if (mode >= 0) - pkey->save_parameters = mode; - return (ret); - } -#endif -#ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) { - int ret = pkey->save_parameters; - - if (mode >= 0) - pkey->save_parameters = mode; - return (ret); - } -#endif - return (0); -} - -int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) -{ - if (to->type != from->type) { - EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES); - goto err; - } - - if (EVP_PKEY_missing_parameters(from)) { - EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS); - goto err; - } - - if (!EVP_PKEY_missing_parameters(to)) { - if (EVP_PKEY_cmp_parameters(to, from) == 1) - return 1; - EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS); - return 0; - } - - if (from->ameth && from->ameth->param_copy) - return from->ameth->param_copy(to, from); - err: - return 0; -} - -int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) -{ - if (pkey->ameth && pkey->ameth->param_missing) - return pkey->ameth->param_missing(pkey); - return 0; -} - -int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) -{ - if (a->type != b->type) - return -1; - if (a->ameth && a->ameth->param_cmp) - return a->ameth->param_cmp(a, b); - return -2; -} - -int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - if (a->type != b->type) - return -1; - - if (a->ameth) { - int ret; - /* Compare parameters if the algorithm has them */ - if (a->ameth->param_cmp) { - ret = a->ameth->param_cmp(a, b); - if (ret <= 0) - return ret; - } - - if (a->ameth->pub_cmp) - return a->ameth->pub_cmp(a, b); - } - - return -2; -} - -EVP_PKEY *EVP_PKEY_new(void) -{ - EVP_PKEY *ret; - - ret = (EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY)); - if (ret == NULL) { - EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - ret->type = EVP_PKEY_NONE; - ret->save_type = EVP_PKEY_NONE; - ret->references = 1; - ret->ameth = NULL; - ret->engine = NULL; - ret->pkey.ptr = NULL; - ret->attributes = NULL; - ret->save_parameters = 1; - return (ret); -} - -/* - * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey - * is NULL just return 1 or 0 if the algorithm exists. - */ - -static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *e = NULL; - if (pkey) { - if (pkey->pkey.ptr) - EVP_PKEY_free_it(pkey); - /* - * If key type matches and a method exists then this lookup has - * succeeded once so just indicate success. - */ - if ((type == pkey->save_type) && pkey->ameth) - return 1; -#ifndef OPENSSL_NO_ENGINE - /* If we have an ENGINE release it */ - if (pkey->engine) { - ENGINE_finish(pkey->engine); - pkey->engine = NULL; - } -#endif - } - if (str) - ameth = EVP_PKEY_asn1_find_str(&e, str, len); - else - ameth = EVP_PKEY_asn1_find(&e, type); -#ifndef OPENSSL_NO_ENGINE - if (!pkey && e) - ENGINE_finish(e); -#endif - if (!ameth) { - EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); - return 0; - } - if (pkey) { - pkey->ameth = ameth; - pkey->engine = e; - - pkey->type = pkey->ameth->pkey_id; - pkey->save_type = type; - } - return 1; -} - -int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) -{ - return pkey_set_type(pkey, type, NULL, -1); -} - -int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) -{ - return pkey_set_type(pkey, EVP_PKEY_NONE, str, len); -} - -int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) -{ - if (pkey == NULL || !EVP_PKEY_set_type(pkey, type)) - return 0; - pkey->pkey.ptr = key; - return (key != NULL); -} - -void *EVP_PKEY_get0(EVP_PKEY *pkey) -{ - return pkey->pkey.ptr; -} - -#ifndef OPENSSL_NO_RSA -int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) -{ - int ret = EVP_PKEY_assign_RSA(pkey, key); - if (ret) - RSA_up_ref(key); - return ret; -} - -RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_RSA) { - EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY); - return NULL; - } - RSA_up_ref(pkey->pkey.rsa); - return pkey->pkey.rsa; -} -#endif - -#ifndef OPENSSL_NO_DSA -int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) -{ - int ret = EVP_PKEY_assign_DSA(pkey, key); - if (ret) - DSA_up_ref(key); - return ret; -} - -DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_DSA) { - EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY); - return NULL; - } - DSA_up_ref(pkey->pkey.dsa); - return pkey->pkey.dsa; -} -#endif - -#ifndef OPENSSL_NO_EC - -int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) -{ - int ret = EVP_PKEY_assign_EC_KEY(pkey, key); - if (ret) - EC_KEY_up_ref(key); - return ret; -} - -EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_EC) { - EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY); - return NULL; - } - EC_KEY_up_ref(pkey->pkey.ec); - return pkey->pkey.ec; -} -#endif - -#ifndef OPENSSL_NO_DH - -int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) -{ - int ret = EVP_PKEY_assign_DH(pkey, key); - if (ret) - DH_up_ref(key); - return ret; -} - -DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_DH && pkey->type != EVP_PKEY_DHX) { - EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY); - return NULL; - } - DH_up_ref(pkey->pkey.dh); - return pkey->pkey.dh; -} -#endif - -int EVP_PKEY_type(int type) -{ - int ret; - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *e; - ameth = EVP_PKEY_asn1_find(&e, type); - if (ameth) - ret = ameth->pkey_id; - else - ret = NID_undef; -#ifndef OPENSSL_NO_ENGINE - if (e) - ENGINE_finish(e); -#endif - return ret; -} - -int EVP_PKEY_id(const EVP_PKEY *pkey) -{ - return pkey->type; -} - -int EVP_PKEY_base_id(const EVP_PKEY *pkey) -{ - return EVP_PKEY_type(pkey->type); -} - -void EVP_PKEY_free(EVP_PKEY *x) -{ - int i; - - if (x == NULL) - return; - - i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY); -#ifdef REF_PRINT - REF_PRINT("EVP_PKEY", x); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "EVP_PKEY_free, bad reference count\n"); - abort(); - } -#endif - EVP_PKEY_free_it(x); - if (x->attributes) - sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); - OPENSSL_free(x); -} - -static void EVP_PKEY_free_it(EVP_PKEY *x) -{ - if (x->ameth && x->ameth->pkey_free) { - x->ameth->pkey_free(x); - x->pkey.ptr = NULL; - } -#ifndef OPENSSL_NO_ENGINE - if (x->engine) { - ENGINE_finish(x->engine); - x->engine = NULL; - } -#endif -} - -static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, - const char *kstr) -{ - BIO_indent(out, indent, 128); - BIO_printf(out, "%s algorithm \"%s\" unsupported\n", - kstr, OBJ_nid2ln(pkey->type)); - return 1; -} - -int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx) -{ - if (pkey->ameth && pkey->ameth->pub_print) - return pkey->ameth->pub_print(out, pkey, indent, pctx); - - return unsup_alg(out, pkey, indent, "Public Key"); -} - -int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx) -{ - if (pkey->ameth && pkey->ameth->priv_print) - return pkey->ameth->priv_print(out, pkey, indent, pctx); - - return unsup_alg(out, pkey, indent, "Private Key"); -} - -int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, - int indent, ASN1_PCTX *pctx) -{ - if (pkey->ameth && pkey->ameth->param_print) - return pkey->ameth->param_print(out, pkey, indent, pctx); - return unsup_alg(out, pkey, indent, "Parameters"); -} - -int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) -{ - if (!pkey->ameth || !pkey->ameth->pkey_ctrl) - return -2; - return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, - 0, pnid); -} -/* crypto/evp/p_open.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" - -#ifndef OPENSSL_NO_RSA - -# include "evp.h" -# include "objects.h" -# include "x509.h" -# include "rsa.h" - -int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, - const unsigned char *ek, int ekl, const unsigned char *iv, - EVP_PKEY *priv) -{ - unsigned char *key = NULL; - int i, size = 0, ret = 0; - - if (type) { - EVP_CIPHER_CTX_init(ctx); - if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL)) - return 0; - } - - if (!priv) - return 1; - - if (priv->type != EVP_PKEY_RSA) { - EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA); - goto err; - } - - size = RSA_size(priv->pkey.rsa); - key = (unsigned char *)OPENSSL_malloc(size + 2); - if (key == NULL) { - /* ERROR */ - EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE); - goto err; - } - - i = EVP_PKEY_decrypt_old(key, ek, ekl, priv); - if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) { - /* ERROR */ - goto err; - } - if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) - goto err; - - ret = 1; - err: - if (key != NULL) - OPENSSL_cleanse(key, size); - OPENSSL_free(key); - return (ret); -} - -int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) -{ - int i; - - i = EVP_DecryptFinal_ex(ctx, out, outl); - if (i) - i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); - return (i); -} -#else /* !OPENSSL_NO_RSA */ - -# ifdef PEDANTIC -static void *dummy = &dummy; -# endif - -#endif -/* crypto/evp/p_seal.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "rand.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -// #include "evp.h" -// #include "objects.h" -// #include "x509.h" - -int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, - unsigned char **ek, int *ekl, unsigned char *iv, - EVP_PKEY **pubk, int npubk) -{ - unsigned char key[EVP_MAX_KEY_LENGTH]; - int i; - - if (type) { - EVP_CIPHER_CTX_init(ctx); - if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL)) - return 0; - } - if ((npubk <= 0) || !pubk) - return 1; - if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) - return 0; - if (EVP_CIPHER_CTX_iv_length(ctx) - && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0) - return 0; - - if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) - return 0; - - for (i = 0; i < npubk; i++) { - ekl[i] = - EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx), - pubk[i]); - if (ekl[i] <= 0) - return (-1); - } - return (npubk); -} - -/*- MACRO -void EVP_SealUpdate(ctx,out,outl,in,inl) -EVP_CIPHER_CTX *ctx; -unsigned char *out; -int *outl; -unsigned char *in; -int inl; - { - EVP_EncryptUpdate(ctx,out,outl,in,inl); - } -*/ - -int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) -{ - int i; - i = EVP_EncryptFinal_ex(ctx, out, outl); - if (i) - i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL); - return i; -} -/* crypto/evp/p_sign.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "objects.h" -// #include "x509.h" - -#ifdef undef -void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) -{ - EVP_DigestInit_ex(ctx, type); -} - -void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) -{ - EVP_DigestUpdate(ctx, data, count); -} -#endif - -int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, - unsigned int *siglen, EVP_PKEY *pkey) -{ - unsigned char m[EVP_MAX_MD_SIZE]; - unsigned int m_len; - int i = 0, ok = 0, v; - EVP_MD_CTX tmp_ctx; - EVP_PKEY_CTX *pkctx = NULL; - - *siglen = 0; - EVP_MD_CTX_init(&tmp_ctx); - if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) - goto err; - if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len)) - goto err; - EVP_MD_CTX_cleanup(&tmp_ctx); - - if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { - size_t sltmp = (size_t)EVP_PKEY_size(pkey); - i = 0; - pkctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pkctx) - goto err; - if (EVP_PKEY_sign_init(pkctx) <= 0) - goto err; - if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) - goto err; - if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) - goto err; - *siglen = sltmp; - i = 1; - err: - EVP_PKEY_CTX_free(pkctx); - return i; - } - - for (i = 0; i < 4; i++) { - v = ctx->digest->required_pkey_type[i]; - if (v == 0) - break; - if (pkey->type == v) { - ok = 1; - break; - } - } - if (!ok) { - EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE); - return (0); - } - - if (ctx->digest->sign == NULL) { - EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_NO_SIGN_FUNCTION_CONFIGURED); - return (0); - } - return (ctx->digest->sign(ctx->digest->type, m, m_len, sigret, siglen, - pkey->pkey.ptr)); -} -/* crypto/evp/p_verify.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "objects.h" -// #include "x509.h" - -int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, - unsigned int siglen, EVP_PKEY *pkey) -{ - unsigned char m[EVP_MAX_MD_SIZE]; - unsigned int m_len; - int i = 0, ok = 0, v; - EVP_MD_CTX tmp_ctx; - EVP_PKEY_CTX *pkctx = NULL; - - EVP_MD_CTX_init(&tmp_ctx); - if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) - goto err; - if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len)) - goto err; - EVP_MD_CTX_cleanup(&tmp_ctx); - - if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { - i = -1; - pkctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pkctx) - goto err; - if (EVP_PKEY_verify_init(pkctx) <= 0) - goto err; - if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) - goto err; - i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); - err: - EVP_PKEY_CTX_free(pkctx); - return i; - } - - for (i = 0; i < 4; i++) { - v = ctx->digest->required_pkey_type[i]; - if (v == 0) - break; - if (pkey->type == v) { - ok = 1; - break; - } - } - if (!ok) { - EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE); - return (-1); - } - if (ctx->digest->verify == NULL) { - EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED); - return (0); - } - - return (ctx->digest->verify(ctx->digest->type, m, m_len, - sigbuf, siglen, pkey->pkey.ptr)); -} diff --git a/Sources/COpenSSL/pcbc_enc.c b/Sources/COpenSSL/pcbc_enc.c deleted file mode 100644 index 144d5ed8..00000000 --- a/Sources/COpenSSL/pcbc_enc.c +++ /dev/null @@ -1,115 +0,0 @@ -/* crypto/des/pcbc_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, int enc) -{ - register DES_LONG sin0, sin1, xor0, xor1, tout0, tout1; - DES_LONG tin[2]; - const unsigned char *in; - unsigned char *out, *iv; - - in = input; - out = output; - iv = &(*ivec)[0]; - - if (enc) { - c2l(iv, xor0); - c2l(iv, xor1); - for (; length > 0; length -= 8) { - if (length >= 8) { - c2l(in, sin0); - c2l(in, sin1); - } else - c2ln(in, sin0, sin1, length); - tin[0] = sin0 ^ xor0; - tin[1] = sin1 ^ xor1; - DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); - tout0 = tin[0]; - tout1 = tin[1]; - xor0 = sin0 ^ tout0; - xor1 = sin1 ^ tout1; - l2c(tout0, out); - l2c(tout1, out); - } - } else { - c2l(iv, xor0); - c2l(iv, xor1); - for (; length > 0; length -= 8) { - c2l(in, sin0); - c2l(in, sin1); - tin[0] = sin0; - tin[1] = sin1; - DES_encrypt1((DES_LONG *)tin, schedule, DES_DECRYPT); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - if (length >= 8) { - l2c(tout0, out); - l2c(tout1, out); - } else - l2cn(tout0, tout1, out, length); - xor0 = tout0 ^ sin0; - xor1 = tout1 ^ sin1; - } - } - tin[0] = tin[1] = 0; - sin0 = sin1 = xor0 = xor1 = tout0 = tout1 = 0; -} diff --git a/Sources/COpenSSL/pcy_.c b/Sources/COpenSSL/pcy_.c deleted file mode 100644 index 800e0642..00000000 --- a/Sources/COpenSSL/pcy_.c +++ /dev/null @@ -1,1721 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* pcy_cache.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "cryptlib.h" -#include "x509.h" -#include "x509v3.h" - -#include "pcy_int.h" - -static int policy_data_cmp(const X509_POLICY_DATA *const *a, - const X509_POLICY_DATA *const *b); -static int policy_cache_set_int(long *out, ASN1_INTEGER *value); - -/* - * Set cache entry according to CertificatePolicies extension. Note: this - * destroys the passed CERTIFICATEPOLICIES structure. - */ - -static int policy_cache_create(X509 *x, - CERTIFICATEPOLICIES *policies, int crit) -{ - int i; - int ret = 0; - X509_POLICY_CACHE *cache = x->policy_cache; - X509_POLICY_DATA *data = NULL; - POLICYINFO *policy; - if (sk_POLICYINFO_num(policies) == 0) - goto bad_policy; - cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); - if (!cache->data) - goto bad_policy; - for (i = 0; i < sk_POLICYINFO_num(policies); i++) { - policy = sk_POLICYINFO_value(policies, i); - data = policy_data_new(policy, NULL, crit); - if (!data) - goto bad_policy; - /* - * Duplicate policy OIDs are illegal: reject if matches found. - */ - if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { - if (cache->anyPolicy) { - ret = -1; - goto bad_policy; - } - cache->anyPolicy = data; - } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) { - ret = -1; - goto bad_policy; - } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) - goto bad_policy; - data = NULL; - } - ret = 1; - bad_policy: - if (ret == -1) - x->ex_flags |= EXFLAG_INVALID_POLICY; - if (data) - policy_data_free(data); - sk_POLICYINFO_pop_free(policies, POLICYINFO_free); - if (ret <= 0) { - sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); - cache->data = NULL; - } - return ret; -} - -static int policy_cache_new(X509 *x) -{ - X509_POLICY_CACHE *cache; - ASN1_INTEGER *ext_any = NULL; - POLICY_CONSTRAINTS *ext_pcons = NULL; - CERTIFICATEPOLICIES *ext_cpols = NULL; - POLICY_MAPPINGS *ext_pmaps = NULL; - int i; - cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE)); - if (!cache) - return 0; - cache->anyPolicy = NULL; - cache->data = NULL; - cache->any_skip = -1; - cache->explicit_skip = -1; - cache->map_skip = -1; - - x->policy_cache = cache; - - /* - * Handle requireExplicitPolicy *first*. Need to process this even if we - * don't have any policies. - */ - ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL); - - if (!ext_pcons) { - if (i != -1) - goto bad_cache; - } else { - if (!ext_pcons->requireExplicitPolicy - && !ext_pcons->inhibitPolicyMapping) - goto bad_cache; - if (!policy_cache_set_int(&cache->explicit_skip, - ext_pcons->requireExplicitPolicy)) - goto bad_cache; - if (!policy_cache_set_int(&cache->map_skip, - ext_pcons->inhibitPolicyMapping)) - goto bad_cache; - } - - /* Process CertificatePolicies */ - - ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL); - /* - * If no CertificatePolicies extension or problem decoding then there is - * no point continuing because the valid policies will be NULL. - */ - if (!ext_cpols) { - /* If not absent some problem with extension */ - if (i != -1) - goto bad_cache; - return 1; - } - - i = policy_cache_create(x, ext_cpols, i); - - /* NB: ext_cpols freed by policy_cache_set_policies */ - - if (i <= 0) - return i; - - ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL); - - if (!ext_pmaps) { - /* If not absent some problem with extension */ - if (i != -1) - goto bad_cache; - } else { - i = policy_cache_set_mapping(x, ext_pmaps); - if (i <= 0) - goto bad_cache; - } - - ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL); - - if (!ext_any) { - if (i != -1) - goto bad_cache; - } else if (!policy_cache_set_int(&cache->any_skip, ext_any)) - goto bad_cache; - - if (0) { - bad_cache: - x->ex_flags |= EXFLAG_INVALID_POLICY; - } - - if (ext_pcons) - POLICY_CONSTRAINTS_free(ext_pcons); - - if (ext_any) - ASN1_INTEGER_free(ext_any); - - return 1; - -} - -void policy_cache_free(X509_POLICY_CACHE *cache) -{ - if (!cache) - return; - if (cache->anyPolicy) - policy_data_free(cache->anyPolicy); - if (cache->data) - sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); - OPENSSL_free(cache); -} - -const X509_POLICY_CACHE *policy_cache_set(X509 *x) -{ - - if (x->policy_cache == NULL) { - CRYPTO_w_lock(CRYPTO_LOCK_X509); - policy_cache_new(x); - CRYPTO_w_unlock(CRYPTO_LOCK_X509); - } - - return x->policy_cache; - -} - -X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, - const ASN1_OBJECT *id) -{ - int idx; - X509_POLICY_DATA tmp; - tmp.valid_policy = (ASN1_OBJECT *)id; - idx = sk_X509_POLICY_DATA_find(cache->data, &tmp); - if (idx == -1) - return NULL; - return sk_X509_POLICY_DATA_value(cache->data, idx); -} - -static int policy_data_cmp(const X509_POLICY_DATA *const *a, - const X509_POLICY_DATA *const *b) -{ - return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy); -} - -static int policy_cache_set_int(long *out, ASN1_INTEGER *value) -{ - if (value == NULL) - return 1; - if (value->type == V_ASN1_NEG_INTEGER) - return 0; - *out = ASN1_INTEGER_get(value); - return 1; -} -/* pcy_data.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "x509.h" -// #include "x509v3.h" - -// #include "pcy_int.h" - -/* Policy Node routines */ - -void policy_data_free(X509_POLICY_DATA *data) -{ - ASN1_OBJECT_free(data->valid_policy); - /* Don't free qualifiers if shared */ - if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS)) - sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free); - sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free); - OPENSSL_free(data); -} - -/* - * Create a data based on an existing policy. If 'id' is NULL use the oid in - * the policy, otherwise use 'id'. This behaviour covers the two types of - * data in RFC3280: data with from a CertificatePolcies extension and - * additional data with just the qualifiers of anyPolicy and ID from another - * source. - */ - -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, - const ASN1_OBJECT *cid, int crit) -{ - X509_POLICY_DATA *ret; - ASN1_OBJECT *id; - if (!policy && !cid) - return NULL; - if (cid) { - id = OBJ_dup(cid); - if (!id) - return NULL; - } else - id = NULL; - ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); - if (!ret) - return NULL; - ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); - if (!ret->expected_policy_set) { - OPENSSL_free(ret); - if (id) - ASN1_OBJECT_free(id); - return NULL; - } - - if (crit) - ret->flags = POLICY_DATA_FLAG_CRITICAL; - else - ret->flags = 0; - - if (id) - ret->valid_policy = id; - else { - ret->valid_policy = policy->policyid; - policy->policyid = NULL; - } - - if (policy) { - ret->qualifier_set = policy->qualifiers; - policy->qualifiers = NULL; - } else - ret->qualifier_set = NULL; - - return ret; -} -/* pcy_lib.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "x509.h" -// #include "x509v3.h" - -// #include "pcy_int.h" - -/* accessor functions */ - -/* X509_POLICY_TREE stuff */ - -int X509_policy_tree_level_count(const X509_POLICY_TREE *tree) -{ - if (!tree) - return 0; - return tree->nlevel; -} - -X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, - int i) -{ - if (!tree || (i < 0) || (i >= tree->nlevel)) - return NULL; - return tree->levels + i; -} - -STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const - X509_POLICY_TREE - *tree) -{ - if (!tree) - return NULL; - return tree->auth_policies; -} - -STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const - X509_POLICY_TREE - *tree) -{ - if (!tree) - return NULL; - if (tree->flags & POLICY_FLAG_ANY_POLICY) - return tree->auth_policies; - else - return tree->user_policies; -} - -/* X509_POLICY_LEVEL stuff */ - -int X509_policy_level_node_count(X509_POLICY_LEVEL *level) -{ - int n; - if (!level) - return 0; - if (level->anyPolicy) - n = 1; - else - n = 0; - if (level->nodes) - n += sk_X509_POLICY_NODE_num(level->nodes); - return n; -} - -X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) -{ - if (!level) - return NULL; - if (level->anyPolicy) { - if (i == 0) - return level->anyPolicy; - i--; - } - return sk_X509_POLICY_NODE_value(level->nodes, i); -} - -/* X509_POLICY_NODE stuff */ - -const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node) -{ - if (!node) - return NULL; - return node->data->valid_policy; -} - -#if 0 -int X509_policy_node_get_critical(const X509_POLICY_NODE *node) -{ - if (node_critical(node)) - return 1; - return 0; -} -#endif - -STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const - X509_POLICY_NODE - *node) -{ - if (!node) - return NULL; - return node->data->qualifier_set; -} - -const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE - *node) -{ - if (!node) - return NULL; - return node->parent; -} -/* pcy_map.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "x509.h" -// #include "x509v3.h" - -// #include "pcy_int.h" - -/* - * Set policy mapping entries in cache. Note: this modifies the passed - * POLICY_MAPPINGS structure - */ - -int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) -{ - POLICY_MAPPING *map; - X509_POLICY_DATA *data; - X509_POLICY_CACHE *cache = x->policy_cache; - int i; - int ret = 0; - if (sk_POLICY_MAPPING_num(maps) == 0) { - ret = -1; - goto bad_mapping; - } - for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { - map = sk_POLICY_MAPPING_value(maps, i); - /* Reject if map to or from anyPolicy */ - if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) - || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) { - ret = -1; - goto bad_mapping; - } - - /* Attempt to find matching policy data */ - data = policy_cache_find_data(cache, map->issuerDomainPolicy); - /* If we don't have anyPolicy can't map */ - if (!data && !cache->anyPolicy) - continue; - - /* Create a NODE from anyPolicy */ - if (!data) { - data = policy_data_new(NULL, map->issuerDomainPolicy, - cache->anyPolicy->flags - & POLICY_DATA_FLAG_CRITICAL); - if (!data) - goto bad_mapping; - data->qualifier_set = cache->anyPolicy->qualifier_set; - /* - * map->issuerDomainPolicy = NULL; - */ - data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; - data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; - if (!sk_X509_POLICY_DATA_push(cache->data, data)) { - policy_data_free(data); - goto bad_mapping; - } - } else - data->flags |= POLICY_DATA_FLAG_MAPPED; - if (!sk_ASN1_OBJECT_push(data->expected_policy_set, - map->subjectDomainPolicy)) - goto bad_mapping; - map->subjectDomainPolicy = NULL; - - } - - ret = 1; - bad_mapping: - if (ret == -1) - x->ex_flags |= EXFLAG_INVALID_POLICY; - sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); - return ret; - -} -/* pcy_node.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "asn1.h" -// #include "x509.h" -// #include "x509v3.h" - -// #include "pcy_int.h" - -static int node_cmp(const X509_POLICY_NODE *const *a, - const X509_POLICY_NODE *const *b) -{ - return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); -} - -STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) -{ - return sk_X509_POLICY_NODE_new(node_cmp); -} - -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, - const ASN1_OBJECT *id) -{ - X509_POLICY_DATA n; - X509_POLICY_NODE l; - int idx; - - n.valid_policy = (ASN1_OBJECT *)id; - l.data = &n; - - idx = sk_X509_POLICY_NODE_find(nodes, &l); - if (idx == -1) - return NULL; - - return sk_X509_POLICY_NODE_value(nodes, idx); - -} - -X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, - const X509_POLICY_NODE *parent, - const ASN1_OBJECT *id) -{ - X509_POLICY_NODE *node; - int i; - for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { - node = sk_X509_POLICY_NODE_value(level->nodes, i); - if (node->parent == parent) { - if (!OBJ_cmp(node->data->valid_policy, id)) - return node; - } - } - return NULL; -} - -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - const X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree) -{ - X509_POLICY_NODE *node; - node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); - if (!node) - return NULL; - node->data = data; - node->parent = parent; - node->nchild = 0; - if (level) { - if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { - if (level->anyPolicy) - goto node_error; - level->anyPolicy = node; - } else { - - if (!level->nodes) - level->nodes = policy_node_cmp_new(); - if (!level->nodes) - goto node_error; - if (!sk_X509_POLICY_NODE_push(level->nodes, node)) - goto node_error; - } - } - - if (tree) { - if (!tree->extra_data) - tree->extra_data = sk_X509_POLICY_DATA_new_null(); - if (!tree->extra_data) - goto node_error; - if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) - goto node_error; - } - - if (parent) - parent->nchild++; - - return node; - - node_error: - policy_node_free(node); - return 0; - -} - -void policy_node_free(X509_POLICY_NODE *node) -{ - OPENSSL_free(node); -} - -/* - * See if a policy node matches a policy OID. If mapping enabled look through - * expected policy set otherwise just valid policy. - */ - -int policy_node_match(const X509_POLICY_LEVEL *lvl, - const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) -{ - int i; - ASN1_OBJECT *policy_oid; - const X509_POLICY_DATA *x = node->data; - - if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) - || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) { - if (!OBJ_cmp(x->valid_policy, oid)) - return 1; - return 0; - } - - for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) { - policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); - if (!OBJ_cmp(policy_oid, oid)) - return 1; - } - return 0; - -} -/* pcy_tree.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "x509.h" -// #include "x509v3.h" - -// #include "pcy_int.h" - -/* - * Enable this to print out the complete policy tree at various point during - * evaluation. - */ - -/* - * #define OPENSSL_POLICY_DEBUG - */ - -#ifdef OPENSSL_POLICY_DEBUG - -static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, - X509_POLICY_NODE *node, int indent) -{ - if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) - || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) - BIO_puts(err, " Not Mapped\n"); - else { - int i; - STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; - ASN1_OBJECT *oid; - BIO_puts(err, " Expected: "); - for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) { - oid = sk_ASN1_OBJECT_value(pset, i); - if (i) - BIO_puts(err, ", "); - i2a_ASN1_OBJECT(err, oid); - } - BIO_puts(err, "\n"); - } -} - -static void tree_print(char *str, X509_POLICY_TREE *tree, - X509_POLICY_LEVEL *curr) -{ - X509_POLICY_LEVEL *plev; - X509_POLICY_NODE *node; - int i; - BIO *err; - err = BIO_new_fp(stderr, BIO_NOCLOSE); - if (!curr) - curr = tree->levels + tree->nlevel; - else - curr++; - BIO_printf(err, "Level print after %s\n", str); - BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); - for (plev = tree->levels; plev != curr; plev++) { - BIO_printf(err, "Level %ld, flags = %x\n", - plev - tree->levels, plev->flags); - for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) { - node = sk_X509_POLICY_NODE_value(plev->nodes, i); - X509_POLICY_NODE_print(err, node, 2); - expected_print(err, plev, node, 2); - BIO_printf(err, " Flags: %x\n", node->data->flags); - } - if (plev->anyPolicy) - X509_POLICY_NODE_print(err, plev->anyPolicy, 2); - } - - BIO_free(err); - -} -#else - -# define tree_print(a,b,c) /* */ - -#endif - -/*- - * Initialize policy tree. Return values: - * 0 Some internal error occurred. - * -1 Inconsistent or invalid extensions in certificates. - * 1 Tree initialized OK. - * 2 Policy tree is empty. - * 5 Tree OK and requireExplicitPolicy true. - * 6 Tree empty and requireExplicitPolicy true. - */ - -static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, - unsigned int flags) -{ - X509_POLICY_TREE *tree; - X509_POLICY_LEVEL *level; - const X509_POLICY_CACHE *cache; - X509_POLICY_DATA *data = NULL; - X509 *x; - int ret = 1; - int i, n; - int explicit_policy; - int any_skip; - int map_skip; - *ptree = NULL; - n = sk_X509_num(certs); - -#if 0 - /* Disable policy mapping for now... */ - flags |= X509_V_FLAG_INHIBIT_MAP; -#endif - - if (flags & X509_V_FLAG_EXPLICIT_POLICY) - explicit_policy = 0; - else - explicit_policy = n + 1; - - if (flags & X509_V_FLAG_INHIBIT_ANY) - any_skip = 0; - else - any_skip = n + 1; - - if (flags & X509_V_FLAG_INHIBIT_MAP) - map_skip = 0; - else - map_skip = n + 1; - - /* Can't do anything with just a trust anchor */ - if (n == 1) - return 1; - /* - * First setup policy cache in all certificates apart from the trust - * anchor. Note any bad cache results on the way. Also can calculate - * explicit_policy value at this point. - */ - for (i = n - 2; i >= 0; i--) { - x = sk_X509_value(certs, i); - X509_check_purpose(x, -1, -1); - cache = policy_cache_set(x); - /* If cache NULL something bad happened: return immediately */ - if (cache == NULL) - return 0; - /* - * If inconsistent extensions keep a note of it but continue - */ - if (x->ex_flags & EXFLAG_INVALID_POLICY) - ret = -1; - /* - * Otherwise if we have no data (hence no CertificatePolicies) and - * haven't already set an inconsistent code note it. - */ - else if ((ret == 1) && !cache->data) - ret = 2; - if (explicit_policy > 0) { - if (!(x->ex_flags & EXFLAG_SI)) - explicit_policy--; - if ((cache->explicit_skip != -1) - && (cache->explicit_skip < explicit_policy)) - explicit_policy = cache->explicit_skip; - } - } - - if (ret != 1) { - if (ret == 2 && !explicit_policy) - return 6; - return ret; - } - - /* If we get this far initialize the tree */ - - tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE)); - - if (!tree) - return 0; - - tree->flags = 0; - tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n); - tree->nlevel = 0; - tree->extra_data = NULL; - tree->auth_policies = NULL; - tree->user_policies = NULL; - - if (!tree->levels) { - OPENSSL_free(tree); - return 0; - } - - memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); - - tree->nlevel = n; - - level = tree->levels; - - /* Root data: initialize to anyPolicy */ - - data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); - - if (!data || !level_add_node(level, data, NULL, tree)) - goto bad_tree; - - for (i = n - 2; i >= 0; i--) { - level++; - x = sk_X509_value(certs, i); - cache = policy_cache_set(x); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - level->cert = x; - - if (!cache->anyPolicy) - level->flags |= X509_V_FLAG_INHIBIT_ANY; - - /* Determine inhibit any and inhibit map flags */ - if (any_skip == 0) { - /* - * Any matching allowed if certificate is self issued and not the - * last in the chain. - */ - if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) - level->flags |= X509_V_FLAG_INHIBIT_ANY; - } else { - if (!(x->ex_flags & EXFLAG_SI)) - any_skip--; - if ((cache->any_skip >= 0) - && (cache->any_skip < any_skip)) - any_skip = cache->any_skip; - } - - if (map_skip == 0) - level->flags |= X509_V_FLAG_INHIBIT_MAP; - else { - if (!(x->ex_flags & EXFLAG_SI)) - map_skip--; - if ((cache->map_skip >= 0) - && (cache->map_skip < map_skip)) - map_skip = cache->map_skip; - } - - } - - *ptree = tree; - - if (explicit_policy) - return 1; - else - return 5; - - bad_tree: - - X509_policy_tree_free(tree); - - return 0; - -} - -static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, - const X509_POLICY_DATA *data) -{ - X509_POLICY_LEVEL *last = curr - 1; - X509_POLICY_NODE *node; - int i, matched = 0; - /* Iterate through all in nodes linking matches */ - for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { - node = sk_X509_POLICY_NODE_value(last->nodes, i); - if (policy_node_match(last, node, data->valid_policy)) { - if (!level_add_node(curr, data, node, NULL)) - return 0; - matched = 1; - } - } - if (!matched && last->anyPolicy) { - if (!level_add_node(curr, data, last->anyPolicy, NULL)) - return 0; - } - return 1; -} - -/* - * This corresponds to RFC3280 6.1.3(d)(1): link any data from - * CertificatePolicies onto matching parent or anyPolicy if no match. - */ - -static int tree_link_nodes(X509_POLICY_LEVEL *curr, - const X509_POLICY_CACHE *cache) -{ - int i; - X509_POLICY_DATA *data; - - for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) { - data = sk_X509_POLICY_DATA_value(cache->data, i); - /* - * If a node is mapped any it doesn't have a corresponding - * CertificatePolicies entry. However such an identical node would - * be created if anyPolicy matching is enabled because there would be - * no match with the parent valid_policy_set. So we create link - * because then it will have the mapping flags right and we can prune - * it later. - */ -#if 0 - if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) - && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) - continue; -#endif - /* Look for matching nodes in previous level */ - if (!tree_link_matching_nodes(curr, data)) - return 0; - } - return 1; -} - -/* - * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched - * policies in the parent and link to anyPolicy. - */ - -static int tree_add_unmatched(X509_POLICY_LEVEL *curr, - const X509_POLICY_CACHE *cache, - const ASN1_OBJECT *id, - X509_POLICY_NODE *node, X509_POLICY_TREE *tree) -{ - X509_POLICY_DATA *data; - if (id == NULL) - id = node->data->valid_policy; - /* - * Create a new node with qualifiers from anyPolicy and id from unmatched - * node. - */ - data = policy_data_new(NULL, id, node_critical(node)); - - if (data == NULL) - return 0; - /* Curr may not have anyPolicy */ - data->qualifier_set = cache->anyPolicy->qualifier_set; - data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; - if (!level_add_node(curr, data, node, tree)) { - policy_data_free(data); - return 0; - } - - return 1; -} - -static int tree_link_unmatched(X509_POLICY_LEVEL *curr, - const X509_POLICY_CACHE *cache, - X509_POLICY_NODE *node, X509_POLICY_TREE *tree) -{ - const X509_POLICY_LEVEL *last = curr - 1; - int i; - - if ((last->flags & X509_V_FLAG_INHIBIT_MAP) - || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) { - /* If no policy mapping: matched if one child present */ - if (node->nchild) - return 1; - if (!tree_add_unmatched(curr, cache, NULL, node, tree)) - return 0; - /* Add it */ - } else { - /* If mapping: matched if one child per expected policy set */ - STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; - if (node->nchild == sk_ASN1_OBJECT_num(expset)) - return 1; - /* Locate unmatched nodes */ - for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) { - ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); - if (level_find_node(curr, node, oid)) - continue; - if (!tree_add_unmatched(curr, cache, oid, node, tree)) - return 0; - } - - } - - return 1; - -} - -static int tree_link_any(X509_POLICY_LEVEL *curr, - const X509_POLICY_CACHE *cache, - X509_POLICY_TREE *tree) -{ - int i; - /* - * X509_POLICY_DATA *data; - */ - X509_POLICY_NODE *node; - X509_POLICY_LEVEL *last = curr - 1; - - for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { - node = sk_X509_POLICY_NODE_value(last->nodes, i); - - if (!tree_link_unmatched(curr, cache, node, tree)) - return 0; - -#if 0 - - /* - * Skip any node with any children: we only want unmathced nodes. - * Note: need something better for policy mapping because each node - * may have multiple children - */ - if (node->nchild) - continue; - - /* - * Create a new node with qualifiers from anyPolicy and id from - * unmatched node. - */ - data = policy_data_new(NULL, node->data->valid_policy, - node_critical(node)); - - if (data == NULL) - return 0; - /* Curr may not have anyPolicy */ - data->qualifier_set = cache->anyPolicy->qualifier_set; - data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; - if (!level_add_node(curr, data, node, tree)) { - policy_data_free(data); - return 0; - } -#endif - - } - /* Finally add link to anyPolicy */ - if (last->anyPolicy) { - if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL)) - return 0; - } - return 1; -} - -/* - * Prune the tree: delete any child mapped child data on the current level - * then proceed up the tree deleting any data with no children. If we ever - * have no data on a level we can halt because the tree will be empty. - */ - -static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) -{ - STACK_OF(X509_POLICY_NODE) *nodes; - X509_POLICY_NODE *node; - int i; - nodes = curr->nodes; - if (curr->flags & X509_V_FLAG_INHIBIT_MAP) { - for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { - node = sk_X509_POLICY_NODE_value(nodes, i); - /* Delete any mapped data: see RFC3280 XXXX */ - if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) { - node->parent->nchild--; - OPENSSL_free(node); - (void)sk_X509_POLICY_NODE_delete(nodes, i); - } - } - } - - for (;;) { - --curr; - nodes = curr->nodes; - for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { - node = sk_X509_POLICY_NODE_value(nodes, i); - if (node->nchild == 0) { - node->parent->nchild--; - OPENSSL_free(node); - (void)sk_X509_POLICY_NODE_delete(nodes, i); - } - } - if (curr->anyPolicy && !curr->anyPolicy->nchild) { - if (curr->anyPolicy->parent) - curr->anyPolicy->parent->nchild--; - OPENSSL_free(curr->anyPolicy); - curr->anyPolicy = NULL; - } - if (curr == tree->levels) { - /* If we zapped anyPolicy at top then tree is empty */ - if (!curr->anyPolicy) - return 2; - return 1; - } - } - - return 1; - -} - -static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, - X509_POLICY_NODE *pcy) -{ - if (!*pnodes) { - *pnodes = policy_node_cmp_new(); - if (!*pnodes) - return 0; - } else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1) - return 1; - - if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) - return 0; - - return 1; - -} - -/* - * Calculate the authority set based on policy tree. The 'pnodes' parameter - * is used as a store for the set of policy nodes used to calculate the user - * set. If the authority set is not anyPolicy then pnodes will just point to - * the authority set. If however the authority set is anyPolicy then the set - * of valid policies (other than anyPolicy) is store in pnodes. The return - * value of '2' is used in this case to indicate that pnodes should be freed. - */ - -static int tree_calculate_authority_set(X509_POLICY_TREE *tree, - STACK_OF(X509_POLICY_NODE) **pnodes) -{ - X509_POLICY_LEVEL *curr; - X509_POLICY_NODE *node, *anyptr; - STACK_OF(X509_POLICY_NODE) **addnodes; - int i, j; - curr = tree->levels + tree->nlevel - 1; - - /* If last level contains anyPolicy set is anyPolicy */ - if (curr->anyPolicy) { - if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) - return 0; - addnodes = pnodes; - } else - /* Add policies to authority set */ - addnodes = &tree->auth_policies; - - curr = tree->levels; - for (i = 1; i < tree->nlevel; i++) { - /* - * If no anyPolicy node on this this level it can't appear on lower - * levels so end search. - */ - if (!(anyptr = curr->anyPolicy)) - break; - curr++; - for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) { - node = sk_X509_POLICY_NODE_value(curr->nodes, j); - if ((node->parent == anyptr) - && !tree_add_auth_node(addnodes, node)) - return 0; - } - } - - if (addnodes == pnodes) - return 2; - - *pnodes = tree->auth_policies; - - return 1; -} - -static int tree_calculate_user_set(X509_POLICY_TREE *tree, - STACK_OF(ASN1_OBJECT) *policy_oids, - STACK_OF(X509_POLICY_NODE) *auth_nodes) -{ - int i; - X509_POLICY_NODE *node; - ASN1_OBJECT *oid; - - X509_POLICY_NODE *anyPolicy; - X509_POLICY_DATA *extra; - - /* - * Check if anyPolicy present in authority constrained policy set: this - * will happen if it is a leaf node. - */ - - if (sk_ASN1_OBJECT_num(policy_oids) <= 0) - return 1; - - anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; - - for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { - oid = sk_ASN1_OBJECT_value(policy_oids, i); - if (OBJ_obj2nid(oid) == NID_any_policy) { - tree->flags |= POLICY_FLAG_ANY_POLICY; - return 1; - } - } - - for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { - oid = sk_ASN1_OBJECT_value(policy_oids, i); - node = tree_find_sk(auth_nodes, oid); - if (!node) { - if (!anyPolicy) - continue; - /* - * Create a new node with policy ID from user set and qualifiers - * from anyPolicy. - */ - extra = policy_data_new(NULL, oid, node_critical(anyPolicy)); - if (!extra) - return 0; - extra->qualifier_set = anyPolicy->data->qualifier_set; - extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS - | POLICY_DATA_FLAG_EXTRA_NODE; - node = level_add_node(NULL, extra, anyPolicy->parent, tree); - } - if (!tree->user_policies) { - tree->user_policies = sk_X509_POLICY_NODE_new_null(); - if (!tree->user_policies) - return 1; - } - if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) - return 0; - } - return 1; - -} - -static int tree_evaluate(X509_POLICY_TREE *tree) -{ - int ret, i; - X509_POLICY_LEVEL *curr = tree->levels + 1; - const X509_POLICY_CACHE *cache; - - for (i = 1; i < tree->nlevel; i++, curr++) { - cache = policy_cache_set(curr->cert); - if (!tree_link_nodes(curr, cache)) - return 0; - - if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) - && !tree_link_any(curr, cache, tree)) - return 0; - tree_print("before tree_prune()", tree, curr); - ret = tree_prune(tree, curr); - if (ret != 1) - return ret; - } - - return 1; - -} - -static void exnode_free(X509_POLICY_NODE *node) -{ - if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) - OPENSSL_free(node); -} - -void X509_policy_tree_free(X509_POLICY_TREE *tree) -{ - X509_POLICY_LEVEL *curr; - int i; - - if (!tree) - return; - - sk_X509_POLICY_NODE_free(tree->auth_policies); - sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); - - for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) { - if (curr->cert) - X509_free(curr->cert); - if (curr->nodes) - sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free); - if (curr->anyPolicy) - policy_node_free(curr->anyPolicy); - } - - if (tree->extra_data) - sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free); - - OPENSSL_free(tree->levels); - OPENSSL_free(tree); - -} - -/*- - * Application policy checking function. - * Return codes: - * 0 Internal Error. - * 1 Successful. - * -1 One or more certificates contain invalid or inconsistent extensions - * -2 User constrained policy set empty and requireExplicit true. - */ - -int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, - STACK_OF(X509) *certs, - STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) -{ - int ret; - int calc_ret; - X509_POLICY_TREE *tree = NULL; - STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; - *ptree = NULL; - - *pexplicit_policy = 0; - ret = tree_init(&tree, certs, flags); - - switch (ret) { - - /* Tree empty requireExplicit False: OK */ - case 2: - return 1; - - /* Some internal error */ - case -1: - return -1; - - /* Some internal error */ - case 0: - return 0; - - /* Tree empty requireExplicit True: Error */ - - case 6: - *pexplicit_policy = 1; - return -2; - - /* Tree OK requireExplicit True: OK and continue */ - case 5: - *pexplicit_policy = 1; - break; - - /* Tree OK: continue */ - - case 1: - if (!tree) - /* - * tree_init() returns success and a null tree - * if it's just looking at a trust anchor. - * I'm not sure that returning success here is - * correct, but I'm sure that reporting this - * as an internal error which our caller - * interprets as a malloc failure is wrong. - */ - return 1; - break; - } - - if (!tree) - goto error; - ret = tree_evaluate(tree); - - tree_print("tree_evaluate()", tree, NULL); - - if (ret <= 0) - goto error; - - /* Return value 2 means tree empty */ - if (ret == 2) { - X509_policy_tree_free(tree); - if (*pexplicit_policy) - return -2; - else - return 1; - } - - /* Tree is not empty: continue */ - - calc_ret = tree_calculate_authority_set(tree, &auth_nodes); - - if (!calc_ret) - goto error; - - ret = tree_calculate_user_set(tree, policy_oids, auth_nodes); - - if (calc_ret == 2) - sk_X509_POLICY_NODE_free(auth_nodes); - - if (!ret) - goto error; - - - if (tree) - *ptree = tree; - - if (*pexplicit_policy) { - nodes = X509_policy_tree_get0_user_policies(tree); - if (sk_X509_POLICY_NODE_num(nodes) <= 0) - return -2; - } - - return 1; - - error: - - X509_policy_tree_free(tree); - - return 0; - -} diff --git a/Sources/COpenSSL/pcy_int.h b/Sources/COpenSSL/pcy_int.h deleted file mode 100644 index b5075f9e..00000000 --- a/Sources/COpenSSL/pcy_int.h +++ /dev/null @@ -1,217 +0,0 @@ -/* pcy_int.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; - -DECLARE_STACK_OF(X509_POLICY_DATA) - -/* Internal structures */ - -/* - * This structure and the field names correspond to the Policy 'node' of - * RFC3280. NB this structure contains no pointers to parent or child data: - * X509_POLICY_NODE contains that. This means that the main policy data can - * be kept static and cached with the certificate. - */ - -struct X509_POLICY_DATA_st { - unsigned int flags; - /* Policy OID and qualifiers for this data */ - ASN1_OBJECT *valid_policy; - STACK_OF(POLICYQUALINFO) *qualifier_set; - STACK_OF(ASN1_OBJECT) *expected_policy_set; -}; - -/* X509_POLICY_DATA flags values */ - -/* - * This flag indicates the structure has been mapped using a policy mapping - * extension. If policy mapping is not active its references get deleted. - */ - -#define POLICY_DATA_FLAG_MAPPED 0x1 - -/* - * This flag indicates the data doesn't correspond to a policy in Certificate - * Policies: it has been mapped to any policy. - */ - -#define POLICY_DATA_FLAG_MAPPED_ANY 0x2 - -/* AND with flags to see if any mapping has occurred */ - -#define POLICY_DATA_FLAG_MAP_MASK 0x3 - -/* qualifiers are shared and shouldn't be freed */ - -#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 - -/* Parent node is an extra node and should be freed */ - -#define POLICY_DATA_FLAG_EXTRA_NODE 0x8 - -/* Corresponding CertificatePolicies is critical */ - -#define POLICY_DATA_FLAG_CRITICAL 0x10 - -/* This structure is cached with a certificate */ - -struct X509_POLICY_CACHE_st { - /* anyPolicy data or NULL if no anyPolicy */ - X509_POLICY_DATA *anyPolicy; - /* other policy data */ - STACK_OF(X509_POLICY_DATA) *data; - /* If InhibitAnyPolicy present this is its value or -1 if absent. */ - long any_skip; - /* - * If policyConstraints and requireExplicitPolicy present this is its - * value or -1 if absent. - */ - long explicit_skip; - /* - * If policyConstraints and policyMapping present this is its value or -1 - * if absent. - */ - long map_skip; -}; - -/* - * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL - */ - -/* This structure represents the relationship between nodes */ - -struct X509_POLICY_NODE_st { - /* node data this refers to */ - const X509_POLICY_DATA *data; - /* Parent node */ - X509_POLICY_NODE *parent; - /* Number of child nodes */ - int nchild; -}; - -struct X509_POLICY_LEVEL_st { - /* Cert for this level */ - X509 *cert; - /* nodes at this level */ - STACK_OF(X509_POLICY_NODE) *nodes; - /* anyPolicy node */ - X509_POLICY_NODE *anyPolicy; - /* Extra data */ - /* - * STACK_OF(X509_POLICY_DATA) *extra_data; - */ - unsigned int flags; -}; - -struct X509_POLICY_TREE_st { - /* This is the tree 'level' data */ - X509_POLICY_LEVEL *levels; - int nlevel; - /* - * Extra policy data when additional nodes (not from the certificate) are - * required. - */ - STACK_OF(X509_POLICY_DATA) *extra_data; - /* This is the authority constained policy set */ - STACK_OF(X509_POLICY_NODE) *auth_policies; - STACK_OF(X509_POLICY_NODE) *user_policies; - unsigned int flags; -}; - -/* Set if anyPolicy present in user policies */ -#define POLICY_FLAG_ANY_POLICY 0x2 - -/* Useful macros */ - -#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL) -#define node_critical(node) node_data_critical(node->data) - -/* Internal functions */ - -X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, - int crit); -void policy_data_free(X509_POLICY_DATA *data); - -X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, - const ASN1_OBJECT *id); -int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); - -STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); - -void policy_cache_init(void); - -void policy_cache_free(X509_POLICY_CACHE *cache); - -X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, - const X509_POLICY_NODE *parent, - const ASN1_OBJECT *id); - -X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, - const ASN1_OBJECT *id); - -X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, - const X509_POLICY_DATA *data, - X509_POLICY_NODE *parent, - X509_POLICY_TREE *tree); -void policy_node_free(X509_POLICY_NODE *node); -int policy_node_match(const X509_POLICY_LEVEL *lvl, - const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); - -const X509_POLICY_CACHE *policy_cache_set(X509 *x); diff --git a/Sources/COpenSSL/pem.h b/Sources/COpenSSL/pem.h deleted file mode 100644 index 0d64a193..00000000 --- a/Sources/COpenSSL/pem.h +++ /dev/null @@ -1,618 +0,0 @@ -/* crypto/pem/pem.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_PEM_H -# define HEADER_PEM_H - -# include "e_os2.h" -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# ifndef OPENSSL_NO_STACK -# include "stack.h" -# endif -# include "evp.h" -# include "x509.h" -# include "pem2.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# define PEM_BUFSIZE 1024 - -# define PEM_OBJ_UNDEF 0 -# define PEM_OBJ_X509 1 -# define PEM_OBJ_X509_REQ 2 -# define PEM_OBJ_CRL 3 -# define PEM_OBJ_SSL_SESSION 4 -# define PEM_OBJ_PRIV_KEY 10 -# define PEM_OBJ_PRIV_RSA 11 -# define PEM_OBJ_PRIV_DSA 12 -# define PEM_OBJ_PRIV_DH 13 -# define PEM_OBJ_PUB_RSA 14 -# define PEM_OBJ_PUB_DSA 15 -# define PEM_OBJ_PUB_DH 16 -# define PEM_OBJ_DHPARAMS 17 -# define PEM_OBJ_DSAPARAMS 18 -# define PEM_OBJ_PRIV_RSA_PUBLIC 19 -# define PEM_OBJ_PRIV_ECDSA 20 -# define PEM_OBJ_PUB_ECDSA 21 -# define PEM_OBJ_ECPARAMETERS 22 - -# define PEM_ERROR 30 -# define PEM_DEK_DES_CBC 40 -# define PEM_DEK_IDEA_CBC 45 -# define PEM_DEK_DES_EDE 50 -# define PEM_DEK_DES_ECB 60 -# define PEM_DEK_RSA 70 -# define PEM_DEK_RSA_MD2 80 -# define PEM_DEK_RSA_MD5 90 - -# define PEM_MD_MD2 NID_md2 -# define PEM_MD_MD5 NID_md5 -# define PEM_MD_SHA NID_sha -# define PEM_MD_MD2_RSA NID_md2WithRSAEncryption -# define PEM_MD_MD5_RSA NID_md5WithRSAEncryption -# define PEM_MD_SHA_RSA NID_sha1WithRSAEncryption - -# define PEM_STRING_X509_OLD "X509 CERTIFICATE" -# define PEM_STRING_X509 "CERTIFICATE" -# define PEM_STRING_X509_PAIR "CERTIFICATE PAIR" -# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" -# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" -# define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" -# define PEM_STRING_X509_CRL "X509 CRL" -# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" -# define PEM_STRING_PUBLIC "PUBLIC KEY" -# define PEM_STRING_RSA "RSA PRIVATE KEY" -# define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" -# define PEM_STRING_DSA "DSA PRIVATE KEY" -# define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" -# define PEM_STRING_PKCS7 "PKCS7" -# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" -# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" -# define PEM_STRING_PKCS8INF "PRIVATE KEY" -# define PEM_STRING_DHPARAMS "DH PARAMETERS" -# define PEM_STRING_DHXPARAMS "X9.42 DH PARAMETERS" -# define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" -# define PEM_STRING_DSAPARAMS "DSA PARAMETERS" -# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" -# define PEM_STRING_ECPARAMETERS "EC PARAMETERS" -# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" -# define PEM_STRING_PARAMETERS "PARAMETERS" -# define PEM_STRING_CMS "CMS" - - /* - * Note that this structure is initialised by PEM_SealInit and cleaned up - * by PEM_SealFinal (at least for now) - */ -typedef struct PEM_Encode_Seal_st { - EVP_ENCODE_CTX encode; - EVP_MD_CTX md; - EVP_CIPHER_CTX cipher; -} PEM_ENCODE_SEAL_CTX; - -/* enc_type is one off */ -# define PEM_TYPE_ENCRYPTED 10 -# define PEM_TYPE_MIC_ONLY 20 -# define PEM_TYPE_MIC_CLEAR 30 -# define PEM_TYPE_CLEAR 40 - -typedef struct pem_recip_st { - char *name; - X509_NAME *dn; - int cipher; - int key_enc; - /* char iv[8]; unused and wrong size */ -} PEM_USER; - -typedef struct pem_ctx_st { - int type; /* what type of object */ - struct { - int version; - int mode; - } proc_type; - - char *domain; - - struct { - int cipher; - /*- - unused, and wrong size - unsigned char iv[8]; */ - } DEK_info; - - PEM_USER *originator; - - int num_recipient; - PEM_USER **recipient; -/*- - XXX(ben): don#t think this is used! - STACK *x509_chain; / * certificate chain */ - EVP_MD *md; /* signature type */ - - int md_enc; /* is the md encrypted or not? */ - int md_len; /* length of md_data */ - char *md_data; /* message digest, could be pkey encrypted */ - - EVP_CIPHER *dec; /* date encryption cipher */ - int key_len; /* key length */ - unsigned char *key; /* key */ - /*- - unused, and wrong size - unsigned char iv[8]; */ - - int data_enc; /* is the data encrypted */ - int data_len; - unsigned char *data; -} PEM_CTX; - -/* - * These macros make the PEM_read/PEM_write functions easier to maintain and - * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or - * IMPLEMENT_PEM_rw_cb(...) - */ - -# ifdef OPENSSL_NO_FP_API - -# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ -# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ -# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ -# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ -# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ -# else - -# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ -type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ -{ \ -return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ -} - -# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ -int PEM_write_##name(FILE *fp, type *x) \ -{ \ -return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ -} - -# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ -int PEM_write_##name(FILE *fp, const type *x) \ -{ \ -return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ -} - -# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ -int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ - unsigned char *kstr, int klen, pem_password_cb *cb, \ - void *u) \ - { \ - return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ - } - -# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ -int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ - unsigned char *kstr, int klen, pem_password_cb *cb, \ - void *u) \ - { \ - return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ - } - -# endif - -# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ -type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ -{ \ -return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ -} - -# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ -int PEM_write_bio_##name(BIO *bp, type *x) \ -{ \ -return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ -} - -# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ -int PEM_write_bio_##name(BIO *bp, const type *x) \ -{ \ -return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ -} - -# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ -int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ - unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ - { \ - return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ - } - -# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ -int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ - unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ - { \ - return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ - } - -# define IMPLEMENT_PEM_write(name, type, str, asn1) \ - IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ - IMPLEMENT_PEM_write_fp(name, type, str, asn1) - -# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ - IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ - IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) - -# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ - IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ - IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) - -# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ - IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ - IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) - -# define IMPLEMENT_PEM_read(name, type, str, asn1) \ - IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ - IMPLEMENT_PEM_read_fp(name, type, str, asn1) - -# define IMPLEMENT_PEM_rw(name, type, str, asn1) \ - IMPLEMENT_PEM_read(name, type, str, asn1) \ - IMPLEMENT_PEM_write(name, type, str, asn1) - -# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ - IMPLEMENT_PEM_read(name, type, str, asn1) \ - IMPLEMENT_PEM_write_const(name, type, str, asn1) - -# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ - IMPLEMENT_PEM_read(name, type, str, asn1) \ - IMPLEMENT_PEM_write_cb(name, type, str, asn1) - -/* These are the same except they are for the declarations */ - -# if defined(OPENSSL_NO_FP_API) - -# define DECLARE_PEM_read_fp(name, type) /**/ -# define DECLARE_PEM_write_fp(name, type) /**/ -# define DECLARE_PEM_write_cb_fp(name, type) /**/ -# else - -# define DECLARE_PEM_read_fp(name, type) \ - type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); - -# define DECLARE_PEM_write_fp(name, type) \ - int PEM_write_##name(FILE *fp, type *x); - -# define DECLARE_PEM_write_fp_const(name, type) \ - int PEM_write_##name(FILE *fp, const type *x); - -# define DECLARE_PEM_write_cb_fp(name, type) \ - int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ - unsigned char *kstr, int klen, pem_password_cb *cb, void *u); - -# endif - -# ifndef OPENSSL_NO_BIO -# define DECLARE_PEM_read_bio(name, type) \ - type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); - -# define DECLARE_PEM_write_bio(name, type) \ - int PEM_write_bio_##name(BIO *bp, type *x); - -# define DECLARE_PEM_write_bio_const(name, type) \ - int PEM_write_bio_##name(BIO *bp, const type *x); - -# define DECLARE_PEM_write_cb_bio(name, type) \ - int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ - unsigned char *kstr, int klen, pem_password_cb *cb, void *u); - -# else - -# define DECLARE_PEM_read_bio(name, type) /**/ -# define DECLARE_PEM_write_bio(name, type) /**/ -# define DECLARE_PEM_write_bio_const(name, type) /**/ -# define DECLARE_PEM_write_cb_bio(name, type) /**/ -# endif -# define DECLARE_PEM_write(name, type) \ - DECLARE_PEM_write_bio(name, type) \ - DECLARE_PEM_write_fp(name, type) -# define DECLARE_PEM_write_const(name, type) \ - DECLARE_PEM_write_bio_const(name, type) \ - DECLARE_PEM_write_fp_const(name, type) -# define DECLARE_PEM_write_cb(name, type) \ - DECLARE_PEM_write_cb_bio(name, type) \ - DECLARE_PEM_write_cb_fp(name, type) -# define DECLARE_PEM_read(name, type) \ - DECLARE_PEM_read_bio(name, type) \ - DECLARE_PEM_read_fp(name, type) -# define DECLARE_PEM_rw(name, type) \ - DECLARE_PEM_read(name, type) \ - DECLARE_PEM_write(name, type) -# define DECLARE_PEM_rw_const(name, type) \ - DECLARE_PEM_read(name, type) \ - DECLARE_PEM_write_const(name, type) -# define DECLARE_PEM_rw_cb(name, type) \ - DECLARE_PEM_read(name, type) \ - DECLARE_PEM_write_cb(name, type) -# if 1 -/* "userdata": new with OpenSSL 0.9.4 */ -typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata); -# else -/* OpenSSL 0.9.3, 0.9.3a */ -typedef int pem_password_cb (char *buf, int size, int rwflag); -# endif - -int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); -int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, - pem_password_cb *callback, void *u); - -# ifndef OPENSSL_NO_BIO -int PEM_read_bio(BIO *bp, char **name, char **header, - unsigned char **data, long *len); -int PEM_write_bio(BIO *bp, const char *name, const char *hdr, - const unsigned char *data, long len); -int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, - const char *name, BIO *bp, pem_password_cb *cb, - void *u); -void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, - pem_password_cb *cb, void *u); -int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, - const EVP_CIPHER *enc, unsigned char *kstr, int klen, - pem_password_cb *cb, void *u); - -STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u); -int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cd, void *u); -# endif - -int PEM_read(FILE *fp, char **name, char **header, - unsigned char **data, long *len); -int PEM_write(FILE *fp, const char *name, const char *hdr, - const unsigned char *data, long len); -void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, - pem_password_cb *cb, void *u); -int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u); -STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u); - -int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, - EVP_MD *md_type, unsigned char **ek, int *ekl, - unsigned char *iv, EVP_PKEY **pubk, int npubk); -void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, - unsigned char *in, int inl); -int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, - unsigned char *out, int *outl, EVP_PKEY *priv); - -void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); -void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); -int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, - unsigned int *siglen, EVP_PKEY *pkey); - -/* The default pem_password_cb that's used internally */ -int PEM_def_callback(char *buf, int num, int rwflag, void *userdata); -void PEM_proc_type(char *buf, int type); -void PEM_dek_info(char *buf, const char *type, int len, char *str); - -# include "symhacks.h" - -DECLARE_PEM_rw(X509, X509) -DECLARE_PEM_rw(X509_AUX, X509) -DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR) -DECLARE_PEM_rw(X509_REQ, X509_REQ) -DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) -DECLARE_PEM_rw(X509_CRL, X509_CRL) -DECLARE_PEM_rw(PKCS7, PKCS7) -DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) -DECLARE_PEM_rw(PKCS8, X509_SIG) -DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) -# ifndef OPENSSL_NO_RSA -DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) -DECLARE_PEM_rw_const(RSAPublicKey, RSA) -DECLARE_PEM_rw(RSA_PUBKEY, RSA) -# endif -# ifndef OPENSSL_NO_DSA -DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) -DECLARE_PEM_rw(DSA_PUBKEY, DSA) -DECLARE_PEM_rw_const(DSAparams, DSA) -# endif -# ifndef OPENSSL_NO_EC -DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) -DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) -DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) -# endif -# ifndef OPENSSL_NO_DH -DECLARE_PEM_rw_const(DHparams, DH) -DECLARE_PEM_write_const(DHxparams, DH) -# endif -DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) -DECLARE_PEM_rw(PUBKEY, EVP_PKEY) - -int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u); -int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, - char *, int, pem_password_cb *, void *); -int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u); -int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u); -EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u); - -int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u); -int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u); -int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u); - -EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - void *u); - -int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cd, - void *u); - -EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); -int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); - -EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); -EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); -EVP_PKEY *b2i_PrivateKey_bio(BIO *in); -EVP_PKEY *b2i_PublicKey_bio(BIO *in); -int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); -int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); -# ifndef OPENSSL_NO_RC4 -EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); -int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, - pem_password_cb *cb, void *u); -# endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ - -void ERR_load_PEM_strings(void); - -/* Error codes for the PEM functions. */ - -/* Function codes. */ -# define PEM_F_B2I_DSS 127 -# define PEM_F_B2I_PVK_BIO 128 -# define PEM_F_B2I_RSA 129 -# define PEM_F_CHECK_BITLEN_DSA 130 -# define PEM_F_CHECK_BITLEN_RSA 131 -# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 -# define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 -# define PEM_F_DO_B2I 132 -# define PEM_F_DO_B2I_BIO 133 -# define PEM_F_DO_BLOB_HEADER 134 -# define PEM_F_DO_PK8PKEY 126 -# define PEM_F_DO_PK8PKEY_FP 125 -# define PEM_F_DO_PVK_BODY 135 -# define PEM_F_DO_PVK_HEADER 136 -# define PEM_F_I2B_PVK 137 -# define PEM_F_I2B_PVK_BIO 138 -# define PEM_F_LOAD_IV 101 -# define PEM_F_PEM_ASN1_READ 102 -# define PEM_F_PEM_ASN1_READ_BIO 103 -# define PEM_F_PEM_ASN1_WRITE 104 -# define PEM_F_PEM_ASN1_WRITE_BIO 105 -# define PEM_F_PEM_DEF_CALLBACK 100 -# define PEM_F_PEM_DO_HEADER 106 -# define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118 -# define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 -# define PEM_F_PEM_PK8PKEY 119 -# define PEM_F_PEM_READ 108 -# define PEM_F_PEM_READ_BIO 109 -# define PEM_F_PEM_READ_BIO_DHPARAMS 141 -# define PEM_F_PEM_READ_BIO_PARAMETERS 140 -# define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 -# define PEM_F_PEM_READ_DHPARAMS 142 -# define PEM_F_PEM_READ_PRIVATEKEY 124 -# define PEM_F_PEM_SEALFINAL 110 -# define PEM_F_PEM_SEALINIT 111 -# define PEM_F_PEM_SIGNFINAL 112 -# define PEM_F_PEM_WRITE 113 -# define PEM_F_PEM_WRITE_BIO 114 -# define PEM_F_PEM_WRITE_PRIVATEKEY 139 -# define PEM_F_PEM_X509_INFO_READ 115 -# define PEM_F_PEM_X509_INFO_READ_BIO 116 -# define PEM_F_PEM_X509_INFO_WRITE_BIO 117 - -/* Reason codes. */ -# define PEM_R_BAD_BASE64_DECODE 100 -# define PEM_R_BAD_DECRYPT 101 -# define PEM_R_BAD_END_LINE 102 -# define PEM_R_BAD_IV_CHARS 103 -# define PEM_R_BAD_MAGIC_NUMBER 116 -# define PEM_R_BAD_PASSWORD_READ 104 -# define PEM_R_BAD_VERSION_NUMBER 117 -# define PEM_R_BIO_WRITE_FAILURE 118 -# define PEM_R_CIPHER_IS_NULL 127 -# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 -# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 -# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 -# define PEM_R_HEADER_TOO_LONG 128 -# define PEM_R_INCONSISTENT_HEADER 121 -# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 -# define PEM_R_KEYBLOB_TOO_SHORT 123 -# define PEM_R_NOT_DEK_INFO 105 -# define PEM_R_NOT_ENCRYPTED 106 -# define PEM_R_NOT_PROC_TYPE 107 -# define PEM_R_NO_START_LINE 108 -# define PEM_R_PROBLEMS_GETTING_PASSWORD 109 -# define PEM_R_PUBLIC_KEY_NO_RSA 110 -# define PEM_R_PVK_DATA_TOO_SHORT 124 -# define PEM_R_PVK_TOO_SHORT 125 -# define PEM_R_READ_KEY 111 -# define PEM_R_SHORT_HEADER 112 -# define PEM_R_UNSUPPORTED_CIPHER 113 -# define PEM_R_UNSUPPORTED_ENCRYPTION 114 -# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 - -# ifdef __cplusplus -} -# endif -#endif diff --git a/Sources/COpenSSL/pem2.h b/Sources/COpenSSL/pem2.h deleted file mode 100644 index 84897d5e..00000000 --- a/Sources/COpenSSL/pem2.h +++ /dev/null @@ -1,70 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * This header only exists to break a circular dependency between pem and err - * Ben 30 Jan 1999. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef HEADER_PEM_H -void ERR_load_PEM_strings(void); -#endif - -#ifdef __cplusplus -} -#endif diff --git a/Sources/COpenSSL/pem_.c b/Sources/COpenSSL/pem_.c deleted file mode 100644 index 1d3a8f59..00000000 --- a/Sources/COpenSSL/pem_.c +++ /dev/null @@ -1,2922 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/pem/pem_all.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "bio.h" -#include "evp.h" -#include "x509.h" -#include "pkcs7.h" -#include "pem.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -#ifndef OPENSSL_NO_RSA -static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); -#endif -#ifndef OPENSSL_NO_DSA -static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); -#endif - -#ifndef OPENSSL_NO_EC -static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); -#endif - -IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) - -IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) -IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) -IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) - -IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, - PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE) -#ifndef OPENSSL_NO_RSA -/* - * We treat RSA or DSA private keys as a special case. For private keys we - * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract - * the relevant private key: this means can handle "traditional" and PKCS#8 - * formats transparently. - */ -static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) -{ - RSA *rtmp; - if (!key) - return NULL; - rtmp = EVP_PKEY_get1_RSA(key); - EVP_PKEY_free(key); - if (!rtmp) - return NULL; - if (rsa) { - RSA_free(*rsa); - *rsa = rtmp; - } - return rtmp; -} - -RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, - void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_rsa(pktmp, rsa); -} - -# ifndef OPENSSL_NO_FP_API - -RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_rsa(pktmp, rsa); -} - -# endif - -# ifdef OPENSSL_FIPS - -int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - if (FIPS_mode()) { - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_RSA(k, x); - - ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; - } else - return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey, - PEM_STRING_RSA, bp, x, enc, kstr, klen, cb, - u); -} - -# ifndef OPENSSL_NO_FP_API -int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - if (FIPS_mode()) { - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - - EVP_PKEY_set1_RSA(k, x); - - ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; - } else - return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey, - PEM_STRING_RSA, fp, x, enc, kstr, klen, cb, u); -} -# endif - -# else - -IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, - RSAPrivateKey) -# endif -IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, - RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, - PEM_STRING_PUBLIC, - RSA_PUBKEY) -#endif -#ifndef OPENSSL_NO_DSA -static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) -{ - DSA *dtmp; - if (!key) - return NULL; - dtmp = EVP_PKEY_get1_DSA(key); - EVP_PKEY_free(key); - if (!dtmp) - return NULL; - if (dsa) { - DSA_free(*dsa); - *dsa = dtmp; - } - return dtmp; -} - -DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, - void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ -} - -# ifdef OPENSSL_FIPS - -int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - if (FIPS_mode()) { - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_DSA(k, x); - - ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; - } else - return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey, - PEM_STRING_DSA, bp, x, enc, kstr, klen, cb, - u); -} - -# ifndef OPENSSL_NO_FP_API -int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - if (FIPS_mode()) { - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_DSA(k, x); - ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; - } else - return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey, - PEM_STRING_DSA, fp, x, enc, kstr, klen, cb, u); -} -# endif - -# else - -IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, - DSAPrivateKey) -# endif - IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) -# ifndef OPENSSL_NO_FP_API -DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ -} - -# endif - -IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) -#endif -#ifndef OPENSSL_NO_EC -static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) -{ - EC_KEY *dtmp; - if (!key) - return NULL; - dtmp = EVP_PKEY_get1_EC_KEY(key); - EVP_PKEY_free(key); - if (!dtmp) - return NULL; - if (eckey) { - EC_KEY_free(*eckey); - *eckey = dtmp; - } - return dtmp; -} - -EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, - void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_eckey(pktmp, key); /* will free pktmp */ -} - -IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, - ECPKParameters) -# ifdef OPENSSL_FIPS -int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - if (FIPS_mode()) { - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_EC_KEY(k, x); - - ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; - } else - return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey, - PEM_STRING_ECPRIVATEKEY, - bp, x, enc, kstr, klen, cb, u); -} - -# ifndef OPENSSL_NO_FP_API -int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - if (FIPS_mode()) { - EVP_PKEY *k; - int ret; - k = EVP_PKEY_new(); - if (!k) - return 0; - EVP_PKEY_set1_EC_KEY(k, x); - ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); - EVP_PKEY_free(k); - return ret; - } else - return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey, - PEM_STRING_ECPRIVATEKEY, - fp, x, enc, kstr, klen, cb, u); -} -# endif - -# else - IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, - ECPrivateKey) -# endif -IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) -# ifndef OPENSSL_NO_FP_API -EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, - void *u) -{ - EVP_PKEY *pktmp; - pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ -} - -# endif - -#endif - -#ifndef OPENSSL_NO_DH - -IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) - IMPLEMENT_PEM_write_const(DHxparams, DH, PEM_STRING_DHXPARAMS, DHxparams) -#endif -IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) -/* crypto/pem/pem_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "pem.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason) - -static ERR_STRING_DATA PEM_str_functs[] = { - {ERR_FUNC(PEM_F_B2I_DSS), "B2I_DSS"}, - {ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"}, - {ERR_FUNC(PEM_F_B2I_RSA), "B2I_RSA"}, - {ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"}, - {ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"}, - {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"}, - {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"}, - {ERR_FUNC(PEM_F_DO_B2I), "DO_B2I"}, - {ERR_FUNC(PEM_F_DO_B2I_BIO), "DO_B2I_BIO"}, - {ERR_FUNC(PEM_F_DO_BLOB_HEADER), "DO_BLOB_HEADER"}, - {ERR_FUNC(PEM_F_DO_PK8PKEY), "DO_PK8PKEY"}, - {ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "DO_PK8PKEY_FP"}, - {ERR_FUNC(PEM_F_DO_PVK_BODY), "DO_PVK_BODY"}, - {ERR_FUNC(PEM_F_DO_PVK_HEADER), "DO_PVK_HEADER"}, - {ERR_FUNC(PEM_F_I2B_PVK), "I2B_PVK"}, - {ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"}, - {ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"}, - {ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"}, - {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"}, - {ERR_FUNC(PEM_F_PEM_ASN1_WRITE), "PEM_ASN1_write"}, - {ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO), "PEM_ASN1_write_bio"}, - {ERR_FUNC(PEM_F_PEM_DEF_CALLBACK), "PEM_def_callback"}, - {ERR_FUNC(PEM_F_PEM_DO_HEADER), "PEM_do_header"}, - {ERR_FUNC(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY), - "PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"}, - {ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO), "PEM_get_EVP_CIPHER_INFO"}, - {ERR_FUNC(PEM_F_PEM_PK8PKEY), "PEM_PK8PKEY"}, - {ERR_FUNC(PEM_F_PEM_READ), "PEM_read"}, - {ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"}, - {ERR_FUNC(PEM_F_PEM_READ_BIO_DHPARAMS), "PEM_READ_BIO_DHPARAMS"}, - {ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"}, - {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_READ_BIO_PRIVATEKEY"}, - {ERR_FUNC(PEM_F_PEM_READ_DHPARAMS), "PEM_READ_DHPARAMS"}, - {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"}, - {ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"}, - {ERR_FUNC(PEM_F_PEM_SEALINIT), "PEM_SealInit"}, - {ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"}, - {ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"}, - {ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"}, - {ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_WRITE_PRIVATEKEY"}, - {ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"}, - {ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"}, - {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"}, - {0, NULL} -}; - -static ERR_STRING_DATA PEM_str_reasons[] = { - {ERR_REASON(PEM_R_BAD_BASE64_DECODE), "bad base64 decode"}, - {ERR_REASON(PEM_R_BAD_DECRYPT), "bad decrypt"}, - {ERR_REASON(PEM_R_BAD_END_LINE), "bad end line"}, - {ERR_REASON(PEM_R_BAD_IV_CHARS), "bad iv chars"}, - {ERR_REASON(PEM_R_BAD_MAGIC_NUMBER), "bad magic number"}, - {ERR_REASON(PEM_R_BAD_PASSWORD_READ), "bad password read"}, - {ERR_REASON(PEM_R_BAD_VERSION_NUMBER), "bad version number"}, - {ERR_REASON(PEM_R_BIO_WRITE_FAILURE), "bio write failure"}, - {ERR_REASON(PEM_R_CIPHER_IS_NULL), "cipher is null"}, - {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY), - "error converting private key"}, - {ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB), - "expecting private key blob"}, - {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB), - "expecting public key blob"}, - {ERR_REASON(PEM_R_HEADER_TOO_LONG), "header too long"}, - {ERR_REASON(PEM_R_INCONSISTENT_HEADER), "inconsistent header"}, - {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR), - "keyblob header parse error"}, - {ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT), "keyblob too short"}, - {ERR_REASON(PEM_R_NOT_DEK_INFO), "not dek info"}, - {ERR_REASON(PEM_R_NOT_ENCRYPTED), "not encrypted"}, - {ERR_REASON(PEM_R_NOT_PROC_TYPE), "not proc type"}, - {ERR_REASON(PEM_R_NO_START_LINE), "no start line"}, - {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD), - "problems getting password"}, - {ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA), "public key no rsa"}, - {ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT), "pvk data too short"}, - {ERR_REASON(PEM_R_PVK_TOO_SHORT), "pvk too short"}, - {ERR_REASON(PEM_R_READ_KEY), "read key"}, - {ERR_REASON(PEM_R_SHORT_HEADER), "short header"}, - {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, - {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"}, - {ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS), - "unsupported key components"}, - {0, NULL} -}; - -#endif - -void ERR_load_PEM_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) { - ERR_load_strings(0, PEM_str_functs); - ERR_load_strings(0, PEM_str_reasons); - } -#endif -} -/* crypto/pem/pem_info.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "buffer.h" -#include "objects.h" -// #include "evp.h" -// #include "x509.h" -// #include "pem.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif - -#ifndef OPENSSL_NO_FP_API -STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u) -{ - BIO *b; - STACK_OF(X509_INFO) *ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_X509_INFO_read_bio(b, sk, cb, u); - BIO_free(b); - return (ret); -} -#endif - -STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, - pem_password_cb *cb, void *u) -{ - X509_INFO *xi = NULL; - char *name = NULL, *header = NULL; - void *pp; - unsigned char *data = NULL; - const unsigned char *p; - long len, error = 0; - int ok = 0; - STACK_OF(X509_INFO) *ret = NULL; - unsigned int i, raw, ptype; - d2i_of_void *d2i = 0; - - if (sk == NULL) { - if ((ret = sk_X509_INFO_new_null()) == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - } else - ret = sk; - - if ((xi = X509_INFO_new()) == NULL) - goto err; - for (;;) { - raw = 0; - ptype = 0; - i = PEM_read_bio(bp, &name, &header, &data, &len); - if (i == 0) { - error = ERR_GET_REASON(ERR_peek_last_error()); - if (error == PEM_R_NO_START_LINE) { - ERR_clear_error(); - break; - } - goto err; - } - start: - if ((strcmp(name, PEM_STRING_X509) == 0) || - (strcmp(name, PEM_STRING_X509_OLD) == 0)) { - d2i = (D2I_OF(void)) d2i_X509; - if (xi->x509 != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; - } - pp = &(xi->x509); - } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) { - d2i = (D2I_OF(void)) d2i_X509_AUX; - if (xi->x509 != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; - } - pp = &(xi->x509); - } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { - d2i = (D2I_OF(void)) d2i_X509_CRL; - if (xi->crl != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; - } - pp = &(xi->crl); - } else -#ifndef OPENSSL_NO_RSA - if (strcmp(name, PEM_STRING_RSA) == 0) { - d2i = (D2I_OF(void)) d2i_RSAPrivateKey; - if (xi->x_pkey != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; - } - - xi->enc_data = NULL; - xi->enc_len = 0; - - xi->x_pkey = X509_PKEY_new(); - if (xi->x_pkey == NULL) - goto err; - ptype = EVP_PKEY_RSA; - pp = &xi->x_pkey->dec_pkey; - if ((int)strlen(header) > 10) /* assume encrypted */ - raw = 1; - } else -#endif -#ifndef OPENSSL_NO_DSA - if (strcmp(name, PEM_STRING_DSA) == 0) { - d2i = (D2I_OF(void)) d2i_DSAPrivateKey; - if (xi->x_pkey != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; - } - - xi->enc_data = NULL; - xi->enc_len = 0; - - xi->x_pkey = X509_PKEY_new(); - if (xi->x_pkey == NULL) - goto err; - ptype = EVP_PKEY_DSA; - pp = &xi->x_pkey->dec_pkey; - if ((int)strlen(header) > 10) /* assume encrypted */ - raw = 1; - } else -#endif -#ifndef OPENSSL_NO_EC - if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) { - d2i = (D2I_OF(void)) d2i_ECPrivateKey; - if (xi->x_pkey != NULL) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - if ((xi = X509_INFO_new()) == NULL) - goto err; - goto start; - } - - xi->enc_data = NULL; - xi->enc_len = 0; - - xi->x_pkey = X509_PKEY_new(); - if (xi->x_pkey == NULL) - goto err; - ptype = EVP_PKEY_EC; - pp = &xi->x_pkey->dec_pkey; - if ((int)strlen(header) > 10) /* assume encrypted */ - raw = 1; - } else -#endif - { - d2i = NULL; - pp = NULL; - } - - if (d2i != NULL) { - if (!raw) { - EVP_CIPHER_INFO cipher; - - if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) - goto err; - if (!PEM_do_header(&cipher, data, &len, cb, u)) - goto err; - p = data; - if (ptype) { - if (!d2i_PrivateKey(ptype, pp, &p, len)) { - PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB); - goto err; - } - } else if (d2i(pp, &p, len) == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB); - goto err; - } - } else { /* encrypted RSA data */ - if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher)) - goto err; - xi->enc_data = (char *)data; - xi->enc_len = (int)len; - data = NULL; - } - } else { - /* unknown */ - } - if (name != NULL) - OPENSSL_free(name); - if (header != NULL) - OPENSSL_free(header); - if (data != NULL) - OPENSSL_free(data); - name = NULL; - header = NULL; - data = NULL; - } - - /* - * if the last one hasn't been pushed yet and there is anything in it - * then add it to the stack ... - */ - if ((xi->x509 != NULL) || (xi->crl != NULL) || - (xi->x_pkey != NULL) || (xi->enc_data != NULL)) { - if (!sk_X509_INFO_push(ret, xi)) - goto err; - xi = NULL; - } - ok = 1; - err: - if (xi != NULL) - X509_INFO_free(xi); - if (!ok) { - for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) { - xi = sk_X509_INFO_value(ret, i); - X509_INFO_free(xi); - } - if (ret != sk) - sk_X509_INFO_free(ret); - ret = NULL; - } - - if (name != NULL) - OPENSSL_free(name); - if (header != NULL) - OPENSSL_free(header); - if (data != NULL) - OPENSSL_free(data); - return (ret); -} - -/* A TJH addition */ -int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - EVP_CIPHER_CTX ctx; - int i, ret = 0; - unsigned char *data = NULL; - const char *objstr = NULL; - char buf[PEM_BUFSIZE]; - unsigned char *iv = NULL; - - if (enc != NULL) { - objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); - if (objstr == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); - goto err; - } - } - - /* - * now for the fun part ... if we have a private key then we have to be - * able to handle a not-yet-decrypted key being written out correctly ... - * if it is decrypted or it is non-encrypted then we use the base code - */ - if (xi->x_pkey != NULL) { - if ((xi->enc_data != NULL) && (xi->enc_len > 0)) { - if (enc == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_CIPHER_IS_NULL); - goto err; - } - - /* copy from weirdo names into more normal things */ - iv = xi->enc_cipher.iv; - data = (unsigned char *)xi->enc_data; - i = xi->enc_len; - - /* - * we take the encryption data from the internal stuff rather - * than what the user has passed us ... as we have to match - * exactly for some strange reason - */ - objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher)); - if (objstr == NULL) { - PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, - PEM_R_UNSUPPORTED_CIPHER); - goto err; - } - - /* create the right magic header stuff */ - OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <= - sizeof(buf)); - buf[0] = '\0'; - PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); - PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); - - /* use the normal code to write things out */ - i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); - if (i <= 0) - goto err; - } else { - /* Add DSA/DH */ -#ifndef OPENSSL_NO_RSA - /* normal optionally encrypted stuff */ - if (PEM_write_bio_RSAPrivateKey(bp, - xi->x_pkey->dec_pkey->pkey.rsa, - enc, kstr, klen, cb, u) <= 0) - goto err; -#endif - } - } - - /* if we have a certificate then write it out now */ - if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0)) - goto err; - - /* - * we are ignoring anything else that is loaded into the X509_INFO - * structure for the moment ... as I don't need it so I'm not coding it - * here and Eric can do it when this makes it into the base library --tjh - */ - - ret = 1; - - err: - OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); - OPENSSL_cleanse(buf, PEM_BUFSIZE); - return (ret); -} -/* crypto/pem/pem_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "objects.h" -// #include "evp.h" -#include "rand.h" -// #include "x509.h" -// #include "pem.h" -#include "pkcs12.h" -#include "asn1_locl.h" -#ifndef OPENSSL_NO_DES -# include "des.h" -#endif -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -const char PEM_version[] = "PEM" OPENSSL_VERSION_PTEXT; - -#define MIN_LENGTH 4 - -static int load_iv(char **fromp, unsigned char *to, int num); -static int check_pem(const char *nm, const char *name); -int pem_check_suffix(const char *pem_str, const char *suffix); - -int PEM_def_callback(char *buf, int num, int rwflag, void *userdata) -{ - int i, min_len; - const char *prompt; - - /* We assume that the user passes a default password as userdata */ - if (userdata) { - i = strlen(userdata); - i = (i > num) ? num : i; - memcpy(buf, userdata, i); - return i; - } - - prompt = EVP_get_pw_prompt(); - if (prompt == NULL) - prompt = "Enter PEM pass phrase:"; - - /* - * rwflag == 0 means decryption - * rwflag == 1 means encryption - * - * We assume that for encryption, we want a minimum length, while for - * decryption, we cannot know any minimum length, so we assume zero. - */ - min_len = rwflag ? MIN_LENGTH : 0; - - i = EVP_read_pw_string_min(buf, min_len, num, prompt, rwflag); - if (i != 0) { - PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD); - memset(buf, 0, (unsigned int)num); - return -1; - } - return strlen(buf); -} - -void PEM_proc_type(char *buf, int type) -{ - const char *str; - - if (type == PEM_TYPE_ENCRYPTED) - str = "ENCRYPTED"; - else if (type == PEM_TYPE_MIC_CLEAR) - str = "MIC-CLEAR"; - else if (type == PEM_TYPE_MIC_ONLY) - str = "MIC-ONLY"; - else - str = "BAD-TYPE"; - - BUF_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE); - BUF_strlcat(buf, str, PEM_BUFSIZE); - BUF_strlcat(buf, "\n", PEM_BUFSIZE); -} - -void PEM_dek_info(char *buf, const char *type, int len, char *str) -{ - static const unsigned char map[17] = "0123456789ABCDEF"; - long i; - int j; - - BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); - BUF_strlcat(buf, type, PEM_BUFSIZE); - BUF_strlcat(buf, ",", PEM_BUFSIZE); - j = strlen(buf); - if (j + (len * 2) + 1 > PEM_BUFSIZE) - return; - for (i = 0; i < len; i++) { - buf[j + i * 2] = map[(str[i] >> 4) & 0x0f]; - buf[j + i * 2 + 1] = map[(str[i]) & 0x0f]; - } - buf[j + i * 2] = '\n'; - buf[j + i * 2 + 1] = '\0'; -} - -#ifndef OPENSSL_NO_FP_API -void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, - pem_password_cb *cb, void *u) -{ - BIO *b; - void *ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u); - BIO_free(b); - return (ret); -} -#endif - -static int check_pem(const char *nm, const char *name) -{ - /* Normal matching nm and name */ - if (!strcmp(nm, name)) - return 1; - - /* Make PEM_STRING_EVP_PKEY match any private key */ - - if (!strcmp(name, PEM_STRING_EVP_PKEY)) { - int slen; - const EVP_PKEY_ASN1_METHOD *ameth; - if (!strcmp(nm, PEM_STRING_PKCS8)) - return 1; - if (!strcmp(nm, PEM_STRING_PKCS8INF)) - return 1; - slen = pem_check_suffix(nm, "PRIVATE KEY"); - if (slen > 0) { - /* - * NB: ENGINE implementations wont contain a deprecated old - * private key decode function so don't look for them. - */ - ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); - if (ameth && ameth->old_priv_decode) - return 1; - } - return 0; - } - - if (!strcmp(name, PEM_STRING_PARAMETERS)) { - int slen; - const EVP_PKEY_ASN1_METHOD *ameth; - slen = pem_check_suffix(nm, "PARAMETERS"); - if (slen > 0) { - ENGINE *e; - ameth = EVP_PKEY_asn1_find_str(&e, nm, slen); - if (ameth) { - int r; - if (ameth->param_decode) - r = 1; - else - r = 0; -#ifndef OPENSSL_NO_ENGINE - if (e) - ENGINE_finish(e); -#endif - return r; - } - } - return 0; - } - /* If reading DH parameters handle X9.42 DH format too */ - if (!strcmp(nm, PEM_STRING_DHXPARAMS) && - !strcmp(name, PEM_STRING_DHPARAMS)) - return 1; - - /* Permit older strings */ - - if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509)) - return 1; - - if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) && - !strcmp(name, PEM_STRING_X509_REQ)) - return 1; - - /* Allow normal certs to be read as trusted certs */ - if (!strcmp(nm, PEM_STRING_X509) && - !strcmp(name, PEM_STRING_X509_TRUSTED)) - return 1; - - if (!strcmp(nm, PEM_STRING_X509_OLD) && - !strcmp(name, PEM_STRING_X509_TRUSTED)) - return 1; - - /* Some CAs use PKCS#7 with CERTIFICATE headers */ - if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7)) - return 1; - - if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && - !strcmp(name, PEM_STRING_PKCS7)) - return 1; - -#ifndef OPENSSL_NO_CMS - if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS)) - return 1; - /* Allow CMS to be read from PKCS#7 headers */ - if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS)) - return 1; -#endif - - return 0; -} - -int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, - const char *name, BIO *bp, pem_password_cb *cb, - void *u) -{ - EVP_CIPHER_INFO cipher; - char *nm = NULL, *header = NULL; - unsigned char *data = NULL; - long len; - int ret = 0; - - for (;;) { - if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { - if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) - ERR_add_error_data(2, "Expecting: ", name); - return 0; - } - if (check_pem(nm, name)) - break; - OPENSSL_free(nm); - OPENSSL_free(header); - OPENSSL_free(data); - } - if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) - goto err; - if (!PEM_do_header(&cipher, data, &len, cb, u)) - goto err; - - *pdata = data; - *plen = len; - - if (pnm) - *pnm = nm; - - ret = 1; - - err: - if (!ret || !pnm) - OPENSSL_free(nm); - OPENSSL_free(header); - if (!ret) - OPENSSL_free(data); - return ret; -} - -#ifndef OPENSSL_NO_FP_API -int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u); - BIO_free(b); - return (ret); -} -#endif - -int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, - void *x, const EVP_CIPHER *enc, unsigned char *kstr, - int klen, pem_password_cb *callback, void *u) -{ - EVP_CIPHER_CTX ctx; - int dsize = 0, i, j, ret = 0; - unsigned char *p, *data = NULL; - const char *objstr = NULL; - char buf[PEM_BUFSIZE]; - unsigned char key[EVP_MAX_KEY_LENGTH]; - unsigned char iv[EVP_MAX_IV_LENGTH]; - - if (enc != NULL) { - objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); - if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) { - PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); - goto err; - } - } - - if ((dsize = i2d(x, NULL)) < 0) { - PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB); - dsize = 0; - goto err; - } - /* dzise + 8 bytes are needed */ - /* actually it needs the cipher block size extra... */ - data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20); - if (data == NULL) { - PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - p = data; - i = i2d(x, &p); - - if (enc != NULL) { - if (kstr == NULL) { - if (callback == NULL) - klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); - else - klen = (*callback) (buf, PEM_BUFSIZE, 1, u); - if (klen <= 0) { - PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY); - goto err; - } -#ifdef CHARSET_EBCDIC - /* Convert the pass phrase from EBCDIC */ - ebcdic2ascii(buf, buf, klen); -#endif - kstr = (unsigned char *)buf; - } - RAND_add(data, i, 0); /* put in the RSA key. */ - OPENSSL_assert(enc->iv_len <= (int)sizeof(iv)); - if (RAND_bytes(iv, enc->iv_len) <= 0) /* Generate a salt */ - goto err; - /* - * The 'iv' is used as the iv and as a salt. It is NOT taken from - * the BytesToKey function - */ - if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) - goto err; - - if (kstr == (unsigned char *)buf) - OPENSSL_cleanse(buf, PEM_BUFSIZE); - - OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <= - sizeof(buf)); - - buf[0] = '\0'; - PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); - PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); - /* k=strlen(buf); */ - - EVP_CIPHER_CTX_init(&ctx); - ret = 1; - if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) - || !EVP_EncryptUpdate(&ctx, data, &j, data, i) - || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i)) - ret = 0; - EVP_CIPHER_CTX_cleanup(&ctx); - if (ret == 0) - goto err; - i += j; - } else { - ret = 1; - buf[0] = '\0'; - } - i = PEM_write_bio(bp, name, buf, data, i); - if (i <= 0) - ret = 0; - err: - OPENSSL_cleanse(key, sizeof(key)); - OPENSSL_cleanse(iv, sizeof(iv)); - OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); - OPENSSL_cleanse(buf, PEM_BUFSIZE); - if (data != NULL) { - OPENSSL_cleanse(data, (unsigned int)dsize); - OPENSSL_free(data); - } - return (ret); -} - -int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, - pem_password_cb *callback, void *u) -{ - int i = 0, j, o, klen; - long len; - EVP_CIPHER_CTX ctx; - unsigned char key[EVP_MAX_KEY_LENGTH]; - char buf[PEM_BUFSIZE]; - - len = *plen; - - if (cipher->cipher == NULL) - return (1); - if (callback == NULL) - klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u); - else - klen = callback(buf, PEM_BUFSIZE, 0, u); - if (klen < 0) { - PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ); - return (0); - } -#ifdef CHARSET_EBCDIC - /* Convert the pass phrase from EBCDIC */ - ebcdic2ascii(buf, buf, klen); -#endif - - if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]), - (unsigned char *)buf, klen, 1, key, NULL)) - return 0; - - j = (int)len; - EVP_CIPHER_CTX_init(&ctx); - o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0])); - if (o) - o = EVP_DecryptUpdate(&ctx, data, &i, data, j); - if (o) - o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j); - EVP_CIPHER_CTX_cleanup(&ctx); - OPENSSL_cleanse((char *)buf, sizeof(buf)); - OPENSSL_cleanse((char *)key, sizeof(key)); - if (o) - j += i; - else { - PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT); - return (0); - } - *plen = j; - return (1); -} - -int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) -{ - const EVP_CIPHER *enc = NULL; - char *p, c; - char **header_pp = &header; - - cipher->cipher = NULL; - memset(cipher->iv, 0, sizeof(cipher->iv)); - if ((header == NULL) || (*header == '\0') || (*header == '\n')) - return (1); - if (strncmp(header, "Proc-Type: ", 11) != 0) { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE); - return (0); - } - header += 11; - if (*header != '4') - return (0); - header++; - if (*header != ',') - return (0); - header++; - if (strncmp(header, "ENCRYPTED", 9) != 0) { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED); - return (0); - } - for (; (*header != '\n') && (*header != '\0'); header++) ; - if (*header == '\0') { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER); - return (0); - } - header++; - if (strncmp(header, "DEK-Info: ", 10) != 0) { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO); - return (0); - } - header += 10; - - p = header; - for (;;) { - c = *header; -#ifndef CHARSET_EBCDIC - if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || - ((c >= '0') && (c <= '9')))) - break; -#else - if (!(isupper((unsigned char)c) || (c == '-') - || isdigit((unsigned char)c))) - break; -#endif - header++; - } - *header = '\0'; - cipher->cipher = enc = EVP_get_cipherbyname(p); - *header = c; - header++; - - if (enc == NULL) { - PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION); - return (0); - } - if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len)) - return (0); - - return (1); -} - -static int load_iv(char **fromp, unsigned char *to, int num) -{ - int v, i; - char *from; - - from = *fromp; - for (i = 0; i < num; i++) - to[i] = 0; - num *= 2; - for (i = 0; i < num; i++) { - if ((*from >= '0') && (*from <= '9')) - v = *from - '0'; - else if ((*from >= 'A') && (*from <= 'F')) - v = *from - 'A' + 10; - else if ((*from >= 'a') && (*from <= 'f')) - v = *from - 'a' + 10; - else { - PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS); - return (0); - } - from++; - to[i / 2] |= v << (long)((!(i & 1)) * 4); - } - - *fromp = from; - return (1); -} - -#ifndef OPENSSL_NO_FP_API -int PEM_write(FILE *fp, const char *name, const char *header, - const unsigned char *data, long len) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_write_bio(b, name, header, data, len); - BIO_free(b); - return (ret); -} -#endif - -int PEM_write_bio(BIO *bp, const char *name, const char *header, - const unsigned char *data, long len) -{ - int nlen, n, i, j, outl; - unsigned char *buf = NULL; - EVP_ENCODE_CTX ctx; - int reason = ERR_R_BUF_LIB; - - EVP_EncodeInit(&ctx); - nlen = strlen(name); - - if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || - (BIO_write(bp, name, nlen) != nlen) || - (BIO_write(bp, "-----\n", 6) != 6)) - goto err; - - i = strlen(header); - if (i > 0) { - if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) - goto err; - } - - buf = OPENSSL_malloc(PEM_BUFSIZE * 8); - if (buf == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - - i = j = 0; - while (len > 0) { - n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); - EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n); - if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) - goto err; - i += outl; - len -= n; - j += n; - } - EVP_EncodeFinal(&ctx, buf, &outl); - if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) - goto err; - OPENSSL_cleanse(buf, PEM_BUFSIZE * 8); - OPENSSL_free(buf); - buf = NULL; - if ((BIO_write(bp, "-----END ", 9) != 9) || - (BIO_write(bp, name, nlen) != nlen) || - (BIO_write(bp, "-----\n", 6) != 6)) - goto err; - return (i + outl); - err: - if (buf) { - OPENSSL_cleanse(buf, PEM_BUFSIZE * 8); - OPENSSL_free(buf); - } - PEMerr(PEM_F_PEM_WRITE_BIO, reason); - return (0); -} - -#ifndef OPENSSL_NO_FP_API -int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, - long *len) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_read_bio(b, name, header, data, len); - BIO_free(b); - return (ret); -} -#endif - -int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, - long *len) -{ - EVP_ENCODE_CTX ctx; - int end = 0, i, k, bl = 0, hl = 0, nohead = 0; - char buf[256]; - BUF_MEM *nameB; - BUF_MEM *headerB; - BUF_MEM *dataB, *tmpB; - - nameB = BUF_MEM_new(); - headerB = BUF_MEM_new(); - dataB = BUF_MEM_new(); - if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { - BUF_MEM_free(nameB); - BUF_MEM_free(headerB); - BUF_MEM_free(dataB); - PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); - return (0); - } - - buf[254] = '\0'; - for (;;) { - i = BIO_gets(bp, buf, 254); - - if (i <= 0) { - PEMerr(PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE); - goto err; - } - - while ((i >= 0) && (buf[i] <= ' ')) - i--; - buf[++i] = '\n'; - buf[++i] = '\0'; - - if (strncmp(buf, "-----BEGIN ", 11) == 0) { - i = strlen(&(buf[11])); - - if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0) - continue; - if (!BUF_MEM_grow(nameB, i + 9)) { - PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - memcpy(nameB->data, &(buf[11]), i - 6); - nameB->data[i - 6] = '\0'; - break; - } - } - hl = 0; - if (!BUF_MEM_grow(headerB, 256)) { - PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - headerB->data[0] = '\0'; - for (;;) { - i = BIO_gets(bp, buf, 254); - if (i <= 0) - break; - - while ((i >= 0) && (buf[i] <= ' ')) - i--; - buf[++i] = '\n'; - buf[++i] = '\0'; - - if (buf[0] == '\n') - break; - if (!BUF_MEM_grow(headerB, hl + i + 9)) { - PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - if (strncmp(buf, "-----END ", 9) == 0) { - nohead = 1; - break; - } - memcpy(&(headerB->data[hl]), buf, i); - headerB->data[hl + i] = '\0'; - hl += i; - } - - bl = 0; - if (!BUF_MEM_grow(dataB, 1024)) { - PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - dataB->data[0] = '\0'; - if (!nohead) { - for (;;) { - i = BIO_gets(bp, buf, 254); - if (i <= 0) - break; - - while ((i >= 0) && (buf[i] <= ' ')) - i--; - buf[++i] = '\n'; - buf[++i] = '\0'; - - if (i != 65) - end = 1; - if (strncmp(buf, "-----END ", 9) == 0) - break; - if (i > 65) - break; - if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { - PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - memcpy(&(dataB->data[bl]), buf, i); - dataB->data[bl + i] = '\0'; - bl += i; - if (end) { - buf[0] = '\0'; - i = BIO_gets(bp, buf, 254); - if (i <= 0) - break; - - while ((i >= 0) && (buf[i] <= ' ')) - i--; - buf[++i] = '\n'; - buf[++i] = '\0'; - - break; - } - } - } else { - tmpB = headerB; - headerB = dataB; - dataB = tmpB; - bl = hl; - } - i = strlen(nameB->data); - if ((strncmp(buf, "-----END ", 9) != 0) || - (strncmp(nameB->data, &(buf[9]), i) != 0) || - (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) { - PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE); - goto err; - } - - EVP_DecodeInit(&ctx); - i = EVP_DecodeUpdate(&ctx, - (unsigned char *)dataB->data, &bl, - (unsigned char *)dataB->data, bl); - if (i < 0) { - PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE); - goto err; - } - i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); - if (i < 0) { - PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE); - goto err; - } - bl += k; - - if (bl == 0) - goto err; - *name = nameB->data; - *header = headerB->data; - *data = (unsigned char *)dataB->data; - *len = bl; - OPENSSL_free(nameB); - OPENSSL_free(headerB); - OPENSSL_free(dataB); - return (1); - err: - BUF_MEM_free(nameB); - BUF_MEM_free(headerB); - BUF_MEM_free(dataB); - return (0); -} - -/* - * Check pem string and return prefix length. If for example the pem_str == - * "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" the return value is 3 for the - * string "RSA". - */ - -int pem_check_suffix(const char *pem_str, const char *suffix) -{ - int pem_len = strlen(pem_str); - int suffix_len = strlen(suffix); - const char *p; - if (suffix_len + 1 >= pem_len) - return 0; - p = pem_str + pem_len - suffix_len; - if (strcmp(p, suffix)) - return 0; - p--; - if (*p != ' ') - return 0; - return p - pem_str; -} -/* crypto/pem/pem_oth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "objects.h" -// #include "evp.h" -// #include "rand.h" -// #include "x509.h" -// #include "pem.h" - -/* Handle 'other' PEMs: not private keys */ - -void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, - pem_password_cb *cb, void *u) -{ - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - char *ret = NULL; - - if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) - return NULL; - p = data; - ret = d2i(x, &p, len); - if (ret == NULL) - PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB); - OPENSSL_free(data); - return (ret); -} -/* crypto/pem/pem_pkey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "objects.h" -// #include "evp.h" -// #include "rand.h" -// #include "x509.h" -// #include "pkcs12.h" -// #include "pem.h" - -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, - int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); -static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, - int nid, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u); - -/* - * These functions write a private key in PKCS#8 format: it is a "drop in" - * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' - * is NULL then it uses the unencrypted private key form. The 'nid' versions - * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. - */ - -int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); -} - -int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); -} - -int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); -} - -int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); -} - -static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, - const EVP_CIPHER *enc, char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - X509_SIG *p8; - PKCS8_PRIV_KEY_INFO *p8inf; - char buf[PEM_BUFSIZE]; - int ret; - if (!(p8inf = EVP_PKEY2PKCS8(x))) { - PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); - return 0; - } - if (enc || (nid != -1)) { - if (!kstr) { - if (!cb) - klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); - else - klen = cb(buf, PEM_BUFSIZE, 1, u); - if (klen <= 0) { - PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return 0; - } - - kstr = buf; - } - p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); - if (kstr == buf) - OPENSSL_cleanse(buf, klen); - PKCS8_PRIV_KEY_INFO_free(p8inf); - if (p8 == NULL) - return 0; - if (isder) - ret = i2d_PKCS8_bio(bp, p8); - else - ret = PEM_write_bio_PKCS8(bp, p8); - X509_SIG_free(p8); - return ret; - } else { - if (isder) - ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); - else - ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; - } -} - -EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u) -{ - PKCS8_PRIV_KEY_INFO *p8inf = NULL; - X509_SIG *p8 = NULL; - int klen; - EVP_PKEY *ret; - char psbuf[PEM_BUFSIZE]; - p8 = d2i_PKCS8_bio(bp, NULL); - if (!p8) - return NULL; - if (cb) - klen = cb(psbuf, PEM_BUFSIZE, 0, u); - else - klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); - if (klen < 0) { - PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); - X509_SIG_free(p8); - return NULL; - } - p8inf = PKCS8_decrypt(p8, psbuf, klen); - X509_SIG_free(p8); - OPENSSL_cleanse(psbuf, klen); - if (!p8inf) - return NULL; - ret = EVP_PKCS82PKEY(p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - if (!ret) - return NULL; - if (x) { - if (*x) - EVP_PKEY_free(*x); - *x = ret; - } - return ret; -} - -#ifndef OPENSSL_NO_FP_API - -int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); -} - -int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); -} - -int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, - char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); -} - -int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - char *kstr, int klen, pem_password_cb *cb, - void *u) -{ - return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); -} - -static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, - const EVP_CIPHER *enc, char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - BIO *bp; - int ret; - if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { - PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB); - return (0); - } - ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); - BIO_free(bp); - return ret; -} - -EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - void *u) -{ - BIO *bp; - EVP_PKEY *ret; - if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { - PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP, ERR_R_BUF_LIB); - return NULL; - } - ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); - BIO_free(bp); - return ret; -} - -#endif - -IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) - - -IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, - PKCS8_PRIV_KEY_INFO) -/* crypto/pem/pem_pkey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "objects.h" -// #include "evp.h" -// #include "rand.h" -// #include "x509.h" -// #include "pkcs12.h" -// #include "pem.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -// #include "asn1_locl.h" - -int pem_check_suffix(const char *pem_str, const char *suffix); - -EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, - void *u) -{ - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - int slen; - EVP_PKEY *ret = NULL; - - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) - return NULL; - p = data; - - if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); - if (!p8inf) - goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - if (*x) - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { - PKCS8_PRIV_KEY_INFO *p8inf; - X509_SIG *p8; - int klen; - char psbuf[PEM_BUFSIZE]; - p8 = d2i_X509_SIG(NULL, &p, len); - if (!p8) - goto p8err; - if (cb) - klen = cb(psbuf, PEM_BUFSIZE, 0, u); - else - klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); - if (klen < 0) { - PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); - X509_SIG_free(p8); - goto err; - } - p8inf = PKCS8_decrypt(p8, psbuf, klen); - X509_SIG_free(p8); - OPENSSL_cleanse(psbuf, klen); - if (!p8inf) - goto p8err; - ret = EVP_PKCS82PKEY(p8inf); - if (x) { - if (*x) - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - PKCS8_PRIV_KEY_INFO_free(p8inf); - } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { - const EVP_PKEY_ASN1_METHOD *ameth; - ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); - if (!ameth || !ameth->old_priv_decode) - goto p8err; - ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); - } - p8err: - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); - err: - OPENSSL_free(nm); - OPENSSL_cleanse(data, len); - OPENSSL_free(data); - return (ret); -} - -int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - char pem_str[80]; - if (!x->ameth || x->ameth->priv_encode) - return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, - (char *)kstr, klen, cb, u); - - BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); - return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, - pem_str, bp, x, enc, kstr, klen, cb, u); -} - -EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) -{ - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - int slen; - EVP_PKEY *ret = NULL; - - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, - bp, 0, NULL)) - return NULL; - p = data; - - if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) { - ret = EVP_PKEY_new(); - if (!ret) - goto err; - if (!EVP_PKEY_set_type_str(ret, nm, slen) - || !ret->ameth->param_decode - || !ret->ameth->param_decode(ret, &p, len)) { - EVP_PKEY_free(ret); - ret = NULL; - goto err; - } - if (x) { - if (*x) - EVP_PKEY_free((EVP_PKEY *)*x); - *x = ret; - } - } - err: - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); - return (ret); -} - -int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) -{ - char pem_str[80]; - if (!x->ameth || !x->ameth->param_encode) - return 0; - - BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); - return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, - pem_str, bp, x, NULL, NULL, 0, 0, NULL); -} - -#ifndef OPENSSL_NO_FP_API -EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, - void *u) -{ - BIO *b; - EVP_PKEY *ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_read_bio_PrivateKey(b, x, cb, u); - BIO_free(b); - return (ret); -} - -int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, - unsigned char *kstr, int klen, - pem_password_cb *cb, void *u) -{ - BIO *b; - int ret; - - if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { - PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY, ERR_R_BUF_LIB); - return 0; - } - ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); - BIO_free(b); - return ret; -} - -#endif - -#ifndef OPENSSL_NO_DH - -/* Transparently read in PKCS#3 or X9.42 DH parameters */ - -DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) -{ - char *nm = NULL; - const unsigned char *p = NULL; - unsigned char *data = NULL; - long len; - DH *ret = NULL; - - if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_DHPARAMS, bp, cb, u)) - return NULL; - p = data; - - if (!strcmp(nm, PEM_STRING_DHXPARAMS)) - ret = d2i_DHxparams(x, &p, len); - else - ret = d2i_DHparams(x, &p, len); - - if (ret == NULL) - PEMerr(PEM_F_PEM_READ_BIO_DHPARAMS, ERR_R_ASN1_LIB); - OPENSSL_free(nm); - OPENSSL_free(data); - return ret; -} - -# ifndef OPENSSL_NO_FP_API -DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u) -{ - BIO *b; - DH *ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - PEMerr(PEM_F_PEM_READ_DHPARAMS, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = PEM_read_bio_DHparams(b, x, cb, u); - BIO_free(b); - return (ret); -} -# endif - -#endif -/* crypto/pem/pem_seal.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "opensslconf.h" /* for OPENSSL_NO_RSA */ -#ifndef OPENSSL_NO_RSA -# include -# include "cryptlib.h" -# include "evp.h" -# include "rand.h" -# include "objects.h" -# include "x509.h" -# include "pem.h" -# include "rsa.h" - -int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type, - unsigned char **ek, int *ekl, unsigned char *iv, - EVP_PKEY **pubk, int npubk) -{ - unsigned char key[EVP_MAX_KEY_LENGTH]; - int ret = -1; - int i, j, max = 0; - char *s = NULL; - - for (i = 0; i < npubk; i++) { - if (pubk[i]->type != EVP_PKEY_RSA) { - PEMerr(PEM_F_PEM_SEALINIT, PEM_R_PUBLIC_KEY_NO_RSA); - goto err; - } - j = RSA_size(pubk[i]->pkey.rsa); - if (j > max) - max = j; - } - s = (char *)OPENSSL_malloc(max * 2); - if (s == NULL) { - PEMerr(PEM_F_PEM_SEALINIT, ERR_R_MALLOC_FAILURE); - goto err; - } - - EVP_EncodeInit(&ctx->encode); - - EVP_MD_CTX_init(&ctx->md); - if (!EVP_SignInit(&ctx->md, md_type)) - goto err; - - EVP_CIPHER_CTX_init(&ctx->cipher); - ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk); - if (ret <= 0) - goto err; - - /* base64 encode the keys */ - for (i = 0; i < npubk; i++) { - j = EVP_EncodeBlock((unsigned char *)s, ek[i], - RSA_size(pubk[i]->pkey.rsa)); - ekl[i] = j; - memcpy(ek[i], s, j + 1); - } - - ret = npubk; - err: - if (s != NULL) - OPENSSL_free(s); - OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); - return (ret); -} - -void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, - unsigned char *in, int inl) -{ - unsigned char buffer[1600]; - int i, j; - - *outl = 0; - EVP_SignUpdate(&ctx->md, in, inl); - for (;;) { - if (inl <= 0) - break; - if (inl > 1200) - i = 1200; - else - i = inl; - EVP_EncryptUpdate(&ctx->cipher, buffer, &j, in, i); - EVP_EncodeUpdate(&ctx->encode, out, &j, buffer, j); - *outl += j; - out += j; - in += i; - inl -= i; - } -} - -int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, - unsigned char *out, int *outl, EVP_PKEY *priv) -{ - unsigned char *s = NULL; - int ret = 0, j; - unsigned int i; - - if (priv->type != EVP_PKEY_RSA) { - PEMerr(PEM_F_PEM_SEALFINAL, PEM_R_PUBLIC_KEY_NO_RSA); - goto err; - } - i = RSA_size(priv->pkey.rsa); - if (i < 100) - i = 100; - s = (unsigned char *)OPENSSL_malloc(i * 2); - if (s == NULL) { - PEMerr(PEM_F_PEM_SEALFINAL, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_EncryptFinal_ex(&ctx->cipher, s, (int *)&i)) - goto err; - EVP_EncodeUpdate(&ctx->encode, out, &j, s, i); - *outl = j; - out += j; - EVP_EncodeFinal(&ctx->encode, out, &j); - *outl += j; - - if (!EVP_SignFinal(&ctx->md, s, &i, priv)) - goto err; - *sigl = EVP_EncodeBlock(sig, s, i); - - ret = 1; - err: - EVP_MD_CTX_cleanup(&ctx->md); - EVP_CIPHER_CTX_cleanup(&ctx->cipher); - if (s != NULL) - OPENSSL_free(s); - return (ret); -} -#else /* !OPENSSL_NO_RSA */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif -/* crypto/pem/pem_sign.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "rand.h" -// #include "evp.h" -// #include "objects.h" -// #include "x509.h" -// #include "pem.h" - -void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) -{ - EVP_DigestInit_ex(ctx, type, NULL); -} - -void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) -{ - EVP_DigestUpdate(ctx, data, count); -} - -int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, - unsigned int *siglen, EVP_PKEY *pkey) -{ - unsigned char *m; - int i, ret = 0; - unsigned int m_len; - - m = (unsigned char *)OPENSSL_malloc(EVP_PKEY_size(pkey) + 2); - if (m == NULL) { - PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0) - goto err; - - i = EVP_EncodeBlock(sigret, m, m_len); - *siglen = i; - ret = 1; - err: - /* ctx has been zeroed by EVP_SignFinal() */ - if (m != NULL) - OPENSSL_free(m); - return (ret); -} -/* pem_x509.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bio.h" -// #include "evp.h" -// #include "x509.h" -// #include "pkcs7.h" -// #include "pem.h" - -IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) -/* pem_xaux.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bio.h" -// #include "evp.h" -// #include "x509.h" -// #include "pkcs7.h" -// #include "pem.h" - -IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX) -IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR, - X509_CERT_PAIR) diff --git a/Sources/COpenSSL/pk12err.c b/Sources/COpenSSL/pk12err.c deleted file mode 100644 index 1b8e8cb9..00000000 --- a/Sources/COpenSSL/pk12err.c +++ /dev/null @@ -1,149 +0,0 @@ -/* crypto/pkcs12/pk12err.c */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "pkcs12.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason) - -static ERR_STRING_DATA PKCS12_str_functs[] = { - {ERR_FUNC(PKCS12_F_PARSE_BAG), "PARSE_BAG"}, - {ERR_FUNC(PKCS12_F_PARSE_BAGS), "PARSE_BAGS"}, - {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME), "PKCS12_ADD_FRIENDLYNAME"}, - {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC), - "PKCS12_add_friendlyname_asc"}, - {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI), - "PKCS12_add_friendlyname_uni"}, - {ERR_FUNC(PKCS12_F_PKCS12_ADD_LOCALKEYID), "PKCS12_add_localkeyid"}, - {ERR_FUNC(PKCS12_F_PKCS12_CREATE), "PKCS12_create"}, - {ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC), "PKCS12_gen_mac"}, - {ERR_FUNC(PKCS12_F_PKCS12_INIT), "PKCS12_init"}, - {ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I), "PKCS12_item_decrypt_d2i"}, - {ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT), "PKCS12_item_i2d_encrypt"}, - {ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG), "PKCS12_item_pack_safebag"}, - {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC), "PKCS12_key_gen_asc"}, - {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI), "PKCS12_key_gen_uni"}, - {ERR_FUNC(PKCS12_F_PKCS12_MAKE_KEYBAG), "PKCS12_MAKE_KEYBAG"}, - {ERR_FUNC(PKCS12_F_PKCS12_MAKE_SHKEYBAG), "PKCS12_MAKE_SHKEYBAG"}, - {ERR_FUNC(PKCS12_F_PKCS12_NEWPASS), "PKCS12_newpass"}, - {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA), "PKCS12_pack_p7data"}, - {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA), "PKCS12_pack_p7encdata"}, - {ERR_FUNC(PKCS12_F_PKCS12_PARSE), "PKCS12_parse"}, - {ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT), "PKCS12_pbe_crypt"}, - {ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN), "PKCS12_PBE_keyivgen"}, - {ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC), "PKCS12_setup_mac"}, - {ERR_FUNC(PKCS12_F_PKCS12_SET_MAC), "PKCS12_set_mac"}, - {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES), "PKCS12_unpack_authsafes"}, - {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA), "PKCS12_unpack_p7data"}, - {ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"}, - {ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"}, - {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"}, - {0, NULL} -}; - -static ERR_STRING_DATA PKCS12_str_reasons[] = { - {ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"}, - {ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"}, - {ERR_REASON(PKCS12_R_DECODE_ERROR), "decode error"}, - {ERR_REASON(PKCS12_R_ENCODE_ERROR), "encode error"}, - {ERR_REASON(PKCS12_R_ENCRYPT_ERROR), "encrypt error"}, - {ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE), - "error setting encrypted data type"}, - {ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, - {ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER), - "invalid null pkcs12 pointer"}, - {ERR_REASON(PKCS12_R_IV_GEN_ERROR), "iv gen error"}, - {ERR_REASON(PKCS12_R_KEY_GEN_ERROR), "key gen error"}, - {ERR_REASON(PKCS12_R_MAC_ABSENT), "mac absent"}, - {ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR), "mac generation error"}, - {ERR_REASON(PKCS12_R_MAC_SETUP_ERROR), "mac setup error"}, - {ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR), "mac string set error"}, - {ERR_REASON(PKCS12_R_MAC_VERIFY_ERROR), "mac verify error"}, - {ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE), "mac verify failure"}, - {ERR_REASON(PKCS12_R_PARSE_ERROR), "parse error"}, - {ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR), - "pkcs12 algor cipherinit error"}, - {ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR), - "pkcs12 cipherfinal error"}, - {ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR), "pkcs12 pbe crypt error"}, - {ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM), - "unknown digest algorithm"}, - {ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE), "unsupported pkcs12 mode"}, - {0, NULL} -}; - -#endif - -void ERR_load_PKCS12_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) { - ERR_load_strings(0, PKCS12_str_functs); - ERR_load_strings(0, PKCS12_str_reasons); - } -#endif -} diff --git a/Sources/COpenSSL/pk7_.c b/Sources/COpenSSL/pk7_.c deleted file mode 100644 index beaf5ce2..00000000 --- a/Sources/COpenSSL/pk7_.c +++ /dev/null @@ -1,3112 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* pk7_asn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "asn1t.h" -#include "pkcs7.h" -#include "x509.h" - -/* PKCS#7 ASN1 module */ - -/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */ - -ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0); - -ASN1_ADB(PKCS7) = { - ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)), - ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)), - ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)), - ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)), - ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)), - ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) -} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); - -/* PKCS#7 streaming support */ -static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - ASN1_STREAM_ARG *sarg = exarg; - PKCS7 **pp7 = (PKCS7 **)pval; - - switch (operation) { - - case ASN1_OP_STREAM_PRE: - if (PKCS7_stream(&sarg->boundary, *pp7) <= 0) - return 0; - case ASN1_OP_DETACHED_PRE: - sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out); - if (!sarg->ndef_bio) - return 0; - break; - - case ASN1_OP_STREAM_POST: - case ASN1_OP_DETACHED_POST: - if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0) - return 0; - break; - - } - return 1; -} - -ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = { - ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), - ASN1_ADB_OBJECT(PKCS7) -}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7) - -IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) - -IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7) - -ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = { - ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER), - ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR), - ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7), - ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0), - ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1), - ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO) -} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) - -/* Minor tweak to operation: free up EVP_PKEY */ -static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_FREE_POST) { - PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; - EVP_PKEY_free(si->pkey); - } - return 1; -} - -ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = { - ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), - ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR), - /* NB this should be a SET OF but we use a SEQUENCE OF so the - * original order * is retained when the structure is reencoded. - * Since the attributes are implicitly tagged this will not affect - * the encoding. - */ - ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0), - ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR), - ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING), - ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1) -} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) - -ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = { - ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME), - ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER) -} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) - -ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = { - ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER), - ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), - ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT) -} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) - -/* Minor tweak to operation: free up X509 */ -static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_FREE_POST) { - PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; - X509_free(ri->cert); - } - return 1; -} - -ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = { - ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), - ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR), - ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) - -ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = { - ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), - ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), - ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0) -} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) - -ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = { - ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER), - ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), - ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR), - ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT), - ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0), - ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1), - ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO) -} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) - -ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = { - ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER), - ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT) -} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT) - -ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = { - ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER), - ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR), - ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7), - ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING) -} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST) - -IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST) - -/* Specials for authenticated attributes */ - -/* - * When signing attributes we want to reorder them to match the sorted - * encoding. - */ - -ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) -ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN) - -/* - * When verifying attributes we need to use the received order. So we use - * SEQUENCE OF and tag it to SET OF - */ - -ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, - V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) -ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY) - -IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7) -/* pk7_attr.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "bio.h" -#include "asn1.h" -// #include "asn1t.h" -#include "pem.h" -// #include "pkcs7.h" -// #include "x509.h" -#include "err.h" - -int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, - STACK_OF(X509_ALGOR) *cap) -{ - ASN1_STRING *seq; - if (!(seq = ASN1_STRING_new())) { - PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, ERR_R_MALLOC_FAILURE); - return 0; - } - seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data, - ASN1_ITEM_rptr(X509_ALGORS)); - return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, - V_ASN1_SEQUENCE, seq); -} - -STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si) -{ - ASN1_TYPE *cap; - const unsigned char *p; - - cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities); - if (!cap || (cap->type != V_ASN1_SEQUENCE)) - return NULL; - p = cap->value.sequence->data; - return (STACK_OF(X509_ALGOR) *) - ASN1_item_d2i(NULL, &p, cap->value.sequence->length, - ASN1_ITEM_rptr(X509_ALGORS)); -} - -/* Basic smime-capabilities OID and optional integer arg */ -int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) -{ - X509_ALGOR *alg; - - if (!(alg = X509_ALGOR_new())) { - PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); - return 0; - } - ASN1_OBJECT_free(alg->algorithm); - alg->algorithm = OBJ_nid2obj(nid); - if (arg > 0) { - ASN1_INTEGER *nbit; - if (!(alg->parameter = ASN1_TYPE_new())) { - PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!(nbit = ASN1_INTEGER_new())) { - PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!ASN1_INTEGER_set(nbit, arg)) { - PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); - return 0; - } - alg->parameter->value.integer = nbit; - alg->parameter->type = V_ASN1_INTEGER; - } - sk_X509_ALGOR_push(sk, alg); - return 1; -} - -int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid) -{ - if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType)) - return 0; - if (!coid) - coid = OBJ_nid2obj(NID_pkcs7_data); - return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, - V_ASN1_OBJECT, coid); -} - -int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t) -{ - if (!t && !(t = X509_gmtime_adj(NULL, 0))) { - PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME, - ERR_R_MALLOC_FAILURE); - return 0; - } - return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, - V_ASN1_UTCTIME, t); -} - -int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, - const unsigned char *md, int mdlen) -{ - ASN1_OCTET_STRING *os; - os = ASN1_OCTET_STRING_new(); - if (!os) - return 0; - if (!ASN1_STRING_set(os, md, mdlen) - || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest, - V_ASN1_OCTET_STRING, os)) { - ASN1_OCTET_STRING_free(os); - return 0; - } - return 1; -} -/* crypto/pkcs7/pk7_dgst.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "evp.h" -#include "rand.h" -#include "objects.h" -// #include "x509.h" -// #include "pkcs7.h" -/* crypto/pkcs7/pk7_doit.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "rand.h" -// #include "objects.h" -// #include "x509.h" -#include "x509v3.h" -// #include "err.h" - -static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, - void *value); -static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); - -static int PKCS7_type_is_other(PKCS7 *p7) -{ - int isOther = 1; - - int nid = OBJ_obj2nid(p7->type); - - switch (nid) { - case NID_pkcs7_data: - case NID_pkcs7_signed: - case NID_pkcs7_enveloped: - case NID_pkcs7_signedAndEnveloped: - case NID_pkcs7_digest: - case NID_pkcs7_encrypted: - isOther = 0; - break; - default: - isOther = 1; - } - - return isOther; - -} - -static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) -{ - if (PKCS7_type_is_data(p7)) - return p7->d.data; - if (PKCS7_type_is_other(p7) && p7->d.other - && (p7->d.other->type == V_ASN1_OCTET_STRING)) - return p7->d.other->value.octet_string; - return NULL; -} - -static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) -{ - BIO *btmp; - const EVP_MD *md; - if ((btmp = BIO_new(BIO_f_md())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); - goto err; - } - - md = EVP_get_digestbyobj(alg->algorithm); - if (md == NULL) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE); - goto err; - } - - BIO_set_md(btmp, md); - if (*pbio == NULL) - *pbio = btmp; - else if (!BIO_push(*pbio, btmp)) { - PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); - goto err; - } - btmp = NULL; - - return 1; - - err: - if (btmp) - BIO_free(btmp); - return 0; - -} - -static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, - unsigned char *key, int keylen) -{ - EVP_PKEY_CTX *pctx = NULL; - EVP_PKEY *pkey = NULL; - unsigned char *ek = NULL; - int ret = 0; - size_t eklen; - - pkey = X509_get_pubkey(ri->cert); - - if (!pkey) - return 0; - - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pctx) - return 0; - - if (EVP_PKEY_encrypt_init(pctx) <= 0) - goto err; - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, - EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) { - PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); - goto err; - } - - if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) - goto err; - - ek = OPENSSL_malloc(eklen); - - if (ek == NULL) { - PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) - goto err; - - ASN1_STRING_set0(ri->enc_key, ek, eklen); - ek = NULL; - - ret = 1; - - err: - if (pkey) - EVP_PKEY_free(pkey); - if (pctx) - EVP_PKEY_CTX_free(pctx); - if (ek) - OPENSSL_free(ek); - return ret; - -} - -static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, - PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) -{ - EVP_PKEY_CTX *pctx = NULL; - unsigned char *ek = NULL; - size_t eklen; - - int ret = -1; - - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (!pctx) - return -1; - - if (EVP_PKEY_decrypt_init(pctx) <= 0) - goto err; - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, - EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); - goto err; - } - - if (EVP_PKEY_decrypt(pctx, NULL, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0) - goto err; - - ek = OPENSSL_malloc(eklen); - - if (ek == NULL) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (EVP_PKEY_decrypt(pctx, ek, &eklen, - ri->enc_key->data, ri->enc_key->length) <= 0) { - ret = 0; - PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); - goto err; - } - - ret = 1; - - if (*pek) { - OPENSSL_cleanse(*pek, *peklen); - OPENSSL_free(*pek); - } - - *pek = ek; - *peklen = eklen; - - err: - if (pctx) - EVP_PKEY_CTX_free(pctx); - if (!ret && ek) - OPENSSL_free(ek); - - return ret; -} - -BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) -{ - int i; - BIO *out = NULL, *btmp = NULL; - X509_ALGOR *xa = NULL; - const EVP_CIPHER *evp_cipher = NULL; - STACK_OF(X509_ALGOR) *md_sk = NULL; - STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; - X509_ALGOR *xalg = NULL; - PKCS7_RECIP_INFO *ri = NULL; - ASN1_OCTET_STRING *os = NULL; - - if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); - return NULL; - } - /* - * The content field in the PKCS7 ContentInfo is optional, but that really - * only applies to inner content (precisely, detached signatures). - * - * When reading content, missing outer content is therefore treated as an - * error. - * - * When creating content, PKCS7_content_new() must be called before - * calling this method, so a NULL p7->d is always an error. - */ - if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); - return NULL; - } - - i = OBJ_obj2nid(p7->type); - p7->state = PKCS7_S_HEADER; - - switch (i) { - case NID_pkcs7_signed: - md_sk = p7->d.sign->md_algs; - os = PKCS7_get_octet_string(p7->d.sign->contents); - break; - case NID_pkcs7_signedAndEnveloped: - rsk = p7->d.signed_and_enveloped->recipientinfo; - md_sk = p7->d.signed_and_enveloped->md_algs; - xalg = p7->d.signed_and_enveloped->enc_data->algorithm; - evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; - if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); - goto err; - } - break; - case NID_pkcs7_enveloped: - rsk = p7->d.enveloped->recipientinfo; - xalg = p7->d.enveloped->enc_data->algorithm; - evp_cipher = p7->d.enveloped->enc_data->cipher; - if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); - goto err; - } - break; - case NID_pkcs7_digest: - xa = p7->d.digest->md; - os = PKCS7_get_octet_string(p7->d.digest->contents); - break; - case NID_pkcs7_data: - break; - default: - PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); - goto err; - } - - for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) - if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) - goto err; - - if (xa && !PKCS7_bio_add_digest(&out, xa)) - goto err; - - if (evp_cipher != NULL) { - unsigned char key[EVP_MAX_KEY_LENGTH]; - unsigned char iv[EVP_MAX_IV_LENGTH]; - int keylen, ivlen; - EVP_CIPHER_CTX *ctx; - - if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); - goto err; - } - BIO_get_cipher_ctx(btmp, &ctx); - keylen = EVP_CIPHER_key_length(evp_cipher); - ivlen = EVP_CIPHER_iv_length(evp_cipher); - xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); - if (ivlen > 0) - if (RAND_bytes(iv, ivlen) <= 0) - goto err; - if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) - goto err; - if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) - goto err; - if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) - goto err; - - if (ivlen > 0) { - if (xalg->parameter == NULL) { - xalg->parameter = ASN1_TYPE_new(); - if (xalg->parameter == NULL) - goto err; - } - if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) - goto err; - } - - /* Lets do the pub key stuff :-) */ - for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { - ri = sk_PKCS7_RECIP_INFO_value(rsk, i); - if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) - goto err; - } - OPENSSL_cleanse(key, keylen); - - if (out == NULL) - out = btmp; - else - BIO_push(out, btmp); - btmp = NULL; - } - - if (bio == NULL) { - if (PKCS7_is_detached(p7)) { - bio = BIO_new(BIO_s_null()); - } else if (os && os->length > 0) { - bio = BIO_new_mem_buf(os->data, os->length); - } else { - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) - goto err; - BIO_set_mem_eof_return(bio, 0); - } - if (bio == NULL) - goto err; - } - if (out) - BIO_push(out, bio); - else - out = bio; - bio = NULL; - if (0) { - err: - if (out != NULL) - BIO_free_all(out); - if (btmp != NULL) - BIO_free_all(btmp); - out = NULL; - } - return (out); -} - -static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) -{ - int ret; - ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, - pcert->cert_info->issuer); - if (ret) - return ret; - return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, - ri->issuer_and_serial->serial); -} - -/* int */ -BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) -{ - int i, j; - BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; - X509_ALGOR *xa; - ASN1_OCTET_STRING *data_body = NULL; - const EVP_MD *evp_md; - const EVP_CIPHER *evp_cipher = NULL; - EVP_CIPHER_CTX *evp_ctx = NULL; - X509_ALGOR *enc_alg = NULL; - STACK_OF(X509_ALGOR) *md_sk = NULL; - STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; - PKCS7_RECIP_INFO *ri = NULL; - unsigned char *ek = NULL, *tkey = NULL; - int eklen = 0, tkeylen = 0; - - if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); - return NULL; - } - - if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); - return NULL; - } - - i = OBJ_obj2nid(p7->type); - p7->state = PKCS7_S_HEADER; - - switch (i) { - case NID_pkcs7_signed: - /* - * p7->d.sign->contents is a PKCS7 structure consisting of a contentType - * field and optional content. - * data_body is NULL if that structure has no (=detached) content - * or if the contentType is wrong (i.e., not "data"). - */ - data_body = PKCS7_get_octet_string(p7->d.sign->contents); - if (!PKCS7_is_detached(p7) && data_body == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_INVALID_SIGNED_DATA_TYPE); - goto err; - } - md_sk = p7->d.sign->md_algs; - break; - case NID_pkcs7_signedAndEnveloped: - rsk = p7->d.signed_and_enveloped->recipientinfo; - md_sk = p7->d.signed_and_enveloped->md_algs; - /* data_body is NULL if the optional EncryptedContent is missing. */ - data_body = p7->d.signed_and_enveloped->enc_data->enc_data; - enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; - evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); - if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNSUPPORTED_CIPHER_TYPE); - goto err; - } - break; - case NID_pkcs7_enveloped: - rsk = p7->d.enveloped->recipientinfo; - enc_alg = p7->d.enveloped->enc_data->algorithm; - /* data_body is NULL if the optional EncryptedContent is missing. */ - data_body = p7->d.enveloped->enc_data->enc_data; - evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); - if (evp_cipher == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNSUPPORTED_CIPHER_TYPE); - goto err; - } - break; - default: - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); - goto err; - } - - /* Detached content must be supplied via in_bio instead. */ - if (data_body == NULL && in_bio == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); - goto err; - } - - /* We will be checking the signature */ - if (md_sk != NULL) { - for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { - xa = sk_X509_ALGOR_value(md_sk, i); - if ((btmp = BIO_new(BIO_f_md())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); - goto err; - } - - j = OBJ_obj2nid(xa->algorithm); - evp_md = EVP_get_digestbynid(j); - if (evp_md == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_UNKNOWN_DIGEST_TYPE); - goto err; - } - - BIO_set_md(btmp, evp_md); - if (out == NULL) - out = btmp; - else - BIO_push(out, btmp); - btmp = NULL; - } - } - - if (evp_cipher != NULL) { -#if 0 - unsigned char key[EVP_MAX_KEY_LENGTH]; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char *p; - int keylen, ivlen; - int max; - X509_OBJECT ret; -#endif - - if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); - goto err; - } - - /* - * It was encrypted, we need to decrypt the secret key with the - * private key - */ - - /* - * Find the recipientInfo which matches the passed certificate (if - * any) - */ - - if (pcert) { - for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { - ri = sk_PKCS7_RECIP_INFO_value(rsk, i); - if (!pkcs7_cmp_ri(ri, pcert)) - break; - ri = NULL; - } - if (ri == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATADECODE, - PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); - goto err; - } - } - - /* If we haven't got a certificate try each ri in turn */ - if (pcert == NULL) { - /* - * Always attempt to decrypt all rinfo even after sucess as a - * defence against MMA timing attacks. - */ - for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { - ri = sk_PKCS7_RECIP_INFO_value(rsk, i); - - if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) - goto err; - ERR_clear_error(); - } - } else { - /* Only exit on fatal errors, not decrypt failure */ - if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) - goto err; - ERR_clear_error(); - } - - evp_ctx = NULL; - BIO_get_cipher_ctx(etmp, &evp_ctx); - if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) - goto err; - if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) - goto err; - /* Generate random key as MMA defence */ - tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); - tkey = OPENSSL_malloc(tkeylen); - if (!tkey) - goto err; - if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) - goto err; - if (ek == NULL) { - ek = tkey; - eklen = tkeylen; - tkey = NULL; - } - - if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { - /* - * Some S/MIME clients don't use the same key and effective key - * length. The key length is determined by the size of the - * decrypted RSA key. - */ - if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { - /* Use random key as MMA defence */ - OPENSSL_cleanse(ek, eklen); - OPENSSL_free(ek); - ek = tkey; - eklen = tkeylen; - tkey = NULL; - } - } - /* Clear errors so we don't leak information useful in MMA */ - ERR_clear_error(); - if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) - goto err; - - if (ek) { - OPENSSL_cleanse(ek, eklen); - OPENSSL_free(ek); - ek = NULL; - } - if (tkey) { - OPENSSL_cleanse(tkey, tkeylen); - OPENSSL_free(tkey); - tkey = NULL; - } - - if (out == NULL) - out = etmp; - else - BIO_push(out, etmp); - etmp = NULL; - } -#if 1 - if (in_bio != NULL) { - bio = in_bio; - } else { -# if 0 - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) - goto err; - /* - * We need to set this so that when we have read all the data, the - * encrypt BIO, if present, will read EOF and encode the last few - * bytes - */ - BIO_set_mem_eof_return(bio, 0); - - if (data_body->length > 0) - BIO_write(bio, (char *)data_body->data, data_body->length); -# else - if (data_body->length > 0) - bio = BIO_new_mem_buf(data_body->data, data_body->length); - else { - bio = BIO_new(BIO_s_mem()); - if (bio == NULL) - goto err; - BIO_set_mem_eof_return(bio, 0); - } - if (bio == NULL) - goto err; -# endif - } - BIO_push(out, bio); - bio = NULL; -#endif - if (0) { - err: - if (ek) { - OPENSSL_cleanse(ek, eklen); - OPENSSL_free(ek); - } - if (tkey) { - OPENSSL_cleanse(tkey, tkeylen); - OPENSSL_free(tkey); - } - if (out != NULL) - BIO_free_all(out); - if (btmp != NULL) - BIO_free_all(btmp); - if (etmp != NULL) - BIO_free_all(etmp); - if (bio != NULL) - BIO_free_all(bio); - out = NULL; - } - return (out); -} - -static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) -{ - for (;;) { - bio = BIO_find_type(bio, BIO_TYPE_MD); - if (bio == NULL) { - PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); - return NULL; - } - BIO_get_md_ctx(bio, pmd); - if (*pmd == NULL) { - PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR); - return NULL; - } - if (EVP_MD_CTX_type(*pmd) == nid) - return bio; - bio = BIO_next(bio); - } - return NULL; -} - -static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) -{ - unsigned char md_data[EVP_MAX_MD_SIZE]; - unsigned int md_len; - - /* Add signing time if not already present */ - if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { - if (!PKCS7_add0_attrib_signing_time(si, NULL)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); - return 0; - } - } - - /* Add digest */ - if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); - return 0; - } - if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { - PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); - return 0; - } - - /* Now sign the attributes */ - if (!PKCS7_SIGNER_INFO_sign(si)) - return 0; - - return 1; -} - -int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) -{ - int ret = 0; - int i, j; - BIO *btmp; - PKCS7_SIGNER_INFO *si; - EVP_MD_CTX *mdc, ctx_tmp; - STACK_OF(X509_ATTRIBUTE) *sk; - STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; - ASN1_OCTET_STRING *os = NULL; - - if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); - return 0; - } - - if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); - return 0; - } - - EVP_MD_CTX_init(&ctx_tmp); - i = OBJ_obj2nid(p7->type); - p7->state = PKCS7_S_HEADER; - - switch (i) { - case NID_pkcs7_data: - os = p7->d.data; - break; - case NID_pkcs7_signedAndEnveloped: - /* XXXXXXXXXXXXXXXX */ - si_sk = p7->d.signed_and_enveloped->signer_info; - os = p7->d.signed_and_enveloped->enc_data->enc_data; - if (!os) { - os = M_ASN1_OCTET_STRING_new(); - if (!os) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); - goto err; - } - p7->d.signed_and_enveloped->enc_data->enc_data = os; - } - break; - case NID_pkcs7_enveloped: - /* XXXXXXXXXXXXXXXX */ - os = p7->d.enveloped->enc_data->enc_data; - if (!os) { - os = M_ASN1_OCTET_STRING_new(); - if (!os) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); - goto err; - } - p7->d.enveloped->enc_data->enc_data = os; - } - break; - case NID_pkcs7_signed: - si_sk = p7->d.sign->signer_info; - os = PKCS7_get_octet_string(p7->d.sign->contents); - /* If detached data then the content is excluded */ - if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { - M_ASN1_OCTET_STRING_free(os); - os = NULL; - p7->d.sign->contents->d.data = NULL; - } - break; - - case NID_pkcs7_digest: - os = PKCS7_get_octet_string(p7->d.digest->contents); - /* If detached data then the content is excluded */ - if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { - M_ASN1_OCTET_STRING_free(os); - os = NULL; - p7->d.digest->contents->d.data = NULL; - } - break; - - default: - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); - goto err; - } - - if (si_sk != NULL) { - for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { - si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); - if (si->pkey == NULL) - continue; - - j = OBJ_obj2nid(si->digest_alg->algorithm); - - btmp = bio; - - btmp = PKCS7_find_digest(&mdc, btmp, j); - - if (btmp == NULL) - goto err; - - /* - * We now have the EVP_MD_CTX, lets do the signing. - */ - if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) - goto err; - - sk = si->auth_attr; - - /* - * If there are attributes, we add the digest attribute and only - * sign the attributes - */ - if (sk_X509_ATTRIBUTE_num(sk) > 0) { - if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) - goto err; - } else { - unsigned char *abuf = NULL; - unsigned int abuflen; - abuflen = EVP_PKEY_size(si->pkey); - abuf = OPENSSL_malloc(abuflen); - if (!abuf) - goto err; - - if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); - goto err; - } - ASN1_STRING_set0(si->enc_digest, abuf, abuflen); - } - } - } else if (i == NID_pkcs7_digest) { - unsigned char md_data[EVP_MAX_MD_SIZE]; - unsigned int md_len; - if (!PKCS7_find_digest(&mdc, bio, - OBJ_obj2nid(p7->d.digest->md->algorithm))) - goto err; - if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) - goto err; - M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); - } - - if (!PKCS7_is_detached(p7)) { - /* - * NOTE(emilia): I think we only reach os == NULL here because detached - * digested data support is broken. - */ - if (os == NULL) - goto err; - if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { - char *cont; - long contlen; - btmp = BIO_find_type(bio, BIO_TYPE_MEM); - if (btmp == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); - goto err; - } - contlen = BIO_get_mem_data(btmp, &cont); - /* - * Mark the BIO read only then we can use its copy of the data - * instead of making an extra copy. - */ - BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); - BIO_set_mem_eof_return(btmp, 0); - ASN1_STRING_set0(os, (unsigned char *)cont, contlen); - } - } - ret = 1; - err: - EVP_MD_CTX_cleanup(&ctx_tmp); - return (ret); -} - -int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) -{ - EVP_MD_CTX mctx; - EVP_PKEY_CTX *pctx; - unsigned char *abuf = NULL; - int alen; - size_t siglen; - const EVP_MD *md = NULL; - - md = EVP_get_digestbyobj(si->digest_alg->algorithm); - if (md == NULL) - return 0; - - EVP_MD_CTX_init(&mctx); - if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) - goto err; - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); - goto err; - } - - alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, - ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); - if (!abuf) - goto err; - if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) - goto err; - OPENSSL_free(abuf); - abuf = NULL; - if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) - goto err; - abuf = OPENSSL_malloc(siglen); - if (!abuf) - goto err; - if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) - goto err; - - if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, - EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); - goto err; - } - - EVP_MD_CTX_cleanup(&mctx); - - ASN1_STRING_set0(si->enc_digest, abuf, siglen); - - return 1; - - err: - if (abuf) - OPENSSL_free(abuf); - EVP_MD_CTX_cleanup(&mctx); - return 0; - -} - -int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, - PKCS7 *p7, PKCS7_SIGNER_INFO *si) -{ - PKCS7_ISSUER_AND_SERIAL *ias; - int ret = 0, i; - STACK_OF(X509) *cert; - X509 *x509; - - if (p7 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); - return 0; - } - - if (p7->d.ptr == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); - return 0; - } - - if (PKCS7_type_is_signed(p7)) { - cert = p7->d.sign->cert; - } else if (PKCS7_type_is_signedAndEnveloped(p7)) { - cert = p7->d.signed_and_enveloped->cert; - } else { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); - goto err; - } - /* XXXXXXXXXXXXXXXXXXXXXXX */ - ias = si->issuer_and_serial; - - x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); - - /* were we able to find the cert in passed to us */ - if (x509 == NULL) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, - PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); - goto err; - } - - /* Lets verify */ - if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); - goto err; - } - X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); - i = X509_verify_cert(ctx); - if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); - X509_STORE_CTX_cleanup(ctx); - goto err; - } - X509_STORE_CTX_cleanup(ctx); - - return PKCS7_signatureVerify(bio, p7, si, x509); - err: - return ret; -} - -int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - X509 *x509) -{ - ASN1_OCTET_STRING *os; - EVP_MD_CTX mdc_tmp, *mdc; - int ret = 0, i; - int md_type; - STACK_OF(X509_ATTRIBUTE) *sk; - BIO *btmp; - EVP_PKEY *pkey; - - EVP_MD_CTX_init(&mdc_tmp); - - if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); - goto err; - } - - md_type = OBJ_obj2nid(si->digest_alg->algorithm); - - btmp = bio; - for (;;) { - if ((btmp == NULL) || - ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); - goto err; - } - BIO_get_md_ctx(btmp, &mdc); - if (mdc == NULL) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - if (EVP_MD_CTX_type(mdc) == md_type) - break; - /* - * Workaround for some broken clients that put the signature OID - * instead of the digest OID in digest_alg->algorithm - */ - if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) - break; - btmp = BIO_next(btmp); - } - - /* - * mdc is the digest ctx that we want, unless there are attributes, in - * which case the digest is the signed attributes - */ - if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc)) - goto err; - - sk = si->auth_attr; - if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { - unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; - unsigned int md_len; - int alen; - ASN1_OCTET_STRING *message_digest; - - if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) - goto err; - message_digest = PKCS7_digest_from_attributes(sk); - if (!message_digest) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, - PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); - goto err; - } - if ((message_digest->length != (int)md_len) || - (memcmp(message_digest->data, md_dat, md_len))) { -#if 0 - { - int ii; - for (ii = 0; ii < message_digest->length; ii++) - printf("%02X", message_digest->data[ii]); - printf(" sent\n"); - for (ii = 0; ii < md_len; ii++) - printf("%02X", md_dat[ii]); - printf(" calc\n"); - } -#endif - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); - ret = -1; - goto err; - } - - if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL)) - goto err; - - alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, - ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); - if (alen <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB); - ret = -1; - goto err; - } - if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) - goto err; - - OPENSSL_free(abuf); - } - - os = si->enc_digest; - pkey = X509_get_pubkey(x509); - if (!pkey) { - ret = -1; - goto err; - } - - i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); - EVP_PKEY_free(pkey); - if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); - ret = -1; - goto err; - } else - ret = 1; - err: - EVP_MD_CTX_cleanup(&mdc_tmp); - return (ret); -} - -PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) -{ - STACK_OF(PKCS7_RECIP_INFO) *rsk; - PKCS7_RECIP_INFO *ri; - int i; - - i = OBJ_obj2nid(p7->type); - if (i != NID_pkcs7_signedAndEnveloped) - return NULL; - if (p7->d.signed_and_enveloped == NULL) - return NULL; - rsk = p7->d.signed_and_enveloped->recipientinfo; - if (rsk == NULL) - return NULL; - if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) - return (NULL); - ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); - return (ri->issuer_and_serial); -} - -ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) -{ - return (get_attribute(si->auth_attr, nid)); -} - -ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) -{ - return (get_attribute(si->unauth_attr, nid)); -} - -static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) -{ - int i; - X509_ATTRIBUTE *xa; - ASN1_OBJECT *o; - - o = OBJ_nid2obj(nid); - if (!o || !sk) - return (NULL); - for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { - xa = sk_X509_ATTRIBUTE_value(sk, i); - if (OBJ_cmp(xa->object, o) == 0) { - if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) - return (sk_ASN1_TYPE_value(xa->value.set, 0)); - else - return (NULL); - } - } - return (NULL); -} - -ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) -{ - ASN1_TYPE *astype; - if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) - return NULL; - return astype->value.octet_string; -} - -int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, - STACK_OF(X509_ATTRIBUTE) *sk) -{ - int i; - - if (p7si->auth_attr != NULL) - sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free); - p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk); - if (p7si->auth_attr == NULL) - return 0; - for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { - if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i, - X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value - (sk, i)))) - == NULL) - return (0); - } - return (1); -} - -int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, - STACK_OF(X509_ATTRIBUTE) *sk) -{ - int i; - - if (p7si->unauth_attr != NULL) - sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free); - p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk); - if (p7si->unauth_attr == NULL) - return 0; - for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { - if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i, - X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value - (sk, i)))) - == NULL) - return (0); - } - return (1); -} - -int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, - void *value) -{ - return (add_attribute(&(p7si->auth_attr), nid, atrtype, value)); -} - -int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, - void *value) -{ - return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value)); -} - -static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, - void *value) -{ - X509_ATTRIBUTE *attr = NULL; - - if (*sk == NULL) { - *sk = sk_X509_ATTRIBUTE_new_null(); - if (*sk == NULL) - return 0; - new_attrib: - if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value))) - return 0; - if (!sk_X509_ATTRIBUTE_push(*sk, attr)) { - X509_ATTRIBUTE_free(attr); - return 0; - } - } else { - int i; - - for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) { - attr = sk_X509_ATTRIBUTE_value(*sk, i); - if (OBJ_obj2nid(attr->object) == nid) { - X509_ATTRIBUTE_free(attr); - attr = X509_ATTRIBUTE_create(nid, atrtype, value); - if (attr == NULL) - return 0; - if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) { - X509_ATTRIBUTE_free(attr); - return 0; - } - goto end; - } - } - goto new_attrib; - } - end: - return (1); -} -/* crypto/pkcs7/pk7_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "x509.h" -#include "asn1_locl.h" - -long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) -{ - int nid; - long ret; - - nid = OBJ_obj2nid(p7->type); - - switch (cmd) { - /* NOTE(emilia): does not support detached digested data. */ - case PKCS7_OP_SET_DETACHED_SIGNATURE: - if (nid == NID_pkcs7_signed) { - ret = p7->detached = (int)larg; - if (ret && PKCS7_type_is_data(p7->d.sign->contents)) { - ASN1_OCTET_STRING *os; - os = p7->d.sign->contents->d.data; - ASN1_OCTET_STRING_free(os); - p7->d.sign->contents->d.data = NULL; - } - } else { - PKCS7err(PKCS7_F_PKCS7_CTRL, - PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); - ret = 0; - } - break; - case PKCS7_OP_GET_DETACHED_SIGNATURE: - if (nid == NID_pkcs7_signed) { - if (!p7->d.sign || !p7->d.sign->contents->d.ptr) - ret = 1; - else - ret = 0; - - p7->detached = ret; - } else { - PKCS7err(PKCS7_F_PKCS7_CTRL, - PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); - ret = 0; - } - - break; - default: - PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION); - ret = 0; - } - return (ret); -} - -int PKCS7_content_new(PKCS7 *p7, int type) -{ - PKCS7 *ret = NULL; - - if ((ret = PKCS7_new()) == NULL) - goto err; - if (!PKCS7_set_type(ret, type)) - goto err; - if (!PKCS7_set_content(p7, ret)) - goto err; - - return (1); - err: - if (ret != NULL) - PKCS7_free(ret); - return (0); -} - -int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) -{ - int i; - - i = OBJ_obj2nid(p7->type); - switch (i) { - case NID_pkcs7_signed: - if (p7->d.sign->contents != NULL) - PKCS7_free(p7->d.sign->contents); - p7->d.sign->contents = p7_data; - break; - case NID_pkcs7_digest: - if (p7->d.digest->contents != NULL) - PKCS7_free(p7->d.digest->contents); - p7->d.digest->contents = p7_data; - break; - case NID_pkcs7_data: - case NID_pkcs7_enveloped: - case NID_pkcs7_signedAndEnveloped: - case NID_pkcs7_encrypted: - default: - PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); - goto err; - } - return (1); - err: - return (0); -} - -int PKCS7_set_type(PKCS7 *p7, int type) -{ - ASN1_OBJECT *obj; - - /* - * PKCS7_content_free(p7); - */ - obj = OBJ_nid2obj(type); /* will not fail */ - - switch (type) { - case NID_pkcs7_signed: - p7->type = obj; - if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL) - goto err; - if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) { - PKCS7_SIGNED_free(p7->d.sign); - p7->d.sign = NULL; - goto err; - } - break; - case NID_pkcs7_data: - p7->type = obj; - if ((p7->d.data = M_ASN1_OCTET_STRING_new()) == NULL) - goto err; - break; - case NID_pkcs7_signedAndEnveloped: - p7->type = obj; - if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new()) - == NULL) - goto err; - if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) - goto err; - p7->d.signed_and_enveloped->enc_data->content_type - = OBJ_nid2obj(NID_pkcs7_data); - break; - case NID_pkcs7_enveloped: - p7->type = obj; - if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) - == NULL) - goto err; - if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0)) - goto err; - p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); - break; - case NID_pkcs7_encrypted: - p7->type = obj; - if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) - == NULL) - goto err; - if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0)) - goto err; - p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); - break; - - case NID_pkcs7_digest: - p7->type = obj; - if ((p7->d.digest = PKCS7_DIGEST_new()) - == NULL) - goto err; - if (!ASN1_INTEGER_set(p7->d.digest->version, 0)) - goto err; - break; - default: - PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); - goto err; - } - return (1); - err: - return (0); -} - -int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) -{ - p7->type = OBJ_nid2obj(type); - p7->d.other = other; - return 1; -} - -int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) -{ - int i, j, nid; - X509_ALGOR *alg; - STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; - STACK_OF(X509_ALGOR) *md_sk; - - i = OBJ_obj2nid(p7->type); - switch (i) { - case NID_pkcs7_signed: - signer_sk = p7->d.sign->signer_info; - md_sk = p7->d.sign->md_algs; - break; - case NID_pkcs7_signedAndEnveloped: - signer_sk = p7->d.signed_and_enveloped->signer_info; - md_sk = p7->d.signed_and_enveloped->md_algs; - break; - default: - PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE); - return (0); - } - - nid = OBJ_obj2nid(psi->digest_alg->algorithm); - - /* If the digest is not currently listed, add it */ - j = 0; - for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { - alg = sk_X509_ALGOR_value(md_sk, i); - if (OBJ_obj2nid(alg->algorithm) == nid) { - j = 1; - break; - } - } - if (!j) { /* we need to add another algorithm */ - if (!(alg = X509_ALGOR_new()) - || !(alg->parameter = ASN1_TYPE_new())) { - X509_ALGOR_free(alg); - PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE); - return (0); - } - alg->algorithm = OBJ_nid2obj(nid); - alg->parameter->type = V_ASN1_NULL; - if (!sk_X509_ALGOR_push(md_sk, alg)) { - X509_ALGOR_free(alg); - return 0; - } - } - - if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) - return 0; - return (1); -} - -int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) -{ - int i; - STACK_OF(X509) **sk; - - i = OBJ_obj2nid(p7->type); - switch (i) { - case NID_pkcs7_signed: - sk = &(p7->d.sign->cert); - break; - case NID_pkcs7_signedAndEnveloped: - sk = &(p7->d.signed_and_enveloped->cert); - break; - default: - PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE); - return (0); - } - - if (*sk == NULL) - *sk = sk_X509_new_null(); - if (*sk == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); - return 0; - } - CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); - if (!sk_X509_push(*sk, x509)) { - X509_free(x509); - return 0; - } - return (1); -} - -int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) -{ - int i; - STACK_OF(X509_CRL) **sk; - - i = OBJ_obj2nid(p7->type); - switch (i) { - case NID_pkcs7_signed: - sk = &(p7->d.sign->crl); - break; - case NID_pkcs7_signedAndEnveloped: - sk = &(p7->d.signed_and_enveloped->crl); - break; - default: - PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE); - return (0); - } - - if (*sk == NULL) - *sk = sk_X509_CRL_new_null(); - if (*sk == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE); - return 0; - } - - CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); - if (!sk_X509_CRL_push(*sk, crl)) { - X509_CRL_free(crl); - return 0; - } - return (1); -} - -int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, - const EVP_MD *dgst) -{ - int ret; - - /* We now need to add another PKCS7_SIGNER_INFO entry */ - if (!ASN1_INTEGER_set(p7i->version, 1)) - goto err; - if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, - X509_get_issuer_name(x509))) - goto err; - - /* - * because ASN1_INTEGER_set is used to set a 'long' we will do things the - * ugly way. - */ - M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); - if (!(p7i->issuer_and_serial->serial = - M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) - goto err; - - /* lets keep the pkey around for a while */ - CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - p7i->pkey = pkey; - - /* Set the algorithms */ - - X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), - V_ASN1_NULL, NULL); - - if (pkey->ameth && pkey->ameth->pkey_ctrl) { - ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i); - if (ret > 0) - return 1; - if (ret != -2) { - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, - PKCS7_R_SIGNING_CTRL_FAILURE); - return 0; - } - } - PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, - PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - err: - return 0; -} - -PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, - const EVP_MD *dgst) -{ - PKCS7_SIGNER_INFO *si = NULL; - - if (dgst == NULL) { - int def_nid; - if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) - goto err; - dgst = EVP_get_digestbynid(def_nid); - if (dgst == NULL) { - PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST); - goto err; - } - } - - if ((si = PKCS7_SIGNER_INFO_new()) == NULL) - goto err; - if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) - goto err; - if (!PKCS7_add_signer(p7, si)) - goto err; - return (si); - err: - if (si) - PKCS7_SIGNER_INFO_free(si); - return (NULL); -} - -int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) -{ - if (PKCS7_type_is_digest(p7)) { - if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) { - PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE); - return 0; - } - p7->d.digest->md->parameter->type = V_ASN1_NULL; - p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); - return 1; - } - - PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE); - return 1; -} - -STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7) -{ - if (p7 == NULL || p7->d.ptr == NULL) - return NULL; - if (PKCS7_type_is_signed(p7)) { - return (p7->d.sign->signer_info); - } else if (PKCS7_type_is_signedAndEnveloped(p7)) { - return (p7->d.signed_and_enveloped->signer_info); - } else - return (NULL); -} - -void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, - X509_ALGOR **pdig, X509_ALGOR **psig) -{ - if (pk) - *pk = si->pkey; - if (pdig) - *pdig = si->digest_alg; - if (psig) - *psig = si->digest_enc_alg; -} - -void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) -{ - if (penc) - *penc = ri->key_enc_algor; -} - -PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) -{ - PKCS7_RECIP_INFO *ri; - - if ((ri = PKCS7_RECIP_INFO_new()) == NULL) - goto err; - if (!PKCS7_RECIP_INFO_set(ri, x509)) - goto err; - if (!PKCS7_add_recipient_info(p7, ri)) - goto err; - return ri; - err: - if (ri) - PKCS7_RECIP_INFO_free(ri); - return NULL; -} - -int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) -{ - int i; - STACK_OF(PKCS7_RECIP_INFO) *sk; - - i = OBJ_obj2nid(p7->type); - switch (i) { - case NID_pkcs7_signedAndEnveloped: - sk = p7->d.signed_and_enveloped->recipientinfo; - break; - case NID_pkcs7_enveloped: - sk = p7->d.enveloped->recipientinfo; - break; - default: - PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO, - PKCS7_R_WRONG_CONTENT_TYPE); - return (0); - } - - if (!sk_PKCS7_RECIP_INFO_push(sk, ri)) - return 0; - return (1); -} - -int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) -{ - int ret; - EVP_PKEY *pkey = NULL; - if (!ASN1_INTEGER_set(p7i->version, 0)) - return 0; - if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, - X509_get_issuer_name(x509))) - return 0; - - M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); - if (!(p7i->issuer_and_serial->serial = - M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) - return 0; - - pkey = X509_get_pubkey(x509); - - if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { - PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, - PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; - } - - ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i); - if (ret == -2) { - PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, - PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); - goto err; - } - if (ret <= 0) { - PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, - PKCS7_R_ENCRYPTION_CTRL_FAILURE); - goto err; - } - - EVP_PKEY_free(pkey); - - CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); - p7i->cert = x509; - - return 1; - - err: - if (pkey) - EVP_PKEY_free(pkey); - return 0; -} - -X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) -{ - if (PKCS7_type_is_signed(p7)) - return (X509_find_by_issuer_and_serial(p7->d.sign->cert, - si->issuer_and_serial->issuer, - si-> - issuer_and_serial->serial)); - else - return (NULL); -} - -int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) -{ - int i; - PKCS7_ENC_CONTENT *ec; - - i = OBJ_obj2nid(p7->type); - switch (i) { - case NID_pkcs7_signedAndEnveloped: - ec = p7->d.signed_and_enveloped->enc_data; - break; - case NID_pkcs7_enveloped: - ec = p7->d.enveloped->enc_data; - break; - default: - PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE); - return (0); - } - - /* Check cipher OID exists and has data in it */ - i = EVP_CIPHER_type(cipher); - if (i == NID_undef) { - PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, - PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); - return (0); - } - - ec->cipher = cipher; - return 1; -} - -int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) -{ - ASN1_OCTET_STRING *os = NULL; - - switch (OBJ_obj2nid(p7->type)) { - case NID_pkcs7_data: - os = p7->d.data; - break; - - case NID_pkcs7_signedAndEnveloped: - os = p7->d.signed_and_enveloped->enc_data->enc_data; - if (os == NULL) { - os = M_ASN1_OCTET_STRING_new(); - p7->d.signed_and_enveloped->enc_data->enc_data = os; - } - break; - - case NID_pkcs7_enveloped: - os = p7->d.enveloped->enc_data->enc_data; - if (os == NULL) { - os = M_ASN1_OCTET_STRING_new(); - p7->d.enveloped->enc_data->enc_data = os; - } - break; - - case NID_pkcs7_signed: - os = p7->d.sign->contents->d.data; - break; - - default: - os = NULL; - break; - } - - if (os == NULL) - return 0; - - os->flags |= ASN1_STRING_FLAG_NDEF; - *boundary = &os->data; - - return 1; -} -/* pk7_mime.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "rand.h" -// #include "x509.h" -// #include "asn1.h" - -/* PKCS#7 wrappers round generalised stream and MIME routines */ - -int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) -{ - return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags, - ASN1_ITEM_rptr(PKCS7)); -} - -int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) -{ - return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)p7, in, flags, - "PKCS7", ASN1_ITEM_rptr(PKCS7)); -} - -int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) -{ - STACK_OF(X509_ALGOR) *mdalgs; - int ctype_nid = OBJ_obj2nid(p7->type); - if (ctype_nid == NID_pkcs7_signed) - mdalgs = p7->d.sign->md_algs; - else - mdalgs = NULL; - - flags ^= SMIME_OLDMIME; - - return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags, - ctype_nid, NID_undef, mdalgs, - ASN1_ITEM_rptr(PKCS7)); -} - -PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) -{ - return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7)); -} -/* pk7_smime.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* Simple PKCS#7 processing functions */ - -#include -// #include "cryptlib.h" -// #include "x509.h" -// #include "x509v3.h" - -static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); - -PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, - BIO *data, int flags) -{ - PKCS7 *p7; - int i; - - if (!(p7 = PKCS7_new())) { - PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (!PKCS7_set_type(p7, NID_pkcs7_signed)) - goto err; - - if (!PKCS7_content_new(p7, NID_pkcs7_data)) - goto err; - - if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) { - PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR); - goto err; - } - - if (!(flags & PKCS7_NOCERTS)) { - for (i = 0; i < sk_X509_num(certs); i++) { - if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) - goto err; - } - } - - if (flags & PKCS7_DETACHED) - PKCS7_set_detached(p7, 1); - - if (flags & (PKCS7_STREAM | PKCS7_PARTIAL)) - return p7; - - if (PKCS7_final(p7, data, flags)) - return p7; - - err: - PKCS7_free(p7); - return NULL; -} - -int PKCS7_final(PKCS7 *p7, BIO *data, int flags) -{ - BIO *p7bio; - int ret = 0; - if (!(p7bio = PKCS7_dataInit(p7, NULL))) { - PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE); - return 0; - } - - SMIME_crlf_copy(data, p7bio, flags); - - (void)BIO_flush(p7bio); - - if (!PKCS7_dataFinal(p7, p7bio)) { - PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN); - goto err; - } - - ret = 1; - - err: - BIO_free_all(p7bio); - - return ret; - -} - -/* Check to see if a cipher exists and if so add S/MIME capabilities */ - -static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) -{ - if (EVP_get_cipherbynid(nid)) - return PKCS7_simple_smimecap(sk, nid, arg); - return 1; -} - -static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) -{ - if (EVP_get_digestbynid(nid)) - return PKCS7_simple_smimecap(sk, nid, arg); - return 1; -} - -PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, - EVP_PKEY *pkey, const EVP_MD *md, - int flags) -{ - PKCS7_SIGNER_INFO *si = NULL; - STACK_OF(X509_ALGOR) *smcap = NULL; - if (!X509_check_private_key(signcert, pkey)) { - PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, - PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); - return NULL; - } - - if (!(si = PKCS7_add_signature(p7, signcert, pkey, md))) { - PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, - PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); - return NULL; - } - - if (!(flags & PKCS7_NOCERTS)) { - if (!PKCS7_add_certificate(p7, signcert)) - goto err; - } - - if (!(flags & PKCS7_NOATTR)) { - if (!PKCS7_add_attrib_content_type(si, NULL)) - goto err; - /* Add SMIMECapabilities */ - if (!(flags & PKCS7_NOSMIMECAP)) { - if (!(smcap = sk_X509_ALGOR_new_null())) { - PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) - || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) - || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) - || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) - || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) - || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) - || !add_cipher_smcap(smcap, NID_rc2_cbc, 128) - || !add_cipher_smcap(smcap, NID_rc2_cbc, 64) - || !add_cipher_smcap(smcap, NID_des_cbc, -1) - || !add_cipher_smcap(smcap, NID_rc2_cbc, 40) - || !PKCS7_add_attrib_smimecap(si, smcap)) - goto err; - sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); - smcap = NULL; - } - if (flags & PKCS7_REUSE_DIGEST) { - if (!pkcs7_copy_existing_digest(p7, si)) - goto err; - if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si)) - goto err; - } - } - return si; - err: - if (smcap) - sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); - return NULL; -} - -/* - * Search for a digest matching SignerInfo digest type and if found copy - * across. - */ - -static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) -{ - int i; - STACK_OF(PKCS7_SIGNER_INFO) *sinfos; - PKCS7_SIGNER_INFO *sitmp; - ASN1_OCTET_STRING *osdig = NULL; - sinfos = PKCS7_get_signer_info(p7); - for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { - sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); - if (si == sitmp) - break; - if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) - continue; - if (!OBJ_cmp(si->digest_alg->algorithm, sitmp->digest_alg->algorithm)) { - osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); - break; - } - - } - - if (osdig) - return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); - - PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, - PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); - return 0; -} - -int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, - BIO *indata, BIO *out, int flags) -{ - STACK_OF(X509) *signers; - X509 *signer; - STACK_OF(PKCS7_SIGNER_INFO) *sinfos; - PKCS7_SIGNER_INFO *si; - X509_STORE_CTX cert_ctx; - char buf[4096]; - int i, j = 0, k, ret = 0; - BIO *p7bio = NULL; - BIO *tmpin = NULL, *tmpout = NULL; - - if (!p7) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER); - return 0; - } - - if (!PKCS7_type_is_signed(p7)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE); - return 0; - } - - /* Check for no data and no content: no data to verify signature */ - if (PKCS7_get_detached(p7) && !indata) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT); - return 0; - } -#if 0 - /* - * NB: this test commented out because some versions of Netscape - * illegally include zero length content when signing data. Also - * Microsoft Authenticode includes a SpcIndirectDataContent data - * structure which describes the content to be protected by the - * signature, rather than directly embedding that content. So - * Authenticode implementations are also expected to use - * PKCS7_verify() with explicit external data, on non-detached - * PKCS#7 signatures. - * - * In OpenSSL 1.1 a new flag PKCS7_NO_DUAL_CONTENT has been - * introduced to disable this sanity check. For the 1.0.2 branch - * this change is not acceptable, so the check remains completely - * commented out (as it has been for a long time). - */ - - /* Check for data and content: two sets of data */ - if (!PKCS7_get_detached(p7) && indata) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT); - return 0; - } -#endif - - sinfos = PKCS7_get_signer_info(p7); - - if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA); - return 0; - } - - signers = PKCS7_get0_signers(p7, certs, flags); - if (!signers) - return 0; - - /* Now verify the certificates */ - - if (!(flags & PKCS7_NOVERIFY)) - for (k = 0; k < sk_X509_num(signers); k++) { - signer = sk_X509_value(signers, k); - if (!(flags & PKCS7_NOCHAIN)) { - if (!X509_STORE_CTX_init(&cert_ctx, store, signer, - p7->d.sign->cert)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); - goto err; - } - X509_STORE_CTX_set_default(&cert_ctx, "smime_sign"); - } else if (!X509_STORE_CTX_init(&cert_ctx, store, signer, NULL)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); - goto err; - } - if (!(flags & PKCS7_NOCRL)) - X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); - i = X509_verify_cert(&cert_ctx); - if (i <= 0) - j = X509_STORE_CTX_get_error(&cert_ctx); - X509_STORE_CTX_cleanup(&cert_ctx); - if (i <= 0) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, - PKCS7_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(j)); - goto err; - } - /* Check for revocation status here */ - } - - /* - * Performance optimization: if the content is a memory BIO then store - * its contents in a temporary read only memory BIO. This avoids - * potentially large numbers of slow copies of data which will occur when - * reading from a read write memory BIO when signatures are calculated. - */ - - if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) { - char *ptr; - long len; - len = BIO_get_mem_data(indata, &ptr); - tmpin = BIO_new_mem_buf(ptr, len); - if (tmpin == NULL) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - } else - tmpin = indata; - - if (!(p7bio = PKCS7_dataInit(p7, tmpin))) - goto err; - - if (flags & PKCS7_TEXT) { - if (!(tmpout = BIO_new(BIO_s_mem()))) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - BIO_set_mem_eof_return(tmpout, 0); - } else - tmpout = out; - - /* We now have to 'read' from p7bio to calculate digests etc. */ - for (;;) { - i = BIO_read(p7bio, buf, sizeof(buf)); - if (i <= 0) - break; - if (tmpout) - BIO_write(tmpout, buf, i); - } - - if (flags & PKCS7_TEXT) { - if (!SMIME_text(tmpout, out)) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR); - BIO_free(tmpout); - goto err; - } - BIO_free(tmpout); - } - - /* Now Verify All Signatures */ - if (!(flags & PKCS7_NOSIGS)) - for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { - si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); - signer = sk_X509_value(signers, i); - j = PKCS7_signatureVerify(p7bio, p7, si, signer); - if (j <= 0) { - PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE); - goto err; - } - } - - ret = 1; - - err: - if (tmpin == indata) { - if (indata) - BIO_pop(p7bio); - } - BIO_free_all(p7bio); - sk_X509_free(signers); - return ret; -} - -STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, - int flags) -{ - STACK_OF(X509) *signers; - STACK_OF(PKCS7_SIGNER_INFO) *sinfos; - PKCS7_SIGNER_INFO *si; - PKCS7_ISSUER_AND_SERIAL *ias; - X509 *signer; - int i; - - if (!p7) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER); - return NULL; - } - - if (!PKCS7_type_is_signed(p7)) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE); - return NULL; - } - - /* Collect all the signers together */ - - sinfos = PKCS7_get_signer_info(p7); - - if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS); - return 0; - } - - if (!(signers = sk_X509_new_null())) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { - si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); - ias = si->issuer_and_serial; - signer = NULL; - /* If any certificates passed they take priority */ - if (certs) - signer = X509_find_by_issuer_and_serial(certs, - ias->issuer, ias->serial); - if (!signer && !(flags & PKCS7_NOINTERN) - && p7->d.sign->cert) - signer = - X509_find_by_issuer_and_serial(p7->d.sign->cert, - ias->issuer, ias->serial); - if (!signer) { - PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, - PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); - sk_X509_free(signers); - return 0; - } - - if (!sk_X509_push(signers, signer)) { - sk_X509_free(signers); - return NULL; - } - } - return signers; -} - -/* Build a complete PKCS#7 enveloped data */ - -PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, - int flags) -{ - PKCS7 *p7; - BIO *p7bio = NULL; - int i; - X509 *x509; - if (!(p7 = PKCS7_new())) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) - goto err; - if (!PKCS7_set_cipher(p7, cipher)) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER); - goto err; - } - - for (i = 0; i < sk_X509_num(certs); i++) { - x509 = sk_X509_value(certs, i); - if (!PKCS7_add_recipient(p7, x509)) { - PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT); - goto err; - } - } - - if (flags & PKCS7_STREAM) - return p7; - - if (PKCS7_final(p7, in, flags)) - return p7; - - err: - - BIO_free_all(p7bio); - PKCS7_free(p7); - return NULL; - -} - -int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) -{ - BIO *tmpmem; - int ret, i; - char buf[4096]; - - if (!p7) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER); - return 0; - } - - if (!PKCS7_type_is_enveloped(p7)) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE); - return 0; - } - - if (cert && !X509_check_private_key(cert, pkey)) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, - PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); - return 0; - } - - if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR); - return 0; - } - - if (flags & PKCS7_TEXT) { - BIO *tmpbuf, *bread; - /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ - if (!(tmpbuf = BIO_new(BIO_f_buffer()))) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); - BIO_free_all(tmpmem); - return 0; - } - if (!(bread = BIO_push(tmpbuf, tmpmem))) { - PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); - BIO_free_all(tmpbuf); - BIO_free_all(tmpmem); - return 0; - } - ret = SMIME_text(bread, data); - if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { - if (!BIO_get_cipher_status(tmpmem)) - ret = 0; - } - BIO_free_all(bread); - return ret; - } else { - for (;;) { - i = BIO_read(tmpmem, buf, sizeof(buf)); - if (i <= 0) { - ret = 1; - if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { - if (!BIO_get_cipher_status(tmpmem)) - ret = 0; - } - - break; - } - if (BIO_write(data, buf, i) != i) { - ret = 0; - break; - } - } - BIO_free_all(tmpmem); - return ret; - } -} diff --git a/Sources/COpenSSL/pk7_enc.h b/Sources/COpenSSL/pk7_enc.h deleted file mode 100644 index f3f4c7ff..00000000 --- a/Sources/COpenSSL/pk7_enc.h +++ /dev/null @@ -1,75 +0,0 @@ -/* crypto/pkcs7/pk7_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "rand.h" -#include "objects.h" -#include "x509.h" -#include "pkcs7.h" - -PKCS7_in_bio(PKCS7 *p7, BIO *in); -PKCS7_out_bio(PKCS7 *p7, BIO *out); - -PKCS7_add_signer(PKCS7 *p7, X509 *cert, EVP_PKEY *key); -PKCS7_cipher(PKCS7 *p7, EVP_CIPHER *cipher); - -PKCS7_Init(PKCS7 *p7); -PKCS7_Update(PKCS7 *p7); -PKCS7_Finish(PKCS7 *p7); diff --git a/Sources/COpenSSL/pkcs12.h b/Sources/COpenSSL/pkcs12.h deleted file mode 100644 index 8674a34a..00000000 --- a/Sources/COpenSSL/pkcs12.h +++ /dev/null @@ -1,342 +0,0 @@ -/* pkcs12.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_PKCS12_H -# define HEADER_PKCS12_H - -# include "bio.h" -# include "x509.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# define PKCS12_KEY_ID 1 -# define PKCS12_IV_ID 2 -# define PKCS12_MAC_ID 3 - -/* Default iteration count */ -# ifndef PKCS12_DEFAULT_ITER -# define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER -# endif - -# define PKCS12_MAC_KEY_LENGTH 20 - -# define PKCS12_SALT_LEN 8 - -/* Uncomment out next line for unicode password and names, otherwise ASCII */ - -/* - * #define PBE_UNICODE - */ - -# ifdef PBE_UNICODE -# define PKCS12_key_gen PKCS12_key_gen_uni -# define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni -# else -# define PKCS12_key_gen PKCS12_key_gen_asc -# define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc -# endif - -/* MS key usage constants */ - -# define KEY_EX 0x10 -# define KEY_SIG 0x80 - -typedef struct { - X509_SIG *dinfo; - ASN1_OCTET_STRING *salt; - ASN1_INTEGER *iter; /* defaults to 1 */ -} PKCS12_MAC_DATA; - -typedef struct { - ASN1_INTEGER *version; - PKCS12_MAC_DATA *mac; - PKCS7 *authsafes; -} PKCS12; - -typedef struct { - ASN1_OBJECT *type; - union { - struct pkcs12_bag_st *bag; /* secret, crl and certbag */ - struct pkcs8_priv_key_info_st *keybag; /* keybag */ - X509_SIG *shkeybag; /* shrouded key bag */ - STACK_OF(PKCS12_SAFEBAG) *safes; - ASN1_TYPE *other; - } value; - STACK_OF(X509_ATTRIBUTE) *attrib; -} PKCS12_SAFEBAG; - -DECLARE_STACK_OF(PKCS12_SAFEBAG) -DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG) -DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG) - -typedef struct pkcs12_bag_st { - ASN1_OBJECT *type; - union { - ASN1_OCTET_STRING *x509cert; - ASN1_OCTET_STRING *x509crl; - ASN1_OCTET_STRING *octet; - ASN1_IA5STRING *sdsicert; - ASN1_TYPE *other; /* Secret or other bag */ - } value; -} PKCS12_BAGS; - -# define PKCS12_ERROR 0 -# define PKCS12_OK 1 - -/* Compatibility macros */ - -# define M_PKCS12_x5092certbag PKCS12_x5092certbag -# define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag - -# define M_PKCS12_certbag2x509 PKCS12_certbag2x509 -# define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl - -# define M_PKCS12_unpack_p7data PKCS12_unpack_p7data -# define M_PKCS12_pack_authsafes PKCS12_pack_authsafes -# define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes -# define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata - -# define M_PKCS12_decrypt_skey PKCS12_decrypt_skey -# define M_PKCS8_decrypt PKCS8_decrypt - -# define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type) -# define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type) -# define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type - -# define PKCS12_get_attr(bag, attr_nid) \ - PKCS12_get_attr_gen(bag->attrib, attr_nid) - -# define PKCS8_get_attr(p8, attr_nid) \ - PKCS12_get_attr_gen(p8->attributes, attr_nid) - -# define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0) - -PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509); -PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl); -X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag); -X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag); - -PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, - int nid1, int nid2); -PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8); -PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, - int passlen); -PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, - const char *pass, int passlen); -X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, - const char *pass, int passlen, unsigned char *salt, - int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); -PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, - int passlen, unsigned char *salt, - int saltlen, int iter, - PKCS8_PRIV_KEY_INFO *p8); -PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); -STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); -PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, - unsigned char *salt, int saltlen, int iter, - STACK_OF(PKCS12_SAFEBAG) *bags); -STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, - int passlen); - -int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); -STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12); - -int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, - int namelen); -int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, - int namelen); -int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, - int namelen); -int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, - const unsigned char *name, int namelen); -int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); -ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid); -char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); -unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, - int passlen, unsigned char *in, int inlen, - unsigned char **data, int *datalen, - int en_de); -void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, - const char *pass, int passlen, - ASN1_OCTET_STRING *oct, int zbuf); -ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, - const ASN1_ITEM *it, - const char *pass, int passlen, - void *obj, int zbuf); -PKCS12 *PKCS12_init(int mode); -int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, - int saltlen, int id, int iter, int n, - unsigned char *out, const EVP_MD *md_type); -int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, - int saltlen, int id, int iter, int n, - unsigned char *out, const EVP_MD *md_type); -int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, - ASN1_TYPE *param, const EVP_CIPHER *cipher, - const EVP_MD *md_type, int en_de); -int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, - unsigned char *mac, unsigned int *maclen); -int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); -int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, - unsigned char *salt, int saltlen, int iter, - const EVP_MD *md_type); -int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, - int saltlen, const EVP_MD *md_type); -unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, - unsigned char **uni, int *unilen); -char *OPENSSL_uni2asc(unsigned char *uni, int unilen); - -DECLARE_ASN1_FUNCTIONS(PKCS12) -DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) -DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) -DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) - -DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) -DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) - -void PKCS12_PBE_add(void); -int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, - STACK_OF(X509) **ca); -PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, - STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, - int mac_iter, int keytype); - -PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); -PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, - EVP_PKEY *key, int key_usage, int iter, - int key_nid, char *pass); -int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, - int safe_nid, int iter, char *pass); -PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); - -int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); -int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); -PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); -PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); -int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_PKCS12_strings(void); - -/* Error codes for the PKCS12 functions. */ - -/* Function codes. */ -# define PKCS12_F_PARSE_BAG 129 -# define PKCS12_F_PARSE_BAGS 103 -# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME 100 -# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC 127 -# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI 102 -# define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 -# define PKCS12_F_PKCS12_CREATE 105 -# define PKCS12_F_PKCS12_GEN_MAC 107 -# define PKCS12_F_PKCS12_INIT 109 -# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 -# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 -# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 -# define PKCS12_F_PKCS12_KEY_GEN_ASC 110 -# define PKCS12_F_PKCS12_KEY_GEN_UNI 111 -# define PKCS12_F_PKCS12_MAKE_KEYBAG 112 -# define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 -# define PKCS12_F_PKCS12_NEWPASS 128 -# define PKCS12_F_PKCS12_PACK_P7DATA 114 -# define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 -# define PKCS12_F_PKCS12_PARSE 118 -# define PKCS12_F_PKCS12_PBE_CRYPT 119 -# define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 -# define PKCS12_F_PKCS12_SETUP_MAC 122 -# define PKCS12_F_PKCS12_SET_MAC 123 -# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 -# define PKCS12_F_PKCS12_UNPACK_P7DATA 131 -# define PKCS12_F_PKCS12_VERIFY_MAC 126 -# define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 -# define PKCS12_F_PKCS8_ENCRYPT 125 - -/* Reason codes. */ -# define PKCS12_R_CANT_PACK_STRUCTURE 100 -# define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 -# define PKCS12_R_DECODE_ERROR 101 -# define PKCS12_R_ENCODE_ERROR 102 -# define PKCS12_R_ENCRYPT_ERROR 103 -# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 -# define PKCS12_R_INVALID_NULL_ARGUMENT 104 -# define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 -# define PKCS12_R_IV_GEN_ERROR 106 -# define PKCS12_R_KEY_GEN_ERROR 107 -# define PKCS12_R_MAC_ABSENT 108 -# define PKCS12_R_MAC_GENERATION_ERROR 109 -# define PKCS12_R_MAC_SETUP_ERROR 110 -# define PKCS12_R_MAC_STRING_SET_ERROR 111 -# define PKCS12_R_MAC_VERIFY_ERROR 112 -# define PKCS12_R_MAC_VERIFY_FAILURE 113 -# define PKCS12_R_PARSE_ERROR 114 -# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 -# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 -# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 -# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 -# define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/pkcs7.h b/Sources/COpenSSL/pkcs7.h deleted file mode 100644 index 64f8a659..00000000 --- a/Sources/COpenSSL/pkcs7.h +++ /dev/null @@ -1,481 +0,0 @@ -/* crypto/pkcs7/pkcs7.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_PKCS7_H -# define HEADER_PKCS7_H - -# include "asn1.h" -# include "bio.h" -# include "e_os2.h" - -# include "symhacks.h" -# include "ossl_typ.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef OPENSSL_SYS_WIN32 -/* Under Win32 thes are defined in wincrypt.h */ -# undef PKCS7_ISSUER_AND_SERIAL -# undef PKCS7_SIGNER_INFO -# endif - -/*- -Encryption_ID DES-CBC -Digest_ID MD5 -Digest_Encryption_ID rsaEncryption -Key_Encryption_ID rsaEncryption -*/ - -typedef struct pkcs7_issuer_and_serial_st { - X509_NAME *issuer; - ASN1_INTEGER *serial; -} PKCS7_ISSUER_AND_SERIAL; - -typedef struct pkcs7_signer_info_st { - ASN1_INTEGER *version; /* version 1 */ - PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; - X509_ALGOR *digest_alg; - STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ - X509_ALGOR *digest_enc_alg; - ASN1_OCTET_STRING *enc_digest; - STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ - /* The private key to sign with */ - EVP_PKEY *pkey; -} PKCS7_SIGNER_INFO; - -DECLARE_STACK_OF(PKCS7_SIGNER_INFO) -DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) - -typedef struct pkcs7_recip_info_st { - ASN1_INTEGER *version; /* version 0 */ - PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; - X509_ALGOR *key_enc_algor; - ASN1_OCTET_STRING *enc_key; - X509 *cert; /* get the pub-key from this */ -} PKCS7_RECIP_INFO; - -DECLARE_STACK_OF(PKCS7_RECIP_INFO) -DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) - -typedef struct pkcs7_signed_st { - ASN1_INTEGER *version; /* version 1 */ - STACK_OF(X509_ALGOR) *md_algs; /* md used */ - STACK_OF(X509) *cert; /* [ 0 ] */ - STACK_OF(X509_CRL) *crl; /* [ 1 ] */ - STACK_OF(PKCS7_SIGNER_INFO) *signer_info; - struct pkcs7_st *contents; -} PKCS7_SIGNED; -/* - * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about - * merging the two - */ - -typedef struct pkcs7_enc_content_st { - ASN1_OBJECT *content_type; - X509_ALGOR *algorithm; - ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ - const EVP_CIPHER *cipher; -} PKCS7_ENC_CONTENT; - -typedef struct pkcs7_enveloped_st { - ASN1_INTEGER *version; /* version 0 */ - STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; - PKCS7_ENC_CONTENT *enc_data; -} PKCS7_ENVELOPE; - -typedef struct pkcs7_signedandenveloped_st { - ASN1_INTEGER *version; /* version 1 */ - STACK_OF(X509_ALGOR) *md_algs; /* md used */ - STACK_OF(X509) *cert; /* [ 0 ] */ - STACK_OF(X509_CRL) *crl; /* [ 1 ] */ - STACK_OF(PKCS7_SIGNER_INFO) *signer_info; - PKCS7_ENC_CONTENT *enc_data; - STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; -} PKCS7_SIGN_ENVELOPE; - -typedef struct pkcs7_digest_st { - ASN1_INTEGER *version; /* version 0 */ - X509_ALGOR *md; /* md used */ - struct pkcs7_st *contents; - ASN1_OCTET_STRING *digest; -} PKCS7_DIGEST; - -typedef struct pkcs7_encrypted_st { - ASN1_INTEGER *version; /* version 0 */ - PKCS7_ENC_CONTENT *enc_data; -} PKCS7_ENCRYPT; - -typedef struct pkcs7_st { - /* - * The following is non NULL if it contains ASN1 encoding of this - * structure - */ - unsigned char *asn1; - long length; -# define PKCS7_S_HEADER 0 -# define PKCS7_S_BODY 1 -# define PKCS7_S_TAIL 2 - int state; /* used during processing */ - int detached; - ASN1_OBJECT *type; - /* content as defined by the type */ - /* - * all encryption/message digests are applied to the 'contents', leaving - * out the 'type' field. - */ - union { - char *ptr; - /* NID_pkcs7_data */ - ASN1_OCTET_STRING *data; - /* NID_pkcs7_signed */ - PKCS7_SIGNED *sign; - /* NID_pkcs7_enveloped */ - PKCS7_ENVELOPE *enveloped; - /* NID_pkcs7_signedAndEnveloped */ - PKCS7_SIGN_ENVELOPE *signed_and_enveloped; - /* NID_pkcs7_digest */ - PKCS7_DIGEST *digest; - /* NID_pkcs7_encrypted */ - PKCS7_ENCRYPT *encrypted; - /* Anything else */ - ASN1_TYPE *other; - } d; -} PKCS7; - -DECLARE_STACK_OF(PKCS7) -DECLARE_ASN1_SET_OF(PKCS7) -DECLARE_PKCS12_STACK_OF(PKCS7) - -# define PKCS7_OP_SET_DETACHED_SIGNATURE 1 -# define PKCS7_OP_GET_DETACHED_SIGNATURE 2 - -# define PKCS7_get_signed_attributes(si) ((si)->auth_attr) -# define PKCS7_get_attributes(si) ((si)->unauth_attr) - -# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) -# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) -# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) -# define PKCS7_type_is_signedAndEnveloped(a) \ - (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) -# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) -# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) - -# define PKCS7_set_detached(p,v) \ - PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) -# define PKCS7_get_detached(p) \ - PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) - -# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) - -/* S/MIME related flags */ - -# define PKCS7_TEXT 0x1 -# define PKCS7_NOCERTS 0x2 -# define PKCS7_NOSIGS 0x4 -# define PKCS7_NOCHAIN 0x8 -# define PKCS7_NOINTERN 0x10 -# define PKCS7_NOVERIFY 0x20 -# define PKCS7_DETACHED 0x40 -# define PKCS7_BINARY 0x80 -# define PKCS7_NOATTR 0x100 -# define PKCS7_NOSMIMECAP 0x200 -# define PKCS7_NOOLDMIMETYPE 0x400 -# define PKCS7_CRLFEOL 0x800 -# define PKCS7_STREAM 0x1000 -# define PKCS7_NOCRL 0x2000 -# define PKCS7_PARTIAL 0x4000 -# define PKCS7_REUSE_DIGEST 0x8000 - -/* Flags: for compatibility with older code */ - -# define SMIME_TEXT PKCS7_TEXT -# define SMIME_NOCERTS PKCS7_NOCERTS -# define SMIME_NOSIGS PKCS7_NOSIGS -# define SMIME_NOCHAIN PKCS7_NOCHAIN -# define SMIME_NOINTERN PKCS7_NOINTERN -# define SMIME_NOVERIFY PKCS7_NOVERIFY -# define SMIME_DETACHED PKCS7_DETACHED -# define SMIME_BINARY PKCS7_BINARY -# define SMIME_NOATTR PKCS7_NOATTR - -DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) - -int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, - const EVP_MD *type, unsigned char *md, - unsigned int *len); -# ifndef OPENSSL_NO_FP_API -PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); -int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); -# endif -PKCS7 *PKCS7_dup(PKCS7 *p7); -PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); -int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); -int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); -int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); - -DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) -DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) -DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) -DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) -DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) -DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) -DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) -DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) -DECLARE_ASN1_FUNCTIONS(PKCS7) - -DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) -DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) - -DECLARE_ASN1_NDEF_FUNCTION(PKCS7) -DECLARE_ASN1_PRINT_FUNCTION(PKCS7) - -long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); - -int PKCS7_set_type(PKCS7 *p7, int type); -int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); -int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); -int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, - const EVP_MD *dgst); -int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); -int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); -int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); -int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); -int PKCS7_content_new(PKCS7 *p7, int nid); -int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, - BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); -int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, - X509 *x509); - -BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); -int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); -BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); - -PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, - EVP_PKEY *pkey, const EVP_MD *dgst); -X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); -int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); -STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); - -PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); -void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, - X509_ALGOR **pdig, X509_ALGOR **psig); -void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); -int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); -int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); -int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); -int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); - -PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); -ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); -int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, - void *data); -int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, - void *value); -ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); -ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); -int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, - STACK_OF(X509_ATTRIBUTE) *sk); -int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, - STACK_OF(X509_ATTRIBUTE) *sk); - -PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, - BIO *data, int flags); - -PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, - X509 *signcert, EVP_PKEY *pkey, - const EVP_MD *md, int flags); - -int PKCS7_final(PKCS7 *p7, BIO *data, int flags); -int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, - BIO *indata, BIO *out, int flags); -STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, - int flags); -PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, - int flags); -int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, - int flags); - -int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, - STACK_OF(X509_ALGOR) *cap); -STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); -int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); - -int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); -int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); -int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, - const unsigned char *md, int mdlen); - -int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); -PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); - -BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_PKCS7_strings(void); - -/* Error codes for the PKCS7 functions. */ - -/* Function codes. */ -# define PKCS7_F_B64_READ_PKCS7 120 -# define PKCS7_F_B64_WRITE_PKCS7 121 -# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 -# define PKCS7_F_I2D_PKCS7_BIO_STREAM 140 -# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 -# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 -# define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 -# define PKCS7_F_PKCS7_ADD_CRL 101 -# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 -# define PKCS7_F_PKCS7_ADD_SIGNATURE 131 -# define PKCS7_F_PKCS7_ADD_SIGNER 103 -# define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 -# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 -# define PKCS7_F_PKCS7_CTRL 104 -# define PKCS7_F_PKCS7_DATADECODE 112 -# define PKCS7_F_PKCS7_DATAFINAL 128 -# define PKCS7_F_PKCS7_DATAINIT 105 -# define PKCS7_F_PKCS7_DATASIGN 106 -# define PKCS7_F_PKCS7_DATAVERIFY 107 -# define PKCS7_F_PKCS7_DECRYPT 114 -# define PKCS7_F_PKCS7_DECRYPT_RINFO 133 -# define PKCS7_F_PKCS7_ENCODE_RINFO 132 -# define PKCS7_F_PKCS7_ENCRYPT 115 -# define PKCS7_F_PKCS7_FINAL 134 -# define PKCS7_F_PKCS7_FIND_DIGEST 127 -# define PKCS7_F_PKCS7_GET0_SIGNERS 124 -# define PKCS7_F_PKCS7_RECIP_INFO_SET 130 -# define PKCS7_F_PKCS7_SET_CIPHER 108 -# define PKCS7_F_PKCS7_SET_CONTENT 109 -# define PKCS7_F_PKCS7_SET_DIGEST 126 -# define PKCS7_F_PKCS7_SET_TYPE 110 -# define PKCS7_F_PKCS7_SIGN 116 -# define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 -# define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 -# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 -# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 -# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 -# define PKCS7_F_PKCS7_VERIFY 117 -# define PKCS7_F_SMIME_READ_PKCS7 122 -# define PKCS7_F_SMIME_TEXT 123 - -/* Reason codes. */ -# define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 -# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 -# define PKCS7_R_CIPHER_NOT_INITIALIZED 116 -# define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 -# define PKCS7_R_CTRL_ERROR 152 -# define PKCS7_R_DECODE_ERROR 130 -# define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 -# define PKCS7_R_DECRYPT_ERROR 119 -# define PKCS7_R_DIGEST_FAILURE 101 -# define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 -# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 -# define PKCS7_R_ERROR_ADDING_RECIPIENT 120 -# define PKCS7_R_ERROR_SETTING_CIPHER 121 -# define PKCS7_R_INVALID_MIME_TYPE 131 -# define PKCS7_R_INVALID_NULL_POINTER 143 -# define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155 -# define PKCS7_R_MIME_NO_CONTENT_TYPE 132 -# define PKCS7_R_MIME_PARSE_ERROR 133 -# define PKCS7_R_MIME_SIG_PARSE_ERROR 134 -# define PKCS7_R_MISSING_CERIPEND_INFO 103 -# define PKCS7_R_NO_CONTENT 122 -# define PKCS7_R_NO_CONTENT_TYPE 135 -# define PKCS7_R_NO_DEFAULT_DIGEST 151 -# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 -# define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 -# define PKCS7_R_NO_MULTIPART_BOUNDARY 137 -# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 -# define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146 -# define PKCS7_R_NO_SIGNATURES_ON_DATA 123 -# define PKCS7_R_NO_SIGNERS 142 -# define PKCS7_R_NO_SIG_CONTENT_TYPE 138 -# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 -# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 -# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 -# define PKCS7_R_PKCS7_DATAFINAL 126 -# define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 -# define PKCS7_R_PKCS7_DATASIGN 145 -# define PKCS7_R_PKCS7_PARSE_ERROR 139 -# define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140 -# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 -# define PKCS7_R_SIGNATURE_FAILURE 105 -# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 -# define PKCS7_R_SIGNING_CTRL_FAILURE 147 -# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 -# define PKCS7_R_SIG_INVALID_MIME_TYPE 141 -# define PKCS7_R_SMIME_TEXT_ERROR 129 -# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 -# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 -# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 -# define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 -# define PKCS7_R_UNKNOWN_OPERATION 110 -# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 -# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 -# define PKCS7_R_WRONG_CONTENT_TYPE 113 -# define PKCS7_R_WRONG_PKCS7_TYPE 114 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/pkcs7err.c b/Sources/COpenSSL/pkcs7err.c deleted file mode 100644 index 57a43435..00000000 --- a/Sources/COpenSSL/pkcs7err.c +++ /dev/null @@ -1,207 +0,0 @@ -/* crypto/pkcs7/pkcs7err.c */ -/* ==================================================================== - * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "pkcs7.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason) - -static ERR_STRING_DATA PKCS7_str_functs[] = { - {ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"}, - {ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"}, - {ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB), "DO_PKCS7_SIGNED_ATTRIB"}, - {ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM), "i2d_PKCS7_bio_stream"}, - {ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME), - "PKCS7_add0_attrib_signing_time"}, - {ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), - "PKCS7_add_attrib_smimecap"}, - {ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"}, - {ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"}, - {ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"}, - {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"}, - {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"}, - {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"}, - {ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST), - "PKCS7_COPY_EXISTING_DIGEST"}, - {ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"}, - {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"}, - {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"}, - {ERR_FUNC(PKCS7_F_PKCS7_DATAINIT), "PKCS7_dataInit"}, - {ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"}, - {ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"}, - {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"}, - {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "PKCS7_DECRYPT_RINFO"}, - {ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "PKCS7_ENCODE_RINFO"}, - {ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"}, - {ERR_FUNC(PKCS7_F_PKCS7_FINAL), "PKCS7_final"}, - {ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"}, - {ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"}, - {ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET), "PKCS7_RECIP_INFO_set"}, - {ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"}, - {ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"}, - {ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"}, - {ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"}, - {ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"}, - {ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"}, - {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"}, - {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"}, - {ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"}, - {ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"}, - {ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"}, - {ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"}, - {ERR_FUNC(PKCS7_F_SMIME_TEXT), "SMIME_text"}, - {0, NULL} -}; - -static ERR_STRING_DATA PKCS7_str_reasons[] = { - {ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR), - "certificate verify error"}, - {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), - "cipher has no object identifier"}, - {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED), "cipher not initialized"}, - {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT), - "content and data present"}, - {ERR_REASON(PKCS7_R_CTRL_ERROR), "ctrl error"}, - {ERR_REASON(PKCS7_R_DECODE_ERROR), "decode error"}, - {ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH), - "decrypted key is wrong length"}, - {ERR_REASON(PKCS7_R_DECRYPT_ERROR), "decrypt error"}, - {ERR_REASON(PKCS7_R_DIGEST_FAILURE), "digest failure"}, - {ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE), "encryption ctrl failure"}, - {ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), - "encryption not supported for this key type"}, - {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT), "error adding recipient"}, - {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER), "error setting cipher"}, - {ERR_REASON(PKCS7_R_INVALID_MIME_TYPE), "invalid mime type"}, - {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"}, - {ERR_REASON(PKCS7_R_INVALID_SIGNED_DATA_TYPE), - "invalid signed data type"}, - {ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE), "mime no content type"}, - {ERR_REASON(PKCS7_R_MIME_PARSE_ERROR), "mime parse error"}, - {ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"}, - {ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO), "missing ceripend info"}, - {ERR_REASON(PKCS7_R_NO_CONTENT), "no content"}, - {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE), "no content type"}, - {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST), "no default digest"}, - {ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND), - "no matching digest type found"}, - {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE), - "no multipart body failure"}, - {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"}, - {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE), - "no recipient matches certificate"}, - {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY), - "no recipient matches key"}, - {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"}, - {ERR_REASON(PKCS7_R_NO_SIGNERS), "no signers"}, - {ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE), "no sig content type"}, - {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE), - "operation not supported on this type"}, - {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR), - "pkcs7 add signature error"}, - {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR), "pkcs7 add signer error"}, - {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL), "pkcs7 datafinal"}, - {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR), "pkcs7 datafinal error"}, - {ERR_REASON(PKCS7_R_PKCS7_DATASIGN), "pkcs7 datasign"}, - {ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR), "pkcs7 parse error"}, - {ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR), "pkcs7 sig parse error"}, - {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), - "private key does not match certificate"}, - {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE), "signature failure"}, - {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND), - "signer certificate not found"}, - {ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE), "signing ctrl failure"}, - {ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), - "signing not supported for this key type"}, - {ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"}, - {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR), "smime text error"}, - {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE), - "unable to find certificate"}, - {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"}, - {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST), - "unable to find message digest"}, - {ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE), "unknown digest type"}, - {ERR_REASON(PKCS7_R_UNKNOWN_OPERATION), "unknown operation"}, - {ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"}, - {ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE), - "unsupported content type"}, - {ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE), "wrong content type"}, - {ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE), "wrong pkcs7 type"}, - {0, NULL} -}; - -#endif - -void ERR_load_PKCS7_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) { - ERR_load_strings(0, PKCS7_str_functs); - ERR_load_strings(0, PKCS7_str_reasons); - } -#endif -} diff --git a/Sources/COpenSSL/pmeth_.c b/Sources/COpenSSL/pmeth_.c deleted file mode 100644 index 5a59488f..00000000 --- a/Sources/COpenSSL/pmeth_.c +++ /dev/null @@ -1,1328 +0,0 @@ -/* pmeth_fn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "cryptlib.h" -#include "objects.h" -#include "evp.h" -#include "evp_locl.h" - -#define M_check_autoarg(ctx, arg, arglen, err) \ - if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \ - size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ - \ - if (pksize == 0) { \ - EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \ - return 0; \ - } \ - if (!arg) { \ - *arglen = pksize; \ - return 1; \ - } \ - if (*arglen < pksize) { \ - EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \ - return 0; \ - } \ - } - -int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { - EVPerr(EVP_F_EVP_PKEY_SIGN_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_SIGN; - if (!ctx->pmeth->sign_init) - return 1; - ret = ctx->pmeth->sign_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, - unsigned char *sig, size_t *siglen, - const unsigned char *tbs, size_t tbslen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { - EVPerr(EVP_F_EVP_PKEY_SIGN, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_SIGN) { - EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) - return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); -} - -int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_VERIFY; - if (!ctx->pmeth->verify_init) - return 1; - ret = ctx->pmeth->verify_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { - EVPerr(EVP_F_EVP_PKEY_VERIFY, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_VERIFY) { - EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); -} - -int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; - if (!ctx->pmeth->verify_recover_init) - return 1; - ret = ctx->pmeth->verify_recover_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, - unsigned char *rout, size_t *routlen, - const unsigned char *sig, size_t siglen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { - EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) - return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); -} - -int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { - EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_ENCRYPT; - if (!ctx->pmeth->encrypt_init) - return 1; - ret = ctx->pmeth->encrypt_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { - EVPerr(EVP_F_EVP_PKEY_ENCRYPT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { - EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) - return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); -} - -int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { - EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_DECRYPT; - if (!ctx->pmeth->decrypt_init) - return 1; - ret = ctx->pmeth->decrypt_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { - EVPerr(EVP_F_EVP_PKEY_DECRYPT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_DECRYPT) { - EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) - return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); -} - -int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_DERIVE; - if (!ctx->pmeth->derive_init) - return 1; - ret = ctx->pmeth->derive_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) -{ - int ret; - if (!ctx || !ctx->pmeth - || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) - || !ctx->pmeth->ctrl) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_DERIVE - && ctx->operation != EVP_PKEY_OP_ENCRYPT - && ctx->operation != EVP_PKEY_OP_DECRYPT) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, - EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - - ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); - - if (ret <= 0) - return ret; - - if (ret == 2) - return 1; - - if (!ctx->pkey) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); - return -1; - } - - if (ctx->pkey->type != peer->type) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES); - return -1; - } - - /* - * ran@cryptocom.ru: For clarity. The error is if parameters in peer are - * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return - * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 - * (different key types) is impossible here because it is checked earlier. - * -2 is OK for us here, as well as 1, so we can check for 0 only. - */ - if (!EVP_PKEY_missing_parameters(peer) && - !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { - EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS); - return -1; - } - - if (ctx->peerkey) - EVP_PKEY_free(ctx->peerkey); - ctx->peerkey = peer; - - ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); - - if (ret <= 0) { - ctx->peerkey = NULL; - return ret; - } - - CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY); - return 1; -} - -int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { - EVPerr(EVP_F_EVP_PKEY_DERIVE, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_DERIVE) { - EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) - return ctx->pmeth->derive(ctx, key, pkeylen); -} -/* pmeth_gn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "evp.h" -#include "bn.h" -// #include "evp_locl.h" - -int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { - EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_PARAMGEN; - if (!ctx->pmeth->paramgen_init) - return 1; - ret = ctx->pmeth->paramgen_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { - EVPerr(EVP_F_EVP_PKEY_PARAMGEN, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - - if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { - EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - - if (ppkey == NULL) - return -1; - - if (*ppkey == NULL) - *ppkey = EVP_PKEY_new(); - - if (*ppkey == NULL) { - EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE); - return -1; - } - - ret = ctx->pmeth->paramgen(ctx, *ppkey); - if (ret <= 0) { - EVP_PKEY_free(*ppkey); - *ppkey = NULL; - } - return ret; -} - -int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { - EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - ctx->operation = EVP_PKEY_OP_KEYGEN; - if (!ctx->pmeth->keygen_init) - return 1; - ret = ctx->pmeth->keygen_init(ctx); - if (ret <= 0) - ctx->operation = EVP_PKEY_OP_UNDEFINED; - return ret; -} - -int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) -{ - int ret; - - if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { - EVPerr(EVP_F_EVP_PKEY_KEYGEN, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - } - if (ctx->operation != EVP_PKEY_OP_KEYGEN) { - EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED); - return -1; - } - - if (!ppkey) - return -1; - - if (*ppkey == NULL) - *ppkey = EVP_PKEY_new(); - if (*ppkey == NULL) - return -1; - - ret = ctx->pmeth->keygen(ctx, *ppkey); - if (ret <= 0) { - EVP_PKEY_free(*ppkey); - *ppkey = NULL; - } - return ret; -} - -void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) -{ - ctx->pkey_gencb = cb; -} - -EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx) -{ - return ctx->pkey_gencb; -} - -/* - * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style - * callbacks. - */ - -static int trans_cb(int a, int b, BN_GENCB *gcb) -{ - EVP_PKEY_CTX *ctx = gcb->arg; - ctx->keygen_info[0] = a; - ctx->keygen_info[1] = b; - return ctx->pkey_gencb(ctx); -} - -void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx) -{ - BN_GENCB_set(cb, trans_cb, ctx) -} - -int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) -{ - if (idx == -1) - return ctx->keygen_info_count; - if (idx < 0 || idx > ctx->keygen_info_count) - return 0; - return ctx->keygen_info[idx]; -} - -EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, - const unsigned char *key, int keylen) -{ - EVP_PKEY_CTX *mac_ctx = NULL; - EVP_PKEY *mac_key = NULL; - mac_ctx = EVP_PKEY_CTX_new_id(type, e); - if (!mac_ctx) - return NULL; - if (EVP_PKEY_keygen_init(mac_ctx) <= 0) - goto merr; - if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_SET_MAC_KEY, - keylen, (void *)key) <= 0) - goto merr; - if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) - goto merr; - merr: - if (mac_ctx) - EVP_PKEY_CTX_free(mac_ctx); - return mac_key; -} -/* pmeth_lib.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "evp.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -#include "asn1_locl.h" -// #include "evp_locl.h" - -typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); - -DECLARE_STACK_OF(EVP_PKEY_METHOD) -STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; - -extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth; -extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth; -extern const EVP_PKEY_METHOD dhx_pkey_meth; - -static const EVP_PKEY_METHOD *standard_methods[] = { -#ifndef OPENSSL_NO_RSA - &rsa_pkey_meth, -#endif -#ifndef OPENSSL_NO_DH - &dh_pkey_meth, -#endif -#ifndef OPENSSL_NO_DSA - &dsa_pkey_meth, -#endif -#ifndef OPENSSL_NO_EC - &ec_pkey_meth, -#endif - &hmac_pkey_meth, -#ifndef OPENSSL_NO_CMAC - &cmac_pkey_meth, -#endif -#ifndef OPENSSL_NO_DH - &dhx_pkey_meth -#endif -}; - -DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, - pmeth); - -static int pmeth_cmp(const EVP_PKEY_METHOD *const *a, - const EVP_PKEY_METHOD *const *b) -{ - return ((*a)->pkey_id - (*b)->pkey_id); -} - -IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, - pmeth); - -const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) -{ - EVP_PKEY_METHOD tmp; - const EVP_PKEY_METHOD *t = &tmp, **ret; - tmp.pkey_id = type; - if (app_pkey_methods) { - int idx; - idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp); - if (idx >= 0) - return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); - } - ret = OBJ_bsearch_pmeth(&t, standard_methods, - sizeof(standard_methods) / - sizeof(EVP_PKEY_METHOD *)); - if (!ret || !*ret) - return NULL; - return *ret; -} - -static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) -{ - EVP_PKEY_CTX *ret; - const EVP_PKEY_METHOD *pmeth; - if (id == -1) { - if (!pkey || !pkey->ameth) - return NULL; - id = pkey->ameth->pkey_id; - } -#ifndef OPENSSL_NO_ENGINE - if (pkey && pkey->engine) - e = pkey->engine; - /* Try to find an ENGINE which implements this method */ - if (e) { - if (!ENGINE_init(e)) { - EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB); - return NULL; - } - } else - e = ENGINE_get_pkey_meth_engine(id); - - /* - * If an ENGINE handled this method look it up. Othewise use internal - * tables. - */ - - if (e) - pmeth = ENGINE_get_pkey_meth(e, id); - else -#endif - pmeth = EVP_PKEY_meth_find(id); - - if (pmeth == NULL) { - EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); - return NULL; - } - - ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); - if (!ret) { -#ifndef OPENSSL_NO_ENGINE - if (e) - ENGINE_finish(e); -#endif - EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - ret->engine = e; - ret->pmeth = pmeth; - ret->operation = EVP_PKEY_OP_UNDEFINED; - ret->pkey = pkey; - ret->peerkey = NULL; - ret->pkey_gencb = 0; - if (pkey) - CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - ret->data = NULL; - - if (pmeth->init) { - if (pmeth->init(ret) <= 0) { - ret->pmeth = NULL; - EVP_PKEY_CTX_free(ret); - return NULL; - } - } - - return ret; -} - -EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) -{ - EVP_PKEY_METHOD *pmeth; - - pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD)); - if (!pmeth) - return NULL; - - memset(pmeth, 0, sizeof(EVP_PKEY_METHOD)); - - pmeth->pkey_id = id; - pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; - return pmeth; -} - -void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, - const EVP_PKEY_METHOD *meth) -{ - if (ppkey_id) - *ppkey_id = meth->pkey_id; - if (pflags) - *pflags = meth->flags; -} - -void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) -{ - - dst->init = src->init; - dst->copy = src->copy; - dst->cleanup = src->cleanup; - - dst->paramgen_init = src->paramgen_init; - dst->paramgen = src->paramgen; - - dst->keygen_init = src->keygen_init; - dst->keygen = src->keygen; - - dst->sign_init = src->sign_init; - dst->sign = src->sign; - - dst->verify_init = src->verify_init; - dst->verify = src->verify; - - dst->verify_recover_init = src->verify_recover_init; - dst->verify_recover = src->verify_recover; - - dst->signctx_init = src->signctx_init; - dst->signctx = src->signctx; - - dst->verifyctx_init = src->verifyctx_init; - dst->verifyctx = src->verifyctx; - - dst->encrypt_init = src->encrypt_init; - dst->encrypt = src->encrypt; - - dst->decrypt_init = src->decrypt_init; - dst->decrypt = src->decrypt; - - dst->derive_init = src->derive_init; - dst->derive = src->derive; - - dst->ctrl = src->ctrl; - dst->ctrl_str = src->ctrl_str; -} - -void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) -{ - if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC)) - OPENSSL_free(pmeth); -} - -EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) -{ - return int_ctx_new(pkey, e, -1); -} - -EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) -{ - return int_ctx_new(NULL, e, id); -} - -EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) -{ - EVP_PKEY_CTX *rctx; - if (!pctx->pmeth || !pctx->pmeth->copy) - return NULL; -#ifndef OPENSSL_NO_ENGINE - /* Make sure it's safe to copy a pkey context using an ENGINE */ - if (pctx->engine && !ENGINE_init(pctx->engine)) { - EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB); - return 0; - } -#endif - rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); - if (!rctx) - return NULL; - - rctx->pmeth = pctx->pmeth; -#ifndef OPENSSL_NO_ENGINE - rctx->engine = pctx->engine; -#endif - - if (pctx->pkey) - CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - - rctx->pkey = pctx->pkey; - - if (pctx->peerkey) - CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - - rctx->peerkey = pctx->peerkey; - - rctx->data = NULL; - rctx->app_data = NULL; - rctx->operation = pctx->operation; - - if (pctx->pmeth->copy(rctx, pctx) > 0) - return rctx; - - rctx->pmeth = NULL; - EVP_PKEY_CTX_free(rctx); - return NULL; - -} - -int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) -{ - if (app_pkey_methods == NULL) { - app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp); - if (!app_pkey_methods) - return 0; - } - if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) - return 0; - sk_EVP_PKEY_METHOD_sort(app_pkey_methods); - return 1; -} - -void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) -{ - if (ctx == NULL) - return; - if (ctx->pmeth && ctx->pmeth->cleanup) - ctx->pmeth->cleanup(ctx); - if (ctx->pkey) - EVP_PKEY_free(ctx->pkey); - if (ctx->peerkey) - EVP_PKEY_free(ctx->peerkey); -#ifndef OPENSSL_NO_ENGINE - if (ctx->engine) - /* - * The EVP_PKEY_CTX we used belongs to an ENGINE, release the - * functional reference we held for this reason. - */ - ENGINE_finish(ctx->engine); -#endif - OPENSSL_free(ctx); -} - -int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, - int cmd, int p1, void *p2) -{ - int ret; - if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; - } - if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) - return -1; - - if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET); - return -1; - } - - if ((optype != -1) && !(ctx->operation & optype)) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION); - return -1; - } - - ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); - - if (ret == -2) - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); - - return ret; - -} - -int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, - const char *name, const char *value) -{ - if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); - return -2; - } - if (!strcmp(name, "digest")) { - const EVP_MD *md; - if (!value || !(md = EVP_get_digestbyname(value))) { - EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_INVALID_DIGEST); - return 0; - } - return EVP_PKEY_CTX_set_signature_md(ctx, md); - } - return ctx->pmeth->ctrl_str(ctx, name, value); -} - -int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx) -{ - return ctx->operation; -} - -void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen) -{ - ctx->keygen_info = dat; - ctx->keygen_info_count = datlen; -} - -void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data) -{ - ctx->data = data; -} - -void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx) -{ - return ctx->data; -} - -EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) -{ - return ctx->pkey; -} - -EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx) -{ - return ctx->peerkey; -} - -void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) -{ - ctx->app_data = data; -} - -void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) -{ - return ctx->app_data; -} - -void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, - int (*init) (EVP_PKEY_CTX *ctx)) -{ - pmeth->init = init; -} - -void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, - int (*copy) (EVP_PKEY_CTX *dst, - EVP_PKEY_CTX *src)) -{ - pmeth->copy = copy; -} - -void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, - void (*cleanup) (EVP_PKEY_CTX *ctx)) -{ - pmeth->cleanup = cleanup; -} - -void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, - int (*paramgen_init) (EVP_PKEY_CTX *ctx), - int (*paramgen) (EVP_PKEY_CTX *ctx, - EVP_PKEY *pkey)) -{ - pmeth->paramgen_init = paramgen_init; - pmeth->paramgen = paramgen; -} - -void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, - int (*keygen_init) (EVP_PKEY_CTX *ctx), - int (*keygen) (EVP_PKEY_CTX *ctx, - EVP_PKEY *pkey)) -{ - pmeth->keygen_init = keygen_init; - pmeth->keygen = keygen; -} - -void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, - int (*sign_init) (EVP_PKEY_CTX *ctx), - int (*sign) (EVP_PKEY_CTX *ctx, - unsigned char *sig, size_t *siglen, - const unsigned char *tbs, - size_t tbslen)) -{ - pmeth->sign_init = sign_init; - pmeth->sign = sign; -} - -void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, - int (*verify_init) (EVP_PKEY_CTX *ctx), - int (*verify) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, - size_t siglen, - const unsigned char *tbs, - size_t tbslen)) -{ - pmeth->verify_init = verify_init; - pmeth->verify = verify; -} - -void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, - int (*verify_recover_init) (EVP_PKEY_CTX - *ctx), - int (*verify_recover) (EVP_PKEY_CTX - *ctx, - unsigned char - *sig, - size_t *siglen, - const unsigned - char *tbs, - size_t tbslen)) -{ - pmeth->verify_recover_init = verify_recover_init; - pmeth->verify_recover = verify_recover; -} - -void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, - int (*signctx_init) (EVP_PKEY_CTX *ctx, - EVP_MD_CTX *mctx), - int (*signctx) (EVP_PKEY_CTX *ctx, - unsigned char *sig, - size_t *siglen, - EVP_MD_CTX *mctx)) -{ - pmeth->signctx_init = signctx_init; - pmeth->signctx = signctx; -} - -void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, - int (*verifyctx_init) (EVP_PKEY_CTX *ctx, - EVP_MD_CTX *mctx), - int (*verifyctx) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, - int siglen, - EVP_MD_CTX *mctx)) -{ - pmeth->verifyctx_init = verifyctx_init; - pmeth->verifyctx = verifyctx; -} - -void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, - int (*encrypt_init) (EVP_PKEY_CTX *ctx), - int (*encryptfn) (EVP_PKEY_CTX *ctx, - unsigned char *out, - size_t *outlen, - const unsigned char *in, - size_t inlen)) -{ - pmeth->encrypt_init = encrypt_init; - pmeth->encrypt = encryptfn; -} - -void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, - int (*decrypt_init) (EVP_PKEY_CTX *ctx), - int (*decrypt) (EVP_PKEY_CTX *ctx, - unsigned char *out, - size_t *outlen, - const unsigned char *in, - size_t inlen)) -{ - pmeth->decrypt_init = decrypt_init; - pmeth->decrypt = decrypt; -} - -void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, - int (*derive_init) (EVP_PKEY_CTX *ctx), - int (*derive) (EVP_PKEY_CTX *ctx, - unsigned char *key, - size_t *keylen)) -{ - pmeth->derive_init = derive_init; - pmeth->derive = derive; -} - -void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, - int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, - void *p2), - int (*ctrl_str) (EVP_PKEY_CTX *ctx, - const char *type, - const char *value)) -{ - pmeth->ctrl = ctrl; - pmeth->ctrl_str = ctrl_str; -} - -void EVP_PKEY_meth_get_init(EVP_PKEY_METHOD *pmeth, - int (**pinit) (EVP_PKEY_CTX *ctx)) -{ - *pinit = pmeth->init; -} - -void EVP_PKEY_meth_get_copy(EVP_PKEY_METHOD *pmeth, - int (**pcopy) (EVP_PKEY_CTX *dst, - EVP_PKEY_CTX *src)) -{ - *pcopy = pmeth->copy; -} - -void EVP_PKEY_meth_get_cleanup(EVP_PKEY_METHOD *pmeth, - void (**pcleanup) (EVP_PKEY_CTX *ctx)) -{ - *pcleanup = pmeth->cleanup; -} - -void EVP_PKEY_meth_get_paramgen(EVP_PKEY_METHOD *pmeth, - int (**pparamgen_init) (EVP_PKEY_CTX *ctx), - int (**pparamgen) (EVP_PKEY_CTX *ctx, - EVP_PKEY *pkey)) -{ - if (pparamgen_init) - *pparamgen_init = pmeth->paramgen_init; - if (pparamgen) - *pparamgen = pmeth->paramgen; -} - -void EVP_PKEY_meth_get_keygen(EVP_PKEY_METHOD *pmeth, - int (**pkeygen_init) (EVP_PKEY_CTX *ctx), - int (**pkeygen) (EVP_PKEY_CTX *ctx, - EVP_PKEY *pkey)) -{ - if (pkeygen_init) - *pkeygen_init = pmeth->keygen_init; - if (pkeygen) - *pkeygen = pmeth->keygen; -} - -void EVP_PKEY_meth_get_sign(EVP_PKEY_METHOD *pmeth, - int (**psign_init) (EVP_PKEY_CTX *ctx), - int (**psign) (EVP_PKEY_CTX *ctx, - unsigned char *sig, size_t *siglen, - const unsigned char *tbs, - size_t tbslen)) -{ - if (psign_init) - *psign_init = pmeth->sign_init; - if (psign) - *psign = pmeth->sign; -} - -void EVP_PKEY_meth_get_verify(EVP_PKEY_METHOD *pmeth, - int (**pverify_init) (EVP_PKEY_CTX *ctx), - int (**pverify) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, - size_t siglen, - const unsigned char *tbs, - size_t tbslen)) -{ - if (pverify_init) - *pverify_init = pmeth->verify_init; - if (pverify) - *pverify = pmeth->verify; -} - -void EVP_PKEY_meth_get_verify_recover(EVP_PKEY_METHOD *pmeth, - int (**pverify_recover_init) (EVP_PKEY_CTX - *ctx), - int (**pverify_recover) (EVP_PKEY_CTX - *ctx, - unsigned char - *sig, - size_t *siglen, - const unsigned - char *tbs, - size_t tbslen)) -{ - if (pverify_recover_init) - *pverify_recover_init = pmeth->verify_recover_init; - if (pverify_recover) - *pverify_recover = pmeth->verify_recover; -} - -void EVP_PKEY_meth_get_signctx(EVP_PKEY_METHOD *pmeth, - int (**psignctx_init) (EVP_PKEY_CTX *ctx, - EVP_MD_CTX *mctx), - int (**psignctx) (EVP_PKEY_CTX *ctx, - unsigned char *sig, - size_t *siglen, - EVP_MD_CTX *mctx)) -{ - if (psignctx_init) - *psignctx_init = pmeth->signctx_init; - if (psignctx) - *psignctx = pmeth->signctx; -} - -void EVP_PKEY_meth_get_verifyctx(EVP_PKEY_METHOD *pmeth, - int (**pverifyctx_init) (EVP_PKEY_CTX *ctx, - EVP_MD_CTX *mctx), - int (**pverifyctx) (EVP_PKEY_CTX *ctx, - const unsigned char *sig, - int siglen, - EVP_MD_CTX *mctx)) -{ - if (pverifyctx_init) - *pverifyctx_init = pmeth->verifyctx_init; - if (pverifyctx) - *pverifyctx = pmeth->verifyctx; -} - -void EVP_PKEY_meth_get_encrypt(EVP_PKEY_METHOD *pmeth, - int (**pencrypt_init) (EVP_PKEY_CTX *ctx), - int (**pencryptfn) (EVP_PKEY_CTX *ctx, - unsigned char *out, - size_t *outlen, - const unsigned char *in, - size_t inlen)) -{ - if (pencrypt_init) - *pencrypt_init = pmeth->encrypt_init; - if (pencryptfn) - *pencryptfn = pmeth->encrypt; -} - -void EVP_PKEY_meth_get_decrypt(EVP_PKEY_METHOD *pmeth, - int (**pdecrypt_init) (EVP_PKEY_CTX *ctx), - int (**pdecrypt) (EVP_PKEY_CTX *ctx, - unsigned char *out, - size_t *outlen, - const unsigned char *in, - size_t inlen)) -{ - if (pdecrypt_init) - *pdecrypt_init = pmeth->decrypt_init; - if (pdecrypt) - *pdecrypt = pmeth->decrypt; -} - -void EVP_PKEY_meth_get_derive(EVP_PKEY_METHOD *pmeth, - int (**pderive_init) (EVP_PKEY_CTX *ctx), - int (**pderive) (EVP_PKEY_CTX *ctx, - unsigned char *key, - size_t *keylen)) -{ - if (pderive_init) - *pderive_init = pmeth->derive_init; - if (pderive) - *pderive = pmeth->derive; -} - -void EVP_PKEY_meth_get_ctrl(EVP_PKEY_METHOD *pmeth, - int (**pctrl) (EVP_PKEY_CTX *ctx, int type, int p1, - void *p2), - int (**pctrl_str) (EVP_PKEY_CTX *ctx, - const char *type, - const char *value)) -{ - if (pctrl) - *pctrl = pmeth->ctrl; - if (pctrl_str) - *pctrl_str = pmeth->ctrl_str; -} diff --git a/Sources/COpenSSL/pqueue.c b/Sources/COpenSSL/pqueue.c deleted file mode 100644 index 8eded3be..00000000 --- a/Sources/COpenSSL/pqueue.c +++ /dev/null @@ -1,235 +0,0 @@ -/* crypto/pqueue/pqueue.c */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "cryptlib.h" -#include "bn.h" -#include "pqueue.h" - -typedef struct _pqueue { - pitem *items; - int count; -} pqueue_s; - -pitem *pitem_new(unsigned char *prio64be, void *data) -{ - pitem *item = (pitem *)OPENSSL_malloc(sizeof(pitem)); - if (item == NULL) - return NULL; - - memcpy(item->priority, prio64be, sizeof(item->priority)); - - item->data = data; - item->next = NULL; - - return item; -} - -void pitem_free(pitem *item) -{ - if (item == NULL) - return; - - OPENSSL_free(item); -} - -pqueue_s *pqueue_new() -{ - pqueue_s *pq = (pqueue_s *)OPENSSL_malloc(sizeof(pqueue_s)); - if (pq == NULL) - return NULL; - - memset(pq, 0x00, sizeof(pqueue_s)); - return pq; -} - -void pqueue_free(pqueue_s *pq) -{ - if (pq == NULL) - return; - - OPENSSL_free(pq); -} - -pitem *pqueue_insert(pqueue_s *pq, pitem *item) -{ - pitem *curr, *next; - - if (pq->items == NULL) { - pq->items = item; - return item; - } - - for (curr = NULL, next = pq->items; - next != NULL; curr = next, next = next->next) { - /* - * we can compare 64-bit value in big-endian encoding with memcmp:-) - */ - int cmp = memcmp(next->priority, item->priority, 8); - if (cmp > 0) { /* next > item */ - item->next = next; - - if (curr == NULL) - pq->items = item; - else - curr->next = item; - - return item; - } - - else if (cmp == 0) /* duplicates not allowed */ - return NULL; - } - - item->next = NULL; - curr->next = item; - - return item; -} - -pitem *pqueue_peek(pqueue_s *pq) -{ - return pq->items; -} - -pitem *pqueue_pop(pqueue_s *pq) -{ - pitem *item = pq->items; - - if (pq->items != NULL) - pq->items = pq->items->next; - - return item; -} - -pitem *pqueue_find(pqueue_s *pq, unsigned char *prio64be) -{ - pitem *next; - pitem *found = NULL; - - if (pq->items == NULL) - return NULL; - - for (next = pq->items; next->next != NULL; next = next->next) { - if (memcmp(next->priority, prio64be, 8) == 0) { - found = next; - break; - } - } - - /* check the one last node */ - if (memcmp(next->priority, prio64be, 8) == 0) - found = next; - - if (!found) - return NULL; - -#if 0 /* find works in peek mode */ - if (prev == NULL) - pq->items = next->next; - else - prev->next = next->next; -#endif - - return found; -} - -void pqueue_print(pqueue_s *pq) -{ - pitem *item = pq->items; - - while (item != NULL) { - printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n", - item->priority[0], item->priority[1], - item->priority[2], item->priority[3], - item->priority[4], item->priority[5], - item->priority[6], item->priority[7]); - item = item->next; - } -} - -pitem *pqueue_iterator(pqueue_s *pq) -{ - return pqueue_peek(pq); -} - -pitem *pqueue_next(pitem **item) -{ - pitem *ret; - - if (item == NULL || *item == NULL) - return NULL; - - /* *item != NULL */ - ret = *item; - *item = (*item)->next; - - return ret; -} - -int pqueue_size(pqueue_s *pq) -{ - pitem *item = pq->items; - int count = 0; - - while (item != NULL) { - count++; - item = item->next; - } - return count; -} diff --git a/Sources/COpenSSL/pqueue.h b/Sources/COpenSSL/pqueue.h deleted file mode 100644 index d40d9c7d..00000000 --- a/Sources/COpenSSL/pqueue.h +++ /dev/null @@ -1,99 +0,0 @@ -/* crypto/pqueue/pqueue.h */ -/* - * DTLS implementation written by Nagendra Modadugu - * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. - */ -/* ==================================================================== - * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_PQUEUE_H -# define HEADER_PQUEUE_H - -# include -# include -# include - -#ifdef __cplusplus -extern "C" { -#endif -typedef struct _pqueue *pqueue; - -typedef struct _pitem { - unsigned char priority[8]; /* 64-bit value in big-endian encoding */ - void *data; - struct _pitem *next; -} pitem; - -typedef struct _pitem *piterator; - -pitem *pitem_new(unsigned char *prio64be, void *data); -void pitem_free(pitem *item); - -pqueue pqueue_new(void); -void pqueue_free(pqueue pq); - -pitem *pqueue_insert(pqueue pq, pitem *item); -pitem *pqueue_peek(pqueue pq); -pitem *pqueue_pop(pqueue pq); -pitem *pqueue_find(pqueue pq, unsigned char *prio64be); -pitem *pqueue_iterator(pqueue pq); -pitem *pqueue_next(piterator *iter); - -void pqueue_print(pqueue pq); -int pqueue_size(pqueue pq); - -#ifdef __cplusplus -} -#endif -#endif /* ! HEADER_PQUEUE_H */ diff --git a/Sources/COpenSSL/pvkfmt.c b/Sources/COpenSSL/pvkfmt.c deleted file mode 100644 index d5852b13..00000000 --- a/Sources/COpenSSL/pvkfmt.c +++ /dev/null @@ -1,896 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2005. - */ -/* ==================================================================== - * Copyright (c) 2005-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * Support for PVK format keys and related structures (such a PUBLICKEYBLOB - * and PRIVATEKEYBLOB). - */ - -#include "cryptlib.h" -#include "pem.h" -#include "rand.h" -#include "bn.h" -#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) -# include "dsa.h" -# include "rsa.h" - -/* - * Utility function: read a DWORD (4 byte unsigned integer) in little endian - * format - */ - -static unsigned int read_ledword(const unsigned char **in) -{ - const unsigned char *p = *in; - unsigned int ret; - ret = *p++; - ret |= (*p++ << 8); - ret |= (*p++ << 16); - ret |= (*p++ << 24); - *in = p; - return ret; -} - -/* - * Read a BIGNUM in little endian format. The docs say that this should take - * up bitlen/8 bytes. - */ - -static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) -{ - const unsigned char *p; - unsigned char *tmpbuf, *q; - unsigned int i; - p = *in + nbyte - 1; - tmpbuf = OPENSSL_malloc(nbyte); - if (!tmpbuf) - return 0; - q = tmpbuf; - for (i = 0; i < nbyte; i++) - *q++ = *p--; - *r = BN_bin2bn(tmpbuf, nbyte, NULL); - OPENSSL_free(tmpbuf); - if (*r) { - *in += nbyte; - return 1; - } else - return 0; -} - -/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */ - -# define MS_PUBLICKEYBLOB 0x6 -# define MS_PRIVATEKEYBLOB 0x7 -# define MS_RSA1MAGIC 0x31415352L -# define MS_RSA2MAGIC 0x32415352L -# define MS_DSS1MAGIC 0x31535344L -# define MS_DSS2MAGIC 0x32535344L - -# define MS_KEYALG_RSA_KEYX 0xa400 -# define MS_KEYALG_DSS_SIGN 0x2200 - -# define MS_KEYTYPE_KEYX 0x1 -# define MS_KEYTYPE_SIGN 0x2 - -/* Maximum length of a blob after header */ -# define BLOB_MAX_LENGTH 102400 - -/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ -# define MS_PVKMAGIC 0xb0b5f11eL -/* Salt length for PVK files */ -# define PVK_SALTLEN 0x10 -/* Maximum length in PVK header */ -# define PVK_MAX_KEYLEN 102400 -/* Maximum salt length */ -# define PVK_MAX_SALTLEN 10240 - -static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, - unsigned int bitlen, int ispub); -static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, - unsigned int bitlen, int ispub); - -static int do_blob_header(const unsigned char **in, unsigned int length, - unsigned int *pmagic, unsigned int *pbitlen, - int *pisdss, int *pispub) -{ - const unsigned char *p = *in; - if (length < 16) - return 0; - /* bType */ - if (*p == MS_PUBLICKEYBLOB) { - if (*pispub == 0) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); - return 0; - } - *pispub = 1; - } else if (*p == MS_PRIVATEKEYBLOB) { - if (*pispub == 1) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); - return 0; - } - *pispub = 0; - } else - return 0; - p++; - /* Version */ - if (*p++ != 0x2) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER); - return 0; - } - /* Ignore reserved, aiKeyAlg */ - p += 6; - *pmagic = read_ledword(&p); - *pbitlen = read_ledword(&p); - *pisdss = 0; - switch (*pmagic) { - - case MS_DSS1MAGIC: - *pisdss = 1; - case MS_RSA1MAGIC: - if (*pispub == 0) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); - return 0; - } - break; - - case MS_DSS2MAGIC: - *pisdss = 1; - case MS_RSA2MAGIC: - if (*pispub == 1) { - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); - return 0; - } - break; - - default: - PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER); - return -1; - } - *in = p; - return 1; -} - -static unsigned int blob_length(unsigned bitlen, int isdss, int ispub) -{ - unsigned int nbyte, hnbyte; - nbyte = (bitlen + 7) >> 3; - hnbyte = (bitlen + 15) >> 4; - if (isdss) { - - /* - * Expected length: 20 for q + 3 components bitlen each + 24 for seed - * structure. - */ - if (ispub) - return 44 + 3 * nbyte; - /* - * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed - * structure. - */ - else - return 64 + 2 * nbyte; - } else { - /* Expected length: 4 for 'e' + 'n' */ - if (ispub) - return 4 + nbyte; - else - /* - * Expected length: 4 for 'e' and 7 other components. 2 - * components are bitlen size, 5 are bitlen/2 - */ - return 4 + 2 * nbyte + 5 * hnbyte; - } - -} - -static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length, - int ispub) -{ - const unsigned char *p = *in; - unsigned int bitlen, magic; - int isdss; - if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) { - PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); - return NULL; - } - length -= 16; - if (length < blob_length(bitlen, isdss, ispub)) { - PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT); - return NULL; - } - if (isdss) - return b2i_dss(&p, length, bitlen, ispub); - else - return b2i_rsa(&p, length, bitlen, ispub); -} - -static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) -{ - const unsigned char *p; - unsigned char hdr_buf[16], *buf = NULL; - unsigned int bitlen, magic, length; - int isdss; - EVP_PKEY *ret = NULL; - if (BIO_read(in, hdr_buf, 16) != 16) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); - return NULL; - } - p = hdr_buf; - if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0) - return NULL; - - length = blob_length(bitlen, isdss, ispub); - if (length > BLOB_MAX_LENGTH) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG); - return NULL; - } - buf = OPENSSL_malloc(length); - if (!buf) { - PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); - goto err; - } - p = buf; - if (BIO_read(in, buf, length) != (int)length) { - PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); - goto err; - } - - if (isdss) - ret = b2i_dss(&p, length, bitlen, ispub); - else - ret = b2i_rsa(&p, length, bitlen, ispub); - - err: - if (buf) - OPENSSL_free(buf); - return ret; -} - -static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, - unsigned int bitlen, int ispub) -{ - const unsigned char *p = *in; - EVP_PKEY *ret = NULL; - DSA *dsa = NULL; - BN_CTX *ctx = NULL; - unsigned int nbyte; - nbyte = (bitlen + 7) >> 3; - - dsa = DSA_new(); - ret = EVP_PKEY_new(); - if (!dsa || !ret) - goto memerr; - if (!read_lebn(&p, nbyte, &dsa->p)) - goto memerr; - if (!read_lebn(&p, 20, &dsa->q)) - goto memerr; - if (!read_lebn(&p, nbyte, &dsa->g)) - goto memerr; - if (ispub) { - if (!read_lebn(&p, nbyte, &dsa->pub_key)) - goto memerr; - } else { - if (!read_lebn(&p, 20, &dsa->priv_key)) - goto memerr; - /* Calculate public key */ - if (!(dsa->pub_key = BN_new())) - goto memerr; - if (!(ctx = BN_CTX_new())) - goto memerr; - - if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) - - goto memerr; - BN_CTX_free(ctx); - } - - EVP_PKEY_set1_DSA(ret, dsa); - DSA_free(dsa); - *in = p; - return ret; - - memerr: - PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE); - if (dsa) - DSA_free(dsa); - if (ret) - EVP_PKEY_free(ret); - if (ctx) - BN_CTX_free(ctx); - return NULL; -} - -static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, - unsigned int bitlen, int ispub) -{ - const unsigned char *p = *in; - EVP_PKEY *ret = NULL; - RSA *rsa = NULL; - unsigned int nbyte, hnbyte; - nbyte = (bitlen + 7) >> 3; - hnbyte = (bitlen + 15) >> 4; - rsa = RSA_new(); - ret = EVP_PKEY_new(); - if (!rsa || !ret) - goto memerr; - rsa->e = BN_new(); - if (!rsa->e) - goto memerr; - if (!BN_set_word(rsa->e, read_ledword(&p))) - goto memerr; - if (!read_lebn(&p, nbyte, &rsa->n)) - goto memerr; - if (!ispub) { - if (!read_lebn(&p, hnbyte, &rsa->p)) - goto memerr; - if (!read_lebn(&p, hnbyte, &rsa->q)) - goto memerr; - if (!read_lebn(&p, hnbyte, &rsa->dmp1)) - goto memerr; - if (!read_lebn(&p, hnbyte, &rsa->dmq1)) - goto memerr; - if (!read_lebn(&p, hnbyte, &rsa->iqmp)) - goto memerr; - if (!read_lebn(&p, nbyte, &rsa->d)) - goto memerr; - } - - EVP_PKEY_set1_RSA(ret, rsa); - RSA_free(rsa); - *in = p; - return ret; - memerr: - PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE); - if (rsa) - RSA_free(rsa); - if (ret) - EVP_PKEY_free(ret); - return NULL; -} - -EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length) -{ - return do_b2i(in, length, 0); -} - -EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length) -{ - return do_b2i(in, length, 1); -} - -EVP_PKEY *b2i_PrivateKey_bio(BIO *in) -{ - return do_b2i_bio(in, 0); -} - -EVP_PKEY *b2i_PublicKey_bio(BIO *in) -{ - return do_b2i_bio(in, 1); -} - -static void write_ledword(unsigned char **out, unsigned int dw) -{ - unsigned char *p = *out; - *p++ = dw & 0xff; - *p++ = (dw >> 8) & 0xff; - *p++ = (dw >> 16) & 0xff; - *p++ = (dw >> 24) & 0xff; - *out = p; -} - -static void write_lebn(unsigned char **out, const BIGNUM *bn, int len) -{ - int nb, i; - unsigned char *p = *out, *q, c; - nb = BN_num_bytes(bn); - BN_bn2bin(bn, p); - q = p + nb - 1; - /* In place byte order reversal */ - for (i = 0; i < nb / 2; i++) { - c = *p; - *p++ = *q; - *q-- = c; - } - *out += nb; - /* Pad with zeroes if we have to */ - if (len > 0) { - len -= nb; - if (len > 0) { - memset(*out, 0, len); - *out += len; - } - } -} - -static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic); -static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic); - -static void write_rsa(unsigned char **out, RSA *rsa, int ispub); -static void write_dsa(unsigned char **out, DSA *dsa, int ispub); - -static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) -{ - unsigned char *p; - unsigned int bitlen, magic = 0, keyalg; - int outlen, noinc = 0; - if (pk->type == EVP_PKEY_DSA) { - bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic); - keyalg = MS_KEYALG_DSS_SIGN; - } else if (pk->type == EVP_PKEY_RSA) { - bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic); - keyalg = MS_KEYALG_RSA_KEYX; - } else - return -1; - if (bitlen == 0) - return -1; - outlen = 16 + blob_length(bitlen, - keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); - if (out == NULL) - return outlen; - if (*out) - p = *out; - else { - p = OPENSSL_malloc(outlen); - if (!p) - return -1; - *out = p; - noinc = 1; - } - if (ispub) - *p++ = MS_PUBLICKEYBLOB; - else - *p++ = MS_PRIVATEKEYBLOB; - *p++ = 0x2; - *p++ = 0; - *p++ = 0; - write_ledword(&p, keyalg); - write_ledword(&p, magic); - write_ledword(&p, bitlen); - if (keyalg == MS_KEYALG_DSS_SIGN) - write_dsa(&p, pk->pkey.dsa, ispub); - else - write_rsa(&p, pk->pkey.rsa, ispub); - if (!noinc) - *out += outlen; - return outlen; -} - -static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) -{ - unsigned char *tmp = NULL; - int outlen, wrlen; - outlen = do_i2b(&tmp, pk, ispub); - if (outlen < 0) - return -1; - wrlen = BIO_write(out, tmp, outlen); - OPENSSL_free(tmp); - if (wrlen == outlen) - return outlen; - return -1; -} - -static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) -{ - int bitlen; - bitlen = BN_num_bits(dsa->p); - if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) - || (BN_num_bits(dsa->g) > bitlen)) - goto badkey; - if (ispub) { - if (BN_num_bits(dsa->pub_key) > bitlen) - goto badkey; - *pmagic = MS_DSS1MAGIC; - } else { - if (BN_num_bits(dsa->priv_key) > 160) - goto badkey; - *pmagic = MS_DSS2MAGIC; - } - - return bitlen; - badkey: - PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); - return 0; -} - -static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) -{ - int nbyte, hnbyte, bitlen; - if (BN_num_bits(rsa->e) > 32) - goto badkey; - bitlen = BN_num_bits(rsa->n); - nbyte = BN_num_bytes(rsa->n); - hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; - if (ispub) { - *pmagic = MS_RSA1MAGIC; - return bitlen; - } else { - *pmagic = MS_RSA2MAGIC; - /* - * For private key each component must fit within nbyte or hnbyte. - */ - if (BN_num_bytes(rsa->d) > nbyte) - goto badkey; - if ((BN_num_bytes(rsa->iqmp) > hnbyte) - || (BN_num_bytes(rsa->p) > hnbyte) - || (BN_num_bytes(rsa->q) > hnbyte) - || (BN_num_bytes(rsa->dmp1) > hnbyte) - || (BN_num_bytes(rsa->dmq1) > hnbyte)) - goto badkey; - } - return bitlen; - badkey: - PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); - return 0; -} - -static void write_rsa(unsigned char **out, RSA *rsa, int ispub) -{ - int nbyte, hnbyte; - nbyte = BN_num_bytes(rsa->n); - hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; - write_lebn(out, rsa->e, 4); - write_lebn(out, rsa->n, -1); - if (ispub) - return; - write_lebn(out, rsa->p, hnbyte); - write_lebn(out, rsa->q, hnbyte); - write_lebn(out, rsa->dmp1, hnbyte); - write_lebn(out, rsa->dmq1, hnbyte); - write_lebn(out, rsa->iqmp, hnbyte); - write_lebn(out, rsa->d, nbyte); -} - -static void write_dsa(unsigned char **out, DSA *dsa, int ispub) -{ - int nbyte; - nbyte = BN_num_bytes(dsa->p); - write_lebn(out, dsa->p, nbyte); - write_lebn(out, dsa->q, 20); - write_lebn(out, dsa->g, nbyte); - if (ispub) - write_lebn(out, dsa->pub_key, nbyte); - else - write_lebn(out, dsa->priv_key, 20); - /* Set "invalid" for seed structure values */ - memset(*out, 0xff, 24); - *out += 24; - return; -} - -int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk) -{ - return do_i2b_bio(out, pk, 0); -} - -int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk) -{ - return do_i2b_bio(out, pk, 1); -} - -# ifndef OPENSSL_NO_RC4 - -static int do_PVK_header(const unsigned char **in, unsigned int length, - int skip_magic, - unsigned int *psaltlen, unsigned int *pkeylen) -{ - const unsigned char *p = *in; - unsigned int pvk_magic, is_encrypted; - if (skip_magic) { - if (length < 20) { - PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); - return 0; - } - } else { - if (length < 24) { - PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); - return 0; - } - pvk_magic = read_ledword(&p); - if (pvk_magic != MS_PVKMAGIC) { - PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER); - return 0; - } - } - /* Skip reserved */ - p += 4; - /* - * keytype = - */ read_ledword(&p); - is_encrypted = read_ledword(&p); - *psaltlen = read_ledword(&p); - *pkeylen = read_ledword(&p); - - if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN) - return 0; - - if (is_encrypted && !*psaltlen) { - PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER); - return 0; - } - - *in = p; - return 1; -} - -static int derive_pvk_key(unsigned char *key, - const unsigned char *salt, unsigned int saltlen, - const unsigned char *pass, int passlen) -{ - EVP_MD_CTX mctx; - int rv = 1; - EVP_MD_CTX_init(&mctx); - if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL) - || !EVP_DigestUpdate(&mctx, salt, saltlen) - || !EVP_DigestUpdate(&mctx, pass, passlen) - || !EVP_DigestFinal_ex(&mctx, key, NULL)) - rv = 0; - - EVP_MD_CTX_cleanup(&mctx); - return rv; -} - -static EVP_PKEY *do_PVK_body(const unsigned char **in, - unsigned int saltlen, unsigned int keylen, - pem_password_cb *cb, void *u) -{ - EVP_PKEY *ret = NULL; - const unsigned char *p = *in; - unsigned int magic; - unsigned char *enctmp = NULL, *q; - EVP_CIPHER_CTX cctx; - EVP_CIPHER_CTX_init(&cctx); - if (saltlen) { - char psbuf[PEM_BUFSIZE]; - unsigned char keybuf[20]; - int enctmplen, inlen; - if (cb) - inlen = cb(psbuf, PEM_BUFSIZE, 0, u); - else - inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); - if (inlen < 0) { - PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ); - goto err; - } - enctmp = OPENSSL_malloc(keylen + 8); - if (!enctmp) { - PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!derive_pvk_key(keybuf, p, saltlen, - (unsigned char *)psbuf, inlen)) - goto err; - p += saltlen; - /* Copy BLOBHEADER across, decrypt rest */ - memcpy(enctmp, p, 8); - p += 8; - if (keylen < 8) { - PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT); - goto err; - } - inlen = keylen - 8; - q = enctmp + 8; - if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) - goto err; - if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen)) - goto err; - if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen)) - goto err; - magic = read_ledword((const unsigned char **)&q); - if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { - q = enctmp + 8; - memset(keybuf + 5, 0, 11); - if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) - goto err; - OPENSSL_cleanse(keybuf, 20); - if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen)) - goto err; - if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen)) - goto err; - magic = read_ledword((const unsigned char **)&q); - if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { - PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT); - goto err; - } - } else - OPENSSL_cleanse(keybuf, 20); - p = enctmp; - } - - ret = b2i_PrivateKey(&p, keylen); - err: - EVP_CIPHER_CTX_cleanup(&cctx); - if (enctmp && saltlen) - OPENSSL_free(enctmp); - return ret; -} - -EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) -{ - unsigned char pvk_hdr[24], *buf = NULL; - const unsigned char *p; - int buflen; - EVP_PKEY *ret = NULL; - unsigned int saltlen, keylen; - if (BIO_read(in, pvk_hdr, 24) != 24) { - PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); - return NULL; - } - p = pvk_hdr; - - if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen)) - return 0; - buflen = (int)keylen + saltlen; - buf = OPENSSL_malloc(buflen); - if (!buf) { - PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE); - return 0; - } - p = buf; - if (BIO_read(in, buf, buflen) != buflen) { - PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); - goto err; - } - ret = do_PVK_body(&p, saltlen, keylen, cb, u); - - err: - if (buf) { - OPENSSL_cleanse(buf, buflen); - OPENSSL_free(buf); - } - return ret; -} - -static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, - pem_password_cb *cb, void *u) -{ - int outlen = 24, pklen; - unsigned char *p, *salt = NULL; - EVP_CIPHER_CTX cctx; - EVP_CIPHER_CTX_init(&cctx); - if (enclevel) - outlen += PVK_SALTLEN; - pklen = do_i2b(NULL, pk, 0); - if (pklen < 0) - return -1; - outlen += pklen; - if (!out) - return outlen; - if (*out) - p = *out; - else { - p = OPENSSL_malloc(outlen); - if (!p) { - PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE); - return -1; - } - *out = p; - } - - write_ledword(&p, MS_PVKMAGIC); - write_ledword(&p, 0); - if (pk->type == EVP_PKEY_DSA) - write_ledword(&p, MS_KEYTYPE_SIGN); - else - write_ledword(&p, MS_KEYTYPE_KEYX); - write_ledword(&p, enclevel ? 1 : 0); - write_ledword(&p, enclevel ? PVK_SALTLEN : 0); - write_ledword(&p, pklen); - if (enclevel) { - if (RAND_bytes(p, PVK_SALTLEN) <= 0) - goto error; - salt = p; - p += PVK_SALTLEN; - } - do_i2b(&p, pk, 0); - if (enclevel == 0) - return outlen; - else { - char psbuf[PEM_BUFSIZE]; - unsigned char keybuf[20]; - int enctmplen, inlen; - if (cb) - inlen = cb(psbuf, PEM_BUFSIZE, 1, u); - else - inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u); - if (inlen <= 0) { - PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ); - goto error; - } - if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, - (unsigned char *)psbuf, inlen)) - goto error; - if (enclevel == 1) - memset(keybuf + 5, 0, 11); - p = salt + PVK_SALTLEN + 8; - if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) - goto error; - OPENSSL_cleanse(keybuf, 20); - if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8)) - goto error; - if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen)) - goto error; - } - EVP_CIPHER_CTX_cleanup(&cctx); - return outlen; - - error: - EVP_CIPHER_CTX_cleanup(&cctx); - return -1; -} - -int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, - pem_password_cb *cb, void *u) -{ - unsigned char *tmp = NULL; - int outlen, wrlen; - outlen = i2b_PVK(&tmp, pk, enclevel, cb, u); - if (outlen < 0) - return -1; - wrlen = BIO_write(out, tmp, outlen); - OPENSSL_free(tmp); - if (wrlen == outlen) { - PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE); - return outlen; - } - return -1; -} - -# endif - -#endif diff --git a/Sources/COpenSSL/qud_cksm.c b/Sources/COpenSSL/qud_cksm.c deleted file mode 100644 index 2a168a57..00000000 --- a/Sources/COpenSSL/qud_cksm.c +++ /dev/null @@ -1,143 +0,0 @@ -/* crypto/des/qud_cksm.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer IEEE - * Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 This module in - * only based on the code in this paper and is almost definitely not the same - * as the MIT implementation. - */ -#include "des_locl.h" - -/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */ -#define Q_B0(a) (((DES_LONG)(a))) -#define Q_B1(a) (((DES_LONG)(a))<<8) -#define Q_B2(a) (((DES_LONG)(a))<<16) -#define Q_B3(a) (((DES_LONG)(a))<<24) - -/* used to scramble things a bit */ -/* Got the value MIT uses via brute force :-) 2/10/90 eay */ -#define NOISE ((DES_LONG)83653421L) - -DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], - long length, int out_count, DES_cblock *seed) -{ - DES_LONG z0, z1, t0, t1; - int i; - long l; - const unsigned char *cp; -#ifdef _CRAY - struct lp_st { - int a:32; - int b:32; - } *lp; -#else - DES_LONG *lp; -#endif - - if (out_count < 1) - out_count = 1; -#ifdef _CRAY - lp = (struct lp_st *)&(output[0])[0]; -#else - lp = (DES_LONG *)&(output[0])[0]; -#endif - - z0 = Q_B0((*seed)[0]) | Q_B1((*seed)[1]) | Q_B2((*seed)[2]) | - Q_B3((*seed)[3]); - z1 = Q_B0((*seed)[4]) | Q_B1((*seed)[5]) | Q_B2((*seed)[6]) | - Q_B3((*seed)[7]); - - for (i = 0; ((i < 4) && (i < out_count)); i++) { - cp = input; - l = length; - while (l > 0) { - if (l > 1) { - t0 = (DES_LONG)(*(cp++)); - t0 |= (DES_LONG)Q_B1(*(cp++)); - l--; - } else - t0 = (DES_LONG)(*(cp++)); - l--; - /* add */ - t0 += z0; - t0 &= 0xffffffffL; - t1 = z1; - /* square, well sort of square */ - z0 = ((((t0 * t0) & 0xffffffffL) + ((t1 * t1) & 0xffffffffL)) - & 0xffffffffL) % 0x7fffffffL; - z1 = ((t0 * ((t1 + NOISE) & 0xffffffffL)) & 0xffffffffL) % - 0x7fffffffL; - } - if (lp != NULL) { - /* - * The MIT library assumes that the checksum is composed of - * 2*out_count 32 bit ints - */ -#ifdef _CRAY - (*lp).a = z0; - (*lp).b = z1; - lp++; -#else - *lp++ = z0; - *lp++ = z1; -#endif - } - } - return (z0); -} diff --git a/Sources/COpenSSL/rand.h b/Sources/COpenSSL/rand.h deleted file mode 100644 index 143eae91..00000000 --- a/Sources/COpenSSL/rand.h +++ /dev/null @@ -1,150 +0,0 @@ -/* crypto/rand/rand.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_RAND_H -# define HEADER_RAND_H - -# include -# include "ossl_typ.h" -# include "e_os2.h" - -# if defined(OPENSSL_SYS_WINDOWS) -# include -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -# if defined(OPENSSL_FIPS) -# define FIPS_RAND_SIZE_T size_t -# endif - -/* Already defined in ossl_typ.h */ -/* typedef struct rand_meth_st RAND_METHOD; */ - -struct rand_meth_st { - void (*seed) (const void *buf, int num); - int (*bytes) (unsigned char *buf, int num); - void (*cleanup) (void); - void (*add) (const void *buf, int num, double entropy); - int (*pseudorand) (unsigned char *buf, int num); - int (*status) (void); -}; - -# ifdef BN_DEBUG -extern int rand_predictable; -# endif - -int RAND_set_rand_method(const RAND_METHOD *meth); -const RAND_METHOD *RAND_get_rand_method(void); -# ifndef OPENSSL_NO_ENGINE -int RAND_set_rand_engine(ENGINE *engine); -# endif -RAND_METHOD *RAND_SSLeay(void); -void RAND_cleanup(void); -int RAND_bytes(unsigned char *buf, int num); -int RAND_pseudo_bytes(unsigned char *buf, int num); -void RAND_seed(const void *buf, int num); -void RAND_add(const void *buf, int num, double entropy); -int RAND_load_file(const char *file, long max_bytes); -int RAND_write_file(const char *file); -const char *RAND_file_name(char *file, size_t num); -int RAND_status(void); -int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); -int RAND_egd(const char *path); -int RAND_egd_bytes(const char *path, int bytes); -int RAND_poll(void); - -# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) - -void RAND_screen(void); -int RAND_event(UINT, WPARAM, LPARAM); - -# endif - -# ifdef OPENSSL_FIPS -void RAND_set_fips_drbg_type(int type, int flags); -int RAND_init_fips(void); -# endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_RAND_strings(void); - -/* Error codes for the RAND functions. */ - -/* Function codes. */ -# define RAND_F_RAND_GET_RAND_METHOD 101 -# define RAND_F_RAND_INIT_FIPS 102 -# define RAND_F_SSLEAY_RAND_BYTES 100 - -/* Reason codes. */ -# define RAND_R_DUAL_EC_DRBG_DISABLED 104 -# define RAND_R_ERROR_INITIALISING_DRBG 102 -# define RAND_R_ERROR_INSTANTIATING_DRBG 103 -# define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 -# define RAND_R_PRNG_NOT_SEEDED 100 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/rand_.c b/Sources/COpenSSL/rand_.c deleted file mode 100644 index 03b915f1..00000000 --- a/Sources/COpenSSL/rand_.c +++ /dev/null @@ -1,2501 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/rand/rand_egd.c */ -/* Written by Ulf Moeller and Lutz Jaenicke for the OpenSSL project. */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "e_os2.h" -#include "rand.h" -#include "buffer.h" - -/*- - * Query the EGD . - * - * This module supplies three routines: - * - * RAND_query_egd_bytes(path, buf, bytes) - * will actually query "bytes" bytes of entropy form the egd-socket located - * at path and will write them to buf (if supplied) or will directly feed - * it to RAND_seed() if buf==NULL. - * The number of bytes is not limited by the maximum chunk size of EGD, - * which is 255 bytes. If more than 255 bytes are wanted, several chunks - * of entropy bytes are requested. The connection is left open until the - * query is competed. - * RAND_query_egd_bytes() returns with - * -1 if an error occured during connection or communication. - * num the number of bytes read from the EGD socket. This number is either - * the number of bytes requested or smaller, if the EGD pool is - * drained and the daemon signals that the pool is empty. - * This routine does not touch any RAND_status(). This is necessary, since - * PRNG functions may call it during initialization. - * - * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them - * used to seed the PRNG. - * RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL. - * Unlike RAND_query_egd_bytes(), RAND_status() is used to test the - * seed status so that the return value can reflect the seed state: - * -1 if an error occured during connection or communication _or_ - * if the PRNG has still not received the required seeding. - * num the number of bytes read from the EGD socket. This number is either - * the number of bytes requested or smaller, if the EGD pool is - * drained and the daemon signals that the pool is empty. - * - * RAND_egd(path) will query 255 bytes and use the bytes retreived to seed - * the PRNG. - * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. - */ - -#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS) -int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) -{ - return (-1); -} - -int RAND_egd(const char *path) -{ - return (-1); -} - -int RAND_egd_bytes(const char *path, int bytes) -{ - return (-1); -} -#else -# include "opensslconf.h" -# include OPENSSL_UNISTD -# include -# include -# include -# ifndef NO_SYS_UN_H -# ifdef OPENSSL_SYS_VXWORKS -# include -# else -# include -# endif -# else -struct sockaddr_un { - short sun_family; /* AF_UNIX */ - char sun_path[108]; /* path name (gag) */ -}; -# endif /* NO_SYS_UN_H */ -# include -# include - -# ifndef offsetof -# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -# endif - -int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) -{ - int ret = 0; - struct sockaddr_un addr; - int len, num, numbytes; - int fd = -1; - int success; - unsigned char egdbuf[2], tempbuf[255], *retrievebuf; - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - if (strlen(path) >= sizeof(addr.sun_path)) - return (-1); - BUF_strlcpy(addr.sun_path, path, sizeof(addr.sun_path)); - len = offsetof(struct sockaddr_un, sun_path) + strlen(path); - fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd == -1) - return (-1); - success = 0; - while (!success) { - if (connect(fd, (struct sockaddr *)&addr, len) == 0) - success = 1; - else { - switch (errno) { -# ifdef EINTR - case EINTR: -# endif -# ifdef EAGAIN - case EAGAIN: -# endif -# ifdef EINPROGRESS - case EINPROGRESS: -# endif -# ifdef EALREADY - case EALREADY: -# endif - /* No error, try again */ - break; -# ifdef EISCONN - case EISCONN: - success = 1; - break; -# endif - default: - goto err; /* failure */ - } - } - } - - while (bytes > 0) { - egdbuf[0] = 1; - egdbuf[1] = bytes < 255 ? bytes : 255; - numbytes = 0; - while (numbytes != 2) { - num = write(fd, egdbuf + numbytes, 2 - numbytes); - if (num >= 0) - numbytes += num; - else { - switch (errno) { -# ifdef EINTR - case EINTR: -# endif -# ifdef EAGAIN - case EAGAIN: -# endif - /* No error, try again */ - break; - default: - ret = -1; - goto err; /* failure */ - } - } - } - numbytes = 0; - while (numbytes != 1) { - num = read(fd, egdbuf, 1); - if (num == 0) - goto err; /* descriptor closed */ - else if (num > 0) - numbytes += num; - else { - switch (errno) { -# ifdef EINTR - case EINTR: -# endif -# ifdef EAGAIN - case EAGAIN: -# endif - /* No error, try again */ - break; - default: - ret = -1; - goto err; /* failure */ - } - } - } - if (egdbuf[0] == 0) - goto err; - if (buf) - retrievebuf = buf + ret; - else - retrievebuf = tempbuf; - numbytes = 0; - while (numbytes != egdbuf[0]) { - num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes); - if (num == 0) - goto err; /* descriptor closed */ - else if (num > 0) - numbytes += num; - else { - switch (errno) { -# ifdef EINTR - case EINTR: -# endif -# ifdef EAGAIN - case EAGAIN: -# endif - /* No error, try again */ - break; - default: - ret = -1; - goto err; /* failure */ - } - } - } - ret += egdbuf[0]; - bytes -= egdbuf[0]; - if (!buf) - RAND_seed(tempbuf, egdbuf[0]); - } - err: - if (fd != -1) - close(fd); - return (ret); -} - -int RAND_egd_bytes(const char *path, int bytes) -{ - int num, ret = 0; - - num = RAND_query_egd_bytes(path, NULL, bytes); - if (num < 1) - goto err; - if (RAND_status() == 1) - ret = num; - err: - return (ret); -} - -int RAND_egd(const char *path) -{ - return (RAND_egd_bytes(path, 255)); -} - -#endif -/* crypto/rand/rand_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "rand.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason) - -static ERR_STRING_DATA RAND_str_functs[] = { - {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, - {ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"}, - {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, - {0, NULL} -}; - -static ERR_STRING_DATA RAND_str_reasons[] = { - {ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED), "dual ec drbg disabled"}, - {ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, - {ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, - {ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET), - "no fips random method set"}, - {ERR_REASON(RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"}, - {0, NULL} -}; - -#endif - -void ERR_load_RAND_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) { - ERR_load_strings(0, RAND_str_functs); - ERR_load_strings(0, RAND_str_reasons); - } -#endif -} -/* crypto/des/rand_key.c */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "des.h" -// #include "rand.h" - -int DES_random_key(DES_cblock *ret) -{ - do { - if (RAND_bytes((unsigned char *)ret, sizeof(DES_cblock)) != 1) - return (0); - } while (DES_is_weak_key(ret)); - DES_set_odd_parity(ret); - return (1); -} -/* crypto/rand/rand_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "cryptlib.h" -// #include "rand.h" - -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -#ifdef OPENSSL_FIPS -# include -# include -# include "rand_lcl.h" -#endif - -#ifndef OPENSSL_NO_ENGINE -/* non-NULL if default_RAND_meth is ENGINE-provided */ -static ENGINE *funct_ref = NULL; -#endif -static const RAND_METHOD *default_RAND_meth = NULL; - -int RAND_set_rand_method(const RAND_METHOD *meth) -{ -#ifndef OPENSSL_NO_ENGINE - if (funct_ref) { - ENGINE_finish(funct_ref); - funct_ref = NULL; - } -#endif - default_RAND_meth = meth; - return 1; -} - -const RAND_METHOD *RAND_get_rand_method(void) -{ - if (!default_RAND_meth) { -#ifndef OPENSSL_NO_ENGINE - ENGINE *e = ENGINE_get_default_RAND(); - if (e) { - default_RAND_meth = ENGINE_get_RAND(e); - if (!default_RAND_meth) { - ENGINE_finish(e); - e = NULL; - } - } - if (e) - funct_ref = e; - else -#endif - default_RAND_meth = RAND_SSLeay(); - } - return default_RAND_meth; -} - -#ifndef OPENSSL_NO_ENGINE -int RAND_set_rand_engine(ENGINE *engine) -{ - const RAND_METHOD *tmp_meth = NULL; - if (engine) { - if (!ENGINE_init(engine)) - return 0; - tmp_meth = ENGINE_get_RAND(engine); - if (!tmp_meth) { - ENGINE_finish(engine); - return 0; - } - } - /* This function releases any prior ENGINE so call it first */ - RAND_set_rand_method(tmp_meth); - funct_ref = engine; - return 1; -} -#endif - -void RAND_cleanup(void) -{ - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->cleanup) - meth->cleanup(); - RAND_set_rand_method(NULL); -} - -void RAND_seed(const void *buf, int num) -{ - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->seed) - meth->seed(buf, num); -} - -void RAND_add(const void *buf, int num, double entropy) -{ - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->add) - meth->add(buf, num, entropy); -} - -int RAND_bytes(unsigned char *buf, int num) -{ - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->bytes) - return meth->bytes(buf, num); - return (-1); -} - -int RAND_pseudo_bytes(unsigned char *buf, int num) -{ - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->pseudorand) - return meth->pseudorand(buf, num); - return (-1); -} - -int RAND_status(void) -{ - const RAND_METHOD *meth = RAND_get_rand_method(); - if (meth && meth->status) - return meth->status(); - return 0; -} - -#ifdef OPENSSL_FIPS - -/* - * FIPS DRBG initialisation code. This sets up the DRBG for use by the rest - * of OpenSSL. - */ - -/* - * Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather - * entropy internally through RAND_poll()). - */ - -static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout, - int entropy, size_t min_len, size_t max_len) -{ - /* Round up request to multiple of block size */ - min_len = ((min_len + 19) / 20) * 20; - *pout = OPENSSL_malloc(min_len); - if (!*pout) - return 0; - - /* Enforces a reseed of the SSLEAY PRNG before generating random bytes */ - if (ssleay_rand_bytes_from_system(*pout, min_len) <= 0) { - OPENSSL_free(*pout); - *pout = NULL; - return 0; - } - return min_len; -} - -static size_t drbg_get_nonce(DRBG_CTX *ctx, unsigned char **pout, - int entropy, size_t min_len, size_t max_len) -{ - /* Round up request to multiple of block size */ - min_len = ((min_len + 19) / 20) * 20; - *pout = OPENSSL_malloc(min_len); - if (!*pout) - return 0; - if (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 0) { - OPENSSL_free(*pout); - *pout = NULL; - return 0; - } - return min_len; -} - -static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen) -{ - if (out) { - OPENSSL_cleanse(out, olen); - OPENSSL_free(out); - } -} - -/* - * Set "additional input" when generating random data. This uses the current - * PID, a time value and a counter. - */ - -static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout) -{ - /* Use of static variables is OK as this happens under a lock */ - static unsigned char buf[16]; - static unsigned long counter; - FIPS_get_timevec(buf, &counter); - *pout = buf; - return sizeof(buf); -} - -/* - * RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is - * correctly seeded by RAND_poll(). - */ - -static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen, - double entropy) -{ - RAND_SSLeay()->add(in, inlen, entropy); - return 1; -} - -static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen) -{ - RAND_SSLeay()->seed(in, inlen); - return 1; -} - -# ifndef OPENSSL_DRBG_DEFAULT_TYPE -# define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr -# endif -# ifndef OPENSSL_DRBG_DEFAULT_FLAGS -# define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF -# endif - -static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE; -static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS; - -void RAND_set_fips_drbg_type(int type, int flags) -{ - fips_drbg_type = type; - fips_drbg_flags = flags; -} - -int RAND_init_fips(void) -{ - DRBG_CTX *dctx; - size_t plen; - unsigned char pers[32], *p; -# ifndef OPENSSL_ALLOW_DUAL_EC_DRBG - if (fips_drbg_type >> 16) { - RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED); - return 0; - } -# endif - - dctx = FIPS_get_default_drbg(); - if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0) { - RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG); - return 0; - } - - FIPS_drbg_set_callbacks(dctx, - drbg_get_entropy, drbg_free_entropy, 20, - drbg_get_nonce, drbg_free_entropy); - FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0, - drbg_rand_seed, drbg_rand_add); - /* Personalisation string: a string followed by date time vector */ - strcpy((char *)pers, "OpenSSL DRBG2.0"); - plen = drbg_get_adin(dctx, &p); - memcpy(pers + 16, p, plen); - - if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0) { - RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG); - return 0; - } - FIPS_rand_set_method(FIPS_drbg_method()); - return 1; -} - -#endif -/* crypto/rand/rand_nw.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "rand.h" -#include "rand_lcl.h" - -#if defined (OPENSSL_SYS_NETWARE) - -# if defined(NETWARE_LIBC) -# include -# else -# include -# endif - -extern int GetProcessSwitchCount(void); -# if !defined(NETWARE_LIBC) || (CURRENT_NDK_THRESHOLD < 509220000) -extern void *RunningProcess; /* declare here same as found in newer NDKs */ -extern unsigned long GetSuperHighResolutionTimer(void); -# endif - - /* - * the FAQ indicates we need to provide at least 20 bytes (160 bits) of - * seed - */ -int RAND_poll(void) -{ - unsigned long l; - unsigned long tsc; - int i; - - /* - * There are several options to gather miscellaneous data but for now we - * will loop checking the time stamp counter (rdtsc) and the - * SuperHighResolutionTimer. Each iteration will collect 8 bytes of data - * but it is treated as only 1 byte of entropy. The call to - * ThreadSwitchWithDelay() will introduce additional variability into the - * data returned by rdtsc. Applications can agument the seed material by - * adding additional stuff with RAND_add() and should probably do so. - */ - l = GetProcessSwitchCount(); - RAND_add(&l, sizeof(l), 1); - - /* need to cast the void* to unsigned long here */ - l = (unsigned long)RunningProcess; - RAND_add(&l, sizeof(l), 1); - - for (i = 2; i < ENTROPY_NEEDED; i++) { -# ifdef __MWERKS__ - asm { - rdtsc mov tsc, eax} -# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) - asm volatile ("rdtsc":"=a" (tsc)::"edx"); -# endif - - RAND_add(&tsc, sizeof(tsc), 1); - - l = GetSuperHighResolutionTimer(); - RAND_add(&l, sizeof(l), 0); - -# if defined(NETWARE_LIBC) - NXThreadYield(); -# else /* NETWARE_CLIB */ - ThreadSwitchWithDelay(); -# endif - } - - return 1; -} - -#endif -/* crypto/rand/rand_os2.c */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "rand.h" -// #include "rand_lcl.h" - -#ifdef OPENSSL_SYS_OS2 - -# define INCL_DOSPROCESS -# define INCL_DOSPROFILE -# define INCL_DOSMISC -# define INCL_DOSMODULEMGR -# include - -# define CMD_KI_RDCNT (0x63) - -typedef struct _CPUUTIL { - ULONG ulTimeLow; /* Low 32 bits of time stamp */ - ULONG ulTimeHigh; /* High 32 bits of time stamp */ - ULONG ulIdleLow; /* Low 32 bits of idle time */ - ULONG ulIdleHigh; /* High 32 bits of idle time */ - ULONG ulBusyLow; /* Low 32 bits of busy time */ - ULONG ulBusyHigh; /* High 32 bits of busy time */ - ULONG ulIntrLow; /* Low 32 bits of interrupt time */ - ULONG ulIntrHigh; /* High 32 bits of interrupt time */ -} CPUUTIL; - -# ifndef __KLIBC__ -APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, - ULONG ulParm2, ULONG ulParm3) = NULL; -APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, - ULONG _res_, PVOID buf, ULONG bufsz) = - NULL; -# endif -HMODULE hDoscalls = 0; - -int RAND_poll(void) -{ - char failed_module[20]; - QWORD qwTime; - ULONG SysVars[QSV_FOREGROUND_PROCESS]; - - if (hDoscalls == 0) { - ULONG rc = - DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", - &hDoscalls); - -# ifndef __KLIBC__ - if (rc == 0) { - rc = DosQueryProcAddr(hDoscalls, 976, NULL, - (PFN *) & DosPerfSysCall); - - if (rc) - DosPerfSysCall = NULL; - - rc = DosQueryProcAddr(hDoscalls, 368, NULL, - (PFN *) & DosQuerySysState); - - if (rc) - DosQuerySysState = NULL; - } -# endif - } - - /* Sample the hi-res timer, runs at around 1.1 MHz */ - DosTmrQueryTime(&qwTime); - RAND_add(&qwTime, sizeof(qwTime), 2); - - /* - * Sample a bunch of system variables, includes various process & memory - * statistics - */ - DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars)); - RAND_add(SysVars, sizeof(SysVars), 4); - - /* - * If available, sample CPU registers that count at CPU MHz Only fairly - * new CPUs (PPro & K6 onwards) & OS/2 versions support this - */ - if (DosPerfSysCall) { - CPUUTIL util; - - if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG) & util, 0, 0) == 0) { - RAND_add(&util, sizeof(util), 10); - } else { -# ifndef __KLIBC__ - DosPerfSysCall = NULL; -# endif - } - } - - /* - * DosQuerySysState() gives us a huge quantity of process, thread, memory - * & handle stats - */ - if (DosQuerySysState) { - char *buffer = OPENSSL_malloc(256 * 1024); - - if (!buffer) - return 0; - - if (DosQuerySysState(0x1F, 0, 0, 0, buffer, 256 * 1024) == 0) { - /* - * First 4 bytes in buffer is a pointer to the thread count there - * should be at least 1 byte of entropy per thread - */ - RAND_add(buffer, 256 * 1024, **(ULONG **) buffer); - } - - OPENSSL_free(buffer); - return 1; - } - - return 0; -} - -#endif /* OPENSSL_SYS_OS2 */ -/* crypto/rand/rand_unix.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#include - -#define USE_SOCKETS -#include "e_os.h" -// #include "cryptlib.h" -// #include "rand.h" -// #include "rand_lcl.h" - -#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) - -# include -# include -# include -# include -# include -# include -# include -# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually - * everywhere */ -# include -# endif -# include -# ifndef FD_SETSIZE -# define FD_SETSIZE (8*sizeof(fd_set)) -# endif - -# if defined(OPENSSL_SYS_VOS) - -/* - * The following algorithm repeatedly samples the real-time clock (RTC) to - * generate a sequence of unpredictable data. The algorithm relies upon the - * uneven execution speed of the code (due to factors such as cache misses, - * interrupts, bus activity, and scheduling) and upon the rather large - * relative difference between the speed of the clock and the rate at which - * it can be read. - * - * If this code is ported to an environment where execution speed is more - * constant or where the RTC ticks at a much slower rate, or the clock can be - * read with fewer instructions, it is likely that the results would be far - * more predictable. - * - * As a precaution, we generate 4 times the minimum required amount of seed - * data. - */ - -int RAND_poll(void) -{ - short int code; - gid_t curr_gid; - pid_t curr_pid; - uid_t curr_uid; - int i, k; - struct timespec ts; - unsigned char v; - -# ifdef OPENSSL_SYS_VOS_HPPA - long duration; - extern void s$sleep(long *_duration, short int *_code); -# else -# ifdef OPENSSL_SYS_VOS_IA32 - long long duration; - extern void s$sleep2(long long *_duration, short int *_code); -# else -# error "Unsupported Platform." -# endif /* OPENSSL_SYS_VOS_IA32 */ -# endif /* OPENSSL_SYS_VOS_HPPA */ - - /* - * Seed with the gid, pid, and uid, to ensure *some* variation between - * different processes. - */ - - curr_gid = getgid(); - RAND_add(&curr_gid, sizeof(curr_gid), 1); - curr_gid = 0; - - curr_pid = getpid(); - RAND_add(&curr_pid, sizeof(curr_pid), 1); - curr_pid = 0; - - curr_uid = getuid(); - RAND_add(&curr_uid, sizeof(curr_uid), 1); - curr_uid = 0; - - for (i = 0; i < (ENTROPY_NEEDED * 4); i++) { - /* - * burn some cpu; hope for interrupts, cache collisions, bus - * interference, etc. - */ - for (k = 0; k < 99; k++) - ts.tv_nsec = random(); - -# ifdef OPENSSL_SYS_VOS_HPPA - /* sleep for 1/1024 of a second (976 us). */ - duration = 1; - s$sleep(&duration, &code); -# else -# ifdef OPENSSL_SYS_VOS_IA32 - /* sleep for 1/65536 of a second (15 us). */ - duration = 1; - s$sleep2(&duration, &code); -# endif /* OPENSSL_SYS_VOS_IA32 */ -# endif /* OPENSSL_SYS_VOS_HPPA */ - - /* get wall clock time. */ - clock_gettime(CLOCK_REALTIME, &ts); - - /* take 8 bits */ - v = (unsigned char)(ts.tv_nsec % 256); - RAND_add(&v, sizeof(v), 1); - v = 0; - } - return 1; -} -# elif defined __OpenBSD__ -int RAND_poll(void) -{ - u_int32_t rnd = 0, i; - unsigned char buf[ENTROPY_NEEDED]; - - for (i = 0; i < sizeof(buf); i++) { - if (i % 4 == 0) - rnd = arc4random(); - buf[i] = rnd; - rnd >>= 8; - } - RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); - OPENSSL_cleanse(buf, sizeof(buf)); - - return 1; -} -# else /* !defined(__OpenBSD__) */ -int RAND_poll(void) -{ - unsigned long l; - pid_t curr_pid = getpid(); -# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) - unsigned char tmpbuf[ENTROPY_NEEDED]; - int n = 0; -# endif -# ifdef DEVRANDOM - static const char *randomfiles[] = { DEVRANDOM }; - struct stat randomstats[sizeof(randomfiles) / sizeof(randomfiles[0])]; - int fd; - unsigned int i; -# endif -# ifdef DEVRANDOM_EGD - static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; - const char **egdsocket = NULL; -# endif - -# ifdef DEVRANDOM - memset(randomstats, 0, sizeof(randomstats)); - /* - * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have - * this. Use /dev/urandom if you can as /dev/random may block if it runs - * out of random entries. - */ - - for (i = 0; (i < sizeof(randomfiles) / sizeof(randomfiles[0])) && - (n < ENTROPY_NEEDED); i++) { - if ((fd = open(randomfiles[i], O_RDONLY -# ifdef O_NONBLOCK - | O_NONBLOCK -# endif -# ifdef O_BINARY - | O_BINARY -# endif -# ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do - * not make it our controlling tty */ - | O_NOCTTY -# endif - )) >= 0) { - int usec = 10 * 1000; /* spend 10ms on each file */ - int r; - unsigned int j; - struct stat *st = &randomstats[i]; - - /* - * Avoid using same input... Used to be O_NOFOLLOW above, but - * it's not universally appropriate... - */ - if (fstat(fd, st) != 0) { - close(fd); - continue; - } - for (j = 0; j < i; j++) { - if (randomstats[j].st_ino == st->st_ino && - randomstats[j].st_dev == st->st_dev) - break; - } - if (j < i) { - close(fd); - continue; - } - - do { - int try_read = 0; - -# if defined(OPENSSL_SYS_BEOS_R5) - /* - * select() is broken in BeOS R5, so we simply try to read - * something and snooze if we couldn't - */ - try_read = 1; - -# elif defined(OPENSSL_SYS_LINUX) - /* use poll() */ - struct pollfd pset; - - pset.fd = fd; - pset.events = POLLIN; - pset.revents = 0; - - if (poll(&pset, 1, usec / 1000) < 0) - usec = 0; - else - try_read = (pset.revents & POLLIN) != 0; - -# else - /* use select() */ - fd_set fset; - struct timeval t; - - t.tv_sec = 0; - t.tv_usec = usec; - - if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) { - /* - * can't use select, so just try to read once anyway - */ - try_read = 1; - } else { - FD_ZERO(&fset); - FD_SET(fd, &fset); - - if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) { - usec = t.tv_usec; - if (FD_ISSET(fd, &fset)) - try_read = 1; - } else - usec = 0; - } -# endif - - if (try_read) { - r = read(fd, (unsigned char *)tmpbuf + n, - ENTROPY_NEEDED - n); - if (r > 0) - n += r; -# if defined(OPENSSL_SYS_BEOS_R5) - if (r == 0) - snooze(t.tv_usec); -# endif - } else - r = -1; - - /* - * Some Unixen will update t in select(), some won't. For - * those who won't, or if we didn't use select() in the first - * place, give up here, otherwise, we will do this once again - * for the remaining time. - */ - if (usec == 10 * 1000) - usec = 0; - } - while ((r > 0 || - (errno == EINTR || errno == EAGAIN)) && usec != 0 - && n < ENTROPY_NEEDED); - - close(fd); - } - } -# endif /* defined(DEVRANDOM) */ - -# ifdef DEVRANDOM_EGD - /* - * Use an EGD socket to read entropy from an EGD or PRNGD entropy - * collecting daemon. - */ - - for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; - egdsocket++) { - int r; - - r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n, - ENTROPY_NEEDED - n); - if (r > 0) - n += r; - } -# endif /* defined(DEVRANDOM_EGD) */ - -# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) - if (n > 0) { - RAND_add(tmpbuf, sizeof(tmpbuf), (double)n); - OPENSSL_cleanse(tmpbuf, n); - } -# endif - - /* put in some default random data, we need more than just this */ - l = curr_pid; - RAND_add(&l, sizeof(l), 0.0); - l = getuid(); - RAND_add(&l, sizeof(l), 0.0); - - l = time(NULL); - RAND_add(&l, sizeof(l), 0.0); - -# if defined(OPENSSL_SYS_BEOS) - { - system_info sysInfo; - get_system_info(&sysInfo); - RAND_add(&sysInfo, sizeof(sysInfo), 0); - } -# endif - -# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) - return 1; -# else - return 0; -# endif -} - -# endif /* defined(__OpenBSD__) */ -#endif /* !(defined(OPENSSL_SYS_WINDOWS) || - * defined(OPENSSL_SYS_WIN32) || - * defined(OPENSSL_SYS_VMS) || - * defined(OPENSSL_SYS_OS2) || - * defined(OPENSSL_SYS_VXWORKS) || - * defined(OPENSSL_SYS_NETWARE)) */ - -#if defined(OPENSSL_SYS_VXWORKS) -int RAND_poll(void) -{ - return 0; -} -#endif -/* crypto/rand/rand_vms.c */ -/* - * Written by Richard Levitte for the OpenSSL project - * 2000. - */ -/* - * Modified by VMS Software, Inc (2016) - * Eliminate looping through all processes (performance) - * Add additional randomizations using rand() function - */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "rand.h" -// #include "rand_lcl.h" - -#if defined(OPENSSL_SYS_VMS) -# include -# include -# include -# include -# include -# ifdef __DECC -# pragma message disable DOLLARID -# endif - -/* - * Use 32-bit pointers almost everywhere. Define the type to which to cast a - * pointer passed to an external function. - */ -# if __INITIAL_POINTER_SIZE == 64 -# define PTR_T __void_ptr64 -# pragma pointer_size save -# pragma pointer_size 32 -# else /* __INITIAL_POINTER_SIZE == 64 */ -# define PTR_T void * -# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ - -static struct items_data_st { - short length, code; /* length is number of bytes */ -} items_data[] = { - {4, JPI$_BUFIO}, - {4, JPI$_CPUTIM}, - {4, JPI$_DIRIO}, - {4, JPI$_IMAGECOUNT}, - {8, JPI$_LAST_LOGIN_I}, - {8, JPI$_LOGINTIM}, - {4, JPI$_PAGEFLTS}, - {4, JPI$_PID}, - {4, JPI$_PPGCNT}, - {4, JPI$_WSPEAK}, - {4, JPI$_FINALEXC}, - {0, 0} /* zero terminated */ -}; - -int RAND_poll(void) -{ - - /* determine the number of items in the JPI array */ - - struct items_data_st item_entry; - int item_entry_count = sizeof(items_data)/sizeof(item_entry); - - /* Create the JPI itemlist array to hold item_data content */ - - struct { - short length, code; - int *buffer; - int *retlen; - } item[item_entry_count], *pitem; /* number of entries in items_data */ - - struct items_data_st *pitems_data; - pitems_data = items_data; - pitem = item; - int data_buffer[(item_entry_count*2)+4]; /* 8 bytes per entry max */ - int iosb[2]; - int sys_time[2]; - int *ptr; - int i, j ; - int tmp_length = 0; - int total_length = 0; - - /* Setup itemlist for GETJPI */ - - while (pitems_data->length) { - pitem->length = pitems_data->length; - pitem->code = pitems_data->code; - pitem->buffer = &data_buffer[total_length]; - pitem->retlen = 0; - /* total_length is in longwords */ - total_length += pitems_data->length/4; - pitems_data++; - pitem ++; - } - pitem->length = pitem->code = 0; - - /* Fill data_buffer with various info bits from this process */ - /* and twist that data to seed the SSL random number init */ - - if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) == SS$_NORMAL) { - for (i = 0; i < total_length; i++) { - sys$gettim((struct _generic_64 *)&sys_time[0]); - srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i); - - if (i == (total_length - 1)) { /* for JPI$_FINALEXC */ - ptr = &data_buffer[i]; - for (j = 0; j < 4; j++) { - data_buffer[i + j] = ptr[j]; - /* OK to use rand() just to scramble the seed */ - data_buffer[i + j] ^= (sys_time[0] ^ rand()); - tmp_length++; - } - } else { - /* OK to use rand() just to scramble the seed */ - data_buffer[i] ^= (sys_time[0] ^ rand()); - } - } - - total_length += (tmp_length - 1); - - /* size of seed is total_length*4 bytes (64bytes) */ - RAND_add((PTR_T) data_buffer, total_length*4, total_length * 2); - } else { - return 0; - } - - return 1; -} -#endif -/* crypto/rand/rand_win.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "rand.h" -// #include "rand_lcl.h" - -#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) -# include -# ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0400 -# endif -# include -# include - -/* - * Limit the time spent walking through the heap, processes, threads and - * modules to a maximum of 1000 miliseconds each, unless CryptoGenRandom - * failed - */ -# define MAXDELAY 1000 - -/* - * Intel hardware RNG CSP -- available from - * http://developer.intel.com/design/security/rng/redist_license.htm - */ -# define PROV_INTEL_SEC 22 -# define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider" - -static void readtimer(void); -static void readscreen(void); - -/* - * It appears like CURSORINFO, PCURSORINFO and LPCURSORINFO are only defined - * when WINVER is 0x0500 and up, which currently only happens on Win2000. - * Unfortunately, those are typedefs, so they're a little bit difficult to - * detect properly. On the other hand, the macro CURSOR_SHOWING is defined - * within the same conditional, so it can be use to detect the absence of - * said typedefs. - */ - -# ifndef CURSOR_SHOWING -/* - * Information about the global cursor. - */ -typedef struct tagCURSORINFO { - DWORD cbSize; - DWORD flags; - HCURSOR hCursor; - POINT ptScreenPos; -} CURSORINFO, *PCURSORINFO, *LPCURSORINFO; - -# define CURSOR_SHOWING 0x00000001 -# endif /* CURSOR_SHOWING */ - -# if !defined(OPENSSL_SYS_WINCE) -typedef BOOL(WINAPI *CRYPTACQUIRECONTEXTW) (HCRYPTPROV *, LPCWSTR, LPCWSTR, - DWORD, DWORD); -typedef BOOL(WINAPI *CRYPTGENRANDOM) (HCRYPTPROV, DWORD, BYTE *); -typedef BOOL(WINAPI *CRYPTRELEASECONTEXT) (HCRYPTPROV, DWORD); - -typedef HWND(WINAPI *GETFOREGROUNDWINDOW) (VOID); -typedef BOOL(WINAPI *GETCURSORINFO) (PCURSORINFO); -typedef DWORD(WINAPI *GETQUEUESTATUS) (UINT); - -typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD); -typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE); -typedef BOOL(WINAPI *HEAP32FIRST) (LPHEAPENTRY32, DWORD, size_t); -typedef BOOL(WINAPI *HEAP32NEXT) (LPHEAPENTRY32); -typedef BOOL(WINAPI *HEAP32LIST) (HANDLE, LPHEAPLIST32); -typedef BOOL(WINAPI *PROCESS32) (HANDLE, LPPROCESSENTRY32); -typedef BOOL(WINAPI *THREAD32) (HANDLE, LPTHREADENTRY32); -typedef BOOL(WINAPI *MODULE32) (HANDLE, LPMODULEENTRY32); - -# include -# include -# if 1 -/* - * The NET API is Unicode only. It requires the use of the UNICODE macro. - * When UNICODE is defined LPTSTR becomes LPWSTR. LMSTR was was added to the - * Platform SDK to allow the NET API to be used in non-Unicode applications - * provided that Unicode strings were still used for input. LMSTR is defined - * as LPWSTR. - */ -typedef NET_API_STATUS(NET_API_FUNCTION *NETSTATGET) - (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE *); -typedef NET_API_STATUS(NET_API_FUNCTION *NETFREE) (LPBYTE); -# endif /* 1 */ -# endif /* !OPENSSL_SYS_WINCE */ - -#define NOTTOOLONG(start) ((GetTickCount() - (start)) < MAXDELAY) - -int RAND_poll(void) -{ - MEMORYSTATUS m; - HCRYPTPROV hProvider = 0; - DWORD w; - int good = 0; - -# if defined(OPENSSL_SYS_WINCE) -# if defined(_WIN32_WCE) && _WIN32_WCE>=300 - /* - * Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available - * in commonly available implementations prior 300... - */ - { - BYTE buf[64]; - /* poll the CryptoAPI PRNG */ - /* The CryptoAPI returns sizeof(buf) bytes of randomness */ - if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - if (CryptGenRandom(hProvider, sizeof(buf), buf)) - RAND_add(buf, sizeof(buf), sizeof(buf)); - CryptReleaseContext(hProvider, 0); - } - } -# endif -# else /* OPENSSL_SYS_WINCE */ - /* - * None of below libraries are present on Windows CE, which is - * why we #ifndef the whole section. This also excuses us from - * handling the GetProcAddress issue. The trouble is that in - * real Win32 API GetProcAddress is available in ANSI flavor - * only. In WinCE on the other hand GetProcAddress is a macro - * most commonly defined as GetProcAddressW, which accepts - * Unicode argument. If we were to call GetProcAddress under - * WinCE, I'd recommend to either redefine GetProcAddress as - * GetProcAddressA (there seem to be one in common CE spec) or - * implement own shim routine, which would accept ANSI argument - * and expand it to Unicode. - */ - { - /* load functions dynamically - not available on all systems */ - HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL")); - HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL")); - HMODULE user = NULL; - HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL")); - CRYPTACQUIRECONTEXTW acquire = NULL; - CRYPTGENRANDOM gen = NULL; - CRYPTRELEASECONTEXT release = NULL; - NETSTATGET netstatget = NULL; - NETFREE netfree = NULL; - BYTE buf[64]; - - if (netapi) { - netstatget = - (NETSTATGET) GetProcAddress(netapi, "NetStatisticsGet"); - netfree = (NETFREE) GetProcAddress(netapi, "NetApiBufferFree"); - } - - if (netstatget && netfree) { - LPBYTE outbuf; - /* - * NetStatisticsGet() is a Unicode only function - * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0 - * contains 17 fields. We treat each field as a source of one - * byte of entropy. - */ - - if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0) { - RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45); - netfree(outbuf); - } - if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0) { - RAND_add(outbuf, sizeof(STAT_SERVER_0), 17); - netfree(outbuf); - } - } - - if (netapi) - FreeLibrary(netapi); - - /* - * It appears like this can cause an exception deep within - * ADVAPI32.DLL at random times on Windows 2000. Reported by Jeffrey - * Altman. Only use it on NT. - */ - - if (advapi) { - /* - * If it's available, then it's available in both ANSI - * and UNICODE flavors even in Win9x, documentation says. - * We favor Unicode... - */ - acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi, - "CryptAcquireContextW"); - gen = (CRYPTGENRANDOM) GetProcAddress(advapi, "CryptGenRandom"); - release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi, - "CryptReleaseContext"); - } - - if (acquire && gen && release) { - /* poll the CryptoAPI PRNG */ - /* The CryptoAPI returns sizeof(buf) bytes of randomness */ - if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - if (gen(hProvider, sizeof(buf), buf) != 0) { - RAND_add(buf, sizeof(buf), 0); - good = 1; -# if 0 - printf("randomness from PROV_RSA_FULL\n"); -# endif - } - release(hProvider, 0); - } - - /* poll the Pentium PRG with CryptoAPI */ - if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0)) { - if (gen(hProvider, sizeof(buf), buf) != 0) { - RAND_add(buf, sizeof(buf), sizeof(buf)); - good = 1; -# if 0 - printf("randomness from PROV_INTEL_SEC\n"); -# endif - } - release(hProvider, 0); - } - } - - if (advapi) - FreeLibrary(advapi); - - if ((!check_winnt() || - !OPENSSL_isservice()) && - (user = LoadLibrary(TEXT("USER32.DLL")))) { - GETCURSORINFO cursor; - GETFOREGROUNDWINDOW win; - GETQUEUESTATUS queue; - - win = - (GETFOREGROUNDWINDOW) GetProcAddress(user, - "GetForegroundWindow"); - cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo"); - queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus"); - - if (win) { - /* window handle */ - HWND h = win(); - RAND_add(&h, sizeof(h), 0); - } - if (cursor) { - /* - * unfortunately, its not safe to call GetCursorInfo() on NT4 - * even though it exists in SP3 (or SP6) and higher. - */ - if (check_winnt() && !check_win_minplat(5)) - cursor = 0; - } - if (cursor) { - /* cursor position */ - /* assume 2 bytes of entropy */ - CURSORINFO ci; - ci.cbSize = sizeof(CURSORINFO); - if (cursor(&ci)) - RAND_add(&ci, ci.cbSize, 2); - } - - if (queue) { - /* message queue status */ - /* assume 1 byte of entropy */ - w = queue(QS_ALLEVENTS); - RAND_add(&w, sizeof(w), 1); - } - - FreeLibrary(user); - } - - /*- - * Toolhelp32 snapshot: enumerate processes, threads, modules and heap - * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm - * (Win 9x and 2000 only, not available on NT) - * - * This seeding method was proposed in Peter Gutmann, Software - * Generation of Practically Strong Random Numbers, - * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html - * revised version at http://www.cryptoengines.com/~peter/06_random.pdf - * (The assignment of entropy estimates below is arbitrary, but based - * on Peter's analysis the full poll appears to be safe. Additional - * interactive seeding is encouraged.) - */ - - if (kernel) { - CREATETOOLHELP32SNAPSHOT snap; - CLOSETOOLHELP32SNAPSHOT close_snap; - HANDLE handle; - - HEAP32FIRST heap_first; - HEAP32NEXT heap_next; - HEAP32LIST heaplist_first, heaplist_next; - PROCESS32 process_first, process_next; - THREAD32 thread_first, thread_next; - MODULE32 module_first, module_next; - - HEAPLIST32 hlist; - HEAPENTRY32 hentry; - PROCESSENTRY32 p; - THREADENTRY32 t; - MODULEENTRY32 m; - DWORD starttime = 0; - - snap = (CREATETOOLHELP32SNAPSHOT) - GetProcAddress(kernel, "CreateToolhelp32Snapshot"); - close_snap = (CLOSETOOLHELP32SNAPSHOT) - GetProcAddress(kernel, "CloseToolhelp32Snapshot"); - heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First"); - heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next"); - heaplist_first = - (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst"); - heaplist_next = - (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext"); - process_first = - (PROCESS32) GetProcAddress(kernel, "Process32First"); - process_next = - (PROCESS32) GetProcAddress(kernel, "Process32Next"); - thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First"); - thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next"); - module_first = (MODULE32) GetProcAddress(kernel, "Module32First"); - module_next = (MODULE32) GetProcAddress(kernel, "Module32Next"); - - if (snap && heap_first && heap_next && heaplist_first && - heaplist_next && process_first && process_next && - thread_first && thread_next && module_first && - module_next && (handle = snap(TH32CS_SNAPALL, 0)) - != INVALID_HANDLE_VALUE) { - /* heap list and heap walking */ - /* - * HEAPLIST32 contains 3 fields that will change with each - * entry. Consider each field a source of 1 byte of entropy. - * HEAPENTRY32 contains 5 fields that will change with each - * entry. Consider each field a source of 1 byte of entropy. - */ - ZeroMemory(&hlist, sizeof(HEAPLIST32)); - hlist.dwSize = sizeof(HEAPLIST32); - if (good) - starttime = GetTickCount(); -# ifdef _MSC_VER - if (heaplist_first(handle, &hlist)) { - /* - * following discussion on dev ML, exception on WinCE (or - * other Win platform) is theoretically of unknown - * origin; prevent infinite loop here when this - * theoretical case occurs; otherwise cope with the - * expected (MSDN documented) exception-throwing - * behaviour of Heap32Next() on WinCE. - * - * based on patch in original message by Tanguy Fautré - * (2009/03/02) Subject: RAND_poll() and - * CreateToolhelp32Snapshot() stability - */ - int ex_cnt_limit = 42; - do { - RAND_add(&hlist, hlist.dwSize, 3); - __try { - ZeroMemory(&hentry, sizeof(HEAPENTRY32)); - hentry.dwSize = sizeof(HEAPENTRY32); - if (heap_first(&hentry, - hlist.th32ProcessID, - hlist.th32HeapID)) { - int entrycnt = 80; - do - RAND_add(&hentry, hentry.dwSize, 5); - while (heap_next(&hentry) - && (!good || NOTTOOLONG(starttime)) - && --entrycnt > 0); - } - } - __except(EXCEPTION_EXECUTE_HANDLER) { - /* - * ignore access violations when walking the heap - * list - */ - ex_cnt_limit--; - } - } while (heaplist_next(handle, &hlist) - && (!good || NOTTOOLONG(starttime)) - && ex_cnt_limit > 0); - } -# else - if (heaplist_first(handle, &hlist)) { - do { - RAND_add(&hlist, hlist.dwSize, 3); - hentry.dwSize = sizeof(HEAPENTRY32); - if (heap_first(&hentry, - hlist.th32ProcessID, - hlist.th32HeapID)) { - int entrycnt = 80; - do - RAND_add(&hentry, hentry.dwSize, 5); - while (heap_next(&hentry) - && (!good || NOTTOOLONG(starttime)) - && --entrycnt > 0); - } - } while (heaplist_next(handle, &hlist) - && (!good || NOTTOOLONG(starttime))); - } -# endif - - /* process walking */ - /* - * PROCESSENTRY32 contains 9 fields that will change with - * each entry. Consider each field a source of 1 byte of - * entropy. - */ - p.dwSize = sizeof(PROCESSENTRY32); - - if (good) - starttime = GetTickCount(); - if (process_first(handle, &p)) - do - RAND_add(&p, p.dwSize, 9); - while (process_next(handle, &p) - && (!good || NOTTOOLONG(starttime))); - - /* thread walking */ - /* - * THREADENTRY32 contains 6 fields that will change with each - * entry. Consider each field a source of 1 byte of entropy. - */ - t.dwSize = sizeof(THREADENTRY32); - if (good) - starttime = GetTickCount(); - if (thread_first(handle, &t)) - do - RAND_add(&t, t.dwSize, 6); - while (thread_next(handle, &t) - && (!good || NOTTOOLONG(starttime))); - - /* module walking */ - /* - * MODULEENTRY32 contains 9 fields that will change with each - * entry. Consider each field a source of 1 byte of entropy. - */ - m.dwSize = sizeof(MODULEENTRY32); - if (good) - starttime = GetTickCount(); - if (module_first(handle, &m)) - do - RAND_add(&m, m.dwSize, 9); - while (module_next(handle, &m) - && (!good || NOTTOOLONG(starttime))); - if (close_snap) - close_snap(handle); - else - CloseHandle(handle); - - } - - FreeLibrary(kernel); - } - } -# endif /* !OPENSSL_SYS_WINCE */ - - /* timer data */ - readtimer(); - - /* memory usage statistics */ - GlobalMemoryStatus(&m); - RAND_add(&m, sizeof(m), 1); - - /* process ID */ - w = GetCurrentProcessId(); - RAND_add(&w, sizeof(w), 1); - -# if 0 - printf("Exiting RAND_poll\n"); -# endif - - return (1); -} - -int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) -{ - double add_entropy = 0; - - switch (iMsg) { - case WM_KEYDOWN: - { - static WPARAM key; - if (key != wParam) - add_entropy = 0.05; - key = wParam; - } - break; - case WM_MOUSEMOVE: - { - static int lastx, lasty, lastdx, lastdy; - int x, y, dx, dy; - - x = LOWORD(lParam); - y = HIWORD(lParam); - dx = lastx - x; - dy = lasty - y; - if (dx != 0 && dy != 0 && dx - lastdx != 0 && dy - lastdy != 0) - add_entropy = .2; - lastx = x, lasty = y; - lastdx = dx, lastdy = dy; - } - break; - } - - readtimer(); - RAND_add(&iMsg, sizeof(iMsg), add_entropy); - RAND_add(&wParam, sizeof(wParam), 0); - RAND_add(&lParam, sizeof(lParam), 0); - - return (RAND_status()); -} - -void RAND_screen(void) -{ /* function available for backward - * compatibility */ - RAND_poll(); - readscreen(); -} - -/* feed timing information to the PRNG */ -static void readtimer(void) -{ - DWORD w; - LARGE_INTEGER l; - static int have_perfc = 1; -# if defined(_MSC_VER) && defined(_M_X86) - static int have_tsc = 1; - DWORD cyclecount; - - if (have_tsc) { - __try { - __asm { - _emit 0x0f _emit 0x31 mov cyclecount, eax} - RAND_add(&cyclecount, sizeof(cyclecount), 1); - } - __except(EXCEPTION_EXECUTE_HANDLER) { - have_tsc = 0; - } - } -# else -# define have_tsc 0 -# endif - - if (have_perfc) { - if (QueryPerformanceCounter(&l) == 0) - have_perfc = 0; - else - RAND_add(&l, sizeof(l), 0); - } - - if (!have_tsc && !have_perfc) { - w = GetTickCount(); - RAND_add(&w, sizeof(w), 0); - } -} - -/* feed screen contents to PRNG */ -/***************************************************************************** - * - * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V. - * - * Code adapted from - * ; - * the original copyright message is: - * - * (C) Copyright Microsoft Corp. 1993. All rights reserved. - * - * You have a royalty-free right to use, modify, reproduce and - * distribute the Sample Files (and/or any modified version) in - * any way you find useful, provided that you agree that - * Microsoft has no warranty obligations or liability for any - * Sample Application Files which are modified. - */ - -static void readscreen(void) -{ -# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) - HDC hScrDC; /* screen DC */ - HBITMAP hBitmap; /* handle for our bitmap */ - BITMAP bm; /* bitmap properties */ - unsigned int size; /* size of bitmap */ - char *bmbits; /* contents of bitmap */ - int w; /* screen width */ - int h; /* screen height */ - int y; /* y-coordinate of screen lines to grab */ - int n = 16; /* number of screen lines to grab at a time */ - BITMAPINFOHEADER bi; /* info about the bitmap */ - - if (check_winnt() && OPENSSL_isservice() > 0) - return; - - /* Get a reference to the screen DC */ - hScrDC = GetDC(NULL); - - /* Get screen resolution */ - w = GetDeviceCaps(hScrDC, HORZRES); - h = GetDeviceCaps(hScrDC, VERTRES); - - /* Create a bitmap compatible with the screen DC */ - hBitmap = CreateCompatibleBitmap(hScrDC, w, n); - - /* Get bitmap properties */ - GetObject(hBitmap, sizeof(bm), (LPSTR)&bm); - size = (unsigned int)4 * bm.bmHeight * bm.bmWidth; - bi.biSize = sizeof(bi); - bi.biWidth = bm.bmWidth; - bi.biHeight = bm.bmHeight; - bi.biPlanes = 1; - bi.biBitCount = 32; - bi.biCompression = BI_RGB; - bi.biSizeImage = 0; - bi.biXPelsPerMeter = 0; - bi.biYPelsPerMeter = 0; - bi.biClrUsed = 0; - bi.biClrImportant = 0; - - bmbits = OPENSSL_malloc(size); - if (bmbits) { - /* Now go through the whole screen, repeatedly grabbing n lines */ - for (y = 0; y < h - n; y += n) { - unsigned char md[MD_DIGEST_LENGTH]; - - /* Copy the bits of the current line range into the buffer */ - GetDIBits(hScrDC, hBitmap, y, n, - bmbits, (LPBITMAPINFO)&bi, DIB_RGB_COLORS); - - /* Get the hash of the bitmap */ - MD(bmbits, size, md); - - /* Seed the random generator with the hash value */ - RAND_add(md, MD_DIGEST_LENGTH, 0); - } - - OPENSSL_free(bmbits); - } - - /* Clean up */ - DeleteObject(hBitmap); - ReleaseDC(NULL, hScrDC); -# endif /* !OPENSSL_SYS_WINCE */ -} - -#endif diff --git a/Sources/COpenSSL/rand_lcl.h b/Sources/COpenSSL/rand_lcl.h deleted file mode 100644 index 500a44a2..00000000 --- a/Sources/COpenSSL/rand_lcl.h +++ /dev/null @@ -1,158 +0,0 @@ -/* crypto/rand/rand_lcl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_RAND_LCL_H -# define HEADER_RAND_LCL_H - -# define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */ - -# if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) -# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) -# define USE_SHA1_RAND -# elif !defined(OPENSSL_NO_MD5) -# define USE_MD5_RAND -# elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES) -# define USE_MDC2_RAND -# elif !defined(OPENSSL_NO_MD2) -# define USE_MD2_RAND -# else -# error No message digest algorithm available -# endif -# endif - -# include "evp.h" -# define MD_Update(a,b,c) EVP_DigestUpdate(a,b,c) -# define MD_Final(a,b) EVP_DigestFinal_ex(a,b,NULL) -# if defined(USE_MD5_RAND) -# include "md5.h" -# define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH -# define MD_Init(a) EVP_DigestInit_ex(a,EVP_md5(), NULL) -# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md5(), NULL) -# elif defined(USE_SHA1_RAND) -# include "sha.h" -# define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH -# define MD_Init(a) EVP_DigestInit_ex(a,EVP_sha1(), NULL) -# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL) -# elif defined(USE_MDC2_RAND) -# include "mdc2.h" -# define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH -# define MD_Init(a) EVP_DigestInit_ex(a,EVP_mdc2(), NULL) -# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL) -# elif defined(USE_MD2_RAND) -# include -# define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH -# define MD_Init(a) EVP_DigestInit_ex(a,EVP_md2(), NULL) -# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL) -# endif - -int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock); -int ssleay_rand_bytes_from_system(unsigned char *buf, int num); -#endif diff --git a/Sources/COpenSSL/randfile.c b/Sources/COpenSSL/randfile.c deleted file mode 100644 index db4ca5b2..00000000 --- a/Sources/COpenSSL/randfile.c +++ /dev/null @@ -1,372 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/rand/randfile.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include - -#include "cryptlib.h" -#include "e_os.h" -#include "crypto.h" -#include "rand.h" -#include "buffer.h" - -#ifdef OPENSSL_SYS_VMS -# include -#endif -#ifndef NO_SYS_TYPES_H -# include -#endif -#ifndef OPENSSL_NO_POSIX_IO -# include -# include -/* - * Following should not be needed, and we could have been stricter - * and demand S_IS*. But some systems just don't comply... Formally - * below macros are "anatomically incorrect", because normally they - * would look like ((m) & MASK == TYPE), but since MASK availability - * is as questionable, we settle for this poor-man fallback... - */ -# if !defined(S_ISBLK) -# if defined(_S_IFBLK) -# define S_ISBLK(m) ((m) & _S_IFBLK) -# elif defined(S_IFBLK) -# define S_ISBLK(m) ((m) & S_IFBLK) -# elif defined(_WIN32) -# define S_ISBLK(m) 0 /* no concept of block devices on Windows */ -# endif -# endif -# if !defined(S_ISCHR) -# if defined(_S_IFCHR) -# define S_ISCHR(m) ((m) & _S_IFCHR) -# elif defined(S_IFCHR) -# define S_ISCHR(m) ((m) & S_IFCHR) -# endif -# endif -#endif - -#ifdef _WIN32 -# define stat _stat -# define chmod _chmod -# define open _open -# define fdopen _fdopen -#endif - -#undef BUFSIZE -#define BUFSIZE 1024 -#define RAND_DATA 1024 - -#if (defined(OPENSSL_SYS_VMS) && (defined(__alpha) || defined(__ia64))) -/* - * This declaration is a nasty hack to get around vms' extension to fopen for - * passing in sharing options being disabled by our /STANDARD=ANSI89 - */ -static FILE *(*const vms_fopen)(const char *, const char *, ...) = - (FILE *(*)(const char *, const char *, ...))fopen; -# define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0" -#endif - -/* #define RFILE ".rnd" - defined in ../../e_os.h */ - -/* - * Note that these functions are intended for seed files only. Entropy - * devices and EGD sockets are handled in rand_unix.c - */ - -int RAND_load_file(const char *file, long bytes) -{ - /*- - * If bytes >= 0, read up to 'bytes' bytes. - * if bytes == -1, read complete file. - */ - - MS_STATIC unsigned char buf[BUFSIZE]; -#ifndef OPENSSL_NO_POSIX_IO - struct stat sb; -#endif - int i, ret = 0, n; -/* - * If setvbuf() is to be called, then the FILE pointer - * to it must be 32 bit. -*/ - -#if !defined OPENSSL_NO_SETVBUF_IONBF && defined(OPENSSL_SYS_VMS) && defined(__VMS_VER) && (__VMS_VER >= 70000000) - /* For 64-bit-->32 bit API Support*/ -#if __INITIAL_POINTER_SIZE == 64 -#pragma __required_pointer_size __save -#pragma __required_pointer_size 32 -#endif - FILE *in; /* setvbuf() requires 32-bit pointers */ -#if __INITIAL_POINTER_SIZE == 64 -#pragma __required_pointer_size __restore -#endif -#else - FILE *in; -#endif /* OPENSSL_SYS_VMS */ - - if (file == NULL) - return (0); - -#ifndef OPENSSL_NO_POSIX_IO -# ifdef PURIFY - /* - * struct stat can have padding and unused fields that may not be - * initialized in the call to stat(). We need to clear the entire - * structure before calling RAND_add() to avoid complaints from - * applications such as Valgrind. - */ - memset(&sb, 0, sizeof(sb)); -# endif - if (stat(file, &sb) < 0) - return (0); - RAND_add(&sb, sizeof(sb), 0.0); -#endif - if (bytes == 0) - return (ret); - -#ifdef OPENSSL_SYS_VMS - in = vms_fopen(file, "rb", VMS_OPEN_ATTRS); -#else - in = fopen(file, "rb"); -#endif - if (in == NULL) - goto err; -#if defined(S_ISBLK) && defined(S_ISCHR) && !defined(OPENSSL_NO_POSIX_IO) - if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { - /* - * this file is a device. we don't want read an infinite number of - * bytes from a random device, nor do we want to use buffered I/O - * because we will waste system entropy. - */ - bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */ -# ifndef OPENSSL_NO_SETVBUF_IONBF - setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */ -# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ - } -#endif - for (;;) { - if (bytes > 0) - n = (bytes < BUFSIZE) ? (int)bytes : BUFSIZE; - else - n = BUFSIZE; - i = fread(buf, 1, n, in); - if (i <= 0) - break; -#ifdef PURIFY - RAND_add(buf, i, (double)i); -#else - /* even if n != i, use the full array */ - RAND_add(buf, n, (double)i); -#endif - ret += i; - if (bytes > 0) { - bytes -= n; - if (bytes <= 0) - break; - } - } - fclose(in); - OPENSSL_cleanse(buf, BUFSIZE); - err: - return (ret); -} - -int RAND_write_file(const char *file) -{ - unsigned char buf[BUFSIZE]; - int i, ret = 0, rand_err = 0; - FILE *out = NULL; - int n; -#ifndef OPENSSL_NO_POSIX_IO - struct stat sb; - - i = stat(file, &sb); - if (i != -1) { -# if defined(S_ISBLK) && defined(S_ISCHR) - if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { - /* - * this file is a device. we don't write back to it. we - * "succeed" on the assumption this is some sort of random - * device. Otherwise attempting to write to and chmod the device - * causes problems. - */ - return (1); - } -# endif - } -#endif - -#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS) - { -# ifndef O_BINARY -# define O_BINARY 0 -# endif - /* - * chmod(..., 0600) is too late to protect the file, permissions - * should be restrictive from the start - */ - int fd = open(file, O_WRONLY | O_CREAT | O_BINARY, 0600); - if (fd != -1) - out = fdopen(fd, "wb"); - } -#endif - -#if (defined(OPENSSL_SYS_VMS) && (defined(__alpha) || defined(__ia64))) - /* - * VMS NOTE: Prior versions of this routine created a _new_ version of - * the rand file for each call into this routine, then deleted all - * existing versions named ;-1, and finally renamed the current version - * as ';1'. Under concurrent usage, this resulted in an RMS race - * condition in rename() which could orphan files (see vms message help - * for RMS$_REENT). With the fopen() calls below, openssl/VMS now shares - * the top-level version of the rand file. Note that there may still be - * conditions where the top-level rand file is locked. If so, this code - * will then create a new version of the rand file. Without the delete - * and rename code, this can result in ascending file versions that stop - * at version 32767, and this routine will then return an error. The - * remedy for this is to recode the calling application to avoid - * concurrent use of the rand file, or synchronize usage at the - * application level. Also consider whether or not you NEED a persistent - * rand file in a concurrent use situation. - */ - - out = vms_fopen(file, "rb+", VMS_OPEN_ATTRS); - if (out == NULL) - out = vms_fopen(file, "wb", VMS_OPEN_ATTRS); -#else - if (out == NULL) - out = fopen(file, "wb"); -#endif - if (out == NULL) - goto err; - -#ifndef NO_CHMOD - chmod(file, 0600); -#endif - n = RAND_DATA; - for (;;) { - i = (n > BUFSIZE) ? BUFSIZE : n; - n -= BUFSIZE; - if (RAND_bytes(buf, i) <= 0) - rand_err = 1; - i = fwrite(buf, 1, i, out); - if (i <= 0) { - ret = 0; - break; - } - ret += i; - if (n <= 0) - break; - } - - fclose(out); - OPENSSL_cleanse(buf, BUFSIZE); - err: - return (rand_err ? -1 : ret); -} - -const char *RAND_file_name(char *buf, size_t size) -{ - char *s = NULL; -#ifdef __OpenBSD__ - struct stat sb; -#endif - - s = ossl_safe_getenv("RANDFILE"); - if (s != NULL && *s && strlen(s) + 1 < size) { - if (BUF_strlcpy(buf, s, size) >= size) - return NULL; - } else { - s = ossl_safe_getenv("HOME"); -#ifdef DEFAULT_HOME - if (s == NULL) { - s = DEFAULT_HOME; - } -#endif - if (s && *s && strlen(s) + strlen(RFILE) + 2 < size) { - BUF_strlcpy(buf, s, size); -#ifndef OPENSSL_SYS_VMS - BUF_strlcat(buf, "/", size); -#endif - BUF_strlcat(buf, RFILE, size); - } else - buf[0] = '\0'; /* no file name */ - } - -#ifdef __OpenBSD__ - /* - * given that all random loads just fail if the file can't be seen on a - * stat, we stat the file we're returning, if it fails, use /dev/arandom - * instead. this allows the user to use their own source for good random - * data, but defaults to something hopefully decent if that isn't - * available. - */ - - if (!buf[0]) - if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) { - return (NULL); - } - if (stat(buf, &sb) == -1) - if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) { - return (NULL); - } -#endif - return (buf); -} diff --git a/Sources/COpenSSL/rc2.h b/Sources/COpenSSL/rc2.h deleted file mode 100644 index fb887701..00000000 --- a/Sources/COpenSSL/rc2.h +++ /dev/null @@ -1,103 +0,0 @@ -/* crypto/rc2/rc2.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_RC2_H -# define HEADER_RC2_H - -# include "opensslconf.h"/* OPENSSL_NO_RC2, RC2_INT */ -# ifdef OPENSSL_NO_RC2 -# error RC2 is disabled. -# endif - -# define RC2_ENCRYPT 1 -# define RC2_DECRYPT 0 - -# define RC2_BLOCK 8 -# define RC2_KEY_LENGTH 16 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct rc2_key_st { - RC2_INT data[64]; -} RC2_KEY; - -# ifdef OPENSSL_FIPS -void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, - int bits); -# endif -void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); -void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, - RC2_KEY *key, int enc); -void RC2_encrypt(unsigned long *data, RC2_KEY *key); -void RC2_decrypt(unsigned long *data, RC2_KEY *key); -void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, - RC2_KEY *ks, unsigned char *iv, int enc); -void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, RC2_KEY *schedule, unsigned char *ivec, - int *num, int enc); -void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, RC2_KEY *schedule, unsigned char *ivec, - int *num); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/rc2_.c b/Sources/COpenSSL/rc2_.c deleted file mode 100644 index 7ca86e23..00000000 --- a/Sources/COpenSSL/rc2_.c +++ /dev/null @@ -1,477 +0,0 @@ -/* crypto/rc2/rc2_cbc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "rc2.h" -#include "rc2_locl.h" - -void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, - RC2_KEY *ks, unsigned char *iv, int encrypt) -{ - register unsigned long tin0, tin1; - register unsigned long tout0, tout1, xor0, xor1; - register long l = length; - unsigned long tin[2]; - - if (encrypt) { - c2l(iv, tout0); - c2l(iv, tout1); - iv -= 8; - for (l -= 8; l >= 0; l -= 8) { - c2l(in, tin0); - c2l(in, tin1); - tin0 ^= tout0; - tin1 ^= tout1; - tin[0] = tin0; - tin[1] = tin1; - RC2_encrypt(tin, ks); - tout0 = tin[0]; - l2c(tout0, out); - tout1 = tin[1]; - l2c(tout1, out); - } - if (l != -8) { - c2ln(in, tin0, tin1, l + 8); - tin0 ^= tout0; - tin1 ^= tout1; - tin[0] = tin0; - tin[1] = tin1; - RC2_encrypt(tin, ks); - tout0 = tin[0]; - l2c(tout0, out); - tout1 = tin[1]; - l2c(tout1, out); - } - l2c(tout0, iv); - l2c(tout1, iv); - } else { - c2l(iv, xor0); - c2l(iv, xor1); - iv -= 8; - for (l -= 8; l >= 0; l -= 8) { - c2l(in, tin0); - tin[0] = tin0; - c2l(in, tin1); - tin[1] = tin1; - RC2_decrypt(tin, ks); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2c(tout0, out); - l2c(tout1, out); - xor0 = tin0; - xor1 = tin1; - } - if (l != -8) { - c2l(in, tin0); - tin[0] = tin0; - c2l(in, tin1); - tin[1] = tin1; - RC2_decrypt(tin, ks); - tout0 = tin[0] ^ xor0; - tout1 = tin[1] ^ xor1; - l2cn(tout0, tout1, out, l + 8); - xor0 = tin0; - xor1 = tin1; - } - l2c(xor0, iv); - l2c(xor1, iv); - } - tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; - tin[0] = tin[1] = 0; -} - -void RC2_encrypt(unsigned long *d, RC2_KEY *key) -{ - int i, n; - register RC2_INT *p0, *p1; - register RC2_INT x0, x1, x2, x3, t; - unsigned long l; - - l = d[0]; - x0 = (RC2_INT) l & 0xffff; - x1 = (RC2_INT) (l >> 16L); - l = d[1]; - x2 = (RC2_INT) l & 0xffff; - x3 = (RC2_INT) (l >> 16L); - - n = 3; - i = 5; - - p0 = p1 = &(key->data[0]); - for (;;) { - t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; - x0 = (t << 1) | (t >> 15); - t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; - x1 = (t << 2) | (t >> 14); - t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; - x2 = (t << 3) | (t >> 13); - t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; - x3 = (t << 5) | (t >> 11); - - if (--i == 0) { - if (--n == 0) - break; - i = (n == 2) ? 6 : 5; - - x0 += p1[x3 & 0x3f]; - x1 += p1[x0 & 0x3f]; - x2 += p1[x1 & 0x3f]; - x3 += p1[x2 & 0x3f]; - } - } - - d[0] = - (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); - d[1] = - (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); -} - -void RC2_decrypt(unsigned long *d, RC2_KEY *key) -{ - int i, n; - register RC2_INT *p0, *p1; - register RC2_INT x0, x1, x2, x3, t; - unsigned long l; - - l = d[0]; - x0 = (RC2_INT) l & 0xffff; - x1 = (RC2_INT) (l >> 16L); - l = d[1]; - x2 = (RC2_INT) l & 0xffff; - x3 = (RC2_INT) (l >> 16L); - - n = 3; - i = 5; - - p0 = &(key->data[63]); - p1 = &(key->data[0]); - for (;;) { - t = ((x3 << 11) | (x3 >> 5)) & 0xffff; - x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff; - t = ((x2 << 13) | (x2 >> 3)) & 0xffff; - x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff; - t = ((x1 << 14) | (x1 >> 2)) & 0xffff; - x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff; - t = ((x0 << 15) | (x0 >> 1)) & 0xffff; - x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff; - - if (--i == 0) { - if (--n == 0) - break; - i = (n == 2) ? 6 : 5; - - x3 = (x3 - p1[x2 & 0x3f]) & 0xffff; - x2 = (x2 - p1[x1 & 0x3f]) & 0xffff; - x1 = (x1 - p1[x0 & 0x3f]) & 0xffff; - x0 = (x0 - p1[x3 & 0x3f]) & 0xffff; - } - } - - d[0] = - (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); - d[1] = - (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); -} -/* crypto/rc2/rc2_ecb.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "rc2.h" -// #include "rc2_locl.h" -#include "opensslv.h" - -const char RC2_version[] = "RC2" OPENSSL_VERSION_PTEXT; - -/*- - * RC2 as implemented frm a posting from - * Newsgroups: sci.crypt - * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann) - * Subject: Specification for Ron Rivests Cipher No.2 - * Message-ID: <4fk39f$f70@net.auckland.ac.nz> - * Date: 11 Feb 1996 06:45:03 GMT - */ - -void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks, - int encrypt) -{ - unsigned long l, d[2]; - - c2l(in, l); - d[0] = l; - c2l(in, l); - d[1] = l; - if (encrypt) - RC2_encrypt(d, ks); - else - RC2_decrypt(d, ks); - l = d[0]; - l2c(l, out); - l = d[1]; - l2c(l, out); - l = d[0] = d[1] = 0; -} -/* crypto/rc2/rc2_skey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "crypto.h" -// #include "rc2.h" -// #include "rc2_locl.h" - -static const unsigned char key_table[256] = { - 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, - 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, - 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5, - 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, - 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, - 0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, - 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f, - 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, - 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, - 0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, - 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde, - 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, - 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, - 0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, - 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85, - 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, - 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, - 0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, - 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b, - 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, - 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, - 0xfe, 0x7f, 0xc1, 0xad, -}; - -#if defined(_MSC_VER) && defined(_ARM_) -# pragma optimize("g",off) -#endif - -/* - * It has come to my attention that there are 2 versions of the RC2 key - * schedule. One which is normal, and anther which has a hook to use a - * reduced key length. BSAFE uses the 'retarded' version. What I previously - * shipped is the same as specifying 1024 for the 'bits' parameter. Bsafe - * uses a version where the bits parameter is the same as len*8 - */ -void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) -#ifdef OPENSSL_FIPS -{ - fips_cipher_abort(RC2); - private_RC2_set_key(key, len, data, bits); -} - -void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, - int bits) -#endif -{ - int i, j; - unsigned char *k; - RC2_INT *ki; - unsigned int c, d; - - k = (unsigned char *)&(key->data[0]); - *k = 0; /* for if there is a zero length key */ - - if (len > 128) - len = 128; - if (bits <= 0) - bits = 1024; - if (bits > 1024) - bits = 1024; - - for (i = 0; i < len; i++) - k[i] = data[i]; - - /* expand table */ - d = k[len - 1]; - j = 0; - for (i = len; i < 128; i++, j++) { - d = key_table[(k[j] + d) & 0xff]; - k[i] = d; - } - - /* hmm.... key reduction to 'bits' bits */ - - j = (bits + 7) >> 3; - i = 128 - j; - c = (0xff >> (-bits & 0x07)); - - d = key_table[k[i] & c]; - k[i] = d; - while (i--) { - d = key_table[k[i + j] ^ d]; - k[i] = d; - } - - /* copy from bytes into RC2_INT's */ - ki = &(key->data[63]); - for (i = 127; i >= 0; i -= 2) - *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff; -} - -#if defined(_MSC_VER) -# pragma optimize("",on) -#endif diff --git a/Sources/COpenSSL/rc2_locl.h b/Sources/COpenSSL/rc2_locl.h deleted file mode 100644 index e72a20c0..00000000 --- a/Sources/COpenSSL/rc2_locl.h +++ /dev/null @@ -1,155 +0,0 @@ -/* crypto/rc2/rc2_locl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#undef c2l -#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<<24L) - -/* NOTE - c is not incremented as per c2l */ -#undef c2ln -#define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ - } \ - } - -#undef l2c -#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24L)&0xff)) - -/* NOTE - c is not incremented as per l2c */ -#undef l2cn -#define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -/* NOTE - c is not incremented as per n2l */ -#define n2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c)))) ; \ - case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 6: l2|=((unsigned long)(*(--(c))))<<16; \ - case 5: l2|=((unsigned long)(*(--(c))))<<24; \ - case 4: l1 =((unsigned long)(*(--(c)))) ; \ - case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 2: l1|=((unsigned long)(*(--(c))))<<16; \ - case 1: l1|=((unsigned long)(*(--(c))))<<24; \ - } \ - } - -/* NOTE - c is not incremented as per l2n */ -#define l2nn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - } \ - } - -#undef n2l -#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ - l|=((unsigned long)(*((c)++)))<<16L, \ - l|=((unsigned long)(*((c)++)))<< 8L, \ - l|=((unsigned long)(*((c)++)))) - -#undef l2n -#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -#define C_RC2(n) \ - t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \ - x0=(t<<1)|(t>>15); \ - t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \ - x1=(t<<2)|(t>>14); \ - t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \ - x2=(t<<3)|(t>>13); \ - t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \ - x3=(t<<5)|(t>>11); diff --git a/Sources/COpenSSL/rc2cfb64.c b/Sources/COpenSSL/rc2cfb64.c deleted file mode 100644 index 445099dc..00000000 --- a/Sources/COpenSSL/rc2cfb64.c +++ /dev/null @@ -1,123 +0,0 @@ -/* crypto/rc2/rc2cfb64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "rc2.h" -#include "rc2_locl.h" - -/* - * The input and output encrypted as though 64bit cfb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ - -void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, - long length, RC2_KEY *schedule, unsigned char *ivec, - int *num, int encrypt) -{ - register unsigned long v0, v1, t; - register int n = *num; - register long l = length; - unsigned long ti[2]; - unsigned char *iv, c, cc; - - iv = (unsigned char *)ivec; - if (encrypt) { - while (l--) { - if (n == 0) { - c2l(iv, v0); - ti[0] = v0; - c2l(iv, v1); - ti[1] = v1; - RC2_encrypt((unsigned long *)ti, schedule); - iv = (unsigned char *)ivec; - t = ti[0]; - l2c(t, iv); - t = ti[1]; - l2c(t, iv); - iv = (unsigned char *)ivec; - } - c = *(in++) ^ iv[n]; - *(out++) = c; - iv[n] = c; - n = (n + 1) & 0x07; - } - } else { - while (l--) { - if (n == 0) { - c2l(iv, v0); - ti[0] = v0; - c2l(iv, v1); - ti[1] = v1; - RC2_encrypt((unsigned long *)ti, schedule); - iv = (unsigned char *)ivec; - t = ti[0]; - l2c(t, iv); - t = ti[1]; - l2c(t, iv); - iv = (unsigned char *)ivec; - } - cc = *(in++); - c = iv[n]; - iv[n] = cc; - *(out++) = c ^ cc; - n = (n + 1) & 0x07; - } - } - v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; - *num = n; -} diff --git a/Sources/COpenSSL/rc2ofb64.c b/Sources/COpenSSL/rc2ofb64.c deleted file mode 100644 index 18f58f18..00000000 --- a/Sources/COpenSSL/rc2ofb64.c +++ /dev/null @@ -1,110 +0,0 @@ -/* crypto/rc2/rc2ofb64.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "rc2.h" -#include "rc2_locl.h" - -/* - * The input and output encrypted as though 64bit ofb mode is being used. - * The extra state information to record how much of the 64bit block we have - * used is contained in *num; - */ -void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, - long length, RC2_KEY *schedule, unsigned char *ivec, - int *num) -{ - register unsigned long v0, v1, t; - register int n = *num; - register long l = length; - unsigned char d[8]; - register char *dp; - unsigned long ti[2]; - unsigned char *iv; - int save = 0; - - iv = (unsigned char *)ivec; - c2l(iv, v0); - c2l(iv, v1); - ti[0] = v0; - ti[1] = v1; - dp = (char *)d; - l2c(v0, dp); - l2c(v1, dp); - while (l--) { - if (n == 0) { - RC2_encrypt((unsigned long *)ti, schedule); - dp = (char *)d; - t = ti[0]; - l2c(t, dp); - t = ti[1]; - l2c(t, dp); - save++; - } - *(out++) = *(in++) ^ d[n]; - n = (n + 1) & 0x07; - } - if (save) { - v0 = ti[0]; - v1 = ti[1]; - iv = (unsigned char *)ivec; - l2c(v0, iv); - l2c(v1, iv); - } - t = v0 = v1 = ti[0] = ti[1] = 0; - *num = n; -} diff --git a/Sources/COpenSSL/rc4.h b/Sources/COpenSSL/rc4.h deleted file mode 100644 index a9db1753..00000000 --- a/Sources/COpenSSL/rc4.h +++ /dev/null @@ -1,88 +0,0 @@ -/* crypto/rc4/rc4.h */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_RC4_H -# define HEADER_RC4_H - -# include "opensslconf.h"/* OPENSSL_NO_RC4, RC4_INT */ -# ifdef OPENSSL_NO_RC4 -# error RC4 is disabled. -# endif - -# include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct rc4_key_st { - RC4_INT x, y; - RC4_INT data[256]; -} RC4_KEY; - -const char *RC4_options(void); -void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); -void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); -void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, - unsigned char *outdata); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/rc4_.c b/Sources/COpenSSL/rc4_.c deleted file mode 100644 index 244947d1..00000000 --- a/Sources/COpenSSL/rc4_.c +++ /dev/null @@ -1,512 +0,0 @@ -/* crypto/rc4/rc4_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "rc4.h" -#include "rc4_locl.h" - -/*- - * RC4 as implemented from a posting from - * Newsgroups: sci.crypt - * From: sterndark@netcom.com (David Sterndark) - * Subject: RC4 Algorithm revealed. - * Message-ID: - * Date: Wed, 14 Sep 1994 06:35:31 GMT - */ - -void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, - unsigned char *outdata) -{ - register RC4_INT *d; - register RC4_INT x, y, tx, ty; - size_t i; - - x = key->x; - y = key->y; - d = key->data; - -#if defined(RC4_CHUNK) && !defined(PEDANTIC) - /*- - * The original reason for implementing this(*) was the fact that - * pre-21164a Alpha CPUs don't have byte load/store instructions - * and e.g. a byte store has to be done with 64-bit load, shift, - * and, or and finally 64-bit store. Peaking data and operating - * at natural word size made it possible to reduce amount of - * instructions as well as to perform early read-ahead without - * suffering from RAW (read-after-write) hazard. This resulted - * in ~40%(**) performance improvement on 21064 box with gcc. - * But it's not only Alpha users who win here:-) Thanks to the - * early-n-wide read-ahead this implementation also exhibits - * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending - * on sizeof(RC4_INT)). - * - * (*) "this" means code which recognizes the case when input - * and output pointers appear to be aligned at natural CPU - * word boundary - * (**) i.e. according to 'apps/openssl speed rc4' benchmark, - * crypto/rc4/rc4speed.c exhibits almost 70% speed-up... - * - * Cavets. - * - * - RC4_CHUNK="unsigned long long" should be a #1 choice for - * UltraSPARC. Unfortunately gcc generates very slow code - * (2.5-3 times slower than one generated by Sun's WorkShop - * C) and therefore gcc (at least 2.95 and earlier) should - * always be told that RC4_CHUNK="unsigned long". - * - * - */ - -# define RC4_STEP ( \ - x=(x+1) &0xff, \ - tx=d[x], \ - y=(tx+y)&0xff, \ - ty=d[y], \ - d[y]=tx, \ - d[x]=ty, \ - (RC4_CHUNK)d[(tx+ty)&0xff]\ - ) - - if ((((size_t)indata & (sizeof(RC4_CHUNK) - 1)) | - ((size_t)outdata & (sizeof(RC4_CHUNK) - 1))) == 0) { - RC4_CHUNK ichunk, otp; - const union { - long one; - char little; - } is_endian = { - 1 - }; - - /*- - * I reckon we can afford to implement both endian - * cases and to decide which way to take at run-time - * because the machine code appears to be very compact - * and redundant 1-2KB is perfectly tolerable (i.e. - * in case the compiler fails to eliminate it:-). By - * suggestion from Terrel Larson - * who also stands for the is_endian union:-) - * - * Special notes. - * - * - is_endian is declared automatic as doing otherwise - * (declaring static) prevents gcc from eliminating - * the redundant code; - * - compilers (those I've tried) don't seem to have - * problems eliminating either the operators guarded - * by "if (sizeof(RC4_CHUNK)==8)" or the condition - * expressions themselves so I've got 'em to replace - * corresponding #ifdefs from the previous version; - * - I chose to let the redundant switch cases when - * sizeof(RC4_CHUNK)!=8 be (were also #ifdefed - * before); - * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in - * [LB]ESHFT guards against "shift is out of range" - * warnings when sizeof(RC4_CHUNK)!=8 - * - * - */ - if (!is_endian.little) { /* BIG-ENDIAN CASE */ -# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1)) - for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) { - ichunk = *(RC4_CHUNK *) indata; - otp = RC4_STEP << BESHFT(0); - otp |= RC4_STEP << BESHFT(1); - otp |= RC4_STEP << BESHFT(2); - otp |= RC4_STEP << BESHFT(3); - if (sizeof(RC4_CHUNK) == 8) { - otp |= RC4_STEP << BESHFT(4); - otp |= RC4_STEP << BESHFT(5); - otp |= RC4_STEP << BESHFT(6); - otp |= RC4_STEP << BESHFT(7); - } - *(RC4_CHUNK *) outdata = otp ^ ichunk; - indata += sizeof(RC4_CHUNK); - outdata += sizeof(RC4_CHUNK); - } - if (len) { - RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk; - - ichunk = *(RC4_CHUNK *) indata; - ochunk = *(RC4_CHUNK *) outdata; - otp = 0; - i = BESHFT(0); - mask <<= (sizeof(RC4_CHUNK) - len) << 3; - switch (len & (sizeof(RC4_CHUNK) - 1)) { - case 7: - otp = RC4_STEP << i, i -= 8; - case 6: - otp |= RC4_STEP << i, i -= 8; - case 5: - otp |= RC4_STEP << i, i -= 8; - case 4: - otp |= RC4_STEP << i, i -= 8; - case 3: - otp |= RC4_STEP << i, i -= 8; - case 2: - otp |= RC4_STEP << i, i -= 8; - case 1: - otp |= RC4_STEP << i, i -= 8; - case 0:; /* - * it's never the case, - * but it has to be here - * for ultrix? - */ - } - ochunk &= ~mask; - ochunk |= (otp ^ ichunk) & mask; - *(RC4_CHUNK *) outdata = ochunk; - } - key->x = x; - key->y = y; - return; - } else { /* LITTLE-ENDIAN CASE */ -# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1)) - for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) { - ichunk = *(RC4_CHUNK *) indata; - otp = RC4_STEP; - otp |= RC4_STEP << 8; - otp |= RC4_STEP << 16; - otp |= RC4_STEP << 24; - if (sizeof(RC4_CHUNK) == 8) { - otp |= RC4_STEP << LESHFT(4); - otp |= RC4_STEP << LESHFT(5); - otp |= RC4_STEP << LESHFT(6); - otp |= RC4_STEP << LESHFT(7); - } - *(RC4_CHUNK *) outdata = otp ^ ichunk; - indata += sizeof(RC4_CHUNK); - outdata += sizeof(RC4_CHUNK); - } - if (len) { - RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk; - - ichunk = *(RC4_CHUNK *) indata; - ochunk = *(RC4_CHUNK *) outdata; - otp = 0; - i = 0; - mask >>= (sizeof(RC4_CHUNK) - len) << 3; - switch (len & (sizeof(RC4_CHUNK) - 1)) { - case 7: - otp = RC4_STEP, i += 8; - case 6: - otp |= RC4_STEP << i, i += 8; - case 5: - otp |= RC4_STEP << i, i += 8; - case 4: - otp |= RC4_STEP << i, i += 8; - case 3: - otp |= RC4_STEP << i, i += 8; - case 2: - otp |= RC4_STEP << i, i += 8; - case 1: - otp |= RC4_STEP << i, i += 8; - case 0:; /* - * it's never the case, - * but it has to be here - * for ultrix? - */ - } - ochunk &= ~mask; - ochunk |= (otp ^ ichunk) & mask; - *(RC4_CHUNK *) outdata = ochunk; - } - key->x = x; - key->y = y; - return; - } - } -#endif -#define LOOP(in,out) \ - x=((x+1)&0xff); \ - tx=d[x]; \ - y=(tx+y)&0xff; \ - d[x]=ty=d[y]; \ - d[y]=tx; \ - (out) = d[(tx+ty)&0xff]^ (in); - -#ifndef RC4_INDEX -# define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++)) -#else -# define RC4_LOOP(a,b,i) LOOP(a[i],b[i]) -#endif - - i = len >> 3; - if (i) { - for (;;) { - RC4_LOOP(indata, outdata, 0); - RC4_LOOP(indata, outdata, 1); - RC4_LOOP(indata, outdata, 2); - RC4_LOOP(indata, outdata, 3); - RC4_LOOP(indata, outdata, 4); - RC4_LOOP(indata, outdata, 5); - RC4_LOOP(indata, outdata, 6); - RC4_LOOP(indata, outdata, 7); -#ifdef RC4_INDEX - indata += 8; - outdata += 8; -#endif - if (--i == 0) - break; - } - } - i = len & 0x07; - if (i) { - for (;;) { - RC4_LOOP(indata, outdata, 0); - if (--i == 0) - break; - RC4_LOOP(indata, outdata, 1); - if (--i == 0) - break; - RC4_LOOP(indata, outdata, 2); - if (--i == 0) - break; - RC4_LOOP(indata, outdata, 3); - if (--i == 0) - break; - RC4_LOOP(indata, outdata, 4); - if (--i == 0) - break; - RC4_LOOP(indata, outdata, 5); - if (--i == 0) - break; - RC4_LOOP(indata, outdata, 6); - if (--i == 0) - break; - } - } - key->x = x; - key->y = y; -} -/* crypto/rc4/rc4_skey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "rc4.h" -// #include "rc4_locl.h" -#include "opensslv.h" - -const char RC4_version[] = "RC4" OPENSSL_VERSION_PTEXT; - -const char *RC4_options(void) -{ -#ifdef RC4_INDEX - if (sizeof(RC4_INT) == 1) - return ("rc4(idx,char)"); - else - return ("rc4(idx,int)"); -#else - if (sizeof(RC4_INT) == 1) - return ("rc4(ptr,char)"); - else - return ("rc4(ptr,int)"); -#endif -} - -/*- - * RC4 as implemented from a posting from - * Newsgroups: sci.crypt - * From: sterndark@netcom.com (David Sterndark) - * Subject: RC4 Algorithm revealed. - * Message-ID: - * Date: Wed, 14 Sep 1994 06:35:31 GMT - */ - -void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) -{ - register RC4_INT tmp; - register int id1, id2; - register RC4_INT *d; - unsigned int i; - - d = &(key->data[0]); - key->x = 0; - key->y = 0; - id1 = id2 = 0; - -#define SK_LOOP(d,n) { \ - tmp=d[(n)]; \ - id2 = (data[id1] + tmp + id2) & 0xff; \ - if (++id1 == len) id1=0; \ - d[(n)]=d[id2]; \ - d[id2]=tmp; } - - for (i = 0; i < 256; i++) - d[i] = i; - for (i = 0; i < 256; i += 4) { - SK_LOOP(d, i + 0); - SK_LOOP(d, i + 1); - SK_LOOP(d, i + 2); - SK_LOOP(d, i + 3); - } -} -/* crypto/rc4/rc4_utl.c */ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "opensslv.h" -#include "crypto.h" -// #include "rc4.h" - -void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) -{ -#ifdef OPENSSL_FIPS - fips_cipher_abort(RC4); -#endif - private_RC4_set_key(key, len, data); -} diff --git a/Sources/COpenSSL/rc4_locl.h b/Sources/COpenSSL/rc4_locl.h deleted file mode 100644 index 5737a64e..00000000 --- a/Sources/COpenSSL/rc4_locl.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef HEADER_RC4_LOCL_H -# define HEADER_RC4_LOCL_H -# include "opensslconf.h" -# include "cryptlib.h" -#endif diff --git a/Sources/COpenSSL/read2pwd.c b/Sources/COpenSSL/read2pwd.c deleted file mode 100644 index a9521856..00000000 --- a/Sources/COpenSSL/read2pwd.c +++ /dev/null @@ -1,140 +0,0 @@ -/* crypto/des/read2pwd.c */ -/* ==================================================================== - * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "des.h" -#include "ui.h" -#include "crypto.h" - -int DES_read_password(DES_cblock *key, const char *prompt, int verify) -{ - int ok; - char buf[BUFSIZ], buff[BUFSIZ]; - - if ((ok = UI_UTIL_read_pw(buf, buff, BUFSIZ, prompt, verify)) == 0) - DES_string_to_key(buf, key); - OPENSSL_cleanse(buf, BUFSIZ); - OPENSSL_cleanse(buff, BUFSIZ); - return (ok); -} - -int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, - const char *prompt, int verify) -{ - int ok; - char buf[BUFSIZ], buff[BUFSIZ]; - - if ((ok = UI_UTIL_read_pw(buf, buff, BUFSIZ, prompt, verify)) == 0) - DES_string_to_2keys(buf, key1, key2); - OPENSSL_cleanse(buf, BUFSIZ); - OPENSSL_cleanse(buff, BUFSIZ); - return (ok); -} diff --git a/Sources/COpenSSL/ripemd.h b/Sources/COpenSSL/ripemd.h deleted file mode 100644 index 5c5100d7..00000000 --- a/Sources/COpenSSL/ripemd.h +++ /dev/null @@ -1,105 +0,0 @@ -/* crypto/ripemd/ripemd.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_RIPEMD_H -# define HEADER_RIPEMD_H - -# include "e_os2.h" -# include - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef OPENSSL_NO_RIPEMD -# error RIPEMD is disabled. -# endif - -# if defined(__LP32__) -# define RIPEMD160_LONG unsigned long -# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) -# define RIPEMD160_LONG unsigned long -# define RIPEMD160_LONG_LOG2 3 -# else -# define RIPEMD160_LONG unsigned int -# endif - -# define RIPEMD160_CBLOCK 64 -# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) -# define RIPEMD160_DIGEST_LENGTH 20 - -typedef struct RIPEMD160state_st { - RIPEMD160_LONG A, B, C, D, E; - RIPEMD160_LONG Nl, Nh; - RIPEMD160_LONG data[RIPEMD160_LBLOCK]; - unsigned int num; -} RIPEMD160_CTX; - -# ifdef OPENSSL_FIPS -int private_RIPEMD160_Init(RIPEMD160_CTX *c); -# endif -int RIPEMD160_Init(RIPEMD160_CTX *c); -int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); -int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); -unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md); -void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/rmd_.c b/Sources/COpenSSL/rmd_.c deleted file mode 100644 index 69c8490c..00000000 --- a/Sources/COpenSSL/rmd_.c +++ /dev/null @@ -1,411 +0,0 @@ -/* crypto/ripemd/rmd_dgst.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "rmd_locl.h" -#include "opensslv.h" -// #include "crypto.h" - -const char RMD160_version[] = "RIPE-MD160" OPENSSL_VERSION_PTEXT; - -#ifdef RMD160_ASM -void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p, size_t num); -# define ripemd160_block ripemd160_block_x86 -#else -void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p, size_t num); -#endif - -fips_md_init(RIPEMD160) -{ - memset(c, 0, sizeof(*c)); - c->A = RIPEMD160_A; - c->B = RIPEMD160_B; - c->C = RIPEMD160_C; - c->D = RIPEMD160_D; - c->E = RIPEMD160_E; - return 1; -} - -#ifndef ripemd160_block_data_order -# ifdef X -# undef X -# endif -void ripemd160_block_data_order(RIPEMD160_CTX *ctx, const void *p, size_t num) -{ - const unsigned char *data = p; - register unsigned MD32_REG_T A, B, C, D, E; - unsigned MD32_REG_T a, b, c, d, e, l; -# ifndef MD32_XARRAY - /* See comment in crypto/sha/sha_locl.h for details. */ - unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; -# define X(i) XX##i -# else - RIPEMD160_LONG XX[16]; -# define X(i) XX[i] -# endif - - for (; num--;) { - - A = ctx->A; - B = ctx->B; - C = ctx->C; - D = ctx->D; - E = ctx->E; - - (void)HOST_c2l(data, l); - X(0) = l; - (void)HOST_c2l(data, l); - X(1) = l; - RIP1(A, B, C, D, E, WL00, SL00); - (void)HOST_c2l(data, l); - X(2) = l; - RIP1(E, A, B, C, D, WL01, SL01); - (void)HOST_c2l(data, l); - X(3) = l; - RIP1(D, E, A, B, C, WL02, SL02); - (void)HOST_c2l(data, l); - X(4) = l; - RIP1(C, D, E, A, B, WL03, SL03); - (void)HOST_c2l(data, l); - X(5) = l; - RIP1(B, C, D, E, A, WL04, SL04); - (void)HOST_c2l(data, l); - X(6) = l; - RIP1(A, B, C, D, E, WL05, SL05); - (void)HOST_c2l(data, l); - X(7) = l; - RIP1(E, A, B, C, D, WL06, SL06); - (void)HOST_c2l(data, l); - X(8) = l; - RIP1(D, E, A, B, C, WL07, SL07); - (void)HOST_c2l(data, l); - X(9) = l; - RIP1(C, D, E, A, B, WL08, SL08); - (void)HOST_c2l(data, l); - X(10) = l; - RIP1(B, C, D, E, A, WL09, SL09); - (void)HOST_c2l(data, l); - X(11) = l; - RIP1(A, B, C, D, E, WL10, SL10); - (void)HOST_c2l(data, l); - X(12) = l; - RIP1(E, A, B, C, D, WL11, SL11); - (void)HOST_c2l(data, l); - X(13) = l; - RIP1(D, E, A, B, C, WL12, SL12); - (void)HOST_c2l(data, l); - X(14) = l; - RIP1(C, D, E, A, B, WL13, SL13); - (void)HOST_c2l(data, l); - X(15) = l; - RIP1(B, C, D, E, A, WL14, SL14); - RIP1(A, B, C, D, E, WL15, SL15); - - RIP2(E, A, B, C, D, WL16, SL16, KL1); - RIP2(D, E, A, B, C, WL17, SL17, KL1); - RIP2(C, D, E, A, B, WL18, SL18, KL1); - RIP2(B, C, D, E, A, WL19, SL19, KL1); - RIP2(A, B, C, D, E, WL20, SL20, KL1); - RIP2(E, A, B, C, D, WL21, SL21, KL1); - RIP2(D, E, A, B, C, WL22, SL22, KL1); - RIP2(C, D, E, A, B, WL23, SL23, KL1); - RIP2(B, C, D, E, A, WL24, SL24, KL1); - RIP2(A, B, C, D, E, WL25, SL25, KL1); - RIP2(E, A, B, C, D, WL26, SL26, KL1); - RIP2(D, E, A, B, C, WL27, SL27, KL1); - RIP2(C, D, E, A, B, WL28, SL28, KL1); - RIP2(B, C, D, E, A, WL29, SL29, KL1); - RIP2(A, B, C, D, E, WL30, SL30, KL1); - RIP2(E, A, B, C, D, WL31, SL31, KL1); - - RIP3(D, E, A, B, C, WL32, SL32, KL2); - RIP3(C, D, E, A, B, WL33, SL33, KL2); - RIP3(B, C, D, E, A, WL34, SL34, KL2); - RIP3(A, B, C, D, E, WL35, SL35, KL2); - RIP3(E, A, B, C, D, WL36, SL36, KL2); - RIP3(D, E, A, B, C, WL37, SL37, KL2); - RIP3(C, D, E, A, B, WL38, SL38, KL2); - RIP3(B, C, D, E, A, WL39, SL39, KL2); - RIP3(A, B, C, D, E, WL40, SL40, KL2); - RIP3(E, A, B, C, D, WL41, SL41, KL2); - RIP3(D, E, A, B, C, WL42, SL42, KL2); - RIP3(C, D, E, A, B, WL43, SL43, KL2); - RIP3(B, C, D, E, A, WL44, SL44, KL2); - RIP3(A, B, C, D, E, WL45, SL45, KL2); - RIP3(E, A, B, C, D, WL46, SL46, KL2); - RIP3(D, E, A, B, C, WL47, SL47, KL2); - - RIP4(C, D, E, A, B, WL48, SL48, KL3); - RIP4(B, C, D, E, A, WL49, SL49, KL3); - RIP4(A, B, C, D, E, WL50, SL50, KL3); - RIP4(E, A, B, C, D, WL51, SL51, KL3); - RIP4(D, E, A, B, C, WL52, SL52, KL3); - RIP4(C, D, E, A, B, WL53, SL53, KL3); - RIP4(B, C, D, E, A, WL54, SL54, KL3); - RIP4(A, B, C, D, E, WL55, SL55, KL3); - RIP4(E, A, B, C, D, WL56, SL56, KL3); - RIP4(D, E, A, B, C, WL57, SL57, KL3); - RIP4(C, D, E, A, B, WL58, SL58, KL3); - RIP4(B, C, D, E, A, WL59, SL59, KL3); - RIP4(A, B, C, D, E, WL60, SL60, KL3); - RIP4(E, A, B, C, D, WL61, SL61, KL3); - RIP4(D, E, A, B, C, WL62, SL62, KL3); - RIP4(C, D, E, A, B, WL63, SL63, KL3); - - RIP5(B, C, D, E, A, WL64, SL64, KL4); - RIP5(A, B, C, D, E, WL65, SL65, KL4); - RIP5(E, A, B, C, D, WL66, SL66, KL4); - RIP5(D, E, A, B, C, WL67, SL67, KL4); - RIP5(C, D, E, A, B, WL68, SL68, KL4); - RIP5(B, C, D, E, A, WL69, SL69, KL4); - RIP5(A, B, C, D, E, WL70, SL70, KL4); - RIP5(E, A, B, C, D, WL71, SL71, KL4); - RIP5(D, E, A, B, C, WL72, SL72, KL4); - RIP5(C, D, E, A, B, WL73, SL73, KL4); - RIP5(B, C, D, E, A, WL74, SL74, KL4); - RIP5(A, B, C, D, E, WL75, SL75, KL4); - RIP5(E, A, B, C, D, WL76, SL76, KL4); - RIP5(D, E, A, B, C, WL77, SL77, KL4); - RIP5(C, D, E, A, B, WL78, SL78, KL4); - RIP5(B, C, D, E, A, WL79, SL79, KL4); - - a = A; - b = B; - c = C; - d = D; - e = E; - /* Do other half */ - A = ctx->A; - B = ctx->B; - C = ctx->C; - D = ctx->D; - E = ctx->E; - - RIP5(A, B, C, D, E, WR00, SR00, KR0); - RIP5(E, A, B, C, D, WR01, SR01, KR0); - RIP5(D, E, A, B, C, WR02, SR02, KR0); - RIP5(C, D, E, A, B, WR03, SR03, KR0); - RIP5(B, C, D, E, A, WR04, SR04, KR0); - RIP5(A, B, C, D, E, WR05, SR05, KR0); - RIP5(E, A, B, C, D, WR06, SR06, KR0); - RIP5(D, E, A, B, C, WR07, SR07, KR0); - RIP5(C, D, E, A, B, WR08, SR08, KR0); - RIP5(B, C, D, E, A, WR09, SR09, KR0); - RIP5(A, B, C, D, E, WR10, SR10, KR0); - RIP5(E, A, B, C, D, WR11, SR11, KR0); - RIP5(D, E, A, B, C, WR12, SR12, KR0); - RIP5(C, D, E, A, B, WR13, SR13, KR0); - RIP5(B, C, D, E, A, WR14, SR14, KR0); - RIP5(A, B, C, D, E, WR15, SR15, KR0); - - RIP4(E, A, B, C, D, WR16, SR16, KR1); - RIP4(D, E, A, B, C, WR17, SR17, KR1); - RIP4(C, D, E, A, B, WR18, SR18, KR1); - RIP4(B, C, D, E, A, WR19, SR19, KR1); - RIP4(A, B, C, D, E, WR20, SR20, KR1); - RIP4(E, A, B, C, D, WR21, SR21, KR1); - RIP4(D, E, A, B, C, WR22, SR22, KR1); - RIP4(C, D, E, A, B, WR23, SR23, KR1); - RIP4(B, C, D, E, A, WR24, SR24, KR1); - RIP4(A, B, C, D, E, WR25, SR25, KR1); - RIP4(E, A, B, C, D, WR26, SR26, KR1); - RIP4(D, E, A, B, C, WR27, SR27, KR1); - RIP4(C, D, E, A, B, WR28, SR28, KR1); - RIP4(B, C, D, E, A, WR29, SR29, KR1); - RIP4(A, B, C, D, E, WR30, SR30, KR1); - RIP4(E, A, B, C, D, WR31, SR31, KR1); - - RIP3(D, E, A, B, C, WR32, SR32, KR2); - RIP3(C, D, E, A, B, WR33, SR33, KR2); - RIP3(B, C, D, E, A, WR34, SR34, KR2); - RIP3(A, B, C, D, E, WR35, SR35, KR2); - RIP3(E, A, B, C, D, WR36, SR36, KR2); - RIP3(D, E, A, B, C, WR37, SR37, KR2); - RIP3(C, D, E, A, B, WR38, SR38, KR2); - RIP3(B, C, D, E, A, WR39, SR39, KR2); - RIP3(A, B, C, D, E, WR40, SR40, KR2); - RIP3(E, A, B, C, D, WR41, SR41, KR2); - RIP3(D, E, A, B, C, WR42, SR42, KR2); - RIP3(C, D, E, A, B, WR43, SR43, KR2); - RIP3(B, C, D, E, A, WR44, SR44, KR2); - RIP3(A, B, C, D, E, WR45, SR45, KR2); - RIP3(E, A, B, C, D, WR46, SR46, KR2); - RIP3(D, E, A, B, C, WR47, SR47, KR2); - - RIP2(C, D, E, A, B, WR48, SR48, KR3); - RIP2(B, C, D, E, A, WR49, SR49, KR3); - RIP2(A, B, C, D, E, WR50, SR50, KR3); - RIP2(E, A, B, C, D, WR51, SR51, KR3); - RIP2(D, E, A, B, C, WR52, SR52, KR3); - RIP2(C, D, E, A, B, WR53, SR53, KR3); - RIP2(B, C, D, E, A, WR54, SR54, KR3); - RIP2(A, B, C, D, E, WR55, SR55, KR3); - RIP2(E, A, B, C, D, WR56, SR56, KR3); - RIP2(D, E, A, B, C, WR57, SR57, KR3); - RIP2(C, D, E, A, B, WR58, SR58, KR3); - RIP2(B, C, D, E, A, WR59, SR59, KR3); - RIP2(A, B, C, D, E, WR60, SR60, KR3); - RIP2(E, A, B, C, D, WR61, SR61, KR3); - RIP2(D, E, A, B, C, WR62, SR62, KR3); - RIP2(C, D, E, A, B, WR63, SR63, KR3); - - RIP1(B, C, D, E, A, WR64, SR64); - RIP1(A, B, C, D, E, WR65, SR65); - RIP1(E, A, B, C, D, WR66, SR66); - RIP1(D, E, A, B, C, WR67, SR67); - RIP1(C, D, E, A, B, WR68, SR68); - RIP1(B, C, D, E, A, WR69, SR69); - RIP1(A, B, C, D, E, WR70, SR70); - RIP1(E, A, B, C, D, WR71, SR71); - RIP1(D, E, A, B, C, WR72, SR72); - RIP1(C, D, E, A, B, WR73, SR73); - RIP1(B, C, D, E, A, WR74, SR74); - RIP1(A, B, C, D, E, WR75, SR75); - RIP1(E, A, B, C, D, WR76, SR76); - RIP1(D, E, A, B, C, WR77, SR77); - RIP1(C, D, E, A, B, WR78, SR78); - RIP1(B, C, D, E, A, WR79, SR79); - - D = ctx->B + c + D; - ctx->B = ctx->C + d + E; - ctx->C = ctx->D + e + A; - ctx->D = ctx->E + a + B; - ctx->E = ctx->A + b + C; - ctx->A = D; - - } -} -#endif -/* crypto/ripemd/rmd_one.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "ripemd.h" -// #include "crypto.h" - -unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md) -{ - RIPEMD160_CTX c; - static unsigned char m[RIPEMD160_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - if (!RIPEMD160_Init(&c)) - return NULL; - RIPEMD160_Update(&c, d, n); - RIPEMD160_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ - return (md); -} diff --git a/Sources/COpenSSL/rmd_locl.h b/Sources/COpenSSL/rmd_locl.h deleted file mode 100644 index 62d5ecdd..00000000 --- a/Sources/COpenSSL/rmd_locl.h +++ /dev/null @@ -1,149 +0,0 @@ -/* crypto/ripemd/rmd_locl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "opensslconf.h" -#include "ripemd.h" - -#ifndef RIPEMD160_LONG_LOG2 -# define RIPEMD160_LONG_LOG2 2 /* default to 32 bits */ -#endif - -/* - * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c - * FOR EXPLANATIONS ON FOLLOWING "CODE." - * - */ -#ifdef RMD160_ASM -# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) -# define ripemd160_block_data_order ripemd160_block_asm_data_order -# endif -#endif - -void ripemd160_block_data_order(RIPEMD160_CTX *c, const void *p, size_t num); - -#define DATA_ORDER_IS_LITTLE_ENDIAN - -#define HASH_LONG RIPEMD160_LONG -#define HASH_CTX RIPEMD160_CTX -#define HASH_CBLOCK RIPEMD160_CBLOCK -#define HASH_UPDATE RIPEMD160_Update -#define HASH_TRANSFORM RIPEMD160_Transform -#define HASH_FINAL RIPEMD160_Final -#define HASH_MAKE_STRING(c,s) do { \ - unsigned long ll; \ - ll=(c)->A; (void)HOST_l2c(ll,(s)); \ - ll=(c)->B; (void)HOST_l2c(ll,(s)); \ - ll=(c)->C; (void)HOST_l2c(ll,(s)); \ - ll=(c)->D; (void)HOST_l2c(ll,(s)); \ - ll=(c)->E; (void)HOST_l2c(ll,(s)); \ - } while (0) -#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order - -#include "md32_common.h" - -#if 0 -# define F1(x,y,z) ((x)^(y)^(z)) -# define F2(x,y,z) (((x)&(y))|((~x)&z)) -# define F3(x,y,z) (((x)|(~y))^(z)) -# define F4(x,y,z) (((x)&(z))|((y)&(~(z)))) -# define F5(x,y,z) ((x)^((y)|(~(z)))) -#else -/* - * Transformed F2 and F4 are courtesy of Wei Dai - */ -# define F1(x,y,z) ((x) ^ (y) ^ (z)) -# define F2(x,y,z) ((((y) ^ (z)) & (x)) ^ (z)) -# define F3(x,y,z) (((~(y)) | (x)) ^ (z)) -# define F4(x,y,z) ((((x) ^ (y)) & (z)) ^ (y)) -# define F5(x,y,z) (((~(z)) | (y)) ^ (x)) -#endif - -#define RIPEMD160_A 0x67452301L -#define RIPEMD160_B 0xEFCDAB89L -#define RIPEMD160_C 0x98BADCFEL -#define RIPEMD160_D 0x10325476L -#define RIPEMD160_E 0xC3D2E1F0L - -#include "rmdconst.h" - -#define RIP1(a,b,c,d,e,w,s) { \ - a+=F1(b,c,d)+X(w); \ - a=ROTATE(a,s)+e; \ - c=ROTATE(c,10); } - -#define RIP2(a,b,c,d,e,w,s,K) { \ - a+=F2(b,c,d)+X(w)+K; \ - a=ROTATE(a,s)+e; \ - c=ROTATE(c,10); } - -#define RIP3(a,b,c,d,e,w,s,K) { \ - a+=F3(b,c,d)+X(w)+K; \ - a=ROTATE(a,s)+e; \ - c=ROTATE(c,10); } - -#define RIP4(a,b,c,d,e,w,s,K) { \ - a+=F4(b,c,d)+X(w)+K; \ - a=ROTATE(a,s)+e; \ - c=ROTATE(c,10); } - -#define RIP5(a,b,c,d,e,w,s,K) { \ - a+=F5(b,c,d)+X(w)+K; \ - a=ROTATE(a,s)+e; \ - c=ROTATE(c,10); } diff --git a/Sources/COpenSSL/rmdconst.h b/Sources/COpenSSL/rmdconst.h deleted file mode 100644 index 8fe33de1..00000000 --- a/Sources/COpenSSL/rmdconst.h +++ /dev/null @@ -1,398 +0,0 @@ -/* crypto/ripemd/rmdconst.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -#define KL0 0x00000000L -#define KL1 0x5A827999L -#define KL2 0x6ED9EBA1L -#define KL3 0x8F1BBCDCL -#define KL4 0xA953FD4EL - -#define KR0 0x50A28BE6L -#define KR1 0x5C4DD124L -#define KR2 0x6D703EF3L -#define KR3 0x7A6D76E9L -#define KR4 0x00000000L - -#define WL00 0 -#define SL00 11 -#define WL01 1 -#define SL01 14 -#define WL02 2 -#define SL02 15 -#define WL03 3 -#define SL03 12 -#define WL04 4 -#define SL04 5 -#define WL05 5 -#define SL05 8 -#define WL06 6 -#define SL06 7 -#define WL07 7 -#define SL07 9 -#define WL08 8 -#define SL08 11 -#define WL09 9 -#define SL09 13 -#define WL10 10 -#define SL10 14 -#define WL11 11 -#define SL11 15 -#define WL12 12 -#define SL12 6 -#define WL13 13 -#define SL13 7 -#define WL14 14 -#define SL14 9 -#define WL15 15 -#define SL15 8 - -#define WL16 7 -#define SL16 7 -#define WL17 4 -#define SL17 6 -#define WL18 13 -#define SL18 8 -#define WL19 1 -#define SL19 13 -#define WL20 10 -#define SL20 11 -#define WL21 6 -#define SL21 9 -#define WL22 15 -#define SL22 7 -#define WL23 3 -#define SL23 15 -#define WL24 12 -#define SL24 7 -#define WL25 0 -#define SL25 12 -#define WL26 9 -#define SL26 15 -#define WL27 5 -#define SL27 9 -#define WL28 2 -#define SL28 11 -#define WL29 14 -#define SL29 7 -#define WL30 11 -#define SL30 13 -#define WL31 8 -#define SL31 12 - -#define WL32 3 -#define SL32 11 -#define WL33 10 -#define SL33 13 -#define WL34 14 -#define SL34 6 -#define WL35 4 -#define SL35 7 -#define WL36 9 -#define SL36 14 -#define WL37 15 -#define SL37 9 -#define WL38 8 -#define SL38 13 -#define WL39 1 -#define SL39 15 -#define WL40 2 -#define SL40 14 -#define WL41 7 -#define SL41 8 -#define WL42 0 -#define SL42 13 -#define WL43 6 -#define SL43 6 -#define WL44 13 -#define SL44 5 -#define WL45 11 -#define SL45 12 -#define WL46 5 -#define SL46 7 -#define WL47 12 -#define SL47 5 - -#define WL48 1 -#define SL48 11 -#define WL49 9 -#define SL49 12 -#define WL50 11 -#define SL50 14 -#define WL51 10 -#define SL51 15 -#define WL52 0 -#define SL52 14 -#define WL53 8 -#define SL53 15 -#define WL54 12 -#define SL54 9 -#define WL55 4 -#define SL55 8 -#define WL56 13 -#define SL56 9 -#define WL57 3 -#define SL57 14 -#define WL58 7 -#define SL58 5 -#define WL59 15 -#define SL59 6 -#define WL60 14 -#define SL60 8 -#define WL61 5 -#define SL61 6 -#define WL62 6 -#define SL62 5 -#define WL63 2 -#define SL63 12 - -#define WL64 4 -#define SL64 9 -#define WL65 0 -#define SL65 15 -#define WL66 5 -#define SL66 5 -#define WL67 9 -#define SL67 11 -#define WL68 7 -#define SL68 6 -#define WL69 12 -#define SL69 8 -#define WL70 2 -#define SL70 13 -#define WL71 10 -#define SL71 12 -#define WL72 14 -#define SL72 5 -#define WL73 1 -#define SL73 12 -#define WL74 3 -#define SL74 13 -#define WL75 8 -#define SL75 14 -#define WL76 11 -#define SL76 11 -#define WL77 6 -#define SL77 8 -#define WL78 15 -#define SL78 5 -#define WL79 13 -#define SL79 6 - -#define WR00 5 -#define SR00 8 -#define WR01 14 -#define SR01 9 -#define WR02 7 -#define SR02 9 -#define WR03 0 -#define SR03 11 -#define WR04 9 -#define SR04 13 -#define WR05 2 -#define SR05 15 -#define WR06 11 -#define SR06 15 -#define WR07 4 -#define SR07 5 -#define WR08 13 -#define SR08 7 -#define WR09 6 -#define SR09 7 -#define WR10 15 -#define SR10 8 -#define WR11 8 -#define SR11 11 -#define WR12 1 -#define SR12 14 -#define WR13 10 -#define SR13 14 -#define WR14 3 -#define SR14 12 -#define WR15 12 -#define SR15 6 - -#define WR16 6 -#define SR16 9 -#define WR17 11 -#define SR17 13 -#define WR18 3 -#define SR18 15 -#define WR19 7 -#define SR19 7 -#define WR20 0 -#define SR20 12 -#define WR21 13 -#define SR21 8 -#define WR22 5 -#define SR22 9 -#define WR23 10 -#define SR23 11 -#define WR24 14 -#define SR24 7 -#define WR25 15 -#define SR25 7 -#define WR26 8 -#define SR26 12 -#define WR27 12 -#define SR27 7 -#define WR28 4 -#define SR28 6 -#define WR29 9 -#define SR29 15 -#define WR30 1 -#define SR30 13 -#define WR31 2 -#define SR31 11 - -#define WR32 15 -#define SR32 9 -#define WR33 5 -#define SR33 7 -#define WR34 1 -#define SR34 15 -#define WR35 3 -#define SR35 11 -#define WR36 7 -#define SR36 8 -#define WR37 14 -#define SR37 6 -#define WR38 6 -#define SR38 6 -#define WR39 9 -#define SR39 14 -#define WR40 11 -#define SR40 12 -#define WR41 8 -#define SR41 13 -#define WR42 12 -#define SR42 5 -#define WR43 2 -#define SR43 14 -#define WR44 10 -#define SR44 13 -#define WR45 0 -#define SR45 13 -#define WR46 4 -#define SR46 7 -#define WR47 13 -#define SR47 5 - -#define WR48 8 -#define SR48 15 -#define WR49 6 -#define SR49 5 -#define WR50 4 -#define SR50 8 -#define WR51 1 -#define SR51 11 -#define WR52 3 -#define SR52 14 -#define WR53 11 -#define SR53 14 -#define WR54 15 -#define SR54 6 -#define WR55 0 -#define SR55 14 -#define WR56 5 -#define SR56 6 -#define WR57 12 -#define SR57 9 -#define WR58 2 -#define SR58 12 -#define WR59 13 -#define SR59 9 -#define WR60 9 -#define SR60 12 -#define WR61 7 -#define SR61 5 -#define WR62 10 -#define SR62 15 -#define WR63 14 -#define SR63 8 - -#define WR64 12 -#define SR64 8 -#define WR65 15 -#define SR65 5 -#define WR66 10 -#define SR66 12 -#define WR67 4 -#define SR67 9 -#define WR68 1 -#define SR68 12 -#define WR69 5 -#define SR69 5 -#define WR70 8 -#define SR70 14 -#define WR71 7 -#define SR71 6 -#define WR72 6 -#define SR72 8 -#define WR73 2 -#define SR73 13 -#define WR74 13 -#define SR74 6 -#define WR75 14 -#define SR75 5 -#define WR76 0 -#define SR76 15 -#define WR77 3 -#define SR77 13 -#define WR78 9 -#define SR78 11 -#define WR79 11 -#define SR79 11 diff --git a/Sources/COpenSSL/rpc_des.h b/Sources/COpenSSL/rpc_des.h deleted file mode 100644 index 4db9062d..00000000 --- a/Sources/COpenSSL/rpc_des.h +++ /dev/null @@ -1,130 +0,0 @@ -/* crypto/des/rpc_des.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */ -/*- - * Sun RPC is a product of Sun Microsystems, Inc. and is provided for - * unrestricted use provided that this legend is included on all tape - * media and as a part of the software program in whole or part. Users - * may copy or modify Sun RPC without charge, but are not authorized - * to license or distribute it to anyone else except as part of a product or - * program developed by the user. - * - * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE - * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun RPC is provided with no support and without any obligation on the - * part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -/* - * Generic DES driver interface - * Keep this file hardware independent! - * Copyright (c) 1986 by Sun Microsystems, Inc. - */ - -#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */ -#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */ - -#ifdef HEADER_DES_H -# undef ENCRYPT -# undef DECRYPT -#endif - -enum desdir { ENCRYPT, DECRYPT }; -enum desmode { CBC, ECB }; - -/* - * parameters to ioctl call - */ -struct desparams { - unsigned char des_key[8]; /* key (with low bit parity) */ - enum desdir des_dir; /* direction */ - enum desmode des_mode; /* mode */ - unsigned char des_ivec[8]; /* input vector */ - unsigned des_len; /* number of bytes to crypt */ - union { - unsigned char UDES_data[DES_QUICKLEN]; - unsigned char *UDES_buf; - } UDES; -#define des_data UDES.UDES_data /* direct data here if quick */ -#define des_buf UDES.UDES_buf /* otherwise, pointer to data */ -}; - -/* - * Encrypt an arbitrary sized buffer - */ -#define DESIOCBLOCK _IOWR('d', 6, struct desparams) - -/* - * Encrypt of small amount of data, quickly - */ -#define DESIOCQUICK _IOWR('d', 7, struct desparams) diff --git a/Sources/COpenSSL/rpc_enc.c b/Sources/COpenSSL/rpc_enc.c deleted file mode 100644 index f5a84c5b..00000000 --- a/Sources/COpenSSL/rpc_enc.c +++ /dev/null @@ -1,100 +0,0 @@ -/* crypto/des/rpc_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "rpc_des.h" -#include "des_locl.h" -#include "des_ver.h" - -int _des_crypt(char *buf, int len, struct desparams *desp); -int _des_crypt(char *buf, int len, struct desparams *desp) -{ - DES_key_schedule ks; - int enc; - - DES_set_key_unchecked(&desp->des_key, &ks); - enc = (desp->des_dir == ENCRYPT) ? DES_ENCRYPT : DES_DECRYPT; - - if (desp->des_mode == CBC) - DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf, - (DES_cblock *)desp->UDES.UDES_buf, &ks, enc); - else { - DES_ncbc_encrypt(desp->UDES.UDES_buf, desp->UDES.UDES_buf, - len, &ks, &desp->des_ivec, enc); -#ifdef undef - /* - * len will always be %8 if called from common_crypt in secure_rpc. - * Libdes's cbc encrypt does not copy back the iv, so we have to do - * it here. - */ - /* It does now :-) eay 20/09/95 */ - - a = (char *)&(desp->UDES.UDES_buf[len - 8]); - b = (char *)&(desp->des_ivec[0]); - - *(a++) = *(b++); - *(a++) = *(b++); - *(a++) = *(b++); - *(a++) = *(b++); - *(a++) = *(b++); - *(a++) = *(b++); - *(a++) = *(b++); - *(a++) = *(b++); -#endif - } - return (1); -} diff --git a/Sources/COpenSSL/rsa.h b/Sources/COpenSSL/rsa.h deleted file mode 100644 index d6ea13cc..00000000 --- a/Sources/COpenSSL/rsa.h +++ /dev/null @@ -1,664 +0,0 @@ -/* crypto/rsa/rsa.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_RSA_H -# define HEADER_RSA_H - -# include "asn1.h" - -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# include "crypto.h" -# include "ossl_typ.h" -# ifndef OPENSSL_NO_DEPRECATED -# include "bn.h" -# endif - -# ifdef OPENSSL_NO_RSA -# error RSA is disabled. -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* Declared already in ossl_typ.h */ -/* typedef struct rsa_st RSA; */ -/* typedef struct rsa_meth_st RSA_METHOD; */ - -struct rsa_meth_st { - const char *name; - int (*rsa_pub_enc) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); - int (*rsa_pub_dec) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); - int (*rsa_priv_enc) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); - int (*rsa_priv_dec) (int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); - /* Can be null */ - int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); - /* Can be null */ - int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, - const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); - /* called at new */ - int (*init) (RSA *rsa); - /* called at free */ - int (*finish) (RSA *rsa); - /* RSA_METHOD_FLAG_* things */ - int flags; - /* may be needed! */ - char *app_data; - /* - * New sign and verify functions: some libraries don't allow arbitrary - * data to be signed/verified: this allows them to be used. Note: for - * this to work the RSA_public_decrypt() and RSA_private_encrypt() should - * *NOT* be used RSA_sign(), RSA_verify() should be used instead. Note: - * for backwards compatibility this functionality is only enabled if the - * RSA_FLAG_SIGN_VER option is set in 'flags'. - */ - int (*rsa_sign) (int type, - const unsigned char *m, unsigned int m_length, - unsigned char *sigret, unsigned int *siglen, - const RSA *rsa); - int (*rsa_verify) (int dtype, const unsigned char *m, - unsigned int m_length, const unsigned char *sigbuf, - unsigned int siglen, const RSA *rsa); - /* - * If this callback is NULL, the builtin software RSA key-gen will be - * used. This is for behavioural compatibility whilst the code gets - * rewired, but one day it would be nice to assume there are no such - * things as "builtin software" implementations. - */ - int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); -}; - -struct rsa_st { - /* - * The first parameter is used to pickup errors where this is passed - * instead of aEVP_PKEY, it is set to 0 - */ - int pad; - long version; - const RSA_METHOD *meth; - /* functional reference if 'meth' is ENGINE-provided */ - ENGINE *engine; - BIGNUM *n; - BIGNUM *e; - BIGNUM *d; - BIGNUM *p; - BIGNUM *q; - BIGNUM *dmp1; - BIGNUM *dmq1; - BIGNUM *iqmp; - /* be careful using this if the RSA structure is shared */ - CRYPTO_EX_DATA ex_data; - int references; - int flags; - /* Used to cache montgomery values */ - BN_MONT_CTX *_method_mod_n; - BN_MONT_CTX *_method_mod_p; - BN_MONT_CTX *_method_mod_q; - /* - * all BIGNUM values are actually in the following data, if it is not - * NULL - */ - char *bignum_data; - BN_BLINDING *blinding; - BN_BLINDING *mt_blinding; -}; - -# ifndef OPENSSL_RSA_MAX_MODULUS_BITS -# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 -# endif - -# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS -# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 -# endif -# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS - -/* exponent limit enforced for "large" modulus only */ -# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 -# endif - -# define RSA_3 0x3L -# define RSA_F4 0x10001L - -# define RSA_METHOD_FLAG_NO_CHECK 0x0001/* don't check pub/private - * match */ - -# define RSA_FLAG_CACHE_PUBLIC 0x0002 -# define RSA_FLAG_CACHE_PRIVATE 0x0004 -# define RSA_FLAG_BLINDING 0x0008 -# define RSA_FLAG_THREAD_SAFE 0x0010 -/* - * This flag means the private key operations will be handled by rsa_mod_exp - * and that they do not depend on the private key components being present: - * for example a key stored in external hardware. Without this flag - * bn_mod_exp gets called when private key components are absent. - */ -# define RSA_FLAG_EXT_PKEY 0x0020 - -/* - * This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify - * functions. - */ -# define RSA_FLAG_SIGN_VER 0x0040 - -/* - * new with 0.9.6j and 0.9.7b; the built-in - * RSA implementation now uses blinding by - * default (ignoring RSA_FLAG_BLINDING), - * but other engines might not need it - */ -# define RSA_FLAG_NO_BLINDING 0x0080 -/* - * new with 0.9.8f; the built-in RSA - * implementation now uses constant time - * operations by default in private key operations, - * e.g., constant time modular exponentiation, - * modular inverse without leaking branches, - * division without leaking branches. This - * flag disables these constant time - * operations and results in faster RSA - * private key operations. - */ -# define RSA_FLAG_NO_CONSTTIME 0x0100 -# ifdef OPENSSL_USE_DEPRECATED -/* deprecated name for the flag*/ -/* - * new with 0.9.7h; the built-in RSA - * implementation now uses constant time - * modular exponentiation for secret exponents - * by default. This flag causes the - * faster variable sliding window method to - * be used for all exponents. - */ -# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME -# endif - -# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \ - pad, NULL) - -# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \ - EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) - -# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ - (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ - EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \ - len, NULL) - -# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ - (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ - EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \ - 0, plen) - -# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ - EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) - -# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ - EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) - -# define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ - EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ - EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md) - -# define EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ - EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md) - -# define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ - EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, \ - EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd) - -# define EVP_PKEY_CTX_get_rsa_oaep_md(ctx, pmd) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ - EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)pmd) - -# define EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, l, llen) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ - EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen, (void *)l) - -# define EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, l) \ - EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, \ - EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, (void *)l) - -# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) -# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) - -# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) -# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) -# define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) - -# define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) -# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) -# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) - -# define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 9) -# define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 10) - -# define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 11) -# define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) - -# define RSA_PKCS1_PADDING 1 -# define RSA_SSLV23_PADDING 2 -# define RSA_NO_PADDING 3 -# define RSA_PKCS1_OAEP_PADDING 4 -# define RSA_X931_PADDING 5 -/* EVP_PKEY_ only */ -# define RSA_PKCS1_PSS_PADDING 6 - -# define RSA_PKCS1_PADDING_SIZE 11 - -# define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) -# define RSA_get_app_data(s) RSA_get_ex_data(s,0) - -RSA *RSA_new(void); -RSA *RSA_new_method(ENGINE *engine); -int RSA_size(const RSA *rsa); - -/* Deprecated version */ -# ifndef OPENSSL_NO_DEPRECATED -RSA *RSA_generate_key(int bits, unsigned long e, void - (*callback) (int, int, void *), void *cb_arg); -# endif /* !defined(OPENSSL_NO_DEPRECATED) */ - -/* New version */ -int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); - -int RSA_check_key(const RSA *); - /* next 4 return -1 on error */ -int RSA_public_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -int RSA_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -int RSA_public_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -int RSA_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -void RSA_free(RSA *r); -/* "up" the RSA object's reference count */ -int RSA_up_ref(RSA *r); - -int RSA_flags(const RSA *r); - -void RSA_set_default_method(const RSA_METHOD *meth); -const RSA_METHOD *RSA_get_default_method(void); -const RSA_METHOD *RSA_get_method(const RSA *rsa); -int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); - -/* This function needs the memory locking malloc callbacks to be installed */ -int RSA_memory_lock(RSA *r); - -/* these are the actual SSLeay RSA functions */ -const RSA_METHOD *RSA_PKCS1_SSLeay(void); - -const RSA_METHOD *RSA_null_method(void); - -DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) -DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) - -typedef struct rsa_pss_params_st { - X509_ALGOR *hashAlgorithm; - X509_ALGOR *maskGenAlgorithm; - ASN1_INTEGER *saltLength; - ASN1_INTEGER *trailerField; -} RSA_PSS_PARAMS; - -DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) - -typedef struct rsa_oaep_params_st { - X509_ALGOR *hashFunc; - X509_ALGOR *maskGenFunc; - X509_ALGOR *pSourceFunc; -} RSA_OAEP_PARAMS; - -DECLARE_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) - -# ifndef OPENSSL_NO_FP_API -int RSA_print_fp(FILE *fp, const RSA *r, int offset); -# endif - -# ifndef OPENSSL_NO_BIO -int RSA_print(BIO *bp, const RSA *r, int offset); -# endif - -# ifndef OPENSSL_NO_RC4 -int i2d_RSA_NET(const RSA *a, unsigned char **pp, - int (*cb) (char *buf, int len, const char *prompt, - int verify), int sgckey); -RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, - int (*cb) (char *buf, int len, const char *prompt, - int verify), int sgckey); - -int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, - int (*cb) (char *buf, int len, const char *prompt, - int verify)); -RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, - int (*cb) (char *buf, int len, const char *prompt, - int verify)); -# endif - -/* - * The following 2 functions sign and verify a X509_SIG ASN1 object inside - * PKCS#1 padded RSA encryption - */ -int RSA_sign(int type, const unsigned char *m, unsigned int m_length, - unsigned char *sigret, unsigned int *siglen, RSA *rsa); -int RSA_verify(int type, const unsigned char *m, unsigned int m_length, - const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); - -/* - * The following 2 function sign and verify a ASN1_OCTET_STRING object inside - * PKCS#1 padded RSA encryption - */ -int RSA_sign_ASN1_OCTET_STRING(int type, - const unsigned char *m, unsigned int m_length, - unsigned char *sigret, unsigned int *siglen, - RSA *rsa); -int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, - unsigned int m_length, unsigned char *sigbuf, - unsigned int siglen, RSA *rsa); - -int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); -void RSA_blinding_off(RSA *rsa); -BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); - -int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, - const unsigned char *f, int fl); -int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, - const unsigned char *f, int fl, - int rsa_len); -int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, - const unsigned char *f, int fl); -int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, - const unsigned char *f, int fl, - int rsa_len); -int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, - long seedlen, const EVP_MD *dgst); -int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, - const unsigned char *f, int fl, - const unsigned char *p, int pl); -int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, - const unsigned char *f, int fl, int rsa_len, - const unsigned char *p, int pl); -int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - const unsigned char *param, int plen, - const EVP_MD *md, const EVP_MD *mgf1md); -int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - int num, const unsigned char *param, - int plen, const EVP_MD *md, - const EVP_MD *mgf1md); -int RSA_padding_add_SSLv23(unsigned char *to, int tlen, - const unsigned char *f, int fl); -int RSA_padding_check_SSLv23(unsigned char *to, int tlen, - const unsigned char *f, int fl, int rsa_len); -int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f, - int fl); -int RSA_padding_check_none(unsigned char *to, int tlen, - const unsigned char *f, int fl, int rsa_len); -int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f, - int fl); -int RSA_padding_check_X931(unsigned char *to, int tlen, - const unsigned char *f, int fl, int rsa_len); -int RSA_X931_hash_id(int nid); - -int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, - const EVP_MD *Hash, const unsigned char *EM, - int sLen); -int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, - const unsigned char *mHash, const EVP_MD *Hash, - int sLen); - -int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, - const EVP_MD *Hash, const EVP_MD *mgf1Hash, - const unsigned char *EM, int sLen); - -int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, - const unsigned char *mHash, - const EVP_MD *Hash, const EVP_MD *mgf1Hash, - int sLen); - -int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int RSA_set_ex_data(RSA *r, int idx, void *arg); -void *RSA_get_ex_data(const RSA *r, int idx); - -RSA *RSAPublicKey_dup(RSA *rsa); -RSA *RSAPrivateKey_dup(RSA *rsa); - -/* - * If this flag is set the RSA method is FIPS compliant and can be used in - * FIPS mode. This is set in the validated module method. If an application - * sets this flag in its own methods it is its responsibility to ensure the - * result is compliant. - */ - -# define RSA_FLAG_FIPS_METHOD 0x0400 - -/* - * If this flag is set the operations normally disabled in FIPS mode are - * permitted it is then the applications responsibility to ensure that the - * usage is compliant. - */ - -# define RSA_FLAG_NON_FIPS_ALLOW 0x0400 -/* - * Application has decided PRNG is good enough to generate a key: don't - * check. - */ -# define RSA_FLAG_CHECKED 0x0800 - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_RSA_strings(void); - -/* Error codes for the RSA functions. */ - -/* Function codes. */ -# define RSA_F_CHECK_PADDING_MD 140 -# define RSA_F_DO_RSA_PRINT 146 -# define RSA_F_INT_RSA_VERIFY 145 -# define RSA_F_MEMORY_LOCK 100 -# define RSA_F_OLD_RSA_PRIV_DECODE 147 -# define RSA_F_PKEY_RSA_CTRL 143 -# define RSA_F_PKEY_RSA_CTRL_STR 144 -# define RSA_F_PKEY_RSA_SIGN 142 -# define RSA_F_PKEY_RSA_VERIFY 154 -# define RSA_F_PKEY_RSA_VERIFYRECOVER 141 -# define RSA_F_RSA_ALGOR_TO_MD 157 -# define RSA_F_RSA_BUILTIN_KEYGEN 129 -# define RSA_F_RSA_CHECK_KEY 123 -# define RSA_F_RSA_CMS_DECRYPT 158 -# define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 -# define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102 -# define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103 -# define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104 -# define RSA_F_RSA_GENERATE_KEY 105 -# define RSA_F_RSA_GENERATE_KEY_EX 155 -# define RSA_F_RSA_ITEM_VERIFY 156 -# define RSA_F_RSA_MEMORY_LOCK 130 -# define RSA_F_RSA_MGF1_TO_MD 159 -# define RSA_F_RSA_NEW_METHOD 106 -# define RSA_F_RSA_NULL 124 -# define RSA_F_RSA_NULL_MOD_EXP 131 -# define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 -# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 -# define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 -# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 -# define RSA_F_RSA_PADDING_ADD_NONE 107 -# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 -# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1 160 -# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 -# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148 -# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 -# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 -# define RSA_F_RSA_PADDING_ADD_SSLV23 110 -# define RSA_F_RSA_PADDING_ADD_X931 127 -# define RSA_F_RSA_PADDING_CHECK_NONE 111 -# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 -# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1 161 -# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 -# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 -# define RSA_F_RSA_PADDING_CHECK_SSLV23 114 -# define RSA_F_RSA_PADDING_CHECK_X931 128 -# define RSA_F_RSA_PRINT 115 -# define RSA_F_RSA_PRINT_FP 116 -# define RSA_F_RSA_PRIVATE_DECRYPT 150 -# define RSA_F_RSA_PRIVATE_ENCRYPT 151 -# define RSA_F_RSA_PRIV_DECODE 137 -# define RSA_F_RSA_PRIV_ENCODE 138 -# define RSA_F_RSA_PSS_TO_CTX 162 -# define RSA_F_RSA_PUBLIC_DECRYPT 152 -# define RSA_F_RSA_PUBLIC_ENCRYPT 153 -# define RSA_F_RSA_PUB_DECODE 139 -# define RSA_F_RSA_SETUP_BLINDING 136 -# define RSA_F_RSA_SIGN 117 -# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 -# define RSA_F_RSA_VERIFY 119 -# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 -# define RSA_F_RSA_VERIFY_PKCS1_PSS 126 -# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149 - -/* Reason codes. */ -# define RSA_R_ALGORITHM_MISMATCH 100 -# define RSA_R_BAD_E_VALUE 101 -# define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 -# define RSA_R_BAD_PAD_BYTE_COUNT 103 -# define RSA_R_BAD_SIGNATURE 104 -# define RSA_R_BLOCK_TYPE_IS_NOT_01 106 -# define RSA_R_BLOCK_TYPE_IS_NOT_02 107 -# define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 -# define RSA_R_DATA_TOO_LARGE 109 -# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 -# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 -# define RSA_R_DATA_TOO_SMALL 111 -# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 -# define RSA_R_DIGEST_DOES_NOT_MATCH 166 -# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 -# define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 -# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 -# define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 -# define RSA_R_FIRST_OCTET_INVALID 133 -# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 -# define RSA_R_INVALID_DIGEST 160 -# define RSA_R_INVALID_DIGEST_LENGTH 143 -# define RSA_R_INVALID_HEADER 137 -# define RSA_R_INVALID_KEYBITS 145 -# define RSA_R_INVALID_LABEL 161 -# define RSA_R_INVALID_MESSAGE_LENGTH 131 -# define RSA_R_INVALID_MGF1_MD 156 -# define RSA_R_INVALID_OAEP_PARAMETERS 162 -# define RSA_R_INVALID_PADDING 138 -# define RSA_R_INVALID_PADDING_MODE 141 -# define RSA_R_INVALID_PSS_PARAMETERS 149 -# define RSA_R_INVALID_PSS_SALTLEN 146 -# define RSA_R_INVALID_SALT_LENGTH 150 -# define RSA_R_INVALID_TRAILER 139 -# define RSA_R_INVALID_X931_DIGEST 142 -# define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 -# define RSA_R_KEY_SIZE_TOO_SMALL 120 -# define RSA_R_LAST_OCTET_INVALID 134 -# define RSA_R_MODULUS_TOO_LARGE 105 -# define RSA_R_NON_FIPS_RSA_METHOD 157 -# define RSA_R_NO_PUBLIC_EXPONENT 140 -# define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 -# define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 -# define RSA_R_OAEP_DECODING_ERROR 121 -# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158 -# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 -# define RSA_R_PADDING_CHECK_FAILED 114 -# define RSA_R_PKCS_DECODING_ERROR 159 -# define RSA_R_P_NOT_PRIME 128 -# define RSA_R_Q_NOT_PRIME 129 -# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 -# define RSA_R_SLEN_CHECK_FAILED 136 -# define RSA_R_SLEN_RECOVERY_FAILED 135 -# define RSA_R_SSLV3_ROLLBACK_ATTACK 115 -# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 -# define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 -# define RSA_R_UNKNOWN_DIGEST 163 -# define RSA_R_UNKNOWN_MASK_DIGEST 151 -# define RSA_R_UNKNOWN_PADDING_TYPE 118 -# define RSA_R_UNKNOWN_PSS_DIGEST 152 -# define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE 164 -# define RSA_R_UNSUPPORTED_LABEL_SOURCE 165 -# define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 -# define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 -# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 -# define RSA_R_VALUE_MISSING 147 -# define RSA_R_WRONG_SIGNATURE_LENGTH 119 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/rsa_.c b/Sources/COpenSSL/rsa_.c deleted file mode 100644 index 6ab5d9c8..00000000 --- a/Sources/COpenSSL/rsa_.c +++ /dev/null @@ -1,6247 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/rsa/rsa_ameth.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "asn1t.h" -#include "x509.h" -#include "rsa.h" -#include "bn.h" -#ifndef OPENSSL_NO_CMS -# include "cms.h" -#endif -#include "asn1_locl.h" - -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si); -static int rsa_cms_verify(CMS_SignerInfo *si); -static int rsa_cms_decrypt(CMS_RecipientInfo *ri); -static int rsa_cms_encrypt(CMS_RecipientInfo *ri); -#endif - -static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) -{ - unsigned char *penc = NULL; - int penclen; - penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); - if (penclen <= 0) - return 0; - if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), - V_ASN1_NULL, NULL, penc, penclen)) - return 1; - - OPENSSL_free(penc); - return 0; -} - -static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) -{ - const unsigned char *p; - int pklen; - RSA *rsa = NULL; - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) - return 0; - if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) { - RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); - return 0; - } - EVP_PKEY_assign_RSA(pkey, rsa); - return 1; -} - -static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) -{ - if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 - || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) - return 0; - return 1; -} - -static int old_rsa_priv_decode(EVP_PKEY *pkey, - const unsigned char **pder, int derlen) -{ - RSA *rsa; - if (!(rsa = d2i_RSAPrivateKey(NULL, pder, derlen))) { - RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); - return 0; - } - EVP_PKEY_assign_RSA(pkey, rsa); - return 1; -} - -static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) -{ - return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); -} - -static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) -{ - unsigned char *rk = NULL; - int rklen; - rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); - - if (rklen <= 0) { - RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0, - V_ASN1_NULL, NULL, rk, rklen)) { - RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); - return 0; - } - - return 1; -} - -static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) -{ - const unsigned char *p; - int pklen; - if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) - return 0; - return old_rsa_priv_decode(pkey, &p, pklen); -} - -static int int_rsa_size(const EVP_PKEY *pkey) -{ - return RSA_size(pkey->pkey.rsa); -} - -static int rsa_bits(const EVP_PKEY *pkey) -{ - return BN_num_bits(pkey->pkey.rsa->n); -} - -static void int_rsa_free(EVP_PKEY *pkey) -{ - RSA_free(pkey->pkey.rsa); -} - -static void update_buflen(const BIGNUM *b, size_t *pbuflen) -{ - size_t i; - if (!b) - return; - if (*pbuflen < (i = (size_t)BN_num_bytes(b))) - *pbuflen = i; -} - -static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv) -{ - char *str; - const char *s; - unsigned char *m = NULL; - int ret = 0, mod_len = 0; - size_t buf_len = 0; - - update_buflen(x->n, &buf_len); - update_buflen(x->e, &buf_len); - - if (priv) { - update_buflen(x->d, &buf_len); - update_buflen(x->p, &buf_len); - update_buflen(x->q, &buf_len); - update_buflen(x->dmp1, &buf_len); - update_buflen(x->dmq1, &buf_len); - update_buflen(x->iqmp, &buf_len); - } - - m = (unsigned char *)OPENSSL_malloc(buf_len + 10); - if (m == NULL) { - RSAerr(RSA_F_DO_RSA_PRINT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (x->n != NULL) - mod_len = BN_num_bits(x->n); - - if (!BIO_indent(bp, off, 128)) - goto err; - - if (priv && x->d) { - if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) - <= 0) - goto err; - str = "modulus:"; - s = "publicExponent:"; - } else { - if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) - <= 0) - goto err; - str = "Modulus:"; - s = "Exponent:"; - } - if (!ASN1_bn_print(bp, str, x->n, m, off)) - goto err; - if (!ASN1_bn_print(bp, s, x->e, m, off)) - goto err; - if (priv) { - if (!ASN1_bn_print(bp, "privateExponent:", x->d, m, off)) - goto err; - if (!ASN1_bn_print(bp, "prime1:", x->p, m, off)) - goto err; - if (!ASN1_bn_print(bp, "prime2:", x->q, m, off)) - goto err; - if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, m, off)) - goto err; - if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, m, off)) - goto err; - if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, m, off)) - goto err; - } - ret = 1; - err: - if (m != NULL) - OPENSSL_free(m); - return (ret); -} - -static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); -} - -static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *ctx) -{ - return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); -} - -/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */ -static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) -{ - const unsigned char *p; - int plen; - if (alg == NULL || alg->parameter == NULL) - return NULL; - if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) - return NULL; - if (alg->parameter->type != V_ASN1_SEQUENCE) - return NULL; - - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - return d2i_X509_ALGOR(NULL, &p, plen); -} - -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg, - X509_ALGOR **pmaskHash) -{ - const unsigned char *p; - int plen; - RSA_PSS_PARAMS *pss; - - *pmaskHash = NULL; - - if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) - return NULL; - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); - - if (!pss) - return NULL; - - *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); - - return pss; -} - -static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, - X509_ALGOR *maskHash, int indent) -{ - int rv = 0; - if (!pss) { - if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) - return 0; - return 1; - } - if (BIO_puts(bp, "\n") <= 0) - goto err; - if (!BIO_indent(bp, indent, 128)) - goto err; - if (BIO_puts(bp, "Hash Algorithm: ") <= 0) - goto err; - - if (pss->hashAlgorithm) { - if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) - goto err; - } else if (BIO_puts(bp, "sha1 (default)") <= 0) - goto err; - - if (BIO_puts(bp, "\n") <= 0) - goto err; - - if (!BIO_indent(bp, indent, 128)) - goto err; - - if (BIO_puts(bp, "Mask Algorithm: ") <= 0) - goto err; - if (pss->maskGenAlgorithm) { - if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) - goto err; - if (BIO_puts(bp, " with ") <= 0) - goto err; - if (maskHash) { - if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) - goto err; - } else if (BIO_puts(bp, "INVALID") <= 0) - goto err; - } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) - goto err; - BIO_puts(bp, "\n"); - - if (!BIO_indent(bp, indent, 128)) - goto err; - if (BIO_puts(bp, "Salt Length: 0x") <= 0) - goto err; - if (pss->saltLength) { - if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) - goto err; - } else if (BIO_puts(bp, "14 (default)") <= 0) - goto err; - BIO_puts(bp, "\n"); - - if (!BIO_indent(bp, indent, 128)) - goto err; - if (BIO_puts(bp, "Trailer Field: 0x") <= 0) - goto err; - if (pss->trailerField) { - if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) - goto err; - } else if (BIO_puts(bp, "BC (default)") <= 0) - goto err; - BIO_puts(bp, "\n"); - - rv = 1; - - err: - return rv; - -} - -static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, - const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) -{ - if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) { - int rv; - RSA_PSS_PARAMS *pss; - X509_ALGOR *maskHash; - pss = rsa_pss_decode(sigalg, &maskHash); - rv = rsa_pss_param_print(bp, pss, maskHash, indent); - if (pss) - RSA_PSS_PARAMS_free(pss); - if (maskHash) - X509_ALGOR_free(maskHash); - if (!rv) - return 0; - } else if (!sig && BIO_puts(bp, "\n") <= 0) - return 0; - if (sig) - return X509_signature_dump(bp, sig, indent); - return 1; -} - -static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) -{ - X509_ALGOR *alg = NULL; - switch (op) { - - case ASN1_PKEY_CTRL_PKCS7_SIGN: - if (arg1 == 0) - PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); - break; - - case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: - if (arg1 == 0) - PKCS7_RECIP_INFO_get0_alg(arg2, &alg); - break; -#ifndef OPENSSL_NO_CMS - case ASN1_PKEY_CTRL_CMS_SIGN: - if (arg1 == 0) - return rsa_cms_sign(arg2); - else if (arg1 == 1) - return rsa_cms_verify(arg2); - break; - - case ASN1_PKEY_CTRL_CMS_ENVELOPE: - if (arg1 == 0) - return rsa_cms_encrypt(arg2); - else if (arg1 == 1) - return rsa_cms_decrypt(arg2); - break; - - case ASN1_PKEY_CTRL_CMS_RI_TYPE: - *(int *)arg2 = CMS_RECIPINFO_TRANS; - return 1; -#endif - - case ASN1_PKEY_CTRL_DEFAULT_MD_NID: - *(int *)arg2 = NID_sha256; - return 1; - - default: - return -2; - - } - - if (alg) - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - - return 1; - -} - -/* allocate and set algorithm ID from EVP_MD, default SHA1 */ -static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) -{ - if (EVP_MD_type(md) == NID_sha1) - return 1; - *palg = X509_ALGOR_new(); - if (!*palg) - return 0; - X509_ALGOR_set_md(*palg, md); - return 1; -} - -/* Allocate and set MGF1 algorithm ID from EVP_MD */ -static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) -{ - X509_ALGOR *algtmp = NULL; - ASN1_STRING *stmp = NULL; - *palg = NULL; - if (EVP_MD_type(mgf1md) == NID_sha1) - return 1; - /* need to embed algorithm ID inside another */ - if (!rsa_md_to_algor(&algtmp, mgf1md)) - goto err; - if (!ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) - goto err; - *palg = X509_ALGOR_new(); - if (!*palg) - goto err; - X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); - stmp = NULL; - err: - if (stmp) - ASN1_STRING_free(stmp); - if (algtmp) - X509_ALGOR_free(algtmp); - if (*palg) - return 1; - return 0; -} - -/* convert algorithm ID to EVP_MD, default SHA1 */ -static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) -{ - const EVP_MD *md; - if (!alg) - return EVP_sha1(); - md = EVP_get_digestbyobj(alg->algorithm); - if (md == NULL) - RSAerr(RSA_F_RSA_ALGOR_TO_MD, RSA_R_UNKNOWN_DIGEST); - return md; -} - -/* convert MGF1 algorithm ID to EVP_MD, default SHA1 */ -static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) -{ - const EVP_MD *md; - if (!alg) - return EVP_sha1(); - /* Check mask and lookup mask hash algorithm */ - if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) { - RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_ALGORITHM); - return NULL; - } - if (!maskHash) { - RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNSUPPORTED_MASK_PARAMETER); - return NULL; - } - md = EVP_get_digestbyobj(maskHash->algorithm); - if (md == NULL) { - RSAerr(RSA_F_RSA_MGF1_TO_MD, RSA_R_UNKNOWN_MASK_DIGEST); - return NULL; - } - return md; -} - -/* - * Convert EVP_PKEY_CTX is PSS mode into corresponding algorithm parameter, - * suitable for setting an AlgorithmIdentifier. - */ - -static ASN1_STRING *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx) -{ - const EVP_MD *sigmd, *mgf1md; - RSA_PSS_PARAMS *pss = NULL; - ASN1_STRING *os = NULL; - EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); - int saltlen, rv = 0; - if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0) - goto err; - if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) - goto err; - if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) - goto err; - if (saltlen == -1) - saltlen = EVP_MD_size(sigmd); - else if (saltlen == -2) { - saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; - if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) - saltlen--; - } - pss = RSA_PSS_PARAMS_new(); - if (!pss) - goto err; - if (saltlen != 20) { - pss->saltLength = ASN1_INTEGER_new(); - if (!pss->saltLength) - goto err; - if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) - goto err; - } - if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd)) - goto err; - if (!rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) - goto err; - /* Finally create string with pss parameter encoding. */ - if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) - goto err; - rv = 1; - err: - if (pss) - RSA_PSS_PARAMS_free(pss); - if (rv) - return os; - if (os) - ASN1_STRING_free(os); - return NULL; -} - -/* - * From PSS AlgorithmIdentifier set public key parameters. If pkey isn't NULL - * then the EVP_MD_CTX is setup and initalised. If it is NULL parameters are - * passed to pkctx instead. - */ - -static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, - X509_ALGOR *sigalg, EVP_PKEY *pkey) -{ - int rv = -1; - int saltlen; - const EVP_MD *mgf1md = NULL, *md = NULL; - RSA_PSS_PARAMS *pss; - X509_ALGOR *maskHash; - /* Sanity check: make sure it is PSS */ - if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); - return -1; - } - /* Decode PSS parameters */ - pss = rsa_pss_decode(sigalg, &maskHash); - - if (pss == NULL) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_PSS_PARAMETERS); - goto err; - } - mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); - if (!mgf1md) - goto err; - md = rsa_algor_to_md(pss->hashAlgorithm); - if (!md) - goto err; - - if (pss->saltLength) { - saltlen = ASN1_INTEGER_get(pss->saltLength); - - /* - * Could perform more salt length sanity checks but the main RSA - * routines will trap other invalid values anyway. - */ - if (saltlen < 0) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_SALT_LENGTH); - goto err; - } - } else - saltlen = 20; - - /* - * low-level routines support only trailer field 0xbc (value 1) and - * PKCS#1 says we should reject any other value anyway. - */ - if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_INVALID_TRAILER); - goto err; - } - - /* We have all parameters now set up context */ - - if (pkey) { - if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) - goto err; - } else { - const EVP_MD *checkmd; - if (EVP_PKEY_CTX_get_signature_md(pkctx, &checkmd) <= 0) - goto err; - if (EVP_MD_type(md) != EVP_MD_type(checkmd)) { - RSAerr(RSA_F_RSA_PSS_TO_CTX, RSA_R_DIGEST_DOES_NOT_MATCH); - goto err; - } - } - - if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) - goto err; - - if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) - goto err; - - if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) - goto err; - /* Carry on */ - rv = 1; - - err: - RSA_PSS_PARAMS_free(pss); - if (maskHash) - X509_ALGOR_free(maskHash); - return rv; -} - -#ifndef OPENSSL_NO_CMS -static int rsa_cms_verify(CMS_SignerInfo *si) -{ - int nid, nid2; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - nid = OBJ_obj2nid(alg->algorithm); - if (nid == NID_rsaEncryption) - return 1; - if (nid == NID_rsassaPss) - return rsa_pss_to_ctx(NULL, pkctx, alg, NULL); - /* Workaround for some implementation that use a signature OID */ - if (OBJ_find_sigid_algs(nid, NULL, &nid2)) { - if (nid2 == NID_rsaEncryption) - return 1; - } - return 0; -} -#endif - -/* - * Customised RSA item verification routine. This is called when a signature - * is encountered requiring special handling. We currently only handle PSS. - */ - -static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, - EVP_PKEY *pkey) -{ - /* Sanity check: make sure it is PSS */ - if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { - RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); - return -1; - } - if (rsa_pss_to_ctx(ctx, NULL, sigalg, pkey) > 0) { - /* Carry on */ - return 2; - } - return -1; -} - -#ifndef OPENSSL_NO_CMS -static int rsa_cms_sign(CMS_SignerInfo *si) -{ - int pad_mode = RSA_PKCS1_PADDING; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_SignerInfo_get0_pkey_ctx(si); - ASN1_STRING *os = NULL; - CMS_SignerInfo_get0_algs(si, NULL, NULL, NULL, &alg); - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } - /* We don't support it */ - if (pad_mode != RSA_PKCS1_PSS_PADDING) - return 0; - os = rsa_ctx_to_pss(pkctx); - if (!os) - return 0; - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os); - return 1; -} -#endif - -static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *alg1, X509_ALGOR *alg2, - ASN1_BIT_STRING *sig) -{ - int pad_mode; - EVP_PKEY_CTX *pkctx = ctx->pctx; - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - if (pad_mode == RSA_PKCS1_PADDING) - return 2; - if (pad_mode == RSA_PKCS1_PSS_PADDING) { - ASN1_STRING *os1 = NULL; - os1 = rsa_ctx_to_pss(pkctx); - if (!os1) - return 0; - /* Duplicate parameters if we have to */ - if (alg2) { - ASN1_STRING *os2 = ASN1_STRING_dup(os1); - if (!os2) { - ASN1_STRING_free(os1); - return 0; - } - X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), - V_ASN1_SEQUENCE, os2); - } - X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), - V_ASN1_SEQUENCE, os1); - return 3; - } - return 2; -} - -#ifndef OPENSSL_NO_CMS -static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg, - X509_ALGOR **pmaskHash) -{ - const unsigned char *p; - int plen; - RSA_OAEP_PARAMS *pss; - - *pmaskHash = NULL; - - if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) - return NULL; - p = alg->parameter->value.sequence->data; - plen = alg->parameter->value.sequence->length; - pss = d2i_RSA_OAEP_PARAMS(NULL, &p, plen); - - if (!pss) - return NULL; - - *pmaskHash = rsa_mgf1_decode(pss->maskGenFunc); - - return pss; -} - -static int rsa_cms_decrypt(CMS_RecipientInfo *ri) -{ - EVP_PKEY_CTX *pkctx; - X509_ALGOR *cmsalg; - int nid; - int rv = -1; - unsigned char *label = NULL; - int labellen = 0; - const EVP_MD *mgf1md = NULL, *md = NULL; - RSA_OAEP_PARAMS *oaep; - X509_ALGOR *maskHash; - pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - if (!pkctx) - return 0; - if (!CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &cmsalg)) - return -1; - nid = OBJ_obj2nid(cmsalg->algorithm); - if (nid == NID_rsaEncryption) - return 1; - if (nid != NID_rsaesOaep) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE); - return -1; - } - /* Decode OAEP parameters */ - oaep = rsa_oaep_decode(cmsalg, &maskHash); - - if (oaep == NULL) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_OAEP_PARAMETERS); - goto err; - } - - mgf1md = rsa_mgf1_to_md(oaep->maskGenFunc, maskHash); - if (!mgf1md) - goto err; - md = rsa_algor_to_md(oaep->hashFunc); - if (!md) - goto err; - - if (oaep->pSourceFunc) { - X509_ALGOR *plab = oaep->pSourceFunc; - if (OBJ_obj2nid(plab->algorithm) != NID_pSpecified) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_UNSUPPORTED_LABEL_SOURCE); - goto err; - } - if (plab->parameter->type != V_ASN1_OCTET_STRING) { - RSAerr(RSA_F_RSA_CMS_DECRYPT, RSA_R_INVALID_LABEL); - goto err; - } - - label = plab->parameter->value.octet_string->data; - /* Stop label being freed when OAEP parameters are freed */ - plab->parameter->value.octet_string->data = NULL; - labellen = plab->parameter->value.octet_string->length; - } - - if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) - goto err; - if (EVP_PKEY_CTX_set_rsa_oaep_md(pkctx, md) <= 0) - goto err; - if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) - goto err; - if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, label, labellen) <= 0) - goto err; - /* Carry on */ - rv = 1; - - err: - RSA_OAEP_PARAMS_free(oaep); - if (maskHash) - X509_ALGOR_free(maskHash); - return rv; -} - -static int rsa_cms_encrypt(CMS_RecipientInfo *ri) -{ - const EVP_MD *md, *mgf1md; - RSA_OAEP_PARAMS *oaep = NULL; - ASN1_STRING *os = NULL; - X509_ALGOR *alg; - EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri); - int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen; - unsigned char *label; - CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg); - if (pkctx) { - if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) - return 0; - } - if (pad_mode == RSA_PKCS1_PADDING) { - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); - return 1; - } - /* Not supported */ - if (pad_mode != RSA_PKCS1_OAEP_PADDING) - return 0; - if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0) - goto err; - if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) - goto err; - labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label); - if (labellen < 0) - goto err; - oaep = RSA_OAEP_PARAMS_new(); - if (!oaep) - goto err; - if (!rsa_md_to_algor(&oaep->hashFunc, md)) - goto err; - if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md)) - goto err; - if (labellen > 0) { - ASN1_OCTET_STRING *los = ASN1_OCTET_STRING_new(); - oaep->pSourceFunc = X509_ALGOR_new(); - if (!oaep->pSourceFunc) - goto err; - if (!los) - goto err; - if (!ASN1_OCTET_STRING_set(los, label, labellen)) { - ASN1_OCTET_STRING_free(los); - goto err; - } - X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified), - V_ASN1_OCTET_STRING, los); - } - /* create string with pss parameter encoding. */ - if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os)) - goto err; - X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os); - os = NULL; - rv = 1; - err: - if (oaep) - RSA_OAEP_PARAMS_free(oaep); - if (os) - ASN1_STRING_free(os); - return rv; -} -#endif - -const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { - { - EVP_PKEY_RSA, - EVP_PKEY_RSA, - ASN1_PKEY_SIGPARAM_NULL, - - "RSA", - "OpenSSL RSA method", - - rsa_pub_decode, - rsa_pub_encode, - rsa_pub_cmp, - rsa_pub_print, - - rsa_priv_decode, - rsa_priv_encode, - rsa_priv_print, - - int_rsa_size, - rsa_bits, - - 0, 0, 0, 0, 0, 0, - - rsa_sig_print, - int_rsa_free, - rsa_pkey_ctrl, - old_rsa_priv_decode, - old_rsa_priv_encode, - rsa_item_verify, - rsa_item_sign}, - - { - EVP_PKEY_RSA2, - EVP_PKEY_RSA, - ASN1_PKEY_ALIAS} -}; -/* rsa_asn1.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "x509.h" -// #include "asn1t.h" - -/* Override the default free and new methods */ -static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_NEW_PRE) { - *pval = (ASN1_VALUE *)RSA_new(); - if (*pval) - return 2; - return 0; - } else if (operation == ASN1_OP_FREE_PRE) { - RSA_free((RSA *)*pval); - *pval = NULL; - return 2; - } - return 1; -} - -ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = { - ASN1_SIMPLE(RSA, version, LONG), - ASN1_SIMPLE(RSA, n, BIGNUM), - ASN1_SIMPLE(RSA, e, BIGNUM), - ASN1_SIMPLE(RSA, d, BIGNUM), - ASN1_SIMPLE(RSA, p, BIGNUM), - ASN1_SIMPLE(RSA, q, BIGNUM), - ASN1_SIMPLE(RSA, dmp1, BIGNUM), - ASN1_SIMPLE(RSA, dmq1, BIGNUM), - ASN1_SIMPLE(RSA, iqmp, BIGNUM) -} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey) - - -ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = { - ASN1_SIMPLE(RSA, n, BIGNUM), - ASN1_SIMPLE(RSA, e, BIGNUM), -} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey) - -ASN1_SEQUENCE(RSA_PSS_PARAMS) = { - ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0), - ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1), - ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2), - ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3) -} ASN1_SEQUENCE_END(RSA_PSS_PARAMS) - -IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS) - -ASN1_SEQUENCE(RSA_OAEP_PARAMS) = { - ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0), - ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1), - ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2), -} ASN1_SEQUENCE_END(RSA_OAEP_PARAMS) - -IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey) - -RSA *RSAPublicKey_dup(RSA *rsa) -{ - return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); -} - -RSA *RSAPrivateKey_dup(RSA *rsa) -{ - return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); -} -/* crypto/rsa/rsa_chk.c */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -// #include "bn.h" -#include "err.h" -// #include "rsa.h" - -int RSA_check_key(const RSA *key) -{ - BIGNUM *i, *j, *k, *l, *m; - BN_CTX *ctx; - int ret = 1; - - if (!key->p || !key->q || !key->n || !key->e || !key->d) { - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING); - return 0; - } - - i = BN_new(); - j = BN_new(); - k = BN_new(); - l = BN_new(); - m = BN_new(); - ctx = BN_CTX_new(); - if (i == NULL || j == NULL || k == NULL || l == NULL - || m == NULL || ctx == NULL) { - ret = -1; - RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (BN_is_one(key->e)) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_BAD_E_VALUE); - } - if (!BN_is_odd(key->e)) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_BAD_E_VALUE); - } - - /* p prime? */ - if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL) != 1) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME); - } - - /* q prime? */ - if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL) != 1) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME); - } - - /* n = p*q? */ - if (!BN_mul(i, key->p, key->q, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(i, key->n) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q); - } - - /* d*e = 1 mod lcm(p-1,q-1)? */ - if (!BN_sub(i, key->p, BN_value_one())) { - ret = -1; - goto err; - } - if (!BN_sub(j, key->q, BN_value_one())) { - ret = -1; - goto err; - } - - /* now compute k = lcm(i,j) */ - if (!BN_mul(l, i, j, ctx)) { - ret = -1; - goto err; - } - if (!BN_gcd(m, i, j, ctx)) { - ret = -1; - goto err; - } - if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */ - ret = -1; - goto err; - } - if (!BN_mod_mul(i, key->d, key->e, k, ctx)) { - ret = -1; - goto err; - } - - if (!BN_is_one(i)) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1); - } - - if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { - /* dmp1 = d mod (p-1)? */ - if (!BN_sub(i, key->p, BN_value_one())) { - ret = -1; - goto err; - } - if (!BN_mod(j, key->d, i, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(j, key->dmp1) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D); - } - - /* dmq1 = d mod (q-1)? */ - if (!BN_sub(i, key->q, BN_value_one())) { - ret = -1; - goto err; - } - if (!BN_mod(j, key->d, i, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(j, key->dmq1) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); - } - - /* iqmp = q^-1 mod p? */ - if (!BN_mod_inverse(i, key->q, key->p, ctx)) { - ret = -1; - goto err; - } - if (BN_cmp(i, key->iqmp) != 0) { - ret = 0; - RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q); - } - } - - err: - BN_free(i); - BN_free(j); - BN_free(k); - BN_free(l); - BN_free(m); - BN_CTX_free(ctx); - return ret; -} -/* crypto/rsa/rsa_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "crypto.h" -// #include "cryptlib.h" -#include "lhash.h" -// #include "bn.h" -// #include "rsa.h" -#include "rand.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -int RSA_size(const RSA *r) -{ - return (BN_num_bytes(r->n)); -} - -int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, - RSA *rsa, int padding) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); - return -1; - } -#endif - return (rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding)); -} - -int RSA_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); - return -1; - } -#endif - return (rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); -} - -int RSA_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); - return -1; - } -#endif - return (rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding)); -} - -int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, - RSA *rsa, int padding) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); - return -1; - } -#endif - return (rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); -} - -int RSA_flags(const RSA *r) -{ - return ((r == NULL) ? 0 : r->meth->flags); -} - -void RSA_blinding_off(RSA *rsa) -{ - if (rsa->blinding != NULL) { - BN_BLINDING_free(rsa->blinding); - rsa->blinding = NULL; - } - rsa->flags &= ~RSA_FLAG_BLINDING; - rsa->flags |= RSA_FLAG_NO_BLINDING; -} - -int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) -{ - int ret = 0; - - if (rsa->blinding != NULL) - RSA_blinding_off(rsa); - - rsa->blinding = RSA_setup_blinding(rsa, ctx); - if (rsa->blinding == NULL) - goto err; - - rsa->flags |= RSA_FLAG_BLINDING; - rsa->flags &= ~RSA_FLAG_NO_BLINDING; - ret = 1; - err: - return (ret); -} - -static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, - const BIGNUM *q, BN_CTX *ctx) -{ - BIGNUM *ret = NULL, *r0, *r1, *r2; - - if (d == NULL || p == NULL || q == NULL) - return NULL; - - BN_CTX_start(ctx); - r0 = BN_CTX_get(ctx); - r1 = BN_CTX_get(ctx); - r2 = BN_CTX_get(ctx); - if (r2 == NULL) - goto err; - - if (!BN_sub(r1, p, BN_value_one())) - goto err; - if (!BN_sub(r2, q, BN_value_one())) - goto err; - if (!BN_mul(r0, r1, r2, ctx)) - goto err; - - ret = BN_mod_inverse(NULL, d, r0, ctx); - err: - BN_CTX_end(ctx); - return ret; -} - -BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) -{ - BIGNUM local_n; - BIGNUM *e, *n; - BN_CTX *ctx; - BN_BLINDING *ret = NULL; - - if (in_ctx == NULL) { - if ((ctx = BN_CTX_new()) == NULL) - return 0; - } else - ctx = in_ctx; - - BN_CTX_start(ctx); - e = BN_CTX_get(ctx); - if (e == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (rsa->e == NULL) { - e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); - if (e == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); - goto err; - } - } else - e = rsa->e; - - if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) { - /* - * if PRNG is not properly seeded, resort to secret exponent as - * unpredictable seed - */ - RAND_add(rsa->d->d, rsa->d->dmax * sizeof(rsa->d->d[0]), 0.0); - } - - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - /* Set BN_FLG_CONSTTIME flag */ - n = &local_n; - BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); - } else - n = rsa->n; - - ret = BN_BLINDING_create_param(NULL, e, n, ctx, - rsa->meth->bn_mod_exp, rsa->_method_mod_n); - if (ret == NULL) { - RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); - goto err; - } - CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); - err: - BN_CTX_end(ctx); - if (in_ctx == NULL) - BN_CTX_free(ctx); - if (rsa->e == NULL) - BN_free(e); - - return ret; -} -/* crypto/rsa/rsa_depr.c */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NB: This file contains deprecated functions (compatibility wrappers to the - * "new" versions). - */ - -#include -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" - -#ifdef OPENSSL_NO_DEPRECATED - -static void *dummy = &dummy; - -#else - -RSA *RSA_generate_key(int bits, unsigned long e_value, - void (*callback) (int, int, void *), void *cb_arg) -{ - BN_GENCB cb; - int i; - RSA *rsa = RSA_new(); - BIGNUM *e = BN_new(); - - if (!rsa || !e) - goto err; - - /* - * The problem is when building with 8, 16, or 32 BN_ULONG, unsigned long - * can be larger - */ - for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) { - if (e_value & (1UL << i)) - if (BN_set_bit(e, i) == 0) - goto err; - } - - BN_GENCB_set_old(&cb, callback, cb_arg); - - if (RSA_generate_key_ex(rsa, bits, e, &cb)) { - BN_free(e); - return rsa; - } - err: - if (e) - BN_free(e); - if (rsa) - RSA_free(rsa); - return 0; -} -#endif -/* crypto/rsa/rsa_eay.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "rand.h" -#include "bn_int.h" - -#ifndef RSA_NULL - -static int RSA_eay_public_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int RSA_eay_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int RSA_eay_public_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int RSA_eay_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, - BN_CTX *ctx); -static int RSA_eay_init(RSA *rsa); -static int RSA_eay_finish(RSA *rsa); -static RSA_METHOD rsa_pkcs1_eay_meth = { - "Eric Young's PKCS#1 RSA", - RSA_eay_public_encrypt, - RSA_eay_public_decrypt, /* signature verification */ - RSA_eay_private_encrypt, /* signing */ - RSA_eay_private_decrypt, - RSA_eay_mod_exp, - BN_mod_exp_mont, /* XXX probably we should not use Montgomery - * if e == 3 */ - RSA_eay_init, - RSA_eay_finish, - 0, /* flags */ - NULL, - 0, /* rsa_sign */ - 0, /* rsa_verify */ - NULL /* rsa_keygen */ -}; - -const RSA_METHOD *RSA_PKCS1_SSLeay(void) -{ - return (&rsa_pkcs1_eay_meth); -} - -static int RSA_eay_public_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - BIGNUM *f, *ret; - int i, num = 0, r = -1; - unsigned char *buf = NULL; - BN_CTX *ctx = NULL; - - if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); - return -1; - } - - if (BN_ucmp(rsa->n, rsa->e) <= 0) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); - return -1; - } - - /* for large moduli, enforce exponent limit */ - if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { - if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); - return -1; - } - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - ret = BN_CTX_get(ctx); - num = BN_num_bytes(rsa->n); - buf = OPENSSL_malloc(num); - if (!f || !ret || !buf) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); - break; -# ifndef OPENSSL_NO_SHA - case RSA_PKCS1_OAEP_PADDING: - i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); - break; -# endif - case RSA_SSLV23_PADDING: - i = RSA_padding_add_SSLv23(buf, num, from, flen); - break; - case RSA_NO_PADDING: - i = RSA_padding_add_none(buf, num, from, flen); - break; - default: - RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - if (i <= 0) - goto err; - - if (BN_bin2bn(buf, num, f) == NULL) - goto err; - - if (BN_ucmp(f, rsa->n) >= 0) { - /* usually the padding functions would catch this */ - RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, - rsa->n, ctx)) - goto err; - - if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - - /* - * BN_bn2binpad puts in leading 0 bytes if the number is less than - * the length of the modulus. - */ - r = bn_bn2binpad(ret, to, num); - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (buf != NULL) { - OPENSSL_cleanse(buf, num); - OPENSSL_free(buf); - } - return (r); -} - -static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) -{ - BN_BLINDING *ret; - int got_write_lock = 0; - CRYPTO_THREADID cur; - - CRYPTO_r_lock(CRYPTO_LOCK_RSA); - - if (rsa->blinding == NULL) { - CRYPTO_r_unlock(CRYPTO_LOCK_RSA); - CRYPTO_w_lock(CRYPTO_LOCK_RSA); - got_write_lock = 1; - - if (rsa->blinding == NULL) - rsa->blinding = RSA_setup_blinding(rsa, ctx); - } - - ret = rsa->blinding; - if (ret == NULL) - goto err; - - CRYPTO_THREADID_current(&cur); - if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) { - /* rsa->blinding is ours! */ - - *local = 1; - } else { - /* resort to rsa->mt_blinding instead */ - - /* - * instructs rsa_blinding_convert(), rsa_blinding_invert() that the - * BN_BLINDING is shared, meaning that accesses require locks, and - * that the blinding factor must be stored outside the BN_BLINDING - */ - *local = 0; - - if (rsa->mt_blinding == NULL) { - if (!got_write_lock) { - CRYPTO_r_unlock(CRYPTO_LOCK_RSA); - CRYPTO_w_lock(CRYPTO_LOCK_RSA); - got_write_lock = 1; - } - - if (rsa->mt_blinding == NULL) - rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); - } - ret = rsa->mt_blinding; - } - - err: - if (got_write_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_RSA); - else - CRYPTO_r_unlock(CRYPTO_LOCK_RSA); - return ret; -} - -static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, - BN_CTX *ctx) -{ - if (unblind == NULL) - /* - * Local blinding: store the unblinding factor in BN_BLINDING. - */ - return BN_BLINDING_convert_ex(f, NULL, b, ctx); - else { - /* - * Shared blinding: store the unblinding factor outside BN_BLINDING. - */ - int ret; - CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); - ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); - CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); - return ret; - } -} - -static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, - BN_CTX *ctx) -{ - /* - * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex - * will use the unblinding factor stored in BN_BLINDING. If BN_BLINDING - * is shared between threads, unblind must be non-null: - * BN_BLINDING_invert_ex will then use the local unblinding factor, and - * will only read the modulus from BN_BLINDING. In both cases it's safe - * to access the blinding without a lock. - */ - return BN_BLINDING_invert_ex(f, unblind, b, ctx); -} - -/* signing */ -static int RSA_eay_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - BIGNUM *f, *ret, *res; - int i, num = 0, r = -1; - unsigned char *buf = NULL; - BN_CTX *ctx = NULL; - int local_blinding = 0; - /* - * Used only if the blinding structure is shared. A non-NULL unblind - * instructs rsa_blinding_convert() and rsa_blinding_invert() to store - * the unblinding factor outside the blinding structure. - */ - BIGNUM *unblind = NULL; - BN_BLINDING *blinding = NULL; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - ret = BN_CTX_get(ctx); - num = BN_num_bytes(rsa->n); - buf = OPENSSL_malloc(num); - if (!f || !ret || !buf) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - switch (padding) { - case RSA_PKCS1_PADDING: - i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); - break; - case RSA_X931_PADDING: - i = RSA_padding_add_X931(buf, num, from, flen); - break; - case RSA_NO_PADDING: - i = RSA_padding_add_none(buf, num, from, flen); - break; - case RSA_SSLV23_PADDING: - default: - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - if (i <= 0) - goto err; - - if (BN_bin2bn(buf, num, f) == NULL) - goto err; - - if (BN_ucmp(f, rsa->n) >= 0) { - /* usually the padding functions would catch this */ - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { - blinding = rsa_get_blinding(rsa, &local_blinding, ctx); - if (blinding == NULL) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - if (blinding != NULL) { - if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!rsa_blinding_convert(blinding, f, unblind, ctx)) - goto err; - } - - if ((rsa->flags & RSA_FLAG_EXT_PKEY) || - ((rsa->p != NULL) && - (rsa->q != NULL) && - (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { - if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) - goto err; - } else { - BIGNUM local_d; - BIGNUM *d = NULL; - - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - BN_init(&local_d); - d = &local_d; - BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - } else - d = rsa->d; - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, - rsa->n, ctx)) - goto err; - - if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - } - - if (blinding) - if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) - goto err; - - if (padding == RSA_X931_PADDING) { - BN_sub(f, rsa->n, ret); - if (BN_cmp(ret, f) > 0) - res = f; - else - res = ret; - } else - res = ret; - - /* - * BN_bn2binpad puts in leading 0 bytes if the number is less than - * the length of the modulus. - */ - r = bn_bn2binpad(res, to, num); - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (buf != NULL) { - OPENSSL_cleanse(buf, num); - OPENSSL_free(buf); - } - return (r); -} - -static int RSA_eay_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - BIGNUM *f, *ret; - int j, num = 0, r = -1; - unsigned char *buf = NULL; - BN_CTX *ctx = NULL; - int local_blinding = 0; - /* - * Used only if the blinding structure is shared. A non-NULL unblind - * instructs rsa_blinding_convert() and rsa_blinding_invert() to store - * the unblinding factor outside the blinding structure. - */ - BIGNUM *unblind = NULL; - BN_BLINDING *blinding = NULL; - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - ret = BN_CTX_get(ctx); - num = BN_num_bytes(rsa->n); - buf = OPENSSL_malloc(num); - if (!f || !ret || !buf) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * This check was for equality but PGP does evil things and chops off the - * top '0' bytes - */ - if (flen > num) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, - RSA_R_DATA_GREATER_THAN_MOD_LEN); - goto err; - } - - /* make data into a big number */ - if (BN_bin2bn(from, (int)flen, f) == NULL) - goto err; - - if (BN_ucmp(f, rsa->n) >= 0) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { - blinding = rsa_get_blinding(rsa, &local_blinding, ctx); - if (blinding == NULL) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - if (blinding != NULL) { - if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { - RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!rsa_blinding_convert(blinding, f, unblind, ctx)) - goto err; - } - - /* do the decrypt */ - if ((rsa->flags & RSA_FLAG_EXT_PKEY) || - ((rsa->p != NULL) && - (rsa->q != NULL) && - (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { - if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) - goto err; - } else { - BIGNUM local_d; - BIGNUM *d = NULL; - - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - d = &local_d; - BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - } else - d = rsa->d; - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, - rsa->n, ctx)) - goto err; - if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - } - - if (blinding) - if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) - goto err; - - j = bn_bn2binpad(ret, buf, num); - - switch (padding) { - case RSA_PKCS1_PADDING: - r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); - break; -# ifndef OPENSSL_NO_SHA - case RSA_PKCS1_OAEP_PADDING: - r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); - break; -# endif - case RSA_SSLV23_PADDING: - r = RSA_padding_check_SSLv23(to, num, buf, j, num); - break; - case RSA_NO_PADDING: - memcpy(to, buf, (r = j)); - break; - default: - RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - if (r < 0) - RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); - - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (buf != NULL) { - OPENSSL_cleanse(buf, num); - OPENSSL_free(buf); - } - return (r); -} - -/* signature verification */ -static int RSA_eay_public_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - BIGNUM *f, *ret; - int i, num = 0, r = -1; - unsigned char *buf = NULL; - BN_CTX *ctx = NULL; - - if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); - return -1; - } - - if (BN_ucmp(rsa->n, rsa->e) <= 0) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); - return -1; - } - - /* for large moduli, enforce exponent limit */ - if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { - if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); - return -1; - } - } - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - BN_CTX_start(ctx); - f = BN_CTX_get(ctx); - ret = BN_CTX_get(ctx); - num = BN_num_bytes(rsa->n); - buf = OPENSSL_malloc(num); - if (!f || !ret || !buf) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * This check was for equality but PGP does evil things and chops off the - * top '0' bytes - */ - if (flen > num) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); - goto err; - } - - if (BN_bin2bn(from, flen, f) == NULL) - goto err; - - if (BN_ucmp(f, rsa->n) >= 0) { - RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, - RSA_R_DATA_TOO_LARGE_FOR_MODULUS); - goto err; - } - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, - rsa->n, ctx)) - goto err; - - if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - - if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12)) - if (!BN_sub(ret, rsa->n, ret)) - goto err; - - i = bn_bn2binpad(ret, buf, num); - - switch (padding) { - case RSA_PKCS1_PADDING: - r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num); - break; - case RSA_X931_PADDING: - r = RSA_padding_check_X931(to, num, buf, i, num); - break; - case RSA_NO_PADDING: - memcpy(to, buf, (r = i)); - break; - default: - RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); - goto err; - } - if (r < 0) - RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED); - - err: - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - if (buf != NULL) { - OPENSSL_cleanse(buf, num); - OPENSSL_free(buf); - } - return (r); -} - -static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) -{ - BIGNUM *r1, *m1, *vrfy; - BIGNUM local_dmp1, local_dmq1, local_c, local_r1; - BIGNUM *dmp1, *dmq1, *c, *pr1; - int ret = 0, smooth = 0; - - BN_CTX_start(ctx); - r1 = BN_CTX_get(ctx); - m1 = BN_CTX_get(ctx); - vrfy = BN_CTX_get(ctx); - - { - BIGNUM local_p, local_q; - BIGNUM *p = NULL, *q = NULL; - - /* - * Make sure BN_mod_inverse in Montgomery intialization uses the - * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) - */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - BN_init(&local_p); - p = &local_p; - BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); - - BN_init(&local_q); - q = &local_q; - BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME); - } else { - p = rsa->p; - q = rsa->q; - } - - if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_p, CRYPTO_LOCK_RSA, - p, ctx)) - goto err; - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_q, CRYPTO_LOCK_RSA, - q, ctx)) - goto err; - - smooth = (rsa->meth->bn_mod_exp == BN_mod_exp_mont) - && (BN_num_bits(q) == BN_num_bits(p)); - } - } - - if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) - if (!BN_MONT_CTX_set_locked(&rsa->_method_mod_n, CRYPTO_LOCK_RSA, - rsa->n, ctx)) - goto err; - - if (smooth) { - /* - * Conversion from Montgomery domain, a.k.a. Montgomery reduction, - * accepts values in [0-m*2^w) range. w is m's bit width rounded up - * to limb width. So that at the very least if |I| is fully reduced, - * i.e. less than p*q, we can count on from-to round to perform - * below modulo operations on |I|. Unlike BN_mod it's constant time. - */ - if (/* m1 = I moq q */ - !bn_from_mont_fixed_top(m1, I, rsa->_method_mod_q, ctx) - || !bn_to_mont_fixed_top(m1, m1, rsa->_method_mod_q, ctx) - /* m1 = m1^dmq1 mod q */ - || !BN_mod_exp_mont_consttime(m1, m1, rsa->dmq1, rsa->q, ctx, - rsa->_method_mod_q) - /* r1 = I mod p */ - || !bn_from_mont_fixed_top(r1, I, rsa->_method_mod_p, ctx) - || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) - /* r1 = r1^dmp1 mod p */ - || !BN_mod_exp_mont_consttime(r1, r1, rsa->dmp1, rsa->p, ctx, - rsa->_method_mod_p) - /* r1 = (r1 - m1) mod p */ - /* - * bn_mod_sub_fixed_top is not regular modular subtraction, - * it can tolerate subtrahend to be larger than modulus, but - * not bit-wise wider. This makes up for uncommon q>p case, - * when |m1| can be larger than |rsa->p|. - */ - || !bn_mod_sub_fixed_top(r1, r1, m1, rsa->p) - - /* r1 = r1 * iqmp mod p */ - || !bn_to_mont_fixed_top(r1, r1, rsa->_method_mod_p, ctx) - || !bn_mul_mont_fixed_top(r1, r1, rsa->iqmp, rsa->_method_mod_p, - ctx) - /* r0 = r1 * q + m1 */ - || !bn_mul_fixed_top(r0, r1, rsa->q, ctx) - || !bn_mod_add_fixed_top(r0, r0, m1, rsa->n)) - goto err; - - goto tail; - } - - /* compute I mod q */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - c = &local_c; - BN_with_flags(c, I, BN_FLG_CONSTTIME); - if (!BN_mod(r1, c, rsa->q, ctx)) - goto err; - } else { - if (!BN_mod(r1, I, rsa->q, ctx)) - goto err; - } - - /* compute r1^dmq1 mod q */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - dmq1 = &local_dmq1; - BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); - } else - dmq1 = rsa->dmq1; - if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) - goto err; - - /* compute I mod p */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - c = &local_c; - BN_with_flags(c, I, BN_FLG_CONSTTIME); - if (!BN_mod(r1, c, rsa->p, ctx)) - goto err; - } else { - if (!BN_mod(r1, I, rsa->p, ctx)) - goto err; - } - - /* compute r1^dmp1 mod p */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - dmp1 = &local_dmp1; - BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); - } else - dmp1 = rsa->dmp1; - if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) - goto err; - - if (!BN_sub(r0, r0, m1)) - goto err; - /* - * This will help stop the size of r0 increasing, which does affect the - * multiply if it optimised for a power of 2 size - */ - if (BN_is_negative(r0)) - if (!BN_add(r0, r0, rsa->p)) - goto err; - - if (!BN_mul(r1, r0, rsa->iqmp, ctx)) - goto err; - - /* Turn BN_FLG_CONSTTIME flag on before division operation */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - pr1 = &local_r1; - BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); - } else - pr1 = r1; - if (!BN_mod(r0, pr1, rsa->p, ctx)) - goto err; - - /* - * If p < q it is occasionally possible for the correction of adding 'p' - * if r0 is negative above to leave the result still negative. This can - * break the private key operations: the following second correction - * should *always* correct this rare occurrence. This will *never* happen - * with OpenSSL generated keys because they ensure p > q [steve] - */ - if (BN_is_negative(r0)) - if (!BN_add(r0, r0, rsa->p)) - goto err; - if (!BN_mul(r1, r0, rsa->q, ctx)) - goto err; - if (!BN_add(r0, r1, m1)) - goto err; - - tail: - if (rsa->e && rsa->n) { - if (rsa->meth->bn_mod_exp == BN_mod_exp_mont) { - if (!BN_mod_exp_mont(vrfy, r0, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - } else { - bn_correct_top(r0); - if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - } - /* - * If 'I' was greater than (or equal to) rsa->n, the operation will - * be equivalent to using 'I mod n'. However, the result of the - * verify will *always* be less than 'n' so we don't check for - * absolute equality, just congruency. - */ - if (!BN_sub(vrfy, vrfy, I)) - goto err; - if (BN_is_zero(vrfy)) { - bn_correct_top(r0); - ret = 1; - goto err; /* not actually error */ - } - if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) - goto err; - if (BN_is_negative(vrfy)) - if (!BN_add(vrfy, vrfy, rsa->n)) - goto err; - if (!BN_is_zero(vrfy)) { - /* - * 'I' and 'vrfy' aren't congruent mod n. Don't leak - * miscalculated CRT output, just do a raw (slower) mod_exp and - * return that instead. - */ - - BIGNUM local_d; - BIGNUM *d = NULL; - - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - d = &local_d; - BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - } else - d = rsa->d; - if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, - rsa->_method_mod_n)) - goto err; - } - } - /* - * It's unfortunate that we have to bn_correct_top(r0). What hopefully - * saves the day is that correction is highly unlike, and private key - * operations are customarily performed on blinded message. Which means - * that attacker won't observe correlation with chosen plaintext. - * Secondly, remaining code would still handle it in same computational - * time and even conceal memory access pattern around corrected top. - */ - bn_correct_top(r0); - ret = 1; - err: - BN_CTX_end(ctx); - return (ret); -} - -static int RSA_eay_init(RSA *rsa) -{ - rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE; - return (1); -} - -static int RSA_eay_finish(RSA *rsa) -{ - if (rsa->_method_mod_n != NULL) - BN_MONT_CTX_free(rsa->_method_mod_n); - if (rsa->_method_mod_p != NULL) - BN_MONT_CTX_free(rsa->_method_mod_p); - if (rsa->_method_mod_q != NULL) - BN_MONT_CTX_free(rsa->_method_mod_q); - return (1); -} - -#endif -/* crypto/rsa/rsa_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -// #include "err.h" -// #include "rsa.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason) - -static ERR_STRING_DATA RSA_str_functs[] = { - {ERR_FUNC(RSA_F_CHECK_PADDING_MD), "CHECK_PADDING_MD"}, - {ERR_FUNC(RSA_F_DO_RSA_PRINT), "DO_RSA_PRINT"}, - {ERR_FUNC(RSA_F_INT_RSA_VERIFY), "INT_RSA_VERIFY"}, - {ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"}, - {ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "OLD_RSA_PRIV_DECODE"}, - {ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"}, - {ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"}, - {ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"}, - {ERR_FUNC(RSA_F_PKEY_RSA_VERIFY), "PKEY_RSA_VERIFY"}, - {ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"}, - {ERR_FUNC(RSA_F_RSA_ALGOR_TO_MD), "RSA_ALGOR_TO_MD"}, - {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, - {ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"}, - {ERR_FUNC(RSA_F_RSA_CMS_DECRYPT), "RSA_CMS_DECRYPT"}, - {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, - {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"}, - {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"}, - {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"}, - {ERR_FUNC(RSA_F_RSA_GENERATE_KEY), "RSA_generate_key"}, - {ERR_FUNC(RSA_F_RSA_GENERATE_KEY_EX), "RSA_generate_key_ex"}, - {ERR_FUNC(RSA_F_RSA_ITEM_VERIFY), "RSA_ITEM_VERIFY"}, - {ERR_FUNC(RSA_F_RSA_MEMORY_LOCK), "RSA_memory_lock"}, - {ERR_FUNC(RSA_F_RSA_MGF1_TO_MD), "RSA_MGF1_TO_MD"}, - {ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"}, - {ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"}, - {ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP), "RSA_NULL_MOD_EXP"}, - {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_NULL_PRIVATE_DECRYPT"}, - {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_NULL_PRIVATE_ENCRYPT"}, - {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_NULL_PUBLIC_DECRYPT"}, - {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_NULL_PUBLIC_ENCRYPT"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP), - "RSA_padding_add_PKCS1_OAEP"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1), - "RSA_padding_add_PKCS1_OAEP_mgf1"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1), - "RSA_padding_add_PKCS1_PSS_mgf1"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1), - "RSA_padding_add_PKCS1_type_1"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2), - "RSA_padding_add_PKCS1_type_2"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"}, - {ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"}, - {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE), "RSA_padding_check_none"}, - {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP), - "RSA_padding_check_PKCS1_OAEP"}, - {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1), - "RSA_padding_check_PKCS1_OAEP_mgf1"}, - {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1), - "RSA_padding_check_PKCS1_type_1"}, - {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2), - "RSA_padding_check_PKCS1_type_2"}, - {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"}, - {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"}, - {ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"}, - {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"}, - {ERR_FUNC(RSA_F_RSA_PRIVATE_DECRYPT), "RSA_private_decrypt"}, - {ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"}, - {ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"}, - {ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"}, - {ERR_FUNC(RSA_F_RSA_PSS_TO_CTX), "RSA_PSS_TO_CTX"}, - {ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"}, - {ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"}, - {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"}, - {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, - {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, - {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), - "RSA_sign_ASN1_OCTET_STRING"}, - {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, - {ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING), - "RSA_verify_ASN1_OCTET_STRING"}, - {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_verify_PKCS1_PSS"}, - {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1), "RSA_verify_PKCS1_PSS_mgf1"}, - {0, NULL} -}; - -static ERR_STRING_DATA RSA_str_reasons[] = { - {ERR_REASON(RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"}, - {ERR_REASON(RSA_R_BAD_E_VALUE), "bad e value"}, - {ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT), "bad fixed header decrypt"}, - {ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count"}, - {ERR_REASON(RSA_R_BAD_SIGNATURE), "bad signature"}, - {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01), "block type is not 01"}, - {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02), "block type is not 02"}, - {ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN), - "data greater than mod len"}, - {ERR_REASON(RSA_R_DATA_TOO_LARGE), "data too large"}, - {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), - "data too large for key size"}, - {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS), - "data too large for modulus"}, - {ERR_REASON(RSA_R_DATA_TOO_SMALL), "data too small"}, - {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), - "data too small for key size"}, - {ERR_REASON(RSA_R_DIGEST_DOES_NOT_MATCH), "digest does not match"}, - {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), - "digest too big for rsa key"}, - {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"}, - {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D), "dmq1 not congruent to d"}, - {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1), "d e not congruent to 1"}, - {ERR_REASON(RSA_R_FIRST_OCTET_INVALID), "first octet invalid"}, - {ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), - "illegal or unsupported padding mode"}, - {ERR_REASON(RSA_R_INVALID_DIGEST), "invalid digest"}, - {ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, - {ERR_REASON(RSA_R_INVALID_HEADER), "invalid header"}, - {ERR_REASON(RSA_R_INVALID_KEYBITS), "invalid keybits"}, - {ERR_REASON(RSA_R_INVALID_LABEL), "invalid label"}, - {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"}, - {ERR_REASON(RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"}, - {ERR_REASON(RSA_R_INVALID_OAEP_PARAMETERS), "invalid oaep parameters"}, - {ERR_REASON(RSA_R_INVALID_PADDING), "invalid padding"}, - {ERR_REASON(RSA_R_INVALID_PADDING_MODE), "invalid padding mode"}, - {ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS), "invalid pss parameters"}, - {ERR_REASON(RSA_R_INVALID_PSS_SALTLEN), "invalid pss saltlen"}, - {ERR_REASON(RSA_R_INVALID_SALT_LENGTH), "invalid salt length"}, - {ERR_REASON(RSA_R_INVALID_TRAILER), "invalid trailer"}, - {ERR_REASON(RSA_R_INVALID_X931_DIGEST), "invalid x931 digest"}, - {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q), "iqmp not inverse of q"}, - {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL), "key size too small"}, - {ERR_REASON(RSA_R_LAST_OCTET_INVALID), "last octet invalid"}, - {ERR_REASON(RSA_R_MODULUS_TOO_LARGE), "modulus too large"}, - {ERR_REASON(RSA_R_NON_FIPS_RSA_METHOD), "non fips rsa method"}, - {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"}, - {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING), - "null before block missing"}, - {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q), "n does not equal p q"}, - {ERR_REASON(RSA_R_OAEP_DECODING_ERROR), "oaep decoding error"}, - {ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE), - "operation not allowed in fips mode"}, - {ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), - "operation not supported for this keytype"}, - {ERR_REASON(RSA_R_PADDING_CHECK_FAILED), "padding check failed"}, - {ERR_REASON(RSA_R_PKCS_DECODING_ERROR), "pkcs decoding error"}, - {ERR_REASON(RSA_R_P_NOT_PRIME), "p not prime"}, - {ERR_REASON(RSA_R_Q_NOT_PRIME), "q not prime"}, - {ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), - "rsa operations not supported"}, - {ERR_REASON(RSA_R_SLEN_CHECK_FAILED), "salt length check failed"}, - {ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED), "salt length recovery failed"}, - {ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK), "sslv3 rollback attack"}, - {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), - "the asn1 object identifier is not known for this md"}, - {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"}, - {ERR_REASON(RSA_R_UNKNOWN_DIGEST), "unknown digest"}, - {ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST), "unknown mask digest"}, - {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE), "unknown padding type"}, - {ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST), "unknown pss digest"}, - {ERR_REASON(RSA_R_UNSUPPORTED_ENCRYPTION_TYPE), - "unsupported encryption type"}, - {ERR_REASON(RSA_R_UNSUPPORTED_LABEL_SOURCE), "unsupported label source"}, - {ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM), - "unsupported mask algorithm"}, - {ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER), - "unsupported mask parameter"}, - {ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE), - "unsupported signature type"}, - {ERR_REASON(RSA_R_VALUE_MISSING), "value missing"}, - {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, - {0, NULL} -}; - -#endif - -void ERR_load_RSA_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) { - ERR_load_strings(0, RSA_str_functs); - ERR_load_strings(0, RSA_str_reasons); - } -#endif -} -/* crypto/rsa/rsa_gen.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/* - * NB: these functions have been "upgraded", the deprecated versions (which - * are compatibility wrappers using these functions) are in rsa_depr.c. - - * Geoff - */ - -#include -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -#ifdef OPENSSL_FIPS -# include -extern int FIPS_rsa_x931_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, - BN_GENCB *cb); -#endif - -static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, - BN_GENCB *cb); - -/* - * NB: this wrapper would normally be placed in rsa_lib.c and the static - * implementation would probably be in rsa_eay.c. Nonetheless, is kept here - * so that we don't introduce a new linker dependency. Eg. any application - * that wasn't previously linking object code related to key-generation won't - * have to now just because key-generation is part of RSA_METHOD. - */ -int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD); - return 0; - } -#endif - if (rsa->meth->rsa_keygen) - return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_rsa_x931_generate_key_ex(rsa, bits, e_value, cb); -#endif - return rsa_builtin_keygen(rsa, bits, e_value, cb); -} - -static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, - BN_GENCB *cb) -{ - BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; - BIGNUM local_r0, local_d, local_p; - BIGNUM *pr0, *d, *p; - int bitsp, bitsq, ok = -1, n = 0; - BN_CTX *ctx = NULL; - unsigned long error = 0; - - /* - * When generating ridiculously small keys, we can get stuck - * continually regenerating the same prime values. - */ - if (bits < 16) { - ok = 0; /* we set our own err */ - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); - goto err; - } - - ctx = BN_CTX_new(); - if (ctx == NULL) - goto err; - BN_CTX_start(ctx); - r0 = BN_CTX_get(ctx); - r1 = BN_CTX_get(ctx); - r2 = BN_CTX_get(ctx); - r3 = BN_CTX_get(ctx); - if (r3 == NULL) - goto err; - - bitsp = (bits + 1) / 2; - bitsq = bits - bitsp; - - /* We need the RSA components non-NULL */ - if (!rsa->n && ((rsa->n = BN_new()) == NULL)) - goto err; - if (!rsa->d && ((rsa->d = BN_new()) == NULL)) - goto err; - if (!rsa->e && ((rsa->e = BN_new()) == NULL)) - goto err; - if (!rsa->p && ((rsa->p = BN_new()) == NULL)) - goto err; - if (!rsa->q && ((rsa->q = BN_new()) == NULL)) - goto err; - if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) - goto err; - if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) - goto err; - if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) - goto err; - - if (BN_copy(rsa->e, e_value) == NULL) - goto err; - - BN_set_flags(rsa->p, BN_FLG_CONSTTIME); - BN_set_flags(rsa->q, BN_FLG_CONSTTIME); - BN_set_flags(r2, BN_FLG_CONSTTIME); - /* generate p and q */ - for (;;) { - if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) - goto err; - if (!BN_sub(r2, rsa->p, BN_value_one())) - goto err; - ERR_set_mark(); - if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { - /* GCD == 1 since inverse exists */ - break; - } - error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_BN - && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { - /* GCD != 1 */ - ERR_pop_to_mark(); - } else { - goto err; - } - if (!BN_GENCB_call(cb, 2, n++)) - goto err; - } - if (!BN_GENCB_call(cb, 3, 0)) - goto err; - for (;;) { - do { - if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) - goto err; - } while (BN_cmp(rsa->p, rsa->q) == 0); - if (!BN_sub(r2, rsa->q, BN_value_one())) - goto err; - ERR_set_mark(); - if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) { - /* GCD == 1 since inverse exists */ - break; - } - error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_BN - && ERR_GET_REASON(error) == BN_R_NO_INVERSE) { - /* GCD != 1 */ - ERR_pop_to_mark(); - } else { - goto err; - } - if (!BN_GENCB_call(cb, 2, n++)) - goto err; - } - if (!BN_GENCB_call(cb, 3, 1)) - goto err; - if (BN_cmp(rsa->p, rsa->q) < 0) { - tmp = rsa->p; - rsa->p = rsa->q; - rsa->q = tmp; - } - - /* calculate n */ - if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) - goto err; - - /* calculate d */ - if (!BN_sub(r1, rsa->p, BN_value_one())) - goto err; /* p-1 */ - if (!BN_sub(r2, rsa->q, BN_value_one())) - goto err; /* q-1 */ - if (!BN_mul(r0, r1, r2, ctx)) - goto err; /* (p-1)(q-1) */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - pr0 = &local_r0; - BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); - } else - pr0 = r0; - if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) - goto err; /* d */ - - /* set up d for correct BN_FLG_CONSTTIME flag */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - d = &local_d; - BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); - } else - d = rsa->d; - - /* calculate d mod (p-1) */ - if (!BN_mod(rsa->dmp1, d, r1, ctx)) - goto err; - - /* calculate d mod (q-1) */ - if (!BN_mod(rsa->dmq1, d, r2, ctx)) - goto err; - - /* calculate inverse of q mod p */ - if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { - p = &local_p; - BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); - } else - p = rsa->p; - if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) - goto err; - - ok = 1; - err: - if (ok == -1) { - RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); - ok = 0; - } - if (ctx != NULL) { - BN_CTX_end(ctx); - BN_CTX_free(ctx); - } - - return ok; -} -/* crypto/rsa/rsa_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "crypto.h" -// #include "cryptlib.h" -// #include "lhash.h" -// #include "bn.h" -// #include "rsa.h" -// #include "rand.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -#ifdef OPENSSL_FIPS -# include -#endif - -const char RSA_version[] = "RSA" OPENSSL_VERSION_PTEXT; - -static const RSA_METHOD *default_RSA_meth = NULL; - -RSA *RSA_new(void) -{ - RSA *r = RSA_new_method(NULL); - - return r; -} - -void RSA_set_default_method(const RSA_METHOD *meth) -{ - default_RSA_meth = meth; -} - -const RSA_METHOD *RSA_get_default_method(void) -{ - if (default_RSA_meth == NULL) { -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return FIPS_rsa_pkcs1_ssleay(); - else - return RSA_PKCS1_SSLeay(); -#else -# ifdef RSA_NULL - default_RSA_meth = RSA_null_method(); -# else - default_RSA_meth = RSA_PKCS1_SSLeay(); -# endif -#endif - } - - return default_RSA_meth; -} - -const RSA_METHOD *RSA_get_method(const RSA *rsa) -{ - return rsa->meth; -} - -int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) -{ - /* - * NB: The caller is specifically setting a method, so it's not up to us - * to deal with which ENGINE it comes from. - */ - const RSA_METHOD *mtmp; - mtmp = rsa->meth; - if (mtmp->finish) - mtmp->finish(rsa); -#ifndef OPENSSL_NO_ENGINE - if (rsa->engine) { - ENGINE_finish(rsa->engine); - rsa->engine = NULL; - } -#endif - rsa->meth = meth; - if (meth->init) - meth->init(rsa); - return 1; -} - -RSA *RSA_new_method(ENGINE *engine) -{ - RSA *ret; - - ret = (RSA *)OPENSSL_malloc(sizeof(RSA)); - if (ret == NULL) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return NULL; - } - memset(ret,0,sizeof(RSA)); - - ret->meth = RSA_get_default_method(); -#ifndef OPENSSL_NO_ENGINE - if (engine) { - if (!ENGINE_init(engine)) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); - OPENSSL_free(ret); - return NULL; - } - ret->engine = engine; - } else - ret->engine = ENGINE_get_default_RSA(); - if (ret->engine) { - ret->meth = ENGINE_get_RSA(ret->engine); - if (!ret->meth) { - RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); - ENGINE_finish(ret->engine); - OPENSSL_free(ret); - return NULL; - } - } -#endif - - ret->pad = 0; - ret->version = 0; - ret->n = NULL; - ret->e = NULL; - ret->d = NULL; - ret->p = NULL; - ret->q = NULL; - ret->dmp1 = NULL; - ret->dmq1 = NULL; - ret->iqmp = NULL; - ret->references = 1; - ret->_method_mod_n = NULL; - ret->_method_mod_p = NULL; - ret->_method_mod_q = NULL; - ret->blinding = NULL; - ret->mt_blinding = NULL; - ret->bignum_data = NULL; - ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - OPENSSL_free(ret); - return (NULL); - } - - if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { -#ifndef OPENSSL_NO_ENGINE - if (ret->engine) - ENGINE_finish(ret->engine); -#endif - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); - OPENSSL_free(ret); - ret = NULL; - } - return (ret); -} - -void RSA_free(RSA *r) -{ - int i; - - if (r == NULL) - return; - - i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_RSA); -#ifdef REF_PRINT - REF_PRINT("RSA", r); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "RSA_free, bad reference count\n"); - abort(); - } -#endif - - if (r->meth->finish) - r->meth->finish(r); -#ifndef OPENSSL_NO_ENGINE - if (r->engine) - ENGINE_finish(r->engine); -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); - - if (r->n != NULL) - BN_clear_free(r->n); - if (r->e != NULL) - BN_clear_free(r->e); - if (r->d != NULL) - BN_clear_free(r->d); - if (r->p != NULL) - BN_clear_free(r->p); - if (r->q != NULL) - BN_clear_free(r->q); - if (r->dmp1 != NULL) - BN_clear_free(r->dmp1); - if (r->dmq1 != NULL) - BN_clear_free(r->dmq1); - if (r->iqmp != NULL) - BN_clear_free(r->iqmp); - if (r->blinding != NULL) - BN_BLINDING_free(r->blinding); - if (r->mt_blinding != NULL) - BN_BLINDING_free(r->mt_blinding); - if (r->bignum_data != NULL) - OPENSSL_free_locked(r->bignum_data); - OPENSSL_free(r); -} - -int RSA_up_ref(RSA *r) -{ - int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); -#ifdef REF_PRINT - REF_PRINT("RSA", r); -#endif -#ifdef REF_CHECK - if (i < 2) { - fprintf(stderr, "RSA_up_ref, bad reference count\n"); - abort(); - } -#endif - return ((i > 1) ? 1 : 0); -} - -int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, - new_func, dup_func, free_func); -} - -int RSA_set_ex_data(RSA *r, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); -} - -void *RSA_get_ex_data(const RSA *r, int idx) -{ - return (CRYPTO_get_ex_data(&r->ex_data, idx)); -} - -int RSA_memory_lock(RSA *r) -{ - int i, j, k, off; - char *p; - BIGNUM *bn, **t[6], *b; - BN_ULONG *ul; - - if (r->d == NULL) - return (1); - t[0] = &r->d; - t[1] = &r->p; - t[2] = &r->q; - t[3] = &r->dmp1; - t[4] = &r->dmq1; - t[5] = &r->iqmp; - k = sizeof(BIGNUM) * 6; - off = k / sizeof(BN_ULONG) + 1; - j = 1; - for (i = 0; i < 6; i++) - j += (*t[i])->top; - if ((p = OPENSSL_malloc_locked((off + j) * sizeof(BN_ULONG))) == NULL) { - RSAerr(RSA_F_RSA_MEMORY_LOCK, ERR_R_MALLOC_FAILURE); - return (0); - } - bn = (BIGNUM *)p; - ul = (BN_ULONG *)&(p[off]); - for (i = 0; i < 6; i++) { - b = *(t[i]); - *(t[i]) = &(bn[i]); - memcpy((char *)&(bn[i]), (char *)b, sizeof(BIGNUM)); - bn[i].flags = BN_FLG_STATIC_DATA; - bn[i].d = ul; - memcpy((char *)ul, b->d, sizeof(BN_ULONG) * b->top); - ul += b->top; - BN_clear_free(b); - } - - /* I should fix this so it can still be done */ - r->flags &= ~(RSA_FLAG_CACHE_PRIVATE | RSA_FLAG_CACHE_PUBLIC); - - r->bignum_data = p; - return (1); -} -/* crypto/rsa/rsa_none.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "rand.h" - -int RSA_padding_add_none(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - if (flen > tlen) { - RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return (0); - } - - if (flen < tlen) { - RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); - return (0); - } - - memcpy(to, from, (unsigned int)flen); - return (1); -} - -int RSA_padding_check_none(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num) -{ - - if (flen > tlen) { - RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE); - return (-1); - } - - memset(to, 0, tlen - flen); - memcpy(to + tlen - flen, from, flen); - return (tlen); -} -/* rsa_null.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "rand.h" - -/* - * This is a dummy RSA implementation that just returns errors when called. - * It is designed to allow some RSA functions to work while stopping those - * covered by the RSA patent. That is RSA, encryption, decryption, signing - * and verify is not allowed but RSA key generation, key checking and other - * operations (like storing RSA keys) are permitted. - */ - -static int RSA_null_public_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int RSA_null_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int RSA_null_public_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -static int RSA_null_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding); -#if 0 /* not currently used */ -static int RSA_null_mod_exp(const BIGNUM *r0, const BIGNUM *i, RSA *rsa); -#endif -static int RSA_null_init(RSA *rsa); -static int RSA_null_finish(RSA *rsa); -static RSA_METHOD rsa_null_meth = { - "Null RSA", - RSA_null_public_encrypt, - RSA_null_public_decrypt, - RSA_null_private_encrypt, - RSA_null_private_decrypt, - NULL, - NULL, - RSA_null_init, - RSA_null_finish, - 0, - NULL, - NULL, - NULL, - NULL -}; - -const RSA_METHOD *RSA_null_method(void) -{ - return (&rsa_null_meth); -} - -static int RSA_null_public_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); - return -1; -} - -static int RSA_null_private_encrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT, - RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); - return -1; -} - -static int RSA_null_private_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT, - RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); - return -1; -} - -static int RSA_null_public_decrypt(int flen, const unsigned char *from, - unsigned char *to, RSA *rsa, int padding) -{ - RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); - return -1; -} - -#if 0 /* not currently used */ -static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) -{ - ... err(RSA_F_RSA_NULL_MOD_EXP, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); - return -1; -} -#endif - -static int RSA_null_init(RSA *rsa) -{ - return (1); -} - -static int RSA_null_finish(RSA *rsa) -{ - return (1); -} -/* crypto/rsa/rsa_oaep.c */ -/* - * Written by Ulf Moeller. This software is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. - */ - -/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ - -/* - * See Victor Shoup, "OAEP reconsidered," Nov. 2000, for problems with the security - * proof for the original OAEP scheme, which EME-OAEP is based on. A new - * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern, - * "RSA-OEAP is Still Alive!", Dec. 2000, . The new proof has stronger requirements - * for the underlying permutation: "partial-one-wayness" instead of - * one-wayness. For the RSA function, this is an equivalent notion. - */ - -#include "constant_time_locl.h" - -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) -# include -# include "cryptlib.h" -# include "bn.h" -# include "rsa.h" -# include "evp.h" -# include "rand.h" -# include "sha.h" - -int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, - const unsigned char *from, int flen, - const unsigned char *param, int plen) -{ - return RSA_padding_add_PKCS1_OAEP_mgf1(to, tlen, from, flen, - param, plen, NULL, NULL); -} - -int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - const unsigned char *param, int plen, - const EVP_MD *md, const EVP_MD *mgf1md) -{ - int i, emlen = tlen - 1; - unsigned char *db, *seed; - unsigned char *dbmask, seedmask[EVP_MAX_MD_SIZE]; - int mdlen; - - if (md == NULL) - md = EVP_sha1(); - if (mgf1md == NULL) - mgf1md = md; - - mdlen = EVP_MD_size(md); - - if (flen > emlen - 2 * mdlen - 1) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return 0; - } - - if (emlen < 2 * mdlen + 1) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, - RSA_R_KEY_SIZE_TOO_SMALL); - return 0; - } - - to[0] = 0; - seed = to + 1; - db = to + mdlen + 1; - - if (!EVP_Digest((void *)param, plen, db, NULL, md, NULL)) - return 0; - memset(db + mdlen, 0, emlen - flen - 2 * mdlen - 1); - db[emlen - flen - mdlen - 1] = 0x01; - memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen); - if (RAND_bytes(seed, mdlen) <= 0) - return 0; -# ifdef PKCS_TESTVECT - memcpy(seed, - "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f", - 20); -# endif - - dbmask = OPENSSL_malloc(emlen - mdlen); - if (dbmask == NULL) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0) - goto err; - for (i = 0; i < emlen - mdlen; i++) - db[i] ^= dbmask[i]; - - if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0) - goto err; - for (i = 0; i < mdlen; i++) - seed[i] ^= seedmask[i]; - - OPENSSL_free(dbmask); - return 1; - - err: - OPENSSL_free(dbmask); - return 0; -} - -int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num, - const unsigned char *param, int plen) -{ - return RSA_padding_check_PKCS1_OAEP_mgf1(to, tlen, from, flen, num, - param, plen, NULL, NULL); -} - -int RSA_padding_check_PKCS1_OAEP_mgf1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - int num, const unsigned char *param, - int plen, const EVP_MD *md, - const EVP_MD *mgf1md) -{ - int i, dblen = 0, mlen = -1, one_index = 0, msg_index; - unsigned int good, found_one_byte; - const unsigned char *maskedseed, *maskeddb; - /* - * |em| is the encoded message, zero-padded to exactly |num| bytes: em = - * Y || maskedSeed || maskedDB - */ - unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE], - phash[EVP_MAX_MD_SIZE]; - int mdlen; - - if (md == NULL) - md = EVP_sha1(); - if (mgf1md == NULL) - mgf1md = md; - - mdlen = EVP_MD_size(md); - - if (tlen <= 0 || flen <= 0) - return -1; - /* - * |num| is the length of the modulus; |flen| is the length of the - * encoded message. Therefore, for any |from| that was obtained by - * decrypting a ciphertext, we must have |flen| <= |num|. Similarly, - * num < 2 * mdlen + 2 must hold for the modulus irrespective of - * the ciphertext, see PKCS #1 v2.2, section 7.1.2. - * This does not leak any side-channel information. - */ - if (num < flen || num < 2 * mdlen + 2) - goto decoding_err; - - dblen = num - mdlen - 1; - db = OPENSSL_malloc(dblen); - if (db == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, ERR_R_MALLOC_FAILURE); - goto cleanup; - } - - if (flen != num) { - em = OPENSSL_malloc(num); - if (em == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, - ERR_R_MALLOC_FAILURE); - goto cleanup; - } - - /* - * Caller is encouraged to pass zero-padded message created with - * BN_bn2binpad, but if it doesn't, we do this zero-padding copy - * to avoid leaking that information. The copy still leaks some - * side-channel information, but it's impossible to have a fixed - * memory access pattern since we can't read out of the bounds of - * |from|. - */ - memset(em, 0, num); - memcpy(em + num - flen, from, flen); - from = em; - } - - /* - * The first byte must be zero, however we must not leak if this is - * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA - * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001). - */ - good = constant_time_is_zero(from[0]); - - maskedseed = from + 1; - maskeddb = from + 1 + mdlen; - - if (PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) - goto cleanup; - for (i = 0; i < mdlen; i++) - seed[i] ^= maskedseed[i]; - - if (PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) - goto cleanup; - for (i = 0; i < dblen; i++) - db[i] ^= maskeddb[i]; - - if (!EVP_Digest((void *)param, plen, phash, NULL, md, NULL)) - goto cleanup; - - good &= constant_time_is_zero(CRYPTO_memcmp(db, phash, mdlen)); - - found_one_byte = 0; - for (i = mdlen; i < dblen; i++) { - /* - * Padding consists of a number of 0-bytes, followed by a 1. - */ - unsigned int equals1 = constant_time_eq(db[i], 1); - unsigned int equals0 = constant_time_is_zero(db[i]); - one_index = constant_time_select_int(~found_one_byte & equals1, - i, one_index); - found_one_byte |= equals1; - good &= (found_one_byte | equals0); - } - - good &= found_one_byte; - - /* - * At this point |good| is zero unless the plaintext was valid, - * so plaintext-awareness ensures timing side-channels are no longer a - * concern. - */ - if (!good) - goto decoding_err; - - msg_index = one_index + 1; - mlen = dblen - msg_index; - - if (tlen < mlen) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, RSA_R_DATA_TOO_LARGE); - mlen = -1; - } else { - memcpy(to, db + msg_index, mlen); - goto cleanup; - } - - decoding_err: - /* - * To avoid chosen ciphertext attacks, the error message should not - * reveal which kind of decoding error happened. - */ - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP_MGF1, - RSA_R_OAEP_DECODING_ERROR); - cleanup: - if (db != NULL) { - OPENSSL_cleanse(db, dblen); - OPENSSL_free(db); - } - if (em != NULL) { - OPENSSL_cleanse(em, num); - OPENSSL_free(em); - } - return mlen; -} - -int PKCS1_MGF1(unsigned char *mask, long len, - const unsigned char *seed, long seedlen, const EVP_MD *dgst) -{ - long i, outlen = 0; - unsigned char cnt[4]; - EVP_MD_CTX c; - unsigned char md[EVP_MAX_MD_SIZE]; - int mdlen; - int rv = -1; - - EVP_MD_CTX_init(&c); - mdlen = EVP_MD_size(dgst); - if (mdlen < 0) - goto err; - for (i = 0; outlen < len; i++) { - cnt[0] = (unsigned char)((i >> 24) & 255); - cnt[1] = (unsigned char)((i >> 16) & 255); - cnt[2] = (unsigned char)((i >> 8)) & 255; - cnt[3] = (unsigned char)(i & 255); - if (!EVP_DigestInit_ex(&c, dgst, NULL) - || !EVP_DigestUpdate(&c, seed, seedlen) - || !EVP_DigestUpdate(&c, cnt, 4)) - goto err; - if (outlen + mdlen <= len) { - if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL)) - goto err; - outlen += mdlen; - } else { - if (!EVP_DigestFinal_ex(&c, md, NULL)) - goto err; - memcpy(mask + outlen, md, len - outlen); - outlen = len; - } - } - rv = 0; - err: - EVP_MD_CTX_cleanup(&c); - return rv; -} - -#endif -/* crypto/rsa/rsa_pk1.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "constant_time_locl.h" - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "rand.h" - -int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int j; - unsigned char *p; - - if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return (0); - } - - p = (unsigned char *)to; - - *(p++) = 0; - *(p++) = 1; /* Private Key BT (Block Type) */ - - /* pad out with 0xff data */ - j = tlen - 3 - flen; - memset(p, 0xff, j); - p += j; - *(p++) = '\0'; - memcpy(p, from, (unsigned int)flen); - return (1); -} - -int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, - const unsigned char *from, int flen, - int num) -{ - int i, j; - const unsigned char *p; - - p = from; - - /* - * The format is - * 00 || 01 || PS || 00 || D - * PS - padding string, at least 8 bytes of FF - * D - data. - */ - - if (num < 11) - return -1; - - /* Accept inputs with and without the leading 0-byte. */ - if (num == flen) { - if ((*p++) != 0x00) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_INVALID_PADDING); - return -1; - } - flen--; - } - - if ((num != (flen + 1)) || (*(p++) != 01)) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BLOCK_TYPE_IS_NOT_01); - return (-1); - } - - /* scan over padding data */ - j = flen - 1; /* one for type. */ - for (i = 0; i < j; i++) { - if (*p != 0xff) { /* should decrypt to 0xff */ - if (*p == 0) { - p++; - break; - } else { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BAD_FIXED_HEADER_DECRYPT); - return (-1); - } - } - p++; - } - - if (i == j) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_NULL_BEFORE_BLOCK_MISSING); - return (-1); - } - - if (i < 8) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, - RSA_R_BAD_PAD_BYTE_COUNT); - return (-1); - } - i++; /* Skip over the '\0' */ - j -= i; - if (j > tlen) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE); - return (-1); - } - memcpy(to, p, (unsigned int)j); - - return (j); -} - -int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int i, j; - unsigned char *p; - - if (flen > (tlen - 11)) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return (0); - } - - p = (unsigned char *)to; - - *(p++) = 0; - *(p++) = 2; /* Public Key BT (Block Type) */ - - /* pad out with non-zero random data */ - j = tlen - 3 - flen; - - if (RAND_bytes(p, j) <= 0) - return (0); - for (i = 0; i < j; i++) { - if (*p == '\0') - do { - if (RAND_bytes(p, 1) <= 0) - return (0); - } while (*p == '\0'); - p++; - } - - *(p++) = '\0'; - - memcpy(p, from, (unsigned int)flen); - return (1); -} - -int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, - const unsigned char *from, int flen, - int num) -{ - int i; - /* |em| is the encoded message, zero-padded to exactly |num| bytes */ - unsigned char *em = NULL; - unsigned int good, found_zero_byte; - int zero_index = 0, msg_index, mlen = -1; - - if (tlen < 0 || flen < 0) - return -1; - - /* - * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", - * section 7.2.2. - */ - - if (flen > num) - goto err; - - if (num < 11) - goto err; - - if (flen != num) { - em = OPENSSL_malloc(num); - if (em == NULL) { - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); - return -1; - } - /* - * Caller is encouraged to pass zero-padded message created with - * BN_bn2binpad, but if it doesn't, we do this zero-padding copy - * to avoid leaking that information. The copy still leaks some - * side-channel information, but it's impossible to have a fixed - * memory access pattern since we can't read out of the bounds of - * |from|. - */ - memset(em, 0, num); - memcpy(em + num - flen, from, flen); - from = em; - } - - good = constant_time_is_zero(from[0]); - good &= constant_time_eq(from[1], 2); - - found_zero_byte = 0; - for (i = 2; i < num; i++) { - unsigned int equals0 = constant_time_is_zero(from[i]); - zero_index = - constant_time_select_int(~found_zero_byte & equals0, i, - zero_index); - found_zero_byte |= equals0; - } - - /* - * PS must be at least 8 bytes long, and it starts two bytes into |from|. - * If we never found a 0-byte, then |zero_index| is 0 and the check - * also fails. - */ - good &= constant_time_ge((unsigned int)(zero_index), 2 + 8); - - /* - * Skip the zero byte. This is incorrect if we never found a zero-byte - * but in this case we also do not copy the message out. - */ - msg_index = zero_index + 1; - mlen = num - msg_index; - - /* - * For good measure, do this check in constant time as well; it could - * leak something if |tlen| was assuming valid padding. - */ - good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen)); - - /* - * We can't continue in constant-time because we need to copy the result - * and we cannot fake its length. This unavoidably leaks timing - * information at the API boundary. - */ - if (!good) { - mlen = -1; - goto err; - } - - memcpy(to, from + msg_index, mlen); - - err: - if (em != NULL) { - OPENSSL_cleanse(em, num); - OPENSSL_free(em); - } - if (mlen == -1) - RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, - RSA_R_PKCS_DECODING_ERROR); - return mlen; -} -/* crypto/rsa/rsa_pmeth.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" -// #include "rsa.h" -// #include "bn.h" -#include "evp.h" -#include "x509v3.h" -#ifndef OPENSSL_NO_CMS -# include "cms.h" -#endif -#ifdef OPENSSL_FIPS -# include -#endif -#include "evp_locl.h" -#include "rsa_locl.h" - -/* RSA pkey context structure */ - -typedef struct { - /* Key gen parameters */ - int nbits; - BIGNUM *pub_exp; - /* Keygen callback info */ - int gentmp[2]; - /* RSA padding mode */ - int pad_mode; - /* message digest */ - const EVP_MD *md; - /* message digest for MGF1 */ - const EVP_MD *mgf1md; - /* PSS salt length */ - int saltlen; - /* Temp buffer */ - unsigned char *tbuf; - /* OAEP label */ - unsigned char *oaep_label; - size_t oaep_labellen; -} RSA_PKEY_CTX; - -static int pkey_rsa_init(EVP_PKEY_CTX *ctx) -{ - RSA_PKEY_CTX *rctx; - rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); - if (!rctx) - return 0; - rctx->nbits = 1024; - rctx->pub_exp = NULL; - rctx->pad_mode = RSA_PKCS1_PADDING; - rctx->md = NULL; - rctx->mgf1md = NULL; - rctx->tbuf = NULL; - - rctx->saltlen = -2; - - rctx->oaep_label = NULL; - rctx->oaep_labellen = 0; - - ctx->data = rctx; - ctx->keygen_info = rctx->gentmp; - ctx->keygen_info_count = 2; - - return 1; -} - -static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) -{ - RSA_PKEY_CTX *dctx, *sctx; - if (!pkey_rsa_init(dst)) - return 0; - sctx = src->data; - dctx = dst->data; - dctx->nbits = sctx->nbits; - if (sctx->pub_exp) { - dctx->pub_exp = BN_dup(sctx->pub_exp); - if (!dctx->pub_exp) - return 0; - } - dctx->pad_mode = sctx->pad_mode; - dctx->md = sctx->md; - dctx->mgf1md = sctx->mgf1md; - if (sctx->oaep_label) { - if (dctx->oaep_label) - OPENSSL_free(dctx->oaep_label); - dctx->oaep_label = BUF_memdup(sctx->oaep_label, sctx->oaep_labellen); - if (!dctx->oaep_label) - return 0; - dctx->oaep_labellen = sctx->oaep_labellen; - } - return 1; -} - -static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) -{ - if (ctx->tbuf) - return 1; - ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); - if (!ctx->tbuf) - return 0; - return 1; -} - -static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) -{ - RSA_PKEY_CTX *rctx = ctx->data; - if (rctx) { - if (rctx->pub_exp) - BN_free(rctx->pub_exp); - if (rctx->tbuf) - OPENSSL_free(rctx->tbuf); - if (rctx->oaep_label) - OPENSSL_free(rctx->oaep_label); - OPENSSL_free(rctx); - } -} - -#ifdef OPENSSL_FIPS -/* - * FIP checker. Return value indicates status of context parameters: 1 : - * redirect to FIPS. 0 : don't redirect to FIPS. -1 : illegal operation in - * FIPS mode. - */ - -static int pkey_fips_check_rsa(const RSA *rsa, const EVP_MD **pmd, - const EVP_MD **pmgf1md) -{ - int rv = -1; - - if (!FIPS_mode()) - return 0; - if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) - rv = 0; - if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) - return -1; - if (*pmd != NULL) { - *pmd = FIPS_get_digestbynid(EVP_MD_type(*pmd)); - if (*pmd == NULL || !((*pmd)->flags & EVP_MD_FLAG_FIPS)) - return rv; - } - if (*pmgf1md != NULL) { - *pmgf1md = FIPS_get_digestbynid(EVP_MD_type(*pmgf1md)); - if (*pmgf1md == NULL || !((*pmgf1md)->flags & EVP_MD_FLAG_FIPS)) - return rv; - } - return 1; -} -#endif - -static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, - size_t *siglen, const unsigned char *tbs, - size_t tbslen) -{ - int ret; - RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; - const EVP_MD *md = rctx->md; - const EVP_MD *mgf1md = rctx->mgf1md; - -#ifdef OPENSSL_FIPS - ret = pkey_fips_check_rsa(rsa, &md, &mgf1md); - if (ret < 0) { - RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return -1; - } -#endif - - if (md != NULL) { - if (tbslen != (size_t)EVP_MD_size(md)) { - RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); - return -1; - } -#ifdef OPENSSL_FIPS - if (ret > 0) { - unsigned int slen; - ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, md, rctx->pad_mode, - rctx->saltlen, mgf1md, sig, &slen); - if (ret > 0) - *siglen = slen; - else - *siglen = 0; - return ret; - } -#endif - - if (EVP_MD_type(md) == NID_mdc2) { - unsigned int sltmp; - if (rctx->pad_mode != RSA_PKCS1_PADDING) - return -1; - ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, - rsa); - - if (ret <= 0) - return ret; - ret = sltmp; - } else if (rctx->pad_mode == RSA_X931_PADDING) { - if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { - RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL); - return -1; - } - if (!setup_tbuf(rctx, ctx)) { - RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE); - return -1; - } - memcpy(rctx->tbuf, tbs, tbslen); - rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(md)); - ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, - sig, rsa, RSA_X931_PADDING); - } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { - unsigned int sltmp; - ret = RSA_sign(EVP_MD_type(md), tbs, tbslen, sig, &sltmp, rsa); - if (ret <= 0) - return ret; - ret = sltmp; - } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { - if (!setup_tbuf(rctx, ctx)) - return -1; - if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, - md, mgf1md, rctx->saltlen)) - return -1; - ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, - sig, rsa, RSA_NO_PADDING); - } else - return -1; - } else - ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, - rctx->pad_mode); - if (ret < 0) - return ret; - *siglen = ret; - return 1; -} - -static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, - unsigned char *rout, size_t *routlen, - const unsigned char *sig, size_t siglen) -{ - int ret; - RSA_PKEY_CTX *rctx = ctx->data; - - if (rctx->md) { - if (rctx->pad_mode == RSA_X931_PADDING) { - if (!setup_tbuf(rctx, ctx)) - return -1; - ret = RSA_public_decrypt(siglen, sig, - rctx->tbuf, ctx->pkey->pkey.rsa, - RSA_X931_PADDING); - if (ret < 1) - return 0; - ret--; - if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_type(rctx->md))) { - RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, - RSA_R_ALGORITHM_MISMATCH); - return 0; - } - if (ret != EVP_MD_size(rctx->md)) { - RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, - RSA_R_INVALID_DIGEST_LENGTH); - return 0; - } - if (rout) - memcpy(rout, rctx->tbuf, ret); - } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { - size_t sltmp; - ret = int_rsa_verify(EVP_MD_type(rctx->md), - NULL, 0, rout, &sltmp, - sig, siglen, ctx->pkey->pkey.rsa); - if (ret <= 0) - return 0; - ret = sltmp; - } else - return -1; - } else - ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, - rctx->pad_mode); - if (ret < 0) - return ret; - *routlen = ret; - return 1; -} - -static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, - const unsigned char *sig, size_t siglen, - const unsigned char *tbs, size_t tbslen) -{ - RSA_PKEY_CTX *rctx = ctx->data; - RSA *rsa = ctx->pkey->pkey.rsa; - const EVP_MD *md = rctx->md; - const EVP_MD *mgf1md = rctx->mgf1md; - size_t rslen; - -#ifdef OPENSSL_FIPS - int rv = pkey_fips_check_rsa(rsa, &md, &mgf1md); - - if (rv < 0) { - RSAerr(RSA_F_PKEY_RSA_VERIFY, - RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); - return -1; - } -#endif - if (md != NULL) { -#ifdef OPENSSL_FIPS - if (rv > 0) { - return FIPS_rsa_verify_digest(rsa, tbs, tbslen, md, rctx->pad_mode, - rctx->saltlen, mgf1md, sig, siglen); - - } -#endif - if (rctx->pad_mode == RSA_PKCS1_PADDING) - return RSA_verify(EVP_MD_type(md), tbs, tbslen, - sig, siglen, rsa); - if (tbslen != (size_t)EVP_MD_size(md)) { - RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); - return -1; - } - if (rctx->pad_mode == RSA_X931_PADDING) { - if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0) - return 0; - } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { - int ret; - if (!setup_tbuf(rctx, ctx)) - return -1; - ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, - rsa, RSA_NO_PADDING); - if (ret <= 0) - return 0; - ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, md, mgf1md, - rctx->tbuf, rctx->saltlen); - if (ret <= 0) - return 0; - return 1; - } else - return -1; - } else { - if (!setup_tbuf(rctx, ctx)) - return -1; - rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, - rsa, rctx->pad_mode); - if (rslen == 0) - return 0; - } - - if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) - return 0; - - return 1; - -} - -static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - int ret; - RSA_PKEY_CTX *rctx = ctx->data; - if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { - int klen = RSA_size(ctx->pkey->pkey.rsa); - if (!setup_tbuf(rctx, ctx)) - return -1; - if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen, - in, inlen, - rctx->oaep_label, - rctx->oaep_labellen, - rctx->md, rctx->mgf1md)) - return -1; - ret = RSA_public_encrypt(klen, rctx->tbuf, out, - ctx->pkey->pkey.rsa, RSA_NO_PADDING); - } else - ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, - rctx->pad_mode); - if (ret < 0) - return ret; - *outlen = ret; - return 1; -} - -static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, - unsigned char *out, size_t *outlen, - const unsigned char *in, size_t inlen) -{ - int ret; - RSA_PKEY_CTX *rctx = ctx->data; - if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { - if (!setup_tbuf(rctx, ctx)) - return -1; - ret = RSA_private_decrypt(inlen, in, rctx->tbuf, - ctx->pkey->pkey.rsa, RSA_NO_PADDING); - if (ret <= 0) - return ret; - ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf, - ret, ret, - rctx->oaep_label, - rctx->oaep_labellen, - rctx->md, rctx->mgf1md); - } else - ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, - rctx->pad_mode); - if (ret < 0) - return ret; - *outlen = ret; - return 1; -} - -static int check_padding_md(const EVP_MD *md, int padding) -{ - if (!md) - return 1; - - if (padding == RSA_NO_PADDING) { - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); - return 0; - } - - if (padding == RSA_X931_PADDING) { - if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) { - RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); - return 0; - } - return 1; - } - - return 1; -} - -static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) -{ - RSA_PKEY_CTX *rctx = ctx->data; - switch (type) { - case EVP_PKEY_CTRL_RSA_PADDING: - if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { - if (!check_padding_md(rctx->md, p1)) - return 0; - if (p1 == RSA_PKCS1_PSS_PADDING) { - if (!(ctx->operation & - (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) - goto bad_pad; - if (!rctx->md) - rctx->md = EVP_sha1(); - } - if (p1 == RSA_PKCS1_OAEP_PADDING) { - if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) - goto bad_pad; - if (!rctx->md) - rctx->md = EVP_sha1(); - } - rctx->pad_mode = p1; - return 1; - } - bad_pad: - RSAerr(RSA_F_PKEY_RSA_CTRL, - RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); - return -2; - - case EVP_PKEY_CTRL_GET_RSA_PADDING: - *(int *)p2 = rctx->pad_mode; - return 1; - - case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: - case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: - if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); - return -2; - } - if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) - *(int *)p2 = rctx->saltlen; - else { - if (p1 < -2) - return -2; - rctx->saltlen = p1; - } - return 1; - - case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: - if (p1 < 256) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); - return -2; - } - rctx->nbits = p1; - return 1; - - case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: - if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE); - return -2; - } - BN_free(rctx->pub_exp); - rctx->pub_exp = p2; - return 1; - - case EVP_PKEY_CTRL_RSA_OAEP_MD: - case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: - if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); - return -2; - } - if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) - *(const EVP_MD **)p2 = rctx->md; - else - rctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_MD: - if (!check_padding_md(p2, rctx->pad_mode)) - return 0; - rctx->md = p2; - return 1; - - case EVP_PKEY_CTRL_GET_MD: - *(const EVP_MD **)p2 = rctx->md; - return 1; - - case EVP_PKEY_CTRL_RSA_MGF1_MD: - case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: - if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING - && rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); - return -2; - } - if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { - if (rctx->mgf1md) - *(const EVP_MD **)p2 = rctx->mgf1md; - else - *(const EVP_MD **)p2 = rctx->md; - } else - rctx->mgf1md = p2; - return 1; - - case EVP_PKEY_CTRL_RSA_OAEP_LABEL: - if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); - return -2; - } - if (rctx->oaep_label) - OPENSSL_free(rctx->oaep_label); - if (p2 && p1 > 0) { - rctx->oaep_label = p2; - rctx->oaep_labellen = p1; - } else { - rctx->oaep_label = NULL; - rctx->oaep_labellen = 0; - } - return 1; - - case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: - if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { - RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PADDING_MODE); - return -2; - } - *(unsigned char **)p2 = rctx->oaep_label; - return rctx->oaep_labellen; - - case EVP_PKEY_CTRL_DIGESTINIT: - case EVP_PKEY_CTRL_PKCS7_ENCRYPT: - case EVP_PKEY_CTRL_PKCS7_DECRYPT: - case EVP_PKEY_CTRL_PKCS7_SIGN: - return 1; -#ifndef OPENSSL_NO_CMS - case EVP_PKEY_CTRL_CMS_DECRYPT: - case EVP_PKEY_CTRL_CMS_ENCRYPT: - case EVP_PKEY_CTRL_CMS_SIGN: - return 1; -#endif - case EVP_PKEY_CTRL_PEER_KEY: - RSAerr(RSA_F_PKEY_RSA_CTRL, - RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; - - default: - return -2; - - } -} - -static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, - const char *type, const char *value) -{ - if (!value) { - RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); - return 0; - } - if (!strcmp(type, "rsa_padding_mode")) { - int pm; - if (!strcmp(value, "pkcs1")) - pm = RSA_PKCS1_PADDING; - else if (!strcmp(value, "sslv23")) - pm = RSA_SSLV23_PADDING; - else if (!strcmp(value, "none")) - pm = RSA_NO_PADDING; - else if (!strcmp(value, "oeap")) - pm = RSA_PKCS1_OAEP_PADDING; - else if (!strcmp(value, "oaep")) - pm = RSA_PKCS1_OAEP_PADDING; - else if (!strcmp(value, "x931")) - pm = RSA_X931_PADDING; - else if (!strcmp(value, "pss")) - pm = RSA_PKCS1_PSS_PADDING; - else { - RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); - return -2; - } - return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); - } - - if (!strcmp(type, "rsa_pss_saltlen")) { - int saltlen; - saltlen = atoi(value); - return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); - } - - if (!strcmp(type, "rsa_keygen_bits")) { - int nbits; - nbits = atoi(value); - return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); - } - - if (!strcmp(type, "rsa_keygen_pubexp")) { - int ret; - BIGNUM *pubexp = NULL; - if (!BN_asc2bn(&pubexp, value)) - return 0; - ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); - if (ret <= 0) - BN_free(pubexp); - return ret; - } - - if (!strcmp(type, "rsa_mgf1_md")) { - const EVP_MD *md; - if (!(md = EVP_get_digestbyname(value))) { - RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); - return 0; - } - return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md); - } - - if (!strcmp(type, "rsa_oaep_md")) { - const EVP_MD *md; - if (!(md = EVP_get_digestbyname(value))) { - RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST); - return 0; - } - return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md); - } - if (!strcmp(type, "rsa_oaep_label")) { - unsigned char *lab; - long lablen; - int ret; - lab = string_to_hex(value, &lablen); - if (!lab) - return 0; - ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); - if (ret <= 0) - OPENSSL_free(lab); - return ret; - } - - return -2; -} - -static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) -{ - RSA *rsa = NULL; - RSA_PKEY_CTX *rctx = ctx->data; - BN_GENCB *pcb, cb; - int ret; - if (!rctx->pub_exp) { - rctx->pub_exp = BN_new(); - if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) - return 0; - } - rsa = RSA_new(); - if (!rsa) - return 0; - if (ctx->pkey_gencb) { - pcb = &cb; - evp_pkey_set_cb_translate(pcb, ctx); - } else - pcb = NULL; - ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); - if (ret > 0) - EVP_PKEY_assign_RSA(pkey, rsa); - else - RSA_free(rsa); - return ret; -} - -const EVP_PKEY_METHOD rsa_pkey_meth = { - EVP_PKEY_RSA, - EVP_PKEY_FLAG_AUTOARGLEN, - pkey_rsa_init, - pkey_rsa_copy, - pkey_rsa_cleanup, - - 0, 0, - - 0, - pkey_rsa_keygen, - - 0, - pkey_rsa_sign, - - 0, - pkey_rsa_verify, - - 0, - pkey_rsa_verifyrecover, - - 0, 0, 0, 0, - - 0, - pkey_rsa_encrypt, - - 0, - pkey_rsa_decrypt, - - 0, 0, - - pkey_rsa_ctrl, - pkey_rsa_ctrl_str -}; -/* crypto/rsa/rsa_prn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2006. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "rsa.h" -// #include "evp.h" - -#ifndef OPENSSL_NO_FP_API -int RSA_print_fp(FILE *fp, const RSA *x, int off) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = RSA_print(b, x, off); - BIO_free(b); - return (ret); -} -#endif - -int RSA_print(BIO *bp, const RSA *x, int off) -{ - EVP_PKEY *pk; - int ret; - pk = EVP_PKEY_new(); - if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x)) - return 0; - ret = EVP_PKEY_print_private(bp, pk, off, NULL); - EVP_PKEY_free(pk); - return ret; -} -/* rsa_pss.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2005. - */ -/* ==================================================================== - * Copyright (c) 2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "evp.h" -// #include "rand.h" -#include "sha.h" - -static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - -#if defined(_MSC_VER) && defined(_ARM_) -# pragma optimize("g", off) -#endif - -int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, - const EVP_MD *Hash, const unsigned char *EM, - int sLen) -{ - return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen); -} - -int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, - const EVP_MD *Hash, const EVP_MD *mgf1Hash, - const unsigned char *EM, int sLen) -{ - int i; - int ret = 0; - int hLen, maskedDBLen, MSBits, emLen; - const unsigned char *H; - unsigned char *DB = NULL; - EVP_MD_CTX ctx; - unsigned char H_[EVP_MAX_MD_SIZE]; - EVP_MD_CTX_init(&ctx); - - if (mgf1Hash == NULL) - mgf1Hash = Hash; - - hLen = EVP_MD_size(Hash); - if (hLen < 0) - goto err; - /*- - * Negative sLen has special meanings: - * -1 sLen == hLen - * -2 salt length is autorecovered from signature - * -N reserved - */ - if (sLen == -1) - sLen = hLen; - else if (sLen == -2) - sLen = -2; - else if (sLen < -2) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); - goto err; - } - - MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; - emLen = RSA_size(rsa); - if (EM[0] & (0xFF << MSBits)) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID); - goto err; - } - if (MSBits == 0) { - EM++; - emLen--; - } - if (emLen < hLen + 2) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); - goto err; - } - if (sLen > emLen - hLen - 2) { /* sLen can be small negative */ - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); - goto err; - } - if (EM[emLen - 1] != 0xbc) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID); - goto err; - } - maskedDBLen = emLen - hLen - 1; - H = EM + maskedDBLen; - DB = OPENSSL_malloc(maskedDBLen); - if (!DB) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE); - goto err; - } - if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) - goto err; - for (i = 0; i < maskedDBLen; i++) - DB[i] ^= EM[i]; - if (MSBits) - DB[0] &= 0xFF >> (8 - MSBits); - for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ; - if (DB[i++] != 0x1) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED); - goto err; - } - if (sLen >= 0 && (maskedDBLen - i) != sLen) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); - goto err; - } - if (!EVP_DigestInit_ex(&ctx, Hash, NULL) - || !EVP_DigestUpdate(&ctx, zeroes, sizeof(zeroes)) - || !EVP_DigestUpdate(&ctx, mHash, hLen)) - goto err; - if (maskedDBLen - i) { - if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i)) - goto err; - } - if (!EVP_DigestFinal_ex(&ctx, H_, NULL)) - goto err; - if (memcmp(H_, H, hLen)) { - RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE); - ret = 0; - } else - ret = 1; - - err: - if (DB) - OPENSSL_free(DB); - EVP_MD_CTX_cleanup(&ctx); - - return ret; - -} - -int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, - const unsigned char *mHash, - const EVP_MD *Hash, int sLen) -{ - return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen); -} - -int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, - const unsigned char *mHash, - const EVP_MD *Hash, const EVP_MD *mgf1Hash, - int sLen) -{ - int i; - int ret = 0; - int hLen, maskedDBLen, MSBits, emLen; - unsigned char *H, *salt = NULL, *p; - EVP_MD_CTX ctx; - - if (mgf1Hash == NULL) - mgf1Hash = Hash; - - hLen = EVP_MD_size(Hash); - if (hLen < 0) - goto err; - /*- - * Negative sLen has special meanings: - * -1 sLen == hLen - * -2 salt length is maximized - * -N reserved - */ - if (sLen == -1) - sLen = hLen; - else if (sLen == -2) - sLen = -2; - else if (sLen < -2) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); - goto err; - } - - MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; - emLen = RSA_size(rsa); - if (MSBits == 0) { - *EM++ = 0; - emLen--; - } - if (emLen < hLen + 2) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - goto err; - } - if (sLen == -2) { - sLen = emLen - hLen - 2; - } else if (sLen > emLen - hLen - 2) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - goto err; - } - if (sLen > 0) { - salt = OPENSSL_malloc(sLen); - if (!salt) { - RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, - ERR_R_MALLOC_FAILURE); - goto err; - } - if (RAND_bytes(salt, sLen) <= 0) - goto err; - } - maskedDBLen = emLen - hLen - 1; - H = EM + maskedDBLen; - EVP_MD_CTX_init(&ctx); - if (!EVP_DigestInit_ex(&ctx, Hash, NULL) - || !EVP_DigestUpdate(&ctx, zeroes, sizeof(zeroes)) - || !EVP_DigestUpdate(&ctx, mHash, hLen)) - goto err; - if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen)) - goto err; - if (!EVP_DigestFinal_ex(&ctx, H, NULL)) - goto err; - EVP_MD_CTX_cleanup(&ctx); - - /* Generate dbMask in place then perform XOR on it */ - if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) - goto err; - - p = EM; - - /* - * Initial PS XORs with all zeroes which is a NOP so just update pointer. - * Note from a test above this value is guaranteed to be non-negative. - */ - p += emLen - sLen - hLen - 2; - *p++ ^= 0x1; - if (sLen > 0) { - for (i = 0; i < sLen; i++) - *p++ ^= salt[i]; - } - if (MSBits) - EM[0] &= 0xFF >> (8 - MSBits); - - /* H is already in place so just set final 0xbc */ - - EM[emLen - 1] = 0xbc; - - ret = 1; - - err: - if (salt) - OPENSSL_free(salt); - - return ret; - -} - -#if defined(_MSC_VER) -# pragma optimize("",on) -#endif -/* crypto/rsa/rsa_saos.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -#include "objects.h" -// #include "x509.h" - -int RSA_sign_ASN1_OCTET_STRING(int type, - const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, - RSA *rsa) -{ - ASN1_OCTET_STRING sig; - int i, j, ret = 1; - unsigned char *p, *s; - - sig.type = V_ASN1_OCTET_STRING; - sig.length = m_len; - sig.data = (unsigned char *)m; - - i = i2d_ASN1_OCTET_STRING(&sig, NULL); - j = RSA_size(rsa); - if (i > (j - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, - RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); - return (0); - } - s = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1); - if (s == NULL) { - RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); - return (0); - } - p = s; - i2d_ASN1_OCTET_STRING(&sig, &p); - i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); - if (i <= 0) - ret = 0; - else - *siglen = i; - - OPENSSL_cleanse(s, (unsigned int)j + 1); - OPENSSL_free(s); - return (ret); -} - -int RSA_verify_ASN1_OCTET_STRING(int dtype, - const unsigned char *m, - unsigned int m_len, unsigned char *sigbuf, - unsigned int siglen, RSA *rsa) -{ - int i, ret = 0; - unsigned char *s; - const unsigned char *p; - ASN1_OCTET_STRING *sig = NULL; - - if (siglen != (unsigned int)RSA_size(rsa)) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, - RSA_R_WRONG_SIGNATURE_LENGTH); - return (0); - } - - s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen); - if (s == NULL) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); - goto err; - } - i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); - - if (i <= 0) - goto err; - - p = s; - sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i); - if (sig == NULL) - goto err; - - if (((unsigned int)sig->length != m_len) || - (memcmp(m, sig->data, m_len) != 0)) { - RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE); - } else - ret = 1; - err: - if (sig != NULL) - M_ASN1_OCTET_STRING_free(sig); - if (s != NULL) { - OPENSSL_cleanse(s, (unsigned int)siglen); - OPENSSL_free(s); - } - return (ret); -} -/* crypto/rsa/rsa_sign.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "objects.h" -// #include "x509.h" -// #include "rsa_locl.h" - -/* Size of an SSL signature: MD5+SHA1 */ -#define SSL_SIG_LENGTH 36 - -int RSA_sign(int type, const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, RSA *rsa) -{ - X509_SIG sig; - ASN1_TYPE parameter; - int i, j, ret = 1; - unsigned char *p, *tmps = NULL; - const unsigned char *s = NULL; - X509_ALGOR algor; - ASN1_OCTET_STRING digest; -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD); - return 0; - } -#endif - if ((rsa->meth->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) { - return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); - } - /* Special case: SSL signature, just check the length */ - if (type == NID_md5_sha1) { - if (m_len != SSL_SIG_LENGTH) { - RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); - return (0); - } - i = SSL_SIG_LENGTH; - s = m; - } else { - sig.algor = &algor; - sig.algor->algorithm = OBJ_nid2obj(type); - if (sig.algor->algorithm == NULL) { - RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE); - return (0); - } - if (sig.algor->algorithm->length == 0) { - RSAerr(RSA_F_RSA_SIGN, - RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); - return (0); - } - parameter.type = V_ASN1_NULL; - parameter.value.ptr = NULL; - sig.algor->parameter = ¶meter; - - sig.digest = &digest; - sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */ - sig.digest->length = m_len; - - i = i2d_X509_SIG(&sig, NULL); - } - j = RSA_size(rsa); - if (i > (j - RSA_PKCS1_PADDING_SIZE)) { - RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); - return (0); - } - if (type != NID_md5_sha1) { - tmps = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1); - if (tmps == NULL) { - RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE); - return (0); - } - p = tmps; - i2d_X509_SIG(&sig, &p); - s = tmps; - } - i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); - if (i <= 0) - ret = 0; - else - *siglen = i; - - if (type != NID_md5_sha1) { - OPENSSL_cleanse(tmps, (unsigned int)j + 1); - OPENSSL_free(tmps); - } - return (ret); -} - -/* - * Check DigestInfo structure does not contain extraneous data by reencoding - * using DER and checking encoding against original. - */ -static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, - int dinfolen) -{ - unsigned char *der = NULL; - int derlen; - int ret = 0; - derlen = i2d_X509_SIG(sig, &der); - if (derlen <= 0) - return 0; - if (derlen == dinfolen && !memcmp(dinfo, der, derlen)) - ret = 1; - OPENSSL_cleanse(der, derlen); - OPENSSL_free(der); - return ret; -} - -int int_rsa_verify(int dtype, const unsigned char *m, - unsigned int m_len, - unsigned char *rm, size_t *prm_len, - const unsigned char *sigbuf, size_t siglen, RSA *rsa) -{ - int i, ret = 0, sigtype; - unsigned char *s; - X509_SIG *sig = NULL; - -#ifdef OPENSSL_FIPS - if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) - && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD); - return 0; - } -#endif - - if (siglen != (unsigned int)RSA_size(rsa)) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); - return (0); - } - - if ((dtype == NID_md5_sha1) && rm) { - i = RSA_public_decrypt((int)siglen, - sigbuf, rm, rsa, RSA_PKCS1_PADDING); - if (i <= 0) - return 0; - *prm_len = i; - return 1; - } - - s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen); - if (s == NULL) { - RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); - goto err; - } - if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); - goto err; - } - i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); - - if (i <= 0) - goto err; - /* - * Oddball MDC2 case: signature can be OCTET STRING. check for correct - * tag and length octets. - */ - if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) { - if (rm) { - memcpy(rm, s + 2, 16); - *prm_len = 16; - ret = 1; - } else if (memcmp(m, s + 2, 16)) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - } else { - ret = 1; - } - } else if (dtype == NID_md5_sha1) { - /* Special case: SSL signature */ - if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - else - ret = 1; - } else { - const unsigned char *p = s; - sig = d2i_X509_SIG(NULL, &p, (long)i); - - if (sig == NULL) - goto err; - - /* Excess data can be used to create forgeries */ - if (p != s + i || !rsa_check_digestinfo(sig, s, i)) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - goto err; - } - - /* - * Parameters to the signature algorithm can also be used to create - * forgeries - */ - if (sig->algor->parameter - && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - goto err; - } - - sigtype = OBJ_obj2nid(sig->algor->algorithm); - -#ifdef RSA_DEBUG - /* put a backward compatibility flag in EAY */ - fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype), - OBJ_nid2ln(dtype)); -#endif - if (sigtype != dtype) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); - goto err; - } - if (rm) { - const EVP_MD *md; - md = EVP_get_digestbynid(dtype); - if (md && (EVP_MD_size(md) != sig->digest->length)) - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); - else { - memcpy(rm, sig->digest->data, sig->digest->length); - *prm_len = sig->digest->length; - ret = 1; - } - } else if (((unsigned int)sig->digest->length != m_len) || - (memcmp(m, sig->digest->data, m_len) != 0)) { - RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); - } else - ret = 1; - } - err: - if (sig != NULL) - X509_SIG_free(sig); - if (s != NULL) { - OPENSSL_cleanse(s, (unsigned int)siglen); - OPENSSL_free(s); - } - return (ret); -} - -int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, - const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) -{ - - if ((rsa->meth->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) { - return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa); - } - - return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); -} -/* crypto/rsa/rsa_ssl.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "rand.h" - -int RSA_padding_add_SSLv23(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int i, j; - unsigned char *p; - - if (flen > (tlen - 11)) { - RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23, - RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return (0); - } - - p = (unsigned char *)to; - - *(p++) = 0; - *(p++) = 2; /* Public Key BT (Block Type) */ - - /* pad out with non-zero random data */ - j = tlen - 3 - 8 - flen; - - if (RAND_bytes(p, j) <= 0) - return (0); - for (i = 0; i < j; i++) { - if (*p == '\0') - do { - if (RAND_bytes(p, 1) <= 0) - return (0); - } while (*p == '\0'); - p++; - } - - memset(p, 3, 8); - p += 8; - *(p++) = '\0'; - - memcpy(p, from, (unsigned int)flen); - return (1); -} - -int RSA_padding_check_SSLv23(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num) -{ - int i, j, k; - const unsigned char *p; - - p = from; - if (flen < 10) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL); - return (-1); - } - /* Accept even zero-padded input */ - if (flen == num) { - if (*(p++) != 0) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02); - return -1; - } - flen--; - } - if ((num != (flen + 1)) || (*(p++) != 02)) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02); - return (-1); - } - - /* scan over padding data */ - j = flen - 1; /* one for type */ - for (i = 0; i < j; i++) - if (*(p++) == 0) - break; - - if ((i == j) || (i < 8)) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, - RSA_R_NULL_BEFORE_BLOCK_MISSING); - return (-1); - } - for (k = -9; k < -1; k++) { - if (p[k] != 0x03) - break; - } - if (k == -1) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_SSLV3_ROLLBACK_ATTACK); - return (-1); - } - - i++; /* Skip over the '\0' */ - j -= i; - if (j > tlen) { - RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE); - return (-1); - } - memcpy(to, p, (unsigned int)j); - - return (j); -} -/* rsa_x931.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2005. - */ -/* ==================================================================== - * Copyright (c) 2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "rsa.h" -// #include "rand.h" -// #include "objects.h" - -int RSA_padding_add_X931(unsigned char *to, int tlen, - const unsigned char *from, int flen) -{ - int j; - unsigned char *p; - - /* - * Absolute minimum amount of padding is 1 header nibble, 1 padding - * nibble and 2 trailer bytes: but 1 hash if is already in 'from'. - */ - - j = tlen - flen - 2; - - if (j < 0) { - RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); - return -1; - } - - p = (unsigned char *)to; - - /* If no padding start and end nibbles are in one byte */ - if (j == 0) - *p++ = 0x6A; - else { - *p++ = 0x6B; - if (j > 1) { - memset(p, 0xBB, j - 1); - p += j - 1; - } - *p++ = 0xBA; - } - memcpy(p, from, (unsigned int)flen); - p += flen; - *p = 0xCC; - return (1); -} - -int RSA_padding_check_X931(unsigned char *to, int tlen, - const unsigned char *from, int flen, int num) -{ - int i = 0, j; - const unsigned char *p; - - p = from; - if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER); - return -1; - } - - if (*p++ == 0x6B) { - j = flen - 3; - for (i = 0; i < j; i++) { - unsigned char c = *p++; - if (c == 0xBA) - break; - if (c != 0xBB) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); - return -1; - } - } - - j -= i; - - if (i == 0) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); - return -1; - } - - } else - j = flen - 2; - - if (p[j] != 0xCC) { - RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER); - return -1; - } - - memcpy(to, p, (unsigned int)j); - - return (j); -} - -/* Translate between X931 hash ids and NIDs */ - -int RSA_X931_hash_id(int nid) -{ - switch (nid) { - case NID_sha1: - return 0x33; - - case NID_sha256: - return 0x34; - - case NID_sha384: - return 0x36; - - case NID_sha512: - return 0x35; - - } - return -1; -} diff --git a/Sources/COpenSSL/rsa_locl.h b/Sources/COpenSSL/rsa_locl.h deleted file mode 100644 index 3e88187d..00000000 --- a/Sources/COpenSSL/rsa_locl.h +++ /dev/null @@ -1,4 +0,0 @@ -extern int int_rsa_verify(int dtype, const unsigned char *m, - unsigned int m_len, unsigned char *rm, - size_t *prm_len, const unsigned char *sigbuf, - size_t siglen, RSA *rsa); diff --git a/Sources/COpenSSL/rsaz_exp.c b/Sources/COpenSSL/rsaz_exp.c deleted file mode 100644 index c54c6feb..00000000 --- a/Sources/COpenSSL/rsaz_exp.c +++ /dev/null @@ -1,346 +0,0 @@ -/***************************************************************************** -* * -* Copyright (c) 2012, Intel Corporation * -* * -* All rights reserved. * -* * -* Redistribution and use in source and binary forms, with or without * -* modification, are permitted provided that the following conditions are * -* met: * -* * -* * Redistributions of source code must retain the above copyright * -* notice, this list of conditions and the following disclaimer. * -* * -* * Redistributions in binary form must reproduce the above copyright * -* notice, this list of conditions and the following disclaimer in the * -* documentation and/or other materials provided with the * -* distribution. * -* * -* * Neither the name of the Intel Corporation nor the names of its * -* contributors may be used to endorse or promote products derived from * -* this software without specific prior written permission. * -* * -* * -* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY * -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * -* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR * -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * -* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * -* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * -* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * -* * -****************************************************************************** -* Developers and authors: * -* Shay Gueron (1, 2), and Vlad Krasnov (1) * -* (1) Intel Corporation, Israel Development Center, Haifa, Israel * -* (2) University of Haifa, Israel * -*****************************************************************************/ - -#include "rsaz_exp.h" - -#ifdef RSAZ_ENABLED - -/* - * See crypto/bn/asm/rsaz-avx2.pl for further details. - */ -void rsaz_1024_norm2red_avx2(void *red, const void *norm); -void rsaz_1024_mul_avx2(void *ret, const void *a, const void *b, - const void *n, BN_ULONG k); -void rsaz_1024_sqr_avx2(void *ret, const void *a, const void *n, BN_ULONG k, - int cnt); -void rsaz_1024_scatter5_avx2(void *tbl, const void *val, int i); -void rsaz_1024_gather5_avx2(void *val, const void *tbl, int i); -void rsaz_1024_red2norm_avx2(void *norm, const void *red); - -#if defined(__GNUC__) -# define ALIGN64 __attribute__((aligned(64))) -#elif defined(_MSC_VER) -# define ALIGN64 __declspec(align(64)) -#elif defined(__SUNPRO_C) -# define ALIGN64 -# pragma align 64(one,two80) -#else -/* not fatal, might hurt performance a little */ -# define ALIGN64 -#endif - -ALIGN64 static const BN_ULONG one[40] = { - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -ALIGN64 static const BN_ULONG two80[40] = { - 0, 0, 1 << 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16], - const BN_ULONG base_norm[16], - const BN_ULONG exponent[16], - const BN_ULONG m_norm[16], const BN_ULONG RR[16], - BN_ULONG k0) -{ - unsigned char storage[320 * 3 + 32 * 9 * 16 + 64]; /* 5.5KB */ - unsigned char *p_str = storage + (64 - ((size_t)storage % 64)); - unsigned char *a_inv, *m, *result; - unsigned char *table_s = p_str + 320 * 3; - unsigned char *R2 = table_s; /* borrow */ - int index; - int wvalue; - - if ((((size_t)p_str & 4095) + 320) >> 12) { - result = p_str; - a_inv = p_str + 320; - m = p_str + 320 * 2; /* should not cross page */ - } else { - m = p_str; /* should not cross page */ - result = p_str + 320; - a_inv = p_str + 320 * 2; - } - - rsaz_1024_norm2red_avx2(m, m_norm); - rsaz_1024_norm2red_avx2(a_inv, base_norm); - rsaz_1024_norm2red_avx2(R2, RR); - - rsaz_1024_mul_avx2(R2, R2, R2, m, k0); - rsaz_1024_mul_avx2(R2, R2, two80, m, k0); - - /* table[0] = 1 */ - rsaz_1024_mul_avx2(result, R2, one, m, k0); - /* table[1] = a_inv^1 */ - rsaz_1024_mul_avx2(a_inv, a_inv, R2, m, k0); - - rsaz_1024_scatter5_avx2(table_s, result, 0); - rsaz_1024_scatter5_avx2(table_s, a_inv, 1); - - /* table[2] = a_inv^2 */ - rsaz_1024_sqr_avx2(result, a_inv, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 2); -#if 0 - /* this is almost 2x smaller and less than 1% slower */ - for (index = 3; index < 32; index++) { - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, index); - } -#else - /* table[4] = a_inv^4 */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 4); - /* table[8] = a_inv^8 */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 8); - /* table[16] = a_inv^16 */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 16); - /* table[17] = a_inv^17 */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 17); - - /* table[3] */ - rsaz_1024_gather5_avx2(result, table_s, 2); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 3); - /* table[6] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 6); - /* table[12] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 12); - /* table[24] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 24); - /* table[25] */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 25); - - /* table[5] */ - rsaz_1024_gather5_avx2(result, table_s, 4); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 5); - /* table[10] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 10); - /* table[20] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 20); - /* table[21] */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 21); - - /* table[7] */ - rsaz_1024_gather5_avx2(result, table_s, 6); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 7); - /* table[14] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 14); - /* table[28] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 28); - /* table[29] */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 29); - - /* table[9] */ - rsaz_1024_gather5_avx2(result, table_s, 8); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 9); - /* table[18] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 18); - /* table[19] */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 19); - - /* table[11] */ - rsaz_1024_gather5_avx2(result, table_s, 10); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 11); - /* table[22] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 22); - /* table[23] */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 23); - - /* table[13] */ - rsaz_1024_gather5_avx2(result, table_s, 12); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 13); - /* table[26] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 26); - /* table[27] */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 27); - - /* table[15] */ - rsaz_1024_gather5_avx2(result, table_s, 14); - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 15); - /* table[30] */ - rsaz_1024_sqr_avx2(result, result, m, k0, 1); - rsaz_1024_scatter5_avx2(table_s, result, 30); - /* table[31] */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - rsaz_1024_scatter5_avx2(table_s, result, 31); -#endif - - /* load first window */ - p_str = (unsigned char *)exponent; - wvalue = p_str[127] >> 3; - rsaz_1024_gather5_avx2(result, table_s, wvalue); - - index = 1014; - - while (index > -1) { /* loop for the remaining 127 windows */ - - rsaz_1024_sqr_avx2(result, result, m, k0, 5); - - wvalue = *((unsigned short *)&p_str[index / 8]); - wvalue = (wvalue >> (index % 8)) & 31; - index -= 5; - - rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); /* borrow a_inv */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - } - - /* square four times */ - rsaz_1024_sqr_avx2(result, result, m, k0, 4); - - wvalue = p_str[0] & 15; - - rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); /* borrow a_inv */ - rsaz_1024_mul_avx2(result, result, a_inv, m, k0); - - /* from Montgomery */ - rsaz_1024_mul_avx2(result, result, one, m, k0); - - rsaz_1024_red2norm_avx2(result_norm, result); - - OPENSSL_cleanse(storage, sizeof(storage)); -} - -/* - * See crypto/bn/rsaz-x86_64.pl for further details. - */ -void rsaz_512_mul(void *ret, const void *a, const void *b, const void *n, - BN_ULONG k); -void rsaz_512_mul_scatter4(void *ret, const void *a, const void *n, - BN_ULONG k, const void *tbl, unsigned int power); -void rsaz_512_mul_gather4(void *ret, const void *a, const void *tbl, - const void *n, BN_ULONG k, unsigned int power); -void rsaz_512_mul_by_one(void *ret, const void *a, const void *n, BN_ULONG k); -void rsaz_512_sqr(void *ret, const void *a, const void *n, BN_ULONG k, - int cnt); -void rsaz_512_scatter4(void *tbl, const BN_ULONG *val, int power); -void rsaz_512_gather4(BN_ULONG *val, const void *tbl, int power); - -void RSAZ_512_mod_exp(BN_ULONG result[8], - const BN_ULONG base[8], const BN_ULONG exponent[8], - const BN_ULONG m[8], BN_ULONG k0, const BN_ULONG RR[8]) -{ - unsigned char storage[16 * 8 * 8 + 64 * 2 + 64]; /* 1.2KB */ - unsigned char *table = storage + (64 - ((size_t)storage % 64)); - BN_ULONG *a_inv = (BN_ULONG *)(table + 16 * 8 * 8); - BN_ULONG *temp = (BN_ULONG *)(table + 16 * 8 * 8 + 8 * 8); - unsigned char *p_str = (unsigned char *)exponent; - int index; - unsigned int wvalue; - - /* table[0] = 1_inv */ - temp[0] = 0 - m[0]; - temp[1] = ~m[1]; - temp[2] = ~m[2]; - temp[3] = ~m[3]; - temp[4] = ~m[4]; - temp[5] = ~m[5]; - temp[6] = ~m[6]; - temp[7] = ~m[7]; - rsaz_512_scatter4(table, temp, 0); - - /* table [1] = a_inv^1 */ - rsaz_512_mul(a_inv, base, RR, m, k0); - rsaz_512_scatter4(table, a_inv, 1); - - /* table [2] = a_inv^2 */ - rsaz_512_sqr(temp, a_inv, m, k0, 1); - rsaz_512_scatter4(table, temp, 2); - - for (index = 3; index < 16; index++) - rsaz_512_mul_scatter4(temp, a_inv, m, k0, table, index); - - /* load first window */ - wvalue = p_str[63]; - - rsaz_512_gather4(temp, table, wvalue >> 4); - rsaz_512_sqr(temp, temp, m, k0, 4); - rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue & 0xf); - - for (index = 62; index >= 0; index--) { - wvalue = p_str[index]; - - rsaz_512_sqr(temp, temp, m, k0, 4); - rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue >> 4); - - rsaz_512_sqr(temp, temp, m, k0, 4); - rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue & 0x0f); - } - - /* from Montgomery */ - rsaz_512_mul_by_one(result, temp, m, k0); - - OPENSSL_cleanse(storage, sizeof(storage)); -} - -#else - -# if defined(PEDANTIC) || defined(__DECC) || defined(__clang__) -static void *dummy = &dummy; -# endif - -#endif diff --git a/Sources/COpenSSL/rsaz_exp.h b/Sources/COpenSSL/rsaz_exp.h deleted file mode 100644 index ab7ebaa2..00000000 --- a/Sources/COpenSSL/rsaz_exp.h +++ /dev/null @@ -1,68 +0,0 @@ -/***************************************************************************** -* * -* Copyright (c) 2012, Intel Corporation * -* * -* All rights reserved. * -* * -* Redistribution and use in source and binary forms, with or without * -* modification, are permitted provided that the following conditions are * -* met: * -* * -* * Redistributions of source code must retain the above copyright * -* notice, this list of conditions and the following disclaimer. * -* * -* * Redistributions in binary form must reproduce the above copyright * -* notice, this list of conditions and the following disclaimer in the * -* documentation and/or other materials provided with the * -* distribution. * -* * -* * Neither the name of the Intel Corporation nor the names of its * -* contributors may be used to endorse or promote products derived from * -* this software without specific prior written permission. * -* * -* * -* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY * -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * -* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR * -* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * -* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * -* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * -* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * -* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * -* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * -* * -****************************************************************************** -* Developers and authors: * -* Shay Gueron (1, 2), and Vlad Krasnov (1) * -* (1) Intel Corporation, Israel Development Center, Haifa, Israel * -* (2) University of Haifa, Israel * -*****************************************************************************/ - -#ifndef RSAZ_EXP_H -# define RSAZ_EXP_H - -# undef RSAZ_ENABLED -# if defined(OPENSSL_BN_ASM_MONT) && \ - (defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64)) -# define RSAZ_ENABLED - -# include "bn.h" - -void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16], - const BN_ULONG base_norm[16], - const BN_ULONG exponent[16], - const BN_ULONG m_norm[16], const BN_ULONG RR[16], - BN_ULONG k0); -int rsaz_avx2_eligible(); - -void RSAZ_512_mod_exp(BN_ULONG result[8], - const BN_ULONG base_norm[8], const BN_ULONG exponent[8], - const BN_ULONG m_norm[8], BN_ULONG k0, - const BN_ULONG RR[8]); - -# endif - -#endif diff --git a/Sources/COpenSSL/s23_.c b/Sources/COpenSSL/s23_.c deleted file mode 100644 index e14f5fa1..00000000 --- a/Sources/COpenSSL/s23_.c +++ /dev/null @@ -1,1884 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ssl/s23_clnt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "ssl_locl.h" -#include "buffer.h" -#include "rand.h" -#include "objects.h" -#include "evp.h" - -static const SSL_METHOD *ssl23_get_client_method(int ver); -static int ssl23_client_hello(SSL *s); -static int ssl23_get_server_hello(SSL *s); -static const SSL_METHOD *ssl23_get_client_method(int ver) -{ -#ifndef OPENSSL_NO_SSL2 - if (ver == SSL2_VERSION) - return (SSLv2_client_method()); -#endif -#ifndef OPENSSL_NO_SSL3 - if (ver == SSL3_VERSION) - return (SSLv3_client_method()); -#endif - if (ver == TLS1_VERSION) - return (TLSv1_client_method()); - else if (ver == TLS1_1_VERSION) - return (TLSv1_1_client_method()); - else if (ver == TLS1_2_VERSION) - return (TLSv1_2_client_method()); - else - return (NULL); -} - -IMPLEMENT_ssl23_meth_func(SSLv23_client_method, - ssl_undefined_function, - ssl23_connect, ssl23_get_client_method) - -int ssl23_connect(SSL *s) -{ - BUF_MEM *buf = NULL; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state; - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_BEFORE: - case SSL_ST_CONNECT: - case SSL_ST_BEFORE | SSL_ST_CONNECT: - case SSL_ST_OK | SSL_ST_CONNECT: - - if (s->session != NULL) { - SSLerr(SSL_F_SSL23_CONNECT, - SSL_R_SSL23_DOING_SESSION_ID_REUSE); - ret = -1; - goto end; - } - s->server = 0; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - /* s->version=TLS1_VERSION; */ - s->type = SSL_ST_CONNECT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - ret = -1; - goto end; - } - s->init_buf = buf; - buf = NULL; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - goto end; - } - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - goto end; - } - - s->state = SSL23_ST_CW_CLNT_HELLO_A; - s->ctx->stats.sess_connect++; - s->init_num = 0; - break; - - case SSL23_ST_CW_CLNT_HELLO_A: - case SSL23_ST_CW_CLNT_HELLO_B: - - s->shutdown = 0; - ret = ssl23_client_hello(s); - if (ret <= 0) - goto end; - s->state = SSL23_ST_CR_SRVR_HELLO_A; - s->init_num = 0; - - break; - - case SSL23_ST_CR_SRVR_HELLO_A: - case SSL23_ST_CR_SRVR_HELLO_B: - ret = ssl23_get_server_hello(s); - if (ret >= 0) - cb = NULL; - goto end; - /* break; */ - - default: - SSLerr(SSL_F_SSL23_CONNECT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - if (s->debug) { - (void)BIO_flush(s->wbio); - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; - } - } - end: - s->in_handshake--; - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s, SSL_CB_CONNECT_EXIT, ret); - return (ret); -} - -static int ssl23_no_ssl2_ciphers(SSL *s) -{ - SSL_CIPHER *cipher; - STACK_OF(SSL_CIPHER) *ciphers; - int i; - ciphers = SSL_get_ciphers(s); - for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { - cipher = sk_SSL_CIPHER_value(ciphers, i); - if (cipher->algorithm_ssl == SSL_SSLV2) - return 0; - } - return 1; -} - -/* - * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on - * failure, 1 on success. - */ -int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) -{ - int send_time = 0; - if (len < 4) - return 0; - if (server) - send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0; - else - send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0; - if (send_time) { - unsigned long Time = (unsigned long)time(NULL); - unsigned char *p = result; - l2n(Time, p); - return RAND_bytes(p, len - 4); - } else - return RAND_bytes(result, len); -} - -static int ssl23_client_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int i, ch_len; - unsigned long l; - int ssl2_compat; - int version = 0, version_major, version_minor; - int al = 0; -#ifndef OPENSSL_NO_COMP - int j; - SSL_COMP *comp; -#endif - int ret; - unsigned long mask, options = s->options; - - ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1; - - if (ssl2_compat && ssl23_no_ssl2_ciphers(s)) - ssl2_compat = 0; - - /* - * SSL_OP_NO_X disables all protocols above X *if* there are - * some protocols below X enabled. This is required in order - * to maintain "version capability" vector contiguous. So - * that if application wants to disable TLS1.0 in favour of - * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the - * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. - */ - mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 -#if !defined(OPENSSL_NO_SSL3) - | SSL_OP_NO_SSLv3 -#endif -#if !defined(OPENSSL_NO_SSL2) - | (ssl2_compat ? SSL_OP_NO_SSLv2 : 0) -#endif - ; -#if !defined(OPENSSL_NO_TLS1_2_CLIENT) - version = TLS1_2_VERSION; - - if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) - version = TLS1_1_VERSION; -#else - version = TLS1_1_VERSION; -#endif - mask &= ~SSL_OP_NO_TLSv1_1; - if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) - version = TLS1_VERSION; - mask &= ~SSL_OP_NO_TLSv1; -#if !defined(OPENSSL_NO_SSL3) - if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) - version = SSL3_VERSION; - mask &= ~SSL_OP_NO_SSLv3; -#endif -#if !defined(OPENSSL_NO_SSL2) - if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask) - version = SSL2_VERSION; -#endif - -#ifndef OPENSSL_NO_TLSEXT - if (version != SSL2_VERSION) { - /* - * have to disable SSL 2.0 compatibility if we need TLS extensions - */ - - if (s->tlsext_hostname != NULL) - ssl2_compat = 0; - if (s->tlsext_status_type != -1) - ssl2_compat = 0; -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->ctx->tlsext_opaque_prf_input_callback != 0 - || s->tlsext_opaque_prf_input != NULL) - ssl2_compat = 0; -# endif - if (s->cert->cli_ext.meths_count != 0) - ssl2_compat = 0; - } -#endif - - buf = (unsigned char *)s->init_buf->data; - if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { - /* - * Since we're sending s23 client hello, we're not reusing a session, as - * we'd be using the method from the saved session instead - */ - if (!ssl_get_new_session(s, 0)) { - return -1; - } - - p = s->s3->client_random; - if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) - return -1; - - if (version == TLS1_2_VERSION) { - version_major = TLS1_2_VERSION_MAJOR; - version_minor = TLS1_2_VERSION_MINOR; - } else if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, - SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); - return -1; - } else if (version == TLS1_1_VERSION) { - version_major = TLS1_1_VERSION_MAJOR; - version_minor = TLS1_1_VERSION_MINOR; - } else if (version == TLS1_VERSION) { - version_major = TLS1_VERSION_MAJOR; - version_minor = TLS1_VERSION_MINOR; - } -#ifdef OPENSSL_FIPS - else if (FIPS_mode()) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - return -1; - } -#endif - else if (version == SSL3_VERSION) { - version_major = SSL3_VERSION_MAJOR; - version_minor = SSL3_VERSION_MINOR; - } else if (version == SSL2_VERSION) { - version_major = SSL2_VERSION_MAJOR; - version_minor = SSL2_VERSION_MINOR; - } else { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_PROTOCOLS_AVAILABLE); - return (-1); - } - - s->client_version = version; - - if (ssl2_compat) { - /* create SSL 2.0 compatible Client Hello */ - - /* two byte record header will be written last */ - d = &(buf[2]); - p = d + 9; /* leave space for message type, version, - * individual length fields */ - - *(d++) = SSL2_MT_CLIENT_HELLO; - *(d++) = version_major; - *(d++) = version_minor; - - /* Ciphers supported */ - i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), p, 0); - if (i == 0) { - /* no ciphers */ - SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); - return -1; - } - s2n(i, d); - p += i; - - /* - * put in the session-id length (zero since there is no reuse) - */ - s2n(0, d); - - if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) - ch_len = SSL2_CHALLENGE_LENGTH; - else - ch_len = SSL2_MAX_CHALLENGE_LENGTH; - - /* write out sslv2 challenge */ - /* - * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it - * is one of SSL2_MAX_CHALLENGE_LENGTH (32) or - * SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for - * futurproofing - */ - if (SSL3_RANDOM_SIZE < ch_len) - i = SSL3_RANDOM_SIZE; - else - i = ch_len; - s2n(i, d); - memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE); - if (RAND_bytes (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) - <= 0) - return -1; - - memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); - p += i; - - i = p - &(buf[2]); - buf[0] = ((i >> 8) & 0xff) | 0x80; - buf[1] = (i & 0xff); - - /* number of bytes to write */ - s->init_num = i + 2; - s->init_off = 0; - - ssl3_finish_mac(s, &(buf[2]), i); - } else { - /* create Client Hello in SSL 3.0/TLS 1.0 format */ - - /* - * do the record header (5 bytes) and handshake message header (4 - * bytes) last - */ - d = p = &(buf[9]); - - *(p++) = version_major; - *(p++) = version_minor; - - /* Random stuff */ - memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /* Session ID (zero since there is no reuse) */ - *(p++) = 0; - - /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ - i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), - ssl3_put_cipher_by_char); - if (i == 0) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); - return -1; - } -#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH - /* - * Some servers hang if client hello > 256 bytes as hack - * workaround chop number of supported ciphers to keep it well - * below this if we use TLS v1.2 - */ - if (TLS1_get_version(s) >= TLS1_2_VERSION - && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) - i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; -#endif - s2n(i, p); - p += i; - - /* COMPRESSION */ -#ifdef OPENSSL_NO_COMP - *(p++) = 1; -#else - if ((s->options & SSL_OP_NO_COMPRESSION) - || !s->ctx->comp_methods) - j = 0; - else - j = sk_SSL_COMP_num(s->ctx->comp_methods); - *(p++) = 1 + j; - for (i = 0; i < j; i++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); - *(p++) = comp->id; - } -#endif - *(p++) = 0; /* Add the NULL method */ - -#ifndef OPENSSL_NO_TLSEXT - /* TLS extensions */ - if (ssl_prepare_clienthello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - return -1; - } - if ((p = - ssl_add_clienthello_tlsext(s, p, - buf + SSL3_RT_MAX_PLAIN_LENGTH, - &al)) == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - return -1; - } -#endif - - l = p - d; - - /* fill in 4-byte handshake header */ - d = &(buf[5]); - *(d++) = SSL3_MT_CLIENT_HELLO; - l2n3(l, d); - - l += 4; - - if (l > SSL3_RT_MAX_PLAIN_LENGTH) { - SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - return -1; - } - - /* fill in 5-byte record header */ - d = buf; - *(d++) = SSL3_RT_HANDSHAKE; - *(d++) = version_major; - /* - * Some servers hang if we use long client hellos and a record - * number > TLS 1.0. - */ - if (TLS1_get_client_version(s) > TLS1_VERSION) - *(d++) = 1; - else - *(d++) = version_minor; - s2n((int)l, d); - - /* number of bytes to write */ - s->init_num = p - buf; - s->init_off = 0; - - ssl3_finish_mac(s, &(buf[5]), s->init_num - 5); - } - - s->state = SSL23_ST_CW_CLNT_HELLO_B; - s->init_off = 0; - } - - /* SSL3_ST_CW_CLNT_HELLO_B */ - ret = ssl23_write_bytes(s); - - if ((ret >= 2) && s->msg_callback) { - /* Client Hello has been sent; tell msg_callback */ - - if (ssl2_compat) - s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data + 2, - ret - 2, s, s->msg_callback_arg); - else { - s->msg_callback(1, version, SSL3_RT_HEADER, s->init_buf->data, 5, - s, s->msg_callback_arg); - s->msg_callback(1, version, SSL3_RT_HANDSHAKE, - s->init_buf->data + 5, ret - 5, s, - s->msg_callback_arg); - } - } - - return ret; -} - -static int ssl23_get_server_hello(SSL *s) -{ - char buf[8]; - unsigned char *p; - int i; - int n; - - n = ssl23_read_bytes(s, 7); - - if (n != 7) - return (n); - p = s->packet; - - memcpy(buf, p, n); - - if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) && - (p[5] == 0x00) && (p[6] == 0x02)) { -#ifdef OPENSSL_NO_SSL2 - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; -#else - /* we are talking sslv2 */ - /* - * we need to clean up the SSLv3 setup and put in the sslv2 stuff. - */ - int ch_len; - - if (s->options & SSL_OP_NO_SSLv2) { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - if (s->s2 == NULL) { - if (!ssl2_new(s)) - goto err; - } else - ssl2_clear(s); - - if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) - ch_len = SSL2_CHALLENGE_LENGTH; - else - ch_len = SSL2_MAX_CHALLENGE_LENGTH; - - /* write out sslv2 challenge */ - /* - * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it is - * one of SSL2_MAX_CHALLENGE_LENGTH (32) or SSL2_MAX_CHALLENGE_LENGTH - * (16), but leave the check in for futurproofing - */ - i = (SSL3_RANDOM_SIZE < ch_len) - ? SSL3_RANDOM_SIZE : ch_len; - s->s2->challenge_length = i; - memcpy(s->s2->challenge, - &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); - - if (s->s3 != NULL) - ssl3_free(s); - - if (!BUF_MEM_grow_clean(s->init_buf, - SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, ERR_R_BUF_LIB); - goto err; - } - - s->state = SSL2_ST_GET_SERVER_HELLO_A; - if (!(s->client_version == SSL2_VERSION)) - /* - * use special padding (SSL 3.0 draft/RFC 2246, App. E.2) - */ - s->s2->ssl2_rollback = 1; - - /* - * setup the 7 bytes we have read so we get them from the sslv2 - * buffer - */ - s->rstate = SSL_ST_READ_HEADER; - s->packet_length = n; - s->packet = &(s->s2->rbuf[0]); - memcpy(s->packet, buf, n); - s->s2->rbuf_left = n; - s->s2->rbuf_offs = 0; - - /* we have already written one */ - s->s2->write_sequence = 1; - - s->method = SSLv2_client_method(); - s->handshake_func = s->method->ssl_connect; -#endif - } else if (p[1] == SSL3_VERSION_MAJOR && - p[2] <= TLS1_2_VERSION_MINOR && - ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || - (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) { - /* we have sslv3 or tls1 (server hello or alert) */ - -#ifndef OPENSSL_NO_SSL3 - if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) { -# ifdef OPENSSL_FIPS - if (FIPS_mode()) { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - goto err; - } -# endif - s->version = SSL3_VERSION; - s->method = SSLv3_client_method(); - } else -#endif - if ((p[2] == TLS1_VERSION_MINOR) && !(s->options & SSL_OP_NO_TLSv1)) { - s->version = TLS1_VERSION; - s->method = TLSv1_client_method(); - } else if ((p[2] == TLS1_1_VERSION_MINOR) && - !(s->options & SSL_OP_NO_TLSv1_1)) { - s->version = TLS1_1_VERSION; - s->method = TLSv1_1_client_method(); - } else if ((p[2] == TLS1_2_VERSION_MINOR) && - !(s->options & SSL_OP_NO_TLSv1_2)) { - s->version = TLS1_2_VERSION; - s->method = TLSv1_2_client_method(); - } else { - /* - * Unrecognised version, we'll send a protocol version alert using - * our preferred version. - */ - switch(s->client_version) { - default: - /* - * Shouldn't happen - * Fall through - */ - case TLS1_2_VERSION: - s->version = TLS1_2_VERSION; - s->method = TLSv1_2_client_method(); - break; - case TLS1_1_VERSION: - s->version = TLS1_1_VERSION; - s->method = TLSv1_1_client_method(); - break; - case TLS1_VERSION: - s->version = TLS1_VERSION; - s->method = TLSv1_client_method(); - break; -#ifndef OPENSSL_NO_SSL3 - case SSL3_VERSION: - s->version = SSL3_VERSION; - s->method = SSLv3_client_method(); - break; -#endif - } - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); - goto err; - } - - s->session->ssl_version = s->version; - - /* ensure that TLS_MAX_VERSION is up-to-date */ - OPENSSL_assert(s->version <= TLS_MAX_VERSION); - - if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) { - /* fatal alert */ - - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int j; - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - i = p[5]; - if (cb != NULL) { - j = (i << 8) | p[6]; - cb(s, SSL_CB_READ_ALERT, j); - } - - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); - s->msg_callback(0, s->version, SSL3_RT_ALERT, p + 5, 2, s, - s->msg_callback_arg); - } - - s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_AD_REASON_OFFSET + p[6]); - goto err; - } - - if (!ssl_init_wbio_buffer(s, 1)) - goto err; - - /* we are in this state */ - s->state = SSL3_ST_CR_SRVR_HELLO_A; - - /* - * put the 7 bytes we have read into the input buffer for SSLv3 - */ - s->rstate = SSL_ST_READ_HEADER; - s->packet_length = n; - if (s->s3->rbuf.buf == NULL) - if (!ssl3_setup_read_buffer(s)) - goto err; - s->packet = &(s->s3->rbuf.buf[0]); - memcpy(s->packet, buf, n); - s->s3->rbuf.left = n; - s->s3->rbuf.offset = 0; - - s->handshake_func = s->method->ssl_connect; - } else { - SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNKNOWN_PROTOCOL); - goto err; - } - s->init_num = 0; - - return (SSL_connect(s)); - err: - return (-1); -} -/* ssl/s23_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "objects.h" -// #include "ssl_locl.h" - -long ssl23_default_timeout(void) -{ - return (300); -} - -int ssl23_num_ciphers(void) -{ - return (ssl3_num_ciphers() -#ifndef OPENSSL_NO_SSL2 - + ssl2_num_ciphers() -#endif - ); -} - -const SSL_CIPHER *ssl23_get_cipher(unsigned int u) -{ - unsigned int uu = ssl3_num_ciphers(); - - if (u < uu) - return (ssl3_get_cipher(u)); - else -#ifndef OPENSSL_NO_SSL2 - return (ssl2_get_cipher(u - uu)); -#else - return (NULL); -#endif -} - -/* - * This function needs to check if the ciphers required are actually - * available - */ -const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p) -{ - const SSL_CIPHER *cp; - - cp = ssl3_get_cipher_by_char(p); -#ifndef OPENSSL_NO_SSL2 - if (cp == NULL) - cp = ssl2_get_cipher_by_char(p); -#endif - return (cp); -} - -int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) -{ - long l; - - /* We can write SSLv2 and SSLv3 ciphers */ - /* but no ECC ciphers */ - if (c->algorithm_mkey == SSL_kECDHr || - c->algorithm_mkey == SSL_kECDHe || - c->algorithm_mkey == SSL_kEECDH || - c->algorithm_auth == SSL_aECDH || c->algorithm_auth == SSL_aECDSA) - return 0; - if (p != NULL) { - l = c->id; - p[0] = ((unsigned char)(l >> 16L)) & 0xFF; - p[1] = ((unsigned char)(l >> 8L)) & 0xFF; - p[2] = ((unsigned char)(l)) & 0xFF; - } - return (3); -} - -int ssl23_read(SSL *s, void *buf, int len) -{ - int n; - - clear_sys_error(); - if (SSL_in_init(s) && (!s->in_handshake)) { - n = s->handshake_func(s); - if (n < 0) - return (n); - if (n == 0) { - SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - return (SSL_read(s, buf, len)); - } else { - ssl_undefined_function(s); - return (-1); - } -} - -int ssl23_peek(SSL *s, void *buf, int len) -{ - int n; - - clear_sys_error(); - if (SSL_in_init(s) && (!s->in_handshake)) { - n = s->handshake_func(s); - if (n < 0) - return (n); - if (n == 0) { - SSLerr(SSL_F_SSL23_PEEK, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - return (SSL_peek(s, buf, len)); - } else { - ssl_undefined_function(s); - return (-1); - } -} - -int ssl23_write(SSL *s, const void *buf, int len) -{ - int n; - - clear_sys_error(); - if (SSL_in_init(s) && (!s->in_handshake)) { - n = s->handshake_func(s); - if (n < 0) - return (n); - if (n == 0) { - SSLerr(SSL_F_SSL23_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - return (SSL_write(s, buf, len)); - } else { - ssl_undefined_function(s); - return (-1); - } -} -/* ssl/s23_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "objects.h" -// #include "ssl_locl.h" - -static const SSL_METHOD *ssl23_get_method(int ver); -static const SSL_METHOD *ssl23_get_method(int ver) -{ -#ifndef OPENSSL_NO_SSL2 - if (ver == SSL2_VERSION) - return (SSLv2_method()); - else -#endif -#ifndef OPENSSL_NO_SSL3 - if (ver == SSL3_VERSION) - return (SSLv3_method()); - else -#endif -#ifndef OPENSSL_NO_TLS1 - if (ver == TLS1_VERSION) - return (TLSv1_method()); - else if (ver == TLS1_1_VERSION) - return (TLSv1_1_method()); - else if (ver == TLS1_2_VERSION) - return (TLSv1_2_method()); - else -#endif - return (NULL); -} - -IMPLEMENT_ssl23_meth_func(SSLv23_method, - ssl23_accept, ssl23_connect, ssl23_get_method) -/* ssl/s23_pkt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#define USE_SOCKETS -// #include "ssl_locl.h" -// #include "evp.h" -// #include "buffer.h" - -/* - * Return values are as per SSL_write() - */ -int ssl23_write_bytes(SSL *s) -{ - int i, num, tot; - char *buf; - - buf = s->init_buf->data; - tot = s->init_off; - num = s->init_num; - for (;;) { - s->rwstate = SSL_WRITING; - i = BIO_write(s->wbio, &(buf[tot]), num); - if (i <= 0) { - s->init_off = tot; - s->init_num = num; - return i; - } - s->rwstate = SSL_NOTHING; - if (i == num) - return (tot + i); - - num -= i; - tot += i; - } -} - -/* return regularly only when we have read (at least) 'n' bytes - * - * Return values are as per SSL_read() - */ -int ssl23_read_bytes(SSL *s, int n) -{ - unsigned char *p; - int j; - - if (s->packet_length < (unsigned int)n) { - p = s->packet; - - for (;;) { - s->rwstate = SSL_READING; - j = BIO_read(s->rbio, (char *)&(p[s->packet_length]), - n - s->packet_length); - if (j <= 0) - return j; - s->rwstate = SSL_NOTHING; - s->packet_length += j; - if (s->packet_length >= (unsigned int)n) - return (s->packet_length); - } - } - return (n); -} -/* ssl/s23_srvr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "ssl_locl.h" -// #include "buffer.h" -// #include "rand.h" -// #include "objects.h" -// #include "evp.h" -#ifdef OPENSSL_FIPS -# include -#endif - -static const SSL_METHOD *ssl23_get_server_method(int ver); -int ssl23_get_client_hello(SSL *s); -static const SSL_METHOD *ssl23_get_server_method(int ver) -{ -#ifndef OPENSSL_NO_SSL2 - if (ver == SSL2_VERSION) - return (SSLv2_server_method()); -#endif -#ifndef OPENSSL_NO_SSL3 - if (ver == SSL3_VERSION) - return (SSLv3_server_method()); -#endif - if (ver == TLS1_VERSION) - return (TLSv1_server_method()); - else if (ver == TLS1_1_VERSION) - return (TLSv1_1_server_method()); - else if (ver == TLS1_2_VERSION) - return (TLSv1_2_server_method()); - else - return (NULL); -} - -IMPLEMENT_ssl23_meth_func(SSLv23_server_method, - ssl23_accept, - ssl_undefined_function, ssl23_get_server_method) - -int ssl23_accept(SSL *s) -{ - BUF_MEM *buf; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state; - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_BEFORE: - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - case SSL_ST_OK | SSL_ST_ACCEPT: - - s->server = 1; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - /* s->version=SSL3_VERSION; */ - s->type = SSL_ST_ACCEPT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - BUF_MEM_free(buf); - ret = -1; - goto end; - } - s->init_buf = buf; - } - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - goto end; - } - - s->state = SSL23_ST_SR_CLNT_HELLO_A; - s->ctx->stats.sess_accept++; - s->init_num = 0; - break; - - case SSL23_ST_SR_CLNT_HELLO_A: - case SSL23_ST_SR_CLNT_HELLO_B: - - s->shutdown = 0; - ret = ssl23_get_client_hello(s); - if (ret >= 0) - cb = NULL; - goto end; - /* break; */ - - default: - SSLerr(SSL_F_SSL23_ACCEPT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; - } - } - end: - s->in_handshake--; - if (cb != NULL) - cb(s, SSL_CB_ACCEPT_EXIT, ret); - return (ret); -} - -int ssl23_get_client_hello(SSL *s) -{ - /*- - * Request this many bytes in initial read. - * We can detect SSL 3.0/TLS 1.0 Client Hellos - * ('type == 3') correctly only when the following - * is in a single record, which is not guaranteed by - * the protocol specification: - * Byte Content - * 0 type \ - * 1/2 version > record header - * 3/4 length / - * 5 msg_type \ - * 6-8 length > Client Hello message - * 9/10 client_version / - */ - char buf_space[11]; - char *buf = &(buf_space[0]); - unsigned char *p, *d, *d_len, *dd; - unsigned int i; - unsigned int csl, sil, cl; - int n = 0, j; - int type = 0; - int v[2]; - - if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { - /* read the initial header */ - v[0] = v[1] = 0; - - if (!ssl3_setup_buffers(s)) - goto err; - - n = ssl23_read_bytes(s, sizeof(buf_space)); - if (n != sizeof(buf_space)) - return (n); /* n == -1 || n == 0 */ - - p = s->packet; - - memcpy(buf, p, n); - - if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { - /* - * SSLv2 header - */ - if ((p[3] == 0x00) && (p[4] == 0x02)) { - v[0] = p[3]; - v[1] = p[4]; - /* SSLv2 */ - if (!(s->options & SSL_OP_NO_SSLv2)) - type = 1; - } else if (p[3] == SSL3_VERSION_MAJOR) { - v[0] = p[3]; - v[1] = p[4]; - /* SSLv3/TLSv1 */ - if (p[4] >= TLS1_VERSION_MINOR) { - if (p[4] >= TLS1_2_VERSION_MINOR && - !(s->options & SSL_OP_NO_TLSv1_2)) { - s->version = TLS1_2_VERSION; - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (p[4] >= TLS1_1_VERSION_MINOR && - !(s->options & SSL_OP_NO_TLSv1_1)) { - s->version = TLS1_1_VERSION; - /* - * type=2; - *//* - * done later to survive restarts - */ - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (!(s->options & SSL_OP_NO_TLSv1)) { - s->version = TLS1_VERSION; - /* - * type=2; - *//* - * done later to survive restarts - */ - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (!(s->options & SSL_OP_NO_SSLv3)) { - s->version = SSL3_VERSION; - /* type=2; */ - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (!(s->options & SSL_OP_NO_SSLv2)) { - type = 1; - } - } else if (!(s->options & SSL_OP_NO_SSLv3)) { - s->version = SSL3_VERSION; - /* type=2; */ - s->state = SSL23_ST_SR_CLNT_HELLO_B; - } else if (!(s->options & SSL_OP_NO_SSLv2)) - type = 1; - - } - } - /* p[4] < 5 ... silly record length? */ - else if ((p[0] == SSL3_RT_HANDSHAKE) && - (p[1] == SSL3_VERSION_MAJOR) && - (p[5] == SSL3_MT_CLIENT_HELLO) && ((p[3] == 0 && p[4] < 5) - || (p[9] >= p[1]))) { - /* - * SSLv3 or tls1 header - */ - - v[0] = p[1]; /* major version (= SSL3_VERSION_MAJOR) */ - /* - * We must look at client_version inside the Client Hello message - * to get the correct minor version. However if we have only a - * pathologically small fragment of the Client Hello message, this - * would be difficult, and we'd have to read more records to find - * out. No known SSL 3.0 client fragments ClientHello like this, - * so we simply reject such connections to avoid protocol version - * downgrade attacks. - */ - if (p[3] == 0 && p[4] < 6) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_SMALL); - goto err; - } - /* - * if major version number > 3 set minor to a value which will - * use the highest version 3 we support. If TLS 2.0 ever appears - * we will need to revise this.... - */ - if (p[9] > SSL3_VERSION_MAJOR) - v[1] = 0xff; - else - v[1] = p[10]; /* minor version according to client_version */ - if (v[1] >= TLS1_VERSION_MINOR) { - if (v[1] >= TLS1_2_VERSION_MINOR && - !(s->options & SSL_OP_NO_TLSv1_2)) { - s->version = TLS1_2_VERSION; - type = 3; - } else if (v[1] >= TLS1_1_VERSION_MINOR && - !(s->options & SSL_OP_NO_TLSv1_1)) { - s->version = TLS1_1_VERSION; - type = 3; - } else if (!(s->options & SSL_OP_NO_TLSv1)) { - s->version = TLS1_VERSION; - type = 3; - } else if (!(s->options & SSL_OP_NO_SSLv3)) { - s->version = SSL3_VERSION; - type = 3; - } - } else { - /* client requests SSL 3.0 */ - if (!(s->options & SSL_OP_NO_SSLv3)) { - s->version = SSL3_VERSION; - type = 3; - } else if (!(s->options & SSL_OP_NO_TLSv1)) { - /* - * we won't be able to use TLS of course, but this will - * send an appropriate alert - */ - s->version = TLS1_VERSION; - type = 3; - } - } - } else if ((strncmp("GET ", (char *)p, 4) == 0) || - (strncmp("POST ", (char *)p, 5) == 0) || - (strncmp("HEAD ", (char *)p, 5) == 0) || - (strncmp("PUT ", (char *)p, 4) == 0)) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTP_REQUEST); - goto err; - } else if (strncmp("CONNECT", (char *)p, 7) == 0) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTPS_PROXY_REQUEST); - goto err; - } - } - - /* ensure that TLS_MAX_VERSION is up-to-date */ - OPENSSL_assert(s->version <= TLS_MAX_VERSION); - - if (s->version < TLS1_2_VERSION && tls1_suiteb(s)) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); - goto err; - } -#ifdef OPENSSL_FIPS - if (FIPS_mode() && (s->version < TLS1_VERSION)) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - goto err; - } -#endif - - if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { - /* - * we have SSLv3/TLSv1 in an SSLv2 header (other cases skip this - * state) - */ - - type = 2; - p = s->packet; - v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ - v[1] = p[4]; - - /*- - * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 - * header is sent directly on the wire, not wrapped as a TLS - * record. It's format is: - * Byte Content - * 0-1 msg_length - * 2 msg_type - * 3-4 version - * 5-6 cipher_spec_length - * 7-8 session_id_length - * 9-10 challenge_length - * ... ... - */ - n = ((p[0] & 0x7f) << 8) | p[1]; - if (n > (1024 * 4)) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_LARGE); - goto err; - } - if (n < 9) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_RECORD_LENGTH_MISMATCH); - goto err; - } - - j = ssl23_read_bytes(s, n + 2); - /* - * We previously read 11 bytes, so if j > 0, we must have j == n+2 == - * s->packet_length. We have at least 11 valid packet bytes. - */ - if (j <= 0) - return (j); - - ssl3_finish_mac(s, s->packet + 2, s->packet_length - 2); - - /* CLIENT-HELLO */ - if (s->msg_callback) - s->msg_callback(0, SSL2_VERSION, 0, s->packet + 2, - s->packet_length - 2, s, s->msg_callback_arg); - - p = s->packet; - p += 5; - n2s(p, csl); - n2s(p, sil); - n2s(p, cl); - d = (unsigned char *)s->init_buf->data; - if ((csl + sil + cl + 11) != s->packet_length) { /* We can't have TLS - * extensions in SSL - * 2.0 format * - * Client Hello, can - * we? Error - * condition should - * be * '>' - * otherweise */ - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, - SSL_R_RECORD_LENGTH_MISMATCH); - goto err; - } - - /* record header: msg_type ... */ - *(d++) = SSL3_MT_CLIENT_HELLO; - /* ... and length (actual value will be written later) */ - d_len = d; - d += 3; - - /* client_version */ - *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ - *(d++) = v[1]; - - /* lets populate the random area */ - /* get the challenge_length */ - i = (cl > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : cl; - memset(d, 0, SSL3_RANDOM_SIZE); - memcpy(&(d[SSL3_RANDOM_SIZE - i]), &(p[csl + sil]), i); - d += SSL3_RANDOM_SIZE; - - /* no session-id reuse */ - *(d++) = 0; - - /* ciphers */ - j = 0; - dd = d; - d += 2; - for (i = 0; i < csl; i += 3) { - if (p[i] != 0) - continue; - *(d++) = p[i + 1]; - *(d++) = p[i + 2]; - j += 2; - } - s2n(j, dd); - - /* COMPRESSION */ - *(d++) = 1; - *(d++) = 0; - -#if 0 - /* copy any remaining data with may be extensions */ - p = p + csl + sil + cl; - while (p < s->packet + s->packet_length) { - *(d++) = *(p++); - } -#endif - - i = (d - (unsigned char *)s->init_buf->data) - 4; - l2n3((long)i, d_len); - - /* get the data reused from the init_buf */ - s->s3->tmp.reuse_message = 1; - s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; - s->s3->tmp.message_size = i; - } - - /* imaginary new state (for program structure): */ - /* s->state = SSL23_SR_CLNT_HELLO_C */ - - if (type == 1) { -#ifdef OPENSSL_NO_SSL2 - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; -#else - /* we are talking sslv2 */ - /* - * we need to clean up the SSLv3/TLSv1 setup and put in the sslv2 - * stuff. - */ - - if (s->s2 == NULL) { - if (!ssl2_new(s)) - goto err; - } else - ssl2_clear(s); - - if (s->s3 != NULL) - ssl3_free(s); - - if (!BUF_MEM_grow_clean(s->init_buf, - SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { - goto err; - } - - s->state = SSL2_ST_GET_CLIENT_HELLO_A; - if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3) - s->s2->ssl2_rollback = 0; - else - /* - * reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0 - * (SSL 3.0 draft/RFC 2246, App. E.2) - */ - s->s2->ssl2_rollback = 1; - - /* - * setup the n bytes we have read so we get them from the sslv2 - * buffer - */ - s->rstate = SSL_ST_READ_HEADER; - s->packet_length = n; - s->packet = &(s->s2->rbuf[0]); - memcpy(s->packet, buf, n); - s->s2->rbuf_left = n; - s->s2->rbuf_offs = 0; - - s->method = SSLv2_server_method(); - s->handshake_func = s->method->ssl_accept; -#endif - } - - if ((type == 2) || (type == 3)) { - /* - * we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) - */ - const SSL_METHOD *new_method; - new_method = ssl23_get_server_method(s->version); - if (new_method == NULL) { - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); - goto err; - } - s->method = new_method; - - if (!ssl_init_wbio_buffer(s, 1)) - goto err; - - /* we are in this state */ - s->state = SSL3_ST_SR_CLNT_HELLO_A; - - if (type == 3) { - /* - * put the 'n' bytes we have read into the input buffer for SSLv3 - */ - s->rstate = SSL_ST_READ_HEADER; - s->packet_length = n; - if (s->s3->rbuf.buf == NULL) - if (!ssl3_setup_read_buffer(s)) - goto err; - - s->packet = &(s->s3->rbuf.buf[0]); - memcpy(s->packet, buf, n); - s->s3->rbuf.left = n; - s->s3->rbuf.offset = 0; - } else { - s->packet_length = 0; - s->s3->rbuf.left = 0; - s->s3->rbuf.offset = 0; - } -#if 0 /* ssl3_get_client_hello does this */ - s->client_version = (v[0] << 8) | v[1]; -#endif - s->handshake_func = s->method->ssl_accept; - } - - if ((type < 1) || (type > 3)) { - /* bad, very bad */ - SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); - goto err; - } - s->init_num = 0; - - if (buf != buf_space) - OPENSSL_free(buf); - return (SSL_accept(s)); - err: - if (buf != buf_space) - OPENSSL_free(buf); - return (-1); -} diff --git a/Sources/COpenSSL/s2_.c b/Sources/COpenSSL/s2_.c deleted file mode 100644 index cbee1941..00000000 --- a/Sources/COpenSSL/s2_.c +++ /dev/null @@ -1,3850 +0,0 @@ -/* ssl/s2_clnt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -# include -# include "rand.h" -# include "buffer.h" -# include "objects.h" -# include "evp.h" - -static const SSL_METHOD *ssl2_get_client_method(int ver); -static int get_server_finished(SSL *s); -static int get_server_verify(SSL *s); -static int get_server_hello(SSL *s); -static int client_hello(SSL *s); -static int client_master_key(SSL *s); -static int client_finished(SSL *s); -static int client_certificate(SSL *s); -static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, - unsigned char *to, int padding); -# define BREAK break - -static const SSL_METHOD *ssl2_get_client_method(int ver) -{ - if (ver == SSL2_VERSION) - return (SSLv2_client_method()); - else - return (NULL); -} - -IMPLEMENT_ssl2_meth_func(SSLv2_client_method, - ssl_undefined_function, - ssl2_connect, ssl2_get_client_method) - -int ssl2_connect(SSL *s) -{ - unsigned long l = (unsigned long)time(NULL); - BUF_MEM *buf = NULL; - int ret = -1; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int new_state, state; - - RAND_add(&l, sizeof(l), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - /* init things to blank */ - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_BEFORE: - case SSL_ST_CONNECT: - case SSL_ST_BEFORE | SSL_ST_CONNECT: - case SSL_ST_OK | SSL_ST_CONNECT: - - s->server = 0; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - s->version = SSL2_VERSION; - s->type = SSL_ST_CONNECT; - - buf = s->init_buf; - if ((buf == NULL) && ((buf = BUF_MEM_new()) == NULL)) { - ret = -1; - goto end; - } - if (!BUF_MEM_grow(buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { - if (buf == s->init_buf) - buf = NULL; - ret = -1; - goto end; - } - s->init_buf = buf; - buf = NULL; - s->init_num = 0; - s->state = SSL2_ST_SEND_CLIENT_HELLO_A; - s->ctx->stats.sess_connect++; - s->handshake_func = ssl2_connect; - BREAK; - - case SSL2_ST_SEND_CLIENT_HELLO_A: - case SSL2_ST_SEND_CLIENT_HELLO_B: - s->shutdown = 0; - ret = client_hello(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_GET_SERVER_HELLO_A; - BREAK; - - case SSL2_ST_GET_SERVER_HELLO_A: - case SSL2_ST_GET_SERVER_HELLO_B: - ret = get_server_hello(s); - if (ret <= 0) - goto end; - s->init_num = 0; - if (!s->hit) { /* new session */ - s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_A; - BREAK; - } else { - s->state = SSL2_ST_CLIENT_START_ENCRYPTION; - break; - } - - case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: - case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: - ret = client_master_key(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_CLIENT_START_ENCRYPTION; - break; - - case SSL2_ST_CLIENT_START_ENCRYPTION: - /* - * Ok, we now have all the stuff needed to start encrypting, so - * lets fire it up :-) - */ - if (!ssl2_enc_init(s, 1)) { - ret = -1; - goto end; - } - s->s2->clear_text = 0; - s->state = SSL2_ST_SEND_CLIENT_FINISHED_A; - break; - - case SSL2_ST_SEND_CLIENT_FINISHED_A: - case SSL2_ST_SEND_CLIENT_FINISHED_B: - ret = client_finished(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_GET_SERVER_VERIFY_A; - break; - - case SSL2_ST_GET_SERVER_VERIFY_A: - case SSL2_ST_GET_SERVER_VERIFY_B: - ret = get_server_verify(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_GET_SERVER_FINISHED_A; - break; - - case SSL2_ST_GET_SERVER_FINISHED_A: - case SSL2_ST_GET_SERVER_FINISHED_B: - ret = get_server_finished(s); - if (ret <= 0) - goto end; - break; - - case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: - case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: - case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: - case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: - case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: - ret = client_certificate(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_GET_SERVER_FINISHED_A; - break; - - case SSL_ST_OK: - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } - s->init_num = 0; - /* ERR_clear_error(); */ - - /* - * If we want to cache session-ids in the client and we - * successfully add the session-id to the cache, and there is a - * callback, then pass it out. 26/11/96 - eay - only add if not a - * re-used session. - */ - - ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); - if (s->hit) - s->ctx->stats.sess_hit++; - - ret = 1; - /* s->server=0; */ - s->ctx->stats.sess_connect_good++; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - - goto end; - /* break; */ - default: - SSLerr(SSL_F_SSL2_CONNECT, SSL_R_UNKNOWN_STATE); - return (-1); - /* break; */ - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; - } - } - end: - s->in_handshake--; - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s, SSL_CB_CONNECT_EXIT, ret); - return (ret); -} - -static int get_server_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p; - int i, j; - unsigned long len; - STACK_OF(SSL_CIPHER) *sk = NULL, *cl, *prio, *allow; - - buf = (unsigned char *)s->init_buf->data; - p = buf; - if (s->state == SSL2_ST_GET_SERVER_HELLO_A) { - i = ssl2_read(s, (char *)&(buf[s->init_num]), 11 - s->init_num); - if (i < (11 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i)); - s->init_num = 11; - - if (*(p++) != SSL2_MT_SERVER_HELLO) { - if (p[-1] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_READ_WRONG_PACKET_TYPE); - } else - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_PEER_ERROR); - return (-1); - } -# if 0 - s->hit = (*(p++)) ? 1 : 0; - /* - * Some [PPC?] compilers fail to increment p in above statement, e.g. - * one provided with Rhapsody 5.5, but most recent example XL C 11.1 - * for AIX, even without optimization flag... - */ -# else - s->hit = (*p) ? 1 : 0; - p++; -# endif - s->s2->tmp.cert_type = *(p++); - n2s(p, i); - if (i < s->version) - s->version = i; - n2s(p, i); - s->s2->tmp.cert_length = i; - n2s(p, i); - s->s2->tmp.csl = i; - n2s(p, i); - s->s2->tmp.conn_id_length = i; - s->state = SSL2_ST_GET_SERVER_HELLO_B; - } - - /* SSL2_ST_GET_SERVER_HELLO_B */ - len = - 11 + (unsigned long)s->s2->tmp.cert_length + - (unsigned long)s->s2->tmp.csl + - (unsigned long)s->s2->tmp.conn_id_length; - if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_MESSAGE_TOO_LONG); - return -1; - } - j = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(buf[s->init_num]), j); - if (i != j) - return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i)); - if (s->msg_callback) { - /* SERVER-HELLO */ - s->msg_callback(0, s->version, 0, buf, (size_t)len, s, - s->msg_callback_arg); - } - - /* things are looking good */ - - p = buf + 11; - if (s->hit) { - if (s->s2->tmp.cert_length != 0) { - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CERT_LENGTH_NOT_ZERO); - return (-1); - } - if (s->s2->tmp.cert_type != 0) { - if (!(s->options & SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)) { - SSLerr(SSL_F_GET_SERVER_HELLO, - SSL_R_REUSE_CERT_TYPE_NOT_ZERO); - return (-1); - } - } - if (s->s2->tmp.csl != 0) { - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CIPHER_LIST_NOT_ZERO); - return (-1); - } - } else { -# if 0 - /* very bad */ - memset(s->session->session_id, 0, - SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES); - s->session->session_id_length = 0; -# endif - - /* - * we need to do this in case we were trying to reuse a client - * session but others are already reusing it. If this was a new - * 'blank' session ID, the session-id length will still be 0 - */ - if (s->session->session_id_length > 0) { - if (!ssl_get_new_session(s, 0)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } - - if (ssl2_set_certificate(s, s->s2->tmp.cert_type, - s->s2->tmp.cert_length, p) <= 0) { - ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); - return (-1); - } - p += s->s2->tmp.cert_length; - - if (s->s2->tmp.csl == 0) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_LIST); - return (-1); - } - - /* - * We have just received a list of ciphers back from the server. We - * need to get the ones that match, then select the one we want the - * most :-). - */ - - /* load the ciphers */ - sk = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.csl, - &s->session->ciphers); - p += s->s2->tmp.csl; - if (sk == NULL) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_MALLOC_FAILURE); - return (-1); - } - - (void)sk_SSL_CIPHER_set_cmp_func(sk, ssl_cipher_ptr_id_cmp); - - /* get the array of ciphers we will accept */ - cl = SSL_get_ciphers(s); - (void)sk_SSL_CIPHER_set_cmp_func(cl, ssl_cipher_ptr_id_cmp); - - /* - * If server preference flag set, choose the first - * (highest priority) cipher the server sends, otherwise - * client preference has priority. - */ - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { - prio = sk; - allow = cl; - } else { - prio = cl; - allow = sk; - } - /* - * In theory we could have ciphers sent back that we don't want to - * use but that does not matter since we will check against the list - * we originally sent and for performance reasons we should not - * bother to match the two lists up just to check. - */ - for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { - if (sk_SSL_CIPHER_find(allow, sk_SSL_CIPHER_value(prio, i)) >= 0) - break; - } - - if (i >= sk_SSL_CIPHER_num(prio)) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_MATCH); - return (-1); - } - s->session->cipher = sk_SSL_CIPHER_value(prio, i); - - if (s->session->peer != NULL) { /* can't happen */ - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - return (-1); - } - - s->session->peer = s->session->sess_cert->peer_key->x509; - /* peer_key->x509 has been set by ssl2_set_certificate. */ - CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509); - } - - if (s->session->sess_cert == NULL - || s->session->peer != s->session->sess_cert->peer_key->x509) - /* can't happen */ - { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - return (-1); - } - - s->s2->conn_id_length = s->s2->tmp.conn_id_length; - if (s->s2->conn_id_length > sizeof(s->s2->conn_id)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG); - return -1; - } - memcpy(s->s2->conn_id, p, s->s2->tmp.conn_id_length); - return (1); -} - -static int client_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; -/* CIPHER **cipher;*/ - int i, n, j; - - buf = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A) { - if ((s->session == NULL) || (s->session->ssl_version != s->version)) { - if (!ssl_get_new_session(s, 0)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } - /* else use the pre-loaded session */ - - p = buf; /* header */ - d = p + 9; /* data section */ - *(p++) = SSL2_MT_CLIENT_HELLO; /* type */ - s2n(SSL2_VERSION, p); /* version */ - n = j = 0; - - n = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), d, 0); - d += n; - - if (n == 0) { - SSLerr(SSL_F_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); - return (-1); - } - - s2n(n, p); /* cipher spec num bytes */ - - if ((s->session->session_id_length > 0) && - (s->session->session_id_length <= - SSL2_MAX_SSL_SESSION_ID_LENGTH)) { - i = s->session->session_id_length; - s2n(i, p); /* session id length */ - memcpy(d, s->session->session_id, (unsigned int)i); - d += i; - } else { - s2n(0, p); - } - - s->s2->challenge_length = SSL2_CHALLENGE_LENGTH; - s2n(SSL2_CHALLENGE_LENGTH, p); /* challenge length */ - /* - * challenge id data - */ - if (RAND_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) - return -1; - memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH); - d += SSL2_CHALLENGE_LENGTH; - - s->state = SSL2_ST_SEND_CLIENT_HELLO_B; - s->init_num = d - buf; - s->init_off = 0; - } - /* SSL2_ST_SEND_CLIENT_HELLO_B */ - return (ssl2_do_write(s)); -} - -static int client_master_key(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int clear, enc, karg, i; - SSL_SESSION *sess; - const EVP_CIPHER *c; - const EVP_MD *md; - - buf = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) { - - if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_CLIENT_MASTER_KEY, - SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); - return (-1); - } - sess = s->session; - p = buf; - d = p + 10; - *(p++) = SSL2_MT_CLIENT_MASTER_KEY; /* type */ - - i = ssl_put_cipher_by_char(s, sess->cipher, p); - p += i; - - /* make key_arg data */ - i = EVP_CIPHER_iv_length(c); - sess->key_arg_length = i; - if (i > SSL_MAX_KEY_ARG_LENGTH) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - if (i > 0) - if (RAND_bytes(sess->key_arg, i) <= 0) - return -1; - - /* make a master key */ - i = EVP_CIPHER_key_length(c); - sess->master_key_length = i; - if (i > 0) { - if (i > (int)sizeof(sess->master_key)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - if (RAND_bytes(sess->master_key, i) <= 0) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } - - if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) - enc = 8; - else if (SSL_C_IS_EXPORT(sess->cipher)) - enc = 5; - else - enc = i; - - if ((int)i < enc) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_CIPHER_TABLE_SRC_ERROR); - return (-1); - } - clear = i - enc; - s2n(clear, p); - memcpy(d, sess->master_key, (unsigned int)clear); - d += clear; - - enc = ssl_rsa_public_encrypt(sess->sess_cert, enc, - &(sess->master_key[clear]), d, - (s-> - s2->ssl2_rollback) ? RSA_SSLV23_PADDING - : RSA_PKCS1_PADDING); - if (enc <= 0) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_PUBLIC_KEY_ENCRYPT_ERROR); - return (-1); - } -# ifdef PKCS1_CHECK - if (s->options & SSL_OP_PKCS1_CHECK_1) - d[1]++; - if (s->options & SSL_OP_PKCS1_CHECK_2) - sess->master_key[clear]++; -# endif - s2n(enc, p); - d += enc; - karg = sess->key_arg_length; - s2n(karg, p); /* key arg size */ - if (karg > (int)sizeof(sess->key_arg)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(d, sess->key_arg, (unsigned int)karg); - d += karg; - - s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_B; - s->init_num = d - buf; - s->init_off = 0; - } - - /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */ - return (ssl2_do_write(s)); -} - -static int client_finished(SSL *s) -{ - unsigned char *p; - - if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A) { - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL2_MT_CLIENT_FINISHED; - if (s->s2->conn_id_length > sizeof(s->s2->conn_id)) { - SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(p, s->s2->conn_id, (unsigned int)s->s2->conn_id_length); - - s->state = SSL2_ST_SEND_CLIENT_FINISHED_B; - s->init_num = s->s2->conn_id_length + 1; - s->init_off = 0; - } - return (ssl2_do_write(s)); -} - -/* read the data and then respond */ -static int client_certificate(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int i; - unsigned int n; - int cert_ch_len; - unsigned char *cert_ch; - - buf = (unsigned char *)s->init_buf->data; - - /* - * We have a cert associated with the SSL, so attach it to the session if - * it does not have one - */ - - if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A) { - i = ssl2_read(s, (char *)&(buf[s->init_num]), - SSL2_MAX_CERT_CHALLENGE_LENGTH + 2 - s->init_num); - if (i < (SSL2_MIN_CERT_CHALLENGE_LENGTH + 2 - s->init_num)) - return (ssl2_part_read(s, SSL_F_CLIENT_CERTIFICATE, i)); - s->init_num += i; - if (s->msg_callback) { - /* REQUEST-CERTIFICATE */ - s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, - s->msg_callback_arg); - } - - /* type=buf[0]; */ - /* type eq x509 */ - if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { - ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); - SSLerr(SSL_F_CLIENT_CERTIFICATE, SSL_R_BAD_AUTHENTICATION_TYPE); - return (-1); - } - - if ((s->cert == NULL) || - (s->cert->key->x509 == NULL) || - (s->cert->key->privatekey == NULL)) { - s->state = SSL2_ST_X509_GET_CLIENT_CERTIFICATE; - } else - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C; - } - - cert_ch = buf + 2; - cert_ch_len = s->init_num - 2; - - if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE) { - X509 *x509 = NULL; - EVP_PKEY *pkey = NULL; - - /* - * If we get an error we need to ssl->rwstate=SSL_X509_LOOKUP; - * return(error); We should then be retried when things are ok and we - * can get a cert or not - */ - - i = 0; - if (s->ctx->client_cert_cb != NULL) { - i = s->ctx->client_cert_cb(s, &(x509), &(pkey)); - } - - if (i < 0) { - s->rwstate = SSL_X509_LOOKUP; - return (-1); - } - s->rwstate = SSL_NOTHING; - - if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C; - if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) { - i = 0; - } - X509_free(x509); - EVP_PKEY_free(pkey); - } else if (i == 1) { - if (x509 != NULL) - X509_free(x509); - if (pkey != NULL) - EVP_PKEY_free(pkey); - SSLerr(SSL_F_CLIENT_CERTIFICATE, - SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); - i = 0; - } - - if (i == 0) { - /* - * We have no client certificate to respond with so send the - * correct error message back - */ - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_B; - p = buf; - *(p++) = SSL2_MT_ERROR; - s2n(SSL2_PE_NO_CERTIFICATE, p); - s->init_off = 0; - s->init_num = 3; - /* Write is done at the end */ - } - } - - if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B) { - return (ssl2_do_write(s)); - } - - if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C) { - EVP_MD_CTX ctx; - - /* - * ok, now we calculate the checksum do it first so we can reuse buf - * :-) - */ - p = buf; - EVP_MD_CTX_init(&ctx); - EVP_SignInit_ex(&ctx, s->ctx->rsa_md5, NULL); - EVP_SignUpdate(&ctx, s->s2->key_material, s->s2->key_material_length); - EVP_SignUpdate(&ctx, cert_ch, (unsigned int)cert_ch_len); - i = i2d_X509(s->session->sess_cert->peer_key->x509, &p); - /* - * Don't update the signature if it fails - FIXME: probably should - * handle this better - */ - if (i > 0) - EVP_SignUpdate(&ctx, buf, (unsigned int)i); - - p = buf; - d = p + 6; - *(p++) = SSL2_MT_CLIENT_CERTIFICATE; - *(p++) = SSL2_CT_X509_CERTIFICATE; - n = i2d_X509(s->cert->key->x509, &d); - s2n(n, p); - - if (!EVP_SignFinal(&ctx, d, &n, s->cert->key->privatekey)) { - /* - * this is not good. If things have failed it means there so - * something wrong with the key. We will continue with a 0 length - * signature - */ - } - EVP_MD_CTX_cleanup(&ctx); - s2n(n, p); - d += n; - - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_D; - s->init_num = d - buf; - s->init_off = 0; - } - /* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */ - return (ssl2_do_write(s)); -} - -static int get_server_verify(SSL *s) -{ - unsigned char *p; - int i, n, len; - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_GET_SERVER_VERIFY_A) { - i = ssl2_read(s, (char *)&(p[s->init_num]), 1 - s->init_num); - if (i < (1 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i)); - s->init_num += i; - - s->state = SSL2_ST_GET_SERVER_VERIFY_B; - if (*p != SSL2_MT_SERVER_VERIFY) { - if (p[0] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_READ_WRONG_PACKET_TYPE); - } else { - SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_PEER_ERROR); - /* try to read the error message */ - i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); - return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); - } - return (-1); - } - } - - p = (unsigned char *)s->init_buf->data; - len = 1 + s->s2->challenge_length; - n = len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), n); - if (i < n) - return (ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i)); - if (s->msg_callback) { - /* SERVER-VERIFY */ - s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); - } - p += 1; - - if (CRYPTO_memcmp(p, s->s2->challenge, s->s2->challenge_length) != 0) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_CHALLENGE_IS_DIFFERENT); - return (-1); - } - return (1); -} - -static int get_server_finished(SSL *s) -{ - unsigned char *buf; - unsigned char *p; - int i, n, len; - - buf = (unsigned char *)s->init_buf->data; - p = buf; - if (s->state == SSL2_ST_GET_SERVER_FINISHED_A) { - i = ssl2_read(s, (char *)&(buf[s->init_num]), 1 - s->init_num); - if (i < (1 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i)); - s->init_num += i; - - if (*p == SSL2_MT_REQUEST_CERTIFICATE) { - s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_A; - return (1); - } else if (*p != SSL2_MT_SERVER_FINISHED) { - if (p[0] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_FINISHED, - SSL_R_READ_WRONG_PACKET_TYPE); - } else { - SSLerr(SSL_F_GET_SERVER_FINISHED, SSL_R_PEER_ERROR); - /* try to read the error message */ - i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); - return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); - } - return (-1); - } - s->state = SSL2_ST_GET_SERVER_FINISHED_B; - } - - len = 1 + SSL2_SSL_SESSION_ID_LENGTH; - n = len - s->init_num; - i = ssl2_read(s, (char *)&(buf[s->init_num]), n); - if (i < n) { - /* - * XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH, - * that's the maximum - */ - return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i)); - } - s->init_num += i; - if (s->msg_callback) { - /* SERVER-FINISHED */ - s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, - s->msg_callback_arg); - } - - if (!s->hit) { /* new session */ - /* new session-id */ - /* - * Make sure we were not trying to re-use an old SSL_SESSION or bad - * things can happen - */ - /* ZZZZZZZZZZZZZ */ - s->session->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; - memcpy(s->session->session_id, p + 1, SSL2_SSL_SESSION_ID_LENGTH); - } else { - if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG)) { - if ((s->session->session_id_length > - sizeof(s->session->session_id)) - || (0 != - memcmp(buf + 1, s->session->session_id, - (unsigned int)s->session->session_id_length))) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_SERVER_FINISHED, - SSL_R_SSL_SESSION_ID_IS_DIFFERENT); - return (-1); - } - } - } - s->state = SSL_ST_OK; - return (1); -} - -/* loads in the certificate from the server */ -int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data) -{ - STACK_OF(X509) *sk = NULL; - EVP_PKEY *pkey = NULL; - SESS_CERT *sc = NULL; - int i; - X509 *x509 = NULL; - int ret = 0; - - x509 = d2i_X509(NULL, &data, (long)len); - if (x509 == NULL) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_X509_LIB); - goto err; - } - - if ((sk = sk_X509_new_null()) == NULL || !sk_X509_push(sk, x509)) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - - i = ssl_verify_cert_chain(s, sk); - - if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_CERTIFICATE_VERIFY_FAILED); - goto err; - } - ERR_clear_error(); /* but we keep s->verify_result */ - s->session->verify_result = s->verify_result; - - /* server's cert for this session */ - sc = ssl_sess_cert_new(); - if (sc == NULL) { - ret = -1; - goto err; - } - if (s->session->sess_cert) - ssl_sess_cert_free(s->session->sess_cert); - s->session->sess_cert = sc; - - sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509 = x509; - sc->peer_key = &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]); - - pkey = X509_get_pubkey(x509); - x509 = NULL; - if (pkey == NULL) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, - SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY); - goto err; - } - if (pkey->type != EVP_PKEY_RSA) { - SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_PUBLIC_KEY_NOT_RSA); - goto err; - } - - if (!ssl_set_peer_cert_type(sc, SSL2_CT_X509_CERTIFICATE)) - goto err; - ret = 1; - err: - sk_X509_free(sk); - X509_free(x509); - EVP_PKEY_free(pkey); - return (ret); -} - -static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, - unsigned char *to, int padding) -{ - EVP_PKEY *pkey = NULL; - int i = -1; - - if ((sc == NULL) || (sc->peer_key->x509 == NULL) || - ((pkey = X509_get_pubkey(sc->peer_key->x509)) == NULL)) { - SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_NO_PUBLICKEY); - return (-1); - } - if (pkey->type != EVP_PKEY_RSA) { - SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA); - goto end; - } - - /* we have the public key */ - i = RSA_public_encrypt(len, from, to, pkey->pkey.rsa, padding); - if (i < 0) - SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, ERR_R_RSA_LIB); - end: - EVP_PKEY_free(pkey); - return (i); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif -/* ssl/s2_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -# include - -int ssl2_enc_init(SSL *s, int client) -{ - /* Max number of bytes needed */ - EVP_CIPHER_CTX *rs, *ws; - const EVP_CIPHER *c; - const EVP_MD *md; - int num; - - if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_SSL2_ENC_INIT, SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); - return (0); - } - ssl_replace_hash(&s->read_hash, md); - ssl_replace_hash(&s->write_hash, md); - - if ((s->enc_read_ctx == NULL) && ((s->enc_read_ctx = (EVP_CIPHER_CTX *) - OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) - == NULL)) - goto err; - - /* - * make sure it's intialized in case the malloc for enc_write_ctx fails - * and we exit with an error - */ - rs = s->enc_read_ctx; - EVP_CIPHER_CTX_init(rs); - - if ((s->enc_write_ctx == NULL) && ((s->enc_write_ctx = (EVP_CIPHER_CTX *) - OPENSSL_malloc(sizeof - (EVP_CIPHER_CTX))) == - NULL)) - goto err; - - ws = s->enc_write_ctx; - EVP_CIPHER_CTX_init(ws); - - num = c->key_len; - s->s2->key_material_length = num * 2; - OPENSSL_assert(s->s2->key_material_length <= sizeof(s->s2->key_material)); - - if (ssl2_generate_key_material(s) <= 0) - return 0; - - OPENSSL_assert(c->iv_len <= (int)sizeof(s->session->key_arg)); - EVP_EncryptInit_ex(ws, c, NULL, - &(s->s2->key_material[(client) ? num : 0]), - s->session->key_arg); - EVP_DecryptInit_ex(rs, c, NULL, - &(s->s2->key_material[(client) ? 0 : num]), - s->session->key_arg); - s->s2->read_key = &(s->s2->key_material[(client) ? 0 : num]); - s->s2->write_key = &(s->s2->key_material[(client) ? num : 0]); - return (1); - err: - SSLerr(SSL_F_SSL2_ENC_INIT, ERR_R_MALLOC_FAILURE); - return (0); -} - -/* - * read/writes from s->s2->mac_data using length for encrypt and decrypt. - * It sets s->s2->padding and s->[rw]length if we are encrypting Returns 0 on - * error and 1 on success - */ -int ssl2_enc(SSL *s, int send) -{ - EVP_CIPHER_CTX *ds; - unsigned long l; - int bs; - - if (send) { - ds = s->enc_write_ctx; - l = s->s2->wlength; - } else { - ds = s->enc_read_ctx; - l = s->s2->rlength; - } - - /* check for NULL cipher */ - if (ds == NULL) - return 1; - - bs = ds->cipher->block_size; - /* - * This should be using (bs-1) and bs instead of 7 and 8, but what the - * hell. - */ - if (bs == 8) - l = (l + 7) / 8 * 8; - - if (EVP_Cipher(ds, s->s2->mac_data, s->s2->mac_data, l) < 1) - return 0; - - return 1; -} - -void ssl2_mac(SSL *s, unsigned char *md, int send) -{ - EVP_MD_CTX c; - unsigned char sequence[4], *p, *sec, *act; - unsigned long seq; - unsigned int len; - - if (send) { - seq = s->s2->write_sequence; - sec = s->s2->write_key; - len = s->s2->wact_data_length; - act = s->s2->wact_data; - } else { - seq = s->s2->read_sequence; - sec = s->s2->read_key; - len = s->s2->ract_data_length; - act = s->s2->ract_data; - } - - p = &(sequence[0]); - l2n(seq, p); - - /* There has to be a MAC algorithm. */ - EVP_MD_CTX_init(&c); - EVP_MD_CTX_copy(&c, s->read_hash); - EVP_DigestUpdate(&c, sec, EVP_CIPHER_CTX_key_length(s->enc_read_ctx)); - EVP_DigestUpdate(&c, act, len); - /* the above line also does the pad data */ - EVP_DigestUpdate(&c, sequence, 4); - EVP_DigestFinal_ex(&c, md, NULL); - EVP_MD_CTX_cleanup(&c); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif -/* ssl/s2_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -# include -# include "objects.h" -# include "evp.h" -# include "md5.h" - -const char ssl2_version_str[] = "SSLv2" OPENSSL_VERSION_PTEXT; - -# define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER)) - -/* list of available SSLv2 ciphers (sorted by id) */ -OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = { -# if 0 -/* NULL_WITH_MD5 v3 */ - { - 1, - SSL2_TXT_NULL_WITH_MD5, - SSL2_CK_NULL_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_MD5, - SSL_SSLV2, - SSL_EXPORT | SSL_EXP40 | SSL_STRONG_NONE, - 0, - 0, - 0, - }, -# endif - -/* RC4_128_WITH_MD5 */ - { - 1, - SSL2_TXT_RC4_128_WITH_MD5, - SSL2_CK_RC4_128_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - 0, - 128, - 128, - }, - -# if 0 -/* RC4_128_EXPORT40_WITH_MD5 */ - { - 1, - SSL2_TXT_RC4_128_EXPORT40_WITH_MD5, - SSL2_CK_RC4_128_EXPORT40_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL2_CF_5_BYTE_ENC, - 40, - 128, - }, -# endif - -/* RC2_128_CBC_WITH_MD5 */ - { - 1, - SSL2_TXT_RC2_128_CBC_WITH_MD5, - SSL2_CK_RC2_128_CBC_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC2, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - 0, - 128, - 128, - }, - -# if 0 -/* RC2_128_CBC_EXPORT40_WITH_MD5 */ - { - 1, - SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5, - SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC2, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL2_CF_5_BYTE_ENC, - 40, - 128, - }, -# endif - -# ifndef OPENSSL_NO_IDEA -/* IDEA_128_CBC_WITH_MD5 */ - { - 1, - SSL2_TXT_IDEA_128_CBC_WITH_MD5, - SSL2_CK_IDEA_128_CBC_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_IDEA, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - 0, - 128, - 128, - }, -# endif - -# if 0 -/* DES_64_CBC_WITH_MD5 */ - { - 1, - SSL2_TXT_DES_64_CBC_WITH_MD5, - SSL2_CK_DES_64_CBC_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_DES, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - 0, - 56, - 56, - }, -# endif - -/* DES_192_EDE3_CBC_WITH_MD5 */ - { - 1, - SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5, - SSL2_CK_DES_192_EDE3_CBC_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_3DES, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - 0, - 112, - 168, - }, - -# if 0 -/* RC4_64_WITH_MD5 */ - { - 1, - SSL2_TXT_RC4_64_WITH_MD5, - SSL2_CK_RC4_64_WITH_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL2_CF_8_BYTE_ENC, - 64, - 64, - }, -# endif - -# if 0 -/* NULL SSLeay (testing) */ - { - 0, - SSL2_TXT_NULL, - SSL2_CK_NULL, - 0, - 0, - 0, - 0, - SSL_SSLV2, - SSL_STRONG_NONE, - 0, - 0, - 0, - }, -# endif - -/* end of list :-) */ -}; - -long ssl2_default_timeout(void) -{ - return (300); -} - -int ssl2_num_ciphers(void) -{ - return (SSL2_NUM_CIPHERS); -} - -const SSL_CIPHER *ssl2_get_cipher(unsigned int u) -{ - if (u < SSL2_NUM_CIPHERS) - return (&(ssl2_ciphers[SSL2_NUM_CIPHERS - 1 - u])); - else - return (NULL); -} - -int ssl2_pending(const SSL *s) -{ - return SSL_in_init(s) ? 0 : s->s2->ract_data_length; -} - -int ssl2_new(SSL *s) -{ - SSL2_STATE *s2; - - if ((s2 = OPENSSL_malloc(sizeof(*s2))) == NULL) - goto err; - memset(s2, 0, sizeof(*s2)); - -# if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2 -# error "assertion failed" -# endif - - if ((s2->rbuf = - OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) == NULL) - goto err; - /* - * wbuf needs one byte more because when using two-byte headers, we leave - * the first byte unused in do_ssl_write (s2_pkt.c) - */ - if ((s2->wbuf = - OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 3)) == NULL) - goto err; - s->s2 = s2; - - ssl2_clear(s); - return (1); - err: - if (s2 != NULL) { - if (s2->wbuf != NULL) - OPENSSL_free(s2->wbuf); - if (s2->rbuf != NULL) - OPENSSL_free(s2->rbuf); - OPENSSL_free(s2); - } - return (0); -} - -void ssl2_free(SSL *s) -{ - SSL2_STATE *s2; - - if (s == NULL) - return; - - s2 = s->s2; - if (s2->rbuf != NULL) - OPENSSL_free(s2->rbuf); - if (s2->wbuf != NULL) - OPENSSL_free(s2->wbuf); - OPENSSL_cleanse(s2, sizeof(*s2)); - OPENSSL_free(s2); - s->s2 = NULL; -} - -void ssl2_clear(SSL *s) -{ - SSL2_STATE *s2; - unsigned char *rbuf, *wbuf; - - s2 = s->s2; - - rbuf = s2->rbuf; - wbuf = s2->wbuf; - - memset(s2, 0, sizeof(*s2)); - - s2->rbuf = rbuf; - s2->wbuf = wbuf; - s2->clear_text = 1; - s->packet = s2->rbuf; - s->version = SSL2_VERSION; - s->packet_length = 0; -} - -long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg) -{ - int ret = 0; - - switch (cmd) { - case SSL_CTRL_GET_SESSION_REUSED: - ret = s->hit; - break; - case SSL_CTRL_CHECK_PROTO_VERSION: - return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg); - default: - break; - } - return (ret); -} - -long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) -{ - return (0); -} - -long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) -{ - return (0); -} - -long ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) -{ - return (0); -} - -/* - * This function needs to check if the ciphers required are actually - * available - */ -const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p) -{ - SSL_CIPHER c; - const SSL_CIPHER *cp; - unsigned long id; - - id = 0x02000000L | ((unsigned long)p[0] << 16L) | - ((unsigned long)p[1] << 8L) | (unsigned long)p[2]; - c.id = id; - cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS); - return cp; -} - -int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) -{ - long l; - - if (p != NULL) { - l = c->id; - if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) - return (0); - p[0] = ((unsigned char)(l >> 16L)) & 0xFF; - p[1] = ((unsigned char)(l >> 8L)) & 0xFF; - p[2] = ((unsigned char)(l)) & 0xFF; - } - return (3); -} - -int ssl2_generate_key_material(SSL *s) -{ - unsigned int i; - EVP_MD_CTX ctx; - unsigned char *km; - unsigned char c = '0'; - const EVP_MD *md5; - int md_size; - - md5 = EVP_md5(); - -# ifdef CHARSET_EBCDIC - c = os_toascii['0']; /* Must be an ASCII '0', not EBCDIC '0', see - * SSLv2 docu */ -# endif - EVP_MD_CTX_init(&ctx); - km = s->s2->key_material; - - if (s->session->master_key_length < 0 || - s->session->master_key_length > (int)sizeof(s->session->master_key)) { - SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); - return 0; - } - md_size = EVP_MD_size(md5); - if (md_size < 0) - return 0; - for (i = 0; i < s->s2->key_material_length; i += md_size) { - if (((km - s->s2->key_material) + md_size) > - (int)sizeof(s->s2->key_material)) { - /* - * EVP_DigestFinal_ex() below would write beyond buffer - */ - SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); - return 0; - } - - EVP_DigestInit_ex(&ctx, md5, NULL); - - OPENSSL_assert(s->session->master_key_length >= 0 - && s->session->master_key_length - <= (int)sizeof(s->session->master_key)); - EVP_DigestUpdate(&ctx, s->session->master_key, - s->session->master_key_length); - EVP_DigestUpdate(&ctx, &c, 1); - c++; - EVP_DigestUpdate(&ctx, s->s2->challenge, s->s2->challenge_length); - EVP_DigestUpdate(&ctx, s->s2->conn_id, s->s2->conn_id_length); - EVP_DigestFinal_ex(&ctx, km, NULL); - km += md_size; - } - - EVP_MD_CTX_cleanup(&ctx); - return 1; -} - -void ssl2_return_error(SSL *s, int err) -{ - if (!s->error) { - s->error = 3; - s->error_code = err; - - ssl2_write_error(s); - } -} - -void ssl2_write_error(SSL *s) -{ - unsigned char buf[3]; - int i, error; - - buf[0] = SSL2_MT_ERROR; - buf[1] = (s->error_code >> 8) & 0xff; - buf[2] = (s->error_code) & 0xff; - -/* state=s->rwstate;*/ - - error = s->error; /* number of bytes left to write */ - s->error = 0; - OPENSSL_assert(error >= 0 && error <= (int)sizeof(buf)); - i = ssl2_write(s, &(buf[3 - error]), error); - -/* if (i == error) s->rwstate=state; */ - - if (i < 0) - s->error = error; - else { - s->error = error - i; - - if (s->error == 0) - if (s->msg_callback) { - /* ERROR */ - s->msg_callback(1, s->version, 0, buf, 3, s, - s->msg_callback_arg); - } - } -} - -int ssl2_shutdown(SSL *s) -{ - s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); - return (1); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif -/* ssl/s2_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2_METHOD -# ifndef OPENSSL_NO_SSL2 -# include -# include "objects.h" - -static const SSL_METHOD *ssl2_get_method(int ver); -static const SSL_METHOD *ssl2_get_method(int ver) -{ - if (ver == SSL2_VERSION) - return (SSLv2_method()); - else - return (NULL); -} - -IMPLEMENT_ssl2_meth_func(SSLv2_method, - ssl2_accept, ssl2_connect, ssl2_get_method) - -# else /* !OPENSSL_NO_SSL2 */ - -const SSL_METHOD *SSLv2_method(void) { return NULL; } -const SSL_METHOD *SSLv2_client_method(void) { return NULL; } -const SSL_METHOD *SSLv2_server_method(void) { return NULL; } - -# endif - -#else /* !OPENSSL_NO_SSL2_METHOD */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif -/* ssl/s2_pkt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -# include -# include -# define USE_SOCKETS - -static int read_n(SSL *s, unsigned int n, unsigned int max, - unsigned int extend); -static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); -static int write_pending(SSL *s, const unsigned char *buf, unsigned int len); -static int ssl_mt_error(int n); - -/* - * SSL 2.0 imlementation for SSL_read/SSL_peek - This routine will return 0 - * to len bytes, decrypted etc if required. - */ -static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) -{ - int n; - unsigned char mac[MAX_MAC_SIZE]; - unsigned char *p; - int i; - int mac_size; - - ssl2_read_again: - if (SSL_in_init(s) && !s->in_handshake) { - n = s->handshake_func(s); - if (n < 0) - return (n); - if (n == 0) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - } - - clear_sys_error(); - s->rwstate = SSL_NOTHING; - if (len <= 0) - return (len); - - if (s->s2->ract_data_length != 0) { /* read from buffer */ - if (len > s->s2->ract_data_length) - n = s->s2->ract_data_length; - else - n = len; - - memcpy(buf, s->s2->ract_data, (unsigned int)n); - if (!peek) { - s->s2->ract_data_length -= n; - s->s2->ract_data += n; - if (s->s2->ract_data_length == 0) - s->rstate = SSL_ST_READ_HEADER; - } - - return (n); - } - - /* - * s->s2->ract_data_length == 0 Fill the buffer, then goto - * ssl2_read_again. - */ - - if (s->rstate == SSL_ST_READ_HEADER) { - if (s->first_packet) { - n = read_n(s, 5, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); - if (n <= 0) - return (n); /* error or non-blocking */ - s->first_packet = 0; - p = s->packet; - if (!((p[0] & 0x80) && ((p[2] == SSL2_MT_CLIENT_HELLO) || - (p[2] == SSL2_MT_SERVER_HELLO)))) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, - SSL_R_NON_SSLV2_INITIAL_PACKET); - return (-1); - } - } else { - n = read_n(s, 2, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); - if (n <= 0) - return (n); /* error or non-blocking */ - } - /* part read stuff */ - - s->rstate = SSL_ST_READ_BODY; - p = s->packet; - /* Do header */ - /* - * s->s2->padding=0; - */ - s->s2->escape = 0; - s->s2->rlength = (((unsigned int)p[0]) << 8) | ((unsigned int)p[1]); - if ((p[0] & TWO_BYTE_BIT)) { /* Two byte header? */ - s->s2->three_byte_header = 0; - s->s2->rlength &= TWO_BYTE_MASK; - } else { - s->s2->three_byte_header = 1; - s->s2->rlength &= THREE_BYTE_MASK; - - /* security >s2->escape */ - s->s2->escape = ((p[0] & SEC_ESC_BIT)) ? 1 : 0; - } - } - - if (s->rstate == SSL_ST_READ_BODY) { - n = s->s2->rlength + 2 + s->s2->three_byte_header; - if (n > (int)s->packet_length) { - n -= s->packet_length; - i = read_n(s, (unsigned int)n, (unsigned int)n, 1); - if (i <= 0) - return (i); /* ERROR */ - } - - p = &(s->packet[2]); - s->rstate = SSL_ST_READ_HEADER; - if (s->s2->three_byte_header) - s->s2->padding = *(p++); - else - s->s2->padding = 0; - - /* Data portion */ - if (s->s2->clear_text) { - mac_size = 0; - s->s2->mac_data = p; - s->s2->ract_data = p; - if (s->s2->padding) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); - return (-1); - } - } else { - mac_size = EVP_MD_CTX_size(s->read_hash); - if (mac_size < 0) - return -1; - OPENSSL_assert(mac_size <= MAX_MAC_SIZE); - s->s2->mac_data = p; - s->s2->ract_data = &p[mac_size]; - if (s->s2->padding + mac_size > s->s2->rlength) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); - return (-1); - } - } - - s->s2->ract_data_length = s->s2->rlength; - /* - * added a check for length > max_size in case encryption was not - * turned on yet due to an error - */ - if ((!s->s2->clear_text) && - (s->s2->rlength >= (unsigned int)mac_size)) { - if (!ssl2_enc(s, 0)) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_DECRYPTION_FAILED); - return (-1); - } - s->s2->ract_data_length -= mac_size; - ssl2_mac(s, mac, 0); - s->s2->ract_data_length -= s->s2->padding; - if ((CRYPTO_memcmp(mac, s->s2->mac_data, mac_size) != 0) || - (s->s2->rlength % - EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_MAC_DECODE); - return (-1); - } - } - INC32(s->s2->read_sequence); /* expect next number */ - /* s->s2->ract_data is now available for processing */ - - /* - * Possibly the packet that we just read had 0 actual data bytes. - * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.) - * In this case, returning 0 would be interpreted by the caller as - * indicating EOF, so it's not a good idea. Instead, we just - * continue reading; thus ssl2_read_internal may have to process - * multiple packets before it can return. [Note that using select() - * for blocking sockets *never* guarantees that the next SSL_read - * will not block -- the available data may contain incomplete - * packets, and except for SSL 2, renegotiation can confuse things - * even more.] - */ - - goto ssl2_read_again; /* This should really be "return - * ssl2_read(s,buf,len)", but that would - * allow for denial-of-service attacks if a C - * compiler is used that does not recognize - * end-recursion. */ - } else { - SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_STATE); - return (-1); - } -} - -int ssl2_read(SSL *s, void *buf, int len) -{ - return ssl2_read_internal(s, buf, len, 0); -} - -int ssl2_peek(SSL *s, void *buf, int len) -{ - return ssl2_read_internal(s, buf, len, 1); -} - -/* - * Return values are as per SSL_read() - */ -static int read_n(SSL *s, unsigned int n, unsigned int max, - unsigned int extend) -{ - int i, off, newb; - - /* - * if there is stuff still in the buffer from a previous read, and there - * is more than we want, take some. - */ - if (s->s2->rbuf_left >= (int)n) { - if (extend) - s->packet_length += n; - else { - s->packet = &(s->s2->rbuf[s->s2->rbuf_offs]); - s->packet_length = n; - } - s->s2->rbuf_left -= n; - s->s2->rbuf_offs += n; - return (n); - } - - if (!s->read_ahead) - max = n; - if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) - max = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2; - - /* - * Else we want more than we have. First, if there is some left or we - * want to extend - */ - off = 0; - if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend)) { - newb = s->s2->rbuf_left; - if (extend) { - off = s->packet_length; - if (s->packet != s->s2->rbuf) - memcpy(s->s2->rbuf, s->packet, (unsigned int)newb + off); - } else if (s->s2->rbuf_offs != 0) { - memcpy(s->s2->rbuf, &(s->s2->rbuf[s->s2->rbuf_offs]), - (unsigned int)newb); - s->s2->rbuf_offs = 0; - } - s->s2->rbuf_left = 0; - } else - newb = 0; - - /* - * off is the offset to start writing too. r->s2->rbuf_offs is the - * 'unread data', now 0. newb is the number of new bytes so far - */ - s->packet = s->s2->rbuf; - while (newb < (int)n) { - clear_sys_error(); - if (s->rbio != NULL) { - s->rwstate = SSL_READING; - i = BIO_read(s->rbio, (char *)&(s->s2->rbuf[off + newb]), - max - newb); - } else { - SSLerr(SSL_F_READ_N, SSL_R_READ_BIO_NOT_SET); - i = -1; - } -# ifdef PKT_DEBUG - if (s->debug & 0x01) - sleep(1); -# endif - if (i <= 0) { - s->s2->rbuf_left += newb; - return i; - } - newb += i; - } - - /* record unread data */ - if (newb > (int)n) { - s->s2->rbuf_offs = n + off; - s->s2->rbuf_left = newb - n; - } else { - s->s2->rbuf_offs = 0; - s->s2->rbuf_left = 0; - } - if (extend) - s->packet_length += n; - else - s->packet_length = n; - s->rwstate = SSL_NOTHING; - return (n); -} - -int ssl2_write(SSL *s, const void *_buf, int len) -{ - const unsigned char *buf = _buf; - unsigned int n, tot; - int i; - - if (SSL_in_init(s) && !s->in_handshake) { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL2_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - } - - if (s->error) { - ssl2_write_error(s); - if (s->error) - return (-1); - } - - clear_sys_error(); - s->rwstate = SSL_NOTHING; - if (len <= 0) - return (len); - - tot = s->s2->wnum; - s->s2->wnum = 0; - - n = (len - tot); - for (;;) { - i = n_do_ssl_write(s, &(buf[tot]), n); - if (i <= 0) { - s->s2->wnum = tot; - return (i); - } - if ((i == (int)n) || (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { - return (tot + i); - } - - n -= i; - tot += i; - } -} - -/* - * Return values are as per SSL_write() - */ -static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) -{ - int i; - - /* s->s2->wpend_len != 0 MUST be true. */ - - /* - * check that they have given us the same buffer to write - */ - if ((s->s2->wpend_tot > (int)len) || - ((s->s2->wpend_buf != buf) && - !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))) { - SSLerr(SSL_F_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); - return (-1); - } - - for (;;) { - clear_sys_error(); - if (s->wbio != NULL) { - s->rwstate = SSL_WRITING; - i = BIO_write(s->wbio, - (char *)&(s->s2->write_ptr[s->s2->wpend_off]), - (unsigned int)s->s2->wpend_len); - } else { - SSLerr(SSL_F_WRITE_PENDING, SSL_R_WRITE_BIO_NOT_SET); - i = -1; - } -# ifdef PKT_DEBUG - if (s->debug & 0x01) - sleep(1); -# endif - if (i == s->s2->wpend_len) { - s->s2->wpend_len = 0; - s->rwstate = SSL_NOTHING; - return (s->s2->wpend_ret); - } else if (i <= 0) - return i; - s->s2->wpend_off += i; - s->s2->wpend_len -= i; - } -} - -static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) -{ - unsigned int j, k, olen, p, bs; - int mac_size; - register unsigned char *pp; - - olen = len; - - /* - * first check if there is data from an encryption waiting to be sent - - * it must be sent because the other end is waiting. This will happen - * with non-blocking IO. We print it and then return. - */ - if (s->s2->wpend_len != 0) - return (write_pending(s, buf, len)); - - /* set mac_size to mac size */ - if (s->s2->clear_text) - mac_size = 0; - else { - mac_size = EVP_MD_CTX_size(s->write_hash); - if (mac_size < 0) - return -1; - } - - /* lets set the pad p */ - if (s->s2->clear_text) { - if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) - len = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; - p = 0; - s->s2->three_byte_header = 0; - /* len=len; */ - } else { - bs = EVP_CIPHER_CTX_block_size(s->enc_read_ctx); - j = len + mac_size; - /* - * Two-byte headers allow for a larger record length than three-byte - * headers, but we can't use them if we need padding or if we have to - * set the escape bit. - */ - if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) && (!s->s2->escape)) { - if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) - j = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; - /* - * set k to the max number of bytes with 2 byte header - */ - k = j - (j % bs); - /* how many data bytes? */ - len = k - mac_size; - s->s2->three_byte_header = 0; - p = 0; - } else if ((bs <= 1) && (!s->s2->escape)) { - /*- - * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus - * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - */ - s->s2->three_byte_header = 0; - p = 0; - } else { /* we may have to use a 3 byte header */ - - /*- - * If s->s2->escape is not set, then - * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus - * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. - */ - p = (j % bs); - p = (p == 0) ? 0 : (bs - p); - if (s->s2->escape) { - s->s2->three_byte_header = 1; - if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) - j = SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER; - } else - s->s2->three_byte_header = (p == 0) ? 0 : 1; - } - } - - /*- - * Now - * j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - * holds, and if s->s2->three_byte_header is set, then even - * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER. - */ - - /* - * mac_size is the number of MAC bytes len is the number of data bytes we - * are going to send p is the number of padding bytes (if it is a - * two-byte header, then p == 0) - */ - - s->s2->wlength = len; - s->s2->padding = p; - s->s2->mac_data = &(s->s2->wbuf[3]); - s->s2->wact_data = &(s->s2->wbuf[3 + mac_size]); - - /* - * It would be clearer to write this as follows: - * if (mac_size + len + p > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) - * However |len| is user input that could in theory be very large. We - * know |mac_size| and |p| are small, so to avoid any possibility of - * overflow we write it like this. - * - * In theory this should never fail because the logic above should have - * modified |len| if it is too big. But we are being cautious. - */ - if (len > (SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - (mac_size + p))) { - return -1; - } - /* we copy the data into s->s2->wbuf */ - memcpy(s->s2->wact_data, buf, len); - if (p) - memset(&(s->s2->wact_data[len]), 0, p); /* arbitrary padding */ - - if (!s->s2->clear_text) { - s->s2->wact_data_length = len + p; - ssl2_mac(s, s->s2->mac_data, 1); - s->s2->wlength += p + mac_size; - if (ssl2_enc(s, 1) < 1) - return -1; - } - - /* package up the header */ - s->s2->wpend_len = s->s2->wlength; - if (s->s2->three_byte_header) { /* 3 byte header */ - pp = s->s2->mac_data; - pp -= 3; - pp[0] = (s->s2->wlength >> 8) & (THREE_BYTE_MASK >> 8); - if (s->s2->escape) - pp[0] |= SEC_ESC_BIT; - pp[1] = s->s2->wlength & 0xff; - pp[2] = s->s2->padding; - s->s2->wpend_len += 3; - } else { - pp = s->s2->mac_data; - pp -= 2; - pp[0] = ((s->s2->wlength >> 8) & (TWO_BYTE_MASK >> 8)) | TWO_BYTE_BIT; - pp[1] = s->s2->wlength & 0xff; - s->s2->wpend_len += 2; - } - s->s2->write_ptr = pp; - - INC32(s->s2->write_sequence); /* expect next number */ - - /* lets try to actually write the data */ - s->s2->wpend_tot = olen; - s->s2->wpend_buf = buf; - - s->s2->wpend_ret = len; - - s->s2->wpend_off = 0; - return (write_pending(s, buf, olen)); -} - -int ssl2_part_read(SSL *s, unsigned long f, int i) -{ - unsigned char *p; - int j; - - if (i < 0) { - /* ssl2_return_error(s); */ - /* - * for non-blocking io, this is not necessarily fatal - */ - return (i); - } else { - s->init_num += i; - - /* - * Check for error. While there are recoverable errors, this - * function is not called when those must be expected; any error - * detected here is fatal. - */ - if (s->init_num >= 3) { - p = (unsigned char *)s->init_buf->data; - if (p[0] == SSL2_MT_ERROR) { - j = (p[1] << 8) | p[2]; - SSLerr((int)f, ssl_mt_error(j)); - s->init_num -= 3; - if (s->init_num > 0) - memmove(p, p + 3, s->init_num); - } - } - - /* - * If it's not an error message, we have some error anyway -- the - * message was shorter than expected. This too is treated as fatal - * (at least if SSL_get_error is asked for its opinion). - */ - return (0); - } -} - -int ssl2_do_write(SSL *s) -{ - int ret; - - ret = ssl2_write(s, &s->init_buf->data[s->init_off], s->init_num); - if (ret == s->init_num) { - if (s->msg_callback) - s->msg_callback(1, s->version, 0, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, - s->msg_callback_arg); - return (1); - } - if (ret < 0) - return (-1); - s->init_off += ret; - s->init_num -= ret; - return (0); -} - -static int ssl_mt_error(int n) -{ - int ret; - - switch (n) { - case SSL2_PE_NO_CIPHER: - ret = SSL_R_PEER_ERROR_NO_CIPHER; - break; - case SSL2_PE_NO_CERTIFICATE: - ret = SSL_R_PEER_ERROR_NO_CERTIFICATE; - break; - case SSL2_PE_BAD_CERTIFICATE: - ret = SSL_R_PEER_ERROR_CERTIFICATE; - break; - case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE: - ret = SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; - break; - default: - ret = SSL_R_UNKNOWN_REMOTE_ERROR_TYPE; - break; - } - return (ret); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif -/* ssl/s2_srvr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "ssl_locl.h" -#ifndef OPENSSL_NO_SSL2 -#include "constant_time_locl.h" -# include -# include "bio.h" -# include "rand.h" -# include "objects.h" -# include "evp.h" - -static const SSL_METHOD *ssl2_get_server_method(int ver); -static int get_client_master_key(SSL *s); -static int get_client_hello(SSL *s); -static int server_hello(SSL *s); -static int get_client_finished(SSL *s); -static int server_verify(SSL *s); -static int server_finish(SSL *s); -static int request_certificate(SSL *s); -static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, - unsigned char *to, int padding); -# define BREAK break - -static const SSL_METHOD *ssl2_get_server_method(int ver) -{ - if (ver == SSL2_VERSION) - return (SSLv2_server_method()); - else - return (NULL); -} - -IMPLEMENT_ssl2_meth_func(SSLv2_server_method, - ssl2_accept, - ssl_undefined_function, ssl2_get_server_method) - -int ssl2_accept(SSL *s) -{ - unsigned long l = (unsigned long)time(NULL); - BUF_MEM *buf = NULL; - int ret = -1; - long num1; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int new_state, state; - - RAND_add(&l, sizeof(l), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - /* init things to blank */ - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - if (s->cert == NULL) { - SSLerr(SSL_F_SSL2_ACCEPT, SSL_R_NO_CERTIFICATE_SET); - return (-1); - } - - clear_sys_error(); - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_BEFORE: - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - case SSL_ST_OK | SSL_ST_ACCEPT: - - s->server = 1; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - s->version = SSL2_VERSION; - s->type = SSL_ST_ACCEPT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - goto end; - } - if (!BUF_MEM_grow - (buf, (int)SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { - BUF_MEM_free(buf); - ret = -1; - goto end; - } - s->init_buf = buf; - } - s->init_num = 0; - s->ctx->stats.sess_accept++; - s->handshake_func = ssl2_accept; - s->state = SSL2_ST_GET_CLIENT_HELLO_A; - BREAK; - - case SSL2_ST_GET_CLIENT_HELLO_A: - case SSL2_ST_GET_CLIENT_HELLO_B: - case SSL2_ST_GET_CLIENT_HELLO_C: - s->shutdown = 0; - ret = get_client_hello(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_SEND_SERVER_HELLO_A; - BREAK; - - case SSL2_ST_SEND_SERVER_HELLO_A: - case SSL2_ST_SEND_SERVER_HELLO_B: - ret = server_hello(s); - if (ret <= 0) - goto end; - s->init_num = 0; - if (!s->hit) { - s->state = SSL2_ST_GET_CLIENT_MASTER_KEY_A; - BREAK; - } else { - s->state = SSL2_ST_SERVER_START_ENCRYPTION; - BREAK; - } - case SSL2_ST_GET_CLIENT_MASTER_KEY_A: - case SSL2_ST_GET_CLIENT_MASTER_KEY_B: - ret = get_client_master_key(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_SERVER_START_ENCRYPTION; - BREAK; - - case SSL2_ST_SERVER_START_ENCRYPTION: - /* - * Ok we how have sent all the stuff needed to start encrypting, - * the next packet back will be encrypted. - */ - if (!ssl2_enc_init(s, 0)) { - ret = -1; - goto end; - } - s->s2->clear_text = 0; - s->state = SSL2_ST_SEND_SERVER_VERIFY_A; - BREAK; - - case SSL2_ST_SEND_SERVER_VERIFY_A: - case SSL2_ST_SEND_SERVER_VERIFY_B: - ret = server_verify(s); - if (ret <= 0) - goto end; - s->init_num = 0; - if (s->hit) { - /* - * If we are in here, we have been buffering the output, so - * we need to flush it and remove buffering from future - * traffic - */ - s->state = SSL2_ST_SEND_SERVER_VERIFY_C; - BREAK; - } else { - s->state = SSL2_ST_GET_CLIENT_FINISHED_A; - break; - } - - case SSL2_ST_SEND_SERVER_VERIFY_C: - /* get the number of bytes to write */ - num1 = BIO_ctrl(s->wbio, BIO_CTRL_INFO, 0, NULL); - if (num1 > 0) { - s->rwstate = SSL_WRITING; - num1 = BIO_flush(s->wbio); - if (num1 <= 0) { - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - } - - /* flushed and now remove buffering */ - s->wbio = BIO_pop(s->wbio); - - s->state = SSL2_ST_GET_CLIENT_FINISHED_A; - BREAK; - - case SSL2_ST_GET_CLIENT_FINISHED_A: - case SSL2_ST_GET_CLIENT_FINISHED_B: - ret = get_client_finished(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_A; - BREAK; - - case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: - case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: - case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: - case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: - /* - * don't do a 'request certificate' if we don't want to, or we - * already have one, and we only want to do it once. - */ - if (!(s->verify_mode & SSL_VERIFY_PEER) || - ((s->session->peer != NULL) && - (s->verify_mode & SSL_VERIFY_CLIENT_ONCE))) { - s->state = SSL2_ST_SEND_SERVER_FINISHED_A; - break; - } else { - ret = request_certificate(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL2_ST_SEND_SERVER_FINISHED_A; - } - BREAK; - - case SSL2_ST_SEND_SERVER_FINISHED_A: - case SSL2_ST_SEND_SERVER_FINISHED_B: - ret = server_finish(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL_ST_OK; - break; - - case SSL_ST_OK: - BUF_MEM_free(s->init_buf); - ssl_free_wbio_buffer(s); - s->init_buf = NULL; - s->init_num = 0; - /* ERR_clear_error(); */ - - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); - - s->ctx->stats.sess_accept_good++; - /* s->server=1; */ - ret = 1; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - - goto end; - /* BREAK; */ - - default: - SSLerr(SSL_F_SSL2_ACCEPT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* BREAK; */ - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; - } - } - end: - s->in_handshake--; - if (cb != NULL) - cb(s, SSL_CB_ACCEPT_EXIT, ret); - return (ret); -} - -static int get_client_master_key(SSL *s) -{ - int is_export, i, n, keya; - unsigned int num_encrypted_key_bytes, key_length; - unsigned long len; - unsigned char *p; - const SSL_CIPHER *cp; - const EVP_CIPHER *c; - const EVP_MD *md; - unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; - unsigned char decrypt_good; - size_t j; - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A) { - i = ssl2_read(s, (char *)&(p[s->init_num]), 10 - s->init_num); - - if (i < (10 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_MASTER_KEY, i)); - s->init_num = 10; - - if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY) { - if (p[-1] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, - SSL_R_READ_WRONG_PACKET_TYPE); - } else - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR); - return (-1); - } - - cp = ssl2_get_cipher_by_char(p); - if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); - return (-1); - } - s->session->cipher = cp; - - p += 3; - n2s(p, i); - s->s2->tmp.clear = i; - n2s(p, i); - s->s2->tmp.enc = i; - n2s(p, i); - if (i > SSL_MAX_KEY_ARG_LENGTH) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); - return -1; - } - s->session->key_arg_length = i; - s->state = SSL2_ST_GET_CLIENT_MASTER_KEY_B; - } - - /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */ - p = (unsigned char *)s->init_buf->data; - if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - keya = s->session->key_arg_length; - len = - 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + - (unsigned long)keya; - if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_MESSAGE_TOO_LONG); - return -1; - } - n = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), n); - if (i != n) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_MASTER_KEY, i)); - if (s->msg_callback) { - /* CLIENT-MASTER-KEY */ - s->msg_callback(0, s->version, 0, p, (size_t)len, s, - s->msg_callback_arg); - } - p += 10; - - memcpy(s->session->key_arg, &(p[s->s2->tmp.clear + s->s2->tmp.enc]), - (unsigned int)keya); - - if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_PRIVATEKEY); - return (-1); - } - - is_export = SSL_C_IS_EXPORT(s->session->cipher); - - if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, - SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); - return (0); - } - - /* - * The format of the CLIENT-MASTER-KEY message is - * 1 byte message type - * 3 bytes cipher - * 2-byte clear key length (stored in s->s2->tmp.clear) - * 2-byte encrypted key length (stored in s->s2->tmp.enc) - * 2-byte key args length (IV etc) - * clear key - * encrypted key - * key args - * - * If the cipher is an export cipher, then the encrypted key bytes - * are a fixed portion of the total key (5 or 8 bytes). The size of - * this portion is in |num_encrypted_key_bytes|. If the cipher is not an - * export cipher, then the entire key material is encrypted (i.e., clear - * key length must be zero). - */ - key_length = (unsigned int)EVP_CIPHER_key_length(c); - if (key_length > SSL_MAX_MASTER_KEY_LENGTH) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); - return -1; - } - - if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) { - is_export = 1; - num_encrypted_key_bytes = 8; - } else if (is_export) { - num_encrypted_key_bytes = 5; - } else { - num_encrypted_key_bytes = key_length; - } - - if (s->s2->tmp.clear + num_encrypted_key_bytes != key_length) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH); - return -1; - } - /* - * The encrypted blob must decrypt to the encrypted portion of the key. - * Decryption can't be expanding, so if we don't have enough encrypted - * bytes to fit the key in the buffer, stop now. - */ - if (s->s2->tmp.enc < num_encrypted_key_bytes) { - ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT); - return -1; - } - - /* - * We must not leak whether a decryption failure occurs because of - * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, - * section 7.4.7.1). The code follows that advice of the TLS RFC and - * generates a random premaster secret for the case that the decrypt - * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 - */ - - if (RAND_bytes(rand_premaster_secret, - (int)num_encrypted_key_bytes) <= 0) - return 0; - - i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, - &(p[s->s2->tmp.clear]), - &(p[s->s2->tmp.clear]), - (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING : - RSA_PKCS1_PADDING); - ERR_clear_error(); - /* - * If a bad decrypt, continue with protocol but with a random master - * secret (Bleichenbacher attack) - */ - decrypt_good = constant_time_eq_int_8(i, (int)num_encrypted_key_bytes); - for (j = 0; j < num_encrypted_key_bytes; j++) { - p[s->s2->tmp.clear + j] = - constant_time_select_8(decrypt_good, p[s->s2->tmp.clear + j], - rand_premaster_secret[j]); - } - - s->session->master_key_length = (int)key_length; - memcpy(s->session->master_key, p, key_length); - OPENSSL_cleanse(p, key_length); - - return 1; -} - -static int get_client_hello(SSL *s) -{ - int i, n; - unsigned long len; - unsigned char *p; - STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */ - STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */ - STACK_OF(SSL_CIPHER) *prio, *allow; - int z; - - /* - * This is a bit of a hack to check for the correct packet type the first - * time round. - */ - if (s->state == SSL2_ST_GET_CLIENT_HELLO_A) { - s->first_packet = 1; - s->state = SSL2_ST_GET_CLIENT_HELLO_B; - } - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_GET_CLIENT_HELLO_B) { - i = ssl2_read(s, (char *)&(p[s->init_num]), 9 - s->init_num); - if (i < (9 - s->init_num)) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_HELLO, i)); - s->init_num = 9; - - if (*(p++) != SSL2_MT_CLIENT_HELLO) { - if (p[-1] != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_READ_WRONG_PACKET_TYPE); - } else - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_PEER_ERROR); - return (-1); - } - n2s(p, i); - if (i < s->version) - s->version = i; - n2s(p, i); - s->s2->tmp.cipher_spec_length = i; - n2s(p, i); - s->s2->tmp.session_id_length = i; - if ((i < 0) || (i > SSL_MAX_SSL_SESSION_ID_LENGTH)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - return -1; - } - n2s(p, i); - s->s2->challenge_length = i; - if ((i < SSL2_MIN_CHALLENGE_LENGTH) || - (i > SSL2_MAX_CHALLENGE_LENGTH)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_INVALID_CHALLENGE_LENGTH); - return (-1); - } - s->state = SSL2_ST_GET_CLIENT_HELLO_C; - } - - /* SSL2_ST_GET_CLIENT_HELLO_C */ - p = (unsigned char *)s->init_buf->data; - len = - 9 + (unsigned long)s->s2->tmp.cipher_spec_length + - (unsigned long)s->s2->challenge_length + - (unsigned long)s->s2->tmp.session_id_length; - if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_MESSAGE_TOO_LONG); - return -1; - } - n = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), n); - if (i != n) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_HELLO, i)); - if (s->msg_callback) { - /* CLIENT-HELLO */ - s->msg_callback(0, s->version, 0, p, (size_t)len, s, - s->msg_callback_arg); - } - p += 9; - - /* - * get session-id before cipher stuff so we can get out session structure - * if it is cached - */ - /* session-id */ - if ((s->s2->tmp.session_id_length != 0) && - (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_BAD_SSL_SESSION_ID_LENGTH); - return (-1); - } - - if (s->s2->tmp.session_id_length == 0) { - if (!ssl_get_new_session(s, 1)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } else { - i = ssl_get_prev_session(s, &(p[s->s2->tmp.cipher_spec_length]), - s->s2->tmp.session_id_length, NULL); - if (i == 1) { /* previous session */ - s->hit = 1; - } else if (i == -1) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } else { - if (s->cert == NULL) { - ssl2_return_error(s, SSL2_PE_NO_CERTIFICATE); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CERTIFICATE_SET); - return (-1); - } - - if (!ssl_get_new_session(s, 1)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - return (-1); - } - } - } - - if (!s->hit) { - cs = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.cipher_spec_length, - &s->session->ciphers); - if (cs == NULL) - goto mem_err; - - cl = SSL_get_ciphers(s); - - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { - prio = sk_SSL_CIPHER_dup(cl); - if (prio == NULL) - goto mem_err; - allow = cs; - } else { - prio = cs; - allow = cl; - } - - /* Generate list of SSLv2 ciphers shared between client and server */ - for (z = 0; z < sk_SSL_CIPHER_num(prio); z++) { - const SSL_CIPHER *cp = sk_SSL_CIPHER_value(prio, z); - if ((cp->algorithm_ssl & SSL_SSLV2) == 0 || - sk_SSL_CIPHER_find(allow, cp) < 0) { - (void)sk_SSL_CIPHER_delete(prio, z); - z--; - } - } - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { - sk_SSL_CIPHER_free(s->session->ciphers); - s->session->ciphers = prio; - } - - /* Make sure we have at least one cipher in common */ - if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) { - ssl2_return_error(s, SSL2_PE_NO_CIPHER); - SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH); - return -1; - } - /* - * s->session->ciphers should now have a list of ciphers that are on - * both the client and server. This list is ordered by the order the - * client sent the ciphers or in the order of the server's preference - * if SSL_OP_CIPHER_SERVER_PREFERENCE was set. - */ - } - p += s->s2->tmp.cipher_spec_length; - /* done cipher selection */ - - /* session id extracted already */ - p += s->s2->tmp.session_id_length; - - /* challenge */ - if (s->s2->challenge_length > sizeof(s->s2->challenge)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(s->s2->challenge, p, (unsigned int)s->s2->challenge_length); - return (1); - mem_err: - SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_MALLOC_FAILURE); - return (0); -} - -static int server_hello(SSL *s) -{ - unsigned char *p, *d; - int n, hit; - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_SEND_SERVER_HELLO_A) { - d = p + 11; - *(p++) = SSL2_MT_SERVER_HELLO; /* type */ - hit = s->hit; - *(p++) = (unsigned char)hit; -# if 1 - if (!hit) { - if (s->session->sess_cert != NULL) - /* - * This can't really happen because get_client_hello has - * called ssl_get_new_session, which does not set sess_cert. - */ - ssl_sess_cert_free(s->session->sess_cert); - s->session->sess_cert = ssl_sess_cert_new(); - if (s->session->sess_cert == NULL) { - SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE); - return (-1); - } - } - /* - * If 'hit' is set, then s->sess_cert may be non-NULL or NULL, - * depending on whether it survived in the internal cache or was - * retrieved from an external cache. If it is NULL, we cannot put any - * useful data in it anyway, so we don't touch it. - */ - -# else /* That's what used to be done when cert_st - * and sess_cert_st were * the same. */ - if (!hit) { /* else add cert to session */ - CRYPTO_add(&s->cert->references, 1, CRYPTO_LOCK_SSL_CERT); - if (s->session->sess_cert != NULL) - ssl_cert_free(s->session->sess_cert); - s->session->sess_cert = s->cert; - } else { /* We have a session id-cache hit, if the * - * session-id has no certificate listed - * against * the 'cert' structure, grab the - * 'old' one * listed against the SSL - * connection */ - if (s->session->sess_cert == NULL) { - CRYPTO_add(&s->cert->references, 1, CRYPTO_LOCK_SSL_CERT); - s->session->sess_cert = s->cert; - } - } -# endif - - if (s->cert == NULL) { - ssl2_return_error(s, SSL2_PE_NO_CERTIFICATE); - SSLerr(SSL_F_SERVER_HELLO, SSL_R_NO_CERTIFICATE_SPECIFIED); - return (-1); - } - - if (hit) { - *(p++) = 0; /* no certificate type */ - s2n(s->version, p); /* version */ - s2n(0, p); /* cert len */ - s2n(0, p); /* ciphers len */ - } else { - /* EAY EAY */ - /* put certificate type */ - *(p++) = SSL2_CT_X509_CERTIFICATE; - s2n(s->version, p); /* version */ - n = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, NULL); - s2n(n, p); /* certificate length */ - i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, &d); - n = 0; - - /* - * lets send out the ciphers we like in the prefered order - */ - n = ssl_cipher_list_to_bytes(s, s->session->ciphers, d, 0); - d += n; - s2n(n, p); /* add cipher length */ - } - - /* make and send conn_id */ - s2n(SSL2_CONNECTION_ID_LENGTH, p); /* add conn_id length */ - s->s2->conn_id_length = SSL2_CONNECTION_ID_LENGTH; - if (RAND_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= 0) - return -1; - memcpy(d, s->s2->conn_id, SSL2_CONNECTION_ID_LENGTH); - d += SSL2_CONNECTION_ID_LENGTH; - - s->state = SSL2_ST_SEND_SERVER_HELLO_B; - s->init_num = d - (unsigned char *)s->init_buf->data; - s->init_off = 0; - } - /* SSL2_ST_SEND_SERVER_HELLO_B */ - /* - * If we are using TCP/IP, the performance is bad if we do 2 writes - * without a read between them. This occurs when Session-id reuse is - * used, so I will put in a buffering module - */ - if (s->hit) { - if (!ssl_init_wbio_buffer(s, 1)) - return (-1); - } - - return (ssl2_do_write(s)); -} - -static int get_client_finished(SSL *s) -{ - unsigned char *p; - int i, n; - unsigned long len; - - p = (unsigned char *)s->init_buf->data; - if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A) { - i = ssl2_read(s, (char *)&(p[s->init_num]), 1 - s->init_num); - if (i < 1 - s->init_num) - return (ssl2_part_read(s, SSL_F_GET_CLIENT_FINISHED, i)); - s->init_num += i; - - if (*p != SSL2_MT_CLIENT_FINISHED) { - if (*p != SSL2_MT_ERROR) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_FINISHED, - SSL_R_READ_WRONG_PACKET_TYPE); - } else { - SSLerr(SSL_F_GET_CLIENT_FINISHED, SSL_R_PEER_ERROR); - /* try to read the error message */ - i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); - return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); - } - return (-1); - } - s->state = SSL2_ST_GET_CLIENT_FINISHED_B; - } - - /* SSL2_ST_GET_CLIENT_FINISHED_B */ - if (s->s2->conn_id_length > sizeof(s->s2->conn_id)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); - return -1; - } - len = 1 + (unsigned long)s->s2->conn_id_length; - n = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), n); - if (i < n) { - return (ssl2_part_read(s, SSL_F_GET_CLIENT_FINISHED, i)); - } - if (s->msg_callback) { - /* CLIENT-FINISHED */ - s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); - } - p += 1; - if (memcmp(p, s->s2->conn_id, s->s2->conn_id_length) != 0) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_GET_CLIENT_FINISHED, SSL_R_CONNECTION_ID_IS_DIFFERENT); - return (-1); - } - return (1); -} - -static int server_verify(SSL *s) -{ - unsigned char *p; - - if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A) { - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL2_MT_SERVER_VERIFY; - if (s->s2->challenge_length > sizeof(s->s2->challenge)) { - SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(p, s->s2->challenge, (unsigned int)s->s2->challenge_length); - /* p+=s->s2->challenge_length; */ - - s->state = SSL2_ST_SEND_SERVER_VERIFY_B; - s->init_num = s->s2->challenge_length + 1; - s->init_off = 0; - } - return (ssl2_do_write(s)); -} - -static int server_finish(SSL *s) -{ - unsigned char *p; - - if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A) { - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL2_MT_SERVER_FINISHED; - - if (s->session->session_id_length > sizeof(s->session->session_id)) { - SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR); - return -1; - } - memcpy(p, s->session->session_id, - (unsigned int)s->session->session_id_length); - /* p+=s->session->session_id_length; */ - - s->state = SSL2_ST_SEND_SERVER_FINISHED_B; - s->init_num = s->session->session_id_length + 1; - s->init_off = 0; - } - - /* SSL2_ST_SEND_SERVER_FINISHED_B */ - return (ssl2_do_write(s)); -} - -/* send the request and check the response */ -static int request_certificate(SSL *s) -{ - const unsigned char *cp; - unsigned char *p, *p2, *buf2; - unsigned char *ccd; - int i, j, ctype, ret = -1; - unsigned long len; - X509 *x509 = NULL; - STACK_OF(X509) *sk = NULL; - - ccd = s->s2->tmp.ccl; - if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A) { - p = (unsigned char *)s->init_buf->data; - *(p++) = SSL2_MT_REQUEST_CERTIFICATE; - *(p++) = SSL2_AT_MD5_WITH_RSA_ENCRYPTION; - if (RAND_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) - return -1; - memcpy(p, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH); - - s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_B; - s->init_num = SSL2_MIN_CERT_CHALLENGE_LENGTH + 2; - s->init_off = 0; - } - - if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B) { - i = ssl2_do_write(s); - if (i <= 0) { - ret = i; - goto end; - } - - s->init_num = 0; - s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_C; - } - - if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C) { - p = (unsigned char *)s->init_buf->data; - /* try to read 6 octets ... */ - i = ssl2_read(s, (char *)&(p[s->init_num]), 6 - s->init_num); - /* - * ... but don't call ssl2_part_read now if we got at least 3 - * (probably NO-CERTIFICATE-ERROR) - */ - if (i < 3 - s->init_num) { - ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, i); - goto end; - } - s->init_num += i; - - if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR)) { - n2s(p, i); - if (i != SSL2_PE_NO_CERTIFICATE) { - /* - * not the error message we expected -- let ssl2_part_read - * handle it - */ - s->init_num -= 3; - ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, 3); - goto end; - } - - if (s->msg_callback) { - /* ERROR */ - s->msg_callback(0, s->version, 0, p, 3, s, - s->msg_callback_arg); - } - - /* - * this is the one place where we can recover from an SSL 2.0 - * error - */ - - if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { - ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); - SSLerr(SSL_F_REQUEST_CERTIFICATE, - SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - goto end; - } - ret = 1; - goto end; - } - if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6)) { - ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); - SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_SHORT_READ); - goto end; - } - if (s->init_num != 6) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR); - goto end; - } - - /* ok we have a response */ - /* certificate type, there is only one right now. */ - ctype = *(p++); - if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { - ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); - SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_BAD_RESPONSE_ARGUMENT); - goto end; - } - n2s(p, i); - s->s2->tmp.clen = i; - n2s(p, i); - s->s2->tmp.rlen = i; - s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_D; - } - - /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */ - p = (unsigned char *)s->init_buf->data; - len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen; - if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_MESSAGE_TOO_LONG); - goto end; - } - j = (int)len - s->init_num; - i = ssl2_read(s, (char *)&(p[s->init_num]), j); - if (i < j) { - ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, i); - goto end; - } - if (s->msg_callback) { - /* CLIENT-CERTIFICATE */ - s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); - } - p += 6; - - cp = p; - x509 = (X509 *)d2i_X509(NULL, &cp, (long)s->s2->tmp.clen); - if (x509 == NULL) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_X509_LIB); - goto msg_end; - } - - if (((sk = sk_X509_new_null()) == NULL) || (!sk_X509_push(sk, x509))) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto msg_end; - } - - i = ssl_verify_cert_chain(s, sk); - - if (i > 0) { /* we like the packet, now check the chksum */ - EVP_MD_CTX ctx; - EVP_PKEY *pkey = NULL; - - EVP_MD_CTX_init(&ctx); - if (!EVP_VerifyInit_ex(&ctx, s->ctx->rsa_md5, NULL) - || !EVP_VerifyUpdate(&ctx, s->s2->key_material, - s->s2->key_material_length) - || !EVP_VerifyUpdate(&ctx, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH)) - goto msg_end; - - i = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, NULL); - buf2 = OPENSSL_malloc((unsigned int)i); - if (buf2 == NULL) { - SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto msg_end; - } - p2 = buf2; - i = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, &p2); - if (!EVP_VerifyUpdate(&ctx, buf2, (unsigned int)i)) { - OPENSSL_free(buf2); - goto msg_end; - } - OPENSSL_free(buf2); - - pkey = X509_get_pubkey(x509); - if (pkey == NULL) - goto end; - i = EVP_VerifyFinal(&ctx, cp, s->s2->tmp.rlen, pkey); - EVP_PKEY_free(pkey); - EVP_MD_CTX_cleanup(&ctx); - - if (i > 0) { - if (s->session->peer != NULL) - X509_free(s->session->peer); - s->session->peer = x509; - CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); - s->session->verify_result = s->verify_result; - ret = 1; - goto end; - } else { - SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_BAD_CHECKSUM); - goto msg_end; - } - } else { - msg_end: - ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); - } - end: - sk_X509_free(sk); - X509_free(x509); - return (ret); -} - -static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, - unsigned char *to, int padding) -{ - RSA *rsa; - int i; - - if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)) { - SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, SSL_R_NO_PRIVATEKEY); - return (-1); - } - if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA) { - SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA); - return (-1); - } - rsa = c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa; - - /* we have the public key */ - i = RSA_private_decrypt(len, from, to, rsa, padding); - if (i < 0) - SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, ERR_R_RSA_LIB); - return (i); -} -#else /* !OPENSSL_NO_SSL2 */ - -# if PEDANTIC -static void *dummy = &dummy; -# endif - -#endif diff --git a/Sources/COpenSSL/s3_.c b/Sources/COpenSSL/s3_.c deleted file mode 100644 index 8a611fd6..00000000 --- a/Sources/COpenSSL/s3_.c +++ /dev/null @@ -1,16475 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ssl/s3_both.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include -#include -#include -#include "ssl_locl.h" -#include "buffer.h" -#include "rand.h" -#include "objects.h" -#include "evp.h" -#include "x509.h" - -/* - * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or - * SSL3_RT_CHANGE_CIPHER_SPEC) - */ -int ssl3_do_write(SSL *s, int type) -{ - int ret; - - ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], - s->init_num); - if (ret < 0) - return (-1); - if (type == SSL3_RT_HANDSHAKE) - /* - * should not be done for 'Hello Request's, but in that case we'll - * ignore the result anyway - */ - ssl3_finish_mac(s, (unsigned char *)&s->init_buf->data[s->init_off], - ret); - - if (ret == s->init_num) { - if (s->msg_callback) - s->msg_callback(1, s->version, type, s->init_buf->data, - (size_t)(s->init_off + s->init_num), s, - s->msg_callback_arg); - return (1); - } - s->init_off += ret; - s->init_num -= ret; - return (0); -} - -int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) -{ - unsigned char *p; - int i; - unsigned long l; - - if (s->state == a) { - p = ssl_handshake_start(s); - - i = s->method->ssl3_enc->final_finish_mac(s, - sender, slen, - s->s3->tmp.finish_md); - if (i <= 0) - return 0; - s->s3->tmp.finish_md_len = i; - memcpy(p, s->s3->tmp.finish_md, i); - l = i; - - /* - * Copy the finished so we can use it for renegotiation checks - */ - if (s->type == SSL_ST_CONNECT) { - OPENSSL_assert(i <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i); - s->s3->previous_client_finished_len = i; - } else { - OPENSSL_assert(i <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i); - s->s3->previous_server_finished_len = i; - } - -#ifdef OPENSSL_SYS_WIN16 - /* - * MSVC 1.5 does not clear the top bytes of the word unless I do - * this. - */ - l &= 0xffff; -#endif - ssl_set_handshake_header(s, SSL3_MT_FINISHED, l); - s->state = b; - } - - /* SSL3_ST_SEND_xxxxxx_HELLO_B */ - return ssl_do_write(s); -} - -#ifndef OPENSSL_NO_NEXTPROTONEG -/* - * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen - * to far. - */ -static void ssl3_take_mac(SSL *s) -{ - const char *sender; - int slen; - /* - * If no new cipher setup return immediately: other functions will set - * the appropriate error. - */ - if (s->s3->tmp.new_cipher == NULL) - return; - if (s->state & SSL_ST_CONNECT) { - sender = s->method->ssl3_enc->server_finished_label; - slen = s->method->ssl3_enc->server_finished_label_len; - } else { - sender = s->method->ssl3_enc->client_finished_label; - slen = s->method->ssl3_enc->client_finished_label_len; - } - - s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, - sender, - slen, - s->s3->tmp.peer_finish_md); -} -#endif - -int ssl3_get_finished(SSL *s, int a, int b) -{ - int al, i, ok; - long n; - unsigned char *p; - -#ifdef OPENSSL_NO_NEXTPROTONEG - /* - * the mac has already been generated when we received the change cipher - * spec message and is in s->s3->tmp.peer_finish_md - */ -#endif - - /* 64 argument should actually be 36+4 :-) */ - n = s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok); - - if (!ok) - return ((int)n); - - /* If this occurs, we have missed a message */ - if (!s->s3->change_cipher_spec) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS); - goto f_err; - } - s->s3->change_cipher_spec = 0; - - p = (unsigned char *)s->init_msg; - i = s->s3->tmp.peer_finish_md_len; - - if (i != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_BAD_DIGEST_LENGTH); - goto f_err; - } - - if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_DIGEST_CHECK_FAILED); - goto f_err; - } - - /* - * Copy the finished so we can use it for renegotiation checks - */ - if (s->type == SSL_ST_ACCEPT) { - OPENSSL_assert(i <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, i); - s->s3->previous_client_finished_len = i; - } else { - OPENSSL_assert(i <= EVP_MAX_MD_SIZE); - memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, i); - s->s3->previous_server_finished_len = i; - } - - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return (0); -} - -/*- - * for these 2 messages, we need to - * ssl->enc_read_ctx re-init - * ssl->s3->read_sequence zero - * ssl->s3->read_mac_secret re-init - * ssl->session->read_sym_enc assign - * ssl->session->read_compression assign - * ssl->session->read_hash assign - */ -int ssl3_send_change_cipher_spec(SSL *s, int a, int b) -{ - unsigned char *p; - - if (s->state == a) { - p = (unsigned char *)s->init_buf->data; - *p = SSL3_MT_CCS; - s->init_num = 1; - s->init_off = 0; - - s->state = b; - } - - /* SSL3_ST_CW_CHANGE_B */ - return (ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); -} - -unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) -{ - unsigned char *p; - unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s); - - if (!ssl_add_cert_chain(s, cpk, &l)) - return 0; - - l -= 3 + SSL_HM_HEADER_LENGTH(s); - p = ssl_handshake_start(s); - l2n3(l, p); - l += 3; - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, l); - return l + SSL_HM_HEADER_LENGTH(s); -} - -/* - * Obtain handshake message of message type 'mt' (any if mt == -1), maximum - * acceptable body length 'max'. The first four bytes (msg_type and length) - * are read in state 'st1', the body is read in state 'stn'. - */ -long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) -{ - unsigned char *p; - unsigned long l; - long n; - int i, al; - - if (s->s3->tmp.reuse_message) { - s->s3->tmp.reuse_message = 0; - if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - *ok = 1; - s->state = stn; - s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; - s->init_num = (int)s->s3->tmp.message_size; - return s->init_num; - } - - p = (unsigned char *)s->init_buf->data; - - if (s->state == st1) { /* s->init_num < SSL3_HM_HEADER_LENGTH */ - int skip_message; - - do { - while (s->init_num < SSL3_HM_HEADER_LENGTH) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, - &p[s->init_num], - SSL3_HM_HEADER_LENGTH - - s->init_num, 0); - if (i <= 0) { - s->rwstate = SSL_READING; - *ok = 0; - return i; - } - s->init_num += i; - } - - skip_message = 0; - if (!s->server) - if (p[0] == SSL3_MT_HELLO_REQUEST) - /* - * The server may always send 'Hello Request' messages -- - * we are doing a handshake anyway now, so ignore them if - * their format is correct. Does not count for 'Finished' - * MAC. - */ - if (p[1] == 0 && p[2] == 0 && p[3] == 0) { - s->init_num = 0; - skip_message = 1; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, SSL3_HM_HEADER_LENGTH, s, - s->msg_callback_arg); - } - } - while (skip_message); - - /* s->init_num == SSL3_HM_HEADER_LENGTH */ - - if ((mt >= 0) && (*p != mt)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - s->s3->tmp.message_type = *(p++); - - n2l3(p, l); - if (l > (unsigned long)max) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - /* - * Make buffer slightly larger than message length as a precaution - * against small OOB reads e.g. CVE-2016-6306 - */ - if (l - && !BUF_MEM_grow_clean(s->init_buf, - (int)l + SSL3_HM_HEADER_LENGTH + 16)) { - SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); - goto err; - } - s->s3->tmp.message_size = l; - s->state = stn; - - s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; - s->init_num = 0; - } - - /* next state (stn) */ - p = s->init_msg; - n = s->s3->tmp.message_size - s->init_num; - while (n > 0) { - i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], - n, 0); - if (i <= 0) { - s->rwstate = SSL_READING; - *ok = 0; - return i; - } - s->init_num += i; - n -= i; - } - -#ifndef OPENSSL_NO_NEXTPROTONEG - /* - * If receiving Finished, record MAC of prior handshake messages for - * Finished verification. - */ - if (*s->init_buf->data == SSL3_MT_FINISHED) - ssl3_take_mac(s); -#endif - - /* Feed this message into MAC computation. */ - ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->init_num + SSL3_HM_HEADER_LENGTH); - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, - s->msg_callback_arg); - *ok = 1; - return s->init_num; - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - *ok = 0; - return (-1); -} - -int ssl_cert_type(X509 *x, EVP_PKEY *pkey) -{ - EVP_PKEY *pk; - int ret = -1, i; - - if (pkey == NULL) - pk = X509_get_pubkey(x); - else - pk = pkey; - if (pk == NULL) - goto err; - - i = pk->type; - if (i == EVP_PKEY_RSA) { - ret = SSL_PKEY_RSA_ENC; - } else if (i == EVP_PKEY_DSA) { - ret = SSL_PKEY_DSA_SIGN; - } -#ifndef OPENSSL_NO_EC - else if (i == EVP_PKEY_EC) { - ret = SSL_PKEY_ECC; - } -#endif - else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) { - ret = SSL_PKEY_GOST94; - } else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) { - ret = SSL_PKEY_GOST01; - } else if (x && (i == EVP_PKEY_DH || i == EVP_PKEY_DHX)) { - /* - * For DH two cases: DH certificate signed with RSA and DH - * certificate signed with DSA. - */ - i = X509_certificate_type(x, pk); - if (i & EVP_PKS_RSA) - ret = SSL_PKEY_DH_RSA; - else if (i & EVP_PKS_DSA) - ret = SSL_PKEY_DH_DSA; - } - - err: - if (!pkey) - EVP_PKEY_free(pk); - return (ret); -} - -int ssl_verify_alarm_type(long type) -{ - int al; - - switch (type) { - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - case X509_V_ERR_UNABLE_TO_GET_CRL: - case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: - al = SSL_AD_UNKNOWN_CA; - break; - case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: - case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: - case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: - case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: - case X509_V_ERR_CERT_NOT_YET_VALID: - case X509_V_ERR_CRL_NOT_YET_VALID: - case X509_V_ERR_CERT_UNTRUSTED: - case X509_V_ERR_CERT_REJECTED: - case X509_V_ERR_HOSTNAME_MISMATCH: - case X509_V_ERR_EMAIL_MISMATCH: - case X509_V_ERR_IP_ADDRESS_MISMATCH: - al = SSL_AD_BAD_CERTIFICATE; - break; - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - case X509_V_ERR_CRL_SIGNATURE_FAILURE: - al = SSL_AD_DECRYPT_ERROR; - break; - case X509_V_ERR_CERT_HAS_EXPIRED: - case X509_V_ERR_CRL_HAS_EXPIRED: - al = SSL_AD_CERTIFICATE_EXPIRED; - break; - case X509_V_ERR_CERT_REVOKED: - al = SSL_AD_CERTIFICATE_REVOKED; - break; - case X509_V_ERR_UNSPECIFIED: - case X509_V_ERR_OUT_OF_MEM: - case X509_V_ERR_INVALID_CALL: - case X509_V_ERR_STORE_LOOKUP: - al = SSL_AD_INTERNAL_ERROR; - break; - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - case X509_V_ERR_CERT_CHAIN_TOO_LONG: - case X509_V_ERR_PATH_LENGTH_EXCEEDED: - case X509_V_ERR_INVALID_CA: - al = SSL_AD_UNKNOWN_CA; - break; - case X509_V_ERR_APPLICATION_VERIFICATION: - al = SSL_AD_HANDSHAKE_FAILURE; - break; - case X509_V_ERR_INVALID_PURPOSE: - al = SSL_AD_UNSUPPORTED_CERTIFICATE; - break; - default: - al = SSL_AD_CERTIFICATE_UNKNOWN; - break; - } - return (al); -} - -#ifndef OPENSSL_NO_BUF_FREELISTS -/*- - * On some platforms, malloc() performance is bad enough that you can't just - * free() and malloc() buffers all the time, so we need to use freelists from - * unused buffers. Currently, each freelist holds memory chunks of only a - * given size (list->chunklen); other sized chunks are freed and malloced. - * This doesn't help much if you're using many different SSL option settings - * with a given context. (The options affecting buffer size are - * max_send_fragment, read buffer vs write buffer, - * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and - * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.) Using a separate freelist for every - * possible size is not an option, since max_send_fragment can take on many - * different values. - * - * If you are on a platform with a slow malloc(), and you're using SSL - * connections with many different settings for these options, and you need to - * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options: - * - Link against a faster malloc implementation. - * - Use a separate SSL_CTX for each option set. - * - Improve this code. - */ -static void *freelist_extract(SSL_CTX *ctx, int for_read, int sz) -{ - SSL3_BUF_FREELIST *list; - SSL3_BUF_FREELIST_ENTRY *ent = NULL; - void *result = NULL; - - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; - if (list != NULL && sz == (int)list->chunklen) - ent = list->head; - if (ent != NULL) { - list->head = ent->next; - result = ent; - if (--list->len == 0) - list->chunklen = 0; - } - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - if (!result) - result = OPENSSL_malloc(sz); - return result; -} - -static void freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem) -{ - SSL3_BUF_FREELIST *list; - SSL3_BUF_FREELIST_ENTRY *ent; - - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; - if (list != NULL && - (sz == list->chunklen || list->chunklen == 0) && - list->len < ctx->freelist_max_len && sz >= sizeof(*ent)) { - list->chunklen = sz; - ent = mem; - ent->next = list->head; - list->head = ent; - ++list->len; - mem = NULL; - } - - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - if (mem) - OPENSSL_free(mem); -} -#else -# define freelist_extract(c,fr,sz) OPENSSL_malloc(sz) -# define freelist_insert(c,fr,sz,m) OPENSSL_free(m) -#endif - -int ssl3_setup_read_buffer(SSL *s) -{ - unsigned char *p; - size_t len, align = 0, headerlen; - - if (SSL_IS_DTLS(s)) - headerlen = DTLS1_RT_HEADER_LENGTH; - else - headerlen = SSL3_RT_HEADER_LENGTH; - -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - - if (s->s3->rbuf.buf == NULL) { - len = SSL3_RT_MAX_PLAIN_LENGTH - + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; - if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { - s->s3->init_extra = 1; - len += SSL3_RT_MAX_EXTRA; - } -#ifndef OPENSSL_NO_COMP - if (!(s->options & SSL_OP_NO_COMPRESSION)) - len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; -#endif - if ((p = freelist_extract(s->ctx, 1, len)) == NULL) - goto err; - s->s3->rbuf.buf = p; - s->s3->rbuf.len = len; - } - - s->packet = &(s->s3->rbuf.buf[0]); - return 1; - - err: - SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER, ERR_R_MALLOC_FAILURE); - return 0; -} - -int ssl3_setup_write_buffer(SSL *s) -{ - unsigned char *p; - size_t len, align = 0, headerlen; - - if (SSL_IS_DTLS(s)) - headerlen = DTLS1_RT_HEADER_LENGTH + 1; - else - headerlen = SSL3_RT_HEADER_LENGTH; - -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - - if (s->s3->wbuf.buf == NULL) { - len = s->max_send_fragment - + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; -#ifndef OPENSSL_NO_COMP - if (!(s->options & SSL_OP_NO_COMPRESSION)) - len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; -#endif - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) - len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; - - if ((p = freelist_extract(s->ctx, 0, len)) == NULL) - goto err; - s->s3->wbuf.buf = p; - s->s3->wbuf.len = len; - } - - return 1; - - err: - SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE); - return 0; -} - -int ssl3_setup_buffers(SSL *s) -{ - if (!ssl3_setup_read_buffer(s)) - return 0; - if (!ssl3_setup_write_buffer(s)) - return 0; - return 1; -} - -int ssl3_release_write_buffer(SSL *s) -{ - if (s->s3->wbuf.buf != NULL) { - freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf); - s->s3->wbuf.buf = NULL; - } - return 1; -} - -int ssl3_release_read_buffer(SSL *s) -{ - if (s->s3->rbuf.buf != NULL) { - freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf); - s->s3->rbuf.buf = NULL; - } - return 1; -} -/* ssl/s3_cbc.c */ -/* ==================================================================== - * Copyright (c) 2012 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "constant_time_locl.h" -// #include "ssl_locl.h" - -#include "md5.h" -#include "sha.h" - -/* - * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's - * length field. (SHA-384/512 have 128-bit length.) - */ -#define MAX_HASH_BIT_COUNT_BYTES 16 - -/* - * MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. - * Currently SHA-384/512 has a 128-byte block size and that's the largest - * supported by TLS.) - */ -#define MAX_HASH_BLOCK_SIZE 128 - -/*- - * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC - * record in |rec| by updating |rec->length| in constant time. - * - * block_size: the block size of the cipher used to encrypt the record. - * returns: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding was valid - * -1: otherwise. - */ -int ssl3_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - unsigned block_size, unsigned mac_size) -{ - unsigned padding_length, good; - const unsigned overhead = 1 /* padding length byte */ + mac_size; - - /* - * These lengths are all public so we can test them in non-constant time. - */ - if (overhead > rec->length) - return 0; - - padding_length = rec->data[rec->length - 1]; - good = constant_time_ge(rec->length, padding_length + overhead); - /* SSLv3 requires that the padding is minimal. */ - good &= constant_time_ge(block_size, padding_length + 1); - padding_length = good & (padding_length + 1); - rec->length -= padding_length; - rec->type |= padding_length << 8; /* kludge: pass padding length */ - return constant_time_select_int(good, 1, -1); -} - -/*- - * tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC - * record in |rec| in constant time and returns 1 if the padding is valid and - * -1 otherwise. It also removes any explicit IV from the start of the record - * without leaking any timing about whether there was enough space after the - * padding was removed. - * - * block_size: the block size of the cipher used to encrypt the record. - * returns: - * 0: (in non-constant time) if the record is publicly invalid. - * 1: if the padding was valid - * -1: otherwise. - */ -int tls1_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - unsigned block_size, unsigned mac_size) -{ - unsigned padding_length, good, to_check, i; - const unsigned overhead = 1 /* padding length byte */ + mac_size; - /* Check if version requires explicit IV */ - if (SSL_USE_EXPLICIT_IV(s)) { - /* - * These lengths are all public so we can test them in non-constant - * time. - */ - if (overhead + block_size > rec->length) - return 0; - /* We can now safely skip explicit IV */ - rec->data += block_size; - rec->input += block_size; - rec->length -= block_size; - } else if (overhead > rec->length) - return 0; - - padding_length = rec->data[rec->length - 1]; - - /* - * NB: if compression is in operation the first packet may not be of even - * length so the padding bug check cannot be performed. This bug - * workaround has been around since SSLeay so hopefully it is either - * fixed now or no buggy implementation supports compression [steve] - */ - if ((s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) { - /* First packet is even in size, so check */ - if ((CRYPTO_memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0", 8) == 0) && - !(padding_length & 1)) { - s->s3->flags |= TLS1_FLAGS_TLS_PADDING_BUG; - } - if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && padding_length > 0) { - padding_length--; - } - } - - if (EVP_CIPHER_flags(s->enc_read_ctx->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { - /* padding is already verified */ - rec->length -= padding_length + 1; - return 1; - } - - good = constant_time_ge(rec->length, overhead + padding_length); - /* - * The padding consists of a length byte at the end of the record and - * then that many bytes of padding, all with the same value as the length - * byte. Thus, with the length byte included, there are i+1 bytes of - * padding. We can't check just |padding_length+1| bytes because that - * leaks decrypted information. Therefore we always have to check the - * maximum amount of padding possible. (Again, the length of the record - * is public information so we can use it.) - */ - to_check = 255; /* maximum amount of padding. */ - if (to_check > rec->length - 1) - to_check = rec->length - 1; - - for (i = 0; i < to_check; i++) { - unsigned char mask = constant_time_ge_8(padding_length, i); - unsigned char b = rec->data[rec->length - 1 - i]; - /* - * The final |padding_length+1| bytes should all have the value - * |padding_length|. Therefore the XOR should be zero. - */ - good &= ~(mask & (padding_length ^ b)); - } - - /* - * If any of the final |padding_length+1| bytes had the wrong value, one - * or more of the lower eight bits of |good| will be cleared. - */ - good = constant_time_eq(0xff, good & 0xff); - padding_length = good & (padding_length + 1); - rec->length -= padding_length; - rec->type |= padding_length << 8; /* kludge: pass padding length */ - - return constant_time_select_int(good, 1, -1); -} - -/*- - * ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in - * constant time (independent of the concrete value of rec->length, which may - * vary within a 256-byte window). - * - * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to - * this function. - * - * On entry: - * rec->orig_len >= md_size - * md_size <= EVP_MAX_MD_SIZE - * - * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with - * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into - * a single or pair of cache-lines, then the variable memory accesses don't - * actually affect the timing. CPUs with smaller cache-lines [if any] are - * not multi-core and are not considered vulnerable to cache-timing attacks. - */ -#define CBC_MAC_ROTATE_IN_PLACE - -void ssl3_cbc_copy_mac(unsigned char *out, - const SSL3_RECORD *rec, - unsigned md_size, unsigned orig_len) -{ -#if defined(CBC_MAC_ROTATE_IN_PLACE) - unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; - unsigned char *rotated_mac; -#else - unsigned char rotated_mac[EVP_MAX_MD_SIZE]; -#endif - - /* - * mac_end is the index of |rec->data| just after the end of the MAC. - */ - unsigned mac_end = rec->length; - unsigned mac_start = mac_end - md_size; - /* - * scan_start contains the number of bytes that we can ignore because the - * MAC's position can only vary by 255 bytes. - */ - unsigned scan_start = 0; - unsigned i, j; - unsigned div_spoiler; - unsigned rotate_offset; - - OPENSSL_assert(orig_len >= md_size); - OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); - -#if defined(CBC_MAC_ROTATE_IN_PLACE) - rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63); -#endif - - /* This information is public so it's safe to branch based on it. */ - if (orig_len > md_size + 255 + 1) - scan_start = orig_len - (md_size + 255 + 1); - /* - * div_spoiler contains a multiple of md_size that is used to cause the - * modulo operation to be constant time. Without this, the time varies - * based on the amount of padding when running on Intel chips at least. - * The aim of right-shifting md_size is so that the compiler doesn't - * figure out that it can remove div_spoiler as that would require it to - * prove that md_size is always even, which I hope is beyond it. - */ - div_spoiler = md_size >> 1; - div_spoiler <<= (sizeof(div_spoiler) - 1) * 8; - rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; - - memset(rotated_mac, 0, md_size); - for (i = scan_start, j = 0; i < orig_len; i++) { - unsigned char mac_started = constant_time_ge_8(i, mac_start); - unsigned char mac_ended = constant_time_ge_8(i, mac_end); - unsigned char b = rec->data[i]; - rotated_mac[j++] |= b & mac_started & ~mac_ended; - j &= constant_time_lt(j, md_size); - } - - /* Now rotate the MAC */ -#if defined(CBC_MAC_ROTATE_IN_PLACE) - j = 0; - for (i = 0; i < md_size; i++) { - /* in case cache-line is 32 bytes, touch second line */ - ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32]; - out[j++] = rotated_mac[rotate_offset++]; - rotate_offset &= constant_time_lt(rotate_offset, md_size); - } -#else - memset(out, 0, md_size); - rotate_offset = md_size - rotate_offset; - rotate_offset &= constant_time_lt(rotate_offset, md_size); - for (i = 0; i < md_size; i++) { - for (j = 0; j < md_size; j++) - out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); - rotate_offset++; - rotate_offset &= constant_time_lt(rotate_offset, md_size); - } -#endif -} - -/* - * u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in - * little-endian order. The value of p is advanced by four. - */ -#define u32toLE(n, p) \ - (*((p)++)=(unsigned char)(n), \ - *((p)++)=(unsigned char)(n>>8), \ - *((p)++)=(unsigned char)(n>>16), \ - *((p)++)=(unsigned char)(n>>24)) - -/* - * These functions serialize the state of a hash and thus perform the - * standard "final" operation without adding the padding and length that such - * a function typically does. - */ -static void tls1_md5_final_raw(void *ctx, unsigned char *md_out) -{ - MD5_CTX *md5 = ctx; - u32toLE(md5->A, md_out); - u32toLE(md5->B, md_out); - u32toLE(md5->C, md_out); - u32toLE(md5->D, md_out); -} - -static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out) -{ - SHA_CTX *sha1 = ctx; - l2n(sha1->h0, md_out); - l2n(sha1->h1, md_out); - l2n(sha1->h2, md_out); - l2n(sha1->h3, md_out); - l2n(sha1->h4, md_out); -} - -#define LARGEST_DIGEST_CTX SHA_CTX - -#ifndef OPENSSL_NO_SHA256 -static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out) -{ - SHA256_CTX *sha256 = ctx; - unsigned i; - - for (i = 0; i < 8; i++) { - l2n(sha256->h[i], md_out); - } -} - -# undef LARGEST_DIGEST_CTX -# define LARGEST_DIGEST_CTX SHA256_CTX -#endif - -#ifndef OPENSSL_NO_SHA512 -static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) -{ - SHA512_CTX *sha512 = ctx; - unsigned i; - - for (i = 0; i < 8; i++) { - l2n8(sha512->h[i], md_out); - } -} - -# undef LARGEST_DIGEST_CTX -# define LARGEST_DIGEST_CTX SHA512_CTX -#endif - -/* - * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function - * which ssl3_cbc_digest_record supports. - */ -char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) -{ -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return 0; -#endif - switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: - case NID_sha1: -#ifndef OPENSSL_NO_SHA256 - case NID_sha224: - case NID_sha256: -#endif -#ifndef OPENSSL_NO_SHA512 - case NID_sha384: - case NID_sha512: -#endif - return 1; - default: - return 0; - } -} - -/*- - * ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS - * record. - * - * ctx: the EVP_MD_CTX from which we take the hash function. - * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. - * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. - * md_out_size: if non-NULL, the number of output bytes is written here. - * header: the 13-byte, TLS record header. - * data: the record data itself, less any preceeding explicit IV. - * data_plus_mac_size: the secret, reported length of the data and MAC - * once the padding has been removed. - * data_plus_mac_plus_padding_size: the public length of the whole - * record, including padding. - * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. - * - * On entry: by virtue of having been through one of the remove_padding - * functions, above, we know that data_plus_mac_size is large enough to contain - * a padding byte and MAC. (If the padding was invalid, it might contain the - * padding too. ) - * Returns 1 on success or 0 on error - */ -int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, - unsigned char *md_out, - size_t *md_out_size, - const unsigned char header[13], - const unsigned char *data, - size_t data_plus_mac_size, - size_t data_plus_mac_plus_padding_size, - const unsigned char *mac_secret, - unsigned mac_secret_length, char is_sslv3) -{ - union { - double align; - unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; - } md_state; - void (*md_final_raw) (void *ctx, unsigned char *md_out); - void (*md_transform) (void *ctx, const unsigned char *block); - unsigned md_size, md_block_size = 64; - unsigned sslv3_pad_length = 40, header_length, variance_blocks, - len, max_mac_bytes, num_blocks, - num_starting_blocks, k, mac_end_offset, c, index_a, index_b; - unsigned int bits; /* at most 18 bits */ - unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; - /* hmac_pad is the masked HMAC key. */ - unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; - unsigned char first_block[MAX_HASH_BLOCK_SIZE]; - unsigned char mac_out[EVP_MAX_MD_SIZE]; - unsigned i, j, md_out_size_u; - EVP_MD_CTX md_ctx; - /* - * mdLengthSize is the number of bytes in the length field that - * terminates * the hash. - */ - unsigned md_length_size = 8; - char length_is_big_endian = 1; - - /* - * This is a, hopefully redundant, check that allows us to forget about - * many possible overflows later in this function. - */ - OPENSSL_assert(data_plus_mac_plus_padding_size < 1024 * 1024); - - switch (EVP_MD_CTX_type(ctx)) { - case NID_md5: - if (MD5_Init((MD5_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_md5_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))MD5_Transform; - md_size = 16; - sslv3_pad_length = 48; - length_is_big_endian = 0; - break; - case NID_sha1: - if (SHA1_Init((SHA_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha1_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA1_Transform; - md_size = 20; - break; -#ifndef OPENSSL_NO_SHA256 - case NID_sha224: - if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha256_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; - md_size = 224 / 8; - break; - case NID_sha256: - if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha256_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; - md_size = 32; - break; -#endif -#ifndef OPENSSL_NO_SHA512 - case NID_sha384: - if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha512_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA512_Transform; - md_size = 384 / 8; - md_block_size = 128; - md_length_size = 16; - break; - case NID_sha512: - if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0) - return 0; - md_final_raw = tls1_sha512_final_raw; - md_transform = - (void (*)(void *ctx, const unsigned char *block))SHA512_Transform; - md_size = 64; - md_block_size = 128; - md_length_size = 16; - break; -#endif - default: - /* - * ssl3_cbc_record_digest_supported should have been called first to - * check that the hash function is supported. - */ - OPENSSL_assert(0); - if (md_out_size) - *md_out_size = 0; - return 0; - } - - OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); - OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); - OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); - - header_length = 13; - if (is_sslv3) { - header_length = mac_secret_length + sslv3_pad_length + 8 /* sequence - * number */ + - 1 /* record type */ + - 2 /* record length */ ; - } - - /* - * variance_blocks is the number of blocks of the hash that we have to - * calculate in constant time because they could be altered by the - * padding value. In SSLv3, the padding must be minimal so the end of - * the plaintext varies by, at most, 15+20 = 35 bytes. (We conservatively - * assume that the MAC size varies from 0..20 bytes.) In case the 9 bytes - * of hash termination (0x80 + 64-bit length) don't fit in the final - * block, we say that the final two blocks can vary based on the padding. - * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not - * required to be minimal. Therefore we say that the final six blocks can - * vary based on the padding. Later in the function, if the message is - * short and there obviously cannot be this many blocks then - * variance_blocks can be reduced. - */ - variance_blocks = is_sslv3 ? 2 : 6; - /* - * From now on we're dealing with the MAC, which conceptually has 13 - * bytes of `header' before the start of the data (TLS) or 71/75 bytes - * (SSLv3) - */ - len = data_plus_mac_plus_padding_size + header_length; - /* - * max_mac_bytes contains the maximum bytes of bytes in the MAC, - * including * |header|, assuming that there's no padding. - */ - max_mac_bytes = len - md_size - 1; - /* num_blocks is the maximum number of hash blocks. */ - num_blocks = - (max_mac_bytes + 1 + md_length_size + md_block_size - - 1) / md_block_size; - /* - * In order to calculate the MAC in constant time we have to handle the - * final blocks specially because the padding value could cause the end - * to appear somewhere in the final |variance_blocks| blocks and we can't - * leak where. However, |num_starting_blocks| worth of data can be hashed - * right away because no padding value can affect whether they are - * plaintext. - */ - num_starting_blocks = 0; - /* - * k is the starting byte offset into the conceptual header||data where - * we start processing. - */ - k = 0; - /* - * mac_end_offset is the index just past the end of the data to be MACed. - */ - mac_end_offset = data_plus_mac_size + header_length - md_size; - /* - * c is the index of the 0x80 byte in the final hash block that contains - * application data. - */ - c = mac_end_offset % md_block_size; - /* - * index_a is the hash block number that contains the 0x80 terminating - * value. - */ - index_a = mac_end_offset / md_block_size; - /* - * index_b is the hash block number that contains the 64-bit hash length, - * in bits. - */ - index_b = (mac_end_offset + md_length_size) / md_block_size; - /* - * bits is the hash-length in bits. It includes the additional hash block - * for the masked HMAC key, or whole of |header| in the case of SSLv3. - */ - - /* - * For SSLv3, if we're going to have any starting blocks then we need at - * least two because the header is larger than a single block. - */ - if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) { - num_starting_blocks = num_blocks - variance_blocks; - k = md_block_size * num_starting_blocks; - } - - bits = 8 * mac_end_offset; - if (!is_sslv3) { - /* - * Compute the initial HMAC block. For SSLv3, the padding and secret - * bytes are included in |header| because they take more than a - * single block. - */ - bits += 8 * md_block_size; - memset(hmac_pad, 0, md_block_size); - OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); - memcpy(hmac_pad, mac_secret, mac_secret_length); - for (i = 0; i < md_block_size; i++) - hmac_pad[i] ^= 0x36; - - md_transform(md_state.c, hmac_pad); - } - - if (length_is_big_endian) { - memset(length_bytes, 0, md_length_size - 4); - length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24); - length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16); - length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8); - length_bytes[md_length_size - 1] = (unsigned char)bits; - } else { - memset(length_bytes, 0, md_length_size); - length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24); - length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16); - length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8); - length_bytes[md_length_size - 8] = (unsigned char)bits; - } - - if (k > 0) { - if (is_sslv3) { - unsigned overhang; - - /* - * The SSLv3 header is larger than a single block. overhang is - * the number of bytes beyond a single block that the header - * consumes: either 7 bytes (SHA1) or 11 bytes (MD5). There are no - * ciphersuites in SSLv3 that are not SHA1 or MD5 based and - * therefore we can be confident that the header_length will be - * greater than |md_block_size|. However we add a sanity check just - * in case - */ - if (header_length <= md_block_size) { - /* Should never happen */ - return 0; - } - overhang = header_length - md_block_size; - md_transform(md_state.c, header); - memcpy(first_block, header + md_block_size, overhang); - memcpy(first_block + overhang, data, md_block_size - overhang); - md_transform(md_state.c, first_block); - for (i = 1; i < k / md_block_size - 1; i++) - md_transform(md_state.c, data + md_block_size * i - overhang); - } else { - /* k is a multiple of md_block_size. */ - memcpy(first_block, header, 13); - memcpy(first_block + 13, data, md_block_size - 13); - md_transform(md_state.c, first_block); - for (i = 1; i < k / md_block_size; i++) - md_transform(md_state.c, data + md_block_size * i - 13); - } - } - - memset(mac_out, 0, sizeof(mac_out)); - - /* - * We now process the final hash blocks. For each block, we construct it - * in constant time. If the |i==index_a| then we'll include the 0x80 - * bytes and zero pad etc. For each block we selectively copy it, in - * constant time, to |mac_out|. - */ - for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; - i++) { - unsigned char block[MAX_HASH_BLOCK_SIZE]; - unsigned char is_block_a = constant_time_eq_8(i, index_a); - unsigned char is_block_b = constant_time_eq_8(i, index_b); - for (j = 0; j < md_block_size; j++) { - unsigned char b = 0, is_past_c, is_past_cp1; - if (k < header_length) - b = header[k]; - else if (k < data_plus_mac_plus_padding_size + header_length) - b = data[k - header_length]; - k++; - - is_past_c = is_block_a & constant_time_ge_8(j, c); - is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); - /* - * If this is the block containing the end of the application - * data, and we are at the offset for the 0x80 value, then - * overwrite b with 0x80. - */ - b = constant_time_select_8(is_past_c, 0x80, b); - /* - * If this the the block containing the end of the application - * data and we're past the 0x80 value then just write zero. - */ - b = b & ~is_past_cp1; - /* - * If this is index_b (the final block), but not index_a (the end - * of the data), then the 64-bit length didn't fit into index_a - * and we're having to add an extra block of zeros. - */ - b &= ~is_block_b | is_block_a; - - /* - * The final bytes of one of the blocks contains the length. - */ - if (j >= md_block_size - md_length_size) { - /* If this is index_b, write a length byte. */ - b = constant_time_select_8(is_block_b, - length_bytes[j - - (md_block_size - - md_length_size)], b); - } - block[j] = b; - } - - md_transform(md_state.c, block); - md_final_raw(md_state.c, block); - /* If this is index_b, copy the hash value to |mac_out|. */ - for (j = 0; j < md_size; j++) - mac_out[j] |= block[j] & is_block_b; - } - - EVP_MD_CTX_init(&md_ctx); - if (EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ ) <= 0) - goto err; - if (is_sslv3) { - /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ - memset(hmac_pad, 0x5c, sslv3_pad_length); - - if (EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length) <= 0 - || EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length) <= 0 - || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0) - goto err; - } else { - /* Complete the HMAC in the standard manner. */ - for (i = 0; i < md_block_size; i++) - hmac_pad[i] ^= 0x6a; - - if (EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size) <= 0 - || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0) - goto err; - } - EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); - if (md_out_size) - *md_out_size = md_out_size_u; - EVP_MD_CTX_cleanup(&md_ctx); - - return 1; -err: - EVP_MD_CTX_cleanup(&md_ctx); - return 0; -} - -#ifdef OPENSSL_FIPS - -/* - * Due to the need to use EVP in FIPS mode we can't reimplement digests but - * we can ensure the number of blocks processed is equal for all cases by - * digesting additional data. - */ - -void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx, - EVP_MD_CTX *mac_ctx, const unsigned char *data, - size_t data_len, size_t orig_len) -{ - size_t block_size, digest_pad, blocks_data, blocks_orig; - if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE) - return; - block_size = EVP_MD_CTX_block_size(mac_ctx); - /*- - * We are in FIPS mode if we get this far so we know we have only SHA* - * digests and TLS to deal with. - * Minimum digest padding length is 17 for SHA384/SHA512 and 9 - * otherwise. - * Additional header is 13 bytes. To get the number of digest blocks - * processed round up the amount of data plus padding to the nearest - * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise. - * So we have: - * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size - * equivalently: - * blocks = (payload_len + digest_pad + 12)/block_size + 1 - * HMAC adds a constant overhead. - * We're ultimately only interested in differences so this becomes - * blocks = (payload_len + 29)/128 - * for SHA384/SHA512 and - * blocks = (payload_len + 21)/64 - * otherwise. - */ - digest_pad = block_size == 64 ? 21 : 29; - blocks_orig = (orig_len + digest_pad) / block_size; - blocks_data = (data_len + digest_pad) / block_size; - /* - * MAC enough blocks to make up the difference between the original and - * actual lengths plus one extra block to ensure this is never a no op. - * The "data" pointer should always have enough space to perform this - * operation as it is large enough for a maximum length TLS buffer. - */ - EVP_DigestSignUpdate(mac_ctx, data, - (blocks_orig - blocks_data + 1) * block_size); -} -#endif -/* ssl/s3_clnt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * ECC cipher suite support in OpenSSL originally written by - * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -// #include "ssl_locl.h" -#include "kssl_lcl.h" -// #include "buffer.h" -// #include "rand.h" -// #include "objects.h" -// #include "evp.h" -// #include "md5.h" -#ifdef OPENSSL_FIPS -# include -#endif -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#include "bn.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b); -#ifndef OPENSSL_NO_TLSEXT -static int ssl3_check_finished(SSL *s); -#endif - -#ifndef OPENSSL_NO_SSL3_METHOD -static const SSL_METHOD *ssl3_get_client_method(int ver) -{ - if (ver == SSL3_VERSION) - return (SSLv3_client_method()); - else - return (NULL); -} - -IMPLEMENT_ssl3_meth_func(SSLv3_client_method, - ssl_undefined_function, - ssl3_connect, ssl3_get_client_method) -#endif -int ssl3_connect(SSL *s) -{ - BUF_MEM *buf = NULL; - unsigned long Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state, skip = 0; - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - -#ifndef OPENSSL_NO_HEARTBEATS - /* - * If we're awaiting a HeartbeatResponse, pretend we already got and - * don't await it anymore, because Heartbeats don't make sense during - * handshakes anyway. - */ - if (s->tlsext_hb_pending) { - s->tlsext_hb_pending = 0; - s->tlsext_hb_seq++; - } -#endif - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_RENEGOTIATE: - s->renegotiate = 1; - s->state = SSL_ST_CONNECT; - s->ctx->stats.sess_connect_renegotiate++; - /* break */ - case SSL_ST_BEFORE: - case SSL_ST_CONNECT: - case SSL_ST_BEFORE | SSL_ST_CONNECT: - case SSL_ST_OK | SSL_ST_CONNECT: - - s->server = 0; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - if ((s->version & 0xff00) != 0x0300) { - SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - ret = -1; - goto end; - } - - /* s->version=SSL3_VERSION; */ - s->type = SSL_ST_CONNECT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - s->init_buf = buf; - buf = NULL; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* setup buffing BIO */ - if (!ssl_init_wbio_buffer(s, 0)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - /* don't push the buffering BIO quite yet */ - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->state = SSL3_ST_CW_CLNT_HELLO_A; - s->ctx->stats.sess_connect++; - s->init_num = 0; - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; - /* - * Should have been reset by ssl3_get_finished, too. - */ - s->s3->change_cipher_spec = 0; - break; - - case SSL3_ST_CW_CLNT_HELLO_A: - case SSL3_ST_CW_CLNT_HELLO_B: - - s->shutdown = 0; - ret = ssl3_client_hello(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_SRVR_HELLO_A; - s->init_num = 0; - - /* turn on buffering for the next lot of output */ - if (s->bbio != s->wbio) - s->wbio = BIO_push(s->bbio, s->wbio); - - break; - - case SSL3_ST_CR_SRVR_HELLO_A: - case SSL3_ST_CR_SRVR_HELLO_B: - ret = ssl3_get_server_hello(s); - if (ret <= 0) - goto end; - - if (s->hit) { - s->state = SSL3_ST_CR_FINISHED_A; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_ticket_expected) { - /* receive renewed session ticket */ - s->state = SSL3_ST_CR_SESSION_TICKET_A; - } -#endif - } else { - s->state = SSL3_ST_CR_CERT_A; - } - s->init_num = 0; - break; - case SSL3_ST_CR_CERT_A: - case SSL3_ST_CR_CERT_B: -#ifndef OPENSSL_NO_TLSEXT - /* Noop (ret = 0) for everything but EAP-FAST. */ - ret = ssl3_check_finished(s); - if (ret < 0) - goto end; - if (ret == 1) { - s->hit = 1; - s->state = SSL3_ST_CR_FINISHED_A; - s->init_num = 0; - break; - } -#endif - /* Check if it is anon DH/ECDH, SRP auth */ - /* or PSK */ - if (! - (s->s3->tmp. - new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - ret = ssl3_get_server_certificate(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_status_expected) - s->state = SSL3_ST_CR_CERT_STATUS_A; - else - s->state = SSL3_ST_CR_KEY_EXCH_A; - } else { - skip = 1; - s->state = SSL3_ST_CR_KEY_EXCH_A; - } -#else - } else - skip = 1; - - s->state = SSL3_ST_CR_KEY_EXCH_A; -#endif - s->init_num = 0; - break; - - case SSL3_ST_CR_KEY_EXCH_A: - case SSL3_ST_CR_KEY_EXCH_B: - ret = ssl3_get_key_exchange(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_CERT_REQ_A; - s->init_num = 0; - - /* - * at this point we check that we have the required stuff from - * the server - */ - if (!ssl3_check_cert_and_algorithm(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - - case SSL3_ST_CR_CERT_REQ_A: - case SSL3_ST_CR_CERT_REQ_B: - ret = ssl3_get_certificate_request(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_SRVR_DONE_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_SRVR_DONE_A: - case SSL3_ST_CR_SRVR_DONE_B: - ret = ssl3_get_server_done(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SRP - if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) { - if ((ret = SRP_Calc_A_param(s)) <= 0) { - SSLerr(SSL_F_SSL3_CONNECT, SSL_R_SRP_A_CALC); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - goto end; - } - } -#endif - if (s->s3->tmp.cert_req) - s->state = SSL3_ST_CW_CERT_A; - else - s->state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; - - break; - - case SSL3_ST_CW_CERT_A: - case SSL3_ST_CW_CERT_B: - case SSL3_ST_CW_CERT_C: - case SSL3_ST_CW_CERT_D: - ret = ssl3_send_client_certificate(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_KEY_EXCH_A; - s->init_num = 0; - break; - - case SSL3_ST_CW_KEY_EXCH_A: - case SSL3_ST_CW_KEY_EXCH_B: - ret = ssl3_send_client_key_exchange(s); - if (ret <= 0) - goto end; - /* - * EAY EAY EAY need to check for DH fix cert sent back - */ - /* - * For TLS, cert_req is set to 2, so a cert chain of nothing is - * sent, but no verify packet is sent - */ - /* - * XXX: For now, we do not support client authentication in ECDH - * cipher suites with ECDH (rather than ECDSA) certificates. We - * need to skip the certificate verify message when client's - * ECDH public key is sent inside the client certificate. - */ - if (s->s3->tmp.cert_req == 1) { - s->state = SSL3_ST_CW_CERT_VRFY_A; - } else { - s->state = SSL3_ST_CW_CHANGE_A; - } - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { - s->state = SSL3_ST_CW_CHANGE_A; - } - - s->init_num = 0; - break; - - case SSL3_ST_CW_CERT_VRFY_A: - case SSL3_ST_CW_CERT_VRFY_B: - ret = ssl3_send_client_verify(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_CHANGE_A; - s->init_num = 0; - break; - - case SSL3_ST_CW_CHANGE_A: - case SSL3_ST_CW_CHANGE_B: - ret = ssl3_send_change_cipher_spec(s, - SSL3_ST_CW_CHANGE_A, - SSL3_ST_CW_CHANGE_B); - if (ret <= 0) - goto end; - -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->state = SSL3_ST_CW_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) - s->state = SSL3_ST_CW_NEXT_PROTO_A; - else - s->state = SSL3_ST_CW_FINISHED_A; -#endif - s->init_num = 0; - - s->session->cipher = s->s3->tmp.new_cipher; -#ifdef OPENSSL_NO_COMP - s->session->compress_meth = 0; -#else - if (s->s3->tmp.new_compression == NULL) - s->session->compress_meth = 0; - else - s->session->compress_meth = s->s3->tmp.new_compression->id; -#endif - if (!s->method->ssl3_enc->setup_key_block(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_CLIENT_WRITE)) - { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - break; - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - case SSL3_ST_CW_NEXT_PROTO_A: - case SSL3_ST_CW_NEXT_PROTO_B: - ret = ssl3_send_next_proto(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_FINISHED_A; - break; -#endif - - case SSL3_ST_CW_FINISHED_A: - case SSL3_ST_CW_FINISHED_B: - ret = ssl3_send_finished(s, - SSL3_ST_CW_FINISHED_A, - SSL3_ST_CW_FINISHED_B, - s->method-> - ssl3_enc->client_finished_label, - s->method-> - ssl3_enc->client_finished_label_len); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CW_FLUSH; - - /* clear flags */ - s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; - if (s->hit) { - s->s3->tmp.next_state = SSL_ST_OK; - if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { - s->state = SSL_ST_OK; - s->s3->flags |= SSL3_FLAGS_POP_BUFFER; - s->s3->delay_buf_pop_ret = 0; - } - } else { -#ifndef OPENSSL_NO_TLSEXT - /* - * Allow NewSessionTicket if ticket expected - */ - if (s->tlsext_ticket_expected) - s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; - else -#endif - - s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; - } - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_CR_SESSION_TICKET_A: - case SSL3_ST_CR_SESSION_TICKET_B: - ret = ssl3_get_new_session_ticket(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_FINISHED_A; - s->init_num = 0; - break; - - case SSL3_ST_CR_CERT_STATUS_A: - case SSL3_ST_CR_CERT_STATUS_B: - ret = ssl3_get_cert_status(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_CR_KEY_EXCH_A; - s->init_num = 0; - break; -#endif - - case SSL3_ST_CR_FINISHED_A: - case SSL3_ST_CR_FINISHED_B: - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; - ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, - SSL3_ST_CR_FINISHED_B); - if (ret <= 0) - goto end; - - if (s->hit) - s->state = SSL3_ST_CW_CHANGE_A; - else - s->state = SSL_ST_OK; - s->init_num = 0; - break; - - case SSL3_ST_CW_FLUSH: - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - s->state = s->s3->tmp.next_state; - break; - - case SSL_ST_OK: - /* clean a few things up */ - ssl3_cleanup_key_block(s); - - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } - - /* - * If we are not 'joining' the last two packets, remove the - * buffering now - */ - if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) - ssl_free_wbio_buffer(s); - /* else do it later in ssl3_write */ - - s->init_num = 0; - s->renegotiate = 0; - s->new_session = 0; - - ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); - if (s->hit) - s->ctx->stats.sess_hit++; - - ret = 1; - /* s->server=0; */ - s->handshake_func = ssl3_connect; - s->ctx->stats.sess_connect_good++; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - - goto end; - /* break; */ - - case SSL_ST_ERR: - default: - SSLerr(SSL_F_SSL3_CONNECT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - /* did we do anything */ - if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_CONNECT_LOOP, 1); - s->state = new_state; - } - } - skip = 0; - } - end: - s->in_handshake--; - if (buf != NULL) - BUF_MEM_free(buf); - if (cb != NULL) - cb(s, SSL_CB_CONNECT_EXIT, ret); - return (ret); -} - -int ssl3_client_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int i; - unsigned long l; - int al = 0; -#ifndef OPENSSL_NO_COMP - int j; - SSL_COMP *comp; -#endif - - buf = (unsigned char *)s->init_buf->data; - if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { - SSL_SESSION *sess = s->session; - if ((sess == NULL) || (sess->ssl_version != s->version) || -#ifdef OPENSSL_NO_TLSEXT - !sess->session_id_length || -#else - /* - * In the case of EAP-FAST, we can have a pre-shared - * "ticket" without a session ID. - */ - (!sess->session_id_length && !sess->tlsext_tick) || -#endif - (sess->not_resumable)) { - if (!ssl_get_new_session(s, 0)) - goto err; - } - if (s->method->version == DTLS_ANY_VERSION) { - /* Determine which DTLS version to use */ - int options = s->options; - /* If DTLS 1.2 disabled correct the version number */ - if (options & SSL_OP_NO_DTLSv1_2) { - if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - goto err; - } - /* - * Disabling all versions is silly: return an error. - */ - if (options & SSL_OP_NO_DTLSv1) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_WRONG_SSL_VERSION); - goto err; - } - /* - * Update method so we don't use any DTLS 1.2 features. - */ - s->method = DTLSv1_client_method(); - s->version = DTLS1_VERSION; - } else { - /* - * We only support one version: update method - */ - if (options & SSL_OP_NO_DTLSv1) - s->method = DTLSv1_2_client_method(); - s->version = DTLS1_2_VERSION; - } - s->client_version = s->version; - } - /* else use the pre-loaded session */ - - p = s->s3->client_random; - - /* - * for DTLS if client_random is initialized, reuse it, we are - * required to use same upon reply to HelloVerify - */ - if (SSL_IS_DTLS(s)) { - size_t idx; - i = 1; - for (idx = 0; idx < sizeof(s->s3->client_random); idx++) { - if (p[idx]) { - i = 0; - break; - } - } - } else - i = 1; - - if (i && ssl_fill_hello_random(s, 0, p, - sizeof(s->s3->client_random)) <= 0) - goto err; - - /* Do the message type and length last */ - d = p = ssl_handshake_start(s); - - /*- - * version indicates the negotiated version: for example from - * an SSLv2/v3 compatible client hello). The client_version - * field is the maximum version we permit and it is also - * used in RSA encrypted premaster secrets. Some servers can - * choke if we initially report a higher version then - * renegotiate to a lower one in the premaster secret. This - * didn't happen with TLS 1.0 as most servers supported it - * but it can with TLS 1.1 or later if the server only supports - * 1.0. - * - * Possible scenario with previous logic: - * 1. Client hello indicates TLS 1.2 - * 2. Server hello says TLS 1.0 - * 3. RSA encrypted premaster secret uses 1.2. - * 4. Handhaked proceeds using TLS 1.0. - * 5. Server sends hello request to renegotiate. - * 6. Client hello indicates TLS v1.0 as we now - * know that is maximum server supports. - * 7. Server chokes on RSA encrypted premaster secret - * containing version 1.0. - * - * For interoperability it should be OK to always use the - * maximum version we support in client hello and then rely - * on the checking of version to ensure the servers isn't - * being inconsistent: for example initially negotiating with - * TLS 1.0 and renegotiating with TLS 1.2. We do this by using - * client_version in client hello and not resetting it to - * the negotiated version. - */ -#if 0 - *(p++) = s->version >> 8; - *(p++) = s->version & 0xff; - s->client_version = s->version; -#else - *(p++) = s->client_version >> 8; - *(p++) = s->client_version & 0xff; -#endif - - /* Random stuff */ - memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /* Session ID */ - if (s->new_session) - i = 0; - else - i = s->session->session_id_length; - *(p++) = i; - if (i != 0) { - if (i > (int)sizeof(s->session->session_id)) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; - } - memcpy(p, s->session->session_id, i); - p += i; - } - - /* cookie stuff for DTLS */ - if (SSL_IS_DTLS(s)) { - if (s->d1->cookie_len > sizeof(s->d1->cookie)) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; - } - *(p++) = s->d1->cookie_len; - memcpy(p, s->d1->cookie, s->d1->cookie_len); - p += s->d1->cookie_len; - } - - /* Ciphers supported */ - i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0); - if (i == 0) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); - goto err; - } -#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH - /* - * Some servers hang if client hello > 256 bytes as hack workaround - * chop number of supported ciphers to keep it well below this if we - * use TLS v1.2 - */ - if (TLS1_get_version(s) >= TLS1_2_VERSION - && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) - i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; -#endif - s2n(i, p); - p += i; - - /* COMPRESSION */ -#ifdef OPENSSL_NO_COMP - *(p++) = 1; -#else - - if ((s->options & SSL_OP_NO_COMPRESSION) - || !s->ctx->comp_methods) - j = 0; - else - j = sk_SSL_COMP_num(s->ctx->comp_methods); - *(p++) = 1 + j; - for (i = 0; i < j; i++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); - *(p++) = comp->id; - } -#endif - *(p++) = 0; /* Add the NULL method */ - -#ifndef OPENSSL_NO_TLSEXT - /* TLS extensions */ - if (ssl_prepare_clienthello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - goto err; - } - if ((p = - ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH, - &al)) == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto err; - } -#endif - - l = p - d; - ssl_set_handshake_header(s, SSL3_MT_CLIENT_HELLO, l); - s->state = SSL3_ST_CW_CLNT_HELLO_B; - } - - /* SSL3_ST_CW_CLNT_HELLO_B */ - return ssl_do_write(s); - err: - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_server_hello(SSL *s) -{ - STACK_OF(SSL_CIPHER) *sk; - const SSL_CIPHER *c; - CERT *ct = s->cert; - unsigned char *p, *d; - int i, al = SSL_AD_INTERNAL_ERROR, ok; - unsigned int j; - long n; -#ifndef OPENSSL_NO_COMP - SSL_COMP *comp; -#endif - /* - * Hello verify request and/or server hello version may not match so set - * first packet if we're negotiating version. - */ - if (SSL_IS_DTLS(s)) - s->first_packet = 1; - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_SRVR_HELLO_A, - SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, &ok); - - if (!ok) - return ((int)n); - - if (SSL_IS_DTLS(s)) { - s->first_packet = 0; - if (s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) { - if (s->d1->send_cookie == 0) { - s->s3->tmp.reuse_message = 1; - return 1; - } else { /* already sent a cookie */ - - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE); - goto f_err; - } - } - } - - if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE); - goto f_err; - } - - d = p = (unsigned char *)s->init_msg; - if (s->method->version == DTLS_ANY_VERSION) { - /* Work out correct protocol version to use */ - int hversion = (p[0] << 8) | p[1]; - int options = s->options; - if (hversion == DTLS1_2_VERSION && !(options & SSL_OP_NO_DTLSv1_2)) - s->method = DTLSv1_2_client_method(); - else if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - s->version = hversion; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } else if (hversion == DTLS1_VERSION && !(options & SSL_OP_NO_DTLSv1)) - s->method = DTLSv1_client_method(); - else { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); - s->version = hversion; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - s->session->ssl_version = s->version = s->method->version; - } - - if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); - s->version = (s->version & 0xff00) | p[1]; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - p += 2; - - /* load the server hello data */ - /* load the server random */ - memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - s->hit = 0; - - /* get the session-id */ - j = *(p++); - - if ((j > sizeof(s->session->session_id)) || (j > SSL3_SESSION_ID_SIZE)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SSL3_SESSION_ID_TOO_LONG); - goto f_err; - } -#ifndef OPENSSL_NO_TLSEXT - /* - * Check if we can resume the session based on external pre-shared secret. - * EAP-FAST (RFC 4851) supports two types of session resumption. - * Resumption based on server-side state works with session IDs. - * Resumption based on pre-shared Protected Access Credentials (PACs) - * works by overriding the SessionTicket extension at the application - * layer, and does not send a session ID. (We do not know whether EAP-FAST - * servers would honour the session ID.) Therefore, the session ID alone - * is not a reliable indicator of session resumption, so we first check if - * we can resume, and later peek at the next handshake message to see if the - * server wants to resume. - */ - if (s->version >= TLS1_VERSION && s->tls_session_secret_cb && - s->session->tlsext_tick) { - SSL_CIPHER *pref_cipher = NULL; - s->session->master_key_length = sizeof(s->session->master_key); - if (s->tls_session_secret_cb(s, s->session->master_key, - &s->session->master_key_length, - NULL, &pref_cipher, - s->tls_session_secret_cb_arg)) { - s->session->cipher = pref_cipher ? - pref_cipher : ssl_get_cipher_by_char(s, p + j); - } else { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - } -#endif /* OPENSSL_NO_TLSEXT */ - - if (j != 0 && j == s->session->session_id_length - && memcmp(p, s->session->session_id, j) == 0) { - if (s->sid_ctx_length != s->session->sid_ctx_length - || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) { - /* actually a client application bug */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); - goto f_err; - } - s->hit = 1; - } else { - /* - * If we were trying for session-id reuse but the server - * didn't echo the ID, make a new SSL_SESSION. - * In the case of EAP-FAST and PAC, we do not send a session ID, - * so the PAC-based session secret is always preserved. It'll be - * overwritten if the server refuses resumption. - */ - if (s->session->session_id_length > 0) { - if (!ssl_get_new_session(s, 0)) { - goto f_err; - } - } - s->session->session_id_length = j; - memcpy(s->session->session_id, p, j); /* j could be 0 */ - } - p += j; - c = ssl_get_cipher_by_char(s, p); - if (c == NULL) { - /* unknown cipher */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_UNKNOWN_CIPHER_RETURNED); - goto f_err; - } - /* Set version disabled mask now we know version */ - if (!SSL_USE_TLS1_2_CIPHERS(s)) - ct->mask_ssl = SSL_TLSV1_2; - else - ct->mask_ssl = 0; - /* - * If it is a disabled cipher we didn't send it in client hello, so - * return an error. - */ - if (c->algorithm_ssl & ct->mask_ssl || - c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); - goto f_err; - } - p += ssl_put_cipher_by_char(s, NULL, NULL); - - sk = ssl_get_ciphers_by_id(s); - i = sk_SSL_CIPHER_find(sk, c); - if (i < 0) { - /* we did not say we would use this cipher */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); - goto f_err; - } - - /* - * Depending on the session caching (internal/external), the cipher - * and/or cipher_id values may not be set. Make sure that cipher_id is - * set and use it for comparison. - */ - if (s->session->cipher) - s->session->cipher_id = s->session->cipher->id; - if (s->hit && (s->session->cipher_id != c->id)) { -/* Workaround is now obsolete */ -#if 0 - if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) -#endif - { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); - goto f_err; - } - } - s->s3->tmp.new_cipher = c; - /* - * Don't digest cached records if no sigalgs: we may need them for client - * authentication. - */ - if (!SSL_USE_SIGALGS(s) && !ssl3_digest_cached_records(s)) - goto f_err; - /* lets get the compression algorithm */ - /* COMPRESSION */ -#ifdef OPENSSL_NO_COMP - if (*(p++) != 0) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); - goto f_err; - } - /* - * If compression is disabled we'd better not try to resume a session - * using compression. - */ - if (s->session->compress_meth != 0) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_INCONSISTENT_COMPRESSION); - goto f_err; - } -#else - j = *(p++); - if (s->hit && j != s->session->compress_meth) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED); - goto f_err; - } - if (j == 0) - comp = NULL; - else if (s->options & SSL_OP_NO_COMPRESSION) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_COMPRESSION_DISABLED); - goto f_err; - } else - comp = ssl3_comp_find(s->ctx->comp_methods, j); - - if ((j != 0) && (comp == NULL)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); - goto f_err; - } else { - s->s3->tmp.new_compression = comp; - } -#endif - -#ifndef OPENSSL_NO_TLSEXT - /* TLS extensions */ - if (!ssl_parse_serverhello_tlsext(s, &p, d, n)) { - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_PARSE_TLSEXT); - goto err; - } -#endif - - if (p != (d + n)) { - /* wrong packet length */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH); - goto f_err; - } - - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_server_certificate(SSL *s) -{ - int al, i, ok, ret = -1; - unsigned long n, nc, llen, l; - X509 *x = NULL; - const unsigned char *q, *p; - unsigned char *d; - STACK_OF(X509) *sk = NULL; - SESS_CERT *sc; - EVP_PKEY *pkey = NULL; - int need_cert = 1; /* VRS: 0=> will allow null cert if auth == - * KRB5 */ - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_CERT_A, - SSL3_ST_CR_CERT_B, - -1, s->max_cert_list, &ok); - - if (!ok) - return ((int)n); - - if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) || - ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && - (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE))) { - s->s3->tmp.reuse_message = 1; - return (1); - } - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_BAD_MESSAGE_TYPE); - goto f_err; - } - p = d = (unsigned char *)s->init_msg; - - if ((sk = sk_X509_new_null()) == NULL) { - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - - n2l3(p, llen); - if (llen + 3 != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - for (nc = 0; nc < llen;) { - if (nc + 3 > llen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - n2l3(p, l); - if ((l + nc + 3) > llen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - - q = p; - x = d2i_X509(NULL, &q, l); - if (x == NULL) { - al = SSL_AD_BAD_CERTIFICATE; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_ASN1_LIB); - goto f_err; - } - if (q != (p + l)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - if (!sk_X509_push(sk, x)) { - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - x = NULL; - nc += l + 3; - p = q; - } - - i = ssl_verify_cert_chain(s, sk); - if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0) -#ifndef OPENSSL_NO_KRB5 - && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) -#endif /* OPENSSL_NO_KRB5 */ - ) { - al = ssl_verify_alarm_type(s->verify_result); - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_CERTIFICATE_VERIFY_FAILED); - goto f_err; - } - ERR_clear_error(); /* but we keep s->verify_result */ - - sc = ssl_sess_cert_new(); - if (sc == NULL) - goto err; - - if (s->session->sess_cert) - ssl_sess_cert_free(s->session->sess_cert); - s->session->sess_cert = sc; - - sc->cert_chain = sk; - /* - * Inconsistency alert: cert_chain does include the peer's certificate, - * which we don't include in s3_srvr.c - */ - x = sk_X509_value(sk, 0); - sk = NULL; - /* - * VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end - */ - - pkey = X509_get_pubkey(x); - - /* VRS: allow null cert if auth == KRB5 */ - need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) - ? 0 : 1; - -#ifdef KSSL_DEBUG - fprintf(stderr, "pkey,x = %p, %p\n", pkey, x); - fprintf(stderr, "ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x, pkey)); - fprintf(stderr, "cipher, alg, nc = %s, %lx, %lx, %d\n", - s->s3->tmp.new_cipher->name, - s->s3->tmp.new_cipher->algorithm_mkey, - s->s3->tmp.new_cipher->algorithm_auth, need_cert); -#endif /* KSSL_DEBUG */ - - if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) { - x = NULL; - al = SSL3_AL_FATAL; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); - goto f_err; - } - - i = ssl_cert_type(x, pkey); - if (need_cert && i < 0) { - x = NULL; - al = SSL3_AL_FATAL; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_UNKNOWN_CERTIFICATE_TYPE); - goto f_err; - } - - if (need_cert) { - int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); - if (exp_idx >= 0 && i != exp_idx) { - x = NULL; - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, - SSL_R_WRONG_CERTIFICATE_TYPE); - goto f_err; - } - sc->peer_cert_type = i; - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - /* - * Why would the following ever happen? We just created sc a couple - * of lines ago. - */ - if (sc->peer_pkeys[i].x509 != NULL) - X509_free(sc->peer_pkeys[i].x509); - sc->peer_pkeys[i].x509 = x; - sc->peer_key = &(sc->peer_pkeys[i]); - - if (s->session->peer != NULL) - X509_free(s->session->peer); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - s->session->peer = x; - } else { - sc->peer_cert_type = i; - sc->peer_key = NULL; - - if (s->session->peer != NULL) - X509_free(s->session->peer); - s->session->peer = NULL; - } - s->session->verify_result = s->verify_result; - - x = NULL; - ret = 1; - if (0) { - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - } - - EVP_PKEY_free(pkey); - X509_free(x); - sk_X509_pop_free(sk, X509_free); - return (ret); -} - -int ssl3_get_key_exchange(SSL *s) -{ -#ifndef OPENSSL_NO_RSA - unsigned char *q, md_buf[EVP_MAX_MD_SIZE * 2]; -#endif - EVP_MD_CTX md_ctx; - unsigned char *param, *p; - int al, j, ok; - long i, param_len, n, alg_k, alg_a; - EVP_PKEY *pkey = NULL; - const EVP_MD *md = NULL; -#ifndef OPENSSL_NO_RSA - RSA *rsa = NULL; -#endif -#ifndef OPENSSL_NO_DH - DH *dh = NULL; -#endif -#ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh = NULL; - BN_CTX *bn_ctx = NULL; - EC_POINT *srvr_ecpoint = NULL; - int curve_nid = 0; - int encoded_pt_len = 0; -#endif - - EVP_MD_CTX_init(&md_ctx); - - /* - * use same message size as in ssl3_get_certificate_request() as - * ServerKeyExchange message may be skipped - */ - n = s->method->ssl_get_message(s, - SSL3_ST_CR_KEY_EXCH_A, - SSL3_ST_CR_KEY_EXCH_B, - -1, s->max_cert_list, &ok); - if (!ok) - return ((int)n); - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - - if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { - /* - * Can't skip server key exchange if this is an ephemeral - * ciphersuite. - */ - if (alg_k & (SSL_kDHE | SSL_kECDHE)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - al = SSL_AD_UNEXPECTED_MESSAGE; - goto f_err; - } -#ifndef OPENSSL_NO_PSK - /* - * In plain PSK ciphersuite, ServerKeyExchange can be omitted if no - * identity hint is sent. Set session->sess_cert anyway to avoid - * problems later. - */ - if (alg_k & SSL_kPSK) { - s->session->sess_cert = ssl_sess_cert_new(); - if (s->ctx->psk_identity_hint) - OPENSSL_free(s->ctx->psk_identity_hint); - s->ctx->psk_identity_hint = NULL; - } -#endif - s->s3->tmp.reuse_message = 1; - return (1); - } - - param = p = (unsigned char *)s->init_msg; - if (s->session->sess_cert != NULL) { -#ifndef OPENSSL_NO_RSA - if (s->session->sess_cert->peer_rsa_tmp != NULL) { - RSA_free(s->session->sess_cert->peer_rsa_tmp); - s->session->sess_cert->peer_rsa_tmp = NULL; - } -#endif -#ifndef OPENSSL_NO_DH - if (s->session->sess_cert->peer_dh_tmp) { - DH_free(s->session->sess_cert->peer_dh_tmp); - s->session->sess_cert->peer_dh_tmp = NULL; - } -#endif -#ifndef OPENSSL_NO_ECDH - if (s->session->sess_cert->peer_ecdh_tmp) { - EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); - s->session->sess_cert->peer_ecdh_tmp = NULL; - } -#endif - } else { - s->session->sess_cert = ssl_sess_cert_new(); - } - - /* Total length of the parameters including the length prefix */ - param_len = 0; - - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - - al = SSL_AD_DECODE_ERROR; - -#ifndef OPENSSL_NO_PSK - if (alg_k & SSL_kPSK) { - param_len = 2; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - /* - * Store PSK identity hint for later use, hint is used in - * ssl3_send_client_key_exchange. Assume that the maximum length of - * a PSK identity hint can be as long as the maximum length of a PSK - * identity. - */ - if (i > PSK_MAX_IDENTITY_LEN) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); - goto f_err; - } - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); - goto f_err; - } - param_len += i; - - s->session->psk_identity_hint = BUF_strndup((char *)p, i); - if (s->session->psk_identity_hint == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto f_err; - } - - p += i; - n -= param_len; - } else -#endif /* !OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - if (alg_k & SSL_kSRP) { - param_len = 2; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH); - goto f_err; - } - param_len += i; - - if (!(s->srp_ctx.N = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH); - goto f_err; - } - param_len += i; - - if (!(s->srp_ctx.g = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (1 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 1; - - i = (unsigned int)(p[0]); - p++; - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_S_LENGTH); - goto f_err; - } - param_len += i; - - if (!(s->srp_ctx.s = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_B_LENGTH); - goto f_err; - } - param_len += i; - - if (!(s->srp_ctx.B = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - n -= param_len; - - if (!srp_verify_server_param(s, &al)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_PARAMETERS); - goto f_err; - } - -/* We must check if there is a certificate */ -# ifndef OPENSSL_NO_RSA - if (alg_a & SSL_aRSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); -# else - if (0) ; -# endif -# ifndef OPENSSL_NO_DSA - else if (alg_a & SSL_aDSS) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN]. - x509); -# endif - } else -#endif /* !OPENSSL_NO_SRP */ -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - /* Temporary RSA keys only allowed in export ciphersuites */ - if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - if ((rsa = RSA_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - param_len = 2; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH); - goto f_err; - } - param_len += i; - - if (!(rsa->n = BN_bin2bn(p, i, rsa->n))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_E_LENGTH); - goto f_err; - } - param_len += i; - - if (!(rsa->e = BN_bin2bn(p, i, rsa->e))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - n -= param_len; - - /* this should be because we are using an export cipher */ - if (alg_a & SSL_aRSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); - else { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - if (EVP_PKEY_bits(pkey) <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } - - s->session->sess_cert->peer_rsa_tmp = rsa; - rsa = NULL; - } -#else /* OPENSSL_NO_RSA */ - if (0) ; -#endif -#ifndef OPENSSL_NO_DH - else if (alg_k & SSL_kEDH) { - if ((dh = DH_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - - param_len = 2; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH); - goto f_err; - } - param_len += i; - - if (!(dh->p = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_LENGTH); - goto f_err; - } - param_len += i; - - if (!(dh->g = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - - if (2 > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - param_len += 2; - - n2s(p, i); - - if (i > n - param_len) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_LENGTH); - goto f_err; - } - param_len += i; - - if (!(dh->pub_key = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - p += i; - n -= param_len; - - if (BN_is_zero(dh->pub_key)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE); - goto f_err; - } - - /*- - * Check that p and g are suitable enough - * - * p is odd - * 1 < g < p - 1 - */ - { - BIGNUM *tmp = NULL; - - if (!BN_is_odd(dh->p)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE); - goto f_err; - } - if (BN_is_negative(dh->g) || BN_is_zero(dh->g) - || BN_is_one(dh->g)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); - goto f_err; - } - if ((tmp = BN_new()) == NULL - || BN_copy(tmp, dh->p) == NULL - || !BN_sub_word(tmp, 1)) { - BN_free(tmp); - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - if (BN_cmp(dh->g, tmp) >= 0) { - BN_free(tmp); - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); - goto f_err; - } - BN_free(tmp); - } - -# ifndef OPENSSL_NO_RSA - if (alg_a & SSL_aRSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); -# else - if (0) ; -# endif -# ifndef OPENSSL_NO_DSA - else if (alg_a & SSL_aDSS) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN]. - x509); -# endif - /* else anonymous DH, so no certificate or pkey. */ - - s->session->sess_cert->peer_dh_tmp = dh; - dh = NULL; - } else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); - goto f_err; - } -#endif /* !OPENSSL_NO_DH */ - -#ifndef OPENSSL_NO_ECDH - else if (alg_k & SSL_kEECDH) { - EC_GROUP *ngroup; - const EC_GROUP *group; - - if ((ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * Extract elliptic curve parameters and the server's ephemeral ECDH - * public key. Keep accumulating lengths of various components in - * param_len and make sure it never exceeds n. - */ - - /* - * XXX: For now we only support named (not generic) curves and the - * ECParameters in this case is just three bytes. We also need one - * byte for the length of the encoded point - */ - param_len = 4; - if (param_len > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - /* - * Check curve is one of our preferences, if not server has sent an - * invalid curve. ECParameters is 3 bytes. - */ - if (!tls1_check_curve(s, p, 3)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE); - goto f_err; - } - - if ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); - goto f_err; - } - - ngroup = EC_GROUP_new_by_curve_name(curve_nid); - if (ngroup == NULL) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - if (EC_KEY_set_group(ecdh, ngroup) == 0) { - EC_GROUP_free(ngroup); - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - EC_GROUP_free(ngroup); - - group = EC_KEY_get0_group(ecdh); - - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - (EC_GROUP_get_degree(group) > 163)) { - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); - goto f_err; - } - - p += 3; - - /* Next, get the encoded ECPoint */ - if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || - ((bn_ctx = BN_CTX_new()) == NULL)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - encoded_pt_len = *p; /* length of encoded point */ - p += 1; - - if ((encoded_pt_len > n - param_len) || - (EC_POINT_oct2point(group, srvr_ecpoint, - p, encoded_pt_len, bn_ctx) == 0)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); - goto f_err; - } - param_len += encoded_pt_len; - - n -= param_len; - p += encoded_pt_len; - - /* - * The ECC/TLS specification does not mention the use of DSA to sign - * ECParameters in the server key exchange message. We do support RSA - * and ECDSA. - */ - if (0) ; -# ifndef OPENSSL_NO_RSA - else if (alg_a & SSL_aRSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); -# endif -# ifndef OPENSSL_NO_ECDSA - else if (alg_a & SSL_aECDSA) - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); -# endif - /* else anonymous ECDH, so no certificate or pkey. */ - EC_KEY_set_public_key(ecdh, srvr_ecpoint); - s->session->sess_cert->peer_ecdh_tmp = ecdh; - ecdh = NULL; - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - EC_POINT_free(srvr_ecpoint); - srvr_ecpoint = NULL; - } else if (alg_k) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); - goto f_err; - } -#endif /* !OPENSSL_NO_ECDH */ - - /* p points to the next byte, there are 'n' bytes left */ - - /* if it was signed, check the signature */ - if (pkey != NULL) { - if (SSL_USE_SIGALGS(s)) { - int rv; - if (2 > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - rv = tls12_check_peer_sigalg(&md, s, p, pkey); - if (rv == -1) - goto err; - else if (rv == 0) { - goto f_err; - } -#ifdef SSL_DEBUG - fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); -#endif - p += 2; - n -= 2; - } else - md = EVP_sha1(); - - if (2 > n) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - n -= 2; - j = EVP_PKEY_size(pkey); - - /* - * Check signature length. If n is 0 then signature is empty - */ - if ((i != n) || (n > j) || (n <= 0)) { - /* wrong packet length */ - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH); - goto f_err; - } -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { - int num; - unsigned int size; - - j = 0; - q = md_buf; - for (num = 2; num > 0; num--) { - EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - if (EVP_DigestInit_ex(&md_ctx, - (num == 2) ? s->ctx->md5 : s->ctx->sha1, - NULL) <= 0 - || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&md_ctx, param, param_len) <= 0 - || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - q += size; - j += size; - } - i = RSA_verify(NID_md5_sha1, md_buf, j, p, n, pkey->pkey.rsa); - if (i < 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT); - goto f_err; - } - if (i == 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); - goto f_err; - } - } else -#endif - { - if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0 - || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_VerifyUpdate(&md_ctx, param, param_len) <= 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EVP_LIB); - goto f_err; - } - if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); - goto f_err; - } - } - } else { - /* aNULL, aSRP or kPSK do not need public keys */ - if (!(alg_a & (SSL_aNULL | SSL_aSRP)) && !(alg_k & SSL_kPSK)) { - /* Might be wrong key type, check it */ - if (ssl3_check_cert_and_algorithm(s)) - /* Otherwise this shouldn't happen */ - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - /* still data left over */ - if (n != 0) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE); - goto f_err; - } - } - EVP_PKEY_free(pkey); - EVP_MD_CTX_cleanup(&md_ctx); - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - EVP_PKEY_free(pkey); -#ifndef OPENSSL_NO_RSA - if (rsa != NULL) - RSA_free(rsa); -#endif -#ifndef OPENSSL_NO_DH - if (dh != NULL) - DH_free(dh); -#endif -#ifndef OPENSSL_NO_ECDH - BN_CTX_free(bn_ctx); - EC_POINT_free(srvr_ecpoint); - if (ecdh != NULL) - EC_KEY_free(ecdh); -#endif - EVP_MD_CTX_cleanup(&md_ctx); - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_certificate_request(SSL *s) -{ - int ok, ret = 0; - unsigned long n, nc, l; - unsigned int llen, ctype_num, i; - X509_NAME *xn = NULL; - const unsigned char *p, *q; - unsigned char *d; - STACK_OF(X509_NAME) *ca_sk = NULL; - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_CERT_REQ_A, - SSL3_ST_CR_CERT_REQ_B, - -1, s->max_cert_list, &ok); - - if (!ok) - return ((int)n); - - s->s3->tmp.cert_req = 0; - - if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) { - s->s3->tmp.reuse_message = 1; - /* - * If we get here we don't need any cached handshake records as we - * wont be doing client auth. - */ - if (s->s3->handshake_buffer) { - if (!ssl3_digest_cached_records(s)) - goto err; - } - return (1); - } - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_WRONG_MESSAGE_TYPE); - goto err; - } - - /* TLS does not like anon-DH with client cert */ - if (s->version > SSL3_VERSION) { - if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, - SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); - goto err; - } - } - - p = d = (unsigned char *)s->init_msg; - - if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* get the certificate types */ - ctype_num = *(p++); - if (s->cert->ctypes) { - OPENSSL_free(s->cert->ctypes); - s->cert->ctypes = NULL; - } - if (ctype_num > SSL3_CT_NUMBER) { - /* If we exceed static buffer copy all to cert structure */ - s->cert->ctypes = OPENSSL_malloc(ctype_num); - if (s->cert->ctypes == NULL) { - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); - goto err; - } - memcpy(s->cert->ctypes, p, ctype_num); - s->cert->ctype_num = (size_t)ctype_num; - ctype_num = SSL3_CT_NUMBER; - } - for (i = 0; i < ctype_num; i++) - s->s3->tmp.ctype[i] = p[i]; - p += p[-1]; - if (SSL_USE_SIGALGS(s)) { - n2s(p, llen); - /* - * Check we have enough room for signature algorithms and following - * length value. - */ - if ((unsigned long)(p - d + llen + 2) > n) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - /* Clear certificate digests and validity flags */ - for (i = 0; i < SSL_PKEY_NUM; i++) { - s->cert->pkeys[i].digest = NULL; - s->cert->pkeys[i].valid_flags = 0; - } - if ((llen & 1) || !tls1_save_sigalgs(s, p, llen)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, - SSL_R_SIGNATURE_ALGORITHMS_ERROR); - goto err; - } - if (!tls1_process_sigalgs(s)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); - goto err; - } - p += llen; - } - - /* get the CA RDNs */ - n2s(p, llen); -#if 0 - { - FILE *out; - out = fopen("/tmp/vsign.der", "w"); - fwrite(p, 1, llen, out); - fclose(out); - } -#endif - - if ((unsigned long)(p - d + llen) != n) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); - goto err; - } - - for (nc = 0; nc < llen;) { - if (nc + 2 > llen) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); - goto err; - } - n2s(p, l); - if ((l + nc + 2) > llen) { - if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) - goto cont; /* netscape bugs */ - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); - goto err; - } - - q = p; - - if ((xn = d2i_X509_NAME(NULL, &q, l)) == NULL) { - /* If netscape tolerance is on, ignore errors */ - if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG) - goto cont; - else { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB); - goto err; - } - } - - if (q != (p + l)) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, - SSL_R_CA_DN_LENGTH_MISMATCH); - goto err; - } - if (!sk_X509_NAME_push(ca_sk, xn)) { - SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); - goto err; - } - xn = NULL; - - p += l; - nc += l + 2; - } - - if (0) { - cont: - ERR_clear_error(); - } - - /* we should setup a certificate to return.... */ - s->s3->tmp.cert_req = 1; - s->s3->tmp.ctype_num = ctype_num; - if (s->s3->tmp.ca_names != NULL) - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - s->s3->tmp.ca_names = ca_sk; - ca_sk = NULL; - - ret = 1; - goto done; - err: - s->state = SSL_ST_ERR; - done: - X509_NAME_free(xn); - if (ca_sk != NULL) - sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); - return (ret); -} - -static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b) -{ - return (X509_NAME_cmp(*a, *b)); -} - -#ifndef OPENSSL_NO_TLSEXT -int ssl3_get_new_session_ticket(SSL *s) -{ - int ok, al, ret = 0, ticklen; - long n; - const unsigned char *p; - unsigned char *d; - unsigned long ticket_lifetime_hint; - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_SESSION_TICKET_A, - SSL3_ST_CR_SESSION_TICKET_B, - SSL3_MT_NEWSESSION_TICKET, 16384, &ok); - - if (!ok) - return ((int)n); - - if (n < 6) { - /* need at least ticket_lifetime_hint + ticket length */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - - p = d = (unsigned char *)s->init_msg; - - n2l(p, ticket_lifetime_hint); - n2s(p, ticklen); - /* ticket_lifetime_hint + ticket_length + ticket */ - if (ticklen + 6 != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - - /* Server is allowed to change its mind and send an empty ticket. */ - if (ticklen == 0) - return 1; - - if (s->session->session_id_length > 0) { - int i = s->session_ctx->session_cache_mode; - SSL_SESSION *new_sess; - /* - * We reused an existing session, so we need to replace it with a new - * one - */ - if (i & SSL_SESS_CACHE_CLIENT) { - /* - * Remove the old session from the cache - */ - if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) { - if (s->session_ctx->remove_session_cb != NULL) - s->session_ctx->remove_session_cb(s->session_ctx, - s->session); - } else { - /* We carry on if this fails */ - SSL_CTX_remove_session(s->session_ctx, s->session); - } - } - - if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); - goto f_err; - } - - SSL_SESSION_free(s->session); - s->session = new_sess; - } - - if (s->session->tlsext_tick) { - OPENSSL_free(s->session->tlsext_tick); - s->session->tlsext_ticklen = 0; - } - s->session->tlsext_tick = OPENSSL_malloc(ticklen); - if (!s->session->tlsext_tick) { - SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); - goto err; - } - memcpy(s->session->tlsext_tick, p, ticklen); - s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; - s->session->tlsext_ticklen = ticklen; - /* - * There are two ways to detect a resumed ticket session. One is to set - * an appropriate session ID and then the server must return a match in - * ServerHello. This allows the normal client session ID matching to work - * and we know much earlier that the ticket has been accepted. The - * other way is to set zero length session ID when the ticket is - * presented and rely on the handshake to determine session resumption. - * We choose the former approach because this fits in with assumptions - * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is - * SHA256 is disabled) hash of the ticket. - */ - EVP_Digest(p, ticklen, - s->session->session_id, &s->session->session_id_length, -# ifndef OPENSSL_NO_SHA256 - EVP_sha256(), NULL); -# else - EVP_sha1(), NULL); -# endif - ret = 1; - return (ret); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_cert_status(SSL *s) -{ - int ok, al; - unsigned long resplen, n; - const unsigned char *p; - - n = s->method->ssl_get_message(s, - SSL3_ST_CR_CERT_STATUS_A, - SSL3_ST_CR_CERT_STATUS_B, - -1, 16384, &ok); - - if (!ok) - return ((int)n); - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { - /* - * The CertificateStatus message is optional even if - * tlsext_status_expected is set - */ - s->s3->tmp.reuse_message = 1; - } else { - if (n < 4) { - /* need at least status type + length */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - p = (unsigned char *)s->init_msg; - if (*p++ != TLSEXT_STATUSTYPE_ocsp) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE); - goto f_err; - } - n2l3(p, resplen); - if (resplen + 4 != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - s->tlsext_ocsp_resp = BUF_memdup(p, resplen); - if (s->tlsext_ocsp_resp == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE); - goto f_err; - } - s->tlsext_ocsp_resplen = resplen; - } - if (s->ctx->tlsext_status_cb) { - int ret; - ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - if (ret == 0) { - al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_INVALID_STATUS_RESPONSE); - goto f_err; - } - if (ret < 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE); - goto f_err; - } - } - return 1; - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->state = SSL_ST_ERR; - return (-1); -} -#endif - -int ssl3_get_server_done(SSL *s) -{ - int ok, ret = 0; - long n; - - /* Second to last param should be very small, like 0 :-) */ - n = s->method->ssl_get_message(s, - SSL3_ST_CR_SRVR_DONE_A, - SSL3_ST_CR_SRVR_DONE_B, - SSL3_MT_SERVER_DONE, 30, &ok); - - if (!ok) - return ((int)n); - if (n > 0) { - /* should contain no data */ - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); - SSLerr(SSL_F_SSL3_GET_SERVER_DONE, SSL_R_LENGTH_MISMATCH); - s->state = SSL_ST_ERR; - return -1; - } - ret = 1; - return (ret); -} - -#ifndef OPENSSL_NO_DH -static DH *get_server_static_dh_key(SESS_CERT *scert) -{ - DH *dh_srvr = NULL; - EVP_PKEY *spkey = NULL; - int idx = scert->peer_cert_type; - - if (idx >= 0) - spkey = X509_get_pubkey(scert->peer_pkeys[idx].x509); - if (spkey) { - dh_srvr = EVP_PKEY_get1_DH(spkey); - EVP_PKEY_free(spkey); - } - if (dh_srvr == NULL) - SSLerr(SSL_F_GET_SERVER_STATIC_DH_KEY, ERR_R_INTERNAL_ERROR); - return dh_srvr; -} -#endif - -int ssl3_send_client_key_exchange(SSL *s) -{ - unsigned char *p; - int n; - unsigned long alg_k; -#ifndef OPENSSL_NO_RSA - unsigned char *q; - EVP_PKEY *pkey = NULL; -#endif -#ifndef OPENSSL_NO_KRB5 - KSSL_ERR kssl_err; -#endif /* OPENSSL_NO_KRB5 */ -#ifndef OPENSSL_NO_ECDH - EC_KEY *clnt_ecdh = NULL; - const EC_POINT *srvr_ecpoint = NULL; - EVP_PKEY *srvr_pub_pkey = NULL; - unsigned char *encodedPoint = NULL; - int encoded_pt_len = 0; - BN_CTX *bn_ctx = NULL; -#endif - - if (s->state == SSL3_ST_CW_KEY_EXCH_A) { - p = ssl_handshake_start(s); - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - - /* Fool emacs indentation */ - if (0) { - } -#ifndef OPENSSL_NO_RSA - else if (alg_k & SSL_kRSA) { - RSA *rsa; - unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; - - if (s->session->sess_cert == NULL) { - /* - * We should always have a server certificate with SSL_kRSA. - */ - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - if (s->session->sess_cert->peer_rsa_tmp != NULL) - rsa = s->session->sess_cert->peer_rsa_tmp; - else { - pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC]. - x509); - if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) - || (pkey->pkey.rsa == NULL)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - EVP_PKEY_free(pkey); - goto err; - } - rsa = pkey->pkey.rsa; - EVP_PKEY_free(pkey); - } - - tmp_buf[0] = s->client_version >> 8; - tmp_buf[1] = s->client_version & 0xff; - if (RAND_bytes(&(tmp_buf[2]), sizeof(tmp_buf) - 2) <= 0) - goto err; - - s->session->master_key_length = sizeof(tmp_buf); - - q = p; - /* Fix buf for TLS and beyond */ - if (s->version > SSL3_VERSION) - p += 2; - n = RSA_public_encrypt(sizeof(tmp_buf), - tmp_buf, p, rsa, RSA_PKCS1_PADDING); -# ifdef PKCS1_CHECK - if (s->options & SSL_OP_PKCS1_CHECK_1) - p[1]++; - if (s->options & SSL_OP_PKCS1_CHECK_2) - tmp_buf[0] = 0x70; -# endif - if (n <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_RSA_ENCRYPT); - goto err; - } - - /* Fix buf for TLS and beyond */ - if (s->version > SSL3_VERSION) { - s2n(n, q); - n += 2; - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - tmp_buf, - sizeof(tmp_buf)); - OPENSSL_cleanse(tmp_buf, sizeof(tmp_buf)); - } -#endif -#ifndef OPENSSL_NO_KRB5 - else if (alg_k & SSL_kKRB5) { - krb5_error_code krb5rc; - KSSL_CTX *kssl_ctx = s->kssl_ctx; - /* krb5_data krb5_ap_req; */ - krb5_data *enc_ticket; - krb5_data authenticator, *authp = NULL; - EVP_CIPHER_CTX ciph_ctx; - const EVP_CIPHER *enc = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; - unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_IV_LENGTH]; - int padl, outl = sizeof(epms); - - EVP_CIPHER_CTX_init(&ciph_ctx); - -# ifdef KSSL_DEBUG - fprintf(stderr, "ssl3_send_client_key_exchange(%lx & %lx)\n", - alg_k, SSL_kKRB5); -# endif /* KSSL_DEBUG */ - - authp = NULL; -# ifdef KRB5SENDAUTH - if (KRB5SENDAUTH) - authp = &authenticator; -# endif /* KRB5SENDAUTH */ - - krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, &kssl_err); - enc = kssl_map_enc(kssl_ctx->enctype); - if (enc == NULL) - goto err; -# ifdef KSSL_DEBUG - { - fprintf(stderr, "kssl_cget_tkt rtn %d\n", krb5rc); - if (krb5rc && kssl_err.text) - fprintf(stderr, "kssl_cget_tkt kssl_err=%s\n", - kssl_err.text); - } -# endif /* KSSL_DEBUG */ - - if (krb5rc) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } - - /*- - * 20010406 VRS - Earlier versions used KRB5 AP_REQ - * in place of RFC 2712 KerberosWrapper, as in: - * - * Send ticket (copy to *p, set n = length) - * n = krb5_ap_req.length; - * memcpy(p, krb5_ap_req.data, krb5_ap_req.length); - * if (krb5_ap_req.data) - * kssl_krb5_free_data_contents(NULL,&krb5_ap_req); - * - * Now using real RFC 2712 KerberosWrapper - * (Thanks to Simon Wilkinson ) - * Note: 2712 "opaque" types are here replaced - * with a 2-byte length followed by the value. - * Example: - * KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms - * Where "xx xx" = length bytes. Shown here with - * optional authenticator omitted. - */ - - /* KerberosWrapper.Ticket */ - s2n(enc_ticket->length, p); - memcpy(p, enc_ticket->data, enc_ticket->length); - p += enc_ticket->length; - n = enc_ticket->length + 2; - - /* KerberosWrapper.Authenticator */ - if (authp && authp->length) { - s2n(authp->length, p); - memcpy(p, authp->data, authp->length); - p += authp->length; - n += authp->length + 2; - - free(authp->data); - authp->data = NULL; - authp->length = 0; - } else { - s2n(0, p); /* null authenticator length */ - n += 2; - } - - tmp_buf[0] = s->client_version >> 8; - tmp_buf[1] = s->client_version & 0xff; - if (RAND_bytes(&(tmp_buf[2]), sizeof(tmp_buf) - 2) <= 0) - goto err; - - /*- - * 20010420 VRS. Tried it this way; failed. - * EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL); - * EVP_CIPHER_CTX_set_key_length(&ciph_ctx, - * kssl_ctx->length); - * EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); - */ - - memset(iv, 0, sizeof(iv)); /* per RFC 1510 */ - EVP_EncryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv); - EVP_EncryptUpdate(&ciph_ctx, epms, &outl, tmp_buf, - sizeof(tmp_buf)); - EVP_EncryptFinal_ex(&ciph_ctx, &(epms[outl]), &padl); - outl += padl; - if (outl > (int)sizeof(epms)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - - /* KerberosWrapper.EncryptedPreMasterSecret */ - s2n(outl, p); - memcpy(p, epms, outl); - p += outl; - n += outl + 2; - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - tmp_buf, - sizeof(tmp_buf)); - - OPENSSL_cleanse(tmp_buf, sizeof(tmp_buf)); - OPENSSL_cleanse(epms, outl); - } -#endif -#ifndef OPENSSL_NO_DH - else if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { - DH *dh_srvr, *dh_clnt; - SESS_CERT *scert = s->session->sess_cert; - - if (scert == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_UNEXPECTED_MESSAGE); - goto err; - } - - if (scert->peer_dh_tmp != NULL) { - dh_srvr = scert->peer_dh_tmp; - } else { - dh_srvr = get_server_static_dh_key(scert); - if (dh_srvr == NULL) - goto err; - } - - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { - /* Use client certificate key */ - EVP_PKEY *clkey = s->cert->key->privatekey; - dh_clnt = NULL; - if (clkey) - dh_clnt = EVP_PKEY_get1_DH(clkey); - if (dh_clnt == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - } else { - /* generate a new random key */ - if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - if (!DH_generate_key(dh_clnt)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - DH_free(dh_clnt); - goto err; - } - } - - /* - * use the 'p' output buffer for the DH key, but make sure to - * clear it out afterwards - */ - - n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); - if (scert->peer_dh_tmp == NULL) - DH_free(dh_srvr); - - if (n <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - DH_free(dh_clnt); - goto err; - } - - /* generate master key from the result */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, n); - /* clean up */ - memset(p, 0, n); - - if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) - n = 0; - else { - /* send off the data */ - n = BN_num_bytes(dh_clnt->pub_key); - s2n(n, p); - BN_bn2bin(dh_clnt->pub_key, p); - n += 2; - } - - DH_free(dh_clnt); - } -#endif - -#ifndef OPENSSL_NO_ECDH - else if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { - const EC_GROUP *srvr_group = NULL; - EC_KEY *tkey; - int ecdh_clnt_cert = 0; - int field_size = 0; - - if (s->session->sess_cert == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_UNEXPECTED_MESSAGE); - goto err; - } - - /* - * Did we send out the client's ECDH share for use in premaster - * computation as part of client certificate? If so, set - * ecdh_clnt_cert to 1. - */ - if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->cert != NULL)) { - /*- - * XXX: For now, we do not support client - * authentication using ECDH certificates. - * To add such support, one needs to add - * code that checks for appropriate - * conditions and sets ecdh_clnt_cert to 1. - * For example, the cert have an ECC - * key on the same curve as the server's - * and the key should be authorized for - * key agreement. - * - * One also needs to add code in ssl3_connect - * to skip sending the certificate verify - * message. - * - * if ((s->cert->key->privatekey != NULL) && - * (s->cert->key->privatekey->type == - * EVP_PKEY_EC) && ...) - * ecdh_clnt_cert = 1; - */ - } - - if (s->session->sess_cert->peer_ecdh_tmp != NULL) { - tkey = s->session->sess_cert->peer_ecdh_tmp; - } else { - /* Get the Server Public Key from Cert */ - srvr_pub_pkey = - X509_get_pubkey(s->session-> - sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); - if ((srvr_pub_pkey == NULL) - || (srvr_pub_pkey->type != EVP_PKEY_EC) - || (srvr_pub_pkey->pkey.ec == NULL)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - tkey = srvr_pub_pkey->pkey.ec; - } - - srvr_group = EC_KEY_get0_group(tkey); - srvr_ecpoint = EC_KEY_get0_public_key(tkey); - - if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - if ((clnt_ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - if (ecdh_clnt_cert) { - /* - * Reuse key info from our certificate We only need our - * private key to perform the ECDH computation. - */ - const BIGNUM *priv_key; - tkey = s->cert->key->privatekey->pkey.ec; - priv_key = EC_KEY_get0_private_key(tkey); - if (priv_key == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - } else { - /* Generate a new ECDH key pair */ - if (!(EC_KEY_generate_key(clnt_ecdh))) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_ECDH_LIB); - goto err; - } - } - - /* - * use the 'p' output buffer for the ECDH key, but make sure to - * clear it out afterwards - */ - - field_size = EC_GROUP_get_degree(srvr_group); - if (field_size <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint, - clnt_ecdh, NULL); - if (n <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - /* generate master key from the result */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, n); - - memset(p, 0, n); /* clean up */ - - if (ecdh_clnt_cert) { - /* Send empty client key exch message */ - n = 0; - } else { - /* - * First check the size of encoding and allocate memory - * accordingly. - */ - encoded_pt_len = - EC_POINT_point2oct(srvr_group, - EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, - NULL, 0, NULL); - - encodedPoint = (unsigned char *) - OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char)); - bn_ctx = BN_CTX_new(); - if ((encodedPoint == NULL) || (bn_ctx == NULL)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Encode the public key */ - n = EC_POINT_point2oct(srvr_group, - EC_KEY_get0_public_key(clnt_ecdh), - POINT_CONVERSION_UNCOMPRESSED, - encodedPoint, encoded_pt_len, bn_ctx); - - *p = n; /* length of encoded point */ - /* Encoded point will be copied here */ - p += 1; - /* copy the point */ - memcpy((unsigned char *)p, encodedPoint, n); - /* increment n to account for length field */ - n += 1; - } - - /* Free allocated memory */ - BN_CTX_free(bn_ctx); - if (encodedPoint != NULL) - OPENSSL_free(encodedPoint); - if (clnt_ecdh != NULL) - EC_KEY_free(clnt_ecdh); - EVP_PKEY_free(srvr_pub_pkey); - } -#endif /* !OPENSSL_NO_ECDH */ - else if (alg_k & SSL_kGOST) { - /* GOST key exchange message creation */ - EVP_PKEY_CTX *pkey_ctx; - X509 *peer_cert; - size_t msglen; - unsigned int md_len; - int keytype; - unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; - EVP_MD_CTX *ukm_hash; - EVP_PKEY *pub_key; - - /* - * Get server sertificate PKEY and create ctx from it - */ - peer_cert = - s->session-> - sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST01)].x509; - if (!peer_cert) - peer_cert = - s->session-> - sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST94)].x509; - if (!peer_cert) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); - goto err; - } - - pkey_ctx = EVP_PKEY_CTX_new(pub_key = - X509_get_pubkey(peer_cert), NULL); - if (pkey_ctx == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - /* - * If we have send a certificate, and certificate key - * - * * parameters match those of server certificate, use - * certificate key for key exchange - */ - - /* Otherwise, generate ephemeral key pair */ - - if (pkey_ctx == NULL - || EVP_PKEY_encrypt_init(pkey_ctx) <= 0 - /* Generate session key */ - || RAND_bytes(premaster_secret, 32) <= 0) { - EVP_PKEY_CTX_free(pkey_ctx); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - /* - * Compute shared IV and store it in algorithm-specific context - * data - */ - ukm_hash = EVP_MD_CTX_create(); - if (EVP_DigestInit(ukm_hash, - EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0 - || EVP_DigestUpdate(ukm_hash, s->s3->client_random, - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(ukm_hash, s->s3->server_random, - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) { - EVP_MD_CTX_destroy(ukm_hash); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - EVP_MD_CTX_destroy(ukm_hash); - if (EVP_PKEY_CTX_ctrl - (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8, - shared_ukm) < 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_LIBRARY_BUG); - goto err; - } - /* Make GOST keytransport blob message */ - /* - * Encapsulate it into sequence - */ - *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; - msglen = 255; - if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32) - <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_LIBRARY_BUG); - goto err; - } - if (msglen >= 0x80) { - *(p++) = 0x81; - *(p++) = msglen & 0xff; - n = msglen + 3; - } else { - *(p++) = msglen & 0xff; - n = msglen + 2; - } - memcpy(p, tmp, msglen); - EVP_PKEY_CTX_free(pkey_ctx); - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - premaster_secret, - 32); - EVP_PKEY_free(pub_key); - - } -#ifndef OPENSSL_NO_SRP - else if (alg_k & SSL_kSRP) { - if (s->srp_ctx.A != NULL) { - /* send off the data */ - n = BN_num_bytes(s->srp_ctx.A); - s2n(n, p); - BN_bn2bin(s->srp_ctx.A, p); - n += 2; - } else { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - if (s->session->srp_username != NULL) - OPENSSL_free(s->session->srp_username); - s->session->srp_username = BUF_strdup(s->srp_ctx.login); - if (s->session->srp_username == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - if ((s->session->master_key_length = - SRP_generate_client_master_secret(s, - s->session->master_key)) < - 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - } -#endif -#ifndef OPENSSL_NO_PSK - else if (alg_k & SSL_kPSK) { - /* - * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a - * \0-terminated identity. The last byte is for us for simulating - * strnlen. - */ - char identity[PSK_MAX_IDENTITY_LEN + 2]; - size_t identity_len; - unsigned char *t = NULL; - unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; - unsigned int pre_ms_len = 0, psk_len = 0; - int psk_err = 1; - - n = 0; - if (s->psk_client_callback == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_NO_CLIENT_CB); - goto err; - } - - memset(identity, 0, sizeof(identity)); - psk_len = s->psk_client_callback(s, s->session->psk_identity_hint, - identity, sizeof(identity) - 1, - psk_or_pre_ms, - sizeof(psk_or_pre_ms)); - if (psk_len > PSK_MAX_PSK_LEN) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto psk_err; - } else if (psk_len == 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_IDENTITY_NOT_FOUND); - goto psk_err; - } - identity[PSK_MAX_IDENTITY_LEN + 1] = '\0'; - identity_len = strlen(identity); - if (identity_len > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto psk_err; - } - /* create PSK pre_master_secret */ - pre_ms_len = 2 + psk_len + 2 + psk_len; - t = psk_or_pre_ms; - memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); - s2n(psk_len, t); - memset(t, 0, psk_len); - t += psk_len; - s2n(psk_len, t); - - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - s->session->psk_identity_hint = - BUF_strdup(s->ctx->psk_identity_hint); - if (s->ctx->psk_identity_hint != NULL - && s->session->psk_identity_hint == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - if (s->session->psk_identity != NULL) - OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strdup(identity); - if (s->session->psk_identity == NULL) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - psk_or_pre_ms, - pre_ms_len); - s2n(identity_len, p); - memcpy(p, identity, identity_len); - n = 2 + identity_len; - psk_err = 0; - psk_err: - OPENSSL_cleanse(identity, sizeof(identity)); - OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); - if (psk_err != 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - goto err; - } - } -#endif - else { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n); - s->state = SSL3_ST_CW_KEY_EXCH_B; - } - - /* SSL3_ST_CW_KEY_EXCH_B */ - return ssl_do_write(s); - err: -#ifndef OPENSSL_NO_ECDH - BN_CTX_free(bn_ctx); - if (encodedPoint != NULL) - OPENSSL_free(encodedPoint); - if (clnt_ecdh != NULL) - EC_KEY_free(clnt_ecdh); - EVP_PKEY_free(srvr_pub_pkey); -#endif - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_send_client_verify(SSL *s) -{ - unsigned char *p; - unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; - EVP_PKEY *pkey; - EVP_PKEY_CTX *pctx = NULL; - EVP_MD_CTX mctx; - unsigned u = 0; - unsigned long n; - int j; - - EVP_MD_CTX_init(&mctx); - - if (s->state == SSL3_ST_CW_CERT_VRFY_A) { - p = ssl_handshake_start(s); - pkey = s->cert->key->privatekey; -/* Create context from key and test if sha1 is allowed as digest */ - pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (pctx == NULL || EVP_PKEY_sign_init(pctx) <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) { - if (!SSL_USE_SIGALGS(s)) - s->method->ssl3_enc->cert_verify_mac(s, - NID_sha1, - &(data - [MD5_DIGEST_LENGTH])); - } else { - ERR_clear_error(); - } - /* - * For TLS v1.2 send signature algorithm and signature using agreed - * digest and cached handshake records. - */ - if (SSL_USE_SIGALGS(s)) { - long hdatalen = 0; - void *hdata; - const EVP_MD *md = s->cert->key->digest; - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - p += 2; -#ifdef SSL_DEBUG - fprintf(stderr, "Using TLS 1.2 with client alg %s\n", - EVP_MD_name(md)); -#endif - if (!EVP_SignInit_ex(&mctx, md, NULL) - || !EVP_SignUpdate(&mctx, hdata, hdatalen) - || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_EVP_LIB); - goto err; - } - s2n(u, p); - n = u + 4; - if (!ssl3_digest_cached_records(s)) - goto err; - } else -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) { - s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0])); - if (RSA_sign(NID_md5_sha1, data, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, - &(p[2]), &u, pkey->pkey.rsa) <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB); - goto err; - } - s2n(u, p); - n = u + 2; - } else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) { - if (!DSA_sign(pkey->save_type, - &(data[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, &(p[2]), - (unsigned int *)&j, pkey->pkey.dsa)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB); - goto err; - } - s2n(j, p); - n = j + 2; - } else -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) { - if (!ECDSA_sign(pkey->save_type, - &(data[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, &(p[2]), - (unsigned int *)&j, pkey->pkey.ec)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB); - goto err; - } - s2n(j, p); - n = j + 2; - } else -#endif - if (pkey->type == NID_id_GostR3410_94 - || pkey->type == NID_id_GostR3410_2001) { - unsigned char signbuf[64]; - int i; - size_t sigsize = 64; - s->method->ssl3_enc->cert_verify_mac(s, - NID_id_GostR3411_94, data); - if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - for (i = 63, j = 0; i >= 0; j++, i--) { - p[2 + j] = signbuf[i]; - } - s2n(j, p); - n = j + 2; - } else { - SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); - goto err; - } - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n); - s->state = SSL3_ST_CW_CERT_VRFY_B; - } - EVP_MD_CTX_cleanup(&mctx); - EVP_PKEY_CTX_free(pctx); - return ssl_do_write(s); - err: - EVP_MD_CTX_cleanup(&mctx); - EVP_PKEY_CTX_free(pctx); - s->state = SSL_ST_ERR; - return (-1); -} - -/* - * Check a certificate can be used for client authentication. Currently check - * cert exists, if we have a suitable digest for TLS 1.2 if static DH client - * certificates can be used and optionally checks suitability for Suite B. - */ -static int ssl3_check_client_certificate(SSL *s) -{ - unsigned long alg_k; - if (!s->cert || !s->cert->key->x509 || !s->cert->key->privatekey) - return 0; - /* If no suitable signature algorithm can't use certificate */ - if (SSL_USE_SIGALGS(s) && !s->cert->key->digest) - return 0; - /* - * If strict mode check suitability of chain before using it. This also - * adjusts suite B digest if necessary. - */ - if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT && - !tls1_check_chain(s, NULL, NULL, NULL, -2)) - return 0; - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - /* See if we can use client certificate for fixed DH */ - if (alg_k & (SSL_kDHr | SSL_kDHd)) { - SESS_CERT *scert = s->session->sess_cert; - int i = scert->peer_cert_type; - EVP_PKEY *clkey = NULL, *spkey = NULL; - clkey = s->cert->key->privatekey; - /* If client key not DH assume it can be used */ - if (EVP_PKEY_id(clkey) != EVP_PKEY_DH) - return 1; - if (i >= 0) - spkey = X509_get_pubkey(scert->peer_pkeys[i].x509); - if (spkey) { - /* Compare server and client parameters */ - i = EVP_PKEY_cmp_parameters(clkey, spkey); - EVP_PKEY_free(spkey); - if (i != 1) - return 0; - } - s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; - } - return 1; -} - -int ssl3_send_client_certificate(SSL *s) -{ - X509 *x509 = NULL; - EVP_PKEY *pkey = NULL; - int i; - - if (s->state == SSL3_ST_CW_CERT_A) { - /* Let cert callback update client certificates if required */ - if (s->cert->cert_cb) { - i = s->cert->cert_cb(s, s->cert->cert_cb_arg); - if (i < 0) { - s->rwstate = SSL_X509_LOOKUP; - return -1; - } - if (i == 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return 0; - } - s->rwstate = SSL_NOTHING; - } - if (ssl3_check_client_certificate(s)) - s->state = SSL3_ST_CW_CERT_C; - else - s->state = SSL3_ST_CW_CERT_B; - } - - /* We need to get a client cert */ - if (s->state == SSL3_ST_CW_CERT_B) { - /* - * If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP; - * return(-1); We then get retied later - */ - i = ssl_do_client_cert_cb(s, &x509, &pkey); - if (i < 0) { - s->rwstate = SSL_X509_LOOKUP; - return (-1); - } - s->rwstate = SSL_NOTHING; - if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { - s->state = SSL3_ST_CW_CERT_B; - if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) - i = 0; - } else if (i == 1) { - i = 0; - SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, - SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); - } - - if (x509 != NULL) - X509_free(x509); - if (pkey != NULL) - EVP_PKEY_free(pkey); - if (i && !ssl3_check_client_certificate(s)) - i = 0; - if (i == 0) { - if (s->version == SSL3_VERSION) { - s->s3->tmp.cert_req = 0; - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); - return (1); - } else { - s->s3->tmp.cert_req = 2; - } - } - - /* Ok, we have a cert */ - s->state = SSL3_ST_CW_CERT_C; - } - - if (s->state == SSL3_ST_CW_CERT_C) { - s->state = SSL3_ST_CW_CERT_D; - if (!ssl3_output_cert_chain(s, - (s->s3->tmp.cert_req == - 2) ? NULL : s->cert->key)) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return 0; - } - } - /* SSL3_ST_CW_CERT_D */ - return ssl_do_write(s); -} - -#define has_bits(i,m) (((i)&(m)) == (m)) - -int ssl3_check_cert_and_algorithm(SSL *s) -{ - int i, idx; - long alg_k, alg_a; - EVP_PKEY *pkey = NULL; - int pkey_bits; - SESS_CERT *sc; -#ifndef OPENSSL_NO_RSA - RSA *rsa; -#endif -#ifndef OPENSSL_NO_DH - DH *dh; -#endif - int al = SSL_AD_HANDSHAKE_FAILURE; - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - - /* we don't have a certificate */ - if ((alg_a & (SSL_aNULL | SSL_aKRB5)) || (alg_k & SSL_kPSK)) - return (1); - - sc = s->session->sess_cert; - if (sc == NULL) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); - goto err; - } -#ifndef OPENSSL_NO_RSA - rsa = s->session->sess_cert->peer_rsa_tmp; -#endif -#ifndef OPENSSL_NO_DH - dh = s->session->sess_cert->peer_dh_tmp; -#endif - - /* This is the passed certificate */ - - idx = sc->peer_cert_type; -#ifndef OPENSSL_NO_ECDH - if (idx == SSL_PKEY_ECC) { - if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s) == 0) { - /* check failed */ - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_BAD_ECC_CERT); - goto f_err; - } else { - return 1; - } - } else if (alg_a & SSL_aECDSA) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_ECDSA_SIGNING_CERT); - goto f_err; - } else if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_MISSING_ECDH_CERT); - goto f_err; - } -#endif - pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509); - pkey_bits = EVP_PKEY_bits(pkey); - i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey); - EVP_PKEY_free(pkey); - - /* Check that we have a certificate if we require one */ - if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_RSA_SIGNING_CERT); - goto f_err; - } -#ifndef OPENSSL_NO_DSA - else if ((alg_a & SSL_aDSS) && !has_bits(i, EVP_PK_DSA | EVP_PKT_SIGN)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_DSA_SIGNING_CERT); - goto f_err; - } -#endif -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_RSA_ENCRYPTING_CERT); - goto f_err; - } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { - if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_RSA_ENCRYPTING_CERT); - goto f_err; - } - if (rsa != NULL) { - /* server key exchange is not allowed. */ - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); - goto f_err; - } - } - } - } -#endif -#ifndef OPENSSL_NO_DH - if ((alg_k & SSL_kEDH) && dh == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); - goto f_err; - } - if ((alg_k & SSL_kDHr) && !SSL_USE_SIGALGS(s) && - !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_DH_RSA_CERT); - goto f_err; - } -# ifndef OPENSSL_NO_DSA - if ((alg_k & SSL_kDHd) && !SSL_USE_SIGALGS(s) && - !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_DH_DSA_CERT); - goto f_err; - } -# endif - - if (alg_k & (SSL_kDHE | SSL_kDHr | SSL_kDHd)) { - int dh_size; - if (alg_k & SSL_kDHE) { - dh_size = BN_num_bits(dh->p); - } else { - DH *dh_srvr = get_server_static_dh_key(sc); - if (dh_srvr == NULL) - goto f_err; - dh_size = BN_num_bits(dh_srvr->p); - DH_free(dh_srvr); - } - - if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 1024) - || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); - goto f_err; - } - } -#endif /* !OPENSSL_NO_DH */ - - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - if (rsa == NULL) { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_RSA_KEY); - goto f_err; - } else if (BN_num_bits(rsa->n) > - SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - /* We have a temporary RSA key but it's too large. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_RSA_KEY); - goto f_err; - } - } else -#endif -#ifndef OPENSSL_NO_DH - if (alg_k & SSL_kDHE) { - if (BN_num_bits(dh->p) > - SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { - /* We have a temporary DH key but it's too large. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_DH_KEY); - goto f_err; - } - } else if (alg_k & (SSL_kDHr | SSL_kDHd)) { - /* The cert should have had an export DH key. */ - al = SSL_AD_EXPORT_RESTRICTION; - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_MISSING_EXPORT_TMP_DH_KEY); - goto f_err; - } else -#endif - { - SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, - SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); - goto f_err; - } - } - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (0); -} - -#ifndef OPENSSL_NO_TLSEXT -/* - * Normally, we can tell if the server is resuming the session from - * the session ID. EAP-FAST (RFC 4851), however, relies on the next server - * message after the ServerHello to determine if the server is resuming. - * Therefore, we allow EAP-FAST to peek ahead. - * ssl3_check_finished returns 1 if we are resuming from an external - * pre-shared secret, we have a "ticket" and the next server handshake message - * is Finished; and 0 otherwise. It returns -1 upon an error. - */ -static int ssl3_check_finished(SSL *s) -{ - int ok = 0; - - if (s->version < TLS1_VERSION || !s->tls_session_secret_cb || - !s->session->tlsext_tick) - return 0; - - /* Need to permit this temporarily, in case the next message is Finished. */ - s->s3->flags |= SSL3_FLAGS_CCS_OK; - /* - * This function is called when we might get a Certificate message instead, - * so permit appropriate message length. - * We ignore the return value as we're only interested in the message type - * and not its length. - */ - s->method->ssl_get_message(s, - SSL3_ST_CR_CERT_A, - SSL3_ST_CR_CERT_B, - -1, s->max_cert_list, &ok); - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; - - if (!ok) - return -1; - - s->s3->tmp.reuse_message = 1; - - if (s->s3->tmp.message_type == SSL3_MT_FINISHED) - return 1; - - /* If we're not done, then the CCS arrived early and we should bail. */ - if (s->s3->change_cipher_spec) { - SSLerr(SSL_F_SSL3_CHECK_FINISHED, SSL_R_CCS_RECEIVED_EARLY); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); - return -1; - } - - return 0; -} - -# ifndef OPENSSL_NO_NEXTPROTONEG -int ssl3_send_next_proto(SSL *s) -{ - unsigned int len, padding_len; - unsigned char *d; - - if (s->state == SSL3_ST_CW_NEXT_PROTO_A) { - len = s->next_proto_negotiated_len; - padding_len = 32 - ((len + 2) % 32); - d = (unsigned char *)s->init_buf->data; - d[4] = len; - memcpy(d + 5, s->next_proto_negotiated, len); - d[5 + len] = padding_len; - memset(d + 6 + len, 0, padding_len); - *(d++) = SSL3_MT_NEXT_PROTO; - l2n3(2 + len + padding_len, d); - s->state = SSL3_ST_CW_NEXT_PROTO_B; - s->init_num = 4 + 2 + len + padding_len; - s->init_off = 0; - } - - return ssl3_do_write(s, SSL3_RT_HANDSHAKE); -} -#endif /* !OPENSSL_NO_NEXTPROTONEG */ -#endif /* !OPENSSL_NO_TLSEXT */ - -int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) -{ - int i = 0; -#ifndef OPENSSL_NO_ENGINE - if (s->ctx->client_cert_engine) { - i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, - SSL_get_client_CA_list(s), - px509, ppkey, NULL, NULL, NULL); - if (i != 0) - return i; - } -#endif - if (s->ctx->client_cert_cb) - i = s->ctx->client_cert_cb(s, px509, ppkey); - return i; -} -/* ssl/s3_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -// #include "ssl_locl.h" -// #include "evp.h" -// #include "md5.h" - -static unsigned char ssl3_pad_1[48] = { - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, - 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 -}; - -static unsigned char ssl3_pad_2[48] = { - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, - 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c -}; - -static int ssl3_handshake_mac(SSL *s, int md_nid, - const char *sender, int len, unsigned char *p); -static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) -{ - EVP_MD_CTX m5; - EVP_MD_CTX s1; - unsigned char buf[16], smd[SHA_DIGEST_LENGTH]; - unsigned char c = 'A'; - unsigned int i, j, k; - -#ifdef CHARSET_EBCDIC - c = os_toascii[c]; /* 'A' in ASCII */ -#endif - k = 0; - EVP_MD_CTX_init(&m5); - EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - EVP_MD_CTX_init(&s1); - for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { - k++; - if (k > sizeof(buf)) - /* bug: 'buf' is too small for this ciphersuite */ - goto err; - - for (j = 0; j < k; j++) - buf[j] = c; - c++; - if (!EVP_DigestInit_ex(&s1, EVP_sha1(), NULL) || - !EVP_DigestUpdate(&s1, buf, k) || - !EVP_DigestUpdate(&s1, s->session->master_key, - s->session->master_key_length) || - !EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE) || - !EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE) || - !EVP_DigestFinal_ex(&s1, smd, NULL)) - goto err2; - - if (!EVP_DigestInit_ex(&m5, EVP_md5(), NULL) || - !EVP_DigestUpdate(&m5, s->session->master_key, - s->session->master_key_length) || - !EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH)) - goto err2; - if ((int)(i + MD5_DIGEST_LENGTH) > num) { - if (!EVP_DigestFinal_ex(&m5, smd, NULL)) - goto err2; - memcpy(km, smd, (num - i)); - } else - if (!EVP_DigestFinal_ex(&m5, km, NULL)) - goto err2; - - km += MD5_DIGEST_LENGTH; - } - OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH); - EVP_MD_CTX_cleanup(&m5); - EVP_MD_CTX_cleanup(&s1); - return 1; - err: - SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); - err2: - EVP_MD_CTX_cleanup(&m5); - EVP_MD_CTX_cleanup(&s1); - return 0; -} - -int ssl3_change_cipher_state(SSL *s, int which) -{ - unsigned char *p, *mac_secret; - unsigned char exp_key[EVP_MAX_KEY_LENGTH]; - unsigned char exp_iv[EVP_MAX_IV_LENGTH]; - unsigned char *ms, *key, *iv, *er1, *er2; - EVP_CIPHER_CTX *dd; - const EVP_CIPHER *c; -#ifndef OPENSSL_NO_COMP - COMP_METHOD *comp; -#endif - const EVP_MD *m; - EVP_MD_CTX md; - int is_exp, n, i, j, k, cl; - int reuse_dd = 0; - - is_exp = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); - c = s->s3->tmp.new_sym_enc; - m = s->s3->tmp.new_hash; - /* m == NULL will lead to a crash later */ - OPENSSL_assert(m); -#ifndef OPENSSL_NO_COMP - if (s->s3->tmp.new_compression == NULL) - comp = NULL; - else - comp = s->s3->tmp.new_compression->method; -#endif - - if (which & SSL3_CC_READ) { - if (s->enc_read_ctx != NULL) - reuse_dd = 1; - else if ((s->enc_read_ctx = - OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) - goto err; - else - /* - * make sure it's intialized in case we exit later with an error - */ - EVP_CIPHER_CTX_init(s->enc_read_ctx); - dd = s->enc_read_ctx; - - if (ssl_replace_hash(&s->read_hash, m) == NULL) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } -#ifndef OPENSSL_NO_COMP - /* COMPRESS */ - if (s->expand != NULL) { - COMP_CTX_free(s->expand); - s->expand = NULL; - } - if (comp != NULL) { - s->expand = COMP_CTX_new(comp); - if (s->expand == NULL) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err2; - } - if (s->s3->rrec.comp == NULL) - s->s3->rrec.comp = (unsigned char *) - OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); - if (s->s3->rrec.comp == NULL) - goto err; - } -#endif - memset(&(s->s3->read_sequence[0]), 0, 8); - mac_secret = &(s->s3->read_mac_secret[0]); - } else { - if (s->enc_write_ctx != NULL) - reuse_dd = 1; - else if ((s->enc_write_ctx = - OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) - goto err; - else - /* - * make sure it's intialized in case we exit later with an error - */ - EVP_CIPHER_CTX_init(s->enc_write_ctx); - dd = s->enc_write_ctx; - if (ssl_replace_hash(&s->write_hash, m) == NULL) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } -#ifndef OPENSSL_NO_COMP - /* COMPRESS */ - if (s->compress != NULL) { - COMP_CTX_free(s->compress); - s->compress = NULL; - } - if (comp != NULL) { - s->compress = COMP_CTX_new(comp); - if (s->compress == NULL) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err2; - } - } -#endif - memset(&(s->s3->write_sequence[0]), 0, 8); - mac_secret = &(s->s3->write_mac_secret[0]); - } - - if (reuse_dd) - EVP_CIPHER_CTX_cleanup(dd); - - p = s->s3->tmp.key_block; - i = EVP_MD_size(m); - if (i < 0) - goto err2; - cl = EVP_CIPHER_key_length(c); - j = is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? - cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; - /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */ - k = EVP_CIPHER_iv_length(c); - if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || - (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { - ms = &(p[0]); - n = i + i; - key = &(p[n]); - n += j + j; - iv = &(p[n]); - n += k + k; - er1 = &(s->s3->client_random[0]); - er2 = &(s->s3->server_random[0]); - } else { - n = i; - ms = &(p[n]); - n += i + j; - key = &(p[n]); - n += j + k; - iv = &(p[n]); - n += k; - er1 = &(s->s3->server_random[0]); - er2 = &(s->s3->client_random[0]); - } - - if (n > s->s3->tmp.key_block_length) { - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - - EVP_MD_CTX_init(&md); - memcpy(mac_secret, ms, i); - if (is_exp) { - /* - * In here I set both the read and write key/iv to the same value - * since only the correct one will be used :-). - */ - if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || - !EVP_DigestUpdate(&md, key, j) || - !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || - !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || - !EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL)) { - EVP_MD_CTX_cleanup(&md); - goto err2; - } - key = &(exp_key[0]); - - if (k > 0) { - if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || - !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || - !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || - !EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL)) { - EVP_MD_CTX_cleanup(&md); - goto err2; - } - iv = &(exp_iv[0]); - } - } - EVP_MD_CTX_cleanup(&md); - - s->session->key_arg_length = 0; - - if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) - goto err2; - -#ifdef OPENSSL_SSL_TRACE_CRYPTO - if (s->msg_callback) { - - int wh = which & SSL3_CC_WRITE ? - TLS1_RT_CRYPTO_WRITE : TLS1_RT_CRYPTO_READ; - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC, - mac_secret, EVP_MD_size(m), s, s->msg_callback_arg); - if (c->key_len) - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, - key, c->key_len, s, s->msg_callback_arg); - if (k) { - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_IV, - iv, k, s, s->msg_callback_arg); - } - } -#endif - - OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key)); - OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv)); - return (1); - err: - SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); - err2: - return (0); -} - -int ssl3_setup_key_block(SSL *s) -{ - unsigned char *p; - const EVP_CIPHER *c; - const EVP_MD *hash; - int num; - int ret = 0; - SSL_COMP *comp; - - if (s->s3->tmp.key_block_length != 0) - return (1); - - if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp)) { - SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); - return (0); - } - - s->s3->tmp.new_sym_enc = c; - s->s3->tmp.new_hash = hash; -#ifdef OPENSSL_NO_COMP - s->s3->tmp.new_compression = NULL; -#else - s->s3->tmp.new_compression = comp; -#endif - - num = EVP_MD_size(hash); - if (num < 0) - return 0; - - num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c); - num *= 2; - - ssl3_cleanup_key_block(s); - - if ((p = OPENSSL_malloc(num)) == NULL) - goto err; - - s->s3->tmp.key_block_length = num; - s->s3->tmp.key_block = p; - - ret = ssl3_generate_key_block(s, p, num); - - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { - /* - * enable vulnerability countermeasure for CBC ciphers with known-IV - * problem (http://www.openssl.org/~bodo/tls-cbc.txt) - */ - s->s3->need_empty_fragments = 1; - - if (s->session->cipher != NULL) { - if (s->session->cipher->algorithm_enc == SSL_eNULL) - s->s3->need_empty_fragments = 0; - -#ifndef OPENSSL_NO_RC4 - if (s->session->cipher->algorithm_enc == SSL_RC4) - s->s3->need_empty_fragments = 0; -#endif - } - } - - return ret; - - err: - SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - return (0); -} - -void ssl3_cleanup_key_block(SSL *s) -{ - if (s->s3->tmp.key_block != NULL) { - OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length); - OPENSSL_free(s->s3->tmp.key_block); - s->s3->tmp.key_block = NULL; - } - s->s3->tmp.key_block_length = 0; -} - -/*- - * ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. - * - * Returns: - * 0: (in non-constant time) if the record is publically invalid (i.e. too - * short etc). - * 1: if the record's padding is valid / the encryption was successful. - * -1: if the record's padding is invalid or, if sending, an internal error - * occured. - */ -int ssl3_enc(SSL *s, int send) -{ - SSL3_RECORD *rec; - EVP_CIPHER_CTX *ds; - unsigned long l; - int bs, i, mac_size = 0; - const EVP_CIPHER *enc; - - if (send) { - ds = s->enc_write_ctx; - rec = &(s->s3->wrec); - if (s->enc_write_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); - } else { - ds = s->enc_read_ctx; - rec = &(s->s3->rrec); - if (s->enc_read_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); - } - - if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { - memmove(rec->data, rec->input, rec->length); - rec->input = rec->data; - } else { - l = rec->length; - bs = EVP_CIPHER_block_size(ds->cipher); - - /* COMPRESS */ - - if ((bs != 1) && send) { - i = bs - ((int)l % bs); - - /* we need to add 'i-1' padding bytes */ - l += i; - /* - * the last of these zero bytes will be overwritten with the - * padding length. - */ - memset(&rec->input[rec->length], 0, i); - rec->length += i; - rec->input[l - 1] = (i - 1); - } - - if (!send) { - if (l == 0 || l % bs != 0) - return 0; - /* otherwise, rec->length >= bs */ - } - - if (EVP_Cipher(ds, rec->data, rec->input, l) < 1) - return -1; - - if (EVP_MD_CTX_md(s->read_hash) != NULL) - mac_size = EVP_MD_CTX_size(s->read_hash); - if ((bs != 1) && !send) - return ssl3_cbc_remove_padding(s, rec, bs, mac_size); - } - return 1; -} - -int ssl3_init_finished_mac(SSL *s) -{ - if (s->s3->handshake_buffer) - BIO_free(s->s3->handshake_buffer); - if (s->s3->handshake_dgst) - ssl3_free_digest_list(s); - s->s3->handshake_buffer = BIO_new(BIO_s_mem()); - if (s->s3->handshake_buffer == NULL) - return 0; - (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); - return 1; -} - -void ssl3_free_digest_list(SSL *s) -{ - int i; - if (!s->s3->handshake_dgst) - return; - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i]) - EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]); - } - OPENSSL_free(s->s3->handshake_dgst); - s->s3->handshake_dgst = NULL; -} - -void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) -{ - if (s->s3->handshake_buffer - && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { - BIO_write(s->s3->handshake_buffer, (void *)buf, len); - } else { - int i; - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i] != NULL) - EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len); - } - } -} - -int ssl3_digest_cached_records(SSL *s) -{ - int i; - long mask; - const EVP_MD *md; - long hdatalen; - void *hdata; - - /* Allocate handshake_dgst array */ - ssl3_free_digest_list(s); - s->s3->handshake_dgst = - OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); - if (s->s3->handshake_dgst == NULL) { - SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); - return 0; - } - memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (hdatalen <= 0) { - SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH); - return 0; - } - - /* Loop through bitso of algorithm2 field and create MD_CTX-es */ - for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { - if ((mask & ssl_get_algorithm2(s)) && md) { - s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); - if (s->s3->handshake_dgst[i] == NULL) { - SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); - return 0; - } -#ifdef OPENSSL_FIPS - if (EVP_MD_nid(md) == NID_md5) { - EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i], - EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - } -#endif - if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL) - || !EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, - hdatalen)) { - SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR); - return 0; - } - } else { - s->s3->handshake_dgst[i] = NULL; - } - } - if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { - /* Free handshake_buffer BIO */ - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; - } - - return 1; -} - -int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p) -{ - return (ssl3_handshake_mac(s, md_nid, NULL, 0, p)); -} - -int ssl3_final_finish_mac(SSL *s, - const char *sender, int len, unsigned char *p) -{ - int ret, sha1len; - ret = ssl3_handshake_mac(s, NID_md5, sender, len, p); - if (ret == 0) - return 0; - - p += ret; - - sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p); - if (sha1len == 0) - return 0; - - ret += sha1len; - return (ret); -} - -static int ssl3_handshake_mac(SSL *s, int md_nid, - const char *sender, int len, unsigned char *p) -{ - unsigned int ret; - int npad, n; - unsigned int i; - unsigned char md_buf[EVP_MAX_MD_SIZE]; - EVP_MD_CTX ctx, *d = NULL; - - if (s->s3->handshake_buffer) - if (!ssl3_digest_cached_records(s)) - return 0; - - /* - * Search for digest of specified type in the handshake_dgst array - */ - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i] - && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { - d = s->s3->handshake_dgst[i]; - break; - } - } - if (!d) { - SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST); - return 0; - } - EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - EVP_MD_CTX_copy_ex(&ctx, d); - n = EVP_MD_CTX_size(&ctx); - if (n < 0) - return 0; - - npad = (48 / n) * n; - if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0) - || EVP_DigestUpdate(&ctx, s->session->master_key, - s->session->master_key_length) <= 0 - || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0 - || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0 - - || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0 - || EVP_DigestUpdate(&ctx, s->session->master_key, - s->session->master_key_length) <= 0 - || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0 - || EVP_DigestUpdate(&ctx, md_buf, i) <= 0 - || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) { - SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR); - ret = 0; - } - - EVP_MD_CTX_cleanup(&ctx); - - return ((int)ret); -} - -int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) -{ - SSL3_RECORD *rec; - unsigned char *mac_sec, *seq; - EVP_MD_CTX md_ctx; - const EVP_MD_CTX *hash; - unsigned char *p, rec_char; - size_t md_size, orig_len; - int npad; - int t; - - if (send) { - rec = &(ssl->s3->wrec); - mac_sec = &(ssl->s3->write_mac_secret[0]); - seq = &(ssl->s3->write_sequence[0]); - hash = ssl->write_hash; - } else { - rec = &(ssl->s3->rrec); - mac_sec = &(ssl->s3->read_mac_secret[0]); - seq = &(ssl->s3->read_sequence[0]); - hash = ssl->read_hash; - } - - t = EVP_MD_CTX_size(hash); - if (t < 0) - return -1; - md_size = t; - npad = (48 / md_size) * md_size; - - /* - * kludge: ssl3_cbc_remove_padding passes padding length in rec->type - */ - orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); - rec->type &= 0xff; - - if (!send && - EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && - ssl3_cbc_record_digest_supported(hash)) { - /* - * This is a CBC-encrypted record. We must avoid leaking any - * timing-side channel information about how many blocks of data we - * are hashing because that gives an attacker a timing-oracle. - */ - - /*- - * npad is, at most, 48 bytes and that's with MD5: - * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. - * - * With SHA-1 (the largest hash speced for SSLv3) the hash size - * goes up 4, but npad goes down by 8, resulting in a smaller - * total size. - */ - unsigned char header[75]; - unsigned j = 0; - memcpy(header + j, mac_sec, md_size); - j += md_size; - memcpy(header + j, ssl3_pad_1, npad); - j += npad; - memcpy(header + j, seq, 8); - j += 8; - header[j++] = rec->type; - header[j++] = rec->length >> 8; - header[j++] = rec->length & 0xff; - - /* Final param == is SSLv3 */ - if (ssl3_cbc_digest_record(hash, - md, &md_size, - header, rec->input, - rec->length + md_size, orig_len, - mac_sec, md_size, 1) <= 0) - return -1; - } else { - unsigned int md_size_u; - /* Chop the digest off the end :-) */ - EVP_MD_CTX_init(&md_ctx); - - rec_char = rec->type; - p = md; - s2n(rec->length, p); - if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0 - || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0 - || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0 - || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0 - || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0 - || EVP_DigestUpdate(&md_ctx, md, 2) <= 0 - || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0 - || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0 - || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0 - || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0 - || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0 - || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0 - || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) { - EVP_MD_CTX_cleanup(&md_ctx); - return -1; - } - md_size = md_size_u; - - EVP_MD_CTX_cleanup(&md_ctx); - } - - ssl3_record_sequence_update(seq); - return (md_size); -} - -void ssl3_record_sequence_update(unsigned char *seq) -{ - int i; - - for (i = 7; i >= 0; i--) { - ++seq[i]; - if (seq[i] != 0) - break; - } -} - -int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, - int len) -{ - static const unsigned char *salt[3] = { -#ifndef CHARSET_EBCDIC - (const unsigned char *)"A", - (const unsigned char *)"BB", - (const unsigned char *)"CCC", -#else - (const unsigned char *)"\x41", - (const unsigned char *)"\x42\x42", - (const unsigned char *)"\x43\x43\x43", -#endif - }; - unsigned char buf[EVP_MAX_MD_SIZE]; - EVP_MD_CTX ctx; - int i, ret = 0; - unsigned int n; -#ifdef OPENSSL_SSL_TRACE_CRYPTO - unsigned char *tmpout = out; -#endif - - EVP_MD_CTX_init(&ctx); - for (i = 0; i < 3; i++) { - if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0 - || EVP_DigestUpdate(&ctx, salt[i], - strlen((const char *)salt[i])) <= 0 - || EVP_DigestUpdate(&ctx, p, len) <= 0 - || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0 - - || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0 - || EVP_DigestUpdate(&ctx, p, len) <= 0 - || EVP_DigestUpdate(&ctx, buf, n) <= 0 - || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) { - SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR); - ret = 0; - break; - } - out += n; - ret += n; - } - EVP_MD_CTX_cleanup(&ctx); - -#ifdef OPENSSL_SSL_TRACE_CRYPTO - if (ret > 0 && s->msg_callback) { - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER, - p, len, s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM, - s->s3->client_random, SSL3_RANDOM_SIZE, - s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM, - s->s3->server_random, SSL3_RANDOM_SIZE, - s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER, - tmpout, SSL3_MASTER_SECRET_SIZE, - s, s->msg_callback_arg); - } -#endif - OPENSSL_cleanse(buf, sizeof(buf)); - return (ret); -} - -int ssl3_alert_code(int code) -{ - switch (code) { - case SSL_AD_CLOSE_NOTIFY: - return (SSL3_AD_CLOSE_NOTIFY); - case SSL_AD_UNEXPECTED_MESSAGE: - return (SSL3_AD_UNEXPECTED_MESSAGE); - case SSL_AD_BAD_RECORD_MAC: - return (SSL3_AD_BAD_RECORD_MAC); - case SSL_AD_DECRYPTION_FAILED: - return (SSL3_AD_BAD_RECORD_MAC); - case SSL_AD_RECORD_OVERFLOW: - return (SSL3_AD_BAD_RECORD_MAC); - case SSL_AD_DECOMPRESSION_FAILURE: - return (SSL3_AD_DECOMPRESSION_FAILURE); - case SSL_AD_HANDSHAKE_FAILURE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_NO_CERTIFICATE: - return (SSL3_AD_NO_CERTIFICATE); - case SSL_AD_BAD_CERTIFICATE: - return (SSL3_AD_BAD_CERTIFICATE); - case SSL_AD_UNSUPPORTED_CERTIFICATE: - return (SSL3_AD_UNSUPPORTED_CERTIFICATE); - case SSL_AD_CERTIFICATE_REVOKED: - return (SSL3_AD_CERTIFICATE_REVOKED); - case SSL_AD_CERTIFICATE_EXPIRED: - return (SSL3_AD_CERTIFICATE_EXPIRED); - case SSL_AD_CERTIFICATE_UNKNOWN: - return (SSL3_AD_CERTIFICATE_UNKNOWN); - case SSL_AD_ILLEGAL_PARAMETER: - return (SSL3_AD_ILLEGAL_PARAMETER); - case SSL_AD_UNKNOWN_CA: - return (SSL3_AD_BAD_CERTIFICATE); - case SSL_AD_ACCESS_DENIED: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_DECODE_ERROR: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_DECRYPT_ERROR: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_EXPORT_RESTRICTION: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_PROTOCOL_VERSION: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_INSUFFICIENT_SECURITY: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_INTERNAL_ERROR: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_USER_CANCELLED: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_NO_RENEGOTIATION: - return (-1); /* Don't send it :-) */ - case SSL_AD_UNSUPPORTED_EXTENSION: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_CERTIFICATE_UNOBTAINABLE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_UNRECOGNIZED_NAME: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_UNKNOWN_PSK_IDENTITY: - return (TLS1_AD_UNKNOWN_PSK_IDENTITY); - case SSL_AD_INAPPROPRIATE_FALLBACK: - return (TLS1_AD_INAPPROPRIATE_FALLBACK); - default: - return (-1); - } -} -/* ssl/s3_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * ECC cipher suite support in OpenSSL originally written by - * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -// #include "objects.h" -// #include "ssl_locl.h" -// #include "kssl_lcl.h" -// #include "md5.h" -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -const char ssl3_version_str[] = "SSLv3" OPENSSL_VERSION_PTEXT; - -#define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER)) - -/* list of available SSLv3 ciphers (sorted by id) */ -OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { - -/* The RSA ciphers */ -/* Cipher 01 */ - { - 1, - SSL3_TXT_RSA_NULL_MD5, - SSL3_CK_RSA_NULL_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - -/* Cipher 02 */ - { - 1, - SSL3_TXT_RSA_NULL_SHA, - SSL3_CK_RSA_NULL_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - -/* Cipher 03 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_RSA_RC4_40_MD5, - SSL3_CK_RSA_RC4_40_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -#endif - -/* Cipher 04 */ - { - 1, - SSL3_TXT_RSA_RC4_128_MD5, - SSL3_CK_RSA_RC4_128_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 05 */ - { - 1, - SSL3_TXT_RSA_RC4_128_SHA, - SSL3_CK_RSA_RC4_128_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 06 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_RSA_RC2_40_MD5, - SSL3_CK_RSA_RC2_40_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC2, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -#endif - -/* Cipher 07 */ -#ifndef OPENSSL_NO_IDEA - { - 1, - SSL3_TXT_RSA_IDEA_128_SHA, - SSL3_CK_RSA_IDEA_128_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_IDEA, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -#endif - -/* Cipher 08 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_RSA_DES_40_CBC_SHA, - SSL3_CK_RSA_DES_40_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 09 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_RSA_DES_64_CBC_SHA, - SSL3_CK_RSA_DES_64_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 0A */ - { - 1, - SSL3_TXT_RSA_DES_192_CBC3_SHA, - SSL3_CK_RSA_DES_192_CBC3_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* The DH ciphers */ -/* Cipher 0B */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 0, - SSL3_TXT_DH_DSS_DES_40_CBC_SHA, - SSL3_CK_DH_DSS_DES_40_CBC_SHA, - SSL_kDHd, - SSL_aDH, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 0C */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_DH_DSS_DES_64_CBC_SHA, - SSL3_CK_DH_DSS_DES_64_CBC_SHA, - SSL_kDHd, - SSL_aDH, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 0D */ - { - 1, - SSL3_TXT_DH_DSS_DES_192_CBC3_SHA, - SSL3_CK_DH_DSS_DES_192_CBC3_SHA, - SSL_kDHd, - SSL_aDH, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 0E */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 0, - SSL3_TXT_DH_RSA_DES_40_CBC_SHA, - SSL3_CK_DH_RSA_DES_40_CBC_SHA, - SSL_kDHr, - SSL_aDH, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 0F */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_DH_RSA_DES_64_CBC_SHA, - SSL3_CK_DH_RSA_DES_64_CBC_SHA, - SSL_kDHr, - SSL_aDH, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 10 */ - { - 1, - SSL3_TXT_DH_RSA_DES_192_CBC3_SHA, - SSL3_CK_DH_RSA_DES_192_CBC3_SHA, - SSL_kDHr, - SSL_aDH, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* The Ephemeral DH ciphers */ -/* Cipher 11 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_EDH_DSS_DES_40_CBC_SHA, - SSL3_CK_EDH_DSS_DES_40_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 12 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_EDH_DSS_DES_64_CBC_SHA, - SSL3_CK_EDH_DSS_DES_64_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 13 */ - { - 1, - SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, - SSL3_CK_EDH_DSS_DES_192_CBC3_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 14 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_EDH_RSA_DES_40_CBC_SHA, - SSL3_CK_EDH_RSA_DES_40_CBC_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -#endif - -/* Cipher 15 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_EDH_RSA_DES_64_CBC_SHA, - SSL3_CK_EDH_RSA_DES_64_CBC_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 16 */ - { - 1, - SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, - SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 17 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_ADH_RC4_40_MD5, - SSL3_CK_ADH_RC4_40_MD5, - SSL_kEDH, - SSL_aNULL, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -#endif - -/* Cipher 18 */ - { - 1, - SSL3_TXT_ADH_RC4_128_MD5, - SSL3_CK_ADH_RC4_128_MD5, - SSL_kEDH, - SSL_aNULL, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 19 */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_ADH_DES_40_CBC_SHA, - SSL3_CK_ADH_DES_40_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -#endif - -/* Cipher 1A */ -#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_ADH_DES_64_CBC_SHA, - SSL3_CK_ADH_DES_64_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -#endif - -/* Cipher 1B */ - { - 1, - SSL3_TXT_ADH_DES_192_CBC_SHA, - SSL3_CK_ADH_DES_192_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Fortezza ciphersuite from SSL 3.0 spec */ -#if 0 -/* Cipher 1C */ - { - 0, - SSL3_TXT_FZA_DMS_NULL_SHA, - SSL3_CK_FZA_DMS_NULL_SHA, - SSL_kFZA, - SSL_aFZA, - SSL_eNULL, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - -/* Cipher 1D */ - { - 0, - SSL3_TXT_FZA_DMS_FZA_SHA, - SSL3_CK_FZA_DMS_FZA_SHA, - SSL_kFZA, - SSL_aFZA, - SSL_eFZA, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - -/* Cipher 1E */ - { - 0, - SSL3_TXT_FZA_DMS_RC4_SHA, - SSL3_CK_FZA_DMS_RC4_SHA, - SSL_kFZA, - SSL_aFZA, - SSL_RC4, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -#endif - -#ifndef OPENSSL_NO_KRB5 -/* The Kerberos ciphers*/ -/* Cipher 1E */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_DES_64_CBC_SHA, - SSL3_CK_KRB5_DES_64_CBC_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -# endif - -/* Cipher 1F */ - { - 1, - SSL3_TXT_KRB5_DES_192_CBC3_SHA, - SSL3_CK_KRB5_DES_192_CBC3_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_3DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 20 */ - { - 1, - SSL3_TXT_KRB5_RC4_128_SHA, - SSL3_CK_KRB5_RC4_128_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC4, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 21 */ - { - 1, - SSL3_TXT_KRB5_IDEA_128_CBC_SHA, - SSL3_CK_KRB5_IDEA_128_CBC_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_IDEA, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 22 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_DES_64_CBC_MD5, - SSL3_CK_KRB5_DES_64_CBC_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_DES, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -# endif - -/* Cipher 23 */ - { - 1, - SSL3_TXT_KRB5_DES_192_CBC3_MD5, - SSL3_CK_KRB5_DES_192_CBC3_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_3DES, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - -/* Cipher 24 */ - { - 1, - SSL3_TXT_KRB5_RC4_128_MD5, - SSL3_CK_KRB5_RC4_128_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 25 */ - { - 1, - SSL3_TXT_KRB5_IDEA_128_CBC_MD5, - SSL3_CK_KRB5_IDEA_128_CBC_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_IDEA, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 26 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_DES_40_CBC_SHA, - SSL3_CK_KRB5_DES_40_CBC_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_DES, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -# endif - -/* Cipher 27 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_RC2_40_CBC_SHA, - SSL3_CK_KRB5_RC2_40_CBC_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC2, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -# endif - -/* Cipher 28 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_RC4_40_SHA, - SSL3_CK_KRB5_RC4_40_SHA, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC4, - SSL_SHA1, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -# endif - -/* Cipher 29 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_DES_40_CBC_MD5, - SSL3_CK_KRB5_DES_40_CBC_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_DES, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 56, - }, -# endif - -/* Cipher 2A */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_RC2_40_CBC_MD5, - SSL3_CK_KRB5_RC2_40_CBC_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC2, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -# endif - -/* Cipher 2B */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - SSL3_TXT_KRB5_RC4_40_MD5, - SSL3_CK_KRB5_RC4_40_MD5, - SSL_kKRB5, - SSL_aKRB5, - SSL_RC4, - SSL_MD5, - SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 40, - 128, - }, -# endif -#endif /* OPENSSL_NO_KRB5 */ - -/* New AES ciphersuites */ -/* Cipher 2F */ - { - 1, - TLS1_TXT_RSA_WITH_AES_128_SHA, - TLS1_CK_RSA_WITH_AES_128_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 30 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_128_SHA, - TLS1_CK_DH_DSS_WITH_AES_128_SHA, - SSL_kDHd, - SSL_aDH, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 31 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_128_SHA, - TLS1_CK_DH_RSA_WITH_AES_128_SHA, - SSL_kDHr, - SSL_aDH, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 32 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_128_SHA, - TLS1_CK_DHE_DSS_WITH_AES_128_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 33 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, - TLS1_CK_DHE_RSA_WITH_AES_128_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -/* Cipher 34 */ - { - 1, - TLS1_TXT_ADH_WITH_AES_128_SHA, - TLS1_CK_ADH_WITH_AES_128_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -/* Cipher 35 */ - { - 1, - TLS1_TXT_RSA_WITH_AES_256_SHA, - TLS1_CK_RSA_WITH_AES_256_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -/* Cipher 36 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_256_SHA, - TLS1_CK_DH_DSS_WITH_AES_256_SHA, - SSL_kDHd, - SSL_aDH, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - -/* Cipher 37 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_256_SHA, - TLS1_CK_DH_RSA_WITH_AES_256_SHA, - SSL_kDHr, - SSL_aDH, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - -/* Cipher 38 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_256_SHA, - TLS1_CK_DHE_DSS_WITH_AES_256_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - -/* Cipher 39 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, - TLS1_CK_DHE_RSA_WITH_AES_256_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 3A */ - { - 1, - TLS1_TXT_ADH_WITH_AES_256_SHA, - TLS1_CK_ADH_WITH_AES_256_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* TLS v1.2 ciphersuites */ - /* Cipher 3B */ - { - 1, - TLS1_TXT_RSA_WITH_NULL_SHA256, - TLS1_CK_RSA_WITH_NULL_SHA256, - SSL_kRSA, - SSL_aRSA, - SSL_eNULL, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher 3C */ - { - 1, - TLS1_TXT_RSA_WITH_AES_128_SHA256, - TLS1_CK_RSA_WITH_AES_128_SHA256, - SSL_kRSA, - SSL_aRSA, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 3D */ - { - 1, - TLS1_TXT_RSA_WITH_AES_256_SHA256, - TLS1_CK_RSA_WITH_AES_256_SHA256, - SSL_kRSA, - SSL_aRSA, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 3E */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_128_SHA256, - TLS1_CK_DH_DSS_WITH_AES_128_SHA256, - SSL_kDHd, - SSL_aDH, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 3F */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_128_SHA256, - TLS1_CK_DH_RSA_WITH_AES_128_SHA256, - SSL_kDHr, - SSL_aDH, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 40 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256, - TLS1_CK_DHE_DSS_WITH_AES_128_SHA256, - SSL_kEDH, - SSL_aDSS, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -#ifndef OPENSSL_NO_CAMELLIA - /* Camellia ciphersuites from RFC4132 (128-bit portion) */ - - /* Cipher 41 */ - { - 1, - TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 42 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, - SSL_kDHd, - SSL_aDH, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 43 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kDHr, - SSL_aDH, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 44 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 45 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 46 */ - { - 1, - TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA, - TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_CAMELLIA128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -#endif /* OPENSSL_NO_CAMELLIA */ - -#if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES - /* New TLS Export CipherSuites from expired ID */ -# if 0 - /* Cipher 60 */ - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5, - TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_MD5, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 128, - }, - - /* Cipher 61 */ - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, - TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, - SSL_kRSA, - SSL_aRSA, - SSL_RC2, - SSL_MD5, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 128, - }, -# endif - - /* Cipher 62 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA, - TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -# endif - - /* Cipher 63 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, - TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 56, - }, -# endif - - /* Cipher 64 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA, - TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 128, - }, -# endif - - /* Cipher 65 */ -# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS - { - 1, - TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, - TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 56, - 128, - }, -# endif - - /* Cipher 66 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA, - TLS1_CK_DHE_DSS_WITH_RC4_128_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, -#endif - - /* TLS v1.2 ciphersuites */ - /* Cipher 67 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, - SSL_kEDH, - SSL_aRSA, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 68 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_256_SHA256, - TLS1_CK_DH_DSS_WITH_AES_256_SHA256, - SSL_kDHd, - SSL_aDH, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 69 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_256_SHA256, - TLS1_CK_DH_RSA_WITH_AES_256_SHA256, - SSL_kDHr, - SSL_aDH, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 6A */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256, - TLS1_CK_DHE_DSS_WITH_AES_256_SHA256, - SSL_kEDH, - SSL_aDSS, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 6B */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, - SSL_kEDH, - SSL_aRSA, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 6C */ - { - 1, - TLS1_TXT_ADH_WITH_AES_128_SHA256, - TLS1_CK_ADH_WITH_AES_128_SHA256, - SSL_kEDH, - SSL_aNULL, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 6D */ - { - 1, - TLS1_TXT_ADH_WITH_AES_256_SHA256, - TLS1_CK_ADH_WITH_AES_256_SHA256, - SSL_kEDH, - SSL_aNULL, - SSL_AES256, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* GOST Ciphersuites */ - - { - 1, - "GOST94-GOST89-GOST89", - 0x3000080, - SSL_kGOST, - SSL_aGOST94, - SSL_eGOST2814789CNT, - SSL_GOST89MAC, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC, - 256, - 256}, - { - 1, - "GOST2001-GOST89-GOST89", - 0x3000081, - SSL_kGOST, - SSL_aGOST01, - SSL_eGOST2814789CNT, - SSL_GOST89MAC, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC, - 256, - 256}, - { - 1, - "GOST94-NULL-GOST94", - 0x3000082, - SSL_kGOST, - SSL_aGOST94, - SSL_eNULL, - SSL_GOST94, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94, - 0, - 0}, - { - 1, - "GOST2001-NULL-GOST94", - 0x3000083, - SSL_kGOST, - SSL_aGOST01, - SSL_eNULL, - SSL_GOST94, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE, - SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94, - 0, - 0}, - -#ifndef OPENSSL_NO_CAMELLIA - /* Camellia ciphersuites from RFC4132 (256-bit portion) */ - - /* Cipher 84 */ - { - 1, - TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - /* Cipher 85 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, - SSL_kDHd, - SSL_aDH, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 86 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kDHr, - SSL_aDH, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 87 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 88 */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher 89 */ - { - 1, - TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA, - TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_CAMELLIA256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -#endif /* OPENSSL_NO_CAMELLIA */ - -#ifndef OPENSSL_NO_PSK - /* Cipher 8A */ - { - 1, - TLS1_TXT_PSK_WITH_RC4_128_SHA, - TLS1_CK_PSK_WITH_RC4_128_SHA, - SSL_kPSK, - SSL_aPSK, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 8B */ - { - 1, - TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA, - TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA, - SSL_kPSK, - SSL_aPSK, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher 8C */ - { - 1, - TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, - TLS1_CK_PSK_WITH_AES_128_CBC_SHA, - SSL_kPSK, - SSL_aPSK, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 8D */ - { - 1, - TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, - TLS1_CK_PSK_WITH_AES_256_CBC_SHA, - SSL_kPSK, - SSL_aPSK, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -#endif /* OPENSSL_NO_PSK */ - -#ifndef OPENSSL_NO_SEED - /* SEED ciphersuites from RFC4162 */ - - /* Cipher 96 */ - { - 1, - TLS1_TXT_RSA_WITH_SEED_SHA, - TLS1_CK_RSA_WITH_SEED_SHA, - SSL_kRSA, - SSL_aRSA, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 97 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_SEED_SHA, - TLS1_CK_DH_DSS_WITH_SEED_SHA, - SSL_kDHd, - SSL_aDH, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 98 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_SEED_SHA, - TLS1_CK_DH_RSA_WITH_SEED_SHA, - SSL_kDHr, - SSL_aDH, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 99 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_SEED_SHA, - TLS1_CK_DHE_DSS_WITH_SEED_SHA, - SSL_kEDH, - SSL_aDSS, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 9A */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_SEED_SHA, - TLS1_CK_DHE_RSA_WITH_SEED_SHA, - SSL_kEDH, - SSL_aRSA, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher 9B */ - { - 1, - TLS1_TXT_ADH_WITH_SEED_SHA, - TLS1_CK_ADH_WITH_SEED_SHA, - SSL_kEDH, - SSL_aNULL, - SSL_SEED, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - -#endif /* OPENSSL_NO_SEED */ - - /* GCM ciphersuites from RFC5288 */ - - /* Cipher 9C */ - { - 1, - TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, - SSL_kRSA, - SSL_aRSA, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher 9D */ - { - 1, - TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, - SSL_kRSA, - SSL_aRSA, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher 9E */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, - SSL_kEDH, - SSL_aRSA, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher 9F */ - { - 1, - TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, - SSL_kEDH, - SSL_aRSA, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher A0 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256, - SSL_kDHr, - SSL_aDH, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher A1 */ - { - 1, - TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384, - SSL_kDHr, - SSL_aDH, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher A2 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256, - TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256, - SSL_kEDH, - SSL_aDSS, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher A3 */ - { - 1, - TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384, - TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384, - SSL_kEDH, - SSL_aDSS, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher A4 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256, - TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256, - SSL_kDHd, - SSL_aDH, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher A5 */ - { - 1, - TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384, - TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384, - SSL_kDHd, - SSL_aDH, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher A6 */ - { - 1, - TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256, - TLS1_CK_ADH_WITH_AES_128_GCM_SHA256, - SSL_kEDH, - SSL_aNULL, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher A7 */ - { - 1, - TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384, - TLS1_CK_ADH_WITH_AES_256_GCM_SHA384, - SSL_kEDH, - SSL_aNULL, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - { - 1, - "SCSV", - SSL3_CK_SCSV, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0}, -#endif - -#ifndef OPENSSL_NO_ECDH - /* Cipher C001 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA, - TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C002 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA, - TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C003 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C004 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C005 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - SSL_kECDHe, - SSL_aECDH, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C006 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C007 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C008 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C009 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C00A */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C00B */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_NULL_SHA, - TLS1_CK_ECDH_RSA_WITH_NULL_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C00C */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA, - TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C00D */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C00E */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C00F */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA, - SSL_kECDHr, - SSL_aECDH, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C010 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, - TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C011 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, - TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C012 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C013 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C014 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, - SSL_kEECDH, - SSL_aRSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C015 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_NULL_SHA, - TLS1_CK_ECDH_anon_WITH_NULL_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_eNULL, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 0, - 0, - }, - - /* Cipher C016 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA, - TLS1_CK_ECDH_anon_WITH_RC4_128_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_RC4, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C017 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA, - TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C018 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA, - TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C019 */ - { - 1, - TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA, - TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA, - SSL_kEECDH, - SSL_aNULL, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -#endif /* OPENSSL_NO_ECDH */ - -#ifndef OPENSSL_NO_SRP - /* Cipher C01A */ - { - 1, - TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA, - TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA, - SSL_kSRP, - SSL_aSRP, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C01B */ - { - 1, - TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, - TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, - SSL_kSRP, - SSL_aRSA, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C01C */ - { - 1, - TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, - TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, - SSL_kSRP, - SSL_aDSS, - SSL_3DES, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_MEDIUM, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 112, - 168, - }, - - /* Cipher C01D */ - { - 1, - TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA, - TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA, - SSL_kSRP, - SSL_aSRP, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C01E */ - { - 1, - TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, - TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, - SSL_kSRP, - SSL_aRSA, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C01F */ - { - 1, - TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, - TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, - SSL_kSRP, - SSL_aDSS, - SSL_AES128, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 128, - 128, - }, - - /* Cipher C020 */ - { - 1, - TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA, - TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA, - SSL_kSRP, - SSL_aSRP, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C021 */ - { - 1, - TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, - TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, - SSL_kSRP, - SSL_aRSA, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - - /* Cipher C022 */ - { - 1, - TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, - TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, - SSL_kSRP, - SSL_aDSS, - SSL_AES256, - SSL_SHA1, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, -#endif /* OPENSSL_NO_SRP */ -#ifndef OPENSSL_NO_ECDH - - /* HMAC based TLS v1.2 ciphersuites from RFC5289 */ - - /* Cipher C023 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C024 */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES256, - SSL_SHA384, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C025 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256, - TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256, - SSL_kECDHe, - SSL_aECDH, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C026 */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384, - TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384, - SSL_kECDHe, - SSL_aECDH, - SSL_AES256, - SSL_SHA384, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C027 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, - TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, - SSL_kEECDH, - SSL_aRSA, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C028 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, - TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, - SSL_kEECDH, - SSL_aRSA, - SSL_AES256, - SSL_SHA384, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C029 */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256, - TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256, - SSL_kECDHr, - SSL_aECDH, - SSL_AES128, - SSL_SHA256, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C02A */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384, - TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384, - SSL_kECDHr, - SSL_aECDH, - SSL_AES256, - SSL_SHA384, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* GCM based TLS v1.2 ciphersuites from RFC5289 */ - - /* Cipher C02B */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C02C */ - { - 1, - TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - SSL_kEECDH, - SSL_aECDSA, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C02D */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - SSL_kECDHe, - SSL_aECDH, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C02E */ - { - 1, - TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - SSL_kECDHe, - SSL_aECDH, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C02F */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - SSL_kEECDH, - SSL_aRSA, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C030 */ - { - 1, - TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - SSL_kEECDH, - SSL_aRSA, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - - /* Cipher C031 */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256, - TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256, - SSL_kECDHr, - SSL_aECDH, - SSL_AES128GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, - 128, - 128, - }, - - /* Cipher C032 */ - { - 1, - TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384, - TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384, - SSL_kECDHr, - SSL_aECDH, - SSL_AES256GCM, - SSL_AEAD, - SSL_TLSV1_2, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, - SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, - 256, - 256, - }, - -#endif /* OPENSSL_NO_ECDH */ - -#ifdef TEMP_GOST_TLS -/* Cipher FF00 */ - { - 1, - "GOST-MD5", - 0x0300ff00, - SSL_kRSA, - SSL_aRSA, - SSL_eGOST2814789CNT, - SSL_MD5, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256, - }, - { - 1, - "GOST-GOST94", - 0x0300ff01, - SSL_kRSA, - SSL_aRSA, - SSL_eGOST2814789CNT, - SSL_GOST94, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256}, - { - 1, - "GOST-GOST89MAC", - 0x0300ff02, - SSL_kRSA, - SSL_aRSA, - SSL_eGOST2814789CNT, - SSL_GOST89MAC, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, - 256, - 256}, - { - 1, - "GOST-GOST89STREAM", - 0x0300ff03, - SSL_kRSA, - SSL_aRSA, - SSL_eGOST2814789CNT, - SSL_GOST89MAC, - SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, - SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF | TLS1_STREAM_MAC, - 256, - 256}, -#endif - -/* end of list */ -}; - -SSL3_ENC_METHOD SSLv3_enc_data = { - ssl3_enc, - n_ssl3_mac, - ssl3_setup_key_block, - ssl3_generate_master_secret, - ssl3_change_cipher_state, - ssl3_final_finish_mac, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, - ssl3_cert_verify_mac, - SSL3_MD_CLIENT_FINISHED_CONST, 4, - SSL3_MD_SERVER_FINISHED_CONST, 4, - ssl3_alert_code, - (int (*)(SSL *, unsigned char *, size_t, const char *, - size_t, const unsigned char *, size_t, - int use_context))ssl_undefined_function, - 0, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write -}; - -long ssl3_default_timeout(void) -{ - /* - * 2 hours, the 24 hours mentioned in the SSLv3 spec is way too long for - * http, the cache would over fill - */ - return (60 * 60 * 2); -} - -int ssl3_num_ciphers(void) -{ - return (SSL3_NUM_CIPHERS); -} - -const SSL_CIPHER *ssl3_get_cipher(unsigned int u) -{ - if (u < SSL3_NUM_CIPHERS) - return (&(ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - u])); - else - return (NULL); -} - -int ssl3_pending(const SSL *s) -{ - if (s->rstate == SSL_ST_READ_BODY) - return 0; - - return (s->s3->rrec.type == - SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0; -} - -void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len) -{ - unsigned char *p = (unsigned char *)s->init_buf->data; - *(p++) = htype; - l2n3(len, p); - s->init_num = (int)len + SSL3_HM_HEADER_LENGTH; - s->init_off = 0; -} - -int ssl3_handshake_write(SSL *s) -{ - return ssl3_do_write(s, SSL3_RT_HANDSHAKE); -} - -int ssl3_new(SSL *s) -{ - SSL3_STATE *s3; - - if ((s3 = OPENSSL_malloc(sizeof(*s3))) == NULL) - goto err; - memset(s3, 0, sizeof(*s3)); - memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num)); - memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num)); - - s->s3 = s3; - -#ifndef OPENSSL_NO_SRP - SSL_SRP_CTX_init(s); -#endif - s->method->ssl_clear(s); - return (1); - err: - return (0); -} - -void ssl3_free(SSL *s) -{ - if (s == NULL || s->s3 == NULL) - return; - -#ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL) - OPENSSL_free(s->s3->client_opaque_prf_input); - if (s->s3->server_opaque_prf_input != NULL) - OPENSSL_free(s->s3->server_opaque_prf_input); -#endif - - ssl3_cleanup_key_block(s); - if (s->s3->rbuf.buf != NULL) - ssl3_release_read_buffer(s); - if (s->s3->wbuf.buf != NULL) - ssl3_release_write_buffer(s); - if (s->s3->rrec.comp != NULL) - OPENSSL_free(s->s3->rrec.comp); -#ifndef OPENSSL_NO_DH - if (s->s3->tmp.dh != NULL) - DH_free(s->s3->tmp.dh); -#endif -#ifndef OPENSSL_NO_ECDH - if (s->s3->tmp.ecdh != NULL) - EC_KEY_free(s->s3->tmp.ecdh); -#endif - - if (s->s3->tmp.ca_names != NULL) - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - if (s->s3->handshake_buffer) { - BIO_free(s->s3->handshake_buffer); - } - if (s->s3->handshake_dgst) - ssl3_free_digest_list(s); -#ifndef OPENSSL_NO_TLSEXT - if (s->s3->alpn_selected) - OPENSSL_free(s->s3->alpn_selected); -#endif - -#ifndef OPENSSL_NO_SRP - SSL_SRP_CTX_free(s); -#endif - OPENSSL_cleanse(s->s3, sizeof(*s->s3)); - OPENSSL_free(s->s3); - s->s3 = NULL; -} - -void ssl3_clear(SSL *s) -{ - unsigned char *rp, *wp; - size_t rlen, wlen; - int init_extra; - -#ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL) - OPENSSL_free(s->s3->client_opaque_prf_input); - s->s3->client_opaque_prf_input = NULL; - if (s->s3->server_opaque_prf_input != NULL) - OPENSSL_free(s->s3->server_opaque_prf_input); - s->s3->server_opaque_prf_input = NULL; -#endif - - ssl3_cleanup_key_block(s); - if (s->s3->tmp.ca_names != NULL) - sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); - - if (s->s3->rrec.comp != NULL) { - OPENSSL_free(s->s3->rrec.comp); - s->s3->rrec.comp = NULL; - } -#ifndef OPENSSL_NO_DH - if (s->s3->tmp.dh != NULL) { - DH_free(s->s3->tmp.dh); - s->s3->tmp.dh = NULL; - } -#endif -#ifndef OPENSSL_NO_ECDH - if (s->s3->tmp.ecdh != NULL) { - EC_KEY_free(s->s3->tmp.ecdh); - s->s3->tmp.ecdh = NULL; - } -#endif -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC - s->s3->is_probably_safari = 0; -# endif /* !OPENSSL_NO_EC */ -#endif /* !OPENSSL_NO_TLSEXT */ - - rp = s->s3->rbuf.buf; - wp = s->s3->wbuf.buf; - rlen = s->s3->rbuf.len; - wlen = s->s3->wbuf.len; - init_extra = s->s3->init_extra; - if (s->s3->handshake_buffer) { - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; - } - if (s->s3->handshake_dgst) { - ssl3_free_digest_list(s); - } -#if !defined(OPENSSL_NO_TLSEXT) - if (s->s3->alpn_selected) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = NULL; - } -#endif - memset(s->s3, 0, sizeof(*s->s3)); - s->s3->rbuf.buf = rp; - s->s3->wbuf.buf = wp; - s->s3->rbuf.len = rlen; - s->s3->wbuf.len = wlen; - s->s3->init_extra = init_extra; - - ssl_free_wbio_buffer(s); - - s->packet_length = 0; - s->s3->renegotiate = 0; - s->s3->total_renegotiations = 0; - s->s3->num_renegotiations = 0; - s->s3->in_read_app_data = 0; - s->version = SSL3_VERSION; - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - if (s->next_proto_negotiated) { - OPENSSL_free(s->next_proto_negotiated); - s->next_proto_negotiated = NULL; - s->next_proto_negotiated_len = 0; - } -#endif -} - -#ifndef OPENSSL_NO_SRP -static char *MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg) -{ - return BUF_strdup(s->srp_ctx.info); -} -#endif - -static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, - size_t len); - -long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) -{ - int ret = 0; - -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA) - if ( -# ifndef OPENSSL_NO_RSA - cmd == SSL_CTRL_SET_TMP_RSA || cmd == SSL_CTRL_SET_TMP_RSA_CB || -# endif -# ifndef OPENSSL_NO_DSA - cmd == SSL_CTRL_SET_TMP_DH || cmd == SSL_CTRL_SET_TMP_DH_CB || -# endif - 0) { - if (!ssl_cert_inst(&s->cert)) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE); - return (0); - } - } -#endif - - switch (cmd) { - case SSL_CTRL_GET_SESSION_REUSED: - ret = s->hit; - break; - case SSL_CTRL_GET_CLIENT_CERT_REQUEST: - break; - case SSL_CTRL_GET_NUM_RENEGOTIATIONS: - ret = s->s3->num_renegotiations; - break; - case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: - ret = s->s3->num_renegotiations; - s->s3->num_renegotiations = 0; - break; - case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: - ret = s->s3->total_renegotiations; - break; - case SSL_CTRL_GET_FLAGS: - ret = (int)(s->s3->flags); - break; -#ifndef OPENSSL_NO_RSA - case SSL_CTRL_NEED_TMP_RSA: - if ((s->cert != NULL) && (s->cert->rsa_tmp == NULL) && - ((s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) || - (EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > - (512 / 8)))) - ret = 1; - break; - case SSL_CTRL_SET_TMP_RSA: - { - RSA *rsa = (RSA *)parg; - if (rsa == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return (ret); - } - if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_RSA_LIB); - return (ret); - } - if (s->cert->rsa_tmp != NULL) - RSA_free(s->cert->rsa_tmp); - s->cert->rsa_tmp = rsa; - ret = 1; - } - break; - case SSL_CTRL_SET_TMP_RSA_CB: - { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (ret); - } - break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_CTRL_SET_TMP_DH: - { - DH *dh = (DH *)parg; - if (dh == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return (ret); - } - if ((dh = DHparams_dup(dh)) == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB); - return (ret); - } - if (s->cert->dh_tmp != NULL) - DH_free(s->cert->dh_tmp); - s->cert->dh_tmp = dh; - ret = 1; - } - break; - case SSL_CTRL_SET_TMP_DH_CB: - { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (ret); - } - break; -#endif -#ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_TMP_ECDH: - { - EC_KEY *ecdh = NULL; - - if (parg == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return (ret); - } - if (!EC_KEY_up_ref((EC_KEY *)parg)) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB); - return (ret); - } - ecdh = (EC_KEY *)parg; - if (!(s->options & SSL_OP_SINGLE_ECDH_USE)) { - if (!EC_KEY_generate_key(ecdh)) { - EC_KEY_free(ecdh); - SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB); - return (ret); - } - } - if (s->cert->ecdh_tmp != NULL) - EC_KEY_free(s->cert->ecdh_tmp); - s->cert->ecdh_tmp = ecdh; - ret = 1; - } - break; - case SSL_CTRL_SET_TMP_ECDH_CB: - { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (ret); - } - break; -#endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_TLSEXT - case SSL_CTRL_SET_TLSEXT_HOSTNAME: - if (larg == TLSEXT_NAMETYPE_host_name) { - size_t len; - - if (s->tlsext_hostname != NULL) - OPENSSL_free(s->tlsext_hostname); - s->tlsext_hostname = NULL; - - ret = 1; - if (parg == NULL) - break; - len = strlen((char *)parg); - if (len == 0 || len > TLSEXT_MAXLEN_host_name) { - SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); - return 0; - } - if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL) { - SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR); - return 0; - } - } else { - SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); - return 0; - } - break; - case SSL_CTRL_SET_TLSEXT_DEBUG_ARG: - s->tlsext_debug_arg = parg; - ret = 1; - break; - -# ifdef TLSEXT_TYPE_opaque_prf_input - case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT: - if (larg > 12288) { /* actual internal limit is 2^16 for the - * complete hello message * (including the - * cert chain and everything) */ - SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG); - break; - } - if (s->tlsext_opaque_prf_input != NULL) - OPENSSL_free(s->tlsext_opaque_prf_input); - if ((size_t)larg == 0) - s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte - * just to get - * non-NULL */ - else - s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg); - if (s->tlsext_opaque_prf_input != NULL) { - s->tlsext_opaque_prf_input_len = (size_t)larg; - ret = 1; - } else - s->tlsext_opaque_prf_input_len = 0; - break; -# endif - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: - s->tlsext_status_type = larg; - ret = 1; - break; - - case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS: - *(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts; - ret = 1; - break; - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS: - s->tlsext_ocsp_exts = parg; - ret = 1; - break; - - case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS: - *(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids; - ret = 1; - break; - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS: - s->tlsext_ocsp_ids = parg; - ret = 1; - break; - - case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: - *(unsigned char **)parg = s->tlsext_ocsp_resp; - return s->tlsext_ocsp_resplen; - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: - if (s->tlsext_ocsp_resp) - OPENSSL_free(s->tlsext_ocsp_resp); - s->tlsext_ocsp_resp = parg; - s->tlsext_ocsp_resplen = larg; - ret = 1; - break; - -# ifndef OPENSSL_NO_HEARTBEATS - case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT: - if (SSL_IS_DTLS(s)) - ret = dtls1_heartbeat(s); - else - ret = tls1_heartbeat(s); - break; - - case SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING: - ret = s->tlsext_hb_pending; - break; - - case SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS: - if (larg) - s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_RECV_REQUESTS; - else - s->tlsext_heartbeat &= ~SSL_TLSEXT_HB_DONT_RECV_REQUESTS; - ret = 1; - break; -# endif - -#endif /* !OPENSSL_NO_TLSEXT */ - - case SSL_CTRL_CHAIN: - if (larg) - return ssl_cert_set1_chain(s->cert, (STACK_OF(X509) *)parg); - else - return ssl_cert_set0_chain(s->cert, (STACK_OF(X509) *)parg); - - case SSL_CTRL_CHAIN_CERT: - if (larg) - return ssl_cert_add1_chain_cert(s->cert, (X509 *)parg); - else - return ssl_cert_add0_chain_cert(s->cert, (X509 *)parg); - - case SSL_CTRL_GET_CHAIN_CERTS: - *(STACK_OF(X509) **)parg = s->cert->key->chain; - break; - - case SSL_CTRL_SELECT_CURRENT_CERT: - return ssl_cert_select_current(s->cert, (X509 *)parg); - - case SSL_CTRL_SET_CURRENT_CERT: - if (larg == SSL_CERT_SET_SERVER) { - CERT_PKEY *cpk; - const SSL_CIPHER *cipher; - if (!s->server) - return 0; - cipher = s->s3->tmp.new_cipher; - if (!cipher) - return 0; - /* - * No certificate for unauthenticated ciphersuites or using SRP - * authentication - */ - if (cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) - return 2; - cpk = ssl_get_server_send_pkey(s); - if (!cpk) - return 0; - s->cert->key = cpk; - return 1; - } - return ssl_cert_set_current(s->cert, larg); - -#ifndef OPENSSL_NO_EC - case SSL_CTRL_GET_CURVES: - { - unsigned char *clist; - size_t clistlen; - if (!s->session) - return 0; - clist = s->session->tlsext_ellipticcurvelist; - clistlen = s->session->tlsext_ellipticcurvelist_length / 2; - if (parg) { - size_t i; - int *cptr = parg; - unsigned int cid, nid; - for (i = 0; i < clistlen; i++) { - n2s(clist, cid); - nid = tls1_ec_curve_id2nid(cid); - if (nid != 0) - cptr[i] = nid; - else - cptr[i] = TLSEXT_nid_unknown | cid; - } - } - return (int)clistlen; - } - - case SSL_CTRL_SET_CURVES: - return tls1_set_curves(&s->tlsext_ellipticcurvelist, - &s->tlsext_ellipticcurvelist_length, - parg, larg); - - case SSL_CTRL_SET_CURVES_LIST: - return tls1_set_curves_list(&s->tlsext_ellipticcurvelist, - &s->tlsext_ellipticcurvelist_length, - parg); - - case SSL_CTRL_GET_SHARED_CURVE: - return tls1_shared_curve(s, larg); - -# ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_ECDH_AUTO: - s->cert->ecdh_tmp_auto = larg; - return 1; -# endif -#endif - case SSL_CTRL_SET_SIGALGS: - return tls1_set_sigalgs(s->cert, parg, larg, 0); - - case SSL_CTRL_SET_SIGALGS_LIST: - return tls1_set_sigalgs_list(s->cert, parg, 0); - - case SSL_CTRL_SET_CLIENT_SIGALGS: - return tls1_set_sigalgs(s->cert, parg, larg, 1); - - case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(s->cert, parg, 1); - - case SSL_CTRL_GET_CLIENT_CERT_TYPES: - { - const unsigned char **pctype = parg; - if (s->server || !s->s3->tmp.cert_req) - return 0; - if (s->cert->ctypes) { - if (pctype) - *pctype = s->cert->ctypes; - return (int)s->cert->ctype_num; - } - if (pctype) - *pctype = (unsigned char *)s->s3->tmp.ctype; - return s->s3->tmp.ctype_num; - } - - case SSL_CTRL_SET_CLIENT_CERT_TYPES: - if (!s->server) - return 0; - return ssl3_set_req_cert_type(s->cert, parg, larg); - - case SSL_CTRL_BUILD_CERT_CHAIN: - return ssl_build_cert_chain(s->cert, s->ctx->cert_store, larg); - - case SSL_CTRL_SET_VERIFY_CERT_STORE: - return ssl_cert_set_cert_store(s->cert, parg, 0, larg); - - case SSL_CTRL_SET_CHAIN_CERT_STORE: - return ssl_cert_set_cert_store(s->cert, parg, 1, larg); - - case SSL_CTRL_GET_PEER_SIGNATURE_NID: - if (SSL_USE_SIGALGS(s)) { - if (s->session && s->session->sess_cert) { - const EVP_MD *sig; - sig = s->session->sess_cert->peer_key->digest; - if (sig) { - *(int *)parg = EVP_MD_type(sig); - return 1; - } - } - return 0; - } - /* Might want to do something here for other versions */ - else - return 0; - - case SSL_CTRL_GET_SERVER_TMP_KEY: - if (s->server || !s->session || !s->session->sess_cert) - return 0; - else { - SESS_CERT *sc; - EVP_PKEY *ptmp; - int rv = 0; - sc = s->session->sess_cert; -#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDH) - if (!sc->peer_rsa_tmp && !sc->peer_dh_tmp && !sc->peer_ecdh_tmp) - return 0; -#endif - ptmp = EVP_PKEY_new(); - if (!ptmp) - return 0; - if (0) ; -#ifndef OPENSSL_NO_RSA - else if (sc->peer_rsa_tmp) - rv = EVP_PKEY_set1_RSA(ptmp, sc->peer_rsa_tmp); -#endif -#ifndef OPENSSL_NO_DH - else if (sc->peer_dh_tmp) - rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp); -#endif -#ifndef OPENSSL_NO_ECDH - else if (sc->peer_ecdh_tmp) - rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp); -#endif - if (rv) { - *(EVP_PKEY **)parg = ptmp; - return 1; - } - EVP_PKEY_free(ptmp); - return 0; - } -#ifndef OPENSSL_NO_EC - case SSL_CTRL_GET_EC_POINT_FORMATS: - { - SSL_SESSION *sess = s->session; - const unsigned char **pformat = parg; - if (!sess || !sess->tlsext_ecpointformatlist) - return 0; - *pformat = sess->tlsext_ecpointformatlist; - return (int)sess->tlsext_ecpointformatlist_length; - } -#endif - - case SSL_CTRL_CHECK_PROTO_VERSION: - /* - * For library-internal use; checks that the current protocol is the - * highest enabled version (according to s->ctx->method, as version - * negotiation may have changed s->method). - */ - if (s->version == s->ctx->method->version) - return 1; - /* - * Apparently we're using a version-flexible SSL_METHOD (not at its - * highest protocol version). - */ - if (s->ctx->method->version == SSLv23_method()->version) { -#if TLS_MAX_VERSION != TLS1_2_VERSION -# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION. -#endif - if (!(s->options & SSL_OP_NO_TLSv1_2)) - return s->version == TLS1_2_VERSION; - if (!(s->options & SSL_OP_NO_TLSv1_1)) - return s->version == TLS1_1_VERSION; - if (!(s->options & SSL_OP_NO_TLSv1)) - return s->version == TLS1_VERSION; - if (!(s->options & SSL_OP_NO_SSLv3)) - return s->version == SSL3_VERSION; - if (!(s->options & SSL_OP_NO_SSLv2)) - return s->version == SSL2_VERSION; - } - return 0; /* Unexpected state; fail closed. */ - - default: - break; - } - return (ret); -} - -long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) -{ - int ret = 0; - -#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA) - if ( -# ifndef OPENSSL_NO_RSA - cmd == SSL_CTRL_SET_TMP_RSA_CB || -# endif -# ifndef OPENSSL_NO_DSA - cmd == SSL_CTRL_SET_TMP_DH_CB || -# endif - 0) { - if (!ssl_cert_inst(&s->cert)) { - SSLerr(SSL_F_SSL3_CALLBACK_CTRL, ERR_R_MALLOC_FAILURE); - return (0); - } - } -#endif - - switch (cmd) { -#ifndef OPENSSL_NO_RSA - case SSL_CTRL_SET_TMP_RSA_CB: - { - s->cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_CTRL_SET_TMP_DH_CB: - { - s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_TMP_ECDH_CB: - { - s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_TLSEXT - case SSL_CTRL_SET_TLSEXT_DEBUG_CB: - s->tlsext_debug_cb = (void (*)(SSL *, int, int, - unsigned char *, int, void *))fp; - break; -#endif - default: - break; - } - return (ret); -} - -long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) -{ - CERT *cert; - - cert = ctx->cert; - - switch (cmd) { -#ifndef OPENSSL_NO_RSA - case SSL_CTRL_NEED_TMP_RSA: - if ((cert->rsa_tmp == NULL) && - ((cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) || - (EVP_PKEY_size(cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > - (512 / 8))) - ) - return (1); - else - return (0); - /* break; */ - case SSL_CTRL_SET_TMP_RSA: - { - RSA *rsa; - int i; - - rsa = (RSA *)parg; - i = 1; - if (rsa == NULL) - i = 0; - else { - if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) - i = 0; - } - if (!i) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_RSA_LIB); - return (0); - } else { - if (cert->rsa_tmp != NULL) - RSA_free(cert->rsa_tmp); - cert->rsa_tmp = rsa; - return (1); - } - } - /* break; */ - case SSL_CTRL_SET_TMP_RSA_CB: - { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); - } - break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_CTRL_SET_TMP_DH: - { - DH *new = NULL, *dh; - - dh = (DH *)parg; - if ((new = DHparams_dup(dh)) == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB); - return 0; - } - if (cert->dh_tmp != NULL) - DH_free(cert->dh_tmp); - cert->dh_tmp = new; - return 1; - } - /* - * break; - */ - case SSL_CTRL_SET_TMP_DH_CB: - { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); - } - break; -#endif -#ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_TMP_ECDH: - { - EC_KEY *ecdh = NULL; - - if (parg == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB); - return 0; - } - ecdh = EC_KEY_dup((EC_KEY *)parg); - if (ecdh == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_EC_LIB); - return 0; - } - if (!(ctx->options & SSL_OP_SINGLE_ECDH_USE)) { - if (!EC_KEY_generate_key(ecdh)) { - EC_KEY_free(ecdh); - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB); - return 0; - } - } - - if (cert->ecdh_tmp != NULL) { - EC_KEY_free(cert->ecdh_tmp); - } - cert->ecdh_tmp = ecdh; - return 1; - } - /* break; */ - case SSL_CTRL_SET_TMP_ECDH_CB: - { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); - } - break; -#endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_TLSEXT - case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: - ctx->tlsext_servername_arg = parg; - break; - case SSL_CTRL_SET_TLSEXT_TICKET_KEYS: - case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: - { - unsigned char *keys = parg; - if (!keys) - return 48; - if (larg != 48) { - SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH); - return 0; - } - if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) { - memcpy(ctx->tlsext_tick_key_name, keys, 16); - memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16); - memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16); - } else { - memcpy(keys, ctx->tlsext_tick_key_name, 16); - memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16); - memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16); - } - return 1; - } - -# ifdef TLSEXT_TYPE_opaque_prf_input - case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG: - ctx->tlsext_opaque_prf_input_callback_arg = parg; - return 1; -# endif - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: - ctx->tlsext_status_arg = parg; - return 1; - break; - -# ifndef OPENSSL_NO_SRP - case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - if (ctx->srp_ctx.login != NULL) - OPENSSL_free(ctx->srp_ctx.login); - ctx->srp_ctx.login = NULL; - if (parg == NULL) - break; - if (strlen((const char *)parg) > 255 - || strlen((const char *)parg) < 1) { - SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME); - return 0; - } - if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL) { - SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR); - return 0; - } - break; - case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD: - ctx->srp_ctx.SRP_give_srp_client_pwd_callback = - srp_password_from_info_cb; - ctx->srp_ctx.info = parg; - break; - case SSL_CTRL_SET_SRP_ARG: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - ctx->srp_ctx.SRP_cb_arg = parg; - break; - - case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH: - ctx->srp_ctx.strength = larg; - break; -# endif - -# ifndef OPENSSL_NO_EC - case SSL_CTRL_SET_CURVES: - return tls1_set_curves(&ctx->tlsext_ellipticcurvelist, - &ctx->tlsext_ellipticcurvelist_length, - parg, larg); - - case SSL_CTRL_SET_CURVES_LIST: - return tls1_set_curves_list(&ctx->tlsext_ellipticcurvelist, - &ctx->tlsext_ellipticcurvelist_length, - parg); -# ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_ECDH_AUTO: - ctx->cert->ecdh_tmp_auto = larg; - return 1; -# endif -# endif - case SSL_CTRL_SET_SIGALGS: - return tls1_set_sigalgs(ctx->cert, parg, larg, 0); - - case SSL_CTRL_SET_SIGALGS_LIST: - return tls1_set_sigalgs_list(ctx->cert, parg, 0); - - case SSL_CTRL_SET_CLIENT_SIGALGS: - return tls1_set_sigalgs(ctx->cert, parg, larg, 1); - - case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(ctx->cert, parg, 1); - - case SSL_CTRL_SET_CLIENT_CERT_TYPES: - return ssl3_set_req_cert_type(ctx->cert, parg, larg); - - case SSL_CTRL_BUILD_CERT_CHAIN: - return ssl_build_cert_chain(ctx->cert, ctx->cert_store, larg); - - case SSL_CTRL_SET_VERIFY_CERT_STORE: - return ssl_cert_set_cert_store(ctx->cert, parg, 0, larg); - - case SSL_CTRL_SET_CHAIN_CERT_STORE: - return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg); - -#endif /* !OPENSSL_NO_TLSEXT */ - - /* A Thawte special :-) */ - case SSL_CTRL_EXTRA_CHAIN_CERT: - if (ctx->extra_certs == NULL) { - if ((ctx->extra_certs = sk_X509_new_null()) == NULL) - return (0); - } - sk_X509_push(ctx->extra_certs, (X509 *)parg); - break; - - case SSL_CTRL_GET_EXTRA_CHAIN_CERTS: - if (ctx->extra_certs == NULL && larg == 0) - *(STACK_OF(X509) **)parg = ctx->cert->key->chain; - else - *(STACK_OF(X509) **)parg = ctx->extra_certs; - break; - - case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS: - if (ctx->extra_certs) { - sk_X509_pop_free(ctx->extra_certs, X509_free); - ctx->extra_certs = NULL; - } - break; - - case SSL_CTRL_CHAIN: - if (larg) - return ssl_cert_set1_chain(ctx->cert, (STACK_OF(X509) *)parg); - else - return ssl_cert_set0_chain(ctx->cert, (STACK_OF(X509) *)parg); - - case SSL_CTRL_CHAIN_CERT: - if (larg) - return ssl_cert_add1_chain_cert(ctx->cert, (X509 *)parg); - else - return ssl_cert_add0_chain_cert(ctx->cert, (X509 *)parg); - - case SSL_CTRL_GET_CHAIN_CERTS: - *(STACK_OF(X509) **)parg = ctx->cert->key->chain; - break; - - case SSL_CTRL_SELECT_CURRENT_CERT: - return ssl_cert_select_current(ctx->cert, (X509 *)parg); - - case SSL_CTRL_SET_CURRENT_CERT: - return ssl_cert_set_current(ctx->cert, larg); - - default: - return (0); - } - return (1); -} - -long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) -{ - CERT *cert; - - cert = ctx->cert; - - switch (cmd) { -#ifndef OPENSSL_NO_RSA - case SSL_CTRL_SET_TMP_RSA_CB: - { - cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_DH - case SSL_CTRL_SET_TMP_DH_CB: - { - cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_ECDH - case SSL_CTRL_SET_TMP_ECDH_CB: - { - cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; - } - break; -#endif -#ifndef OPENSSL_NO_TLSEXT - case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: - ctx->tlsext_servername_callback = (int (*)(SSL *, int *, void *))fp; - break; - -# ifdef TLSEXT_TYPE_opaque_prf_input - case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB: - ctx->tlsext_opaque_prf_input_callback = - (int (*)(SSL *, void *, size_t, void *))fp; - break; -# endif - - case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB: - ctx->tlsext_status_cb = (int (*)(SSL *, void *))fp; - break; - - case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB: - ctx->tlsext_ticket_key_cb = (int (*)(SSL *, unsigned char *, - unsigned char *, - EVP_CIPHER_CTX *, - HMAC_CTX *, int))fp; - break; - -# ifndef OPENSSL_NO_SRP - case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - ctx->srp_ctx.SRP_verify_param_callback = (int (*)(SSL *, void *))fp; - break; - case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - ctx->srp_ctx.TLS_ext_srp_username_callback = - (int (*)(SSL *, int *, void *))fp; - break; - case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB: - ctx->srp_ctx.srp_Mask |= SSL_kSRP; - ctx->srp_ctx.SRP_give_srp_client_pwd_callback = - (char *(*)(SSL *, void *))fp; - break; -# endif -#endif - default: - return (0); - } - return (1); -} - -/* - * This function needs to check if the ciphers required are actually - * available - */ -const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p) -{ - SSL_CIPHER c; - const SSL_CIPHER *cp; - unsigned long id; - - id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1]; - c.id = id; - cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS); -#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES - if (cp == NULL) - fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]); -#endif - return cp; -} - -int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) -{ - long l; - - if (p != NULL) { - l = c->id; - if ((l & 0xff000000) != 0x03000000) - return (0); - p[0] = ((unsigned char)(l >> 8L)) & 0xFF; - p[1] = ((unsigned char)(l)) & 0xFF; - } - return (2); -} - -SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, - STACK_OF(SSL_CIPHER) *srvr) -{ - SSL_CIPHER *c, *ret = NULL; - STACK_OF(SSL_CIPHER) *prio, *allow; - int i, ii, ok; - CERT *cert; - unsigned long alg_k, alg_a, mask_k, mask_a, emask_k, emask_a; - - /* Let's see which ciphers we can support */ - cert = s->cert; - -#if 0 - /* - * Do not set the compare functions, because this may lead to a - * reordering by "id". We want to keep the original ordering. We may pay - * a price in performance during sk_SSL_CIPHER_find(), but would have to - * pay with the price of sk_SSL_CIPHER_dup(). - */ - sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp); - sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp); -#endif - -#ifdef CIPHER_DEBUG - fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), - (void *)srvr); - for (i = 0; i < sk_SSL_CIPHER_num(srvr); ++i) { - c = sk_SSL_CIPHER_value(srvr, i); - fprintf(stderr, "%p:%s\n", (void *)c, c->name); - } - fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), - (void *)clnt); - for (i = 0; i < sk_SSL_CIPHER_num(clnt); ++i) { - c = sk_SSL_CIPHER_value(clnt, i); - fprintf(stderr, "%p:%s\n", (void *)c, c->name); - } -#endif - - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || tls1_suiteb(s)) { - prio = srvr; - allow = clnt; - } else { - prio = clnt; - allow = srvr; - } - - tls1_set_cert_validity(s); - - for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { - c = sk_SSL_CIPHER_value(prio, i); - - /* Skip TLS v1.2 only ciphersuites if not supported */ - if ((c->algorithm_ssl & SSL_TLSV1_2) && !SSL_USE_TLS1_2_CIPHERS(s)) - continue; - - ssl_set_cert_masks(cert, c); - mask_k = cert->mask_k; - mask_a = cert->mask_a; - emask_k = cert->export_mask_k; - emask_a = cert->export_mask_a; -#ifndef OPENSSL_NO_SRP - if (s->srp_ctx.srp_Mask & SSL_kSRP) { - mask_k |= SSL_kSRP; - emask_k |= SSL_kSRP; - mask_a |= SSL_aSRP; - emask_a |= SSL_aSRP; - } -#endif - -#ifdef KSSL_DEBUG - /* - * fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n", - * i,c->algorithms); - */ -#endif /* KSSL_DEBUG */ - - alg_k = c->algorithm_mkey; - alg_a = c->algorithm_auth; - -#ifndef OPENSSL_NO_KRB5 - if (alg_k & SSL_kKRB5) { - if (!kssl_keytab_is_available(s->kssl_ctx)) - continue; - } -#endif /* OPENSSL_NO_KRB5 */ -#ifndef OPENSSL_NO_PSK - /* with PSK there must be server callback set */ - if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL) - continue; -#endif /* OPENSSL_NO_PSK */ - - if (SSL_C_IS_EXPORT(c)) { - ok = (alg_k & emask_k) && (alg_a & emask_a); -#ifdef CIPHER_DEBUG - fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n", - ok, alg_k, alg_a, emask_k, emask_a, (void *)c, c->name); -#endif - } else { - ok = (alg_k & mask_k) && (alg_a & mask_a); -#ifdef CIPHER_DEBUG - fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k, - alg_a, mask_k, mask_a, (void *)c, c->name); -#endif - } - -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC -# ifndef OPENSSL_NO_ECDH - /* - * if we are considering an ECC cipher suite that uses an ephemeral - * EC key check it - */ - if (alg_k & SSL_kEECDH) - ok = ok && tls1_check_ec_tmp_key(s, c->id); -# endif /* OPENSSL_NO_ECDH */ -# endif /* OPENSSL_NO_EC */ -#endif /* OPENSSL_NO_TLSEXT */ - - if (!ok) - continue; - ii = sk_SSL_CIPHER_find(allow, c); - if (ii >= 0) { -#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT) - if ((alg_k & SSL_kEECDH) && (alg_a & SSL_aECDSA) - && s->s3->is_probably_safari) { - if (!ret) - ret = sk_SSL_CIPHER_value(allow, ii); - continue; - } -#endif - ret = sk_SSL_CIPHER_value(allow, ii); - break; - } - } - return (ret); -} - -int ssl3_get_req_cert_type(SSL *s, unsigned char *p) -{ - int ret = 0; - const unsigned char *sig; - size_t i, siglen; - int have_rsa_sign = 0, have_dsa_sign = 0; -#ifndef OPENSSL_NO_ECDSA - int have_ecdsa_sign = 0; -#endif -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) - int nostrict = 1; -#endif -#if !defined(OPENSSL_NO_GOST) || !defined(OPENSSL_NO_DH) || \ - !defined(OPENSSL_NO_ECDH) - unsigned long alg_k; -#endif - - /* If we have custom certificate types set, use them */ - if (s->cert->ctypes) { - memcpy(p, s->cert->ctypes, s->cert->ctype_num); - return (int)s->cert->ctype_num; - } - /* get configured sigalgs */ - siglen = tls12_get_psigalgs(s, 1, &sig); -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) - if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) - nostrict = 0; -#endif - for (i = 0; i < siglen; i += 2, sig += 2) { - switch (sig[1]) { - case TLSEXT_signature_rsa: - have_rsa_sign = 1; - break; - - case TLSEXT_signature_dsa: - have_dsa_sign = 1; - break; -#ifndef OPENSSL_NO_ECDSA - case TLSEXT_signature_ecdsa: - have_ecdsa_sign = 1; - break; -#endif - } - } - -#if !defined(OPENSSL_NO_GOST) || !defined(OPENSSL_NO_DH) || \ - !defined(OPENSSL_NO_ECDH) - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; -#endif - -#ifndef OPENSSL_NO_GOST - if (s->version >= TLS1_VERSION) { - if (alg_k & SSL_kGOST) { - p[ret++] = TLS_CT_GOST94_SIGN; - p[ret++] = TLS_CT_GOST01_SIGN; - return (ret); - } - } -#endif - -#ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kDHr | SSL_kEDH)) { -# ifndef OPENSSL_NO_RSA - /* - * Since this refers to a certificate signed with an RSA algorithm, - * only check for rsa signing in strict mode. - */ - if (nostrict || have_rsa_sign) - p[ret++] = SSL3_CT_RSA_FIXED_DH; -# endif -# ifndef OPENSSL_NO_DSA - if (nostrict || have_dsa_sign) - p[ret++] = SSL3_CT_DSS_FIXED_DH; -# endif - } - if ((s->version == SSL3_VERSION) && - (alg_k & (SSL_kEDH | SSL_kDHd | SSL_kDHr))) { -# ifndef OPENSSL_NO_RSA - p[ret++] = SSL3_CT_RSA_EPHEMERAL_DH; -# endif -# ifndef OPENSSL_NO_DSA - p[ret++] = SSL3_CT_DSS_EPHEMERAL_DH; -# endif - } -#endif /* !OPENSSL_NO_DH */ -#ifndef OPENSSL_NO_RSA - if (have_rsa_sign) - p[ret++] = SSL3_CT_RSA_SIGN; -#endif -#ifndef OPENSSL_NO_DSA - if (have_dsa_sign) - p[ret++] = SSL3_CT_DSS_SIGN; -#endif -#ifndef OPENSSL_NO_ECDH - if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->version >= TLS1_VERSION)) { - if (nostrict || have_rsa_sign) - p[ret++] = TLS_CT_RSA_FIXED_ECDH; - if (nostrict || have_ecdsa_sign) - p[ret++] = TLS_CT_ECDSA_FIXED_ECDH; - } -#endif - -#ifndef OPENSSL_NO_ECDSA - /* - * ECDSA certs can be used with RSA cipher suites as well so we don't - * need to check for SSL_kECDH or SSL_kEECDH - */ - if (s->version >= TLS1_VERSION) { - if (have_ecdsa_sign) - p[ret++] = TLS_CT_ECDSA_SIGN; - } -#endif - return (ret); -} - -static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len) -{ - if (c->ctypes) { - OPENSSL_free(c->ctypes); - c->ctypes = NULL; - } - if (!p || !len) - return 1; - if (len > 0xff) - return 0; - c->ctypes = OPENSSL_malloc(len); - if (!c->ctypes) - return 0; - memcpy(c->ctypes, p, len); - c->ctype_num = len; - return 1; -} - -int ssl3_shutdown(SSL *s) -{ - int ret; - - /* - * Don't do anything much if we have not done the handshake or we don't - * want to send messages :-) - */ - if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE)) { - s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); - return (1); - } - - if (!(s->shutdown & SSL_SENT_SHUTDOWN)) { - s->shutdown |= SSL_SENT_SHUTDOWN; -#if 1 - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); -#endif - /* - * our shutdown alert has been sent now, and if it still needs to be - * written, s->s3->alert_dispatch will be true - */ - if (s->s3->alert_dispatch) - return (-1); /* return WANT_WRITE */ - } else if (s->s3->alert_dispatch) { - /* resend it if not sent */ -#if 1 - ret = s->method->ssl_dispatch_alert(s); - if (ret == -1) { - /* - * we only get to return -1 here the 2nd/Nth invocation, we must - * have already signalled return 0 upon a previous invoation, - * return WANT_WRITE - */ - return (ret); - } -#endif - } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { - /* - * If we are waiting for a close from our peer, we are closed - */ - s->method->ssl_read_bytes(s, 0, NULL, 0, 0); - if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { - return (-1); /* return WANT_READ */ - } - } - - if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) && - !s->s3->alert_dispatch) - return (1); - else - return (0); -} - -int ssl3_write(SSL *s, const void *buf, int len) -{ - int ret, n; - -#if 0 - if (s->shutdown & SSL_SEND_SHUTDOWN) { - s->rwstate = SSL_NOTHING; - return (0); - } -#endif - clear_sys_error(); - if (s->s3->renegotiate) - ssl3_renegotiate_check(s); - - /* - * This is an experimental flag that sends the last handshake message in - * the same packet as the first use data - used to see if it helps the - * TCP protocol during session-id reuse - */ - /* The second test is because the buffer may have been removed */ - if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) { - /* First time through, we write into the buffer */ - if (s->s3->delay_buf_pop_ret == 0) { - ret = ssl3_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len); - if (ret <= 0) - return (ret); - - s->s3->delay_buf_pop_ret = ret; - } - - s->rwstate = SSL_WRITING; - n = BIO_flush(s->wbio); - if (n <= 0) - return (n); - s->rwstate = SSL_NOTHING; - - /* We have flushed the buffer, so remove it */ - ssl_free_wbio_buffer(s); - s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; - - ret = s->s3->delay_buf_pop_ret; - s->s3->delay_buf_pop_ret = 0; - } else { - ret = s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, - buf, len); - if (ret <= 0) - return (ret); - } - - return (ret); -} - -static int ssl3_read_internal(SSL *s, void *buf, int len, int peek) -{ - int ret; - - clear_sys_error(); - if (s->s3->renegotiate) - ssl3_renegotiate_check(s); - s->s3->in_read_app_data = 1; - ret = - s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, - peek); - if ((ret == -1) && (s->s3->in_read_app_data == 2)) { - /* - * ssl3_read_bytes decided to call s->handshake_func, which called - * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes - * actually found application data and thinks that application data - * makes sense here; so disable handshake processing and try to read - * application data again. - */ - s->in_handshake++; - ret = - s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, - peek); - s->in_handshake--; - } else - s->s3->in_read_app_data = 0; - - return (ret); -} - -int ssl3_read(SSL *s, void *buf, int len) -{ - return ssl3_read_internal(s, buf, len, 0); -} - -int ssl3_peek(SSL *s, void *buf, int len) -{ - return ssl3_read_internal(s, buf, len, 1); -} - -int ssl3_renegotiate(SSL *s) -{ - if (s->handshake_func == NULL) - return (1); - - if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) - return (0); - - s->s3->renegotiate = 1; - return (1); -} - -int ssl3_renegotiate_check(SSL *s) -{ - int ret = 0; - - if (s->s3->renegotiate) { - if ((s->s3->rbuf.left == 0) && - (s->s3->wbuf.left == 0) && !SSL_in_init(s)) { - /* - * if we are the server, and we have sent a 'RENEGOTIATE' - * message, we need to go to SSL_ST_ACCEPT. - */ - /* SSL_ST_ACCEPT */ - s->state = SSL_ST_RENEGOTIATE; - s->s3->renegotiate = 0; - s->s3->num_renegotiations++; - s->s3->total_renegotiations++; - ret = 1; - } - } - return (ret); -} - -/* - * If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and - * handshake macs if required. - */ -long ssl_get_algorithm2(SSL *s) -{ - long alg2; - if (s->s3 == NULL || s->s3->tmp.new_cipher == NULL) - return -1; - alg2 = s->s3->tmp.new_cipher->algorithm2; - if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF - && alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF)) - return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; - return alg2; -} -/* ssl/s3_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "objects.h" -// #include "ssl_locl.h" - -#ifndef OPENSSL_NO_SSL3_METHOD -static const SSL_METHOD *ssl3_get_method(int ver) -{ - if (ver == SSL3_VERSION) - return (SSLv3_method()); - else - return (NULL); -} - -IMPLEMENT_ssl3_meth_func(SSLv3_method, - ssl3_accept, ssl3_connect, ssl3_get_method) -#endif -/* ssl/s3_pkt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#define USE_SOCKETS -// #include "ssl_locl.h" -// #include "evp.h" -// #include "buffer.h" -// #include "rand.h" - -#ifndef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK -# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 -#endif - -#if defined(OPENSSL_SMALL_FOOTPRINT) || \ - !( defined(AES_ASM) && ( \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_AMD64) || defined(_M_X64) || \ - defined(__INTEL__) ) \ - ) -# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK -# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0 -#endif - -static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragment); -static int ssl3_get_record(SSL *s); - -/* - * Return values are as per SSL_read() - */ -int ssl3_read_n(SSL *s, int n, int max, int extend) -{ - /* - * If extend == 0, obtain new n-byte packet; if extend == 1, increase - * packet by another n bytes. The packet will be in the sub-array of - * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If - * s->read_ahead is set, 'max' bytes may be stored in rbuf [plus - * s->packet_length bytes if extend == 1].) - */ - int i, len, left; - long align = 0; - unsigned char *pkt; - SSL3_BUFFER *rb; - - if (n <= 0) - return n; - - rb = &(s->s3->rbuf); - if (rb->buf == NULL) - if (!ssl3_setup_read_buffer(s)) - return -1; - - left = rb->left; -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (long)rb->buf + SSL3_RT_HEADER_LENGTH; - align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - - if (!extend) { - /* start with empty packet ... */ - if (left == 0) - rb->offset = align; - else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { - /* - * check if next packet length is large enough to justify payload - * alignment... - */ - pkt = rb->buf + rb->offset; - if (pkt[0] == SSL3_RT_APPLICATION_DATA - && (pkt[3] << 8 | pkt[4]) >= 128) { - /* - * Note that even if packet is corrupted and its length field - * is insane, we can only be led to wrong decision about - * whether memmove will occur or not. Header values has no - * effect on memmove arguments and therefore no buffer - * overrun can be triggered. - */ - memmove(rb->buf + align, pkt, left); - rb->offset = align; - } - } - s->packet = rb->buf + rb->offset; - s->packet_length = 0; - /* ... now we can act as if 'extend' was set */ - } - - /* - * For DTLS/UDP reads should not span multiple packets because the read - * operation returns the whole packet at once (as long as it fits into - * the buffer). - */ - if (SSL_IS_DTLS(s)) { - if (left == 0 && extend) - return 0; - if (left > 0 && n > left) - n = left; - } - - /* if there is enough in the buffer from a previous read, take some */ - if (left >= n) { - s->packet_length += n; - rb->left = left - n; - rb->offset += n; - return (n); - } - - /* else we need to read more data */ - - len = s->packet_length; - pkt = rb->buf + align; - /* - * Move any available bytes to front of buffer: 'len' bytes already - * pointed to by 'packet', 'left' extra ones at the end - */ - if (s->packet != pkt) { /* len > 0 */ - memmove(pkt, s->packet, len + left); - s->packet = pkt; - rb->offset = len + align; - } - - if (n > (int)(rb->len - rb->offset)) { /* does not happen */ - SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR); - return -1; - } - - /* We always act like read_ahead is set for DTLS */ - if (!s->read_ahead && !SSL_IS_DTLS(s)) - /* ignore max parameter */ - max = n; - else { - if (max < n) - max = n; - if (max > (int)(rb->len - rb->offset)) - max = rb->len - rb->offset; - } - - while (left < n) { - /* - * Now we have len+left bytes at the front of s->s3->rbuf.buf and - * need to read in more until we have len+n (up to len+max if - * possible) - */ - - clear_sys_error(); - if (s->rbio != NULL) { - s->rwstate = SSL_READING; - i = BIO_read(s->rbio, pkt + len + left, max - left); - } else { - SSLerr(SSL_F_SSL3_READ_N, SSL_R_READ_BIO_NOT_SET); - i = -1; - } - - if (i <= 0) { - rb->left = left; - if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) - if (len + left == 0) - ssl3_release_read_buffer(s); - return (i); - } - left += i; - /* - * reads should *never* span multiple packets for DTLS because the - * underlying transport protocol is message oriented as opposed to - * byte oriented as in the TLS case. - */ - if (SSL_IS_DTLS(s)) { - if (n > left) - n = left; /* makes the while condition false */ - } - } - - /* done reading, now the book-keeping */ - rb->offset += n; - rb->left = left - n; - s->packet_length += n; - s->rwstate = SSL_NOTHING; - return (n); -} - -/* - * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that - * will be processed per call to ssl3_get_record. Without this limit an - * attacker could send empty records at a faster rate than we can process and - * cause ssl3_get_record to loop forever. - */ -#define MAX_EMPTY_RECORDS 32 - -/*- - * Call this to get a new input record. - * It will return <= 0 if more data is needed, normally due to an error - * or non-blocking IO. - * When it finishes, one packet has been decoded and can be found in - * ssl->s3->rrec.type - is the type of record - * ssl->s3->rrec.data, - data - * ssl->s3->rrec.length, - number of bytes - */ -/* used only by ssl3_read_bytes */ -static int ssl3_get_record(SSL *s) -{ - int ssl_major, ssl_minor, al; - int enc_err, n, i, ret = -1; - SSL3_RECORD *rr; - SSL_SESSION *sess; - unsigned char *p; - unsigned char md[EVP_MAX_MD_SIZE]; - short version; - unsigned mac_size, orig_len; - size_t extra; - unsigned empty_record_count = 0; - - rr = &(s->s3->rrec); - sess = s->session; - - if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) - extra = SSL3_RT_MAX_EXTRA; - else - extra = 0; - if (extra && !s->s3->init_extra) { - /* - * An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER set after - * ssl3_setup_buffers() was done - */ - SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR); - return -1; - } - - again: - /* check if we have the header */ - if ((s->rstate != SSL_ST_READ_BODY) || - (s->packet_length < SSL3_RT_HEADER_LENGTH)) { - n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); - if (n <= 0) - return (n); /* error or non-blocking */ - s->rstate = SSL_ST_READ_BODY; - - p = s->packet; - if (s->msg_callback) - s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, - s->msg_callback_arg); - - /* Pull apart the header into the SSL3_RECORD */ - rr->type = *(p++); - ssl_major = *(p++); - ssl_minor = *(p++); - version = (ssl_major << 8) | ssl_minor; - n2s(p, rr->length); -#if 0 - fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length); -#endif - - /* Lets check version */ - if (!s->first_packet) { - if (version != s->version) { - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); - if ((s->version & 0xFF00) == (version & 0xFF00) - && !s->enc_write_ctx && !s->write_hash) { - if (rr->type == SSL3_RT_ALERT) { - /* - * The record is using an incorrect version number, but - * what we've got appears to be an alert. We haven't - * read the body yet to check whether its a fatal or - * not - but chances are it is. We probably shouldn't - * send a fatal alert back. We'll just end. - */ - goto err; - } - /* - * Send back error using their minor version number :-) - */ - s->version = (unsigned short)version; - } - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - } - - if ((version >> 8) != SSL3_VERSION_MAJOR) { - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); - goto err; - } - - if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG); - goto f_err; - } - - /* now s->rstate == SSL_ST_READ_BODY */ - } - - /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ - - if (rr->length > s->packet_length - SSL3_RT_HEADER_LENGTH) { - /* now s->packet_length == SSL3_RT_HEADER_LENGTH */ - i = rr->length; - n = ssl3_read_n(s, i, i, 1); - if (n <= 0) - return (n); /* error or non-blocking io */ - /* - * now n == rr->length, and s->packet_length == SSL3_RT_HEADER_LENGTH - * + rr->length - */ - } - - s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ - - /* - * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, - * and we have that many bytes in s->packet - */ - rr->input = &(s->packet[SSL3_RT_HEADER_LENGTH]); - - /* - * ok, we can now read from 's->packet' data into 'rr' rr->input points - * at rr->length bytes, which need to be copied into rr->data by either - * the decryption or by the decompression When the data is 'copied' into - * the rr->data buffer, rr->input will be pointed at the new buffer - */ - - /* - * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length - * bytes of encrypted compressed stuff. - */ - - /* check is not needed I believe */ - if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); - goto f_err; - } - - /* decrypt in place in 'rr->input' */ - rr->data = rr->input; - - enc_err = s->method->ssl3_enc->enc(s, 0); - /*- - * enc_err is: - * 0: (in non-constant time) if the record is publically invalid. - * 1: if the padding is valid - * -1: if the padding is invalid - */ - if (enc_err == 0) { - al = SSL_AD_DECRYPTION_FAILED; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); - goto f_err; - } -#ifdef TLS_DEBUG - printf("dec %d\n", rr->length); - { - unsigned int z; - for (z = 0; z < rr->length; z++) - printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\n"); -#endif - - /* r->length is now the compressed data plus mac */ - if ((sess != NULL) && - (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { - /* s->read_hash != NULL => mac_size != -1 */ - unsigned char *mac = NULL; - unsigned char mac_tmp[EVP_MAX_MD_SIZE]; - mac_size = EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); - - /* - * kludge: *_cbc_remove_padding passes padding length in rr->type - */ - orig_len = rr->length + ((unsigned int)rr->type >> 8); - - /* - * orig_len is the length of the record before any padding was - * removed. This is public information, as is the MAC in use, - * therefore we can safely process the record in a different amount - * of time if it's too short to possibly contain a MAC. - */ - if (orig_len < mac_size || - /* CBC records must have a padding length byte too. */ - (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && - orig_len < mac_size + 1)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { - /* - * We update the length so that the TLS header bytes can be - * constructed correctly but we need to extract the MAC in - * constant time from within the record, without leaking the - * contents of the padding bytes. - */ - mac = mac_tmp; - ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); - rr->length -= mac_size; - } else { - /* - * In this case there's no padding, so |orig_len| equals - * |rec->length| and we checked that there's enough bytes for - * |mac_size| above. - */ - rr->length -= mac_size; - mac = &rr->data[rr->length]; - } - - i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); - if (i < 0 || mac == NULL - || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) - enc_err = -1; - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra + mac_size) - enc_err = -1; - } - - if (enc_err < 0) { - /* - * A separate 'decryption_failed' alert was introduced with TLS 1.0, - * SSL 3.0 only has 'bad_record_mac'. But unless a decryption - * failure is directly visible from the ciphertext anyway, we should - * not reveal which kind of error occured -- this might become - * visible to an attacker (e.g. via a logfile) - */ - al = SSL_AD_BAD_RECORD_MAC; - SSLerr(SSL_F_SSL3_GET_RECORD, - SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); - goto f_err; - } - - /* r->length is now just compressed */ - if (s->expand != NULL) { - if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_COMPRESSED_LENGTH_TOO_LONG); - goto f_err; - } - if (!ssl3_do_uncompress(s)) { - al = SSL_AD_DECOMPRESSION_FAILURE; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_DECOMPRESSION); - goto f_err; - } - } - - if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH + extra) { - al = SSL_AD_RECORD_OVERFLOW; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); - goto f_err; - } - - rr->off = 0; - /*- - * So at this point the following is true - * ssl->s3->rrec.type is the type of record - * ssl->s3->rrec.length == number of bytes in record - * ssl->s3->rrec.off == offset to first valid byte - * ssl->s3->rrec.data == where to take bytes from, increment - * after use :-). - */ - - /* we have pulled in a full packet so zero things */ - s->packet_length = 0; - - /* just read a 0 length packet */ - if (rr->length == 0) { - empty_record_count++; - if (empty_record_count > MAX_EMPTY_RECORDS) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_RECORD_TOO_SMALL); - goto f_err; - } - goto again; - } -#if 0 - fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, - rr->length); -#endif - - return (1); - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (ret); -} - -int ssl3_do_uncompress(SSL *ssl) -{ -#ifndef OPENSSL_NO_COMP - int i; - SSL3_RECORD *rr; - - rr = &(ssl->s3->rrec); - i = COMP_expand_block(ssl->expand, rr->comp, - SSL3_RT_MAX_PLAIN_LENGTH, rr->data, - (int)rr->length); - if (i < 0) - return (0); - else - rr->length = i; - rr->data = rr->comp; -#endif - return (1); -} - -int ssl3_do_compress(SSL *ssl) -{ -#ifndef OPENSSL_NO_COMP - int i; - SSL3_RECORD *wr; - - wr = &(ssl->s3->wrec); - i = COMP_compress_block(ssl->compress, wr->data, - SSL3_RT_MAX_COMPRESSED_LENGTH, - wr->input, (int)wr->length); - if (i < 0) - return (0); - else - wr->length = i; - - wr->input = wr->data; -#endif - return (1); -} - -/* - * Call this to write data in records of type 'type' It will return <= 0 if - * not all data has been sent or non-blocking IO. - */ -int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) -{ - const unsigned char *buf = buf_; - int tot; - unsigned int n, nw; -#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - unsigned int max_send_fragment; -#endif - SSL3_BUFFER *wb = &(s->s3->wbuf); - int i; - - s->rwstate = SSL_NOTHING; - OPENSSL_assert(s->s3->wnum <= INT_MAX); - tot = s->s3->wnum; - s->s3->wnum = 0; - - if (SSL_in_init(s) && !s->in_handshake) { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return -1; - } - } - - /* - * ensure that if we end up with a smaller value of data to write out - * than the the original len from a write which didn't complete for - * non-blocking I/O and also somehow ended up avoiding the check for - * this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be - * possible to end up with (len-tot) as a large number that will then - * promptly send beyond the end of the users buffer ... so we trap and - * report the error in a way the user will notice - */ - if ((len < tot) || ((wb->left != 0) && (len < (tot + s->s3->wpend_tot)))) { - SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); - return (-1); - } - - /* - * first check if there is a SSL3_BUFFER still being written out. This - * will happen with non blocking IO - */ - if (wb->left != 0) { - i = ssl3_write_pending(s, type, &buf[tot], s->s3->wpend_tot); - if (i <= 0) { - /* XXX should we ssl3_release_write_buffer if i<0? */ - s->s3->wnum = tot; - return i; - } - tot += i; /* this might be last fragment */ - } -#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK - /* - * Depending on platform multi-block can deliver several *times* - * better performance. Downside is that it has to allocate - * jumbo buffer to accomodate up to 8 records, but the - * compromise is considered worthy. - */ - if (type == SSL3_RT_APPLICATION_DATA && - len >= 4 * (int)(max_send_fragment = s->max_send_fragment) && - s->compress == NULL && s->msg_callback == NULL && - SSL_USE_EXPLICIT_IV(s) && - s->enc_write_ctx != NULL && - EVP_CIPHER_flags(s->enc_write_ctx->cipher) & - EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) { - unsigned char aad[13]; - EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; - int packlen; - - /* minimize address aliasing conflicts */ - if ((max_send_fragment & 0xfff) == 0) - max_send_fragment -= 512; - - if (tot == 0 || wb->buf == NULL) { /* allocate jumbo buffer */ - ssl3_release_write_buffer(s); - - packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE, - max_send_fragment, NULL); - - if (len >= 8 * (int)max_send_fragment) - packlen *= 8; - else - packlen *= 4; - - wb->buf = OPENSSL_malloc(packlen); - if (!wb->buf) { - SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_MALLOC_FAILURE); - return -1; - } - wb->len = packlen; - } else if (tot == len) { /* done? */ - OPENSSL_free(wb->buf); /* free jumbo buffer */ - wb->buf = NULL; - return tot; - } - - n = (len - tot); - for (;;) { - if (n < 4 * max_send_fragment) { - OPENSSL_free(wb->buf); /* free jumbo buffer */ - wb->buf = NULL; - break; - } - - if (s->s3->alert_dispatch) { - i = s->method->ssl_dispatch_alert(s); - if (i <= 0) { - s->s3->wnum = tot; - return i; - } - } - - if (n >= 8 * max_send_fragment) - nw = max_send_fragment * (mb_param.interleave = 8); - else - nw = max_send_fragment * (mb_param.interleave = 4); - - memcpy(aad, s->s3->write_sequence, 8); - aad[8] = type; - aad[9] = (unsigned char)(s->version >> 8); - aad[10] = (unsigned char)(s->version); - aad[11] = 0; - aad[12] = 0; - mb_param.out = NULL; - mb_param.inp = aad; - mb_param.len = nw; - - packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_AAD, - sizeof(mb_param), &mb_param); - - if (packlen <= 0 || packlen > (int)wb->len) { /* never happens */ - OPENSSL_free(wb->buf); /* free jumbo buffer */ - wb->buf = NULL; - break; - } - - mb_param.out = wb->buf; - mb_param.inp = &buf[tot]; - mb_param.len = nw; - - if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx, - EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT, - sizeof(mb_param), &mb_param) <= 0) - return -1; - - s->s3->write_sequence[7] += mb_param.interleave; - if (s->s3->write_sequence[7] < mb_param.interleave) { - int j = 6; - while (j >= 0 && (++s->s3->write_sequence[j--]) == 0) ; - } - - wb->offset = 0; - wb->left = packlen; - - s->s3->wpend_tot = nw; - s->s3->wpend_buf = &buf[tot]; - s->s3->wpend_type = type; - s->s3->wpend_ret = nw; - - i = ssl3_write_pending(s, type, &buf[tot], nw); - if (i <= 0) { - if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) { - OPENSSL_free(wb->buf); - wb->buf = NULL; - } - s->s3->wnum = tot; - return i; - } - if (i == (int)n) { - OPENSSL_free(wb->buf); /* free jumbo buffer */ - wb->buf = NULL; - return tot + i; - } - n -= i; - tot += i; - } - } else -#endif - if (tot == len) { /* done? */ - if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s)) - ssl3_release_write_buffer(s); - - return tot; - } - - n = (len - tot); - for (;;) { - if (n > s->max_send_fragment) - nw = s->max_send_fragment; - else - nw = n; - - i = do_ssl3_write(s, type, &(buf[tot]), nw, 0); - if (i <= 0) { - /* XXX should we ssl3_release_write_buffer if i<0? */ - s->s3->wnum = tot; - return i; - } - - if ((i == (int)n) || - (type == SSL3_RT_APPLICATION_DATA && - (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { - /* - * next chunk of data should get another prepended empty fragment - * in ciphersuites with known-IV weakness: - */ - s->s3->empty_fragment_done = 0; - - if ((i == (int)n) && s->mode & SSL_MODE_RELEASE_BUFFERS && - !SSL_IS_DTLS(s)) - ssl3_release_write_buffer(s); - - return tot + i; - } - - n -= i; - tot += i; - } -} - -static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragment) -{ - unsigned char *p, *plen; - int i, mac_size, clear = 0; - int prefix_len = 0; - int eivlen; - long align = 0; - SSL3_RECORD *wr; - SSL3_BUFFER *wb = &(s->s3->wbuf); - SSL_SESSION *sess; - - /* - * first check if there is a SSL3_BUFFER still being written out. This - * will happen with non blocking IO - */ - if (wb->left != 0) - return (ssl3_write_pending(s, type, buf, len)); - - /* If we have an alert to send, lets send it */ - if (s->s3->alert_dispatch) { - i = s->method->ssl_dispatch_alert(s); - if (i <= 0) - return (i); - /* if it went, fall through and send more stuff */ - } - - if (wb->buf == NULL) - if (!ssl3_setup_write_buffer(s)) - return -1; - - if (len == 0 && !create_empty_fragment) - return 0; - - wr = &(s->s3->wrec); - sess = s->session; - - if ((sess == NULL) || - (s->enc_write_ctx == NULL) || - (EVP_MD_CTX_md(s->write_hash) == NULL)) { -#if 1 - clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ -#else - clear = 1; -#endif - mac_size = 0; - } else { - mac_size = EVP_MD_CTX_size(s->write_hash); - if (mac_size < 0) - goto err; - } - - /* - * 'create_empty_fragment' is true only when this function calls itself - */ - if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) { - /* - * countermeasure against known-IV weakness in CBC ciphersuites (see - * http://www.openssl.org/~bodo/tls-cbc.txt) - */ - - if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { - /* - * recursive function call with 'create_empty_fragment' set; this - * prepares and buffers the data for an empty fragment (these - * 'prefix_len' bytes are sent out later together with the actual - * payload) - */ - prefix_len = do_ssl3_write(s, type, buf, 0, 1); - if (prefix_len <= 0) - goto err; - - if (prefix_len > - (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) - { - /* insufficient space */ - SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); - goto err; - } - } - - s->s3->empty_fragment_done = 1; - } - - if (create_empty_fragment) { -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - /* - * extra fragment would be couple of cipher blocks, which would be - * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real - * payload, then we can just pretent we simply have two headers. - */ - align = (long)wb->buf + 2 * SSL3_RT_HEADER_LENGTH; - align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - p = wb->buf + align; - wb->offset = align; - } else if (prefix_len) { - p = wb->buf + wb->offset + prefix_len; - } else { -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 - align = (long)wb->buf + SSL3_RT_HEADER_LENGTH; - align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); -#endif - p = wb->buf + align; - wb->offset = align; - } - - /* write the header */ - - *(p++) = type & 0xff; - wr->type = type; - - *(p++) = (s->version >> 8); - /* - * Some servers hang if iniatial client hello is larger than 256 bytes - * and record version number > TLS 1.0 - */ - if (s->state == SSL3_ST_CW_CLNT_HELLO_B - && !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION) - *(p++) = 0x1; - else - *(p++) = s->version & 0xff; - - /* field where we are to write out packet length */ - plen = p; - p += 2; - /* Explicit IV length, block ciphers appropriate version flag */ - if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) { - int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); - if (mode == EVP_CIPH_CBC_MODE) { - eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); - if (eivlen <= 1) - eivlen = 0; - } - /* Need explicit part of IV for GCM mode */ - else if (mode == EVP_CIPH_GCM_MODE) - eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; - else - eivlen = 0; - } else - eivlen = 0; - - /* lets setup the record stuff. */ - wr->data = p + eivlen; - wr->length = (int)len; - wr->input = (unsigned char *)buf; - - /* - * we now 'read' from wr->input, wr->length bytes into wr->data - */ - - /* first we compress */ - if (s->compress != NULL) { - if (!ssl3_do_compress(s)) { - SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE); - goto err; - } - } else { - memcpy(wr->data, wr->input, wr->length); - wr->input = wr->data; - } - - /* - * we should still have the output to wr->data and the input from - * wr->input. Length should be wr->length. wr->data still points in the - * wb->buf - */ - - if (mac_size != 0) { - if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0) - goto err; - wr->length += mac_size; - } - - wr->input = p; - wr->data = p; - - if (eivlen) { - /* - * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err; - */ - wr->length += eivlen; - } - - if (s->method->ssl3_enc->enc(s, 1) < 1) - goto err; - - /* record length after mac and block padding */ - s2n(wr->length, plen); - - if (s->msg_callback) - s->msg_callback(1, 0, SSL3_RT_HEADER, plen - 5, 5, s, - s->msg_callback_arg); - - /* - * we should now have wr->data pointing to the encrypted data, which is - * wr->length long - */ - wr->type = type; /* not needed but helps for debugging */ - wr->length += SSL3_RT_HEADER_LENGTH; - - if (create_empty_fragment) { - /* - * we are in a recursive call; just return the length, don't write - * out anything here - */ - return wr->length; - } - - /* now let's set up wb */ - wb->left = prefix_len + wr->length; - - /* - * memorize arguments so that ssl3_write_pending can detect bad write - * retries later - */ - s->s3->wpend_tot = len; - s->s3->wpend_buf = buf; - s->s3->wpend_type = type; - s->s3->wpend_ret = len; - - /* we now just need to write the buffer */ - return ssl3_write_pending(s, type, buf, len); - err: - return -1; -} - -/* if s->s3->wbuf.left != 0, we need to call this - * - * Return values are as per SSL_write(), i.e. - */ -int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, - unsigned int len) -{ - int i; - SSL3_BUFFER *wb = &(s->s3->wbuf); - - if ((s->s3->wpend_tot > (int)len) - || (!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) - && (s->s3->wpend_buf != buf)) - || (s->s3->wpend_type != type)) { - SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); - return (-1); - } - - for (;;) { - clear_sys_error(); - if (s->wbio != NULL) { - s->rwstate = SSL_WRITING; - i = BIO_write(s->wbio, - (char *)&(wb->buf[wb->offset]), - (unsigned int)wb->left); - } else { - SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET); - i = -1; - } - if (i == wb->left) { - wb->left = 0; - wb->offset += i; - s->rwstate = SSL_NOTHING; - return (s->s3->wpend_ret); - } else if (i <= 0) { - if (SSL_IS_DTLS(s)) { - /* - * For DTLS, just drop it. That's kind of the whole point in - * using a datagram service - */ - wb->left = 0; - } - return i; - } - wb->offset += i; - wb->left -= i; - } -} - -/*- - * Return up to 'len' payload bytes received in 'type' records. - * 'type' is one of the following: - * - * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) - * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) - * - 0 (during a shutdown, no data has to be returned) - * - * If we don't have stored data to work from, read a SSL/TLS record first - * (possibly multiple records if we still don't have anything to return). - * - * This function must handle any surprises the peer may have for us, such as - * Alert records (e.g. close_notify), ChangeCipherSpec records (not really - * a surprise, but handled as if it were), or renegotiation requests. - * Also if record payloads contain fragments too small to process, we store - * them until there is enough for the respective protocol (the record protocol - * may use arbitrary fragmentation and even interleaving): - * Change cipher spec protocol - * just 1 byte needed, no need for keeping anything stored - * Alert protocol - * 2 bytes needed (AlertLevel, AlertDescription) - * Handshake protocol - * 4 bytes needed (HandshakeType, uint24 length) -- we just have - * to detect unexpected Client Hello and Hello Request messages - * here, anything else is handled by higher layers - * Application data protocol - * none of our business - */ -int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) -{ - int al, i, j, ret; - unsigned int n; - SSL3_RECORD *rr; - void (*cb) (const SSL *ssl, int type2, int val) = NULL; - - if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ - if (!ssl3_setup_read_buffer(s)) - return (-1); - - if ((type && (type != SSL3_RT_APPLICATION_DATA) - && (type != SSL3_RT_HANDSHAKE)) || (peek - && (type != - SSL3_RT_APPLICATION_DATA))) { - SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); - return -1; - } - - if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0)) - /* (partially) satisfy request from storage */ - { - unsigned char *src = s->s3->handshake_fragment; - unsigned char *dst = buf; - unsigned int k; - - /* peek == 0 */ - n = 0; - while ((len > 0) && (s->s3->handshake_fragment_len > 0)) { - *dst++ = *src++; - len--; - s->s3->handshake_fragment_len--; - n++; - } - /* move any remaining fragment bytes: */ - for (k = 0; k < s->s3->handshake_fragment_len; k++) - s->s3->handshake_fragment[k] = *src++; - return n; - } - - /* - * Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. - */ - - if (!s->in_handshake && SSL_in_init(s)) { - /* type == SSL3_RT_APPLICATION_DATA */ - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - } - start: - s->rwstate = SSL_NOTHING; - - /*- - * s->s3->rrec.type - is the type of record - * s->s3->rrec.data, - data - * s->s3->rrec.off, - offset into 'data' for next read - * s->s3->rrec.length, - number of bytes. - */ - rr = &(s->s3->rrec); - - /* get new packet if necessary */ - if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { - ret = ssl3_get_record(s); - if (ret <= 0) - return (ret); - } - - /* - * Reset the count of consecutive warning alerts if we've got a non-empty - * record that isn't an alert. - */ - if (rr->type != SSL3_RT_ALERT && rr->length != 0) - s->cert->alert_count = 0; - - /* we now have a packet which can be read and processed */ - - if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, - * reset by ssl3_get_finished */ - && (rr->type != SSL3_RT_HANDSHAKE)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); - goto f_err; - } - - /* - * If the other end has shut down, throw anything we read away (even in - * 'peek' mode) - */ - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - rr->length = 0; - s->rwstate = SSL_NOTHING; - return (0); - } - - if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or - * SSL3_RT_HANDSHAKE */ - /* - * make sure that we are not getting application data when we are - * doing a handshake for the first time - */ - if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && - (s->enc_read_ctx == NULL)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); - goto f_err; - } - - if (len <= 0) - return (len); - - if ((unsigned int)len > rr->length) - n = rr->length; - else - n = (unsigned int)len; - - memcpy(buf, &(rr->data[rr->off]), n); - if (!peek) { - rr->length -= n; - rr->off += n; - if (rr->length == 0) { - s->rstate = SSL_ST_READ_HEADER; - rr->off = 0; - if (s->mode & SSL_MODE_RELEASE_BUFFERS - && s->s3->rbuf.left == 0) - ssl3_release_read_buffer(s); - } - } - return (n); - } - - /* - * If we get here, then type != rr->type; if we have a handshake message, - * then it was unexpected (Hello Request or Client Hello). - */ - - /* - * In case of record types for which we have 'fragment' storage, fill - * that so that we can process the data at a fixed place. - */ - { - unsigned int dest_maxlen = 0; - unsigned char *dest = NULL; - unsigned int *dest_len = NULL; - - if (rr->type == SSL3_RT_HANDSHAKE) { - dest_maxlen = sizeof(s->s3->handshake_fragment); - dest = s->s3->handshake_fragment; - dest_len = &s->s3->handshake_fragment_len; - } else if (rr->type == SSL3_RT_ALERT) { - dest_maxlen = sizeof(s->s3->alert_fragment); - dest = s->s3->alert_fragment; - dest_len = &s->s3->alert_fragment_len; - } -#ifndef OPENSSL_NO_HEARTBEATS - else if (rr->type == TLS1_RT_HEARTBEAT) { - i = tls1_process_heartbeat(s); - - if (i < 0) - return i; - - rr->length = 0; - if (s->mode & SSL_MODE_AUTO_RETRY) - goto start; - - /* Exit and notify application to read again */ - s->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - return (-1); - } -#endif - - if (dest_maxlen > 0) { - n = dest_maxlen - *dest_len; /* available space in 'dest' */ - if (rr->length < n) - n = rr->length; /* available bytes */ - - /* now move 'n' bytes: */ - while (n-- > 0) { - dest[(*dest_len)++] = rr->data[rr->off++]; - rr->length--; - } - - if (*dest_len < dest_maxlen) - goto start; /* fragment was too small */ - } - } - - /*- - * s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; - * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. - * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) - */ - - /* If we are a client, check for an incoming 'Hello Request': */ - if ((!s->server) && - (s->s3->handshake_fragment_len >= 4) && - (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && - (s->session != NULL) && (s->session->cipher != NULL)) { - s->s3->handshake_fragment_len = 0; - - if ((s->s3->handshake_fragment[1] != 0) || - (s->s3->handshake_fragment[2] != 0) || - (s->s3->handshake_fragment[3] != 0)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); - goto f_err; - } - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - s->s3->handshake_fragment, 4, s, - s->msg_callback_arg); - - if (SSL_is_init_finished(s) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && - !s->s3->renegotiate) { - ssl3_renegotiate(s); - if (ssl3_renegotiate_check(s)) { - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL3_READ_BYTES, - SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ - BIO *bio; - /* - * In the case where we try to read application data, - * but we trigger an SSL handshake, we return -1 with - * the retry option set. Otherwise renegotiation may - * cause nasty problems in the blocking world - */ - s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - } - } - } - /* - * we either finished a handshake or ignored the request, now try - * again to obtain the (application) data we were asked for - */ - goto start; - } - - /* - * If we are a server and get a client hello when renegotiation isn't - * allowed send back a no renegotiation alert and carry on. - */ - if (s->server - && SSL_is_init_finished(s) - && !s->s3->send_connection_binding - && s->version > SSL3_VERSION - && s->s3->handshake_fragment_len >= SSL3_HM_HEADER_LENGTH - && s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO - && s->s3->previous_client_finished_len != 0 - && (s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) == 0) { - s->s3->handshake_fragment_len = 0; - rr->length = 0; - ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); - goto start; - } - - if (s->s3->alert_fragment_len >= 2) { - int alert_level = s->s3->alert_fragment[0]; - int alert_descr = s->s3->alert_fragment[1]; - - s->s3->alert_fragment_len = 0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_ALERT, - s->s3->alert_fragment, 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (alert_level << 8) | alert_descr; - cb(s, SSL_CB_READ_ALERT, j); - } - - if (alert_level == SSL3_AL_WARNING) { - s->s3->warn_alert = alert_descr; - - s->cert->alert_count++; - if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); - goto f_err; - } - - if (alert_descr == SSL_AD_CLOSE_NOTIFY) { - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - return (0); - } - /* - * This is a warning but we receive it if we requested - * renegotiation and the peer denied it. Terminate with a fatal - * alert because if application tried to renegotiatie it - * presumably had a good reason and expects it to succeed. In - * future we might have a renegotiation where we don't care if - * the peer refused it where we carry on. - */ - else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION); - goto f_err; - } -#ifdef SSL_AD_MISSING_SRP_USERNAME - else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME) - return (0); -#endif - } else if (alert_level == SSL3_AL_FATAL) { - char tmp[16]; - - s->rwstate = SSL_NOTHING; - s->s3->fatal_alert = alert_descr; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); - BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr); - ERR_add_error_data(2, "SSL alert number ", tmp); - s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->session_ctx, s->session); - return (0); - } else { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); - goto f_err; - } - - goto start; - } - - if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a - * shutdown */ - s->rwstate = SSL_NOTHING; - rr->length = 0; - return (0); - } - - if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { - /* - * 'Change Cipher Spec' is just a single byte, so we know exactly - * what the record payload has to look like - */ - if ((rr->length != 1) || (rr->off != 0) || - (rr->data[0] != SSL3_MT_CCS)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto f_err; - } - - /* Check we have a cipher to change to */ - if (s->s3->tmp.new_cipher == NULL) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); - goto f_err; - } - - if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); - goto f_err; - } - - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; - - rr->length = 0; - - if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - rr->data, 1, s, s->msg_callback_arg); - - s->s3->change_cipher_spec = 1; - if (!ssl3_do_change_cipher_spec(s)) - goto err; - else - goto start; - } - - /* - * Unexpected handshake message (Client Hello, or protocol violation) - */ - if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) { - if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && - !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { -#if 0 /* worked only because C operator preferences - * are not as expected (and because this is - * not really needed for clients except for - * detecting protocol violations): */ - s->state = SSL_ST_BEFORE | (s->server) - ? SSL_ST_ACCEPT : SSL_ST_CONNECT; -#else - s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; -#endif - s->renegotiate = 1; - s->new_session = 1; - } - i = s->handshake_func(s); - if (i < 0) - return (i); - if (i == 0) { - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); - return (-1); - } - - if (!(s->mode & SSL_MODE_AUTO_RETRY)) { - if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ - BIO *bio; - /* - * In the case where we try to read application data, but we - * trigger an SSL handshake, we return -1 with the retry - * option set. Otherwise renegotiation may cause nasty - * problems in the blocking world - */ - s->rwstate = SSL_READING; - bio = SSL_get_rbio(s); - BIO_clear_retry_flags(bio); - BIO_set_retry_read(bio); - return (-1); - } - } - goto start; - } - - switch (rr->type) { - default: - /* - * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but - * TLS 1.2 says you MUST send an unexpected message alert. We use the - * TLS 1.2 behaviour for all protocol versions to prevent issues where - * no progress is being made and the peer continually sends unrecognised - * record types, using up resources processing them. - */ - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - case SSL3_RT_CHANGE_CIPHER_SPEC: - case SSL3_RT_ALERT: - case SSL3_RT_HANDSHAKE: - /* - * we already handled all of these, with the possible exception of - * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not - * happen when type != rr->type - */ - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); - goto f_err; - case SSL3_RT_APPLICATION_DATA: - /* - * At this point, we were expecting handshake data, but have - * application data. If the library was running inside ssl3_read() - * (i.e. in_read_app_data is set) and it makes sense to read - * application data at this point (session renegotiation not yet - * started), we will indulge it. - */ - if (s->s3->in_read_app_data && - (s->s3->total_renegotiations != 0) && - (((s->state & SSL_ST_CONNECT) && - (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && - (s->state <= SSL3_ST_CR_SRVR_HELLO_A) - ) || ((s->state & SSL_ST_ACCEPT) && - (s->state <= SSL3_ST_SW_HELLO_REQ_A) && - (s->state >= SSL3_ST_SR_CLNT_HELLO_A) - ) - )) { - s->s3->in_read_app_data = 2; - return (-1); - } else { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); - goto f_err; - } - } - /* not reached */ - - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - return (-1); -} - -int ssl3_do_change_cipher_spec(SSL *s) -{ - int i; - const char *sender; - int slen; - - if (s->state & SSL_ST_ACCEPT) - i = SSL3_CHANGE_CIPHER_SERVER_READ; - else - i = SSL3_CHANGE_CIPHER_CLIENT_READ; - - if (s->s3->tmp.key_block == NULL) { - if (s->session == NULL || s->session->master_key_length == 0) { - /* might happen if dtls1_read_bytes() calls this */ - SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, - SSL_R_CCS_RECEIVED_EARLY); - return (0); - } - - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->method->ssl3_enc->setup_key_block(s)) - return (0); - } - - if (!s->method->ssl3_enc->change_cipher_state(s, i)) - return (0); - - /* - * we have to record the message digest at this point so we can get it - * before we read the finished message - */ - if (s->state & SSL_ST_CONNECT) { - sender = s->method->ssl3_enc->server_finished_label; - slen = s->method->ssl3_enc->server_finished_label_len; - } else { - sender = s->method->ssl3_enc->client_finished_label; - slen = s->method->ssl3_enc->client_finished_label_len; - } - - i = s->method->ssl3_enc->final_finish_mac(s, - sender, slen, - s->s3->tmp.peer_finish_md); - if (i == 0) { - SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); - return 0; - } - s->s3->tmp.peer_finish_md_len = i; - - return (1); -} - -int ssl3_send_alert(SSL *s, int level, int desc) -{ - /* Map tls/ssl alert value to correct one */ - desc = s->method->ssl3_enc->alert_value(desc); - if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) - desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have - * protocol_version alerts */ - if (desc < 0) - return -1; - /* If a fatal one, remove from cache */ - if ((level == 2) && (s->session != NULL)) - SSL_CTX_remove_session(s->session_ctx, s->session); - - s->s3->alert_dispatch = 1; - s->s3->send_alert[0] = level; - s->s3->send_alert[1] = desc; - if (s->s3->wbuf.left == 0) /* data still being written out? */ - return s->method->ssl_dispatch_alert(s); - /* - * else data is still being written out, we will get written some time in - * the future - */ - return -1; -} - -int ssl3_dispatch_alert(SSL *s) -{ - int i, j; - void (*cb) (const SSL *ssl, int type, int val) = NULL; - - s->s3->alert_dispatch = 0; - i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0); - if (i <= 0) { - s->s3->alert_dispatch = 1; - } else { - /* - * Alert sent to BIO. If it is important, flush it now. If the - * message does not get sent due to non-blocking IO, we will not - * worry too much. - */ - if (s->s3->send_alert[0] == SSL3_AL_FATAL) - (void)BIO_flush(s->wbio); - - if (s->msg_callback) - s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, - 2, s, s->msg_callback_arg); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - if (cb != NULL) { - j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; - cb(s, SSL_CB_WRITE_ALERT, j); - } - } - return (i); -} -/* ssl/s3_srvr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * ECC cipher suite support in OpenSSL originally written by - * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#define REUSE_CIPHER_BUG -#define NETSCAPE_HANG_BUG - -#include -// #include "ssl_locl.h" -// #include "kssl_lcl.h" -// #include "constant_time_locl.h" -// #include "buffer.h" -// #include "rand.h" -// #include "objects.h" -// #include "evp.h" -#include "hmac.h" -// #include "x509.h" -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -// #include "bn.h" -#ifndef OPENSSL_NO_KRB5 -# include "krb5_asn.h" -#endif -// #include "md5.h" - -#ifndef OPENSSL_NO_SSL3_METHOD -static const SSL_METHOD *ssl3_get_server_method(int ver); - -static const SSL_METHOD *ssl3_get_server_method(int ver) -{ - if (ver == SSL3_VERSION) - return (SSLv3_server_method()); - else - return (NULL); -} - -IMPLEMENT_ssl3_meth_func(SSLv3_server_method, - ssl3_accept, - ssl_undefined_function, ssl3_get_server_method) -#endif -#ifndef OPENSSL_NO_SRP -static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) -{ - int ret = SSL_ERROR_NONE; - - *al = SSL_AD_UNRECOGNIZED_NAME; - - if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) && - (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) { - if (s->srp_ctx.login == NULL) { - /* - * RFC 5054 says SHOULD reject, we do so if There is no srp - * login name - */ - ret = SSL3_AL_FATAL; - *al = SSL_AD_UNKNOWN_PSK_IDENTITY; - } else { - ret = SSL_srp_server_param_with_username(s, al); - } - } - return ret; -} -#endif - -int ssl3_accept(SSL *s) -{ - BUF_MEM *buf; - unsigned long alg_k, Time = (unsigned long)time(NULL); - void (*cb) (const SSL *ssl, int type, int val) = NULL; - int ret = -1; - int new_state, state, skip = 0; - - RAND_add(&Time, sizeof(Time), 0); - ERR_clear_error(); - clear_sys_error(); - - if (s->info_callback != NULL) - cb = s->info_callback; - else if (s->ctx->info_callback != NULL) - cb = s->ctx->info_callback; - - /* init things to blank */ - s->in_handshake++; - if (!SSL_in_init(s) || SSL_in_before(s)) - SSL_clear(s); - - if (s->cert == NULL) { - SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_NO_CERTIFICATE_SET); - return (-1); - } -#ifndef OPENSSL_NO_HEARTBEATS - /* - * If we're awaiting a HeartbeatResponse, pretend we already got and - * don't await it anymore, because Heartbeats don't make sense during - * handshakes anyway. - */ - if (s->tlsext_hb_pending) { - s->tlsext_hb_pending = 0; - s->tlsext_hb_seq++; - } -#endif - - for (;;) { - state = s->state; - - switch (s->state) { - case SSL_ST_RENEGOTIATE: - s->renegotiate = 1; - /* s->state=SSL_ST_ACCEPT; */ - - case SSL_ST_BEFORE: - case SSL_ST_ACCEPT: - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - case SSL_ST_OK | SSL_ST_ACCEPT: - - s->server = 1; - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_START, 1); - - if ((s->version >> 8) != 3) { - SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } - s->type = SSL_ST_ACCEPT; - - if (s->init_buf == NULL) { - if ((buf = BUF_MEM_new()) == NULL) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { - BUF_MEM_free(buf); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - s->init_buf = buf; - } - - if (!ssl3_setup_buffers(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->init_num = 0; - s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY; - s->s3->flags &= ~SSL3_FLAGS_CCS_OK; - /* - * Should have been reset by ssl3_get_finished, too. - */ - s->s3->change_cipher_spec = 0; - - if (s->state != SSL_ST_RENEGOTIATE) { - /* - * Ok, we now need to push on a buffering BIO so that the - * output is sent in a way that TCP likes :-) - */ - if (!ssl_init_wbio_buffer(s, 1)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - s->state = SSL3_ST_SR_CLNT_HELLO_A; - s->ctx->stats.sess_accept++; - } else if (!s->s3->send_connection_binding && - !(s->options & - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - /* - * Server attempting to renegotiate with client that doesn't - * support secure renegotiation. - */ - SSLerr(SSL_F_SSL3_ACCEPT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } else { - /* - * s->state == SSL_ST_RENEGOTIATE, we will just send a - * HelloRequest - */ - s->ctx->stats.sess_accept_renegotiate++; - s->state = SSL3_ST_SW_HELLO_REQ_A; - } - break; - - case SSL3_ST_SW_HELLO_REQ_A: - case SSL3_ST_SW_HELLO_REQ_B: - - s->shutdown = 0; - ret = ssl3_send_hello_request(s); - if (ret <= 0) - goto end; - s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - - if (!ssl3_init_finished_mac(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - break; - - case SSL3_ST_SW_HELLO_REQ_C: - s->state = SSL_ST_OK; - break; - - case SSL3_ST_SR_CLNT_HELLO_A: - case SSL3_ST_SR_CLNT_HELLO_B: - case SSL3_ST_SR_CLNT_HELLO_C: - - s->shutdown = 0; - ret = ssl3_get_client_hello(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_SRP - s->state = SSL3_ST_SR_CLNT_HELLO_D; - case SSL3_ST_SR_CLNT_HELLO_D: - { - int al; - if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) { - /* - * callback indicates firther work to be done - */ - s->rwstate = SSL_X509_LOOKUP; - goto end; - } - if (ret != SSL_ERROR_NONE) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - /* - * This is not really an error but the only means to for - * a client to detect whether srp is supported. - */ - if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY) - SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT); - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - } -#endif - - s->renegotiate = 2; - s->state = SSL3_ST_SW_SRVR_HELLO_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_SRVR_HELLO_A: - case SSL3_ST_SW_SRVR_HELLO_B: - ret = ssl3_send_server_hello(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->hit) { - if (s->tlsext_ticket_expected) - s->state = SSL3_ST_SW_SESSION_TICKET_A; - else - s->state = SSL3_ST_SW_CHANGE_A; - } -#else - if (s->hit) - s->state = SSL3_ST_SW_CHANGE_A; -#endif - else - s->state = SSL3_ST_SW_CERT_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_A: - case SSL3_ST_SW_CERT_B: - /* Check if it is anon DH or anon ECDH, */ - /* normal PSK or KRB5 or SRP */ - if (! - (s->s3->tmp. - new_cipher->algorithm_auth & (SSL_aNULL | SSL_aKRB5 | - SSL_aSRP)) -&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - ret = ssl3_send_server_certificate(s); - if (ret <= 0) - goto end; -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_status_expected) - s->state = SSL3_ST_SW_CERT_STATUS_A; - else - s->state = SSL3_ST_SW_KEY_EXCH_A; - } else { - skip = 1; - s->state = SSL3_ST_SW_KEY_EXCH_A; - } -#else - } else - skip = 1; - - s->state = SSL3_ST_SW_KEY_EXCH_A; -#endif - s->init_num = 0; - break; - - case SSL3_ST_SW_KEY_EXCH_A: - case SSL3_ST_SW_KEY_EXCH_B: - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - - /* - * clear this, it may get reset by - * send_server_key_exchange - */ - s->s3->tmp.use_rsa_tmp = 0; - - /* - * only send if a DH key exchange, fortezza or RSA but we have a - * sign only certificate PSK: may send PSK identity hints For - * ECC ciphersuites, we send a serverKeyExchange message only if - * the cipher suite is either ECDH-anon or ECDHE. In other cases, - * the server certificate contains the server's public key for - * key exchange. - */ - if (0 - /* - * PSK: send ServerKeyExchange if PSK identity hint if - * provided - */ -#ifndef OPENSSL_NO_PSK - || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) -#endif -#ifndef OPENSSL_NO_SRP - /* SRP: send ServerKeyExchange */ - || (alg_k & SSL_kSRP) -#endif - || (alg_k & SSL_kEDH) - || (alg_k & SSL_kEECDH) - || ((alg_k & SSL_kRSA) - && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL - || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) - && EVP_PKEY_size(s->cert->pkeys - [SSL_PKEY_RSA_ENC].privatekey) * - 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) - ) - ) - ) - ) { - ret = ssl3_send_server_key_exchange(s); - if (ret <= 0) - goto end; - } else - skip = 1; - - s->state = SSL3_ST_SW_CERT_REQ_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_REQ_A: - case SSL3_ST_SW_CERT_REQ_B: - if ( /* don't request cert unless asked for it: */ - !(s->verify_mode & SSL_VERIFY_PEER) || - /* - * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert - * during re-negotiation: - */ - (s->s3->tmp.finish_md_len != 0 && - (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || - /* - * never request cert in anonymous ciphersuites (see - * section "Certificate request" in SSL 3 drafts and in - * RFC 2246): - */ - ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && - /* - * ... except when the application insists on - * verification (against the specs, but s3_clnt.c accepts - * this for SSL 3) - */ - !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || - /* - * never request cert in Kerberos ciphersuites - */ - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) || - /* don't request certificate for SRP auth */ - (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP) - /* - * With normal PSK Certificates and Certificate Requests - * are omitted - */ - || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - /* no cert request */ - skip = 1; - s->s3->tmp.cert_request = 0; - s->state = SSL3_ST_SW_SRVR_DONE_A; - if (s->s3->handshake_buffer) { - if (!ssl3_digest_cached_records(s)) { - s->state = SSL_ST_ERR; - return -1; - } - } - } else { - s->s3->tmp.cert_request = 1; - ret = ssl3_send_certificate_request(s); - if (ret <= 0) - goto end; -#ifndef NETSCAPE_HANG_BUG - s->state = SSL3_ST_SW_SRVR_DONE_A; -#else - s->state = SSL3_ST_SW_FLUSH; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; -#endif - s->init_num = 0; - } - break; - - case SSL3_ST_SW_SRVR_DONE_A: - case SSL3_ST_SW_SRVR_DONE_B: - ret = ssl3_send_server_done(s); - if (ret <= 0) - goto end; - s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; - s->state = SSL3_ST_SW_FLUSH; - s->init_num = 0; - break; - - case SSL3_ST_SW_FLUSH: - - /* - * This code originally checked to see if any data was pending - * using BIO_CTRL_INFO and then flushed. This caused problems as - * documented in PR#1939. The proposed fix doesn't completely - * resolve this issue as buggy implementations of - * BIO_CTRL_PENDING still exist. So instead we just flush - * unconditionally. - */ - - s->rwstate = SSL_WRITING; - if (BIO_flush(s->wbio) <= 0) { - ret = -1; - goto end; - } - s->rwstate = SSL_NOTHING; - - s->state = s->s3->tmp.next_state; - break; - - case SSL3_ST_SR_CERT_A: - case SSL3_ST_SR_CERT_B: - if (s->s3->tmp.cert_request) { - ret = ssl3_get_client_certificate(s); - if (ret <= 0) - goto end; - } - s->init_num = 0; - s->state = SSL3_ST_SR_KEY_EXCH_A; - break; - - case SSL3_ST_SR_KEY_EXCH_A: - case SSL3_ST_SR_KEY_EXCH_B: - ret = ssl3_get_client_key_exchange(s); - if (ret <= 0) - goto end; - if (ret == 2) { - /* - * For the ECDH ciphersuites when the client sends its ECDH - * pub key in a certificate, the CertificateVerify message is - * not sent. Also for GOST ciphersuites when the client uses - * its key from the certificate for key exchange. - */ -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) - s->state = SSL3_ST_SR_NEXT_PROTO_A; - else - s->state = SSL3_ST_SR_FINISHED_A; -#endif - s->init_num = 0; - } else if (SSL_USE_SIGALGS(s)) { - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - if (!s->session->peer) - break; - /* - * For sigalgs freeze the handshake buffer at this point and - * digest cached records. - */ - if (!s->s3->handshake_buffer) { - SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } - s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; - if (!ssl3_digest_cached_records(s)) { - s->state = SSL_ST_ERR; - return -1; - } - } else { - int offset = 0; - int dgst_num; - - s->state = SSL3_ST_SR_CERT_VRFY_A; - s->init_num = 0; - - /* - * We need to get hashes here so if there is a client cert, - * it can be verified FIXME - digest processing for - * CertificateVerify should be generalized. But it is next - * step - */ - if (s->s3->handshake_buffer) { - if (!ssl3_digest_cached_records(s)) { - s->state = SSL_ST_ERR; - return -1; - } - } - for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) - if (s->s3->handshake_dgst[dgst_num]) { - int dgst_size; - - s->method->ssl3_enc->cert_verify_mac(s, - EVP_MD_CTX_type - (s-> - s3->handshake_dgst - [dgst_num]), - &(s->s3-> - tmp.cert_verify_md - [offset])); - dgst_size = - EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); - if (dgst_size < 0) { - s->state = SSL_ST_ERR; - ret = -1; - goto end; - } - offset += dgst_size; - } - } - break; - - case SSL3_ST_SR_CERT_VRFY_A: - case SSL3_ST_SR_CERT_VRFY_B: - ret = ssl3_get_cert_verify(s); - if (ret <= 0) - goto end; - -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) - s->state = SSL3_ST_SR_NEXT_PROTO_A; - else - s->state = SSL3_ST_SR_FINISHED_A; -#endif - s->init_num = 0; - break; - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - case SSL3_ST_SR_NEXT_PROTO_A: - case SSL3_ST_SR_NEXT_PROTO_B: - /* - * Enable CCS for NPN. Receiving a CCS clears the flag, so make - * sure not to re-enable it to ban duplicates. This *should* be the - * first time we have received one - but we check anyway to be - * cautious. - * s->s3->change_cipher_spec is set when a CCS is - * processed in s3_pkt.c, and remains set until - * the client's Finished message is read. - */ - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; - - ret = ssl3_get_next_proto(s); - if (ret <= 0) - goto end; - s->init_num = 0; - s->state = SSL3_ST_SR_FINISHED_A; - break; -#endif - - case SSL3_ST_SR_FINISHED_A: - case SSL3_ST_SR_FINISHED_B: - /* - * Enable CCS for handshakes without NPN. In NPN the CCS flag has - * already been set. Receiving a CCS clears the flag, so make - * sure not to re-enable it to ban duplicates. - * s->s3->change_cipher_spec is set when a CCS is - * processed in s3_pkt.c, and remains set until - * the client's Finished message is read. - */ - if (!s->s3->change_cipher_spec) - s->s3->flags |= SSL3_FLAGS_CCS_OK; - ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, - SSL3_ST_SR_FINISHED_B); - if (ret <= 0) - goto end; - if (s->hit) - s->state = SSL_ST_OK; -#ifndef OPENSSL_NO_TLSEXT - else if (s->tlsext_ticket_expected) - s->state = SSL3_ST_SW_SESSION_TICKET_A; -#endif - else - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; - break; - -#ifndef OPENSSL_NO_TLSEXT - case SSL3_ST_SW_SESSION_TICKET_A: - case SSL3_ST_SW_SESSION_TICKET_B: - ret = ssl3_send_newsession_ticket(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_CHANGE_A; - s->init_num = 0; - break; - - case SSL3_ST_SW_CERT_STATUS_A: - case SSL3_ST_SW_CERT_STATUS_B: - ret = ssl3_send_cert_status(s); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_KEY_EXCH_A; - s->init_num = 0; - break; - -#endif - - case SSL3_ST_SW_CHANGE_A: - case SSL3_ST_SW_CHANGE_B: - - s->session->cipher = s->s3->tmp.new_cipher; - if (!s->method->ssl3_enc->setup_key_block(s)) { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - ret = ssl3_send_change_cipher_spec(s, - SSL3_ST_SW_CHANGE_A, - SSL3_ST_SW_CHANGE_B); - - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_FINISHED_A; - s->init_num = 0; - - if (!s->method->ssl3_enc->change_cipher_state(s, - SSL3_CHANGE_CIPHER_SERVER_WRITE)) - { - ret = -1; - s->state = SSL_ST_ERR; - goto end; - } - - break; - - case SSL3_ST_SW_FINISHED_A: - case SSL3_ST_SW_FINISHED_B: - ret = ssl3_send_finished(s, - SSL3_ST_SW_FINISHED_A, - SSL3_ST_SW_FINISHED_B, - s->method-> - ssl3_enc->server_finished_label, - s->method-> - ssl3_enc->server_finished_label_len); - if (ret <= 0) - goto end; - s->state = SSL3_ST_SW_FLUSH; - if (s->hit) { -#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; -#else - if (s->s3->next_proto_neg_seen) { - s->s3->tmp.next_state = SSL3_ST_SR_NEXT_PROTO_A; - } else - s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; -#endif - } else - s->s3->tmp.next_state = SSL_ST_OK; - s->init_num = 0; - break; - - case SSL_ST_OK: - /* clean a few things up */ - ssl3_cleanup_key_block(s); - - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - - /* remove buffering on output */ - ssl_free_wbio_buffer(s); - - s->init_num = 0; - - if (s->renegotiate == 2) { /* skipped if we just sent a - * HelloRequest */ - s->renegotiate = 0; - s->new_session = 0; - - ssl_update_cache(s, SSL_SESS_CACHE_SERVER); - - s->ctx->stats.sess_accept_good++; - /* s->server=1; */ - s->handshake_func = ssl3_accept; - - if (cb != NULL) - cb(s, SSL_CB_HANDSHAKE_DONE, 1); - } - - ret = 1; - goto end; - /* break; */ - - case SSL_ST_ERR: - default: - SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE); - ret = -1; - goto end; - /* break; */ - } - - if (!s->s3->tmp.reuse_message && !skip) { - if (s->debug) { - if ((ret = BIO_flush(s->wbio)) <= 0) - goto end; - } - - if ((cb != NULL) && (s->state != state)) { - new_state = s->state; - s->state = state; - cb(s, SSL_CB_ACCEPT_LOOP, 1); - s->state = new_state; - } - } - skip = 0; - } - end: - /* BIO_flush(s->wbio); */ - - s->in_handshake--; - if (cb != NULL) - cb(s, SSL_CB_ACCEPT_EXIT, ret); - return (ret); -} - -int ssl3_send_hello_request(SSL *s) -{ - - if (s->state == SSL3_ST_SW_HELLO_REQ_A) { - ssl_set_handshake_header(s, SSL3_MT_HELLO_REQUEST, 0); - s->state = SSL3_ST_SW_HELLO_REQ_B; - } - - /* SSL3_ST_SW_HELLO_REQ_B */ - return ssl_do_write(s); -} - -int ssl3_get_client_hello(SSL *s) -{ - int i, j, ok, al = SSL_AD_INTERNAL_ERROR, ret = -1, cookie_valid = 0; - unsigned int cookie_len; - long n; - unsigned long id; - unsigned char *p, *d; - SSL_CIPHER *c; -#ifndef OPENSSL_NO_COMP - unsigned char *q; - SSL_COMP *comp = NULL; -#endif - STACK_OF(SSL_CIPHER) *ciphers = NULL; - - if (s->state == SSL3_ST_SR_CLNT_HELLO_C && !s->first_packet) - goto retry_cert; - - /* - * We do this so that we will respond with our native type. If we are - * TLSv1 and we get SSLv3, we will respond with TLSv1, This down - * switching should be handled by a different method. If we are SSLv3, we - * will respond with SSLv3, even if prompted with TLSv1. - */ - if (s->state == SSL3_ST_SR_CLNT_HELLO_A) { - s->state = SSL3_ST_SR_CLNT_HELLO_B; - } - s->first_packet = 1; - n = s->method->ssl_get_message(s, - SSL3_ST_SR_CLNT_HELLO_B, - SSL3_ST_SR_CLNT_HELLO_C, - SSL3_MT_CLIENT_HELLO, - SSL3_RT_MAX_PLAIN_LENGTH, &ok); - - if (!ok) - return ((int)n); - s->first_packet = 0; - d = p = (unsigned char *)s->init_msg; - - /* - * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte - * for session id length - */ - if (n < 2 + SSL3_RANDOM_SIZE + 1) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - /* - * use version from inside client hello, not from record header (may - * differ: see RFC 2246, Appendix E, second paragraph) - */ - s->client_version = (((int)p[0]) << 8) | (int)p[1]; - p += 2; - - if (SSL_IS_DTLS(s) ? (s->client_version > s->version && - s->method->version != DTLS_ANY_VERSION) - : (s->client_version < s->version)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); - if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && - !s->enc_write_ctx && !s->write_hash) { - /* - * similar to ssl3_get_record, send alert using remote version - * number - */ - s->version = s->client_version; - } - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - - /* - * If we require cookies and this ClientHello doesn't contain one, just - * return since we do not want to allocate any memory yet. So check - * cookie length... - */ - if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { - unsigned int session_length, cookie_length; - - session_length = *(p + SSL3_RANDOM_SIZE); - - if (SSL3_RANDOM_SIZE + session_length + 1 - >= (unsigned int)((d + n) - p)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1); - - if (cookie_length == 0) - return 1; - } - - /* load the client random */ - memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /* get the session-id */ - j = *(p++); - - if ((d + n) - p < j) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - if ((j < 0) || (j > SSL_MAX_SSL_SESSION_ID_LENGTH)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - - s->hit = 0; - /* - * Versions before 0.9.7 always allow clients to resume sessions in - * renegotiation. 0.9.7 and later allow this by default, but optionally - * ignore resumption requests with flag - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather - * than a change to default behavior so that applications relying on this - * for security won't even compile against older library versions). - * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to - * request renegotiation but not a new session (s->new_session remains - * unset): for servers, this essentially just means that the - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored. - */ - if ((s->new_session - && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { - if (!ssl_get_new_session(s, 1)) - goto err; - } else { - i = ssl_get_prev_session(s, p, j, d + n); - /* - * Only resume if the session's version matches the negotiated - * version. - * RFC 5246 does not provide much useful advice on resumption - * with a different protocol version. It doesn't forbid it but - * the sanity of such behaviour would be questionable. - * In practice, clients do not accept a version mismatch and - * will abort the handshake with an error. - */ - if (i == 1 && s->version == s->session->ssl_version) { /* previous - * session */ - s->hit = 1; - } else if (i == -1) - goto err; - else { /* i == 0 */ - - if (!ssl_get_new_session(s, 1)) - goto err; - } - } - - p += j; - - if (SSL_IS_DTLS(s)) { - /* cookie stuff */ - if ((d + n) - p < 1) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - cookie_len = *(p++); - - if ((unsigned int)((d + n ) - p) < cookie_len) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - - /* - * The ClientHello may contain a cookie even if the - * HelloVerify message has not been sent--make sure that it - * does not cause an overflow. - */ - if (cookie_len > sizeof(s->d1->rcvd_cookie)) { - /* too much data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); - goto f_err; - } - - /* verify the cookie if appropriate option is set. */ - if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) { - memcpy(s->d1->rcvd_cookie, p, cookie_len); - - if (s->ctx->app_verify_cookie_cb != NULL) { - if (s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie, - cookie_len) == 0) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_COOKIE_MISMATCH); - goto f_err; - } - /* else cookie verification succeeded */ - } - /* default verification */ - else if (memcmp(s->d1->rcvd_cookie, s->d1->cookie, - s->d1->cookie_len) != 0) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); - goto f_err; - } - cookie_valid = 1; - } - - p += cookie_len; - if (s->method->version == DTLS_ANY_VERSION) { - /* Select version to use */ - if (s->client_version <= DTLS1_2_VERSION && - !(s->options & SSL_OP_NO_DTLSv1_2)) { - s->version = DTLS1_2_VERSION; - s->method = DTLSv1_2_server_method(); - } else if (tls1_suiteb(s)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - s->version = s->client_version; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } else if (s->client_version <= DTLS1_VERSION && - !(s->options & SSL_OP_NO_DTLSv1)) { - s->version = DTLS1_VERSION; - s->method = DTLSv1_server_method(); - } else { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_WRONG_VERSION_NUMBER); - s->version = s->client_version; - al = SSL_AD_PROTOCOL_VERSION; - goto f_err; - } - s->session->ssl_version = s->version; - } - } - - if ((d + n ) - p < 2) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); - goto f_err; - } - n2s(p, i); - - if (i == 0) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED); - goto f_err; - } - - /* i bytes of cipher data + 1 byte for compression length later */ - if ((d + n) - p < i + 1) { - /* not enough data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) { - goto err; - } - p += i; - - /* If it is a hit, check that the cipher is in the list */ - if (s->hit) { - j = 0; - id = s->session->cipher->id; - -#ifdef CIPHER_DEBUG - fprintf(stderr, "client sent %d ciphers\n", - sk_SSL_CIPHER_num(ciphers)); -#endif - for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { - c = sk_SSL_CIPHER_value(ciphers, i); -#ifdef CIPHER_DEBUG - fprintf(stderr, "client [%2d of %2d]:%s\n", - i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c)); -#endif - if (c->id == id) { - j = 1; - break; - } - } - /* - * Disabled because it can be used in a ciphersuite downgrade attack: - * CVE-2010-4180. - */ -#if 0 - if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) - && (sk_SSL_CIPHER_num(ciphers) == 1)) { - /* - * Special case as client bug workaround: the previously used - * cipher may not be in the current list, the client instead - * might be trying to continue using a cipher that before wasn't - * chosen due to server preferences. We'll have to reject the - * connection if the cipher is not enabled, though. - */ - c = sk_SSL_CIPHER_value(ciphers, 0); - if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) { - s->session->cipher = c; - j = 1; - } - } -#endif - if (j == 0) { - /* - * we need to have the cipher in the cipher list if we are asked - * to reuse it - */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_REQUIRED_CIPHER_MISSING); - goto f_err; - } - } - - /* compression */ - i = *(p++); - if ((d + n) - p < i) { - /* not enough data */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); - goto f_err; - } -#ifndef OPENSSL_NO_COMP - q = p; -#endif - for (j = 0; j < i; j++) { - if (p[j] == 0) - break; - } - - p += i; - if (j >= i) { - /* no compress */ - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED); - goto f_err; - } -#ifndef OPENSSL_NO_TLSEXT - /* TLS extensions */ - if (s->version >= SSL3_VERSION) { - if (!ssl_parse_clienthello_tlsext(s, &p, d + n)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); - goto err; - } - } - - /* - * Check if we want to use external pre-shared secret for this handshake - * for not reused session only. We need to generate server_random before - * calling tls_session_secret_cb in order to allow SessionTicket - * processing to use it in key derivation. - */ - { - unsigned char *pos; - pos = s->s3->server_random; - if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) { - goto f_err; - } - } - - if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) { - SSL_CIPHER *pref_cipher = NULL; - - s->session->master_key_length = sizeof(s->session->master_key); - if (s->tls_session_secret_cb(s, s->session->master_key, - &s->session->master_key_length, ciphers, - &pref_cipher, - s->tls_session_secret_cb_arg)) { - s->hit = 1; - s->session->ciphers = ciphers; - s->session->verify_result = X509_V_OK; - - ciphers = NULL; - - /* check if some cipher was preferred by call back */ - pref_cipher = - pref_cipher ? pref_cipher : ssl3_choose_cipher(s, - s-> - session->ciphers, - SSL_get_ciphers - (s)); - if (pref_cipher == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); - goto f_err; - } - - s->session->cipher = pref_cipher; - - if (s->cipher_list) - sk_SSL_CIPHER_free(s->cipher_list); - - if (s->cipher_list_by_id) - sk_SSL_CIPHER_free(s->cipher_list_by_id); - - s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); - s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); - } - } -#endif - - /* - * Worst case, we will use the NULL compression, but if we have other - * options, we will now look for them. We have i-1 compression - * algorithms from the client, starting at q. - */ - s->s3->tmp.new_compression = NULL; -#ifndef OPENSSL_NO_COMP - /* This only happens if we have a cache hit */ - if (s->session->compress_meth != 0) { - int m, comp_id = s->session->compress_meth; - /* Perform sanity checks on resumed compression algorithm */ - /* Can't disable compression */ - if (s->options & SSL_OP_NO_COMPRESSION) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_INCONSISTENT_COMPRESSION); - goto f_err; - } - /* Look for resumed compression method */ - for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); - if (comp_id == comp->id) { - s->s3->tmp.new_compression = comp; - break; - } - } - if (s->s3->tmp.new_compression == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_INVALID_COMPRESSION_ALGORITHM); - goto f_err; - } - /* Look for resumed method in compression list */ - for (m = 0; m < i; m++) { - if (q[m] == comp_id) - break; - } - if (m >= i) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, - SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING); - goto f_err; - } - } else if (s->hit) - comp = NULL; - else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) { - /* See if we have a match */ - int m, nn, o, v, done = 0; - - nn = sk_SSL_COMP_num(s->ctx->comp_methods); - for (m = 0; m < nn; m++) { - comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); - v = comp->id; - for (o = 0; o < i; o++) { - if (v == q[o]) { - done = 1; - break; - } - } - if (done) - break; - } - if (done) - s->s3->tmp.new_compression = comp; - else - comp = NULL; - } -#else - /* - * If compression is disabled we'd better not try to resume a session - * using compression. - */ - if (s->session->compress_meth != 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_INCONSISTENT_COMPRESSION); - goto f_err; - } -#endif - - /* - * Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher - */ - - if (!s->hit) { -#ifdef OPENSSL_NO_COMP - s->session->compress_meth = 0; -#else - s->session->compress_meth = (comp == NULL) ? 0 : comp->id; -#endif - if (s->session->ciphers != NULL) - sk_SSL_CIPHER_free(s->session->ciphers); - s->session->ciphers = ciphers; - if (ciphers == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); - goto f_err; - } - ciphers = NULL; - if (!tls1_set_server_sigalgs(s)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - goto err; - } - /* Let cert callback update server certificates if required */ - retry_cert: - if (s->cert->cert_cb) { - int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg); - if (rv == 0) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CERT_CB_ERROR); - goto f_err; - } - if (rv < 0) { - s->rwstate = SSL_X509_LOOKUP; - return -1; - } - s->rwstate = SSL_NOTHING; - } - c = ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); - - if (c == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); - goto f_err; - } - s->s3->tmp.new_cipher = c; - } else { - /* Session-id reuse */ -#ifdef REUSE_CIPHER_BUG - STACK_OF(SSL_CIPHER) *sk; - SSL_CIPHER *nc = NULL; - SSL_CIPHER *ec = NULL; - - if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) { - sk = s->session->ciphers; - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - c = sk_SSL_CIPHER_value(sk, i); - if (c->algorithm_enc & SSL_eNULL) - nc = c; - if (SSL_C_IS_EXPORT(c)) - ec = c; - } - if (nc != NULL) - s->s3->tmp.new_cipher = nc; - else if (ec != NULL) - s->s3->tmp.new_cipher = ec; - else - s->s3->tmp.new_cipher = s->session->cipher; - } else -#endif - s->s3->tmp.new_cipher = s->session->cipher; - } - - if (!SSL_USE_SIGALGS(s) || !(s->verify_mode & SSL_VERIFY_PEER)) { - if (!ssl3_digest_cached_records(s)) - goto f_err; - } - - /*- - * we now have the following setup. - * client_random - * cipher_list - our prefered list of ciphers - * ciphers - the clients prefered list of ciphers - * compression - basically ignored right now - * ssl version is set - sslv3 - * s->session - The ssl session has been setup. - * s->hit - session reuse flag - * s->tmp.new_cipher - the new cipher to use. - */ - - /* Handles TLS extensions that we couldn't check earlier */ - if (s->version >= SSL3_VERSION) { - if (!ssl_check_clienthello_tlsext_late(s, &al)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - goto f_err; - } - } - - ret = cookie_valid ? 2 : 1; - if (0) { - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - } - - if (ciphers != NULL) - sk_SSL_CIPHER_free(ciphers); - return ret; -} - -int ssl3_send_server_hello(SSL *s) -{ - unsigned char *buf; - unsigned char *p, *d; - int i, sl; - int al = 0; - unsigned long l; - - if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { - buf = (unsigned char *)s->init_buf->data; -#ifdef OPENSSL_NO_TLSEXT - p = s->s3->server_random; - if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) { - s->state = SSL_ST_ERR; - return -1; - } -#endif - /* Do the message type and length last */ - d = p = ssl_handshake_start(s); - - *(p++) = s->version >> 8; - *(p++) = s->version & 0xff; - - /* Random stuff */ - memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); - p += SSL3_RANDOM_SIZE; - - /*- - * There are several cases for the session ID to send - * back in the server hello: - * - For session reuse from the session cache, - * we send back the old session ID. - * - If stateless session reuse (using a session ticket) - * is successful, we send back the client's "session ID" - * (which doesn't actually identify the session). - * - If it is a new session, we send back the new - * session ID. - * - However, if we want the new session to be single-use, - * we send back a 0-length session ID. - * s->hit is non-zero in either case of session reuse, - * so the following won't overwrite an ID that we're supposed - * to send back. - */ - if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) - && !s->hit) - s->session->session_id_length = 0; - - sl = s->session->session_id_length; - if (sl > (int)sizeof(s->session->session_id)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } - *(p++) = sl; - memcpy(p, s->session->session_id, sl); - p += sl; - - /* put the cipher */ - i = ssl3_put_cipher_by_char(s->s3->tmp.new_cipher, p); - p += i; - - /* put the compression method */ -#ifdef OPENSSL_NO_COMP - *(p++) = 0; -#else - if (s->s3->tmp.new_compression == NULL) - *(p++) = 0; - else - *(p++) = s->s3->tmp.new_compression->id; -#endif -#ifndef OPENSSL_NO_TLSEXT - if (ssl_prepare_serverhello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); - s->state = SSL_ST_ERR; - return -1; - } - if ((p = - ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH, - &al)) == NULL) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return -1; - } -#endif - /* do the header */ - l = (p - d); - ssl_set_handshake_header(s, SSL3_MT_SERVER_HELLO, l); - s->state = SSL3_ST_SW_SRVR_HELLO_B; - } - - /* SSL3_ST_SW_SRVR_HELLO_B */ - return ssl_do_write(s); -} - -int ssl3_send_server_done(SSL *s) -{ - - if (s->state == SSL3_ST_SW_SRVR_DONE_A) { - ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0); - s->state = SSL3_ST_SW_SRVR_DONE_B; - } - - /* SSL3_ST_SW_SRVR_DONE_B */ - return ssl_do_write(s); -} - -int ssl3_send_server_key_exchange(SSL *s) -{ -#ifndef OPENSSL_NO_RSA - unsigned char *q; - int j, num; - RSA *rsa; - unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; - unsigned int u; -#endif -#ifndef OPENSSL_NO_DH -# ifdef OPENSSL_NO_RSA - int j; -# endif - DH *dh = NULL, *dhp; -#endif -#ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh = NULL, *ecdhp; - unsigned char *encodedPoint = NULL; - int encodedlen = 0; - int curve_id = 0; - BN_CTX *bn_ctx = NULL; -#endif - EVP_PKEY *pkey; - const EVP_MD *md = NULL; - unsigned char *p, *d; - int al, i; - unsigned long type; - int n; - CERT *cert; - BIGNUM *r[4]; - int nr[4], kn; - BUF_MEM *buf; - EVP_MD_CTX md_ctx; - - EVP_MD_CTX_init(&md_ctx); - if (s->state == SSL3_ST_SW_KEY_EXCH_A) { - type = s->s3->tmp.new_cipher->algorithm_mkey; - cert = s->cert; - - buf = s->init_buf; - - r[0] = r[1] = r[2] = r[3] = NULL; - n = 0; -#ifndef OPENSSL_NO_RSA - if (type & SSL_kRSA) { - rsa = cert->rsa_tmp; - if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) { - rsa = s->cert->rsa_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s->s3-> - tmp.new_cipher)); - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_ERROR_GENERATING_TMP_RSA_KEY); - goto f_err; - } - RSA_up_ref(rsa); - cert->rsa_tmp = rsa; - } - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_TMP_RSA_KEY); - goto f_err; - } - r[0] = rsa->n; - r[1] = rsa->e; - s->s3->tmp.use_rsa_tmp = 1; - } else -#endif -#ifndef OPENSSL_NO_DH - if (type & SSL_kEDH) { - dhp = cert->dh_tmp; - if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) - dhp = s->cert->dh_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s->s3-> - tmp.new_cipher)); - if (dhp == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } - - if (s->s3->tmp.dh != NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - if ((dh = DHparams_dup(dhp)) == NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - - s->s3->tmp.dh = dh; - if (!DH_generate_key(dh)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); - goto err; - } - r[0] = dh->p; - r[1] = dh->g; - r[2] = dh->pub_key; - } else -#endif -#ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) { - const EC_GROUP *group; - - if (s->s3->tmp.ecdh != NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - - ecdhp = cert->ecdh_tmp; - if (s->cert->ecdh_tmp_auto) { - /* Get NID of appropriate shared curve */ - int nid = tls1_shared_curve(s, -2); - if (nid != NID_undef) - ecdhp = EC_KEY_new_by_curve_name(nid); - } else if ((ecdhp == NULL) && s->cert->ecdh_tmp_cb) { - ecdhp = s->cert->ecdh_tmp_cb(s, - SSL_C_IS_EXPORT(s->s3-> - tmp.new_cipher), - SSL_C_EXPORT_PKEYLENGTH(s-> - s3->tmp.new_cipher)); - } - if (ecdhp == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_TMP_ECDH_KEY); - goto f_err; - } - - /* Duplicate the ECDH structure. */ - if (s->cert->ecdh_tmp_auto) - ecdh = ecdhp; - else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - s->s3->tmp.ecdh = ecdh; - if ((EC_KEY_get0_public_key(ecdh) == NULL) || - (EC_KEY_get0_private_key(ecdh) == NULL) || - (s->options & SSL_OP_SINGLE_ECDH_USE)) { - if (!EC_KEY_generate_key(ecdh)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_ECDH_LIB); - goto err; - } - } - - if (((group = EC_KEY_get0_group(ecdh)) == NULL) || - (EC_KEY_get0_public_key(ecdh) == NULL) || - (EC_KEY_get0_private_key(ecdh) == NULL)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - (EC_GROUP_get_degree(group) > 163)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); - goto err; - } - - /* - * XXX: For now, we only support ephemeral ECDH keys over named - * (not generic) curves. For supported named curves, curve_id is - * non-zero. - */ - if ((curve_id = - tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group))) - == 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); - goto err; - } - - /* - * Encode the public key. First check the size of encoding and - * allocate memory accordingly. - */ - encodedlen = EC_POINT_point2oct(group, - EC_KEY_get0_public_key(ecdh), - POINT_CONVERSION_UNCOMPRESSED, - NULL, 0, NULL); - - encodedPoint = (unsigned char *) - OPENSSL_malloc(encodedlen * sizeof(unsigned char)); - bn_ctx = BN_CTX_new(); - if ((encodedPoint == NULL) || (bn_ctx == NULL)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - encodedlen = EC_POINT_point2oct(group, - EC_KEY_get0_public_key(ecdh), - POINT_CONVERSION_UNCOMPRESSED, - encodedPoint, encodedlen, bn_ctx); - - if (encodedlen == 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - BN_CTX_free(bn_ctx); - bn_ctx = NULL; - - /* - * XXX: For now, we only support named (not generic) curves in - * ECDH ephemeral key exchanges. In this situation, we need four - * additional bytes to encode the entire ServerECDHParams - * structure. - */ - n = 4 + encodedlen; - - /* - * We'll generate the serverKeyExchange message explicitly so we - * can set these to NULLs - */ - r[0] = NULL; - r[1] = NULL; - r[2] = NULL; - r[3] = NULL; - } else -#endif /* !OPENSSL_NO_ECDH */ -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) { - /* - * reserve size for record length and PSK identity hint - */ - n += 2 + strlen(s->ctx->psk_identity_hint); - } else -#endif /* !OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - if (type & SSL_kSRP) { - if ((s->srp_ctx.N == NULL) || - (s->srp_ctx.g == NULL) || - (s->srp_ctx.s == NULL) || (s->srp_ctx.B == NULL)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_MISSING_SRP_PARAM); - goto err; - } - r[0] = s->srp_ctx.N; - r[1] = s->srp_ctx.g; - r[2] = s->srp_ctx.s; - r[3] = s->srp_ctx.B; - } else -#endif - { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); - goto f_err; - } - for (i = 0; i < 4 && r[i] != NULL; i++) { - nr[i] = BN_num_bytes(r[i]); -#ifndef OPENSSL_NO_SRP - if ((i == 2) && (type & SSL_kSRP)) - n += 1 + nr[i]; - else -#endif -#ifndef OPENSSL_NO_DH - /* - * for interoperability with some versions of the Microsoft TLS - * stack, we need to zero pad the DHE pub key to the same length - * as the prime, so use the length of the prime here - */ - if ((i == 2) && (type & (SSL_kEDH))) - n += 2 + nr[0]; - else -#endif - n += 2 + nr[i]; - } - - if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) - && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { - if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md)) - == NULL) { - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - kn = EVP_PKEY_size(pkey); - /* Allow space for signature algorithm */ - if (SSL_USE_SIGALGS(s)) - kn += 2; - /* Allow space for signature length */ - kn += 2; - } else { - pkey = NULL; - kn = 0; - } - - if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_BUF); - goto err; - } - d = p = ssl_handshake_start(s); - - for (i = 0; i < 4 && r[i] != NULL; i++) { -#ifndef OPENSSL_NO_SRP - if ((i == 2) && (type & SSL_kSRP)) { - *p = nr[i]; - p++; - } else -#endif -#ifndef OPENSSL_NO_DH - /* - * for interoperability with some versions of the Microsoft TLS - * stack, we need to zero pad the DHE pub key to the same length - * as the prime - */ - if ((i == 2) && (type & (SSL_kEDH))) { - s2n(nr[0], p); - for (j = 0; j < (nr[0] - nr[2]); ++j) { - *p = 0; - ++p; - } - } else -#endif - s2n(nr[i], p); - BN_bn2bin(r[i], p); - p += nr[i]; - } - -#ifndef OPENSSL_NO_ECDH - if (type & SSL_kEECDH) { - /* - * XXX: For now, we only support named (not generic) curves. In - * this situation, the serverKeyExchange message has: [1 byte - * CurveType], [2 byte CurveName] [1 byte length of encoded - * point], followed by the actual encoded point itself - */ - *p = NAMED_CURVE_TYPE; - p += 1; - *p = 0; - p += 1; - *p = curve_id; - p += 1; - *p = encodedlen; - p += 1; - memcpy((unsigned char *)p, - (unsigned char *)encodedPoint, encodedlen); - OPENSSL_free(encodedPoint); - encodedPoint = NULL; - p += encodedlen; - } -#endif - -#ifndef OPENSSL_NO_PSK - if (type & SSL_kPSK) { - size_t len = strlen(s->ctx->psk_identity_hint); - - /* copy PSK identity hint */ - s2n(len, p); - memcpy(p, s->ctx->psk_identity_hint, len); - p += len; - } -#endif - - /* not anonymous */ - if (pkey != NULL) { - /* - * n is the length of the params, they start at &(d[4]) and p - * points to the space at the end. - */ -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA && !SSL_USE_SIGALGS(s)) { - q = md_buf; - j = 0; - for (num = 2; num > 0; num--) { - EVP_MD_CTX_set_flags(&md_ctx, - EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - if (EVP_DigestInit_ex(&md_ctx, - (num == 2) ? s->ctx->md5 - : s->ctx->sha1, - NULL) <= 0 - || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestUpdate(&md_ctx, d, n) <= 0 - || EVP_DigestFinal_ex(&md_ctx, q, - (unsigned int *)&i) <= 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_LIB_EVP); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - q += i; - j += i; - } - if (RSA_sign(NID_md5_sha1, md_buf, j, - &(p[2]), &u, pkey->pkey.rsa) <= 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_RSA); - goto err; - } - s2n(u, p); - n += u + 2; - } else -#endif - if (md) { - /* send signature algorithm */ - if (SSL_USE_SIGALGS(s)) { - if (!tls12_get_sigandhash(p, pkey, md)) { - /* Should never happen */ - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto f_err; - } - p += 2; - } -#ifdef SSL_DEBUG - fprintf(stderr, "Using hash %s\n", EVP_MD_name(md)); -#endif - if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0 - || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_SignUpdate(&md_ctx, d, n) <= 0 - || EVP_SignFinal(&md_ctx, &(p[2]), - (unsigned int *)&i, pkey) <= 0) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_EVP); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - s2n(i, p); - n += i + 2; - if (SSL_USE_SIGALGS(s)) - n += 2; - } else { - /* Is this error check actually needed? */ - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - SSL_R_UNKNOWN_PKEY_TYPE); - goto f_err; - } - } - - ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n); - } - - s->state = SSL3_ST_SW_KEY_EXCH_B; - EVP_MD_CTX_cleanup(&md_ctx); - return ssl_do_write(s); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: -#ifndef OPENSSL_NO_ECDH - if (encodedPoint != NULL) - OPENSSL_free(encodedPoint); - BN_CTX_free(bn_ctx); -#endif - EVP_MD_CTX_cleanup(&md_ctx); - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_send_certificate_request(SSL *s) -{ - unsigned char *p, *d; - int i, j, nl, off, n; - STACK_OF(X509_NAME) *sk = NULL; - X509_NAME *name; - BUF_MEM *buf; - - if (s->state == SSL3_ST_SW_CERT_REQ_A) { - buf = s->init_buf; - - d = p = ssl_handshake_start(s); - - /* get the list of acceptable cert types */ - p++; - n = ssl3_get_req_cert_type(s, p); - d[0] = n; - p += n; - n++; - - if (SSL_USE_SIGALGS(s)) { - const unsigned char *psigs; - nl = tls12_get_psigalgs(s, 1, &psigs); - if (nl > SSL_MAX_2_BYTE_LEN) { - SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, - SSL_R_LENGTH_TOO_LONG); - goto err; - } - s2n(nl, p); - memcpy(p, psigs, nl); - p += nl; - n += nl + 2; - } - - off = n; - p += 2; - n += 2; - - sk = SSL_get_client_CA_list(s); - nl = 0; - if (sk != NULL) { - for (i = 0; i < sk_X509_NAME_num(sk); i++) { - name = sk_X509_NAME_value(sk, i); - j = i2d_X509_NAME(name, NULL); - if (j > SSL_MAX_2_BYTE_LEN) { - SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, - SSL_R_LENGTH_TOO_LONG); - goto err; - } - if (!BUF_MEM_grow_clean - (buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) { - SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, - ERR_R_BUF_LIB); - goto err; - } - p = ssl_handshake_start(s) + n; - if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) { - s2n(j, p); - i2d_X509_NAME(name, &p); - n += 2 + j; - nl += 2 + j; - } else { - d = p; - i2d_X509_NAME(name, &p); - j -= 2; - s2n(j, d); - j += 2; - n += j; - nl += j; - } - if (nl > SSL_MAX_2_BYTE_LEN) { - SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, - SSL_R_LENGTH_TOO_LONG); - goto err; - } - } - } - /* else no CA names */ - p = ssl_handshake_start(s) + off; - s2n(nl, p); - - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n); - -#ifdef NETSCAPE_HANG_BUG - if (!SSL_IS_DTLS(s)) { - if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) { - SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_BUF_LIB); - goto err; - } - p = (unsigned char *)s->init_buf->data + s->init_num; - /* do the header */ - *(p++) = SSL3_MT_SERVER_DONE; - *(p++) = 0; - *(p++) = 0; - *(p++) = 0; - s->init_num += 4; - } -#endif - - s->state = SSL3_ST_SW_CERT_REQ_B; - } - - /* SSL3_ST_SW_CERT_REQ_B */ - return ssl_do_write(s); - err: - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_client_key_exchange(SSL *s) -{ - int i, al, ok; - long n; - unsigned long alg_k; - unsigned char *p; -#ifndef OPENSSL_NO_RSA - RSA *rsa = NULL; - EVP_PKEY *pkey = NULL; -#endif -#ifndef OPENSSL_NO_DH - BIGNUM *pub = NULL; - DH *dh_srvr, *dh_clnt = NULL; -#endif -#ifndef OPENSSL_NO_KRB5 - KSSL_ERR kssl_err; -#endif /* OPENSSL_NO_KRB5 */ - -#ifndef OPENSSL_NO_ECDH - EC_KEY *srvr_ecdh = NULL; - EVP_PKEY *clnt_pub_pkey = NULL; - EC_POINT *clnt_ecpoint = NULL; - BN_CTX *bn_ctx = NULL; -#endif - - n = s->method->ssl_get_message(s, - SSL3_ST_SR_KEY_EXCH_A, - SSL3_ST_SR_KEY_EXCH_B, - SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, &ok); - - if (!ok) - return ((int)n); - p = (unsigned char *)s->init_msg; - - alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - -#ifndef OPENSSL_NO_RSA - if (alg_k & SSL_kRSA) { - unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; - int decrypt_len; - unsigned char decrypt_good, version_good; - size_t j, padding_len; - - /* FIX THIS UP EAY EAY EAY EAY */ - if (s->s3->tmp.use_rsa_tmp) { - if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL)) - rsa = s->cert->rsa_tmp; - /* - * Don't do a callback because rsa_tmp should be sent already - */ - if (rsa == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_RSA_PKEY); - goto f_err; - - } - } else { - pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; - if ((pkey == NULL) || - (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_RSA_CERTIFICATE); - goto f_err; - } - rsa = pkey->pkey.rsa; - } - - /* TLS and [incidentally] DTLS{0xFEFF} */ - if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) { - n2s(p, i); - if (n != i + 2) { - if (!(s->options & SSL_OP_TLS_D5_BUG)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); - goto f_err; - } else - p -= 2; - } else - n = i; - } - - /* - * Reject overly short RSA ciphertext because we want to be sure - * that the buffer size makes it safe to iterate over the entire - * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The - * actual expected size is larger due to RSA padding, but the - * bound is sufficient to be safe. - */ - if (n < SSL_MAX_MASTER_KEY_LENGTH) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); - goto f_err; - } - - /* - * We must not leak whether a decryption failure occurs because of - * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, - * section 7.4.7.1). The code follows that advice of the TLS RFC and - * generates a random premaster secret for the case that the decrypt - * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 - */ - - if (RAND_bytes(rand_premaster_secret, - sizeof(rand_premaster_secret)) <= 0) - goto err; - - /* - * Decrypt with no padding. PKCS#1 padding will be removed as part of - * the timing-sensitive code below. - */ - decrypt_len = - RSA_private_decrypt((int)n, p, p, rsa, RSA_NO_PADDING); - if (decrypt_len < 0) - goto err; - - /* Check the padding. See RFC 3447, section 7.2.2. */ - - /* - * The smallest padded premaster is 11 bytes of overhead. Small keys - * are publicly invalid, so this may return immediately. This ensures - * PS is at least 8 bytes. - */ - if (decrypt_len < 11 + SSL_MAX_MASTER_KEY_LENGTH) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto f_err; - } - - padding_len = decrypt_len - SSL_MAX_MASTER_KEY_LENGTH; - decrypt_good = constant_time_eq_int_8(p[0], 0) & - constant_time_eq_int_8(p[1], 2); - for (j = 2; j < padding_len - 1; j++) { - decrypt_good &= ~constant_time_is_zero_8(p[j]); - } - decrypt_good &= constant_time_is_zero_8(p[padding_len - 1]); - p += padding_len; - - /* - * If the version in the decrypted pre-master secret is correct then - * version_good will be 0xff, otherwise it'll be zero. The - * Klima-Pokorny-Rosa extension of Bleichenbacher's attack - * (http://eprint.iacr.org/2003/052/) exploits the version number - * check as a "bad version oracle". Thus version checks are done in - * constant time and are treated like any other decryption error. - */ - version_good = - constant_time_eq_8(p[0], (unsigned)(s->client_version >> 8)); - version_good &= - constant_time_eq_8(p[1], (unsigned)(s->client_version & 0xff)); - - /* - * The premaster secret must contain the same version number as the - * ClientHello to detect version rollback attacks (strangely, the - * protocol does not offer such protection for DH ciphersuites). - * However, buggy clients exist that send the negotiated protocol - * version instead if the server does not support the requested - * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such - * clients. - */ - if (s->options & SSL_OP_TLS_ROLLBACK_BUG) { - unsigned char workaround_good; - workaround_good = - constant_time_eq_8(p[0], (unsigned)(s->version >> 8)); - workaround_good &= - constant_time_eq_8(p[1], (unsigned)(s->version & 0xff)); - version_good |= workaround_good; - } - - /* - * Both decryption and version must be good for decrypt_good to - * remain non-zero (0xff). - */ - decrypt_good &= version_good; - - /* - * Now copy rand_premaster_secret over from p using - * decrypt_good_mask. If decryption failed, then p does not - * contain valid plaintext, however, a check above guarantees - * it is still sufficiently large to read from. - */ - for (j = 0; j < sizeof(rand_premaster_secret); j++) { - p[j] = constant_time_select_8(decrypt_good, p[j], - rand_premaster_secret[j]); - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, - sizeof - (rand_premaster_secret)); - OPENSSL_cleanse(p, sizeof(rand_premaster_secret)); - } else -#endif -#ifndef OPENSSL_NO_DH - if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { - int idx = -1; - EVP_PKEY *skey = NULL; - if (n > 1) { - n2s(p, i); - } else { - if (alg_k & SSL_kDHE) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); - goto f_err; - } - i = 0; - } - if (n && n != i + 2) { - if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } else { - p -= 2; - i = (int)n; - } - } - if (alg_k & SSL_kDHr) - idx = SSL_PKEY_DH_RSA; - else if (alg_k & SSL_kDHd) - idx = SSL_PKEY_DH_DSA; - if (idx >= 0) { - skey = s->cert->pkeys[idx].privatekey; - if ((skey == NULL) || - (skey->type != EVP_PKEY_DH) || (skey->pkey.dh == NULL)) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_RSA_CERTIFICATE); - goto f_err; - } - dh_srvr = skey->pkey.dh; - } else if (s->s3->tmp.dh == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } else - dh_srvr = s->s3->tmp.dh; - - if (n == 0L) { - /* Get pubkey from cert */ - EVP_PKEY *clkey = X509_get_pubkey(s->session->peer); - if (clkey) { - if (EVP_PKEY_cmp_parameters(clkey, skey) == 1) - dh_clnt = EVP_PKEY_get1_DH(clkey); - } - if (dh_clnt == NULL) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_DH_KEY); - goto f_err; - } - EVP_PKEY_free(clkey); - pub = dh_clnt->pub_key; - } else - pub = BN_bin2bn(p, i, NULL); - if (pub == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB); - goto err; - } - - i = DH_compute_key(p, pub, dh_srvr); - - if (i <= 0) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); - BN_clear_free(pub); - goto f_err; - } - - DH_free(s->s3->tmp.dh); - s->s3->tmp.dh = NULL; - if (dh_clnt) - DH_free(dh_clnt); - else - BN_clear_free(pub); - pub = NULL; - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, i); - OPENSSL_cleanse(p, i); - if (dh_clnt) - return 2; - } else -#endif -#ifndef OPENSSL_NO_KRB5 - if (alg_k & SSL_kKRB5) { - krb5_error_code krb5rc; - krb5_data enc_ticket; - krb5_data authenticator; - krb5_data enc_pms; - KSSL_CTX *kssl_ctx = s->kssl_ctx; - EVP_CIPHER_CTX ciph_ctx; - const EVP_CIPHER *enc = NULL; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH]; - int padl, outl; - krb5_timestamp authtime = 0; - krb5_ticket_times ttimes; - int kerr = 0; - - EVP_CIPHER_CTX_init(&ciph_ctx); - - if (!kssl_ctx) - kssl_ctx = kssl_ctx_new(); - - n2s(p, i); - enc_ticket.length = i; - - if (n < (long)(enc_ticket.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - enc_ticket.data = (char *)p; - p += enc_ticket.length; - - n2s(p, i); - authenticator.length = i; - - if (n < (long)(enc_ticket.length + authenticator.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - authenticator.data = (char *)p; - p += authenticator.length; - - n2s(p, i); - enc_pms.length = i; - enc_pms.data = (char *)p; - p += enc_pms.length; - - /* - * Note that the length is checked again below, ** after decryption - */ - if (enc_pms.length > sizeof(pms)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - if (n != (long)(enc_ticket.length + authenticator.length + - enc_pms.length + 6)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto err; - } - - if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes, - &kssl_err)) != 0) { -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_sget_tkt rtn %d [%d]\n", - krb5rc, kssl_err.reason); - if (kssl_err.text) - fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); -# endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } - - /* - * Note: no authenticator is not considered an error, ** but will - * return authtime == 0. - */ - if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator, - &authtime, &kssl_err)) != 0) { -# ifdef KSSL_DEBUG - fprintf(stderr, "kssl_check_authent rtn %d [%d]\n", - krb5rc, kssl_err.reason); - if (kssl_err.text) - fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); -# endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } - - if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc); - goto err; - } -# ifdef KSSL_DEBUG - kssl_ctx_show(kssl_ctx); -# endif /* KSSL_DEBUG */ - - enc = kssl_map_enc(kssl_ctx->enctype); - if (enc == NULL) - goto err; - - memset(iv, 0, sizeof(iv)); /* per RFC 1510 */ - - if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto err; - } - if (!EVP_DecryptUpdate(&ciph_ctx, pms, &outl, - (unsigned char *)enc_pms.data, enc_pms.length)) - { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - kerr = 1; - goto kclean; - } - if (outl > SSL_MAX_MASTER_KEY_LENGTH) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - kerr = 1; - goto kclean; - } - if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - kerr = 1; - goto kclean; - } - outl += padl; - if (outl > SSL_MAX_MASTER_KEY_LENGTH) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - kerr = 1; - goto kclean; - } - if (!((pms[0] == (s->client_version >> 8)) - && (pms[1] == (s->client_version & 0xff)))) { - /* - * The premaster secret must contain the same version number as - * the ClientHello to detect version rollback attacks (strangely, - * the protocol does not offer such protection for DH - * ciphersuites). However, buggy clients exist that send random - * bytes instead of the protocol version. If - * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. - * (Perhaps we should have a separate BUG value for the Kerberos - * cipher) - */ - if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_AD_DECODE_ERROR); - kerr = 1; - goto kclean; - } - } - - EVP_CIPHER_CTX_cleanup(&ciph_ctx); - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - pms, outl); - - if (kssl_ctx->client_princ) { - size_t len = strlen(kssl_ctx->client_princ); - if (len < SSL_MAX_KRB5_PRINCIPAL_LENGTH) { - s->session->krb5_client_princ_len = len; - memcpy(s->session->krb5_client_princ, kssl_ctx->client_princ, - len); - } - } - - /*- Was doing kssl_ctx_free() here, - * but it caused problems for apache. - * kssl_ctx = kssl_ctx_free(kssl_ctx); - * if (s->kssl_ctx) s->kssl_ctx = NULL; - */ - - kclean: - OPENSSL_cleanse(pms, sizeof(pms)); - if (kerr) - goto err; - } else -#endif /* OPENSSL_NO_KRB5 */ - -#ifndef OPENSSL_NO_ECDH - if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { - int ret = 1; - int field_size = 0; - const EC_KEY *tkey; - const EC_GROUP *group; - const BIGNUM *priv_key; - - /* initialize structures for server's ECDH key pair */ - if ((srvr_ecdh = EC_KEY_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Let's get server private key and group information */ - if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { - /* use the certificate */ - tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec; - } else { - /* - * use the ephermeral values we saved when generating the - * ServerKeyExchange msg. - */ - tkey = s->s3->tmp.ecdh; - } - - group = EC_KEY_get0_group(tkey); - priv_key = EC_KEY_get0_private_key(tkey); - - if (!EC_KEY_set_group(srvr_ecdh, group) || - !EC_KEY_set_private_key(srvr_ecdh, priv_key)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - - /* Let's get client's public key */ - if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (n == 0L) { - /* Client Publickey was in Client Certificate */ - - if (alg_k & SSL_kEECDH) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_MISSING_TMP_ECDH_KEY); - goto f_err; - } - if (((clnt_pub_pkey = X509_get_pubkey(s->session->peer)) - == NULL) || (clnt_pub_pkey->type != EVP_PKEY_EC)) { - /* - * XXX: For now, we do not support client authentication - * using ECDH certificates so this branch (n == 0L) of the - * code is never executed. When that support is added, we - * ought to ensure the key received in the certificate is - * authorized for key agreement. ECDH_compute_key implicitly - * checks that the two ECDH shares are for the same group. - */ - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); - goto f_err; - } - - if (EC_POINT_copy(clnt_ecpoint, - EC_KEY_get0_public_key(clnt_pub_pkey-> - pkey.ec)) == 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; - } - ret = 2; /* Skip certificate verify processing */ - } else { - /* - * Get client's public key from encoded point in the - * ClientKeyExchange message. - */ - if ((bn_ctx = BN_CTX_new()) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Get encoded point length */ - i = *p; - p += 1; - if (n != 1 + i) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } - /* - * p is pointing to somewhere in the buffer currently, so set it - * to the start - */ - p = (unsigned char *)s->init_buf->data; - } - - /* Compute the shared pre-master secret */ - field_size = EC_GROUP_get_degree(group); - if (field_size <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - i = ECDH_compute_key(p, (field_size + 7) / 8, clnt_ecpoint, srvr_ecdh, - NULL); - if (i <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } - - EVP_PKEY_free(clnt_pub_pkey); - EC_POINT_free(clnt_ecpoint); - EC_KEY_free(srvr_ecdh); - BN_CTX_free(bn_ctx); - EC_KEY_free(s->s3->tmp.ecdh); - s->s3->tmp.ecdh = NULL; - - /* Compute the master secret */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - p, i); - - OPENSSL_cleanse(p, i); - return (ret); - } else -#endif -#ifndef OPENSSL_NO_PSK - if (alg_k & SSL_kPSK) { - unsigned char *t = NULL; - unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; - unsigned int pre_ms_len = 0, psk_len = 0; - int psk_err = 1; - char tmp_id[PSK_MAX_IDENTITY_LEN + 1]; - - al = SSL_AD_HANDSHAKE_FAILURE; - - n2s(p, i); - if (n != i + 2) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); - goto psk_err; - } - if (i > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DATA_LENGTH_TOO_LONG); - goto psk_err; - } - if (s->psk_server_callback == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_NO_SERVER_CB); - goto psk_err; - } - - /* - * Create guaranteed NULL-terminated identity string for the callback - */ - memcpy(tmp_id, p, i); - memset(tmp_id + i, 0, PSK_MAX_IDENTITY_LEN + 1 - i); - psk_len = s->psk_server_callback(s, tmp_id, - psk_or_pre_ms, - sizeof(psk_or_pre_ms)); - OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN + 1); - - if (psk_len > PSK_MAX_PSK_LEN) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto psk_err; - } else if (psk_len == 0) { - /* - * PSK related to the given identity not found - */ - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_PSK_IDENTITY_NOT_FOUND); - al = SSL_AD_UNKNOWN_PSK_IDENTITY; - goto psk_err; - } - - /* create PSK pre_master_secret */ - pre_ms_len = 2 + psk_len + 2 + psk_len; - t = psk_or_pre_ms; - memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); - s2n(psk_len, t); - memset(t, 0, psk_len); - t += psk_len; - s2n(psk_len, t); - - if (s->session->psk_identity != NULL) - OPENSSL_free(s->session->psk_identity); - s->session->psk_identity = BUF_strndup((char *)p, i); - if (s->session->psk_identity == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); - if (s->ctx->psk_identity_hint != NULL && - s->session->psk_identity_hint == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto psk_err; - } - - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - psk_or_pre_ms, - pre_ms_len); - psk_err = 0; - psk_err: - OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); - if (psk_err != 0) - goto f_err; - } else -#endif -#ifndef OPENSSL_NO_SRP - if (alg_k & SSL_kSRP) { - int param_len; - - n2s(p, i); - param_len = i + 2; - if (param_len > n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_SRP_A_LENGTH); - goto f_err; - } - if (!(s->srp_ctx.A = BN_bin2bn(p, i, NULL))) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_BN_LIB); - goto err; - } - if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 - || BN_is_zero(s->srp_ctx.A)) { - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_BAD_SRP_PARAMETERS); - goto f_err; - } - if (s->session->srp_username != NULL) - OPENSSL_free(s->session->srp_username); - s->session->srp_username = BUF_strdup(s->srp_ctx.login); - if (s->session->srp_username == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if ((s->session->master_key_length = - SRP_generate_server_master_secret(s, - s->session->master_key)) < 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto err; - } - - p += i; - } else -#endif /* OPENSSL_NO_SRP */ - if (alg_k & SSL_kGOST) { - int ret = 0; - EVP_PKEY_CTX *pkey_ctx; - EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; - unsigned char premaster_secret[32], *start; - size_t outlen = 32, inlen; - unsigned long alg_a; - int Ttag, Tclass; - long Tlen; - - /* Get our certificate private key */ - alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if (alg_a & SSL_aGOST94) - pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; - else if (alg_a & SSL_aGOST01) - pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; - - pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); - if (pkey_ctx == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); - goto f_err; - } - if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); - goto gerr; - } - /* - * If client certificate is present and is of the same type, maybe - * use it for key exchange. Don't mind errors from - * EVP_PKEY_derive_set_peer, because it is completely valid to use a - * client certificate for authorization only. - */ - client_pub_pkey = X509_get_pubkey(s->session->peer); - if (client_pub_pkey) { - if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) - ERR_clear_error(); - } - /* Decrypt session key */ - if (ASN1_get_object - ((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, - n) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE - || Tclass != V_ASN1_UNIVERSAL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto gerr; - } - start = p; - inlen = Tlen; - if (EVP_PKEY_decrypt - (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, - SSL_R_DECRYPTION_FAILED); - goto gerr; - } - /* Generate master secret */ - s->session->master_key_length = - s->method->ssl3_enc->generate_master_secret(s, - s-> - session->master_key, - premaster_secret, 32); - OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret)); - /* Check if pubkey from client certificate was used */ - if (EVP_PKEY_CTX_ctrl - (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) - ret = 2; - else - ret = 1; - gerr: - EVP_PKEY_free(client_pub_pkey); - EVP_PKEY_CTX_free(pkey_ctx); - if (ret) - return ret; - else - goto err; - } else { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE); - goto f_err; - } - - return (1); - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP) - err: -#endif -#ifndef OPENSSL_NO_ECDH - EVP_PKEY_free(clnt_pub_pkey); - EC_POINT_free(clnt_ecpoint); - if (srvr_ecdh != NULL) - EC_KEY_free(srvr_ecdh); - BN_CTX_free(bn_ctx); -#endif - s->state = SSL_ST_ERR; - return (-1); -} - -int ssl3_get_cert_verify(SSL *s) -{ - EVP_PKEY *pkey = NULL; - unsigned char *p; - int al, ok, ret = 0; - long n; - int type = 0, i, j; - X509 *peer; - const EVP_MD *md = NULL; - EVP_MD_CTX mctx; - EVP_MD_CTX_init(&mctx); - - /* - * We should only process a CertificateVerify message if we have received - * a Certificate from the client. If so then |s->session->peer| will be non - * NULL. In some instances a CertificateVerify message is not required even - * if the peer has sent a Certificate (e.g. such as in the case of static - * DH). In that case the ClientKeyExchange processing will skip the - * CertificateVerify state so we should not arrive here. - */ - if (s->session->peer == NULL) { - ret = 1; - goto end; - } - - n = s->method->ssl_get_message(s, - SSL3_ST_SR_CERT_VRFY_A, - SSL3_ST_SR_CERT_VRFY_B, - SSL3_MT_CERTIFICATE_VERIFY, - SSL3_RT_MAX_PLAIN_LENGTH, &ok); - - if (!ok) - return ((int)n); - - peer = s->session->peer; - pkey = X509_get_pubkey(peer); - if (pkey == NULL) { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - - type = X509_certificate_type(peer, pkey); - - if (!(type & EVP_PKT_SIGN)) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, - SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); - al = SSL_AD_ILLEGAL_PARAMETER; - goto f_err; - } - - /* we now have a signature that we need to verify */ - p = (unsigned char *)s->init_msg; - /* Check for broken implementations of GOST ciphersuites */ - /* - * If key is GOST and n is exactly 64, it is bare signature without - * length field - */ - if (n == 64 && (pkey->type == NID_id_GostR3410_94 || - pkey->type == NID_id_GostR3410_2001)) { - i = 64; - } else { - if (SSL_USE_SIGALGS(s)) { - int rv = tls12_check_peer_sigalg(&md, s, p, pkey); - if (rv == -1) { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } else if (rv == 0) { - al = SSL_AD_DECODE_ERROR; - goto f_err; - } -#ifdef SSL_DEBUG - fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); -#endif - p += 2; - n -= 2; - } - n2s(p, i); - n -= 2; - if (i > n) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - } - j = EVP_PKEY_size(pkey); - if ((i > j) || (n > j) || (n <= 0)) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE); - al = SSL_AD_DECODE_ERROR; - goto f_err; - } - - if (SSL_USE_SIGALGS(s)) { - long hdatalen = 0; - void *hdata; - hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); - if (hdatalen <= 0) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } -#ifdef SSL_DEBUG - fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n", - EVP_MD_name(md)); -#endif - if (!EVP_VerifyInit_ex(&mctx, md, NULL) - || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB); - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - - if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE); - goto f_err; - } - } else -#ifndef OPENSSL_NO_RSA - if (pkey->type == EVP_PKEY_RSA) { - i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md, - MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i, - pkey->pkey.rsa); - if (i < 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT); - goto f_err; - } - if (i == 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE); - goto f_err; - } - } else -#endif -#ifndef OPENSSL_NO_DSA - if (pkey->type == EVP_PKEY_DSA) { - j = DSA_verify(pkey->save_type, - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa); - if (j <= 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE); - goto f_err; - } - } else -#endif -#ifndef OPENSSL_NO_ECDSA - if (pkey->type == EVP_PKEY_EC) { - j = ECDSA_verify(pkey->save_type, - &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec); - if (j <= 0) { - /* bad signature */ - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); - goto f_err; - } - } else -#endif - if (pkey->type == NID_id_GostR3410_94 - || pkey->type == NID_id_GostR3410_2001) { - unsigned char signature[64]; - int idx; - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL); - if (pctx == NULL) { - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_MALLOC_FAILURE); - goto f_err; - } - if (EVP_PKEY_verify_init(pctx) <= 0) { - EVP_PKEY_CTX_free(pctx); - al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - goto f_err; - } - if (i != 64) { -#ifdef SSL_DEBUG - fprintf(stderr, "GOST signature length is %d", i); -#endif - } - for (idx = 0; idx < 64; idx++) { - signature[63 - idx] = p[idx]; - } - j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md, - 32); - EVP_PKEY_CTX_free(pctx); - if (j <= 0) { - al = SSL_AD_DECRYPT_ERROR; - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); - goto f_err; - } - } else { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); - al = SSL_AD_UNSUPPORTED_CERTIFICATE; - goto f_err; - } - - ret = 1; - if (0) { - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - s->state = SSL_ST_ERR; - } - end: - if (s->s3->handshake_buffer) { - BIO_free(s->s3->handshake_buffer); - s->s3->handshake_buffer = NULL; - s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; - } - EVP_MD_CTX_cleanup(&mctx); - EVP_PKEY_free(pkey); - return (ret); -} - -int ssl3_get_client_certificate(SSL *s) -{ - int i, ok, al, ret = -1; - X509 *x = NULL; - unsigned long l, nc, llen, n; - const unsigned char *p, *q; - unsigned char *d; - STACK_OF(X509) *sk = NULL; - - n = s->method->ssl_get_message(s, - SSL3_ST_SR_CERT_A, - SSL3_ST_SR_CERT_B, - -1, s->max_cert_list, &ok); - - if (!ok) - return ((int)n); - - if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { - if ((s->verify_mode & SSL_VERIFY_PEER) && - (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } - /* - * If tls asked for a client cert, the client must return a 0 list - */ - if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); - al = SSL_AD_UNEXPECTED_MESSAGE; - goto f_err; - } - s->s3->tmp.reuse_message = 1; - return (1); - } - - if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { - al = SSL_AD_UNEXPECTED_MESSAGE; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE); - goto f_err; - } - p = d = (unsigned char *)s->init_msg; - - if ((sk = sk_X509_new_null()) == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - - n2l3(p, llen); - if (llen + 3 != n) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH); - goto f_err; - } - for (nc = 0; nc < llen;) { - if (nc + 3 > llen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - n2l3(p, l); - if ((l + nc + 3) > llen) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - - q = p; - x = d2i_X509(NULL, &p, l); - if (x == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB); - goto err; - } - if (p != (q + l)) { - al = SSL_AD_DECODE_ERROR; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_CERT_LENGTH_MISMATCH); - goto f_err; - } - if (!sk_X509_push(sk, x)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - x = NULL; - nc += l + 3; - } - - if (sk_X509_num(sk) <= 0) { - /* TLS does not mind 0 certs returned */ - if (s->version == SSL3_VERSION) { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_NO_CERTIFICATES_RETURNED); - goto f_err; - } - /* Fail for TLS only if we required a certificate */ - else if ((s->verify_mode & SSL_VERIFY_PEER) && - (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - al = SSL_AD_HANDSHAKE_FAILURE; - goto f_err; - } - /* No client certificate so digest cached records */ - if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s)) { - al = SSL_AD_INTERNAL_ERROR; - goto f_err; - } - } else { - i = ssl_verify_cert_chain(s, sk); - if (i <= 0) { - al = ssl_verify_alarm_type(s->verify_result); - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, - SSL_R_CERTIFICATE_VERIFY_FAILED); - goto f_err; - } - } - - if (s->session->peer != NULL) /* This should not be needed */ - X509_free(s->session->peer); - s->session->peer = sk_X509_shift(sk); - s->session->verify_result = s->verify_result; - - /* - * With the current implementation, sess_cert will always be NULL when we - * arrive here. - */ - if (s->session->sess_cert == NULL) { - s->session->sess_cert = ssl_sess_cert_new(); - if (s->session->sess_cert == NULL) { - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); - goto err; - } - } - if (s->session->sess_cert->cert_chain != NULL) - sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); - s->session->sess_cert->cert_chain = sk; - /* - * Inconsistency alert: cert_chain does *not* include the peer's own - * certificate, while we do include it in s3_clnt.c - */ - - sk = NULL; - - ret = 1; - if (0) { - f_err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - err: - s->state = SSL_ST_ERR; - } - - if (x != NULL) - X509_free(x); - if (sk != NULL) - sk_X509_pop_free(sk, X509_free); - return (ret); -} - -int ssl3_send_server_certificate(SSL *s) -{ - CERT_PKEY *cpk; - - if (s->state == SSL3_ST_SW_CERT_A) { - cpk = ssl_get_server_send_pkey(s); - if (cpk == NULL) { - /* VRS: allow null cert if auth == KRB5 */ - if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) || - (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, - ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return (0); - } - } - - if (!ssl3_output_cert_chain(s, cpk)) { - SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); - s->state = SSL_ST_ERR; - return (0); - } - s->state = SSL3_ST_SW_CERT_B; - } - - /* SSL3_ST_SW_CERT_B */ - return ssl_do_write(s); -} - -#ifndef OPENSSL_NO_TLSEXT -/* send a new session ticket (not necessarily for a new session) */ -int ssl3_send_newsession_ticket(SSL *s) -{ - unsigned char *senc = NULL; - EVP_CIPHER_CTX ctx; - HMAC_CTX hctx; - - if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { - unsigned char *p, *macstart; - const unsigned char *const_p; - int len, slen_full, slen; - SSL_SESSION *sess; - unsigned int hlen; - SSL_CTX *tctx = s->initial_ctx; - unsigned char iv[EVP_MAX_IV_LENGTH]; - unsigned char key_name[16]; - - /* get session encoding length */ - slen_full = i2d_SSL_SESSION(s->session, NULL); - /* - * Some length values are 16 bits, so forget it if session is too - * long - */ - if (slen_full == 0 || slen_full > 0xFF00) { - s->state = SSL_ST_ERR; - return -1; - } - senc = OPENSSL_malloc(slen_full); - if (!senc) { - s->state = SSL_ST_ERR; - return -1; - } - - EVP_CIPHER_CTX_init(&ctx); - HMAC_CTX_init(&hctx); - - p = senc; - if (!i2d_SSL_SESSION(s->session, &p)) - goto err; - - /* - * create a fresh copy (not shared with other threads) to clean up - */ - const_p = senc; - sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); - if (sess == NULL) - goto err; - sess->session_id_length = 0; /* ID is irrelevant for the ticket */ - - slen = i2d_SSL_SESSION(sess, NULL); - if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ - SSL_SESSION_free(sess); - goto err; - } - p = senc; - if (!i2d_SSL_SESSION(sess, &p)) { - SSL_SESSION_free(sess); - goto err; - } - SSL_SESSION_free(sess); - - /*- - * Grow buffer if need be: the length calculation is as - * follows handshake_header_length + - * 4 (ticket lifetime hint) + 2 (ticket length) + - * 16 (key name) + max_iv_len (iv length) + - * session_length + max_enc_block_size (max encrypted session - * length) + max_md_size (HMAC). - */ - if (!BUF_MEM_grow(s->init_buf, - SSL_HM_HEADER_LENGTH(s) + 22 + EVP_MAX_IV_LENGTH + - EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) - goto err; - - p = ssl_handshake_start(s); - /* - * Initialize HMAC and cipher contexts. If callback present it does - * all the work otherwise use generated values from parent ctx. - */ - if (tctx->tlsext_ticket_key_cb) { - /* if 0 is returned, write en empty ticket */ - int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, - &hctx, 1); - - if (ret == 0) { - l2n(0, p); /* timeout */ - s2n(0, p); /* length */ - ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, - p - ssl_handshake_start(s)); - s->state = SSL3_ST_SW_SESSION_TICKET_B; - OPENSSL_free(senc); - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hctx); - return ssl_do_write(s); - } - if (ret < 0) - goto err; - } else { - if (RAND_bytes(iv, 16) <= 0) - goto err; - if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, - tctx->tlsext_tick_aes_key, iv)) - goto err; - if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, - tlsext_tick_md(), NULL)) - goto err; - memcpy(key_name, tctx->tlsext_tick_key_name, 16); - } - - /* - * Ticket lifetime hint (advisory only): We leave this unspecified - * for resumed session (for simplicity), and guess that tickets for - * new sessions will live as long as their sessions. - */ - l2n(s->hit ? 0 : s->session->timeout, p); - - /* Skip ticket length for now */ - p += 2; - /* Output key name */ - macstart = p; - memcpy(p, key_name, 16); - p += 16; - /* output IV */ - memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); - p += EVP_CIPHER_CTX_iv_length(&ctx); - /* Encrypt session data */ - if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen)) - goto err; - p += len; - if (!EVP_EncryptFinal(&ctx, p, &len)) - goto err; - p += len; - - if (!HMAC_Update(&hctx, macstart, p - macstart)) - goto err; - if (!HMAC_Final(&hctx, p, &hlen)) - goto err; - - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hctx); - - p += hlen; - /* Now write out lengths: p points to end of data written */ - /* Total length */ - len = p - ssl_handshake_start(s); - /* Skip ticket lifetime hint */ - p = ssl_handshake_start(s) + 4; - s2n(len - 6, p); - ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, len); - s->state = SSL3_ST_SW_SESSION_TICKET_B; - OPENSSL_free(senc); - } - - /* SSL3_ST_SW_SESSION_TICKET_B */ - return ssl_do_write(s); - err: - if (senc) - OPENSSL_free(senc); - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hctx); - s->state = SSL_ST_ERR; - return -1; -} - -int ssl3_send_cert_status(SSL *s) -{ - if (s->state == SSL3_ST_SW_CERT_STATUS_A) { - unsigned char *p; - size_t msglen; - - /*- - * Grow buffer if need be: the length calculation is as - * follows handshake_header_length + - * 1 (ocsp response type) + 3 (ocsp response length) - * + (ocsp response) - */ - msglen = 4 + s->tlsext_ocsp_resplen; - if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + msglen)) { - s->state = SSL_ST_ERR; - return -1; - } - - p = ssl_handshake_start(s); - - /* status type */ - *(p++) = s->tlsext_status_type; - /* length of OCSP response */ - l2n3(s->tlsext_ocsp_resplen, p); - /* actual response */ - memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen); - - ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_STATUS, msglen); - } - - /* SSL3_ST_SW_CERT_STATUS_B */ - return (ssl_do_write(s)); -} - -# ifndef OPENSSL_NO_NEXTPROTONEG -/* - * ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. - * It sets the next_proto member in s if found - */ -int ssl3_get_next_proto(SSL *s) -{ - int ok; - int proto_len, padding_len; - long n; - const unsigned char *p; - - /* - * Clients cannot send a NextProtocol message if we didn't see the - * extension in their ClientHello - */ - if (!s->s3->next_proto_neg_seen) { - SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, - SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); - s->state = SSL_ST_ERR; - return -1; - } - - /* See the payload format below */ - n = s->method->ssl_get_message(s, - SSL3_ST_SR_NEXT_PROTO_A, - SSL3_ST_SR_NEXT_PROTO_B, - SSL3_MT_NEXT_PROTO, 514, &ok); - - if (!ok) - return ((int)n); - - /* - * s->state doesn't reflect whether ChangeCipherSpec has been received in - * this handshake, but s->s3->change_cipher_spec does (will be reset by - * ssl3_get_finished). - */ - if (!s->s3->change_cipher_spec) { - SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); - s->state = SSL_ST_ERR; - return -1; - } - - if (n < 2) { - s->state = SSL_ST_ERR; - return 0; /* The body must be > 1 bytes long */ - } - - p = (unsigned char *)s->init_msg; - - /*- - * The payload looks like: - * uint8 proto_len; - * uint8 proto[proto_len]; - * uint8 padding_len; - * uint8 padding[padding_len]; - */ - proto_len = p[0]; - if (proto_len + 2 > s->init_num) { - s->state = SSL_ST_ERR; - return 0; - } - padding_len = p[proto_len + 1]; - if (proto_len + padding_len + 2 != s->init_num) { - s->state = SSL_ST_ERR; - return 0; - } - - s->next_proto_negotiated = OPENSSL_malloc(proto_len); - if (!s->next_proto_negotiated) { - SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE); - s->state = SSL_ST_ERR; - return 0; - } - memcpy(s->next_proto_negotiated, p + 1, proto_len); - s->next_proto_negotiated_len = proto_len; - - return 1; -} -# endif - -#endif diff --git a/Sources/COpenSSL/safestack.h b/Sources/COpenSSL/safestack.h deleted file mode 100644 index 0cd2b495..00000000 --- a/Sources/COpenSSL/safestack.h +++ /dev/null @@ -1,2672 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_SAFESTACK_H -# define HEADER_SAFESTACK_H - -# include "stack.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# ifndef CHECKED_PTR_OF -# define CHECKED_PTR_OF(type, p) \ - ((void*) (1 ? p : (type*)0)) -# endif - -/* - * In C++ we get problems because an explicit cast is needed from (void *) we - * use CHECKED_STACK_OF to ensure the correct type is passed in the macros - * below. - */ - -# define CHECKED_STACK_OF(type, p) \ - ((_STACK*) (1 ? p : (STACK_OF(type)*)0)) - -# define CHECKED_SK_COPY_FUNC(type, p) \ - ((void *(*)(void *)) ((1 ? p : (type *(*)(const type *))0))) - -# define CHECKED_SK_FREE_FUNC(type, p) \ - ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) - -# define CHECKED_SK_CMP_FUNC(type, p) \ - ((int (*)(const void *, const void *)) \ - ((1 ? p : (int (*)(const type * const *, const type * const *))0))) - -# define STACK_OF(type) struct stack_st_##type -# define PREDECLARE_STACK_OF(type) STACK_OF(type); - -# define DECLARE_STACK_OF(type) \ -STACK_OF(type) \ - { \ - _STACK stack; \ - }; -# define DECLARE_SPECIAL_STACK_OF(type, type2) \ -STACK_OF(type) \ - { \ - _STACK stack; \ - }; - -/* nada (obsolete in new safestack approach)*/ -# define IMPLEMENT_STACK_OF(type) - -/*- - * Strings are special: normally an lhash entry will point to a single - * (somewhat) mutable object. In the case of strings: - * - * a) Instead of a single char, there is an array of chars, NUL-terminated. - * b) The string may have be immutable. - * - * So, they need their own declarations. Especially important for - * type-checking tools, such as Deputy. - * - * In practice, however, it appears to be hard to have a const - * string. For now, I'm settling for dealing with the fact it is a - * string at all. - */ -typedef char *OPENSSL_STRING; - -typedef const char *OPENSSL_CSTRING; - -/* - * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but - * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned - * above, instead of a single char each entry is a NUL-terminated array of - * chars. So, we have to implement STRING specially for STACK_OF. This is - * dealt with in the autogenerated macros below. - */ - -DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char) - -/* - * Similarly, we sometimes use a block of characters, NOT nul-terminated. - * These should also be distinguished from "normal" stacks. - */ -typedef void *OPENSSL_BLOCK; -DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) - -/* - * SKM_sk_... stack macros are internal to safestack.h: never use them - * directly, use sk__... instead - */ -# define SKM_sk_new(type, cmp) \ - ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp))) -# define SKM_sk_new_null(type) \ - ((STACK_OF(type) *)sk_new_null()) -# define SKM_sk_free(type, st) \ - sk_free(CHECKED_STACK_OF(type, st)) -# define SKM_sk_num(type, st) \ - sk_num(CHECKED_STACK_OF(type, st)) -# define SKM_sk_value(type, st,i) \ - ((type *)sk_value(CHECKED_STACK_OF(type, st), i)) -# define SKM_sk_set(type, st,i,val) \ - sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val)) -# define SKM_sk_zero(type, st) \ - sk_zero(CHECKED_STACK_OF(type, st)) -# define SKM_sk_push(type, st, val) \ - sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) -# define SKM_sk_unshift(type, st, val) \ - sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) -# define SKM_sk_find(type, st, val) \ - sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) -# define SKM_sk_find_ex(type, st, val) \ - sk_find_ex(CHECKED_STACK_OF(type, st), \ - CHECKED_PTR_OF(type, val)) -# define SKM_sk_delete(type, st, i) \ - (type *)sk_delete(CHECKED_STACK_OF(type, st), i) -# define SKM_sk_delete_ptr(type, st, ptr) \ - (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr)) -# define SKM_sk_insert(type, st,val, i) \ - sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i) -# define SKM_sk_set_cmp_func(type, st, cmp) \ - ((int (*)(const type * const *,const type * const *)) \ - sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp))) -# define SKM_sk_dup(type, st) \ - (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st)) -# define SKM_sk_pop_free(type, st, free_func) \ - sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) -# define SKM_sk_deep_copy(type, st, copy_func, free_func) \ - (STACK_OF(type) *)sk_deep_copy(CHECKED_STACK_OF(type, st), CHECKED_SK_COPY_FUNC(type, copy_func), CHECKED_SK_FREE_FUNC(type, free_func)) -# define SKM_sk_shift(type, st) \ - (type *)sk_shift(CHECKED_STACK_OF(type, st)) -# define SKM_sk_pop(type, st) \ - (type *)sk_pop(CHECKED_STACK_OF(type, st)) -# define SKM_sk_sort(type, st) \ - sk_sort(CHECKED_STACK_OF(type, st)) -# define SKM_sk_is_sorted(type, st) \ - sk_is_sorted(CHECKED_STACK_OF(type, st)) -# define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - (STACK_OF(type) *)d2i_ASN1_SET( \ - (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \ - pp, length, \ - CHECKED_D2I_OF(type, d2i_func), \ - CHECKED_SK_FREE_FUNC(type, free_func), \ - ex_tag, ex_class) -# define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ - i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \ - CHECKED_I2D_OF(type, i2d_func), \ - ex_tag, ex_class, is_set) -# define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \ - ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \ - CHECKED_I2D_OF(type, i2d_func), buf, len) -# define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \ - (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func)) -# define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \ - (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \ - CHECKED_D2I_OF(type, d2i_func), \ - CHECKED_SK_FREE_FUNC(type, free_func), \ - pass, passlen, oct, seq) -/* - * This block of defines is updated by util/mkstack.pl, please do not touch! - */ -# define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp)) -# define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) -# define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) -# define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) -# define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i)) -# define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val)) -# define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st)) -# define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val)) -# define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val)) -# define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val)) -# define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val)) -# define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i)) -# define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr)) -# define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i)) -# define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp)) -# define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st) -# define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func)) -# define sk_ACCESS_DESCRIPTION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ACCESS_DESCRIPTION, (st), (copy_func), (free_func)) -# define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st)) -# define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st)) -# define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) -# define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) -# define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp)) -# define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) -# define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) -# define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) -# define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i)) -# define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val)) -# define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st)) -# define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val)) -# define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val)) -# define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val)) -# define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val)) -# define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i)) -# define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr)) -# define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i)) -# define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp)) -# define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st) -# define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func)) -# define sk_ASIdOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASIdOrRange, (st), (copy_func), (free_func)) -# define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st)) -# define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st)) -# define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) -# define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) -# define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp)) -# define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) -# define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) -# define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) -# define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i)) -# define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val)) -# define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st)) -# define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val)) -# define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val)) -# define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val)) -# define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val)) -# define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i)) -# define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr)) -# define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i)) -# define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp)) -# define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st) -# define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func)) -# define sk_ASN1_GENERALSTRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_GENERALSTRING, (st), (copy_func), (free_func)) -# define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st)) -# define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st)) -# define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) -# define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) -# define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp)) -# define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) -# define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) -# define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) -# define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i)) -# define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val)) -# define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st)) -# define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val)) -# define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val)) -# define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val)) -# define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val)) -# define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i)) -# define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr)) -# define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i)) -# define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp)) -# define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st) -# define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func)) -# define sk_ASN1_INTEGER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_INTEGER, (st), (copy_func), (free_func)) -# define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st)) -# define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st)) -# define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) -# define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) -# define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp)) -# define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) -# define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) -# define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) -# define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i)) -# define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val)) -# define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st)) -# define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val)) -# define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val)) -# define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val)) -# define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val)) -# define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i)) -# define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr)) -# define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i)) -# define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp)) -# define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st) -# define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func)) -# define sk_ASN1_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_OBJECT, (st), (copy_func), (free_func)) -# define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st)) -# define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st)) -# define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) -# define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) -# define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp)) -# define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) -# define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) -# define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) -# define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i)) -# define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val)) -# define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st)) -# define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val)) -# define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val)) -# define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val)) -# define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val)) -# define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i)) -# define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr)) -# define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i)) -# define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp)) -# define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st) -# define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func)) -# define sk_ASN1_STRING_TABLE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_STRING_TABLE, (st), (copy_func), (free_func)) -# define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st)) -# define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st)) -# define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) -# define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) -# define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp)) -# define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) -# define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) -# define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) -# define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i)) -# define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val)) -# define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st)) -# define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val)) -# define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val)) -# define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val)) -# define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val)) -# define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i)) -# define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr)) -# define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i)) -# define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp)) -# define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st) -# define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func)) -# define sk_ASN1_TYPE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_TYPE, (st), (copy_func), (free_func)) -# define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st)) -# define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st)) -# define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) -# define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) -# define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp)) -# define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING) -# define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st)) -# define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st)) -# define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i)) -# define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val)) -# define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st)) -# define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val)) -# define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val)) -# define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val)) -# define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val)) -# define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i)) -# define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr)) -# define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i)) -# define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp)) -# define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st) -# define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func)) -# define sk_ASN1_UTF8STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_UTF8STRING, (st), (copy_func), (free_func)) -# define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st)) -# define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st)) -# define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st)) -# define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st)) -# define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp)) -# define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) -# define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) -# define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) -# define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i)) -# define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val)) -# define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st)) -# define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val)) -# define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val)) -# define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val)) -# define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val)) -# define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i)) -# define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr)) -# define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i)) -# define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp)) -# define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st) -# define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func)) -# define sk_ASN1_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ASN1_VALUE, (st), (copy_func), (free_func)) -# define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st)) -# define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st)) -# define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) -# define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) -# define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp)) -# define sk_BIO_new_null() SKM_sk_new_null(BIO) -# define sk_BIO_free(st) SKM_sk_free(BIO, (st)) -# define sk_BIO_num(st) SKM_sk_num(BIO, (st)) -# define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i)) -# define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val)) -# define sk_BIO_zero(st) SKM_sk_zero(BIO, (st)) -# define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val)) -# define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val)) -# define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val)) -# define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val)) -# define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i)) -# define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr)) -# define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i)) -# define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp)) -# define sk_BIO_dup(st) SKM_sk_dup(BIO, st) -# define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func)) -# define sk_BIO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BIO, (st), (copy_func), (free_func)) -# define sk_BIO_shift(st) SKM_sk_shift(BIO, (st)) -# define sk_BIO_pop(st) SKM_sk_pop(BIO, (st)) -# define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) -# define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) -# define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp)) -# define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY) -# define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st)) -# define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st)) -# define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i)) -# define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val)) -# define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st)) -# define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val)) -# define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val)) -# define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val)) -# define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val)) -# define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i)) -# define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr)) -# define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i)) -# define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp)) -# define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st) -# define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func)) -# define sk_BY_DIR_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_ENTRY, (st), (copy_func), (free_func)) -# define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st)) -# define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st)) -# define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st)) -# define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st)) -# define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp)) -# define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH) -# define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st)) -# define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st)) -# define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i)) -# define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val)) -# define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st)) -# define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val)) -# define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val)) -# define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val)) -# define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val)) -# define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i)) -# define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr)) -# define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i)) -# define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp)) -# define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st) -# define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func)) -# define sk_BY_DIR_HASH_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(BY_DIR_HASH, (st), (copy_func), (free_func)) -# define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st)) -# define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st)) -# define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st)) -# define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st)) -# define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp)) -# define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) -# define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) -# define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) -# define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i)) -# define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val)) -# define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st)) -# define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val)) -# define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val)) -# define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val)) -# define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val)) -# define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i)) -# define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr)) -# define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i)) -# define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp)) -# define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st) -# define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func)) -# define sk_CMS_CertificateChoices_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_CertificateChoices, (st), (copy_func), (free_func)) -# define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st)) -# define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st)) -# define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) -# define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) -# define sk_CMS_RecipientEncryptedKey_new(cmp) SKM_sk_new(CMS_RecipientEncryptedKey, (cmp)) -# define sk_CMS_RecipientEncryptedKey_new_null() SKM_sk_new_null(CMS_RecipientEncryptedKey) -# define sk_CMS_RecipientEncryptedKey_free(st) SKM_sk_free(CMS_RecipientEncryptedKey, (st)) -# define sk_CMS_RecipientEncryptedKey_num(st) SKM_sk_num(CMS_RecipientEncryptedKey, (st)) -# define sk_CMS_RecipientEncryptedKey_value(st, i) SKM_sk_value(CMS_RecipientEncryptedKey, (st), (i)) -# define sk_CMS_RecipientEncryptedKey_set(st, i, val) SKM_sk_set(CMS_RecipientEncryptedKey, (st), (i), (val)) -# define sk_CMS_RecipientEncryptedKey_zero(st) SKM_sk_zero(CMS_RecipientEncryptedKey, (st)) -# define sk_CMS_RecipientEncryptedKey_push(st, val) SKM_sk_push(CMS_RecipientEncryptedKey, (st), (val)) -# define sk_CMS_RecipientEncryptedKey_unshift(st, val) SKM_sk_unshift(CMS_RecipientEncryptedKey, (st), (val)) -# define sk_CMS_RecipientEncryptedKey_find(st, val) SKM_sk_find(CMS_RecipientEncryptedKey, (st), (val)) -# define sk_CMS_RecipientEncryptedKey_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientEncryptedKey, (st), (val)) -# define sk_CMS_RecipientEncryptedKey_delete(st, i) SKM_sk_delete(CMS_RecipientEncryptedKey, (st), (i)) -# define sk_CMS_RecipientEncryptedKey_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientEncryptedKey, (st), (ptr)) -# define sk_CMS_RecipientEncryptedKey_insert(st, val, i) SKM_sk_insert(CMS_RecipientEncryptedKey, (st), (val), (i)) -# define sk_CMS_RecipientEncryptedKey_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientEncryptedKey, (st), (cmp)) -# define sk_CMS_RecipientEncryptedKey_dup(st) SKM_sk_dup(CMS_RecipientEncryptedKey, st) -# define sk_CMS_RecipientEncryptedKey_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientEncryptedKey, (st), (free_func)) -# define sk_CMS_RecipientEncryptedKey_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientEncryptedKey, (st), (copy_func), (free_func)) -# define sk_CMS_RecipientEncryptedKey_shift(st) SKM_sk_shift(CMS_RecipientEncryptedKey, (st)) -# define sk_CMS_RecipientEncryptedKey_pop(st) SKM_sk_pop(CMS_RecipientEncryptedKey, (st)) -# define sk_CMS_RecipientEncryptedKey_sort(st) SKM_sk_sort(CMS_RecipientEncryptedKey, (st)) -# define sk_CMS_RecipientEncryptedKey_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientEncryptedKey, (st)) -# define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp)) -# define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) -# define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) -# define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) -# define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i)) -# define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val)) -# define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st)) -# define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val)) -# define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val)) -# define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val)) -# define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val)) -# define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i)) -# define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr)) -# define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i)) -# define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp)) -# define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st) -# define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func)) -# define sk_CMS_RecipientInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RecipientInfo, (st), (copy_func), (free_func)) -# define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st)) -# define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st)) -# define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) -# define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) -# define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp)) -# define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) -# define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) -# define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) -# define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i)) -# define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val)) -# define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st)) -# define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val)) -# define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val)) -# define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val)) -# define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val)) -# define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i)) -# define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr)) -# define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i)) -# define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp)) -# define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st) -# define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func)) -# define sk_CMS_RevocationInfoChoice_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_RevocationInfoChoice, (st), (copy_func), (free_func)) -# define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st)) -# define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st)) -# define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) -# define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) -# define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp)) -# define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) -# define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) -# define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) -# define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i)) -# define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val)) -# define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st)) -# define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val)) -# define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val)) -# define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val)) -# define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val)) -# define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i)) -# define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr)) -# define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i)) -# define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp)) -# define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st) -# define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func)) -# define sk_CMS_SignerInfo_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CMS_SignerInfo, (st), (copy_func), (free_func)) -# define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st)) -# define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st)) -# define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) -# define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) -# define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp)) -# define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) -# define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) -# define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) -# define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i)) -# define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val)) -# define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st)) -# define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val)) -# define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val)) -# define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val)) -# define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val)) -# define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i)) -# define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr)) -# define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i)) -# define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp)) -# define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st) -# define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func)) -# define sk_CONF_IMODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_IMODULE, (st), (copy_func), (free_func)) -# define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st)) -# define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st)) -# define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) -# define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) -# define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp)) -# define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) -# define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) -# define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) -# define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i)) -# define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val)) -# define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st)) -# define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val)) -# define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val)) -# define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val)) -# define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val)) -# define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i)) -# define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr)) -# define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i)) -# define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp)) -# define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st) -# define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func)) -# define sk_CONF_MODULE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_MODULE, (st), (copy_func), (free_func)) -# define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st)) -# define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st)) -# define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) -# define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) -# define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp)) -# define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) -# define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) -# define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) -# define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i)) -# define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val)) -# define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st)) -# define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val)) -# define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val)) -# define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val)) -# define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val)) -# define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i)) -# define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr)) -# define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i)) -# define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp)) -# define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st) -# define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func)) -# define sk_CONF_VALUE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CONF_VALUE, (st), (copy_func), (free_func)) -# define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st)) -# define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st)) -# define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) -# define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) -# define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp)) -# define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) -# define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st)) -# define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) -# define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i)) -# define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val)) -# define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st)) -# define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val)) -# define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val)) -# define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val)) -# define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val)) -# define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i)) -# define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr)) -# define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i)) -# define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp)) -# define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st) -# define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func)) -# define sk_CRYPTO_EX_DATA_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_EX_DATA_FUNCS, (st), (copy_func), (free_func)) -# define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st)) -# define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st)) -# define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st)) -# define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st)) -# define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp)) -# define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) -# define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) -# define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) -# define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i)) -# define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val)) -# define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st)) -# define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val)) -# define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val)) -# define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val)) -# define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val)) -# define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i)) -# define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr)) -# define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i)) -# define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp)) -# define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st) -# define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func)) -# define sk_CRYPTO_dynlock_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(CRYPTO_dynlock, (st), (copy_func), (free_func)) -# define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st)) -# define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st)) -# define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) -# define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) -# define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp)) -# define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) -# define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) -# define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) -# define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i)) -# define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val)) -# define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st)) -# define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val)) -# define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val)) -# define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val)) -# define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val)) -# define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i)) -# define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr)) -# define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i)) -# define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp)) -# define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st) -# define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func)) -# define sk_DIST_POINT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(DIST_POINT, (st), (copy_func), (free_func)) -# define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st)) -# define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st)) -# define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) -# define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) -# define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp)) -# define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE) -# define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st)) -# define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st)) -# define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i)) -# define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val)) -# define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st)) -# define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val)) -# define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val)) -# define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val)) -# define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val)) -# define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i)) -# define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr)) -# define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i)) -# define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp)) -# define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st) -# define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func)) -# define sk_ENGINE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE, (st), (copy_func), (free_func)) -# define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st)) -# define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st)) -# define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st)) -# define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st)) -# define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp)) -# define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM) -# define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st)) -# define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st)) -# define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i)) -# define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val)) -# define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st)) -# define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val)) -# define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val)) -# define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val)) -# define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val)) -# define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i)) -# define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr)) -# define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i)) -# define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp)) -# define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st) -# define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func)) -# define sk_ENGINE_CLEANUP_ITEM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ENGINE_CLEANUP_ITEM, (st), (copy_func), (free_func)) -# define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st)) -# define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st)) -# define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st)) -# define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st)) -# define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp)) -# define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID) -# define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st)) -# define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st)) -# define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i)) -# define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val)) -# define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st)) -# define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val)) -# define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val)) -# define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val)) -# define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val)) -# define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i)) -# define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr)) -# define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i)) -# define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp)) -# define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st) -# define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func)) -# define sk_ESS_CERT_ID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(ESS_CERT_ID, (st), (copy_func), (free_func)) -# define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st)) -# define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st)) -# define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st)) -# define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st)) -# define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp)) -# define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD) -# define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st)) -# define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st)) -# define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i)) -# define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val)) -# define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st)) -# define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val)) -# define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val)) -# define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val)) -# define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val)) -# define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i)) -# define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr)) -# define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i)) -# define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp)) -# define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st) -# define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func)) -# define sk_EVP_MD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_MD, (st), (copy_func), (free_func)) -# define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st)) -# define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st)) -# define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st)) -# define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st)) -# define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp)) -# define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL) -# define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st)) -# define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st)) -# define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i)) -# define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val)) -# define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st)) -# define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val)) -# define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val)) -# define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val)) -# define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val)) -# define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i)) -# define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr)) -# define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i)) -# define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp)) -# define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st) -# define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func)) -# define sk_EVP_PBE_CTL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PBE_CTL, (st), (copy_func), (free_func)) -# define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st)) -# define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st)) -# define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st)) -# define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st)) -# define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp)) -# define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD) -# define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st)) -# define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st)) -# define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i)) -# define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val)) -# define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st)) -# define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val)) -# define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val)) -# define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val)) -# define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val)) -# define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i)) -# define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr)) -# define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i)) -# define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp)) -# define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st) -# define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func)) -# define sk_EVP_PKEY_ASN1_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_ASN1_METHOD, (st), (copy_func), (free_func)) -# define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st)) -# define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st)) -# define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st)) -# define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st)) -# define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp)) -# define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD) -# define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st)) -# define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st)) -# define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i)) -# define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val)) -# define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st)) -# define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val)) -# define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val)) -# define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val)) -# define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val)) -# define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i)) -# define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr)) -# define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i)) -# define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp)) -# define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st) -# define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func)) -# define sk_EVP_PKEY_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(EVP_PKEY_METHOD, (st), (copy_func), (free_func)) -# define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st)) -# define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st)) -# define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st)) -# define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st)) -# define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp)) -# define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) -# define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) -# define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) -# define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i)) -# define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val)) -# define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st)) -# define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val)) -# define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val)) -# define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val)) -# define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val)) -# define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i)) -# define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr)) -# define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i)) -# define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp)) -# define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st) -# define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) -# define sk_GENERAL_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAME, (st), (copy_func), (free_func)) -# define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st)) -# define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st)) -# define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) -# define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) -# define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp)) -# define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) -# define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) -# define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) -# define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i)) -# define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val)) -# define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st)) -# define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val)) -# define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val)) -# define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val)) -# define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val)) -# define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i)) -# define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr)) -# define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i)) -# define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp)) -# define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st) -# define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func)) -# define sk_GENERAL_NAMES_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_NAMES, (st), (copy_func), (free_func)) -# define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st)) -# define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st)) -# define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) -# define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) -# define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp)) -# define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) -# define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) -# define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) -# define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i)) -# define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val)) -# define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st)) -# define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val)) -# define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val)) -# define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val)) -# define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val)) -# define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i)) -# define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr)) -# define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i)) -# define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp)) -# define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st) -# define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func)) -# define sk_GENERAL_SUBTREE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(GENERAL_SUBTREE, (st), (copy_func), (free_func)) -# define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st)) -# define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st)) -# define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) -# define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) -# define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp)) -# define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) -# define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) -# define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) -# define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i)) -# define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val)) -# define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st)) -# define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val)) -# define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val)) -# define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val)) -# define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val)) -# define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i)) -# define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr)) -# define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i)) -# define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp)) -# define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st) -# define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func)) -# define sk_IPAddressFamily_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressFamily, (st), (copy_func), (free_func)) -# define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st)) -# define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st)) -# define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) -# define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) -# define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp)) -# define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) -# define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) -# define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) -# define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i)) -# define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val)) -# define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st)) -# define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val)) -# define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val)) -# define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val)) -# define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val)) -# define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i)) -# define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr)) -# define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i)) -# define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp)) -# define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st) -# define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func)) -# define sk_IPAddressOrRange_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(IPAddressOrRange, (st), (copy_func), (free_func)) -# define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st)) -# define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st)) -# define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) -# define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) -# define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp)) -# define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY) -# define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st)) -# define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st)) -# define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i)) -# define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val)) -# define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st)) -# define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val)) -# define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val)) -# define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val)) -# define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val)) -# define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i)) -# define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr)) -# define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i)) -# define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp)) -# define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st) -# define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func)) -# define sk_KRB5_APREQBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_APREQBODY, (st), (copy_func), (free_func)) -# define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st)) -# define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st)) -# define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st)) -# define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st)) -# define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp)) -# define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA) -# define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st)) -# define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st)) -# define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i)) -# define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val)) -# define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st)) -# define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val)) -# define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val)) -# define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val)) -# define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val)) -# define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i)) -# define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr)) -# define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i)) -# define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp)) -# define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st) -# define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func)) -# define sk_KRB5_AUTHDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHDATA, (st), (copy_func), (free_func)) -# define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st)) -# define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st)) -# define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st)) -# define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st)) -# define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp)) -# define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY) -# define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st)) -# define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st)) -# define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i)) -# define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val)) -# define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st)) -# define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val)) -# define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val)) -# define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val)) -# define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val)) -# define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i)) -# define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr)) -# define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i)) -# define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp)) -# define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st) -# define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func)) -# define sk_KRB5_AUTHENTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_AUTHENTBODY, (st), (copy_func), (free_func)) -# define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st)) -# define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st)) -# define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st)) -# define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st)) -# define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp)) -# define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM) -# define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st)) -# define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st)) -# define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i)) -# define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val)) -# define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st)) -# define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val)) -# define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val)) -# define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val)) -# define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val)) -# define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i)) -# define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr)) -# define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i)) -# define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp)) -# define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st) -# define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func)) -# define sk_KRB5_CHECKSUM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_CHECKSUM, (st), (copy_func), (free_func)) -# define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st)) -# define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st)) -# define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st)) -# define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st)) -# define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp)) -# define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA) -# define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st)) -# define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st)) -# define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i)) -# define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val)) -# define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st)) -# define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val)) -# define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val)) -# define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val)) -# define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val)) -# define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i)) -# define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr)) -# define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i)) -# define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp)) -# define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st) -# define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func)) -# define sk_KRB5_ENCDATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCDATA, (st), (copy_func), (free_func)) -# define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st)) -# define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st)) -# define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st)) -# define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st)) -# define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp)) -# define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY) -# define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st)) -# define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st)) -# define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i)) -# define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val)) -# define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st)) -# define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val)) -# define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val)) -# define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val)) -# define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val)) -# define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i)) -# define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr)) -# define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i)) -# define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp)) -# define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st) -# define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func)) -# define sk_KRB5_ENCKEY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_ENCKEY, (st), (copy_func), (free_func)) -# define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st)) -# define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st)) -# define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st)) -# define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st)) -# define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp)) -# define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME) -# define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st)) -# define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st)) -# define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i)) -# define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val)) -# define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st)) -# define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val)) -# define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val)) -# define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val)) -# define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val)) -# define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i)) -# define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr)) -# define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i)) -# define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp)) -# define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st) -# define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func)) -# define sk_KRB5_PRINCNAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_PRINCNAME, (st), (copy_func), (free_func)) -# define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st)) -# define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st)) -# define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st)) -# define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st)) -# define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp)) -# define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY) -# define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st)) -# define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st)) -# define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i)) -# define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val)) -# define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st)) -# define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val)) -# define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val)) -# define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val)) -# define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val)) -# define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i)) -# define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr)) -# define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i)) -# define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp)) -# define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st) -# define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func)) -# define sk_KRB5_TKTBODY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(KRB5_TKTBODY, (st), (copy_func), (free_func)) -# define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st)) -# define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st)) -# define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st)) -# define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st)) -# define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp)) -# define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA) -# define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st)) -# define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st)) -# define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i)) -# define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val)) -# define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st)) -# define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val)) -# define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val)) -# define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val)) -# define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val)) -# define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i)) -# define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr)) -# define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i)) -# define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp)) -# define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st) -# define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func)) -# define sk_MEM_OBJECT_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MEM_OBJECT_DATA, (st), (copy_func), (free_func)) -# define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st)) -# define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st)) -# define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st)) -# define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st)) -# define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp)) -# define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) -# define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) -# define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) -# define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i)) -# define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val)) -# define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st)) -# define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val)) -# define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val)) -# define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val)) -# define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val)) -# define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i)) -# define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr)) -# define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i)) -# define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp)) -# define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st) -# define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func)) -# define sk_MIME_HEADER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_HEADER, (st), (copy_func), (free_func)) -# define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st)) -# define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st)) -# define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) -# define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) -# define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp)) -# define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) -# define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) -# define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) -# define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i)) -# define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val)) -# define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st)) -# define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val)) -# define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val)) -# define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val)) -# define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val)) -# define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i)) -# define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr)) -# define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i)) -# define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp)) -# define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st) -# define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func)) -# define sk_MIME_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(MIME_PARAM, (st), (copy_func), (free_func)) -# define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st)) -# define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st)) -# define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) -# define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) -# define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp)) -# define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) -# define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) -# define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) -# define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i)) -# define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val)) -# define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st)) -# define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val)) -# define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val)) -# define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val)) -# define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val)) -# define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i)) -# define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr)) -# define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i)) -# define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp)) -# define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st) -# define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func)) -# define sk_NAME_FUNCS_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(NAME_FUNCS, (st), (copy_func), (free_func)) -# define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st)) -# define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st)) -# define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) -# define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) -# define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp)) -# define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) -# define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) -# define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) -# define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i)) -# define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val)) -# define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st)) -# define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val)) -# define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val)) -# define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val)) -# define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val)) -# define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i)) -# define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr)) -# define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i)) -# define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp)) -# define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st) -# define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func)) -# define sk_OCSP_CERTID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_CERTID, (st), (copy_func), (free_func)) -# define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st)) -# define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st)) -# define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) -# define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) -# define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp)) -# define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) -# define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) -# define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) -# define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i)) -# define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val)) -# define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st)) -# define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val)) -# define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val)) -# define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val)) -# define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val)) -# define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i)) -# define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr)) -# define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i)) -# define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp)) -# define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st) -# define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func)) -# define sk_OCSP_ONEREQ_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_ONEREQ, (st), (copy_func), (free_func)) -# define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st)) -# define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st)) -# define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) -# define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) -# define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp)) -# define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) -# define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) -# define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) -# define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i)) -# define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val)) -# define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st)) -# define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val)) -# define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val)) -# define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val)) -# define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val)) -# define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i)) -# define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr)) -# define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i)) -# define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp)) -# define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st) -# define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func)) -# define sk_OCSP_RESPID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_RESPID, (st), (copy_func), (free_func)) -# define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st)) -# define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st)) -# define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) -# define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) -# define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp)) -# define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) -# define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) -# define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) -# define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i)) -# define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val)) -# define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st)) -# define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val)) -# define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val)) -# define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val)) -# define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val)) -# define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i)) -# define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr)) -# define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i)) -# define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp)) -# define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st) -# define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func)) -# define sk_OCSP_SINGLERESP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(OCSP_SINGLERESP, (st), (copy_func), (free_func)) -# define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st)) -# define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st)) -# define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) -# define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) -# define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp)) -# define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) -# define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) -# define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) -# define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i)) -# define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val)) -# define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st)) -# define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val)) -# define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val)) -# define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val)) -# define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val)) -# define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i)) -# define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr)) -# define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i)) -# define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp)) -# define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st) -# define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func)) -# define sk_PKCS12_SAFEBAG_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS12_SAFEBAG, (st), (copy_func), (free_func)) -# define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st)) -# define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st)) -# define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) -# define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) -# define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp)) -# define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) -# define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) -# define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) -# define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i)) -# define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val)) -# define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st)) -# define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val)) -# define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val)) -# define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val)) -# define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val)) -# define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i)) -# define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr)) -# define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i)) -# define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp)) -# define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st) -# define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func)) -# define sk_PKCS7_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7, (st), (copy_func), (free_func)) -# define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st)) -# define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st)) -# define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) -# define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) -# define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp)) -# define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) -# define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) -# define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) -# define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i)) -# define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val)) -# define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st)) -# define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val)) -# define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val)) -# define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val)) -# define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val)) -# define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i)) -# define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr)) -# define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i)) -# define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp)) -# define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st) -# define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func)) -# define sk_PKCS7_RECIP_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_RECIP_INFO, (st), (copy_func), (free_func)) -# define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st)) -# define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st)) -# define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) -# define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) -# define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp)) -# define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) -# define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) -# define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) -# define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i)) -# define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val)) -# define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st)) -# define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val)) -# define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val)) -# define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val)) -# define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val)) -# define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i)) -# define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr)) -# define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i)) -# define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp)) -# define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st) -# define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func)) -# define sk_PKCS7_SIGNER_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(PKCS7_SIGNER_INFO, (st), (copy_func), (free_func)) -# define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st)) -# define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st)) -# define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) -# define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) -# define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp)) -# define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) -# define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) -# define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) -# define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i)) -# define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val)) -# define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st)) -# define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val)) -# define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val)) -# define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val)) -# define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val)) -# define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i)) -# define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr)) -# define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i)) -# define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp)) -# define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st) -# define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func)) -# define sk_POLICYINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYINFO, (st), (copy_func), (free_func)) -# define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st)) -# define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st)) -# define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) -# define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) -# define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp)) -# define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) -# define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) -# define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) -# define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i)) -# define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val)) -# define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st)) -# define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val)) -# define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val)) -# define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val)) -# define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val)) -# define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i)) -# define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr)) -# define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i)) -# define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp)) -# define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st) -# define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func)) -# define sk_POLICYQUALINFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICYQUALINFO, (st), (copy_func), (free_func)) -# define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st)) -# define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st)) -# define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) -# define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) -# define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp)) -# define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) -# define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) -# define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) -# define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i)) -# define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val)) -# define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st)) -# define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val)) -# define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val)) -# define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val)) -# define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val)) -# define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i)) -# define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr)) -# define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i)) -# define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp)) -# define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st) -# define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func)) -# define sk_POLICY_MAPPING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(POLICY_MAPPING, (st), (copy_func), (free_func)) -# define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st)) -# define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st)) -# define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) -# define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) -# define sk_SCT_new(cmp) SKM_sk_new(SCT, (cmp)) -# define sk_SCT_new_null() SKM_sk_new_null(SCT) -# define sk_SCT_free(st) SKM_sk_free(SCT, (st)) -# define sk_SCT_num(st) SKM_sk_num(SCT, (st)) -# define sk_SCT_value(st, i) SKM_sk_value(SCT, (st), (i)) -# define sk_SCT_set(st, i, val) SKM_sk_set(SCT, (st), (i), (val)) -# define sk_SCT_zero(st) SKM_sk_zero(SCT, (st)) -# define sk_SCT_push(st, val) SKM_sk_push(SCT, (st), (val)) -# define sk_SCT_unshift(st, val) SKM_sk_unshift(SCT, (st), (val)) -# define sk_SCT_find(st, val) SKM_sk_find(SCT, (st), (val)) -# define sk_SCT_find_ex(st, val) SKM_sk_find_ex(SCT, (st), (val)) -# define sk_SCT_delete(st, i) SKM_sk_delete(SCT, (st), (i)) -# define sk_SCT_delete_ptr(st, ptr) SKM_sk_delete_ptr(SCT, (st), (ptr)) -# define sk_SCT_insert(st, val, i) SKM_sk_insert(SCT, (st), (val), (i)) -# define sk_SCT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SCT, (st), (cmp)) -# define sk_SCT_dup(st) SKM_sk_dup(SCT, st) -# define sk_SCT_pop_free(st, free_func) SKM_sk_pop_free(SCT, (st), (free_func)) -# define sk_SCT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SCT, (st), (copy_func), (free_func)) -# define sk_SCT_shift(st) SKM_sk_shift(SCT, (st)) -# define sk_SCT_pop(st) SKM_sk_pop(SCT, (st)) -# define sk_SCT_sort(st) SKM_sk_sort(SCT, (st)) -# define sk_SCT_is_sorted(st) SKM_sk_is_sorted(SCT, (st)) -# define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp)) -# define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN) -# define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st)) -# define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st)) -# define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i)) -# define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val)) -# define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st)) -# define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val)) -# define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val)) -# define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val)) -# define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val)) -# define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i)) -# define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr)) -# define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i)) -# define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp)) -# define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st) -# define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func)) -# define sk_SRP_gN_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN, (st), (copy_func), (free_func)) -# define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st)) -# define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st)) -# define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st)) -# define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st)) -# define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp)) -# define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache) -# define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st)) -# define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st)) -# define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i)) -# define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val)) -# define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st)) -# define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val)) -# define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val)) -# define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val)) -# define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val)) -# define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i)) -# define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr)) -# define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i)) -# define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp)) -# define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st) -# define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func)) -# define sk_SRP_gN_cache_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_gN_cache, (st), (copy_func), (free_func)) -# define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st)) -# define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st)) -# define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st)) -# define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st)) -# define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp)) -# define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd) -# define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st)) -# define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st)) -# define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i)) -# define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val)) -# define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st)) -# define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val)) -# define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val)) -# define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val)) -# define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val)) -# define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i)) -# define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr)) -# define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i)) -# define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp)) -# define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st) -# define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func)) -# define sk_SRP_user_pwd_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRP_user_pwd, (st), (copy_func), (free_func)) -# define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st)) -# define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st)) -# define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st)) -# define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st)) -# define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp)) -# define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE) -# define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st)) -# define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st)) -# define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i)) -# define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val)) -# define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st)) -# define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val)) -# define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val)) -# define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val)) -# define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val)) -# define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i)) -# define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr)) -# define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i)) -# define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp)) -# define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st) -# define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func)) -# define sk_SRTP_PROTECTION_PROFILE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SRTP_PROTECTION_PROFILE, (st), (copy_func), (free_func)) -# define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st)) -# define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st)) -# define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st)) -# define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st)) -# define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) -# define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) -# define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) -# define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) -# define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i)) -# define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val)) -# define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st)) -# define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val)) -# define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val)) -# define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val)) -# define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val)) -# define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i)) -# define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr)) -# define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i)) -# define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp)) -# define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st) -# define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func)) -# define sk_SSL_CIPHER_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_CIPHER, (st), (copy_func), (free_func)) -# define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st)) -# define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st)) -# define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) -# define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) -# define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp)) -# define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) -# define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) -# define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) -# define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i)) -# define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val)) -# define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st)) -# define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val)) -# define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val)) -# define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val)) -# define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val)) -# define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i)) -# define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr)) -# define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i)) -# define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp)) -# define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st) -# define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func)) -# define sk_SSL_COMP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SSL_COMP, (st), (copy_func), (free_func)) -# define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st)) -# define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st)) -# define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) -# define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) -# define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp)) -# define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY) -# define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st)) -# define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st)) -# define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i)) -# define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val)) -# define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st)) -# define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val)) -# define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val)) -# define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val)) -# define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val)) -# define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i)) -# define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr)) -# define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i)) -# define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp)) -# define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st) -# define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func)) -# define sk_STACK_OF_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STACK_OF_X509_NAME_ENTRY, (st), (copy_func), (free_func)) -# define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st)) -# define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st)) -# define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st)) -# define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st)) -# define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp)) -# define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO) -# define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st)) -# define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st)) -# define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i)) -# define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val)) -# define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st)) -# define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val)) -# define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val)) -# define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val)) -# define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val)) -# define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i)) -# define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr)) -# define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i)) -# define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp)) -# define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st) -# define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func)) -# define sk_STORE_ATTR_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_ATTR_INFO, (st), (copy_func), (free_func)) -# define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st)) -# define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st)) -# define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st)) -# define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st)) -# define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp)) -# define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) -# define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) -# define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) -# define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i)) -# define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val)) -# define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st)) -# define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val)) -# define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val)) -# define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val)) -# define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val)) -# define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i)) -# define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr)) -# define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i)) -# define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp)) -# define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st) -# define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func)) -# define sk_STORE_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(STORE_OBJECT, (st), (copy_func), (free_func)) -# define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st)) -# define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st)) -# define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) -# define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) -# define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp)) -# define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID) -# define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st)) -# define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st)) -# define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i)) -# define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val)) -# define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st)) -# define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val)) -# define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val)) -# define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val)) -# define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val)) -# define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i)) -# define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr)) -# define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i)) -# define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp)) -# define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st) -# define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func)) -# define sk_SXNETID_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(SXNETID, (st), (copy_func), (free_func)) -# define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st)) -# define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st)) -# define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st)) -# define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st)) -# define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp)) -# define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) -# define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) -# define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) -# define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i)) -# define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val)) -# define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st)) -# define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val)) -# define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val)) -# define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val)) -# define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val)) -# define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i)) -# define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr)) -# define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i)) -# define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp)) -# define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st) -# define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func)) -# define sk_UI_STRING_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(UI_STRING, (st), (copy_func), (free_func)) -# define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st)) -# define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st)) -# define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) -# define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) -# define sk_X509_new(cmp) SKM_sk_new(X509, (cmp)) -# define sk_X509_new_null() SKM_sk_new_null(X509) -# define sk_X509_free(st) SKM_sk_free(X509, (st)) -# define sk_X509_num(st) SKM_sk_num(X509, (st)) -# define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i)) -# define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val)) -# define sk_X509_zero(st) SKM_sk_zero(X509, (st)) -# define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val)) -# define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val)) -# define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val)) -# define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val)) -# define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i)) -# define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr)) -# define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i)) -# define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp)) -# define sk_X509_dup(st) SKM_sk_dup(X509, st) -# define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func)) -# define sk_X509_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509, (st), (copy_func), (free_func)) -# define sk_X509_shift(st) SKM_sk_shift(X509, (st)) -# define sk_X509_pop(st) SKM_sk_pop(X509, (st)) -# define sk_X509_sort(st) SKM_sk_sort(X509, (st)) -# define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) -# define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp)) -# define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) -# define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) -# define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) -# define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i)) -# define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val)) -# define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st)) -# define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val)) -# define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val)) -# define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val)) -# define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val)) -# define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i)) -# define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr)) -# define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i)) -# define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp)) -# define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st) -# define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func)) -# define sk_X509V3_EXT_METHOD_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509V3_EXT_METHOD, (st), (copy_func), (free_func)) -# define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st)) -# define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st)) -# define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) -# define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) -# define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp)) -# define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) -# define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) -# define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) -# define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i)) -# define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val)) -# define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st)) -# define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val)) -# define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val)) -# define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val)) -# define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val)) -# define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i)) -# define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr)) -# define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i)) -# define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp)) -# define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st) -# define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func)) -# define sk_X509_ALGOR_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ALGOR, (st), (copy_func), (free_func)) -# define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st)) -# define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st)) -# define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) -# define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) -# define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp)) -# define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) -# define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) -# define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) -# define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i)) -# define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val)) -# define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st)) -# define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val)) -# define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val)) -# define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val)) -# define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val)) -# define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i)) -# define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr)) -# define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i)) -# define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp)) -# define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st) -# define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func)) -# define sk_X509_ATTRIBUTE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_ATTRIBUTE, (st), (copy_func), (free_func)) -# define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st)) -# define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st)) -# define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) -# define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) -# define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp)) -# define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) -# define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) -# define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) -# define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i)) -# define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val)) -# define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st)) -# define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val)) -# define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val)) -# define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val)) -# define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val)) -# define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i)) -# define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr)) -# define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i)) -# define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp)) -# define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st) -# define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func)) -# define sk_X509_CRL_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_CRL, (st), (copy_func), (free_func)) -# define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st)) -# define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st)) -# define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) -# define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) -# define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp)) -# define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) -# define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) -# define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) -# define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i)) -# define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val)) -# define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st)) -# define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val)) -# define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val)) -# define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val)) -# define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val)) -# define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i)) -# define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr)) -# define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i)) -# define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp)) -# define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st) -# define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func)) -# define sk_X509_EXTENSION_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_EXTENSION, (st), (copy_func), (free_func)) -# define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st)) -# define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st)) -# define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) -# define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) -# define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp)) -# define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) -# define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) -# define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) -# define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i)) -# define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val)) -# define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st)) -# define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val)) -# define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val)) -# define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val)) -# define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val)) -# define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i)) -# define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr)) -# define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i)) -# define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp)) -# define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st) -# define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func)) -# define sk_X509_INFO_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_INFO, (st), (copy_func), (free_func)) -# define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st)) -# define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st)) -# define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) -# define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) -# define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp)) -# define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) -# define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) -# define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) -# define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i)) -# define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val)) -# define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st)) -# define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val)) -# define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val)) -# define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val)) -# define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val)) -# define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i)) -# define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr)) -# define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i)) -# define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp)) -# define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st) -# define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func)) -# define sk_X509_LOOKUP_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_LOOKUP, (st), (copy_func), (free_func)) -# define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st)) -# define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st)) -# define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) -# define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) -# define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp)) -# define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) -# define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) -# define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) -# define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i)) -# define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val)) -# define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st)) -# define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val)) -# define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val)) -# define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val)) -# define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val)) -# define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i)) -# define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr)) -# define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i)) -# define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp)) -# define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st) -# define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func)) -# define sk_X509_NAME_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME, (st), (copy_func), (free_func)) -# define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st)) -# define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st)) -# define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) -# define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) -# define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp)) -# define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) -# define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) -# define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) -# define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i)) -# define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val)) -# define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st)) -# define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val)) -# define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val)) -# define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val)) -# define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val)) -# define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i)) -# define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr)) -# define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i)) -# define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp)) -# define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st) -# define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func)) -# define sk_X509_NAME_ENTRY_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_NAME_ENTRY, (st), (copy_func), (free_func)) -# define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st)) -# define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st)) -# define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) -# define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) -# define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp)) -# define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) -# define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) -# define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) -# define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i)) -# define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val)) -# define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st)) -# define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val)) -# define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val)) -# define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val)) -# define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val)) -# define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i)) -# define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr)) -# define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i)) -# define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp)) -# define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st) -# define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func)) -# define sk_X509_OBJECT_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_OBJECT, (st), (copy_func), (free_func)) -# define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st)) -# define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st)) -# define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) -# define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) -# define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp)) -# define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA) -# define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st)) -# define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st)) -# define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i)) -# define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val)) -# define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st)) -# define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val)) -# define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val)) -# define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val)) -# define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val)) -# define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i)) -# define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr)) -# define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i)) -# define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp)) -# define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st) -# define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func)) -# define sk_X509_POLICY_DATA_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_DATA, (st), (copy_func), (free_func)) -# define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st)) -# define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st)) -# define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st)) -# define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st)) -# define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) -# define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) -# define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) -# define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) -# define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i)) -# define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val)) -# define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st)) -# define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val)) -# define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val)) -# define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val)) -# define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val)) -# define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i)) -# define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr)) -# define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i)) -# define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp)) -# define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st) -# define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func)) -# define sk_X509_POLICY_NODE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_POLICY_NODE, (st), (copy_func), (free_func)) -# define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st)) -# define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st)) -# define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) -# define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) -# define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp)) -# define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) -# define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) -# define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) -# define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i)) -# define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val)) -# define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st)) -# define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val)) -# define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val)) -# define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val)) -# define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val)) -# define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i)) -# define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr)) -# define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i)) -# define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp)) -# define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st) -# define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func)) -# define sk_X509_PURPOSE_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_PURPOSE, (st), (copy_func), (free_func)) -# define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st)) -# define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st)) -# define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) -# define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) -# define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp)) -# define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) -# define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) -# define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) -# define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i)) -# define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val)) -# define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st)) -# define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val)) -# define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val)) -# define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val)) -# define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val)) -# define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i)) -# define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr)) -# define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i)) -# define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp)) -# define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st) -# define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func)) -# define sk_X509_REVOKED_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_REVOKED, (st), (copy_func), (free_func)) -# define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st)) -# define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st)) -# define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) -# define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) -# define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp)) -# define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) -# define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) -# define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) -# define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i)) -# define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val)) -# define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st)) -# define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val)) -# define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val)) -# define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val)) -# define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val)) -# define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i)) -# define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr)) -# define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i)) -# define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp)) -# define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st) -# define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func)) -# define sk_X509_TRUST_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_TRUST, (st), (copy_func), (free_func)) -# define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st)) -# define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st)) -# define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) -# define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) -# define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp)) -# define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) -# define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) -# define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) -# define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i)) -# define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val)) -# define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st)) -# define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val)) -# define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val)) -# define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val)) -# define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val)) -# define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i)) -# define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr)) -# define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i)) -# define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp)) -# define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st) -# define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func)) -# define sk_X509_VERIFY_PARAM_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(X509_VERIFY_PARAM, (st), (copy_func), (free_func)) -# define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st)) -# define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st)) -# define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) -# define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) -# define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp)) -# define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple) -# define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st)) -# define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st)) -# define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i)) -# define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val)) -# define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st)) -# define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val)) -# define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val)) -# define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val)) -# define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val)) -# define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i)) -# define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr)) -# define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i)) -# define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp)) -# define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st) -# define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func)) -# define sk_nid_triple_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(nid_triple, (st), (copy_func), (free_func)) -# define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st)) -# define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st)) -# define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st)) -# define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st)) -# define sk_void_new(cmp) SKM_sk_new(void, (cmp)) -# define sk_void_new_null() SKM_sk_new_null(void) -# define sk_void_free(st) SKM_sk_free(void, (st)) -# define sk_void_num(st) SKM_sk_num(void, (st)) -# define sk_void_value(st, i) SKM_sk_value(void, (st), (i)) -# define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val)) -# define sk_void_zero(st) SKM_sk_zero(void, (st)) -# define sk_void_push(st, val) SKM_sk_push(void, (st), (val)) -# define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val)) -# define sk_void_find(st, val) SKM_sk_find(void, (st), (val)) -# define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val)) -# define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i)) -# define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr)) -# define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i)) -# define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp)) -# define sk_void_dup(st) SKM_sk_dup(void, st) -# define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func)) -# define sk_void_deep_copy(st, copy_func, free_func) SKM_sk_deep_copy(void, (st), (copy_func), (free_func)) -# define sk_void_shift(st) SKM_sk_shift(void, (st)) -# define sk_void_pop(st) SKM_sk_pop(void, (st)) -# define sk_void_sort(st) SKM_sk_sort(void, (st)) -# define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st)) -# define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp))) -# define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null()) -# define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) -# define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) -# define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i)) -# define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st) -# define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC(char, free_func)) -# define sk_OPENSSL_STRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_STRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_COPY_FUNC(char, copy_func), CHECKED_SK_FREE_FUNC(char, free_func))) -# define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i) -# define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st) -# define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val)) -# define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st)) -# define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) -# define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val)) -# define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i)) -# define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr)) -# define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \ - ((int (*)(const char * const *,const char * const *)) \ - sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp))) -# define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st) -# define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st)) -# define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st)) -# define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st)) -# define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st)) -# define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp))) -# define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null()) -# define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) -# define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) -# define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i)) -# define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st) -# define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC(void, free_func)) -# define sk_OPENSSL_BLOCK_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_BLOCK) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_COPY_FUNC(void, copy_func), CHECKED_SK_FREE_FUNC(void, free_func))) -# define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i) -# define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st) -# define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val)) -# define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st)) -# define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) -# define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val)) -# define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i)) -# define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr)) -# define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \ - ((int (*)(const void * const *,const void * const *)) \ - sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp))) -# define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st) -# define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st)) -# define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st)) -# define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st)) -# define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st)) -# define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) -# define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null()) -# define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) -# define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) -# define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i)) -# define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st) -# define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func)) -# define sk_OPENSSL_PSTRING_deep_copy(st, copy_func, free_func) ((STACK_OF(OPENSSL_PSTRING) *)sk_deep_copy(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_COPY_FUNC(OPENSSL_STRING, copy_func), CHECKED_SK_FREE_FUNC(OPENSSL_STRING, free_func))) -# define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i) -# define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st) -# define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val)) -# define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st)) -# define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) -# define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val)) -# define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i)) -# define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr)) -# define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \ - ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \ - sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) -# define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st) -# define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st)) -# define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st)) -# define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st)) -# define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st)) -# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_X509(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func)) -# define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ - SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) -# define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \ - SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) -# define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \ - SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len)) -# define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \ - SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func)) -# define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \ - SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) -# define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \ - SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) -# define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj) -# define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst) -# define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst) -# define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst) -# define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn) -# define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg) -# define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh) -# define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh) -# define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh) -# define lh_ADDED_OBJ_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(ADDED_OBJ,lh,out) -# define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out) -# define lh_ADDED_OBJ_stats_bio(lh,out) \ - LHM_lh_stats_bio(ADDED_OBJ,lh,out) -# define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh) -# define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info) -# define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst) -# define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst) -# define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst) -# define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn) -# define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg) -# define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh) -# define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh) -# define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh) -# define lh_APP_INFO_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(APP_INFO,lh,out) -# define lh_APP_INFO_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(APP_INFO,lh,out) -# define lh_APP_INFO_stats_bio(lh,out) \ - LHM_lh_stats_bio(APP_INFO,lh,out) -# define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh) -# define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value) -# define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst) -# define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst) -# define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst) -# define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn) -# define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg) -# define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh) -# define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh) -# define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh) -# define lh_CONF_VALUE_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(CONF_VALUE,lh,out) -# define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out) -# define lh_CONF_VALUE_stats_bio(lh,out) \ - LHM_lh_stats_bio(CONF_VALUE,lh,out) -# define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh) -# define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile) -# define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst) -# define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst) -# define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst) -# define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn) -# define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg) -# define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh) -# define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh) -# define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh) -# define lh_ENGINE_PILE_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(ENGINE_PILE,lh,out) -# define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out) -# define lh_ENGINE_PILE_stats_bio(lh,out) \ - LHM_lh_stats_bio(ENGINE_PILE,lh,out) -# define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh) -# define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state) -# define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst) -# define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst) -# define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst) -# define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn) -# define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg) -# define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh) -# define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh) -# define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh) -# define lh_ERR_STATE_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(ERR_STATE,lh,out) -# define lh_ERR_STATE_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out) -# define lh_ERR_STATE_stats_bio(lh,out) \ - LHM_lh_stats_bio(ERR_STATE,lh,out) -# define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh) -# define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data) -# define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst) -# define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst) -# define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst) -# define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn) -# define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg) -# define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh) -# define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh) -# define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh) -# define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out) -# define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out) -# define lh_ERR_STRING_DATA_stats_bio(lh,out) \ - LHM_lh_stats_bio(ERR_STRING_DATA,lh,out) -# define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh) -# define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item) -# define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst) -# define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst) -# define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst) -# define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn) -# define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg) -# define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh) -# define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh) -# define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh) -# define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out) -# define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out) -# define lh_EX_CLASS_ITEM_stats_bio(lh,out) \ - LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out) -# define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh) -# define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function) -# define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst) -# define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst) -# define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst) -# define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn) -# define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg) -# define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh) -# define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh) -# define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh) -# define lh_FUNCTION_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(FUNCTION,lh,out) -# define lh_FUNCTION_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(FUNCTION,lh,out) -# define lh_FUNCTION_stats_bio(lh,out) \ - LHM_lh_stats_bio(FUNCTION,lh,out) -# define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh) -# define lh_MEM_new() LHM_lh_new(MEM,mem) -# define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst) -# define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst) -# define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst) -# define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn) -# define lh_MEM_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg) -# define lh_MEM_error(lh) LHM_lh_error(MEM,lh) -# define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh) -# define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh) -# define lh_MEM_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(MEM,lh,out) -# define lh_MEM_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(MEM,lh,out) -# define lh_MEM_stats_bio(lh,out) \ - LHM_lh_stats_bio(MEM,lh,out) -# define lh_MEM_free(lh) LHM_lh_free(MEM,lh) -# define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name) -# define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst) -# define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst) -# define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst) -# define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn) -# define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg) -# define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh) -# define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh) -# define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh) -# define lh_OBJ_NAME_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(OBJ_NAME,lh,out) -# define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out) -# define lh_OBJ_NAME_stats_bio(lh,out) \ - LHM_lh_stats_bio(OBJ_NAME,lh,out) -# define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh) -# define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring) -# define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst) -# define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst) -# define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst) -# define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn) -# define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg) -# define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh) -# define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh) -# define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh) -# define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out) -# define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out) -# define lh_OPENSSL_CSTRING_stats_bio(lh,out) \ - LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out) -# define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh) -# define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string) -# define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst) -# define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst) -# define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst) -# define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn) -# define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg) -# define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh) -# define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh) -# define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh) -# define lh_OPENSSL_STRING_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out) -# define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out) -# define lh_OPENSSL_STRING_stats_bio(lh,out) \ - LHM_lh_stats_bio(OPENSSL_STRING,lh,out) -# define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh) -# define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session) -# define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst) -# define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst) -# define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst) -# define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn) -# define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \ - LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg) -# define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh) -# define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh) -# define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh) -# define lh_SSL_SESSION_node_stats_bio(lh,out) \ - LHM_lh_node_stats_bio(SSL_SESSION,lh,out) -# define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \ - LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out) -# define lh_SSL_SESSION_stats_bio(lh,out) \ - LHM_lh_stats_bio(SSL_SESSION,lh,out) -# define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh) -#ifdef __cplusplus -} -#endif -#endif /* !defined HEADER_SAFESTACK_H */ diff --git a/Sources/COpenSSL/seed.c b/Sources/COpenSSL/seed.c deleted file mode 100644 index 79d2f6f1..00000000 --- a/Sources/COpenSSL/seed.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of author nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#ifndef OPENSSL_NO_SEED - -# include -# include -# include -# ifdef WIN32 -# include -# endif - -# include "crypto.h" -# include "seed.h" -# include "seed_locl.h" - -# ifdef SS /* can get defined on Solaris by inclusion of - * */ -# undef SS -# endif - -static const seed_word SS[4][256] = { { - 0x2989a1a8, 0x05858184, 0x16c6d2d4, - 0x13c3d3d0, 0x14445054, 0x1d0d111c, - 0x2c8ca0ac, 0x25052124, - 0x1d4d515c, 0x03434340, 0x18081018, - 0x1e0e121c, 0x11415150, 0x3cccf0fc, - 0x0acac2c8, 0x23436360, - 0x28082028, 0x04444044, 0x20002020, - 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, - 0x08c8c0c8, 0x17071314, - 0x2585a1a4, 0x0f8f838c, 0x03030300, - 0x3b4b7378, 0x3b8bb3b8, 0x13031310, - 0x12c2d2d0, 0x2ecee2ec, - 0x30407070, 0x0c8c808c, 0x3f0f333c, - 0x2888a0a8, 0x32023230, 0x1dcdd1dc, - 0x36c6f2f4, 0x34447074, - 0x2ccce0ec, 0x15859194, 0x0b0b0308, - 0x17475354, 0x1c4c505c, 0x1b4b5358, - 0x3d8db1bc, 0x01010100, - 0x24042024, 0x1c0c101c, 0x33437370, - 0x18889098, 0x10001010, 0x0cccc0cc, - 0x32c2f2f0, 0x19c9d1d8, - 0x2c0c202c, 0x27c7e3e4, 0x32427270, - 0x03838380, 0x1b8b9398, 0x11c1d1d0, - 0x06868284, 0x09c9c1c8, - 0x20406060, 0x10405050, 0x2383a3a0, - 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, - 0x1e8e929c, 0x0f4f434c, - 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, - 0x38487078, 0x2686a2a4, 0x12021210, - 0x2f8fa3ac, 0x15c5d1d4, - 0x21416160, 0x03c3c3c0, 0x3484b0b4, - 0x01414140, 0x12425250, 0x3d4d717c, - 0x0d8d818c, 0x08080008, - 0x1f0f131c, 0x19899198, 0x00000000, - 0x19091118, 0x04040004, 0x13435350, - 0x37c7f3f4, 0x21c1e1e0, - 0x3dcdf1fc, 0x36467274, 0x2f0f232c, - 0x27072324, 0x3080b0b0, 0x0b8b8388, - 0x0e0e020c, 0x2b8ba3a8, - 0x2282a2a0, 0x2e4e626c, 0x13839390, - 0x0d4d414c, 0x29496168, 0x3c4c707c, - 0x09090108, 0x0a0a0208, - 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, - 0x05c5c1c4, 0x07878384, 0x14041014, - 0x3ecef2fc, 0x24446064, - 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, - 0x1a0a1218, 0x06060204, 0x21012120, - 0x2b4b6368, 0x26466264, - 0x02020200, 0x35c5f1f4, 0x12829290, - 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, - 0x3e4e727c, 0x10c0d0d0, - 0x3a4a7278, 0x07474344, 0x16869294, - 0x25c5e1e4, 0x26062224, 0x00808080, - 0x2d8da1ac, 0x1fcfd3dc, - 0x2181a1a0, 0x30003030, 0x37073334, - 0x2e8ea2ac, 0x36063234, 0x15051114, - 0x22022220, 0x38083038, - 0x34c4f0f4, 0x2787a3a4, 0x05454144, - 0x0c4c404c, 0x01818180, 0x29c9e1e8, - 0x04848084, 0x17879394, - 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, - 0x3c0c303c, 0x31417170, 0x11011110, - 0x07c7c3c4, 0x09898188, - 0x35457174, 0x3bcbf3f8, 0x1acad2d8, - 0x38c8f0f8, 0x14849094, 0x19495158, - 0x02828280, 0x04c4c0c4, - 0x3fcff3fc, 0x09494148, 0x39093138, - 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, - 0x17c7d3d4, 0x3888b0b8, - 0x0f0f030c, 0x0e8e828c, 0x02424240, - 0x23032320, 0x11819190, 0x2c4c606c, - 0x1bcbd3d8, 0x2484a0a4, - 0x34043034, 0x31c1f1f0, 0x08484048, - 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, - 0x2d0d212c, 0x00404040, - 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, - 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, - 0x0e4e424c, 0x15455154, - 0x3b0b3338, 0x1cccd0dc, 0x28486068, - 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, - 0x0a4a4248, 0x16465254, - 0x37477374, 0x2080a0a0, 0x2dcde1ec, - 0x06464244, 0x3585b1b4, 0x2b0b2328, - 0x25456164, 0x3acaf2f8, - 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, - 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, - 0x26c6e2e4, 0x3282b2b0, - 0x31013130, 0x2acae2e8, 0x2d4d616c, - 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, - 0x0dcdc1cc, 0x08888088, - 0x16061214, 0x3a0a3238, 0x18485058, - 0x14c4d0d4, 0x22426260, 0x29092128, - 0x07070304, 0x33033330, - 0x28c8e0e8, 0x1b0b1318, 0x05050104, - 0x39497178, 0x10809090, 0x2a4a6268, - 0x2a0a2228, 0x1a8a9298}, { - 0x38380830, - 0xe828c8e0, - 0x2c2d0d21, - 0xa42686a2, - 0xcc0fcfc3, - 0xdc1eced2, - 0xb03383b3, - 0xb83888b0, - 0xac2f8fa3, - 0x60204060, - 0x54154551, - 0xc407c7c3, - 0x44044440, - 0x6c2f4f63, - 0x682b4b63, - 0x581b4b53, - 0xc003c3c3, - 0x60224262, - 0x30330333, - 0xb43585b1, - 0x28290921, - 0xa02080a0, - 0xe022c2e2, - 0xa42787a3, - 0xd013c3d3, - 0x90118191, - 0x10110111, - 0x04060602, - 0x1c1c0c10, - 0xbc3c8cb0, - 0x34360632, - 0x480b4b43, - 0xec2fcfe3, - 0x88088880, - 0x6c2c4c60, - 0xa82888a0, - 0x14170713, - 0xc404c4c0, - 0x14160612, - 0xf434c4f0, - 0xc002c2c2, - 0x44054541, - 0xe021c1e1, - 0xd416c6d2, - 0x3c3f0f33, - 0x3c3d0d31, - 0x8c0e8e82, - 0x98188890, - 0x28280820, - 0x4c0e4e42, - 0xf436c6f2, - 0x3c3e0e32, - 0xa42585a1, - 0xf839c9f1, - 0x0c0d0d01, - 0xdc1fcfd3, - 0xd818c8d0, - 0x282b0b23, - 0x64264662, - 0x783a4a72, - 0x24270723, - 0x2c2f0f23, - 0xf031c1f1, - 0x70324272, - 0x40024242, - 0xd414c4d0, - 0x40014141, - 0xc000c0c0, - 0x70334373, - 0x64274763, - 0xac2c8ca0, - 0x880b8b83, - 0xf437c7f3, - 0xac2d8da1, - 0x80008080, - 0x1c1f0f13, - 0xc80acac2, - 0x2c2c0c20, - 0xa82a8aa2, - 0x34340430, - 0xd012c2d2, - 0x080b0b03, - 0xec2ecee2, - 0xe829c9e1, - 0x5c1d4d51, - 0x94148490, - 0x18180810, - 0xf838c8f0, - 0x54174753, - 0xac2e8ea2, - 0x08080800, - 0xc405c5c1, - 0x10130313, - 0xcc0dcdc1, - 0x84068682, - 0xb83989b1, - 0xfc3fcff3, - 0x7c3d4d71, - 0xc001c1c1, - 0x30310131, - 0xf435c5f1, - 0x880a8a82, - 0x682a4a62, - 0xb03181b1, - 0xd011c1d1, - 0x20200020, - 0xd417c7d3, - 0x00020202, - 0x20220222, - 0x04040400, - 0x68284860, - 0x70314171, - 0x04070703, - 0xd81bcbd3, - 0x9c1d8d91, - 0x98198991, - 0x60214161, - 0xbc3e8eb2, - 0xe426c6e2, - 0x58194951, - 0xdc1dcdd1, - 0x50114151, - 0x90108090, - 0xdc1cccd0, - 0x981a8a92, - 0xa02383a3, - 0xa82b8ba3, - 0xd010c0d0, - 0x80018181, - 0x0c0f0f03, - 0x44074743, - 0x181a0a12, - 0xe023c3e3, - 0xec2ccce0, - 0x8c0d8d81, - 0xbc3f8fb3, - 0x94168692, - 0x783b4b73, - 0x5c1c4c50, - 0xa02282a2, - 0xa02181a1, - 0x60234363, - 0x20230323, - 0x4c0d4d41, - 0xc808c8c0, - 0x9c1e8e92, - 0x9c1c8c90, - 0x383a0a32, - 0x0c0c0c00, - 0x2c2e0e22, - 0xb83a8ab2, - 0x6c2e4e62, - 0x9c1f8f93, - 0x581a4a52, - 0xf032c2f2, - 0x90128292, - 0xf033c3f3, - 0x48094941, - 0x78384870, - 0xcc0cccc0, - 0x14150511, - 0xf83bcbf3, - 0x70304070, - 0x74354571, - 0x7c3f4f73, - 0x34350531, - 0x10100010, - 0x00030303, - 0x64244460, - 0x6c2d4d61, - 0xc406c6c2, - 0x74344470, - 0xd415c5d1, - 0xb43484b0, - 0xe82acae2, - 0x08090901, - 0x74364672, - 0x18190911, - 0xfc3ecef2, - 0x40004040, - 0x10120212, - 0xe020c0e0, - 0xbc3d8db1, - 0x04050501, - 0xf83acaf2, - 0x00010101, - 0xf030c0f0, - 0x282a0a22, - 0x5c1e4e52, - 0xa82989a1, - 0x54164652, - 0x40034343, - 0x84058581, - 0x14140410, - 0x88098981, - 0x981b8b93, - 0xb03080b0, - 0xe425c5e1, - 0x48084840, - 0x78394971, - 0x94178793, - 0xfc3cccf0, - 0x1c1e0e12, - 0x80028282, - 0x20210121, - 0x8c0c8c80, - 0x181b0b13, - 0x5c1f4f53, - 0x74374773, - 0x54144450, - 0xb03282b2, - 0x1c1d0d11, - 0x24250521, - 0x4c0f4f43, - 0x00000000, - 0x44064642, - 0xec2dcde1, - 0x58184850, - 0x50124252, - 0xe82bcbe3, - 0x7c3e4e72, - 0xd81acad2, - 0xc809c9c1, - 0xfc3dcdf1, - 0x30300030, - 0x94158591, - 0x64254561, - 0x3c3c0c30, - 0xb43686b2, - 0xe424c4e0, - 0xb83b8bb3, - 0x7c3c4c70, - 0x0c0e0e02, - 0x50104050, - 0x38390931, - 0x24260622, - 0x30320232, - 0x84048480, - 0x68294961, - 0x90138393, - 0x34370733, - 0xe427c7e3, - 0x24240420, - 0xa42484a0, - 0xc80bcbc3, - 0x50134353, - 0x080a0a02, - 0x84078783, - 0xd819c9d1, - 0x4c0c4c40, - 0x80038383, - 0x8c0f8f83, - 0xcc0ecec2, - 0x383b0b33, - 0x480a4a42, - 0xb43787b3}, -{ - 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, - 0xa0ac2c8c, 0x21242505, - 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, - 0xc2c80aca, 0x63602343, - 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, - 0xc0c808c8, 0x13141707, - 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, - 0xd2d012c2, 0xe2ec2ece, - 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, - 0xf2f436c6, 0x70743444, - 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, - 0xb1bc3d8d, 0x01000101, - 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, - 0xf2f032c2, 0xd1d819c9, - 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, - 0x82840686, 0xc1c809c9, - 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, - 0x929c1e8e, 0x434c0f4f, - 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, - 0xa3ac2f8f, 0xd1d415c5, - 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, - 0x818c0d8d, 0x00080808, - 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, - 0xf3f437c7, 0xe1e021c1, - 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, - 0x020c0e0e, 0xa3a82b8b, - 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, - 0x01080909, 0x02080a0a, - 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, - 0xf2fc3ece, 0x60642444, - 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, - 0x63682b4b, 0x62642646, - 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, - 0x727c3e4e, 0xd0d010c0, - 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, - 0xa1ac2d8d, 0xd3dc1fcf, - 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, - 0x22202202, 0x30383808, - 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, - 0x80840484, 0x93941787, - 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, - 0xc3c407c7, 0x81880989, - 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, - 0x82800282, 0xc0c404c4, - 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, - 0xd3d417c7, 0xb0b83888, - 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, - 0xd3d81bcb, 0xa0a42484, - 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, - 0x212c2d0d, 0x40400040, - 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, - 0x424c0e4e, 0x51541545, - 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, - 0x42480a4a, 0x52541646, - 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, - 0x61642545, 0xf2f83aca, - 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, - 0xe2e426c6, 0xb2b03282, - 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, - 0xc1cc0dcd, 0x80880888, - 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, - 0x03040707, 0x33303303, - 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, - 0x22282a0a, 0x92981a8a}, { - 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, - 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, - 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, - 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, - 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, - 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, - 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, - 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, - 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, - 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, - 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, - 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, - 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, - 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, - 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, - 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, - 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, - 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, - 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, - 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, - 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, - 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, - 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, - 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, - 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, - 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, - 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, - 0x02222022, 0x04000404, 0x48606828, 0x41717031, - 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, - 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, - 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, - 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, - 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, - 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, - 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, - 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, - 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, - 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, - 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, - 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, - 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, - 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, - 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, - 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, - 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, - 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, - 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, - 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, - 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, - 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, - 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, - 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, - 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, - 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, - 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, - 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, - 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, - 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, - 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, - 0x02323032, 0x84808404, 0x49616829, 0x83939013, - 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, - 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, - 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, - 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437} -}; - -/* key schedule constants - golden ratio */ -# define KC0 0x9e3779b9 -# define KC1 0x3c6ef373 -# define KC2 0x78dde6e6 -# define KC3 0xf1bbcdcc -# define KC4 0xe3779b99 -# define KC5 0xc6ef3733 -# define KC6 0x8dde6e67 -# define KC7 0x1bbcdccf -# define KC8 0x3779b99e -# define KC9 0x6ef3733c -# define KC10 0xdde6e678 -# define KC11 0xbbcdccf1 -# define KC12 0x779b99e3 -# define KC13 0xef3733c6 -# define KC14 0xde6e678d -# define KC15 0xbcdccf1b - -# if defined(OPENSSL_SMALL_FOOTPRINT) -static const seed_word KC[] = { - KC0, KC1, KC2, KC3, KC4, KC5, KC6, KC7, - KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15 -}; -# endif -void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], - SEED_KEY_SCHEDULE *ks) -# ifdef OPENSSL_FIPS -{ - fips_cipher_abort(SEED); - private_SEED_set_key(rawkey, ks); -} - -void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], - SEED_KEY_SCHEDULE *ks) -# endif -{ - seed_word x1, x2, x3, x4; - seed_word t0, t1; - - char2word(rawkey, x1); - char2word(rawkey + 4, x2); - char2word(rawkey + 8, x3); - char2word(rawkey + 12, x4); - - t0 = (x1 + x3 - KC0) & 0xffffffff; - t1 = (x2 - x4 + KC0) & 0xffffffff; - KEYUPDATE_TEMP(t0, t1, &ks->data[0]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1); - KEYUPDATE_TEMP(t0, t1, &ks->data[2]); - -# if !defined(OPENSSL_SMALL_FOOTPRINT) - KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2); - KEYUPDATE_TEMP(t0, t1, &ks->data[4]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3); - KEYUPDATE_TEMP(t0, t1, &ks->data[6]); - KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4); - KEYUPDATE_TEMP(t0, t1, &ks->data[8]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5); - KEYUPDATE_TEMP(t0, t1, &ks->data[10]); - KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6); - KEYUPDATE_TEMP(t0, t1, &ks->data[12]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7); - KEYUPDATE_TEMP(t0, t1, &ks->data[14]); - KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8); - KEYUPDATE_TEMP(t0, t1, &ks->data[16]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9); - KEYUPDATE_TEMP(t0, t1, &ks->data[18]); - KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10); - KEYUPDATE_TEMP(t0, t1, &ks->data[20]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11); - KEYUPDATE_TEMP(t0, t1, &ks->data[22]); - KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12); - KEYUPDATE_TEMP(t0, t1, &ks->data[24]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13); - KEYUPDATE_TEMP(t0, t1, &ks->data[26]); - KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14); - KEYUPDATE_TEMP(t0, t1, &ks->data[28]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15); - KEYUPDATE_TEMP(t0, t1, &ks->data[30]); -# else - { - int i; - for (i = 2; i < 16; i += 2) { - KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]); - KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2]); - KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i + 1]); - KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2 + 2]); - } - } -# endif -} - -void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], - unsigned char d[SEED_BLOCK_SIZE], - const SEED_KEY_SCHEDULE *ks) -{ - seed_word x1, x2, x3, x4; - seed_word t0, t1; - - char2word(s, x1); - char2word(s + 4, x2); - char2word(s + 8, x3); - char2word(s + 12, x4); - -# if !defined(OPENSSL_SMALL_FOOTPRINT) - E_SEED(t0, t1, x1, x2, x3, x4, 0); - E_SEED(t0, t1, x3, x4, x1, x2, 2); - E_SEED(t0, t1, x1, x2, x3, x4, 4); - E_SEED(t0, t1, x3, x4, x1, x2, 6); - E_SEED(t0, t1, x1, x2, x3, x4, 8); - E_SEED(t0, t1, x3, x4, x1, x2, 10); - E_SEED(t0, t1, x1, x2, x3, x4, 12); - E_SEED(t0, t1, x3, x4, x1, x2, 14); - E_SEED(t0, t1, x1, x2, x3, x4, 16); - E_SEED(t0, t1, x3, x4, x1, x2, 18); - E_SEED(t0, t1, x1, x2, x3, x4, 20); - E_SEED(t0, t1, x3, x4, x1, x2, 22); - E_SEED(t0, t1, x1, x2, x3, x4, 24); - E_SEED(t0, t1, x3, x4, x1, x2, 26); - E_SEED(t0, t1, x1, x2, x3, x4, 28); - E_SEED(t0, t1, x3, x4, x1, x2, 30); -# else - { - int i; - for (i = 0; i < 30; i += 4) { - E_SEED(t0, t1, x1, x2, x3, x4, i); - E_SEED(t0, t1, x3, x4, x1, x2, i + 2); - } - } -# endif - - word2char(x3, d); - word2char(x4, d + 4); - word2char(x1, d + 8); - word2char(x2, d + 12); -} - -void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], - unsigned char d[SEED_BLOCK_SIZE], - const SEED_KEY_SCHEDULE *ks) -{ - seed_word x1, x2, x3, x4; - seed_word t0, t1; - - char2word(s, x1); - char2word(s + 4, x2); - char2word(s + 8, x3); - char2word(s + 12, x4); - -# if !defined(OPENSSL_SMALL_FOOTPRINT) - E_SEED(t0, t1, x1, x2, x3, x4, 30); - E_SEED(t0, t1, x3, x4, x1, x2, 28); - E_SEED(t0, t1, x1, x2, x3, x4, 26); - E_SEED(t0, t1, x3, x4, x1, x2, 24); - E_SEED(t0, t1, x1, x2, x3, x4, 22); - E_SEED(t0, t1, x3, x4, x1, x2, 20); - E_SEED(t0, t1, x1, x2, x3, x4, 18); - E_SEED(t0, t1, x3, x4, x1, x2, 16); - E_SEED(t0, t1, x1, x2, x3, x4, 14); - E_SEED(t0, t1, x3, x4, x1, x2, 12); - E_SEED(t0, t1, x1, x2, x3, x4, 10); - E_SEED(t0, t1, x3, x4, x1, x2, 8); - E_SEED(t0, t1, x1, x2, x3, x4, 6); - E_SEED(t0, t1, x3, x4, x1, x2, 4); - E_SEED(t0, t1, x1, x2, x3, x4, 2); - E_SEED(t0, t1, x3, x4, x1, x2, 0); -# else - { - int i; - for (i = 30; i > 0; i -= 4) { - E_SEED(t0, t1, x1, x2, x3, x4, i); - E_SEED(t0, t1, x3, x4, x1, x2, i - 2); - - } - } -# endif - - word2char(x3, d); - word2char(x4, d + 4); - word2char(x1, d + 8); - word2char(x2, d + 12); -} - -#endif /* OPENSSL_NO_SEED */ diff --git a/Sources/COpenSSL/seed.h b/Sources/COpenSSL/seed.h deleted file mode 100644 index 30fa2a7d..00000000 --- a/Sources/COpenSSL/seed.h +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of author nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_SEED_H -# define HEADER_SEED_H - -# include "opensslconf.h" -# include "e_os2.h" -# include "crypto.h" - -# ifdef OPENSSL_NO_SEED -# error SEED is disabled. -# endif - -/* look whether we need 'long' to get 32 bits */ -# ifdef AES_LONG -# ifndef SEED_LONG -# define SEED_LONG 1 -# endif -# endif - -# if !defined(NO_SYS_TYPES_H) -# include -# endif - -# define SEED_BLOCK_SIZE 16 -# define SEED_KEY_LENGTH 16 - - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct seed_key_st { -# ifdef SEED_LONG - unsigned long data[32]; -# else - unsigned int data[32]; -# endif -} SEED_KEY_SCHEDULE; - -# ifdef OPENSSL_FIPS -void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], - SEED_KEY_SCHEDULE *ks); -# endif -void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], - SEED_KEY_SCHEDULE *ks); - -void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], - unsigned char d[SEED_BLOCK_SIZE], - const SEED_KEY_SCHEDULE *ks); -void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], - unsigned char d[SEED_BLOCK_SIZE], - const SEED_KEY_SCHEDULE *ks); - -void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, - const SEED_KEY_SCHEDULE *ks, int enc); -void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, - const SEED_KEY_SCHEDULE *ks, - unsigned char ivec[SEED_BLOCK_SIZE], int enc); -void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const SEED_KEY_SCHEDULE *ks, - unsigned char ivec[SEED_BLOCK_SIZE], int *num, - int enc); -void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const SEED_KEY_SCHEDULE *ks, - unsigned char ivec[SEED_BLOCK_SIZE], int *num); - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_SEED_H */ diff --git a/Sources/COpenSSL/seed_.c b/Sources/COpenSSL/seed_.c deleted file mode 100644 index 86d9f35c..00000000 --- a/Sources/COpenSSL/seed_.c +++ /dev/null @@ -1,361 +0,0 @@ -/* crypto/seed/seed_cbc.c */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -#include "seed.h" -#include "modes.h" - -void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const SEED_KEY_SCHEDULE *ks, - unsigned char ivec[SEED_BLOCK_SIZE], int enc) -{ - if (enc) - CRYPTO_cbc128_encrypt(in, out, len, ks, ivec, - (block128_f) SEED_encrypt); - else - CRYPTO_cbc128_decrypt(in, out, len, ks, ivec, - (block128_f) SEED_decrypt); -} -/* crypto/seed/seed_cfb.c */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "seed.h" -// #include "modes.h" - -void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const SEED_KEY_SCHEDULE *ks, - unsigned char ivec[SEED_BLOCK_SIZE], int *num, - int enc) -{ - CRYPTO_cfb128_encrypt(in, out, len, ks, ivec, num, enc, - (block128_f) SEED_encrypt); -} -/* crypto/seed/seed_ecb.c */ -/* ==================================================================== - * Copyright (c) 2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "seed.h" - -void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, - const SEED_KEY_SCHEDULE *ks, int enc) -{ - if (enc) - SEED_encrypt(in, out, ks); - else - SEED_decrypt(in, out, ks); -} -/* crypto/seed/seed_ofb.c */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "seed.h" -// #include "modes.h" - -void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const SEED_KEY_SCHEDULE *ks, - unsigned char ivec[SEED_BLOCK_SIZE], int *num) -{ - CRYPTO_ofb128_encrypt(in, out, len, ks, ivec, num, - (block128_f) SEED_encrypt); -} diff --git a/Sources/COpenSSL/seed_locl.h b/Sources/COpenSSL/seed_locl.h deleted file mode 100644 index 8dd4f12a..00000000 --- a/Sources/COpenSSL/seed_locl.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Neither the name of author nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#ifndef HEADER_SEED_LOCL_H -# define HEADER_SEED_LOCL_H - -# include "e_os2.h" -# include "seed.h" - -# ifdef SEED_LONG /* need 32-bit type */ -typedef unsigned long seed_word; -# else -typedef unsigned int seed_word; -# endif - - -#ifdef __cplusplus -extern "C" { -#endif - -# define G_FUNC(v) \ - SS[0][(unsigned char) (v) & 0xff] ^ SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \ - SS[2][(unsigned char)((v)>>16) & 0xff] ^ SS[3][(unsigned char)((v)>>24) & 0xff] - -# define char2word(c, i) \ - (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3])) - -# define word2char(l, c) \ - *((c)+0) = (unsigned char)((l)>>24) & 0xff; \ - *((c)+1) = (unsigned char)((l)>>16) & 0xff; \ - *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \ - *((c)+3) = (unsigned char)((l)) & 0xff - -# define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC) \ - (T0) = (X3); \ - (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff; \ - (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff; \ - (T0) = ((X1) + (X3) - (KC)) & 0xffffffff; \ - (T1) = ((X2) + (KC) - (X4)) & 0xffffffff - -# define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC) \ - (T0) = (X1); \ - (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff; \ - (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff; \ - (T0) = ((X1) + (X3) - (KC)) & 0xffffffff; \ - (T1) = ((X2) + (KC) - (X4)) & 0xffffffff - -# define KEYUPDATE_TEMP(T0, T1, K) \ - (K)[0] = G_FUNC((T0)); \ - (K)[1] = G_FUNC((T1)) - -# define XOR_SEEDBLOCK(DST, SRC) \ - ((DST))[0] ^= ((SRC))[0]; \ - ((DST))[1] ^= ((SRC))[1]; \ - ((DST))[2] ^= ((SRC))[2]; \ - ((DST))[3] ^= ((SRC))[3] - -# define MOV_SEEDBLOCK(DST, SRC) \ - ((DST))[0] = ((SRC))[0]; \ - ((DST))[1] = ((SRC))[1]; \ - ((DST))[2] = ((SRC))[2]; \ - ((DST))[3] = ((SRC))[3] - -# define CHAR2WORD(C, I) \ - char2word((C), (I)[0]); \ - char2word((C+4), (I)[1]); \ - char2word((C+8), (I)[2]); \ - char2word((C+12), (I)[3]) - -# define WORD2CHAR(I, C) \ - word2char((I)[0], (C)); \ - word2char((I)[1], (C+4)); \ - word2char((I)[2], (C+8)); \ - word2char((I)[3], (C+12)) - -# define E_SEED(T0, T1, X1, X2, X3, X4, rbase) \ - (T0) = (X3) ^ (ks->data)[(rbase)]; \ - (T1) = (X4) ^ (ks->data)[(rbase)+1]; \ - (T1) ^= (T0); \ - (T1) = G_FUNC((T1)); \ - (T0) = ((T0) + (T1)) & 0xffffffff; \ - (T0) = G_FUNC((T0)); \ - (T1) = ((T1) + (T0)) & 0xffffffff; \ - (T1) = G_FUNC((T1)); \ - (T0) = ((T0) + (T1)) & 0xffffffff; \ - (X1) ^= (T0); \ - (X2) ^= (T1) - -#ifdef __cplusplus -} -#endif - -#endif /* HEADER_SEED_LOCL_H */ diff --git a/Sources/COpenSSL/set_key.c b/Sources/COpenSSL/set_key.c deleted file mode 100644 index 166c42bc..00000000 --- a/Sources/COpenSSL/set_key.c +++ /dev/null @@ -1,448 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/des/set_key.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/*- - * set_key.c v 1.4 eay 24/9/91 - * 1.4 Speed up by 400% :-) - * 1.3 added register declarations. - * 1.2 unrolled make_key_sched a bit more - * 1.1 added norm_expand_bits - * 1.0 First working version - */ -#include "crypto.h" -#include "des_locl.h" - -OPENSSL_IMPLEMENT_GLOBAL(int, DES_check_key, 0) - /* - * defaults to false - */ -static const unsigned char odd_parity[256] = { - 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, - 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, - 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, - 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, - 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, - 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, - 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110, - 110, - 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127, - 127, - 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143, - 143, - 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158, - 158, - 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174, - 174, - 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, - 191, - 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, - 206, - 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, - 223, - 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, - 239, - 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254, - 254 -}; - -void DES_set_odd_parity(DES_cblock *key) -{ - unsigned int i; - - for (i = 0; i < DES_KEY_SZ; i++) - (*key)[i] = odd_parity[(*key)[i]]; -} - -int DES_check_key_parity(const_DES_cblock *key) -{ - unsigned int i; - - for (i = 0; i < DES_KEY_SZ; i++) { - if ((*key)[i] != odd_parity[(*key)[i]]) - return (0); - } - return (1); -} - -/*- - * Weak and semi weak keys as taken from - * %A D.W. Davies - * %A W.L. Price - * %T Security for Computer Networks - * %I John Wiley & Sons - * %D 1984 - * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference - * (and actual cblock values). - */ -#define NUM_WEAK_KEY 16 -static const DES_cblock weak_keys[NUM_WEAK_KEY] = { - /* weak keys */ - {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, - {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}, - {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, - {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1}, - /* semi-weak keys */ - {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE}, - {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01}, - {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1}, - {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E}, - {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1}, - {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01}, - {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE}, - {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E}, - {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E}, - {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01}, - {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, - {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1} -}; - -int DES_is_weak_key(const_DES_cblock *key) -{ - int i; - - for (i = 0; i < NUM_WEAK_KEY; i++) - /* - * Added == 0 to comparison, I obviously don't run this section very - * often :-(, thanks to engineering@MorningStar.Com for the fix eay - * 93/06/29 Another problem, I was comparing only the first 4 bytes, - * 97/03/18 - */ - if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0) - return (1); - return (0); -} - -/*- - * NOW DEFINED IN des_local.h - * See ecb_encrypt.c for a pseudo description of these macros. - * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ - * (b)^=(t),\ - * (a)=((a)^((t)<<(n)))) - */ - -#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ - (a)=(a)^(t)^(t>>(16-(n)))) - -static const DES_LONG des_skb[8][64] = { - { - /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ - 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L, - 0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L, - 0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L, - 0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L, - 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L, - 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L, - 0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L, - 0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L, - 0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L, - 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L, - 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L, - 0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L, - 0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L, - 0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L, - 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L, - 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L, - }, - { - /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ - 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L, - 0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L, - 0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L, - 0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L, - 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L, - 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L, - 0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L, - 0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L, - 0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L, - 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L, - 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L, - 0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L, - 0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L, - 0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L, - 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L, - 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L, - }, - { - /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ - 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L, - 0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L, - 0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L, - 0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L, - 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L, - 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L, - 0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L, - 0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L, - 0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L, - 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L, - 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L, - 0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L, - 0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L, - 0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L, - 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L, - 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L, - }, - { - /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ - 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L, - 0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L, - 0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L, - 0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L, - 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L, - 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L, - 0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L, - 0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L, - 0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L, - 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L, - 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L, - 0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L, - 0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L, - 0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L, - 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L, - 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L, - }, - { - /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ - 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L, - 0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L, - 0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L, - 0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L, - 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L, - 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L, - 0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L, - 0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L, - 0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L, - 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L, - 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L, - 0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L, - 0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L, - 0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L, - 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L, - 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L, - }, - { - /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ - 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L, - 0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L, - 0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L, - 0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L, - 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L, - 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L, - 0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L, - 0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L, - 0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L, - 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L, - 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L, - 0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L, - 0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L, - 0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L, - 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L, - 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L, - }, - { - /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ - 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L, - 0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L, - 0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L, - 0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L, - 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L, - 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L, - 0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L, - 0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L, - 0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L, - 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L, - 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L, - 0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L, - 0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L, - 0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L, - 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L, - 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L, - }, - { - /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ - 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L, - 0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L, - 0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L, - 0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L, - 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L, - 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L, - 0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L, - 0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L, - 0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L, - 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L, - 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L, - 0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L, - 0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L, - 0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L, - 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L, - 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L, - } -}; - -int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule) -{ - if (DES_check_key) { - return DES_set_key_checked(key, schedule); - } else { - DES_set_key_unchecked(key, schedule); - return 0; - } -} - -/*- - * return 0 if key parity is odd (correct), - * return -1 if key parity error, - * return -2 if illegal weak key. - */ -int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule) -{ - if (!DES_check_key_parity(key)) - return (-1); - if (DES_is_weak_key(key)) - return (-2); - DES_set_key_unchecked(key, schedule); - return 0; -} - -void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) -#ifdef OPENSSL_FIPS -{ - fips_cipher_abort(DES); - private_DES_set_key_unchecked(key, schedule); -} - -void private_DES_set_key_unchecked(const_DES_cblock *key, - DES_key_schedule *schedule) -#endif -{ - static const int shifts2[16] = - { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 }; - register DES_LONG c, d, t, s, t2; - register const unsigned char *in; - register DES_LONG *k; - register int i; - -#ifdef OPENBSD_DEV_CRYPTO - memcpy(schedule->key, key, sizeof(schedule->key)); - schedule->session = NULL; -#endif - k = &schedule->ks->deslong[0]; - in = &(*key)[0]; - - c2l(in, c); - c2l(in, d); - - /* - * do PC1 in 47 simple operations :-) Thanks to John Fletcher - * (john_fletcher@lccmail.ocf.llnl.gov) for the inspiration. :-) - */ - PERM_OP(d, c, t, 4, 0x0f0f0f0fL); - HPERM_OP(c, t, -2, 0xcccc0000L); - HPERM_OP(d, t, -2, 0xcccc0000L); - PERM_OP(d, c, t, 1, 0x55555555L); - PERM_OP(c, d, t, 8, 0x00ff00ffL); - PERM_OP(d, c, t, 1, 0x55555555L); - d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) | - ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L)); - c &= 0x0fffffffL; - - for (i = 0; i < ITERATIONS; i++) { - if (shifts2[i]) { - c = ((c >> 2L) | (c << 26L)); - d = ((d >> 2L) | (d << 26L)); - } else { - c = ((c >> 1L) | (c << 27L)); - d = ((d >> 1L) | (d << 27L)); - } - c &= 0x0fffffffL; - d &= 0x0fffffffL; - /* - * could be a few less shifts but I am to lazy at this point in time - * to investigate - */ - s = des_skb[0][(c) & 0x3f] | - des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] | - des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] | - des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) | - ((c >> 22L) & 0x38)]; - t = des_skb[4][(d) & 0x3f] | - des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] | - des_skb[6][(d >> 15L) & 0x3f] | - des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)]; - - /* table contained 0213 4657 */ - t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL; - *(k++) = ROTATE(t2, 30) & 0xffffffffL; - - t2 = ((s >> 16L) | (t & 0xffff0000L)); - *(k++) = ROTATE(t2, 26) & 0xffffffffL; - } -} - -int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule) -{ - return (DES_set_key(key, schedule)); -} - -/*- -#undef des_fixup_key_parity -void des_fixup_key_parity(des_cblock *key) - { - des_set_odd_parity(key); - } -*/ diff --git a/Sources/COpenSSL/sha.h b/Sources/COpenSSL/sha.h deleted file mode 100644 index 53ae6f77..00000000 --- a/Sources/COpenSSL/sha.h +++ /dev/null @@ -1,214 +0,0 @@ -/* crypto/sha/sha.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_SHA_H -# define HEADER_SHA_H - -# include "e_os2.h" -# include - -#ifdef __cplusplus -extern "C" { -#endif - -# if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1)) -# error SHA is disabled. -# endif - -# if defined(OPENSSL_FIPS) -# define FIPS_SHA_SIZE_T size_t -# endif - -/*- - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! - * ! SHA_LONG_LOG2 has to be defined along. ! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - */ - -# if defined(__LP32__) -# define SHA_LONG unsigned long -# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) -# define SHA_LONG unsigned long -# define SHA_LONG_LOG2 3 -# else -# define SHA_LONG unsigned int -# endif - -# define SHA_LBLOCK 16 -# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a - * contiguous array of 32 bit wide - * big-endian values. */ -# define SHA_LAST_BLOCK (SHA_CBLOCK-8) -# define SHA_DIGEST_LENGTH 20 - -typedef struct SHAstate_st { - SHA_LONG h0, h1, h2, h3, h4; - SHA_LONG Nl, Nh; - SHA_LONG data[SHA_LBLOCK]; - unsigned int num; -} SHA_CTX; - -# ifndef OPENSSL_NO_SHA0 -# ifdef OPENSSL_FIPS -int private_SHA_Init(SHA_CTX *c); -# endif -int SHA_Init(SHA_CTX *c); -int SHA_Update(SHA_CTX *c, const void *data, size_t len); -int SHA_Final(unsigned char *md, SHA_CTX *c); -unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md); -void SHA_Transform(SHA_CTX *c, const unsigned char *data); -# endif -# ifndef OPENSSL_NO_SHA1 -# ifdef OPENSSL_FIPS -int private_SHA1_Init(SHA_CTX *c); -# endif -int SHA1_Init(SHA_CTX *c); -int SHA1_Update(SHA_CTX *c, const void *data, size_t len); -int SHA1_Final(unsigned char *md, SHA_CTX *c); -unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); -void SHA1_Transform(SHA_CTX *c, const unsigned char *data); -# endif - -# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a - * contiguous array of 32 bit wide - * big-endian values. */ -# define SHA224_DIGEST_LENGTH 28 -# define SHA256_DIGEST_LENGTH 32 - -typedef struct SHA256state_st { - SHA_LONG h[8]; - SHA_LONG Nl, Nh; - SHA_LONG data[SHA_LBLOCK]; - unsigned int num, md_len; -} SHA256_CTX; - -# ifndef OPENSSL_NO_SHA256 -# ifdef OPENSSL_FIPS -int private_SHA224_Init(SHA256_CTX *c); -int private_SHA256_Init(SHA256_CTX *c); -# endif -int SHA224_Init(SHA256_CTX *c); -int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); -int SHA224_Final(unsigned char *md, SHA256_CTX *c); -unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); -int SHA256_Init(SHA256_CTX *c); -int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); -int SHA256_Final(unsigned char *md, SHA256_CTX *c); -unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); -void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); -# endif - -# define SHA384_DIGEST_LENGTH 48 -# define SHA512_DIGEST_LENGTH 64 - -# ifndef OPENSSL_NO_SHA512 -/* - * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 - * being exactly 64-bit wide. See Implementation Notes in sha512.c - * for further details. - */ -/* - * SHA-512 treats input data as a - * contiguous array of 64 bit - * wide big-endian values. - */ -# define SHA512_CBLOCK (SHA_LBLOCK*8) -# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) -# define SHA_LONG64 unsigned __int64 -# define U64(C) C##UI64 -# elif defined(__arch64__) -# define SHA_LONG64 unsigned long -# define U64(C) C##UL -# else -# define SHA_LONG64 unsigned long long -# define U64(C) C##ULL -# endif - -typedef struct SHA512state_st { - SHA_LONG64 h[8]; - SHA_LONG64 Nl, Nh; - union { - SHA_LONG64 d[SHA_LBLOCK]; - unsigned char p[SHA512_CBLOCK]; - } u; - unsigned int num, md_len; -} SHA512_CTX; -# endif - -# ifndef OPENSSL_NO_SHA512 -# ifdef OPENSSL_FIPS -int private_SHA384_Init(SHA512_CTX *c); -int private_SHA512_Init(SHA512_CTX *c); -# endif -int SHA384_Init(SHA512_CTX *c); -int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); -int SHA384_Final(unsigned char *md, SHA512_CTX *c); -unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md); -int SHA512_Init(SHA512_CTX *c); -int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); -int SHA512_Final(unsigned char *md, SHA512_CTX *c); -unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md); -void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); -# endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/sha1_one.c b/Sources/COpenSSL/sha1_one.c deleted file mode 100644 index d875ce45..00000000 --- a/Sources/COpenSSL/sha1_one.c +++ /dev/null @@ -1,79 +0,0 @@ -/* crypto/sha/sha1_one.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "crypto.h" -#include "sha.h" - -#ifndef OPENSSL_NO_SHA1 -unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA_CTX c; - static unsigned char m[SHA_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - if (!SHA1_Init(&c)) - return NULL; - SHA1_Update(&c, d, n); - SHA1_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return (md); -} -#endif diff --git a/Sources/COpenSSL/sha1dgst.c b/Sources/COpenSSL/sha1dgst.c deleted file mode 100644 index 15b12300..00000000 --- a/Sources/COpenSSL/sha1dgst.c +++ /dev/null @@ -1,74 +0,0 @@ -/* crypto/sha/sha1dgst.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "crypto.h" -#include "opensslconf.h" -#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA) - -# undef SHA_0 -# define SHA_1 - -# include "opensslv.h" - -const char SHA1_version[] = "SHA1" OPENSSL_VERSION_PTEXT; - -/* The implementation is in ../md32_common.h */ - -# include "sha_locl.h" - -#endif diff --git a/Sources/COpenSSL/sha256.c b/Sources/COpenSSL/sha256.c deleted file mode 100644 index 1bdaa249..00000000 --- a/Sources/COpenSSL/sha256.c +++ /dev/null @@ -1,388 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/sha/sha256.c */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved - * according to the OpenSSL license [found in ../../LICENSE]. - * ==================================================================== - */ -#include "opensslconf.h" -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) - -# include -# include - -# include "crypto.h" -# include "sha.h" -# include "opensslv.h" - -const char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT; - -fips_md_init_ctx(SHA224, SHA256) -{ - memset(c, 0, sizeof(*c)); - c->h[0] = 0xc1059ed8UL; - c->h[1] = 0x367cd507UL; - c->h[2] = 0x3070dd17UL; - c->h[3] = 0xf70e5939UL; - c->h[4] = 0xffc00b31UL; - c->h[5] = 0x68581511UL; - c->h[6] = 0x64f98fa7UL; - c->h[7] = 0xbefa4fa4UL; - c->md_len = SHA224_DIGEST_LENGTH; - return 1; -} - -fips_md_init(SHA256) -{ - memset(c, 0, sizeof(*c)); - c->h[0] = 0x6a09e667UL; - c->h[1] = 0xbb67ae85UL; - c->h[2] = 0x3c6ef372UL; - c->h[3] = 0xa54ff53aUL; - c->h[4] = 0x510e527fUL; - c->h[5] = 0x9b05688cUL; - c->h[6] = 0x1f83d9abUL; - c->h[7] = 0x5be0cd19UL; - c->md_len = SHA256_DIGEST_LENGTH; - return 1; -} - -unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA256_CTX c; - static unsigned char m[SHA224_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - SHA224_Init(&c); - SHA256_Update(&c, d, n); - SHA256_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return (md); -} - -unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA256_CTX c; - static unsigned char m[SHA256_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - SHA256_Init(&c); - SHA256_Update(&c, d, n); - SHA256_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return (md); -} - -int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) -{ - return SHA256_Update(c, data, len); -} - -int SHA224_Final(unsigned char *md, SHA256_CTX *c) -{ - return SHA256_Final(md, c); -} - -# define DATA_ORDER_IS_BIG_ENDIAN - -# define HASH_LONG SHA_LONG -# define HASH_CTX SHA256_CTX -# define HASH_CBLOCK SHA_CBLOCK -/* - * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." - * default: case below covers for it. It's not clear however if it's - * permitted to truncate to amount of bytes not divisible by 4. I bet not, - * but if it is, then default: case shall be extended. For reference. - * Idea behind separate cases for pre-defined lenghts is to let the - * compiler decide if it's appropriate to unroll small loops. - */ -# define HASH_MAKE_STRING(c,s) do { \ - unsigned long ll; \ - unsigned int nn; \ - switch ((c)->md_len) \ - { case SHA224_DIGEST_LENGTH: \ - for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s)); } \ - break; \ - case SHA256_DIGEST_LENGTH: \ - for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s)); } \ - break; \ - default: \ - if ((c)->md_len > SHA256_DIGEST_LENGTH) \ - return 0; \ - for (nn=0;nn<(c)->md_len/4;nn++) \ - { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ - break; \ - } \ - } while (0) - -# define HASH_UPDATE SHA256_Update -# define HASH_TRANSFORM SHA256_Transform -# define HASH_FINAL SHA256_Final -# define HASH_BLOCK_DATA_ORDER sha256_block_data_order -# ifndef SHA256_ASM -static -# endif -void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); - -# include "md32_common.h" - -# ifndef SHA256_ASM -static const SHA_LONG K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - -/* - * FIPS specification refers to right rotations, while our ROTATE macro - * is left one. This is why you might notice that rotation coefficients - * differ from those observed in FIPS document by 32-N... - */ -# define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10)) -# define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7)) -# define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3)) -# define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10)) - -# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) -# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -# ifdef OPENSSL_SMALL_FOOTPRINT - -static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, - size_t num) -{ - unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2; - SHA_LONG X[16], l; - int i; - const unsigned char *data = in; - - while (num--) { - - a = ctx->h[0]; - b = ctx->h[1]; - c = ctx->h[2]; - d = ctx->h[3]; - e = ctx->h[4]; - f = ctx->h[5]; - g = ctx->h[6]; - h = ctx->h[7]; - - for (i = 0; i < 16; i++) { - HOST_c2l(data, l); - T1 = X[i] = l; - T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; - T2 = Sigma0(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - } - - for (; i < 64; i++) { - s0 = X[(i + 1) & 0x0f]; - s0 = sigma0(s0); - s1 = X[(i + 14) & 0x0f]; - s1 = sigma1(s1); - - T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; - T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; - T2 = Sigma0(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - } - - ctx->h[0] += a; - ctx->h[1] += b; - ctx->h[2] += c; - ctx->h[3] += d; - ctx->h[4] += e; - ctx->h[5] += f; - ctx->h[6] += g; - ctx->h[7] += h; - - } -} - -# else - -# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ - T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \ - h = Sigma0(a) + Maj(a,b,c); \ - d += T1; h += T1; } while (0) - -# define ROUND_16_63(i,a,b,c,d,e,f,g,h,X) do { \ - s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ - s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ - T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ - ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) - -static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, - size_t num) -{ - unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1; - SHA_LONG X[16]; - int i; - const unsigned char *data = in; - const union { - long one; - char little; - } is_endian = { - 1 - }; - - while (num--) { - - a = ctx->h[0]; - b = ctx->h[1]; - c = ctx->h[2]; - d = ctx->h[3]; - e = ctx->h[4]; - f = ctx->h[5]; - g = ctx->h[6]; - h = ctx->h[7]; - - if (!is_endian.little && sizeof(SHA_LONG) == 4 - && ((size_t)in % 4) == 0) { - const SHA_LONG *W = (const SHA_LONG *)data; - - T1 = X[0] = W[0]; - ROUND_00_15(0, a, b, c, d, e, f, g, h); - T1 = X[1] = W[1]; - ROUND_00_15(1, h, a, b, c, d, e, f, g); - T1 = X[2] = W[2]; - ROUND_00_15(2, g, h, a, b, c, d, e, f); - T1 = X[3] = W[3]; - ROUND_00_15(3, f, g, h, a, b, c, d, e); - T1 = X[4] = W[4]; - ROUND_00_15(4, e, f, g, h, a, b, c, d); - T1 = X[5] = W[5]; - ROUND_00_15(5, d, e, f, g, h, a, b, c); - T1 = X[6] = W[6]; - ROUND_00_15(6, c, d, e, f, g, h, a, b); - T1 = X[7] = W[7]; - ROUND_00_15(7, b, c, d, e, f, g, h, a); - T1 = X[8] = W[8]; - ROUND_00_15(8, a, b, c, d, e, f, g, h); - T1 = X[9] = W[9]; - ROUND_00_15(9, h, a, b, c, d, e, f, g); - T1 = X[10] = W[10]; - ROUND_00_15(10, g, h, a, b, c, d, e, f); - T1 = X[11] = W[11]; - ROUND_00_15(11, f, g, h, a, b, c, d, e); - T1 = X[12] = W[12]; - ROUND_00_15(12, e, f, g, h, a, b, c, d); - T1 = X[13] = W[13]; - ROUND_00_15(13, d, e, f, g, h, a, b, c); - T1 = X[14] = W[14]; - ROUND_00_15(14, c, d, e, f, g, h, a, b); - T1 = X[15] = W[15]; - ROUND_00_15(15, b, c, d, e, f, g, h, a); - - data += SHA256_CBLOCK; - } else { - SHA_LONG l; - - HOST_c2l(data, l); - T1 = X[0] = l; - ROUND_00_15(0, a, b, c, d, e, f, g, h); - HOST_c2l(data, l); - T1 = X[1] = l; - ROUND_00_15(1, h, a, b, c, d, e, f, g); - HOST_c2l(data, l); - T1 = X[2] = l; - ROUND_00_15(2, g, h, a, b, c, d, e, f); - HOST_c2l(data, l); - T1 = X[3] = l; - ROUND_00_15(3, f, g, h, a, b, c, d, e); - HOST_c2l(data, l); - T1 = X[4] = l; - ROUND_00_15(4, e, f, g, h, a, b, c, d); - HOST_c2l(data, l); - T1 = X[5] = l; - ROUND_00_15(5, d, e, f, g, h, a, b, c); - HOST_c2l(data, l); - T1 = X[6] = l; - ROUND_00_15(6, c, d, e, f, g, h, a, b); - HOST_c2l(data, l); - T1 = X[7] = l; - ROUND_00_15(7, b, c, d, e, f, g, h, a); - HOST_c2l(data, l); - T1 = X[8] = l; - ROUND_00_15(8, a, b, c, d, e, f, g, h); - HOST_c2l(data, l); - T1 = X[9] = l; - ROUND_00_15(9, h, a, b, c, d, e, f, g); - HOST_c2l(data, l); - T1 = X[10] = l; - ROUND_00_15(10, g, h, a, b, c, d, e, f); - HOST_c2l(data, l); - T1 = X[11] = l; - ROUND_00_15(11, f, g, h, a, b, c, d, e); - HOST_c2l(data, l); - T1 = X[12] = l; - ROUND_00_15(12, e, f, g, h, a, b, c, d); - HOST_c2l(data, l); - T1 = X[13] = l; - ROUND_00_15(13, d, e, f, g, h, a, b, c); - HOST_c2l(data, l); - T1 = X[14] = l; - ROUND_00_15(14, c, d, e, f, g, h, a, b); - HOST_c2l(data, l); - T1 = X[15] = l; - ROUND_00_15(15, b, c, d, e, f, g, h, a); - } - - for (i = 16; i < 64; i += 8) { - ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X); - ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X); - ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X); - ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X); - ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X); - ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X); - ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X); - ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X); - } - - ctx->h[0] += a; - ctx->h[1] += b; - ctx->h[2] += c; - ctx->h[3] += d; - ctx->h[4] += e; - ctx->h[5] += f; - ctx->h[6] += g; - ctx->h[7] += h; - - } -} - -# endif -# endif /* SHA256_ASM */ - -#endif /* OPENSSL_NO_SHA256 */ diff --git a/Sources/COpenSSL/sha512.c b/Sources/COpenSSL/sha512.c deleted file mode 100644 index 08376c06..00000000 --- a/Sources/COpenSSL/sha512.c +++ /dev/null @@ -1,684 +0,0 @@ -/* crypto/sha/sha512.c */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved - * according to the OpenSSL license [found in ../../LICENSE]. - * ==================================================================== - */ -#include "opensslconf.h" -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) -/*- - * IMPLEMENTATION NOTES. - * - * As you might have noticed 32-bit hash algorithms: - * - * - permit SHA_LONG to be wider than 32-bit (case on CRAY); - * - optimized versions implement two transform functions: one operating - * on [aligned] data in host byte order and one - on data in input - * stream byte order; - * - share common byte-order neutral collector and padding function - * implementations, ../md32_common.h; - * - * Neither of the above applies to this SHA-512 implementations. Reasons - * [in reverse order] are: - * - * - it's the only 64-bit hash algorithm for the moment of this writing, - * there is no need for common collector/padding implementation [yet]; - * - by supporting only one transform function [which operates on - * *aligned* data in input stream byte order, big-endian in this case] - * we minimize burden of maintenance in two ways: a) collector/padding - * function is simpler; b) only one transform function to stare at; - * - SHA_LONG64 is required to be exactly 64-bit in order to be able to - * apply a number of optimizations to mitigate potential performance - * penalties caused by previous design decision; - * - * Caveat lector. - * - * Implementation relies on the fact that "long long" is 64-bit on - * both 32- and 64-bit platforms. If some compiler vendor comes up - * with 128-bit long long, adjustment to sha.h would be required. - * As this implementation relies on 64-bit integer type, it's totally - * inappropriate for platforms which don't support it, most notably - * 16-bit platforms. - * - */ -# include -# include - -# include "crypto.h" -# include "sha.h" -# include "opensslv.h" - -# include "cryptlib.h" - -const char SHA512_version[] = "SHA-512" OPENSSL_VERSION_PTEXT; - -# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ - defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \ - defined(__s390__) || defined(__s390x__) || \ - defined(__aarch64__) || \ - defined(SHA512_ASM) -# define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA -# endif - -fips_md_init_ctx(SHA384, SHA512) -{ - c->h[0] = U64(0xcbbb9d5dc1059ed8); - c->h[1] = U64(0x629a292a367cd507); - c->h[2] = U64(0x9159015a3070dd17); - c->h[3] = U64(0x152fecd8f70e5939); - c->h[4] = U64(0x67332667ffc00b31); - c->h[5] = U64(0x8eb44a8768581511); - c->h[6] = U64(0xdb0c2e0d64f98fa7); - c->h[7] = U64(0x47b5481dbefa4fa4); - - c->Nl = 0; - c->Nh = 0; - c->num = 0; - c->md_len = SHA384_DIGEST_LENGTH; - return 1; -} - -fips_md_init(SHA512) -{ - c->h[0] = U64(0x6a09e667f3bcc908); - c->h[1] = U64(0xbb67ae8584caa73b); - c->h[2] = U64(0x3c6ef372fe94f82b); - c->h[3] = U64(0xa54ff53a5f1d36f1); - c->h[4] = U64(0x510e527fade682d1); - c->h[5] = U64(0x9b05688c2b3e6c1f); - c->h[6] = U64(0x1f83d9abfb41bd6b); - c->h[7] = U64(0x5be0cd19137e2179); - - c->Nl = 0; - c->Nh = 0; - c->num = 0; - c->md_len = SHA512_DIGEST_LENGTH; - return 1; -} - -# ifndef SHA512_ASM -static -# endif -void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); - -int SHA512_Final(unsigned char *md, SHA512_CTX *c) -{ - unsigned char *p = (unsigned char *)c->u.p; - size_t n = c->num; - - p[n] = 0x80; /* There always is a room for one */ - n++; - if (n > (sizeof(c->u) - 16)) - memset(p + n, 0, sizeof(c->u) - n), n = 0, - sha512_block_data_order(c, p, 1); - - memset(p + n, 0, sizeof(c->u) - 16 - n); -# ifdef B_ENDIAN - c->u.d[SHA_LBLOCK - 2] = c->Nh; - c->u.d[SHA_LBLOCK - 1] = c->Nl; -# else - p[sizeof(c->u) - 1] = (unsigned char)(c->Nl); - p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8); - p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16); - p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24); - p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32); - p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40); - p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48); - p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56); - p[sizeof(c->u) - 9] = (unsigned char)(c->Nh); - p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8); - p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16); - p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24); - p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32); - p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40); - p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48); - p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56); -# endif - - sha512_block_data_order(c, p, 1); - - if (md == 0) - return 0; - - switch (c->md_len) { - /* Let compiler decide if it's appropriate to unroll... */ - case SHA384_DIGEST_LENGTH: - for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) { - SHA_LONG64 t = c->h[n]; - - *(md++) = (unsigned char)(t >> 56); - *(md++) = (unsigned char)(t >> 48); - *(md++) = (unsigned char)(t >> 40); - *(md++) = (unsigned char)(t >> 32); - *(md++) = (unsigned char)(t >> 24); - *(md++) = (unsigned char)(t >> 16); - *(md++) = (unsigned char)(t >> 8); - *(md++) = (unsigned char)(t); - } - break; - case SHA512_DIGEST_LENGTH: - for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) { - SHA_LONG64 t = c->h[n]; - - *(md++) = (unsigned char)(t >> 56); - *(md++) = (unsigned char)(t >> 48); - *(md++) = (unsigned char)(t >> 40); - *(md++) = (unsigned char)(t >> 32); - *(md++) = (unsigned char)(t >> 24); - *(md++) = (unsigned char)(t >> 16); - *(md++) = (unsigned char)(t >> 8); - *(md++) = (unsigned char)(t); - } - break; - /* ... as well as make sure md_len is not abused. */ - default: - return 0; - } - - return 1; -} - -int SHA384_Final(unsigned char *md, SHA512_CTX *c) -{ - return SHA512_Final(md, c); -} - -int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len) -{ - SHA_LONG64 l; - unsigned char *p = c->u.p; - const unsigned char *data = (const unsigned char *)_data; - - if (len == 0) - return 1; - - l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff); - if (l < c->Nl) - c->Nh++; - if (sizeof(len) >= 8) - c->Nh += (((SHA_LONG64) len) >> 61); - c->Nl = l; - - if (c->num != 0) { - size_t n = sizeof(c->u) - c->num; - - if (len < n) { - memcpy(p + c->num, data, len), c->num += (unsigned int)len; - return 1; - } else { - memcpy(p + c->num, data, n), c->num = 0; - len -= n, data += n; - sha512_block_data_order(c, p, 1); - } - } - - if (len >= sizeof(c->u)) { -# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA - if ((size_t)data % sizeof(c->u.d[0]) != 0) - while (len >= sizeof(c->u)) - memcpy(p, data, sizeof(c->u)), - sha512_block_data_order(c, p, 1), - len -= sizeof(c->u), data += sizeof(c->u); - else -# endif - sha512_block_data_order(c, data, len / sizeof(c->u)), - data += len, len %= sizeof(c->u), data -= len; - } - - if (len != 0) - memcpy(p, data, len), c->num = (int)len; - - return 1; -} - -int SHA384_Update(SHA512_CTX *c, const void *data, size_t len) -{ - return SHA512_Update(c, data, len); -} - -void SHA512_Transform(SHA512_CTX *c, const unsigned char *data) -{ -# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA - if ((size_t)data % sizeof(c->u.d[0]) != 0) - memcpy(c->u.p, data, sizeof(c->u.p)), data = c->u.p; -# endif - sha512_block_data_order(c, data, 1); -} - -unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA512_CTX c; - static unsigned char m[SHA384_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - SHA384_Init(&c); - SHA512_Update(&c, d, n); - SHA512_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return (md); -} - -unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA512_CTX c; - static unsigned char m[SHA512_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - SHA512_Init(&c); - SHA512_Update(&c, d, n); - SHA512_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return (md); -} - -# ifndef SHA512_ASM -static const SHA_LONG64 K512[80] = { - U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd), - U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc), - U64(0x3956c25bf348b538), U64(0x59f111f1b605d019), - U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118), - U64(0xd807aa98a3030242), U64(0x12835b0145706fbe), - U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2), - U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1), - U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694), - U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3), - U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65), - U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483), - U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5), - U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210), - U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4), - U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725), - U64(0x06ca6351e003826f), U64(0x142929670a0e6e70), - U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926), - U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df), - U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8), - U64(0x81c2c92e47edaee6), U64(0x92722c851482353b), - U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001), - U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30), - U64(0xd192e819d6ef5218), U64(0xd69906245565a910), - U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8), - U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53), - U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8), - U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb), - U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3), - U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60), - U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec), - U64(0x90befffa23631e28), U64(0xa4506cebde82bde9), - U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b), - U64(0xca273eceea26619c), U64(0xd186b8c721c0c207), - U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178), - U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6), - U64(0x113f9804bef90dae), U64(0x1b710b35131c471b), - U64(0x28db77f523047d84), U64(0x32caab7b40c72493), - U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c), - U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a), - U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817) -}; - -# ifndef PEDANTIC -# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) -# if defined(__x86_64) || defined(__x86_64__) -# define ROTR(a,n) ({ SHA_LONG64 ret; \ - asm ("rorq %1,%0" \ - : "=r"(ret) \ - : "J"(n),"0"(a) \ - : "cc"); ret; }) -# if !defined(B_ENDIAN) -# define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x))); \ - asm ("bswapq %0" \ - : "=r"(ret) \ - : "0"(ret)); ret; }) -# endif -# elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN) -# if defined(I386_ONLY) -# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ - unsigned int hi=p[0],lo=p[1]; \ - asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\ - "roll $16,%%eax; roll $16,%%edx; "\ - "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \ - : "=a"(lo),"=d"(hi) \ - : "0"(lo),"1"(hi) : "cc"); \ - ((SHA_LONG64)hi)<<32|lo; }) -# else -# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ - unsigned int hi=p[0],lo=p[1]; \ - asm ("bswapl %0; bswapl %1;" \ - : "=r"(lo),"=r"(hi) \ - : "0"(lo),"1"(hi)); \ - ((SHA_LONG64)hi)<<32|lo; }) -# endif -# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) -# define ROTR(a,n) ({ SHA_LONG64 ret; \ - asm ("rotrdi %0,%1,%2" \ - : "=r"(ret) \ - : "r"(a),"K"(n)); ret; }) -# elif defined(__aarch64__) -# define ROTR(a,n) ({ SHA_LONG64 ret; \ - asm ("ror %0,%1,%2" \ - : "=r"(ret) \ - : "r"(a),"I"(n)); ret; }) -# if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ - __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ -# define PULL64(x) ({ SHA_LONG64 ret; \ - asm ("rev %0,%1" \ - : "=r"(ret) \ - : "r"(*((const SHA_LONG64 *)(&(x))))); ret; }) -# endif -# endif -# elif defined(_MSC_VER) -# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ -# pragma intrinsic(_rotr64) -# define ROTR(a,n) _rotr64((a),n) -# endif -# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) -# if defined(I386_ONLY) -static SHA_LONG64 __fastcall __pull64be(const void *x) -{ - _asm mov edx,[ecx + 0] - _asm mov eax,[ecx + 4] -_asm xchg dh, dl - _asm xchg ah, al - _asm rol edx, 16 _asm rol eax, 16 _asm xchg dh, dl _asm xchg ah, al} -# else -static SHA_LONG64 __fastcall __pull64be(const void *x) -{ - _asm mov edx,[ecx + 0] - _asm mov eax,[ecx + 4] -_asm bswap edx _asm bswap eax} -# endif -# define PULL64(x) __pull64be(&(x)) -# if _MSC_VER<=1200 -# pragma inline_depth(0) -# endif -# endif -# endif -# endif -# ifndef PULL64 -# define B(x,j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8)) -# define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7)) -# endif -# ifndef ROTR -# define ROTR(x,s) (((x)>>s) | (x)<<(64-s)) -# endif -# define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) -# define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) -# define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) -# define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) -# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) -# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) -# if defined(__i386) || defined(__i386__) || defined(_M_IX86) -/* - * This code should give better results on 32-bit CPU with less than - * ~24 registers, both size and performance wise... - */ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, - size_t num) -{ - const SHA_LONG64 *W = in; - SHA_LONG64 A, E, T; - SHA_LONG64 X[9 + 80], *F; - int i; - - while (num--) { - - F = X + 80; - A = ctx->h[0]; - F[1] = ctx->h[1]; - F[2] = ctx->h[2]; - F[3] = ctx->h[3]; - E = ctx->h[4]; - F[5] = ctx->h[5]; - F[6] = ctx->h[6]; - F[7] = ctx->h[7]; - - for (i = 0; i < 16; i++, F--) { -# ifdef B_ENDIAN - T = W[i]; -# else - T = PULL64(W[i]); -# endif - F[0] = A; - F[4] = E; - F[8] = T; - T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i]; - E = F[3] + T; - A = T + Sigma0(A) + Maj(A, F[1], F[2]); - } - - for (; i < 80; i++, F--) { - T = sigma0(F[8 + 16 - 1]); - T += sigma1(F[8 + 16 - 14]); - T += F[8 + 16] + F[8 + 16 - 9]; - - F[0] = A; - F[4] = E; - F[8] = T; - T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i]; - E = F[3] + T; - A = T + Sigma0(A) + Maj(A, F[1], F[2]); - } - - ctx->h[0] += A; - ctx->h[1] += F[1]; - ctx->h[2] += F[2]; - ctx->h[3] += F[3]; - ctx->h[4] += E; - ctx->h[5] += F[5]; - ctx->h[6] += F[6]; - ctx->h[7] += F[7]; - - W += SHA_LBLOCK; - } -} - -# elif defined(OPENSSL_SMALL_FOOTPRINT) -static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, - size_t num) -{ - const SHA_LONG64 *W = in; - SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2; - SHA_LONG64 X[16]; - int i; - - while (num--) { - - a = ctx->h[0]; - b = ctx->h[1]; - c = ctx->h[2]; - d = ctx->h[3]; - e = ctx->h[4]; - f = ctx->h[5]; - g = ctx->h[6]; - h = ctx->h[7]; - - for (i = 0; i < 16; i++) { -# ifdef B_ENDIAN - T1 = X[i] = W[i]; -# else - T1 = X[i] = PULL64(W[i]); -# endif - T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; - T2 = Sigma0(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - } - - for (; i < 80; i++) { - s0 = X[(i + 1) & 0x0f]; - s0 = sigma0(s0); - s1 = X[(i + 14) & 0x0f]; - s1 = sigma1(s1); - - T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; - T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; - T2 = Sigma0(a) + Maj(a, b, c); - h = g; - g = f; - f = e; - e = d + T1; - d = c; - c = b; - b = a; - a = T1 + T2; - } - - ctx->h[0] += a; - ctx->h[1] += b; - ctx->h[2] += c; - ctx->h[3] += d; - ctx->h[4] += e; - ctx->h[5] += f; - ctx->h[6] += g; - ctx->h[7] += h; - - W += SHA_LBLOCK; - } -} - -# else -# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ - T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \ - h = Sigma0(a) + Maj(a,b,c); \ - d += T1; h += T1; } while (0) -# define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \ - s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \ - s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \ - T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \ - ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0) -static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, - size_t num) -{ - const SHA_LONG64 *W = in; - SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1; - SHA_LONG64 X[16]; - int i; - - while (num--) { - - a = ctx->h[0]; - b = ctx->h[1]; - c = ctx->h[2]; - d = ctx->h[3]; - e = ctx->h[4]; - f = ctx->h[5]; - g = ctx->h[6]; - h = ctx->h[7]; - -# ifdef B_ENDIAN - T1 = X[0] = W[0]; - ROUND_00_15(0, a, b, c, d, e, f, g, h); - T1 = X[1] = W[1]; - ROUND_00_15(1, h, a, b, c, d, e, f, g); - T1 = X[2] = W[2]; - ROUND_00_15(2, g, h, a, b, c, d, e, f); - T1 = X[3] = W[3]; - ROUND_00_15(3, f, g, h, a, b, c, d, e); - T1 = X[4] = W[4]; - ROUND_00_15(4, e, f, g, h, a, b, c, d); - T1 = X[5] = W[5]; - ROUND_00_15(5, d, e, f, g, h, a, b, c); - T1 = X[6] = W[6]; - ROUND_00_15(6, c, d, e, f, g, h, a, b); - T1 = X[7] = W[7]; - ROUND_00_15(7, b, c, d, e, f, g, h, a); - T1 = X[8] = W[8]; - ROUND_00_15(8, a, b, c, d, e, f, g, h); - T1 = X[9] = W[9]; - ROUND_00_15(9, h, a, b, c, d, e, f, g); - T1 = X[10] = W[10]; - ROUND_00_15(10, g, h, a, b, c, d, e, f); - T1 = X[11] = W[11]; - ROUND_00_15(11, f, g, h, a, b, c, d, e); - T1 = X[12] = W[12]; - ROUND_00_15(12, e, f, g, h, a, b, c, d); - T1 = X[13] = W[13]; - ROUND_00_15(13, d, e, f, g, h, a, b, c); - T1 = X[14] = W[14]; - ROUND_00_15(14, c, d, e, f, g, h, a, b); - T1 = X[15] = W[15]; - ROUND_00_15(15, b, c, d, e, f, g, h, a); -# else - T1 = X[0] = PULL64(W[0]); - ROUND_00_15(0, a, b, c, d, e, f, g, h); - T1 = X[1] = PULL64(W[1]); - ROUND_00_15(1, h, a, b, c, d, e, f, g); - T1 = X[2] = PULL64(W[2]); - ROUND_00_15(2, g, h, a, b, c, d, e, f); - T1 = X[3] = PULL64(W[3]); - ROUND_00_15(3, f, g, h, a, b, c, d, e); - T1 = X[4] = PULL64(W[4]); - ROUND_00_15(4, e, f, g, h, a, b, c, d); - T1 = X[5] = PULL64(W[5]); - ROUND_00_15(5, d, e, f, g, h, a, b, c); - T1 = X[6] = PULL64(W[6]); - ROUND_00_15(6, c, d, e, f, g, h, a, b); - T1 = X[7] = PULL64(W[7]); - ROUND_00_15(7, b, c, d, e, f, g, h, a); - T1 = X[8] = PULL64(W[8]); - ROUND_00_15(8, a, b, c, d, e, f, g, h); - T1 = X[9] = PULL64(W[9]); - ROUND_00_15(9, h, a, b, c, d, e, f, g); - T1 = X[10] = PULL64(W[10]); - ROUND_00_15(10, g, h, a, b, c, d, e, f); - T1 = X[11] = PULL64(W[11]); - ROUND_00_15(11, f, g, h, a, b, c, d, e); - T1 = X[12] = PULL64(W[12]); - ROUND_00_15(12, e, f, g, h, a, b, c, d); - T1 = X[13] = PULL64(W[13]); - ROUND_00_15(13, d, e, f, g, h, a, b, c); - T1 = X[14] = PULL64(W[14]); - ROUND_00_15(14, c, d, e, f, g, h, a, b); - T1 = X[15] = PULL64(W[15]); - ROUND_00_15(15, b, c, d, e, f, g, h, a); -# endif - - for (i = 16; i < 80; i += 16) { - ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X); - ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X); - ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X); - ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X); - ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X); - ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X); - ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X); - ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X); - ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X); - ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X); - ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X); - ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X); - ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X); - ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X); - ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X); - ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X); - } - - ctx->h[0] += a; - ctx->h[1] += b; - ctx->h[2] += c; - ctx->h[3] += d; - ctx->h[4] += e; - ctx->h[5] += f; - ctx->h[6] += g; - ctx->h[7] += h; - - W += SHA_LBLOCK; - } -} - -# endif - -# endif /* SHA512_ASM */ - -#else /* !OPENSSL_NO_SHA512 */ - -# if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) -static void *dummy = &dummy; -# endif - -#endif /* !OPENSSL_NO_SHA512 */ diff --git a/Sources/COpenSSL/sha_.c b/Sources/COpenSSL/sha_.c deleted file mode 100644 index e289d108..00000000 --- a/Sources/COpenSSL/sha_.c +++ /dev/null @@ -1,153 +0,0 @@ -/* crypto/sha/sha1dgst.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "crypto.h" -#include "opensslconf.h" -#if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA) - -# undef SHA_1 -# define SHA_0 - -# include "opensslv.h" - -const char SHA_version[] = "SHA" OPENSSL_VERSION_PTEXT; - -/* The implementation is in ../md32_common.h */ - -# include "sha_locl.h" - -#endif -/* crypto/sha/sha_one.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include "sha.h" -// #include "crypto.h" - -#ifndef OPENSSL_NO_SHA0 -unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md) -{ - SHA_CTX c; - static unsigned char m[SHA_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - if (!SHA_Init(&c)) - return NULL; - SHA_Update(&c, d, n); - SHA_Final(md, &c); - OPENSSL_cleanse(&c, sizeof(c)); - return (md); -} -#endif diff --git a/Sources/COpenSSL/sha_locl.h b/Sources/COpenSSL/sha_locl.h deleted file mode 100644 index 8ebcf822..00000000 --- a/Sources/COpenSSL/sha_locl.h +++ /dev/null @@ -1,501 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/sha/sha_locl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include - -#include "opensslconf.h" -#include "sha.h" - -#define DATA_ORDER_IS_BIG_ENDIAN - -#define HASH_LONG SHA_LONG -#define HASH_CTX SHA_CTX -#define HASH_CBLOCK SHA_CBLOCK -#define HASH_MAKE_STRING(c,s) do { \ - unsigned long ll; \ - ll=(c)->h0; (void)HOST_l2c(ll,(s)); \ - ll=(c)->h1; (void)HOST_l2c(ll,(s)); \ - ll=(c)->h2; (void)HOST_l2c(ll,(s)); \ - ll=(c)->h3; (void)HOST_l2c(ll,(s)); \ - ll=(c)->h4; (void)HOST_l2c(ll,(s)); \ - } while (0) - -#if defined(SHA_0) - -# define HASH_UPDATE SHA_Update -# define HASH_TRANSFORM SHA_Transform -# define HASH_FINAL SHA_Final -# define HASH_INIT SHA_Init -# define HASH_BLOCK_DATA_ORDER sha_block_data_order -# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id)) - -static void sha_block_data_order(SHA_CTX *c, const void *p, size_t num); - -#elif defined(SHA_1) - -# define HASH_UPDATE SHA1_Update -# define HASH_TRANSFORM SHA1_Transform -# define HASH_FINAL SHA1_Final -# define HASH_INIT SHA1_Init -# define HASH_BLOCK_DATA_ORDER sha1_block_data_order -# if defined(__MWERKS__) && defined(__MC68K__) - /* Metrowerks for Motorola fails otherwise:-( */ -# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \ - ix=(a)=ROTATE((a),1); \ - } while (0) -# else -# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \ - ix=(a)=ROTATE((a),1) \ - ) -# endif - -# ifndef SHA1_ASM -static -# endif -void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num); - -#else -# error "Either SHA_0 or SHA_1 must be defined." -#endif - -#include "md32_common.h" - -#define INIT_DATA_h0 0x67452301UL -#define INIT_DATA_h1 0xefcdab89UL -#define INIT_DATA_h2 0x98badcfeUL -#define INIT_DATA_h3 0x10325476UL -#define INIT_DATA_h4 0xc3d2e1f0UL - -#ifdef SHA_0 -fips_md_init(SHA) -#else -fips_md_init_ctx(SHA1, SHA) -#endif -{ - memset(c, 0, sizeof(*c)); - c->h0 = INIT_DATA_h0; - c->h1 = INIT_DATA_h1; - c->h2 = INIT_DATA_h2; - c->h3 = INIT_DATA_h3; - c->h4 = INIT_DATA_h4; - return 1; -} - -#define K_00_19 0x5a827999UL -#define K_20_39 0x6ed9eba1UL -#define K_40_59 0x8f1bbcdcUL -#define K_60_79 0xca62c1d6UL - -/* - * As pointed out by Wei Dai , F() below can be simplified - * to the code in F_00_19. Wei attributes these optimisations to Peter - * Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define - * F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another - * tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a - */ -#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) -#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) -#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) -#define F_60_79(b,c,d) F_20_39(b,c,d) - -#ifndef OPENSSL_SMALL_FOOTPRINT - -# define BODY_00_15(i,a,b,c,d,e,f,xi) \ - (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ - (b)=ROTATE((b),30); - -# define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ - Xupdate(f,xi,xa,xb,xc,xd); \ - (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ - (b)=ROTATE((b),30); - -# define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ - Xupdate(f,xi,xa,xb,xc,xd); \ - (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ - (b)=ROTATE((b),30); - -# define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \ - Xupdate(f,xa,xa,xb,xc,xd); \ - (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ - (b)=ROTATE((b),30); - -# define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \ - Xupdate(f,xa,xa,xb,xc,xd); \ - (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ - (b)=ROTATE((b),30); - -# define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \ - Xupdate(f,xa,xa,xb,xc,xd); \ - (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ - (b)=ROTATE((b),30); - -# ifdef X -# undef X -# endif -# ifndef MD32_XARRAY - /* - * Originally X was an array. As it's automatic it's natural - * to expect RISC compiler to accomodate at least part of it in - * the register bank, isn't it? Unfortunately not all compilers - * "find" this expectation reasonable:-( On order to make such - * compilers generate better code I replace X[] with a bunch of - * X0, X1, etc. See the function body below... - * - */ -# define X(i) XX##i -# else - /* - * However! Some compilers (most notably HP C) get overwhelmed by - * that many local variables so that we have to have the way to - * fall down to the original behavior. - */ -# define X(i) XX[i] -# endif - -# if !defined(SHA_1) || !defined(SHA1_ASM) -static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) -{ - const unsigned char *data = p; - register unsigned MD32_REG_T A, B, C, D, E, T, l; -# ifndef MD32_XARRAY - unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, - XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; -# else - SHA_LONG XX[16]; -# endif - - A = c->h0; - B = c->h1; - C = c->h2; - D = c->h3; - E = c->h4; - - for (;;) { - const union { - long one; - char little; - } is_endian = { - 1 - }; - - if (!is_endian.little && sizeof(SHA_LONG) == 4 - && ((size_t)p % 4) == 0) { - const SHA_LONG *W = (const SHA_LONG *)data; - - X(0) = W[0]; - X(1) = W[1]; - BODY_00_15(0, A, B, C, D, E, T, X(0)); - X(2) = W[2]; - BODY_00_15(1, T, A, B, C, D, E, X(1)); - X(3) = W[3]; - BODY_00_15(2, E, T, A, B, C, D, X(2)); - X(4) = W[4]; - BODY_00_15(3, D, E, T, A, B, C, X(3)); - X(5) = W[5]; - BODY_00_15(4, C, D, E, T, A, B, X(4)); - X(6) = W[6]; - BODY_00_15(5, B, C, D, E, T, A, X(5)); - X(7) = W[7]; - BODY_00_15(6, A, B, C, D, E, T, X(6)); - X(8) = W[8]; - BODY_00_15(7, T, A, B, C, D, E, X(7)); - X(9) = W[9]; - BODY_00_15(8, E, T, A, B, C, D, X(8)); - X(10) = W[10]; - BODY_00_15(9, D, E, T, A, B, C, X(9)); - X(11) = W[11]; - BODY_00_15(10, C, D, E, T, A, B, X(10)); - X(12) = W[12]; - BODY_00_15(11, B, C, D, E, T, A, X(11)); - X(13) = W[13]; - BODY_00_15(12, A, B, C, D, E, T, X(12)); - X(14) = W[14]; - BODY_00_15(13, T, A, B, C, D, E, X(13)); - X(15) = W[15]; - BODY_00_15(14, E, T, A, B, C, D, X(14)); - BODY_00_15(15, D, E, T, A, B, C, X(15)); - - data += SHA_CBLOCK; - } else { - (void)HOST_c2l(data, l); - X(0) = l; - (void)HOST_c2l(data, l); - X(1) = l; - BODY_00_15(0, A, B, C, D, E, T, X(0)); - (void)HOST_c2l(data, l); - X(2) = l; - BODY_00_15(1, T, A, B, C, D, E, X(1)); - (void)HOST_c2l(data, l); - X(3) = l; - BODY_00_15(2, E, T, A, B, C, D, X(2)); - (void)HOST_c2l(data, l); - X(4) = l; - BODY_00_15(3, D, E, T, A, B, C, X(3)); - (void)HOST_c2l(data, l); - X(5) = l; - BODY_00_15(4, C, D, E, T, A, B, X(4)); - (void)HOST_c2l(data, l); - X(6) = l; - BODY_00_15(5, B, C, D, E, T, A, X(5)); - (void)HOST_c2l(data, l); - X(7) = l; - BODY_00_15(6, A, B, C, D, E, T, X(6)); - (void)HOST_c2l(data, l); - X(8) = l; - BODY_00_15(7, T, A, B, C, D, E, X(7)); - (void)HOST_c2l(data, l); - X(9) = l; - BODY_00_15(8, E, T, A, B, C, D, X(8)); - (void)HOST_c2l(data, l); - X(10) = l; - BODY_00_15(9, D, E, T, A, B, C, X(9)); - (void)HOST_c2l(data, l); - X(11) = l; - BODY_00_15(10, C, D, E, T, A, B, X(10)); - (void)HOST_c2l(data, l); - X(12) = l; - BODY_00_15(11, B, C, D, E, T, A, X(11)); - (void)HOST_c2l(data, l); - X(13) = l; - BODY_00_15(12, A, B, C, D, E, T, X(12)); - (void)HOST_c2l(data, l); - X(14) = l; - BODY_00_15(13, T, A, B, C, D, E, X(13)); - (void)HOST_c2l(data, l); - X(15) = l; - BODY_00_15(14, E, T, A, B, C, D, X(14)); - BODY_00_15(15, D, E, T, A, B, C, X(15)); - } - - BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13)); - BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14)); - BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15)); - BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0)); - - BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1)); - BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2)); - BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3)); - BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4)); - BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5)); - BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6)); - BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7)); - BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8)); - BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9)); - BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10)); - BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11)); - BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12)); - - BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13)); - BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14)); - BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15)); - BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0)); - BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1)); - BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2)); - BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3)); - BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4)); - - BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5)); - BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6)); - BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7)); - BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8)); - BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9)); - BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10)); - BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11)); - BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12)); - BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13)); - BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14)); - BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15)); - BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0)); - BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1)); - BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2)); - BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3)); - BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4)); - BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5)); - BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6)); - BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7)); - BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8)); - - BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9)); - BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10)); - BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11)); - BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12)); - BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13)); - BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14)); - BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15)); - BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0)); - BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1)); - BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2)); - BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3)); - BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4)); - BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5)); - BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6)); - BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7)); - BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8)); - BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9)); - BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10)); - BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11)); - BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12)); - - c->h0 = (c->h0 + E) & 0xffffffffL; - c->h1 = (c->h1 + T) & 0xffffffffL; - c->h2 = (c->h2 + A) & 0xffffffffL; - c->h3 = (c->h3 + B) & 0xffffffffL; - c->h4 = (c->h4 + C) & 0xffffffffL; - - if (--num == 0) - break; - - A = c->h0; - B = c->h1; - C = c->h2; - D = c->h3; - E = c->h4; - - } -} -# endif - -#else /* OPENSSL_SMALL_FOOTPRINT */ - -# define BODY_00_15(xi) do { \ - T=E+K_00_19+F_00_19(B,C,D); \ - E=D, D=C, C=ROTATE(B,30), B=A; \ - A=ROTATE(A,5)+T+xi; } while(0) - -# define BODY_16_19(xa,xb,xc,xd) do { \ - Xupdate(T,xa,xa,xb,xc,xd); \ - T+=E+K_00_19+F_00_19(B,C,D); \ - E=D, D=C, C=ROTATE(B,30), B=A; \ - A=ROTATE(A,5)+T; } while(0) - -# define BODY_20_39(xa,xb,xc,xd) do { \ - Xupdate(T,xa,xa,xb,xc,xd); \ - T+=E+K_20_39+F_20_39(B,C,D); \ - E=D, D=C, C=ROTATE(B,30), B=A; \ - A=ROTATE(A,5)+T; } while(0) - -# define BODY_40_59(xa,xb,xc,xd) do { \ - Xupdate(T,xa,xa,xb,xc,xd); \ - T+=E+K_40_59+F_40_59(B,C,D); \ - E=D, D=C, C=ROTATE(B,30), B=A; \ - A=ROTATE(A,5)+T; } while(0) - -# define BODY_60_79(xa,xb,xc,xd) do { \ - Xupdate(T,xa,xa,xb,xc,xd); \ - T=E+K_60_79+F_60_79(B,C,D); \ - E=D, D=C, C=ROTATE(B,30), B=A; \ - A=ROTATE(A,5)+T+xa; } while(0) - -# if !defined(SHA_1) || !defined(SHA1_ASM) -static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) -{ - const unsigned char *data = p; - register unsigned MD32_REG_T A, B, C, D, E, T, l; - int i; - SHA_LONG X[16]; - - A = c->h0; - B = c->h1; - C = c->h2; - D = c->h3; - E = c->h4; - - for (;;) { - for (i = 0; i < 16; i++) { - HOST_c2l(data, l); - X[i] = l; - BODY_00_15(X[i]); - } - for (i = 0; i < 4; i++) { - BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]); - } - for (; i < 24; i++) { - BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15], - X[(i + 13) & 15]); - } - for (i = 0; i < 20; i++) { - BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], - X[(i + 5) & 15]); - } - for (i = 4; i < 24; i++) { - BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], - X[(i + 5) & 15]); - } - - c->h0 = (c->h0 + A) & 0xffffffffL; - c->h1 = (c->h1 + B) & 0xffffffffL; - c->h2 = (c->h2 + C) & 0xffffffffL; - c->h3 = (c->h3 + D) & 0xffffffffL; - c->h4 = (c->h4 + E) & 0xffffffffL; - - if (--num == 0) - break; - - A = c->h0; - B = c->h1; - C = c->h2; - D = c->h3; - E = c->h4; - - } -} -# endif - -#endif diff --git a/Sources/COpenSSL/spr.h b/Sources/COpenSSL/spr.h deleted file mode 100644 index e85d3100..00000000 --- a/Sources/COpenSSL/spr.h +++ /dev/null @@ -1,212 +0,0 @@ -/* crypto/des/spr.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64] = { - { - /* nibble 0 */ - 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, - 0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, - 0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, - 0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, - 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, - 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, - 0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, - 0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, - 0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, - 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, - 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, - 0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, - 0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, - 0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, - 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, - 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, - }, - { - /* nibble 1 */ - 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, - 0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, - 0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, - 0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, - 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, - 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, - 0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, - 0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, - 0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, - 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, - 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, - 0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, - 0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, - 0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, - 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, - 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, - }, - { - /* nibble 2 */ - 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, - 0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, - 0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, - 0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, - 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, - 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, - 0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, - 0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, - 0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, - 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, - 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, - 0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, - 0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, - 0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, - 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, - 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, - }, - { - /* nibble 3 */ - 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, - 0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, - 0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, - 0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, - 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, - 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, - 0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, - 0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, - 0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, - 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, - 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, - 0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, - 0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, - 0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, - 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, - 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, - }, - { - /* nibble 4 */ - 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, - 0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, - 0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, - 0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, - 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, - 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, - 0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, - 0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, - 0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, - 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, - 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, - 0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, - 0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, - 0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, - 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, - 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, - }, - { - /* nibble 5 */ - 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, - 0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, - 0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, - 0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, - 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, - 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, - 0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, - 0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, - 0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, - 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, - 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, - 0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, - 0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, - 0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, - 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, - 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, - }, - { - /* nibble 6 */ - 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, - 0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, - 0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, - 0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, - 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, - 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, - 0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, - 0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, - 0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, - 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, - 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, - 0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, - 0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, - 0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, - 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, - 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, - }, - { - /* nibble 7 */ - 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, - 0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, - 0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, - 0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, - 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, - 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, - 0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, - 0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, - 0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, - 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, - 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, - 0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, - 0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, - 0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, - 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, - 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, - } -}; diff --git a/Sources/COpenSSL/srp.h b/Sources/COpenSSL/srp.h deleted file mode 100644 index 20816b67..00000000 --- a/Sources/COpenSSL/srp.h +++ /dev/null @@ -1,179 +0,0 @@ -/* crypto/srp/srp.h */ -/* - * Written by Christophe Renou (christophe.renou@edelweb.fr) with the - * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the - * EdelKey project and contributed to the OpenSSL project 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef __SRP_H__ -# define __SRP_H__ - -# ifndef OPENSSL_NO_SRP - -# include -# include - -#ifdef __cplusplus -extern "C" { -#endif - -# include "safestack.h" -# include "bn.h" -# include "crypto.h" - -typedef struct SRP_gN_cache_st { - char *b64_bn; - BIGNUM *bn; -} SRP_gN_cache; - - -DECLARE_STACK_OF(SRP_gN_cache) - -typedef struct SRP_user_pwd_st { - /* Owned by us. */ - char *id; - BIGNUM *s; - BIGNUM *v; - /* Not owned by us. */ - const BIGNUM *g; - const BIGNUM *N; - /* Owned by us. */ - char *info; -} SRP_user_pwd; - -DECLARE_STACK_OF(SRP_user_pwd) - -void SRP_user_pwd_free(SRP_user_pwd *user_pwd); - -typedef struct SRP_VBASE_st { - STACK_OF(SRP_user_pwd) *users_pwd; - STACK_OF(SRP_gN_cache) *gN_cache; -/* to simulate a user */ - char *seed_key; - BIGNUM *default_g; - BIGNUM *default_N; -} SRP_VBASE; - -/* - * Structure interne pour retenir les couples N et g - */ -typedef struct SRP_gN_st { - char *id; - BIGNUM *g; - BIGNUM *N; -} SRP_gN; - -DECLARE_STACK_OF(SRP_gN) - -SRP_VBASE *SRP_VBASE_new(char *seed_key); -int SRP_VBASE_free(SRP_VBASE *vb); -int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file); - -/* This method ignores the configured seed and fails for an unknown user. */ -SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username); -/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/ -SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); - -char *SRP_create_verifier(const char *user, const char *pass, char **salt, - char **verifier, const char *N, const char *g); -int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, - BIGNUM **verifier, BIGNUM *N, BIGNUM *g); - -# define SRP_NO_ERROR 0 -# define SRP_ERR_VBASE_INCOMPLETE_FILE 1 -# define SRP_ERR_VBASE_BN_LIB 2 -# define SRP_ERR_OPEN_FILE 3 -# define SRP_ERR_MEMORY 4 - -# define DB_srptype 0 -# define DB_srpverifier 1 -# define DB_srpsalt 2 -# define DB_srpid 3 -# define DB_srpgN 4 -# define DB_srpinfo 5 -# undef DB_NUMBER -# define DB_NUMBER 6 - -# define DB_SRP_INDEX 'I' -# define DB_SRP_VALID 'V' -# define DB_SRP_REVOKED 'R' -# define DB_SRP_MODIF 'v' - -/* see srp.c */ -char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N); -SRP_gN *SRP_get_default_gN(const char *id); - -/* server side .... */ -BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, - BIGNUM *N); -BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v); -int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N); -BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N); - -/* client side .... */ -BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass); -BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g); -BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, - BIGNUM *a, BIGNUM *u); -int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N); - -# define SRP_MINIMAL_N 1024 - -#ifdef __cplusplus -} -#endif - -# endif -#endif diff --git a/Sources/COpenSSL/srp_.c b/Sources/COpenSSL/srp_.c deleted file mode 100644 index cdbb8769..00000000 --- a/Sources/COpenSSL/srp_.c +++ /dev/null @@ -1,1091 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/srp/srp_lib.c */ -/* - * Written by Christophe Renou (christophe.renou@edelweb.fr) with the - * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the - * EdelKey project and contributed to the OpenSSL project 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef OPENSSL_NO_SRP -# include "cryptlib.h" -# include "srp_lcl.h" -# include "srp.h" -# include "evp.h" - -# if (BN_BYTES == 8) -# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) -# define bn_pack4(a1,a2,a3,a4) ((a1##UI64<<48)|(a2##UI64<<32)|(a3##UI64<<16)|a4##UI64) -# elif defined(__arch64__) -# define bn_pack4(a1,a2,a3,a4) ((a1##UL<<48)|(a2##UL<<32)|(a3##UL<<16)|a4##UL) -# else -# define bn_pack4(a1,a2,a3,a4) ((a1##ULL<<48)|(a2##ULL<<32)|(a3##ULL<<16)|a4##ULL) -# endif -# elif (BN_BYTES == 4) -# define bn_pack4(a1,a2,a3,a4) ((a3##UL<<16)|a4##UL), ((a1##UL<<16)|a2##UL) -# else -# error "unsupported BN_BYTES" -# endif - -# include "srp_grps.h" - -static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g) -{ - /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */ - - unsigned char digest[SHA_DIGEST_LENGTH]; - unsigned char *tmp; - EVP_MD_CTX ctxt; - int longg; - int longN = BN_num_bytes(N); - - if (BN_ucmp(g, N) >= 0) - return NULL; - - if ((tmp = OPENSSL_malloc(longN)) == NULL) - return NULL; - BN_bn2bin(N, tmp); - - EVP_MD_CTX_init(&ctxt); - EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); - EVP_DigestUpdate(&ctxt, tmp, longN); - - memset(tmp, 0, longN); - longg = BN_bn2bin(g, tmp); - /* use the zeros behind to pad on left */ - EVP_DigestUpdate(&ctxt, tmp + longg, longN - longg); - EVP_DigestUpdate(&ctxt, tmp, longg); - OPENSSL_free(tmp); - - EVP_DigestFinal_ex(&ctxt, digest, NULL); - EVP_MD_CTX_cleanup(&ctxt); - return BN_bin2bn(digest, sizeof(digest), NULL); -} - -BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) -{ - /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */ - - BIGNUM *u; - unsigned char cu[SHA_DIGEST_LENGTH]; - unsigned char *cAB; - EVP_MD_CTX ctxt; - int longN; - if ((A == NULL) || (B == NULL) || (N == NULL)) - return NULL; - - if (BN_ucmp(A, N) >= 0 || BN_ucmp(B, N) >= 0) - return NULL; - - longN = BN_num_bytes(N); - - if ((cAB = OPENSSL_malloc(2 * longN)) == NULL) - return NULL; - - memset(cAB, 0, longN); - - EVP_MD_CTX_init(&ctxt); - EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); - EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A, cAB + longN), longN); - EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B, cAB + longN), longN); - OPENSSL_free(cAB); - EVP_DigestFinal_ex(&ctxt, cu, NULL); - EVP_MD_CTX_cleanup(&ctxt); - - if (!(u = BN_bin2bn(cu, sizeof(cu), NULL))) - return NULL; - if (!BN_is_zero(u)) - return u; - BN_free(u); - return NULL; -} - -BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, - BIGNUM *N) -{ - BIGNUM *tmp = NULL, *S = NULL; - BN_CTX *bn_ctx; - - if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL) - return NULL; - - if ((bn_ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL) - goto err; - - /* S = (A*v**u) ** b */ - - if (!BN_mod_exp(tmp, v, u, N, bn_ctx)) - goto err; - if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx)) - goto err; - - S = BN_new(); - if (S != NULL && !BN_mod_exp(S, tmp, b, N, bn_ctx)) { - BN_free(S); - S = NULL; - } - err: - BN_CTX_free(bn_ctx); - BN_clear_free(tmp); - return S; -} - -BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v) -{ - BIGNUM *kv = NULL, *gb = NULL; - BIGNUM *B = NULL, *k = NULL; - BN_CTX *bn_ctx; - - if (b == NULL || N == NULL || g == NULL || v == NULL || - (bn_ctx = BN_CTX_new()) == NULL) - return NULL; - - if ((kv = BN_new()) == NULL || - (gb = BN_new()) == NULL || (B = BN_new()) == NULL) - goto err; - - /* B = g**b + k*v */ - - if (!BN_mod_exp(gb, g, b, N, bn_ctx) || - !(k = srp_Calc_k(N, g)) || - !BN_mod_mul(kv, v, k, N, bn_ctx) || - !BN_mod_add(B, gb, kv, N, bn_ctx)) { - BN_free(B); - B = NULL; - } - err: - BN_CTX_free(bn_ctx); - BN_clear_free(kv); - BN_clear_free(gb); - BN_free(k); - return B; -} - -BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass) -{ - unsigned char dig[SHA_DIGEST_LENGTH]; - EVP_MD_CTX ctxt; - unsigned char *cs; - - if ((s == NULL) || (user == NULL) || (pass == NULL)) - return NULL; - - if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL) - return NULL; - - EVP_MD_CTX_init(&ctxt); - EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); - EVP_DigestUpdate(&ctxt, user, strlen(user)); - EVP_DigestUpdate(&ctxt, ":", 1); - EVP_DigestUpdate(&ctxt, pass, strlen(pass)); - EVP_DigestFinal_ex(&ctxt, dig, NULL); - - EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); - BN_bn2bin(s, cs); - EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s)); - OPENSSL_free(cs); - EVP_DigestUpdate(&ctxt, dig, sizeof(dig)); - EVP_DigestFinal_ex(&ctxt, dig, NULL); - EVP_MD_CTX_cleanup(&ctxt); - - return BN_bin2bn(dig, sizeof(dig), NULL); -} - -BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g) -{ - BN_CTX *bn_ctx; - BIGNUM *A = NULL; - - if (a == NULL || N == NULL || g == NULL || - (bn_ctx = BN_CTX_new()) == NULL) - return NULL; - - if ((A = BN_new()) != NULL && !BN_mod_exp(A, g, a, N, bn_ctx)) { - BN_free(A); - A = NULL; - } - BN_CTX_free(bn_ctx); - return A; -} - -BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, - BIGNUM *a, BIGNUM *u) -{ - BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL; - BN_CTX *bn_ctx; - - if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL - || a == NULL || (bn_ctx = BN_CTX_new()) == NULL) - return NULL; - - if ((tmp = BN_new()) == NULL || - (tmp2 = BN_new()) == NULL || - (tmp3 = BN_new()) == NULL) - goto err; - - if (!BN_mod_exp(tmp, g, x, N, bn_ctx)) - goto err; - if (!(k = srp_Calc_k(N, g))) - goto err; - if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx)) - goto err; - if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx)) - goto err; - - if (!BN_mul(tmp3, u, x, bn_ctx)) - goto err; - if (!BN_add(tmp2, a, tmp3)) - goto err; - K = BN_new(); - if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) { - BN_free(K); - K = NULL; - } - - err: - BN_CTX_free(bn_ctx); - BN_clear_free(tmp); - BN_clear_free(tmp2); - BN_clear_free(tmp3); - BN_free(k); - return K; -} - -int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N) -{ - BIGNUM *r; - BN_CTX *bn_ctx; - int ret = 0; - - if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL) - return 0; - - if ((r = BN_new()) == NULL) - goto err; - /* Checks if B % N == 0 */ - if (!BN_nnmod(r, B, N, bn_ctx)) - goto err; - ret = !BN_is_zero(r); - err: - BN_CTX_free(bn_ctx); - BN_free(r); - return ret; -} - -int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N) -{ - /* Checks if A % N == 0 */ - return SRP_Verify_B_mod_N(A, N); -} - -/* - * Check if G and N are kwown parameters. The values have been generated - * from the ietf-tls-srp draft version 8 - */ -char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N) -{ - size_t i; - if ((g == NULL) || (N == NULL)) - return 0; - - srp_bn_print(g); - srp_bn_print(N); - - for (i = 0; i < KNOWN_GN_NUMBER; i++) { - if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0) - return knowngN[i].id; - } - return NULL; -} - -SRP_gN *SRP_get_default_gN(const char *id) -{ - size_t i; - - if (id == NULL) - return knowngN; - for (i = 0; i < KNOWN_GN_NUMBER; i++) { - if (strcmp(knowngN[i].id, id) == 0) - return knowngN + i; - } - return NULL; -} -#endif -/* crypto/srp/srp_vfy.c */ -/* - * Written by Christophe Renou (christophe.renou@edelweb.fr) with the - * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the - * EdelKey project and contributed to the OpenSSL project 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef OPENSSL_NO_SRP -# include "cryptlib.h" -# include "srp_lcl.h" -# include "srp.h" -# include "evp.h" -# include "buffer.h" -# include "rand.h" -# include "txt_db.h" - -# define SRP_RANDOM_SALT_LEN 20 -# define MAX_LEN 2500 - -static char b64table[] = - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; - -/* - * the following two conversion routines have been inspired by code from - * Stanford - */ - -/* - * Convert a base64 string into raw byte array representation. - */ -static int t_fromb64(unsigned char *a, size_t alen, const char *src) -{ - char *loc; - int i, j; - int size; - - if (alen == 0 || alen > INT_MAX) - return -1; - - while (*src && (*src == ' ' || *src == '\t' || *src == '\n')) - ++src; - size = strlen(src); - if (size < 0 || size >= (int)alen) - return -1; - - i = 0; - while (i < size) { - loc = strchr(b64table, src[i]); - if (loc == (char *)0) - break; - else - a[i] = loc - b64table; - ++i; - } - /* if nothing valid to process we have a zero length response */ - if (i == 0) - return 0; - size = i; - i = size - 1; - j = size; - while (1) { - a[j] = a[i]; - if (--i < 0) - break; - a[j] |= (a[i] & 3) << 6; - --j; - a[j] = (unsigned char)((a[i] & 0x3c) >> 2); - if (--i < 0) - break; - a[j] |= (a[i] & 0xf) << 4; - --j; - a[j] = (unsigned char)((a[i] & 0x30) >> 4); - if (--i < 0) - break; - a[j] |= (a[i] << 2); - - a[--j] = 0; - if (--i < 0) - break; - } - while (j <= size && a[j] == 0) - ++j; - i = 0; - while (j <= size) - a[i++] = a[j++]; - return i; -} - -/* - * Convert a raw byte string into a null-terminated base64 ASCII string. - */ -static char *t_tob64(char *dst, const unsigned char *src, int size) -{ - int c, pos = size % 3; - unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0; - char *olddst = dst; - - switch (pos) { - case 1: - b2 = src[0]; - break; - case 2: - b1 = src[0]; - b2 = src[1]; - break; - } - - while (1) { - c = (b0 & 0xfc) >> 2; - if (notleading || c != 0) { - *dst++ = b64table[c]; - notleading = 1; - } - c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4); - if (notleading || c != 0) { - *dst++ = b64table[c]; - notleading = 1; - } - c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6); - if (notleading || c != 0) { - *dst++ = b64table[c]; - notleading = 1; - } - c = b2 & 0x3f; - if (notleading || c != 0) { - *dst++ = b64table[c]; - notleading = 1; - } - if (pos >= size) - break; - else { - b0 = src[pos++]; - b1 = src[pos++]; - b2 = src[pos++]; - } - } - - *dst++ = '\0'; - return olddst; -} - -void SRP_user_pwd_free(SRP_user_pwd *user_pwd) -{ - if (user_pwd == NULL) - return; - BN_free(user_pwd->s); - BN_clear_free(user_pwd->v); - OPENSSL_free(user_pwd->id); - OPENSSL_free(user_pwd->info); - OPENSSL_free(user_pwd); -} - -static SRP_user_pwd *SRP_user_pwd_new() -{ - SRP_user_pwd *ret = OPENSSL_malloc(sizeof(SRP_user_pwd)); - if (ret == NULL) - return NULL; - ret->N = NULL; - ret->g = NULL; - ret->s = NULL; - ret->v = NULL; - ret->id = NULL; - ret->info = NULL; - return ret; -} - -static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g, - const BIGNUM *N) -{ - vinfo->N = N; - vinfo->g = g; -} - -static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id, - const char *info) -{ - if (id != NULL && NULL == (vinfo->id = BUF_strdup(id))) - return 0; - return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))); -} - -static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s, - const char *v) -{ - unsigned char tmp[MAX_LEN]; - int len; - - vinfo->v = NULL; - vinfo->s = NULL; - - len = t_fromb64(tmp, sizeof(tmp), v); - if (len < 0) - return 0; - if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL))) - return 0; - len = t_fromb64(tmp, sizeof(tmp), s); - if (len < 0) - goto err; - vinfo->s = BN_bin2bn(tmp, len, NULL); - if (vinfo->s == NULL) - goto err; - return 1; - err: - BN_free(vinfo->v); - vinfo->v = NULL; - return 0; -} - -static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v) -{ - vinfo->v = v; - vinfo->s = s; - return (vinfo->s != NULL && vinfo->v != NULL); -} - -static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src) -{ - SRP_user_pwd *ret; - - if (src == NULL) - return NULL; - if ((ret = SRP_user_pwd_new()) == NULL) - return NULL; - - SRP_user_pwd_set_gN(ret, src->g, src->N); - if (!SRP_user_pwd_set_ids(ret, src->id, src->info) - || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) { - SRP_user_pwd_free(ret); - return NULL; - } - return ret; -} - -SRP_VBASE *SRP_VBASE_new(char *seed_key) -{ - SRP_VBASE *vb = (SRP_VBASE *)OPENSSL_malloc(sizeof(SRP_VBASE)); - - if (vb == NULL) - return NULL; - if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) || - !(vb->gN_cache = sk_SRP_gN_cache_new_null())) { - OPENSSL_free(vb); - return NULL; - } - vb->default_g = NULL; - vb->default_N = NULL; - vb->seed_key = NULL; - if ((seed_key != NULL) && (vb->seed_key = BUF_strdup(seed_key)) == NULL) { - sk_SRP_user_pwd_free(vb->users_pwd); - sk_SRP_gN_cache_free(vb->gN_cache); - OPENSSL_free(vb); - return NULL; - } - return vb; -} - -int SRP_VBASE_free(SRP_VBASE *vb) -{ - sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free); - sk_SRP_gN_cache_free(vb->gN_cache); - OPENSSL_free(vb->seed_key); - OPENSSL_free(vb); - return 0; -} - -static SRP_gN_cache *SRP_gN_new_init(const char *ch) -{ - unsigned char tmp[MAX_LEN]; - int len; - - SRP_gN_cache *newgN = - (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache)); - if (newgN == NULL) - return NULL; - - len = t_fromb64(tmp, sizeof(tmp), ch); - if (len < 0) - goto err; - - if ((newgN->b64_bn = BUF_strdup(ch)) == NULL) - goto err; - - if ((newgN->bn = BN_bin2bn(tmp, len, NULL))) - return newgN; - - OPENSSL_free(newgN->b64_bn); - err: - OPENSSL_free(newgN); - return NULL; -} - -static void SRP_gN_free(SRP_gN_cache *gN_cache) -{ - if (gN_cache == NULL) - return; - OPENSSL_free(gN_cache->b64_bn); - BN_free(gN_cache->bn); - OPENSSL_free(gN_cache); -} - -static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab) -{ - int i; - - SRP_gN *gN; - if (gN_tab != NULL) - for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) { - gN = sk_SRP_gN_value(gN_tab, i); - if (gN && (id == NULL || strcmp(gN->id, id) == 0)) - return gN; - } - - return SRP_get_default_gN(id); -} - -static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch) -{ - int i; - if (gN_cache == NULL) - return NULL; - - /* search if we have already one... */ - for (i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) { - SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i); - if (strcmp(cache->b64_bn, ch) == 0) - return cache->bn; - } - { /* it is the first time that we find it */ - SRP_gN_cache *newgN = SRP_gN_new_init(ch); - if (newgN) { - if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0) - return newgN->bn; - SRP_gN_free(newgN); - } - } - return NULL; -} - -/* - * this function parses verifier file. Format is: - * string(index):base64(N):base64(g):0 - * string(username):base64(v):base64(salt):int(index) - */ - -int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) -{ - int error_code; - STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null(); - char *last_index = NULL; - int i; - char **pp; - - SRP_gN *gN = NULL; - SRP_user_pwd *user_pwd = NULL; - - TXT_DB *tmpdb = NULL; - BIO *in = BIO_new(BIO_s_file()); - - error_code = SRP_ERR_OPEN_FILE; - - if (in == NULL || BIO_read_filename(in, verifier_file) <= 0) - goto err; - - error_code = SRP_ERR_VBASE_INCOMPLETE_FILE; - - if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) - goto err; - - error_code = SRP_ERR_MEMORY; - - if (vb->seed_key) { - last_index = SRP_get_default_gN(NULL)->id; - } - for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) { - pp = sk_OPENSSL_PSTRING_value(tmpdb->data, i); - if (pp[DB_srptype][0] == DB_SRP_INDEX) { - /* - * we add this couple in the internal Stack - */ - - if ((gN = (SRP_gN *) OPENSSL_malloc(sizeof(SRP_gN))) == NULL) - goto err; - - if (!(gN->id = BUF_strdup(pp[DB_srpid])) - || !(gN->N = - SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier])) - || !(gN->g = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpsalt])) - || sk_SRP_gN_insert(SRP_gN_tab, gN, 0) == 0) - goto err; - - gN = NULL; - - if (vb->seed_key != NULL) { - last_index = pp[DB_srpid]; - } - } else if (pp[DB_srptype][0] == DB_SRP_VALID) { - /* it is a user .... */ - SRP_gN *lgN; - if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN], SRP_gN_tab)) != NULL) { - error_code = SRP_ERR_MEMORY; - if ((user_pwd = SRP_user_pwd_new()) == NULL) - goto err; - - SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N); - if (!SRP_user_pwd_set_ids - (user_pwd, pp[DB_srpid], pp[DB_srpinfo])) - goto err; - - error_code = SRP_ERR_VBASE_BN_LIB; - if (!SRP_user_pwd_set_sv - (user_pwd, pp[DB_srpsalt], pp[DB_srpverifier])) - goto err; - - if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0) - goto err; - user_pwd = NULL; /* abandon responsability */ - } - } - } - - if (last_index != NULL) { - /* this means that we want to simulate a default user */ - - if (((gN = SRP_get_gN_by_id(last_index, SRP_gN_tab)) == NULL)) { - error_code = SRP_ERR_VBASE_BN_LIB; - goto err; - } - vb->default_g = gN->g; - vb->default_N = gN->N; - gN = NULL; - } - error_code = SRP_NO_ERROR; - - err: - /* - * there may be still some leaks to fix, if this fails, the application - * terminates most likely - */ - - if (gN != NULL) { - OPENSSL_free(gN->id); - OPENSSL_free(gN); - } - - SRP_user_pwd_free(user_pwd); - - if (tmpdb) - TXT_DB_free(tmpdb); - if (in) - BIO_free_all(in); - - sk_SRP_gN_free(SRP_gN_tab); - - return error_code; - -} - -static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username) -{ - int i; - SRP_user_pwd *user; - - if (vb == NULL) - return NULL; - - for (i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) { - user = sk_SRP_user_pwd_value(vb->users_pwd, i); - if (strcmp(user->id, username) == 0) - return user; - } - - return NULL; -} - -/* - * This method ignores the configured seed and fails for an unknown user. - * Ownership of the returned pointer is not released to the caller. - * In other words, caller must not free the result. - */ -SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username) -{ - return find_user(vb, username); -} - -/* - * Ownership of the returned pointer is released to the caller. - * In other words, caller must free the result once done. - */ -SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) -{ - SRP_user_pwd *user; - unsigned char digv[SHA_DIGEST_LENGTH]; - unsigned char digs[SHA_DIGEST_LENGTH]; - EVP_MD_CTX ctxt; - - if (vb == NULL) - return NULL; - - if ((user = find_user(vb, username)) != NULL) - return srp_user_pwd_dup(user); - - if ((vb->seed_key == NULL) || - (vb->default_g == NULL) || (vb->default_N == NULL)) - return NULL; - -/* if the user is unknown we set parameters as well if we have a seed_key */ - - if ((user = SRP_user_pwd_new()) == NULL) - return NULL; - - SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N); - - if (!SRP_user_pwd_set_ids(user, username, NULL)) - goto err; - - if (RAND_bytes(digv, SHA_DIGEST_LENGTH) <= 0) - goto err; - EVP_MD_CTX_init(&ctxt); - EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); - EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key)); - EVP_DigestUpdate(&ctxt, username, strlen(username)); - EVP_DigestFinal_ex(&ctxt, digs, NULL); - EVP_MD_CTX_cleanup(&ctxt); - if (SRP_user_pwd_set_sv_BN - (user, BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL), - BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL))) - return user; - - err:SRP_user_pwd_free(user); - return NULL; -} - -/* - * create a verifier (*salt,*verifier,g and N are in base64) - */ -char *SRP_create_verifier(const char *user, const char *pass, char **salt, - char **verifier, const char *N, const char *g) -{ - int len; - char *result = NULL, *vf = NULL; - BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL; - unsigned char tmp[MAX_LEN]; - unsigned char tmp2[MAX_LEN]; - char *defgNid = NULL; - int vfsize = 0; - - if ((user == NULL) || - (pass == NULL) || (salt == NULL) || (verifier == NULL)) - goto err; - - if (N) { - if (!(len = t_fromb64(tmp, sizeof(tmp), N))) - goto err; - N_bn = BN_bin2bn(tmp, len, NULL); - if (!(len = t_fromb64(tmp, sizeof(tmp), g))) - goto err; - g_bn = BN_bin2bn(tmp, len, NULL); - defgNid = "*"; - } else { - SRP_gN *gN = SRP_get_gN_by_id(g, NULL); - if (gN == NULL) - goto err; - N_bn = gN->N; - g_bn = gN->g; - defgNid = gN->id; - } - - if (*salt == NULL) { - if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) - goto err; - - s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); - } else { - if (!(len = t_fromb64(tmp2, sizeof(tmp2), *salt))) - goto err; - s = BN_bin2bn(tmp2, len, NULL); - } - - if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) - goto err; - - BN_bn2bin(v, tmp); - vfsize = BN_num_bytes(v) * 2; - if (((vf = OPENSSL_malloc(vfsize)) == NULL)) - goto err; - t_tob64(vf, tmp, BN_num_bytes(v)); - - if (*salt == NULL) { - char *tmp_salt; - - if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) { - goto err; - } - t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN); - *salt = tmp_salt; - } - - *verifier = vf; - vf = NULL; - result = defgNid; - - err: - if (N) { - BN_free(N_bn); - BN_free(g_bn); - } - if (vf != NULL) - OPENSSL_cleanse(vf, vfsize); - OPENSSL_free(vf); - BN_clear_free(s); - BN_clear_free(v); - return result; -} - -/* - * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL - * then the provided salt will be used. On successful exit *verifier will point - * to a newly allocated BIGNUM containing the verifier and (if a salt was not - * provided) *salt will be populated with a newly allocated BIGNUM containing a - * random salt. - * The caller is responsible for freeing the allocated *salt and *verifier - * BIGNUMS. - */ -int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, - BIGNUM **verifier, BIGNUM *N, BIGNUM *g) -{ - int result = 0; - BIGNUM *x = NULL; - BN_CTX *bn_ctx = BN_CTX_new(); - unsigned char tmp2[MAX_LEN]; - BIGNUM *salttmp = NULL; - - if ((user == NULL) || - (pass == NULL) || - (salt == NULL) || - (verifier == NULL) || (N == NULL) || (g == NULL) || (bn_ctx == NULL)) - goto err; - - srp_bn_print(N); - srp_bn_print(g); - - if (*salt == NULL) { - if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0) - goto err; - - salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); - } else { - salttmp = *salt; - } - - x = SRP_Calc_x(salttmp, user, pass); - - *verifier = BN_new(); - if (*verifier == NULL) - goto err; - - if (!BN_mod_exp(*verifier, g, x, N, bn_ctx)) { - BN_clear_free(*verifier); - goto err; - } - - srp_bn_print(*verifier); - - result = 1; - *salt = salttmp; - - err: - if (*salt != salttmp) - BN_clear_free(salttmp); - BN_clear_free(x); - BN_CTX_free(bn_ctx); - return result; -} - -#endif diff --git a/Sources/COpenSSL/srp_grps.h b/Sources/COpenSSL/srp_grps.h deleted file mode 100644 index f76652cb..00000000 --- a/Sources/COpenSSL/srp_grps.h +++ /dev/null @@ -1,528 +0,0 @@ -/* start of generated data */ - -static BN_ULONG bn_group_1024_value[] = { - bn_pack4(0x9FC6, 0x1D2F, 0xC0EB, 0x06E3), - bn_pack4(0xFD51, 0x38FE, 0x8376, 0x435B), - bn_pack4(0x2FD4, 0xCBF4, 0x976E, 0xAA9A), - bn_pack4(0x68ED, 0xBC3C, 0x0572, 0x6CC0), - bn_pack4(0xC529, 0xF566, 0x660E, 0x57EC), - bn_pack4(0x8255, 0x9B29, 0x7BCF, 0x1885), - bn_pack4(0xCE8E, 0xF4AD, 0x69B1, 0x5D49), - bn_pack4(0x5DC7, 0xD7B4, 0x6154, 0xD6B6), - bn_pack4(0x8E49, 0x5C1D, 0x6089, 0xDAD1), - bn_pack4(0xE0D5, 0xD8E2, 0x50B9, 0x8BE4), - bn_pack4(0x383B, 0x4813, 0xD692, 0xC6E0), - bn_pack4(0xD674, 0xDF74, 0x96EA, 0x81D3), - bn_pack4(0x9EA2, 0x314C, 0x9C25, 0x6576), - bn_pack4(0x6072, 0x6187, 0x75FF, 0x3C0B), - bn_pack4(0x9C33, 0xF80A, 0xFA8F, 0xC5E8), - bn_pack4(0xEEAF, 0x0AB9, 0xADB3, 0x8DD6) -}; - -static BIGNUM bn_group_1024 = { - bn_group_1024_value, - (sizeof(bn_group_1024_value)) / sizeof(BN_ULONG), - (sizeof(bn_group_1024_value)) / sizeof(BN_ULONG), - 0, - BN_FLG_STATIC_DATA -}; - -static BN_ULONG bn_group_1536_value[] = { - bn_pack4(0xCF76, 0xE3FE, 0xD135, 0xF9BB), - bn_pack4(0x1518, 0x0F93, 0x499A, 0x234D), - bn_pack4(0x8CE7, 0xA28C, 0x2442, 0xC6F3), - bn_pack4(0x5A02, 0x1FFF, 0x5E91, 0x479E), - bn_pack4(0x7F8A, 0x2FE9, 0xB8B5, 0x292E), - bn_pack4(0x837C, 0x264A, 0xE3A9, 0xBEB8), - bn_pack4(0xE442, 0x734A, 0xF7CC, 0xB7AE), - bn_pack4(0x6577, 0x2E43, 0x7D6C, 0x7F8C), - bn_pack4(0xDB2F, 0xD53D, 0x24B7, 0xC486), - bn_pack4(0x6EDF, 0x0195, 0x3934, 0x9627), - bn_pack4(0x158B, 0xFD3E, 0x2B9C, 0x8CF5), - bn_pack4(0x764E, 0x3F4B, 0x53DD, 0x9DA1), - bn_pack4(0x4754, 0x8381, 0xDBC5, 0xB1FC), - bn_pack4(0x9B60, 0x9E0B, 0xE3BA, 0xB63D), - bn_pack4(0x8134, 0xB1C8, 0xB979, 0x8914), - bn_pack4(0xDF02, 0x8A7C, 0xEC67, 0xF0D0), - bn_pack4(0x80B6, 0x55BB, 0x9A22, 0xE8DC), - bn_pack4(0x1558, 0x903B, 0xA0D0, 0xF843), - bn_pack4(0x51C6, 0xA94B, 0xE460, 0x7A29), - bn_pack4(0x5F4F, 0x5F55, 0x6E27, 0xCBDE), - bn_pack4(0xBEEE, 0xA961, 0x4B19, 0xCC4D), - bn_pack4(0xDBA5, 0x1DF4, 0x99AC, 0x4C80), - bn_pack4(0xB1F1, 0x2A86, 0x17A4, 0x7BBB), - bn_pack4(0x9DEF, 0x3CAF, 0xB939, 0x277A) -}; - -static BIGNUM bn_group_1536 = { - bn_group_1536_value, - (sizeof(bn_group_1536_value)) / sizeof(BN_ULONG), - (sizeof(bn_group_1536_value)) / sizeof(BN_ULONG), - 0, - BN_FLG_STATIC_DATA -}; - -static BN_ULONG bn_group_2048_value[] = { - bn_pack4(0x0FA7, 0x111F, 0x9E4A, 0xFF73), - bn_pack4(0x9B65, 0xE372, 0xFCD6, 0x8EF2), - bn_pack4(0x35DE, 0x236D, 0x525F, 0x5475), - bn_pack4(0x94B5, 0xC803, 0xD89F, 0x7AE4), - bn_pack4(0x71AE, 0x35F8, 0xE9DB, 0xFBB6), - bn_pack4(0x2A56, 0x98F3, 0xA8D0, 0xC382), - bn_pack4(0x9CCC, 0x041C, 0x7BC3, 0x08D8), - bn_pack4(0xAF87, 0x4E73, 0x03CE, 0x5329), - bn_pack4(0x6160, 0x2790, 0x04E5, 0x7AE6), - bn_pack4(0x032C, 0xFBDB, 0xF52F, 0xB378), - bn_pack4(0x5EA7, 0x7A27, 0x75D2, 0xECFA), - bn_pack4(0x5445, 0x23B5, 0x24B0, 0xD57D), - bn_pack4(0x5B9D, 0x32E6, 0x88F8, 0x7748), - bn_pack4(0xF1D2, 0xB907, 0x8717, 0x461A), - bn_pack4(0x76BD, 0x207A, 0x436C, 0x6481), - bn_pack4(0xCA97, 0xB43A, 0x23FB, 0x8016), - bn_pack4(0x1D28, 0x1E44, 0x6B14, 0x773B), - bn_pack4(0x7359, 0xD041, 0xD5C3, 0x3EA7), - bn_pack4(0xA80D, 0x740A, 0xDBF4, 0xFF74), - bn_pack4(0x55F9, 0x7993, 0xEC97, 0x5EEA), - bn_pack4(0x2918, 0xA996, 0x2F0B, 0x93B8), - bn_pack4(0x661A, 0x05FB, 0xD5FA, 0xAAE8), - bn_pack4(0xCF60, 0x9517, 0x9A16, 0x3AB3), - bn_pack4(0xE808, 0x3969, 0xEDB7, 0x67B0), - bn_pack4(0xCD7F, 0x48A9, 0xDA04, 0xFD50), - bn_pack4(0xD523, 0x12AB, 0x4B03, 0x310D), - bn_pack4(0x8193, 0xE075, 0x7767, 0xA13D), - bn_pack4(0xA373, 0x29CB, 0xB4A0, 0x99ED), - bn_pack4(0xFC31, 0x9294, 0x3DB5, 0x6050), - bn_pack4(0xAF72, 0xB665, 0x1987, 0xEE07), - bn_pack4(0xF166, 0xDE5E, 0x1389, 0x582F), - bn_pack4(0xAC6B, 0xDB41, 0x324A, 0x9A9B) -}; - -static BIGNUM bn_group_2048 = { - bn_group_2048_value, - (sizeof(bn_group_2048_value)) / sizeof(BN_ULONG), - (sizeof(bn_group_2048_value)) / sizeof(BN_ULONG), - 0, - BN_FLG_STATIC_DATA -}; - -static BN_ULONG bn_group_3072_value[] = { - bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), - bn_pack4(0x4B82, 0xD120, 0xA93A, 0xD2CA), - bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), - bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), - bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), - bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), - bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), - bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), - bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), - bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), - bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), - bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), - bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), - bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), - bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), - bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), - bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), - bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), - bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), - bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), - bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), - bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), - bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), - bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), - bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), - bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), - bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), - bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), - bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), - bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), - bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), - bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), - bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), - bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), - bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), - bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), - bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), - bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), - bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), - bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), - bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), - bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), - bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), - bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), - bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), - bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), - bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), - bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) -}; - -static BIGNUM bn_group_3072 = { - bn_group_3072_value, - (sizeof(bn_group_3072_value)) / sizeof(BN_ULONG), - (sizeof(bn_group_3072_value)) / sizeof(BN_ULONG), - 0, - BN_FLG_STATIC_DATA -}; - -static BN_ULONG bn_group_4096_value[] = { - bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), - bn_pack4(0x4DF4, 0x35C9, 0x3406, 0x3199), - bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), - bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), - bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), - bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), - bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), - bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), - bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), - bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), - bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), - bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), - bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), - bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), - bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), - bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), - bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), - bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), - bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), - bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), - bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), - bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), - bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), - bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), - bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), - bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), - bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), - bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), - bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), - bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), - bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), - bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), - bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), - bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), - bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), - bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), - bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), - bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), - bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), - bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), - bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), - bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), - bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), - bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), - bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), - bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), - bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), - bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), - bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), - bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), - bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), - bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), - bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), - bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), - bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), - bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), - bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), - bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), - bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), - bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), - bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), - bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), - bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), - bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) -}; - -static BIGNUM bn_group_4096 = { - bn_group_4096_value, - (sizeof(bn_group_4096_value)) / sizeof(BN_ULONG), - (sizeof(bn_group_4096_value)) / sizeof(BN_ULONG), - 0, - BN_FLG_STATIC_DATA -}; - -static BN_ULONG bn_group_6144_value[] = { - bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), - bn_pack4(0xE694, 0xF91E, 0x6DCC, 0x4024), - bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6), - bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE), - bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468), - bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632), - bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C), - bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0), - bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76), - bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328), - bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0), - bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8), - bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA), - bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5), - bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE), - bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3), - bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E), - bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82), - bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6), - bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03), - bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC), - bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF), - bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42), - bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B), - bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B), - bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED), - bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918), - bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831), - bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE), - bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E), - bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD), - bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE), - bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026), - bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492), - bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), - bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), - bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), - bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), - bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), - bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), - bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), - bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), - bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), - bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), - bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), - bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), - bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), - bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), - bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), - bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), - bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), - bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), - bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), - bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), - bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), - bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), - bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), - bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), - bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), - bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), - bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), - bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), - bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), - bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), - bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), - bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), - bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), - bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), - bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), - bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), - bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), - bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), - bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), - bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), - bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), - bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), - bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), - bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), - bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), - bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), - bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), - bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), - bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), - bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), - bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), - bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), - bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), - bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), - bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), - bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), - bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), - bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), - bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), - bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), - bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), - bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) -}; - -static BIGNUM bn_group_6144 = { - bn_group_6144_value, - (sizeof(bn_group_6144_value)) / sizeof(BN_ULONG), - (sizeof(bn_group_6144_value)) / sizeof(BN_ULONG), - 0, - BN_FLG_STATIC_DATA -}; - -static BN_ULONG bn_group_8192_value[] = { - bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), - bn_pack4(0x60C9, 0x80DD, 0x98ED, 0xD3DF), - bn_pack4(0xC81F, 0x56E8, 0x80B9, 0x6E71), - bn_pack4(0x9E30, 0x50E2, 0x7656, 0x94DF), - bn_pack4(0x9558, 0xE447, 0x5677, 0xE9AA), - bn_pack4(0xC919, 0x0DA6, 0xFC02, 0x6E47), - bn_pack4(0x889A, 0x002E, 0xD5EE, 0x382B), - bn_pack4(0x4009, 0x438B, 0x481C, 0x6CD7), - bn_pack4(0x3590, 0x46F4, 0xEB87, 0x9F92), - bn_pack4(0xFAF3, 0x6BC3, 0x1ECF, 0xA268), - bn_pack4(0xB1D5, 0x10BD, 0x7EE7, 0x4D73), - bn_pack4(0xF9AB, 0x4819, 0x5DED, 0x7EA1), - bn_pack4(0x64F3, 0x1CC5, 0x0846, 0x851D), - bn_pack4(0x4597, 0xE899, 0xA025, 0x5DC1), - bn_pack4(0xDF31, 0x0EE0, 0x74AB, 0x6A36), - bn_pack4(0x6D2A, 0x13F8, 0x3F44, 0xF82D), - bn_pack4(0x062B, 0x3CF5, 0xB3A2, 0x78A6), - bn_pack4(0x7968, 0x3303, 0xED5B, 0xDD3A), - bn_pack4(0xFA9D, 0x4B7F, 0xA2C0, 0x87E8), - bn_pack4(0x4BCB, 0xC886, 0x2F83, 0x85DD), - bn_pack4(0x3473, 0xFC64, 0x6CEA, 0x306B), - bn_pack4(0x13EB, 0x57A8, 0x1A23, 0xF0C7), - bn_pack4(0x2222, 0x2E04, 0xA403, 0x7C07), - bn_pack4(0xE3FD, 0xB8BE, 0xFC84, 0x8AD9), - bn_pack4(0x238F, 0x16CB, 0xE39D, 0x652D), - bn_pack4(0x3423, 0xB474, 0x2BF1, 0xC978), - bn_pack4(0x3AAB, 0x639C, 0x5AE4, 0xF568), - bn_pack4(0x2576, 0xF693, 0x6BA4, 0x2466), - bn_pack4(0x741F, 0xA7BF, 0x8AFC, 0x47ED), - bn_pack4(0x3BC8, 0x32B6, 0x8D9D, 0xD300), - bn_pack4(0xD8BE, 0xC4D0, 0x73B9, 0x31BA), - bn_pack4(0x3877, 0x7CB6, 0xA932, 0xDF8C), - bn_pack4(0x74A3, 0x926F, 0x12FE, 0xE5E4), - bn_pack4(0xE694, 0xF91E, 0x6DBE, 0x1159), - bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6), - bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE), - bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468), - bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632), - bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C), - bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0), - bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76), - bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328), - bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0), - bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8), - bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA), - bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5), - bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE), - bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3), - bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E), - bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82), - bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6), - bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03), - bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC), - bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF), - bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42), - bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B), - bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B), - bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED), - bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918), - bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831), - bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE), - bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E), - bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD), - bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE), - bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026), - bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492), - bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), - bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), - bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), - bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), - bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), - bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), - bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), - bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), - bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), - bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), - bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), - bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), - bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), - bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), - bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), - bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), - bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), - bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), - bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), - bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), - bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), - bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), - bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), - bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), - bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), - bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), - bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), - bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), - bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), - bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), - bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), - bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), - bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), - bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), - bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), - bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), - bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), - bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), - bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), - bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), - bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), - bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), - bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), - bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), - bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), - bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), - bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), - bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), - bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), - bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), - bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), - bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), - bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), - bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), - bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), - bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), - bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), - bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), - bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), - bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), - bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), - bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) -}; - -static BIGNUM bn_group_8192 = { - bn_group_8192_value, - (sizeof(bn_group_8192_value)) / sizeof(BN_ULONG), - (sizeof(bn_group_8192_value)) / sizeof(BN_ULONG), - 0, - BN_FLG_STATIC_DATA -}; - -static BN_ULONG bn_generator_19_value[] = { 19 }; - -static BIGNUM bn_generator_19 = { - bn_generator_19_value, - 1, - 1, - 0, - BN_FLG_STATIC_DATA -}; -static BN_ULONG bn_generator_5_value[] = { 5 }; - -static BIGNUM bn_generator_5 = { - bn_generator_5_value, - 1, - 1, - 0, - BN_FLG_STATIC_DATA -}; -static BN_ULONG bn_generator_2_value[] = { 2 }; - -static BIGNUM bn_generator_2 = { - bn_generator_2_value, - 1, - 1, - 0, - BN_FLG_STATIC_DATA -}; - -static SRP_gN knowngN[] = { - {"8192", &bn_generator_19, &bn_group_8192}, - {"6144", &bn_generator_5, &bn_group_6144}, - {"4096", &bn_generator_5, &bn_group_4096}, - {"3072", &bn_generator_5, &bn_group_3072}, - {"2048", &bn_generator_2, &bn_group_2048}, - {"1536", &bn_generator_2, &bn_group_1536}, - {"1024", &bn_generator_2, &bn_group_1024}, -}; - -#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN) - -/* end of generated data */ diff --git a/Sources/COpenSSL/srp_lcl.h b/Sources/COpenSSL/srp_lcl.h deleted file mode 100644 index b74c2496..00000000 --- a/Sources/COpenSSL/srp_lcl.h +++ /dev/null @@ -1,84 +0,0 @@ -/* crypto/srp/srp_lcl.h */ -/* - * Written by Peter Sylvester (peter.sylvester@edelweb.fr) for the EdelKey - * project and contributed to the OpenSSL project 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef HEADER_SRP_LCL_H -# define HEADER_SRP_LCL_H - -# include "srp.h" -# include "sha.h" - -# if 0 -# define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \ - fprintf(stderr,"\n");} -# else -# define srp_bn_print(a) -# endif - - - -#ifdef __cplusplus -extern "C" { -#endif - - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/srtp.h b/Sources/COpenSSL/srtp.h deleted file mode 100644 index 94d32d8c..00000000 --- a/Sources/COpenSSL/srtp.h +++ /dev/null @@ -1,147 +0,0 @@ -/* ssl/srtp.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* - * DTLS code by Eric Rescorla - * - * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. - */ - -#ifndef HEADER_D1_SRTP_H -# define HEADER_D1_SRTP_H - -# include "ssl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# define SRTP_AES128_CM_SHA1_80 0x0001 -# define SRTP_AES128_CM_SHA1_32 0x0002 -# define SRTP_AES128_F8_SHA1_80 0x0003 -# define SRTP_AES128_F8_SHA1_32 0x0004 -# define SRTP_NULL_SHA1_80 0x0005 -# define SRTP_NULL_SHA1_32 0x0006 - -# ifndef OPENSSL_NO_SRTP - -int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); -int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); - -STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); -SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); - -# endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/ssl.h b/Sources/COpenSSL/ssl.h deleted file mode 100644 index 189db400..00000000 --- a/Sources/COpenSSL/ssl.h +++ /dev/null @@ -1,3164 +0,0 @@ -/* ssl/ssl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#ifndef HEADER_SSL_H -# define HEADER_SSL_H - -# include "e_os2.h" - -# ifndef OPENSSL_NO_COMP -# include "comp.h" -# endif -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# ifndef OPENSSL_NO_DEPRECATED -# ifndef OPENSSL_NO_X509 -# include "x509.h" -# endif -# include "crypto.h" -# include "lhash.h" -# include "buffer.h" -# endif -# include "pem.h" -# include "hmac.h" - -# include "kssl.h" -# include "safestack.h" -# include "symhacks.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* SSLeay version number for ASN.1 encoding of the session information */ -/*- - * Version 0 - initial version - * Version 1 - added the optional peer certificate - */ -# define SSL_SESSION_ASN1_VERSION 0x0001 - -/* text strings for the ciphers */ -# define SSL_TXT_NULL_WITH_MD5 SSL2_TXT_NULL_WITH_MD5 -# define SSL_TXT_RC4_128_WITH_MD5 SSL2_TXT_RC4_128_WITH_MD5 -# define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 -# define SSL_TXT_RC2_128_CBC_WITH_MD5 SSL2_TXT_RC2_128_CBC_WITH_MD5 -# define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 -# define SSL_TXT_IDEA_128_CBC_WITH_MD5 SSL2_TXT_IDEA_128_CBC_WITH_MD5 -# define SSL_TXT_DES_64_CBC_WITH_MD5 SSL2_TXT_DES_64_CBC_WITH_MD5 -# define SSL_TXT_DES_64_CBC_WITH_SHA SSL2_TXT_DES_64_CBC_WITH_SHA -# define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 -# define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA - -/* - * VRS Additional Kerberos5 entries - */ -# define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA -# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA -# define SSL_TXT_KRB5_RC4_128_SHA SSL3_TXT_KRB5_RC4_128_SHA -# define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA -# define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 -# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 -# define SSL_TXT_KRB5_RC4_128_MD5 SSL3_TXT_KRB5_RC4_128_MD5 -# define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 - -# define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA -# define SSL_TXT_KRB5_RC2_40_CBC_SHA SSL3_TXT_KRB5_RC2_40_CBC_SHA -# define SSL_TXT_KRB5_RC4_40_SHA SSL3_TXT_KRB5_RC4_40_SHA -# define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 -# define SSL_TXT_KRB5_RC2_40_CBC_MD5 SSL3_TXT_KRB5_RC2_40_CBC_MD5 -# define SSL_TXT_KRB5_RC4_40_MD5 SSL3_TXT_KRB5_RC4_40_MD5 - -# define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA -# define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 -# define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA -# define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 -# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA -# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 -# define SSL_MAX_KRB5_PRINCIPAL_LENGTH 256 - -# define SSL_MAX_SSL_SESSION_ID_LENGTH 32 -# define SSL_MAX_SID_CTX_LENGTH 32 - -# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) -# define SSL_MAX_KEY_ARG_LENGTH 8 -# define SSL_MAX_MASTER_KEY_LENGTH 48 - -/* These are used to specify which ciphers to use and not to use */ - -# define SSL_TXT_EXP40 "EXPORT40" -# define SSL_TXT_EXP56 "EXPORT56" -# define SSL_TXT_LOW "LOW" -# define SSL_TXT_MEDIUM "MEDIUM" -# define SSL_TXT_HIGH "HIGH" -# define SSL_TXT_FIPS "FIPS" - -# define SSL_TXT_kFZA "kFZA"/* unused! */ -# define SSL_TXT_aFZA "aFZA"/* unused! */ -# define SSL_TXT_eFZA "eFZA"/* unused! */ -# define SSL_TXT_FZA "FZA"/* unused! */ - -# define SSL_TXT_aNULL "aNULL" -# define SSL_TXT_eNULL "eNULL" -# define SSL_TXT_NULL "NULL" - -# define SSL_TXT_kRSA "kRSA" -# define SSL_TXT_kDHr "kDHr" -# define SSL_TXT_kDHd "kDHd" -# define SSL_TXT_kDH "kDH" -# define SSL_TXT_kEDH "kEDH" -# define SSL_TXT_kDHE "kDHE"/* alias for kEDH */ -# define SSL_TXT_kKRB5 "kKRB5" -# define SSL_TXT_kECDHr "kECDHr" -# define SSL_TXT_kECDHe "kECDHe" -# define SSL_TXT_kECDH "kECDH" -# define SSL_TXT_kEECDH "kEECDH" -# define SSL_TXT_kECDHE "kECDHE"/* alias for kEECDH */ -# define SSL_TXT_kPSK "kPSK" -# define SSL_TXT_kGOST "kGOST" -# define SSL_TXT_kSRP "kSRP" - -# define SSL_TXT_aRSA "aRSA" -# define SSL_TXT_aDSS "aDSS" -# define SSL_TXT_aDH "aDH" -# define SSL_TXT_aECDH "aECDH" -# define SSL_TXT_aKRB5 "aKRB5" -# define SSL_TXT_aECDSA "aECDSA" -# define SSL_TXT_aPSK "aPSK" -# define SSL_TXT_aGOST94 "aGOST94" -# define SSL_TXT_aGOST01 "aGOST01" -# define SSL_TXT_aGOST "aGOST" -# define SSL_TXT_aSRP "aSRP" - -# define SSL_TXT_DSS "DSS" -# define SSL_TXT_DH "DH" -# define SSL_TXT_EDH "EDH"/* same as "kEDH:-ADH" */ -# define SSL_TXT_DHE "DHE"/* alias for EDH */ -# define SSL_TXT_ADH "ADH" -# define SSL_TXT_RSA "RSA" -# define SSL_TXT_ECDH "ECDH" -# define SSL_TXT_EECDH "EECDH"/* same as "kEECDH:-AECDH" */ -# define SSL_TXT_ECDHE "ECDHE"/* alias for ECDHE" */ -# define SSL_TXT_AECDH "AECDH" -# define SSL_TXT_ECDSA "ECDSA" -# define SSL_TXT_KRB5 "KRB5" -# define SSL_TXT_PSK "PSK" -# define SSL_TXT_SRP "SRP" - -# define SSL_TXT_DES "DES" -# define SSL_TXT_3DES "3DES" -# define SSL_TXT_RC4 "RC4" -# define SSL_TXT_RC2 "RC2" -# define SSL_TXT_IDEA "IDEA" -# define SSL_TXT_SEED "SEED" -# define SSL_TXT_AES128 "AES128" -# define SSL_TXT_AES256 "AES256" -# define SSL_TXT_AES "AES" -# define SSL_TXT_AES_GCM "AESGCM" -# define SSL_TXT_CAMELLIA128 "CAMELLIA128" -# define SSL_TXT_CAMELLIA256 "CAMELLIA256" -# define SSL_TXT_CAMELLIA "CAMELLIA" - -# define SSL_TXT_MD5 "MD5" -# define SSL_TXT_SHA1 "SHA1" -# define SSL_TXT_SHA "SHA"/* same as "SHA1" */ -# define SSL_TXT_GOST94 "GOST94" -# define SSL_TXT_GOST89MAC "GOST89MAC" -# define SSL_TXT_SHA256 "SHA256" -# define SSL_TXT_SHA384 "SHA384" - -# define SSL_TXT_SSLV2 "SSLv2" -# define SSL_TXT_SSLV3 "SSLv3" -# define SSL_TXT_TLSV1 "TLSv1" -# define SSL_TXT_TLSV1_1 "TLSv1.1" -# define SSL_TXT_TLSV1_2 "TLSv1.2" - -# define SSL_TXT_EXP "EXP" -# define SSL_TXT_EXPORT "EXPORT" - -# define SSL_TXT_ALL "ALL" - -/*- - * COMPLEMENTOF* definitions. These identifiers are used to (de-select) - * ciphers normally not being used. - * Example: "RC4" will activate all ciphers using RC4 including ciphers - * without authentication, which would normally disabled by DEFAULT (due - * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" - * will make sure that it is also disabled in the specific selection. - * COMPLEMENTOF* identifiers are portable between version, as adjustments - * to the default cipher setup will also be included here. - * - * COMPLEMENTOFDEFAULT does not experience the same special treatment that - * DEFAULT gets, as only selection is being done and no sorting as needed - * for DEFAULT. - */ -# define SSL_TXT_CMPALL "COMPLEMENTOFALL" -# define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" - -/* - * The following cipher list is used by default. It also is substituted when - * an application-defined cipher list string starts with 'DEFAULT'. - */ -# define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2" -/* - * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always - * starts with a reasonable order, and all we have to do for DEFAULT is - * throwing out anonymous and unencrypted ciphersuites! (The latter are not - * actually enabled by ALL, but "ALL:RSA" would enable some of them.) - */ - -/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ -# define SSL_SENT_SHUTDOWN 1 -# define SSL_RECEIVED_SHUTDOWN 2 - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -# if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2) -# define OPENSSL_NO_SSL2 -# endif - -# define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 -# define SSL_FILETYPE_PEM X509_FILETYPE_PEM - -/* - * This is needed to stop compilers complaining about the 'struct ssl_st *' - * function parameters used to prototype callbacks in SSL_CTX. - */ -typedef struct ssl_st *ssl_crock_st; -typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; -typedef struct ssl_method_st SSL_METHOD; -typedef struct ssl_cipher_st SSL_CIPHER; -typedef struct ssl_session_st SSL_SESSION; -typedef struct tls_sigalgs_st TLS_SIGALGS; -typedef struct ssl_conf_ctx_st SSL_CONF_CTX; - -DECLARE_STACK_OF(SSL_CIPHER) - -/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ -typedef struct srtp_protection_profile_st { - const char *name; - unsigned long id; -} SRTP_PROTECTION_PROFILE; - -DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE) - -typedef int (*tls_session_ticket_ext_cb_fn) (SSL *s, - const unsigned char *data, - int len, void *arg); -typedef int (*tls_session_secret_cb_fn) (SSL *s, void *secret, - int *secret_len, - STACK_OF(SSL_CIPHER) *peer_ciphers, - SSL_CIPHER **cipher, void *arg); - -# ifndef OPENSSL_NO_TLSEXT - -/* Typedefs for handling custom extensions */ - -typedef int (*custom_ext_add_cb) (SSL *s, unsigned int ext_type, - const unsigned char **out, - size_t *outlen, int *al, void *add_arg); - -typedef void (*custom_ext_free_cb) (SSL *s, unsigned int ext_type, - const unsigned char *out, void *add_arg); - -typedef int (*custom_ext_parse_cb) (SSL *s, unsigned int ext_type, - const unsigned char *in, - size_t inlen, int *al, void *parse_arg); - -# endif - -# ifndef OPENSSL_NO_SSL_INTERN - -/* used to hold info on the particular ciphers used */ -struct ssl_cipher_st { - int valid; - const char *name; /* text name */ - unsigned long id; /* id, 4 bytes, first is version */ - /* - * changed in 0.9.9: these four used to be portions of a single value - * 'algorithms' - */ - unsigned long algorithm_mkey; /* key exchange algorithm */ - unsigned long algorithm_auth; /* server authentication */ - unsigned long algorithm_enc; /* symmetric encryption */ - unsigned long algorithm_mac; /* symmetric authentication */ - unsigned long algorithm_ssl; /* (major) protocol version */ - unsigned long algo_strength; /* strength and export flags */ - unsigned long algorithm2; /* Extra flags */ - int strength_bits; /* Number of bits really used */ - int alg_bits; /* Number of bits for algorithm */ -}; - -/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ -struct ssl_method_st { - int version; - int (*ssl_new) (SSL *s); - void (*ssl_clear) (SSL *s); - void (*ssl_free) (SSL *s); - int (*ssl_accept) (SSL *s); - int (*ssl_connect) (SSL *s); - int (*ssl_read) (SSL *s, void *buf, int len); - int (*ssl_peek) (SSL *s, void *buf, int len); - int (*ssl_write) (SSL *s, const void *buf, int len); - int (*ssl_shutdown) (SSL *s); - int (*ssl_renegotiate) (SSL *s); - int (*ssl_renegotiate_check) (SSL *s); - long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long - max, int *ok); - int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len, - int peek); - int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len); - int (*ssl_dispatch_alert) (SSL *s); - long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg); - long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg); - const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr); - int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr); - int (*ssl_pending) (const SSL *s); - int (*num_ciphers) (void); - const SSL_CIPHER *(*get_cipher) (unsigned ncipher); - const struct ssl_method_st *(*get_ssl_method) (int version); - long (*get_timeout) (void); - struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ - int (*ssl_version) (void); - long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void)); - long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void)); -}; - -/*- - * Lets make this into an ASN.1 type structure as follows - * SSL_SESSION_ID ::= SEQUENCE { - * version INTEGER, -- structure version number - * SSLversion INTEGER, -- SSL version number - * Cipher OCTET STRING, -- the 3 byte cipher ID - * Session_ID OCTET STRING, -- the Session ID - * Master_key OCTET STRING, -- the master key - * KRB5_principal OCTET STRING -- optional Kerberos principal - * Key_Arg [ 0 ] IMPLICIT OCTET STRING, -- the optional Key argument - * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time - * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds - * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate - * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context - * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' - * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension - * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint - * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity - * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket - * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only) - * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method - * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username - * } - * Look in ssl/ssl_asn1.c for more details - * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). - */ -struct ssl_session_st { - int ssl_version; /* what ssl version session info is being - * kept in here? */ - /* only really used in SSLv2 */ - unsigned int key_arg_length; - unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH]; - int master_key_length; - unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; - /* session_id - valid? */ - unsigned int session_id_length; - unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; - /* - * this is used to determine whether the session is being reused in the - * appropriate context. It is up to the application to set this, via - * SSL_new - */ - unsigned int sid_ctx_length; - unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; -# ifndef OPENSSL_NO_KRB5 - unsigned int krb5_client_princ_len; - unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH]; -# endif /* OPENSSL_NO_KRB5 */ -# ifndef OPENSSL_NO_PSK - char *psk_identity_hint; - char *psk_identity; -# endif - /* - * Used to indicate that session resumption is not allowed. Applications - * can also set this bit for a new session via not_resumable_session_cb - * to disable session caching and tickets. - */ - int not_resumable; - /* The cert is the certificate used to establish this connection */ - struct sess_cert_st /* SESS_CERT */ *sess_cert; - /* - * This is the cert for the other end. On clients, it will be the same as - * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is - * not retained in the external representation of sessions, see - * ssl_asn1.c). - */ - X509 *peer; - /* - * when app_verify_callback accepts a session where the peer's - * certificate is not ok, we must remember the error for session reuse: - */ - long verify_result; /* only for servers */ - int references; - long timeout; - long time; - unsigned int compress_meth; /* Need to lookup the method */ - const SSL_CIPHER *cipher; - unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used - * to load the 'cipher' structure */ - STACK_OF(SSL_CIPHER) *ciphers; /* ciphers offered by the client */ - CRYPTO_EX_DATA ex_data; /* application specific data */ - /* - * These are used to make removal of session-ids more efficient and to - * implement a maximum cache size. - */ - struct ssl_session_st *prev, *next; -# ifndef OPENSSL_NO_TLSEXT - char *tlsext_hostname; -# ifndef OPENSSL_NO_EC - size_t tlsext_ecpointformatlist_length; - unsigned char *tlsext_ecpointformatlist; /* peer's list */ - size_t tlsext_ellipticcurvelist_length; - unsigned char *tlsext_ellipticcurvelist; /* peer's list */ -# endif /* OPENSSL_NO_EC */ - /* RFC4507 info */ - unsigned char *tlsext_tick; /* Session ticket */ - size_t tlsext_ticklen; /* Session ticket length */ - long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ -# endif -# ifndef OPENSSL_NO_SRP - char *srp_username; -# endif -}; - -# endif - -# define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L -# define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L -/* Allow initial connection to servers that don't support RI */ -# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L -# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L -# define SSL_OP_TLSEXT_PADDING 0x00000010L -# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L -# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L -# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L -# define SSL_OP_TLS_D5_BUG 0x00000100L -# define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L - -/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */ -# define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 -/* Refers to ancient SSLREF and SSLv2, retained for compatibility */ -# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 - -/* - * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in - * OpenSSL 0.9.6d. Usually (depending on the application protocol) the - * workaround is not needed. Unfortunately some broken SSL/TLS - * implementations cannot handle it at all, which is why we include it in - * SSL_OP_ALL. - */ -/* added in 0.9.6e */ -# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800L - -/* - * SSL_OP_ALL: various bug workarounds that should be rather harmless. This - * used to be 0x000FFFFFL before 0.9.7. - */ -# define SSL_OP_ALL 0x80000BFFL - -/* DTLS options */ -# define SSL_OP_NO_QUERY_MTU 0x00001000L -/* Turn on Cookie Exchange (on relevant for servers) */ -# define SSL_OP_COOKIE_EXCHANGE 0x00002000L -/* Don't use RFC4507 ticket extension */ -# define SSL_OP_NO_TICKET 0x00004000L -/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client) */ -# define SSL_OP_CISCO_ANYCONNECT 0x00008000L - -/* As server, disallow session resumption on renegotiation */ -# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L -/* Don't use compression even if supported */ -# define SSL_OP_NO_COMPRESSION 0x00020000L -/* Permit unsafe legacy renegotiation */ -# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L -/* If set, always create a new key when using tmp_ecdh parameters */ -# define SSL_OP_SINGLE_ECDH_USE 0x00080000L -/* Does nothing: retained for compatibility */ -# define SSL_OP_SINGLE_DH_USE 0x00100000L -/* Does nothing: retained for compatibiity */ -# define SSL_OP_EPHEMERAL_RSA 0x0 -/* - * Set on servers to choose the cipher according to the server's preferences - */ -# define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L -/* - * If set, a server will allow a client to issue a SSLv3.0 version number as - * latest version supported in the premaster secret, even when TLSv1.0 - * (version 3.1) was announced in the client hello. Normally this is - * forbidden to prevent version rollback attacks. - */ -# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000L - -# define SSL_OP_NO_SSLv2 0x01000000L -# define SSL_OP_NO_SSLv3 0x02000000L -# define SSL_OP_NO_TLSv1 0x04000000L -# define SSL_OP_NO_TLSv1_2 0x08000000L -# define SSL_OP_NO_TLSv1_1 0x10000000L - -# define SSL_OP_NO_DTLSv1 0x04000000L -# define SSL_OP_NO_DTLSv1_2 0x08000000L - -# define SSL_OP_NO_SSL_MASK (SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3|\ - SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_TLSv1_2) - -/* - * These next two were never actually used for anything since SSLeay zap so - * we have some more flags. - */ -/* - * The next flag deliberately changes the ciphertest, this is a check for the - * PKCS#1 attack - */ -# define SSL_OP_PKCS1_CHECK_1 0x0 -# define SSL_OP_PKCS1_CHECK_2 0x0 - -# define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L -# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L -/* - * Make server add server-hello extension from early version of cryptopro - * draft, when GOST ciphersuite is negotiated. Required for interoperability - * with CryptoPro CSP 3.x - */ -# define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000L - -/* - * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success - * when just a single record has been written): - */ -# define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L -/* - * Make it possible to retry SSL_write() with changed buffer location (buffer - * contents must stay the same!); this is not the default to avoid the - * misconception that non-blocking SSL_write() behaves like non-blocking - * write(): - */ -# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L -/* - * Never bother the application with retries if the transport is blocking: - */ -# define SSL_MODE_AUTO_RETRY 0x00000004L -/* Don't attempt to automatically build certificate chain */ -# define SSL_MODE_NO_AUTO_CHAIN 0x00000008L -/* - * Save RAM by releasing read and write buffers when they're empty. (SSL3 and - * TLS only.) "Released" buffers are put onto a free-list in the context or - * just freed (depending on the context's setting for freelist_max_len). - */ -# define SSL_MODE_RELEASE_BUFFERS 0x00000010L -/* - * Send the current time in the Random fields of the ClientHello and - * ServerHello records for compatibility with hypothetical implementations - * that require it. - */ -# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L -# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L -/* - * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications - * that reconnect with a downgraded protocol version; see - * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your - * application attempts a normal handshake. Only use this in explicit - * fallback retries, following the guidance in - * draft-ietf-tls-downgrade-scsv-00. - */ -# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L - -/* Cert related flags */ -/* - * Many implementations ignore some aspects of the TLS standards such as - * enforcing certifcate chain algorithms. When this is set we enforce them. - */ -# define SSL_CERT_FLAG_TLS_STRICT 0x00000001L - -/* Suite B modes, takes same values as certificate verify flags */ -# define SSL_CERT_FLAG_SUITEB_128_LOS_ONLY 0x10000 -/* Suite B 192 bit only mode */ -# define SSL_CERT_FLAG_SUITEB_192_LOS 0x20000 -/* Suite B 128 bit mode allowing 192 bit algorithms */ -# define SSL_CERT_FLAG_SUITEB_128_LOS 0x30000 - -/* Perform all sorts of protocol violations for testing purposes */ -# define SSL_CERT_FLAG_BROKEN_PROTOCOL 0x10000000 - -/* Flags for building certificate chains */ -/* Treat any existing certificates as untrusted CAs */ -# define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1 -/* Don't include root CA in chain */ -# define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2 -/* Just check certificates already there */ -# define SSL_BUILD_CHAIN_FLAG_CHECK 0x4 -/* Ignore verification errors */ -# define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8 -/* Clear verification errors from queue */ -# define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10 - -/* Flags returned by SSL_check_chain */ -/* Certificate can be used with this session */ -# define CERT_PKEY_VALID 0x1 -/* Certificate can also be used for signing */ -# define CERT_PKEY_SIGN 0x2 -/* EE certificate signing algorithm OK */ -# define CERT_PKEY_EE_SIGNATURE 0x10 -/* CA signature algorithms OK */ -# define CERT_PKEY_CA_SIGNATURE 0x20 -/* EE certificate parameters OK */ -# define CERT_PKEY_EE_PARAM 0x40 -/* CA certificate parameters OK */ -# define CERT_PKEY_CA_PARAM 0x80 -/* Signing explicitly allowed as opposed to SHA1 fallback */ -# define CERT_PKEY_EXPLICIT_SIGN 0x100 -/* Client CA issuer names match (always set for server cert) */ -# define CERT_PKEY_ISSUER_NAME 0x200 -/* Cert type matches client types (always set for server cert) */ -# define CERT_PKEY_CERT_TYPE 0x400 -/* Cert chain suitable to Suite B */ -# define CERT_PKEY_SUITEB 0x800 - -# define SSL_CONF_FLAG_CMDLINE 0x1 -# define SSL_CONF_FLAG_FILE 0x2 -# define SSL_CONF_FLAG_CLIENT 0x4 -# define SSL_CONF_FLAG_SERVER 0x8 -# define SSL_CONF_FLAG_SHOW_ERRORS 0x10 -# define SSL_CONF_FLAG_CERTIFICATE 0x20 -/* Configuration value types */ -# define SSL_CONF_TYPE_UNKNOWN 0x0 -# define SSL_CONF_TYPE_STRING 0x1 -# define SSL_CONF_TYPE_FILE 0x2 -# define SSL_CONF_TYPE_DIR 0x3 - -/* - * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they - * cannot be used to clear bits. - */ - -# define SSL_CTX_set_options(ctx,op) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) -# define SSL_CTX_clear_options(ctx,op) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) -# define SSL_CTX_get_options(ctx) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL) -# define SSL_set_options(ssl,op) \ - SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL) -# define SSL_clear_options(ssl,op) \ - SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) -# define SSL_get_options(ssl) \ - SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL) - -# define SSL_CTX_set_mode(ctx,op) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) -# define SSL_CTX_clear_mode(ctx,op) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) -# define SSL_CTX_get_mode(ctx) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) -# define SSL_clear_mode(ssl,op) \ - SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) -# define SSL_set_mode(ssl,op) \ - SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) -# define SSL_get_mode(ssl) \ - SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) -# define SSL_set_mtu(ssl, mtu) \ - SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) -# define DTLS_set_link_mtu(ssl, mtu) \ - SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL) -# define DTLS_get_link_min_mtu(ssl) \ - SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL) - -# define SSL_get_secure_renegotiation_support(ssl) \ - SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) - -# ifndef OPENSSL_NO_HEARTBEATS -# define SSL_heartbeat(ssl) \ - SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL) -# endif - -# define SSL_CTX_set_cert_flags(ctx,op) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_CERT_FLAGS,(op),NULL) -# define SSL_set_cert_flags(s,op) \ - SSL_ctrl((s),SSL_CTRL_CERT_FLAGS,(op),NULL) -# define SSL_CTX_clear_cert_flags(ctx,op) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) -# define SSL_clear_cert_flags(s,op) \ - SSL_ctrl((s),SSL_CTRL_CLEAR_CERT_FLAGS,(op),NULL) - -void SSL_CTX_set_msg_callback(SSL_CTX *ctx, - void (*cb) (int write_p, int version, - int content_type, const void *buf, - size_t len, SSL *ssl, void *arg)); -void SSL_set_msg_callback(SSL *ssl, - void (*cb) (int write_p, int version, - int content_type, const void *buf, - size_t len, SSL *ssl, void *arg)); -# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) -# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) - -# ifndef OPENSSL_NO_SRP - -# ifndef OPENSSL_NO_SSL_INTERN - -typedef struct srp_ctx_st { - /* param for all the callbacks */ - void *SRP_cb_arg; - /* set client Hello login callback */ - int (*TLS_ext_srp_username_callback) (SSL *, int *, void *); - /* set SRP N/g param callback for verification */ - int (*SRP_verify_param_callback) (SSL *, void *); - /* set SRP client passwd callback */ - char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *); - char *login; - BIGNUM *N, *g, *s, *B, *A; - BIGNUM *a, *b, *v; - char *info; - int strength; - unsigned long srp_Mask; -} SRP_CTX; - -# endif - -/* see tls_srp.c */ -int SSL_SRP_CTX_init(SSL *s); -int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); -int SSL_SRP_CTX_free(SSL *ctx); -int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); -int SSL_srp_server_param_with_username(SSL *s, int *ad); -int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key); -int SRP_Calc_A_param(SSL *s); -int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key); - -# endif - -# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) -# define SSL_MAX_CERT_LIST_DEFAULT 1024*30 - /* 30k max cert list :-) */ -# else -# define SSL_MAX_CERT_LIST_DEFAULT 1024*100 - /* 100k max cert list :-) */ -# endif - -# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) - -/* - * This callback type is used inside SSL_CTX, SSL, and in the functions that - * set them. It is used to override the generation of SSL/TLS session IDs in - * a server. Return value should be zero on an error, non-zero to proceed. - * Also, callbacks should themselves check if the id they generate is unique - * otherwise the SSL handshake will fail with an error - callbacks can do - * this using the 'ssl' value they're passed by; - * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in - * is set at the maximum size the session ID can be. In SSLv2 this is 16 - * bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback can alter this - * length to be less if desired, but under SSLv2 session IDs are supposed to - * be fixed at 16 bytes so the id will be padded after the callback returns - * in this case. It is also an error for the callback to set the size to - * zero. - */ -typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id, - unsigned int *id_len); - -typedef struct ssl_comp_st SSL_COMP; - -# ifndef OPENSSL_NO_SSL_INTERN - -struct ssl_comp_st { - int id; - const char *name; -# ifndef OPENSSL_NO_COMP - COMP_METHOD *method; -# else - char *method; -# endif -}; - -DECLARE_STACK_OF(SSL_COMP) -DECLARE_LHASH_OF(SSL_SESSION); - -struct ssl_ctx_st { - const SSL_METHOD *method; - STACK_OF(SSL_CIPHER) *cipher_list; - /* same as above but sorted for lookup */ - STACK_OF(SSL_CIPHER) *cipher_list_by_id; - struct x509_store_st /* X509_STORE */ *cert_store; - LHASH_OF(SSL_SESSION) *sessions; - /* - * Most session-ids that will be cached, default is - * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. - */ - unsigned long session_cache_size; - struct ssl_session_st *session_cache_head; - struct ssl_session_st *session_cache_tail; - /* - * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT, - * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which - * means only SSL_accept which cache SSL_SESSIONS. - */ - int session_cache_mode; - /* - * If timeout is not 0, it is the default timeout value set when - * SSL_new() is called. This has been put in to make life easier to set - * things up - */ - long session_timeout; - /* - * If this callback is not null, it will be called each time a session id - * is added to the cache. If this function returns 1, it means that the - * callback will do a SSL_SESSION_free() when it has finished using it. - * Otherwise, on 0, it means the callback has finished with it. If - * remove_session_cb is not null, it will be called when a session-id is - * removed from the cache. After the call, OpenSSL will - * SSL_SESSION_free() it. - */ - int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess); - void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess); - SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl, - unsigned char *data, int len, int *copy); - struct { - int sess_connect; /* SSL new conn - started */ - int sess_connect_renegotiate; /* SSL reneg - requested */ - int sess_connect_good; /* SSL new conne/reneg - finished */ - int sess_accept; /* SSL new accept - started */ - int sess_accept_renegotiate; /* SSL reneg - requested */ - int sess_accept_good; /* SSL accept/reneg - finished */ - int sess_miss; /* session lookup misses */ - int sess_timeout; /* reuse attempt on timeouted session */ - int sess_cache_full; /* session removed due to full cache */ - int sess_hit; /* session reuse actually done */ - int sess_cb_hit; /* session-id that was not in the cache was - * passed back via the callback. This - * indicates that the application is - * supplying session-id's from other - * processes - spooky :-) */ - } stats; - - int references; - - /* if defined, these override the X509_verify_cert() calls */ - int (*app_verify_callback) (X509_STORE_CTX *, void *); - void *app_verify_arg; - /* - * before OpenSSL 0.9.7, 'app_verify_arg' was ignored - * ('app_verify_callback' was called with just one argument) - */ - - /* Default password callback. */ - pem_password_cb *default_passwd_callback; - - /* Default password callback user data. */ - void *default_passwd_callback_userdata; - - /* get client cert callback */ - int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey); - - /* cookie generate callback */ - int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie, - unsigned int *cookie_len); - - /* verify cookie callback */ - int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie, - unsigned int cookie_len); - - CRYPTO_EX_DATA ex_data; - - const EVP_MD *rsa_md5; /* For SSLv2 - name is 'ssl2-md5' */ - const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ - const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ - - STACK_OF(X509) *extra_certs; - STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */ - - /* Default values used when no per-SSL value is defined follow */ - - /* used if SSL's info_callback is NULL */ - void (*info_callback) (const SSL *ssl, int type, int val); - - /* what we put in client cert requests */ - STACK_OF(X509_NAME) *client_CA; - - /* - * Default values to use in SSL structures follow (these are copied by - * SSL_new) - */ - - unsigned long options; - unsigned long mode; - long max_cert_list; - - struct cert_st /* CERT */ *cert; - int read_ahead; - - /* callback that allows applications to peek at protocol messages */ - void (*msg_callback) (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg); - void *msg_callback_arg; - - int verify_mode; - unsigned int sid_ctx_length; - unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; - /* called 'verify_callback' in the SSL */ - int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); - - /* Default generate session ID callback. */ - GEN_SESSION_CB generate_session_id; - - X509_VERIFY_PARAM *param; - -# if 0 - int purpose; /* Purpose setting */ - int trust; /* Trust setting */ -# endif - - int quiet_shutdown; - - /* - * Maximum amount of data to send in one fragment. actual record size can - * be more than this due to padding and MAC overheads. - */ - unsigned int max_send_fragment; - -# ifndef OPENSSL_NO_ENGINE - /* - * Engine to pass requests for client certs to - */ - ENGINE *client_cert_engine; -# endif - -# ifndef OPENSSL_NO_TLSEXT - /* TLS extensions servername callback */ - int (*tlsext_servername_callback) (SSL *, int *, void *); - void *tlsext_servername_arg; - /* RFC 4507 session ticket keys */ - unsigned char tlsext_tick_key_name[16]; - unsigned char tlsext_tick_hmac_key[16]; - unsigned char tlsext_tick_aes_key[16]; - /* Callback to support customisation of ticket key setting */ - int (*tlsext_ticket_key_cb) (SSL *ssl, - unsigned char *name, unsigned char *iv, - EVP_CIPHER_CTX *ectx, - HMAC_CTX *hctx, int enc); - - /* certificate status request info */ - /* Callback for status request */ - int (*tlsext_status_cb) (SSL *ssl, void *arg); - void *tlsext_status_arg; - - /* draft-rescorla-tls-opaque-prf-input-00.txt information */ - int (*tlsext_opaque_prf_input_callback) (SSL *, void *peerinput, - size_t len, void *arg); - void *tlsext_opaque_prf_input_callback_arg; -# endif - -# ifndef OPENSSL_NO_PSK - char *psk_identity_hint; - unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, - char *identity, - unsigned int max_identity_len, - unsigned char *psk, - unsigned int max_psk_len); - unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, - unsigned char *psk, - unsigned int max_psk_len); -# endif - -# ifndef OPENSSL_NO_BUF_FREELISTS -# define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32 - unsigned int freelist_max_len; - struct ssl3_buf_freelist_st *wbuf_freelist; - struct ssl3_buf_freelist_st *rbuf_freelist; -# endif -# ifndef OPENSSL_NO_SRP - SRP_CTX srp_ctx; /* ctx for SRP authentication */ -# endif - -# ifndef OPENSSL_NO_TLSEXT - -# ifndef OPENSSL_NO_NEXTPROTONEG - /* Next protocol negotiation information */ - /* (for experimental NPN extension). */ - - /* - * For a server, this contains a callback function by which the set of - * advertised protocols can be provided. - */ - int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf, - unsigned int *len, void *arg); - void *next_protos_advertised_cb_arg; - /* - * For a client, this contains a callback function that selects the next - * protocol from the list provided by the server. - */ - int (*next_proto_select_cb) (SSL *s, unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, void *arg); - void *next_proto_select_cb_arg; -# endif - /* SRTP profiles we are willing to do from RFC 5764 */ - STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; - - /* - * ALPN information (we are in the process of transitioning from NPN to - * ALPN.) - */ - - /*- - * For a server, this contains a callback function that allows the - * server to select the protocol for the connection. - * out: on successful return, this must point to the raw protocol - * name (without the length prefix). - * outlen: on successful return, this contains the length of |*out|. - * in: points to the client's list of supported protocols in - * wire-format. - * inlen: the length of |in|. - */ - int (*alpn_select_cb) (SSL *s, - const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, void *arg); - void *alpn_select_cb_arg; - - /* - * For a client, this contains the list of supported protocols in wire - * format. - */ - unsigned char *alpn_client_proto_list; - unsigned alpn_client_proto_list_len; - -# ifndef OPENSSL_NO_EC - /* EC extension values inherited by SSL structure */ - size_t tlsext_ecpointformatlist_length; - unsigned char *tlsext_ecpointformatlist; - size_t tlsext_ellipticcurvelist_length; - unsigned char *tlsext_ellipticcurvelist; -# endif /* OPENSSL_NO_EC */ -# endif -}; - -# endif - -# define SSL_SESS_CACHE_OFF 0x0000 -# define SSL_SESS_CACHE_CLIENT 0x0001 -# define SSL_SESS_CACHE_SERVER 0x0002 -# define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) -# define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 -/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ -# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 -# define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 -# define SSL_SESS_CACHE_NO_INTERNAL \ - (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) - -LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); -# define SSL_CTX_sess_number(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) -# define SSL_CTX_sess_connect(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) -# define SSL_CTX_sess_connect_good(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) -# define SSL_CTX_sess_connect_renegotiate(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) -# define SSL_CTX_sess_accept(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) -# define SSL_CTX_sess_accept_renegotiate(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) -# define SSL_CTX_sess_accept_good(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) -# define SSL_CTX_sess_hits(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) -# define SSL_CTX_sess_cb_hits(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) -# define SSL_CTX_sess_misses(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) -# define SSL_CTX_sess_timeouts(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) -# define SSL_CTX_sess_cache_full(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) - -void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, - int (*new_session_cb) (struct ssl_st *ssl, - SSL_SESSION *sess)); -int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, - SSL_SESSION *sess); -void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, - void (*remove_session_cb) (struct ssl_ctx_st - *ctx, - SSL_SESSION - *sess)); -void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx, - SSL_SESSION *sess); -void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, - SSL_SESSION *(*get_session_cb) (struct ssl_st - *ssl, - unsigned char - *data, int len, - int *copy)); -SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, - unsigned char *Data, - int len, int *copy); -void SSL_CTX_set_info_callback(SSL_CTX *ctx, - void (*cb) (const SSL *ssl, int type, - int val)); -void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, - int val); -void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, - int (*client_cert_cb) (SSL *ssl, X509 **x509, - EVP_PKEY **pkey)); -int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, - EVP_PKEY **pkey); -# ifndef OPENSSL_NO_ENGINE -int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); -# endif -void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, - int (*app_gen_cookie_cb) (SSL *ssl, - unsigned char - *cookie, - unsigned int - *cookie_len)); -void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, - int (*app_verify_cookie_cb) (SSL *ssl, - unsigned char - *cookie, - unsigned int - cookie_len)); -# ifndef OPENSSL_NO_NEXTPROTONEG -void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, - int (*cb) (SSL *ssl, - const unsigned char - **out, - unsigned int *outlen, - void *arg), void *arg); -void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, - int (*cb) (SSL *ssl, - unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), void *arg); -void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, - unsigned *len); -# endif - -# ifndef OPENSSL_NO_TLSEXT -int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - const unsigned char *client, - unsigned int client_len); -# endif - -# define OPENSSL_NPN_UNSUPPORTED 0 -# define OPENSSL_NPN_NEGOTIATED 1 -# define OPENSSL_NPN_NO_OVERLAP 2 - -int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, - unsigned protos_len); -int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, - unsigned protos_len); -void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), void *arg); -void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, - unsigned *len); - -# ifndef OPENSSL_NO_PSK -/* - * the maximum length of the buffer given to callbacks containing the - * resulting identity/psk - */ -# define PSK_MAX_IDENTITY_LEN 128 -# define PSK_MAX_PSK_LEN 256 -void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, - unsigned int (*psk_client_callback) (SSL - *ssl, - const - char - *hint, - char - *identity, - unsigned - int - max_identity_len, - unsigned - char - *psk, - unsigned - int - max_psk_len)); -void SSL_set_psk_client_callback(SSL *ssl, - unsigned int (*psk_client_callback) (SSL - *ssl, - const - char - *hint, - char - *identity, - unsigned - int - max_identity_len, - unsigned - char - *psk, - unsigned - int - max_psk_len)); -void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, - unsigned int (*psk_server_callback) (SSL - *ssl, - const - char - *identity, - unsigned - char - *psk, - unsigned - int - max_psk_len)); -void SSL_set_psk_server_callback(SSL *ssl, - unsigned int (*psk_server_callback) (SSL - *ssl, - const - char - *identity, - unsigned - char - *psk, - unsigned - int - max_psk_len)); -int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); -int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); -const char *SSL_get_psk_identity_hint(const SSL *s); -const char *SSL_get_psk_identity(const SSL *s); -# endif - -# ifndef OPENSSL_NO_TLSEXT -/* Register callbacks to handle custom TLS Extensions for client or server. */ - -int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type, - custom_ext_add_cb add_cb, - custom_ext_free_cb free_cb, - void *add_arg, - custom_ext_parse_cb parse_cb, - void *parse_arg); - -int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type, - custom_ext_add_cb add_cb, - custom_ext_free_cb free_cb, - void *add_arg, - custom_ext_parse_cb parse_cb, - void *parse_arg); - -int SSL_extension_supported(unsigned int ext_type); - -# endif - -# define SSL_NOTHING 1 -# define SSL_WRITING 2 -# define SSL_READING 3 -# define SSL_X509_LOOKUP 4 - -/* These will only be used when doing non-blocking IO */ -# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) -# define SSL_want_read(s) (SSL_want(s) == SSL_READING) -# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) -# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) - -# define SSL_MAC_FLAG_READ_MAC_STREAM 1 -# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 - -# ifndef OPENSSL_NO_SSL_INTERN - -struct ssl_st { - /* - * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, - * DTLS1_VERSION) - */ - int version; - /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ - int type; - /* SSLv3 */ - const SSL_METHOD *method; - /* - * There are 2 BIO's even though they are normally both the same. This - * is so data can be read and written to different handlers - */ -# ifndef OPENSSL_NO_BIO - /* used by SSL_read */ - BIO *rbio; - /* used by SSL_write */ - BIO *wbio; - /* used during session-id reuse to concatenate messages */ - BIO *bbio; -# else - /* used by SSL_read */ - char *rbio; - /* used by SSL_write */ - char *wbio; - char *bbio; -# endif - /* - * This holds a variable that indicates what we were doing when a 0 or -1 - * is returned. This is needed for non-blocking IO so we know what - * request needs re-doing when in SSL_accept or SSL_connect - */ - int rwstate; - /* true when we are actually in SSL_accept() or SSL_connect() */ - int in_handshake; - int (*handshake_func) (SSL *); - /* - * Imagine that here's a boolean member "init" that is switched as soon - * as SSL_set_{accept/connect}_state is called for the first time, so - * that "state" and "handshake_func" are properly initialized. But as - * handshake_func is == 0 until then, we use this test instead of an - * "init" member. - */ - /* are we the server side? - mostly used by SSL_clear */ - int server; - /* - * Generate a new session or reuse an old one. - * NB: For servers, the 'new' session may actually be a previously - * cached session or even the previous session unless - * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set - */ - int new_session; - /* don't send shutdown packets */ - int quiet_shutdown; - /* we have shut things down, 0x01 sent, 0x02 for received */ - int shutdown; - /* where we are */ - int state; - /* where we are when reading */ - int rstate; - BUF_MEM *init_buf; /* buffer used during init */ - void *init_msg; /* pointer to handshake message body, set by - * ssl3_get_message() */ - int init_num; /* amount read/written */ - int init_off; /* amount read/written */ - /* used internally to point at a raw packet */ - unsigned char *packet; - unsigned int packet_length; - struct ssl2_state_st *s2; /* SSLv2 variables */ - struct ssl3_state_st *s3; /* SSLv3 variables */ - struct dtls1_state_st *d1; /* DTLSv1 variables */ - int read_ahead; /* Read as many input bytes as possible (for - * non-blocking reads) */ - /* callback that allows applications to peek at protocol messages */ - void (*msg_callback) (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg); - void *msg_callback_arg; - int hit; /* reusing a previous session */ - X509_VERIFY_PARAM *param; -# if 0 - int purpose; /* Purpose setting */ - int trust; /* Trust setting */ -# endif - /* crypto */ - STACK_OF(SSL_CIPHER) *cipher_list; - STACK_OF(SSL_CIPHER) *cipher_list_by_id; - /* - * These are the ones being used, the ones in SSL_SESSION are the ones to - * be 'copied' into these ones - */ - int mac_flags; - EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ - EVP_MD_CTX *read_hash; /* used for mac generation */ -# ifndef OPENSSL_NO_COMP - COMP_CTX *expand; /* uncompress */ -# else - char *expand; -# endif - EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ - EVP_MD_CTX *write_hash; /* used for mac generation */ -# ifndef OPENSSL_NO_COMP - COMP_CTX *compress; /* compression */ -# else - char *compress; -# endif - /* session info */ - /* client cert? */ - /* This is used to hold the server certificate used */ - struct cert_st /* CERT */ *cert; - /* - * the session_id_context is used to ensure sessions are only reused in - * the appropriate context - */ - unsigned int sid_ctx_length; - unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; - /* This can also be in the session once a session is established */ - SSL_SESSION *session; - /* Default generate session ID callback. */ - GEN_SESSION_CB generate_session_id; - /* Used in SSL2 and SSL3 */ - /* - * 0 don't care about verify failure. - * 1 fail if verify fails - */ - int verify_mode; - /* fail if callback returns 0 */ - int (*verify_callback) (int ok, X509_STORE_CTX *ctx); - /* optional informational callback */ - void (*info_callback) (const SSL *ssl, int type, int val); - /* error bytes to be written */ - int error; - /* actual code */ - int error_code; -# ifndef OPENSSL_NO_KRB5 - /* Kerberos 5 context */ - KSSL_CTX *kssl_ctx; -# endif /* OPENSSL_NO_KRB5 */ -# ifndef OPENSSL_NO_PSK - unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, - char *identity, - unsigned int max_identity_len, - unsigned char *psk, - unsigned int max_psk_len); - unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, - unsigned char *psk, - unsigned int max_psk_len); -# endif - SSL_CTX *ctx; - /* - * set this flag to 1 and a sleep(1) is put into all SSL_read() and - * SSL_write() calls, good for nbio debuging :-) - */ - int debug; - /* extra application data */ - long verify_result; - CRYPTO_EX_DATA ex_data; - /* for server side, keep the list of CA_dn we can use */ - STACK_OF(X509_NAME) *client_CA; - int references; - /* protocol behaviour */ - unsigned long options; - /* API behaviour */ - unsigned long mode; - long max_cert_list; - int first_packet; - /* what was passed, used for SSLv3/TLS rollback check */ - int client_version; - unsigned int max_send_fragment; -# ifndef OPENSSL_NO_TLSEXT - /* TLS extension debug callback */ - void (*tlsext_debug_cb) (SSL *s, int client_server, int type, - unsigned char *data, int len, void *arg); - void *tlsext_debug_arg; - char *tlsext_hostname; - /*- - * no further mod of servername - * 0 : call the servername extension callback. - * 1 : prepare 2, allow last ack just after in server callback. - * 2 : don't call servername callback, no ack in server hello - */ - int servername_done; - /* certificate status request info */ - /* Status type or -1 if no status type */ - int tlsext_status_type; - /* Expect OCSP CertificateStatus message */ - int tlsext_status_expected; - /* OCSP status request only */ - STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; - X509_EXTENSIONS *tlsext_ocsp_exts; - /* OCSP response received or to be sent */ - unsigned char *tlsext_ocsp_resp; - int tlsext_ocsp_resplen; - /* RFC4507 session ticket expected to be received or sent */ - int tlsext_ticket_expected; -# ifndef OPENSSL_NO_EC - size_t tlsext_ecpointformatlist_length; - /* our list */ - unsigned char *tlsext_ecpointformatlist; - size_t tlsext_ellipticcurvelist_length; - /* our list */ - unsigned char *tlsext_ellipticcurvelist; -# endif /* OPENSSL_NO_EC */ - /* - * draft-rescorla-tls-opaque-prf-input-00.txt information to be used for - * handshakes - */ - void *tlsext_opaque_prf_input; - size_t tlsext_opaque_prf_input_len; - /* TLS Session Ticket extension override */ - TLS_SESSION_TICKET_EXT *tlsext_session_ticket; - /* TLS Session Ticket extension callback */ - tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; - void *tls_session_ticket_ext_cb_arg; - /* TLS pre-shared secret session resumption */ - tls_session_secret_cb_fn tls_session_secret_cb; - void *tls_session_secret_cb_arg; - SSL_CTX *initial_ctx; /* initial ctx, used to store sessions */ -# ifndef OPENSSL_NO_NEXTPROTONEG - /* - * Next protocol negotiation. For the client, this is the protocol that - * we sent in NextProtocol and is set when handling ServerHello - * extensions. For a server, this is the client's selected_protocol from - * NextProtocol and is set when handling the NextProtocol message, before - * the Finished message. - */ - unsigned char *next_proto_negotiated; - unsigned char next_proto_negotiated_len; -# endif -# define session_ctx initial_ctx - /* What we'll do */ - STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; - /* What's been chosen */ - SRTP_PROTECTION_PROFILE *srtp_profile; - /*- - * Is use of the Heartbeat extension negotiated? - * 0: disabled - * 1: enabled - * 2: enabled, but not allowed to send Requests - */ - unsigned int tlsext_heartbeat; - /* Indicates if a HeartbeatRequest is in flight */ - unsigned int tlsext_hb_pending; - /* HeartbeatRequest sequence number */ - unsigned int tlsext_hb_seq; -# else -# define session_ctx ctx -# endif /* OPENSSL_NO_TLSEXT */ - /*- - * 1 if we are renegotiating. - * 2 if we are a server and are inside a handshake - * (i.e. not just sending a HelloRequest) - */ - int renegotiate; -# ifndef OPENSSL_NO_SRP - /* ctx for SRP authentication */ - SRP_CTX srp_ctx; -# endif -# ifndef OPENSSL_NO_TLSEXT - /* - * For a client, this contains the list of supported protocols in wire - * format. - */ - unsigned char *alpn_client_proto_list; - unsigned alpn_client_proto_list_len; -# endif /* OPENSSL_NO_TLSEXT */ -}; - -# endif - -#ifdef __cplusplus -} -#endif - -# include "ssl2.h" -# include "ssl3.h" -# include "tls1.h" /* This is mostly sslv3 with a few tweaks */ -# include "dtls1.h" /* Datagram TLS */ -# include "ssl23.h" -# include "srtp.h" /* Support for the use_srtp extension */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* compatibility */ -# define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) -# define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) -# define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0,(char *)a)) -# define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) -# define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) -# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg)) - -/* - * The following are the possible values for ssl->state are are used to - * indicate where we are up to in the SSL connection establishment. The - * macros that follow are about the only things you should need to use and - * even then, only when using non-blocking IO. It can also be useful to work - * out where you were when the connection failed - */ - -# define SSL_ST_CONNECT 0x1000 -# define SSL_ST_ACCEPT 0x2000 -# define SSL_ST_MASK 0x0FFF -# define SSL_ST_INIT (SSL_ST_CONNECT|SSL_ST_ACCEPT) -# define SSL_ST_BEFORE 0x4000 -# define SSL_ST_OK 0x03 -# define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) -# define SSL_ST_ERR (0x05|SSL_ST_INIT) - -# define SSL_CB_LOOP 0x01 -# define SSL_CB_EXIT 0x02 -# define SSL_CB_READ 0x04 -# define SSL_CB_WRITE 0x08 -# define SSL_CB_ALERT 0x4000/* used in callback */ -# define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) -# define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) -# define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) -# define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) -# define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) -# define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) -# define SSL_CB_HANDSHAKE_START 0x10 -# define SSL_CB_HANDSHAKE_DONE 0x20 - -/* Is the SSL_connection established? */ -# define SSL_get_state(a) SSL_state(a) -# define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK) -# define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT) -# define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE) -# define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT) -# define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT) - -/* - * The following 2 states are kept in ssl->rstate when reads fail, you should - * not need these - */ -# define SSL_ST_READ_HEADER 0xF0 -# define SSL_ST_READ_BODY 0xF1 -# define SSL_ST_READ_DONE 0xF2 - -/*- - * Obtain latest Finished message - * -- that we sent (SSL_get_finished) - * -- that we expected from peer (SSL_get_peer_finished). - * Returns length (0 == no Finished so far), copies up to 'count' bytes. - */ -size_t SSL_get_finished(const SSL *s, void *buf, size_t count); -size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); - -/* - * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are - * 'ored' with SSL_VERIFY_PEER if they are desired - */ -# define SSL_VERIFY_NONE 0x00 -# define SSL_VERIFY_PEER 0x01 -# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 -# define SSL_VERIFY_CLIENT_ONCE 0x04 - -# define OpenSSL_add_ssl_algorithms() SSL_library_init() -# define SSLeay_add_ssl_algorithms() SSL_library_init() - -/* this is for backward compatibility */ -# if 0 /* NEW_SSLEAY */ -# define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c) -# define SSL_set_pref_cipher(c,n) SSL_set_cipher_list(c,n) -# define SSL_add_session(a,b) SSL_CTX_add_session((a),(b)) -# define SSL_remove_session(a,b) SSL_CTX_remove_session((a),(b)) -# define SSL_flush_sessions(a,b) SSL_CTX_flush_sessions((a),(b)) -# endif -/* More backward compatibility */ -# define SSL_get_cipher(s) \ - SSL_CIPHER_get_name(SSL_get_current_cipher(s)) -# define SSL_get_cipher_bits(s,np) \ - SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) -# define SSL_get_cipher_version(s) \ - SSL_CIPHER_get_version(SSL_get_current_cipher(s)) -# define SSL_get_cipher_name(s) \ - SSL_CIPHER_get_name(SSL_get_current_cipher(s)) -# define SSL_get_time(a) SSL_SESSION_get_time(a) -# define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) -# define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) -# define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) - -# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) -# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) - -DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) -# define SSL_AD_REASON_OFFSET 1000/* offset to get SSL_R_... value - * from SSL_AD_... */ -/* These alert types are for SSLv3 and TLSv1 */ -# define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY -/* fatal */ -# define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE -/* fatal */ -# define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC -# define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED -# define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW -/* fatal */ -# define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE -/* fatal */ -# define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE -/* Not for TLS */ -# define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE -# define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE -# define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE -# define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED -# define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED -# define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN -/* fatal */ -# define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER -/* fatal */ -# define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA -/* fatal */ -# define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED -/* fatal */ -# define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR -# define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR -/* fatal */ -# define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION -/* fatal */ -# define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION -/* fatal */ -# define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY -/* fatal */ -# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR -# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED -# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION -# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION -# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE -# define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME -# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE -# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE -/* fatal */ -# define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY -/* fatal */ -# define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK -# define SSL_ERROR_NONE 0 -# define SSL_ERROR_SSL 1 -# define SSL_ERROR_WANT_READ 2 -# define SSL_ERROR_WANT_WRITE 3 -# define SSL_ERROR_WANT_X509_LOOKUP 4 -# define SSL_ERROR_SYSCALL 5/* look at error stack/return - * value/errno */ -# define SSL_ERROR_ZERO_RETURN 6 -# define SSL_ERROR_WANT_CONNECT 7 -# define SSL_ERROR_WANT_ACCEPT 8 -# define SSL_CTRL_NEED_TMP_RSA 1 -# define SSL_CTRL_SET_TMP_RSA 2 -# define SSL_CTRL_SET_TMP_DH 3 -# define SSL_CTRL_SET_TMP_ECDH 4 -# define SSL_CTRL_SET_TMP_RSA_CB 5 -# define SSL_CTRL_SET_TMP_DH_CB 6 -# define SSL_CTRL_SET_TMP_ECDH_CB 7 -# define SSL_CTRL_GET_SESSION_REUSED 8 -# define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 -# define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 -# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 -# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 -# define SSL_CTRL_GET_FLAGS 13 -# define SSL_CTRL_EXTRA_CHAIN_CERT 14 -# define SSL_CTRL_SET_MSG_CALLBACK 15 -# define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 -/* only applies to datagram connections */ -# define SSL_CTRL_SET_MTU 17 -/* Stats */ -# define SSL_CTRL_SESS_NUMBER 20 -# define SSL_CTRL_SESS_CONNECT 21 -# define SSL_CTRL_SESS_CONNECT_GOOD 22 -# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 -# define SSL_CTRL_SESS_ACCEPT 24 -# define SSL_CTRL_SESS_ACCEPT_GOOD 25 -# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 -# define SSL_CTRL_SESS_HIT 27 -# define SSL_CTRL_SESS_CB_HIT 28 -# define SSL_CTRL_SESS_MISSES 29 -# define SSL_CTRL_SESS_TIMEOUTS 30 -# define SSL_CTRL_SESS_CACHE_FULL 31 -# define SSL_CTRL_OPTIONS 32 -# define SSL_CTRL_MODE 33 -# define SSL_CTRL_GET_READ_AHEAD 40 -# define SSL_CTRL_SET_READ_AHEAD 41 -# define SSL_CTRL_SET_SESS_CACHE_SIZE 42 -# define SSL_CTRL_GET_SESS_CACHE_SIZE 43 -# define SSL_CTRL_SET_SESS_CACHE_MODE 44 -# define SSL_CTRL_GET_SESS_CACHE_MODE 45 -# define SSL_CTRL_GET_MAX_CERT_LIST 50 -# define SSL_CTRL_SET_MAX_CERT_LIST 51 -# define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 -/* see tls1.h for macros based on these */ -# ifndef OPENSSL_NO_TLSEXT -# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 -# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 -# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 -# define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 -# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 -# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 -# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 -# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 -# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 -# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 -# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 -# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 -# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 -# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 -# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 -# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 -# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 -# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 -# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 -# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 -# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 -# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 -# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 -# define SSL_CTRL_SET_SRP_ARG 78 -# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 -# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 -# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 -# ifndef OPENSSL_NO_HEARTBEATS -# define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT 85 -# define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86 -# define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87 -# endif -# endif /* OPENSSL_NO_TLSEXT */ -# define DTLS_CTRL_GET_TIMEOUT 73 -# define DTLS_CTRL_HANDLE_TIMEOUT 74 -# define DTLS_CTRL_LISTEN 75 -# define SSL_CTRL_GET_RI_SUPPORT 76 -# define SSL_CTRL_CLEAR_OPTIONS 77 -# define SSL_CTRL_CLEAR_MODE 78 -# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 -# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 -# define SSL_CTRL_CHAIN 88 -# define SSL_CTRL_CHAIN_CERT 89 -# define SSL_CTRL_GET_CURVES 90 -# define SSL_CTRL_SET_CURVES 91 -# define SSL_CTRL_SET_CURVES_LIST 92 -# define SSL_CTRL_GET_SHARED_CURVE 93 -# define SSL_CTRL_SET_ECDH_AUTO 94 -# define SSL_CTRL_SET_SIGALGS 97 -# define SSL_CTRL_SET_SIGALGS_LIST 98 -# define SSL_CTRL_CERT_FLAGS 99 -# define SSL_CTRL_CLEAR_CERT_FLAGS 100 -# define SSL_CTRL_SET_CLIENT_SIGALGS 101 -# define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102 -# define SSL_CTRL_GET_CLIENT_CERT_TYPES 103 -# define SSL_CTRL_SET_CLIENT_CERT_TYPES 104 -# define SSL_CTRL_BUILD_CERT_CHAIN 105 -# define SSL_CTRL_SET_VERIFY_CERT_STORE 106 -# define SSL_CTRL_SET_CHAIN_CERT_STORE 107 -# define SSL_CTRL_GET_PEER_SIGNATURE_NID 108 -# define SSL_CTRL_GET_SERVER_TMP_KEY 109 -# define SSL_CTRL_GET_RAW_CIPHERLIST 110 -# define SSL_CTRL_GET_EC_POINT_FORMATS 111 -# define SSL_CTRL_GET_CHAIN_CERTS 115 -# define SSL_CTRL_SELECT_CURRENT_CERT 116 -# define SSL_CTRL_SET_CURRENT_CERT 117 -# define SSL_CTRL_CHECK_PROTO_VERSION 119 -# define DTLS_CTRL_SET_LINK_MTU 120 -# define DTLS_CTRL_GET_LINK_MIN_MTU 121 -# define SSL_CERT_SET_FIRST 1 -# define SSL_CERT_SET_NEXT 2 -# define SSL_CERT_SET_SERVER 3 -# define DTLSv1_get_timeout(ssl, arg) \ - SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) -# define DTLSv1_handle_timeout(ssl) \ - SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) -# define DTLSv1_listen(ssl, peer) \ - SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer) -# define SSL_session_reused(ssl) \ - SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) -# define SSL_num_renegotiations(ssl) \ - SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) -# define SSL_clear_num_renegotiations(ssl) \ - SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) -# define SSL_total_renegotiations(ssl) \ - SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) -# define SSL_CTX_need_tmp_RSA(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL) -# define SSL_CTX_set_tmp_rsa(ctx,rsa) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) -# define SSL_CTX_set_tmp_dh(ctx,dh) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh) -# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) -# define SSL_need_tmp_RSA(ssl) \ - SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL) -# define SSL_set_tmp_rsa(ssl,rsa) \ - SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) -# define SSL_set_tmp_dh(ssl,dh) \ - SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh) -# define SSL_set_tmp_ecdh(ssl,ecdh) \ - SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) -# define SSL_CTX_add_extra_chain_cert(ctx,x509) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509) -# define SSL_CTX_get_extra_chain_certs(ctx,px509) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) -# define SSL_CTX_get_extra_chain_certs_only(ctx,px509) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,1,px509) -# define SSL_CTX_clear_extra_chain_certs(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) -# define SSL_CTX_set0_chain(ctx,sk) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk) -# define SSL_CTX_set1_chain(ctx,sk) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk) -# define SSL_CTX_add0_chain_cert(ctx,x509) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509) -# define SSL_CTX_add1_chain_cert(ctx,x509) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509) -# define SSL_CTX_get0_chain_certs(ctx,px509) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) -# define SSL_CTX_clear_chain_certs(ctx) \ - SSL_CTX_set0_chain(ctx,NULL) -# define SSL_CTX_build_cert_chain(ctx, flags) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) -# define SSL_CTX_select_current_cert(ctx,x509) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509) -# define SSL_CTX_set_current_cert(ctx, op) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) -# define SSL_CTX_set0_verify_cert_store(ctx,st) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st) -# define SSL_CTX_set1_verify_cert_store(ctx,st) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st) -# define SSL_CTX_set0_chain_cert_store(ctx,st) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st) -# define SSL_CTX_set1_chain_cert_store(ctx,st) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st) -# define SSL_set0_chain(ctx,sk) \ - SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk) -# define SSL_set1_chain(ctx,sk) \ - SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk) -# define SSL_add0_chain_cert(ctx,x509) \ - SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509) -# define SSL_add1_chain_cert(ctx,x509) \ - SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509) -# define SSL_get0_chain_certs(ctx,px509) \ - SSL_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509) -# define SSL_clear_chain_certs(ctx) \ - SSL_set0_chain(ctx,NULL) -# define SSL_build_cert_chain(s, flags) \ - SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL) -# define SSL_select_current_cert(ctx,x509) \ - SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)x509) -# define SSL_set_current_cert(ctx,op) \ - SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL) -# define SSL_set0_verify_cert_store(s,st) \ - SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)st) -# define SSL_set1_verify_cert_store(s,st) \ - SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,1,(char *)st) -# define SSL_set0_chain_cert_store(s,st) \ - SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)st) -# define SSL_set1_chain_cert_store(s,st) \ - SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)st) -# define SSL_get1_curves(ctx, s) \ - SSL_ctrl(ctx,SSL_CTRL_GET_CURVES,0,(char *)s) -# define SSL_CTX_set1_curves(ctx, clist, clistlen) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist) -# define SSL_CTX_set1_curves_list(ctx, s) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s) -# define SSL_set1_curves(ctx, clist, clistlen) \ - SSL_ctrl(ctx,SSL_CTRL_SET_CURVES,clistlen,(char *)clist) -# define SSL_set1_curves_list(ctx, s) \ - SSL_ctrl(ctx,SSL_CTRL_SET_CURVES_LIST,0,(char *)s) -# define SSL_get_shared_curve(s, n) \ - SSL_ctrl(s,SSL_CTRL_GET_SHARED_CURVE,n,NULL) -# define SSL_CTX_set_ecdh_auto(ctx, onoff) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) -# define SSL_set_ecdh_auto(s, onoff) \ - SSL_ctrl(s,SSL_CTRL_SET_ECDH_AUTO,onoff,NULL) -# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist) -# define SSL_CTX_set1_sigalgs_list(ctx, s) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s) -# define SSL_set1_sigalgs(ctx, slist, slistlen) \ - SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)slist) -# define SSL_set1_sigalgs_list(ctx, s) \ - SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)s) -# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)slist) -# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s) -# define SSL_set1_client_sigalgs(ctx, slist, slistlen) \ - SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)slist) -# define SSL_set1_client_sigalgs_list(ctx, s) \ - SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)s) -# define SSL_get0_certificate_types(s, clist) \ - SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist) -# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist) -# define SSL_set1_client_certificate_types(s, clist, clistlen) \ - SSL_ctrl(s,SSL_CTRL_SET_CLIENT_CERT_TYPES,clistlen,(char *)clist) -# define SSL_get_peer_signature_nid(s, pn) \ - SSL_ctrl(s,SSL_CTRL_GET_PEER_SIGNATURE_NID,0,pn) -# define SSL_get_server_tmp_key(s, pk) \ - SSL_ctrl(s,SSL_CTRL_GET_SERVER_TMP_KEY,0,pk) -# define SSL_get0_raw_cipherlist(s, plst) \ - SSL_ctrl(s,SSL_CTRL_GET_RAW_CIPHERLIST,0,(char *)plst) -# define SSL_get0_ec_point_formats(s, plst) \ - SSL_ctrl(s,SSL_CTRL_GET_EC_POINT_FORMATS,0,(char *)plst) -# ifndef OPENSSL_NO_BIO -BIO_METHOD *BIO_f_ssl(void); -BIO *BIO_new_ssl(SSL_CTX *ctx, int client); -BIO *BIO_new_ssl_connect(SSL_CTX *ctx); -BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); -int BIO_ssl_copy_session_id(BIO *to, BIO *from); -void BIO_ssl_shutdown(BIO *ssl_bio); - -# endif - -int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); -SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); -void SSL_CTX_free(SSL_CTX *); -long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); -long SSL_CTX_get_timeout(const SSL_CTX *ctx); -X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); -void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); -int SSL_want(const SSL *s); -int SSL_clear(SSL *s); - -void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); - -const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); -int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); -char *SSL_CIPHER_get_version(const SSL_CIPHER *c); -const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); -unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c); - -int SSL_get_fd(const SSL *s); -int SSL_get_rfd(const SSL *s); -int SSL_get_wfd(const SSL *s); -const char *SSL_get_cipher_list(const SSL *s, int n); -char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size); -int SSL_get_read_ahead(const SSL *s); -int SSL_pending(const SSL *s); -# ifndef OPENSSL_NO_SOCK -int SSL_set_fd(SSL *s, int fd); -int SSL_set_rfd(SSL *s, int fd); -int SSL_set_wfd(SSL *s, int fd); -# endif -# ifndef OPENSSL_NO_BIO -void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); -BIO *SSL_get_rbio(const SSL *s); -BIO *SSL_get_wbio(const SSL *s); -# endif -int SSL_set_cipher_list(SSL *s, const char *str); -void SSL_set_read_ahead(SSL *s, int yes); -int SSL_get_verify_mode(const SSL *s); -int SSL_get_verify_depth(const SSL *s); -int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *); -void SSL_set_verify(SSL *s, int mode, - int (*callback) (int ok, X509_STORE_CTX *ctx)); -void SSL_set_verify_depth(SSL *s, int depth); -void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg); -# ifndef OPENSSL_NO_RSA -int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); -# endif -int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); -int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); -int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, - long len); -int SSL_use_certificate(SSL *ssl, X509 *x); -int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); - -# ifndef OPENSSL_NO_TLSEXT -/* Set serverinfo data for the current active cert. */ -int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, - size_t serverinfo_length); -# ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); -# endif /* NO_STDIO */ - -# endif - -# ifndef OPENSSL_NO_STDIO -int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); -int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); -int SSL_use_certificate_file(SSL *ssl, const char *file, int type); -int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); -int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); -/* PEM type */ -int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); -STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); -int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, - const char *file); -# ifndef OPENSSL_SYS_VMS -/* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */ -# ifndef OPENSSL_SYS_MACINTOSH_CLASSIC -int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, - const char *dir); -# endif -# endif - -# endif - -void SSL_load_error_strings(void); -const char *SSL_state_string(const SSL *s); -const char *SSL_rstate_string(const SSL *s); -const char *SSL_state_string_long(const SSL *s); -const char *SSL_rstate_string_long(const SSL *s); -long SSL_SESSION_get_time(const SSL_SESSION *s); -long SSL_SESSION_set_time(SSL_SESSION *s, long t); -long SSL_SESSION_get_timeout(const SSL_SESSION *s); -long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); -void SSL_copy_session_id(SSL *to, const SSL *from); -X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); -int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, - unsigned int sid_ctx_len); - -SSL_SESSION *SSL_SESSION_new(void); -const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, - unsigned int *len); -unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); -# ifndef OPENSSL_NO_FP_API -int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); -# endif -# ifndef OPENSSL_NO_BIO -int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); -# endif -void SSL_SESSION_free(SSL_SESSION *ses); -int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); -int SSL_set_session(SSL *to, SSL_SESSION *session); -int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); -int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c); -int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); -int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB); -int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, - unsigned int id_len); -SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, - long length); - -# ifdef HEADER_X509_H -X509 *SSL_get_peer_certificate(const SSL *s); -# endif - -STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); - -int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); -int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); -int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, - X509_STORE_CTX *); -void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, - int (*callback) (int, X509_STORE_CTX *)); -void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); -void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, - int (*cb) (X509_STORE_CTX *, void *), - void *arg); -void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), - void *arg); -# ifndef OPENSSL_NO_RSA -int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); -# endif -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, - long len); -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); -int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, - const unsigned char *d, long len); -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, - const unsigned char *d); - -void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); -void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); - -int SSL_CTX_check_private_key(const SSL_CTX *ctx); -int SSL_check_private_key(const SSL *ctx); - -int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, - unsigned int sid_ctx_len); - -SSL *SSL_new(SSL_CTX *ctx); -int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, - unsigned int sid_ctx_len); - -int SSL_CTX_set_purpose(SSL_CTX *s, int purpose); -int SSL_set_purpose(SSL *s, int purpose); -int SSL_CTX_set_trust(SSL_CTX *s, int trust); -int SSL_set_trust(SSL *s, int trust); - -int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); -int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); - -X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); -X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); - -# ifndef OPENSSL_NO_SRP -int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name); -int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password); -int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); -int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, - char *(*cb) (SSL *, void *)); -int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, - int (*cb) (SSL *, void *)); -int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, - int (*cb) (SSL *, int *, void *)); -int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); - -int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, - BIGNUM *sa, BIGNUM *v, char *info); -int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, - const char *grp); - -BIGNUM *SSL_get_srp_g(SSL *s); -BIGNUM *SSL_get_srp_N(SSL *s); - -char *SSL_get_srp_username(SSL *s); -char *SSL_get_srp_userinfo(SSL *s); -# endif - -void SSL_certs_clear(SSL *s); -void SSL_free(SSL *ssl); -int SSL_accept(SSL *ssl); -int SSL_connect(SSL *ssl); -int SSL_read(SSL *ssl, void *buf, int num); -int SSL_peek(SSL *ssl, void *buf, int num); -int SSL_write(SSL *ssl, const void *buf, int num); -long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); -long SSL_callback_ctrl(SSL *, int, void (*)(void)); -long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); -long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); - -int SSL_get_error(const SSL *s, int ret_code); -const char *SSL_get_version(const SSL *s); - -/* This sets the 'default' SSL version that SSL_new() will create */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); - -# ifndef OPENSSL_NO_SSL2_METHOD -const SSL_METHOD *SSLv2_method(void); /* SSLv2 */ -const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */ -const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ -# endif - -# ifndef OPENSSL_NO_SSL3_METHOD -const SSL_METHOD *SSLv3_method(void); /* SSLv3 */ -const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ -const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ -# endif - -const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS - * version */ -const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available - * SSL/TLS version */ -const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available - * SSL/TLS version */ - -const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ -const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ -const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ - -const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */ -const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */ -const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */ - -const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */ -const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */ -const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */ - -const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ -const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ -const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ - -const SSL_METHOD *DTLSv1_2_method(void); /* DTLSv1.2 */ -const SSL_METHOD *DTLSv1_2_server_method(void); /* DTLSv1.2 */ -const SSL_METHOD *DTLSv1_2_client_method(void); /* DTLSv1.2 */ - -const SSL_METHOD *DTLS_method(void); /* DTLS 1.0 and 1.2 */ -const SSL_METHOD *DTLS_server_method(void); /* DTLS 1.0 and 1.2 */ -const SSL_METHOD *DTLS_client_method(void); /* DTLS 1.0 and 1.2 */ - -STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); - -int SSL_do_handshake(SSL *s); -int SSL_renegotiate(SSL *s); -int SSL_renegotiate_abbreviated(SSL *s); -int SSL_renegotiate_pending(SSL *s); -int SSL_shutdown(SSL *s); - -const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); -const SSL_METHOD *SSL_get_ssl_method(SSL *s); -int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); -const char *SSL_alert_type_string_long(int value); -const char *SSL_alert_type_string(int value); -const char *SSL_alert_desc_string_long(int value); -const char *SSL_alert_desc_string(int value); - -void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); -void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); -STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); -STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); -int SSL_add_client_CA(SSL *ssl, X509 *x); -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); - -void SSL_set_connect_state(SSL *s); -void SSL_set_accept_state(SSL *s); - -long SSL_get_default_timeout(const SSL *s); - -int SSL_library_init(void); - -char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); -STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk); - -SSL *SSL_dup(SSL *ssl); - -X509 *SSL_get_certificate(const SSL *ssl); -/* - * EVP_PKEY - */ struct evp_pkey_st *SSL_get_privatekey(const SSL *ssl); - -X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); -EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); - -void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); -int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); -void SSL_set_quiet_shutdown(SSL *ssl, int mode); -int SSL_get_quiet_shutdown(const SSL *ssl); -void SSL_set_shutdown(SSL *ssl, int mode); -int SSL_get_shutdown(const SSL *ssl); -int SSL_version(const SSL *ssl); -int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); -int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, - const char *CApath); -# define SSL_get0_session SSL_get_session/* just peek at pointer */ -SSL_SESSION *SSL_get_session(const SSL *ssl); -SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ -SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); -SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); -void SSL_set_info_callback(SSL *ssl, - void (*cb) (const SSL *ssl, int type, int val)); -void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type, - int val); -int SSL_state(const SSL *ssl); -void SSL_set_state(SSL *ssl, int state); - -void SSL_set_verify_result(SSL *ssl, long v); -long SSL_get_verify_result(const SSL *ssl); - -int SSL_set_ex_data(SSL *ssl, int idx, void *data); -void *SSL_get_ex_data(const SSL *ssl, int idx); -int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); - -int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); -void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); -int SSL_SESSION_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); - -int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); -void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); -int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); - -int SSL_get_ex_data_X509_STORE_CTX_idx(void); - -# define SSL_CTX_sess_set_cache_size(ctx,t) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) -# define SSL_CTX_sess_get_cache_size(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) -# define SSL_CTX_set_session_cache_mode(ctx,m) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) -# define SSL_CTX_get_session_cache_mode(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) - -# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) -# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) -# define SSL_CTX_get_read_ahead(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) -# define SSL_CTX_set_read_ahead(ctx,m) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) -# define SSL_CTX_get_max_cert_list(ctx) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) -# define SSL_CTX_set_max_cert_list(ctx,m) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) -# define SSL_get_max_cert_list(ssl) \ - SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) -# define SSL_set_max_cert_list(ssl,m) \ - SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) - -# define SSL_CTX_set_max_send_fragment(ctx,m) \ - SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) -# define SSL_set_max_send_fragment(ssl,m) \ - SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) - - /* NB: the keylength is only applicable when is_export is true */ -# ifndef OPENSSL_NO_RSA -void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, - RSA *(*cb) (SSL *ssl, int is_export, - int keylength)); - -void SSL_set_tmp_rsa_callback(SSL *ssl, - RSA *(*cb) (SSL *ssl, int is_export, - int keylength)); -# endif -# ifndef OPENSSL_NO_DH -void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, - DH *(*dh) (SSL *ssl, int is_export, - int keylength)); -void SSL_set_tmp_dh_callback(SSL *ssl, - DH *(*dh) (SSL *ssl, int is_export, - int keylength)); -# endif -# ifndef OPENSSL_NO_ECDH -void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, - EC_KEY *(*ecdh) (SSL *ssl, int is_export, - int keylength)); -void SSL_set_tmp_ecdh_callback(SSL *ssl, - EC_KEY *(*ecdh) (SSL *ssl, int is_export, - int keylength)); -# endif - -const COMP_METHOD *SSL_get_current_compression(SSL *s); -const COMP_METHOD *SSL_get_current_expansion(SSL *s); -const char *SSL_COMP_get_name(const COMP_METHOD *comp); -STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); -STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) - *meths); -void SSL_COMP_free_compression_methods(void); -int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); - -const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr); - -/* TLS extensions functions */ -int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); - -int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, - void *arg); - -/* Pre-shared secret session resumption functions */ -int SSL_set_session_secret_cb(SSL *s, - tls_session_secret_cb_fn tls_session_secret_cb, - void *arg); - -void SSL_set_debug(SSL *s, int debug); -int SSL_cache_hit(SSL *s); -int SSL_is_server(SSL *s); - -SSL_CONF_CTX *SSL_CONF_CTX_new(void); -int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx); -void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx); -unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags); -unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags); -int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre); - -void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl); -void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx); - -int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value); -int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv); -int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd); - -# ifndef OPENSSL_NO_SSL_TRACE -void SSL_trace(int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg); -const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c); -# endif - -# ifndef OPENSSL_NO_UNIT_TEST -const struct openssl_ssl_test_functions *SSL_test_functions(void); -# endif - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_SSL_strings(void); - -/* Error codes for the SSL functions. */ - -/* Function codes. */ -# define SSL_F_CHECK_SUITEB_CIPHER_LIST 331 -# define SSL_F_CLIENT_CERTIFICATE 100 -# define SSL_F_CLIENT_FINISHED 167 -# define SSL_F_CLIENT_HELLO 101 -# define SSL_F_CLIENT_MASTER_KEY 102 -# define SSL_F_D2I_SSL_SESSION 103 -# define SSL_F_DO_DTLS1_WRITE 245 -# define SSL_F_DO_SSL3_WRITE 104 -# define SSL_F_DTLS1_ACCEPT 246 -# define SSL_F_DTLS1_ADD_CERT_TO_BUF 295 -# define SSL_F_DTLS1_BUFFER_RECORD 247 -# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 316 -# define SSL_F_DTLS1_CLIENT_HELLO 248 -# define SSL_F_DTLS1_CONNECT 249 -# define SSL_F_DTLS1_ENC 250 -# define SSL_F_DTLS1_GET_HELLO_VERIFY 251 -# define SSL_F_DTLS1_GET_MESSAGE 252 -# define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 -# define SSL_F_DTLS1_GET_RECORD 254 -# define SSL_F_DTLS1_HANDLE_TIMEOUT 297 -# define SSL_F_DTLS1_HEARTBEAT 305 -# define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 -# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 -# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424 -# define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 -# define SSL_F_DTLS1_PROCESS_RECORD 257 -# define SSL_F_DTLS1_READ_BYTES 258 -# define SSL_F_DTLS1_READ_FAILED 259 -# define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST 260 -# define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE 261 -# define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE 262 -# define SSL_F_DTLS1_SEND_CLIENT_VERIFY 263 -# define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST 264 -# define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE 265 -# define SSL_F_DTLS1_SEND_SERVER_HELLO 266 -# define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE 267 -# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 -# define SSL_F_GET_CLIENT_FINISHED 105 -# define SSL_F_GET_CLIENT_HELLO 106 -# define SSL_F_GET_CLIENT_MASTER_KEY 107 -# define SSL_F_GET_SERVER_FINISHED 108 -# define SSL_F_GET_SERVER_HELLO 109 -# define SSL_F_GET_SERVER_STATIC_DH_KEY 340 -# define SSL_F_GET_SERVER_VERIFY 110 -# define SSL_F_I2D_SSL_SESSION 111 -# define SSL_F_READ_N 112 -# define SSL_F_REQUEST_CERTIFICATE 113 -# define SSL_F_SERVER_FINISH 239 -# define SSL_F_SERVER_HELLO 114 -# define SSL_F_SERVER_VERIFY 240 -# define SSL_F_SSL23_ACCEPT 115 -# define SSL_F_SSL23_CLIENT_HELLO 116 -# define SSL_F_SSL23_CONNECT 117 -# define SSL_F_SSL23_GET_CLIENT_HELLO 118 -# define SSL_F_SSL23_GET_SERVER_HELLO 119 -# define SSL_F_SSL23_PEEK 237 -# define SSL_F_SSL23_READ 120 -# define SSL_F_SSL23_WRITE 121 -# define SSL_F_SSL2_ACCEPT 122 -# define SSL_F_SSL2_CONNECT 123 -# define SSL_F_SSL2_ENC_INIT 124 -# define SSL_F_SSL2_GENERATE_KEY_MATERIAL 241 -# define SSL_F_SSL2_PEEK 234 -# define SSL_F_SSL2_READ 125 -# define SSL_F_SSL2_READ_INTERNAL 236 -# define SSL_F_SSL2_SET_CERTIFICATE 126 -# define SSL_F_SSL2_WRITE 127 -# define SSL_F_SSL3_ACCEPT 128 -# define SSL_F_SSL3_ADD_CERT_TO_BUF 296 -# define SSL_F_SSL3_CALLBACK_CTRL 233 -# define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 -# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 -# define SSL_F_SSL3_CHECK_CLIENT_HELLO 304 -# define SSL_F_SSL3_CHECK_FINISHED 339 -# define SSL_F_SSL3_CLIENT_HELLO 131 -# define SSL_F_SSL3_CONNECT 132 -# define SSL_F_SSL3_CTRL 213 -# define SSL_F_SSL3_CTX_CTRL 133 -# define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 -# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 -# define SSL_F_SSL3_ENC 134 -# define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 -# define SSL_F_SSL3_GENERATE_MASTER_SECRET 388 -# define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 -# define SSL_F_SSL3_GET_CERT_STATUS 289 -# define SSL_F_SSL3_GET_CERT_VERIFY 136 -# define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137 -# define SSL_F_SSL3_GET_CLIENT_HELLO 138 -# define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139 -# define SSL_F_SSL3_GET_FINISHED 140 -# define SSL_F_SSL3_GET_KEY_EXCHANGE 141 -# define SSL_F_SSL3_GET_MESSAGE 142 -# define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283 -# define SSL_F_SSL3_GET_NEXT_PROTO 306 -# define SSL_F_SSL3_GET_RECORD 143 -# define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 -# define SSL_F_SSL3_GET_SERVER_DONE 145 -# define SSL_F_SSL3_GET_SERVER_HELLO 146 -# define SSL_F_SSL3_HANDSHAKE_MAC 285 -# define SSL_F_SSL3_NEW_SESSION_TICKET 287 -# define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 -# define SSL_F_SSL3_PEEK 235 -# define SSL_F_SSL3_READ_BYTES 148 -# define SSL_F_SSL3_READ_N 149 -# define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150 -# define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151 -# define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152 -# define SSL_F_SSL3_SEND_CLIENT_VERIFY 153 -# define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 -# define SSL_F_SSL3_SEND_SERVER_HELLO 242 -# define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 -# define SSL_F_SSL3_SETUP_KEY_BLOCK 157 -# define SSL_F_SSL3_SETUP_READ_BUFFER 156 -# define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 -# define SSL_F_SSL3_WRITE_BYTES 158 -# define SSL_F_SSL3_WRITE_PENDING 159 -# define SSL_F_SSL_ADD_CERT_CHAIN 318 -# define SSL_F_SSL_ADD_CERT_TO_BUF 319 -# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 -# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 -# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 -# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 -# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 -# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 -# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 -# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 -# define SSL_F_SSL_BAD_METHOD 160 -# define SSL_F_SSL_BUILD_CERT_CHAIN 332 -# define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 -# define SSL_F_SSL_CERT_DUP 221 -# define SSL_F_SSL_CERT_INST 222 -# define SSL_F_SSL_CERT_INSTANTIATE 214 -# define SSL_F_SSL_CERT_NEW 162 -# define SSL_F_SSL_CHECK_PRIVATE_KEY 163 -# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 -# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 -# define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 -# define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 -# define SSL_F_SSL_CLEAR 164 -# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 -# define SSL_F_SSL_CONF_CMD 334 -# define SSL_F_SSL_CREATE_CIPHER_LIST 166 -# define SSL_F_SSL_CTRL 232 -# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 -# define SSL_F_SSL_CTX_MAKE_PROFILES 309 -# define SSL_F_SSL_CTX_NEW 169 -# define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 -# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 -# define SSL_F_SSL_CTX_SET_PURPOSE 226 -# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 -# define SSL_F_SSL_CTX_SET_SSL_VERSION 170 -# define SSL_F_SSL_CTX_SET_TRUST 229 -# define SSL_F_SSL_CTX_USE_CERTIFICATE 171 -# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 -# define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 -# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 -# define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 -# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 -# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 -# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 -# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 -# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 -# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 -# define SSL_F_SSL_CTX_USE_SERVERINFO 336 -# define SSL_F_SSL_CTX_USE_SERVERINFO_FILE 337 -# define SSL_F_SSL_DO_HANDSHAKE 180 -# define SSL_F_SSL_GET_NEW_SESSION 181 -# define SSL_F_SSL_GET_PREV_SESSION 217 -# define SSL_F_SSL_GET_SERVER_CERT_INDEX 322 -# define SSL_F_SSL_GET_SERVER_SEND_CERT 182 -# define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 -# define SSL_F_SSL_GET_SIGN_PKEY 183 -# define SSL_F_SSL_INIT_WBIO_BUFFER 184 -# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 -# define SSL_F_SSL_NEW 186 -# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 -# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 -# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 -# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 -# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 -# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 -# define SSL_F_SSL_PEEK 270 -# define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281 -# define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282 -# define SSL_F_SSL_READ 223 -# define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 -# define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 -# define SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT 320 -# define SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT 321 -# define SSL_F_SSL_SESSION_DUP 348 -# define SSL_F_SSL_SESSION_NEW 189 -# define SSL_F_SSL_SESSION_PRINT_FP 190 -# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 -# define SSL_F_SSL_SESS_CERT_NEW 225 -# define SSL_F_SSL_SET_CERT 191 -# define SSL_F_SSL_SET_CIPHER_LIST 271 -# define SSL_F_SSL_SET_FD 192 -# define SSL_F_SSL_SET_PKEY 193 -# define SSL_F_SSL_SET_PURPOSE 227 -# define SSL_F_SSL_SET_RFD 194 -# define SSL_F_SSL_SET_SESSION 195 -# define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 -# define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 -# define SSL_F_SSL_SET_TRUST 228 -# define SSL_F_SSL_SET_WFD 196 -# define SSL_F_SSL_SHUTDOWN 224 -# define SSL_F_SSL_SRP_CTX_INIT 313 -# define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 -# define SSL_F_SSL_UNDEFINED_FUNCTION 197 -# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 -# define SSL_F_SSL_USE_CERTIFICATE 198 -# define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 -# define SSL_F_SSL_USE_CERTIFICATE_FILE 200 -# define SSL_F_SSL_USE_PRIVATEKEY 201 -# define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 -# define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 -# define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 -# define SSL_F_SSL_USE_RSAPRIVATEKEY 204 -# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 -# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 -# define SSL_F_SSL_VERIFY_CERT_CHAIN 207 -# define SSL_F_SSL_WRITE 208 -# define SSL_F_TLS12_CHECK_PEER_SIGALG 333 -# define SSL_F_TLS1_CERT_VERIFY_MAC 286 -# define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 -# define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 -# define SSL_F_TLS1_ENC 210 -# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 -# define SSL_F_TLS1_GET_CURVELIST 338 -# define SSL_F_TLS1_HEARTBEAT 315 -# define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 -# define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 -# define SSL_F_TLS1_PRF 284 -# define SSL_F_TLS1_SETUP_KEY_BLOCK 211 -# define SSL_F_TLS1_SET_SERVER_SIGALGS 335 -# define SSL_F_WRITE_PENDING 212 - -/* Reason codes. */ -# define SSL_R_APP_DATA_IN_HANDSHAKE 100 -# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 -# define SSL_R_BAD_ALERT_RECORD 101 -# define SSL_R_BAD_AUTHENTICATION_TYPE 102 -# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 -# define SSL_R_BAD_CHECKSUM 104 -# define SSL_R_BAD_DATA 390 -# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 -# define SSL_R_BAD_DECOMPRESSION 107 -# define SSL_R_BAD_DH_G_LENGTH 108 -# define SSL_R_BAD_DH_G_VALUE 375 -# define SSL_R_BAD_DH_PUB_KEY_LENGTH 109 -# define SSL_R_BAD_DH_PUB_KEY_VALUE 393 -# define SSL_R_BAD_DH_P_LENGTH 110 -# define SSL_R_BAD_DH_P_VALUE 395 -# define SSL_R_BAD_DIGEST_LENGTH 111 -# define SSL_R_BAD_DSA_SIGNATURE 112 -# define SSL_R_BAD_ECC_CERT 304 -# define SSL_R_BAD_ECDSA_SIGNATURE 305 -# define SSL_R_BAD_ECPOINT 306 -# define SSL_R_BAD_HANDSHAKE_LENGTH 332 -# define SSL_R_BAD_HELLO_REQUEST 105 -# define SSL_R_BAD_LENGTH 271 -# define SSL_R_BAD_MAC_DECODE 113 -# define SSL_R_BAD_MAC_LENGTH 333 -# define SSL_R_BAD_MESSAGE_TYPE 114 -# define SSL_R_BAD_PACKET_LENGTH 115 -# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 -# define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH 316 -# define SSL_R_BAD_RESPONSE_ARGUMENT 117 -# define SSL_R_BAD_RSA_DECRYPT 118 -# define SSL_R_BAD_RSA_ENCRYPT 119 -# define SSL_R_BAD_RSA_E_LENGTH 120 -# define SSL_R_BAD_RSA_MODULUS_LENGTH 121 -# define SSL_R_BAD_RSA_SIGNATURE 122 -# define SSL_R_BAD_SIGNATURE 123 -# define SSL_R_BAD_SRP_A_LENGTH 347 -# define SSL_R_BAD_SRP_B_LENGTH 348 -# define SSL_R_BAD_SRP_G_LENGTH 349 -# define SSL_R_BAD_SRP_N_LENGTH 350 -# define SSL_R_BAD_SRP_PARAMETERS 371 -# define SSL_R_BAD_SRP_S_LENGTH 351 -# define SSL_R_BAD_SRTP_MKI_VALUE 352 -# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 -# define SSL_R_BAD_SSL_FILETYPE 124 -# define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 -# define SSL_R_BAD_STATE 126 -# define SSL_R_BAD_VALUE 384 -# define SSL_R_BAD_WRITE_RETRY 127 -# define SSL_R_BIO_NOT_SET 128 -# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 -# define SSL_R_BN_LIB 130 -# define SSL_R_CA_DN_LENGTH_MISMATCH 131 -# define SSL_R_CA_DN_TOO_LONG 132 -# define SSL_R_CCS_RECEIVED_EARLY 133 -# define SSL_R_CERTIFICATE_VERIFY_FAILED 134 -# define SSL_R_CERT_CB_ERROR 377 -# define SSL_R_CERT_LENGTH_MISMATCH 135 -# define SSL_R_CHALLENGE_IS_DIFFERENT 136 -# define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 -# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 -# define SSL_R_CIPHER_TABLE_SRC_ERROR 139 -# define SSL_R_CLIENTHELLO_TLSEXT 226 -# define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 -# define SSL_R_COMPRESSION_DISABLED 343 -# define SSL_R_COMPRESSION_FAILURE 141 -# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 -# define SSL_R_COMPRESSION_LIBRARY_ERROR 142 -# define SSL_R_CONNECTION_ID_IS_DIFFERENT 143 -# define SSL_R_CONNECTION_TYPE_NOT_SET 144 -# define SSL_R_COOKIE_MISMATCH 308 -# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 -# define SSL_R_DATA_LENGTH_TOO_LONG 146 -# define SSL_R_DECRYPTION_FAILED 147 -# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 -# define SSL_R_DH_KEY_TOO_SMALL 372 -# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 -# define SSL_R_DIGEST_CHECK_FAILED 149 -# define SSL_R_DTLS_MESSAGE_TOO_BIG 334 -# define SSL_R_DUPLICATE_COMPRESSION_ID 309 -# define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT 317 -# define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 -# define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322 -# define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323 -# define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE 374 -# define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310 -# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 -# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 -# define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282 -# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 -# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 -# define SSL_R_EXTRA_DATA_IN_MESSAGE 153 -# define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 -# define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355 -# define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356 -# define SSL_R_HTTPS_PROXY_REQUEST 155 -# define SSL_R_HTTP_REQUEST 156 -# define SSL_R_ILLEGAL_PADDING 283 -# define SSL_R_ILLEGAL_SUITEB_DIGEST 380 -# define SSL_R_INAPPROPRIATE_FALLBACK 373 -# define SSL_R_INCONSISTENT_COMPRESSION 340 -# define SSL_R_INVALID_CHALLENGE_LENGTH 158 -# define SSL_R_INVALID_COMMAND 280 -# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 -# define SSL_R_INVALID_NULL_CMD_NAME 385 -# define SSL_R_INVALID_PURPOSE 278 -# define SSL_R_INVALID_SERVERINFO_DATA 388 -# define SSL_R_INVALID_SRP_USERNAME 357 -# define SSL_R_INVALID_STATUS_RESPONSE 328 -# define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 -# define SSL_R_INVALID_TRUST 279 -# define SSL_R_KEY_ARG_TOO_LONG 284 -# define SSL_R_KRB5 285 -# define SSL_R_KRB5_C_CC_PRINC 286 -# define SSL_R_KRB5_C_GET_CRED 287 -# define SSL_R_KRB5_C_INIT 288 -# define SSL_R_KRB5_C_MK_REQ 289 -# define SSL_R_KRB5_S_BAD_TICKET 290 -# define SSL_R_KRB5_S_INIT 291 -# define SSL_R_KRB5_S_RD_REQ 292 -# define SSL_R_KRB5_S_TKT_EXPIRED 293 -# define SSL_R_KRB5_S_TKT_NYV 294 -# define SSL_R_KRB5_S_TKT_SKEW 295 -# define SSL_R_LENGTH_MISMATCH 159 -# define SSL_R_LENGTH_TOO_LONG 404 -# define SSL_R_LENGTH_TOO_SHORT 160 -# define SSL_R_LIBRARY_BUG 274 -# define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 -# define SSL_R_MESSAGE_TOO_LONG 296 -# define SSL_R_MISSING_DH_DSA_CERT 162 -# define SSL_R_MISSING_DH_KEY 163 -# define SSL_R_MISSING_DH_RSA_CERT 164 -# define SSL_R_MISSING_DSA_SIGNING_CERT 165 -# define SSL_R_MISSING_ECDH_CERT 382 -# define SSL_R_MISSING_ECDSA_SIGNING_CERT 381 -# define SSL_R_MISSING_EXPORT_TMP_DH_KEY 166 -# define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 167 -# define SSL_R_MISSING_RSA_CERTIFICATE 168 -# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 -# define SSL_R_MISSING_RSA_SIGNING_CERT 170 -# define SSL_R_MISSING_SRP_PARAM 358 -# define SSL_R_MISSING_TMP_DH_KEY 171 -# define SSL_R_MISSING_TMP_ECDH_KEY 311 -# define SSL_R_MISSING_TMP_RSA_KEY 172 -# define SSL_R_MISSING_TMP_RSA_PKEY 173 -# define SSL_R_MISSING_VERIFY_MESSAGE 174 -# define SSL_R_MULTIPLE_SGC_RESTARTS 346 -# define SSL_R_NON_SSLV2_INITIAL_PACKET 175 -# define SSL_R_NO_CERTIFICATES_RETURNED 176 -# define SSL_R_NO_CERTIFICATE_ASSIGNED 177 -# define SSL_R_NO_CERTIFICATE_RETURNED 178 -# define SSL_R_NO_CERTIFICATE_SET 179 -# define SSL_R_NO_CERTIFICATE_SPECIFIED 180 -# define SSL_R_NO_CIPHERS_AVAILABLE 181 -# define SSL_R_NO_CIPHERS_PASSED 182 -# define SSL_R_NO_CIPHERS_SPECIFIED 183 -# define SSL_R_NO_CIPHER_LIST 184 -# define SSL_R_NO_CIPHER_MATCH 185 -# define SSL_R_NO_CLIENT_CERT_METHOD 331 -# define SSL_R_NO_CLIENT_CERT_RECEIVED 186 -# define SSL_R_NO_COMPRESSION_SPECIFIED 187 -# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 -# define SSL_R_NO_METHOD_SPECIFIED 188 -# define SSL_R_NO_PEM_EXTENSIONS 389 -# define SSL_R_NO_PRIVATEKEY 189 -# define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 -# define SSL_R_NO_PROTOCOLS_AVAILABLE 191 -# define SSL_R_NO_PUBLICKEY 192 -# define SSL_R_NO_RENEGOTIATION 339 -# define SSL_R_NO_REQUIRED_DIGEST 324 -# define SSL_R_NO_SHARED_CIPHER 193 -# define SSL_R_NO_SHARED_SIGATURE_ALGORITHMS 376 -# define SSL_R_NO_SRTP_PROFILES 359 -# define SSL_R_NO_VERIFY_CALLBACK 194 -# define SSL_R_NULL_SSL_CTX 195 -# define SSL_R_NULL_SSL_METHOD_PASSED 196 -# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 -# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 -# define SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE 387 -# define SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE 379 -# define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 -# define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG 327 -# define SSL_R_PACKET_LENGTH_TOO_LONG 198 -# define SSL_R_PARSE_TLSEXT 227 -# define SSL_R_PATH_TOO_LONG 270 -# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 -# define SSL_R_PEER_ERROR 200 -# define SSL_R_PEER_ERROR_CERTIFICATE 201 -# define SSL_R_PEER_ERROR_NO_CERTIFICATE 202 -# define SSL_R_PEER_ERROR_NO_CIPHER 203 -# define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 204 -# define SSL_R_PEM_NAME_BAD_PREFIX 391 -# define SSL_R_PEM_NAME_TOO_SHORT 392 -# define SSL_R_PRE_MAC_LENGTH_TOO_LONG 205 -# define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 206 -# define SSL_R_PROTOCOL_IS_SHUTDOWN 207 -# define SSL_R_PSK_IDENTITY_NOT_FOUND 223 -# define SSL_R_PSK_NO_CLIENT_CB 224 -# define SSL_R_PSK_NO_SERVER_CB 225 -# define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 208 -# define SSL_R_PUBLIC_KEY_IS_NOT_RSA 209 -# define SSL_R_PUBLIC_KEY_NOT_RSA 210 -# define SSL_R_READ_BIO_NOT_SET 211 -# define SSL_R_READ_TIMEOUT_EXPIRED 312 -# define SSL_R_READ_WRONG_PACKET_TYPE 212 -# define SSL_R_RECORD_LENGTH_MISMATCH 213 -# define SSL_R_RECORD_TOO_LARGE 214 -# define SSL_R_RECORD_TOO_SMALL 298 -# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 -# define SSL_R_RENEGOTIATION_ENCODING_ERR 336 -# define SSL_R_RENEGOTIATION_MISMATCH 337 -# define SSL_R_REQUIRED_CIPHER_MISSING 215 -# define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING 342 -# define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 -# define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 -# define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 -# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 -# define SSL_R_SERVERHELLO_TLSEXT 275 -# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 -# define SSL_R_SHORT_READ 219 -# define SSL_R_SHUTDOWN_WHILE_IN_INIT 407 -# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 -# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 -# define SSL_R_SRP_A_CALC 361 -# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 -# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 -# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 -# define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 -# define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 -# define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 -# define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 -# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 -# define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 -# define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 -# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 -# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 -# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 -# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 -# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 -# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 -# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 -# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 -# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 -# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 -# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 -# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 -# define SSL_R_SSL_HANDSHAKE_FAILURE 229 -# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 -# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 -# define SSL_R_SSL_SESSION_ID_CONFLICT 302 -# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 -# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 -# define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 231 -# define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 -# define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 -# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 -# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 -# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 -# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 -# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 -# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 -# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 -# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 -# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 -# define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 -# define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 -# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 -# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 -# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 -# define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 -# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 -# define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 -# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 -# define SSL_R_TLS_HEARTBEAT_PENDING 366 -# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 -# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 -# define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 -# define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 -# define SSL_R_TOO_MANY_WARN_ALERTS 409 -# define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 -# define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236 -# define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313 -# define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 237 -# define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 238 -# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 -# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 -# define SSL_R_UNABLE_TO_FIND_SSL_METHOD 240 -# define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 241 -# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 -# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 -# define SSL_R_UNEXPECTED_MESSAGE 244 -# define SSL_R_UNEXPECTED_RECORD 245 -# define SSL_R_UNINITIALIZED 276 -# define SSL_R_UNKNOWN_ALERT_TYPE 246 -# define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 -# define SSL_R_UNKNOWN_CIPHER_RETURNED 248 -# define SSL_R_UNKNOWN_CIPHER_TYPE 249 -# define SSL_R_UNKNOWN_CMD_NAME 386 -# define SSL_R_UNKNOWN_DIGEST 368 -# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 -# define SSL_R_UNKNOWN_PKEY_TYPE 251 -# define SSL_R_UNKNOWN_PROTOCOL 252 -# define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 -# define SSL_R_UNKNOWN_SSL_VERSION 254 -# define SSL_R_UNKNOWN_STATE 255 -# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 -# define SSL_R_UNSUPPORTED_CIPHER 256 -# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 -# define SSL_R_UNSUPPORTED_DIGEST_TYPE 326 -# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 -# define SSL_R_UNSUPPORTED_PROTOCOL 258 -# define SSL_R_UNSUPPORTED_SSL_VERSION 259 -# define SSL_R_UNSUPPORTED_STATUS_TYPE 329 -# define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 -# define SSL_R_WRITE_BIO_NOT_SET 260 -# define SSL_R_WRONG_CERTIFICATE_TYPE 383 -# define SSL_R_WRONG_CIPHER_RETURNED 261 -# define SSL_R_WRONG_CURVE 378 -# define SSL_R_WRONG_MESSAGE_TYPE 262 -# define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263 -# define SSL_R_WRONG_SIGNATURE_LENGTH 264 -# define SSL_R_WRONG_SIGNATURE_SIZE 265 -# define SSL_R_WRONG_SIGNATURE_TYPE 370 -# define SSL_R_WRONG_SSL_VERSION 266 -# define SSL_R_WRONG_VERSION_NUMBER 267 -# define SSL_R_X509_LIB 268 -# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ssl2.h b/Sources/COpenSSL/ssl2.h deleted file mode 100644 index 03c7dd8c..00000000 --- a/Sources/COpenSSL/ssl2.h +++ /dev/null @@ -1,265 +0,0 @@ -/* ssl/ssl2.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_SSL2_H -# define HEADER_SSL2_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Protocol Version Codes */ -# define SSL2_VERSION 0x0002 -# define SSL2_VERSION_MAJOR 0x00 -# define SSL2_VERSION_MINOR 0x02 -/* #define SSL2_CLIENT_VERSION 0x0002 */ -/* #define SSL2_SERVER_VERSION 0x0002 */ - -/* Protocol Message Codes */ -# define SSL2_MT_ERROR 0 -# define SSL2_MT_CLIENT_HELLO 1 -# define SSL2_MT_CLIENT_MASTER_KEY 2 -# define SSL2_MT_CLIENT_FINISHED 3 -# define SSL2_MT_SERVER_HELLO 4 -# define SSL2_MT_SERVER_VERIFY 5 -# define SSL2_MT_SERVER_FINISHED 6 -# define SSL2_MT_REQUEST_CERTIFICATE 7 -# define SSL2_MT_CLIENT_CERTIFICATE 8 - -/* Error Message Codes */ -# define SSL2_PE_UNDEFINED_ERROR 0x0000 -# define SSL2_PE_NO_CIPHER 0x0001 -# define SSL2_PE_NO_CERTIFICATE 0x0002 -# define SSL2_PE_BAD_CERTIFICATE 0x0004 -# define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006 - -/* Cipher Kind Values */ -# define SSL2_CK_NULL_WITH_MD5 0x02000000/* v3 */ -# define SSL2_CK_RC4_128_WITH_MD5 0x02010080 -# define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080 -# define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080 -# define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080 -# define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080 -# define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040 -# define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140/* v3 */ -# define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0 -# define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0/* v3 */ -# define SSL2_CK_RC4_64_WITH_MD5 0x02080080/* MS hack */ - -# define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800/* SSLeay */ -# define SSL2_CK_NULL 0x02ff0810/* SSLeay */ - -# define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1" -# define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5" -# define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5" -# define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5" -# define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5" -# define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5" -# define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5" -# define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5" -# define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA" -# define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5" -# define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA" -# define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5" - -# define SSL2_TXT_NULL "NULL" - -/* Flags for the SSL_CIPHER.algorithm2 field */ -# define SSL2_CF_5_BYTE_ENC 0x01 -# define SSL2_CF_8_BYTE_ENC 0x02 - -/* Certificate Type Codes */ -# define SSL2_CT_X509_CERTIFICATE 0x01 - -/* Authentication Type Code */ -# define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01 - -# define SSL2_MAX_SSL_SESSION_ID_LENGTH 32 - -/* Upper/Lower Bounds */ -# define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256 -# ifdef OPENSSL_SYS_MPE -# define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 29998u -# else -# define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u - /* 2^15-1 */ -# endif -# define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383/* 2^14-1 */ - -# define SSL2_CHALLENGE_LENGTH 16 -/* - * #define SSL2_CHALLENGE_LENGTH 32 - */ -# define SSL2_MIN_CHALLENGE_LENGTH 16 -# define SSL2_MAX_CHALLENGE_LENGTH 32 -# define SSL2_CONNECTION_ID_LENGTH 16 -# define SSL2_MAX_CONNECTION_ID_LENGTH 16 -# define SSL2_SSL_SESSION_ID_LENGTH 16 -# define SSL2_MAX_CERT_CHALLENGE_LENGTH 32 -# define SSL2_MIN_CERT_CHALLENGE_LENGTH 16 -# define SSL2_MAX_KEY_MATERIAL_LENGTH 24 - -# ifndef HEADER_SSL_LOCL_H -# define CERT char -# endif - -# ifndef OPENSSL_NO_SSL_INTERN - -typedef struct ssl2_state_st { - int three_byte_header; - int clear_text; /* clear text */ - int escape; /* not used in SSLv2 */ - int ssl2_rollback; /* used if SSLv23 rolled back to SSLv2 */ - /* - * non-blocking io info, used to make sure the same args were passwd - */ - unsigned int wnum; /* number of bytes sent so far */ - int wpend_tot; - const unsigned char *wpend_buf; - int wpend_off; /* offset to data to write */ - int wpend_len; /* number of bytes passwd to write */ - int wpend_ret; /* number of bytes to return to caller */ - /* buffer raw data */ - int rbuf_left; - int rbuf_offs; - unsigned char *rbuf; - unsigned char *wbuf; - unsigned char *write_ptr; /* used to point to the start due to 2/3 byte - * header. */ - unsigned int padding; - unsigned int rlength; /* passed to ssl2_enc */ - int ract_data_length; /* Set when things are encrypted. */ - unsigned int wlength; /* passed to ssl2_enc */ - int wact_data_length; /* Set when things are decrypted. */ - unsigned char *ract_data; - unsigned char *wact_data; - unsigned char *mac_data; - unsigned char *read_key; - unsigned char *write_key; - /* Stuff specifically to do with this SSL session */ - unsigned int challenge_length; - unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH]; - unsigned int conn_id_length; - unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH]; - unsigned int key_material_length; - unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH * 2]; - unsigned long read_sequence; - unsigned long write_sequence; - struct { - unsigned int conn_id_length; - unsigned int cert_type; - unsigned int cert_length; - unsigned int csl; - unsigned int clear; - unsigned int enc; - unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH]; - unsigned int cipher_spec_length; - unsigned int session_id_length; - unsigned int clen; - unsigned int rlen; - } tmp; -} SSL2_STATE; - -# endif - -/* SSLv2 */ -/* client */ -# define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_HELLO_B (0x11|SSL_ST_CONNECT) -# define SSL2_ST_GET_SERVER_HELLO_A (0x20|SSL_ST_CONNECT) -# define SSL2_ST_GET_SERVER_HELLO_B (0x21|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_MASTER_KEY_A (0x30|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_MASTER_KEY_B (0x31|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_FINISHED_A (0x40|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_FINISHED_B (0x41|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_CERTIFICATE_A (0x50|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_CERTIFICATE_B (0x51|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_CERTIFICATE_C (0x52|SSL_ST_CONNECT) -# define SSL2_ST_SEND_CLIENT_CERTIFICATE_D (0x53|SSL_ST_CONNECT) -# define SSL2_ST_GET_SERVER_VERIFY_A (0x60|SSL_ST_CONNECT) -# define SSL2_ST_GET_SERVER_VERIFY_B (0x61|SSL_ST_CONNECT) -# define SSL2_ST_GET_SERVER_FINISHED_A (0x70|SSL_ST_CONNECT) -# define SSL2_ST_GET_SERVER_FINISHED_B (0x71|SSL_ST_CONNECT) -# define SSL2_ST_CLIENT_START_ENCRYPTION (0x80|SSL_ST_CONNECT) -# define SSL2_ST_X509_GET_CLIENT_CERTIFICATE (0x90|SSL_ST_CONNECT) -/* server */ -# define SSL2_ST_GET_CLIENT_HELLO_A (0x10|SSL_ST_ACCEPT) -# define SSL2_ST_GET_CLIENT_HELLO_B (0x11|SSL_ST_ACCEPT) -# define SSL2_ST_GET_CLIENT_HELLO_C (0x12|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_SERVER_HELLO_A (0x20|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_SERVER_HELLO_B (0x21|SSL_ST_ACCEPT) -# define SSL2_ST_GET_CLIENT_MASTER_KEY_A (0x30|SSL_ST_ACCEPT) -# define SSL2_ST_GET_CLIENT_MASTER_KEY_B (0x31|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_SERVER_VERIFY_A (0x40|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_SERVER_VERIFY_B (0x41|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_SERVER_VERIFY_C (0x42|SSL_ST_ACCEPT) -# define SSL2_ST_GET_CLIENT_FINISHED_A (0x50|SSL_ST_ACCEPT) -# define SSL2_ST_GET_CLIENT_FINISHED_B (0x51|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_SERVER_FINISHED_A (0x60|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_SERVER_FINISHED_B (0x61|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_REQUEST_CERTIFICATE_A (0x70|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_REQUEST_CERTIFICATE_B (0x71|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_REQUEST_CERTIFICATE_C (0x72|SSL_ST_ACCEPT) -# define SSL2_ST_SEND_REQUEST_CERTIFICATE_D (0x73|SSL_ST_ACCEPT) -# define SSL2_ST_SERVER_START_ENCRYPTION (0x80|SSL_ST_ACCEPT) -# define SSL2_ST_X509_GET_SERVER_CERTIFICATE (0x90|SSL_ST_ACCEPT) - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ssl23.h b/Sources/COpenSSL/ssl23.h deleted file mode 100644 index 9de4685a..00000000 --- a/Sources/COpenSSL/ssl23.h +++ /dev/null @@ -1,84 +0,0 @@ -/* ssl/ssl23.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_SSL23_H -# define HEADER_SSL23_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * client - */ -/* write to server */ -# define SSL23_ST_CW_CLNT_HELLO_A (0x210|SSL_ST_CONNECT) -# define SSL23_ST_CW_CLNT_HELLO_B (0x211|SSL_ST_CONNECT) -/* read from server */ -# define SSL23_ST_CR_SRVR_HELLO_A (0x220|SSL_ST_CONNECT) -# define SSL23_ST_CR_SRVR_HELLO_B (0x221|SSL_ST_CONNECT) - -/* server */ -/* read from client */ -# define SSL23_ST_SR_CLNT_HELLO_A (0x210|SSL_ST_ACCEPT) -# define SSL23_ST_SR_CLNT_HELLO_B (0x211|SSL_ST_ACCEPT) - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ssl3.h b/Sources/COpenSSL/ssl3.h deleted file mode 100644 index 328f72cd..00000000 --- a/Sources/COpenSSL/ssl3.h +++ /dev/null @@ -1,774 +0,0 @@ -/* ssl/ssl3.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#ifndef HEADER_SSL3_H -# define HEADER_SSL3_H - -# ifndef OPENSSL_NO_COMP -# include "comp.h" -# endif -# include "buffer.h" -# include "evp.h" -# include "ssl.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Signalling cipher suite value from RFC 5746 - * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) - */ -# define SSL3_CK_SCSV 0x030000FF - -/* - * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 - * (TLS_FALLBACK_SCSV) - */ -# define SSL3_CK_FALLBACK_SCSV 0x03005600 - -# define SSL3_CK_RSA_NULL_MD5 0x03000001 -# define SSL3_CK_RSA_NULL_SHA 0x03000002 -# define SSL3_CK_RSA_RC4_40_MD5 0x03000003 -# define SSL3_CK_RSA_RC4_128_MD5 0x03000004 -# define SSL3_CK_RSA_RC4_128_SHA 0x03000005 -# define SSL3_CK_RSA_RC2_40_MD5 0x03000006 -# define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 -# define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 -# define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 -# define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A - -# define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B -# define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C -# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D -# define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E -# define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F -# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 - -# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA 0x03000011 -# define SSL3_CK_DHE_DSS_DES_40_CBC_SHA SSL3_CK_EDH_DSS_DES_40_CBC_SHA -# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA 0x03000012 -# define SSL3_CK_DHE_DSS_DES_64_CBC_SHA SSL3_CK_EDH_DSS_DES_64_CBC_SHA -# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 -# define SSL3_CK_DHE_DSS_DES_192_CBC3_SHA SSL3_CK_EDH_DSS_DES_192_CBC3_SHA -# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 -# define SSL3_CK_DHE_RSA_DES_40_CBC_SHA SSL3_CK_EDH_RSA_DES_40_CBC_SHA -# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 -# define SSL3_CK_DHE_RSA_DES_64_CBC_SHA SSL3_CK_EDH_RSA_DES_64_CBC_SHA -# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 -# define SSL3_CK_DHE_RSA_DES_192_CBC3_SHA SSL3_CK_EDH_RSA_DES_192_CBC3_SHA - -# define SSL3_CK_ADH_RC4_40_MD5 0x03000017 -# define SSL3_CK_ADH_RC4_128_MD5 0x03000018 -# define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 -# define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A -# define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B - -# if 0 -# define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C -# define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D -# if 0 /* Because it clashes with KRB5, is never - * used any more, and is safe to remove - * according to David Hopwood - * of the - * ietf-tls list */ -# define SSL3_CK_FZA_DMS_RC4_SHA 0x0300001E -# endif -# endif - -/* - * VRS Additional Kerberos5 entries - */ -# define SSL3_CK_KRB5_DES_64_CBC_SHA 0x0300001E -# define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x0300001F -# define SSL3_CK_KRB5_RC4_128_SHA 0x03000020 -# define SSL3_CK_KRB5_IDEA_128_CBC_SHA 0x03000021 -# define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000022 -# define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000023 -# define SSL3_CK_KRB5_RC4_128_MD5 0x03000024 -# define SSL3_CK_KRB5_IDEA_128_CBC_MD5 0x03000025 - -# define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000026 -# define SSL3_CK_KRB5_RC2_40_CBC_SHA 0x03000027 -# define SSL3_CK_KRB5_RC4_40_SHA 0x03000028 -# define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000029 -# define SSL3_CK_KRB5_RC2_40_CBC_MD5 0x0300002A -# define SSL3_CK_KRB5_RC4_40_MD5 0x0300002B - -# define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" -# define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" -# define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" -# define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" -# define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" -# define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" -# define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" -# define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" -# define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" -# define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" - -# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" -# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" -# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" -# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" -# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" -# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" - -# define SSL3_TXT_DHE_DSS_DES_40_CBC_SHA "EXP-DHE-DSS-DES-CBC-SHA" -# define SSL3_TXT_DHE_DSS_DES_64_CBC_SHA "DHE-DSS-DES-CBC-SHA" -# define SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA "DHE-DSS-DES-CBC3-SHA" -# define SSL3_TXT_DHE_RSA_DES_40_CBC_SHA "EXP-DHE-RSA-DES-CBC-SHA" -# define SSL3_TXT_DHE_RSA_DES_64_CBC_SHA "DHE-RSA-DES-CBC-SHA" -# define SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA "DHE-RSA-DES-CBC3-SHA" - -/* - * This next block of six "EDH" labels is for backward compatibility with - * older versions of OpenSSL. New code should use the six "DHE" labels above - * instead: - */ -# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" -# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" -# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" -# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" -# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" -# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" - -# define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" -# define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" -# define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" -# define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" -# define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" - -# if 0 -# define SSL3_TXT_FZA_DMS_NULL_SHA "FZA-NULL-SHA" -# define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" -# define SSL3_TXT_FZA_DMS_RC4_SHA "FZA-RC4-SHA" -# endif - -# define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" -# define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" -# define SSL3_TXT_KRB5_RC4_128_SHA "KRB5-RC4-SHA" -# define SSL3_TXT_KRB5_IDEA_128_CBC_SHA "KRB5-IDEA-CBC-SHA" -# define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" -# define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" -# define SSL3_TXT_KRB5_RC4_128_MD5 "KRB5-RC4-MD5" -# define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 "KRB5-IDEA-CBC-MD5" - -# define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" -# define SSL3_TXT_KRB5_RC2_40_CBC_SHA "EXP-KRB5-RC2-CBC-SHA" -# define SSL3_TXT_KRB5_RC4_40_SHA "EXP-KRB5-RC4-SHA" -# define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" -# define SSL3_TXT_KRB5_RC2_40_CBC_MD5 "EXP-KRB5-RC2-CBC-MD5" -# define SSL3_TXT_KRB5_RC4_40_MD5 "EXP-KRB5-RC4-MD5" - -# define SSL3_SSL_SESSION_ID_LENGTH 32 -# define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 - -# define SSL3_MASTER_SECRET_SIZE 48 -# define SSL3_RANDOM_SIZE 32 -# define SSL3_SESSION_ID_SIZE 32 -# define SSL3_RT_HEADER_LENGTH 5 - -# define SSL3_HM_HEADER_LENGTH 4 - -# ifndef SSL3_ALIGN_PAYLOAD - /* - * Some will argue that this increases memory footprint, but it's not - * actually true. Point is that malloc has to return at least 64-bit aligned - * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case. - * Suggested pre-gaping simply moves these wasted bytes from the end of - * allocated region to its front, but makes data payload aligned, which - * improves performance:-) - */ -# define SSL3_ALIGN_PAYLOAD 8 -# else -# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 -# error "insane SSL3_ALIGN_PAYLOAD" -# undef SSL3_ALIGN_PAYLOAD -# endif -# endif - -/* - * This is the maximum MAC (digest) size used by the SSL library. Currently - * maximum of 20 is used by SHA1, but we reserve for future extension for - * 512-bit hashes. - */ - -# define SSL3_RT_MAX_MD_SIZE 64 - -/* - * Maximum block size used in all ciphersuites. Currently 16 for AES. - */ - -# define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 - -# define SSL3_RT_MAX_EXTRA (16384) - -/* Maximum plaintext length: defined by SSL/TLS standards */ -# define SSL3_RT_MAX_PLAIN_LENGTH 16384 -/* Maximum compression overhead: defined by SSL/TLS standards */ -# define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 - -/* - * The standards give a maximum encryption overhead of 1024 bytes. In - * practice the value is lower than this. The overhead is the maximum number - * of padding bytes (256) plus the mac size. - */ -# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) - -/* - * OpenSSL currently only uses a padding length of at most one block so the - * send overhead is smaller. - */ - -# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ - (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) - -/* If compression isn't used don't include the compression overhead */ - -# ifdef OPENSSL_NO_COMP -# define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH -# else -# define SSL3_RT_MAX_COMPRESSED_LENGTH \ - (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) -# endif -# define SSL3_RT_MAX_ENCRYPTED_LENGTH \ - (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) -# define SSL3_RT_MAX_PACKET_SIZE \ - (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) - -# define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" -# define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" - -# define SSL3_VERSION 0x0300 -# define SSL3_VERSION_MAJOR 0x03 -# define SSL3_VERSION_MINOR 0x00 - -# define SSL3_RT_CHANGE_CIPHER_SPEC 20 -# define SSL3_RT_ALERT 21 -# define SSL3_RT_HANDSHAKE 22 -# define SSL3_RT_APPLICATION_DATA 23 -# define TLS1_RT_HEARTBEAT 24 - -/* Pseudo content types to indicate additional parameters */ -# define TLS1_RT_CRYPTO 0x1000 -# define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1) -# define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2) -# define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3) -# define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4) - -# define TLS1_RT_CRYPTO_READ 0x0000 -# define TLS1_RT_CRYPTO_WRITE 0x0100 -# define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5) -# define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6) -# define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7) -# define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8) - -/* Pseudo content type for SSL/TLS header info */ -# define SSL3_RT_HEADER 0x100 - -# define SSL3_AL_WARNING 1 -# define SSL3_AL_FATAL 2 - -# define SSL3_AD_CLOSE_NOTIFY 0 -# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ -# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ -# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ -# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ -# define SSL3_AD_NO_CERTIFICATE 41 -# define SSL3_AD_BAD_CERTIFICATE 42 -# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 -# define SSL3_AD_CERTIFICATE_REVOKED 44 -# define SSL3_AD_CERTIFICATE_EXPIRED 45 -# define SSL3_AD_CERTIFICATE_UNKNOWN 46 -# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ - -# define TLS1_HB_REQUEST 1 -# define TLS1_HB_RESPONSE 2 - -# ifndef OPENSSL_NO_SSL_INTERN - -typedef struct ssl3_record_st { - /* type of record */ - /* - * r - */ int type; - /* How many bytes available */ - /* - * rw - */ unsigned int length; - /* read/write offset into 'buf' */ - /* - * r - */ unsigned int off; - /* pointer to the record data */ - /* - * rw - */ unsigned char *data; - /* where the decode bytes are */ - /* - * rw - */ unsigned char *input; - /* only used with decompression - malloc()ed */ - /* - * r - */ unsigned char *comp; - /* epoch number, needed by DTLS1 */ - /* - * r - */ unsigned long epoch; - /* sequence number, needed by DTLS1 */ - /* - * r - */ unsigned char seq_num[8]; -} SSL3_RECORD; - -typedef struct ssl3_buffer_st { - /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */ - unsigned char *buf; - /* buffer size */ - size_t len; - /* where to 'copy from' */ - int offset; - /* how many bytes left */ - int left; -} SSL3_BUFFER; - -# endif - -# define SSL3_CT_RSA_SIGN 1 -# define SSL3_CT_DSS_SIGN 2 -# define SSL3_CT_RSA_FIXED_DH 3 -# define SSL3_CT_DSS_FIXED_DH 4 -# define SSL3_CT_RSA_EPHEMERAL_DH 5 -# define SSL3_CT_DSS_EPHEMERAL_DH 6 -# define SSL3_CT_FORTEZZA_DMS 20 -/* - * SSL3_CT_NUMBER is used to size arrays and it must be large enough to - * contain all of the cert types defined either for SSLv3 and TLSv1. - */ -# define SSL3_CT_NUMBER 9 - -# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 -# define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 -# define SSL3_FLAGS_POP_BUFFER 0x0004 -# define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 -# define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 -# define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 -/* - * Set when the handshake is ready to process peer's ChangeCipherSpec message. - * Cleared after the message has been processed. - */ -# define SSL3_FLAGS_CCS_OK 0x0080 - -/* SSL3_FLAGS_SGC_RESTART_DONE is no longer used */ -# define SSL3_FLAGS_SGC_RESTART_DONE 0x0040 - -# ifndef OPENSSL_NO_SSL_INTERN - -typedef struct ssl3_state_st { - long flags; - int delay_buf_pop_ret; - unsigned char read_sequence[8]; - int read_mac_secret_size; - unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; - unsigned char write_sequence[8]; - int write_mac_secret_size; - unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; - unsigned char server_random[SSL3_RANDOM_SIZE]; - unsigned char client_random[SSL3_RANDOM_SIZE]; - /* flags for countermeasure against known-IV weakness */ - int need_empty_fragments; - int empty_fragment_done; - /* The value of 'extra' when the buffers were initialized */ - int init_extra; - SSL3_BUFFER rbuf; /* read IO goes into here */ - SSL3_BUFFER wbuf; /* write IO goes into here */ - SSL3_RECORD rrec; /* each decoded record goes in here */ - SSL3_RECORD wrec; /* goes out from here */ - /* - * storage for Alert/Handshake protocol data received but not yet - * processed by ssl3_read_bytes: - */ - unsigned char alert_fragment[2]; - unsigned int alert_fragment_len; - unsigned char handshake_fragment[4]; - unsigned int handshake_fragment_len; - /* partial write - check the numbers match */ - unsigned int wnum; /* number of bytes sent so far */ - int wpend_tot; /* number bytes written */ - int wpend_type; - int wpend_ret; /* number of bytes submitted */ - const unsigned char *wpend_buf; - /* used during startup, digest all incoming/outgoing packets */ - BIO *handshake_buffer; - /* - * When set of handshake digests is determined, buffer is hashed and - * freed and MD_CTX-es for all required digests are stored in this array - */ - EVP_MD_CTX **handshake_dgst; - /* - * Set whenever an expected ChangeCipherSpec message is processed. - * Unset when the peer's Finished message is received. - * Unexpected ChangeCipherSpec messages trigger a fatal alert. - */ - int change_cipher_spec; - int warn_alert; - int fatal_alert; - /* - * we allow one fatal and one warning alert to be outstanding, send close - * alert via the warning alert - */ - int alert_dispatch; - unsigned char send_alert[2]; - /* - * This flag is set when we should renegotiate ASAP, basically when there - * is no more data in the read or write buffers - */ - int renegotiate; - int total_renegotiations; - int num_renegotiations; - int in_read_app_data; - /* - * Opaque PRF input as used for the current handshake. These fields are - * used only if TLSEXT_TYPE_opaque_prf_input is defined (otherwise, they - * are merely present to improve binary compatibility) - */ - void *client_opaque_prf_input; - size_t client_opaque_prf_input_len; - void *server_opaque_prf_input; - size_t server_opaque_prf_input_len; - struct { - /* actually only needs to be 16+20 */ - unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2]; - /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ - unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; - int finish_md_len; - unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2]; - int peer_finish_md_len; - unsigned long message_size; - int message_type; - /* used to hold the new cipher we are going to use */ - const SSL_CIPHER *new_cipher; -# ifndef OPENSSL_NO_DH - DH *dh; -# endif -# ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh; /* holds short lived ECDH key */ -# endif - /* used when SSL_ST_FLUSH_DATA is entered */ - int next_state; - int reuse_message; - /* used for certificate requests */ - int cert_req; - int ctype_num; - char ctype[SSL3_CT_NUMBER]; - STACK_OF(X509_NAME) *ca_names; - int use_rsa_tmp; - int key_block_length; - unsigned char *key_block; - const EVP_CIPHER *new_sym_enc; - const EVP_MD *new_hash; - int new_mac_pkey_type; - int new_mac_secret_size; -# ifndef OPENSSL_NO_COMP - const SSL_COMP *new_compression; -# else - char *new_compression; -# endif - int cert_request; - } tmp; - - /* Connection binding to prevent renegotiation attacks */ - unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; - unsigned char previous_client_finished_len; - unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; - unsigned char previous_server_finished_len; - int send_connection_binding; /* TODOEKR */ - -# ifndef OPENSSL_NO_NEXTPROTONEG - /* - * Set if we saw the Next Protocol Negotiation extension from our peer. - */ - int next_proto_neg_seen; -# endif - -# ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC - /* - * This is set to true if we believe that this is a version of Safari - * running on OS X 10.6 or newer. We wish to know this because Safari on - * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. - */ - char is_probably_safari; -# endif /* !OPENSSL_NO_EC */ - - /* - * ALPN information (we are in the process of transitioning from NPN to - * ALPN.) - */ - - /* - * In a server these point to the selected ALPN protocol after the - * ClientHello has been processed. In a client these contain the protocol - * that the server selected once the ServerHello has been processed. - */ - unsigned char *alpn_selected; - unsigned alpn_selected_len; -# endif /* OPENSSL_NO_TLSEXT */ -} SSL3_STATE; - -# endif - -/* SSLv3 */ -/* - * client - */ -/* extra state */ -# define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT) -# ifndef OPENSSL_NO_SCTP -# define DTLS1_SCTP_ST_CW_WRITE_SOCK (0x310|SSL_ST_CONNECT) -# define DTLS1_SCTP_ST_CR_READ_SOCK (0x320|SSL_ST_CONNECT) -# endif -/* write to server */ -# define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT) -# define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT) -/* read from server */ -# define SSL3_ST_CR_SRVR_HELLO_A (0x120|SSL_ST_CONNECT) -# define SSL3_ST_CR_SRVR_HELLO_B (0x121|SSL_ST_CONNECT) -# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT) -# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT) -# define SSL3_ST_CR_CERT_A (0x130|SSL_ST_CONNECT) -# define SSL3_ST_CR_CERT_B (0x131|SSL_ST_CONNECT) -# define SSL3_ST_CR_KEY_EXCH_A (0x140|SSL_ST_CONNECT) -# define SSL3_ST_CR_KEY_EXCH_B (0x141|SSL_ST_CONNECT) -# define SSL3_ST_CR_CERT_REQ_A (0x150|SSL_ST_CONNECT) -# define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT) -# define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT) -# define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT) -/* write to server */ -# define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) -# define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT) -# define SSL3_ST_CW_CERT_C (0x172|SSL_ST_CONNECT) -# define SSL3_ST_CW_CERT_D (0x173|SSL_ST_CONNECT) -# define SSL3_ST_CW_KEY_EXCH_A (0x180|SSL_ST_CONNECT) -# define SSL3_ST_CW_KEY_EXCH_B (0x181|SSL_ST_CONNECT) -# define SSL3_ST_CW_CERT_VRFY_A (0x190|SSL_ST_CONNECT) -# define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT) -# define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT) -# define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT) -# ifndef OPENSSL_NO_NEXTPROTONEG -# define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT) -# define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT) -# endif -# define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) -# define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT) -/* read from server */ -# define SSL3_ST_CR_CHANGE_A (0x1C0|SSL_ST_CONNECT) -# define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT) -# define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT) -# define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT) -# define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT) -# define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT) -# define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT) -# define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT) - -/* server */ -/* extra state */ -# define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT) -# ifndef OPENSSL_NO_SCTP -# define DTLS1_SCTP_ST_SW_WRITE_SOCK (0x310|SSL_ST_ACCEPT) -# define DTLS1_SCTP_ST_SR_READ_SOCK (0x320|SSL_ST_ACCEPT) -# endif -/* read from client */ -/* Do not change the number values, they do matter */ -# define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) -# define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) -# define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) -# define SSL3_ST_SR_CLNT_HELLO_D (0x115|SSL_ST_ACCEPT) -/* write to client */ -# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) -# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT) -# define SSL3_ST_SW_HELLO_REQ_A (0x120|SSL_ST_ACCEPT) -# define SSL3_ST_SW_HELLO_REQ_B (0x121|SSL_ST_ACCEPT) -# define SSL3_ST_SW_HELLO_REQ_C (0x122|SSL_ST_ACCEPT) -# define SSL3_ST_SW_SRVR_HELLO_A (0x130|SSL_ST_ACCEPT) -# define SSL3_ST_SW_SRVR_HELLO_B (0x131|SSL_ST_ACCEPT) -# define SSL3_ST_SW_CERT_A (0x140|SSL_ST_ACCEPT) -# define SSL3_ST_SW_CERT_B (0x141|SSL_ST_ACCEPT) -# define SSL3_ST_SW_KEY_EXCH_A (0x150|SSL_ST_ACCEPT) -# define SSL3_ST_SW_KEY_EXCH_B (0x151|SSL_ST_ACCEPT) -# define SSL3_ST_SW_CERT_REQ_A (0x160|SSL_ST_ACCEPT) -# define SSL3_ST_SW_CERT_REQ_B (0x161|SSL_ST_ACCEPT) -# define SSL3_ST_SW_SRVR_DONE_A (0x170|SSL_ST_ACCEPT) -# define SSL3_ST_SW_SRVR_DONE_B (0x171|SSL_ST_ACCEPT) -/* read from client */ -# define SSL3_ST_SR_CERT_A (0x180|SSL_ST_ACCEPT) -# define SSL3_ST_SR_CERT_B (0x181|SSL_ST_ACCEPT) -# define SSL3_ST_SR_KEY_EXCH_A (0x190|SSL_ST_ACCEPT) -# define SSL3_ST_SR_KEY_EXCH_B (0x191|SSL_ST_ACCEPT) -# define SSL3_ST_SR_CERT_VRFY_A (0x1A0|SSL_ST_ACCEPT) -# define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT) -# define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT) -# define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT) -# ifndef OPENSSL_NO_NEXTPROTONEG -# define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT) -# define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT) -# endif -# define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT) -# define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT) -/* write to client */ -# define SSL3_ST_SW_CHANGE_A (0x1D0|SSL_ST_ACCEPT) -# define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT) -# define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) -# define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) -# define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_ACCEPT) -# define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) -# define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT) -# define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT) - -# define SSL3_MT_HELLO_REQUEST 0 -# define SSL3_MT_CLIENT_HELLO 1 -# define SSL3_MT_SERVER_HELLO 2 -# define SSL3_MT_NEWSESSION_TICKET 4 -# define SSL3_MT_CERTIFICATE 11 -# define SSL3_MT_SERVER_KEY_EXCHANGE 12 -# define SSL3_MT_CERTIFICATE_REQUEST 13 -# define SSL3_MT_SERVER_DONE 14 -# define SSL3_MT_CERTIFICATE_VERIFY 15 -# define SSL3_MT_CLIENT_KEY_EXCHANGE 16 -# define SSL3_MT_FINISHED 20 -# define SSL3_MT_CERTIFICATE_STATUS 22 -# ifndef OPENSSL_NO_NEXTPROTONEG -# define SSL3_MT_NEXT_PROTO 67 -# endif -# define DTLS1_MT_HELLO_VERIFY_REQUEST 3 - -# define SSL3_MT_CCS 1 - -/* These are used when changing over to a new cipher */ -# define SSL3_CC_READ 0x01 -# define SSL3_CC_WRITE 0x02 -# define SSL3_CC_CLIENT 0x10 -# define SSL3_CC_SERVER 0x20 -# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) -# define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) -# define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) -# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ssl_.c b/Sources/COpenSSL/ssl_.c deleted file mode 100644 index 8e765126..00000000 --- a/Sources/COpenSSL/ssl_.c +++ /dev/null @@ -1,13101 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ssl/ssl_algs.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "objects.h" -#include "lhash.h" -#include "ssl_locl.h" - -int SSL_library_init(void) -{ - -#ifndef OPENSSL_NO_DES - EVP_add_cipher(EVP_des_cbc()); - EVP_add_cipher(EVP_des_ede3_cbc()); -#endif -#ifndef OPENSSL_NO_IDEA - EVP_add_cipher(EVP_idea_cbc()); -#endif -#ifndef OPENSSL_NO_RC4 - EVP_add_cipher(EVP_rc4()); -# if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) - EVP_add_cipher(EVP_rc4_hmac_md5()); -# endif -#endif -#ifndef OPENSSL_NO_RC2 - EVP_add_cipher(EVP_rc2_cbc()); - /* - * Not actually used for SSL/TLS but this makes PKCS#12 work if an - * application only calls SSL_library_init(). - */ - EVP_add_cipher(EVP_rc2_40_cbc()); -#endif -#ifndef OPENSSL_NO_AES - EVP_add_cipher(EVP_aes_128_cbc()); - EVP_add_cipher(EVP_aes_192_cbc()); - EVP_add_cipher(EVP_aes_256_cbc()); - EVP_add_cipher(EVP_aes_128_gcm()); - EVP_add_cipher(EVP_aes_256_gcm()); -# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) - EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); - EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); -# endif -# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) - EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256()); - EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256()); -# endif - -#endif -#ifndef OPENSSL_NO_CAMELLIA - EVP_add_cipher(EVP_camellia_128_cbc()); - EVP_add_cipher(EVP_camellia_256_cbc()); -#endif - -#ifndef OPENSSL_NO_SEED - EVP_add_cipher(EVP_seed_cbc()); -#endif - -#ifndef OPENSSL_NO_MD5 - EVP_add_digest(EVP_md5()); - EVP_add_digest_alias(SN_md5, "ssl2-md5"); - EVP_add_digest_alias(SN_md5, "ssl3-md5"); -#endif -#ifndef OPENSSL_NO_SHA - EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ - EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); - EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); -#endif -#ifndef OPENSSL_NO_SHA256 - EVP_add_digest(EVP_sha224()); - EVP_add_digest(EVP_sha256()); -#endif -#ifndef OPENSSL_NO_SHA512 - EVP_add_digest(EVP_sha384()); - EVP_add_digest(EVP_sha512()); -#endif -#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) - EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ - EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); - EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); - EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); -#endif -#ifndef OPENSSL_NO_ECDSA - EVP_add_digest(EVP_ecdsa()); -#endif - /* If you want support for phased out ciphers, add the following */ -#if 0 - EVP_add_digest(EVP_sha()); - EVP_add_digest(EVP_dss()); -#endif -#ifndef OPENSSL_NO_COMP - /* - * This will initialise the built-in compression algorithms. The value - * returned is a STACK_OF(SSL_COMP), but that can be discarded safely - */ - (void)SSL_COMP_get_compression_methods(); -#endif - /* initialize cipher/digest methods table */ - ssl_load_ciphers(); - return (1); -} -/* ssl/ssl_asn1.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -#include -// #include "ssl_locl.h" -#include "asn1_mac.h" -// #include "objects.h" -#include "x509.h" - -typedef struct ssl_session_asn1_st { - ASN1_INTEGER version; - ASN1_INTEGER ssl_version; - ASN1_OCTET_STRING cipher; - ASN1_OCTET_STRING comp_id; - ASN1_OCTET_STRING master_key; - ASN1_OCTET_STRING session_id; - ASN1_OCTET_STRING session_id_context; - ASN1_OCTET_STRING key_arg; -#ifndef OPENSSL_NO_KRB5 - ASN1_OCTET_STRING krb5_princ; -#endif /* OPENSSL_NO_KRB5 */ - ASN1_INTEGER time; - ASN1_INTEGER timeout; - ASN1_INTEGER verify_result; -#ifndef OPENSSL_NO_TLSEXT - ASN1_OCTET_STRING tlsext_hostname; - ASN1_INTEGER tlsext_tick_lifetime; - ASN1_OCTET_STRING tlsext_tick; -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_PSK - ASN1_OCTET_STRING psk_identity_hint; - ASN1_OCTET_STRING psk_identity; -#endif /* OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - ASN1_OCTET_STRING srp_username; -#endif /* OPENSSL_NO_SRP */ -} SSL_SESSION_ASN1; - -int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) -{ -#define LSIZE2 (sizeof(long)*2) - int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0; - unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2]; - unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2]; -#ifndef OPENSSL_NO_TLSEXT - int v6 = 0, v9 = 0, v10 = 0; - unsigned char ibuf6[LSIZE2]; -#endif -#ifndef OPENSSL_NO_PSK - int v7 = 0, v8 = 0; -#endif -#ifndef OPENSSL_NO_COMP - unsigned char cbuf; - int v11 = 0; -#endif -#ifndef OPENSSL_NO_SRP - int v12 = 0; -#endif - long l; - SSL_SESSION_ASN1 a; - M_ASN1_I2D_vars(in); - - if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0))) - return (0); - - /* - * Note that I cheat in the following 2 assignments. I know that if the - * ASN1_INTEGER passed to ASN1_INTEGER_set is > sizeof(long)+1, the - * buffer will not be re-OPENSSL_malloc()ed. This is a bit evil but makes - * things simple, no dynamic allocation to clean up :-) - */ - a.version.length = LSIZE2; - a.version.type = V_ASN1_INTEGER; - a.version.data = ibuf1; - ASN1_INTEGER_set(&(a.version), SSL_SESSION_ASN1_VERSION); - - a.ssl_version.length = LSIZE2; - a.ssl_version.type = V_ASN1_INTEGER; - a.ssl_version.data = ibuf2; - ASN1_INTEGER_set(&(a.ssl_version), in->ssl_version); - - a.cipher.type = V_ASN1_OCTET_STRING; - a.cipher.data = buf; - - if (in->cipher == NULL) - l = in->cipher_id; - else - l = in->cipher->id; - if (in->ssl_version == SSL2_VERSION) { - a.cipher.length = 3; - buf[0] = ((unsigned char)(l >> 16L)) & 0xff; - buf[1] = ((unsigned char)(l >> 8L)) & 0xff; - buf[2] = ((unsigned char)(l)) & 0xff; - } else { - a.cipher.length = 2; - buf[0] = ((unsigned char)(l >> 8L)) & 0xff; - buf[1] = ((unsigned char)(l)) & 0xff; - } - -#ifndef OPENSSL_NO_COMP - if (in->compress_meth) { - cbuf = (unsigned char)in->compress_meth; - a.comp_id.length = 1; - a.comp_id.type = V_ASN1_OCTET_STRING; - a.comp_id.data = &cbuf; - } -#endif - - a.master_key.length = in->master_key_length; - a.master_key.type = V_ASN1_OCTET_STRING; - a.master_key.data = in->master_key; - - a.session_id.length = in->session_id_length; - a.session_id.type = V_ASN1_OCTET_STRING; - a.session_id.data = in->session_id; - - a.session_id_context.length = in->sid_ctx_length; - a.session_id_context.type = V_ASN1_OCTET_STRING; - a.session_id_context.data = in->sid_ctx; - - a.key_arg.length = in->key_arg_length; - a.key_arg.type = V_ASN1_OCTET_STRING; - a.key_arg.data = in->key_arg; - -#ifndef OPENSSL_NO_KRB5 - if (in->krb5_client_princ_len) { - a.krb5_princ.length = in->krb5_client_princ_len; - a.krb5_princ.type = V_ASN1_OCTET_STRING; - a.krb5_princ.data = in->krb5_client_princ; - } -#endif /* OPENSSL_NO_KRB5 */ - - if (in->time != 0L) { - a.time.length = LSIZE2; - a.time.type = V_ASN1_INTEGER; - a.time.data = ibuf3; - ASN1_INTEGER_set(&(a.time), in->time); - } - - if (in->timeout != 0L) { - a.timeout.length = LSIZE2; - a.timeout.type = V_ASN1_INTEGER; - a.timeout.data = ibuf4; - ASN1_INTEGER_set(&(a.timeout), in->timeout); - } - - if (in->verify_result != X509_V_OK) { - a.verify_result.length = LSIZE2; - a.verify_result.type = V_ASN1_INTEGER; - a.verify_result.data = ibuf5; - ASN1_INTEGER_set(&a.verify_result, in->verify_result); - } -#ifndef OPENSSL_NO_TLSEXT - if (in->tlsext_hostname) { - a.tlsext_hostname.length = strlen(in->tlsext_hostname); - a.tlsext_hostname.type = V_ASN1_OCTET_STRING; - a.tlsext_hostname.data = (unsigned char *)in->tlsext_hostname; - } - if (in->tlsext_tick) { - a.tlsext_tick.length = in->tlsext_ticklen; - a.tlsext_tick.type = V_ASN1_OCTET_STRING; - a.tlsext_tick.data = (unsigned char *)in->tlsext_tick; - } - if (in->tlsext_tick_lifetime_hint > 0) { - a.tlsext_tick_lifetime.length = LSIZE2; - a.tlsext_tick_lifetime.type = V_ASN1_INTEGER; - a.tlsext_tick_lifetime.data = ibuf6; - ASN1_INTEGER_set(&a.tlsext_tick_lifetime, - in->tlsext_tick_lifetime_hint); - } -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_PSK - if (in->psk_identity_hint) { - a.psk_identity_hint.length = strlen(in->psk_identity_hint); - a.psk_identity_hint.type = V_ASN1_OCTET_STRING; - a.psk_identity_hint.data = (unsigned char *)(in->psk_identity_hint); - } - if (in->psk_identity) { - a.psk_identity.length = strlen(in->psk_identity); - a.psk_identity.type = V_ASN1_OCTET_STRING; - a.psk_identity.data = (unsigned char *)(in->psk_identity); - } -#endif /* OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - if (in->srp_username) { - a.srp_username.length = strlen(in->srp_username); - a.srp_username.type = V_ASN1_OCTET_STRING; - a.srp_username.data = (unsigned char *)(in->srp_username); - } -#endif /* OPENSSL_NO_SRP */ - - M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); - M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); - M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING); -#ifndef OPENSSL_NO_KRB5 - if (in->krb5_client_princ_len) - M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); -#endif /* OPENSSL_NO_KRB5 */ - if (in->key_arg_length > 0) - M_ASN1_I2D_len_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING); - if (in->time != 0L) - M_ASN1_I2D_len_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1); - if (in->timeout != 0L) - M_ASN1_I2D_len_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2); - if (in->peer != NULL) - M_ASN1_I2D_len_EXP_opt(in->peer, i2d_X509, 3, v3); - M_ASN1_I2D_len_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4, - v4); - if (in->verify_result != X509_V_OK) - M_ASN1_I2D_len_EXP_opt(&(a.verify_result), i2d_ASN1_INTEGER, 5, v5); - -#ifndef OPENSSL_NO_TLSEXT - if (in->tlsext_tick_lifetime_hint > 0) - M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9, - v9); - if (in->tlsext_tick) - M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10, - v10); - if (in->tlsext_hostname) - M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6, - v6); -# ifndef OPENSSL_NO_COMP - if (in->compress_meth) - M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11); -# endif -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_PSK - if (in->psk_identity_hint) - M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING, - 7, v7); - if (in->psk_identity) - M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8, - v8); -#endif /* OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_SRP - if (in->srp_username) - M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12, - v12); -#endif /* OPENSSL_NO_SRP */ - - M_ASN1_I2D_seq_total(); - - M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER); - M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER); - M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING); - M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING); -#ifndef OPENSSL_NO_KRB5 - if (in->krb5_client_princ_len) - M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); -#endif /* OPENSSL_NO_KRB5 */ - if (in->key_arg_length > 0) - M_ASN1_I2D_put_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING, 0); - if (in->time != 0L) - M_ASN1_I2D_put_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1); - if (in->timeout != 0L) - M_ASN1_I2D_put_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2); - if (in->peer != NULL) - M_ASN1_I2D_put_EXP_opt(in->peer, i2d_X509, 3, v3); - M_ASN1_I2D_put_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4, - v4); - if (in->verify_result != X509_V_OK) - M_ASN1_I2D_put_EXP_opt(&a.verify_result, i2d_ASN1_INTEGER, 5, v5); -#ifndef OPENSSL_NO_TLSEXT - if (in->tlsext_hostname) - M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6, - v6); -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_PSK - if (in->psk_identity_hint) - M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING, - 7, v7); - if (in->psk_identity) - M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8, - v8); -#endif /* OPENSSL_NO_PSK */ -#ifndef OPENSSL_NO_TLSEXT - if (in->tlsext_tick_lifetime_hint > 0) - M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9, - v9); - if (in->tlsext_tick) - M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10, - v10); -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_COMP - if (in->compress_meth) - M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11); -#endif -#ifndef OPENSSL_NO_SRP - if (in->srp_username) - M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12, - v12); -#endif /* OPENSSL_NO_SRP */ - M_ASN1_I2D_finish(); -} - -SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, - long length) -{ - int ssl_version = 0, i; - long id; - ASN1_INTEGER ai, *aip; - ASN1_OCTET_STRING os, *osp; - M_ASN1_D2I_vars(a, SSL_SESSION *, SSL_SESSION_new); - - aip = &ai; - osp = &os; - - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - - ai.data = NULL; - ai.length = 0; - M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); - if (ai.data != NULL) { - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } - - /* we don't care about the version right now :-) */ - M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); - ssl_version = (int)ASN1_INTEGER_get(aip); - ret->ssl_version = ssl_version; - if (ai.data != NULL) { - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } - - os.data = NULL; - os.length = 0; - M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); - if (ssl_version == SSL2_VERSION) { - if (os.length != 3) { - c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; - c.line = __LINE__; - goto err; - } - id = 0x02000000L | - ((unsigned long)os.data[0] << 16L) | - ((unsigned long)os.data[1] << 8L) | (unsigned long)os.data[2]; - } else if ((ssl_version >> 8) == SSL3_VERSION_MAJOR - || (ssl_version >> 8) == DTLS1_VERSION_MAJOR - || ssl_version == DTLS1_BAD_VER) { - if (os.length != 2) { - c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; - c.line = __LINE__; - goto err; - } - id = 0x03000000L | - ((unsigned long)os.data[0] << 8L) | (unsigned long)os.data[1]; - } else { - c.error = SSL_R_UNKNOWN_SSL_VERSION; - c.line = __LINE__; - goto err; - } - - ret->cipher = NULL; - ret->cipher_id = id; - - M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); - if ((ssl_version >> 8) >= SSL3_VERSION_MAJOR) - i = SSL3_MAX_SSL_SESSION_ID_LENGTH; - else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */ - i = SSL2_MAX_SSL_SESSION_ID_LENGTH; - - if (os.length > i) - os.length = i; - if (os.length > (int)sizeof(ret->session_id)) /* can't happen */ - os.length = sizeof(ret->session_id); - - ret->session_id_length = os.length; - OPENSSL_assert(os.length <= (int)sizeof(ret->session_id)); - memcpy(ret->session_id, os.data, os.length); - - M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); - if (os.length > SSL_MAX_MASTER_KEY_LENGTH) - ret->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; - else - ret->master_key_length = os.length; - memcpy(ret->master_key, os.data, ret->master_key_length); - - os.length = 0; - -#ifndef OPENSSL_NO_KRB5 - os.length = 0; - M_ASN1_D2I_get_opt(osp, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING); - if (os.data) { - if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH) - ret->krb5_client_princ_len = 0; - else - ret->krb5_client_princ_len = os.length; - memcpy(ret->krb5_client_princ, os.data, ret->krb5_client_princ_len); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->krb5_client_princ_len = 0; -#endif /* OPENSSL_NO_KRB5 */ - - M_ASN1_D2I_get_IMP_opt(osp, d2i_ASN1_OCTET_STRING, 0, - V_ASN1_OCTET_STRING); - if (os.length > SSL_MAX_KEY_ARG_LENGTH) - ret->key_arg_length = SSL_MAX_KEY_ARG_LENGTH; - else - ret->key_arg_length = os.length; - memcpy(ret->key_arg, os.data, ret->key_arg_length); - if (os.data != NULL) - OPENSSL_free(os.data); - - ai.length = 0; - M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 1); - if (ai.data != NULL) { - ret->time = ASN1_INTEGER_get(aip); - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } else - ret->time = (unsigned long)time(NULL); - - ai.length = 0; - M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 2); - if (ai.data != NULL) { - ret->timeout = ASN1_INTEGER_get(aip); - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } else - ret->timeout = 3; - - if (ret->peer != NULL) { - X509_free(ret->peer); - ret->peer = NULL; - } - M_ASN1_D2I_get_EXP_opt(ret->peer, d2i_X509, 3); - - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 4); - - if (os.data != NULL) { - if (os.length > SSL_MAX_SID_CTX_LENGTH) { - c.error = SSL_R_BAD_LENGTH; - c.line = __LINE__; - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - goto err; - } else { - ret->sid_ctx_length = os.length; - memcpy(ret->sid_ctx, os.data, os.length); - } - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->sid_ctx_length = 0; - - ai.length = 0; - M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 5); - if (ai.data != NULL) { - ret->verify_result = ASN1_INTEGER_get(aip); - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } else - ret->verify_result = X509_V_OK; - -#ifndef OPENSSL_NO_TLSEXT - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 6); - if (os.data) { - ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->tlsext_hostname = NULL; -#endif /* OPENSSL_NO_TLSEXT */ - -#ifndef OPENSSL_NO_PSK - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 7); - if (os.data) { - ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->psk_identity_hint = NULL; - - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 8); - if (os.data) { - ret->psk_identity = BUF_strndup((char *)os.data, os.length); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->psk_identity = NULL; -#endif /* OPENSSL_NO_PSK */ - -#ifndef OPENSSL_NO_TLSEXT - ai.length = 0; - M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 9); - if (ai.data != NULL) { - ret->tlsext_tick_lifetime_hint = ASN1_INTEGER_get(aip); - OPENSSL_free(ai.data); - ai.data = NULL; - ai.length = 0; - } else if (ret->tlsext_ticklen && ret->session_id_length) - ret->tlsext_tick_lifetime_hint = -1; - else - ret->tlsext_tick_lifetime_hint = 0; - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 10); - if (os.data) { - ret->tlsext_tick = os.data; - ret->tlsext_ticklen = os.length; - os.data = NULL; - os.length = 0; - } else - ret->tlsext_tick = NULL; -#endif /* OPENSSL_NO_TLSEXT */ -#ifndef OPENSSL_NO_COMP - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 11); - if (os.data) { - ret->compress_meth = os.data[0]; - OPENSSL_free(os.data); - os.data = NULL; - } -#endif - -#ifndef OPENSSL_NO_SRP - os.length = 0; - os.data = NULL; - M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 12); - if (os.data) { - ret->srp_username = BUF_strndup((char *)os.data, os.length); - OPENSSL_free(os.data); - os.data = NULL; - os.length = 0; - } else - ret->srp_username = NULL; -#endif /* OPENSSL_NO_SRP */ - - M_ASN1_D2I_Finish(a, SSL_SESSION_free, SSL_F_D2I_SSL_SESSION); -} -/* - * ! \file ssl/ssl_cert.c - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#include - -#include "e_os.h" -#ifndef NO_SYS_TYPES_H -# include -#endif - -#include "o_dir.h" -// #include "objects.h" -#include "bio.h" -#include "pem.h" -#include "x509v3.h" -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#include "bn.h" -// #include "ssl_locl.h" - -int SSL_get_ex_data_X509_STORE_CTX_idx(void) -{ - static volatile int ssl_x509_store_ctx_idx = -1; - int got_write_lock = 0; - - if (((size_t)&ssl_x509_store_ctx_idx & - (sizeof(ssl_x509_store_ctx_idx) - 1)) - == 0) { /* check alignment, practically always true */ - int ret; - - if ((ret = ssl_x509_store_ctx_idx) < 0) { - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - if ((ret = ssl_x509_store_ctx_idx) < 0) { - ret = ssl_x509_store_ctx_idx = - X509_STORE_CTX_get_ex_new_index(0, - "SSL for verify callback", - NULL, NULL, NULL); - } - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - } - - return ret; - } else { /* commonly eliminated */ - - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - - if (ssl_x509_store_ctx_idx < 0) { - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - got_write_lock = 1; - - if (ssl_x509_store_ctx_idx < 0) { - ssl_x509_store_ctx_idx = - X509_STORE_CTX_get_ex_new_index(0, - "SSL for verify callback", - NULL, NULL, NULL); - } - } - - if (got_write_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - else - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - - return ssl_x509_store_ctx_idx; - } -} - -void ssl_cert_set_default_md(CERT *cert) -{ - /* Set digest values to defaults */ -#ifndef OPENSSL_NO_DSA - cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); -#endif -#ifndef OPENSSL_NO_RSA - cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); -#endif -#ifndef OPENSSL_NO_ECDSA - cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); -#endif -} - -CERT *ssl_cert_new(void) -{ - CERT *ret; - - ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); - if (ret == NULL) { - SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - memset(ret, 0, sizeof(CERT)); - - ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); - ret->references = 1; - ssl_cert_set_default_md(ret); - return (ret); -} - -CERT *ssl_cert_dup(CERT *cert) -{ - CERT *ret; - int i; - - ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); - if (ret == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - memset(ret, 0, sizeof(CERT)); - - ret->references = 1; - ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; - /* - * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that - * more readable - */ - - ret->valid = cert->valid; - ret->mask_k = cert->mask_k; - ret->mask_a = cert->mask_a; - ret->export_mask_k = cert->export_mask_k; - ret->export_mask_a = cert->export_mask_a; - -#ifndef OPENSSL_NO_RSA - if (cert->rsa_tmp != NULL) { - RSA_up_ref(cert->rsa_tmp); - ret->rsa_tmp = cert->rsa_tmp; - } - ret->rsa_tmp_cb = cert->rsa_tmp_cb; -#endif - -#ifndef OPENSSL_NO_DH - if (cert->dh_tmp != NULL) { - ret->dh_tmp = DHparams_dup(cert->dh_tmp); - if (ret->dh_tmp == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); - goto err; - } - if (cert->dh_tmp->priv_key) { - BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); - if (!b) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); - goto err; - } - ret->dh_tmp->priv_key = b; - } - if (cert->dh_tmp->pub_key) { - BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); - if (!b) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); - goto err; - } - ret->dh_tmp->pub_key = b; - } - } - ret->dh_tmp_cb = cert->dh_tmp_cb; -#endif - -#ifndef OPENSSL_NO_ECDH - if (cert->ecdh_tmp) { - ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); - if (ret->ecdh_tmp == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); - goto err; - } - } - ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; - ret->ecdh_tmp_auto = cert->ecdh_tmp_auto; -#endif - - for (i = 0; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = cert->pkeys + i; - CERT_PKEY *rpk = ret->pkeys + i; - if (cpk->x509 != NULL) { - rpk->x509 = cpk->x509; - CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509); - } - - if (cpk->privatekey != NULL) { - rpk->privatekey = cpk->privatekey; - CRYPTO_add(&cpk->privatekey->references, 1, CRYPTO_LOCK_EVP_PKEY); - } - - if (cpk->chain) { - rpk->chain = X509_chain_up_ref(cpk->chain); - if (!rpk->chain) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); - goto err; - } - } - rpk->valid_flags = 0; -#ifndef OPENSSL_NO_TLSEXT - if (cert->pkeys[i].serverinfo != NULL) { - /* Just copy everything. */ - ret->pkeys[i].serverinfo = - OPENSSL_malloc(cert->pkeys[i].serverinfo_length); - if (ret->pkeys[i].serverinfo == NULL) { - SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); - goto err; - } - ret->pkeys[i].serverinfo_length = - cert->pkeys[i].serverinfo_length; - memcpy(ret->pkeys[i].serverinfo, - cert->pkeys[i].serverinfo, - cert->pkeys[i].serverinfo_length); - } -#endif - } - - /* - * Set digests to defaults. NB: we don't copy existing values as they - * will be set during handshake. - */ - ssl_cert_set_default_md(ret); - /* Peer sigalgs set to NULL as we get these from handshake too */ - ret->peer_sigalgs = NULL; - ret->peer_sigalgslen = 0; - /* Configured sigalgs however we copy across */ - - if (cert->conf_sigalgs) { - ret->conf_sigalgs = OPENSSL_malloc(cert->conf_sigalgslen); - if (!ret->conf_sigalgs) - goto err; - memcpy(ret->conf_sigalgs, cert->conf_sigalgs, cert->conf_sigalgslen); - ret->conf_sigalgslen = cert->conf_sigalgslen; - } else - ret->conf_sigalgs = NULL; - - if (cert->client_sigalgs) { - ret->client_sigalgs = OPENSSL_malloc(cert->client_sigalgslen); - if (!ret->client_sigalgs) - goto err; - memcpy(ret->client_sigalgs, cert->client_sigalgs, - cert->client_sigalgslen); - ret->client_sigalgslen = cert->client_sigalgslen; - } else - ret->client_sigalgs = NULL; - /* Shared sigalgs also NULL */ - ret->shared_sigalgs = NULL; - /* Copy any custom client certificate types */ - if (cert->ctypes) { - ret->ctypes = OPENSSL_malloc(cert->ctype_num); - if (!ret->ctypes) - goto err; - memcpy(ret->ctypes, cert->ctypes, cert->ctype_num); - ret->ctype_num = cert->ctype_num; - } - - ret->cert_flags = cert->cert_flags; - - ret->cert_cb = cert->cert_cb; - ret->cert_cb_arg = cert->cert_cb_arg; - - if (cert->verify_store) { - CRYPTO_add(&cert->verify_store->references, 1, - CRYPTO_LOCK_X509_STORE); - ret->verify_store = cert->verify_store; - } - - if (cert->chain_store) { - CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE); - ret->chain_store = cert->chain_store; - } - - ret->ciphers_raw = NULL; - -#ifndef OPENSSL_NO_TLSEXT - if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext)) - goto err; - if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext)) - goto err; -#endif - - return (ret); - - err: -#ifndef OPENSSL_NO_RSA - if (ret->rsa_tmp != NULL) - RSA_free(ret->rsa_tmp); -#endif -#ifndef OPENSSL_NO_DH - if (ret->dh_tmp != NULL) - DH_free(ret->dh_tmp); -#endif -#ifndef OPENSSL_NO_ECDH - if (ret->ecdh_tmp != NULL) - EC_KEY_free(ret->ecdh_tmp); -#endif - -#ifndef OPENSSL_NO_TLSEXT - custom_exts_free(&ret->cli_ext); - custom_exts_free(&ret->srv_ext); -#endif - - ssl_cert_clear_certs(ret); - OPENSSL_free(ret); - - return NULL; -} - -/* Free up and clear all certificates and chains */ - -void ssl_cert_clear_certs(CERT *c) -{ - int i; - if (c == NULL) - return; - for (i = 0; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = c->pkeys + i; - if (cpk->x509) { - X509_free(cpk->x509); - cpk->x509 = NULL; - } - if (cpk->privatekey) { - EVP_PKEY_free(cpk->privatekey); - cpk->privatekey = NULL; - } - if (cpk->chain) { - sk_X509_pop_free(cpk->chain, X509_free); - cpk->chain = NULL; - } -#ifndef OPENSSL_NO_TLSEXT - if (cpk->serverinfo) { - OPENSSL_free(cpk->serverinfo); - cpk->serverinfo = NULL; - cpk->serverinfo_length = 0; - } -#endif - /* Clear all flags apart from explicit sign */ - cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; - } -} - -void ssl_cert_free(CERT *c) -{ - int i; - - if (c == NULL) - return; - - i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); -#ifdef REF_PRINT - REF_PRINT("CERT", c); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "ssl_cert_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - -#ifndef OPENSSL_NO_RSA - if (c->rsa_tmp) - RSA_free(c->rsa_tmp); -#endif -#ifndef OPENSSL_NO_DH - if (c->dh_tmp) - DH_free(c->dh_tmp); -#endif -#ifndef OPENSSL_NO_ECDH - if (c->ecdh_tmp) - EC_KEY_free(c->ecdh_tmp); -#endif - - ssl_cert_clear_certs(c); - if (c->peer_sigalgs) - OPENSSL_free(c->peer_sigalgs); - if (c->conf_sigalgs) - OPENSSL_free(c->conf_sigalgs); - if (c->client_sigalgs) - OPENSSL_free(c->client_sigalgs); - if (c->shared_sigalgs) - OPENSSL_free(c->shared_sigalgs); - if (c->ctypes) - OPENSSL_free(c->ctypes); - if (c->verify_store) - X509_STORE_free(c->verify_store); - if (c->chain_store) - X509_STORE_free(c->chain_store); - if (c->ciphers_raw) - OPENSSL_free(c->ciphers_raw); -#ifndef OPENSSL_NO_TLSEXT - custom_exts_free(&c->cli_ext); - custom_exts_free(&c->srv_ext); - if (c->alpn_proposed) - OPENSSL_free(c->alpn_proposed); -#endif - OPENSSL_free(c); -} - -int ssl_cert_inst(CERT **o) -{ - /* - * Create a CERT if there isn't already one (which cannot really happen, - * as it is initially created in SSL_CTX_new; but the earlier code - * usually allows for that one being non-existant, so we follow that - * behaviour, as it might turn out that there actually is a reason for it - * -- but I'm not sure that *all* of the existing code could cope with - * s->cert being NULL, otherwise we could do without the initialization - * in SSL_CTX_new). - */ - - if (o == NULL) { - SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (*o == NULL) { - if ((*o = ssl_cert_new()) == NULL) { - SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); - return (0); - } - } - return (1); -} - -int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain) -{ - CERT_PKEY *cpk = c->key; - if (!cpk) - return 0; - if (cpk->chain) - sk_X509_pop_free(cpk->chain, X509_free); - cpk->chain = chain; - return 1; -} - -int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) -{ - STACK_OF(X509) *dchain; - if (!chain) - return ssl_cert_set0_chain(c, NULL); - dchain = X509_chain_up_ref(chain); - if (!dchain) - return 0; - if (!ssl_cert_set0_chain(c, dchain)) { - sk_X509_pop_free(dchain, X509_free); - return 0; - } - return 1; -} - -int ssl_cert_add0_chain_cert(CERT *c, X509 *x) -{ - CERT_PKEY *cpk = c->key; - if (!cpk) - return 0; - if (!cpk->chain) - cpk->chain = sk_X509_new_null(); - if (!cpk->chain || !sk_X509_push(cpk->chain, x)) - return 0; - return 1; -} - -int ssl_cert_add1_chain_cert(CERT *c, X509 *x) -{ - if (!ssl_cert_add0_chain_cert(c, x)) - return 0; - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - return 1; -} - -int ssl_cert_select_current(CERT *c, X509 *x) -{ - int i; - if (x == NULL) - return 0; - for (i = 0; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = c->pkeys + i; - if (cpk->x509 == x && cpk->privatekey) { - c->key = cpk; - return 1; - } - } - - for (i = 0; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = c->pkeys + i; - if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { - c->key = cpk; - return 1; - } - } - return 0; -} - -int ssl_cert_set_current(CERT *c, long op) -{ - int i, idx; - if (!c) - return 0; - if (op == SSL_CERT_SET_FIRST) - idx = 0; - else if (op == SSL_CERT_SET_NEXT) { - idx = (int)(c->key - c->pkeys + 1); - if (idx >= SSL_PKEY_NUM) - return 0; - } else - return 0; - for (i = idx; i < SSL_PKEY_NUM; i++) { - CERT_PKEY *cpk = c->pkeys + i; - if (cpk->x509 && cpk->privatekey) { - c->key = cpk; - return 1; - } - } - return 0; -} - -void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), void *arg) -{ - c->cert_cb = cb; - c->cert_cb_arg = arg; -} - -SESS_CERT *ssl_sess_cert_new(void) -{ - SESS_CERT *ret; - - ret = OPENSSL_malloc(sizeof(*ret)); - if (ret == NULL) { - SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - - memset(ret, 0, sizeof(*ret)); - ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); - ret->references = 1; - - return ret; -} - -void ssl_sess_cert_free(SESS_CERT *sc) -{ - int i; - - if (sc == NULL) - return; - - i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); -#ifdef REF_PRINT - REF_PRINT("SESS_CERT", sc); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "ssl_sess_cert_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - /* i == 0 */ - if (sc->cert_chain != NULL) - sk_X509_pop_free(sc->cert_chain, X509_free); - for (i = 0; i < SSL_PKEY_NUM; i++) { - if (sc->peer_pkeys[i].x509 != NULL) - X509_free(sc->peer_pkeys[i].x509); -#if 0 /* We don't have the peer's private key. - * These lines are just * here as a reminder - * that we're still using a - * not-quite-appropriate * data structure. */ - if (sc->peer_pkeys[i].privatekey != NULL) - EVP_PKEY_free(sc->peer_pkeys[i].privatekey); -#endif - } - -#ifndef OPENSSL_NO_RSA - if (sc->peer_rsa_tmp != NULL) - RSA_free(sc->peer_rsa_tmp); -#endif -#ifndef OPENSSL_NO_DH - if (sc->peer_dh_tmp != NULL) - DH_free(sc->peer_dh_tmp); -#endif -#ifndef OPENSSL_NO_ECDH - if (sc->peer_ecdh_tmp != NULL) - EC_KEY_free(sc->peer_ecdh_tmp); -#endif - - OPENSSL_free(sc); -} - -int ssl_set_peer_cert_type(SESS_CERT *sc, int type) -{ - sc->peer_cert_type = type; - return (1); -} - -int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) -{ - X509 *x; - int i; - X509_STORE *verify_store; - X509_STORE_CTX ctx; - - if (s->cert->verify_store) - verify_store = s->cert->verify_store; - else - verify_store = s->ctx->cert_store; - - if ((sk == NULL) || (sk_X509_num(sk) == 0)) - return (0); - - x = sk_X509_value(sk, 0); - if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) { - SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); - return (0); - } - /* Set suite B flags if needed */ - X509_STORE_CTX_set_flags(&ctx, tls1_suiteb(s)); -#if 0 - if (SSL_get_verify_depth(s) >= 0) - X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); -#endif - X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); - - /* - * We need to inherit the verify parameters. These can be determined by - * the context: if its a server it will verify SSL client certificates or - * vice versa. - */ - - X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); - /* - * Anything non-default in "param" should overwrite anything in the ctx. - */ - X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); - - if (s->verify_callback) - X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); - - if (s->ctx->app_verify_callback != NULL) -#if 1 /* new with OpenSSL 0.9.7 */ - i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); -#else - i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ -#endif - else { -#ifndef OPENSSL_NO_X509_VERIFY - i = X509_verify_cert(&ctx); -#else - i = 0; - ctx.error = X509_V_ERR_APPLICATION_VERIFICATION; - SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK); -#endif - } - - s->verify_result = ctx.error; - X509_STORE_CTX_cleanup(&ctx); - - return (i); -} - -static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, - STACK_OF(X509_NAME) *name_list) -{ - if (*ca_list != NULL) - sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); - - *ca_list = name_list; -} - -STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) -{ - int i; - STACK_OF(X509_NAME) *ret; - X509_NAME *name; - - ret = sk_X509_NAME_new_null(); - for (i = 0; i < sk_X509_NAME_num(sk); i++) { - name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); - if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { - sk_X509_NAME_pop_free(ret, X509_NAME_free); - return (NULL); - } - } - return (ret); -} - -void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) -{ - set_client_CA_list(&(s->client_CA), name_list); -} - -void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) -{ - set_client_CA_list(&(ctx->client_CA), name_list); -} - -STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) -{ - return (ctx->client_CA); -} - -STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) -{ - if (s->type == SSL_ST_CONNECT) { /* we are in the client */ - if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL)) - return (s->s3->tmp.ca_names); - else - return (NULL); - } else { - if (s->client_CA != NULL) - return (s->client_CA); - else - return (s->ctx->client_CA); - } -} - -static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) -{ - X509_NAME *name; - - if (x == NULL) - return (0); - if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) - return (0); - - if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) - return (0); - - if (!sk_X509_NAME_push(*sk, name)) { - X509_NAME_free(name); - return (0); - } - return (1); -} - -int SSL_add_client_CA(SSL *ssl, X509 *x) -{ - return (add_client_CA(&(ssl->client_CA), x)); -} - -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) -{ - return (add_client_CA(&(ctx->client_CA), x)); -} - -static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) -{ - return (X509_NAME_cmp(*a, *b)); -} - -#ifndef OPENSSL_NO_STDIO -/** - * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; - * it doesn't really have anything to do with clients (except that a common use - * for a stack of CAs is to send it to the client). Actually, it doesn't have - * much to do with CAs, either, since it will load any old cert. - * \param file the file containing one or more certs. - * \return a ::STACK containing the certs. - */ -STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) -{ - BIO *in; - X509 *x = NULL; - X509_NAME *xn = NULL; - STACK_OF(X509_NAME) *ret = NULL, *sk; - - sk = sk_X509_NAME_new(xname_cmp); - - in = BIO_new(BIO_s_file_internal()); - - if ((sk == NULL) || (in == NULL)) { - SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!BIO_read_filename(in, file)) - goto err; - - for (;;) { - if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) - break; - if (ret == NULL) { - ret = sk_X509_NAME_new_null(); - if (ret == NULL) { - SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); - goto err; - } - } - if ((xn = X509_get_subject_name(x)) == NULL) - goto err; - /* check for duplicates */ - xn = X509_NAME_dup(xn); - if (xn == NULL) - goto err; - if (sk_X509_NAME_find(sk, xn) >= 0) - X509_NAME_free(xn); - else { - sk_X509_NAME_push(sk, xn); - sk_X509_NAME_push(ret, xn); - } - } - - if (0) { - err: - if (ret != NULL) - sk_X509_NAME_pop_free(ret, X509_NAME_free); - ret = NULL; - } - if (sk != NULL) - sk_X509_NAME_free(sk); - if (in != NULL) - BIO_free(in); - if (x != NULL) - X509_free(x); - if (ret != NULL) - ERR_clear_error(); - return (ret); -} -#endif - -/** - * Add a file of certs to a stack. - * \param stack the stack to add to. - * \param file the file to add from. All certs in this file that are not - * already in the stack will be added. - * \return 1 for success, 0 for failure. Note that in the case of failure some - * certs may have been added to \c stack. - */ - -int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, - const char *file) -{ - BIO *in; - X509 *x = NULL; - X509_NAME *xn = NULL; - int ret = 1; - int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); - - oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); - - in = BIO_new(BIO_s_file_internal()); - - if (in == NULL) { - SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, - ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!BIO_read_filename(in, file)) - goto err; - - for (;;) { - if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) - break; - if ((xn = X509_get_subject_name(x)) == NULL) - goto err; - xn = X509_NAME_dup(xn); - if (xn == NULL) - goto err; - if (sk_X509_NAME_find(stack, xn) >= 0) - X509_NAME_free(xn); - else - sk_X509_NAME_push(stack, xn); - } - - ERR_clear_error(); - - if (0) { - err: - ret = 0; - } - if (in != NULL) - BIO_free(in); - if (x != NULL) - X509_free(x); - - (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); - - return ret; -} - -/** - * Add a directory of certs to a stack. - * \param stack the stack to append to. - * \param dir the directory to append from. All files in this directory will be - * examined as potential certs. Any that are acceptable to - * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be - * included. - * \return 1 for success, 0 for failure. Note that in the case of failure some - * certs may have been added to \c stack. - */ - -int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, - const char *dir) -{ - OPENSSL_DIR_CTX *d = NULL; - const char *filename; - int ret = 0; - - CRYPTO_w_lock(CRYPTO_LOCK_READDIR); - - /* Note that a side effect is that the CAs will be sorted by name */ - - while ((filename = OPENSSL_DIR_read(&d, dir))) { - char buf[1024]; - int r; - - if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { - SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, - SSL_R_PATH_TOO_LONG); - goto err; - } -#ifdef OPENSSL_SYS_VMS - r = BIO_snprintf(buf, sizeof(buf), "%s%s", dir, filename); -#else - r = BIO_snprintf(buf, sizeof(buf), "%s/%s", dir, filename); -#endif - if (r <= 0 || r >= (int)sizeof(buf)) - goto err; - if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) - goto err; - } - - if (errno) { - SYSerr(SYS_F_OPENDIR, get_last_sys_error()); - ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); - SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); - goto err; - } - - ret = 1; - - err: - if (d) - OPENSSL_DIR_end(&d); - CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); - return ret; -} - -/* Add a certificate to a BUF_MEM structure */ - -static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) -{ - int n; - unsigned char *p; - - n = i2d_X509(x, NULL); - if (n < 0 || !BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) { - SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); - return 0; - } - p = (unsigned char *)&(buf->data[*l]); - l2n3(n, p); - n = i2d_X509(x, &p); - if (n < 0) { - /* Shouldn't happen */ - SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); - return 0; - } - *l += n + 3; - - return 1; -} - -/* Add certificate chain to internal SSL BUF_MEM strcuture */ -int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) -{ - BUF_MEM *buf = s->init_buf; - int no_chain; - int i; - - X509 *x; - STACK_OF(X509) *extra_certs; - X509_STORE *chain_store; - - if (cpk) - x = cpk->x509; - else - x = NULL; - - if (s->cert->chain_store) - chain_store = s->cert->chain_store; - else - chain_store = s->ctx->cert_store; - - /* - * If we have a certificate specific chain use it, else use parent ctx. - */ - if (cpk && cpk->chain) - extra_certs = cpk->chain; - else - extra_certs = s->ctx->extra_certs; - - if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) - no_chain = 1; - else - no_chain = 0; - - /* TLSv1 sends a chain with nothing in it, instead of an alert */ - if (!BUF_MEM_grow_clean(buf, 10)) { - SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_BUF_LIB); - return 0; - } - if (x != NULL) { - if (no_chain) { - if (!ssl_add_cert_to_buf(buf, l, x)) - return 0; - } else { - X509_STORE_CTX xs_ctx; - - if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) { - SSLerr(SSL_F_SSL_ADD_CERT_CHAIN, ERR_R_X509_LIB); - return (0); - } - X509_verify_cert(&xs_ctx); - /* Don't leave errors in the queue */ - ERR_clear_error(); - for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { - x = sk_X509_value(xs_ctx.chain, i); - - if (!ssl_add_cert_to_buf(buf, l, x)) { - X509_STORE_CTX_cleanup(&xs_ctx); - return 0; - } - } - X509_STORE_CTX_cleanup(&xs_ctx); - } - } - for (i = 0; i < sk_X509_num(extra_certs); i++) { - x = sk_X509_value(extra_certs, i); - if (!ssl_add_cert_to_buf(buf, l, x)) - return 0; - } - - return 1; -} - -/* Build a certificate chain for current certificate */ -int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) -{ - CERT_PKEY *cpk = c->key; - X509_STORE_CTX xs_ctx; - STACK_OF(X509) *chain = NULL, *untrusted = NULL; - X509 *x; - int i, rv = 0; - unsigned long error; - - if (!cpk->x509) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET); - goto err; - } - /* Rearranging and check the chain: add everything to a store */ - if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) { - chain_store = X509_STORE_new(); - if (!chain_store) - goto err; - for (i = 0; i < sk_X509_num(cpk->chain); i++) { - x = sk_X509_value(cpk->chain, i); - if (!X509_STORE_add_cert(chain_store, x)) { - error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) != ERR_LIB_X509 || - ERR_GET_REASON(error) != - X509_R_CERT_ALREADY_IN_HASH_TABLE) - goto err; - ERR_clear_error(); - } - } - /* Add EE cert too: it might be self signed */ - if (!X509_STORE_add_cert(chain_store, cpk->x509)) { - error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) != ERR_LIB_X509 || - ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) - goto err; - ERR_clear_error(); - } - } else { - if (c->chain_store) - chain_store = c->chain_store; - - if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) - untrusted = cpk->chain; - } - - if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB); - goto err; - } - /* Set suite B flags if needed */ - X509_STORE_CTX_set_flags(&xs_ctx, - c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); - - i = X509_verify_cert(&xs_ctx); - if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { - if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) - ERR_clear_error(); - i = 1; - rv = 2; - } - if (i > 0) - chain = X509_STORE_CTX_get1_chain(&xs_ctx); - if (i <= 0) { - SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED); - i = X509_STORE_CTX_get_error(&xs_ctx); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(i)); - - X509_STORE_CTX_cleanup(&xs_ctx); - goto err; - } - X509_STORE_CTX_cleanup(&xs_ctx); - if (cpk->chain) - sk_X509_pop_free(cpk->chain, X509_free); - /* Remove EE certificate from chain */ - x = sk_X509_shift(chain); - X509_free(x); - if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) { - if (sk_X509_num(chain) > 0) { - /* See if last cert is self signed */ - x = sk_X509_value(chain, sk_X509_num(chain) - 1); - X509_check_purpose(x, -1, 0); - if (x->ex_flags & EXFLAG_SS) { - x = sk_X509_pop(chain); - X509_free(x); - } - } - } - cpk->chain = chain; - if (rv == 0) - rv = 1; - err: - if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) - X509_STORE_free(chain_store); - - return rv; -} - -int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) -{ - X509_STORE **pstore; - if (chain) - pstore = &c->chain_store; - else - pstore = &c->verify_store; - if (*pstore) - X509_STORE_free(*pstore); - *pstore = store; - if (ref && store) - CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE); - return 1; -} -/* ssl/ssl_ciph.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -// #include "objects.h" -#ifndef OPENSSL_NO_COMP -# include "comp.h" -#endif -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -// #include "ssl_locl.h" - -#define SSL_ENC_DES_IDX 0 -#define SSL_ENC_3DES_IDX 1 -#define SSL_ENC_RC4_IDX 2 -#define SSL_ENC_RC2_IDX 3 -#define SSL_ENC_IDEA_IDX 4 -#define SSL_ENC_NULL_IDX 5 -#define SSL_ENC_AES128_IDX 6 -#define SSL_ENC_AES256_IDX 7 -#define SSL_ENC_CAMELLIA128_IDX 8 -#define SSL_ENC_CAMELLIA256_IDX 9 -#define SSL_ENC_GOST89_IDX 10 -#define SSL_ENC_SEED_IDX 11 -#define SSL_ENC_AES128GCM_IDX 12 -#define SSL_ENC_AES256GCM_IDX 13 -#define SSL_ENC_NUM_IDX 14 - -static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL -}; - -#define SSL_COMP_NULL_IDX 0 -#define SSL_COMP_ZLIB_IDX 1 -#define SSL_COMP_NUM_IDX 2 - -static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; - -#define SSL_MD_MD5_IDX 0 -#define SSL_MD_SHA1_IDX 1 -#define SSL_MD_GOST94_IDX 2 -#define SSL_MD_GOST89MAC_IDX 3 -#define SSL_MD_SHA256_IDX 4 -#define SSL_MD_SHA384_IDX 5 -/* - * Constant SSL_MAX_DIGEST equal to size of digests array should be defined - * in the ssl_locl.h - */ -#define SSL_MD_NUM_IDX SSL_MAX_DIGEST -static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { - NULL, NULL, NULL, NULL, NULL, NULL -}; - -/* - * PKEY_TYPE for GOST89MAC is known in advance, but, because implementation - * is engine-provided, we'll fill it only if corresponding EVP_PKEY_METHOD is - * found - */ -static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { - EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, - EVP_PKEY_HMAC, EVP_PKEY_HMAC -}; - -static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { - 0, 0, 0, 0, 0, 0 -}; - -static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = { - SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA, - SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, - SSL_HANDSHAKE_MAC_SHA384 -}; - -#define CIPHER_ADD 1 -#define CIPHER_KILL 2 -#define CIPHER_DEL 3 -#define CIPHER_ORD 4 -#define CIPHER_SPECIAL 5 - -typedef struct cipher_order_st { - const SSL_CIPHER *cipher; - int active; - int dead; - struct cipher_order_st *next, *prev; -} CIPHER_ORDER; - -static const SSL_CIPHER cipher_aliases[] = { - /* "ALL" doesn't include eNULL (must be specifically enabled) */ - {0, SSL_TXT_ALL, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, 0}, - /* "COMPLEMENTOFALL" */ - {0, SSL_TXT_CMPALL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, - - /* - * "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in - * ALL!) - */ - {0, SSL_TXT_CMPDEF, 0, 0, 0, 0, 0, 0, SSL_NOT_DEFAULT, 0, 0, 0}, - - /* - * key exchange aliases (some of those using only a single bit here - * combine multiple key exchange algs according to the RFCs, e.g. kEDH - * combines DHE_DSS and DHE_RSA) - */ - {0, SSL_TXT_kRSA, 0, SSL_kRSA, 0, 0, 0, 0, 0, 0, 0, 0}, - - {0, SSL_TXT_kDHr, 0, SSL_kDHr, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kDHd, 0, SSL_kDHd, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kDH, 0, SSL_kDHr | SSL_kDHd, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kEDH, 0, SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kDHE, 0, SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_DH, 0, SSL_kDHr | SSL_kDHd | SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, - 0}, - - {0, SSL_TXT_kKRB5, 0, SSL_kKRB5, 0, 0, 0, 0, 0, 0, 0, 0}, - - {0, SSL_TXT_kECDHr, 0, SSL_kECDHr, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kECDHe, 0, SSL_kECDHe, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kECDH, 0, SSL_kECDHr | SSL_kECDHe, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kEECDH, 0, SSL_kEECDH, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kECDHE, 0, SSL_kEECDH, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_ECDH, 0, SSL_kECDHr | SSL_kECDHe | SSL_kEECDH, 0, 0, 0, 0, 0, - 0, 0, 0}, - - {0, SSL_TXT_kPSK, 0, SSL_kPSK, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kSRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_kGOST, 0, SSL_kGOST, 0, 0, 0, 0, 0, 0, 0, 0}, - - /* server authentication aliases */ - {0, SSL_TXT_aRSA, 0, 0, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aDSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_DSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aKRB5, 0, 0, SSL_aKRB5, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aNULL, 0, 0, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - /* no such ciphersuites supported! */ - {0, SSL_TXT_aDH, 0, 0, SSL_aDH, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aECDH, 0, 0, SSL_aECDH, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_ECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aPSK, 0, 0, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aGOST94, 0, 0, SSL_aGOST94, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aGOST01, 0, 0, SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aGOST, 0, 0, SSL_aGOST94 | SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_aSRP, 0, 0, SSL_aSRP, 0, 0, 0, 0, 0, 0, 0}, - - /* aliases combining key exchange and server authentication */ - {0, SSL_TXT_EDH, 0, SSL_kEDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_DHE, 0, SSL_kEDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_EECDH, 0, SSL_kEECDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_ECDHE, 0, SSL_kEECDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_NULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_KRB5, 0, SSL_kKRB5, SSL_aKRB5, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_RSA, 0, SSL_kRSA, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_ADH, 0, SSL_kEDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_AECDH, 0, SSL_kEECDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_PSK, 0, SSL_kPSK, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, - - /* symmetric encryption aliases */ - {0, SSL_TXT_DES, 0, 0, 0, SSL_DES, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_3DES, 0, 0, 0, SSL_3DES, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_RC4, 0, 0, 0, SSL_RC4, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_RC2, 0, 0, 0, SSL_RC2, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_IDEA, 0, 0, 0, SSL_IDEA, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SEED, 0, 0, 0, SSL_SEED, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_eNULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_AES128, 0, 0, 0, SSL_AES128 | SSL_AES128GCM, 0, 0, 0, 0, 0, - 0}, - {0, SSL_TXT_AES256, 0, 0, 0, SSL_AES256 | SSL_AES256GCM, 0, 0, 0, 0, 0, - 0}, - {0, SSL_TXT_AES, 0, 0, 0, SSL_AES, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_AES_GCM, 0, 0, 0, SSL_AES128GCM | SSL_AES256GCM, 0, 0, 0, 0, - 0, 0}, - {0, SSL_TXT_CAMELLIA128, 0, 0, 0, SSL_CAMELLIA128, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_CAMELLIA256, 0, 0, 0, SSL_CAMELLIA256, 0, 0, 0, 0, 0, 0}, - {0, SSL_TXT_CAMELLIA, 0, 0, 0, SSL_CAMELLIA128 | SSL_CAMELLIA256, 0, 0, 0, - 0, 0, 0}, - - /* MAC aliases */ - {0, SSL_TXT_MD5, 0, 0, 0, 0, SSL_MD5, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SHA1, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SHA, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0}, - {0, SSL_TXT_GOST94, 0, 0, 0, 0, SSL_GOST94, 0, 0, 0, 0, 0}, - {0, SSL_TXT_GOST89MAC, 0, 0, 0, 0, SSL_GOST89MAC, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SHA256, 0, 0, 0, 0, SSL_SHA256, 0, 0, 0, 0, 0}, - {0, SSL_TXT_SHA384, 0, 0, 0, 0, SSL_SHA384, 0, 0, 0, 0, 0}, - - /* protocol version aliases */ - {0, SSL_TXT_SSLV2, 0, 0, 0, 0, 0, SSL_SSLV2, 0, 0, 0, 0}, - {0, SSL_TXT_SSLV3, 0, 0, 0, 0, 0, SSL_SSLV3, 0, 0, 0, 0}, - {0, SSL_TXT_TLSV1, 0, 0, 0, 0, 0, SSL_TLSV1, 0, 0, 0, 0}, - {0, SSL_TXT_TLSV1_2, 0, 0, 0, 0, 0, SSL_TLSV1_2, 0, 0, 0, 0}, - - /* export flag */ - {0, SSL_TXT_EXP, 0, 0, 0, 0, 0, 0, SSL_EXPORT, 0, 0, 0}, - {0, SSL_TXT_EXPORT, 0, 0, 0, 0, 0, 0, SSL_EXPORT, 0, 0, 0}, - - /* strength classes */ - {0, SSL_TXT_EXP40, 0, 0, 0, 0, 0, 0, SSL_EXP40, 0, 0, 0}, - {0, SSL_TXT_EXP56, 0, 0, 0, 0, 0, 0, SSL_EXP56, 0, 0, 0}, - {0, SSL_TXT_LOW, 0, 0, 0, 0, 0, 0, SSL_LOW, 0, 0, 0}, - {0, SSL_TXT_MEDIUM, 0, 0, 0, 0, 0, 0, SSL_MEDIUM, 0, 0, 0}, - {0, SSL_TXT_HIGH, 0, 0, 0, 0, 0, 0, SSL_HIGH, 0, 0, 0}, - /* FIPS 140-2 approved ciphersuite */ - {0, SSL_TXT_FIPS, 0, 0, 0, ~SSL_eNULL, 0, 0, SSL_FIPS, 0, 0, 0}, - /* "DHE-" aliases to "EDH-" labels (for forward compatibility) */ - {0, SSL3_TXT_DHE_DSS_DES_40_CBC_SHA, 0, - SSL_kDHE, SSL_aDSS, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_EXPORT | SSL_EXP40, - 0, 0, 0,}, - {0, SSL3_TXT_DHE_DSS_DES_64_CBC_SHA, 0, - SSL_kDHE, SSL_aDSS, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_NOT_EXP | SSL_LOW, - 0, 0, 0,}, - {0, SSL3_TXT_DHE_DSS_DES_192_CBC3_SHA, 0, - SSL_kDHE, SSL_aDSS, SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, 0, 0, 0,}, - {0, SSL3_TXT_DHE_RSA_DES_40_CBC_SHA, 0, - SSL_kDHE, SSL_aRSA, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_EXPORT | SSL_EXP40, - 0, 0, 0,}, - {0, SSL3_TXT_DHE_RSA_DES_64_CBC_SHA, 0, - SSL_kDHE, SSL_aRSA, SSL_DES, SSL_SHA1, SSL_SSLV3, SSL_NOT_EXP | SSL_LOW, - 0, 0, 0,}, - {0, SSL3_TXT_DHE_RSA_DES_192_CBC3_SHA, 0, - SSL_kDHE, SSL_aRSA, SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, 0, 0, 0,}, -}; - -/* - * Search for public key algorithm with given name and return its pkey_id if - * it is available. Otherwise return 0 - */ -#ifdef OPENSSL_NO_ENGINE - -static int get_optional_pkey_id(const char *pkey_name) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - int pkey_id = 0; - ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1); - if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, - ameth) > 0) { - return pkey_id; - } - return 0; -} - -#else - -static int get_optional_pkey_id(const char *pkey_name) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - ENGINE *tmpeng = NULL; - int pkey_id = 0; - ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1); - if (ameth) { - if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, - ameth) <= 0) - pkey_id = 0; - } - if (tmpeng) - ENGINE_finish(tmpeng); - return pkey_id; -} - -#endif - -void ssl_load_ciphers(void) -{ - ssl_cipher_methods[SSL_ENC_DES_IDX] = EVP_get_cipherbyname(SN_des_cbc); - ssl_cipher_methods[SSL_ENC_3DES_IDX] = - EVP_get_cipherbyname(SN_des_ede3_cbc); - ssl_cipher_methods[SSL_ENC_RC4_IDX] = EVP_get_cipherbyname(SN_rc4); - ssl_cipher_methods[SSL_ENC_RC2_IDX] = EVP_get_cipherbyname(SN_rc2_cbc); -#ifndef OPENSSL_NO_IDEA - ssl_cipher_methods[SSL_ENC_IDEA_IDX] = EVP_get_cipherbyname(SN_idea_cbc); -#else - ssl_cipher_methods[SSL_ENC_IDEA_IDX] = NULL; -#endif - ssl_cipher_methods[SSL_ENC_AES128_IDX] = - EVP_get_cipherbyname(SN_aes_128_cbc); - ssl_cipher_methods[SSL_ENC_AES256_IDX] = - EVP_get_cipherbyname(SN_aes_256_cbc); - ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] = - EVP_get_cipherbyname(SN_camellia_128_cbc); - ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] = - EVP_get_cipherbyname(SN_camellia_256_cbc); - ssl_cipher_methods[SSL_ENC_GOST89_IDX] = - EVP_get_cipherbyname(SN_gost89_cnt); - ssl_cipher_methods[SSL_ENC_SEED_IDX] = EVP_get_cipherbyname(SN_seed_cbc); - - ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] = - EVP_get_cipherbyname(SN_aes_128_gcm); - ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] = - EVP_get_cipherbyname(SN_aes_256_gcm); - - ssl_digest_methods[SSL_MD_MD5_IDX] = EVP_get_digestbyname(SN_md5); - ssl_mac_secret_size[SSL_MD_MD5_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); - OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); - ssl_digest_methods[SSL_MD_SHA1_IDX] = EVP_get_digestbyname(SN_sha1); - ssl_mac_secret_size[SSL_MD_SHA1_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); - OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); - ssl_digest_methods[SSL_MD_GOST94_IDX] = - EVP_get_digestbyname(SN_id_GostR3411_94); - if (ssl_digest_methods[SSL_MD_GOST94_IDX]) { - ssl_mac_secret_size[SSL_MD_GOST94_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); - OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); - } - ssl_digest_methods[SSL_MD_GOST89MAC_IDX] = - EVP_get_digestbyname(SN_id_Gost28147_89_MAC); - ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); - if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { - ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; - } - - ssl_digest_methods[SSL_MD_SHA256_IDX] = EVP_get_digestbyname(SN_sha256); - ssl_mac_secret_size[SSL_MD_SHA256_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); - ssl_digest_methods[SSL_MD_SHA384_IDX] = EVP_get_digestbyname(SN_sha384); - ssl_mac_secret_size[SSL_MD_SHA384_IDX] = - EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); -} - -#ifndef OPENSSL_NO_COMP - -static int sk_comp_cmp(const SSL_COMP *const *a, const SSL_COMP *const *b) -{ - return ((*a)->id - (*b)->id); -} - -static void load_builtin_compressions(void) -{ - int got_write_lock = 0; - - CRYPTO_r_lock(CRYPTO_LOCK_SSL); - if (ssl_comp_methods == NULL) { - CRYPTO_r_unlock(CRYPTO_LOCK_SSL); - CRYPTO_w_lock(CRYPTO_LOCK_SSL); - got_write_lock = 1; - - if (ssl_comp_methods == NULL) { - SSL_COMP *comp = NULL; - - MemCheck_off(); - ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp); - if (ssl_comp_methods != NULL) { - comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); - if (comp != NULL) { - comp->method = COMP_zlib(); - if (comp->method && comp->method->type == NID_undef) - OPENSSL_free(comp); - else { - comp->id = SSL_COMP_ZLIB_IDX; - comp->name = comp->method->name; - sk_SSL_COMP_push(ssl_comp_methods, comp); - } - } - sk_SSL_COMP_sort(ssl_comp_methods); - } - MemCheck_on(); - } - } - - if (got_write_lock) - CRYPTO_w_unlock(CRYPTO_LOCK_SSL); - else - CRYPTO_r_unlock(CRYPTO_LOCK_SSL); -} -#endif - -int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, - int *mac_secret_size, SSL_COMP **comp) -{ - int i; - const SSL_CIPHER *c; - - c = s->cipher; - if (c == NULL) - return (0); - if (comp != NULL) { - SSL_COMP ctmp; -#ifndef OPENSSL_NO_COMP - load_builtin_compressions(); -#endif - - *comp = NULL; - ctmp.id = s->compress_meth; - if (ssl_comp_methods != NULL) { - i = sk_SSL_COMP_find(ssl_comp_methods, &ctmp); - if (i >= 0) - *comp = sk_SSL_COMP_value(ssl_comp_methods, i); - else - *comp = NULL; - } - } - - if ((enc == NULL) || (md == NULL)) - return (0); - - switch (c->algorithm_enc) { - case SSL_DES: - i = SSL_ENC_DES_IDX; - break; - case SSL_3DES: - i = SSL_ENC_3DES_IDX; - break; - case SSL_RC4: - i = SSL_ENC_RC4_IDX; - break; - case SSL_RC2: - i = SSL_ENC_RC2_IDX; - break; - case SSL_IDEA: - i = SSL_ENC_IDEA_IDX; - break; - case SSL_eNULL: - i = SSL_ENC_NULL_IDX; - break; - case SSL_AES128: - i = SSL_ENC_AES128_IDX; - break; - case SSL_AES256: - i = SSL_ENC_AES256_IDX; - break; - case SSL_CAMELLIA128: - i = SSL_ENC_CAMELLIA128_IDX; - break; - case SSL_CAMELLIA256: - i = SSL_ENC_CAMELLIA256_IDX; - break; - case SSL_eGOST2814789CNT: - i = SSL_ENC_GOST89_IDX; - break; - case SSL_SEED: - i = SSL_ENC_SEED_IDX; - break; - case SSL_AES128GCM: - i = SSL_ENC_AES128GCM_IDX; - break; - case SSL_AES256GCM: - i = SSL_ENC_AES256GCM_IDX; - break; - default: - i = -1; - break; - } - - if ((i < 0) || (i >= SSL_ENC_NUM_IDX)) - *enc = NULL; - else { - if (i == SSL_ENC_NULL_IDX) - *enc = EVP_enc_null(); - else - *enc = ssl_cipher_methods[i]; - } - - switch (c->algorithm_mac) { - case SSL_MD5: - i = SSL_MD_MD5_IDX; - break; - case SSL_SHA1: - i = SSL_MD_SHA1_IDX; - break; - case SSL_SHA256: - i = SSL_MD_SHA256_IDX; - break; - case SSL_SHA384: - i = SSL_MD_SHA384_IDX; - break; - case SSL_GOST94: - i = SSL_MD_GOST94_IDX; - break; - case SSL_GOST89MAC: - i = SSL_MD_GOST89MAC_IDX; - break; - default: - i = -1; - break; - } - if ((i < 0) || (i >= SSL_MD_NUM_IDX)) { - *md = NULL; - if (mac_pkey_type != NULL) - *mac_pkey_type = NID_undef; - if (mac_secret_size != NULL) - *mac_secret_size = 0; - if (c->algorithm_mac == SSL_AEAD) - mac_pkey_type = NULL; - } else { - *md = ssl_digest_methods[i]; - if (mac_pkey_type != NULL) - *mac_pkey_type = ssl_mac_pkey_id[i]; - if (mac_secret_size != NULL) - *mac_secret_size = ssl_mac_secret_size[i]; - } - - if ((*enc != NULL) && - (*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)) - && (!mac_pkey_type || *mac_pkey_type != NID_undef)) { - const EVP_CIPHER *evp; - - if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR || - s->ssl_version < TLS1_VERSION) - return 1; - -#ifdef OPENSSL_FIPS - if (FIPS_mode()) - return 1; -#endif - - if (c->algorithm_enc == SSL_RC4 && - c->algorithm_mac == SSL_MD5 && - (evp = EVP_get_cipherbyname("RC4-HMAC-MD5"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES128 && - c->algorithm_mac == SSL_SHA1 && - (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES256 && - c->algorithm_mac == SSL_SHA1 && - (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES128 && - c->algorithm_mac == SSL_SHA256 && - (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA256"))) - *enc = evp, *md = NULL; - else if (c->algorithm_enc == SSL_AES256 && - c->algorithm_mac == SSL_SHA256 && - (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA256"))) - *enc = evp, *md = NULL; - return (1); - } else - return (0); -} - -int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) -{ - if (idx < 0 || idx >= SSL_MD_NUM_IDX) { - return 0; - } - *mask = ssl_handshake_digest_flag[idx]; - if (*mask) - *md = ssl_digest_methods[idx]; - else - *md = NULL; - return 1; -} - -#define ITEM_SEP(a) \ - (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) - -static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, - CIPHER_ORDER **tail) -{ - if (curr == *tail) - return; - if (curr == *head) - *head = curr->next; - if (curr->prev != NULL) - curr->prev->next = curr->next; - if (curr->next != NULL) - curr->next->prev = curr->prev; - (*tail)->next = curr; - curr->prev = *tail; - curr->next = NULL; - *tail = curr; -} - -static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, - CIPHER_ORDER **tail) -{ - if (curr == *head) - return; - if (curr == *tail) - *tail = curr->prev; - if (curr->next != NULL) - curr->next->prev = curr->prev; - if (curr->prev != NULL) - curr->prev->next = curr->next; - (*head)->prev = curr; - curr->next = *head; - curr->prev = NULL; - *head = curr; -} - -static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, - unsigned long *enc, unsigned long *mac, - unsigned long *ssl) -{ - *mkey = 0; - *auth = 0; - *enc = 0; - *mac = 0; - *ssl = 0; - -#ifdef OPENSSL_NO_RSA - *mkey |= SSL_kRSA; - *auth |= SSL_aRSA; -#endif -#ifdef OPENSSL_NO_DSA - *auth |= SSL_aDSS; -#endif -#ifdef OPENSSL_NO_DH - *mkey |= SSL_kDHr | SSL_kDHd | SSL_kEDH; - *auth |= SSL_aDH; -#endif -#ifdef OPENSSL_NO_KRB5 - *mkey |= SSL_kKRB5; - *auth |= SSL_aKRB5; -#endif -#ifdef OPENSSL_NO_ECDSA - *auth |= SSL_aECDSA; -#endif -#ifdef OPENSSL_NO_ECDH - *mkey |= SSL_kECDHe | SSL_kECDHr; - *auth |= SSL_aECDH; -#endif -#ifdef OPENSSL_NO_PSK - *mkey |= SSL_kPSK; - *auth |= SSL_aPSK; -#endif -#ifdef OPENSSL_NO_SRP - *mkey |= SSL_kSRP; -#endif - /* - * Check for presence of GOST 34.10 algorithms, and if they do not - * present, disable appropriate auth and key exchange - */ - if (!get_optional_pkey_id("gost94")) { - *auth |= SSL_aGOST94; - } - if (!get_optional_pkey_id("gost2001")) { - *auth |= SSL_aGOST01; - } - /* - * Disable GOST key exchange if no GOST signature algs are available * - */ - if ((*auth & (SSL_aGOST94 | SSL_aGOST01)) == (SSL_aGOST94 | SSL_aGOST01)) { - *mkey |= SSL_kGOST; - } -#ifdef SSL_FORBID_ENULL - *enc |= SSL_eNULL; -#endif - - *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX] == NULL) ? SSL_DES : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX] == NULL) ? SSL_RC4 : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX] == NULL) ? SSL_RC2 : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128 : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256 : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == - NULL) ? SSL_AES128GCM : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == - NULL) ? SSL_AES256GCM : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == - NULL) ? SSL_CAMELLIA128 : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == - NULL) ? SSL_CAMELLIA256 : 0; - *enc |= - (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == - NULL) ? SSL_eGOST2814789CNT : 0; - *enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED : 0; - - *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX] == NULL) ? SSL_MD5 : 0; - *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1 : 0; - *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256 : 0; - *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384 : 0; - *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94 : 0; - *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL - || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] == - NID_undef) ? SSL_GOST89MAC : 0; - -} - -static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, - int num_of_ciphers, - unsigned long disabled_mkey, - unsigned long disabled_auth, - unsigned long disabled_enc, - unsigned long disabled_mac, - unsigned long disabled_ssl, - CIPHER_ORDER *co_list, - CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p) -{ - int i, co_list_num; - const SSL_CIPHER *c; - - /* - * We have num_of_ciphers descriptions compiled in, depending on the - * method selected (SSLv2 and/or SSLv3, TLSv1 etc). - * These will later be sorted in a linked list with at most num - * entries. - */ - - /* Get the initial list of ciphers */ - co_list_num = 0; /* actual count of ciphers */ - for (i = 0; i < num_of_ciphers; i++) { - c = ssl_method->get_cipher(i); - /* drop those that use any of that is not available */ - if ((c != NULL) && c->valid && -#ifdef OPENSSL_FIPS - (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) && -#endif - !(c->algorithm_mkey & disabled_mkey) && - !(c->algorithm_auth & disabled_auth) && - !(c->algorithm_enc & disabled_enc) && - !(c->algorithm_mac & disabled_mac) && - !(c->algorithm_ssl & disabled_ssl)) { - co_list[co_list_num].cipher = c; - co_list[co_list_num].next = NULL; - co_list[co_list_num].prev = NULL; - co_list[co_list_num].active = 0; - co_list_num++; -#ifdef KSSL_DEBUG - fprintf(stderr, "\t%d: %s %lx %lx %lx\n", i, c->name, c->id, - c->algorithm_mkey, c->algorithm_auth); -#endif /* KSSL_DEBUG */ - /* - * if (!sk_push(ca_list,(char *)c)) goto err; - */ - } - } - - /* - * Prepare linked list from list entries - */ - if (co_list_num > 0) { - co_list[0].prev = NULL; - - if (co_list_num > 1) { - co_list[0].next = &co_list[1]; - - for (i = 1; i < co_list_num - 1; i++) { - co_list[i].prev = &co_list[i - 1]; - co_list[i].next = &co_list[i + 1]; - } - - co_list[co_list_num - 1].prev = &co_list[co_list_num - 2]; - } - - co_list[co_list_num - 1].next = NULL; - - *head_p = &co_list[0]; - *tail_p = &co_list[co_list_num - 1]; - } -} - -static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, - int num_of_group_aliases, - unsigned long disabled_mkey, - unsigned long disabled_auth, - unsigned long disabled_enc, - unsigned long disabled_mac, - unsigned long disabled_ssl, - CIPHER_ORDER *head) -{ - CIPHER_ORDER *ciph_curr; - const SSL_CIPHER **ca_curr; - int i; - unsigned long mask_mkey = ~disabled_mkey; - unsigned long mask_auth = ~disabled_auth; - unsigned long mask_enc = ~disabled_enc; - unsigned long mask_mac = ~disabled_mac; - unsigned long mask_ssl = ~disabled_ssl; - - /* - * First, add the real ciphers as already collected - */ - ciph_curr = head; - ca_curr = ca_list; - while (ciph_curr != NULL) { - *ca_curr = ciph_curr->cipher; - ca_curr++; - ciph_curr = ciph_curr->next; - } - - /* - * Now we add the available ones from the cipher_aliases[] table. - * They represent either one or more algorithms, some of which - * in any affected category must be supported (set in enabled_mask), - * or represent a cipher strength value (will be added in any case because algorithms=0). - */ - for (i = 0; i < num_of_group_aliases; i++) { - unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey; - unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth; - unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc; - unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac; - unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl; - - if (algorithm_mkey) - if ((algorithm_mkey & mask_mkey) == 0) - continue; - - if (algorithm_auth) - if ((algorithm_auth & mask_auth) == 0) - continue; - - if (algorithm_enc) - if ((algorithm_enc & mask_enc) == 0) - continue; - - if (algorithm_mac) - if ((algorithm_mac & mask_mac) == 0) - continue; - - if (algorithm_ssl) - if ((algorithm_ssl & mask_ssl) == 0) - continue; - - *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); - ca_curr++; - } - - *ca_curr = NULL; /* end of list */ -} - -static void ssl_cipher_apply_rule(unsigned long cipher_id, - unsigned long alg_mkey, - unsigned long alg_auth, - unsigned long alg_enc, - unsigned long alg_mac, - unsigned long alg_ssl, - unsigned long algo_strength, int rule, - int strength_bits, CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p) -{ - CIPHER_ORDER *head, *tail, *curr, *next, *last; - const SSL_CIPHER *cp; - int reverse = 0; - -#ifdef CIPHER_DEBUG - fprintf(stderr, - "Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n", - rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, - algo_strength, strength_bits); -#endif - - if (rule == CIPHER_DEL) - reverse = 1; /* needed to maintain sorting between - * currently deleted ciphers */ - - head = *head_p; - tail = *tail_p; - - if (reverse) { - next = tail; - last = head; - } else { - next = head; - last = tail; - } - - curr = NULL; - for (;;) { - if (curr == last) - break; - - curr = next; - - if (curr == NULL) - break; - - next = reverse ? curr->prev : curr->next; - - cp = curr->cipher; - - /* - * Selection criteria is either the value of strength_bits - * or the algorithms used. - */ - if (strength_bits >= 0) { - if (strength_bits != cp->strength_bits) - continue; - } else { -#ifdef CIPHER_DEBUG - fprintf(stderr, - "\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", - cp->name, cp->algorithm_mkey, cp->algorithm_auth, - cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, - cp->algo_strength); -#endif -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (cipher_id && cipher_id != cp->id) - continue; -#endif - if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) - continue; - if (alg_auth && !(alg_auth & cp->algorithm_auth)) - continue; - if (alg_enc && !(alg_enc & cp->algorithm_enc)) - continue; - if (alg_mac && !(alg_mac & cp->algorithm_mac)) - continue; - if (alg_ssl && !(alg_ssl & cp->algorithm_ssl)) - continue; - if ((algo_strength & SSL_EXP_MASK) - && !(algo_strength & SSL_EXP_MASK & cp->algo_strength)) - continue; - if ((algo_strength & SSL_STRONG_MASK) - && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength)) - continue; - if ((algo_strength & SSL_NOT_DEFAULT) - && !(cp->algo_strength & SSL_NOT_DEFAULT)) - continue; - } - -#ifdef CIPHER_DEBUG - fprintf(stderr, "Action = %d\n", rule); -#endif - - /* add the cipher if it has not been added yet. */ - if (rule == CIPHER_ADD) { - /* reverse == 0 */ - if (!curr->active) { - ll_append_tail(&head, curr, &tail); - curr->active = 1; - } - } - /* Move the added cipher to this location */ - else if (rule == CIPHER_ORD) { - /* reverse == 0 */ - if (curr->active) { - ll_append_tail(&head, curr, &tail); - } - } else if (rule == CIPHER_DEL) { - /* reverse == 1 */ - if (curr->active) { - /* - * most recently deleted ciphersuites get best positions for - * any future CIPHER_ADD (note that the CIPHER_DEL loop works - * in reverse to maintain the order) - */ - ll_append_head(&head, curr, &tail); - curr->active = 0; - } - } else if (rule == CIPHER_KILL) { - /* reverse == 0 */ - if (head == curr) - head = curr->next; - else - curr->prev->next = curr->next; - if (tail == curr) - tail = curr->prev; - curr->active = 0; - if (curr->next != NULL) - curr->next->prev = curr->prev; - if (curr->prev != NULL) - curr->prev->next = curr->next; - curr->next = NULL; - curr->prev = NULL; - } - } - - *head_p = head; - *tail_p = tail; -} - -static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p) -{ - int max_strength_bits, i, *number_uses; - CIPHER_ORDER *curr; - - /* - * This routine sorts the ciphers with descending strength. The sorting - * must keep the pre-sorted sequence, so we apply the normal sorting - * routine as '+' movement to the end of the list. - */ - max_strength_bits = 0; - curr = *head_p; - while (curr != NULL) { - if (curr->active && (curr->cipher->strength_bits > max_strength_bits)) - max_strength_bits = curr->cipher->strength_bits; - curr = curr->next; - } - - number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); - if (!number_uses) { - SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE); - return (0); - } - memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); - - /* - * Now find the strength_bits values actually used - */ - curr = *head_p; - while (curr != NULL) { - if (curr->active) - number_uses[curr->cipher->strength_bits]++; - curr = curr->next; - } - /* - * Go through the list of used strength_bits values in descending - * order. - */ - for (i = max_strength_bits; i >= 0; i--) - if (number_uses[i] > 0) - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, - tail_p); - - OPENSSL_free(number_uses); - return (1); -} - -static int ssl_cipher_process_rulestr(const char *rule_str, - CIPHER_ORDER **head_p, - CIPHER_ORDER **tail_p, - const SSL_CIPHER **ca_list) -{ - unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, - algo_strength; - const char *l, *buf; - int j, multi, found, rule, retval, ok, buflen; - unsigned long cipher_id = 0; - char ch; - - retval = 1; - l = rule_str; - for (;;) { - ch = *l; - - if (ch == '\0') - break; /* done */ - if (ch == '-') { - rule = CIPHER_DEL; - l++; - } else if (ch == '+') { - rule = CIPHER_ORD; - l++; - } else if (ch == '!') { - rule = CIPHER_KILL; - l++; - } else if (ch == '@') { - rule = CIPHER_SPECIAL; - l++; - } else { - rule = CIPHER_ADD; - } - - if (ITEM_SEP(ch)) { - l++; - continue; - } - - alg_mkey = 0; - alg_auth = 0; - alg_enc = 0; - alg_mac = 0; - alg_ssl = 0; - algo_strength = 0; - - for (;;) { - ch = *l; - buf = l; - buflen = 0; -#ifndef CHARSET_EBCDIC - while (((ch >= 'A') && (ch <= 'Z')) || - ((ch >= '0') && (ch <= '9')) || - ((ch >= 'a') && (ch <= 'z')) || (ch == '-') || (ch == '.')) -#else - while (isalnum((unsigned char)ch) || (ch == '-') || (ch == '.')) -#endif - { - ch = *(++l); - buflen++; - } - - if (buflen == 0) { - /* - * We hit something we cannot deal with, - * it is no command or separator nor - * alphanumeric, so we call this an error. - */ - SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, - SSL_R_INVALID_COMMAND); - retval = found = 0; - l++; - break; - } - - if (rule == CIPHER_SPECIAL) { - found = 0; /* unused -- avoid compiler warning */ - break; /* special treatment */ - } - - /* check for multi-part specification */ - if (ch == '+') { - multi = 1; - l++; - } else - multi = 0; - - /* - * Now search for the cipher alias in the ca_list. Be careful - * with the strncmp, because the "buflen" limitation - * will make the rule "ADH:SOME" and the cipher - * "ADH-MY-CIPHER" look like a match for buflen=3. - * So additionally check whether the cipher name found - * has the correct length. We can save a strlen() call: - * just checking for the '\0' at the right place is - * sufficient, we have to strncmp() anyway. (We cannot - * use strcmp(), because buf is not '\0' terminated.) - */ - j = found = 0; - cipher_id = 0; - while (ca_list[j]) { - if (!strncmp(buf, ca_list[j]->name, buflen) && - (ca_list[j]->name[buflen] == '\0')) { - found = 1; - break; - } else - j++; - } - - if (!found) - break; /* ignore this entry */ - - if (ca_list[j]->algorithm_mkey) { - if (alg_mkey) { - alg_mkey &= ca_list[j]->algorithm_mkey; - if (!alg_mkey) { - found = 0; - break; - } - } else - alg_mkey = ca_list[j]->algorithm_mkey; - } - - if (ca_list[j]->algorithm_auth) { - if (alg_auth) { - alg_auth &= ca_list[j]->algorithm_auth; - if (!alg_auth) { - found = 0; - break; - } - } else - alg_auth = ca_list[j]->algorithm_auth; - } - - if (ca_list[j]->algorithm_enc) { - if (alg_enc) { - alg_enc &= ca_list[j]->algorithm_enc; - if (!alg_enc) { - found = 0; - break; - } - } else - alg_enc = ca_list[j]->algorithm_enc; - } - - if (ca_list[j]->algorithm_mac) { - if (alg_mac) { - alg_mac &= ca_list[j]->algorithm_mac; - if (!alg_mac) { - found = 0; - break; - } - } else - alg_mac = ca_list[j]->algorithm_mac; - } - - if (ca_list[j]->algo_strength & SSL_EXP_MASK) { - if (algo_strength & SSL_EXP_MASK) { - algo_strength &= - (ca_list[j]->algo_strength & SSL_EXP_MASK) | - ~SSL_EXP_MASK; - if (!(algo_strength & SSL_EXP_MASK)) { - found = 0; - break; - } - } else - algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK; - } - - if (ca_list[j]->algo_strength & SSL_STRONG_MASK) { - if (algo_strength & SSL_STRONG_MASK) { - algo_strength &= - (ca_list[j]->algo_strength & SSL_STRONG_MASK) | - ~SSL_STRONG_MASK; - if (!(algo_strength & SSL_STRONG_MASK)) { - found = 0; - break; - } - } else - algo_strength |= - ca_list[j]->algo_strength & SSL_STRONG_MASK; - } - - if (ca_list[j]->algo_strength & SSL_NOT_DEFAULT) { - algo_strength |= SSL_NOT_DEFAULT; - } - - if (ca_list[j]->valid) { - /* - * explicit ciphersuite found; its protocol version does not - * become part of the search pattern! - */ - - cipher_id = ca_list[j]->id; - } else { - /* - * not an explicit ciphersuite; only in this case, the - * protocol version is considered part of the search pattern - */ - - if (ca_list[j]->algorithm_ssl) { - if (alg_ssl) { - alg_ssl &= ca_list[j]->algorithm_ssl; - if (!alg_ssl) { - found = 0; - break; - } - } else - alg_ssl = ca_list[j]->algorithm_ssl; - } - } - - if (!multi) - break; - } - - /* - * Ok, we have the rule, now apply it - */ - if (rule == CIPHER_SPECIAL) { /* special command */ - ok = 0; - if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) - ok = ssl_cipher_strength_sort(head_p, tail_p); - else - SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, - SSL_R_INVALID_COMMAND); - if (ok == 0) - retval = 0; - /* - * We do not support any "multi" options - * together with "@", so throw away the - * rest of the command, if any left, until - * end or ':' is found. - */ - while ((*l != '\0') && !ITEM_SEP(*l)) - l++; - } else if (found) { - ssl_cipher_apply_rule(cipher_id, - alg_mkey, alg_auth, alg_enc, alg_mac, - alg_ssl, algo_strength, rule, -1, head_p, - tail_p); - } else { - while ((*l != '\0') && !ITEM_SEP(*l)) - l++; - } - if (*l == '\0') - break; /* done */ - } - - return (retval); -} - -#ifndef OPENSSL_NO_EC -static int check_suiteb_cipher_list(const SSL_METHOD *meth, CERT *c, - const char **prule_str) -{ - unsigned int suiteb_flags = 0; -# ifndef OPENSSL_NO_ECDH - unsigned int suiteb_comb2 = 0; -#endif - - if (strncmp(*prule_str, "SUITEB128ONLY", 13) == 0) { - suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS_ONLY; - } else if (strncmp(*prule_str, "SUITEB128C2", 11) == 0) { -# ifndef OPENSSL_NO_ECDH - suiteb_comb2 = 1; -# endif - suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; - } else if (strncmp(*prule_str, "SUITEB128", 9) == 0) { - suiteb_flags = SSL_CERT_FLAG_SUITEB_128_LOS; - } else if (strncmp(*prule_str, "SUITEB192", 9) == 0) { - suiteb_flags = SSL_CERT_FLAG_SUITEB_192_LOS; - } - - if (suiteb_flags) { - c->cert_flags &= ~SSL_CERT_FLAG_SUITEB_128_LOS; - c->cert_flags |= suiteb_flags; - } else - suiteb_flags = c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS; - - if (!suiteb_flags) - return 1; - /* Check version: if TLS 1.2 ciphers allowed we can use Suite B */ - - if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS)) { - if (meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE); - else - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE); - return 0; - } -# ifndef OPENSSL_NO_ECDH - switch (suiteb_flags) { - case SSL_CERT_FLAG_SUITEB_128_LOS: - if (suiteb_comb2) - *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384"; - else - *prule_str = - "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384"; - break; - case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: - *prule_str = "ECDHE-ECDSA-AES128-GCM-SHA256"; - break; - case SSL_CERT_FLAG_SUITEB_192_LOS: - *prule_str = "ECDHE-ECDSA-AES256-GCM-SHA384"; - break; - } - /* Set auto ECDH parameter determination */ - c->ecdh_tmp_auto = 1; - return 1; -# else - SSLerr(SSL_F_CHECK_SUITEB_CIPHER_LIST, - SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE); - return 0; -# endif -} -#endif - -STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER) - **cipher_list, STACK_OF(SSL_CIPHER) - **cipher_list_by_id, - const char *rule_str, CERT *c) -{ - int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; - unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, - disabled_ssl; - STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; - const char *rule_p; - CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; - const SSL_CIPHER **ca_list = NULL; - - /* - * Return with error if nothing to do. - */ - if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) - return NULL; -#ifndef OPENSSL_NO_EC - if (!check_suiteb_cipher_list(ssl_method, c, &rule_str)) - return NULL; -#endif - - /* - * To reduce the work to do we only want to process the compiled - * in algorithms, so we first get the mask of disabled ciphers. - */ - ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, - &disabled_mac, &disabled_ssl); - - /* - * Now we have to collect the available ciphers from the compiled - * in ciphers. We cannot get more than the number compiled in, so - * it is used for allocation. - */ - num_of_ciphers = ssl_method->num_ciphers(); -#ifdef KSSL_DEBUG - fprintf(stderr, "ssl_create_cipher_list() for %d ciphers\n", - num_of_ciphers); -#endif /* KSSL_DEBUG */ - co_list = - (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); - if (co_list == NULL) { - SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - return (NULL); /* Failure */ - } - - ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, - disabled_mkey, disabled_auth, disabled_enc, - disabled_mac, disabled_ssl, co_list, &head, - &tail); - - /* Now arrange all ciphers by preference: */ - - /* - * Everything else being equal, prefer ephemeral ECDH over other key - * exchange mechanisms - */ - ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, - &tail); - ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, - &tail); - - /* AES is our preferred symmetric cipher */ - ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, - &tail); - - /* Temporarily enable everything else for sorting */ - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); - - /* Low priority for MD5 */ - ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, - &tail); - - /* - * Move anonymous ciphers to the end. Usually, these will remain - * disabled. (For applications that allow them, they aren't too bad, but - * we prefer authenticated ciphers.) - */ - ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - - /* Move ciphers without forward secrecy to the end */ - ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - /* - * ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, - * &head, &tail); - */ - ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - ssl_cipher_apply_rule(0, SSL_kKRB5, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - - /* RC4 is sort-of broken -- move the the end */ - ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, - &tail); - - /* - * Now sort by symmetric encryption strength. The above ordering remains - * in force within each class - */ - if (!ssl_cipher_strength_sort(&head, &tail)) { - OPENSSL_free(co_list); - return NULL; - } - - /* Now disable everything (maintaining the ordering!) */ - ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); - - /* - * We also need cipher aliases for selecting based on the rule_str. - * There might be two types of entries in the rule_str: 1) names - * of ciphers themselves 2) aliases for groups of ciphers. - * For 1) we need the available ciphers and for 2) the cipher - * groups of cipher_aliases added together in one list (otherwise - * we would be happy with just the cipher_aliases table). - */ - num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); - num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; - ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); - if (ca_list == NULL) { - OPENSSL_free(co_list); - SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - return (NULL); /* Failure */ - } - ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, - disabled_mkey, disabled_auth, disabled_enc, - disabled_mac, disabled_ssl, head); - - /* - * If the rule_string begins with DEFAULT, apply the default rule - * before using the (possibly available) additional rules. - */ - ok = 1; - rule_p = rule_str; - if (strncmp(rule_str, "DEFAULT", 7) == 0) { - ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, - &head, &tail, ca_list); - rule_p += 7; - if (*rule_p == ':') - rule_p++; - } - - if (ok && (strlen(rule_p) > 0)) - ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); - - OPENSSL_free((void *)ca_list); /* Not needed anymore */ - - if (!ok) { /* Rule processing failure */ - OPENSSL_free(co_list); - return (NULL); - } - - /* - * Allocate new "cipherstack" for the result, return with error - * if we cannot get one. - */ - if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { - OPENSSL_free(co_list); - return (NULL); - } - - /* - * The cipher selection for the list is done. The ciphers are added - * to the resulting precedence to the STACK_OF(SSL_CIPHER). - */ - for (curr = head; curr != NULL; curr = curr->next) { -#ifdef OPENSSL_FIPS - if (curr->active - && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) -#else - if (curr->active) -#endif - { - sk_SSL_CIPHER_push(cipherstack, curr->cipher); -#ifdef CIPHER_DEBUG - fprintf(stderr, "<%s>\n", curr->cipher->name); -#endif - } - } - OPENSSL_free(co_list); /* Not needed any longer */ - - tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack); - if (tmp_cipher_list == NULL) { - sk_SSL_CIPHER_free(cipherstack); - return NULL; - } - if (*cipher_list != NULL) - sk_SSL_CIPHER_free(*cipher_list); - *cipher_list = cipherstack; - if (*cipher_list_by_id != NULL) - sk_SSL_CIPHER_free(*cipher_list_by_id); - *cipher_list_by_id = tmp_cipher_list; - (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, - ssl_cipher_ptr_id_cmp); - - sk_SSL_CIPHER_sort(*cipher_list_by_id); - return (cipherstack); -} - -char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) -{ - int is_export, pkl, kl; - const char *ver, *exp_str; - const char *kx, *au, *enc, *mac; - unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2; -#ifdef KSSL_DEBUG - static const char *format = - "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n"; -#else - static const char *format = - "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; -#endif /* KSSL_DEBUG */ - - alg_mkey = cipher->algorithm_mkey; - alg_auth = cipher->algorithm_auth; - alg_enc = cipher->algorithm_enc; - alg_mac = cipher->algorithm_mac; - alg_ssl = cipher->algorithm_ssl; - - alg2 = cipher->algorithm2; - - is_export = SSL_C_IS_EXPORT(cipher); - pkl = SSL_C_EXPORT_PKEYLENGTH(cipher); - kl = SSL_C_EXPORT_KEYLENGTH(cipher); - exp_str = is_export ? " export" : ""; - - if (alg_ssl & SSL_SSLV2) - ver = "SSLv2"; - else if (alg_ssl & SSL_SSLV3) - ver = "SSLv3"; - else if (alg_ssl & SSL_TLSV1_2) - ver = "TLSv1.2"; - else - ver = "unknown"; - - switch (alg_mkey) { - case SSL_kRSA: - kx = is_export ? (pkl == 512 ? "RSA(512)" : "RSA(1024)") : "RSA"; - break; - case SSL_kDHr: - kx = "DH/RSA"; - break; - case SSL_kDHd: - kx = "DH/DSS"; - break; - case SSL_kKRB5: - kx = "KRB5"; - break; - case SSL_kEDH: - kx = is_export ? (pkl == 512 ? "DH(512)" : "DH(1024)") : "DH"; - break; - case SSL_kECDHr: - kx = "ECDH/RSA"; - break; - case SSL_kECDHe: - kx = "ECDH/ECDSA"; - break; - case SSL_kEECDH: - kx = "ECDH"; - break; - case SSL_kPSK: - kx = "PSK"; - break; - case SSL_kSRP: - kx = "SRP"; - break; - case SSL_kGOST: - kx = "GOST"; - break; - default: - kx = "unknown"; - } - - switch (alg_auth) { - case SSL_aRSA: - au = "RSA"; - break; - case SSL_aDSS: - au = "DSS"; - break; - case SSL_aDH: - au = "DH"; - break; - case SSL_aKRB5: - au = "KRB5"; - break; - case SSL_aECDH: - au = "ECDH"; - break; - case SSL_aNULL: - au = "None"; - break; - case SSL_aECDSA: - au = "ECDSA"; - break; - case SSL_aPSK: - au = "PSK"; - break; - case SSL_aSRP: - au = "SRP"; - break; - case SSL_aGOST94: - au = "GOST94"; - break; - case SSL_aGOST01: - au = "GOST01"; - break; - default: - au = "unknown"; - break; - } - - switch (alg_enc) { - case SSL_DES: - enc = (is_export && kl == 5) ? "DES(40)" : "DES(56)"; - break; - case SSL_3DES: - enc = "3DES(168)"; - break; - case SSL_RC4: - enc = is_export ? (kl == 5 ? "RC4(40)" : "RC4(56)") - : ((alg2 & SSL2_CF_8_BYTE_ENC) ? "RC4(64)" : "RC4(128)"); - break; - case SSL_RC2: - enc = is_export ? (kl == 5 ? "RC2(40)" : "RC2(56)") : "RC2(128)"; - break; - case SSL_IDEA: - enc = "IDEA(128)"; - break; - case SSL_eNULL: - enc = "None"; - break; - case SSL_AES128: - enc = "AES(128)"; - break; - case SSL_AES256: - enc = "AES(256)"; - break; - case SSL_AES128GCM: - enc = "AESGCM(128)"; - break; - case SSL_AES256GCM: - enc = "AESGCM(256)"; - break; - case SSL_CAMELLIA128: - enc = "Camellia(128)"; - break; - case SSL_CAMELLIA256: - enc = "Camellia(256)"; - break; - case SSL_SEED: - enc = "SEED(128)"; - break; - case SSL_eGOST2814789CNT: - enc = "GOST89(256)"; - break; - default: - enc = "unknown"; - break; - } - - switch (alg_mac) { - case SSL_MD5: - mac = "MD5"; - break; - case SSL_SHA1: - mac = "SHA1"; - break; - case SSL_SHA256: - mac = "SHA256"; - break; - case SSL_SHA384: - mac = "SHA384"; - break; - case SSL_AEAD: - mac = "AEAD"; - break; - case SSL_GOST89MAC: - mac = "GOST89"; - break; - case SSL_GOST94: - mac = "GOST94"; - break; - default: - mac = "unknown"; - break; - } - - if (buf == NULL) { - len = 128; - buf = OPENSSL_malloc(len); - if (buf == NULL) - return ("OPENSSL_malloc Error"); - } else if (len < 128) - return ("Buffer too small"); - -#ifdef KSSL_DEBUG - BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac, - exp_str, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl); -#else - BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac, - exp_str); -#endif /* KSSL_DEBUG */ - return (buf); -} - -char *SSL_CIPHER_get_version(const SSL_CIPHER *c) -{ - int i; - - if (c == NULL) - return ("(NONE)"); - i = (int)(c->id >> 24L); - if (i == 3) - return ("TLSv1/SSLv3"); - else if (i == 2) - return ("SSLv2"); - else - return ("unknown"); -} - -/* return the actual cipher being used */ -const char *SSL_CIPHER_get_name(const SSL_CIPHER *c) -{ - if (c != NULL) - return (c->name); - return ("(NONE)"); -} - -/* number of bits for symmetric cipher */ -int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) -{ - int ret = 0; - - if (c != NULL) { - if (alg_bits != NULL) - *alg_bits = c->alg_bits; - ret = c->strength_bits; - } - return (ret); -} - -unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c) -{ - return c->id; -} - -SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) -{ - SSL_COMP *ctmp; - int i, nn; - - if ((n == 0) || (sk == NULL)) - return (NULL); - nn = sk_SSL_COMP_num(sk); - for (i = 0; i < nn; i++) { - ctmp = sk_SSL_COMP_value(sk, i); - if (ctmp->id == n) - return (ctmp); - } - return (NULL); -} - -#ifdef OPENSSL_NO_COMP -STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) -{ - return NULL; -} - -STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) - *meths) -{ - return NULL; -} - -void SSL_COMP_free_compression_methods(void) -{ -} - -int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) -{ - return 1; -} - -const char *SSL_COMP_get_name(const COMP_METHOD *comp) -{ - return NULL; -} -#else -STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) -{ - load_builtin_compressions(); - return (ssl_comp_methods); -} - -STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) - *meths) -{ - STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods; - ssl_comp_methods = meths; - return old_meths; -} - -static void cmeth_free(SSL_COMP *cm) -{ - OPENSSL_free(cm); -} - -void SSL_COMP_free_compression_methods(void) -{ - STACK_OF(SSL_COMP) *old_meths = ssl_comp_methods; - ssl_comp_methods = NULL; - sk_SSL_COMP_pop_free(old_meths, cmeth_free); -} - -int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) -{ - SSL_COMP *comp; - - if (cm == NULL || cm->type == NID_undef) - return 1; - - /*- - * According to draft-ietf-tls-compression-04.txt, the - * compression number ranges should be the following: - * - * 0 to 63: methods defined by the IETF - * 64 to 192: external party methods assigned by IANA - * 193 to 255: reserved for private use - */ - if (id < 193 || id > 255) { - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, - SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); - return 1; - } - - MemCheck_off(); - comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); - if (comp == NULL) { - MemCheck_on(); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); - return 1; - } - comp->id = id; - comp->method = cm; - comp->name = cm->name; - load_builtin_compressions(); - if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) { - OPENSSL_free(comp); - MemCheck_on(); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, - SSL_R_DUPLICATE_COMPRESSION_ID); - return (1); - } else if ((ssl_comp_methods == NULL) - || !sk_SSL_COMP_push(ssl_comp_methods, comp)) { - OPENSSL_free(comp); - MemCheck_on(); - SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); - return (1); - } else { - MemCheck_on(); - return (0); - } -} - -const char *SSL_COMP_get_name(const COMP_METHOD *comp) -{ - if (comp) - return comp->name; - return NULL; -} -#endif -/* For a cipher return the index corresponding to the certificate type */ -int ssl_cipher_get_cert_index(const SSL_CIPHER *c) -{ - unsigned long alg_k, alg_a; - - alg_k = c->algorithm_mkey; - alg_a = c->algorithm_auth; - - if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { - /* - * we don't need to look at SSL_kEECDH since no certificate is needed - * for anon ECDH and for authenticated EECDH, the check for the auth - * algorithm will set i correctly NOTE: For ECDH-RSA, we need an ECC - * not an RSA cert but for EECDH-RSA we need an RSA cert. Placing the - * checks for SSL_kECDH before RSA checks ensures the correct cert is - * chosen. - */ - return SSL_PKEY_ECC; - } else if (alg_a & SSL_aECDSA) - return SSL_PKEY_ECC; - else if (alg_k & SSL_kDHr) - return SSL_PKEY_DH_RSA; - else if (alg_k & SSL_kDHd) - return SSL_PKEY_DH_DSA; - else if (alg_a & SSL_aDSS) - return SSL_PKEY_DSA_SIGN; - else if (alg_a & SSL_aRSA) - return SSL_PKEY_RSA_ENC; - else if (alg_a & SSL_aKRB5) - /* VRS something else here? */ - return -1; - else if (alg_a & SSL_aGOST94) - return SSL_PKEY_GOST94; - else if (alg_a & SSL_aGOST01) - return SSL_PKEY_GOST01; - return -1; -} - -const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr) -{ - const SSL_CIPHER *c; - c = ssl->method->get_cipher_by_char(ptr); - if (c == NULL || c->valid == 0) - return NULL; - return c; -} - -const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr) -{ - return ssl->method->get_cipher_by_char(ptr); -} -/* - * ! \file ssl/ssl_conf.c \brief SSL configuration functions - */ -/* ==================================================================== - * Copyright (c) 2012 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifdef REF_CHECK -# include -#endif -#include -// #include "ssl_locl.h" -#include "conf.h" -// #include "objects.h" -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif - -/* - * structure holding name tables. This is used for pemitted elements in lists - * such as TLSv1 and single command line switches such as no_tls1 - */ - -typedef struct { - const char *name; - int namelen; - unsigned int name_flags; - unsigned long option_value; -} ssl_flag_tbl; - -/* Sense of name is inverted e.g. "TLSv1" will clear SSL_OP_NO_TLSv1 */ -#define SSL_TFLAG_INV 0x1 -/* Flags refers to cert_flags not options */ -#define SSL_TFLAG_CERT 0x2 -/* Option can only be used for clients */ -#define SSL_TFLAG_CLIENT SSL_CONF_FLAG_CLIENT -/* Option can only be used for servers */ -#define SSL_TFLAG_SERVER SSL_CONF_FLAG_SERVER -#define SSL_TFLAG_BOTH (SSL_TFLAG_CLIENT|SSL_TFLAG_SERVER) - -#define SSL_FLAG_TBL(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_BOTH, flag} -#define SSL_FLAG_TBL_SRV(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_SERVER, flag} -#define SSL_FLAG_TBL_CLI(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_CLIENT, flag} -#define SSL_FLAG_TBL_INV(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_BOTH, flag} -#define SSL_FLAG_TBL_SRV_INV(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_INV|SSL_TFLAG_SERVER, flag} -#define SSL_FLAG_TBL_CERT(str, flag) \ - {str, (int)(sizeof(str) - 1), SSL_TFLAG_CERT|SSL_TFLAG_BOTH, flag} - -/* - * Opaque structure containing SSL configuration context. - */ - -struct ssl_conf_ctx_st { - /* - * Various flags indicating (among other things) which options we will - * recognise. - */ - unsigned int flags; - /* Prefix and length of commands */ - char *prefix; - size_t prefixlen; - /* SSL_CTX or SSL structure to perform operations on */ - SSL_CTX *ctx; - SSL *ssl; - /* Pointer to SSL or SSL_CTX options field or NULL if none */ - unsigned long *poptions; - /* Pointer to SSL or SSL_CTX cert_flags or NULL if none */ - unsigned int *pcert_flags; - /* Current flag table being worked on */ - const ssl_flag_tbl *tbl; - /* Size of table */ - size_t ntbl; -}; - -static int ssl_match_option(SSL_CONF_CTX *cctx, const ssl_flag_tbl *tbl, - const char *name, int namelen, int onoff) -{ - /* If name not relevant for context skip */ - if (!(cctx->flags & tbl->name_flags & SSL_TFLAG_BOTH)) - return 0; - if (namelen == -1) { - if (strcmp(tbl->name, name)) - return 0; - } else if (tbl->namelen != namelen - || strncasecmp(tbl->name, name, namelen)) - return 0; - if (cctx->poptions) { - if (tbl->name_flags & SSL_TFLAG_INV) - onoff ^= 1; - if (tbl->name_flags & SSL_TFLAG_CERT) { - if (onoff) - *cctx->pcert_flags |= tbl->option_value; - else - *cctx->pcert_flags &= ~tbl->option_value; - } else { - if (onoff) - *cctx->poptions |= tbl->option_value; - else - *cctx->poptions &= ~tbl->option_value; - } - } - return 1; -} - -static int ssl_set_option_list(const char *elem, int len, void *usr) -{ - SSL_CONF_CTX *cctx = usr; - size_t i; - const ssl_flag_tbl *tbl; - int onoff = 1; - /* - * len == -1 indicates not being called in list context, just for single - * command line switches, so don't allow +, -. - */ - if (elem == NULL) - return 0; - if (len != -1) { - if (*elem == '+') { - elem++; - len--; - onoff = 1; - } else if (*elem == '-') { - elem++; - len--; - onoff = 0; - } - } - for (i = 0, tbl = cctx->tbl; i < cctx->ntbl; i++, tbl++) { - if (ssl_match_option(cctx, tbl, elem, len, onoff)) - return 1; - } - return 0; -} - -/* Single command line switches with no argument e.g. -no_ssl3 */ -static int ctrl_str_option(SSL_CONF_CTX *cctx, const char *cmd) -{ - static const ssl_flag_tbl ssl_option_single[] = { - SSL_FLAG_TBL("no_ssl2", SSL_OP_NO_SSLv2), - SSL_FLAG_TBL("no_ssl3", SSL_OP_NO_SSLv3), - SSL_FLAG_TBL("no_tls1", SSL_OP_NO_TLSv1), - SSL_FLAG_TBL("no_tls1_1", SSL_OP_NO_TLSv1_1), - SSL_FLAG_TBL("no_tls1_2", SSL_OP_NO_TLSv1_2), - SSL_FLAG_TBL("bugs", SSL_OP_ALL), - SSL_FLAG_TBL("no_comp", SSL_OP_NO_COMPRESSION), - SSL_FLAG_TBL_SRV("ecdh_single", SSL_OP_SINGLE_ECDH_USE), -#ifndef OPENSSL_NO_TLSEXT - SSL_FLAG_TBL("no_ticket", SSL_OP_NO_TICKET), -#endif - SSL_FLAG_TBL_SRV("serverpref", SSL_OP_CIPHER_SERVER_PREFERENCE), - SSL_FLAG_TBL("legacy_renegotiation", - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), - SSL_FLAG_TBL_SRV("legacy_server_connect", - SSL_OP_LEGACY_SERVER_CONNECT), - SSL_FLAG_TBL_SRV("no_resumption_on_reneg", - SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), - SSL_FLAG_TBL_SRV_INV("no_legacy_server_connect", - SSL_OP_LEGACY_SERVER_CONNECT), - SSL_FLAG_TBL_CERT("strict", SSL_CERT_FLAG_TLS_STRICT), -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - SSL_FLAG_TBL_CERT("debug_broken_protocol", - SSL_CERT_FLAG_BROKEN_PROTOCOL), -#endif - }; - cctx->tbl = ssl_option_single; - cctx->ntbl = sizeof(ssl_option_single) / sizeof(ssl_flag_tbl); - return ssl_set_option_list(cmd, -1, cctx); -} - -/* Set supported signature algorithms */ -static int cmd_SignatureAlgorithms(SSL_CONF_CTX *cctx, const char *value) -{ - int rv; - if (cctx->ssl) - rv = SSL_set1_sigalgs_list(cctx->ssl, value); - /* NB: ctx == NULL performs syntax checking only */ - else - rv = SSL_CTX_set1_sigalgs_list(cctx->ctx, value); - return rv > 0; -} - -/* Set supported client signature algorithms */ -static int cmd_ClientSignatureAlgorithms(SSL_CONF_CTX *cctx, - const char *value) -{ - int rv; - if (cctx->ssl) - rv = SSL_set1_client_sigalgs_list(cctx->ssl, value); - /* NB: ctx == NULL performs syntax checking only */ - else - rv = SSL_CTX_set1_client_sigalgs_list(cctx->ctx, value); - return rv > 0; -} - -static int cmd_Curves(SSL_CONF_CTX *cctx, const char *value) -{ - int rv; - if (cctx->ssl) - rv = SSL_set1_curves_list(cctx->ssl, value); - /* NB: ctx == NULL performs syntax checking only */ - else - rv = SSL_CTX_set1_curves_list(cctx->ctx, value); - return rv > 0; -} - -#ifndef OPENSSL_NO_ECDH -/* ECDH temporary parameters */ -static int cmd_ECDHParameters(SSL_CONF_CTX *cctx, const char *value) -{ - int onoff = -1, rv = 1; - if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) - return -2; - if (cctx->flags & SSL_CONF_FLAG_FILE) { - if (*value == '+') { - onoff = 1; - value++; - } - if (*value == '-') { - onoff = 0; - value++; - } - if (!strcasecmp(value, "automatic")) { - if (onoff == -1) - onoff = 1; - } else if (onoff != -1) - return 0; - } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { - if (!strcmp(value, "auto")) - onoff = 1; - } - - if (onoff != -1) { - if (cctx->ctx) - rv = SSL_CTX_set_ecdh_auto(cctx->ctx, onoff); - else if (cctx->ssl) - rv = SSL_set_ecdh_auto(cctx->ssl, onoff); - } else { - EC_KEY *ecdh; - int nid; - nid = EC_curve_nist2nid(value); - if (nid == NID_undef) - nid = OBJ_sn2nid(value); - if (nid == 0) - return 0; - ecdh = EC_KEY_new_by_curve_name(nid); - if (!ecdh) - return 0; - if (cctx->ctx) - rv = SSL_CTX_set_tmp_ecdh(cctx->ctx, ecdh); - else if (cctx->ssl) - rv = SSL_set_tmp_ecdh(cctx->ssl, ecdh); - EC_KEY_free(ecdh); - } - - return rv > 0; -} -#endif -static int cmd_CipherString(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 1; - if (cctx->ctx) - rv = SSL_CTX_set_cipher_list(cctx->ctx, value); - if (cctx->ssl) - rv = SSL_set_cipher_list(cctx->ssl, value); - return rv > 0; -} - -static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) -{ - static const ssl_flag_tbl ssl_protocol_list[] = { - SSL_FLAG_TBL_INV("ALL", SSL_OP_NO_SSL_MASK), - SSL_FLAG_TBL_INV("SSLv2", SSL_OP_NO_SSLv2), - SSL_FLAG_TBL_INV("SSLv3", SSL_OP_NO_SSLv3), - SSL_FLAG_TBL_INV("TLSv1", SSL_OP_NO_TLSv1), - SSL_FLAG_TBL_INV("TLSv1.1", SSL_OP_NO_TLSv1_1), - SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2) - }; - int ret; - int sslv2off; - - if (!(cctx->flags & SSL_CONF_FLAG_FILE)) - return -2; - cctx->tbl = ssl_protocol_list; - cctx->ntbl = sizeof(ssl_protocol_list) / sizeof(ssl_flag_tbl); - - sslv2off = *cctx->poptions & SSL_OP_NO_SSLv2; - ret = CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); - /* Never turn on SSLv2 through configuration */ - *cctx->poptions |= sslv2off; - return ret; -} - -static int cmd_Options(SSL_CONF_CTX *cctx, const char *value) -{ - static const ssl_flag_tbl ssl_option_list[] = { - SSL_FLAG_TBL_INV("SessionTicket", SSL_OP_NO_TICKET), - SSL_FLAG_TBL_INV("EmptyFragments", - SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS), - SSL_FLAG_TBL("Bugs", SSL_OP_ALL), - SSL_FLAG_TBL_INV("Compression", SSL_OP_NO_COMPRESSION), - SSL_FLAG_TBL_SRV("ServerPreference", SSL_OP_CIPHER_SERVER_PREFERENCE), - SSL_FLAG_TBL_SRV("NoResumptionOnRenegotiation", - SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION), - SSL_FLAG_TBL_SRV("DHSingle", SSL_OP_SINGLE_DH_USE), - SSL_FLAG_TBL_SRV("ECDHSingle", SSL_OP_SINGLE_ECDH_USE), - SSL_FLAG_TBL("UnsafeLegacyRenegotiation", - SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION), - }; - if (!(cctx->flags & SSL_CONF_FLAG_FILE)) - return -2; - if (value == NULL) - return -3; - cctx->tbl = ssl_option_list; - cctx->ntbl = sizeof(ssl_option_list) / sizeof(ssl_flag_tbl); - return CONF_parse_list(value, ',', 1, ssl_set_option_list, cctx); -} - -static int cmd_Certificate(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 1; - if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) - return -2; - if (cctx->ctx) - rv = SSL_CTX_use_certificate_chain_file(cctx->ctx, value); - if (cctx->ssl) - rv = SSL_use_certificate_file(cctx->ssl, value, SSL_FILETYPE_PEM); - return rv > 0; -} - -static int cmd_PrivateKey(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 1; - if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) - return -2; - if (cctx->ctx) - rv = SSL_CTX_use_PrivateKey_file(cctx->ctx, value, SSL_FILETYPE_PEM); - if (cctx->ssl) - rv = SSL_use_PrivateKey_file(cctx->ssl, value, SSL_FILETYPE_PEM); - return rv > 0; -} - -static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 1; - if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) - return -2; - if (!(cctx->flags & SSL_CONF_FLAG_SERVER)) - return -2; - if (cctx->ctx) - rv = SSL_CTX_use_serverinfo_file(cctx->ctx, value); - return rv > 0; -} - -#ifndef OPENSSL_NO_DH -static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value) -{ - int rv = 0; - DH *dh = NULL; - BIO *in = NULL; - if (!(cctx->flags & SSL_CONF_FLAG_CERTIFICATE)) - return -2; - if (cctx->ctx || cctx->ssl) { - in = BIO_new(BIO_s_file_internal()); - if (!in) - goto end; - if (BIO_read_filename(in, value) <= 0) - goto end; - dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); - if (!dh) - goto end; - } else - return 1; - if (cctx->ctx) - rv = SSL_CTX_set_tmp_dh(cctx->ctx, dh); - if (cctx->ssl) - rv = SSL_set_tmp_dh(cctx->ssl, dh); - end: - if (dh) - DH_free(dh); - if (in) - BIO_free(in); - return rv > 0; -} -#endif -typedef struct { - int (*cmd) (SSL_CONF_CTX *cctx, const char *value); - const char *str_file; - const char *str_cmdline; - unsigned int value_type; -} ssl_conf_cmd_tbl; - -/* Table of supported parameters */ - -#define SSL_CONF_CMD(name, cmdopt, type) \ - {cmd_##name, #name, cmdopt, type} - -#define SSL_CONF_CMD_STRING(name, cmdopt) \ - SSL_CONF_CMD(name, cmdopt, SSL_CONF_TYPE_STRING) - -static const ssl_conf_cmd_tbl ssl_conf_cmds[] = { - SSL_CONF_CMD_STRING(SignatureAlgorithms, "sigalgs"), - SSL_CONF_CMD_STRING(ClientSignatureAlgorithms, "client_sigalgs"), - SSL_CONF_CMD_STRING(Curves, "curves"), -#ifndef OPENSSL_NO_ECDH - SSL_CONF_CMD_STRING(ECDHParameters, "named_curve"), -#endif - SSL_CONF_CMD_STRING(CipherString, "cipher"), - SSL_CONF_CMD_STRING(Protocol, NULL), - SSL_CONF_CMD_STRING(Options, NULL), - SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE), - SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE), - SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE), -#ifndef OPENSSL_NO_DH - SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE) -#endif -}; - -static int ssl_conf_cmd_skip_prefix(SSL_CONF_CTX *cctx, const char **pcmd) -{ - if (!pcmd || !*pcmd) - return 0; - /* If a prefix is set, check and skip */ - if (cctx->prefix) { - if (strlen(*pcmd) <= cctx->prefixlen) - return 0; - if (cctx->flags & SSL_CONF_FLAG_CMDLINE && - strncmp(*pcmd, cctx->prefix, cctx->prefixlen)) - return 0; - if (cctx->flags & SSL_CONF_FLAG_FILE && - strncasecmp(*pcmd, cctx->prefix, cctx->prefixlen)) - return 0; - *pcmd += cctx->prefixlen; - } else if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { - if (**pcmd != '-' || !(*pcmd)[1]) - return 0; - *pcmd += 1; - } - return 1; -} - -static const ssl_conf_cmd_tbl *ssl_conf_cmd_lookup(SSL_CONF_CTX *cctx, - const char *cmd) -{ - const ssl_conf_cmd_tbl *t; - size_t i; - if (cmd == NULL) - return NULL; - - /* Look for matching parameter name in table */ - for (i = 0, t = ssl_conf_cmds; - i < sizeof(ssl_conf_cmds) / sizeof(ssl_conf_cmd_tbl); i++, t++) { - if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { - if (t->str_cmdline && !strcmp(t->str_cmdline, cmd)) - return t; - } - if (cctx->flags & SSL_CONF_FLAG_FILE) { - if (t->str_file && !strcasecmp(t->str_file, cmd)) - return t; - } - } - return NULL; -} - -int SSL_CONF_cmd(SSL_CONF_CTX *cctx, const char *cmd, const char *value) -{ - const ssl_conf_cmd_tbl *runcmd; - if (cmd == NULL) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_INVALID_NULL_CMD_NAME); - return 0; - } - - if (!ssl_conf_cmd_skip_prefix(cctx, &cmd)) - return -2; - - runcmd = ssl_conf_cmd_lookup(cctx, cmd); - - if (runcmd) { - int rv; - if (value == NULL) - return -3; - rv = runcmd->cmd(cctx, value); - if (rv > 0) - return 2; - if (rv == -2) - return -2; - if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_BAD_VALUE); - ERR_add_error_data(4, "cmd=", cmd, ", value=", value); - } - return 0; - } - - if (cctx->flags & SSL_CONF_FLAG_CMDLINE) { - if (ctrl_str_option(cctx, cmd)) - return 1; - } - - if (cctx->flags & SSL_CONF_FLAG_SHOW_ERRORS) { - SSLerr(SSL_F_SSL_CONF_CMD, SSL_R_UNKNOWN_CMD_NAME); - ERR_add_error_data(2, "cmd=", cmd); - } - - return -2; -} - -int SSL_CONF_cmd_argv(SSL_CONF_CTX *cctx, int *pargc, char ***pargv) -{ - int rv; - const char *arg = NULL, *argn; - if (pargc && *pargc == 0) - return 0; - if (!pargc || *pargc > 0) - arg = **pargv; - if (arg == NULL) - return 0; - if (!pargc || *pargc > 1) - argn = (*pargv)[1]; - else - argn = NULL; - cctx->flags &= ~SSL_CONF_FLAG_FILE; - cctx->flags |= SSL_CONF_FLAG_CMDLINE; - rv = SSL_CONF_cmd(cctx, arg, argn); - if (rv > 0) { - /* Success: update pargc, pargv */ - (*pargv) += rv; - if (pargc) - (*pargc) -= rv; - return rv; - } - /* Unknown switch: indicate no arguments processed */ - if (rv == -2) - return 0; - /* Some error occurred processing command, return fatal error */ - if (rv == 0) - return -1; - return rv; -} - -int SSL_CONF_cmd_value_type(SSL_CONF_CTX *cctx, const char *cmd) -{ - if (ssl_conf_cmd_skip_prefix(cctx, &cmd)) { - const ssl_conf_cmd_tbl *runcmd; - runcmd = ssl_conf_cmd_lookup(cctx, cmd); - if (runcmd) - return runcmd->value_type; - } - return SSL_CONF_TYPE_UNKNOWN; -} - -SSL_CONF_CTX *SSL_CONF_CTX_new(void) -{ - SSL_CONF_CTX *ret; - ret = OPENSSL_malloc(sizeof(SSL_CONF_CTX)); - if (ret) { - ret->flags = 0; - ret->prefix = NULL; - ret->prefixlen = 0; - ret->ssl = NULL; - ret->ctx = NULL; - ret->poptions = NULL; - ret->pcert_flags = NULL; - ret->tbl = NULL; - ret->ntbl = 0; - } - return ret; -} - -int SSL_CONF_CTX_finish(SSL_CONF_CTX *cctx) -{ - return 1; -} - -void SSL_CONF_CTX_free(SSL_CONF_CTX *cctx) -{ - if (cctx) { - if (cctx->prefix) - OPENSSL_free(cctx->prefix); - OPENSSL_free(cctx); - } -} - -unsigned int SSL_CONF_CTX_set_flags(SSL_CONF_CTX *cctx, unsigned int flags) -{ - cctx->flags |= flags; - return cctx->flags; -} - -unsigned int SSL_CONF_CTX_clear_flags(SSL_CONF_CTX *cctx, unsigned int flags) -{ - cctx->flags &= ~flags; - return cctx->flags; -} - -int SSL_CONF_CTX_set1_prefix(SSL_CONF_CTX *cctx, const char *pre) -{ - char *tmp = NULL; - if (pre) { - tmp = BUF_strdup(pre); - if (tmp == NULL) - return 0; - } - if (cctx->prefix) - OPENSSL_free(cctx->prefix); - cctx->prefix = tmp; - if (tmp) - cctx->prefixlen = strlen(tmp); - else - cctx->prefixlen = 0; - return 1; -} - -void SSL_CONF_CTX_set_ssl(SSL_CONF_CTX *cctx, SSL *ssl) -{ - cctx->ssl = ssl; - cctx->ctx = NULL; - if (ssl) { - cctx->poptions = &ssl->options; - cctx->pcert_flags = &ssl->cert->cert_flags; - } else { - cctx->poptions = NULL; - cctx->pcert_flags = NULL; - } -} - -void SSL_CONF_CTX_set_ssl_ctx(SSL_CONF_CTX *cctx, SSL_CTX *ctx) -{ - cctx->ctx = ctx; - cctx->ssl = NULL; - if (ctx) { - cctx->poptions = &ctx->options; - cctx->pcert_flags = &ctx->cert->cert_flags; - } else { - cctx->poptions = NULL; - cctx->pcert_flags = NULL; - } -} -/* ssl/ssl_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "ssl.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason) - -static ERR_STRING_DATA SSL_str_functs[] = { - {ERR_FUNC(SSL_F_CHECK_SUITEB_CIPHER_LIST), "CHECK_SUITEB_CIPHER_LIST"}, - {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"}, - {ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"}, - {ERR_FUNC(SSL_F_CLIENT_HELLO), "CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_CLIENT_MASTER_KEY), "CLIENT_MASTER_KEY"}, - {ERR_FUNC(SSL_F_D2I_SSL_SESSION), "d2i_SSL_SESSION"}, - {ERR_FUNC(SSL_F_DO_DTLS1_WRITE), "do_dtls1_write"}, - {ERR_FUNC(SSL_F_DO_SSL3_WRITE), "DO_SSL3_WRITE"}, - {ERR_FUNC(SSL_F_DTLS1_ACCEPT), "dtls1_accept"}, - {ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"}, - {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"}, - {ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "dtls1_check_timeout_num"}, - {ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "dtls1_client_hello"}, - {ERR_FUNC(SSL_F_DTLS1_CONNECT), "dtls1_connect"}, - {ERR_FUNC(SSL_F_DTLS1_GET_HELLO_VERIFY), "DTLS1_GET_HELLO_VERIFY"}, - {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE), "dtls1_get_message"}, - {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), - "DTLS1_GET_MESSAGE_FRAGMENT"}, - {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "dtls1_get_record"}, - {ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "dtls1_handle_timeout"}, - {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"}, - {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "dtls1_output_cert_chain"}, - {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, - {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), - "DTLS1_PROCESS_BUFFERED_RECORDS"}, - {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), - "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, - {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, - {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "dtls1_read_bytes"}, - {ERR_FUNC(SSL_F_DTLS1_READ_FAILED), "dtls1_read_failed"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST), - "dtls1_send_certificate_request"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE), - "dtls1_send_client_certificate"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE), - "dtls1_send_client_key_exchange"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_VERIFY), "dtls1_send_client_verify"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST), - "DTLS1_SEND_HELLO_VERIFY_REQUEST"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE), - "dtls1_send_server_certificate"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_HELLO), "dtls1_send_server_hello"}, - {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE), - "dtls1_send_server_key_exchange"}, - {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES), - "dtls1_write_app_data_bytes"}, - {ERR_FUNC(SSL_F_GET_CLIENT_FINISHED), "GET_CLIENT_FINISHED"}, - {ERR_FUNC(SSL_F_GET_CLIENT_HELLO), "GET_CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_GET_CLIENT_MASTER_KEY), "GET_CLIENT_MASTER_KEY"}, - {ERR_FUNC(SSL_F_GET_SERVER_FINISHED), "GET_SERVER_FINISHED"}, - {ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"}, - {ERR_FUNC(SSL_F_GET_SERVER_STATIC_DH_KEY), "GET_SERVER_STATIC_DH_KEY"}, - {ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"}, - {ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"}, - {ERR_FUNC(SSL_F_READ_N), "READ_N"}, - {ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"}, - {ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"}, - {ERR_FUNC(SSL_F_SERVER_HELLO), "SERVER_HELLO"}, - {ERR_FUNC(SSL_F_SERVER_VERIFY), "SERVER_VERIFY"}, - {ERR_FUNC(SSL_F_SSL23_ACCEPT), "ssl23_accept"}, - {ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO), "SSL23_CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_CONNECT), "ssl23_connect"}, - {ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO), "SSL23_GET_CLIENT_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO), "SSL23_GET_SERVER_HELLO"}, - {ERR_FUNC(SSL_F_SSL23_PEEK), "ssl23_peek"}, - {ERR_FUNC(SSL_F_SSL23_READ), "ssl23_read"}, - {ERR_FUNC(SSL_F_SSL23_WRITE), "ssl23_write"}, - {ERR_FUNC(SSL_F_SSL2_ACCEPT), "ssl2_accept"}, - {ERR_FUNC(SSL_F_SSL2_CONNECT), "ssl2_connect"}, - {ERR_FUNC(SSL_F_SSL2_ENC_INIT), "ssl2_enc_init"}, - {ERR_FUNC(SSL_F_SSL2_GENERATE_KEY_MATERIAL), - "ssl2_generate_key_material"}, - {ERR_FUNC(SSL_F_SSL2_PEEK), "ssl2_peek"}, - {ERR_FUNC(SSL_F_SSL2_READ), "ssl2_read"}, - {ERR_FUNC(SSL_F_SSL2_READ_INTERNAL), "SSL2_READ_INTERNAL"}, - {ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE), "ssl2_set_certificate"}, - {ERR_FUNC(SSL_F_SSL2_WRITE), "ssl2_write"}, - {ERR_FUNC(SSL_F_SSL3_ACCEPT), "ssl3_accept"}, - {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, - {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "ssl3_callback_ctrl"}, - {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "ssl3_change_cipher_state"}, - {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), - "ssl3_check_cert_and_algorithm"}, - {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "ssl3_check_client_hello"}, - {ERR_FUNC(SSL_F_SSL3_CHECK_FINISHED), "SSL3_CHECK_FINISHED"}, - {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "ssl3_client_hello"}, - {ERR_FUNC(SSL_F_SSL3_CONNECT), "ssl3_connect"}, - {ERR_FUNC(SSL_F_SSL3_CTRL), "ssl3_ctrl"}, - {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "ssl3_ctx_ctrl"}, - {ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS), - "ssl3_digest_cached_records"}, - {ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), - "ssl3_do_change_cipher_spec"}, - {ERR_FUNC(SSL_F_SSL3_ENC), "ssl3_enc"}, - {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, - {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET), - "ssl3_generate_master_secret"}, - {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), - "ssl3_get_certificate_request"}, - {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "ssl3_get_cert_status"}, - {ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "ssl3_get_cert_verify"}, - {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE), - "ssl3_get_client_certificate"}, - {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "ssl3_get_client_hello"}, - {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE), - "ssl3_get_client_key_exchange"}, - {ERR_FUNC(SSL_F_SSL3_GET_FINISHED), "ssl3_get_finished"}, - {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE), "ssl3_get_key_exchange"}, - {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE), "ssl3_get_message"}, - {ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET), - "ssl3_get_new_session_ticket"}, - {ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO), "ssl3_get_next_proto"}, - {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "SSL3_GET_RECORD"}, - {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE), - "ssl3_get_server_certificate"}, - {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "ssl3_get_server_done"}, - {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO), "ssl3_get_server_hello"}, - {ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC), "ssl3_handshake_mac"}, - {ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET), "SSL3_NEW_SESSION_TICKET"}, - {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "ssl3_output_cert_chain"}, - {ERR_FUNC(SSL_F_SSL3_PEEK), "ssl3_peek"}, - {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "ssl3_read_bytes"}, - {ERR_FUNC(SSL_F_SSL3_READ_N), "ssl3_read_n"}, - {ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST), - "ssl3_send_certificate_request"}, - {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE), - "ssl3_send_client_certificate"}, - {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE), - "ssl3_send_client_key_exchange"}, - {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "ssl3_send_client_verify"}, - {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE), - "ssl3_send_server_certificate"}, - {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO), "ssl3_send_server_hello"}, - {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE), - "ssl3_send_server_key_exchange"}, - {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "ssl3_setup_key_block"}, - {ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER), "ssl3_setup_read_buffer"}, - {ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "ssl3_setup_write_buffer"}, - {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "ssl3_write_bytes"}, - {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "ssl3_write_pending"}, - {ERR_FUNC(SSL_F_SSL_ADD_CERT_CHAIN), "ssl_add_cert_chain"}, - {ERR_FUNC(SSL_F_SSL_ADD_CERT_TO_BUF), "SSL_ADD_CERT_TO_BUF"}, - {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), - "ssl_add_clienthello_renegotiate_ext"}, - {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), - "ssl_add_clienthello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT), - "ssl_add_clienthello_use_srtp_ext"}, - {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), - "SSL_add_dir_cert_subjects_to_stack"}, - {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), - "SSL_add_file_cert_subjects_to_stack"}, - {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT), - "ssl_add_serverhello_renegotiate_ext"}, - {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), - "ssl_add_serverhello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT), - "ssl_add_serverhello_use_srtp_ext"}, - {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "ssl_bad_method"}, - {ERR_FUNC(SSL_F_SSL_BUILD_CERT_CHAIN), "ssl_build_cert_chain"}, - {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "ssl_bytes_to_cipher_list"}, - {ERR_FUNC(SSL_F_SSL_CERT_DUP), "ssl_cert_dup"}, - {ERR_FUNC(SSL_F_SSL_CERT_INST), "ssl_cert_inst"}, - {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE), "SSL_CERT_INSTANTIATE"}, - {ERR_FUNC(SSL_F_SSL_CERT_NEW), "ssl_cert_new"}, - {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"}, - {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT), - "SSL_CHECK_SERVERHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG), - "ssl_check_srvr_ecc_cert_and_alg"}, - {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR), - "SSL_CIPHER_PROCESS_RULESTR"}, - {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"}, - {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"}, - {ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD), - "SSL_COMP_add_compression_method"}, - {ERR_FUNC(SSL_F_SSL_CONF_CMD), "SSL_CONF_cmd"}, - {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "ssl_create_cipher_list"}, - {ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"}, - {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"}, - {ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES), "SSL_CTX_MAKE_PROFILES"}, - {ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE), - "SSL_CTX_set_client_cert_engine"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE), "SSL_CTX_set_purpose"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), - "SSL_CTX_set_session_id_context"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"}, - {ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST), "SSL_CTX_set_trust"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1), - "SSL_CTX_use_certificate_ASN1"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE), - "SSL_CTX_use_certificate_chain_file"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE), - "SSL_CTX_use_certificate_file"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1), - "SSL_CTX_use_PrivateKey_ASN1"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE), - "SSL_CTX_use_PrivateKey_file"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT), - "SSL_CTX_use_psk_identity_hint"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY), "SSL_CTX_use_RSAPrivateKey"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1), - "SSL_CTX_use_RSAPrivateKey_ASN1"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE), - "SSL_CTX_use_RSAPrivateKey_file"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_SERVERINFO), "SSL_CTX_use_serverinfo"}, - {ERR_FUNC(SSL_F_SSL_CTX_USE_SERVERINFO_FILE), - "SSL_CTX_use_serverinfo_file"}, - {ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE), "SSL_do_handshake"}, - {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "ssl_get_new_session"}, - {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "ssl_get_prev_session"}, - {ERR_FUNC(SSL_F_SSL_GET_SERVER_CERT_INDEX), "SSL_GET_SERVER_CERT_INDEX"}, - {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"}, - {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "ssl_get_server_send_pkey"}, - {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "ssl_get_sign_pkey"}, - {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "ssl_init_wbio_buffer"}, - {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, - {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"}, - {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT), - "ssl_parse_clienthello_renegotiate_ext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), - "ssl_parse_clienthello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT), - "ssl_parse_clienthello_use_srtp_ext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT), - "ssl_parse_serverhello_renegotiate_ext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), - "ssl_parse_serverhello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT), - "ssl_parse_serverhello_use_srtp_ext"}, - {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"}, - {ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT), - "ssl_prepare_clienthello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT), - "ssl_prepare_serverhello_tlsext"}, - {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, - {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, - {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, - {ERR_FUNC(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT), - "SSL_SCAN_CLIENTHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT), - "SSL_SCAN_SERVERHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"}, - {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"}, - {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, - {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), - "SSL_SESSION_set1_id_context"}, - {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "ssl_sess_cert_new"}, - {ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"}, - {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"}, - {ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"}, - {ERR_FUNC(SSL_F_SSL_SET_PKEY), "SSL_SET_PKEY"}, - {ERR_FUNC(SSL_F_SSL_SET_PURPOSE), "SSL_set_purpose"}, - {ERR_FUNC(SSL_F_SSL_SET_RFD), "SSL_set_rfd"}, - {ERR_FUNC(SSL_F_SSL_SET_SESSION), "SSL_set_session"}, - {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT), - "SSL_set_session_id_context"}, - {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), - "SSL_set_session_ticket_ext"}, - {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, - {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, - {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, - {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"}, - {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), - "ssl_undefined_const_function"}, - {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "ssl_undefined_function"}, - {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), - "ssl_undefined_void_function"}, - {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"}, - {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"}, - {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"}, - {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY), "SSL_use_PrivateKey"}, - {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1), "SSL_use_PrivateKey_ASN1"}, - {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE), "SSL_use_PrivateKey_file"}, - {ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT), "SSL_use_psk_identity_hint"}, - {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY), "SSL_use_RSAPrivateKey"}, - {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1), - "SSL_use_RSAPrivateKey_ASN1"}, - {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE), - "SSL_use_RSAPrivateKey_file"}, - {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "ssl_verify_cert_chain"}, - {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, - {ERR_FUNC(SSL_F_TLS12_CHECK_PEER_SIGALG), "tls12_check_peer_sigalg"}, - {ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"}, - {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "tls1_change_cipher_state"}, - {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), - "TLS1_CHECK_SERVERHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_TLS1_ENC), "tls1_enc"}, - {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), - "tls1_export_keying_material"}, - {ERR_FUNC(SSL_F_TLS1_GET_CURVELIST), "TLS1_GET_CURVELIST"}, - {ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "tls1_heartbeat"}, - {ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), - "TLS1_PREPARE_CLIENTHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), - "TLS1_PREPARE_SERVERHELLO_TLSEXT"}, - {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, - {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "tls1_setup_key_block"}, - {ERR_FUNC(SSL_F_TLS1_SET_SERVER_SIGALGS), "tls1_set_server_sigalgs"}, - {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, - {0, NULL} -}; - -static ERR_STRING_DATA SSL_str_reasons[] = { - {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE), "app data in handshake"}, - {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), - "attempt to reuse session in different context"}, - {ERR_REASON(SSL_R_BAD_ALERT_RECORD), "bad alert record"}, - {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"}, - {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"}, - {ERR_REASON(SSL_R_BAD_CHECKSUM), "bad checksum"}, - {ERR_REASON(SSL_R_BAD_DATA), "bad data"}, - {ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), - "bad data returned by callback"}, - {ERR_REASON(SSL_R_BAD_DECOMPRESSION), "bad decompression"}, - {ERR_REASON(SSL_R_BAD_DH_G_LENGTH), "bad dh g length"}, - {ERR_REASON(SSL_R_BAD_DH_G_VALUE), "bad dh g value"}, - {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH), "bad dh pub key length"}, - {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"}, - {ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"}, - {ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"}, - {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"}, - {ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"}, - {ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"}, - {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE), "bad ecdsa signature"}, - {ERR_REASON(SSL_R_BAD_ECPOINT), "bad ecpoint"}, - {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH), "bad handshake length"}, - {ERR_REASON(SSL_R_BAD_HELLO_REQUEST), "bad hello request"}, - {ERR_REASON(SSL_R_BAD_LENGTH), "bad length"}, - {ERR_REASON(SSL_R_BAD_MAC_DECODE), "bad mac decode"}, - {ERR_REASON(SSL_R_BAD_MAC_LENGTH), "bad mac length"}, - {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE), "bad message type"}, - {ERR_REASON(SSL_R_BAD_PACKET_LENGTH), "bad packet length"}, - {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), - "bad protocol version number"}, - {ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH), - "bad psk identity hint length"}, - {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT), "bad response argument"}, - {ERR_REASON(SSL_R_BAD_RSA_DECRYPT), "bad rsa decrypt"}, - {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT), "bad rsa encrypt"}, - {ERR_REASON(SSL_R_BAD_RSA_E_LENGTH), "bad rsa e length"}, - {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"}, - {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE), "bad rsa signature"}, - {ERR_REASON(SSL_R_BAD_SIGNATURE), "bad signature"}, - {ERR_REASON(SSL_R_BAD_SRP_A_LENGTH), "bad srp a length"}, - {ERR_REASON(SSL_R_BAD_SRP_B_LENGTH), "bad srp b length"}, - {ERR_REASON(SSL_R_BAD_SRP_G_LENGTH), "bad srp g length"}, - {ERR_REASON(SSL_R_BAD_SRP_N_LENGTH), "bad srp n length"}, - {ERR_REASON(SSL_R_BAD_SRP_PARAMETERS), "bad srp parameters"}, - {ERR_REASON(SSL_R_BAD_SRP_S_LENGTH), "bad srp s length"}, - {ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE), "bad srtp mki value"}, - {ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), - "bad srtp protection profile list"}, - {ERR_REASON(SSL_R_BAD_SSL_FILETYPE), "bad ssl filetype"}, - {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH), - "bad ssl session id length"}, - {ERR_REASON(SSL_R_BAD_STATE), "bad state"}, - {ERR_REASON(SSL_R_BAD_VALUE), "bad value"}, - {ERR_REASON(SSL_R_BAD_WRITE_RETRY), "bad write retry"}, - {ERR_REASON(SSL_R_BIO_NOT_SET), "bio not set"}, - {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), - "block cipher pad is wrong"}, - {ERR_REASON(SSL_R_BN_LIB), "bn lib"}, - {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH), "ca dn length mismatch"}, - {ERR_REASON(SSL_R_CA_DN_TOO_LONG), "ca dn too long"}, - {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY), "ccs received early"}, - {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED), - "certificate verify failed"}, - {ERR_REASON(SSL_R_CERT_CB_ERROR), "cert cb error"}, - {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH), "cert length mismatch"}, - {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"}, - {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"}, - {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE), - "cipher or hash unavailable"}, - {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"}, - {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT), "clienthello tlsext"}, - {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG), - "compressed length too long"}, - {ERR_REASON(SSL_R_COMPRESSION_DISABLED), "compression disabled"}, - {ERR_REASON(SSL_R_COMPRESSION_FAILURE), "compression failure"}, - {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), - "compression id not within private range"}, - {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR), - "compression library error"}, - {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT), - "connection id is different"}, - {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"}, - {ERR_REASON(SSL_R_COOKIE_MISMATCH), "cookie mismatch"}, - {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED), - "data between ccs and finished"}, - {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG), "data length too long"}, - {ERR_REASON(SSL_R_DECRYPTION_FAILED), "decryption failed"}, - {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), - "decryption failed or bad record mac"}, - {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"}, - {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), - "dh public value length is wrong"}, - {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED), "digest check failed"}, - {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG), "dtls message too big"}, - {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"}, - {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT), - "ecc cert not for key agreement"}, - {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"}, - {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE), - "ecc cert should have rsa signature"}, - {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE), - "ecc cert should have sha1 signature"}, - {ERR_REASON(SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE), - "ecdh required for suiteb mode"}, - {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER), - "ecgroup too large for cipher"}, - {ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), - "empty srtp protection profile list"}, - {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG), - "encrypted length too long"}, - {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY), - "error generating tmp rsa key"}, - {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), - "error in received cipher list"}, - {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"}, - {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE), "extra data in message"}, - {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"}, - {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS), - "got next proto before a ccs"}, - {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION), - "got next proto without seeing extension"}, - {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST), "https proxy request"}, - {ERR_REASON(SSL_R_HTTP_REQUEST), "http request"}, - {ERR_REASON(SSL_R_ILLEGAL_PADDING), "illegal padding"}, - {ERR_REASON(SSL_R_ILLEGAL_SUITEB_DIGEST), "illegal Suite B digest"}, - {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"}, - {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"}, - {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"}, - {ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"}, - {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM), - "invalid compression algorithm"}, - {ERR_REASON(SSL_R_INVALID_NULL_CMD_NAME), "invalid null cmd name"}, - {ERR_REASON(SSL_R_INVALID_PURPOSE), "invalid purpose"}, - {ERR_REASON(SSL_R_INVALID_SERVERINFO_DATA), "invalid serverinfo data"}, - {ERR_REASON(SSL_R_INVALID_SRP_USERNAME), "invalid srp username"}, - {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"}, - {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH), - "invalid ticket keys length"}, - {ERR_REASON(SSL_R_INVALID_TRUST), "invalid trust"}, - {ERR_REASON(SSL_R_KEY_ARG_TOO_LONG), "key arg too long"}, - {ERR_REASON(SSL_R_KRB5), "krb5"}, - {ERR_REASON(SSL_R_KRB5_C_CC_PRINC), "krb5 client cc principal (no tkt?)"}, - {ERR_REASON(SSL_R_KRB5_C_GET_CRED), "krb5 client get cred"}, - {ERR_REASON(SSL_R_KRB5_C_INIT), "krb5 client init"}, - {ERR_REASON(SSL_R_KRB5_C_MK_REQ), "krb5 client mk_req (expired tkt?)"}, - {ERR_REASON(SSL_R_KRB5_S_BAD_TICKET), "krb5 server bad ticket"}, - {ERR_REASON(SSL_R_KRB5_S_INIT), "krb5 server init"}, - {ERR_REASON(SSL_R_KRB5_S_RD_REQ), "krb5 server rd_req (keytab perms?)"}, - {ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED), "krb5 server tkt expired"}, - {ERR_REASON(SSL_R_KRB5_S_TKT_NYV), "krb5 server tkt not yet valid"}, - {ERR_REASON(SSL_R_KRB5_S_TKT_SKEW), "krb5 server tkt skew"}, - {ERR_REASON(SSL_R_LENGTH_MISMATCH), "length mismatch"}, - {ERR_REASON(SSL_R_LENGTH_TOO_SHORT), "length too short"}, - {ERR_REASON(SSL_R_LIBRARY_BUG), "library bug"}, - {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"}, - {ERR_REASON(SSL_R_MESSAGE_TOO_LONG), "message too long"}, - {ERR_REASON(SSL_R_MISSING_DH_DSA_CERT), "missing dh dsa cert"}, - {ERR_REASON(SSL_R_MISSING_DH_KEY), "missing dh key"}, - {ERR_REASON(SSL_R_MISSING_DH_RSA_CERT), "missing dh rsa cert"}, - {ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"}, - {ERR_REASON(SSL_R_MISSING_ECDH_CERT), "missing ecdh cert"}, - {ERR_REASON(SSL_R_MISSING_ECDSA_SIGNING_CERT), - "missing ecdsa signing cert"}, - {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY), - "missing export tmp dh key"}, - {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY), - "missing export tmp rsa key"}, - {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"}, - {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), - "missing rsa encrypting cert"}, - {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"}, - {ERR_REASON(SSL_R_MISSING_SRP_PARAM), "can't find SRP server param"}, - {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key"}, - {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY), "missing tmp ecdh key"}, - {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY), "missing tmp rsa key"}, - {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY), "missing tmp rsa pkey"}, - {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"}, - {ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS), "multiple sgc restarts"}, - {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"}, - {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"}, - {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"}, - {ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"}, - {ERR_REASON(SSL_R_NO_CERTIFICATE_SET), "no certificate set"}, - {ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"}, - {ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE), "no ciphers available"}, - {ERR_REASON(SSL_R_NO_CIPHERS_PASSED), "no ciphers passed"}, - {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED), "no ciphers specified"}, - {ERR_REASON(SSL_R_NO_CIPHER_LIST), "no cipher list"}, - {ERR_REASON(SSL_R_NO_CIPHER_MATCH), "no cipher match"}, - {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD), "no client cert method"}, - {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"}, - {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"}, - {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), - "Peer haven't sent GOST certificate, required for selected ciphersuite"}, - {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED), "no method specified"}, - {ERR_REASON(SSL_R_NO_PEM_EXTENSIONS), "no pem extensions"}, - {ERR_REASON(SSL_R_NO_PRIVATEKEY), "no privatekey"}, - {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"}, - {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"}, - {ERR_REASON(SSL_R_NO_PUBLICKEY), "no publickey"}, - {ERR_REASON(SSL_R_NO_RENEGOTIATION), "no renegotiation"}, - {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST), - "digest requred for handshake isn't computed"}, - {ERR_REASON(SSL_R_NO_SHARED_CIPHER), "no shared cipher"}, - {ERR_REASON(SSL_R_NO_SHARED_SIGATURE_ALGORITHMS), - "no shared sigature algorithms"}, - {ERR_REASON(SSL_R_NO_SRTP_PROFILES), "no srtp profiles"}, - {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK), "no verify callback"}, - {ERR_REASON(SSL_R_NULL_SSL_CTX), "null ssl ctx"}, - {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"}, - {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), - "old session cipher not returned"}, - {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), - "old session compression algorithm not returned"}, - {ERR_REASON(SSL_R_ONLY_DTLS_1_2_ALLOWED_IN_SUITEB_MODE), - "only DTLS 1.2 allowed in Suite B mode"}, - {ERR_REASON(SSL_R_ONLY_TLS_1_2_ALLOWED_IN_SUITEB_MODE), - "only TLS 1.2 allowed in Suite B mode"}, - {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), - "only tls allowed in fips mode"}, - {ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG), - "opaque PRF input too long"}, - {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"}, - {ERR_REASON(SSL_R_PARSE_TLSEXT), "parse tlsext"}, - {ERR_REASON(SSL_R_PATH_TOO_LONG), "path too long"}, - {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), - "peer did not return a certificate"}, - {ERR_REASON(SSL_R_PEER_ERROR), "peer error"}, - {ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"}, - {ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE), - "peer error no certificate"}, - {ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER), "peer error no cipher"}, - {ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE), - "peer error unsupported certificate type"}, - {ERR_REASON(SSL_R_PEM_NAME_BAD_PREFIX), "pem name bad prefix"}, - {ERR_REASON(SSL_R_PEM_NAME_TOO_SHORT), "pem name too short"}, - {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"}, - {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS), - "problems mapping cipher functions"}, - {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN), "protocol is shutdown"}, - {ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"}, - {ERR_REASON(SSL_R_PSK_NO_CLIENT_CB), "psk no client cb"}, - {ERR_REASON(SSL_R_PSK_NO_SERVER_CB), "psk no server cb"}, - {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"}, - {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA), "public key is not rsa"}, - {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, - {ERR_REASON(SSL_R_READ_BIO_NOT_SET), "read bio not set"}, - {ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED), "read timeout expired"}, - {ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"}, - {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"}, - {ERR_REASON(SSL_R_RECORD_TOO_LARGE), "record too large"}, - {ERR_REASON(SSL_R_RECORD_TOO_SMALL), "record too small"}, - {ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"}, - {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR), - "renegotiation encoding err"}, - {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"}, - {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"}, - {ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING), - "required compresssion algorithm missing"}, - {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO), - "reuse cert length not zero"}, - {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"}, - {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO), - "reuse cipher list not zero"}, - {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), - "scsv received when renegotiating"}, - {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"}, - {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), - "session id context uninitialized"}, - {ERR_REASON(SSL_R_SHORT_READ), "short read"}, - {ERR_REASON(SSL_R_SHUTDOWN_WHILE_IN_INIT), "shutdown while in init"}, - {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR), - "signature algorithms error"}, - {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), - "signature for non signing certificate"}, - {ERR_REASON(SSL_R_SRP_A_CALC), "error with the srp params"}, - {ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), - "srtp could not allocate profiles"}, - {ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), - "srtp protection profile list too long"}, - {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), - "srtp unknown protection profile"}, - {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), - "ssl23 doing session id reuse"}, - {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG), - "ssl2 connection id too long"}, - {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), - "ssl3 ext invalid ecpointformat"}, - {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), - "ssl3 ext invalid servername"}, - {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE), - "ssl3 ext invalid servername type"}, - {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"}, - {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT), - "ssl3 session id too short"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), - "sslv3 alert bad certificate"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), - "sslv3 alert bad record mac"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), - "sslv3 alert certificate expired"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), - "sslv3 alert certificate revoked"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), - "sslv3 alert certificate unknown"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), - "sslv3 alert decompression failure"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), - "sslv3 alert handshake failure"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), - "sslv3 alert illegal parameter"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE), - "sslv3 alert no certificate"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), - "sslv3 alert unexpected message"}, - {ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), - "sslv3 alert unsupported certificate"}, - {ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), - "ssl ctx has no default ssl version"}, - {ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE), "ssl handshake failure"}, - {ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), - "ssl library has no ciphers"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), - "ssl session id callback failed"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), - "ssl session id context too long"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), - "ssl session id has bad length"}, - {ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT), - "ssl session id is different"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED), - "tlsv1 alert access denied"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), - "tlsv1 alert decryption failed"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), - "tlsv1 alert decrypt error"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), - "tlsv1 alert export restriction"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), - "tlsv1 alert inappropriate fallback"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), - "tlsv1 alert insufficient security"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), - "tlsv1 alert internal error"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), - "tlsv1 alert no renegotiation"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), - "tlsv1 alert protocol version"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), - "tlsv1 alert record overflow"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"}, - {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED), - "tlsv1 alert user cancelled"}, - {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), - "tlsv1 bad certificate hash value"}, - {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), - "tlsv1 bad certificate status response"}, - {ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), - "tlsv1 certificate unobtainable"}, - {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"}, - {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION), - "tlsv1 unsupported extension"}, - {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER), - "tls client cert req with anon cipher"}, - {ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), - "peer does not accept heartbeats"}, - {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING), - "heartbeat request already pending"}, - {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), - "tls illegal exporter label"}, - {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), - "tls invalid ecpointformat list"}, - {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"}, - {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), - "tls peer did not respond with certificate list"}, - {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), - "tls rsa encrypted value length is wrong"}, - {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), - "tried to use unsupported cipher"}, - {ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS), - "unable to decode dh certs"}, - {ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), - "unable to decode ecdh certs"}, - {ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY), - "unable to extract public key"}, - {ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS), - "unable to find dh parameters"}, - {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), - "unable to find ecdh parameters"}, - {ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), - "unable to find public key parameters"}, - {ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD), - "unable to find ssl method"}, - {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES), - "unable to load ssl2 md5 routines"}, - {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES), - "unable to load ssl3 md5 routines"}, - {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), - "unable to load ssl3 sha1 routines"}, - {ERR_REASON(SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, - {ERR_REASON(SSL_R_UNEXPECTED_RECORD), "unexpected record"}, - {ERR_REASON(SSL_R_UNINITIALIZED), "uninitialized"}, - {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"}, - {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"}, - {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"}, - {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE), "unknown cipher type"}, - {ERR_REASON(SSL_R_UNKNOWN_CMD_NAME), "unknown cmd name"}, - {ERR_REASON(SSL_R_UNKNOWN_DIGEST), "unknown digest"}, - {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), - "unknown key exchange type"}, - {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE), "unknown pkey type"}, - {ERR_REASON(SSL_R_UNKNOWN_PROTOCOL), "unknown protocol"}, - {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE), - "unknown remote error type"}, - {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION), "unknown ssl version"}, - {ERR_REASON(SSL_R_UNKNOWN_STATE), "unknown state"}, - {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), - "unsafe legacy renegotiation disabled"}, - {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, - {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), - "unsupported compression algorithm"}, - {ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"}, - {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), - "unsupported elliptic curve"}, - {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL), "unsupported protocol"}, - {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"}, - {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"}, - {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"}, - {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET), "write bio not set"}, - {ERR_REASON(SSL_R_WRONG_CERTIFICATE_TYPE), "wrong certificate type"}, - {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"}, - {ERR_REASON(SSL_R_WRONG_CURVE), "wrong curve"}, - {ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE), "wrong message type"}, - {ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"}, - {ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, - {ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE), "wrong signature size"}, - {ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE), "wrong signature type"}, - {ERR_REASON(SSL_R_WRONG_SSL_VERSION), "wrong ssl version"}, - {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER), "wrong version number"}, - {ERR_REASON(SSL_R_X509_LIB), "x509 lib"}, - {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), - "x509 verification setup problems"}, - {0, NULL} -}; - -#endif - -void ERR_load_SSL_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) { - ERR_load_strings(0, SSL_str_functs); - ERR_load_strings(0, SSL_str_reasons); - } -#endif -} -/* ssl/ssl_err2.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "err.h" -// #include "ssl.h" - -void SSL_load_error_strings(void) -{ -#ifndef OPENSSL_NO_ERR - ERR_load_crypto_strings(); - ERR_load_SSL_strings(); -#endif -} -/* - * ! \file ssl/ssl_lib.c \brief Version independent SSL functions. - */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#ifdef REF_CHECK -# include -#endif -#include -// #include "ssl_locl.h" -#include "kssl_lcl.h" -// #include "objects.h" -// #include "lhash.h" -// #include "x509v3.h" -#include "rand.h" -#include "ocsp.h" -#ifndef OPENSSL_NO_DH -# include "dh.h" -#endif -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif - -const char *SSL_version_str = OPENSSL_VERSION_TEXT; - -SSL3_ENC_METHOD ssl3_undef_enc_method = { - /* - * evil casts, but these functions are only called if there's a library - * bug - */ - (int (*)(SSL *, int))ssl_undefined_function, - (int (*)(SSL *, unsigned char *, int))ssl_undefined_function, - ssl_undefined_function, - (int (*)(SSL *, unsigned char *, unsigned char *, int)) - ssl_undefined_function, - (int (*)(SSL *, int))ssl_undefined_function, - (int (*)(SSL *, const char *, int, unsigned char *)) - ssl_undefined_function, - 0, /* finish_mac_length */ - (int (*)(SSL *, int, unsigned char *))ssl_undefined_function, - NULL, /* client_finished_label */ - 0, /* client_finished_label_len */ - NULL, /* server_finished_label */ - 0, /* server_finished_label_len */ - (int (*)(int))ssl_undefined_function, - (int (*)(SSL *, unsigned char *, size_t, const char *, - size_t, const unsigned char *, size_t, - int use_context))ssl_undefined_function, -}; - -int SSL_clear(SSL *s) -{ - - if (s->method == NULL) { - SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED); - return (0); - } - - if (ssl_clear_bad_session(s)) { - SSL_SESSION_free(s->session); - s->session = NULL; - } - - s->error = 0; - s->hit = 0; - s->shutdown = 0; - -#if 0 - /* - * Disabled since version 1.10 of this file (early return not - * needed because SSL_clear is not called when doing renegotiation) - */ - /* - * This is set if we are doing dynamic renegotiation so keep - * the old cipher. It is sort of a SSL_clear_lite :-) - */ - if (s->renegotiate) - return (1); -#else - if (s->renegotiate) { - SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR); - return 0; - } -#endif - - s->type = 0; - - s->state = SSL_ST_BEFORE | ((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT); - - s->version = s->method->version; - s->client_version = s->version; - s->rwstate = SSL_NOTHING; - s->rstate = SSL_ST_READ_HEADER; -#if 0 - s->read_ahead = s->ctx->read_ahead; -#endif - - if (s->init_buf != NULL) { - BUF_MEM_free(s->init_buf); - s->init_buf = NULL; - } - - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); - - s->first_packet = 0; -#ifndef OPENSSL_NO_TLSEXT - if (s->cert != NULL) { - if (s->cert->alpn_proposed) { - OPENSSL_free(s->cert->alpn_proposed); - s->cert->alpn_proposed = NULL; - } - s->cert->alpn_proposed_len = 0; - s->cert->alpn_sent = 0; - } -#endif -#if 1 - /* - * Check to see if we were changed into a different method, if so, revert - * back if we are not doing session-id reuse. - */ - if (!s->in_handshake && (s->session == NULL) - && (s->method != s->ctx->method)) { - s->method->ssl_free(s); - s->method = s->ctx->method; - if (!s->method->ssl_new(s)) - return (0); - } else -#endif - s->method->ssl_clear(s); - return (1); -} - -/** Used to change an SSL_CTXs default SSL method type */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) -{ - STACK_OF(SSL_CIPHER) *sk; - - ctx->method = meth; - - sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list), - &(ctx->cipher_list_by_id), - meth->version == - SSL2_VERSION ? "SSLv2" : - SSL_DEFAULT_CIPHER_LIST, ctx->cert); - if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { - SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, - SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); - return (0); - } - return (1); -} - -SSL *SSL_new(SSL_CTX *ctx) -{ - SSL *s; - - if (ctx == NULL) { - SSLerr(SSL_F_SSL_NEW, SSL_R_NULL_SSL_CTX); - return (NULL); - } - if (ctx->method == NULL) { - SSLerr(SSL_F_SSL_NEW, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); - return (NULL); - } - - s = (SSL *)OPENSSL_malloc(sizeof(SSL)); - if (s == NULL) - goto err; - memset(s, 0, sizeof(SSL)); - -#ifndef OPENSSL_NO_KRB5 - s->kssl_ctx = kssl_ctx_new(); -#endif /* OPENSSL_NO_KRB5 */ - - s->options = ctx->options; - s->mode = ctx->mode; - s->max_cert_list = ctx->max_cert_list; - s->references = 1; - - if (ctx->cert != NULL) { - /* - * Earlier library versions used to copy the pointer to the CERT, not - * its contents; only when setting new parameters for the per-SSL - * copy, ssl_cert_new would be called (and the direct reference to - * the per-SSL_CTX settings would be lost, but those still were - * indirectly accessed for various purposes, and for that reason they - * used to be known as s->ctx->default_cert). Now we don't look at the - * SSL_CTX's CERT after having duplicated it once. - */ - - s->cert = ssl_cert_dup(ctx->cert); - if (s->cert == NULL) - goto err; - } else - s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */ - - s->read_ahead = ctx->read_ahead; - s->msg_callback = ctx->msg_callback; - s->msg_callback_arg = ctx->msg_callback_arg; - s->verify_mode = ctx->verify_mode; -#if 0 - s->verify_depth = ctx->verify_depth; -#endif - s->sid_ctx_length = ctx->sid_ctx_length; - OPENSSL_assert(s->sid_ctx_length <= sizeof(s->sid_ctx)); - memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); - s->verify_callback = ctx->default_verify_callback; - s->generate_session_id = ctx->generate_session_id; - - s->param = X509_VERIFY_PARAM_new(); - if (!s->param) - goto err; - X509_VERIFY_PARAM_inherit(s->param, ctx->param); -#if 0 - s->purpose = ctx->purpose; - s->trust = ctx->trust; -#endif - s->quiet_shutdown = ctx->quiet_shutdown; - s->max_send_fragment = ctx->max_send_fragment; - - CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); - s->ctx = ctx; -#ifndef OPENSSL_NO_TLSEXT - s->tlsext_debug_cb = 0; - s->tlsext_debug_arg = NULL; - s->tlsext_ticket_expected = 0; - s->tlsext_status_type = -1; - s->tlsext_status_expected = 0; - s->tlsext_ocsp_ids = NULL; - s->tlsext_ocsp_exts = NULL; - s->tlsext_ocsp_resp = NULL; - s->tlsext_ocsp_resplen = -1; - CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); - s->initial_ctx = ctx; -# ifndef OPENSSL_NO_EC - if (ctx->tlsext_ecpointformatlist) { - s->tlsext_ecpointformatlist = - BUF_memdup(ctx->tlsext_ecpointformatlist, - ctx->tlsext_ecpointformatlist_length); - if (!s->tlsext_ecpointformatlist) - goto err; - s->tlsext_ecpointformatlist_length = - ctx->tlsext_ecpointformatlist_length; - } - if (ctx->tlsext_ellipticcurvelist) { - s->tlsext_ellipticcurvelist = - BUF_memdup(ctx->tlsext_ellipticcurvelist, - ctx->tlsext_ellipticcurvelist_length); - if (!s->tlsext_ellipticcurvelist) - goto err; - s->tlsext_ellipticcurvelist_length = - ctx->tlsext_ellipticcurvelist_length; - } -# endif -# ifndef OPENSSL_NO_NEXTPROTONEG - s->next_proto_negotiated = NULL; -# endif - - if (s->ctx->alpn_client_proto_list) { - s->alpn_client_proto_list = - OPENSSL_malloc(s->ctx->alpn_client_proto_list_len); - if (s->alpn_client_proto_list == NULL) - goto err; - memcpy(s->alpn_client_proto_list, s->ctx->alpn_client_proto_list, - s->ctx->alpn_client_proto_list_len); - s->alpn_client_proto_list_len = s->ctx->alpn_client_proto_list_len; - } -#endif - - s->verify_result = X509_V_OK; - - s->method = ctx->method; - - if (!s->method->ssl_new(s)) - goto err; - - s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1; - - SSL_clear(s); - - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); - -#ifndef OPENSSL_NO_PSK - s->psk_client_callback = ctx->psk_client_callback; - s->psk_server_callback = ctx->psk_server_callback; -#endif - - return (s); - err: - if (s != NULL) - SSL_free(s); - SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); -} - -int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, - unsigned int sid_ctx_len) -{ - if (sid_ctx_len > sizeof(ctx->sid_ctx)) { - SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); - return 0; - } - ctx->sid_ctx_length = sid_ctx_len; - memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len); - - return 1; -} - -int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, - unsigned int sid_ctx_len) -{ - if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { - SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); - return 0; - } - ssl->sid_ctx_length = sid_ctx_len; - memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len); - - return 1; -} - -int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) -{ - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - ctx->generate_session_id = cb; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - return 1; -} - -int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) -{ - CRYPTO_w_lock(CRYPTO_LOCK_SSL); - ssl->generate_session_id = cb; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL); - return 1; -} - -int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, - unsigned int id_len) -{ - /* - * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how - * we can "construct" a session to give us the desired check - ie. to - * find if there's a session in the hash table that would conflict with - * any new session built out of this id/id_len and the ssl_version in use - * by this SSL. - */ - SSL_SESSION r, *p; - - if (id_len > sizeof(r.session_id)) - return 0; - - r.ssl_version = ssl->version; - r.session_id_length = id_len; - memcpy(r.session_id, id, id_len); - /* - * NB: SSLv2 always uses a fixed 16-byte session ID, so even if a - * callback is calling us to check the uniqueness of a shorter ID, it - * must be compared as a padded-out ID because that is what it will be - * converted to when the callback has finished choosing it. - */ - if ((r.ssl_version == SSL2_VERSION) && - (id_len < SSL2_SSL_SESSION_ID_LENGTH)) { - memset(r.session_id + id_len, 0, SSL2_SSL_SESSION_ID_LENGTH - id_len); - r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH; - } - - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r); - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - return (p != NULL); -} - -int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) -{ - return X509_VERIFY_PARAM_set_purpose(s->param, purpose); -} - -int SSL_set_purpose(SSL *s, int purpose) -{ - return X509_VERIFY_PARAM_set_purpose(s->param, purpose); -} - -int SSL_CTX_set_trust(SSL_CTX *s, int trust) -{ - return X509_VERIFY_PARAM_set_trust(s->param, trust); -} - -int SSL_set_trust(SSL *s, int trust) -{ - return X509_VERIFY_PARAM_set_trust(s->param, trust); -} - -int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) -{ - return X509_VERIFY_PARAM_set1(ctx->param, vpm); -} - -int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) -{ - return X509_VERIFY_PARAM_set1(ssl->param, vpm); -} - -X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) -{ - return ctx->param; -} - -X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) -{ - return ssl->param; -} - -void SSL_certs_clear(SSL *s) -{ - ssl_cert_clear_certs(s->cert); -} - -void SSL_free(SSL *s) -{ - int i; - - if (s == NULL) - return; - - i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL); -#ifdef REF_PRINT - REF_PRINT("SSL", s); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "SSL_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - if (s->param) - X509_VERIFY_PARAM_free(s->param); - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); - - if (s->bbio != NULL) { - /* If the buffering BIO is in place, pop it off */ - if (s->bbio == s->wbio) { - s->wbio = BIO_pop(s->wbio); - } - BIO_free(s->bbio); - s->bbio = NULL; - } - if (s->rbio != NULL) - BIO_free_all(s->rbio); - if ((s->wbio != NULL) && (s->wbio != s->rbio)) - BIO_free_all(s->wbio); - - if (s->init_buf != NULL) - BUF_MEM_free(s->init_buf); - - /* add extra stuff */ - if (s->cipher_list != NULL) - sk_SSL_CIPHER_free(s->cipher_list); - if (s->cipher_list_by_id != NULL) - sk_SSL_CIPHER_free(s->cipher_list_by_id); - - /* Make the next call work :-) */ - if (s->session != NULL) { - ssl_clear_bad_session(s); - SSL_SESSION_free(s->session); - } - - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); - - if (s->cert != NULL) - ssl_cert_free(s->cert); - /* Free up if allocated */ - -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_hostname) - OPENSSL_free(s->tlsext_hostname); - if (s->initial_ctx) - SSL_CTX_free(s->initial_ctx); -# ifndef OPENSSL_NO_EC - if (s->tlsext_ecpointformatlist) - OPENSSL_free(s->tlsext_ecpointformatlist); - if (s->tlsext_ellipticcurvelist) - OPENSSL_free(s->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ - if (s->tlsext_opaque_prf_input) - OPENSSL_free(s->tlsext_opaque_prf_input); - if (s->tlsext_ocsp_exts) - sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); - if (s->tlsext_ocsp_ids) - sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); - if (s->tlsext_ocsp_resp) - OPENSSL_free(s->tlsext_ocsp_resp); - if (s->alpn_client_proto_list) - OPENSSL_free(s->alpn_client_proto_list); -#endif - - if (s->client_CA != NULL) - sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); - - if (s->method != NULL) - s->method->ssl_free(s); - - if (s->ctx) - SSL_CTX_free(s->ctx); - -#ifndef OPENSSL_NO_KRB5 - if (s->kssl_ctx != NULL) - kssl_ctx_free(s->kssl_ctx); -#endif /* OPENSSL_NO_KRB5 */ - -#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) - if (s->next_proto_negotiated) - OPENSSL_free(s->next_proto_negotiated); -#endif - -#ifndef OPENSSL_NO_SRTP - if (s->srtp_profiles) - sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); -#endif - - OPENSSL_free(s); -} - -void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) -{ - /* - * If the output buffering BIO is still in place, remove it - */ - if (s->bbio != NULL) { - if (s->wbio == s->bbio) { - s->wbio = s->wbio->next_bio; - s->bbio->next_bio = NULL; - } - } - if ((s->rbio != NULL) && (s->rbio != rbio)) - BIO_free_all(s->rbio); - if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio)) - BIO_free_all(s->wbio); - s->rbio = rbio; - s->wbio = wbio; -} - -BIO *SSL_get_rbio(const SSL *s) -{ - return (s->rbio); -} - -BIO *SSL_get_wbio(const SSL *s) -{ - return (s->wbio); -} - -int SSL_get_fd(const SSL *s) -{ - return (SSL_get_rfd(s)); -} - -int SSL_get_rfd(const SSL *s) -{ - int ret = -1; - BIO *b, *r; - - b = SSL_get_rbio(s); - r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); - if (r != NULL) - BIO_get_fd(r, &ret); - return (ret); -} - -int SSL_get_wfd(const SSL *s) -{ - int ret = -1; - BIO *b, *r; - - b = SSL_get_wbio(s); - r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); - if (r != NULL) - BIO_get_fd(r, &ret); - return (ret); -} - -#ifndef OPENSSL_NO_SOCK -int SSL_set_fd(SSL *s, int fd) -{ - int ret = 0; - BIO *bio = NULL; - - bio = BIO_new(BIO_s_socket()); - - if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); - goto err; - } - BIO_set_fd(bio, fd, BIO_NOCLOSE); - SSL_set_bio(s, bio, bio); - ret = 1; - err: - return (ret); -} - -int SSL_set_wfd(SSL *s, int fd) -{ - int ret = 0; - BIO *bio = NULL; - - if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET) - || ((int)BIO_get_fd(s->rbio, NULL) != fd)) { - bio = BIO_new(BIO_s_socket()); - - if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB); - goto err; - } - BIO_set_fd(bio, fd, BIO_NOCLOSE); - SSL_set_bio(s, SSL_get_rbio(s), bio); - } else - SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s)); - ret = 1; - err: - return (ret); -} - -int SSL_set_rfd(SSL *s, int fd) -{ - int ret = 0; - BIO *bio = NULL; - - if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET) - || ((int)BIO_get_fd(s->wbio, NULL) != fd)) { - bio = BIO_new(BIO_s_socket()); - - if (bio == NULL) { - SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB); - goto err; - } - BIO_set_fd(bio, fd, BIO_NOCLOSE); - SSL_set_bio(s, bio, SSL_get_wbio(s)); - } else - SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s)); - ret = 1; - err: - return (ret); -} -#endif - -/* return length of latest Finished message we sent, copy to 'buf' */ -size_t SSL_get_finished(const SSL *s, void *buf, size_t count) -{ - size_t ret = 0; - - if (s->s3 != NULL) { - ret = s->s3->tmp.finish_md_len; - if (count > ret) - count = ret; - memcpy(buf, s->s3->tmp.finish_md, count); - } - return ret; -} - -/* return length of latest Finished message we expected, copy to 'buf' */ -size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) -{ - size_t ret = 0; - - if (s->s3 != NULL) { - ret = s->s3->tmp.peer_finish_md_len; - if (count > ret) - count = ret; - memcpy(buf, s->s3->tmp.peer_finish_md, count); - } - return ret; -} - -int SSL_get_verify_mode(const SSL *s) -{ - return (s->verify_mode); -} - -int SSL_get_verify_depth(const SSL *s) -{ - return X509_VERIFY_PARAM_get_depth(s->param); -} - -int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *) { - return (s->verify_callback); -} - -int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) -{ - return (ctx->verify_mode); -} - -int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) -{ - return X509_VERIFY_PARAM_get_depth(ctx->param); -} - -int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, X509_STORE_CTX *) { - return (ctx->default_verify_callback); -} - -void SSL_set_verify(SSL *s, int mode, - int (*callback) (int ok, X509_STORE_CTX *ctx)) -{ - s->verify_mode = mode; - if (callback != NULL) - s->verify_callback = callback; -} - -void SSL_set_verify_depth(SSL *s, int depth) -{ - X509_VERIFY_PARAM_set_depth(s->param, depth); -} - -void SSL_set_read_ahead(SSL *s, int yes) -{ - s->read_ahead = yes; -} - -int SSL_get_read_ahead(const SSL *s) -{ - return (s->read_ahead); -} - -int SSL_pending(const SSL *s) -{ - /* - * SSL_pending cannot work properly if read-ahead is enabled - * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is - * impossible to fix since SSL_pending cannot report errors that may be - * observed while scanning the new data. (Note that SSL_pending() is - * often used as a boolean value, so we'd better not return -1.) - */ - return (s->method->ssl_pending(s)); -} - -X509 *SSL_get_peer_certificate(const SSL *s) -{ - X509 *r; - - if ((s == NULL) || (s->session == NULL)) - r = NULL; - else - r = s->session->peer; - - if (r == NULL) - return (r); - - CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509); - - return (r); -} - -STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) -{ - STACK_OF(X509) *r; - - if ((s == NULL) || (s->session == NULL) - || (s->session->sess_cert == NULL)) - r = NULL; - else - r = s->session->sess_cert->cert_chain; - - /* - * If we are a client, cert_chain includes the peer's own certificate; if - * we are a server, it does not. - */ - - return (r); -} - -/* - * Now in theory, since the calling process own 't' it should be safe to - * modify. We need to be able to read f without being hassled - */ -void SSL_copy_session_id(SSL *t, const SSL *f) -{ - CERT *tmp; - - /* Do we need to to SSL locking? */ - SSL_set_session(t, SSL_get_session(f)); - - /* - * what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa - */ - if (t->method != f->method) { - t->method->ssl_free(t); /* cleanup current */ - t->method = f->method; /* change method */ - t->method->ssl_new(t); /* setup new */ - } - - tmp = t->cert; - if (f->cert != NULL) { - CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); - t->cert = f->cert; - } else - t->cert = NULL; - if (tmp != NULL) - ssl_cert_free(tmp); - SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length); -} - -/* Fix this so it checks all the valid key/cert options */ -int SSL_CTX_check_private_key(const SSL_CTX *ctx) -{ - if ((ctx == NULL) || - (ctx->cert == NULL) || (ctx->cert->key->x509 == NULL)) { - SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, - SSL_R_NO_CERTIFICATE_ASSIGNED); - return (0); - } - if (ctx->cert->key->privatekey == NULL) { - SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, - SSL_R_NO_PRIVATE_KEY_ASSIGNED); - return (0); - } - return (X509_check_private_key - (ctx->cert->key->x509, ctx->cert->key->privatekey)); -} - -/* Fix this function so that it takes an optional type parameter */ -int SSL_check_private_key(const SSL *ssl) -{ - if (ssl == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (ssl->cert == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); - return 0; - } - if (ssl->cert->key->x509 == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); - return (0); - } - if (ssl->cert->key->privatekey == NULL) { - SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED); - return (0); - } - return (X509_check_private_key(ssl->cert->key->x509, - ssl->cert->key->privatekey)); -} - -int SSL_accept(SSL *s) -{ - if (s->handshake_func == 0) - /* Not properly initialized yet */ - SSL_set_accept_state(s); - - return (s->method->ssl_accept(s)); -} - -int SSL_connect(SSL *s) -{ - if (s->handshake_func == 0) - /* Not properly initialized yet */ - SSL_set_connect_state(s); - - return (s->method->ssl_connect(s)); -} - -long SSL_get_default_timeout(const SSL *s) -{ - return (s->method->get_timeout()); -} - -int SSL_read(SSL *s, void *buf, int num) -{ - if (s->handshake_func == 0) { - SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED); - return -1; - } - - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - s->rwstate = SSL_NOTHING; - return (0); - } - return (s->method->ssl_read(s, buf, num)); -} - -int SSL_peek(SSL *s, void *buf, int num) -{ - if (s->handshake_func == 0) { - SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED); - return -1; - } - - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - return (0); - } - return (s->method->ssl_peek(s, buf, num)); -} - -int SSL_write(SSL *s, const void *buf, int num) -{ - if (s->handshake_func == 0) { - SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED); - return -1; - } - - if (s->shutdown & SSL_SENT_SHUTDOWN) { - s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN); - return (-1); - } - return (s->method->ssl_write(s, buf, num)); -} - -int SSL_shutdown(SSL *s) -{ - /* - * Note that this function behaves differently from what one might - * expect. Return values are 0 for no success (yet), 1 for success; but - * calling it once is usually not enough, even if blocking I/O is used - * (see ssl3_shutdown). - */ - - if (s->handshake_func == 0) { - SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED); - return -1; - } - - if (!SSL_in_init(s)) { - return s->method->ssl_shutdown(s); - } else { - SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_SHUTDOWN_WHILE_IN_INIT); - return -1; - } -} - -int SSL_renegotiate(SSL *s) -{ - if (s->renegotiate == 0) - s->renegotiate = 1; - - s->new_session = 1; - - return (s->method->ssl_renegotiate(s)); -} - -int SSL_renegotiate_abbreviated(SSL *s) -{ - if (s->renegotiate == 0) - s->renegotiate = 1; - - s->new_session = 0; - - return (s->method->ssl_renegotiate(s)); -} - -int SSL_renegotiate_pending(SSL *s) -{ - /* - * becomes true when negotiation is requested; false again once a - * handshake has finished - */ - return (s->renegotiate != 0); -} - -long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) -{ - long l; - - switch (cmd) { - case SSL_CTRL_GET_READ_AHEAD: - return (s->read_ahead); - case SSL_CTRL_SET_READ_AHEAD: - l = s->read_ahead; - s->read_ahead = larg; - return (l); - - case SSL_CTRL_SET_MSG_CALLBACK_ARG: - s->msg_callback_arg = parg; - return 1; - - case SSL_CTRL_OPTIONS: - return (s->options |= larg); - case SSL_CTRL_CLEAR_OPTIONS: - return (s->options &= ~larg); - case SSL_CTRL_MODE: - return (s->mode |= larg); - case SSL_CTRL_CLEAR_MODE: - return (s->mode &= ~larg); - case SSL_CTRL_GET_MAX_CERT_LIST: - return (s->max_cert_list); - case SSL_CTRL_SET_MAX_CERT_LIST: - l = s->max_cert_list; - s->max_cert_list = larg; - return (l); - case SSL_CTRL_SET_MAX_SEND_FRAGMENT: - if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) - return 0; - s->max_send_fragment = larg; - return 1; - case SSL_CTRL_GET_RI_SUPPORT: - if (s->s3) - return s->s3->send_connection_binding; - else - return 0; - case SSL_CTRL_CERT_FLAGS: - return (s->cert->cert_flags |= larg); - case SSL_CTRL_CLEAR_CERT_FLAGS: - return (s->cert->cert_flags &= ~larg); - - case SSL_CTRL_GET_RAW_CIPHERLIST: - if (parg) { - if (s->cert->ciphers_raw == NULL) - return 0; - *(unsigned char **)parg = s->cert->ciphers_raw; - return (int)s->cert->ciphers_rawlen; - } else - return ssl_put_cipher_by_char(s, NULL, NULL); - default: - return (s->method->ssl_ctrl(s, cmd, larg, parg)); - } -} - -long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) -{ - switch (cmd) { - case SSL_CTRL_SET_MSG_CALLBACK: - s->msg_callback = (void (*) - (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, - void *arg))(fp); - return 1; - - default: - return (s->method->ssl_callback_ctrl(s, cmd, fp)); - } -} - -LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) -{ - return ctx->sessions; -} - -long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) -{ - long l; - /* For some cases with ctx == NULL perform syntax checks */ - if (ctx == NULL) { - switch (cmd) { -#ifndef OPENSSL_NO_EC - case SSL_CTRL_SET_CURVES_LIST: - return tls1_set_curves_list(NULL, NULL, parg); -#endif - case SSL_CTRL_SET_SIGALGS_LIST: - case SSL_CTRL_SET_CLIENT_SIGALGS_LIST: - return tls1_set_sigalgs_list(NULL, parg, 0); - default: - return 0; - } - } - - switch (cmd) { - case SSL_CTRL_GET_READ_AHEAD: - return (ctx->read_ahead); - case SSL_CTRL_SET_READ_AHEAD: - l = ctx->read_ahead; - ctx->read_ahead = larg; - return (l); - - case SSL_CTRL_SET_MSG_CALLBACK_ARG: - ctx->msg_callback_arg = parg; - return 1; - - case SSL_CTRL_GET_MAX_CERT_LIST: - return (ctx->max_cert_list); - case SSL_CTRL_SET_MAX_CERT_LIST: - l = ctx->max_cert_list; - ctx->max_cert_list = larg; - return (l); - - case SSL_CTRL_SET_SESS_CACHE_SIZE: - l = ctx->session_cache_size; - ctx->session_cache_size = larg; - return (l); - case SSL_CTRL_GET_SESS_CACHE_SIZE: - return (ctx->session_cache_size); - case SSL_CTRL_SET_SESS_CACHE_MODE: - l = ctx->session_cache_mode; - ctx->session_cache_mode = larg; - return (l); - case SSL_CTRL_GET_SESS_CACHE_MODE: - return (ctx->session_cache_mode); - - case SSL_CTRL_SESS_NUMBER: - return (lh_SSL_SESSION_num_items(ctx->sessions)); - case SSL_CTRL_SESS_CONNECT: - return (ctx->stats.sess_connect); - case SSL_CTRL_SESS_CONNECT_GOOD: - return (ctx->stats.sess_connect_good); - case SSL_CTRL_SESS_CONNECT_RENEGOTIATE: - return (ctx->stats.sess_connect_renegotiate); - case SSL_CTRL_SESS_ACCEPT: - return (ctx->stats.sess_accept); - case SSL_CTRL_SESS_ACCEPT_GOOD: - return (ctx->stats.sess_accept_good); - case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: - return (ctx->stats.sess_accept_renegotiate); - case SSL_CTRL_SESS_HIT: - return (ctx->stats.sess_hit); - case SSL_CTRL_SESS_CB_HIT: - return (ctx->stats.sess_cb_hit); - case SSL_CTRL_SESS_MISSES: - return (ctx->stats.sess_miss); - case SSL_CTRL_SESS_TIMEOUTS: - return (ctx->stats.sess_timeout); - case SSL_CTRL_SESS_CACHE_FULL: - return (ctx->stats.sess_cache_full); - case SSL_CTRL_OPTIONS: - return (ctx->options |= larg); - case SSL_CTRL_CLEAR_OPTIONS: - return (ctx->options &= ~larg); - case SSL_CTRL_MODE: - return (ctx->mode |= larg); - case SSL_CTRL_CLEAR_MODE: - return (ctx->mode &= ~larg); - case SSL_CTRL_SET_MAX_SEND_FRAGMENT: - if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) - return 0; - ctx->max_send_fragment = larg; - return 1; - case SSL_CTRL_CERT_FLAGS: - return (ctx->cert->cert_flags |= larg); - case SSL_CTRL_CLEAR_CERT_FLAGS: - return (ctx->cert->cert_flags &= ~larg); - default: - return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg)); - } -} - -long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) -{ - switch (cmd) { - case SSL_CTRL_SET_MSG_CALLBACK: - ctx->msg_callback = (void (*) - (int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, - void *arg))(fp); - return 1; - - default: - return (ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp)); - } -} - -int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b) -{ - long l; - - l = a->id - b->id; - if (l == 0L) - return (0); - else - return ((l > 0) ? 1 : -1); -} - -int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, - const SSL_CIPHER *const *bp) -{ - long l; - - l = (*ap)->id - (*bp)->id; - if (l == 0L) - return (0); - else - return ((l > 0) ? 1 : -1); -} - -/** return a STACK of the ciphers available for the SSL and in order of - * preference */ -STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) -{ - if (s != NULL) { - if (s->cipher_list != NULL) { - return (s->cipher_list); - } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { - return (s->ctx->cipher_list); - } - } - return (NULL); -} - -/** return a STACK of the ciphers available for the SSL and in order of - * algorithm id */ -STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) -{ - if (s != NULL) { - if (s->cipher_list_by_id != NULL) { - return (s->cipher_list_by_id); - } else if ((s->ctx != NULL) && (s->ctx->cipher_list_by_id != NULL)) { - return (s->ctx->cipher_list_by_id); - } - } - return (NULL); -} - -/** The old interface to get the same thing as SSL_get_ciphers() */ -const char *SSL_get_cipher_list(const SSL *s, int n) -{ - SSL_CIPHER *c; - STACK_OF(SSL_CIPHER) *sk; - - if (s == NULL) - return (NULL); - sk = SSL_get_ciphers(s); - if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n)) - return (NULL); - c = sk_SSL_CIPHER_value(sk, n); - if (c == NULL) - return (NULL); - return (c->name); -} - -/** specify the ciphers to be used by default by the SSL_CTX */ -int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) -{ - STACK_OF(SSL_CIPHER) *sk; - - sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list, - &ctx->cipher_list_by_id, str, ctx->cert); - /* - * ssl_create_cipher_list may return an empty stack if it was unable to - * find a cipher matching the given rule string (for example if the rule - * string specifies a cipher which has been disabled). This is not an - * error as far as ssl_create_cipher_list is concerned, and hence - * ctx->cipher_list and ctx->cipher_list_by_id has been updated. - */ - if (sk == NULL) - return 0; - else if (sk_SSL_CIPHER_num(sk) == 0) { - SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); - return 0; - } - return 1; -} - -/** specify the ciphers to be used by the SSL */ -int SSL_set_cipher_list(SSL *s, const char *str) -{ - STACK_OF(SSL_CIPHER) *sk; - - sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list, - &s->cipher_list_by_id, str, s->cert); - /* see comment in SSL_CTX_set_cipher_list */ - if (sk == NULL) - return 0; - else if (sk_SSL_CIPHER_num(sk) == 0) { - SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); - return 0; - } - return 1; -} - -/* works well for SSLv2, not so good for SSLv3 */ -char *SSL_get_shared_ciphers(const SSL *s, char *buf, int size) -{ - char *p; - STACK_OF(SSL_CIPHER) *clntsk, *srvrsk; - SSL_CIPHER *c; - int i; - - if (!s->server - || s->session == NULL - || s->session->ciphers == NULL - || size < 2) - return NULL; - - p = buf; - clntsk = s->session->ciphers; - srvrsk = SSL_get_ciphers(s); - if (clntsk == NULL || srvrsk == NULL) - return NULL; - - if (sk_SSL_CIPHER_num(clntsk) == 0 || sk_SSL_CIPHER_num(srvrsk) == 0) - return NULL; - - for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) { - int n; - - c = sk_SSL_CIPHER_value(clntsk, i); - if (sk_SSL_CIPHER_find(srvrsk, c) < 0) - continue; - - n = strlen(c->name); - if (n + 1 > size) { - if (p != buf) - --p; - *p = '\0'; - return buf; - } - strcpy(p, c->name); - p += n; - *(p++) = ':'; - size -= n + 1; - } - p[-1] = '\0'; - return (buf); -} - -int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, - unsigned char *p, - int (*put_cb) (const SSL_CIPHER *, - unsigned char *)) -{ - int i, j = 0; - SSL_CIPHER *c; - CERT *ct = s->cert; - unsigned char *q; - int empty_reneg_info_scsv = !s->renegotiate; - /* Set disabled masks for this session */ - ssl_set_client_disabled(s); - - if (sk == NULL) - return (0); - q = p; - if (put_cb == NULL) - put_cb = s->method->put_cipher_by_char; - - for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { - c = sk_SSL_CIPHER_value(sk, i); - /* Skip disabled ciphers */ - if (c->algorithm_ssl & ct->mask_ssl || - c->algorithm_mkey & ct->mask_k || c->algorithm_auth & ct->mask_a) - continue; -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (c->id == SSL3_CK_SCSV) { - if (!empty_reneg_info_scsv) - continue; - else - empty_reneg_info_scsv = 0; - } -#endif - j = put_cb(c, p); - p += j; - } - /* - * If p == q, no ciphers; caller indicates an error. Otherwise, add - * applicable SCSVs. - */ - if (p != q) { - if (empty_reneg_info_scsv) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, - "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); -#endif - } - if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { - static SSL_CIPHER scsv = { - 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - j = put_cb(&scsv, p); - p += j; - } - } - - return (p - q); -} - -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, - int num, - STACK_OF(SSL_CIPHER) **skp) -{ - const SSL_CIPHER *c; - STACK_OF(SSL_CIPHER) *sk; - int i, n; - - if (s->s3) - s->s3->send_connection_binding = 0; - - n = ssl_put_cipher_by_char(s, NULL, NULL); - if (n == 0 || (num % n) != 0) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); - return (NULL); - } - if ((skp == NULL) || (*skp == NULL)) { - sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ - if(sk == NULL) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - return NULL; - } - } else { - sk = *skp; - sk_SSL_CIPHER_zero(sk); - } - - if (s->cert->ciphers_raw) - OPENSSL_free(s->cert->ciphers_raw); - s->cert->ciphers_raw = BUF_memdup(p, num); - if (s->cert->ciphers_raw == NULL) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - s->cert->ciphers_rawlen = (size_t)num; - - for (i = 0; i < num; i += n) { - /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ - if (s->s3 && (n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_SCSV & 0xff))) { - /* SCSV fatal if renegotiating */ - if (s->renegotiate) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); - ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - goto err; - } - s->s3->send_connection_binding = 1; - p += n; -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "SCSV received by server\n"); -#endif - continue; - } - - /* Check for TLS_FALLBACK_SCSV */ - if ((n != 3 || !p[0]) && - (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && - (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { - /* - * The SCSV indicates that the client previously tried a higher - * version. Fail if the current version is an unexpected - * downgrade. - */ - if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, - SSL_R_INAPPROPRIATE_FALLBACK); - if (s->s3) - ssl3_send_alert(s, SSL3_AL_FATAL, - SSL_AD_INAPPROPRIATE_FALLBACK); - goto err; - } - p += n; - continue; - } - - c = ssl_get_cipher_by_char(s, p); - p += n; - if (c != NULL) { - if (!sk_SSL_CIPHER_push(sk, c)) { - SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - } - } - - if (skp != NULL) - *skp = sk; - return (sk); - err: - if ((skp == NULL) || (*skp == NULL)) - sk_SSL_CIPHER_free(sk); - return (NULL); -} - -#ifndef OPENSSL_NO_TLSEXT -/** return a servername extension value if provided in Client Hello, or NULL. - * So far, only host_name types are defined (RFC 3546). - */ - -const char *SSL_get_servername(const SSL *s, const int type) -{ - if (type != TLSEXT_NAMETYPE_host_name) - return NULL; - - return s->session && !s->tlsext_hostname ? - s->session->tlsext_hostname : s->tlsext_hostname; -} - -int SSL_get_servername_type(const SSL *s) -{ - if (s->session - && (!s->tlsext_hostname ? s->session-> - tlsext_hostname : s->tlsext_hostname)) - return TLSEXT_NAMETYPE_host_name; - return -1; -} - -/* - * SSL_select_next_proto implements the standard protocol selection. It is - * expected that this function is called from the callback set by - * SSL_CTX_set_next_proto_select_cb. The protocol data is assumed to be a - * vector of 8-bit, length prefixed byte strings. The length byte itself is - * not included in the length. A byte string of length 0 is invalid. No byte - * string may be truncated. The current, but experimental algorithm for - * selecting the protocol is: 1) If the server doesn't support NPN then this - * is indicated to the callback. In this case, the client application has to - * abort the connection or have a default application level protocol. 2) If - * the server supports NPN, but advertises an empty list then the client - * selects the first protcol in its list, but indicates via the API that this - * fallback case was enacted. 3) Otherwise, the client finds the first - * protocol in the server's list that it supports and selects this protocol. - * This is because it's assumed that the server has better information about - * which protocol a client should use. 4) If the client doesn't support any - * of the server's advertised protocols, then this is treated the same as - * case 2. It returns either OPENSSL_NPN_NEGOTIATED if a common protocol was - * found, or OPENSSL_NPN_NO_OVERLAP if the fallback case was reached. - */ -int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, - const unsigned char *server, - unsigned int server_len, - const unsigned char *client, - unsigned int client_len) -{ - unsigned int i, j; - const unsigned char *result; - int status = OPENSSL_NPN_UNSUPPORTED; - - /* - * For each protocol in server preference order, see if we support it. - */ - for (i = 0; i < server_len;) { - for (j = 0; j < client_len;) { - if (server[i] == client[j] && - memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) { - /* We found a match */ - result = &server[i]; - status = OPENSSL_NPN_NEGOTIATED; - goto found; - } - j += client[j]; - j++; - } - i += server[i]; - i++; - } - - /* There's no overlap between our protocols and the server's list. */ - result = client; - status = OPENSSL_NPN_NO_OVERLAP; - - found: - *out = (unsigned char *)result + 1; - *outlen = result[0]; - return status; -} - -# ifndef OPENSSL_NO_NEXTPROTONEG -/* - * SSL_get0_next_proto_negotiated sets *data and *len to point to the - * client's requested protocol for this connection and returns 0. If the - * client didn't request any protocol, then *data is set to NULL. Note that - * the client can request any protocol it chooses. The value returned from - * this function need not be a member of the list of supported protocols - * provided by the callback. - */ -void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, - unsigned *len) -{ - *data = s->next_proto_negotiated; - if (!*data) { - *len = 0; - } else { - *len = s->next_proto_negotiated_len; - } -} - -/* - * SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when - * a TLS server needs a list of supported protocols for Next Protocol - * Negotiation. The returned list must be in wire format. The list is - * returned by setting |out| to point to it and |outlen| to its length. This - * memory will not be modified, but one should assume that the SSL* keeps a - * reference to it. The callback should return SSL_TLSEXT_ERR_OK if it - * wishes to advertise. Otherwise, no such extension will be included in the - * ServerHello. - */ -void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - const unsigned char - **out, - unsigned int *outlen, - void *arg), void *arg) -{ - ctx->next_protos_advertised_cb = cb; - ctx->next_protos_advertised_cb_arg = arg; -} - -/* - * SSL_CTX_set_next_proto_select_cb sets a callback that is called when a - * client needs to select a protocol from the server's provided list. |out| - * must be set to point to the selected protocol (which may be within |in|). - * The length of the protocol name must be written into |outlen|. The - * server's advertised protocols are provided in |in| and |inlen|. The - * callback can assume that |in| is syntactically valid. The client must - * select a protocol. It is fatal to the connection if this callback returns - * a value other than SSL_TLSEXT_ERR_OK. - */ -void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *s, unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), void *arg) -{ - ctx->next_proto_select_cb = cb; - ctx->next_proto_select_cb_arg = arg; -} -# endif - -/* - * SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|. - * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit - * length-prefixed strings). Returns 0 on success. - */ -int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, - unsigned protos_len) -{ - if (ctx->alpn_client_proto_list) - OPENSSL_free(ctx->alpn_client_proto_list); - - ctx->alpn_client_proto_list = OPENSSL_malloc(protos_len); - if (!ctx->alpn_client_proto_list) - return 1; - memcpy(ctx->alpn_client_proto_list, protos, protos_len); - ctx->alpn_client_proto_list_len = protos_len; - - return 0; -} - -/* - * SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|. - * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit - * length-prefixed strings). Returns 0 on success. - */ -int SSL_set_alpn_protos(SSL *ssl, const unsigned char *protos, - unsigned protos_len) -{ - if (ssl->alpn_client_proto_list) - OPENSSL_free(ssl->alpn_client_proto_list); - - ssl->alpn_client_proto_list = OPENSSL_malloc(protos_len); - if (!ssl->alpn_client_proto_list) - return 1; - memcpy(ssl->alpn_client_proto_list, protos, protos_len); - ssl->alpn_client_proto_list_len = protos_len; - - return 0; -} - -/* - * SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is - * called during ClientHello processing in order to select an ALPN protocol - * from the client's list of offered protocols. - */ -void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), void *arg) -{ - ctx->alpn_select_cb = cb; - ctx->alpn_select_cb_arg = arg; -} - -/* - * SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from - * |ssl|. On return it sets |*data| to point to |*len| bytes of protocol name - * (not including the leading length-prefix byte). If the server didn't - * respond with a negotiated protocol then |*len| will be zero. - */ -void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, - unsigned *len) -{ - *data = NULL; - if (ssl->s3) - *data = ssl->s3->alpn_selected; - if (*data == NULL) - *len = 0; - else - *len = ssl->s3->alpn_selected_len; -} - -#endif /* !OPENSSL_NO_TLSEXT */ - -int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, - const char *label, size_t llen, - const unsigned char *context, size_t contextlen, - int use_context) -{ - if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) - return -1; - - return s->method->ssl3_enc->export_keying_material(s, out, olen, label, - llen, context, - contextlen, use_context); -} - -static unsigned long ssl_session_hash(const SSL_SESSION *a) -{ - const unsigned char *session_id = a->session_id; - unsigned long l; - unsigned char tmp_storage[4]; - - if (a->session_id_length < sizeof(tmp_storage)) { - memset(tmp_storage, 0, sizeof(tmp_storage)); - memcpy(tmp_storage, a->session_id, a->session_id_length); - session_id = tmp_storage; - } - - l = (unsigned long) - ((unsigned long)session_id[0]) | - ((unsigned long)session_id[1] << 8L) | - ((unsigned long)session_id[2] << 16L) | - ((unsigned long)session_id[3] << 24L); - return (l); -} - -/* - * NB: If this function (or indeed the hash function which uses a sort of - * coarser function than this one) is changed, ensure - * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on - * being able to construct an SSL_SESSION that will collide with any existing - * session with a matching session ID. - */ -static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) -{ - if (a->ssl_version != b->ssl_version) - return (1); - if (a->session_id_length != b->session_id_length) - return (1); - return (memcmp(a->session_id, b->session_id, a->session_id_length)); -} - -/* - * These wrapper functions should remain rather than redeclaring - * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each - * variable. The reason is that the functions aren't static, they're exposed - * via ssl.h. - */ -static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION) -static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION) - -SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) -{ - SSL_CTX *ret = NULL; - - if (meth == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_NULL_SSL_METHOD_PASSED); - return (NULL); - } -#ifdef OPENSSL_FIPS - if (FIPS_mode() && (meth->version < TLS1_VERSION)) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); - return NULL; - } -#endif - - if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); - goto err; - } - ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX)); - if (ret == NULL) - goto err; - - memset(ret, 0, sizeof(SSL_CTX)); - - ret->method = meth; - - ret->cert_store = NULL; - ret->session_cache_mode = SSL_SESS_CACHE_SERVER; - ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; - ret->session_cache_head = NULL; - ret->session_cache_tail = NULL; - - /* We take the system default */ - ret->session_timeout = meth->get_timeout(); - - ret->new_session_cb = 0; - ret->remove_session_cb = 0; - ret->get_session_cb = 0; - ret->generate_session_id = 0; - - memset((char *)&ret->stats, 0, sizeof(ret->stats)); - - ret->references = 1; - ret->quiet_shutdown = 0; - -/* ret->cipher=NULL;*/ -/*- - ret->s2->challenge=NULL; - ret->master_key=NULL; - ret->key_arg=NULL; - ret->s2->conn_id=NULL; */ - - ret->info_callback = NULL; - - ret->app_verify_callback = 0; - ret->app_verify_arg = NULL; - - ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; - ret->read_ahead = 0; - ret->msg_callback = 0; - ret->msg_callback_arg = NULL; - ret->verify_mode = SSL_VERIFY_NONE; -#if 0 - ret->verify_depth = -1; /* Don't impose a limit (but x509_lu.c does) */ -#endif - ret->sid_ctx_length = 0; - ret->default_verify_callback = NULL; - if ((ret->cert = ssl_cert_new()) == NULL) - goto err; - - ret->default_passwd_callback = 0; - ret->default_passwd_callback_userdata = NULL; - ret->client_cert_cb = 0; - ret->app_gen_cookie_cb = 0; - ret->app_verify_cookie_cb = 0; - - ret->sessions = lh_SSL_SESSION_new(); - if (ret->sessions == NULL) - goto err; - ret->cert_store = X509_STORE_new(); - if (ret->cert_store == NULL) - goto err; - - ssl_create_cipher_list(ret->method, - &ret->cipher_list, &ret->cipher_list_by_id, - meth->version == - SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST, - ret->cert); - if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS); - goto err2; - } - - ret->param = X509_VERIFY_PARAM_new(); - if (!ret->param) - goto err; - - if ((ret->rsa_md5 = EVP_get_digestbyname("ssl2-md5")) == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES); - goto err2; - } - if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); - goto err2; - } - if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); - goto err2; - } - - if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL) - goto err; - - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); - - ret->extra_certs = NULL; - /* No compression for DTLS */ - if (!(meth->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS)) - ret->comp_methods = SSL_COMP_get_compression_methods(); - - ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; - -#ifndef OPENSSL_NO_TLSEXT - ret->tlsext_servername_callback = 0; - ret->tlsext_servername_arg = NULL; - /* Setup RFC4507 ticket keys */ - if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0) - || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) - || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) - ret->options |= SSL_OP_NO_TICKET; - - ret->tlsext_status_cb = 0; - ret->tlsext_status_arg = NULL; - -# ifndef OPENSSL_NO_NEXTPROTONEG - ret->next_protos_advertised_cb = 0; - ret->next_proto_select_cb = 0; -# endif -#endif -#ifndef OPENSSL_NO_PSK - ret->psk_identity_hint = NULL; - ret->psk_client_callback = NULL; - ret->psk_server_callback = NULL; -#endif -#ifndef OPENSSL_NO_SRP - SSL_CTX_SRP_CTX_init(ret); -#endif -#ifndef OPENSSL_NO_BUF_FREELISTS - ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; - ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); - if (!ret->rbuf_freelist) - goto err; - ret->rbuf_freelist->chunklen = 0; - ret->rbuf_freelist->len = 0; - ret->rbuf_freelist->head = NULL; - ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); - if (!ret->wbuf_freelist) - goto err; - ret->wbuf_freelist->chunklen = 0; - ret->wbuf_freelist->len = 0; - ret->wbuf_freelist->head = NULL; -#endif -#ifndef OPENSSL_NO_ENGINE - ret->client_cert_engine = NULL; -# ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO -# define eng_strx(x) #x -# define eng_str(x) eng_strx(x) - /* Use specific client engine automatically... ignore errors */ - { - ENGINE *eng; - eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); - if (!eng) { - ERR_clear_error(); - ENGINE_load_builtin_engines(); - eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); - } - if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) - ERR_clear_error(); - } -# endif -#endif - /* - * Default is to connect to non-RI servers. When RI is more widely - * deployed might change this. - */ - ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; - - /* - * Disable SSLv2 by default, callers that want to enable SSLv2 will have to - * explicitly clear this option via either of SSL_CTX_clear_options() or - * SSL_clear_options(). - */ - ret->options |= SSL_OP_NO_SSLv2; - - return (ret); - err: - SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); - err2: - if (ret != NULL) - SSL_CTX_free(ret); - return (NULL); -} - -#if 0 -static void SSL_COMP_free(SSL_COMP *comp) -{ - OPENSSL_free(comp); -} -#endif - -#ifndef OPENSSL_NO_BUF_FREELISTS -static void ssl_buf_freelist_free(SSL3_BUF_FREELIST *list) -{ - SSL3_BUF_FREELIST_ENTRY *ent, *next; - for (ent = list->head; ent; ent = next) { - next = ent->next; - OPENSSL_free(ent); - } - OPENSSL_free(list); -} -#endif - -void SSL_CTX_free(SSL_CTX *a) -{ - int i; - - if (a == NULL) - return; - - i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX); -#ifdef REF_PRINT - REF_PRINT("SSL_CTX", a); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "SSL_CTX_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - if (a->param) - X509_VERIFY_PARAM_free(a->param); - - /* - * Free internal session cache. However: the remove_cb() may reference - * the ex_data of SSL_CTX, thus the ex_data store can only be removed - * after the sessions were flushed. - * As the ex_data handling routines might also touch the session cache, - * the most secure solution seems to be: empty (flush) the cache, then - * free ex_data, then finally free the cache. - * (See ticket [openssl.org #212].) - */ - if (a->sessions != NULL) - SSL_CTX_flush_sessions(a, 0); - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); - - if (a->sessions != NULL) - lh_SSL_SESSION_free(a->sessions); - - if (a->cert_store != NULL) - X509_STORE_free(a->cert_store); - if (a->cipher_list != NULL) - sk_SSL_CIPHER_free(a->cipher_list); - if (a->cipher_list_by_id != NULL) - sk_SSL_CIPHER_free(a->cipher_list_by_id); - if (a->cert != NULL) - ssl_cert_free(a->cert); - if (a->client_CA != NULL) - sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free); - if (a->extra_certs != NULL) - sk_X509_pop_free(a->extra_certs, X509_free); -#if 0 /* This should never be done, since it - * removes a global database */ - if (a->comp_methods != NULL) - sk_SSL_COMP_pop_free(a->comp_methods, SSL_COMP_free); -#else - a->comp_methods = NULL; -#endif - -#ifndef OPENSSL_NO_SRTP - if (a->srtp_profiles) - sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); -#endif - -#ifndef OPENSSL_NO_PSK - if (a->psk_identity_hint) - OPENSSL_free(a->psk_identity_hint); -#endif -#ifndef OPENSSL_NO_SRP - SSL_CTX_SRP_CTX_free(a); -#endif -#ifndef OPENSSL_NO_ENGINE - if (a->client_cert_engine) - ENGINE_finish(a->client_cert_engine); -#endif - -#ifndef OPENSSL_NO_BUF_FREELISTS - if (a->wbuf_freelist) - ssl_buf_freelist_free(a->wbuf_freelist); - if (a->rbuf_freelist) - ssl_buf_freelist_free(a->rbuf_freelist); -#endif -#ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_EC - if (a->tlsext_ecpointformatlist) - OPENSSL_free(a->tlsext_ecpointformatlist); - if (a->tlsext_ellipticcurvelist) - OPENSSL_free(a->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ - if (a->alpn_client_proto_list != NULL) - OPENSSL_free(a->alpn_client_proto_list); -#endif - - OPENSSL_free(a); -} - -void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) -{ - ctx->default_passwd_callback = cb; -} - -void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) -{ - ctx->default_passwd_callback_userdata = u; -} - -void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, - int (*cb) (X509_STORE_CTX *, void *), - void *arg) -{ - ctx->app_verify_callback = cb; - ctx->app_verify_arg = arg; -} - -void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, - int (*cb) (int, X509_STORE_CTX *)) -{ - ctx->verify_mode = mode; - ctx->default_verify_callback = cb; -} - -void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) -{ - X509_VERIFY_PARAM_set_depth(ctx->param, depth); -} - -void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb) (SSL *ssl, void *arg), - void *arg) -{ - ssl_cert_set_cert_cb(c->cert, cb, arg); -} - -void SSL_set_cert_cb(SSL *s, int (*cb) (SSL *ssl, void *arg), void *arg) -{ - ssl_cert_set_cert_cb(s->cert, cb, arg); -} - -void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) -{ - CERT_PKEY *cpk; - int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign; - int rsa_enc_export, dh_rsa_export, dh_dsa_export; - int rsa_tmp_export, dh_tmp_export, kl; - unsigned long mask_k, mask_a, emask_k, emask_a; -#ifndef OPENSSL_NO_ECDSA - int have_ecc_cert, ecdsa_ok; -#endif -#ifndef OPENSSL_NO_ECDH - int have_ecdh_tmp, ecdh_ok, ecc_pkey_size; -#endif -#ifndef OPENSSL_NO_EC - X509 *x = NULL; - EVP_PKEY *ecc_pkey = NULL; - int signature_nid = 0, pk_nid = 0, md_nid = 0; -#endif - if (c == NULL) - return; - - kl = SSL_C_EXPORT_PKEYLENGTH(cipher); - -#ifndef OPENSSL_NO_RSA - rsa_tmp = (c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL); - rsa_tmp_export = (c->rsa_tmp_cb != NULL || - (rsa_tmp && RSA_size(c->rsa_tmp) * 8 <= kl)); -#else - rsa_tmp = rsa_tmp_export = 0; -#endif -#ifndef OPENSSL_NO_DH - dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL); - dh_tmp_export = (c->dh_tmp_cb != NULL || - (dh_tmp && DH_size(c->dh_tmp) * 8 <= kl)); -#else - dh_tmp = dh_tmp_export = 0; -#endif - -#ifndef OPENSSL_NO_ECDH - have_ecdh_tmp = (c->ecdh_tmp || c->ecdh_tmp_cb || c->ecdh_tmp_auto); -#endif - cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]); - rsa_enc = cpk->valid_flags & CERT_PKEY_VALID; - rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); - cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]); - rsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; - cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]); - dsa_sign = cpk->valid_flags & CERT_PKEY_SIGN; - cpk = &(c->pkeys[SSL_PKEY_DH_RSA]); - dh_rsa = cpk->valid_flags & CERT_PKEY_VALID; - dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); - cpk = &(c->pkeys[SSL_PKEY_DH_DSA]); -/* FIX THIS EAY EAY EAY */ - dh_dsa = cpk->valid_flags & CERT_PKEY_VALID; - dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); - cpk = &(c->pkeys[SSL_PKEY_ECC]); -#ifndef OPENSSL_NO_EC - have_ecc_cert = cpk->valid_flags & CERT_PKEY_VALID; -#endif - mask_k = 0; - mask_a = 0; - emask_k = 0; - emask_a = 0; - -#ifdef CIPHER_DEBUG - fprintf(stderr, - "rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n", - rsa_tmp, rsa_tmp_export, dh_tmp, have_ecdh_tmp, rsa_enc, - rsa_enc_export, rsa_sign, dsa_sign, dh_rsa, dh_dsa); -#endif - - cpk = &(c->pkeys[SSL_PKEY_GOST01]); - if (cpk->x509 != NULL && cpk->privatekey != NULL) { - mask_k |= SSL_kGOST; - mask_a |= SSL_aGOST01; - } - cpk = &(c->pkeys[SSL_PKEY_GOST94]); - if (cpk->x509 != NULL && cpk->privatekey != NULL) { - mask_k |= SSL_kGOST; - mask_a |= SSL_aGOST94; - } - - if (rsa_enc || (rsa_tmp && rsa_sign)) - mask_k |= SSL_kRSA; - if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc))) - emask_k |= SSL_kRSA; - -#if 0 - /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */ - if ((dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign)) - mask_k |= SSL_kEDH; - if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) && - (rsa_enc || rsa_sign || dsa_sign)) - emask_k |= SSL_kEDH; -#endif - - if (dh_tmp_export) - emask_k |= SSL_kEDH; - - if (dh_tmp) - mask_k |= SSL_kEDH; - - if (dh_rsa) - mask_k |= SSL_kDHr; - if (dh_rsa_export) - emask_k |= SSL_kDHr; - - if (dh_dsa) - mask_k |= SSL_kDHd; - if (dh_dsa_export) - emask_k |= SSL_kDHd; - - if (mask_k & (SSL_kDHr | SSL_kDHd)) - mask_a |= SSL_aDH; - - if (rsa_enc || rsa_sign) { - mask_a |= SSL_aRSA; - emask_a |= SSL_aRSA; - } - - if (dsa_sign) { - mask_a |= SSL_aDSS; - emask_a |= SSL_aDSS; - } - - mask_a |= SSL_aNULL; - emask_a |= SSL_aNULL; - -#ifndef OPENSSL_NO_KRB5 - mask_k |= SSL_kKRB5; - mask_a |= SSL_aKRB5; - emask_k |= SSL_kKRB5; - emask_a |= SSL_aKRB5; -#endif - - /* - * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites - * depending on the key usage extension. - */ -#ifndef OPENSSL_NO_EC - if (have_ecc_cert) { - cpk = &c->pkeys[SSL_PKEY_ECC]; - x = cpk->x509; - /* This call populates extension flags (ex_flags) */ - X509_check_purpose(x, -1, 0); -# ifndef OPENSSL_NO_ECDH - ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; -# endif - ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? - (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; - if (!(cpk->valid_flags & CERT_PKEY_SIGN)) - ecdsa_ok = 0; - ecc_pkey = X509_get_pubkey(x); -# ifndef OPENSSL_NO_ECDH - ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; -# endif - EVP_PKEY_free(ecc_pkey); - if ((x->sig_alg) && (x->sig_alg->algorithm)) { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } -# ifndef OPENSSL_NO_ECDH - if (ecdh_ok) { - - if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { - mask_k |= SSL_kECDHr; - mask_a |= SSL_aECDH; - if (ecc_pkey_size <= 163) { - emask_k |= SSL_kECDHr; - emask_a |= SSL_aECDH; - } - } - - if (pk_nid == NID_X9_62_id_ecPublicKey) { - mask_k |= SSL_kECDHe; - mask_a |= SSL_aECDH; - if (ecc_pkey_size <= 163) { - emask_k |= SSL_kECDHe; - emask_a |= SSL_aECDH; - } - } - } -# endif -# ifndef OPENSSL_NO_ECDSA - if (ecdsa_ok) { - mask_a |= SSL_aECDSA; - emask_a |= SSL_aECDSA; - } -# endif - } -#endif - -#ifndef OPENSSL_NO_ECDH - if (have_ecdh_tmp) { - mask_k |= SSL_kEECDH; - emask_k |= SSL_kEECDH; - } -#endif - -#ifndef OPENSSL_NO_PSK - mask_k |= SSL_kPSK; - mask_a |= SSL_aPSK; - emask_k |= SSL_kPSK; - emask_a |= SSL_aPSK; -#endif - - c->mask_k = mask_k; - c->mask_a = mask_a; - c->export_mask_k = emask_k; - c->export_mask_a = emask_a; - c->valid = 1; -} - -/* This handy macro borrowed from crypto/x509v3/v3_purp.c */ -#define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) - -#ifndef OPENSSL_NO_ECDH - -int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) -{ - unsigned long alg_k, alg_a; - EVP_PKEY *pkey = NULL; - int keysize = 0; - int signature_nid = 0, md_nid = 0, pk_nid = 0; - const SSL_CIPHER *cs = s->s3->tmp.new_cipher; - - alg_k = cs->algorithm_mkey; - alg_a = cs->algorithm_auth; - - if (SSL_C_IS_EXPORT(cs)) { - /* ECDH key length in export ciphers must be <= 163 bits */ - pkey = X509_get_pubkey(x); - if (pkey == NULL) - return 0; - keysize = EVP_PKEY_bits(pkey); - EVP_PKEY_free(pkey); - if (keysize > 163) - return 0; - } - - /* This call populates the ex_flags field correctly */ - X509_check_purpose(x, -1, 0); - if ((x->sig_alg) && (x->sig_alg->algorithm)) { - signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); - OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); - } - if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { - /* key usage, if present, must allow key agreement */ - if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); - return 0; - } - if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION) { - /* signature alg must be ECDSA */ - if (pk_nid != NID_X9_62_id_ecPublicKey) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE); - return 0; - } - } - if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION) { - /* signature alg must be RSA */ - - if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE); - return 0; - } - } - } - if (alg_a & SSL_aECDSA) { - /* key usage, if present, must allow signing */ - if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) { - SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, - SSL_R_ECC_CERT_NOT_FOR_SIGNING); - return 0; - } - } - - return 1; /* all checks are ok */ -} - -#endif - -static int ssl_get_server_cert_index(const SSL *s) -{ - int idx; - idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); - if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) - idx = SSL_PKEY_RSA_SIGN; - if (idx == -1) - SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR); - return idx; -} - -CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) -{ - CERT *c; - int i; - - c = s->cert; - if (!s->s3 || !s->s3->tmp.new_cipher) - return NULL; - ssl_set_cert_masks(c, s->s3->tmp.new_cipher); - -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - /* - * Broken protocol test: return last used certificate: which may mismatch - * the one expected. - */ - if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) - return c->key; -#endif - - i = ssl_get_server_cert_index(s); - - /* This may or may not be an error. */ - if (i < 0) - return NULL; - - /* May be NULL. */ - return &c->pkeys[i]; -} - -EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, - const EVP_MD **pmd) -{ - unsigned long alg_a; - CERT *c; - int idx = -1; - - alg_a = cipher->algorithm_auth; - c = s->cert; - -#ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - /* - * Broken protocol test: use last key: which may mismatch the one - * expected. - */ - if (c->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) - idx = c->key - c->pkeys; - else -#endif - - if ((alg_a & SSL_aDSS) && - (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) - idx = SSL_PKEY_DSA_SIGN; - else if (alg_a & SSL_aRSA) { - if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) - idx = SSL_PKEY_RSA_SIGN; - else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) - idx = SSL_PKEY_RSA_ENC; - } else if ((alg_a & SSL_aECDSA) && - (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) - idx = SSL_PKEY_ECC; - if (idx == -1) { - SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR); - return (NULL); - } - if (pmd) - *pmd = c->pkeys[idx].digest; - return c->pkeys[idx].privatekey; -} - -#ifndef OPENSSL_NO_TLSEXT -int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, - size_t *serverinfo_length) -{ - CERT *c = NULL; - int i = 0; - *serverinfo_length = 0; - - c = s->cert; - i = ssl_get_server_cert_index(s); - - if (i == -1) - return 0; - if (c->pkeys[i].serverinfo == NULL) - return 0; - - *serverinfo = c->pkeys[i].serverinfo; - *serverinfo_length = c->pkeys[i].serverinfo_length; - return 1; -} -#endif - -void ssl_update_cache(SSL *s, int mode) -{ - int i; - - /* - * If the session_id_length is 0, we are not supposed to cache it, and it - * would be rather hard to do anyway :-) - */ - if (s->session->session_id_length == 0) - return; - - i = s->session_ctx->session_cache_mode; - if ((i & mode) && (!s->hit) - && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) - || SSL_CTX_add_session(s->session_ctx, s->session)) - && (s->session_ctx->new_session_cb != NULL)) { - CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION); - if (!s->session_ctx->new_session_cb(s, s->session)) - SSL_SESSION_free(s->session); - } - - /* auto flush every 255 connections */ - if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) { - if ((((mode & SSL_SESS_CACHE_CLIENT) - ? s->session_ctx->stats.sess_connect_good - : s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) { - SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL)); - } - } -} - -const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) -{ - return ctx->method; -} - -const SSL_METHOD *SSL_get_ssl_method(SSL *s) -{ - return (s->method); -} - -int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth) -{ - int conn = -1; - int ret = 1; - - if (s->method != meth) { - if (s->handshake_func != NULL) - conn = (s->handshake_func == s->method->ssl_connect); - - if (s->method->version == meth->version) - s->method = meth; - else { - s->method->ssl_free(s); - s->method = meth; - ret = s->method->ssl_new(s); - } - - if (conn == 1) - s->handshake_func = meth->ssl_connect; - else if (conn == 0) - s->handshake_func = meth->ssl_accept; - } - return (ret); -} - -int SSL_get_error(const SSL *s, int i) -{ - int reason; - unsigned long l; - BIO *bio; - - if (i > 0) - return (SSL_ERROR_NONE); - - /* - * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc, - * where we do encode the error - */ - if ((l = ERR_peek_error()) != 0) { - if (ERR_GET_LIB(l) == ERR_LIB_SYS) - return (SSL_ERROR_SYSCALL); - else - return (SSL_ERROR_SSL); - } - - if ((i < 0) && SSL_want_read(s)) { - bio = SSL_get_rbio(s); - if (BIO_should_read(bio)) - return (SSL_ERROR_WANT_READ); - else if (BIO_should_write(bio)) - /* - * This one doesn't make too much sense ... We never try to write - * to the rbio, and an application program where rbio and wbio - * are separate couldn't even know what it should wait for. - * However if we ever set s->rwstate incorrectly (so that we have - * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and - * wbio *are* the same, this test works around that bug; so it - * might be safer to keep it. - */ - return (SSL_ERROR_WANT_WRITE); - else if (BIO_should_io_special(bio)) { - reason = BIO_get_retry_reason(bio); - if (reason == BIO_RR_CONNECT) - return (SSL_ERROR_WANT_CONNECT); - else if (reason == BIO_RR_ACCEPT) - return (SSL_ERROR_WANT_ACCEPT); - else - return (SSL_ERROR_SYSCALL); /* unknown */ - } - } - - if ((i < 0) && SSL_want_write(s)) { - bio = SSL_get_wbio(s); - if (BIO_should_write(bio)) - return (SSL_ERROR_WANT_WRITE); - else if (BIO_should_read(bio)) - /* - * See above (SSL_want_read(s) with BIO_should_write(bio)) - */ - return (SSL_ERROR_WANT_READ); - else if (BIO_should_io_special(bio)) { - reason = BIO_get_retry_reason(bio); - if (reason == BIO_RR_CONNECT) - return (SSL_ERROR_WANT_CONNECT); - else if (reason == BIO_RR_ACCEPT) - return (SSL_ERROR_WANT_ACCEPT); - else - return (SSL_ERROR_SYSCALL); - } - } - if ((i < 0) && SSL_want_x509_lookup(s)) { - return (SSL_ERROR_WANT_X509_LOOKUP); - } - - if (i == 0) { - if (s->version == SSL2_VERSION) { - /* assume it is the socket being closed */ - return (SSL_ERROR_ZERO_RETURN); - } else { - if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && - (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) - return (SSL_ERROR_ZERO_RETURN); - } - } - return (SSL_ERROR_SYSCALL); -} - -int SSL_do_handshake(SSL *s) -{ - int ret = 1; - - if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET); - return (-1); - } - - s->method->ssl_renegotiate_check(s); - - if (SSL_in_init(s) || SSL_in_before(s)) { - ret = s->handshake_func(s); - } - return (ret); -} - -/* - * For the next 2 functions, SSL_clear() sets shutdown and so one of these - * calls will reset it - */ -void SSL_set_accept_state(SSL *s) -{ - s->server = 1; - s->shutdown = 0; - s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE; - s->handshake_func = s->method->ssl_accept; - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); -} - -void SSL_set_connect_state(SSL *s) -{ - s->server = 0; - s->shutdown = 0; - s->state = SSL_ST_CONNECT | SSL_ST_BEFORE; - s->handshake_func = s->method->ssl_connect; - /* clear the current cipher */ - ssl_clear_cipher_ctx(s); - ssl_clear_hash_ctx(&s->read_hash); - ssl_clear_hash_ctx(&s->write_hash); -} - -int ssl_undefined_function(SSL *s) -{ - SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); -} - -int ssl_undefined_void_function(void) -{ - SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); -} - -int ssl_undefined_const_function(const SSL *s) -{ - SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION, - ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (0); -} - -SSL_METHOD *ssl_bad_method(int ver) -{ - SSLerr(SSL_F_SSL_BAD_METHOD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return (NULL); -} - -const char *SSL_get_version(const SSL *s) -{ - if (s->version == TLS1_2_VERSION) - return ("TLSv1.2"); - else if (s->version == TLS1_1_VERSION) - return ("TLSv1.1"); - else if (s->version == TLS1_VERSION) - return ("TLSv1"); - else if (s->version == SSL3_VERSION) - return ("SSLv3"); - else if (s->version == SSL2_VERSION) - return ("SSLv2"); - else if (s->version == DTLS1_BAD_VER) - return ("DTLSv0.9"); - else if (s->version == DTLS1_VERSION) - return ("DTLSv1"); - else if (s->version == DTLS1_2_VERSION) - return ("DTLSv1.2"); - else - return ("unknown"); -} - -SSL *SSL_dup(SSL *s) -{ - STACK_OF(X509_NAME) *sk; - X509_NAME *xn; - SSL *ret; - int i; - - if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL) - return (NULL); - - ret->version = s->version; - ret->type = s->type; - ret->method = s->method; - - if (s->session != NULL) { - /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */ - SSL_copy_session_id(ret, s); - } else { - /* - * No session has been established yet, so we have to expect that - * s->cert or ret->cert will be changed later -- they should not both - * point to the same object, and thus we can't use - * SSL_copy_session_id. - */ - - ret->method->ssl_free(ret); - ret->method = s->method; - ret->method->ssl_new(ret); - - if (s->cert != NULL) { - if (ret->cert != NULL) { - ssl_cert_free(ret->cert); - } - ret->cert = ssl_cert_dup(s->cert); - if (ret->cert == NULL) - goto err; - } - - SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length); - } - - ret->options = s->options; - ret->mode = s->mode; - SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s)); - SSL_set_read_ahead(ret, SSL_get_read_ahead(s)); - ret->msg_callback = s->msg_callback; - ret->msg_callback_arg = s->msg_callback_arg; - SSL_set_verify(ret, SSL_get_verify_mode(s), SSL_get_verify_callback(s)); - SSL_set_verify_depth(ret, SSL_get_verify_depth(s)); - ret->generate_session_id = s->generate_session_id; - - SSL_set_info_callback(ret, SSL_get_info_callback(s)); - - ret->debug = s->debug; - - /* copy app data, a little dangerous perhaps */ - if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data)) - goto err; - - /* setup rbio, and wbio */ - if (s->rbio != NULL) { - if (!BIO_dup_state(s->rbio, (char *)&ret->rbio)) - goto err; - } - if (s->wbio != NULL) { - if (s->wbio != s->rbio) { - if (!BIO_dup_state(s->wbio, (char *)&ret->wbio)) - goto err; - } else - ret->wbio = ret->rbio; - } - ret->rwstate = s->rwstate; - ret->in_handshake = s->in_handshake; - ret->handshake_func = s->handshake_func; - ret->server = s->server; - ret->renegotiate = s->renegotiate; - ret->new_session = s->new_session; - ret->quiet_shutdown = s->quiet_shutdown; - ret->shutdown = s->shutdown; - ret->state = s->state; /* SSL_dup does not really work at any state, - * though */ - ret->rstate = s->rstate; - ret->init_num = 0; /* would have to copy ret->init_buf, - * ret->init_msg, ret->init_num, - * ret->init_off */ - ret->hit = s->hit; - - X509_VERIFY_PARAM_inherit(ret->param, s->param); - - /* dup the cipher_list and cipher_list_by_id stacks */ - if (s->cipher_list != NULL) { - if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) - goto err; - } - if (s->cipher_list_by_id != NULL) - if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id)) - == NULL) - goto err; - - /* Dup the client_CA list */ - if (s->client_CA != NULL) { - if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL) - goto err; - ret->client_CA = sk; - for (i = 0; i < sk_X509_NAME_num(sk); i++) { - xn = sk_X509_NAME_value(sk, i); - if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) { - X509_NAME_free(xn); - goto err; - } - } - } - - if (0) { - err: - if (ret != NULL) - SSL_free(ret); - ret = NULL; - } - return (ret); -} - -void ssl_clear_cipher_ctx(SSL *s) -{ - if (s->enc_read_ctx != NULL) { - EVP_CIPHER_CTX_cleanup(s->enc_read_ctx); - OPENSSL_free(s->enc_read_ctx); - s->enc_read_ctx = NULL; - } - if (s->enc_write_ctx != NULL) { - EVP_CIPHER_CTX_cleanup(s->enc_write_ctx); - OPENSSL_free(s->enc_write_ctx); - s->enc_write_ctx = NULL; - } -#ifndef OPENSSL_NO_COMP - if (s->expand != NULL) { - COMP_CTX_free(s->expand); - s->expand = NULL; - } - if (s->compress != NULL) { - COMP_CTX_free(s->compress); - s->compress = NULL; - } -#endif -} - -X509 *SSL_get_certificate(const SSL *s) -{ - if (s->cert != NULL) - return (s->cert->key->x509); - else - return (NULL); -} - -EVP_PKEY *SSL_get_privatekey(const SSL *s) -{ - if (s->cert != NULL) - return (s->cert->key->privatekey); - else - return (NULL); -} - -X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) -{ - if (ctx->cert != NULL) - return ctx->cert->key->x509; - else - return NULL; -} - -EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) -{ - if (ctx->cert != NULL) - return ctx->cert->key->privatekey; - else - return NULL; -} - -const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) -{ - if ((s->session != NULL) && (s->session->cipher != NULL)) - return (s->session->cipher); - return (NULL); -} - -#ifdef OPENSSL_NO_COMP -const COMP_METHOD *SSL_get_current_compression(SSL *s) -{ - return NULL; -} - -const COMP_METHOD *SSL_get_current_expansion(SSL *s) -{ - return NULL; -} -#else - -const COMP_METHOD *SSL_get_current_compression(SSL *s) -{ - if (s->compress != NULL) - return (s->compress->meth); - return (NULL); -} - -const COMP_METHOD *SSL_get_current_expansion(SSL *s) -{ - if (s->expand != NULL) - return (s->expand->meth); - return (NULL); -} -#endif - -int ssl_init_wbio_buffer(SSL *s, int push) -{ - BIO *bbio; - - if (s->bbio == NULL) { - bbio = BIO_new(BIO_f_buffer()); - if (bbio == NULL) - return (0); - s->bbio = bbio; - } else { - bbio = s->bbio; - if (s->bbio == s->wbio) - s->wbio = BIO_pop(s->wbio); - } - (void)BIO_reset(bbio); -/* if (!BIO_set_write_buffer_size(bbio,16*1024)) */ - if (!BIO_set_read_buffer_size(bbio, 1)) { - SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB); - return (0); - } - if (push) { - if (s->wbio != bbio) - s->wbio = BIO_push(bbio, s->wbio); - } else { - if (s->wbio == bbio) - s->wbio = BIO_pop(bbio); - } - return (1); -} - -void ssl_free_wbio_buffer(SSL *s) -{ - if (s->bbio == NULL) - return; - - if (s->bbio == s->wbio) { - /* remove buffering */ - s->wbio = BIO_pop(s->wbio); -#ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids - * adding one more preprocessor symbol */ - assert(s->wbio != NULL); -#endif - } - BIO_free(s->bbio); - s->bbio = NULL; -} - -void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) -{ - ctx->quiet_shutdown = mode; -} - -int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) -{ - return (ctx->quiet_shutdown); -} - -void SSL_set_quiet_shutdown(SSL *s, int mode) -{ - s->quiet_shutdown = mode; -} - -int SSL_get_quiet_shutdown(const SSL *s) -{ - return (s->quiet_shutdown); -} - -void SSL_set_shutdown(SSL *s, int mode) -{ - s->shutdown = mode; -} - -int SSL_get_shutdown(const SSL *s) -{ - return (s->shutdown); -} - -int SSL_version(const SSL *s) -{ - return (s->version); -} - -SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) -{ - return (ssl->ctx); -} - -SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) -{ - CERT *ocert = ssl->cert; - if (ssl->ctx == ctx) - return ssl->ctx; -#ifndef OPENSSL_NO_TLSEXT - if (ctx == NULL) - ctx = ssl->initial_ctx; -#endif - ssl->cert = ssl_cert_dup(ctx->cert); - if (ocert) { - int i; - /* Preserve any already negotiated parameters */ - if (ssl->server) { - ssl->cert->peer_sigalgs = ocert->peer_sigalgs; - ssl->cert->peer_sigalgslen = ocert->peer_sigalgslen; - ocert->peer_sigalgs = NULL; - ssl->cert->ciphers_raw = ocert->ciphers_raw; - ssl->cert->ciphers_rawlen = ocert->ciphers_rawlen; - ocert->ciphers_raw = NULL; - } - for (i = 0; i < SSL_PKEY_NUM; i++) { - ssl->cert->pkeys[i].digest = ocert->pkeys[i].digest; - } -#ifndef OPENSSL_NO_TLSEXT - ssl->cert->alpn_proposed = ocert->alpn_proposed; - ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len; - ocert->alpn_proposed = NULL; - ssl->cert->alpn_sent = ocert->alpn_sent; - - if (!custom_exts_copy_flags(&ssl->cert->srv_ext, &ocert->srv_ext)) - return NULL; -#endif - ssl_cert_free(ocert); - } - - /* - * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH), - * so setter APIs must prevent invalid lengths from entering the system. - */ - OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx)); - - /* - * If the session ID context matches that of the parent SSL_CTX, - * inherit it from the new SSL_CTX as well. If however the context does - * not match (i.e., it was set per-ssl with SSL_set_session_id_context), - * leave it unchanged. - */ - if ((ssl->ctx != NULL) && - (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) && - (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0)) { - ssl->sid_ctx_length = ctx->sid_ctx_length; - memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx)); - } - - CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); - if (ssl->ctx != NULL) - SSL_CTX_free(ssl->ctx); /* decrement reference count */ - ssl->ctx = ctx; - - return (ssl->ctx); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) -{ - return (X509_STORE_set_default_paths(ctx->cert_store)); -} - -int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, - const char *CApath) -{ - return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath)); -} -#endif - -void SSL_set_info_callback(SSL *ssl, - void (*cb) (const SSL *ssl, int type, int val)) -{ - ssl->info_callback = cb; -} - -/* - * One compiler (Diab DCC) doesn't like argument names in returned function - * pointer. - */ -void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ , - int /* type */ , - int /* val */ ) { - return ssl->info_callback; -} - -int SSL_state(const SSL *ssl) -{ - return (ssl->state); -} - -void SSL_set_state(SSL *ssl, int state) -{ - ssl->state = state; -} - -void SSL_set_verify_result(SSL *ssl, long arg) -{ - ssl->verify_result = arg; -} - -long SSL_get_verify_result(const SSL *ssl) -{ - return (ssl->verify_result); -} - -int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, - new_func, dup_func, free_func); -} - -int SSL_set_ex_data(SSL *s, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); -} - -void *SSL_get_ex_data(const SSL *s, int idx) -{ - return (CRYPTO_get_ex_data(&s->ex_data, idx)); -} - -int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, - new_func, dup_func, free_func); -} - -int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); -} - -void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) -{ - return (CRYPTO_get_ex_data(&s->ex_data, idx)); -} - -int ssl_ok(SSL *s) -{ - return (1); -} - -X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) -{ - return (ctx->cert_store); -} - -void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) -{ - if (ctx->cert_store != NULL) - X509_STORE_free(ctx->cert_store); - ctx->cert_store = store; -} - -int SSL_want(const SSL *s) -{ - return (s->rwstate); -} - -/** - * \brief Set the callback for generating temporary RSA keys. - * \param ctx the SSL context. - * \param cb the callback - */ - -#ifndef OPENSSL_NO_RSA -void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb) (SSL *ssl, - int is_export, - int keylength)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb); -} - -void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb) (SSL *ssl, - int is_export, - int keylength)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb); -} -#endif - -#ifdef DOXYGEN -/** - * \brief The RSA temporary key callback function. - * \param ssl the SSL session. - * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite. - * \param keylength if \c is_export is \c TRUE, then \c keylength is the size - * of the required key in bits. - * \return the temporary RSA key. - * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback - */ - -RSA *cb(SSL *ssl, int is_export, int keylength) -{ -} -#endif - -/** - * \brief Set the callback for generating temporary DH keys. - * \param ctx the SSL context. - * \param dh the callback - */ - -#ifndef OPENSSL_NO_DH -void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, - DH *(*dh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); -} - -void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); -} -#endif - -#ifndef OPENSSL_NO_ECDH -void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, - EC_KEY *(*ecdh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, - (void (*)(void))ecdh); -} - -void SSL_set_tmp_ecdh_callback(SSL *ssl, - EC_KEY *(*ecdh) (SSL *ssl, int is_export, - int keylength)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh); -} -#endif - -#ifndef OPENSSL_NO_PSK -int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) -{ - if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, - SSL_R_DATA_LENGTH_TOO_LONG); - return 0; - } - if (ctx->psk_identity_hint != NULL) - OPENSSL_free(ctx->psk_identity_hint); - if (identity_hint != NULL) { - ctx->psk_identity_hint = BUF_strdup(identity_hint); - if (ctx->psk_identity_hint == NULL) - return 0; - } else - ctx->psk_identity_hint = NULL; - return 1; -} - -int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) -{ - if (s == NULL) - return 0; - - if (s->session == NULL) - return 1; /* session not created yet, ignored */ - - if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { - SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); - return 0; - } - if (s->session->psk_identity_hint != NULL) - OPENSSL_free(s->session->psk_identity_hint); - if (identity_hint != NULL) { - s->session->psk_identity_hint = BUF_strdup(identity_hint); - if (s->session->psk_identity_hint == NULL) - return 0; - } else - s->session->psk_identity_hint = NULL; - return 1; -} - -const char *SSL_get_psk_identity_hint(const SSL *s) -{ - if (s == NULL || s->session == NULL) - return NULL; - return (s->session->psk_identity_hint); -} - -const char *SSL_get_psk_identity(const SSL *s) -{ - if (s == NULL || s->session == NULL) - return NULL; - return (s->session->psk_identity); -} - -void SSL_set_psk_client_callback(SSL *s, - unsigned int (*cb) (SSL *ssl, - const char *hint, - char *identity, - unsigned int - max_identity_len, - unsigned char *psk, - unsigned int - max_psk_len)) -{ - s->psk_client_callback = cb; -} - -void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, - unsigned int (*cb) (SSL *ssl, - const char *hint, - char *identity, - unsigned int - max_identity_len, - unsigned char *psk, - unsigned int - max_psk_len)) -{ - ctx->psk_client_callback = cb; -} - -void SSL_set_psk_server_callback(SSL *s, - unsigned int (*cb) (SSL *ssl, - const char *identity, - unsigned char *psk, - unsigned int - max_psk_len)) -{ - s->psk_server_callback = cb; -} - -void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, - unsigned int (*cb) (SSL *ssl, - const char *identity, - unsigned char *psk, - unsigned int - max_psk_len)) -{ - ctx->psk_server_callback = cb; -} -#endif - -void SSL_CTX_set_msg_callback(SSL_CTX *ctx, - void (*cb) (int write_p, int version, - int content_type, const void *buf, - size_t len, SSL *ssl, void *arg)) -{ - SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); -} - -void SSL_set_msg_callback(SSL *ssl, - void (*cb) (int write_p, int version, - int content_type, const void *buf, - size_t len, SSL *ssl, void *arg)) -{ - SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); -} - -/* - * Allocates new EVP_MD_CTX and sets pointer to it into given pointer - * vairable, freeing EVP_MD_CTX previously stored in that variable, if any. - * If EVP_MD pointer is passed, initializes ctx with this md Returns newly - * allocated ctx; - */ - -EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) -{ - ssl_clear_hash_ctx(hash); - *hash = EVP_MD_CTX_create(); - if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) { - EVP_MD_CTX_destroy(*hash); - *hash = NULL; - return NULL; - } - return *hash; -} - -void ssl_clear_hash_ctx(EVP_MD_CTX **hash) -{ - - if (*hash) - EVP_MD_CTX_destroy(*hash); - *hash = NULL; -} - -void SSL_set_debug(SSL *s, int debug) -{ - s->debug = debug; -} - -int SSL_cache_hit(SSL *s) -{ - return s->hit; -} - -int SSL_is_server(SSL *s) -{ - return s->server; -} - -#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16) -# include "bio/bss_file.c" -#endif - -IMPLEMENT_STACK_OF(SSL_CIPHER) -IMPLEMENT_STACK_OF(SSL_COMP) -IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); -/* ssl/ssl_rsa.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "ssl_locl.h" -// #include "bio.h" -// #include "objects.h" -#include "evp.h" -// #include "x509.h" -// #include "pem.h" - -static int ssl_set_cert(CERT *c, X509 *x509); -static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); -int SSL_use_certificate(SSL *ssl, X509 *x) -{ - if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ssl->cert)) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); - return (0); - } - return (ssl_set_cert(ssl->cert, x)); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_use_certificate_file(SSL *ssl, const char *file, int type) -{ - int j; - BIO *in; - int ret = 0; - X509 *x = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, - ssl->ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); - goto end; - } - - ret = SSL_use_certificate(ssl, x); - end: - if (x != NULL) - X509_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) -{ - X509 *x; - int ret; - - x = d2i_X509(NULL, &d, (long)len); - if (x == NULL) { - SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_use_certificate(ssl, x); - X509_free(x); - return (ret); -} - -#ifndef OPENSSL_NO_RSA -int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) -{ - EVP_PKEY *pkey; - int ret; - - if (rsa == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ssl->cert)) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - if ((pkey = EVP_PKEY_new()) == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); - return (0); - } - - RSA_up_ref(rsa); - if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { - RSA_free(rsa); - return 0; - } - - ret = ssl_set_pkey(ssl->cert, pkey); - EVP_PKEY_free(pkey); - return (ret); -} -#endif - -static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) -{ - int i; - /* - * Special case for DH: check two DH certificate types for a match. This - * means for DH certificates we must set the certificate first. - */ - if (pkey->type == EVP_PKEY_DH) { - X509 *x; - i = -1; - x = c->pkeys[SSL_PKEY_DH_RSA].x509; - if (x && X509_check_private_key(x, pkey)) - i = SSL_PKEY_DH_RSA; - x = c->pkeys[SSL_PKEY_DH_DSA].x509; - if (i == -1 && x && X509_check_private_key(x, pkey)) - i = SSL_PKEY_DH_DSA; - ERR_clear_error(); - } else - i = ssl_cert_type(NULL, pkey); - if (i < 0) { - SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); - return (0); - } - - if (c->pkeys[i].x509 != NULL) { - EVP_PKEY *pktmp; - pktmp = X509_get_pubkey(c->pkeys[i].x509); - if (pktmp == NULL) { - SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE); - EVP_PKEY_free(pktmp); - return 0; - } - /* - * The return code from EVP_PKEY_copy_parameters is deliberately - * ignored. Some EVP_PKEY types cannot do this. - */ - EVP_PKEY_copy_parameters(pktmp, pkey); - EVP_PKEY_free(pktmp); - ERR_clear_error(); - -#ifndef OPENSSL_NO_RSA - /* - * Don't check the public/private key, this is mostly for smart - * cards. - */ - if ((pkey->type == EVP_PKEY_RSA) && - (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; - else -#endif - if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { - X509_free(c->pkeys[i].x509); - c->pkeys[i].x509 = NULL; - return 0; - } - } - - if (c->pkeys[i].privatekey != NULL) - EVP_PKEY_free(c->pkeys[i].privatekey); - CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - c->pkeys[i].privatekey = pkey; - c->key = &(c->pkeys[i]); - - c->valid = 0; - return (1); -} - -#ifndef OPENSSL_NO_RSA -# ifndef OPENSSL_NO_STDIO -int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - RSA *rsa = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, - ssl->ctx->default_passwd_callback, - ssl-> - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (rsa == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_use_RSAPrivateKey(ssl, rsa); - RSA_free(rsa); - end: - if (in != NULL) - BIO_free(in); - return (ret); -} -# endif - -int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len) -{ - int ret; - const unsigned char *p; - RSA *rsa; - - p = d; - if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_use_RSAPrivateKey(ssl, rsa); - RSA_free(rsa); - return (ret); -} -#endif /* !OPENSSL_NO_RSA */ - -int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) -{ - int ret; - - if (pkey == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ssl->cert)) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - ret = ssl_set_pkey(ssl->cert, pkey); - return (ret); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - EVP_PKEY *pkey = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - pkey = PEM_read_bio_PrivateKey(in, NULL, - ssl->ctx->default_passwd_callback, - ssl-> - ctx->default_passwd_callback_userdata); - } else if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - pkey = d2i_PrivateKey_bio(in, NULL); - } else { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (pkey == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_use_PrivateKey(ssl, pkey); - EVP_PKEY_free(pkey); - end: - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, - long len) -{ - int ret; - const unsigned char *p; - EVP_PKEY *pkey; - - p = d; - if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_use_PrivateKey(ssl, pkey); - EVP_PKEY_free(pkey); - return (ret); -} - -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) -{ - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ctx->cert)) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); - return (0); - } - return (ssl_set_cert(ctx->cert, x)); -} - -static int ssl_set_cert(CERT *c, X509 *x) -{ - EVP_PKEY *pkey; - int i; - - pkey = X509_get_pubkey(x); - if (pkey == NULL) { - SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); - return (0); - } - - i = ssl_cert_type(x, pkey); - if (i < 0) { - SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); - EVP_PKEY_free(pkey); - return (0); - } - - if (c->pkeys[i].privatekey != NULL) { - /* - * The return code from EVP_PKEY_copy_parameters is deliberately - * ignored. Some EVP_PKEY types cannot do this. - */ - EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); - ERR_clear_error(); - -#ifndef OPENSSL_NO_RSA - /* - * Don't check the public/private key, this is mostly for smart - * cards. - */ - if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && - (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & - RSA_METHOD_FLAG_NO_CHECK)) ; - else -#endif /* OPENSSL_NO_RSA */ - if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { - /* - * don't fail for a cert/key mismatch, just free current private - * key (when switching to a different cert & key, first this - * function should be used, then ssl_set_pkey - */ - EVP_PKEY_free(c->pkeys[i].privatekey); - c->pkeys[i].privatekey = NULL; - /* clear error queue */ - ERR_clear_error(); - } - } - - EVP_PKEY_free(pkey); - - if (c->pkeys[i].x509 != NULL) - X509_free(c->pkeys[i].x509); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - c->pkeys[i].x509 = x; - c->key = &(c->pkeys[i]); - - c->valid = 0; - return (1); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) -{ - int j; - BIO *in; - int ret = 0; - X509 *x = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - x = d2i_X509_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); - end: - if (x != NULL) - X509_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, - const unsigned char *d) -{ - X509 *x; - int ret; - - x = d2i_X509(NULL, &d, (long)len); - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_CTX_use_certificate(ctx, x); - X509_free(x); - return (ret); -} - -#ifndef OPENSSL_NO_RSA -int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) -{ - int ret; - EVP_PKEY *pkey; - - if (rsa == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ctx->cert)) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - if ((pkey = EVP_PKEY_new()) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); - return (0); - } - - RSA_up_ref(rsa); - if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { - RSA_free(rsa); - return 0; - } - - ret = ssl_set_pkey(ctx->cert, pkey); - EVP_PKEY_free(pkey); - return (ret); -} - -# ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - RSA *rsa = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - rsa = d2i_RSAPrivateKey_bio(in, NULL); - } else if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - rsa = PEM_read_bio_RSAPrivateKey(in, NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (rsa == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); - RSA_free(rsa); - end: - if (in != NULL) - BIO_free(in); - return (ret); -} -# endif - -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, - long len) -{ - int ret; - const unsigned char *p; - RSA *rsa; - - p = d; - if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); - RSA_free(rsa); - return (ret); -} -#endif /* !OPENSSL_NO_RSA */ - -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) -{ - if (pkey == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - if (!ssl_cert_inst(&ctx->cert)) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - return (ssl_set_pkey(ctx->cert, pkey)); -} - -#ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) -{ - int j, ret = 0; - BIO *in; - EVP_PKEY *pkey = NULL; - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_PEM) { - j = ERR_R_PEM_LIB; - pkey = PEM_read_bio_PrivateKey(in, NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - } else if (type == SSL_FILETYPE_ASN1) { - j = ERR_R_ASN1_LIB; - pkey = d2i_PrivateKey_bio(in, NULL); - } else { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); - goto end; - } - if (pkey == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); - goto end; - } - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - end: - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, - const unsigned char *d, long len) -{ - int ret; - const unsigned char *p; - EVP_PKEY *pkey; - - p = d; - if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); - return (0); - } - - ret = SSL_CTX_use_PrivateKey(ctx, pkey); - EVP_PKEY_free(pkey); - return (ret); -} - -#ifndef OPENSSL_NO_STDIO -/* - * Read a file that contains our certificate in "PEM" format, possibly - * followed by a sequence of CA certificates that should be sent to the peer - * in the Certificate message. - */ -int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) -{ - BIO *in; - int ret = 0; - X509 *x = NULL; - - ERR_clear_error(); /* clear error stack for - * SSL_CTX_use_certificate() */ - - in = BIO_new(BIO_s_file_internal()); - if (in == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); - goto end; - } - - x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - if (x == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); - goto end; - } - - ret = SSL_CTX_use_certificate(ctx, x); - - if (ERR_peek_error() != 0) - ret = 0; /* Key/certificate mismatch doesn't imply - * ret==0 ... */ - if (ret) { - /* - * If we could set up our certificate, now proceed to the CA - * certificates. - */ - X509 *ca; - int r; - unsigned long err; - - SSL_CTX_clear_chain_certs(ctx); - - while ((ca = PEM_read_bio_X509(in, NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata)) - != NULL) { - r = SSL_CTX_add0_chain_cert(ctx, ca); - if (!r) { - X509_free(ca); - ret = 0; - goto end; - } - /* - * Note that we must not free r if it was successfully added to - * the chain (while we must free the main certificate, since its - * reference count is increased by SSL_CTX_use_certificate). - */ - } - /* When the while loop ends, it's usually just EOF. */ - err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_PEM - && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) - ERR_clear_error(); - else - ret = 0; /* some real error */ - } - - end: - if (x != NULL) - X509_free(x); - if (in != NULL) - BIO_free(in); - return (ret); -} -#endif - -#ifndef OPENSSL_NO_TLSEXT -static int serverinfo_find_extension(const unsigned char *serverinfo, - size_t serverinfo_length, - unsigned int extension_type, - const unsigned char **extension_data, - size_t *extension_length) -{ - *extension_data = NULL; - *extension_length = 0; - if (serverinfo == NULL || serverinfo_length == 0) - return -1; - for (;;) { - unsigned int type = 0; - size_t len = 0; - - /* end of serverinfo */ - if (serverinfo_length == 0) - return 0; /* Extension not found */ - - /* read 2-byte type field */ - if (serverinfo_length < 2) - return -1; /* Error */ - type = (serverinfo[0] << 8) + serverinfo[1]; - serverinfo += 2; - serverinfo_length -= 2; - - /* read 2-byte len field */ - if (serverinfo_length < 2) - return -1; /* Error */ - len = (serverinfo[0] << 8) + serverinfo[1]; - serverinfo += 2; - serverinfo_length -= 2; - - if (len > serverinfo_length) - return -1; /* Error */ - - if (type == extension_type) { - *extension_data = serverinfo; - *extension_length = len; - return 1; /* Success */ - } - - serverinfo += len; - serverinfo_length -= len; - } - return 0; /* Error */ -} - -static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type, - const unsigned char *in, - size_t inlen, int *al, void *arg) -{ - - if (inlen != 0) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - return 1; -} - -static int serverinfo_srv_add_cb(SSL *s, unsigned int ext_type, - const unsigned char **out, size_t *outlen, - int *al, void *arg) -{ - const unsigned char *serverinfo = NULL; - size_t serverinfo_length = 0; - - /* Is there serverinfo data for the chosen server cert? */ - if ((ssl_get_server_cert_serverinfo(s, &serverinfo, - &serverinfo_length)) != 0) { - /* Find the relevant extension from the serverinfo */ - int retval = serverinfo_find_extension(serverinfo, serverinfo_length, - ext_type, out, outlen); - if (retval == -1) { - *al = SSL_AD_DECODE_ERROR; - return -1; /* Error */ - } - if (retval == 0) - return 0; /* No extension found, don't send extension */ - return 1; /* Send extension */ - } - return 0; /* No serverinfo data found, don't send - * extension */ -} - -/* - * With a NULL context, this function just checks that the serverinfo data - * parses correctly. With a non-NULL context, it registers callbacks for - * the included extensions. - */ -static int serverinfo_process_buffer(const unsigned char *serverinfo, - size_t serverinfo_length, SSL_CTX *ctx) -{ - if (serverinfo == NULL || serverinfo_length == 0) - return 0; - for (;;) { - unsigned int ext_type = 0; - size_t len = 0; - - /* end of serverinfo */ - if (serverinfo_length == 0) - return 1; - - /* read 2-byte type field */ - if (serverinfo_length < 2) - return 0; - /* FIXME: check for types we understand explicitly? */ - - /* Register callbacks for extensions */ - ext_type = (serverinfo[0] << 8) + serverinfo[1]; - if (ctx) { - int have_ext_cbs = 0; - size_t i; - custom_ext_methods *exts = &ctx->cert->srv_ext; - custom_ext_method *meth = exts->meths; - - for (i = 0; i < exts->meths_count; i++, meth++) { - if (ext_type == meth->ext_type) { - have_ext_cbs = 1; - break; - } - } - - if (!have_ext_cbs && !SSL_CTX_add_server_custom_ext(ctx, ext_type, - serverinfo_srv_add_cb, - NULL, NULL, - serverinfo_srv_parse_cb, - NULL)) - return 0; - } - - serverinfo += 2; - serverinfo_length -= 2; - - /* read 2-byte len field */ - if (serverinfo_length < 2) - return 0; - len = (serverinfo[0] << 8) + serverinfo[1]; - serverinfo += 2; - serverinfo_length -= 2; - - if (len > serverinfo_length) - return 0; - - serverinfo += len; - serverinfo_length -= len; - } -} - -int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, - size_t serverinfo_length) -{ - unsigned char *new_serverinfo; - - if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if (!serverinfo_process_buffer(serverinfo, serverinfo_length, NULL)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA); - return 0; - } - if (!ssl_cert_inst(&ctx->cert)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE); - return 0; - } - if (ctx->cert->key == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR); - return 0; - } - new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, - serverinfo_length); - if (new_serverinfo == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE); - return 0; - } - ctx->cert->key->serverinfo = new_serverinfo; - memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); - ctx->cert->key->serverinfo_length = serverinfo_length; - - /* - * Now that the serverinfo is validated and stored, go ahead and - * register callbacks. - */ - if (!serverinfo_process_buffer(serverinfo, serverinfo_length, ctx)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, SSL_R_INVALID_SERVERINFO_DATA); - return 0; - } - return 1; -} - -# ifndef OPENSSL_NO_STDIO -int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) -{ - unsigned char *serverinfo = NULL; - size_t serverinfo_length = 0; - unsigned char *extension = 0; - long extension_length = 0; - char *name = NULL; - char *header = NULL; - char namePrefix[] = "SERVERINFO FOR "; - int ret = 0; - BIO *bin = NULL; - size_t num_extensions = 0; - unsigned char *new_serverinfo; - - if (ctx == NULL || file == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - ERR_R_PASSED_NULL_PARAMETER); - goto end; - } - - bin = BIO_new(BIO_s_file_internal()); - if (bin == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_BUF_LIB); - goto end; - } - if (BIO_read_filename(bin, file) <= 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_SYS_LIB); - goto end; - } - - for (num_extensions = 0;; num_extensions++) { - if (PEM_read_bio(bin, &name, &header, &extension, &extension_length) - == 0) { - /* - * There must be at least one extension in this file - */ - if (num_extensions == 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_NO_PEM_EXTENSIONS); - goto end; - } else /* End of file, we're done */ - break; - } - /* Check that PEM name starts with "BEGIN SERVERINFO FOR " */ - if (strlen(name) < strlen(namePrefix)) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_PEM_NAME_TOO_SHORT); - goto end; - } - if (strncmp(name, namePrefix, strlen(namePrefix)) != 0) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, - SSL_R_PEM_NAME_BAD_PREFIX); - goto end; - } - /* - * Check that the decoded PEM data is plausible (valid length field) - */ - if (extension_length < 4 - || (extension[2] << 8) + extension[3] != extension_length - 4) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, SSL_R_BAD_DATA); - goto end; - } - /* Append the decoded extension to the serverinfo buffer */ - new_serverinfo = - OPENSSL_realloc(serverinfo, serverinfo_length + extension_length); - if (new_serverinfo == NULL) { - SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); - goto end; - } - serverinfo = new_serverinfo; - memcpy(serverinfo + serverinfo_length, extension, extension_length); - serverinfo_length += extension_length; - - OPENSSL_free(name); - name = NULL; - OPENSSL_free(header); - header = NULL; - OPENSSL_free(extension); - extension = NULL; - } - - ret = SSL_CTX_use_serverinfo(ctx, serverinfo, serverinfo_length); - end: - /* SSL_CTX_use_serverinfo makes a local copy of the serverinfo. */ - OPENSSL_free(name); - OPENSSL_free(header); - OPENSSL_free(extension); - OPENSSL_free(serverinfo); - if (bin != NULL) - BIO_free(bin); - return ret; -} -# endif /* OPENSSL_NO_STDIO */ -#endif /* OPENSSL_NO_TLSEXT */ -/* ssl/ssl_sess.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -// #include "lhash.h" -// #include "rand.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -// #include "ssl_locl.h" - -static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); -static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); -static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); - -SSL_SESSION *SSL_get_session(const SSL *ssl) -/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ -{ - return (ssl->session); -} - -SSL_SESSION *SSL_get1_session(SSL *ssl) -/* variant of SSL_get_session: caller really gets something */ -{ - SSL_SESSION *sess; - /* - * Need to lock this all up rather than just use CRYPTO_add so that - * somebody doesn't free ssl->session between when we check it's non-null - * and when we up the reference count. - */ - CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); - sess = ssl->session; - if (sess) - sess->references++; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); - return (sess); -} - -int SSL_SESSION_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp, - new_func, dup_func, free_func); -} - -int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); -} - -void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) -{ - return (CRYPTO_get_ex_data(&s->ex_data, idx)); -} - -SSL_SESSION *SSL_SESSION_new(void) -{ - SSL_SESSION *ss; - - ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION)); - if (ss == NULL) { - SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); - return (0); - } - memset(ss, 0, sizeof(SSL_SESSION)); - - ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ - ss->references = 1; - ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */ - ss->time = (unsigned long)time(NULL); - ss->prev = NULL; - ss->next = NULL; - ss->compress_meth = 0; -#ifndef OPENSSL_NO_TLSEXT - ss->tlsext_hostname = NULL; -# ifndef OPENSSL_NO_EC - ss->tlsext_ecpointformatlist_length = 0; - ss->tlsext_ecpointformatlist = NULL; - ss->tlsext_ellipticcurvelist_length = 0; - ss->tlsext_ellipticcurvelist = NULL; -# endif -#endif - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); -#ifndef OPENSSL_NO_PSK - ss->psk_identity_hint = NULL; - ss->psk_identity = NULL; -#endif -#ifndef OPENSSL_NO_SRP - ss->srp_username = NULL; -#endif - return (ss); -} - -/* - * Create a new SSL_SESSION and duplicate the contents of |src| into it. If - * ticket == 0 then no ticket information is duplicated, otherwise it is. - */ -SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) -{ - SSL_SESSION *dest; - - dest = OPENSSL_malloc(sizeof(*src)); - if (dest == NULL) { - goto err; - } - memcpy(dest, src, sizeof(*dest)); - - /* - * Set the various pointers to NULL so that we can call SSL_SESSION_free in - * the case of an error whilst halfway through constructing dest - */ -#ifndef OPENSSL_NO_PSK - dest->psk_identity_hint = NULL; - dest->psk_identity = NULL; -#endif - dest->ciphers = NULL; -#ifndef OPENSSL_NO_TLSEXT - dest->tlsext_hostname = NULL; -# ifndef OPENSSL_NO_EC - dest->tlsext_ecpointformatlist = NULL; - dest->tlsext_ellipticcurvelist = NULL; -# endif - dest->tlsext_tick = NULL; -#endif -#ifndef OPENSSL_NO_SRP - dest->srp_username = NULL; -#endif - - /* We deliberately don't copy the prev and next pointers */ - dest->prev = NULL; - dest->next = NULL; - - dest->references = 1; - - if (src->sess_cert != NULL) - CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); - - if (src->peer != NULL) - CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); - - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) - goto err; - -#ifndef OPENSSL_NO_PSK - if (src->psk_identity_hint) { - dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint); - if (dest->psk_identity_hint == NULL) { - goto err; - } - } - if (src->psk_identity) { - dest->psk_identity = BUF_strdup(src->psk_identity); - if (dest->psk_identity == NULL) { - goto err; - } - } -#endif - - if(src->ciphers != NULL) { - dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); - if (dest->ciphers == NULL) - goto err; - } - - if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, - &dest->ex_data, &src->ex_data)) { - goto err; - } - -#ifndef OPENSSL_NO_TLSEXT - if (src->tlsext_hostname) { - dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname); - if (dest->tlsext_hostname == NULL) { - goto err; - } - } -# ifndef OPENSSL_NO_EC - if (src->tlsext_ecpointformatlist) { - dest->tlsext_ecpointformatlist = - BUF_memdup(src->tlsext_ecpointformatlist, - src->tlsext_ecpointformatlist_length); - if (dest->tlsext_ecpointformatlist == NULL) - goto err; - } - if (src->tlsext_ellipticcurvelist) { - dest->tlsext_ellipticcurvelist = - BUF_memdup(src->tlsext_ellipticcurvelist, - src->tlsext_ellipticcurvelist_length); - if (dest->tlsext_ellipticcurvelist == NULL) - goto err; - } -# endif - - if (ticket != 0 && src->tlsext_tick != NULL) { - dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); - if(dest->tlsext_tick == NULL) - goto err; - } else { - dest->tlsext_tick_lifetime_hint = 0; - dest->tlsext_ticklen = 0; - } -#endif - -#ifndef OPENSSL_NO_SRP - if (src->srp_username) { - dest->srp_username = BUF_strdup(src->srp_username); - if (dest->srp_username == NULL) { - goto err; - } - } -#endif - - return dest; -err: - SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); - SSL_SESSION_free(dest); - return NULL; -} - -const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, - unsigned int *len) -{ - if (len) - *len = s->session_id_length; - return s->session_id; -} - -unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s) -{ - return s->compress_meth; -} - -/* - * Even with SSLv2, we have 16 bytes (128 bits) of session ID space. - * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random - * gunk repeatedly until we have no conflict is going to complete in one - * iteration pretty much "most" of the time (btw: understatement). So, if it - * takes us 10 iterations and we still can't avoid a conflict - well that's a - * reasonable point to call it quits. Either the RAND code is broken or - * someone is trying to open roughly very close to 2^128 (or 2^256) SSL - * sessions to our server. How you might store that many sessions is perhaps - * a more interesting question ... - */ - -#define MAX_SESS_ID_ATTEMPTS 10 -static int def_generate_session_id(const SSL *ssl, unsigned char *id, - unsigned int *id_len) -{ - unsigned int retry = 0; - do - if (RAND_bytes(id, *id_len) <= 0) - return 0; - while (SSL_has_matching_session_id(ssl, id, *id_len) && - (++retry < MAX_SESS_ID_ATTEMPTS)) ; - if (retry < MAX_SESS_ID_ATTEMPTS) - return 1; - /* else - woops a session_id match */ - /* - * XXX We should also check the external cache -- but the probability of - * a collision is negligible, and we could not prevent the concurrent - * creation of sessions with identical IDs since we currently don't have - * means to atomically check whether a session ID already exists and make - * a reservation for it if it does not (this problem applies to the - * internal cache as well). - */ - return 0; -} - -int ssl_get_new_session(SSL *s, int session) -{ - /* This gets used by clients and servers. */ - - unsigned int tmp; - SSL_SESSION *ss = NULL; - GEN_SESSION_CB cb = def_generate_session_id; - - if ((ss = SSL_SESSION_new()) == NULL) - return (0); - - /* If the context has a default timeout, use it */ - if (s->session_ctx->session_timeout == 0) - ss->timeout = SSL_get_default_timeout(s); - else - ss->timeout = s->session_ctx->session_timeout; - - if (s->session != NULL) { - SSL_SESSION_free(s->session); - s->session = NULL; - } - - if (session) { - if (s->version == SSL2_VERSION) { - ss->ssl_version = SSL2_VERSION; - ss->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; - } else if (s->version == SSL3_VERSION) { - ss->ssl_version = SSL3_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == TLS1_VERSION) { - ss->ssl_version = TLS1_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == TLS1_1_VERSION) { - ss->ssl_version = TLS1_1_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == TLS1_2_VERSION) { - ss->ssl_version = TLS1_2_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == DTLS1_BAD_VER) { - ss->ssl_version = DTLS1_BAD_VER; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == DTLS1_VERSION) { - ss->ssl_version = DTLS1_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else if (s->version == DTLS1_2_VERSION) { - ss->ssl_version = DTLS1_2_VERSION; - ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; - } else { - SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); - SSL_SESSION_free(ss); - return (0); - } -#ifndef OPENSSL_NO_TLSEXT - /*- - * If RFC5077 ticket, use empty session ID (as server). - * Note that: - * (a) ssl_get_prev_session() does lookahead into the - * ClientHello extensions to find the session ticket. - * When ssl_get_prev_session() fails, s3_srvr.c calls - * ssl_get_new_session() in ssl3_get_client_hello(). - * At that point, it has not yet parsed the extensions, - * however, because of the lookahead, it already knows - * whether a ticket is expected or not. - * - * (b) s3_clnt.c calls ssl_get_new_session() before parsing - * ServerHello extensions, and before recording the session - * ID received from the server, so this block is a noop. - */ - if (s->tlsext_ticket_expected) { - ss->session_id_length = 0; - goto sess_id_done; - } -#endif - /* Choose which callback will set the session ID */ - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - if (s->generate_session_id) - cb = s->generate_session_id; - else if (s->session_ctx->generate_session_id) - cb = s->session_ctx->generate_session_id; - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - /* Choose a session ID */ - tmp = ss->session_id_length; - if (!cb(s, ss->session_id, &tmp)) { - /* The callback failed */ - SSLerr(SSL_F_SSL_GET_NEW_SESSION, - SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); - SSL_SESSION_free(ss); - return (0); - } - /* - * Don't allow the callback to set the session length to zero. nor - * set it higher than it was. - */ - if (!tmp || (tmp > ss->session_id_length)) { - /* The callback set an illegal length */ - SSLerr(SSL_F_SSL_GET_NEW_SESSION, - SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); - SSL_SESSION_free(ss); - return (0); - } - /* If the session length was shrunk and we're SSLv2, pad it */ - if ((tmp < ss->session_id_length) && (s->version == SSL2_VERSION)) - memset(ss->session_id + tmp, 0, ss->session_id_length - tmp); - else - ss->session_id_length = tmp; - /* Finally, check for a conflict */ - if (SSL_has_matching_session_id(s, ss->session_id, - ss->session_id_length)) { - SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT); - SSL_SESSION_free(ss); - return (0); - } -#ifndef OPENSSL_NO_TLSEXT - sess_id_done: - if (s->tlsext_hostname) { - ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname); - if (ss->tlsext_hostname == NULL) { - SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); - SSL_SESSION_free(ss); - return 0; - } - } -#endif - } else { - ss->session_id_length = 0; - } - - if (s->sid_ctx_length > sizeof(ss->sid_ctx)) { - SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); - SSL_SESSION_free(ss); - return 0; - } - memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); - ss->sid_ctx_length = s->sid_ctx_length; - s->session = ss; - ss->ssl_version = s->version; - ss->verify_result = X509_V_OK; - - return (1); -} - -/*- - * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this - * connection. It is only called by servers. - * - * session_id: points at the session ID in the ClientHello. This code will - * read past the end of this in order to parse out the session ticket - * extension, if any. - * len: the length of the session ID. - * limit: a pointer to the first byte after the ClientHello. - * - * Returns: - * -1: error - * 0: a session may have been found. - * - * Side effects: - * - If a session is found then s->session is pointed at it (after freeing an - * existing session if need be) and s->verify_result is set from the session. - * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1 - * if the server should issue a new session ticket (to 0 otherwise). - */ -int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, - const unsigned char *limit) -{ - /* This is used only by servers. */ - - SSL_SESSION *ret = NULL; - int fatal = 0; - int try_session_cache = 1; -#ifndef OPENSSL_NO_TLSEXT - int r; -#endif - - if (limit - session_id < len) { - fatal = 1; - goto err; - } - - if (len == 0) - try_session_cache = 0; - -#ifndef OPENSSL_NO_TLSEXT - /* sets s->tlsext_ticket_expected */ - r = tls1_process_ticket(s, session_id, len, limit, &ret); - switch (r) { - case -1: /* Error during processing */ - fatal = 1; - goto err; - case 0: /* No ticket found */ - case 1: /* Zero length ticket found */ - break; /* Ok to carry on processing session id. */ - case 2: /* Ticket found but not decrypted. */ - case 3: /* Ticket decrypted, *ret has been set. */ - try_session_cache = 0; - break; - default: - abort(); - } -#endif - - if (try_session_cache && - ret == NULL && - !(s->session_ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { - SSL_SESSION data; - data.ssl_version = s->version; - data.session_id_length = len; - if (len == 0) - return 0; - memcpy(data.session_id, session_id, len); - CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); - ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); - if (ret != NULL) { - /* don't allow other threads to steal it: */ - CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); - } - CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); - if (ret == NULL) - s->session_ctx->stats.sess_miss++; - } - - if (try_session_cache && - ret == NULL && s->session_ctx->get_session_cb != NULL) { - int copy = 1; - - if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) { - s->session_ctx->stats.sess_cb_hit++; - - /* - * Increment reference count now if the session callback asks us - * to do so (note that if the session structures returned by the - * callback are shared between threads, it must handle the - * reference count itself [i.e. copy == 0], or things won't be - * thread-safe). - */ - if (copy) - CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); - - /* - * Add the externally cached session to the internal cache as - * well if and only if we are supposed to. - */ - if (! - (s->session_ctx->session_cache_mode & - SSL_SESS_CACHE_NO_INTERNAL_STORE)) - /* - * The following should not return 1, otherwise, things are - * very strange - */ - SSL_CTX_add_session(s->session_ctx, ret); - } - } - - if (ret == NULL) - goto err; - - /* Now ret is non-NULL and we own one of its reference counts. */ - - if (ret->sid_ctx_length != s->sid_ctx_length - || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) { - /* - * We have the session requested by the client, but we don't want to - * use it in this context. - */ - goto err; /* treat like cache miss */ - } - - if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { - /* - * We can't be sure if this session is being used out of context, - * which is especially important for SSL_VERIFY_PEER. The application - * should have used SSL[_CTX]_set_session_id_context. For this error - * case, we generate an error instead of treating the event like a - * cache miss (otherwise it would be easy for applications to - * effectively disable the session cache by accident without anyone - * noticing). - */ - - SSLerr(SSL_F_SSL_GET_PREV_SESSION, - SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); - fatal = 1; - goto err; - } - - if (ret->cipher == NULL) { - unsigned char buf[5], *p; - unsigned long l; - - p = buf; - l = ret->cipher_id; - l2n(l, p); - if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR) - ret->cipher = ssl_get_cipher_by_char(s, &(buf[2])); - else - ret->cipher = ssl_get_cipher_by_char(s, &(buf[1])); - if (ret->cipher == NULL) - goto err; - } - - if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */ - s->session_ctx->stats.sess_timeout++; - if (try_session_cache) { - /* session was from the cache, so remove it */ - SSL_CTX_remove_session(s->session_ctx, ret); - } - goto err; - } - - s->session_ctx->stats.sess_hit++; - - if (s->session != NULL) - SSL_SESSION_free(s->session); - s->session = ret; - s->verify_result = s->session->verify_result; - return 1; - - err: - if (ret != NULL) { - SSL_SESSION_free(ret); -#ifndef OPENSSL_NO_TLSEXT - if (!try_session_cache) { - /* - * The session was from a ticket, so we should issue a ticket for - * the new session - */ - s->tlsext_ticket_expected = 1; - } -#endif - } - if (fatal) - return -1; - else - return 0; -} - -int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) -{ - int ret = 0; - SSL_SESSION *s; - - /* - * add just 1 reference count for the SSL_CTX's session cache even though - * it has two ways of access: each session is in a doubly linked list and - * an lhash - */ - CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); - /* - * if session c is in already in cache, we take back the increment later - */ - - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - s = lh_SSL_SESSION_insert(ctx->sessions, c); - - /* - * s != NULL iff we already had a session with the given PID. In this - * case, s == c should hold (then we did not really modify - * ctx->sessions), or we're in trouble. - */ - if (s != NULL && s != c) { - /* We *are* in trouble ... */ - SSL_SESSION_list_remove(ctx, s); - SSL_SESSION_free(s); - /* - * ... so pretend the other session did not exist in cache (we cannot - * handle two SSL_SESSION structures with identical session ID in the - * same cache, which could happen e.g. when two threads concurrently - * obtain the same session from an external cache) - */ - s = NULL; - } else if (s == NULL && - lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) { - /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */ - - /* - * ... so take back the extra reference and also don't add - * the session to the SSL_SESSION_list at this time - */ - s = c; - } - - /* Put at the head of the queue unless it is already in the cache */ - if (s == NULL) - SSL_SESSION_list_add(ctx, c); - - if (s != NULL) { - /* - * existing cache entry -- decrement previously incremented reference - * count because it already takes into account the cache - */ - - SSL_SESSION_free(s); /* s == c */ - ret = 0; - } else { - /* - * new cache entry -- remove old ones if cache has become too large - */ - - ret = 1; - - if (SSL_CTX_sess_get_cache_size(ctx) > 0) { - while (SSL_CTX_sess_number(ctx) > - SSL_CTX_sess_get_cache_size(ctx)) { - if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) - break; - else - ctx->stats.sess_cache_full++; - } - } - } - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - return (ret); -} - -int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) -{ - return remove_session_lock(ctx, c, 1); -} - -static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) -{ - SSL_SESSION *r; - int ret = 0; - - if ((c != NULL) && (c->session_id_length != 0)) { - if (lck) - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { - ret = 1; - r = lh_SSL_SESSION_delete(ctx->sessions, c); - SSL_SESSION_list_remove(ctx, c); - } - - if (lck) - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); - - if (ret) { - r->not_resumable = 1; - if (ctx->remove_session_cb != NULL) - ctx->remove_session_cb(ctx, r); - SSL_SESSION_free(r); - } - } else - ret = 0; - return (ret); -} - -void SSL_SESSION_free(SSL_SESSION *ss) -{ - int i; - - if (ss == NULL) - return; - - i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); -#ifdef REF_PRINT - REF_PRINT("SSL_SESSION", ss); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "SSL_SESSION_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); - - OPENSSL_cleanse(ss->key_arg, sizeof(ss->key_arg)); - OPENSSL_cleanse(ss->master_key, sizeof(ss->master_key)); - OPENSSL_cleanse(ss->session_id, sizeof(ss->session_id)); - if (ss->sess_cert != NULL) - ssl_sess_cert_free(ss->sess_cert); - if (ss->peer != NULL) - X509_free(ss->peer); - if (ss->ciphers != NULL) - sk_SSL_CIPHER_free(ss->ciphers); -#ifndef OPENSSL_NO_TLSEXT - if (ss->tlsext_hostname != NULL) - OPENSSL_free(ss->tlsext_hostname); - if (ss->tlsext_tick != NULL) - OPENSSL_free(ss->tlsext_tick); -# ifndef OPENSSL_NO_EC - ss->tlsext_ecpointformatlist_length = 0; - if (ss->tlsext_ecpointformatlist != NULL) - OPENSSL_free(ss->tlsext_ecpointformatlist); - ss->tlsext_ellipticcurvelist_length = 0; - if (ss->tlsext_ellipticcurvelist != NULL) - OPENSSL_free(ss->tlsext_ellipticcurvelist); -# endif /* OPENSSL_NO_EC */ -#endif -#ifndef OPENSSL_NO_PSK - if (ss->psk_identity_hint != NULL) - OPENSSL_free(ss->psk_identity_hint); - if (ss->psk_identity != NULL) - OPENSSL_free(ss->psk_identity); -#endif -#ifndef OPENSSL_NO_SRP - if (ss->srp_username != NULL) - OPENSSL_free(ss->srp_username); -#endif - OPENSSL_cleanse(ss, sizeof(*ss)); - OPENSSL_free(ss); -} - -int SSL_set_session(SSL *s, SSL_SESSION *session) -{ - int ret = 0; - const SSL_METHOD *meth; - - if (session != NULL) { - meth = s->ctx->method->get_ssl_method(session->ssl_version); - if (meth == NULL) - meth = s->method->get_ssl_method(session->ssl_version); - if (meth == NULL) { - SSLerr(SSL_F_SSL_SET_SESSION, SSL_R_UNABLE_TO_FIND_SSL_METHOD); - return (0); - } - - if (meth != s->method) { - if (!SSL_set_ssl_method(s, meth)) - return (0); - } -#ifndef OPENSSL_NO_KRB5 - if (s->kssl_ctx && !s->kssl_ctx->client_princ && - session->krb5_client_princ_len > 0) { - s->kssl_ctx->client_princ = - (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); - if (s->kssl_ctx->client_princ == NULL) { - SSLerr(SSL_F_SSL_SET_SESSION, ERR_R_MALLOC_FAILURE); - return 0; - } - memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ, - session->krb5_client_princ_len); - s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; - } -#endif /* OPENSSL_NO_KRB5 */ - - /* CRYPTO_w_lock(CRYPTO_LOCK_SSL); */ - CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); - if (s->session != NULL) - SSL_SESSION_free(s->session); - s->session = session; - s->verify_result = s->session->verify_result; - /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL); */ - ret = 1; - } else { - if (s->session != NULL) { - SSL_SESSION_free(s->session); - s->session = NULL; - } - - meth = s->ctx->method; - if (meth != s->method) { - if (!SSL_set_ssl_method(s, meth)) - return (0); - } - ret = 1; - } - return (ret); -} - -long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) -{ - if (s == NULL) - return (0); - s->timeout = t; - return (1); -} - -long SSL_SESSION_get_timeout(const SSL_SESSION *s) -{ - if (s == NULL) - return (0); - return (s->timeout); -} - -long SSL_SESSION_get_time(const SSL_SESSION *s) -{ - if (s == NULL) - return (0); - return (s->time); -} - -long SSL_SESSION_set_time(SSL_SESSION *s, long t) -{ - if (s == NULL) - return (0); - s->time = t; - return (t); -} - -X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) -{ - return s->peer; -} - -int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, - unsigned int sid_ctx_len) -{ - if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { - SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT, - SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); - return 0; - } - s->sid_ctx_length = sid_ctx_len; - if (s->sid_ctx != sid_ctx) - memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); - - return 1; -} - -long SSL_CTX_set_timeout(SSL_CTX *s, long t) -{ - long l; - if (s == NULL) - return (0); - l = s->session_timeout; - s->session_timeout = t; - return (l); -} - -long SSL_CTX_get_timeout(const SSL_CTX *s) -{ - if (s == NULL) - return (0); - return (s->session_timeout); -} - -#ifndef OPENSSL_NO_TLSEXT -int SSL_set_session_secret_cb(SSL *s, - int (*tls_session_secret_cb) (SSL *s, - void *secret, - int *secret_len, - STACK_OF(SSL_CIPHER) - *peer_ciphers, - SSL_CIPHER - **cipher, - void *arg), - void *arg) -{ - if (s == NULL) - return (0); - s->tls_session_secret_cb = tls_session_secret_cb; - s->tls_session_secret_cb_arg = arg; - return (1); -} - -int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, - void *arg) -{ - if (s == NULL) - return (0); - s->tls_session_ticket_ext_cb = cb; - s->tls_session_ticket_ext_cb_arg = arg; - return (1); -} - -int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) -{ - if (s->version >= TLS1_VERSION) { - if (s->tlsext_session_ticket) { - OPENSSL_free(s->tlsext_session_ticket); - s->tlsext_session_ticket = NULL; - } - - s->tlsext_session_ticket = - OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); - if (!s->tlsext_session_ticket) { - SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); - return 0; - } - - if (ext_data) { - s->tlsext_session_ticket->length = ext_len; - s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; - memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); - } else { - s->tlsext_session_ticket->length = 0; - s->tlsext_session_ticket->data = NULL; - } - - return 1; - } - - return 0; -} -#endif /* OPENSSL_NO_TLSEXT */ - -typedef struct timeout_param_st { - SSL_CTX *ctx; - long time; - LHASH_OF(SSL_SESSION) *cache; -} TIMEOUT_PARAM; - -static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) -{ - if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */ - /* - * The reason we don't call SSL_CTX_remove_session() is to save on - * locking overhead - */ - (void)lh_SSL_SESSION_delete(p->cache, s); - SSL_SESSION_list_remove(p->ctx, s); - s->not_resumable = 1; - if (p->ctx->remove_session_cb != NULL) - p->ctx->remove_session_cb(p->ctx, s); - SSL_SESSION_free(s); - } -} - -static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM) - -void SSL_CTX_flush_sessions(SSL_CTX *s, long t) -{ - unsigned long i; - TIMEOUT_PARAM tp; - - tp.ctx = s; - tp.cache = s->sessions; - if (tp.cache == NULL) - return; - tp.time = t; - CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); - i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; - CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; - lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), - TIMEOUT_PARAM, &tp); - CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; - CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); -} - -int ssl_clear_bad_session(SSL *s) -{ - if ((s->session != NULL) && - !(s->shutdown & SSL_SENT_SHUTDOWN) && - !(SSL_in_init(s) || SSL_in_before(s))) { - SSL_CTX_remove_session(s->session_ctx, s->session); - return (1); - } else - return (0); -} - -/* locked by SSL_CTX in the calling function */ -static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) -{ - if ((s->next == NULL) || (s->prev == NULL)) - return; - - if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { - /* last element in list */ - if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { - /* only one element in list */ - ctx->session_cache_head = NULL; - ctx->session_cache_tail = NULL; - } else { - ctx->session_cache_tail = s->prev; - s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); - } - } else { - if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { - /* first element in list */ - ctx->session_cache_head = s->next; - s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); - } else { - /* middle of list */ - s->next->prev = s->prev; - s->prev->next = s->next; - } - } - s->prev = s->next = NULL; -} - -static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) -{ - if ((s->next != NULL) && (s->prev != NULL)) - SSL_SESSION_list_remove(ctx, s); - - if (ctx->session_cache_head == NULL) { - ctx->session_cache_head = s; - ctx->session_cache_tail = s; - s->prev = (SSL_SESSION *)&(ctx->session_cache_head); - s->next = (SSL_SESSION *)&(ctx->session_cache_tail); - } else { - s->next = ctx->session_cache_head; - s->next->prev = s; - s->prev = (SSL_SESSION *)&(ctx->session_cache_head); - ctx->session_cache_head = s; - } -} - -void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, - int (*cb) (struct ssl_st *ssl, - SSL_SESSION *sess)) -{ - ctx->new_session_cb = cb; -} - -int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) { - return ctx->new_session_cb; -} - -void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, - void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess)) -{ - ctx->remove_session_cb = cb; -} - -void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx, - SSL_SESSION *sess) { - return ctx->remove_session_cb; -} - -void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, - SSL_SESSION *(*cb) (struct ssl_st *ssl, - unsigned char *data, int len, - int *copy)) -{ - ctx->get_session_cb = cb; -} - -SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl, - unsigned char *data, - int len, int *copy) { - return ctx->get_session_cb; -} - -void SSL_CTX_set_info_callback(SSL_CTX *ctx, - void (*cb) (const SSL *ssl, int type, int val)) -{ - ctx->info_callback = cb; -} - -void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, - int val) { - return ctx->info_callback; -} - -void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, X509 **x509, - EVP_PKEY **pkey)) -{ - ctx->client_cert_cb = cb; -} - -int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, - EVP_PKEY **pkey) { - return ctx->client_cert_cb; -} - -#ifndef OPENSSL_NO_ENGINE -int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) -{ - if (!ENGINE_init(e)) { - SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB); - return 0; - } - if (!ENGINE_get_ssl_client_cert_function(e)) { - SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, - SSL_R_NO_CLIENT_CERT_METHOD); - ENGINE_finish(e); - return 0; - } - ctx->client_cert_engine = e; - return 1; -} -#endif - -void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - unsigned char *cookie, - unsigned int *cookie_len)) -{ - ctx->app_gen_cookie_cb = cb; -} - -void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, unsigned char *cookie, - unsigned int cookie_len)) -{ - ctx->app_verify_cookie_cb = cb; -} - -IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, - SSL_SESSION) -/* ssl/ssl_stat.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -// #include "ssl_locl.h" - -const char *SSL_state_string_long(const SSL *s) -{ - const char *str; - - switch (s->state) { - case SSL_ST_BEFORE: - str = "before SSL initialization"; - break; - case SSL_ST_ACCEPT: - str = "before accept initialization"; - break; - case SSL_ST_CONNECT: - str = "before connect initialization"; - break; - case SSL_ST_OK: - str = "SSL negotiation finished successfully"; - break; - case SSL_ST_RENEGOTIATE: - str = "SSL renegotiate ciphers"; - break; - case SSL_ST_BEFORE | SSL_ST_CONNECT: - str = "before/connect initialization"; - break; - case SSL_ST_OK | SSL_ST_CONNECT: - str = "ok/connect SSL initialization"; - break; - case SSL_ST_BEFORE | SSL_ST_ACCEPT: - str = "before/accept initialization"; - break; - case SSL_ST_OK | SSL_ST_ACCEPT: - str = "ok/accept SSL initialization"; - break; - case SSL_ST_ERR: - str = "error"; - break; -#ifndef OPENSSL_NO_SSL2 - case SSL2_ST_CLIENT_START_ENCRYPTION: - str = "SSLv2 client start encryption"; - break; - case SSL2_ST_SERVER_START_ENCRYPTION: - str = "SSLv2 server start encryption"; - break; - case SSL2_ST_SEND_CLIENT_HELLO_A: - str = "SSLv2 write client hello A"; - break; - case SSL2_ST_SEND_CLIENT_HELLO_B: - str = "SSLv2 write client hello B"; - break; - case SSL2_ST_GET_SERVER_HELLO_A: - str = "SSLv2 read server hello A"; - break; - case SSL2_ST_GET_SERVER_HELLO_B: - str = "SSLv2 read server hello B"; - break; - case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: - str = "SSLv2 write client master key A"; - break; - case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: - str = "SSLv2 write client master key B"; - break; - case SSL2_ST_SEND_CLIENT_FINISHED_A: - str = "SSLv2 write client finished A"; - break; - case SSL2_ST_SEND_CLIENT_FINISHED_B: - str = "SSLv2 write client finished B"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: - str = "SSLv2 write client certificate A"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: - str = "SSLv2 write client certificate B"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: - str = "SSLv2 write client certificate C"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: - str = "SSLv2 write client certificate D"; - break; - case SSL2_ST_GET_SERVER_VERIFY_A: - str = "SSLv2 read server verify A"; - break; - case SSL2_ST_GET_SERVER_VERIFY_B: - str = "SSLv2 read server verify B"; - break; - case SSL2_ST_GET_SERVER_FINISHED_A: - str = "SSLv2 read server finished A"; - break; - case SSL2_ST_GET_SERVER_FINISHED_B: - str = "SSLv2 read server finished B"; - break; - case SSL2_ST_GET_CLIENT_HELLO_A: - str = "SSLv2 read client hello A"; - break; - case SSL2_ST_GET_CLIENT_HELLO_B: - str = "SSLv2 read client hello B"; - break; - case SSL2_ST_GET_CLIENT_HELLO_C: - str = "SSLv2 read client hello C"; - break; - case SSL2_ST_SEND_SERVER_HELLO_A: - str = "SSLv2 write server hello A"; - break; - case SSL2_ST_SEND_SERVER_HELLO_B: - str = "SSLv2 write server hello B"; - break; - case SSL2_ST_GET_CLIENT_MASTER_KEY_A: - str = "SSLv2 read client master key A"; - break; - case SSL2_ST_GET_CLIENT_MASTER_KEY_B: - str = "SSLv2 read client master key B"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_A: - str = "SSLv2 write server verify A"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_B: - str = "SSLv2 write server verify B"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_C: - str = "SSLv2 write server verify C"; - break; - case SSL2_ST_GET_CLIENT_FINISHED_A: - str = "SSLv2 read client finished A"; - break; - case SSL2_ST_GET_CLIENT_FINISHED_B: - str = "SSLv2 read client finished B"; - break; - case SSL2_ST_SEND_SERVER_FINISHED_A: - str = "SSLv2 write server finished A"; - break; - case SSL2_ST_SEND_SERVER_FINISHED_B: - str = "SSLv2 write server finished B"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: - str = "SSLv2 write request certificate A"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: - str = "SSLv2 write request certificate B"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: - str = "SSLv2 write request certificate C"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: - str = "SSLv2 write request certificate D"; - break; - case SSL2_ST_X509_GET_SERVER_CERTIFICATE: - str = "SSLv2 X509 read server certificate"; - break; - case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: - str = "SSLv2 X509 read client certificate"; - break; -#endif - -#ifndef OPENSSL_NO_SSL3 -/* SSLv3 additions */ - case SSL3_ST_CW_CLNT_HELLO_A: - str = "SSLv3 write client hello A"; - break; - case SSL3_ST_CW_CLNT_HELLO_B: - str = "SSLv3 write client hello B"; - break; - case SSL3_ST_CR_SRVR_HELLO_A: - str = "SSLv3 read server hello A"; - break; - case SSL3_ST_CR_SRVR_HELLO_B: - str = "SSLv3 read server hello B"; - break; - case SSL3_ST_CR_CERT_A: - str = "SSLv3 read server certificate A"; - break; - case SSL3_ST_CR_CERT_B: - str = "SSLv3 read server certificate B"; - break; - case SSL3_ST_CR_KEY_EXCH_A: - str = "SSLv3 read server key exchange A"; - break; - case SSL3_ST_CR_KEY_EXCH_B: - str = "SSLv3 read server key exchange B"; - break; - case SSL3_ST_CR_CERT_REQ_A: - str = "SSLv3 read server certificate request A"; - break; - case SSL3_ST_CR_CERT_REQ_B: - str = "SSLv3 read server certificate request B"; - break; - case SSL3_ST_CR_SESSION_TICKET_A: - str = "SSLv3 read server session ticket A"; - break; - case SSL3_ST_CR_SESSION_TICKET_B: - str = "SSLv3 read server session ticket B"; - break; - case SSL3_ST_CR_SRVR_DONE_A: - str = "SSLv3 read server done A"; - break; - case SSL3_ST_CR_SRVR_DONE_B: - str = "SSLv3 read server done B"; - break; - case SSL3_ST_CW_CERT_A: - str = "SSLv3 write client certificate A"; - break; - case SSL3_ST_CW_CERT_B: - str = "SSLv3 write client certificate B"; - break; - case SSL3_ST_CW_CERT_C: - str = "SSLv3 write client certificate C"; - break; - case SSL3_ST_CW_CERT_D: - str = "SSLv3 write client certificate D"; - break; - case SSL3_ST_CW_KEY_EXCH_A: - str = "SSLv3 write client key exchange A"; - break; - case SSL3_ST_CW_KEY_EXCH_B: - str = "SSLv3 write client key exchange B"; - break; - case SSL3_ST_CW_CERT_VRFY_A: - str = "SSLv3 write certificate verify A"; - break; - case SSL3_ST_CW_CERT_VRFY_B: - str = "SSLv3 write certificate verify B"; - break; - - case SSL3_ST_CW_CHANGE_A: - case SSL3_ST_SW_CHANGE_A: - str = "SSLv3 write change cipher spec A"; - break; - case SSL3_ST_CW_CHANGE_B: - case SSL3_ST_SW_CHANGE_B: - str = "SSLv3 write change cipher spec B"; - break; - case SSL3_ST_CW_FINISHED_A: - case SSL3_ST_SW_FINISHED_A: - str = "SSLv3 write finished A"; - break; - case SSL3_ST_CW_FINISHED_B: - case SSL3_ST_SW_FINISHED_B: - str = "SSLv3 write finished B"; - break; - case SSL3_ST_CR_CHANGE_A: - case SSL3_ST_SR_CHANGE_A: - str = "SSLv3 read change cipher spec A"; - break; - case SSL3_ST_CR_CHANGE_B: - case SSL3_ST_SR_CHANGE_B: - str = "SSLv3 read change cipher spec B"; - break; - case SSL3_ST_CR_FINISHED_A: - case SSL3_ST_SR_FINISHED_A: - str = "SSLv3 read finished A"; - break; - case SSL3_ST_CR_FINISHED_B: - case SSL3_ST_SR_FINISHED_B: - str = "SSLv3 read finished B"; - break; - - case SSL3_ST_CW_FLUSH: - case SSL3_ST_SW_FLUSH: - str = "SSLv3 flush data"; - break; - - case SSL3_ST_SR_CLNT_HELLO_A: - str = "SSLv3 read client hello A"; - break; - case SSL3_ST_SR_CLNT_HELLO_B: - str = "SSLv3 read client hello B"; - break; - case SSL3_ST_SR_CLNT_HELLO_C: - str = "SSLv3 read client hello C"; - break; - case SSL3_ST_SW_HELLO_REQ_A: - str = "SSLv3 write hello request A"; - break; - case SSL3_ST_SW_HELLO_REQ_B: - str = "SSLv3 write hello request B"; - break; - case SSL3_ST_SW_HELLO_REQ_C: - str = "SSLv3 write hello request C"; - break; - case SSL3_ST_SW_SRVR_HELLO_A: - str = "SSLv3 write server hello A"; - break; - case SSL3_ST_SW_SRVR_HELLO_B: - str = "SSLv3 write server hello B"; - break; - case SSL3_ST_SW_CERT_A: - str = "SSLv3 write certificate A"; - break; - case SSL3_ST_SW_CERT_B: - str = "SSLv3 write certificate B"; - break; - case SSL3_ST_SW_KEY_EXCH_A: - str = "SSLv3 write key exchange A"; - break; - case SSL3_ST_SW_KEY_EXCH_B: - str = "SSLv3 write key exchange B"; - break; - case SSL3_ST_SW_CERT_REQ_A: - str = "SSLv3 write certificate request A"; - break; - case SSL3_ST_SW_CERT_REQ_B: - str = "SSLv3 write certificate request B"; - break; - case SSL3_ST_SW_SESSION_TICKET_A: - str = "SSLv3 write session ticket A"; - break; - case SSL3_ST_SW_SESSION_TICKET_B: - str = "SSLv3 write session ticket B"; - break; - case SSL3_ST_SW_SRVR_DONE_A: - str = "SSLv3 write server done A"; - break; - case SSL3_ST_SW_SRVR_DONE_B: - str = "SSLv3 write server done B"; - break; - case SSL3_ST_SR_CERT_A: - str = "SSLv3 read client certificate A"; - break; - case SSL3_ST_SR_CERT_B: - str = "SSLv3 read client certificate B"; - break; - case SSL3_ST_SR_KEY_EXCH_A: - str = "SSLv3 read client key exchange A"; - break; - case SSL3_ST_SR_KEY_EXCH_B: - str = "SSLv3 read client key exchange B"; - break; - case SSL3_ST_SR_CERT_VRFY_A: - str = "SSLv3 read certificate verify A"; - break; - case SSL3_ST_SR_CERT_VRFY_B: - str = "SSLv3 read certificate verify B"; - break; -#endif - -/* SSLv2/v3 compatibility states */ -/* client */ - case SSL23_ST_CW_CLNT_HELLO_A: - str = "SSLv2/v3 write client hello A"; - break; - case SSL23_ST_CW_CLNT_HELLO_B: - str = "SSLv2/v3 write client hello B"; - break; - case SSL23_ST_CR_SRVR_HELLO_A: - str = "SSLv2/v3 read server hello A"; - break; - case SSL23_ST_CR_SRVR_HELLO_B: - str = "SSLv2/v3 read server hello B"; - break; -/* server */ - case SSL23_ST_SR_CLNT_HELLO_A: - str = "SSLv2/v3 read client hello A"; - break; - case SSL23_ST_SR_CLNT_HELLO_B: - str = "SSLv2/v3 read client hello B"; - break; - -/* DTLS */ - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: - str = "DTLS1 read hello verify request A"; - break; - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: - str = "DTLS1 read hello verify request B"; - break; - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: - str = "DTLS1 write hello verify request A"; - break; - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: - str = "DTLS1 write hello verify request B"; - break; - - default: - str = "unknown state"; - break; - } - return (str); -} - -const char *SSL_rstate_string_long(const SSL *s) -{ - const char *str; - - switch (s->rstate) { - case SSL_ST_READ_HEADER: - str = "read header"; - break; - case SSL_ST_READ_BODY: - str = "read body"; - break; - case SSL_ST_READ_DONE: - str = "read done"; - break; - default: - str = "unknown"; - break; - } - return (str); -} - -const char *SSL_state_string(const SSL *s) -{ - const char *str; - - switch (s->state) { - case SSL_ST_BEFORE: - str = "PINIT "; - break; - case SSL_ST_ACCEPT: - str = "AINIT "; - break; - case SSL_ST_CONNECT: - str = "CINIT "; - break; - case SSL_ST_OK: - str = "SSLOK "; - break; - case SSL_ST_ERR: - str = "SSLERR"; - break; -#ifndef OPENSSL_NO_SSL2 - case SSL2_ST_CLIENT_START_ENCRYPTION: - str = "2CSENC"; - break; - case SSL2_ST_SERVER_START_ENCRYPTION: - str = "2SSENC"; - break; - case SSL2_ST_SEND_CLIENT_HELLO_A: - str = "2SCH_A"; - break; - case SSL2_ST_SEND_CLIENT_HELLO_B: - str = "2SCH_B"; - break; - case SSL2_ST_GET_SERVER_HELLO_A: - str = "2GSH_A"; - break; - case SSL2_ST_GET_SERVER_HELLO_B: - str = "2GSH_B"; - break; - case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: - str = "2SCMKA"; - break; - case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: - str = "2SCMKB"; - break; - case SSL2_ST_SEND_CLIENT_FINISHED_A: - str = "2SCF_A"; - break; - case SSL2_ST_SEND_CLIENT_FINISHED_B: - str = "2SCF_B"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: - str = "2SCC_A"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: - str = "2SCC_B"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: - str = "2SCC_C"; - break; - case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: - str = "2SCC_D"; - break; - case SSL2_ST_GET_SERVER_VERIFY_A: - str = "2GSV_A"; - break; - case SSL2_ST_GET_SERVER_VERIFY_B: - str = "2GSV_B"; - break; - case SSL2_ST_GET_SERVER_FINISHED_A: - str = "2GSF_A"; - break; - case SSL2_ST_GET_SERVER_FINISHED_B: - str = "2GSF_B"; - break; - case SSL2_ST_GET_CLIENT_HELLO_A: - str = "2GCH_A"; - break; - case SSL2_ST_GET_CLIENT_HELLO_B: - str = "2GCH_B"; - break; - case SSL2_ST_GET_CLIENT_HELLO_C: - str = "2GCH_C"; - break; - case SSL2_ST_SEND_SERVER_HELLO_A: - str = "2SSH_A"; - break; - case SSL2_ST_SEND_SERVER_HELLO_B: - str = "2SSH_B"; - break; - case SSL2_ST_GET_CLIENT_MASTER_KEY_A: - str = "2GCMKA"; - break; - case SSL2_ST_GET_CLIENT_MASTER_KEY_B: - str = "2GCMKA"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_A: - str = "2SSV_A"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_B: - str = "2SSV_B"; - break; - case SSL2_ST_SEND_SERVER_VERIFY_C: - str = "2SSV_C"; - break; - case SSL2_ST_GET_CLIENT_FINISHED_A: - str = "2GCF_A"; - break; - case SSL2_ST_GET_CLIENT_FINISHED_B: - str = "2GCF_B"; - break; - case SSL2_ST_SEND_SERVER_FINISHED_A: - str = "2SSF_A"; - break; - case SSL2_ST_SEND_SERVER_FINISHED_B: - str = "2SSF_B"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: - str = "2SRC_A"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: - str = "2SRC_B"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: - str = "2SRC_C"; - break; - case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: - str = "2SRC_D"; - break; - case SSL2_ST_X509_GET_SERVER_CERTIFICATE: - str = "2X9GSC"; - break; - case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: - str = "2X9GCC"; - break; -#endif - -#ifndef OPENSSL_NO_SSL3 -/* SSLv3 additions */ - case SSL3_ST_SW_FLUSH: - case SSL3_ST_CW_FLUSH: - str = "3FLUSH"; - break; - case SSL3_ST_CW_CLNT_HELLO_A: - str = "3WCH_A"; - break; - case SSL3_ST_CW_CLNT_HELLO_B: - str = "3WCH_B"; - break; - case SSL3_ST_CR_SRVR_HELLO_A: - str = "3RSH_A"; - break; - case SSL3_ST_CR_SRVR_HELLO_B: - str = "3RSH_B"; - break; - case SSL3_ST_CR_CERT_A: - str = "3RSC_A"; - break; - case SSL3_ST_CR_CERT_B: - str = "3RSC_B"; - break; - case SSL3_ST_CR_KEY_EXCH_A: - str = "3RSKEA"; - break; - case SSL3_ST_CR_KEY_EXCH_B: - str = "3RSKEB"; - break; - case SSL3_ST_CR_CERT_REQ_A: - str = "3RCR_A"; - break; - case SSL3_ST_CR_CERT_REQ_B: - str = "3RCR_B"; - break; - case SSL3_ST_CR_SRVR_DONE_A: - str = "3RSD_A"; - break; - case SSL3_ST_CR_SRVR_DONE_B: - str = "3RSD_B"; - break; - case SSL3_ST_CW_CERT_A: - str = "3WCC_A"; - break; - case SSL3_ST_CW_CERT_B: - str = "3WCC_B"; - break; - case SSL3_ST_CW_CERT_C: - str = "3WCC_C"; - break; - case SSL3_ST_CW_CERT_D: - str = "3WCC_D"; - break; - case SSL3_ST_CW_KEY_EXCH_A: - str = "3WCKEA"; - break; - case SSL3_ST_CW_KEY_EXCH_B: - str = "3WCKEB"; - break; - case SSL3_ST_CW_CERT_VRFY_A: - str = "3WCV_A"; - break; - case SSL3_ST_CW_CERT_VRFY_B: - str = "3WCV_B"; - break; - - case SSL3_ST_SW_CHANGE_A: - case SSL3_ST_CW_CHANGE_A: - str = "3WCCSA"; - break; - case SSL3_ST_SW_CHANGE_B: - case SSL3_ST_CW_CHANGE_B: - str = "3WCCSB"; - break; - case SSL3_ST_SW_FINISHED_A: - case SSL3_ST_CW_FINISHED_A: - str = "3WFINA"; - break; - case SSL3_ST_SW_FINISHED_B: - case SSL3_ST_CW_FINISHED_B: - str = "3WFINB"; - break; - case SSL3_ST_SR_CHANGE_A: - case SSL3_ST_CR_CHANGE_A: - str = "3RCCSA"; - break; - case SSL3_ST_SR_CHANGE_B: - case SSL3_ST_CR_CHANGE_B: - str = "3RCCSB"; - break; - case SSL3_ST_SR_FINISHED_A: - case SSL3_ST_CR_FINISHED_A: - str = "3RFINA"; - break; - case SSL3_ST_SR_FINISHED_B: - case SSL3_ST_CR_FINISHED_B: - str = "3RFINB"; - break; - - case SSL3_ST_SW_HELLO_REQ_A: - str = "3WHR_A"; - break; - case SSL3_ST_SW_HELLO_REQ_B: - str = "3WHR_B"; - break; - case SSL3_ST_SW_HELLO_REQ_C: - str = "3WHR_C"; - break; - case SSL3_ST_SR_CLNT_HELLO_A: - str = "3RCH_A"; - break; - case SSL3_ST_SR_CLNT_HELLO_B: - str = "3RCH_B"; - break; - case SSL3_ST_SR_CLNT_HELLO_C: - str = "3RCH_C"; - break; - case SSL3_ST_SW_SRVR_HELLO_A: - str = "3WSH_A"; - break; - case SSL3_ST_SW_SRVR_HELLO_B: - str = "3WSH_B"; - break; - case SSL3_ST_SW_CERT_A: - str = "3WSC_A"; - break; - case SSL3_ST_SW_CERT_B: - str = "3WSC_B"; - break; - case SSL3_ST_SW_KEY_EXCH_A: - str = "3WSKEA"; - break; - case SSL3_ST_SW_KEY_EXCH_B: - str = "3WSKEB"; - break; - case SSL3_ST_SW_CERT_REQ_A: - str = "3WCR_A"; - break; - case SSL3_ST_SW_CERT_REQ_B: - str = "3WCR_B"; - break; - case SSL3_ST_SW_SRVR_DONE_A: - str = "3WSD_A"; - break; - case SSL3_ST_SW_SRVR_DONE_B: - str = "3WSD_B"; - break; - case SSL3_ST_SR_CERT_A: - str = "3RCC_A"; - break; - case SSL3_ST_SR_CERT_B: - str = "3RCC_B"; - break; - case SSL3_ST_SR_KEY_EXCH_A: - str = "3RCKEA"; - break; - case SSL3_ST_SR_KEY_EXCH_B: - str = "3RCKEB"; - break; - case SSL3_ST_SR_CERT_VRFY_A: - str = "3RCV_A"; - break; - case SSL3_ST_SR_CERT_VRFY_B: - str = "3RCV_B"; - break; -#endif - -/* SSLv2/v3 compatibility states */ -/* client */ - case SSL23_ST_CW_CLNT_HELLO_A: - str = "23WCHA"; - break; - case SSL23_ST_CW_CLNT_HELLO_B: - str = "23WCHB"; - break; - case SSL23_ST_CR_SRVR_HELLO_A: - str = "23RSHA"; - break; - case SSL23_ST_CR_SRVR_HELLO_B: - str = "23RSHA"; - break; -/* server */ - case SSL23_ST_SR_CLNT_HELLO_A: - str = "23RCHA"; - break; - case SSL23_ST_SR_CLNT_HELLO_B: - str = "23RCHB"; - break; - -/* DTLS */ - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: - str = "DRCHVA"; - break; - case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: - str = "DRCHVB"; - break; - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: - str = "DWCHVA"; - break; - case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: - str = "DWCHVB"; - break; - - default: - str = "UNKWN "; - break; - } - return (str); -} - -const char *SSL_alert_type_string_long(int value) -{ - value >>= 8; - if (value == SSL3_AL_WARNING) - return ("warning"); - else if (value == SSL3_AL_FATAL) - return ("fatal"); - else - return ("unknown"); -} - -const char *SSL_alert_type_string(int value) -{ - value >>= 8; - if (value == SSL3_AL_WARNING) - return ("W"); - else if (value == SSL3_AL_FATAL) - return ("F"); - else - return ("U"); -} - -const char *SSL_alert_desc_string(int value) -{ - const char *str; - - switch (value & 0xff) { - case SSL3_AD_CLOSE_NOTIFY: - str = "CN"; - break; - case SSL3_AD_UNEXPECTED_MESSAGE: - str = "UM"; - break; - case SSL3_AD_BAD_RECORD_MAC: - str = "BM"; - break; - case SSL3_AD_DECOMPRESSION_FAILURE: - str = "DF"; - break; - case SSL3_AD_HANDSHAKE_FAILURE: - str = "HF"; - break; - case SSL3_AD_NO_CERTIFICATE: - str = "NC"; - break; - case SSL3_AD_BAD_CERTIFICATE: - str = "BC"; - break; - case SSL3_AD_UNSUPPORTED_CERTIFICATE: - str = "UC"; - break; - case SSL3_AD_CERTIFICATE_REVOKED: - str = "CR"; - break; - case SSL3_AD_CERTIFICATE_EXPIRED: - str = "CE"; - break; - case SSL3_AD_CERTIFICATE_UNKNOWN: - str = "CU"; - break; - case SSL3_AD_ILLEGAL_PARAMETER: - str = "IP"; - break; - case TLS1_AD_DECRYPTION_FAILED: - str = "DC"; - break; - case TLS1_AD_RECORD_OVERFLOW: - str = "RO"; - break; - case TLS1_AD_UNKNOWN_CA: - str = "CA"; - break; - case TLS1_AD_ACCESS_DENIED: - str = "AD"; - break; - case TLS1_AD_DECODE_ERROR: - str = "DE"; - break; - case TLS1_AD_DECRYPT_ERROR: - str = "CY"; - break; - case TLS1_AD_EXPORT_RESTRICTION: - str = "ER"; - break; - case TLS1_AD_PROTOCOL_VERSION: - str = "PV"; - break; - case TLS1_AD_INSUFFICIENT_SECURITY: - str = "IS"; - break; - case TLS1_AD_INTERNAL_ERROR: - str = "IE"; - break; - case TLS1_AD_USER_CANCELLED: - str = "US"; - break; - case TLS1_AD_NO_RENEGOTIATION: - str = "NR"; - break; - case TLS1_AD_UNSUPPORTED_EXTENSION: - str = "UE"; - break; - case TLS1_AD_CERTIFICATE_UNOBTAINABLE: - str = "CO"; - break; - case TLS1_AD_UNRECOGNIZED_NAME: - str = "UN"; - break; - case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - str = "BR"; - break; - case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: - str = "BH"; - break; - case TLS1_AD_UNKNOWN_PSK_IDENTITY: - str = "UP"; - break; - default: - str = "UK"; - break; - } - return (str); -} - -const char *SSL_alert_desc_string_long(int value) -{ - const char *str; - - switch (value & 0xff) { - case SSL3_AD_CLOSE_NOTIFY: - str = "close notify"; - break; - case SSL3_AD_UNEXPECTED_MESSAGE: - str = "unexpected_message"; - break; - case SSL3_AD_BAD_RECORD_MAC: - str = "bad record mac"; - break; - case SSL3_AD_DECOMPRESSION_FAILURE: - str = "decompression failure"; - break; - case SSL3_AD_HANDSHAKE_FAILURE: - str = "handshake failure"; - break; - case SSL3_AD_NO_CERTIFICATE: - str = "no certificate"; - break; - case SSL3_AD_BAD_CERTIFICATE: - str = "bad certificate"; - break; - case SSL3_AD_UNSUPPORTED_CERTIFICATE: - str = "unsupported certificate"; - break; - case SSL3_AD_CERTIFICATE_REVOKED: - str = "certificate revoked"; - break; - case SSL3_AD_CERTIFICATE_EXPIRED: - str = "certificate expired"; - break; - case SSL3_AD_CERTIFICATE_UNKNOWN: - str = "certificate unknown"; - break; - case SSL3_AD_ILLEGAL_PARAMETER: - str = "illegal parameter"; - break; - case TLS1_AD_DECRYPTION_FAILED: - str = "decryption failed"; - break; - case TLS1_AD_RECORD_OVERFLOW: - str = "record overflow"; - break; - case TLS1_AD_UNKNOWN_CA: - str = "unknown CA"; - break; - case TLS1_AD_ACCESS_DENIED: - str = "access denied"; - break; - case TLS1_AD_DECODE_ERROR: - str = "decode error"; - break; - case TLS1_AD_DECRYPT_ERROR: - str = "decrypt error"; - break; - case TLS1_AD_EXPORT_RESTRICTION: - str = "export restriction"; - break; - case TLS1_AD_PROTOCOL_VERSION: - str = "protocol version"; - break; - case TLS1_AD_INSUFFICIENT_SECURITY: - str = "insufficient security"; - break; - case TLS1_AD_INTERNAL_ERROR: - str = "internal error"; - break; - case TLS1_AD_USER_CANCELLED: - str = "user canceled"; - break; - case TLS1_AD_NO_RENEGOTIATION: - str = "no renegotiation"; - break; - case TLS1_AD_UNSUPPORTED_EXTENSION: - str = "unsupported extension"; - break; - case TLS1_AD_CERTIFICATE_UNOBTAINABLE: - str = "certificate unobtainable"; - break; - case TLS1_AD_UNRECOGNIZED_NAME: - str = "unrecognized name"; - break; - case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - str = "bad certificate status response"; - break; - case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: - str = "bad certificate hash value"; - break; - case TLS1_AD_UNKNOWN_PSK_IDENTITY: - str = "unknown PSK identity"; - break; - default: - str = "unknown"; - break; - } - return (str); -} - -const char *SSL_rstate_string(const SSL *s) -{ - const char *str; - - switch (s->rstate) { - case SSL_ST_READ_HEADER: - str = "RH"; - break; - case SSL_ST_READ_BODY: - str = "RB"; - break; - case SSL_ST_READ_DONE: - str = "RD"; - break; - default: - str = "unknown"; - break; - } - return (str); -} -/* ssl/ssl_txt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -#include "buffer.h" -// #include "ssl_locl.h" - -#ifndef OPENSSL_NO_FP_API -int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file_internal())) == NULL) { - SSLerr(SSL_F_SSL_SESSION_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = SSL_SESSION_print(b, x); - BIO_free(b); - return (ret); -} -#endif - -int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) -{ - unsigned int i; - const char *s; - - if (x == NULL) - goto err; - if (BIO_puts(bp, "SSL-Session:\n") <= 0) - goto err; - if (x->ssl_version == SSL2_VERSION) - s = "SSLv2"; - else if (x->ssl_version == SSL3_VERSION) - s = "SSLv3"; - else if (x->ssl_version == TLS1_2_VERSION) - s = "TLSv1.2"; - else if (x->ssl_version == TLS1_1_VERSION) - s = "TLSv1.1"; - else if (x->ssl_version == TLS1_VERSION) - s = "TLSv1"; - else if (x->ssl_version == DTLS1_VERSION) - s = "DTLSv1"; - else if (x->ssl_version == DTLS1_2_VERSION) - s = "DTLSv1.2"; - else if (x->ssl_version == DTLS1_BAD_VER) - s = "DTLSv1-bad"; - else - s = "unknown"; - if (BIO_printf(bp, " Protocol : %s\n", s) <= 0) - goto err; - - if (x->cipher == NULL) { - if (((x->cipher_id) & 0xff000000) == 0x02000000) { - if (BIO_printf - (bp, " Cipher : %06lX\n", x->cipher_id & 0xffffff) <= 0) - goto err; - } else { - if (BIO_printf - (bp, " Cipher : %04lX\n", x->cipher_id & 0xffff) <= 0) - goto err; - } - } else { - if (BIO_printf - (bp, " Cipher : %s\n", - ((x->cipher == NULL) ? "unknown" : x->cipher->name)) <= 0) - goto err; - } - if (BIO_puts(bp, " Session-ID: ") <= 0) - goto err; - for (i = 0; i < x->session_id_length; i++) { - if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0) - goto err; - } - if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0) - goto err; - for (i = 0; i < x->sid_ctx_length; i++) { - if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) - goto err; - } - if (BIO_puts(bp, "\n Master-Key: ") <= 0) - goto err; - for (i = 0; i < (unsigned int)x->master_key_length; i++) { - if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0) - goto err; - } - if (BIO_puts(bp, "\n Key-Arg : ") <= 0) - goto err; - if (x->key_arg_length == 0) { - if (BIO_puts(bp, "None") <= 0) - goto err; - } else - for (i = 0; i < x->key_arg_length; i++) { - if (BIO_printf(bp, "%02X", x->key_arg[i]) <= 0) - goto err; - } -#ifndef OPENSSL_NO_KRB5 - if (BIO_puts(bp, "\n Krb5 Principal: ") <= 0) - goto err; - if (x->krb5_client_princ_len == 0) { - if (BIO_puts(bp, "None") <= 0) - goto err; - } else - for (i = 0; i < x->krb5_client_princ_len; i++) { - if (BIO_printf(bp, "%02X", x->krb5_client_princ[i]) <= 0) - goto err; - } -#endif /* OPENSSL_NO_KRB5 */ -#ifndef OPENSSL_NO_PSK - if (BIO_puts(bp, "\n PSK identity: ") <= 0) - goto err; - if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) - goto err; - if (BIO_puts(bp, "\n PSK identity hint: ") <= 0) - goto err; - if (BIO_printf - (bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) - goto err; -#endif -#ifndef OPENSSL_NO_SRP - if (BIO_puts(bp, "\n SRP username: ") <= 0) - goto err; - if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) - goto err; -#endif -#ifndef OPENSSL_NO_TLSEXT - if (x->tlsext_tick_lifetime_hint) { - if (BIO_printf(bp, - "\n TLS session ticket lifetime hint: %ld (seconds)", - x->tlsext_tick_lifetime_hint) <= 0) - goto err; - } - if (x->tlsext_tick) { - if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0) - goto err; - if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) - <= 0) - goto err; - } -#endif - -#ifndef OPENSSL_NO_COMP - if (x->compress_meth != 0) { - SSL_COMP *comp = NULL; - - ssl_cipher_get_evp(x, NULL, NULL, NULL, NULL, &comp); - if (comp == NULL) { - if (BIO_printf(bp, "\n Compression: %d", x->compress_meth) <= - 0) - goto err; - } else { - if (BIO_printf - (bp, "\n Compression: %d (%s)", comp->id, - comp->method->name) <= 0) - goto err; - } - } -#endif - if (x->time != 0L) { - if (BIO_printf(bp, "\n Start Time: %ld", x->time) <= 0) - goto err; - } - if (x->timeout != 0L) { - if (BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0) - goto err; - } - if (BIO_puts(bp, "\n") <= 0) - goto err; - - if (BIO_puts(bp, " Verify return code: ") <= 0) - goto err; - if (BIO_printf(bp, "%ld (%s)\n", x->verify_result, - X509_verify_cert_error_string(x->verify_result)) <= 0) - goto err; - - return (1); - err: - return (0); -} -/* ssl_utst.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2014 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "ssl_locl.h" - -#ifndef OPENSSL_NO_UNIT_TEST - -static const struct openssl_ssl_test_functions ssl_test_functions = { - ssl_init_wbio_buffer, - ssl3_setup_buffers, - tls1_process_heartbeat, - dtls1_process_heartbeat -}; - -const struct openssl_ssl_test_functions *SSL_test_functions(void) -{ - return &ssl_test_functions; -} - -#endif diff --git a/Sources/COpenSSL/ssl_locl.h b/Sources/COpenSSL/ssl_locl.h deleted file mode 100644 index 0365e267..00000000 --- a/Sources/COpenSSL/ssl_locl.h +++ /dev/null @@ -1,1499 +0,0 @@ -/* ssl/ssl_locl.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECC cipher suite support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#ifndef HEADER_SSL_LOCL_H -# define HEADER_SSL_LOCL_H -# include -# include -# include -# include - -# include "e_os.h" - -# include "buffer.h" -# ifndef OPENSSL_NO_COMP -# include "comp.h" -# endif -# include "bio.h" -# include "stack.h" -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif -# ifndef OPENSSL_NO_DSA -# include "dsa.h" -# endif -# include "err.h" -# include "ssl.h" -# include "symhacks.h" - -# ifdef OPENSSL_BUILD_SHLIBSSL -# undef OPENSSL_EXTERN -# define OPENSSL_EXTERN OPENSSL_EXPORT -# endif - -# undef PKCS1_CHECK - -# define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ - l|=(((unsigned long)(*((c)++)))<< 8), \ - l|=(((unsigned long)(*((c)++)))<<16), \ - l|=(((unsigned long)(*((c)++)))<<24)) - -/* NOTE - c is not incremented as per c2l */ -# define c2ln(c,l1,l2,n) { \ - c+=n; \ - l1=l2=0; \ - switch (n) { \ - case 8: l2 =((unsigned long)(*(--(c))))<<24; \ - case 7: l2|=((unsigned long)(*(--(c))))<<16; \ - case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ - case 5: l2|=((unsigned long)(*(--(c)))); \ - case 4: l1 =((unsigned long)(*(--(c))))<<24; \ - case 3: l1|=((unsigned long)(*(--(c))))<<16; \ - case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ - case 1: l1|=((unsigned long)(*(--(c)))); \ - } \ - } - -# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff)) - -# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \ - l|=((unsigned long)(*((c)++)))<<16, \ - l|=((unsigned long)(*((c)++)))<< 8, \ - l|=((unsigned long)(*((c)++)))) - -# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ - *((c)++)=(unsigned char)(((l)>>32)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ - *((c)++)=(unsigned char)(((l)>>48)&0xff), \ - *((c)++)=(unsigned char)(((l)>>40)&0xff), \ - *((c)++)=(unsigned char)(((l)>>32)&0xff), \ - *((c)++)=(unsigned char)(((l)>>24)&0xff), \ - *((c)++)=(unsigned char)(((l)>>16)&0xff), \ - *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ - *((c)++)=(unsigned char)(((l) )&0xff)) - -# define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \ - l|=((BN_ULLONG)(*((c)++)))<<32, \ - l|=((BN_ULLONG)(*((c)++)))<<24, \ - l|=((BN_ULLONG)(*((c)++)))<<16, \ - l|=((BN_ULLONG)(*((c)++)))<< 8, \ - l|=((BN_ULLONG)(*((c)++)))) - -/* NOTE - c is not incremented as per l2c */ -# define l2cn(l1,l2,c,n) { \ - c+=n; \ - switch (n) { \ - case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ - case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ - case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ - case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ - case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ - case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ - case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ - case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ - } \ - } - -# define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \ - (((unsigned int)(c[1])) )),c+=2) -# define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \ - c[1]=(unsigned char)(((s) )&0xff)),c+=2) - -# define n2l3(c,l) ((l =(((unsigned long)(c[0]))<<16)| \ - (((unsigned long)(c[1]))<< 8)| \ - (((unsigned long)(c[2])) )),c+=3) - -# define l2n3(l,c) ((c[0]=(unsigned char)(((l)>>16)&0xff), \ - c[1]=(unsigned char)(((l)>> 8)&0xff), \ - c[2]=(unsigned char)(((l) )&0xff)),c+=3) - -# define SSL_MAX_2_BYTE_LEN (0xffff) - -/* LOCAL STUFF */ - -# define SSL_DECRYPT 0 -# define SSL_ENCRYPT 1 - -# define TWO_BYTE_BIT 0x80 -# define SEC_ESC_BIT 0x40 -# define TWO_BYTE_MASK 0x7fff -# define THREE_BYTE_MASK 0x3fff - -# define INC32(a) ((a)=((a)+1)&0xffffffffL) -# define DEC32(a) ((a)=((a)-1)&0xffffffffL) -# define MAX_MAC_SIZE 20 /* up from 16 for SSLv3 */ - -/* - * Define the Bitmasks for SSL_CIPHER.algorithms. - * This bits are used packed as dense as possible. If new methods/ciphers - * etc will be added, the bits a likely to change, so this information - * is for internal library use only, even though SSL_CIPHER.algorithms - * can be publicly accessed. - * Use the according functions for cipher management instead. - * - * The bit mask handling in the selection and sorting scheme in - * ssl_create_cipher_list() has only limited capabilities, reflecting - * that the different entities within are mutually exclusive: - * ONLY ONE BIT PER MASK CAN BE SET AT A TIME. - */ - -/* Bits for algorithm_mkey (key exchange algorithm) */ -/* RSA key exchange */ -# define SSL_kRSA 0x00000001L -/* DH cert, RSA CA cert */ -# define SSL_kDHr 0x00000002L -/* DH cert, DSA CA cert */ -# define SSL_kDHd 0x00000004L -/* tmp DH key no DH cert */ -# define SSL_kEDH 0x00000008L -/* forward-compatible synonym */ -# define SSL_kDHE SSL_kEDH -/* Kerberos5 key exchange */ -# define SSL_kKRB5 0x00000010L -/* ECDH cert, RSA CA cert */ -# define SSL_kECDHr 0x00000020L -/* ECDH cert, ECDSA CA cert */ -# define SSL_kECDHe 0x00000040L -/* ephemeral ECDH */ -# define SSL_kEECDH 0x00000080L -/* forward-compatible synonym */ -# define SSL_kECDHE SSL_kEECDH -/* PSK */ -# define SSL_kPSK 0x00000100L -/* GOST key exchange */ -# define SSL_kGOST 0x00000200L -/* SRP */ -# define SSL_kSRP 0x00000400L - -/* Bits for algorithm_auth (server authentication) */ -/* RSA auth */ -# define SSL_aRSA 0x00000001L -/* DSS auth */ -# define SSL_aDSS 0x00000002L -/* no auth (i.e. use ADH or AECDH) */ -# define SSL_aNULL 0x00000004L -/* Fixed DH auth (kDHd or kDHr) */ -# define SSL_aDH 0x00000008L -/* Fixed ECDH auth (kECDHe or kECDHr) */ -# define SSL_aECDH 0x00000010L -/* KRB5 auth */ -# define SSL_aKRB5 0x00000020L -/* ECDSA auth*/ -# define SSL_aECDSA 0x00000040L -/* PSK auth */ -# define SSL_aPSK 0x00000080L -/* GOST R 34.10-94 signature auth */ -# define SSL_aGOST94 0x00000100L -/* GOST R 34.10-2001 signature auth */ -# define SSL_aGOST01 0x00000200L -/* SRP auth */ -# define SSL_aSRP 0x00000400L - -/* Bits for algorithm_enc (symmetric encryption) */ -# define SSL_DES 0x00000001L -# define SSL_3DES 0x00000002L -# define SSL_RC4 0x00000004L -# define SSL_RC2 0x00000008L -# define SSL_IDEA 0x00000010L -# define SSL_eNULL 0x00000020L -# define SSL_AES128 0x00000040L -# define SSL_AES256 0x00000080L -# define SSL_CAMELLIA128 0x00000100L -# define SSL_CAMELLIA256 0x00000200L -# define SSL_eGOST2814789CNT 0x00000400L -# define SSL_SEED 0x00000800L -# define SSL_AES128GCM 0x00001000L -# define SSL_AES256GCM 0x00002000L - -# define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM) -# define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) - -/* Bits for algorithm_mac (symmetric authentication) */ - -# define SSL_MD5 0x00000001L -# define SSL_SHA1 0x00000002L -# define SSL_GOST94 0x00000004L -# define SSL_GOST89MAC 0x00000008L -# define SSL_SHA256 0x00000010L -# define SSL_SHA384 0x00000020L -/* Not a real MAC, just an indication it is part of cipher */ -# define SSL_AEAD 0x00000040L - -/* Bits for algorithm_ssl (protocol version) */ -# define SSL_SSLV2 0x00000001UL -# define SSL_SSLV3 0x00000002UL -# define SSL_TLSV1 SSL_SSLV3/* for now */ -# define SSL_TLSV1_2 0x00000004UL - -/* Bits for algorithm2 (handshake digests and other extra flags) */ - -# define SSL_HANDSHAKE_MAC_MD5 0x10 -# define SSL_HANDSHAKE_MAC_SHA 0x20 -# define SSL_HANDSHAKE_MAC_GOST94 0x40 -# define SSL_HANDSHAKE_MAC_SHA256 0x80 -# define SSL_HANDSHAKE_MAC_SHA384 0x100 -# define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) - -/* - * When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX make - * sure to update this constant too - */ -# define SSL_MAX_DIGEST 6 - -# define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT) - -# define TLS1_PRF_DGST_SHIFT 10 -# define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) -# define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) - -/* - * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also - * goes into algorithm2) - */ -# define TLS1_STREAM_MAC 0x04 - -/* - * Export and cipher strength information. For each cipher we have to decide - * whether it is exportable or not. This information is likely to change - * over time, since the export control rules are no static technical issue. - * - * Independent of the export flag the cipher strength is sorted into classes. - * SSL_EXP40 was denoting the 40bit US export limit of past times, which now - * is at 56bit (SSL_EXP56). If the exportable cipher class is going to change - * again (eg. to 64bit) the use of "SSL_EXP*" becomes blurred even more, - * since SSL_EXP64 could be similar to SSL_LOW. - * For this reason SSL_MICRO and SSL_MINI macros are included to widen the - * namespace of SSL_LOW-SSL_HIGH to lower values. As development of speed - * and ciphers goes, another extension to SSL_SUPER and/or SSL_ULTRA would - * be possible. - */ -# define SSL_EXP_MASK 0x00000003L -# define SSL_STRONG_MASK 0x000001fcL - -# define SSL_NOT_EXP 0x00000001L -# define SSL_EXPORT 0x00000002L - -# define SSL_STRONG_NONE 0x00000004L -# define SSL_EXP40 0x00000008L -# define SSL_MICRO (SSL_EXP40) -# define SSL_EXP56 0x00000010L -# define SSL_MINI (SSL_EXP56) -# define SSL_LOW 0x00000020L -# define SSL_MEDIUM 0x00000040L -# define SSL_HIGH 0x00000080L -# define SSL_FIPS 0x00000100L -# define SSL_NOT_DEFAULT 0x00000200L - -/* we have used 000003ff - 22 bits left to go */ - -/*- - * Macros to check the export status and cipher strength for export ciphers. - * Even though the macros for EXPORT and EXPORT40/56 have similar names, - * their meaning is different: - * *_EXPORT macros check the 'exportable' status. - * *_EXPORT40/56 macros are used to check whether a certain cipher strength - * is given. - * Since the SSL_IS_EXPORT* and SSL_EXPORT* macros depend on the correct - * algorithm structure element to be passed (algorithms, algo_strength) and no - * typechecking can be done as they are all of type unsigned long, their - * direct usage is discouraged. - * Use the SSL_C_* macros instead. - */ -# define SSL_IS_EXPORT(a) ((a)&SSL_EXPORT) -# define SSL_IS_EXPORT56(a) ((a)&SSL_EXP56) -# define SSL_IS_EXPORT40(a) ((a)&SSL_EXP40) -# define SSL_C_IS_EXPORT(c) SSL_IS_EXPORT((c)->algo_strength) -# define SSL_C_IS_EXPORT56(c) SSL_IS_EXPORT56((c)->algo_strength) -# define SSL_C_IS_EXPORT40(c) SSL_IS_EXPORT40((c)->algo_strength) - -# define SSL_EXPORT_KEYLENGTH(a,s) (SSL_IS_EXPORT40(s) ? 5 : \ - (a) == SSL_DES ? 8 : 7) -# define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024) -# define SSL_C_EXPORT_KEYLENGTH(c) SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \ - (c)->algo_strength) -# define SSL_C_EXPORT_PKEYLENGTH(c) SSL_EXPORT_PKEYLENGTH((c)->algo_strength) - -/* Check if an SSL structure is using DTLS */ -# define SSL_IS_DTLS(s) (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) -/* See if we need explicit IV */ -# define SSL_USE_EXPLICIT_IV(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_EXPLICIT_IV) -/* - * See if we use signature algorithms extension and signature algorithm - * before signatures. - */ -# define SSL_USE_SIGALGS(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) -/* - * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may - * apply to others in future. - */ -# define SSL_USE_TLS1_2_CIPHERS(s) \ - (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) -/* - * Determine if a client can use TLS 1.2 ciphersuites: can't rely on method - * flags because it may not be set to correct version yet. - */ -# define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \ - ((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \ - (!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION)) -/* - * Determine if a client should send signature algorithms extension: - * as with TLS1.2 cipher we can't rely on method flags. - */ -# define SSL_CLIENT_USE_SIGALGS(s) \ - SSL_CLIENT_USE_TLS1_2_CIPHERS(s) - -/* Mostly for SSLv3 */ -# define SSL_PKEY_RSA_ENC 0 -# define SSL_PKEY_RSA_SIGN 1 -# define SSL_PKEY_DSA_SIGN 2 -# define SSL_PKEY_DH_RSA 3 -# define SSL_PKEY_DH_DSA 4 -# define SSL_PKEY_ECC 5 -# define SSL_PKEY_GOST94 6 -# define SSL_PKEY_GOST01 7 -# define SSL_PKEY_NUM 8 - -/*- - * SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) | - * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN) - * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN) - * SSL_kEDH <- RSA_ENC | RSA_SIGN | DSA_SIGN - * SSL_aRSA <- RSA_ENC | RSA_SIGN - * SSL_aDSS <- DSA_SIGN - */ - -/*- -#define CERT_INVALID 0 -#define CERT_PUBLIC_KEY 1 -#define CERT_PRIVATE_KEY 2 -*/ - -# ifndef OPENSSL_NO_EC -/* - * From ECC-TLS draft, used in encoding the curve type in ECParameters - */ -# define EXPLICIT_PRIME_CURVE_TYPE 1 -# define EXPLICIT_CHAR2_CURVE_TYPE 2 -# define NAMED_CURVE_TYPE 3 -# endif /* OPENSSL_NO_EC */ - -typedef struct cert_pkey_st { - X509 *x509; - EVP_PKEY *privatekey; - /* Digest to use when signing */ - const EVP_MD *digest; - /* Chain for this certificate */ - STACK_OF(X509) *chain; -# ifndef OPENSSL_NO_TLSEXT - /*- - * serverinfo data for this certificate. The data is in TLS Extension - * wire format, specifically it's a series of records like: - * uint16_t extension_type; // (RFC 5246, 7.4.1.4, Extension) - * uint16_t length; - * uint8_t data[length]; - */ - unsigned char *serverinfo; - size_t serverinfo_length; -# endif - /* - * Set if CERT_PKEY can be used with current SSL session: e.g. - * appropriate curve, signature algorithms etc. If zero it can't be used - * at all. - */ - int valid_flags; -} CERT_PKEY; -/* Retrieve Suite B flags */ -# define tls1_suiteb(s) (s->cert->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS) -/* Uses to check strict mode: suite B modes are always strict */ -# define SSL_CERT_FLAGS_CHECK_TLS_STRICT \ - (SSL_CERT_FLAG_SUITEB_128_LOS|SSL_CERT_FLAG_TLS_STRICT) - -typedef struct { - unsigned short ext_type; - /* - * Per-connection flags relating to this extension type: not used if - * part of an SSL_CTX structure. - */ - unsigned short ext_flags; - custom_ext_add_cb add_cb; - custom_ext_free_cb free_cb; - void *add_arg; - custom_ext_parse_cb parse_cb; - void *parse_arg; -} custom_ext_method; - -/* ext_flags values */ - -/* - * Indicates an extension has been received. Used to check for unsolicited or - * duplicate extensions. - */ -# define SSL_EXT_FLAG_RECEIVED 0x1 -/* - * Indicates an extension has been sent: used to enable sending of - * corresponding ServerHello extension. - */ -# define SSL_EXT_FLAG_SENT 0x2 - -# define MAX_WARN_ALERT_COUNT 5 - -typedef struct { - custom_ext_method *meths; - size_t meths_count; -} custom_ext_methods; - -typedef struct cert_st { - /* Current active set */ - /* - * ALWAYS points to an element of the pkeys array - * Probably it would make more sense to store - * an index, not a pointer. - */ - CERT_PKEY *key; - /* - * For servers the following masks are for the key and auth algorithms - * that are supported by the certs below. For clients they are masks of - * *disabled* algorithms based on the current session. - */ - int valid; - unsigned long mask_k; - unsigned long mask_a; - unsigned long export_mask_k; - unsigned long export_mask_a; - /* Client only */ - unsigned long mask_ssl; -# ifndef OPENSSL_NO_RSA - RSA *rsa_tmp; - RSA *(*rsa_tmp_cb) (SSL *ssl, int is_export, int keysize); -# endif -# ifndef OPENSSL_NO_DH - DH *dh_tmp; - DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize); -# endif -# ifndef OPENSSL_NO_ECDH - EC_KEY *ecdh_tmp; - /* Callback for generating ephemeral ECDH keys */ - EC_KEY *(*ecdh_tmp_cb) (SSL *ssl, int is_export, int keysize); - /* Select ECDH parameters automatically */ - int ecdh_tmp_auto; -# endif - /* Flags related to certificates */ - unsigned int cert_flags; - CERT_PKEY pkeys[SSL_PKEY_NUM]; - /* - * Certificate types (received or sent) in certificate request message. - * On receive this is only set if number of certificate types exceeds - * SSL3_CT_NUMBER. - */ - unsigned char *ctypes; - size_t ctype_num; - /* - * signature algorithms peer reports: e.g. supported signature algorithms - * extension for server or as part of a certificate request for client. - */ - unsigned char *peer_sigalgs; - /* Size of above array */ - size_t peer_sigalgslen; - /* - * suppported signature algorithms. When set on a client this is sent in - * the client hello as the supported signature algorithms extension. For - * servers it represents the signature algorithms we are willing to use. - */ - unsigned char *conf_sigalgs; - /* Size of above array */ - size_t conf_sigalgslen; - /* - * Client authentication signature algorithms, if not set then uses - * conf_sigalgs. On servers these will be the signature algorithms sent - * to the client in a cerificate request for TLS 1.2. On a client this - * represents the signature algortithms we are willing to use for client - * authentication. - */ - unsigned char *client_sigalgs; - /* Size of above array */ - size_t client_sigalgslen; - /* - * Signature algorithms shared by client and server: cached because these - * are used most often. - */ - TLS_SIGALGS *shared_sigalgs; - size_t shared_sigalgslen; - /* - * Certificate setup callback: if set is called whenever a certificate - * may be required (client or server). the callback can then examine any - * appropriate parameters and setup any certificates required. This - * allows advanced applications to select certificates on the fly: for - * example based on supported signature algorithms or curves. - */ - int (*cert_cb) (SSL *ssl, void *arg); - void *cert_cb_arg; - /* - * Optional X509_STORE for chain building or certificate validation If - * NULL the parent SSL_CTX store is used instead. - */ - X509_STORE *chain_store; - X509_STORE *verify_store; - /* Raw values of the cipher list from a client */ - unsigned char *ciphers_raw; - size_t ciphers_rawlen; - /* Custom extension methods for server and client */ - custom_ext_methods cli_ext; - custom_ext_methods srv_ext; - int references; /* >1 only if SSL_copy_session_id is used */ - /* non-optimal, but here due to compatibility */ - unsigned char *alpn_proposed; /* server */ - unsigned int alpn_proposed_len; - int alpn_sent; /* client */ - /* Count of the number of consecutive warning alerts received */ - unsigned int alert_count; -} CERT; - -typedef struct sess_cert_st { - STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */ - /* The 'peer_...' members are used only by clients. */ - int peer_cert_type; - CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never - * NULL!) */ - CERT_PKEY peer_pkeys[SSL_PKEY_NUM]; - /* - * Obviously we don't have the private keys of these, so maybe we - * shouldn't even use the CERT_PKEY type here. - */ -# ifndef OPENSSL_NO_RSA - RSA *peer_rsa_tmp; /* not used for SSL 2 */ -# endif -# ifndef OPENSSL_NO_DH - DH *peer_dh_tmp; /* not used for SSL 2 */ -# endif -# ifndef OPENSSL_NO_ECDH - EC_KEY *peer_ecdh_tmp; -# endif - int references; /* actually always 1 at the moment */ -} SESS_CERT; -/* Structure containing decoded values of signature algorithms extension */ -struct tls_sigalgs_st { - /* NID of hash algorithm */ - int hash_nid; - /* NID of signature algorithm */ - int sign_nid; - /* Combined hash and signature NID */ - int signandhash_nid; - /* Raw values used in extension */ - unsigned char rsign; - unsigned char rhash; -}; - -/* - * #define MAC_DEBUG - */ - -/* - * #define ERR_DEBUG - */ -/* - * #define ABORT_DEBUG - */ -/* - * #define PKT_DEBUG 1 - */ -/* - * #define DES_DEBUG - */ -/* - * #define DES_OFB_DEBUG - */ -/* - * #define SSL_DEBUG - */ -/* - * #define RSA_DEBUG - */ -/* - * #define IDEA_DEBUG - */ - -# define FP_ICC (int (*)(const void *,const void *)) -# define ssl_put_cipher_by_char(ssl,ciph,ptr) \ - ((ssl)->method->put_cipher_by_char((ciph),(ptr))) - -/* - * This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit - * of a mess of functions, but hell, think of it as an opaque structure :-) - */ -typedef struct ssl3_enc_method { - int (*enc) (SSL *, int); - int (*mac) (SSL *, unsigned char *, int); - int (*setup_key_block) (SSL *); - int (*generate_master_secret) (SSL *, unsigned char *, unsigned char *, - int); - int (*change_cipher_state) (SSL *, int); - int (*final_finish_mac) (SSL *, const char *, int, unsigned char *); - int finish_mac_length; - int (*cert_verify_mac) (SSL *, int, unsigned char *); - const char *client_finished_label; - int client_finished_label_len; - const char *server_finished_label; - int server_finished_label_len; - int (*alert_value) (int); - int (*export_keying_material) (SSL *, unsigned char *, size_t, - const char *, size_t, - const unsigned char *, size_t, - int use_context); - /* Various flags indicating protocol version requirements */ - unsigned int enc_flags; - /* Handshake header length */ - unsigned int hhlen; - /* Set the handshake header */ - void (*set_handshake_header) (SSL *s, int type, unsigned long len); - /* Write out handshake message */ - int (*do_write) (SSL *s); -} SSL3_ENC_METHOD; - -# define SSL_HM_HEADER_LENGTH(s) s->method->ssl3_enc->hhlen -# define ssl_handshake_start(s) \ - (((unsigned char *)s->init_buf->data) + s->method->ssl3_enc->hhlen) -# define ssl_set_handshake_header(s, htype, len) \ - s->method->ssl3_enc->set_handshake_header(s, htype, len) -# define ssl_do_write(s) s->method->ssl3_enc->do_write(s) - -/* Values for enc_flags */ - -/* Uses explicit IV for CBC mode */ -# define SSL_ENC_FLAG_EXPLICIT_IV 0x1 -/* Uses signature algorithms extension */ -# define SSL_ENC_FLAG_SIGALGS 0x2 -/* Uses SHA256 default PRF */ -# define SSL_ENC_FLAG_SHA256_PRF 0x4 -/* Is DTLS */ -# define SSL_ENC_FLAG_DTLS 0x8 -/* - * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may - * apply to others in future. - */ -# define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x10 - -# ifndef OPENSSL_NO_COMP -/* Used for holding the relevant compression methods loaded into SSL_CTX */ -typedef struct ssl3_comp_st { - int comp_id; /* The identifier byte for this compression - * type */ - char *name; /* Text name used for the compression type */ - COMP_METHOD *method; /* The method :-) */ -} SSL3_COMP; -# endif - -# ifndef OPENSSL_NO_BUF_FREELISTS -typedef struct ssl3_buf_freelist_st { - size_t chunklen; - unsigned int len; - struct ssl3_buf_freelist_entry_st *head; -} SSL3_BUF_FREELIST; - -typedef struct ssl3_buf_freelist_entry_st { - struct ssl3_buf_freelist_entry_st *next; -} SSL3_BUF_FREELIST_ENTRY; -# endif - -extern SSL3_ENC_METHOD ssl3_undef_enc_method; -OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[]; -OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[]; - -SSL_METHOD *ssl_bad_method(int ver); - -extern SSL3_ENC_METHOD TLSv1_enc_data; -extern SSL3_ENC_METHOD TLSv1_1_enc_data; -extern SSL3_ENC_METHOD TLSv1_2_enc_data; -extern SSL3_ENC_METHOD SSLv3_enc_data; -extern SSL3_ENC_METHOD DTLSv1_enc_data; -extern SSL3_ENC_METHOD DTLSv1_2_enc_data; - -# define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ - s_get_meth, enc_data) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - version, \ - tls1_new, \ - tls1_clear, \ - tls1_free, \ - s_accept, \ - s_connect, \ - ssl3_read, \ - ssl3_peek, \ - ssl3_write, \ - ssl3_shutdown, \ - ssl3_renegotiate, \ - ssl3_renegotiate_check, \ - ssl3_get_message, \ - ssl3_read_bytes, \ - ssl3_write_bytes, \ - ssl3_dispatch_alert, \ - ssl3_ctrl, \ - ssl3_ctx_ctrl, \ - ssl3_get_cipher_by_char, \ - ssl3_put_cipher_by_char, \ - ssl3_pending, \ - ssl3_num_ciphers, \ - ssl3_get_cipher, \ - s_get_meth, \ - tls1_default_timeout, \ - &enc_data, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -# define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - SSL3_VERSION, \ - ssl3_new, \ - ssl3_clear, \ - ssl3_free, \ - s_accept, \ - s_connect, \ - ssl3_read, \ - ssl3_peek, \ - ssl3_write, \ - ssl3_shutdown, \ - ssl3_renegotiate, \ - ssl3_renegotiate_check, \ - ssl3_get_message, \ - ssl3_read_bytes, \ - ssl3_write_bytes, \ - ssl3_dispatch_alert, \ - ssl3_ctrl, \ - ssl3_ctx_ctrl, \ - ssl3_get_cipher_by_char, \ - ssl3_put_cipher_by_char, \ - ssl3_pending, \ - ssl3_num_ciphers, \ - ssl3_get_cipher, \ - s_get_meth, \ - ssl3_default_timeout, \ - &SSLv3_enc_data, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -# define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - TLS1_2_VERSION, \ - tls1_new, \ - tls1_clear, \ - tls1_free, \ - s_accept, \ - s_connect, \ - ssl23_read, \ - ssl23_peek, \ - ssl23_write, \ - ssl_undefined_function, \ - ssl_undefined_function, \ - ssl_ok, \ - ssl3_get_message, \ - ssl3_read_bytes, \ - ssl3_write_bytes, \ - ssl3_dispatch_alert, \ - ssl3_ctrl, \ - ssl3_ctx_ctrl, \ - ssl23_get_cipher_by_char, \ - ssl23_put_cipher_by_char, \ - ssl_undefined_const_function, \ - ssl23_num_ciphers, \ - ssl23_get_cipher, \ - s_get_meth, \ - ssl23_default_timeout, \ - &TLSv1_2_enc_data, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -# define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - SSL2_VERSION, \ - ssl2_new, /* local */ \ - ssl2_clear, /* local */ \ - ssl2_free, /* local */ \ - s_accept, \ - s_connect, \ - ssl2_read, \ - ssl2_peek, \ - ssl2_write, \ - ssl2_shutdown, \ - ssl_ok, /* NULL - renegotiate */ \ - ssl_ok, /* NULL - check renegotiate */ \ - NULL, /* NULL - ssl_get_message */ \ - NULL, /* NULL - ssl_get_record */ \ - NULL, /* NULL - ssl_write_bytes */ \ - NULL, /* NULL - dispatch_alert */ \ - ssl2_ctrl, /* local */ \ - ssl2_ctx_ctrl, /* local */ \ - ssl2_get_cipher_by_char, \ - ssl2_put_cipher_by_char, \ - ssl2_pending, \ - ssl2_num_ciphers, \ - ssl2_get_cipher, \ - s_get_meth, \ - ssl2_default_timeout, \ - &ssl3_undef_enc_method, \ - ssl_undefined_void_function, \ - ssl2_callback_ctrl, /* local */ \ - ssl2_ctx_callback_ctrl, /* local */ \ - }; \ - return &func_name##_data; \ - } - -# define IMPLEMENT_dtls1_meth_func(version, func_name, s_accept, s_connect, \ - s_get_meth, enc_data) \ -const SSL_METHOD *func_name(void) \ - { \ - static const SSL_METHOD func_name##_data= { \ - version, \ - dtls1_new, \ - dtls1_clear, \ - dtls1_free, \ - s_accept, \ - s_connect, \ - ssl3_read, \ - ssl3_peek, \ - ssl3_write, \ - dtls1_shutdown, \ - ssl3_renegotiate, \ - ssl3_renegotiate_check, \ - dtls1_get_message, \ - dtls1_read_bytes, \ - dtls1_write_app_data_bytes, \ - dtls1_dispatch_alert, \ - dtls1_ctrl, \ - ssl3_ctx_ctrl, \ - ssl3_get_cipher_by_char, \ - ssl3_put_cipher_by_char, \ - ssl3_pending, \ - ssl3_num_ciphers, \ - dtls1_get_cipher, \ - s_get_meth, \ - dtls1_default_timeout, \ - &enc_data, \ - ssl_undefined_void_function, \ - ssl3_callback_ctrl, \ - ssl3_ctx_callback_ctrl, \ - }; \ - return &func_name##_data; \ - } - -struct openssl_ssl_test_functions { - int (*p_ssl_init_wbio_buffer) (SSL *s, int push); - int (*p_ssl3_setup_buffers) (SSL *s); - int (*p_tls1_process_heartbeat) (SSL *s); - int (*p_dtls1_process_heartbeat) (SSL *s); -}; - -# ifndef OPENSSL_UNIT_TEST - -void ssl_clear_cipher_ctx(SSL *s); -int ssl_clear_bad_session(SSL *s); -CERT *ssl_cert_new(void); -CERT *ssl_cert_dup(CERT *cert); -void ssl_cert_set_default_md(CERT *cert); -int ssl_cert_inst(CERT **o); -void ssl_cert_clear_certs(CERT *c); -void ssl_cert_free(CERT *c); -SESS_CERT *ssl_sess_cert_new(void); -void ssl_sess_cert_free(SESS_CERT *sc); -int ssl_set_peer_cert_type(SESS_CERT *c, int type); -int ssl_get_new_session(SSL *s, int session); -int ssl_get_prev_session(SSL *s, unsigned char *session, int len, - const unsigned char *limit); -SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket); -int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); -DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); -int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, - const SSL_CIPHER *const *bp); -STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, - int num, - STACK_OF(SSL_CIPHER) **skp); -int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, - unsigned char *p, - int (*put_cb) (const SSL_CIPHER *, - unsigned char *)); -STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, - STACK_OF(SSL_CIPHER) **pref, - STACK_OF(SSL_CIPHER) **sorted, - const char *rule_str, CERT *c); -void ssl_update_cache(SSL *s, int mode); -int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, - const EVP_MD **md, int *mac_pkey_type, - int *mac_secret_size, SSL_COMP **comp); -int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md); -int ssl_cipher_get_cert_index(const SSL_CIPHER *c); -const SSL_CIPHER *ssl_get_cipher_by_char(SSL *ssl, const unsigned char *ptr); -int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain); -int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain); -int ssl_cert_add0_chain_cert(CERT *c, X509 *x); -int ssl_cert_add1_chain_cert(CERT *c, X509 *x); -int ssl_cert_select_current(CERT *c, X509 *x); -int ssl_cert_set_current(CERT *c, long arg); -X509 *ssl_cert_get0_next_certificate(CERT *c, int first); -void ssl_cert_set_cert_cb(CERT *c, int (*cb) (SSL *ssl, void *arg), - void *arg); - -int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk); -int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l); -int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags); -int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref); -int ssl_undefined_function(SSL *s); -int ssl_undefined_void_function(void); -int ssl_undefined_const_function(const SSL *s); -CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); -# ifndef OPENSSL_NO_TLSEXT -int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, - size_t *serverinfo_length); -# endif -EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd); -int ssl_cert_type(X509 *x, EVP_PKEY *pkey); -void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); -STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); -int ssl_verify_alarm_type(long type); -void ssl_load_ciphers(void); -int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len); - -int ssl2_enc_init(SSL *s, int client); -int ssl2_generate_key_material(SSL *s); -int ssl2_enc(SSL *s, int send_data); -void ssl2_mac(SSL *s, unsigned char *mac, int send_data); -const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p); -int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -int ssl2_part_read(SSL *s, unsigned long f, int i); -int ssl2_do_write(SSL *s); -int ssl2_set_certificate(SSL *s, int type, int len, - const unsigned char *data); -void ssl2_return_error(SSL *s, int reason); -void ssl2_write_error(SSL *s); -int ssl2_num_ciphers(void); -const SSL_CIPHER *ssl2_get_cipher(unsigned int u); -int ssl2_new(SSL *s); -void ssl2_free(SSL *s); -int ssl2_accept(SSL *s); -int ssl2_connect(SSL *s); -int ssl2_read(SSL *s, void *buf, int len); -int ssl2_peek(SSL *s, void *buf, int len); -int ssl2_write(SSL *s, const void *buf, int len); -int ssl2_shutdown(SSL *s); -void ssl2_clear(SSL *s); -long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg); -long ssl2_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); -long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); -long ssl2_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); -int ssl2_pending(const SSL *s); -long ssl2_default_timeout(void); - -const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); -int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -int ssl3_init_finished_mac(SSL *s); -int ssl3_send_server_certificate(SSL *s); -int ssl3_send_newsession_ticket(SSL *s); -int ssl3_send_cert_status(SSL *s); -int ssl3_get_finished(SSL *s, int state_a, int state_b); -int ssl3_setup_key_block(SSL *s); -int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b); -int ssl3_change_cipher_state(SSL *s, int which); -void ssl3_cleanup_key_block(SSL *s); -int ssl3_do_write(SSL *s, int type); -int ssl3_send_alert(SSL *s, int level, int desc); -int ssl3_generate_master_secret(SSL *s, unsigned char *out, - unsigned char *p, int len); -int ssl3_get_req_cert_type(SSL *s, unsigned char *p); -long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); -int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen); -int ssl3_num_ciphers(void); -const SSL_CIPHER *ssl3_get_cipher(unsigned int u); -int ssl3_renegotiate(SSL *ssl); -int ssl3_renegotiate_check(SSL *ssl); -int ssl3_dispatch_alert(SSL *s); -int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); -int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); -int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, - unsigned char *p); -int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); -void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len); -int ssl3_enc(SSL *s, int send_data); -int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data); -void ssl3_free_digest_list(SSL *s); -unsigned long ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk); -SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, - STACK_OF(SSL_CIPHER) *srvr); -int ssl3_setup_buffers(SSL *s); -int ssl3_setup_read_buffer(SSL *s); -int ssl3_setup_write_buffer(SSL *s); -int ssl3_release_read_buffer(SSL *s); -int ssl3_release_write_buffer(SSL *s); -int ssl3_digest_cached_records(SSL *s); -int ssl3_new(SSL *s); -void ssl3_free(SSL *s); -int ssl3_accept(SSL *s); -int ssl3_connect(SSL *s); -int ssl3_read(SSL *s, void *buf, int len); -int ssl3_peek(SSL *s, void *buf, int len); -int ssl3_write(SSL *s, const void *buf, int len); -int ssl3_shutdown(SSL *s); -void ssl3_clear(SSL *s); -long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg); -long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); -long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); -long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); -int ssl3_pending(const SSL *s); - -void ssl3_record_sequence_update(unsigned char *seq); -int ssl3_do_change_cipher_spec(SSL *ssl); -long ssl3_default_timeout(void); - -void ssl3_set_handshake_header(SSL *s, int htype, unsigned long len); -int ssl3_handshake_write(SSL *s); - -int ssl23_num_ciphers(void); -const SSL_CIPHER *ssl23_get_cipher(unsigned int u); -int ssl23_read(SSL *s, void *buf, int len); -int ssl23_peek(SSL *s, void *buf, int len); -int ssl23_write(SSL *s, const void *buf, int len); -int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p); -long ssl23_default_timeout(void); - -long tls1_default_timeout(void); -int dtls1_do_write(SSL *s, int type); -int ssl3_read_n(SSL *s, int n, int max, int extend); -int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); -int ssl3_do_compress(SSL *ssl); -int ssl3_do_uncompress(SSL *ssl); -int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, - unsigned int len); -unsigned char *dtls1_set_message_header(SSL *s, - unsigned char *p, unsigned char mt, - unsigned long len, - unsigned long frag_off, - unsigned long frag_len); - -int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len); -int dtls1_write_bytes(SSL *s, int type, const void *buf, int len); - -int dtls1_send_change_cipher_spec(SSL *s, int a, int b); -int dtls1_read_failed(SSL *s, int code); -int dtls1_buffer_message(SSL *s, int ccs); -int dtls1_retransmit_message(SSL *s, unsigned short seq, - unsigned long frag_off, int *found); -int dtls1_get_queue_priority(unsigned short seq, int is_ccs); -int dtls1_retransmit_buffered_messages(SSL *s); -void dtls1_clear_received_buffer(SSL *s); -void dtls1_clear_sent_buffer(SSL *s); -void dtls1_get_message_header(unsigned char *data, - struct hm_header_st *msg_hdr); -void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); -void dtls1_reset_seq_numbers(SSL *s, int rw); -long dtls1_default_timeout(void); -struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft); -int dtls1_check_timeout_num(SSL *s); -int dtls1_handle_timeout(SSL *s); -const SSL_CIPHER *dtls1_get_cipher(unsigned int u); -void dtls1_start_timer(SSL *s); -void dtls1_stop_timer(SSL *s); -int dtls1_is_timer_expired(SSL *s); -void dtls1_double_timeout(SSL *s); -int dtls1_send_newsession_ticket(SSL *s); -unsigned int dtls1_min_mtu(SSL *s); -unsigned int dtls1_link_min_mtu(void); -void dtls1_hm_fragment_free(hm_fragment *frag); - -/* some client-only functions */ -int ssl3_client_hello(SSL *s); -int ssl3_get_server_hello(SSL *s); -int ssl3_get_certificate_request(SSL *s); -int ssl3_get_new_session_ticket(SSL *s); -int ssl3_get_cert_status(SSL *s); -int ssl3_get_server_done(SSL *s); -int ssl3_send_client_verify(SSL *s); -int ssl3_send_client_certificate(SSL *s); -int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); -int ssl3_send_client_key_exchange(SSL *s); -int ssl3_get_key_exchange(SSL *s); -int ssl3_get_server_certificate(SSL *s); -int ssl3_check_cert_and_algorithm(SSL *s); -# ifndef OPENSSL_NO_TLSEXT -# ifndef OPENSSL_NO_NEXTPROTONEG -int ssl3_send_next_proto(SSL *s); -# endif -# endif - -int dtls1_client_hello(SSL *s); - -/* some server-only functions */ -int ssl3_get_client_hello(SSL *s); -int ssl3_send_server_hello(SSL *s); -int ssl3_send_hello_request(SSL *s); -int ssl3_send_server_key_exchange(SSL *s); -int ssl3_send_certificate_request(SSL *s); -int ssl3_send_server_done(SSL *s); -int ssl3_get_client_certificate(SSL *s); -int ssl3_get_client_key_exchange(SSL *s); -int ssl3_get_cert_verify(SSL *s); -# ifndef OPENSSL_NO_NEXTPROTONEG -int ssl3_get_next_proto(SSL *s); -# endif - -int ssl23_accept(SSL *s); -int ssl23_connect(SSL *s); -int ssl23_read_bytes(SSL *s, int n); -int ssl23_write_bytes(SSL *s); - -int tls1_new(SSL *s); -void tls1_free(SSL *s); -void tls1_clear(SSL *s); -long tls1_ctrl(SSL *s, int cmd, long larg, void *parg); -long tls1_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); - -int dtls1_new(SSL *s); -int dtls1_accept(SSL *s); -int dtls1_connect(SSL *s); -void dtls1_free(SSL *s); -void dtls1_clear(SSL *s); -long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); -int dtls1_shutdown(SSL *s); - -long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); -int dtls1_get_record(SSL *s); -int do_dtls1_write(SSL *s, int type, const unsigned char *buf, - unsigned int len, int create_empty_fragement); -int dtls1_dispatch_alert(SSL *s); - -int ssl_init_wbio_buffer(SSL *s, int push); -void ssl_free_wbio_buffer(SSL *s); - -int tls1_change_cipher_state(SSL *s, int which); -int tls1_setup_key_block(SSL *s); -int tls1_enc(SSL *s, int snd); -int tls1_final_finish_mac(SSL *s, - const char *str, int slen, unsigned char *p); -int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); -int tls1_mac(SSL *ssl, unsigned char *md, int snd); -int tls1_generate_master_secret(SSL *s, unsigned char *out, - unsigned char *p, int len); -int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, - const char *label, size_t llen, - const unsigned char *p, size_t plen, - int use_context); -int tls1_alert_code(int code); -int ssl3_alert_code(int code); -int ssl_ok(SSL *s); - -# ifndef OPENSSL_NO_ECDH -int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); -# endif - -SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); - -# ifndef OPENSSL_NO_EC -int tls1_ec_curve_id2nid(int curve_id); -int tls1_ec_nid2curve_id(int nid); -int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); -int tls1_shared_curve(SSL *s, int nmatch); -int tls1_set_curves(unsigned char **pext, size_t *pextlen, - int *curves, size_t ncurves); -int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, - const char *str); -# ifndef OPENSSL_NO_ECDH -int tls1_check_ec_tmp_key(SSL *s, unsigned long id); -# endif /* OPENSSL_NO_ECDH */ -# endif /* OPENSSL_NO_EC */ - -# ifndef OPENSSL_NO_TLSEXT -int tls1_shared_list(SSL *s, - const unsigned char *l1, size_t l1len, - const unsigned char *l2, size_t l2len, int nmatch); -unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al); -unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al); -int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, - unsigned char *limit); -int tls1_set_server_sigalgs(SSL *s); -int ssl_check_clienthello_tlsext_late(SSL *s, int *al); -int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, - unsigned char *d, int n); -int ssl_prepare_clienthello_tlsext(SSL *s); -int ssl_prepare_serverhello_tlsext(SSL *s); - -# ifndef OPENSSL_NO_HEARTBEATS -int tls1_heartbeat(SSL *s); -int dtls1_heartbeat(SSL *s); -int tls1_process_heartbeat(SSL *s); -int dtls1_process_heartbeat(SSL *s); -# endif - -# ifdef OPENSSL_NO_SHA256 -# define tlsext_tick_md EVP_sha1 -# else -# define tlsext_tick_md EVP_sha256 -# endif -int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, - const unsigned char *limit, SSL_SESSION **ret); - -int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, - const EVP_MD *md); -int tls12_get_sigid(const EVP_PKEY *pk); -const EVP_MD *tls12_get_hash(unsigned char hash_alg); - -int tls1_set_sigalgs_list(CERT *c, const char *str, int client); -int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, int client); -int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, - int idx); -void tls1_set_cert_validity(SSL *s); - -# endif -EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md); -void ssl_clear_hash_ctx(EVP_MD_CTX **hash); -int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, - int maxlen); -int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, - int *al); -int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, - int maxlen); -int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, - int *al); -long ssl_get_algorithm2(SSL *s); -int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize); -int tls1_process_sigalgs(SSL *s); -size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs); -int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, - const unsigned char *sig, EVP_PKEY *pkey); -void ssl_set_client_disabled(SSL *s); - -int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, - int maxlen); -int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len, - int *al); -int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, - int maxlen); -int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len, - int *al); - -/* s3_cbc.c */ -void ssl3_cbc_copy_mac(unsigned char *out, - const SSL3_RECORD *rec, - unsigned md_size, unsigned orig_len); -int ssl3_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - unsigned block_size, unsigned mac_size); -int tls1_cbc_remove_padding(const SSL *s, - SSL3_RECORD *rec, - unsigned block_size, unsigned mac_size); -char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); -int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, - unsigned char *md_out, - size_t *md_out_size, - const unsigned char header[13], - const unsigned char *data, - size_t data_plus_mac_size, - size_t data_plus_mac_plus_padding_size, - const unsigned char *mac_secret, - unsigned mac_secret_length, char is_sslv3); - -void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx, - EVP_MD_CTX *mac_ctx, const unsigned char *data, - size_t data_len, size_t orig_len); - -int srp_verify_server_param(SSL *s, int *al); - -/* t1_ext.c */ - -void custom_ext_init(custom_ext_methods *meths); - -int custom_ext_parse(SSL *s, int server, - unsigned int ext_type, - const unsigned char *ext_data, size_t ext_size, int *al); -int custom_ext_add(SSL *s, int server, - unsigned char **pret, unsigned char *limit, int *al); - -int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src); -int custom_exts_copy_flags(custom_ext_methods *dst, - const custom_ext_methods *src); -void custom_exts_free(custom_ext_methods *exts); - -# else - -# define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer -# define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers -# define tls1_process_heartbeat SSL_test_functions()->p_tls1_process_heartbeat -# define dtls1_process_heartbeat SSL_test_functions()->p_dtls1_process_heartbeat - -# endif -#endif diff --git a/Sources/COpenSSL/stack.c b/Sources/COpenSSL/stack.c deleted file mode 100644 index 2ae0c354..00000000 --- a/Sources/COpenSSL/stack.c +++ /dev/null @@ -1,384 +0,0 @@ -/* crypto/stack/stack.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -/*- - * Code for stacks - * Author - Eric Young v 1.0 - * 1.2 eay 12-Mar-97 - Modified sk_find so that it _DOES_ return the - * lowest index for the searched item. - * - * 1.1 eay - Take from netdb and added to SSLeay - * - * 1.0 eay - First version 29/07/92 - */ -#include -#include "cryptlib.h" -#include "stack.h" -#include "objects.h" - -#undef MIN_NODES -#define MIN_NODES 4 - -const char STACK_version[] = "Stack" OPENSSL_VERSION_PTEXT; - -#include - -int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) - (const void *, const void *) { - int (*old) (const void *, const void *) = sk->comp; - - if (sk->comp != c) - sk->sorted = 0; - sk->comp = c; - - return old; -} - -_STACK *sk_dup(_STACK *sk) -{ - _STACK *ret; - char **s; - - if ((ret = sk_new(sk->comp)) == NULL) - goto err; - s = (char **)OPENSSL_realloc((char *)ret->data, - (unsigned int)sizeof(char *) * - sk->num_alloc); - if (s == NULL) - goto err; - ret->data = s; - - ret->num = sk->num; - memcpy(ret->data, sk->data, sizeof(char *) * sk->num); - ret->sorted = sk->sorted; - ret->num_alloc = sk->num_alloc; - ret->comp = sk->comp; - return (ret); - err: - if (ret) - sk_free(ret); - return (NULL); -} - -_STACK *sk_deep_copy(_STACK *sk, void *(*copy_func) (void *), - void (*free_func) (void *)) -{ - _STACK *ret; - int i; - - if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL) - return ret; - ret->comp = sk->comp; - ret->sorted = sk->sorted; - ret->num = sk->num; - ret->num_alloc = sk->num > MIN_NODES ? sk->num : MIN_NODES; - ret->data = OPENSSL_malloc(sizeof(char *) * ret->num_alloc); - if (ret->data == NULL) { - OPENSSL_free(ret); - return NULL; - } - for (i = 0; i < ret->num_alloc; i++) - ret->data[i] = NULL; - - for (i = 0; i < ret->num; ++i) { - if (sk->data[i] == NULL) - continue; - if ((ret->data[i] = copy_func(sk->data[i])) == NULL) { - while (--i >= 0) - if (ret->data[i] != NULL) - free_func(ret->data[i]); - sk_free(ret); - return NULL; - } - } - return ret; -} - -_STACK *sk_new_null(void) -{ - return sk_new((int (*)(const void *, const void *))0); -} - -_STACK *sk_new(int (*c) (const void *, const void *)) -{ - _STACK *ret; - int i; - - if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL) - goto err; - if ((ret->data = OPENSSL_malloc(sizeof(char *) * MIN_NODES)) == NULL) - goto err; - for (i = 0; i < MIN_NODES; i++) - ret->data[i] = NULL; - ret->comp = c; - ret->num_alloc = MIN_NODES; - ret->num = 0; - ret->sorted = 0; - return (ret); - err: - if (ret) - OPENSSL_free(ret); - return (NULL); -} - -int sk_insert(_STACK *st, void *data, int loc) -{ - char **s; - - if (st == NULL) - return 0; - if (st->num_alloc <= st->num + 1) { - s = OPENSSL_realloc((char *)st->data, - (unsigned int)sizeof(char *) * st->num_alloc * 2); - if (s == NULL) - return (0); - st->data = s; - st->num_alloc *= 2; - } - if ((loc >= (int)st->num) || (loc < 0)) - st->data[st->num] = data; - else { - int i; - char **f, **t; - - f = st->data; - t = &(st->data[1]); - for (i = st->num; i >= loc; i--) - t[i] = f[i]; - -#ifdef undef /* no memmove on sunos :-( */ - memmove(&(st->data[loc + 1]), - &(st->data[loc]), sizeof(char *) * (st->num - loc)); -#endif - st->data[loc] = data; - } - st->num++; - st->sorted = 0; - return (st->num); -} - -void *sk_delete_ptr(_STACK *st, void *p) -{ - int i; - - for (i = 0; i < st->num; i++) - if (st->data[i] == p) - return (sk_delete(st, i)); - return (NULL); -} - -void *sk_delete(_STACK *st, int loc) -{ - char *ret; - int i, j; - - if (!st || (loc < 0) || (loc >= st->num)) - return NULL; - - ret = st->data[loc]; - if (loc != st->num - 1) { - j = st->num - 1; - for (i = loc; i < j; i++) - st->data[i] = st->data[i + 1]; - /* - * In theory memcpy is not safe for this memcpy( &(st->data[loc]), - * &(st->data[loc+1]), sizeof(char *)*(st->num-loc-1)); - */ - } - st->num--; - return (ret); -} - -static int internal_find(_STACK *st, void *data, int ret_val_options) -{ - const void *const *r; - int i; - - if (st == NULL) - return -1; - - if (st->comp == NULL) { - for (i = 0; i < st->num; i++) - if (st->data[i] == data) - return (i); - return (-1); - } - sk_sort(st); - if (data == NULL) - return (-1); - r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp, - ret_val_options); - if (r == NULL) - return (-1); - return (int)((char **)r - st->data); -} - -int sk_find(_STACK *st, void *data) -{ - return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); -} - -int sk_find_ex(_STACK *st, void *data) -{ - return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); -} - -int sk_push(_STACK *st, void *data) -{ - return (sk_insert(st, data, st->num)); -} - -int sk_unshift(_STACK *st, void *data) -{ - return (sk_insert(st, data, 0)); -} - -void *sk_shift(_STACK *st) -{ - if (st == NULL) - return (NULL); - if (st->num <= 0) - return (NULL); - return (sk_delete(st, 0)); -} - -void *sk_pop(_STACK *st) -{ - if (st == NULL) - return (NULL); - if (st->num <= 0) - return (NULL); - return (sk_delete(st, st->num - 1)); -} - -void sk_zero(_STACK *st) -{ - if (st == NULL) - return; - if (st->num <= 0) - return; - memset((char *)st->data, 0, sizeof(*st->data) * st->num); - st->num = 0; -} - -void sk_pop_free(_STACK *st, void (*func) (void *)) -{ - int i; - - if (st == NULL) - return; - for (i = 0; i < st->num; i++) - if (st->data[i] != NULL) - func(st->data[i]); - sk_free(st); -} - -void sk_free(_STACK *st) -{ - if (st == NULL) - return; - if (st->data != NULL) - OPENSSL_free(st->data); - OPENSSL_free(st); -} - -int sk_num(const _STACK *st) -{ - if (st == NULL) - return -1; - return st->num; -} - -void *sk_value(const _STACK *st, int i) -{ - if (!st || (i < 0) || (i >= st->num)) - return NULL; - return st->data[i]; -} - -void *sk_set(_STACK *st, int i, void *value) -{ - if (!st || (i < 0) || (i >= st->num)) - return NULL; - return (st->data[i] = value); -} - -void sk_sort(_STACK *st) -{ - if (st && !st->sorted && st->comp != NULL) { - int (*comp_func) (const void *, const void *); - - /* - * same comment as in sk_find ... previously st->comp was declared as - * a (void*,void*) callback type, but this made the population of the - * callback pointer illogical - our callbacks compare type** with - * type**, so we leave the casting until absolutely necessary (ie. - * "now"). - */ - comp_func = (int (*)(const void *, const void *))(st->comp); - qsort(st->data, st->num, sizeof(char *), comp_func); - st->sorted = 1; - } -} - -int sk_is_sorted(const _STACK *st) -{ - if (!st) - return 1; - return st->sorted; -} diff --git a/Sources/COpenSSL/stack.h b/Sources/COpenSSL/stack.h deleted file mode 100644 index eb072166..00000000 --- a/Sources/COpenSSL/stack.h +++ /dev/null @@ -1,107 +0,0 @@ -/* crypto/stack/stack.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_STACK_H -# define HEADER_STACK_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct stack_st { - int num; - char **data; - int sorted; - int num_alloc; - int (*comp) (const void *, const void *); -} _STACK; /* Use STACK_OF(...) instead */ - -# define M_sk_num(sk) ((sk) ? (sk)->num:-1) -# define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) - -int sk_num(const _STACK *); -void *sk_value(const _STACK *, int); - -void *sk_set(_STACK *, int, void *); - -_STACK *sk_new(int (*cmp) (const void *, const void *)); -_STACK *sk_new_null(void); -void sk_free(_STACK *); -void sk_pop_free(_STACK *st, void (*func) (void *)); -_STACK *sk_deep_copy(_STACK *, void *(*)(void *), void (*)(void *)); -int sk_insert(_STACK *sk, void *data, int where); -void *sk_delete(_STACK *st, int loc); -void *sk_delete_ptr(_STACK *st, void *p); -int sk_find(_STACK *st, void *data); -int sk_find_ex(_STACK *st, void *data); -int sk_push(_STACK *st, void *data); -int sk_unshift(_STACK *st, void *data); -void *sk_shift(_STACK *st); -void *sk_pop(_STACK *st); -void sk_zero(_STACK *st); -int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) - (const void *, const void *); -_STACK *sk_dup(_STACK *st); -void sk_sort(_STACK *st); -int sk_is_sorted(const _STACK *st); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/str2key.c b/Sources/COpenSSL/str2key.c deleted file mode 100644 index bcb8b1ca..00000000 --- a/Sources/COpenSSL/str2key.c +++ /dev/null @@ -1,165 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/des/str2key.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "crypto.h" -#include "des_locl.h" - -void DES_string_to_key(const char *str, DES_cblock *key) -{ - DES_key_schedule ks; - int i, length; - register unsigned char j; - - memset(key, 0, 8); - length = strlen(str); -#ifdef OLD_STR_TO_KEY - for (i = 0; i < length; i++) - (*key)[i % 8] ^= (str[i] << 1); -#else /* MIT COMPATIBLE */ - for (i = 0; i < length; i++) { - j = str[i]; - if ((i % 16) < 8) - (*key)[i % 8] ^= (j << 1); - else { - /* Reverse the bit order 05/05/92 eay */ - j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f); - j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33); - j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55); - (*key)[7 - (i % 8)] ^= j; - } - } -#endif - DES_set_odd_parity(key); -#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY - if (DES_is_weak_key(key)) - (*key)[7] ^= 0xF0; - DES_set_key(key, &ks); -#else - DES_set_key_unchecked(key, &ks); -#endif - DES_cbc_cksum((const unsigned char *)str, key, length, &ks, key); - OPENSSL_cleanse(&ks, sizeof(ks)); - DES_set_odd_parity(key); -} - -void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2) -{ - DES_key_schedule ks; - int i, length; - register unsigned char j; - - memset(key1, 0, 8); - memset(key2, 0, 8); - length = strlen(str); -#ifdef OLD_STR_TO_KEY - if (length <= 8) { - for (i = 0; i < length; i++) { - (*key2)[i] = (*key1)[i] = (str[i] << 1); - } - } else { - for (i = 0; i < length; i++) { - if ((i / 8) & 1) - (*key2)[i % 8] ^= (str[i] << 1); - else - (*key1)[i % 8] ^= (str[i] << 1); - } - } -#else /* MIT COMPATIBLE */ - for (i = 0; i < length; i++) { - j = str[i]; - if ((i % 32) < 16) { - if ((i % 16) < 8) - (*key1)[i % 8] ^= (j << 1); - else - (*key2)[i % 8] ^= (j << 1); - } else { - j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f); - j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33); - j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55); - if ((i % 16) < 8) - (*key1)[7 - (i % 8)] ^= j; - else - (*key2)[7 - (i % 8)] ^= j; - } - } - if (length <= 8) - memcpy(key2, key1, 8); -#endif - DES_set_odd_parity(key1); - DES_set_odd_parity(key2); -#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY - if (DES_is_weak_key(key1)) - (*key1)[7] ^= 0xF0; - DES_set_key(key1, &ks); -#else - DES_set_key_unchecked(key1, &ks); -#endif - DES_cbc_cksum((const unsigned char *)str, key1, length, &ks, key1); -#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY - if (DES_is_weak_key(key2)) - (*key2)[7] ^= 0xF0; - DES_set_key(key2, &ks); -#else - DES_set_key_unchecked(key2, &ks); -#endif - DES_cbc_cksum((const unsigned char *)str, key2, length, &ks, key2); - OPENSSL_cleanse(&ks, sizeof(ks)); - DES_set_odd_parity(key1); - DES_set_odd_parity(key2); -} diff --git a/Sources/COpenSSL/sureware.h b/Sources/COpenSSL/sureware.h deleted file mode 100644 index b1423e19..00000000 --- a/Sources/COpenSSL/sureware.h +++ /dev/null @@ -1,250 +0,0 @@ -/*- - * Written by Corinne Dive-Reclus(cdive@baltimore.com) - * - * Copyright@2001 Baltimore Technologies Ltd. - * - * THIS FILE IS PROVIDED BY BALTIMORE TECHNOLOGIES ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL BALTIMORE TECHNOLOGIES BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifdef WIN32 -# define SW_EXPORT __declspec ( dllexport ) -#else -# define SW_EXPORT -#endif - -/* - * List of exposed SureWare errors - */ -#define SUREWAREHOOK_ERROR_FAILED -1 -#define SUREWAREHOOK_ERROR_FALLBACK -2 -#define SUREWAREHOOK_ERROR_UNIT_FAILURE -3 -#define SUREWAREHOOK_ERROR_DATA_SIZE -4 -#define SUREWAREHOOK_ERROR_INVALID_PAD -5 -/*- -* -----------------WARNING----------------------------------- -* In all the following functions: -* msg is a string with at least 24 bytes free. -* A 24 bytes string will be concatenated to the existing content of msg. -*/ -/*- -* SureWare Initialisation function -* in param threadsafe, if !=0, thread safe enabled -* return SureWareHOOK_ERROR_UNIT_FAILURE if failure, 1 if success -*/ -typedef int SureWareHook_Init_t(char *const msg, int threadsafe); -extern SW_EXPORT SureWareHook_Init_t SureWareHook_Init; -/*- -* SureWare Finish function -*/ -typedef void SureWareHook_Finish_t(void); -extern SW_EXPORT SureWareHook_Finish_t SureWareHook_Finish; -/*- -* PRE_CONDITION: -* DO NOT CALL ANY OF THE FOLLOWING FUNCTIONS IN CASE OF INIT FAILURE -*/ -/*- -* SureWare RAND Bytes function -* In case of failure, the content of buf is unpredictable. -* return 1 if success -* SureWareHOOK_ERROR_FALLBACK if function not available in hardware -* SureWareHOOK_ERROR_FAILED if error while processing -* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure -* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf -* -* in/out param buf : a num bytes long buffer where random bytes will be put -* in param num : the number of bytes into buf -*/ -typedef int SureWareHook_Rand_Bytes_t(char *const msg, unsigned char *buf, - int num); -extern SW_EXPORT SureWareHook_Rand_Bytes_t SureWareHook_Rand_Bytes; - -/*- -* SureWare RAND Seed function -* Adds some seed to the Hardware Random Number Generator -* return 1 if success -* SureWareHOOK_ERROR_FALLBACK if function not available in hardware -* SureWareHOOK_ERROR_FAILED if error while processing -* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure -* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf -* -* in param buf : the seed to add into the HRNG -* in param num : the number of bytes into buf -*/ -typedef int SureWareHook_Rand_Seed_t(char *const msg, const void *buf, - int num); -extern SW_EXPORT SureWareHook_Rand_Seed_t SureWareHook_Rand_Seed; - -/*- -* SureWare Load Private Key function -* return 1 if success -* SureWareHOOK_ERROR_FAILED if error while processing -* No hardware is contact for this function. -* -* in param key_id :the name of the private protected key file without the extension - ".sws" -* out param hptr : a pointer to a buffer allocated by SureWare_Hook -* out param num: the effective key length in bytes -* out param keytype: 1 if RSA 2 if DSA -*/ -typedef int SureWareHook_Load_Privkey_t(char *const msg, const char *key_id, - char **hptr, unsigned long *num, - char *keytype); -extern SW_EXPORT SureWareHook_Load_Privkey_t SureWareHook_Load_Privkey; - -/*- -* SureWare Info Public Key function -* return 1 if success -* SureWareHOOK_ERROR_FAILED if error while processing -* No hardware is contact for this function. -* -* in param key_id :the name of the private protected key file without the extension - ".swp" -* out param hptr : a pointer to a buffer allocated by SureWare_Hook -* out param num: the effective key length in bytes -* out param keytype: 1 if RSA 2 if DSA -*/ -typedef int SureWareHook_Info_Pubkey_t(char *const msg, const char *key_id, - unsigned long *num, char *keytype); -extern SW_EXPORT SureWareHook_Info_Pubkey_t SureWareHook_Info_Pubkey; - -/*- -* SureWare Load Public Key function -* return 1 if success -* SureWareHOOK_ERROR_FAILED if error while processing -* No hardware is contact for this function. -* -* in param key_id :the name of the public protected key file without the extension - ".swp" -* in param num : the bytes size of n and e -* out param n: where to write modulus in bn format -* out param e: where to write exponent in bn format -*/ -typedef int SureWareHook_Load_Rsa_Pubkey_t(char *const msg, - const char *key_id, - unsigned long num, - unsigned long *n, - unsigned long *e); -extern SW_EXPORT SureWareHook_Load_Rsa_Pubkey_t SureWareHook_Load_Rsa_Pubkey; - -/*- -* SureWare Load DSA Public Key function -* return 1 if success -* SureWareHOOK_ERROR_FAILED if error while processing -* No hardware is contact for this function. -* -* in param key_id :the name of the public protected key file without the extension - ".swp" -* in param num : the bytes size of n and e -* out param pub: where to write pub key in bn format -* out param p: where to write prime in bn format -* out param q: where to write sunprime (length 20 bytes) in bn format -* out param g: where to write base in bn format -*/ -typedef int SureWareHook_Load_Dsa_Pubkey_t(char *const msg, - const char *key_id, - unsigned long num, - unsigned long *pub, - unsigned long *p, unsigned long *q, - unsigned long *g); -extern SW_EXPORT SureWareHook_Load_Dsa_Pubkey_t SureWareHook_Load_Dsa_Pubkey; - -/*- -* SureWare Free function -* Destroy the key into the hardware if destroy==1 -*/ -typedef void SureWareHook_Free_t(char *p, int destroy); -extern SW_EXPORT SureWareHook_Free_t SureWareHook_Free; - -#define SUREWARE_PKCS1_PAD 1 -#define SUREWARE_ISO9796_PAD 2 -#define SUREWARE_NO_PAD 0 -/*- -* SureWare RSA Private Decryption -* return 1 if success -* SureWareHOOK_ERROR_FAILED if error while processing -* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure -* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf -* -* in param flen : byte size of from and to -* in param from : encrypted data buffer, should be a not-null valid pointer -* out param tlen: byte size of decrypted data, if error, unexpected value -* out param to : decrypted data buffer, should be a not-null valid pointer -* in param prsa: a protected key pointer, should be a not-null valid pointer -* int padding: padding id as follow -* SUREWARE_PKCS1_PAD -* SUREWARE_NO_PAD -* -*/ -typedef int SureWareHook_Rsa_Priv_Dec_t(char *const msg, int flen, - unsigned char *from, int *tlen, - unsigned char *to, char *prsa, - int padding); -extern SW_EXPORT SureWareHook_Rsa_Priv_Dec_t SureWareHook_Rsa_Priv_Dec; -/*- -* SureWare RSA Signature -* return 1 if success -* SureWareHOOK_ERROR_FAILED if error while processing -* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure -* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf -* -* in param flen : byte size of from and to -* in param from : encrypted data buffer, should be a not-null valid pointer -* out param tlen: byte size of decrypted data, if error, unexpected value -* out param to : decrypted data buffer, should be a not-null valid pointer -* in param prsa: a protected key pointer, should be a not-null valid pointer -* int padding: padding id as follow -* SUREWARE_PKCS1_PAD -* SUREWARE_ISO9796_PAD -* -*/ -typedef int SureWareHook_Rsa_Sign_t(char *const msg, int flen, - unsigned char *from, int *tlen, - unsigned char *to, char *prsa, - int padding); -extern SW_EXPORT SureWareHook_Rsa_Sign_t SureWareHook_Rsa_Sign; -/*- -* SureWare DSA Signature -* return 1 if success -* SureWareHOOK_ERROR_FAILED if error while processing -* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure -* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf -* -* in param flen : byte size of from and to -* in param from : encrypted data buffer, should be a not-null valid pointer -* out param to : decrypted data buffer, should be a 40bytes valid pointer -* in param pdsa: a protected key pointer, should be a not-null valid pointer -* -*/ -typedef int SureWareHook_Dsa_Sign_t(char *const msg, int flen, - const unsigned char *from, - unsigned long *r, unsigned long *s, - char *pdsa); -extern SW_EXPORT SureWareHook_Dsa_Sign_t SureWareHook_Dsa_Sign; - -/*- -* SureWare Mod Exp -* return 1 if success -* SureWareHOOK_ERROR_FAILED if error while processing -* SureWareHOOK_ERROR_UNIT_FAILURE if hardware failure -* SUREWAREHOOK_ERROR_DATA_SIZE wrong size for buf -* -* mod and res are mlen bytes long. -* exp is elen bytes long -* data is dlen bytes long -* mlen,elen and dlen are all multiple of sizeof(unsigned long) -*/ -typedef int SureWareHook_Mod_Exp_t(char *const msg, int mlen, - const unsigned long *mod, int elen, - const unsigned long *exponent, int dlen, - unsigned long *data, unsigned long *res); -extern SW_EXPORT SureWareHook_Mod_Exp_t SureWareHook_Mod_Exp; diff --git a/Sources/COpenSSL/symhacks.h b/Sources/COpenSSL/symhacks.h deleted file mode 100644 index f5677389..00000000 --- a/Sources/COpenSSL/symhacks.h +++ /dev/null @@ -1,518 +0,0 @@ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_SYMHACKS_H -# define HEADER_SYMHACKS_H - -# include "e_os2.h" - -/* - * Hacks to solve the problem with linkers incapable of handling very long - * symbol names. In the case of VMS, the limit is 31 characters on VMS for - * VAX. - */ -/* - * Note that this affects util/libeay.num and util/ssleay.num... you may - * change those manually, but that's not recommended, as those files are - * controlled centrally and updated on Unix, and the central definition may - * disagree with yours, which in turn may come with shareable library - * incompatibilities. - */ -# ifdef OPENSSL_SYS_VMS - -/* Hack a long name in crypto/ex_data.c */ -# undef CRYPTO_get_ex_data_implementation -# define CRYPTO_get_ex_data_implementation CRYPTO_get_ex_data_impl -# undef CRYPTO_set_ex_data_implementation -# define CRYPTO_set_ex_data_implementation CRYPTO_set_ex_data_impl - -/* Hack a long name in crypto/asn1/a_mbstr.c */ -# undef ASN1_STRING_set_default_mask_asc -# define ASN1_STRING_set_default_mask_asc ASN1_STRING_set_def_mask_asc - -# if 0 /* No longer needed, since safestack macro - * magic does the job */ -/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */ -# undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO -# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO i2d_ASN1_SET_OF_PKCS7_SIGINF -# undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO -# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO d2i_ASN1_SET_OF_PKCS7_SIGINF -# endif - -# if 0 /* No longer needed, since safestack macro - * magic does the job */ -/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */ -# undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO -# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO i2d_ASN1_SET_OF_PKCS7_RECINF -# undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO -# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO d2i_ASN1_SET_OF_PKCS7_RECINF -# endif - -# if 0 /* No longer needed, since safestack macro - * magic does the job */ -/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */ -# undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION -# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION i2d_ASN1_SET_OF_ACC_DESC -# undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION -# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION d2i_ASN1_SET_OF_ACC_DESC -# endif - -/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */ -# undef PEM_read_NETSCAPE_CERT_SEQUENCE -# define PEM_read_NETSCAPE_CERT_SEQUENCE PEM_read_NS_CERT_SEQ -# undef PEM_write_NETSCAPE_CERT_SEQUENCE -# define PEM_write_NETSCAPE_CERT_SEQUENCE PEM_write_NS_CERT_SEQ -# undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE -# define PEM_read_bio_NETSCAPE_CERT_SEQUENCE PEM_read_bio_NS_CERT_SEQ -# undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE -# define PEM_write_bio_NETSCAPE_CERT_SEQUENCE PEM_write_bio_NS_CERT_SEQ -# undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE -# define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ - -/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */ -# undef PEM_read_PKCS8_PRIV_KEY_INFO -# define PEM_read_PKCS8_PRIV_KEY_INFO PEM_read_P8_PRIV_KEY_INFO -# undef PEM_write_PKCS8_PRIV_KEY_INFO -# define PEM_write_PKCS8_PRIV_KEY_INFO PEM_write_P8_PRIV_KEY_INFO -# undef PEM_read_bio_PKCS8_PRIV_KEY_INFO -# define PEM_read_bio_PKCS8_PRIV_KEY_INFO PEM_read_bio_P8_PRIV_KEY_INFO -# undef PEM_write_bio_PKCS8_PRIV_KEY_INFO -# define PEM_write_bio_PKCS8_PRIV_KEY_INFO PEM_write_bio_P8_PRIV_KEY_INFO -# undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO -# define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO PEM_wrt_cb_bio_P8_PRIV_KEY_INFO - -/* Hack other PEM names */ -# undef PEM_write_bio_PKCS8PrivateKey_nid -# define PEM_write_bio_PKCS8PrivateKey_nid PEM_write_bio_PKCS8PrivKey_nid - -/* Hack some long X509 names */ -# undef X509_REVOKED_get_ext_by_critical -# define X509_REVOKED_get_ext_by_critical X509_REVOKED_get_ext_by_critic -# undef X509_policy_tree_get0_user_policies -# define X509_policy_tree_get0_user_policies X509_pcy_tree_get0_usr_policies -# undef X509_policy_node_get0_qualifiers -# define X509_policy_node_get0_qualifiers X509_pcy_node_get0_qualifiers -# undef X509_STORE_CTX_get_explicit_policy -# define X509_STORE_CTX_get_explicit_policy X509_STORE_CTX_get_expl_policy -# undef X509_STORE_CTX_get0_current_issuer -# define X509_STORE_CTX_get0_current_issuer X509_STORE_CTX_get0_cur_issuer - -/* Hack some long CRYPTO names */ -# undef CRYPTO_set_dynlock_destroy_callback -# define CRYPTO_set_dynlock_destroy_callback CRYPTO_set_dynlock_destroy_cb -# undef CRYPTO_set_dynlock_create_callback -# define CRYPTO_set_dynlock_create_callback CRYPTO_set_dynlock_create_cb -# undef CRYPTO_set_dynlock_lock_callback -# define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb -# undef CRYPTO_get_dynlock_lock_callback -# define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb -# undef CRYPTO_get_dynlock_destroy_callback -# define CRYPTO_get_dynlock_destroy_callback CRYPTO_get_dynlock_destroy_cb -# undef CRYPTO_get_dynlock_create_callback -# define CRYPTO_get_dynlock_create_callback CRYPTO_get_dynlock_create_cb -# undef CRYPTO_set_locked_mem_ex_functions -# define CRYPTO_set_locked_mem_ex_functions CRYPTO_set_locked_mem_ex_funcs -# undef CRYPTO_get_locked_mem_ex_functions -# define CRYPTO_get_locked_mem_ex_functions CRYPTO_get_locked_mem_ex_funcs - -/* Hack some long SSL/TLS names */ -# undef SSL_CTX_set_default_verify_paths -# define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths -# undef SSL_get_ex_data_X509_STORE_CTX_idx -# define SSL_get_ex_data_X509_STORE_CTX_idx SSL_get_ex_d_X509_STORE_CTX_idx -# undef SSL_add_file_cert_subjects_to_stack -# define SSL_add_file_cert_subjects_to_stack SSL_add_file_cert_subjs_to_stk -# undef SSL_add_dir_cert_subjects_to_stack -# define SSL_add_dir_cert_subjects_to_stack SSL_add_dir_cert_subjs_to_stk -# undef SSL_CTX_use_certificate_chain_file -# define SSL_CTX_use_certificate_chain_file SSL_CTX_use_cert_chain_file -# undef SSL_CTX_set_cert_verify_callback -# define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb -# undef SSL_CTX_set_default_passwd_cb_userdata -# define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud -# undef SSL_COMP_get_compression_methods -# define SSL_COMP_get_compression_methods SSL_COMP_get_compress_methods -# undef SSL_COMP_set0_compression_methods -# define SSL_COMP_set0_compression_methods SSL_COMP_set0_compress_methods -# undef SSL_COMP_free_compression_methods -# define SSL_COMP_free_compression_methods SSL_COMP_free_compress_methods -# undef ssl_add_clienthello_renegotiate_ext -# define ssl_add_clienthello_renegotiate_ext ssl_add_clienthello_reneg_ext -# undef ssl_add_serverhello_renegotiate_ext -# define ssl_add_serverhello_renegotiate_ext ssl_add_serverhello_reneg_ext -# undef ssl_parse_clienthello_renegotiate_ext -# define ssl_parse_clienthello_renegotiate_ext ssl_parse_clienthello_reneg_ext -# undef ssl_parse_serverhello_renegotiate_ext -# define ssl_parse_serverhello_renegotiate_ext ssl_parse_serverhello_reneg_ext -# undef SSL_srp_server_param_with_username -# define SSL_srp_server_param_with_username SSL_srp_server_param_with_un -# undef SSL_CTX_set_srp_client_pwd_callback -# define SSL_CTX_set_srp_client_pwd_callback SSL_CTX_set_srp_client_pwd_cb -# undef SSL_CTX_set_srp_verify_param_callback -# define SSL_CTX_set_srp_verify_param_callback SSL_CTX_set_srp_vfy_param_cb -# undef SSL_CTX_set_srp_username_callback -# define SSL_CTX_set_srp_username_callback SSL_CTX_set_srp_un_cb -# undef ssl_add_clienthello_use_srtp_ext -# define ssl_add_clienthello_use_srtp_ext ssl_add_clihello_use_srtp_ext -# undef ssl_add_serverhello_use_srtp_ext -# define ssl_add_serverhello_use_srtp_ext ssl_add_serhello_use_srtp_ext -# undef ssl_parse_clienthello_use_srtp_ext -# define ssl_parse_clienthello_use_srtp_ext ssl_parse_clihello_use_srtp_ext -# undef ssl_parse_serverhello_use_srtp_ext -# define ssl_parse_serverhello_use_srtp_ext ssl_parse_serhello_use_srtp_ext -# undef SSL_CTX_set_next_protos_advertised_cb -# define SSL_CTX_set_next_protos_advertised_cb SSL_CTX_set_next_protos_adv_cb -# undef SSL_CTX_set_next_proto_select_cb -# define SSL_CTX_set_next_proto_select_cb SSL_CTX_set_next_proto_sel_cb - -# undef tls1_send_server_supplemental_data -# define tls1_send_server_supplemental_data tls1_send_server_suppl_data -# undef tls1_send_client_supplemental_data -# define tls1_send_client_supplemental_data tls1_send_client_suppl_data -# undef tls1_get_server_supplemental_data -# define tls1_get_server_supplemental_data tls1_get_server_suppl_data -# undef tls1_get_client_supplemental_data -# define tls1_get_client_supplemental_data tls1_get_client_suppl_data - -# undef ssl3_cbc_record_digest_supported -# define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support -# undef ssl_check_clienthello_tlsext_late -# define ssl_check_clienthello_tlsext_late ssl_check_clihello_tlsext_late -# undef ssl_check_clienthello_tlsext_early -# define ssl_check_clienthello_tlsext_early ssl_check_clihello_tlsext_early - -/* Hack some RSA long names */ -# undef RSA_padding_check_PKCS1_OAEP_mgf1 -# define RSA_padding_check_PKCS1_OAEP_mgf1 RSA_pad_check_PKCS1_OAEP_mgf1 - -/* Hack some ENGINE long names */ -# undef ENGINE_get_default_BN_mod_exp_crt -# define ENGINE_get_default_BN_mod_exp_crt ENGINE_get_def_BN_mod_exp_crt -# undef ENGINE_set_default_BN_mod_exp_crt -# define ENGINE_set_default_BN_mod_exp_crt ENGINE_set_def_BN_mod_exp_crt -# undef ENGINE_set_load_privkey_function -# define ENGINE_set_load_privkey_function ENGINE_set_load_privkey_fn -# undef ENGINE_get_load_privkey_function -# define ENGINE_get_load_privkey_function ENGINE_get_load_privkey_fn -# undef ENGINE_unregister_pkey_asn1_meths -# define ENGINE_unregister_pkey_asn1_meths ENGINE_unreg_pkey_asn1_meths -# undef ENGINE_register_all_pkey_asn1_meths -# define ENGINE_register_all_pkey_asn1_meths ENGINE_reg_all_pkey_asn1_meths -# undef ENGINE_set_default_pkey_asn1_meths -# define ENGINE_set_default_pkey_asn1_meths ENGINE_set_def_pkey_asn1_meths -# undef ENGINE_get_pkey_asn1_meth_engine -# define ENGINE_get_pkey_asn1_meth_engine ENGINE_get_pkey_asn1_meth_eng -# undef ENGINE_set_load_ssl_client_cert_function -# define ENGINE_set_load_ssl_client_cert_function \ - ENGINE_set_ld_ssl_clnt_cert_fn -# undef ENGINE_get_ssl_client_cert_function -# define ENGINE_get_ssl_client_cert_function ENGINE_get_ssl_client_cert_fn - -/* Hack some long OCSP names */ -# undef OCSP_REQUEST_get_ext_by_critical -# define OCSP_REQUEST_get_ext_by_critical OCSP_REQUEST_get_ext_by_crit -# undef OCSP_BASICRESP_get_ext_by_critical -# define OCSP_BASICRESP_get_ext_by_critical OCSP_BASICRESP_get_ext_by_crit -# undef OCSP_SINGLERESP_get_ext_by_critical -# define OCSP_SINGLERESP_get_ext_by_critical OCSP_SINGLERESP_get_ext_by_crit - -/* Hack some long DES names */ -# undef _ossl_old_des_ede3_cfb64_encrypt -# define _ossl_old_des_ede3_cfb64_encrypt _ossl_odes_ede3_cfb64_encrypt -# undef _ossl_old_des_ede3_ofb64_encrypt -# define _ossl_old_des_ede3_ofb64_encrypt _ossl_odes_ede3_ofb64_encrypt - -/* Hack some long EVP names */ -# undef OPENSSL_add_all_algorithms_noconf -# define OPENSSL_add_all_algorithms_noconf OPENSSL_add_all_algo_noconf -# undef OPENSSL_add_all_algorithms_conf -# define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algo_conf -# undef EVP_PKEY_meth_set_verify_recover -# define EVP_PKEY_meth_set_verify_recover EVP_PKEY_meth_set_vrfy_recover -# undef EVP_PKEY_meth_get_verify_recover -# define EVP_PKEY_meth_get_verify_recover EVP_PKEY_meth_get_vrfy_recover - -/* Hack some long EC names */ -# undef EC_GROUP_set_point_conversion_form -# define EC_GROUP_set_point_conversion_form EC_GROUP_set_point_conv_form -# undef EC_GROUP_get_point_conversion_form -# define EC_GROUP_get_point_conversion_form EC_GROUP_get_point_conv_form -# undef EC_GROUP_clear_free_all_extra_data -# define EC_GROUP_clear_free_all_extra_data EC_GROUP_clr_free_all_xtra_data -# undef EC_KEY_set_public_key_affine_coordinates -# define EC_KEY_set_public_key_affine_coordinates \ - EC_KEY_set_pub_key_aff_coords -# undef EC_POINT_set_Jprojective_coordinates_GFp -# define EC_POINT_set_Jprojective_coordinates_GFp \ - EC_POINT_set_Jproj_coords_GFp -# undef EC_POINT_get_Jprojective_coordinates_GFp -# define EC_POINT_get_Jprojective_coordinates_GFp \ - EC_POINT_get_Jproj_coords_GFp -# undef EC_POINT_set_affine_coordinates_GFp -# define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coords_GFp -# undef EC_POINT_get_affine_coordinates_GFp -# define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coords_GFp -# undef EC_POINT_set_compressed_coordinates_GFp -# define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp -# undef EC_POINT_set_affine_coordinates_GF2m -# define EC_POINT_set_affine_coordinates_GF2m EC_POINT_set_affine_coords_GF2m -# undef EC_POINT_get_affine_coordinates_GF2m -# define EC_POINT_get_affine_coordinates_GF2m EC_POINT_get_affine_coords_GF2m -# undef EC_POINT_set_compressed_coordinates_GF2m -# define EC_POINT_set_compressed_coordinates_GF2m \ - EC_POINT_set_compr_coords_GF2m -# undef ec_GF2m_simple_group_clear_finish -# define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish -# undef ec_GF2m_simple_group_check_discriminant -# define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim -# undef ec_GF2m_simple_point_clear_finish -# define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish -# undef ec_GF2m_simple_point_set_to_infinity -# define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf -# undef ec_GF2m_simple_points_make_affine -# define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine -# undef ec_GF2m_simple_point_set_affine_coordinates -# define ec_GF2m_simple_point_set_affine_coordinates \ - ec_GF2m_smp_pt_set_af_coords -# undef ec_GF2m_simple_point_get_affine_coordinates -# define ec_GF2m_simple_point_get_affine_coordinates \ - ec_GF2m_smp_pt_get_af_coords -# undef ec_GF2m_simple_set_compressed_coordinates -# define ec_GF2m_simple_set_compressed_coordinates \ - ec_GF2m_smp_set_compr_coords -# undef ec_GFp_simple_group_set_curve_GFp -# define ec_GFp_simple_group_set_curve_GFp ec_GFp_simple_grp_set_curve_GFp -# undef ec_GFp_simple_group_get_curve_GFp -# define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp -# undef ec_GFp_simple_group_clear_finish -# define ec_GFp_simple_group_clear_finish ec_GFp_simple_grp_clear_finish -# undef ec_GFp_simple_group_set_generator -# define ec_GFp_simple_group_set_generator ec_GFp_simple_grp_set_generator -# undef ec_GFp_simple_group_get0_generator -# define ec_GFp_simple_group_get0_generator ec_GFp_simple_grp_gt0_generator -# undef ec_GFp_simple_group_get_cofactor -# define ec_GFp_simple_group_get_cofactor ec_GFp_simple_grp_get_cofactor -# undef ec_GFp_simple_point_clear_finish -# define ec_GFp_simple_point_clear_finish ec_GFp_simple_pt_clear_finish -# undef ec_GFp_simple_point_set_to_infinity -# define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf -# undef ec_GFp_simple_points_make_affine -# define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine -# undef ec_GFp_simple_set_Jprojective_coordinates_GFp -# define ec_GFp_simple_set_Jprojective_coordinates_GFp \ - ec_GFp_smp_set_Jproj_coords_GFp -# undef ec_GFp_simple_get_Jprojective_coordinates_GFp -# define ec_GFp_simple_get_Jprojective_coordinates_GFp \ - ec_GFp_smp_get_Jproj_coords_GFp -# undef ec_GFp_simple_point_set_affine_coordinates_GFp -# define ec_GFp_simple_point_set_affine_coordinates_GFp \ - ec_GFp_smp_pt_set_af_coords_GFp -# undef ec_GFp_simple_point_get_affine_coordinates_GFp -# define ec_GFp_simple_point_get_affine_coordinates_GFp \ - ec_GFp_smp_pt_get_af_coords_GFp -# undef ec_GFp_simple_set_compressed_coordinates_GFp -# define ec_GFp_simple_set_compressed_coordinates_GFp \ - ec_GFp_smp_set_compr_coords_GFp -# undef ec_GFp_simple_point_set_affine_coordinates -# define ec_GFp_simple_point_set_affine_coordinates \ - ec_GFp_smp_pt_set_af_coords -# undef ec_GFp_simple_point_get_affine_coordinates -# define ec_GFp_simple_point_get_affine_coordinates \ - ec_GFp_smp_pt_get_af_coords -# undef ec_GFp_simple_set_compressed_coordinates -# define ec_GFp_simple_set_compressed_coordinates \ - ec_GFp_smp_set_compr_coords -# undef ec_GFp_simple_group_check_discriminant -# define ec_GFp_simple_group_check_discriminant ec_GFp_simple_grp_chk_discrim - -/* Hack som long STORE names */ -# undef STORE_method_set_initialise_function -# define STORE_method_set_initialise_function STORE_meth_set_initialise_fn -# undef STORE_method_set_cleanup_function -# define STORE_method_set_cleanup_function STORE_meth_set_cleanup_fn -# undef STORE_method_set_generate_function -# define STORE_method_set_generate_function STORE_meth_set_generate_fn -# undef STORE_method_set_modify_function -# define STORE_method_set_modify_function STORE_meth_set_modify_fn -# undef STORE_method_set_revoke_function -# define STORE_method_set_revoke_function STORE_meth_set_revoke_fn -# undef STORE_method_set_delete_function -# define STORE_method_set_delete_function STORE_meth_set_delete_fn -# undef STORE_method_set_list_start_function -# define STORE_method_set_list_start_function STORE_meth_set_list_start_fn -# undef STORE_method_set_list_next_function -# define STORE_method_set_list_next_function STORE_meth_set_list_next_fn -# undef STORE_method_set_list_end_function -# define STORE_method_set_list_end_function STORE_meth_set_list_end_fn -# undef STORE_method_set_update_store_function -# define STORE_method_set_update_store_function STORE_meth_set_update_store_fn -# undef STORE_method_set_lock_store_function -# define STORE_method_set_lock_store_function STORE_meth_set_lock_store_fn -# undef STORE_method_set_unlock_store_function -# define STORE_method_set_unlock_store_function STORE_meth_set_unlock_store_fn -# undef STORE_method_get_initialise_function -# define STORE_method_get_initialise_function STORE_meth_get_initialise_fn -# undef STORE_method_get_cleanup_function -# define STORE_method_get_cleanup_function STORE_meth_get_cleanup_fn -# undef STORE_method_get_generate_function -# define STORE_method_get_generate_function STORE_meth_get_generate_fn -# undef STORE_method_get_modify_function -# define STORE_method_get_modify_function STORE_meth_get_modify_fn -# undef STORE_method_get_revoke_function -# define STORE_method_get_revoke_function STORE_meth_get_revoke_fn -# undef STORE_method_get_delete_function -# define STORE_method_get_delete_function STORE_meth_get_delete_fn -# undef STORE_method_get_list_start_function -# define STORE_method_get_list_start_function STORE_meth_get_list_start_fn -# undef STORE_method_get_list_next_function -# define STORE_method_get_list_next_function STORE_meth_get_list_next_fn -# undef STORE_method_get_list_end_function -# define STORE_method_get_list_end_function STORE_meth_get_list_end_fn -# undef STORE_method_get_update_store_function -# define STORE_method_get_update_store_function STORE_meth_get_update_store_fn -# undef STORE_method_get_lock_store_function -# define STORE_method_get_lock_store_function STORE_meth_get_lock_store_fn -# undef STORE_method_get_unlock_store_function -# define STORE_method_get_unlock_store_function STORE_meth_get_unlock_store_fn - -/* Hack some long TS names */ -# undef TS_RESP_CTX_set_status_info_cond -# define TS_RESP_CTX_set_status_info_cond TS_RESP_CTX_set_stat_info_cond -# undef TS_RESP_CTX_set_clock_precision_digits -# define TS_RESP_CTX_set_clock_precision_digits TS_RESP_CTX_set_clk_prec_digits -# undef TS_CONF_set_clock_precision_digits -# define TS_CONF_set_clock_precision_digits TS_CONF_set_clk_prec_digits - -/* Hack some long CMS names */ -# undef CMS_RecipientInfo_ktri_get0_algs -# define CMS_RecipientInfo_ktri_get0_algs CMS_RecipInfo_ktri_get0_algs -# undef CMS_RecipientInfo_ktri_get0_signer_id -# define CMS_RecipientInfo_ktri_get0_signer_id CMS_RecipInfo_ktri_get0_sigr_id -# undef CMS_OtherRevocationInfoFormat_it -# define CMS_OtherRevocationInfoFormat_it CMS_OtherRevocInfoFormat_it -# undef CMS_KeyAgreeRecipientIdentifier_it -# define CMS_KeyAgreeRecipientIdentifier_it CMS_KeyAgreeRecipIdentifier_it -# undef CMS_OriginatorIdentifierOrKey_it -# define CMS_OriginatorIdentifierOrKey_it CMS_OriginatorIdOrKey_it -# undef cms_SignerIdentifier_get0_signer_id -# define cms_SignerIdentifier_get0_signer_id cms_SignerId_get0_signer_id -# undef CMS_RecipientInfo_kari_get0_orig_id -# define CMS_RecipientInfo_kari_get0_orig_id CMS_RecipInfo_kari_get0_orig_id -# undef CMS_RecipientInfo_kari_get0_reks -# define CMS_RecipientInfo_kari_get0_reks CMS_RecipInfo_kari_get0_reks -# undef CMS_RecipientEncryptedKey_cert_cmp -# define CMS_RecipientEncryptedKey_cert_cmp CMS_RecipEncryptedKey_cert_cmp -# undef CMS_RecipientInfo_kari_set0_pkey -# define CMS_RecipientInfo_kari_set0_pkey CMS_RecipInfo_kari_set0_pkey -# undef CMS_RecipientEncryptedKey_get0_id -# define CMS_RecipientEncryptedKey_get0_id CMS_RecipEncryptedKey_get0_id -# undef CMS_RecipientInfo_kari_orig_id_cmp -# define CMS_RecipientInfo_kari_orig_id_cmp CMS_RecipInfo_kari_orig_id_cmp - -/* Hack some long DTLS1 names */ -# undef dtls1_retransmit_buffered_messages -# define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs - -/* Hack some long SRP names */ -# undef SRP_generate_server_master_secret -# define SRP_generate_server_master_secret SRP_gen_server_master_secret -# undef SRP_generate_client_master_secret -# define SRP_generate_client_master_secret SRP_gen_client_master_secret - -/* Hack some long UI names */ -# undef UI_method_get_prompt_constructor -# define UI_method_get_prompt_constructor UI_method_get_prompt_constructr -# undef UI_method_set_prompt_constructor -# define UI_method_set_prompt_constructor UI_method_set_prompt_constructr - -# endif /* defined OPENSSL_SYS_VMS */ - -/* Case insensitive linking causes problems.... */ -# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) -# undef ERR_load_CRYPTO_strings -# define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings -# undef OCSP_crlID_new -# define OCSP_crlID_new OCSP_crlID2_new - -# undef d2i_ECPARAMETERS -# define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS -# undef i2d_ECPARAMETERS -# define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS -# undef d2i_ECPKPARAMETERS -# define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS -# undef i2d_ECPKPARAMETERS -# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS - -/* - * These functions do not seem to exist! However, I'm paranoid... Original - * command in x509v3.h: These functions are being redefined in another - * directory, and clash when the linker is case-insensitive, so let's hide - * them a little, by giving them an extra 'o' at the beginning of the name... - */ -# undef X509v3_cleanup_extensions -# define X509v3_cleanup_extensions oX509v3_cleanup_extensions -# undef X509v3_add_extension -# define X509v3_add_extension oX509v3_add_extension -# undef X509v3_add_netscape_extensions -# define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions -# undef X509v3_add_standard_extensions -# define X509v3_add_standard_extensions oX509v3_add_standard_extensions - -/* This one clashes with CMS_data_create */ -# undef cms_Data_create -# define cms_Data_create priv_cms_Data_create - -# endif - -#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/Sources/COpenSSL/t1_.c b/Sources/COpenSSL/t1_.c deleted file mode 100644 index 83e7e297..00000000 --- a/Sources/COpenSSL/t1_.c +++ /dev/null @@ -1,8111 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ssl/t1_clnt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "ssl_locl.h" -#include "buffer.h" -#include "rand.h" -#include "objects.h" -#include "evp.h" - -static const SSL_METHOD *tls1_get_client_method(int ver); -static const SSL_METHOD *tls1_get_client_method(int ver) -{ - if (ver == TLS1_2_VERSION) - return TLSv1_2_client_method(); - if (ver == TLS1_1_VERSION) - return TLSv1_1_client_method(); - if (ver == TLS1_VERSION) - return TLSv1_client_method(); - return NULL; -} - -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method, - ssl_undefined_function, - ssl3_connect, - tls1_get_client_method, TLSv1_2_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method, - ssl_undefined_function, - ssl3_connect, - tls1_get_client_method, TLSv1_1_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method, - ssl_undefined_function, - ssl3_connect, tls1_get_client_method, TLSv1_enc_data) -/* ssl/t1_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#include -// #include "ssl_locl.h" -#ifndef OPENSSL_NO_COMP -# include "comp.h" -#endif -// #include "evp.h" -#include "hmac.h" -#include "md5.h" -// #include "rand.h" -#ifdef KSSL_DEBUG -# include "des.h" -#endif - -/* seed1 through seed5 are virtually concatenated */ -static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, - int sec_len, - const void *seed1, int seed1_len, - const void *seed2, int seed2_len, - const void *seed3, int seed3_len, - const void *seed4, int seed4_len, - const void *seed5, int seed5_len, - unsigned char *out, int olen) -{ - int chunk; - size_t j; - EVP_MD_CTX ctx, ctx_tmp, ctx_init; - EVP_PKEY *mac_key; - unsigned char A1[EVP_MAX_MD_SIZE]; - size_t A1_len; - int ret = 0; - - chunk = EVP_MD_size(md); - OPENSSL_assert(chunk >= 0); - - EVP_MD_CTX_init(&ctx); - EVP_MD_CTX_init(&ctx_tmp); - EVP_MD_CTX_init(&ctx_init); - EVP_MD_CTX_set_flags(&ctx_init, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); - if (!mac_key) - goto err; - if (!EVP_DigestSignInit(&ctx_init, NULL, md, NULL, mac_key)) - goto err; - if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) - goto err; - if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) - goto err; - if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) - goto err; - if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) - goto err; - if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) - goto err; - if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) - goto err; - if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) - goto err; - - for (;;) { - /* Reinit mac contexts */ - if (!EVP_MD_CTX_copy_ex(&ctx, &ctx_init)) - goto err; - if (!EVP_DigestSignUpdate(&ctx, A1, A1_len)) - goto err; - if (olen > chunk && !EVP_MD_CTX_copy_ex(&ctx_tmp, &ctx)) - goto err; - if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) - goto err; - if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) - goto err; - if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) - goto err; - if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) - goto err; - if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) - goto err; - - if (olen > chunk) { - if (!EVP_DigestSignFinal(&ctx, out, &j)) - goto err; - out += j; - olen -= j; - /* calc the next A1 value */ - if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) - goto err; - } else { /* last one */ - - if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) - goto err; - memcpy(out, A1, olen); - break; - } - } - ret = 1; - err: - EVP_PKEY_free(mac_key); - EVP_MD_CTX_cleanup(&ctx); - EVP_MD_CTX_cleanup(&ctx_tmp); - EVP_MD_CTX_cleanup(&ctx_init); - OPENSSL_cleanse(A1, sizeof(A1)); - return ret; -} - -/* seed1 through seed5 are virtually concatenated */ -static int tls1_PRF(long digest_mask, - const void *seed1, int seed1_len, - const void *seed2, int seed2_len, - const void *seed3, int seed3_len, - const void *seed4, int seed4_len, - const void *seed5, int seed5_len, - const unsigned char *sec, int slen, - unsigned char *out1, unsigned char *out2, int olen) -{ - int len, i, idx, count; - const unsigned char *S1; - long m; - const EVP_MD *md; - int ret = 0; - - /* Count number of digests and partition sec evenly */ - count = 0; - for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { - if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) - count++; - } - if (!count) { - /* Should never happen */ - SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); - goto err; - } - len = slen / count; - if (count == 1) - slen = 0; - S1 = sec; - memset(out1, 0, olen); - for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { - if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) { - if (!md) { - SSLerr(SSL_F_TLS1_PRF, SSL_R_UNSUPPORTED_DIGEST_TYPE); - goto err; - } - if (!tls1_P_hash(md, S1, len + (slen & 1), - seed1, seed1_len, seed2, seed2_len, seed3, - seed3_len, seed4, seed4_len, seed5, seed5_len, - out2, olen)) - goto err; - S1 += len; - for (i = 0; i < olen; i++) { - out1[i] ^= out2[i]; - } - } - } - ret = 1; - err: - return ret; -} - -static int tls1_generate_key_block(SSL *s, unsigned char *km, - unsigned char *tmp, int num) -{ - int ret; - ret = tls1_PRF(ssl_get_algorithm2(s), - TLS_MD_KEY_EXPANSION_CONST, - TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random, - SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, - NULL, 0, NULL, 0, s->session->master_key, - s->session->master_key_length, km, tmp, num); -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_generate_key_block() ==> %d byte master_key =\n\t", - s->session->master_key_length); - { - int i; - for (i = 0; i < s->session->master_key_length; i++) { - fprintf(stderr, "%02X", s->session->master_key[i]); - } - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - return ret; -} - -int tls1_change_cipher_state(SSL *s, int which) -{ - static const unsigned char empty[] = ""; - unsigned char *p, *mac_secret; - unsigned char *exp_label; - unsigned char tmp1[EVP_MAX_KEY_LENGTH]; - unsigned char tmp2[EVP_MAX_KEY_LENGTH]; - unsigned char iv1[EVP_MAX_IV_LENGTH * 2]; - unsigned char iv2[EVP_MAX_IV_LENGTH * 2]; - unsigned char *ms, *key, *iv; - int client_write; - EVP_CIPHER_CTX *dd; - const EVP_CIPHER *c; -#ifndef OPENSSL_NO_COMP - const SSL_COMP *comp; -#endif - const EVP_MD *m; - int mac_type; - int *mac_secret_size; - EVP_MD_CTX *mac_ctx; - EVP_PKEY *mac_key; - int is_export, n, i, j, k, exp_label_len, cl; - int reuse_dd = 0; - - is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); - c = s->s3->tmp.new_sym_enc; - m = s->s3->tmp.new_hash; - mac_type = s->s3->tmp.new_mac_pkey_type; -#ifndef OPENSSL_NO_COMP - comp = s->s3->tmp.new_compression; -#endif - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_change_cipher_state(which= %d) w/\n", which); - fprintf(stderr, "\talg= %ld/%ld, comp= %p\n", - s->s3->tmp.new_cipher->algorithm_mkey, - s->s3->tmp.new_cipher->algorithm_auth, comp); - fprintf(stderr, "\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); - fprintf(stderr, "\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", - c->nid, c->block_size, c->key_len, c->iv_len); - fprintf(stderr, "\tkey_block: len= %d, data= ", - s->s3->tmp.key_block_length); - { - int i; - for (i = 0; i < s->s3->tmp.key_block_length; i++) - fprintf(stderr, "%02x", s->s3->tmp.key_block[i]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - - if (which & SSL3_CC_READ) { - if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) - s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; - else - s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; - - if (s->enc_read_ctx != NULL) - reuse_dd = 1; - else if ((s->enc_read_ctx = - OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) - goto err; - else - /* - * make sure it's intialized in case we exit later with an error - */ - EVP_CIPHER_CTX_init(s->enc_read_ctx); - dd = s->enc_read_ctx; - mac_ctx = ssl_replace_hash(&s->read_hash, NULL); - if (mac_ctx == NULL) - goto err; -#ifndef OPENSSL_NO_COMP - if (s->expand != NULL) { - COMP_CTX_free(s->expand); - s->expand = NULL; - } - if (comp != NULL) { - s->expand = COMP_CTX_new(comp->method); - if (s->expand == NULL) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err2; - } - if (s->s3->rrec.comp == NULL) - s->s3->rrec.comp = (unsigned char *) - OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); - if (s->s3->rrec.comp == NULL) - goto err; - } -#endif - /* - * this is done by dtls1_reset_seq_numbers for DTLS - */ - if (!SSL_IS_DTLS(s)) - memset(&(s->s3->read_sequence[0]), 0, 8); - mac_secret = &(s->s3->read_mac_secret[0]); - mac_secret_size = &(s->s3->read_mac_secret_size); - } else { - if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) - s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; - else - s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; - if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) - reuse_dd = 1; - else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) - goto err; - dd = s->enc_write_ctx; - if (SSL_IS_DTLS(s)) { - mac_ctx = EVP_MD_CTX_create(); - if (mac_ctx == NULL) - goto err; - s->write_hash = mac_ctx; - } else { - mac_ctx = ssl_replace_hash(&s->write_hash, NULL); - if (mac_ctx == NULL) - goto err; - } -#ifndef OPENSSL_NO_COMP - if (s->compress != NULL) { - COMP_CTX_free(s->compress); - s->compress = NULL; - } - if (comp != NULL) { - s->compress = COMP_CTX_new(comp->method); - if (s->compress == NULL) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, - SSL_R_COMPRESSION_LIBRARY_ERROR); - goto err2; - } - } -#endif - /* - * this is done by dtls1_reset_seq_numbers for DTLS - */ - if (!SSL_IS_DTLS(s)) - memset(&(s->s3->write_sequence[0]), 0, 8); - mac_secret = &(s->s3->write_mac_secret[0]); - mac_secret_size = &(s->s3->write_mac_secret_size); - } - - if (reuse_dd) - EVP_CIPHER_CTX_cleanup(dd); - - p = s->s3->tmp.key_block; - i = *mac_secret_size = s->s3->tmp.new_mac_secret_size; - - cl = EVP_CIPHER_key_length(c); - j = is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? - cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; - /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ - /* If GCM mode only part of IV comes from PRF */ - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) - k = EVP_GCM_TLS_FIXED_IV_LEN; - else - k = EVP_CIPHER_iv_length(c); - if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || - (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { - ms = &(p[0]); - n = i + i; - key = &(p[n]); - n += j + j; - iv = &(p[n]); - n += k + k; - exp_label = (unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; - exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; - client_write = 1; - } else { - n = i; - ms = &(p[n]); - n += i + j; - key = &(p[n]); - n += j + k; - iv = &(p[n]); - n += k; - exp_label = (unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; - exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; - client_write = 0; - } - - if (n > s->s3->tmp.key_block_length) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - - memcpy(mac_secret, ms, i); - - if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { - mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, - mac_secret, *mac_secret_size); - if (mac_key == NULL - || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) { - EVP_PKEY_free(mac_key); - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - EVP_PKEY_free(mac_key); - } -#ifdef TLS_DEBUG - printf("which = %04X\nmac key=", which); - { - int z; - for (z = 0; z < i; z++) - printf("%02X%c", ms[z], ((z + 1) % 16) ? ' ' : '\n'); - } -#endif - if (is_export) { - /* - * In here I set both the read and write key/iv to the same value - * since only the correct one will be used :-). - */ - if (!tls1_PRF(ssl_get_algorithm2(s), - exp_label, exp_label_len, - s->s3->client_random, SSL3_RANDOM_SIZE, - s->s3->server_random, SSL3_RANDOM_SIZE, - NULL, 0, NULL, 0, - key, j, tmp1, tmp2, EVP_CIPHER_key_length(c))) - goto err2; - key = tmp1; - - if (k > 0) { - if (!tls1_PRF(ssl_get_algorithm2(s), - TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, - s->s3->client_random, SSL3_RANDOM_SIZE, - s->s3->server_random, SSL3_RANDOM_SIZE, - NULL, 0, NULL, 0, empty, 0, iv1, iv2, k * 2)) - goto err2; - if (client_write) - iv = iv1; - else - iv = &(iv1[k]); - } - } - - s->session->key_arg_length = 0; -#ifdef KSSL_DEBUG - { - int i; - fprintf(stderr, "EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); - fprintf(stderr, "\tkey= "); - for (i = 0; i < c->key_len; i++) - fprintf(stderr, "%02x", key[i]); - fprintf(stderr, "\n"); - fprintf(stderr, "\t iv= "); - for (i = 0; i < c->iv_len; i++) - fprintf(stderr, "%02x", iv[i]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { - if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE)) - || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv)) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - } else { - if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } - } - /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ - if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size - && !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY, - *mac_secret_size, mac_secret)) { - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); - goto err2; - } -#ifdef OPENSSL_SSL_TRACE_CRYPTO - if (s->msg_callback) { - int wh = which & SSL3_CC_WRITE ? TLS1_RT_CRYPTO_WRITE : 0; - if (*mac_secret_size) - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_MAC, - mac_secret, *mac_secret_size, - s, s->msg_callback_arg); - if (c->key_len) - s->msg_callback(2, s->version, wh | TLS1_RT_CRYPTO_KEY, - key, c->key_len, s, s->msg_callback_arg); - if (k) { - if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) - wh |= TLS1_RT_CRYPTO_FIXED_IV; - else - wh |= TLS1_RT_CRYPTO_IV; - s->msg_callback(2, s->version, wh, iv, k, s, s->msg_callback_arg); - } - } -#endif - -#ifdef TLS_DEBUG - printf("which = %04X\nkey=", which); - { - int z; - for (z = 0; z < EVP_CIPHER_key_length(c); z++) - printf("%02X%c", key[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\niv="); - { - int z; - for (z = 0; z < k; z++) - printf("%02X%c", iv[z], ((z + 1) % 16) ? ' ' : '\n'); - } - printf("\n"); -#endif - - OPENSSL_cleanse(tmp1, sizeof(tmp1)); - OPENSSL_cleanse(tmp2, sizeof(tmp1)); - OPENSSL_cleanse(iv1, sizeof(iv1)); - OPENSSL_cleanse(iv2, sizeof(iv2)); - return (1); - err: - SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); - err2: - return (0); -} - -int tls1_setup_key_block(SSL *s) -{ - unsigned char *p1, *p2 = NULL; - const EVP_CIPHER *c; - const EVP_MD *hash; - int num; - SSL_COMP *comp; - int mac_type = NID_undef, mac_secret_size = 0; - int ret = 0; - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_setup_key_block()\n"); -#endif /* KSSL_DEBUG */ - - if (s->s3->tmp.key_block_length != 0) - return (1); - - if (!ssl_cipher_get_evp - (s->session, &c, &hash, &mac_type, &mac_secret_size, &comp)) { - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); - return (0); - } - - s->s3->tmp.new_sym_enc = c; - s->s3->tmp.new_hash = hash; - s->s3->tmp.new_mac_pkey_type = mac_type; - s->s3->tmp.new_mac_secret_size = mac_secret_size; - num = - EVP_CIPHER_key_length(c) + mac_secret_size + EVP_CIPHER_iv_length(c); - num *= 2; - - ssl3_cleanup_key_block(s); - - if ((p1 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - goto err; - } - - s->s3->tmp.key_block_length = num; - s->s3->tmp.key_block = p1; - - if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { - SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - goto err; - } -#ifdef TLS_DEBUG - printf("client random\n"); - { - int z; - for (z = 0; z < SSL3_RANDOM_SIZE; z++) - printf("%02X%c", s->s3->client_random[z], - ((z + 1) % 16) ? ' ' : '\n'); - } - printf("server random\n"); - { - int z; - for (z = 0; z < SSL3_RANDOM_SIZE; z++) - printf("%02X%c", s->s3->server_random[z], - ((z + 1) % 16) ? ' ' : '\n'); - } - printf("pre-master\n"); - { - int z; - for (z = 0; z < s->session->master_key_length; z++) - printf("%02X%c", s->session->master_key[z], - ((z + 1) % 16) ? ' ' : '\n'); - } -#endif - if (!tls1_generate_key_block(s, p1, p2, num)) - goto err; -#ifdef TLS_DEBUG - printf("\nkey block\n"); - { - int z; - for (z = 0; z < num; z++) - printf("%02X%c", p1[z], ((z + 1) % 16) ? ' ' : '\n'); - } -#endif - - if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) - && s->method->version <= TLS1_VERSION) { - /* - * enable vulnerability countermeasure for CBC ciphers with known-IV - * problem (http://www.openssl.org/~bodo/tls-cbc.txt) - */ - s->s3->need_empty_fragments = 1; - - if (s->session->cipher != NULL) { - if (s->session->cipher->algorithm_enc == SSL_eNULL) - s->s3->need_empty_fragments = 0; - -#ifndef OPENSSL_NO_RC4 - if (s->session->cipher->algorithm_enc == SSL_RC4) - s->s3->need_empty_fragments = 0; -#endif - } - } - - ret = 1; - err: - if (p2) { - OPENSSL_cleanse(p2, num); - OPENSSL_free(p2); - } - return (ret); -} - -/*- - * tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. - * - * Returns: - * 0: (in non-constant time) if the record is publically invalid (i.e. too - * short etc). - * 1: if the record's padding is valid / the encryption was successful. - * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, - * an internal error occured. - */ -int tls1_enc(SSL *s, int send) -{ - SSL3_RECORD *rec; - EVP_CIPHER_CTX *ds; - unsigned long l; - int bs, i, j, k, pad = 0, ret, mac_size = 0; - const EVP_CIPHER *enc; - - if (send) { - if (EVP_MD_CTX_md(s->write_hash)) { - int n = EVP_MD_CTX_size(s->write_hash); - OPENSSL_assert(n >= 0); - } - ds = s->enc_write_ctx; - rec = &(s->s3->wrec); - if (s->enc_write_ctx == NULL) - enc = NULL; - else { - int ivlen; - enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); - /* For TLSv1.1 and later explicit IV */ - if (SSL_USE_EXPLICIT_IV(s) - && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) - ivlen = EVP_CIPHER_iv_length(enc); - else - ivlen = 0; - if (ivlen > 1) { - if (rec->data != rec->input) - /* - * we can't write into the input stream: Can this ever - * happen?? (steve) - */ - fprintf(stderr, - "%s:%d: rec->data != rec->input\n", - __FILE__, __LINE__); - else if (RAND_bytes(rec->input, ivlen) <= 0) - return -1; - } - } - } else { - if (EVP_MD_CTX_md(s->read_hash)) { - int n = EVP_MD_CTX_size(s->read_hash); - OPENSSL_assert(n >= 0); - } - ds = s->enc_read_ctx; - rec = &(s->s3->rrec); - if (s->enc_read_ctx == NULL) - enc = NULL; - else - enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); - } - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_enc(%d)\n", send); -#endif /* KSSL_DEBUG */ - - if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { - memmove(rec->data, rec->input, rec->length); - rec->input = rec->data; - ret = 1; - } else { - l = rec->length; - bs = EVP_CIPHER_block_size(ds->cipher); - - if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { - unsigned char buf[EVP_AEAD_TLS1_AAD_LEN], *seq; - - seq = send ? s->s3->write_sequence : s->s3->read_sequence; - - if (SSL_IS_DTLS(s)) { - unsigned char dtlsseq[9], *p = dtlsseq; - - s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p); - memcpy(p, &seq[2], 6); - memcpy(buf, dtlsseq, 8); - } else { - memcpy(buf, seq, 8); - for (i = 7; i >= 0; i--) { /* increment */ - ++seq[i]; - if (seq[i] != 0) - break; - } - } - - buf[8] = rec->type; - buf[9] = (unsigned char)(s->version >> 8); - buf[10] = (unsigned char)(s->version); - buf[11] = rec->length >> 8; - buf[12] = rec->length & 0xff; - pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, - EVP_AEAD_TLS1_AAD_LEN, buf); - if (pad <= 0) - return -1; - if (send) { - l += pad; - rec->length += pad; - } - } else if ((bs != 1) && send) { - i = bs - ((int)l % bs); - - /* Add weird padding of upto 256 bytes */ - - /* we need to add 'i' padding bytes of value j */ - j = i - 1; - if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { - if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) - j++; - } - for (k = (int)l; k < (int)(l + i); k++) - rec->input[k] = j; - l += i; - rec->length += i; - } -#ifdef KSSL_DEBUG - { - unsigned long ui; - fprintf(stderr, - "EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", - ds, rec->data, rec->input, l); - fprintf(stderr, - "\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n", - ds->buf_len, ds->cipher->key_len, DES_KEY_SZ, - DES_SCHEDULE_SZ, ds->cipher->iv_len); - fprintf(stderr, "\t\tIV: "); - for (i = 0; i < ds->cipher->iv_len; i++) - fprintf(stderr, "%02X", ds->iv[i]); - fprintf(stderr, "\n"); - fprintf(stderr, "\trec->input="); - for (ui = 0; ui < l; ui++) - fprintf(stderr, " %02x", rec->input[ui]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - - if (!send) { - if (l == 0 || l % bs != 0) - return 0; - } - - i = EVP_Cipher(ds, rec->data, rec->input, l); - if ((EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_CUSTOM_CIPHER) - ? (i < 0) - : (i == 0)) - return -1; /* AEAD can fail to verify MAC */ - if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send) { - rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; - rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; - } -#ifdef KSSL_DEBUG - { - unsigned long i; - fprintf(stderr, "\trec->data="); - for (i = 0; i < l; i++) - fprintf(stderr, " %02x", rec->data[i]); - fprintf(stderr, "\n"); - } -#endif /* KSSL_DEBUG */ - - ret = 1; - if (EVP_MD_CTX_md(s->read_hash) != NULL) - mac_size = EVP_MD_CTX_size(s->read_hash); - if ((bs != 1) && !send) - ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); - if (pad && !send) - rec->length -= pad; - } - return ret; -} - -int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) -{ - unsigned int ret; - EVP_MD_CTX ctx, *d = NULL; - int i; - - if (s->s3->handshake_buffer) - if (!ssl3_digest_cached_records(s)) - return 0; - - for (i = 0; i < SSL_MAX_DIGEST; i++) { - if (s->s3->handshake_dgst[i] - && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { - d = s->s3->handshake_dgst[i]; - break; - } - } - if (!d) { - SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC, SSL_R_NO_REQUIRED_DIGEST); - return 0; - } - - EVP_MD_CTX_init(&ctx); - if (EVP_MD_CTX_copy_ex(&ctx, d) <=0 - || EVP_DigestFinal_ex(&ctx, out, &ret) <= 0) - ret = 0; - EVP_MD_CTX_cleanup(&ctx); - return ((int)ret); -} - -int tls1_final_finish_mac(SSL *s, - const char *str, int slen, unsigned char *out) -{ - unsigned int i; - EVP_MD_CTX ctx; - unsigned char buf[2 * EVP_MAX_MD_SIZE]; - unsigned char *q, buf2[12]; - int idx; - long mask; - int err = 0; - const EVP_MD *md; - - q = buf; - - if (s->s3->handshake_buffer) - if (!ssl3_digest_cached_records(s)) - return 0; - - EVP_MD_CTX_init(&ctx); - - for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) { - if (mask & ssl_get_algorithm2(s)) { - int hashsize = EVP_MD_size(md); - EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx]; - if (!hdgst || hashsize < 0 - || hashsize > (int)(sizeof(buf) - (size_t)(q - buf))) { - /* - * internal error: 'buf' is too small for this cipersuite! - */ - err = 1; - } else { - if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) || - !EVP_DigestFinal_ex(&ctx, q, &i) || - (i != (unsigned int)hashsize)) - err = 1; - q += hashsize; - } - } - } - - if (!tls1_PRF(ssl_get_algorithm2(s), - str, slen, buf, (int)(q - buf), NULL, 0, NULL, 0, NULL, 0, - s->session->master_key, s->session->master_key_length, - out, buf2, sizeof(buf2))) - err = 1; - EVP_MD_CTX_cleanup(&ctx); - - OPENSSL_cleanse(buf, (int)(q - buf)); - OPENSSL_cleanse(buf2, sizeof(buf2)); - if (err) - return 0; - else - return sizeof(buf2); -} - -int tls1_mac(SSL *ssl, unsigned char *md, int send) -{ - SSL3_RECORD *rec; - unsigned char *seq; - EVP_MD_CTX *hash; - size_t md_size, orig_len; - int i; - EVP_MD_CTX hmac, *mac_ctx; - unsigned char header[13]; - int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) - : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); - int t; - - if (send) { - rec = &(ssl->s3->wrec); - seq = &(ssl->s3->write_sequence[0]); - hash = ssl->write_hash; - } else { - rec = &(ssl->s3->rrec); - seq = &(ssl->s3->read_sequence[0]); - hash = ssl->read_hash; - } - - t = EVP_MD_CTX_size(hash); - OPENSSL_assert(t >= 0); - md_size = t; - - /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ - if (stream_mac) { - mac_ctx = hash; - } else { - if (!EVP_MD_CTX_copy(&hmac, hash)) - return -1; - mac_ctx = &hmac; - } - - if (SSL_IS_DTLS(ssl)) { - unsigned char dtlsseq[8], *p = dtlsseq; - - s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p); - memcpy(p, &seq[2], 6); - - memcpy(header, dtlsseq, 8); - } else - memcpy(header, seq, 8); - - /* - * kludge: tls1_cbc_remove_padding passes padding length in rec->type - */ - orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); - rec->type &= 0xff; - - header[8] = rec->type; - header[9] = (unsigned char)(ssl->version >> 8); - header[10] = (unsigned char)(ssl->version); - header[11] = (rec->length) >> 8; - header[12] = (rec->length) & 0xff; - - if (!send && - EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && - ssl3_cbc_record_digest_supported(mac_ctx)) { - /* - * This is a CBC-encrypted record. We must avoid leaking any - * timing-side channel information about how many blocks of data we - * are hashing because that gives an attacker a timing-oracle. - */ - /* Final param == not SSLv3 */ - if (ssl3_cbc_digest_record(mac_ctx, - md, &md_size, - header, rec->input, - rec->length + md_size, orig_len, - ssl->s3->read_mac_secret, - ssl->s3->read_mac_secret_size, 0) <= 0) { - if (!stream_mac) - EVP_MD_CTX_cleanup(&hmac); - return -1; - } - } else { - if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 - || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 - || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { - if (!stream_mac) - EVP_MD_CTX_cleanup(&hmac); - return -1; - } -#ifdef OPENSSL_FIPS - if (!send && FIPS_mode()) - tls_fips_digest_extra(ssl->enc_read_ctx, - mac_ctx, rec->input, rec->length, orig_len); -#endif - } - - if (!stream_mac) - EVP_MD_CTX_cleanup(&hmac); -#ifdef TLS_DEBUG - fprintf(stderr, "seq="); - { - int z; - for (z = 0; z < 8; z++) - fprintf(stderr, "%02X ", seq[z]); - fprintf(stderr, "\n"); - } - fprintf(stderr, "rec="); - { - unsigned int z; - for (z = 0; z < rec->length; z++) - fprintf(stderr, "%02X ", rec->data[z]); - fprintf(stderr, "\n"); - } -#endif - - if (!SSL_IS_DTLS(ssl)) { - for (i = 7; i >= 0; i--) { - ++seq[i]; - if (seq[i] != 0) - break; - } - } -#ifdef TLS_DEBUG - { - unsigned int z; - for (z = 0; z < md_size; z++) - fprintf(stderr, "%02X ", md[z]); - fprintf(stderr, "\n"); - } -#endif - return (md_size); -} - -int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, - int len) -{ - unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; - const void *co = NULL, *so = NULL; - int col = 0, sol = 0; - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_generate_master_secret(%p,%p, %p, %d)\n", s, out, p, - len); -#endif /* KSSL_DEBUG */ - -#ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL - && s->s3->server_opaque_prf_input != NULL - && s->s3->client_opaque_prf_input_len > 0 - && s->s3->client_opaque_prf_input_len == - s->s3->server_opaque_prf_input_len) { - co = s->s3->client_opaque_prf_input; - col = s->s3->server_opaque_prf_input_len; - so = s->s3->server_opaque_prf_input; - /* - * must be same as col (see - * draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) - */ - sol = s->s3->client_opaque_prf_input_len; - } -#endif - - tls1_PRF(ssl_get_algorithm2(s), - TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, - s->s3->client_random, SSL3_RANDOM_SIZE, - co, col, - s->s3->server_random, SSL3_RANDOM_SIZE, - so, sol, p, len, s->session->master_key, buff, sizeof(buff)); - OPENSSL_cleanse(buff, sizeof(buff)); -#ifdef SSL_DEBUG - fprintf(stderr, "Premaster Secret:\n"); - BIO_dump_fp(stderr, (char *)p, len); - fprintf(stderr, "Client Random:\n"); - BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE); - fprintf(stderr, "Server Random:\n"); - BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE); - fprintf(stderr, "Master Secret:\n"); - BIO_dump_fp(stderr, (char *)s->session->master_key, - SSL3_MASTER_SECRET_SIZE); -#endif - -#ifdef OPENSSL_SSL_TRACE_CRYPTO - if (s->msg_callback) { - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_PREMASTER, - p, len, s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_CLIENT_RANDOM, - s->s3->client_random, SSL3_RANDOM_SIZE, - s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_SERVER_RANDOM, - s->s3->server_random, SSL3_RANDOM_SIZE, - s, s->msg_callback_arg); - s->msg_callback(2, s->version, TLS1_RT_CRYPTO_MASTER, - s->session->master_key, - SSL3_MASTER_SECRET_SIZE, s, s->msg_callback_arg); - } -#endif - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_generate_master_secret() complete\n"); -#endif /* KSSL_DEBUG */ - return (SSL3_MASTER_SECRET_SIZE); -} - -int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, - const char *label, size_t llen, - const unsigned char *context, - size_t contextlen, int use_context) -{ - unsigned char *buff; - unsigned char *val = NULL; - size_t vallen, currentvalpos; - int rv; - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n", - s, out, olen, label, llen, context, contextlen); -#endif /* KSSL_DEBUG */ - - buff = OPENSSL_malloc(olen); - if (buff == NULL) - goto err2; - - /* - * construct PRF arguments we construct the PRF argument ourself rather - * than passing separate values into the TLS PRF to ensure that the - * concatenation of values does not create a prohibited label. - */ - vallen = llen + SSL3_RANDOM_SIZE * 2; - if (use_context) { - vallen += 2 + contextlen; - } - - val = OPENSSL_malloc(vallen); - if (val == NULL) - goto err2; - currentvalpos = 0; - memcpy(val + currentvalpos, (unsigned char *)label, llen); - currentvalpos += llen; - memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE); - currentvalpos += SSL3_RANDOM_SIZE; - memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE); - currentvalpos += SSL3_RANDOM_SIZE; - - if (use_context) { - val[currentvalpos] = (contextlen >> 8) & 0xff; - currentvalpos++; - val[currentvalpos] = contextlen & 0xff; - currentvalpos++; - if ((contextlen > 0) || (context != NULL)) { - memcpy(val + currentvalpos, context, contextlen); - } - } - - /* - * disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited - * label len) = 15, so size of val > max(prohibited label len) = 15 and - * the comparisons won't have buffer overflow - */ - if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST, - TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) - goto err1; - if (memcmp(val, TLS_MD_SERVER_FINISH_CONST, - TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) - goto err1; - if (memcmp(val, TLS_MD_MASTER_SECRET_CONST, - TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) - goto err1; - if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST, - TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) - goto err1; - - rv = tls1_PRF(ssl_get_algorithm2(s), - val, vallen, - NULL, 0, - NULL, 0, - NULL, 0, - NULL, 0, - s->session->master_key, s->session->master_key_length, - out, buff, olen); - OPENSSL_cleanse(val, vallen); - OPENSSL_cleanse(buff, olen); - -#ifdef KSSL_DEBUG - fprintf(stderr, "tls1_export_keying_material() complete\n"); -#endif /* KSSL_DEBUG */ - goto ret; - err1: - SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, - SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); - rv = 0; - goto ret; - err2: - SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE); - rv = 0; - ret: - if (buff != NULL) - OPENSSL_free(buff); - if (val != NULL) - OPENSSL_free(val); - return (rv); -} - -int tls1_alert_code(int code) -{ - switch (code) { - case SSL_AD_CLOSE_NOTIFY: - return (SSL3_AD_CLOSE_NOTIFY); - case SSL_AD_UNEXPECTED_MESSAGE: - return (SSL3_AD_UNEXPECTED_MESSAGE); - case SSL_AD_BAD_RECORD_MAC: - return (SSL3_AD_BAD_RECORD_MAC); - case SSL_AD_DECRYPTION_FAILED: - return (TLS1_AD_DECRYPTION_FAILED); - case SSL_AD_RECORD_OVERFLOW: - return (TLS1_AD_RECORD_OVERFLOW); - case SSL_AD_DECOMPRESSION_FAILURE: - return (SSL3_AD_DECOMPRESSION_FAILURE); - case SSL_AD_HANDSHAKE_FAILURE: - return (SSL3_AD_HANDSHAKE_FAILURE); - case SSL_AD_NO_CERTIFICATE: - return (-1); - case SSL_AD_BAD_CERTIFICATE: - return (SSL3_AD_BAD_CERTIFICATE); - case SSL_AD_UNSUPPORTED_CERTIFICATE: - return (SSL3_AD_UNSUPPORTED_CERTIFICATE); - case SSL_AD_CERTIFICATE_REVOKED: - return (SSL3_AD_CERTIFICATE_REVOKED); - case SSL_AD_CERTIFICATE_EXPIRED: - return (SSL3_AD_CERTIFICATE_EXPIRED); - case SSL_AD_CERTIFICATE_UNKNOWN: - return (SSL3_AD_CERTIFICATE_UNKNOWN); - case SSL_AD_ILLEGAL_PARAMETER: - return (SSL3_AD_ILLEGAL_PARAMETER); - case SSL_AD_UNKNOWN_CA: - return (TLS1_AD_UNKNOWN_CA); - case SSL_AD_ACCESS_DENIED: - return (TLS1_AD_ACCESS_DENIED); - case SSL_AD_DECODE_ERROR: - return (TLS1_AD_DECODE_ERROR); - case SSL_AD_DECRYPT_ERROR: - return (TLS1_AD_DECRYPT_ERROR); - case SSL_AD_EXPORT_RESTRICTION: - return (TLS1_AD_EXPORT_RESTRICTION); - case SSL_AD_PROTOCOL_VERSION: - return (TLS1_AD_PROTOCOL_VERSION); - case SSL_AD_INSUFFICIENT_SECURITY: - return (TLS1_AD_INSUFFICIENT_SECURITY); - case SSL_AD_INTERNAL_ERROR: - return (TLS1_AD_INTERNAL_ERROR); - case SSL_AD_USER_CANCELLED: - return (TLS1_AD_USER_CANCELLED); - case SSL_AD_NO_RENEGOTIATION: - return (TLS1_AD_NO_RENEGOTIATION); - case SSL_AD_UNSUPPORTED_EXTENSION: - return (TLS1_AD_UNSUPPORTED_EXTENSION); - case SSL_AD_CERTIFICATE_UNOBTAINABLE: - return (TLS1_AD_CERTIFICATE_UNOBTAINABLE); - case SSL_AD_UNRECOGNIZED_NAME: - return (TLS1_AD_UNRECOGNIZED_NAME); - case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - return (TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); - case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: - return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); - case SSL_AD_UNKNOWN_PSK_IDENTITY: - return (TLS1_AD_UNKNOWN_PSK_IDENTITY); - case SSL_AD_INAPPROPRIATE_FALLBACK: - return (TLS1_AD_INAPPROPRIATE_FALLBACK); -#if 0 - /* not appropriate for TLS, not used for DTLS */ - case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: - return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); -#endif - default: - return (-1); - } -} -/* ssl/t1_ext.c */ -/* ==================================================================== - * Copyright (c) 2014 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* Custom extension utility functions */ - -// #include "ssl_locl.h" - -#ifndef OPENSSL_NO_TLSEXT - -/* Find a custom extension from the list. */ -static custom_ext_method *custom_ext_find(custom_ext_methods *exts, - unsigned int ext_type) -{ - size_t i; - custom_ext_method *meth = exts->meths; - for (i = 0; i < exts->meths_count; i++, meth++) { - if (ext_type == meth->ext_type) - return meth; - } - return NULL; -} - -/* - * Initialise custom extensions flags to indicate neither sent nor received. - */ -void custom_ext_init(custom_ext_methods *exts) -{ - size_t i; - custom_ext_method *meth = exts->meths; - for (i = 0; i < exts->meths_count; i++, meth++) - meth->ext_flags = 0; -} - -/* Pass received custom extension data to the application for parsing. */ -int custom_ext_parse(SSL *s, int server, - unsigned int ext_type, - const unsigned char *ext_data, size_t ext_size, int *al) -{ - custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext; - custom_ext_method *meth; - meth = custom_ext_find(exts, ext_type); - /* If not found return success */ - if (!meth) - return 1; - if (!server) { - /* - * If it's ServerHello we can't have any extensions not sent in - * ClientHello. - */ - if (!(meth->ext_flags & SSL_EXT_FLAG_SENT)) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - } - /* If already present it's a duplicate */ - if (meth->ext_flags & SSL_EXT_FLAG_RECEIVED) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - meth->ext_flags |= SSL_EXT_FLAG_RECEIVED; - /* If no parse function set return success */ - if (!meth->parse_cb) - return 1; - - return meth->parse_cb(s, ext_type, ext_data, ext_size, al, - meth->parse_arg); -} - -/* - * Request custom extension data from the application and add to the return - * buffer. - */ -int custom_ext_add(SSL *s, int server, - unsigned char **pret, unsigned char *limit, int *al) -{ - custom_ext_methods *exts = server ? &s->cert->srv_ext : &s->cert->cli_ext; - custom_ext_method *meth; - unsigned char *ret = *pret; - size_t i; - - for (i = 0; i < exts->meths_count; i++) { - const unsigned char *out = NULL; - size_t outlen = 0; - meth = exts->meths + i; - - if (server) { - /* - * For ServerHello only send extensions present in ClientHello. - */ - if (!(meth->ext_flags & SSL_EXT_FLAG_RECEIVED)) - continue; - /* If callback absent for server skip it */ - if (!meth->add_cb) - continue; - } - if (meth->add_cb) { - int cb_retval = 0; - cb_retval = meth->add_cb(s, meth->ext_type, - &out, &outlen, al, meth->add_arg); - if (cb_retval < 0) - return 0; /* error */ - if (cb_retval == 0) - continue; /* skip this extension */ - } - if (4 > limit - ret || outlen > (size_t)(limit - ret - 4)) - return 0; - s2n(meth->ext_type, ret); - s2n(outlen, ret); - if (outlen) { - memcpy(ret, out, outlen); - ret += outlen; - } - /* - * We can't send duplicates: code logic should prevent this. - */ - OPENSSL_assert(!(meth->ext_flags & SSL_EXT_FLAG_SENT)); - /* - * Indicate extension has been sent: this is both a sanity check to - * ensure we don't send duplicate extensions and indicates that it is - * not an error if the extension is present in ServerHello. - */ - meth->ext_flags |= SSL_EXT_FLAG_SENT; - if (meth->free_cb) - meth->free_cb(s, meth->ext_type, out, meth->add_arg); - } - *pret = ret; - return 1; -} - -/* Copy the flags from src to dst for any extensions that exist in both */ -int custom_exts_copy_flags(custom_ext_methods *dst, - const custom_ext_methods *src) -{ - size_t i; - custom_ext_method *methsrc = src->meths; - - for (i = 0; i < src->meths_count; i++, methsrc++) { - custom_ext_method *methdst = custom_ext_find(dst, methsrc->ext_type); - - if (methdst == NULL) - continue; - - methdst->ext_flags = methsrc->ext_flags; - } - - return 1; -} - -/* Copy table of custom extensions */ -int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src) -{ - if (src->meths_count) { - dst->meths = - BUF_memdup(src->meths, - sizeof(custom_ext_method) * src->meths_count); - if (dst->meths == NULL) - return 0; - dst->meths_count = src->meths_count; - } - return 1; -} - -void custom_exts_free(custom_ext_methods *exts) -{ - if (exts->meths) - OPENSSL_free(exts->meths); -} - -/* Set callbacks for a custom extension. */ -static int custom_ext_meth_add(custom_ext_methods *exts, - unsigned int ext_type, - custom_ext_add_cb add_cb, - custom_ext_free_cb free_cb, - void *add_arg, - custom_ext_parse_cb parse_cb, void *parse_arg) -{ - custom_ext_method *meth; - /* - * Check application error: if add_cb is not set free_cb will never be - * called. - */ - if (!add_cb && free_cb) - return 0; - /* Don't add if extension supported internally. */ - if (SSL_extension_supported(ext_type)) - return 0; - /* Extension type must fit in 16 bits */ - if (ext_type > 0xffff) - return 0; - /* Search for duplicate */ - if (custom_ext_find(exts, ext_type)) - return 0; - meth = OPENSSL_realloc(exts->meths, - (exts->meths_count + 1) - * sizeof(custom_ext_method)); - if (meth == NULL) - return 0; - - exts->meths = meth; - meth += exts->meths_count; - memset(meth, 0, sizeof(custom_ext_method)); - meth->parse_cb = parse_cb; - meth->add_cb = add_cb; - meth->free_cb = free_cb; - meth->ext_type = ext_type; - meth->add_arg = add_arg; - meth->parse_arg = parse_arg; - exts->meths_count++; - return 1; -} - -/* Application level functions to add custom extension callbacks */ -int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned int ext_type, - custom_ext_add_cb add_cb, - custom_ext_free_cb free_cb, - void *add_arg, - custom_ext_parse_cb parse_cb, - void *parse_arg) -{ - return custom_ext_meth_add(&ctx->cert->cli_ext, ext_type, - add_cb, free_cb, add_arg, parse_cb, parse_arg); -} - -int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned int ext_type, - custom_ext_add_cb add_cb, - custom_ext_free_cb free_cb, - void *add_arg, - custom_ext_parse_cb parse_cb, - void *parse_arg) -{ - return custom_ext_meth_add(&ctx->cert->srv_ext, ext_type, - add_cb, free_cb, add_arg, parse_cb, parse_arg); -} - -int SSL_extension_supported(unsigned int ext_type) -{ - switch (ext_type) { - /* Internally supported extensions. */ - case TLSEXT_TYPE_application_layer_protocol_negotiation: - case TLSEXT_TYPE_ec_point_formats: - case TLSEXT_TYPE_elliptic_curves: - case TLSEXT_TYPE_heartbeat: -# ifndef OPENSSL_NO_NEXTPROTONEG - case TLSEXT_TYPE_next_proto_neg: -# endif - case TLSEXT_TYPE_padding: - case TLSEXT_TYPE_renegotiate: - case TLSEXT_TYPE_server_name: - case TLSEXT_TYPE_session_ticket: - case TLSEXT_TYPE_signature_algorithms: - case TLSEXT_TYPE_srp: - case TLSEXT_TYPE_status_request: - case TLSEXT_TYPE_use_srtp: -# ifdef TLSEXT_TYPE_opaque_prf_input - case TLSEXT_TYPE_opaque_prf_input: -# endif -# ifdef TLSEXT_TYPE_encrypt_then_mac - case TLSEXT_TYPE_encrypt_then_mac: -# endif - return 1; - default: - return 0; - } -} -#endif -/* ssl/t1_lib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "objects.h" -// #include "evp.h" -// #include "hmac.h" -#ifndef OPENSSL_NO_EC -#ifdef OPENSSL_NO_EC2M -# include "ec.h" -#endif -#endif -#include "ocsp.h" -// #include "rand.h" -// #include "ssl_locl.h" - -const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT; - -#ifndef OPENSSL_NO_TLSEXT -static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, - const unsigned char *sess_id, int sesslen, - SSL_SESSION **psess); -static int ssl_check_clienthello_tlsext_early(SSL *s); -int ssl_check_serverhello_tlsext(SSL *s); -#endif - -#define CHECKLEN(curr, val, limit) \ - (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val)) - -SSL3_ENC_METHOD TLSv1_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - 0, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write -}; - -SSL3_ENC_METHOD TLSv1_1_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_EXPLICIT_IV, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write -}; - -SSL3_ENC_METHOD TLSv1_2_enc_data = { - tls1_enc, - tls1_mac, - tls1_setup_key_block, - tls1_generate_master_secret, - tls1_change_cipher_state, - tls1_final_finish_mac, - TLS1_FINISH_MAC_LENGTH, - tls1_cert_verify_mac, - TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, - TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, - tls1_alert_code, - tls1_export_keying_material, - SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF - | SSL_ENC_FLAG_TLS1_2_CIPHERS, - SSL3_HM_HEADER_LENGTH, - ssl3_set_handshake_header, - ssl3_handshake_write -}; - -long tls1_default_timeout(void) -{ - /* - * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for - * http, the cache would over fill - */ - return (60 * 60 * 2); -} - -int tls1_new(SSL *s) -{ - if (!ssl3_new(s)) - return (0); - s->method->ssl_clear(s); - return (1); -} - -void tls1_free(SSL *s) -{ -#ifndef OPENSSL_NO_TLSEXT - if (s->tlsext_session_ticket) { - OPENSSL_free(s->tlsext_session_ticket); - } -#endif /* OPENSSL_NO_TLSEXT */ - ssl3_free(s); -} - -void tls1_clear(SSL *s) -{ - ssl3_clear(s); - s->version = s->method->version; -} - -#ifndef OPENSSL_NO_EC - -static int nid_list[] = { - NID_sect163k1, /* sect163k1 (1) */ - NID_sect163r1, /* sect163r1 (2) */ - NID_sect163r2, /* sect163r2 (3) */ - NID_sect193r1, /* sect193r1 (4) */ - NID_sect193r2, /* sect193r2 (5) */ - NID_sect233k1, /* sect233k1 (6) */ - NID_sect233r1, /* sect233r1 (7) */ - NID_sect239k1, /* sect239k1 (8) */ - NID_sect283k1, /* sect283k1 (9) */ - NID_sect283r1, /* sect283r1 (10) */ - NID_sect409k1, /* sect409k1 (11) */ - NID_sect409r1, /* sect409r1 (12) */ - NID_sect571k1, /* sect571k1 (13) */ - NID_sect571r1, /* sect571r1 (14) */ - NID_secp160k1, /* secp160k1 (15) */ - NID_secp160r1, /* secp160r1 (16) */ - NID_secp160r2, /* secp160r2 (17) */ - NID_secp192k1, /* secp192k1 (18) */ - NID_X9_62_prime192v1, /* secp192r1 (19) */ - NID_secp224k1, /* secp224k1 (20) */ - NID_secp224r1, /* secp224r1 (21) */ - NID_secp256k1, /* secp256k1 (22) */ - NID_X9_62_prime256v1, /* secp256r1 (23) */ - NID_secp384r1, /* secp384r1 (24) */ - NID_secp521r1, /* secp521r1 (25) */ - NID_brainpoolP256r1, /* brainpoolP256r1 (26) */ - NID_brainpoolP384r1, /* brainpoolP384r1 (27) */ - NID_brainpoolP512r1 /* brainpool512r1 (28) */ -}; - -static const unsigned char ecformats_default[] = { - TLSEXT_ECPOINTFORMAT_uncompressed, - TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, - TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 -}; - -/* The client's default curves / the server's 'auto' curves. */ -static const unsigned char eccurves_auto[] = { - /* Prefer P-256 which has the fastest and most secure implementations. */ - 0, 23, /* secp256r1 (23) */ - /* Other >= 256-bit prime curves. */ - 0, 25, /* secp521r1 (25) */ - 0, 28, /* brainpool512r1 (28) */ - 0, 27, /* brainpoolP384r1 (27) */ - 0, 24, /* secp384r1 (24) */ - 0, 26, /* brainpoolP256r1 (26) */ - 0, 22, /* secp256k1 (22) */ -# ifndef OPENSSL_NO_EC2M - /* >= 256-bit binary curves. */ - 0, 14, /* sect571r1 (14) */ - 0, 13, /* sect571k1 (13) */ - 0, 11, /* sect409k1 (11) */ - 0, 12, /* sect409r1 (12) */ - 0, 9, /* sect283k1 (9) */ - 0, 10, /* sect283r1 (10) */ -# endif -}; - -static const unsigned char eccurves_all[] = { - /* Prefer P-256 which has the fastest and most secure implementations. */ - 0, 23, /* secp256r1 (23) */ - /* Other >= 256-bit prime curves. */ - 0, 25, /* secp521r1 (25) */ - 0, 28, /* brainpool512r1 (28) */ - 0, 27, /* brainpoolP384r1 (27) */ - 0, 24, /* secp384r1 (24) */ - 0, 26, /* brainpoolP256r1 (26) */ - 0, 22, /* secp256k1 (22) */ -# ifndef OPENSSL_NO_EC2M - /* >= 256-bit binary curves. */ - 0, 14, /* sect571r1 (14) */ - 0, 13, /* sect571k1 (13) */ - 0, 11, /* sect409k1 (11) */ - 0, 12, /* sect409r1 (12) */ - 0, 9, /* sect283k1 (9) */ - 0, 10, /* sect283r1 (10) */ -# endif - /* - * Remaining curves disabled by default but still permitted if set - * via an explicit callback or parameters. - */ - 0, 20, /* secp224k1 (20) */ - 0, 21, /* secp224r1 (21) */ - 0, 18, /* secp192k1 (18) */ - 0, 19, /* secp192r1 (19) */ - 0, 15, /* secp160k1 (15) */ - 0, 16, /* secp160r1 (16) */ - 0, 17, /* secp160r2 (17) */ -# ifndef OPENSSL_NO_EC2M - 0, 8, /* sect239k1 (8) */ - 0, 6, /* sect233k1 (6) */ - 0, 7, /* sect233r1 (7) */ - 0, 4, /* sect193r1 (4) */ - 0, 5, /* sect193r2 (5) */ - 0, 1, /* sect163k1 (1) */ - 0, 2, /* sect163r1 (2) */ - 0, 3, /* sect163r2 (3) */ -# endif -}; - -static const unsigned char suiteb_curves[] = { - 0, TLSEXT_curve_P_256, - 0, TLSEXT_curve_P_384 -}; - -# ifdef OPENSSL_FIPS -/* Brainpool not allowed in FIPS mode */ -static const unsigned char fips_curves_default[] = { -# ifndef OPENSSL_NO_EC2M - 0, 14, /* sect571r1 (14) */ - 0, 13, /* sect571k1 (13) */ -# endif - 0, 25, /* secp521r1 (25) */ -# ifndef OPENSSL_NO_EC2M - 0, 11, /* sect409k1 (11) */ - 0, 12, /* sect409r1 (12) */ -# endif - 0, 24, /* secp384r1 (24) */ -# ifndef OPENSSL_NO_EC2M - 0, 9, /* sect283k1 (9) */ - 0, 10, /* sect283r1 (10) */ -# endif - 0, 22, /* secp256k1 (22) */ - 0, 23, /* secp256r1 (23) */ -# ifndef OPENSSL_NO_EC2M - 0, 8, /* sect239k1 (8) */ - 0, 6, /* sect233k1 (6) */ - 0, 7, /* sect233r1 (7) */ -# endif - 0, 20, /* secp224k1 (20) */ - 0, 21, /* secp224r1 (21) */ -# ifndef OPENSSL_NO_EC2M - 0, 4, /* sect193r1 (4) */ - 0, 5, /* sect193r2 (5) */ -# endif - 0, 18, /* secp192k1 (18) */ - 0, 19, /* secp192r1 (19) */ -# ifndef OPENSSL_NO_EC2M - 0, 1, /* sect163k1 (1) */ - 0, 2, /* sect163r1 (2) */ - 0, 3, /* sect163r2 (3) */ -# endif - 0, 15, /* secp160k1 (15) */ - 0, 16, /* secp160r1 (16) */ - 0, 17, /* secp160r2 (17) */ -}; -# endif - -int tls1_ec_curve_id2nid(int curve_id) -{ - /* ECC curves from RFC 4492 and RFC 7027 */ - if ((curve_id < 1) || ((unsigned int)curve_id > - sizeof(nid_list) / sizeof(nid_list[0]))) - return 0; - return nid_list[curve_id - 1]; -} - -int tls1_ec_nid2curve_id(int nid) -{ - /* ECC curves from RFC 4492 and RFC 7027 */ - switch (nid) { - case NID_sect163k1: /* sect163k1 (1) */ - return 1; - case NID_sect163r1: /* sect163r1 (2) */ - return 2; - case NID_sect163r2: /* sect163r2 (3) */ - return 3; - case NID_sect193r1: /* sect193r1 (4) */ - return 4; - case NID_sect193r2: /* sect193r2 (5) */ - return 5; - case NID_sect233k1: /* sect233k1 (6) */ - return 6; - case NID_sect233r1: /* sect233r1 (7) */ - return 7; - case NID_sect239k1: /* sect239k1 (8) */ - return 8; - case NID_sect283k1: /* sect283k1 (9) */ - return 9; - case NID_sect283r1: /* sect283r1 (10) */ - return 10; - case NID_sect409k1: /* sect409k1 (11) */ - return 11; - case NID_sect409r1: /* sect409r1 (12) */ - return 12; - case NID_sect571k1: /* sect571k1 (13) */ - return 13; - case NID_sect571r1: /* sect571r1 (14) */ - return 14; - case NID_secp160k1: /* secp160k1 (15) */ - return 15; - case NID_secp160r1: /* secp160r1 (16) */ - return 16; - case NID_secp160r2: /* secp160r2 (17) */ - return 17; - case NID_secp192k1: /* secp192k1 (18) */ - return 18; - case NID_X9_62_prime192v1: /* secp192r1 (19) */ - return 19; - case NID_secp224k1: /* secp224k1 (20) */ - return 20; - case NID_secp224r1: /* secp224r1 (21) */ - return 21; - case NID_secp256k1: /* secp256k1 (22) */ - return 22; - case NID_X9_62_prime256v1: /* secp256r1 (23) */ - return 23; - case NID_secp384r1: /* secp384r1 (24) */ - return 24; - case NID_secp521r1: /* secp521r1 (25) */ - return 25; - case NID_brainpoolP256r1: /* brainpoolP256r1 (26) */ - return 26; - case NID_brainpoolP384r1: /* brainpoolP384r1 (27) */ - return 27; - case NID_brainpoolP512r1: /* brainpool512r1 (28) */ - return 28; - default: - return 0; - } -} - -/* - * Get curves list, if "sess" is set return client curves otherwise - * preferred list. - * Sets |num_curves| to the number of curves in the list, i.e., - * the length of |pcurves| is 2 * num_curves. - * Returns 1 on success and 0 if the client curves list has invalid format. - * The latter indicates an internal error: we should not be accepting such - * lists in the first place. - * TODO(emilia): we should really be storing the curves list in explicitly - * parsed form instead. (However, this would affect binary compatibility - * so cannot happen in the 1.0.x series.) - */ -static int tls1_get_curvelist(SSL *s, int sess, - const unsigned char **pcurves, - size_t *num_curves) -{ - size_t pcurveslen = 0; - if (sess) { - *pcurves = s->session->tlsext_ellipticcurvelist; - pcurveslen = s->session->tlsext_ellipticcurvelist_length; - } else { - /* For Suite B mode only include P-256, P-384 */ - switch (tls1_suiteb(s)) { - case SSL_CERT_FLAG_SUITEB_128_LOS: - *pcurves = suiteb_curves; - pcurveslen = sizeof(suiteb_curves); - break; - - case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: - *pcurves = suiteb_curves; - pcurveslen = 2; - break; - - case SSL_CERT_FLAG_SUITEB_192_LOS: - *pcurves = suiteb_curves + 2; - pcurveslen = 2; - break; - default: - *pcurves = s->tlsext_ellipticcurvelist; - pcurveslen = s->tlsext_ellipticcurvelist_length; - } - if (!*pcurves) { -# ifdef OPENSSL_FIPS - if (FIPS_mode()) { - *pcurves = fips_curves_default; - pcurveslen = sizeof(fips_curves_default); - } else -# endif - { - if (!s->server -# ifndef OPENSSL_NO_ECDH - || s->cert->ecdh_tmp_auto -# endif - ) { - *pcurves = eccurves_auto; - pcurveslen = sizeof(eccurves_auto); - } else { - *pcurves = eccurves_all; - pcurveslen = sizeof(eccurves_all); - } - } - } - } - /* We do not allow odd length arrays to enter the system. */ - if (pcurveslen & 1) { - SSLerr(SSL_F_TLS1_GET_CURVELIST, ERR_R_INTERNAL_ERROR); - *num_curves = 0; - return 0; - } else { - *num_curves = pcurveslen / 2; - return 1; - } -} - -/* Check a curve is one of our preferences */ -int tls1_check_curve(SSL *s, const unsigned char *p, size_t len) -{ - const unsigned char *curves; - size_t num_curves, i; - unsigned int suiteb_flags = tls1_suiteb(s); - if (len != 3 || p[0] != NAMED_CURVE_TYPE) - return 0; - /* Check curve matches Suite B preferences */ - if (suiteb_flags) { - unsigned long cid = s->s3->tmp.new_cipher->id; - if (p[1]) - return 0; - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) { - if (p[2] != TLSEXT_curve_P_256) - return 0; - } else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) { - if (p[2] != TLSEXT_curve_P_384) - return 0; - } else /* Should never happen */ - return 0; - } - if (!tls1_get_curvelist(s, 0, &curves, &num_curves)) - return 0; - for (i = 0; i < num_curves; i++, curves += 2) { - if (p[1] == curves[0] && p[2] == curves[1]) - return 1; - } - return 0; -} - -/*- - * Return |nmatch|th shared curve or NID_undef if there is no match. - * For nmatch == -1, return number of matches - * For nmatch == -2, return the NID of the curve to use for - * an EC tmp key, or NID_undef if there is no match. - */ -int tls1_shared_curve(SSL *s, int nmatch) -{ - const unsigned char *pref, *supp; - size_t num_pref, num_supp, i, j; - int k; - /* Can't do anything on client side */ - if (s->server == 0) - return -1; - if (nmatch == -2) { - if (tls1_suiteb(s)) { - /* - * For Suite B ciphersuite determines curve: we already know - * these are acceptable due to previous checks. - */ - unsigned long cid = s->s3->tmp.new_cipher->id; - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - return NID_X9_62_prime256v1; /* P-256 */ - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - return NID_secp384r1; /* P-384 */ - /* Should never happen */ - return NID_undef; - } - /* If not Suite B just return first preference shared curve */ - nmatch = 0; - } - /* - * Avoid truncation. tls1_get_curvelist takes an int - * but s->options is a long... - */ - if (!tls1_get_curvelist - (s, (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0, &supp, - &num_supp)) - /* In practice, NID_undef == 0 but let's be precise. */ - return nmatch == -1 ? 0 : NID_undef; - if (!tls1_get_curvelist - (s, !(s->options & SSL_OP_CIPHER_SERVER_PREFERENCE), &pref, - &num_pref)) - return nmatch == -1 ? 0 : NID_undef; - - /* - * If the client didn't send the elliptic_curves extension all of them - * are allowed. - */ - if (num_supp == 0 && (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) != 0) { - supp = eccurves_all; - num_supp = sizeof(eccurves_all) / 2; - } else if (num_pref == 0 && - (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) == 0) { - pref = eccurves_all; - num_pref = sizeof(eccurves_all) / 2; - } - - k = 0; - for (i = 0; i < num_pref; i++, pref += 2) { - const unsigned char *tsupp = supp; - for (j = 0; j < num_supp; j++, tsupp += 2) { - if (pref[0] == tsupp[0] && pref[1] == tsupp[1]) { - if (nmatch == k) { - int id = (pref[0] << 8) | pref[1]; - return tls1_ec_curve_id2nid(id); - } - k++; - } - } - } - if (nmatch == -1) - return k; - /* Out of range (nmatch > k). */ - return NID_undef; -} - -int tls1_set_curves(unsigned char **pext, size_t *pextlen, - int *curves, size_t ncurves) -{ - unsigned char *clist, *p; - size_t i; - /* - * Bitmap of curves included to detect duplicates: only works while curve - * ids < 32 - */ - unsigned long dup_list = 0; -# ifdef OPENSSL_NO_EC2M - EC_GROUP *curve; -# endif - - clist = OPENSSL_malloc(ncurves * 2); - if (!clist) - return 0; - for (i = 0, p = clist; i < ncurves; i++) { - unsigned long idmask; - int id; - id = tls1_ec_nid2curve_id(curves[i]); -# ifdef OPENSSL_FIPS - /* NB: 25 is last curve ID supported by FIPS module */ - if (FIPS_mode() && id > 25) { - OPENSSL_free(clist); - return 0; - } -# endif -# ifdef OPENSSL_NO_EC2M - curve = EC_GROUP_new_by_curve_name(curves[i]); - if (!curve || EC_METHOD_get_field_type(EC_GROUP_method_of(curve)) - == NID_X9_62_characteristic_two_field) { - if (curve) - EC_GROUP_free(curve); - OPENSSL_free(clist); - return 0; - } else - EC_GROUP_free(curve); -# endif - idmask = 1L << id; - if (!id || (dup_list & idmask)) { - OPENSSL_free(clist); - return 0; - } - dup_list |= idmask; - s2n(id, p); - } - if (*pext) - OPENSSL_free(*pext); - *pext = clist; - *pextlen = ncurves * 2; - return 1; -} - -# define MAX_CURVELIST 28 - -typedef struct { - size_t nidcnt; - int nid_arr[MAX_CURVELIST]; -} nid_cb_st; - -static int nid_cb(const char *elem, int len, void *arg) -{ - nid_cb_st *narg = arg; - size_t i; - int nid; - char etmp[20]; - if (elem == NULL) - return 0; - if (narg->nidcnt == MAX_CURVELIST) - return 0; - if (len > (int)(sizeof(etmp) - 1)) - return 0; - memcpy(etmp, elem, len); - etmp[len] = 0; - nid = EC_curve_nist2nid(etmp); - if (nid == NID_undef) - nid = OBJ_sn2nid(etmp); - if (nid == NID_undef) - nid = OBJ_ln2nid(etmp); - if (nid == NID_undef) - return 0; - for (i = 0; i < narg->nidcnt; i++) - if (narg->nid_arr[i] == nid) - return 0; - narg->nid_arr[narg->nidcnt++] = nid; - return 1; -} - -/* Set curves based on a colon separate list */ -int tls1_set_curves_list(unsigned char **pext, size_t *pextlen, - const char *str) -{ - nid_cb_st ncb; - ncb.nidcnt = 0; - if (!CONF_parse_list(str, ':', 1, nid_cb, &ncb)) - return 0; - if (pext == NULL) - return 1; - return tls1_set_curves(pext, pextlen, ncb.nid_arr, ncb.nidcnt); -} - -/* For an EC key set TLS id and required compression based on parameters */ -static int tls1_set_ec_id(unsigned char *curve_id, unsigned char *comp_id, - EC_KEY *ec) -{ - int is_prime, id; - const EC_GROUP *grp; - const EC_METHOD *meth; - if (!ec) - return 0; - /* Determine if it is a prime field */ - grp = EC_KEY_get0_group(ec); - if (!grp) - return 0; - meth = EC_GROUP_method_of(grp); - if (!meth) - return 0; - if (EC_METHOD_get_field_type(meth) == NID_X9_62_prime_field) - is_prime = 1; - else - is_prime = 0; - /* Determine curve ID */ - id = EC_GROUP_get_curve_name(grp); - id = tls1_ec_nid2curve_id(id); - /* If we have an ID set it, otherwise set arbitrary explicit curve */ - if (id) { - curve_id[0] = 0; - curve_id[1] = (unsigned char)id; - } else { - curve_id[0] = 0xff; - if (is_prime) - curve_id[1] = 0x01; - else - curve_id[1] = 0x02; - } - if (comp_id) { - if (EC_KEY_get0_public_key(ec) == NULL) - return 0; - if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) { - if (is_prime) - *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; - else - *comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; - } else - *comp_id = TLSEXT_ECPOINTFORMAT_uncompressed; - } - return 1; -} - -/* Check an EC key is compatible with extensions */ -static int tls1_check_ec_key(SSL *s, - unsigned char *curve_id, unsigned char *comp_id) -{ - const unsigned char *pformats, *pcurves; - size_t num_formats, num_curves, i; - int j; - /* - * If point formats extension present check it, otherwise everything is - * supported (see RFC4492). - */ - if (comp_id && s->session->tlsext_ecpointformatlist) { - pformats = s->session->tlsext_ecpointformatlist; - num_formats = s->session->tlsext_ecpointformatlist_length; - for (i = 0; i < num_formats; i++, pformats++) { - if (*comp_id == *pformats) - break; - } - if (i == num_formats) - return 0; - } - if (!curve_id) - return 1; - /* Check curve is consistent with client and server preferences */ - for (j = 0; j <= 1; j++) { - if (!tls1_get_curvelist(s, j, &pcurves, &num_curves)) - return 0; - if (j == 1 && num_curves == 0) { - /* - * If we've not received any curves then skip this check. - * RFC 4492 does not require the supported elliptic curves extension - * so if it is not sent we can just choose any curve. - * It is invalid to send an empty list in the elliptic curves - * extension, so num_curves == 0 always means no extension. - */ - break; - } - for (i = 0; i < num_curves; i++, pcurves += 2) { - if (pcurves[0] == curve_id[0] && pcurves[1] == curve_id[1]) - break; - } - if (i == num_curves) - return 0; - /* For clients can only check sent curve list */ - if (!s->server) - return 1; - } - return 1; -} - -static void tls1_get_formatlist(SSL *s, const unsigned char **pformats, - size_t *num_formats) -{ - /* - * If we have a custom point format list use it otherwise use default - */ - if (s->tlsext_ecpointformatlist) { - *pformats = s->tlsext_ecpointformatlist; - *num_formats = s->tlsext_ecpointformatlist_length; - } else { - *pformats = ecformats_default; - /* For Suite B we don't support char2 fields */ - if (tls1_suiteb(s)) - *num_formats = sizeof(ecformats_default) - 1; - else - *num_formats = sizeof(ecformats_default); - } -} - -/* - * Check cert parameters compatible with extensions: currently just checks EC - * certificates have compatible curves and compression. - */ -static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) -{ - unsigned char comp_id, curve_id[2]; - EVP_PKEY *pkey; - int rv; - pkey = X509_get_pubkey(x); - if (!pkey) - return 0; - /* If not EC nothing to do */ - if (pkey->type != EVP_PKEY_EC) { - EVP_PKEY_free(pkey); - return 1; - } - rv = tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec); - EVP_PKEY_free(pkey); - if (!rv) - return 0; - /* - * Can't check curve_id for client certs as we don't have a supported - * curves extension. - */ - rv = tls1_check_ec_key(s, s->server ? curve_id : NULL, &comp_id); - if (!rv) - return 0; - /* - * Special case for suite B. We *MUST* sign using SHA256+P-256 or - * SHA384+P-384, adjust digest if necessary. - */ - if (set_ee_md && tls1_suiteb(s)) { - int check_md; - size_t i; - CERT *c = s->cert; - if (curve_id[0]) - return 0; - /* Check to see we have necessary signing algorithm */ - if (curve_id[1] == TLSEXT_curve_P_256) - check_md = NID_ecdsa_with_SHA256; - else if (curve_id[1] == TLSEXT_curve_P_384) - check_md = NID_ecdsa_with_SHA384; - else - return 0; /* Should never happen */ - for (i = 0; i < c->shared_sigalgslen; i++) - if (check_md == c->shared_sigalgs[i].signandhash_nid) - break; - if (i == c->shared_sigalgslen) - return 0; - if (set_ee_md == 2) { - if (check_md == NID_ecdsa_with_SHA256) - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha256(); - else - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha384(); - } - } - return rv; -} - -# ifndef OPENSSL_NO_ECDH -/* Check EC temporary key is compatible with client extensions */ -int tls1_check_ec_tmp_key(SSL *s, unsigned long cid) -{ - unsigned char curve_id[2]; - EC_KEY *ec = s->cert->ecdh_tmp; -# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - /* Allow any curve: not just those peer supports */ - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) - return 1; -# endif - /* - * If Suite B, AES128 MUST use P-256 and AES256 MUST use P-384, no other - * curves permitted. - */ - if (tls1_suiteb(s)) { - /* Curve to check determined by ciphersuite */ - if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - curve_id[1] = TLSEXT_curve_P_256; - else if (cid == TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - curve_id[1] = TLSEXT_curve_P_384; - else - return 0; - curve_id[0] = 0; - /* Check this curve is acceptable */ - if (!tls1_check_ec_key(s, curve_id, NULL)) - return 0; - /* If auto or setting curve from callback assume OK */ - if (s->cert->ecdh_tmp_auto || s->cert->ecdh_tmp_cb) - return 1; - /* Otherwise check curve is acceptable */ - else { - unsigned char curve_tmp[2]; - if (!ec) - return 0; - if (!tls1_set_ec_id(curve_tmp, NULL, ec)) - return 0; - if (!curve_tmp[0] || curve_tmp[1] == curve_id[1]) - return 1; - return 0; - } - - } - if (s->cert->ecdh_tmp_auto) { - /* Need a shared curve */ - if (tls1_shared_curve(s, 0)) - return 1; - else - return 0; - } - if (!ec) { - if (s->cert->ecdh_tmp_cb) - return 1; - else - return 0; - } - if (!tls1_set_ec_id(curve_id, NULL, ec)) - return 0; -/* Set this to allow use of invalid curves for testing */ -# if 0 - return 1; -# else - return tls1_check_ec_key(s, curve_id, NULL); -# endif -} -# endif /* OPENSSL_NO_ECDH */ - -#else - -static int tls1_check_cert_param(SSL *s, X509 *x, int set_ee_md) -{ - return 1; -} - -#endif /* OPENSSL_NO_EC */ - -#ifndef OPENSSL_NO_TLSEXT - -/* - * List of supported signature algorithms and hashes. Should make this - * customisable at some point, for now include everything we support. - */ - -# ifdef OPENSSL_NO_RSA -# define tlsext_sigalg_rsa(md) /* */ -# else -# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa, -# endif - -# ifdef OPENSSL_NO_DSA -# define tlsext_sigalg_dsa(md) /* */ -# else -# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa, -# endif - -# ifdef OPENSSL_NO_ECDSA -# define tlsext_sigalg_ecdsa(md) - /* */ -# else -# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa, -# endif - -# define tlsext_sigalg(md) \ - tlsext_sigalg_rsa(md) \ - tlsext_sigalg_dsa(md) \ - tlsext_sigalg_ecdsa(md) - -static unsigned char tls12_sigalgs[] = { -# ifndef OPENSSL_NO_SHA512 - tlsext_sigalg(TLSEXT_hash_sha512) - tlsext_sigalg(TLSEXT_hash_sha384) -# endif -# ifndef OPENSSL_NO_SHA256 - tlsext_sigalg(TLSEXT_hash_sha256) - tlsext_sigalg(TLSEXT_hash_sha224) -# endif -# ifndef OPENSSL_NO_SHA - tlsext_sigalg(TLSEXT_hash_sha1) -# endif -}; - -# ifndef OPENSSL_NO_ECDSA -static unsigned char suiteb_sigalgs[] = { - tlsext_sigalg_ecdsa(TLSEXT_hash_sha256) - tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) -}; -# endif -size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs) -{ - /* - * If Suite B mode use Suite B sigalgs only, ignore any other - * preferences. - */ -# ifndef OPENSSL_NO_EC - switch (tls1_suiteb(s)) { - case SSL_CERT_FLAG_SUITEB_128_LOS: - *psigs = suiteb_sigalgs; - return sizeof(suiteb_sigalgs); - - case SSL_CERT_FLAG_SUITEB_128_LOS_ONLY: - *psigs = suiteb_sigalgs; - return 2; - - case SSL_CERT_FLAG_SUITEB_192_LOS: - *psigs = suiteb_sigalgs + 2; - return 2; - } -# endif - /* If server use client authentication sigalgs if not NULL */ - if (s->server == sent && s->cert->client_sigalgs) { - *psigs = s->cert->client_sigalgs; - return s->cert->client_sigalgslen; - } else if (s->cert->conf_sigalgs) { - *psigs = s->cert->conf_sigalgs; - return s->cert->conf_sigalgslen; - } else { - *psigs = tls12_sigalgs; - return sizeof(tls12_sigalgs); - } -} - -/* - * Check signature algorithm is consistent with sent supported signature - * algorithms and if so return relevant digest. - */ -int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, - const unsigned char *sig, EVP_PKEY *pkey) -{ - const unsigned char *sent_sigs; - size_t sent_sigslen, i; - int sigalg = tls12_get_sigid(pkey); - /* Should never happen */ - if (sigalg == -1) - return -1; - /* Check key type is consistent with signature */ - if (sigalg != (int)sig[1]) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); - return 0; - } -# ifndef OPENSSL_NO_EC - if (pkey->type == EVP_PKEY_EC) { - unsigned char curve_id[2], comp_id; - /* Check compression and curve matches extensions */ - if (!tls1_set_ec_id(curve_id, &comp_id, pkey->pkey.ec)) - return 0; - if (!s->server && !tls1_check_ec_key(s, curve_id, &comp_id)) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_CURVE); - return 0; - } - /* If Suite B only P-384+SHA384 or P-256+SHA-256 allowed */ - if (tls1_suiteb(s)) { - if (curve_id[0]) - return 0; - if (curve_id[1] == TLSEXT_curve_P_256) { - if (sig[0] != TLSEXT_hash_sha256) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_ILLEGAL_SUITEB_DIGEST); - return 0; - } - } else if (curve_id[1] == TLSEXT_curve_P_384) { - if (sig[0] != TLSEXT_hash_sha384) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, - SSL_R_ILLEGAL_SUITEB_DIGEST); - return 0; - } - } else - return 0; - } - } else if (tls1_suiteb(s)) - return 0; -# endif - - /* Check signature matches a type we sent */ - sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); - for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) { - if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1]) - break; - } - /* Allow fallback to SHA1 if not strict mode */ - if (i == sent_sigslen - && (sig[0] != TLSEXT_hash_sha1 - || s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_WRONG_SIGNATURE_TYPE); - return 0; - } - *pmd = tls12_get_hash(sig[0]); - if (*pmd == NULL) { - SSLerr(SSL_F_TLS12_CHECK_PEER_SIGALG, SSL_R_UNKNOWN_DIGEST); - return 0; - } - /* - * Store the digest used so applications can retrieve it if they wish. - */ - if (s->session && s->session->sess_cert) - s->session->sess_cert->peer_key->digest = *pmd; - return 1; -} - -/* - * Get a mask of disabled algorithms: an algorithm is disabled if it isn't - * supported or doesn't appear in supported signature algorithms. Unlike - * ssl_cipher_get_disabled this applies to a specific session and not global - * settings. - */ -void ssl_set_client_disabled(SSL *s) -{ - CERT *c = s->cert; - const unsigned char *sigalgs; - size_t i, sigalgslen; - int have_rsa = 0, have_dsa = 0, have_ecdsa = 0; - c->mask_a = 0; - c->mask_k = 0; - /* Don't allow TLS 1.2 only ciphers if we don't suppport them */ - if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s)) - c->mask_ssl = SSL_TLSV1_2; - else - c->mask_ssl = 0; - /* - * Now go through all signature algorithms seeing if we support any for - * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. - */ - sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); - for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { - switch (sigalgs[1]) { -# ifndef OPENSSL_NO_RSA - case TLSEXT_signature_rsa: - have_rsa = 1; - break; -# endif -# ifndef OPENSSL_NO_DSA - case TLSEXT_signature_dsa: - have_dsa = 1; - break; -# endif -# ifndef OPENSSL_NO_ECDSA - case TLSEXT_signature_ecdsa: - have_ecdsa = 1; - break; -# endif - } - } - /* - * Disable auth and static DH if we don't include any appropriate - * signature algorithms. - */ - if (!have_rsa) { - c->mask_a |= SSL_aRSA; - c->mask_k |= SSL_kDHr | SSL_kECDHr; - } - if (!have_dsa) { - c->mask_a |= SSL_aDSS; - c->mask_k |= SSL_kDHd; - } - if (!have_ecdsa) { - c->mask_a |= SSL_aECDSA; - c->mask_k |= SSL_kECDHe; - } -# ifndef OPENSSL_NO_KRB5 - if (!kssl_tgt_is_available(s->kssl_ctx)) { - c->mask_a |= SSL_aKRB5; - c->mask_k |= SSL_kKRB5; - } -# endif -# ifndef OPENSSL_NO_PSK - /* with PSK there must be client callback set */ - if (!s->psk_client_callback) { - c->mask_a |= SSL_aPSK; - c->mask_k |= SSL_kPSK; - } -# endif /* OPENSSL_NO_PSK */ -# ifndef OPENSSL_NO_SRP - if (!(s->srp_ctx.srp_Mask & SSL_kSRP)) { - c->mask_a |= SSL_aSRP; - c->mask_k |= SSL_kSRP; - } -# endif - c->valid = 1; -} - -unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al) -{ - int extdatalen = 0; - unsigned char *orig = buf; - unsigned char *ret = buf; -# ifndef OPENSSL_NO_EC - /* See if we support any ECC ciphersuites */ - int using_ecc = 0; - if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) { - int i; - unsigned long alg_k, alg_a; - STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s); - - for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) { - SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); - - alg_k = c->algorithm_mkey; - alg_a = c->algorithm_auth; - if ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe) - || (alg_a & SSL_aECDSA))) { - using_ecc = 1; - break; - } - } - } -# endif - - /* don't add extensions for SSLv3 unless doing secure renegotiation */ - if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) - return orig; - - ret += 2; - - if (ret >= limit) - return NULL; /* this really never occurs, but ... */ - - if (s->tlsext_hostname != NULL) { - /* Add TLS extension servername to the Client Hello message */ - size_t size_str; - - /*- - * check for enough space. - * 4 for the servername type and entension length - * 2 for servernamelist length - * 1 for the hostname type - * 2 for hostname length - * + hostname length - */ - size_str = strlen(s->tlsext_hostname); - if (CHECKLEN(ret, 9 + size_str, limit)) - return NULL; - - /* extension type and length */ - s2n(TLSEXT_TYPE_server_name, ret); - s2n(size_str + 5, ret); - - /* length of servername list */ - s2n(size_str + 3, ret); - - /* hostname type, length and hostname */ - *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name; - s2n(size_str, ret); - memcpy(ret, s->tlsext_hostname, size_str); - ret += size_str; - } - - /* Add RI if renegotiating */ - if (s->renegotiate) { - int el; - - if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - if ((limit - ret - 4 - el) < 0) - return NULL; - - s2n(TLSEXT_TYPE_renegotiate, ret); - s2n(el, ret); - - if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - ret += el; - } -# ifndef OPENSSL_NO_SRP - /* Add SRP username if there is one */ - if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the - * Client Hello message */ - - size_t login_len = strlen(s->srp_ctx.login); - if (login_len > 255 || login_len == 0) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - /*- - * check for enough space. - * 4 for the srp type type and entension length - * 1 for the srp user identity - * + srp user identity length - */ - if (CHECKLEN(ret, 5 + login_len, limit)) - return NULL; - - /* fill in the extension */ - s2n(TLSEXT_TYPE_srp, ret); - s2n(login_len + 1, ret); - (*ret++) = (unsigned char)login_len; - memcpy(ret, s->srp_ctx.login, login_len); - ret += login_len; - } -# endif - -# ifndef OPENSSL_NO_EC - if (using_ecc) { - /* - * Add TLS extension ECPointFormats to the ClientHello message - */ - const unsigned char *pcurves, *pformats; - size_t num_curves, num_formats, curves_list_len; - - tls1_get_formatlist(s, &pformats, &num_formats); - - if (num_formats > 255) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - /*- - * check for enough space. - * 4 bytes for the ec point formats type and extension length - * 1 byte for the length of the formats - * + formats length - */ - if (CHECKLEN(ret, 5 + num_formats, limit)) - return NULL; - - s2n(TLSEXT_TYPE_ec_point_formats, ret); - /* The point format list has 1-byte length. */ - s2n(num_formats + 1, ret); - *(ret++) = (unsigned char)num_formats; - memcpy(ret, pformats, num_formats); - ret += num_formats; - - /* - * Add TLS extension EllipticCurves to the ClientHello message - */ - pcurves = s->tlsext_ellipticcurvelist; - if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) - return NULL; - - if (num_curves > 65532 / 2) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - curves_list_len = 2 * num_curves; - /*- - * check for enough space. - * 4 bytes for the ec curves type and extension length - * 2 bytes for the curve list length - * + curve list length - */ - if (CHECKLEN(ret, 6 + curves_list_len, limit)) - return NULL; - - s2n(TLSEXT_TYPE_elliptic_curves, ret); - s2n(curves_list_len + 2, ret); - s2n(curves_list_len, ret); - memcpy(ret, pcurves, curves_list_len); - ret += curves_list_len; - } -# endif /* OPENSSL_NO_EC */ - - if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { - size_t ticklen; - if (!s->new_session && s->session && s->session->tlsext_tick) - ticklen = s->session->tlsext_ticklen; - else if (s->session && s->tlsext_session_ticket && - s->tlsext_session_ticket->data) { - ticklen = s->tlsext_session_ticket->length; - s->session->tlsext_tick = OPENSSL_malloc(ticklen); - if (!s->session->tlsext_tick) - return NULL; - memcpy(s->session->tlsext_tick, - s->tlsext_session_ticket->data, ticklen); - s->session->tlsext_ticklen = ticklen; - } else - ticklen = 0; - if (ticklen == 0 && s->tlsext_session_ticket && - s->tlsext_session_ticket->data == NULL) - goto skip_ext; - /* - * Check for enough room 2 for extension type, 2 for len rest for - * ticket - */ - if (CHECKLEN(ret, 4 + ticklen, limit)) - return NULL; - s2n(TLSEXT_TYPE_session_ticket, ret); - s2n(ticklen, ret); - if (ticklen > 0) { - memcpy(ret, s->session->tlsext_tick, ticklen); - ret += ticklen; - } - } - skip_ext: - - if (SSL_CLIENT_USE_SIGALGS(s)) { - size_t salglen; - const unsigned char *salg; - salglen = tls12_get_psigalgs(s, 1, &salg); - - /*- - * check for enough space. - * 4 bytes for the sigalgs type and extension length - * 2 bytes for the sigalg list length - * + sigalg list length - */ - if (CHECKLEN(ret, salglen + 6, limit)) - return NULL; - s2n(TLSEXT_TYPE_signature_algorithms, ret); - s2n(salglen + 2, ret); - s2n(salglen, ret); - memcpy(ret, salg, salglen); - ret += salglen; - } -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL) { - size_t col = s->s3->client_opaque_prf_input_len; - - if ((long)(limit - ret - 6 - col < 0)) - return NULL; - if (col > 0xFFFD) /* can't happen */ - return NULL; - - s2n(TLSEXT_TYPE_opaque_prf_input, ret); - s2n(col + 2, ret); - s2n(col, ret); - memcpy(ret, s->s3->client_opaque_prf_input, col); - ret += col; - } -# endif - - if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { - int i; - size_t extlen, idlen; - int lentmp; - OCSP_RESPID *id; - - idlen = 0; - for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { - id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); - lentmp = i2d_OCSP_RESPID(id, NULL); - if (lentmp <= 0) - return NULL; - idlen += (size_t)lentmp + 2; - } - - if (s->tlsext_ocsp_exts) { - lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); - if (lentmp < 0) - return NULL; - extlen = (size_t)lentmp; - } else - extlen = 0; - - if (extlen + idlen > 0xFFF0) - return NULL; - /* - * 2 bytes for status request type - * 2 bytes for status request len - * 1 byte for OCSP request type - * 2 bytes for length of ids - * 2 bytes for length of extensions - * + length of ids - * + length of extensions - */ - if (CHECKLEN(ret, 9 + idlen + extlen, limit)) - return NULL; - - s2n(TLSEXT_TYPE_status_request, ret); - s2n(extlen + idlen + 5, ret); - *(ret++) = TLSEXT_STATUSTYPE_ocsp; - s2n(idlen, ret); - for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { - /* save position of id len */ - unsigned char *q = ret; - id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); - /* skip over id len */ - ret += 2; - lentmp = i2d_OCSP_RESPID(id, &ret); - /* write id len */ - s2n(lentmp, q); - } - s2n(extlen, ret); - if (extlen > 0) - i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret); - } -# ifndef OPENSSL_NO_HEARTBEATS - /* Add Heartbeat extension */ - - /*- - * check for enough space. - * 4 bytes for the heartbeat ext type and extension length - * 1 byte for the mode - */ - if (CHECKLEN(ret, 5, limit)) - return NULL; - - s2n(TLSEXT_TYPE_heartbeat, ret); - s2n(1, ret); - /*- - * Set mode: - * 1: peer may send requests - * 2: peer not allowed to send requests - */ - if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) - *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; - else - *(ret++) = SSL_TLSEXT_HB_ENABLED; -# endif - -# ifndef OPENSSL_NO_NEXTPROTONEG - if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) { - /* - * The client advertises an emtpy extension to indicate its support - * for Next Protocol Negotiation - */ - - /*- - * check for enough space. - * 4 bytes for the NPN ext type and extension length - */ - if (CHECKLEN(ret, 4, limit)) - return NULL; - s2n(TLSEXT_TYPE_next_proto_neg, ret); - s2n(0, ret); - } -# endif - - if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) { - /*- - * check for enough space. - * 4 bytes for the ALPN type and extension length - * 2 bytes for the ALPN protocol list length - * + ALPN protocol list length - */ - if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit)) - return NULL; - s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); - s2n(2 + s->alpn_client_proto_list_len, ret); - s2n(s->alpn_client_proto_list_len, ret); - memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len); - ret += s->alpn_client_proto_list_len; - s->cert->alpn_sent = 1; - } -# ifndef OPENSSL_NO_SRTP - if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { - int el; - - ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); - - /*- - * check for enough space. - * 4 bytes for the SRTP type and extension length - * + SRTP profiles length - */ - if (CHECKLEN(ret, 4 + el, limit)) - return NULL; - - s2n(TLSEXT_TYPE_use_srtp, ret); - s2n(el, ret); - - if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - ret += el; - } -# endif - custom_ext_init(&s->cert->cli_ext); - /* Add custom TLS Extensions to ClientHello */ - if (!custom_ext_add(s, 0, &ret, limit, al)) - return NULL; - - /* - * Add padding to workaround bugs in F5 terminators. See - * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this - * code works out the length of all existing extensions it MUST always - * appear last. - */ - if (s->options & SSL_OP_TLSEXT_PADDING) { - int hlen = ret - (unsigned char *)s->init_buf->data; - /* - * The code in s23_clnt.c to build ClientHello messages includes the - * 5-byte record header in the buffer, while the code in s3_clnt.c - * does not. - */ - if (s->state == SSL23_ST_CW_CLNT_HELLO_A) - hlen -= 5; - if (hlen > 0xff && hlen < 0x200) { - hlen = 0x200 - hlen; - if (hlen >= 4) - hlen -= 4; - else - hlen = 0; - - /*- - * check for enough space. Strictly speaking we know we've already - * got enough space because to get here the message size is < 0x200, - * but we know that we've allocated far more than that in the buffer - * - but for consistency and robustness we're going to check anyway. - * - * 4 bytes for the padding type and extension length - * + padding length - */ - if (CHECKLEN(ret, 4 + hlen, limit)) - return NULL; - s2n(TLSEXT_TYPE_padding, ret); - s2n(hlen, ret); - memset(ret, 0, hlen); - ret += hlen; - } - } - - if ((extdatalen = ret - orig - 2) == 0) - return orig; - - s2n(extdatalen, orig); - return ret; -} - -unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, - unsigned char *limit, int *al) -{ - int extdatalen = 0; - unsigned char *orig = buf; - unsigned char *ret = buf; -# ifndef OPENSSL_NO_NEXTPROTONEG - int next_proto_neg_seen; -# endif -# ifndef OPENSSL_NO_EC - unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; - int using_ecc = (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) - || (alg_a & SSL_aECDSA); - using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL); -# endif - /* - * don't add extensions for SSLv3, unless doing secure renegotiation - */ - if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) - return orig; - - ret += 2; - if (ret >= limit) - return NULL; /* this really never occurs, but ... */ - - if (!s->hit && s->servername_done == 1 - && s->session->tlsext_hostname != NULL) { - if ((long)(limit - ret - 4) < 0) - return NULL; - - s2n(TLSEXT_TYPE_server_name, ret); - s2n(0, ret); - } - - if (s->s3->send_connection_binding) { - int el; - - if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - /*- - * check for enough space. - * 4 bytes for the reneg type and extension length - * + reneg data length - */ - if (CHECKLEN(ret, 4 + el, limit)) - return NULL; - - s2n(TLSEXT_TYPE_renegotiate, ret); - s2n(el, ret); - - if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - ret += el; - } -# ifndef OPENSSL_NO_EC - if (using_ecc) { - const unsigned char *plist; - size_t plistlen; - /* - * Add TLS extension ECPointFormats to the ServerHello message - */ - - tls1_get_formatlist(s, &plist, &plistlen); - - if (plistlen > 255) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - - /*- - * check for enough space. - * 4 bytes for the ec points format type and extension length - * 1 byte for the points format list length - * + length of points format list - */ - if (CHECKLEN(ret, 5 + plistlen, limit)) - return NULL; - - s2n(TLSEXT_TYPE_ec_point_formats, ret); - s2n(plistlen + 1, ret); - *(ret++) = (unsigned char)plistlen; - memcpy(ret, plist, plistlen); - ret += plistlen; - - } - /* - * Currently the server should not respond with a SupportedCurves - * extension - */ -# endif /* OPENSSL_NO_EC */ - - if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) { - /*- - * check for enough space. - * 4 bytes for the Ticket type and extension length - */ - if (CHECKLEN(ret, 4, limit)) - return NULL; - s2n(TLSEXT_TYPE_session_ticket, ret); - s2n(0, ret); - } else { - /* if we don't add the above TLSEXT, we can't add a session ticket later */ - s->tlsext_ticket_expected = 0; - } - - if (s->tlsext_status_expected) { - /*- - * check for enough space. - * 4 bytes for the Status request type and extension length - */ - if (CHECKLEN(ret, 4, limit)) - return NULL; - s2n(TLSEXT_TYPE_status_request, ret); - s2n(0, ret); - } -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->server_opaque_prf_input != NULL) { - size_t sol = s->s3->server_opaque_prf_input_len; - - if ((long)(limit - ret - 6 - sol) < 0) - return NULL; - if (sol > 0xFFFD) /* can't happen */ - return NULL; - - s2n(TLSEXT_TYPE_opaque_prf_input, ret); - s2n(sol + 2, ret); - s2n(sol, ret); - memcpy(ret, s->s3->server_opaque_prf_input, sol); - ret += sol; - } -# endif - -# ifndef OPENSSL_NO_SRTP - if (SSL_IS_DTLS(s) && s->srtp_profile) { - int el; - - ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); - - /*- - * check for enough space. - * 4 bytes for the SRTP profiles type and extension length - * + length of the SRTP profiles list - */ - if (CHECKLEN(ret, 4 + el, limit)) - return NULL; - - s2n(TLSEXT_TYPE_use_srtp, ret); - s2n(el, ret); - - if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); - return NULL; - } - ret += el; - } -# endif - - if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80 - || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81) - && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) { - const unsigned char cryptopro_ext[36] = { - 0xfd, 0xe8, /* 65000 */ - 0x00, 0x20, /* 32 bytes length */ - 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, - 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, - 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, - 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 - }; - - /* check for enough space. */ - if (CHECKLEN(ret, sizeof(cryptopro_ext), limit)) - return NULL; - memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext)); - ret += sizeof(cryptopro_ext); - - } -# ifndef OPENSSL_NO_HEARTBEATS - /* Add Heartbeat extension if we've received one */ - if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) { - /*- - * check for enough space. - * 4 bytes for the Heartbeat type and extension length - * 1 byte for the mode - */ - if (CHECKLEN(ret, 5, limit)) - return NULL; - s2n(TLSEXT_TYPE_heartbeat, ret); - s2n(1, ret); - /*- - * Set mode: - * 1: peer may send requests - * 2: peer not allowed to send requests - */ - if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) - *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; - else - *(ret++) = SSL_TLSEXT_HB_ENABLED; - - } -# endif - -# ifndef OPENSSL_NO_NEXTPROTONEG - next_proto_neg_seen = s->s3->next_proto_neg_seen; - s->s3->next_proto_neg_seen = 0; - if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) { - const unsigned char *npa; - unsigned int npalen; - int r; - - r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, - s-> - ctx->next_protos_advertised_cb_arg); - if (r == SSL_TLSEXT_ERR_OK) { - /*- - * check for enough space. - * 4 bytes for the NPN type and extension length - * + length of protocols list - */ - if (CHECKLEN(ret, 4 + npalen, limit)) - return NULL; - s2n(TLSEXT_TYPE_next_proto_neg, ret); - s2n(npalen, ret); - memcpy(ret, npa, npalen); - ret += npalen; - s->s3->next_proto_neg_seen = 1; - } - } -# endif - if (!custom_ext_add(s, 1, &ret, limit, al)) - return NULL; - - if (s->s3->alpn_selected) { - const unsigned char *selected = s->s3->alpn_selected; - size_t len = s->s3->alpn_selected_len; - - /*- - * check for enough space. - * 4 bytes for the ALPN type and extension length - * 2 bytes for ALPN data length - * 1 byte for selected protocol length - * + length of the selected protocol - */ - if (CHECKLEN(ret, 7 + len, limit)) - return NULL; - s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); - s2n(3 + len, ret); - s2n(1 + len, ret); - *ret++ = (unsigned char)len; - memcpy(ret, selected, len); - ret += len; - } - - if ((extdatalen = ret - orig - 2) == 0) - return orig; - - s2n(extdatalen, orig); - return ret; -} - -# ifndef OPENSSL_NO_EC -/*- - * ssl_check_for_safari attempts to fingerprint Safari using OS X - * SecureTransport using the TLS extension block in |d|, of length |n|. - * Safari, since 10.6, sends exactly these extensions, in this order: - * SNI, - * elliptic_curves - * ec_point_formats - * - * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8, - * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them. - * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from - * 10.8..10.8.3 (which don't work). - */ -static void ssl_check_for_safari(SSL *s, const unsigned char *data, - const unsigned char *limit) -{ - unsigned short type, size; - static const unsigned char kSafariExtensionsBlock[] = { - 0x00, 0x0a, /* elliptic_curves extension */ - 0x00, 0x08, /* 8 bytes */ - 0x00, 0x06, /* 6 bytes of curve ids */ - 0x00, 0x17, /* P-256 */ - 0x00, 0x18, /* P-384 */ - 0x00, 0x19, /* P-521 */ - - 0x00, 0x0b, /* ec_point_formats */ - 0x00, 0x02, /* 2 bytes */ - 0x01, /* 1 point format */ - 0x00, /* uncompressed */ - }; - - /* The following is only present in TLS 1.2 */ - static const unsigned char kSafariTLS12ExtensionsBlock[] = { - 0x00, 0x0d, /* signature_algorithms */ - 0x00, 0x0c, /* 12 bytes */ - 0x00, 0x0a, /* 10 bytes */ - 0x05, 0x01, /* SHA-384/RSA */ - 0x04, 0x01, /* SHA-256/RSA */ - 0x02, 0x01, /* SHA-1/RSA */ - 0x04, 0x03, /* SHA-256/ECDSA */ - 0x02, 0x03, /* SHA-1/ECDSA */ - }; - - if (limit - data <= 2) - return; - data += 2; - - if (limit - data < 4) - return; - n2s(data, type); - n2s(data, size); - - if (type != TLSEXT_TYPE_server_name) - return; - - if (limit - data < size) - return; - data += size; - - if (TLS1_get_client_version(s) >= TLS1_2_VERSION) { - const size_t len1 = sizeof(kSafariExtensionsBlock); - const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); - - if (limit - data != (int)(len1 + len2)) - return; - if (memcmp(data, kSafariExtensionsBlock, len1) != 0) - return; - if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0) - return; - } else { - const size_t len = sizeof(kSafariExtensionsBlock); - - if (limit - data != (int)(len)) - return; - if (memcmp(data, kSafariExtensionsBlock, len) != 0) - return; - } - - s->s3->is_probably_safari = 1; -} -# endif /* !OPENSSL_NO_EC */ - -/* - * tls1_alpn_handle_client_hello is called to save the ALPN extension in a - * ClientHello. data: the contents of the extension, not including the type - * and length. data_len: the number of bytes in |data| al: a pointer to the - * alert value to send in the event of a non-zero return. returns: 0 on - * success. - */ -static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, - unsigned data_len, int *al) -{ - unsigned i; - unsigned proto_len; - - if (data_len < 2) - goto parse_error; - - /* - * data should contain a uint16 length followed by a series of 8-bit, - * length-prefixed strings. - */ - i = ((unsigned)data[0]) << 8 | ((unsigned)data[1]); - data_len -= 2; - data += 2; - if (data_len != i) - goto parse_error; - - if (data_len < 2) - goto parse_error; - - for (i = 0; i < data_len;) { - proto_len = data[i]; - i++; - - if (proto_len == 0) - goto parse_error; - - if (i + proto_len < i || i + proto_len > data_len) - goto parse_error; - - i += proto_len; - } - - if (s->cert->alpn_proposed != NULL) - OPENSSL_free(s->cert->alpn_proposed); - s->cert->alpn_proposed = OPENSSL_malloc(data_len); - if (s->cert->alpn_proposed == NULL) { - *al = SSL_AD_INTERNAL_ERROR; - return -1; - } - memcpy(s->cert->alpn_proposed, data, data_len); - s->cert->alpn_proposed_len = data_len; - return 0; - - parse_error: - *al = SSL_AD_DECODE_ERROR; - return -1; -} - -/* - * Process the ALPN extension in a ClientHello. - * al: a pointer to the alert value to send in the event of a failure. - * returns 1 on success, 0 on failure: al set only on failure - */ -static int tls1_alpn_handle_client_hello_late(SSL *s, int *al) -{ - const unsigned char *selected = NULL; - unsigned char selected_len = 0; - - if (s->ctx->alpn_select_cb != NULL && s->cert->alpn_proposed != NULL) { - int r = s->ctx->alpn_select_cb(s, &selected, &selected_len, - s->cert->alpn_proposed, - s->cert->alpn_proposed_len, - s->ctx->alpn_select_cb_arg); - - if (r == SSL_TLSEXT_ERR_OK) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = OPENSSL_malloc(selected_len); - if (s->s3->alpn_selected == NULL) { - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->s3->alpn_selected, selected, selected_len); - s->s3->alpn_selected_len = selected_len; -# ifndef OPENSSL_NO_NEXTPROTONEG - /* ALPN takes precedence over NPN. */ - s->s3->next_proto_neg_seen = 0; -# endif - } - } - - return 1; -} - -static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, - unsigned char *limit, int *al) -{ - unsigned short type; - unsigned short size; - unsigned short len; - unsigned char *data = *p; - int renegotiate_seen = 0; - - s->servername_done = 0; - s->tlsext_status_type = -1; -# ifndef OPENSSL_NO_NEXTPROTONEG - s->s3->next_proto_neg_seen = 0; -# endif - - if (s->s3->alpn_selected) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = NULL; - } - s->s3->alpn_selected_len = 0; - if (s->cert->alpn_proposed) { - OPENSSL_free(s->cert->alpn_proposed); - s->cert->alpn_proposed = NULL; - } - s->cert->alpn_proposed_len = 0; -# ifndef OPENSSL_NO_HEARTBEATS - s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | - SSL_TLSEXT_HB_DONT_SEND_REQUESTS); -# endif - -# ifndef OPENSSL_NO_EC - if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) - ssl_check_for_safari(s, data, limit); -# endif /* !OPENSSL_NO_EC */ - - /* Clear any signature algorithms extension received */ - if (s->cert->peer_sigalgs) { - OPENSSL_free(s->cert->peer_sigalgs); - s->cert->peer_sigalgs = NULL; - } -# ifndef OPENSSL_NO_SRP - if (s->srp_ctx.login != NULL) { - OPENSSL_free(s->srp_ctx.login); - s->srp_ctx.login = NULL; - } -# endif - - s->srtp_profile = NULL; - - if (data == limit) - goto ri_check; - - if (limit - data < 2) - goto err; - - n2s(data, len); - - if (limit - data != len) - goto err; - - while (limit - data >= 4) { - n2s(data, type); - n2s(data, size); - - if (limit - data < size) - goto err; -# if 0 - fprintf(stderr, "Received extension type %d size %d\n", type, size); -# endif - if (s->tlsext_debug_cb) - s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); -/*- - * The servername extension is treated as follows: - * - * - Only the hostname type is supported with a maximum length of 255. - * - The servername is rejected if too long or if it contains zeros, - * in which case an fatal alert is generated. - * - The servername field is maintained together with the session cache. - * - When a session is resumed, the servername call back invoked in order - * to allow the application to position itself to the right context. - * - The servername is acknowledged if it is new for a session or when - * it is identical to a previously used for the same session. - * Applications can control the behaviour. They can at any time - * set a 'desirable' servername for a new SSL object. This can be the - * case for example with HTTPS when a Host: header field is received and - * a renegotiation is requested. In this case, a possible servername - * presented in the new client hello is only acknowledged if it matches - * the value of the Host: field. - * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION - * if they provide for changing an explicit servername context for the - * session, i.e. when the session has been established with a servername - * extension. - * - On session reconnect, the servername extension may be absent. - * - */ - - if (type == TLSEXT_TYPE_server_name) { - unsigned char *sdata; - int servname_type; - int dsize; - - if (size < 2) - goto err; - n2s(data, dsize); - size -= 2; - if (dsize > size) - goto err; - - sdata = data; - while (dsize > 3) { - servname_type = *(sdata++); - n2s(sdata, len); - dsize -= 3; - - if (len > dsize) - goto err; - - if (s->servername_done == 0) - switch (servname_type) { - case TLSEXT_NAMETYPE_host_name: - if (!s->hit) { - if (s->session->tlsext_hostname) - goto err; - - if (len > TLSEXT_MAXLEN_host_name) { - *al = TLS1_AD_UNRECOGNIZED_NAME; - return 0; - } - if ((s->session->tlsext_hostname = - OPENSSL_malloc(len + 1)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->session->tlsext_hostname, sdata, len); - s->session->tlsext_hostname[len] = '\0'; - if (strlen(s->session->tlsext_hostname) != len) { - OPENSSL_free(s->session->tlsext_hostname); - s->session->tlsext_hostname = NULL; - *al = TLS1_AD_UNRECOGNIZED_NAME; - return 0; - } - s->servername_done = 1; - - } else - s->servername_done = s->session->tlsext_hostname - && strlen(s->session->tlsext_hostname) == len - && strncmp(s->session->tlsext_hostname, - (char *)sdata, len) == 0; - - break; - - default: - break; - } - - dsize -= len; - } - if (dsize != 0) - goto err; - - } -# ifndef OPENSSL_NO_SRP - else if (type == TLSEXT_TYPE_srp) { - if (size == 0 || ((len = data[0])) != (size - 1)) - goto err; - if (s->srp_ctx.login != NULL) - goto err; - if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL) - return -1; - memcpy(s->srp_ctx.login, &data[1], len); - s->srp_ctx.login[len] = '\0'; - - if (strlen(s->srp_ctx.login) != len) - goto err; - } -# endif - -# ifndef OPENSSL_NO_EC - else if (type == TLSEXT_TYPE_ec_point_formats) { - unsigned char *sdata = data; - int ecpointformatlist_length; - - if (size == 0) - goto err; - - ecpointformatlist_length = *(sdata++); - if (ecpointformatlist_length != size - 1 || - ecpointformatlist_length < 1) - goto err; - if (!s->hit) { - if (s->session->tlsext_ecpointformatlist) { - OPENSSL_free(s->session->tlsext_ecpointformatlist); - s->session->tlsext_ecpointformatlist = NULL; - } - s->session->tlsext_ecpointformatlist_length = 0; - if ((s->session->tlsext_ecpointformatlist = - OPENSSL_malloc(ecpointformatlist_length)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - s->session->tlsext_ecpointformatlist_length = - ecpointformatlist_length; - memcpy(s->session->tlsext_ecpointformatlist, sdata, - ecpointformatlist_length); - } -# if 0 - fprintf(stderr, - "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", - s->session->tlsext_ecpointformatlist_length); - sdata = s->session->tlsext_ecpointformatlist; - for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif - } else if (type == TLSEXT_TYPE_elliptic_curves) { - unsigned char *sdata = data; - int ellipticcurvelist_length = (*(sdata++) << 8); - ellipticcurvelist_length += (*(sdata++)); - - if (ellipticcurvelist_length != size - 2 || - ellipticcurvelist_length < 1 || - /* Each NamedCurve is 2 bytes. */ - ellipticcurvelist_length & 1) - goto err; - - if (!s->hit) { - if (s->session->tlsext_ellipticcurvelist) - goto err; - - s->session->tlsext_ellipticcurvelist_length = 0; - if ((s->session->tlsext_ellipticcurvelist = - OPENSSL_malloc(ellipticcurvelist_length)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - s->session->tlsext_ellipticcurvelist_length = - ellipticcurvelist_length; - memcpy(s->session->tlsext_ellipticcurvelist, sdata, - ellipticcurvelist_length); - } -# if 0 - fprintf(stderr, - "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", - s->session->tlsext_ellipticcurvelist_length); - sdata = s->session->tlsext_ellipticcurvelist; - for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif - } -# endif /* OPENSSL_NO_EC */ -# ifdef TLSEXT_TYPE_opaque_prf_input - else if (type == TLSEXT_TYPE_opaque_prf_input) { - unsigned char *sdata = data; - - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - n2s(sdata, s->s3->client_opaque_prf_input_len); - if (s->s3->client_opaque_prf_input_len != size - 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - if (s->s3->client_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->client_opaque_prf_input); - } - - /* dummy byte just to get non-NULL */ - if (s->s3->client_opaque_prf_input_len == 0) - s->s3->client_opaque_prf_input = OPENSSL_malloc(1); - else - s->s3->client_opaque_prf_input = - BUF_memdup(sdata, s->s3->client_opaque_prf_input_len); - if (s->s3->client_opaque_prf_input == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - } -# endif - else if (type == TLSEXT_TYPE_session_ticket) { - if (s->tls_session_ticket_ext_cb && - !s->tls_session_ticket_ext_cb(s, data, size, - s->tls_session_ticket_ext_cb_arg)) - { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - } else if (type == TLSEXT_TYPE_renegotiate) { - if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) - return 0; - renegotiate_seen = 1; - } else if (type == TLSEXT_TYPE_signature_algorithms) { - int dsize; - if (s->cert->peer_sigalgs || size < 2) - goto err; - n2s(data, dsize); - size -= 2; - if (dsize != size || dsize & 1 || !dsize) - goto err; - if (!tls1_save_sigalgs(s, data, dsize)) - goto err; - } else if (type == TLSEXT_TYPE_status_request && !s->hit) { - if (size < 5) - goto err; - - s->tlsext_status_type = *data++; - size--; - if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { - const unsigned char *sdata; - int dsize; - /* Read in responder_id_list */ - n2s(data, dsize); - size -= 2; - if (dsize > size) - goto err; - - /* - * We remove any OCSP_RESPIDs from a previous handshake - * to prevent unbounded memory growth - CVE-2016-6304 - */ - sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, - OCSP_RESPID_free); - if (dsize > 0) { - s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); - if (s->tlsext_ocsp_ids == NULL) { - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - } else { - s->tlsext_ocsp_ids = NULL; - } - - while (dsize > 0) { - OCSP_RESPID *id; - int idsize; - if (dsize < 4) - goto err; - n2s(data, idsize); - dsize -= 2 + idsize; - size -= 2 + idsize; - if (dsize < 0) - goto err; - sdata = data; - data += idsize; - id = d2i_OCSP_RESPID(NULL, &sdata, idsize); - if (!id) - goto err; - if (data != sdata) { - OCSP_RESPID_free(id); - goto err; - } - if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { - OCSP_RESPID_free(id); - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - } - - /* Read in request_extensions */ - if (size < 2) - goto err; - n2s(data, dsize); - size -= 2; - if (dsize != size) - goto err; - sdata = data; - if (dsize > 0) { - if (s->tlsext_ocsp_exts) { - sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, - X509_EXTENSION_free); - } - - s->tlsext_ocsp_exts = - d2i_X509_EXTENSIONS(NULL, &sdata, dsize); - if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) - goto err; - } - } - /* - * We don't know what to do with any other type * so ignore it. - */ - else - s->tlsext_status_type = -1; - } -# ifndef OPENSSL_NO_HEARTBEATS - else if (type == TLSEXT_TYPE_heartbeat) { - switch (data[0]) { - case 0x01: /* Client allows us to send HB requests */ - s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; - break; - case 0x02: /* Client doesn't accept HB requests */ - s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; - s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; - break; - default: - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - } -# endif -# ifndef OPENSSL_NO_NEXTPROTONEG - else if (type == TLSEXT_TYPE_next_proto_neg && - s->s3->tmp.finish_md_len == 0) { - /*- - * We shouldn't accept this extension on a - * renegotiation. - * - * s->new_session will be set on renegotiation, but we - * probably shouldn't rely that it couldn't be set on - * the initial renegotation too in certain cases (when - * there's some other reason to disallow resuming an - * earlier session -- the current code won't be doing - * anything like that, but this might change). - * - * A valid sign that there's been a previous handshake - * in this connection is if s->s3->tmp.finish_md_len > - * 0. (We are talking about a check that will happen - * in the Hello protocol round, well before a new - * Finished message could have been computed.) - */ - s->s3->next_proto_neg_seen = 1; - } -# endif - - else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation && - s->s3->tmp.finish_md_len == 0) { - if (tls1_alpn_handle_client_hello(s, data, size, al) != 0) - return 0; - } - - /* session ticket processed earlier */ -# ifndef OPENSSL_NO_SRTP - else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) - && type == TLSEXT_TYPE_use_srtp) { - if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) - return 0; - } -# endif - - data += size; - } - - /* Spurious data on the end */ - if (data != limit) - goto err; - - *p = data; - - ri_check: - - /* Need RI if renegotiating */ - - if (!renegotiate_seen && s->renegotiate && - !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - *al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - return 0; - } - - return 1; -err: - *al = SSL_AD_DECODE_ERROR; - return 0; -} - -/* - * Parse any custom extensions found. "data" is the start of the extension data - * and "limit" is the end of the record. TODO: add strict syntax checking. - */ - -static int ssl_scan_clienthello_custom_tlsext(SSL *s, - const unsigned char *data, - const unsigned char *limit, - int *al) -{ - unsigned short type, size, len; - /* If resumed session or no custom extensions nothing to do */ - if (s->hit || s->cert->srv_ext.meths_count == 0) - return 1; - - if (limit - data <= 2) - return 1; - n2s(data, len); - - if (limit - data < len) - return 1; - - while (limit - data >= 4) { - n2s(data, type); - n2s(data, size); - - if (limit - data < size) - return 1; - if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0) - return 0; - - data += size; - } - - return 1; -} - -int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, - unsigned char *limit) -{ - int al = -1; - unsigned char *ptmp = *p; - /* - * Internally supported extensions are parsed first so SNI can be handled - * before custom extensions. An application processing SNI will typically - * switch the parent context using SSL_set_SSL_CTX and custom extensions - * need to be handled by the new SSL_CTX structure. - */ - if (ssl_scan_clienthello_tlsext(s, p, limit, &al) <= 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; - } - - if (ssl_check_clienthello_tlsext_early(s) <= 0) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_CLIENTHELLO_TLSEXT); - return 0; - } - - custom_ext_init(&s->cert->srv_ext); - if (ssl_scan_clienthello_custom_tlsext(s, ptmp, limit, &al) <= 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; - } - - return 1; -} - -# ifndef OPENSSL_NO_NEXTPROTONEG -/* - * ssl_next_proto_validate validates a Next Protocol Negotiation block. No - * elements of zero length are allowed and the set of elements must exactly - * fill the length of the block. - */ -static char ssl_next_proto_validate(unsigned char *d, unsigned len) -{ - unsigned int off = 0; - - while (off < len) { - if (d[off] == 0) - return 0; - off += d[off]; - off++; - } - - return off == len; -} -# endif - -static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, - unsigned char *d, int n, int *al) -{ - unsigned short length; - unsigned short type; - unsigned short size; - unsigned char *data = *p; - int tlsext_servername = 0; - int renegotiate_seen = 0; - -# ifndef OPENSSL_NO_NEXTPROTONEG - s->s3->next_proto_neg_seen = 0; -# endif - s->tlsext_ticket_expected = 0; - - if (s->s3->alpn_selected) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = NULL; - } -# ifndef OPENSSL_NO_HEARTBEATS - s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | - SSL_TLSEXT_HB_DONT_SEND_REQUESTS); -# endif - - if ((d + n) - data <= 2) - goto ri_check; - - n2s(data, length); - if ((d + n) - data != length) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - while ((d + n) - data >= 4) { - n2s(data, type); - n2s(data, size); - - if ((d + n) - data < size) - goto ri_check; - - if (s->tlsext_debug_cb) - s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg); - - if (type == TLSEXT_TYPE_server_name) { - if (s->tlsext_hostname == NULL || size > 0) { - *al = TLS1_AD_UNRECOGNIZED_NAME; - return 0; - } - tlsext_servername = 1; - } -# ifndef OPENSSL_NO_EC - else if (type == TLSEXT_TYPE_ec_point_formats) { - unsigned char *sdata = data; - int ecpointformatlist_length; - - if (size == 0) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - - ecpointformatlist_length = *(sdata++); - if (ecpointformatlist_length != size - 1) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - if (!s->hit) { - s->session->tlsext_ecpointformatlist_length = 0; - if (s->session->tlsext_ecpointformatlist != NULL) - OPENSSL_free(s->session->tlsext_ecpointformatlist); - if ((s->session->tlsext_ecpointformatlist = - OPENSSL_malloc(ecpointformatlist_length)) == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - s->session->tlsext_ecpointformatlist_length = - ecpointformatlist_length; - memcpy(s->session->tlsext_ecpointformatlist, sdata, - ecpointformatlist_length); - } -# if 0 - fprintf(stderr, - "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); - sdata = s->session->tlsext_ecpointformatlist; - for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) - fprintf(stderr, "%i ", *(sdata++)); - fprintf(stderr, "\n"); -# endif - } -# endif /* OPENSSL_NO_EC */ - - else if (type == TLSEXT_TYPE_session_ticket) { - if (s->tls_session_ticket_ext_cb && - !s->tls_session_ticket_ext_cb(s, data, size, - s->tls_session_ticket_ext_cb_arg)) - { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - if ((SSL_get_options(s) & SSL_OP_NO_TICKET) - || (size > 0)) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - s->tlsext_ticket_expected = 1; - } -# ifdef TLSEXT_TYPE_opaque_prf_input - else if (type == TLSEXT_TYPE_opaque_prf_input) { - unsigned char *sdata = data; - - if (size < 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - n2s(sdata, s->s3->server_opaque_prf_input_len); - if (s->s3->server_opaque_prf_input_len != size - 2) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - if (s->s3->server_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->server_opaque_prf_input); - } - if (s->s3->server_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->server_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->server_opaque_prf_input = - BUF_memdup(sdata, s->s3->server_opaque_prf_input_len); - } - - if (s->s3->server_opaque_prf_input == NULL) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - } -# endif - else if (type == TLSEXT_TYPE_status_request) { - /* - * MUST be empty and only sent if we've requested a status - * request message. - */ - if ((s->tlsext_status_type == -1) || (size > 0)) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - /* Set flag to expect CertificateStatus message */ - s->tlsext_status_expected = 1; - } -# ifndef OPENSSL_NO_NEXTPROTONEG - else if (type == TLSEXT_TYPE_next_proto_neg && - s->s3->tmp.finish_md_len == 0) { - unsigned char *selected; - unsigned char selected_len; - - /* We must have requested it. */ - if (s->ctx->next_proto_select_cb == NULL) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - /* The data must be valid */ - if (!ssl_next_proto_validate(data, size)) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - if (s-> - ctx->next_proto_select_cb(s, &selected, &selected_len, data, - size, - s->ctx->next_proto_select_cb_arg) != - SSL_TLSEXT_ERR_OK) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - /* - * Could be non-NULL if server has sent multiple NPN extensions in - * a single Serverhello - */ - OPENSSL_free(s->next_proto_negotiated); - s->next_proto_negotiated = OPENSSL_malloc(selected_len); - if (!s->next_proto_negotiated) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->next_proto_negotiated, selected, selected_len); - s->next_proto_negotiated_len = selected_len; - s->s3->next_proto_neg_seen = 1; - } -# endif - - else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation) { - unsigned len; - - /* We must have requested it. */ - if (!s->cert->alpn_sent) { - *al = TLS1_AD_UNSUPPORTED_EXTENSION; - return 0; - } - if (size < 4) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - /*- - * The extension data consists of: - * uint16 list_length - * uint8 proto_length; - * uint8 proto[proto_length]; - */ - len = data[0]; - len <<= 8; - len |= data[1]; - if (len != (unsigned)size - 2) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - len = data[2]; - if (len != (unsigned)size - 3) { - *al = TLS1_AD_DECODE_ERROR; - return 0; - } - if (s->s3->alpn_selected) - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = OPENSSL_malloc(len); - if (!s->s3->alpn_selected) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; - } - memcpy(s->s3->alpn_selected, data + 3, len); - s->s3->alpn_selected_len = len; - } - - else if (type == TLSEXT_TYPE_renegotiate) { - if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) - return 0; - renegotiate_seen = 1; - } -# ifndef OPENSSL_NO_HEARTBEATS - else if (type == TLSEXT_TYPE_heartbeat) { - switch (data[0]) { - case 0x01: /* Server allows us to send HB requests */ - s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; - break; - case 0x02: /* Server doesn't accept HB requests */ - s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; - s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; - break; - default: - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - } -# endif -# ifndef OPENSSL_NO_SRTP - else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { - if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al)) - return 0; - } -# endif - /* - * If this extension type was not otherwise handled, but matches a - * custom_cli_ext_record, then send it to the c callback - */ - else if (custom_ext_parse(s, 0, type, data, size, al) <= 0) - return 0; - - data += size; - } - - if (data != d + n) { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - - if (!s->hit && tlsext_servername == 1) { - if (s->tlsext_hostname) { - if (s->session->tlsext_hostname == NULL) { - s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname); - if (!s->session->tlsext_hostname) { - *al = SSL_AD_UNRECOGNIZED_NAME; - return 0; - } - } else { - *al = SSL_AD_DECODE_ERROR; - return 0; - } - } - } - - *p = data; - - ri_check: - - /* - * Determine if we need to see RI. Strictly speaking if we want to avoid - * an attack we should *always* see RI even on initial server hello - * because the client doesn't see any renegotiation during an attack. - * However this would mean we could not connect to any server which - * doesn't support RI so for the immediate future tolerate RI absence on - * initial connect only. - */ - if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) - && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - *al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - return 0; - } - - return 1; -} - -int ssl_prepare_clienthello_tlsext(SSL *s) -{ - -# ifdef TLSEXT_TYPE_opaque_prf_input - { - int r = 1; - - if (s->ctx->tlsext_opaque_prf_input_callback != 0) { - r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, - s-> - ctx->tlsext_opaque_prf_input_callback_arg); - if (!r) - return -1; - } - - if (s->tlsext_opaque_prf_input != NULL) { - if (s->s3->client_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->client_opaque_prf_input); - } - - if (s->tlsext_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->client_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->client_opaque_prf_input = - BUF_memdup(s->tlsext_opaque_prf_input, - s->tlsext_opaque_prf_input_len); - } - if (s->s3->client_opaque_prf_input == NULL) { - SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT, - ERR_R_MALLOC_FAILURE); - return -1; - } - s->s3->client_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } - - if (r == 2) - /* - * at callback's request, insist on receiving an appropriate - * server opaque PRF input - */ - s->s3->server_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } -# endif - - s->cert->alpn_sent = 0; - return 1; -} - -int ssl_prepare_serverhello_tlsext(SSL *s) -{ - return 1; -} - -static int ssl_check_clienthello_tlsext_early(SSL *s) -{ - int ret = SSL_TLSEXT_ERR_NOACK; - int al = SSL_AD_UNRECOGNIZED_NAME; - -# ifndef OPENSSL_NO_EC - /* - * The handling of the ECPointFormats extension is done elsewhere, namely - * in ssl3_choose_cipher in s3_lib.c. - */ - /* - * The handling of the EllipticCurves extension is done elsewhere, namely - * in ssl3_choose_cipher in s3_lib.c. - */ -# endif - - if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) - ret = - s->ctx->tlsext_servername_callback(s, &al, - s->ctx->tlsext_servername_arg); - else if (s->initial_ctx != NULL - && s->initial_ctx->tlsext_servername_callback != 0) - ret = - s->initial_ctx->tlsext_servername_callback(s, &al, - s-> - initial_ctx->tlsext_servername_arg); - -# ifdef TLSEXT_TYPE_opaque_prf_input - { - /* - * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we - * might be sending an alert in response to the client hello, so this - * has to happen here in ssl_check_clienthello_tlsext_early(). - */ - - int r = 1; - - if (s->ctx->tlsext_opaque_prf_input_callback != 0) { - r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, - s-> - ctx->tlsext_opaque_prf_input_callback_arg); - if (!r) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - } - - if (s->s3->server_opaque_prf_input != NULL) { - /* shouldn't really happen */ - OPENSSL_free(s->s3->server_opaque_prf_input); - } - s->s3->server_opaque_prf_input = NULL; - - if (s->tlsext_opaque_prf_input != NULL) { - if (s->s3->client_opaque_prf_input != NULL && - s->s3->client_opaque_prf_input_len == - s->tlsext_opaque_prf_input_len) { - /* - * can only use this extension if we have a server opaque PRF - * input of the same length as the client opaque PRF input! - */ - - if (s->tlsext_opaque_prf_input_len == 0) { - /* dummy byte just to get non-NULL */ - s->s3->server_opaque_prf_input = OPENSSL_malloc(1); - } else { - s->s3->server_opaque_prf_input = - BUF_memdup(s->tlsext_opaque_prf_input, - s->tlsext_opaque_prf_input_len); - } - if (s->s3->server_opaque_prf_input == NULL) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - s->s3->server_opaque_prf_input_len = - s->tlsext_opaque_prf_input_len; - } - } - - if (r == 2 && s->s3->server_opaque_prf_input == NULL) { - /* - * The callback wants to enforce use of the extension, but we - * can't do that with the client opaque PRF input; abort the - * handshake. - */ - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_HANDSHAKE_FAILURE; - } - } - - err: -# endif - switch (ret) { - case SSL_TLSEXT_ERR_ALERT_FATAL: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return -1; - - case SSL_TLSEXT_ERR_ALERT_WARNING: - ssl3_send_alert(s, SSL3_AL_WARNING, al); - return 1; - - case SSL_TLSEXT_ERR_NOACK: - s->servername_done = 0; - default: - return 1; - } -} - -int tls1_set_server_sigalgs(SSL *s) -{ - int al; - size_t i; - /* Clear any shared sigtnature algorithms */ - if (s->cert->shared_sigalgs) { - OPENSSL_free(s->cert->shared_sigalgs); - s->cert->shared_sigalgs = NULL; - s->cert->shared_sigalgslen = 0; - } - /* Clear certificate digests and validity flags */ - for (i = 0; i < SSL_PKEY_NUM; i++) { - s->cert->pkeys[i].digest = NULL; - s->cert->pkeys[i].valid_flags = 0; - } - - /* If sigalgs received process it. */ - if (s->cert->peer_sigalgs) { - if (!tls1_process_sigalgs(s)) { - SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, ERR_R_MALLOC_FAILURE); - al = SSL_AD_INTERNAL_ERROR; - goto err; - } - /* Fatal error is no shared signature algorithms */ - if (!s->cert->shared_sigalgs) { - SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, - SSL_R_NO_SHARED_SIGATURE_ALGORITHMS); - al = SSL_AD_HANDSHAKE_FAILURE; - goto err; - } - } else - ssl_cert_set_default_md(s->cert); - return 1; - err: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; -} - -/* - * Upon success, returns 1. - * Upon failure, returns 0 and sets |al| to the appropriate fatal alert. - */ -int ssl_check_clienthello_tlsext_late(SSL *s, int *al) -{ - - /* - * If status request then ask callback what to do. Note: this must be - * called after servername callbacks in case the certificate has changed, - * and must be called after the cipher has been chosen because this may - * influence which certificate is sent - */ - if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) { - int ret; - CERT_PKEY *certpkey; - certpkey = ssl_get_server_send_pkey(s); - /* If no certificate can't return certificate status */ - if (certpkey != NULL) { - /* - * Set current certificate to one we will use so SSL_get_certificate - * et al can pick it up. - */ - s->cert->key = certpkey; - ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - switch (ret) { - /* We don't want to send a status request response */ - case SSL_TLSEXT_ERR_NOACK: - s->tlsext_status_expected = 0; - break; - /* status request response should be sent */ - case SSL_TLSEXT_ERR_OK: - if (s->tlsext_ocsp_resp) - s->tlsext_status_expected = 1; - break; - /* something bad happened */ - case SSL_TLSEXT_ERR_ALERT_FATAL: - default: - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - } - } - - if (!tls1_alpn_handle_client_hello_late(s, al)) { - return 0; - } - - return 1; -} - -int ssl_check_serverhello_tlsext(SSL *s) -{ - int ret = SSL_TLSEXT_ERR_NOACK; - int al = SSL_AD_UNRECOGNIZED_NAME; - -# ifndef OPENSSL_NO_EC - /* - * If we are client and using an elliptic curve cryptography cipher - * suite, then if server returns an EC point formats lists extension it - * must contain uncompressed. - */ - unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; - unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; - if ((s->tlsext_ecpointformatlist != NULL) - && (s->tlsext_ecpointformatlist_length > 0) - && (s->session->tlsext_ecpointformatlist != NULL) - && (s->session->tlsext_ecpointformatlist_length > 0) - && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) - || (alg_a & SSL_aECDSA))) { - /* we are using an ECC cipher */ - size_t i; - unsigned char *list; - int found_uncompressed = 0; - list = s->session->tlsext_ecpointformatlist; - for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) { - if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) { - found_uncompressed = 1; - break; - } - } - if (!found_uncompressed) { - SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT, - SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); - return -1; - } - } - ret = SSL_TLSEXT_ERR_OK; -# endif /* OPENSSL_NO_EC */ - - if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) - ret = - s->ctx->tlsext_servername_callback(s, &al, - s->ctx->tlsext_servername_arg); - else if (s->initial_ctx != NULL - && s->initial_ctx->tlsext_servername_callback != 0) - ret = - s->initial_ctx->tlsext_servername_callback(s, &al, - s-> - initial_ctx->tlsext_servername_arg); - -# ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->server_opaque_prf_input_len > 0) { - /* - * This case may indicate that we, as a client, want to insist on - * using opaque PRF inputs. So first verify that we really have a - * value from the server too. - */ - - if (s->s3->server_opaque_prf_input == NULL) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_HANDSHAKE_FAILURE; - } - - /* - * Anytime the server *has* sent an opaque PRF input, we need to - * check that we have a client opaque PRF input of the same size. - */ - if (s->s3->client_opaque_prf_input == NULL || - s->s3->client_opaque_prf_input_len != - s->s3->server_opaque_prf_input_len) { - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_ILLEGAL_PARAMETER; - } - } -# endif - - OPENSSL_free(s->tlsext_ocsp_resp); - s->tlsext_ocsp_resp = NULL; - s->tlsext_ocsp_resplen = -1; - /* - * If we've requested certificate status and we wont get one tell the - * callback - */ - if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected) - && !(s->hit) && s->ctx && s->ctx->tlsext_status_cb) { - int r; - /* - * Call callback with resp == NULL and resplen == -1 so callback - * knows there is no response - */ - r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - if (r == 0) { - al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - } - if (r < 0) { - al = SSL_AD_INTERNAL_ERROR; - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - } - } - - switch (ret) { - case SSL_TLSEXT_ERR_ALERT_FATAL: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return -1; - - case SSL_TLSEXT_ERR_ALERT_WARNING: - ssl3_send_alert(s, SSL3_AL_WARNING, al); - return 1; - - case SSL_TLSEXT_ERR_NOACK: - s->servername_done = 0; - default: - return 1; - } -} - -int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, - int n) -{ - int al = -1; - if (s->version < SSL3_VERSION) - return 1; - if (ssl_scan_serverhello_tlsext(s, p, d, n, &al) <= 0) { - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return 0; - } - - if (ssl_check_serverhello_tlsext(s) <= 0) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_SERVERHELLO_TLSEXT); - return 0; - } - return 1; -} - -/*- - * Since the server cache lookup is done early on in the processing of the - * ClientHello, and other operations depend on the result, we need to handle - * any TLS session ticket extension at the same time. - * - * session_id: points at the session ID in the ClientHello. This code will - * read past the end of this in order to parse out the session ticket - * extension, if any. - * len: the length of the session ID. - * limit: a pointer to the first byte after the ClientHello. - * ret: (output) on return, if a ticket was decrypted, then this is set to - * point to the resulting session. - * - * If s->tls_session_secret_cb is set then we are expecting a pre-shared key - * ciphersuite, in which case we have no use for session tickets and one will - * never be decrypted, nor will s->tlsext_ticket_expected be set to 1. - * - * Returns: - * -1: fatal error, either from parsing or decrypting the ticket. - * 0: no ticket was found (or was ignored, based on settings). - * 1: a zero length extension was found, indicating that the client supports - * session tickets but doesn't currently have one to offer. - * 2: either s->tls_session_secret_cb was set, or a ticket was offered but - * couldn't be decrypted because of a non-fatal error. - * 3: a ticket was successfully decrypted and *ret was set. - * - * Side effects: - * Sets s->tlsext_ticket_expected to 1 if the server will have to issue - * a new session ticket to the client because the client indicated support - * (and s->tls_session_secret_cb is NULL) but the client either doesn't have - * a session ticket or we couldn't use the one it gave us, or if - * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket. - * Otherwise, s->tlsext_ticket_expected is set to 0. - */ -int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, - const unsigned char *limit, SSL_SESSION **ret) -{ - /* Point after session ID in client hello */ - const unsigned char *p = session_id + len; - unsigned short i; - - *ret = NULL; - s->tlsext_ticket_expected = 0; - - /* - * If tickets disabled behave as if no ticket present to permit stateful - * resumption. - */ - if (SSL_get_options(s) & SSL_OP_NO_TICKET) - return 0; - if ((s->version <= SSL3_VERSION) || !limit) - return 0; - if (p >= limit) - return -1; - /* Skip past DTLS cookie */ - if (SSL_IS_DTLS(s)) { - i = *(p++); - - if (limit - p <= i) - return -1; - - p += i; - } - /* Skip past cipher list */ - n2s(p, i); - if (limit - p <= i) - return -1; - p += i; - - /* Skip past compression algorithm list */ - i = *(p++); - if (limit - p < i) - return -1; - p += i; - - /* Now at start of extensions */ - if (limit - p <= 2) - return 0; - n2s(p, i); - while (limit - p >= 4) { - unsigned short type, size; - n2s(p, type); - n2s(p, size); - if (limit - p < size) - return 0; - if (type == TLSEXT_TYPE_session_ticket) { - int r; - if (size == 0) { - /* - * The client will accept a ticket but doesn't currently have - * one. - */ - s->tlsext_ticket_expected = 1; - return 1; - } - if (s->tls_session_secret_cb) { - /* - * Indicate that the ticket couldn't be decrypted rather than - * generating the session from ticket now, trigger - * abbreviated handshake based on external mechanism to - * calculate the master secret later. - */ - return 2; - } - r = tls_decrypt_ticket(s, p, size, session_id, len, ret); - switch (r) { - case 2: /* ticket couldn't be decrypted */ - s->tlsext_ticket_expected = 1; - return 2; - case 3: /* ticket was decrypted */ - return r; - case 4: /* ticket decrypted but need to renew */ - s->tlsext_ticket_expected = 1; - return 3; - default: /* fatal error */ - return -1; - } - } - p += size; - } - return 0; -} - -/*- - * tls_decrypt_ticket attempts to decrypt a session ticket. - * - * etick: points to the body of the session ticket extension. - * eticklen: the length of the session tickets extenion. - * sess_id: points at the session ID. - * sesslen: the length of the session ID. - * psess: (output) on return, if a ticket was decrypted, then this is set to - * point to the resulting session. - * - * Returns: - * -1: fatal error, either from parsing or decrypting the ticket. - * 2: the ticket couldn't be decrypted. - * 3: a ticket was successfully decrypted and *psess was set. - * 4: same as 3, but the ticket needs to be renewed. - */ -static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, - int eticklen, const unsigned char *sess_id, - int sesslen, SSL_SESSION **psess) -{ - SSL_SESSION *sess; - unsigned char *sdec; - const unsigned char *p; - int slen, mlen, renew_ticket = 0; - unsigned char tick_hmac[EVP_MAX_MD_SIZE]; - HMAC_CTX hctx; - EVP_CIPHER_CTX ctx; - SSL_CTX *tctx = s->initial_ctx; - - /* Need at least keyname + iv */ - if (eticklen < 16 + EVP_MAX_IV_LENGTH) - return 2; - - /* Initialize session ticket encryption and HMAC contexts */ - HMAC_CTX_init(&hctx); - EVP_CIPHER_CTX_init(&ctx); - if (tctx->tlsext_ticket_key_cb) { - unsigned char *nctick = (unsigned char *)etick; - int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, - &ctx, &hctx, 0); - if (rv < 0) - goto err; - if (rv == 0) { - HMAC_CTX_cleanup(&hctx); - EVP_CIPHER_CTX_cleanup(&ctx); - return 2; - } - if (rv == 2) - renew_ticket = 1; - } else { - /* Check key name matches */ - if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) - return 2; - if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, - tlsext_tick_md(), NULL) <= 0 - || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, - tctx->tlsext_tick_aes_key, - etick + 16) <= 0) { - goto err; - } - } - /* - * Attempt to process session ticket, first conduct sanity and integrity - * checks on ticket. - */ - mlen = HMAC_size(&hctx); - if (mlen < 0) { - goto err; - } - /* Sanity check ticket length: must exceed keyname + IV + HMAC */ - if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { - HMAC_CTX_cleanup(&hctx); - EVP_CIPHER_CTX_cleanup(&ctx); - return 2; - } - - eticklen -= mlen; - /* Check HMAC of encrypted ticket */ - if (HMAC_Update(&hctx, etick, eticklen) <= 0 - || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) { - goto err; - } - HMAC_CTX_cleanup(&hctx); - if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) { - EVP_CIPHER_CTX_cleanup(&ctx); - return 2; - } - /* Attempt to decrypt session data */ - /* Move p after IV to start of encrypted ticket, update length */ - p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); - eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); - sdec = OPENSSL_malloc(eticklen); - if (sdec == NULL - || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) { - EVP_CIPHER_CTX_cleanup(&ctx); - OPENSSL_free(sdec); - return -1; - } - if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) { - EVP_CIPHER_CTX_cleanup(&ctx); - OPENSSL_free(sdec); - return 2; - } - slen += mlen; - EVP_CIPHER_CTX_cleanup(&ctx); - p = sdec; - - sess = d2i_SSL_SESSION(NULL, &p, slen); - slen -= p - sdec; - OPENSSL_free(sdec); - if (sess) { - /* Some additional consistency checks */ - if (slen != 0 || sess->session_id_length != 0) { - SSL_SESSION_free(sess); - return 2; - } - /* - * The session ID, if non-empty, is used by some clients to detect - * that the ticket has been accepted. So we copy it to the session - * structure. If it is empty set length to zero as required by - * standard. - */ - if (sesslen) - memcpy(sess->session_id, sess_id, sesslen); - sess->session_id_length = sesslen; - *psess = sess; - if (renew_ticket) - return 4; - else - return 3; - } - ERR_clear_error(); - /* - * For session parse failure, indicate that we need to send a new ticket. - */ - return 2; -err: - EVP_CIPHER_CTX_cleanup(&ctx); - HMAC_CTX_cleanup(&hctx); - return -1; -} - -/* Tables to translate from NIDs to TLS v1.2 ids */ - -typedef struct { - int nid; - int id; -} tls12_lookup; - -static tls12_lookup tls12_md[] = { - {NID_md5, TLSEXT_hash_md5}, - {NID_sha1, TLSEXT_hash_sha1}, - {NID_sha224, TLSEXT_hash_sha224}, - {NID_sha256, TLSEXT_hash_sha256}, - {NID_sha384, TLSEXT_hash_sha384}, - {NID_sha512, TLSEXT_hash_sha512} -}; - -static tls12_lookup tls12_sig[] = { - {EVP_PKEY_RSA, TLSEXT_signature_rsa}, - {EVP_PKEY_DSA, TLSEXT_signature_dsa}, - {EVP_PKEY_EC, TLSEXT_signature_ecdsa} -}; - -static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen) -{ - size_t i; - for (i = 0; i < tlen; i++) { - if (table[i].nid == nid) - return table[i].id; - } - return -1; -} - -static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen) -{ - size_t i; - for (i = 0; i < tlen; i++) { - if ((table[i].id) == id) - return table[i].nid; - } - return NID_undef; -} - -int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, - const EVP_MD *md) -{ - int sig_id, md_id; - if (!md) - return 0; - md_id = tls12_find_id(EVP_MD_type(md), tls12_md, - sizeof(tls12_md) / sizeof(tls12_lookup)); - if (md_id == -1) - return 0; - sig_id = tls12_get_sigid(pk); - if (sig_id == -1) - return 0; - p[0] = (unsigned char)md_id; - p[1] = (unsigned char)sig_id; - return 1; -} - -int tls12_get_sigid(const EVP_PKEY *pk) -{ - return tls12_find_id(pk->type, tls12_sig, - sizeof(tls12_sig) / sizeof(tls12_lookup)); -} - -const EVP_MD *tls12_get_hash(unsigned char hash_alg) -{ - switch (hash_alg) { -# ifndef OPENSSL_NO_MD5 - case TLSEXT_hash_md5: -# ifdef OPENSSL_FIPS - if (FIPS_mode()) - return NULL; -# endif - return EVP_md5(); -# endif -# ifndef OPENSSL_NO_SHA - case TLSEXT_hash_sha1: - return EVP_sha1(); -# endif -# ifndef OPENSSL_NO_SHA256 - case TLSEXT_hash_sha224: - return EVP_sha224(); - - case TLSEXT_hash_sha256: - return EVP_sha256(); -# endif -# ifndef OPENSSL_NO_SHA512 - case TLSEXT_hash_sha384: - return EVP_sha384(); - - case TLSEXT_hash_sha512: - return EVP_sha512(); -# endif - default: - return NULL; - - } -} - -static int tls12_get_pkey_idx(unsigned char sig_alg) -{ - switch (sig_alg) { -# ifndef OPENSSL_NO_RSA - case TLSEXT_signature_rsa: - return SSL_PKEY_RSA_SIGN; -# endif -# ifndef OPENSSL_NO_DSA - case TLSEXT_signature_dsa: - return SSL_PKEY_DSA_SIGN; -# endif -# ifndef OPENSSL_NO_ECDSA - case TLSEXT_signature_ecdsa: - return SSL_PKEY_ECC; -# endif - } - return -1; -} - -/* Convert TLS 1.2 signature algorithm extension values into NIDs */ -static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid, - int *psignhash_nid, const unsigned char *data) -{ - int sign_nid = NID_undef, hash_nid = NID_undef; - if (!phash_nid && !psign_nid && !psignhash_nid) - return; - if (phash_nid || psignhash_nid) { - hash_nid = tls12_find_nid(data[0], tls12_md, - sizeof(tls12_md) / sizeof(tls12_lookup)); - if (phash_nid) - *phash_nid = hash_nid; - } - if (psign_nid || psignhash_nid) { - sign_nid = tls12_find_nid(data[1], tls12_sig, - sizeof(tls12_sig) / sizeof(tls12_lookup)); - if (psign_nid) - *psign_nid = sign_nid; - } - if (psignhash_nid) { - if (sign_nid == NID_undef || hash_nid == NID_undef - || OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, - sign_nid) <= 0) - *psignhash_nid = NID_undef; - } -} - -/* Given preference and allowed sigalgs set shared sigalgs */ -static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig, - const unsigned char *pref, size_t preflen, - const unsigned char *allow, - size_t allowlen) -{ - const unsigned char *ptmp, *atmp; - size_t i, j, nmatch = 0; - for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) { - /* Skip disabled hashes or signature algorithms */ - if (tls12_get_hash(ptmp[0]) == NULL) - continue; - if (tls12_get_pkey_idx(ptmp[1]) == -1) - continue; - for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) { - if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) { - nmatch++; - if (shsig) { - shsig->rhash = ptmp[0]; - shsig->rsign = ptmp[1]; - tls1_lookup_sigalg(&shsig->hash_nid, - &shsig->sign_nid, - &shsig->signandhash_nid, ptmp); - shsig++; - } - break; - } - } - } - return nmatch; -} - -/* Set shared signature algorithms for SSL structures */ -static int tls1_set_shared_sigalgs(SSL *s) -{ - const unsigned char *pref, *allow, *conf; - size_t preflen, allowlen, conflen; - size_t nmatch; - TLS_SIGALGS *salgs = NULL; - CERT *c = s->cert; - unsigned int is_suiteb = tls1_suiteb(s); - if (c->shared_sigalgs) { - OPENSSL_free(c->shared_sigalgs); - c->shared_sigalgs = NULL; - c->shared_sigalgslen = 0; - } - /* If client use client signature algorithms if not NULL */ - if (!s->server && c->client_sigalgs && !is_suiteb) { - conf = c->client_sigalgs; - conflen = c->client_sigalgslen; - } else if (c->conf_sigalgs && !is_suiteb) { - conf = c->conf_sigalgs; - conflen = c->conf_sigalgslen; - } else - conflen = tls12_get_psigalgs(s, 0, &conf); - if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { - pref = conf; - preflen = conflen; - allow = c->peer_sigalgs; - allowlen = c->peer_sigalgslen; - } else { - allow = conf; - allowlen = conflen; - pref = c->peer_sigalgs; - preflen = c->peer_sigalgslen; - } - nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen); - if (nmatch) { - salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS)); - if (!salgs) - return 0; - nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen); - } else { - salgs = NULL; - } - c->shared_sigalgs = salgs; - c->shared_sigalgslen = nmatch; - return 1; -} - -/* Set preferred digest for each key type */ - -int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize) -{ - CERT *c = s->cert; - /* Extension ignored for inappropriate versions */ - if (!SSL_USE_SIGALGS(s)) - return 1; - /* Should never happen */ - if (!c) - return 0; - - if (c->peer_sigalgs) - OPENSSL_free(c->peer_sigalgs); - c->peer_sigalgs = OPENSSL_malloc(dsize); - if (!c->peer_sigalgs) - return 0; - c->peer_sigalgslen = dsize; - memcpy(c->peer_sigalgs, data, dsize); - return 1; -} - -int tls1_process_sigalgs(SSL *s) -{ - int idx; - size_t i; - const EVP_MD *md; - CERT *c = s->cert; - TLS_SIGALGS *sigptr; - if (!tls1_set_shared_sigalgs(s)) - return 0; - -# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { - /* - * Use first set signature preference to force message digest, - * ignoring any peer preferences. - */ - const unsigned char *sigs = NULL; - if (s->server) - sigs = c->conf_sigalgs; - else - sigs = c->client_sigalgs; - if (sigs) { - idx = tls12_get_pkey_idx(sigs[1]); - md = tls12_get_hash(sigs[0]); - c->pkeys[idx].digest = md; - c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; - if (idx == SSL_PKEY_RSA_SIGN) { - c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = - CERT_PKEY_EXPLICIT_SIGN; - c->pkeys[SSL_PKEY_RSA_ENC].digest = md; - } - } - } -# endif - - for (i = 0, sigptr = c->shared_sigalgs; - i < c->shared_sigalgslen; i++, sigptr++) { - idx = tls12_get_pkey_idx(sigptr->rsign); - if (idx > 0 && c->pkeys[idx].digest == NULL) { - md = tls12_get_hash(sigptr->rhash); - c->pkeys[idx].digest = md; - c->pkeys[idx].valid_flags = CERT_PKEY_EXPLICIT_SIGN; - if (idx == SSL_PKEY_RSA_SIGN) { - c->pkeys[SSL_PKEY_RSA_ENC].valid_flags = - CERT_PKEY_EXPLICIT_SIGN; - c->pkeys[SSL_PKEY_RSA_ENC].digest = md; - } - } - - } - /* - * In strict mode leave unset digests as NULL to indicate we can't use - * the certificate for signing. - */ - if (!(s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)) { - /* - * Set any remaining keys to default values. NOTE: if alg is not - * supported it stays as NULL. - */ -# ifndef OPENSSL_NO_DSA - if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) - c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); -# endif -# ifndef OPENSSL_NO_RSA - if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) { - c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); - c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); - } -# endif -# ifndef OPENSSL_NO_ECDSA - if (!c->pkeys[SSL_PKEY_ECC].digest) - c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); -# endif - } - return 1; -} - -int SSL_get_sigalgs(SSL *s, int idx, - int *psign, int *phash, int *psignhash, - unsigned char *rsig, unsigned char *rhash) -{ - const unsigned char *psig = s->cert->peer_sigalgs; - if (psig == NULL) - return 0; - if (idx >= 0) { - idx <<= 1; - if (idx >= (int)s->cert->peer_sigalgslen) - return 0; - psig += idx; - if (rhash) - *rhash = psig[0]; - if (rsig) - *rsig = psig[1]; - tls1_lookup_sigalg(phash, psign, psignhash, psig); - } - return s->cert->peer_sigalgslen / 2; -} - -int SSL_get_shared_sigalgs(SSL *s, int idx, - int *psign, int *phash, int *psignhash, - unsigned char *rsig, unsigned char *rhash) -{ - TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs; - if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen) - return 0; - shsigalgs += idx; - if (phash) - *phash = shsigalgs->hash_nid; - if (psign) - *psign = shsigalgs->sign_nid; - if (psignhash) - *psignhash = shsigalgs->signandhash_nid; - if (rsig) - *rsig = shsigalgs->rsign; - if (rhash) - *rhash = shsigalgs->rhash; - return s->cert->shared_sigalgslen; -} - -# ifndef OPENSSL_NO_HEARTBEATS -int tls1_process_heartbeat(SSL *s) -{ - unsigned char *p = &s->s3->rrec.data[0], *pl; - unsigned short hbtype; - unsigned int payload; - unsigned int padding = 16; /* Use minimum padding */ - - if (s->msg_callback) - s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, - &s->s3->rrec.data[0], s->s3->rrec.length, - s, s->msg_callback_arg); - - /* Read type and payload length first */ - if (1 + 2 + 16 > s->s3->rrec.length) - return 0; /* silently discard */ - hbtype = *p++; - n2s(p, payload); - if (1 + 2 + payload + 16 > s->s3->rrec.length) - return 0; /* silently discard per RFC 6520 sec. 4 */ - pl = p; - - if (hbtype == TLS1_HB_REQUEST) { - unsigned char *buffer, *bp; - int r; - - /* - * Allocate memory for the response, size is 1 bytes message type, - * plus 2 bytes payload length, plus payload, plus padding - */ - buffer = OPENSSL_malloc(1 + 2 + payload + padding); - if (buffer == NULL) - return -1; - bp = buffer; - - /* Enter response type, length and copy payload */ - *bp++ = TLS1_HB_RESPONSE; - s2n(payload, bp); - memcpy(bp, pl, payload); - bp += payload; - /* Random padding */ - if (RAND_bytes(bp, padding) <= 0) { - OPENSSL_free(buffer); - return -1; - } - - r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, - 3 + payload + padding); - - if (r >= 0 && s->msg_callback) - s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buffer, 3 + payload + padding, - s, s->msg_callback_arg); - - OPENSSL_free(buffer); - - if (r < 0) - return r; - } else if (hbtype == TLS1_HB_RESPONSE) { - unsigned int seq; - - /* - * We only send sequence numbers (2 bytes unsigned int), and 16 - * random bytes, so we just try to read the sequence number - */ - n2s(pl, seq); - - if (payload == 18 && seq == s->tlsext_hb_seq) { - s->tlsext_hb_seq++; - s->tlsext_hb_pending = 0; - } - } - - return 0; -} - -int tls1_heartbeat(SSL *s) -{ - unsigned char *buf, *p; - int ret = -1; - unsigned int payload = 18; /* Sequence number + random bytes */ - unsigned int padding = 16; /* Use minimum padding */ - - /* Only send if peer supports and accepts HB requests... */ - if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || - s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { - SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); - return -1; - } - - /* ...and there is none in flight yet... */ - if (s->tlsext_hb_pending) { - SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); - return -1; - } - - /* ...and no handshake in progress. */ - if (SSL_in_init(s) || s->in_handshake) { - SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); - return -1; - } - - /* - * Check if padding is too long, payload and padding must not exceed 2^14 - * - 3 = 16381 bytes in total. - */ - OPENSSL_assert(payload + padding <= 16381); - - /*- - * Create HeartBeat message, we just use a sequence number - * as payload to distuingish different messages and add - * some random stuff. - * - Message Type, 1 byte - * - Payload Length, 2 bytes (unsigned int) - * - Payload, the sequence number (2 bytes uint) - * - Payload, random bytes (16 bytes uint) - * - Padding - */ - buf = OPENSSL_malloc(1 + 2 + payload + padding); - if (buf == NULL) - return -1; - p = buf; - /* Message Type */ - *p++ = TLS1_HB_REQUEST; - /* Payload length (18 bytes here) */ - s2n(payload, p); - /* Sequence number */ - s2n(s->tlsext_hb_seq, p); - /* 16 random bytes */ - if (RAND_bytes(p, 16) <= 0) { - SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); - goto err; - } - p += 16; - /* Random padding */ - if (RAND_bytes(p, padding) <= 0) { - SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); - goto err; - } - - ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); - if (ret >= 0) { - if (s->msg_callback) - s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, - buf, 3 + payload + padding, - s, s->msg_callback_arg); - - s->tlsext_hb_pending = 1; - } - -err: - OPENSSL_free(buf); - - return ret; -} -# endif - -# define MAX_SIGALGLEN (TLSEXT_hash_num * TLSEXT_signature_num * 2) - -typedef struct { - size_t sigalgcnt; - int sigalgs[MAX_SIGALGLEN]; -} sig_cb_st; - -static int sig_cb(const char *elem, int len, void *arg) -{ - sig_cb_st *sarg = arg; - size_t i; - char etmp[20], *p; - int sig_alg, hash_alg; - if (elem == NULL) - return 0; - if (sarg->sigalgcnt == MAX_SIGALGLEN) - return 0; - if (len > (int)(sizeof(etmp) - 1)) - return 0; - memcpy(etmp, elem, len); - etmp[len] = 0; - p = strchr(etmp, '+'); - if (!p) - return 0; - *p = 0; - p++; - if (!*p) - return 0; - - if (!strcmp(etmp, "RSA")) - sig_alg = EVP_PKEY_RSA; - else if (!strcmp(etmp, "DSA")) - sig_alg = EVP_PKEY_DSA; - else if (!strcmp(etmp, "ECDSA")) - sig_alg = EVP_PKEY_EC; - else - return 0; - - hash_alg = OBJ_sn2nid(p); - if (hash_alg == NID_undef) - hash_alg = OBJ_ln2nid(p); - if (hash_alg == NID_undef) - return 0; - - for (i = 0; i < sarg->sigalgcnt; i += 2) { - if (sarg->sigalgs[i] == sig_alg && sarg->sigalgs[i + 1] == hash_alg) - return 0; - } - sarg->sigalgs[sarg->sigalgcnt++] = hash_alg; - sarg->sigalgs[sarg->sigalgcnt++] = sig_alg; - return 1; -} - -/* - * Set suppored signature algorithms based on a colon separated list of the - * form sig+hash e.g. RSA+SHA512:DSA+SHA512 - */ -int tls1_set_sigalgs_list(CERT *c, const char *str, int client) -{ - sig_cb_st sig; - sig.sigalgcnt = 0; - if (!CONF_parse_list(str, ':', 1, sig_cb, &sig)) - return 0; - if (c == NULL) - return 1; - return tls1_set_sigalgs(c, sig.sigalgs, sig.sigalgcnt, client); -} - -int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen, - int client) -{ - unsigned char *sigalgs, *sptr; - int rhash, rsign; - size_t i; - if (salglen & 1) - return 0; - sigalgs = OPENSSL_malloc(salglen); - if (sigalgs == NULL) - return 0; - for (i = 0, sptr = sigalgs; i < salglen; i += 2) { - rhash = tls12_find_id(*psig_nids++, tls12_md, - sizeof(tls12_md) / sizeof(tls12_lookup)); - rsign = tls12_find_id(*psig_nids++, tls12_sig, - sizeof(tls12_sig) / sizeof(tls12_lookup)); - - if (rhash == -1 || rsign == -1) - goto err; - *sptr++ = rhash; - *sptr++ = rsign; - } - - if (client) { - if (c->client_sigalgs) - OPENSSL_free(c->client_sigalgs); - c->client_sigalgs = sigalgs; - c->client_sigalgslen = salglen; - } else { - if (c->conf_sigalgs) - OPENSSL_free(c->conf_sigalgs); - c->conf_sigalgs = sigalgs; - c->conf_sigalgslen = salglen; - } - - return 1; - - err: - OPENSSL_free(sigalgs); - return 0; -} - -static int tls1_check_sig_alg(CERT *c, X509 *x, int default_nid) -{ - int sig_nid; - size_t i; - if (default_nid == -1) - return 1; - sig_nid = X509_get_signature_nid(x); - if (default_nid) - return sig_nid == default_nid ? 1 : 0; - for (i = 0; i < c->shared_sigalgslen; i++) - if (sig_nid == c->shared_sigalgs[i].signandhash_nid) - return 1; - return 0; -} - -/* Check to see if a certificate issuer name matches list of CA names */ -static int ssl_check_ca_name(STACK_OF(X509_NAME) *names, X509 *x) -{ - X509_NAME *nm; - int i; - nm = X509_get_issuer_name(x); - for (i = 0; i < sk_X509_NAME_num(names); i++) { - if (!X509_NAME_cmp(nm, sk_X509_NAME_value(names, i))) - return 1; - } - return 0; -} - -/* - * Check certificate chain is consistent with TLS extensions and is usable by - * server. This servers two purposes: it allows users to check chains before - * passing them to the server and it allows the server to check chains before - * attempting to use them. - */ - -/* Flags which need to be set for a certificate when stict mode not set */ - -# define CERT_PKEY_VALID_FLAGS \ - (CERT_PKEY_EE_SIGNATURE|CERT_PKEY_EE_PARAM) -/* Strict mode flags */ -# define CERT_PKEY_STRICT_FLAGS \ - (CERT_PKEY_VALID_FLAGS|CERT_PKEY_CA_SIGNATURE|CERT_PKEY_CA_PARAM \ - | CERT_PKEY_ISSUER_NAME|CERT_PKEY_CERT_TYPE) - -int tls1_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain, - int idx) -{ - int i; - int rv = 0; - int check_flags = 0, strict_mode; - CERT_PKEY *cpk = NULL; - CERT *c = s->cert; - unsigned int suiteb_flags = tls1_suiteb(s); - /* idx == -1 means checking server chains */ - if (idx != -1) { - /* idx == -2 means checking client certificate chains */ - if (idx == -2) { - cpk = c->key; - idx = cpk - c->pkeys; - } else - cpk = c->pkeys + idx; - x = cpk->x509; - pk = cpk->privatekey; - chain = cpk->chain; - strict_mode = c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT; - /* If no cert or key, forget it */ - if (!x || !pk) - goto end; -# ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL - /* Allow any certificate to pass test */ - if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL) { - rv = CERT_PKEY_STRICT_FLAGS | CERT_PKEY_EXPLICIT_SIGN | - CERT_PKEY_VALID | CERT_PKEY_SIGN; - cpk->valid_flags = rv; - return rv; - } -# endif - } else { - if (!x || !pk) - return 0; - idx = ssl_cert_type(x, pk); - if (idx == -1) - return 0; - cpk = c->pkeys + idx; - if (c->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) - check_flags = CERT_PKEY_STRICT_FLAGS; - else - check_flags = CERT_PKEY_VALID_FLAGS; - strict_mode = 1; - } - - if (suiteb_flags) { - int ok; - if (check_flags) - check_flags |= CERT_PKEY_SUITEB; - ok = X509_chain_check_suiteb(NULL, x, chain, suiteb_flags); - if (ok == X509_V_OK) - rv |= CERT_PKEY_SUITEB; - else if (!check_flags) - goto end; - } - - /* - * Check all signature algorithms are consistent with signature - * algorithms extension if TLS 1.2 or later and strict mode. - */ - if (TLS1_get_version(s) >= TLS1_2_VERSION && strict_mode) { - int default_nid; - unsigned char rsign = 0; - if (c->peer_sigalgs) - default_nid = 0; - /* If no sigalgs extension use defaults from RFC5246 */ - else { - switch (idx) { - case SSL_PKEY_RSA_ENC: - case SSL_PKEY_RSA_SIGN: - case SSL_PKEY_DH_RSA: - rsign = TLSEXT_signature_rsa; - default_nid = NID_sha1WithRSAEncryption; - break; - - case SSL_PKEY_DSA_SIGN: - case SSL_PKEY_DH_DSA: - rsign = TLSEXT_signature_dsa; - default_nid = NID_dsaWithSHA1; - break; - - case SSL_PKEY_ECC: - rsign = TLSEXT_signature_ecdsa; - default_nid = NID_ecdsa_with_SHA1; - break; - - default: - default_nid = -1; - break; - } - } - /* - * If peer sent no signature algorithms extension and we have set - * preferred signature algorithms check we support sha1. - */ - if (default_nid > 0 && c->conf_sigalgs) { - size_t j; - const unsigned char *p = c->conf_sigalgs; - for (j = 0; j < c->conf_sigalgslen; j += 2, p += 2) { - if (p[0] == TLSEXT_hash_sha1 && p[1] == rsign) - break; - } - if (j == c->conf_sigalgslen) { - if (check_flags) - goto skip_sigs; - else - goto end; - } - } - /* Check signature algorithm of each cert in chain */ - if (!tls1_check_sig_alg(c, x, default_nid)) { - if (!check_flags) - goto end; - } else - rv |= CERT_PKEY_EE_SIGNATURE; - rv |= CERT_PKEY_CA_SIGNATURE; - for (i = 0; i < sk_X509_num(chain); i++) { - if (!tls1_check_sig_alg(c, sk_X509_value(chain, i), default_nid)) { - if (check_flags) { - rv &= ~CERT_PKEY_CA_SIGNATURE; - break; - } else - goto end; - } - } - } - /* Else not TLS 1.2, so mark EE and CA signing algorithms OK */ - else if (check_flags) - rv |= CERT_PKEY_EE_SIGNATURE | CERT_PKEY_CA_SIGNATURE; - skip_sigs: - /* Check cert parameters are consistent */ - if (tls1_check_cert_param(s, x, check_flags ? 1 : 2)) - rv |= CERT_PKEY_EE_PARAM; - else if (!check_flags) - goto end; - if (!s->server) - rv |= CERT_PKEY_CA_PARAM; - /* In strict mode check rest of chain too */ - else if (strict_mode) { - rv |= CERT_PKEY_CA_PARAM; - for (i = 0; i < sk_X509_num(chain); i++) { - X509 *ca = sk_X509_value(chain, i); - if (!tls1_check_cert_param(s, ca, 0)) { - if (check_flags) { - rv &= ~CERT_PKEY_CA_PARAM; - break; - } else - goto end; - } - } - } - if (!s->server && strict_mode) { - STACK_OF(X509_NAME) *ca_dn; - int check_type = 0; - switch (pk->type) { - case EVP_PKEY_RSA: - check_type = TLS_CT_RSA_SIGN; - break; - case EVP_PKEY_DSA: - check_type = TLS_CT_DSS_SIGN; - break; - case EVP_PKEY_EC: - check_type = TLS_CT_ECDSA_SIGN; - break; - case EVP_PKEY_DH: - case EVP_PKEY_DHX: - { - int cert_type = X509_certificate_type(x, pk); - if (cert_type & EVP_PKS_RSA) - check_type = TLS_CT_RSA_FIXED_DH; - if (cert_type & EVP_PKS_DSA) - check_type = TLS_CT_DSS_FIXED_DH; - } - } - if (check_type) { - const unsigned char *ctypes; - int ctypelen; - if (c->ctypes) { - ctypes = c->ctypes; - ctypelen = (int)c->ctype_num; - } else { - ctypes = (unsigned char *)s->s3->tmp.ctype; - ctypelen = s->s3->tmp.ctype_num; - } - for (i = 0; i < ctypelen; i++) { - if (ctypes[i] == check_type) { - rv |= CERT_PKEY_CERT_TYPE; - break; - } - } - if (!(rv & CERT_PKEY_CERT_TYPE) && !check_flags) - goto end; - } else - rv |= CERT_PKEY_CERT_TYPE; - - ca_dn = s->s3->tmp.ca_names; - - if (!sk_X509_NAME_num(ca_dn)) - rv |= CERT_PKEY_ISSUER_NAME; - - if (!(rv & CERT_PKEY_ISSUER_NAME)) { - if (ssl_check_ca_name(ca_dn, x)) - rv |= CERT_PKEY_ISSUER_NAME; - } - if (!(rv & CERT_PKEY_ISSUER_NAME)) { - for (i = 0; i < sk_X509_num(chain); i++) { - X509 *xtmp = sk_X509_value(chain, i); - if (ssl_check_ca_name(ca_dn, xtmp)) { - rv |= CERT_PKEY_ISSUER_NAME; - break; - } - } - } - if (!check_flags && !(rv & CERT_PKEY_ISSUER_NAME)) - goto end; - } else - rv |= CERT_PKEY_ISSUER_NAME | CERT_PKEY_CERT_TYPE; - - if (!check_flags || (rv & check_flags) == check_flags) - rv |= CERT_PKEY_VALID; - - end: - - if (TLS1_get_version(s) >= TLS1_2_VERSION) { - if (cpk->valid_flags & CERT_PKEY_EXPLICIT_SIGN) - rv |= CERT_PKEY_EXPLICIT_SIGN | CERT_PKEY_SIGN; - else if (cpk->digest) - rv |= CERT_PKEY_SIGN; - } else - rv |= CERT_PKEY_SIGN | CERT_PKEY_EXPLICIT_SIGN; - - /* - * When checking a CERT_PKEY structure all flags are irrelevant if the - * chain is invalid. - */ - if (!check_flags) { - if (rv & CERT_PKEY_VALID) - cpk->valid_flags = rv; - else { - /* Preserve explicit sign flag, clear rest */ - cpk->valid_flags &= CERT_PKEY_EXPLICIT_SIGN; - return 0; - } - } - return rv; -} - -/* Set validity of certificates in an SSL structure */ -void tls1_set_cert_validity(SSL *s) -{ - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_ENC); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_RSA_SIGN); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DSA_SIGN); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_RSA); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_DH_DSA); - tls1_check_chain(s, NULL, NULL, NULL, SSL_PKEY_ECC); -} - -/* User level utiity function to check a chain is suitable */ -int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain) -{ - return tls1_check_chain(s, x, pk, chain, -1); -} - -#endif -/* ssl/t1_meth.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "objects.h" -// #include "ssl_locl.h" - -static const SSL_METHOD *tls1_get_method(int ver) -{ - if (ver == TLS1_2_VERSION) - return TLSv1_2_method(); - if (ver == TLS1_1_VERSION) - return TLSv1_1_method(); - if (ver == TLS1_VERSION) - return TLSv1_method(); - return NULL; -} - -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method, - ssl3_accept, - ssl3_connect, tls1_get_method, TLSv1_2_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method, - ssl3_accept, - ssl3_connect, tls1_get_method, TLSv1_1_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method, - ssl3_accept, - ssl3_connect, tls1_get_method, TLSv1_enc_data) -/* ssl/t1_reneg.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2009 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#include -// #include "objects.h" -// #include "ssl_locl.h" - -/* Add the client's renegotiation binding */ -int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, - int maxlen) -{ - if (p) { - if ((s->s3->previous_client_finished_len + 1) > maxlen) { - SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATE_EXT_TOO_LONG); - return 0; - } - - /* Length byte */ - *p = s->s3->previous_client_finished_len; - p++; - - memcpy(p, s->s3->previous_client_finished, - s->s3->previous_client_finished_len); -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "%s RI extension sent by client\n", - s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); -#endif - } - - *len = s->s3->previous_client_finished_len + 1; - - return 1; -} - -/* - * Parse the client's renegotiation binding and abort if it's not right - */ -int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, - int *al) -{ - int ilen; - - /* Parse the length byte */ - if (len < 1) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_ENCODING_ERR); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - ilen = *d; - d++; - - /* Consistency check */ - if ((ilen + 1) != len) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_ENCODING_ERR); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - - /* Check that the extension matches */ - if (ilen != s->s3->previous_client_finished_len) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_HANDSHAKE_FAILURE; - return 0; - } - - if (memcmp(d, s->s3->previous_client_finished, - s->s3->previous_client_finished_len)) { - SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_HANDSHAKE_FAILURE; - return 0; - } -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "%s RI extension received by server\n", - ilen ? "Non-empty" : "Empty"); -#endif - - s->s3->send_connection_binding = 1; - - return 1; -} - -/* Add the server's renegotiation binding */ -int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, - int maxlen) -{ - if (p) { - if ((s->s3->previous_client_finished_len + - s->s3->previous_server_finished_len + 1) > maxlen) { - SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATE_EXT_TOO_LONG); - return 0; - } - - /* Length byte */ - *p = s->s3->previous_client_finished_len + - s->s3->previous_server_finished_len; - p++; - - memcpy(p, s->s3->previous_client_finished, - s->s3->previous_client_finished_len); - p += s->s3->previous_client_finished_len; - - memcpy(p, s->s3->previous_server_finished, - s->s3->previous_server_finished_len); -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "%s RI extension sent by server\n", - s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); -#endif - } - - *len = s->s3->previous_client_finished_len - + s->s3->previous_server_finished_len + 1; - - return 1; -} - -/* - * Parse the server's renegotiation binding and abort if it's not right - */ -int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, - int *al) -{ - int expected_len = s->s3->previous_client_finished_len - + s->s3->previous_server_finished_len; - int ilen; - - /* Check for logic errors */ - OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len); - OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len); - - /* Parse the length byte */ - if (len < 1) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_ENCODING_ERR); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - ilen = *d; - d++; - - /* Consistency check */ - if (ilen + 1 != len) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_ENCODING_ERR); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } - - /* Check that the extension matches */ - if (ilen != expected_len) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_HANDSHAKE_FAILURE; - return 0; - } - - if (memcmp(d, s->s3->previous_client_finished, - s->s3->previous_client_finished_len)) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_HANDSHAKE_FAILURE; - return 0; - } - d += s->s3->previous_client_finished_len; - - if (memcmp(d, s->s3->previous_server_finished, - s->s3->previous_server_finished_len)) { - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, - SSL_R_RENEGOTIATION_MISMATCH); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } -#ifdef OPENSSL_RI_DEBUG - fprintf(stderr, "%s RI extension received by client\n", - ilen ? "Non-empty" : "Empty"); -#endif - s->s3->send_connection_binding = 1; - - return 1; -} -/* ssl/t1_srvr.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "ssl_locl.h" -// #include "buffer.h" -// #include "rand.h" -// #include "objects.h" -// #include "evp.h" -#include "x509.h" - -static const SSL_METHOD *tls1_get_server_method(int ver); -static const SSL_METHOD *tls1_get_server_method(int ver) -{ - if (ver == TLS1_2_VERSION) - return TLSv1_2_server_method(); - if (ver == TLS1_1_VERSION) - return TLSv1_1_server_method(); - if (ver == TLS1_VERSION) - return TLSv1_server_method(); - return NULL; -} - -IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method, - ssl3_accept, - ssl_undefined_function, - tls1_get_server_method, TLSv1_2_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method, - ssl3_accept, - ssl_undefined_function, - tls1_get_server_method, TLSv1_1_enc_data) - - IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method, - ssl3_accept, - ssl_undefined_function, - tls1_get_server_method, TLSv1_enc_data) -/* ssl/t1_trce.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2012-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - */ - -// #include "ssl_locl.h" - -#ifndef OPENSSL_NO_SSL_TRACE - -/* Packet trace support for OpenSSL */ - -typedef struct { - int num; - const char *name; -} ssl_trace_tbl; - -# define ssl_trace_str(val, tbl) \ - do_ssl_trace_str(val, tbl, sizeof(tbl)/sizeof(ssl_trace_tbl)) - -# define ssl_trace_list(bio, indent, msg, msglen, value, table) \ - do_ssl_trace_list(bio, indent, msg, msglen, value, \ - table, sizeof(table)/sizeof(ssl_trace_tbl)) - -static const char *do_ssl_trace_str(int val, ssl_trace_tbl *tbl, size_t ntbl) -{ - size_t i; - for (i = 0; i < ntbl; i++, tbl++) { - if (tbl->num == val) - return tbl->name; - } - return "UNKNOWN"; -} - -static int do_ssl_trace_list(BIO *bio, int indent, - const unsigned char *msg, size_t msglen, - size_t vlen, ssl_trace_tbl *tbl, size_t ntbl) -{ - int val; - if (msglen % vlen) - return 0; - while (msglen) { - val = msg[0]; - if (vlen == 2) - val = (val << 8) | msg[1]; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "%s (%d)\n", do_ssl_trace_str(val, tbl, ntbl), val); - msg += vlen; - msglen -= vlen; - } - return 1; -} - -/* Version number */ - -static ssl_trace_tbl ssl_version_tbl[] = { - {SSL2_VERSION, "SSL 2.0"}, - {SSL3_VERSION, "SSL 3.0"}, - {TLS1_VERSION, "TLS 1.0"}, - {TLS1_1_VERSION, "TLS 1.1"}, - {TLS1_2_VERSION, "TLS 1.2"}, - {DTLS1_VERSION, "DTLS 1.0"}, - {DTLS1_2_VERSION, "DTLS 1.2"}, - {DTLS1_BAD_VER, "DTLS 1.0 (bad)"} -}; - -static ssl_trace_tbl ssl_content_tbl[] = { - {SSL3_RT_CHANGE_CIPHER_SPEC, "ChangeCipherSpec"}, - {SSL3_RT_ALERT, "Alert"}, - {SSL3_RT_HANDSHAKE, "Handshake"}, - {SSL3_RT_APPLICATION_DATA, "ApplicationData"}, - {TLS1_RT_HEARTBEAT, "HeartBeat"} -}; - -/* Handshake types */ -static ssl_trace_tbl ssl_handshake_tbl[] = { - {SSL3_MT_HELLO_REQUEST, "HelloRequest"}, - {SSL3_MT_CLIENT_HELLO, "ClientHello"}, - {SSL3_MT_SERVER_HELLO, "ServerHello"}, - {DTLS1_MT_HELLO_VERIFY_REQUEST, "HelloVerifyRequest"}, - {SSL3_MT_NEWSESSION_TICKET, "NewSessionTicket"}, - {SSL3_MT_CERTIFICATE, "Certificate"}, - {SSL3_MT_SERVER_KEY_EXCHANGE, "ServerKeyExchange"}, - {SSL3_MT_CERTIFICATE_REQUEST, "CertificateRequest"}, - {SSL3_MT_CLIENT_KEY_EXCHANGE, "ClientKeyExchange"}, - {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"}, - {SSL3_MT_SERVER_DONE, "ServerHelloDone"}, - {SSL3_MT_CERTIFICATE_VERIFY, "CertificateVerify"}, - {SSL3_MT_CLIENT_KEY_EXCHANGE, "ClientKeyExchange"}, - {SSL3_MT_FINISHED, "Finished"}, - {SSL3_MT_CERTIFICATE_STATUS, "CertificateStatus"} -}; - -/* Cipher suites */ -static ssl_trace_tbl ssl_ciphers_tbl[] = { - {0x0000, "SSL_NULL_WITH_NULL_NULL"}, - {0x0001, "SSL_RSA_WITH_NULL_MD5"}, - {0x0002, "SSL_RSA_WITH_NULL_SHA"}, - {0x0003, "SSL_RSA_EXPORT_WITH_RC4_40_MD5"}, - {0x0004, "SSL_RSA_WITH_RC4_128_MD5"}, - {0x0005, "SSL_RSA_WITH_RC4_128_SHA"}, - {0x0006, "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5"}, - {0x0007, "SSL_RSA_WITH_IDEA_CBC_SHA"}, - {0x0008, "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA"}, - {0x0009, "SSL_RSA_WITH_DES_CBC_SHA"}, - {0x000A, "SSL_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0x000B, "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"}, - {0x000C, "SSL_DH_DSS_WITH_DES_CBC_SHA"}, - {0x000D, "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA"}, - {0x000E, "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"}, - {0x000F, "SSL_DH_RSA_WITH_DES_CBC_SHA"}, - {0x0010, "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0x0011, "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"}, - {0x0012, "SSL_DHE_DSS_WITH_DES_CBC_SHA"}, - {0x0013, "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA"}, - {0x0014, "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"}, - {0x0015, "SSL_DHE_RSA_WITH_DES_CBC_SHA"}, - {0x0016, "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0x0017, "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"}, - {0x0018, "SSL_DH_anon_WITH_RC4_128_MD5"}, - {0x0019, "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"}, - {0x001A, "SSL_DH_anon_WITH_DES_CBC_SHA"}, - {0x001B, "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA"}, - {0x001D, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA"}, - {0x001E, "SSL_FORTEZZA_KEA_WITH_RC4_128_SHA"}, - {0x001F, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA"}, - {0x0020, "TLS_KRB5_WITH_RC4_128_SHA"}, - {0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA"}, - {0x0022, "TLS_KRB5_WITH_DES_CBC_MD5"}, - {0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5"}, - {0x0024, "TLS_KRB5_WITH_RC4_128_MD5"}, - {0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5"}, - {0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA"}, - {0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA"}, - {0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA"}, - {0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5"}, - {0x002A, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5"}, - {0x002B, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5"}, - {0x002F, "TLS_RSA_WITH_AES_128_CBC_SHA"}, - {0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA"}, - {0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA"}, - {0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"}, - {0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"}, - {0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA"}, - {0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA"}, - {0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA"}, - {0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA"}, - {0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"}, - {0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"}, - {0x003A, "TLS_DH_anon_WITH_AES_256_CBC_SHA"}, - {0x003B, "TLS_RSA_WITH_NULL_SHA256"}, - {0x003C, "TLS_RSA_WITH_AES_128_CBC_SHA256"}, - {0x003D, "TLS_RSA_WITH_AES_256_CBC_SHA256"}, - {0x003E, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"}, - {0x003F, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"}, - {0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"}, - {0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"}, - {0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"}, - {0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"}, - {0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"}, - {0x006A, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"}, - {0x006B, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"}, - {0x006C, "TLS_DH_anon_WITH_AES_128_CBC_SHA256"}, - {0x006D, "TLS_DH_anon_WITH_AES_256_CBC_SHA256"}, - {0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"}, - {0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA"}, - {0x008A, "TLS_PSK_WITH_RC4_128_SHA"}, - {0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA"}, - {0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA"}, - {0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA"}, - {0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA"}, - {0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"}, - {0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"}, - {0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"}, - {0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA"}, - {0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"}, - {0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"}, - {0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"}, - {0x0096, "TLS_RSA_WITH_SEED_CBC_SHA"}, - {0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA"}, - {0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA"}, - {0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA"}, - {0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA"}, - {0x009B, "TLS_DH_anon_WITH_SEED_CBC_SHA"}, - {0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256"}, - {0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384"}, - {0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"}, - {0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"}, - {0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"}, - {0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"}, - {0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"}, - {0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"}, - {0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"}, - {0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"}, - {0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256"}, - {0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384"}, - {0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256"}, - {0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384"}, - {0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"}, - {0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"}, - {0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"}, - {0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"}, - {0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256"}, - {0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384"}, - {0x00B0, "TLS_PSK_WITH_NULL_SHA256"}, - {0x00B1, "TLS_PSK_WITH_NULL_SHA384"}, - {0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"}, - {0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"}, - {0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256"}, - {0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384"}, - {0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"}, - {0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"}, - {0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256"}, - {0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384"}, - {0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BB, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BC, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BD, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00BF, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"}, - {0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"}, - {0x00FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"}, - {0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA"}, - {0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"}, - {0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"}, - {0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"}, - {0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"}, - {0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"}, - {0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"}, - {0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"}, - {0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA"}, - {0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA"}, - {0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"}, - {0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"}, - {0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA"}, - {0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"}, - {0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"}, - {0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"}, - {0xC015, "TLS_ECDH_anon_WITH_NULL_SHA"}, - {0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA"}, - {0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"}, - {0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"}, - {0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"}, - {0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA"}, - {0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA"}, - {0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA"}, - {0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA"}, - {0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA"}, - {0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA"}, - {0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA"}, - {0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA"}, - {0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA"}, - {0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"}, - {0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"}, - {0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"}, - {0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"}, - {0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"}, - {0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"}, - {0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"}, - {0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"}, - {0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"}, - {0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"}, - {0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"}, - {0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"}, - {0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"}, - {0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"}, - {0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"}, - {0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"}, - {0xFEFE, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"}, - {0xFEFF, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"}, -}; - -/* Compression methods */ -static ssl_trace_tbl ssl_comp_tbl[] = { - {0x0000, "No Compression"}, - {0x0001, "Zlib Compression"} -}; - -/* Extensions */ -static ssl_trace_tbl ssl_exts_tbl[] = { - {TLSEXT_TYPE_server_name, "server_name"}, - {TLSEXT_TYPE_max_fragment_length, "max_fragment_length"}, - {TLSEXT_TYPE_client_certificate_url, "client_certificate_url"}, - {TLSEXT_TYPE_trusted_ca_keys, "trusted_ca_keys"}, - {TLSEXT_TYPE_truncated_hmac, "truncated_hmac"}, - {TLSEXT_TYPE_status_request, "status_request"}, - {TLSEXT_TYPE_user_mapping, "user_mapping"}, - {TLSEXT_TYPE_client_authz, "client_authz"}, - {TLSEXT_TYPE_server_authz, "server_authz"}, - {TLSEXT_TYPE_cert_type, "cert_type"}, - {TLSEXT_TYPE_elliptic_curves, "elliptic_curves"}, - {TLSEXT_TYPE_ec_point_formats, "ec_point_formats"}, - {TLSEXT_TYPE_srp, "srp"}, - {TLSEXT_TYPE_signature_algorithms, "signature_algorithms"}, - {TLSEXT_TYPE_use_srtp, "use_srtp"}, - {TLSEXT_TYPE_heartbeat, "heartbeat"}, - {TLSEXT_TYPE_session_ticket, "session_ticket"}, -# ifdef TLSEXT_TYPE_opaque_prf_input - {TLSEXT_TYPE_opaque_prf_input, "opaque_prf_input"}, -# endif - {TLSEXT_TYPE_renegotiate, "renegotiate"}, - {TLSEXT_TYPE_next_proto_neg, "next_proto_neg"}, - {TLSEXT_TYPE_padding, "padding"} -}; - -static ssl_trace_tbl ssl_curve_tbl[] = { - {1, "sect163k1 (K-163)"}, - {2, "sect163r1"}, - {3, "sect163r2 (B-163)"}, - {4, "sect193r1"}, - {5, "sect193r2"}, - {6, "sect233k1 (K-233)"}, - {7, "sect233r1 (B-233)"}, - {8, "sect239k1"}, - {9, "sect283k1 (K-283)"}, - {10, "sect283r1 (B-283)"}, - {11, "sect409k1 (K-409)"}, - {12, "sect409r1 (B-409)"}, - {13, "sect571k1 (K-571)"}, - {14, "sect571r1 (B-571)"}, - {15, "secp160k1"}, - {16, "secp160r1"}, - {17, "secp160r2"}, - {18, "secp192k1"}, - {19, "secp192r1 (P-192)"}, - {20, "secp224k1"}, - {21, "secp224r1 (P-224)"}, - {22, "secp256k1"}, - {23, "secp256r1 (P-256)"}, - {24, "secp384r1 (P-384)"}, - {25, "secp521r1 (P-521)"}, - {26, "brainpoolP256r1"}, - {27, "brainpoolP384r1"}, - {28, "brainpoolP512r1"}, - {0xFF01, "arbitrary_explicit_prime_curves"}, - {0xFF02, "arbitrary_explicit_char2_curves"} -}; - -static ssl_trace_tbl ssl_point_tbl[] = { - {0, "uncompressed"}, - {1, "ansiX962_compressed_prime"}, - {2, "ansiX962_compressed_char2"} -}; - -static ssl_trace_tbl ssl_md_tbl[] = { - {0, "none"}, - {1, "md5"}, - {2, "sha1"}, - {3, "sha224"}, - {4, "sha256"}, - {5, "sha384"}, - {6, "sha512"} -}; - -static ssl_trace_tbl ssl_sig_tbl[] = { - {0, "anonymous"}, - {1, "rsa"}, - {2, "dsa"}, - {3, "ecdsa"} -}; - -static ssl_trace_tbl ssl_hb_tbl[] = { - {1, "peer_allowed_to_send"}, - {2, "peer_not_allowed_to_send"} -}; - -static ssl_trace_tbl ssl_hb_type_tbl[] = { - {1, "heartbeat_request"}, - {2, "heartbeat_response"} -}; - -static ssl_trace_tbl ssl_ctype_tbl[] = { - {1, "rsa_sign"}, - {2, "dss_sign"}, - {3, "rsa_fixed_dh"}, - {4, "dss_fixed_dh"}, - {5, "rsa_ephemeral_dh"}, - {6, "dss_ephemeral_dh"}, - {20, "fortezza_dms"}, - {64, "ecdsa_sign"}, - {65, "rsa_fixed_ecdh"}, - {66, "ecdsa_fixed_ecdh"} -}; - -static ssl_trace_tbl ssl_crypto_tbl[] = { - {TLS1_RT_CRYPTO_PREMASTER, "Premaster Secret"}, - {TLS1_RT_CRYPTO_CLIENT_RANDOM, "Client Random"}, - {TLS1_RT_CRYPTO_SERVER_RANDOM, "Server Random"}, - {TLS1_RT_CRYPTO_MASTER, "Master Secret"}, - {TLS1_RT_CRYPTO_MAC | TLS1_RT_CRYPTO_WRITE, "Write Mac Secret"}, - {TLS1_RT_CRYPTO_MAC | TLS1_RT_CRYPTO_READ, "Read Mac Secret"}, - {TLS1_RT_CRYPTO_KEY | TLS1_RT_CRYPTO_WRITE, "Write Key"}, - {TLS1_RT_CRYPTO_KEY | TLS1_RT_CRYPTO_READ, "Read Key"}, - {TLS1_RT_CRYPTO_IV | TLS1_RT_CRYPTO_WRITE, "Write IV"}, - {TLS1_RT_CRYPTO_IV | TLS1_RT_CRYPTO_READ, "Read IV"}, - {TLS1_RT_CRYPTO_FIXED_IV | TLS1_RT_CRYPTO_WRITE, "Write IV (fixed part)"}, - {TLS1_RT_CRYPTO_FIXED_IV | TLS1_RT_CRYPTO_READ, "Read IV (fixed part)"} -}; - -static void ssl_print_hex(BIO *bio, int indent, const char *name, - const unsigned char *msg, size_t msglen) -{ - size_t i; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "%s (len=%d): ", name, (int)msglen); - for (i = 0; i < msglen; i++) - BIO_printf(bio, "%02X", msg[i]); - BIO_puts(bio, "\n"); -} - -static int ssl_print_hexbuf(BIO *bio, int indent, - const char *name, size_t nlen, - const unsigned char **pmsg, size_t *pmsglen) -{ - size_t blen; - const unsigned char *p = *pmsg; - if (*pmsglen < nlen) - return 0; - blen = p[0]; - if (nlen > 1) - blen = (blen << 8) | p[1]; - if (*pmsglen < nlen + blen) - return 0; - p += nlen; - ssl_print_hex(bio, indent, name, p, blen); - *pmsg += blen + nlen; - *pmsglen -= blen + nlen; - return 1; -} - -static int ssl_print_version(BIO *bio, int indent, const char *name, - const unsigned char **pmsg, size_t *pmsglen) -{ - int vers; - if (*pmsglen < 2) - return 0; - vers = ((*pmsg)[0] << 8) | (*pmsg)[1]; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "%s=0x%x (%s)\n", - name, vers, ssl_trace_str(vers, ssl_version_tbl)); - *pmsg += 2; - *pmsglen -= 2; - return 1; -} - -static int ssl_print_random(BIO *bio, int indent, - const unsigned char **pmsg, size_t *pmsglen) -{ - unsigned int tm; - const unsigned char *p = *pmsg; - if (*pmsglen < 32) - return 0; - tm = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - p += 4; - BIO_indent(bio, indent, 80); - BIO_puts(bio, "Random:\n"); - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "gmt_unix_time=0x%08X\n", tm); - ssl_print_hex(bio, indent + 2, "random_bytes", p, 28); - *pmsg += 32; - *pmsglen -= 32; - return 1; -} - -static int ssl_print_signature(BIO *bio, int indent, SSL *s, - const unsigned char **pmsg, size_t *pmsglen) -{ - if (*pmsglen < 2) - return 0; - if (SSL_USE_SIGALGS(s)) { - const unsigned char *p = *pmsg; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "Signature Algorithm %s+%s (%d+%d)\n", - ssl_trace_str(p[0], ssl_md_tbl), - ssl_trace_str(p[1], ssl_sig_tbl), p[0], p[1]); - *pmsg += 2; - *pmsglen -= 2; - } - return ssl_print_hexbuf(bio, indent, "Signature", 2, pmsg, pmsglen); -} - -static int ssl_print_extension(BIO *bio, int indent, int server, int extype, - const unsigned char *ext, size_t extlen) -{ - size_t xlen; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "extension_type=%s(%d), length=%d\n", - ssl_trace_str(extype, ssl_exts_tbl), extype, (int)extlen); - switch (extype) { - case TLSEXT_TYPE_ec_point_formats: - if (extlen < 1) - return 0; - xlen = ext[0]; - if (extlen != xlen + 1) - return 0; - return ssl_trace_list(bio, indent + 2, - ext + 1, xlen, 1, ssl_point_tbl); - - case TLSEXT_TYPE_elliptic_curves: - if (extlen < 2) - return 0; - xlen = (ext[0] << 8) | ext[1]; - if (extlen != xlen + 2) - return 0; - return ssl_trace_list(bio, indent + 2, - ext + 2, xlen, 2, ssl_curve_tbl); - - case TLSEXT_TYPE_signature_algorithms: - - if (extlen < 2) - return 0; - xlen = (ext[0] << 8) | ext[1]; - if (extlen != xlen + 2) - return 0; - if (xlen & 1) - return 0; - ext += 2; - while (xlen > 0) { - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "%s+%s (%d+%d)\n", - ssl_trace_str(ext[0], ssl_md_tbl), - ssl_trace_str(ext[1], ssl_sig_tbl), ext[0], ext[1]); - xlen -= 2; - ext += 2; - } - break; - - case TLSEXT_TYPE_renegotiate: - if (extlen < 1) - return 0; - xlen = ext[0]; - if (xlen + 1 != extlen) - return 0; - ext++; - if (xlen) { - if (server) { - if (xlen & 1) - return 0; - xlen >>= 1; - } - ssl_print_hex(bio, indent + 4, "client_verify_data", ext, xlen); - if (server) { - ext += xlen; - ssl_print_hex(bio, indent + 4, - "server_verify_data", ext, xlen); - } - } else { - BIO_indent(bio, indent + 4, 80); - BIO_puts(bio, "\n"); - } - break; - - case TLSEXT_TYPE_heartbeat: - if (extlen != 1) - return 0; - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "HeartbeatMode: %s\n", - ssl_trace_str(ext[0], ssl_hb_tbl)); - break; - - case TLSEXT_TYPE_session_ticket: - if (extlen != 0) - ssl_print_hex(bio, indent + 4, "ticket", ext, extlen); - break; - - default: - BIO_dump_indent(bio, (char *)ext, extlen, indent + 2); - } - return 1; -} - -static int ssl_print_extensions(BIO *bio, int indent, int server, - const unsigned char *msg, size_t msglen) -{ - size_t extslen; - BIO_indent(bio, indent, 80); - if (msglen == 0) { - BIO_puts(bio, "No Extensions\n"); - return 1; - } - if (msglen < 2) - return 0; - extslen = (msg[0] << 8) | msg[1]; - if (extslen != msglen - 2) - return 0; - msg += 2; - msglen = extslen; - BIO_printf(bio, "extensions, length = %d\n", (int)msglen); - while (msglen > 0) { - int extype; - size_t extlen; - if (msglen < 4) - return 0; - extype = (msg[0] << 8) | msg[1]; - extlen = (msg[2] << 8) | msg[3]; - if (msglen < extlen + 4) - return 0; - msg += 4; - if (!ssl_print_extension(bio, indent + 2, server, - extype, msg, extlen)) - return 0; - msg += extlen; - msglen -= extlen + 4; - } - return 1; -} - -static int ssl_print_client_hello(BIO *bio, SSL *ssl, int indent, - const unsigned char *msg, size_t msglen) -{ - size_t len; - unsigned int cs; - if (!ssl_print_version(bio, indent, "client_version", &msg, &msglen)) - return 0; - if (!ssl_print_random(bio, indent, &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen)) - return 0; - if (SSL_IS_DTLS(ssl)) { - if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen)) - return 0; - } - if (msglen < 2) - return 0; - len = (msg[0] << 8) | msg[1]; - msg += 2; - msglen -= 2; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "cipher_suites (len=%d)\n", (int)len); - if (msglen < len || len & 1) - return 0; - while (len > 0) { - cs = (msg[0] << 8) | msg[1]; - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "{0x%02X, 0x%02X} %s\n", - msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl)); - msg += 2; - msglen -= 2; - len -= 2; - } - if (msglen < 1) - return 0; - len = msg[0]; - msg++; - msglen--; - if (msglen < len) - return 0; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "compression_methods (len=%d)\n", (int)len); - while (len > 0) { - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "%s (0x%02X)\n", - ssl_trace_str(msg[0], ssl_comp_tbl), msg[0]); - msg++; - msglen--; - len--; - } - if (!ssl_print_extensions(bio, indent, 0, msg, msglen)) - return 0; - return 1; -} - -static int dtls_print_hello_vfyrequest(BIO *bio, int indent, - const unsigned char *msg, - size_t msglen) -{ - if (!ssl_print_version(bio, indent, "server_version", &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent, "cookie", 1, &msg, &msglen)) - return 0; - return 1; -} - -static int ssl_print_server_hello(BIO *bio, int indent, - const unsigned char *msg, size_t msglen) -{ - unsigned int cs; - if (!ssl_print_version(bio, indent, "server_version", &msg, &msglen)) - return 0; - if (!ssl_print_random(bio, indent, &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen)) - return 0; - if (msglen < 2) - return 0; - cs = (msg[0] << 8) | msg[1]; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "cipher_suite {0x%02X, 0x%02X} %s\n", - msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl)); - msg += 2; - msglen -= 2; - if (msglen < 1) - return 0; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "compression_method: %s (0x%02X)\n", - ssl_trace_str(msg[0], ssl_comp_tbl), msg[0]); - msg++; - msglen--; - if (!ssl_print_extensions(bio, indent, 1, msg, msglen)) - return 0; - return 1; -} - -static int ssl_get_keyex(const char **pname, SSL *ssl) -{ - unsigned long alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey; - if (alg_k & SSL_kRSA) { - *pname = "rsa"; - return SSL_kRSA; - } - if (alg_k & SSL_kDHr) { - *pname = "dh_rsa"; - return SSL_kDHr; - } - if (alg_k & SSL_kDHd) { - *pname = "dh_dss"; - return SSL_kDHd; - } - if (alg_k & SSL_kKRB5) { - *pname = "krb5"; - return SSL_kKRB5; - } - if (alg_k & SSL_kEDH) { - *pname = "edh"; - return SSL_kEDH; - } - if (alg_k & SSL_kEECDH) { - *pname = "EECDH"; - return SSL_kEECDH; - } - if (alg_k & SSL_kECDHr) { - *pname = "ECDH RSA"; - return SSL_kECDHr; - } - if (alg_k & SSL_kECDHe) { - *pname = "ECDH ECDSA"; - return SSL_kECDHe; - } - if (alg_k & SSL_kPSK) { - *pname = "PSK"; - return SSL_kPSK; - } - if (alg_k & SSL_kSRP) { - *pname = "SRP"; - return SSL_kSRP; - } - if (alg_k & SSL_kGOST) { - *pname = "GOST"; - return SSL_kGOST; - } - *pname = "UNKNOWN"; - return 0; -} - -static int ssl_print_client_keyex(BIO *bio, int indent, SSL *ssl, - const unsigned char *msg, size_t msglen) -{ - const char *algname; - int id; - id = ssl_get_keyex(&algname, ssl); - BIO_indent(bio, indent, 80); - BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname); - switch (id) { - - case SSL_kRSA: - if (TLS1_get_version(ssl) == SSL3_VERSION) { - ssl_print_hex(bio, indent + 2, - "EncyptedPreMasterSecret", msg, msglen); - } else { - if (!ssl_print_hexbuf(bio, indent + 2, - "EncyptedPreMasterSecret", 2, - &msg, &msglen)) - return 0; - } - break; - - /* Implicit parameters only allowed for static DH */ - case SSL_kDHd: - case SSL_kDHr: - if (msglen == 0) { - BIO_indent(bio, indent + 2, 80); - BIO_puts(bio, "implicit\n"); - break; - } - case SSL_kEDH: - if (!ssl_print_hexbuf(bio, indent + 2, "dh_Yc", 2, &msg, &msglen)) - return 0; - break; - - case SSL_kECDHr: - case SSL_kECDHe: - if (msglen == 0) { - BIO_indent(bio, indent + 2, 80); - BIO_puts(bio, "implicit\n"); - break; - } - case SSL_kEECDH: - if (!ssl_print_hexbuf(bio, indent + 2, "ecdh_Yc", 1, &msg, &msglen)) - return 0; - break; - } - - return 1; -} - -static int ssl_print_server_keyex(BIO *bio, int indent, SSL *ssl, - const unsigned char *msg, size_t msglen) -{ - const char *algname; - int id; - id = ssl_get_keyex(&algname, ssl); - BIO_indent(bio, indent, 80); - BIO_printf(bio, "KeyExchangeAlgorithm=%s\n", algname); - switch (id) { - /* Should never happen */ - case SSL_kDHd: - case SSL_kDHr: - case SSL_kECDHr: - case SSL_kECDHe: - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "Unexpected Message\n"); - break; - - case SSL_kRSA: - - if (!ssl_print_hexbuf(bio, indent + 2, "rsa_modulus", 2, - &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent + 2, "rsa_exponent", 2, - &msg, &msglen)) - return 0; - break; - - case SSL_kEDH: - if (!ssl_print_hexbuf(bio, indent + 2, "dh_p", 2, &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent + 2, "dh_g", 2, &msg, &msglen)) - return 0; - if (!ssl_print_hexbuf(bio, indent + 2, "dh_Ys", 2, &msg, &msglen)) - return 0; - break; - - case SSL_kEECDH: - if (msglen < 1) - return 0; - BIO_indent(bio, indent + 2, 80); - if (msg[0] == EXPLICIT_PRIME_CURVE_TYPE) - BIO_puts(bio, "explicit_prime\n"); - else if (msg[0] == EXPLICIT_CHAR2_CURVE_TYPE) - BIO_puts(bio, "explicit_char2\n"); - else if (msg[0] == NAMED_CURVE_TYPE) { - int curve; - if (msglen < 3) - return 0; - curve = (msg[1] << 8) | msg[2]; - BIO_printf(bio, "named_curve: %s (%d)\n", - ssl_trace_str(curve, ssl_curve_tbl), curve); - msg += 3; - msglen -= 3; - if (!ssl_print_hexbuf(bio, indent + 2, "point", 1, &msg, &msglen)) - return 0; - } - break; - } - return ssl_print_signature(bio, indent, ssl, &msg, &msglen); -} - -static int ssl_print_certificate(BIO *bio, int indent, - const unsigned char **pmsg, size_t *pmsglen) -{ - size_t msglen = *pmsglen; - size_t clen; - X509 *x; - const unsigned char *p = *pmsg, *q; - if (msglen < 3) - return 0; - clen = (p[0] << 16) | (p[1] << 8) | p[2]; - if (msglen < clen + 3) - return 0; - q = p + 3; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "ASN.1Cert, length=%d", (int)clen); - x = d2i_X509(NULL, &q, clen); - if (!x) - BIO_puts(bio, "\n"); - else { - BIO_puts(bio, "\n------details-----\n"); - X509_print_ex(bio, x, XN_FLAG_ONELINE, 0); - PEM_write_bio_X509(bio, x); - /* Print certificate stuff */ - BIO_puts(bio, "------------------\n"); - X509_free(x); - } - if (q != p + 3 + clen) { - BIO_puts(bio, "\n"); - } - *pmsg += clen + 3; - *pmsglen -= clen + 3; - return 1; -} - -static int ssl_print_certificates(BIO *bio, int indent, - const unsigned char *msg, size_t msglen) -{ - size_t clen; - if (msglen < 3) - return 0; - clen = (msg[0] << 16) | (msg[1] << 8) | msg[2]; - if (msglen != clen + 3) - return 0; - msg += 3; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "certificate_list, length=%d\n", (int)clen); - while (clen > 0) { - if (!ssl_print_certificate(bio, indent + 2, &msg, &clen)) - return 0; - } - return 1; -} - -static int ssl_print_cert_request(BIO *bio, int indent, SSL *s, - const unsigned char *msg, size_t msglen) -{ - size_t xlen; - if (msglen < 1) - return 0; - xlen = msg[0]; - if (msglen < xlen + 1) - return 0; - msg++; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "certificate_types (len=%d)\n", (int)xlen); - if (!ssl_trace_list(bio, indent + 2, msg, xlen, 1, ssl_ctype_tbl)) - return 0; - msg += xlen; - msglen -= xlen + 1; - if (!SSL_USE_SIGALGS(s)) - goto skip_sig; - if (msglen < 2) - return 0; - xlen = (msg[0] << 8) | msg[1]; - if (msglen < xlen + 2 || (xlen & 1)) - return 0; - msg += 2; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "signature_algorithms (len=%d)\n", (int)xlen); - while (xlen > 0) { - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "%s+%s (%d+%d)\n", - ssl_trace_str(msg[0], ssl_md_tbl), - ssl_trace_str(msg[1], ssl_sig_tbl), msg[0], msg[1]); - xlen -= 2; - msg += 2; - } - msg += xlen; - msglen -= xlen + 2; - - skip_sig: - if (msglen < 2) - return 0; - xlen = (msg[0] << 8) | msg[1]; - BIO_indent(bio, indent, 80); - if (msglen < xlen + 2) - return 0; - msg += 2; - msglen -= 2; - BIO_printf(bio, "certificate_authorities (len=%d)\n", (int)xlen); - while (xlen > 0) { - size_t dlen; - X509_NAME *nm; - const unsigned char *p; - if (xlen < 2) - return 0; - dlen = (msg[0] << 8) | msg[1]; - if (xlen < dlen + 2) - return 0; - msg += 2; - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "DistinguishedName (len=%d): ", (int)dlen); - p = msg; - nm = d2i_X509_NAME(NULL, &p, dlen); - if (!nm) { - BIO_puts(bio, "\n"); - } else { - X509_NAME_print_ex(bio, nm, 0, XN_FLAG_ONELINE); - BIO_puts(bio, "\n"); - X509_NAME_free(nm); - } - xlen -= dlen + 2; - msg += dlen; - } - return 1; -} - -static int ssl_print_ticket(BIO *bio, int indent, - const unsigned char *msg, size_t msglen) -{ - unsigned int tick_life; - if (msglen == 0) { - BIO_indent(bio, indent + 2, 80); - BIO_puts(bio, "No Ticket\n"); - return 1; - } - if (msglen < 4) - return 0; - tick_life = (msg[0] << 24) | (msg[1] << 16) | (msg[2] << 8) | msg[3]; - msglen -= 4; - msg += 4; - BIO_indent(bio, indent + 2, 80); - BIO_printf(bio, "ticket_lifetime_hint=%u\n", tick_life); - if (!ssl_print_hexbuf(bio, indent + 2, "ticket", 2, &msg, &msglen)) - return 0; - if (msglen) - return 0; - return 1; -} - -static int ssl_print_handshake(BIO *bio, SSL *ssl, - const unsigned char *msg, size_t msglen, - int indent) -{ - size_t hlen; - unsigned char htype; - if (msglen < 4) - return 0; - htype = msg[0]; - hlen = (msg[1] << 16) | (msg[2] << 8) | msg[3]; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "%s, Length=%d\n", - ssl_trace_str(htype, ssl_handshake_tbl), (int)hlen); - msg += 4; - msglen -= 4; - if (SSL_IS_DTLS(ssl)) { - if (msglen < 8) - return 0; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "message_seq=%d, fragment_offset=%d, " - "fragment_length=%d\n", - (msg[0] << 8) | msg[1], - (msg[2] << 16) | (msg[3] << 8) | msg[4], - (msg[5] << 16) | (msg[6] << 8) | msg[7]); - msg += 8; - msglen -= 8; - } - if (msglen < hlen) - return 0; - switch (htype) { - case SSL3_MT_CLIENT_HELLO: - if (!ssl_print_client_hello(bio, ssl, indent + 2, msg, msglen)) - return 0; - break; - - case DTLS1_MT_HELLO_VERIFY_REQUEST: - if (!dtls_print_hello_vfyrequest(bio, indent + 2, msg, msglen)) - return 0; - break; - - case SSL3_MT_SERVER_HELLO: - if (!ssl_print_server_hello(bio, indent + 2, msg, msglen)) - return 0; - break; - - case SSL3_MT_SERVER_KEY_EXCHANGE: - if (!ssl_print_server_keyex(bio, indent + 2, ssl, msg, msglen)) - return 0; - break; - - case SSL3_MT_CLIENT_KEY_EXCHANGE: - if (!ssl_print_client_keyex(bio, indent + 2, ssl, msg, msglen)) - return 0; - break; - - case SSL3_MT_CERTIFICATE: - if (!ssl_print_certificates(bio, indent + 2, msg, msglen)) - return 0; - break; - - case SSL3_MT_CERTIFICATE_VERIFY: - if (!ssl_print_signature(bio, indent + 2, ssl, &msg, &msglen)) - return 0; - break; - - case SSL3_MT_CERTIFICATE_REQUEST: - if (!ssl_print_cert_request(bio, indent + 2, ssl, msg, msglen)) - return 0; - break; - - case SSL3_MT_FINISHED: - ssl_print_hex(bio, indent + 2, "verify_data", msg, msglen); - break; - - case SSL3_MT_SERVER_DONE: - if (msglen != 0) - ssl_print_hex(bio, indent + 2, "unexpected value", msg, msglen); - break; - - case SSL3_MT_NEWSESSION_TICKET: - if (!ssl_print_ticket(bio, indent + 2, msg, msglen)) - return 0; - break; - - default: - BIO_indent(bio, indent + 2, 80); - BIO_puts(bio, "Unsupported, hex dump follows:\n"); - BIO_dump_indent(bio, (char *)msg, msglen, indent + 4); - } - return 1; -} - -static int ssl_print_heartbeat(BIO *bio, int indent, - const unsigned char *msg, size_t msglen) -{ - if (msglen < 3) - return 0; - BIO_indent(bio, indent, 80); - BIO_printf(bio, "HeartBeatMessageType: %s\n", - ssl_trace_str(msg[0], ssl_hb_type_tbl)); - msg++; - msglen--; - if (!ssl_print_hexbuf(bio, indent, "payload", 2, &msg, &msglen)) - return 0; - ssl_print_hex(bio, indent, "padding", msg, msglen); - return 1; -} - -const char *SSL_CIPHER_standard_name(const SSL_CIPHER *c) -{ - if (c->algorithm_ssl & SSL_SSLV2) - return NULL; - return ssl_trace_str(c->id & 0xFFFF, ssl_ciphers_tbl); -} - -void SSL_trace(int write_p, int version, int content_type, - const void *buf, size_t msglen, SSL *ssl, void *arg) -{ - const unsigned char *msg = buf; - BIO *bio = arg; - - if (write_p == 2) { - BIO_puts(bio, "Session "); - ssl_print_hex(bio, 0, - ssl_trace_str(content_type, ssl_crypto_tbl), - msg, msglen); - return; - } - switch (content_type) { - case SSL3_RT_HEADER: - { - int hvers; - - /* avoid overlapping with length at the end of buffer */ - if (msglen < (SSL_IS_DTLS(ssl) ? 13 : 5)) { - BIO_puts(bio, write_p ? "Sent" : "Received"); - ssl_print_hex(bio, 0, " too short message", msg, msglen); - break; - } - hvers = msg[1] << 8 | msg[2]; - BIO_puts(bio, write_p ? "Sent" : "Received"); - BIO_printf(bio, " Record\nHeader:\n Version = %s (0x%x)\n", - ssl_trace_str(hvers, ssl_version_tbl), hvers); - if (SSL_IS_DTLS(ssl)) { - BIO_printf(bio, - " epoch=%d, sequence_number=%04x%04x%04x\n", - (msg[3] << 8 | msg[4]), - (msg[5] << 8 | msg[6]), - (msg[7] << 8 | msg[8]), (msg[9] << 8 | msg[10])); -# if 0 - /* - * Just print handshake type so we can see what is going on - * during fragmentation. - */ - BIO_printf(bio, "(%s)\n", - ssl_trace_str(msg[msglen], ssl_handshake_tbl)); -# endif - } - - BIO_printf(bio, " Content Type = %s (%d)\n Length = %d", - ssl_trace_str(msg[0], ssl_content_tbl), msg[0], - msg[msglen - 2] << 8 | msg[msglen - 1]); - } - break; - case SSL3_RT_HANDSHAKE: - if (!ssl_print_handshake(bio, ssl, msg, msglen, 4)) - BIO_printf(bio, "Message length parse error!\n"); - break; - - case SSL3_RT_CHANGE_CIPHER_SPEC: - if (msglen == 1 && msg[0] == 1) - BIO_puts(bio, " change_cipher_spec (1)\n"); - else - ssl_print_hex(bio, 4, "unknown value", msg, msglen); - break; - - case SSL3_RT_ALERT: - if (msglen != 2) { - BIO_puts(bio, " Illegal Alert Length\n"); - } else { - BIO_printf(bio, " Level=%s(%d), description=%s(%d)\n", - SSL_alert_type_string_long(msg[0] << 8), - msg[0], SSL_alert_desc_string_long(msg[1]), msg[1]); - } - break; - - case TLS1_RT_HEARTBEAT: - ssl_print_heartbeat(bio, 4, msg, msglen); - break; - - } - - BIO_puts(bio, "\n"); -} - -#endif diff --git a/Sources/COpenSSL/t_.c b/Sources/COpenSSL/t_.c deleted file mode 100644 index 756b66ba..00000000 --- a/Sources/COpenSSL/t_.c +++ /dev/null @@ -1,1386 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* t_bitst.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "conf.h" -#include "x509v3.h" - -int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, - BIT_STRING_BITNAME *tbl, int indent) -{ - BIT_STRING_BITNAME *bnam; - char first = 1; - BIO_printf(out, "%*s", indent, ""); - for (bnam = tbl; bnam->lname; bnam++) { - if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) { - if (!first) - BIO_puts(out, ", "); - BIO_puts(out, bnam->lname); - first = 0; - } - } - BIO_puts(out, "\n"); - return 1; -} - -int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, - BIT_STRING_BITNAME *tbl) -{ - int bitnum; - bitnum = ASN1_BIT_STRING_num_asc(name, tbl); - if (bitnum < 0) - return 0; - if (bs) { - if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value)) - return 0; - } - return 1; -} - -int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl) -{ - BIT_STRING_BITNAME *bnam; - for (bnam = tbl; bnam->lname; bnam++) { - if (!strcmp(bnam->sname, name) || !strcmp(bnam->lname, name)) - return bnam->bitnum; - } - return -1; -} -/* t_crl.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -#include "buffer.h" -#include "bn.h" -#include "objects.h" -#include "x509.h" -// #include "x509v3.h" - -#ifndef OPENSSL_NO_FP_API -int X509_CRL_print_fp(FILE *fp, X509_CRL *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = X509_CRL_print(b, x); - BIO_free(b); - return (ret); -} -#endif - -int X509_CRL_print(BIO *out, X509_CRL *x) -{ - STACK_OF(X509_REVOKED) *rev; - X509_REVOKED *r; - long l; - int i; - char *p; - - BIO_printf(out, "Certificate Revocation List (CRL):\n"); - l = X509_CRL_get_version(x); - BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l); - i = OBJ_obj2nid(x->sig_alg->algorithm); - X509_signature_print(out, x->sig_alg, NULL); - p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); - BIO_printf(out, "%8sIssuer: %s\n", "", p); - OPENSSL_free(p); - BIO_printf(out, "%8sLast Update: ", ""); - ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x)); - BIO_printf(out, "\n%8sNext Update: ", ""); - if (X509_CRL_get_nextUpdate(x)) - ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x)); - else - BIO_printf(out, "NONE"); - BIO_printf(out, "\n"); - - X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8); - - rev = X509_CRL_get_REVOKED(x); - - if (sk_X509_REVOKED_num(rev) > 0) - BIO_printf(out, "Revoked Certificates:\n"); - else - BIO_printf(out, "No Revoked Certificates.\n"); - - for (i = 0; i < sk_X509_REVOKED_num(rev); i++) { - r = sk_X509_REVOKED_value(rev, i); - BIO_printf(out, " Serial Number: "); - i2a_ASN1_INTEGER(out, r->serialNumber); - BIO_printf(out, "\n Revocation Date: "); - ASN1_TIME_print(out, r->revocationDate); - BIO_printf(out, "\n"); - X509V3_extensions_print(out, "CRL entry extensions", - r->extensions, 0, 8); - } - X509_signature_print(out, x->sig_alg, x->signature); - - return 1; - -} -/* crypto/asn1/t_pkey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "buffer.h" -// #include "bn.h" - -int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, - unsigned char *buf, int off) -{ - int n, i; - const char *neg; - - if (num == NULL) - return (1); - neg = (BN_is_negative(num)) ? "-" : ""; - if (!BIO_indent(bp, off, 128)) - return 0; - if (BN_is_zero(num)) { - if (BIO_printf(bp, "%s 0\n", number) <= 0) - return 0; - return 1; - } - - if (BN_num_bytes(num) <= BN_BYTES) { - if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg, - (unsigned long)num->d[0], neg, - (unsigned long)num->d[0]) - <= 0) - return (0); - } else { - buf[0] = 0; - if (BIO_printf(bp, "%s%s", number, - (neg[0] == '-') ? " (Negative)" : "") <= 0) - return (0); - n = BN_bn2bin(num, &buf[1]); - - if (buf[1] & 0x80) - n++; - else - buf++; - - for (i = 0; i < n; i++) { - if ((i % 15) == 0) { - if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, off + 4, 128)) - return 0; - } - if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") - <= 0) - return (0); - } - if (BIO_write(bp, "\n", 1) <= 0) - return (0); - } - return (1); -} -/* crypto/asn1/t_req.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "bn.h" -// #include "objects.h" -// #include "x509.h" -// #include "x509v3.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif - -#ifndef OPENSSL_NO_FP_API -int X509_REQ_print_fp(FILE *fp, X509_REQ *x) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = X509_REQ_print(b, x); - BIO_free(b); - return (ret); -} -#endif - -int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, - unsigned long cflag) -{ - unsigned long l; - int i; - const char *neg; - X509_REQ_INFO *ri; - EVP_PKEY *pkey; - STACK_OF(X509_ATTRIBUTE) *sk; - STACK_OF(X509_EXTENSION) *exts; - char mlch = ' '; - int nmindent = 0; - - if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { - mlch = '\n'; - nmindent = 12; - } - - if (nmflags == X509_FLAG_COMPAT) - nmindent = 16; - - ri = x->req_info; - if (!(cflag & X509_FLAG_NO_HEADER)) { - if (BIO_write(bp, "Certificate Request:\n", 21) <= 0) - goto err; - if (BIO_write(bp, " Data:\n", 10) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_VERSION)) { - neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : ""; - l = 0; - for (i = 0; i < ri->version->length; i++) { - l <<= 8; - l += ri->version->data[i]; - } - if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg, l, neg, - l) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_SUBJECT)) { - if (BIO_printf(bp, " Subject:%c", mlch) <= 0) - goto err; - if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_PUBKEY)) { - if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) - goto err; - if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) - goto err; - if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0) - goto err; - if (BIO_puts(bp, "\n") <= 0) - goto err; - - pkey = X509_REQ_get_pubkey(x); - if (pkey == NULL) { - BIO_printf(bp, "%12sUnable to load Public Key\n", ""); - ERR_print_errors(bp); - } else { - EVP_PKEY_print_public(bp, pkey, 16, NULL); - EVP_PKEY_free(pkey); - } - } - - if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { - /* may not be */ - if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0) - goto err; - - sk = x->req_info->attributes; - if (sk_X509_ATTRIBUTE_num(sk) == 0) { - if (BIO_printf(bp, "%12sa0:00\n", "") <= 0) - goto err; - } else { - for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { - ASN1_TYPE *at; - X509_ATTRIBUTE *a; - ASN1_BIT_STRING *bs = NULL; - ASN1_TYPE *t; - int j, type = 0, count = 1, ii = 0; - - a = sk_X509_ATTRIBUTE_value(sk, i); - if (X509_REQ_extension_nid(OBJ_obj2nid(a->object))) - continue; - if (BIO_printf(bp, "%12s", "") <= 0) - goto err; - if ((j = i2a_ASN1_OBJECT(bp, a->object)) > 0) { - if (a->single) { - t = a->value.single; - type = t->type; - bs = t->value.bit_string; - } else { - ii = 0; - count = sk_ASN1_TYPE_num(a->value.set); - get_next: - at = sk_ASN1_TYPE_value(a->value.set, ii); - type = at->type; - bs = at->value.asn1_string; - } - } - for (j = 25 - j; j > 0; j--) - if (BIO_write(bp, " ", 1) != 1) - goto err; - if (BIO_puts(bp, ":") <= 0) - goto err; - if ((type == V_ASN1_PRINTABLESTRING) || - (type == V_ASN1_UTF8STRING) || - (type == V_ASN1_T61STRING) || - (type == V_ASN1_IA5STRING)) { - if (BIO_write(bp, (char *)bs->data, bs->length) - != bs->length) - goto err; - BIO_puts(bp, "\n"); - } else { - BIO_puts(bp, "unable to print attribute\n"); - } - if (++ii < count) - goto get_next; - } - } - } - if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { - exts = X509_REQ_get_extensions(x); - if (exts) { - BIO_printf(bp, "%8sRequested Extensions:\n", ""); - for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { - ASN1_OBJECT *obj; - X509_EXTENSION *ex; - int j; - ex = sk_X509_EXTENSION_value(exts, i); - if (BIO_printf(bp, "%12s", "") <= 0) - goto err; - obj = X509_EXTENSION_get_object(ex); - i2a_ASN1_OBJECT(bp, obj); - j = X509_EXTENSION_get_critical(ex); - if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) - goto err; - if (!X509V3_EXT_print(bp, ex, cflag, 16)) { - BIO_printf(bp, "%16s", ""); - M_ASN1_OCTET_STRING_print(bp, ex->value); - } - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - } - } - - if (!(cflag & X509_FLAG_NO_SIGDUMP)) { - if (!X509_signature_print(bp, x->sig_alg, x->signature)) - goto err; - } - - return (1); - err: - X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB); - return (0); -} - -int X509_REQ_print(BIO *bp, X509_REQ *x) -{ - return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); -} -/* t_spki.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "x509.h" -#include "asn1.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -// #include "bn.h" - -/* Print out an SPKI */ - -int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) -{ - EVP_PKEY *pkey; - ASN1_IA5STRING *chal; - int i, n; - char *s; - BIO_printf(out, "Netscape SPKI:\n"); - i = OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm); - BIO_printf(out, " Public Key Algorithm: %s\n", - (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); - pkey = X509_PUBKEY_get(spki->spkac->pubkey); - if (!pkey) - BIO_printf(out, " Unable to load public key\n"); - else { - EVP_PKEY_print_public(out, pkey, 4, NULL); - EVP_PKEY_free(pkey); - } - chal = spki->spkac->challenge; - if (chal->length) - BIO_printf(out, " Challenge String: %s\n", chal->data); - i = OBJ_obj2nid(spki->sig_algor->algorithm); - BIO_printf(out, " Signature Algorithm: %s", - (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); - - n = spki->signature->length; - s = (char *)spki->signature->data; - for (i = 0; i < n; i++) { - if ((i % 18) == 0) - BIO_write(out, "\n ", 7); - BIO_printf(out, "%02x%s", (unsigned char)s[i], - ((i + 1) == n) ? "" : ":"); - } - BIO_write(out, "\n", 1); - return 1; -} -/* crypto/asn1/t_x509.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "buffer.h" -// #include "bn.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif -#ifndef OPENSSL_NO_EC -# include "ec.h" -#endif -// #include "objects.h" -// #include "x509.h" -// #include "x509v3.h" -#include "asn1_locl.h" - -#ifndef OPENSSL_NO_FP_API -int X509_print_fp(FILE *fp, X509 *x) -{ - return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); -} - -int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, - unsigned long cflag) -{ - BIO *b; - int ret; - - if ((b = BIO_new(BIO_s_file())) == NULL) { - X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB); - return (0); - } - BIO_set_fp(b, fp, BIO_NOCLOSE); - ret = X509_print_ex(b, x, nmflag, cflag); - BIO_free(b); - return (ret); -} -#endif - -int X509_print(BIO *bp, X509 *x) -{ - return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); -} - -int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, - unsigned long cflag) -{ - long l; - int ret = 0, i; - char *m = NULL, mlch = ' '; - int nmindent = 0; - X509_CINF *ci; - ASN1_INTEGER *bs; - EVP_PKEY *pkey = NULL; - const char *neg; - - if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { - mlch = '\n'; - nmindent = 12; - } - - if (nmflags == X509_FLAG_COMPAT) - nmindent = 16; - - ci = x->cert_info; - if (!(cflag & X509_FLAG_NO_HEADER)) { - if (BIO_write(bp, "Certificate:\n", 13) <= 0) - goto err; - if (BIO_write(bp, " Data:\n", 10) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_VERSION)) { - l = X509_get_version(x); - if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_SERIAL)) { - - if (BIO_write(bp, " Serial Number:", 22) <= 0) - goto err; - - bs = X509_get_serialNumber(x); - if (bs->length < (int)sizeof(long) - || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) { - l = ASN1_INTEGER_get(bs); - if (bs->type == V_ASN1_NEG_INTEGER) { - l = -l; - neg = "-"; - } else - neg = ""; - if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0) - goto err; - } else { - neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; - if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) - goto err; - - for (i = 0; i < bs->length; i++) { - if (BIO_printf(bp, "%02x%c", bs->data[i], - ((i + 1 == bs->length) ? '\n' : ':')) <= 0) - goto err; - } - } - - } - - if (!(cflag & X509_FLAG_NO_SIGNAME)) { - if (X509_signature_print(bp, ci->signature, NULL) <= 0) - goto err; -#if 0 - if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0) - goto err; - if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0) - goto err; - if (BIO_puts(bp, "\n") <= 0) - goto err; -#endif - } - - if (!(cflag & X509_FLAG_NO_ISSUER)) { - if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) - goto err; - if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) - < 0) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_VALIDITY)) { - if (BIO_write(bp, " Validity\n", 17) <= 0) - goto err; - if (BIO_write(bp, " Not Before: ", 24) <= 0) - goto err; - if (!ASN1_TIME_print(bp, X509_get_notBefore(x))) - goto err; - if (BIO_write(bp, "\n Not After : ", 25) <= 0) - goto err; - if (!ASN1_TIME_print(bp, X509_get_notAfter(x))) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_SUBJECT)) { - if (BIO_printf(bp, " Subject:%c", mlch) <= 0) - goto err; - if (X509_NAME_print_ex - (bp, X509_get_subject_name(x), nmindent, nmflags) < 0) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_PUBKEY)) { - if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) - goto err; - if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) - goto err; - if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) - goto err; - if (BIO_puts(bp, "\n") <= 0) - goto err; - - pkey = X509_get_pubkey(x); - if (pkey == NULL) { - BIO_printf(bp, "%12sUnable to load Public Key\n", ""); - ERR_print_errors(bp); - } else { - EVP_PKEY_print_public(bp, pkey, 16, NULL); - EVP_PKEY_free(pkey); - } - } - - if (!(cflag & X509_FLAG_NO_IDS)) { - if (ci->issuerUID) { - if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) - goto err; - if (!X509_signature_dump(bp, ci->issuerUID, 12)) - goto err; - } - if (ci->subjectUID) { - if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) - goto err; - if (!X509_signature_dump(bp, ci->subjectUID, 12)) - goto err; - } - } - - if (!(cflag & X509_FLAG_NO_EXTENSIONS)) - X509V3_extensions_print(bp, "X509v3 extensions", - ci->extensions, cflag, 8); - - if (!(cflag & X509_FLAG_NO_SIGDUMP)) { - if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) - goto err; - } - if (!(cflag & X509_FLAG_NO_AUX)) { - if (!X509_CERT_AUX_print(bp, x->aux, 0)) - goto err; - } - ret = 1; - err: - if (m != NULL) - OPENSSL_free(m); - return (ret); -} - -int X509_ocspid_print(BIO *bp, X509 *x) -{ - unsigned char *der = NULL; - unsigned char *dertmp; - int derlen; - int i; - unsigned char SHA1md[SHA_DIGEST_LENGTH]; - - /* - * display the hash of the subject as it would appear in OCSP requests - */ - if (BIO_printf(bp, " Subject OCSP hash: ") <= 0) - goto err; - derlen = i2d_X509_NAME(x->cert_info->subject, NULL); - if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL) - goto err; - i2d_X509_NAME(x->cert_info->subject, &dertmp); - - if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) - goto err; - for (i = 0; i < SHA_DIGEST_LENGTH; i++) { - if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) - goto err; - } - OPENSSL_free(der); - der = NULL; - - /* - * display the hash of the public key as it would appear in OCSP requests - */ - if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0) - goto err; - - if (!EVP_Digest(x->cert_info->key->public_key->data, - x->cert_info->key->public_key->length, - SHA1md, NULL, EVP_sha1(), NULL)) - goto err; - for (i = 0; i < SHA_DIGEST_LENGTH; i++) { - if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) - goto err; - } - BIO_printf(bp, "\n"); - - return (1); - err: - if (der != NULL) - OPENSSL_free(der); - return (0); -} - -int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) -{ - const unsigned char *s; - int i, n; - - n = sig->length; - s = sig->data; - for (i = 0; i < n; i++) { - if ((i % 18) == 0) { - if (BIO_write(bp, "\n", 1) <= 0) - return 0; - if (BIO_indent(bp, indent, indent) <= 0) - return 0; - } - if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0) - return 0; - } - if (BIO_write(bp, "\n", 1) != 1) - return 0; - - return 1; -} - -int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig) -{ - int sig_nid; - if (BIO_puts(bp, " Signature Algorithm: ") <= 0) - return 0; - if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) - return 0; - - sig_nid = OBJ_obj2nid(sigalg->algorithm); - if (sig_nid != NID_undef) { - int pkey_nid, dig_nid; - const EVP_PKEY_ASN1_METHOD *ameth; - if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) { - ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); - if (ameth && ameth->sig_print) - return ameth->sig_print(bp, sigalg, sig, 9, 0); - } - } - if (sig) - return X509_signature_dump(bp, sig, 9); - else if (BIO_puts(bp, "\n") <= 0) - return 0; - return 1; -} - -int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) -{ - int i, n; - char buf[80]; - const char *p; - - if (v == NULL) - return (0); - n = 0; - p = (const char *)v->data; - for (i = 0; i < v->length; i++) { - if ((p[i] > '~') || ((p[i] < ' ') && - (p[i] != '\n') && (p[i] != '\r'))) - buf[n] = '.'; - else - buf[n] = p[i]; - n++; - if (n >= 80) { - if (BIO_write(bp, buf, n) <= 0) - return (0); - n = 0; - } - } - if (n > 0) - if (BIO_write(bp, buf, n) <= 0) - return (0); - return (1); -} - -int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) -{ - if (tm->type == V_ASN1_UTCTIME) - return ASN1_UTCTIME_print(bp, tm); - if (tm->type == V_ASN1_GENERALIZEDTIME) - return ASN1_GENERALIZEDTIME_print(bp, tm); - BIO_write(bp, "Bad time value", 14); - return (0); -} - -static const char *mon[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" -}; - -int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) -{ - char *v; - int gmt = 0; - int i; - int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; - char *f = NULL; - int f_len = 0; - - i = tm->length; - v = (char *)tm->data; - - if (i < 12) - goto err; - if (v[i - 1] == 'Z') - gmt = 1; - for (i = 0; i < 12; i++) - if ((v[i] > '9') || (v[i] < '0')) - goto err; - y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 - + (v[2] - '0') * 10 + (v[3] - '0'); - M = (v[4] - '0') * 10 + (v[5] - '0'); - if ((M > 12) || (M < 1)) - goto err; - d = (v[6] - '0') * 10 + (v[7] - '0'); - h = (v[8] - '0') * 10 + (v[9] - '0'); - m = (v[10] - '0') * 10 + (v[11] - '0'); - if (tm->length >= 14 && - (v[12] >= '0') && (v[12] <= '9') && - (v[13] >= '0') && (v[13] <= '9')) { - s = (v[12] - '0') * 10 + (v[13] - '0'); - /* Check for fractions of seconds. */ - if (tm->length >= 15 && v[14] == '.') { - int l = tm->length; - f = &v[14]; /* The decimal point. */ - f_len = 1; - while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9') - ++f_len; - } - } - - if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", - mon[M - 1], d, h, m, s, f_len, f, y, - (gmt) ? " GMT" : "") <= 0) - return (0); - else - return (1); - err: - BIO_write(bp, "Bad time value", 14); - return (0); -} - -int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) -{ - const char *v; - int gmt = 0; - int i; - int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; - - i = tm->length; - v = (const char *)tm->data; - - if (i < 10) - goto err; - if (v[i - 1] == 'Z') - gmt = 1; - for (i = 0; i < 10; i++) - if ((v[i] > '9') || (v[i] < '0')) - goto err; - y = (v[0] - '0') * 10 + (v[1] - '0'); - if (y < 50) - y += 100; - M = (v[2] - '0') * 10 + (v[3] - '0'); - if ((M > 12) || (M < 1)) - goto err; - d = (v[4] - '0') * 10 + (v[5] - '0'); - h = (v[6] - '0') * 10 + (v[7] - '0'); - m = (v[8] - '0') * 10 + (v[9] - '0'); - if (tm->length >= 12 && - (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9')) - s = (v[10] - '0') * 10 + (v[11] - '0'); - - if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", - mon[M - 1], d, h, m, s, y + 1900, - (gmt) ? " GMT" : "") <= 0) - return (0); - else - return (1); - err: - BIO_write(bp, "Bad time value", 14); - return (0); -} - -int X509_NAME_print(BIO *bp, X509_NAME *name, int obase) -{ - char *s, *c, *b; - int ret = 0, l, i; - - l = 80 - 2 - obase; - - b = X509_NAME_oneline(name, NULL, 0); - if (!b) - return 0; - if (!*b) { - OPENSSL_free(b); - return 1; - } - s = b + 1; /* skip the first slash */ - - c = s; - for (;;) { -#ifndef CHARSET_EBCDIC - if (((*s == '/') && - ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || - ((s[2] >= 'A') - && (s[2] <= 'Z') - && (s[3] == '=')) - ))) || (*s == '\0')) -#else - if (((*s == '/') && - (isupper(s[1]) && ((s[2] == '=') || - (isupper(s[2]) && (s[3] == '=')) - ))) || (*s == '\0')) -#endif - { - i = s - c; - if (BIO_write(bp, c, i) != i) - goto err; - c = s + 1; /* skip following slash */ - if (*s != '\0') { - if (BIO_write(bp, ", ", 2) != 2) - goto err; - } - l--; - } - if (*s == '\0') - break; - s++; - l--; - } - - ret = 1; - if (0) { - err: - X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB); - } - OPENSSL_free(b); - return (ret); -} -/* t_x509a.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -#include "evp.h" -// #include "asn1.h" -// #include "x509.h" - -/* - * X509_CERT_AUX and string set routines - */ - -int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) -{ - char oidstr[80], first; - int i; - if (!aux) - return 1; - if (aux->trust) { - first = 1; - BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, ""); - for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { - if (!first) - BIO_puts(out, ", "); - else - first = 0; - OBJ_obj2txt(oidstr, sizeof(oidstr), - sk_ASN1_OBJECT_value(aux->trust, i), 0); - BIO_puts(out, oidstr); - } - BIO_puts(out, "\n"); - } else - BIO_printf(out, "%*sNo Trusted Uses.\n", indent, ""); - if (aux->reject) { - first = 1; - BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, ""); - for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { - if (!first) - BIO_puts(out, ", "); - else - first = 0; - OBJ_obj2txt(oidstr, sizeof(oidstr), - sk_ASN1_OBJECT_value(aux->reject, i), 0); - BIO_puts(out, oidstr); - } - BIO_puts(out, "\n"); - } else - BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); - if (aux->alias) - BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data); - if (aux->keyid) { - BIO_printf(out, "%*sKey Id: ", indent, ""); - for (i = 0; i < aux->keyid->length; i++) - BIO_printf(out, "%s%02X", i ? ":" : "", aux->keyid->data[i]); - BIO_write(out, "\n", 1); - } - return 1; -} diff --git a/Sources/COpenSSL/tasn_.c b/Sources/COpenSSL/tasn_.c deleted file mode 100644 index a27f70c7..00000000 --- a/Sources/COpenSSL/tasn_.c +++ /dev/null @@ -1,3568 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* tasn_dec.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include "asn1.h" -#include "asn1t.h" -#include "objects.h" -#include "buffer.h" -#include "err.h" - -/* - * Constructed types with a recursive definition (such as can be found in PKCS7) - * could eventually exceed the stack given malicious input with excessive - * recursion. Therefore we limit the stack depth. This is the maximum number of - * recursive invocations of asn1_item_embed_d2i(). - */ -#define ASN1_MAX_CONSTRUCTED_NEST 30 - -static int asn1_check_eoc(const unsigned char **in, long len); -static int asn1_find_end(const unsigned char **in, long len, char inf); - -static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, - char inf, int tag, int aclass, int depth); - -static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); - -static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, - char *inf, char *cst, - const unsigned char **in, long len, - int exptag, int expclass, char opt, ASN1_TLC *ctx); - -static int asn1_template_ex_d2i(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth); -static int asn1_template_noexp_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth); -static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, - ASN1_TLC *ctx); - -/* Table to convert tags to bit values, used for MSTRING type */ -static const unsigned long tag2bit[32] = { - /* tags 0 - 3 */ - 0, 0, 0, B_ASN1_BIT_STRING, - /* tags 4- 7 */ - B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, - /* tags 8-11 */ - B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, - /* tags 12-15 */ - B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, - /* tags 16-19 */ - B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, - /* tags 20-22 */ - B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, - /* tags 23-24 */ - B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, - /* tags 25-27 */ - B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, - /* tags 28-31 */ - B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, -}; - -unsigned long ASN1_tag2bit(int tag) -{ - if ((tag < 0) || (tag > 30)) - return 0; - return tag2bit[tag]; -} - -/* Macro to initialize and invalidate the cache */ - -#define asn1_tlc_clear(c) if (c) (c)->valid = 0 -/* Version to avoid compiler warning about 'c' always non-NULL */ -#define asn1_tlc_clear_nc(c) (c)->valid = 0 - -/* - * Decode an ASN1 item, this currently behaves just like a standard 'd2i' - * function. 'in' points to a buffer to read the data from, in future we - * will have more advanced versions that can input data a piece at a time and - * this will simply be a special case. - */ - -ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_ITEM *it) -{ - ASN1_TLC c; - ASN1_VALUE *ptmpval = NULL; - if (!pval) - pval = &ptmpval; - asn1_tlc_clear_nc(&c); - if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) - return *pval; - return NULL; -} - -int ASN1_template_d2i(ASN1_VALUE **pval, - const unsigned char **in, long len, - const ASN1_TEMPLATE *tt) -{ - ASN1_TLC c; - asn1_tlc_clear_nc(&c); - return asn1_template_ex_d2i(pval, in, len, tt, 0, &c, 0); -} - -/* - * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and - * tag mismatch return -1 to handle OPTIONAL - */ -static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, - long len, const ASN1_ITEM *it, int tag, int aclass, - char opt, ASN1_TLC *ctx, int depth) -{ - const ASN1_TEMPLATE *tt, *errtt = NULL; - const ASN1_COMPAT_FUNCS *cf; - const ASN1_EXTERN_FUNCS *ef; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; - const unsigned char *p = NULL, *q; - unsigned char *wp = NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ - unsigned char imphack = 0, oclass; - char seq_eoc, seq_nolen, cst, isopt; - long tmplen; - int i; - int otag; - int ret = 0; - ASN1_VALUE **pchptr, *ptmpval; - int combine = aclass & ASN1_TFLG_COMBINE; - aclass &= ~ASN1_TFLG_COMBINE; - if (!pval) - return 0; - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; - else - asn1_cb = 0; - - if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NESTED_TOO_DEEP); - goto err; - } - - switch (it->itype) { - case ASN1_ITYPE_PRIMITIVE: - if (it->templates) { - /* - * tagging or OPTIONAL is currently illegal on an item template - * because the flags can't get passed down. In practice this - * isn't a problem: we include the relevant flags from the item - * template in the template itself. - */ - if ((tag != -1) || opt) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, - ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); - goto err; - } - return asn1_template_ex_d2i(pval, in, len, - it->templates, opt, ctx, depth); - } - return asn1_d2i_ex_primitive(pval, in, len, it, - tag, aclass, opt, ctx); - break; - - case ASN1_ITYPE_MSTRING: - p = *in; - /* Just read in tag and class */ - ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, - &p, len, -1, 0, 1, ctx); - if (!ret) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } - - /* Must be UNIVERSAL class */ - if (oclass != V_ASN1_UNIVERSAL) { - /* If OPTIONAL, assume this is OK */ - if (opt) - return -1; - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); - goto err; - } - /* Check tag matches bit map */ - if (!(ASN1_tag2bit(otag) & it->utype)) { - /* If OPTIONAL, assume this is OK */ - if (opt) - return -1; - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG); - goto err; - } - return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); - - case ASN1_ITYPE_EXTERN: - /* Use new style d2i */ - ef = it->funcs; - return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); - - case ASN1_ITYPE_COMPAT: - /* we must resort to old style evil hackery */ - cf = it->funcs; - - /* If OPTIONAL see if it is there */ - if (opt) { - int exptag; - p = *in; - if (tag == -1) - exptag = it->utype; - else - exptag = tag; - /* - * Don't care about anything other than presence of expected tag - */ - - ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, - &p, len, exptag, aclass, 1, ctx); - if (!ret) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } - if (ret == -1) - return -1; - } - - /* - * This is the old style evil hack IMPLICIT handling: since the - * underlying code is expecting a tag and class other than the one - * present we change the buffer temporarily then change it back - * afterwards. This doesn't and never did work for tags > 30. Yes - * this is *horrible* but it is only needed for old style d2i which - * will hopefully not be around for much longer. FIXME: should copy - * the buffer then modify it so the input buffer can be const: we - * should *always* copy because the old style d2i might modify the - * buffer. - */ - - if (tag != -1) { - wp = *(unsigned char **)in; - imphack = *wp; - if (p == NULL) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } - *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) - | it->utype); - } - - ptmpval = cf->asn1_d2i(pval, in, len); - - if (tag != -1) - *wp = imphack; - - if (ptmpval) - return 1; - - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - - case ASN1_ITYPE_CHOICE: - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) - goto auxerr; - if (*pval) { - /* Free up and zero CHOICE value if initialised */ - i = asn1_get_choice_selector(pval, it); - if ((i >= 0) && (i < it->tcount)) { - tt = it->templates + i; - pchptr = asn1_get_field_ptr(pval, tt); - ASN1_template_free(pchptr, tt); - asn1_set_choice_selector(pval, -1, it); - } - } else if (!ASN1_item_ex_new(pval, it)) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } - /* CHOICE type, try each possibility in turn */ - p = *in; - for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { - pchptr = asn1_get_field_ptr(pval, tt); - /* - * We mark field as OPTIONAL so its absence can be recognised. - */ - ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx, depth); - /* If field not present, try the next one */ - if (ret == -1) - continue; - /* If positive return, read OK, break loop */ - if (ret > 0) - break; - /* Otherwise must be an ASN1 parsing error */ - errtt = tt; - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } - - /* Did we fall off the end without reading anything? */ - if (i == it->tcount) { - /* If OPTIONAL, this is OK */ - if (opt) { - /* Free and zero it */ - ASN1_item_ex_free(pval, it); - return -1; - } - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); - goto err; - } - - asn1_set_choice_selector(pval, i, it); - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) - goto auxerr; - *in = p; - return 1; - - case ASN1_ITYPE_NDEF_SEQUENCE: - case ASN1_ITYPE_SEQUENCE: - p = *in; - tmplen = len; - - /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ - if (tag == -1) { - tag = V_ASN1_SEQUENCE; - aclass = V_ASN1_UNIVERSAL; - } - /* Get SEQUENCE length and update len, p */ - ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, - &p, len, tag, aclass, opt, ctx); - if (!ret) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } else if (ret == -1) - return -1; - if (aux && (aux->flags & ASN1_AFLG_BROKEN)) { - len = tmplen - (p - *in); - seq_nolen = 1; - } - /* If indefinite we don't do a length check */ - else - seq_nolen = seq_eoc; - if (!cst) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); - goto err; - } - - if (!*pval && !ASN1_item_ex_new(pval, it)) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } - - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) - goto auxerr; - - /* Free up and zero any ADB found */ - for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { - if (tt->flags & ASN1_TFLG_ADB_MASK) { - const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 0); - if (seqtt == NULL) - continue; - pseqval = asn1_get_field_ptr(pval, seqtt); - ASN1_template_free(pseqval, seqtt); - } - } - - /* Get each field entry */ - for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { - const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 1); - if (seqtt == NULL) - goto err; - pseqval = asn1_get_field_ptr(pval, seqtt); - /* Have we ran out of data? */ - if (!len) - break; - q = p; - if (asn1_check_eoc(&p, len)) { - if (!seq_eoc) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC); - goto err; - } - len -= p - q; - seq_eoc = 0; - q = p; - break; - } - /* - * This determines the OPTIONAL flag value. The field cannot be - * omitted if it is the last of a SEQUENCE and there is still - * data to be read. This isn't strictly necessary but it - * increases efficiency in some cases. - */ - if (i == (it->tcount - 1)) - isopt = 0; - else - isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); - /* - * attempt to read in field, allowing each to be OPTIONAL - */ - - ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx, - depth); - if (!ret) { - errtt = seqtt; - goto err; - } else if (ret == -1) { - /* - * OPTIONAL component absent. Free and zero the field. - */ - ASN1_template_free(pseqval, seqtt); - continue; - } - /* Update length */ - len -= p - q; - } - - /* Check for EOC if expecting one */ - if (seq_eoc && !asn1_check_eoc(&p, len)) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); - goto err; - } - /* Check all data read */ - if (!seq_nolen && len) { - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); - goto err; - } - - /* - * If we get here we've got no more data in the SEQUENCE, however we - * may not have read all fields so check all remaining are OPTIONAL - * and clear any that are. - */ - for (; i < it->tcount; tt++, i++) { - const ASN1_TEMPLATE *seqtt; - seqtt = asn1_do_adb(pval, tt, 1); - if (seqtt == NULL) - goto err; - if (seqtt->flags & ASN1_TFLG_OPTIONAL) { - ASN1_VALUE **pseqval; - pseqval = asn1_get_field_ptr(pval, seqtt); - ASN1_template_free(pseqval, seqtt); - } else { - errtt = seqtt; - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING); - goto err; - } - } - /* Save encoding */ - if (!asn1_enc_save(pval, *in, p - *in, it)) - goto auxerr; - if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) - goto auxerr; - *in = p; - return 1; - - default: - return 0; - } - auxerr: - ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); - err: - if (combine == 0) - ASN1_item_ex_free(pval, it); - if (errtt) - ERR_add_error_data(4, "Field=", errtt->field_name, - ", Type=", it->sname); - else - ERR_add_error_data(2, "Type=", it->sname); - return 0; -} - -int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) -{ - return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx, 0); -} - -/* - * Templates are handled with two separate functions. One handles any - * EXPLICIT tag and the other handles the rest. - */ - -static int asn1_template_ex_d2i(ASN1_VALUE **val, - const unsigned char **in, long inlen, - const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth) -{ - int flags, aclass; - int ret; - long len; - const unsigned char *p, *q; - char exp_eoc; - if (!val) - return 0; - flags = tt->flags; - aclass = flags & ASN1_TFLG_TAG_CLASS; - - p = *in; - - /* Check if EXPLICIT tag expected */ - if (flags & ASN1_TFLG_EXPTAG) { - char cst; - /* - * Need to work out amount of data available to the inner content and - * where it starts: so read in EXPLICIT header to get the info. - */ - ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, - &p, inlen, tt->tag, aclass, opt, ctx); - q = p; - if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - return 0; - } else if (ret == -1) - return -1; - if (!cst) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, - ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); - return 0; - } - /* We've found the field so it can't be OPTIONAL now */ - ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx, depth); - if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - return 0; - } - /* We read the field in OK so update length */ - len -= p - q; - if (exp_eoc) { - /* If NDEF we must have an EOC here */ - if (!asn1_check_eoc(&p, len)) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC); - goto err; - } - } else { - /* - * Otherwise we must hit the EXPLICIT tag end or its an error - */ - if (len) { - ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, - ASN1_R_EXPLICIT_LENGTH_MISMATCH); - goto err; - } - } - } else - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx, depth); - - *in = p; - return 1; - - err: - ASN1_template_free(val, tt); - return 0; -} - -static int asn1_template_noexp_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_TEMPLATE *tt, char opt, - ASN1_TLC *ctx, int depth) -{ - int flags, aclass; - int ret; - const unsigned char *p, *q; - if (!val) - return 0; - flags = tt->flags; - aclass = flags & ASN1_TFLG_TAG_CLASS; - - p = *in; - q = p; - - if (flags & ASN1_TFLG_SK_MASK) { - /* SET OF, SEQUENCE OF */ - int sktag, skaclass; - char sk_eoc; - /* First work out expected inner tag value */ - if (flags & ASN1_TFLG_IMPTAG) { - sktag = tt->tag; - skaclass = aclass; - } else { - skaclass = V_ASN1_UNIVERSAL; - if (flags & ASN1_TFLG_SET_OF) - sktag = V_ASN1_SET; - else - sktag = V_ASN1_SEQUENCE; - } - /* Get the tag */ - ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, - &p, len, sktag, skaclass, opt, ctx); - if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); - return 0; - } else if (ret == -1) - return -1; - if (!*val) - *val = (ASN1_VALUE *)sk_new_null(); - else { - /* - * We've got a valid STACK: free up any items present - */ - STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val; - ASN1_VALUE *vtmp; - while (sk_ASN1_VALUE_num(sktmp) > 0) { - vtmp = sk_ASN1_VALUE_pop(sktmp); - ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); - } - } - - if (!*val) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Read as many items as we can */ - while (len > 0) { - ASN1_VALUE *skfield; - q = p; - /* See if EOC found */ - if (asn1_check_eoc(&p, len)) { - if (!sk_eoc) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, - ASN1_R_UNEXPECTED_EOC); - goto err; - } - len -= p - q; - sk_eoc = 0; - break; - } - skfield = NULL; - if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), - -1, 0, 0, ctx, depth)) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, - ERR_R_NESTED_ASN1_ERROR); - goto err; - } - len -= p - q; - if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { - ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); - goto err; - } - } - if (sk_eoc) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); - goto err; - } - } else if (flags & ASN1_TFLG_IMPTAG) { - /* IMPLICIT tagging */ - ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, - aclass, opt, ctx, depth); - if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } else if (ret == -1) - return -1; - } else { - /* Nothing special */ - ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), - -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx, - depth); - if (!ret) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); - goto err; - } else if (ret == -1) - return -1; - } - - *in = p; - return 1; - - err: - ASN1_template_free(val, tt); - return 0; -} - -static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, - const unsigned char **in, long inlen, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx) -{ - int ret = 0, utype; - long plen; - char cst, inf, free_cont = 0; - const unsigned char *p; - BUF_MEM buf = { 0, NULL, 0 }; - const unsigned char *cont = NULL; - long len; - if (!pval) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); - return 0; /* Should never happen */ - } - - if (it->itype == ASN1_ITYPE_MSTRING) { - utype = tag; - tag = -1; - } else - utype = it->utype; - - if (utype == V_ASN1_ANY) { - /* If type is ANY need to figure out type from tag */ - unsigned char oclass; - if (tag >= 0) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); - return 0; - } - if (opt) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, - ASN1_R_ILLEGAL_OPTIONAL_ANY); - return 0; - } - p = *in; - ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, - &p, inlen, -1, 0, 0, ctx); - if (!ret) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); - return 0; - } - if (oclass != V_ASN1_UNIVERSAL) - utype = V_ASN1_OTHER; - } - if (tag == -1) { - tag = utype; - aclass = V_ASN1_UNIVERSAL; - } - p = *in; - /* Check header */ - ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, - &p, inlen, tag, aclass, opt, ctx); - if (!ret) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); - return 0; - } else if (ret == -1) - return -1; - ret = 0; - /* SEQUENCE, SET and "OTHER" are left in encoded form */ - if ((utype == V_ASN1_SEQUENCE) - || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { - /* - * Clear context cache for type OTHER because the auto clear when we - * have a exact match wont work - */ - if (utype == V_ASN1_OTHER) { - asn1_tlc_clear(ctx); - } - /* SEQUENCE and SET must be constructed */ - else if (!cst) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, - ASN1_R_TYPE_NOT_CONSTRUCTED); - return 0; - } - - cont = *in; - /* If indefinite length constructed find the real end */ - if (inf) { - if (!asn1_find_end(&p, plen, inf)) - goto err; - len = p - cont; - } else { - len = p - cont + plen; - p += plen; - } - } else if (cst) { - if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN - || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER - || utype == V_ASN1_ENUMERATED) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE); - return 0; - } - - /* Free any returned 'buf' content */ - free_cont = 1; - /* - * Should really check the internal tags are correct but some things - * may get this wrong. The relevant specs say that constructed string - * types should be OCTET STRINGs internally irrespective of the type. - * So instead just check for UNIVERSAL class and ignore the tag. - */ - if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) { - goto err; - } - len = buf.length; - /* Append a final null to string */ - if (!BUF_MEM_grow_clean(&buf, len + 1)) { - ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); - goto err; - } - buf.data[len] = 0; - cont = (const unsigned char *)buf.data; - } else { - cont = p; - len = plen; - p += plen; - } - - /* We now have content length and type: translate into a structure */ - /* asn1_ex_c2i may reuse allocated buffer, and so sets free_cont to 0 */ - if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) - goto err; - - *in = p; - ret = 1; - err: - if (free_cont && buf.data) - OPENSSL_free(buf.data); - return ret; -} - -/* Translate ASN1 content octets into a structure */ - -int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, char *free_cont, const ASN1_ITEM *it) -{ - ASN1_VALUE **opval = NULL; - ASN1_STRING *stmp; - ASN1_TYPE *typ = NULL; - int ret = 0; - const ASN1_PRIMITIVE_FUNCS *pf; - ASN1_INTEGER **tint; - pf = it->funcs; - - if (pf && pf->prim_c2i) - return pf->prim_c2i(pval, cont, len, utype, free_cont, it); - /* If ANY type clear type and set pointer to internal value */ - if (it->utype == V_ASN1_ANY) { - if (!*pval) { - typ = ASN1_TYPE_new(); - if (typ == NULL) - goto err; - *pval = (ASN1_VALUE *)typ; - } else - typ = (ASN1_TYPE *)*pval; - - if (utype != typ->type) - ASN1_TYPE_set(typ, utype, NULL); - opval = pval; - pval = &typ->value.asn1_value; - } - switch (utype) { - case V_ASN1_OBJECT: - if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) - goto err; - break; - - case V_ASN1_NULL: - if (len) { - ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH); - goto err; - } - *pval = (ASN1_VALUE *)1; - break; - - case V_ASN1_BOOLEAN: - if (len != 1) { - ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); - goto err; - } else { - ASN1_BOOLEAN *tbool; - tbool = (ASN1_BOOLEAN *)pval; - *tbool = *cont; - } - break; - - case V_ASN1_BIT_STRING: - if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) - goto err; - break; - - case V_ASN1_INTEGER: - case V_ASN1_ENUMERATED: - tint = (ASN1_INTEGER **)pval; - if (!c2i_ASN1_INTEGER(tint, &cont, len)) - goto err; - /* Fixup type to match the expected form */ - (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); - break; - - case V_ASN1_OCTET_STRING: - case V_ASN1_NUMERICSTRING: - case V_ASN1_PRINTABLESTRING: - case V_ASN1_T61STRING: - case V_ASN1_VIDEOTEXSTRING: - case V_ASN1_IA5STRING: - case V_ASN1_UTCTIME: - case V_ASN1_GENERALIZEDTIME: - case V_ASN1_GRAPHICSTRING: - case V_ASN1_VISIBLESTRING: - case V_ASN1_GENERALSTRING: - case V_ASN1_UNIVERSALSTRING: - case V_ASN1_BMPSTRING: - case V_ASN1_UTF8STRING: - case V_ASN1_OTHER: - case V_ASN1_SET: - case V_ASN1_SEQUENCE: - default: - if (utype == V_ASN1_BMPSTRING && (len & 1)) { - ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); - goto err; - } - if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { - ASN1err(ASN1_F_ASN1_EX_C2I, - ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); - goto err; - } - /* All based on ASN1_STRING and handled the same */ - if (!*pval) { - stmp = ASN1_STRING_type_new(utype); - if (!stmp) { - ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); - goto err; - } - *pval = (ASN1_VALUE *)stmp; - } else { - stmp = (ASN1_STRING *)*pval; - stmp->type = utype; - } - /* If we've already allocated a buffer use it */ - if (*free_cont) { - if (stmp->data) - OPENSSL_free(stmp->data); - stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ - stmp->length = len; - *free_cont = 0; - } else { - if (!ASN1_STRING_set(stmp, cont, len)) { - ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); - ASN1_STRING_free(stmp); - *pval = NULL; - goto err; - } - } - break; - } - /* If ASN1_ANY and NULL type fix up value */ - if (typ && (utype == V_ASN1_NULL)) - typ->value.ptr = NULL; - - ret = 1; - err: - if (!ret) { - ASN1_TYPE_free(typ); - if (opval) - *opval = NULL; - } - return ret; -} - -/* - * This function finds the end of an ASN1 structure when passed its maximum - * length, whether it is indefinite length and a pointer to the content. This - * is more efficient than calling asn1_collect because it does not recurse on - * each indefinite length header. - */ - -static int asn1_find_end(const unsigned char **in, long len, char inf) -{ - int expected_eoc; - long plen; - const unsigned char *p = *in, *q; - /* If not indefinite length constructed just add length */ - if (inf == 0) { - *in += len; - return 1; - } - expected_eoc = 1; - /* - * Indefinite length constructed form. Find the end when enough EOCs are - * found. If more indefinite length constructed headers are encountered - * increment the expected eoc count otherwise just skip to the end of the - * data. - */ - while (len > 0) { - if (asn1_check_eoc(&p, len)) { - expected_eoc--; - if (expected_eoc == 0) - break; - len -= 2; - continue; - } - q = p; - /* Just read in a header: only care about the length */ - if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, - -1, 0, 0, NULL)) { - ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); - return 0; - } - if (inf) - expected_eoc++; - else - p += plen; - len -= p - q; - } - if (expected_eoc) { - ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); - return 0; - } - *in = p; - return 1; -} - -/* - * This function collects the asn1 data from a constructred string type into - * a buffer. The values of 'in' and 'len' should refer to the contents of the - * constructed type and 'inf' should be set if it is indefinite length. - */ - -#ifndef ASN1_MAX_STRING_NEST -/* - * This determines how many levels of recursion are permitted in ASN1 string - * types. If it is not limited stack overflows can occur. If set to zero no - * recursion is allowed at all. Although zero should be adequate examples - * exist that require a value of 1. So 5 should be more than enough. - */ -# define ASN1_MAX_STRING_NEST 5 -#endif - -static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, - char inf, int tag, int aclass, int depth) -{ - const unsigned char *p, *q; - long plen; - char cst, ininf; - p = *in; - inf &= 1; - /* - * If no buffer and not indefinite length constructed just pass over the - * encoded data - */ - if (!buf && !inf) { - *in += len; - return 1; - } - while (len > 0) { - q = p; - /* Check for EOC */ - if (asn1_check_eoc(&p, len)) { - /* - * EOC is illegal outside indefinite length constructed form - */ - if (!inf) { - ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); - return 0; - } - inf = 0; - break; - } - - if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, - len, tag, aclass, 0, NULL)) { - ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); - return 0; - } - - /* If indefinite length constructed update max length */ - if (cst) { - if (depth >= ASN1_MAX_STRING_NEST) { - ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); - return 0; - } - if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1)) - return 0; - } else if (plen && !collect_data(buf, &p, plen)) - return 0; - len -= p - q; - } - if (inf) { - ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); - return 0; - } - *in = p; - return 1; -} - -static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) -{ - int len; - if (buf) { - len = buf->length; - if (!BUF_MEM_grow_clean(buf, len + plen)) { - ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); - return 0; - } - memcpy(buf->data + len, *p, plen); - } - *p += plen; - return 1; -} - -/* Check for ASN1 EOC and swallow it if found */ - -static int asn1_check_eoc(const unsigned char **in, long len) -{ - const unsigned char *p; - if (len < 2) - return 0; - p = *in; - if (!p[0] && !p[1]) { - *in += 2; - return 1; - } - return 0; -} - -/* - * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the - * length for indefinite length constructed form, we don't know the exact - * length but we can set an upper bound to the amount of data available minus - * the header length just read. - */ - -static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, - char *inf, char *cst, - const unsigned char **in, long len, - int exptag, int expclass, char opt, ASN1_TLC *ctx) -{ - int i; - int ptag, pclass; - long plen; - const unsigned char *p, *q; - p = *in; - q = p; - - if (ctx && ctx->valid) { - i = ctx->ret; - plen = ctx->plen; - pclass = ctx->pclass; - ptag = ctx->ptag; - p += ctx->hdrlen; - } else { - i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); - if (ctx) { - ctx->ret = i; - ctx->plen = plen; - ctx->pclass = pclass; - ctx->ptag = ptag; - ctx->hdrlen = p - q; - ctx->valid = 1; - /* - * If definite length, and no error, length + header can't exceed - * total amount of data available. - */ - if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); - asn1_tlc_clear(ctx); - return 0; - } - } - } - - if (i & 0x80) { - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); - asn1_tlc_clear(ctx); - return 0; - } - if (exptag >= 0) { - if ((exptag != ptag) || (expclass != pclass)) { - /* - * If type is OPTIONAL, not an error: indicate missing type. - */ - if (opt) - return -1; - asn1_tlc_clear(ctx); - ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); - return 0; - } - /* - * We have a tag and class match: assume we are going to do something - * with it - */ - asn1_tlc_clear(ctx); - } - - if (i & 1) - plen = len - (p - q); - - if (inf) - *inf = i & 1; - - if (cst) - *cst = i & V_ASN1_CONSTRUCTED; - - if (olen) - *olen = plen; - - if (oclass) - *oclass = pclass; - - if (otag) - *otag = ptag; - - *in = p; - return 1; -} -/* tasn_enc.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -#include -#include "cryptlib.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "objects.h" - -static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass); -static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, - int skcontlen, const ASN1_ITEM *item, - int do_sort, int iclass); -static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_TEMPLATE *tt, int tag, int aclass); -static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, - const ASN1_ITEM *it, int flags); - -/* - * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use - * indefinite length constructed encoding, where appropriate - */ - -int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, - const ASN1_ITEM *it) -{ - return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); -} - -int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) -{ - return asn1_item_flags_i2d(val, out, it, 0); -} - -/* - * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out' - * points to a buffer to output the data to. The new i2d has one additional - * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is - * allocated and populated with the encoding. - */ - -static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, - const ASN1_ITEM *it, int flags) -{ - if (out && !*out) { - unsigned char *p, *buf; - int len; - len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); - if (len <= 0) - return len; - buf = OPENSSL_malloc(len); - if (!buf) - return -1; - p = buf; - ASN1_item_ex_i2d(&val, &p, it, -1, flags); - *out = buf; - return len; - } - - return ASN1_item_ex_i2d(&val, out, it, -1, flags); -} - -/* - * Encode an item, taking care of IMPLICIT tagging (if any). This function - * performs the normal item handling: it can be used in external types. - */ - -int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass) -{ - const ASN1_TEMPLATE *tt = NULL; - unsigned char *p = NULL; - int i, seqcontlen, seqlen, ndef = 1; - const ASN1_COMPAT_FUNCS *cf; - const ASN1_EXTERN_FUNCS *ef; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb = 0; - - if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) - return 0; - - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; - - switch (it->itype) { - - case ASN1_ITYPE_PRIMITIVE: - if (it->templates) - return asn1_template_ex_i2d(pval, out, it->templates, - tag, aclass); - return asn1_i2d_ex_primitive(pval, out, it, tag, aclass); - break; - - case ASN1_ITYPE_MSTRING: - return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); - - case ASN1_ITYPE_CHOICE: - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) - return 0; - i = asn1_get_choice_selector(pval, it); - if ((i >= 0) && (i < it->tcount)) { - ASN1_VALUE **pchval; - const ASN1_TEMPLATE *chtt; - chtt = it->templates + i; - pchval = asn1_get_field_ptr(pval, chtt); - return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass); - } - /* Fixme: error condition if selector out of range */ - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) - return 0; - break; - - case ASN1_ITYPE_EXTERN: - /* If new style i2d it does all the work */ - ef = it->funcs; - return ef->asn1_ex_i2d(pval, out, it, tag, aclass); - - case ASN1_ITYPE_COMPAT: - /* old style hackery... */ - cf = it->funcs; - if (out) - p = *out; - i = cf->asn1_i2d(*pval, out); - /* - * Fixup for IMPLICIT tag: note this messes up for tags > 30, but so - * did the old code. Tags > 30 are very rare anyway. - */ - if (out && (tag != -1)) - *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED); - return i; - - case ASN1_ITYPE_NDEF_SEQUENCE: - /* Use indefinite length constructed if requested */ - if (aclass & ASN1_TFLG_NDEF) - ndef = 2; - /* fall through */ - - case ASN1_ITYPE_SEQUENCE: - i = asn1_enc_restore(&seqcontlen, out, pval, it); - /* An error occurred */ - if (i < 0) - return 0; - /* We have a valid cached encoding... */ - if (i > 0) - return seqcontlen; - /* Otherwise carry on */ - seqcontlen = 0; - /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ - if (tag == -1) { - tag = V_ASN1_SEQUENCE; - /* Retain any other flags in aclass */ - aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) - | V_ASN1_UNIVERSAL; - } - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) - return 0; - /* First work out sequence content length */ - for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { - const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - int tmplen; - seqtt = asn1_do_adb(pval, tt, 1); - if (!seqtt) - return 0; - pseqval = asn1_get_field_ptr(pval, seqtt); - tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass); - if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) - return -1; - seqcontlen += tmplen; - } - - seqlen = ASN1_object_size(ndef, seqcontlen, tag); - if (!out || seqlen == -1) - return seqlen; - /* Output SEQUENCE header */ - ASN1_put_object(out, ndef, seqcontlen, tag, aclass); - for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { - const ASN1_TEMPLATE *seqtt; - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 1); - if (!seqtt) - return 0; - pseqval = asn1_get_field_ptr(pval, seqtt); - /* FIXME: check for errors in enhanced version */ - asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); - } - if (ndef == 2) - ASN1_put_eoc(out); - if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) - return 0; - return seqlen; - - default: - return 0; - - } - return 0; -} - -int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_TEMPLATE *tt) -{ - return asn1_template_ex_i2d(pval, out, tt, -1, 0); -} - -static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, - const ASN1_TEMPLATE *tt, int tag, int iclass) -{ - int i, ret, flags, ttag, tclass, ndef; - flags = tt->flags; - /* - * Work out tag and class to use: tagging may come either from the - * template or the arguments, not both because this would create - * ambiguity. Additionally the iclass argument may contain some - * additional flags which should be noted and passed down to other - * levels. - */ - if (flags & ASN1_TFLG_TAG_MASK) { - /* Error if argument and template tagging */ - if (tag != -1) - /* FIXME: error code here */ - return -1; - /* Get tagging from template */ - ttag = tt->tag; - tclass = flags & ASN1_TFLG_TAG_CLASS; - } else if (tag != -1) { - /* No template tagging, get from arguments */ - ttag = tag; - tclass = iclass & ASN1_TFLG_TAG_CLASS; - } else { - ttag = -1; - tclass = 0; - } - /* - * Remove any class mask from iflag. - */ - iclass &= ~ASN1_TFLG_TAG_CLASS; - - /* - * At this point 'ttag' contains the outer tag to use, 'tclass' is the - * class and iclass is any flags passed to this function. - */ - - /* if template and arguments require ndef, use it */ - if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF)) - ndef = 2; - else - ndef = 1; - - if (flags & ASN1_TFLG_SK_MASK) { - /* SET OF, SEQUENCE OF */ - STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; - int isset, sktag, skaclass; - int skcontlen, sklen; - ASN1_VALUE *skitem; - - if (!*pval) - return 0; - - if (flags & ASN1_TFLG_SET_OF) { - isset = 1; - /* 2 means we reorder */ - if (flags & ASN1_TFLG_SEQUENCE_OF) - isset = 2; - } else - isset = 0; - - /* - * Work out inner tag value: if EXPLICIT or no tagging use underlying - * type. - */ - if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { - sktag = ttag; - skaclass = tclass; - } else { - skaclass = V_ASN1_UNIVERSAL; - if (isset) - sktag = V_ASN1_SET; - else - sktag = V_ASN1_SEQUENCE; - } - - /* Determine total length of items */ - skcontlen = 0; - for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - int tmplen; - skitem = sk_ASN1_VALUE_value(sk, i); - tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), - -1, iclass); - if (tmplen == -1 || (skcontlen > INT_MAX - tmplen)) - return -1; - skcontlen += tmplen; - } - sklen = ASN1_object_size(ndef, skcontlen, sktag); - if (sklen == -1) - return -1; - /* If EXPLICIT need length of surrounding tag */ - if (flags & ASN1_TFLG_EXPTAG) - ret = ASN1_object_size(ndef, sklen, ttag); - else - ret = sklen; - - if (!out || ret == -1) - return ret; - - /* Now encode this lot... */ - /* EXPLICIT tag */ - if (flags & ASN1_TFLG_EXPTAG) - ASN1_put_object(out, ndef, sklen, ttag, tclass); - /* SET or SEQUENCE and IMPLICIT tag */ - ASN1_put_object(out, ndef, skcontlen, sktag, skaclass); - /* And the stuff itself */ - asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), - isset, iclass); - if (ndef == 2) { - ASN1_put_eoc(out); - if (flags & ASN1_TFLG_EXPTAG) - ASN1_put_eoc(out); - } - - return ret; - } - - if (flags & ASN1_TFLG_EXPTAG) { - /* EXPLICIT tagging */ - /* Find length of tagged item */ - i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass); - if (!i) - return 0; - /* Find length of EXPLICIT tag */ - ret = ASN1_object_size(ndef, i, ttag); - if (out && ret != -1) { - /* Output tag and item */ - ASN1_put_object(out, ndef, i, ttag, tclass); - ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass); - if (ndef == 2) - ASN1_put_eoc(out); - } - return ret; - } - - /* Either normal or IMPLICIT tagging: combine class and flags */ - return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), - ttag, tclass | iclass); - -} - -/* Temporary structure used to hold DER encoding of items for SET OF */ - -typedef struct { - unsigned char *data; - int length; - ASN1_VALUE *field; -} DER_ENC; - -static int der_cmp(const void *a, const void *b) -{ - const DER_ENC *d1 = a, *d2 = b; - int cmplen, i; - cmplen = (d1->length < d2->length) ? d1->length : d2->length; - i = memcmp(d1->data, d2->data, cmplen); - if (i) - return i; - return d1->length - d2->length; -} - -/* Output the content octets of SET OF or SEQUENCE OF */ - -static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, - int skcontlen, const ASN1_ITEM *item, - int do_sort, int iclass) -{ - int i; - ASN1_VALUE *skitem; - unsigned char *tmpdat = NULL, *p = NULL; - DER_ENC *derlst = NULL, *tder; - if (do_sort) { - /* Don't need to sort less than 2 items */ - if (sk_ASN1_VALUE_num(sk) < 2) - do_sort = 0; - else { - derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) - * sizeof(*derlst)); - if (!derlst) - return 0; - tmpdat = OPENSSL_malloc(skcontlen); - if (!tmpdat) { - OPENSSL_free(derlst); - return 0; - } - } - } - /* If not sorting just output each item */ - if (!do_sort) { - for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - skitem = sk_ASN1_VALUE_value(sk, i); - ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); - } - return 1; - } - p = tmpdat; - - /* Doing sort: build up a list of each member's DER encoding */ - for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { - skitem = sk_ASN1_VALUE_value(sk, i); - tder->data = p; - tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); - tder->field = skitem; - } - - /* Now sort them */ - qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); - /* Output sorted DER encoding */ - p = *out; - for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { - memcpy(p, tder->data, tder->length); - p += tder->length; - } - *out = p; - /* If do_sort is 2 then reorder the STACK */ - if (do_sort == 2) { - for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) - (void)sk_ASN1_VALUE_set(sk, i, tder->field); - } - OPENSSL_free(derlst); - OPENSSL_free(tmpdat); - return 1; -} - -static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass) -{ - int len; - int utype; - int usetag; - int ndef = 0; - - utype = it->utype; - - /* - * Get length of content octets and maybe find out the underlying type. - */ - - len = asn1_ex_i2c(pval, NULL, &utype, it); - - /* - * If SEQUENCE, SET or OTHER then header is included in pseudo content - * octets so don't include tag+length. We need to check here because the - * call to asn1_ex_i2c() could change utype. - */ - if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || - (utype == V_ASN1_OTHER)) - usetag = 0; - else - usetag = 1; - - /* -1 means omit type */ - - if (len == -1) - return 0; - - /* -2 return is special meaning use ndef */ - if (len == -2) { - ndef = 2; - len = 0; - } - - /* If not implicitly tagged get tag from underlying type */ - if (tag == -1) - tag = utype; - - /* Output tag+length followed by content octets */ - if (out) { - if (usetag) - ASN1_put_object(out, ndef, len, tag, aclass); - asn1_ex_i2c(pval, *out, &utype, it); - if (ndef) - ASN1_put_eoc(out); - else - *out += len; - } - - if (usetag) - return ASN1_object_size(ndef, len, tag); - return len; -} - -/* Produce content octets from a structure */ - -int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, - const ASN1_ITEM *it) -{ - ASN1_BOOLEAN *tbool = NULL; - ASN1_STRING *strtmp; - ASN1_OBJECT *otmp; - int utype; - const unsigned char *cont; - unsigned char c; - int len; - const ASN1_PRIMITIVE_FUNCS *pf; - pf = it->funcs; - if (pf && pf->prim_i2c) - return pf->prim_i2c(pval, cout, putype, it); - - /* Should type be omitted? */ - if ((it->itype != ASN1_ITYPE_PRIMITIVE) - || (it->utype != V_ASN1_BOOLEAN)) { - if (!*pval) - return -1; - } - - if (it->itype == ASN1_ITYPE_MSTRING) { - /* If MSTRING type set the underlying type */ - strtmp = (ASN1_STRING *)*pval; - utype = strtmp->type; - *putype = utype; - } else if (it->utype == V_ASN1_ANY) { - /* If ANY set type and pointer to value */ - ASN1_TYPE *typ; - typ = (ASN1_TYPE *)*pval; - utype = typ->type; - *putype = utype; - pval = &typ->value.asn1_value; - } else - utype = *putype; - - switch (utype) { - case V_ASN1_OBJECT: - otmp = (ASN1_OBJECT *)*pval; - cont = otmp->data; - len = otmp->length; - if (cont == NULL || len == 0) - return -1; - break; - - case V_ASN1_NULL: - cont = NULL; - len = 0; - break; - - case V_ASN1_BOOLEAN: - tbool = (ASN1_BOOLEAN *)pval; - if (*tbool == -1) - return -1; - if (it->utype != V_ASN1_ANY) { - /* - * Default handling if value == size field then omit - */ - if (*tbool && (it->size > 0)) - return -1; - if (!*tbool && !it->size) - return -1; - } - c = (unsigned char)*tbool; - cont = &c; - len = 1; - break; - - case V_ASN1_BIT_STRING: - return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, - cout ? &cout : NULL); - break; - - case V_ASN1_INTEGER: - case V_ASN1_ENUMERATED: - /* - * These are all have the same content format as ASN1_INTEGER - */ - return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); - break; - - case V_ASN1_OCTET_STRING: - case V_ASN1_NUMERICSTRING: - case V_ASN1_PRINTABLESTRING: - case V_ASN1_T61STRING: - case V_ASN1_VIDEOTEXSTRING: - case V_ASN1_IA5STRING: - case V_ASN1_UTCTIME: - case V_ASN1_GENERALIZEDTIME: - case V_ASN1_GRAPHICSTRING: - case V_ASN1_VISIBLESTRING: - case V_ASN1_GENERALSTRING: - case V_ASN1_UNIVERSALSTRING: - case V_ASN1_BMPSTRING: - case V_ASN1_UTF8STRING: - case V_ASN1_SEQUENCE: - case V_ASN1_SET: - default: - /* All based on ASN1_STRING and handled the same */ - strtmp = (ASN1_STRING *)*pval; - /* Special handling for NDEF */ - if ((it->size == ASN1_TFLG_NDEF) - && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) { - if (cout) { - strtmp->data = cout; - strtmp->length = 0; - } - /* Special return code */ - return -2; - } - cont = strtmp->data; - len = strtmp->length; - - break; - - } - if (cout && len) - memcpy(cout, cont, len); - return len; -} -/* tasn_fre.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "asn1.h" -// #include "asn1t.h" -// #include "objects.h" -#include "asn1_int.h" - -/* Free up an ASN1 structure */ - -void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) -{ - asn1_item_combine_free(&val, it, 0); -} - -void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - asn1_item_combine_free(pval, it, 0); -} - -void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine) -{ - const ASN1_TEMPLATE *tt = NULL, *seqtt; - const ASN1_EXTERN_FUNCS *ef; - const ASN1_COMPAT_FUNCS *cf; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; - int i; - if (!pval) - return; - if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) - return; - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; - else - asn1_cb = 0; - - switch (it->itype) { - - case ASN1_ITYPE_PRIMITIVE: - if (it->templates) - ASN1_template_free(pval, it->templates); - else - ASN1_primitive_free(pval, it); - break; - - case ASN1_ITYPE_MSTRING: - ASN1_primitive_free(pval, it); - break; - - case ASN1_ITYPE_CHOICE: - if (asn1_cb) { - i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); - if (i == 2) - return; - } - i = asn1_get_choice_selector(pval, it); - if ((i >= 0) && (i < it->tcount)) { - ASN1_VALUE **pchval; - tt = it->templates + i; - pchval = asn1_get_field_ptr(pval, tt); - ASN1_template_free(pchval, tt); - } - if (asn1_cb) - asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); - if (!combine) { - OPENSSL_free(*pval); - *pval = NULL; - } - break; - - case ASN1_ITYPE_COMPAT: - cf = it->funcs; - if (cf && cf->asn1_free) - cf->asn1_free(*pval); - break; - - case ASN1_ITYPE_EXTERN: - ef = it->funcs; - if (ef && ef->asn1_ex_free) - ef->asn1_ex_free(pval, it); - break; - - case ASN1_ITYPE_NDEF_SEQUENCE: - case ASN1_ITYPE_SEQUENCE: - if (asn1_do_lock(pval, -1, it) > 0) - return; - if (asn1_cb) { - i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); - if (i == 2) - return; - } - asn1_enc_free(pval, it); - /* - * If we free up as normal we will invalidate any ANY DEFINED BY - * field and we wont be able to determine the type of the field it - * defines. So free up in reverse order. - */ - tt = it->templates + it->tcount - 1; - for (i = 0; i < it->tcount; tt--, i++) { - ASN1_VALUE **pseqval; - seqtt = asn1_do_adb(pval, tt, 0); - if (!seqtt) - continue; - pseqval = asn1_get_field_ptr(pval, seqtt); - ASN1_template_free(pseqval, seqtt); - } - if (asn1_cb) - asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); - if (!combine) { - OPENSSL_free(*pval); - *pval = NULL; - } - break; - } -} - -void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ - int i; - if (tt->flags & ASN1_TFLG_SK_MASK) { - STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; - for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { - ASN1_VALUE *vtmp; - vtmp = sk_ASN1_VALUE_value(sk, i); - asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0); - } - sk_ASN1_VALUE_free(sk); - *pval = NULL; - } else - asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), - tt->flags & ASN1_TFLG_COMBINE); -} - -void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - int utype; - if (it) { - const ASN1_PRIMITIVE_FUNCS *pf; - pf = it->funcs; - if (pf && pf->prim_free) { - pf->prim_free(pval, it); - return; - } - } - /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ - if (!it) { - ASN1_TYPE *typ = (ASN1_TYPE *)*pval; - utype = typ->type; - pval = &typ->value.asn1_value; - if (!*pval) - return; - } else if (it->itype == ASN1_ITYPE_MSTRING) { - utype = -1; - if (!*pval) - return; - } else { - utype = it->utype; - if ((utype != V_ASN1_BOOLEAN) && !*pval) - return; - } - - switch (utype) { - case V_ASN1_OBJECT: - ASN1_OBJECT_free((ASN1_OBJECT *)*pval); - break; - - case V_ASN1_BOOLEAN: - if (it) - *(ASN1_BOOLEAN *)pval = it->size; - else - *(ASN1_BOOLEAN *)pval = -1; - return; - - case V_ASN1_NULL: - break; - - case V_ASN1_ANY: - ASN1_primitive_free(pval, NULL); - OPENSSL_free(*pval); - break; - - default: - ASN1_STRING_free((ASN1_STRING *)*pval); - *pval = NULL; - break; - } - *pval = NULL; -} -/* tasn_new.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "asn1.h" -// #include "objects.h" -// #include "err.h" -// #include "asn1t.h" -#include -// #include "asn1_int.h" - -static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine); -static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); -static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); -static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); - -ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) -{ - ASN1_VALUE *ret = NULL; - if (ASN1_item_ex_new(&ret, it) > 0) - return ret; - return NULL; -} - -/* Allocate an ASN1 structure */ - -int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - return asn1_item_ex_combine_new(pval, it, 0); -} - -static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, - int combine) -{ - const ASN1_TEMPLATE *tt = NULL; - const ASN1_COMPAT_FUNCS *cf; - const ASN1_EXTERN_FUNCS *ef; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; - ASN1_VALUE **pseqval; - int i; - if (aux && aux->asn1_cb) - asn1_cb = aux->asn1_cb; - else - asn1_cb = 0; - -#ifdef CRYPTO_MDEBUG - if (it->sname) - CRYPTO_push_info(it->sname); -#endif - - switch (it->itype) { - - case ASN1_ITYPE_EXTERN: - ef = it->funcs; - if (ef && ef->asn1_ex_new) { - if (!ef->asn1_ex_new(pval, it)) - goto memerr; - } - break; - - case ASN1_ITYPE_COMPAT: - cf = it->funcs; - if (cf && cf->asn1_new) { - *pval = cf->asn1_new(); - if (!*pval) - goto memerr; - } - break; - - case ASN1_ITYPE_PRIMITIVE: - if (it->templates) { - if (!ASN1_template_new(pval, it->templates)) - goto memerr; - } else if (!ASN1_primitive_new(pval, it)) - goto memerr; - break; - - case ASN1_ITYPE_MSTRING: - if (!ASN1_primitive_new(pval, it)) - goto memerr; - break; - - case ASN1_ITYPE_CHOICE: - if (asn1_cb) { - i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); - if (!i) - goto auxerr; - if (i == 2) { -#ifdef CRYPTO_MDEBUG - if (it->sname) - CRYPTO_pop_info(); -#endif - return 1; - } - } - if (!combine) { - *pval = OPENSSL_malloc(it->size); - if (!*pval) - goto memerr; - memset(*pval, 0, it->size); - } - asn1_set_choice_selector(pval, -1, it); - if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) - goto auxerr2; - break; - - case ASN1_ITYPE_NDEF_SEQUENCE: - case ASN1_ITYPE_SEQUENCE: - if (asn1_cb) { - i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); - if (!i) - goto auxerr; - if (i == 2) { -#ifdef CRYPTO_MDEBUG - if (it->sname) - CRYPTO_pop_info(); -#endif - return 1; - } - } - if (!combine) { - *pval = OPENSSL_malloc(it->size); - if (!*pval) - goto memerr; - memset(*pval, 0, it->size); - asn1_do_lock(pval, 0, it); - asn1_enc_init(pval, it); - } - for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { - pseqval = asn1_get_field_ptr(pval, tt); - if (!ASN1_template_new(pseqval, tt)) - goto memerr2; - } - if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) - goto auxerr2; - break; - } -#ifdef CRYPTO_MDEBUG - if (it->sname) - CRYPTO_pop_info(); -#endif - return 1; - - memerr2: - asn1_item_combine_free(pval, it, combine); - memerr: - ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); -#ifdef CRYPTO_MDEBUG - if (it->sname) - CRYPTO_pop_info(); -#endif - return 0; - - auxerr2: - asn1_item_combine_free(pval, it, combine); - auxerr: - ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); -#ifdef CRYPTO_MDEBUG - if (it->sname) - CRYPTO_pop_info(); -#endif - return 0; - -} - -static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - const ASN1_EXTERN_FUNCS *ef; - - switch (it->itype) { - - case ASN1_ITYPE_EXTERN: - ef = it->funcs; - if (ef && ef->asn1_ex_clear) - ef->asn1_ex_clear(pval, it); - else - *pval = NULL; - break; - - case ASN1_ITYPE_PRIMITIVE: - if (it->templates) - asn1_template_clear(pval, it->templates); - else - asn1_primitive_clear(pval, it); - break; - - case ASN1_ITYPE_MSTRING: - asn1_primitive_clear(pval, it); - break; - - case ASN1_ITYPE_COMPAT: - case ASN1_ITYPE_CHOICE: - case ASN1_ITYPE_SEQUENCE: - case ASN1_ITYPE_NDEF_SEQUENCE: - *pval = NULL; - break; - } -} - -int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ - const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); - int ret; - if (tt->flags & ASN1_TFLG_OPTIONAL) { - asn1_template_clear(pval, tt); - return 1; - } - /* If ANY DEFINED BY nothing to do */ - - if (tt->flags & ASN1_TFLG_ADB_MASK) { - *pval = NULL; - return 1; - } -#ifdef CRYPTO_MDEBUG - if (tt->field_name) - CRYPTO_push_info(tt->field_name); -#endif - /* If SET OF or SEQUENCE OF, its a STACK */ - if (tt->flags & ASN1_TFLG_SK_MASK) { - STACK_OF(ASN1_VALUE) *skval; - skval = sk_ASN1_VALUE_new_null(); - if (!skval) { - ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); - ret = 0; - goto done; - } - *pval = (ASN1_VALUE *)skval; - ret = 1; - goto done; - } - /* Otherwise pass it back to the item routine */ - ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); - done: -#ifdef CRYPTO_MDEBUG - if (it->sname) - CRYPTO_pop_info(); -#endif - return ret; -} - -static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ - /* If ADB or STACK just NULL the field */ - if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) - *pval = NULL; - else - asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); -} - -/* - * NB: could probably combine most of the real XXX_new() behaviour and junk - * all the old functions. - */ - -int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - ASN1_TYPE *typ; - ASN1_STRING *str; - int utype; - - if (!it) - return 0; - - if (it->funcs) { - const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; - if (pf->prim_new) - return pf->prim_new(pval, it); - } - - if (it->itype == ASN1_ITYPE_MSTRING) - utype = -1; - else - utype = it->utype; - switch (utype) { - case V_ASN1_OBJECT: - *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); - return 1; - - case V_ASN1_BOOLEAN: - *(ASN1_BOOLEAN *)pval = it->size; - return 1; - - case V_ASN1_NULL: - *pval = (ASN1_VALUE *)1; - return 1; - - case V_ASN1_ANY: - typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); - if (!typ) - return 0; - typ->value.ptr = NULL; - typ->type = -1; - *pval = (ASN1_VALUE *)typ; - break; - - default: - str = ASN1_STRING_type_new(utype); - if (it->itype == ASN1_ITYPE_MSTRING && str) - str->flags |= ASN1_STRING_FLAG_MSTRING; - *pval = (ASN1_VALUE *)str; - break; - } - if (*pval) - return 1; - return 0; -} - -static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - int utype; - if (it && it->funcs) { - const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; - if (pf->prim_clear) - pf->prim_clear(pval, it); - else - *pval = NULL; - return; - } - if (!it || (it->itype == ASN1_ITYPE_MSTRING)) - utype = -1; - else - utype = it->utype; - if (utype == V_ASN1_BOOLEAN) - *(ASN1_BOOLEAN *)pval = it->size; - else - *pval = NULL; -} -/* tasn_prn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "objects.h" -// #include "buffer.h" -// #include "err.h" -#include "x509v3.h" -#include "asn1_locl.h" - -/* - * Print routines. - */ - -/* ASN1_PCTX routines */ - -ASN1_PCTX default_pctx = { - ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ - 0, /* nm_flags */ - 0, /* cert_flags */ - 0, /* oid_flags */ - 0 /* str_flags */ -}; - -ASN1_PCTX *ASN1_PCTX_new(void) -{ - ASN1_PCTX *ret; - ret = OPENSSL_malloc(sizeof(ASN1_PCTX)); - if (ret == NULL) { - ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - ret->flags = 0; - ret->nm_flags = 0; - ret->cert_flags = 0; - ret->oid_flags = 0; - ret->str_flags = 0; - return ret; -} - -void ASN1_PCTX_free(ASN1_PCTX *p) -{ - OPENSSL_free(p); -} - -unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p) -{ - return p->flags; -} - -void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) -{ - p->flags = flags; -} - -unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p) -{ - return p->nm_flags; -} - -void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) -{ - p->nm_flags = flags; -} - -unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p) -{ - return p->cert_flags; -} - -void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) -{ - p->cert_flags = flags; -} - -unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p) -{ - return p->oid_flags; -} - -void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) -{ - p->oid_flags = flags; -} - -unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p) -{ - return p->str_flags; -} - -void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) -{ - p->str_flags = flags; -} - -/* Main print routines */ - -static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, - const ASN1_ITEM *it, - const char *fname, const char *sname, - int nohdr, const ASN1_PCTX *pctx); - -int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, - const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); - -static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, - const ASN1_ITEM *it, int indent, - const char *fname, const char *sname, - const ASN1_PCTX *pctx); - -static int asn1_print_fsname(BIO *out, int indent, - const char *fname, const char *sname, - const ASN1_PCTX *pctx); - -int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, - const ASN1_ITEM *it, const ASN1_PCTX *pctx) -{ - const char *sname; - if (pctx == NULL) - pctx = &default_pctx; - if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) - sname = NULL; - else - sname = it->sname; - return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx); -} - -static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, - const ASN1_ITEM *it, - const char *fname, const char *sname, - int nohdr, const ASN1_PCTX *pctx) -{ - const ASN1_TEMPLATE *tt; - const ASN1_EXTERN_FUNCS *ef; - ASN1_VALUE **tmpfld; - const ASN1_AUX *aux = it->funcs; - ASN1_aux_cb *asn1_cb; - ASN1_PRINT_ARG parg; - int i; - if (aux && aux->asn1_cb) { - parg.out = out; - parg.indent = indent; - parg.pctx = pctx; - asn1_cb = aux->asn1_cb; - } else - asn1_cb = 0; - - if (((it->itype != ASN1_ITYPE_PRIMITIVE) - || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) { - if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) { - if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) - return 0; - if (BIO_puts(out, "\n") <= 0) - return 0; - } - return 1; - } - - switch (it->itype) { - case ASN1_ITYPE_PRIMITIVE: - if (it->templates) { - if (!asn1_template_print_ctx(out, fld, indent, - it->templates, pctx)) - return 0; - break; - } - /* fall thru */ - case ASN1_ITYPE_MSTRING: - if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx)) - return 0; - break; - - case ASN1_ITYPE_EXTERN: - if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) - return 0; - /* Use new style print routine if possible */ - ef = it->funcs; - if (ef && ef->asn1_ex_print) { - i = ef->asn1_ex_print(out, fld, indent, "", pctx); - if (!i) - return 0; - if ((i == 2) && (BIO_puts(out, "\n") <= 0)) - return 0; - return 1; - } else if (sname && - BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0) - return 0; - break; - - case ASN1_ITYPE_CHOICE: -#if 0 - if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) - return 0; -#endif - /* CHOICE type, get selector */ - i = asn1_get_choice_selector(fld, it); - /* This should never happen... */ - if ((i < 0) || (i >= it->tcount)) { - if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0) - return 0; - return 1; - } - tt = it->templates + i; - tmpfld = asn1_get_field_ptr(fld, tt); - if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) - return 0; - break; - - case ASN1_ITYPE_SEQUENCE: - case ASN1_ITYPE_NDEF_SEQUENCE: - if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) - return 0; - if (fname || sname) { - if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { - if (BIO_puts(out, " {\n") <= 0) - return 0; - } else { - if (BIO_puts(out, "\n") <= 0) - return 0; - } - } - - if (asn1_cb) { - i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg); - if (i == 0) - return 0; - if (i == 2) - return 1; - } - - /* Print each field entry */ - for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { - const ASN1_TEMPLATE *seqtt; - seqtt = asn1_do_adb(fld, tt, 1); - if (!seqtt) - return 0; - tmpfld = asn1_get_field_ptr(fld, seqtt); - if (!asn1_template_print_ctx(out, tmpfld, - indent + 2, seqtt, pctx)) - return 0; - } - if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { - if (BIO_printf(out, "%*s}\n", indent, "") < 0) - return 0; - } - - if (asn1_cb) { - i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg); - if (i == 0) - return 0; - } - break; - - default: - BIO_printf(out, "Unprocessed type %d\n", it->itype); - return 0; - } - - return 1; -} - -int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, - const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) -{ - int i, flags; - const char *sname, *fname; - flags = tt->flags; - if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME) - sname = ASN1_ITEM_ptr(tt->item)->sname; - else - sname = NULL; - if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) - fname = NULL; - else - fname = tt->field_name; - if (flags & ASN1_TFLG_SK_MASK) { - char *tname; - ASN1_VALUE *skitem; - STACK_OF(ASN1_VALUE) *stack; - - /* SET OF, SEQUENCE OF */ - if (fname) { - if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) { - if (flags & ASN1_TFLG_SET_OF) - tname = "SET"; - else - tname = "SEQUENCE"; - if (BIO_printf(out, "%*s%s OF %s {\n", - indent, "", tname, tt->field_name) <= 0) - return 0; - } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0) - return 0; - } - stack = (STACK_OF(ASN1_VALUE) *)*fld; - for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) { - if ((i > 0) && (BIO_puts(out, "\n") <= 0)) - return 0; - - skitem = sk_ASN1_VALUE_value(stack, i); - if (!asn1_item_print_ctx(out, &skitem, indent + 2, - ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, - pctx)) - return 0; - } - if (!i && BIO_printf(out, "%*s\n", indent + 2, "") <= 0) - return 0; - if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { - if (BIO_printf(out, "%*s}\n", indent, "") <= 0) - return 0; - } - return 1; - } - return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item), - fname, sname, 0, pctx); -} - -static int asn1_print_fsname(BIO *out, int indent, - const char *fname, const char *sname, - const ASN1_PCTX *pctx) -{ - static char spaces[] = " "; - const int nspaces = sizeof(spaces) - 1; - -#if 0 - if (!sname && !fname) - return 1; -#endif - - while (indent > nspaces) { - if (BIO_write(out, spaces, nspaces) != nspaces) - return 0; - indent -= nspaces; - } - if (BIO_write(out, spaces, indent) != indent) - return 0; - if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) - sname = NULL; - if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) - fname = NULL; - if (!sname && !fname) - return 1; - if (fname) { - if (BIO_puts(out, fname) <= 0) - return 0; - } - if (sname) { - if (fname) { - if (BIO_printf(out, " (%s)", sname) <= 0) - return 0; - } else { - if (BIO_puts(out, sname) <= 0) - return 0; - } - } - if (BIO_write(out, ": ", 2) != 2) - return 0; - return 1; -} - -static int asn1_print_boolean_ctx(BIO *out, int boolval, - const ASN1_PCTX *pctx) -{ - const char *str; - switch (boolval) { - case -1: - str = "BOOL ABSENT"; - break; - - case 0: - str = "FALSE"; - break; - - default: - str = "TRUE"; - break; - - } - - if (BIO_puts(out, str) <= 0) - return 0; - return 1; - -} - -static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, - const ASN1_PCTX *pctx) -{ - char *s; - int ret = 1; - s = i2s_ASN1_INTEGER(NULL, str); - if (s == NULL) - return 0; - if (BIO_puts(out, s) <= 0) - ret = 0; - OPENSSL_free(s); - return ret; -} - -static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, - const ASN1_PCTX *pctx) -{ - char objbuf[80]; - const char *ln; - ln = OBJ_nid2ln(OBJ_obj2nid(oid)); - if (!ln) - ln = ""; - OBJ_obj2txt(objbuf, sizeof(objbuf), oid, 1); - if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) - return 0; - return 1; -} - -static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent, - const ASN1_PCTX *pctx) -{ - if (str->type == V_ASN1_BIT_STRING) { - if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0) - return 0; - } else if (BIO_puts(out, "\n") <= 0) - return 0; - if ((str->length > 0) - && BIO_dump_indent(out, (char *)str->data, str->length, - indent + 2) <= 0) - return 0; - return 1; -} - -static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, - const ASN1_ITEM *it, int indent, - const char *fname, const char *sname, - const ASN1_PCTX *pctx) -{ - long utype; - ASN1_STRING *str; - int ret = 1, needlf = 1; - const char *pname; - const ASN1_PRIMITIVE_FUNCS *pf; - pf = it->funcs; - if (!asn1_print_fsname(out, indent, fname, sname, pctx)) - return 0; - if (pf && pf->prim_print) - return pf->prim_print(out, fld, it, indent, pctx); - if (it->itype == ASN1_ITYPE_MSTRING) { - str = (ASN1_STRING *)*fld; - utype = str->type & ~V_ASN1_NEG; - } else { - utype = it->utype; - if (utype == V_ASN1_BOOLEAN) - str = NULL; - else - str = (ASN1_STRING *)*fld; - } - if (utype == V_ASN1_ANY) { - ASN1_TYPE *atype = (ASN1_TYPE *)*fld; - utype = atype->type; - fld = &atype->value.asn1_value; - str = (ASN1_STRING *)*fld; - if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) - pname = NULL; - else - pname = ASN1_tag2str(utype); - } else { - if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE) - pname = ASN1_tag2str(utype); - else - pname = NULL; - } - - if (utype == V_ASN1_NULL) { - if (BIO_puts(out, "NULL\n") <= 0) - return 0; - return 1; - } - - if (pname) { - if (BIO_puts(out, pname) <= 0) - return 0; - if (BIO_puts(out, ":") <= 0) - return 0; - } - - switch (utype) { - case V_ASN1_BOOLEAN: - { - int boolval = *(int *)fld; - if (boolval == -1) - boolval = it->size; - ret = asn1_print_boolean_ctx(out, boolval, pctx); - } - break; - - case V_ASN1_INTEGER: - case V_ASN1_ENUMERATED: - ret = asn1_print_integer_ctx(out, str, pctx); - break; - - case V_ASN1_UTCTIME: - ret = ASN1_UTCTIME_print(out, str); - break; - - case V_ASN1_GENERALIZEDTIME: - ret = ASN1_GENERALIZEDTIME_print(out, str); - break; - - case V_ASN1_OBJECT: - ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx); - break; - - case V_ASN1_OCTET_STRING: - case V_ASN1_BIT_STRING: - ret = asn1_print_obstring_ctx(out, str, indent, pctx); - needlf = 0; - break; - - case V_ASN1_SEQUENCE: - case V_ASN1_SET: - case V_ASN1_OTHER: - if (BIO_puts(out, "\n") <= 0) - return 0; - if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0) - ret = 0; - needlf = 0; - break; - - default: - ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); - - } - if (!ret) - return 0; - if (needlf && BIO_puts(out, "\n") <= 0) - return 0; - return 1; -} -/* tasn_typ.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#include -// #include "asn1.h" -// #include "asn1t.h" - -/* Declarations for string types */ - - -IMPLEMENT_ASN1_TYPE(ASN1_INTEGER) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER) - -IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED) - -IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING) - -IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING) - -IMPLEMENT_ASN1_TYPE(ASN1_NULL) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL) - -IMPLEMENT_ASN1_TYPE(ASN1_OBJECT) - -IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING) - -IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) - -IMPLEMENT_ASN1_TYPE(ASN1_T61STRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING) - -IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING) - -IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING) - -IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME) - -IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) - -IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) - -IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) - -IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING) -IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING) - -IMPLEMENT_ASN1_TYPE(ASN1_ANY) - -/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */ -IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE) - -IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) - -/* Multistring types */ - -IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE) -IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) - -IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT) -IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) - -IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING) -IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) - -/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */ -IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1) -IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1) -IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0) - -/* Special, OCTET STRING with indefinite length constructed support */ - -IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF) - -ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY) -ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY) - -ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY) -ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY) - -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY) -/* tasn_utl.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include -// #include "asn1.h" -// #include "asn1t.h" -// #include "objects.h" -// #include "err.h" - -/* Utility functions for manipulating fields and offsets */ - -/* Add 'offset' to 'addr' */ -#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset) - -/* - * Given an ASN1_ITEM CHOICE type return the selector value - */ - -int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - int *sel = offset2ptr(*pval, it->utype); - return *sel; -} - -/* - * Given an ASN1_ITEM CHOICE type set the selector value, return old value. - */ - -int asn1_set_choice_selector(ASN1_VALUE **pval, int value, - const ASN1_ITEM *it) -{ - int *sel, ret; - sel = offset2ptr(*pval, it->utype); - ret = *sel; - *sel = value; - return ret; -} - -/* - * Do reference counting. The value 'op' decides what to do. if it is +1 - * then the count is incremented. If op is 0 count is set to 1. If op is -1 - * count is decremented and the return value is the current refrence count or - * 0 if no reference count exists. - */ - -int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) -{ - const ASN1_AUX *aux; - int *lck, ret; - if ((it->itype != ASN1_ITYPE_SEQUENCE) - && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE)) - return 0; - aux = it->funcs; - if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) - return 0; - lck = offset2ptr(*pval, aux->ref_offset); - if (op == 0) { - *lck = 1; - return 1; - } - ret = CRYPTO_add(lck, op, aux->ref_lock); -#ifdef REF_PRINT - fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck); -#endif -#ifdef REF_CHECK - if (ret < 0) - fprintf(stderr, "%s, bad reference count\n", it->sname); -#endif - return ret; -} - -static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - const ASN1_AUX *aux; - if (!pval || !*pval) - return NULL; - aux = it->funcs; - if (!aux || !(aux->flags & ASN1_AFLG_ENCODING)) - return NULL; - return offset2ptr(*pval, aux->enc_offset); -} - -void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (enc) { - enc->enc = NULL; - enc->len = 0; - enc->modified = 1; - } -} - -void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (enc) { - if (enc->enc) - OPENSSL_free(enc->enc); - enc->enc = NULL; - enc->len = 0; - enc->modified = 1; - } -} - -int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, - const ASN1_ITEM *it) -{ - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (!enc) - return 1; - - if (enc->enc) - OPENSSL_free(enc->enc); - enc->enc = OPENSSL_malloc(inlen); - if (!enc->enc) - return 0; - memcpy(enc->enc, in, inlen); - enc->len = inlen; - enc->modified = 0; - - return 1; -} - -int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, - const ASN1_ITEM *it) -{ - ASN1_ENCODING *enc; - enc = asn1_get_enc_ptr(pval, it); - if (!enc || enc->modified) - return 0; - if (out) { - memcpy(*out, enc->enc, enc->len); - *out += enc->len; - } - if (len) - *len = enc->len; - return 1; -} - -/* Given an ASN1_TEMPLATE get a pointer to a field */ -ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) -{ - ASN1_VALUE **pvaltmp; - if (tt->flags & ASN1_TFLG_COMBINE) - return pval; - pvaltmp = offset2ptr(*pval, tt->offset); - /* - * NOTE for BOOLEAN types the field is just a plain int so we can't - * return int **, so settle for (int *). - */ - return pvaltmp; -} - -/* - * Handle ANY DEFINED BY template, find the selector, look up the relevant - * ASN1_TEMPLATE in the table and return it. - */ - -const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, - int nullerr) -{ - const ASN1_ADB *adb; - const ASN1_ADB_TABLE *atbl; - long selector; - ASN1_VALUE **sfld; - int i; - if (!(tt->flags & ASN1_TFLG_ADB_MASK)) - return tt; - - /* Else ANY DEFINED BY ... get the table */ - adb = ASN1_ADB_ptr(tt->item); - - /* Get the selector field */ - sfld = offset2ptr(*pval, adb->offset); - - /* Check if NULL */ - if (*sfld == NULL) { - if (!adb->null_tt) - goto err; - return adb->null_tt; - } - - /* - * Convert type to a long: NB: don't check for NID_undef here because it - * might be a legitimate value in the table - */ - if (tt->flags & ASN1_TFLG_ADB_OID) - selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); - else - selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld); - - /* - * Try to find matching entry in table Maybe should check application - * types first to allow application override? Might also be useful to - * have a flag which indicates table is sorted and we can do a binary - * search. For now stick to a linear search. - */ - - for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++) - if (atbl->value == selector) - return &atbl->tt; - - /* FIXME: need to search application table too */ - - /* No match, return default type */ - if (!adb->default_tt) - goto err; - return adb->default_tt; - - err: - /* FIXME: should log the value or OID of unsupported type */ - if (nullerr) - ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); - return NULL; -} diff --git a/Sources/COpenSSL/tb_asnmth.c b/Sources/COpenSSL/tb_asnmth.c deleted file mode 100644 index 751ebe3e..00000000 --- a/Sources/COpenSSL/tb_asnmth.c +++ /dev/null @@ -1,247 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ==================================================================== - * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" -#include "asn1_locl.h" -#include "evp.h" - -/* - * If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the - * function that is used by EVP to hook in pkey_asn1_meth code and cache - * defaults (etc), will display brief debugging summaries to stderr with the - * 'nid'. - */ -/* #define ENGINE_PKEY_ASN1_METH_DEBUG */ - -static ENGINE_TABLE *pkey_asn1_meth_table = NULL; - -void ENGINE_unregister_pkey_asn1_meths(ENGINE *e) -{ - engine_table_unregister(&pkey_asn1_meth_table, e); -} - -static void engine_unregister_all_pkey_asn1_meths(void) -{ - engine_table_cleanup(&pkey_asn1_meth_table); -} - -int ENGINE_register_pkey_asn1_meths(ENGINE *e) -{ - if (e->pkey_asn1_meths) { - const int *nids; - int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); - if (num_nids > 0) - return engine_table_register(&pkey_asn1_meth_table, - engine_unregister_all_pkey_asn1_meths, - e, nids, num_nids, 0); - } - return 1; -} - -void ENGINE_register_all_pkey_asn1_meths(void) -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_pkey_asn1_meths(e); -} - -int ENGINE_set_default_pkey_asn1_meths(ENGINE *e) -{ - if (e->pkey_asn1_meths) { - const int *nids; - int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); - if (num_nids > 0) - return engine_table_register(&pkey_asn1_meth_table, - engine_unregister_all_pkey_asn1_meths, - e, nids, num_nids, 1); - } - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references) for a given pkey_asn1_meth 'nid' - */ -ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid) -{ - return engine_table_select(&pkey_asn1_meth_table, nid); -} - -/* - * Obtains a pkey_asn1_meth implementation from an ENGINE functional - * reference - */ -const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid) -{ - EVP_PKEY_ASN1_METHOD *ret; - ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e); - if (!fn || !fn(e, &ret, NULL, nid)) { - ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, - ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); - return NULL; - } - return ret; -} - -/* Gets the pkey_asn1_meth callback from an ENGINE structure */ -ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e) -{ - return e->pkey_asn1_meths; -} - -/* Sets the pkey_asn1_meth callback in an ENGINE structure */ -int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f) -{ - e->pkey_asn1_meths = f; - return 1; -} - -/* - * Internal function to free up EVP_PKEY_ASN1_METHOD structures before an - * ENGINE is destroyed - */ - -void engine_pkey_asn1_meths_free(ENGINE *e) -{ - int i; - EVP_PKEY_ASN1_METHOD *pkm; - if (e->pkey_asn1_meths) { - const int *pknids; - int npknids; - npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0); - for (i = 0; i < npknids; i++) { - if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i])) { - EVP_PKEY_asn1_free(pkm); - } - } - } -} - -/* - * Find a method based on a string. This does a linear search through all - * implemented algorithms. This is OK in practice because only a small number - * of algorithms are likely to be implemented in an engine and it is not used - * for speed critical operations. - */ - -const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, - const char *str, - int len) -{ - int i, nidcount; - const int *nids; - EVP_PKEY_ASN1_METHOD *ameth; - if (!e->pkey_asn1_meths) - return NULL; - if (len == -1) - len = strlen(str); - nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0); - for (i = 0; i < nidcount; i++) { - e->pkey_asn1_meths(e, &ameth, NULL, nids[i]); - if (((int)strlen(ameth->pem_str) == len) && - !strncasecmp(ameth->pem_str, str, len)) - return ameth; - } - return NULL; -} - -typedef struct { - ENGINE *e; - const EVP_PKEY_ASN1_METHOD *ameth; - const char *str; - int len; -} ENGINE_FIND_STR; - -static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg) -{ - ENGINE_FIND_STR *lk = arg; - int i; - if (lk->ameth) - return; - for (i = 0; i < sk_ENGINE_num(sk); i++) { - ENGINE *e = sk_ENGINE_value(sk, i); - EVP_PKEY_ASN1_METHOD *ameth; - e->pkey_asn1_meths(e, &ameth, NULL, nid); - if (ameth != NULL && ((int)strlen(ameth->pem_str) == lk->len) && - !strncasecmp(ameth->pem_str, lk->str, lk->len)) { - lk->e = e; - lk->ameth = ameth; - return; - } - } -} - -const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, - const char *str, - int len) -{ - ENGINE_FIND_STR fstr; - fstr.e = NULL; - fstr.ameth = NULL; - fstr.str = str; - fstr.len = len; - CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); - engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr); - /* If found obtain a structural reference to engine */ - if (fstr.e) { - fstr.e->struct_ref++; - engine_ref_debug(fstr.e, 0, 1) - } - *pe = fstr.e; - CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); - return fstr.ameth; -} diff --git a/Sources/COpenSSL/tb_cipher.c b/Sources/COpenSSL/tb_cipher.c deleted file mode 100644 index fcfb2efd..00000000 --- a/Sources/COpenSSL/tb_cipher.c +++ /dev/null @@ -1,143 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_cipher_engine(), the function - * that is used by EVP to hook in cipher code and cache defaults (etc), will - * display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_CIPHER_DEBUG */ - -static ENGINE_TABLE *cipher_table = NULL; - -void ENGINE_unregister_ciphers(ENGINE *e) -{ - engine_table_unregister(&cipher_table, e); -} - -static void engine_unregister_all_ciphers(void) -{ - engine_table_cleanup(&cipher_table); -} - -int ENGINE_register_ciphers(ENGINE *e) -{ - if (e->ciphers) { - const int *nids; - int num_nids = e->ciphers(e, NULL, &nids, 0); - if (num_nids > 0) - return engine_table_register(&cipher_table, - engine_unregister_all_ciphers, e, - nids, num_nids, 0); - } - return 1; -} - -void ENGINE_register_all_ciphers() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_ciphers(e); -} - -int ENGINE_set_default_ciphers(ENGINE *e) -{ - if (e->ciphers) { - const int *nids; - int num_nids = e->ciphers(e, NULL, &nids, 0); - if (num_nids > 0) - return engine_table_register(&cipher_table, - engine_unregister_all_ciphers, e, - nids, num_nids, 1); - } - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references) for a given cipher 'nid' - */ -ENGINE *ENGINE_get_cipher_engine(int nid) -{ - return engine_table_select(&cipher_table, nid); -} - -/* Obtains a cipher implementation from an ENGINE functional reference */ -const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid) -{ - const EVP_CIPHER *ret; - ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e); - if (!fn || !fn(e, &ret, NULL, nid)) { - ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER, ENGINE_R_UNIMPLEMENTED_CIPHER); - return NULL; - } - return ret; -} - -/* Gets the cipher callback from an ENGINE structure */ -ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e) -{ - return e->ciphers; -} - -/* Sets the cipher callback in an ENGINE structure */ -int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f) -{ - e->ciphers = f; - return 1; -} diff --git a/Sources/COpenSSL/tb_dh.c b/Sources/COpenSSL/tb_dh.c deleted file mode 100644 index 8114afa6..00000000 --- a/Sources/COpenSSL/tb_dh.c +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_default_DH(), the function that - * is used by DH to hook in implementation code and cache defaults (etc), - * will display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_DH_DEBUG */ - -static ENGINE_TABLE *dh_table = NULL; -static const int dummy_nid = 1; - -void ENGINE_unregister_DH(ENGINE *e) -{ - engine_table_unregister(&dh_table, e); -} - -static void engine_unregister_all_DH(void) -{ - engine_table_cleanup(&dh_table); -} - -int ENGINE_register_DH(ENGINE *e) -{ - if (e->dh_meth) - return engine_table_register(&dh_table, - engine_unregister_all_DH, e, &dummy_nid, - 1, 0); - return 1; -} - -void ENGINE_register_all_DH() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_DH(e); -} - -int ENGINE_set_default_DH(ENGINE *e) -{ - if (e->dh_meth) - return engine_table_register(&dh_table, - engine_unregister_all_DH, e, &dummy_nid, - 1, 1); - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references). - */ -ENGINE *ENGINE_get_default_DH(void) -{ - return engine_table_select(&dh_table, dummy_nid); -} - -/* Obtains an DH implementation from an ENGINE functional reference */ -const DH_METHOD *ENGINE_get_DH(const ENGINE *e) -{ - return e->dh_meth; -} - -/* Sets an DH implementation in an ENGINE structure */ -int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth) -{ - e->dh_meth = dh_meth; - return 1; -} diff --git a/Sources/COpenSSL/tb_digest.c b/Sources/COpenSSL/tb_digest.c deleted file mode 100644 index de1ad9c0..00000000 --- a/Sources/COpenSSL/tb_digest.c +++ /dev/null @@ -1,143 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_digest_engine(), the function - * that is used by EVP to hook in digest code and cache defaults (etc), will - * display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_DIGEST_DEBUG */ - -static ENGINE_TABLE *digest_table = NULL; - -void ENGINE_unregister_digests(ENGINE *e) -{ - engine_table_unregister(&digest_table, e); -} - -static void engine_unregister_all_digests(void) -{ - engine_table_cleanup(&digest_table); -} - -int ENGINE_register_digests(ENGINE *e) -{ - if (e->digests) { - const int *nids; - int num_nids = e->digests(e, NULL, &nids, 0); - if (num_nids > 0) - return engine_table_register(&digest_table, - engine_unregister_all_digests, e, - nids, num_nids, 0); - } - return 1; -} - -void ENGINE_register_all_digests() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_digests(e); -} - -int ENGINE_set_default_digests(ENGINE *e) -{ - if (e->digests) { - const int *nids; - int num_nids = e->digests(e, NULL, &nids, 0); - if (num_nids > 0) - return engine_table_register(&digest_table, - engine_unregister_all_digests, e, - nids, num_nids, 1); - } - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references) for a given digest 'nid' - */ -ENGINE *ENGINE_get_digest_engine(int nid) -{ - return engine_table_select(&digest_table, nid); -} - -/* Obtains a digest implementation from an ENGINE functional reference */ -const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid) -{ - const EVP_MD *ret; - ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e); - if (!fn || !fn(e, &ret, NULL, nid)) { - ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST, ENGINE_R_UNIMPLEMENTED_DIGEST); - return NULL; - } - return ret; -} - -/* Gets the digest callback from an ENGINE structure */ -ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e) -{ - return e->digests; -} - -/* Sets the digest callback in an ENGINE structure */ -int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f) -{ - e->digests = f; - return 1; -} diff --git a/Sources/COpenSSL/tb_dsa.c b/Sources/COpenSSL/tb_dsa.c deleted file mode 100644 index c1f57f14..00000000 --- a/Sources/COpenSSL/tb_dsa.c +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_default_DSA(), the function that - * is used by DSA to hook in implementation code and cache defaults (etc), - * will display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_DSA_DEBUG */ - -static ENGINE_TABLE *dsa_table = NULL; -static const int dummy_nid = 1; - -void ENGINE_unregister_DSA(ENGINE *e) -{ - engine_table_unregister(&dsa_table, e); -} - -static void engine_unregister_all_DSA(void) -{ - engine_table_cleanup(&dsa_table); -} - -int ENGINE_register_DSA(ENGINE *e) -{ - if (e->dsa_meth) - return engine_table_register(&dsa_table, - engine_unregister_all_DSA, e, &dummy_nid, - 1, 0); - return 1; -} - -void ENGINE_register_all_DSA() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_DSA(e); -} - -int ENGINE_set_default_DSA(ENGINE *e) -{ - if (e->dsa_meth) - return engine_table_register(&dsa_table, - engine_unregister_all_DSA, e, &dummy_nid, - 1, 1); - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references). - */ -ENGINE *ENGINE_get_default_DSA(void) -{ - return engine_table_select(&dsa_table, dummy_nid); -} - -/* Obtains an DSA implementation from an ENGINE functional reference */ -const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e) -{ - return e->dsa_meth; -} - -/* Sets an DSA implementation in an ENGINE structure */ -int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth) -{ - e->dsa_meth = dsa_meth; - return 1; -} diff --git a/Sources/COpenSSL/tb_ecdh.c b/Sources/COpenSSL/tb_ecdh.c deleted file mode 100644 index c51441be..00000000 --- a/Sources/COpenSSL/tb_ecdh.c +++ /dev/null @@ -1,139 +0,0 @@ -/* crypto/engine/tb_ecdh.c */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * The Elliptic Curve Public-Key Crypto Library (ECC Code) included - * herein is developed by SUN MICROSYSTEMS, INC., and is contributed - * to the OpenSSL project. - * - * The ECC Code is licensed pursuant to the OpenSSL open source - * license provided below. - * - * The ECDH engine software is originally written by Nils Gura and - * Douglas Stebila of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_default_ECDH(), the function - * that is used by ECDH to hook in implementation code and cache defaults - * (etc), will display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_ECDH_DEBUG */ - -static ENGINE_TABLE *ecdh_table = NULL; -static const int dummy_nid = 1; - -void ENGINE_unregister_ECDH(ENGINE *e) -{ - engine_table_unregister(&ecdh_table, e); -} - -static void engine_unregister_all_ECDH(void) -{ - engine_table_cleanup(&ecdh_table); -} - -int ENGINE_register_ECDH(ENGINE *e) -{ - if (e->ecdh_meth) - return engine_table_register(&ecdh_table, - engine_unregister_all_ECDH, e, - &dummy_nid, 1, 0); - return 1; -} - -void ENGINE_register_all_ECDH() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_ECDH(e); -} - -int ENGINE_set_default_ECDH(ENGINE *e) -{ - if (e->ecdh_meth) - return engine_table_register(&ecdh_table, - engine_unregister_all_ECDH, e, - &dummy_nid, 1, 1); - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references). - */ -ENGINE *ENGINE_get_default_ECDH(void) -{ - return engine_table_select(&ecdh_table, dummy_nid); -} - -/* Obtains an ECDH implementation from an ENGINE functional reference */ -const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e) -{ - return e->ecdh_meth; -} - -/* Sets an ECDH implementation in an ENGINE structure */ -int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth) -{ - e->ecdh_meth = ecdh_meth; - return 1; -} diff --git a/Sources/COpenSSL/tb_ecdsa.c b/Sources/COpenSSL/tb_ecdsa.c deleted file mode 100644 index a8b9be60..00000000 --- a/Sources/COpenSSL/tb_ecdsa.c +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_default_ECDSA(), the function - * that is used by ECDSA to hook in implementation code and cache defaults - * (etc), will display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_ECDSA_DEBUG */ - -static ENGINE_TABLE *ecdsa_table = NULL; -static const int dummy_nid = 1; - -void ENGINE_unregister_ECDSA(ENGINE *e) -{ - engine_table_unregister(&ecdsa_table, e); -} - -static void engine_unregister_all_ECDSA(void) -{ - engine_table_cleanup(&ecdsa_table); -} - -int ENGINE_register_ECDSA(ENGINE *e) -{ - if (e->ecdsa_meth) - return engine_table_register(&ecdsa_table, - engine_unregister_all_ECDSA, e, - &dummy_nid, 1, 0); - return 1; -} - -void ENGINE_register_all_ECDSA() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_ECDSA(e); -} - -int ENGINE_set_default_ECDSA(ENGINE *e) -{ - if (e->ecdsa_meth) - return engine_table_register(&ecdsa_table, - engine_unregister_all_ECDSA, e, - &dummy_nid, 1, 1); - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references). - */ -ENGINE *ENGINE_get_default_ECDSA(void) -{ - return engine_table_select(&ecdsa_table, dummy_nid); -} - -/* Obtains an ECDSA implementation from an ENGINE functional reference */ -const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e) -{ - return e->ecdsa_meth; -} - -/* Sets an ECDSA implementation in an ENGINE structure */ -int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth) -{ - e->ecdsa_meth = ecdsa_meth; - return 1; -} diff --git a/Sources/COpenSSL/tb_pkmeth.c b/Sources/COpenSSL/tb_pkmeth.c deleted file mode 100644 index 1256573f..00000000 --- a/Sources/COpenSSL/tb_pkmeth.c +++ /dev/null @@ -1,166 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" -#include "evp.h" - -/* - * If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function - * that is used by EVP to hook in pkey_meth code and cache defaults (etc), - * will display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_PKEY_METH_DEBUG */ - -static ENGINE_TABLE *pkey_meth_table = NULL; - -void ENGINE_unregister_pkey_meths(ENGINE *e) -{ - engine_table_unregister(&pkey_meth_table, e); -} - -static void engine_unregister_all_pkey_meths(void) -{ - engine_table_cleanup(&pkey_meth_table); -} - -int ENGINE_register_pkey_meths(ENGINE *e) -{ - if (e->pkey_meths) { - const int *nids; - int num_nids = e->pkey_meths(e, NULL, &nids, 0); - if (num_nids > 0) - return engine_table_register(&pkey_meth_table, - engine_unregister_all_pkey_meths, e, - nids, num_nids, 0); - } - return 1; -} - -void ENGINE_register_all_pkey_meths() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_pkey_meths(e); -} - -int ENGINE_set_default_pkey_meths(ENGINE *e) -{ - if (e->pkey_meths) { - const int *nids; - int num_nids = e->pkey_meths(e, NULL, &nids, 0); - if (num_nids > 0) - return engine_table_register(&pkey_meth_table, - engine_unregister_all_pkey_meths, e, - nids, num_nids, 1); - } - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references) for a given pkey_meth 'nid' - */ -ENGINE *ENGINE_get_pkey_meth_engine(int nid) -{ - return engine_table_select(&pkey_meth_table, nid); -} - -/* Obtains a pkey_meth implementation from an ENGINE functional reference */ -const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid) -{ - EVP_PKEY_METHOD *ret; - ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e); - if (!fn || !fn(e, &ret, NULL, nid)) { - ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH, - ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); - return NULL; - } - return ret; -} - -/* Gets the pkey_meth callback from an ENGINE structure */ -ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e) -{ - return e->pkey_meths; -} - -/* Sets the pkey_meth callback in an ENGINE structure */ -int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f) -{ - e->pkey_meths = f; - return 1; -} - -/* - * Internal function to free up EVP_PKEY_METHOD structures before an ENGINE - * is destroyed - */ - -void engine_pkey_meths_free(ENGINE *e) -{ - int i; - EVP_PKEY_METHOD *pkm; - if (e->pkey_meths) { - const int *pknids; - int npknids; - npknids = e->pkey_meths(e, NULL, &pknids, 0); - for (i = 0; i < npknids; i++) { - if (e->pkey_meths(e, &pkm, NULL, pknids[i])) { - EVP_PKEY_meth_free(pkm); - } - } - } -} diff --git a/Sources/COpenSSL/tb_rand.c b/Sources/COpenSSL/tb_rand.c deleted file mode 100644 index a522264d..00000000 --- a/Sources/COpenSSL/tb_rand.c +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_default_RAND(), the function - * that is used by RAND to hook in implementation code and cache defaults - * (etc), will display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_RAND_DEBUG */ - -static ENGINE_TABLE *rand_table = NULL; -static const int dummy_nid = 1; - -void ENGINE_unregister_RAND(ENGINE *e) -{ - engine_table_unregister(&rand_table, e); -} - -static void engine_unregister_all_RAND(void) -{ - engine_table_cleanup(&rand_table); -} - -int ENGINE_register_RAND(ENGINE *e) -{ - if (e->rand_meth) - return engine_table_register(&rand_table, - engine_unregister_all_RAND, e, - &dummy_nid, 1, 0); - return 1; -} - -void ENGINE_register_all_RAND() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_RAND(e); -} - -int ENGINE_set_default_RAND(ENGINE *e) -{ - if (e->rand_meth) - return engine_table_register(&rand_table, - engine_unregister_all_RAND, e, - &dummy_nid, 1, 1); - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references). - */ -ENGINE *ENGINE_get_default_RAND(void) -{ - return engine_table_select(&rand_table, dummy_nid); -} - -/* Obtains an RAND implementation from an ENGINE functional reference */ -const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e) -{ - return e->rand_meth; -} - -/* Sets an RAND implementation in an ENGINE structure */ -int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth) -{ - e->rand_meth = rand_meth; - return 1; -} diff --git a/Sources/COpenSSL/tb_rsa.c b/Sources/COpenSSL/tb_rsa.c deleted file mode 100644 index 2790a821..00000000 --- a/Sources/COpenSSL/tb_rsa.c +++ /dev/null @@ -1,124 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_default_RSA(), the function that - * is used by RSA to hook in implementation code and cache defaults (etc), - * will display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_RSA_DEBUG */ - -static ENGINE_TABLE *rsa_table = NULL; -static const int dummy_nid = 1; - -void ENGINE_unregister_RSA(ENGINE *e) -{ - engine_table_unregister(&rsa_table, e); -} - -static void engine_unregister_all_RSA(void) -{ - engine_table_cleanup(&rsa_table); -} - -int ENGINE_register_RSA(ENGINE *e) -{ - if (e->rsa_meth) - return engine_table_register(&rsa_table, - engine_unregister_all_RSA, e, &dummy_nid, - 1, 0); - return 1; -} - -void ENGINE_register_all_RSA() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_RSA(e); -} - -int ENGINE_set_default_RSA(ENGINE *e) -{ - if (e->rsa_meth) - return engine_table_register(&rsa_table, - engine_unregister_all_RSA, e, &dummy_nid, - 1, 1); - return 1; -} - -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references). - */ -ENGINE *ENGINE_get_default_RSA(void) -{ - return engine_table_select(&rsa_table, dummy_nid); -} - -/* Obtains an RSA implementation from an ENGINE functional reference */ -const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e) -{ - return e->rsa_meth; -} - -/* Sets an RSA implementation in an ENGINE structure */ -int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth) -{ - e->rsa_meth = rsa_meth; - return 1; -} diff --git a/Sources/COpenSSL/tb_store.c b/Sources/COpenSSL/tb_store.c deleted file mode 100644 index 1eab49d7..00000000 --- a/Sources/COpenSSL/tb_store.c +++ /dev/null @@ -1,129 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "eng_int.h" - -/* - * If this symbol is defined then ENGINE_get_default_STORE(), the function - * that is used by STORE to hook in implementation code and cache defaults - * (etc), will display brief debugging summaries to stderr with the 'nid'. - */ -/* #define ENGINE_STORE_DEBUG */ - -static ENGINE_TABLE *store_table = NULL; -static const int dummy_nid = 1; - -void ENGINE_unregister_STORE(ENGINE *e) -{ - engine_table_unregister(&store_table, e); -} - -static void engine_unregister_all_STORE(void) -{ - engine_table_cleanup(&store_table); -} - -int ENGINE_register_STORE(ENGINE *e) -{ - if (e->store_meth) - return engine_table_register(&store_table, - engine_unregister_all_STORE, e, - &dummy_nid, 1, 0); - return 1; -} - -void ENGINE_register_all_STORE() -{ - ENGINE *e; - - for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) - ENGINE_register_STORE(e); -} - -/* The following two functions are removed because they're useless. */ -#if 0 -int ENGINE_set_default_STORE(ENGINE *e) -{ - if (e->store_meth) - return engine_table_register(&store_table, - engine_unregister_all_STORE, e, - &dummy_nid, 1, 1); - return 1; -} -#endif - -#if 0 -/* - * Exposed API function to get a functional reference from the implementation - * table (ie. try to get a functional reference from the tabled structural - * references). - */ -ENGINE *ENGINE_get_default_STORE(void) -{ - return engine_table_select(&store_table, dummy_nid); -} -#endif - -/* Obtains an STORE implementation from an ENGINE functional reference */ -const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e) -{ - return e->store_meth; -} - -/* Sets an STORE implementation in an ENGINE structure */ -int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth) -{ - e->store_meth = store_meth; - return 1; -} diff --git a/Sources/COpenSSL/th-lock.c b/Sources/COpenSSL/th-lock.c deleted file mode 100644 index 1c6d8046..00000000 --- a/Sources/COpenSSL/th-lock.c +++ /dev/null @@ -1,389 +0,0 @@ -/* crypto/threads/th-lock.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include -#ifdef LINUX -# include -#endif -#ifdef OPENSSL_SYS_WIN32 -# include -#endif -#ifdef SOLARIS -# include -# include -#endif -#ifdef IRIX -# include -# include -#endif -#ifdef PTHREADS -# include -#endif -#include "lhash.h" -#include "crypto.h" -#include "buffer.h" -#include "e_os.h" -#include "x509.h" -#include "ssl.h" -#include "err.h" - -void CRYPTO_thread_setup(void); -void CRYPTO_thread_cleanup(void); - -static void irix_locking_callback(int mode, int type, char *file, int line); -static void solaris_locking_callback(int mode, int type, char *file, - int line); -static void win32_locking_callback(int mode, int type, char *file, int line); -static void pthreads_locking_callback(int mode, int type, char *file, - int line); - -static unsigned long irix_thread_id(void); -static unsigned long solaris_thread_id(void); -static unsigned long pthreads_thread_id(void); - -/*- - * usage: - * CRYPTO_thread_setup(); - * application code - * CRYPTO_thread_cleanup(); - */ - -#define THREAD_STACK_SIZE (16*1024) - -#ifdef OPENSSL_SYS_WIN32 - -static HANDLE *lock_cs; - -void CRYPTO_thread_setup(void) -{ - int i; - - lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); - if (!lock_cs) { - /* Nothing we can do about this...void function! */ - return; - } - for (i = 0; i < CRYPTO_num_locks(); i++) { - lock_cs[i] = CreateMutex(NULL, FALSE, NULL); - } - - CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) - win32_locking_callback); - /* id callback defined */ - return (1); -} - -static void CRYPTO_thread_cleanup(void) -{ - int i; - - CRYPTO_set_locking_callback(NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) - CloseHandle(lock_cs[i]); - OPENSSL_free(lock_cs); -} - -void win32_locking_callback(int mode, int type, char *file, int line) -{ - if (mode & CRYPTO_LOCK) { - WaitForSingleObject(lock_cs[type], INFINITE); - } else { - ReleaseMutex(lock_cs[type]); - } -} - -#endif /* OPENSSL_SYS_WIN32 */ - -#ifdef SOLARIS - -# define USE_MUTEX - -# ifdef USE_MUTEX -static mutex_t *lock_cs; -# else -static rwlock_t *lock_cs; -# endif -static long *lock_count; - -void CRYPTO_thread_setup(void) -{ - int i; - -# ifdef USE_MUTEX - lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t)); -# else - lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(rwlock_t)); -# endif - if (!lock_cs) { - /* Nothing we can do about this...void function! */ - return; - } - lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); - for (i = 0; i < CRYPTO_num_locks(); i++) { - lock_count[i] = 0; -# ifdef USE_MUTEX - mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL); -# else - rwlock_init(&(lock_cs[i]), USYNC_THREAD, NULL); -# endif - } - - CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id); - CRYPTO_set_locking_callback((void (*)())solaris_locking_callback); -} - -void CRYPTO_thread_cleanup(void) -{ - int i; - - CRYPTO_set_locking_callback(NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) { -# ifdef USE_MUTEX - mutex_destroy(&(lock_cs[i])); -# else - rwlock_destroy(&(lock_cs[i])); -# endif - } - OPENSSL_free(lock_cs); - OPENSSL_free(lock_count); -} - -void solaris_locking_callback(int mode, int type, char *file, int line) -{ -# if 0 - fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", - CRYPTO_thread_id(), - (mode & CRYPTO_LOCK) ? "l" : "u", - (type & CRYPTO_READ) ? "r" : "w", file, line); -# endif - -# if 0 - if (CRYPTO_LOCK_SSL_CERT == type) - fprintf(stderr, "(t,m,f,l) %ld %d %s %d\n", - CRYPTO_thread_id(), mode, file, line); -# endif - if (mode & CRYPTO_LOCK) { -# ifdef USE_MUTEX - mutex_lock(&(lock_cs[type])); -# else - if (mode & CRYPTO_READ) - rw_rdlock(&(lock_cs[type])); - else - rw_wrlock(&(lock_cs[type])); -# endif - lock_count[type]++; - } else { -# ifdef USE_MUTEX - mutex_unlock(&(lock_cs[type])); -# else - rw_unlock(&(lock_cs[type])); -# endif - } -} - -unsigned long solaris_thread_id(void) -{ - unsigned long ret; - - ret = (unsigned long)thr_self(); - return (ret); -} -#endif /* SOLARIS */ - -#ifdef IRIX -/* I don't think this works..... */ - -static usptr_t *arena; -static usema_t **lock_cs; - -void CRYPTO_thread_setup(void) -{ - int i; - char filename[20]; - - lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *)); - if (!lock_cs) { - /* Nothing we can do about this...void function! */ - return; - } - - strcpy(filename, "/tmp/mttest.XXXXXX"); - mktemp(filename); - - usconfig(CONF_STHREADIOOFF); - usconfig(CONF_STHREADMALLOCOFF); - usconfig(CONF_INITUSERS, 100); - usconfig(CONF_LOCKTYPE, US_DEBUGPLUS); - arena = usinit(filename); - unlink(filename); - - for (i = 0; i < CRYPTO_num_locks(); i++) { - lock_cs[i] = usnewsema(arena, 1); - } - - CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id); - CRYPTO_set_locking_callback((void (*)())irix_locking_callback); -} - -void CRYPTO_thread_cleanup(void) -{ - int i; - - CRYPTO_set_locking_callback(NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) { - char buf[10]; - - sprintf(buf, "%2d:", i); - usdumpsema(lock_cs[i], stdout, buf); - usfreesema(lock_cs[i], arena); - } - OPENSSL_free(lock_cs); -} - -void irix_locking_callback(int mode, int type, char *file, int line) -{ - if (mode & CRYPTO_LOCK) { - uspsema(lock_cs[type]); - } else { - usvsema(lock_cs[type]); - } -} - -unsigned long irix_thread_id(void) -{ - unsigned long ret; - - ret = (unsigned long)getpid(); - return (ret); -} -#endif /* IRIX */ - -/* Linux and a few others */ -#ifdef PTHREADS - -static pthread_mutex_t *lock_cs; -static long *lock_count; - -void CRYPTO_thread_setup(void) -{ - int i; - - lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); - lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); - if (!lock_cs || !lock_count) { - /* Nothing we can do about this...void function! */ - if (lock_cs) - OPENSSL_free(lock_cs); - if (lock_count) - OPENSSL_free(lock_count); - return; - } - for (i = 0; i < CRYPTO_num_locks(); i++) { - lock_count[i] = 0; - pthread_mutex_init(&(lock_cs[i]), NULL); - } - - CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); - CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); -} - -void thread_cleanup(void) -{ - int i; - - CRYPTO_set_locking_callback(NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) { - pthread_mutex_destroy(&(lock_cs[i])); - } - OPENSSL_free(lock_cs); - OPENSSL_free(lock_count); -} - -void pthreads_locking_callback(int mode, int type, char *file, int line) -{ -# if 0 - fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", - CRYPTO_thread_id(), - (mode & CRYPTO_LOCK) ? "l" : "u", - (type & CRYPTO_READ) ? "r" : "w", file, line); -# endif -# if 0 - if (CRYPTO_LOCK_SSL_CERT == type) - fprintf(stderr, "(t,m,f,l) %ld %d %s %d\n", - CRYPTO_thread_id(), mode, file, line); -# endif - if (mode & CRYPTO_LOCK) { - pthread_mutex_lock(&(lock_cs[type])); - lock_count[type]++; - } else { - pthread_mutex_unlock(&(lock_cs[type])); - } -} - -unsigned long pthreads_thread_id(void) -{ - unsigned long ret; - - ret = (unsigned long)pthread_self(); - return (ret); -} - -#endif /* PTHREADS */ diff --git a/Sources/COpenSSL/tls1.h b/Sources/COpenSSL/tls1.h deleted file mode 100644 index 8295c82c..00000000 --- a/Sources/COpenSSL/tls1.h +++ /dev/null @@ -1,810 +0,0 @@ -/* ssl/tls1.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * - * Portions of the attached software ("Contribution") are developed by - * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. - * - * The Contribution is licensed pursuant to the OpenSSL open source - * license provided above. - * - * ECC cipher suite support in OpenSSL originally written by - * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. - * - */ -/* ==================================================================== - * Copyright 2005 Nokia. All rights reserved. - * - * The portions of the attached software ("Contribution") is developed by - * Nokia Corporation and is licensed pursuant to the OpenSSL open source - * license. - * - * The Contribution, originally written by Mika Kousa and Pasi Eronen of - * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites - * support (see RFC 4279) to OpenSSL. - * - * No patent licenses or other rights except those expressly stated in - * the OpenSSL open source license shall be deemed granted or received - * expressly, by implication, estoppel, or otherwise. - * - * No assurances are provided by Nokia that the Contribution does not - * infringe the patent or other intellectual property rights of any third - * party or that the license provides you with all the necessary rights - * to make use of the Contribution. - * - * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN - * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA - * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY - * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR - * OTHERWISE. - */ - -#ifndef HEADER_TLS1_H -# define HEADER_TLS1_H - -# include "buffer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 - -# define TLS1_VERSION 0x0301 -# define TLS1_1_VERSION 0x0302 -# define TLS1_2_VERSION 0x0303 -# define TLS_MAX_VERSION TLS1_2_VERSION - -# define TLS1_VERSION_MAJOR 0x03 -# define TLS1_VERSION_MINOR 0x01 - -# define TLS1_1_VERSION_MAJOR 0x03 -# define TLS1_1_VERSION_MINOR 0x02 - -# define TLS1_2_VERSION_MAJOR 0x03 -# define TLS1_2_VERSION_MINOR 0x03 - -# define TLS1_get_version(s) \ - ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0) - -# define TLS1_get_client_version(s) \ - ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0) - -# define TLS1_AD_DECRYPTION_FAILED 21 -# define TLS1_AD_RECORD_OVERFLOW 22 -# define TLS1_AD_UNKNOWN_CA 48/* fatal */ -# define TLS1_AD_ACCESS_DENIED 49/* fatal */ -# define TLS1_AD_DECODE_ERROR 50/* fatal */ -# define TLS1_AD_DECRYPT_ERROR 51 -# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ -# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ -# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ -# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ -# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ -# define TLS1_AD_USER_CANCELLED 90 -# define TLS1_AD_NO_RENEGOTIATION 100 -/* codes 110-114 are from RFC3546 */ -# define TLS1_AD_UNSUPPORTED_EXTENSION 110 -# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 -# define TLS1_AD_UNRECOGNIZED_NAME 112 -# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 -# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 -# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ - -/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ -# define TLSEXT_TYPE_server_name 0 -# define TLSEXT_TYPE_max_fragment_length 1 -# define TLSEXT_TYPE_client_certificate_url 2 -# define TLSEXT_TYPE_trusted_ca_keys 3 -# define TLSEXT_TYPE_truncated_hmac 4 -# define TLSEXT_TYPE_status_request 5 -/* ExtensionType values from RFC4681 */ -# define TLSEXT_TYPE_user_mapping 6 -/* ExtensionType values from RFC5878 */ -# define TLSEXT_TYPE_client_authz 7 -# define TLSEXT_TYPE_server_authz 8 -/* ExtensionType values from RFC6091 */ -# define TLSEXT_TYPE_cert_type 9 - -/* ExtensionType values from RFC4492 */ -# define TLSEXT_TYPE_elliptic_curves 10 -# define TLSEXT_TYPE_ec_point_formats 11 - -/* ExtensionType value from RFC5054 */ -# define TLSEXT_TYPE_srp 12 - -/* ExtensionType values from RFC5246 */ -# define TLSEXT_TYPE_signature_algorithms 13 - -/* ExtensionType value from RFC5764 */ -# define TLSEXT_TYPE_use_srtp 14 - -/* ExtensionType value from RFC5620 */ -# define TLSEXT_TYPE_heartbeat 15 - -/* ExtensionType value from RFC7301 */ -# define TLSEXT_TYPE_application_layer_protocol_negotiation 16 - -/* - * ExtensionType value for TLS padding extension. - * http://tools.ietf.org/html/draft-agl-tls-padding - */ -# define TLSEXT_TYPE_padding 21 - -/* ExtensionType value from RFC4507 */ -# define TLSEXT_TYPE_session_ticket 35 - -/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */ -# if 0 -/* - * will have to be provided externally for now , - * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183 - * using whatever extension number you'd like to try - */ -# define TLSEXT_TYPE_opaque_prf_input ?? -# endif - -/* Temporary extension type */ -# define TLSEXT_TYPE_renegotiate 0xff01 - -# ifndef OPENSSL_NO_NEXTPROTONEG -/* This is not an IANA defined extension number */ -# define TLSEXT_TYPE_next_proto_neg 13172 -# endif - -/* NameType value from RFC3546 */ -# define TLSEXT_NAMETYPE_host_name 0 -/* status request value from RFC3546 */ -# define TLSEXT_STATUSTYPE_ocsp 1 - -/* ECPointFormat values from RFC4492 */ -# define TLSEXT_ECPOINTFORMAT_first 0 -# define TLSEXT_ECPOINTFORMAT_uncompressed 0 -# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 -# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 -# define TLSEXT_ECPOINTFORMAT_last 2 - -/* Signature and hash algorithms from RFC5246 */ -# define TLSEXT_signature_anonymous 0 -# define TLSEXT_signature_rsa 1 -# define TLSEXT_signature_dsa 2 -# define TLSEXT_signature_ecdsa 3 - -/* Total number of different signature algorithms */ -# define TLSEXT_signature_num 4 - -# define TLSEXT_hash_none 0 -# define TLSEXT_hash_md5 1 -# define TLSEXT_hash_sha1 2 -# define TLSEXT_hash_sha224 3 -# define TLSEXT_hash_sha256 4 -# define TLSEXT_hash_sha384 5 -# define TLSEXT_hash_sha512 6 - -/* Total number of different digest algorithms */ - -# define TLSEXT_hash_num 7 - -/* Flag set for unrecognised algorithms */ -# define TLSEXT_nid_unknown 0x1000000 - -/* ECC curves */ - -# define TLSEXT_curve_P_256 23 -# define TLSEXT_curve_P_384 24 - -# ifndef OPENSSL_NO_TLSEXT - -# define TLSEXT_MAXLEN_host_name 255 - -const char *SSL_get_servername(const SSL *s, const int type); -int SSL_get_servername_type(const SSL *s); -/* - * SSL_export_keying_material exports a value derived from the master secret, - * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and - * optional context. (Since a zero length context is allowed, the |use_context| - * flag controls whether a context is included.) It returns 1 on success and - * zero otherwise. - */ -int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, - const char *label, size_t llen, - const unsigned char *context, size_t contextlen, - int use_context); - -int SSL_get_sigalgs(SSL *s, int idx, - int *psign, int *phash, int *psignandhash, - unsigned char *rsig, unsigned char *rhash); - -int SSL_get_shared_sigalgs(SSL *s, int idx, - int *psign, int *phash, int *psignandhash, - unsigned char *rsig, unsigned char *rhash); - -int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain); - -# define SSL_set_tlsext_host_name(s,name) \ -SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) - -# define SSL_set_tlsext_debug_callback(ssl, cb) \ -SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb) - -# define SSL_set_tlsext_debug_arg(ssl, arg) \ -SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg) - -# define SSL_set_tlsext_status_type(ssl, type) \ -SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL) - -# define SSL_get_tlsext_status_exts(ssl, arg) \ -SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) - -# define SSL_set_tlsext_status_exts(ssl, arg) \ -SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) - -# define SSL_get_tlsext_status_ids(ssl, arg) \ -SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) - -# define SSL_set_tlsext_status_ids(ssl, arg) \ -SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) - -# define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ -SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg) - -# define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ -SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg) - -# define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ -SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) - -# define SSL_TLSEXT_ERR_OK 0 -# define SSL_TLSEXT_ERR_ALERT_WARNING 1 -# define SSL_TLSEXT_ERR_ALERT_FATAL 2 -# define SSL_TLSEXT_ERR_NOACK 3 - -# define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ -SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) - -# define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys)) -# define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ - SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys)) - -# define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ -SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) - -# define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ -SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg) - -# define SSL_set_tlsext_opaque_prf_input(s, src, len) \ -SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src) -# define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \ -SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb) -# define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \ -SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg) - -# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ -SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) - -# ifndef OPENSSL_NO_HEARTBEATS -# define SSL_TLSEXT_HB_ENABLED 0x01 -# define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02 -# define SSL_TLSEXT_HB_DONT_RECV_REQUESTS 0x04 - -# define SSL_get_tlsext_heartbeat_pending(ssl) \ - SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL) -# define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \ - SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL) -# endif -# endif - -/* PSK ciphersuites from 4279 */ -# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A -# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B -# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C -# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D - -/* - * Additional TLS ciphersuites from expired Internet Draft - * draft-ietf-tls-56-bit-ciphersuites-01.txt (available if - * TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see s3_lib.c). We - * actually treat them like SSL 3.0 ciphers, which we probably shouldn't. - * Note that the first two are actually not in the IDs. - */ -# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060/* not in - * ID */ -# define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061/* not in - * ID */ -# define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 -# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 -# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 -# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x03000065 -# define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066 - -/* AES ciphersuites from RFC3268 */ -# define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F -# define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 -# define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 -# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 -# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 -# define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 - -# define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 -# define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 -# define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 -# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 -# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 -# define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A - -/* TLS v1.2 ciphersuites */ -# define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B -# define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C -# define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D -# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E -# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F -# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 - -/* Camellia ciphersuites from RFC4132 */ -# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 -# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 -# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 -# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 -# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 -# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 - -/* TLS v1.2 ciphersuites */ -# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 -# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 -# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 -# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A -# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B -# define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C -# define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D - -/* Camellia ciphersuites from RFC4132 */ -# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 -# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 -# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 -# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 -# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 -# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 - -/* SEED ciphersuites from RFC4162 */ -# define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 -# define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 -# define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 -# define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 -# define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A -# define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B - -/* TLS v1.2 GCM ciphersuites from RFC5288 */ -# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C -# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D -# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E -# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F -# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 -# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 -# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 -# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 -# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 -# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 -# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 -# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 - -/* - * ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in - * draft 13 - */ -# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 -# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 -# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 -# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 -# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 - -# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 -# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 -# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 -# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 -# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A - -# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B -# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C -# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D -# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E -# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F - -# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 -# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 -# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 -# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 -# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 - -# define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 -# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 -# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 -# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 -# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 - -/* SRP ciphersuites from RFC 5054 */ -# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A -# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B -# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C -# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D -# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E -# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F -# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 -# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 -# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 - -/* ECDH HMAC based ciphersuites from RFC5289 */ - -# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 -# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 -# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 -# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 -# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 -# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 -# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 -# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A - -/* ECDH GCM based ciphersuites from RFC5289 */ -# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B -# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C -# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D -# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E -# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F -# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 -# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 -# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 - -/* - * XXX * Backward compatibility alert: + * Older versions of OpenSSL gave - * some DHE ciphers names with "EDH" + * instead of "DHE". Going forward, we - * should be using DHE + * everywhere, though we may indefinitely maintain - * aliases for users + * or configurations that used "EDH" + - */ -# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5" -# define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5" -# define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DES-CBC-SHA" -# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DHE-DSS-DES-CBC-SHA" -# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA "EXP1024-RC4-SHA" -# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA "EXP1024-DHE-DSS-RC4-SHA" -# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" - -/* AES ciphersuites from RFC3268 */ -# define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" -# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" -# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" -# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" -# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" -# define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" - -# define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" -# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" -# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" -# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" -# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" -# define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" - -/* ECC ciphersuites from RFC4492 */ -# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" -# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" -# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" -# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" -# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" - -# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" -# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" -# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" -# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" -# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" - -# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" -# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" -# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" -# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" -# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" - -# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" -# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" -# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" -# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" -# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" - -# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" -# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" -# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" -# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" -# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" - -/* PSK ciphersuites from RFC 4279 */ -# define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" -# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" -# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" -# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" - -/* SRP ciphersuite from RFC 5054 */ -# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" -# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" -# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" -# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" -# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" -# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" -# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" -# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" -# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" - -/* Camellia ciphersuites from RFC4132 */ -# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" -# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" -# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" -# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" -# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" -# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" - -# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" -# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" -# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" -# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" -# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" -# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" - -/* SEED ciphersuites from RFC4162 */ -# define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" -# define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" -# define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" -# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" -# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" -# define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" - -/* TLS v1.2 ciphersuites */ -# define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" -# define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" -# define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" -# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" -# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" -# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" -# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" -# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" -# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" -# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" -# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" -# define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" -# define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" - -/* TLS v1.2 GCM ciphersuites from RFC5288 */ -# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" -# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" -# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" -# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" -# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" -# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" -# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" -# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" -# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" -# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" -# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" -# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" - -/* ECDH HMAC based ciphersuites from RFC5289 */ - -# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" -# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" -# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" -# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" -# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" -# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" -# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" -# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" - -/* ECDH GCM based ciphersuites from RFC5289 */ -# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" -# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" -# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" -# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" -# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" -# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" -# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" -# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" - -# define TLS_CT_RSA_SIGN 1 -# define TLS_CT_DSS_SIGN 2 -# define TLS_CT_RSA_FIXED_DH 3 -# define TLS_CT_DSS_FIXED_DH 4 -# define TLS_CT_ECDSA_SIGN 64 -# define TLS_CT_RSA_FIXED_ECDH 65 -# define TLS_CT_ECDSA_FIXED_ECDH 66 -# define TLS_CT_GOST94_SIGN 21 -# define TLS_CT_GOST01_SIGN 22 -/* - * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see - * comment there) - */ -# define TLS_CT_NUMBER 9 - -# define TLS1_FINISH_MAC_LENGTH 12 - -# define TLS_MD_MAX_CONST_SIZE 20 -# define TLS_MD_CLIENT_FINISH_CONST "client finished" -# define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 -# define TLS_MD_SERVER_FINISH_CONST "server finished" -# define TLS_MD_SERVER_FINISH_CONST_SIZE 15 -# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" -# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 -# define TLS_MD_KEY_EXPANSION_CONST "key expansion" -# define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 -# define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" -# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 -# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" -# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 -# define TLS_MD_IV_BLOCK_CONST "IV block" -# define TLS_MD_IV_BLOCK_CONST_SIZE 8 -# define TLS_MD_MASTER_SECRET_CONST "master secret" -# define TLS_MD_MASTER_SECRET_CONST_SIZE 13 - -# ifdef CHARSET_EBCDIC -# undef TLS_MD_CLIENT_FINISH_CONST -/* - * client finished - */ -# define TLS_MD_CLIENT_FINISH_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64" - -# undef TLS_MD_SERVER_FINISH_CONST -/* - * server finished - */ -# define TLS_MD_SERVER_FINISH_CONST "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64" - -# undef TLS_MD_SERVER_WRITE_KEY_CONST -/* - * server write key - */ -# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" - -# undef TLS_MD_KEY_EXPANSION_CONST -/* - * key expansion - */ -# define TLS_MD_KEY_EXPANSION_CONST "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e" - -# undef TLS_MD_CLIENT_WRITE_KEY_CONST -/* - * client write key - */ -# define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" - -# undef TLS_MD_SERVER_WRITE_KEY_CONST -/* - * server write key - */ -# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" - -# undef TLS_MD_IV_BLOCK_CONST -/* - * IV block - */ -# define TLS_MD_IV_BLOCK_CONST "\x49\x56\x20\x62\x6c\x6f\x63\x6b" - -# undef TLS_MD_MASTER_SECRET_CONST -/* - * master secret - */ -# define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" -# endif - -/* TLS Session Ticket extension struct */ -struct tls_session_ticket_ext_st { - unsigned short length; - void *data; -}; - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/tls_srp.c b/Sources/COpenSSL/tls_srp.c deleted file mode 100644 index 09b8f370..00000000 --- a/Sources/COpenSSL/tls_srp.c +++ /dev/null @@ -1,543 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* ssl/tls_srp.c */ -/* - * Written by Christophe Renou (christophe.renou@edelweb.fr) with the - * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the - * EdelKey project and contributed to the OpenSSL project 2004. - */ -/* ==================================================================== - * Copyright (c) 2004-2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#include "ssl_locl.h" -#ifndef OPENSSL_NO_SRP - -# include "rand.h" -# include "srp.h" -# include "err.h" - -int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) -{ - if (ctx == NULL) - return 0; - OPENSSL_free(ctx->srp_ctx.login); - BN_free(ctx->srp_ctx.N); - BN_free(ctx->srp_ctx.g); - BN_free(ctx->srp_ctx.s); - BN_free(ctx->srp_ctx.B); - BN_free(ctx->srp_ctx.A); - BN_free(ctx->srp_ctx.a); - BN_free(ctx->srp_ctx.b); - BN_free(ctx->srp_ctx.v); - ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; - ctx->srp_ctx.SRP_cb_arg = NULL; - ctx->srp_ctx.SRP_verify_param_callback = NULL; - ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; - ctx->srp_ctx.N = NULL; - ctx->srp_ctx.g = NULL; - ctx->srp_ctx.s = NULL; - ctx->srp_ctx.B = NULL; - ctx->srp_ctx.A = NULL; - ctx->srp_ctx.a = NULL; - ctx->srp_ctx.b = NULL; - ctx->srp_ctx.v = NULL; - ctx->srp_ctx.login = NULL; - ctx->srp_ctx.info = NULL; - ctx->srp_ctx.strength = SRP_MINIMAL_N; - ctx->srp_ctx.srp_Mask = 0; - return (1); -} - -int SSL_SRP_CTX_free(struct ssl_st *s) -{ - if (s == NULL) - return 0; - OPENSSL_free(s->srp_ctx.login); - BN_free(s->srp_ctx.N); - BN_free(s->srp_ctx.g); - BN_free(s->srp_ctx.s); - BN_free(s->srp_ctx.B); - BN_free(s->srp_ctx.A); - BN_free(s->srp_ctx.a); - BN_free(s->srp_ctx.b); - BN_free(s->srp_ctx.v); - s->srp_ctx.TLS_ext_srp_username_callback = NULL; - s->srp_ctx.SRP_cb_arg = NULL; - s->srp_ctx.SRP_verify_param_callback = NULL; - s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; - s->srp_ctx.N = NULL; - s->srp_ctx.g = NULL; - s->srp_ctx.s = NULL; - s->srp_ctx.B = NULL; - s->srp_ctx.A = NULL; - s->srp_ctx.a = NULL; - s->srp_ctx.b = NULL; - s->srp_ctx.v = NULL; - s->srp_ctx.login = NULL; - s->srp_ctx.info = NULL; - s->srp_ctx.strength = SRP_MINIMAL_N; - s->srp_ctx.srp_Mask = 0; - return (1); -} - -int SSL_SRP_CTX_init(struct ssl_st *s) -{ - SSL_CTX *ctx; - - if ((s == NULL) || ((ctx = s->ctx) == NULL)) - return 0; - s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg; - /* set client Hello login callback */ - s->srp_ctx.TLS_ext_srp_username_callback = - ctx->srp_ctx.TLS_ext_srp_username_callback; - /* set SRP N/g param callback for verification */ - s->srp_ctx.SRP_verify_param_callback = - ctx->srp_ctx.SRP_verify_param_callback; - /* set SRP client passwd callback */ - s->srp_ctx.SRP_give_srp_client_pwd_callback = - ctx->srp_ctx.SRP_give_srp_client_pwd_callback; - - s->srp_ctx.N = NULL; - s->srp_ctx.g = NULL; - s->srp_ctx.s = NULL; - s->srp_ctx.B = NULL; - s->srp_ctx.A = NULL; - s->srp_ctx.a = NULL; - s->srp_ctx.b = NULL; - s->srp_ctx.v = NULL; - s->srp_ctx.login = NULL; - s->srp_ctx.info = ctx->srp_ctx.info; - s->srp_ctx.strength = ctx->srp_ctx.strength; - - if (((ctx->srp_ctx.N != NULL) && - ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) || - ((ctx->srp_ctx.g != NULL) && - ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) || - ((ctx->srp_ctx.s != NULL) && - ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) || - ((ctx->srp_ctx.B != NULL) && - ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) || - ((ctx->srp_ctx.A != NULL) && - ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) || - ((ctx->srp_ctx.a != NULL) && - ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) || - ((ctx->srp_ctx.v != NULL) && - ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || - ((ctx->srp_ctx.b != NULL) && - ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) { - SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB); - goto err; - } - if ((ctx->srp_ctx.login != NULL) && - ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL)) { - SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR); - goto err; - } - s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; - - return (1); - err: - OPENSSL_free(s->srp_ctx.login); - BN_free(s->srp_ctx.N); - BN_free(s->srp_ctx.g); - BN_free(s->srp_ctx.s); - BN_free(s->srp_ctx.B); - BN_free(s->srp_ctx.A); - BN_free(s->srp_ctx.a); - BN_free(s->srp_ctx.b); - BN_free(s->srp_ctx.v); - return (0); -} - -int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) -{ - if (ctx == NULL) - return 0; - - ctx->srp_ctx.SRP_cb_arg = NULL; - /* set client Hello login callback */ - ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; - /* set SRP N/g param callback for verification */ - ctx->srp_ctx.SRP_verify_param_callback = NULL; - /* set SRP client passwd callback */ - ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; - - ctx->srp_ctx.N = NULL; - ctx->srp_ctx.g = NULL; - ctx->srp_ctx.s = NULL; - ctx->srp_ctx.B = NULL; - ctx->srp_ctx.A = NULL; - ctx->srp_ctx.a = NULL; - ctx->srp_ctx.b = NULL; - ctx->srp_ctx.v = NULL; - ctx->srp_ctx.login = NULL; - ctx->srp_ctx.srp_Mask = 0; - ctx->srp_ctx.info = NULL; - ctx->srp_ctx.strength = SRP_MINIMAL_N; - - return (1); -} - -/* server side */ -int SSL_srp_server_param_with_username(SSL *s, int *ad) -{ - unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; - int al; - - *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; - if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && - ((al = - s->srp_ctx.TLS_ext_srp_username_callback(s, ad, - s->srp_ctx.SRP_cb_arg)) != - SSL_ERROR_NONE)) - return al; - - *ad = SSL_AD_INTERNAL_ERROR; - if ((s->srp_ctx.N == NULL) || - (s->srp_ctx.g == NULL) || - (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) - return SSL3_AL_FATAL; - - if (RAND_bytes(b, sizeof(b)) <= 0) - return SSL3_AL_FATAL; - s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); - OPENSSL_cleanse(b, sizeof(b)); - - /* Calculate: B = (kv + g^b) % N */ - - return ((s->srp_ctx.B = - SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, - s->srp_ctx.v)) != - NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL; -} - -/* - * If the server just has the raw password, make up a verifier entry on the - * fly - */ -int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, - const char *grp) -{ - SRP_gN *GN = SRP_get_default_gN(grp); - if (GN == NULL) - return -1; - s->srp_ctx.N = BN_dup(GN->N); - s->srp_ctx.g = BN_dup(GN->g); - if (s->srp_ctx.v != NULL) { - BN_clear_free(s->srp_ctx.v); - s->srp_ctx.v = NULL; - } - if (s->srp_ctx.s != NULL) { - BN_clear_free(s->srp_ctx.s); - s->srp_ctx.s = NULL; - } - if (!SRP_create_verifier_BN - (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) - return -1; - - return 1; -} - -int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, - BIGNUM *sa, BIGNUM *v, char *info) -{ - if (N != NULL) { - if (s->srp_ctx.N != NULL) { - if (!BN_copy(s->srp_ctx.N, N)) { - BN_free(s->srp_ctx.N); - s->srp_ctx.N = NULL; - } - } else - s->srp_ctx.N = BN_dup(N); - } - if (g != NULL) { - if (s->srp_ctx.g != NULL) { - if (!BN_copy(s->srp_ctx.g, g)) { - BN_free(s->srp_ctx.g); - s->srp_ctx.g = NULL; - } - } else - s->srp_ctx.g = BN_dup(g); - } - if (sa != NULL) { - if (s->srp_ctx.s != NULL) { - if (!BN_copy(s->srp_ctx.s, sa)) { - BN_free(s->srp_ctx.s); - s->srp_ctx.s = NULL; - } - } else - s->srp_ctx.s = BN_dup(sa); - } - if (v != NULL) { - if (s->srp_ctx.v != NULL) { - if (!BN_copy(s->srp_ctx.v, v)) { - BN_free(s->srp_ctx.v); - s->srp_ctx.v = NULL; - } - } else - s->srp_ctx.v = BN_dup(v); - } - s->srp_ctx.info = info; - - if (!(s->srp_ctx.N) || - !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v)) - return -1; - - return 1; -} - -int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key) -{ - BIGNUM *K = NULL, *u = NULL; - int ret = -1, tmp_len; - unsigned char *tmp = NULL; - - if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) - goto err; - if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) - goto err; - if (! - (K = - SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, - s->srp_ctx.N))) - goto err; - - tmp_len = BN_num_bytes(K); - if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) - goto err; - BN_bn2bin(K, tmp); - ret = - s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, - tmp_len); - err: - if (tmp) { - OPENSSL_cleanse(tmp, tmp_len); - OPENSSL_free(tmp); - } - BN_clear_free(K); - BN_clear_free(u); - return ret; -} - -/* client side */ -int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key) -{ - BIGNUM *x = NULL, *u = NULL, *K = NULL; - int ret = -1, tmp_len; - char *passwd = NULL; - unsigned char *tmp = NULL; - - /* - * Checks if b % n == 0 - */ - if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0) - goto err; - if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) - goto err; - if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) - goto err; - if (! - (passwd = - s->srp_ctx.SRP_give_srp_client_pwd_callback(s, - s->srp_ctx.SRP_cb_arg))) - goto err; - if (!(x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd))) - goto err; - if (! - (K = - SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, - s->srp_ctx.a, u))) - goto err; - - tmp_len = BN_num_bytes(K); - if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) - goto err; - BN_bn2bin(K, tmp); - ret = - s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, - tmp_len); - err: - if (tmp) { - OPENSSL_cleanse(tmp, tmp_len); - OPENSSL_free(tmp); - } - BN_clear_free(K); - BN_clear_free(x); - if (passwd) { - OPENSSL_cleanse(passwd, strlen(passwd)); - OPENSSL_free(passwd); - } - BN_clear_free(u); - return ret; -} - -int srp_verify_server_param(SSL *s, int *al) -{ - SRP_CTX *srp = &s->srp_ctx; - /* - * Sanity check parameters: we can quickly check B % N == 0 by checking B - * != 0 since B < N - */ - if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0 - || BN_is_zero(srp->B)) { - *al = SSL3_AD_ILLEGAL_PARAMETER; - return 0; - } - - if (BN_num_bits(srp->N) < srp->strength) { - *al = TLS1_AD_INSUFFICIENT_SECURITY; - return 0; - } - - if (srp->SRP_verify_param_callback) { - if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) { - *al = TLS1_AD_INSUFFICIENT_SECURITY; - return 0; - } - } else if (!SRP_check_known_gN_param(srp->g, srp->N)) { - *al = TLS1_AD_INSUFFICIENT_SECURITY; - return 0; - } - - return 1; -} - -int SRP_Calc_A_param(SSL *s) -{ - unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; - - if (RAND_bytes(rnd, sizeof(rnd)) <= 0) - return -1; - s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); - OPENSSL_cleanse(rnd, sizeof(rnd)); - - if (! - (s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g))) - return -1; - - return 1; -} - -BIGNUM *SSL_get_srp_g(SSL *s) -{ - if (s->srp_ctx.g != NULL) - return s->srp_ctx.g; - return s->ctx->srp_ctx.g; -} - -BIGNUM *SSL_get_srp_N(SSL *s) -{ - if (s->srp_ctx.N != NULL) - return s->srp_ctx.N; - return s->ctx->srp_ctx.N; -} - -char *SSL_get_srp_username(SSL *s) -{ - if (s->srp_ctx.login != NULL) - return s->srp_ctx.login; - return s->ctx->srp_ctx.login; -} - -char *SSL_get_srp_userinfo(SSL *s) -{ - if (s->srp_ctx.info != NULL) - return s->srp_ctx.info; - return s->ctx->srp_ctx.info; -} - -# define tls1_ctx_ctrl ssl3_ctx_ctrl -# define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl - -int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name) -{ - return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name); -} - -int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password) -{ - return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password); -} - -int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength) -{ - return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength, - NULL); -} - -int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, - int (*cb) (SSL *, void *)) -{ - return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB, - (void (*)(void))cb); -} - -int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg) -{ - return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg); -} - -int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, - int (*cb) (SSL *, int *, void *)) -{ - return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB, - (void (*)(void))cb); -} - -int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, - char *(*cb) (SSL *, void *)) -{ - return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB, - (void (*)(void))cb); -} - -#endif diff --git a/Sources/COpenSSL/ts.h b/Sources/COpenSSL/ts.h deleted file mode 100644 index f31fab7d..00000000 --- a/Sources/COpenSSL/ts.h +++ /dev/null @@ -1,865 +0,0 @@ -/* crypto/ts/ts.h */ -/* - * Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL project - * 2002, 2003, 2004. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_TS_H -# define HEADER_TS_H - -# include "opensslconf.h" -# include "symhacks.h" -# ifndef OPENSSL_NO_BUFFER -# include "buffer.h" -# endif -# ifndef OPENSSL_NO_EVP -# include "evp.h" -# endif -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# include "stack.h" -# include "asn1.h" -# include "safestack.h" - -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif - -# ifndef OPENSSL_NO_DSA -# include "dsa.h" -# endif - -# ifndef OPENSSL_NO_DH -# include "dh.h" -# endif - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef WIN32 -/* Under Win32 this is defined in wincrypt.h */ -# undef X509_NAME -# endif - -# include "x509.h" -# include "x509v3.h" - -/*- -MessageImprint ::= SEQUENCE { - hashAlgorithm AlgorithmIdentifier, - hashedMessage OCTET STRING } -*/ - -typedef struct TS_msg_imprint_st { - X509_ALGOR *hash_algo; - ASN1_OCTET_STRING *hashed_msg; -} TS_MSG_IMPRINT; - -/*- -TimeStampReq ::= SEQUENCE { - version INTEGER { v1(1) }, - messageImprint MessageImprint, - --a hash algorithm OID and the hash value of the data to be - --time-stamped - reqPolicy TSAPolicyId OPTIONAL, - nonce INTEGER OPTIONAL, - certReq BOOLEAN DEFAULT FALSE, - extensions [0] IMPLICIT Extensions OPTIONAL } -*/ - -typedef struct TS_req_st { - ASN1_INTEGER *version; - TS_MSG_IMPRINT *msg_imprint; - ASN1_OBJECT *policy_id; /* OPTIONAL */ - ASN1_INTEGER *nonce; /* OPTIONAL */ - ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */ - STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ -} TS_REQ; - -/*- -Accuracy ::= SEQUENCE { - seconds INTEGER OPTIONAL, - millis [0] INTEGER (1..999) OPTIONAL, - micros [1] INTEGER (1..999) OPTIONAL } -*/ - -typedef struct TS_accuracy_st { - ASN1_INTEGER *seconds; - ASN1_INTEGER *millis; - ASN1_INTEGER *micros; -} TS_ACCURACY; - -/*- -TSTInfo ::= SEQUENCE { - version INTEGER { v1(1) }, - policy TSAPolicyId, - messageImprint MessageImprint, - -- MUST have the same value as the similar field in - -- TimeStampReq - serialNumber INTEGER, - -- Time-Stamping users MUST be ready to accommodate integers - -- up to 160 bits. - genTime GeneralizedTime, - accuracy Accuracy OPTIONAL, - ordering BOOLEAN DEFAULT FALSE, - nonce INTEGER OPTIONAL, - -- MUST be present if the similar field was present - -- in TimeStampReq. In that case it MUST have the same value. - tsa [0] GeneralName OPTIONAL, - extensions [1] IMPLICIT Extensions OPTIONAL } -*/ - -typedef struct TS_tst_info_st { - ASN1_INTEGER *version; - ASN1_OBJECT *policy_id; - TS_MSG_IMPRINT *msg_imprint; - ASN1_INTEGER *serial; - ASN1_GENERALIZEDTIME *time; - TS_ACCURACY *accuracy; - ASN1_BOOLEAN ordering; - ASN1_INTEGER *nonce; - GENERAL_NAME *tsa; - STACK_OF(X509_EXTENSION) *extensions; -} TS_TST_INFO; - -/*- -PKIStatusInfo ::= SEQUENCE { - status PKIStatus, - statusString PKIFreeText OPTIONAL, - failInfo PKIFailureInfo OPTIONAL } - -From RFC 1510 - section 3.1.1: -PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String - -- text encoded as UTF-8 String (note: each UTF8String SHOULD - -- include an RFC 1766 language tag to indicate the language - -- of the contained text) -*/ - -/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */ - -# define TS_STATUS_GRANTED 0 -# define TS_STATUS_GRANTED_WITH_MODS 1 -# define TS_STATUS_REJECTION 2 -# define TS_STATUS_WAITING 3 -# define TS_STATUS_REVOCATION_WARNING 4 -# define TS_STATUS_REVOCATION_NOTIFICATION 5 - -/* - * Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c - */ - -# define TS_INFO_BAD_ALG 0 -# define TS_INFO_BAD_REQUEST 2 -# define TS_INFO_BAD_DATA_FORMAT 5 -# define TS_INFO_TIME_NOT_AVAILABLE 14 -# define TS_INFO_UNACCEPTED_POLICY 15 -# define TS_INFO_UNACCEPTED_EXTENSION 16 -# define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 -# define TS_INFO_SYSTEM_FAILURE 25 - -typedef struct TS_status_info_st { - ASN1_INTEGER *status; - STACK_OF(ASN1_UTF8STRING) *text; - ASN1_BIT_STRING *failure_info; -} TS_STATUS_INFO; - -DECLARE_STACK_OF(ASN1_UTF8STRING) -DECLARE_ASN1_SET_OF(ASN1_UTF8STRING) - -/*- -TimeStampResp ::= SEQUENCE { - status PKIStatusInfo, - timeStampToken TimeStampToken OPTIONAL } -*/ - -typedef struct TS_resp_st { - TS_STATUS_INFO *status_info; - PKCS7 *token; - TS_TST_INFO *tst_info; -} TS_RESP; - -/* The structure below would belong to the ESS component. */ - -/*- -IssuerSerial ::= SEQUENCE { - issuer GeneralNames, - serialNumber CertificateSerialNumber - } -*/ - -typedef struct ESS_issuer_serial { - STACK_OF(GENERAL_NAME) *issuer; - ASN1_INTEGER *serial; -} ESS_ISSUER_SERIAL; - -/*- -ESSCertID ::= SEQUENCE { - certHash Hash, - issuerSerial IssuerSerial OPTIONAL -} -*/ - -typedef struct ESS_cert_id { - ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ - ESS_ISSUER_SERIAL *issuer_serial; -} ESS_CERT_ID; - -DECLARE_STACK_OF(ESS_CERT_ID) -DECLARE_ASN1_SET_OF(ESS_CERT_ID) - -/*- -SigningCertificate ::= SEQUENCE { - certs SEQUENCE OF ESSCertID, - policies SEQUENCE OF PolicyInformation OPTIONAL -} -*/ - -typedef struct ESS_signing_cert { - STACK_OF(ESS_CERT_ID) *cert_ids; - STACK_OF(POLICYINFO) *policy_info; -} ESS_SIGNING_CERT; - -TS_REQ *TS_REQ_new(void); -void TS_REQ_free(TS_REQ *a); -int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); -TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); - -TS_REQ *TS_REQ_dup(TS_REQ *a); - -TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); -int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); -TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); -int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); - -TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); -void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); -int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); -TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, - const unsigned char **pp, long length); - -TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); - -TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); -int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); -TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); -int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); - -TS_RESP *TS_RESP_new(void); -void TS_RESP_free(TS_RESP *a); -int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); -TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); -TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); -TS_RESP *TS_RESP_dup(TS_RESP *a); - -TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); -int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); -TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); -int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); - -TS_STATUS_INFO *TS_STATUS_INFO_new(void); -void TS_STATUS_INFO_free(TS_STATUS_INFO *a); -int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); -TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, - const unsigned char **pp, long length); -TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); - -TS_TST_INFO *TS_TST_INFO_new(void); -void TS_TST_INFO_free(TS_TST_INFO *a); -int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); -TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, - long length); -TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); - -TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); -int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); -TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); -int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); - -TS_ACCURACY *TS_ACCURACY_new(void); -void TS_ACCURACY_free(TS_ACCURACY *a); -int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); -TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, - long length); -TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); - -ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); -void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); -int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp); -ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, - const unsigned char **pp, - long length); -ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); - -ESS_CERT_ID *ESS_CERT_ID_new(void); -void ESS_CERT_ID_free(ESS_CERT_ID *a); -int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); -ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, - long length); -ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); - -ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); -void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); -int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp); -ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, - const unsigned char **pp, long length); -ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); - -void ERR_load_TS_strings(void); - -int TS_REQ_set_version(TS_REQ *a, long version); -long TS_REQ_get_version(const TS_REQ *a); - -int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); -TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); - -int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); -X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); - -int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); -ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); - -int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy); -ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); - -int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); -const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); - -int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); -int TS_REQ_get_cert_req(const TS_REQ *a); - -STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); -void TS_REQ_ext_free(TS_REQ *a); -int TS_REQ_get_ext_count(TS_REQ *a); -int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); -int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos); -int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); -X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); -X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); -int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); -void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); - -/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ - -int TS_REQ_print_bio(BIO *bio, TS_REQ *a); - -/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ - -int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); -TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); - -/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ -void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); -PKCS7 *TS_RESP_get_token(TS_RESP *a); -TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); - -int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); -long TS_TST_INFO_get_version(const TS_TST_INFO *a); - -int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); -ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); - -int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); -TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); - -int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); -const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); - -int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); -const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); - -int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); -TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); - -int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); -const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); - -int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); -const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); - -int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); -const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); - -int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); -int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); - -int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); -const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); - -int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); -GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); - -STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); -void TS_TST_INFO_ext_free(TS_TST_INFO *a); -int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); -int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); -int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos); -int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); -X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); -X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); -int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); -void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); - -/* - * Declarations related to response generation, defined in ts/ts_resp_sign.c. - */ - -/* Optional flags for response generation. */ - -/* Don't include the TSA name in response. */ -# define TS_TSA_NAME 0x01 - -/* Set ordering to true in response. */ -# define TS_ORDERING 0x02 - -/* - * Include the signer certificate and the other specified certificates in - * the ESS signing certificate attribute beside the PKCS7 signed data. - * Only the signer certificates is included by default. - */ -# define TS_ESS_CERT_ID_CHAIN 0x04 - -/* Forward declaration. */ -struct TS_resp_ctx; - -/* This must return a unique number less than 160 bits long. */ -typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *); - -/* - * This must return the seconds and microseconds since Jan 1, 1970 in the sec - * and usec variables allocated by the caller. Return non-zero for success - * and zero for failure. - */ -typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec, - long *usec); - -/* - * This must process the given extension. It can modify the TS_TST_INFO - * object of the context. Return values: !0 (processed), 0 (error, it must - * set the status info/failure info of the response). - */ -typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *, - void *); - -typedef struct TS_resp_ctx { - X509 *signer_cert; - EVP_PKEY *signer_key; - STACK_OF(X509) *certs; /* Certs to include in signed data. */ - STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ - ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ - STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */ - ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */ - ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */ - ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */ - unsigned clock_precision_digits; /* fraction of seconds in time stamp - * token. */ - unsigned flags; /* Optional info, see values above. */ - /* Callback functions. */ - TS_serial_cb serial_cb; - void *serial_cb_data; /* User data for serial_cb. */ - TS_time_cb time_cb; - void *time_cb_data; /* User data for time_cb. */ - TS_extension_cb extension_cb; - void *extension_cb_data; /* User data for extension_cb. */ - /* These members are used only while creating the response. */ - TS_REQ *request; - TS_RESP *response; - TS_TST_INFO *tst_info; -} TS_RESP_CTX; - -DECLARE_STACK_OF(EVP_MD) -DECLARE_ASN1_SET_OF(EVP_MD) - -/* Creates a response context that can be used for generating responses. */ -TS_RESP_CTX *TS_RESP_CTX_new(void); -void TS_RESP_CTX_free(TS_RESP_CTX *ctx); - -/* This parameter must be set. */ -int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); - -/* This parameter must be set. */ -int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); - -/* This parameter must be set. */ -int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy); - -/* No additional certs are included in the response by default. */ -int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); - -/* - * Adds a new acceptable policy, only the default policy is accepted by - * default. - */ -int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy); - -/* - * Adds a new acceptable message digest. Note that no message digests are - * accepted by default. The md argument is shared with the caller. - */ -int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); - -/* Accuracy is not included by default. */ -int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, - int secs, int millis, int micros); - -/* - * Clock precision digits, i.e. the number of decimal digits: '0' means sec, - * '3' msec, '6' usec, and so on. Default is 0. - */ -int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, - unsigned clock_precision_digits); -/* At most we accept usec precision. */ -# define TS_MAX_CLOCK_PRECISION_DIGITS 6 - -/* Maximum status message length */ -# define TS_MAX_STATUS_LENGTH (1024 * 1024) - -/* No flags are set by default. */ -void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); - -/* Default callback always returns a constant. */ -void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); - -/* Default callback uses the gettimeofday() and gmtime() system calls. */ -void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); - -/* - * Default callback rejects all extensions. The extension callback is called - * when the TS_TST_INFO object is already set up and not signed yet. - */ -/* FIXME: extension handling is not tested yet. */ -void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, - TS_extension_cb cb, void *data); - -/* The following methods can be used in the callbacks. */ -int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, - int status, const char *text); - -/* Sets the status info only if it is still TS_STATUS_GRANTED. */ -int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, - int status, const char *text); - -int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); - -/* The get methods below can be used in the extension callback. */ -TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); - -TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); - -/* - * Creates the signed TS_TST_INFO and puts it in TS_RESP. - * In case of errors it sets the status info properly. - * Returns NULL only in case of memory allocation/fatal error. - */ -TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); - -/* - * Declarations related to response verification, - * they are defined in ts/ts_resp_verify.c. - */ - -int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, - X509_STORE *store, X509 **signer_out); - -/* Context structure for the generic verify method. */ - -/* Verify the signer's certificate and the signature of the response. */ -# define TS_VFY_SIGNATURE (1u << 0) -/* Verify the version number of the response. */ -# define TS_VFY_VERSION (1u << 1) -/* Verify if the policy supplied by the user matches the policy of the TSA. */ -# define TS_VFY_POLICY (1u << 2) -/* - * Verify the message imprint provided by the user. This flag should not be - * specified with TS_VFY_DATA. - */ -# define TS_VFY_IMPRINT (1u << 3) -/* - * Verify the message imprint computed by the verify method from the user - * provided data and the MD algorithm of the response. This flag should not - * be specified with TS_VFY_IMPRINT. - */ -# define TS_VFY_DATA (1u << 4) -/* Verify the nonce value. */ -# define TS_VFY_NONCE (1u << 5) -/* Verify if the TSA name field matches the signer certificate. */ -# define TS_VFY_SIGNER (1u << 6) -/* Verify if the TSA name field equals to the user provided name. */ -# define TS_VFY_TSA_NAME (1u << 7) - -/* You can use the following convenience constants. */ -# define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ - | TS_VFY_VERSION \ - | TS_VFY_POLICY \ - | TS_VFY_IMPRINT \ - | TS_VFY_NONCE \ - | TS_VFY_SIGNER \ - | TS_VFY_TSA_NAME) -# define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ - | TS_VFY_VERSION \ - | TS_VFY_POLICY \ - | TS_VFY_DATA \ - | TS_VFY_NONCE \ - | TS_VFY_SIGNER \ - | TS_VFY_TSA_NAME) - -typedef struct TS_verify_ctx { - /* Set this to the union of TS_VFY_... flags you want to carry out. */ - unsigned flags; - /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */ - X509_STORE *store; - STACK_OF(X509) *certs; - /* Must be set only with TS_VFY_POLICY. */ - ASN1_OBJECT *policy; - /* - * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the - * algorithm from the response is used. - */ - X509_ALGOR *md_alg; - unsigned char *imprint; - unsigned imprint_len; - /* Must be set only with TS_VFY_DATA. */ - BIO *data; - /* Must be set only with TS_VFY_TSA_NAME. */ - ASN1_INTEGER *nonce; - /* Must be set only with TS_VFY_TSA_NAME. */ - GENERAL_NAME *tsa_name; -} TS_VERIFY_CTX; - -int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); -int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); - -/* - * Declarations related to response verification context, - * they are defined in ts/ts_verify_ctx.c. - */ - -/* Set all fields to zero. */ -TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); -void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); -void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); -void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); - -/*- - * If ctx is NULL, it allocates and returns a new object, otherwise - * it returns ctx. It initialises all the members as follows: - * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) - * certs = NULL - * store = NULL - * policy = policy from the request or NULL if absent (in this case - * TS_VFY_POLICY is cleared from flags as well) - * md_alg = MD algorithm from request - * imprint, imprint_len = imprint from request - * data = NULL - * nonce, nonce_len = nonce from the request or NULL if absent (in this case - * TS_VFY_NONCE is cleared from flags as well) - * tsa_name = NULL - * Important: after calling this method TS_VFY_SIGNATURE should be added! - */ -TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); - -/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ - -int TS_RESP_print_bio(BIO *bio, TS_RESP *a); -int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); -int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); - -/* Common utility functions defined in ts/ts_lib.c */ - -int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); -int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); -int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); -int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); -int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); - -/* - * Function declarations for handling configuration options, defined in - * ts/ts_conf.c - */ - -X509 *TS_CONF_load_cert(const char *file); -STACK_OF(X509) *TS_CONF_load_certs(const char *file); -EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); -const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); -int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, - TS_RESP_CTX *ctx); -int TS_CONF_set_crypto_device(CONF *conf, const char *section, - const char *device); -int TS_CONF_set_default_engine(const char *name); -int TS_CONF_set_signer_cert(CONF *conf, const char *section, - const char *cert, TS_RESP_CTX *ctx); -int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, - TS_RESP_CTX *ctx); -int TS_CONF_set_signer_key(CONF *conf, const char *section, - const char *key, const char *pass, - TS_RESP_CTX *ctx); -int TS_CONF_set_def_policy(CONF *conf, const char *section, - const char *policy, TS_RESP_CTX *ctx); -int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); -int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); -int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); -int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, - TS_RESP_CTX *ctx); -int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); -int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); -int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, - TS_RESP_CTX *ctx); - -/* -------------------------------------------------- */ -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_TS_strings(void); - -/* Error codes for the TS functions. */ - -/* Function codes. */ -# define TS_F_D2I_TS_RESP 147 -# define TS_F_DEF_SERIAL_CB 110 -# define TS_F_DEF_TIME_CB 111 -# define TS_F_ESS_ADD_SIGNING_CERT 112 -# define TS_F_ESS_CERT_ID_NEW_INIT 113 -# define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 -# define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 -# define TS_F_PKCS7_TO_TS_TST_INFO 148 -# define TS_F_TS_ACCURACY_SET_MICROS 115 -# define TS_F_TS_ACCURACY_SET_MILLIS 116 -# define TS_F_TS_ACCURACY_SET_SECONDS 117 -# define TS_F_TS_CHECK_IMPRINTS 100 -# define TS_F_TS_CHECK_NONCES 101 -# define TS_F_TS_CHECK_POLICY 102 -# define TS_F_TS_CHECK_SIGNING_CERTS 103 -# define TS_F_TS_CHECK_STATUS_INFO 104 -# define TS_F_TS_COMPUTE_IMPRINT 145 -# define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 -# define TS_F_TS_GET_STATUS_TEXT 105 -# define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 -# define TS_F_TS_REQ_SET_MSG_IMPRINT 119 -# define TS_F_TS_REQ_SET_NONCE 120 -# define TS_F_TS_REQ_SET_POLICY_ID 121 -# define TS_F_TS_RESP_CREATE_RESPONSE 122 -# define TS_F_TS_RESP_CREATE_TST_INFO 123 -# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 -# define TS_F_TS_RESP_CTX_ADD_MD 125 -# define TS_F_TS_RESP_CTX_ADD_POLICY 126 -# define TS_F_TS_RESP_CTX_NEW 127 -# define TS_F_TS_RESP_CTX_SET_ACCURACY 128 -# define TS_F_TS_RESP_CTX_SET_CERTS 129 -# define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 -# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 -# define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 -# define TS_F_TS_RESP_GET_POLICY 133 -# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 -# define TS_F_TS_RESP_SET_STATUS_INFO 135 -# define TS_F_TS_RESP_SET_TST_INFO 150 -# define TS_F_TS_RESP_SIGN 136 -# define TS_F_TS_RESP_VERIFY_SIGNATURE 106 -# define TS_F_TS_RESP_VERIFY_TOKEN 107 -# define TS_F_TS_TST_INFO_SET_ACCURACY 137 -# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 -# define TS_F_TS_TST_INFO_SET_NONCE 139 -# define TS_F_TS_TST_INFO_SET_POLICY_ID 140 -# define TS_F_TS_TST_INFO_SET_SERIAL 141 -# define TS_F_TS_TST_INFO_SET_TIME 142 -# define TS_F_TS_TST_INFO_SET_TSA 143 -# define TS_F_TS_VERIFY 108 -# define TS_F_TS_VERIFY_CERT 109 -# define TS_F_TS_VERIFY_CTX_NEW 144 - -/* Reason codes. */ -# define TS_R_BAD_PKCS7_TYPE 132 -# define TS_R_BAD_TYPE 133 -# define TS_R_CERTIFICATE_VERIFY_ERROR 100 -# define TS_R_COULD_NOT_SET_ENGINE 127 -# define TS_R_COULD_NOT_SET_TIME 115 -# define TS_R_D2I_TS_RESP_INT_FAILED 128 -# define TS_R_DETACHED_CONTENT 134 -# define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 -# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 -# define TS_R_INVALID_NULL_POINTER 102 -# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 -# define TS_R_MESSAGE_IMPRINT_MISMATCH 103 -# define TS_R_NONCE_MISMATCH 104 -# define TS_R_NONCE_NOT_RETURNED 105 -# define TS_R_NO_CONTENT 106 -# define TS_R_NO_TIME_STAMP_TOKEN 107 -# define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 -# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 -# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 -# define TS_R_POLICY_MISMATCH 108 -# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 -# define TS_R_RESPONSE_SETUP_ERROR 121 -# define TS_R_SIGNATURE_FAILURE 109 -# define TS_R_THERE_MUST_BE_ONE_SIGNER 110 -# define TS_R_TIME_SYSCALL_ERROR 122 -# define TS_R_TOKEN_NOT_PRESENT 130 -# define TS_R_TOKEN_PRESENT 131 -# define TS_R_TSA_NAME_MISMATCH 111 -# define TS_R_TSA_UNTRUSTED 112 -# define TS_R_TST_INFO_SETUP_ERROR 123 -# define TS_R_TS_DATASIGN 124 -# define TS_R_UNACCEPTABLE_POLICY 125 -# define TS_R_UNSUPPORTED_MD_ALGORITHM 126 -# define TS_R_UNSUPPORTED_VERSION 113 -# define TS_R_WRONG_CONTENT_TYPE 114 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ts_.c b/Sources/COpenSSL/ts_.c deleted file mode 100644 index 118721c9..00000000 --- a/Sources/COpenSSL/ts_.c +++ /dev/null @@ -1,4091 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/ts/ts_asn1.c */ -/* - * Written by Nils Larsch for the OpenSSL project 2004. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "ts.h" -#include "err.h" -#include "asn1t.h" - -ASN1_SEQUENCE(TS_MSG_IMPRINT) = { - ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR), - ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(TS_MSG_IMPRINT) - -IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT) -IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT) -#ifndef OPENSSL_NO_BIO -TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a) -{ - return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, - d2i_TS_MSG_IMPRINT, bp, a); -} - -int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a) -{ - return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a); -} -#endif -#ifndef OPENSSL_NO_FP_API -TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a) -{ - return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, - d2i_TS_MSG_IMPRINT, fp, a); -} - -int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a) -{ - return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a); -} -#endif - -ASN1_SEQUENCE(TS_REQ) = { - ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER), - ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT), - ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT), - ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER), - ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN), - ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0) -} ASN1_SEQUENCE_END(TS_REQ) - -IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ) -IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ) -#ifndef OPENSSL_NO_BIO -TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a) -{ - return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a); -} - -int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a) -{ - return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a); -} -#endif -#ifndef OPENSSL_NO_FP_API -TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a) -{ - return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a); -} - -int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a) -{ - return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a); -} -#endif - -ASN1_SEQUENCE(TS_ACCURACY) = { - ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER), - ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0), - ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1) -} ASN1_SEQUENCE_END(TS_ACCURACY) - -IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY) -IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY) - -ASN1_SEQUENCE(TS_TST_INFO) = { - ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT), - ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT), - ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER), - ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME), - ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY), - ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN), - ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER), - ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0), - ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1) -} ASN1_SEQUENCE_END(TS_TST_INFO) - -IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO) -IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO) -#ifndef OPENSSL_NO_BIO -TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a) -{ - return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, - a); -} - -int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a) -{ - return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a); -} -#endif -#ifndef OPENSSL_NO_FP_API -TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a) -{ - return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, - a); -} - -int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a) -{ - return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a); -} -#endif - -ASN1_SEQUENCE(TS_STATUS_INFO) = { - ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER), - ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING), - ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END(TS_STATUS_INFO) - -IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO) -IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO) - -static int ts_resp_set_tst_info(TS_RESP *a) -{ - long status; - - status = ASN1_INTEGER_get(a->status_info->status); - - if (a->token) { - if (status != 0 && status != 1) { - TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT); - return 0; - } - if (a->tst_info != NULL) - TS_TST_INFO_free(a->tst_info); - a->tst_info = PKCS7_to_TS_TST_INFO(a->token); - if (!a->tst_info) { - TSerr(TS_F_TS_RESP_SET_TST_INFO, - TS_R_PKCS7_TO_TS_TST_INFO_FAILED); - return 0; - } - } else if (status == 0 || status == 1) { - TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT); - return 0; - } - - return 1; -} - -static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - TS_RESP *ts_resp = (TS_RESP *)*pval; - if (op == ASN1_OP_NEW_POST) { - ts_resp->tst_info = NULL; - } else if (op == ASN1_OP_FREE_POST) { - if (ts_resp->tst_info != NULL) - TS_TST_INFO_free(ts_resp->tst_info); - } else if (op == ASN1_OP_D2I_POST) { - if (ts_resp_set_tst_info(ts_resp) == 0) - return 0; - } - return 1; -} - -ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = { - ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO), - ASN1_OPT(TS_RESP, token, PKCS7), -} ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP) - -IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP) - -IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP) - -#ifndef OPENSSL_NO_BIO -TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a) -{ - return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a); -} - -int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a) -{ - return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a); -} -#endif -#ifndef OPENSSL_NO_FP_API -TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a) -{ - return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a); -} - -int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a) -{ - return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a); -} -#endif - -ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = { - ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME), - ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER) -} ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL) - -IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL) -IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL) - -ASN1_SEQUENCE(ESS_CERT_ID) = { - ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING), - ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL) -} ASN1_SEQUENCE_END(ESS_CERT_ID) - -IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID) -IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID) - -ASN1_SEQUENCE(ESS_SIGNING_CERT) = { - ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID), - ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO) -} ASN1_SEQUENCE_END(ESS_SIGNING_CERT) - -IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT) -IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT) - -/* Getting encapsulated TS_TST_INFO object from PKCS7. */ -TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) -{ - PKCS7_SIGNED *pkcs7_signed; - PKCS7 *enveloped; - ASN1_TYPE *tst_info_wrapper; - ASN1_OCTET_STRING *tst_info_der; - const unsigned char *p; - - if (!PKCS7_type_is_signed(token)) { - TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); - return NULL; - } - - /* Content must be present. */ - if (PKCS7_get_detached(token)) { - TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT); - return NULL; - } - - /* We have a signed data with content. */ - pkcs7_signed = token->d.sign; - enveloped = pkcs7_signed->contents; - if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) { - TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); - return NULL; - } - - /* We have a DER encoded TST_INFO as the signed data. */ - tst_info_wrapper = enveloped->d.other; - if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) { - TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE); - return NULL; - } - - /* We have the correct ASN1_OCTET_STRING type. */ - tst_info_der = tst_info_wrapper->value.octet_string; - /* At last, decode the TST_INFO. */ - p = tst_info_der->data; - return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length); -} -/* crypto/ts/ts_conf.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -#include "crypto.h" -#include "cryptlib.h" -#include "pem.h" -#ifndef OPENSSL_NO_ENGINE -# include "engine.h" -#endif -// #include "ts.h" - -/* Macro definitions for the configuration file. */ - -#define BASE_SECTION "tsa" -#define ENV_DEFAULT_TSA "default_tsa" -#define ENV_SERIAL "serial" -#define ENV_CRYPTO_DEVICE "crypto_device" -#define ENV_SIGNER_CERT "signer_cert" -#define ENV_CERTS "certs" -#define ENV_SIGNER_KEY "signer_key" -#define ENV_DEFAULT_POLICY "default_policy" -#define ENV_OTHER_POLICIES "other_policies" -#define ENV_DIGESTS "digests" -#define ENV_ACCURACY "accuracy" -#define ENV_ORDERING "ordering" -#define ENV_TSA_NAME "tsa_name" -#define ENV_ESS_CERT_ID_CHAIN "ess_cert_id_chain" -#define ENV_VALUE_SECS "secs" -#define ENV_VALUE_MILLISECS "millisecs" -#define ENV_VALUE_MICROSECS "microsecs" -#define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits" -#define ENV_VALUE_YES "yes" -#define ENV_VALUE_NO "no" - -/* Function definitions for certificate and key loading. */ - -X509 *TS_CONF_load_cert(const char *file) -{ - BIO *cert = NULL; - X509 *x = NULL; - - if ((cert = BIO_new_file(file, "r")) == NULL) - goto end; - x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); - end: - if (x == NULL) - fprintf(stderr, "unable to load certificate: %s\n", file); - BIO_free(cert); - return x; -} - -STACK_OF(X509) *TS_CONF_load_certs(const char *file) -{ - BIO *certs = NULL; - STACK_OF(X509) *othercerts = NULL; - STACK_OF(X509_INFO) *allcerts = NULL; - int i; - - if (!(certs = BIO_new_file(file, "r"))) - goto end; - - if (!(othercerts = sk_X509_new_null())) - goto end; - allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL); - for (i = 0; i < sk_X509_INFO_num(allcerts); i++) { - X509_INFO *xi = sk_X509_INFO_value(allcerts, i); - if (xi->x509) { - sk_X509_push(othercerts, xi->x509); - xi->x509 = NULL; - } - } - end: - if (othercerts == NULL) - fprintf(stderr, "unable to load certificates: %s\n", file); - sk_X509_INFO_pop_free(allcerts, X509_INFO_free); - BIO_free(certs); - return othercerts; -} - -EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass) -{ - BIO *key = NULL; - EVP_PKEY *pkey = NULL; - - if (!(key = BIO_new_file(file, "r"))) - goto end; - pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *)pass); - end: - if (pkey == NULL) - fprintf(stderr, "unable to load private key: %s\n", file); - BIO_free(key); - return pkey; -} - -/* Function definitions for handling configuration options. */ - -static void TS_CONF_lookup_fail(const char *name, const char *tag) -{ - fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag); -} - -static void TS_CONF_invalid(const char *name, const char *tag) -{ - fprintf(stderr, "invalid variable value for %s::%s\n", name, tag); -} - -const char *TS_CONF_get_tsa_section(CONF *conf, const char *section) -{ - if (!section) { - section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA); - if (!section) - TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA); - } - return section; -} - -int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, - TS_RESP_CTX *ctx) -{ - int ret = 0; - char *serial = NCONF_get_string(conf, section, ENV_SERIAL); - if (!serial) { - TS_CONF_lookup_fail(section, ENV_SERIAL); - goto err; - } - TS_RESP_CTX_set_serial_cb(ctx, cb, serial); - - ret = 1; - err: - return ret; -} - -#ifndef OPENSSL_NO_ENGINE - -int TS_CONF_set_crypto_device(CONF *conf, const char *section, - const char *device) -{ - int ret = 0; - - if (!device) - device = NCONF_get_string(conf, section, ENV_CRYPTO_DEVICE); - - if (device && !TS_CONF_set_default_engine(device)) { - TS_CONF_invalid(section, ENV_CRYPTO_DEVICE); - goto err; - } - ret = 1; - err: - return ret; -} - -int TS_CONF_set_default_engine(const char *name) -{ - ENGINE *e = NULL; - int ret = 0; - - /* Leave the default if builtin specified. */ - if (strcmp(name, "builtin") == 0) - return 1; - - if (!(e = ENGINE_by_id(name))) - goto err; - /* Enable the use of the NCipher HSM for forked children. */ - if (strcmp(name, "chil") == 0) - ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0); - /* All the operations are going to be carried out by the engine. */ - if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) - goto err; - ret = 1; - err: - if (!ret) { - TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, TS_R_COULD_NOT_SET_ENGINE); - ERR_add_error_data(2, "engine:", name); - } - if (e) - ENGINE_free(e); - return ret; -} - -#endif - -int TS_CONF_set_signer_cert(CONF *conf, const char *section, - const char *cert, TS_RESP_CTX *ctx) -{ - int ret = 0; - X509 *cert_obj = NULL; - if (!cert) - cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT); - if (!cert) { - TS_CONF_lookup_fail(section, ENV_SIGNER_CERT); - goto err; - } - if (!(cert_obj = TS_CONF_load_cert(cert))) - goto err; - if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj)) - goto err; - - ret = 1; - err: - X509_free(cert_obj); - return ret; -} - -int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, - TS_RESP_CTX *ctx) -{ - int ret = 0; - STACK_OF(X509) *certs_obj = NULL; - if (!certs) - certs = NCONF_get_string(conf, section, ENV_CERTS); - /* Certificate chain is optional. */ - if (!certs) - goto end; - if (!(certs_obj = TS_CONF_load_certs(certs))) - goto err; - if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) - goto err; - end: - ret = 1; - err: - sk_X509_pop_free(certs_obj, X509_free); - return ret; -} - -int TS_CONF_set_signer_key(CONF *conf, const char *section, - const char *key, const char *pass, - TS_RESP_CTX *ctx) -{ - int ret = 0; - EVP_PKEY *key_obj = NULL; - if (!key) - key = NCONF_get_string(conf, section, ENV_SIGNER_KEY); - if (!key) { - TS_CONF_lookup_fail(section, ENV_SIGNER_KEY); - goto err; - } - if (!(key_obj = TS_CONF_load_key(key, pass))) - goto err; - if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) - goto err; - - ret = 1; - err: - EVP_PKEY_free(key_obj); - return ret; -} - -int TS_CONF_set_def_policy(CONF *conf, const char *section, - const char *policy, TS_RESP_CTX *ctx) -{ - int ret = 0; - ASN1_OBJECT *policy_obj = NULL; - if (!policy) - policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY); - if (!policy) { - TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY); - goto err; - } - if (!(policy_obj = OBJ_txt2obj(policy, 0))) { - TS_CONF_invalid(section, ENV_DEFAULT_POLICY); - goto err; - } - if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj)) - goto err; - - ret = 1; - err: - ASN1_OBJECT_free(policy_obj); - return ret; -} - -int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx) -{ - int ret = 0; - int i; - STACK_OF(CONF_VALUE) *list = NULL; - char *policies = NCONF_get_string(conf, section, - ENV_OTHER_POLICIES); - /* If no other policy is specified, that's fine. */ - if (policies && !(list = X509V3_parse_list(policies))) { - TS_CONF_invalid(section, ENV_OTHER_POLICIES); - goto err; - } - for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { - CONF_VALUE *val = sk_CONF_VALUE_value(list, i); - const char *extval = val->value ? val->value : val->name; - ASN1_OBJECT *objtmp; - if (!(objtmp = OBJ_txt2obj(extval, 0))) { - TS_CONF_invalid(section, ENV_OTHER_POLICIES); - goto err; - } - if (!TS_RESP_CTX_add_policy(ctx, objtmp)) - goto err; - ASN1_OBJECT_free(objtmp); - } - - ret = 1; - err: - sk_CONF_VALUE_pop_free(list, X509V3_conf_free); - return ret; -} - -int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx) -{ - int ret = 0; - int i; - STACK_OF(CONF_VALUE) *list = NULL; - char *digests = NCONF_get_string(conf, section, ENV_DIGESTS); - if (!digests) { - TS_CONF_lookup_fail(section, ENV_DIGESTS); - goto err; - } - if (!(list = X509V3_parse_list(digests))) { - TS_CONF_invalid(section, ENV_DIGESTS); - goto err; - } - if (sk_CONF_VALUE_num(list) == 0) { - TS_CONF_invalid(section, ENV_DIGESTS); - goto err; - } - for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { - CONF_VALUE *val = sk_CONF_VALUE_value(list, i); - const char *extval = val->value ? val->value : val->name; - const EVP_MD *md; - if (!(md = EVP_get_digestbyname(extval))) { - TS_CONF_invalid(section, ENV_DIGESTS); - goto err; - } - if (!TS_RESP_CTX_add_md(ctx, md)) - goto err; - } - - ret = 1; - err: - sk_CONF_VALUE_pop_free(list, X509V3_conf_free); - return ret; -} - -int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) -{ - int ret = 0; - int i; - int secs = 0, millis = 0, micros = 0; - STACK_OF(CONF_VALUE) *list = NULL; - char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY); - - if (accuracy && !(list = X509V3_parse_list(accuracy))) { - TS_CONF_invalid(section, ENV_ACCURACY); - goto err; - } - for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { - CONF_VALUE *val = sk_CONF_VALUE_value(list, i); - if (strcmp(val->name, ENV_VALUE_SECS) == 0) { - if (val->value) - secs = atoi(val->value); - } else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) { - if (val->value) - millis = atoi(val->value); - } else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) { - if (val->value) - micros = atoi(val->value); - } else { - TS_CONF_invalid(section, ENV_ACCURACY); - goto err; - } - } - if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros)) - goto err; - - ret = 1; - err: - sk_CONF_VALUE_pop_free(list, X509V3_conf_free); - return ret; -} - -int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, - TS_RESP_CTX *ctx) -{ - int ret = 0; - long digits = 0; - - /* - * If not specified, set the default value to 0, i.e. sec precision - */ - if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS, - &digits)) - digits = 0; - if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) { - TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS); - goto err; - } - - if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits)) - goto err; - - return 1; - err: - return ret; -} - -static int TS_CONF_add_flag(CONF *conf, const char *section, - const char *field, int flag, TS_RESP_CTX *ctx) -{ - /* Default is false. */ - const char *value = NCONF_get_string(conf, section, field); - if (value) { - if (strcmp(value, ENV_VALUE_YES) == 0) - TS_RESP_CTX_add_flags(ctx, flag); - else if (strcmp(value, ENV_VALUE_NO) != 0) { - TS_CONF_invalid(section, field); - return 0; - } - } - - return 1; -} - -int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx) -{ - return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx); -} - -int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx) -{ - return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx); -} - -int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, - TS_RESP_CTX *ctx) -{ - return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, - TS_ESS_CERT_ID_CHAIN, ctx); -} -/* crypto/ts/ts_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -// #include "err.h" -// #include "ts.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason) - -static ERR_STRING_DATA TS_str_functs[] = { - {ERR_FUNC(TS_F_D2I_TS_RESP), "d2i_TS_RESP"}, - {ERR_FUNC(TS_F_DEF_SERIAL_CB), "DEF_SERIAL_CB"}, - {ERR_FUNC(TS_F_DEF_TIME_CB), "DEF_TIME_CB"}, - {ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_ADD_SIGNING_CERT"}, - {ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ESS_CERT_ID_NEW_INIT"}, - {ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ESS_SIGNING_CERT_NEW_INIT"}, - {ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "INT_TS_RESP_VERIFY_TOKEN"}, - {ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"}, - {ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"}, - {ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS), "TS_ACCURACY_set_millis"}, - {ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS), "TS_ACCURACY_set_seconds"}, - {ERR_FUNC(TS_F_TS_CHECK_IMPRINTS), "TS_CHECK_IMPRINTS"}, - {ERR_FUNC(TS_F_TS_CHECK_NONCES), "TS_CHECK_NONCES"}, - {ERR_FUNC(TS_F_TS_CHECK_POLICY), "TS_CHECK_POLICY"}, - {ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "TS_CHECK_SIGNING_CERTS"}, - {ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "TS_CHECK_STATUS_INFO"}, - {ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "TS_COMPUTE_IMPRINT"}, - {ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"}, - {ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "TS_GET_STATUS_TEXT"}, - {ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"}, - {ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT), "TS_REQ_set_msg_imprint"}, - {ERR_FUNC(TS_F_TS_REQ_SET_NONCE), "TS_REQ_set_nonce"}, - {ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID), "TS_REQ_set_policy_id"}, - {ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE), "TS_RESP_create_response"}, - {ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO), "TS_RESP_CREATE_TST_INFO"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO), - "TS_RESP_CTX_add_failure_info"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD), "TS_RESP_CTX_add_md"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY), "TS_RESP_CTX_add_policy"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_NEW), "TS_RESP_CTX_new"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY), "TS_RESP_CTX_set_accuracy"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS), "TS_RESP_CTX_set_certs"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY), "TS_RESP_CTX_set_def_policy"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT), - "TS_RESP_CTX_set_signer_cert"}, - {ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO), - "TS_RESP_CTX_set_status_info"}, - {ERR_FUNC(TS_F_TS_RESP_GET_POLICY), "TS_RESP_GET_POLICY"}, - {ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION), - "TS_RESP_SET_GENTIME_WITH_PRECISION"}, - {ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO), "TS_RESP_set_status_info"}, - {ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO), "TS_RESP_set_tst_info"}, - {ERR_FUNC(TS_F_TS_RESP_SIGN), "TS_RESP_SIGN"}, - {ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE), "TS_RESP_verify_signature"}, - {ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN), "TS_RESP_verify_token"}, - {ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY), "TS_TST_INFO_set_accuracy"}, - {ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT), - "TS_TST_INFO_set_msg_imprint"}, - {ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE), "TS_TST_INFO_set_nonce"}, - {ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID), "TS_TST_INFO_set_policy_id"}, - {ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL), "TS_TST_INFO_set_serial"}, - {ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME), "TS_TST_INFO_set_time"}, - {ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA), "TS_TST_INFO_set_tsa"}, - {ERR_FUNC(TS_F_TS_VERIFY), "TS_VERIFY"}, - {ERR_FUNC(TS_F_TS_VERIFY_CERT), "TS_VERIFY_CERT"}, - {ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW), "TS_VERIFY_CTX_new"}, - {0, NULL} -}; - -static ERR_STRING_DATA TS_str_reasons[] = { - {ERR_REASON(TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type"}, - {ERR_REASON(TS_R_BAD_TYPE), "bad type"}, - {ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, - {ERR_REASON(TS_R_COULD_NOT_SET_ENGINE), "could not set engine"}, - {ERR_REASON(TS_R_COULD_NOT_SET_TIME), "could not set time"}, - {ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED), "d2i ts resp int failed"}, - {ERR_REASON(TS_R_DETACHED_CONTENT), "detached content"}, - {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR), - "ess add signing cert error"}, - {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR), - "ess signing certificate error"}, - {ERR_REASON(TS_R_INVALID_NULL_POINTER), "invalid null pointer"}, - {ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE), - "invalid signer certificate purpose"}, - {ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH), "message imprint mismatch"}, - {ERR_REASON(TS_R_NONCE_MISMATCH), "nonce mismatch"}, - {ERR_REASON(TS_R_NONCE_NOT_RETURNED), "nonce not returned"}, - {ERR_REASON(TS_R_NO_CONTENT), "no content"}, - {ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN), "no time stamp token"}, - {ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"}, - {ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR), - "pkcs7 add signed attr error"}, - {ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED), - "pkcs7 to ts tst info failed"}, - {ERR_REASON(TS_R_POLICY_MISMATCH), "policy mismatch"}, - {ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), - "private key does not match certificate"}, - {ERR_REASON(TS_R_RESPONSE_SETUP_ERROR), "response setup error"}, - {ERR_REASON(TS_R_SIGNATURE_FAILURE), "signature failure"}, - {ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER), "there must be one signer"}, - {ERR_REASON(TS_R_TIME_SYSCALL_ERROR), "time syscall error"}, - {ERR_REASON(TS_R_TOKEN_NOT_PRESENT), "token not present"}, - {ERR_REASON(TS_R_TOKEN_PRESENT), "token present"}, - {ERR_REASON(TS_R_TSA_NAME_MISMATCH), "tsa name mismatch"}, - {ERR_REASON(TS_R_TSA_UNTRUSTED), "tsa untrusted"}, - {ERR_REASON(TS_R_TST_INFO_SETUP_ERROR), "tst info setup error"}, - {ERR_REASON(TS_R_TS_DATASIGN), "ts datasign"}, - {ERR_REASON(TS_R_UNACCEPTABLE_POLICY), "unacceptable policy"}, - {ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM), "unsupported md algorithm"}, - {ERR_REASON(TS_R_UNSUPPORTED_VERSION), "unsupported version"}, - {ERR_REASON(TS_R_WRONG_CONTENT_TYPE), "wrong content type"}, - {0, NULL} -}; - -#endif - -void ERR_load_TS_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(TS_str_functs[0].error) == NULL) { - ERR_load_strings(0, TS_str_functs); - ERR_load_strings(0, TS_str_reasons); - } -#endif -} -/* crypto/ts/ts_lib.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -#include "objects.h" -#include "bn.h" -#include "x509v3.h" -// #include "ts.h" - -/* Local function declarations. */ - -/* Function definitions. */ - -int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num) -{ - BIGNUM num_bn; - int result = 0; - char *hex; - - BN_init(&num_bn); - ASN1_INTEGER_to_BN(num, &num_bn); - if ((hex = BN_bn2hex(&num_bn))) { - result = BIO_write(bio, "0x", 2) > 0; - result = result && BIO_write(bio, hex, strlen(hex)) > 0; - OPENSSL_free(hex); - } - BN_free(&num_bn); - - return result; -} - -int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj) -{ - char obj_txt[128]; - - OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); - BIO_printf(bio, "%s\n", obj_txt); - - return 1; -} - -int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions) -{ - int i, critical, n; - X509_EXTENSION *ex; - ASN1_OBJECT *obj; - - BIO_printf(bio, "Extensions:\n"); - n = X509v3_get_ext_count(extensions); - for (i = 0; i < n; i++) { - ex = X509v3_get_ext(extensions, i); - obj = X509_EXTENSION_get_object(ex); - i2a_ASN1_OBJECT(bio, obj); - critical = X509_EXTENSION_get_critical(ex); - BIO_printf(bio, ": %s\n", critical ? "critical" : ""); - if (!X509V3_EXT_print(bio, ex, 0, 4)) { - BIO_printf(bio, "%4s", ""); - M_ASN1_OCTET_STRING_print(bio, ex->value); - } - BIO_write(bio, "\n", 1); - } - - return 1; -} - -int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg) -{ - int i = OBJ_obj2nid(alg->algorithm); - return BIO_printf(bio, "Hash Algorithm: %s\n", - (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); -} - -int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a) -{ - const ASN1_OCTET_STRING *msg; - - TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a)); - - BIO_printf(bio, "Message data:\n"); - msg = TS_MSG_IMPRINT_get_msg(a); - BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg), - M_ASN1_STRING_length(msg), 4); - - return 1; -} -/* crypto/ts/ts_req_print.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "bn.h" -// #include "x509v3.h" -// #include "ts.h" - -/* Function definitions. */ - -int TS_REQ_print_bio(BIO *bio, TS_REQ *a) -{ - int v; - ASN1_OBJECT *policy_id; - const ASN1_INTEGER *nonce; - - if (a == NULL) - return 0; - - v = TS_REQ_get_version(a); - BIO_printf(bio, "Version: %d\n", v); - - TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a)); - - BIO_printf(bio, "Policy OID: "); - policy_id = TS_REQ_get_policy_id(a); - if (policy_id == NULL) - BIO_printf(bio, "unspecified\n"); - else - TS_OBJ_print_bio(bio, policy_id); - - BIO_printf(bio, "Nonce: "); - nonce = TS_REQ_get_nonce(a); - if (nonce == NULL) - BIO_printf(bio, "unspecified"); - else - TS_ASN1_INTEGER_print_bio(bio, nonce); - BIO_write(bio, "\n", 1); - - BIO_printf(bio, "Certificate required: %s\n", - TS_REQ_get_cert_req(a) ? "yes" : "no"); - - TS_ext_print_bio(bio, TS_REQ_get_exts(a)); - - return 1; -} -/* crypto/ts/ts_req_utils.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "x509v3.h" -// #include "ts.h" - -int TS_REQ_set_version(TS_REQ *a, long version) -{ - return ASN1_INTEGER_set(a->version, version); -} - -long TS_REQ_get_version(const TS_REQ *a) -{ - return ASN1_INTEGER_get(a->version); -} - -int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint) -{ - TS_MSG_IMPRINT *new_msg_imprint; - - if (a->msg_imprint == msg_imprint) - return 1; - new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); - if (new_msg_imprint == NULL) { - TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); - return 0; - } - TS_MSG_IMPRINT_free(a->msg_imprint); - a->msg_imprint = new_msg_imprint; - return 1; -} - -TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a) -{ - return a->msg_imprint; -} - -int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg) -{ - X509_ALGOR *new_alg; - - if (a->hash_algo == alg) - return 1; - new_alg = X509_ALGOR_dup(alg); - if (new_alg == NULL) { - TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE); - return 0; - } - X509_ALGOR_free(a->hash_algo); - a->hash_algo = new_alg; - return 1; -} - -X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a) -{ - return a->hash_algo; -} - -int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len) -{ - return ASN1_OCTET_STRING_set(a->hashed_msg, d, len); -} - -ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a) -{ - return a->hashed_msg; -} - -int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy) -{ - ASN1_OBJECT *new_policy; - - if (a->policy_id == policy) - return 1; - new_policy = OBJ_dup(policy); - if (new_policy == NULL) { - TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); - return 0; - } - ASN1_OBJECT_free(a->policy_id); - a->policy_id = new_policy; - return 1; -} - -ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a) -{ - return a->policy_id; -} - -int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce) -{ - ASN1_INTEGER *new_nonce; - - if (a->nonce == nonce) - return 1; - new_nonce = ASN1_INTEGER_dup(nonce); - if (new_nonce == NULL) { - TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE); - return 0; - } - ASN1_INTEGER_free(a->nonce); - a->nonce = new_nonce; - return 1; -} - -const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a) -{ - return a->nonce; -} - -int TS_REQ_set_cert_req(TS_REQ *a, int cert_req) -{ - a->cert_req = cert_req ? 0xFF : 0x00; - return 1; -} - -int TS_REQ_get_cert_req(const TS_REQ *a) -{ - return a->cert_req ? 1 : 0; -} - -STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a) -{ - return a->extensions; -} - -void TS_REQ_ext_free(TS_REQ *a) -{ - if (!a) - return; - sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); - a->extensions = NULL; -} - -int TS_REQ_get_ext_count(TS_REQ *a) -{ - return X509v3_get_ext_count(a->extensions); -} - -int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos) -{ - return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); -} - -int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos) -{ - return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); -} - -int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos) -{ - return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); -} - -X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc) -{ - return X509v3_get_ext(a->extensions, loc); -} - -X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc) -{ - return X509v3_delete_ext(a->extensions, loc); -} - -int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc) -{ - return X509v3_add_ext(&a->extensions, ex, loc) != NULL; -} - -void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(a->extensions, nid, crit, idx); -} -/* crypto/ts/ts_resp_print.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "bn.h" -// #include "x509v3.h" -// #include "ts.h" - -struct status_map_st { - int bit; - const char *text; -}; - -/* Local function declarations. */ - -static int TS_status_map_print(BIO *bio, struct status_map_st *a, - ASN1_BIT_STRING *v); -static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy); - -/* Function definitions. */ - -int TS_RESP_print_bio(BIO *bio, TS_RESP *a) -{ - TS_TST_INFO *tst_info; - - BIO_printf(bio, "Status info:\n"); - TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a)); - - BIO_printf(bio, "\nTST info:\n"); - tst_info = TS_RESP_get_tst_info(a); - if (tst_info != NULL) - TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a)); - else - BIO_printf(bio, "Not included.\n"); - - return 1; -} - -int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a) -{ - static const char *status_map[] = { - "Granted.", - "Granted with modifications.", - "Rejected.", - "Waiting.", - "Revocation warning.", - "Revoked." - }; - static struct status_map_st failure_map[] = { - {TS_INFO_BAD_ALG, - "unrecognized or unsupported algorithm identifier"}, - {TS_INFO_BAD_REQUEST, - "transaction not permitted or supported"}, - {TS_INFO_BAD_DATA_FORMAT, - "the data submitted has the wrong format"}, - {TS_INFO_TIME_NOT_AVAILABLE, - "the TSA's time source is not available"}, - {TS_INFO_UNACCEPTED_POLICY, - "the requested TSA policy is not supported by the TSA"}, - {TS_INFO_UNACCEPTED_EXTENSION, - "the requested extension is not supported by the TSA"}, - {TS_INFO_ADD_INFO_NOT_AVAILABLE, - "the additional information requested could not be understood " - "or is not available"}, - {TS_INFO_SYSTEM_FAILURE, - "the request cannot be handled due to system failure"}, - {-1, NULL} - }; - long status; - int i, lines = 0; - - /* Printing status code. */ - BIO_printf(bio, "Status: "); - status = ASN1_INTEGER_get(a->status); - if (0 <= status - && status < (long)(sizeof(status_map) / sizeof(status_map[0]))) - BIO_printf(bio, "%s\n", status_map[status]); - else - BIO_printf(bio, "out of bounds\n"); - - /* Printing status description. */ - BIO_printf(bio, "Status description: "); - for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) { - if (i > 0) - BIO_puts(bio, "\t"); - ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i), 0); - BIO_puts(bio, "\n"); - } - if (i == 0) - BIO_printf(bio, "unspecified\n"); - - /* Printing failure information. */ - BIO_printf(bio, "Failure info: "); - if (a->failure_info != NULL) - lines = TS_status_map_print(bio, failure_map, a->failure_info); - if (lines == 0) - BIO_printf(bio, "unspecified"); - BIO_printf(bio, "\n"); - - return 1; -} - -static int TS_status_map_print(BIO *bio, struct status_map_st *a, - ASN1_BIT_STRING *v) -{ - int lines = 0; - - for (; a->bit >= 0; ++a) { - if (ASN1_BIT_STRING_get_bit(v, a->bit)) { - if (++lines > 1) - BIO_printf(bio, ", "); - BIO_printf(bio, "%s", a->text); - } - } - - return lines; -} - -int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a) -{ - int v; - ASN1_OBJECT *policy_id; - const ASN1_INTEGER *serial; - const ASN1_GENERALIZEDTIME *gtime; - TS_ACCURACY *accuracy; - const ASN1_INTEGER *nonce; - GENERAL_NAME *tsa_name; - - if (a == NULL) - return 0; - - /* Print version. */ - v = TS_TST_INFO_get_version(a); - BIO_printf(bio, "Version: %d\n", v); - - /* Print policy id. */ - BIO_printf(bio, "Policy OID: "); - policy_id = TS_TST_INFO_get_policy_id(a); - TS_OBJ_print_bio(bio, policy_id); - - /* Print message imprint. */ - TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a)); - - /* Print serial number. */ - BIO_printf(bio, "Serial number: "); - serial = TS_TST_INFO_get_serial(a); - if (serial == NULL) - BIO_printf(bio, "unspecified"); - else - TS_ASN1_INTEGER_print_bio(bio, serial); - BIO_write(bio, "\n", 1); - - /* Print time stamp. */ - BIO_printf(bio, "Time stamp: "); - gtime = TS_TST_INFO_get_time(a); - ASN1_GENERALIZEDTIME_print(bio, gtime); - BIO_write(bio, "\n", 1); - - /* Print accuracy. */ - BIO_printf(bio, "Accuracy: "); - accuracy = TS_TST_INFO_get_accuracy(a); - if (accuracy == NULL) - BIO_printf(bio, "unspecified"); - else - TS_ACCURACY_print_bio(bio, accuracy); - BIO_write(bio, "\n", 1); - - /* Print ordering. */ - BIO_printf(bio, "Ordering: %s\n", - TS_TST_INFO_get_ordering(a) ? "yes" : "no"); - - /* Print nonce. */ - BIO_printf(bio, "Nonce: "); - nonce = TS_TST_INFO_get_nonce(a); - if (nonce == NULL) - BIO_printf(bio, "unspecified"); - else - TS_ASN1_INTEGER_print_bio(bio, nonce); - BIO_write(bio, "\n", 1); - - /* Print TSA name. */ - BIO_printf(bio, "TSA: "); - tsa_name = TS_TST_INFO_get_tsa(a); - if (tsa_name == NULL) - BIO_printf(bio, "unspecified"); - else { - STACK_OF(CONF_VALUE) *nval; - if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL))) - X509V3_EXT_val_prn(bio, nval, 0, 0); - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - } - BIO_write(bio, "\n", 1); - - /* Print extensions. */ - TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a)); - - return 1; -} - -static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy) -{ - const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy); - const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy); - const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy); - - if (seconds != NULL) - TS_ASN1_INTEGER_print_bio(bio, seconds); - else - BIO_printf(bio, "unspecified"); - BIO_printf(bio, " seconds, "); - if (millis != NULL) - TS_ASN1_INTEGER_print_bio(bio, millis); - else - BIO_printf(bio, "unspecified"); - BIO_printf(bio, " millis, "); - if (micros != NULL) - TS_ASN1_INTEGER_print_bio(bio, micros); - else - BIO_printf(bio, "unspecified"); - BIO_printf(bio, " micros"); - - return 1; -} -/* crypto/ts/ts_resp_sign.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -#include "o_time.h" - -#if defined(OPENSSL_SYS_UNIX) -# include -#endif - -// #include "objects.h" -// #include "ts.h" -#include "pkcs7.h" - -/* Private function declarations. */ - -static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *); -static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec); -static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *); - -static void TS_RESP_CTX_init(TS_RESP_CTX *ctx); -static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx); -static int TS_RESP_check_request(TS_RESP_CTX *ctx); -static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx); -static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, - ASN1_OBJECT *policy); -static int TS_RESP_process_extensions(TS_RESP_CTX *ctx); -static int TS_RESP_sign(TS_RESP_CTX *ctx); - -static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, - STACK_OF(X509) *certs); -static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); -static int TS_TST_INFO_content_new(PKCS7 *p7); -static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); - -static ASN1_GENERALIZEDTIME -*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long, - unsigned); - -/* Default callbacks for response generation. */ - -static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) -{ - ASN1_INTEGER *serial = ASN1_INTEGER_new(); - if (!serial) - goto err; - if (!ASN1_INTEGER_set(serial, 1)) - goto err; - return serial; - err: - TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE); - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Error during serial number generation."); - return NULL; -} - -#if defined(OPENSSL_SYS_UNIX) - -/* Use the gettimeofday function call. */ -static int def_time_cb(struct TS_resp_ctx *ctx, void *data, - long *sec, long *usec) -{ - struct timeval tv; - if (gettimeofday(&tv, NULL) != 0) { - TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Time is not available."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); - return 0; - } - /* Return time to caller. */ - *sec = tv.tv_sec; - *usec = tv.tv_usec; - - return 1; -} - -#else - -/* Use the time function call that provides only seconds precision. */ -static int def_time_cb(struct TS_resp_ctx *ctx, void *data, - long *sec, long *usec) -{ - time_t t; - if (time(&t) == (time_t)-1) { - TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Time is not available."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); - return 0; - } - /* Return time to caller, only second precision. */ - *sec = (long)t; - *usec = 0; - - return 1; -} - -#endif - -static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, - void *data) -{ - /* No extensions are processed here. */ - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Unsupported extension."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION); - return 0; -} - -/* TS_RESP_CTX management functions. */ - -TS_RESP_CTX *TS_RESP_CTX_new() -{ - TS_RESP_CTX *ctx; - - if (!(ctx = (TS_RESP_CTX *)OPENSSL_malloc(sizeof(TS_RESP_CTX)))) { - TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - memset(ctx, 0, sizeof(TS_RESP_CTX)); - - /* Setting default callbacks. */ - ctx->serial_cb = def_serial_cb; - ctx->time_cb = def_time_cb; - ctx->extension_cb = def_extension_cb; - - return ctx; -} - -void TS_RESP_CTX_free(TS_RESP_CTX *ctx) -{ - if (!ctx) - return; - - X509_free(ctx->signer_cert); - EVP_PKEY_free(ctx->signer_key); - sk_X509_pop_free(ctx->certs, X509_free); - sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free); - ASN1_OBJECT_free(ctx->default_policy); - sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */ - ASN1_INTEGER_free(ctx->seconds); - ASN1_INTEGER_free(ctx->millis); - ASN1_INTEGER_free(ctx->micros); - OPENSSL_free(ctx); -} - -int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) -{ - if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) { - TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, - TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); - return 0; - } - if (ctx->signer_cert) - X509_free(ctx->signer_cert); - ctx->signer_cert = signer; - CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509); - return 1; -} - -int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key) -{ - if (ctx->signer_key) - EVP_PKEY_free(ctx->signer_key); - ctx->signer_key = key; - CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY); - - return 1; -} - -int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy) -{ - if (ctx->default_policy) - ASN1_OBJECT_free(ctx->default_policy); - if (!(ctx->default_policy = OBJ_dup(def_policy))) - goto err; - return 1; - err: - TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE); - return 0; -} - -int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) -{ - - if (ctx->certs) { - sk_X509_pop_free(ctx->certs, X509_free); - ctx->certs = NULL; - } - if (!certs) - return 1; - if (!(ctx->certs = X509_chain_up_ref(certs))) { - TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE); - return 0; - } - - return 1; -} - -int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) -{ - ASN1_OBJECT *copy = NULL; - - /* Create new policy stack if necessary. */ - if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) - goto err; - if (!(copy = OBJ_dup(policy))) - goto err; - if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) - goto err; - - return 1; - err: - TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE); - ASN1_OBJECT_free(copy); - return 0; -} - -int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) -{ - /* Create new md stack if necessary. */ - if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) - goto err; - /* Add the shared md, no copy needed. */ - if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) - goto err; - - return 1; - err: - TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE); - return 0; -} - -#define TS_RESP_CTX_accuracy_free(ctx) \ - ASN1_INTEGER_free(ctx->seconds); \ - ctx->seconds = NULL; \ - ASN1_INTEGER_free(ctx->millis); \ - ctx->millis = NULL; \ - ASN1_INTEGER_free(ctx->micros); \ - ctx->micros = NULL; - -int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, - int secs, int millis, int micros) -{ - - TS_RESP_CTX_accuracy_free(ctx); - if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) - || !ASN1_INTEGER_set(ctx->seconds, secs))) - goto err; - if (millis && (!(ctx->millis = ASN1_INTEGER_new()) - || !ASN1_INTEGER_set(ctx->millis, millis))) - goto err; - if (micros && (!(ctx->micros = ASN1_INTEGER_new()) - || !ASN1_INTEGER_set(ctx->micros, micros))) - goto err; - - return 1; - err: - TS_RESP_CTX_accuracy_free(ctx); - TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE); - return 0; -} - -void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags) -{ - ctx->flags |= flags; -} - -void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data) -{ - ctx->serial_cb = cb; - ctx->serial_cb_data = data; -} - -void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data) -{ - ctx->time_cb = cb; - ctx->time_cb_data = data; -} - -void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, - TS_extension_cb cb, void *data) -{ - ctx->extension_cb = cb; - ctx->extension_cb_data = data; -} - -int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, - int status, const char *text) -{ - TS_STATUS_INFO *si = NULL; - ASN1_UTF8STRING *utf8_text = NULL; - int ret = 0; - - if (!(si = TS_STATUS_INFO_new())) - goto err; - if (!ASN1_INTEGER_set(si->status, status)) - goto err; - if (text) { - if (!(utf8_text = ASN1_UTF8STRING_new()) - || !ASN1_STRING_set(utf8_text, text, strlen(text))) - goto err; - if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null())) - goto err; - if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) - goto err; - utf8_text = NULL; /* Ownership is lost. */ - } - if (!TS_RESP_set_status_info(ctx->response, si)) - goto err; - ret = 1; - err: - if (!ret) - TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); - TS_STATUS_INFO_free(si); - ASN1_UTF8STRING_free(utf8_text); - return ret; -} - -int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, - int status, const char *text) -{ - int ret = 1; - TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); - - if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) { - /* Status has not been set, set it now. */ - ret = TS_RESP_CTX_set_status_info(ctx, status, text); - } - return ret; -} - -int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) -{ - TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); - if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new())) - goto err; - if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1)) - goto err; - return 1; - err: - TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE); - return 0; -} - -TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx) -{ - return ctx->request; -} - -TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx) -{ - return ctx->tst_info; -} - -int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, - unsigned precision) -{ - if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) - return 0; - ctx->clock_precision_digits = precision; - return 1; -} - -/* Main entry method of the response generation. */ -TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) -{ - ASN1_OBJECT *policy; - TS_RESP *response; - int result = 0; - - TS_RESP_CTX_init(ctx); - - /* Creating the response object. */ - if (!(ctx->response = TS_RESP_new())) { - TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE); - goto end; - } - - /* Parsing DER request. */ - if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) { - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Bad request format or " "system error."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); - goto end; - } - - /* Setting default status info. */ - if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL)) - goto end; - - /* Checking the request format. */ - if (!TS_RESP_check_request(ctx)) - goto end; - - /* Checking acceptable policies. */ - if (!(policy = TS_RESP_get_policy(ctx))) - goto end; - - /* Creating the TS_TST_INFO object. */ - if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy))) - goto end; - - /* Processing extensions. */ - if (!TS_RESP_process_extensions(ctx)) - goto end; - - /* Generating the signature. */ - if (!TS_RESP_sign(ctx)) - goto end; - - /* Everything was successful. */ - result = 1; - end: - if (!result) { - TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR); - if (ctx->response != NULL) { - if (TS_RESP_CTX_set_status_info_cond(ctx, - TS_STATUS_REJECTION, - "Error during response " - "generation.") == 0) { - TS_RESP_free(ctx->response); - ctx->response = NULL; - } - } - } - response = ctx->response; - ctx->response = NULL; /* Ownership will be returned to caller. */ - TS_RESP_CTX_cleanup(ctx); - return response; -} - -/* Initializes the variable part of the context. */ -static void TS_RESP_CTX_init(TS_RESP_CTX *ctx) -{ - ctx->request = NULL; - ctx->response = NULL; - ctx->tst_info = NULL; -} - -/* Cleans up the variable part of the context. */ -static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx) -{ - TS_REQ_free(ctx->request); - ctx->request = NULL; - TS_RESP_free(ctx->response); - ctx->response = NULL; - TS_TST_INFO_free(ctx->tst_info); - ctx->tst_info = NULL; -} - -/* Checks the format and content of the request. */ -static int TS_RESP_check_request(TS_RESP_CTX *ctx) -{ - TS_REQ *request = ctx->request; - TS_MSG_IMPRINT *msg_imprint; - X509_ALGOR *md_alg; - int md_alg_id; - const ASN1_OCTET_STRING *digest; - EVP_MD *md = NULL; - int i; - - /* Checking request version. */ - if (TS_REQ_get_version(request) != 1) { - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Bad request version."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST); - return 0; - } - - /* Checking message digest algorithm. */ - msg_imprint = TS_REQ_get_msg_imprint(request); - md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint); - md_alg_id = OBJ_obj2nid(md_alg->algorithm); - for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) { - EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); - if (md_alg_id == EVP_MD_type(current_md)) - md = current_md; - } - if (!md) { - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Message digest algorithm is " - "not supported."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); - return 0; - } - - /* No message digest takes parameter. */ - if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) { - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Superfluous message digest " - "parameter."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); - return 0; - } - /* Checking message digest size. */ - digest = TS_MSG_IMPRINT_get_msg(msg_imprint); - if (digest->length != EVP_MD_size(md)) { - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Bad message digest."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); - return 0; - } - - return 1; -} - -/* Returns the TSA policy based on the requested and acceptable policies. */ -static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx) -{ - ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request); - ASN1_OBJECT *policy = NULL; - int i; - - if (ctx->default_policy == NULL) { - TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER); - return NULL; - } - /* - * Return the default policy if none is requested or the default is - * requested. - */ - if (!requested || !OBJ_cmp(requested, ctx->default_policy)) - policy = ctx->default_policy; - - /* Check if the policy is acceptable. */ - for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) { - ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i); - if (!OBJ_cmp(requested, current)) - policy = current; - } - if (!policy) { - TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY); - TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, - "Requested policy is not " "supported."); - TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY); - } - return policy; -} - -/* Creates the TS_TST_INFO object based on the settings of the context. */ -static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, - ASN1_OBJECT *policy) -{ - int result = 0; - TS_TST_INFO *tst_info = NULL; - ASN1_INTEGER *serial = NULL; - ASN1_GENERALIZEDTIME *asn1_time = NULL; - long sec, usec; - TS_ACCURACY *accuracy = NULL; - const ASN1_INTEGER *nonce; - GENERAL_NAME *tsa_name = NULL; - - if (!(tst_info = TS_TST_INFO_new())) - goto end; - if (!TS_TST_INFO_set_version(tst_info, 1)) - goto end; - if (!TS_TST_INFO_set_policy_id(tst_info, policy)) - goto end; - if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint)) - goto end; - if (!(serial = (*ctx->serial_cb) (ctx, ctx->serial_cb_data)) - || !TS_TST_INFO_set_serial(tst_info, serial)) - goto end; - if (!(*ctx->time_cb) (ctx, ctx->time_cb_data, &sec, &usec) - || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, - sec, usec, - ctx->clock_precision_digits)) - || !TS_TST_INFO_set_time(tst_info, asn1_time)) - goto end; - - /* Setting accuracy if needed. */ - if ((ctx->seconds || ctx->millis || ctx->micros) - && !(accuracy = TS_ACCURACY_new())) - goto end; - - if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds)) - goto end; - if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis)) - goto end; - if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros)) - goto end; - if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) - goto end; - - /* Setting ordering. */ - if ((ctx->flags & TS_ORDERING) - && !TS_TST_INFO_set_ordering(tst_info, 1)) - goto end; - - /* Setting nonce if needed. */ - if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL - && !TS_TST_INFO_set_nonce(tst_info, nonce)) - goto end; - - /* Setting TSA name to subject of signer certificate. */ - if (ctx->flags & TS_TSA_NAME) { - if (!(tsa_name = GENERAL_NAME_new())) - goto end; - tsa_name->type = GEN_DIRNAME; - tsa_name->d.dirn = - X509_NAME_dup(ctx->signer_cert->cert_info->subject); - if (!tsa_name->d.dirn) - goto end; - if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) - goto end; - } - - result = 1; - end: - if (!result) { - TS_TST_INFO_free(tst_info); - tst_info = NULL; - TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR); - TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, - "Error during TSTInfo " - "generation."); - } - GENERAL_NAME_free(tsa_name); - TS_ACCURACY_free(accuracy); - ASN1_GENERALIZEDTIME_free(asn1_time); - ASN1_INTEGER_free(serial); - - return tst_info; -} - -/* Processing the extensions of the request. */ -static int TS_RESP_process_extensions(TS_RESP_CTX *ctx) -{ - STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request); - int i; - int ok = 1; - - for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) { - X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); - /* - * XXXXX The last argument was previously (void *)ctx->extension_cb, - * but ISO C doesn't permit converting a function pointer to void *. - * For lack of better information, I'm placing a NULL there instead. - * The callback can pick its own address out from the ctx anyway... - */ - ok = (*ctx->extension_cb) (ctx, ext, NULL); - } - - return ok; -} - -/* Functions for signing the TS_TST_INFO structure of the context. */ -static int TS_RESP_sign(TS_RESP_CTX *ctx) -{ - int ret = 0; - PKCS7 *p7 = NULL; - PKCS7_SIGNER_INFO *si; - STACK_OF(X509) *certs; /* Certificates to include in sc. */ - ESS_SIGNING_CERT *sc = NULL; - ASN1_OBJECT *oid; - BIO *p7bio = NULL; - int i; - - /* Check if signcert and pkey match. */ - if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); - goto err; - } - - /* Create a new PKCS7 signed object. */ - if (!(p7 = PKCS7_new())) { - TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - if (!PKCS7_set_type(p7, NID_pkcs7_signed)) - goto err; - - /* Force SignedData version to be 3 instead of the default 1. */ - if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) - goto err; - - /* Add signer certificate and optional certificate chain. */ - if (TS_REQ_get_cert_req(ctx->request)) { - PKCS7_add_certificate(p7, ctx->signer_cert); - if (ctx->certs) { - for (i = 0; i < sk_X509_num(ctx->certs); ++i) { - X509 *cert = sk_X509_value(ctx->certs, i); - PKCS7_add_certificate(p7, cert); - } - } - } - - /* Add a new signer info. */ - if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, - ctx->signer_key, EVP_sha1()))) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR); - goto err; - } - - /* Add content type signed attribute to the signer info. */ - oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); - if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, - V_ASN1_OBJECT, oid)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); - goto err; - } - - /* - * Create the ESS SigningCertificate attribute which contains the signer - * certificate id and optionally the certificate chain. - */ - certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; - if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs))) - goto err; - - /* Add SigningCertificate signed attribute to the signer info. */ - if (!ESS_add_signing_cert(si, sc)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); - goto err; - } - - /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */ - if (!TS_TST_INFO_content_new(p7)) - goto err; - - /* Add the DER encoded tst_info to the PKCS7 structure. */ - if (!(p7bio = PKCS7_dataInit(p7, NULL))) { - TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* Convert tst_info to DER. */ - if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); - goto err; - } - - /* Create the signature and add it to the signer info. */ - if (!PKCS7_dataFinal(p7, p7bio)) { - TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); - goto err; - } - - /* Set new PKCS7 and TST_INFO objects. */ - TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); - p7 = NULL; /* Ownership is lost. */ - ctx->tst_info = NULL; /* Ownership is lost. */ - - ret = 1; - err: - if (!ret) - TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, - "Error during signature " - "generation."); - BIO_free_all(p7bio); - ESS_SIGNING_CERT_free(sc); - PKCS7_free(p7); - return ret; -} - -static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, - STACK_OF(X509) *certs) -{ - ESS_CERT_ID *cid; - ESS_SIGNING_CERT *sc = NULL; - int i; - - /* Creating the ESS_CERT_ID stack. */ - if (!(sc = ESS_SIGNING_CERT_new())) - goto err; - if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null())) - goto err; - - /* Adding the signing certificate id. */ - if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) - || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) - goto err; - /* Adding the certificate chain ids. */ - for (i = 0; i < sk_X509_num(certs); ++i) { - X509 *cert = sk_X509_value(certs, i); - if (!(cid = ESS_CERT_ID_new_init(cert, 1)) - || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) - goto err; - } - - return sc; - err: - ESS_SIGNING_CERT_free(sc); - TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE); - return NULL; -} - -static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) -{ - ESS_CERT_ID *cid = NULL; - GENERAL_NAME *name = NULL; - - /* Recompute SHA1 hash of certificate if necessary (side effect). */ - X509_check_purpose(cert, -1, 0); - - if (!(cid = ESS_CERT_ID_new())) - goto err; - if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash, - sizeof(cert->sha1_hash))) - goto err; - - /* Setting the issuer/serial if requested. */ - if (issuer_needed) { - /* Creating issuer/serial structure. */ - if (!cid->issuer_serial - && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new())) - goto err; - /* Creating general name from the certificate issuer. */ - if (!(name = GENERAL_NAME_new())) - goto err; - name->type = GEN_DIRNAME; - if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) - goto err; - if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) - goto err; - name = NULL; /* Ownership is lost. */ - /* Setting the serial number. */ - ASN1_INTEGER_free(cid->issuer_serial->serial); - if (!(cid->issuer_serial->serial = - ASN1_INTEGER_dup(cert->cert_info->serialNumber))) - goto err; - } - - return cid; - err: - GENERAL_NAME_free(name); - ESS_CERT_ID_free(cid); - TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE); - return NULL; -} - -static int TS_TST_INFO_content_new(PKCS7 *p7) -{ - PKCS7 *ret = NULL; - ASN1_OCTET_STRING *octet_string = NULL; - - /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */ - if (!(ret = PKCS7_new())) - goto err; - if (!(ret->d.other = ASN1_TYPE_new())) - goto err; - ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); - if (!(octet_string = ASN1_OCTET_STRING_new())) - goto err; - ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string); - octet_string = NULL; - - /* Add encapsulated content to signed PKCS7 structure. */ - if (!PKCS7_set_content(p7, ret)) - goto err; - - return 1; - err: - ASN1_OCTET_STRING_free(octet_string); - PKCS7_free(ret); - return 0; -} - -static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) -{ - ASN1_STRING *seq = NULL; - unsigned char *p, *pp = NULL; - int len; - - len = i2d_ESS_SIGNING_CERT(sc, NULL); - if (!(pp = (unsigned char *)OPENSSL_malloc(len))) { - TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); - goto err; - } - p = pp; - i2d_ESS_SIGNING_CERT(sc, &p); - if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { - TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); - goto err; - } - OPENSSL_free(pp); - pp = NULL; - return PKCS7_add_signed_attribute(si, - NID_id_smime_aa_signingCertificate, - V_ASN1_SEQUENCE, seq); - err: - ASN1_STRING_free(seq); - OPENSSL_free(pp); - - return 0; -} - -static ASN1_GENERALIZEDTIME -*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, - long sec, long usec, unsigned precision) -{ - time_t time_sec = (time_t)sec; - struct tm *tm = NULL; - struct tm result = {0}; - char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; - char *p = genTime_str; - char *p_end = genTime_str + sizeof(genTime_str); - - if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) - goto err; - - if (!(tm = OPENSSL_gmtime(&time_sec, &result))) - goto err; - - /* - * Put "genTime_str" in GeneralizedTime format. We work around the - * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST - * NOT include fractional seconds") and OpenSSL related functions to - * meet the rfc3161 requirement: "GeneralizedTime syntax can include - * fraction-of-second details". - */ - p += BIO_snprintf(p, p_end - p, - "%04d%02d%02d%02d%02d%02d", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - if (precision > 0) { - /* Add fraction of seconds (leave space for dot and null). */ - BIO_snprintf(p, 2 + precision, ".%06ld", usec); - /* - * We cannot use the snprintf return value, because it might have - * been truncated. - */ - p += strlen(p); - - /* - * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the - * following restrictions for a DER-encoding, which OpenSSL - * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't - * support: "The encoding MUST terminate with a "Z" (which means - * "Zulu" time). The decimal point element, if present, MUST be the - * point option ".". The fractional-seconds elements, if present, - * MUST omit all trailing 0's; if the elements correspond to 0, they - * MUST be wholly omitted, and the decimal point element also MUST be - * omitted." - */ - /* - * Remove trailing zeros. The dot guarantees the exit condition of - * this loop even if all the digits are zero. - */ - while (*--p == '0') - /* - * empty - */ ; - /* p points to either the dot or the last non-zero digit. */ - if (*p != '.') - ++p; - } - /* Add the trailing Z and the terminating null. */ - *p++ = 'Z'; - *p++ = '\0'; - - /* Now call OpenSSL to check and set our genTime value */ - if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new())) - goto err; - if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) { - ASN1_GENERALIZEDTIME_free(asn1_time); - goto err; - } - - return asn1_time; - err: - TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME); - return NULL; -} -/* crypto/ts/ts_resp_utils.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "ts.h" -// #include "pkcs7.h" - -/* Function definitions. */ - -int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info) -{ - TS_STATUS_INFO *new_status_info; - - if (a->status_info == status_info) - return 1; - new_status_info = TS_STATUS_INFO_dup(status_info); - if (new_status_info == NULL) { - TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); - return 0; - } - TS_STATUS_INFO_free(a->status_info); - a->status_info = new_status_info; - - return 1; -} - -TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a) -{ - return a->status_info; -} - -/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ -void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info) -{ - /* Set new PKCS7 and TST_INFO objects. */ - PKCS7_free(a->token); - a->token = p7; - TS_TST_INFO_free(a->tst_info); - a->tst_info = tst_info; -} - -PKCS7 *TS_RESP_get_token(TS_RESP *a) -{ - return a->token; -} - -TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a) -{ - return a->tst_info; -} - -int TS_TST_INFO_set_version(TS_TST_INFO *a, long version) -{ - return ASN1_INTEGER_set(a->version, version); -} - -long TS_TST_INFO_get_version(const TS_TST_INFO *a) -{ - return ASN1_INTEGER_get(a->version); -} - -int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy) -{ - ASN1_OBJECT *new_policy; - - if (a->policy_id == policy) - return 1; - new_policy = OBJ_dup(policy); - if (new_policy == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); - return 0; - } - ASN1_OBJECT_free(a->policy_id); - a->policy_id = new_policy; - return 1; -} - -ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a) -{ - return a->policy_id; -} - -int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint) -{ - TS_MSG_IMPRINT *new_msg_imprint; - - if (a->msg_imprint == msg_imprint) - return 1; - new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); - if (new_msg_imprint == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); - return 0; - } - TS_MSG_IMPRINT_free(a->msg_imprint); - a->msg_imprint = new_msg_imprint; - return 1; -} - -TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a) -{ - return a->msg_imprint; -} - -int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial) -{ - ASN1_INTEGER *new_serial; - - if (a->serial == serial) - return 1; - new_serial = ASN1_INTEGER_dup(serial); - if (new_serial == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE); - return 0; - } - ASN1_INTEGER_free(a->serial); - a->serial = new_serial; - return 1; -} - -const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a) -{ - return a->serial; -} - -int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime) -{ - ASN1_GENERALIZEDTIME *new_time; - - if (a->time == gtime) - return 1; - new_time = M_ASN1_GENERALIZEDTIME_dup(gtime); - if (new_time == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE); - return 0; - } - ASN1_GENERALIZEDTIME_free(a->time); - a->time = new_time; - return 1; -} - -const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a) -{ - return a->time; -} - -int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy) -{ - TS_ACCURACY *new_accuracy; - - if (a->accuracy == accuracy) - return 1; - new_accuracy = TS_ACCURACY_dup(accuracy); - if (new_accuracy == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE); - return 0; - } - TS_ACCURACY_free(a->accuracy); - a->accuracy = new_accuracy; - return 1; -} - -TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a) -{ - return a->accuracy; -} - -int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds) -{ - ASN1_INTEGER *new_seconds; - - if (a->seconds == seconds) - return 1; - new_seconds = ASN1_INTEGER_dup(seconds); - if (new_seconds == NULL) { - TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE); - return 0; - } - ASN1_INTEGER_free(a->seconds); - a->seconds = new_seconds; - return 1; -} - -const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a) -{ - return a->seconds; -} - -int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis) -{ - ASN1_INTEGER *new_millis = NULL; - - if (a->millis == millis) - return 1; - if (millis != NULL) { - new_millis = ASN1_INTEGER_dup(millis); - if (new_millis == NULL) { - TSerr(TS_F_TS_ACCURACY_SET_MILLIS, ERR_R_MALLOC_FAILURE); - return 0; - } - } - ASN1_INTEGER_free(a->millis); - a->millis = new_millis; - return 1; -} - -const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a) -{ - return a->millis; -} - -int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros) -{ - ASN1_INTEGER *new_micros = NULL; - - if (a->micros == micros) - return 1; - if (micros != NULL) { - new_micros = ASN1_INTEGER_dup(micros); - if (new_micros == NULL) { - TSerr(TS_F_TS_ACCURACY_SET_MICROS, ERR_R_MALLOC_FAILURE); - return 0; - } - } - ASN1_INTEGER_free(a->micros); - a->micros = new_micros; - return 1; -} - -const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a) -{ - return a->micros; -} - -int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering) -{ - a->ordering = ordering ? 0xFF : 0x00; - return 1; -} - -int TS_TST_INFO_get_ordering(const TS_TST_INFO *a) -{ - return a->ordering ? 1 : 0; -} - -int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce) -{ - ASN1_INTEGER *new_nonce; - - if (a->nonce == nonce) - return 1; - new_nonce = ASN1_INTEGER_dup(nonce); - if (new_nonce == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE); - return 0; - } - ASN1_INTEGER_free(a->nonce); - a->nonce = new_nonce; - return 1; -} - -const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a) -{ - return a->nonce; -} - -int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa) -{ - GENERAL_NAME *new_tsa; - - if (a->tsa == tsa) - return 1; - new_tsa = GENERAL_NAME_dup(tsa); - if (new_tsa == NULL) { - TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE); - return 0; - } - GENERAL_NAME_free(a->tsa); - a->tsa = new_tsa; - return 1; -} - -GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a) -{ - return a->tsa; -} - -STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a) -{ - return a->extensions; -} - -void TS_TST_INFO_ext_free(TS_TST_INFO *a) -{ - if (!a) - return; - sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); - a->extensions = NULL; -} - -int TS_TST_INFO_get_ext_count(TS_TST_INFO *a) -{ - return X509v3_get_ext_count(a->extensions); -} - -int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos) -{ - return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); -} - -int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos) -{ - return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); -} - -int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos) -{ - return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); -} - -X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc) -{ - return X509v3_get_ext(a->extensions, loc); -} - -X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc) -{ - return X509v3_delete_ext(a->extensions, loc); -} - -int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc) -{ - return X509v3_add_ext(&a->extensions, ex, loc) != NULL; -} - -void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(a->extensions, nid, crit, idx); -} -/* crypto/ts/ts_resp_verify.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2002. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "objects.h" -// #include "ts.h" -// #include "pkcs7.h" - -/* Private function declarations. */ - -static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, - X509 *signer, STACK_OF(X509) **chain); -static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, - STACK_OF(X509) *chain); -static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); -static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); -static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo); -static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, - PKCS7 *token, TS_TST_INFO *tst_info); -static int TS_check_status_info(TS_RESP *response); -static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); -static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); -static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, - X509_ALGOR **md_alg, - unsigned char **imprint, unsigned *imprint_len); -static int TS_check_imprints(X509_ALGOR *algor_a, - unsigned char *imprint_a, unsigned len_a, - TS_TST_INFO *tst_info); -static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); -static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); -static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, - GENERAL_NAME *name); - -/* - * Local mapping between response codes and descriptions. - * Don't forget to change TS_STATUS_BUF_SIZE when modifying - * the elements of this array. - */ -static const char *TS_status_text[] = { "granted", - "grantedWithMods", - "rejection", - "waiting", - "revocationWarning", - "revocationNotification" -}; - -#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) - -/* - * This must be greater or equal to the sum of the strings in TS_status_text - * plus the number of its elements. - */ -#define TS_STATUS_BUF_SIZE 256 - -static struct { - int code; - const char *text; -} TS_failure_info[] = { - { - TS_INFO_BAD_ALG, "badAlg" - }, - { - TS_INFO_BAD_REQUEST, "badRequest" - }, - { - TS_INFO_BAD_DATA_FORMAT, "badDataFormat" - }, - { - TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" - }, - { - TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" - }, - { - TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" - }, - { - TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" - }, - { - TS_INFO_SYSTEM_FAILURE, "systemFailure" - } -}; - -#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ - sizeof(*TS_failure_info)) - -/* Functions for verifying a signed TS_TST_INFO structure. */ - -/*- - * This function carries out the following tasks: - * - Checks if there is one and only one signer. - * - Search for the signing certificate in 'certs' and in the response. - * - Check the extended key usage and key usage fields of the signer - * certificate (done by the path validation). - * - Build and validate the certificate path. - * - Check if the certificate path meets the requirements of the - * SigningCertificate ESS signed attribute. - * - Verify the signature value. - * - Returns the signer certificate in 'signer', if 'signer' is not NULL. - */ -int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, - X509_STORE *store, X509 **signer_out) -{ - STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; - PKCS7_SIGNER_INFO *si; - STACK_OF(X509) *signers = NULL; - X509 *signer; - STACK_OF(X509) *chain = NULL; - char buf[4096]; - int i, j = 0, ret = 0; - BIO *p7bio = NULL; - - /* Some sanity checks first. */ - if (!token) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER); - goto err; - } - - /* Check for the correct content type */ - if (!PKCS7_type_is_signed(token)) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE); - goto err; - } - - /* Check if there is one and only one signer. */ - sinfos = PKCS7_get_signer_info(token); - if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_THERE_MUST_BE_ONE_SIGNER); - goto err; - } - si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); - - /* Check for no content: no data to verify signature. */ - if (PKCS7_get_detached(token)) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT); - goto err; - } - - /* - * Get hold of the signer certificate, search only internal certificates - * if it was requested. - */ - signers = PKCS7_get0_signers(token, certs, 0); - if (!signers || sk_X509_num(signers) != 1) - goto err; - signer = sk_X509_value(signers, 0); - - /* Now verify the certificate. */ - if (!TS_verify_cert(store, certs, signer, &chain)) - goto err; - - /* - * Check if the signer certificate is consistent with the ESS extension. - */ - if (!TS_check_signing_certs(si, chain)) - goto err; - - /* Creating the message digest. */ - p7bio = PKCS7_dataInit(token, NULL); - - /* We now have to 'read' from p7bio to calculate digests etc. */ - while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0) ; - - /* Verifying the signature. */ - j = PKCS7_signatureVerify(p7bio, token, si, signer); - if (j <= 0) { - TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE); - goto err; - } - - /* Return the signer certificate if needed. */ - if (signer_out) { - *signer_out = signer; - CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); - } - - ret = 1; - - err: - BIO_free_all(p7bio); - sk_X509_pop_free(chain, X509_free); - sk_X509_free(signers); - - return ret; -} - -/* - * The certificate chain is returned in chain. Caller is responsible for - * freeing the vector. - */ -static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, - X509 *signer, STACK_OF(X509) **chain) -{ - X509_STORE_CTX cert_ctx; - int i; - int ret = 1; - - /* chain is an out argument. */ - *chain = NULL; - if (!X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted)) - return 0; - X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); - i = X509_verify_cert(&cert_ctx); - if (i <= 0) { - int j = X509_STORE_CTX_get_error(&cert_ctx); - TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); - ERR_add_error_data(2, "Verify error:", - X509_verify_cert_error_string(j)); - ret = 0; - } else { - /* Get a copy of the certificate chain. */ - *chain = X509_STORE_CTX_get1_chain(&cert_ctx); - } - - X509_STORE_CTX_cleanup(&cert_ctx); - - return ret; -} - -static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, - STACK_OF(X509) *chain) -{ - ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); - STACK_OF(ESS_CERT_ID) *cert_ids = NULL; - X509 *cert; - int i = 0; - int ret = 0; - - if (!ss) - goto err; - cert_ids = ss->cert_ids; - /* The signer certificate must be the first in cert_ids. */ - cert = sk_X509_value(chain, 0); - if (TS_find_cert(cert_ids, cert) != 0) - goto err; - - /* - * Check the other certificates of the chain if there are more than one - * certificate ids in cert_ids. - */ - if (sk_ESS_CERT_ID_num(cert_ids) > 1) { - /* All the certificates of the chain must be in cert_ids. */ - for (i = 1; i < sk_X509_num(chain); ++i) { - cert = sk_X509_value(chain, i); - if (TS_find_cert(cert_ids, cert) < 0) - goto err; - } - } - ret = 1; - err: - if (!ret) - TSerr(TS_F_TS_CHECK_SIGNING_CERTS, - TS_R_ESS_SIGNING_CERTIFICATE_ERROR); - ESS_SIGNING_CERT_free(ss); - return ret; -} - -static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) -{ - ASN1_TYPE *attr; - const unsigned char *p; - attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate); - if (!attr) - return NULL; - p = attr->value.sequence->data; - return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); -} - -/* Returns < 0 if certificate is not found, certificate index otherwise. */ -static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) -{ - int i; - - if (!cert_ids || !cert) - return -1; - - /* Recompute SHA1 hash of certificate if necessary (side effect). */ - X509_check_purpose(cert, -1, 0); - - /* Look for cert in the cert_ids vector. */ - for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { - ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); - - /* Check the SHA-1 hash first. */ - if (cid->hash->length == sizeof(cert->sha1_hash) - && !memcmp(cid->hash->data, cert->sha1_hash, - sizeof(cert->sha1_hash))) { - /* Check the issuer/serial as well if specified. */ - ESS_ISSUER_SERIAL *is = cid->issuer_serial; - if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) - return i; - } - } - - return -1; -} - -static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo) -{ - GENERAL_NAME *issuer; - - if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) - return -1; - - /* Check the issuer first. It must be a directory name. */ - issuer = sk_GENERAL_NAME_value(is->issuer, 0); - if (issuer->type != GEN_DIRNAME - || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer)) - return -1; - - /* Check the serial number, too. */ - if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber)) - return -1; - - return 0; -} - -/*- - * Verifies whether 'response' contains a valid response with regards - * to the settings of the context: - * - Gives an error message if the TS_TST_INFO is not present. - * - Calls _TS_RESP_verify_token to verify the token content. - */ -int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) -{ - PKCS7 *token = TS_RESP_get_token(response); - TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); - int ret = 0; - - /* Check if we have a successful TS_TST_INFO object in place. */ - if (!TS_check_status_info(response)) - goto err; - - /* Check the contents of the time stamp token. */ - if (!int_TS_RESP_verify_token(ctx, token, tst_info)) - goto err; - - ret = 1; - err: - return ret; -} - -/* - * Tries to extract a TS_TST_INFO structure from the PKCS7 token and - * calls the internal int_TS_RESP_verify_token function for verifying it. - */ -int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) -{ - TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); - int ret = 0; - if (tst_info) { - ret = int_TS_RESP_verify_token(ctx, token, tst_info); - TS_TST_INFO_free(tst_info); - } - return ret; -} - -/*- - * Verifies whether the 'token' contains a valid time stamp token - * with regards to the settings of the context. Only those checks are - * carried out that are specified in the context: - * - Verifies the signature of the TS_TST_INFO. - * - Checks the version number of the response. - * - Check if the requested and returned policies math. - * - Check if the message imprints are the same. - * - Check if the nonces are the same. - * - Check if the TSA name matches the signer. - * - Check if the TSA name is the expected TSA. - */ -static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, - PKCS7 *token, TS_TST_INFO *tst_info) -{ - X509 *signer = NULL; - GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); - X509_ALGOR *md_alg = NULL; - unsigned char *imprint = NULL; - unsigned imprint_len = 0; - int ret = 0; - int flags = ctx->flags; - - /* Some options require us to also check the signature */ - if (((flags & TS_VFY_SIGNER) && tsa_name != NULL) - || (flags & TS_VFY_TSA_NAME)) { - flags |= TS_VFY_SIGNATURE; - } - - /* Verify the signature. */ - if ((flags & TS_VFY_SIGNATURE) - && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer)) - goto err; - - /* Check version number of response. */ - if ((flags & TS_VFY_VERSION) - && TS_TST_INFO_get_version(tst_info) != 1) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); - goto err; - } - - /* Check policies. */ - if ((flags & TS_VFY_POLICY) - && !TS_check_policy(ctx->policy, tst_info)) - goto err; - - /* Check message imprints. */ - if ((flags & TS_VFY_IMPRINT) - && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, - tst_info)) - goto err; - - /* Compute and check message imprints. */ - if ((flags & TS_VFY_DATA) - && (!TS_compute_imprint(ctx->data, tst_info, - &md_alg, &imprint, &imprint_len) - || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) - goto err; - - /* Check nonces. */ - if ((flags & TS_VFY_NONCE) - && !TS_check_nonces(ctx->nonce, tst_info)) - goto err; - - /* Check whether TSA name and signer certificate match. */ - if ((flags & TS_VFY_SIGNER) - && tsa_name && !TS_check_signer_name(tsa_name, signer)) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); - goto err; - } - - /* Check whether the TSA is the expected one. */ - if ((flags & TS_VFY_TSA_NAME) - && !TS_check_signer_name(ctx->tsa_name, signer)) { - TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); - goto err; - } - - ret = 1; - err: - X509_free(signer); - X509_ALGOR_free(md_alg); - OPENSSL_free(imprint); - return ret; -} - -static int TS_check_status_info(TS_RESP *response) -{ - TS_STATUS_INFO *info = TS_RESP_get_status_info(response); - long status = ASN1_INTEGER_get(info->status); - const char *status_text = NULL; - char *embedded_status_text = NULL; - char failure_text[TS_STATUS_BUF_SIZE] = ""; - - /* Check if everything went fine. */ - if (status == 0 || status == 1) - return 1; - - /* There was an error, get the description in status_text. */ - if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE) - status_text = TS_status_text[status]; - else - status_text = "unknown code"; - - /* Set the embedded_status_text to the returned description. */ - if (sk_ASN1_UTF8STRING_num(info->text) > 0 - && !(embedded_status_text = TS_get_status_text(info->text))) - return 0; - - /* Filling in failure_text with the failure information. */ - if (info->failure_info) { - int i; - int first = 1; - for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) { - if (ASN1_BIT_STRING_get_bit(info->failure_info, - TS_failure_info[i].code)) { - if (!first) - strcat(failure_text, ","); - else - first = 0; - strcat(failure_text, TS_failure_info[i].text); - } - } - } - if (failure_text[0] == '\0') - strcpy(failure_text, "unspecified"); - - /* Making up the error string. */ - TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN); - ERR_add_error_data(6, - "status code: ", status_text, - ", status text: ", embedded_status_text ? - embedded_status_text : "unspecified", - ", failure codes: ", failure_text); - OPENSSL_free(embedded_status_text); - - return 0; -} - -static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) -{ - int i; - int length = 0; - char *result = NULL; - char *p; - - /* Determine length first. */ - for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) { - ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); - if (ASN1_STRING_length(current) > TS_MAX_STATUS_LENGTH - length - 1) - return NULL; - length += ASN1_STRING_length(current); - length += 1; /* separator character */ - } - /* Allocate memory (closing '\0' included). */ - if (!(result = OPENSSL_malloc(length))) { - TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE); - return NULL; - } - /* Concatenate the descriptions. */ - for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) { - ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); - length = ASN1_STRING_length(current); - if (i > 0) - *p++ = '/'; - strncpy(p, (const char *)ASN1_STRING_data(current), length); - p += length; - } - /* We do have space for this, too. */ - *p = '\0'; - - return result; -} - -static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) -{ - ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); - - if (OBJ_cmp(req_oid, resp_oid) != 0) { - TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH); - return 0; - } - - return 1; -} - -static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, - X509_ALGOR **md_alg, - unsigned char **imprint, unsigned *imprint_len) -{ - TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); - X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); - const EVP_MD *md; - EVP_MD_CTX md_ctx; - unsigned char buffer[4096]; - int length; - - *md_alg = NULL; - *imprint = NULL; - - /* Return the MD algorithm of the response. */ - if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) - goto err; - - /* Getting the MD object. */ - if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) { - TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM); - goto err; - } - - /* Compute message digest. */ - length = EVP_MD_size(md); - if (length < 0) - goto err; - *imprint_len = length; - if (!(*imprint = OPENSSL_malloc(*imprint_len))) { - TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (!EVP_DigestInit(&md_ctx, md)) - goto err; - while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) { - if (!EVP_DigestUpdate(&md_ctx, buffer, length)) - goto err; - } - if (!EVP_DigestFinal(&md_ctx, *imprint, NULL)) - goto err; - - return 1; - err: - X509_ALGOR_free(*md_alg); - OPENSSL_free(*imprint); - *imprint_len = 0; - *imprint = 0; - return 0; -} - -static int TS_check_imprints(X509_ALGOR *algor_a, - unsigned char *imprint_a, unsigned len_a, - TS_TST_INFO *tst_info) -{ - TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); - X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); - int ret = 0; - - /* algor_a is optional. */ - if (algor_a) { - /* Compare algorithm OIDs. */ - if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) - goto err; - - /* The parameter must be NULL in both. */ - if ((algor_a->parameter - && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) - || (algor_b->parameter - && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL)) - goto err; - } - - /* Compare octet strings. */ - ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) && - memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0; - err: - if (!ret) - TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH); - return ret; -} - -static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) -{ - const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); - - /* Error if nonce is missing. */ - if (!b) { - TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED); - return 0; - } - - /* No error if a nonce is returned without being requested. */ - if (ASN1_INTEGER_cmp(a, b) != 0) { - TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH); - return 0; - } - - return 1; -} - -/* - * Check if the specified TSA name matches either the subject or one of the - * subject alternative names of the TSA certificate. - */ -static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) -{ - STACK_OF(GENERAL_NAME) *gen_names = NULL; - int idx = -1; - int found = 0; - - /* Check the subject name first. */ - if (tsa_name->type == GEN_DIRNAME - && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0) - return 1; - - /* Check all the alternative names. */ - gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx); - while (gen_names != NULL - && !(found = TS_find_name(gen_names, tsa_name) >= 0)) { - /* - * Get the next subject alternative name, although there should be no - * more than one. - */ - GENERAL_NAMES_free(gen_names); - gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, - NULL, &idx); - } - if (gen_names) - GENERAL_NAMES_free(gen_names); - - return found; -} - -/* Returns 1 if name is in gen_names, 0 otherwise. */ -static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) -{ - int i, found; - for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); ++i) { - GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); - found = GENERAL_NAME_cmp(current, name) == 0; - } - return found ? i - 1 : -1; -} -/* crypto/ts/ts_verify_ctx.c */ -/* - * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project - * 2003. - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -// #include "cryptlib.h" -// #include "objects.h" -// #include "ts.h" - -TS_VERIFY_CTX *TS_VERIFY_CTX_new(void) -{ - TS_VERIFY_CTX *ctx = - (TS_VERIFY_CTX *)OPENSSL_malloc(sizeof(TS_VERIFY_CTX)); - if (ctx) - memset(ctx, 0, sizeof(TS_VERIFY_CTX)); - else - TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE); - return ctx; -} - -void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx) -{ - OPENSSL_assert(ctx != NULL); - memset(ctx, 0, sizeof(TS_VERIFY_CTX)); -} - -void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx) -{ - if (!ctx) - return; - - TS_VERIFY_CTX_cleanup(ctx); - OPENSSL_free(ctx); -} - -void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx) -{ - if (!ctx) - return; - - X509_STORE_free(ctx->store); - sk_X509_pop_free(ctx->certs, X509_free); - - ASN1_OBJECT_free(ctx->policy); - - X509_ALGOR_free(ctx->md_alg); - OPENSSL_free(ctx->imprint); - - BIO_free_all(ctx->data); - - ASN1_INTEGER_free(ctx->nonce); - - GENERAL_NAME_free(ctx->tsa_name); - - TS_VERIFY_CTX_init(ctx); -} - -TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx) -{ - TS_VERIFY_CTX *ret = ctx; - ASN1_OBJECT *policy; - TS_MSG_IMPRINT *imprint; - X509_ALGOR *md_alg; - ASN1_OCTET_STRING *msg; - const ASN1_INTEGER *nonce; - - OPENSSL_assert(req != NULL); - if (ret) - TS_VERIFY_CTX_cleanup(ret); - else if (!(ret = TS_VERIFY_CTX_new())) - return NULL; - - /* Setting flags. */ - ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE); - - /* Setting policy. */ - if ((policy = TS_REQ_get_policy_id(req)) != NULL) { - if (!(ret->policy = OBJ_dup(policy))) - goto err; - } else - ret->flags &= ~TS_VFY_POLICY; - - /* Setting md_alg, imprint and imprint_len. */ - imprint = TS_REQ_get_msg_imprint(req); - md_alg = TS_MSG_IMPRINT_get_algo(imprint); - if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) - goto err; - msg = TS_MSG_IMPRINT_get_msg(imprint); - ret->imprint_len = ASN1_STRING_length(msg); - if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) - goto err; - memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len); - - /* Setting nonce. */ - if ((nonce = TS_REQ_get_nonce(req)) != NULL) { - if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) - goto err; - } else - ret->flags &= ~TS_VFY_NONCE; - - return ret; - err: - if (ctx) - TS_VERIFY_CTX_cleanup(ctx); - else - TS_VERIFY_CTX_free(ret); - return NULL; -} diff --git a/Sources/COpenSSL/txt_db.c b/Sources/COpenSSL/txt_db.c deleted file mode 100644 index 316bc6aa..00000000 --- a/Sources/COpenSSL/txt_db.c +++ /dev/null @@ -1,398 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/txt_db/txt_db.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include "cryptlib.h" -#include "buffer.h" -#include "txt_db.h" - -#undef BUFSIZE -#define BUFSIZE 512 - -const char TXT_DB_version[] = "TXT_DB" OPENSSL_VERSION_PTEXT; - -TXT_DB *TXT_DB_read(BIO *in, int num) -{ - TXT_DB *ret = NULL; - int er = 1; - int esc = 0; - long ln = 0; - int i, add, n; - int size = BUFSIZE; - int offset = 0; - char *p, *f; - OPENSSL_STRING *pp; - BUF_MEM *buf = NULL; - - if ((buf = BUF_MEM_new()) == NULL) - goto err; - if (!BUF_MEM_grow(buf, size)) - goto err; - - if ((ret = OPENSSL_malloc(sizeof(TXT_DB))) == NULL) - goto err; - ret->num_fields = num; - ret->index = NULL; - ret->qual = NULL; - if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL) - goto err; - if ((ret->index = OPENSSL_malloc(sizeof(*ret->index) * num)) == NULL) - goto err; - if ((ret->qual = OPENSSL_malloc(sizeof(*(ret->qual)) * num)) == NULL) - goto err; - for (i = 0; i < num; i++) { - ret->index[i] = NULL; - ret->qual[i] = NULL; - } - - add = (num + 1) * sizeof(char *); - buf->data[size - 1] = '\0'; - offset = 0; - for (;;) { - if (offset != 0) { - size += BUFSIZE; - if (!BUF_MEM_grow_clean(buf, size)) - goto err; - } - buf->data[offset] = '\0'; - BIO_gets(in, &(buf->data[offset]), size - offset); - ln++; - if (buf->data[offset] == '\0') - break; - if ((offset == 0) && (buf->data[0] == '#')) - continue; - i = strlen(&(buf->data[offset])); - offset += i; - if (buf->data[offset - 1] != '\n') - continue; - else { - buf->data[offset - 1] = '\0'; /* blat the '\n' */ - if (!(p = OPENSSL_malloc(add + offset))) - goto err; - offset = 0; - } - pp = (char **)p; - p += add; - n = 0; - pp[n++] = p; - i = 0; - f = buf->data; - - esc = 0; - for (;;) { - if (*f == '\0') - break; - if (*f == '\t') { - if (esc) - p--; - else { - *(p++) = '\0'; - f++; - if (n >= num) - break; - pp[n++] = p; - continue; - } - } - esc = (*f == '\\'); - *(p++) = *(f++); - } - *(p++) = '\0'; - if ((n != num) || (*f != '\0')) { -#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary - * fix :-( */ - fprintf(stderr, - "wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n", - ln, num, n, f); -#endif - OPENSSL_free(pp); - er = 2; - goto err; - } - pp[n] = p; - if (!sk_OPENSSL_PSTRING_push(ret->data, pp)) { -#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary - * fix :-( */ - fprintf(stderr, "failure in sk_push\n"); -#endif - OPENSSL_free(pp); - er = 2; - goto err; - } - } - er = 0; - err: - BUF_MEM_free(buf); - if (er) { -#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) - if (er == 1) - fprintf(stderr, "OPENSSL_malloc failure\n"); -#endif - if (ret != NULL) { - if (ret->data != NULL) - sk_OPENSSL_PSTRING_free(ret->data); - if (ret->index != NULL) - OPENSSL_free(ret->index); - if (ret->qual != NULL) - OPENSSL_free(ret->qual); - if (ret != NULL) - OPENSSL_free(ret); - } - return (NULL); - } else - return (ret); -} - -OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, - OPENSSL_STRING *value) -{ - OPENSSL_STRING *ret; - LHASH_OF(OPENSSL_STRING) *lh; - - if (idx >= db->num_fields) { - db->error = DB_ERROR_INDEX_OUT_OF_RANGE; - return (NULL); - } - lh = db->index[idx]; - if (lh == NULL) { - db->error = DB_ERROR_NO_INDEX; - return (NULL); - } - ret = lh_OPENSSL_STRING_retrieve(lh, value); - db->error = DB_ERROR_OK; - return (ret); -} - -int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), - LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) -{ - LHASH_OF(OPENSSL_STRING) *idx; - OPENSSL_STRING *r, *k; - int i, n; - - if (field >= db->num_fields) { - db->error = DB_ERROR_INDEX_OUT_OF_RANGE; - return (0); - } - /* FIXME: we lose type checking at this point */ - if ((idx = (LHASH_OF(OPENSSL_STRING) *)lh_new(hash, cmp)) == NULL) { - db->error = DB_ERROR_MALLOC; - return (0); - } - n = sk_OPENSSL_PSTRING_num(db->data); - for (i = 0; i < n; i++) { - r = sk_OPENSSL_PSTRING_value(db->data, i); - if ((qual != NULL) && (qual(r) == 0)) - continue; - if ((k = lh_OPENSSL_STRING_insert(idx, r)) != NULL) { - db->error = DB_ERROR_INDEX_CLASH; - db->arg1 = sk_OPENSSL_PSTRING_find(db->data, k); - db->arg2 = i; - lh_OPENSSL_STRING_free(idx); - return (0); - } - if (lh_OPENSSL_STRING_retrieve(idx, r) == NULL) { - db->error = DB_ERROR_MALLOC; - lh_OPENSSL_STRING_free(idx); - return (0); - } - } - if (db->index[field] != NULL) - lh_OPENSSL_STRING_free(db->index[field]); - db->index[field] = idx; - db->qual[field] = qual; - return (1); -} - -long TXT_DB_write(BIO *out, TXT_DB *db) -{ - long i, j, n, nn, l, tot = 0; - char *p, **pp, *f; - BUF_MEM *buf = NULL; - long ret = -1; - - if ((buf = BUF_MEM_new()) == NULL) - goto err; - n = sk_OPENSSL_PSTRING_num(db->data); - nn = db->num_fields; - for (i = 0; i < n; i++) { - pp = sk_OPENSSL_PSTRING_value(db->data, i); - - l = 0; - for (j = 0; j < nn; j++) { - if (pp[j] != NULL) - l += strlen(pp[j]); - } - if (!BUF_MEM_grow_clean(buf, (int)(l * 2 + nn))) - goto err; - - p = buf->data; - for (j = 0; j < nn; j++) { - f = pp[j]; - if (f != NULL) - for (;;) { - if (*f == '\0') - break; - if (*f == '\t') - *(p++) = '\\'; - *(p++) = *(f++); - } - *(p++) = '\t'; - } - p[-1] = '\n'; - j = p - buf->data; - if (BIO_write(out, buf->data, (int)j) != j) - goto err; - tot += j; - } - ret = tot; - err: - if (buf != NULL) - BUF_MEM_free(buf); - return (ret); -} - -int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row) -{ - int i; - OPENSSL_STRING *r; - - for (i = 0; i < db->num_fields; i++) { - if (db->index[i] != NULL) { - if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) - continue; - r = lh_OPENSSL_STRING_retrieve(db->index[i], row); - if (r != NULL) { - db->error = DB_ERROR_INDEX_CLASH; - db->arg1 = i; - db->arg_row = r; - goto err; - } - } - } - - for (i = 0; i < db->num_fields; i++) { - if (db->index[i] != NULL) { - if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) - continue; - (void)lh_OPENSSL_STRING_insert(db->index[i], row); - if (lh_OPENSSL_STRING_retrieve(db->index[i], row) == NULL) - goto err1; - } - } - if (!sk_OPENSSL_PSTRING_push(db->data, row)) - goto err1; - return (1); - - err1: - db->error = DB_ERROR_MALLOC; - while (i-- > 0) { - if (db->index[i] != NULL) { - if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) - continue; - (void)lh_OPENSSL_STRING_delete(db->index[i], row); - } - } - err: - return (0); -} - -void TXT_DB_free(TXT_DB *db) -{ - int i, n; - char **p, *max; - - if (db == NULL) - return; - - if (db->index != NULL) { - for (i = db->num_fields - 1; i >= 0; i--) - if (db->index[i] != NULL) - lh_OPENSSL_STRING_free(db->index[i]); - OPENSSL_free(db->index); - } - if (db->qual != NULL) - OPENSSL_free(db->qual); - if (db->data != NULL) { - for (i = sk_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) { - /* - * check if any 'fields' have been allocated from outside of the - * initial block - */ - p = sk_OPENSSL_PSTRING_value(db->data, i); - max = p[db->num_fields]; /* last address */ - if (max == NULL) { /* new row */ - for (n = 0; n < db->num_fields; n++) - if (p[n] != NULL) - OPENSSL_free(p[n]); - } else { - for (n = 0; n < db->num_fields; n++) { - if (((p[n] < (char *)p) || (p[n] > max)) - && (p[n] != NULL)) - OPENSSL_free(p[n]); - } - } - OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data, i)); - } - sk_OPENSSL_PSTRING_free(db->data); - } - OPENSSL_free(db); -} diff --git a/Sources/COpenSSL/txt_db.h b/Sources/COpenSSL/txt_db.h deleted file mode 100644 index e16e960e..00000000 --- a/Sources/COpenSSL/txt_db.h +++ /dev/null @@ -1,112 +0,0 @@ -/* crypto/txt_db/txt_db.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_TXT_DB_H -# define HEADER_TXT_DB_H - -# include "opensslconf.h" -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# include "stack.h" -# include "lhash.h" - -# define DB_ERROR_OK 0 -# define DB_ERROR_MALLOC 1 -# define DB_ERROR_INDEX_CLASH 2 -# define DB_ERROR_INDEX_OUT_OF_RANGE 3 -# define DB_ERROR_NO_INDEX 4 -# define DB_ERROR_INSERT_INDEX_CLASH 5 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef OPENSSL_STRING *OPENSSL_PSTRING; -DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) - -typedef struct txt_db_st { - int num_fields; - STACK_OF(OPENSSL_PSTRING) *data; - LHASH_OF(OPENSSL_STRING) **index; - int (**qual) (OPENSSL_STRING *); - long error; - long arg1; - long arg2; - OPENSSL_STRING *arg_row; -} TXT_DB; - -# ifndef OPENSSL_NO_BIO -TXT_DB *TXT_DB_read(BIO *in, int num); -long TXT_DB_write(BIO *out, TXT_DB *db); -# else -TXT_DB *TXT_DB_read(char *in, int num); -long TXT_DB_write(char *out, TXT_DB *db); -# endif -int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), - LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); -void TXT_DB_free(TXT_DB *db); -OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, - OPENSSL_STRING *value); -int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/ui.h b/Sources/COpenSSL/ui.h deleted file mode 100644 index f6154e07..00000000 --- a/Sources/COpenSSL/ui.h +++ /dev/null @@ -1,415 +0,0 @@ -/* crypto/ui/ui.h */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_UI_H -# define HEADER_UI_H - -# ifndef OPENSSL_NO_DEPRECATED -# include "crypto.h" -# endif -# include "safestack.h" -# include "ossl_typ.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Declared already in ossl_typ.h */ -/* typedef struct ui_st UI; */ -/* typedef struct ui_method_st UI_METHOD; */ - -/* - * All the following functions return -1 or NULL on error and in some cases - * (UI_process()) -2 if interrupted or in some other way cancelled. When - * everything is fine, they return 0, a positive value or a non-NULL pointer, - * all depending on their purpose. - */ - -/* Creators and destructor. */ -UI *UI_new(void); -UI *UI_new_method(const UI_METHOD *method); -void UI_free(UI *ui); - -/*- - The following functions are used to add strings to be printed and prompt - strings to prompt for data. The names are UI_{add,dup}__string - and UI_{add,dup}_input_boolean. - - UI_{add,dup}__string have the following meanings: - add add a text or prompt string. The pointers given to these - functions are used verbatim, no copying is done. - dup make a copy of the text or prompt string, then add the copy - to the collection of strings in the user interface. - - The function is a name for the functionality that the given - string shall be used for. It can be one of: - input use the string as data prompt. - verify use the string as verification prompt. This - is used to verify a previous input. - info use the string for informational output. - error use the string for error output. - Honestly, there's currently no difference between info and error for the - moment. - - UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", - and are typically used when one wants to prompt for a yes/no response. - - All of the functions in this group take a UI and a prompt string. - The string input and verify addition functions also take a flag argument, - a buffer for the result to end up with, a minimum input size and a maximum - input size (the result buffer MUST be large enough to be able to contain - the maximum number of characters). Additionally, the verify addition - functions takes another buffer to compare the result against. - The boolean input functions take an action description string (which should - be safe to ignore if the expected user action is obvious, for example with - a dialog box with an OK button and a Cancel button), a string of acceptable - characters to mean OK and to mean Cancel. The two last strings are checked - to make sure they don't have common characters. Additionally, the same - flag argument as for the string input is taken, as well as a result buffer. - The result buffer is required to be at least one byte long. Depending on - the answer, the first character from the OK or the Cancel character strings - will be stored in the first byte of the result buffer. No NUL will be - added, so the result is *not* a string. - - On success, the all return an index of the added information. That index - is usefull when retrieving results with UI_get0_result(). */ -int UI_add_input_string(UI *ui, const char *prompt, int flags, - char *result_buf, int minsize, int maxsize); -int UI_dup_input_string(UI *ui, const char *prompt, int flags, - char *result_buf, int minsize, int maxsize); -int UI_add_verify_string(UI *ui, const char *prompt, int flags, - char *result_buf, int minsize, int maxsize, - const char *test_buf); -int UI_dup_verify_string(UI *ui, const char *prompt, int flags, - char *result_buf, int minsize, int maxsize, - const char *test_buf); -int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, - const char *ok_chars, const char *cancel_chars, - int flags, char *result_buf); -int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, - const char *ok_chars, const char *cancel_chars, - int flags, char *result_buf); -int UI_add_info_string(UI *ui, const char *text); -int UI_dup_info_string(UI *ui, const char *text); -int UI_add_error_string(UI *ui, const char *text); -int UI_dup_error_string(UI *ui, const char *text); - -/* These are the possible flags. They can be or'ed together. */ -/* Use to have echoing of input */ -# define UI_INPUT_FLAG_ECHO 0x01 -/* - * Use a default password. Where that password is found is completely up to - * the application, it might for example be in the user data set with - * UI_add_user_data(). It is not recommended to have more than one input in - * each UI being marked with this flag, or the application might get - * confused. - */ -# define UI_INPUT_FLAG_DEFAULT_PWD 0x02 - -/*- - * The user of these routines may want to define flags of their own. The core - * UI won't look at those, but will pass them on to the method routines. They - * must use higher bits so they don't get confused with the UI bits above. - * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good - * example of use is this: - * - * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) - * -*/ -# define UI_INPUT_FLAG_USER_BASE 16 - -/*- - * The following function helps construct a prompt. object_desc is a - * textual short description of the object, for example "pass phrase", - * and object_name is the name of the object (might be a card name or - * a file name. - * The returned string shall always be allocated on the heap with - * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). - * - * If the ui_method doesn't contain a pointer to a user-defined prompt - * constructor, a default string is built, looking like this: - * - * "Enter {object_desc} for {object_name}:" - * - * So, if object_desc has the value "pass phrase" and object_name has - * the value "foo.key", the resulting string is: - * - * "Enter pass phrase for foo.key:" -*/ -char *UI_construct_prompt(UI *ui_method, - const char *object_desc, const char *object_name); - -/* - * The following function is used to store a pointer to user-specific data. - * Any previous such pointer will be returned and replaced. - * - * For callback purposes, this function makes a lot more sense than using - * ex_data, since the latter requires that different parts of OpenSSL or - * applications share the same ex_data index. - * - * Note that the UI_OpenSSL() method completely ignores the user data. Other - * methods may not, however. - */ -void *UI_add_user_data(UI *ui, void *user_data); -/* We need a user data retrieving function as well. */ -void *UI_get0_user_data(UI *ui); - -/* Return the result associated with a prompt given with the index i. */ -const char *UI_get0_result(UI *ui, int i); - -/* When all strings have been added, process the whole thing. */ -int UI_process(UI *ui); - -/* - * Give a user interface parametrised control commands. This can be used to - * send down an integer, a data pointer or a function pointer, as well as be - * used to get information from a UI. - */ -int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)); - -/* The commands */ -/* - * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the - * OpenSSL error stack before printing any info or added error messages and - * before any prompting. - */ -# define UI_CTRL_PRINT_ERRORS 1 -/* - * Check if a UI_process() is possible to do again with the same instance of - * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 - * if not. - */ -# define UI_CTRL_IS_REDOABLE 2 - -/* Some methods may use extra data */ -# define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) -# define UI_get_app_data(s) UI_get_ex_data(s,0) -int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int UI_set_ex_data(UI *r, int idx, void *arg); -void *UI_get_ex_data(UI *r, int idx); - -/* Use specific methods instead of the built-in one */ -void UI_set_default_method(const UI_METHOD *meth); -const UI_METHOD *UI_get_default_method(void); -const UI_METHOD *UI_get_method(UI *ui); -const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); - -/* The method with all the built-in thingies */ -UI_METHOD *UI_OpenSSL(void); - -/* ---------- For method writers ---------- */ -/*- - A method contains a number of functions that implement the low level - of the User Interface. The functions are: - - an opener This function starts a session, maybe by opening - a channel to a tty, or by opening a window. - a writer This function is called to write a given string, - maybe to the tty, maybe as a field label in a - window. - a flusher This function is called to flush everything that - has been output so far. It can be used to actually - display a dialog box after it has been built. - a reader This function is called to read a given prompt, - maybe from the tty, maybe from a field in a - window. Note that it's called wth all string - structures, not only the prompt ones, so it must - check such things itself. - a closer This function closes the session, maybe by closing - the channel to the tty, or closing the window. - - All these functions are expected to return: - - 0 on error. - 1 on success. - -1 on out-of-band events, for example if some prompting has - been canceled (by pressing Ctrl-C, for example). This is - only checked when returned by the flusher or the reader. - - The way this is used, the opener is first called, then the writer for all - strings, then the flusher, then the reader for all strings and finally the - closer. Note that if you want to prompt from a terminal or other command - line interface, the best is to have the reader also write the prompts - instead of having the writer do it. If you want to prompt from a dialog - box, the writer can be used to build up the contents of the box, and the - flusher to actually display the box and run the event loop until all data - has been given, after which the reader only grabs the given data and puts - them back into the UI strings. - - All method functions take a UI as argument. Additionally, the writer and - the reader take a UI_STRING. -*/ - -/* - * The UI_STRING type is the data structure that contains all the needed info - * about a string or a prompt, including test data for a verification prompt. - */ -typedef struct ui_string_st UI_STRING; -DECLARE_STACK_OF(UI_STRING) - -/* - * The different types of strings that are currently supported. This is only - * needed by method authors. - */ -enum UI_string_types { - UIT_NONE = 0, - UIT_PROMPT, /* Prompt for a string */ - UIT_VERIFY, /* Prompt for a string and verify */ - UIT_BOOLEAN, /* Prompt for a yes/no response */ - UIT_INFO, /* Send info to the user */ - UIT_ERROR /* Send an error message to the user */ -}; - -/* Create and manipulate methods */ -UI_METHOD *UI_create_method(char *name); -void UI_destroy_method(UI_METHOD *ui_method); -int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)); -int UI_method_set_writer(UI_METHOD *method, - int (*writer) (UI *ui, UI_STRING *uis)); -int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)); -int UI_method_set_reader(UI_METHOD *method, - int (*reader) (UI *ui, UI_STRING *uis)); -int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)); -int UI_method_set_prompt_constructor(UI_METHOD *method, - char *(*prompt_constructor) (UI *ui, - const char - *object_desc, - const char - *object_name)); -int (*UI_method_get_opener(UI_METHOD *method)) (UI *); -int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *); -int (*UI_method_get_flusher(UI_METHOD *method)) (UI *); -int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *); -int (*UI_method_get_closer(UI_METHOD *method)) (UI *); -char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *, - const char *, - const char *); - -/* - * The following functions are helpers for method writers to access relevant - * data from a UI_STRING. - */ - -/* Return type of the UI_STRING */ -enum UI_string_types UI_get_string_type(UI_STRING *uis); -/* Return input flags of the UI_STRING */ -int UI_get_input_flags(UI_STRING *uis); -/* Return the actual string to output (the prompt, info or error) */ -const char *UI_get0_output_string(UI_STRING *uis); -/* - * Return the optional action string to output (the boolean promtp - * instruction) - */ -const char *UI_get0_action_string(UI_STRING *uis); -/* Return the result of a prompt */ -const char *UI_get0_result_string(UI_STRING *uis); -/* - * Return the string to test the result against. Only useful with verifies. - */ -const char *UI_get0_test_string(UI_STRING *uis); -/* Return the required minimum size of the result */ -int UI_get_result_minsize(UI_STRING *uis); -/* Return the required maximum size of the result */ -int UI_get_result_maxsize(UI_STRING *uis); -/* Set the result of a UI_STRING. */ -int UI_set_result(UI *ui, UI_STRING *uis, const char *result); - -/* A couple of popular utility functions */ -int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, - int verify); -int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, - int verify); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_UI_strings(void); - -/* Error codes for the UI functions. */ - -/* Function codes. */ -# define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 -# define UI_F_GENERAL_ALLOCATE_PROMPT 109 -# define UI_F_GENERAL_ALLOCATE_STRING 100 -# define UI_F_UI_CTRL 111 -# define UI_F_UI_DUP_ERROR_STRING 101 -# define UI_F_UI_DUP_INFO_STRING 102 -# define UI_F_UI_DUP_INPUT_BOOLEAN 110 -# define UI_F_UI_DUP_INPUT_STRING 103 -# define UI_F_UI_DUP_VERIFY_STRING 106 -# define UI_F_UI_GET0_RESULT 107 -# define UI_F_UI_NEW_METHOD 104 -# define UI_F_UI_SET_RESULT 105 - -/* Reason codes. */ -# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 -# define UI_R_INDEX_TOO_LARGE 102 -# define UI_R_INDEX_TOO_SMALL 103 -# define UI_R_NO_RESULT_BUFFER 105 -# define UI_R_RESULT_TOO_LARGE 100 -# define UI_R_RESULT_TOO_SMALL 101 -# define UI_R_UNKNOWN_CONTROL_COMMAND 106 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ui_.c b/Sources/COpenSSL/ui_.c deleted file mode 100644 index 0313f443..00000000 --- a/Sources/COpenSSL/ui_.c +++ /dev/null @@ -1,1900 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/ui/ui_compat.c */ -/* ==================================================================== - * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "ui_compat.h" - -int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, - int verify) -{ - return UI_UTIL_read_pw_string(buf, length, prompt, verify); -} - -int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, - int verify) -{ - return UI_UTIL_read_pw(buf, buff, size, prompt, verify); -} -/* crypto/ui/ui_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "ui.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_UI,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_UI,0,reason) - -static ERR_STRING_DATA UI_str_functs[] = { - {ERR_FUNC(UI_F_GENERAL_ALLOCATE_BOOLEAN), "GENERAL_ALLOCATE_BOOLEAN"}, - {ERR_FUNC(UI_F_GENERAL_ALLOCATE_PROMPT), "GENERAL_ALLOCATE_PROMPT"}, - {ERR_FUNC(UI_F_GENERAL_ALLOCATE_STRING), "GENERAL_ALLOCATE_STRING"}, - {ERR_FUNC(UI_F_UI_CTRL), "UI_ctrl"}, - {ERR_FUNC(UI_F_UI_DUP_ERROR_STRING), "UI_dup_error_string"}, - {ERR_FUNC(UI_F_UI_DUP_INFO_STRING), "UI_dup_info_string"}, - {ERR_FUNC(UI_F_UI_DUP_INPUT_BOOLEAN), "UI_dup_input_boolean"}, - {ERR_FUNC(UI_F_UI_DUP_INPUT_STRING), "UI_dup_input_string"}, - {ERR_FUNC(UI_F_UI_DUP_VERIFY_STRING), "UI_dup_verify_string"}, - {ERR_FUNC(UI_F_UI_GET0_RESULT), "UI_get0_result"}, - {ERR_FUNC(UI_F_UI_NEW_METHOD), "UI_new_method"}, - {ERR_FUNC(UI_F_UI_SET_RESULT), "UI_set_result"}, - {0, NULL} -}; - -static ERR_STRING_DATA UI_str_reasons[] = { - {ERR_REASON(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS), - "common ok and cancel characters"}, - {ERR_REASON(UI_R_INDEX_TOO_LARGE), "index too large"}, - {ERR_REASON(UI_R_INDEX_TOO_SMALL), "index too small"}, - {ERR_REASON(UI_R_NO_RESULT_BUFFER), "no result buffer"}, - {ERR_REASON(UI_R_RESULT_TOO_LARGE), "result too large"}, - {ERR_REASON(UI_R_RESULT_TOO_SMALL), "result too small"}, - {ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND), "unknown control command"}, - {0, NULL} -}; - -#endif - -void ERR_load_UI_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(UI_str_functs[0].error) == NULL) { - ERR_load_strings(0, UI_str_functs); - ERR_load_strings(0, UI_str_reasons); - } -#endif -} -/* crypto/ui/ui_lib.c */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "e_os2.h" -#include "buffer.h" -// #include "ui.h" -// #include "err.h" -#include "ui_locl.h" - -IMPLEMENT_STACK_OF(UI_STRING_ST) - -static const UI_METHOD *default_UI_meth = NULL; - -UI *UI_new(void) -{ - return (UI_new_method(NULL)); -} - -UI *UI_new_method(const UI_METHOD *method) -{ - UI *ret; - - ret = (UI *)OPENSSL_malloc(sizeof(UI)); - if (ret == NULL) { - UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE); - return NULL; - } - if (method == NULL) - ret->meth = UI_get_default_method(); - else - ret->meth = method; - - ret->strings = NULL; - ret->user_data = NULL; - ret->flags = 0; - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data); - return ret; -} - -static void free_string(UI_STRING *uis) -{ - if (uis->flags & OUT_STRING_FREEABLE) { - OPENSSL_free((char *)uis->out_string); - switch (uis->type) { - case UIT_BOOLEAN: - OPENSSL_free((char *)uis->_.boolean_data.action_desc); - OPENSSL_free((char *)uis->_.boolean_data.ok_chars); - OPENSSL_free((char *)uis->_.boolean_data.cancel_chars); - break; - default: - break; - } - } - OPENSSL_free(uis); -} - -void UI_free(UI *ui) -{ - if (ui == NULL) - return; - sk_UI_STRING_pop_free(ui->strings, free_string); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data); - OPENSSL_free(ui); -} - -static int allocate_string_stack(UI *ui) -{ - if (ui->strings == NULL) { - ui->strings = sk_UI_STRING_new_null(); - if (ui->strings == NULL) { - return -1; - } - } - return 0; -} - -static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt, - int prompt_freeable, - enum UI_string_types type, - int input_flags, char *result_buf) -{ - UI_STRING *ret = NULL; - - if (prompt == NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, ERR_R_PASSED_NULL_PARAMETER); - } else if ((type == UIT_PROMPT || type == UIT_VERIFY - || type == UIT_BOOLEAN) && result_buf == NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, UI_R_NO_RESULT_BUFFER); - } else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING)))) { - ret->out_string = prompt; - ret->flags = prompt_freeable ? OUT_STRING_FREEABLE : 0; - ret->input_flags = input_flags; - ret->type = type; - ret->result_buf = result_buf; - } - return ret; -} - -static int general_allocate_string(UI *ui, const char *prompt, - int prompt_freeable, - enum UI_string_types type, int input_flags, - char *result_buf, int minsize, int maxsize, - const char *test_buf) -{ - int ret = -1; - UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable, - type, input_flags, result_buf); - - if (s != NULL) { - if (allocate_string_stack(ui) >= 0) { - s->_.string_data.result_minsize = minsize; - s->_.string_data.result_maxsize = maxsize; - s->_.string_data.test_buf = test_buf; - ret = sk_UI_STRING_push(ui->strings, s); - /* sk_push() returns 0 on error. Let's addapt that */ - if (ret <= 0) - ret--; - } else - free_string(s); - } - return ret; -} - -static int general_allocate_boolean(UI *ui, - const char *prompt, - const char *action_desc, - const char *ok_chars, - const char *cancel_chars, - int prompt_freeable, - enum UI_string_types type, - int input_flags, char *result_buf) -{ - int ret = -1; - UI_STRING *s; - const char *p; - - if (ok_chars == NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER); - } else if (cancel_chars == NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER); - } else { - for (p = ok_chars; *p != '\0'; p++) { - if (strchr(cancel_chars, *p) != NULL) { - UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, - UI_R_COMMON_OK_AND_CANCEL_CHARACTERS); - } - } - - s = general_allocate_prompt(ui, prompt, prompt_freeable, - type, input_flags, result_buf); - - if (s != NULL) { - if (allocate_string_stack(ui) >= 0) { - s->_.boolean_data.action_desc = action_desc; - s->_.boolean_data.ok_chars = ok_chars; - s->_.boolean_data.cancel_chars = cancel_chars; - ret = sk_UI_STRING_push(ui->strings, s); - /* - * sk_push() returns 0 on error. Let's addapt that - */ - if (ret <= 0) - ret--; - } else - free_string(s); - } - } - return ret; -} - -/* - * Returns the index to the place in the stack or -1 for error. Uses a - * direct reference to the prompt. - */ -int UI_add_input_string(UI *ui, const char *prompt, int flags, - char *result_buf, int minsize, int maxsize) -{ - return general_allocate_string(ui, prompt, 0, - UIT_PROMPT, flags, result_buf, minsize, - maxsize, NULL); -} - -/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */ -int UI_dup_input_string(UI *ui, const char *prompt, int flags, - char *result_buf, int minsize, int maxsize) -{ - char *prompt_copy = NULL; - - if (prompt != NULL) { - prompt_copy = BUF_strdup(prompt); - if (prompt_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE); - return 0; - } - } - - return general_allocate_string(ui, prompt_copy, 1, - UIT_PROMPT, flags, result_buf, minsize, - maxsize, NULL); -} - -int UI_add_verify_string(UI *ui, const char *prompt, int flags, - char *result_buf, int minsize, int maxsize, - const char *test_buf) -{ - return general_allocate_string(ui, prompt, 0, - UIT_VERIFY, flags, result_buf, minsize, - maxsize, test_buf); -} - -int UI_dup_verify_string(UI *ui, const char *prompt, int flags, - char *result_buf, int minsize, int maxsize, - const char *test_buf) -{ - char *prompt_copy = NULL; - - if (prompt != NULL) { - prompt_copy = BUF_strdup(prompt); - if (prompt_copy == NULL) { - UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE); - return -1; - } - } - - return general_allocate_string(ui, prompt_copy, 1, - UIT_VERIFY, flags, result_buf, minsize, - maxsize, test_buf); -} - -int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, - const char *ok_chars, const char *cancel_chars, - int flags, char *result_buf) -{ - return general_allocate_boolean(ui, prompt, action_desc, - ok_chars, cancel_chars, 0, UIT_BOOLEAN, - flags, result_buf); -} - -int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, - const char *ok_chars, const char *cancel_chars, - int flags, char *result_buf) -{ - char *prompt_copy = NULL; - char *action_desc_copy = NULL; - char *ok_chars_copy = NULL; - char *cancel_chars_copy = NULL; - - if (prompt != NULL) { - prompt_copy = BUF_strdup(prompt); - if (prompt_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (action_desc != NULL) { - action_desc_copy = BUF_strdup(action_desc); - if (action_desc_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (ok_chars != NULL) { - ok_chars_copy = BUF_strdup(ok_chars); - if (ok_chars_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - if (cancel_chars != NULL) { - cancel_chars_copy = BUF_strdup(cancel_chars); - if (cancel_chars_copy == NULL) { - UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - return general_allocate_boolean(ui, prompt_copy, action_desc_copy, - ok_chars_copy, cancel_chars_copy, 1, - UIT_BOOLEAN, flags, result_buf); - err: - if (prompt_copy) - OPENSSL_free(prompt_copy); - if (action_desc_copy) - OPENSSL_free(action_desc_copy); - if (ok_chars_copy) - OPENSSL_free(ok_chars_copy); - if (cancel_chars_copy) - OPENSSL_free(cancel_chars_copy); - return -1; -} - -int UI_add_info_string(UI *ui, const char *text) -{ - return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0, - NULL); -} - -int UI_dup_info_string(UI *ui, const char *text) -{ - char *text_copy = NULL; - - if (text != NULL) { - text_copy = BUF_strdup(text); - if (text_copy == NULL) { - UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE); - return -1; - } - } - - return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL, - 0, 0, NULL); -} - -int UI_add_error_string(UI *ui, const char *text) -{ - return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0, - NULL); -} - -int UI_dup_error_string(UI *ui, const char *text) -{ - char *text_copy = NULL; - - if (text != NULL) { - text_copy = BUF_strdup(text); - if (text_copy == NULL) { - UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE); - return -1; - } - } - return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL, - 0, 0, NULL); -} - -char *UI_construct_prompt(UI *ui, const char *object_desc, - const char *object_name) -{ - char *prompt = NULL; - - if (ui->meth->ui_construct_prompt != NULL) - prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name); - else { - char prompt1[] = "Enter "; - char prompt2[] = " for "; - char prompt3[] = ":"; - int len = 0; - - if (object_desc == NULL) - return NULL; - len = sizeof(prompt1) - 1 + strlen(object_desc); - if (object_name != NULL) - len += sizeof(prompt2) - 1 + strlen(object_name); - len += sizeof(prompt3) - 1; - - prompt = (char *)OPENSSL_malloc(len + 1); - if (prompt == NULL) - return NULL; - BUF_strlcpy(prompt, prompt1, len + 1); - BUF_strlcat(prompt, object_desc, len + 1); - if (object_name != NULL) { - BUF_strlcat(prompt, prompt2, len + 1); - BUF_strlcat(prompt, object_name, len + 1); - } - BUF_strlcat(prompt, prompt3, len + 1); - } - return prompt; -} - -void *UI_add_user_data(UI *ui, void *user_data) -{ - void *old_data = ui->user_data; - ui->user_data = user_data; - return old_data; -} - -void *UI_get0_user_data(UI *ui) -{ - return ui->user_data; -} - -const char *UI_get0_result(UI *ui, int i) -{ - if (i < 0) { - UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL); - return NULL; - } - if (i >= sk_UI_STRING_num(ui->strings)) { - UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE); - return NULL; - } - return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i)); -} - -static int print_error(const char *str, size_t len, UI *ui) -{ - UI_STRING uis; - - memset(&uis, 0, sizeof(uis)); - uis.type = UIT_ERROR; - uis.out_string = str; - - if (ui->meth->ui_write_string != NULL - && ui->meth->ui_write_string(ui, &uis) <= 0) - return -1; - return 0; -} - -int UI_process(UI *ui) -{ - int i, ok = 0; - - if (ui->meth->ui_open_session != NULL - && ui->meth->ui_open_session(ui) <= 0) { - ok = -1; - goto err; - } - - if (ui->flags & UI_FLAG_PRINT_ERRORS) - ERR_print_errors_cb((int (*)(const char *, size_t, void *)) - print_error, (void *)ui); - - for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) { - if (ui->meth->ui_write_string != NULL - && (ui->meth->ui_write_string(ui, - sk_UI_STRING_value(ui->strings, i)) - <= 0)) - { - ok = -1; - goto err; - } - } - - if (ui->meth->ui_flush != NULL) - switch (ui->meth->ui_flush(ui)) { - case -1: /* Interrupt/Cancel/something... */ - ok = -2; - goto err; - case 0: /* Errors */ - ok = -1; - goto err; - default: /* Success */ - ok = 0; - break; - } - - for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) { - if (ui->meth->ui_read_string != NULL) { - switch (ui->meth->ui_read_string(ui, - sk_UI_STRING_value(ui->strings, - i))) { - case -1: /* Interrupt/Cancel/something... */ - ok = -2; - goto err; - case 0: /* Errors */ - ok = -1; - goto err; - default: /* Success */ - ok = 0; - break; - } - } - } - - err: - if (ui->meth->ui_close_session != NULL - && ui->meth->ui_close_session(ui) <= 0) - return -1; - return ok; -} - -int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)) -{ - if (ui == NULL) { - UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER); - return -1; - } - switch (cmd) { - case UI_CTRL_PRINT_ERRORS: - { - int save_flag = ! !(ui->flags & UI_FLAG_PRINT_ERRORS); - if (i) - ui->flags |= UI_FLAG_PRINT_ERRORS; - else - ui->flags &= ~UI_FLAG_PRINT_ERRORS; - return save_flag; - } - case UI_CTRL_IS_REDOABLE: - return ! !(ui->flags & UI_FLAG_REDOABLE); - default: - break; - } - UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND); - return -1; -} - -int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp, - new_func, dup_func, free_func); -} - -int UI_set_ex_data(UI *r, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); -} - -void *UI_get_ex_data(UI *r, int idx) -{ - return (CRYPTO_get_ex_data(&r->ex_data, idx)); -} - -void UI_set_default_method(const UI_METHOD *meth) -{ - default_UI_meth = meth; -} - -const UI_METHOD *UI_get_default_method(void) -{ - if (default_UI_meth == NULL) { - default_UI_meth = UI_OpenSSL(); - } - return default_UI_meth; -} - -const UI_METHOD *UI_get_method(UI *ui) -{ - return ui->meth; -} - -const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth) -{ - ui->meth = meth; - return ui->meth; -} - -UI_METHOD *UI_create_method(char *name) -{ - UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD)); - - if (ui_method) { - memset(ui_method, 0, sizeof(*ui_method)); - ui_method->name = BUF_strdup(name); - } - return ui_method; -} - -/* - * BIG FSCKING WARNING!!!! If you use this on a statically allocated method - * (that is, it hasn't been allocated using UI_create_method(), you deserve - * anything Murphy can throw at you and more! You have been warned. - */ -void UI_destroy_method(UI_METHOD *ui_method) -{ - OPENSSL_free(ui_method->name); - ui_method->name = NULL; - OPENSSL_free(ui_method); -} - -int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)) -{ - if (method != NULL) { - method->ui_open_session = opener; - return 0; - } - return -1; -} - -int UI_method_set_writer(UI_METHOD *method, - int (*writer) (UI *ui, UI_STRING *uis)) -{ - if (method != NULL) { - method->ui_write_string = writer; - return 0; - } - return -1; -} - -int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)) -{ - if (method != NULL) { - method->ui_flush = flusher; - return 0; - } - return -1; -} - -int UI_method_set_reader(UI_METHOD *method, - int (*reader) (UI *ui, UI_STRING *uis)) -{ - if (method != NULL) { - method->ui_read_string = reader; - return 0; - } - return -1; -} - -int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)) -{ - if (method != NULL) { - method->ui_close_session = closer; - return 0; - } - return -1; -} - -int UI_method_set_prompt_constructor(UI_METHOD *method, - char *(*prompt_constructor) (UI *ui, - const char - *object_desc, - const char - *object_name)) -{ - if (method != NULL) { - method->ui_construct_prompt = prompt_constructor; - return 0; - } - return -1; -} - -int (*UI_method_get_opener(UI_METHOD *method)) (UI *) -{ - if (method != NULL) - return method->ui_open_session; - return NULL; -} - -int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) -{ - if (method != NULL) - return method->ui_write_string; - return NULL; -} - -int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) -{ - if (method != NULL) - return method->ui_flush; - return NULL; -} - -int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) -{ - if (method != NULL) - return method->ui_read_string; - return NULL; -} - -int (*UI_method_get_closer(UI_METHOD *method)) (UI *) -{ - if (method != NULL) - return method->ui_close_session; - return NULL; -} - -char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *, - const char *, - const char *) -{ - if (method != NULL) - return method->ui_construct_prompt; - return NULL; -} - -enum UI_string_types UI_get_string_type(UI_STRING *uis) -{ - if (!uis) - return UIT_NONE; - return uis->type; -} - -int UI_get_input_flags(UI_STRING *uis) -{ - if (!uis) - return 0; - return uis->input_flags; -} - -const char *UI_get0_output_string(UI_STRING *uis) -{ - if (!uis) - return NULL; - return uis->out_string; -} - -const char *UI_get0_action_string(UI_STRING *uis) -{ - if (!uis) - return NULL; - switch (uis->type) { - case UIT_BOOLEAN: - return uis->_.boolean_data.action_desc; - default: - return NULL; - } -} - -const char *UI_get0_result_string(UI_STRING *uis) -{ - if (!uis) - return NULL; - switch (uis->type) { - case UIT_PROMPT: - case UIT_VERIFY: - return uis->result_buf; - default: - return NULL; - } -} - -const char *UI_get0_test_string(UI_STRING *uis) -{ - if (!uis) - return NULL; - switch (uis->type) { - case UIT_VERIFY: - return uis->_.string_data.test_buf; - default: - return NULL; - } -} - -int UI_get_result_minsize(UI_STRING *uis) -{ - if (!uis) - return -1; - switch (uis->type) { - case UIT_PROMPT: - case UIT_VERIFY: - return uis->_.string_data.result_minsize; - default: - return -1; - } -} - -int UI_get_result_maxsize(UI_STRING *uis) -{ - if (!uis) - return -1; - switch (uis->type) { - case UIT_PROMPT: - case UIT_VERIFY: - return uis->_.string_data.result_maxsize; - default: - return -1; - } -} - -int UI_set_result(UI *ui, UI_STRING *uis, const char *result) -{ - int l = strlen(result); - - ui->flags &= ~UI_FLAG_REDOABLE; - - if (!uis) - return -1; - switch (uis->type) { - case UIT_PROMPT: - case UIT_VERIFY: - { - char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1]; - char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1]; - - BIO_snprintf(number1, sizeof(number1), "%d", - uis->_.string_data.result_minsize); - BIO_snprintf(number2, sizeof(number2), "%d", - uis->_.string_data.result_maxsize); - - if (l < uis->_.string_data.result_minsize) { - ui->flags |= UI_FLAG_REDOABLE; - UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_SMALL); - ERR_add_error_data(5, "You must type in ", - number1, " to ", number2, " characters"); - return -1; - } - if (l > uis->_.string_data.result_maxsize) { - ui->flags |= UI_FLAG_REDOABLE; - UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_LARGE); - ERR_add_error_data(5, "You must type in ", - number1, " to ", number2, " characters"); - return -1; - } - } - - if (!uis->result_buf) { - UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER); - return -1; - } - - BUF_strlcpy(uis->result_buf, result, - uis->_.string_data.result_maxsize + 1); - break; - case UIT_BOOLEAN: - { - const char *p; - - if (!uis->result_buf) { - UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER); - return -1; - } - - uis->result_buf[0] = '\0'; - for (p = result; *p; p++) { - if (strchr(uis->_.boolean_data.ok_chars, *p)) { - uis->result_buf[0] = uis->_.boolean_data.ok_chars[0]; - break; - } - if (strchr(uis->_.boolean_data.cancel_chars, *p)) { - uis->result_buf[0] = uis->_.boolean_data.cancel_chars[0]; - break; - } - } - } - default: - break; - } - return 0; -} -/* crypto/ui/ui_openssl.c */ -/* - * Written by Richard Levitte (richard@levitte.org) and others for the - * OpenSSL project 2001. - */ -/* ==================================================================== - * Copyright (c) 2001-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/*- - * The lowest level part of this file was previously in crypto/des/read_pwd.c, - * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -// #include "e_os2.h" - -/* - * need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc - * [maybe others?], because it masks interfaces not discussed in standard, - * sigaction and fileno included. -pedantic would be more appropriate for the - * intended purposes, but we can't prevent users from adding -ansi. - */ -#if defined(OPENSSL_SYSNAME_VXWORKS) -# include -#endif - -#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) -# ifndef _POSIX_C_SOURCE -# define _POSIX_C_SOURCE 2 -# endif -#endif -#include -#include -#include -#include - -#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) -# ifdef OPENSSL_UNISTD -# include OPENSSL_UNISTD -# else -# include -# endif -/* - * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX - * system and have sigaction and termios. - */ -# if defined(_POSIX_VERSION) - -# define SIGACTION -# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) -# define TERMIOS -# endif - -# endif -#endif - -#ifdef WIN16TTY -# undef OPENSSL_SYS_WIN16 -# undef WIN16 -# undef _WINDOWS -# include -#endif - -/* 06-Apr-92 Luke Brennan Support for VMS */ -// #include "ui_locl.h" -// #include "cryptlib.h" - -#ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ -# include -# ifdef __DECC -# pragma message disable DOLLARID -# endif -#endif - -#ifdef WIN_CONSOLE_BUG -# include -# ifndef OPENSSL_SYS_WINCE -# include -# endif -#endif - -/* - * There are 5 types of terminal interface supported, TERMIO, TERMIOS, VMS, - * MSDOS and SGTTY. - * - * If someone defines one of the macros TERMIO, TERMIOS or SGTTY, it will - * remain respected. Otherwise, we default to TERMIOS except for a few - * systems that require something different. - * - * Note: we do not use SGTTY unless it's defined by the configuration. We - * may eventually opt to remove it's use entirely. - */ - -#if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) - -# if defined(_LIBC) -# undef TERMIOS -# define TERMIO -# undef SGTTY -/* - * We know that VMS, MSDOS, VXWORKS, NETWARE use entirely other mechanisms. - * MAC_OS_GUSI_SOURCE should probably go away, but that needs to be confirmed. - */ -# elif !defined(OPENSSL_SYS_VMS) \ - && !defined(OPENSSL_SYS_MSDOS) \ - && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) \ - && !defined(MAC_OS_GUSI_SOURCE) \ - && !defined(OPENSSL_SYS_VXWORKS) \ - && !defined(OPENSSL_SYS_NETWARE) -# define TERMIOS -# undef TERMIO -# undef SGTTY -# endif - -#endif - -#ifdef TERMIOS -# include -# define TTY_STRUCT struct termios -# define TTY_FLAGS c_lflag -# define TTY_get(tty,data) tcgetattr(tty,data) -# define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) -#endif - -#ifdef TERMIO -# include -# define TTY_STRUCT struct termio -# define TTY_FLAGS c_lflag -# define TTY_get(tty,data) ioctl(tty,TCGETA,data) -# define TTY_set(tty,data) ioctl(tty,TCSETA,data) -#endif - -#ifdef SGTTY -# include -# define TTY_STRUCT struct sgttyb -# define TTY_FLAGS sg_flags -# define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) -# define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) -#endif - -#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS) -# include -#endif - -#ifdef OPENSSL_SYS_MSDOS -# include -#endif - -#ifdef OPENSSL_SYS_VMS -# include -# include -# include -# include -struct IOSB { - short iosb$w_value; - short iosb$w_count; - long iosb$l_info; -}; -#endif - -#ifdef OPENSSL_SYS_SUNOS -typedef int sig_atomic_t; -#endif - -#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE) -/* - * This one needs work. As a matter of fact the code is unoperational - * and this is only a trick to get it compiled. - * - */ -# define TTY_STRUCT int -#endif - -#ifndef NX509_SIG -# define NX509_SIG 32 -#endif - -/* Define globals. They are protected by a lock */ -#ifdef SIGACTION -static struct sigaction savsig[NX509_SIG]; -#else -static void (*savsig[NX509_SIG]) (int); -#endif - -#ifdef OPENSSL_SYS_VMS -static struct IOSB iosb; -static $DESCRIPTOR(terminal, "TT"); -static long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this - * will always suffice for the actual - * structures? */ -static long status; -static unsigned short channel = 0; -#else -# if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) -static TTY_STRUCT tty_orig, tty_new; -# endif -#endif -static FILE *tty_in, *tty_out; -static int is_a_tty; - -/* Declare static functions */ -#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) -static int read_till_nl(FILE *); -static void recsig(int); -static void pushsig(void); -static void popsig(void); -#endif -#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) -static int noecho_fgets(char *buf, int size, FILE *tty); -#endif -static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); - -static int read_string(UI *ui, UI_STRING *uis); -static int write_string(UI *ui, UI_STRING *uis); - -static int open_console(UI *ui); -static int echo_console(UI *ui); -static int noecho_console(UI *ui); -static int close_console(UI *ui); - -static UI_METHOD ui_openssl = { - "OpenSSL default user interface", - open_console, - write_string, - NULL, /* No flusher is needed for command lines */ - read_string, - close_console, - NULL -}; - -/* The method with all the built-in thingies */ -UI_METHOD *UI_OpenSSL(void) -{ - return &ui_openssl; -} - -/* - * The following function makes sure that info and error strings are printed - * before any prompt. - */ -static int write_string(UI *ui, UI_STRING *uis) -{ - switch (UI_get_string_type(uis)) { - case UIT_ERROR: - case UIT_INFO: - fputs(UI_get0_output_string(uis), tty_out); - fflush(tty_out); - break; - default: - break; - } - return 1; -} - -static int read_string(UI *ui, UI_STRING *uis) -{ - int ok = 0; - - switch (UI_get_string_type(uis)) { - case UIT_BOOLEAN: - fputs(UI_get0_output_string(uis), tty_out); - fputs(UI_get0_action_string(uis), tty_out); - fflush(tty_out); - return read_string_inner(ui, uis, - UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, - 0); - case UIT_PROMPT: - fputs(UI_get0_output_string(uis), tty_out); - fflush(tty_out); - return read_string_inner(ui, uis, - UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, - 1); - case UIT_VERIFY: - fprintf(tty_out, "Verifying - %s", UI_get0_output_string(uis)); - fflush(tty_out); - if ((ok = read_string_inner(ui, uis, - UI_get_input_flags(uis) & - UI_INPUT_FLAG_ECHO, 1)) <= 0) - return ok; - if (strcmp(UI_get0_result_string(uis), UI_get0_test_string(uis)) != 0) { - fprintf(tty_out, "Verify failure\n"); - fflush(tty_out); - return 0; - } - break; - default: - break; - } - return 1; -} - -#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) -/* Internal functions to read a string without echoing */ -static int read_till_nl(FILE *in) -{ -# define SIZE 4 - char buf[SIZE + 1]; - - do { - if (!fgets(buf, SIZE, in)) - return 0; - } while (strchr(buf, '\n') == NULL); - return 1; -} - -static volatile sig_atomic_t intr_signal; -#endif - -static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) -{ - static int ps; - int ok; - char result[BUFSIZ]; - int maxsize = BUFSIZ - 1; -#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) - char *p; - - intr_signal = 0; - ok = 0; - ps = 0; - - pushsig(); - ps = 1; - - if (!echo && !noecho_console(ui)) - goto error; - ps = 2; - - result[0] = '\0'; -# ifdef OPENSSL_SYS_MSDOS - if (!echo) { - noecho_fgets(result, maxsize, tty_in); - p = result; /* FIXME: noecho_fgets doesn't return errors */ - } else - p = fgets(result, maxsize, tty_in); -# else - p = fgets(result, maxsize, tty_in); -# endif - if (p == NULL) - goto error; - if (feof(tty_in)) - goto error; - if (ferror(tty_in)) - goto error; - if ((p = (char *)strchr(result, '\n')) != NULL) { - if (strip_nl) - *p = '\0'; - } else if (!read_till_nl(tty_in)) - goto error; - if (UI_set_result(ui, uis, result) >= 0) - ok = 1; - - error: - if (intr_signal == SIGINT) - ok = -1; - if (!echo) - fprintf(tty_out, "\n"); - if (ps >= 2 && !echo && !echo_console(ui)) - ok = 0; - - if (ps >= 1) - popsig(); -#else - ok = 1; -#endif - - OPENSSL_cleanse(result, BUFSIZ); - return ok; -} - -/* Internal functions to open, handle and close a channel to the console. */ -static int open_console(UI *ui) -{ - CRYPTO_w_lock(CRYPTO_LOCK_UI); - is_a_tty = 1; - -#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS) - tty_in = stdin; - tty_out = stderr; -#else -# ifdef OPENSSL_SYS_MSDOS -# define DEV_TTY "con" -# else -# define DEV_TTY "/dev/tty" -# endif - if ((tty_in = fopen(DEV_TTY, "r")) == NULL) - tty_in = stdin; - if ((tty_out = fopen(DEV_TTY, "w")) == NULL) - tty_out = stderr; -#endif - -#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) - if (TTY_get(fileno(tty_in), &tty_orig) == -1) { -# ifdef ENOTTY - if (errno == ENOTTY) - is_a_tty = 0; - else -# endif -# ifdef EINVAL - /* - * Ariel Glenn ariel@columbia.edu reports that solaris can return - * EINVAL instead. This should be ok - */ - if (errno == EINVAL) - is_a_tty = 0; - else -# endif -# ifdef ENXIO - /* - * Solaris can return ENXIO. - * This should be ok - */ - if (errno == ENXIO) - is_a_tty = 0; - else -# endif -# ifdef EIO - /* - * Linux can return EIO. - * This should be ok - */ - if (errno == EIO) - is_a_tty = 0; - else -# endif -# ifdef ENODEV - /* - * MacOS X returns ENODEV (Operation not supported by device), - * which seems appropriate. - */ - if (errno == ENODEV) - is_a_tty = 0; - else -# endif - return 0; - } -#endif -#ifdef OPENSSL_SYS_VMS - status = sys$assign(&terminal, &channel, 0, 0); - - /* if there isn't a TT device, something is very wrong */ - if (status != SS$_NORMAL) - return 0; - - status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, - 0, 0, 0, 0); - - /* If IO$_SENSEMODE doesn't work, this is not a terminal device */ - if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) - is_a_tty = 0; -#endif - return 1; -} - -static int noecho_console(UI *ui) -{ -#ifdef TTY_FLAGS - memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); - tty_new.TTY_FLAGS &= ~ECHO; -#endif - -#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) - if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) - return 0; -#endif -#ifdef OPENSSL_SYS_VMS - if (is_a_tty) { - tty_new[0] = tty_orig[0]; - tty_new[1] = tty_orig[1] | TT$M_NOECHO; - tty_new[2] = tty_orig[2]; - status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, - 0, 0, 0, 0); - if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) - return 0; - } -#endif - return 1; -} - -static int echo_console(UI *ui) -{ -#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) - memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); - if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) - return 0; -#endif -#ifdef OPENSSL_SYS_VMS - if (is_a_tty) { - tty_new[0] = tty_orig[0]; - tty_new[1] = tty_orig[1]; - tty_new[2] = tty_orig[2]; - status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, - 0, 0, 0, 0); - if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) - return 0; - } -#endif - return 1; -} - -static int close_console(UI *ui) -{ - if (tty_in != stdin) - fclose(tty_in); - if (tty_out != stderr) - fclose(tty_out); -#ifdef OPENSSL_SYS_VMS - status = sys$dassgn(channel); - if (status != SS$_NORMAL) - return 0; -#endif - CRYPTO_w_unlock(CRYPTO_LOCK_UI); - - return 1; -} - -#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) -/* Internal functions to handle signals and act on them */ -static void pushsig(void) -{ -# ifndef OPENSSL_SYS_WIN32 - int i; -# endif -# ifdef SIGACTION - struct sigaction sa; - - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = recsig; -# endif - -# ifdef OPENSSL_SYS_WIN32 - savsig[SIGABRT] = signal(SIGABRT, recsig); - savsig[SIGFPE] = signal(SIGFPE, recsig); - savsig[SIGILL] = signal(SIGILL, recsig); - savsig[SIGINT] = signal(SIGINT, recsig); - savsig[SIGSEGV] = signal(SIGSEGV, recsig); - savsig[SIGTERM] = signal(SIGTERM, recsig); -# else - for (i = 1; i < NX509_SIG; i++) { -# ifdef SIGUSR1 - if (i == SIGUSR1) - continue; -# endif -# ifdef SIGUSR2 - if (i == SIGUSR2) - continue; -# endif -# ifdef SIGKILL - if (i == SIGKILL) /* We can't make any action on that. */ - continue; -# endif -# ifdef SIGACTION - sigaction(i, &sa, &savsig[i]); -# else - savsig[i] = signal(i, recsig); -# endif - } -# endif - -# ifdef SIGWINCH - signal(SIGWINCH, SIG_DFL); -# endif -} - -static void popsig(void) -{ -# ifdef OPENSSL_SYS_WIN32 - signal(SIGABRT, savsig[SIGABRT]); - signal(SIGFPE, savsig[SIGFPE]); - signal(SIGILL, savsig[SIGILL]); - signal(SIGINT, savsig[SIGINT]); - signal(SIGSEGV, savsig[SIGSEGV]); - signal(SIGTERM, savsig[SIGTERM]); -# else - int i; - for (i = 1; i < NX509_SIG; i++) { -# ifdef SIGUSR1 - if (i == SIGUSR1) - continue; -# endif -# ifdef SIGUSR2 - if (i == SIGUSR2) - continue; -# endif -# ifdef SIGACTION - sigaction(i, &savsig[i], NULL); -# else - signal(i, savsig[i]); -# endif - } -# endif -} - -static void recsig(int i) -{ - intr_signal = i; -} -#endif - -/* Internal functions specific for Windows */ -#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) -static int noecho_fgets(char *buf, int size, FILE *tty) -{ - int i; - char *p; - - p = buf; - for (;;) { - if (size == 0) { - *p = '\0'; - break; - } - size--; -# ifdef WIN16TTY - i = _inchar(); -# elif defined(_WIN32) - i = _getch(); -# else - i = getch(); -# endif - if (i == '\r') - i = '\n'; - *(p++) = i; - if (i == '\n') { - *p = '\0'; - break; - } - } -# ifdef WIN_CONSOLE_BUG - /* - * Win95 has several evil console bugs: one of these is that the last - * character read using getch() is passed to the next read: this is - * usually a CR so this can be trouble. No STDIO fix seems to work but - * flushing the console appears to do the trick. - */ - { - HANDLE inh; - inh = GetStdHandle(STD_INPUT_HANDLE); - FlushConsoleInputBuffer(inh); - } -# endif - return (strlen(buf)); -} -#endif -/* crypto/ui/ui_util.c */ -/* ==================================================================== - * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "ui_locl.h" - -int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, - int verify) -{ - char buff[BUFSIZ]; - int ret; - - ret = - UI_UTIL_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length, - prompt, verify); - OPENSSL_cleanse(buff, BUFSIZ); - return (ret); -} - -int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, - int verify) -{ - int ok = 0; - UI *ui; - - if (size < 1) - return -1; - - ui = UI_new(); - if (ui) { - ok = UI_add_input_string(ui, prompt, 0, buf, 0, size - 1); - if (ok >= 0 && verify) - ok = UI_add_verify_string(ui, prompt, 0, buff, 0, size - 1, buf); - if (ok >= 0) - ok = UI_process(ui); - UI_free(ui); - } - if (ok > 0) - ok = 0; - return (ok); -} diff --git a/Sources/COpenSSL/ui_compat.h b/Sources/COpenSSL/ui_compat.h deleted file mode 100644 index 8d7b5f19..00000000 --- a/Sources/COpenSSL/ui_compat.h +++ /dev/null @@ -1,88 +0,0 @@ -/* crypto/ui/ui.h */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_UI_COMPAT_H -# define HEADER_UI_COMPAT_H - -# include "opensslconf.h" -# include "ui.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The following functions were previously part of the DES section, and are - * provided here for backward compatibility reasons. - */ - -# define des_read_pw_string(b,l,p,v) \ - _ossl_old_des_read_pw_string((b),(l),(p),(v)) -# define des_read_pw(b,bf,s,p,v) \ - _ossl_old_des_read_pw((b),(bf),(s),(p),(v)) - -int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, - int verify); -int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, - int verify); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/ui_locl.h b/Sources/COpenSSL/ui_locl.h deleted file mode 100644 index 2d6063fd..00000000 --- a/Sources/COpenSSL/ui_locl.h +++ /dev/null @@ -1,145 +0,0 @@ -/* crypto/ui/ui.h */ -/* - * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef HEADER_UI_LOCL_H -# define HEADER_UI_LOCL_H - -# include "ui.h" -# include "crypto.h" - -# ifdef _ -# undef _ -# endif - -struct ui_method_st { - char *name; - /* - * All the functions return 1 or non-NULL for success and 0 or NULL for - * failure - */ - /* - * Open whatever channel for this, be it the console, an X window or - * whatever. This function should use the ex_data structure to save - * intermediate data. - */ - int (*ui_open_session) (UI *ui); - int (*ui_write_string) (UI *ui, UI_STRING *uis); - /* - * Flush the output. If a GUI dialog box is used, this function can be - * used to actually display it. - */ - int (*ui_flush) (UI *ui); - int (*ui_read_string) (UI *ui, UI_STRING *uis); - int (*ui_close_session) (UI *ui); - /* - * Construct a prompt in a user-defined manner. object_desc is a textual - * short description of the object, for example "pass phrase", and - * object_name is the name of the object (might be a card name or a file - * name. The returned string shall always be allocated on the heap with - * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). - */ - char *(*ui_construct_prompt) (UI *ui, const char *object_desc, - const char *object_name); -}; - -struct ui_string_st { - enum UI_string_types type; /* Input */ - const char *out_string; /* Input */ - int input_flags; /* Flags from the user */ - /* - * The following parameters are completely irrelevant for UIT_INFO, and - * can therefore be set to 0 or NULL - */ - char *result_buf; /* Input and Output: If not NULL, - * user-defined with size in result_maxsize. - * Otherwise, it may be allocated by the UI - * routine, meaning result_minsize is going - * to be overwritten. */ - union { - struct { - int result_minsize; /* Input: minimum required size of the - * result. */ - int result_maxsize; /* Input: maximum permitted size of the - * result */ - const char *test_buf; /* Input: test string to verify against */ - } string_data; - struct { - const char *action_desc; /* Input */ - const char *ok_chars; /* Input */ - const char *cancel_chars; /* Input */ - } boolean_data; - } _; - -# define OUT_STRING_FREEABLE 0x01 - int flags; /* flags for internal use */ -}; - -struct ui_st { - const UI_METHOD *meth; - STACK_OF(UI_STRING) *strings; /* We might want to prompt for more than - * one thing at a time, and with different - * echoing status. */ - void *user_data; - CRYPTO_EX_DATA ex_data; -# define UI_FLAG_REDOABLE 0x0001 -# define UI_FLAG_PRINT_ERRORS 0x0100 - int flags; -}; - -#endif diff --git a/Sources/COpenSSL/uid.c b/Sources/COpenSSL/uid.c deleted file mode 100644 index d10536e7..00000000 --- a/Sources/COpenSSL/uid.c +++ /dev/null @@ -1,88 +0,0 @@ -/* crypto/uid.c */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include "crypto.h" -#include "opensslconf.h" - -#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2) - -# include OPENSSL_UNISTD - -int OPENSSL_issetugid(void) -{ - return issetugid(); -} - -#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) - -int OPENSSL_issetugid(void) -{ - return 0; -} - -#else - -# include OPENSSL_UNISTD -# include - -int OPENSSL_issetugid(void) -{ - if (getuid() != geteuid()) - return 1; - if (getgid() != getegid()) - return 1; - return 0; -} -#endif diff --git a/Sources/COpenSSL/v3_.c b/Sources/COpenSSL/v3_.c deleted file mode 100644 index e77010c5..00000000 --- a/Sources/COpenSSL/v3_.c +++ /dev/null @@ -1,10782 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* - * Contributed to the OpenSSL Project by the American Registry for - * Internet Numbers ("ARIN"). - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - */ - -/* - * Implementation of RFC 3779 section 2.2. - */ - -#include -#include - -#include "cryptlib.h" -#include "conf.h" -#include "asn1.h" -#include "asn1t.h" -#include "buffer.h" -#include "x509v3.h" - -#ifndef OPENSSL_NO_RFC3779 - -/* - * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. - */ - -ASN1_SEQUENCE(IPAddressRange) = { - ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), - ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END(IPAddressRange) - -ASN1_CHOICE(IPAddressOrRange) = { - ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), - ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) -} ASN1_CHOICE_END(IPAddressOrRange) - -ASN1_CHOICE(IPAddressChoice) = { - ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), - ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) -} ASN1_CHOICE_END(IPAddressChoice) - -ASN1_SEQUENCE(IPAddressFamily) = { - ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), - ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) -} ASN1_SEQUENCE_END(IPAddressFamily) - -ASN1_ITEM_TEMPLATE(IPAddrBlocks) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, - IPAddrBlocks, IPAddressFamily) -ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) - -IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) -IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange) -IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice) -IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) - -/* - * How much buffer space do we need for a raw address? - */ -# define ADDR_RAW_BUF_LEN 16 - -/* - * What's the address length associated with this AFI? - */ -static int length_from_afi(const unsigned afi) -{ - switch (afi) { - case IANA_AFI_IPV4: - return 4; - case IANA_AFI_IPV6: - return 16; - default: - return 0; - } -} - -/* - * Extract the AFI from an IPAddressFamily. - */ -unsigned int v3_addr_get_afi(const IPAddressFamily *f) -{ - if (f == NULL - || f->addressFamily == NULL - || f->addressFamily->data == NULL - || f->addressFamily->length < 2) - return 0; - return (f->addressFamily->data[0] << 8) | f->addressFamily->data[1]; -} - -/* - * Expand the bitstring form of an address into a raw byte array. - * At the moment this is coded for simplicity, not speed. - */ -static int addr_expand(unsigned char *addr, - const ASN1_BIT_STRING *bs, - const int length, const unsigned char fill) -{ - if (bs->length < 0 || bs->length > length) - return 0; - if (bs->length > 0) { - memcpy(addr, bs->data, bs->length); - if ((bs->flags & 7) != 0) { - unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); - if (fill == 0) - addr[bs->length - 1] &= ~mask; - else - addr[bs->length - 1] |= mask; - } - } - memset(addr + bs->length, fill, length - bs->length); - return 1; -} - -/* - * Extract the prefix length from a bitstring. - */ -# define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) - -/* - * i2r handler for one address bitstring. - */ -static int i2r_address(BIO *out, - const unsigned afi, - const unsigned char fill, const ASN1_BIT_STRING *bs) -{ - unsigned char addr[ADDR_RAW_BUF_LEN]; - int i, n; - - if (bs->length < 0) - return 0; - switch (afi) { - case IANA_AFI_IPV4: - if (!addr_expand(addr, bs, 4, fill)) - return 0; - BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); - break; - case IANA_AFI_IPV6: - if (!addr_expand(addr, bs, 16, fill)) - return 0; - for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; - n -= 2) ; - for (i = 0; i < n; i += 2) - BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], - (i < 14 ? ":" : "")); - if (i < 16) - BIO_puts(out, ":"); - if (i == 0) - BIO_puts(out, ":"); - break; - default: - for (i = 0; i < bs->length; i++) - BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); - BIO_printf(out, "[%d]", (int)(bs->flags & 7)); - break; - } - return 1; -} - -/* - * i2r handler for a sequence of addresses and ranges. - */ -static int i2r_IPAddressOrRanges(BIO *out, - const int indent, - const IPAddressOrRanges *aors, - const unsigned afi) -{ - int i; - for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { - const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); - BIO_printf(out, "%*s", indent, ""); - switch (aor->type) { - case IPAddressOrRange_addressPrefix: - if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) - return 0; - BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); - continue; - case IPAddressOrRange_addressRange: - if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) - return 0; - BIO_puts(out, "-"); - if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) - return 0; - BIO_puts(out, "\n"); - continue; - } - } - return 1; -} - -/* - * i2r handler for an IPAddrBlocks extension. - */ -static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, - void *ext, BIO *out, int indent) -{ - const IPAddrBlocks *addr = ext; - int i; - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); - const unsigned int afi = v3_addr_get_afi(f); - switch (afi) { - case IANA_AFI_IPV4: - BIO_printf(out, "%*sIPv4", indent, ""); - break; - case IANA_AFI_IPV6: - BIO_printf(out, "%*sIPv6", indent, ""); - break; - default: - BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); - break; - } - if (f->addressFamily->length > 2) { - switch (f->addressFamily->data[2]) { - case 1: - BIO_puts(out, " (Unicast)"); - break; - case 2: - BIO_puts(out, " (Multicast)"); - break; - case 3: - BIO_puts(out, " (Unicast/Multicast)"); - break; - case 4: - BIO_puts(out, " (MPLS)"); - break; - case 64: - BIO_puts(out, " (Tunnel)"); - break; - case 65: - BIO_puts(out, " (VPLS)"); - break; - case 66: - BIO_puts(out, " (BGP MDT)"); - break; - case 128: - BIO_puts(out, " (MPLS-labeled VPN)"); - break; - default: - BIO_printf(out, " (Unknown SAFI %u)", - (unsigned)f->addressFamily->data[2]); - break; - } - } - switch (f->ipAddressChoice->type) { - case IPAddressChoice_inherit: - BIO_puts(out, ": inherit\n"); - break; - case IPAddressChoice_addressesOrRanges: - BIO_puts(out, ":\n"); - if (!i2r_IPAddressOrRanges(out, - indent + 2, - f->ipAddressChoice-> - u.addressesOrRanges, afi)) - return 0; - break; - } - } - return 1; -} - -/* - * Sort comparison function for a sequence of IPAddressOrRange - * elements. - * - * There's no sane answer we can give if addr_expand() fails, and an - * assertion failure on externally supplied data is seriously uncool, - * so we just arbitrarily declare that if given invalid inputs this - * function returns -1. If this messes up your preferred sort order - * for garbage input, tough noogies. - */ -static int IPAddressOrRange_cmp(const IPAddressOrRange *a, - const IPAddressOrRange *b, const int length) -{ - unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; - int prefixlen_a = 0, prefixlen_b = 0; - int r; - - switch (a->type) { - case IPAddressOrRange_addressPrefix: - if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) - return -1; - prefixlen_a = addr_prefixlen(a->u.addressPrefix); - break; - case IPAddressOrRange_addressRange: - if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) - return -1; - prefixlen_a = length * 8; - break; - } - - switch (b->type) { - case IPAddressOrRange_addressPrefix: - if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) - return -1; - prefixlen_b = addr_prefixlen(b->u.addressPrefix); - break; - case IPAddressOrRange_addressRange: - if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) - return -1; - prefixlen_b = length * 8; - break; - } - - if ((r = memcmp(addr_a, addr_b, length)) != 0) - return r; - else - return prefixlen_a - prefixlen_b; -} - -/* - * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() - * comparision routines are only allowed two arguments. - */ -static int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, - const IPAddressOrRange *const *b) -{ - return IPAddressOrRange_cmp(*a, *b, 4); -} - -/* - * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() - * comparision routines are only allowed two arguments. - */ -static int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, - const IPAddressOrRange *const *b) -{ - return IPAddressOrRange_cmp(*a, *b, 16); -} - -/* - * Calculate whether a range collapses to a prefix. - * See last paragraph of RFC 3779 2.2.3.7. - */ -static int range_should_be_prefix(const unsigned char *min, - const unsigned char *max, const int length) -{ - unsigned char mask; - int i, j; - - OPENSSL_assert(memcmp(min, max, length) <= 0); - for (i = 0; i < length && min[i] == max[i]; i++) ; - for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ; - if (i < j) - return -1; - if (i > j) - return i * 8; - mask = min[i] ^ max[i]; - switch (mask) { - case 0x01: - j = 7; - break; - case 0x03: - j = 6; - break; - case 0x07: - j = 5; - break; - case 0x0F: - j = 4; - break; - case 0x1F: - j = 3; - break; - case 0x3F: - j = 2; - break; - case 0x7F: - j = 1; - break; - default: - return -1; - } - if ((min[i] & mask) != 0 || (max[i] & mask) != mask) - return -1; - else - return i * 8 + j; -} - -/* - * Construct a prefix. - */ -static int make_addressPrefix(IPAddressOrRange **result, - unsigned char *addr, const int prefixlen) -{ - int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; - IPAddressOrRange *aor = IPAddressOrRange_new(); - - if (aor == NULL) - return 0; - aor->type = IPAddressOrRange_addressPrefix; - if (aor->u.addressPrefix == NULL && - (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) - goto err; - if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) - goto err; - aor->u.addressPrefix->flags &= ~7; - aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; - if (bitlen > 0) { - aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); - aor->u.addressPrefix->flags |= 8 - bitlen; - } - - *result = aor; - return 1; - - err: - IPAddressOrRange_free(aor); - return 0; -} - -/* - * Construct a range. If it can be expressed as a prefix, - * return a prefix instead. Doing this here simplifies - * the rest of the code considerably. - */ -static int make_addressRange(IPAddressOrRange **result, - unsigned char *min, - unsigned char *max, const int length) -{ - IPAddressOrRange *aor; - int i, prefixlen; - - if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) - return make_addressPrefix(result, min, prefixlen); - - if ((aor = IPAddressOrRange_new()) == NULL) - return 0; - aor->type = IPAddressOrRange_addressRange; - OPENSSL_assert(aor->u.addressRange == NULL); - if ((aor->u.addressRange = IPAddressRange_new()) == NULL) - goto err; - if (aor->u.addressRange->min == NULL && - (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) - goto err; - if (aor->u.addressRange->max == NULL && - (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) - goto err; - - for (i = length; i > 0 && min[i - 1] == 0x00; --i) ; - if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) - goto err; - aor->u.addressRange->min->flags &= ~7; - aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; - if (i > 0) { - unsigned char b = min[i - 1]; - int j = 1; - while ((b & (0xFFU >> j)) != 0) - ++j; - aor->u.addressRange->min->flags |= 8 - j; - } - - for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ; - if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) - goto err; - aor->u.addressRange->max->flags &= ~7; - aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; - if (i > 0) { - unsigned char b = max[i - 1]; - int j = 1; - while ((b & (0xFFU >> j)) != (0xFFU >> j)) - ++j; - aor->u.addressRange->max->flags |= 8 - j; - } - - *result = aor; - return 1; - - err: - IPAddressOrRange_free(aor); - return 0; -} - -/* - * Construct a new address family or find an existing one. - */ -static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, - const unsigned afi, - const unsigned *safi) -{ - IPAddressFamily *f; - unsigned char key[3]; - unsigned keylen; - int i; - - key[0] = (afi >> 8) & 0xFF; - key[1] = afi & 0xFF; - if (safi != NULL) { - key[2] = *safi & 0xFF; - keylen = 3; - } else { - keylen = 2; - } - - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - f = sk_IPAddressFamily_value(addr, i); - OPENSSL_assert(f->addressFamily->data != NULL); - if (f->addressFamily->length == keylen && - !memcmp(f->addressFamily->data, key, keylen)) - return f; - } - - if ((f = IPAddressFamily_new()) == NULL) - goto err; - if (f->ipAddressChoice == NULL && - (f->ipAddressChoice = IPAddressChoice_new()) == NULL) - goto err; - if (f->addressFamily == NULL && - (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) - goto err; - if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) - goto err; - if (!sk_IPAddressFamily_push(addr, f)) - goto err; - - return f; - - err: - IPAddressFamily_free(f); - return NULL; -} - -/* - * Add an inheritance element. - */ -int v3_addr_add_inherit(IPAddrBlocks *addr, - const unsigned afi, const unsigned *safi) -{ - IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); - if (f == NULL || - f->ipAddressChoice == NULL || - (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && - f->ipAddressChoice->u.addressesOrRanges != NULL)) - return 0; - if (f->ipAddressChoice->type == IPAddressChoice_inherit && - f->ipAddressChoice->u.inherit != NULL) - return 1; - if (f->ipAddressChoice->u.inherit == NULL && - (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) - return 0; - f->ipAddressChoice->type = IPAddressChoice_inherit; - return 1; -} - -/* - * Construct an IPAddressOrRange sequence, or return an existing one. - */ -static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, - const unsigned afi, - const unsigned *safi) -{ - IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); - IPAddressOrRanges *aors = NULL; - - if (f == NULL || - f->ipAddressChoice == NULL || - (f->ipAddressChoice->type == IPAddressChoice_inherit && - f->ipAddressChoice->u.inherit != NULL)) - return NULL; - if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) - aors = f->ipAddressChoice->u.addressesOrRanges; - if (aors != NULL) - return aors; - if ((aors = sk_IPAddressOrRange_new_null()) == NULL) - return NULL; - switch (afi) { - case IANA_AFI_IPV4: - (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); - break; - case IANA_AFI_IPV6: - (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); - break; - } - f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; - f->ipAddressChoice->u.addressesOrRanges = aors; - return aors; -} - -/* - * Add a prefix. - */ -int v3_addr_add_prefix(IPAddrBlocks *addr, - const unsigned afi, - const unsigned *safi, - unsigned char *a, const int prefixlen) -{ - IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); - IPAddressOrRange *aor; - if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) - return 0; - if (sk_IPAddressOrRange_push(aors, aor)) - return 1; - IPAddressOrRange_free(aor); - return 0; -} - -/* - * Add a range. - */ -int v3_addr_add_range(IPAddrBlocks *addr, - const unsigned afi, - const unsigned *safi, - unsigned char *min, unsigned char *max) -{ - IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); - IPAddressOrRange *aor; - int length = length_from_afi(afi); - if (aors == NULL) - return 0; - if (!make_addressRange(&aor, min, max, length)) - return 0; - if (sk_IPAddressOrRange_push(aors, aor)) - return 1; - IPAddressOrRange_free(aor); - return 0; -} - -/* - * Extract min and max values from an IPAddressOrRange. - */ -static int extract_min_max(IPAddressOrRange *aor, - unsigned char *min, unsigned char *max, int length) -{ - if (aor == NULL || min == NULL || max == NULL) - return 0; - switch (aor->type) { - case IPAddressOrRange_addressPrefix: - return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && - addr_expand(max, aor->u.addressPrefix, length, 0xFF)); - case IPAddressOrRange_addressRange: - return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && - addr_expand(max, aor->u.addressRange->max, length, 0xFF)); - } - return 0; -} - -/* - * Public wrapper for extract_min_max(). - */ -int v3_addr_get_range(IPAddressOrRange *aor, - const unsigned afi, - unsigned char *min, - unsigned char *max, const int length) -{ - int afi_length = length_from_afi(afi); - if (aor == NULL || min == NULL || max == NULL || - afi_length == 0 || length < afi_length || - (aor->type != IPAddressOrRange_addressPrefix && - aor->type != IPAddressOrRange_addressRange) || - !extract_min_max(aor, min, max, afi_length)) - return 0; - - return afi_length; -} - -/* - * Sort comparision function for a sequence of IPAddressFamily. - * - * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about - * the ordering: I can read it as meaning that IPv6 without a SAFI - * comes before IPv4 with a SAFI, which seems pretty weird. The - * examples in appendix B suggest that the author intended the - * null-SAFI rule to apply only within a single AFI, which is what I - * would have expected and is what the following code implements. - */ -static int IPAddressFamily_cmp(const IPAddressFamily *const *a_, - const IPAddressFamily *const *b_) -{ - const ASN1_OCTET_STRING *a = (*a_)->addressFamily; - const ASN1_OCTET_STRING *b = (*b_)->addressFamily; - int len = ((a->length <= b->length) ? a->length : b->length); - int cmp = memcmp(a->data, b->data, len); - return cmp ? cmp : a->length - b->length; -} - -/* - * Check whether an IPAddrBLocks is in canonical form. - */ -int v3_addr_is_canonical(IPAddrBlocks *addr) -{ - unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; - unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; - IPAddressOrRanges *aors; - int i, j, k; - - /* - * Empty extension is cannonical. - */ - if (addr == NULL) - return 1; - - /* - * Check whether the top-level list is in order. - */ - for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { - const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); - const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); - if (IPAddressFamily_cmp(&a, &b) >= 0) - return 0; - } - - /* - * Top level's ok, now check each address family. - */ - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); - int length = length_from_afi(v3_addr_get_afi(f)); - - /* - * Inheritance is canonical. Anything other than inheritance or - * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. - */ - if (f == NULL || f->ipAddressChoice == NULL) - return 0; - switch (f->ipAddressChoice->type) { - case IPAddressChoice_inherit: - continue; - case IPAddressChoice_addressesOrRanges: - break; - default: - return 0; - } - - /* - * It's an IPAddressOrRanges sequence, check it. - */ - aors = f->ipAddressChoice->u.addressesOrRanges; - if (sk_IPAddressOrRange_num(aors) == 0) - return 0; - for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { - IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); - IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); - - if (!extract_min_max(a, a_min, a_max, length) || - !extract_min_max(b, b_min, b_max, length)) - return 0; - - /* - * Punt misordered list, overlapping start, or inverted range. - */ - if (memcmp(a_min, b_min, length) >= 0 || - memcmp(a_min, a_max, length) > 0 || - memcmp(b_min, b_max, length) > 0) - return 0; - - /* - * Punt if adjacent or overlapping. Check for adjacency by - * subtracting one from b_min first. - */ - for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ; - if (memcmp(a_max, b_min, length) >= 0) - return 0; - - /* - * Check for range that should be expressed as a prefix. - */ - if (a->type == IPAddressOrRange_addressRange && - range_should_be_prefix(a_min, a_max, length) >= 0) - return 0; - } - - /* - * Check range to see if it's inverted or should be a - * prefix. - */ - j = sk_IPAddressOrRange_num(aors) - 1; - { - IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); - if (a != NULL && a->type == IPAddressOrRange_addressRange) { - if (!extract_min_max(a, a_min, a_max, length)) - return 0; - if (memcmp(a_min, a_max, length) > 0 || - range_should_be_prefix(a_min, a_max, length) >= 0) - return 0; - } - } - } - - /* - * If we made it through all that, we're happy. - */ - return 1; -} - -/* - * Whack an IPAddressOrRanges into canonical form. - */ -static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, - const unsigned afi) -{ - int i, j, length = length_from_afi(afi); - - /* - * Sort the IPAddressOrRanges sequence. - */ - sk_IPAddressOrRange_sort(aors); - - /* - * Clean up representation issues, punt on duplicates or overlaps. - */ - for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { - IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); - IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); - unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; - unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; - - if (!extract_min_max(a, a_min, a_max, length) || - !extract_min_max(b, b_min, b_max, length)) - return 0; - - /* - * Punt inverted ranges. - */ - if (memcmp(a_min, a_max, length) > 0 || - memcmp(b_min, b_max, length) > 0) - return 0; - - /* - * Punt overlaps. - */ - if (memcmp(a_max, b_min, length) >= 0) - return 0; - - /* - * Merge if a and b are adjacent. We check for - * adjacency by subtracting one from b_min first. - */ - for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ; - if (memcmp(a_max, b_min, length) == 0) { - IPAddressOrRange *merged; - if (!make_addressRange(&merged, a_min, b_max, length)) - return 0; - (void)sk_IPAddressOrRange_set(aors, i, merged); - (void)sk_IPAddressOrRange_delete(aors, i + 1); - IPAddressOrRange_free(a); - IPAddressOrRange_free(b); - --i; - continue; - } - } - - /* - * Check for inverted final range. - */ - j = sk_IPAddressOrRange_num(aors) - 1; - { - IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); - if (a != NULL && a->type == IPAddressOrRange_addressRange) { - unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; - extract_min_max(a, a_min, a_max, length); - if (memcmp(a_min, a_max, length) > 0) - return 0; - } - } - - return 1; -} - -/* - * Whack an IPAddrBlocks extension into canonical form. - */ -int v3_addr_canonize(IPAddrBlocks *addr) -{ - int i; - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); - if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && - !IPAddressOrRanges_canonize(f->ipAddressChoice-> - u.addressesOrRanges, - v3_addr_get_afi(f))) - return 0; - } - (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); - sk_IPAddressFamily_sort(addr); - OPENSSL_assert(v3_addr_is_canonical(addr)); - return 1; -} - -/* - * v2i handler for the IPAddrBlocks extension. - */ -static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, - STACK_OF(CONF_VALUE) *values) -{ - static const char v4addr_chars[] = "0123456789."; - static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; - IPAddrBlocks *addr = NULL; - char *s = NULL, *t; - int i; - - if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - CONF_VALUE *val = sk_CONF_VALUE_value(values, i); - unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; - unsigned afi, *safi = NULL, safi_; - const char *addr_chars; - int prefixlen, i1, i2, delim, length; - - if (!name_cmp(val->name, "IPv4")) { - afi = IANA_AFI_IPV4; - } else if (!name_cmp(val->name, "IPv6")) { - afi = IANA_AFI_IPV6; - } else if (!name_cmp(val->name, "IPv4-SAFI")) { - afi = IANA_AFI_IPV4; - safi = &safi_; - } else if (!name_cmp(val->name, "IPv6-SAFI")) { - afi = IANA_AFI_IPV6; - safi = &safi_; - } else { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_NAME_ERROR); - X509V3_conf_err(val); - goto err; - } - - switch (afi) { - case IANA_AFI_IPV4: - addr_chars = v4addr_chars; - break; - case IANA_AFI_IPV6: - addr_chars = v6addr_chars; - break; - } - - length = length_from_afi(afi); - - /* - * Handle SAFI, if any, and BUF_strdup() so we can null-terminate - * the other input values. - */ - if (safi != NULL) { - *safi = strtoul(val->value, &t, 0); - t += strspn(t, " \t"); - if (*safi > 0xFF || *t++ != ':') { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); - X509V3_conf_err(val); - goto err; - } - t += strspn(t, " \t"); - s = BUF_strdup(t); - } else { - s = BUF_strdup(val->value); - } - if (s == NULL) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); - goto err; - } - - /* - * Check for inheritance. Not worth additional complexity to - * optimize this (seldom-used) case. - */ - if (!strcmp(s, "inherit")) { - if (!v3_addr_add_inherit(addr, afi, safi)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_INVALID_INHERITANCE); - X509V3_conf_err(val); - goto err; - } - OPENSSL_free(s); - s = NULL; - continue; - } - - i1 = strspn(s, addr_chars); - i2 = i1 + strspn(s + i1, " \t"); - delim = s[i2++]; - s[i1] = '\0'; - - if (a2i_ipadd(min, s) != length) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); - X509V3_conf_err(val); - goto err; - } - - switch (delim) { - case '/': - prefixlen = (int)strtoul(s + i2, &t, 10); - if (t == s + i2 || *t != '\0') { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); - goto err; - } - break; - case '-': - i1 = i2 + strspn(s + i2, " \t"); - i2 = i1 + strspn(s + i1, addr_chars); - if (i1 == i2 || s[i2] != '\0') { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (a2i_ipadd(max, s + i1) != length) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_INVALID_IPADDRESS); - X509V3_conf_err(val); - goto err; - } - if (memcmp(min, max, length_from_afi(afi)) > 0) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - if (!v3_addr_add_range(addr, afi, safi, min, max)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); - goto err; - } - break; - case '\0': - if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); - goto err; - } - break; - default: - X509V3err(X509V3_F_V2I_IPADDRBLOCKS, - X509V3_R_EXTENSION_VALUE_ERROR); - X509V3_conf_err(val); - goto err; - } - - OPENSSL_free(s); - s = NULL; - } - - /* - * Canonize the result, then we're done. - */ - if (!v3_addr_canonize(addr)) - goto err; - return addr; - - err: - OPENSSL_free(s); - sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); - return NULL; -} - -/* - * OpenSSL dispatch - */ -const X509V3_EXT_METHOD v3_addr = { - NID_sbgp_ipAddrBlock, /* nid */ - 0, /* flags */ - ASN1_ITEM_ref(IPAddrBlocks), /* template */ - 0, 0, 0, 0, /* old functions, ignored */ - 0, /* i2s */ - 0, /* s2i */ - 0, /* i2v */ - v2i_IPAddrBlocks, /* v2i */ - i2r_IPAddrBlocks, /* i2r */ - 0, /* r2i */ - NULL /* extension-specific data */ -}; - -/* - * Figure out whether extension sues inheritance. - */ -int v3_addr_inherits(IPAddrBlocks *addr) -{ - int i; - if (addr == NULL) - return 0; - for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { - IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); - if (f->ipAddressChoice->type == IPAddressChoice_inherit) - return 1; - } - return 0; -} - -/* - * Figure out whether parent contains child. - */ -static int addr_contains(IPAddressOrRanges *parent, - IPAddressOrRanges *child, int length) -{ - unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; - unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; - int p, c; - - if (child == NULL || parent == child) - return 1; - if (parent == NULL) - return 0; - - p = 0; - for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { - if (!extract_min_max(sk_IPAddressOrRange_value(child, c), - c_min, c_max, length)) - return -1; - for (;; p++) { - if (p >= sk_IPAddressOrRange_num(parent)) - return 0; - if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), - p_min, p_max, length)) - return 0; - if (memcmp(p_max, c_max, length) < 0) - continue; - if (memcmp(p_min, c_min, length) > 0) - return 0; - break; - } - } - - return 1; -} - -/* - * Test whether a is a subset of b. - */ -int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) -{ - int i; - if (a == NULL || a == b) - return 1; - if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) - return 0; - (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); - for (i = 0; i < sk_IPAddressFamily_num(a); i++) { - IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); - int j = sk_IPAddressFamily_find(b, fa); - IPAddressFamily *fb; - fb = sk_IPAddressFamily_value(b, j); - if (fb == NULL) - return 0; - if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, - fa->ipAddressChoice->u.addressesOrRanges, - length_from_afi(v3_addr_get_afi(fb)))) - return 0; - } - return 1; -} - -/* - * Validation error handling via callback. - */ -# define validation_err(_err_) \ - do { \ - if (ctx != NULL) { \ - ctx->error = _err_; \ - ctx->error_depth = i; \ - ctx->current_cert = x; \ - ret = ctx->verify_cb(0, ctx); \ - } else { \ - ret = 0; \ - } \ - if (!ret) \ - goto done; \ - } while (0) - -/* - * Core code for RFC 3779 2.3 path validation. - * - * Returns 1 for success, 0 on error. - * - * When returning 0, ctx->error MUST be set to an appropriate value other than - * X509_V_OK. - */ -static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, - STACK_OF(X509) *chain, - IPAddrBlocks *ext) -{ - IPAddrBlocks *child = NULL; - int i, j, ret = 1; - X509 *x; - - OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); - OPENSSL_assert(ctx != NULL || ext != NULL); - OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); - - /* - * Figure out where to start. If we don't have an extension to - * check, we're done. Otherwise, check canonical form and - * set up for walking up the chain. - */ - if (ext != NULL) { - i = -1; - x = NULL; - } else { - i = 0; - x = sk_X509_value(chain, i); - OPENSSL_assert(x != NULL); - if ((ext = x->rfc3779_addr) == NULL) - goto done; - } - if (!v3_addr_is_canonical(ext)) - validation_err(X509_V_ERR_INVALID_EXTENSION); - (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); - if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { - X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, - ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ret = 0; - goto done; - } - - /* - * Now walk up the chain. No cert may list resources that its - * parent doesn't list. - */ - for (i++; i < sk_X509_num(chain); i++) { - x = sk_X509_value(chain, i); - OPENSSL_assert(x != NULL); - if (!v3_addr_is_canonical(x->rfc3779_addr)) - validation_err(X509_V_ERR_INVALID_EXTENSION); - if (x->rfc3779_addr == NULL) { - for (j = 0; j < sk_IPAddressFamily_num(child); j++) { - IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); - if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - break; - } - } - continue; - } - (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, - IPAddressFamily_cmp); - for (j = 0; j < sk_IPAddressFamily_num(child); j++) { - IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); - int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); - IPAddressFamily *fp = - sk_IPAddressFamily_value(x->rfc3779_addr, k); - if (fp == NULL) { - if (fc->ipAddressChoice->type == - IPAddressChoice_addressesOrRanges) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - break; - } - continue; - } - if (fp->ipAddressChoice->type == - IPAddressChoice_addressesOrRanges) { - if (fc->ipAddressChoice->type == IPAddressChoice_inherit - || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, - fc->ipAddressChoice->u.addressesOrRanges, - length_from_afi(v3_addr_get_afi(fc)))) - sk_IPAddressFamily_set(child, j, fp); - else - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - } - - /* - * Trust anchor can't inherit. - */ - OPENSSL_assert(x != NULL); - if (x->rfc3779_addr != NULL) { - for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { - IPAddressFamily *fp = - sk_IPAddressFamily_value(x->rfc3779_addr, j); - if (fp->ipAddressChoice->type == IPAddressChoice_inherit - && sk_IPAddressFamily_find(child, fp) >= 0) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - - done: - sk_IPAddressFamily_free(child); - return ret; -} - -# undef validation_err - -/* - * RFC 3779 2.3 path validation -- called from X509_verify_cert(). - */ -int v3_addr_validate_path(X509_STORE_CTX *ctx) -{ - return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); -} - -/* - * RFC 3779 2.3 path validation of an extension. - * Test whether chain covers extension. - */ -int v3_addr_validate_resource_set(STACK_OF(X509) *chain, - IPAddrBlocks *ext, int allow_inheritance) -{ - if (ext == NULL) - return 1; - if (chain == NULL || sk_X509_num(chain) == 0) - return 0; - if (!allow_inheritance && v3_addr_inherits(ext)) - return 0; - return v3_addr_validate_path_internal(NULL, chain, ext); -} - -#endif /* OPENSSL_NO_RFC3779 */ -/* v3_akey.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" - -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - AUTHORITY_KEYID *akeyid, - STACK_OF(CONF_VALUE) - *extlist); -static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values); - -const X509V3_EXT_METHOD v3_akey_id = { - NID_authority_key_identifier, - X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID, - (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, - 0, 0, - NULL -}; - -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - AUTHORITY_KEYID *akeyid, - STACK_OF(CONF_VALUE) - *extlist) -{ - char *tmp; - if (akeyid->keyid) { - tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length); - X509V3_add_value("keyid", tmp, &extlist); - OPENSSL_free(tmp); - } - if (akeyid->issuer) - extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); - if (akeyid->serial) { - tmp = hex_to_string(akeyid->serial->data, akeyid->serial->length); - X509V3_add_value("serial", tmp, &extlist); - OPENSSL_free(tmp); - } - return extlist; -} - -/*- - * Currently two options: - * keyid: use the issuers subject keyid, the value 'always' means its is - * an error if the issuer certificate doesn't have a key id. - * issuer: use the issuers cert issuer and serial number. The default is - * to only use this if keyid is not present. With the option 'always' - * this is always included. - */ - -static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - char keyid = 0, issuer = 0; - int i; - CONF_VALUE *cnf; - ASN1_OCTET_STRING *ikeyid = NULL; - X509_NAME *isname = NULL; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gen = NULL; - ASN1_INTEGER *serial = NULL; - X509_EXTENSION *ext; - X509 *cert; - AUTHORITY_KEYID *akeyid; - - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - cnf = sk_CONF_VALUE_value(values, i); - if (!strcmp(cnf->name, "keyid")) { - keyid = 1; - if (cnf->value && !strcmp(cnf->value, "always")) - keyid = 2; - } else if (!strcmp(cnf->name, "issuer")) { - issuer = 1; - if (cnf->value && !strcmp(cnf->value, "always")) - issuer = 2; - } else { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION); - ERR_add_error_data(2, "name=", cnf->name); - return NULL; - } - } - - if (!ctx || !ctx->issuer_cert) { - if (ctx && (ctx->flags == CTX_TEST)) - return AUTHORITY_KEYID_new(); - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, - X509V3_R_NO_ISSUER_CERTIFICATE); - return NULL; - } - - cert = ctx->issuer_cert; - - if (keyid) { - i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); - if ((i >= 0) && (ext = X509_get_ext(cert, i))) - ikeyid = X509V3_EXT_d2i(ext); - if (keyid == 2 && !ikeyid) { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, - X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); - return NULL; - } - } - - if ((issuer && !ikeyid) || (issuer == 2)) { - isname = X509_NAME_dup(X509_get_issuer_name(cert)); - serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)); - if (!isname || !serial) { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, - X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); - goto err; - } - } - - if (!(akeyid = AUTHORITY_KEYID_new())) - goto err; - - if (isname) { - if (!(gens = sk_GENERAL_NAME_new_null()) - || !(gen = GENERAL_NAME_new()) - || !sk_GENERAL_NAME_push(gens, gen)) { - X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE); - goto err; - } - gen->type = GEN_DIRNAME; - gen->d.dirn = isname; - } - - akeyid->issuer = gens; - akeyid->serial = serial; - akeyid->keyid = ikeyid; - - return akeyid; - - err: - X509_NAME_free(isname); - M_ASN1_INTEGER_free(serial); - M_ASN1_OCTET_STRING_free(ikeyid); - return NULL; -} -/* v3_akey_asn1.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" - -ASN1_SEQUENCE(AUTHORITY_KEYID) = { - ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), - ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), - ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) -} ASN1_SEQUENCE_END(AUTHORITY_KEYID) - -IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) -/* v3_alt.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "x509v3.h" - -static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); -static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); -static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); -static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); - -const X509V3_EXT_METHOD v3_alt[] = { - {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_GENERAL_NAMES, - (X509V3_EXT_V2I)v2i_subject_alt, - NULL, NULL, NULL}, - - {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_GENERAL_NAMES, - (X509V3_EXT_V2I)v2i_issuer_alt, - NULL, NULL, NULL}, - - {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_GENERAL_NAMES, - NULL, NULL, NULL, NULL}, -}; - -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, - GENERAL_NAMES *gens, - STACK_OF(CONF_VALUE) *ret) -{ - int i; - GENERAL_NAME *gen; - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gen = sk_GENERAL_NAME_value(gens, i); - ret = i2v_GENERAL_NAME(method, gen, ret); - } - if (!ret) - return sk_CONF_VALUE_new_null(); - return ret; -} - -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, - GENERAL_NAME *gen, - STACK_OF(CONF_VALUE) *ret) -{ - unsigned char *p; - char oline[256], htmp[5]; - int i; - switch (gen->type) { - case GEN_OTHERNAME: - if (!X509V3_add_value("othername", "", &ret)) - return NULL; - break; - - case GEN_X400: - if (!X509V3_add_value("X400Name", "", &ret)) - return NULL; - break; - - case GEN_EDIPARTY: - if (!X509V3_add_value("EdiPartyName", "", &ret)) - return NULL; - break; - - case GEN_EMAIL: - if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) - return NULL; - break; - - case GEN_DNS: - if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) - return NULL; - break; - - case GEN_URI: - if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) - return NULL; - break; - - case GEN_DIRNAME: - if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL - || !X509V3_add_value("DirName", oline, &ret)) - return NULL; - break; - - case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_snprintf(oline, sizeof(oline), - "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - oline[0] = 0; - for (i = 0; i < 8; i++) { - BIO_snprintf(htmp, sizeof(htmp), "%X", p[0] << 8 | p[1]); - p += 2; - strcat(oline, htmp); - if (i != 7) - strcat(oline, ":"); - } - } else { - if (!X509V3_add_value("IP Address", "", &ret)) - return NULL; - break; - } - if (!X509V3_add_value("IP Address", oline, &ret)) - return NULL; - break; - - case GEN_RID: - i2t_ASN1_OBJECT(oline, 256, gen->d.rid); - if (!X509V3_add_value("Registered ID", oline, &ret)) - return NULL; - break; - } - return ret; -} - -int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) -{ - unsigned char *p; - int i; - switch (gen->type) { - case GEN_OTHERNAME: - BIO_printf(out, "othername:"); - break; - - case GEN_X400: - BIO_printf(out, "X400Name:"); - break; - - case GEN_EDIPARTY: - /* Maybe fix this: it is supported now */ - BIO_printf(out, "EdiPartyName:"); - break; - - case GEN_EMAIL: - BIO_printf(out, "email:%s", gen->d.ia5->data); - break; - - case GEN_DNS: - BIO_printf(out, "DNS:%s", gen->d.ia5->data); - break; - - case GEN_URI: - BIO_printf(out, "URI:%s", gen->d.ia5->data); - break; - - case GEN_DIRNAME: - BIO_printf(out, "DirName: "); - X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); - break; - - case GEN_IPADD: - p = gen->d.ip->data; - if (gen->d.ip->length == 4) - BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - else if (gen->d.ip->length == 16) { - BIO_printf(out, "IP Address"); - for (i = 0; i < 8; i++) { - BIO_printf(out, ":%X", p[0] << 8 | p[1]); - p += 2; - } - BIO_puts(out, "\n"); - } else { - BIO_printf(out, "IP Address:"); - break; - } - break; - - case GEN_RID: - BIO_printf(out, "Registered ID"); - i2a_ASN1_OBJECT(out, gen->d.rid); - break; - } - return 1; -} - -static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - int i; - if (!(gens = sk_GENERAL_NAME_new_null())) { - X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!name_cmp(cnf->name, "issuer") && cnf->value && - !strcmp(cnf->value, "copy")) { - if (!copy_issuer(ctx, gens)) - goto err; - } else { - GENERAL_NAME *gen; - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - sk_GENERAL_NAME_push(gens, gen); - } - } - return gens; - err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return NULL; -} - -/* Append subject altname of issuer to issuer alt name of subject */ - -static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) -{ - GENERAL_NAMES *ialt; - GENERAL_NAME *gen; - X509_EXTENSION *ext; - int i; - if (ctx && (ctx->flags == CTX_TEST)) - return 1; - if (!ctx || !ctx->issuer_cert) { - X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); - goto err; - } - i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); - if (i < 0) - return 1; - if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || - !(ialt = X509V3_EXT_d2i(ext))) { - X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); - goto err; - } - - for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { - gen = sk_GENERAL_NAME_value(ialt, i); - if (!sk_GENERAL_NAME_push(gens, gen)) { - X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); - goto err; - } - } - sk_GENERAL_NAME_free(ialt); - - return 1; - - err: - return 0; - -} - -static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - int i; - if (!(gens = sk_GENERAL_NAME_new_null())) { - X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "copy")) { - if (!copy_email(ctx, gens, 0)) - goto err; - } else if (!name_cmp(cnf->name, "email") && cnf->value && - !strcmp(cnf->value, "move")) { - if (!copy_email(ctx, gens, 1)) - goto err; - } else { - GENERAL_NAME *gen; - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - sk_GENERAL_NAME_push(gens, gen); - } - } - return gens; - err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return NULL; -} - -/* - * Copy any email addresses in a certificate or request to GENERAL_NAMES - */ - -static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) -{ - X509_NAME *nm; - ASN1_IA5STRING *email = NULL; - X509_NAME_ENTRY *ne; - GENERAL_NAME *gen = NULL; - int i; - if (ctx != NULL && ctx->flags == CTX_TEST) - return 1; - if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { - X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); - goto err; - } - /* Find the subject name */ - if (ctx->subject_cert) - nm = X509_get_subject_name(ctx->subject_cert); - else - nm = X509_REQ_get_subject_name(ctx->subject_req); - - /* Now add any email address(es) to STACK */ - i = -1; - while ((i = X509_NAME_get_index_by_NID(nm, - NID_pkcs9_emailAddress, i)) >= 0) { - ne = X509_NAME_get_entry(nm, i); - email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); - if (move_p) { - X509_NAME_delete_entry(nm, i); - X509_NAME_ENTRY_free(ne); - i--; - } - if (!email || !(gen = GENERAL_NAME_new())) { - X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); - goto err; - } - gen->d.ia5 = email; - email = NULL; - gen->type = GEN_EMAIL; - if (!sk_GENERAL_NAME_push(gens, gen)) { - X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); - goto err; - } - gen = NULL; - } - - return 1; - - err: - GENERAL_NAME_free(gen); - M_ASN1_IA5STRING_free(email); - return 0; - -} - -GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - GENERAL_NAME *gen; - GENERAL_NAMES *gens = NULL; - CONF_VALUE *cnf; - int i; - if (!(gens = sk_GENERAL_NAME_new_null())) { - X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - sk_GENERAL_NAME_push(gens, gen); - } - return gens; - err: - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return NULL; -} - -GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf) -{ - return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); -} - -GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, int gen_type, char *value, - int is_nc) -{ - char is_string = 0; - GENERAL_NAME *gen = NULL; - - if (!value) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); - return NULL; - } - - if (out) - gen = out; - else { - gen = GENERAL_NAME_new(); - if (gen == NULL) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); - return NULL; - } - } - - switch (gen_type) { - case GEN_URI: - case GEN_EMAIL: - case GEN_DNS: - is_string = 1; - break; - - case GEN_RID: - { - ASN1_OBJECT *obj; - if (!(obj = OBJ_txt2obj(value, 0))) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); - ERR_add_error_data(2, "value=", value); - goto err; - } - gen->d.rid = obj; - } - break; - - case GEN_IPADD: - if (is_nc) - gen->d.ip = a2i_IPADDRESS_NC(value); - else - gen->d.ip = a2i_IPADDRESS(value); - if (gen->d.ip == NULL) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS); - ERR_add_error_data(2, "value=", value); - goto err; - } - break; - - case GEN_DIRNAME: - if (!do_dirname(gen, value, ctx)) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR); - goto err; - } - break; - - case GEN_OTHERNAME: - if (!do_othername(gen, value, ctx)) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR); - goto err; - } - break; - default: - X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); - goto err; - } - - if (is_string) { - if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || - !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, - strlen(value))) { - X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); - goto err; - } - } - - gen->type = gen_type; - - return gen; - - err: - if (!out) - GENERAL_NAME_free(gen); - return NULL; -} - -GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) -{ - int type; - - char *name, *value; - - name = cnf->name; - value = cnf->value; - - if (!value) { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); - return NULL; - } - - if (!name_cmp(name, "email")) - type = GEN_EMAIL; - else if (!name_cmp(name, "URI")) - type = GEN_URI; - else if (!name_cmp(name, "DNS")) - type = GEN_DNS; - else if (!name_cmp(name, "RID")) - type = GEN_RID; - else if (!name_cmp(name, "IP")) - type = GEN_IPADD; - else if (!name_cmp(name, "dirName")) - type = GEN_DIRNAME; - else if (!name_cmp(name, "otherName")) - type = GEN_OTHERNAME; - else { - X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); - ERR_add_error_data(2, "name=", name); - return NULL; - } - - return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); - -} - -static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) -{ - char *objtmp = NULL, *p; - int objlen; - if (!(p = strchr(value, ';'))) - return 0; - if (!(gen->d.otherName = OTHERNAME_new())) - return 0; - /* - * Free this up because we will overwrite it. no need to free type_id - * because it is static - */ - ASN1_TYPE_free(gen->d.otherName->value); - if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) - return 0; - objlen = p - value; - objtmp = OPENSSL_malloc(objlen + 1); - if (objtmp == NULL) - return 0; - strncpy(objtmp, value, objlen); - objtmp[objlen] = 0; - gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); - OPENSSL_free(objtmp); - if (!gen->d.otherName->type_id) - return 0; - return 1; -} - -static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) -{ - int ret = 0; - STACK_OF(CONF_VALUE) *sk = NULL; - X509_NAME *nm = NULL; - if (!(nm = X509_NAME_new())) - goto err; - sk = X509V3_get_section(ctx, value); - if (!sk) { - X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); - ERR_add_error_data(2, "section=", value); - goto err; - } - /* FIXME: should allow other character types... */ - ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); - if (!ret) - goto err; - gen->d.dirn = nm; - -err: - if (ret == 0) - X509_NAME_free(nm); - X509V3_section_free(ctx, sk); - return ret; -} -/* - * Contributed to the OpenSSL Project by the American Registry for - * Internet Numbers ("ARIN"). - */ -/* ==================================================================== - * Copyright (c) 2006 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - */ - -/* - * Implementation of RFC 3779 section 3.2. - */ - -#include -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" -#include "x509.h" -#include "bn.h" - -#ifndef OPENSSL_NO_RFC3779 - -/* - * OpenSSL ASN.1 template translation of RFC 3779 3.2.3. - */ - -ASN1_SEQUENCE(ASRange) = { - ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), - ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) -} ASN1_SEQUENCE_END(ASRange) - -ASN1_CHOICE(ASIdOrRange) = { - ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), - ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) -} ASN1_CHOICE_END(ASIdOrRange) - -ASN1_CHOICE(ASIdentifierChoice) = { - ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), - ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) -} ASN1_CHOICE_END(ASIdentifierChoice) - -ASN1_SEQUENCE(ASIdentifiers) = { - ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), - ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) -} ASN1_SEQUENCE_END(ASIdentifiers) - -IMPLEMENT_ASN1_FUNCTIONS(ASRange) -IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange) -IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice) -IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) - -/* - * i2r method for an ASIdentifierChoice. - */ -static int i2r_ASIdentifierChoice(BIO *out, - ASIdentifierChoice *choice, - int indent, const char *msg) -{ - int i; - char *s; - if (choice == NULL) - return 1; - BIO_printf(out, "%*s%s:\n", indent, "", msg); - switch (choice->type) { - case ASIdentifierChoice_inherit: - BIO_printf(out, "%*sinherit\n", indent + 2, ""); - break; - case ASIdentifierChoice_asIdsOrRanges: - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) { - ASIdOrRange *aor = - sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - switch (aor->type) { - case ASIdOrRange_id: - if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL) - return 0; - BIO_printf(out, "%*s%s\n", indent + 2, "", s); - OPENSSL_free(s); - break; - case ASIdOrRange_range: - if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL) - return 0; - BIO_printf(out, "%*s%s-", indent + 2, "", s); - OPENSSL_free(s); - if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL) - return 0; - BIO_printf(out, "%s\n", s); - OPENSSL_free(s); - break; - default: - return 0; - } - } - break; - default: - return 0; - } - return 1; -} - -/* - * i2r method for an ASIdentifier extension. - */ -static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, - void *ext, BIO *out, int indent) -{ - ASIdentifiers *asid = ext; - return (i2r_ASIdentifierChoice(out, asid->asnum, indent, - "Autonomous System Numbers") && - i2r_ASIdentifierChoice(out, asid->rdi, indent, - "Routing Domain Identifiers")); -} - -/* - * Sort comparision function for a sequence of ASIdOrRange elements. - */ -static int ASIdOrRange_cmp(const ASIdOrRange *const *a_, - const ASIdOrRange *const *b_) -{ - const ASIdOrRange *a = *a_, *b = *b_; - - OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || - (a->type == ASIdOrRange_range && a->u.range != NULL && - a->u.range->min != NULL && a->u.range->max != NULL)); - - OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || - (b->type == ASIdOrRange_range && b->u.range != NULL && - b->u.range->min != NULL && b->u.range->max != NULL)); - - if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) - return ASN1_INTEGER_cmp(a->u.id, b->u.id); - - if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { - int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); - return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, - b->u.range->max); - } - - if (a->type == ASIdOrRange_id) - return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); - else - return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); -} - -/* - * Add an inherit element. - */ -int v3_asid_add_inherit(ASIdentifiers *asid, int which) -{ - ASIdentifierChoice **choice; - if (asid == NULL) - return 0; - switch (which) { - case V3_ASID_ASNUM: - choice = &asid->asnum; - break; - case V3_ASID_RDI: - choice = &asid->rdi; - break; - default: - return 0; - } - if (*choice == NULL) { - if ((*choice = ASIdentifierChoice_new()) == NULL) - return 0; - OPENSSL_assert((*choice)->u.inherit == NULL); - if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) - return 0; - (*choice)->type = ASIdentifierChoice_inherit; - } - return (*choice)->type == ASIdentifierChoice_inherit; -} - -/* - * Add an ID or range to an ASIdentifierChoice. - */ -int v3_asid_add_id_or_range(ASIdentifiers *asid, - int which, ASN1_INTEGER *min, ASN1_INTEGER *max) -{ - ASIdentifierChoice **choice; - ASIdOrRange *aor; - if (asid == NULL) - return 0; - switch (which) { - case V3_ASID_ASNUM: - choice = &asid->asnum; - break; - case V3_ASID_RDI: - choice = &asid->rdi; - break; - default: - return 0; - } - if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) - return 0; - if (*choice == NULL) { - if ((*choice = ASIdentifierChoice_new()) == NULL) - return 0; - OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); - (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); - if ((*choice)->u.asIdsOrRanges == NULL) - return 0; - (*choice)->type = ASIdentifierChoice_asIdsOrRanges; - } - if ((aor = ASIdOrRange_new()) == NULL) - return 0; - if (max == NULL) { - aor->type = ASIdOrRange_id; - aor->u.id = min; - } else { - aor->type = ASIdOrRange_range; - if ((aor->u.range = ASRange_new()) == NULL) - goto err; - ASN1_INTEGER_free(aor->u.range->min); - aor->u.range->min = min; - ASN1_INTEGER_free(aor->u.range->max); - aor->u.range->max = max; - } - if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) - goto err; - return 1; - - err: - ASIdOrRange_free(aor); - return 0; -} - -/* - * Extract min and max values from an ASIdOrRange. - */ -static void extract_min_max(ASIdOrRange *aor, - ASN1_INTEGER **min, ASN1_INTEGER **max) -{ - OPENSSL_assert(aor != NULL && min != NULL && max != NULL); - switch (aor->type) { - case ASIdOrRange_id: - *min = aor->u.id; - *max = aor->u.id; - return; - case ASIdOrRange_range: - *min = aor->u.range->min; - *max = aor->u.range->max; - return; - } -} - -/* - * Check whether an ASIdentifierChoice is in canonical form. - */ -static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) -{ - ASN1_INTEGER *a_max_plus_one = NULL; - BIGNUM *bn = NULL; - int i, ret = 0; - - /* - * Empty element or inheritance is canonical. - */ - if (choice == NULL || choice->type == ASIdentifierChoice_inherit) - return 1; - - /* - * If not a list, or if empty list, it's broken. - */ - if (choice->type != ASIdentifierChoice_asIdsOrRanges || - sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) - return 0; - - /* - * It's a list, check it. - */ - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { - ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); - ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; - - extract_min_max(a, &a_min, &a_max); - extract_min_max(b, &b_min, &b_max); - - /* - * Punt misordered list, overlapping start, or inverted range. - */ - if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || - ASN1_INTEGER_cmp(a_min, a_max) > 0 || - ASN1_INTEGER_cmp(b_min, b_max) > 0) - goto done; - - /* - * Calculate a_max + 1 to check for adjacency. - */ - if ((bn == NULL && (bn = BN_new()) == NULL) || - ASN1_INTEGER_to_BN(a_max, bn) == NULL || - !BN_add_word(bn, 1) || - (a_max_plus_one = - BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, - ERR_R_MALLOC_FAILURE); - goto done; - } - - /* - * Punt if adjacent or overlapping. - */ - if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) - goto done; - } - - /* - * Check for inverted range. - */ - i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; - { - ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - ASN1_INTEGER *a_min, *a_max; - if (a != NULL && a->type == ASIdOrRange_range) { - extract_min_max(a, &a_min, &a_max); - if (ASN1_INTEGER_cmp(a_min, a_max) > 0) - goto done; - } - } - - ret = 1; - - done: - ASN1_INTEGER_free(a_max_plus_one); - BN_free(bn); - return ret; -} - -/* - * Check whether an ASIdentifier extension is in canonical form. - */ -int v3_asid_is_canonical(ASIdentifiers *asid) -{ - return (asid == NULL || - (ASIdentifierChoice_is_canonical(asid->asnum) && - ASIdentifierChoice_is_canonical(asid->rdi))); -} - -/* - * Whack an ASIdentifierChoice into canonical form. - */ -static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) -{ - ASN1_INTEGER *a_max_plus_one = NULL; - BIGNUM *bn = NULL; - int i, ret = 0; - - /* - * Nothing to do for empty element or inheritance. - */ - if (choice == NULL || choice->type == ASIdentifierChoice_inherit) - return 1; - - /* - * If not a list, or if empty list, it's broken. - */ - if (choice->type != ASIdentifierChoice_asIdsOrRanges || - sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - X509V3_R_EXTENSION_VALUE_ERROR); - return 0; - } - - /* - * We have a non-empty list. Sort it. - */ - sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); - - /* - * Now check for errors and suboptimal encoding, rejecting the - * former and fixing the latter. - */ - for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { - ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); - ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; - - extract_min_max(a, &a_min, &a_max); - extract_min_max(b, &b_min, &b_max); - - /* - * Make sure we're properly sorted (paranoia). - */ - OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); - - /* - * Punt inverted ranges. - */ - if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || - ASN1_INTEGER_cmp(b_min, b_max) > 0) - goto done; - - /* - * Check for overlaps. - */ - if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - X509V3_R_EXTENSION_VALUE_ERROR); - goto done; - } - - /* - * Calculate a_max + 1 to check for adjacency. - */ - if ((bn == NULL && (bn = BN_new()) == NULL) || - ASN1_INTEGER_to_BN(a_max, bn) == NULL || - !BN_add_word(bn, 1) || - (a_max_plus_one = - BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - ERR_R_MALLOC_FAILURE); - goto done; - } - - /* - * If a and b are adjacent, merge them. - */ - if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { - ASRange *r; - switch (a->type) { - case ASIdOrRange_id: - if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) { - X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, - ERR_R_MALLOC_FAILURE); - goto done; - } - r->min = a_min; - r->max = b_max; - a->type = ASIdOrRange_range; - a->u.range = r; - break; - case ASIdOrRange_range: - ASN1_INTEGER_free(a->u.range->max); - a->u.range->max = b_max; - break; - } - switch (b->type) { - case ASIdOrRange_id: - b->u.id = NULL; - break; - case ASIdOrRange_range: - b->u.range->max = NULL; - break; - } - ASIdOrRange_free(b); - (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); - i--; - continue; - } - } - - /* - * Check for final inverted range. - */ - i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; - { - ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); - ASN1_INTEGER *a_min, *a_max; - if (a != NULL && a->type == ASIdOrRange_range) { - extract_min_max(a, &a_min, &a_max); - if (ASN1_INTEGER_cmp(a_min, a_max) > 0) - goto done; - } - } - - OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ - - ret = 1; - - done: - ASN1_INTEGER_free(a_max_plus_one); - BN_free(bn); - return ret; -} - -/* - * Whack an ASIdentifier extension into canonical form. - */ -int v3_asid_canonize(ASIdentifiers *asid) -{ - return (asid == NULL || - (ASIdentifierChoice_canonize(asid->asnum) && - ASIdentifierChoice_canonize(asid->rdi))); -} - -/* - * v2i method for an ASIdentifier extension. - */ -static void *v2i_ASIdentifiers(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, - STACK_OF(CONF_VALUE) *values) -{ - ASN1_INTEGER *min = NULL, *max = NULL; - ASIdentifiers *asid = NULL; - int i; - - if ((asid = ASIdentifiers_new()) == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - CONF_VALUE *val = sk_CONF_VALUE_value(values, i); - int i1, i2, i3, is_range, which; - - /* - * Figure out whether this is an AS or an RDI. - */ - if (!name_cmp(val->name, "AS")) { - which = V3_ASID_ASNUM; - } else if (!name_cmp(val->name, "RDI")) { - which = V3_ASID_RDI; - } else { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_EXTENSION_NAME_ERROR); - X509V3_conf_err(val); - goto err; - } - - /* - * Handle inheritance. - */ - if (!strcmp(val->value, "inherit")) { - if (v3_asid_add_inherit(asid, which)) - continue; - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_INVALID_INHERITANCE); - X509V3_conf_err(val); - goto err; - } - - /* - * Number, range, or mistake, pick it apart and figure out which. - */ - i1 = strspn(val->value, "0123456789"); - if (val->value[i1] == '\0') { - is_range = 0; - } else { - is_range = 1; - i2 = i1 + strspn(val->value + i1, " \t"); - if (val->value[i2] != '-') { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_INVALID_ASNUMBER); - X509V3_conf_err(val); - goto err; - } - i2++; - i2 = i2 + strspn(val->value + i2, " \t"); - i3 = i2 + strspn(val->value + i2, "0123456789"); - if (val->value[i3] != '\0') { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_INVALID_ASRANGE); - X509V3_conf_err(val); - goto err; - } - } - - /* - * Syntax is ok, read and add it. - */ - if (!is_range) { - if (!X509V3_get_value_int(val, &min)) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - goto err; - } - } else { - char *s = BUF_strdup(val->value); - if (s == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - goto err; - } - s[i1] = '\0'; - min = s2i_ASN1_INTEGER(NULL, s); - max = s2i_ASN1_INTEGER(NULL, s + i2); - OPENSSL_free(s); - if (min == NULL || max == NULL) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - goto err; - } - if (ASN1_INTEGER_cmp(min, max) > 0) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, - X509V3_R_EXTENSION_VALUE_ERROR); - goto err; - } - } - if (!v3_asid_add_id_or_range(asid, which, min, max)) { - X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); - goto err; - } - min = max = NULL; - } - - /* - * Canonize the result, then we're done. - */ - if (!v3_asid_canonize(asid)) - goto err; - return asid; - - err: - ASIdentifiers_free(asid); - ASN1_INTEGER_free(min); - ASN1_INTEGER_free(max); - return NULL; -} - -/* - * OpenSSL dispatch. - */ -const X509V3_EXT_METHOD v3_asid = { - NID_sbgp_autonomousSysNum, /* nid */ - 0, /* flags */ - ASN1_ITEM_ref(ASIdentifiers), /* template */ - 0, 0, 0, 0, /* old functions, ignored */ - 0, /* i2s */ - 0, /* s2i */ - 0, /* i2v */ - v2i_ASIdentifiers, /* v2i */ - i2r_ASIdentifiers, /* i2r */ - 0, /* r2i */ - NULL /* extension-specific data */ -}; - -/* - * Figure out whether extension uses inheritance. - */ -int v3_asid_inherits(ASIdentifiers *asid) -{ - return (asid != NULL && - ((asid->asnum != NULL && - asid->asnum->type == ASIdentifierChoice_inherit) || - (asid->rdi != NULL && - asid->rdi->type == ASIdentifierChoice_inherit))); -} - -/* - * Figure out whether parent contains child. - */ -static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) -{ - ASN1_INTEGER *p_min, *p_max, *c_min, *c_max; - int p, c; - - if (child == NULL || parent == child) - return 1; - if (parent == NULL) - return 0; - - p = 0; - for (c = 0; c < sk_ASIdOrRange_num(child); c++) { - extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max); - for (;; p++) { - if (p >= sk_ASIdOrRange_num(parent)) - return 0; - extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max); - if (ASN1_INTEGER_cmp(p_max, c_max) < 0) - continue; - if (ASN1_INTEGER_cmp(p_min, c_min) > 0) - return 0; - break; - } - } - - return 1; -} - -/* - * Test whether a is a subet of b. - */ -int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) -{ - return (a == NULL || - a == b || - (b != NULL && - !v3_asid_inherits(a) && - !v3_asid_inherits(b) && - asid_contains(b->asnum->u.asIdsOrRanges, - a->asnum->u.asIdsOrRanges) && - asid_contains(b->rdi->u.asIdsOrRanges, - a->rdi->u.asIdsOrRanges))); -} - -/* - * Validation error handling via callback. - */ -# define validation_err(_err_) \ - do { \ - if (ctx != NULL) { \ - ctx->error = _err_; \ - ctx->error_depth = i; \ - ctx->current_cert = x; \ - ret = ctx->verify_cb(0, ctx); \ - } else { \ - ret = 0; \ - } \ - if (!ret) \ - goto done; \ - } while (0) - -/* - * Core code for RFC 3779 3.3 path validation. - */ -static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, - STACK_OF(X509) *chain, - ASIdentifiers *ext) -{ - ASIdOrRanges *child_as = NULL, *child_rdi = NULL; - int i, ret = 1, inherit_as = 0, inherit_rdi = 0; - X509 *x; - - OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); - OPENSSL_assert(ctx != NULL || ext != NULL); - OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); - - /* - * Figure out where to start. If we don't have an extension to - * check, we're done. Otherwise, check canonical form and - * set up for walking up the chain. - */ - if (ext != NULL) { - i = -1; - x = NULL; - } else { - i = 0; - x = sk_X509_value(chain, i); - OPENSSL_assert(x != NULL); - if ((ext = x->rfc3779_asid) == NULL) - goto done; - } - if (!v3_asid_is_canonical(ext)) - validation_err(X509_V_ERR_INVALID_EXTENSION); - if (ext->asnum != NULL) { - switch (ext->asnum->type) { - case ASIdentifierChoice_inherit: - inherit_as = 1; - break; - case ASIdentifierChoice_asIdsOrRanges: - child_as = ext->asnum->u.asIdsOrRanges; - break; - } - } - if (ext->rdi != NULL) { - switch (ext->rdi->type) { - case ASIdentifierChoice_inherit: - inherit_rdi = 1; - break; - case ASIdentifierChoice_asIdsOrRanges: - child_rdi = ext->rdi->u.asIdsOrRanges; - break; - } - } - - /* - * Now walk up the chain. Extensions must be in canonical form, no - * cert may list resources that its parent doesn't list. - */ - for (i++; i < sk_X509_num(chain); i++) { - x = sk_X509_value(chain, i); - OPENSSL_assert(x != NULL); - if (x->rfc3779_asid == NULL) { - if (child_as != NULL || child_rdi != NULL) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - continue; - } - if (!v3_asid_is_canonical(x->rfc3779_asid)) - validation_err(X509_V_ERR_INVALID_EXTENSION); - if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - child_as = NULL; - inherit_as = 0; - } - if (x->rfc3779_asid->asnum != NULL && - x->rfc3779_asid->asnum->type == - ASIdentifierChoice_asIdsOrRanges) { - if (inherit_as - || asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, - child_as)) { - child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; - inherit_as = 0; - } else { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - child_rdi = NULL; - inherit_rdi = 0; - } - if (x->rfc3779_asid->rdi != NULL && - x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { - if (inherit_rdi || - asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, - child_rdi)) { - child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; - inherit_rdi = 0; - } else { - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - } - } - - /* - * Trust anchor can't inherit. - */ - OPENSSL_assert(x != NULL); - if (x->rfc3779_asid != NULL) { - if (x->rfc3779_asid->asnum != NULL && - x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - if (x->rfc3779_asid->rdi != NULL && - x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) - validation_err(X509_V_ERR_UNNESTED_RESOURCE); - } - - done: - return ret; -} - -# undef validation_err - -/* - * RFC 3779 3.3 path validation -- called from X509_verify_cert(). - */ -int v3_asid_validate_path(X509_STORE_CTX *ctx) -{ - return v3_asid_validate_path_internal(ctx, ctx->chain, NULL); -} - -/* - * RFC 3779 3.3 path validation of an extension. - * Test whether chain covers extension. - */ -int v3_asid_validate_resource_set(STACK_OF(X509) *chain, - ASIdentifiers *ext, int allow_inheritance) -{ - if (ext == NULL) - return 1; - if (chain == NULL || sk_X509_num(chain) == 0) - return 0; - if (!allow_inheritance && v3_asid_inherits(ext)) - return 0; - return v3_asid_validate_path_internal(NULL, chain, ext); -} - -#endif /* OPENSSL_NO_RFC3779 */ -/* v3_bcons.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "conf.h" -// #include "x509v3.h" - -static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - BASIC_CONSTRAINTS *bcons, - STACK_OF(CONF_VALUE) - *extlist); -static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values); - -const X509V3_EXT_METHOD v3_bcons = { - NID_basic_constraints, 0, - ASN1_ITEM_ref(BASIC_CONSTRAINTS), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS, - (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, - NULL, NULL, - NULL -}; - -ASN1_SEQUENCE(BASIC_CONSTRAINTS) = { - ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN), - ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER) -} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS) - -IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) - -static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - BASIC_CONSTRAINTS *bcons, - STACK_OF(CONF_VALUE) - *extlist) -{ - X509V3_add_value_bool("CA", bcons->ca, &extlist); - X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); - return extlist; -} - -static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - BASIC_CONSTRAINTS *bcons = NULL; - CONF_VALUE *val; - int i; - if (!(bcons = BASIC_CONSTRAINTS_new())) { - X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - val = sk_CONF_VALUE_value(values, i); - if (!strcmp(val->name, "CA")) { - if (!X509V3_get_value_bool(val, &bcons->ca)) - goto err; - } else if (!strcmp(val->name, "pathlen")) { - if (!X509V3_get_value_int(val, &bcons->pathlen)) - goto err; - } else { - X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME); - X509V3_conf_err(val); - goto err; - } - } - return bcons; - err: - BASIC_CONSTRAINTS_free(bcons); - return NULL; -} -/* v3_bitst.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "x509v3.h" - -static BIT_STRING_BITNAME ns_cert_type_table[] = { - {0, "SSL Client", "client"}, - {1, "SSL Server", "server"}, - {2, "S/MIME", "email"}, - {3, "Object Signing", "objsign"}, - {4, "Unused", "reserved"}, - {5, "SSL CA", "sslCA"}, - {6, "S/MIME CA", "emailCA"}, - {7, "Object Signing CA", "objCA"}, - {-1, NULL, NULL} -}; - -static BIT_STRING_BITNAME key_usage_type_table[] = { - {0, "Digital Signature", "digitalSignature"}, - {1, "Non Repudiation", "nonRepudiation"}, - {2, "Key Encipherment", "keyEncipherment"}, - {3, "Data Encipherment", "dataEncipherment"}, - {4, "Key Agreement", "keyAgreement"}, - {5, "Certificate Sign", "keyCertSign"}, - {6, "CRL Sign", "cRLSign"}, - {7, "Encipher Only", "encipherOnly"}, - {8, "Decipher Only", "decipherOnly"}, - {-1, NULL, NULL} -}; - -const X509V3_EXT_METHOD v3_nscert = -EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); -const X509V3_EXT_METHOD v3_key_usage = -EXT_BITSTRING(NID_key_usage, key_usage_type_table); - -STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - ASN1_BIT_STRING *bits, - STACK_OF(CONF_VALUE) *ret) -{ - BIT_STRING_BITNAME *bnam; - for (bnam = method->usr_data; bnam->lname; bnam++) { - if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) - X509V3_add_value(bnam->lname, NULL, &ret); - } - return ret; -} - -ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - CONF_VALUE *val; - ASN1_BIT_STRING *bs; - int i; - BIT_STRING_BITNAME *bnam; - if (!(bs = M_ASN1_BIT_STRING_new())) { - X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - for (bnam = method->usr_data; bnam->lname; bnam++) { - if (!strcmp(bnam->sname, val->name) || - !strcmp(bnam->lname, val->name)) { - if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { - X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, - ERR_R_MALLOC_FAILURE); - M_ASN1_BIT_STRING_free(bs); - return NULL; - } - break; - } - } - if (!bnam->lname) { - X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, - X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); - X509V3_conf_err(val); - M_ASN1_BIT_STRING_free(bs); - return NULL; - } - } - return bs; -} -/* v3_conf.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* extension creation utilities */ - -#include -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "x509.h" -// #include "x509v3.h" - -static int v3_check_critical(char **value); -static int v3_check_generic(char **value); -static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, - int crit, char *value); -static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, - int crit, int type, - X509V3_CTX *ctx); -static char *conf_lhash_get_string(void *db, char *section, char *value); -static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section); -static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, - int ext_nid, int crit, void *ext_struc); -static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, - long *ext_len); -/* CONF *conf: Config file */ -/* char *name: Name */ -/* char *value: Value */ -X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, - char *value) -{ - int crit; - int ext_type; - X509_EXTENSION *ret; - crit = v3_check_critical(&value); - if ((ext_type = v3_check_generic(&value))) - return v3_generic_extension(name, value, crit, ext_type, ctx); - ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); - if (!ret) { - X509V3err(X509V3_F_X509V3_EXT_NCONF, X509V3_R_ERROR_IN_EXTENSION); - ERR_add_error_data(4, "name=", name, ", value=", value); - } - return ret; -} - -/* CONF *conf: Config file */ -/* char *value: Value */ -X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, - char *value) -{ - int crit; - int ext_type; - crit = v3_check_critical(&value); - if ((ext_type = v3_check_generic(&value))) - return v3_generic_extension(OBJ_nid2sn(ext_nid), - value, crit, ext_type, ctx); - return do_ext_nconf(conf, ctx, ext_nid, crit, value); -} - -/* CONF *conf: Config file */ -/* char *value: Value */ -static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, - int crit, char *value) -{ - const X509V3_EXT_METHOD *method; - X509_EXTENSION *ext; - STACK_OF(CONF_VALUE) *nval; - void *ext_struc; - if (ext_nid == NID_undef) { - X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME); - return NULL; - } - if (!(method = X509V3_EXT_get_nid(ext_nid))) { - X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION); - return NULL; - } - /* Now get internal extension representation based on type */ - if (method->v2i) { - if (*value == '@') - nval = NCONF_get_section(conf, value + 1); - else - nval = X509V3_parse_list(value); - if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) { - X509V3err(X509V3_F_DO_EXT_NCONF, - X509V3_R_INVALID_EXTENSION_STRING); - ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", - value); - if (*value != '@') - sk_CONF_VALUE_free(nval); - return NULL; - } - ext_struc = method->v2i(method, ctx, nval); - if (*value != '@') - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - if (!ext_struc) - return NULL; - } else if (method->s2i) { - if (!(ext_struc = method->s2i(method, ctx, value))) - return NULL; - } else if (method->r2i) { - if (!ctx->db || !ctx->db_meth) { - X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE); - return NULL; - } - if (!(ext_struc = method->r2i(method, ctx, value))) - return NULL; - } else { - X509V3err(X509V3_F_DO_EXT_NCONF, - X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); - ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); - return NULL; - } - - ext = do_ext_i2d(method, ext_nid, crit, ext_struc); - if (method->it) - ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); - else - method->ext_free(ext_struc); - return ext; - -} - -static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, - int ext_nid, int crit, void *ext_struc) -{ - unsigned char *ext_der; - int ext_len; - ASN1_OCTET_STRING *ext_oct; - X509_EXTENSION *ext; - /* Convert internal representation to DER */ - if (method->it) { - ext_der = NULL; - ext_len = - ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); - if (ext_len < 0) - goto merr; - } else { - unsigned char *p; - ext_len = method->i2d(ext_struc, NULL); - if (!(ext_der = OPENSSL_malloc(ext_len))) - goto merr; - p = ext_der; - method->i2d(ext_struc, &p); - } - if (!(ext_oct = M_ASN1_OCTET_STRING_new())) - goto merr; - ext_oct->data = ext_der; - ext_oct->length = ext_len; - - ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); - if (!ext) - goto merr; - M_ASN1_OCTET_STRING_free(ext_oct); - - return ext; - - merr: - X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE); - return NULL; - -} - -/* Given an internal structure, nid and critical flag create an extension */ - -X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) -{ - const X509V3_EXT_METHOD *method; - if (!(method = X509V3_EXT_get_nid(ext_nid))) { - X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION); - return NULL; - } - return do_ext_i2d(method, ext_nid, crit, ext_struc); -} - -/* Check the extension string for critical flag */ -static int v3_check_critical(char **value) -{ - char *p = *value; - if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) - return 0; - p += 9; - while (isspace((unsigned char)*p)) - p++; - *value = p; - return 1; -} - -/* Check extension string for generic extension and return the type */ -static int v3_check_generic(char **value) -{ - int gen_type = 0; - char *p = *value; - if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { - p += 4; - gen_type = 1; - } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { - p += 5; - gen_type = 2; - } else - return 0; - - while (isspace((unsigned char)*p)) - p++; - *value = p; - return gen_type; -} - -/* Create a generic extension: for now just handle DER type */ -static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, - int crit, int gen_type, - X509V3_CTX *ctx) -{ - unsigned char *ext_der = NULL; - long ext_len; - ASN1_OBJECT *obj = NULL; - ASN1_OCTET_STRING *oct = NULL; - X509_EXTENSION *extension = NULL; - if (!(obj = OBJ_txt2obj(ext, 0))) { - X509V3err(X509V3_F_V3_GENERIC_EXTENSION, - X509V3_R_EXTENSION_NAME_ERROR); - ERR_add_error_data(2, "name=", ext); - goto err; - } - - if (gen_type == 1) - ext_der = string_to_hex(value, &ext_len); - else if (gen_type == 2) - ext_der = generic_asn1(value, ctx, &ext_len); - - if (ext_der == NULL) { - X509V3err(X509V3_F_V3_GENERIC_EXTENSION, - X509V3_R_EXTENSION_VALUE_ERROR); - ERR_add_error_data(2, "value=", value); - goto err; - } - - if (!(oct = M_ASN1_OCTET_STRING_new())) { - X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE); - goto err; - } - - oct->data = ext_der; - oct->length = ext_len; - ext_der = NULL; - - extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); - - err: - ASN1_OBJECT_free(obj); - M_ASN1_OCTET_STRING_free(oct); - if (ext_der) - OPENSSL_free(ext_der); - return extension; - -} - -static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, - long *ext_len) -{ - ASN1_TYPE *typ; - unsigned char *ext_der = NULL; - typ = ASN1_generate_v3(value, ctx); - if (typ == NULL) - return NULL; - *ext_len = i2d_ASN1_TYPE(typ, &ext_der); - ASN1_TYPE_free(typ); - return ext_der; -} - -/* - * This is the main function: add a bunch of extensions based on a config - * file section to an extension STACK. - */ - -int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, - STACK_OF(X509_EXTENSION) **sk) -{ - X509_EXTENSION *ext; - STACK_OF(CONF_VALUE) *nval; - CONF_VALUE *val; - int i; - if (!(nval = NCONF_get_section(conf, section))) - return 0; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) - return 0; - if (sk != NULL) { - if (X509v3_add_ext(sk, ext, -1) == NULL) { - X509_EXTENSION_free(ext); - return 0; - } - } - X509_EXTENSION_free(ext); - } - return 1; -} - -/* - * Convenience functions to add extensions to a certificate, CRL and request - */ - -int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, - X509 *cert) -{ - STACK_OF(X509_EXTENSION) **sk = NULL; - if (cert) - sk = &cert->cert_info->extensions; - return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -} - -/* Same as above but for a CRL */ - -int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, - X509_CRL *crl) -{ - STACK_OF(X509_EXTENSION) **sk = NULL; - if (crl) - sk = &crl->crl->extensions; - return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); -} - -/* Add extensions to certificate request */ - -int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, - X509_REQ *req) -{ - STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; - int i; - if (req) - sk = &extlist; - i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); - if (!i || !sk) - return i; - i = X509_REQ_add_extensions(req, extlist); - sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); - return i; -} - -/* Config database functions */ - -char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section) -{ - if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { - X509V3err(X509V3_F_X509V3_GET_STRING, X509V3_R_OPERATION_NOT_DEFINED); - return NULL; - } - if (ctx->db_meth->get_string) - return ctx->db_meth->get_string(ctx->db, name, section); - return NULL; -} - -STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section) -{ - if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { - X509V3err(X509V3_F_X509V3_GET_SECTION, - X509V3_R_OPERATION_NOT_DEFINED); - return NULL; - } - if (ctx->db_meth->get_section) - return ctx->db_meth->get_section(ctx->db, section); - return NULL; -} - -void X509V3_string_free(X509V3_CTX *ctx, char *str) -{ - if (!str) - return; - if (ctx->db_meth->free_string) - ctx->db_meth->free_string(ctx->db, str); -} - -void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) -{ - if (!section) - return; - if (ctx->db_meth->free_section) - ctx->db_meth->free_section(ctx->db, section); -} - -static char *nconf_get_string(void *db, char *section, char *value) -{ - return NCONF_get_string(db, section, value); -} - -static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section) -{ - return NCONF_get_section(db, section); -} - -static X509V3_CONF_METHOD nconf_method = { - nconf_get_string, - nconf_get_section, - NULL, - NULL -}; - -void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) -{ - ctx->db_meth = &nconf_method; - ctx->db = conf; -} - -void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, - X509_CRL *crl, int flags) -{ - ctx->issuer_cert = issuer; - ctx->subject_cert = subj; - ctx->crl = crl; - ctx->subject_req = req; - ctx->flags = flags; -} - -/* Old conf compatibility functions */ - -X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - char *name, char *value) -{ - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_nconf(&ctmp, ctx, name, value); -} - -/* LHASH *conf: Config file */ -/* char *value: Value */ -X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, - X509V3_CTX *ctx, int ext_nid, char *value) -{ - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value); -} - -static char *conf_lhash_get_string(void *db, char *section, char *value) -{ - return CONF_get_string(db, section, value); -} - -static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section) -{ - return CONF_get_section(db, section); -} - -static X509V3_CONF_METHOD conf_lhash_method = { - conf_lhash_get_string, - conf_lhash_get_section, - NULL, - NULL -}; - -void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) -{ - ctx->db_meth = &conf_lhash_method; - ctx->db = lhash; -} - -int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - char *section, X509 *cert) -{ - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert); -} - -/* Same as above but for a CRL */ - -int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - char *section, X509_CRL *crl) -{ - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl); -} - -/* Add extensions to certificate request */ - -int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - char *section, X509_REQ *req) -{ - CONF ctmp; - CONF_set_nconf(&ctmp, conf); - return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req); -} -/* v3_cpols.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" - -#include "pcy_int.h" - -/* Certificate policies extension support: this one is a bit complex... */ - -static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, - BIO *out, int indent); -static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *value); -static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, - int indent); -static void print_notice(BIO *out, USERNOTICE *notice, int indent); -static POLICYINFO *policy_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *polstrs, int ia5org); -static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *unot, int ia5org); -static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); - -const X509V3_EXT_METHOD v3_cpols = { - NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES), - 0, 0, 0, 0, - 0, 0, - 0, 0, - (X509V3_EXT_I2R)i2r_certpol, - (X509V3_EXT_R2I)r2i_certpol, - NULL -}; - -ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO) -ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES) - -IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) - -ASN1_SEQUENCE(POLICYINFO) = { - ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), - ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO) -} ASN1_SEQUENCE_END(POLICYINFO) - -IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO) - -ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY); - -ASN1_ADB(POLICYQUALINFO) = { - ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)), - ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)) -} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL); - -ASN1_SEQUENCE(POLICYQUALINFO) = { - ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), - ASN1_ADB_OBJECT(POLICYQUALINFO) -} ASN1_SEQUENCE_END(POLICYQUALINFO) - -IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO) - -ASN1_SEQUENCE(USERNOTICE) = { - ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), - ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT) -} ASN1_SEQUENCE_END(USERNOTICE) - -IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE) - -ASN1_SEQUENCE(NOTICEREF) = { - ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), - ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER) -} ASN1_SEQUENCE_END(NOTICEREF) - -IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF) - -static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *value) -{ - STACK_OF(POLICYINFO) *pols = NULL; - char *pstr; - POLICYINFO *pol; - ASN1_OBJECT *pobj; - STACK_OF(CONF_VALUE) *vals; - CONF_VALUE *cnf; - int i, ia5org; - pols = sk_POLICYINFO_new_null(); - if (pols == NULL) { - X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); - return NULL; - } - vals = X509V3_parse_list(value); - if (vals == NULL) { - X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB); - goto err; - } - ia5org = 0; - for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { - cnf = sk_CONF_VALUE_value(vals, i); - if (cnf->value || !cnf->name) { - X509V3err(X509V3_F_R2I_CERTPOL, - X509V3_R_INVALID_POLICY_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pstr = cnf->name; - if (!strcmp(pstr, "ia5org")) { - ia5org = 1; - continue; - } else if (*pstr == '@') { - STACK_OF(CONF_VALUE) *polsect; - polsect = X509V3_get_section(ctx, pstr + 1); - if (!polsect) { - X509V3err(X509V3_F_R2I_CERTPOL, X509V3_R_INVALID_SECTION); - - X509V3_conf_err(cnf); - goto err; - } - pol = policy_section(ctx, polsect, ia5org); - X509V3_section_free(ctx, polsect); - if (!pol) - goto err; - } else { - if (!(pobj = OBJ_txt2obj(cnf->name, 0))) { - X509V3err(X509V3_F_R2I_CERTPOL, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pol = POLICYINFO_new(); - if (pol == NULL) { - X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); - goto err; - } - pol->policyid = pobj; - } - if (!sk_POLICYINFO_push(pols, pol)) { - POLICYINFO_free(pol); - X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); - goto err; - } - } - sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); - return pols; - err: - sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); - sk_POLICYINFO_pop_free(pols, POLICYINFO_free); - return NULL; -} - -static POLICYINFO *policy_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *polstrs, int ia5org) -{ - int i; - CONF_VALUE *cnf; - POLICYINFO *pol; - POLICYQUALINFO *qual; - if (!(pol = POLICYINFO_new())) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { - cnf = sk_CONF_VALUE_value(polstrs, i); - if (!strcmp(cnf->name, "policyIdentifier")) { - ASN1_OBJECT *pobj; - if (!(pobj = OBJ_txt2obj(cnf->value, 0))) { - X509V3err(X509V3_F_POLICY_SECTION, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(cnf); - goto err; - } - pol->policyid = pobj; - - } else if (!name_cmp(cnf->name, "CPS")) { - if (!pol->qualifiers) - pol->qualifiers = sk_POLICYQUALINFO_new_null(); - if (!(qual = POLICYQUALINFO_new())) - goto merr; - if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) - goto merr; - if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_cps))) { - X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR); - goto err; - } - if (!(qual->d.cpsuri = M_ASN1_IA5STRING_new())) - goto merr; - if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, - strlen(cnf->value))) - goto merr; - } else if (!name_cmp(cnf->name, "userNotice")) { - STACK_OF(CONF_VALUE) *unot; - if (*cnf->value != '@') { - X509V3err(X509V3_F_POLICY_SECTION, - X509V3_R_EXPECTED_A_SECTION_NAME); - X509V3_conf_err(cnf); - goto err; - } - unot = X509V3_get_section(ctx, cnf->value + 1); - if (!unot) { - X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_SECTION); - - X509V3_conf_err(cnf); - goto err; - } - qual = notice_section(ctx, unot, ia5org); - X509V3_section_free(ctx, unot); - if (!qual) - goto err; - if (!pol->qualifiers) - pol->qualifiers = sk_POLICYQUALINFO_new_null(); - if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) - goto merr; - } else { - X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_OPTION); - - X509V3_conf_err(cnf); - goto err; - } - } - if (!pol->policyid) { - X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_NO_POLICY_IDENTIFIER); - goto err; - } - - return pol; - - merr: - X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE); - - err: - POLICYINFO_free(pol); - return NULL; - -} - -static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *unot, int ia5org) -{ - int i, ret; - CONF_VALUE *cnf; - USERNOTICE *not; - POLICYQUALINFO *qual; - if (!(qual = POLICYQUALINFO_new())) - goto merr; - if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice))) { - X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR); - goto err; - } - if (!(not = USERNOTICE_new())) - goto merr; - qual->d.usernotice = not; - for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { - cnf = sk_CONF_VALUE_value(unot, i); - if (!strcmp(cnf->name, "explicitText")) { - if (!(not->exptext = M_ASN1_VISIBLESTRING_new())) - goto merr; - if (!ASN1_STRING_set(not->exptext, cnf->value, - strlen(cnf->value))) - goto merr; - } else if (!strcmp(cnf->name, "organization")) { - NOTICEREF *nref; - if (!not->noticeref) { - if (!(nref = NOTICEREF_new())) - goto merr; - not->noticeref = nref; - } else - nref = not->noticeref; - if (ia5org) - nref->organization->type = V_ASN1_IA5STRING; - else - nref->organization->type = V_ASN1_VISIBLESTRING; - if (!ASN1_STRING_set(nref->organization, cnf->value, - strlen(cnf->value))) - goto merr; - } else if (!strcmp(cnf->name, "noticeNumbers")) { - NOTICEREF *nref; - STACK_OF(CONF_VALUE) *nos; - if (!not->noticeref) { - if (!(nref = NOTICEREF_new())) - goto merr; - not->noticeref = nref; - } else - nref = not->noticeref; - nos = X509V3_parse_list(cnf->value); - if (!nos || !sk_CONF_VALUE_num(nos)) { - X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_NUMBERS); - X509V3_conf_err(cnf); - goto err; - } - ret = nref_nos(nref->noticenos, nos); - sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); - if (!ret) - goto err; - } else { - X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_OPTION); - X509V3_conf_err(cnf); - goto err; - } - } - - if (not->noticeref && - (!not->noticeref->noticenos || !not->noticeref->organization)) { - X509V3err(X509V3_F_NOTICE_SECTION, - X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); - goto err; - } - - return qual; - - merr: - X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE); - - err: - POLICYQUALINFO_free(qual); - return NULL; -} - -static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) -{ - CONF_VALUE *cnf; - ASN1_INTEGER *aint; - - int i; - - for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { - cnf = sk_CONF_VALUE_value(nos, i); - if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { - X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER); - goto err; - } - if (!sk_ASN1_INTEGER_push(nnums, aint)) - goto merr; - } - return 1; - - merr: - ASN1_INTEGER_free(aint); - X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE); - - err: - return 0; -} - -static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, - BIO *out, int indent) -{ - int i; - POLICYINFO *pinfo; - /* First print out the policy OIDs */ - for (i = 0; i < sk_POLICYINFO_num(pol); i++) { - pinfo = sk_POLICYINFO_value(pol, i); - BIO_printf(out, "%*sPolicy: ", indent, ""); - i2a_ASN1_OBJECT(out, pinfo->policyid); - BIO_puts(out, "\n"); - if (pinfo->qualifiers) - print_qualifiers(out, pinfo->qualifiers, indent + 2); - } - return 1; -} - -static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, - int indent) -{ - POLICYQUALINFO *qualinfo; - int i; - for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { - qualinfo = sk_POLICYQUALINFO_value(quals, i); - switch (OBJ_obj2nid(qualinfo->pqualid)) { - case NID_id_qt_cps: - BIO_printf(out, "%*sCPS: %s\n", indent, "", - qualinfo->d.cpsuri->data); - break; - - case NID_id_qt_unotice: - BIO_printf(out, "%*sUser Notice:\n", indent, ""); - print_notice(out, qualinfo->d.usernotice, indent + 2); - break; - - default: - BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, ""); - - i2a_ASN1_OBJECT(out, qualinfo->pqualid); - BIO_puts(out, "\n"); - break; - } - } -} - -static void print_notice(BIO *out, USERNOTICE *notice, int indent) -{ - int i; - if (notice->noticeref) { - NOTICEREF *ref; - ref = notice->noticeref; - BIO_printf(out, "%*sOrganization: %s\n", indent, "", - ref->organization->data); - BIO_printf(out, "%*sNumber%s: ", indent, "", - sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); - for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { - ASN1_INTEGER *num; - char *tmp; - num = sk_ASN1_INTEGER_value(ref->noticenos, i); - if (i) - BIO_puts(out, ", "); - if (num == NULL) - BIO_puts(out, "(null)"); - else { - tmp = i2s_ASN1_INTEGER(NULL, num); - if (tmp == NULL) - return; - BIO_puts(out, tmp); - OPENSSL_free(tmp); - } - } - BIO_puts(out, "\n"); - } - if (notice->exptext) - BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", - notice->exptext->data); -} - -void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) -{ - const X509_POLICY_DATA *dat = node->data; - - BIO_printf(out, "%*sPolicy: ", indent, ""); - - i2a_ASN1_OBJECT(out, dat->valid_policy); - BIO_puts(out, "\n"); - BIO_printf(out, "%*s%s\n", indent + 2, "", - node_data_critical(dat) ? "Critical" : "Non Critical"); - if (dat->qualifier_set) - print_qualifiers(out, dat->qualifier_set, indent + 2); - else - BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); -} - - -IMPLEMENT_STACK_OF(X509_POLICY_NODE) - -IMPLEMENT_STACK_OF(X509_POLICY_DATA) -/* v3_crld.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" - -static void *v2i_crld(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, - int indent); - -const X509V3_EXT_METHOD v3_crld = { - NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), - 0, 0, 0, 0, - 0, 0, - 0, - v2i_crld, - i2r_crldp, 0, - NULL -}; - -const X509V3_EXT_METHOD v3_freshest_crl = { - NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), - 0, 0, 0, 0, - 0, 0, - 0, - v2i_crld, - i2r_crldp, 0, - NULL -}; - -static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, - char *sect) -{ - STACK_OF(CONF_VALUE) *gnsect; - STACK_OF(GENERAL_NAME) *gens; - if (*sect == '@') - gnsect = X509V3_get_section(ctx, sect + 1); - else - gnsect = X509V3_parse_list(sect); - if (!gnsect) { - X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, X509V3_R_SECTION_NOT_FOUND); - return NULL; - } - gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); - if (*sect == '@') - X509V3_section_free(ctx, gnsect); - else - sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); - return gens; -} - -static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, - CONF_VALUE *cnf) -{ - STACK_OF(GENERAL_NAME) *fnm = NULL; - STACK_OF(X509_NAME_ENTRY) *rnm = NULL; - if (!strncmp(cnf->name, "fullname", 9)) { - fnm = gnames_from_sectname(ctx, cnf->value); - if (!fnm) - goto err; - } else if (!strcmp(cnf->name, "relativename")) { - int ret; - STACK_OF(CONF_VALUE) *dnsect; - X509_NAME *nm; - nm = X509_NAME_new(); - if (!nm) - return -1; - dnsect = X509V3_get_section(ctx, cnf->value); - if (!dnsect) { - X509V3err(X509V3_F_SET_DIST_POINT_NAME, - X509V3_R_SECTION_NOT_FOUND); - return -1; - } - ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); - X509V3_section_free(ctx, dnsect); - rnm = nm->entries; - nm->entries = NULL; - X509_NAME_free(nm); - if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) - goto err; - /* - * Since its a name fragment can't have more than one RDNSequence - */ - if (sk_X509_NAME_ENTRY_value(rnm, - sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { - X509V3err(X509V3_F_SET_DIST_POINT_NAME, - X509V3_R_INVALID_MULTIPLE_RDNS); - goto err; - } - } else - return 0; - - if (*pdp) { - X509V3err(X509V3_F_SET_DIST_POINT_NAME, - X509V3_R_DISTPOINT_ALREADY_SET); - goto err; - } - - *pdp = DIST_POINT_NAME_new(); - if (!*pdp) - goto err; - if (fnm) { - (*pdp)->type = 0; - (*pdp)->name.fullname = fnm; - } else { - (*pdp)->type = 1; - (*pdp)->name.relativename = rnm; - } - - return 1; - - err: - if (fnm) - sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); - if (rnm) - sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); - return -1; -} - -static const BIT_STRING_BITNAME reason_flags[] = { - {0, "Unused", "unused"}, - {1, "Key Compromise", "keyCompromise"}, - {2, "CA Compromise", "CACompromise"}, - {3, "Affiliation Changed", "affiliationChanged"}, - {4, "Superseded", "superseded"}, - {5, "Cessation Of Operation", "cessationOfOperation"}, - {6, "Certificate Hold", "certificateHold"}, - {7, "Privilege Withdrawn", "privilegeWithdrawn"}, - {8, "AA Compromise", "AACompromise"}, - {-1, NULL, NULL} -}; - -static int set_reasons(ASN1_BIT_STRING **preas, char *value) -{ - STACK_OF(CONF_VALUE) *rsk = NULL; - const BIT_STRING_BITNAME *pbn; - const char *bnam; - int i, ret = 0; - rsk = X509V3_parse_list(value); - if (!rsk) - return 0; - if (*preas) - return 0; - for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { - bnam = sk_CONF_VALUE_value(rsk, i)->name; - if (!*preas) { - *preas = ASN1_BIT_STRING_new(); - if (!*preas) - goto err; - } - for (pbn = reason_flags; pbn->lname; pbn++) { - if (!strcmp(pbn->sname, bnam)) { - if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) - goto err; - break; - } - } - if (!pbn->lname) - goto err; - } - ret = 1; - - err: - sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); - return ret; -} - -static int print_reasons(BIO *out, const char *rname, - ASN1_BIT_STRING *rflags, int indent) -{ - int first = 1; - const BIT_STRING_BITNAME *pbn; - BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); - for (pbn = reason_flags; pbn->lname; pbn++) { - if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { - if (first) - first = 0; - else - BIO_puts(out, ", "); - BIO_puts(out, pbn->lname); - } - } - if (first) - BIO_puts(out, "\n"); - else - BIO_puts(out, "\n"); - return 1; -} - -static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - int i; - CONF_VALUE *cnf; - DIST_POINT *point = NULL; - point = DIST_POINT_new(); - if (!point) - goto err; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - int ret; - cnf = sk_CONF_VALUE_value(nval, i); - ret = set_dist_point_name(&point->distpoint, ctx, cnf); - if (ret > 0) - continue; - if (ret < 0) - goto err; - if (!strcmp(cnf->name, "reasons")) { - if (!set_reasons(&point->reasons, cnf->value)) - goto err; - } else if (!strcmp(cnf->name, "CRLissuer")) { - point->CRLissuer = gnames_from_sectname(ctx, cnf->value); - if (!point->CRLissuer) - goto err; - } - } - - return point; - - err: - if (point) - DIST_POINT_free(point); - return NULL; -} - -static void *v2i_crld(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - STACK_OF(DIST_POINT) *crld = NULL; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gen = NULL; - CONF_VALUE *cnf; - int i; - if (!(crld = sk_DIST_POINT_new_null())) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - DIST_POINT *point; - cnf = sk_CONF_VALUE_value(nval, i); - if (!cnf->value) { - STACK_OF(CONF_VALUE) *dpsect; - dpsect = X509V3_get_section(ctx, cnf->name); - if (!dpsect) - goto err; - point = crldp_from_section(ctx, dpsect); - X509V3_section_free(ctx, dpsect); - if (!point) - goto err; - if (!sk_DIST_POINT_push(crld, point)) { - DIST_POINT_free(point); - goto merr; - } - } else { - if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) - goto err; - if (!(gens = GENERAL_NAMES_new())) - goto merr; - if (!sk_GENERAL_NAME_push(gens, gen)) - goto merr; - gen = NULL; - if (!(point = DIST_POINT_new())) - goto merr; - if (!sk_DIST_POINT_push(crld, point)) { - DIST_POINT_free(point); - goto merr; - } - if (!(point->distpoint = DIST_POINT_NAME_new())) - goto merr; - point->distpoint->name.fullname = gens; - point->distpoint->type = 0; - gens = NULL; - } - } - return crld; - - merr: - X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE); - err: - GENERAL_NAME_free(gen); - GENERAL_NAMES_free(gens); - sk_DIST_POINT_pop_free(crld, DIST_POINT_free); - return NULL; -} - -IMPLEMENT_STACK_OF(DIST_POINT) - -IMPLEMENT_ASN1_SET_OF(DIST_POINT) - -static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; - - switch (operation) { - case ASN1_OP_NEW_POST: - dpn->dpname = NULL; - break; - - case ASN1_OP_FREE_POST: - if (dpn->dpname) - X509_NAME_free(dpn->dpname); - break; - } - return 1; -} - - -ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { - ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), - ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) -} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) - - -IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) - -ASN1_SEQUENCE(DIST_POINT) = { - ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), - ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), - ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2) -} ASN1_SEQUENCE_END(DIST_POINT) - -IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT) - -ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT) -ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) - -IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) - -ASN1_SEQUENCE(ISSUING_DIST_POINT) = { - ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), - ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), - ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), - ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), - ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), - ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5) -} ASN1_SEQUENCE_END(ISSUING_DIST_POINT) - -IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) - -static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, - int indent); -static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); - -const X509V3_EXT_METHOD v3_idp = { - NID_issuing_distribution_point, X509V3_EXT_MULTILINE, - ASN1_ITEM_ref(ISSUING_DIST_POINT), - 0, 0, 0, 0, - 0, 0, - 0, - v2i_idp, - i2r_idp, 0, - NULL -}; - -static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - ISSUING_DIST_POINT *idp = NULL; - CONF_VALUE *cnf; - char *name, *val; - int i, ret; - idp = ISSUING_DIST_POINT_new(); - if (!idp) - goto merr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - name = cnf->name; - val = cnf->value; - ret = set_dist_point_name(&idp->distpoint, ctx, cnf); - if (ret > 0) - continue; - if (ret < 0) - goto err; - if (!strcmp(name, "onlyuser")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) - goto err; - } else if (!strcmp(name, "onlyCA")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) - goto err; - } else if (!strcmp(name, "onlyAA")) { - if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) - goto err; - } else if (!strcmp(name, "indirectCRL")) { - if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) - goto err; - } else if (!strcmp(name, "onlysomereasons")) { - if (!set_reasons(&idp->onlysomereasons, val)) - goto err; - } else { - X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME); - X509V3_conf_err(cnf); - goto err; - } - } - return idp; - - merr: - X509V3err(X509V3_F_V2I_IDP, ERR_R_MALLOC_FAILURE); - err: - ISSUING_DIST_POINT_free(idp); - return NULL; -} - -static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) -{ - int i; - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - BIO_printf(out, "%*s", indent + 2, ""); - GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); - BIO_puts(out, "\n"); - } - return 1; -} - -static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) -{ - if (dpn->type == 0) { - BIO_printf(out, "%*sFull Name:\n", indent, ""); - print_gens(out, dpn->name.fullname, indent); - } else { - X509_NAME ntmp; - ntmp.entries = dpn->name.relativename; - BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); - X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); - BIO_puts(out, "\n"); - } - return 1; -} - -static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, - int indent) -{ - ISSUING_DIST_POINT *idp = pidp; - if (idp->distpoint) - print_distpoint(out, idp->distpoint, indent); - if (idp->onlyuser > 0) - BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); - if (idp->onlyCA > 0) - BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); - if (idp->indirectCRL > 0) - BIO_printf(out, "%*sIndirect CRL\n", indent, ""); - if (idp->onlysomereasons) - print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent); - if (idp->onlyattr > 0) - BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); - if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) - && (idp->indirectCRL <= 0) && !idp->onlysomereasons - && (idp->onlyattr <= 0)) - BIO_printf(out, "%*s\n", indent, ""); - - return 1; -} - -static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, - int indent) -{ - STACK_OF(DIST_POINT) *crld = pcrldp; - DIST_POINT *point; - int i; - for (i = 0; i < sk_DIST_POINT_num(crld); i++) { - BIO_puts(out, "\n"); - point = sk_DIST_POINT_value(crld, i); - if (point->distpoint) - print_distpoint(out, point->distpoint, indent); - if (point->reasons) - print_reasons(out, "Reasons", point->reasons, indent); - if (point->CRLissuer) { - BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); - print_gens(out, point->CRLissuer, indent); - } - } - return 1; -} - -int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) -{ - int i; - STACK_OF(X509_NAME_ENTRY) *frag; - X509_NAME_ENTRY *ne; - if (!dpn || (dpn->type != 1)) - return 1; - frag = dpn->name.relativename; - dpn->dpname = X509_NAME_dup(iname); - if (!dpn->dpname) - return 0; - for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { - ne = sk_X509_NAME_ENTRY_value(frag, i); - if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } - } - /* generate cached encoding of name */ - if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { - X509_NAME_free(dpn->dpname); - dpn->dpname = NULL; - return 0; - } - return 1; -} -/* v3_enum.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "x509v3.h" - -static ENUMERATED_NAMES crl_reasons[] = { - {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, - {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, - {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, - {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", - "affiliationChanged"}, - {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, - {CRL_REASON_CESSATION_OF_OPERATION, - "Cessation Of Operation", "cessationOfOperation"}, - {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, - {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, - {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", - "privilegeWithdrawn"}, - {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, - {-1, NULL, NULL} -}; - -const X509V3_EXT_METHOD v3_crl_reason = { - NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, - 0, - 0, 0, 0, 0, - crl_reasons -}; - -char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e) -{ - ENUMERATED_NAMES *enam; - long strval; - strval = ASN1_ENUMERATED_get(e); - for (enam = method->usr_data; enam->lname; enam++) { - if (strval == enam->bitnum) - return BUF_strdup(enam->lname); - } - return i2s_ASN1_ENUMERATED(method, e); -} -/* v3_extku.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "conf.h" -// #include "x509v3.h" - -static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD - *method, void *eku, STACK_OF(CONF_VALUE) - *extlist); - -const X509V3_EXT_METHOD v3_ext_ku = { - NID_ext_key_usage, 0, - ASN1_ITEM_ref(EXTENDED_KEY_USAGE), - 0, 0, 0, 0, - 0, 0, - i2v_EXTENDED_KEY_USAGE, - v2i_EXTENDED_KEY_USAGE, - 0, 0, - NULL -}; - -/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ -const X509V3_EXT_METHOD v3_ocsp_accresp = { - NID_id_pkix_OCSP_acceptableResponses, 0, - ASN1_ITEM_ref(EXTENDED_KEY_USAGE), - 0, 0, 0, 0, - 0, 0, - i2v_EXTENDED_KEY_USAGE, - v2i_EXTENDED_KEY_USAGE, - 0, 0, - NULL -}; - -ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT) -ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE) - -IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) - -static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD - *method, void *a, STACK_OF(CONF_VALUE) - *ext_list) -{ - EXTENDED_KEY_USAGE *eku = a; - int i; - ASN1_OBJECT *obj; - char obj_tmp[80]; - for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { - obj = sk_ASN1_OBJECT_value(eku, i); - i2t_ASN1_OBJECT(obj_tmp, 80, obj); - X509V3_add_value(NULL, obj_tmp, &ext_list); - } - return ext_list; -} - -static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - EXTENDED_KEY_USAGE *extku; - char *extval; - ASN1_OBJECT *objtmp; - CONF_VALUE *val; - int i; - - if (!(extku = sk_ASN1_OBJECT_new_null())) { - X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (val->value) - extval = val->value; - else - extval = val->name; - if (!(objtmp = OBJ_txt2obj(extval, 0))) { - sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); - X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return NULL; - } - sk_ASN1_OBJECT_push(extku, objtmp); - } - return extku; -} -/* v3_genn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "conf.h" -// #include "x509v3.h" - -ASN1_SEQUENCE(OTHERNAME) = { - ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), - /* Maybe have a true ANY DEFINED BY later */ - ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0) -} ASN1_SEQUENCE_END(OTHERNAME) - -IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME) - -ASN1_SEQUENCE(EDIPARTYNAME) = { - ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), - ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) -} ASN1_SEQUENCE_END(EDIPARTYNAME) - -IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME) - -ASN1_CHOICE(GENERAL_NAME) = { - ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), - ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL), - ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS), - /* Don't decode this */ - ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400), - /* X509_NAME is a CHOICE type so use EXPLICIT */ - ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME), - ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY), - ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI), - ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD), - ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID) -} ASN1_CHOICE_END(GENERAL_NAME) - -IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME) - -ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME) -ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) - -IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) - -GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a) -{ - return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME, - (d2i_of_void *)d2i_GENERAL_NAME, - (char *)a); -} - -/* Returns 0 if they are equal, != 0 otherwise. */ -int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) -{ - int result = -1; - - if (!a || !b || a->type != b->type) - return -1; - switch (a->type) { - case GEN_X400: - case GEN_EDIPARTY: - result = ASN1_TYPE_cmp(a->d.other, b->d.other); - break; - - case GEN_OTHERNAME: - result = OTHERNAME_cmp(a->d.otherName, b->d.otherName); - break; - - case GEN_EMAIL: - case GEN_DNS: - case GEN_URI: - result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5); - break; - - case GEN_DIRNAME: - result = X509_NAME_cmp(a->d.dirn, b->d.dirn); - break; - - case GEN_IPADD: - result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); - break; - - case GEN_RID: - result = OBJ_cmp(a->d.rid, b->d.rid); - break; - } - return result; -} - -/* Returns 0 if they are equal, != 0 otherwise. */ -int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) -{ - int result = -1; - - if (!a || !b) - return -1; - /* Check their type first. */ - if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) - return result; - /* Check the value. */ - result = ASN1_TYPE_cmp(a->value, b->value); - return result; -} - -void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) -{ - switch (type) { - case GEN_X400: - case GEN_EDIPARTY: - a->d.other = value; - break; - - case GEN_OTHERNAME: - a->d.otherName = value; - break; - - case GEN_EMAIL: - case GEN_DNS: - case GEN_URI: - a->d.ia5 = value; - break; - - case GEN_DIRNAME: - a->d.dirn = value; - break; - - case GEN_IPADD: - a->d.ip = value; - break; - - case GEN_RID: - a->d.rid = value; - break; - } - a->type = type; -} - -void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) -{ - if (ptype) - *ptype = a->type; - switch (a->type) { - case GEN_X400: - case GEN_EDIPARTY: - return a->d.other; - - case GEN_OTHERNAME: - return a->d.otherName; - - case GEN_EMAIL: - case GEN_DNS: - case GEN_URI: - return a->d.ia5; - - case GEN_DIRNAME: - return a->d.dirn; - - case GEN_IPADD: - return a->d.ip; - - case GEN_RID: - return a->d.rid; - - default: - return NULL; - } -} - -int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, - ASN1_OBJECT *oid, ASN1_TYPE *value) -{ - OTHERNAME *oth; - oth = OTHERNAME_new(); - if (!oth) - return 0; - ASN1_TYPE_free(oth->value); - oth->type_id = oid; - oth->value = value; - GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); - return 1; -} - -int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, - ASN1_OBJECT **poid, ASN1_TYPE **pvalue) -{ - if (gen->type != GEN_OTHERNAME) - return 0; - if (poid) - *poid = gen->d.otherName->type_id; - if (pvalue) - *pvalue = gen->d.otherName->value; - return 1; -} -/* v3_ia5.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "conf.h" -// #include "x509v3.h" - -static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - ASN1_IA5STRING *ia5); -static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); -const X509V3_EXT_METHOD v3_ns_ia5_list[] = { - EXT_IA5STRING(NID_netscape_base_url), - EXT_IA5STRING(NID_netscape_revocation_url), - EXT_IA5STRING(NID_netscape_ca_revocation_url), - EXT_IA5STRING(NID_netscape_renewal_url), - EXT_IA5STRING(NID_netscape_ca_policy_url), - EXT_IA5STRING(NID_netscape_ssl_server_name), - EXT_IA5STRING(NID_netscape_comment), - EXT_END -}; - -static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - ASN1_IA5STRING *ia5) -{ - char *tmp; - if (!ia5 || !ia5->length) - return NULL; - if (!(tmp = OPENSSL_malloc(ia5->length + 1))) { - X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); - return NULL; - } - memcpy(tmp, ia5->data, ia5->length); - tmp[ia5->length] = 0; - return tmp; -} - -static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str) -{ - ASN1_IA5STRING *ia5; - if (!str) { - X509V3err(X509V3_F_S2I_ASN1_IA5STRING, - X509V3_R_INVALID_NULL_ARGUMENT); - return NULL; - } - if (!(ia5 = M_ASN1_IA5STRING_new())) - goto err; - if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char *)str, - strlen(str))) { - M_ASN1_IA5STRING_free(ia5); - goto err; - } -#ifdef CHARSET_EBCDIC - ebcdic2ascii(ia5->data, ia5->data, ia5->length); -#endif /* CHARSET_EBCDIC */ - return ia5; - err: - X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); - return NULL; -} -/* v3_info.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" - -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD - *method, AUTHORITY_INFO_ACCESS - *ainfo, STACK_OF(CONF_VALUE) - *ret); -static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD - *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) - *nval); - -const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE, - ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, - (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, - 0, 0, - NULL -}; - -const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE, - ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), - 0, 0, 0, 0, - 0, 0, - (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, - (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, - 0, 0, - NULL -}; - -ASN1_SEQUENCE(ACCESS_DESCRIPTION) = { - ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT), - ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME) -} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION) - -IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) - -ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION) -ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS) - -IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) - -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( - X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, - STACK_OF(CONF_VALUE) *ret) -{ - ACCESS_DESCRIPTION *desc; - int i, nlen; - char objtmp[80], *ntmp; - CONF_VALUE *vtmp; - STACK_OF(CONF_VALUE) *tret = ret; - - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { - STACK_OF(CONF_VALUE) *tmp; - - desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); - tmp = i2v_GENERAL_NAME(method, desc->location, tret); - if (tmp == NULL) - goto err; - tret = tmp; - vtmp = sk_CONF_VALUE_value(tret, i); - i2t_ASN1_OBJECT(objtmp, sizeof(objtmp), desc->method); - nlen = strlen(objtmp) + strlen(vtmp->name) + 5; - ntmp = OPENSSL_malloc(nlen); - if (ntmp == NULL) - goto err; - BUF_strlcpy(ntmp, objtmp, nlen); - BUF_strlcat(ntmp, " - ", nlen); - BUF_strlcat(ntmp, vtmp->name, nlen); - OPENSSL_free(vtmp->name); - vtmp->name = ntmp; - - } - if (ret == NULL && tret == NULL) - return sk_CONF_VALUE_new_null(); - - return tret; - err: - X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); - if (ret == NULL && tret != NULL) - sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); - return NULL; -} - -static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD - *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) - *nval) -{ - AUTHORITY_INFO_ACCESS *ainfo = NULL; - CONF_VALUE *cnf, ctmp; - ACCESS_DESCRIPTION *acc; - int i, objlen; - char *objtmp, *ptmp; - if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!(acc = ACCESS_DESCRIPTION_new()) - || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, - ERR_R_MALLOC_FAILURE); - goto err; - } - ptmp = strchr(cnf->name, ';'); - if (!ptmp) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, - X509V3_R_INVALID_SYNTAX); - goto err; - } - objlen = ptmp - cnf->name; - ctmp.name = ptmp + 1; - ctmp.value = cnf->value; - if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) - goto err; - if (!(objtmp = OPENSSL_malloc(objlen + 1))) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, - ERR_R_MALLOC_FAILURE); - goto err; - } - strncpy(objtmp, cnf->name, objlen); - objtmp[objlen] = 0; - acc->method = OBJ_txt2obj(objtmp, 0); - if (!acc->method) { - X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, - X509V3_R_BAD_OBJECT); - ERR_add_error_data(2, "value=", objtmp); - OPENSSL_free(objtmp); - goto err; - } - OPENSSL_free(objtmp); - - } - return ainfo; - err: - sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); - return NULL; -} - -int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a) -{ - i2a_ASN1_OBJECT(bp, a->method); -#ifdef UNDEF - i2a_GENERAL_NAME(bp, a->location); -#endif - return 2; -} -/* v3_int.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "x509v3.h" - -const X509V3_EXT_METHOD v3_crl_num = { - NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_INTEGER, - 0, - 0, 0, 0, 0, NULL -}; - -const X509V3_EXT_METHOD v3_delta_crl = { - NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_INTEGER, - 0, - 0, 0, 0, 0, NULL -}; - -static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, - char *value) -{ - return s2i_ASN1_INTEGER(meth, value); -} - -const X509V3_EXT_METHOD v3_inhibit_anyp = { - NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_INTEGER, - (X509V3_EXT_S2I)s2i_asn1_int, - 0, 0, 0, 0, NULL -}; -/* v3_ncons.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "conf.h" -// #include "x509v3.h" - -static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, - BIO *bp, int ind); -static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, - STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, - int ind, char *name); -static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); - -static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); -static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); -static int nc_dn(X509_NAME *sub, X509_NAME *nm); -static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); -static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); -static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); - -const X509V3_EXT_METHOD v3_name_constraints = { - NID_name_constraints, 0, - ASN1_ITEM_ref(NAME_CONSTRAINTS), - 0, 0, 0, 0, - 0, 0, - 0, v2i_NAME_CONSTRAINTS, - i2r_NAME_CONSTRAINTS, 0, - NULL -}; - -ASN1_SEQUENCE(GENERAL_SUBTREE) = { - ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), - ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), - ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1) -} ASN1_SEQUENCE_END(GENERAL_SUBTREE) - -ASN1_SEQUENCE(NAME_CONSTRAINTS) = { - ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, - GENERAL_SUBTREE, 0), - ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, - GENERAL_SUBTREE, 1), -} ASN1_SEQUENCE_END(NAME_CONSTRAINTS) - - -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) - -/* - * We cannot use strncasecmp here because that applies locale specific rules. - * For example in Turkish 'I' is not the uppercase character for 'i'. We need to - * do a simple ASCII case comparison ignoring the locale (that is why we use - * numeric constants below). - */ -static int ia5ncasecmp(const char *s1, const char *s2, size_t n) -{ - for (; n > 0; n--, s1++, s2++) { - if (*s1 != *s2) { - unsigned char c1 = (unsigned char)*s1, c2 = (unsigned char)*s2; - - /* Convert to lower case */ - if (c1 >= 0x41 /* A */ && c1 <= 0x5A /* Z */) - c1 += 0x20; - if (c2 >= 0x41 /* A */ && c2 <= 0x5A /* Z */) - c2 += 0x20; - - if (c1 == c2) - continue; - - if (c1 < c2) - return -1; - - /* c1 > c2 */ - return 1; - } else if (*s1 == 0) { - /* If we get here we know that *s2 == 0 too */ - return 0; - } - } - - return 0; -} - -static int ia5casecmp(const char *s1, const char *s2) -{ - /* No portable definition of SIZE_MAX, so we use (size_t)(-1) instead */ - return ia5ncasecmp(s1, s2, (size_t)(-1)); -} - -static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - int i; - CONF_VALUE tval, *val; - STACK_OF(GENERAL_SUBTREE) **ptree = NULL; - NAME_CONSTRAINTS *ncons = NULL; - GENERAL_SUBTREE *sub = NULL; - ncons = NAME_CONSTRAINTS_new(); - if (!ncons) - goto memerr; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!strncmp(val->name, "permitted", 9) && val->name[9]) { - ptree = &ncons->permittedSubtrees; - tval.name = val->name + 10; - } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { - ptree = &ncons->excludedSubtrees; - tval.name = val->name + 9; - } else { - X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX); - goto err; - } - tval.value = val->value; - sub = GENERAL_SUBTREE_new(); - if (sub == NULL) - goto memerr; - if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) - goto err; - if (!*ptree) - *ptree = sk_GENERAL_SUBTREE_new_null(); - if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) - goto memerr; - sub = NULL; - } - - return ncons; - - memerr: - X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); - err: - if (ncons) - NAME_CONSTRAINTS_free(ncons); - if (sub) - GENERAL_SUBTREE_free(sub); - - return NULL; -} - -static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, - BIO *bp, int ind) -{ - NAME_CONSTRAINTS *ncons = a; - do_i2r_name_constraints(method, ncons->permittedSubtrees, - bp, ind, "Permitted"); - do_i2r_name_constraints(method, ncons->excludedSubtrees, - bp, ind, "Excluded"); - return 1; -} - -static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, - STACK_OF(GENERAL_SUBTREE) *trees, - BIO *bp, int ind, char *name) -{ - GENERAL_SUBTREE *tree; - int i; - if (sk_GENERAL_SUBTREE_num(trees) > 0) - BIO_printf(bp, "%*s%s:\n", ind, "", name); - for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { - tree = sk_GENERAL_SUBTREE_value(trees, i); - BIO_printf(bp, "%*s", ind + 2, ""); - if (tree->base->type == GEN_IPADD) - print_nc_ipadd(bp, tree->base->d.ip); - else - GENERAL_NAME_print(bp, tree->base); - BIO_puts(bp, "\n"); - } - return 1; -} - -static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) -{ - int i, len; - unsigned char *p; - p = ip->data; - len = ip->length; - BIO_puts(bp, "IP:"); - if (len == 8) { - BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", - p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); - } else if (len == 32) { - for (i = 0; i < 16; i++) { - BIO_printf(bp, "%X", p[0] << 8 | p[1]); - p += 2; - if (i == 7) - BIO_puts(bp, "/"); - else if (i != 15) - BIO_puts(bp, ":"); - } - } else - BIO_printf(bp, "IP Address:"); - return 1; -} - -/*- - * Check a certificate conforms to a specified set of constraints. - * Return values: - * X509_V_OK: All constraints obeyed. - * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. - * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. - * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. - * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. - * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. - * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name - */ - -int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) -{ - int r, i; - X509_NAME *nm; - - nm = X509_get_subject_name(x); - - if (X509_NAME_entry_count(nm) > 0) { - GENERAL_NAME gntmp; - gntmp.type = GEN_DIRNAME; - gntmp.d.directoryName = nm; - - r = nc_match(&gntmp, nc); - - if (r != X509_V_OK) - return r; - - gntmp.type = GEN_EMAIL; - - /* Process any email address attributes in subject name */ - - for (i = -1;;) { - X509_NAME_ENTRY *ne; - i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i); - if (i == -1) - break; - ne = X509_NAME_get_entry(nm, i); - gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); - if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - - r = nc_match(&gntmp, nc); - - if (r != X509_V_OK) - return r; - } - - } - - for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); - r = nc_match(gen, nc); - if (r != X509_V_OK) - return r; - } - - return X509_V_OK; - -} - -static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) -{ - GENERAL_SUBTREE *sub; - int i, r, match = 0; - - /* - * Permitted subtrees: if any subtrees exist of matching the type at - * least one subtree must match. - */ - - for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { - sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); - if (gen->type != sub->base->type) - continue; - if (sub->minimum || sub->maximum) - return X509_V_ERR_SUBTREE_MINMAX; - /* If we already have a match don't bother trying any more */ - if (match == 2) - continue; - if (match == 0) - match = 1; - r = nc_match_single(gen, sub->base); - if (r == X509_V_OK) - match = 2; - else if (r != X509_V_ERR_PERMITTED_VIOLATION) - return r; - } - - if (match == 1) - return X509_V_ERR_PERMITTED_VIOLATION; - - /* Excluded subtrees: must not match any of these */ - - for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { - sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); - if (gen->type != sub->base->type) - continue; - if (sub->minimum || sub->maximum) - return X509_V_ERR_SUBTREE_MINMAX; - - r = nc_match_single(gen, sub->base); - if (r == X509_V_OK) - return X509_V_ERR_EXCLUDED_VIOLATION; - else if (r != X509_V_ERR_PERMITTED_VIOLATION) - return r; - - } - - return X509_V_OK; - -} - -static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) -{ - switch (base->type) { - case GEN_DIRNAME: - return nc_dn(gen->d.directoryName, base->d.directoryName); - - case GEN_DNS: - return nc_dns(gen->d.dNSName, base->d.dNSName); - - case GEN_EMAIL: - return nc_email(gen->d.rfc822Name, base->d.rfc822Name); - - case GEN_URI: - return nc_uri(gen->d.uniformResourceIdentifier, - base->d.uniformResourceIdentifier); - - default: - return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; - } - -} - -/* - * directoryName name constraint matching. The canonical encoding of - * X509_NAME makes this comparison easy. It is matched if the subtree is a - * subset of the name. - */ - -static int nc_dn(X509_NAME *nm, X509_NAME *base) -{ - /* Ensure canonical encodings are up to date. */ - if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) - return X509_V_ERR_OUT_OF_MEM; - if (base->modified && i2d_X509_NAME(base, NULL) < 0) - return X509_V_ERR_OUT_OF_MEM; - if (base->canon_enclen > nm->canon_enclen) - return X509_V_ERR_PERMITTED_VIOLATION; - if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) - return X509_V_ERR_PERMITTED_VIOLATION; - return X509_V_OK; -} - -static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) -{ - char *baseptr = (char *)base->data; - char *dnsptr = (char *)dns->data; - /* Empty matches everything */ - if (!*baseptr) - return X509_V_OK; - /* - * Otherwise can add zero or more components on the left so compare RHS - * and if dns is longer and expect '.' as preceding character. - */ - if (dns->length > base->length) { - dnsptr += dns->length - base->length; - if (*baseptr != '.' && dnsptr[-1] != '.') - return X509_V_ERR_PERMITTED_VIOLATION; - } - - if (ia5casecmp(baseptr, dnsptr)) - return X509_V_ERR_PERMITTED_VIOLATION; - - return X509_V_OK; - -} - -static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) -{ - const char *baseptr = (char *)base->data; - const char *emlptr = (char *)eml->data; - - const char *baseat = strchr(baseptr, '@'); - const char *emlat = strchr(emlptr, '@'); - if (!emlat) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - /* Special case: inital '.' is RHS match */ - if (!baseat && (*baseptr == '.')) { - if (eml->length > base->length) { - emlptr += eml->length - base->length; - if (ia5casecmp(baseptr, emlptr) == 0) - return X509_V_OK; - } - return X509_V_ERR_PERMITTED_VIOLATION; - } - - /* If we have anything before '@' match local part */ - - if (baseat) { - if (baseat != baseptr) { - if ((baseat - baseptr) != (emlat - emlptr)) - return X509_V_ERR_PERMITTED_VIOLATION; - /* Case sensitive match of local part */ - if (strncmp(baseptr, emlptr, emlat - emlptr)) - return X509_V_ERR_PERMITTED_VIOLATION; - } - /* Position base after '@' */ - baseptr = baseat + 1; - } - emlptr = emlat + 1; - /* Just have hostname left to match: case insensitive */ - if (ia5casecmp(baseptr, emlptr)) - return X509_V_ERR_PERMITTED_VIOLATION; - - return X509_V_OK; - -} - -static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) -{ - const char *baseptr = (char *)base->data; - const char *hostptr = (char *)uri->data; - const char *p = strchr(hostptr, ':'); - int hostlen; - /* Check for foo:// and skip past it */ - if (!p || (p[1] != '/') || (p[2] != '/')) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - hostptr = p + 3; - - /* Determine length of hostname part of URI */ - - /* Look for a port indicator as end of hostname first */ - - p = strchr(hostptr, ':'); - /* Otherwise look for trailing slash */ - if (!p) - p = strchr(hostptr, '/'); - - if (!p) - hostlen = strlen(hostptr); - else - hostlen = p - hostptr; - - if (hostlen == 0) - return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; - - /* Special case: inital '.' is RHS match */ - if (*baseptr == '.') { - if (hostlen > base->length) { - p = hostptr + hostlen - base->length; - if (ia5ncasecmp(p, baseptr, base->length) == 0) - return X509_V_OK; - } - return X509_V_ERR_PERMITTED_VIOLATION; - } - - if ((base->length != (int)hostlen) - || ia5ncasecmp(hostptr, baseptr, hostlen)) - return X509_V_ERR_PERMITTED_VIOLATION; - - return X509_V_OK; - -} -/* v3_ocsp.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#ifndef OPENSSL_NO_OCSP - -# include -# include "cryptlib.h" -# include "conf.h" -# include "asn1.h" -# include "ocsp.h" -# include "x509v3.h" - -/* - * OCSP extensions and a couple of CRL entry extensions - */ - -static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce, - BIO *out, int indent); -static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, - BIO *out, int indent); -static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out, - int indent); - -static void *ocsp_nonce_new(void); -static int i2d_ocsp_nonce(void *a, unsigned char **pp); -static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); -static void ocsp_nonce_free(void *a); -static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, - BIO *out, int indent); - -static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, - void *nocheck, BIO *out, int indent); -static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str); -static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, - BIO *bp, int ind); - -const X509V3_EXT_METHOD v3_ocsp_crlid = { - NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID), - 0, 0, 0, 0, - 0, 0, - 0, 0, - i2r_ocsp_crlid, 0, - NULL -}; - -const X509V3_EXT_METHOD v3_ocsp_acutoff = { - NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), - 0, 0, 0, 0, - 0, 0, - 0, 0, - i2r_ocsp_acutoff, 0, - NULL -}; - -const X509V3_EXT_METHOD v3_crl_invdate = { - NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), - 0, 0, 0, 0, - 0, 0, - 0, 0, - i2r_ocsp_acutoff, 0, - NULL -}; - -const X509V3_EXT_METHOD v3_crl_hold = { - NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT), - 0, 0, 0, 0, - 0, 0, - 0, 0, - i2r_object, 0, - NULL -}; - -const X509V3_EXT_METHOD v3_ocsp_nonce = { - NID_id_pkix_OCSP_Nonce, 0, NULL, - ocsp_nonce_new, - ocsp_nonce_free, - d2i_ocsp_nonce, - i2d_ocsp_nonce, - 0, 0, - 0, 0, - i2r_ocsp_nonce, 0, - NULL -}; - -const X509V3_EXT_METHOD v3_ocsp_nocheck = { - NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL), - 0, 0, 0, 0, - 0, s2i_ocsp_nocheck, - 0, 0, - i2r_ocsp_nocheck, 0, - NULL -}; - -const X509V3_EXT_METHOD v3_ocsp_serviceloc = { - NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC), - 0, 0, 0, 0, - 0, 0, - 0, 0, - i2r_ocsp_serviceloc, 0, - NULL -}; - -static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp, - int ind) -{ - OCSP_CRLID *a = in; - if (a->crlUrl) { - if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) - goto err; - if (!ASN1_STRING_print(bp, (ASN1_STRING *)a->crlUrl)) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (a->crlNum) { - if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) - goto err; - if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - if (a->crlTime) { - if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) - goto err; - if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) - goto err; - if (BIO_write(bp, "\n", 1) <= 0) - goto err; - } - return 1; - err: - return 0; -} - -static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, - BIO *bp, int ind) -{ - if (BIO_printf(bp, "%*s", ind, "") <= 0) - return 0; - if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) - return 0; - return 1; -} - -static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp, - int ind) -{ - if (BIO_printf(bp, "%*s", ind, "") <= 0) - return 0; - if (i2a_ASN1_OBJECT(bp, oid) <= 0) - return 0; - return 1; -} - -/* - * OCSP nonce. This is needs special treatment because it doesn't have an - * ASN1 encoding at all: it just contains arbitrary data. - */ - -static void *ocsp_nonce_new(void) -{ - return ASN1_OCTET_STRING_new(); -} - -static int i2d_ocsp_nonce(void *a, unsigned char **pp) -{ - ASN1_OCTET_STRING *os = a; - if (pp) { - memcpy(*pp, os->data, os->length); - *pp += os->length; - } - return os->length; -} - -static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) -{ - ASN1_OCTET_STRING *os, **pos; - pos = a; - if (!pos || !*pos) - os = ASN1_OCTET_STRING_new(); - else - os = *pos; - if (!ASN1_OCTET_STRING_set(os, *pp, length)) - goto err; - - *pp += length; - - if (pos) - *pos = os; - return os; - - err: - if (os && (!pos || (*pos != os))) - M_ASN1_OCTET_STRING_free(os); - OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE); - return NULL; -} - -static void ocsp_nonce_free(void *a) -{ - M_ASN1_OCTET_STRING_free(a); -} - -static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, - BIO *out, int indent) -{ - if (BIO_printf(out, "%*s", indent, "") <= 0) - return 0; - if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) - return 0; - return 1; -} - -/* Nocheck is just a single NULL. Don't print anything and always set it */ - -static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, - BIO *out, int indent) -{ - return 1; -} - -static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, const char *str) -{ - return ASN1_NULL_new(); -} - -static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, - BIO *bp, int ind) -{ - int i; - OCSP_SERVICELOC *a = in; - ACCESS_DESCRIPTION *ad; - - if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) - goto err; - if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) - goto err; - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) { - ad = sk_ACCESS_DESCRIPTION_value(a->locator, i); - if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0) - goto err; - if (i2a_ASN1_OBJECT(bp, ad->method) <= 0) - goto err; - if (BIO_puts(bp, " - ") <= 0) - goto err; - if (GENERAL_NAME_print(bp, ad->location) <= 0) - goto err; - } - return 1; - err: - return 0; -} -#endif -/* v3_pci.c */ -/* - * Contributed to the OpenSSL Project 2004 by Richard Levitte - * (richard@levitte.org) - */ -/* Copyright (c) 2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "x509v3.h" - -static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, - BIO *out, int indent); -static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); - -const X509V3_EXT_METHOD v3_pci = - { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), - 0, 0, 0, 0, - 0, 0, - NULL, NULL, - (X509V3_EXT_I2R)i2r_pci, - (X509V3_EXT_R2I)r2i_pci, - NULL, -}; - -static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, - BIO *out, int indent) -{ - BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); - if (pci->pcPathLengthConstraint) - i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); - else - BIO_printf(out, "infinite"); - BIO_puts(out, "\n"); - BIO_printf(out, "%*sPolicy Language: ", indent, ""); - i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); - BIO_puts(out, "\n"); - if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) - BIO_printf(out, "%*sPolicy Text: %s\n", indent, "", - pci->proxyPolicy->policy->data); - return 1; -} - -static int process_pci_value(CONF_VALUE *val, - ASN1_OBJECT **language, ASN1_INTEGER **pathlen, - ASN1_OCTET_STRING **policy) -{ - int free_policy = 0; - - if (strcmp(val->name, "language") == 0) { - if (*language) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); - X509V3_conf_err(val); - return 0; - } - if (!(*language = OBJ_txt2obj(val->value, 0))) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return 0; - } - } else if (strcmp(val->name, "pathlen") == 0) { - if (*pathlen) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); - X509V3_conf_err(val); - return 0; - } - if (!X509V3_get_value_int(val, pathlen)) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_POLICY_PATH_LENGTH); - X509V3_conf_err(val); - return 0; - } - } else if (strcmp(val->name, "policy") == 0) { - unsigned char *tmp_data = NULL; - long val_len; - if (!*policy) { - *policy = ASN1_OCTET_STRING_new(); - if (!*policy) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); - X509V3_conf_err(val); - return 0; - } - free_policy = 1; - } - if (strncmp(val->value, "hex:", 4) == 0) { - unsigned char *tmp_data2 = - string_to_hex(val->value + 4, &val_len); - - if (!tmp_data2) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_ILLEGAL_HEX_DIGIT); - X509V3_conf_err(val); - goto err; - } - - tmp_data = OPENSSL_realloc((*policy)->data, - (*policy)->length + val_len + 1); - if (tmp_data) { - (*policy)->data = tmp_data; - memcpy(&(*policy)->data[(*policy)->length], - tmp_data2, val_len); - (*policy)->length += val_len; - (*policy)->data[(*policy)->length] = '\0'; - } else { - OPENSSL_free(tmp_data2); - /* - * realloc failure implies the original data space is b0rked - * too! - */ - (*policy)->data = NULL; - (*policy)->length = 0; - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); - X509V3_conf_err(val); - goto err; - } - OPENSSL_free(tmp_data2); - } else if (strncmp(val->value, "file:", 5) == 0) { - unsigned char buf[2048]; - int n; - BIO *b = BIO_new_file(val->value + 5, "r"); - if (!b) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); - X509V3_conf_err(val); - goto err; - } - while ((n = BIO_read(b, buf, sizeof(buf))) > 0 - || (n == 0 && BIO_should_retry(b))) { - if (!n) - continue; - - tmp_data = OPENSSL_realloc((*policy)->data, - (*policy)->length + n + 1); - - if (!tmp_data) - break; - - (*policy)->data = tmp_data; - memcpy(&(*policy)->data[(*policy)->length], buf, n); - (*policy)->length += n; - (*policy)->data[(*policy)->length] = '\0'; - } - BIO_free_all(b); - - if (n < 0) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); - X509V3_conf_err(val); - goto err; - } - } else if (strncmp(val->value, "text:", 5) == 0) { - val_len = strlen(val->value + 5); - tmp_data = OPENSSL_realloc((*policy)->data, - (*policy)->length + val_len + 1); - if (tmp_data) { - (*policy)->data = tmp_data; - memcpy(&(*policy)->data[(*policy)->length], - val->value + 5, val_len); - (*policy)->length += val_len; - (*policy)->data[(*policy)->length] = '\0'; - } else { - /* - * realloc failure implies the original data space is b0rked - * too! - */ - (*policy)->data = NULL; - (*policy)->length = 0; - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); - X509V3_conf_err(val); - goto err; - } - } else { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); - X509V3_conf_err(val); - goto err; - } - if (!tmp_data) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); - X509V3_conf_err(val); - goto err; - } - } - return 1; - err: - if (free_policy) { - ASN1_OCTET_STRING_free(*policy); - *policy = NULL; - } - return 0; -} - -static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *value) -{ - PROXY_CERT_INFO_EXTENSION *pci = NULL; - STACK_OF(CONF_VALUE) *vals; - ASN1_OBJECT *language = NULL; - ASN1_INTEGER *pathlen = NULL; - ASN1_OCTET_STRING *policy = NULL; - int i, j; - - vals = X509V3_parse_list(value); - for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { - CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); - if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { - X509V3err(X509V3_F_R2I_PCI, - X509V3_R_INVALID_PROXY_POLICY_SETTING); - X509V3_conf_err(cnf); - goto err; - } - if (*cnf->name == '@') { - STACK_OF(CONF_VALUE) *sect; - int success_p = 1; - - sect = X509V3_get_section(ctx, cnf->name + 1); - if (!sect) { - X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION); - X509V3_conf_err(cnf); - goto err; - } - for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) { - success_p = - process_pci_value(sk_CONF_VALUE_value(sect, j), - &language, &pathlen, &policy); - } - X509V3_section_free(ctx, sect); - if (!success_p) - goto err; - } else { - if (!process_pci_value(cnf, &language, &pathlen, &policy)) { - X509V3_conf_err(cnf); - goto err; - } - } - } - - /* Language is mandatory */ - if (!language) { - X509V3err(X509V3_F_R2I_PCI, - X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); - goto err; - } - i = OBJ_obj2nid(language); - if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) { - X509V3err(X509V3_F_R2I_PCI, - X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); - goto err; - } - - pci = PROXY_CERT_INFO_EXTENSION_new(); - if (!pci) { - X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE); - goto err; - } - - pci->proxyPolicy->policyLanguage = language; - language = NULL; - pci->proxyPolicy->policy = policy; - policy = NULL; - pci->pcPathLengthConstraint = pathlen; - pathlen = NULL; - goto end; - err: - if (language) { - ASN1_OBJECT_free(language); - language = NULL; - } - if (pathlen) { - ASN1_INTEGER_free(pathlen); - pathlen = NULL; - } - if (policy) { - ASN1_OCTET_STRING_free(policy); - policy = NULL; - } - if (pci) { - PROXY_CERT_INFO_EXTENSION_free(pci); - pci = NULL; - } - end: - sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); - return pci; -} -/* v3_pcia.c */ -/* - * Contributed to the OpenSSL Project 2004 by Richard Levitte - * (richard@levitte.org) - */ -/* Copyright (c) 2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" - -ASN1_SEQUENCE(PROXY_POLICY) = - { - ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT), - ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(PROXY_POLICY) - -IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY) - -ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) = - { - ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER), - ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY) -} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION) - -IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) -/* v3_pcons.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "conf.h" -// #include "x509v3.h" - -static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD - *method, void *bcons, STACK_OF(CONF_VALUE) - *extlist); -static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values); - -const X509V3_EXT_METHOD v3_policy_constraints = { - NID_policy_constraints, 0, - ASN1_ITEM_ref(POLICY_CONSTRAINTS), - 0, 0, 0, 0, - 0, 0, - i2v_POLICY_CONSTRAINTS, - v2i_POLICY_CONSTRAINTS, - NULL, NULL, - NULL -}; - -ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { - ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0), - ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1) -} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS) - -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) - -static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD - *method, void *a, STACK_OF(CONF_VALUE) - *extlist) -{ - POLICY_CONSTRAINTS *pcons = a; - X509V3_add_value_int("Require Explicit Policy", - pcons->requireExplicitPolicy, &extlist); - X509V3_add_value_int("Inhibit Policy Mapping", - pcons->inhibitPolicyMapping, &extlist); - return extlist; -} - -static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *values) -{ - POLICY_CONSTRAINTS *pcons = NULL; - CONF_VALUE *val; - int i; - if (!(pcons = POLICY_CONSTRAINTS_new())) { - X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE); - return NULL; - } - for (i = 0; i < sk_CONF_VALUE_num(values); i++) { - val = sk_CONF_VALUE_value(values, i); - if (!strcmp(val->name, "requireExplicitPolicy")) { - if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) - goto err; - } else if (!strcmp(val->name, "inhibitPolicyMapping")) { - if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) - goto err; - } else { - X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME); - X509V3_conf_err(val); - goto err; - } - } - if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { - X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, - X509V3_R_ILLEGAL_EMPTY_EXTENSION); - goto err; - } - - return pcons; - err: - POLICY_CONSTRAINTS_free(pcons); - return NULL; -} -/* v3_pku.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" - -static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, - PKEY_USAGE_PERIOD *usage, BIO *out, - int indent); -/* - * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, - * X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); - */ -const X509V3_EXT_METHOD v3_pkey_usage_period = { - NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD), - 0, 0, 0, 0, - 0, 0, 0, 0, - (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL, - NULL -}; - -ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = { - ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0), - ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1) -} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD) - -IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) - -static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, - PKEY_USAGE_PERIOD *usage, BIO *out, - int indent) -{ - BIO_printf(out, "%*s", indent, ""); - if (usage->notBefore) { - BIO_write(out, "Not Before: ", 12); - ASN1_GENERALIZEDTIME_print(out, usage->notBefore); - if (usage->notAfter) - BIO_write(out, ", ", 2); - } - if (usage->notAfter) { - BIO_write(out, "Not After: ", 11); - ASN1_GENERALIZEDTIME_print(out, usage->notAfter); - } - return 1; -} - -/*- -static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values) -X509V3_EXT_METHOD *method; -X509V3_CTX *ctx; -STACK_OF(CONF_VALUE) *values; -{ -return NULL; -} -*/ -/* v3_pmaps.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "conf.h" -// #include "x509v3.h" - -static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); -static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD - *method, void *pmps, STACK_OF(CONF_VALUE) - *extlist); - -const X509V3_EXT_METHOD v3_policy_mappings = { - NID_policy_mappings, 0, - ASN1_ITEM_ref(POLICY_MAPPINGS), - 0, 0, 0, 0, - 0, 0, - i2v_POLICY_MAPPINGS, - v2i_POLICY_MAPPINGS, - 0, 0, - NULL -}; - -ASN1_SEQUENCE(POLICY_MAPPING) = { - ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT), - ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT) -} ASN1_SEQUENCE_END(POLICY_MAPPING) - -ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS, - POLICY_MAPPING) -ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) - -IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) - -static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD - *method, void *a, STACK_OF(CONF_VALUE) - *ext_list) -{ - POLICY_MAPPINGS *pmaps = a; - POLICY_MAPPING *pmap; - int i; - char obj_tmp1[80]; - char obj_tmp2[80]; - for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { - pmap = sk_POLICY_MAPPING_value(pmaps, i); - i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); - i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); - X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); - } - return ext_list; -} - -static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) -{ - POLICY_MAPPINGS *pmaps; - POLICY_MAPPING *pmap; - ASN1_OBJECT *obj1, *obj2; - CONF_VALUE *val; - int i; - - if (!(pmaps = sk_POLICY_MAPPING_new_null())) { - X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); - return NULL; - } - - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - val = sk_CONF_VALUE_value(nval, i); - if (!val->value || !val->name) { - sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); - X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return NULL; - } - obj1 = OBJ_txt2obj(val->name, 0); - obj2 = OBJ_txt2obj(val->value, 0); - if (!obj1 || !obj2) { - sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); - X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, - X509V3_R_INVALID_OBJECT_IDENTIFIER); - X509V3_conf_err(val); - return NULL; - } - pmap = POLICY_MAPPING_new(); - if (!pmap) { - sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); - X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); - return NULL; - } - pmap->issuerDomainPolicy = obj1; - pmap->subjectDomainPolicy = obj2; - sk_POLICY_MAPPING_push(pmaps, pmap); - } - return pmaps; -} -/* v3_prn.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* X509 v3 extension utilities */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "x509v3.h" - -/* Extension printing routines */ - -static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, - unsigned long flag, int indent, int supported); - -/* Print out a name+value stack */ - -void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, - int ml) -{ - int i; - CONF_VALUE *nval; - if (!val) - return; - if (!ml || !sk_CONF_VALUE_num(val)) { - BIO_printf(out, "%*s", indent, ""); - if (!sk_CONF_VALUE_num(val)) - BIO_puts(out, "\n"); - } - for (i = 0; i < sk_CONF_VALUE_num(val); i++) { - if (ml) - BIO_printf(out, "%*s", indent, ""); - else if (i > 0) - BIO_printf(out, ", "); - nval = sk_CONF_VALUE_value(val, i); - if (!nval->name) - BIO_puts(out, nval->value); - else if (!nval->value) - BIO_puts(out, nval->name); -#ifndef CHARSET_EBCDIC - else - BIO_printf(out, "%s:%s", nval->name, nval->value); -#else - else { - int len; - char *tmp; - len = strlen(nval->value) + 1; - tmp = OPENSSL_malloc(len); - if (tmp) { - ascii2ebcdic(tmp, nval->value, len); - BIO_printf(out, "%s:%s", nval->name, tmp); - OPENSSL_free(tmp); - } - } -#endif - if (ml) - BIO_puts(out, "\n"); - } -} - -/* Main routine: print out a general extension */ - -int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, - int indent) -{ - void *ext_str = NULL; - char *value = NULL; - const unsigned char *p; - const X509V3_EXT_METHOD *method; - STACK_OF(CONF_VALUE) *nval = NULL; - int ok = 1; - - if (!(method = X509V3_EXT_get(ext))) - return unknown_ext_print(out, ext, flag, indent, 0); - p = ext->value->data; - if (method->it) - ext_str = - ASN1_item_d2i(NULL, &p, ext->value->length, - ASN1_ITEM_ptr(method->it)); - else - ext_str = method->d2i(NULL, &p, ext->value->length); - - if (!ext_str) - return unknown_ext_print(out, ext, flag, indent, 1); - - if (method->i2s) { - if (!(value = method->i2s(method, ext_str))) { - ok = 0; - goto err; - } -#ifndef CHARSET_EBCDIC - BIO_printf(out, "%*s%s", indent, "", value); -#else - { - int len; - char *tmp; - len = strlen(value) + 1; - tmp = OPENSSL_malloc(len); - if (tmp) { - ascii2ebcdic(tmp, value, len); - BIO_printf(out, "%*s%s", indent, "", tmp); - OPENSSL_free(tmp); - } - } -#endif - } else if (method->i2v) { - if (!(nval = method->i2v(method, ext_str, NULL))) { - ok = 0; - goto err; - } - X509V3_EXT_val_prn(out, nval, indent, - method->ext_flags & X509V3_EXT_MULTILINE); - } else if (method->i2r) { - if (!method->i2r(method, ext_str, out, indent)) - ok = 0; - } else - ok = 0; - - err: - sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); - if (value) - OPENSSL_free(value); - if (method->it) - ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it)); - else - method->ext_free(ext_str); - return ok; -} - -int X509V3_extensions_print(BIO *bp, char *title, - STACK_OF(X509_EXTENSION) *exts, - unsigned long flag, int indent) -{ - int i, j; - - if (sk_X509_EXTENSION_num(exts) <= 0) - return 1; - - if (title) { - BIO_printf(bp, "%*s%s:\n", indent, "", title); - indent += 4; - } - - for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { - ASN1_OBJECT *obj; - X509_EXTENSION *ex; - ex = sk_X509_EXTENSION_value(exts, i); - if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) - return 0; - obj = X509_EXTENSION_get_object(ex); - i2a_ASN1_OBJECT(bp, obj); - j = X509_EXTENSION_get_critical(ex); - if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) - return 0; - if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { - BIO_printf(bp, "%*s", indent + 4, ""); - M_ASN1_OCTET_STRING_print(bp, ex->value); - } - if (BIO_write(bp, "\n", 1) <= 0) - return 0; - } - return 1; -} - -static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, - unsigned long flag, int indent, int supported) -{ - switch (flag & X509V3_EXT_UNKNOWN_MASK) { - - case X509V3_EXT_DEFAULT: - return 0; - - case X509V3_EXT_ERROR_UNKNOWN: - if (supported) - BIO_printf(out, "%*s", indent, ""); - else - BIO_printf(out, "%*s", indent, ""); - return 1; - - case X509V3_EXT_PARSE_UNKNOWN: - return ASN1_parse_dump(out, - ext->value->data, ext->value->length, indent, - -1); - case X509V3_EXT_DUMP_UNKNOWN: - return BIO_dump_indent(out, (char *)ext->value->data, - ext->value->length, indent); - - default: - return 1; - } -} - -#ifndef OPENSSL_NO_FP_API -int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) -{ - BIO *bio_tmp; - int ret; - if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) - return 0; - ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); - BIO_free(bio_tmp); - return ret; -} -#endif -/* v3_purp.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 1999-2018 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "x509v3.h" -#include "x509_vfy.h" - -static void x509v3_cache_extensions(X509 *x); - -static int check_ssl_ca(const X509 *x); -static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int purpose_smime(const X509 *x, int ca); -static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, - int ca); -static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); -static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); - -static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b); -static void xptable_free(X509_PURPOSE *p); - -static X509_PURPOSE xstandard[] = { - {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, - check_purpose_ssl_client, "SSL client", "sslclient", NULL}, - {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, - check_purpose_ssl_server, "SSL server", "sslserver", NULL}, - {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, - check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL}, - {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, - "S/MIME signing", "smimesign", NULL}, - {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, - check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, - {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, - "CRL signing", "crlsign", NULL}, - {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", - NULL}, - {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, - "OCSP helper", "ocsphelper", NULL}, - {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, - check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", - NULL}, -}; - -#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) - -IMPLEMENT_STACK_OF(X509_PURPOSE) - -static STACK_OF(X509_PURPOSE) *xptable = NULL; - -static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) -{ - return (*a)->purpose - (*b)->purpose; -} - -/* - * As much as I'd like to make X509_check_purpose use a "const" X509* I - * really can't because it does recalculate hashes and do other non-const - * things. - */ -int X509_check_purpose(X509 *x, int id, int ca) -{ - int idx; - const X509_PURPOSE *pt; - - x509v3_cache_extensions(x); - - /* Return if side-effect only call */ - if (id == -1) - return 1; - idx = X509_PURPOSE_get_by_id(id); - if (idx == -1) - return -1; - pt = X509_PURPOSE_get0(idx); - return pt->check_purpose(pt, x, ca); -} - -int X509_PURPOSE_set(int *p, int purpose) -{ - if (X509_PURPOSE_get_by_id(purpose) == -1) { - X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE); - return 0; - } - *p = purpose; - return 1; -} - -int X509_PURPOSE_get_count(void) -{ - if (!xptable) - return X509_PURPOSE_COUNT; - return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; -} - -X509_PURPOSE *X509_PURPOSE_get0(int idx) -{ - if (idx < 0) - return NULL; - if (idx < (int)X509_PURPOSE_COUNT) - return xstandard + idx; - return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); -} - -int X509_PURPOSE_get_by_sname(char *sname) -{ - int i; - X509_PURPOSE *xptmp; - for (i = 0; i < X509_PURPOSE_get_count(); i++) { - xptmp = X509_PURPOSE_get0(i); - if (!strcmp(xptmp->sname, sname)) - return i; - } - return -1; -} - -int X509_PURPOSE_get_by_id(int purpose) -{ - X509_PURPOSE tmp; - int idx; - if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) - return purpose - X509_PURPOSE_MIN; - tmp.purpose = purpose; - if (!xptable) - return -1; - idx = sk_X509_PURPOSE_find(xptable, &tmp); - if (idx == -1) - return -1; - return idx + X509_PURPOSE_COUNT; -} - -int X509_PURPOSE_add(int id, int trust, int flags, - int (*ck) (const X509_PURPOSE *, const X509 *, int), - char *name, char *sname, void *arg) -{ - int idx; - X509_PURPOSE *ptmp; - /* - * This is set according to what we change: application can't set it - */ - flags &= ~X509_PURPOSE_DYNAMIC; - /* This will always be set for application modified trust entries */ - flags |= X509_PURPOSE_DYNAMIC_NAME; - /* Get existing entry if any */ - idx = X509_PURPOSE_get_by_id(id); - /* Need a new entry */ - if (idx == -1) { - if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) { - X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - ptmp->flags = X509_PURPOSE_DYNAMIC; - } else - ptmp = X509_PURPOSE_get0(idx); - - /* OPENSSL_free existing name if dynamic */ - if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { - OPENSSL_free(ptmp->name); - OPENSSL_free(ptmp->sname); - } - /* dup supplied name */ - ptmp->name = BUF_strdup(name); - ptmp->sname = BUF_strdup(sname); - if (!ptmp->name || !ptmp->sname) { - X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - /* Keep the dynamic flag of existing entry */ - ptmp->flags &= X509_PURPOSE_DYNAMIC; - /* Set all other flags */ - ptmp->flags |= flags; - - ptmp->purpose = id; - ptmp->trust = trust; - ptmp->check_purpose = ck; - ptmp->usr_data = arg; - - /* If its a new entry manage the dynamic table */ - if (idx == -1) { - if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) { - X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!sk_X509_PURPOSE_push(xptable, ptmp)) { - X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - } - return 1; -} - -static void xptable_free(X509_PURPOSE *p) -{ - if (!p) - return; - if (p->flags & X509_PURPOSE_DYNAMIC) { - if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { - OPENSSL_free(p->name); - OPENSSL_free(p->sname); - } - OPENSSL_free(p); - } -} - -void X509_PURPOSE_cleanup(void) -{ - unsigned int i; - sk_X509_PURPOSE_pop_free(xptable, xptable_free); - for (i = 0; i < X509_PURPOSE_COUNT; i++) - xptable_free(xstandard + i); - xptable = NULL; -} - -int X509_PURPOSE_get_id(X509_PURPOSE *xp) -{ - return xp->purpose; -} - -char *X509_PURPOSE_get0_name(X509_PURPOSE *xp) -{ - return xp->name; -} - -char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp) -{ - return xp->sname; -} - -int X509_PURPOSE_get_trust(X509_PURPOSE *xp) -{ - return xp->trust; -} - -static int nid_cmp(const int *a, const int *b) -{ - return *a - *b; -} - -DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid); -IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid); - -int X509_supported_extension(X509_EXTENSION *ex) -{ - /* - * This table is a list of the NIDs of supported extensions: that is - * those which are used by the verify process. If an extension is - * critical and doesn't appear in this list then the verify process will - * normally reject the certificate. The list must be kept in numerical - * order because it will be searched using bsearch. - */ - - static const int supported_nids[] = { - NID_netscape_cert_type, /* 71 */ - NID_key_usage, /* 83 */ - NID_subject_alt_name, /* 85 */ - NID_basic_constraints, /* 87 */ - NID_certificate_policies, /* 89 */ - NID_crl_distribution_points, /* 103 */ - NID_ext_key_usage, /* 126 */ -#ifndef OPENSSL_NO_RFC3779 - NID_sbgp_ipAddrBlock, /* 290 */ - NID_sbgp_autonomousSysNum, /* 291 */ -#endif - NID_policy_constraints, /* 401 */ - NID_proxyCertInfo, /* 663 */ - NID_name_constraints, /* 666 */ - NID_policy_mappings, /* 747 */ - NID_inhibit_any_policy /* 748 */ - }; - - int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); - - if (ex_nid == NID_undef) - return 0; - - if (OBJ_bsearch_nid(&ex_nid, supported_nids, - sizeof(supported_nids) / sizeof(int))) - return 1; - return 0; -} - -static void setup_dp(X509 *x, DIST_POINT *dp) -{ - X509_NAME *iname = NULL; - int i; - if (dp->reasons) { - if (dp->reasons->length > 0) - dp->dp_reasons = dp->reasons->data[0]; - if (dp->reasons->length > 1) - dp->dp_reasons |= (dp->reasons->data[1] << 8); - dp->dp_reasons &= CRLDP_ALL_REASONS; - } else - dp->dp_reasons = CRLDP_ALL_REASONS; - if (!dp->distpoint || (dp->distpoint->type != 1)) - return; - for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); - if (gen->type == GEN_DIRNAME) { - iname = gen->d.directoryName; - break; - } - } - if (!iname) - iname = X509_get_issuer_name(x); - - DIST_POINT_set_dpname(dp->distpoint, iname); - -} - -static void setup_crldp(X509 *x) -{ - int i; - x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); - for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) - setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); -} - -#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) -#define ku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) -#define xku_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) -#define ns_reject(x, usage) \ - (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) - -static void x509v3_cache_extensions(X509 *x) -{ - BASIC_CONSTRAINTS *bs; - PROXY_CERT_INFO_EXTENSION *pci; - ASN1_BIT_STRING *usage; - ASN1_BIT_STRING *ns; - EXTENDED_KEY_USAGE *extusage; - X509_EXTENSION *ex; - int i; - - CRYPTO_w_lock(CRYPTO_LOCK_X509); - if (x->ex_flags & EXFLAG_SET) { - CRYPTO_w_unlock(CRYPTO_LOCK_X509); - return; - } - -#ifndef OPENSSL_NO_SHA - X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); -#endif - /* V1 should mean no extensions ... */ - if (!X509_get_version(x)) - x->ex_flags |= EXFLAG_V1; - /* Handle basic constraints */ - if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { - if (bs->ca) - x->ex_flags |= EXFLAG_CA; - if (bs->pathlen) { - if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) - || !bs->ca) { - x->ex_flags |= EXFLAG_INVALID; - x->ex_pathlen = 0; - } else - x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); - } else - x->ex_pathlen = -1; - BASIC_CONSTRAINTS_free(bs); - x->ex_flags |= EXFLAG_BCONS; - } - /* Handle proxy certificates */ - if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { - if (x->ex_flags & EXFLAG_CA - || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 - || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { - x->ex_flags |= EXFLAG_INVALID; - } - if (pci->pcPathLengthConstraint) { - x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); - } else - x->ex_pcpathlen = -1; - PROXY_CERT_INFO_EXTENSION_free(pci); - x->ex_flags |= EXFLAG_PROXY; - } - /* Handle key usage */ - if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { - if (usage->length > 0) { - x->ex_kusage = usage->data[0]; - if (usage->length > 1) - x->ex_kusage |= usage->data[1] << 8; - } else - x->ex_kusage = 0; - x->ex_flags |= EXFLAG_KUSAGE; - ASN1_BIT_STRING_free(usage); - } - x->ex_xkusage = 0; - if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { - x->ex_flags |= EXFLAG_XKUSAGE; - for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { - switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { - case NID_server_auth: - x->ex_xkusage |= XKU_SSL_SERVER; - break; - - case NID_client_auth: - x->ex_xkusage |= XKU_SSL_CLIENT; - break; - - case NID_email_protect: - x->ex_xkusage |= XKU_SMIME; - break; - - case NID_code_sign: - x->ex_xkusage |= XKU_CODE_SIGN; - break; - - case NID_ms_sgc: - case NID_ns_sgc: - x->ex_xkusage |= XKU_SGC; - break; - - case NID_OCSP_sign: - x->ex_xkusage |= XKU_OCSP_SIGN; - break; - - case NID_time_stamp: - x->ex_xkusage |= XKU_TIMESTAMP; - break; - - case NID_dvcs: - x->ex_xkusage |= XKU_DVCS; - break; - - case NID_anyExtendedKeyUsage: - x->ex_xkusage |= XKU_ANYEKU; - break; - } - } - sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); - } - - if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { - if (ns->length > 0) - x->ex_nscert = ns->data[0]; - else - x->ex_nscert = 0; - x->ex_flags |= EXFLAG_NSCERT; - ASN1_BIT_STRING_free(ns); - } - x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); - x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); - /* Does subject name match issuer ? */ - if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) { - x->ex_flags |= EXFLAG_SI; - /* If SKID matches AKID also indicate self signed */ - if (X509_check_akid(x, x->akid) == X509_V_OK && - !ku_reject(x, KU_KEY_CERT_SIGN)) - x->ex_flags |= EXFLAG_SS; - } - x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); - if (!x->nc && (i != -1)) - x->ex_flags |= EXFLAG_INVALID; - setup_crldp(x); - -#ifndef OPENSSL_NO_RFC3779 - x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); - x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, - NULL, NULL); -#endif - for (i = 0; i < X509_get_ext_count(x); i++) { - ex = X509_get_ext(x, i); - if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) - == NID_freshest_crl) - x->ex_flags |= EXFLAG_FRESHEST; - if (!X509_EXTENSION_get_critical(ex)) - continue; - if (!X509_supported_extension(ex)) { - x->ex_flags |= EXFLAG_CRITICAL; - break; - } - } - x->ex_flags |= EXFLAG_SET; - CRYPTO_w_unlock(CRYPTO_LOCK_X509); -} - -/*- - * CA checks common to all purposes - * return codes: - * 0 not a CA - * 1 is a CA - * 2 basicConstraints absent so "maybe" a CA - * 3 basicConstraints absent but self signed V1. - * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. - */ - -static int check_ca(const X509 *x) -{ - /* keyUsage if present should allow cert signing */ - if (ku_reject(x, KU_KEY_CERT_SIGN)) - return 0; - if (x->ex_flags & EXFLAG_BCONS) { - if (x->ex_flags & EXFLAG_CA) - return 1; - /* If basicConstraints says not a CA then say so */ - else - return 0; - } else { - /* we support V1 roots for... uh, I don't really know why. */ - if ((x->ex_flags & V1_ROOT) == V1_ROOT) - return 3; - /* - * If key usage present it must have certSign so tolerate it - */ - else if (x->ex_flags & EXFLAG_KUSAGE) - return 4; - /* Older certificates could have Netscape-specific CA types */ - else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA) - return 5; - /* can this still be regarded a CA certificate? I doubt it */ - return 0; - } -} - -int X509_check_ca(X509 *x) -{ - x509v3_cache_extensions(x); - - return check_ca(x); -} - -/* Check SSL CA: common checks for SSL client and server */ -static int check_ssl_ca(const X509 *x) -{ - int ca_ret; - ca_ret = check_ca(x); - if (!ca_ret) - return 0; - /* check nsCertType if present */ - if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) - return ca_ret; - else - return 0; -} - -static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - if (xku_reject(x, XKU_SSL_CLIENT)) - return 0; - if (ca) - return check_ssl_ca(x); - /* We need to do digital signatures or key agreement */ - if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)) - return 0; - /* nsCertType if present should allow SSL client use */ - if (ns_reject(x, NS_SSL_CLIENT)) - return 0; - return 1; -} - -/* - * Key usage needed for TLS/SSL server: digital signature, encipherment or - * key agreement. The ssl code can check this more thoroughly for individual - * key types. - */ -#define KU_TLS \ - KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT - -static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC)) - return 0; - if (ca) - return check_ssl_ca(x); - - if (ns_reject(x, NS_SSL_SERVER)) - return 0; - if (ku_reject(x, KU_TLS)) - return 0; - - return 1; - -} - -static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - int ret; - ret = check_purpose_ssl_server(xp, x, ca); - if (!ret || ca) - return ret; - /* We need to encipher or Netscape complains */ - if (ku_reject(x, KU_KEY_ENCIPHERMENT)) - return 0; - return ret; -} - -/* common S/MIME checks */ -static int purpose_smime(const X509 *x, int ca) -{ - if (xku_reject(x, XKU_SMIME)) - return 0; - if (ca) { - int ca_ret; - ca_ret = check_ca(x); - if (!ca_ret) - return 0; - /* check nsCertType if present */ - if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) - return ca_ret; - else - return 0; - } - if (x->ex_flags & EXFLAG_NSCERT) { - if (x->ex_nscert & NS_SMIME) - return 1; - /* Workaround for some buggy certificates */ - if (x->ex_nscert & NS_SSL_CLIENT) - return 2; - return 0; - } - return 1; -} - -static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - int ret; - ret = purpose_smime(x, ca); - if (!ret || ca) - return ret; - if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) - return 0; - return ret; -} - -static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - int ret; - ret = purpose_smime(x, ca); - if (!ret || ca) - return ret; - if (ku_reject(x, KU_KEY_ENCIPHERMENT)) - return 0; - return ret; -} - -static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - if (ca) { - int ca_ret; - if ((ca_ret = check_ca(x)) != 2) - return ca_ret; - else - return 0; - } - if (ku_reject(x, KU_CRL_SIGN)) - return 0; - return 1; -} - -/* - * OCSP helper: this is *not* a full OCSP check. It just checks that each CA - * is valid. Additional checks must be made on the chain. - */ - -static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - /* - * Must be a valid CA. Should we really support the "I don't know" value - * (2)? - */ - if (ca) - return check_ca(x); - /* leaf certificate is checked in OCSP_verify() */ - return 1; -} - -static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, - int ca) -{ - int i_ext; - - /* If ca is true we must return if this is a valid CA certificate. */ - if (ca) - return check_ca(x); - - /* - * Check the optional key usage field: - * if Key Usage is present, it must be one of digitalSignature - * and/or nonRepudiation (other values are not consistent and shall - * be rejected). - */ - if ((x->ex_flags & EXFLAG_KUSAGE) - && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || - !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) - return 0; - - /* Only time stamp key usage is permitted and it's required. */ - if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) - return 0; - - /* Extended Key Usage MUST be critical */ - i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1); - if (i_ext >= 0) { - X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); - if (!X509_EXTENSION_get_critical(ext)) - return 0; - } - - return 1; -} - -static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) -{ - return 1; -} - -/*- - * Various checks to see if one certificate issued the second. - * This can be used to prune a set of possible issuer certificates - * which have been looked up using some simple method such as by - * subject name. - * These are: - * 1. Check issuer_name(subject) == subject_name(issuer) - * 2. If akid(subject) exists check it matches issuer - * 3. If key_usage(issuer) exists check it supports certificate signing - * returns 0 for OK, positive for reason for mismatch, reasons match - * codes for X509_verify_cert() - */ - -int X509_check_issued(X509 *issuer, X509 *subject) -{ - if (X509_NAME_cmp(X509_get_subject_name(issuer), - X509_get_issuer_name(subject))) - return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; - - x509v3_cache_extensions(issuer); - x509v3_cache_extensions(subject); - - if (subject->akid) { - int ret = X509_check_akid(issuer, subject->akid); - if (ret != X509_V_OK) - return ret; - } - - if (subject->ex_flags & EXFLAG_PROXY) { - if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) - return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; - } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) - return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; - return X509_V_OK; -} - -int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) -{ - - if (!akid) - return X509_V_OK; - - /* Check key ids (if present) */ - if (akid->keyid && issuer->skid && - ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) - return X509_V_ERR_AKID_SKID_MISMATCH; - /* Check serial number */ - if (akid->serial && - ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) - return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; - /* Check issuer name */ - if (akid->issuer) { - /* - * Ugh, for some peculiar reason AKID includes SEQUENCE OF - * GeneralName. So look for a DirName. There may be more than one but - * we only take any notice of the first. - */ - GENERAL_NAMES *gens; - GENERAL_NAME *gen; - X509_NAME *nm = NULL; - int i; - gens = akid->issuer; - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type == GEN_DIRNAME) { - nm = gen->d.dirn; - break; - } - } - if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) - return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; - } - return X509_V_OK; -} -/* v3_scts.c */ -/* - * Written by Rob Stradling (rob@comodo.com) for the OpenSSL project 2014. - */ -/* ==================================================================== - * Copyright (c) 2014 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "x509v3.h" - -/* Signature and hash algorithms from RFC 5246 */ -#define TLSEXT_hash_sha256 4 - -#define TLSEXT_signature_rsa 1 -#define TLSEXT_signature_ecdsa 3 - - -#define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \ - (((unsigned int)(c[1])) )),c+=2) - -#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) -# define SCT_TIMESTAMP unsigned __int64 -#elif defined(__arch64__) -# define SCT_TIMESTAMP unsigned long -#else -# define SCT_TIMESTAMP unsigned long long -#endif - -#define n2l8(c,l) (l =((SCT_TIMESTAMP)(*((c)++)))<<56, \ - l|=((SCT_TIMESTAMP)(*((c)++)))<<48, \ - l|=((SCT_TIMESTAMP)(*((c)++)))<<40, \ - l|=((SCT_TIMESTAMP)(*((c)++)))<<32, \ - l|=((SCT_TIMESTAMP)(*((c)++)))<<24, \ - l|=((SCT_TIMESTAMP)(*((c)++)))<<16, \ - l|=((SCT_TIMESTAMP)(*((c)++)))<< 8, \ - l|=((SCT_TIMESTAMP)(*((c)++)))) - -typedef struct SCT_st { - /* The encoded SCT */ - unsigned char *sct; - unsigned short sctlen; - /* - * Components of the SCT. "logid", "ext" and "sig" point to addresses - * inside "sct". - */ - unsigned char version; - unsigned char *logid; - unsigned short logidlen; - SCT_TIMESTAMP timestamp; - unsigned char *ext; - unsigned short extlen; - unsigned char hash_alg; - unsigned char sig_alg; - unsigned char *sig; - unsigned short siglen; -} SCT; - -DECLARE_STACK_OF(SCT) - -static void SCT_LIST_free(STACK_OF(SCT) *a); -static STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, - const unsigned char **pp, long length); -static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list, - BIO *out, int indent); - -const X509V3_EXT_METHOD v3_ct_scts[] = { - {NID_ct_precert_scts, 0, NULL, - 0, (X509V3_EXT_FREE)SCT_LIST_free, - (X509V3_EXT_D2I)d2i_SCT_LIST, 0, - 0, 0, 0, 0, - (X509V3_EXT_I2R)i2r_SCT_LIST, 0, - NULL}, - - {NID_ct_cert_scts, 0, NULL, - 0, (X509V3_EXT_FREE)SCT_LIST_free, - (X509V3_EXT_D2I)d2i_SCT_LIST, 0, - 0, 0, 0, 0, - (X509V3_EXT_I2R)i2r_SCT_LIST, 0, - NULL}, -}; - -static void tls12_signature_print(BIO *out, const unsigned char hash_alg, - const unsigned char sig_alg) -{ - int nid = NID_undef; - /* RFC6962 only permits two signature algorithms */ - if (hash_alg == TLSEXT_hash_sha256) { - if (sig_alg == TLSEXT_signature_rsa) - nid = NID_sha256WithRSAEncryption; - else if (sig_alg == TLSEXT_signature_ecdsa) - nid = NID_ecdsa_with_SHA256; - } - if (nid == NID_undef) - BIO_printf(out, "%02X%02X", hash_alg, sig_alg); - else - BIO_printf(out, "%s", OBJ_nid2ln(nid)); -} - -static void timestamp_print(BIO *out, SCT_TIMESTAMP timestamp) -{ - ASN1_GENERALIZEDTIME *gen; - char genstr[20]; - gen = ASN1_GENERALIZEDTIME_new(); - ASN1_GENERALIZEDTIME_adj(gen, (time_t)0, - (int)(timestamp / 86400000), - (int)(timestamp % 86400000) / 1000); - /* - * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15 - * characters long with a final Z. Update it with fractional seconds. - */ - BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ", - ASN1_STRING_data(gen), (unsigned int)(timestamp % 1000)); - ASN1_GENERALIZEDTIME_set_string(gen, genstr); - ASN1_GENERALIZEDTIME_print(out, gen); - ASN1_GENERALIZEDTIME_free(gen); -} - -static void SCT_free(SCT *sct) -{ - if (sct) { - if (sct->sct) - OPENSSL_free(sct->sct); - OPENSSL_free(sct); - } -} - -static void SCT_LIST_free(STACK_OF(SCT) *a) -{ - sk_SCT_pop_free(a, SCT_free); -} - -static STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, - const unsigned char **pp, long length) -{ - ASN1_OCTET_STRING *oct = NULL; - STACK_OF(SCT) *sk = NULL; - SCT *sct; - unsigned char *p, *p2; - unsigned short listlen, sctlen = 0, fieldlen; - const unsigned char *q = *pp; - - if (d2i_ASN1_OCTET_STRING(&oct, &q, length) == NULL) - return NULL; - if (oct->length < 2) - goto done; - p = oct->data; - n2s(p, listlen); - if (listlen != oct->length - 2) - goto done; - - if ((sk = sk_SCT_new_null()) == NULL) - goto done; - - while (listlen > 0) { - if (listlen < 2) - goto err; - n2s(p, sctlen); - listlen -= 2; - - if ((sctlen < 1) || (sctlen > listlen)) - goto err; - listlen -= sctlen; - - sct = OPENSSL_malloc(sizeof(SCT)); - if (!sct) - goto err; - if (!sk_SCT_push(sk, sct)) { - OPENSSL_free(sct); - goto err; - } - - sct->sct = OPENSSL_malloc(sctlen); - if (!sct->sct) - goto err; - memcpy(sct->sct, p, sctlen); - sct->sctlen = sctlen; - p += sctlen; - p2 = sct->sct; - - sct->version = *p2++; - if (sct->version == 0) { /* SCT v1 */ - /*- - * Fixed-length header: - * struct { - * (1 byte) Version sct_version; - * (32 bytes) LogID id; - * (8 bytes) uint64 timestamp; - * (2 bytes + ?) CtExtensions extensions; - */ - if (sctlen < 43) - goto err; - sctlen -= 43; - - sct->logid = p2; - sct->logidlen = 32; - p2 += 32; - - n2l8(p2, sct->timestamp); - - n2s(p2, fieldlen); - if (sctlen < fieldlen) - goto err; - sct->ext = p2; - sct->extlen = fieldlen; - p2 += fieldlen; - sctlen -= fieldlen; - - /*- - * digitally-signed struct header: - * (1 byte) Hash algorithm - * (1 byte) Signature algorithm - * (2 bytes + ?) Signature - */ - if (sctlen < 4) - goto err; - sctlen -= 4; - - sct->hash_alg = *p2++; - sct->sig_alg = *p2++; - n2s(p2, fieldlen); - if (sctlen != fieldlen) - goto err; - sct->sig = p2; - sct->siglen = fieldlen; - } - } - - done: - ASN1_OCTET_STRING_free(oct); - *pp = q; - return sk; - - err: - SCT_LIST_free(sk); - sk = NULL; - goto done; -} - -static int i2r_SCT_LIST(X509V3_EXT_METHOD *method, STACK_OF(SCT) *sct_list, - BIO *out, int indent) -{ - SCT *sct; - int i; - - for (i = 0; i < sk_SCT_num(sct_list);) { - sct = sk_SCT_value(sct_list, i); - - BIO_printf(out, "%*sSigned Certificate Timestamp:", indent, ""); - BIO_printf(out, "\n%*sVersion : ", indent + 4, ""); - - if (sct->version == 0) { /* SCT v1 */ - BIO_printf(out, "v1(0)"); - - BIO_printf(out, "\n%*sLog ID : ", indent + 4, ""); - BIO_hex_string(out, indent + 16, 16, sct->logid, sct->logidlen); - - BIO_printf(out, "\n%*sTimestamp : ", indent + 4, ""); - timestamp_print(out, sct->timestamp); - - BIO_printf(out, "\n%*sExtensions: ", indent + 4, ""); - if (sct->extlen == 0) - BIO_printf(out, "none"); - else - BIO_hex_string(out, indent + 16, 16, sct->ext, sct->extlen); - - BIO_printf(out, "\n%*sSignature : ", indent + 4, ""); - tls12_signature_print(out, sct->hash_alg, sct->sig_alg); - BIO_printf(out, "\n%*s ", indent + 4, ""); - BIO_hex_string(out, indent + 16, 16, sct->sig, sct->siglen); - } else { /* Unknown version */ - - BIO_printf(out, "unknown\n%*s", indent + 16, ""); - BIO_hex_string(out, indent + 16, 16, sct->sct, sct->sctlen); - } - - if (++i < sk_SCT_num(sct_list)) - BIO_printf(out, "\n"); - } - - return 1; -} -/* v3_skey.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "x509v3.h" - -static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); -const X509V3_EXT_METHOD v3_skey_id = { - NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING), - 0, 0, 0, 0, - (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, - (X509V3_EXT_S2I)s2i_skey_id, - 0, 0, 0, 0, - NULL -}; - -char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct) -{ - return hex_to_string(oct->data, oct->length); -} - -ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str) -{ - ASN1_OCTET_STRING *oct; - long length; - - if (!(oct = M_ASN1_OCTET_STRING_new())) { - X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (!(oct->data = string_to_hex(str, &length))) { - M_ASN1_OCTET_STRING_free(oct); - return NULL; - } - - oct->length = length; - - return oct; - -} - -static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str) -{ - ASN1_OCTET_STRING *oct; - ASN1_BIT_STRING *pk; - unsigned char pkey_dig[EVP_MAX_MD_SIZE]; - unsigned int diglen; - - if (strcmp(str, "hash")) - return s2i_ASN1_OCTET_STRING(method, ctx, str); - - if (!(oct = M_ASN1_OCTET_STRING_new())) { - X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); - return NULL; - } - - if (ctx && (ctx->flags == CTX_TEST)) - return oct; - - if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { - X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); - goto err; - } - - if (ctx->subject_req) - pk = ctx->subject_req->req_info->pubkey->public_key; - else - pk = ctx->subject_cert->cert_info->key->public_key; - - if (!pk) { - X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); - goto err; - } - - if (!EVP_Digest - (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL)) - goto err; - - if (!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { - X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); - goto err; - } - - return oct; - - err: - M_ASN1_OCTET_STRING_free(oct); - return NULL; -} -/* v3_sxnet.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "asn1.h" -// #include "asn1t.h" -// #include "x509v3.h" - -/* Support for Thawte strong extranet extension */ - -#define SXNET_TEST - -static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, - int indent); -#ifdef SXNET_TEST -static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -#endif -const X509V3_EXT_METHOD v3_sxnet = { - NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET), - 0, 0, 0, 0, - 0, 0, - 0, -#ifdef SXNET_TEST - (X509V3_EXT_V2I)sxnet_v2i, -#else - 0, -#endif - (X509V3_EXT_I2R)sxnet_i2r, - 0, - NULL -}; - -ASN1_SEQUENCE(SXNETID) = { - ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER), - ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(SXNETID) - -IMPLEMENT_ASN1_FUNCTIONS(SXNETID) - -ASN1_SEQUENCE(SXNET) = { - ASN1_SIMPLE(SXNET, version, ASN1_INTEGER), - ASN1_SEQUENCE_OF(SXNET, ids, SXNETID) -} ASN1_SEQUENCE_END(SXNET) - -IMPLEMENT_ASN1_FUNCTIONS(SXNET) - -static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, - int indent) -{ - long v; - char *tmp; - SXNETID *id; - int i; - v = ASN1_INTEGER_get(sx->version); - BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v); - for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { - id = sk_SXNETID_value(sx->ids, i); - tmp = i2s_ASN1_INTEGER(NULL, id->zone); - BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); - OPENSSL_free(tmp); - M_ASN1_OCTET_STRING_print(out, id->user); - } - return 1; -} - -#ifdef SXNET_TEST - -/* - * NBB: this is used for testing only. It should *not* be used for anything - * else because it will just take static IDs from the configuration file and - * they should really be separate values for each user. - */ - -static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval) -{ - CONF_VALUE *cnf; - SXNET *sx = NULL; - int i; - for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { - cnf = sk_CONF_VALUE_value(nval, i); - if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) - return NULL; - } - return sx; -} - -#endif - -/* Strong Extranet utility functions */ - -/* Add an id given the zone as an ASCII number */ - -int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen) -{ - ASN1_INTEGER *izone = NULL; - if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) { - X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); - return 0; - } - return SXNET_add_id_INTEGER(psx, izone, user, userlen); -} - -/* Add an id given the zone as an unsigned long */ - -int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, - int userlen) -{ - ASN1_INTEGER *izone = NULL; - if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { - X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE); - M_ASN1_INTEGER_free(izone); - return 0; - } - return SXNET_add_id_INTEGER(psx, izone, user, userlen); - -} - -/* - * Add an id given the zone as an ASN1_INTEGER. Note this version uses the - * passed integer and doesn't make a copy so don't free it up afterwards. - */ - -int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user, - int userlen) -{ - SXNET *sx = NULL; - SXNETID *id = NULL; - if (!psx || !zone || !user) { - X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, - X509V3_R_INVALID_NULL_ARGUMENT); - return 0; - } - if (userlen == -1) - userlen = strlen(user); - if (userlen > 64) { - X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG); - return 0; - } - if (!*psx) { - if (!(sx = SXNET_new())) - goto err; - if (!ASN1_INTEGER_set(sx->version, 0)) - goto err; - *psx = sx; - } else - sx = *psx; - if (SXNET_get_id_INTEGER(sx, zone)) { - X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID); - return 0; - } - - if (!(id = SXNETID_new())) - goto err; - if (userlen == -1) - userlen = strlen(user); - - if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) - goto err; - if (!sk_SXNETID_push(sx->ids, id)) - goto err; - id->zone = zone; - return 1; - - err: - X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE); - SXNETID_free(id); - SXNET_free(sx); - *psx = NULL; - return 0; -} - -ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone) -{ - ASN1_INTEGER *izone = NULL; - ASN1_OCTET_STRING *oct; - if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) { - X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); - return NULL; - } - oct = SXNET_get_id_INTEGER(sx, izone); - M_ASN1_INTEGER_free(izone); - return oct; -} - -ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) -{ - ASN1_INTEGER *izone = NULL; - ASN1_OCTET_STRING *oct; - if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { - X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE); - M_ASN1_INTEGER_free(izone); - return NULL; - } - oct = SXNET_get_id_INTEGER(sx, izone); - M_ASN1_INTEGER_free(izone); - return oct; -} - -ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) -{ - SXNETID *id; - int i; - for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { - id = sk_SXNETID_value(sx->ids, i); - if (!M_ASN1_INTEGER_cmp(id->zone, zone)) - return id->user; - } - return NULL; -} - -IMPLEMENT_STACK_OF(SXNETID) - -IMPLEMENT_ASN1_SET_OF(SXNETID) -/* v3_utl.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* X509 v3 extension utilities */ - -#include -#include -// #include "cryptlib.h" -// #include "conf.h" -// #include "x509v3.h" -// #include "bn.h" - -static char *strip_spaces(char *name); -static int sk_strcmp(const char *const *a, const char *const *b); -static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, - GENERAL_NAMES *gens); -static void str_free(OPENSSL_STRING str); -static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); - -static int ipv4_from_asc(unsigned char *v4, const char *in); -static int ipv6_from_asc(unsigned char *v6, const char *in); -static int ipv6_cb(const char *elem, int len, void *usr); -static int ipv6_hex(unsigned char *out, const char *in, int inlen); - -/* Add a CONF_VALUE name value pair to stack */ - -int X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **extlist) -{ - CONF_VALUE *vtmp = NULL; - char *tname = NULL, *tvalue = NULL; - if (name && !(tname = BUF_strdup(name))) - goto err; - if (value && !(tvalue = BUF_strdup(value))) - goto err; - if (!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) - goto err; - if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) - goto err; - vtmp->section = NULL; - vtmp->name = tname; - vtmp->value = tvalue; - if (!sk_CONF_VALUE_push(*extlist, vtmp)) - goto err; - return 1; - err: - X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE); - if (vtmp) - OPENSSL_free(vtmp); - if (tname) - OPENSSL_free(tname); - if (tvalue) - OPENSSL_free(tvalue); - return 0; -} - -int X509V3_add_value_uchar(const char *name, const unsigned char *value, - STACK_OF(CONF_VALUE) **extlist) -{ - return X509V3_add_value(name, (const char *)value, extlist); -} - -/* Free function for STACK_OF(CONF_VALUE) */ - -void X509V3_conf_free(CONF_VALUE *conf) -{ - if (!conf) - return; - if (conf->name) - OPENSSL_free(conf->name); - if (conf->value) - OPENSSL_free(conf->value); - if (conf->section) - OPENSSL_free(conf->section); - OPENSSL_free(conf); -} - -int X509V3_add_value_bool(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist) -{ - if (asn1_bool) - return X509V3_add_value(name, "TRUE", extlist); - return X509V3_add_value(name, "FALSE", extlist); -} - -int X509V3_add_value_bool_nf(char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist) -{ - if (asn1_bool) - return X509V3_add_value(name, "TRUE", extlist); - return 1; -} - -char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a) -{ - BIGNUM *bntmp = NULL; - char *strtmp = NULL; - if (!a) - return NULL; - if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || - !(strtmp = BN_bn2dec(bntmp))) - X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); - BN_free(bntmp); - return strtmp; -} - -char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a) -{ - BIGNUM *bntmp = NULL; - char *strtmp = NULL; - if (!a) - return NULL; - if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || - !(strtmp = BN_bn2dec(bntmp))) - X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); - BN_free(bntmp); - return strtmp; -} - -ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value) -{ - BIGNUM *bn = NULL; - ASN1_INTEGER *aint; - int isneg, ishex; - int ret; - if (!value) { - X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE); - return 0; - } - bn = BN_new(); - if (value[0] == '-') { - value++; - isneg = 1; - } else - isneg = 0; - - if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { - value += 2; - ishex = 1; - } else - ishex = 0; - - if (ishex) - ret = BN_hex2bn(&bn, value); - else - ret = BN_dec2bn(&bn, value); - - if (!ret || value[ret]) { - BN_free(bn); - X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR); - return 0; - } - - if (isneg && BN_is_zero(bn)) - isneg = 0; - - aint = BN_to_ASN1_INTEGER(bn, NULL); - BN_free(bn); - if (!aint) { - X509V3err(X509V3_F_S2I_ASN1_INTEGER, - X509V3_R_BN_TO_ASN1_INTEGER_ERROR); - return 0; - } - if (isneg) - aint->type |= V_ASN1_NEG; - return aint; -} - -int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, - STACK_OF(CONF_VALUE) **extlist) -{ - char *strtmp; - int ret; - if (!aint) - return 1; - if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) - return 0; - ret = X509V3_add_value(name, strtmp, extlist); - OPENSSL_free(strtmp); - return ret; -} - -int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool) -{ - char *btmp; - if (!(btmp = value->value)) - goto err; - if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") - || !strcmp(btmp, "Y") || !strcmp(btmp, "y") - || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { - *asn1_bool = 0xff; - return 1; - } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") - || !strcmp(btmp, "N") || !strcmp(btmp, "n") - || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { - *asn1_bool = 0; - return 1; - } - err: - X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL, - X509V3_R_INVALID_BOOLEAN_STRING); - X509V3_conf_err(value); - return 0; -} - -int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint) -{ - ASN1_INTEGER *itmp; - if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { - X509V3_conf_err(value); - return 0; - } - *aint = itmp; - return 1; -} - -#define HDR_NAME 1 -#define HDR_VALUE 2 - -/* - * #define DEBUG - */ - -STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) -{ - char *p, *q, c; - char *ntmp, *vtmp; - STACK_OF(CONF_VALUE) *values = NULL; - char *linebuf; - int state; - /* We are going to modify the line so copy it first */ - linebuf = BUF_strdup(line); - if (linebuf == NULL) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE); - goto err; - } - state = HDR_NAME; - ntmp = NULL; - /* Go through all characters */ - for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); - p++) { - - switch (state) { - case HDR_NAME: - if (c == ':') { - state = HDR_VALUE; - *p = 0; - ntmp = strip_spaces(q); - if (!ntmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, - X509V3_R_INVALID_NULL_NAME); - goto err; - } - q = p + 1; - } else if (c == ',') { - *p = 0; - ntmp = strip_spaces(q); - q = p + 1; -#if 0 - printf("%s\n", ntmp); -#endif - if (!ntmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, - X509V3_R_INVALID_NULL_NAME); - goto err; - } - X509V3_add_value(ntmp, NULL, &values); - } - break; - - case HDR_VALUE: - if (c == ',') { - state = HDR_NAME; - *p = 0; - vtmp = strip_spaces(q); -#if 0 - printf("%s\n", ntmp); -#endif - if (!vtmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, - X509V3_R_INVALID_NULL_VALUE); - goto err; - } - X509V3_add_value(ntmp, vtmp, &values); - ntmp = NULL; - q = p + 1; - } - - } - } - - if (state == HDR_VALUE) { - vtmp = strip_spaces(q); -#if 0 - printf("%s=%s\n", ntmp, vtmp); -#endif - if (!vtmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, - X509V3_R_INVALID_NULL_VALUE); - goto err; - } - X509V3_add_value(ntmp, vtmp, &values); - } else { - ntmp = strip_spaces(q); -#if 0 - printf("%s\n", ntmp); -#endif - if (!ntmp) { - X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME); - goto err; - } - X509V3_add_value(ntmp, NULL, &values); - } - OPENSSL_free(linebuf); - return values; - - err: - OPENSSL_free(linebuf); - sk_CONF_VALUE_pop_free(values, X509V3_conf_free); - return NULL; - -} - -/* Delete leading and trailing spaces from a string */ -static char *strip_spaces(char *name) -{ - char *p, *q; - /* Skip over leading spaces */ - p = name; - while (*p && isspace((unsigned char)*p)) - p++; - if (!*p) - return NULL; - q = p + strlen(p) - 1; - while ((q != p) && isspace((unsigned char)*q)) - q--; - if (p != q) - q[1] = 0; - if (!*p) - return NULL; - return p; -} - -/* hex string utilities */ - -/* - * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its - * hex representation @@@ (Contents of buffer are always kept in ASCII, also - * on EBCDIC machines) - */ - -char *hex_to_string(const unsigned char *buffer, long len) -{ - char *tmp, *q; - const unsigned char *p; - int i; - const static char hexdig[] = "0123456789ABCDEF"; - if (!buffer || !len) - return NULL; - if (!(tmp = OPENSSL_malloc(len * 3 + 1))) { - X509V3err(X509V3_F_HEX_TO_STRING, ERR_R_MALLOC_FAILURE); - return NULL; - } - q = tmp; - for (i = 0, p = buffer; i < len; i++, p++) { - *q++ = hexdig[(*p >> 4) & 0xf]; - *q++ = hexdig[*p & 0xf]; - *q++ = ':'; - } - q[-1] = 0; -#ifdef CHARSET_EBCDIC - ebcdic2ascii(tmp, tmp, q - tmp - 1); -#endif - - return tmp; -} - -/* - * Give a string of hex digits convert to a buffer - */ - -unsigned char *string_to_hex(const char *str, long *len) -{ - unsigned char *hexbuf, *q; - unsigned char ch, cl, *p; - if (!str) { - X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_INVALID_NULL_ARGUMENT); - return NULL; - } - if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) - goto err; - for (p = (unsigned char *)str, q = hexbuf; *p;) { - ch = *p++; -#ifdef CHARSET_EBCDIC - ch = os_toebcdic[ch]; -#endif - if (ch == ':') - continue; - cl = *p++; -#ifdef CHARSET_EBCDIC - cl = os_toebcdic[cl]; -#endif - if (!cl) { - X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ODD_NUMBER_OF_DIGITS); - OPENSSL_free(hexbuf); - return NULL; - } - if (isupper(ch)) - ch = tolower(ch); - if (isupper(cl)) - cl = tolower(cl); - - if ((ch >= '0') && (ch <= '9')) - ch -= '0'; - else if ((ch >= 'a') && (ch <= 'f')) - ch -= 'a' - 10; - else - goto badhex; - - if ((cl >= '0') && (cl <= '9')) - cl -= '0'; - else if ((cl >= 'a') && (cl <= 'f')) - cl -= 'a' - 10; - else - goto badhex; - - *q++ = (ch << 4) | cl; - } - - if (len) - *len = q - hexbuf; - - return hexbuf; - - err: - if (hexbuf) - OPENSSL_free(hexbuf); - X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE); - return NULL; - - badhex: - OPENSSL_free(hexbuf); - X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT); - return NULL; - -} - -/* - * V2I name comparison function: returns zero if 'name' matches cmp or cmp.* - */ - -int name_cmp(const char *name, const char *cmp) -{ - int len, ret; - char c; - len = strlen(cmp); - if ((ret = strncmp(name, cmp, len))) - return ret; - c = name[len]; - if (!c || (c == '.')) - return 0; - return 1; -} - -static int sk_strcmp(const char *const *a, const char *const *b) -{ - return strcmp(*a, *b); -} - -STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) -{ - GENERAL_NAMES *gens; - STACK_OF(OPENSSL_STRING) *ret; - - gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - ret = get_email(X509_get_subject_name(x), gens); - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - return ret; -} - -STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) -{ - AUTHORITY_INFO_ACCESS *info; - STACK_OF(OPENSSL_STRING) *ret = NULL; - int i; - - info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); - if (!info) - return NULL; - for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { - ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); - if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { - if (ad->location->type == GEN_URI) { - if (!append_ia5 - (&ret, ad->location->d.uniformResourceIdentifier)) - break; - } - } - } - AUTHORITY_INFO_ACCESS_free(info); - return ret; -} - -STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) -{ - GENERAL_NAMES *gens; - STACK_OF(X509_EXTENSION) *exts; - STACK_OF(OPENSSL_STRING) *ret; - - exts = X509_REQ_get_extensions(x); - gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); - ret = get_email(X509_REQ_get_subject_name(x), gens); - sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); - sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); - return ret; -} - -static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, - GENERAL_NAMES *gens) -{ - STACK_OF(OPENSSL_STRING) *ret = NULL; - X509_NAME_ENTRY *ne; - ASN1_IA5STRING *email; - GENERAL_NAME *gen; - int i; - /* Now add any email address(es) to STACK */ - i = -1; - /* First supplied X509_NAME */ - while ((i = X509_NAME_get_index_by_NID(name, - NID_pkcs9_emailAddress, i)) >= 0) { - ne = X509_NAME_get_entry(name, i); - email = X509_NAME_ENTRY_get_data(ne); - if (!append_ia5(&ret, email)) - return NULL; - } - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type != GEN_EMAIL) - continue; - if (!append_ia5(&ret, gen->d.ia5)) - return NULL; - } - return ret; -} - -static void str_free(OPENSSL_STRING str) -{ - OPENSSL_free(str); -} - -static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) -{ - char *emtmp; - /* First some sanity checks */ - if (email->type != V_ASN1_IA5STRING) - return 1; - if (!email->data || !email->length) - return 1; - if (!*sk) - *sk = sk_OPENSSL_STRING_new(sk_strcmp); - if (!*sk) - return 0; - /* Don't add duplicates */ - if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) - return 1; - emtmp = BUF_strdup((char *)email->data); - if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) { - X509_email_free(*sk); - *sk = NULL; - return 0; - } - return 1; -} - -void X509_email_free(STACK_OF(OPENSSL_STRING) *sk) -{ - sk_OPENSSL_STRING_pop_free(sk, str_free); -} - -typedef int (*equal_fn) (const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, - unsigned int flags); - -/* Skip pattern prefix to match "wildcard" subject */ -static void skip_prefix(const unsigned char **p, size_t *plen, - const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - const unsigned char *pattern = *p; - size_t pattern_len = *plen; - - /* - * If subject starts with a leading '.' followed by more octets, and - * pattern is longer, compare just an equal-length suffix with the - * full subject (starting at the '.'), provided the prefix contains - * no NULs. - */ - if ((flags & _X509_CHECK_FLAG_DOT_SUBDOMAINS) == 0) - return; - - while (pattern_len > subject_len && *pattern) { - if ((flags & X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS) && - *pattern == '.') - break; - ++pattern; - --pattern_len; - } - - /* Skip if entire prefix acceptable */ - if (pattern_len == subject_len) { - *p = pattern; - *plen = pattern_len; - } -} - -/* Compare while ASCII ignoring case. */ -static int equal_nocase(const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); - if (pattern_len != subject_len) - return 0; - while (pattern_len) { - unsigned char l = *pattern; - unsigned char r = *subject; - /* The pattern must not contain NUL characters. */ - if (l == 0) - return 0; - if (l != r) { - if ('A' <= l && l <= 'Z') - l = (l - 'A') + 'a'; - if ('A' <= r && r <= 'Z') - r = (r - 'A') + 'a'; - if (l != r) - return 0; - } - ++pattern; - ++subject; - --pattern_len; - } - return 1; -} - -/* Compare using memcmp. */ -static int equal_case(const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - skip_prefix(&pattern, &pattern_len, subject, subject_len, flags); - if (pattern_len != subject_len) - return 0; - return !memcmp(pattern, subject, pattern_len); -} - -/* - * RFC 5280, section 7.5, requires that only the domain is compared in a - * case-insensitive manner. - */ -static int equal_email(const unsigned char *a, size_t a_len, - const unsigned char *b, size_t b_len, - unsigned int unused_flags) -{ - size_t i = a_len; - if (a_len != b_len) - return 0; - /* - * We search backwards for the '@' character, so that we do not have to - * deal with quoted local-parts. The domain part is compared in a - * case-insensitive manner. - */ - while (i > 0) { - --i; - if (a[i] == '@' || b[i] == '@') { - if (!equal_nocase(a + i, a_len - i, b + i, a_len - i, 0)) - return 0; - break; - } - } - if (i == 0) - i = a_len; - return equal_case(a, i, b, i, 0); -} - -/* - * Compare the prefix and suffix with the subject, and check that the - * characters in-between are valid. - */ -static int wildcard_match(const unsigned char *prefix, size_t prefix_len, - const unsigned char *suffix, size_t suffix_len, - const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - const unsigned char *wildcard_start; - const unsigned char *wildcard_end; - const unsigned char *p; - int allow_multi = 0; - int allow_idna = 0; - - if (subject_len < prefix_len + suffix_len) - return 0; - if (!equal_nocase(prefix, prefix_len, subject, prefix_len, flags)) - return 0; - wildcard_start = subject + prefix_len; - wildcard_end = subject + (subject_len - suffix_len); - if (!equal_nocase(wildcard_end, suffix_len, suffix, suffix_len, flags)) - return 0; - /* - * If the wildcard makes up the entire first label, it must match at - * least one character. - */ - if (prefix_len == 0 && *suffix == '.') { - if (wildcard_start == wildcard_end) - return 0; - allow_idna = 1; - if (flags & X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS) - allow_multi = 1; - } - /* IDNA labels cannot match partial wildcards */ - if (!allow_idna && - subject_len >= 4 && strncasecmp((char *)subject, "xn--", 4) == 0) - return 0; - /* The wildcard may match a literal '*' */ - if (wildcard_end == wildcard_start + 1 && *wildcard_start == '*') - return 1; - /* - * Check that the part matched by the wildcard contains only - * permitted characters and only matches a single label unless - * allow_multi is set. - */ - for (p = wildcard_start; p != wildcard_end; ++p) - if (!(('0' <= *p && *p <= '9') || - ('A' <= *p && *p <= 'Z') || - ('a' <= *p && *p <= 'z') || - *p == '-' || (allow_multi && *p == '.'))) - return 0; - return 1; -} - -#define LABEL_START (1 << 0) -#define LABEL_END (1 << 1) -#define LABEL_HYPHEN (1 << 2) -#define LABEL_IDNA (1 << 3) - -static const unsigned char *valid_star(const unsigned char *p, size_t len, - unsigned int flags) -{ - const unsigned char *star = 0; - size_t i; - int state = LABEL_START; - int dots = 0; - for (i = 0; i < len; ++i) { - /* - * Locate first and only legal wildcard, either at the start - * or end of a non-IDNA first and not final label. - */ - if (p[i] == '*') { - int atstart = (state & LABEL_START); - int atend = (i == len - 1 || p[i + 1] == '.'); - /*- - * At most one wildcard per pattern. - * No wildcards in IDNA labels. - * No wildcards after the first label. - */ - if (star != NULL || (state & LABEL_IDNA) != 0 || dots) - return NULL; - /* Only full-label '*.example.com' wildcards? */ - if ((flags & X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS) - && (!atstart || !atend)) - return NULL; - /* No 'foo*bar' wildcards */ - if (!atstart && !atend) - return NULL; - star = &p[i]; - state &= ~LABEL_START; - } else if (('a' <= p[i] && p[i] <= 'z') - || ('A' <= p[i] && p[i] <= 'Z') - || ('0' <= p[i] && p[i] <= '9')) { - if ((state & LABEL_START) != 0 - && len - i >= 4 && strncasecmp((char *)&p[i], "xn--", 4) == 0) - state |= LABEL_IDNA; - state &= ~(LABEL_HYPHEN | LABEL_START); - } else if (p[i] == '.') { - if ((state & (LABEL_HYPHEN | LABEL_START)) != 0) - return NULL; - state = LABEL_START; - ++dots; - } else if (p[i] == '-') { - /* no domain/subdomain starts with '-' */ - if ((state & LABEL_START) != 0) - return NULL; - state |= LABEL_HYPHEN; - } else - return NULL; - } - - /* - * The final label must not end in a hyphen or ".", and - * there must be at least two dots after the star. - */ - if ((state & (LABEL_START | LABEL_HYPHEN)) != 0 || dots < 2) - return NULL; - return star; -} - -/* Compare using wildcards. */ -static int equal_wildcard(const unsigned char *pattern, size_t pattern_len, - const unsigned char *subject, size_t subject_len, - unsigned int flags) -{ - const unsigned char *star = NULL; - - /* - * Subject names starting with '.' can only match a wildcard pattern - * via a subject sub-domain pattern suffix match. - */ - if (!(subject_len > 1 && subject[0] == '.')) - star = valid_star(pattern, pattern_len, flags); - if (star == NULL) - return equal_nocase(pattern, pattern_len, - subject, subject_len, flags); - return wildcard_match(pattern, star - pattern, - star + 1, (pattern + pattern_len) - star - 1, - subject, subject_len, flags); -} - -/* - * Compare an ASN1_STRING to a supplied string. If they match return 1. If - * cmp_type > 0 only compare if string matches the type, otherwise convert it - * to UTF8. - */ - -static int do_check_string(ASN1_STRING *a, int cmp_type, equal_fn equal, - unsigned int flags, const char *b, size_t blen, - char **peername) -{ - int rv = 0; - - if (!a->data || !a->length) - return 0; - if (cmp_type > 0) { - if (cmp_type != a->type) - return 0; - if (cmp_type == V_ASN1_IA5STRING) - rv = equal(a->data, a->length, (unsigned char *)b, blen, flags); - else if (a->length == (int)blen && !memcmp(a->data, b, blen)) - rv = 1; - if (rv > 0 && peername) - *peername = BUF_strndup((char *)a->data, a->length); - } else { - int astrlen; - unsigned char *astr; - astrlen = ASN1_STRING_to_UTF8(&astr, a); - if (astrlen < 0) { - /* - * -1 could be an internal malloc failure or a decoding error from - * malformed input; we can't distinguish. - */ - return -1; - } - rv = equal(astr, astrlen, (unsigned char *)b, blen, flags); - if (rv > 0 && peername) - *peername = BUF_strndup((char *)astr, astrlen); - OPENSSL_free(astr); - } - return rv; -} - -static int do_x509_check(X509 *x, const char *chk, size_t chklen, - unsigned int flags, int check_type, char **peername) -{ - GENERAL_NAMES *gens = NULL; - X509_NAME *name = NULL; - int i; - int cnid = NID_undef; - int alt_type; - int san_present = 0; - int rv = 0; - equal_fn equal; - - /* See below, this flag is internal-only */ - flags &= ~_X509_CHECK_FLAG_DOT_SUBDOMAINS; - if (check_type == GEN_EMAIL) { - cnid = NID_pkcs9_emailAddress; - alt_type = V_ASN1_IA5STRING; - equal = equal_email; - } else if (check_type == GEN_DNS) { - cnid = NID_commonName; - /* Implicit client-side DNS sub-domain pattern */ - if (chklen > 1 && chk[0] == '.') - flags |= _X509_CHECK_FLAG_DOT_SUBDOMAINS; - alt_type = V_ASN1_IA5STRING; - if (flags & X509_CHECK_FLAG_NO_WILDCARDS) - equal = equal_nocase; - else - equal = equal_wildcard; - } else { - alt_type = V_ASN1_OCTET_STRING; - equal = equal_case; - } - - if (chklen == 0) - chklen = strlen(chk); - - gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - if (gens) { - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - GENERAL_NAME *gen; - ASN1_STRING *cstr; - gen = sk_GENERAL_NAME_value(gens, i); - if (gen->type != check_type) - continue; - san_present = 1; - if (check_type == GEN_EMAIL) - cstr = gen->d.rfc822Name; - else if (check_type == GEN_DNS) - cstr = gen->d.dNSName; - else - cstr = gen->d.iPAddress; - /* Positive on success, negative on error! */ - if ((rv = do_check_string(cstr, alt_type, equal, flags, - chk, chklen, peername)) != 0) - break; - } - GENERAL_NAMES_free(gens); - if (rv != 0) - return rv; - if (cnid == NID_undef - || (san_present - && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT))) - return 0; - } - - /* We're done if CN-ID is not pertinent */ - if (cnid == NID_undef) - return 0; - - i = -1; - name = X509_get_subject_name(x); - while ((i = X509_NAME_get_index_by_NID(name, cnid, i)) >= 0) { - X509_NAME_ENTRY *ne; - ASN1_STRING *str; - ne = X509_NAME_get_entry(name, i); - str = X509_NAME_ENTRY_get_data(ne); - /* Positive on success, negative on error! */ - if ((rv = do_check_string(str, -1, equal, flags, - chk, chklen, peername)) != 0) - return rv; - } - return 0; -} - -int X509_check_host(X509 *x, const char *chk, size_t chklen, - unsigned int flags, char **peername) -{ - if (chk == NULL) - return -2; - /* - * Embedded NULs are disallowed, except as the last character of a - * string of length 2 or more (tolerate caller including terminating - * NUL in string length). - */ - if (chklen == 0) - chklen = strlen(chk); - else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen)) - return -2; - if (chklen > 1 && chk[chklen - 1] == '\0') - --chklen; - return do_x509_check(x, chk, chklen, flags, GEN_DNS, peername); -} - -int X509_check_email(X509 *x, const char *chk, size_t chklen, - unsigned int flags) -{ - if (chk == NULL) - return -2; - /* - * Embedded NULs are disallowed, except as the last character of a - * string of length 2 or more (tolerate caller including terminating - * NUL in string length). - */ - if (chklen == 0) - chklen = strlen((char *)chk); - else if (memchr(chk, '\0', chklen > 1 ? chklen - 1 : chklen)) - return -2; - if (chklen > 1 && chk[chklen - 1] == '\0') - --chklen; - return do_x509_check(x, chk, chklen, flags, GEN_EMAIL, NULL); -} - -int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, - unsigned int flags) -{ - if (chk == NULL) - return -2; - return do_x509_check(x, (char *)chk, chklen, flags, GEN_IPADD, NULL); -} - -int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags) -{ - unsigned char ipout[16]; - size_t iplen; - - if (ipasc == NULL) - return -2; - iplen = (size_t)a2i_ipadd(ipout, ipasc); - if (iplen == 0) - return -2; - return do_x509_check(x, (char *)ipout, iplen, flags, GEN_IPADD, NULL); -} - -/* - * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible - * with RFC3280. - */ - -ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) -{ - unsigned char ipout[16]; - ASN1_OCTET_STRING *ret; - int iplen; - - /* If string contains a ':' assume IPv6 */ - - iplen = a2i_ipadd(ipout, ipasc); - - if (!iplen) - return NULL; - - ret = ASN1_OCTET_STRING_new(); - if (!ret) - return NULL; - if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { - ASN1_OCTET_STRING_free(ret); - return NULL; - } - return ret; -} - -ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) -{ - ASN1_OCTET_STRING *ret = NULL; - unsigned char ipout[32]; - char *iptmp = NULL, *p; - int iplen1, iplen2; - p = strchr(ipasc, '/'); - if (!p) - return NULL; - iptmp = BUF_strdup(ipasc); - if (!iptmp) - return NULL; - p = iptmp + (p - ipasc); - *p++ = 0; - - iplen1 = a2i_ipadd(ipout, iptmp); - - if (!iplen1) - goto err; - - iplen2 = a2i_ipadd(ipout + iplen1, p); - - OPENSSL_free(iptmp); - iptmp = NULL; - - if (!iplen2 || (iplen1 != iplen2)) - goto err; - - ret = ASN1_OCTET_STRING_new(); - if (!ret) - goto err; - if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) - goto err; - - return ret; - - err: - if (iptmp) - OPENSSL_free(iptmp); - if (ret) - ASN1_OCTET_STRING_free(ret); - return NULL; -} - -int a2i_ipadd(unsigned char *ipout, const char *ipasc) -{ - /* If string contains a ':' assume IPv6 */ - - if (strchr(ipasc, ':')) { - if (!ipv6_from_asc(ipout, ipasc)) - return 0; - return 16; - } else { - if (!ipv4_from_asc(ipout, ipasc)) - return 0; - return 4; - } -} - -static int ipv4_from_asc(unsigned char *v4, const char *in) -{ - int a0, a1, a2, a3; - if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) - return 0; - if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) - || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) - return 0; - v4[0] = a0; - v4[1] = a1; - v4[2] = a2; - v4[3] = a3; - return 1; -} - -typedef struct { - /* Temporary store for IPV6 output */ - unsigned char tmp[16]; - /* Total number of bytes in tmp */ - int total; - /* The position of a zero (corresponding to '::') */ - int zero_pos; - /* Number of zeroes */ - int zero_cnt; -} IPV6_STAT; - -static int ipv6_from_asc(unsigned char *v6, const char *in) -{ - IPV6_STAT v6stat; - v6stat.total = 0; - v6stat.zero_pos = -1; - v6stat.zero_cnt = 0; - /* - * Treat the IPv6 representation as a list of values separated by ':'. - * The presence of a '::' will parse as one, two or three zero length - * elements. - */ - if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) - return 0; - - /* Now for some sanity checks */ - - if (v6stat.zero_pos == -1) { - /* If no '::' must have exactly 16 bytes */ - if (v6stat.total != 16) - return 0; - } else { - /* If '::' must have less than 16 bytes */ - if (v6stat.total == 16) - return 0; - /* More than three zeroes is an error */ - if (v6stat.zero_cnt > 3) - return 0; - /* Can only have three zeroes if nothing else present */ - else if (v6stat.zero_cnt == 3) { - if (v6stat.total > 0) - return 0; - } - /* Can only have two zeroes if at start or end */ - else if (v6stat.zero_cnt == 2) { - if ((v6stat.zero_pos != 0) - && (v6stat.zero_pos != v6stat.total)) - return 0; - } else - /* Can only have one zero if *not* start or end */ - { - if ((v6stat.zero_pos == 0) - || (v6stat.zero_pos == v6stat.total)) - return 0; - } - } - - /* Format result */ - - if (v6stat.zero_pos >= 0) { - /* Copy initial part */ - memcpy(v6, v6stat.tmp, v6stat.zero_pos); - /* Zero middle */ - memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); - /* Copy final part */ - if (v6stat.total != v6stat.zero_pos) - memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, - v6stat.tmp + v6stat.zero_pos, - v6stat.total - v6stat.zero_pos); - } else - memcpy(v6, v6stat.tmp, 16); - - return 1; -} - -static int ipv6_cb(const char *elem, int len, void *usr) -{ - IPV6_STAT *s = usr; - /* Error if 16 bytes written */ - if (s->total == 16) - return 0; - if (len == 0) { - /* Zero length element, corresponds to '::' */ - if (s->zero_pos == -1) - s->zero_pos = s->total; - /* If we've already got a :: its an error */ - else if (s->zero_pos != s->total) - return 0; - s->zero_cnt++; - } else { - /* If more than 4 characters could be final a.b.c.d form */ - if (len > 4) { - /* Need at least 4 bytes left */ - if (s->total > 12) - return 0; - /* Must be end of string */ - if (elem[len]) - return 0; - if (!ipv4_from_asc(s->tmp + s->total, elem)) - return 0; - s->total += 4; - } else { - if (!ipv6_hex(s->tmp + s->total, elem, len)) - return 0; - s->total += 2; - } - } - return 1; -} - -/* - * Convert a string of up to 4 hex digits into the corresponding IPv6 form. - */ - -static int ipv6_hex(unsigned char *out, const char *in, int inlen) -{ - unsigned char c; - unsigned int num = 0; - if (inlen > 4) - return 0; - while (inlen--) { - c = *in++; - num <<= 4; - if ((c >= '0') && (c <= '9')) - num |= c - '0'; - else if ((c >= 'A') && (c <= 'F')) - num |= c - 'A' + 10; - else if ((c >= 'a') && (c <= 'f')) - num |= c - 'a' + 10; - else - return 0; - } - out[0] = num >> 8; - out[1] = num & 0xff; - return 1; -} - -int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, - unsigned long chtype) -{ - CONF_VALUE *v; - int i, mval; - char *p, *type; - if (!nm) - return 0; - - for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { - v = sk_CONF_VALUE_value(dn_sk, i); - type = v->name; - /* - * Skip past any leading X. X: X, etc to allow for multiple instances - */ - for (p = type; *p; p++) -#ifndef CHARSET_EBCDIC - if ((*p == ':') || (*p == ',') || (*p == '.')) -#else - if ((*p == os_toascii[':']) || (*p == os_toascii[',']) - || (*p == os_toascii['.'])) -#endif - { - p++; - if (*p) - type = p; - break; - } -#ifndef CHARSET_EBCDIC - if (*type == '+') -#else - if (*type == os_toascii['+']) -#endif - { - mval = -1; - type++; - } else - mval = 0; - if (!X509_NAME_add_entry_by_txt(nm, type, chtype, - (unsigned char *)v->value, -1, -1, - mval)) - return 0; - - } - return 1; -} diff --git a/Sources/COpenSSL/v3_lib.c b/Sources/COpenSSL/v3_lib.c deleted file mode 100644 index 28bcdafc..00000000 --- a/Sources/COpenSSL/v3_lib.c +++ /dev/null @@ -1,371 +0,0 @@ -/* v3_lib.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -/* X509 v3 extension utilities */ - -#include -#include "cryptlib.h" -#include "conf.h" -#include "x509v3.h" - -#include "ext_dat.h" - -static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; - -static int ext_cmp(const X509V3_EXT_METHOD *const *a, - const X509V3_EXT_METHOD *const *b); -static void ext_list_free(X509V3_EXT_METHOD *ext); - -int X509V3_EXT_add(X509V3_EXT_METHOD *ext) -{ - if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) { - X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { - X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - return 1; -} - -static int ext_cmp(const X509V3_EXT_METHOD *const *a, - const X509V3_EXT_METHOD *const *b) -{ - return ((*a)->ext_nid - (*b)->ext_nid); -} - -DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, - const X509V3_EXT_METHOD *, ext); -IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, - const X509V3_EXT_METHOD *, ext); - -const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) -{ - X509V3_EXT_METHOD tmp; - const X509V3_EXT_METHOD *t = &tmp, *const *ret; - int idx; - if (nid < 0) - return NULL; - tmp.ext_nid = nid; - ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT); - if (ret) - return *ret; - if (!ext_list) - return NULL; - idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); - if (idx == -1) - return NULL; - return sk_X509V3_EXT_METHOD_value(ext_list, idx); -} - -const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext) -{ - int nid; - if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) - return NULL; - return X509V3_EXT_get_nid(nid); -} - -int X509V3_EXT_free(int nid, void *ext_data) -{ - const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid); - if (ext_method == NULL) { - X509V3err(X509V3_F_X509V3_EXT_FREE, - X509V3_R_CANNOT_FIND_FREE_FUNCTION); - return 0; - } - - if (ext_method->it != NULL) - ASN1_item_free(ext_data, ASN1_ITEM_ptr(ext_method->it)); - else if (ext_method->ext_free != NULL) - ext_method->ext_free(ext_data); - else { - X509V3err(X509V3_F_X509V3_EXT_FREE, - X509V3_R_CANNOT_FIND_FREE_FUNCTION); - return 0; - } - - return 1; -} - -int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) -{ - for (; extlist->ext_nid != -1; extlist++) - if (!X509V3_EXT_add(extlist)) - return 0; - return 1; -} - -int X509V3_EXT_add_alias(int nid_to, int nid_from) -{ - const X509V3_EXT_METHOD *ext; - X509V3_EXT_METHOD *tmpext; - - if (!(ext = X509V3_EXT_get_nid(nid_from))) { - X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, - X509V3_R_EXTENSION_NOT_FOUND); - return 0; - } - if (! - (tmpext = - (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { - X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE); - return 0; - } - *tmpext = *ext; - tmpext->ext_nid = nid_to; - tmpext->ext_flags |= X509V3_EXT_DYNAMIC; - return X509V3_EXT_add(tmpext); -} - -void X509V3_EXT_cleanup(void) -{ - sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free); - ext_list = NULL; -} - -static void ext_list_free(X509V3_EXT_METHOD *ext) -{ - if (ext->ext_flags & X509V3_EXT_DYNAMIC) - OPENSSL_free(ext); -} - -/* - * Legacy function: we don't need to add standard extensions any more because - * they are now kept in ext_dat.h. - */ - -int X509V3_add_standard_extensions(void) -{ - return 1; -} - -/* Return an extension internal structure */ - -void *X509V3_EXT_d2i(X509_EXTENSION *ext) -{ - const X509V3_EXT_METHOD *method; - const unsigned char *p; - - if (!(method = X509V3_EXT_get(ext))) - return NULL; - p = ext->value->data; - if (method->it) - return ASN1_item_d2i(NULL, &p, ext->value->length, - ASN1_ITEM_ptr(method->it)); - return method->d2i(NULL, &p, ext->value->length); -} - -/*- - * Get critical flag and decoded version of extension from a NID. - * The "idx" variable returns the last found extension and can - * be used to retrieve multiple extensions of the same NID. - * However multiple extensions with the same NID is usually - * due to a badly encoded certificate so if idx is NULL we - * choke if multiple extensions exist. - * The "crit" variable is set to the critical value. - * The return value is the decoded extension or NULL on - * error. The actual error can have several different causes, - * the value of *crit reflects the cause: - * >= 0, extension found but not decoded (reflects critical value). - * -1 extension not found. - * -2 extension occurs more than once. - */ - -void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, - int *idx) -{ - int lastpos, i; - X509_EXTENSION *ex, *found_ex = NULL; - if (!x) { - if (idx) - *idx = -1; - if (crit) - *crit = -1; - return NULL; - } - if (idx) - lastpos = *idx + 1; - else - lastpos = 0; - if (lastpos < 0) - lastpos = 0; - for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) { - ex = sk_X509_EXTENSION_value(x, i); - if (OBJ_obj2nid(ex->object) == nid) { - if (idx) { - *idx = i; - found_ex = ex; - break; - } else if (found_ex) { - /* Found more than one */ - if (crit) - *crit = -2; - return NULL; - } - found_ex = ex; - } - } - if (found_ex) { - /* Found it */ - if (crit) - *crit = X509_EXTENSION_get_critical(found_ex); - return X509V3_EXT_d2i(found_ex); - } - - /* Extension not found */ - if (idx) - *idx = -1; - if (crit) - *crit = -1; - return NULL; -} - -/* - * This function is a general extension append, replace and delete utility. - * The precise operation is governed by the 'flags' value. The 'crit' and - * 'value' arguments (if relevant) are the extensions internal structure. - */ - -int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, - int crit, unsigned long flags) -{ - int errcode, extidx = -1; - X509_EXTENSION *ext = NULL, *extmp; - STACK_OF(X509_EXTENSION) *ret = NULL; - unsigned long ext_op = flags & X509V3_ADD_OP_MASK; - - /* - * If appending we don't care if it exists, otherwise look for existing - * extension. - */ - if (ext_op != X509V3_ADD_APPEND) - extidx = X509v3_get_ext_by_NID(*x, nid, -1); - - /* See if extension exists */ - if (extidx >= 0) { - /* If keep existing, nothing to do */ - if (ext_op == X509V3_ADD_KEEP_EXISTING) - return 1; - /* If default then its an error */ - if (ext_op == X509V3_ADD_DEFAULT) { - errcode = X509V3_R_EXTENSION_EXISTS; - goto err; - } - /* If delete, just delete it */ - if (ext_op == X509V3_ADD_DELETE) { - if (!sk_X509_EXTENSION_delete(*x, extidx)) - return -1; - return 1; - } - } else { - /* - * If replace existing or delete, error since extension must exist - */ - if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || - (ext_op == X509V3_ADD_DELETE)) { - errcode = X509V3_R_EXTENSION_NOT_FOUND; - goto err; - } - } - - /* - * If we get this far then we have to create an extension: could have - * some flags for alternative encoding schemes... - */ - - ext = X509V3_EXT_i2d(nid, crit, value); - - if (!ext) { - X509V3err(X509V3_F_X509V3_ADD1_I2D, - X509V3_R_ERROR_CREATING_EXTENSION); - return 0; - } - - /* If extension exists replace it.. */ - if (extidx >= 0) { - extmp = sk_X509_EXTENSION_value(*x, extidx); - X509_EXTENSION_free(extmp); - if (!sk_X509_EXTENSION_set(*x, extidx, ext)) - return -1; - return 1; - } - - if ((ret = *x) == NULL - && (ret = sk_X509_EXTENSION_new_null()) == NULL) - goto m_fail; - if (!sk_X509_EXTENSION_push(ret, ext)) - goto m_fail; - - *x = ret; - return 1; - - m_fail: - if (ret != *x) - sk_X509_EXTENSION_free(ret); - X509_EXTENSION_free(ext); - return -1; - - err: - if (!(flags & X509V3_ADD_SILENT)) - X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode); - return 0; -} - -IMPLEMENT_STACK_OF(X509V3_EXT_METHOD) diff --git a/Sources/COpenSSL/v3err.c b/Sources/COpenSSL/v3err.c deleted file mode 100644 index 1274e690..00000000 --- a/Sources/COpenSSL/v3err.c +++ /dev/null @@ -1,249 +0,0 @@ -/* crypto/x509v3/v3err.c */ -/* ==================================================================== - * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -#include "x509v3.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason) - -static ERR_STRING_DATA X509V3_str_functs[] = { - {ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "a2i_GENERAL_NAME"}, - {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), - "ASIDENTIFIERCHOICE_CANONIZE"}, - {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), - "ASIDENTIFIERCHOICE_IS_CANONICAL"}, - {ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"}, - {ERR_FUNC(X509V3_F_COPY_ISSUER), "COPY_ISSUER"}, - {ERR_FUNC(X509V3_F_DO_DIRNAME), "DO_DIRNAME"}, - {ERR_FUNC(X509V3_F_DO_EXT_CONF), "DO_EXT_CONF"}, - {ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"}, - {ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"}, - {ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"}, - {ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "GNAMES_FROM_SECTNAME"}, - {ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"}, - {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"}, - {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"}, - {ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"}, - {ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS), - "I2V_AUTHORITY_INFO_ACCESS"}, - {ERR_FUNC(X509V3_F_NOTICE_SECTION), "NOTICE_SECTION"}, - {ERR_FUNC(X509V3_F_NREF_NOS), "NREF_NOS"}, - {ERR_FUNC(X509V3_F_POLICY_SECTION), "POLICY_SECTION"}, - {ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "PROCESS_PCI_VALUE"}, - {ERR_FUNC(X509V3_F_R2I_CERTPOL), "R2I_CERTPOL"}, - {ERR_FUNC(X509V3_F_R2I_PCI), "R2I_PCI"}, - {ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "S2I_ASN1_IA5STRING"}, - {ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"}, - {ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"}, - {ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"}, - {ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"}, - {ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "SET_DIST_POINT_NAME"}, - {ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"}, - {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"}, - {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"}, - {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"}, - {ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"}, - {ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"}, - {ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "V2I_ASIDENTIFIERS"}, - {ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"}, - {ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS), - "V2I_AUTHORITY_INFO_ACCESS"}, - {ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "V2I_AUTHORITY_KEYID"}, - {ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "V2I_BASIC_CONSTRAINTS"}, - {ERR_FUNC(X509V3_F_V2I_CRLD), "V2I_CRLD"}, - {ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"}, - {ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"}, - {ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"}, - {ERR_FUNC(X509V3_F_V2I_IDP), "V2I_IDP"}, - {ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"}, - {ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"}, - {ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"}, - {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "V2I_POLICY_CONSTRAINTS"}, - {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "V2I_POLICY_MAPPINGS"}, - {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "V2I_SUBJECT_ALT"}, - {ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL), - "V3_ADDR_VALIDATE_PATH_INTERNAL"}, - {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "V3_GENERIC_EXTENSION"}, - {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"}, - {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"}, - {ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"}, - {ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"}, - {ERR_FUNC(X509V3_F_X509V3_EXT_CONF), "X509V3_EXT_conf"}, - {ERR_FUNC(X509V3_F_X509V3_EXT_FREE), "X509V3_EXT_free"}, - {ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"}, - {ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"}, - {ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"}, - {ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"}, - {ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"}, - {ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"}, - {ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"}, - {ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"}, - {0, NULL} -}; - -static ERR_STRING_DATA X509V3_str_reasons[] = { - {ERR_REASON(X509V3_R_BAD_IP_ADDRESS), "bad ip address"}, - {ERR_REASON(X509V3_R_BAD_OBJECT), "bad object"}, - {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR), "bn dec2bn error"}, - {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR), - "bn to asn1 integer error"}, - {ERR_REASON(X509V3_R_CANNOT_FIND_FREE_FUNCTION), - "cannot find free function"}, - {ERR_REASON(X509V3_R_DIRNAME_ERROR), "dirname error"}, - {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"}, - {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID), "duplicate zone id"}, - {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, - {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION), - "error creating extension"}, - {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION), "error in extension"}, - {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"}, - {ERR_REASON(X509V3_R_EXTENSION_EXISTS), "extension exists"}, - {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"}, - {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"}, - {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), - "extension setting not supported"}, - {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"}, - {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"}, - {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"}, - {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), - "incorrect policy syntax tag"}, - {ERR_REASON(X509V3_R_INVALID_ASNUMBER), "invalid asnumber"}, - {ERR_REASON(X509V3_R_INVALID_ASRANGE), "invalid asrange"}, - {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, - {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING), - "invalid extension string"}, - {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"}, - {ERR_REASON(X509V3_R_INVALID_IPADDRESS), "invalid ipaddress"}, - {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"}, - {ERR_REASON(X509V3_R_INVALID_NAME), "invalid name"}, - {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, - {ERR_REASON(X509V3_R_INVALID_NULL_NAME), "invalid null name"}, - {ERR_REASON(X509V3_R_INVALID_NULL_VALUE), "invalid null value"}, - {ERR_REASON(X509V3_R_INVALID_NUMBER), "invalid number"}, - {ERR_REASON(X509V3_R_INVALID_NUMBERS), "invalid numbers"}, - {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER), - "invalid object identifier"}, - {ERR_REASON(X509V3_R_INVALID_OPTION), "invalid option"}, - {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER), - "invalid policy identifier"}, - {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING), - "invalid proxy policy setting"}, - {ERR_REASON(X509V3_R_INVALID_PURPOSE), "invalid purpose"}, - {ERR_REASON(X509V3_R_INVALID_SAFI), "invalid safi"}, - {ERR_REASON(X509V3_R_INVALID_SECTION), "invalid section"}, - {ERR_REASON(X509V3_R_INVALID_SYNTAX), "invalid syntax"}, - {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"}, - {ERR_REASON(X509V3_R_MISSING_VALUE), "missing value"}, - {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), - "need organization and numbers"}, - {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE), "no config database"}, - {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"}, - {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS), "no issuer details"}, - {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"}, - {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), - "no proxy cert policy language defined"}, - {ERR_REASON(X509V3_R_NO_PUBLIC_KEY), "no public key"}, - {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS), "no subject details"}, - {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, - {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"}, - {ERR_REASON(X509V3_R_OTHERNAME_ERROR), "othername error"}, - {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), - "policy language already defined"}, - {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH), "policy path length"}, - {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), - "policy path length already defined"}, - {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED), - "policy syntax not currently supported"}, - {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), - "policy when proxy language requires no policy"}, - {ERR_REASON(X509V3_R_SECTION_NOT_FOUND), "section not found"}, - {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), - "unable to get issuer details"}, - {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), - "unable to get issuer keyid"}, - {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), - "unknown bit string argument"}, - {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION), "unknown extension"}, - {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"}, - {ERR_REASON(X509V3_R_UNKNOWN_OPTION), "unknown option"}, - {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION), "unsupported option"}, - {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE), "unsupported type"}, - {ERR_REASON(X509V3_R_USER_TOO_LONG), "user too long"}, - {0, NULL} -}; - -#endif - -void ERR_load_X509V3_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { - ERR_load_strings(0, X509V3_str_functs); - ERR_load_strings(0, X509V3_str_reasons); - } -#endif -} diff --git a/Sources/COpenSSL/vpm_int.h b/Sources/COpenSSL/vpm_int.h deleted file mode 100644 index 9c55defc..00000000 --- a/Sources/COpenSSL/vpm_int.h +++ /dev/null @@ -1,70 +0,0 @@ -/* vpm_int.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2013. - */ -/* ==================================================================== - * Copyright (c) 2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* internal only structure to hold additional X509_VERIFY_PARAM data */ - -struct X509_VERIFY_PARAM_ID_st { - STACK_OF(OPENSSL_STRING) *hosts; /* Set of acceptable names */ - unsigned int hostflags; /* Flags to control matching features */ - char *peername; /* Matching hostname in peer certificate */ - char *email; /* If not NULL email address to match */ - size_t emaillen; - unsigned char *ip; /* If not NULL IP address to match */ - size_t iplen; /* Length of IP address */ -}; diff --git a/Sources/COpenSSL/whrlpool.h b/Sources/COpenSSL/whrlpool.h deleted file mode 100644 index b6f3d035..00000000 --- a/Sources/COpenSSL/whrlpool.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef HEADER_WHRLPOOL_H -# define HEADER_WHRLPOOL_H - -# include "e_os2.h" -# include - -#ifdef __cplusplus -extern "C" { -#endif - -# define WHIRLPOOL_DIGEST_LENGTH (512/8) -# define WHIRLPOOL_BBLOCK 512 -# define WHIRLPOOL_COUNTER (256/8) - -typedef struct { - union { - unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; - /* double q is here to ensure 64-bit alignment */ - double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)]; - } H; - unsigned char data[WHIRLPOOL_BBLOCK / 8]; - unsigned int bitoff; - size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)]; -} WHIRLPOOL_CTX; - -# ifndef OPENSSL_NO_WHIRLPOOL -# ifdef OPENSSL_FIPS -int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c); -# endif -int WHIRLPOOL_Init(WHIRLPOOL_CTX *c); -int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes); -void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits); -int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c); -unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md); -# endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/Sources/COpenSSL/wp_.c b/Sources/COpenSSL/wp_.c deleted file mode 100644 index cf6a3191..00000000 --- a/Sources/COpenSSL/wp_.c +++ /dev/null @@ -1,1038 +0,0 @@ -/** - * The Whirlpool hashing function. - * - *

- * References - * - *

- * The Whirlpool algorithm was developed by - * Paulo S. L. M. Barreto and - * Vincent Rijmen. - * - * See - * P.S.L.M. Barreto, V. Rijmen, - * ``The Whirlpool hashing function,'' - * NESSIE submission, 2000 (tweaked version, 2001), - * - * - * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and - * Vincent Rijmen. Lookup "reference implementations" on - * - * - * ============================================================================= - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "wp_locl.h" -#include - -typedef unsigned char u8; -#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32) -typedef unsigned __int64 u64; -#elif defined(__arch64__) -typedef unsigned long u64; -#else -typedef unsigned long long u64; -#endif - -#define ROUNDS 10 - -#define STRICT_ALIGNMENT -#if defined(__i386) || defined(__i386__) || \ - defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) -/* - * Well, formally there're couple of other architectures, which permit - * unaligned loads, specifically those not crossing cache lines, IA-64 and - * PowerPC... - */ -# undef STRICT_ALIGNMENT -#endif - -#undef SMALL_REGISTER_BANK -#if defined(__i386) || defined(__i386__) || defined(_M_IX86) -# define SMALL_REGISTER_BANK -# if defined(WHIRLPOOL_ASM) -# ifndef OPENSSL_SMALL_FOOTPRINT -/* - * it appears that for elder non-MMX - * CPUs this is actually faster! - */ -# define OPENSSL_SMALL_FOOTPRINT -# endif -# define GO_FOR_MMX(ctx,inp,num) do { \ - extern unsigned int OPENSSL_ia32cap_P[]; \ - void whirlpool_block_mmx(void *,const void *,size_t); \ - if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \ - whirlpool_block_mmx(ctx->H.c,inp,num); return; \ - } while (0) -# endif -#endif - -#undef ROTATE -#if defined(_MSC_VER) -# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ -# pragma intrinsic(_rotl64) -# define ROTATE(a,n) _rotl64((a),n) -# endif -#elif defined(__GNUC__) && __GNUC__>=2 -# if defined(__x86_64) || defined(__x86_64__) -# if defined(L_ENDIAN) -# define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \ - : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) -# elif defined(B_ENDIAN) - /* - * Most will argue that x86_64 is always little-endian. Well, yes, but - * then we have stratus.com who has modified gcc to "emulate" - * big-endian on x86. Is there evidence that they [or somebody else] - * won't do same for x86_64? Naturally no. And this line is waiting - * ready for that brave soul:-) - */ -# define ROTATE(a,n) ({ u64 ret; asm ("rorq %1,%0" \ - : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) -# endif -# elif defined(__ia64) || defined(__ia64__) -# if defined(L_ENDIAN) -# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ - : "=r"(ret) : "r"(a),"M"(64-(n))); ret; }) -# elif defined(B_ENDIAN) -# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ - : "=r"(ret) : "r"(a),"M"(n)); ret; }) -# endif -# endif -#endif - -#if defined(OPENSSL_SMALL_FOOTPRINT) -# if !defined(ROTATE) -# if defined(L_ENDIAN) /* little-endians have to rotate left */ -# define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n)) -# elif defined(B_ENDIAN) /* big-endians have to rotate right */ -# define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n)) -# endif -# endif -# if defined(ROTATE) && !defined(STRICT_ALIGNMENT) -# define STRICT_ALIGNMENT /* ensure smallest table size */ -# endif -#endif - -/* - * Table size depends on STRICT_ALIGNMENT and whether or not endian- - * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not - * defined, which is normally the case on x86[_64] CPUs, the table is - * 4KB large unconditionally. Otherwise if ROTATE is defined, the - * table is 2KB large, and otherwise - 16KB. 2KB table requires a - * whole bunch of additional rotations, but I'm willing to "trade," - * because 16KB table certainly trashes L1 cache. I wish all CPUs - * could handle unaligned load as 4KB table doesn't trash the cache, - * nor does it require additional rotations. - */ -/* - * Note that every Cn macro expands as two loads: one byte load and - * one quadword load. One can argue that that many single-byte loads - * is too excessive, as one could load a quadword and "milk" it for - * eight 8-bit values instead. Well, yes, but in order to do so *and* - * avoid excessive loads you have to accomodate a handful of 64-bit - * values in the register bank and issue a bunch of shifts and mask. - * It's a tradeoff: loads vs. shift and mask in big register bank[!]. - * On most CPUs eight single-byte loads are faster and I let other - * ones to depend on smart compiler to fold byte loads if beneficial. - * Hand-coded assembler would be another alternative:-) - */ -#ifdef STRICT_ALIGNMENT -# if defined(ROTATE) -# define N 1 -# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7 -# define C0(K,i) (Cx.q[K.c[(i)*8+0]]) -# define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8) -# define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16) -# define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24) -# define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32) -# define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40) -# define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48) -# define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56) -# else -# define N 8 -# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ - c7,c0,c1,c2,c3,c4,c5,c6, \ - c6,c7,c0,c1,c2,c3,c4,c5, \ - c5,c6,c7,c0,c1,c2,c3,c4, \ - c4,c5,c6,c7,c0,c1,c2,c3, \ - c3,c4,c5,c6,c7,c0,c1,c2, \ - c2,c3,c4,c5,c6,c7,c0,c1, \ - c1,c2,c3,c4,c5,c6,c7,c0 -# define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]]) -# define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]]) -# define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]]) -# define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]]) -# define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]]) -# define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]]) -# define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]]) -# define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]]) -# endif -#else -# define N 2 -# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ - c0,c1,c2,c3,c4,c5,c6,c7 -# define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) -# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) -# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) -# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) -# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) -# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) -# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) -# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) -#endif - -static const - union { - u8 c[(256 * N + ROUNDS) * sizeof(u64)]; - u64 q[(256 * N + ROUNDS)]; -} Cx = { - { - /* Note endian-neutral representation:-) */ - LL(0x18, 0x18, 0x60, 0x18, 0xc0, 0x78, 0x30, 0xd8), - LL(0x23, 0x23, 0x8c, 0x23, 0x05, 0xaf, 0x46, 0x26), - LL(0xc6, 0xc6, 0x3f, 0xc6, 0x7e, 0xf9, 0x91, 0xb8), - LL(0xe8, 0xe8, 0x87, 0xe8, 0x13, 0x6f, 0xcd, 0xfb), - LL(0x87, 0x87, 0x26, 0x87, 0x4c, 0xa1, 0x13, 0xcb), - LL(0xb8, 0xb8, 0xda, 0xb8, 0xa9, 0x62, 0x6d, 0x11), - LL(0x01, 0x01, 0x04, 0x01, 0x08, 0x05, 0x02, 0x09), - LL(0x4f, 0x4f, 0x21, 0x4f, 0x42, 0x6e, 0x9e, 0x0d), - LL(0x36, 0x36, 0xd8, 0x36, 0xad, 0xee, 0x6c, 0x9b), - LL(0xa6, 0xa6, 0xa2, 0xa6, 0x59, 0x04, 0x51, 0xff), - LL(0xd2, 0xd2, 0x6f, 0xd2, 0xde, 0xbd, 0xb9, 0x0c), - LL(0xf5, 0xf5, 0xf3, 0xf5, 0xfb, 0x06, 0xf7, 0x0e), - LL(0x79, 0x79, 0xf9, 0x79, 0xef, 0x80, 0xf2, 0x96), - LL(0x6f, 0x6f, 0xa1, 0x6f, 0x5f, 0xce, 0xde, 0x30), - LL(0x91, 0x91, 0x7e, 0x91, 0xfc, 0xef, 0x3f, 0x6d), - LL(0x52, 0x52, 0x55, 0x52, 0xaa, 0x07, 0xa4, 0xf8), - LL(0x60, 0x60, 0x9d, 0x60, 0x27, 0xfd, 0xc0, 0x47), - LL(0xbc, 0xbc, 0xca, 0xbc, 0x89, 0x76, 0x65, 0x35), - LL(0x9b, 0x9b, 0x56, 0x9b, 0xac, 0xcd, 0x2b, 0x37), - LL(0x8e, 0x8e, 0x02, 0x8e, 0x04, 0x8c, 0x01, 0x8a), - LL(0xa3, 0xa3, 0xb6, 0xa3, 0x71, 0x15, 0x5b, 0xd2), - LL(0x0c, 0x0c, 0x30, 0x0c, 0x60, 0x3c, 0x18, 0x6c), - LL(0x7b, 0x7b, 0xf1, 0x7b, 0xff, 0x8a, 0xf6, 0x84), - LL(0x35, 0x35, 0xd4, 0x35, 0xb5, 0xe1, 0x6a, 0x80), - LL(0x1d, 0x1d, 0x74, 0x1d, 0xe8, 0x69, 0x3a, 0xf5), - LL(0xe0, 0xe0, 0xa7, 0xe0, 0x53, 0x47, 0xdd, 0xb3), - LL(0xd7, 0xd7, 0x7b, 0xd7, 0xf6, 0xac, 0xb3, 0x21), - LL(0xc2, 0xc2, 0x2f, 0xc2, 0x5e, 0xed, 0x99, 0x9c), - LL(0x2e, 0x2e, 0xb8, 0x2e, 0x6d, 0x96, 0x5c, 0x43), - LL(0x4b, 0x4b, 0x31, 0x4b, 0x62, 0x7a, 0x96, 0x29), - LL(0xfe, 0xfe, 0xdf, 0xfe, 0xa3, 0x21, 0xe1, 0x5d), - LL(0x57, 0x57, 0x41, 0x57, 0x82, 0x16, 0xae, 0xd5), - LL(0x15, 0x15, 0x54, 0x15, 0xa8, 0x41, 0x2a, 0xbd), - LL(0x77, 0x77, 0xc1, 0x77, 0x9f, 0xb6, 0xee, 0xe8), - LL(0x37, 0x37, 0xdc, 0x37, 0xa5, 0xeb, 0x6e, 0x92), - LL(0xe5, 0xe5, 0xb3, 0xe5, 0x7b, 0x56, 0xd7, 0x9e), - LL(0x9f, 0x9f, 0x46, 0x9f, 0x8c, 0xd9, 0x23, 0x13), - LL(0xf0, 0xf0, 0xe7, 0xf0, 0xd3, 0x17, 0xfd, 0x23), - LL(0x4a, 0x4a, 0x35, 0x4a, 0x6a, 0x7f, 0x94, 0x20), - LL(0xda, 0xda, 0x4f, 0xda, 0x9e, 0x95, 0xa9, 0x44), - LL(0x58, 0x58, 0x7d, 0x58, 0xfa, 0x25, 0xb0, 0xa2), - LL(0xc9, 0xc9, 0x03, 0xc9, 0x06, 0xca, 0x8f, 0xcf), - LL(0x29, 0x29, 0xa4, 0x29, 0x55, 0x8d, 0x52, 0x7c), - LL(0x0a, 0x0a, 0x28, 0x0a, 0x50, 0x22, 0x14, 0x5a), - LL(0xb1, 0xb1, 0xfe, 0xb1, 0xe1, 0x4f, 0x7f, 0x50), - LL(0xa0, 0xa0, 0xba, 0xa0, 0x69, 0x1a, 0x5d, 0xc9), - LL(0x6b, 0x6b, 0xb1, 0x6b, 0x7f, 0xda, 0xd6, 0x14), - LL(0x85, 0x85, 0x2e, 0x85, 0x5c, 0xab, 0x17, 0xd9), - LL(0xbd, 0xbd, 0xce, 0xbd, 0x81, 0x73, 0x67, 0x3c), - LL(0x5d, 0x5d, 0x69, 0x5d, 0xd2, 0x34, 0xba, 0x8f), - LL(0x10, 0x10, 0x40, 0x10, 0x80, 0x50, 0x20, 0x90), - LL(0xf4, 0xf4, 0xf7, 0xf4, 0xf3, 0x03, 0xf5, 0x07), - LL(0xcb, 0xcb, 0x0b, 0xcb, 0x16, 0xc0, 0x8b, 0xdd), - LL(0x3e, 0x3e, 0xf8, 0x3e, 0xed, 0xc6, 0x7c, 0xd3), - LL(0x05, 0x05, 0x14, 0x05, 0x28, 0x11, 0x0a, 0x2d), - LL(0x67, 0x67, 0x81, 0x67, 0x1f, 0xe6, 0xce, 0x78), - LL(0xe4, 0xe4, 0xb7, 0xe4, 0x73, 0x53, 0xd5, 0x97), - LL(0x27, 0x27, 0x9c, 0x27, 0x25, 0xbb, 0x4e, 0x02), - LL(0x41, 0x41, 0x19, 0x41, 0x32, 0x58, 0x82, 0x73), - LL(0x8b, 0x8b, 0x16, 0x8b, 0x2c, 0x9d, 0x0b, 0xa7), - LL(0xa7, 0xa7, 0xa6, 0xa7, 0x51, 0x01, 0x53, 0xf6), - LL(0x7d, 0x7d, 0xe9, 0x7d, 0xcf, 0x94, 0xfa, 0xb2), - LL(0x95, 0x95, 0x6e, 0x95, 0xdc, 0xfb, 0x37, 0x49), - LL(0xd8, 0xd8, 0x47, 0xd8, 0x8e, 0x9f, 0xad, 0x56), - LL(0xfb, 0xfb, 0xcb, 0xfb, 0x8b, 0x30, 0xeb, 0x70), - LL(0xee, 0xee, 0x9f, 0xee, 0x23, 0x71, 0xc1, 0xcd), - LL(0x7c, 0x7c, 0xed, 0x7c, 0xc7, 0x91, 0xf8, 0xbb), - LL(0x66, 0x66, 0x85, 0x66, 0x17, 0xe3, 0xcc, 0x71), - LL(0xdd, 0xdd, 0x53, 0xdd, 0xa6, 0x8e, 0xa7, 0x7b), - LL(0x17, 0x17, 0x5c, 0x17, 0xb8, 0x4b, 0x2e, 0xaf), - LL(0x47, 0x47, 0x01, 0x47, 0x02, 0x46, 0x8e, 0x45), - LL(0x9e, 0x9e, 0x42, 0x9e, 0x84, 0xdc, 0x21, 0x1a), - LL(0xca, 0xca, 0x0f, 0xca, 0x1e, 0xc5, 0x89, 0xd4), - LL(0x2d, 0x2d, 0xb4, 0x2d, 0x75, 0x99, 0x5a, 0x58), - LL(0xbf, 0xbf, 0xc6, 0xbf, 0x91, 0x79, 0x63, 0x2e), - LL(0x07, 0x07, 0x1c, 0x07, 0x38, 0x1b, 0x0e, 0x3f), - LL(0xad, 0xad, 0x8e, 0xad, 0x01, 0x23, 0x47, 0xac), - LL(0x5a, 0x5a, 0x75, 0x5a, 0xea, 0x2f, 0xb4, 0xb0), - LL(0x83, 0x83, 0x36, 0x83, 0x6c, 0xb5, 0x1b, 0xef), - LL(0x33, 0x33, 0xcc, 0x33, 0x85, 0xff, 0x66, 0xb6), - LL(0x63, 0x63, 0x91, 0x63, 0x3f, 0xf2, 0xc6, 0x5c), - LL(0x02, 0x02, 0x08, 0x02, 0x10, 0x0a, 0x04, 0x12), - LL(0xaa, 0xaa, 0x92, 0xaa, 0x39, 0x38, 0x49, 0x93), - LL(0x71, 0x71, 0xd9, 0x71, 0xaf, 0xa8, 0xe2, 0xde), - LL(0xc8, 0xc8, 0x07, 0xc8, 0x0e, 0xcf, 0x8d, 0xc6), - LL(0x19, 0x19, 0x64, 0x19, 0xc8, 0x7d, 0x32, 0xd1), - LL(0x49, 0x49, 0x39, 0x49, 0x72, 0x70, 0x92, 0x3b), - LL(0xd9, 0xd9, 0x43, 0xd9, 0x86, 0x9a, 0xaf, 0x5f), - LL(0xf2, 0xf2, 0xef, 0xf2, 0xc3, 0x1d, 0xf9, 0x31), - LL(0xe3, 0xe3, 0xab, 0xe3, 0x4b, 0x48, 0xdb, 0xa8), - LL(0x5b, 0x5b, 0x71, 0x5b, 0xe2, 0x2a, 0xb6, 0xb9), - LL(0x88, 0x88, 0x1a, 0x88, 0x34, 0x92, 0x0d, 0xbc), - LL(0x9a, 0x9a, 0x52, 0x9a, 0xa4, 0xc8, 0x29, 0x3e), - LL(0x26, 0x26, 0x98, 0x26, 0x2d, 0xbe, 0x4c, 0x0b), - LL(0x32, 0x32, 0xc8, 0x32, 0x8d, 0xfa, 0x64, 0xbf), - LL(0xb0, 0xb0, 0xfa, 0xb0, 0xe9, 0x4a, 0x7d, 0x59), - LL(0xe9, 0xe9, 0x83, 0xe9, 0x1b, 0x6a, 0xcf, 0xf2), - LL(0x0f, 0x0f, 0x3c, 0x0f, 0x78, 0x33, 0x1e, 0x77), - LL(0xd5, 0xd5, 0x73, 0xd5, 0xe6, 0xa6, 0xb7, 0x33), - LL(0x80, 0x80, 0x3a, 0x80, 0x74, 0xba, 0x1d, 0xf4), - LL(0xbe, 0xbe, 0xc2, 0xbe, 0x99, 0x7c, 0x61, 0x27), - LL(0xcd, 0xcd, 0x13, 0xcd, 0x26, 0xde, 0x87, 0xeb), - LL(0x34, 0x34, 0xd0, 0x34, 0xbd, 0xe4, 0x68, 0x89), - LL(0x48, 0x48, 0x3d, 0x48, 0x7a, 0x75, 0x90, 0x32), - LL(0xff, 0xff, 0xdb, 0xff, 0xab, 0x24, 0xe3, 0x54), - LL(0x7a, 0x7a, 0xf5, 0x7a, 0xf7, 0x8f, 0xf4, 0x8d), - LL(0x90, 0x90, 0x7a, 0x90, 0xf4, 0xea, 0x3d, 0x64), - LL(0x5f, 0x5f, 0x61, 0x5f, 0xc2, 0x3e, 0xbe, 0x9d), - LL(0x20, 0x20, 0x80, 0x20, 0x1d, 0xa0, 0x40, 0x3d), - LL(0x68, 0x68, 0xbd, 0x68, 0x67, 0xd5, 0xd0, 0x0f), - LL(0x1a, 0x1a, 0x68, 0x1a, 0xd0, 0x72, 0x34, 0xca), - LL(0xae, 0xae, 0x82, 0xae, 0x19, 0x2c, 0x41, 0xb7), - LL(0xb4, 0xb4, 0xea, 0xb4, 0xc9, 0x5e, 0x75, 0x7d), - LL(0x54, 0x54, 0x4d, 0x54, 0x9a, 0x19, 0xa8, 0xce), - LL(0x93, 0x93, 0x76, 0x93, 0xec, 0xe5, 0x3b, 0x7f), - LL(0x22, 0x22, 0x88, 0x22, 0x0d, 0xaa, 0x44, 0x2f), - LL(0x64, 0x64, 0x8d, 0x64, 0x07, 0xe9, 0xc8, 0x63), - LL(0xf1, 0xf1, 0xe3, 0xf1, 0xdb, 0x12, 0xff, 0x2a), - LL(0x73, 0x73, 0xd1, 0x73, 0xbf, 0xa2, 0xe6, 0xcc), - LL(0x12, 0x12, 0x48, 0x12, 0x90, 0x5a, 0x24, 0x82), - LL(0x40, 0x40, 0x1d, 0x40, 0x3a, 0x5d, 0x80, 0x7a), - LL(0x08, 0x08, 0x20, 0x08, 0x40, 0x28, 0x10, 0x48), - LL(0xc3, 0xc3, 0x2b, 0xc3, 0x56, 0xe8, 0x9b, 0x95), - LL(0xec, 0xec, 0x97, 0xec, 0x33, 0x7b, 0xc5, 0xdf), - LL(0xdb, 0xdb, 0x4b, 0xdb, 0x96, 0x90, 0xab, 0x4d), - LL(0xa1, 0xa1, 0xbe, 0xa1, 0x61, 0x1f, 0x5f, 0xc0), - LL(0x8d, 0x8d, 0x0e, 0x8d, 0x1c, 0x83, 0x07, 0x91), - LL(0x3d, 0x3d, 0xf4, 0x3d, 0xf5, 0xc9, 0x7a, 0xc8), - LL(0x97, 0x97, 0x66, 0x97, 0xcc, 0xf1, 0x33, 0x5b), - LL(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - LL(0xcf, 0xcf, 0x1b, 0xcf, 0x36, 0xd4, 0x83, 0xf9), - LL(0x2b, 0x2b, 0xac, 0x2b, 0x45, 0x87, 0x56, 0x6e), - LL(0x76, 0x76, 0xc5, 0x76, 0x97, 0xb3, 0xec, 0xe1), - LL(0x82, 0x82, 0x32, 0x82, 0x64, 0xb0, 0x19, 0xe6), - LL(0xd6, 0xd6, 0x7f, 0xd6, 0xfe, 0xa9, 0xb1, 0x28), - LL(0x1b, 0x1b, 0x6c, 0x1b, 0xd8, 0x77, 0x36, 0xc3), - LL(0xb5, 0xb5, 0xee, 0xb5, 0xc1, 0x5b, 0x77, 0x74), - LL(0xaf, 0xaf, 0x86, 0xaf, 0x11, 0x29, 0x43, 0xbe), - LL(0x6a, 0x6a, 0xb5, 0x6a, 0x77, 0xdf, 0xd4, 0x1d), - LL(0x50, 0x50, 0x5d, 0x50, 0xba, 0x0d, 0xa0, 0xea), - LL(0x45, 0x45, 0x09, 0x45, 0x12, 0x4c, 0x8a, 0x57), - LL(0xf3, 0xf3, 0xeb, 0xf3, 0xcb, 0x18, 0xfb, 0x38), - LL(0x30, 0x30, 0xc0, 0x30, 0x9d, 0xf0, 0x60, 0xad), - LL(0xef, 0xef, 0x9b, 0xef, 0x2b, 0x74, 0xc3, 0xc4), - LL(0x3f, 0x3f, 0xfc, 0x3f, 0xe5, 0xc3, 0x7e, 0xda), - LL(0x55, 0x55, 0x49, 0x55, 0x92, 0x1c, 0xaa, 0xc7), - LL(0xa2, 0xa2, 0xb2, 0xa2, 0x79, 0x10, 0x59, 0xdb), - LL(0xea, 0xea, 0x8f, 0xea, 0x03, 0x65, 0xc9, 0xe9), - LL(0x65, 0x65, 0x89, 0x65, 0x0f, 0xec, 0xca, 0x6a), - LL(0xba, 0xba, 0xd2, 0xba, 0xb9, 0x68, 0x69, 0x03), - LL(0x2f, 0x2f, 0xbc, 0x2f, 0x65, 0x93, 0x5e, 0x4a), - LL(0xc0, 0xc0, 0x27, 0xc0, 0x4e, 0xe7, 0x9d, 0x8e), - LL(0xde, 0xde, 0x5f, 0xde, 0xbe, 0x81, 0xa1, 0x60), - LL(0x1c, 0x1c, 0x70, 0x1c, 0xe0, 0x6c, 0x38, 0xfc), - LL(0xfd, 0xfd, 0xd3, 0xfd, 0xbb, 0x2e, 0xe7, 0x46), - LL(0x4d, 0x4d, 0x29, 0x4d, 0x52, 0x64, 0x9a, 0x1f), - LL(0x92, 0x92, 0x72, 0x92, 0xe4, 0xe0, 0x39, 0x76), - LL(0x75, 0x75, 0xc9, 0x75, 0x8f, 0xbc, 0xea, 0xfa), - LL(0x06, 0x06, 0x18, 0x06, 0x30, 0x1e, 0x0c, 0x36), - LL(0x8a, 0x8a, 0x12, 0x8a, 0x24, 0x98, 0x09, 0xae), - LL(0xb2, 0xb2, 0xf2, 0xb2, 0xf9, 0x40, 0x79, 0x4b), - LL(0xe6, 0xe6, 0xbf, 0xe6, 0x63, 0x59, 0xd1, 0x85), - LL(0x0e, 0x0e, 0x38, 0x0e, 0x70, 0x36, 0x1c, 0x7e), - LL(0x1f, 0x1f, 0x7c, 0x1f, 0xf8, 0x63, 0x3e, 0xe7), - LL(0x62, 0x62, 0x95, 0x62, 0x37, 0xf7, 0xc4, 0x55), - LL(0xd4, 0xd4, 0x77, 0xd4, 0xee, 0xa3, 0xb5, 0x3a), - LL(0xa8, 0xa8, 0x9a, 0xa8, 0x29, 0x32, 0x4d, 0x81), - LL(0x96, 0x96, 0x62, 0x96, 0xc4, 0xf4, 0x31, 0x52), - LL(0xf9, 0xf9, 0xc3, 0xf9, 0x9b, 0x3a, 0xef, 0x62), - LL(0xc5, 0xc5, 0x33, 0xc5, 0x66, 0xf6, 0x97, 0xa3), - LL(0x25, 0x25, 0x94, 0x25, 0x35, 0xb1, 0x4a, 0x10), - LL(0x59, 0x59, 0x79, 0x59, 0xf2, 0x20, 0xb2, 0xab), - LL(0x84, 0x84, 0x2a, 0x84, 0x54, 0xae, 0x15, 0xd0), - LL(0x72, 0x72, 0xd5, 0x72, 0xb7, 0xa7, 0xe4, 0xc5), - LL(0x39, 0x39, 0xe4, 0x39, 0xd5, 0xdd, 0x72, 0xec), - LL(0x4c, 0x4c, 0x2d, 0x4c, 0x5a, 0x61, 0x98, 0x16), - LL(0x5e, 0x5e, 0x65, 0x5e, 0xca, 0x3b, 0xbc, 0x94), - LL(0x78, 0x78, 0xfd, 0x78, 0xe7, 0x85, 0xf0, 0x9f), - LL(0x38, 0x38, 0xe0, 0x38, 0xdd, 0xd8, 0x70, 0xe5), - LL(0x8c, 0x8c, 0x0a, 0x8c, 0x14, 0x86, 0x05, 0x98), - LL(0xd1, 0xd1, 0x63, 0xd1, 0xc6, 0xb2, 0xbf, 0x17), - LL(0xa5, 0xa5, 0xae, 0xa5, 0x41, 0x0b, 0x57, 0xe4), - LL(0xe2, 0xe2, 0xaf, 0xe2, 0x43, 0x4d, 0xd9, 0xa1), - LL(0x61, 0x61, 0x99, 0x61, 0x2f, 0xf8, 0xc2, 0x4e), - LL(0xb3, 0xb3, 0xf6, 0xb3, 0xf1, 0x45, 0x7b, 0x42), - LL(0x21, 0x21, 0x84, 0x21, 0x15, 0xa5, 0x42, 0x34), - LL(0x9c, 0x9c, 0x4a, 0x9c, 0x94, 0xd6, 0x25, 0x08), - LL(0x1e, 0x1e, 0x78, 0x1e, 0xf0, 0x66, 0x3c, 0xee), - LL(0x43, 0x43, 0x11, 0x43, 0x22, 0x52, 0x86, 0x61), - LL(0xc7, 0xc7, 0x3b, 0xc7, 0x76, 0xfc, 0x93, 0xb1), - LL(0xfc, 0xfc, 0xd7, 0xfc, 0xb3, 0x2b, 0xe5, 0x4f), - LL(0x04, 0x04, 0x10, 0x04, 0x20, 0x14, 0x08, 0x24), - LL(0x51, 0x51, 0x59, 0x51, 0xb2, 0x08, 0xa2, 0xe3), - LL(0x99, 0x99, 0x5e, 0x99, 0xbc, 0xc7, 0x2f, 0x25), - LL(0x6d, 0x6d, 0xa9, 0x6d, 0x4f, 0xc4, 0xda, 0x22), - LL(0x0d, 0x0d, 0x34, 0x0d, 0x68, 0x39, 0x1a, 0x65), - LL(0xfa, 0xfa, 0xcf, 0xfa, 0x83, 0x35, 0xe9, 0x79), - LL(0xdf, 0xdf, 0x5b, 0xdf, 0xb6, 0x84, 0xa3, 0x69), - LL(0x7e, 0x7e, 0xe5, 0x7e, 0xd7, 0x9b, 0xfc, 0xa9), - LL(0x24, 0x24, 0x90, 0x24, 0x3d, 0xb4, 0x48, 0x19), - LL(0x3b, 0x3b, 0xec, 0x3b, 0xc5, 0xd7, 0x76, 0xfe), - LL(0xab, 0xab, 0x96, 0xab, 0x31, 0x3d, 0x4b, 0x9a), - LL(0xce, 0xce, 0x1f, 0xce, 0x3e, 0xd1, 0x81, 0xf0), - LL(0x11, 0x11, 0x44, 0x11, 0x88, 0x55, 0x22, 0x99), - LL(0x8f, 0x8f, 0x06, 0x8f, 0x0c, 0x89, 0x03, 0x83), - LL(0x4e, 0x4e, 0x25, 0x4e, 0x4a, 0x6b, 0x9c, 0x04), - LL(0xb7, 0xb7, 0xe6, 0xb7, 0xd1, 0x51, 0x73, 0x66), - LL(0xeb, 0xeb, 0x8b, 0xeb, 0x0b, 0x60, 0xcb, 0xe0), - LL(0x3c, 0x3c, 0xf0, 0x3c, 0xfd, 0xcc, 0x78, 0xc1), - LL(0x81, 0x81, 0x3e, 0x81, 0x7c, 0xbf, 0x1f, 0xfd), - LL(0x94, 0x94, 0x6a, 0x94, 0xd4, 0xfe, 0x35, 0x40), - LL(0xf7, 0xf7, 0xfb, 0xf7, 0xeb, 0x0c, 0xf3, 0x1c), - LL(0xb9, 0xb9, 0xde, 0xb9, 0xa1, 0x67, 0x6f, 0x18), - LL(0x13, 0x13, 0x4c, 0x13, 0x98, 0x5f, 0x26, 0x8b), - LL(0x2c, 0x2c, 0xb0, 0x2c, 0x7d, 0x9c, 0x58, 0x51), - LL(0xd3, 0xd3, 0x6b, 0xd3, 0xd6, 0xb8, 0xbb, 0x05), - LL(0xe7, 0xe7, 0xbb, 0xe7, 0x6b, 0x5c, 0xd3, 0x8c), - LL(0x6e, 0x6e, 0xa5, 0x6e, 0x57, 0xcb, 0xdc, 0x39), - LL(0xc4, 0xc4, 0x37, 0xc4, 0x6e, 0xf3, 0x95, 0xaa), - LL(0x03, 0x03, 0x0c, 0x03, 0x18, 0x0f, 0x06, 0x1b), - LL(0x56, 0x56, 0x45, 0x56, 0x8a, 0x13, 0xac, 0xdc), - LL(0x44, 0x44, 0x0d, 0x44, 0x1a, 0x49, 0x88, 0x5e), - LL(0x7f, 0x7f, 0xe1, 0x7f, 0xdf, 0x9e, 0xfe, 0xa0), - LL(0xa9, 0xa9, 0x9e, 0xa9, 0x21, 0x37, 0x4f, 0x88), - LL(0x2a, 0x2a, 0xa8, 0x2a, 0x4d, 0x82, 0x54, 0x67), - LL(0xbb, 0xbb, 0xd6, 0xbb, 0xb1, 0x6d, 0x6b, 0x0a), - LL(0xc1, 0xc1, 0x23, 0xc1, 0x46, 0xe2, 0x9f, 0x87), - LL(0x53, 0x53, 0x51, 0x53, 0xa2, 0x02, 0xa6, 0xf1), - LL(0xdc, 0xdc, 0x57, 0xdc, 0xae, 0x8b, 0xa5, 0x72), - LL(0x0b, 0x0b, 0x2c, 0x0b, 0x58, 0x27, 0x16, 0x53), - LL(0x9d, 0x9d, 0x4e, 0x9d, 0x9c, 0xd3, 0x27, 0x01), - LL(0x6c, 0x6c, 0xad, 0x6c, 0x47, 0xc1, 0xd8, 0x2b), - LL(0x31, 0x31, 0xc4, 0x31, 0x95, 0xf5, 0x62, 0xa4), - LL(0x74, 0x74, 0xcd, 0x74, 0x87, 0xb9, 0xe8, 0xf3), - LL(0xf6, 0xf6, 0xff, 0xf6, 0xe3, 0x09, 0xf1, 0x15), - LL(0x46, 0x46, 0x05, 0x46, 0x0a, 0x43, 0x8c, 0x4c), - LL(0xac, 0xac, 0x8a, 0xac, 0x09, 0x26, 0x45, 0xa5), - LL(0x89, 0x89, 0x1e, 0x89, 0x3c, 0x97, 0x0f, 0xb5), - LL(0x14, 0x14, 0x50, 0x14, 0xa0, 0x44, 0x28, 0xb4), - LL(0xe1, 0xe1, 0xa3, 0xe1, 0x5b, 0x42, 0xdf, 0xba), - LL(0x16, 0x16, 0x58, 0x16, 0xb0, 0x4e, 0x2c, 0xa6), - LL(0x3a, 0x3a, 0xe8, 0x3a, 0xcd, 0xd2, 0x74, 0xf7), - LL(0x69, 0x69, 0xb9, 0x69, 0x6f, 0xd0, 0xd2, 0x06), - LL(0x09, 0x09, 0x24, 0x09, 0x48, 0x2d, 0x12, 0x41), - LL(0x70, 0x70, 0xdd, 0x70, 0xa7, 0xad, 0xe0, 0xd7), - LL(0xb6, 0xb6, 0xe2, 0xb6, 0xd9, 0x54, 0x71, 0x6f), - LL(0xd0, 0xd0, 0x67, 0xd0, 0xce, 0xb7, 0xbd, 0x1e), - LL(0xed, 0xed, 0x93, 0xed, 0x3b, 0x7e, 0xc7, 0xd6), - LL(0xcc, 0xcc, 0x17, 0xcc, 0x2e, 0xdb, 0x85, 0xe2), - LL(0x42, 0x42, 0x15, 0x42, 0x2a, 0x57, 0x84, 0x68), - LL(0x98, 0x98, 0x5a, 0x98, 0xb4, 0xc2, 0x2d, 0x2c), - LL(0xa4, 0xa4, 0xaa, 0xa4, 0x49, 0x0e, 0x55, 0xed), - LL(0x28, 0x28, 0xa0, 0x28, 0x5d, 0x88, 0x50, 0x75), - LL(0x5c, 0x5c, 0x6d, 0x5c, 0xda, 0x31, 0xb8, 0x86), - LL(0xf8, 0xf8, 0xc7, 0xf8, 0x93, 0x3f, 0xed, 0x6b), - LL(0x86, 0x86, 0x22, 0x86, 0x44, 0xa4, 0x11, 0xc2), -#define RC (&(Cx.q[256*N])) - 0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, - /* rc[ROUNDS] */ - 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, 0x60, 0xbc, 0x9b, - 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, - 0xfe, 0x57, 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, - 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, 0xbd, 0x5d, 0x10, 0xf4, - 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, - 0xd8, 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, - 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33 - } - }; - -void whirlpool_block(WHIRLPOOL_CTX *ctx, const void *inp, size_t n) -{ - int r; - const u8 *p = inp; - union { - u64 q[8]; - u8 c[64]; - } S, K, *H = (void *)ctx->H.q; - -#ifdef GO_FOR_MMX - GO_FOR_MMX(ctx, inp, n); -#endif - do { -#ifdef OPENSSL_SMALL_FOOTPRINT - u64 L[8]; - int i; - - for (i = 0; i < 64; i++) - S.c[i] = (K.c[i] = H->c[i]) ^ p[i]; - for (r = 0; r < ROUNDS; r++) { - for (i = 0; i < 8; i++) { - L[i] = i ? 0 : RC[r]; - L[i] ^= C0(K, i) ^ C1(K, (i - 1) & 7) ^ - C2(K, (i - 2) & 7) ^ C3(K, (i - 3) & 7) ^ - C4(K, (i - 4) & 7) ^ C5(K, (i - 5) & 7) ^ - C6(K, (i - 6) & 7) ^ C7(K, (i - 7) & 7); - } - memcpy(K.q, L, 64); - for (i = 0; i < 8; i++) { - L[i] ^= C0(S, i) ^ C1(S, (i - 1) & 7) ^ - C2(S, (i - 2) & 7) ^ C3(S, (i - 3) & 7) ^ - C4(S, (i - 4) & 7) ^ C5(S, (i - 5) & 7) ^ - C6(S, (i - 6) & 7) ^ C7(S, (i - 7) & 7); - } - memcpy(S.q, L, 64); - } - for (i = 0; i < 64; i++) - H->c[i] ^= S.c[i] ^ p[i]; -#else - u64 L0, L1, L2, L3, L4, L5, L6, L7; - -# ifdef STRICT_ALIGNMENT - if ((size_t)p & 7) { - memcpy(S.c, p, 64); - S.q[0] ^= (K.q[0] = H->q[0]); - S.q[1] ^= (K.q[1] = H->q[1]); - S.q[2] ^= (K.q[2] = H->q[2]); - S.q[3] ^= (K.q[3] = H->q[3]); - S.q[4] ^= (K.q[4] = H->q[4]); - S.q[5] ^= (K.q[5] = H->q[5]); - S.q[6] ^= (K.q[6] = H->q[6]); - S.q[7] ^= (K.q[7] = H->q[7]); - } else -# endif - { - const u64 *pa = (const u64 *)p; - S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; - S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; - S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; - S.q[3] = (K.q[3] = H->q[3]) ^ pa[3]; - S.q[4] = (K.q[4] = H->q[4]) ^ pa[4]; - S.q[5] = (K.q[5] = H->q[5]) ^ pa[5]; - S.q[6] = (K.q[6] = H->q[6]) ^ pa[6]; - S.q[7] = (K.q[7] = H->q[7]) ^ pa[7]; - } - - for (r = 0; r < ROUNDS; r++) { -# ifdef SMALL_REGISTER_BANK - L0 = C0(K, 0) ^ C1(K, 7) ^ C2(K, 6) ^ C3(K, 5) ^ - C4(K, 4) ^ C5(K, 3) ^ C6(K, 2) ^ C7(K, 1) ^ RC[r]; - L1 = C0(K, 1) ^ C1(K, 0) ^ C2(K, 7) ^ C3(K, 6) ^ - C4(K, 5) ^ C5(K, 4) ^ C6(K, 3) ^ C7(K, 2); - L2 = C0(K, 2) ^ C1(K, 1) ^ C2(K, 0) ^ C3(K, 7) ^ - C4(K, 6) ^ C5(K, 5) ^ C6(K, 4) ^ C7(K, 3); - L3 = C0(K, 3) ^ C1(K, 2) ^ C2(K, 1) ^ C3(K, 0) ^ - C4(K, 7) ^ C5(K, 6) ^ C6(K, 5) ^ C7(K, 4); - L4 = C0(K, 4) ^ C1(K, 3) ^ C2(K, 2) ^ C3(K, 1) ^ - C4(K, 0) ^ C5(K, 7) ^ C6(K, 6) ^ C7(K, 5); - L5 = C0(K, 5) ^ C1(K, 4) ^ C2(K, 3) ^ C3(K, 2) ^ - C4(K, 1) ^ C5(K, 0) ^ C6(K, 7) ^ C7(K, 6); - L6 = C0(K, 6) ^ C1(K, 5) ^ C2(K, 4) ^ C3(K, 3) ^ - C4(K, 2) ^ C5(K, 1) ^ C6(K, 0) ^ C7(K, 7); - L7 = C0(K, 7) ^ C1(K, 6) ^ C2(K, 5) ^ C3(K, 4) ^ - C4(K, 3) ^ C5(K, 2) ^ C6(K, 1) ^ C7(K, 0); - - K.q[0] = L0; - K.q[1] = L1; - K.q[2] = L2; - K.q[3] = L3; - K.q[4] = L4; - K.q[5] = L5; - K.q[6] = L6; - K.q[7] = L7; - - L0 ^= C0(S, 0) ^ C1(S, 7) ^ C2(S, 6) ^ C3(S, 5) ^ - C4(S, 4) ^ C5(S, 3) ^ C6(S, 2) ^ C7(S, 1); - L1 ^= C0(S, 1) ^ C1(S, 0) ^ C2(S, 7) ^ C3(S, 6) ^ - C4(S, 5) ^ C5(S, 4) ^ C6(S, 3) ^ C7(S, 2); - L2 ^= C0(S, 2) ^ C1(S, 1) ^ C2(S, 0) ^ C3(S, 7) ^ - C4(S, 6) ^ C5(S, 5) ^ C6(S, 4) ^ C7(S, 3); - L3 ^= C0(S, 3) ^ C1(S, 2) ^ C2(S, 1) ^ C3(S, 0) ^ - C4(S, 7) ^ C5(S, 6) ^ C6(S, 5) ^ C7(S, 4); - L4 ^= C0(S, 4) ^ C1(S, 3) ^ C2(S, 2) ^ C3(S, 1) ^ - C4(S, 0) ^ C5(S, 7) ^ C6(S, 6) ^ C7(S, 5); - L5 ^= C0(S, 5) ^ C1(S, 4) ^ C2(S, 3) ^ C3(S, 2) ^ - C4(S, 1) ^ C5(S, 0) ^ C6(S, 7) ^ C7(S, 6); - L6 ^= C0(S, 6) ^ C1(S, 5) ^ C2(S, 4) ^ C3(S, 3) ^ - C4(S, 2) ^ C5(S, 1) ^ C6(S, 0) ^ C7(S, 7); - L7 ^= C0(S, 7) ^ C1(S, 6) ^ C2(S, 5) ^ C3(S, 4) ^ - C4(S, 3) ^ C5(S, 2) ^ C6(S, 1) ^ C7(S, 0); - - S.q[0] = L0; - S.q[1] = L1; - S.q[2] = L2; - S.q[3] = L3; - S.q[4] = L4; - S.q[5] = L5; - S.q[6] = L6; - S.q[7] = L7; -# else - L0 = C0(K, 0); - L1 = C1(K, 0); - L2 = C2(K, 0); - L3 = C3(K, 0); - L4 = C4(K, 0); - L5 = C5(K, 0); - L6 = C6(K, 0); - L7 = C7(K, 0); - L0 ^= RC[r]; - - L1 ^= C0(K, 1); - L2 ^= C1(K, 1); - L3 ^= C2(K, 1); - L4 ^= C3(K, 1); - L5 ^= C4(K, 1); - L6 ^= C5(K, 1); - L7 ^= C6(K, 1); - L0 ^= C7(K, 1); - - L2 ^= C0(K, 2); - L3 ^= C1(K, 2); - L4 ^= C2(K, 2); - L5 ^= C3(K, 2); - L6 ^= C4(K, 2); - L7 ^= C5(K, 2); - L0 ^= C6(K, 2); - L1 ^= C7(K, 2); - - L3 ^= C0(K, 3); - L4 ^= C1(K, 3); - L5 ^= C2(K, 3); - L6 ^= C3(K, 3); - L7 ^= C4(K, 3); - L0 ^= C5(K, 3); - L1 ^= C6(K, 3); - L2 ^= C7(K, 3); - - L4 ^= C0(K, 4); - L5 ^= C1(K, 4); - L6 ^= C2(K, 4); - L7 ^= C3(K, 4); - L0 ^= C4(K, 4); - L1 ^= C5(K, 4); - L2 ^= C6(K, 4); - L3 ^= C7(K, 4); - - L5 ^= C0(K, 5); - L6 ^= C1(K, 5); - L7 ^= C2(K, 5); - L0 ^= C3(K, 5); - L1 ^= C4(K, 5); - L2 ^= C5(K, 5); - L3 ^= C6(K, 5); - L4 ^= C7(K, 5); - - L6 ^= C0(K, 6); - L7 ^= C1(K, 6); - L0 ^= C2(K, 6); - L1 ^= C3(K, 6); - L2 ^= C4(K, 6); - L3 ^= C5(K, 6); - L4 ^= C6(K, 6); - L5 ^= C7(K, 6); - - L7 ^= C0(K, 7); - L0 ^= C1(K, 7); - L1 ^= C2(K, 7); - L2 ^= C3(K, 7); - L3 ^= C4(K, 7); - L4 ^= C5(K, 7); - L5 ^= C6(K, 7); - L6 ^= C7(K, 7); - - K.q[0] = L0; - K.q[1] = L1; - K.q[2] = L2; - K.q[3] = L3; - K.q[4] = L4; - K.q[5] = L5; - K.q[6] = L6; - K.q[7] = L7; - - L0 ^= C0(S, 0); - L1 ^= C1(S, 0); - L2 ^= C2(S, 0); - L3 ^= C3(S, 0); - L4 ^= C4(S, 0); - L5 ^= C5(S, 0); - L6 ^= C6(S, 0); - L7 ^= C7(S, 0); - - L1 ^= C0(S, 1); - L2 ^= C1(S, 1); - L3 ^= C2(S, 1); - L4 ^= C3(S, 1); - L5 ^= C4(S, 1); - L6 ^= C5(S, 1); - L7 ^= C6(S, 1); - L0 ^= C7(S, 1); - - L2 ^= C0(S, 2); - L3 ^= C1(S, 2); - L4 ^= C2(S, 2); - L5 ^= C3(S, 2); - L6 ^= C4(S, 2); - L7 ^= C5(S, 2); - L0 ^= C6(S, 2); - L1 ^= C7(S, 2); - - L3 ^= C0(S, 3); - L4 ^= C1(S, 3); - L5 ^= C2(S, 3); - L6 ^= C3(S, 3); - L7 ^= C4(S, 3); - L0 ^= C5(S, 3); - L1 ^= C6(S, 3); - L2 ^= C7(S, 3); - - L4 ^= C0(S, 4); - L5 ^= C1(S, 4); - L6 ^= C2(S, 4); - L7 ^= C3(S, 4); - L0 ^= C4(S, 4); - L1 ^= C5(S, 4); - L2 ^= C6(S, 4); - L3 ^= C7(S, 4); - - L5 ^= C0(S, 5); - L6 ^= C1(S, 5); - L7 ^= C2(S, 5); - L0 ^= C3(S, 5); - L1 ^= C4(S, 5); - L2 ^= C5(S, 5); - L3 ^= C6(S, 5); - L4 ^= C7(S, 5); - - L6 ^= C0(S, 6); - L7 ^= C1(S, 6); - L0 ^= C2(S, 6); - L1 ^= C3(S, 6); - L2 ^= C4(S, 6); - L3 ^= C5(S, 6); - L4 ^= C6(S, 6); - L5 ^= C7(S, 6); - - L7 ^= C0(S, 7); - L0 ^= C1(S, 7); - L1 ^= C2(S, 7); - L2 ^= C3(S, 7); - L3 ^= C4(S, 7); - L4 ^= C5(S, 7); - L5 ^= C6(S, 7); - L6 ^= C7(S, 7); - - S.q[0] = L0; - S.q[1] = L1; - S.q[2] = L2; - S.q[3] = L3; - S.q[4] = L4; - S.q[5] = L5; - S.q[6] = L6; - S.q[7] = L7; -# endif - } - -# ifdef STRICT_ALIGNMENT - if ((size_t)p & 7) { - int i; - for (i = 0; i < 64; i++) - H->c[i] ^= S.c[i] ^ p[i]; - } else -# endif - { - const u64 *pa = (const u64 *)p; - H->q[0] ^= S.q[0] ^ pa[0]; - H->q[1] ^= S.q[1] ^ pa[1]; - H->q[2] ^= S.q[2] ^ pa[2]; - H->q[3] ^= S.q[3] ^ pa[3]; - H->q[4] ^= S.q[4] ^ pa[4]; - H->q[5] ^= S.q[5] ^ pa[5]; - H->q[6] ^= S.q[6] ^ pa[6]; - H->q[7] ^= S.q[7] ^ pa[7]; - } -#endif - p += 64; - } while (--n); -} -/** - * The Whirlpool hashing function. - * - *

- * References - * - *

- * The Whirlpool algorithm was developed by - * Paulo S. L. M. Barreto and - * Vincent Rijmen. - * - * See - * P.S.L.M. Barreto, V. Rijmen, - * ``The Whirlpool hashing function,'' - * NESSIE submission, 2000 (tweaked version, 2001), - * - * - * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and - * Vincent Rijmen. Lookup "reference implementations" on - * - * - * ============================================================================= - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * OpenSSL-specific implementation notes. - * - * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect - * number of *bytes* as input length argument. Bit-oriented routine - * as specified by authors is called WHIRLPOOL_BitUpdate[!] and - * does not have one-stroke counterpart. - * - * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially - * to serve WHIRLPOOL_Update. This is done for performance. - * - * Unlike authors' reference implementation, block processing - * routine whirlpool_block is designed to operate on multi-block - * input. This is done for perfomance. - */ - -#include "crypto.h" -// #include "wp_locl.h" -// #include "crypto.h" -#include - -fips_md_init(WHIRLPOOL) -{ - memset(c, 0, sizeof(*c)); - return (1); -} - -int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes) -{ - /* - * Well, largest suitable chunk size actually is - * (1<<(sizeof(size_t)*8-3))-64, but below number is large enough for not - * to care about excessive calls to WHIRLPOOL_BitUpdate... - */ - size_t chunk = ((size_t)1) << (sizeof(size_t) * 8 - 4); - const unsigned char *inp = _inp; - - while (bytes >= chunk) { - WHIRLPOOL_BitUpdate(c, inp, chunk * 8); - bytes -= chunk; - inp += chunk; - } - if (bytes) - WHIRLPOOL_BitUpdate(c, inp, bytes * 8); - - return (1); -} - -void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) -{ - size_t n; - unsigned int bitoff = c->bitoff, - bitrem = bitoff % 8, inpgap = (8 - (unsigned int)bits % 8) & 7; - const unsigned char *inp = _inp; - - /* - * This 256-bit increment procedure relies on the size_t being natural - * size of CPU register, so that we don't have to mask the value in order - * to detect overflows. - */ - c->bitlen[0] += bits; - if (c->bitlen[0] < bits) { /* overflow */ - n = 1; - do { - c->bitlen[n]++; - } while (c->bitlen[n] == 0 - && ++n < (WHIRLPOOL_COUNTER / sizeof(size_t))); - } -#ifndef OPENSSL_SMALL_FOOTPRINT - reconsider: - if (inpgap == 0 && bitrem == 0) { /* byte-oriented loop */ - while (bits) { - if (bitoff == 0 && (n = bits / WHIRLPOOL_BBLOCK)) { - whirlpool_block(c, inp, n); - inp += n * WHIRLPOOL_BBLOCK / 8; - bits %= WHIRLPOOL_BBLOCK; - } else { - unsigned int byteoff = bitoff / 8; - - bitrem = WHIRLPOOL_BBLOCK - bitoff; /* re-use bitrem */ - if (bits >= bitrem) { - bits -= bitrem; - bitrem /= 8; - memcpy(c->data + byteoff, inp, bitrem); - inp += bitrem; - whirlpool_block(c, c->data, 1); - bitoff = 0; - } else { - memcpy(c->data + byteoff, inp, bits / 8); - bitoff += (unsigned int)bits; - bits = 0; - } - c->bitoff = bitoff; - } - } - } else /* bit-oriented loop */ -#endif - { - /*- - inp - | - +-------+-------+------- - ||||||||||||||||||||| - +-------+-------+------- - +-------+-------+-------+-------+------- - |||||||||||||| c->data - +-------+-------+-------+-------+------- - | - c->bitoff/8 - */ - while (bits) { - unsigned int byteoff = bitoff / 8; - unsigned char b; - -#ifndef OPENSSL_SMALL_FOOTPRINT - if (bitrem == inpgap) { - c->data[byteoff++] |= inp[0] & (0xff >> inpgap); - inpgap = 8 - inpgap; - bitoff += inpgap; - bitrem = 0; /* bitoff%8 */ - bits -= inpgap; - inpgap = 0; /* bits%8 */ - inp++; - if (bitoff == WHIRLPOOL_BBLOCK) { - whirlpool_block(c, c->data, 1); - bitoff = 0; - } - c->bitoff = bitoff; - goto reconsider; - } else -#endif - if (bits > 8) { - b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap))); - b &= 0xff; - if (bitrem) - c->data[byteoff++] |= b >> bitrem; - else - c->data[byteoff++] = b; - bitoff += 8; - bits -= 8; - inp++; - if (bitoff >= WHIRLPOOL_BBLOCK) { - whirlpool_block(c, c->data, 1); - byteoff = 0; - bitoff %= WHIRLPOOL_BBLOCK; - } - if (bitrem) - c->data[byteoff] = b << (8 - bitrem); - } else { /* remaining less than or equal to 8 bits */ - - b = (inp[0] << inpgap) & 0xff; - if (bitrem) - c->data[byteoff++] |= b >> bitrem; - else - c->data[byteoff++] = b; - bitoff += (unsigned int)bits; - if (bitoff == WHIRLPOOL_BBLOCK) { - whirlpool_block(c, c->data, 1); - byteoff = 0; - bitoff %= WHIRLPOOL_BBLOCK; - } - if (bitrem) - c->data[byteoff] = b << (8 - bitrem); - bits = 0; - } - c->bitoff = bitoff; - } - } -} - -int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c) -{ - unsigned int bitoff = c->bitoff, byteoff = bitoff / 8; - size_t i, j, v; - unsigned char *p; - - bitoff %= 8; - if (bitoff) - c->data[byteoff] |= 0x80 >> bitoff; - else - c->data[byteoff] = 0x80; - byteoff++; - - /* pad with zeros */ - if (byteoff > (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) { - if (byteoff < WHIRLPOOL_BBLOCK / 8) - memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK / 8 - byteoff); - whirlpool_block(c, c->data, 1); - byteoff = 0; - } - if (byteoff < (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) - memset(&c->data[byteoff], 0, - (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER) - byteoff); - /* smash 256-bit c->bitlen in big-endian order */ - p = &c->data[WHIRLPOOL_BBLOCK / 8 - 1]; /* last byte in c->data */ - for (i = 0; i < WHIRLPOOL_COUNTER / sizeof(size_t); i++) - for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8) - *p-- = (unsigned char)(v & 0xff); - - whirlpool_block(c, c->data, 1); - - if (md) { - memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH); - OPENSSL_cleanse(c, sizeof(*c)); - return (1); - } - return (0); -} - -unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md) -{ - WHIRLPOOL_CTX ctx; - static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; - - if (md == NULL) - md = m; - WHIRLPOOL_Init(&ctx); - WHIRLPOOL_Update(&ctx, inp, bytes); - WHIRLPOOL_Final(md, &ctx); - return (md); -} diff --git a/Sources/COpenSSL/wp_locl.h b/Sources/COpenSSL/wp_locl.h deleted file mode 100644 index 3017e2db..00000000 --- a/Sources/COpenSSL/wp_locl.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "whrlpool.h" - -void whirlpool_block(WHIRLPOOL_CTX *, const void *, size_t); diff --git a/Sources/COpenSSL/wrap128.c b/Sources/COpenSSL/wrap128.c deleted file mode 100644 index 8ed6da3d..00000000 --- a/Sources/COpenSSL/wrap128.c +++ /dev/null @@ -1,138 +0,0 @@ -/* crypto/modes/wrap128.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL - * project. - */ -/* ==================================================================== - * Copyright (c) 2013 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "cryptlib.h" -#include "modes.h" - -static const unsigned char default_iv[] = { - 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, -}; - -/* - * Input size limit: lower than maximum of standards but far larger than - * anything that will be used in practice. - */ -#define CRYPTO128_WRAP_MAX (1UL << 31) - -size_t CRYPTO_128_wrap(void *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, size_t inlen, - block128_f block) -{ - unsigned char *A, B[16], *R; - size_t i, j, t; - if ((inlen & 0x7) || (inlen < 8) || (inlen > CRYPTO128_WRAP_MAX)) - return 0; - A = B; - t = 1; - memmove(out + 8, in, inlen); - if (!iv) - iv = default_iv; - - memcpy(A, iv, 8); - - for (j = 0; j < 6; j++) { - R = out + 8; - for (i = 0; i < inlen; i += 8, t++, R += 8) { - memcpy(B + 8, R, 8); - block(B, B, key); - A[7] ^= (unsigned char)(t & 0xff); - if (t > 0xff) { - A[6] ^= (unsigned char)((t >> 8) & 0xff); - A[5] ^= (unsigned char)((t >> 16) & 0xff); - A[4] ^= (unsigned char)((t >> 24) & 0xff); - } - memcpy(R, B + 8, 8); - } - } - memcpy(out, A, 8); - return inlen + 8; -} - -size_t CRYPTO_128_unwrap(void *key, const unsigned char *iv, - unsigned char *out, - const unsigned char *in, size_t inlen, - block128_f block) -{ - unsigned char *A, B[16], *R; - size_t i, j, t; - inlen -= 8; - if ((inlen & 0x7) || (inlen < 16) || (inlen > CRYPTO128_WRAP_MAX)) - return 0; - A = B; - t = 6 * (inlen >> 3); - memcpy(A, in, 8); - memmove(out, in + 8, inlen); - for (j = 0; j < 6; j++) { - R = out + inlen - 8; - for (i = 0; i < inlen; i += 8, t--, R -= 8) { - A[7] ^= (unsigned char)(t & 0xff); - if (t > 0xff) { - A[6] ^= (unsigned char)((t >> 8) & 0xff); - A[5] ^= (unsigned char)((t >> 16) & 0xff); - A[4] ^= (unsigned char)((t >> 24) & 0xff); - } - memcpy(B + 8, R, 8); - block(B, B, key); - memcpy(R, B + 8, 8); - } - } - if (!iv) - iv = default_iv; - if (memcmp(A, iv, 8)) { - OPENSSL_cleanse(out, inlen); - return 0; - } - return inlen; -} diff --git a/Sources/COpenSSL/x509.h b/Sources/COpenSSL/x509.h deleted file mode 100644 index 46eda8fa..00000000 --- a/Sources/COpenSSL/x509.h +++ /dev/null @@ -1,1330 +0,0 @@ -/* crypto/x509/x509.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ -/* ==================================================================== - * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. - * ECDH support in OpenSSL originally developed by - * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. - */ - -#ifndef HEADER_X509_H -# define HEADER_X509_H - -# include "e_os2.h" -# include "symhacks.h" -# ifndef OPENSSL_NO_BUFFER -# include "buffer.h" -# endif -# ifndef OPENSSL_NO_EVP -# include "evp.h" -# endif -# ifndef OPENSSL_NO_BIO -# include "bio.h" -# endif -# include "stack.h" -# include "asn1.h" -# include "safestack.h" - -# ifndef OPENSSL_NO_EC -# include "ec.h" -# endif - -# ifndef OPENSSL_NO_ECDSA -# include "ecdsa.h" -# endif - -# ifndef OPENSSL_NO_ECDH -# include "ecdh.h" -# endif - -# ifndef OPENSSL_NO_DEPRECATED -# ifndef OPENSSL_NO_RSA -# include "rsa.h" -# endif -# ifndef OPENSSL_NO_DSA -# include "dsa.h" -# endif -# ifndef OPENSSL_NO_DH -# include "dh.h" -# endif -# endif - -# ifndef OPENSSL_NO_SHA -# include "sha.h" -# endif -# include "ossl_typ.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef OPENSSL_SYS_WIN32 -/* Under Win32 these are defined in wincrypt.h */ -# undef X509_NAME -# undef X509_CERT_PAIR -# undef X509_EXTENSIONS -# endif - -# define X509_FILETYPE_PEM 1 -# define X509_FILETYPE_ASN1 2 -# define X509_FILETYPE_DEFAULT 3 - -# define X509v3_KU_DIGITAL_SIGNATURE 0x0080 -# define X509v3_KU_NON_REPUDIATION 0x0040 -# define X509v3_KU_KEY_ENCIPHERMENT 0x0020 -# define X509v3_KU_DATA_ENCIPHERMENT 0x0010 -# define X509v3_KU_KEY_AGREEMENT 0x0008 -# define X509v3_KU_KEY_CERT_SIGN 0x0004 -# define X509v3_KU_CRL_SIGN 0x0002 -# define X509v3_KU_ENCIPHER_ONLY 0x0001 -# define X509v3_KU_DECIPHER_ONLY 0x8000 -# define X509v3_KU_UNDEF 0xffff - -typedef struct X509_objects_st { - int nid; - int (*a2i) (void); - int (*i2a) (void); -} X509_OBJECTS; - -struct X509_algor_st { - ASN1_OBJECT *algorithm; - ASN1_TYPE *parameter; -} /* X509_ALGOR */ ; - -DECLARE_ASN1_SET_OF(X509_ALGOR) - -typedef STACK_OF(X509_ALGOR) X509_ALGORS; - -typedef struct X509_val_st { - ASN1_TIME *notBefore; - ASN1_TIME *notAfter; -} X509_VAL; - -struct X509_pubkey_st { - X509_ALGOR *algor; - ASN1_BIT_STRING *public_key; - EVP_PKEY *pkey; -}; - -typedef struct X509_sig_st { - X509_ALGOR *algor; - ASN1_OCTET_STRING *digest; -} X509_SIG; - -typedef struct X509_name_entry_st { - ASN1_OBJECT *object; - ASN1_STRING *value; - int set; - int size; /* temp variable */ -} X509_NAME_ENTRY; - -DECLARE_STACK_OF(X509_NAME_ENTRY) -DECLARE_ASN1_SET_OF(X509_NAME_ENTRY) - -/* we always keep X509_NAMEs in 2 forms. */ -struct X509_name_st { - STACK_OF(X509_NAME_ENTRY) *entries; - int modified; /* true if 'bytes' needs to be built */ -# ifndef OPENSSL_NO_BUFFER - BUF_MEM *bytes; -# else - char *bytes; -# endif -/* unsigned long hash; Keep the hash around for lookups */ - unsigned char *canon_enc; - int canon_enclen; -} /* X509_NAME */ ; - -DECLARE_STACK_OF(X509_NAME) - -# define X509_EX_V_NETSCAPE_HACK 0x8000 -# define X509_EX_V_INIT 0x0001 -typedef struct X509_extension_st { - ASN1_OBJECT *object; - ASN1_BOOLEAN critical; - ASN1_OCTET_STRING *value; -} X509_EXTENSION; - -typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; - -DECLARE_STACK_OF(X509_EXTENSION) -DECLARE_ASN1_SET_OF(X509_EXTENSION) - -/* a sequence of these are used */ -typedef struct x509_attributes_st { - ASN1_OBJECT *object; - int single; /* 0 for a set, 1 for a single item (which is - * wrong) */ - union { - char *ptr; - /* - * 0 - */ STACK_OF(ASN1_TYPE) *set; - /* - * 1 - */ ASN1_TYPE *single; - } value; -} X509_ATTRIBUTE; - -DECLARE_STACK_OF(X509_ATTRIBUTE) -DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) - -typedef struct X509_req_info_st { - ASN1_ENCODING enc; - ASN1_INTEGER *version; - X509_NAME *subject; - X509_PUBKEY *pubkey; - /* d=2 hl=2 l= 0 cons: cont: 00 */ - STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ -} X509_REQ_INFO; - -typedef struct X509_req_st { - X509_REQ_INFO *req_info; - X509_ALGOR *sig_alg; - ASN1_BIT_STRING *signature; - int references; -} X509_REQ; - -typedef struct x509_cinf_st { - ASN1_INTEGER *version; /* [ 0 ] default of v1 */ - ASN1_INTEGER *serialNumber; - X509_ALGOR *signature; - X509_NAME *issuer; - X509_VAL *validity; - X509_NAME *subject; - X509_PUBKEY *key; - ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */ - ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */ - STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */ - ASN1_ENCODING enc; -} X509_CINF; - -/* - * This stuff is certificate "auxiliary info" it contains details which are - * useful in certificate stores and databases. When used this is tagged onto - * the end of the certificate itself - */ - -typedef struct x509_cert_aux_st { - STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */ - STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */ - ASN1_UTF8STRING *alias; /* "friendly name" */ - ASN1_OCTET_STRING *keyid; /* key id of private key */ - STACK_OF(X509_ALGOR) *other; /* other unspecified info */ -} X509_CERT_AUX; - -struct x509_st { - X509_CINF *cert_info; - X509_ALGOR *sig_alg; - ASN1_BIT_STRING *signature; - int valid; - int references; - char *name; - CRYPTO_EX_DATA ex_data; - /* These contain copies of various extension values */ - long ex_pathlen; - long ex_pcpathlen; - unsigned long ex_flags; - unsigned long ex_kusage; - unsigned long ex_xkusage; - unsigned long ex_nscert; - ASN1_OCTET_STRING *skid; - AUTHORITY_KEYID *akid; - X509_POLICY_CACHE *policy_cache; - STACK_OF(DIST_POINT) *crldp; - STACK_OF(GENERAL_NAME) *altname; - NAME_CONSTRAINTS *nc; -# ifndef OPENSSL_NO_RFC3779 - STACK_OF(IPAddressFamily) *rfc3779_addr; - struct ASIdentifiers_st *rfc3779_asid; -# endif -# ifndef OPENSSL_NO_SHA - unsigned char sha1_hash[SHA_DIGEST_LENGTH]; -# endif - X509_CERT_AUX *aux; -} /* X509 */ ; - -DECLARE_STACK_OF(X509) -DECLARE_ASN1_SET_OF(X509) - -/* This is used for a table of trust checking functions */ - -typedef struct x509_trust_st { - int trust; - int flags; - int (*check_trust) (struct x509_trust_st *, X509 *, int); - char *name; - int arg1; - void *arg2; -} X509_TRUST; - -DECLARE_STACK_OF(X509_TRUST) - -typedef struct x509_cert_pair_st { - X509 *forward; - X509 *reverse; -} X509_CERT_PAIR; - -/* standard trust ids */ - -# define X509_TRUST_DEFAULT -1/* Only valid in purpose settings */ - -# define X509_TRUST_COMPAT 1 -# define X509_TRUST_SSL_CLIENT 2 -# define X509_TRUST_SSL_SERVER 3 -# define X509_TRUST_EMAIL 4 -# define X509_TRUST_OBJECT_SIGN 5 -# define X509_TRUST_OCSP_SIGN 6 -# define X509_TRUST_OCSP_REQUEST 7 -# define X509_TRUST_TSA 8 - -/* Keep these up to date! */ -# define X509_TRUST_MIN 1 -# define X509_TRUST_MAX 8 - -/* trust_flags values */ -# define X509_TRUST_DYNAMIC 1 -# define X509_TRUST_DYNAMIC_NAME 2 - -/* check_trust return codes */ - -# define X509_TRUST_TRUSTED 1 -# define X509_TRUST_REJECTED 2 -# define X509_TRUST_UNTRUSTED 3 - -/* Flags for X509_print_ex() */ - -# define X509_FLAG_COMPAT 0 -# define X509_FLAG_NO_HEADER 1L -# define X509_FLAG_NO_VERSION (1L << 1) -# define X509_FLAG_NO_SERIAL (1L << 2) -# define X509_FLAG_NO_SIGNAME (1L << 3) -# define X509_FLAG_NO_ISSUER (1L << 4) -# define X509_FLAG_NO_VALIDITY (1L << 5) -# define X509_FLAG_NO_SUBJECT (1L << 6) -# define X509_FLAG_NO_PUBKEY (1L << 7) -# define X509_FLAG_NO_EXTENSIONS (1L << 8) -# define X509_FLAG_NO_SIGDUMP (1L << 9) -# define X509_FLAG_NO_AUX (1L << 10) -# define X509_FLAG_NO_ATTRIBUTES (1L << 11) -# define X509_FLAG_NO_IDS (1L << 12) - -/* Flags specific to X509_NAME_print_ex() */ - -/* The field separator information */ - -# define XN_FLAG_SEP_MASK (0xf << 16) - -# define XN_FLAG_COMPAT 0/* Traditional SSLeay: use old - * X509_NAME_print */ -# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */ -# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */ -# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */ -# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */ - -# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */ - -/* How the field name is shown */ - -# define XN_FLAG_FN_MASK (0x3 << 21) - -# define XN_FLAG_FN_SN 0/* Object short name */ -# define XN_FLAG_FN_LN (1 << 21)/* Object long name */ -# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */ -# define XN_FLAG_FN_NONE (3 << 21)/* No field names */ - -# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */ - -/* - * This determines if we dump fields we don't recognise: RFC2253 requires - * this. - */ - -# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) - -# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20 - * characters */ - -/* Complete set of RFC2253 flags */ - -# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ - XN_FLAG_SEP_COMMA_PLUS | \ - XN_FLAG_DN_REV | \ - XN_FLAG_FN_SN | \ - XN_FLAG_DUMP_UNKNOWN_FIELDS) - -/* readable oneline form */ - -# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ - ASN1_STRFLGS_ESC_QUOTE | \ - XN_FLAG_SEP_CPLUS_SPC | \ - XN_FLAG_SPC_EQ | \ - XN_FLAG_FN_SN) - -/* readable multiline form */ - -# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ - ASN1_STRFLGS_ESC_MSB | \ - XN_FLAG_SEP_MULTILINE | \ - XN_FLAG_SPC_EQ | \ - XN_FLAG_FN_LN | \ - XN_FLAG_FN_ALIGN) - -struct x509_revoked_st { - ASN1_INTEGER *serialNumber; - ASN1_TIME *revocationDate; - STACK_OF(X509_EXTENSION) /* optional */ *extensions; - /* Set up if indirect CRL */ - STACK_OF(GENERAL_NAME) *issuer; - /* Revocation reason */ - int reason; - int sequence; /* load sequence */ -}; - -DECLARE_STACK_OF(X509_REVOKED) -DECLARE_ASN1_SET_OF(X509_REVOKED) - -typedef struct X509_crl_info_st { - ASN1_INTEGER *version; - X509_ALGOR *sig_alg; - X509_NAME *issuer; - ASN1_TIME *lastUpdate; - ASN1_TIME *nextUpdate; - STACK_OF(X509_REVOKED) *revoked; - STACK_OF(X509_EXTENSION) /* [0] */ *extensions; - ASN1_ENCODING enc; -} X509_CRL_INFO; - -struct X509_crl_st { - /* actual signature */ - X509_CRL_INFO *crl; - X509_ALGOR *sig_alg; - ASN1_BIT_STRING *signature; - int references; - int flags; - /* Copies of various extensions */ - AUTHORITY_KEYID *akid; - ISSUING_DIST_POINT *idp; - /* Convenient breakdown of IDP */ - int idp_flags; - int idp_reasons; - /* CRL and base CRL numbers for delta processing */ - ASN1_INTEGER *crl_number; - ASN1_INTEGER *base_crl_number; -# ifndef OPENSSL_NO_SHA - unsigned char sha1_hash[SHA_DIGEST_LENGTH]; -# endif - STACK_OF(GENERAL_NAMES) *issuers; - const X509_CRL_METHOD *meth; - void *meth_data; -} /* X509_CRL */ ; - -DECLARE_STACK_OF(X509_CRL) -DECLARE_ASN1_SET_OF(X509_CRL) - -typedef struct private_key_st { - int version; - /* The PKCS#8 data types */ - X509_ALGOR *enc_algor; - ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ - /* When decrypted, the following will not be NULL */ - EVP_PKEY *dec_pkey; - /* used to encrypt and decrypt */ - int key_length; - char *key_data; - int key_free; /* true if we should auto free key_data */ - /* expanded version of 'enc_algor' */ - EVP_CIPHER_INFO cipher; - int references; -} X509_PKEY; - -# ifndef OPENSSL_NO_EVP -typedef struct X509_info_st { - X509 *x509; - X509_CRL *crl; - X509_PKEY *x_pkey; - EVP_CIPHER_INFO enc_cipher; - int enc_len; - char *enc_data; - int references; -} X509_INFO; - -DECLARE_STACK_OF(X509_INFO) -# endif - -/* - * The next 2 structures and their 8 routines were sent to me by Pat Richard - * and are used to manipulate Netscapes spki structures - - * useful if you are writing a CA web page - */ -typedef struct Netscape_spkac_st { - X509_PUBKEY *pubkey; - ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ -} NETSCAPE_SPKAC; - -typedef struct Netscape_spki_st { - NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ - X509_ALGOR *sig_algor; - ASN1_BIT_STRING *signature; -} NETSCAPE_SPKI; - -/* Netscape certificate sequence structure */ -typedef struct Netscape_certificate_sequence { - ASN1_OBJECT *type; - STACK_OF(X509) *certs; -} NETSCAPE_CERT_SEQUENCE; - -/*- Unused (and iv length is wrong) -typedef struct CBCParameter_st - { - unsigned char iv[8]; - } CBC_PARAM; -*/ - -/* Password based encryption structure */ - -typedef struct PBEPARAM_st { - ASN1_OCTET_STRING *salt; - ASN1_INTEGER *iter; -} PBEPARAM; - -/* Password based encryption V2 structures */ - -typedef struct PBE2PARAM_st { - X509_ALGOR *keyfunc; - X509_ALGOR *encryption; -} PBE2PARAM; - -typedef struct PBKDF2PARAM_st { -/* Usually OCTET STRING but could be anything */ - ASN1_TYPE *salt; - ASN1_INTEGER *iter; - ASN1_INTEGER *keylength; - X509_ALGOR *prf; -} PBKDF2PARAM; - -/* PKCS#8 private key info structure */ - -struct pkcs8_priv_key_info_st { - /* Flag for various broken formats */ - int broken; -# define PKCS8_OK 0 -# define PKCS8_NO_OCTET 1 -# define PKCS8_EMBEDDED_PARAM 2 -# define PKCS8_NS_DB 3 -# define PKCS8_NEG_PRIVKEY 4 - ASN1_INTEGER *version; - X509_ALGOR *pkeyalg; - /* Should be OCTET STRING but some are broken */ - ASN1_TYPE *pkey; - STACK_OF(X509_ATTRIBUTE) *attributes; -}; - -#ifdef __cplusplus -} -#endif - -# include "x509_vfy.h" -# include "pkcs7.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# define X509_EXT_PACK_UNKNOWN 1 -# define X509_EXT_PACK_STRING 2 - -# define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version) -/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */ -# define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore) -# define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter) -# define X509_extract_key(x) X509_get_pubkey(x)/*****/ -# define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version) -# define X509_REQ_get_subject_name(x) ((x)->req_info->subject) -# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) -# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) -# define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm)) - -# define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version) -# define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate) -# define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate) -# define X509_CRL_get_issuer(x) ((x)->crl->issuer) -# define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) - -void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); -X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), - int (*crl_free) (X509_CRL *crl), - int (*crl_lookup) (X509_CRL *crl, - X509_REVOKED **ret, - ASN1_INTEGER *ser, - X509_NAME *issuer), - int (*crl_verify) (X509_CRL *crl, - EVP_PKEY *pk)); -void X509_CRL_METHOD_free(X509_CRL_METHOD *m); - -void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); -void *X509_CRL_get_meth_data(X509_CRL *crl); - -/* - * This one is only used so that a binary form can output, as in - * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) - */ -# define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) - -const char *X509_verify_cert_error_string(long n); - -# ifndef OPENSSL_NO_EVP -int X509_verify(X509 *a, EVP_PKEY *r); - -int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); -int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); -int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); - -NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len); -char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); -EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); -int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); - -int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); - -int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); -int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig); - -int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); -int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); -int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert); -int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); -int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); -int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); -int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); -int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl); -int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); - -int X509_pubkey_digest(const X509 *data, const EVP_MD *type, - unsigned char *md, unsigned int *len); -int X509_digest(const X509 *data, const EVP_MD *type, - unsigned char *md, unsigned int *len); -int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, - unsigned char *md, unsigned int *len); -int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, - unsigned char *md, unsigned int *len); -int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, - unsigned char *md, unsigned int *len); -# endif - -# ifndef OPENSSL_NO_FP_API -X509 *d2i_X509_fp(FILE *fp, X509 **x509); -int i2d_X509_fp(FILE *fp, X509 *x509); -X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); -int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); -X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); -int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); -# ifndef OPENSSL_NO_RSA -RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); -int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); -RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); -int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); -RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); -int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); -# endif -# ifndef OPENSSL_NO_DSA -DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); -int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); -DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); -int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); -# endif -# ifndef OPENSSL_NO_EC -EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); -int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); -EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); -int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); -# endif -X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); -int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); -PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, - PKCS8_PRIV_KEY_INFO **p8inf); -int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf); -int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); -int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); -int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); -# endif - -# ifndef OPENSSL_NO_BIO -X509 *d2i_X509_bio(BIO *bp, X509 **x509); -int i2d_X509_bio(BIO *bp, X509 *x509); -X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); -int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); -X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); -int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); -# ifndef OPENSSL_NO_RSA -RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); -int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); -RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); -int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); -RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); -int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); -# endif -# ifndef OPENSSL_NO_DSA -DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); -int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); -DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); -int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); -# endif -# ifndef OPENSSL_NO_EC -EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); -int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); -EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); -int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); -# endif -X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); -int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); -PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, - PKCS8_PRIV_KEY_INFO **p8inf); -int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf); -int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); -int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); -int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); -EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); -# endif - -X509 *X509_dup(X509 *x509); -X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); -X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); -X509_CRL *X509_CRL_dup(X509_CRL *crl); -X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); -X509_REQ *X509_REQ_dup(X509_REQ *req); -X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); -int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, - void *pval); -void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, - X509_ALGOR *algor); -void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); -int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); - -X509_NAME *X509_NAME_dup(X509_NAME *xn); -X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); - -int X509_cmp_time(const ASN1_TIME *s, time_t *t); -int X509_cmp_current_time(const ASN1_TIME *s); -ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t); -ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, - int offset_day, long offset_sec, time_t *t); -ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); - -const char *X509_get_default_cert_area(void); -const char *X509_get_default_cert_dir(void); -const char *X509_get_default_cert_file(void); -const char *X509_get_default_cert_dir_env(void); -const char *X509_get_default_cert_file_env(void); -const char *X509_get_default_private_dir(void); - -X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); -X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey); - -DECLARE_ASN1_FUNCTIONS(X509_ALGOR) -DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) -DECLARE_ASN1_FUNCTIONS(X509_VAL) - -DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) - -int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); -EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); -int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); -int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp); -EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); -# ifndef OPENSSL_NO_RSA -int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); -RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); -# endif -# ifndef OPENSSL_NO_DSA -int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp); -DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length); -# endif -# ifndef OPENSSL_NO_EC -int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); -EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); -# endif - -DECLARE_ASN1_FUNCTIONS(X509_SIG) -DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) -DECLARE_ASN1_FUNCTIONS(X509_REQ) - -DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) -X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); - -DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) -DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) - -DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) - -DECLARE_ASN1_FUNCTIONS(X509_NAME) - -int X509_NAME_set(X509_NAME **xn, X509_NAME *name); - -DECLARE_ASN1_FUNCTIONS(X509_CINF) - -DECLARE_ASN1_FUNCTIONS(X509) -DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) - -DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR) - -int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); -int X509_set_ex_data(X509 *r, int idx, void *arg); -void *X509_get_ex_data(X509 *r, int idx); -int i2d_X509_AUX(X509 *a, unsigned char **pp); -X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length); - -int i2d_re_X509_tbs(X509 *x, unsigned char **pp); - -void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, - const X509 *x); -int X509_get_signature_nid(const X509 *x); - -int X509_alias_set1(X509 *x, unsigned char *name, int len); -int X509_keyid_set1(X509 *x, unsigned char *id, int len); -unsigned char *X509_alias_get0(X509 *x, int *len); -unsigned char *X509_keyid_get0(X509 *x, int *len); -int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, - int); -int X509_TRUST_set(int *t, int trust); -int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); -int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); -void X509_trust_clear(X509 *x); -void X509_reject_clear(X509 *x); - -DECLARE_ASN1_FUNCTIONS(X509_REVOKED) -DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) -DECLARE_ASN1_FUNCTIONS(X509_CRL) - -int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); -int X509_CRL_get0_by_serial(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial); -int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); - -X509_PKEY *X509_PKEY_new(void); -void X509_PKEY_free(X509_PKEY *a); -int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp); -X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, - long length); - -DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) -DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) -DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) - -# ifndef OPENSSL_NO_EVP -X509_INFO *X509_INFO_new(void); -void X509_INFO_free(X509_INFO *a); -char *X509_NAME_oneline(X509_NAME *a, char *buf, int size); - -int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, - ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey); - -int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, - unsigned char *md, unsigned int *len); - -int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, - char *data, EVP_PKEY *pkey, const EVP_MD *type); - -int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, - unsigned char *md, unsigned int *len); - -int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, - ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); - -int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, - EVP_PKEY *pkey, const EVP_MD *type); -int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, - X509_ALGOR *algor2, ASN1_BIT_STRING *signature, - void *asn, EVP_MD_CTX *ctx); -# endif - -int X509_set_version(X509 *x, long version); -int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); -ASN1_INTEGER *X509_get_serialNumber(X509 *x); -int X509_set_issuer_name(X509 *x, X509_NAME *name); -X509_NAME *X509_get_issuer_name(X509 *a); -int X509_set_subject_name(X509 *x, X509_NAME *name); -X509_NAME *X509_get_subject_name(X509 *a); -int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); -int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); -int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); -EVP_PKEY *X509_get_pubkey(X509 *x); -ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); -int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ ); - -int X509_REQ_set_version(X509_REQ *x, long version); -int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); -int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); -EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); -int X509_REQ_extension_nid(int nid); -int *X509_REQ_get_extension_nids(void); -void X509_REQ_set_extension_nids(int *nids); -STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); -int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, - int nid); -int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); -int X509_REQ_get_attr_count(const X509_REQ *req); -int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); -int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, - int lastpos); -X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); -X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); -int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); -int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, - const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len); -int X509_REQ_add1_attr_by_NID(X509_REQ *req, - int nid, int type, - const unsigned char *bytes, int len); -int X509_REQ_add1_attr_by_txt(X509_REQ *req, - const char *attrname, int type, - const unsigned char *bytes, int len); - -int X509_CRL_set_version(X509_CRL *x, long version); -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); -int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); -int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); -int X509_CRL_sort(X509_CRL *crl); - -int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); -int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); - -X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, - EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); - -int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); - -int X509_check_private_key(X509 *x509, EVP_PKEY *pkey); -int X509_chain_check_suiteb(int *perror_depth, - X509 *x, STACK_OF(X509) *chain, - unsigned long flags); -int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags); -STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); - -int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); -unsigned long X509_issuer_and_serial_hash(X509 *a); - -int X509_issuer_name_cmp(const X509 *a, const X509 *b); -unsigned long X509_issuer_name_hash(X509 *a); - -int X509_subject_name_cmp(const X509 *a, const X509 *b); -unsigned long X509_subject_name_hash(X509 *x); - -# ifndef OPENSSL_NO_MD5 -unsigned long X509_issuer_name_hash_old(X509 *a); -unsigned long X509_subject_name_hash_old(X509 *x); -# endif - -int X509_cmp(const X509 *a, const X509 *b); -int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); -unsigned long X509_NAME_hash(X509_NAME *x); -unsigned long X509_NAME_hash_old(X509_NAME *x); - -int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); -int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); -# ifndef OPENSSL_NO_FP_API -int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, - unsigned long cflag); -int X509_print_fp(FILE *bp, X509 *x); -int X509_CRL_print_fp(FILE *bp, X509_CRL *x); -int X509_REQ_print_fp(FILE *bp, X509_REQ *req); -int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, - unsigned long flags); -# endif - -# ifndef OPENSSL_NO_BIO -int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); -int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, - unsigned long flags); -int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, - unsigned long cflag); -int X509_print(BIO *bp, X509 *x); -int X509_ocspid_print(BIO *bp, X509 *x); -int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent); -int X509_CRL_print(BIO *bp, X509_CRL *x); -int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, - unsigned long cflag); -int X509_REQ_print(BIO *bp, X509_REQ *req); -# endif - -int X509_NAME_entry_count(X509_NAME *name); -int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len); -int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, - char *buf, int len); - -/* - * NOTE: you should be passsing -1, not 0 as lastpos. The functions that use - * lastpos, search after that position on. - */ -int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos); -int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, - int lastpos); -X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); -X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); -int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, - int loc, int set); -int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, - unsigned char *bytes, int len, int loc, - int set); -int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, - unsigned char *bytes, int len, int loc, - int set); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, - const char *field, int type, - const unsigned char *bytes, - int len); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, - int type, unsigned char *bytes, - int len); -int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, - const unsigned char *bytes, int len, int loc, - int set); -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, - ASN1_OBJECT *obj, int type, - const unsigned char *bytes, - int len); -int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); -int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, - const unsigned char *bytes, int len); -ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); -ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); - -int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); -int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, - int nid, int lastpos); -int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, - ASN1_OBJECT *obj, int lastpos); -int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, - int crit, int lastpos); -X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); -X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); -STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, - X509_EXTENSION *ex, int loc); - -int X509_get_ext_count(X509 *x); -int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); -int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos); -int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); -X509_EXTENSION *X509_get_ext(X509 *x, int loc); -X509_EXTENSION *X509_delete_ext(X509 *x, int loc); -int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); -void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); -int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, - unsigned long flags); - -int X509_CRL_get_ext_count(X509_CRL *x); -int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); -int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos); -int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); -X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); -X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); -int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); -void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); -int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, - unsigned long flags); - -int X509_REVOKED_get_ext_count(X509_REVOKED *x); -int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); -int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, - int lastpos); -int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); -X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); -X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); -int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); -void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); -int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, - unsigned long flags); - -X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, - int nid, int crit, - ASN1_OCTET_STRING *data); -X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, - ASN1_OBJECT *obj, int crit, - ASN1_OCTET_STRING *data); -int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj); -int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); -int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); -ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); -ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); -int X509_EXTENSION_get_critical(X509_EXTENSION *ex); - -int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); -int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, - int lastpos); -int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, - ASN1_OBJECT *obj, int lastpos); -X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); -X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, - X509_ATTRIBUTE *attr); -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) - **x, const ASN1_OBJECT *obj, - int type, - const unsigned char *bytes, - int len); -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) - **x, int nid, int type, - const unsigned char *bytes, - int len); -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) - **x, const char *attrname, - int type, - const unsigned char *bytes, - int len); -void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj, - int lastpos, int type); -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, - int atrtype, const void *data, - int len); -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, - const ASN1_OBJECT *obj, - int atrtype, const void *data, - int len); -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, - const char *atrname, int type, - const unsigned char *bytes, - int len); -int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); -int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, - const void *data, int len); -void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, - void *data); -int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); -ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); -ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); - -int EVP_PKEY_get_attr_count(const EVP_PKEY *key); -int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos); -int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, - int lastpos); -X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); -X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); -int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); -int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, - const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len); -int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, - int nid, int type, - const unsigned char *bytes, int len); -int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, - const char *attrname, int type, - const unsigned char *bytes, int len); - -int X509_verify_cert(X509_STORE_CTX *ctx); - -/* lookup a cert from a X509 STACK */ -X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, - ASN1_INTEGER *serial); -X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); - -DECLARE_ASN1_FUNCTIONS(PBEPARAM) -DECLARE_ASN1_FUNCTIONS(PBE2PARAM) -DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) - -int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, - const unsigned char *salt, int saltlen); - -X509_ALGOR *PKCS5_pbe_set(int alg, int iter, - const unsigned char *salt, int saltlen); -X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, - unsigned char *salt, int saltlen); -X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, - unsigned char *salt, int saltlen, - unsigned char *aiv, int prf_nid); - -X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, - int prf_nid, int keylen); - -/* PKCS#8 utilities */ - -DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) - -EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); -PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); -PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); -PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); - -int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, - int version, int ptype, void *pval, - unsigned char *penc, int penclen); -int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, - const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8); - -int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, - int ptype, void *pval, - unsigned char *penc, int penclen); -int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, - const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, X509_PUBKEY *pub); - -int X509_check_trust(X509 *x, int id, int flags); -int X509_TRUST_get_count(void); -X509_TRUST *X509_TRUST_get0(int idx); -int X509_TRUST_get_by_id(int id); -int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), - char *name, int arg1, void *arg2); -void X509_TRUST_cleanup(void); -int X509_TRUST_get_flags(X509_TRUST *xp); -char *X509_TRUST_get0_name(X509_TRUST *xp); -int X509_TRUST_get_trust(X509_TRUST *xp); - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ - -void ERR_load_X509_strings(void); - -/* Error codes for the X509 functions. */ - -/* Function codes. */ -# define X509_F_ADD_CERT_DIR 100 -# define X509_F_BY_FILE_CTRL 101 -# define X509_F_CHECK_NAME_CONSTRAINTS 106 -# define X509_F_CHECK_POLICY 145 -# define X509_F_DIR_CTRL 102 -# define X509_F_GET_CERT_BY_SUBJECT 103 -# define X509_F_NETSCAPE_SPKI_B64_DECODE 129 -# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 -# define X509_F_X509AT_ADD1_ATTR 135 -# define X509_F_X509V3_ADD_EXT 104 -# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 -# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 -# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 -# define X509_F_X509_ATTRIBUTE_GET0_DATA 139 -# define X509_F_X509_ATTRIBUTE_SET1_DATA 138 -# define X509_F_X509_CHECK_PRIVATE_KEY 128 -# define X509_F_X509_CRL_DIFF 105 -# define X509_F_X509_CRL_PRINT_FP 147 -# define X509_F_X509_EXTENSION_CREATE_BY_NID 108 -# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 -# define X509_F_X509_GET_PUBKEY_PARAMETERS 110 -# define X509_F_X509_LOAD_CERT_CRL_FILE 132 -# define X509_F_X509_LOAD_CERT_FILE 111 -# define X509_F_X509_LOAD_CRL_FILE 112 -# define X509_F_X509_NAME_ADD_ENTRY 113 -# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 -# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 -# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 -# define X509_F_X509_NAME_ONELINE 116 -# define X509_F_X509_NAME_PRINT 117 -# define X509_F_X509_PRINT_EX_FP 118 -# define X509_F_X509_PUBKEY_GET 119 -# define X509_F_X509_PUBKEY_SET 120 -# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 -# define X509_F_X509_REQ_PRINT_EX 121 -# define X509_F_X509_REQ_PRINT_FP 122 -# define X509_F_X509_REQ_TO_X509 123 -# define X509_F_X509_STORE_ADD_CERT 124 -# define X509_F_X509_STORE_ADD_CRL 125 -# define X509_F_X509_STORE_CTX_GET1_ISSUER 146 -# define X509_F_X509_STORE_CTX_INIT 143 -# define X509_F_X509_STORE_CTX_NEW 142 -# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 -# define X509_F_X509_TO_X509_REQ 126 -# define X509_F_X509_TRUST_ADD 133 -# define X509_F_X509_TRUST_SET 141 -# define X509_F_X509_VERIFY_CERT 127 - -/* Reason codes. */ -# define X509_R_AKID_MISMATCH 110 -# define X509_R_BAD_X509_FILETYPE 100 -# define X509_R_BASE64_DECODE_ERROR 118 -# define X509_R_CANT_CHECK_DH_KEY 114 -# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 -# define X509_R_CRL_ALREADY_DELTA 127 -# define X509_R_CRL_VERIFY_FAILURE 131 -# define X509_R_ERR_ASN1_LIB 102 -# define X509_R_IDP_MISMATCH 128 -# define X509_R_INVALID_DIRECTORY 113 -# define X509_R_INVALID_FIELD_NAME 119 -# define X509_R_INVALID_TRUST 123 -# define X509_R_ISSUER_MISMATCH 129 -# define X509_R_KEY_TYPE_MISMATCH 115 -# define X509_R_KEY_VALUES_MISMATCH 116 -# define X509_R_LOADING_CERT_DIR 103 -# define X509_R_LOADING_DEFAULTS 104 -# define X509_R_METHOD_NOT_SUPPORTED 124 -# define X509_R_NAME_TOO_LONG 134 -# define X509_R_NEWER_CRL_NOT_NEWER 132 -# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 -# define X509_R_NO_CRL_NUMBER 130 -# define X509_R_PUBLIC_KEY_DECODE_ERROR 125 -# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 -# define X509_R_SHOULD_RETRY 106 -# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 -# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 -# define X509_R_UNKNOWN_KEY_TYPE 117 -# define X509_R_UNKNOWN_NID 109 -# define X509_R_UNKNOWN_PURPOSE_ID 121 -# define X509_R_UNKNOWN_TRUST_ID 120 -# define X509_R_UNSUPPORTED_ALGORITHM 111 -# define X509_R_WRONG_LOOKUP_TYPE 112 -# define X509_R_WRONG_TYPE 122 - -# ifdef __cplusplus -} -# endif -#endif diff --git a/Sources/COpenSSL/x509_.c b/Sources/COpenSSL/x509_.c deleted file mode 100644 index 3e96217b..00000000 --- a/Sources/COpenSSL/x509_.c +++ /dev/null @@ -1,7118 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/x509/x509_att.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "stack.h" -#include "cryptlib.h" -#include "asn1.h" -#include "objects.h" -#include "evp.h" -#include "x509.h" -#include "x509v3.h" - -int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) -{ - return sk_X509_ATTRIBUTE_num(x); -} - -int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, - int lastpos) -{ - ASN1_OBJECT *obj; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-2); - return (X509at_get_attr_by_OBJ(x, obj, lastpos)); -} - -int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, - ASN1_OBJECT *obj, int lastpos) -{ - int n; - X509_ATTRIBUTE *ex; - - if (sk == NULL) - return (-1); - lastpos++; - if (lastpos < 0) - lastpos = 0; - n = sk_X509_ATTRIBUTE_num(sk); - for (; lastpos < n; lastpos++) { - ex = sk_X509_ATTRIBUTE_value(sk, lastpos); - if (OBJ_cmp(ex->object, obj) == 0) - return (lastpos); - } - return (-1); -} - -X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) -{ - if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) - return NULL; - else - return sk_X509_ATTRIBUTE_value(x, loc); -} - -X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) -{ - X509_ATTRIBUTE *ret; - - if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) - return (NULL); - ret = sk_X509_ATTRIBUTE_delete(x, loc); - return (ret); -} - -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, - X509_ATTRIBUTE *attr) -{ - X509_ATTRIBUTE *new_attr = NULL; - STACK_OF(X509_ATTRIBUTE) *sk = NULL; - - if (x == NULL) { - X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER); - goto err2; - } - - if (*x == NULL) { - if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) - goto err; - } else - sk = *x; - - if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) - goto err2; - if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) - goto err; - if (*x == NULL) - *x = sk; - return (sk); - err: - X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE); - err2: - if (new_attr != NULL) - X509_ATTRIBUTE_free(new_attr); - if (sk != NULL) - sk_X509_ATTRIBUTE_free(sk); - return (NULL); -} - -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) - **x, const ASN1_OBJECT *obj, - int type, - const unsigned char *bytes, - int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) - **x, int nid, int type, - const unsigned char *bytes, - int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - -STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) - **x, const char *attrname, - int type, - const unsigned char *bytes, - int len) -{ - X509_ATTRIBUTE *attr; - STACK_OF(X509_ATTRIBUTE) *ret; - attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); - if (!attr) - return 0; - ret = X509at_add1_attr(x, attr); - X509_ATTRIBUTE_free(attr); - return ret; -} - -void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, - ASN1_OBJECT *obj, int lastpos, int type) -{ - int i; - X509_ATTRIBUTE *at; - i = X509at_get_attr_by_OBJ(x, obj, lastpos); - if (i == -1) - return NULL; - if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) - return NULL; - at = X509at_get_attr(x, i); - if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) - return NULL; - return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); -} - -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, - int atrtype, const void *data, - int len) -{ - ASN1_OBJECT *obj; - X509_ATTRIBUTE *ret; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID); - return (NULL); - } - ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); - if (ret == NULL) - ASN1_OBJECT_free(obj); - return (ret); -} - -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, - const ASN1_OBJECT *obj, - int atrtype, const void *data, - int len) -{ - X509_ATTRIBUTE *ret; - - if ((attr == NULL) || (*attr == NULL)) { - if ((ret = X509_ATTRIBUTE_new()) == NULL) { - X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, - ERR_R_MALLOC_FAILURE); - return (NULL); - } - } else - ret = *attr; - - if (!X509_ATTRIBUTE_set1_object(ret, obj)) - goto err; - if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len)) - goto err; - - if ((attr != NULL) && (*attr == NULL)) - *attr = ret; - return (ret); - err: - if ((attr == NULL) || (ret != *attr)) - X509_ATTRIBUTE_free(ret); - return (NULL); -} - -X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, - const char *atrname, int type, - const unsigned char *bytes, - int len) -{ - ASN1_OBJECT *obj; - X509_ATTRIBUTE *nattr; - - obj = OBJ_txt2obj(atrname, 0); - if (obj == NULL) { - X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, - X509_R_INVALID_FIELD_NAME); - ERR_add_error_data(2, "name=", atrname); - return (NULL); - } - nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); - ASN1_OBJECT_free(obj); - return nattr; -} - -int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) -{ - if ((attr == NULL) || (obj == NULL)) - return (0); - ASN1_OBJECT_free(attr->object); - attr->object = OBJ_dup(obj); - return (1); -} - -int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, - const void *data, int len) -{ - ASN1_TYPE *ttmp = NULL; - ASN1_STRING *stmp = NULL; - int atype = 0; - if (!attr) - return 0; - if (attrtype & MBSTRING_FLAG) { - stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, - OBJ_obj2nid(attr->object)); - if (!stmp) { - X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB); - return 0; - } - atype = stmp->type; - } else if (len != -1) { - if (!(stmp = ASN1_STRING_type_new(attrtype))) - goto err; - if (!ASN1_STRING_set(stmp, data, len)) - goto err; - atype = attrtype; - } - if (!(attr->value.set = sk_ASN1_TYPE_new_null())) - goto err; - attr->single = 0; - /* - * This is a bit naughty because the attribute should really have at - * least one value but some types use and zero length SET and require - * this. - */ - if (attrtype == 0) { - ASN1_STRING_free(stmp); - return 1; - } - if (!(ttmp = ASN1_TYPE_new())) - goto err; - if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { - if (!ASN1_TYPE_set1(ttmp, attrtype, data)) - goto err; - } else { - ASN1_TYPE_set(ttmp, atype, stmp); - stmp = NULL; - } - if (!sk_ASN1_TYPE_push(attr->value.set, ttmp)) - goto err; - return 1; - err: - X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); - ASN1_TYPE_free(ttmp); - ASN1_STRING_free(stmp); - return 0; -} - -int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr) -{ - if (!attr->single) - return sk_ASN1_TYPE_num(attr->value.set); - if (attr->value.single) - return 1; - return 0; -} - -ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) -{ - if (attr == NULL) - return (NULL); - return (attr->object); -} - -void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, - int atrtype, void *data) -{ - ASN1_TYPE *ttmp; - ttmp = X509_ATTRIBUTE_get0_type(attr, idx); - if (!ttmp) - return NULL; - if (atrtype != ASN1_TYPE_get(ttmp)) { - X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE); - return NULL; - } - return ttmp->value.ptr; -} - -ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) -{ - if (attr == NULL) - return (NULL); - if (idx >= X509_ATTRIBUTE_count(attr)) - return NULL; - if (!attr->single) - return sk_ASN1_TYPE_value(attr->value.set, idx); - else - return attr->value.single; -} -/* crypto/x509/x509_cmp.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "objects.h" -// #include "x509.h" -// #include "x509v3.h" - -int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) -{ - int i; - X509_CINF *ai, *bi; - - ai = a->cert_info; - bi = b->cert_info; - i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber); - if (i) - return (i); - return (X509_NAME_cmp(ai->issuer, bi->issuer)); -} - -#ifndef OPENSSL_NO_MD5 -unsigned long X509_issuer_and_serial_hash(X509 *a) -{ - unsigned long ret = 0; - EVP_MD_CTX ctx; - unsigned char md[16]; - char *f; - - EVP_MD_CTX_init(&ctx); - f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0); - if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) - goto err; - if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f))) - goto err; - OPENSSL_free(f); - if (!EVP_DigestUpdate - (&ctx, (unsigned char *)a->cert_info->serialNumber->data, - (unsigned long)a->cert_info->serialNumber->length)) - goto err; - if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL)) - goto err; - ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) - ) & 0xffffffffL; - err: - EVP_MD_CTX_cleanup(&ctx); - return (ret); -} -#endif - -int X509_issuer_name_cmp(const X509 *a, const X509 *b) -{ - return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); -} - -int X509_subject_name_cmp(const X509 *a, const X509 *b) -{ - return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); -} - -int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) -{ - return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); -} - -#ifndef OPENSSL_NO_SHA -int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) -{ - return memcmp(a->sha1_hash, b->sha1_hash, 20); -} -#endif - -X509_NAME *X509_get_issuer_name(X509 *a) -{ - return (a->cert_info->issuer); -} - -unsigned long X509_issuer_name_hash(X509 *x) -{ - return (X509_NAME_hash(x->cert_info->issuer)); -} - -#ifndef OPENSSL_NO_MD5 -unsigned long X509_issuer_name_hash_old(X509 *x) -{ - return (X509_NAME_hash_old(x->cert_info->issuer)); -} -#endif - -X509_NAME *X509_get_subject_name(X509 *a) -{ - return (a->cert_info->subject); -} - -ASN1_INTEGER *X509_get_serialNumber(X509 *a) -{ - return (a->cert_info->serialNumber); -} - -unsigned long X509_subject_name_hash(X509 *x) -{ - return (X509_NAME_hash(x->cert_info->subject)); -} - -#ifndef OPENSSL_NO_MD5 -unsigned long X509_subject_name_hash_old(X509 *x) -{ - return (X509_NAME_hash_old(x->cert_info->subject)); -} -#endif - -#ifndef OPENSSL_NO_SHA -/* - * Compare two certificates: they must be identical for this to work. NB: - * Although "cmp" operations are generally prototyped to take "const" - * arguments (eg. for use in STACKs), the way X509 handling is - these - * operations may involve ensuring the hashes are up-to-date and ensuring - * certain cert information is cached. So this is the point where the - * "depth-first" constification tree has to halt with an evil cast. - */ -int X509_cmp(const X509 *a, const X509 *b) -{ - int rv; - /* ensure hash is valid */ - X509_check_purpose((X509 *)a, -1, 0); - X509_check_purpose((X509 *)b, -1, 0); - - rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); - if (rv) - return rv; - /* Check for match against stored encoding too */ - if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) { - rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len); - if (rv) - return rv; - return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc, - a->cert_info->enc.len); - } - return rv; -} -#endif - -int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) -{ - int ret; - - /* Ensure canonical encoding is present and up to date */ - - if (!a->canon_enc || a->modified) { - ret = i2d_X509_NAME((X509_NAME *)a, NULL); - if (ret < 0) - return -2; - } - - if (!b->canon_enc || b->modified) { - ret = i2d_X509_NAME((X509_NAME *)b, NULL); - if (ret < 0) - return -2; - } - - ret = a->canon_enclen - b->canon_enclen; - - if (ret != 0 || a->canon_enclen == 0) - return ret; - - return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); - -} - -unsigned long X509_NAME_hash(X509_NAME *x) -{ - unsigned long ret = 0; - unsigned char md[SHA_DIGEST_LENGTH]; - - /* Make sure X509_NAME structure contains valid cached encoding */ - i2d_X509_NAME(x, NULL); - if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), - NULL)) - return 0; - - ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) - ) & 0xffffffffL; - return (ret); -} - -#ifndef OPENSSL_NO_MD5 -/* - * I now DER encode the name and hash it. Since I cache the DER encoding, - * this is reasonably efficient. - */ - -unsigned long X509_NAME_hash_old(X509_NAME *x) -{ - EVP_MD_CTX md_ctx; - unsigned long ret = 0; - unsigned char md[16]; - - /* Make sure X509_NAME structure contains valid cached encoding */ - i2d_X509_NAME(x, NULL); - EVP_MD_CTX_init(&md_ctx); - EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); - if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) - && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) - && EVP_DigestFinal_ex(&md_ctx, md, NULL)) - ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | - ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) - ) & 0xffffffffL; - EVP_MD_CTX_cleanup(&md_ctx); - - return (ret); -} -#endif - -/* Search a stack of X509 for a match */ -X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, - ASN1_INTEGER *serial) -{ - int i; - X509_CINF cinf; - X509 x, *x509 = NULL; - - if (!sk) - return NULL; - - x.cert_info = &cinf; - cinf.serialNumber = serial; - cinf.issuer = name; - - for (i = 0; i < sk_X509_num(sk); i++) { - x509 = sk_X509_value(sk, i); - if (X509_issuer_and_serial_cmp(x509, &x) == 0) - return (x509); - } - return (NULL); -} - -X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) -{ - X509 *x509; - int i; - - for (i = 0; i < sk_X509_num(sk); i++) { - x509 = sk_X509_value(sk, i); - if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) - return (x509); - } - return (NULL); -} - -EVP_PKEY *X509_get_pubkey(X509 *x) -{ - if ((x == NULL) || (x->cert_info == NULL)) - return (NULL); - return (X509_PUBKEY_get(x->cert_info->key)); -} - -ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) -{ - if (!x) - return NULL; - return x->cert_info->key->public_key; -} - -int X509_check_private_key(X509 *x, EVP_PKEY *k) -{ - EVP_PKEY *xk; - int ret; - - xk = X509_get_pubkey(x); - - if (xk) - ret = EVP_PKEY_cmp(xk, k); - else - ret = -2; - - switch (ret) { - case 1: - break; - case 0: - X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH); - break; - case -1: - X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); - break; - case -2: - X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); - } - if (xk) - EVP_PKEY_free(xk); - if (ret > 0) - return 1; - return 0; -} - -/* - * Check a suite B algorithm is permitted: pass in a public key and the NID - * of its signature (or 0 if no signature). The pflags is a pointer to a - * flags field which must contain the suite B verification flags. - */ - -#ifndef OPENSSL_NO_EC - -static int check_suite_b(EVP_PKEY *pkey, int sign_nid, unsigned long *pflags) -{ - const EC_GROUP *grp = NULL; - int curve_nid; - if (pkey && pkey->type == EVP_PKEY_EC) - grp = EC_KEY_get0_group(pkey->pkey.ec); - if (!grp) - return X509_V_ERR_SUITE_B_INVALID_ALGORITHM; - curve_nid = EC_GROUP_get_curve_name(grp); - /* Check curve is consistent with LOS */ - if (curve_nid == NID_secp384r1) { /* P-384 */ - /* - * Check signature algorithm is consistent with curve. - */ - if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA384) - return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; - if (!(*pflags & X509_V_FLAG_SUITEB_192_LOS)) - return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; - /* If we encounter P-384 we cannot use P-256 later */ - *pflags &= ~X509_V_FLAG_SUITEB_128_LOS_ONLY; - } else if (curve_nid == NID_X9_62_prime256v1) { /* P-256 */ - if (sign_nid != -1 && sign_nid != NID_ecdsa_with_SHA256) - return X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM; - if (!(*pflags & X509_V_FLAG_SUITEB_128_LOS_ONLY)) - return X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED; - } else - return X509_V_ERR_SUITE_B_INVALID_CURVE; - - return X509_V_OK; -} - -int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, - unsigned long flags) -{ - int rv, i, sign_nid; - EVP_PKEY *pk = NULL; - unsigned long tflags; - if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) - return X509_V_OK; - tflags = flags; - /* If no EE certificate passed in must be first in chain */ - if (x == NULL) { - x = sk_X509_value(chain, 0); - i = 1; - } else - i = 0; - - if (X509_get_version(x) != 2) { - rv = X509_V_ERR_SUITE_B_INVALID_VERSION; - /* Correct error depth */ - i = 0; - goto end; - } - - pk = X509_get_pubkey(x); - /* Check EE key only */ - rv = check_suite_b(pk, -1, &tflags); - if (rv != X509_V_OK) { - /* Correct error depth */ - i = 0; - goto end; - } - for (; i < sk_X509_num(chain); i++) { - sign_nid = X509_get_signature_nid(x); - x = sk_X509_value(chain, i); - if (X509_get_version(x) != 2) { - rv = X509_V_ERR_SUITE_B_INVALID_VERSION; - goto end; - } - EVP_PKEY_free(pk); - pk = X509_get_pubkey(x); - rv = check_suite_b(pk, sign_nid, &tflags); - if (rv != X509_V_OK) - goto end; - } - - /* Final check: root CA signature */ - rv = check_suite_b(pk, X509_get_signature_nid(x), &tflags); - end: - if (pk) - EVP_PKEY_free(pk); - if (rv != X509_V_OK) { - /* Invalid signature or LOS errors are for previous cert */ - if ((rv == X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM - || rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED) && i) - i--; - /* - * If we have LOS error and flags changed then we are signing P-384 - * with P-256. Use more meaninggul error. - */ - if (rv == X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED && flags != tflags) - rv = X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256; - if (perror_depth) - *perror_depth = i; - } - return rv; -} - -int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) -{ - int sign_nid; - if (!(flags & X509_V_FLAG_SUITEB_128_LOS)) - return X509_V_OK; - sign_nid = OBJ_obj2nid(crl->crl->sig_alg->algorithm); - return check_suite_b(pk, sign_nid, &flags); -} - -#else -int X509_chain_check_suiteb(int *perror_depth, X509 *x, STACK_OF(X509) *chain, - unsigned long flags) -{ - return 0; -} - -int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, unsigned long flags) -{ - return 0; -} - -#endif -/* - * Not strictly speaking an "up_ref" as a STACK doesn't have a reference - * count but it has the same effect by duping the STACK and upping the ref of - * each X509 structure. - */ -STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) -{ - STACK_OF(X509) *ret; - int i; - ret = sk_X509_dup(chain); - for (i = 0; i < sk_X509_num(ret); i++) { - X509 *x = sk_X509_value(ret, i); - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - } - return ret; -} -/* crypto/x509/x509_d2.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "crypto.h" -// #include "x509.h" - -#ifndef OPENSSL_NO_STDIO -int X509_STORE_set_default_paths(X509_STORE *ctx) -{ - X509_LOOKUP *lookup; - - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); - if (lookup == NULL) - return (0); - X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); - - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - return (0); - X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); - - /* clear any errors */ - ERR_clear_error(); - - return (1); -} - -int X509_STORE_load_locations(X509_STORE *ctx, const char *file, - const char *path) -{ - X509_LOOKUP *lookup; - - if (file != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); - if (lookup == NULL) - return (0); - if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) - return (0); - } - if (path != NULL) { - lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); - if (lookup == NULL) - return (0); - if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) - return (0); - } - if ((path == NULL) && (file == NULL)) - return (0); - return (1); -} - -#endif -/* crypto/x509/x509_def.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "crypto.h" -// #include "x509.h" - -const char *X509_get_default_private_dir(void) -{ - return (X509_PRIVATE_DIR); -} - -const char *X509_get_default_cert_area(void) -{ - return (X509_CERT_AREA); -} - -const char *X509_get_default_cert_dir(void) -{ - return (X509_CERT_DIR); -} - -const char *X509_get_default_cert_file(void) -{ - return (X509_CERT_FILE); -} - -const char *X509_get_default_cert_dir_env(void) -{ - return (X509_CERT_DIR_EVP); -} - -const char *X509_get_default_cert_file_env(void) -{ - return (X509_CERT_FILE_EVP); -} -/* crypto/x509/x509_err.c */ -/* ==================================================================== - * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -/* - * NOTE: this file was auto generated by the mkerr.pl script: any changes - * made to it will be overwritten when the script next updates this file, - * only reason strings will be preserved. - */ - -#include -#include "err.h" -// #include "x509.h" - -/* BEGIN ERROR CODES */ -#ifndef OPENSSL_NO_ERR - -# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0) -# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason) - -static ERR_STRING_DATA X509_str_functs[] = { - {ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"}, - {ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"}, - {ERR_FUNC(X509_F_CHECK_NAME_CONSTRAINTS), "CHECK_NAME_CONSTRAINTS"}, - {ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"}, - {ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"}, - {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"}, - {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"}, - {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"}, - {ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"}, - {ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"}, - {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID), - "X509_ATTRIBUTE_create_by_NID"}, - {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ), - "X509_ATTRIBUTE_create_by_OBJ"}, - {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT), - "X509_ATTRIBUTE_create_by_txt"}, - {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"}, - {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"}, - {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"}, - {ERR_FUNC(X509_F_X509_CRL_DIFF), "X509_CRL_diff"}, - {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"}, - {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID), - "X509_EXTENSION_create_by_NID"}, - {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ), - "X509_EXTENSION_create_by_OBJ"}, - {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS), - "X509_get_pubkey_parameters"}, - {ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"}, - {ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"}, - {ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"}, - {ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"}, - {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID), - "X509_NAME_ENTRY_create_by_NID"}, - {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT), - "X509_NAME_ENTRY_create_by_txt"}, - {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT), - "X509_NAME_ENTRY_set_object"}, - {ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"}, - {ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"}, - {ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"}, - {ERR_FUNC(X509_F_X509_PUBKEY_GET), "X509_PUBKEY_get"}, - {ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"}, - {ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY), - "X509_REQ_check_private_key"}, - {ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"}, - {ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"}, - {ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"}, - {ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"}, - {ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"}, - {ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER), - "X509_STORE_CTX_get1_issuer"}, - {ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"}, - {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"}, - {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT), - "X509_STORE_CTX_purpose_inherit"}, - {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"}, - {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"}, - {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"}, - {ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"}, - {0, NULL} -}; - -static ERR_STRING_DATA X509_str_reasons[] = { - {ERR_REASON(X509_R_AKID_MISMATCH), "akid mismatch"}, - {ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"}, - {ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"}, - {ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"}, - {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE), - "cert already in hash table"}, - {ERR_REASON(X509_R_CRL_ALREADY_DELTA), "crl already delta"}, - {ERR_REASON(X509_R_CRL_VERIFY_FAILURE), "crl verify failure"}, - {ERR_REASON(X509_R_ERR_ASN1_LIB), "err asn1 lib"}, - {ERR_REASON(X509_R_IDP_MISMATCH), "idp mismatch"}, - {ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"}, - {ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"}, - {ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"}, - {ERR_REASON(X509_R_ISSUER_MISMATCH), "issuer mismatch"}, - {ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"}, - {ERR_REASON(X509_R_KEY_VALUES_MISMATCH), "key values mismatch"}, - {ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"}, - {ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"}, - {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"}, - {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"}, - {ERR_REASON(X509_R_NEWER_CRL_NOT_NEWER), "newer crl not newer"}, - {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), - "no cert set for us to verify"}, - {ERR_REASON(X509_R_NO_CRL_NUMBER), "no crl number"}, - {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"}, - {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"}, - {ERR_REASON(X509_R_SHOULD_RETRY), "should retry"}, - {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), - "unable to find parameters in chain"}, - {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), - "unable to get certs public key"}, - {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"}, - {ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"}, - {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"}, - {ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"}, - {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, - {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"}, - {ERR_REASON(X509_R_WRONG_TYPE), "wrong type"}, - {0, NULL} -}; - -#endif - -void ERR_load_X509_strings(void) -{ -#ifndef OPENSSL_NO_ERR - - if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { - ERR_load_strings(0, X509_str_functs); - ERR_load_strings(0, X509_str_reasons); - } -#endif -} -/* crypto/x509/x509_ext.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "stack.h" -// #include "cryptlib.h" -// #include "asn1.h" -// #include "objects.h" -// #include "evp.h" -// #include "x509.h" -// #include "x509v3.h" - -int X509_CRL_get_ext_count(X509_CRL *x) -{ - return (X509v3_get_ext_count(x->crl->extensions)); -} - -int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); -} - -int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos) -{ - return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); -} - -int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos) -{ - return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); -} - -X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc) -{ - return (X509v3_get_ext(x->crl->extensions, loc)); -} - -X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) -{ - return (X509v3_delete_ext(x->crl->extensions, loc)); -} - -void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(x->crl->extensions, nid, crit, idx); -} - -int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); -} - -int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); -} - -int X509_get_ext_count(X509 *x) -{ - return (X509v3_get_ext_count(x->cert_info->extensions)); -} - -int X509_get_ext_by_NID(X509 *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); -} - -int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos) -{ - return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); -} - -int X509_get_ext_by_critical(X509 *x, int crit, int lastpos) -{ - return (X509v3_get_ext_by_critical - (x->cert_info->extensions, crit, lastpos)); -} - -X509_EXTENSION *X509_get_ext(X509 *x, int loc) -{ - return (X509v3_get_ext(x->cert_info->extensions, loc)); -} - -X509_EXTENSION *X509_delete_ext(X509 *x, int loc) -{ - return (X509v3_delete_ext(x->cert_info->extensions, loc)); -} - -int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); -} - -void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx); -} - -int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, - flags); -} - -int X509_REVOKED_get_ext_count(X509_REVOKED *x) -{ - return (X509v3_get_ext_count(x->extensions)); -} - -int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos) -{ - return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); -} - -int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, - int lastpos) -{ - return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); -} - -int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos) -{ - return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); -} - -X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc) -{ - return (X509v3_get_ext(x->extensions, loc)); -} - -X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) -{ - return (X509v3_delete_ext(x->extensions, loc)); -} - -int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) -{ - return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); -} - -void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx) -{ - return X509V3_get_d2i(x->extensions, nid, crit, idx); -} - -int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, - unsigned long flags) -{ - return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); -} - -IMPLEMENT_STACK_OF(X509_EXTENSION) - -IMPLEMENT_ASN1_SET_OF(X509_EXTENSION) -/* crypto/x509/x509_lu.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "lhash.h" -// #include "x509.h" -// #include "x509v3.h" - -X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) -{ - X509_LOOKUP *ret; - - ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); - if (ret == NULL) - return NULL; - - ret->init = 0; - ret->skip = 0; - ret->method = method; - ret->method_data = NULL; - ret->store_ctx = NULL; - if ((method->new_item != NULL) && !method->new_item(ret)) { - OPENSSL_free(ret); - return NULL; - } - return ret; -} - -void X509_LOOKUP_free(X509_LOOKUP *ctx) -{ - if (ctx == NULL) - return; - if ((ctx->method != NULL) && (ctx->method->free != NULL)) - (*ctx->method->free) (ctx); - OPENSSL_free(ctx); -} - -int X509_LOOKUP_init(X509_LOOKUP *ctx) -{ - if (ctx->method == NULL) - return 0; - if (ctx->method->init != NULL) - return ctx->method->init(ctx); - else - return 1; -} - -int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) -{ - if (ctx->method == NULL) - return 0; - if (ctx->method->shutdown != NULL) - return ctx->method->shutdown(ctx); - else - return 1; -} - -int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, - char **ret) -{ - if (ctx->method == NULL) - return -1; - if (ctx->method->ctrl != NULL) - return ctx->method->ctrl(ctx, cmd, argc, argl, ret); - else - return 1; -} - -int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, - X509_OBJECT *ret) -{ - if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) - return X509_LU_FAIL; - if (ctx->skip) - return 0; - return ctx->method->get_by_subject(ctx, type, name, ret); -} - -int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, - ASN1_INTEGER *serial, X509_OBJECT *ret) -{ - if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) - return X509_LU_FAIL; - return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret); -} - -int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, - unsigned char *bytes, int len, - X509_OBJECT *ret) -{ - if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) - return X509_LU_FAIL; - return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret); -} - -int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, - X509_OBJECT *ret) -{ - if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) - return X509_LU_FAIL; - return ctx->method->get_by_alias(ctx, type, str, len, ret); -} - -static int x509_object_cmp(const X509_OBJECT *const *a, - const X509_OBJECT *const *b) -{ - int ret; - - ret = ((*a)->type - (*b)->type); - if (ret) - return ret; - switch ((*a)->type) { - case X509_LU_X509: - ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); - break; - case X509_LU_CRL: - ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); - break; - default: - /* abort(); */ - return 0; - } - return ret; -} - -X509_STORE *X509_STORE_new(void) -{ - X509_STORE *ret; - - if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) - return NULL; - if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) - goto err0; - ret->cache = 1; - if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) - goto err1; - ret->verify = 0; - ret->verify_cb = 0; - - if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) - goto err2; - - ret->get_issuer = 0; - ret->check_issued = 0; - ret->check_revocation = 0; - ret->get_crl = 0; - ret->check_crl = 0; - ret->cert_crl = 0; - ret->lookup_certs = 0; - ret->lookup_crls = 0; - ret->cleanup = 0; - - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) - goto err3; - - ret->references = 1; - return ret; - - err3: - X509_VERIFY_PARAM_free(ret->param); - err2: - sk_X509_LOOKUP_free(ret->get_cert_methods); - err1: - sk_X509_OBJECT_free(ret->objs); - err0: - OPENSSL_free(ret); - return NULL; -} - -static void cleanup(X509_OBJECT *a) -{ - if (!a) - return; - if (a->type == X509_LU_X509) { - X509_free(a->data.x509); - } else if (a->type == X509_LU_CRL) { - X509_CRL_free(a->data.crl); - } else { - /* abort(); */ - } - - OPENSSL_free(a); -} - -void X509_STORE_free(X509_STORE *vfy) -{ - int i; - STACK_OF(X509_LOOKUP) *sk; - X509_LOOKUP *lu; - - if (vfy == NULL) - return; - - i = CRYPTO_add(&vfy->references, -1, CRYPTO_LOCK_X509_STORE); -#ifdef REF_PRINT - REF_PRINT("X509_STORE", vfy); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "X509_STORE_free, bad reference count\n"); - abort(); /* ok */ - } -#endif - - sk = vfy->get_cert_methods; - for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { - lu = sk_X509_LOOKUP_value(sk, i); - X509_LOOKUP_shutdown(lu); - X509_LOOKUP_free(lu); - } - sk_X509_LOOKUP_free(sk); - sk_X509_OBJECT_pop_free(vfy->objs, cleanup); - - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); - if (vfy->param) - X509_VERIFY_PARAM_free(vfy->param); - OPENSSL_free(vfy); -} - -X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) -{ - int i; - STACK_OF(X509_LOOKUP) *sk; - X509_LOOKUP *lu; - - sk = v->get_cert_methods; - for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { - lu = sk_X509_LOOKUP_value(sk, i); - if (m == lu->method) { - return lu; - } - } - /* a new one */ - lu = X509_LOOKUP_new(m); - if (lu == NULL) - return NULL; - else { - lu->store_ctx = v; - if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) - return lu; - else { - X509_LOOKUP_free(lu); - return NULL; - } - } -} - -int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, - X509_OBJECT *ret) -{ - X509_STORE *ctx = vs->ctx; - X509_LOOKUP *lu; - X509_OBJECT stmp, *tmp; - int i, j; - - if (ctx == NULL) - return 0; - - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - - tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - - if (tmp == NULL || type == X509_LU_CRL) { - for (i = vs->current_method; - i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { - lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); - j = X509_LOOKUP_by_subject(lu, type, name, &stmp); - if (j < 0) { - vs->current_method = j; - return j; - } else if (j) { - tmp = &stmp; - break; - } - } - vs->current_method = 0; - if (tmp == NULL) - return 0; - } - -/*- if (ret->data.ptr != NULL) - X509_OBJECT_free_contents(ret); */ - - ret->type = tmp->type; - ret->data.ptr = tmp->data.ptr; - - X509_OBJECT_up_ref_count(ret); - - return 1; -} - -int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) -{ - X509_OBJECT *obj; - int ret = 1; - - if (x == NULL) - return 0; - obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); - if (obj == NULL) { - X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); - return 0; - } - obj->type = X509_LU_X509; - obj->data.x509 = x; - - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - - X509_OBJECT_up_ref_count(obj); - - if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); - X509err(X509_F_X509_STORE_ADD_CERT, - X509_R_CERT_ALREADY_IN_HASH_TABLE); - ret = 0; - } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); - X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); - ret = 0; - } - - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - - return ret; -} - -int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) -{ - X509_OBJECT *obj; - int ret = 1; - - if (x == NULL) - return 0; - obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); - if (obj == NULL) { - X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); - return 0; - } - obj->type = X509_LU_CRL; - obj->data.crl = x; - - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - - X509_OBJECT_up_ref_count(obj); - - if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); - X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE); - ret = 0; - } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { - X509_OBJECT_free_contents(obj); - OPENSSL_free(obj); - X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); - ret = 0; - } - - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - - return ret; -} - -void X509_OBJECT_up_ref_count(X509_OBJECT *a) -{ - switch (a->type) { - case X509_LU_X509: - CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509); - break; - case X509_LU_CRL: - CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL); - break; - } -} - -void X509_OBJECT_free_contents(X509_OBJECT *a) -{ - switch (a->type) { - case X509_LU_X509: - X509_free(a->data.x509); - break; - case X509_LU_CRL: - X509_CRL_free(a->data.crl); - break; - } -} - -static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name, int *pnmatch) -{ - X509_OBJECT stmp; - X509 x509_s; - X509_CINF cinf_s; - X509_CRL crl_s; - X509_CRL_INFO crl_info_s; - int idx; - - stmp.type = type; - switch (type) { - case X509_LU_X509: - stmp.data.x509 = &x509_s; - x509_s.cert_info = &cinf_s; - cinf_s.subject = name; - break; - case X509_LU_CRL: - stmp.data.crl = &crl_s; - crl_s.crl = &crl_info_s; - crl_info_s.issuer = name; - break; - default: - /* abort(); */ - return -1; - } - - idx = sk_X509_OBJECT_find(h, &stmp); - if (idx >= 0 && pnmatch) { - int tidx; - const X509_OBJECT *tobj, *pstmp; - *pnmatch = 1; - pstmp = &stmp; - for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { - tobj = sk_X509_OBJECT_value(h, tidx); - if (x509_object_cmp(&tobj, &pstmp)) - break; - (*pnmatch)++; - } - } - return idx; -} - -int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name) -{ - return x509_object_idx_cnt(h, type, name, NULL); -} - -X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, - int type, X509_NAME *name) -{ - int idx; - idx = X509_OBJECT_idx_by_subject(h, type, name); - if (idx == -1) - return NULL; - return sk_X509_OBJECT_value(h, idx); -} - -STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) -{ - int i, idx, cnt; - STACK_OF(X509) *sk; - X509 *x; - X509_OBJECT *obj; - - if (ctx->ctx == NULL) - return NULL; - - sk = sk_X509_new_null(); - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); - if (idx < 0) { - /* - * Nothing found in cache: do lookup to possibly add new objects to - * cache - */ - X509_OBJECT xobj; - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { - sk_X509_free(sk); - return NULL; - } - X509_OBJECT_free_contents(&xobj); - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); - if (idx < 0) { - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - sk_X509_free(sk); - return NULL; - } - } - for (i = 0; i < cnt; i++, idx++) { - obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); - x = obj->data.x509; - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); - if (!sk_X509_push(sk, x)) { - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - X509_free(x); - sk_X509_pop_free(sk, X509_free); - return NULL; - } - } - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - return sk; - -} - -STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) -{ - int i, idx, cnt; - STACK_OF(X509_CRL) *sk; - X509_CRL *x; - X509_OBJECT *obj, xobj; - - - if (ctx->ctx == NULL) - return NULL; - - sk = sk_X509_CRL_new_null(); - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - - /* - * Always do lookup to possibly add new CRLs to cache - */ - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { - sk_X509_CRL_free(sk); - return NULL; - } - X509_OBJECT_free_contents(&xobj); - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); - if (idx < 0) { - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - sk_X509_CRL_free(sk); - return NULL; - } - - for (i = 0; i < cnt; i++, idx++) { - obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); - x = obj->data.crl; - CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); - if (!sk_X509_CRL_push(sk, x)) { - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - X509_CRL_free(x); - sk_X509_CRL_pop_free(sk, X509_CRL_free); - return NULL; - } - } - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - return sk; -} - -X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, - X509_OBJECT *x) -{ - int idx, i; - X509_OBJECT *obj; - idx = sk_X509_OBJECT_find(h, x); - if (idx == -1) - return NULL; - if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) - return sk_X509_OBJECT_value(h, idx); - for (i = idx; i < sk_X509_OBJECT_num(h); i++) { - obj = sk_X509_OBJECT_value(h, i); - if (x509_object_cmp - ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) - return NULL; - if (x->type == X509_LU_X509) { - if (!X509_cmp(obj->data.x509, x->data.x509)) - return obj; - } else if (x->type == X509_LU_CRL) { - if (!X509_CRL_match(obj->data.crl, x->data.crl)) - return obj; - } else - return obj; - } - return NULL; -} - -/*- - * Try to get issuer certificate from store. Due to limitations - * of the API this can only retrieve a single certificate matching - * a given subject name. However it will fill the cache with all - * matching certificates, so we can examine the cache for all - * matches. - * - * Return values are: - * 1 lookup successful. - * 0 certificate not found. - * -1 some other error. - */ -int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) -{ - X509_NAME *xn; - X509_OBJECT obj, *pobj; - int i, ok, idx, ret; - xn = X509_get_issuer_name(x); - ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj); - if (ok != X509_LU_X509) { - if (ok == X509_LU_RETRY) { - X509_OBJECT_free_contents(&obj); - X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY); - return -1; - } else if (ok != X509_LU_FAIL) { - X509_OBJECT_free_contents(&obj); - /* not good :-(, break anyway */ - return -1; - } - return 0; - } - /* If certificate matches all OK */ - if (ctx->check_issued(ctx, x, obj.data.x509)) { - *issuer = obj.data.x509; - return 1; - } - X509_OBJECT_free_contents(&obj); - - if (ctx->ctx == NULL) - return 0; - - /* Else find index of first cert accepted by 'check_issued' */ - ret = 0; - CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); - idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); - if (idx != -1) { /* should be true as we've had at least one - * match */ - /* Look through all matching certs for suitable issuer */ - for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { - pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); - /* See if we've run past the matches */ - if (pobj->type != X509_LU_X509) - break; - if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) - break; - if (ctx->check_issued(ctx, x, pobj->data.x509)) { - *issuer = pobj->data.x509; - X509_OBJECT_up_ref_count(pobj); - ret = 1; - break; - } - } - } - CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); - return ret; -} - -int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) -{ - return X509_VERIFY_PARAM_set_flags(ctx->param, flags); -} - -int X509_STORE_set_depth(X509_STORE *ctx, int depth) -{ - X509_VERIFY_PARAM_set_depth(ctx->param, depth); - return 1; -} - -int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) -{ - return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); -} - -int X509_STORE_set_trust(X509_STORE *ctx, int trust) -{ - return X509_VERIFY_PARAM_set_trust(ctx->param, trust); -} - -int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) -{ - return X509_VERIFY_PARAM_set1(ctx->param, param); -} - -void X509_STORE_set_verify_cb(X509_STORE *ctx, - int (*verify_cb) (int, X509_STORE_CTX *)) -{ - ctx->verify_cb = verify_cb; -} - -void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, - STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX - *ctx, - X509_NAME *nm)) -{ - ctx->lookup_crls = cb; -} - -X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx) -{ - return ctx->ctx; -} - -IMPLEMENT_STACK_OF(X509_LOOKUP) - -IMPLEMENT_STACK_OF(X509_OBJECT) -/* crypto/x509/x509_obj.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "lhash.h" -// #include "objects.h" -// #include "x509.h" -#include "buffer.h" - -/* - * Limit to ensure we don't overflow: much greater than - * anything enountered in practice. - */ - -#define NAME_ONELINE_MAX (1024 * 1024) - -char *X509_NAME_oneline(X509_NAME *a, char *buf, int len) -{ - X509_NAME_ENTRY *ne; - int i; - int n, lold, l, l1, l2, num, j, type; - const char *s; - char *p; - unsigned char *q; - BUF_MEM *b = NULL; - static const char hex[17] = "0123456789ABCDEF"; - int gs_doit[4]; - char tmp_buf[80]; -#ifdef CHARSET_EBCDIC - char ebcdic_buf[1024]; -#endif - - if (buf == NULL) { - if ((b = BUF_MEM_new()) == NULL) - goto err; - if (!BUF_MEM_grow(b, 200)) - goto err; - b->data[0] = '\0'; - len = 200; - } else if (len == 0) { - return NULL; - } - if (a == NULL) { - if (b) { - buf = b->data; - OPENSSL_free(b); - } - strncpy(buf, "NO X509_NAME", len); - buf[len - 1] = '\0'; - return buf; - } - - len--; /* space for '\0' */ - l = 0; - for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { - ne = sk_X509_NAME_ENTRY_value(a->entries, i); - n = OBJ_obj2nid(ne->object); - if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { - i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); - s = tmp_buf; - } - l1 = strlen(s); - - type = ne->value->type; - num = ne->value->length; - if (num > NAME_ONELINE_MAX) { - X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); - goto end; - } - q = ne->value->data; -#ifdef CHARSET_EBCDIC - if (type == V_ASN1_GENERALSTRING || - type == V_ASN1_VISIBLESTRING || - type == V_ASN1_PRINTABLESTRING || - type == V_ASN1_TELETEXSTRING || - type == V_ASN1_IA5STRING) { - if (num > (int)sizeof(ebcdic_buf)) - num = sizeof(ebcdic_buf); - ascii2ebcdic(ebcdic_buf, q, num); - q = ebcdic_buf; - } -#endif - - if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { - gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; - for (j = 0; j < num; j++) - if (q[j] != 0) - gs_doit[j & 3] = 1; - - if (gs_doit[0] | gs_doit[1] | gs_doit[2]) - gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; - else { - gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; - gs_doit[3] = 1; - } - } else - gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; - - for (l2 = j = 0; j < num; j++) { - if (!gs_doit[j & 3]) - continue; - l2++; -#ifndef CHARSET_EBCDIC - if ((q[j] < ' ') || (q[j] > '~')) - l2 += 3; -#else - if ((os_toascii[q[j]] < os_toascii[' ']) || - (os_toascii[q[j]] > os_toascii['~'])) - l2 += 3; -#endif - } - - lold = l; - l += 1 + l1 + 1 + l2; - if (l > NAME_ONELINE_MAX) { - X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); - goto end; - } - if (b != NULL) { - if (!BUF_MEM_grow(b, l + 1)) - goto err; - p = &(b->data[lold]); - } else if (l > len) { - break; - } else - p = &(buf[lold]); - *(p++) = '/'; - memcpy(p, s, (unsigned int)l1); - p += l1; - *(p++) = '='; - -#ifndef CHARSET_EBCDIC /* q was assigned above already. */ - q = ne->value->data; -#endif - - for (j = 0; j < num; j++) { - if (!gs_doit[j & 3]) - continue; -#ifndef CHARSET_EBCDIC - n = q[j]; - if ((n < ' ') || (n > '~')) { - *(p++) = '\\'; - *(p++) = 'x'; - *(p++) = hex[(n >> 4) & 0x0f]; - *(p++) = hex[n & 0x0f]; - } else - *(p++) = n; -#else - n = os_toascii[q[j]]; - if ((n < os_toascii[' ']) || (n > os_toascii['~'])) { - *(p++) = '\\'; - *(p++) = 'x'; - *(p++) = hex[(n >> 4) & 0x0f]; - *(p++) = hex[n & 0x0f]; - } else - *(p++) = q[j]; -#endif - } - *p = '\0'; - } - if (b != NULL) { - p = b->data; - OPENSSL_free(b); - } else - p = buf; - if (i == 0) - *p = '\0'; - return (p); - err: - X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE); - end: - BUF_MEM_free(b); - return (NULL); -} -/* crypto/x509/x509_r2x.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "bn.h" -// #include "evp.h" -// #include "asn1.h" -// #include "x509.h" -// #include "objects.h" -// #include "buffer.h" - -X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) -{ - X509 *ret = NULL; - X509_CINF *xi = NULL; - X509_NAME *xn; - EVP_PKEY *pubkey = NULL; - int res; - - if ((ret = X509_new()) == NULL) { - X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); - return NULL; - } - - /* duplicate the request */ - xi = ret->cert_info; - - if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { - if ((xi->version = M_ASN1_INTEGER_new()) == NULL) - goto err; - if (!ASN1_INTEGER_set(xi->version, 2)) - goto err; -/*- xi->extensions=ri->attributes; <- bad, should not ever be done - ri->attributes=NULL; */ - } - - xn = X509_REQ_get_subject_name(r); - if (X509_set_subject_name(ret, xn) == 0) - goto err; - if (X509_set_issuer_name(ret, xn) == 0) - goto err; - - if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) - goto err; - if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) == - NULL) - goto err; - - pubkey = X509_REQ_get_pubkey(r); - res = X509_set_pubkey(ret, pubkey); - EVP_PKEY_free(pubkey); - - if (!res || !X509_sign(ret, pkey, EVP_md5())) - goto err; - if (0) { - err: - X509_free(ret); - ret = NULL; - } - return (ret); -} -/* crypto/x509/x509_req.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "bn.h" -// #include "evp.h" -// #include "asn1.h" -#include "asn1t.h" -// #include "x509.h" -// #include "objects.h" -// #include "buffer.h" -#include "pem.h" - -X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - X509_REQ *ret; - X509_REQ_INFO *ri; - int i; - EVP_PKEY *pktmp; - - ret = X509_REQ_new(); - if (ret == NULL) { - X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE); - goto err; - } - - ri = ret->req_info; - - ri->version->length = 1; - ri->version->data = (unsigned char *)OPENSSL_malloc(1); - if (ri->version->data == NULL) - goto err; - ri->version->data[0] = 0; /* version == 0 */ - - if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) - goto err; - - pktmp = X509_get_pubkey(x); - if (pktmp == NULL) - goto err; - i = X509_REQ_set_pubkey(ret, pktmp); - EVP_PKEY_free(pktmp); - if (!i) - goto err; - - if (pkey != NULL) { - if (!X509_REQ_sign(ret, pkey, md)) - goto err; - } - return (ret); - err: - X509_REQ_free(ret); - return (NULL); -} - -EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) -{ - if ((req == NULL) || (req->req_info == NULL)) - return (NULL); - return (X509_PUBKEY_get(req->req_info->pubkey)); -} - -int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) -{ - EVP_PKEY *xk = NULL; - int ok = 0; - - xk = X509_REQ_get_pubkey(x); - switch (EVP_PKEY_cmp(xk, k)) { - case 1: - ok = 1; - break; - case 0: - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, - X509_R_KEY_VALUES_MISMATCH); - break; - case -1: - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); - break; - case -2: -#ifndef OPENSSL_NO_EC - if (k->type == EVP_PKEY_EC) { - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); - break; - } -#endif -#ifndef OPENSSL_NO_DH - if (k->type == EVP_PKEY_DH) { - /* No idea */ - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, - X509_R_CANT_CHECK_DH_KEY); - break; - } -#endif - X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); - } - - EVP_PKEY_free(xk); - return (ok); -} - -/* - * It seems several organisations had the same idea of including a list of - * extensions in a certificate request. There are at least two OIDs that are - * used and there may be more: so the list is configurable. - */ - -static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef }; - -static int *ext_nids = ext_nid_list; - -int X509_REQ_extension_nid(int req_nid) -{ - int i, nid; - for (i = 0;; i++) { - nid = ext_nids[i]; - if (nid == NID_undef) - return 0; - else if (req_nid == nid) - return 1; - } -} - -int *X509_REQ_get_extension_nids(void) -{ - return ext_nids; -} - -void X509_REQ_set_extension_nids(int *nids) -{ - ext_nids = nids; -} - -STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) -{ - X509_ATTRIBUTE *attr; - ASN1_TYPE *ext = NULL; - int idx, *pnid; - const unsigned char *p; - - if ((req == NULL) || (req->req_info == NULL) || !ext_nids) - return (NULL); - for (pnid = ext_nids; *pnid != NID_undef; pnid++) { - idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); - if (idx == -1) - continue; - attr = X509_REQ_get_attr(req, idx); - if (attr->single) - ext = attr->value.single; - else if (sk_ASN1_TYPE_num(attr->value.set)) - ext = sk_ASN1_TYPE_value(attr->value.set, 0); - break; - } - if (!ext || (ext->type != V_ASN1_SEQUENCE)) - return NULL; - p = ext->value.sequence->data; - return (STACK_OF(X509_EXTENSION) *) - ASN1_item_d2i(NULL, &p, ext->value.sequence->length, - ASN1_ITEM_rptr(X509_EXTENSIONS)); -} - -/* - * Add a STACK_OF extensions to a certificate request: allow alternative OIDs - * in case we want to create a non standard one. - */ - -int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, - int nid) -{ - ASN1_TYPE *at = NULL; - X509_ATTRIBUTE *attr = NULL; - if (!(at = ASN1_TYPE_new()) || !(at->value.sequence = ASN1_STRING_new())) - goto err; - - at->type = V_ASN1_SEQUENCE; - /* Generate encoding of extensions */ - at->value.sequence->length = - ASN1_item_i2d((ASN1_VALUE *)exts, - &at->value.sequence->data, - ASN1_ITEM_rptr(X509_EXTENSIONS)); - if (!(attr = X509_ATTRIBUTE_new())) - goto err; - if (!(attr->value.set = sk_ASN1_TYPE_new_null())) - goto err; - if (!sk_ASN1_TYPE_push(attr->value.set, at)) - goto err; - at = NULL; - attr->single = 0; - attr->object = OBJ_nid2obj(nid); - if (!req->req_info->attributes) { - if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null())) - goto err; - } - if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) - goto err; - return 1; - err: - X509_ATTRIBUTE_free(attr); - ASN1_TYPE_free(at); - return 0; -} - -/* This is the normal usage: use the "official" OID */ -int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) -{ - return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); -} - -/* Request attribute functions */ - -int X509_REQ_get_attr_count(const X509_REQ *req) -{ - return X509at_get_attr_count(req->req_info->attributes); -} - -int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) -{ - return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); -} - -int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, - int lastpos) -{ - return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); -} - -X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) -{ - return X509at_get_attr(req->req_info->attributes, loc); -} - -X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) -{ - return X509at_delete_attr(req->req_info->attributes, loc); -} - -int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) -{ - if (X509at_add1_attr(&req->req_info->attributes, attr)) - return 1; - return 0; -} - -int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, - const ASN1_OBJECT *obj, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, - type, bytes, len)) - return 1; - return 0; -} - -int X509_REQ_add1_attr_by_NID(X509_REQ *req, - int nid, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid, - type, bytes, len)) - return 1; - return 0; -} - -int X509_REQ_add1_attr_by_txt(X509_REQ *req, - const char *attrname, int type, - const unsigned char *bytes, int len) -{ - if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, - type, bytes, len)) - return 1; - return 0; -} -/* crypto/x509/x509_set.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1.h" -// #include "objects.h" -// #include "evp.h" -// #include "x509.h" - -int X509_set_version(X509 *x, long version) -{ - if (x == NULL) - return (0); - if (version == 0) { - M_ASN1_INTEGER_free(x->cert_info->version); - x->cert_info->version = NULL; - return (1); - } - if (x->cert_info->version == NULL) { - if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL) - return (0); - } - return (ASN1_INTEGER_set(x->cert_info->version, version)); -} - -int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) -{ - ASN1_INTEGER *in; - - if (x == NULL) - return (0); - in = x->cert_info->serialNumber; - if (in != serial) { - in = M_ASN1_INTEGER_dup(serial); - if (in != NULL) { - M_ASN1_INTEGER_free(x->cert_info->serialNumber); - x->cert_info->serialNumber = in; - } - } - return (in != NULL); -} - -int X509_set_issuer_name(X509 *x, X509_NAME *name) -{ - if ((x == NULL) || (x->cert_info == NULL)) - return (0); - return (X509_NAME_set(&x->cert_info->issuer, name)); -} - -int X509_set_subject_name(X509 *x, X509_NAME *name) -{ - if ((x == NULL) || (x->cert_info == NULL)) - return (0); - return (X509_NAME_set(&x->cert_info->subject, name)); -} - -int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if ((x == NULL) || (x->cert_info->validity == NULL)) - return (0); - in = x->cert_info->validity->notBefore; - if (in != tm) { - in = M_ASN1_TIME_dup(tm); - if (in != NULL) { - M_ASN1_TIME_free(x->cert_info->validity->notBefore); - x->cert_info->validity->notBefore = in; - } - } - return (in != NULL); -} - -int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if ((x == NULL) || (x->cert_info->validity == NULL)) - return (0); - in = x->cert_info->validity->notAfter; - if (in != tm) { - in = M_ASN1_TIME_dup(tm); - if (in != NULL) { - M_ASN1_TIME_free(x->cert_info->validity->notAfter); - x->cert_info->validity->notAfter = in; - } - } - return (in != NULL); -} - -int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) -{ - if ((x == NULL) || (x->cert_info == NULL)) - return (0); - return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); -} -/* x509_trs.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "x509v3.h" - -static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b); -static void trtable_free(X509_TRUST *p); - -static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); -static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); -static int trust_compat(X509_TRUST *trust, X509 *x, int flags); - -static int obj_trust(int id, X509 *x, int flags); -static int (*default_trust) (int id, X509 *x, int flags) = obj_trust; - -/* - * WARNING: the following table should be kept in order of trust and without - * any gaps so we can just subtract the minimum trust value to get an index - * into the table - */ - -static X509_TRUST trstandard[] = { - {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL}, - {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, - NULL}, - {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, - NULL}, - {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, - NULL}, - {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, - NULL}, - {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, - NULL}, - {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, - NULL}, - {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL} -}; - -#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) - -IMPLEMENT_STACK_OF(X509_TRUST) - -static STACK_OF(X509_TRUST) *trtable = NULL; - -static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b) -{ - return (*a)->trust - (*b)->trust; -} - -int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, - int) { - int (*oldtrust) (int, X509 *, int); - oldtrust = default_trust; - default_trust = trust; - return oldtrust; -} - -int X509_check_trust(X509 *x, int id, int flags) -{ - X509_TRUST *pt; - int idx; - if (id == -1) - return 1; - /* We get this as a default value */ - if (id == 0) { - int rv; - rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); - if (rv != X509_TRUST_UNTRUSTED) - return rv; - return trust_compat(NULL, x, 0); - } - idx = X509_TRUST_get_by_id(id); - if (idx == -1) - return default_trust(id, x, flags); - pt = X509_TRUST_get0(idx); - return pt->check_trust(pt, x, flags); -} - -int X509_TRUST_get_count(void) -{ - if (!trtable) - return X509_TRUST_COUNT; - return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; -} - -X509_TRUST *X509_TRUST_get0(int idx) -{ - if (idx < 0) - return NULL; - if (idx < (int)X509_TRUST_COUNT) - return trstandard + idx; - return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); -} - -int X509_TRUST_get_by_id(int id) -{ - X509_TRUST tmp; - int idx; - if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) - return id - X509_TRUST_MIN; - tmp.trust = id; - if (!trtable) - return -1; - idx = sk_X509_TRUST_find(trtable, &tmp); - if (idx == -1) - return -1; - return idx + X509_TRUST_COUNT; -} - -int X509_TRUST_set(int *t, int trust) -{ - if (X509_TRUST_get_by_id(trust) == -1) { - X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST); - return 0; - } - *t = trust; - return 1; -} - -int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), - char *name, int arg1, void *arg2) -{ - int idx; - X509_TRUST *trtmp; - /* - * This is set according to what we change: application can't set it - */ - flags &= ~X509_TRUST_DYNAMIC; - /* This will always be set for application modified trust entries */ - flags |= X509_TRUST_DYNAMIC_NAME; - /* Get existing entry if any */ - idx = X509_TRUST_get_by_id(id); - /* Need a new entry */ - if (idx == -1) { - if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) { - X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - trtmp->flags = X509_TRUST_DYNAMIC; - } else - trtmp = X509_TRUST_get0(idx); - - /* OPENSSL_free existing name if dynamic */ - if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) - OPENSSL_free(trtmp->name); - /* dup supplied name */ - if (!(trtmp->name = BUF_strdup(name))) { - X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - /* Keep the dynamic flag of existing entry */ - trtmp->flags &= X509_TRUST_DYNAMIC; - /* Set all other flags */ - trtmp->flags |= flags; - - trtmp->trust = id; - trtmp->check_trust = ck; - trtmp->arg1 = arg1; - trtmp->arg2 = arg2; - - /* If its a new entry manage the dynamic table */ - if (idx == -1) { - if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) { - X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - if (!sk_X509_TRUST_push(trtable, trtmp)) { - X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); - return 0; - } - } - return 1; -} - -static void trtable_free(X509_TRUST *p) -{ - if (!p) - return; - if (p->flags & X509_TRUST_DYNAMIC) { - if (p->flags & X509_TRUST_DYNAMIC_NAME) - OPENSSL_free(p->name); - OPENSSL_free(p); - } -} - -void X509_TRUST_cleanup(void) -{ - unsigned int i; - for (i = 0; i < X509_TRUST_COUNT; i++) - trtable_free(trstandard + i); - sk_X509_TRUST_pop_free(trtable, trtable_free); - trtable = NULL; -} - -int X509_TRUST_get_flags(X509_TRUST *xp) -{ - return xp->flags; -} - -char *X509_TRUST_get0_name(X509_TRUST *xp) -{ - return xp->name; -} - -int X509_TRUST_get_trust(X509_TRUST *xp) -{ - return xp->trust; -} - -static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) -{ - if (x->aux && (x->aux->trust || x->aux->reject)) - return obj_trust(trust->arg1, x, flags); - /* - * we don't have any trust settings: for compatibility we return trusted - * if it is self signed - */ - return trust_compat(trust, x, flags); -} - -static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) -{ - if (x->aux) - return obj_trust(trust->arg1, x, flags); - return X509_TRUST_UNTRUSTED; -} - -static int trust_compat(X509_TRUST *trust, X509 *x, int flags) -{ - X509_check_purpose(x, -1, 0); - if (x->ex_flags & EXFLAG_SS) - return X509_TRUST_TRUSTED; - else - return X509_TRUST_UNTRUSTED; -} - -static int obj_trust(int id, X509 *x, int flags) -{ - ASN1_OBJECT *obj; - int i; - X509_CERT_AUX *ax; - ax = x->aux; - if (!ax) - return X509_TRUST_UNTRUSTED; - if (ax->reject) { - for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { - obj = sk_ASN1_OBJECT_value(ax->reject, i); - if (OBJ_obj2nid(obj) == id) - return X509_TRUST_REJECTED; - } - } - if (ax->trust) { - for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { - obj = sk_ASN1_OBJECT_value(ax->trust, i); - if (OBJ_obj2nid(obj) == id) - return X509_TRUST_TRUSTED; - } - } - return X509_TRUST_UNTRUSTED; -} -/* crypto/x509/x509_txt.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include - -// #include "cryptlib.h" -// #include "lhash.h" -// #include "buffer.h" -// #include "evp.h" -// #include "asn1.h" -// #include "x509.h" -// #include "objects.h" - -const char *X509_verify_cert_error_string(long n) -{ - static char buf[100]; - - switch ((int)n) { - case X509_V_OK: - return ("ok"); - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - return ("unable to get issuer certificate"); - case X509_V_ERR_UNABLE_TO_GET_CRL: - return ("unable to get certificate CRL"); - case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: - return ("unable to decrypt certificate's signature"); - case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: - return ("unable to decrypt CRL's signature"); - case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: - return ("unable to decode issuer public key"); - case X509_V_ERR_CERT_SIGNATURE_FAILURE: - return ("certificate signature failure"); - case X509_V_ERR_CRL_SIGNATURE_FAILURE: - return ("CRL signature failure"); - case X509_V_ERR_CERT_NOT_YET_VALID: - return ("certificate is not yet valid"); - case X509_V_ERR_CRL_NOT_YET_VALID: - return ("CRL is not yet valid"); - case X509_V_ERR_CERT_HAS_EXPIRED: - return ("certificate has expired"); - case X509_V_ERR_CRL_HAS_EXPIRED: - return ("CRL has expired"); - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - return ("format error in certificate's notBefore field"); - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - return ("format error in certificate's notAfter field"); - case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: - return ("format error in CRL's lastUpdate field"); - case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: - return ("format error in CRL's nextUpdate field"); - case X509_V_ERR_OUT_OF_MEM: - return ("out of memory"); - case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: - return ("self signed certificate"); - case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: - return ("self signed certificate in certificate chain"); - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: - return ("unable to get local issuer certificate"); - case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: - return ("unable to verify the first certificate"); - case X509_V_ERR_CERT_CHAIN_TOO_LONG: - return ("certificate chain too long"); - case X509_V_ERR_CERT_REVOKED: - return ("certificate revoked"); - case X509_V_ERR_INVALID_CA: - return ("invalid CA certificate"); - case X509_V_ERR_INVALID_NON_CA: - return ("invalid non-CA certificate (has CA markings)"); - case X509_V_ERR_PATH_LENGTH_EXCEEDED: - return ("path length constraint exceeded"); - case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: - return ("proxy path length constraint exceeded"); - case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: - return - ("proxy certificates not allowed, please set the appropriate flag"); - case X509_V_ERR_INVALID_PURPOSE: - return ("unsupported certificate purpose"); - case X509_V_ERR_CERT_UNTRUSTED: - return ("certificate not trusted"); - case X509_V_ERR_CERT_REJECTED: - return ("certificate rejected"); - case X509_V_ERR_APPLICATION_VERIFICATION: - return ("application verification failure"); - case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: - return ("subject issuer mismatch"); - case X509_V_ERR_AKID_SKID_MISMATCH: - return ("authority and subject key identifier mismatch"); - case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: - return ("authority and issuer serial number mismatch"); - case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: - return ("key usage does not include certificate signing"); - case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: - return ("unable to get CRL issuer certificate"); - case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: - return ("unhandled critical extension"); - case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: - return ("key usage does not include CRL signing"); - case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: - return ("key usage does not include digital signature"); - case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: - return ("unhandled critical CRL extension"); - case X509_V_ERR_INVALID_EXTENSION: - return ("invalid or inconsistent certificate extension"); - case X509_V_ERR_INVALID_POLICY_EXTENSION: - return ("invalid or inconsistent certificate policy extension"); - case X509_V_ERR_NO_EXPLICIT_POLICY: - return ("no explicit policy"); - case X509_V_ERR_DIFFERENT_CRL_SCOPE: - return ("Different CRL scope"); - case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: - return ("Unsupported extension feature"); - case X509_V_ERR_UNNESTED_RESOURCE: - return ("RFC 3779 resource not subset of parent's resources"); - - case X509_V_ERR_PERMITTED_VIOLATION: - return ("permitted subtree violation"); - case X509_V_ERR_EXCLUDED_VIOLATION: - return ("excluded subtree violation"); - case X509_V_ERR_SUBTREE_MINMAX: - return ("name constraints minimum and maximum not supported"); - case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: - return ("unsupported name constraint type"); - case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: - return ("unsupported or invalid name constraint syntax"); - case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: - return ("unsupported or invalid name syntax"); - case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: - return ("CRL path validation error"); - - case X509_V_ERR_SUITE_B_INVALID_VERSION: - return ("Suite B: certificate version invalid"); - case X509_V_ERR_SUITE_B_INVALID_ALGORITHM: - return ("Suite B: invalid public key algorithm"); - case X509_V_ERR_SUITE_B_INVALID_CURVE: - return ("Suite B: invalid ECC curve"); - case X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM: - return ("Suite B: invalid signature algorithm"); - case X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED: - return ("Suite B: curve not allowed for this LOS"); - case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256: - return ("Suite B: cannot sign P-384 with P-256"); - - case X509_V_ERR_HOSTNAME_MISMATCH: - return ("Hostname mismatch"); - case X509_V_ERR_EMAIL_MISMATCH: - return ("Email address mismatch"); - case X509_V_ERR_IP_ADDRESS_MISMATCH: - return ("IP address mismatch"); - - case X509_V_ERR_INVALID_CALL: - return ("Invalid certificate verification context"); - case X509_V_ERR_STORE_LOOKUP: - return ("Issuer certificate lookup error"); - case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION: - return ("proxy subject name violation"); - - default: - BIO_snprintf(buf, sizeof(buf), "error number %ld", n); - return (buf); - } -} -/* crypto/x509/x509_v3.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "stack.h" -// #include "cryptlib.h" -// #include "asn1.h" -// #include "objects.h" -// #include "evp.h" -// #include "x509.h" -// #include "x509v3.h" - -int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) -{ - if (x == NULL) - return (0); - return (sk_X509_EXTENSION_num(x)); -} - -int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, - int lastpos) -{ - ASN1_OBJECT *obj; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-2); - return (X509v3_get_ext_by_OBJ(x, obj, lastpos)); -} - -int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, - ASN1_OBJECT *obj, int lastpos) -{ - int n; - X509_EXTENSION *ex; - - if (sk == NULL) - return (-1); - lastpos++; - if (lastpos < 0) - lastpos = 0; - n = sk_X509_EXTENSION_num(sk); - for (; lastpos < n; lastpos++) { - ex = sk_X509_EXTENSION_value(sk, lastpos); - if (OBJ_cmp(ex->object, obj) == 0) - return (lastpos); - } - return (-1); -} - -int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, - int lastpos) -{ - int n; - X509_EXTENSION *ex; - - if (sk == NULL) - return (-1); - lastpos++; - if (lastpos < 0) - lastpos = 0; - n = sk_X509_EXTENSION_num(sk); - for (; lastpos < n; lastpos++) { - ex = sk_X509_EXTENSION_value(sk, lastpos); - if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit)) - return (lastpos); - } - return (-1); -} - -X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) -{ - if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) - return NULL; - else - return sk_X509_EXTENSION_value(x, loc); -} - -X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) -{ - X509_EXTENSION *ret; - - if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) - return (NULL); - ret = sk_X509_EXTENSION_delete(x, loc); - return (ret); -} - -STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, - X509_EXTENSION *ex, int loc) -{ - X509_EXTENSION *new_ex = NULL; - int n; - STACK_OF(X509_EXTENSION) *sk = NULL; - - if (x == NULL) { - X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER); - goto err2; - } - - if (*x == NULL) { - if ((sk = sk_X509_EXTENSION_new_null()) == NULL) - goto err; - } else - sk = *x; - - n = sk_X509_EXTENSION_num(sk); - if (loc > n) - loc = n; - else if (loc < 0) - loc = n; - - if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) - goto err2; - if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) - goto err; - if (*x == NULL) - *x = sk; - return (sk); - err: - X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE); - err2: - if (new_ex != NULL) - X509_EXTENSION_free(new_ex); - if (x != NULL && *x == NULL && sk != NULL) - sk_X509_EXTENSION_free(sk); - return (NULL); -} - -X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, - int crit, - ASN1_OCTET_STRING *data) -{ - ASN1_OBJECT *obj; - X509_EXTENSION *ret; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID); - return (NULL); - } - ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); - if (ret == NULL) - ASN1_OBJECT_free(obj); - return (ret); -} - -X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, - ASN1_OBJECT *obj, int crit, - ASN1_OCTET_STRING *data) -{ - X509_EXTENSION *ret; - - if ((ex == NULL) || (*ex == NULL)) { - if ((ret = X509_EXTENSION_new()) == NULL) { - X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ, - ERR_R_MALLOC_FAILURE); - return (NULL); - } - } else - ret = *ex; - - if (!X509_EXTENSION_set_object(ret, obj)) - goto err; - if (!X509_EXTENSION_set_critical(ret, crit)) - goto err; - if (!X509_EXTENSION_set_data(ret, data)) - goto err; - - if ((ex != NULL) && (*ex == NULL)) - *ex = ret; - return (ret); - err: - if ((ex == NULL) || (ret != *ex)) - X509_EXTENSION_free(ret); - return (NULL); -} - -int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj) -{ - if ((ex == NULL) || (obj == NULL)) - return (0); - ASN1_OBJECT_free(ex->object); - ex->object = OBJ_dup(obj); - return (1); -} - -int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) -{ - if (ex == NULL) - return (0); - ex->critical = (crit) ? 0xFF : -1; - return (1); -} - -int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) -{ - int i; - - if (ex == NULL) - return (0); - i = M_ASN1_OCTET_STRING_set(ex->value, data->data, data->length); - if (!i) - return (0); - return (1); -} - -ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) -{ - if (ex == NULL) - return (NULL); - return (ex->object); -} - -ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) -{ - if (ex == NULL) - return (NULL); - return (ex->value); -} - -int X509_EXTENSION_get_critical(X509_EXTENSION *ex) -{ - if (ex == NULL) - return (0); - if (ex->critical > 0) - return 1; - return 0; -} -/* crypto/x509/x509_vfy.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -#include -#include - -// #include "cryptlib.h" -// #include "crypto.h" -// #include "lhash.h" -// #include "buffer.h" -// #include "evp.h" -// #include "asn1.h" -// #include "x509.h" -// #include "x509v3.h" -// #include "objects.h" -#include "vpm_int.h" - -/* CRL score values */ - -/* No unhandled critical extensions */ - -#define CRL_SCORE_NOCRITICAL 0x100 - -/* certificate is within CRL scope */ - -#define CRL_SCORE_SCOPE 0x080 - -/* CRL times valid */ - -#define CRL_SCORE_TIME 0x040 - -/* Issuer name matches certificate */ - -#define CRL_SCORE_ISSUER_NAME 0x020 - -/* If this score or above CRL is probably valid */ - -#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) - -/* CRL issuer is certificate issuer */ - -#define CRL_SCORE_ISSUER_CERT 0x018 - -/* CRL issuer is on certificate path */ - -#define CRL_SCORE_SAME_PATH 0x008 - -/* CRL issuer matches CRL AKID */ - -#define CRL_SCORE_AKID 0x004 - -/* Have a delta CRL with valid times */ - -#define CRL_SCORE_TIME_DELTA 0x002 - -static int null_callback(int ok, X509_STORE_CTX *e); -static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); -static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); -static int check_chain_extensions(X509_STORE_CTX *ctx); -static int check_name_constraints(X509_STORE_CTX *ctx); -static int check_id(X509_STORE_CTX *ctx); -static int check_trust(X509_STORE_CTX *ctx); -static int check_revocation(X509_STORE_CTX *ctx); -static int check_cert(X509_STORE_CTX *ctx); -static int check_policy(X509_STORE_CTX *ctx); - -static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, - unsigned int *preasons, X509_CRL *crl, X509 *x); -static int get_crl_delta(X509_STORE_CTX *ctx, - X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); -static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, - int *pcrl_score, X509_CRL *base, - STACK_OF(X509_CRL) *crls); -static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, - int *pcrl_score); -static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, - unsigned int *preasons); -static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); -static int check_crl_chain(X509_STORE_CTX *ctx, - STACK_OF(X509) *cert_path, - STACK_OF(X509) *crl_path); - -static int internal_verify(X509_STORE_CTX *ctx); -const char X509_version[] = "X.509" OPENSSL_VERSION_PTEXT; - -static int null_callback(int ok, X509_STORE_CTX *e) -{ - return ok; -} - -#if 0 -static int x509_subject_cmp(X509 **a, X509 **b) -{ - return X509_subject_name_cmp(*a, *b); -} -#endif -/* Return 1 is a certificate is self signed */ -static int cert_self_signed(X509 *x) -{ - X509_check_purpose(x, -1, 0); - if (x->ex_flags & EXFLAG_SS) - return 1; - else - return 0; -} - -/* Given a certificate try and find an exact match in the store */ - -static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) -{ - STACK_OF(X509) *certs; - X509 *xtmp = NULL; - int i; - /* Lookup all certs with matching subject name */ - certs = ctx->lookup_certs(ctx, X509_get_subject_name(x)); - if (certs == NULL) - return NULL; - /* Look for exact match */ - for (i = 0; i < sk_X509_num(certs); i++) { - xtmp = sk_X509_value(certs, i); - if (!X509_cmp(xtmp, x)) - break; - } - if (i < sk_X509_num(certs)) - CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509); - else - xtmp = NULL; - sk_X509_pop_free(certs, X509_free); - return xtmp; -} - -int X509_verify_cert(X509_STORE_CTX *ctx) -{ - X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; - int bad_chain = 0; - X509_VERIFY_PARAM *param = ctx->param; - int depth, i, ok = 0; - int num, j, retry; - int (*cb) (int xok, X509_STORE_CTX *xctx); - STACK_OF(X509) *sktmp = NULL; - int trust = X509_TRUST_UNTRUSTED; - int err; - - if (ctx->cert == NULL) { - X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); - ctx->error = X509_V_ERR_INVALID_CALL; - return -1; - } - if (ctx->chain != NULL) { - /* - * This X509_STORE_CTX has already been used to verify a cert. We - * cannot do another one. - */ - X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - ctx->error = X509_V_ERR_INVALID_CALL; - return -1; - } - - cb = ctx->verify_cb; - - /* - * first we make sure the chain we are going to build is present and that - * the first entry is in place - */ - if (((ctx->chain = sk_X509_new_null()) == NULL) || - (!sk_X509_push(ctx->chain, ctx->cert))) { - X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = -1; - goto err; - } - CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509); - ctx->last_untrusted = 1; - - /* We use a temporary STACK so we can chop and hack at it */ - if (ctx->untrusted != NULL - && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { - X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = -1; - goto err; - } - - num = sk_X509_num(ctx->chain); - x = sk_X509_value(ctx->chain, num - 1); - depth = param->depth; - - for (;;) { - /* If we have enough, we break */ - if (depth < num) - break; /* FIXME: If this happens, we should take - * note of it and, if appropriate, use the - * X509_V_ERR_CERT_CHAIN_TOO_LONG error code - * later. */ - - /* If we are self signed, we break */ - if (cert_self_signed(x)) - break; - /* - * If asked see if we can find issuer in trusted store first - */ - if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) { - ok = ctx->get_issuer(&xtmp, ctx, x); - if (ok < 0) { - ctx->error = X509_V_ERR_STORE_LOOKUP; - goto err; - } - /* - * If successful for now free up cert so it will be picked up - * again later. - */ - if (ok > 0) { - X509_free(xtmp); - break; - } - } - - /* If we were passed a cert chain, use it first */ - if (ctx->untrusted != NULL) { - xtmp = find_issuer(ctx, sktmp, x); - if (xtmp != NULL) { - if (!sk_X509_push(ctx->chain, xtmp)) { - X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = -1; - goto err; - } - CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509); - (void)sk_X509_delete_ptr(sktmp, xtmp); - ctx->last_untrusted++; - x = xtmp; - num++; - /* - * reparse the full chain for the next one - */ - continue; - } - } - break; - } - - /* Remember how many untrusted certs we have */ - j = num; - /* - * at this point, chain should contain a list of untrusted certificates. - * We now need to add at least one trusted one, if possible, otherwise we - * complain. - */ - - do { - /* - * Examine last certificate in chain and see if it is self signed. - */ - i = sk_X509_num(ctx->chain); - x = sk_X509_value(ctx->chain, i - 1); - if (cert_self_signed(x)) { - /* we have a self signed certificate */ - if (sk_X509_num(ctx->chain) == 1) { - /* - * We have a single self signed certificate: see if we can - * find it in the store. We must have an exact match to avoid - * possible impersonation. - */ - ok = ctx->get_issuer(&xtmp, ctx, x); - if ((ok <= 0) || X509_cmp(x, xtmp)) { - ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; - ctx->current_cert = x; - ctx->error_depth = i - 1; - if (ok == 1) - X509_free(xtmp); - bad_chain = 1; - ok = cb(0, ctx); - if (!ok) - goto err; - } else { - /* - * We have a match: replace certificate with store - * version so we get any trust settings. - */ - X509_free(x); - x = xtmp; - (void)sk_X509_set(ctx->chain, i - 1, x); - ctx->last_untrusted = 0; - } - } else { - /* - * extract and save self signed certificate for later use - */ - chain_ss = sk_X509_pop(ctx->chain); - ctx->last_untrusted--; - num--; - j--; - x = sk_X509_value(ctx->chain, num - 1); - } - } - /* We now lookup certs from the certificate store */ - for (;;) { - /* If we have enough, we break */ - if (depth < num) - break; - /* If we are self signed, we break */ - if (cert_self_signed(x)) - break; - ok = ctx->get_issuer(&xtmp, ctx, x); - - if (ok < 0) { - ctx->error = X509_V_ERR_STORE_LOOKUP; - goto err; - } - if (ok == 0) - break; - x = xtmp; - if (!sk_X509_push(ctx->chain, x)) { - X509_free(xtmp); - X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - ok = -1; - goto err; - } - num++; - } - - /* we now have our chain, lets check it... */ - if ((trust = check_trust(ctx)) == X509_TRUST_REJECTED) { - /* Callback already issued */ - ok = 0; - goto err; - } - - /* - * If it's not explicitly trusted then check if there is an alternative - * chain that could be used. We only do this if we haven't already - * checked via TRUSTED_FIRST and the user hasn't switched off alternate - * chain checking - */ - retry = 0; - if (trust != X509_TRUST_TRUSTED - && !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) - && !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { - while (j-- > 1) { - xtmp2 = sk_X509_value(ctx->chain, j - 1); - ok = ctx->get_issuer(&xtmp, ctx, xtmp2); - if (ok < 0) { - ctx->error = X509_V_ERR_STORE_LOOKUP; - goto err; - } - /* Check if we found an alternate chain */ - if (ok > 0) { - /* - * Free up the found cert we'll add it again later - */ - X509_free(xtmp); - - /* - * Dump all the certs above this point - we've found an - * alternate chain - */ - while (num > j) { - xtmp = sk_X509_pop(ctx->chain); - X509_free(xtmp); - num--; - } - ctx->last_untrusted = sk_X509_num(ctx->chain); - retry = 1; - break; - } - } - } - } while (retry); - - /* - * If not explicitly trusted then indicate error unless it's a single - * self signed certificate in which case we've indicated an error already - * and set bad_chain == 1 - */ - if (trust != X509_TRUST_TRUSTED && !bad_chain) { - if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { - if (ctx->last_untrusted >= num) - ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; - else - ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; - ctx->current_cert = x; - } else { - - sk_X509_push(ctx->chain, chain_ss); - num++; - ctx->last_untrusted = num; - ctx->current_cert = chain_ss; - ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; - chain_ss = NULL; - } - - ctx->error_depth = num - 1; - bad_chain = 1; - ok = cb(0, ctx); - if (!ok) - goto err; - } - - /* We have the chain complete: now we need to check its purpose */ - ok = check_chain_extensions(ctx); - - if (!ok) - goto err; - - /* Check name constraints */ - - ok = check_name_constraints(ctx); - - if (!ok) - goto err; - - ok = check_id(ctx); - - if (!ok) - goto err; - - /* We may as well copy down any DSA parameters that are required */ - X509_get_pubkey_parameters(NULL, ctx->chain); - - /* - * Check revocation status: we do this after copying parameters because - * they may be needed for CRL signature verification. - */ - - ok = ctx->check_revocation(ctx); - if (!ok) - goto err; - - err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain, - ctx->param->flags); - if (err != X509_V_OK) { - ctx->error = err; - ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth); - ok = cb(0, ctx); - if (!ok) - goto err; - } - - /* At this point, we have a chain and need to verify it */ - if (ctx->verify != NULL) - ok = ctx->verify(ctx); - else - ok = internal_verify(ctx); - if (!ok) - goto err; - -#ifndef OPENSSL_NO_RFC3779 - /* RFC 3779 path validation, now that CRL check has been done */ - ok = v3_asid_validate_path(ctx); - if (!ok) - goto err; - ok = v3_addr_validate_path(ctx); - if (!ok) - goto err; -#endif - - /* If we get this far evaluate policies */ - if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) - ok = ctx->check_policy(ctx); - if (!ok) - goto err; - if (0) { - err: - /* Ensure we return an error */ - if (ok > 0) - ok = 0; - X509_get_pubkey_parameters(NULL, ctx->chain); - } - if (sktmp != NULL) - sk_X509_free(sktmp); - if (chain_ss != NULL) - X509_free(chain_ss); - - /* Safety net, error returns must set ctx->error */ - if (ok <= 0 && ctx->error == X509_V_OK) - ctx->error = X509_V_ERR_UNSPECIFIED; - return ok; -} - -/* - * Given a STACK_OF(X509) find the issuer of cert (if any) - */ - -static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) -{ - int i; - X509 *issuer; - for (i = 0; i < sk_X509_num(sk); i++) { - issuer = sk_X509_value(sk, i); - if (ctx->check_issued(ctx, x, issuer)) - return issuer; - } - return NULL; -} - -/* Given a possible certificate and issuer check them */ - -static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) -{ - int ret; - ret = X509_check_issued(issuer, x); - if (ret == X509_V_OK) - return 1; - /* If we haven't asked for issuer errors don't set ctx */ - if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) - return 0; - - ctx->error = ret; - ctx->current_cert = x; - ctx->current_issuer = issuer; - return ctx->verify_cb(0, ctx); -} - -/* Alternative lookup method: look from a STACK stored in other_ctx */ - -static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) -{ - *issuer = find_issuer(ctx, ctx->other_ctx, x); - if (*issuer) { - CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); - return 1; - } else - return 0; -} - -/* - * Check a certificate chains extensions for consistency with the supplied - * purpose - */ - -static int check_chain_extensions(X509_STORE_CTX *ctx) -{ -#ifdef OPENSSL_NO_CHAIN_VERIFY - return 1; -#else - int i, ok = 0, must_be_ca, plen = 0; - X509 *x; - int (*cb) (int xok, X509_STORE_CTX *xctx); - int proxy_path_length = 0; - int purpose; - int allow_proxy_certs; - cb = ctx->verify_cb; - - /*- - * must_be_ca can have 1 of 3 values: - * -1: we accept both CA and non-CA certificates, to allow direct - * use of self-signed certificates (which are marked as CA). - * 0: we only accept non-CA certificates. This is currently not - * used, but the possibility is present for future extensions. - * 1: we only accept CA certificates. This is currently used for - * all certificates in the chain except the leaf certificate. - */ - must_be_ca = -1; - - /* CRL path validation */ - if (ctx->parent) { - allow_proxy_certs = 0; - purpose = X509_PURPOSE_CRL_SIGN; - } else { - allow_proxy_certs = - ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); - /* - * A hack to keep people who don't want to modify their software - * happy - */ - if (ossl_safe_getenv("OPENSSL_ALLOW_PROXY_CERTS")) - allow_proxy_certs = 1; - purpose = ctx->param->purpose; - } - - /* Check all untrusted certificates */ - for (i = 0; i < ctx->last_untrusted; i++) { - int ret; - x = sk_X509_value(ctx->chain, i); - if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) - && (x->ex_flags & EXFLAG_CRITICAL)) { - ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { - ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - ret = X509_check_ca(x); - switch (must_be_ca) { - case -1: - if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) - && (ret != 1) && (ret != 0)) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_CA; - } else - ret = 1; - break; - case 0: - if (ret != 0) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_NON_CA; - } else - ret = 1; - break; - default: - if ((ret == 0) - || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) - && (ret != 1))) { - ret = 0; - ctx->error = X509_V_ERR_INVALID_CA; - } else - ret = 1; - break; - } - if (ret == 0) { - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - if (ctx->param->purpose > 0) { - ret = X509_check_purpose(x, purpose, must_be_ca > 0); - if ((ret == 0) - || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) - && (ret != 1))) { - ctx->error = X509_V_ERR_INVALID_PURPOSE; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - } - /* Check pathlen */ - if ((i > 1) && (x->ex_pathlen != -1) - && (plen > (x->ex_pathlen + proxy_path_length))) { - ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - /* Increment path length if not a self issued intermediate CA */ - if (i > 0 && (x->ex_flags & EXFLAG_SI) == 0) - plen++; - /* - * If this certificate is a proxy certificate, the next certificate - * must be another proxy certificate or a EE certificate. If not, - * the next certificate must be a CA certificate. - */ - if (x->ex_flags & EXFLAG_PROXY) { - /* - * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint - * is less than max_path_length, the former should be copied to - * the latter, and 4.1.4 (a) stipulates that max_path_length - * should be verified to be larger than zero and decrement it. - * - * Because we're checking the certs in the reverse order, we start - * with verifying that proxy_path_length isn't larger than pcPLC, - * and copy the latter to the former if it is, and finally, - * increment proxy_path_length. - */ - if (x->ex_pcpathlen != -1) { - if (proxy_path_length > x->ex_pcpathlen) { - ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; - ctx->error_depth = i; - ctx->current_cert = x; - ok = cb(0, ctx); - if (!ok) - goto end; - } - proxy_path_length = x->ex_pcpathlen; - } - proxy_path_length++; - must_be_ca = 0; - } else - must_be_ca = 1; - } - ok = 1; - end: - return ok; -#endif -} - -static int check_name_constraints(X509_STORE_CTX *ctx) -{ - X509 *x; - int i, j, rv; - /* Check name constraints for all certificates */ - for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) { - x = sk_X509_value(ctx->chain, i); - /* Ignore self issued certs unless last in chain */ - if (i && (x->ex_flags & EXFLAG_SI)) - continue; - - /* - * Proxy certificates policy has an extra constraint, where the - * certificate subject MUST be the issuer with a single CN entry - * added. - * (RFC 3820: 3.4, 4.1.3 (a)(4)) - */ - if (x->ex_flags & EXFLAG_PROXY) { - X509_NAME *tmpsubject = X509_get_subject_name(x); - X509_NAME *tmpissuer = X509_get_issuer_name(x); - X509_NAME_ENTRY *tmpentry = NULL; - int last_object_nid = 0; - int err = X509_V_OK; - int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1; - - /* Check that there are at least two RDNs */ - if (last_object_loc < 1) { - err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; - goto proxy_name_done; - } - - /* - * Check that there is exactly one more RDN in subject as - * there is in issuer. - */ - if (X509_NAME_entry_count(tmpsubject) - != X509_NAME_entry_count(tmpissuer) + 1) { - err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; - goto proxy_name_done; - } - - /* - * Check that the last subject component isn't part of a - * multivalued RDN - */ - if (X509_NAME_get_entry(tmpsubject, last_object_loc)->set - == X509_NAME_get_entry(tmpsubject, last_object_loc - 1)->set) { - err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; - goto proxy_name_done; - } - - /* - * Check that the last subject RDN is a commonName, and that - * all the previous RDNs match the issuer exactly - */ - tmpsubject = X509_NAME_dup(tmpsubject); - if (tmpsubject == NULL) { - X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; - } - - tmpentry = - X509_NAME_delete_entry(tmpsubject, last_object_loc); - last_object_nid = - OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry)); - - if (last_object_nid != NID_commonName - || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) { - err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION; - } - - X509_NAME_ENTRY_free(tmpentry); - X509_NAME_free(tmpsubject); - - proxy_name_done: - if (err != X509_V_OK) { - ctx->error = err; - ctx->error_depth = i; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - } - - /* - * Check against constraints for all certificates higher in chain - * including trust anchor. Trust anchor not strictly speaking needed - * but if it includes constraints it is to be assumed it expects them - * to be obeyed. - */ - for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) { - NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; - if (nc) { - rv = NAME_CONSTRAINTS_check(x, nc); - switch (rv) { - case X509_V_OK: - continue; - case X509_V_ERR_OUT_OF_MEM: - ctx->error = rv; - return 0; - default: - ctx->error = rv; - ctx->error_depth = i; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - break; - } - } - } - } - return 1; -} - -static int check_id_error(X509_STORE_CTX *ctx, int errcode) -{ - ctx->error = errcode; - ctx->current_cert = ctx->cert; - ctx->error_depth = 0; - return ctx->verify_cb(0, ctx); -} - -static int check_hosts(X509 *x, X509_VERIFY_PARAM_ID *id) -{ - int i; - int n = sk_OPENSSL_STRING_num(id->hosts); - char *name; - - if (id->peername != NULL) { - OPENSSL_free(id->peername); - id->peername = NULL; - } - for (i = 0; i < n; ++i) { - name = sk_OPENSSL_STRING_value(id->hosts, i); - if (X509_check_host(x, name, 0, id->hostflags, &id->peername) > 0) - return 1; - } - return n == 0; -} - -static int check_id(X509_STORE_CTX *ctx) -{ - X509_VERIFY_PARAM *vpm = ctx->param; - X509_VERIFY_PARAM_ID *id = vpm->id; - X509 *x = ctx->cert; - if (id->hosts && check_hosts(x, id) <= 0) { - if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) - return 0; - } - if (id->email && X509_check_email(x, id->email, id->emaillen, 0) <= 0) { - if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) - return 0; - } - if (id->ip && X509_check_ip(x, id->ip, id->iplen, 0) <= 0) { - if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) - return 0; - } - return 1; -} - -static int check_trust(X509_STORE_CTX *ctx) -{ - int i, ok; - X509 *x = NULL; - int (*cb) (int xok, X509_STORE_CTX *xctx); - cb = ctx->verify_cb; - /* Check all trusted certificates in chain */ - for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) { - x = sk_X509_value(ctx->chain, i); - ok = X509_check_trust(x, ctx->param->trust, 0); - /* If explicitly trusted return trusted */ - if (ok == X509_TRUST_TRUSTED) - return X509_TRUST_TRUSTED; - /* - * If explicitly rejected notify callback and reject if not - * overridden. - */ - if (ok == X509_TRUST_REJECTED) { - ctx->error_depth = i; - ctx->current_cert = x; - ctx->error = X509_V_ERR_CERT_REJECTED; - ok = cb(0, ctx); - if (!ok) - return X509_TRUST_REJECTED; - } - } - /* - * If we accept partial chains and have at least one trusted certificate - * return success. - */ - if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { - X509 *mx; - if (ctx->last_untrusted < sk_X509_num(ctx->chain)) - return X509_TRUST_TRUSTED; - x = sk_X509_value(ctx->chain, 0); - mx = lookup_cert_match(ctx, x); - if (mx) { - (void)sk_X509_set(ctx->chain, 0, mx); - X509_free(x); - ctx->last_untrusted = 0; - return X509_TRUST_TRUSTED; - } - } - - /* - * If no trusted certs in chain at all return untrusted and allow - * standard (no issuer cert) etc errors to be indicated. - */ - return X509_TRUST_UNTRUSTED; -} - -static int check_revocation(X509_STORE_CTX *ctx) -{ - int i, last, ok; - if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) - return 1; - if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) - last = sk_X509_num(ctx->chain) - 1; - else { - /* If checking CRL paths this isn't the EE certificate */ - if (ctx->parent) - return 1; - last = 0; - } - for (i = 0; i <= last; i++) { - ctx->error_depth = i; - ok = check_cert(ctx); - if (!ok) - return ok; - } - return 1; -} - -static int check_cert(X509_STORE_CTX *ctx) -{ - X509_CRL *crl = NULL, *dcrl = NULL; - X509 *x; - int ok, cnum; - unsigned int last_reasons; - cnum = ctx->error_depth; - x = sk_X509_value(ctx->chain, cnum); - ctx->current_cert = x; - ctx->current_issuer = NULL; - ctx->current_crl_score = 0; - ctx->current_reasons = 0; - if (x->ex_flags & EXFLAG_PROXY) - return 1; - while (ctx->current_reasons != CRLDP_ALL_REASONS) { - last_reasons = ctx->current_reasons; - /* Try to retrieve relevant CRL */ - if (ctx->get_crl) - ok = ctx->get_crl(ctx, &crl, x); - else - ok = get_crl_delta(ctx, &crl, &dcrl, x); - /* - * If error looking up CRL, nothing we can do except notify callback - */ - if (!ok) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; - ok = ctx->verify_cb(0, ctx); - goto err; - } - ctx->current_crl = crl; - ok = ctx->check_crl(ctx, crl); - if (!ok) - goto err; - - if (dcrl) { - ok = ctx->check_crl(ctx, dcrl); - if (!ok) - goto err; - ok = ctx->cert_crl(ctx, dcrl, x); - if (!ok) - goto err; - } else - ok = 1; - - /* Don't look in full CRL if delta reason is removefromCRL */ - if (ok != 2) { - ok = ctx->cert_crl(ctx, crl, x); - if (!ok) - goto err; - } - - X509_CRL_free(crl); - X509_CRL_free(dcrl); - crl = NULL; - dcrl = NULL; - /* - * If reasons not updated we wont get anywhere by another iteration, - * so exit loop. - */ - if (last_reasons == ctx->current_reasons) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; - ok = ctx->verify_cb(0, ctx); - goto err; - } - } - err: - X509_CRL_free(crl); - X509_CRL_free(dcrl); - - ctx->current_crl = NULL; - return ok; - -} - -/* Check CRL times against values in X509_STORE_CTX */ - -static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) -{ - time_t *ptime; - int i; - if (notify) - ctx->current_crl = crl; - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) - ptime = &ctx->param->check_time; - else - ptime = NULL; - - i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); - if (i == 0) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (i > 0) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (X509_CRL_get_nextUpdate(crl)) { - i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); - - if (i == 0) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - /* Ignore expiry of base CRL is delta is valid */ - if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { - if (!notify) - return 0; - ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - } - - if (notify) - ctx->current_crl = NULL; - - return 1; -} - -static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, - X509 **pissuer, int *pscore, unsigned int *preasons, - STACK_OF(X509_CRL) *crls) -{ - int i, crl_score, best_score = *pscore; - unsigned int reasons, best_reasons = 0; - X509 *x = ctx->current_cert; - X509_CRL *crl, *best_crl = NULL; - X509 *crl_issuer = NULL, *best_crl_issuer = NULL; - - for (i = 0; i < sk_X509_CRL_num(crls); i++) { - crl = sk_X509_CRL_value(crls, i); - reasons = *preasons; - crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); - if (crl_score < best_score || crl_score == 0) - continue; - /* If current CRL is equivalent use it if it is newer */ - if (crl_score == best_score && best_crl != NULL) { - int day, sec; - if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl), - X509_CRL_get_lastUpdate(crl)) == 0) - continue; - /* - * ASN1_TIME_diff never returns inconsistent signs for |day| - * and |sec|. - */ - if (day <= 0 && sec <= 0) - continue; - } - best_crl = crl; - best_crl_issuer = crl_issuer; - best_score = crl_score; - best_reasons = reasons; - } - - if (best_crl) { - if (*pcrl) - X509_CRL_free(*pcrl); - *pcrl = best_crl; - *pissuer = best_crl_issuer; - *pscore = best_score; - *preasons = best_reasons; - CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); - if (*pdcrl) { - X509_CRL_free(*pdcrl); - *pdcrl = NULL; - } - get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); - } - - if (best_score >= CRL_SCORE_VALID) - return 1; - - return 0; -} - -/* - * Compare two CRL extensions for delta checking purposes. They should be - * both present or both absent. If both present all fields must be identical. - */ - -static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) -{ - ASN1_OCTET_STRING *exta, *extb; - int i; - i = X509_CRL_get_ext_by_NID(a, nid, -1); - if (i >= 0) { - /* Can't have multiple occurrences */ - if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) - return 0; - exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); - } else - exta = NULL; - - i = X509_CRL_get_ext_by_NID(b, nid, -1); - - if (i >= 0) { - - if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) - return 0; - extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); - } else - extb = NULL; - - if (!exta && !extb) - return 1; - - if (!exta || !extb) - return 0; - - if (ASN1_OCTET_STRING_cmp(exta, extb)) - return 0; - - return 1; -} - -/* See if a base and delta are compatible */ - -static int check_delta_base(X509_CRL *delta, X509_CRL *base) -{ - /* Delta CRL must be a delta */ - if (!delta->base_crl_number) - return 0; - /* Base must have a CRL number */ - if (!base->crl_number) - return 0; - /* Issuer names must match */ - if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) - return 0; - /* AKID and IDP must match */ - if (!crl_extension_match(delta, base, NID_authority_key_identifier)) - return 0; - if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) - return 0; - /* Delta CRL base number must not exceed Full CRL number. */ - if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) - return 0; - /* Delta CRL number must exceed full CRL number */ - if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) - return 1; - return 0; -} - -/* - * For a given base CRL find a delta... maybe extend to delta scoring or - * retrieve a chain of deltas... - */ - -static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, - X509_CRL *base, STACK_OF(X509_CRL) *crls) -{ - X509_CRL *delta; - int i; - if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) - return; - if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) - return; - for (i = 0; i < sk_X509_CRL_num(crls); i++) { - delta = sk_X509_CRL_value(crls, i); - if (check_delta_base(delta, base)) { - if (check_crl_time(ctx, delta, 0)) - *pscore |= CRL_SCORE_TIME_DELTA; - CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); - *dcrl = delta; - return; - } - } - *dcrl = NULL; -} - -/* - * For a given CRL return how suitable it is for the supplied certificate - * 'x'. The return value is a mask of several criteria. If the issuer is not - * the certificate issuer this is returned in *pissuer. The reasons mask is - * also used to determine if the CRL is suitable: if no new reasons the CRL - * is rejected, otherwise reasons is updated. - */ - -static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, - unsigned int *preasons, X509_CRL *crl, X509 *x) -{ - - int crl_score = 0; - unsigned int tmp_reasons = *preasons, crl_reasons; - - /* First see if we can reject CRL straight away */ - - /* Invalid IDP cannot be processed */ - if (crl->idp_flags & IDP_INVALID) - return 0; - /* Reason codes or indirect CRLs need extended CRL support */ - if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { - if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) - return 0; - } else if (crl->idp_flags & IDP_REASONS) { - /* If no new reasons reject */ - if (!(crl->idp_reasons & ~tmp_reasons)) - return 0; - } - /* Don't process deltas at this stage */ - else if (crl->base_crl_number) - return 0; - /* If issuer name doesn't match certificate need indirect CRL */ - if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { - if (!(crl->idp_flags & IDP_INDIRECT)) - return 0; - } else - crl_score |= CRL_SCORE_ISSUER_NAME; - - if (!(crl->flags & EXFLAG_CRITICAL)) - crl_score |= CRL_SCORE_NOCRITICAL; - - /* Check expiry */ - if (check_crl_time(ctx, crl, 0)) - crl_score |= CRL_SCORE_TIME; - - /* Check authority key ID and locate certificate issuer */ - crl_akid_check(ctx, crl, pissuer, &crl_score); - - /* If we can't locate certificate issuer at this point forget it */ - - if (!(crl_score & CRL_SCORE_AKID)) - return 0; - - /* Check cert for matching CRL distribution points */ - - if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { - /* If no new reasons reject */ - if (!(crl_reasons & ~tmp_reasons)) - return 0; - tmp_reasons |= crl_reasons; - crl_score |= CRL_SCORE_SCOPE; - } - - *preasons = tmp_reasons; - - return crl_score; - -} - -static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, - X509 **pissuer, int *pcrl_score) -{ - X509 *crl_issuer = NULL; - X509_NAME *cnm = X509_CRL_get_issuer(crl); - int cidx = ctx->error_depth; - int i; - - if (cidx != sk_X509_num(ctx->chain) - 1) - cidx++; - - crl_issuer = sk_X509_value(ctx->chain, cidx); - - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { - *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT; - *pissuer = crl_issuer; - return; - } - } - - for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { - crl_issuer = sk_X509_value(ctx->chain, cidx); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) - continue; - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH; - *pissuer = crl_issuer; - return; - } - } - - /* Anything else needs extended CRL support */ - - if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) - return; - - /* - * Otherwise the CRL issuer is not on the path. Look for it in the set of - * untrusted certificates. - */ - for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { - crl_issuer = sk_X509_value(ctx->untrusted, i); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) - continue; - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { - *pissuer = crl_issuer; - *pcrl_score |= CRL_SCORE_AKID; - return; - } - } -} - -/* - * Check the path of a CRL issuer certificate. This creates a new - * X509_STORE_CTX and populates it with most of the parameters from the - * parent. This could be optimised somewhat since a lot of path checking will - * be duplicated by the parent, but this will rarely be used in practice. - */ - -static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) -{ - X509_STORE_CTX crl_ctx; - int ret; - /* Don't allow recursive CRL path validation */ - if (ctx->parent) - return 0; - if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) - return -1; - - crl_ctx.crls = ctx->crls; - /* Copy verify params across */ - X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); - - crl_ctx.parent = ctx; - crl_ctx.verify_cb = ctx->verify_cb; - - /* Verify CRL issuer */ - ret = X509_verify_cert(&crl_ctx); - - if (ret <= 0) - goto err; - - /* Check chain is acceptable */ - - ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); - err: - X509_STORE_CTX_cleanup(&crl_ctx); - return ret; -} - -/* - * RFC3280 says nothing about the relationship between CRL path and - * certificate path, which could lead to situations where a certificate could - * be revoked or validated by a CA not authorised to do so. RFC5280 is more - * strict and states that the two paths must end in the same trust anchor, - * though some discussions remain... until this is resolved we use the - * RFC5280 version - */ - -static int check_crl_chain(X509_STORE_CTX *ctx, - STACK_OF(X509) *cert_path, - STACK_OF(X509) *crl_path) -{ - X509 *cert_ta, *crl_ta; - cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); - crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); - if (!X509_cmp(cert_ta, crl_ta)) - return 1; - return 0; -} - -/*- - * Check for match between two dist point names: three separate cases. - * 1. Both are relative names and compare X509_NAME types. - * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. - * 3. Both are full names and compare two GENERAL_NAMES. - * 4. One is NULL: automatic match. - */ - -static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) -{ - X509_NAME *nm = NULL; - GENERAL_NAMES *gens = NULL; - GENERAL_NAME *gena, *genb; - int i, j; - if (!a || !b) - return 1; - if (a->type == 1) { - if (!a->dpname) - return 0; - /* Case 1: two X509_NAME */ - if (b->type == 1) { - if (!b->dpname) - return 0; - if (!X509_NAME_cmp(a->dpname, b->dpname)) - return 1; - else - return 0; - } - /* Case 2: set name and GENERAL_NAMES appropriately */ - nm = a->dpname; - gens = b->name.fullname; - } else if (b->type == 1) { - if (!b->dpname) - return 0; - /* Case 2: set name and GENERAL_NAMES appropriately */ - gens = a->name.fullname; - nm = b->dpname; - } - - /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ - if (nm) { - for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { - gena = sk_GENERAL_NAME_value(gens, i); - if (gena->type != GEN_DIRNAME) - continue; - if (!X509_NAME_cmp(nm, gena->d.directoryName)) - return 1; - } - return 0; - } - - /* Else case 3: two GENERAL_NAMES */ - - for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { - gena = sk_GENERAL_NAME_value(a->name.fullname, i); - for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { - genb = sk_GENERAL_NAME_value(b->name.fullname, j); - if (!GENERAL_NAME_cmp(gena, genb)) - return 1; - } - } - - return 0; - -} - -static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) -{ - int i; - X509_NAME *nm = X509_CRL_get_issuer(crl); - /* If no CRLissuer return is successful iff don't need a match */ - if (!dp->CRLissuer) - return ! !(crl_score & CRL_SCORE_ISSUER_NAME); - for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); - if (gen->type != GEN_DIRNAME) - continue; - if (!X509_NAME_cmp(gen->d.directoryName, nm)) - return 1; - } - return 0; -} - -/* Check CRLDP and IDP */ - -static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, - unsigned int *preasons) -{ - int i; - if (crl->idp_flags & IDP_ONLYATTR) - return 0; - if (x->ex_flags & EXFLAG_CA) { - if (crl->idp_flags & IDP_ONLYUSER) - return 0; - } else { - if (crl->idp_flags & IDP_ONLYCA) - return 0; - } - *preasons = crl->idp_reasons; - for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { - DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); - if (crldp_check_crlissuer(dp, crl, crl_score)) { - if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { - *preasons &= dp->dp_reasons; - return 1; - } - } - } - if ((!crl->idp || !crl->idp->distpoint) - && (crl_score & CRL_SCORE_ISSUER_NAME)) - return 1; - return 0; -} - -/* - * Retrieve CRL corresponding to current certificate. If deltas enabled try - * to find a delta CRL too - */ - -static int get_crl_delta(X509_STORE_CTX *ctx, - X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) -{ - int ok; - X509 *issuer = NULL; - int crl_score = 0; - unsigned int reasons; - X509_CRL *crl = NULL, *dcrl = NULL; - STACK_OF(X509_CRL) *skcrl; - X509_NAME *nm = X509_get_issuer_name(x); - reasons = ctx->current_reasons; - ok = get_crl_sk(ctx, &crl, &dcrl, - &issuer, &crl_score, &reasons, ctx->crls); - - if (ok) - goto done; - - /* Lookup CRLs from store */ - - skcrl = ctx->lookup_crls(ctx, nm); - - /* If no CRLs found and a near match from get_crl_sk use that */ - if (!skcrl && crl) - goto done; - - get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); - - sk_X509_CRL_pop_free(skcrl, X509_CRL_free); - - done: - - /* If we got any kind of CRL use it and return success */ - if (crl) { - ctx->current_issuer = issuer; - ctx->current_crl_score = crl_score; - ctx->current_reasons = reasons; - *pcrl = crl; - *pdcrl = dcrl; - return 1; - } - - return 0; -} - -/* Check CRL validity */ -static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) -{ - X509 *issuer = NULL; - EVP_PKEY *ikey = NULL; - int ok = 0, chnum, cnum; - cnum = ctx->error_depth; - chnum = sk_X509_num(ctx->chain) - 1; - /* if we have an alternative CRL issuer cert use that */ - if (ctx->current_issuer) - issuer = ctx->current_issuer; - - /* - * Else find CRL issuer: if not last certificate then issuer is next - * certificate in chain. - */ - else if (cnum < chnum) - issuer = sk_X509_value(ctx->chain, cnum + 1); - else { - issuer = sk_X509_value(ctx->chain, chnum); - /* If not self signed, can't check signature */ - if (!ctx->check_issued(ctx, issuer, issuer)) { - ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - - if (issuer) { - /* - * Skip most tests for deltas because they have already been done - */ - if (!crl->base_crl_number) { - /* Check for cRLSign bit if keyUsage present */ - if ((issuer->ex_flags & EXFLAG_KUSAGE) && - !(issuer->ex_kusage & KU_CRL_SIGN)) { - ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { - ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { - if (check_crl_path(ctx, ctx->current_issuer) <= 0) { - ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - - if (crl->idp_flags & IDP_INVALID) { - ctx->error = X509_V_ERR_INVALID_EXTENSION; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - - } - - if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { - ok = check_crl_time(ctx, crl, 1); - if (!ok) - goto err; - } - - /* Attempt to get issuer certificate public key */ - ikey = X509_get_pubkey(issuer); - - if (!ikey) { - ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } else { - int rv; - rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags); - if (rv != X509_V_OK) { - ctx->error = rv; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - /* Verify CRL signature */ - if (X509_CRL_verify(crl, ikey) <= 0) { - ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; - ok = ctx->verify_cb(0, ctx); - if (!ok) - goto err; - } - } - } - - ok = 1; - - err: - EVP_PKEY_free(ikey); - return ok; -} - -/* Check certificate against CRL */ -static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) -{ - int ok; - X509_REVOKED *rev; - /* - * The rules changed for this... previously if a CRL contained unhandled - * critical extensions it could still be used to indicate a certificate - * was revoked. This has since been changed since critical extension can - * change the meaning of CRL entries. - */ - if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) - && (crl->flags & EXFLAG_CRITICAL)) { - ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; - ok = ctx->verify_cb(0, ctx); - if (!ok) - return 0; - } - /* - * Look for serial number of certificate in CRL If found make sure reason - * is not removeFromCRL. - */ - if (X509_CRL_get0_by_cert(crl, &rev, x)) { - if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) - return 2; - ctx->error = X509_V_ERR_CERT_REVOKED; - ok = ctx->verify_cb(0, ctx); - if (!ok) - return 0; - } - - return 1; -} - -static int check_policy(X509_STORE_CTX *ctx) -{ - int ret; - if (ctx->parent) - return 1; - ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, - ctx->param->policies, ctx->param->flags); - if (ret == 0) { - X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); - ctx->error = X509_V_ERR_OUT_OF_MEM; - return 0; - } - /* Invalid or inconsistent extensions */ - if (ret == -1) { - /* - * Locate certificates with bad extensions and notify callback. - */ - X509 *x; - int i; - for (i = 1; i < sk_X509_num(ctx->chain); i++) { - x = sk_X509_value(ctx->chain, i); - if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) - continue; - ctx->current_cert = x; - ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - return 1; - } - if (ret == -2) { - ctx->current_cert = NULL; - ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; - return ctx->verify_cb(0, ctx); - } - - if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { - ctx->current_cert = NULL; - /* - * Verification errors need to be "sticky", a callback may have allowed - * an SSL handshake to continue despite an error, and we must then - * remain in an error state. Therefore, we MUST NOT clear earlier - * verification errors by setting the error to X509_V_OK. - */ - if (!ctx->verify_cb(2, ctx)) - return 0; - } - - return 1; -} - -static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) -{ - time_t *ptime; - int i; - - if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) - ptime = &ctx->param->check_time; - else - ptime = NULL; - - i = X509_cmp_time(X509_get_notBefore(x), ptime); - if (i == 0) { - ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (i > 0) { - ctx->error = X509_V_ERR_CERT_NOT_YET_VALID; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - i = X509_cmp_time(X509_get_notAfter(x), ptime); - if (i == 0) { - ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - if (i < 0) { - ctx->error = X509_V_ERR_CERT_HAS_EXPIRED; - ctx->current_cert = x; - if (!ctx->verify_cb(0, ctx)) - return 0; - } - - return 1; -} - -static int internal_verify(X509_STORE_CTX *ctx) -{ - int ok = 0, n; - X509 *xs, *xi; - EVP_PKEY *pkey = NULL; - int (*cb) (int xok, X509_STORE_CTX *xctx); - - cb = ctx->verify_cb; - - n = sk_X509_num(ctx->chain); - ctx->error_depth = n - 1; - n--; - xi = sk_X509_value(ctx->chain, n); - - if (ctx->check_issued(ctx, xi, xi)) - xs = xi; - else { - if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) { - xs = xi; - goto check_cert; - } - if (n <= 0) { - ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; - ctx->current_cert = xi; - ok = cb(0, ctx); - goto end; - } else { - n--; - ctx->error_depth = n; - xs = sk_X509_value(ctx->chain, n); - } - } - -/* ctx->error=0; not needed */ - while (n >= 0) { - ctx->error_depth = n; - - /* - * Skip signature check for self signed certificates unless - * explicitly asked for. It doesn't add any security and just wastes - * time. - */ - if (!xs->valid - && (xs != xi - || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) { - if ((pkey = X509_get_pubkey(xi)) == NULL) { - ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; - ctx->current_cert = xi; - ok = (*cb) (0, ctx); - if (!ok) - goto end; - } else if (X509_verify(xs, pkey) <= 0) { - ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; - ctx->current_cert = xs; - ok = (*cb) (0, ctx); - if (!ok) { - EVP_PKEY_free(pkey); - goto end; - } - } - EVP_PKEY_free(pkey); - pkey = NULL; - } - - xs->valid = 1; - - check_cert: - ok = check_cert_time(ctx, xs); - if (!ok) - goto end; - - /* The last error (if any) is still in the error value */ - ctx->current_issuer = xi; - ctx->current_cert = xs; - ok = (*cb) (1, ctx); - if (!ok) - goto end; - - n--; - if (n >= 0) { - xi = xs; - xs = sk_X509_value(ctx->chain, n); - } - } - ok = 1; - end: - return ok; -} - -int X509_cmp_current_time(const ASN1_TIME *ctm) -{ - return X509_cmp_time(ctm, NULL); -} - -int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) -{ - static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1; - static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1; - ASN1_TIME *asn1_cmp_time = NULL; - int i, day, sec, ret = 0; - - /* - * Note that ASN.1 allows much more slack in the time format than RFC5280. - * In RFC5280, the representation is fixed: - * UTCTime: YYMMDDHHMMSSZ - * GeneralizedTime: YYYYMMDDHHMMSSZ - * - * We do NOT currently enforce the following RFC 5280 requirement: - * "CAs conforming to this profile MUST always encode certificate - * validity dates through the year 2049 as UTCTime; certificate validity - * dates in 2050 or later MUST be encoded as GeneralizedTime." - */ - switch (ctm->type) { - case V_ASN1_UTCTIME: - if (ctm->length != (int)(utctime_length)) - return 0; - break; - case V_ASN1_GENERALIZEDTIME: - if (ctm->length != (int)(generalizedtime_length)) - return 0; - break; - default: - return 0; - } - - /** - * Verify the format: the ASN.1 functions we use below allow a more - * flexible format than what's mandated by RFC 5280. - * Digit and date ranges will be verified in the conversion methods. - */ - for (i = 0; i < ctm->length - 1; i++) { - if (!isdigit(ctm->data[i])) - return 0; - } - if (ctm->data[ctm->length - 1] != 'Z') - return 0; - - /* - * There is ASN1_UTCTIME_cmp_time_t but no - * ASN1_GENERALIZEDTIME_cmp_time_t or ASN1_TIME_cmp_time_t, - * so we go through ASN.1 - */ - asn1_cmp_time = X509_time_adj(NULL, 0, cmp_time); - if (asn1_cmp_time == NULL) - goto err; - if (!ASN1_TIME_diff(&day, &sec, ctm, asn1_cmp_time)) - goto err; - - /* - * X509_cmp_time comparison is <=. - * The return value 0 is reserved for errors. - */ - ret = (day >= 0 && sec >= 0) ? -1 : 1; - - err: - ASN1_TIME_free(asn1_cmp_time); - return ret; -} - -ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) -{ - return X509_time_adj(s, adj, NULL); -} - -ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) -{ - return X509_time_adj_ex(s, 0, offset_sec, in_tm); -} - -ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, - int offset_day, long offset_sec, time_t *in_tm) -{ - time_t t; - - if (in_tm) - t = *in_tm; - else - time(&t); - - if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) { - if (s->type == V_ASN1_UTCTIME) - return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); - if (s->type == V_ASN1_GENERALIZEDTIME) - return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); - } - return ASN1_TIME_adj(s, t, offset_day, offset_sec); -} - -int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) -{ - EVP_PKEY *ktmp = NULL, *ktmp2; - int i, j; - - if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) - return 1; - - for (i = 0; i < sk_X509_num(chain); i++) { - ktmp = X509_get_pubkey(sk_X509_value(chain, i)); - if (ktmp == NULL) { - X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, - X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); - return 0; - } - if (!EVP_PKEY_missing_parameters(ktmp)) - break; - else { - EVP_PKEY_free(ktmp); - ktmp = NULL; - } - } - if (ktmp == NULL) { - X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, - X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); - return 0; - } - - /* first, populate the other certs */ - for (j = i - 1; j >= 0; j--) { - ktmp2 = X509_get_pubkey(sk_X509_value(chain, j)); - EVP_PKEY_copy_parameters(ktmp2, ktmp); - EVP_PKEY_free(ktmp2); - } - - if (pkey != NULL) - EVP_PKEY_copy_parameters(pkey, ktmp); - EVP_PKEY_free(ktmp); - return 1; -} - -/* Make a delta CRL as the diff between two full CRLs */ - -X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, - EVP_PKEY *skey, const EVP_MD *md, unsigned int flags) -{ - X509_CRL *crl = NULL; - int i; - STACK_OF(X509_REVOKED) *revs = NULL; - /* CRLs can't be delta already */ - if (base->base_crl_number || newer->base_crl_number) { - X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_ALREADY_DELTA); - return NULL; - } - /* Base and new CRL must have a CRL number */ - if (!base->crl_number || !newer->crl_number) { - X509err(X509_F_X509_CRL_DIFF, X509_R_NO_CRL_NUMBER); - return NULL; - } - /* Issuer names must match */ - if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) { - X509err(X509_F_X509_CRL_DIFF, X509_R_ISSUER_MISMATCH); - return NULL; - } - /* AKID and IDP must match */ - if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { - X509err(X509_F_X509_CRL_DIFF, X509_R_AKID_MISMATCH); - return NULL; - } - if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { - X509err(X509_F_X509_CRL_DIFF, X509_R_IDP_MISMATCH); - return NULL; - } - /* Newer CRL number must exceed full CRL number */ - if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) { - X509err(X509_F_X509_CRL_DIFF, X509_R_NEWER_CRL_NOT_NEWER); - return NULL; - } - /* CRLs must verify */ - if (skey && (X509_CRL_verify(base, skey) <= 0 || - X509_CRL_verify(newer, skey) <= 0)) { - X509err(X509_F_X509_CRL_DIFF, X509_R_CRL_VERIFY_FAILURE); - return NULL; - } - /* Create new CRL */ - crl = X509_CRL_new(); - if (!crl || !X509_CRL_set_version(crl, 1)) - goto memerr; - /* Set issuer name */ - if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) - goto memerr; - - if (!X509_CRL_set_lastUpdate(crl, X509_CRL_get_lastUpdate(newer))) - goto memerr; - if (!X509_CRL_set_nextUpdate(crl, X509_CRL_get_nextUpdate(newer))) - goto memerr; - - /* Set base CRL number: must be critical */ - - if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) - goto memerr; - - /* - * Copy extensions across from newest CRL to delta: this will set CRL - * number to correct value too. - */ - - for (i = 0; i < X509_CRL_get_ext_count(newer); i++) { - X509_EXTENSION *ext; - ext = X509_CRL_get_ext(newer, i); - if (!X509_CRL_add_ext(crl, ext, -1)) - goto memerr; - } - - /* Go through revoked entries, copying as needed */ - - revs = X509_CRL_get_REVOKED(newer); - - for (i = 0; i < sk_X509_REVOKED_num(revs); i++) { - X509_REVOKED *rvn, *rvtmp; - rvn = sk_X509_REVOKED_value(revs, i); - /* - * Add only if not also in base. TODO: need something cleverer here - * for some more complex CRLs covering multiple CAs. - */ - if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) { - rvtmp = X509_REVOKED_dup(rvn); - if (!rvtmp) - goto memerr; - if (!X509_CRL_add0_revoked(crl, rvtmp)) { - X509_REVOKED_free(rvtmp); - goto memerr; - } - } - } - /* TODO: optionally prune deleted entries */ - - if (skey && md && !X509_CRL_sign(crl, skey, md)) - goto memerr; - - return crl; - - memerr: - X509err(X509_F_X509_CRL_DIFF, ERR_R_MALLOC_FAILURE); - if (crl) - X509_CRL_free(crl); - return NULL; -} - -int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func) -{ - /* - * This function is (usually) called only once, by - * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). - */ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp, - new_func, dup_func, free_func); -} - -int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) -{ - return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); -} - -void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) -{ - return CRYPTO_get_ex_data(&ctx->ex_data, idx); -} - -int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) -{ - return ctx->error; -} - -void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) -{ - ctx->error = err; -} - -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) -{ - return ctx->error_depth; -} - -X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) -{ - return ctx->current_cert; -} - -STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) -{ - return ctx->chain; -} - -STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) -{ - if (!ctx->chain) - return NULL; - return X509_chain_up_ref(ctx->chain); -} - -X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) -{ - return ctx->current_issuer; -} - -X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) -{ - return ctx->current_crl; -} - -X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) -{ - return ctx->parent; -} - -void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) -{ - ctx->cert = x; -} - -void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -{ - ctx->untrusted = sk; -} - -void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) -{ - ctx->crls = sk; -} - -int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) -{ - return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); -} - -int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) -{ - return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); -} - -/* - * This function is used to set the X509_STORE_CTX purpose and trust values. - * This is intended to be used when another structure has its own trust and - * purpose values which (if set) will be inherited by the ctx. If they aren't - * set then we will usually have a default purpose in mind which should then - * be used to set the trust value. An example of this is SSL use: an SSL - * structure will have its own purpose and trust settings which the - * application can set: if they aren't set then we use the default of SSL - * client/server. - */ - -int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, - int purpose, int trust) -{ - int idx; - /* If purpose not set use default */ - if (!purpose) - purpose = def_purpose; - /* If we have a purpose then check it is valid */ - if (purpose) { - X509_PURPOSE *ptmp; - idx = X509_PURPOSE_get_by_id(purpose); - if (idx == -1) { - X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, - X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - ptmp = X509_PURPOSE_get0(idx); - if (ptmp->trust == X509_TRUST_DEFAULT) { - idx = X509_PURPOSE_get_by_id(def_purpose); - if (idx == -1) { - X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, - X509_R_UNKNOWN_PURPOSE_ID); - return 0; - } - ptmp = X509_PURPOSE_get0(idx); - } - /* If trust not set then get from purpose default */ - if (!trust) - trust = ptmp->trust; - } - if (trust) { - idx = X509_TRUST_get_by_id(trust); - if (idx == -1) { - X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, - X509_R_UNKNOWN_TRUST_ID); - return 0; - } - } - - if (purpose && !ctx->param->purpose) - ctx->param->purpose = purpose; - if (trust && !ctx->param->trust) - ctx->param->trust = trust; - return 1; -} - -X509_STORE_CTX *X509_STORE_CTX_new(void) -{ - X509_STORE_CTX *ctx; - ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); - if (!ctx) { - X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE); - return NULL; - } - memset(ctx, 0, sizeof(X509_STORE_CTX)); - return ctx; -} - -void X509_STORE_CTX_free(X509_STORE_CTX *ctx) -{ - if (!ctx) - return; - X509_STORE_CTX_cleanup(ctx); - OPENSSL_free(ctx); -} - -int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, - STACK_OF(X509) *chain) -{ - int ret = 1; - ctx->ctx = store; - ctx->current_method = 0; - ctx->cert = x509; - ctx->untrusted = chain; - ctx->crls = NULL; - ctx->last_untrusted = 0; - ctx->other_ctx = NULL; - ctx->valid = 0; - ctx->chain = NULL; - ctx->error = 0; - ctx->explicit_policy = 0; - ctx->error_depth = 0; - ctx->current_cert = NULL; - ctx->current_issuer = NULL; - ctx->current_crl = NULL; - ctx->current_crl_score = 0; - ctx->current_reasons = 0; - ctx->tree = NULL; - ctx->parent = NULL; - /* Zero ex_data to make sure we're cleanup-safe */ - memset(&ctx->ex_data, 0, sizeof(ctx->ex_data)); - - ctx->param = X509_VERIFY_PARAM_new(); - if (!ctx->param) { - X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); - return 0; - } - - /* - * Inherit callbacks and flags from X509_STORE if not set use defaults. - */ - if (store) - ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); - else - ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE; - - if (store) { - ctx->verify_cb = store->verify_cb; - /* Seems to always be 0 in OpenSSL, else must be idempotent */ - ctx->cleanup = store->cleanup; - } else - ctx->cleanup = 0; - - if (ret) - ret = X509_VERIFY_PARAM_inherit(ctx->param, - X509_VERIFY_PARAM_lookup("default")); - - if (ret == 0) { - X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); - goto err; - } - - if (store && store->check_issued) - ctx->check_issued = store->check_issued; - else - ctx->check_issued = check_issued; - - if (store && store->get_issuer) - ctx->get_issuer = store->get_issuer; - else - ctx->get_issuer = X509_STORE_CTX_get1_issuer; - - if (store && store->verify_cb) - ctx->verify_cb = store->verify_cb; - else - ctx->verify_cb = null_callback; - - if (store && store->verify) - ctx->verify = store->verify; - else - ctx->verify = internal_verify; - - if (store && store->check_revocation) - ctx->check_revocation = store->check_revocation; - else - ctx->check_revocation = check_revocation; - - if (store && store->get_crl) - ctx->get_crl = store->get_crl; - else - ctx->get_crl = NULL; - - if (store && store->check_crl) - ctx->check_crl = store->check_crl; - else - ctx->check_crl = check_crl; - - if (store && store->cert_crl) - ctx->cert_crl = store->cert_crl; - else - ctx->cert_crl = cert_crl; - - if (store && store->lookup_certs) - ctx->lookup_certs = store->lookup_certs; - else - ctx->lookup_certs = X509_STORE_get1_certs; - - if (store && store->lookup_crls) - ctx->lookup_crls = store->lookup_crls; - else - ctx->lookup_crls = X509_STORE_get1_crls; - - ctx->check_policy = check_policy; - - if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, - &ctx->ex_data)) - return 1; - X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); - - err: - /* - * On error clean up allocated storage, if the store context was not - * allocated with X509_STORE_CTX_new() this is our last chance to do so. - */ - X509_STORE_CTX_cleanup(ctx); - return 0; -} - -/* - * Set alternative lookup method: just a STACK of trusted certificates. This - * avoids X509_STORE nastiness where it isn't needed. - */ - -void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) -{ - ctx->other_ctx = sk; - ctx->get_issuer = get_issuer_sk; -} - -void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) -{ - /* - * We need to be idempotent because, unfortunately, free() also calls - * cleanup(), so the natural call sequence new(), init(), cleanup(), free() - * calls cleanup() for the same object twice! Thus we must zero the - * pointers below after they're freed! - */ - /* Seems to always be 0 in OpenSSL, do this at most once. */ - if (ctx->cleanup != NULL) { - ctx->cleanup(ctx); - ctx->cleanup = NULL; - } - if (ctx->param != NULL) { - if (ctx->parent == NULL) - X509_VERIFY_PARAM_free(ctx->param); - ctx->param = NULL; - } - if (ctx->tree != NULL) { - X509_policy_tree_free(ctx->tree); - ctx->tree = NULL; - } - if (ctx->chain != NULL) { - sk_X509_pop_free(ctx->chain, X509_free); - ctx->chain = NULL; - } - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); - memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); -} - -void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) -{ - X509_VERIFY_PARAM_set_depth(ctx->param, depth); -} - -void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) -{ - X509_VERIFY_PARAM_set_flags(ctx->param, flags); -} - -void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, - time_t t) -{ - X509_VERIFY_PARAM_set_time(ctx->param, t); -} - -void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, - int (*verify_cb) (int, X509_STORE_CTX *)) -{ - ctx->verify_cb = verify_cb; -} - -X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) -{ - return ctx->tree; -} - -int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) -{ - return ctx->explicit_policy; -} - -int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) -{ - const X509_VERIFY_PARAM *param; - param = X509_VERIFY_PARAM_lookup(name); - if (!param) - return 0; - return X509_VERIFY_PARAM_inherit(ctx->param, param); -} - -X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) -{ - return ctx->param; -} - -void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) -{ - if (ctx->param) - X509_VERIFY_PARAM_free(ctx->param); - ctx->param = param; -} - -IMPLEMENT_STACK_OF(X509) - -IMPLEMENT_ASN1_SET_OF(X509) - -IMPLEMENT_STACK_OF(X509_NAME) - -IMPLEMENT_STACK_OF(X509_ATTRIBUTE) - -IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE) -/* x509_vpm.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2004. - */ -/* ==================================================================== - * Copyright (c) 2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include - -// #include "cryptlib.h" -// #include "crypto.h" -// #include "lhash.h" -// #include "buffer.h" -// #include "x509.h" -// #include "x509v3.h" - -// #include "vpm_int.h" - -/* X509_VERIFY_PARAM functions */ - -#define SET_HOST 0 -#define ADD_HOST 1 - -static char *str_copy(const char *s) -{ - return OPENSSL_strdup(s); -} - -static void str_free(char *s) -{ - OPENSSL_free(s); -} - -#define string_stack_free(sk) sk_OPENSSL_STRING_pop_free(sk, str_free) - -static int int_x509_param_set_hosts(X509_VERIFY_PARAM_ID *id, int mode, - const char *name, size_t namelen) -{ - char *copy; - - /* - * Refuse names with embedded NUL bytes, except perhaps as final byte. - * XXX: Do we need to push an error onto the error stack? - */ - if (namelen == 0 || name == NULL) - namelen = name ? strlen(name) : 0; - else if (name && memchr(name, '\0', namelen > 1 ? namelen - 1 : namelen)) - return 0; - if (namelen > 0 && name[namelen - 1] == '\0') - --namelen; - - if (mode == SET_HOST && id->hosts) { - string_stack_free(id->hosts); - id->hosts = NULL; - } - if (name == NULL || namelen == 0) - return 1; - - copy = BUF_strndup(name, namelen); - if (copy == NULL) - return 0; - - if (id->hosts == NULL && - (id->hosts = sk_OPENSSL_STRING_new_null()) == NULL) { - OPENSSL_free(copy); - return 0; - } - - if (!sk_OPENSSL_STRING_push(id->hosts, copy)) { - OPENSSL_free(copy); - if (sk_OPENSSL_STRING_num(id->hosts) == 0) { - sk_OPENSSL_STRING_free(id->hosts); - id->hosts = NULL; - } - return 0; - } - - return 1; -} - -static void x509_verify_param_zero(X509_VERIFY_PARAM *param) -{ - X509_VERIFY_PARAM_ID *paramid; - if (!param) - return; - param->name = NULL; - param->purpose = 0; - param->trust = 0; - /* - * param->inh_flags = X509_VP_FLAG_DEFAULT; - */ - param->inh_flags = 0; - param->flags = 0; - param->depth = -1; - if (param->policies) { - sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); - param->policies = NULL; - } - paramid = param->id; - if (paramid->hosts) { - string_stack_free(paramid->hosts); - paramid->hosts = NULL; - } - if (paramid->peername) - OPENSSL_free(paramid->peername); - paramid->peername = NULL; - if (paramid->email) { - OPENSSL_free(paramid->email); - paramid->email = NULL; - paramid->emaillen = 0; - } - if (paramid->ip) { - OPENSSL_free(paramid->ip); - paramid->ip = NULL; - paramid->iplen = 0; - } -} - -X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) -{ - X509_VERIFY_PARAM *param; - X509_VERIFY_PARAM_ID *paramid; - - param = OPENSSL_malloc(sizeof(*param)); - if (!param) - return NULL; - memset(param, 0, sizeof(*param)); - - paramid = OPENSSL_malloc(sizeof(*paramid)); - if (!paramid) { - OPENSSL_free(param); - return NULL; - } - memset(paramid, 0, sizeof(*paramid)); - /* Exotic platforms may have non-zero bit representation of NULL */ - paramid->hosts = NULL; - paramid->peername = NULL; - paramid->email = NULL; - paramid->ip = NULL; - - param->id = paramid; - x509_verify_param_zero(param); - return param; -} - -void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) -{ - if (param == NULL) - return; - x509_verify_param_zero(param); - OPENSSL_free(param->id); - OPENSSL_free(param); -} - -/*- - * This function determines how parameters are "inherited" from one structure - * to another. There are several different ways this can happen. - * - * 1. If a child structure needs to have its values initialized from a parent - * they are simply copied across. For example SSL_CTX copied to SSL. - * 2. If the structure should take on values only if they are currently unset. - * For example the values in an SSL structure will take appropriate value - * for SSL servers or clients but only if the application has not set new - * ones. - * - * The "inh_flags" field determines how this function behaves. - * - * Normally any values which are set in the default are not copied from the - * destination and verify flags are ORed together. - * - * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied - * to the destination. Effectively the values in "to" become default values - * which will be used only if nothing new is set in "from". - * - * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether - * they are set or not. Flags is still Ored though. - * - * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead - * of ORed. - * - * If X509_VP_FLAG_LOCKED is set then no values are copied. - * - * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed - * after the next call. - */ - -/* Macro to test if a field should be copied from src to dest */ - -#define test_x509_verify_param_copy(field, def) \ - (to_overwrite || \ - ((src->field != def) && (to_default || (dest->field == def)))) - -/* As above but for ID fields */ - -#define test_x509_verify_param_copy_id(idf, def) \ - test_x509_verify_param_copy(id->idf, def) - -/* Macro to test and copy a field if necessary */ - -#define x509_verify_param_copy(field, def) \ - if (test_x509_verify_param_copy(field, def)) \ - dest->field = src->field - -int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, - const X509_VERIFY_PARAM *src) -{ - unsigned long inh_flags; - int to_default, to_overwrite; - X509_VERIFY_PARAM_ID *id; - if (!src) - return 1; - id = src->id; - inh_flags = dest->inh_flags | src->inh_flags; - - if (inh_flags & X509_VP_FLAG_ONCE) - dest->inh_flags = 0; - - if (inh_flags & X509_VP_FLAG_LOCKED) - return 1; - - if (inh_flags & X509_VP_FLAG_DEFAULT) - to_default = 1; - else - to_default = 0; - - if (inh_flags & X509_VP_FLAG_OVERWRITE) - to_overwrite = 1; - else - to_overwrite = 0; - - x509_verify_param_copy(purpose, 0); - x509_verify_param_copy(trust, 0); - x509_verify_param_copy(depth, -1); - - /* If overwrite or check time not set, copy across */ - - if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { - dest->check_time = src->check_time; - dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; - /* Don't need to copy flag: that is done below */ - } - - if (inh_flags & X509_VP_FLAG_RESET_FLAGS) - dest->flags = 0; - - dest->flags |= src->flags; - - if (test_x509_verify_param_copy(policies, NULL)) { - if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) - return 0; - } - - /* Copy the host flags if and only if we're copying the host list */ - if (test_x509_verify_param_copy_id(hosts, NULL)) { - if (dest->id->hosts) { - string_stack_free(dest->id->hosts); - dest->id->hosts = NULL; - } - if (id->hosts) { - dest->id->hosts = - sk_OPENSSL_STRING_deep_copy(id->hosts, str_copy, str_free); - if (dest->id->hosts == NULL) - return 0; - dest->id->hostflags = id->hostflags; - } - } - - if (test_x509_verify_param_copy_id(email, NULL)) { - if (!X509_VERIFY_PARAM_set1_email(dest, id->email, id->emaillen)) - return 0; - } - - if (test_x509_verify_param_copy_id(ip, NULL)) { - if (!X509_VERIFY_PARAM_set1_ip(dest, id->ip, id->iplen)) - return 0; - } - - return 1; -} - -int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, - const X509_VERIFY_PARAM *from) -{ - unsigned long save_flags = to->inh_flags; - int ret; - to->inh_flags |= X509_VP_FLAG_DEFAULT; - ret = X509_VERIFY_PARAM_inherit(to, from); - to->inh_flags = save_flags; - return ret; -} - -static int int_x509_param_set1(char **pdest, size_t *pdestlen, - const char *src, size_t srclen) -{ - void *tmp; - if (src) { - if (srclen == 0) { - tmp = BUF_strdup(src); - srclen = strlen(src); - } else - tmp = BUF_memdup(src, srclen); - if (!tmp) - return 0; - } else { - tmp = NULL; - srclen = 0; - } - if (*pdest) - OPENSSL_free(*pdest); - *pdest = tmp; - if (pdestlen) - *pdestlen = srclen; - return 1; -} - -int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) -{ - if (param->name) - OPENSSL_free(param->name); - param->name = BUF_strdup(name); - if (param->name) - return 1; - return 0; -} - -int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) -{ - param->flags |= flags; - if (flags & X509_V_FLAG_POLICY_MASK) - param->flags |= X509_V_FLAG_POLICY_CHECK; - return 1; -} - -int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, - unsigned long flags) -{ - param->flags &= ~flags; - return 1; -} - -unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) -{ - return param->flags; -} - -int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) -{ - return X509_PURPOSE_set(¶m->purpose, purpose); -} - -int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) -{ - return X509_TRUST_set(¶m->trust, trust); -} - -void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) -{ - param->depth = depth; -} - -void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) -{ - param->check_time = t; - param->flags |= X509_V_FLAG_USE_CHECK_TIME; -} - -int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, - ASN1_OBJECT *policy) -{ - if (!param->policies) { - param->policies = sk_ASN1_OBJECT_new_null(); - if (!param->policies) - return 0; - } - if (!sk_ASN1_OBJECT_push(param->policies, policy)) - return 0; - return 1; -} - -int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, - STACK_OF(ASN1_OBJECT) *policies) -{ - int i; - ASN1_OBJECT *oid, *doid; - if (!param) - return 0; - if (param->policies) - sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); - - if (!policies) { - param->policies = NULL; - return 1; - } - - param->policies = sk_ASN1_OBJECT_new_null(); - if (!param->policies) - return 0; - - for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { - oid = sk_ASN1_OBJECT_value(policies, i); - doid = OBJ_dup(oid); - if (!doid) - return 0; - if (!sk_ASN1_OBJECT_push(param->policies, doid)) { - ASN1_OBJECT_free(doid); - return 0; - } - } - param->flags |= X509_V_FLAG_POLICY_CHECK; - return 1; -} - -int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen) -{ - return int_x509_param_set_hosts(param->id, SET_HOST, name, namelen); -} - -int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen) -{ - return int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen); -} - -void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, - unsigned int flags) -{ - param->id->hostflags = flags; -} - -char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *param) -{ - return param->id->peername; -} - -int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, - const char *email, size_t emaillen) -{ - return int_x509_param_set1(¶m->id->email, ¶m->id->emaillen, - email, emaillen); -} - -int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, - const unsigned char *ip, size_t iplen) -{ - if (iplen != 0 && iplen != 4 && iplen != 16) - return 0; - return int_x509_param_set1((char **)¶m->id->ip, ¶m->id->iplen, - (char *)ip, iplen); -} - -int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc) -{ - unsigned char ipout[16]; - size_t iplen; - - iplen = (size_t)a2i_ipadd(ipout, ipasc); - if (iplen == 0) - return 0; - return X509_VERIFY_PARAM_set1_ip(param, ipout, iplen); -} - -int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) -{ - return param->depth; -} - -const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param) -{ - return param->name; -} - -static X509_VERIFY_PARAM_ID _empty_id = { NULL, 0U, NULL, NULL, 0, NULL, 0 }; - -#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id - -/* - * Default verify parameters: these are used for various applications and can - * be overridden by the user specified table. NB: the 'name' field *must* be - * in alphabetical order because it will be searched using OBJ_search. - */ - -static const X509_VERIFY_PARAM default_table[] = { - { - "default", /* X509 default parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - 0, /* purpose */ - 0, /* trust */ - 100, /* depth */ - NULL, /* policies */ - vpm_empty_id}, - { - "pkcs7", /* S/MIME sign parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - X509_PURPOSE_SMIME_SIGN, /* purpose */ - X509_TRUST_EMAIL, /* trust */ - -1, /* depth */ - NULL, /* policies */ - vpm_empty_id}, - { - "smime_sign", /* S/MIME sign parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - X509_PURPOSE_SMIME_SIGN, /* purpose */ - X509_TRUST_EMAIL, /* trust */ - -1, /* depth */ - NULL, /* policies */ - vpm_empty_id}, - { - "ssl_client", /* SSL/TLS client parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - X509_PURPOSE_SSL_CLIENT, /* purpose */ - X509_TRUST_SSL_CLIENT, /* trust */ - -1, /* depth */ - NULL, /* policies */ - vpm_empty_id}, - { - "ssl_server", /* SSL/TLS server parameters */ - 0, /* Check time */ - 0, /* internal flags */ - 0, /* flags */ - X509_PURPOSE_SSL_SERVER, /* purpose */ - X509_TRUST_SSL_SERVER, /* trust */ - -1, /* depth */ - NULL, /* policies */ - vpm_empty_id} -}; - -static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; - -static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) -{ - return strcmp(a->name, b->name); -} - -DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); -IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); - -static int param_cmp(const X509_VERIFY_PARAM *const *a, - const X509_VERIFY_PARAM *const *b) -{ - return strcmp((*a)->name, (*b)->name); -} - -int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) -{ - int idx; - X509_VERIFY_PARAM *ptmp; - if (!param_table) { - param_table = sk_X509_VERIFY_PARAM_new(param_cmp); - if (!param_table) - return 0; - } else { - idx = sk_X509_VERIFY_PARAM_find(param_table, param); - if (idx != -1) { - ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); - X509_VERIFY_PARAM_free(ptmp); - (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); - } - } - if (!sk_X509_VERIFY_PARAM_push(param_table, param)) - return 0; - return 1; -} - -int X509_VERIFY_PARAM_get_count(void) -{ - int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); - if (param_table) - num += sk_X509_VERIFY_PARAM_num(param_table); - return num; -} - -const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id) -{ - int num = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); - if (id < num) - return default_table + id; - return sk_X509_VERIFY_PARAM_value(param_table, id - num); -} - -const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) -{ - int idx; - X509_VERIFY_PARAM pm; - - pm.name = (char *)name; - if (param_table) { - idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); - if (idx != -1) - return sk_X509_VERIFY_PARAM_value(param_table, idx); - } - return OBJ_bsearch_table(&pm, default_table, - sizeof(default_table) / - sizeof(X509_VERIFY_PARAM)); -} - -void X509_VERIFY_PARAM_table_cleanup(void) -{ - if (param_table) - sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free); - param_table = NULL; -} diff --git a/Sources/COpenSSL/x509_vfy.h b/Sources/COpenSSL/x509_vfy.h deleted file mode 100644 index 76b4ffdc..00000000 --- a/Sources/COpenSSL/x509_vfy.h +++ /dev/null @@ -1,652 +0,0 @@ -/* crypto/x509/x509_vfy.h */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#ifndef HEADER_X509_H -# include "x509.h" -/* - * openssl/x509.h ends up #include-ing this file at about the only - * appropriate moment. - */ -#endif - -#ifndef HEADER_X509_VFY_H -# define HEADER_X509_VFY_H - -# include "opensslconf.h" -# ifndef OPENSSL_NO_LHASH -# include "lhash.h" -# endif -# include "bio.h" -# include "crypto.h" -# include "symhacks.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# if 0 -/* Outer object */ -typedef struct x509_hash_dir_st { - int num_dirs; - char **dirs; - int *dirs_type; - int num_dirs_alloced; -} X509_HASH_DIR_CTX; -# endif - -typedef struct x509_file_st { - int num_paths; /* number of paths to files or directories */ - int num_alloced; - char **paths; /* the list of paths or directories */ - int *path_type; -} X509_CERT_FILE_CTX; - -/*******************************/ -/*- -SSL_CTX -> X509_STORE - -> X509_LOOKUP - ->X509_LOOKUP_METHOD - -> X509_LOOKUP - ->X509_LOOKUP_METHOD - -SSL -> X509_STORE_CTX - ->X509_STORE - -The X509_STORE holds the tables etc for verification stuff. -A X509_STORE_CTX is used while validating a single certificate. -The X509_STORE has X509_LOOKUPs for looking up certs. -The X509_STORE then calls a function to actually verify the -certificate chain. -*/ - -# define X509_LU_RETRY -1 -# define X509_LU_FAIL 0 -# define X509_LU_X509 1 -# define X509_LU_CRL 2 -# define X509_LU_PKEY 3 - -typedef struct x509_object_st { - /* one of the above types */ - int type; - union { - char *ptr; - X509 *x509; - X509_CRL *crl; - EVP_PKEY *pkey; - } data; -} X509_OBJECT; - -typedef struct x509_lookup_st X509_LOOKUP; - -DECLARE_STACK_OF(X509_LOOKUP) -DECLARE_STACK_OF(X509_OBJECT) - -/* This is a static that defines the function interface */ -typedef struct x509_lookup_method_st { - const char *name; - int (*new_item) (X509_LOOKUP *ctx); - void (*free) (X509_LOOKUP *ctx); - int (*init) (X509_LOOKUP *ctx); - int (*shutdown) (X509_LOOKUP *ctx); - int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, - char **ret); - int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name, - X509_OBJECT *ret); - int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name, - ASN1_INTEGER *serial, X509_OBJECT *ret); - int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type, - unsigned char *bytes, int len, - X509_OBJECT *ret); - int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len, - X509_OBJECT *ret); -} X509_LOOKUP_METHOD; - -typedef struct X509_VERIFY_PARAM_ID_st X509_VERIFY_PARAM_ID; - -/* - * This structure hold all parameters associated with a verify operation by - * including an X509_VERIFY_PARAM structure in related structures the - * parameters used can be customized - */ - -typedef struct X509_VERIFY_PARAM_st { - char *name; - time_t check_time; /* Time to use */ - unsigned long inh_flags; /* Inheritance flags */ - unsigned long flags; /* Various verify flags */ - int purpose; /* purpose to check untrusted certificates */ - int trust; /* trust setting to check */ - int depth; /* Verify depth */ - STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ - X509_VERIFY_PARAM_ID *id; /* opaque ID data */ -} X509_VERIFY_PARAM; - -DECLARE_STACK_OF(X509_VERIFY_PARAM) - -/* - * This is used to hold everything. It is used for all certificate - * validation. Once we have a certificate chain, the 'verify' function is - * then called to actually check the cert chain. - */ -struct x509_store_st { - /* The following is a cache of trusted certs */ - int cache; /* if true, stash any hits */ - STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ - /* These are external lookup methods */ - STACK_OF(X509_LOOKUP) *get_cert_methods; - X509_VERIFY_PARAM *param; - /* Callbacks for various operations */ - /* called to verify a certificate */ - int (*verify) (X509_STORE_CTX *ctx); - /* error callback */ - int (*verify_cb) (int ok, X509_STORE_CTX *ctx); - /* get issuers cert from ctx */ - int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); - /* check issued */ - int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); - /* Check revocation status of chain */ - int (*check_revocation) (X509_STORE_CTX *ctx); - /* retrieve CRL */ - int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); - /* Check CRL validity */ - int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); - /* Check certificate against CRL */ - int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); - STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); - STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); - int (*cleanup) (X509_STORE_CTX *ctx); - CRYPTO_EX_DATA ex_data; - int references; -} /* X509_STORE */ ; - -int X509_STORE_set_depth(X509_STORE *store, int depth); - -# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func)) -# define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func)) - -/* This is the functions plus an instance of the local variables. */ -struct x509_lookup_st { - int init; /* have we been started */ - int skip; /* don't use us. */ - X509_LOOKUP_METHOD *method; /* the functions */ - char *method_data; /* method data */ - X509_STORE *store_ctx; /* who owns us */ -} /* X509_LOOKUP */ ; - -/* - * This is a used when verifying cert chains. Since the gathering of the - * cert chain can take some time (and have to be 'retried', this needs to be - * kept and passed around. - */ -struct x509_store_ctx_st { /* X509_STORE_CTX */ - X509_STORE *ctx; - /* used when looking up certs */ - int current_method; - /* The following are set by the caller */ - /* The cert to check */ - X509 *cert; - /* chain of X509s - untrusted - passed in */ - STACK_OF(X509) *untrusted; - /* set of CRLs passed in */ - STACK_OF(X509_CRL) *crls; - X509_VERIFY_PARAM *param; - /* Other info for use with get_issuer() */ - void *other_ctx; - /* Callbacks for various operations */ - /* called to verify a certificate */ - int (*verify) (X509_STORE_CTX *ctx); - /* error callback */ - int (*verify_cb) (int ok, X509_STORE_CTX *ctx); - /* get issuers cert from ctx */ - int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); - /* check issued */ - int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); - /* Check revocation status of chain */ - int (*check_revocation) (X509_STORE_CTX *ctx); - /* retrieve CRL */ - int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); - /* Check CRL validity */ - int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); - /* Check certificate against CRL */ - int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); - int (*check_policy) (X509_STORE_CTX *ctx); - STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); - STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); - int (*cleanup) (X509_STORE_CTX *ctx); - /* The following is built up */ - /* if 0, rebuild chain */ - int valid; - /* index of last untrusted cert */ - int last_untrusted; - /* chain of X509s - built up and trusted */ - STACK_OF(X509) *chain; - /* Valid policy tree */ - X509_POLICY_TREE *tree; - /* Require explicit policy value */ - int explicit_policy; - /* When something goes wrong, this is why */ - int error_depth; - int error; - X509 *current_cert; - /* cert currently being tested as valid issuer */ - X509 *current_issuer; - /* current CRL */ - X509_CRL *current_crl; - /* score of current CRL */ - int current_crl_score; - /* Reason mask */ - unsigned int current_reasons; - /* For CRL path validation: parent context */ - X509_STORE_CTX *parent; - CRYPTO_EX_DATA ex_data; -} /* X509_STORE_CTX */ ; - -void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); - -# define X509_STORE_CTX_set_app_data(ctx,data) \ - X509_STORE_CTX_set_ex_data(ctx,0,data) -# define X509_STORE_CTX_get_app_data(ctx) \ - X509_STORE_CTX_get_ex_data(ctx,0) - -# define X509_L_FILE_LOAD 1 -# define X509_L_ADD_DIR 2 - -# define X509_LOOKUP_load_file(x,name,type) \ - X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) - -# define X509_LOOKUP_add_dir(x,name,type) \ - X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) - -# define X509_V_OK 0 -# define X509_V_ERR_UNSPECIFIED 1 - -# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 -# define X509_V_ERR_UNABLE_TO_GET_CRL 3 -# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 -# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 -# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 -# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 -# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 -# define X509_V_ERR_CERT_NOT_YET_VALID 9 -# define X509_V_ERR_CERT_HAS_EXPIRED 10 -# define X509_V_ERR_CRL_NOT_YET_VALID 11 -# define X509_V_ERR_CRL_HAS_EXPIRED 12 -# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 -# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 -# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 -# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 -# define X509_V_ERR_OUT_OF_MEM 17 -# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 -# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 -# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 -# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 -# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 -# define X509_V_ERR_CERT_REVOKED 23 -# define X509_V_ERR_INVALID_CA 24 -# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 -# define X509_V_ERR_INVALID_PURPOSE 26 -# define X509_V_ERR_CERT_UNTRUSTED 27 -# define X509_V_ERR_CERT_REJECTED 28 -/* These are 'informational' when looking for issuer cert */ -# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 -# define X509_V_ERR_AKID_SKID_MISMATCH 30 -# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 -# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 - -# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 -# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 -# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 -# define X509_V_ERR_INVALID_NON_CA 37 -# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 -# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 -# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 - -# define X509_V_ERR_INVALID_EXTENSION 41 -# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 -# define X509_V_ERR_NO_EXPLICIT_POLICY 43 -# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 -# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 - -# define X509_V_ERR_UNNESTED_RESOURCE 46 - -# define X509_V_ERR_PERMITTED_VIOLATION 47 -# define X509_V_ERR_EXCLUDED_VIOLATION 48 -# define X509_V_ERR_SUBTREE_MINMAX 49 -# define X509_V_ERR_APPLICATION_VERIFICATION 50 -# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 -# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 -# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 -# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 - -/* Suite B mode algorithm violation */ -# define X509_V_ERR_SUITE_B_INVALID_VERSION 56 -# define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 -# define X509_V_ERR_SUITE_B_INVALID_CURVE 58 -# define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 -# define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 -# define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 - -/* Host, email and IP check errors */ -# define X509_V_ERR_HOSTNAME_MISMATCH 62 -# define X509_V_ERR_EMAIL_MISMATCH 63 -# define X509_V_ERR_IP_ADDRESS_MISMATCH 64 - -/* Caller error */ -# define X509_V_ERR_INVALID_CALL 65 -/* Issuer lookup error */ -# define X509_V_ERR_STORE_LOOKUP 66 - -# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 67 - -/* Certificate verify flags */ - -/* Send issuer+subject checks to verify_cb */ -# define X509_V_FLAG_CB_ISSUER_CHECK 0x1 -/* Use check time instead of current time */ -# define X509_V_FLAG_USE_CHECK_TIME 0x2 -/* Lookup CRLs */ -# define X509_V_FLAG_CRL_CHECK 0x4 -/* Lookup CRLs for whole chain */ -# define X509_V_FLAG_CRL_CHECK_ALL 0x8 -/* Ignore unhandled critical extensions */ -# define X509_V_FLAG_IGNORE_CRITICAL 0x10 -/* Disable workarounds for broken certificates */ -# define X509_V_FLAG_X509_STRICT 0x20 -/* Enable proxy certificate validation */ -# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 -/* Enable policy checking */ -# define X509_V_FLAG_POLICY_CHECK 0x80 -/* Policy variable require-explicit-policy */ -# define X509_V_FLAG_EXPLICIT_POLICY 0x100 -/* Policy variable inhibit-any-policy */ -# define X509_V_FLAG_INHIBIT_ANY 0x200 -/* Policy variable inhibit-policy-mapping */ -# define X509_V_FLAG_INHIBIT_MAP 0x400 -/* Notify callback that policy is OK */ -# define X509_V_FLAG_NOTIFY_POLICY 0x800 -/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ -# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 -/* Delta CRL support */ -# define X509_V_FLAG_USE_DELTAS 0x2000 -/* Check selfsigned CA signature */ -# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 -/* Use trusted store first */ -# define X509_V_FLAG_TRUSTED_FIRST 0x8000 -/* Suite B 128 bit only mode: not normally used */ -# define X509_V_FLAG_SUITEB_128_LOS_ONLY 0x10000 -/* Suite B 192 bit only mode */ -# define X509_V_FLAG_SUITEB_192_LOS 0x20000 -/* Suite B 128 bit mode allowing 192 bit algorithms */ -# define X509_V_FLAG_SUITEB_128_LOS 0x30000 - -/* Allow partial chains if at least one certificate is in trusted store */ -# define X509_V_FLAG_PARTIAL_CHAIN 0x80000 -/* - * If the initial chain is not trusted, do not attempt to build an alternative - * chain. Alternate chain checking was introduced in 1.0.2b. Setting this flag - * will force the behaviour to match that of previous versions. - */ -# define X509_V_FLAG_NO_ALT_CHAINS 0x100000 - -# define X509_VP_FLAG_DEFAULT 0x1 -# define X509_VP_FLAG_OVERWRITE 0x2 -# define X509_VP_FLAG_RESET_FLAGS 0x4 -# define X509_VP_FLAG_LOCKED 0x8 -# define X509_VP_FLAG_ONCE 0x10 - -/* Internal use: mask of policy related options */ -# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ - | X509_V_FLAG_EXPLICIT_POLICY \ - | X509_V_FLAG_INHIBIT_ANY \ - | X509_V_FLAG_INHIBIT_MAP) - -int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, - X509_NAME *name); -X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, - int type, X509_NAME *name); -X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, - X509_OBJECT *x); -void X509_OBJECT_up_ref_count(X509_OBJECT *a); -void X509_OBJECT_free_contents(X509_OBJECT *a); -X509_STORE *X509_STORE_new(void); -void X509_STORE_free(X509_STORE *v); - -STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); -STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); -int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); -int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); -int X509_STORE_set_trust(X509_STORE *ctx, int trust); -int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); - -void X509_STORE_set_verify_cb(X509_STORE *ctx, - int (*verify_cb) (int, X509_STORE_CTX *)); - -void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, - STACK_OF(X509_CRL) *(*cb) (X509_STORE_CTX - *ctx, - X509_NAME *nm)); - -X509_STORE_CTX *X509_STORE_CTX_new(void); - -int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); - -void X509_STORE_CTX_free(X509_STORE_CTX *ctx); -int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, - X509 *x509, STACK_OF(X509) *chain); -void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); -void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); - -X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); - -X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); - -X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); -X509_LOOKUP_METHOD *X509_LOOKUP_file(void); - -int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); -int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); - -int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, - X509_OBJECT *ret); - -int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, - long argl, char **ret); - -# ifndef OPENSSL_NO_STDIO -int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); -int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); -int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); -# endif - -X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); -void X509_LOOKUP_free(X509_LOOKUP *ctx); -int X509_LOOKUP_init(X509_LOOKUP *ctx); -int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, - X509_OBJECT *ret); -int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, - ASN1_INTEGER *serial, X509_OBJECT *ret); -int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, - unsigned char *bytes, int len, - X509_OBJECT *ret); -int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, - X509_OBJECT *ret); -int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); - -# ifndef OPENSSL_NO_STDIO -int X509_STORE_load_locations(X509_STORE *ctx, - const char *file, const char *dir); -int X509_STORE_set_default_paths(X509_STORE *ctx); -# endif - -int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, - CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, - CRYPTO_EX_free *free_func); -int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data); -void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); -int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); -X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); -X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); -X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); -X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); -STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); -STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); -void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); -void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); -int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); -int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); -int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, - int purpose, int trust); -void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); -void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, - time_t t); -void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, - int (*verify_cb) (int, X509_STORE_CTX *)); - -X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); -int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); - -X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); -void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); -int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); - -/* X509_VERIFY_PARAM functions */ - -X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); -void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); -int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, - const X509_VERIFY_PARAM *from); -int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, - const X509_VERIFY_PARAM *from); -int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); -int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, - unsigned long flags); -int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, - unsigned long flags); -unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); -int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); -int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); -void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); -void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); -int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, - ASN1_OBJECT *policy); -int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, - STACK_OF(ASN1_OBJECT) *policies); - -int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen); -int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen); -void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, - unsigned int flags); -char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); -int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, - const char *email, size_t emaillen); -int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, - const unsigned char *ip, size_t iplen); -int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, - const char *ipasc); - -int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); -const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); - -int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); -int X509_VERIFY_PARAM_get_count(void); -const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); -const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); -void X509_VERIFY_PARAM_table_cleanup(void); - -int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, - STACK_OF(X509) *certs, - STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags); - -void X509_policy_tree_free(X509_POLICY_TREE *tree); - -int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); -X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, - int i); - -STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const - X509_POLICY_TREE - *tree); - -STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const - X509_POLICY_TREE - *tree); - -int X509_policy_level_node_count(X509_POLICY_LEVEL *level); - -X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, - int i); - -const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); - -STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const - X509_POLICY_NODE - *node); -const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE - *node); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/x509cset.c b/Sources/COpenSSL/x509cset.c deleted file mode 100644 index 7c28a968..00000000 --- a/Sources/COpenSSL/x509cset.c +++ /dev/null @@ -1,167 +0,0 @@ -/* crypto/x509/x509cset.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2001. - */ -/* ==================================================================== - * Copyright (c) 2001 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "asn1.h" -#include "objects.h" -#include "evp.h" -#include "x509.h" - -int X509_CRL_set_version(X509_CRL *x, long version) -{ - if (x == NULL) - return (0); - if (x->crl->version == NULL) { - if ((x->crl->version = M_ASN1_INTEGER_new()) == NULL) - return (0); - } - return (ASN1_INTEGER_set(x->crl->version, version)); -} - -int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) -{ - if ((x == NULL) || (x->crl == NULL)) - return (0); - return (X509_NAME_set(&x->crl->issuer, name)); -} - -int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if (x == NULL) - return (0); - in = x->crl->lastUpdate; - if (in != tm) { - in = M_ASN1_TIME_dup(tm); - if (in != NULL) { - M_ASN1_TIME_free(x->crl->lastUpdate); - x->crl->lastUpdate = in; - } - } - return (in != NULL); -} - -int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if (x == NULL) - return (0); - in = x->crl->nextUpdate; - if (in != tm) { - in = M_ASN1_TIME_dup(tm); - if (in != NULL) { - M_ASN1_TIME_free(x->crl->nextUpdate); - x->crl->nextUpdate = in; - } - } - return (in != NULL); -} - -int X509_CRL_sort(X509_CRL *c) -{ - int i; - X509_REVOKED *r; - /* - * sort the data so it will be written in serial number order - */ - sk_X509_REVOKED_sort(c->crl->revoked); - for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) { - r = sk_X509_REVOKED_value(c->crl->revoked, i); - r->sequence = i; - } - c->crl->enc.modified = 1; - return 1; -} - -int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) -{ - ASN1_TIME *in; - - if (x == NULL) - return (0); - in = x->revocationDate; - if (in != tm) { - in = M_ASN1_TIME_dup(tm); - if (in != NULL) { - M_ASN1_TIME_free(x->revocationDate); - x->revocationDate = in; - } - } - return (in != NULL); -} - -int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) -{ - ASN1_INTEGER *in; - - if (x == NULL) - return (0); - in = x->serialNumber; - if (in != serial) { - in = M_ASN1_INTEGER_dup(serial); - if (in != NULL) { - M_ASN1_INTEGER_free(x->serialNumber); - x->serialNumber = in; - } - } - return (in != NULL); -} diff --git a/Sources/COpenSSL/x509name.c b/Sources/COpenSSL/x509name.c deleted file mode 100644 index 4b78c5cc..00000000 --- a/Sources/COpenSSL/x509name.c +++ /dev/null @@ -1,398 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* crypto/x509/x509name.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "stack.h" -#include "cryptlib.h" -#include "asn1.h" -#include "objects.h" -#include "evp.h" -#include "x509.h" - -int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) -{ - ASN1_OBJECT *obj; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-1); - return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); -} - -int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf, - int len) -{ - int i; - ASN1_STRING *data; - - i = X509_NAME_get_index_by_OBJ(name, obj, -1); - if (i < 0) - return (-1); - data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); - i = (data->length > (len - 1)) ? (len - 1) : data->length; - if (buf == NULL) - return (data->length); - memcpy(buf, data->data, i); - buf[i] = '\0'; - return (i); -} - -int X509_NAME_entry_count(X509_NAME *name) -{ - if (name == NULL) - return (0); - return (sk_X509_NAME_ENTRY_num(name->entries)); -} - -int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) -{ - ASN1_OBJECT *obj; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) - return (-2); - return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); -} - -/* NOTE: you should be passsing -1, not 0 as lastpos */ -int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos) -{ - int n; - X509_NAME_ENTRY *ne; - STACK_OF(X509_NAME_ENTRY) *sk; - - if (name == NULL) - return (-1); - if (lastpos < 0) - lastpos = -1; - sk = name->entries; - n = sk_X509_NAME_ENTRY_num(sk); - for (lastpos++; lastpos < n; lastpos++) { - ne = sk_X509_NAME_ENTRY_value(sk, lastpos); - if (OBJ_cmp(ne->object, obj) == 0) - return (lastpos); - } - return (-1); -} - -X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc) -{ - if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc - || loc < 0) - return (NULL); - else - return (sk_X509_NAME_ENTRY_value(name->entries, loc)); -} - -X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) -{ - X509_NAME_ENTRY *ret; - int i, n, set_prev, set_next; - STACK_OF(X509_NAME_ENTRY) *sk; - - if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc - || loc < 0) - return (NULL); - sk = name->entries; - ret = sk_X509_NAME_ENTRY_delete(sk, loc); - n = sk_X509_NAME_ENTRY_num(sk); - name->modified = 1; - if (loc == n) - return (ret); - - /* else we need to fixup the set field */ - if (loc != 0) - set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; - else - set_prev = ret->set - 1; - set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; - - /*- - * set_prev is the previous set - * set is the current set - * set_next is the following - * prev 1 1 1 1 1 1 1 1 - * set 1 1 2 2 - * next 1 1 2 2 2 2 3 2 - * so basically only if prev and next differ by 2, then - * re-number down by 1 - */ - if (set_prev + 1 < set_next) - for (i = loc; i < n; i++) - sk_X509_NAME_ENTRY_value(sk, i)->set--; - return (ret); -} - -int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, - unsigned char *bytes, int len, int loc, - int set) -{ - X509_NAME_ENTRY *ne; - int ret; - ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); - return ret; -} - -int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, - unsigned char *bytes, int len, int loc, - int set) -{ - X509_NAME_ENTRY *ne; - int ret; - ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); - return ret; -} - -int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, - const unsigned char *bytes, int len, int loc, - int set) -{ - X509_NAME_ENTRY *ne; - int ret; - ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); - if (!ne) - return 0; - ret = X509_NAME_add_entry(name, ne, loc, set); - X509_NAME_ENTRY_free(ne); - return ret; -} - -/* - * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the - * guy we are about to stomp on. - */ -int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc, - int set) -{ - X509_NAME_ENTRY *new_name = NULL; - int n, i, inc; - STACK_OF(X509_NAME_ENTRY) *sk; - - if (name == NULL) - return (0); - sk = name->entries; - n = sk_X509_NAME_ENTRY_num(sk); - if (loc > n) - loc = n; - else if (loc < 0) - loc = n; - - name->modified = 1; - - if (set == -1) { - if (loc == 0) { - set = 0; - inc = 1; - } else { - set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; - inc = 0; - } - } else { /* if (set >= 0) */ - - if (loc >= n) { - if (loc != 0) - set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; - else - set = 0; - } else - set = sk_X509_NAME_ENTRY_value(sk, loc)->set; - inc = (set == 0) ? 1 : 0; - } - - if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL) - goto err; - new_name->set = set; - if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { - X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE); - goto err; - } - if (inc) { - n = sk_X509_NAME_ENTRY_num(sk); - for (i = loc + 1; i < n; i++) - sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1; - } - return (1); - err: - if (new_name != NULL) - X509_NAME_ENTRY_free(new_name); - return (0); -} - -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, - const char *field, int type, - const unsigned char *bytes, - int len) -{ - ASN1_OBJECT *obj; - X509_NAME_ENTRY *nentry; - - obj = OBJ_txt2obj(field, 0); - if (obj == NULL) { - X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, - X509_R_INVALID_FIELD_NAME); - ERR_add_error_data(2, "name=", field); - return (NULL); - } - nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); - ASN1_OBJECT_free(obj); - return nentry; -} - -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, - int type, unsigned char *bytes, - int len) -{ - ASN1_OBJECT *obj; - X509_NAME_ENTRY *nentry; - - obj = OBJ_nid2obj(nid); - if (obj == NULL) { - X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID); - return (NULL); - } - nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); - ASN1_OBJECT_free(obj); - return nentry; -} - -X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, - ASN1_OBJECT *obj, int type, - const unsigned char *bytes, - int len) -{ - X509_NAME_ENTRY *ret; - - if ((ne == NULL) || (*ne == NULL)) { - if ((ret = X509_NAME_ENTRY_new()) == NULL) - return (NULL); - } else - ret = *ne; - - if (!X509_NAME_ENTRY_set_object(ret, obj)) - goto err; - if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) - goto err; - - if ((ne != NULL) && (*ne == NULL)) - *ne = ret; - return (ret); - err: - if ((ne == NULL) || (ret != *ne)) - X509_NAME_ENTRY_free(ret); - return (NULL); -} - -int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj) -{ - if ((ne == NULL) || (obj == NULL)) { - X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT, - ERR_R_PASSED_NULL_PARAMETER); - return (0); - } - ASN1_OBJECT_free(ne->object); - ne->object = OBJ_dup(obj); - return ((ne->object == NULL) ? 0 : 1); -} - -int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, - const unsigned char *bytes, int len) -{ - int i; - - if ((ne == NULL) || ((bytes == NULL) && (len != 0))) - return (0); - if ((type > 0) && (type & MBSTRING_FLAG)) - return ASN1_STRING_set_by_NID(&ne->value, bytes, - len, type, - OBJ_obj2nid(ne->object)) ? 1 : 0; - if (len < 0) - len = strlen((const char *)bytes); - i = ASN1_STRING_set(ne->value, bytes, len); - if (!i) - return (0); - if (type != V_ASN1_UNDEF) { - if (type == V_ASN1_APP_CHOOSE) - ne->value->type = ASN1_PRINTABLE_type(bytes, len); - else - ne->value->type = type; - } - return (1); -} - -ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne) -{ - if (ne == NULL) - return (NULL); - return (ne->object); -} - -ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne) -{ - if (ne == NULL) - return (NULL); - return (ne->value); -} diff --git a/Sources/COpenSSL/x509rset.c b/Sources/COpenSSL/x509rset.c deleted file mode 100644 index 0bfa5070..00000000 --- a/Sources/COpenSSL/x509rset.c +++ /dev/null @@ -1,85 +0,0 @@ -/* crypto/x509/x509rset.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "asn1.h" -#include "objects.h" -#include "evp.h" -#include "x509.h" - -int X509_REQ_set_version(X509_REQ *x, long version) -{ - if (x == NULL) - return (0); - return (ASN1_INTEGER_set(x->req_info->version, version)); -} - -int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) -{ - if ((x == NULL) || (x->req_info == NULL)) - return (0); - return (X509_NAME_set(&x->req_info->subject, name)); -} - -int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) -{ - if ((x == NULL) || (x->req_info == NULL)) - return (0); - return (X509_PUBKEY_set(&x->req_info->pubkey, pkey)); -} diff --git a/Sources/COpenSSL/x509spki.c b/Sources/COpenSSL/x509spki.c deleted file mode 100644 index c89c20ac..00000000 --- a/Sources/COpenSSL/x509spki.c +++ /dev/null @@ -1,126 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* x509spki.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "cryptlib.h" -#include "x509.h" - -int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) -{ - if ((x == NULL) || (x->spkac == NULL)) - return (0); - return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); -} - -EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) -{ - if ((x == NULL) || (x->spkac == NULL)) - return (NULL); - return (X509_PUBKEY_get(x->spkac->pubkey)); -} - -/* Load a Netscape SPKI from a base64 encoded string */ - -NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) -{ - unsigned char *spki_der; - const unsigned char *p; - int spki_len; - NETSCAPE_SPKI *spki; - if (len <= 0) - len = strlen(str); - if (!(spki_der = OPENSSL_malloc(len + 1))) { - X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE); - return NULL; - } - spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); - if (spki_len < 0) { - X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, X509_R_BASE64_DECODE_ERROR); - OPENSSL_free(spki_der); - return NULL; - } - p = spki_der; - spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); - OPENSSL_free(spki_der); - return spki; -} - -/* Generate a base64 encoded string from an SPKI */ - -char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) -{ - unsigned char *der_spki, *p; - char *b64_str; - int der_len; - der_len = i2d_NETSCAPE_SPKI(spki, NULL); - der_spki = OPENSSL_malloc(der_len); - b64_str = OPENSSL_malloc(der_len * 2); - if (!der_spki || !b64_str) { - OPENSSL_free(der_spki); - OPENSSL_free(b64_str); - X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); - return NULL; - } - p = der_spki; - i2d_NETSCAPE_SPKI(spki, &p); - EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); - OPENSSL_free(der_spki); - return b64_str; -} diff --git a/Sources/COpenSSL/x509type.c b/Sources/COpenSSL/x509type.c deleted file mode 100644 index 9782f6ca..00000000 --- a/Sources/COpenSSL/x509type.c +++ /dev/null @@ -1,127 +0,0 @@ -/* crypto/x509/x509type.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "cryptlib.h" -#include "evp.h" -#include "objects.h" -#include "x509.h" - -int X509_certificate_type(X509 *x, EVP_PKEY *pkey) -{ - EVP_PKEY *pk; - int ret = 0, i; - - if (x == NULL) - return (0); - - if (pkey == NULL) - pk = X509_get_pubkey(x); - else - pk = pkey; - - if (pk == NULL) - return (0); - - switch (pk->type) { - case EVP_PKEY_RSA: - ret = EVP_PK_RSA | EVP_PKT_SIGN; -/* if (!sign only extension) */ - ret |= EVP_PKT_ENC; - break; - case EVP_PKEY_DSA: - ret = EVP_PK_DSA | EVP_PKT_SIGN; - break; - case EVP_PKEY_EC: - ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH; - break; - case EVP_PKEY_DH: - ret = EVP_PK_DH | EVP_PKT_EXCH; - break; - case NID_id_GostR3410_94: - case NID_id_GostR3410_2001: - ret = EVP_PKT_EXCH | EVP_PKT_SIGN; - break; - default: - break; - } - - i = OBJ_obj2nid(x->sig_alg->algorithm); - if (i && OBJ_find_sigid_algs(i, NULL, &i)) { - - switch (i) { - case NID_rsaEncryption: - case NID_rsa: - ret |= EVP_PKS_RSA; - break; - case NID_dsa: - case NID_dsa_2: - ret |= EVP_PKS_DSA; - break; - case NID_X9_62_id_ecPublicKey: - ret |= EVP_PKS_EC; - break; - default: - break; - } - } - - if (pkey == NULL) - EVP_PKEY_free(pk); - return (ret); -} diff --git a/Sources/COpenSSL/x509v3.h b/Sources/COpenSSL/x509v3.h deleted file mode 100644 index 92bf77b0..00000000 --- a/Sources/COpenSSL/x509v3.h +++ /dev/null @@ -1,1055 +0,0 @@ -/* x509v3.h */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ -#ifndef HEADER_X509V3_H -# define HEADER_X509V3_H - -# include "bio.h" -# include "x509.h" -# include "conf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -# ifdef OPENSSL_SYS_WIN32 -/* Under Win32 these are defined in wincrypt.h */ -# undef X509_NAME -# undef X509_CERT_PAIR -# undef X509_EXTENSIONS -# endif - -/* Forward reference */ -struct v3_ext_method; -struct v3_ext_ctx; - -/* Useful typedefs */ - -typedef void *(*X509V3_EXT_NEW)(void); -typedef void (*X509V3_EXT_FREE) (void *); -typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); -typedef int (*X509V3_EXT_I2D) (void *, unsigned char **); -typedef STACK_OF(CONF_VALUE) * - (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext, - STACK_OF(CONF_VALUE) *extlist); -typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, - STACK_OF(CONF_VALUE) *values); -typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, - void *ext); -typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, const char *str); -typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext, - BIO *out, int indent); -typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, - struct v3_ext_ctx *ctx, const char *str); - -/* V3 extension structure */ - -struct v3_ext_method { - int ext_nid; - int ext_flags; -/* If this is set the following four fields are ignored */ - ASN1_ITEM_EXP *it; -/* Old style ASN1 calls */ - X509V3_EXT_NEW ext_new; - X509V3_EXT_FREE ext_free; - X509V3_EXT_D2I d2i; - X509V3_EXT_I2D i2d; -/* The following pair is used for string extensions */ - X509V3_EXT_I2S i2s; - X509V3_EXT_S2I s2i; -/* The following pair is used for multi-valued extensions */ - X509V3_EXT_I2V i2v; - X509V3_EXT_V2I v2i; -/* The following are used for raw extensions */ - X509V3_EXT_I2R i2r; - X509V3_EXT_R2I r2i; - void *usr_data; /* Any extension specific data */ -}; - -typedef struct X509V3_CONF_METHOD_st { - char *(*get_string) (void *db, char *section, char *value); - STACK_OF(CONF_VALUE) *(*get_section) (void *db, char *section); - void (*free_string) (void *db, char *string); - void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section); -} X509V3_CONF_METHOD; - -/* Context specific info */ -struct v3_ext_ctx { -# define CTX_TEST 0x1 - int flags; - X509 *issuer_cert; - X509 *subject_cert; - X509_REQ *subject_req; - X509_CRL *crl; - X509V3_CONF_METHOD *db_meth; - void *db; -/* Maybe more here */ -}; - -typedef struct v3_ext_method X509V3_EXT_METHOD; - -DECLARE_STACK_OF(X509V3_EXT_METHOD) - -/* ext_flags values */ -# define X509V3_EXT_DYNAMIC 0x1 -# define X509V3_EXT_CTX_DEP 0x2 -# define X509V3_EXT_MULTILINE 0x4 - -typedef BIT_STRING_BITNAME ENUMERATED_NAMES; - -typedef struct BASIC_CONSTRAINTS_st { - int ca; - ASN1_INTEGER *pathlen; -} BASIC_CONSTRAINTS; - -typedef struct PKEY_USAGE_PERIOD_st { - ASN1_GENERALIZEDTIME *notBefore; - ASN1_GENERALIZEDTIME *notAfter; -} PKEY_USAGE_PERIOD; - -typedef struct otherName_st { - ASN1_OBJECT *type_id; - ASN1_TYPE *value; -} OTHERNAME; - -typedef struct EDIPartyName_st { - ASN1_STRING *nameAssigner; - ASN1_STRING *partyName; -} EDIPARTYNAME; - -typedef struct GENERAL_NAME_st { -# define GEN_OTHERNAME 0 -# define GEN_EMAIL 1 -# define GEN_DNS 2 -# define GEN_X400 3 -# define GEN_DIRNAME 4 -# define GEN_EDIPARTY 5 -# define GEN_URI 6 -# define GEN_IPADD 7 -# define GEN_RID 8 - int type; - union { - char *ptr; - OTHERNAME *otherName; /* otherName */ - ASN1_IA5STRING *rfc822Name; - ASN1_IA5STRING *dNSName; - ASN1_TYPE *x400Address; - X509_NAME *directoryName; - EDIPARTYNAME *ediPartyName; - ASN1_IA5STRING *uniformResourceIdentifier; - ASN1_OCTET_STRING *iPAddress; - ASN1_OBJECT *registeredID; - /* Old names */ - ASN1_OCTET_STRING *ip; /* iPAddress */ - X509_NAME *dirn; /* dirn */ - ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, - * uniformResourceIdentifier */ - ASN1_OBJECT *rid; /* registeredID */ - ASN1_TYPE *other; /* x400Address */ - } d; -} GENERAL_NAME; - -typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; - -typedef struct ACCESS_DESCRIPTION_st { - ASN1_OBJECT *method; - GENERAL_NAME *location; -} ACCESS_DESCRIPTION; - -typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; - -typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; - -DECLARE_STACK_OF(GENERAL_NAME) -DECLARE_ASN1_SET_OF(GENERAL_NAME) - -DECLARE_STACK_OF(ACCESS_DESCRIPTION) -DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) - -typedef struct DIST_POINT_NAME_st { - int type; - union { - GENERAL_NAMES *fullname; - STACK_OF(X509_NAME_ENTRY) *relativename; - } name; -/* If relativename then this contains the full distribution point name */ - X509_NAME *dpname; -} DIST_POINT_NAME; -/* All existing reasons */ -# define CRLDP_ALL_REASONS 0x807f - -# define CRL_REASON_NONE -1 -# define CRL_REASON_UNSPECIFIED 0 -# define CRL_REASON_KEY_COMPROMISE 1 -# define CRL_REASON_CA_COMPROMISE 2 -# define CRL_REASON_AFFILIATION_CHANGED 3 -# define CRL_REASON_SUPERSEDED 4 -# define CRL_REASON_CESSATION_OF_OPERATION 5 -# define CRL_REASON_CERTIFICATE_HOLD 6 -# define CRL_REASON_REMOVE_FROM_CRL 8 -# define CRL_REASON_PRIVILEGE_WITHDRAWN 9 -# define CRL_REASON_AA_COMPROMISE 10 - -struct DIST_POINT_st { - DIST_POINT_NAME *distpoint; - ASN1_BIT_STRING *reasons; - GENERAL_NAMES *CRLissuer; - int dp_reasons; -}; - -typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; - -DECLARE_STACK_OF(DIST_POINT) -DECLARE_ASN1_SET_OF(DIST_POINT) - -struct AUTHORITY_KEYID_st { - ASN1_OCTET_STRING *keyid; - GENERAL_NAMES *issuer; - ASN1_INTEGER *serial; -}; - -/* Strong extranet structures */ - -typedef struct SXNET_ID_st { - ASN1_INTEGER *zone; - ASN1_OCTET_STRING *user; -} SXNETID; - -DECLARE_STACK_OF(SXNETID) -DECLARE_ASN1_SET_OF(SXNETID) - -typedef struct SXNET_st { - ASN1_INTEGER *version; - STACK_OF(SXNETID) *ids; -} SXNET; - -typedef struct NOTICEREF_st { - ASN1_STRING *organization; - STACK_OF(ASN1_INTEGER) *noticenos; -} NOTICEREF; - -typedef struct USERNOTICE_st { - NOTICEREF *noticeref; - ASN1_STRING *exptext; -} USERNOTICE; - -typedef struct POLICYQUALINFO_st { - ASN1_OBJECT *pqualid; - union { - ASN1_IA5STRING *cpsuri; - USERNOTICE *usernotice; - ASN1_TYPE *other; - } d; -} POLICYQUALINFO; - -DECLARE_STACK_OF(POLICYQUALINFO) -DECLARE_ASN1_SET_OF(POLICYQUALINFO) - -typedef struct POLICYINFO_st { - ASN1_OBJECT *policyid; - STACK_OF(POLICYQUALINFO) *qualifiers; -} POLICYINFO; - -typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; - -DECLARE_STACK_OF(POLICYINFO) -DECLARE_ASN1_SET_OF(POLICYINFO) - -typedef struct POLICY_MAPPING_st { - ASN1_OBJECT *issuerDomainPolicy; - ASN1_OBJECT *subjectDomainPolicy; -} POLICY_MAPPING; - -DECLARE_STACK_OF(POLICY_MAPPING) - -typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; - -typedef struct GENERAL_SUBTREE_st { - GENERAL_NAME *base; - ASN1_INTEGER *minimum; - ASN1_INTEGER *maximum; -} GENERAL_SUBTREE; - -DECLARE_STACK_OF(GENERAL_SUBTREE) - -struct NAME_CONSTRAINTS_st { - STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; - STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; -}; - -typedef struct POLICY_CONSTRAINTS_st { - ASN1_INTEGER *requireExplicitPolicy; - ASN1_INTEGER *inhibitPolicyMapping; -} POLICY_CONSTRAINTS; - -/* Proxy certificate structures, see RFC 3820 */ -typedef struct PROXY_POLICY_st { - ASN1_OBJECT *policyLanguage; - ASN1_OCTET_STRING *policy; -} PROXY_POLICY; - -typedef struct PROXY_CERT_INFO_EXTENSION_st { - ASN1_INTEGER *pcPathLengthConstraint; - PROXY_POLICY *proxyPolicy; -} PROXY_CERT_INFO_EXTENSION; - -DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) -DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) - -struct ISSUING_DIST_POINT_st { - DIST_POINT_NAME *distpoint; - int onlyuser; - int onlyCA; - ASN1_BIT_STRING *onlysomereasons; - int indirectCRL; - int onlyattr; -}; - -/* Values in idp_flags field */ -/* IDP present */ -# define IDP_PRESENT 0x1 -/* IDP values inconsistent */ -# define IDP_INVALID 0x2 -/* onlyuser true */ -# define IDP_ONLYUSER 0x4 -/* onlyCA true */ -# define IDP_ONLYCA 0x8 -/* onlyattr true */ -# define IDP_ONLYATTR 0x10 -/* indirectCRL true */ -# define IDP_INDIRECT 0x20 -/* onlysomereasons present */ -# define IDP_REASONS 0x40 - -# define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \ -",name:", val->name, ",value:", val->value); - -# define X509V3_set_ctx_test(ctx) \ - X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) -# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; - -# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ - 0,0,0,0, \ - 0,0, \ - (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ - (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ - NULL, NULL, \ - table} - -# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ - 0,0,0,0, \ - (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ - (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ - 0,0,0,0, \ - NULL} - -# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} - -/* X509_PURPOSE stuff */ - -# define EXFLAG_BCONS 0x1 -# define EXFLAG_KUSAGE 0x2 -# define EXFLAG_XKUSAGE 0x4 -# define EXFLAG_NSCERT 0x8 - -# define EXFLAG_CA 0x10 -/* Really self issued not necessarily self signed */ -# define EXFLAG_SI 0x20 -# define EXFLAG_V1 0x40 -# define EXFLAG_INVALID 0x80 -# define EXFLAG_SET 0x100 -# define EXFLAG_CRITICAL 0x200 -# define EXFLAG_PROXY 0x400 - -# define EXFLAG_INVALID_POLICY 0x800 -# define EXFLAG_FRESHEST 0x1000 -/* Self signed */ -# define EXFLAG_SS 0x2000 - -# define KU_DIGITAL_SIGNATURE 0x0080 -# define KU_NON_REPUDIATION 0x0040 -# define KU_KEY_ENCIPHERMENT 0x0020 -# define KU_DATA_ENCIPHERMENT 0x0010 -# define KU_KEY_AGREEMENT 0x0008 -# define KU_KEY_CERT_SIGN 0x0004 -# define KU_CRL_SIGN 0x0002 -# define KU_ENCIPHER_ONLY 0x0001 -# define KU_DECIPHER_ONLY 0x8000 - -# define NS_SSL_CLIENT 0x80 -# define NS_SSL_SERVER 0x40 -# define NS_SMIME 0x20 -# define NS_OBJSIGN 0x10 -# define NS_SSL_CA 0x04 -# define NS_SMIME_CA 0x02 -# define NS_OBJSIGN_CA 0x01 -# define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) - -# define XKU_SSL_SERVER 0x1 -# define XKU_SSL_CLIENT 0x2 -# define XKU_SMIME 0x4 -# define XKU_CODE_SIGN 0x8 -# define XKU_SGC 0x10 -# define XKU_OCSP_SIGN 0x20 -# define XKU_TIMESTAMP 0x40 -# define XKU_DVCS 0x80 -# define XKU_ANYEKU 0x100 - -# define X509_PURPOSE_DYNAMIC 0x1 -# define X509_PURPOSE_DYNAMIC_NAME 0x2 - -typedef struct x509_purpose_st { - int purpose; - int trust; /* Default trust ID */ - int flags; - int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int); - char *name; - char *sname; - void *usr_data; -} X509_PURPOSE; - -# define X509_PURPOSE_SSL_CLIENT 1 -# define X509_PURPOSE_SSL_SERVER 2 -# define X509_PURPOSE_NS_SSL_SERVER 3 -# define X509_PURPOSE_SMIME_SIGN 4 -# define X509_PURPOSE_SMIME_ENCRYPT 5 -# define X509_PURPOSE_CRL_SIGN 6 -# define X509_PURPOSE_ANY 7 -# define X509_PURPOSE_OCSP_HELPER 8 -# define X509_PURPOSE_TIMESTAMP_SIGN 9 - -# define X509_PURPOSE_MIN 1 -# define X509_PURPOSE_MAX 9 - -/* Flags for X509V3_EXT_print() */ - -# define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) -/* Return error for unknown extensions */ -# define X509V3_EXT_DEFAULT 0 -/* Print error for unknown extensions */ -# define X509V3_EXT_ERROR_UNKNOWN (1L << 16) -/* ASN1 parse unknown extensions */ -# define X509V3_EXT_PARSE_UNKNOWN (2L << 16) -/* BIO_dump unknown extensions */ -# define X509V3_EXT_DUMP_UNKNOWN (3L << 16) - -/* Flags for X509V3_add1_i2d */ - -# define X509V3_ADD_OP_MASK 0xfL -# define X509V3_ADD_DEFAULT 0L -# define X509V3_ADD_APPEND 1L -# define X509V3_ADD_REPLACE 2L -# define X509V3_ADD_REPLACE_EXISTING 3L -# define X509V3_ADD_KEEP_EXISTING 4L -# define X509V3_ADD_DELETE 5L -# define X509V3_ADD_SILENT 0x10 - -DECLARE_STACK_OF(X509_PURPOSE) - -DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) - -DECLARE_ASN1_FUNCTIONS(SXNET) -DECLARE_ASN1_FUNCTIONS(SXNETID) - -int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); -int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, - int userlen); -int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, - int userlen); - -ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone); -ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); -ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); - -DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) - -DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) - -DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) -GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); -int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); - -ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, - STACK_OF(CONF_VALUE) *nval); -STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, - ASN1_BIT_STRING *bits, - STACK_OF(CONF_VALUE) *extlist); - -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, - GENERAL_NAME *gen, - STACK_OF(CONF_VALUE) *ret); -int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); - -DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) - -STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, - GENERAL_NAMES *gen, - STACK_OF(CONF_VALUE) *extlist); -GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); - -DECLARE_ASN1_FUNCTIONS(OTHERNAME) -DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) -int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); -void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); -void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); -int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, - ASN1_OBJECT *oid, ASN1_TYPE *value); -int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, - ASN1_OBJECT **poid, ASN1_TYPE **pvalue); - -char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, - ASN1_OCTET_STRING *ia5); -ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, char *str); - -DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) -int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a); - -DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) -DECLARE_ASN1_FUNCTIONS(POLICYINFO) -DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) -DECLARE_ASN1_FUNCTIONS(USERNOTICE) -DECLARE_ASN1_FUNCTIONS(NOTICEREF) - -DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) -DECLARE_ASN1_FUNCTIONS(DIST_POINT) -DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) -DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) - -int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); - -int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); - -DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) -DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) - -DECLARE_ASN1_ITEM(POLICY_MAPPING) -DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) -DECLARE_ASN1_ITEM(POLICY_MAPPINGS) - -DECLARE_ASN1_ITEM(GENERAL_SUBTREE) -DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) - -DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) -DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) - -DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) -DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) - -GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, int gen_type, char *value, - int is_nc); - -# ifdef HEADER_CONF_H -GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf); -GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, - const X509V3_EXT_METHOD *method, - X509V3_CTX *ctx, CONF_VALUE *cnf, - int is_nc); -void X509V3_conf_free(CONF_VALUE *val); - -X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, - char *value); -X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, - char *value); -int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, - STACK_OF(X509_EXTENSION) **sk); -int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, - X509 *cert); -int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, - X509_REQ *req); -int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, - X509_CRL *crl); - -X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, - X509V3_CTX *ctx, int ext_nid, - char *value); -X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - char *name, char *value); -int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - char *section, X509 *cert); -int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - char *section, X509_REQ *req); -int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, - char *section, X509_CRL *crl); - -int X509V3_add_value_bool_nf(char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); -int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); -int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); -void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); -void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); -# endif - -char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); -STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section); -void X509V3_string_free(X509V3_CTX *ctx, char *str); -void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); -void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, - X509_REQ *req, X509_CRL *crl, int flags); - -int X509V3_add_value(const char *name, const char *value, - STACK_OF(CONF_VALUE) **extlist); -int X509V3_add_value_uchar(const char *name, const unsigned char *value, - STACK_OF(CONF_VALUE) **extlist); -int X509V3_add_value_bool(const char *name, int asn1_bool, - STACK_OF(CONF_VALUE) **extlist); -int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, - STACK_OF(CONF_VALUE) **extlist); -char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint); -ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value); -char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); -char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, - ASN1_ENUMERATED *aint); -int X509V3_EXT_add(X509V3_EXT_METHOD *ext); -int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); -int X509V3_EXT_add_alias(int nid_to, int nid_from); -void X509V3_EXT_cleanup(void); - -const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); -const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); -int X509V3_add_standard_extensions(void); -STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); -void *X509V3_EXT_d2i(X509_EXTENSION *ext); -void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, - int *idx); -int X509V3_EXT_free(int nid, void *ext_data); - -X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); -int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, - int crit, unsigned long flags); - -char *hex_to_string(const unsigned char *buffer, long len); -unsigned char *string_to_hex(const char *str, long *len); -int name_cmp(const char *name, const char *cmp); - -void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, - int ml); -int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, - int indent); -int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); - -int X509V3_extensions_print(BIO *out, char *title, - STACK_OF(X509_EXTENSION) *exts, - unsigned long flag, int indent); - -int X509_check_ca(X509 *x); -int X509_check_purpose(X509 *x, int id, int ca); -int X509_supported_extension(X509_EXTENSION *ex); -int X509_PURPOSE_set(int *p, int purpose); -int X509_check_issued(X509 *issuer, X509 *subject); -int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); -int X509_PURPOSE_get_count(void); -X509_PURPOSE *X509_PURPOSE_get0(int idx); -int X509_PURPOSE_get_by_sname(char *sname); -int X509_PURPOSE_get_by_id(int id); -int X509_PURPOSE_add(int id, int trust, int flags, - int (*ck) (const X509_PURPOSE *, const X509 *, int), - char *name, char *sname, void *arg); -char *X509_PURPOSE_get0_name(X509_PURPOSE *xp); -char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp); -int X509_PURPOSE_get_trust(X509_PURPOSE *xp); -void X509_PURPOSE_cleanup(void); -int X509_PURPOSE_get_id(X509_PURPOSE *); - -STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); -STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); -void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); -STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); -/* Flags for X509_check_* functions */ - -/* - * Always check subject name for host match even if subject alt names present - */ -# define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT 0x1 -/* Disable wildcard matching for dnsName fields and common name. */ -# define X509_CHECK_FLAG_NO_WILDCARDS 0x2 -/* Wildcards must not match a partial label. */ -# define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS 0x4 -/* Allow (non-partial) wildcards to match multiple labels. */ -# define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS 0x8 -/* Constraint verifier subdomain patterns to match a single labels. */ -# define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS 0x10 -/* - * Match reference identifiers starting with "." to any sub-domain. - * This is a non-public flag, turned on implicitly when the subject - * reference identity is a DNS name. - */ -# define _X509_CHECK_FLAG_DOT_SUBDOMAINS 0x8000 - -int X509_check_host(X509 *x, const char *chk, size_t chklen, - unsigned int flags, char **peername); -int X509_check_email(X509 *x, const char *chk, size_t chklen, - unsigned int flags); -int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, - unsigned int flags); -int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); - -ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); -ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); -int a2i_ipadd(unsigned char *ipout, const char *ipasc); -int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, - unsigned long chtype); - -void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); -DECLARE_STACK_OF(X509_POLICY_NODE) - -# ifndef OPENSSL_NO_RFC3779 - -typedef struct ASRange_st { - ASN1_INTEGER *min, *max; -} ASRange; - -# define ASIdOrRange_id 0 -# define ASIdOrRange_range 1 - -typedef struct ASIdOrRange_st { - int type; - union { - ASN1_INTEGER *id; - ASRange *range; - } u; -} ASIdOrRange; - -typedef STACK_OF(ASIdOrRange) ASIdOrRanges; -DECLARE_STACK_OF(ASIdOrRange) - -# define ASIdentifierChoice_inherit 0 -# define ASIdentifierChoice_asIdsOrRanges 1 - -typedef struct ASIdentifierChoice_st { - int type; - union { - ASN1_NULL *inherit; - ASIdOrRanges *asIdsOrRanges; - } u; -} ASIdentifierChoice; - -typedef struct ASIdentifiers_st { - ASIdentifierChoice *asnum, *rdi; -} ASIdentifiers; - -DECLARE_ASN1_FUNCTIONS(ASRange) -DECLARE_ASN1_FUNCTIONS(ASIdOrRange) -DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice) -DECLARE_ASN1_FUNCTIONS(ASIdentifiers) - -typedef struct IPAddressRange_st { - ASN1_BIT_STRING *min, *max; -} IPAddressRange; - -# define IPAddressOrRange_addressPrefix 0 -# define IPAddressOrRange_addressRange 1 - -typedef struct IPAddressOrRange_st { - int type; - union { - ASN1_BIT_STRING *addressPrefix; - IPAddressRange *addressRange; - } u; -} IPAddressOrRange; - -typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; -DECLARE_STACK_OF(IPAddressOrRange) - -# define IPAddressChoice_inherit 0 -# define IPAddressChoice_addressesOrRanges 1 - -typedef struct IPAddressChoice_st { - int type; - union { - ASN1_NULL *inherit; - IPAddressOrRanges *addressesOrRanges; - } u; -} IPAddressChoice; - -typedef struct IPAddressFamily_st { - ASN1_OCTET_STRING *addressFamily; - IPAddressChoice *ipAddressChoice; -} IPAddressFamily; - -typedef STACK_OF(IPAddressFamily) IPAddrBlocks; -DECLARE_STACK_OF(IPAddressFamily) - -DECLARE_ASN1_FUNCTIONS(IPAddressRange) -DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) -DECLARE_ASN1_FUNCTIONS(IPAddressChoice) -DECLARE_ASN1_FUNCTIONS(IPAddressFamily) - -/* - * API tag for elements of the ASIdentifer SEQUENCE. - */ -# define V3_ASID_ASNUM 0 -# define V3_ASID_RDI 1 - -/* - * AFI values, assigned by IANA. It'd be nice to make the AFI - * handling code totally generic, but there are too many little things - * that would need to be defined for other address families for it to - * be worth the trouble. - */ -# define IANA_AFI_IPV4 1 -# define IANA_AFI_IPV6 2 - -/* - * Utilities to construct and extract values from RFC3779 extensions, - * since some of the encodings (particularly for IP address prefixes - * and ranges) are a bit tedious to work with directly. - */ -int v3_asid_add_inherit(ASIdentifiers *asid, int which); -int v3_asid_add_id_or_range(ASIdentifiers *asid, int which, - ASN1_INTEGER *min, ASN1_INTEGER *max); -int v3_addr_add_inherit(IPAddrBlocks *addr, - const unsigned afi, const unsigned *safi); -int v3_addr_add_prefix(IPAddrBlocks *addr, - const unsigned afi, const unsigned *safi, - unsigned char *a, const int prefixlen); -int v3_addr_add_range(IPAddrBlocks *addr, - const unsigned afi, const unsigned *safi, - unsigned char *min, unsigned char *max); -unsigned v3_addr_get_afi(const IPAddressFamily *f); -int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, - unsigned char *min, unsigned char *max, - const int length); - -/* - * Canonical forms. - */ -int v3_asid_is_canonical(ASIdentifiers *asid); -int v3_addr_is_canonical(IPAddrBlocks *addr); -int v3_asid_canonize(ASIdentifiers *asid); -int v3_addr_canonize(IPAddrBlocks *addr); - -/* - * Tests for inheritance and containment. - */ -int v3_asid_inherits(ASIdentifiers *asid); -int v3_addr_inherits(IPAddrBlocks *addr); -int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); -int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); - -/* - * Check whether RFC 3779 extensions nest properly in chains. - */ -int v3_asid_validate_path(X509_STORE_CTX *); -int v3_addr_validate_path(X509_STORE_CTX *); -int v3_asid_validate_resource_set(STACK_OF(X509) *chain, - ASIdentifiers *ext, int allow_inheritance); -int v3_addr_validate_resource_set(STACK_OF(X509) *chain, - IPAddrBlocks *ext, int allow_inheritance); - -# endif /* OPENSSL_NO_RFC3779 */ - -/* BEGIN ERROR CODES */ -/* - * The following lines are auto generated by the script mkerr.pl. Any changes - * made after this point may be overwritten when the script is next run. - */ -void ERR_load_X509V3_strings(void); - -/* Error codes for the X509V3 functions. */ - -/* Function codes. */ -# define X509V3_F_A2I_GENERAL_NAME 164 -# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 -# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 -# define X509V3_F_COPY_EMAIL 122 -# define X509V3_F_COPY_ISSUER 123 -# define X509V3_F_DO_DIRNAME 144 -# define X509V3_F_DO_EXT_CONF 124 -# define X509V3_F_DO_EXT_I2D 135 -# define X509V3_F_DO_EXT_NCONF 151 -# define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 -# define X509V3_F_GNAMES_FROM_SECTNAME 156 -# define X509V3_F_HEX_TO_STRING 111 -# define X509V3_F_I2S_ASN1_ENUMERATED 121 -# define X509V3_F_I2S_ASN1_IA5STRING 149 -# define X509V3_F_I2S_ASN1_INTEGER 120 -# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 -# define X509V3_F_NOTICE_SECTION 132 -# define X509V3_F_NREF_NOS 133 -# define X509V3_F_POLICY_SECTION 131 -# define X509V3_F_PROCESS_PCI_VALUE 150 -# define X509V3_F_R2I_CERTPOL 130 -# define X509V3_F_R2I_PCI 155 -# define X509V3_F_S2I_ASN1_IA5STRING 100 -# define X509V3_F_S2I_ASN1_INTEGER 108 -# define X509V3_F_S2I_ASN1_OCTET_STRING 112 -# define X509V3_F_S2I_ASN1_SKEY_ID 114 -# define X509V3_F_S2I_SKEY_ID 115 -# define X509V3_F_SET_DIST_POINT_NAME 158 -# define X509V3_F_STRING_TO_HEX 113 -# define X509V3_F_SXNET_ADD_ID_ASC 125 -# define X509V3_F_SXNET_ADD_ID_INTEGER 126 -# define X509V3_F_SXNET_ADD_ID_ULONG 127 -# define X509V3_F_SXNET_GET_ID_ASC 128 -# define X509V3_F_SXNET_GET_ID_ULONG 129 -# define X509V3_F_V2I_ASIDENTIFIERS 163 -# define X509V3_F_V2I_ASN1_BIT_STRING 101 -# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 -# define X509V3_F_V2I_AUTHORITY_KEYID 119 -# define X509V3_F_V2I_BASIC_CONSTRAINTS 102 -# define X509V3_F_V2I_CRLD 134 -# define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 -# define X509V3_F_V2I_GENERAL_NAMES 118 -# define X509V3_F_V2I_GENERAL_NAME_EX 117 -# define X509V3_F_V2I_IDP 157 -# define X509V3_F_V2I_IPADDRBLOCKS 159 -# define X509V3_F_V2I_ISSUER_ALT 153 -# define X509V3_F_V2I_NAME_CONSTRAINTS 147 -# define X509V3_F_V2I_POLICY_CONSTRAINTS 146 -# define X509V3_F_V2I_POLICY_MAPPINGS 145 -# define X509V3_F_V2I_SUBJECT_ALT 154 -# define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 -# define X509V3_F_V3_GENERIC_EXTENSION 116 -# define X509V3_F_X509V3_ADD1_I2D 140 -# define X509V3_F_X509V3_ADD_VALUE 105 -# define X509V3_F_X509V3_EXT_ADD 104 -# define X509V3_F_X509V3_EXT_ADD_ALIAS 106 -# define X509V3_F_X509V3_EXT_CONF 107 -# define X509V3_F_X509V3_EXT_FREE 165 -# define X509V3_F_X509V3_EXT_I2D 136 -# define X509V3_F_X509V3_EXT_NCONF 152 -# define X509V3_F_X509V3_GET_SECTION 142 -# define X509V3_F_X509V3_GET_STRING 143 -# define X509V3_F_X509V3_GET_VALUE_BOOL 110 -# define X509V3_F_X509V3_PARSE_LIST 109 -# define X509V3_F_X509_PURPOSE_ADD 137 -# define X509V3_F_X509_PURPOSE_SET 141 - -/* Reason codes. */ -# define X509V3_R_BAD_IP_ADDRESS 118 -# define X509V3_R_BAD_OBJECT 119 -# define X509V3_R_BN_DEC2BN_ERROR 100 -# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 -# define X509V3_R_CANNOT_FIND_FREE_FUNCTION 168 -# define X509V3_R_DIRNAME_ERROR 149 -# define X509V3_R_DISTPOINT_ALREADY_SET 160 -# define X509V3_R_DUPLICATE_ZONE_ID 133 -# define X509V3_R_ERROR_CONVERTING_ZONE 131 -# define X509V3_R_ERROR_CREATING_EXTENSION 144 -# define X509V3_R_ERROR_IN_EXTENSION 128 -# define X509V3_R_EXPECTED_A_SECTION_NAME 137 -# define X509V3_R_EXTENSION_EXISTS 145 -# define X509V3_R_EXTENSION_NAME_ERROR 115 -# define X509V3_R_EXTENSION_NOT_FOUND 102 -# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 -# define X509V3_R_EXTENSION_VALUE_ERROR 116 -# define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 -# define X509V3_R_ILLEGAL_HEX_DIGIT 113 -# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 -# define X509V3_R_INVALID_ASNUMBER 162 -# define X509V3_R_INVALID_ASRANGE 163 -# define X509V3_R_INVALID_BOOLEAN_STRING 104 -# define X509V3_R_INVALID_EXTENSION_STRING 105 -# define X509V3_R_INVALID_INHERITANCE 165 -# define X509V3_R_INVALID_IPADDRESS 166 -# define X509V3_R_INVALID_MULTIPLE_RDNS 161 -# define X509V3_R_INVALID_NAME 106 -# define X509V3_R_INVALID_NULL_ARGUMENT 107 -# define X509V3_R_INVALID_NULL_NAME 108 -# define X509V3_R_INVALID_NULL_VALUE 109 -# define X509V3_R_INVALID_NUMBER 140 -# define X509V3_R_INVALID_NUMBERS 141 -# define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 -# define X509V3_R_INVALID_OPTION 138 -# define X509V3_R_INVALID_POLICY_IDENTIFIER 134 -# define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 -# define X509V3_R_INVALID_PURPOSE 146 -# define X509V3_R_INVALID_SAFI 164 -# define X509V3_R_INVALID_SECTION 135 -# define X509V3_R_INVALID_SYNTAX 143 -# define X509V3_R_ISSUER_DECODE_ERROR 126 -# define X509V3_R_MISSING_VALUE 124 -# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 -# define X509V3_R_NO_CONFIG_DATABASE 136 -# define X509V3_R_NO_ISSUER_CERTIFICATE 121 -# define X509V3_R_NO_ISSUER_DETAILS 127 -# define X509V3_R_NO_POLICY_IDENTIFIER 139 -# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 -# define X509V3_R_NO_PUBLIC_KEY 114 -# define X509V3_R_NO_SUBJECT_DETAILS 125 -# define X509V3_R_ODD_NUMBER_OF_DIGITS 112 -# define X509V3_R_OPERATION_NOT_DEFINED 148 -# define X509V3_R_OTHERNAME_ERROR 147 -# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 -# define X509V3_R_POLICY_PATH_LENGTH 156 -# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 -# define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 -# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 -# define X509V3_R_SECTION_NOT_FOUND 150 -# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 -# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 -# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 -# define X509V3_R_UNKNOWN_EXTENSION 129 -# define X509V3_R_UNKNOWN_EXTENSION_NAME 130 -# define X509V3_R_UNKNOWN_OPTION 120 -# define X509V3_R_UNSUPPORTED_OPTION 117 -# define X509V3_R_UNSUPPORTED_TYPE 167 -# define X509V3_R_USER_TOO_LONG 132 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/Sources/COpenSSL/x_.c b/Sources/COpenSSL/x_.c deleted file mode 100644 index 337d6534..00000000 --- a/Sources/COpenSSL/x_.c +++ /dev/null @@ -1,3893 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* x_algor.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -#include "x509.h" -#include "asn1.h" -#include "asn1t.h" - -ASN1_SEQUENCE(X509_ALGOR) = { - ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), - ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY) -} ASN1_SEQUENCE_END(X509_ALGOR) - -ASN1_ITEM_TEMPLATE(X509_ALGORS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR) -ASN1_ITEM_TEMPLATE_END(X509_ALGORS) - -IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS) -IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR) - -IMPLEMENT_STACK_OF(X509_ALGOR) -IMPLEMENT_ASN1_SET_OF(X509_ALGOR) - -int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) -{ - if (!alg) - return 0; - if (ptype != V_ASN1_UNDEF) { - if (alg->parameter == NULL) - alg->parameter = ASN1_TYPE_new(); - if (alg->parameter == NULL) - return 0; - } - if (alg) { - if (alg->algorithm) - ASN1_OBJECT_free(alg->algorithm); - alg->algorithm = aobj; - } - if (ptype == 0) - return 1; - if (ptype == V_ASN1_UNDEF) { - if (alg->parameter) { - ASN1_TYPE_free(alg->parameter); - alg->parameter = NULL; - } - } else - ASN1_TYPE_set(alg->parameter, ptype, pval); - return 1; -} - -void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, - X509_ALGOR *algor) -{ - if (paobj) - *paobj = algor->algorithm; - if (pptype) { - if (algor->parameter == NULL) { - *pptype = V_ASN1_UNDEF; - return; - } else - *pptype = algor->parameter->type; - if (ppval) - *ppval = algor->parameter->value.ptr; - } -} - -/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ - -void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) -{ - int param_type; - - if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) - param_type = V_ASN1_UNDEF; - else - param_type = V_ASN1_NULL; - - X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); - -} - -int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) -{ - int rv; - rv = OBJ_cmp(a->algorithm, b->algorithm); - if (rv) - return rv; - if (!a->parameter && !b->parameter) - return 0; - return ASN1_TYPE_cmp(a->parameter, b->parameter); -} -/* crypto/x509/x_all.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include "stack.h" -#include "cryptlib.h" -#include "buffer.h" -// #include "asn1.h" -#include "evp.h" -// #include "x509.h" -#include "ocsp.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif - -int X509_verify(X509 *a, EVP_PKEY *r) -{ - if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature)) - return 0; - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg, - a->signature, a->cert_info, r)); -} - -int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) -{ - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), - a->sig_alg, a->signature, a->req_info, r)); -} - -int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) -{ - return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), - a->sig_algor, a->signature, a->spkac, r)); -} - -int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - x->cert_info->enc.modified = 1; - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, - x->sig_alg, x->signature, x->cert_info, pkey, md)); -} - -int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) -{ - x->cert_info->enc.modified = 1; - return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), - x->cert_info->signature, - x->sig_alg, x->signature, x->cert_info, ctx); -} - -int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert) -{ - return OCSP_REQ_CTX_nbio_d2i(rctx, - (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509)); -} - -int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, - x->signature, x->req_info, pkey, md)); -} - -int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) -{ - return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), - x->sig_alg, NULL, x->signature, x->req_info, - ctx); -} - -int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - x->crl->enc.modified = 1; - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, - x->sig_alg, x->signature, x->crl, pkey, md)); -} - -int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) -{ - x->crl->enc.modified = 1; - return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), - x->crl->sig_alg, x->sig_alg, x->signature, - x->crl, ctx); -} - -int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl) -{ - return OCSP_REQ_CTX_nbio_d2i(rctx, - (ASN1_VALUE **)pcrl, - ASN1_ITEM_rptr(X509_CRL)); -} - -int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) -{ - return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, - x->signature, x->spkac, pkey, md)); -} - -#ifndef OPENSSL_NO_FP_API -X509 *d2i_X509_fp(FILE *fp, X509 **x509) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); -} - -int i2d_X509_fp(FILE *fp, X509 *x509) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); -} -#endif - -X509 *d2i_X509_bio(BIO *bp, X509 **x509) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); -} - -int i2d_X509_bio(BIO *bp, X509 *x509) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); -} - -#ifndef OPENSSL_NO_FP_API -X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); -} - -int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); -} -#endif - -X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); -} - -int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); -} - -#ifndef OPENSSL_NO_FP_API -PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); -} - -int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); -} -#endif - -PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); -} - -int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); -} - -#ifndef OPENSSL_NO_FP_API -X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); -} - -int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); -} -#endif - -X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); -} - -int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); -} - -#ifndef OPENSSL_NO_RSA - -# ifndef OPENSSL_NO_FP_API -RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); -} - -int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); -} - -RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) -{ - return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); -} - -RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa) -{ - return ASN1_d2i_fp((void *(*)(void)) - RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp, - (void **)rsa); -} - -int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) -{ - return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); -} - -int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) -{ - return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa); -} -# endif - -RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); -} - -int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); -} - -RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) -{ - return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); -} - -RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa) -{ - return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa); -} - -int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) -{ - return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); -} - -int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) -{ - return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa); -} -#endif - -#ifndef OPENSSL_NO_DSA -# ifndef OPENSSL_NO_FP_API -DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) -{ - return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa); -} - -int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) -{ - return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa); -} - -DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa) -{ - return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa); -} - -int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa) -{ - return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa); -} -# endif - -DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) -{ - return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa); -} - -int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) -{ - return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa); -} - -DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa) -{ - return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa); -} - -int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa) -{ - return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa); -} - -#endif - -#ifndef OPENSSL_NO_EC -# ifndef OPENSSL_NO_FP_API -EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey) -{ - return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey); -} - -int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey) -{ - return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey); -} - -EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) -{ - return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey); -} - -int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) -{ - return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey); -} -# endif -EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey) -{ - return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey); -} - -int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa) -{ - return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa); -} - -EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) -{ - return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey); -} - -int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) -{ - return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey); -} -#endif - -int X509_pubkey_digest(const X509 *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) -{ - ASN1_BIT_STRING *key; - key = X509_get0_pubkey_bitstr(data); - if (!key) - return 0; - return EVP_Digest(key->data, key->length, md, len, type, NULL); -} - -int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, - unsigned int *len) -{ - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509), type, (char *)data, md, len)); -} - -int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) -{ - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len)); -} - -int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) -{ - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len)); -} - -int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, - unsigned char *md, unsigned int *len) -{ - return (ASN1_item_digest - (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len)); -} - -int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, - const EVP_MD *type, unsigned char *md, - unsigned int *len) -{ - return (ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type, - (char *)data, md, len)); -} - -#ifndef OPENSSL_NO_FP_API -X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) -{ - return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8); -} - -int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) -{ - return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8); -} -#endif - -X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) -{ - return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8); -} - -int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) -{ - return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8); -} - -#ifndef OPENSSL_NO_FP_API -PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, - PKCS8_PRIV_KEY_INFO **p8inf) -{ - return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, - d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf); -} - -int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) -{ - return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp, - p8inf); -} - -int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) -{ - PKCS8_PRIV_KEY_INFO *p8inf; - int ret; - p8inf = EVP_PKEY2PKCS8(key); - if (!p8inf) - return 0; - ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; -} - -int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) -{ - return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey); -} - -EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) -{ - return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a); -} - -int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey) -{ - return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey); -} - -EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a) -{ - return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a); -} - -#endif - -PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, - PKCS8_PRIV_KEY_INFO **p8inf) -{ - return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, - d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf); -} - -int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) -{ - return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp, - p8inf); -} - -int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) -{ - PKCS8_PRIV_KEY_INFO *p8inf; - int ret; - p8inf = EVP_PKEY2PKCS8(key); - if (!p8inf) - return 0; - ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); - PKCS8_PRIV_KEY_INFO_free(p8inf); - return ret; -} - -int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) -{ - return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey); -} - -EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) -{ - return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a); -} - -int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) -{ - return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey); -} - -EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) -{ - return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a); -} -/* crypto/asn1/x_attrib.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -#include "objects.h" -// #include "asn1t.h" -// #include "x509.h" - -/*- - * X509_ATTRIBUTE: this has the following form: - * - * typedef struct x509_attributes_st - * { - * ASN1_OBJECT *object; - * int single; - * union { - * char *ptr; - * STACK_OF(ASN1_TYPE) *set; - * ASN1_TYPE *single; - * } value; - * } X509_ATTRIBUTE; - * - * this needs some extra thought because the CHOICE type is - * merged with the main structure and because the value can - * be anything at all we *must* try the SET OF first because - * the ASN1_ANY type will swallow anything including the whole - * SET OF structure. - */ - -ASN1_CHOICE(X509_ATTRIBUTE_SET) = { - ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY), - ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY) -} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single) - -ASN1_SEQUENCE(X509_ATTRIBUTE) = { - ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT), - /* CHOICE type merged with parent */ - ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET) -} ASN1_SEQUENCE_END(X509_ATTRIBUTE) - -IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE) -IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE) - -X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value) -{ - X509_ATTRIBUTE *ret = NULL; - ASN1_TYPE *val = NULL; - - if ((ret = X509_ATTRIBUTE_new()) == NULL) - return (NULL); - ret->object = OBJ_nid2obj(nid); - ret->single = 0; - if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL) - goto err; - if ((val = ASN1_TYPE_new()) == NULL) - goto err; - if (!sk_ASN1_TYPE_push(ret->value.set, val)) - goto err; - - ASN1_TYPE_set(val, atrtype, value); - return (ret); - err: - if (ret != NULL) - X509_ATTRIBUTE_free(ret); - if (val != NULL) - ASN1_TYPE_free(val); - return (NULL); -} -/* x_bignum.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -#include "bn.h" - -/* - * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER - * as a BIGNUM directly. Currently it ignores the sign which isn't a problem - * since all BIGNUMs used are non negative and anything that looks negative - * is normally due to an encoding error. - */ - -#define BN_SENSITIVE 1 - -static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); -static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); - -static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, - const ASN1_ITEM *it); -static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, char *free_cont, const ASN1_ITEM *it); -static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, - int indent, const ASN1_PCTX *pctx); - -static ASN1_PRIMITIVE_FUNCS bignum_pf = { - NULL, 0, - bn_new, - bn_free, - 0, - bn_c2i, - bn_i2c, - bn_print -}; - -ASN1_ITEM_start(BIGNUM) - ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM" -ASN1_ITEM_end(BIGNUM) - -ASN1_ITEM_start(CBIGNUM) - ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM" -ASN1_ITEM_end(CBIGNUM) - -static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - *pval = (ASN1_VALUE *)BN_new(); - if (*pval) - return 1; - else - return 0; -} - -static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - if (!*pval) - return; - if (it->size & BN_SENSITIVE) - BN_clear_free((BIGNUM *)*pval); - else - BN_free((BIGNUM *)*pval); - *pval = NULL; -} - -static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, - const ASN1_ITEM *it) -{ - BIGNUM *bn; - int pad; - if (!*pval) - return -1; - bn = (BIGNUM *)*pval; - /* If MSB set in an octet we need a padding byte */ - if (BN_num_bits(bn) & 0x7) - pad = 0; - else - pad = 1; - if (cont) { - if (pad) - *cont++ = 0; - BN_bn2bin(bn, cont); - } - return pad + BN_num_bytes(bn); -} - -static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, char *free_cont, const ASN1_ITEM *it) -{ - BIGNUM *bn; - - if (*pval == NULL && !bn_new(pval, it)) - return 0; - bn = (BIGNUM *)*pval; - if (!BN_bin2bn(cont, len, bn)) { - bn_free(pval, it); - return 0; - } - return 1; -} - -static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, - int indent, const ASN1_PCTX *pctx) -{ - if (!BN_print(out, *(BIGNUM **)pval)) - return 0; - if (BIO_puts(out, "\n") <= 0) - return 0; - return 1; -} -/* crypto/asn1/x_crl.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -#include "asn1_locl.h" -// #include "x509.h" -#include "x509v3.h" - -static int X509_REVOKED_cmp(const X509_REVOKED *const *a, - const X509_REVOKED *const *b); -static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); - -ASN1_SEQUENCE(X509_REVOKED) = { - ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER), - ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME), - ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) -} ASN1_SEQUENCE_END(X509_REVOKED) - -static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); -static int def_crl_lookup(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial, - X509_NAME *issuer); - -static X509_CRL_METHOD int_crl_meth = { - 0, - 0, 0, - def_crl_lookup, - def_crl_verify -}; - -static const X509_CRL_METHOD *default_crl_method = &int_crl_meth; - -/* - * The X509_CRL_INFO structure needs a bit of customisation. Since we cache - * the original encoding the signature wont be affected by reordering of the - * revoked field. - */ -static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; - - if (!a || !a->revoked) - return 1; - switch (operation) { - /* - * Just set cmp function here. We don't sort because that would - * affect the output of X509_CRL_print(). - */ - case ASN1_OP_D2I_POST: - (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp); - break; - } - return 1; -} - - -ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { - ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR), - ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME), - ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME), - ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME), - ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED), - ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) -} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) - -/* - * Set CRL entry issuer according to CRL certificate issuer extension. Check - * for unhandled critical CRL entry extensions. - */ - -static int crl_set_issuers(X509_CRL *crl) -{ - - int i, j; - GENERAL_NAMES *gens, *gtmp; - STACK_OF(X509_REVOKED) *revoked; - - revoked = X509_CRL_get_REVOKED(crl); - - gens = NULL; - for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { - X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); - STACK_OF(X509_EXTENSION) *exts; - ASN1_ENUMERATED *reason; - X509_EXTENSION *ext; - gtmp = X509_REVOKED_get_ext_d2i(rev, - NID_certificate_issuer, &j, NULL); - if (!gtmp && (j != -1)) { - crl->flags |= EXFLAG_INVALID; - return 1; - } - - if (gtmp) { - gens = gtmp; - if (!crl->issuers) { - crl->issuers = sk_GENERAL_NAMES_new_null(); - if (!crl->issuers) - return 0; - } - if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) - return 0; - } - rev->issuer = gens; - - reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); - if (!reason && (j != -1)) { - crl->flags |= EXFLAG_INVALID; - return 1; - } - - if (reason) { - rev->reason = ASN1_ENUMERATED_get(reason); - ASN1_ENUMERATED_free(reason); - } else - rev->reason = CRL_REASON_NONE; - - /* Check for critical CRL entry extensions */ - - exts = rev->extensions; - - for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) { - ext = sk_X509_EXTENSION_value(exts, j); - if (ext->critical > 0) { - if (OBJ_obj2nid(ext->object) == NID_certificate_issuer) - continue; - crl->flags |= EXFLAG_CRITICAL; - break; - } - } - - } - - return 1; - -} - -/* - * The X509_CRL structure needs a bit of customisation. Cache some extensions - * and hash of the whole CRL. - */ -static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - X509_CRL *crl = (X509_CRL *)*pval; - STACK_OF(X509_EXTENSION) *exts; - X509_EXTENSION *ext; - int idx; - - switch (operation) { - case ASN1_OP_NEW_POST: - crl->idp = NULL; - crl->akid = NULL; - crl->flags = 0; - crl->idp_flags = 0; - crl->idp_reasons = CRLDP_ALL_REASONS; - crl->meth = default_crl_method; - crl->meth_data = NULL; - crl->issuers = NULL; - crl->crl_number = NULL; - crl->base_crl_number = NULL; - break; - - case ASN1_OP_D2I_POST: -#ifndef OPENSSL_NO_SHA - X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); -#endif - crl->idp = X509_CRL_get_ext_d2i(crl, - NID_issuing_distribution_point, NULL, - NULL); - if (crl->idp) - setup_idp(crl, crl->idp); - - crl->akid = X509_CRL_get_ext_d2i(crl, - NID_authority_key_identifier, NULL, - NULL); - - crl->crl_number = X509_CRL_get_ext_d2i(crl, - NID_crl_number, NULL, NULL); - - crl->base_crl_number = X509_CRL_get_ext_d2i(crl, - NID_delta_crl, NULL, - NULL); - /* Delta CRLs must have CRL number */ - if (crl->base_crl_number && !crl->crl_number) - crl->flags |= EXFLAG_INVALID; - - /* - * See if we have any unhandled critical CRL extensions and indicate - * this in a flag. We only currently handle IDP so anything else - * critical sets the flag. This code accesses the X509_CRL structure - * directly: applications shouldn't do this. - */ - - exts = crl->crl->extensions; - - for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { - int nid; - - ext = sk_X509_EXTENSION_value(exts, idx); - nid = OBJ_obj2nid(ext->object); - if (nid == NID_freshest_crl) - crl->flags |= EXFLAG_FRESHEST; - if (ext->critical > 0) { - /* We handle IDP and deltas */ - if ((nid == NID_issuing_distribution_point) - || (nid == NID_authority_key_identifier) - || (nid == NID_delta_crl)) - continue; - crl->flags |= EXFLAG_CRITICAL; - break; - } - } - - if (!crl_set_issuers(crl)) - return 0; - - if (crl->meth->crl_init) { - if (crl->meth->crl_init(crl) == 0) - return 0; - } - break; - - case ASN1_OP_FREE_POST: - if (crl->meth->crl_free) { - if (!crl->meth->crl_free(crl)) - return 0; - } - if (crl->akid) - AUTHORITY_KEYID_free(crl->akid); - if (crl->idp) - ISSUING_DIST_POINT_free(crl->idp); - ASN1_INTEGER_free(crl->crl_number); - ASN1_INTEGER_free(crl->base_crl_number); - sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); - break; - } - return 1; -} - -/* Convert IDP into a more convenient form */ - -static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) -{ - int idp_only = 0; - /* Set various flags according to IDP */ - crl->idp_flags |= IDP_PRESENT; - if (idp->onlyuser > 0) { - idp_only++; - crl->idp_flags |= IDP_ONLYUSER; - } - if (idp->onlyCA > 0) { - idp_only++; - crl->idp_flags |= IDP_ONLYCA; - } - if (idp->onlyattr > 0) { - idp_only++; - crl->idp_flags |= IDP_ONLYATTR; - } - - if (idp_only > 1) - crl->idp_flags |= IDP_INVALID; - - if (idp->indirectCRL > 0) - crl->idp_flags |= IDP_INDIRECT; - - if (idp->onlysomereasons) { - crl->idp_flags |= IDP_REASONS; - if (idp->onlysomereasons->length > 0) - crl->idp_reasons = idp->onlysomereasons->data[0]; - if (idp->onlysomereasons->length > 1) - crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); - crl->idp_reasons &= CRLDP_ALL_REASONS; - } - - DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); -} - -ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = { - ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), - ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), - ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL) - -IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED) - -IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO) - -IMPLEMENT_ASN1_FUNCTIONS(X509_CRL) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL) - -static int X509_REVOKED_cmp(const X509_REVOKED *const *a, - const X509_REVOKED *const *b) -{ - return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber, - (ASN1_STRING *)(*b)->serialNumber)); -} - -int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) -{ - X509_CRL_INFO *inf; - inf = crl->crl; - if (!inf->revoked) - inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); - if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) { - ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE); - return 0; - } - inf->enc.modified = 1; - return 1; -} - -int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r) -{ - if (crl->meth->crl_verify) - return crl->meth->crl_verify(crl, r); - return 0; -} - -int X509_CRL_get0_by_serial(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial) -{ - if (crl->meth->crl_lookup) - return crl->meth->crl_lookup(crl, ret, serial, NULL); - return 0; -} - -int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) -{ - if (crl->meth->crl_lookup) - return crl->meth->crl_lookup(crl, ret, - X509_get_serialNumber(x), - X509_get_issuer_name(x)); - return 0; -} - -static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) -{ - return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), - crl->sig_alg, crl->signature, crl->crl, r)); -} - -static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, - X509_REVOKED *rev) -{ - int i; - - if (!rev->issuer) { - if (!nm) - return 1; - if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) - return 1; - return 0; - } - - if (!nm) - nm = X509_CRL_get_issuer(crl); - - for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { - GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); - if (gen->type != GEN_DIRNAME) - continue; - if (!X509_NAME_cmp(nm, gen->d.directoryName)) - return 1; - } - return 0; - -} - -static int def_crl_lookup(X509_CRL *crl, - X509_REVOKED **ret, ASN1_INTEGER *serial, - X509_NAME *issuer) -{ - X509_REVOKED rtmp, *rev; - int idx; - rtmp.serialNumber = serial; - /* - * Sort revoked into serial number order if not already sorted. Do this - * under a lock to avoid race condition. - */ - if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { - CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); - sk_X509_REVOKED_sort(crl->crl->revoked); - CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); - } - idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); - if (idx < 0) - return 0; - /* Need to look for matching name */ - for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { - rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); - if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) - return 0; - if (crl_revoked_issuer_match(crl, issuer, rev)) { - if (ret) - *ret = rev; - if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) - return 2; - return 1; - } - } - return 0; -} - -void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) -{ - if (meth == NULL) - default_crl_method = &int_crl_meth; - else - default_crl_method = meth; -} - -X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), - int (*crl_free) (X509_CRL *crl), - int (*crl_lookup) (X509_CRL *crl, - X509_REVOKED **ret, - ASN1_INTEGER *ser, - X509_NAME *issuer), - int (*crl_verify) (X509_CRL *crl, - EVP_PKEY *pk)) -{ - X509_CRL_METHOD *m; - m = OPENSSL_malloc(sizeof(X509_CRL_METHOD)); - if (!m) - return NULL; - m->crl_init = crl_init; - m->crl_free = crl_free; - m->crl_lookup = crl_lookup; - m->crl_verify = crl_verify; - m->flags = X509_CRL_METHOD_DYNAMIC; - return m; -} - -void X509_CRL_METHOD_free(X509_CRL_METHOD *m) -{ - if (!(m->flags & X509_CRL_METHOD_DYNAMIC)) - return; - OPENSSL_free(m); -} - -void X509_CRL_set_meth_data(X509_CRL *crl, void *dat) -{ - crl->meth_data = dat; -} - -void *X509_CRL_get_meth_data(X509_CRL *crl) -{ - return crl->meth_data; -} - -IMPLEMENT_STACK_OF(X509_REVOKED) - -IMPLEMENT_ASN1_SET_OF(X509_REVOKED) - -IMPLEMENT_STACK_OF(X509_CRL) - -IMPLEMENT_ASN1_SET_OF(X509_CRL) -/* x_exten.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "x509.h" -// #include "asn1.h" -// #include "asn1t.h" - -ASN1_SEQUENCE(X509_EXTENSION) = { - ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT), - ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN), - ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(X509_EXTENSION) - -ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION) -ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS) - -IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION) -IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) -IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION) -/* crypto/asn1/x_info.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "asn1.h" -// #include "x509.h" - -X509_INFO *X509_INFO_new(void) -{ - X509_INFO *ret = NULL; - - ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); - if (ret == NULL) { - ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE); - return (NULL); - } - - ret->enc_cipher.cipher = NULL; - ret->enc_len = 0; - ret->enc_data = NULL; - - ret->references = 1; - ret->x509 = NULL; - ret->crl = NULL; - ret->x_pkey = NULL; - return (ret); -} - -void X509_INFO_free(X509_INFO *x) -{ - int i; - - if (x == NULL) - return; - - i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_INFO); -#ifdef REF_PRINT - REF_PRINT("X509_INFO", x); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "X509_INFO_free, bad reference count\n"); - abort(); - } -#endif - - if (x->x509 != NULL) - X509_free(x->x509); - if (x->crl != NULL) - X509_CRL_free(x->crl); - if (x->x_pkey != NULL) - X509_PKEY_free(x->x_pkey); - if (x->enc_data != NULL) - OPENSSL_free(x->enc_data); - OPENSSL_free(x); -} - -IMPLEMENT_STACK_OF(X509_INFO) -/* x_long.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2000. - */ -/* ==================================================================== - * Copyright (c) 2000 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "bn.h" - -/* - * Custom primitive type for long handling. This converts between an - * ASN1_INTEGER and a long directly. - */ - -static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it); -static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it); - -static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, - const ASN1_ITEM *it); -static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, char *free_cont, const ASN1_ITEM *it); -static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, - int indent, const ASN1_PCTX *pctx); - -static ASN1_PRIMITIVE_FUNCS long_pf = { - NULL, 0, - long_new, - long_free, - long_free, /* Clear should set to initial value */ - long_c2i, - long_i2c, - long_print -}; - -ASN1_ITEM_start(LONG) - ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG" -ASN1_ITEM_end(LONG) - -ASN1_ITEM_start(ZLONG) - ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG" -ASN1_ITEM_end(ZLONG) - -static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - *(long *)pval = it->size; - return 1; -} - -static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - *(long *)pval = it->size; -} - -static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, - const ASN1_ITEM *it) -{ - long ltmp; - unsigned long utmp; - int clen, pad, i; - /* this exists to bypass broken gcc optimization */ - char *cp = (char *)pval; - - /* use memcpy, because we may not be long aligned */ - memcpy(<mp, cp, sizeof(long)); - - if (ltmp == it->size) - return -1; - /* - * Convert the long to positive: we subtract one if negative so we can - * cleanly handle the padding if only the MSB of the leading octet is - * set. - */ - if (ltmp < 0) - utmp = 0 - (unsigned long)ltmp - 1; - else - utmp = ltmp; - clen = BN_num_bits_word(utmp); - /* If MSB of leading octet set we need to pad */ - if (!(clen & 0x7)) - pad = 1; - else - pad = 0; - - /* Convert number of bits to number of octets */ - clen = (clen + 7) >> 3; - - if (cont) { - if (pad) - *cont++ = (ltmp < 0) ? 0xff : 0; - for (i = clen - 1; i >= 0; i--) { - cont[i] = (unsigned char)(utmp & 0xff); - if (ltmp < 0) - cont[i] ^= 0xff; - utmp >>= 8; - } - } - return clen + pad; -} - -static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, - int utype, char *free_cont, const ASN1_ITEM *it) -{ - int neg = -1, i; - long ltmp; - unsigned long utmp = 0; - char *cp = (char *)pval; - - if (len) { - /* - * Check possible pad byte. Worst case, we're skipping past actual - * content, but since that's only with 0x00 and 0xff and we set neg - * accordingly, the result will be correct in the end anyway. - */ - switch (cont[0]) { - case 0xff: - cont++; - len--; - neg = 1; - break; - case 0: - cont++; - len--; - neg = 0; - break; - } - } - if (len > (int)sizeof(long)) { - ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); - return 0; - } - if (neg == -1) { - /* Is it negative? */ - if (len && (cont[0] & 0x80)) - neg = 1; - else - neg = 0; - } - utmp = 0; - for (i = 0; i < len; i++) { - utmp <<= 8; - if (neg) - utmp |= cont[i] ^ 0xff; - else - utmp |= cont[i]; - } - ltmp = (long)utmp; - if (neg) { - ltmp = -ltmp; - ltmp--; - } - if (ltmp == it->size) { - ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); - return 0; - } - memcpy(cp, <mp, sizeof(long)); - return 1; -} - -static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, - int indent, const ASN1_PCTX *pctx) -{ - return BIO_printf(out, "%ld\n", *(long *)pval); -} -/* crypto/asn1/x_name.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" -// #include "asn1_locl.h" - -typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; -DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY) - -/* - * Maximum length of X509_NAME: much larger than anything we should - * ever see in practice. - */ - -#define X509_NAME_MAX (1024 * 1024) - -static int x509_name_ex_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_ITEM *it, - int tag, int aclass, char opt, ASN1_TLC *ctx); - -static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass); -static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); -static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); - -static int x509_name_encode(X509_NAME *a); -static int x509_name_canon(X509_NAME *a); -static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); -static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, - unsigned char **in); - -static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, - int indent, - const char *fname, const ASN1_PCTX *pctx); - -ASN1_SEQUENCE(X509_NAME_ENTRY) = { - ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), - ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) -} ASN1_SEQUENCE_END(X509_NAME_ENTRY) - -IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) -IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) - -/* - * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so - * declare two template wrappers for this - */ - -ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) -ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) - -ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = - ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) -ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) - -/* - * Normally that's where it would end: we'd have two nested STACK structures - * representing the ASN1. Unfortunately X509_NAME uses a completely different - * form and caches encodings so we have to process the internal form and - * convert to the external form. - */ - -const ASN1_EXTERN_FUNCS x509_name_ff = { - NULL, - x509_name_ex_new, - x509_name_ex_free, - 0, /* Default clear behaviour is OK */ - x509_name_ex_d2i, - x509_name_ex_i2d, - x509_name_ex_print -}; - -IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) - -IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) - -static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) -{ - X509_NAME *ret = NULL; - ret = OPENSSL_malloc(sizeof(X509_NAME)); - if (!ret) - goto memerr; - if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) - goto memerr; - if ((ret->bytes = BUF_MEM_new()) == NULL) - goto memerr; - ret->canon_enc = NULL; - ret->canon_enclen = 0; - ret->modified = 1; - *val = (ASN1_VALUE *)ret; - return 1; - - memerr: - ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); - if (ret) { - if (ret->entries) - sk_X509_NAME_ENTRY_free(ret->entries); - OPENSSL_free(ret); - } - return 0; -} - -static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) -{ - X509_NAME *a; - if (!pval || !*pval) - return; - a = (X509_NAME *)*pval; - - BUF_MEM_free(a->bytes); - sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); - if (a->canon_enc) - OPENSSL_free(a->canon_enc); - OPENSSL_free(a); - *pval = NULL; -} - -static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) -{ - sk_X509_NAME_ENTRY_free(ne); -} - -static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) -{ - sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); -} - -static int x509_name_ex_d2i(ASN1_VALUE **val, - const unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, - char opt, ASN1_TLC *ctx) -{ - const unsigned char *p = *in, *q; - union { - STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; - ASN1_VALUE *a; - } intname = { - NULL - }; - union { - X509_NAME *x; - ASN1_VALUE *a; - } nm = { - NULL - }; - int i, j, ret; - STACK_OF(X509_NAME_ENTRY) *entries; - X509_NAME_ENTRY *entry; - if (len > X509_NAME_MAX) - len = X509_NAME_MAX; - q = p; - - /* Get internal representation of Name */ - ret = ASN1_item_ex_d2i(&intname.a, - &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), - tag, aclass, opt, ctx); - - if (ret <= 0) - return ret; - - if (*val) - x509_name_ex_free(val, NULL); - if (!x509_name_ex_new(&nm.a, NULL)) - goto err; - /* We've decoded it: now cache encoding */ - if (!BUF_MEM_grow(nm.x->bytes, p - q)) - goto err; - memcpy(nm.x->bytes->data, q, p - q); - - /* Convert internal representation to X509_NAME structure */ - for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { - entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); - for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { - entry = sk_X509_NAME_ENTRY_value(entries, j); - entry->set = i; - if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) - goto err; - sk_X509_NAME_ENTRY_set(entries, j, NULL); - } - } - ret = x509_name_canon(nm.x); - if (!ret) - goto err; - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, - local_sk_X509_NAME_ENTRY_free); - nm.x->modified = 0; - *val = nm.a; - *in = p; - return ret; - err: - if (nm.x != NULL) - X509_NAME_free(nm.x); - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, - local_sk_X509_NAME_ENTRY_pop_free); - ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); - return 0; -} - -static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, - const ASN1_ITEM *it, int tag, int aclass) -{ - int ret; - X509_NAME *a = (X509_NAME *)*val; - if (a->modified) { - ret = x509_name_encode(a); - if (ret < 0) - return ret; - ret = x509_name_canon(a); - if (ret < 0) - return ret; - } - ret = a->bytes->length; - if (out != NULL) { - memcpy(*out, a->bytes->data, ret); - *out += ret; - } - return ret; -} - -static int x509_name_encode(X509_NAME *a) -{ - union { - STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; - ASN1_VALUE *a; - } intname = { - NULL - }; - int len; - unsigned char *p; - STACK_OF(X509_NAME_ENTRY) *entries = NULL; - X509_NAME_ENTRY *entry; - int i, set = -1; - intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); - if (!intname.s) - goto memerr; - for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { - entry = sk_X509_NAME_ENTRY_value(a->entries, i); - if (entry->set != set) { - entries = sk_X509_NAME_ENTRY_new_null(); - if (!entries) - goto memerr; - if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) { - sk_X509_NAME_ENTRY_free(entries); - goto memerr; - } - set = entry->set; - } - if (!sk_X509_NAME_ENTRY_push(entries, entry)) - goto memerr; - } - len = ASN1_item_ex_i2d(&intname.a, NULL, - ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); - if (!BUF_MEM_grow(a->bytes, len)) - goto memerr; - p = (unsigned char *)a->bytes->data; - ASN1_item_ex_i2d(&intname.a, - &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, - local_sk_X509_NAME_ENTRY_free); - a->modified = 0; - return len; - memerr: - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, - local_sk_X509_NAME_ENTRY_free); - ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); - return -1; -} - -static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, - int indent, - const char *fname, const ASN1_PCTX *pctx) -{ - if (X509_NAME_print_ex(out, (X509_NAME *)*pval, - indent, pctx->nm_flags) <= 0) - return 0; - return 2; -} - -/* - * This function generates the canonical encoding of the Name structure. In - * it all strings are converted to UTF8, leading, trailing and multiple - * spaces collapsed, converted to lower case and the leading SEQUENCE header - * removed. In future we could also normalize the UTF8 too. By doing this - * comparison of Name structures can be rapidly perfomed by just using - * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name - * constraints of type dirName can also be checked with a simple memcmp(). - */ - -static int x509_name_canon(X509_NAME *a) -{ - unsigned char *p; - STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; - STACK_OF(X509_NAME_ENTRY) *entries = NULL; - X509_NAME_ENTRY *entry, *tmpentry = NULL; - int i, set = -1, ret = 0; - - if (a->canon_enc) { - OPENSSL_free(a->canon_enc); - a->canon_enc = NULL; - } - /* Special case: empty X509_NAME => null encoding */ - if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { - a->canon_enclen = 0; - return 1; - } - intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); - if (!intname) - goto err; - for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { - entry = sk_X509_NAME_ENTRY_value(a->entries, i); - if (entry->set != set) { - entries = sk_X509_NAME_ENTRY_new_null(); - if (!entries) - goto err; - if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { - sk_X509_NAME_ENTRY_free(entries); - goto err; - } - set = entry->set; - } - tmpentry = X509_NAME_ENTRY_new(); - if (!tmpentry) - goto err; - tmpentry->object = OBJ_dup(entry->object); - if (!asn1_string_canon(tmpentry->value, entry->value)) - goto err; - if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) - goto err; - tmpentry = NULL; - } - - /* Finally generate encoding */ - - a->canon_enclen = i2d_name_canon(intname, NULL); - - p = OPENSSL_malloc(a->canon_enclen); - - if (!p) - goto err; - - a->canon_enc = p; - - i2d_name_canon(intname, &p); - - ret = 1; - - err: - - if (tmpentry) - X509_NAME_ENTRY_free(tmpentry); - if (intname) - sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, - local_sk_X509_NAME_ENTRY_pop_free); - return ret; -} - -/* Bitmap of all the types of string that will be canonicalized. */ - -#define ASN1_MASK_CANON \ - (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ - | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ - | B_ASN1_VISIBLESTRING) - -static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) -{ - unsigned char *to, *from; - int len, i; - - /* If type not in bitmask just copy string across */ - if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { - if (!ASN1_STRING_copy(out, in)) - return 0; - return 1; - } - - out->type = V_ASN1_UTF8STRING; - out->length = ASN1_STRING_to_UTF8(&out->data, in); - if (out->length == -1) - return 0; - - to = out->data; - from = to; - - len = out->length; - - /* - * Convert string in place to canonical form. Ultimately we may need to - * handle a wider range of characters but for now ignore anything with - * MSB set and rely on the isspace() and tolower() functions. - */ - - /* Ignore leading spaces */ - while ((len > 0) && !(*from & 0x80) && isspace(*from)) { - from++; - len--; - } - - to = from + len - 1; - - /* Ignore trailing spaces */ - while ((len > 0) && !(*to & 0x80) && isspace(*to)) { - to--; - len--; - } - - to = out->data; - - i = 0; - while (i < len) { - /* If MSB set just copy across */ - if (*from & 0x80) { - *to++ = *from++; - i++; - } - /* Collapse multiple spaces */ - else if (isspace(*from)) { - /* Copy one space across */ - *to++ = ' '; - /* - * Ignore subsequent spaces. Note: don't need to check len here - * because we know the last character is a non-space so we can't - * overflow. - */ - do { - from++; - i++; - } - while (!(*from & 0x80) && isspace(*from)); - } else { - *to++ = tolower(*from); - from++; - i++; - } - } - - out->length = to - out->data; - - return 1; - -} - -static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, - unsigned char **in) -{ - int i, len, ltmp; - ASN1_VALUE *v; - STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; - - len = 0; - for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { - v = sk_ASN1_VALUE_value(intname, i); - ltmp = ASN1_item_ex_i2d(&v, in, - ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); - if (ltmp < 0) - return ltmp; - len += ltmp; - } - return len; -} - -int X509_NAME_set(X509_NAME **xn, X509_NAME *name) -{ - if ((name = X509_NAME_dup(name)) == NULL) - return 0; - X509_NAME_free(*xn); - *xn = name; - return 1; -} - -IMPLEMENT_STACK_OF(X509_NAME_ENTRY) - -IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY) -/* x_nx509.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 2005. - */ -/* ==================================================================== - * Copyright (c) 2005 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "x509.h" -// #include "asn1.h" -// #include "asn1t.h" - -/* Old netscape certificate wrapper format */ - -ASN1_SEQUENCE(NETSCAPE_X509) = { - ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING), - ASN1_OPT(NETSCAPE_X509, cert, X509) -} ASN1_SEQUENCE_END(NETSCAPE_X509) - -IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509) -/* crypto/asn1/x_pkey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "objects.h" -#include "asn1_mac.h" -// #include "x509.h" - -/* need to implement */ -int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp) -{ - return (0); -} - -X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length) -{ - int i; - M_ASN1_D2I_vars(a, X509_PKEY *, X509_PKEY_new); - - M_ASN1_D2I_Init(); - M_ASN1_D2I_start_sequence(); - M_ASN1_D2I_get_x(X509_ALGOR, ret->enc_algor, d2i_X509_ALGOR); - M_ASN1_D2I_get_x(ASN1_OCTET_STRING, ret->enc_pkey, d2i_ASN1_OCTET_STRING); - - ret->cipher.cipher = - EVP_get_cipherbyname(OBJ_nid2ln - (OBJ_obj2nid(ret->enc_algor->algorithm))); - if (ret->cipher.cipher == NULL) { - c.error = ASN1_R_UNSUPPORTED_CIPHER; - c.line = __LINE__; - goto err; - } - if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING) { - i = ret->enc_algor->parameter->value.octet_string->length; - if (i > EVP_MAX_IV_LENGTH) { - c.error = ASN1_R_IV_TOO_LARGE; - c.line = __LINE__; - goto err; - } - memcpy(ret->cipher.iv, - ret->enc_algor->parameter->value.octet_string->data, i); - } else - memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); - M_ASN1_D2I_Finish(a, X509_PKEY_free, ASN1_F_D2I_X509_PKEY); -} - -X509_PKEY *X509_PKEY_new(void) -{ - X509_PKEY *ret = NULL; - ASN1_CTX c; - - ret = OPENSSL_malloc(sizeof(X509_PKEY)); - if (ret == NULL) { - c.line = __LINE__; - goto err; - } - ret->version = 0; - ret->enc_algor = X509_ALGOR_new(); - ret->enc_pkey = M_ASN1_OCTET_STRING_new(); - ret->dec_pkey = NULL; - ret->key_length = 0; - ret->key_data = NULL; - ret->key_free = 0; - ret->cipher.cipher = NULL; - memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); - ret->references = 1; - if (ret->enc_algor == NULL || ret->enc_pkey == NULL) { - c.line = __LINE__; - goto err; - } - return ret; -err: - X509_PKEY_free(ret); - ASN1_MAC_H_err(ASN1_F_X509_PKEY_NEW, ERR_R_MALLOC_FAILURE, c.line); - return NULL; -} - -void X509_PKEY_free(X509_PKEY *x) -{ - int i; - - if (x == NULL) - return; - - i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_PKEY); -#ifdef REF_PRINT - REF_PRINT("X509_PKEY", x); -#endif - if (i > 0) - return; -#ifdef REF_CHECK - if (i < 0) { - fprintf(stderr, "X509_PKEY_free, bad reference count\n"); - abort(); - } -#endif - - if (x->enc_algor != NULL) - X509_ALGOR_free(x->enc_algor); - if (x->enc_pkey != NULL) - M_ASN1_OCTET_STRING_free(x->enc_pkey); - if (x->dec_pkey != NULL) - EVP_PKEY_free(x->dec_pkey); - if ((x->key_data != NULL) && (x->key_free)) - OPENSSL_free(x->key_data); - OPENSSL_free(x); -} -/* crypto/asn1/x_pubkey.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" -// #include "asn1_locl.h" -#ifndef OPENSSL_NO_RSA -# include "rsa.h" -#endif -#ifndef OPENSSL_NO_DSA -# include "dsa.h" -#endif - -/* Minor tweak to operation: free up EVP_PKEY */ -static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - if (operation == ASN1_OP_FREE_POST) { - X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; - EVP_PKEY_free(pubkey->pkey); - } - return 1; -} - -ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { - ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), - ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) - -IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) - -int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) -{ - X509_PUBKEY *pk = NULL; - - if (x == NULL) - return (0); - - if ((pk = X509_PUBKEY_new()) == NULL) - goto error; - - if (pkey->ameth) { - if (pkey->ameth->pub_encode) { - if (!pkey->ameth->pub_encode(pk, pkey)) { - X509err(X509_F_X509_PUBKEY_SET, - X509_R_PUBLIC_KEY_ENCODE_ERROR); - goto error; - } - } else { - X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED); - goto error; - } - } else { - X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM); - goto error; - } - - if (*x != NULL) - X509_PUBKEY_free(*x); - - *x = pk; - - return 1; - error: - if (pk != NULL) - X509_PUBKEY_free(pk); - return 0; -} - -EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) -{ - EVP_PKEY *ret = NULL; - - if (key == NULL) - goto error; - - if (key->pkey != NULL) { - CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); - return key->pkey; - } - - if (key->public_key == NULL) - goto error; - - if ((ret = EVP_PKEY_new()) == NULL) { - X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); - goto error; - } - - if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) { - X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM); - goto error; - } - - if (ret->ameth->pub_decode) { - if (!ret->ameth->pub_decode(ret, key)) { - X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR); - goto error; - } - } else { - X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED); - goto error; - } - - /* Check to see if another thread set key->pkey first */ - CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); - if (key->pkey) { - CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); - EVP_PKEY_free(ret); - ret = key->pkey; - } else { - key->pkey = ret; - CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); - } - CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); - - return ret; - - error: - if (ret != NULL) - EVP_PKEY_free(ret); - return (NULL); -} - -/* - * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or - * decode as X509_PUBKEY - */ - -EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) -{ - X509_PUBKEY *xpk; - EVP_PKEY *pktmp; - const unsigned char *q; - q = *pp; - xpk = d2i_X509_PUBKEY(NULL, &q, length); - if (!xpk) - return NULL; - pktmp = X509_PUBKEY_get(xpk); - X509_PUBKEY_free(xpk); - if (!pktmp) - return NULL; - *pp = q; - if (a) { - EVP_PKEY_free(*a); - *a = pktmp; - } - return pktmp; -} - -int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) -{ - X509_PUBKEY *xpk = NULL; - int ret; - if (!a) - return 0; - if (!X509_PUBKEY_set(&xpk, a)) - return 0; - ret = i2d_X509_PUBKEY(xpk, pp); - X509_PUBKEY_free(xpk); - return ret; -} - -/* - * The following are equivalents but which return RSA and DSA keys - */ -#ifndef OPENSSL_NO_RSA -RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) -{ - EVP_PKEY *pkey; - RSA *key; - const unsigned char *q; - q = *pp; - pkey = d2i_PUBKEY(NULL, &q, length); - if (!pkey) - return NULL; - key = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); - if (!key) - return NULL; - *pp = q; - if (a) { - RSA_free(*a); - *a = key; - } - return key; -} - -int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) -{ - EVP_PKEY *pktmp; - int ret; - if (!a) - return 0; - pktmp = EVP_PKEY_new(); - if (!pktmp) { - ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE); - return 0; - } - EVP_PKEY_set1_RSA(pktmp, a); - ret = i2d_PUBKEY(pktmp, pp); - EVP_PKEY_free(pktmp); - return ret; -} -#endif - -#ifndef OPENSSL_NO_DSA -DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) -{ - EVP_PKEY *pkey; - DSA *key; - const unsigned char *q; - q = *pp; - pkey = d2i_PUBKEY(NULL, &q, length); - if (!pkey) - return NULL; - key = EVP_PKEY_get1_DSA(pkey); - EVP_PKEY_free(pkey); - if (!key) - return NULL; - *pp = q; - if (a) { - DSA_free(*a); - *a = key; - } - return key; -} - -int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) -{ - EVP_PKEY *pktmp; - int ret; - if (!a) - return 0; - pktmp = EVP_PKEY_new(); - if (!pktmp) { - ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE); - return 0; - } - EVP_PKEY_set1_DSA(pktmp, a); - ret = i2d_PUBKEY(pktmp, pp); - EVP_PKEY_free(pktmp); - return ret; -} -#endif - -#ifndef OPENSSL_NO_EC -EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) -{ - EVP_PKEY *pkey; - EC_KEY *key; - const unsigned char *q; - q = *pp; - pkey = d2i_PUBKEY(NULL, &q, length); - if (!pkey) - return (NULL); - key = EVP_PKEY_get1_EC_KEY(pkey); - EVP_PKEY_free(pkey); - if (!key) - return (NULL); - *pp = q; - if (a) { - EC_KEY_free(*a); - *a = key; - } - return (key); -} - -int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp) -{ - EVP_PKEY *pktmp; - int ret; - if (!a) - return (0); - if ((pktmp = EVP_PKEY_new()) == NULL) { - ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE); - return (0); - } - EVP_PKEY_set1_EC_KEY(pktmp, a); - ret = i2d_PUBKEY(pktmp, pp); - EVP_PKEY_free(pktmp); - return (ret); -} -#endif - -int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, - int ptype, void *pval, - unsigned char *penc, int penclen) -{ - if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) - return 0; - if (penc) { - if (pub->public_key->data) - OPENSSL_free(pub->public_key->data); - pub->public_key->data = penc; - pub->public_key->length = penclen; - /* Set number of unused bits to zero */ - pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; - } - return 1; -} - -int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, - const unsigned char **pk, int *ppklen, - X509_ALGOR **pa, X509_PUBKEY *pub) -{ - if (ppkalg) - *ppkalg = pub->algor->algorithm; - if (pk) { - *pk = pub->public_key->data; - *ppklen = pub->public_key->length; - } - if (pa) - *pa = pub->algor; - return 1; -} -/* crypto/asn1/x_req.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" - -/*- - * X509_REQ_INFO is handled in an unusual way to get round - * invalid encodings. Some broken certificate requests don't - * encode the attributes field if it is empty. This is in - * violation of PKCS#10 but we need to tolerate it. We do - * this by making the attributes field OPTIONAL then using - * the callback to initialise it to an empty STACK. - * - * This means that the field will be correctly encoded unless - * we NULL out the field. - * - * As a result we no longer need the req_kludge field because - * the information is now contained in the attributes field: - * 1. If it is NULL then it's the invalid omission. - * 2. If it is empty it is the correct encoding. - * 3. If it is not empty then some attributes are present. - * - */ - -static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; - - if (operation == ASN1_OP_NEW_POST) { - rinf->attributes = sk_X509_ATTRIBUTE_new_null(); - if (!rinf->attributes) - return 0; - } - return 1; -} - -ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { - ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), - ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), - ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), - /* This isn't really OPTIONAL but it gets round invalid - * encodings - */ - ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0) -} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO) - -IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) - -ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = { - ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO), - ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR), - ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ) - -IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) -/* crypto/asn1/x_sig.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" - -ASN1_SEQUENCE(X509_SIG) = { - ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR), - ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING) -} ASN1_SEQUENCE_END(X509_SIG) - -IMPLEMENT_ASN1_FUNCTIONS(X509_SIG) -/* crypto/asn1/x_spki.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - - /* - * This module was send to me my Pat Richards who wrote it. - * It is under my Copyright with his permission - */ - -#include -// #include "cryptlib.h" -// #include "x509.h" -// #include "asn1t.h" - -ASN1_SEQUENCE(NETSCAPE_SPKAC) = { - ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY), - ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING) -} ASN1_SEQUENCE_END(NETSCAPE_SPKAC) - -IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC) - -ASN1_SEQUENCE(NETSCAPE_SPKI) = { - ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC), - ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR), - ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END(NETSCAPE_SPKI) - -IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI) -/* crypto/asn1/x_val.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "asn1t.h" -// #include "x509.h" - -ASN1_SEQUENCE(X509_VAL) = { - ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME), - ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME) -} ASN1_SEQUENCE_END(X509_VAL) - -IMPLEMENT_ASN1_FUNCTIONS(X509_VAL) -/* crypto/asn1/x_x509.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "asn1t.h" -// #include "x509.h" -// #include "x509v3.h" - -ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { - ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), - ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER), - ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR), - ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), - ASN1_SIMPLE(X509_CINF, validity, X509_VAL), - ASN1_SIMPLE(X509_CINF, subject, X509_NAME), - ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), - ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), - ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), - ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3) -} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) - -IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) -/* X509 top level structure needs a bit of customisation */ - -extern void policy_cache_free(X509_POLICY_CACHE *cache); - -static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) -{ - X509 *ret = (X509 *)*pval; - - switch (operation) { - - case ASN1_OP_NEW_POST: - ret->valid = 0; - ret->name = NULL; - ret->ex_flags = 0; - ret->ex_pathlen = -1; - ret->skid = NULL; - ret->akid = NULL; -#ifndef OPENSSL_NO_RFC3779 - ret->rfc3779_addr = NULL; - ret->rfc3779_asid = NULL; -#endif - ret->aux = NULL; - ret->crldp = NULL; - CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); - break; - - case ASN1_OP_D2I_POST: - if (ret->name != NULL) - OPENSSL_free(ret->name); - ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0); - break; - - case ASN1_OP_FREE_POST: - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); - X509_CERT_AUX_free(ret->aux); - ASN1_OCTET_STRING_free(ret->skid); - AUTHORITY_KEYID_free(ret->akid); - CRL_DIST_POINTS_free(ret->crldp); - policy_cache_free(ret->policy_cache); - GENERAL_NAMES_free(ret->altname); - NAME_CONSTRAINTS_free(ret->nc); -#ifndef OPENSSL_NO_RFC3779 - sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); - ASIdentifiers_free(ret->rfc3779_asid); -#endif - - if (ret->name != NULL) - OPENSSL_free(ret->name); - break; - - } - - return 1; - -} - -ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = { - ASN1_SIMPLE(X509, cert_info, X509_CINF), - ASN1_SIMPLE(X509, sig_alg, X509_ALGOR), - ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING) -} ASN1_SEQUENCE_END_ref(X509, X509) - -IMPLEMENT_ASN1_FUNCTIONS(X509) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509) - -int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, - CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) -{ - return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp, - new_func, dup_func, free_func); -} - -int X509_set_ex_data(X509 *r, int idx, void *arg) -{ - return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); -} - -void *X509_get_ex_data(X509 *r, int idx) -{ - return (CRYPTO_get_ex_data(&r->ex_data, idx)); -} - -/* - * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with - * extra info tagged on the end. Since these functions set how a certificate - * is trusted they should only be used when the certificate comes from a - * reliable source such as local storage. - */ - -X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) -{ - const unsigned char *q; - X509 *ret; - int freeret = 0; - - /* Save start position */ - q = *pp; - - if (!a || *a == NULL) { - freeret = 1; - } - ret = d2i_X509(a, &q, length); - /* If certificate unreadable then forget it */ - if (!ret) - return NULL; - /* update length */ - length -= q - *pp; - if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length)) - goto err; - *pp = q; - return ret; - err: - if (freeret) { - X509_free(ret); - if (a) - *a = NULL; - } - return NULL; -} - -/* - * Serialize trusted certificate to *pp or just return the required buffer - * length if pp == NULL. We ultimately want to avoid modifying *pp in the - * error path, but that depends on similar hygiene in lower-level functions. - * Here we avoid compounding the problem. - */ -static int i2d_x509_aux_internal(X509 *a, unsigned char **pp) -{ - int length, tmplen; - unsigned char *start = pp != NULL ? *pp : NULL; - - OPENSSL_assert(pp == NULL || *pp != NULL); - - /* - * This might perturb *pp on error, but fixing that belongs in i2d_X509() - * not here. It should be that if a == NULL length is zero, but we check - * both just in case. - */ - length = i2d_X509(a, pp); - if (length <= 0 || a == NULL) - return length; - - tmplen = i2d_X509_CERT_AUX(a->aux, pp); - if (tmplen < 0) { - if (start != NULL) - *pp = start; - return tmplen; - } - length += tmplen; - - return length; -} - -/* - * Serialize trusted certificate to *pp, or just return the required buffer - * length if pp == NULL. - * - * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since - * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do - * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the - * allocated buffer. - */ -int i2d_X509_AUX(X509 *a, unsigned char **pp) -{ - int length; - unsigned char *tmp; - - /* Buffer provided by caller */ - if (pp == NULL || *pp != NULL) - return i2d_x509_aux_internal(a, pp); - - /* Obtain the combined length */ - if ((length = i2d_x509_aux_internal(a, NULL)) <= 0) - return length; - - /* Allocate requisite combined storage */ - *pp = tmp = OPENSSL_malloc(length); - if (tmp == NULL) - return -1; /* Push error onto error stack? */ - - /* Encode, but keep *pp at the originally malloced pointer */ - length = i2d_x509_aux_internal(a, &tmp); - if (length <= 0) { - OPENSSL_free(*pp); - *pp = NULL; - } - return length; -} - -int i2d_re_X509_tbs(X509 *x, unsigned char **pp) -{ - x->cert_info->enc.modified = 1; - return i2d_X509_CINF(x->cert_info, pp); -} - -void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, - const X509 *x) -{ - if (psig) - *psig = x->signature; - if (palg) - *palg = x->sig_alg; -} - -int X509_get_signature_nid(const X509 *x) -{ - return OBJ_obj2nid(x->sig_alg->algorithm); -} -/* a_x509a.c */ -/* - * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project - * 1999. - */ -/* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * licensing@OpenSSL.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - * - * This product includes cryptographic software written by Eric Young - * (eay@cryptsoft.com). This product includes software written by Tim - * Hudson (tjh@cryptsoft.com). - * - */ - -#include -// #include "cryptlib.h" -// #include "evp.h" -// #include "asn1t.h" -// #include "x509.h" - -/* - * X509_CERT_AUX routines. These are used to encode additional user - * modifiable data about a certificate. This data is appended to the X509 - * encoding when the *_X509_AUX routines are used. This means that the - * "traditional" X509 routines will simply ignore the extra data. - */ - -static X509_CERT_AUX *aux_get(X509 *x); - -ASN1_SEQUENCE(X509_CERT_AUX) = { - ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT), - ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0), - ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING), - ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING), - ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1) -} ASN1_SEQUENCE_END(X509_CERT_AUX) - -IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX) - -static X509_CERT_AUX *aux_get(X509 *x) -{ - if (!x) - return NULL; - if (!x->aux && !(x->aux = X509_CERT_AUX_new())) - return NULL; - return x->aux; -} - -int X509_alias_set1(X509 *x, unsigned char *name, int len) -{ - X509_CERT_AUX *aux; - if (!name) { - if (!x || !x->aux || !x->aux->alias) - return 1; - ASN1_UTF8STRING_free(x->aux->alias); - x->aux->alias = NULL; - return 1; - } - if (!(aux = aux_get(x))) - return 0; - if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) - return 0; - return ASN1_STRING_set(aux->alias, name, len); -} - -int X509_keyid_set1(X509 *x, unsigned char *id, int len) -{ - X509_CERT_AUX *aux; - if (!id) { - if (!x || !x->aux || !x->aux->keyid) - return 1; - ASN1_OCTET_STRING_free(x->aux->keyid); - x->aux->keyid = NULL; - return 1; - } - if (!(aux = aux_get(x))) - return 0; - if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) - return 0; - return ASN1_STRING_set(aux->keyid, id, len); -} - -unsigned char *X509_alias_get0(X509 *x, int *len) -{ - if (!x->aux || !x->aux->alias) - return NULL; - if (len) - *len = x->aux->alias->length; - return x->aux->alias->data; -} - -unsigned char *X509_keyid_get0(X509 *x, int *len) -{ - if (!x->aux || !x->aux->keyid) - return NULL; - if (len) - *len = x->aux->keyid->length; - return x->aux->keyid->data; -} - -int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) -{ - X509_CERT_AUX *aux; - ASN1_OBJECT *objtmp; - if (!(objtmp = OBJ_dup(obj))) - return 0; - if (!(aux = aux_get(x))) - return 0; - if (!aux->trust && !(aux->trust = sk_ASN1_OBJECT_new_null())) - return 0; - return sk_ASN1_OBJECT_push(aux->trust, objtmp); -} - -int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) -{ - X509_CERT_AUX *aux; - ASN1_OBJECT *objtmp; - if (!(objtmp = OBJ_dup(obj))) - return 0; - if (!(aux = aux_get(x))) - goto err; - if (!aux->reject && !(aux->reject = sk_ASN1_OBJECT_new_null())) - goto err; - return sk_ASN1_OBJECT_push(aux->reject, objtmp); - err: - ASN1_OBJECT_free(objtmp); - return 0; -} - -void X509_trust_clear(X509 *x) -{ - if (x->aux && x->aux->trust) { - sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free); - x->aux->trust = NULL; - } -} - -void X509_reject_clear(X509 *x) -{ - if (x->aux && x->aux->reject) { - sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free); - x->aux->reject = NULL; - } -} - -ASN1_SEQUENCE(X509_CERT_PAIR) = { - ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0), - ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1) -} ASN1_SEQUENCE_END(X509_CERT_PAIR) - -IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR) diff --git a/Sources/COpenSSL/xcbc_enc.c b/Sources/COpenSSL/xcbc_enc.c deleted file mode 100644 index 6fe021be..00000000 --- a/Sources/COpenSSL/xcbc_enc.c +++ /dev/null @@ -1,216 +0,0 @@ -/* crypto/des/xcbc_enc.c */ -/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) - * All rights reserved. - * - * This package is an SSL implementation written - * by Eric Young (eay@cryptsoft.com). - * The implementation was written so as to conform with Netscapes SSL. - * - * This library is free for commercial and non-commercial use as long as - * the following conditions are aheared to. The following conditions - * apply to all code found in this distribution, be it the RC4, RSA, - * lhash, DES, etc., code; not just the SSL code. The SSL documentation - * included with this distribution is covered by the same copyright terms - * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * - * Copyright remains Eric Young's, and as such any Copyright notices in - * the code are not to be removed. - * If this package is used in a product, Eric Young should be given attribution - * as the author of the parts of the library used. - * This can be in the form of a textual message at program startup or - * in documentation (online or textual) provided with the package. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * "This product includes cryptographic software written by - * Eric Young (eay@cryptsoft.com)" - * The word 'cryptographic' can be left out if the rouines from the library - * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from - * the apps directory (application code) you must include an acknowledgement: - * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * - * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * The licence and distribution terms for any publically available version or - * derivative of this code cannot be changed. i.e. this code cannot simply be - * copied and put under another distribution licence - * [including the GNU Public Licence.] - */ - -#include "des_locl.h" - -/* RSA's DESX */ - -#if 0 /* broken code, preserved just in case anyone - * specifically looks for this */ -static const unsigned char desx_white_in2out[256] = { - 0xBD, 0x56, 0xEA, 0xF2, 0xA2, 0xF1, 0xAC, 0x2A, 0xB0, 0x93, 0xD1, 0x9C, - 0x1B, 0x33, 0xFD, 0xD0, - 0x30, 0x04, 0xB6, 0xDC, 0x7D, 0xDF, 0x32, 0x4B, 0xF7, 0xCB, 0x45, 0x9B, - 0x31, 0xBB, 0x21, 0x5A, - 0x41, 0x9F, 0xE1, 0xD9, 0x4A, 0x4D, 0x9E, 0xDA, 0xA0, 0x68, 0x2C, 0xC3, - 0x27, 0x5F, 0x80, 0x36, - 0x3E, 0xEE, 0xFB, 0x95, 0x1A, 0xFE, 0xCE, 0xA8, 0x34, 0xA9, 0x13, 0xF0, - 0xA6, 0x3F, 0xD8, 0x0C, - 0x78, 0x24, 0xAF, 0x23, 0x52, 0xC1, 0x67, 0x17, 0xF5, 0x66, 0x90, 0xE7, - 0xE8, 0x07, 0xB8, 0x60, - 0x48, 0xE6, 0x1E, 0x53, 0xF3, 0x92, 0xA4, 0x72, 0x8C, 0x08, 0x15, 0x6E, - 0x86, 0x00, 0x84, 0xFA, - 0xF4, 0x7F, 0x8A, 0x42, 0x19, 0xF6, 0xDB, 0xCD, 0x14, 0x8D, 0x50, 0x12, - 0xBA, 0x3C, 0x06, 0x4E, - 0xEC, 0xB3, 0x35, 0x11, 0xA1, 0x88, 0x8E, 0x2B, 0x94, 0x99, 0xB7, 0x71, - 0x74, 0xD3, 0xE4, 0xBF, - 0x3A, 0xDE, 0x96, 0x0E, 0xBC, 0x0A, 0xED, 0x77, 0xFC, 0x37, 0x6B, 0x03, - 0x79, 0x89, 0x62, 0xC6, - 0xD7, 0xC0, 0xD2, 0x7C, 0x6A, 0x8B, 0x22, 0xA3, 0x5B, 0x05, 0x5D, 0x02, - 0x75, 0xD5, 0x61, 0xE3, - 0x18, 0x8F, 0x55, 0x51, 0xAD, 0x1F, 0x0B, 0x5E, 0x85, 0xE5, 0xC2, 0x57, - 0x63, 0xCA, 0x3D, 0x6C, - 0xB4, 0xC5, 0xCC, 0x70, 0xB2, 0x91, 0x59, 0x0D, 0x47, 0x20, 0xC8, 0x4F, - 0x58, 0xE0, 0x01, 0xE2, - 0x16, 0x38, 0xC4, 0x6F, 0x3B, 0x0F, 0x65, 0x46, 0xBE, 0x7E, 0x2D, 0x7B, - 0x82, 0xF9, 0x40, 0xB5, - 0x1D, 0x73, 0xF8, 0xEB, 0x26, 0xC7, 0x87, 0x97, 0x25, 0x54, 0xB1, 0x28, - 0xAA, 0x98, 0x9D, 0xA5, - 0x64, 0x6D, 0x7A, 0xD4, 0x10, 0x81, 0x44, 0xEF, 0x49, 0xD6, 0xAE, 0x2E, - 0xDD, 0x76, 0x5C, 0x2F, - 0xA7, 0x1C, 0xC9, 0x09, 0x69, 0x9A, 0x83, 0xCF, 0x29, 0x39, 0xB9, 0xE9, - 0x4C, 0xFF, 0x43, 0xAB, -}; - -void DES_xwhite_in2out(const_DES_cblock *des_key, const_DES_cblock *in_white, - DES_cblock *out_white) -{ - int out0, out1; - int i; - const unsigned char *key = &(*des_key)[0]; - const unsigned char *in = &(*in_white)[0]; - unsigned char *out = &(*out_white)[0]; - - out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = 0; - out0 = out1 = 0; - for (i = 0; i < 8; i++) { - out[i] = key[i] ^ desx_white_in2out[out0 ^ out1]; - out0 = out1; - out1 = (int)out[i & 0x07]; - } - - out0 = out[0]; - out1 = out[i]; /* BUG: out-of-bounds read */ - for (i = 0; i < 8; i++) { - out[i] = in[i] ^ desx_white_in2out[out0 ^ out1]; - out0 = out1; - out1 = (int)out[i & 0x07]; - } -} -#endif - -void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out, - long length, DES_key_schedule *schedule, - DES_cblock *ivec, const_DES_cblock *inw, - const_DES_cblock *outw, int enc) -{ - register DES_LONG tin0, tin1; - register DES_LONG tout0, tout1, xor0, xor1; - register DES_LONG inW0, inW1, outW0, outW1; - register const unsigned char *in2; - register long l = length; - DES_LONG tin[2]; - unsigned char *iv; - - in2 = &(*inw)[0]; - c2l(in2, inW0); - c2l(in2, inW1); - in2 = &(*outw)[0]; - c2l(in2, outW0); - c2l(in2, outW1); - - iv = &(*ivec)[0]; - - if (enc) { - c2l(iv, tout0); - c2l(iv, tout1); - for (l -= 8; l >= 0; l -= 8) { - c2l(in, tin0); - c2l(in, tin1); - tin0 ^= tout0 ^ inW0; - tin[0] = tin0; - tin1 ^= tout1 ^ inW1; - tin[1] = tin1; - DES_encrypt1(tin, schedule, DES_ENCRYPT); - tout0 = tin[0] ^ outW0; - l2c(tout0, out); - tout1 = tin[1] ^ outW1; - l2c(tout1, out); - } - if (l != -8) { - c2ln(in, tin0, tin1, l + 8); - tin0 ^= tout0 ^ inW0; - tin[0] = tin0; - tin1 ^= tout1 ^ inW1; - tin[1] = tin1; - DES_encrypt1(tin, schedule, DES_ENCRYPT); - tout0 = tin[0] ^ outW0; - l2c(tout0, out); - tout1 = tin[1] ^ outW1; - l2c(tout1, out); - } - iv = &(*ivec)[0]; - l2c(tout0, iv); - l2c(tout1, iv); - } else { - c2l(iv, xor0); - c2l(iv, xor1); - for (l -= 8; l > 0; l -= 8) { - c2l(in, tin0); - tin[0] = tin0 ^ outW0; - c2l(in, tin1); - tin[1] = tin1 ^ outW1; - DES_encrypt1(tin, schedule, DES_DECRYPT); - tout0 = tin[0] ^ xor0 ^ inW0; - tout1 = tin[1] ^ xor1 ^ inW1; - l2c(tout0, out); - l2c(tout1, out); - xor0 = tin0; - xor1 = tin1; - } - if (l != -8) { - c2l(in, tin0); - tin[0] = tin0 ^ outW0; - c2l(in, tin1); - tin[1] = tin1 ^ outW1; - DES_encrypt1(tin, schedule, DES_DECRYPT); - tout0 = tin[0] ^ xor0 ^ inW0; - tout1 = tin[1] ^ xor1 ^ inW1; - l2cn(tout0, tout1, out, l + 8); - xor0 = tin0; - xor1 = tin1; - } - - iv = &(*ivec)[0]; - l2c(xor0, iv); - l2c(xor1, iv); - } - tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; - inW0 = inW1 = outW0 = outW1 = 0; - tin[0] = tin[1] = 0; -} diff --git a/Sources/COpenSSL/xts128.c b/Sources/COpenSSL/xts128.c deleted file mode 100644 index 59b439c1..00000000 --- a/Sources/COpenSSL/xts128.c +++ /dev/null @@ -1,204 +0,0 @@ -/* ==================================================================== - * Copyright (c) 2011 The OpenSSL Project. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. All advertising materials mentioning features or use of this - * software must display the following acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" - * - * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * openssl-core@openssl.org. - * - * 5. Products derived from this software may not be called "OpenSSL" - * nor may "OpenSSL" appear in their names without prior written - * permission of the OpenSSL Project. - * - * 6. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by the OpenSSL Project - * for use in the OpenSSL Toolkit (http://www.openssl.org/)" - * - * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY - * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * ==================================================================== - */ - -#include "crypto.h" -#include "modes_lcl.h" -#include - -#ifndef MODES_DEBUG -# ifndef NDEBUG -# define NDEBUG -# endif -#endif -#include - -int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, - const unsigned char iv[16], - const unsigned char *inp, unsigned char *out, - size_t len, int enc) -{ - const union { - long one; - char little; - } is_endian = { - 1 - }; - union { - u64 u[2]; - u32 d[4]; - u8 c[16]; - } tweak, scratch; - unsigned int i; - - if (len < 16) - return -1; - - memcpy(tweak.c, iv, 16); - - (*ctx->block2) (tweak.c, tweak.c, ctx->key2); - - if (!enc && (len % 16)) - len -= 16; - - while (len >= 16) { -#if defined(STRICT_ALIGNMENT) - memcpy(scratch.c, inp, 16); - scratch.u[0] ^= tweak.u[0]; - scratch.u[1] ^= tweak.u[1]; -#else - scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0]; - scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1]; -#endif - (*ctx->block1) (scratch.c, scratch.c, ctx->key1); -#if defined(STRICT_ALIGNMENT) - scratch.u[0] ^= tweak.u[0]; - scratch.u[1] ^= tweak.u[1]; - memcpy(out, scratch.c, 16); -#else - ((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0]; - ((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1]; -#endif - inp += 16; - out += 16; - len -= 16; - - if (len == 0) - return 0; - - if (is_endian.little) { - unsigned int carry, res; - - res = 0x87 & (((int)tweak.d[3]) >> 31); - carry = (unsigned int)(tweak.u[0] >> 63); - tweak.u[0] = (tweak.u[0] << 1) ^ res; - tweak.u[1] = (tweak.u[1] << 1) | carry; - } else { - size_t c; - - for (c = 0, i = 0; i < 16; ++i) { - /* - * + substitutes for |, because c is 1 bit - */ - c += ((size_t)tweak.c[i]) << 1; - tweak.c[i] = (u8)c; - c = c >> 8; - } - tweak.c[0] ^= (u8)(0x87 & (0 - c)); - } - } - if (enc) { - for (i = 0; i < len; ++i) { - u8 c = inp[i]; - out[i] = scratch.c[i]; - scratch.c[i] = c; - } - scratch.u[0] ^= tweak.u[0]; - scratch.u[1] ^= tweak.u[1]; - (*ctx->block1) (scratch.c, scratch.c, ctx->key1); - scratch.u[0] ^= tweak.u[0]; - scratch.u[1] ^= tweak.u[1]; - memcpy(out - 16, scratch.c, 16); - } else { - union { - u64 u[2]; - u8 c[16]; - } tweak1; - - if (is_endian.little) { - unsigned int carry, res; - - res = 0x87 & (((int)tweak.d[3]) >> 31); - carry = (unsigned int)(tweak.u[0] >> 63); - tweak1.u[0] = (tweak.u[0] << 1) ^ res; - tweak1.u[1] = (tweak.u[1] << 1) | carry; - } else { - size_t c; - - for (c = 0, i = 0; i < 16; ++i) { - /* - * + substitutes for |, because c is 1 bit - */ - c += ((size_t)tweak.c[i]) << 1; - tweak1.c[i] = (u8)c; - c = c >> 8; - } - tweak1.c[0] ^= (u8)(0x87 & (0 - c)); - } -#if defined(STRICT_ALIGNMENT) - memcpy(scratch.c, inp, 16); - scratch.u[0] ^= tweak1.u[0]; - scratch.u[1] ^= tweak1.u[1]; -#else - scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0]; - scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1]; -#endif - (*ctx->block1) (scratch.c, scratch.c, ctx->key1); - scratch.u[0] ^= tweak1.u[0]; - scratch.u[1] ^= tweak1.u[1]; - - for (i = 0; i < len; ++i) { - u8 c = inp[16 + i]; - out[16 + i] = scratch.c[i]; - scratch.c[i] = c; - } - scratch.u[0] ^= tweak.u[0]; - scratch.u[1] ^= tweak.u[1]; - (*ctx->block1) (scratch.c, scratch.c, ctx->key1); -#if defined(STRICT_ALIGNMENT) - scratch.u[0] ^= tweak.u[0]; - scratch.u[1] ^= tweak.u[1]; - memcpy(out, scratch.c, 16); -#else - ((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0]; - ((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1]; -#endif - } - - return 0; -} diff --git a/Sources/LinuxBridge/LinuxBridge.c b/Sources/LinuxBridge/LinuxBridge.c deleted file mode 100644 index 480ee5c5..00000000 --- a/Sources/LinuxBridge/LinuxBridge.c +++ /dev/null @@ -1,25 +0,0 @@ - -#include "LinuxBridge.h" - -#undef SIG_IGN -__sighandler_t SIG_IGN = (__sighandler_t)1; - -int linux_fcntl_get(int fd, int cmd) -{ - return fcntl(fd, cmd); -} - -int linux_fcntl_set(int fd, int cmd, int value) -{ - return fcntl(fd, cmd, value); -} - -int linux_open(const char *path, int oflag, mode_t mode) -{ - return open(path, oflag, mode); -} - -int linux_errno() -{ - return errno; -} diff --git a/Sources/LinuxBridge/include/LinuxBridge.h b/Sources/LinuxBridge/include/LinuxBridge.h deleted file mode 100644 index 2ccc2d2a..00000000 --- a/Sources/LinuxBridge/include/LinuxBridge.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _LINUXBRIDGE_H_ -#define _LINUXBRIDGE_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef SIG_IGN -__sighandler_t SIG_IGN; - -int linux_fcntl_get(int fd, int cmd); -int linux_fcntl_set(int fd, int cmd, int value); -int linux_open(const char *path, int oflag, mode_t mode); -int linux_errno(); - -#endif diff --git a/Sources/PerfectCZlib/CMakeLists.txt b/Sources/PerfectCZlib/CMakeLists.txt deleted file mode 100644 index 14411a43..00000000 --- a/Sources/PerfectCZlib/CMakeLists.txt +++ /dev/null @@ -1,249 +0,0 @@ -cmake_minimum_required(VERSION 2.4.4) -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON) - -project(zlib C) - -set(VERSION "1.2.9") - -option(ASM686 "Enable building i686 assembly implementation") -option(AMD64 "Enable building amd64 assembly implementation") - -set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables") -set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries") -set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers") -set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages") -set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") - -include(CheckTypeSize) -include(CheckFunctionExists) -include(CheckIncludeFile) -include(CheckCSourceCompiles) -enable_testing() - -check_include_file(sys/types.h HAVE_SYS_TYPES_H) -check_include_file(stdint.h HAVE_STDINT_H) -check_include_file(stddef.h HAVE_STDDEF_H) - -# -# Check to see if we have large file support -# -set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1) -# We add these other definitions here because CheckTypeSize.cmake -# in CMake 2.4.x does not automatically do so and we want -# compatibility with CMake 2.4.x. -if(HAVE_SYS_TYPES_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H) -endif() -if(HAVE_STDINT_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H) -endif() -if(HAVE_STDDEF_H) - list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H) -endif() -check_type_size(off64_t OFF64_T) -if(HAVE_OFF64_T) - add_definitions(-D_LARGEFILE64_SOURCE=1) -endif() -set(CMAKE_REQUIRED_DEFINITIONS) # clear variable - -# -# Check for fseeko -# -check_function_exists(fseeko HAVE_FSEEKO) -if(NOT HAVE_FSEEKO) - add_definitions(-DNO_FSEEKO) -endif() - -# -# Check for unistd.h -# -check_include_file(unistd.h Z_HAVE_UNISTD_H) - -if(MSVC) - set(CMAKE_DEBUG_POSTFIX "d") - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) - add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) - include_directories(${CMAKE_CURRENT_SOURCE_DIR}) -endif() - -if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) - # If we're doing an out of source build and the user has a zconf.h - # in their source tree... - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h) - message(STATUS "Renaming") - message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h") - message(STATUS "to 'zconf.h.included' because this file is included with zlib") - message(STATUS "but CMake generates it automatically in the build directory.") - file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included) - endif() -endif() - -set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein - ${ZLIB_PC} @ONLY) -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY) -include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) - - -#============================================================================ -# zlib -#============================================================================ - -set(ZLIB_PUBLIC_HDRS - ${CMAKE_CURRENT_BINARY_DIR}/zconf.h - zlib.h -) -set(ZLIB_PRIVATE_HDRS - crc32.h - deflate.h - gzguts.h - inffast.h - inffixed.h - inflate.h - inftrees.h - trees.h - zutil.h -) -set(ZLIB_SRCS - adler32.c - compress.c - crc32.c - deflate.c - gzclose.c - gzlib.c - gzread.c - gzwrite.c - inflate.c - infback.c - inftrees.c - inffast.c - trees.c - uncompr.c - zutil.c -) - -if(NOT MINGW) - set(ZLIB_DLL_SRCS - win32/zlib1.rc # If present will override custom build rule below. - ) -endif() - -if(CMAKE_COMPILER_IS_GNUCC) - if(ASM686) - set(ZLIB_ASMS contrib/asm686/match.S) - elseif (AMD64) - set(ZLIB_ASMS contrib/amd64/amd64-match.S) - endif () - - if(ZLIB_ASMS) - add_definitions(-DASMV) - set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE) - endif() -endif() - -if(MSVC) - if(ASM686) - ENABLE_LANGUAGE(ASM_MASM) - set(ZLIB_ASMS - contrib/masmx86/inffas32.asm - contrib/masmx86/match686.asm - ) - elseif (AMD64) - ENABLE_LANGUAGE(ASM_MASM) - set(ZLIB_ASMS - contrib/masmx64/gvmat64.asm - contrib/masmx64/inffasx64.asm - ) - endif() - - if(ZLIB_ASMS) - add_definitions(-DASMV -DASMINF) - endif() -endif() - -# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION -file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents) -string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" - "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents}) - -if(MINGW) - # This gets us DLL resource information when compiling on MinGW. - if(NOT CMAKE_RC_COMPILER) - set(CMAKE_RC_COMPILER windres.exe) - endif() - - add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - COMMAND ${CMAKE_RC_COMPILER} - -D GCC_WINDRES - -I ${CMAKE_CURRENT_SOURCE_DIR} - -I ${CMAKE_CURRENT_BINARY_DIR} - -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj - -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc) - set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj) -endif(MINGW) - -add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) -set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) -set_target_properties(zlib PROPERTIES SOVERSION 1) - -if(NOT CYGWIN) - # This property causes shared libraries on Linux to have the full version - # encoded into their final filename. We disable this on Cygwin because - # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll - # seems to be the default. - # - # This has no effect with MSVC, on that platform the version info for - # the DLL comes from the resource file win32/zlib1.rc - set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) -endif() - -if(UNIX) - # On unix-like platforms the library is almost always called libz - set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z) - if(NOT APPLE) - set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"") - endif() -elseif(BUILD_SHARED_LIBS AND WIN32) - # Creates zlib1.dll when building shared library version - set_target_properties(zlib PROPERTIES SUFFIX "1.dll") -endif() - -if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL ) - install(TARGETS zlib zlibstatic - RUNTIME DESTINATION "${INSTALL_BIN_DIR}" - ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" - LIBRARY DESTINATION "${INSTALL_LIB_DIR}" ) -endif() -if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}") -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3") -endif() -if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL ) - install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") -endif() - -#============================================================================ -# Example binaries -#============================================================================ - -add_executable(example test/example.c) -target_link_libraries(example zlib) -add_test(example example) - -add_executable(minigzip test/minigzip.c) -target_link_libraries(minigzip zlib) - -if(HAVE_OFF64_T) - add_executable(example64 test/example.c) - target_link_libraries(example64 zlib) - set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") - add_test(example64 example64) - - add_executable(minigzip64 test/minigzip.c) - target_link_libraries(minigzip64 zlib) - set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64") -endif() diff --git a/Sources/PerfectCZlib/ChangeLog b/Sources/PerfectCZlib/ChangeLog deleted file mode 100644 index 63d04953..00000000 --- a/Sources/PerfectCZlib/ChangeLog +++ /dev/null @@ -1,1504 +0,0 @@ - - ChangeLog file for zlib - -Changes in 1.2.9 (31 Dec 2016) -- Fix contrib/minizip to permit unzipping with desktop API [Zouzou] -- Improve contrib/blast to return unused bytes -- Assure that gzoffset() is correct when appending -- Improve compress() and uncompress() to support large lengths -- Fix bug in test/example.c where error code not saved -- Remedy Coverity warning [Randers-Pehrson] -- Improve speed of gzprintf() in transparent mode -- Fix inflateInit2() bug when windowBits is 16 or 32 -- Change DEBUG macro to ZLIB_DEBUG -- Avoid uninitialized access by gzclose_w() -- Allow building zlib outside of the source directory -- Fix bug that accepted invalid zlib header when windowBits is zero -- Fix gzseek() problem on MinGW due to buggy _lseeki64 there -- Loop on write() calls in gzwrite.c in case of non-blocking I/O -- Add --warn (-w) option to ./configure for more compiler warnings -- Reject a window size of 256 bytes if not using the zlib wrapper -- Fix bug when level 0 used with Z_HUFFMAN or Z_RLE -- Add --debug (-d) option to ./configure to define ZLIB_DEBUG -- Fix bugs in creating a very large gzip header -- Add uncompress2() function, which returns the input size used -- Assure that deflateParams() will not switch functions mid-block -- Dramatically speed up deflation for level 0 (storing) -- Add gzfread(), duplicating the interface of fread() -- Add gzfwrite(), duplicating the interface of fwrite() -- Add deflateGetDictionary() function -- Use snprintf() for later versions of Microsoft C -- Fix *Init macros to use z_ prefix when requested -- Replace as400 with os400 for OS/400 support [Monnerat] -- Add crc32_z() and adler32_z() functions with size_t lengths -- Update Visual Studio project files [AraHaan] - -Changes in 1.2.8 (28 Apr 2013) -- Update contrib/minizip/iowin32.c for Windows RT [Vollant] -- Do not force Z_CONST for C++ -- Clean up contrib/vstudio [Roß] -- Correct spelling error in zlib.h -- Fix mixed line endings in contrib/vstudio - -Changes in 1.2.7.3 (13 Apr 2013) -- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc - -Changes in 1.2.7.2 (13 Apr 2013) -- Change check for a four-byte type back to hexadecimal -- Fix typo in win32/Makefile.msc -- Add casts in gzwrite.c for pointer differences - -Changes in 1.2.7.1 (24 Mar 2013) -- Replace use of unsafe string functions with snprintf if available -- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink] -- Fix gzgetc undefine when Z_PREFIX set [Turk] -- Eliminate use of mktemp in Makefile (not always available) -- Fix bug in 'F' mode for gzopen() -- Add inflateGetDictionary() function -- Correct comment in deflate.h -- Use _snprintf for snprintf in Microsoft C -- On Darwin, only use /usr/bin/libtool if libtool is not Apple -- Delete "--version" file if created by "ar --version" [Richard G.] -- Fix configure check for veracity of compiler error return codes -- Fix CMake compilation of static lib for MSVC2010 x64 -- Remove unused variable in infback9.c -- Fix argument checks in gzlog_compress() and gzlog_write() -- Clean up the usage of z_const and respect const usage within zlib -- Clean up examples/gzlog.[ch] comparisons of different types -- Avoid shift equal to bits in type (caused endless loop) -- Fix uninitialized value bug in gzputc() introduced by const patches -- Fix memory allocation error in examples/zran.c [Nor] -- Fix bug where gzopen(), gzclose() would write an empty file -- Fix bug in gzclose() when gzwrite() runs out of memory -- Check for input buffer malloc failure in examples/gzappend.c -- Add note to contrib/blast to use binary mode in stdio -- Fix comparisons of differently signed integers in contrib/blast -- Check for invalid code length codes in contrib/puff -- Fix serious but very rare decompression bug in inftrees.c -- Update inflateBack() comments, since inflate() can be faster -- Use underscored I/O function names for WINAPI_FAMILY -- Add _tr_flush_bits to the external symbols prefixed by --zprefix -- Add contrib/vstudio/vc10 pre-build step for static only -- Quote --version-script argument in CMakeLists.txt -- Don't specify --version-script on Apple platforms in CMakeLists.txt -- Fix casting error in contrib/testzlib/testzlib.c -- Fix types in contrib/minizip to match result of get_crc_table() -- Simplify contrib/vstudio/vc10 with 'd' suffix -- Add TOP support to win32/Makefile.msc -- Suport i686 and amd64 assembler builds in CMakeLists.txt -- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h -- Add vc11 and vc12 build files to contrib/vstudio -- Add gzvprintf() as an undocumented function in zlib -- Fix configure for Sun shell -- Remove runtime check in configure for four-byte integer type -- Add casts and consts to ease user conversion to C++ -- Add man pages for minizip and miniunzip -- In Makefile uninstall, don't rm if preceding cd fails -- Do not return Z_BUF_ERROR if deflateParam() has nothing to write - -Changes in 1.2.7 (2 May 2012) -- Replace use of memmove() with a simple copy for portability -- Test for existence of strerror -- Restore gzgetc_ for backward compatibility with 1.2.6 -- Fix build with non-GNU make on Solaris -- Require gcc 4.0 or later on Mac OS X to use the hidden attribute -- Include unistd.h for Watcom C -- Use __WATCOMC__ instead of __WATCOM__ -- Do not use the visibility attribute if NO_VIZ defined -- Improve the detection of no hidden visibility attribute -- Avoid using __int64 for gcc or solo compilation -- Cast to char * in gzprintf to avoid warnings [Zinser] -- Fix make_vms.com for VAX [Zinser] -- Don't use library or built-in byte swaps -- Simplify test and use of gcc hidden attribute -- Fix bug in gzclose_w() when gzwrite() fails to allocate memory -- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen() -- Fix bug in test/minigzip.c for configure --solo -- Fix contrib/vstudio project link errors [Mohanathas] -- Add ability to choose the builder in make_vms.com [Schweda] -- Add DESTDIR support to mingw32 win32/Makefile.gcc -- Fix comments in win32/Makefile.gcc for proper usage -- Allow overriding the default install locations for cmake -- Generate and install the pkg-config file with cmake -- Build both a static and a shared version of zlib with cmake -- Include version symbols for cmake builds -- If using cmake with MSVC, add the source directory to the includes -- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta] -- Move obsolete emx makefile to old [Truta] -- Allow the use of -Wundef when compiling or using zlib -- Avoid the use of the -u option with mktemp -- Improve inflate() documentation on the use of Z_FINISH -- Recognize clang as gcc -- Add gzopen_w() in Windows for wide character path names -- Rename zconf.h in CMakeLists.txt to move it out of the way -- Add source directory in CMakeLists.txt for building examples -- Look in build directory for zlib.pc in CMakeLists.txt -- Remove gzflags from zlibvc.def in vc9 and vc10 -- Fix contrib/minizip compilation in the MinGW environment -- Update ./configure for Solaris, support --64 [Mooney] -- Remove -R. from Solaris shared build (possible security issue) -- Avoid race condition for parallel make (-j) running example -- Fix type mismatch between get_crc_table() and crc_table -- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler] -- Fix the path to zlib.map in CMakeLists.txt -- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe] -- Add instructions to win32/Makefile.gcc for shared install [Torri] - -Changes in 1.2.6.1 (12 Feb 2012) -- Avoid the use of the Objective-C reserved name "id" -- Include io.h in gzguts.h for Microsoft compilers -- Fix problem with ./configure --prefix and gzgetc macro -- Include gz_header definition when compiling zlib solo -- Put gzflags() functionality back in zutil.c -- Avoid library header include in crc32.c for Z_SOLO -- Use name in GCC_CLASSIC as C compiler for coverage testing, if set -- Minor cleanup in contrib/minizip/zip.c [Vollant] -- Update make_vms.com [Zinser] -- Remove unnecessary gzgetc_ function -- Use optimized byte swap operations for Microsoft and GNU [Snyder] -- Fix minor typo in zlib.h comments [Rzesniowiecki] - -Changes in 1.2.6 (29 Jan 2012) -- Update the Pascal interface in contrib/pascal -- Fix function numbers for gzgetc_ in zlibvc.def files -- Fix configure.ac for contrib/minizip [Schiffer] -- Fix large-entry detection in minizip on 64-bit systems [Schiffer] -- Have ./configure use the compiler return code for error indication -- Fix CMakeLists.txt for cross compilation [McClure] -- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes] -- Fix compilation of contrib/minizip on FreeBSD [Marquez] -- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath] -- Include io.h for Turbo C / Borland C on all platforms [Truta] -- Make version explicit in contrib/minizip/configure.ac [Bosmans] -- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant] -- Minor cleanup up contrib/minizip/unzip.c [Vollant] -- Fix bug when compiling minizip with C++ [Vollant] -- Protect for long name and extra fields in contrib/minizip [Vollant] -- Avoid some warnings in contrib/minizip [Vollant] -- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip -- Add missing libs to minizip linker command -- Add support for VPATH builds in contrib/minizip -- Add an --enable-demos option to contrib/minizip/configure -- Add the generation of configure.log by ./configure -- Exit when required parameters not provided to win32/Makefile.gcc -- Have gzputc return the character written instead of the argument -- Use the -m option on ldconfig for BSD systems [Tobias] -- Correct in zlib.map when deflateResetKeep was added - -Changes in 1.2.5.3 (15 Jan 2012) -- Restore gzgetc function for binary compatibility -- Do not use _lseeki64 under Borland C++ [Truta] -- Update win32/Makefile.msc to build test/*.c [Truta] -- Remove old/visualc6 given CMakefile and other alternatives -- Update AS400 build files and documentation [Monnerat] -- Update win32/Makefile.gcc to build test/*.c [Truta] -- Permit stronger flushes after Z_BLOCK flushes -- Avoid extraneous empty blocks when doing empty flushes -- Permit Z_NULL arguments to deflatePending -- Allow deflatePrime() to insert bits in the middle of a stream -- Remove second empty static block for Z_PARTIAL_FLUSH -- Write out all of the available bits when using Z_BLOCK -- Insert the first two strings in the hash table after a flush - -Changes in 1.2.5.2 (17 Dec 2011) -- fix ld error: unable to find version dependency 'ZLIB_1.2.5' -- use relative symlinks for shared libs -- Avoid searching past window for Z_RLE strategy -- Assure that high-water mark initialization is always applied in deflate -- Add assertions to fill_window() in deflate.c to match comments -- Update python link in README -- Correct spelling error in gzread.c -- Fix bug in gzgets() for a concatenated empty gzip stream -- Correct error in comment for gz_make() -- Change gzread() and related to ignore junk after gzip streams -- Allow gzread() and related to continue after gzclearerr() -- Allow gzrewind() and gzseek() after a premature end-of-file -- Simplify gzseek() now that raw after gzip is ignored -- Change gzgetc() to a macro for speed (~40% speedup in testing) -- Fix gzclose() to return the actual error last encountered -- Always add large file support for windows -- Include zconf.h for windows large file support -- Include zconf.h.cmakein for windows large file support -- Update zconf.h.cmakein on make distclean -- Merge vestigial vsnprintf determination from zutil.h to gzguts.h -- Clarify how gzopen() appends in zlib.h comments -- Correct documentation of gzdirect() since junk at end now ignored -- Add a transparent write mode to gzopen() when 'T' is in the mode -- Update python link in zlib man page -- Get inffixed.h and MAKEFIXED result to match -- Add a ./config --solo option to make zlib subset with no library use -- Add undocumented inflateResetKeep() function for CAB file decoding -- Add --cover option to ./configure for gcc coverage testing -- Add #define ZLIB_CONST option to use const in the z_stream interface -- Add comment to gzdopen() in zlib.h to use dup() when using fileno() -- Note behavior of uncompress() to provide as much data as it can -- Add files in contrib/minizip to aid in building libminizip -- Split off AR options in Makefile.in and configure -- Change ON macro to Z_ARG to avoid application conflicts -- Facilitate compilation with Borland C++ for pragmas and vsnprintf -- Include io.h for Turbo C / Borland C++ -- Move example.c and minigzip.c to test/ -- Simplify incomplete code table filling in inflate_table() -- Remove code from inflate.c and infback.c that is impossible to execute -- Test the inflate code with full coverage -- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw) -- Add deflateResetKeep and fix inflateResetKeep to retain dictionary -- Fix gzwrite.c to accommodate reduced memory zlib compilation -- Have inflate() with Z_FINISH avoid the allocation of a window -- Do not set strm->adler when doing raw inflate -- Fix gzeof() to behave just like feof() when read is not past end of file -- Fix bug in gzread.c when end-of-file is reached -- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF -- Document gzread() capability to read concurrently written files -- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo] - -Changes in 1.2.5.1 (10 Sep 2011) -- Update FAQ entry on shared builds (#13) -- Avoid symbolic argument to chmod in Makefile.in -- Fix bug and add consts in contrib/puff [Oberhumer] -- Update contrib/puff/zeros.raw test file to have all block types -- Add full coverage test for puff in contrib/puff/Makefile -- Fix static-only-build install in Makefile.in -- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno] -- Add libz.a dependency to shared in Makefile.in for parallel builds -- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out -- Replace $(...) with `...` in configure for non-bash sh [Bowler] -- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen] -- Add solaris* to Linux* in configure to allow gcc use [Groffen] -- Add *bsd* to Linux* case in configure [Bar-Lev] -- Add inffast.obj to dependencies in win32/Makefile.msc -- Correct spelling error in deflate.h [Kohler] -- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc -- Add test to configure for GNU C looking for gcc in output of $cc -v -- Add zlib.pc generation to win32/Makefile.gcc [Weigelt] -- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not -- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense -- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser) -- Make stronger test in zconf.h to include unistd.h for LFS -- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack] -- Fix zlib.h LFS support when Z_PREFIX used -- Add updated as400 support (removed from old) [Monnerat] -- Avoid deflate sensitivity to volatile input data -- Avoid division in adler32_combine for NO_DIVIDE -- Clarify the use of Z_FINISH with deflateBound() amount of space -- Set binary for output file in puff.c -- Use u4 type for crc_table to avoid conversion warnings -- Apply casts in zlib.h to avoid conversion warnings -- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller] -- Improve inflateSync() documentation to note indeterminancy -- Add deflatePending() function to return the amount of pending output -- Correct the spelling of "specification" in FAQ [Randers-Pehrson] -- Add a check in configure for stdarg.h, use for gzprintf() -- Check that pointers fit in ints when gzprint() compiled old style -- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler] -- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt] -- Add debug records in assmebler code [Londer] -- Update RFC references to use http://tools.ietf.org/html/... [Li] -- Add --archs option, use of libtool to configure for Mac OS X [Borstel] - -Changes in 1.2.5 (19 Apr 2010) -- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev] -- Default to libdir as sharedlibdir in configure [Nieder] -- Update copyright dates on modified source files -- Update trees.c to be able to generate modified trees.h -- Exit configure for MinGW, suggesting win32/Makefile.gcc -- Check for NULL path in gz_open [Homurlu] - -Changes in 1.2.4.5 (18 Apr 2010) -- Set sharedlibdir in configure [Torok] -- Set LDFLAGS in Makefile.in [Bar-Lev] -- Avoid mkdir objs race condition in Makefile.in [Bowler] -- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays -- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C -- Don't use hidden attribute when it is a warning generator (e.g. Solaris) - -Changes in 1.2.4.4 (18 Apr 2010) -- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok] -- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty -- Try to use bash or ksh regardless of functionality of /bin/sh -- Fix configure incompatibility with NetBSD sh -- Remove attempt to run under bash or ksh since have better NetBSD fix -- Fix win32/Makefile.gcc for MinGW [Bar-Lev] -- Add diagnostic messages when using CROSS_PREFIX in configure -- Added --sharedlibdir option to configure [Weigelt] -- Use hidden visibility attribute when available [Frysinger] - -Changes in 1.2.4.3 (10 Apr 2010) -- Only use CROSS_PREFIX in configure for ar and ranlib if they exist -- Use CROSS_PREFIX for nm [Bar-Lev] -- Assume _LARGEFILE64_SOURCE defined is equivalent to true -- Avoid use of undefined symbols in #if with && and || -- Make *64 prototypes in gzguts.h consistent with functions -- Add -shared load option for MinGW in configure [Bowler] -- Move z_off64_t to public interface, use instead of off64_t -- Remove ! from shell test in configure (not portable to Solaris) -- Change +0 macro tests to -0 for possibly increased portability - -Changes in 1.2.4.2 (9 Apr 2010) -- Add consistent carriage returns to readme.txt's in masmx86 and masmx64 -- Really provide prototypes for *64 functions when building without LFS -- Only define unlink() in minigzip.c if unistd.h not included -- Update README to point to contrib/vstudio project files -- Move projects/vc6 to old/ and remove projects/ -- Include stdlib.h in minigzip.c for setmode() definition under WinCE -- Clean up assembler builds in win32/Makefile.msc [Rowe] -- Include sys/types.h for Microsoft for off_t definition -- Fix memory leak on error in gz_open() -- Symbolize nm as $NM in configure [Weigelt] -- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt] -- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined -- Fix bug in gzeof() to take into account unused input data -- Avoid initialization of structures with variables in puff.c -- Updated win32/README-WIN32.txt [Rowe] - -Changes in 1.2.4.1 (28 Mar 2010) -- Remove the use of [a-z] constructs for sed in configure [gentoo 310225] -- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech] -- Restore "for debugging" comment on sprintf() in gzlib.c -- Remove fdopen for MVS from gzguts.h -- Put new README-WIN32.txt in win32 [Rowe] -- Add check for shell to configure and invoke another shell if needed -- Fix big fat stinking bug in gzseek() on uncompressed files -- Remove vestigial F_OPEN64 define in zutil.h -- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE -- Avoid errors on non-LFS systems when applications define LFS macros -- Set EXE to ".exe" in configure for MINGW [Kahle] -- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill] -- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev] -- Add DLL install in win32/makefile.gcc [Bar-Lev] -- Allow Linux* or linux* from uname in configure [Bar-Lev] -- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev] -- Add cross-compilation prefixes to configure [Bar-Lev] -- Match type exactly in gz_load() invocation in gzread.c -- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func -- Provide prototypes for *64 functions when building zlib without LFS -- Don't use -lc when linking shared library on MinGW -- Remove errno.h check in configure and vestigial errno code in zutil.h - -Changes in 1.2.4 (14 Mar 2010) -- Fix VER3 extraction in configure for no fourth subversion -- Update zlib.3, add docs to Makefile.in to make .pdf out of it -- Add zlib.3.pdf to distribution -- Don't set error code in gzerror() if passed pointer is NULL -- Apply destination directory fixes to CMakeLists.txt [Lowman] -- Move #cmakedefine's to a new zconf.in.cmakein -- Restore zconf.h for builds that don't use configure or cmake -- Add distclean to dummy Makefile for convenience -- Update and improve INDEX, README, and FAQ -- Update CMakeLists.txt for the return of zconf.h [Lowman] -- Update contrib/vstudio/vc9 and vc10 [Vollant] -- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc -- Apply license and readme changes to contrib/asm686 [Raiter] -- Check file name lengths and add -c option in minigzip.c [Li] -- Update contrib/amd64 and contrib/masmx86/ [Vollant] -- Avoid use of "eof" parameter in trees.c to not shadow library variable -- Update make_vms.com for removal of zlibdefs.h [Zinser] -- Update assembler code and vstudio projects in contrib [Vollant] -- Remove outdated assembler code contrib/masm686 and contrib/asm586 -- Remove old vc7 and vc8 from contrib/vstudio -- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe] -- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open() -- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant] -- Remove *64 functions from win32/zlib.def (they're not 64-bit yet) -- Fix bug in void-returning vsprintf() case in gzwrite.c -- Fix name change from inflate.h in contrib/inflate86/inffas86.c -- Check if temporary file exists before removing in make_vms.com [Zinser] -- Fix make install and uninstall for --static option -- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta] -- Update readme.txt in contrib/masmx64 and masmx86 to assemble - -Changes in 1.2.3.9 (21 Feb 2010) -- Expunge gzio.c -- Move as400 build information to old -- Fix updates in contrib/minizip and contrib/vstudio -- Add const to vsnprintf test in configure to avoid warnings [Weigelt] -- Delete zconf.h (made by configure) [Weigelt] -- Change zconf.in.h to zconf.h.in per convention [Weigelt] -- Check for NULL buf in gzgets() -- Return empty string for gzgets() with len == 1 (like fgets()) -- Fix description of gzgets() in zlib.h for end-of-file, NULL return -- Update minizip to 1.1 [Vollant] -- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c -- Note in zlib.h that gzerror() should be used to distinguish from EOF -- Remove use of snprintf() from gzlib.c -- Fix bug in gzseek() -- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant] -- Fix zconf.h generation in CMakeLists.txt [Lowman] -- Improve comments in zconf.h where modified by configure - -Changes in 1.2.3.8 (13 Feb 2010) -- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer] -- Use z_off64_t in gz_zero() and gz_skip() to match state->skip -- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t) -- Revert to Makefile.in from 1.2.3.6 (live with the clutter) -- Fix missing error return in gzflush(), add zlib.h note -- Add *64 functions to zlib.map [Levin] -- Fix signed/unsigned comparison in gz_comp() -- Use SFLAGS when testing shared linking in configure -- Add --64 option to ./configure to use -m64 with gcc -- Fix ./configure --help to correctly name options -- Have make fail if a test fails [Levin] -- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson] -- Remove assembler object files from contrib - -Changes in 1.2.3.7 (24 Jan 2010) -- Always gzopen() with O_LARGEFILE if available -- Fix gzdirect() to work immediately after gzopen() or gzdopen() -- Make gzdirect() more precise when the state changes while reading -- Improve zlib.h documentation in many places -- Catch memory allocation failure in gz_open() -- Complete close operation if seek forward in gzclose_w() fails -- Return Z_ERRNO from gzclose_r() if close() fails -- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL -- Return zero for gzwrite() errors to match zlib.h description -- Return -1 on gzputs() error to match zlib.h description -- Add zconf.in.h to allow recovery from configure modification [Weigelt] -- Fix static library permissions in Makefile.in [Weigelt] -- Avoid warnings in configure tests that hide functionality [Weigelt] -- Add *BSD and DragonFly to Linux case in configure [gentoo 123571] -- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212] -- Avoid access of uninitialized data for first inflateReset2 call [Gomes] -- Keep object files in subdirectories to reduce the clutter somewhat -- Remove default Makefile and zlibdefs.h, add dummy Makefile -- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_ -- Remove zlibdefs.h completely -- modify zconf.h instead - -Changes in 1.2.3.6 (17 Jan 2010) -- Avoid void * arithmetic in gzread.c and gzwrite.c -- Make compilers happier with const char * for gz_error message -- Avoid unused parameter warning in inflate.c -- Avoid signed-unsigned comparison warning in inflate.c -- Indent #pragma's for traditional C -- Fix usage of strwinerror() in glib.c, change to gz_strwinerror() -- Correct email address in configure for system options -- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser] -- Update zlib.map [Brown] -- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok] -- Apply various fixes to CMakeLists.txt [Lowman] -- Add checks on len in gzread() and gzwrite() -- Add error message for no more room for gzungetc() -- Remove zlib version check in gzwrite() -- Defer compression of gzprintf() result until need to -- Use snprintf() in gzdopen() if available -- Remove USE_MMAP configuration determination (only used by minigzip) -- Remove examples/pigz.c (available separately) -- Update examples/gun.c to 1.6 - -Changes in 1.2.3.5 (8 Jan 2010) -- Add space after #if in zutil.h for some compilers -- Fix relatively harmless bug in deflate_fast() [Exarevsky] -- Fix same problem in deflate_slow() -- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown] -- Add deflate_rle() for faster Z_RLE strategy run-length encoding -- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding -- Change name of "write" variable in inffast.c to avoid library collisions -- Fix premature EOF from gzread() in gzio.c [Brown] -- Use zlib header window size if windowBits is 0 in inflateInit2() -- Remove compressBound() call in deflate.c to avoid linking compress.o -- Replace use of errno in gz* with functions, support WinCE [Alves] -- Provide alternative to perror() in minigzip.c for WinCE [Alves] -- Don't use _vsnprintf on later versions of MSVC [Lowman] -- Add CMake build script and input file [Lowman] -- Update contrib/minizip to 1.1 [Svensson, Vollant] -- Moved nintendods directory from contrib to . -- Replace gzio.c with a new set of routines with the same functionality -- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above -- Update contrib/minizip to 1.1b -- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h - -Changes in 1.2.3.4 (21 Dec 2009) -- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility -- Update comments in configure and Makefile.in for default --shared -- Fix test -z's in configure [Marquess] -- Build examplesh and minigzipsh when not testing -- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h -- Import LDFLAGS from the environment in configure -- Fix configure to populate SFLAGS with discovered CFLAGS options -- Adapt make_vms.com to the new Makefile.in [Zinser] -- Add zlib2ansi script for C++ compilation [Marquess] -- Add _FILE_OFFSET_BITS=64 test to make test (when applicable) -- Add AMD64 assembler code for longest match to contrib [Teterin] -- Include options from $SFLAGS when doing $LDSHARED -- Simplify 64-bit file support by introducing z_off64_t type -- Make shared object files in objs directory to work around old Sun cc -- Use only three-part version number for Darwin shared compiles -- Add rc option to ar in Makefile.in for when ./configure not run -- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4* -- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile -- Protect against _FILE_OFFSET_BITS being defined when compiling zlib -- Rename Makefile.in targets allstatic to static and allshared to shared -- Fix static and shared Makefile.in targets to be independent -- Correct error return bug in gz_open() by setting state [Brown] -- Put spaces before ;;'s in configure for better sh compatibility -- Add pigz.c (parallel implementation of gzip) to examples/ -- Correct constant in crc32.c to UL [Leventhal] -- Reject negative lengths in crc32_combine() -- Add inflateReset2() function to work like inflateEnd()/inflateInit2() -- Include sys/types.h for _LARGEFILE64_SOURCE [Brown] -- Correct typo in doc/algorithm.txt [Janik] -- Fix bug in adler32_combine() [Zhu] -- Catch missing-end-of-block-code error in all inflates and in puff - Assures that random input to inflate eventually results in an error -- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/ -- Update ENOUGH and its usage to reflect discovered bounds -- Fix gzerror() error report on empty input file [Brown] -- Add ush casts in trees.c to avoid pedantic runtime errors -- Fix typo in zlib.h uncompress() description [Reiss] -- Correct inflate() comments with regard to automatic header detection -- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays) -- Put new version of gzlog (2.0) in examples with interruption recovery -- Add puff compile option to permit invalid distance-too-far streams -- Add puff TEST command options, ability to read piped input -- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but - _LARGEFILE64_SOURCE not defined -- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart -- Fix deflateSetDictionary() to use all 32K for output consistency -- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h) -- Clear bytes after deflate lookahead to avoid use of uninitialized data -- Change a limit in inftrees.c to be more transparent to Coverity Prevent -- Update win32/zlib.def with exported symbols from zlib.h -- Correct spelling errors in zlib.h [Willem, Sobrado] -- Allow Z_BLOCK for deflate() to force a new block -- Allow negative bits in inflatePrime() to delete existing bit buffer -- Add Z_TREES flush option to inflate() to return at end of trees -- Add inflateMark() to return current state information for random access -- Add Makefile for NintendoDS to contrib [Costa] -- Add -w in configure compile tests to avoid spurious warnings [Beucler] -- Fix typos in zlib.h comments for deflateSetDictionary() -- Fix EOF detection in transparent gzread() [Maier] - -Changes in 1.2.3.3 (2 October 2006) -- Make --shared the default for configure, add a --static option -- Add compile option to permit invalid distance-too-far streams -- Add inflateUndermine() function which is required to enable above -- Remove use of "this" variable name for C++ compatibility [Marquess] -- Add testing of shared library in make test, if shared library built -- Use ftello() and fseeko() if available instead of ftell() and fseek() -- Provide two versions of all functions that use the z_off_t type for - binary compatibility -- a normal version and a 64-bit offset version, - per the Large File Support Extension when _LARGEFILE64_SOURCE is - defined; use the 64-bit versions by default when _FILE_OFFSET_BITS - is defined to be 64 -- Add a --uname= option to configure to perhaps help with cross-compiling - -Changes in 1.2.3.2 (3 September 2006) -- Turn off silly Borland warnings [Hay] -- Use off64_t and define _LARGEFILE64_SOURCE when present -- Fix missing dependency on inffixed.h in Makefile.in -- Rig configure --shared to build both shared and static [Teredesai, Truta] -- Remove zconf.in.h and instead create a new zlibdefs.h file -- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant] -- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt] - -Changes in 1.2.3.1 (16 August 2006) -- Add watcom directory with OpenWatcom make files [Daniel] -- Remove #undef of FAR in zconf.in.h for MVS [Fedtke] -- Update make_vms.com [Zinser] -- Use -fPIC for shared build in configure [Teredesai, Nicholson] -- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen] -- Use fdopen() (not _fdopen()) for Interix in zutil.h [Bäck] -- Add some FAQ entries about the contrib directory -- Update the MVS question in the FAQ -- Avoid extraneous reads after EOF in gzio.c [Brown] -- Correct spelling of "successfully" in gzio.c [Randers-Pehrson] -- Add comments to zlib.h about gzerror() usage [Brown] -- Set extra flags in gzip header in gzopen() like deflate() does -- Make configure options more compatible with double-dash conventions - [Weigelt] -- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen] -- Fix uninstall target in Makefile.in [Truta] -- Add pkgconfig support [Weigelt] -- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt] -- Replace set_data_type() with a more accurate detect_data_type() in - trees.c, according to the txtvsbin.txt document [Truta] -- Swap the order of #include and #include "zlib.h" in - gzio.c, example.c and minigzip.c [Truta] -- Shut up annoying VS2005 warnings about standard C deprecation [Rowe, - Truta] (where?) -- Fix target "clean" from win32/Makefile.bor [Truta] -- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe] -- Update zlib www home address in win32/DLL_FAQ.txt [Truta] -- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove] -- Enable browse info in the "Debug" and "ASM Debug" configurations in - the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta] -- Add pkgconfig support [Weigelt] -- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h, - for use in win32/zlib1.rc [Polushin, Rowe, Truta] -- Add a document that explains the new text detection scheme to - doc/txtvsbin.txt [Truta] -- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta] -- Move algorithm.txt into doc/ [Truta] -- Synchronize FAQ with website -- Fix compressBound(), was low for some pathological cases [Fearnley] -- Take into account wrapper variations in deflateBound() -- Set examples/zpipe.c input and output to binary mode for Windows -- Update examples/zlib_how.html with new zpipe.c (also web site) -- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems - that gcc became pickier in 4.0) -- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain - un-versioned, the patch adds versioning only for symbols introduced in - zlib-1.2.0 or later. It also declares as local those symbols which are - not designed to be exported." [Levin] -- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure -- Do not initialize global static by default in trees.c, add a response - NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess] -- Don't use strerror() in gzio.c under WinCE [Yakimov] -- Don't use errno.h in zutil.h under WinCE [Yakimov] -- Move arguments for AR to its usage to allow replacing ar [Marot] -- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson] -- Improve inflateInit() and inflateInit2() documentation -- Fix structure size comment in inflate.h -- Change configure help option from --h* to --help [Santos] - -Changes in 1.2.3 (18 July 2005) -- Apply security vulnerability fixes to contrib/infback9 as well -- Clean up some text files (carriage returns, trailing space) -- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] - -Changes in 1.2.2.4 (11 July 2005) -- Add inflatePrime() function for starting inflation at bit boundary -- Avoid some Visual C warnings in deflate.c -- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit - compile -- Fix some spelling errors in comments [Betts] -- Correct inflateInit2() error return documentation in zlib.h -- Add zran.c example of compressed data random access to examples - directory, shows use of inflatePrime() -- Fix cast for assignments to strm->state in inflate.c and infback.c -- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] -- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] -- Add cast in trees.c t avoid a warning [Oberhumer] -- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] -- Update make_vms.com [Zinser] -- Initialize state->write in inflateReset() since copied in inflate_fast() -- Be more strict on incomplete code sets in inflate_table() and increase - ENOUGH and MAXD -- this repairs a possible security vulnerability for - invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for - discovering the vulnerability and providing test cases. -- Add ia64 support to configure for HP-UX [Smith] -- Add error return to gzread() for format or i/o error [Levin] -- Use malloc.h for OS/2 [Necasek] - -Changes in 1.2.2.3 (27 May 2005) -- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile -- Typecast fread() return values in gzio.c [Vollant] -- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) -- Fix crc check bug in gzread() after gzungetc() [Heiner] -- Add the deflateTune() function to adjust internal compression parameters -- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) -- Remove an incorrect assertion in examples/zpipe.c -- Add C++ wrapper in infback9.h [Donais] -- Fix bug in inflateCopy() when decoding fixed codes -- Note in zlib.h how much deflateSetDictionary() actually uses -- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) -- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] -- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] -- Add gzdirect() function to indicate transparent reads -- Update contrib/minizip [Vollant] -- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] -- Add casts in crc32.c to avoid warnings [Oberhumer] -- Add contrib/masmx64 [Vollant] -- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] - -Changes in 1.2.2.2 (30 December 2004) -- Replace structure assignments in deflate.c and inflate.c with zmemcpy to - avoid implicit memcpy calls (portability for no-library compilation) -- Increase sprintf() buffer size in gzdopen() to allow for large numbers -- Add INFLATE_STRICT to check distances against zlib header -- Improve WinCE errno handling and comments [Chang] -- Remove comment about no gzip header processing in FAQ -- Add Z_FIXED strategy option to deflateInit2() to force fixed trees -- Add updated make_vms.com [Coghlan], update README -- Create a new "examples" directory, move gzappend.c there, add zpipe.c, - fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. -- Add FAQ entry and comments in deflate.c on uninitialized memory access -- Add Solaris 9 make options in configure [Gilbert] -- Allow strerror() usage in gzio.c for STDC -- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] -- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] -- Use z_off_t for adler32_combine() and crc32_combine() lengths -- Make adler32() much faster for small len -- Use OS_CODE in deflate() default gzip header - -Changes in 1.2.2.1 (31 October 2004) -- Allow inflateSetDictionary() call for raw inflate -- Fix inflate header crc check bug for file names and comments -- Add deflateSetHeader() and gz_header structure for custom gzip headers -- Add inflateGetheader() to retrieve gzip headers -- Add crc32_combine() and adler32_combine() functions -- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list -- Use zstreamp consistently in zlib.h (inflate_back functions) -- Remove GUNZIP condition from definition of inflate_mode in inflate.h - and in contrib/inflate86/inffast.S [Truta, Anderson] -- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] -- Update projects/README.projects and projects/visualc6 [Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] -- Deprecate Z_ASCII; use Z_TEXT instead [Truta] -- Use a new algorithm for setting strm->data_type in trees.c [Truta] -- Do not define an exit() prototype in zutil.c unless DEBUG defined -- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] -- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() -- Fix Darwin build version identification [Peterson] - -Changes in 1.2.2 (3 October 2004) -- Update zlib.h comments on gzip in-memory processing -- Set adler to 1 in inflateReset() to support Java test suite [Walles] -- Add contrib/dotzlib [Ravn] -- Update win32/DLL_FAQ.txt [Truta] -- Update contrib/minizip [Vollant] -- Move contrib/visual-basic.txt to old/ [Truta] -- Fix assembler builds in projects/visualc6/ [Truta] - -Changes in 1.2.1.2 (9 September 2004) -- Update INDEX file -- Fix trees.c to update strm->data_type (no one ever noticed!) -- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] -- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) -- Add limited multitasking protection to DYNAMIC_CRC_TABLE -- Add NO_vsnprintf for VMS in zutil.h [Mozilla] -- Don't declare strerror() under VMS [Mozilla] -- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize -- Update contrib/ada [Anisimkov] -- Update contrib/minizip [Vollant] -- Fix configure to not hardcode directories for Darwin [Peterson] -- Fix gzio.c to not return error on empty files [Brown] -- Fix indentation; update version in contrib/delphi/ZLib.pas and - contrib/pascal/zlibpas.pas [Truta] -- Update mkasm.bat in contrib/masmx86 [Truta] -- Update contrib/untgz [Truta] -- Add projects/README.projects [Truta] -- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] -- Remove an unnecessary assignment to curr in inftrees.c [Truta] -- Add OS/2 to exe builds in configure [Poltorak] -- Remove err dummy parameter in zlib.h [Kientzle] - -Changes in 1.2.1.1 (9 January 2004) -- Update email address in README -- Several FAQ updates -- Fix a big fat bug in inftrees.c that prevented decoding valid - dynamic blocks with only literals and no distance codes -- - Thanks to "Hot Emu" for the bug report and sample file -- Add a note to puff.c on no distance codes case. - -Changes in 1.2.1 (17 November 2003) -- Remove a tab in contrib/gzappend/gzappend.c -- Update some interfaces in contrib for new zlib functions -- Update zlib version number in some contrib entries -- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] -- Support shared libraries on Hurd and KFreeBSD [Brown] -- Fix error in NO_DIVIDE option of adler32.c - -Changes in 1.2.0.8 (4 November 2003) -- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas -- Add experimental NO_DIVIDE #define in adler32.c - - Possibly faster on some processors (let me know if it is) -- Correct Z_BLOCK to not return on first inflate call if no wrap -- Fix strm->data_type on inflate() return to correctly indicate EOB -- Add deflatePrime() function for appending in the middle of a byte -- Add contrib/gzappend for an example of appending to a stream -- Update win32/DLL_FAQ.txt [Truta] -- Delete Turbo C comment in README [Truta] -- Improve some indentation in zconf.h [Truta] -- Fix infinite loop on bad input in configure script [Church] -- Fix gzeof() for concatenated gzip files [Johnson] -- Add example to contrib/visual-basic.txt [Michael B.] -- Add -p to mkdir's in Makefile.in [vda] -- Fix configure to properly detect presence or lack of printf functions -- Add AS400 support [Monnerat] -- Add a little Cygwin support [Wilson] - -Changes in 1.2.0.7 (21 September 2003) -- Correct some debug formats in contrib/infback9 -- Cast a type in a debug statement in trees.c -- Change search and replace delimiter in configure from % to # [Beebe] -- Update contrib/untgz to 0.2 with various fixes [Truta] -- Add build support for Amiga [Nikl] -- Remove some directories in old that have been updated to 1.2 -- Add dylib building for Mac OS X in configure and Makefile.in -- Remove old distribution stuff from Makefile -- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X -- Update links in README - -Changes in 1.2.0.6 (13 September 2003) -- Minor FAQ updates -- Update contrib/minizip to 1.00 [Vollant] -- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] -- Update POSTINC comment for 68060 [Nikl] -- Add contrib/infback9 with deflate64 decoding (unsupported) -- For MVS define NO_vsnprintf and undefine FAR [van Burik] -- Add pragma for fdopen on MVS [van Burik] - -Changes in 1.2.0.5 (8 September 2003) -- Add OF to inflateBackEnd() declaration in zlib.h -- Remember start when using gzdopen in the middle of a file -- Use internal off_t counters in gz* functions to properly handle seeks -- Perform more rigorous check for distance-too-far in inffast.c -- Add Z_BLOCK flush option to return from inflate at block boundary -- Set strm->data_type on return from inflate - - Indicate bits unused, if at block boundary, and if in last block -- Replace size_t with ptrdiff_t in crc32.c, and check for correct size -- Add condition so old NO_DEFLATE define still works for compatibility -- FAQ update regarding the Windows DLL [Truta] -- INDEX update: add qnx entry, remove aix entry [Truta] -- Install zlib.3 into mandir [Wilson] -- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] -- Adapt the zlib interface to the new DLL convention guidelines [Truta] -- Introduce ZLIB_WINAPI macro to allow the export of functions using - the WINAPI calling convention, for Visual Basic [Vollant, Truta] -- Update msdos and win32 scripts and makefiles [Truta] -- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] -- Add contrib/ada [Anisimkov] -- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] -- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] -- Add contrib/masm686 [Truta] -- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm - [Truta, Vollant] -- Update contrib/delphi; rename to contrib/pascal; add example [Truta] -- Remove contrib/delphi2; add a new contrib/delphi [Truta] -- Avoid inclusion of the nonstandard in contrib/iostream, - and fix some method prototypes [Truta] -- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip - [Truta] -- Avoid the use of backslash (\) in contrib/minizip [Vollant] -- Fix file time handling in contrib/untgz; update makefiles [Truta] -- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines - [Vollant] -- Remove contrib/vstudio/vc15_16 [Vollant] -- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] -- Update README.contrib [Truta] -- Invert the assignment order of match_head and s->prev[...] in - INSERT_STRING [Truta] -- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings - [Truta] -- Compare function pointers with 0, not with NULL or Z_NULL [Truta] -- Fix prototype of syncsearch in inflate.c [Truta] -- Introduce ASMINF macro to be enabled when using an ASM implementation - of inflate_fast [Truta] -- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] -- Modify test_gzio in example.c to take a single file name as a - parameter [Truta] -- Exit the example.c program if gzopen fails [Truta] -- Add type casts around strlen in example.c [Truta] -- Remove casting to sizeof in minigzip.c; give a proper type - to the variable compared with SUFFIX_LEN [Truta] -- Update definitions of STDC and STDC99 in zconf.h [Truta] -- Synchronize zconf.h with the new Windows DLL interface [Truta] -- Use SYS16BIT instead of __32BIT__ to distinguish between - 16- and 32-bit platforms [Truta] -- Use far memory allocators in small 16-bit memory models for - Turbo C [Truta] -- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in - zlibCompileFlags [Truta] -- Cygwin has vsnprintf [Wilson] -- In Windows16, OS_CODE is 0, as in MSDOS [Truta] -- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] - -Changes in 1.2.0.4 (10 August 2003) -- Minor FAQ updates -- Be more strict when checking inflateInit2's windowBits parameter -- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well -- Add gzip wrapper option to deflateInit2 using windowBits -- Add updated QNX rule in configure and qnx directory [Bonnefoy] -- Make inflate distance-too-far checks more rigorous -- Clean up FAR usage in inflate -- Add casting to sizeof() in gzio.c and minigzip.c - -Changes in 1.2.0.3 (19 July 2003) -- Fix silly error in gzungetc() implementation [Vollant] -- Update contrib/minizip and contrib/vstudio [Vollant] -- Fix printf format in example.c -- Correct cdecl support in zconf.in.h [Anisimkov] -- Minor FAQ updates - -Changes in 1.2.0.2 (13 July 2003) -- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons -- Attempt to avoid warnings in crc32.c for pointer-int conversion -- Add AIX to configure, remove aix directory [Bakker] -- Add some casts to minigzip.c -- Improve checking after insecure sprintf() or vsprintf() calls -- Remove #elif's from crc32.c -- Change leave label to inf_leave in inflate.c and infback.c to avoid - library conflicts -- Remove inflate gzip decoding by default--only enable gzip decoding by - special request for stricter backward compatibility -- Add zlibCompileFlags() function to return compilation information -- More typecasting in deflate.c to avoid warnings -- Remove leading underscore from _Capital #defines [Truta] -- Fix configure to link shared library when testing -- Add some Windows CE target adjustments [Mai] -- Remove #define ZLIB_DLL in zconf.h [Vollant] -- Add zlib.3 [Rodgers] -- Update RFC URL in deflate.c and algorithm.txt [Mai] -- Add zlib_dll_FAQ.txt to contrib [Truta] -- Add UL to some constants [Truta] -- Update minizip and vstudio [Vollant] -- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h -- Expand use of NO_DUMMY_DECL to avoid all dummy structures -- Added iostream3 to contrib [Schwardt] -- Replace rewind() with fseek() for WinCE [Truta] -- Improve setting of zlib format compression level flags - - Report 0 for huffman and rle strategies and for level == 0 or 1 - - Report 2 only for level == 6 -- Only deal with 64K limit when necessary at compile time [Truta] -- Allow TOO_FAR check to be turned off at compile time [Truta] -- Add gzclearerr() function [Souza] -- Add gzungetc() function - -Changes in 1.2.0.1 (17 March 2003) -- Add Z_RLE strategy for run-length encoding [Truta] - - When Z_RLE requested, restrict matches to distance one - - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE -- Correct FASTEST compilation to allow level == 0 -- Clean up what gets compiled for FASTEST -- Incorporate changes to zconf.in.h [Vollant] - - Refine detection of Turbo C need for dummy returns - - Refine ZLIB_DLL compilation - - Include additional header file on VMS for off_t typedef -- Try to use _vsnprintf where it supplants vsprintf [Vollant] -- Add some casts in inffast.c -- Enchance comments in zlib.h on what happens if gzprintf() tries to - write more than 4095 bytes before compression -- Remove unused state from inflateBackEnd() -- Remove exit(0) from minigzip.c, example.c -- Get rid of all those darn tabs -- Add "check" target to Makefile.in that does the same thing as "test" -- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in -- Update contrib/inflate86 [Anderson] -- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] -- Add msdos and win32 directories with makefiles [Truta] -- More additions and improvements to the FAQ - -Changes in 1.2.0 (9 March 2003) -- New and improved inflate code - - About 20% faster - - Does not allocate 32K window unless and until needed - - Automatically detects and decompresses gzip streams - - Raw inflate no longer needs an extra dummy byte at end - - Added inflateBack functions using a callback interface--even faster - than inflate, useful for file utilities (gzip, zip) - - Added inflateCopy() function to record state for random access on - externally generated deflate streams (e.g. in gzip files) - - More readable code (I hope) -- New and improved crc32() - - About 50% faster, thanks to suggestions from Rodney Brown -- Add deflateBound() and compressBound() functions -- Fix memory leak in deflateInit2() -- Permit setting dictionary for raw deflate (for parallel deflate) -- Fix const declaration for gzwrite() -- Check for some malloc() failures in gzio.c -- Fix bug in gzopen() on single-byte file 0x1f -- Fix bug in gzread() on concatenated file with 0x1f at end of buffer - and next buffer doesn't start with 0x8b -- Fix uncompress() to return Z_DATA_ERROR on truncated input -- Free memory at end of example.c -- Remove MAX #define in trees.c (conflicted with some libraries) -- Fix static const's in deflate.c, gzio.c, and zutil.[ch] -- Declare malloc() and free() in gzio.c if STDC not defined -- Use malloc() instead of calloc() in zutil.c if int big enough -- Define STDC for AIX -- Add aix/ with approach for compiling shared library on AIX -- Add HP-UX support for shared libraries in configure -- Add OpenUNIX support for shared libraries in configure -- Use $cc instead of gcc to build shared library -- Make prefix directory if needed when installing -- Correct Macintosh avoidance of typedef Byte in zconf.h -- Correct Turbo C memory allocation when under Linux -- Use libz.a instead of -lz in Makefile (assure use of compiled library) -- Update configure to check for snprintf or vsnprintf functions and their - return value, warn during make if using an insecure function -- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that - is lost when library is used--resolution is to build new zconf.h -- Documentation improvements (in zlib.h): - - Document raw deflate and inflate - - Update RFCs URL - - Point out that zlib and gzip formats are different - - Note that Z_BUF_ERROR is not fatal - - Document string limit for gzprintf() and possible buffer overflow - - Note requirement on avail_out when flushing - - Note permitted values of flush parameter of inflate() -- Add some FAQs (and even answers) to the FAQ -- Add contrib/inflate86/ for x86 faster inflate -- Add contrib/blast/ for PKWare Data Compression Library decompression -- Add contrib/puff/ simple inflate for deflate format description - -Changes in 1.1.4 (11 March 2002) -- ZFREE was repeated on same allocation on some error conditions. - This creates a security problem described in - http://www.zlib.org/advisory-2002-03-11.txt -- Returned incorrect error (Z_MEM_ERROR) on some invalid data -- Avoid accesses before window for invalid distances with inflate window - less than 32K. -- force windowBits > 8 to avoid a bug in the encoder for a window size - of 256 bytes. (A complete fix will be available in 1.1.5). - -Changes in 1.1.3 (9 July 1998) -- fix "an inflate input buffer bug that shows up on rare but persistent - occasions" (Mark) -- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) -- fix gzseek(..., SEEK_SET) in write mode -- fix crc check after a gzeek (Frank Faubert) -- fix miniunzip when the last entry in a zip file is itself a zip file - (J Lillge) -- add contrib/asm586 and contrib/asm686 (Brian Raiter) - See http://www.muppetlabs.com/~breadbox/software/assembly.html -- add support for Delphi 3 in contrib/delphi (Bob Dellaca) -- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) -- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) -- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) -- added a FAQ file - -- Support gzdopen on Mac with Metrowerks (Jason Linhart) -- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) -- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) -- avoid some warnings with Borland C (Tom Tanner) -- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) -- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) -- allow several arguments to configure (Tim Mooney, Frodo Looijaard) -- use libdir and includedir in Makefile.in (Tim Mooney) -- support shared libraries on OSF1 V4 (Tim Mooney) -- remove so_locations in "make clean" (Tim Mooney) -- fix maketree.c compilation error (Glenn, Mark) -- Python interface to zlib now in Python 1.5 (Jeremy Hylton) -- new Makefile.riscos (Rich Walker) -- initialize static descriptors in trees.c for embedded targets (Nick Smith) -- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) -- add the OS/2 files in Makefile.in too (Andrew Zabolotny) -- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) -- fix maketree.c to allow clean compilation of inffixed.h (Mark) -- fix parameter check in deflateCopy (Gunther Nikl) -- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) -- Many portability patches by Christian Spieler: - . zutil.c, zutil.h: added "const" for zmem* - . Make_vms.com: fixed some typos - . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists - . msdos/Makefile.msc: remove "default rtl link library" info from obj files - . msdos/Makefile.*: use model-dependent name for the built zlib library - . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: - new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) -- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) -- replace __far with _far for better portability (Christian Spieler, Tom Lane) -- fix test for errno.h in configure (Tim Newsham) - -Changes in 1.1.2 (19 March 98) -- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) - See http://www.winimage.com/zLibDll/unzip.html -- preinitialize the inflate tables for fixed codes, to make the code - completely thread safe (Mark) -- some simplifications and slight speed-up to the inflate code (Mark) -- fix gzeof on non-compressed files (Allan Schrum) -- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) -- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) -- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) -- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) -- do not wrap extern "C" around system includes (Tom Lane) -- mention zlib binding for TCL in README (Andreas Kupries) -- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) -- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) -- allow "configure --prefix $HOME" (Tim Mooney) -- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) -- move Makefile.sas to amiga/Makefile.sas - -Changes in 1.1.1 (27 Feb 98) -- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) -- remove block truncation heuristic which had very marginal effect for zlib - (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the - compression ratio on some files. This also allows inlining _tr_tally for - matches in deflate_slow. -- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) - -Changes in 1.1.0 (24 Feb 98) -- do not return STREAM_END prematurely in inflate (John Bowler) -- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) -- compile with -DFASTEST to get compression code optimized for speed only -- in minigzip, try mmap'ing the input file first (Miguel Albrecht) -- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain - on Sun but significant on HP) - -- add a pointer to experimental unzip library in README (Gilles Vollant) -- initialize variable gcc in configure (Chris Herborth) - -Changes in 1.0.9 (17 Feb 1998) -- added gzputs and gzgets functions -- do not clear eof flag in gzseek (Mark Diekhans) -- fix gzseek for files in transparent mode (Mark Diekhans) -- do not assume that vsprintf returns the number of bytes written (Jens Krinke) -- replace EXPORT with ZEXPORT to avoid conflict with other programs -- added compress2 in zconf.h, zlib.def, zlib.dnt -- new asm code from Gilles Vollant in contrib/asm386 -- simplify the inflate code (Mark): - . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() - . ZALLOC the length list in inflate_trees_fixed() instead of using stack - . ZALLOC the value area for huft_build() instead of using stack - . Simplify Z_FINISH check in inflate() - -- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 -- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) -- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with - the declaration of FAR (Gilles VOllant) -- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) -- read_buf buf parameter of type Bytef* instead of charf* -- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) -- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) -- fix check for presence of directories in "make install" (Ian Willis) - -Changes in 1.0.8 (27 Jan 1998) -- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) -- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) -- added compress2() to allow setting the compression level -- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) -- use constant arrays for the static trees in trees.c instead of computing - them at run time (thanks to Ken Raeburn for this suggestion). To create - trees.h, compile with GEN_TREES_H and run "make test". -- check return code of example in "make test" and display result -- pass minigzip command line options to file_compress -- simplifying code of inflateSync to avoid gcc 2.8 bug - -- support CC="gcc -Wall" in configure -s (QingLong) -- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) -- fix test for shared library support to avoid compiler warnings -- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) -- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) -- do not use fdopen for Metrowerks on Mac (Brad Pettit)) -- add checks for gzputc and gzputc in example.c -- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) -- use const for the CRC table (Ken Raeburn) -- fixed "make uninstall" for shared libraries -- use Tracev instead of Trace in infblock.c -- in example.c use correct compressed length for test_sync -- suppress +vnocompatwarnings in configure for HPUX (not always supported) - -Changes in 1.0.7 (20 Jan 1998) -- fix gzseek which was broken in write mode -- return error for gzseek to negative absolute position -- fix configure for Linux (Chun-Chung Chen) -- increase stack space for MSC (Tim Wegner) -- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) -- define EXPORTVA for gzprintf (Gilles Vollant) -- added man page zlib.3 (Rick Rodgers) -- for contrib/untgz, fix makedir() and improve Makefile - -- check gzseek in write mode in example.c -- allocate extra buffer for seeks only if gzseek is actually called -- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) -- add inflateSyncPoint in zconf.h -- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def - -Changes in 1.0.6 (19 Jan 1998) -- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and - gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) -- Fix a deflate bug occurring only with compression level 0 (thanks to - Andy Buckler for finding this one). -- In minigzip, pass transparently also the first byte for .Z files. -- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() -- check Z_FINISH in inflate (thanks to Marc Schluper) -- Implement deflateCopy (thanks to Adam Costello) -- make static libraries by default in configure, add --shared option. -- move MSDOS or Windows specific files to directory msdos -- suppress the notion of partial flush to simplify the interface - (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) -- suppress history buffer provided by application to simplify the interface - (this feature was not implemented anyway in 1.0.4) -- next_in and avail_in must be initialized before calling inflateInit or - inflateInit2 -- add EXPORT in all exported functions (for Windows DLL) -- added Makefile.nt (thanks to Stephen Williams) -- added the unsupported "contrib" directory: - contrib/asm386/ by Gilles Vollant - 386 asm code replacing longest_match(). - contrib/iostream/ by Kevin Ruland - A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge Løvset - Another C++ I/O streams interface - contrib/untgz/ by "Pedro A. Aranda Guti\irrez" - A very simple tar.gz file extractor using zlib - contrib/visual-basic.txt by Carlos Rios - How to use compress(), uncompress() and the gz* functions from VB. -- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression - level) in minigzip (thanks to Tom Lane) - -- use const for rommable constants in deflate -- added test for gzseek and gztell in example.c -- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) -- add undocumented function zError to convert error code to string - (for Tim Smithers) -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. -- Use default memcpy for Symantec MSDOS compiler. -- Add EXPORT keyword for check_func (needed for Windows DLL) -- add current directory to LD_LIBRARY_PATH for "make test" -- create also a link for libz.so.1 -- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) -- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) -- added -soname for Linux in configure (Chun-Chung Chen, -- assign numbers to the exported functions in zlib.def (for Windows DLL) -- add advice in zlib.h for best usage of deflateSetDictionary -- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) -- allow compilation with ANSI keywords only enabled for TurboC in large model -- avoid "versionString"[0] (Borland bug) -- add NEED_DUMMY_RETURN for Borland -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). -- allow compilation with CC -- defined STDC for OS/2 (David Charlap) -- limit external names to 8 chars for MVS (Thomas Lund) -- in minigzip.c, use static buffers only for 16-bit systems -- fix suffix check for "minigzip -d foo.gz" -- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) -- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) -- added makelcc.bat for lcc-win32 (Tom St Denis) -- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. -- check for unistd.h in configure (for off_t) -- remove useless check parameter in inflate_blocks_free -- avoid useless assignment of s->check to itself in inflate_blocks_new -- do not flush twice in gzclose (thanks to Ken Raeburn) -- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h -- use NO_ERRNO_H instead of enumeration of operating systems with errno.h -- work around buggy fclose on pipes for HP/UX -- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) -- fix configure if CC is already equal to gcc - -Changes in 1.0.5 (3 Jan 98) -- Fix inflate to terminate gracefully when fed corrupted or invalid data -- Use const for rommable constants in inflate -- Eliminate memory leaks on error conditions in inflate -- Removed some vestigial code in inflate -- Update web address in README - -Changes in 1.0.4 (24 Jul 96) -- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - bit, so the decompressor could decompress all the correct data but went - on to attempt decompressing extra garbage data. This affected minigzip too. -- zlibVersion and gzerror return const char* (needed for DLL) -- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) -- use z_error only for DEBUG (avoid problem with DLLs) - -Changes in 1.0.3 (2 Jul 96) -- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS - small and medium models; this makes the library incompatible with previous - versions for these models. (No effect in large model or on other systems.) -- return OK instead of BUF_ERROR if previous deflate call returned with - avail_out as zero but there is nothing to do -- added memcmp for non STDC compilers -- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) -- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) -- better check for 16-bit mode MSC (avoids problem with Symantec) - -Changes in 1.0.2 (23 May 96) -- added Windows DLL support -- added a function zlibVersion (for the DLL support) -- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) -- Bytef is define's instead of typedef'd only for Borland C -- avoid reading uninitialized memory in example.c -- mention in README that the zlib format is now RFC1950 -- updated Makefile.dj2 -- added algorithm.doc - -Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] -- fix array overlay in deflate.c which sometimes caused bad compressed data -- fix inflate bug with empty stored block -- fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generate bad compressed data. -- Bytef is define'd instead of typedef'ed (work around Borland bug) -- added an INDEX file -- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), - Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) -- speed up adler32 for modern machines without auto-increment -- added -ansi for IRIX in configure -- static_init_done in trees.c is an int -- define unlink as delete for VMS -- fix configure for QNX -- add configure branch for SCO and HPUX -- avoid many warnings (unused variables, dead assignments, etc...) -- no fdopen for BeOS -- fix the Watcom fix for 32 bit mode (define FAR as empty) -- removed redefinition of Byte for MKWERKS -- work around an MWKERKS bug (incorrect merge of all .h files) - -Changes in 0.99 (27 Jan 96) -- allow preset dictionary shared between compressor and decompressor -- allow compression level 0 (no compression) -- add deflateParams in zlib.h: allow dynamic change of compression level - and compression strategy. -- test large buffers and deflateParams in example.c -- add optional "configure" to build zlib as a shared library -- suppress Makefile.qnx, use configure instead -- fixed deflate for 64-bit systems (detected on Cray) -- fixed inflate_blocks for 64-bit systems (detected on Alpha) -- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) -- always return Z_BUF_ERROR when deflate() has nothing to do -- deflateInit and inflateInit are now macros to allow version checking -- prefix all global functions and types with z_ with -DZ_PREFIX -- make falloc completely reentrant (inftrees.c) -- fixed very unlikely race condition in ct_static_init -- free in reverse order of allocation to help memory manager -- use zlib-1.0/* instead of zlib/* inside the tar.gz -- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith - -Wconversion -Wstrict-prototypes -Wmissing-prototypes" -- allow gzread on concatenated .gz files -- deflateEnd now returns Z_DATA_ERROR if it was premature -- deflate is finally (?) fully deterministic (no matches beyond end of input) -- Document Z_SYNC_FLUSH -- add uninstall in Makefile -- Check for __cpluplus in zlib.h -- Better test in ct_align for partial flush -- avoid harmless warnings for Borland C++ -- initialize hash_head in deflate.c -- avoid warning on fdopen (gzio.c) for HP cc -Aa -- include stdlib.h for STDC compilers -- include errno.h for Cray -- ignore error if ranlib doesn't exist -- call ranlib twice for NeXTSTEP -- use exec_prefix instead of prefix for libz.a -- renamed ct_* as _tr_* to avoid conflict with applications -- clear z->msg in inflateInit2 before any error return -- initialize opaque in example.c, gzio.c, deflate.c and inflate.c -- fixed typo in zconf.h (_GNUC__ => __GNUC__) -- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) -- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) -- in fcalloc, normalize pointer if size > 65520 bytes -- don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... -- use Z_BINARY instead of BINARY -- document that gzclose after gzdopen will close the file -- allow "a" as mode in gzopen. -- fix error checking in gzread -- allow skipping .gz extra-field on pipes -- added reference to Perl interface in README -- put the crc table in FAR data (I dislike more and more the medium model :) -- added get_crc_table -- added a dimension to all arrays (Borland C can't count). -- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast -- guard against multiple inclusion of *.h (for precompiled header on Mac) -- Watcom C pretends to be Microsoft C small model even in 32 bit mode. -- don't use unsized arrays to avoid silly warnings by Visual C++: - warning C4746: 'inflate_mask' : unsized array treated as '__far' - (what's wrong with far data in far model?). -- define enum out of inflate_blocks_state to allow compilation with C++ - -Changes in 0.95 (16 Aug 95) -- fix MSDOS small and medium model (now easier to adapt to any compiler) -- inlined send_bits -- fix the final (:-) bug for deflate with flush (output was correct but - not completely flushed in rare occasions). -- default window size is same for compression and decompression - (it's now sufficient to set MAX_WBITS in zconf.h). -- voidp -> voidpf and voidnp -> voidp (for consistency with other - typedefs and because voidnp was not near in large model). - -Changes in 0.94 (13 Aug 95) -- support MSDOS medium model -- fix deflate with flush (could sometimes generate bad output) -- fix deflateReset (zlib header was incorrectly suppressed) -- added support for VMS -- allow a compression level in gzopen() -- gzflush now calls fflush -- For deflate with flush, flush even if no more input is provided. -- rename libgz.a as libz.a -- avoid complex expression in infcodes.c triggering Turbo C bug -- work around a problem with gcc on Alpha (in INSERT_STRING) -- don't use inline functions (problem with some gcc versions) -- allow renaming of Byte, uInt, etc... with #define. -- avoid warning about (unused) pointer before start of array in deflate.c -- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c -- avoid reserved word 'new' in trees.c - -Changes in 0.93 (25 June 95) -- temporarily disable inline functions -- make deflate deterministic -- give enough lookahead for PARTIAL_FLUSH -- Set binary mode for stdin/stdout in minigzip.c for OS/2 -- don't even use signed char in inflate (not portable enough) -- fix inflate memory leak for segmented architectures - -Changes in 0.92 (3 May 95) -- don't assume that char is signed (problem on SGI) -- Clear bit buffer when starting a stored block -- no memcpy on Pyramid -- suppressed inftest.c -- optimized fill_window, put longest_match inline for gcc -- optimized inflate on stored blocks. -- untabify all sources to simplify patches - -Changes in 0.91 (2 May 95) -- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h -- Document the memory requirements in zconf.h -- added "make install" -- fix sync search logic in inflateSync -- deflate(Z_FULL_FLUSH) now works even if output buffer too short -- after inflateSync, don't scare people with just "lo world" -- added support for DJGPP - -Changes in 0.9 (1 May 95) -- don't assume that zalloc clears the allocated memory (the TurboC bug - was Mark's bug after all :) -- let again gzread copy uncompressed data unchanged (was working in 0.71) -- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented -- added a test of inflateSync in example.c -- moved MAX_WBITS to zconf.h because users might want to change that. -- document explicitly that zalloc(64K) on MSDOS must return a normalized - pointer (zero offset) -- added Makefiles for Microsoft C, Turbo C, Borland C++ -- faster crc32() - -Changes in 0.8 (29 April 95) -- added fast inflate (inffast.c) -- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this - is incompatible with previous versions of zlib which returned Z_OK. -- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) - (actually that was not a compiler bug, see 0.81 above) -- gzread no longer reads one extra byte in certain cases -- In gzio destroy(), don't reference a freed structure -- avoid many warnings for MSDOS -- avoid the ERROR symbol which is used by MS Windows - -Changes in 0.71 (14 April 95) -- Fixed more MSDOS compilation problems :( There is still a bug with - TurboC large model. - -Changes in 0.7 (14 April 95) -- Added full inflate support. -- Simplified the crc32() interface. The pre- and post-conditioning - (one's complement) is now done inside crc32(). WARNING: this is - incompatible with previous versions; see zlib.h for the new usage. - -Changes in 0.61 (12 April 95) -- workaround for a bug in TurboC. example and minigzip now work on MSDOS. - -Changes in 0.6 (11 April 95) -- added minigzip.c -- added gzdopen to reopen a file descriptor as gzFile -- added transparent reading of non-gziped files in gzread. -- fixed bug in gzread (don't read crc as data) -- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). -- don't allocate big arrays in the stack (for MSDOS) -- fix some MSDOS compilation problems - -Changes in 0.5: -- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but - not yet Z_FULL_FLUSH. -- support decompression but only in a single step (forced Z_FINISH) -- added opaque object for zalloc and zfree. -- added deflateReset and inflateReset -- added a variable zlib_version for consistency checking. -- renamed the 'filter' parameter of deflateInit2 as 'strategy'. - Added Z_FILTERED and Z_HUFFMAN_ONLY constants. - -Changes in 0.4: -- avoid "zip" everywhere, use zlib instead of ziplib. -- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush - if compression method == 8. -- added adler32 and crc32 -- renamed deflateOptions as deflateInit2, call one or the other but not both -- added the method parameter for deflateInit2. -- added inflateInit2 -- simplied considerably deflateInit and inflateInit by not supporting - user-provided history buffer. This is supported only in deflateInit2 - and inflateInit2. - -Changes in 0.3: -- prefix all macro names with Z_ -- use Z_FINISH instead of deflateEnd to finish compression. -- added Z_HUFFMAN_ONLY -- added gzerror() diff --git a/Sources/PerfectCZlib/FAQ b/Sources/PerfectCZlib/FAQ deleted file mode 100644 index 99b7cf92..00000000 --- a/Sources/PerfectCZlib/FAQ +++ /dev/null @@ -1,368 +0,0 @@ - - Frequently Asked Questions about zlib - - -If your question is not there, please check the zlib home page -http://zlib.net/ which may have more recent information. -The lastest zlib FAQ is at http://zlib.net/zlib_faq.html - - - 1. Is zlib Y2K-compliant? - - Yes. zlib doesn't handle dates. - - 2. Where can I get a Windows DLL version? - - The zlib sources can be compiled without change to produce a DLL. See the - file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the - precompiled DLL are found in the zlib web site at http://zlib.net/ . - - 3. Where can I get a Visual Basic interface to zlib? - - See - * http://marknelson.us/1997/01/01/zlib-engine/ - * win32/DLL_FAQ.txt in the zlib distribution - - 4. compress() returns Z_BUF_ERROR. - - Make sure that before the call of compress(), the length of the compressed - buffer is equal to the available size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference - ("as any"), not by value ("as long"). - - 5. deflate() or inflate() returns Z_BUF_ERROR. - - Before making the call, make sure that avail_in and avail_out are not zero. - When setting the parameter flush equal to Z_FINISH, also make sure that - avail_out is big enough to allow processing all pending input. Note that a - Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be - made with more input or output space. A Z_BUF_ERROR may in fact be - unavoidable depending on how the functions are used, since it is not - possible to tell whether or not there is more output pending when - strm.avail_out returns with zero. See http://zlib.net/zlib_how.html for a - heavily annotated example. - - 6. Where's the zlib documentation (man pages, etc.)? - - It's in zlib.h . Examples of zlib usage are in the files test/example.c - and test/minigzip.c, with more in examples/ . - - 7. Why don't you use GNU autoconf or libtool or ...? - - Because we would like to keep zlib as a very small and simple package. - zlib is rather portable and doesn't need much configuration. - - 8. I found a bug in zlib. - - Most of the time, such problems are due to an incorrect usage of zlib. - Please try to reproduce the problem with a small program and send the - corresponding source to us at zlib@gzip.org . Do not send multi-megabyte - data files without prior agreement. - - 9. Why do I get "undefined reference to gzputc"? - - If "make test" produces something like - - example.o(.text+0x154): undefined reference to `gzputc' - - check that you don't have old files libz.* in /usr/lib, /usr/local/lib or - /usr/X11R6/lib. Remove any old versions, then do "make install". - -10. I need a Delphi interface to zlib. - - See the contrib/delphi directory in the zlib distribution. - -11. Can zlib handle .zip archives? - - Not by itself, no. See the directory contrib/minizip in the zlib - distribution. - -12. Can zlib handle .Z files? - - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt - the code of uncompress on your own. - -13. How can I make a Unix shared library? - - By default a shared (and a static) library is built for Unix. So: - - make distclean - ./configure - make - -14. How do I install a shared zlib library on Unix? - - After the above, then: - - make install - - However, many flavors of Unix come with a shared zlib already installed. - Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to - it. You can check the version at the top of zlib.h or with the - ZLIB_VERSION symbol defined in zlib.h . - -15. I have a question about OttoPDF. - - We are not the authors of OttoPDF. The real author is on the OttoPDF web - site: Joel Hainley, jhainley@myndkryme.com. - -16. Can zlib decode Flate data in an Adobe PDF file? - - Yes. See http://www.pdflib.com/ . To modify PDF forms, see - http://sourceforge.net/projects/acroformtool/ . - -17. Why am I getting this "register_frame_info not found" error on Solaris? - - After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib - generates an error such as: - - ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: - symbol __register_frame_info: referenced symbol not found - - The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See - http://www.sunfreeware.com for Solaris versions of zlib and applications - using zlib. - -18. Why does gzip give an error on a file I make with compress/deflate? - - The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip formats - use the same compressed data format internally, but have different headers - and trailers around the compressed data. - -19. Ok, so why are there two different formats? - - The gzip format was designed to retain the directory information about a - single file, such as the name and last modification date. The zlib format - on the other hand was designed for in-memory and communication channel - applications, and has a much more compact header and trailer and uses a - faster integrity check than gzip. - -20. Well that's nice, but how do I make a gzip file in memory? - - You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode the - gzip format using inflateInit2(). Read zlib.h for more details. - -21. Is zlib thread-safe? - - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* - functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's *Init* functions - allow for the application to provide custom memory allocation routines. - - Of course, you should only operate on any given zlib or gzip stream from a - single thread at a time. - -22. Can I use zlib in my commercial application? - - Yes. Please read the license in zlib.h. - -23. Is zlib under the GNU license? - - No. Please read the license in zlib.h. - -24. The license says that altered source versions must be "plainly marked". So - what exactly do I need to do to meet that requirement? - - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In - particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers - x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering - is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also - update the version strings in deflate.c and inftrees.c. - - For altered source distributions, you should also note the origin and - nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your - name (or your company's name), and an email address to contact for help or - issues with the library. - - Note that distributing a compiled zlib library along with zlib.h and - zconf.h is also a source distribution, and so you should change - ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes - in zlib.h as you would for a full source distribution. - -25. Will zlib work on a big-endian or little-endian architecture, and can I - exchange compressed data between them? - - Yes and yes. - -26. Will zlib work on a 64-bit machine? - - Yes. It has been tested on 64-bit machines, and has no dependence on any - data types being limited to 32-bits in length. If you have any - difficulties, please provide a complete problem report to zlib@gzip.org - -27. Will zlib decompress data from the PKWare Data Compression Library? - - No. The PKWare DCL uses a completely different compressed data format than - does PKZIP and zlib. However, you can look in zlib's contrib/blast - directory for a possible solution to your problem. - -28. Can I access data randomly in a compressed stream? - - No, not without some preparation. If when compressing you periodically use - Z_FULL_FLUSH, carefully write all the pending data at those points, and - keep an index of those locations, then you can start decompression at those - points. You have to be careful to not use Z_FULL_FLUSH too often, since it - can significantly degrade compression. Alternatively, you can scan a - deflate stream once to generate an index, and then use that index for - random access. See examples/zran.c . - -29. Does zlib work on MVS, OS/390, CICS, etc.? - - It has in the past, but we have not heard of any recent evidence. There - were working ports of zlib 1.1.4 to MVS, but those links no longer work. - If you know of recent, successful applications of zlib on these operating - systems, please let us know. Thanks. - -30. Is there some simpler, easier to read version of inflate I can look at to - understand the deflate format? - - First off, you should read RFC 1951. Second, yes. Look in zlib's - contrib/puff directory. - -31. Does zlib infringe on any patents? - - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: - - http://www.gzip.org/#faq11 - -32. Can zlib work with greater than 4 GB of data? - - Yes. inflate() and deflate() will process any amount of data correctly. - Each call of inflate() or deflate() is limited to input and output chunks - of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These - counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters - updated after each call of inflate() or deflate() to count beyond 4 GB. - compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. - - The word "may" appears several times above since there is a 4 GB limit only - if the compiler's "long" type is 32 bits. If the compiler's "long" type is - 64 bits, then the limit is 16 exabytes. - -33. Does zlib have any security vulnerabilities? - - The only one that we are aware of is potentially in gzprintf(). If zlib is - compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of an 8K string space (or other value as set by - gzbuffer()), other than the caller of gzprintf() assuring that the output - will not exceed 8K. On the other hand, if zlib is compiled to use - snprintf() or vsnprintf(), which should normally be the case, then there is - no vulnerability. The ./configure script will display warnings if an - insecure variation of sprintf() will be used by gzprintf(). Also the - zlibCompileFlags() function will return information on what variant of - sprintf() is used by gzprintf(). - - If you don't have snprintf() or vsnprintf() and would like one, you can - find a portable implementation here: - - http://www.ijs.si/software/snprintf/ - - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability, and versions - 1.2.1 and 1.2.2 were subject to an access exception when decompressing - invalid compressed data. - -34. Is there a Java version of zlib? - - Probably what you want is to use zlib in Java. zlib is already included - as part of the Java SDK in the java.util.zip package. If you really want - a version of zlib written in the Java language, look on the zlib home - page for links: http://zlib.net/ . - -35. I get this or that compiler or source-code scanner warning when I crank it - up to maximally-pedantic. Can't you guys write proper code? - - Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly as well as contradicted each other. So now, we simply - make sure that the code always works. - -36. Valgrind (or some similar memory access checker) says that deflate is - performing a conditional jump that depends on an uninitialized value. - Isn't that a bug? - - No. That is intentional for performance reasons, and the output of deflate - is not affected. This only started showing up recently since zlib 1.2.x - uses malloc() by default for allocations, whereas earlier versions used - calloc(), which zeros out the allocated memory. Even though the code was - correct, versions 1.2.4 and later was changed to not stimulate these - checkers. - -37. Will zlib read the (insert any ancient or arcane format here) compressed - data format? - - Probably not. Look in the comp.compression FAQ for pointers to various - formats and associated software. - -38. How can I encrypt/decrypt zip files with zlib? - - zlib doesn't support encryption. The original PKZIP encryption is very - weak and can be broken with freely available programs. To get strong - encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib - compression. For PKZIP compatible "encryption", look at - http://www.info-zip.org/ - -39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion with - the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 - correctly points to the zlib specification in RFC 1950 for the "deflate" - transfer encoding, there have been reports of servers and browsers that - incorrectly produce or expect raw deflate data per the deflate - specification in RFC 1951, most notably Microsoft. So even though the - "deflate" transfer encoding using the zlib format would be the more - efficient approach (and in fact exactly what the zlib format was designed - for), using the "gzip" transfer encoding is probably more reliable due to - an unfortunate choice of name on the part of the HTTP 1.1 authors. - - Bottom line: use the gzip format for HTTP 1.1 encoding. - -40. Does zlib support the new "Deflate64" format introduced by PKWare? - - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. In - any case, the compression improvements are so modest compared to other more - modern approaches, that it's not worth the effort to implement. - -41. I'm having a problem with the zip functions in zlib, can you help? - - There are no zip functions in zlib. You are probably using minizip by - Giles Vollant, which is found in the contrib directory of zlib. It is not - part of zlib. In fact none of the stuff in contrib is part of zlib. The - files in there are not supported by the zlib authors. You need to contact - the authors of the respective contribution for help. - -42. The match.asm code in contrib is under the GNU General Public License. - Since it's part of zlib, doesn't that mean that all of zlib falls under the - GNU GPL? - - No. The files in contrib are not part of zlib. They were contributed by - other authors and are provided as a convenience to the user within the zlib - distribution. Each item in contrib has its own license. - -43. Is zlib subject to export controls? What is its ECCN? - - zlib is not subject to export controls, and so is classified as EAR99. - -44. Can you please sign these lengthy legal documents and fax them back to us - so that we can use your software in our product? - - No. Go away. Shoo. diff --git a/Sources/PerfectCZlib/INDEX b/Sources/PerfectCZlib/INDEX deleted file mode 100644 index 2ba06412..00000000 --- a/Sources/PerfectCZlib/INDEX +++ /dev/null @@ -1,68 +0,0 @@ -CMakeLists.txt cmake build file -ChangeLog history of changes -FAQ Frequently Asked Questions about zlib -INDEX this file -Makefile dummy Makefile that tells you to ./configure -Makefile.in template for Unix Makefile -README guess what -configure configure script for Unix -make_vms.com makefile for VMS -test/example.c zlib usages examples for build testing -test/minigzip.c minimal gzip-like functionality for build testing -test/infcover.c inf*.c code coverage for build coverage testing -treebuild.xml XML description of source file dependencies -zconf.h.cmakein zconf.h template for cmake -zconf.h.in zconf.h template for configure -zlib.3 Man page for zlib -zlib.3.pdf Man page in PDF format -zlib.map Linux symbol information -zlib.pc.in Template for pkg-config descriptor -zlib.pc.cmakein zlib.pc template for cmake -zlib2ansi perl script to convert source files for C++ compilation - -amiga/ makefiles for Amiga SAS C -as400/ makefiles for AS/400 -doc/ documentation for formats and algorithms -msdos/ makefiles for MSDOS -nintendods/ makefile for Nintendo DS -old/ makefiles for various architectures and zlib documentation - files that have not yet been updated for zlib 1.2.x -qnx/ makefiles for QNX -watcom/ makefiles for OpenWatcom -win32/ makefiles for Windows - - zlib public header files (required for library use): -zconf.h -zlib.h - - private source files used to build the zlib library: -adler32.c -compress.c -crc32.c -crc32.h -deflate.c -deflate.h -gzclose.c -gzguts.h -gzlib.c -gzread.c -gzwrite.c -infback.c -inffast.c -inffast.h -inffixed.h -inflate.c -inflate.h -inftrees.c -inftrees.h -trees.c -trees.h -uncompr.c -zutil.c -zutil.h - - source files for sample programs -See examples/README.examples - - unsupported contributions by third parties -See contrib/README.contrib diff --git a/Sources/PerfectCZlib/Makefile b/Sources/PerfectCZlib/Makefile deleted file mode 100644 index a7f1c5b9..00000000 --- a/Sources/PerfectCZlib/Makefile +++ /dev/null @@ -1,405 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# ./configure; make test -# Normally configure builds both a static and a shared library. -# If you want to build just a static library, use: ./configure --static - -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o - -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: -# make install -# To install in $HOME instead of /usr/local, use: -# make install prefix=$HOME - -CC=gcc - -CFLAGS=-O3 -DHAVE_HIDDEN -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DZLIB_DEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -SFLAGS=-O3 -fPIC -DHAVE_HIDDEN -LDFLAGS= -TEST_LDFLAGS=-L. libz.a -LDSHARED=gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -CPP=gcc -E - -STATICLIB=libz.a -SHAREDLIB=libz.dylib -SHAREDLIBV=libz.1.2.9.dylib -SHAREDLIBM=libz.1.dylib -LIBS=$(STATICLIB) $(SHAREDLIBV) - -AR=libtool -ARFLAGS=-o -RANLIB=ranlib -LDCONFIG=ldconfig -LDSHAREDLIBC=-lc -TAR=tar -SHELL=/bin/sh -EXE= - -prefix =/usr/local -exec_prefix =${prefix} -libdir =${exec_prefix}/lib -sharedlibdir =${libdir} -includedir =${prefix}/include -mandir =${prefix}/share/man -man3dir = ${mandir}/man3 -pkgconfigdir = ${libdir}/pkgconfig -SRCDIR= -ZINC= -ZINCOUT=-I. - -OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o -OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o -OBJC = $(OBJZ) $(OBJG) - -PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo -PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo -PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) - -# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo -OBJA = -PIC_OBJA = - -OBJS = $(OBJC) $(OBJA) - -PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) - -all: static shared - -static: example$(EXE) minigzip$(EXE) - -shared: examplesh$(EXE) minigzipsh$(EXE) - -all64: example64$(EXE) minigzip64$(EXE) - -check: test - -test: all teststatic testshared - -teststatic: static - @TMPST=tmpst_$$; \ - if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; false; \ - fi; \ - rm -f $$TMPST - -testshared: shared - @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ - DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ - SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ - TMPSH=tmpsh_$$; \ - if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \ - echo ' *** zlib shared test OK ***'; \ - else \ - echo ' *** zlib shared test FAILED ***'; false; \ - fi; \ - rm -f $$TMPSH - -test64: all64 - @TMP64=tmp64_$$; \ - if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \ - echo ' *** zlib 64-bit test OK ***'; \ - else \ - echo ' *** zlib 64-bit test FAILED ***'; false; \ - fi; \ - rm -f $$TMP64 - -infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c - -infcover: infcover.o libz.a - $(CC) $(CFLAGS) -o $@ infcover.o libz.a - -cover: infcover - rm -f *.gcda - ./infcover - gcov inf*.c - -libz.a: $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -match.o: match.S - $(CPP) match.S > _match.s - $(CC) -c _match.s - mv _match.o match.o - rm -f _match.s - -match.lo: match.S - $(CPP) match.S > _match.s - $(CC) -c -fPIC _match.s - mv _match.o match.lo - rm -f _match.s - -example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c - -minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c - -example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c - -minigzip64.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/minigzip.c - - -adler32.o: $(SRCDIR)adler32.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)adler32.c - -crc32.o: $(SRCDIR)crc32.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c - -deflate.o: $(SRCDIR)deflate.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c - -infback.o: $(SRCDIR)infback.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c - -inffast.o: $(SRCDIR)inffast.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inffast.c - -inflate.o: $(SRCDIR)inflate.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inflate.c - -inftrees.o: $(SRCDIR)inftrees.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inftrees.c - -trees.o: $(SRCDIR)trees.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)trees.c - -zutil.o: $(SRCDIR)zutil.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)zutil.c - -compress.o: $(SRCDIR)compress.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)compress.c - -uncompr.o: $(SRCDIR)uncompr.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)uncompr.c - -gzclose.o: $(SRCDIR)gzclose.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzclose.c - -gzlib.o: $(SRCDIR)gzlib.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzlib.c - -gzread.o: $(SRCDIR)gzread.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzread.c - -gzwrite.o: $(SRCDIR)gzwrite.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzwrite.c - - -adler32.lo: $(SRCDIR)adler32.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/adler32.o $(SRCDIR)adler32.c - -@mv objs/adler32.o $@ - -crc32.lo: $(SRCDIR)crc32.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c - -@mv objs/crc32.o $@ - -deflate.lo: $(SRCDIR)deflate.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c - -@mv objs/deflate.o $@ - -infback.lo: $(SRCDIR)infback.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c - -@mv objs/infback.o $@ - -inffast.lo: $(SRCDIR)inffast.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inffast.o $(SRCDIR)inffast.c - -@mv objs/inffast.o $@ - -inflate.lo: $(SRCDIR)inflate.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inflate.o $(SRCDIR)inflate.c - -@mv objs/inflate.o $@ - -inftrees.lo: $(SRCDIR)inftrees.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inftrees.o $(SRCDIR)inftrees.c - -@mv objs/inftrees.o $@ - -trees.lo: $(SRCDIR)trees.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/trees.o $(SRCDIR)trees.c - -@mv objs/trees.o $@ - -zutil.lo: $(SRCDIR)zutil.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/zutil.o $(SRCDIR)zutil.c - -@mv objs/zutil.o $@ - -compress.lo: $(SRCDIR)compress.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/compress.o $(SRCDIR)compress.c - -@mv objs/compress.o $@ - -uncompr.lo: $(SRCDIR)uncompr.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/uncompr.o $(SRCDIR)uncompr.c - -@mv objs/uncompr.o $@ - -gzclose.lo: $(SRCDIR)gzclose.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzclose.o $(SRCDIR)gzclose.c - -@mv objs/gzclose.o $@ - -gzlib.lo: $(SRCDIR)gzlib.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzlib.o $(SRCDIR)gzlib.c - -@mv objs/gzlib.o $@ - -gzread.lo: $(SRCDIR)gzread.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzread.o $(SRCDIR)gzread.c - -@mv objs/gzread.o $@ - -gzwrite.lo: $(SRCDIR)gzwrite.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzwrite.o $(SRCDIR)gzwrite.c - -@mv objs/gzwrite.o $@ - - -placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a - $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) - -@rmdir objs - -example$(EXE): example.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) - -minigzip$(EXE): minigzip.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) - -examplesh$(EXE): example.o $(SHAREDLIBV) - $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV) - -minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) - $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV) - -example64$(EXE): example64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) - -minigzip64$(EXE): minigzip64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) - -install-libs: $(LIBS) - -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi - -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi - -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi - -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi - -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi - cp $(STATICLIB) $(DESTDIR)$(libdir) - chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) - -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1 - -@if test -n "$(SHAREDLIBV)"; then \ - cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \ - echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \ - chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ - echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \ - rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ - ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \ - ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ - ($(LDCONFIG) || true) >/dev/null 2>&1; \ - fi - cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir) - chmod 644 $(DESTDIR)$(man3dir)/zlib.3 - cp zlib.pc $(DESTDIR)$(pkgconfigdir) - chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc -# The ranlib in install is needed on NeXTSTEP which checks file times -# ldconfig is for Linux - -install: install-libs - -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi - cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir) - chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h - -uninstall: - cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h - cd $(DESTDIR)$(libdir) && rm -f libz.a; \ - if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ - fi - cd $(DESTDIR)$(man3dir) && rm -f zlib.3 - cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc - -docs: zlib.3.pdf - -zlib.3.pdf: $(SRCDIR)zlib.3 - groff -mandoc -f H -T ps $(SRCDIR)zlib.3 | ps2pdf - $@ - -zconf.h.cmakein: $(SRCDIR)zconf.h.in - -@ TEMPFILE=zconfh_$$; \ - echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\ - sed -f $$TEMPFILE $(SRCDIR)zconf.h.in > $@ &&\ - touch -r $(SRCDIR)zconf.h.in $@ &&\ - rm $$TEMPFILE - -zconf: $(SRCDIR)zconf.h.in - cp -p $(SRCDIR)zconf.h.in zconf.h - -mostlyclean: clean -clean: - rm -f *.o *.lo *~ \ - example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ - example64$(EXE) minigzip64$(EXE) \ - infcover \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o - rm -rf objs - rm -f *.gcda *.gcno *.gcov - rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov - -maintainer-clean: distclean -distclean: clean zconf zconf.h.cmakein docs - rm -f Makefile zlib.pc configure.log - -@rm -f .DS_Store - @if [ -f Makefile.in ]; then \ - printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ - printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \ - touch -r $(SRCDIR)Makefile.in Makefile ; fi - @if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi - @if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi - -tags: - etags $(SRCDIR)*.[ch] - -adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h -gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h -compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h -crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h -deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h -infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h -inffast.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h -inftrees.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h -trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h - -adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h -gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h -compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h -crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h -deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h -infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h -inffast.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h -inftrees.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h -trees.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h diff --git a/Sources/PerfectCZlib/Makefile.in b/Sources/PerfectCZlib/Makefile.in deleted file mode 100644 index c8b487c2..00000000 --- a/Sources/PerfectCZlib/Makefile.in +++ /dev/null @@ -1,405 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# ./configure; make test -# Normally configure builds both a static and a shared library. -# If you want to build just a static library, use: ./configure --static - -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o - -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: -# make install -# To install in $HOME instead of /usr/local, use: -# make install prefix=$HOME - -CC=cc - -CFLAGS=-O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DZLIB_DEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -SFLAGS=-O -LDFLAGS= -TEST_LDFLAGS=-L. libz.a -LDSHARED=$(CC) -CPP=$(CC) -E - -STATICLIB=libz.a -SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.9 -SHAREDLIBM=libz.so.1 -LIBS=$(STATICLIB) $(SHAREDLIBV) - -AR=ar -ARFLAGS=rc -RANLIB=ranlib -LDCONFIG=ldconfig -LDSHAREDLIBC=-lc -TAR=tar -SHELL=/bin/sh -EXE= - -prefix = /usr/local -exec_prefix = ${prefix} -libdir = ${exec_prefix}/lib -sharedlibdir = ${libdir} -includedir = ${prefix}/include -mandir = ${prefix}/share/man -man3dir = ${mandir}/man3 -pkgconfigdir = ${libdir}/pkgconfig -SRCDIR= -ZINC= -ZINCOUT=-I. - -OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o -OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o -OBJC = $(OBJZ) $(OBJG) - -PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo -PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo -PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) - -# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo -OBJA = -PIC_OBJA = - -OBJS = $(OBJC) $(OBJA) - -PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA) - -all: static shared - -static: example$(EXE) minigzip$(EXE) - -shared: examplesh$(EXE) minigzipsh$(EXE) - -all64: example64$(EXE) minigzip64$(EXE) - -check: test - -test: all teststatic testshared - -teststatic: static - @TMPST=tmpst_$$; \ - if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; false; \ - fi; \ - rm -f $$TMPST - -testshared: shared - @LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ - DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ - SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \ - TMPSH=tmpsh_$$; \ - if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \ - echo ' *** zlib shared test OK ***'; \ - else \ - echo ' *** zlib shared test FAILED ***'; false; \ - fi; \ - rm -f $$TMPSH - -test64: all64 - @TMP64=tmp64_$$; \ - if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \ - echo ' *** zlib 64-bit test OK ***'; \ - else \ - echo ' *** zlib 64-bit test FAILED ***'; false; \ - fi; \ - rm -f $$TMP64 - -infcover.o: $(SRCDIR)test/infcover.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/infcover.c - -infcover: infcover.o libz.a - $(CC) $(CFLAGS) -o $@ infcover.o libz.a - -cover: infcover - rm -f *.gcda - ./infcover - gcov inf*.c - -libz.a: $(OBJS) - $(AR) $(ARFLAGS) $@ $(OBJS) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -match.o: match.S - $(CPP) match.S > _match.s - $(CC) -c _match.s - mv _match.o match.o - rm -f _match.s - -match.lo: match.S - $(CPP) match.S > _match.s - $(CC) -c -fPIC _match.s - mv _match.o match.lo - rm -f _match.s - -example.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/example.c - -minigzip.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -c -o $@ $(SRCDIR)test/minigzip.c - -example64.o: $(SRCDIR)test/example.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/example.c - -minigzip64.o: $(SRCDIR)test/minigzip.c $(SRCDIR)zlib.h zconf.h - $(CC) $(CFLAGS) $(ZINCOUT) -D_FILE_OFFSET_BITS=64 -c -o $@ $(SRCDIR)test/minigzip.c - - -adler32.o: $(SRCDIR)adler32.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)adler32.c - -crc32.o: $(SRCDIR)crc32.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)crc32.c - -deflate.o: $(SRCDIR)deflate.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)deflate.c - -infback.o: $(SRCDIR)infback.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)infback.c - -inffast.o: $(SRCDIR)inffast.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inffast.c - -inflate.o: $(SRCDIR)inflate.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inflate.c - -inftrees.o: $(SRCDIR)inftrees.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)inftrees.c - -trees.o: $(SRCDIR)trees.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)trees.c - -zutil.o: $(SRCDIR)zutil.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)zutil.c - -compress.o: $(SRCDIR)compress.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)compress.c - -uncompr.o: $(SRCDIR)uncompr.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)uncompr.c - -gzclose.o: $(SRCDIR)gzclose.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzclose.c - -gzlib.o: $(SRCDIR)gzlib.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzlib.c - -gzread.o: $(SRCDIR)gzread.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzread.c - -gzwrite.o: $(SRCDIR)gzwrite.c - $(CC) $(CFLAGS) $(ZINC) -c -o $@ $(SRCDIR)gzwrite.c - - -adler32.lo: $(SRCDIR)adler32.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/adler32.o $(SRCDIR)adler32.c - -@mv objs/adler32.o $@ - -crc32.lo: $(SRCDIR)crc32.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/crc32.o $(SRCDIR)crc32.c - -@mv objs/crc32.o $@ - -deflate.lo: $(SRCDIR)deflate.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/deflate.o $(SRCDIR)deflate.c - -@mv objs/deflate.o $@ - -infback.lo: $(SRCDIR)infback.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/infback.o $(SRCDIR)infback.c - -@mv objs/infback.o $@ - -inffast.lo: $(SRCDIR)inffast.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inffast.o $(SRCDIR)inffast.c - -@mv objs/inffast.o $@ - -inflate.lo: $(SRCDIR)inflate.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inflate.o $(SRCDIR)inflate.c - -@mv objs/inflate.o $@ - -inftrees.lo: $(SRCDIR)inftrees.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/inftrees.o $(SRCDIR)inftrees.c - -@mv objs/inftrees.o $@ - -trees.lo: $(SRCDIR)trees.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/trees.o $(SRCDIR)trees.c - -@mv objs/trees.o $@ - -zutil.lo: $(SRCDIR)zutil.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/zutil.o $(SRCDIR)zutil.c - -@mv objs/zutil.o $@ - -compress.lo: $(SRCDIR)compress.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/compress.o $(SRCDIR)compress.c - -@mv objs/compress.o $@ - -uncompr.lo: $(SRCDIR)uncompr.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/uncompr.o $(SRCDIR)uncompr.c - -@mv objs/uncompr.o $@ - -gzclose.lo: $(SRCDIR)gzclose.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzclose.o $(SRCDIR)gzclose.c - -@mv objs/gzclose.o $@ - -gzlib.lo: $(SRCDIR)gzlib.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzlib.o $(SRCDIR)gzlib.c - -@mv objs/gzlib.o $@ - -gzread.lo: $(SRCDIR)gzread.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzread.o $(SRCDIR)gzread.c - -@mv objs/gzread.o $@ - -gzwrite.lo: $(SRCDIR)gzwrite.c - -@mkdir objs 2>/dev/null || test -d objs - $(CC) $(SFLAGS) $(ZINC) -DPIC -c -o objs/gzwrite.o $(SRCDIR)gzwrite.c - -@mv objs/gzwrite.o $@ - - -placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a - $(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) - -@rmdir objs - -example$(EXE): example.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS) - -minigzip$(EXE): minigzip.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS) - -examplesh$(EXE): example.o $(SHAREDLIBV) - $(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV) - -minigzipsh$(EXE): minigzip.o $(SHAREDLIBV) - $(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV) - -example64$(EXE): example64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS) - -minigzip64$(EXE): minigzip64.o $(STATICLIB) - $(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS) - -install-libs: $(LIBS) - -@if [ ! -d $(DESTDIR)$(exec_prefix) ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi - -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi - -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi - -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi - -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi - cp $(STATICLIB) $(DESTDIR)$(libdir) - chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) - -@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1 - -@if test -n "$(SHAREDLIBV)"; then \ - cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \ - echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \ - chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \ - echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \ - rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ - ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \ - ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \ - ($(LDCONFIG) || true) >/dev/null 2>&1; \ - fi - cp $(SRCDIR)zlib.3 $(DESTDIR)$(man3dir) - chmod 644 $(DESTDIR)$(man3dir)/zlib.3 - cp zlib.pc $(DESTDIR)$(pkgconfigdir) - chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc -# The ranlib in install is needed on NeXTSTEP which checks file times -# ldconfig is for Linux - -install: install-libs - -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi - cp $(SRCDIR)zlib.h zconf.h $(DESTDIR)$(includedir) - chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h - -uninstall: - cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h - cd $(DESTDIR)$(libdir) && rm -f libz.a; \ - if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ - fi - cd $(DESTDIR)$(man3dir) && rm -f zlib.3 - cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc - -docs: zlib.3.pdf - -zlib.3.pdf: $(SRCDIR)zlib.3 - groff -mandoc -f H -T ps $(SRCDIR)zlib.3 | ps2pdf - $@ - -zconf.h.cmakein: $(SRCDIR)zconf.h.in - -@ TEMPFILE=zconfh_$$; \ - echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\ - sed -f $$TEMPFILE $(SRCDIR)zconf.h.in > $@ &&\ - touch -r $(SRCDIR)zconf.h.in $@ &&\ - rm $$TEMPFILE - -zconf: $(SRCDIR)zconf.h.in - cp -p $(SRCDIR)zconf.h.in zconf.h - -mostlyclean: clean -clean: - rm -f *.o *.lo *~ \ - example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \ - example64$(EXE) minigzip64$(EXE) \ - infcover \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o - rm -rf objs - rm -f *.gcda *.gcno *.gcov - rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov - -maintainer-clean: distclean -distclean: clean zconf zconf.h.cmakein docs - rm -f Makefile zlib.pc configure.log - -@rm -f .DS_Store - @if [ -f Makefile.in ]; then \ - printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ - printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile ; \ - touch -r $(SRCDIR)Makefile.in Makefile ; fi - @if [ ! -f zconf.h.in ]; then rm -f zconf.h zconf.h.cmakein ; fi - @if [ ! -f zlib.3 ]; then rm -f zlib.3.pdf ; fi - -tags: - etags $(SRCDIR)*.[ch] - -adler32.o zutil.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h -gzclose.o gzlib.o gzread.o gzwrite.o: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h -compress.o example.o minigzip.o uncompr.o: $(SRCDIR)zlib.h zconf.h -crc32.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h -deflate.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h -infback.o inflate.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h -inffast.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h -inftrees.o: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h -trees.o: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h - -adler32.lo zutil.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h -gzclose.lo gzlib.lo gzread.lo gzwrite.lo: $(SRCDIR)zlib.h zconf.h $(SRCDIR)gzguts.h -compress.lo example.lo minigzip.lo uncompr.lo: $(SRCDIR)zlib.h zconf.h -crc32.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)crc32.h -deflate.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h -infback.lo inflate.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h $(SRCDIR)inffixed.h -inffast.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h $(SRCDIR)inflate.h $(SRCDIR)inffast.h -inftrees.lo: $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)inftrees.h -trees.lo: $(SRCDIR)deflate.h $(SRCDIR)zutil.h $(SRCDIR)zlib.h zconf.h $(SRCDIR)trees.h diff --git a/Sources/PerfectCZlib/README b/Sources/PerfectCZlib/README deleted file mode 100644 index 8002f398..00000000 --- a/Sources/PerfectCZlib/README +++ /dev/null @@ -1,115 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.9 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and -rfc1952 (gzip format). - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file test/example.c which also tests that -the library is working correctly. Another example is given in the file -test/minigzip.c. The compression library itself is composed of all source -files in the root directory. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile.in. In short "./configure; make test", and if that goes -well, "make install" should work for most flavors of Unix. For Windows, use -one of the special makefiles in win32/ or contrib/vstudio/ . For VMS, use -make_vms.com. - -Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://zlib.net/ . Before reporting a problem, please check this site to -verify that you have the latest version of zlib; otherwise get the latest -version and check whether the problem still exists or not. - -PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help. - -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available at -http://marknelson.us/1997/01/01/zlib-engine/ . - -The changes made in version 1.2.9 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory contrib/ . - -zlib is available in Java using the java.util.zip package, documented at -http://java.sun.com/developer/technicalArticles/Programming/compression/ . - -A Perl interface to zlib written by Paul Marquess is available -at CPAN (Comprehensive Perl Archive Network) sites, including -http://search.cpan.org/~pmqs/IO-Compress-Zlib/ . - -A Python interface to zlib written by A.M. Kuchling is -available in Python 1.5 and later versions, see -http://docs.python.org/library/zlib.html . - -zlib is built into tcl: http://wiki.tcl.tk/4610 . - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant , is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS or BEOS. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate and - zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; they - are too numerous to cite here. - -Copyright notice: - - (C) 1995-2016 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. diff --git a/Sources/PerfectCZlib/adler32.c b/Sources/PerfectCZlib/adler32.c deleted file mode 100644 index d0be4380..00000000 --- a/Sources/PerfectCZlib/adler32.c +++ /dev/null @@ -1,186 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2011, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); - -#define BASE 65521U /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware -- - try it both ways to see which is faster */ -#ifdef NO_DIVIDE -/* note that this assumes BASE is 65521, where 65536 % 65521 == 15 - (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32_z(adler, buf, len) - uLong adler; - const Bytef *buf; - z_size_t len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - return adler32_z(adler, buf, len); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; - - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/Sources/PerfectCZlib/amiga/Makefile.pup b/Sources/PerfectCZlib/amiga/Makefile.pup deleted file mode 100644 index 8940c120..00000000 --- a/Sources/PerfectCZlib/amiga/Makefile.pup +++ /dev/null @@ -1,69 +0,0 @@ -# Amiga powerUP (TM) Makefile -# makefile for libpng and SAS C V6.58/7.00 PPC compiler -# Copyright (C) 1998 by Andreas R. Kleinert - -LIBNAME = libzip.a - -CC = scppc -CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \ - OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER -AR = ppc-amigaos-ar cr -RANLIB = ppc-amigaos-ranlib -LD = ppc-amigaos-ld -r -LDFLAGS = -o -LDLIBS = LIB:scppc.a LIB:end.o -RM = delete quiet - -OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ - uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o - -TEST_OBJS = example.o minigzip.o - -all: example minigzip - -check: test -test: all - example - echo hello world | minigzip | minigzip -d - -$(LIBNAME): $(OBJS) - $(AR) $@ $(OBJS) - -$(RANLIB) $@ - -example: example.o $(LIBNAME) - $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS) - -minigzip: minigzip.o $(LIBNAME) - $(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS) - -mostlyclean: clean -clean: - $(RM) *.o example minigzip $(LIBNAME) foo.gz - -zip: - zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \ - descrip.mms *.[ch] - -tgz: - cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \ - zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzclose.o: zlib.h zconf.h gzguts.h -gzlib.o: zlib.h zconf.h gzguts.h -gzread.o: zlib.h zconf.h gzguts.h -gzwrite.o: zlib.h zconf.h gzguts.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/Sources/PerfectCZlib/amiga/Makefile.sas b/Sources/PerfectCZlib/amiga/Makefile.sas deleted file mode 100644 index 749e2915..00000000 --- a/Sources/PerfectCZlib/amiga/Makefile.sas +++ /dev/null @@ -1,68 +0,0 @@ -# SMakefile for zlib -# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly -# Osma Ahvenlampi -# Amiga, SAS/C 6.56 & Smake - -CC=sc -CFLAGS=OPT -#CFLAGS=OPT CPU=68030 -#CFLAGS=DEBUG=LINE -LDFLAGS=LIB z.lib - -SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \ - NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \ - DEF=POSTINC - -OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ - uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o - -TEST_OBJS = example.o minigzip.o - -all: SCOPTIONS example minigzip - -check: test -test: all - example - echo hello world | minigzip | minigzip -d - -install: z.lib - copy clone zlib.h zconf.h INCLUDE: - copy clone z.lib LIB: - -z.lib: $(OBJS) - oml z.lib r $(OBJS) - -example: example.o z.lib - $(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS) - -minigzip: minigzip.o z.lib - $(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS) - -mostlyclean: clean -clean: - -delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS - -SCOPTIONS: Makefile.sas - copy to $@ (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = sourceLen > (uLong)max ? max : (uInt)sourceLen; - sourceLen -= stream.avail_in; - } - err = deflate(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); - } while (err == Z_OK); - - *destLen = stream.total_out; - deflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; -} diff --git a/Sources/PerfectCZlib/configure b/Sources/PerfectCZlib/configure deleted file mode 100755 index e974d1fd..00000000 --- a/Sources/PerfectCZlib/configure +++ /dev/null @@ -1,921 +0,0 @@ -#!/bin/sh -# configure script for zlib. -# -# Normally configure builds both a static and a shared library. -# If you want to build just a static library, use: ./configure --static -# -# To impose specific compiler or flags or install directory, use for example: -# prefix=$HOME CC=cc CFLAGS="-O4" ./configure -# or for csh/tcsh users: -# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) - -# Incorrect settings of CC or CFLAGS may prevent creating a shared library. -# If you have problems, try without defining CC and CFLAGS before reporting -# an error. - -# start off configure.log -echo -------------------- >> configure.log -echo $0 $* >> configure.log -date >> configure.log - -# get source directory -SRCDIR=`dirname $0` -if test $SRCDIR = "."; then - ZINC="" - ZINCOUT="-I." - SRCDIR="" -else - ZINC='-include zconf.h' - ZINCOUT='-I. -I$(SRCDIR)' - SRCDIR="$SRCDIR/" -fi - -# set command prefix for cross-compilation -if [ -n "${CHOST}" ]; then - uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`" - CROSS_PREFIX="${CHOST}-" -fi - -# destination name for static library -STATICLIB=libz.a - -# extract zlib version numbers from zlib.h -VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}zlib.h` -VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < ${SRCDIR}zlib.h` -VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h` -VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < ${SRCDIR}zlib.h` - -# establish commands for library building -if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then - AR=${AR-"${CROSS_PREFIX}ar"} - test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log -else - AR=${AR-"ar"} - test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log -fi -ARFLAGS=${ARFLAGS-"rc"} -if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then - RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} - test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log -else - RANLIB=${RANLIB-"ranlib"} -fi -if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then - NM=${NM-"${CROSS_PREFIX}nm"} - test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log -else - NM=${NM-"nm"} -fi - -# set defaults before processing command line options -LDCONFIG=${LDCONFIG-"ldconfig"} -LDSHAREDLIBC="${LDSHAREDLIBC--lc}" -ARCHS= -prefix=${prefix-/usr/local} -exec_prefix=${exec_prefix-'${prefix}'} -libdir=${libdir-'${exec_prefix}/lib'} -sharedlibdir=${sharedlibdir-'${libdir}'} -includedir=${includedir-'${prefix}/include'} -mandir=${mandir-'${prefix}/share/man'} -shared_ext='.so' -shared=1 -solo=0 -cover=0 -zprefix=0 -zconst=0 -build64=0 -gcc=0 -warn=0 -debug=0 -old_cc="$CC" -old_cflags="$CFLAGS" -OBJC='$(OBJZ) $(OBJG)' -PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)' - -# leave this script, optionally in a bad way -leave() -{ - if test "$*" != "0"; then - echo "** $0 aborting." | tee -a configure.log - fi - rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version - echo -------------------- >> configure.log - echo >> configure.log - echo >> configure.log - exit $1 -} - -# process command line options -while test $# -ge 1 -do -case "$1" in - -h* | --help) - echo 'usage:' | tee -a configure.log - echo ' configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log - echo ' [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log - echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log - exit 0 ;; - -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;; - -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;; - -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;; - --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;; - -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;; - -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;; - -p* | --prefix) prefix="$2"; shift; shift ;; - -e* | --eprefix) exec_prefix="$2"; shift; shift ;; - -l* | --libdir) libdir="$2"; shift; shift ;; - -i* | --includedir) includedir="$2"; shift; shift ;; - -s* | --shared | --enable-shared) shared=1; shift ;; - -t | --static) shared=0; shift ;; - --solo) solo=1; shift ;; - --cover) cover=1; shift ;; - -z* | --zprefix) zprefix=1; shift ;; - -6* | --64) build64=1; shift ;; - -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;; - --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; - --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; - -c* | --const) zconst=1; shift ;; - -w* | --warn) warn=1; shift ;; - -d* | --debug) debug=1; shift ;; - *) - echo "unknown option: $1" | tee -a configure.log - echo "$0 --help for help" | tee -a configure.log - leave 1;; - esac -done - -# temporary file name -test=ztest$$ - -# put arguments in log, also put test file in log if used in arguments -show() -{ - case "$*" in - *$test.c*) - echo === $test.c === >> configure.log - cat $test.c >> configure.log - echo === >> configure.log;; - esac - echo $* >> configure.log -} - -# check for gcc vs. cc and set compile and link flags based on the system identified by uname -cat > $test.c <&1` in - *gcc*) gcc=1 ;; - *clang*) gcc=1 ;; -esac - -show $cc -c $test.c -if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then - echo ... using gcc >> configure.log - CC="$cc" - CFLAGS="${CFLAGS--O3}" - SFLAGS="${CFLAGS--O3} -fPIC" - if test "$ARCHS"; then - CFLAGS="${CFLAGS} ${ARCHS}" - LDFLAGS="${LDFLAGS} ${ARCHS}" - fi - if test $build64 -eq 1; then - CFLAGS="${CFLAGS} -m64" - SFLAGS="${SFLAGS} -m64" - fi - if test "$warn" -eq 1; then - if test "$zconst" -eq 1; then - CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST" - else - CFLAGS="${CFLAGS} -Wall -Wextra -pedantic" - fi - fi - if test $debug -eq 1; then - CFLAGS="${CFLAGS} -DZLIB_DEBUG" - SFLAGS="${SFLAGS} -DZLIB_DEBUG" - fi - if test -z "$uname"; then - uname=`(uname -s || echo unknown) 2>/dev/null` - fi - case "$uname" in - Linux* | linux* | GNU | GNU/* | solaris*) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} ;; - *BSD | *bsd* | DragonFly) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,${SRCDIR}zlib.map"} - LDCONFIG="ldconfig -m" ;; - CYGWIN* | Cygwin* | cygwin* | OS/2*) - EXE='.exe' ;; - MINGW* | mingw*) -# temporary bypass - rm -f $test.[co] $test $test$shared_ext - echo "Please use win32/Makefile.gcc instead." | tee -a configure.log - leave 1 - LDSHARED=${LDSHARED-"$cc -shared"} - LDSHAREDLIBC="" - EXE='.exe' ;; - QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 - # (alain.bonnefoy@icbt.com) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;; - HP-UX*) - LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} - case `(uname -m || echo unknown) 2>/dev/null` in - ia64) - shared_ext='.so' - SHAREDLIB='libz.so' ;; - *) - shared_ext='.sl' - SHAREDLIB='libz.sl' ;; - esac ;; - Darwin* | darwin*) - shared_ext='.dylib' - SHAREDLIB=libz$shared_ext - SHAREDLIBV=libz.$VER$shared_ext - SHAREDLIBM=libz.$VER1$shared_ext - LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"} - if libtool -V 2>&1 | grep Apple > /dev/null; then - AR="libtool" - else - AR="/usr/bin/libtool" - fi - ARFLAGS="-o" ;; - *) LDSHARED=${LDSHARED-"$cc -shared"} ;; - esac -else - # find system name and corresponding cc options - CC=${CC-cc} - gcc=0 - echo ... using $CC >> configure.log - if test -z "$uname"; then - uname=`(uname -sr || echo unknown) 2>/dev/null` - fi - case "$uname" in - HP-UX*) SFLAGS=${CFLAGS-"-O +z"} - CFLAGS=${CFLAGS-"-O"} -# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} - LDSHARED=${LDSHARED-"ld -b"} - case `(uname -m || echo unknown) 2>/dev/null` in - ia64) - shared_ext='.so' - SHAREDLIB='libz.so' ;; - *) - shared_ext='.sl' - SHAREDLIB='libz.sl' ;; - esac ;; - IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} - CFLAGS=${CFLAGS-"-ansi -O2"} - LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; - OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} - CFLAGS=${CFLAGS-"-O -std1"} - LDFLAGS="${LDFLAGS} -Wl,-rpath,." - LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;; - OSF1*) SFLAGS=${CFLAGS-"-O -std1"} - CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;; - QNX*) SFLAGS=${CFLAGS-"-4 -O"} - CFLAGS=${CFLAGS-"-4 -O"} - LDSHARED=${LDSHARED-"cc"} - RANLIB=${RANLIB-"true"} - AR="cc" - ARFLAGS="-A" ;; - SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} - CFLAGS=${CFLAGS-"-O3"} - LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;; - SunOS\ 5* | solaris*) - LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"} - SFLAGS=${CFLAGS-"-fast -KPIC"} - CFLAGS=${CFLAGS-"-fast"} - if test $build64 -eq 1; then - # old versions of SunPRO/Workshop/Studio don't support -m64, - # but newer ones do. Check for it. - flag64=`$CC -flags | egrep -- '^-m64'` - if test x"$flag64" != x"" ; then - CFLAGS="${CFLAGS} -m64" - SFLAGS="${SFLAGS} -m64" - else - case `(uname -m || echo unknown) 2>/dev/null` in - i86*) - SFLAGS="$SFLAGS -xarch=amd64" - CFLAGS="$CFLAGS -xarch=amd64" ;; - *) - SFLAGS="$SFLAGS -xarch=v9" - CFLAGS="$CFLAGS -xarch=v9" ;; - esac - fi - fi - if test -n "$ZINC"; then - ZINC='-I- -I. -I$(SRCDIR)' - fi - ;; - SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} - CFLAGS=${CFLAGS-"-O2"} - LDSHARED=${LDSHARED-"ld"} ;; - SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} - CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"} - LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;; - UNIX_System_V\ 4.2.0) - SFLAGS=${CFLAGS-"-KPIC -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"} ;; - UNIX_SV\ 4.2MP) - SFLAGS=${CFLAGS-"-Kconform_pic -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"} ;; - OpenUNIX\ 5) - SFLAGS=${CFLAGS-"-KPIC -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"} ;; - AIX*) # Courtesy of dbakker@arrayasolutions.com - SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - LDSHARED=${LDSHARED-"xlc -G"} ;; - # send working options for other systems to zlib@gzip.org - *) SFLAGS=${CFLAGS-"-O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -shared"} ;; - esac -fi - -# destination names for shared library if not defined above -SHAREDLIB=${SHAREDLIB-"libz$shared_ext"} -SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"} -SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} - -echo >> configure.log - -# define functions for testing compiler and library characteristics and logging the results - -cat > $test.c </dev/null; then - try() - { - show $* - test "`( $* ) 2>&1 | tee -a configure.log`" = "" - } - echo - using any output from compiler to indicate an error >> configure.log -else - try() - { - show $* - ( $* ) >> configure.log 2>&1 - ret=$? - if test $ret -ne 0; then - echo "(exit code "$ret")" >> configure.log - fi - return $ret - } -fi - -tryboth() -{ - show $* - got=`( $* ) 2>&1` - ret=$? - printf %s "$got" >> configure.log - if test $ret -ne 0; then - return $ret - fi - test "$got" = "" -} - -cat > $test.c << EOF -int foo() { return 0; } -EOF -echo "Checking for obsessive-compulsive compiler options..." >> configure.log -if try $CC -c $CFLAGS $test.c; then - : -else - echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log - leave 1 -fi - -echo >> configure.log - -# see if shared library build supported -cat > $test.c <> configure.log - show "$NM $test.o | grep _hello" - if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then - CPP="$CPP -DNO_UNDERLINE" - echo Checking for underline in external names... No. | tee -a configure.log - else - echo Checking for underline in external names... Yes. | tee -a configure.log - fi ;; -esac - -echo >> configure.log - -# check for size_t -cat > $test.c < -#include -size_t dummy = 0; -EOF -if try $CC -c $CFLAGS $test.c; then - echo "Checking for size_t... Yes." | tee -a configure.log - need_sizet=0 -else - echo "Checking for size_t... No." | tee -a configure.log - need_sizet=1 -fi - -echo >> configure.log - -# find the size_t integer type, if needed -if test $need_sizet -eq 1; then - cat > $test.c < $test.c < -int main(void) { - if (sizeof(void *) <= sizeof(int)) puts("int"); - else if (sizeof(void *) <= sizeof(long)) puts("long"); - else puts("z_longlong"); - return 0; -} -EOF - else - echo "Checking for long long... No." | tee -a configure.log - cat > $test.c < -int main(void) { - if (sizeof(void *) <= sizeof(int)) puts("int"); - else puts("long"); - return 0; -} -EOF - fi - if try $CC $CFLAGS -o $test $test.c; then - sizet=`./$test` - echo "Checking for a pointer-size integer type..." $sizet"." | tee -a configure.log - else - echo "Failed to find a pointer-size integer type." | tee -a configure.log - leave 1 - fi -fi - -if test $need_sizet -eq 1; then - CFLAGS="${CFLAGS} -DNO_SIZE_T=${sizet}" - SFLAGS="${SFLAGS} -DNO_SIZE_T=${sizet}" -fi - -echo >> configure.log - -# check for large file support, and if none, check for fseeko() -cat > $test.c < -off64_t dummy = 0; -EOF -if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then - CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" - SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" - ALL="${ALL} all64" - TEST="${TEST} test64" - echo "Checking for off64_t... Yes." | tee -a configure.log - echo "Checking for fseeko... Yes." | tee -a configure.log -else - echo "Checking for off64_t... No." | tee -a configure.log - echo >> configure.log - cat > $test.c < -int main(void) { - fseeko(NULL, 0, 0); - return 0; -} -EOF - if try $CC $CFLAGS -o $test $test.c; then - echo "Checking for fseeko... Yes." | tee -a configure.log - else - CFLAGS="${CFLAGS} -DNO_FSEEKO" - SFLAGS="${SFLAGS} -DNO_FSEEKO" - echo "Checking for fseeko... No." | tee -a configure.log - fi -fi - -echo >> configure.log - -# check for strerror() for use by gz* functions -cat > $test.c < -#include -int main() { return strlen(strerror(errno)); } -EOF -if try $CC $CFLAGS -o $test $test.c; then - echo "Checking for strerror... Yes." | tee -a configure.log -else - CFLAGS="${CFLAGS} -DNO_STRERROR" - SFLAGS="${SFLAGS} -DNO_STRERROR" - echo "Checking for strerror... No." | tee -a configure.log -fi - -# copy clean zconf.h for subsequent edits -cp -p ${SRCDIR}zconf.h.in zconf.h - -echo >> configure.log - -# check for unistd.h and save result in zconf.h -cat > $test.c < -int main() { return 0; } -EOF -if try $CC -c $CFLAGS $test.c; then - sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h - mv zconf.temp.h zconf.h - echo "Checking for unistd.h... Yes." | tee -a configure.log -else - echo "Checking for unistd.h... No." | tee -a configure.log -fi - -echo >> configure.log - -# check for stdarg.h and save result in zconf.h -cat > $test.c < -int main() { return 0; } -EOF -if try $CC -c $CFLAGS $test.c; then - sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h - mv zconf.temp.h zconf.h - echo "Checking for stdarg.h... Yes." | tee -a configure.log -else - echo "Checking for stdarg.h... No." | tee -a configure.log -fi - -# if the z_ prefix was requested, save that in zconf.h -if test $zprefix -eq 1; then - sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h - mv zconf.temp.h zconf.h - echo >> configure.log - echo "Using z_ prefix on all symbols." | tee -a configure.log -fi - -# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists -if test $solo -eq 1; then - sed '/#define ZCONF_H/a\ -#define Z_SOLO - -' < zconf.h > zconf.temp.h - mv zconf.temp.h zconf.h -OBJC='$(OBJZ)' -PIC_OBJC='$(PIC_OBJZ)' -fi - -# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X -if test $cover -eq 1; then - CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage" - if test -n "$GCC_CLASSIC"; then - CC=$GCC_CLASSIC - fi -fi - -echo >> configure.log - -# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions -# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a -# return value. The most secure result is vsnprintf() with a return value. snprintf() with a -# return value is secure as well, but then gzprintf() will be limited to 20 arguments. -cat > $test.c < -#include -#include "zconf.h" -int main() -{ -#ifndef STDC - choke me -#endif - return 0; -} -EOF -if try $CC -c $CFLAGS $test.c; then - echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log - - echo >> configure.log - cat > $test.c < -#include -int mytest(const char *fmt, ...) -{ - char buf[20]; - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return 0; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - if try $CC $CFLAGS -o $test $test.c; then - echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log - - echo >> configure.log - cat >$test.c < -#include -int mytest(const char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return n; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - - if try $CC -c $CFLAGS $test.c; then - echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log - else - CFLAGS="$CFLAGS -DHAS_vsnprintf_void" - SFLAGS="$SFLAGS -DHAS_vsnprintf_void" - echo "Checking for return value of vsnprintf()... No." | tee -a configure.log - echo " WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log - echo " can build but will be open to possible string-format security" | tee -a configure.log - echo " vulnerabilities." | tee -a configure.log - fi - else - CFLAGS="$CFLAGS -DNO_vsnprintf" - SFLAGS="$SFLAGS -DNO_vsnprintf" - echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log - echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log - echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log - echo " vulnerabilities." | tee -a configure.log - - echo >> configure.log - cat >$test.c < -#include -int mytest(const char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - va_start(ap, fmt); - n = vsprintf(buf, fmt, ap); - va_end(ap); - return n; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - - if try $CC -c $CFLAGS $test.c; then - echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log - else - CFLAGS="$CFLAGS -DHAS_vsprintf_void" - SFLAGS="$SFLAGS -DHAS_vsprintf_void" - echo "Checking for return value of vsprintf()... No." | tee -a configure.log - echo " WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log - echo " can build but will be open to possible string-format security" | tee -a configure.log - echo " vulnerabilities." | tee -a configure.log - fi - fi -else - echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log - - echo >> configure.log - cat >$test.c < -int mytest() -{ - char buf[20]; - snprintf(buf, sizeof(buf), "%s", "foo"); - return 0; -} -int main() -{ - return (mytest()); -} -EOF - - if try $CC $CFLAGS -o $test $test.c; then - echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log - - echo >> configure.log - cat >$test.c < -int mytest() -{ - char buf[20]; - return snprintf(buf, sizeof(buf), "%s", "foo"); -} -int main() -{ - return (mytest()); -} -EOF - - if try $CC -c $CFLAGS $test.c; then - echo "Checking for return value of snprintf()... Yes." | tee -a configure.log - else - CFLAGS="$CFLAGS -DHAS_snprintf_void" - SFLAGS="$SFLAGS -DHAS_snprintf_void" - echo "Checking for return value of snprintf()... No." | tee -a configure.log - echo " WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log - echo " can build but will be open to possible string-format security" | tee -a configure.log - echo " vulnerabilities." | tee -a configure.log - fi - else - CFLAGS="$CFLAGS -DNO_snprintf" - SFLAGS="$SFLAGS -DNO_snprintf" - echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log - echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log - echo " can build but will be open to possible buffer-overflow security" | tee -a configure.log - echo " vulnerabilities." | tee -a configure.log - - echo >> configure.log - cat >$test.c < -int mytest() -{ - char buf[20]; - return sprintf(buf, "%s", "foo"); -} -int main() -{ - return (mytest()); -} -EOF - - if try $CC -c $CFLAGS $test.c; then - echo "Checking for return value of sprintf()... Yes." | tee -a configure.log - else - CFLAGS="$CFLAGS -DHAS_sprintf_void" - SFLAGS="$SFLAGS -DHAS_sprintf_void" - echo "Checking for return value of sprintf()... No." | tee -a configure.log - echo " WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log - echo " can build but will be open to possible string-format security" | tee -a configure.log - echo " vulnerabilities." | tee -a configure.log - fi - fi -fi - -# see if we can hide zlib internal symbols that are linked between separate source files -if test "$gcc" -eq 1; then - echo >> configure.log - cat > $test.c <> configure.log -echo ALL = $ALL >> configure.log -echo AR = $AR >> configure.log -echo ARFLAGS = $ARFLAGS >> configure.log -echo CC = $CC >> configure.log -echo CFLAGS = $CFLAGS >> configure.log -echo CPP = $CPP >> configure.log -echo EXE = $EXE >> configure.log -echo LDCONFIG = $LDCONFIG >> configure.log -echo LDFLAGS = $LDFLAGS >> configure.log -echo LDSHARED = $LDSHARED >> configure.log -echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log -echo OBJC = $OBJC >> configure.log -echo PIC_OBJC = $PIC_OBJC >> configure.log -echo RANLIB = $RANLIB >> configure.log -echo SFLAGS = $SFLAGS >> configure.log -echo SHAREDLIB = $SHAREDLIB >> configure.log -echo SHAREDLIBM = $SHAREDLIBM >> configure.log -echo SHAREDLIBV = $SHAREDLIBV >> configure.log -echo STATICLIB = $STATICLIB >> configure.log -echo TEST = $TEST >> configure.log -echo VER = $VER >> configure.log -echo Z_U4 = $Z_U4 >> configure.log -echo SRCDIR = $SRCDIR >> configure.log -echo exec_prefix = $exec_prefix >> configure.log -echo includedir = $includedir >> configure.log -echo libdir = $libdir >> configure.log -echo mandir = $mandir >> configure.log -echo prefix = $prefix >> configure.log -echo sharedlibdir = $sharedlibdir >> configure.log -echo uname = $uname >> configure.log - -# udpate Makefile with the configure results -sed < ${SRCDIR}Makefile.in " -/^CC *=/s#=.*#=$CC# -/^CFLAGS *=/s#=.*#=$CFLAGS# -/^SFLAGS *=/s#=.*#=$SFLAGS# -/^LDFLAGS *=/s#=.*#=$LDFLAGS# -/^LDSHARED *=/s#=.*#=$LDSHARED# -/^CPP *=/s#=.*#=$CPP# -/^STATICLIB *=/s#=.*#=$STATICLIB# -/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# -/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# -/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# -/^AR *=/s#=.*#=$AR# -/^ARFLAGS *=/s#=.*#=$ARFLAGS# -/^RANLIB *=/s#=.*#=$RANLIB# -/^LDCONFIG *=/s#=.*#=$LDCONFIG# -/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# -/^EXE *=/s#=.*#=$EXE# -/^SRCDIR *=/s#=.*#=$SRCDIR# -/^ZINC *=/s#=.*#=$ZINC# -/^ZINCOUT *=/s#=.*#=$ZINCOUT# -/^prefix *=/s#=.*#=$prefix# -/^exec_prefix *=/s#=.*#=$exec_prefix# -/^libdir *=/s#=.*#=$libdir# -/^sharedlibdir *=/s#=.*#=$sharedlibdir# -/^includedir *=/s#=.*#=$includedir# -/^mandir *=/s#=.*#=$mandir# -/^OBJC *=/s#=.*#= $OBJC# -/^PIC_OBJC *=/s#=.*#= $PIC_OBJC# -/^all: */s#:.*#: $ALL# -/^test: */s#:.*#: $TEST# -" > Makefile - -# create zlib.pc with the configure results -sed < ${SRCDIR}zlib.pc.in " -/^CC *=/s#=.*#=$CC# -/^CFLAGS *=/s#=.*#=$CFLAGS# -/^CPP *=/s#=.*#=$CPP# -/^LDSHARED *=/s#=.*#=$LDSHARED# -/^STATICLIB *=/s#=.*#=$STATICLIB# -/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# -/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# -/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# -/^AR *=/s#=.*#=$AR# -/^ARFLAGS *=/s#=.*#=$ARFLAGS# -/^RANLIB *=/s#=.*#=$RANLIB# -/^EXE *=/s#=.*#=$EXE# -/^prefix *=/s#=.*#=$prefix# -/^exec_prefix *=/s#=.*#=$exec_prefix# -/^libdir *=/s#=.*#=$libdir# -/^sharedlibdir *=/s#=.*#=$sharedlibdir# -/^includedir *=/s#=.*#=$includedir# -/^mandir *=/s#=.*#=$mandir# -/^LDFLAGS *=/s#=.*#=$LDFLAGS# -" | sed -e " -s/\@VERSION\@/$VER/g; -" > zlib.pc - -# done -leave 0 diff --git a/Sources/PerfectCZlib/configure.log b/Sources/PerfectCZlib/configure.log deleted file mode 100644 index 238753b1..00000000 --- a/Sources/PerfectCZlib/configure.log +++ /dev/null @@ -1,922 +0,0 @@ --------------------- -./configure -Mon 2 Jan 2017 10:55:56 EST -Checking for gcc... -=== ztest58225.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -c ztest58225.c -... using gcc - -Checking for obsessive-compulsive compiler options... -=== ztest58225.c === -int foo() { return 0; } -=== -gcc -c -O3 ztest58225.c - -Checking for shared library support... -=== ztest58225.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -w -c -O3 -fPIC ztest58225.c -gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -O3 -fPIC -o ztest58225.dylib ztest58225.o -Building shared library libz.1.2.9.dylib with gcc. - -=== ztest58225.c === -#include -#include -size_t dummy = 0; -=== -gcc -c -O3 ztest58225.c -Checking for size_t... Yes. - - -=== ztest58225.c === -#include -off64_t dummy = 0; -=== -gcc -c -O3 -D_LARGEFILE64_SOURCE=1 ztest58225.c -ztest58225.c:2:1: error: unknown type name 'off64_t'; did you mean 'off_t'? -off64_t dummy = 0; -^~~~~~~ -off_t -/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/sys/_types/_off_t.h:30:25: note: 'off_t' declared here -typedef __darwin_off_t off_t; - ^ -1 error generated. -(exit code 1) -Checking for off64_t... No. - -=== ztest58225.c === -#include -int main(void) { - fseeko(NULL, 0, 0); - return 0; -} -=== -gcc -O3 -o ztest58225 ztest58225.c -Checking for fseeko... Yes. - -=== ztest58225.c === -#include -#include -int main() { return strlen(strerror(errno)); } -=== -gcc -O3 -o ztest58225 ztest58225.c -Checking for strerror... Yes. - -=== ztest58225.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest58225.c -Checking for unistd.h... Yes. - -=== ztest58225.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest58225.c -Checking for stdarg.h... Yes. - -=== ztest58225.c === -#include -#include -#include "zconf.h" -int main() -{ -#ifndef STDC - choke me -#endif - return 0; -} -=== -gcc -c -O3 ztest58225.c -Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). - -=== ztest58225.c === -#include -#include -int mytest(const char *fmt, ...) -{ - char buf[20]; - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return 0; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -O3 -o ztest58225 ztest58225.c -Checking for vsnprintf() in stdio.h... Yes. - -=== ztest58225.c === -#include -#include -int mytest(const char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return n; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -c -O3 ztest58225.c -Checking for return value of vsnprintf()... Yes. - -=== ztest58225.c === -#define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -int ZLIB_INTERNAL foo; -int main() -{ - return 0; -} -=== -gcc -c -O3 ztest58225.c -Checking for attribute(visibility) support... Yes. - -ALL = static shared -AR = libtool -ARFLAGS = -o -CC = gcc -CFLAGS = -O3 -DHAVE_HIDDEN -CPP = gcc -E -EXE = -LDCONFIG = ldconfig -LDFLAGS = -LDSHARED = gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -LDSHAREDLIBC = -lc -OBJC = $(OBJZ) $(OBJG) -PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) -RANLIB = ranlib -SFLAGS = -O3 -fPIC -DHAVE_HIDDEN -SHAREDLIB = libz.dylib -SHAREDLIBM = libz.1.dylib -SHAREDLIBV = libz.1.2.9.dylib -STATICLIB = libz.a -TEST = all teststatic testshared -VER = 1.2.9 -Z_U4 = -SRCDIR = -exec_prefix = ${prefix} -includedir = ${prefix}/include -libdir = ${exec_prefix}/lib -mandir = ${prefix}/share/man -prefix = /usr/local -sharedlibdir = ${libdir} -uname = Darwin --------------------- - - --------------------- -./configure -Mon 2 Jan 2017 11:00:21 EST -Checking for gcc... -=== ztest58871.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -c ztest58871.c -... using gcc - -Checking for obsessive-compulsive compiler options... -=== ztest58871.c === -int foo() { return 0; } -=== -gcc -c -O3 ztest58871.c - -Checking for shared library support... -=== ztest58871.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -w -c -O3 -fPIC ztest58871.c -gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -O3 -fPIC -o ztest58871.dylib ztest58871.o -Building shared library libz.1.2.9.dylib with gcc. - -=== ztest58871.c === -#include -#include -size_t dummy = 0; -=== -gcc -c -O3 ztest58871.c -Checking for size_t... Yes. - - -=== ztest58871.c === -#include -off64_t dummy = 0; -=== -gcc -c -O3 -D_LARGEFILE64_SOURCE=1 ztest58871.c -ztest58871.c:2:1: error: unknown type name 'off64_t'; did you mean 'off_t'? -off64_t dummy = 0; -^~~~~~~ -off_t -/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/sys/_types/_off_t.h:30:25: note: 'off_t' declared here -typedef __darwin_off_t off_t; - ^ -1 error generated. -(exit code 1) -Checking for off64_t... No. - -=== ztest58871.c === -#include -int main(void) { - fseeko(NULL, 0, 0); - return 0; -} -=== -gcc -O3 -o ztest58871 ztest58871.c -Checking for fseeko... Yes. - -=== ztest58871.c === -#include -#include -int main() { return strlen(strerror(errno)); } -=== -gcc -O3 -o ztest58871 ztest58871.c -Checking for strerror... Yes. - -=== ztest58871.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest58871.c -Checking for unistd.h... Yes. - -=== ztest58871.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest58871.c -Checking for stdarg.h... Yes. - -=== ztest58871.c === -#include -#include -#include "zconf.h" -int main() -{ -#ifndef STDC - choke me -#endif - return 0; -} -=== -gcc -c -O3 ztest58871.c -Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). - -=== ztest58871.c === -#include -#include -int mytest(const char *fmt, ...) -{ - char buf[20]; - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return 0; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -O3 -o ztest58871 ztest58871.c -Checking for vsnprintf() in stdio.h... Yes. - -=== ztest58871.c === -#include -#include -int mytest(const char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return n; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -c -O3 ztest58871.c -Checking for return value of vsnprintf()... Yes. - -=== ztest58871.c === -#define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -int ZLIB_INTERNAL foo; -int main() -{ - return 0; -} -=== -gcc -c -O3 ztest58871.c -Checking for attribute(visibility) support... Yes. - -ALL = static shared -AR = libtool -ARFLAGS = -o -CC = gcc -CFLAGS = -O3 -DHAVE_HIDDEN -CPP = gcc -E -EXE = -LDCONFIG = ldconfig -LDFLAGS = -LDSHARED = gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -LDSHAREDLIBC = -lc -OBJC = $(OBJZ) $(OBJG) -PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) -RANLIB = ranlib -SFLAGS = -O3 -fPIC -DHAVE_HIDDEN -SHAREDLIB = libz.dylib -SHAREDLIBM = libz.1.dylib -SHAREDLIBV = libz.1.2.9.dylib -STATICLIB = libz.a -TEST = all teststatic testshared -VER = 1.2.9 -Z_U4 = -SRCDIR = -exec_prefix = ${prefix} -includedir = ${prefix}/include -libdir = ${exec_prefix}/lib -mandir = ${prefix}/share/man -prefix = /usr/local -sharedlibdir = ${libdir} -uname = Darwin --------------------- - - --------------------- -./configure -Mon 2 Jan 2017 11:00:38 EST -Checking for gcc... -=== ztest59028.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -c ztest59028.c -... using gcc - -Checking for obsessive-compulsive compiler options... -=== ztest59028.c === -int foo() { return 0; } -=== -gcc -c -O3 ztest59028.c - -Checking for shared library support... -=== ztest59028.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -w -c -O3 -fPIC ztest59028.c -gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -O3 -fPIC -o ztest59028.dylib ztest59028.o -Building shared library libz.1.2.9.dylib with gcc. - -=== ztest59028.c === -#include -#include -size_t dummy = 0; -=== -gcc -c -O3 ztest59028.c -Checking for size_t... Yes. - - -=== ztest59028.c === -#include -off64_t dummy = 0; -=== -gcc -c -O3 -D_LARGEFILE64_SOURCE=1 ztest59028.c -ztest59028.c:2:1: error: unknown type name 'off64_t'; did you mean 'off_t'? -off64_t dummy = 0; -^~~~~~~ -off_t -/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/sys/_types/_off_t.h:30:25: note: 'off_t' declared here -typedef __darwin_off_t off_t; - ^ -1 error generated. -(exit code 1) -Checking for off64_t... No. - -=== ztest59028.c === -#include -int main(void) { - fseeko(NULL, 0, 0); - return 0; -} -=== -gcc -O3 -o ztest59028 ztest59028.c -Checking for fseeko... Yes. - -=== ztest59028.c === -#include -#include -int main() { return strlen(strerror(errno)); } -=== -gcc -O3 -o ztest59028 ztest59028.c -Checking for strerror... Yes. - -=== ztest59028.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest59028.c -Checking for unistd.h... Yes. - -=== ztest59028.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest59028.c -Checking for stdarg.h... Yes. - -=== ztest59028.c === -#include -#include -#include "zconf.h" -int main() -{ -#ifndef STDC - choke me -#endif - return 0; -} -=== -gcc -c -O3 ztest59028.c -Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). - -=== ztest59028.c === -#include -#include -int mytest(const char *fmt, ...) -{ - char buf[20]; - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return 0; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -O3 -o ztest59028 ztest59028.c -Checking for vsnprintf() in stdio.h... Yes. - -=== ztest59028.c === -#include -#include -int mytest(const char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return n; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -c -O3 ztest59028.c -Checking for return value of vsnprintf()... Yes. - -=== ztest59028.c === -#define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -int ZLIB_INTERNAL foo; -int main() -{ - return 0; -} -=== -gcc -c -O3 ztest59028.c -Checking for attribute(visibility) support... Yes. - -ALL = static shared -AR = libtool -ARFLAGS = -o -CC = gcc -CFLAGS = -O3 -DHAVE_HIDDEN -CPP = gcc -E -EXE = -LDCONFIG = ldconfig -LDFLAGS = -LDSHARED = gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -LDSHAREDLIBC = -lc -OBJC = $(OBJZ) $(OBJG) -PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) -RANLIB = ranlib -SFLAGS = -O3 -fPIC -DHAVE_HIDDEN -SHAREDLIB = libz.dylib -SHAREDLIBM = libz.1.dylib -SHAREDLIBV = libz.1.2.9.dylib -STATICLIB = libz.a -TEST = all teststatic testshared -VER = 1.2.9 -Z_U4 = -SRCDIR = -exec_prefix = ${prefix} -includedir = ${prefix}/include -libdir = ${exec_prefix}/lib -mandir = ${prefix}/share/man -prefix = /usr/local -sharedlibdir = ${libdir} -uname = Darwin --------------------- - - --------------------- -./configure --help -Mon 2 Jan 2017 11:01:47 EST -usage: - configure [--const] [--zprefix] [--prefix=PREFIX] [--eprefix=EXPREFIX] - [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR] - [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"] --------------------- -./configure -Mon 2 Jan 2017 11:05:34 EST -Checking for gcc... -=== ztest60536.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -c ztest60536.c -... using gcc - -Checking for obsessive-compulsive compiler options... -=== ztest60536.c === -int foo() { return 0; } -=== -gcc -c -O3 ztest60536.c - -Checking for shared library support... -=== ztest60536.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -w -c -O3 -fPIC ztest60536.c -gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -O3 -fPIC -o ztest60536.dylib ztest60536.o -Building shared library libz.1.2.9.dylib with gcc. - -=== ztest60536.c === -#include -#include -size_t dummy = 0; -=== -gcc -c -O3 ztest60536.c -Checking for size_t... Yes. - - -=== ztest60536.c === -#include -off64_t dummy = 0; -=== -gcc -c -O3 -D_LARGEFILE64_SOURCE=1 ztest60536.c -ztest60536.c:2:1: error: unknown type name 'off64_t'; did you mean 'off_t'? -off64_t dummy = 0; -^~~~~~~ -off_t -/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/sys/_types/_off_t.h:30:25: note: 'off_t' declared here -typedef __darwin_off_t off_t; - ^ -1 error generated. -(exit code 1) -Checking for off64_t... No. - -=== ztest60536.c === -#include -int main(void) { - fseeko(NULL, 0, 0); - return 0; -} -=== -gcc -O3 -o ztest60536 ztest60536.c -Checking for fseeko... Yes. - -=== ztest60536.c === -#include -#include -int main() { return strlen(strerror(errno)); } -=== -gcc -O3 -o ztest60536 ztest60536.c -Checking for strerror... Yes. - -=== ztest60536.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest60536.c -Checking for unistd.h... Yes. - -=== ztest60536.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest60536.c -Checking for stdarg.h... Yes. - -=== ztest60536.c === -#include -#include -#include "zconf.h" -int main() -{ -#ifndef STDC - choke me -#endif - return 0; -} -=== -gcc -c -O3 ztest60536.c -Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). - -=== ztest60536.c === -#include -#include -int mytest(const char *fmt, ...) -{ - char buf[20]; - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return 0; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -O3 -o ztest60536 ztest60536.c -Checking for vsnprintf() in stdio.h... Yes. - -=== ztest60536.c === -#include -#include -int mytest(const char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return n; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -c -O3 ztest60536.c -Checking for return value of vsnprintf()... Yes. - -=== ztest60536.c === -#define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -int ZLIB_INTERNAL foo; -int main() -{ - return 0; -} -=== -gcc -c -O3 ztest60536.c -Checking for attribute(visibility) support... Yes. - -ALL = static shared -AR = libtool -ARFLAGS = -o -CC = gcc -CFLAGS = -O3 -DHAVE_HIDDEN -CPP = gcc -E -EXE = -LDCONFIG = ldconfig -LDFLAGS = -LDSHARED = gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -LDSHAREDLIBC = -lc -OBJC = $(OBJZ) $(OBJG) -PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) -RANLIB = ranlib -SFLAGS = -O3 -fPIC -DHAVE_HIDDEN -SHAREDLIB = libz.dylib -SHAREDLIBM = libz.1.dylib -SHAREDLIBV = libz.1.2.9.dylib -STATICLIB = libz.a -TEST = all teststatic testshared -VER = 1.2.9 -Z_U4 = -SRCDIR = -exec_prefix = ${prefix} -includedir = ${prefix}/include -libdir = ${exec_prefix}/lib -mandir = ${prefix}/share/man -prefix = /usr/local -sharedlibdir = ${libdir} -uname = Darwin --------------------- - - --------------------- -./configure -Mon 2 Jan 2017 11:07:58 EST -Checking for gcc... -=== ztest61497.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -c ztest61497.c -... using gcc - -Checking for obsessive-compulsive compiler options... -=== ztest61497.c === -int foo() { return 0; } -=== -gcc -c -O3 ztest61497.c - -Checking for shared library support... -=== ztest61497.c === -extern int getchar(); -int hello() {return getchar();} -=== -gcc -w -c -O3 -fPIC ztest61497.c -gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -O3 -fPIC -o ztest61497.dylib ztest61497.o -Building shared library libz.1.2.9.dylib with gcc. - -=== ztest61497.c === -#include -#include -size_t dummy = 0; -=== -gcc -c -O3 ztest61497.c -Checking for size_t... Yes. - - -=== ztest61497.c === -#include -off64_t dummy = 0; -=== -gcc -c -O3 -D_LARGEFILE64_SOURCE=1 ztest61497.c -ztest61497.c:2:1: error: unknown type name 'off64_t'; did you mean 'off_t'? -off64_t dummy = 0; -^~~~~~~ -off_t -/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include/sys/_types/_off_t.h:30:25: note: 'off_t' declared here -typedef __darwin_off_t off_t; - ^ -1 error generated. -(exit code 1) -Checking for off64_t... No. - -=== ztest61497.c === -#include -int main(void) { - fseeko(NULL, 0, 0); - return 0; -} -=== -gcc -O3 -o ztest61497 ztest61497.c -Checking for fseeko... Yes. - -=== ztest61497.c === -#include -#include -int main() { return strlen(strerror(errno)); } -=== -gcc -O3 -o ztest61497 ztest61497.c -Checking for strerror... Yes. - -=== ztest61497.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest61497.c -Checking for unistd.h... Yes. - -=== ztest61497.c === -#include -int main() { return 0; } -=== -gcc -c -O3 ztest61497.c -Checking for stdarg.h... Yes. - -=== ztest61497.c === -#include -#include -#include "zconf.h" -int main() -{ -#ifndef STDC - choke me -#endif - return 0; -} -=== -gcc -c -O3 ztest61497.c -Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf(). - -=== ztest61497.c === -#include -#include -int mytest(const char *fmt, ...) -{ - char buf[20]; - va_list ap; - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return 0; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -O3 -o ztest61497 ztest61497.c -Checking for vsnprintf() in stdio.h... Yes. - -=== ztest61497.c === -#include -#include -int mytest(const char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - va_start(ap, fmt); - n = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return n; -} -int main() -{ - return (mytest("Hello%d\n", 1)); -} -=== -gcc -c -O3 ztest61497.c -Checking for return value of vsnprintf()... Yes. - -=== ztest61497.c === -#define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -int ZLIB_INTERNAL foo; -int main() -{ - return 0; -} -=== -gcc -c -O3 ztest61497.c -Checking for attribute(visibility) support... Yes. - -ALL = static shared -AR = libtool -ARFLAGS = -o -CC = gcc -CFLAGS = -O3 -DHAVE_HIDDEN -CPP = gcc -E -EXE = -LDCONFIG = ldconfig -LDFLAGS = -LDSHARED = gcc -dynamiclib -install_name ${exec_prefix}/lib/libz.1.dylib -compatibility_version 1 -current_version 1.2.9 -LDSHAREDLIBC = -lc -OBJC = $(OBJZ) $(OBJG) -PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) -RANLIB = ranlib -SFLAGS = -O3 -fPIC -DHAVE_HIDDEN -SHAREDLIB = libz.dylib -SHAREDLIBM = libz.1.dylib -SHAREDLIBV = libz.1.2.9.dylib -STATICLIB = libz.a -TEST = all teststatic testshared -VER = 1.2.9 -Z_U4 = -SRCDIR = -exec_prefix = ${prefix} -includedir = ${prefix}/include -libdir = ${exec_prefix}/lib -mandir = ${prefix}/share/man -prefix = /usr/local -sharedlibdir = ${libdir} -uname = Darwin --------------------- - - diff --git a/Sources/PerfectCZlib/crc32.c b/Sources/PerfectCZlib/crc32.c deleted file mode 100644 index 9580440c..00000000 --- a/Sources/PerfectCZlib/crc32.c +++ /dev/null @@ -1,442 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - - DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h. - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -/* Definitions for doing the crc four data bytes at a time. */ -#if !defined(NOBYFOUR) && defined(Z_U4) -# define BYFOUR -#endif -#ifdef BYFOUR - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, z_size_t)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, z_size_t)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); - - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local z_crc_t FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - z_crc_t c; - int n, k; - z_crc_t poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0; - for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) - poly |= (z_crc_t)1 << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (z_crc_t)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = ZSWAP32(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = ZSWAP32(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const z_crc_t FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const z_crc_t FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const z_crc_t FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32_z(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - z_crc_t endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - return crc32_z(crc, buf, len); -} - -#ifdef BYFOUR - -/* - This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit - integer pointer type. This violates the strict aliasing rule, where a - compiler can assume, for optimization purposes, that two pointers to - fundamentally different types won't ever point to the same memory. This can - manifest as a problem only if one of the pointers is written to. This code - only reads from those pointers. So long as this code remains isolated in - this compilation unit, there won't be a problem. For this reason, this code - should not be copied and pasted into a compilation unit in which other code - writes to the buffer that is passed to these routines. - */ - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = (z_crc_t)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *buf4++; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - z_size_t len; -{ - register z_crc_t c; - register const z_crc_t FAR *buf4; - - c = ZSWAP32((z_crc_t)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(ZSWAP32(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} - -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} diff --git a/Sources/PerfectCZlib/crc32.h b/Sources/PerfectCZlib/crc32.h deleted file mode 100644 index 9e0c7781..00000000 --- a/Sources/PerfectCZlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const z_crc_t FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/Sources/PerfectCZlib/deflate.c b/Sources/PerfectCZlib/deflate.c deleted file mode 100644 index a44d5baa..00000000 --- a/Sources/PerfectCZlib/deflate.c +++ /dev/null @@ -1,2157 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://tools.ietf.org/html/rfc1951 - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.9 Copyright 1995-2016 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local int deflateStateCheck OF((z_streamp strm)); -local void slide_hash OF((deflate_state *s)); -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local unsigned read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef ZLIB_DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ -#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to UPDATE_HASH are made with consecutive input - * characters, so that a running hash key can be computed from the previous - * key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to INSERT_STRING are made with consecutive input - * characters and the first MIN_MATCH bytes of str are valid (except for - * the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* =========================================================================== - * Slide the hash table when sliding the window down (could be avoided with 32 - * bit values at the expense of memory usage). We slide even when level == 0 to - * keep the hash table consistent if we switch back to level > 0 later. - */ -local void slide_hash(s) - deflate_state *s; -{ - unsigned n, m; - Posf *p; - uInt wsize = s->w_size; - - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - } while (--n); - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m - wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif -} - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED || (windowBits == 8 && wrap != 1)) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - s->status = INIT_STATE; /* to pass state test in deflateReset() */ - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = (uInt)windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = (uInt)memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= - * Check for a valid deflate stream state. Return 0 if ok, 1 if not. - */ -local int deflateStateCheck (strm) - z_streamp strm; -{ - deflate_state *s; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - s = strm->state; - if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE && -#ifdef GZIP - s->status != GZIP_STATE && -#endif - s->status != EXTRA_STATE && - s->status != NAME_STATE && - s->status != COMMENT_STATE && - s->status != HCRC_STATE && - s->status != BUSY_STATE && - s->status != FINISH_STATE)) - return 1; - return 0; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - z_const unsigned char *next; - - if (deflateStateCheck(strm) || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; - - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } - - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (z_const Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateGetDictionary (strm, dictionary, dictLength) - z_streamp strm; - Bytef *dictionary; - uInt *dictLength; -{ - deflate_state *s; - uInt len; - - if (deflateStateCheck(strm)) - return Z_STREAM_ERROR; - s = strm->state; - len = s->strstart + s->lookahead; - if (len > s->w_size) - len = s->w_size; - if (dictionary != Z_NULL && len) - zmemcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); - if (dictLength != Z_NULL) - *dictLength = len; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateResetKeep (strm) - z_streamp strm; -{ - deflate_state *s; - - if (deflateStateCheck(strm)) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = -#ifdef GZIP - s->wrap == 2 ? GZIP_STATE : -#endif - s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - int ret; - - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (deflateStateCheck(strm) || strm->state->wrap != 2) - return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePending (strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; -{ - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - deflate_state *s; - int put; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func)) { - /* Flush the last buffer: */ - int err = deflate(strm, Z_BLOCK); - if (err == Z_STREAM_ERROR) - return err; - if (strm->avail_out == 0) - return Z_BUF_ERROR; - } - if (s->level != level) { - if (s->level == 0 && s->matches != 0) { - if (s->matches == 1) - slide_hash(s); - else - CLEAR_HASH(s); - s->matches = 0; - } - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = (uInt)good_length; - s->max_lazy_match = (uInt)max_lazy; - s->nice_match = nice_length; - s->max_chain_length = (uInt)max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (deflateStateCheck(strm)) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; -#ifdef GZIP - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - Bytef *str; - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; -#endif - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output, except for - * some deflate_stored() output, goes through this function so some - * applications may wish to modify it to avoid allocating a large - * strm->next_out buffer and copying into it. (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len; - deflate_state *s = strm->state; - - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } -} - -/* =========================================================================== - * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. - */ -#define HCRC_UPDATE(beg) \ - do { \ - if (s->gzhead->hcrc && s->pending > (beg)) \ - strm->adler = crc32(strm->adler, s->pending_buf + (beg), \ - s->pending - (beg)); \ - } while (0) - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->avail_in != 0 && strm->next_in == Z_NULL) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - old_flush = s->last_flush; - s->last_flush = flush; - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Write the header */ - if (s->status == INIT_STATE) { - /* zlib header */ - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#ifdef GZIP - if (s->status == GZIP_STATE) { - /* gzip header */ - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - uInt left = (s->gzhead->extra_len & 0xffff) - s->gzindex; - while (s->pending + left > s->pending_buf_size) { - uInt copy = s->pending_buf_size - s->pending; - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, copy); - s->pending = s->pending_buf_size; - HCRC_UPDATE(beg); - s->gzindex += copy; - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - left -= copy; - } - zmemcpy(s->pending_buf + s->pending, - s->gzhead->extra + s->gzindex, left); - s->pending += left; - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - s->gzindex = 0; - } - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - ulg beg = s->pending; /* start of bytes to update crc */ - int val; - do { - if (s->pending == s->pending_buf_size) { - HCRC_UPDATE(beg); - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - beg = 0; - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - HCRC_UPDATE(beg); - } - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) { - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - } - s->status = BUSY_STATE; - - /* Compression must start with an empty pending buffer */ - flush_pending(strm); - if (s->pending != 0) { - s->last_flush = -1; - return Z_OK; - } - } -#endif - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->level == 0 ? deflate_stored(s, flush) : - s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (deflateStateCheck(strm)) return Z_STREAM_ERROR; - - status = strm->state->status; - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (deflateStateCheck(source) || dest == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local unsigned read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } -#endif - strm->next_in += len; - strm->total_in += len; - - return len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = (int)s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = (int)s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef ZLIB_DEBUG - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* ZLIB_DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - unsigned n; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize - more); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - slide_hash(s); - more += wsize; - } - if (s->strm->avail_in == 0) break; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); -#ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; -#endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } - - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* Maximum stored block length in deflate format (not including header). */ -#define MAX_STORED 65535 - -/* Minimum of a and b. */ -#define MIN(a, b) ((a) > (b) ? (b) : (a)) - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * - * In case deflateParams() is used to later switch to a non-zero compression - * level, s->matches (otherwise unused when storing) keeps track of the number - * of hash table slides to perform. If s->matches is 1, then one hash table - * slide will be done when switching. If s->matches is 2, the maximum value - * allowed here, then the hash table will be cleared, since two or more slides - * is the same as a clear. - * - * deflate_stored() is written to minimize the number of times an input byte is - * copied. It is most efficient with large input and output buffers, which - * maximizes the opportunites to have a single copy from next_in to next_out. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Smallest worthy block size when not flushing or finishing. By default - * this is 32K. This can be as small as 507 bytes for memLevel == 1. For - * large input and output buffers, the stored block size will be larger. - */ - unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); - - /* Copy as many min_block or larger stored blocks directly to next_out as - * possible. If flushing, copy the remaining available input to next_out as - * stored blocks, if there is enough space. - */ - unsigned len, left, have, last; - unsigned used = s->strm->avail_in; - for (;;) { - /* Set len to the maximum size block that we can copy directly with the - * available input data and output space. Set left to how much of that - * would be copied from what's left in the window. - */ - len = MAX_STORED; /* maximum deflate stored block length */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in avail_out: */ - have = s->strm->avail_out > have ? s->strm->avail_out - have : 0; - left = s->strstart - s->block_start; /* bytes left in window */ - if (len > (ulg)left + s->strm->avail_in) - len = left + s->strm->avail_in; /* limit len to the input */ - if (len > have) - len = have; /* limit len to the output */ - if (left > len) - left = len; /* limit window pull to len */ - - /* If the stored block would be less than min_block in length, or if - * unable to copy all of the available input when flushing, then try - * copying to the window and the pending buffer instead. Also don't - * write an empty block when flushing -- deflate() does that. - */ - if (len < min_block && (len == 0 || flush == Z_NO_FLUSH || - len - left != s->strm->avail_in)) - break; - - /* Make a dummy stored block in pending to get the header bytes, - * including any pending bits. This also updates the debugging counts. - */ - last = flush == Z_FINISH && len - left == s->strm->avail_in ? 1 : 0; - _tr_stored_block(s, (char *)0, 0L, last); - - /* Replace the lengths in the dummy stored block with len. */ - s->pending_buf[s->pending - 4] = len; - s->pending_buf[s->pending - 3] = len >> 8; - s->pending_buf[s->pending - 2] = ~len; - s->pending_buf[s->pending - 1] = ~len >> 8; - - /* Write the stored block header bytes. */ - flush_pending(s->strm); - - /* Update debugging counts for the data about to be copied. */ -#ifdef ZLIB_DEBUG - s->compressed_len += len << 3; - s->bits_sent += len << 3; -#endif - - /* Copy uncompressed bytes from the window to next_out. */ - if (left) { - zmemcpy(s->strm->next_out, s->window + s->block_start, left); - s->strm->next_out += left; - s->strm->avail_out -= left; - s->strm->total_out += left; - s->block_start += left; - len -= left; - } - - /* Copy uncompressed bytes directly from next_in to next_out, updating - * the check value. - */ - if (len) { - read_buf(s->strm, s->strm->next_out, len); - s->strm->next_out += len; - s->strm->avail_out -= len; - s->strm->total_out += len; - } - } - - /* Update the sliding window with the last s->w_size bytes of the copied - * data, or append all of the copied data to the existing window if less - * than s->w_size bytes were copied. Also update the number of bytes to - * insert in the hash tables, in the event that deflateParams() switches to - * a non-zero compression level. - */ - used -= s->strm->avail_in; /* number of input bytes directly copied */ - if (used) { - /* If any input was used, then no unused input remains in the window, - * therefore s->block_start == s->strstart. - */ - if (used >= s->w_size) { /* supplant the previous history */ - s->matches = 2; /* clear hash */ - zmemcpy(s->window, s->strm->next_in - s->w_size, s->w_size); - s->strstart = s->w_size; - } - else { - if (s->window_size - s->strstart <= used) { - /* Slide the window down. */ - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - } - zmemcpy(s->window + s->strstart, s->strm->next_in - used, used); - s->strstart += used; - } - s->block_start = s->strstart; - s->insert += MIN(used, s->w_size - s->insert); - } - - /* If flushing or finishing and all input has been consumed, then done. If - * the code above couldn't write a complete block to next_out, then the - * code following this won't be able to either. - */ - if (flush != Z_NO_FLUSH && s->strm->avail_in == 0 && - (long)s->strstart == s->block_start) - return flush == Z_FINISH ? finish_done : block_done; - - /* Fill the window with any remaining input. */ - have = s->window_size - s->strstart - 1; - if (s->strm->avail_in > have && s->block_start >= (long)s->w_size) { - /* Slide the window down. */ - s->block_start -= s->w_size; - s->strstart -= s->w_size; - zmemcpy(s->window, s->window + s->w_size, s->strstart); - if (s->matches < 2) - s->matches++; /* add a pending slide_hash() */ - have += s->w_size; /* more space now */ - } - if (have > s->strm->avail_in) - have = s->strm->avail_in; - if (have) { - read_buf(s->strm, s->window + s->strstart, have); - s->strstart += have; - } - - /* There was not enough avail_out to write a complete worthy or flushed - * stored block to next_out. Write a stored block to pending instead, if we - * have enough input for a worthy block, or if flushing and there is enough - * room for the remaining input as a stored block in the pending buffer. - */ - have = (s->bi_valid + 42) >> 3; /* number of header bytes */ - /* maximum stored block length that will fit in pending: */ - have = MIN(s->pending_buf_size - have, MAX_STORED); - min_block = MIN(have, s->w_size); - left = s->strstart - s->block_start; - if (left >= min_block || - (left && flush != Z_NO_FLUSH && s->strm->avail_in == 0 && - left <= have)) { - len = MIN(left, have); - last = flush == Z_FINISH && s->strm->avail_in == 0 && - len == left ? 1 : 0; - _tr_stored_block(s, (charf *)s->window + s->block_start, len, last); - s->block_start += len; - flush_pending(s->strm); - if (last) - return finish_started; - } - - /* We've done all we can with the available input and output. */ - return need_more; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest run, plus one for the unrolled loop. - */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (uInt)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; -} diff --git a/Sources/PerfectCZlib/deflate.h b/Sources/PerfectCZlib/deflate.h deleted file mode 100644 index 23ecdd31..00000000 --- a/Sources/PerfectCZlib/deflate.h +++ /dev/null @@ -1,349 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2016 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define Buf_size 16 -/* size of bit buffer in bi_buf */ - -#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ -#ifdef GZIP -# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ -#endif -#define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ -#define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ -#define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ -#define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ -#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ -#define FINISH_STATE 666 /* stream complete */ -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - const static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - ulg pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - ulg gzindex; /* where in extra, name, or comment */ - Byte method; /* can only be DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ - -#ifdef ZLIB_DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (Bytef)(c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef ZLIB_DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/Sources/PerfectCZlib/doc/algorithm.txt b/Sources/PerfectCZlib/doc/algorithm.txt deleted file mode 100644 index c97f4950..00000000 --- a/Sources/PerfectCZlib/doc/algorithm.txt +++ /dev/null @@ -1,209 +0,0 @@ -1. Compression algorithm (deflate) - -The deflation algorithm used by gzip (also zip and zlib) is a variation of -LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in -the input data. The second occurrence of a string is replaced by a -pointer to the previous string, in the form of a pair (distance, -length). Distances are limited to 32K bytes, and lengths are limited -to 258 bytes. When a string does not occur anywhere in the previous -32K bytes, it is emitted as a sequence of literal bytes. (In this -description, `string' must be taken as an arbitrary sequence of bytes, -and is not restricted to printable characters.) - -Literals or match lengths are compressed with one Huffman tree, and -match distances are compressed with another tree. The trees are stored -in a compact form at the start of each block. The blocks can have any -size (except that the compressed data for one block must fit in -available memory). A block is terminated when deflate() determines that -it would be useful to start another block with fresh trees. (This is -somewhat similar to the behavior of LZW-based _compress_.) - -Duplicated strings are found using a hash table. All input strings of -length 3 are inserted in the hash table. A hash index is computed for -the next 3 bytes. If the hash chain for this index is not empty, all -strings in the chain are compared with the current input string, and -the longest match is selected. - -The hash chains are searched starting with the most recent strings, to -favor small distances and thus take advantage of the Huffman encoding. -The hash chains are singly linked. There are no deletions from the -hash chains, the algorithm simply discards matches that are too old. - -To avoid a worst-case situation, very long hash chains are arbitrarily -truncated at a certain length, determined by a runtime option (level -parameter of deflateInit). So deflate() does not always find the longest -possible match but generally finds a match which is long enough. - -deflate() also defers the selection of matches with a lazy evaluation -mechanism. After a match of length N has been found, deflate() searches for -a longer match at the next input byte. If a longer match is found, the -previous match is truncated to a length of one (thus producing a single -literal byte) and the process of lazy evaluation begins again. Otherwise, -the original match is kept, and the next match search is attempted only N -steps later. - -The lazy match evaluation is also subject to a runtime parameter. If -the current match is long enough, deflate() reduces the search for a longer -match, thus speeding up the whole process. If compression ratio is more -important than speed, deflate() attempts a complete second search even if -the first match is already long enough. - -The lazy match evaluation is not performed for the fastest compression -modes (level parameter 1 to 3). For these fast modes, new strings -are inserted in the hash table only when no match was found, or -when the match is not too long. This degrades the compression ratio -but saves time since there are both fewer insertions and fewer searches. - - -2. Decompression algorithm (inflate) - -2.1 Introduction - -The key question is how to represent a Huffman code (or any prefix code) so -that you can decode fast. The most important characteristic is that shorter -codes are much more common than longer codes, so pay attention to decoding the -short codes fast, and let the long codes take longer to decode. - -inflate() sets up a first level table that covers some number of bits of -input less than the length of longest code. It gets that many bits from the -stream, and looks it up in the table. The table will tell if the next -code is that many bits or less and how many, and if it is, it will tell -the value, else it will point to the next level table for which inflate() -grabs more bits and tries to decode a longer code. - -How many bits to make the first lookup is a tradeoff between the time it -takes to decode and the time it takes to build the table. If building the -table took no time (and if you had infinite memory), then there would only -be a first level table to cover all the way to the longest code. However, -building the table ends up taking a lot longer for more bits since short -codes are replicated many times in such a table. What inflate() does is -simply to make the number of bits in the first table a variable, and then -to set that variable for the maximum speed. - -For inflate, which has 286 possible codes for the literal/length tree, the size -of the first table is nine bits. Also the distance trees have 30 possible -values, and the size of the first table is six bits. Note that for each of -those cases, the table ended up one bit longer than the ``average'' code -length, i.e. the code length of an approximately flat code which would be a -little more than eight bits for 286 symbols and a little less than five bits -for 30 symbols. - - -2.2 More details on the inflate table lookup - -Ok, you want to know what this cleverly obfuscated inflate tree actually -looks like. You are correct that it's not a Huffman tree. It is simply a -lookup table for the first, let's say, nine bits of a Huffman symbol. The -symbol could be as short as one bit or as long as 15 bits. If a particular -symbol is shorter than nine bits, then that symbol's translation is duplicated -in all those entries that start with that symbol's bits. For example, if the -symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a -symbol is nine bits long, it appears in the table once. - -If the symbol is longer than nine bits, then that entry in the table points -to another similar table for the remaining bits. Again, there are duplicated -entries as needed. The idea is that most of the time the symbol will be short -and there will only be one table look up. (That's whole idea behind data -compression in the first place.) For the less frequent long symbols, there -will be two lookups. If you had a compression method with really long -symbols, you could have as many levels of lookups as is efficient. For -inflate, two is enough. - -So a table entry either points to another table (in which case nine bits in -the above example are gobbled), or it contains the translation for the symbol -and the number of bits to gobble. Then you start again with the next -ungobbled bit. - -You may wonder: why not just have one lookup table for how ever many bits the -longest symbol is? The reason is that if you do that, you end up spending -more time filling in duplicate symbol entries than you do actually decoding. -At least for deflate's output that generates new trees every several 10's of -kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code -would take too long if you're only decoding several thousand symbols. At the -other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend too much time -traversing the tree while decoding, even for short symbols. - -So the number of bits for the first lookup table is a trade of the time to -fill out the table vs. the time spent looking at the second level and above of -the table. - -Here is an example, scaled down: - -The code being decoded, with 10 symbols, from 1 to 6 bits long: - -A: 0 -B: 10 -C: 1100 -D: 11010 -E: 11011 -F: 11100 -G: 11101 -H: 11110 -I: 111110 -J: 111111 - -Let's make the first table three bits long (eight entries): - -000: A,1 -001: A,1 -010: A,1 -011: A,1 -100: B,2 -101: B,2 -110: -> table X (gobble 3 bits) -111: -> table Y (gobble 3 bits) - -Each entry is what the bits decode as and how many bits that is, i.e. how -many bits to gobble. Or the entry points to another table, with the number of -bits to gobble implicit in the size of the table. - -Table X is two bits long since the longest code starting with 110 is five bits -long: - -00: C,1 -01: C,1 -10: D,2 -11: E,2 - -Table Y is three bits long since the longest code starting with 111 is six -bits long: - -000: F,2 -001: F,2 -010: G,2 -011: G,2 -100: H,2 -101: H,2 -110: I,3 -111: J,3 - -So what we have here are three tables with a total of 20 entries that had to -be constructed. That's compared to 64 entries for a single table. Or -compared to 16 entries for a Huffman tree (six two entry tables and one four -entry table). Assuming that the code ideally represents the probability of -the symbols, it takes on the average 1.25 lookups per symbol. That's compared -to one lookup for the single table, or 1.66 lookups per symbol for the -Huffman tree. - -There, I think that gives you a picture of what's going on. For inflate, the -meaning of a particular symbol is often more than just a letter. It can be a -byte (a "literal"), or it can be either a length or a distance which -indicates a base value and a number of bits to fetch after the code that is -added to the base value. Or it might be the special end-of-block code. The -data structures created in inftrees.c try to encode all that information -compactly in the tables. - - -Jean-loup Gailly Mark Adler -jloup@gzip.org madler@alumni.caltech.edu - - -References: - -[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data -Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, -pp. 337-343. - -``DEFLATE Compressed Data Format Specification'' available in -http://tools.ietf.org/html/rfc1951 diff --git a/Sources/PerfectCZlib/doc/rfc1950.txt b/Sources/PerfectCZlib/doc/rfc1950.txt deleted file mode 100644 index ce6428a0..00000000 --- a/Sources/PerfectCZlib/doc/rfc1950.txt +++ /dev/null @@ -1,619 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1950 Aladdin Enterprises -Category: Informational J-L. Gailly - Info-ZIP - May 1996 - - - ZLIB Compressed Data Format Specification version 3.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format. The - data can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a priori - bounded amount of intermediate storage. The format presently uses - the DEFLATE compression method but can be easily extended to use - other compression methods. It can be implemented readily in a manner - not covered by patents. This specification also defines the ADLER-32 - checksum (an extension and improvement of the Fletcher checksum), - used for detection of data corruption, and provides an algorithm for - computing it. - - - - -Deutsch & Gailly Informational [Page 1] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................ 3 - 1.6. Changes from previous versions ............................ 3 - 2. Detailed specification ......................................... 3 - 2.1. Overall conventions ....................................... 3 - 2.2. Data format ............................................... 4 - 2.3. Compliance ................................................ 7 - 3. References ..................................................... 7 - 4. Source code .................................................... 8 - 5. Security Considerations ........................................ 8 - 6. Acknowledgements ............................................... 8 - 7. Authors' Addresses ............................................. 8 - 8. Appendix: Rationale ............................................ 9 - 9. Appendix: Sample code ..........................................10 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - - * Can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a - priori bounded amount of intermediate storage, and hence can - be used in data communications or similar structures such as - Unix filters; - - * Can use a number of different compression methods; - - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely. - - The data format defined by this specification does not attempt to - allow random access to compressed data. - - - - - - - -Deutsch & Gailly Informational [Page 2] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into zlib format and/or decompress data from zlib - format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. - - 1.3. Scope - - The specification specifies a compressed data format that can be - used for in-memory compression of a sequence of arbitrary bytes. - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any data set that conforms to all - the specifications presented here; a compliant compressor must - produce data sets that conform to all the specifications presented - here. - - 1.5. Definitions of terms and conventions used - - byte: 8 bits stored or transmitted as a unit (same as an octet). - (For this specification, a byte is exactly 8 bits, even on - machines which store a character on a number of bits different - from 8.) See below, for the numbering of bits within a byte. - - 1.6. Changes from previous versions - - Version 3.1 was the first public release of this specification. - In version 3.2, some terminology was changed and the Adler-32 - sample code was rewritten for clarity. In version 3.3, the - support for a preset dictionary was introduced, and the - specification was converted to RFC style. - -2. Detailed specification - - 2.1. Overall conventions - - In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - - - -Deutsch & Gailly Informational [Page 3] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the MOST-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00000010|00001000| - +--------+--------+ - ^ ^ - | | - | + less significant byte = 8 - + more significant byte = 2 x 256 - - 2.2. Data format - - A zlib stream has the following structure: - - 0 1 - +---+---+ - |CMF|FLG| (more-->) - +---+---+ - - - - - - - - -Deutsch & Gailly Informational [Page 4] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - (if FLG.FDICT set) - - 0 1 2 3 - +---+---+---+---+ - | DICTID | (more-->) - +---+---+---+---+ - - +=====================+---+---+---+---+ - |...compressed data...| ADLER32 | - +=====================+---+---+---+---+ - - Any data which may appear after ADLER32 are not part of the zlib - stream. - - CMF (Compression Method and flags) - This byte is divided into a 4-bit compression method and a 4- - bit information field depending on the compression method. - - bits 0 to 3 CM Compression method - bits 4 to 7 CINFO Compression info - - CM (Compression method) - This identifies the compression method used in the file. CM = 8 - denotes the "deflate" compression method with a window size up - to 32K. This is the method used by gzip and PNG (see - references [1] and [2] in Chapter 3, below, for the reference - documents). CM = 15 is reserved. It might be used in a future - version of this specification to indicate the presence of an - extra field before the compressed data. - - CINFO (Compression info) - For CM = 8, CINFO is the base-2 logarithm of the LZ77 window - size, minus eight (CINFO=7 indicates a 32K window size). Values - of CINFO above 7 are not allowed in this version of the - specification. CINFO is not defined in this specification for - CM not equal to 8. - - FLG (FLaGs) - This flag byte is divided as follows: - - bits 0 to 4 FCHECK (check bits for CMF and FLG) - bit 5 FDICT (preset dictionary) - bits 6 to 7 FLEVEL (compression level) - - The FCHECK value must be such that CMF and FLG, when viewed as - a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), - is a multiple of 31. - - - - -Deutsch & Gailly Informational [Page 5] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - FDICT (Preset dictionary) - If FDICT is set, a DICT dictionary identifier is present - immediately after the FLG byte. The dictionary is a sequence of - bytes which are initially fed to the compressor without - producing any compressed output. DICT is the Adler-32 checksum - of this sequence of bytes (see the definition of ADLER32 - below). The decompressor can use this identifier to determine - which dictionary has been used by the compressor. - - FLEVEL (Compression level) - These flags are available for use by specific compression - methods. The "deflate" method (CM = 8) sets these flags as - follows: - - 0 - compressor used fastest algorithm - 1 - compressor used fast algorithm - 2 - compressor used default algorithm - 3 - compressor used maximum compression, slowest algorithm - - The information in FLEVEL is not needed for decompression; it - is there to indicate if recompression might be worthwhile. - - compressed data - For compression method 8, the compressed data is stored in the - deflate compressed data format as described in the document - "DEFLATE Compressed Data Format Specification" by L. Peter - Deutsch. (See reference [3] in Chapter 3, below) - - Other compressed data formats are not specified in this version - of the zlib specification. - - ADLER32 (Adler-32 checksum) - This contains a checksum value of the uncompressed data - (excluding any dictionary data) computed according to Adler-32 - algorithm. This algorithm is a 32-bit extension and improvement - of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 - standard. See references [4] and [5] in Chapter 3, below) - - Adler-32 is composed of two sums accumulated per byte: s1 is - the sum of all bytes, s2 is the sum of all s1 values. Both sums - are done modulo 65521. s1 is initialized to 1, s2 to zero. The - Adler-32 checksum is stored as s2*65536 + s1 in most- - significant-byte first (network) order. - - - - - - - - -Deutsch & Gailly Informational [Page 6] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - 2.3. Compliance - - A compliant compressor must produce streams with correct CMF, FLG - and ADLER32, but need not support preset dictionaries. When the - zlib data format is used as part of another standard data format, - the compressor may use only preset dictionaries that are specified - by this other data format. If this other format does not use the - preset dictionary feature, the compressor must not set the FDICT - flag. - - A compliant decompressor must check CMF, FLG, and ADLER32, and - provide an error indication if any of these have incorrect values. - A compliant decompressor must give an error indication if CM is - not one of the values defined in this specification (only the - value 8 is permitted in this version), since another value could - indicate the presence of new features that would cause subsequent - data to be interpreted incorrectly. A compliant decompressor must - give an error indication if FDICT is set and DICTID is not the - identifier of a known preset dictionary. A decompressor may - ignore FLEVEL and still be compliant. When the zlib data format - is being used as a part of another standard format, a compliant - decompressor must support all the preset dictionaries specified by - the other format. When the other format does not use the preset - dictionary feature, a compliant decompressor must reject any - stream in which the FDICT flag is set. - -3. References - - [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", - available in ftp://ftp.uu.net/graphics/png/documents/ - - [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [4] Fletcher, J. G., "An Arithmetic Checksum for Serial - Transmissions," IEEE Transactions on Communications, Vol. COM-30, - No. 1, January 1982, pp. 247-252. - - [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," - November, 1993, pp. 144, 145. (Available from - gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. - - - - - - - -Deutsch & Gailly Informational [Page 7] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -4. Source code - - Source code for a C language implementation of a "zlib" compliant - library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. - -5. Security Considerations - - A decoder that fails to check the ADLER32 checksum value may be - subject to undetected data corruption. - -6. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Jean-Loup Gailly and Mark Adler designed the zlib format and wrote - the related software described in this specification. Glenn - Randers-Pehrson converted this document to RFC and HTML format. - -7. Authors' Addresses - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - - Jean-Loup Gailly - - EMail: - - Questions about the technical content of this specification can be - sent by email to - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - - - - -Deutsch & Gailly Informational [Page 8] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -8. Appendix: Rationale - - 8.1. Preset dictionaries - - A preset dictionary is specially useful to compress short input - sequences. The compressor can take advantage of the dictionary - context to encode the input in a more compact manner. The - decompressor can be initialized with the appropriate context by - virtually decompressing a compressed version of the dictionary - without producing any output. However for certain compression - algorithms such as the deflate algorithm this operation can be - achieved without actually performing any decompression. - - The compressor and the decompressor must use exactly the same - dictionary. The dictionary may be fixed or may be chosen among a - certain number of predefined dictionaries, according to the kind - of input data. The decompressor can determine which dictionary has - been chosen by the compressor by checking the dictionary - identifier. This document does not specify the contents of - predefined dictionaries, since the optimal dictionaries are - application specific. Standard data formats using this feature of - the zlib specification must precisely define the allowed - dictionaries. - - 8.2. The Adler-32 algorithm - - The Adler-32 algorithm is much faster than the CRC32 algorithm yet - still provides an extremely low probability of undetected errors. - - The modulo on unsigned long accumulators can be delayed for 5552 - bytes, so the modulo operation time is negligible. If the bytes - are a, b, c, the second sum is 3a + 2b + c + 3, and so is position - and order sensitive, unlike the first sum, which is just a - checksum. That 65521 is prime is important to avoid a possible - large class of two-byte errors that leave the check unchanged. - (The Fletcher checksum uses 255, which is not prime and which also - makes the Fletcher check insensitive to single byte changes 0 <-> - 255.) - - The sum s1 is initialized to 1 instead of zero to make the length - of the sequence part of s2, so that the length does not have to be - checked separately. (Any sequence of zeroes has a Fletcher - checksum of zero.) - - - - - - - - -Deutsch & Gailly Informational [Page 9] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - -9. Appendix: Sample code - - The following C code computes the Adler-32 checksum of a data buffer. - It is written for clarity, not for speed. The sample code is in the - ANSI C programming language. Non C users may find it easier to read - with these hints: - - & Bitwise AND operator. - >> Bitwise right shift operator. When applied to an - unsigned quantity, as here, right shift inserts zero bit(s) - at the left. - << Bitwise left shift operator. Left shift inserts zero - bit(s) at the right. - ++ "n++" increments the variable n. - % modulo operator: a % b is the remainder of a divided by b. - - #define BASE 65521 /* largest prime smaller than 65536 */ - - /* - Update a running Adler-32 checksum with the bytes buf[0..len-1] - and return the updated checksum. The Adler-32 checksum should be - initialized to 1. - - Usage example: - - unsigned long adler = 1L; - - while (read_buffer(buffer, length) != EOF) { - adler = update_adler32(adler, buffer, length); - } - if (adler != original_adler) error(); - */ - unsigned long update_adler32(unsigned long adler, - unsigned char *buf, int len) - { - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int n; - - for (n = 0; n < len; n++) { - s1 = (s1 + buf[n]) % BASE; - s2 = (s2 + s1) % BASE; - } - return (s2 << 16) + s1; - } - - /* Return the adler32 of the bytes buf[0..len-1] */ - - - - -Deutsch & Gailly Informational [Page 10] - -RFC 1950 ZLIB Compressed Data Format Specification May 1996 - - - unsigned long adler32(unsigned char *buf, int len) - { - return update_adler32(1L, buf, len); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Deutsch & Gailly Informational [Page 11] - diff --git a/Sources/PerfectCZlib/doc/rfc1951.txt b/Sources/PerfectCZlib/doc/rfc1951.txt deleted file mode 100644 index 403c8c72..00000000 --- a/Sources/PerfectCZlib/doc/rfc1951.txt +++ /dev/null @@ -1,955 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1951 Aladdin Enterprises -Category: Informational May 1996 - - - DEFLATE Compressed Data Format Specification version 1.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format that - compresses data using a combination of the LZ77 algorithm and Huffman - coding, with efficiency comparable to the best currently available - general-purpose compression methods. The data can be produced or - consumed, even for an arbitrarily long sequentially presented input - data stream, using only an a priori bounded amount of intermediate - storage. The format can be implemented readily in a manner not - covered by patents. - - - - - - - - -Deutsch Informational [Page 1] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................ 3 - 1.6. Changes from previous versions ............................ 4 - 2. Compressed representation overview ............................. 4 - 3. Detailed specification ......................................... 5 - 3.1. Overall conventions ....................................... 5 - 3.1.1. Packing into bytes .................................. 5 - 3.2. Compressed block format ................................... 6 - 3.2.1. Synopsis of prefix and Huffman coding ............... 6 - 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 - 3.2.3. Details of block format ............................. 9 - 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 - 3.2.5. Compressed blocks (length and distance codes) ...... 11 - 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 - 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 - 3.3. Compliance ............................................... 14 - 4. Compression algorithm details ................................. 14 - 5. References .................................................... 16 - 6. Security Considerations ....................................... 16 - 7. Source code ................................................... 16 - 8. Acknowledgements .............................................. 16 - 9. Author's Address .............................................. 17 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - * Can be produced or consumed, even for an arbitrarily long - sequentially presented input data stream, using only an a - priori bounded amount of intermediate storage, and hence - can be used in data communications or similar structures - such as Unix filters; - * Compresses data with efficiency comparable to the best - currently available general-purpose compression methods, - and in particular considerably better than the "compress" - program; - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely; - - - -Deutsch Informational [Page 2] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - * Is compatible with the file format produced by the current - widely used gzip utility, in that conforming decompressors - will be able to read data produced by the existing gzip - compressor. - - The data format defined by this specification does not attempt to: - - * Allow random access to compressed data; - * Compress specialized data (e.g., raster graphics) as well - as the best currently available specialized algorithms. - - A simple counting argument shows that no lossless compression - algorithm can compress every possible input data set. For the - format defined here, the worst case expansion is 5 bytes per 32K- - byte block, i.e., a size increase of 0.015% for large data sets. - English text usually compresses by a factor of 2.5 to 3; - executable files usually compress somewhat less; graphical data - such as raster images may compress much more. - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into "deflate" format and/or decompress data from - "deflate" format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. Familiarity with the technique of Huffman coding - is helpful but not required. - - 1.3. Scope - - The specification specifies a method for representing a sequence - of bytes as a (usually shorter) sequence of bits, and a method for - packing the latter bit sequence into bytes. - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any data set that conforms to all - the specifications presented here; a compliant compressor must - produce data sets that conform to all the specifications presented - here. - - 1.5. Definitions of terms and conventions used - - Byte: 8 bits stored or transmitted as a unit (same as an octet). - For this specification, a byte is exactly 8 bits, even on machines - - - -Deutsch Informational [Page 3] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - which store a character on a number of bits different from eight. - See below, for the numbering of bits within a byte. - - String: a sequence of arbitrary bytes. - - 1.6. Changes from previous versions - - There have been no technical changes to the deflate format since - version 1.1 of this specification. In version 1.2, some - terminology was changed. Version 1.3 is a conversion of the - specification to RFC style. - -2. Compressed representation overview - - A compressed data set consists of a series of blocks, corresponding - to successive blocks of input data. The block sizes are arbitrary, - except that non-compressible blocks are limited to 65,535 bytes. - - Each block is compressed using a combination of the LZ77 algorithm - and Huffman coding. The Huffman trees for each block are independent - of those for previous or subsequent blocks; the LZ77 algorithm may - use a reference to a duplicated string occurring in a previous block, - up to 32K input bytes before. - - Each block consists of two parts: a pair of Huffman code trees that - describe the representation of the compressed data part, and a - compressed data part. (The Huffman trees themselves are compressed - using Huffman encoding.) The compressed data consists of a series of - elements of two types: literal bytes (of strings that have not been - detected as duplicated within the previous 32K input bytes), and - pointers to duplicated strings, where a pointer is represented as a - pair . The representation used in the - "deflate" format limits distances to 32K bytes and lengths to 258 - bytes, but does not limit the size of a block, except for - uncompressible blocks, which are limited as noted above. - - Each type of value (literals, distances, and lengths) in the - compressed data is represented using a Huffman code, using one code - tree for literals and lengths and a separate code tree for distances. - The code trees for each block appear in a compact form just before - the compressed data for that block. - - - - - - - - - - -Deutsch Informational [Page 4] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -3. Detailed specification - - 3.1. Overall conventions In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the least-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00001000|00000010| - +--------+--------+ - ^ ^ - | | - | + more significant byte = 2 x 256 - + less significant byte = 8 - - 3.1.1. Packing into bytes - - This document does not address the issue of the order in which - bits of a byte are transmitted on a bit-sequential medium, - since the final data format described here is byte- rather than - - - -Deutsch Informational [Page 5] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - bit-oriented. However, we describe the compressed block format - in below, as a sequence of data elements of various bit - lengths, not a sequence of bytes. We must therefore specify - how to pack these data elements into bytes to form the final - compressed byte sequence: - - * Data elements are packed into bytes in order of - increasing bit number within the byte, i.e., starting - with the least-significant bit of the byte. - * Data elements other than Huffman codes are packed - starting with the least-significant bit of the data - element. - * Huffman codes are packed starting with the most- - significant bit of the code. - - In other words, if one were to print out the compressed data as - a sequence of bytes, starting with the first byte at the - *right* margin and proceeding to the *left*, with the most- - significant bit of each byte on the left as usual, one would be - able to parse the result from right to left, with fixed-width - elements in the correct MSB-to-LSB order and Huffman codes in - bit-reversed order (i.e., with the first bit of the code in the - relative LSB position). - - 3.2. Compressed block format - - 3.2.1. Synopsis of prefix and Huffman coding - - Prefix coding represents symbols from an a priori known - alphabet by bit sequences (codes), one code for each symbol, in - a manner such that different symbols may be represented by bit - sequences of different lengths, but a parser can always parse - an encoded string unambiguously symbol-by-symbol. - - We define a prefix code in terms of a binary tree in which the - two edges descending from each non-leaf node are labeled 0 and - 1 and in which the leaf nodes correspond one-for-one with (are - labeled with) the symbols of the alphabet; then the code for a - symbol is the sequence of 0's and 1's on the edges leading from - the root to the leaf labeled with that symbol. For example: - - - - - - - - - - - -Deutsch Informational [Page 6] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - /\ Symbol Code - 0 1 ------ ---- - / \ A 00 - /\ B B 1 - 0 1 C 011 - / \ D 010 - A /\ - 0 1 - / \ - D C - - A parser can decode the next symbol from an encoded input - stream by walking down the tree from the root, at each step - choosing the edge corresponding to the next input bit. - - Given an alphabet with known symbol frequencies, the Huffman - algorithm allows the construction of an optimal prefix code - (one which represents strings with those symbol frequencies - using the fewest bits of any possible prefix codes for that - alphabet). Such a code is called a Huffman code. (See - reference [1] in Chapter 5, references for additional - information on Huffman codes.) - - Note that in the "deflate" format, the Huffman codes for the - various alphabets must not exceed certain maximum code lengths. - This constraint complicates the algorithm for computing code - lengths from symbol frequencies. Again, see Chapter 5, - references for details. - - 3.2.2. Use of Huffman coding in the "deflate" format - - The Huffman codes used for each alphabet in the "deflate" - format have two additional rules: - - * All codes of a given bit length have lexicographically - consecutive values, in the same order as the symbols - they represent; - - * Shorter codes lexicographically precede longer codes. - - - - - - - - - - - - -Deutsch Informational [Page 7] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - We could recode the example above to follow this rule as - follows, assuming that the order of the alphabet is ABCD: - - Symbol Code - ------ ---- - A 10 - B 0 - C 110 - D 111 - - I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are - lexicographically consecutive. - - Given this rule, we can define the Huffman code for an alphabet - just by giving the bit lengths of the codes for each symbol of - the alphabet in order; this is sufficient to determine the - actual codes. In our example, the code is completely defined - by the sequence of bit lengths (2, 1, 3, 3). The following - algorithm generates the codes as integers, intended to be read - from most- to least-significant bit. The code lengths are - initially in tree[I].Len; the codes are produced in - tree[I].Code. - - 1) Count the number of codes for each code length. Let - bl_count[N] be the number of codes of length N, N >= 1. - - 2) Find the numerical value of the smallest code for each - code length: - - code = 0; - bl_count[0] = 0; - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits-1]) << 1; - next_code[bits] = code; - } - - 3) Assign numerical values to all codes, using consecutive - values for all codes of the same length with the base - values determined at step 2. Codes that are never used - (which have a bit length of zero) must not be assigned a - value. - - for (n = 0; n <= max_code; n++) { - len = tree[n].Len; - if (len != 0) { - tree[n].Code = next_code[len]; - next_code[len]++; - } - - - -Deutsch Informational [Page 8] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - } - - Example: - - Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, - 3, 2, 4, 4). After step 1, we have: - - N bl_count[N] - - ----------- - 2 1 - 3 5 - 4 2 - - Step 2 computes the following next_code values: - - N next_code[N] - - ------------ - 1 0 - 2 0 - 3 2 - 4 14 - - Step 3 produces the following code values: - - Symbol Length Code - ------ ------ ---- - A 3 010 - B 3 011 - C 3 100 - D 3 101 - E 3 110 - F 2 00 - G 4 1110 - H 4 1111 - - 3.2.3. Details of block format - - Each block of compressed data begins with 3 header bits - containing the following data: - - first bit BFINAL - next 2 bits BTYPE - - Note that the header bits do not necessarily begin on a byte - boundary, since a block does not necessarily occupy an integral - number of bytes. - - - - - -Deutsch Informational [Page 9] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - BFINAL is set if and only if this is the last block of the data - set. - - BTYPE specifies how the data are compressed, as follows: - - 00 - no compression - 01 - compressed with fixed Huffman codes - 10 - compressed with dynamic Huffman codes - 11 - reserved (error) - - The only difference between the two compressed cases is how the - Huffman codes for the literal/length and distance alphabets are - defined. - - In all cases, the decoding algorithm for the actual data is as - follows: - - do - read block header from input stream. - if stored with no compression - skip any remaining bits in current partially - processed byte - read LEN and NLEN (see next section) - copy LEN bytes of data to output - otherwise - if compressed with dynamic Huffman codes - read representation of code trees (see - subsection below) - loop (until end of block code recognized) - decode literal/length value from input stream - if value < 256 - copy value (literal byte) to output stream - otherwise - if value = end of block (256) - break from loop - otherwise (value = 257..285) - decode distance from input stream - - move backwards distance bytes in the output - stream, and copy length bytes from this - position to the output stream. - end loop - while not last block - - Note that a duplicated string reference may refer to a string - in a previous block; i.e., the backward distance may cross one - or more block boundaries. However a distance cannot refer past - the beginning of the output stream. (An application using a - - - -Deutsch Informational [Page 10] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - preset dictionary might discard part of the output stream; a - distance can refer to that part of the output stream anyway) - Note also that the referenced string may overlap the current - position; for example, if the last 2 bytes decoded have values - X and Y, a string reference with - adds X,Y,X,Y,X to the output stream. - - We now specify each compression method in turn. - - 3.2.4. Non-compressed blocks (BTYPE=00) - - Any bits of input up to the next byte boundary are ignored. - The rest of the block consists of the following information: - - 0 1 2 3 4... - +---+---+---+---+================================+ - | LEN | NLEN |... LEN bytes of literal data...| - +---+---+---+---+================================+ - - LEN is the number of data bytes in the block. NLEN is the - one's complement of LEN. - - 3.2.5. Compressed blocks (length and distance codes) - - As noted above, encoded data blocks in the "deflate" format - consist of sequences of symbols drawn from three conceptually - distinct alphabets: either literal bytes, from the alphabet of - byte values (0..255), or pairs, - where the length is drawn from (3..258) and the distance is - drawn from (1..32,768). In fact, the literal and length - alphabets are merged into a single alphabet (0..285), where - values 0..255 represent literal bytes, the value 256 indicates - end-of-block, and values 257..285 represent length codes - (possibly in conjunction with extra bits following the symbol - code) as follows: - - - - - - - - - - - - - - - - -Deutsch Informational [Page 11] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - Extra Extra Extra - Code Bits Length(s) Code Bits Lengths Code Bits Length(s) - ---- ---- ------ ---- ---- ------- ---- ---- ------- - 257 0 3 267 1 15,16 277 4 67-82 - 258 0 4 268 1 17,18 278 4 83-98 - 259 0 5 269 2 19-22 279 4 99-114 - 260 0 6 270 2 23-26 280 4 115-130 - 261 0 7 271 2 27-30 281 5 131-162 - 262 0 8 272 2 31-34 282 5 163-194 - 263 0 9 273 3 35-42 283 5 195-226 - 264 0 10 274 3 43-50 284 5 227-257 - 265 1 11,12 275 3 51-58 285 0 258 - 266 1 13,14 276 3 59-66 - - The extra bits should be interpreted as a machine integer - stored with the most-significant bit first, e.g., bits 1110 - represent the value 14. - - Extra Extra Extra - Code Bits Dist Code Bits Dist Code Bits Distance - ---- ---- ---- ---- ---- ------ ---- ---- -------- - 0 0 1 10 4 33-48 20 9 1025-1536 - 1 0 2 11 4 49-64 21 9 1537-2048 - 2 0 3 12 5 65-96 22 10 2049-3072 - 3 0 4 13 5 97-128 23 10 3073-4096 - 4 1 5,6 14 6 129-192 24 11 4097-6144 - 5 1 7,8 15 6 193-256 25 11 6145-8192 - 6 2 9-12 16 7 257-384 26 12 8193-12288 - 7 2 13-16 17 7 385-512 27 12 12289-16384 - 8 3 17-24 18 8 513-768 28 13 16385-24576 - 9 3 25-32 19 8 769-1024 29 13 24577-32768 - - 3.2.6. Compression with fixed Huffman codes (BTYPE=01) - - The Huffman codes for the two alphabets are fixed, and are not - represented explicitly in the data. The Huffman code lengths - for the literal/length alphabet are: - - Lit Value Bits Codes - --------- ---- ----- - 0 - 143 8 00110000 through - 10111111 - 144 - 255 9 110010000 through - 111111111 - 256 - 279 7 0000000 through - 0010111 - 280 - 287 8 11000000 through - 11000111 - - - -Deutsch Informational [Page 12] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - The code lengths are sufficient to generate the actual codes, - as described above; we show the codes in the table for added - clarity. Literal/length values 286-287 will never actually - occur in the compressed data, but participate in the code - construction. - - Distance codes 0-31 are represented by (fixed-length) 5-bit - codes, with possible additional bits as shown in the table - shown in Paragraph 3.2.5, above. Note that distance codes 30- - 31 will never actually occur in the compressed data. - - 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) - - The Huffman codes for the two alphabets appear in the block - immediately after the header bits and before the actual - compressed data, first the literal/length code and then the - distance code. Each code is defined by a sequence of code - lengths, as discussed in Paragraph 3.2.2, above. For even - greater compactness, the code length sequences themselves are - compressed using a Huffman code. The alphabet for code lengths - is as follows: - - 0 - 15: Represent code lengths of 0 - 15 - 16: Copy the previous code length 3 - 6 times. - The next 2 bits indicate repeat length - (0 = 3, ... , 3 = 6) - Example: Codes 8, 16 (+2 bits 11), - 16 (+2 bits 10) will expand to - 12 code lengths of 8 (1 + 6 + 5) - 17: Repeat a code length of 0 for 3 - 10 times. - (3 bits of length) - 18: Repeat a code length of 0 for 11 - 138 times - (7 bits of length) - - A code length of 0 indicates that the corresponding symbol in - the literal/length or distance alphabet will not occur in the - block, and should not participate in the Huffman code - construction algorithm given earlier. If only one distance - code is used, it is encoded using one bit, not zero bits; in - this case there is a single code length of one, with one unused - code. One distance code of zero bits means that there are no - distance codes used at all (the data is all literals). - - We can now define the format of the block: - - 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) - 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) - 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) - - - -Deutsch Informational [Page 13] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - (HCLEN + 4) x 3 bits: code lengths for the code length - alphabet given just above, in the order: 16, 17, 18, - 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 - - These code lengths are interpreted as 3-bit integers - (0-7); as above, a code length of 0 means the - corresponding symbol (literal/length or distance code - length) is not used. - - HLIT + 257 code lengths for the literal/length alphabet, - encoded using the code length Huffman code - - HDIST + 1 code lengths for the distance alphabet, - encoded using the code length Huffman code - - The actual compressed data of the block, - encoded using the literal/length and distance Huffman - codes - - The literal/length symbol 256 (end of data), - encoded using the literal/length Huffman code - - The code length repeat codes can cross from HLIT + 257 to the - HDIST + 1 code lengths. In other words, all code lengths form - a single sequence of HLIT + HDIST + 258 values. - - 3.3. Compliance - - A compressor may limit further the ranges of values specified in - the previous section and still be compliant; for example, it may - limit the range of backward pointers to some value smaller than - 32K. Similarly, a compressor may limit the size of blocks so that - a compressible block fits in memory. - - A compliant decompressor must accept the full range of possible - values defined in the previous section, and must accept blocks of - arbitrary size. - -4. Compression algorithm details - - While it is the intent of this document to define the "deflate" - compressed data format without reference to any particular - compression algorithm, the format is related to the compressed - formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); - since many variations of LZ77 are patented, it is strongly - recommended that the implementor of a compressor follow the general - algorithm presented here, which is known not to be patented per se. - The material in this section is not part of the definition of the - - - -Deutsch Informational [Page 14] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - - specification per se, and a compressor need not follow it in order to - be compliant. - - The compressor terminates a block when it determines that starting a - new block with fresh trees would be useful, or when the block size - fills up the compressor's block buffer. - - The compressor uses a chained hash table to find duplicated strings, - using a hash function that operates on 3-byte sequences. At any - given point during compression, let XYZ be the next 3 input bytes to - be examined (not necessarily all different, of course). First, the - compressor examines the hash chain for XYZ. If the chain is empty, - the compressor simply writes out X as a literal byte and advances one - byte in the input. If the hash chain is not empty, indicating that - the sequence XYZ (or, if we are unlucky, some other 3 bytes with the - same hash function value) has occurred recently, the compressor - compares all strings on the XYZ hash chain with the actual input data - sequence starting at the current point, and selects the longest - match. - - The compressor searches the hash chains starting with the most recent - strings, to favor small distances and thus take advantage of the - Huffman encoding. The hash chains are singly linked. There are no - deletions from the hash chains; the algorithm simply discards matches - that are too old. To avoid a worst-case situation, very long hash - chains are arbitrarily truncated at a certain length, determined by a - run-time parameter. - - To improve overall compression, the compressor optionally defers the - selection of matches ("lazy matching"): after a match of length N has - been found, the compressor searches for a longer match starting at - the next input byte. If it finds a longer match, it truncates the - previous match to a length of one (thus producing a single literal - byte) and then emits the longer match. Otherwise, it emits the - original match, and, as described above, advances N bytes before - continuing. - - Run-time parameters also control this "lazy match" procedure. If - compression ratio is most important, the compressor attempts a - complete second search regardless of the length of the first match. - In the normal case, if the current match is "long enough", the - compressor reduces the search for a longer match, thus speeding up - the process. If speed is most important, the compressor inserts new - strings in the hash table only when no match was found, or when the - match is not "too long". This degrades the compression ratio but - saves time since there are both fewer insertions and fewer searches. - - - - - -Deutsch Informational [Page 15] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -5. References - - [1] Huffman, D. A., "A Method for the Construction of Minimum - Redundancy Codes", Proceedings of the Institute of Radio - Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. - - [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data - Compression", IEEE Transactions on Information Theory, Vol. 23, - No. 3, pp. 337-343. - - [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, - available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ - - [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix - encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. - - [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," - Comm. ACM, 33,4, April 1990, pp. 449-459. - -6. Security Considerations - - Any data compression method involves the reduction of redundancy in - the data. Consequently, any corruption of the data is likely to have - severe effects and be difficult to correct. Uncompressed text, on - the other hand, will probably still be readable despite the presence - of some corrupted bytes. - - It is recommended that systems using this data format provide some - means of validating the integrity of the compressed data. See - reference [3], for example. - -7. Source code - - Source code for a C language implementation of a "deflate" compliant - compressor and decompressor is available within the zlib package at - ftp://ftp.uu.net/pub/archiving/zip/zlib/. - -8. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Phil Katz designed the deflate format. Jean-Loup Gailly and Mark - Adler wrote the related software described in this specification. - Glenn Randers-Pehrson converted this document to RFC and HTML format. - - - -Deutsch Informational [Page 16] - -RFC 1951 DEFLATE Compressed Data Format Specification May 1996 - - -9. Author's Address - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - Questions about the technical content of this specification can be - sent by email to: - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to: - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Deutsch Informational [Page 17] - diff --git a/Sources/PerfectCZlib/doc/rfc1952.txt b/Sources/PerfectCZlib/doc/rfc1952.txt deleted file mode 100644 index a8e51b45..00000000 --- a/Sources/PerfectCZlib/doc/rfc1952.txt +++ /dev/null @@ -1,675 +0,0 @@ - - - - - - -Network Working Group P. Deutsch -Request for Comments: 1952 Aladdin Enterprises -Category: Informational May 1996 - - - GZIP file format specification version 4.3 - -Status of This Memo - - This memo provides information for the Internet community. This memo - does not specify an Internet standard of any kind. Distribution of - this memo is unlimited. - -IESG Note: - - The IESG takes no position on the validity of any Intellectual - Property Rights statements contained in this document. - -Notices - - Copyright (c) 1996 L. Peter Deutsch - - Permission is granted to copy and distribute this document for any - purpose and without charge, including translations into other - languages and incorporation into compilations, provided that the - copyright notice and this notice are preserved, and that any - substantive changes or deletions from the original are clearly - marked. - - A pointer to the latest version of this and related documentation in - HTML format can be found at the URL - . - -Abstract - - This specification defines a lossless compressed data format that is - compatible with the widely used GZIP utility. The format includes a - cyclic redundancy check value for detecting data corruption. The - format presently uses the DEFLATE method of compression but can be - easily extended to use other compression methods. The format can be - implemented readily in a manner not covered by patents. - - - - - - - - - - -Deutsch Informational [Page 1] - -RFC 1952 GZIP File Format Specification May 1996 - - -Table of Contents - - 1. Introduction ................................................... 2 - 1.1. Purpose ................................................... 2 - 1.2. Intended audience ......................................... 3 - 1.3. Scope ..................................................... 3 - 1.4. Compliance ................................................ 3 - 1.5. Definitions of terms and conventions used ................. 3 - 1.6. Changes from previous versions ............................ 3 - 2. Detailed specification ......................................... 4 - 2.1. Overall conventions ....................................... 4 - 2.2. File format ............................................... 5 - 2.3. Member format ............................................. 5 - 2.3.1. Member header and trailer ........................... 6 - 2.3.1.1. Extra field ................................... 8 - 2.3.1.2. Compliance .................................... 9 - 3. References .................................................. 9 - 4. Security Considerations .................................... 10 - 5. Acknowledgements ........................................... 10 - 6. Author's Address ........................................... 10 - 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 - 8. Appendix: Sample CRC Code .................................. 11 - -1. Introduction - - 1.1. Purpose - - The purpose of this specification is to define a lossless - compressed data format that: - - * Is independent of CPU type, operating system, file system, - and character set, and hence can be used for interchange; - * Can compress or decompress a data stream (as opposed to a - randomly accessible file) to produce another data stream, - using only an a priori bounded amount of intermediate - storage, and hence can be used in data communications or - similar structures such as Unix filters; - * Compresses data with efficiency comparable to the best - currently available general-purpose compression methods, - and in particular considerably better than the "compress" - program; - * Can be implemented readily in a manner not covered by - patents, and hence can be practiced freely; - * Is compatible with the file format produced by the current - widely used gzip utility, in that conforming decompressors - will be able to read data produced by the existing gzip - compressor. - - - - -Deutsch Informational [Page 2] - -RFC 1952 GZIP File Format Specification May 1996 - - - The data format defined by this specification does not attempt to: - - * Provide random access to compressed data; - * Compress specialized data (e.g., raster graphics) as well as - the best currently available specialized algorithms. - - 1.2. Intended audience - - This specification is intended for use by implementors of software - to compress data into gzip format and/or decompress data from gzip - format. - - The text of the specification assumes a basic background in - programming at the level of bits and other primitive data - representations. - - 1.3. Scope - - The specification specifies a compression method and a file format - (the latter assuming only that a file can store a sequence of - arbitrary bytes). It does not specify any particular interface to - a file system or anything about character sets or encodings - (except for file names and comments, which are optional). - - 1.4. Compliance - - Unless otherwise indicated below, a compliant decompressor must be - able to accept and decompress any file that conforms to all the - specifications presented here; a compliant compressor must produce - files that conform to all the specifications presented here. The - material in the appendices is not part of the specification per se - and is not relevant to compliance. - - 1.5. Definitions of terms and conventions used - - byte: 8 bits stored or transmitted as a unit (same as an octet). - (For this specification, a byte is exactly 8 bits, even on - machines which store a character on a number of bits different - from 8.) See below for the numbering of bits within a byte. - - 1.6. Changes from previous versions - - There have been no technical changes to the gzip format since - version 4.1 of this specification. In version 4.2, some - terminology was changed, and the sample CRC code was rewritten for - clarity and to eliminate the requirement for the caller to do pre- - and post-conditioning. Version 4.3 is a conversion of the - specification to RFC style. - - - -Deutsch Informational [Page 3] - -RFC 1952 GZIP File Format Specification May 1996 - - -2. Detailed specification - - 2.1. Overall conventions - - In the diagrams below, a box like this: - - +---+ - | | <-- the vertical bars might be missing - +---+ - - represents one byte; a box like this: - - +==============+ - | | - +==============+ - - represents a variable number of bytes. - - Bytes stored within a computer do not have a "bit order", since - they are always treated as a unit. However, a byte considered as - an integer between 0 and 255 does have a most- and least- - significant bit, and since we write numbers with the most- - significant digit on the left, we also write bytes with the most- - significant bit on the left. In the diagrams below, we number the - bits of a byte so that bit 0 is the least-significant bit, i.e., - the bits are numbered: - - +--------+ - |76543210| - +--------+ - - This document does not address the issue of the order in which - bits of a byte are transmitted on a bit-sequential medium, since - the data format described here is byte- rather than bit-oriented. - - Within a computer, a number may occupy multiple bytes. All - multi-byte numbers in the format described here are stored with - the least-significant byte first (at the lower memory address). - For example, the decimal number 520 is stored as: - - 0 1 - +--------+--------+ - |00001000|00000010| - +--------+--------+ - ^ ^ - | | - | + more significant byte = 2 x 256 - + less significant byte = 8 - - - -Deutsch Informational [Page 4] - -RFC 1952 GZIP File Format Specification May 1996 - - - 2.2. File format - - A gzip file consists of a series of "members" (compressed data - sets). The format of each member is specified in the following - section. The members simply appear one after another in the file, - with no additional information before, between, or after them. - - 2.3. Member format - - Each member has the following structure: - - +---+---+---+---+---+---+---+---+---+---+ - |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) - +---+---+---+---+---+---+---+---+---+---+ - - (if FLG.FEXTRA set) - - +---+---+=================================+ - | XLEN |...XLEN bytes of "extra field"...| (more-->) - +---+---+=================================+ - - (if FLG.FNAME set) - - +=========================================+ - |...original file name, zero-terminated...| (more-->) - +=========================================+ - - (if FLG.FCOMMENT set) - - +===================================+ - |...file comment, zero-terminated...| (more-->) - +===================================+ - - (if FLG.FHCRC set) - - +---+---+ - | CRC16 | - +---+---+ - - +=======================+ - |...compressed blocks...| (more-->) - +=======================+ - - 0 1 2 3 4 5 6 7 - +---+---+---+---+---+---+---+---+ - | CRC32 | ISIZE | - +---+---+---+---+---+---+---+---+ - - - - -Deutsch Informational [Page 5] - -RFC 1952 GZIP File Format Specification May 1996 - - - 2.3.1. Member header and trailer - - ID1 (IDentification 1) - ID2 (IDentification 2) - These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 - (0x8b, \213), to identify the file as being in gzip format. - - CM (Compression Method) - This identifies the compression method used in the file. CM - = 0-7 are reserved. CM = 8 denotes the "deflate" - compression method, which is the one customarily used by - gzip and which is documented elsewhere. - - FLG (FLaGs) - This flag byte is divided into individual bits as follows: - - bit 0 FTEXT - bit 1 FHCRC - bit 2 FEXTRA - bit 3 FNAME - bit 4 FCOMMENT - bit 5 reserved - bit 6 reserved - bit 7 reserved - - If FTEXT is set, the file is probably ASCII text. This is - an optional indication, which the compressor may set by - checking a small amount of the input data to see whether any - non-ASCII characters are present. In case of doubt, FTEXT - is cleared, indicating binary data. For systems which have - different file formats for ascii text and binary data, the - decompressor can use FTEXT to choose the appropriate format. - We deliberately do not specify the algorithm used to set - this bit, since a compressor always has the option of - leaving it cleared and a decompressor always has the option - of ignoring it and letting some other program handle issues - of data conversion. - - If FHCRC is set, a CRC16 for the gzip header is present, - immediately before the compressed data. The CRC16 consists - of the two least significant bytes of the CRC32 for all - bytes of the gzip header up to and not including the CRC16. - [The FHCRC bit was never set by versions of gzip up to - 1.2.4, even though it was documented with a different - meaning in gzip 1.2.4.] - - If FEXTRA is set, optional extra fields are present, as - described in a following section. - - - -Deutsch Informational [Page 6] - -RFC 1952 GZIP File Format Specification May 1996 - - - If FNAME is set, an original file name is present, - terminated by a zero byte. The name must consist of ISO - 8859-1 (LATIN-1) characters; on operating systems using - EBCDIC or any other character set for file names, the name - must be translated to the ISO LATIN-1 character set. This - is the original name of the file being compressed, with any - directory components removed, and, if the file being - compressed is on a file system with case insensitive names, - forced to lower case. There is no original file name if the - data was compressed from a source other than a named file; - for example, if the source was stdin on a Unix system, there - is no file name. - - If FCOMMENT is set, a zero-terminated file comment is - present. This comment is not interpreted; it is only - intended for human consumption. The comment must consist of - ISO 8859-1 (LATIN-1) characters. Line breaks should be - denoted by a single line feed character (10 decimal). - - Reserved FLG bits must be zero. - - MTIME (Modification TIME) - This gives the most recent modification time of the original - file being compressed. The time is in Unix format, i.e., - seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this - may cause problems for MS-DOS and other systems that use - local rather than Universal time.) If the compressed data - did not come from a file, MTIME is set to the time at which - compression started. MTIME = 0 means no time stamp is - available. - - XFL (eXtra FLags) - These flags are available for use by specific compression - methods. The "deflate" method (CM = 8) sets these flags as - follows: - - XFL = 2 - compressor used maximum compression, - slowest algorithm - XFL = 4 - compressor used fastest algorithm - - OS (Operating System) - This identifies the type of file system on which compression - took place. This may be useful in determining end-of-line - convention for text files. The currently defined values are - as follows: - - - - - - -Deutsch Informational [Page 7] - -RFC 1952 GZIP File Format Specification May 1996 - - - 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) - 1 - Amiga - 2 - VMS (or OpenVMS) - 3 - Unix - 4 - VM/CMS - 5 - Atari TOS - 6 - HPFS filesystem (OS/2, NT) - 7 - Macintosh - 8 - Z-System - 9 - CP/M - 10 - TOPS-20 - 11 - NTFS filesystem (NT) - 12 - QDOS - 13 - Acorn RISCOS - 255 - unknown - - XLEN (eXtra LENgth) - If FLG.FEXTRA is set, this gives the length of the optional - extra field. See below for details. - - CRC32 (CRC-32) - This contains a Cyclic Redundancy Check value of the - uncompressed data computed according to CRC-32 algorithm - used in the ISO 3309 standard and in section 8.1.1.6.2 of - ITU-T recommendation V.42. (See http://www.iso.ch for - ordering ISO documents. See gopher://info.itu.ch for an - online version of ITU-T V.42.) - - ISIZE (Input SIZE) - This contains the size of the original (uncompressed) input - data modulo 2^32. - - 2.3.1.1. Extra field - - If the FLG.FEXTRA bit is set, an "extra field" is present in - the header, with total length XLEN bytes. It consists of a - series of subfields, each of the form: - - +---+---+---+---+==================================+ - |SI1|SI2| LEN |... LEN bytes of subfield data ...| - +---+---+---+---+==================================+ - - SI1 and SI2 provide a subfield ID, typically two ASCII letters - with some mnemonic value. Jean-Loup Gailly - is maintaining a registry of subfield - IDs; please send him any subfield ID you wish to use. Subfield - IDs with SI2 = 0 are reserved for future use. The following - IDs are currently defined: - - - -Deutsch Informational [Page 8] - -RFC 1952 GZIP File Format Specification May 1996 - - - SI1 SI2 Data - ---------- ---------- ---- - 0x41 ('A') 0x70 ('P') Apollo file type information - - LEN gives the length of the subfield data, excluding the 4 - initial bytes. - - 2.3.1.2. Compliance - - A compliant compressor must produce files with correct ID1, - ID2, CM, CRC32, and ISIZE, but may set all the other fields in - the fixed-length part of the header to default values (255 for - OS, 0 for all others). The compressor must set all reserved - bits to zero. - - A compliant decompressor must check ID1, ID2, and CM, and - provide an error indication if any of these have incorrect - values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC - at least so it can skip over the optional fields if they are - present. It need not examine any other part of the header or - trailer; in particular, a decompressor may ignore FTEXT and OS - and always produce binary output, and still be compliant. A - compliant decompressor must give an error indication if any - reserved bit is non-zero, since such a bit could indicate the - presence of a new field that would cause subsequent data to be - interpreted incorrectly. - -3. References - - [1] "Information Processing - 8-bit single-byte coded graphic - character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). - The ISO 8859-1 (Latin-1) character set is a superset of 7-bit - ASCII. Files defining this character set are available as - iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ - - [2] ISO 3309 - - [3] ITU-T recommendation V.42 - - [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", - available in ftp://ftp.uu.net/pub/archiving/zip/doc/ - - [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in - ftp://prep.ai.mit.edu/pub/gnu/ - - [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table - Look-Up", Communications of the ACM, 31(8), pp.1008-1013. - - - - -Deutsch Informational [Page 9] - -RFC 1952 GZIP File Format Specification May 1996 - - - [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, - pp.118-133. - - [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, - describing the CRC concept. - -4. Security Considerations - - Any data compression method involves the reduction of redundancy in - the data. Consequently, any corruption of the data is likely to have - severe effects and be difficult to correct. Uncompressed text, on - the other hand, will probably still be readable despite the presence - of some corrupted bytes. - - It is recommended that systems using this data format provide some - means of validating the integrity of the compressed data, such as by - setting and checking the CRC-32 check value. - -5. Acknowledgements - - Trademarks cited in this document are the property of their - respective owners. - - Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, - the related software described in this specification. Glenn - Randers-Pehrson converted this document to RFC and HTML format. - -6. Author's Address - - L. Peter Deutsch - Aladdin Enterprises - 203 Santa Margarita Ave. - Menlo Park, CA 94025 - - Phone: (415) 322-0103 (AM only) - FAX: (415) 322-1734 - EMail: - - Questions about the technical content of this specification can be - sent by email to: - - Jean-Loup Gailly and - Mark Adler - - Editorial comments on this specification can be sent by email to: - - L. Peter Deutsch and - Glenn Randers-Pehrson - - - -Deutsch Informational [Page 10] - -RFC 1952 GZIP File Format Specification May 1996 - - -7. Appendix: Jean-Loup Gailly's gzip utility - - The most widely used implementation of gzip compression, and the - original documentation on which this specification is based, were - created by Jean-Loup Gailly . Since this - implementation is a de facto standard, we mention some more of its - features here. Again, the material in this section is not part of - the specification per se, and implementations need not follow it to - be compliant. - - When compressing or decompressing a file, gzip preserves the - protection, ownership, and modification time attributes on the local - file system, since there is no provision for representing protection - attributes in the gzip file format itself. Since the file format - includes a modification time, the gzip decompressor provides a - command line switch that assigns the modification time from the file, - rather than the local modification time of the compressed input, to - the decompressed output. - -8. Appendix: Sample CRC Code - - The following sample code represents a practical implementation of - the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 - for a formal specification.) - - The sample code is in the ANSI C programming language. Non C users - may find it easier to read with these hints: - - & Bitwise AND operator. - ^ Bitwise exclusive-OR operator. - >> Bitwise right shift operator. When applied to an - unsigned quantity, as here, right shift inserts zero - bit(s) at the left. - ! Logical NOT operator. - ++ "n++" increments the variable n. - 0xNNN 0x introduces a hexadecimal (base 16) constant. - Suffix L indicates a long value (at least 32 bits). - - /* Table of CRCs of all 8-bit messages. */ - unsigned long crc_table[256]; - - /* Flag: has the table been computed? Initially false. */ - int crc_table_computed = 0; - - /* Make the table for a fast CRC. */ - void make_crc_table(void) - { - unsigned long c; - - - -Deutsch Informational [Page 11] - -RFC 1952 GZIP File Format Specification May 1996 - - - int n, k; - for (n = 0; n < 256; n++) { - c = (unsigned long) n; - for (k = 0; k < 8; k++) { - if (c & 1) { - c = 0xedb88320L ^ (c >> 1); - } else { - c = c >> 1; - } - } - crc_table[n] = c; - } - crc_table_computed = 1; - } - - /* - Update a running crc with the bytes buf[0..len-1] and return - the updated crc. The crc should be initialized to zero. Pre- and - post-conditioning (one's complement) is performed within this - function so it shouldn't be done by the caller. Usage example: - - unsigned long crc = 0L; - - while (read_buffer(buffer, length) != EOF) { - crc = update_crc(crc, buffer, length); - } - if (crc != original_crc) error(); - */ - unsigned long update_crc(unsigned long crc, - unsigned char *buf, int len) - { - unsigned long c = crc ^ 0xffffffffL; - int n; - - if (!crc_table_computed) - make_crc_table(); - for (n = 0; n < len; n++) { - c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); - } - return c ^ 0xffffffffL; - } - - /* Return the CRC of the bytes buf[0..len-1]. */ - unsigned long crc(unsigned char *buf, int len) - { - return update_crc(0L, buf, len); - } - - - - -Deutsch Informational [Page 12] - diff --git a/Sources/PerfectCZlib/doc/txtvsbin.txt b/Sources/PerfectCZlib/doc/txtvsbin.txt deleted file mode 100644 index 3d0f0634..00000000 --- a/Sources/PerfectCZlib/doc/txtvsbin.txt +++ /dev/null @@ -1,107 +0,0 @@ -A Fast Method for Identifying Plain Text Files -============================================== - - -Introduction ------------- - -Given a file coming from an unknown source, it is sometimes desirable -to find out whether the format of that file is plain text. Although -this may appear like a simple task, a fully accurate detection of the -file type requires heavy-duty semantic analysis on the file contents. -It is, however, possible to obtain satisfactory results by employing -various heuristics. - -Previous versions of PKZip and other zip-compatible compression tools -were using a crude detection scheme: if more than 80% (4/5) of the bytes -found in a certain buffer are within the range [7..127], the file is -labeled as plain text, otherwise it is labeled as binary. A prominent -limitation of this scheme is the restriction to Latin-based alphabets. -Other alphabets, like Greek, Cyrillic or Asian, make extensive use of -the bytes within the range [128..255], and texts using these alphabets -are most often misidentified by this scheme; in other words, the rate -of false negatives is sometimes too high, which means that the recall -is low. Another weakness of this scheme is a reduced precision, due to -the false positives that may occur when binary files containing large -amounts of textual characters are misidentified as plain text. - -In this article we propose a new, simple detection scheme that features -a much increased precision and a near-100% recall. This scheme is -designed to work on ASCII, Unicode and other ASCII-derived alphabets, -and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) -and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings -(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. - - -The Algorithm -------------- - -The algorithm works by dividing the set of bytecodes [0..255] into three -categories: -- The white list of textual bytecodes: - 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. -- The gray list of tolerated bytecodes: - 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). -- The black list of undesired, non-textual bytecodes: - 0 (NUL) to 6, 14 to 31. - -If a file contains at least one byte that belongs to the white list and -no byte that belongs to the black list, then the file is categorized as -plain text; otherwise, it is categorized as binary. (The boundary case, -when the file is empty, automatically falls into the latter category.) - - -Rationale ---------- - -The idea behind this algorithm relies on two observations. - -The first observation is that, although the full range of 7-bit codes -[0..127] is properly specified by the ASCII standard, most control -characters in the range [0..31] are not used in practice. The only -widely-used, almost universally-portable control codes are 9 (TAB), -10 (LF) and 13 (CR). There are a few more control codes that are -recognized on a reduced range of platforms and text viewers/editors: -7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these -codes are rarely (if ever) used alone, without being accompanied by -some printable text. Even the newer, portable text formats such as -XML avoid using control characters outside the list mentioned here. - -The second observation is that most of the binary files tend to contain -control characters, especially 0 (NUL). Even though the older text -detection schemes observe the presence of non-ASCII codes from the range -[128..255], the precision rarely has to suffer if this upper range is -labeled as textual, because the files that are genuinely binary tend to -contain both control characters and codes from the upper range. On the -other hand, the upper range needs to be labeled as textual, because it -is used by virtually all ASCII extensions. In particular, this range is -used for encoding non-Latin scripts. - -Since there is no counting involved, other than simply observing the -presence or the absence of some byte values, the algorithm produces -consistent results, regardless what alphabet encoding is being used. -(If counting were involved, it could be possible to obtain different -results on a text encoded, say, using ISO-8859-16 versus UTF-8.) - -There is an extra category of plain text files that are "polluted" with -one or more black-listed codes, either by mistake or by peculiar design -considerations. In such cases, a scheme that tolerates a small fraction -of black-listed codes would provide an increased recall (i.e. more true -positives). This, however, incurs a reduced precision overall, since -false positives are more likely to appear in binary files that contain -large chunks of textual data. Furthermore, "polluted" plain text should -be regarded as binary by general-purpose text detection schemes, because -general-purpose text processing algorithms might not be applicable. -Under this premise, it is safe to say that our detection method provides -a near-100% recall. - -Experiments have been run on many files coming from various platforms -and applications. We tried plain text files, system logs, source code, -formatted office documents, compiled object code, etc. The results -confirm the optimistic assumptions about the capabilities of this -algorithm. - - --- -Cosmin Truta -Last updated: 2006-May-28 diff --git a/Sources/PerfectCZlib/gzclose.c b/Sources/PerfectCZlib/gzclose.c deleted file mode 100644 index caeb99a3..00000000 --- a/Sources/PerfectCZlib/gzclose.c +++ /dev/null @@ -1,25 +0,0 @@ -/* gzclose.c -- zlib gzclose() function - * Copyright (C) 2004, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* gzclose() is in a separate file so that it is linked in only if it is used. - That way the other gzclose functions can be used instead to avoid linking in - unneeded compression or decompression routines. */ -int ZEXPORT gzclose(file) - gzFile file; -{ -#ifndef NO_GZCOMPRESS - gz_statep state; - - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); -#else - return gzclose_r(file); -#endif -} diff --git a/Sources/PerfectCZlib/gzguts.h b/Sources/PerfectCZlib/gzguts.h deleted file mode 100644 index 990a4d25..00000000 --- a/Sources/PerfectCZlib/gzguts.h +++ /dev/null @@ -1,218 +0,0 @@ -/* gzguts.h -- zlib internal header definitions for gz* operations - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif -#endif - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include -#include "zlib.h" -#ifdef STDC -# include -# include -# include -#endif - -#ifndef _POSIX_SOURCE -# define _POSIX_SOURCE -#endif -#include - -#ifdef _WIN32 -# include -#endif - -#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) -# include -#endif - -#if defined(_WIN32) || defined(__CYGWIN__) -# define WIDECHAR -#endif - -#ifdef WINAPI_FAMILY -# define open _open -# define read _read -# define write _write -# define close _close -#endif - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif - -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS -/* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 -/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -# ifdef VMS -# define NO_vsnprintf -# endif -# ifdef __OS400__ -# define NO_vsnprintf -# endif -# ifdef __MVS__ -# define NO_vsnprintf -# endif -#endif - -/* unlike snprintf (which is required in C99), _snprintf does not guarantee - null termination of the result -- however this is only used in gzlib.c where - the result is assured to fit in the space provided */ -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -/* gz* functions always use library allocation functions */ -#ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); -#endif - -/* get errno and strerror definition */ -#if defined UNDER_CE -# include -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) -#else -# ifndef NO_STRERROR -# include -# define zstrerror() strerror(errno) -# else -# define zstrerror() "stdio error (consult errno)" -# endif -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); -#endif - -/* default memLevel */ -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif - -/* default i/o buffer size -- double this for output when reading (this and - twice this must be able to fit in an unsigned type) */ -#define GZBUFSIZE 8192 - -/* gzip modes, also provide a little integrity check on the passed structure */ -#define GZ_NONE 0 -#define GZ_READ 7247 -#define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ - -/* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ - -/* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer (double-sized when writing) */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int how; /* 0: get header, 1: copy, 2: decompress */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ -} gz_state; -typedef gz_state FAR *gz_statep; - -/* shared functions */ -void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *)); -#if defined UNDER_CE -char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); -#endif - -/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t - value -- needed when comparing unsigned to z_off64_t, which is signed - (possible z_off64_t types off_t, off64_t, and long are all signed) */ -#ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) -#else -unsigned ZLIB_INTERNAL gz_intmax OF((void)); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) -#endif diff --git a/Sources/PerfectCZlib/gzlib.c b/Sources/PerfectCZlib/gzlib.c deleted file mode 100644 index a87d3d19..00000000 --- a/Sources/PerfectCZlib/gzlib.c +++ /dev/null @@ -1,637 +0,0 @@ -/* gzlib.c -- zlib functions common to reading and writing gzip files - * Copyright (C) 2004, 2010, 2011, 2012, 2013, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -#if defined(_WIN32) && !defined(__BORLANDC__) && !defined(__MINGW32__) -# define LSEEK _lseeki64 -#else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 -#else -# define LSEEK lseek -#endif -#endif - -/* Local functions */ -local void gz_reset OF((gz_statep)); -local gzFile gz_open OF((const void *, int, const char *)); - -#if defined UNDER_CE - -/* Map the Windows error number in ERROR to a locale-dependent error message - string and return a pointer to it. Typically, the values for ERROR come - from GetLastError. - - The string pointed to shall not be modified by the application, but may be - overwritten by a subsequent call to gz_strwinerror - - The gz_strwinerror function does not change the current setting of - GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror (error) - DWORD error; -{ - static char buf[1024]; - - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } - - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } - - wcstombs(buf, msgbuf, chars + 1); - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } - - SetLastError(lasterr); - return buf; -} - -#endif /* UNDER_CE */ - -/* Reset gzip file state */ -local void gz_reset(state) - gz_statep state; -{ - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - } - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ -} - -/* Open a gzip file either by name or file descriptor. */ -local gzFile gz_open(path, fd, mode) - const void *path; - int fd; - const char *mode; -{ - gz_statep state; - z_size_t len; - int oflag; -#ifdef O_CLOEXEC - int cloexec = 0; -#endif -#ifdef O_EXCL - int exclusive = 0; -#endif - - /* check input */ - if (path == NULL) - return NULL; - - /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ - - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; -#ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; -#endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; -#ifdef O_CLOEXEC - case 'e': - cloexec = 1; - break; -#endif -#ifdef O_EXCL - case 'x': - exclusive = 1; - break; -#endif - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - break; - case 'T': - state->direct = 1; - break; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } - - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } - - /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); - return NULL; - } - state->direct = 1; /* for empty file */ - } - - /* save the path name for error messages */ -#ifdef WIDECHAR - if (fd == -2) { - len = wcstombs(NULL, path, 0); - if (len == (z_size_t)-1) - len = 0; - } - else -#endif - len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); - return NULL; - } -#ifdef WIDECHAR - if (fd == -2) - if (len) - wcstombs(state->path, path, len + 1); - else - *(state->path) = 0; - else -#endif -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->path, len + 1, "%s", (const char *)path); -#else - strcpy(state->path, path); -#endif - - /* compute the flags for open() */ - oflag = -#ifdef O_LARGEFILE - O_LARGEFILE | -#endif -#ifdef O_BINARY - O_BINARY | -#endif -#ifdef O_CLOEXEC - (cloexec ? O_CLOEXEC : 0) | -#endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | -#ifdef O_EXCL - (exclusive ? O_EXCL : 0) | -#endif - (state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))); - - /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( -#ifdef WIDECHAR - fd == -2 ? _wopen(path, oflag, 0666) : -#endif - open((const char *)path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) { - LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ - state->mode = GZ_WRITE; /* simplify later checks */ - } - - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } - - /* initialize stream */ - gz_reset(state); - - /* return stream */ - return (gzFile)state; -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; -{ - return gz_open(path, -1, mode); -} - -/* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; -{ - char *path; /* identifier for error messages */ - gzFile gz; - - if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ -#else - sprintf(path, "", fd); /* for debugging */ -#endif - gz = gz_open(path, fd, mode); - free(path); - return gz; -} - -/* -- see zlib.h -- */ -#ifdef WIDECHAR -gzFile ZEXPORT gzopen_w(path, mode) - const wchar_t *path; - const char *mode; -{ - return gz_open(path, -2, mode); -} -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; - - /* check and set requested size */ - if ((size << 1) < size) - return -1; /* need to be able to double it */ - if (size < 2) - size = 2; /* need two bytes to check magic header */ - state->want = size; - return 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzrewind(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; -{ - unsigned n; - z_off64_t ret; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; - - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; - - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } - - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } - - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } - - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->x.pos + offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - z_off64_t ret; - - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gztell64(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gztell(file) - gzFile file; -{ - z_off64_t ret; - - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -z_off64_t ZEXPORT gzoffset64(file) - gzFile file; -{ - z_off64_t offset; - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; - - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; -} - -/* -- see zlib.h -- */ -z_off_t ZEXPORT gzoffset(file) - gzFile file; -{ - z_off64_t ret; - - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzeof(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; - - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; -} - -/* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; - - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : - (state->msg == NULL ? "" : state->msg); -} - -/* -- see zlib.h -- */ -void ZEXPORT gzclearerr(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; - - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); -} - -/* Create an error message in allocated memory and set state->err and - state->msg accordingly. Free any previous error message already there. Do - not try to free or allocate space if the error is Z_MEM_ERROR (out of - memory). Simply save the error message as a static string. If there is an - allocation failure constructing the error message, then convert the error to - out of memory. */ -void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; -{ - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } - - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; - - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; - - /* for an out of memory error, return literal string when requested */ - if (err == Z_MEM_ERROR) - return; - - /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == - NULL) { - state->err = Z_MEM_ERROR; - return; - } -#if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); -#else - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); -#endif -} - -#ifndef INT_MAX -/* portably return maximum value for an int (when limits.h presumed not - available) -- we need to do this to cover cases where 2's complement not - used, since C standard permits 1's complement and sign-bit representations, - otherwise we could just use ((unsigned)-1) >> 1 */ -unsigned ZLIB_INTERNAL gz_intmax() -{ - unsigned p, q; - - p = 1; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; -} -#endif diff --git a/Sources/PerfectCZlib/gzread.c b/Sources/PerfectCZlib/gzread.c deleted file mode 100644 index 00c70bbc..00000000 --- a/Sources/PerfectCZlib/gzread.c +++ /dev/null @@ -1,655 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* gzread.c -- zlib functions for reading gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *)); -local int gz_avail OF((gz_statep)); -local int gz_look OF((gz_statep)); -local int gz_decomp OF((gz_statep)); -local int gz_fetch OF((gz_statep)); -local int gz_skip OF((gz_statep, z_off64_t)); -local z_size_t gz_read OF((gz_statep, voidp, z_size_t)); - -/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from - state->fd, and update state->eof, state->err, and state->msg as appropriate. - This function needs to loop on read(), since read() is not guaranteed to - read the number of bytes requested, depending on the type of descriptor. */ -local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; -{ - int ret; - unsigned get, max = ((unsigned)-1 >> 2) + 1; - - *have = 0; - do { - get = len - *have; - if (get > max) - get = max; - ret = read(state->fd, buf + *have, get); - if (ret <= 0) - break; - *have += (unsigned)ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; -} - -/* Load up input buffer and set eof flag if last data loaded -- return -1 on - error, 0 otherwise. Note that the eof flag is set when the end of the input - file is reached, even though there may be unused data in the buffer. Once - that data has been used, no more attempts will be made to read the file. - If strm->avail_in != 0, then the current data is moved to the beginning of - the input buffer, and then the remainder of the buffer is loaded with the - available data from the input file. */ -local int gz_avail(state) - gz_statep state; -{ - unsigned got; - z_streamp strm = &(state->strm); - - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; - unsigned const char *q = strm->next_in; - unsigned n = strm->avail_in; - do { - *p++ = *q++; - } while (--n); - } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; -} - -/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. - If this is the first time in, allocate required memory. state->how will be - left unchanged if there is no more input data available, will be set to COPY - if there is no gzip header and direct copying will be performed, or it will - be set to GZIP for decompression. If direct copying, then leftover input - data from the input buffer will be copied to the output buffer. In that - case, all further file reads will be directly to either the output buffer or - a user buffer. If decompressing, the inflate state will be initialized. - gz_look() will return 0 on success or -1 on failure. */ -local int gz_look(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; - - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } - - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } - - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is - a logical dilemma here when considering the case of a partially written - gzip file, to wit, if a single 31 byte is written, then we cannot tell - whether this is a single-byte file, or just a partially written gzip - file -- for here we assume that if a gzip file is being written, then - the header will be written in a single operation, so that reading a - single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { - inflateReset(strm); - state->how = GZIP; - state->direct = 0; - return 0; - } - - /* no gzip header -- if we were decoding gzip before, then this is trailing - garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; - return 0; - } - - /* doing raw i/o, copy any leftover input to output -- this assumes that - the output buffer is larger than the input buffer, which also assures - space for gzungetc() */ - state->x.next = state->out; - if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - } - state->how = COPY; - state->direct = 1; - return 0; -} - -/* Decompress from input to the provided next_out and avail_out in the state. - On return, state->x.have and state->x.next point to the just decompressed - data. If the gzip stream completes, state->how is reset to LOOK to look for - the next gzip stream or raw data, once state->x.have is depleted. Returns 0 - on success, -1 on failure. */ -local int gz_decomp(state) - gz_statep state; -{ - int ret = Z_OK; - unsigned had; - z_streamp strm = &(state->strm); - - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } - - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); - - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; - - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) - state->how = LOOK; - - /* good decompression */ - return 0; -} - -/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. - Data is either copied from the input file or decompressed from the input - file depending on state->how. If state->how is LOOK, then a gzip header is - looked for to determine whether to copy or decompress. Returns -1 on error, - otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the - end of the input file has been reached and all data has been processed. */ -local int gz_fetch(state) - gz_statep state; -{ - z_streamp strm = &(state->strm); - - do { - switch(state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; -} - -/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ -local int gz_skip(state, len) - gz_statep state; - z_off64_t len; -{ - unsigned n; - - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - len -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; - - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - return 0; -} - -/* Read len bytes into buf from file, or less than len up to the end of the - input. Return the number of bytes read. If zero is returned, either the - end of file was reached, or there was an error. state->err must be - consulted in that case to determine which. */ -local z_size_t gz_read(state, buf, len) - gz_statep state; - voidp buf; - z_size_t len; -{ - z_size_t got; - unsigned n; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return 0; - } - - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* set n to the maximum amount of len that fits in an unsigned int */ - n = -1; - if (n > len) - n = len; - - /* first just try copying data from the output buffer */ - if (state->x.have) { - if (state->x.have < n) - n = state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - } - - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) { - state->past = 1; /* tried to read past end */ - break; - } - - /* need output data -- for small len or new stream load up our output - buffer */ - else if (state->how == LOOK || n < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return 0; - continue; /* no progress yet -- go back to copy above */ - /* the copy above assures that we will leave with space in the - output buffer, allowing at least one gzungetc() to succeed */ - } - - /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, (unsigned char *)buf, n, &n) == -1) - return 0; - } - - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - state->strm.avail_out = n; - state->strm.next_out = (unsigned char *)buf; - if (gz_decomp(state) == -1) - return 0; - n = state->x.have; - state->x.have = 0; - } - - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len); - - /* return number of bytes read into user buffer */ - return got; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); - return -1; - } - - /* read len or fewer bytes to buf */ - len = gz_read(state, buf, len); - - /* check for an error */ - if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - - /* return the number of bytes read (this is assured to fit in an int) */ - return (int)len; -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfread(buf, size, nitems, file) - voidp buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return 0; - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* read len or fewer bytes to buf, return the number of full items read */ - return len ? gz_read(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -#else -# undef gzgetc -#endif -int ZEXPORT gzgetc(file) - gzFile file; -{ - int ret; - unsigned char buf[1]; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } - - /* nothing there -- try gz_read() */ - ret = gz_read(state, buf, 1); - return ret < 1 ? -1 : buf[0]; -} - -int ZEXPORT gzgetc_(file) -gzFile file; -{ - return gzgetc(file); -} - -/* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } - - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = (unsigned char)c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- - append a terminating zero to the string (we don't check for a zero in - the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } - - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; - - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); - - /* return terminated string, or if nothing, end of file */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzdirect(file) - gzFile file; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* if the state is not known, but we can find out, then do so (this is - mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); - - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_r(file) - gzFile file; -{ - int ret, err; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; - - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; -} diff --git a/Sources/PerfectCZlib/gzwrite.c b/Sources/PerfectCZlib/gzwrite.c deleted file mode 100644 index c39cbabf..00000000 --- a/Sources/PerfectCZlib/gzwrite.c +++ /dev/null @@ -1,665 +0,0 @@ -#pragma clang diagnostic ignored "-Wconversion" -/* gzwrite.c -- zlib functions for writing gzip files - * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "gzguts.h" - -/* Local functions */ -local int gz_init OF((gz_statep)); -local int gz_comp OF((gz_statep, int)); -local int gz_zero OF((gz_statep, z_off64_t)); -local z_size_t gz_write OF((gz_statep, voidpc, z_size_t)); - -/* Initialize state for writing a gzip file. Mark initialization by setting - state->size to non-zero. Return -1 on a memory allocation failure, or 0 on - success. */ -local int gz_init(state) - gz_statep state; -{ - int ret; - z_streamp strm = &(state->strm); - - /* allocate input buffer (double size for gzprintf) */ - state->in = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - strm->next_in = NULL; - } - - /* mark state as initialized */ - state->size = state->want; - - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; -} - -/* Compress whatever is at avail_in and next_in and write to the output file. - Return -1 if there is an error writing to the output file or if gz_init() - fails to allocate memory, otherwise 0. flush is assumed to be a valid - deflate() flush value. If flush is Z_FINISH, then the deflate() state is - reset to start a new gzip stream. If gz->direct is true, then simply write - to the output file without compressing, and ignore flush. */ -local int gz_comp(state, flush) - gz_statep state; - int flush; -{ - int ret, writ; - unsigned have, put, max = ((unsigned)-1 >> 2) + 1; - z_streamp strm = &(state->strm); - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; - - /* write directly if requested */ - if (state->direct) { - while (strm->avail_in) { - put = strm->avail_in > max ? max : strm->avail_in; - writ = write(state->fd, strm->next_in, put); - if (writ < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in -= (unsigned)writ; - strm->next_in += writ; - } - return 0; - } - - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if - doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - while (strm->next_out > state->x.next) { - put = strm->next_out - state->x.next > (int)max ? max : - (unsigned)(strm->next_out - state->x.next); - writ = write(state->fd, state->x.next, put); - if (writ < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - state->x.next += writ; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - } - } - - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); - - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - deflateReset(strm); - - /* all done, no errors */ - return 0; -} - -/* Compress len zeros to output. Return -1 on a write error or memory - allocation failure by gz_comp(), or 0 on success. */ -local int gz_zero(state, len) - gz_statep state; - z_off64_t len; -{ - int first; - unsigned n; - z_streamp strm = &(state->strm); - - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; -} - -/* Write len bytes from buf to file. Return the number of bytes written. If - the returned value is less than len, then there was an error. */ -local z_size_t gz_write(state, buf, len) - gz_statep state; - voidpc buf; - z_size_t len; -{ - z_size_t put = len; - - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; - - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } - - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - unsigned have, copy; - - if (state->strm.avail_in == 0) - state->strm.next_in = state->in; - have = (unsigned)((state->strm.next_in + state->strm.avail_in) - - state->in); - copy = state->size - have; - if (copy > len) - copy = len; - memcpy(state->in + have, buf, copy); - state->strm.avail_in += copy; - state->x.pos += copy; - buf = (const char *)buf + copy; - len -= copy; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } - else { - /* consume whatever's left in the input buffer */ - if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - - /* directly compress user buffer to file */ - state->strm.next_in = (z_const Bytef *)buf; - do { - unsigned n = (unsigned)-1; - if (n > len) - n = len; - state->strm.avail_in = n; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - len -= n; - } while (len); - } - - /* input was all buffered or compressed */ - return put; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* since an int is returned, make sure len fits in one, otherwise return - with an error (this avoids a flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } - - /* write len bytes from buf (the return value will fit in an int) */ - return (int)gz_write(state, buf, len); -} - -/* -- see zlib.h -- */ -z_size_t ZEXPORT gzfwrite(buf, size, nitems, file) - voidpc buf; - z_size_t size; - z_size_t nitems; - gzFile file; -{ - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; - - /* compute bytes to read -- error on overflow */ - len = nitems * size; - if (size && len / size != nitems) { - gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); - return 0; - } - - /* write len bytes to buf, return the number of full items written */ - return len ? gz_write(state, buf, len) / size : 0; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned have; - unsigned char buf[1]; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } - - /* try writing to input buffer for speed (state->size == 0 if buffer not - initialized) */ - if (state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = (unsigned char)c; - strm->avail_in++; - state->x.pos++; - return c & 0xff; - } - } - - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = (unsigned char)c; - if (gz_write(state, buf, 1) != 1) - return -1; - return c & 0xff; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzputs(file, str) - gzFile file; - const char *str; -{ - int ret; - z_size_t len; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; - - /* write string */ - len = strlen(str); - ret = gz_write(state, str, len); - return ret == 0 && len != 0 ? -1 : ret; -} - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -#include - -/* -- see zlib.h -- */ -int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) -{ - int len; - unsigned left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->err; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(next, format, va); - for (len = 0; len < state->size; len++) - if (next[len] == 0) break; -# else - len = vsprintf(next, format, va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(next, state->size, format, va); - len = strlen(next); -# else - len = vsnprintf(next, state->size, format, va); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += (unsigned)len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memcpy(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return len; -} - -int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) -{ - va_list va; - int ret; - - va_start(va, format); - ret = gzvprintf(file, format, va); - va_end(va); - return ret; -} - -#else /* !STDC && !Z_HAVE_STDARG_H */ - -/* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - unsigned len, left; - char *next; - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that can really pass pointer in ints */ - if (sizeof(int) != sizeof(void *)) - return Z_STREAM_ERROR; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return state->error; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->error; - } - - /* do the printf() into the input buffer, put length in len -- the input - buffer is double-sized just for this function, so there is guaranteed to - be state->size bytes available after the current contents */ - if (strm->avail_in == 0) - strm->next_in = state->in; - next = (char *)(strm->next_in + strm->avail_in); - next[state->size - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, - a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (next[len] == 0) - break; -# else - len = sprintf(next, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, - a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, - a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(next); -# else - len = snprintf(next, state->size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - - /* check that printf() results fit in buffer */ - if (len == 0 || len >= state->size || next[state->size - 1] != 0) - return 0; - - /* update buffer and position, compress first half if past that */ - strm->avail_in += len; - state->x.pos += len; - if (strm->avail_in >= state->size) { - left = strm->avail_in - state->size; - strm->avail_in = state->size; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return state->err; - memcpy(state->in, state->in + state->size, left); - strm->next_in = state->in; - strm->avail_in = left; - } - return (int)len; -} - -#endif - -/* -- see zlib.h -- */ -int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; -{ - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* compress remaining data with requested flush */ - (void)gz_comp(state, flush); - return state->err; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_statep state; - z_streamp strm; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); - - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; - - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return state->err; - } - - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; -} - -/* -- see zlib.h -- */ -int ZEXPORT gzclose_w(file) - gzFile file; -{ - int ret = Z_OK; - gz_statep state; - - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; - - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } - - /* flush, free memory, and close file */ - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; -} diff --git a/Sources/PerfectCZlib/include/czlib.h b/Sources/PerfectCZlib/include/czlib.h deleted file mode 100755 index a7210132..00000000 --- a/Sources/PerfectCZlib/include/czlib.h +++ /dev/null @@ -1,5 +0,0 @@ - -#include "../zconf.h" -#include "../zlib.h" -#include "../zutil.h" -#include "../inftrees.h" diff --git a/Sources/PerfectCZlib/include/inflate.h b/Sources/PerfectCZlib/include/inflate.h deleted file mode 100644 index a46cce6b..00000000 --- a/Sources/PerfectCZlib/include/inflate.h +++ /dev/null @@ -1,125 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD = 16180, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* State maintained between inflate() calls -- approximately 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/Sources/PerfectCZlib/include/inftrees.h b/Sources/PerfectCZlib/include/inftrees.h deleted file mode 100644 index baa53a0b..00000000 --- a/Sources/PerfectCZlib/include/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/Sources/PerfectCZlib/include/module.modulemap b/Sources/PerfectCZlib/include/module.modulemap deleted file mode 100644 index ef1f495c..00000000 --- a/Sources/PerfectCZlib/include/module.modulemap +++ /dev/null @@ -1,4 +0,0 @@ -module PerfectCZlib { - header "czlib.h" - export * -} diff --git a/Sources/PerfectCZlib/include/zconf.h b/Sources/PerfectCZlib/include/zconf.h deleted file mode 100644 index 77398c11..00000000 --- a/Sources/PerfectCZlib/include/zconf.h +++ /dev/null @@ -1,534 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -#ifdef Z_SOLO - typedef unsigned long z_size_t; -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#if 1 /* was set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#if 1 /* was set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/Sources/PerfectCZlib/include/zlib.h b/Sources/PerfectCZlib/include/zlib.h deleted file mode 100644 index 69fbb978..00000000 --- a/Sources/PerfectCZlib/include/zlib.h +++ /dev/null @@ -1,1910 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.9, December 31st, 2016 - - Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.9" -#define ZLIB_VERNUM 0x1290 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 9 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip and raw deflate streams in - memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in the case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte will go here */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use by the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field for deflate() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary. Some output may be provided even if - flush is zero. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more ouput - in that case. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed - codes block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this - function must be called again with Z_FINISH and more output space (updated - avail_out) but no more input data, until it returns with Z_STREAM_END or an - error. After deflate has returned Z_STREAM_END, the only possible operations - on the stream are deflateReset or deflateEnd. - - Z_FINISH can be used in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, avail_out must be at least the value returned by deflateBound (see - below). Then deflate is guaranteed to return Z_STREAM_END. If not enough - output space is provided, deflate will not return Z_STREAM_END, and it must - be called again as described above. - - deflate() sets strm->adler to the Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is - considered binary. This field is only for information purposes and does not - affect the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL or the state was inadvertently written over - by the application), or Z_BUF_ERROR if no progress is possible (for example - avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and - deflate() can be called again with more input and more output space to - continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provide input is not - read or consumed. Any memory allocation will be deferred to the first call - of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them - to use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression. - Actual decompression will be done by inflate(). So next_in, and avail_in, - next_out, and avail_out are unused and unchanged. The current - implementation of inflateInit() does not process any header information -- - that is deferred until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_on are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed Adler-32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was possible or if there was not enough room in the output - buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute a check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - Adler-32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by deflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, then the input available so far is compressed with the - old level and strategy using deflate(strm, Z_BLOCK). There are three - approaches for the compression levels 0, 1..3, and 4..9 respectively. The - new level and strategy will take effect at the next call of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an Adler-32 or a CRC-32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will not automatically decode concatenated gzip streams. - inflate() will return Z_STREAM_END at the end of the gzip stream. The state - would need to be reset to continue decoding a subsequent gzip stream. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler-32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above, or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the default - behavior of inflate(), which expects a zlib header and trailer around the - deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero -- buf is ignored in that - case -- and inflateBack() will return a buffer error. inflateBack() will - call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. - out() should return zero on success, or non-zero on failure. If out() - returns non-zero, inflateBack() will return with an error. Neither in() nor - out() are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: ZLIB_DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed data. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Three times that size in buffer space is allocated. A larger buffer - size of, for example, 64K or 128K bytes will noticeably increase the speed - of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. Previously provided - data is flushed before the parameter change. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); -/* - Read up to nitems items of size size from file to buf, otherwise operating - as gzread() does. This duplicates the interface of stdio's fread(), with - size_t request and return types. If the library defines size_t, then - z_size_t is identical to size_t. If not, then z_size_t is an unsigned - integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevetheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, reseting and retrying on end-of-file, when size is not 1. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); -/* - gzfwrite() writes nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code in case - of error. The number of uncompressed bytes written is limited to 8191, or - one less than the buffer size given to gzbuffer(). The caller should assure - that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. - This can be determined using zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatenated gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as adler32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as crc32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#endif - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/Sources/PerfectCZlib/infback.c b/Sources/PerfectCZlib/infback.c deleted file mode 100644 index 59679ecb..00000000 --- a/Sources/PerfectCZlib/infback.c +++ /dev/null @@ -1,640 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = (uInt)windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; - - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/Sources/PerfectCZlib/inffast.c b/Sources/PerfectCZlib/inffast.c deleted file mode 100644 index a15876d4..00000000 --- a/Sources/PerfectCZlib/inffast.c +++ /dev/null @@ -1,321 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010, 2013, 2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in; - last = in + (strm->avail_in - 5); - out = strm->next_out; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - *out++ = (unsigned char)(here.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(*in++) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - *out++ = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - *out++ = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - *out++ = *from++; - } while (--len); - continue; - } -#endif - } - from = window; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = window; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - *out++ = *from++; - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - *out++ = *from++; - *out++ = *from++; - *out++ = *from++; - len -= 3; - } while (len > 2); - if (len) { - *out++ = *from++; - if (len > 1) - *out++ = *from++; - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in; - strm->next_out = out; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/Sources/PerfectCZlib/inffast.h b/Sources/PerfectCZlib/inffast.h deleted file mode 100644 index e5c1aa4c..00000000 --- a/Sources/PerfectCZlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/Sources/PerfectCZlib/inffixed.h b/Sources/PerfectCZlib/inffixed.h deleted file mode 100644 index d6283277..00000000 --- a/Sources/PerfectCZlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. - It is part of the implementation of this library and is - subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/Sources/PerfectCZlib/inflate.c b/Sources/PerfectCZlib/inflate.c deleted file mode 100644 index ac333e8c..00000000 --- a/Sources/PerfectCZlib/inflate.c +++ /dev/null @@ -1,1561 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); - -local int inflateStateCheck(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 5; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; -#endif - } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->strm = strm; - state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += (uInt)bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, end, copy) -z_streamp strm; -const Bytef *end; -unsigned copy; -{ - struct inflate_state FAR *state; - unsigned dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - if (len > 15 || len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; - } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if ((state->wrap & 4) && ( -#ifdef GUNZIP - state->flags ? hold : -#endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if ((state->wrap & 4) && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long dictid; - int ret; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -const unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - state->sane = !subvert; - return Z_OK; -#else - (void)subvert; - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) - return -(1L << 16); - state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} - -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long)-1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} diff --git a/Sources/PerfectCZlib/inflate.h b/Sources/PerfectCZlib/inflate.h deleted file mode 100644 index a46cce6b..00000000 --- a/Sources/PerfectCZlib/inflate.h +++ /dev/null @@ -1,125 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD = 16180, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* State maintained between inflate() calls -- approximately 7K bytes, not - including the allocated sliding window, which is up to 32K bytes. */ -struct inflate_state { - z_streamp strm; /* pointer back to this zlib stream */ - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip, - bit 2 true to validate check value */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/Sources/PerfectCZlib/inftrees.c b/Sources/PerfectCZlib/inftrees.c deleted file mode 100644 index fa27dcbd..00000000 --- a/Sources/PerfectCZlib/inftrees.c +++ /dev/null @@ -1,304 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2016 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.9 Copyright 1995-2016 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - unsigned match; /* use base and extra for symbol >= match */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 192, 79}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - match = 20; - break; - case LENS: - base = lbase; - extra = lext; - match = 257; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - match = 0; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if (work[sym] + 1U < match) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if (work[sym] >= match) { - here.op = (unsigned char)(extra[work[sym] - match]); - here.val = base[work[sym] - match]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* fill in remaining table entry if code is incomplete (guaranteed to have - at most one remaining entry, since if the code is incomplete, the - maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/Sources/PerfectCZlib/inftrees.h b/Sources/PerfectCZlib/inftrees.h deleted file mode 100644 index baa53a0b..00000000 --- a/Sources/PerfectCZlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/Sources/PerfectCZlib/make_vms.com b/Sources/PerfectCZlib/make_vms.com deleted file mode 100644 index 65e9d0cb..00000000 --- a/Sources/PerfectCZlib/make_vms.com +++ /dev/null @@ -1,867 +0,0 @@ -$! make libz under VMS written by -$! Martin P.J. Zinser -$! -$! In case of problems with the install you might contact me at -$! zinser@zinser.no-ip.info(preferred) or -$! martin.zinser@eurexchange.com (work) -$! -$! Make procedure history for Zlib -$! -$!------------------------------------------------------------------------------ -$! Version history -$! 0.01 20060120 First version to receive a number -$! 0.02 20061008 Adapt to new Makefile.in -$! 0.03 20091224 Add support for large file check -$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite -$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in -$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples -$! subdir path, update module search in makefile.in -$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned -$! shared image creation -$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared -$! image -$! 0.09 20120305 SMS. P1 sets builder ("MMK", "MMS", " " (built-in)). -$! "" -> automatic, preference: MMK, MMS, built-in. -$! -$ on error then goto err_exit -$! -$ true = 1 -$ false = 0 -$ tmpnam = "temp_" + f$getjpi("","pid") -$ tt = tmpnam + ".txt" -$ tc = tmpnam + ".c" -$ th = tmpnam + ".h" -$ define/nolog tconfig 'th' -$ its_decc = false -$ its_vaxc = false -$ its_gnuc = false -$ s_case = False -$! -$! Setup variables holding "config" information -$! -$ Make = "''p1'" -$ name = "Zlib" -$ version = "?.?.?" -$ v_string = "ZLIB_VERSION" -$ v_file = "zlib.h" -$ ccopt = "/include = []" -$ lopts = "" -$ dnsrl = "" -$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in" -$ conf_check_string = "" -$ linkonly = false -$ optfile = name + ".opt" -$ mapfile = name + ".map" -$ libdefs = "" -$ vax = f$getsyi("HW_MODEL").lt.1024 -$ axp = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096 -$ ia64 = f$getsyi("HW_MODEL").ge.4096 -$! -$! 2012-03-05 SMS. -$! Why is this needed? And if it is needed, why not simply ".not. vax"? -$! -$!!! if axp .or. ia64 then set proc/parse=extended -$! -$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL") -$ mydef = F$parse(whoami,,,"DEVICE") -$ mydir = f$parse(whoami,,,"DIRECTORY") - "][" -$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type") -$! -$! Check for MMK/MMS -$! -$ if (Make .eqs. "") -$ then -$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS" -$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK" -$ else -$ Make = f$edit( Make, "trim") -$ endif -$! -$ gosub find_version -$! -$ open/write topt tmp.opt -$ open/write optf 'optfile' -$! -$ gosub check_opts -$! -$! Look for the compiler used -$! -$ gosub check_compiler -$ close topt -$ close optf -$! -$ if its_decc -$ then -$ ccopt = "/prefix=all" + ccopt -$ if f$trnlnm("SYS") .eqs. "" -$ then -$ if axp -$ then -$ define sys sys$library: -$ else -$ ccopt = "/decc" + ccopt -$ define sys decc$library_include: -$ endif -$ endif -$! -$! 2012-03-05 SMS. -$! Why /NAMES = AS_IS? Why not simply ".not. vax"? And why not on VAX? -$! -$ if axp .or. ia64 -$ then -$ ccopt = ccopt + "/name=as_is/opt=(inline=speed)" -$ s_case = true -$ endif -$ endif -$ if its_vaxc .or. its_gnuc -$ then -$ if f$trnlnm("SYS").eqs."" then define sys sys$library: -$ endif -$! -$! Build a fake configure input header -$! -$ open/write conf_hin config.hin -$ write conf_hin "#undef _LARGEFILE64_SOURCE" -$ close conf_hin -$! -$! -$ i = 0 -$FIND_ACONF: -$ fname = f$element(i,"#",aconf_in_file) -$ if fname .eqs. "#" then goto AMISS_ERR -$ if f$search(fname) .eqs. "" -$ then -$ i = i + 1 -$ goto find_aconf -$ endif -$ open/read/err=aconf_err aconf_in 'fname' -$ open/write aconf zconf.h -$ACONF_LOOP: -$ read/end_of_file=aconf_exit aconf_in line -$ work = f$edit(line, "compress,trim") -$ if f$extract(0,6,work) .nes. "#undef" -$ then -$ if f$extract(0,12,work) .nes. "#cmakedefine" -$ then -$ write aconf line -$ endif -$ else -$ cdef = f$element(1," ",work) -$ gosub check_config -$ endif -$ goto aconf_loop -$ACONF_EXIT: -$ write aconf "" -$ write aconf "/* VMS specifics added by make_vms.com: */" -$ write aconf "#define VMS 1" -$ write aconf "#include " -$ write aconf "#include " -$ write aconf "#ifdef _LARGEFILE" -$ write aconf "# define off64_t __off64_t" -$ write aconf "# define fopen64 fopen" -$ write aconf "# define fseeko64 fseeko" -$ write aconf "# define lseek64 lseek" -$ write aconf "# define ftello64 ftell" -$ write aconf "#endif" -$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)" -$ write aconf "# define HAVE_VSNPRINTF" -$ write aconf "#endif" -$ close aconf_in -$ close aconf -$ if f$search("''th'") .nes. "" then delete 'th';* -$! Build the thing plain or with mms -$! -$ write sys$output "Compiling Zlib sources ..." -$ if make.eqs."" -$ then -$ if (f$search( "example.obj;*") .nes. "") then delete example.obj;* -$ if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;* -$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - - adler32.c zlib.h zconf.h -$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - - compress.c zlib.h zconf.h -$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - - crc32.c zlib.h zconf.h -$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - - deflate.c deflate.h zutil.h zlib.h zconf.h -$ CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" - - gzclose.c zutil.h zlib.h zconf.h -$ CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" - - gzlib.c zutil.h zlib.h zconf.h -$ CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" - - gzread.c zutil.h zlib.h zconf.h -$ CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" - - gzwrite.c zutil.h zlib.h zconf.h -$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" - - infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h -$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - - inffast.c zutil.h zlib.h zconf.h inffast.h -$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - - inflate.c zutil.h zlib.h zconf.h infblock.h -$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - - inftrees.c zutil.h zlib.h zconf.h inftrees.h -$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - - trees.c deflate.h zutil.h zlib.h zconf.h -$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - - uncompr.c zlib.h zconf.h -$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - - zutil.c zutil.h zlib.h zconf.h -$ write sys$output "Building Zlib ..." -$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ -$ write sys$output "Building example..." -$ CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" - - [.test]example.c zlib.h zconf.h -$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb -$ write sys$output "Building minigzip..." -$ CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" - - [.test]minigzip.c zlib.h zconf.h -$ call make minigzip.exe - - "LINK minigzip,libz.olb/lib" - - minigzip.obj libz.olb -$ else -$ gosub crea_mms -$ write sys$output "Make ''name' ''version' with ''Make' " -$ 'make' -$ endif -$! -$! Create shareable image -$! -$ gosub crea_olist -$ write sys$output "Creating libzshr.exe" -$ call map_2_shopt 'mapfile' 'optfile' -$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt -$ write sys$output "Zlib build completed" -$ delete/nolog tmp.opt;* -$ exit -$AMISS_ERR: -$ write sys$output "No source for config.hin found." -$ write sys$output "Tried any of ''aconf_in_file'" -$ goto err_exit -$CC_ERR: -$ write sys$output "C compiler required to build ''name'" -$ goto err_exit -$ERR_EXIT: -$ set message/facil/ident/sever/text -$ close/nolog optf -$ close/nolog topt -$ close/nolog aconf_in -$ close/nolog aconf -$ close/nolog out -$ close/nolog min -$ close/nolog mod -$ close/nolog h_in -$ write sys$output "Exiting..." -$ exit 2 -$! -$! -$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES -$ V = 'F$Verify(0) -$! P1 = What we are trying to make -$! P2 = Command to make it -$! P3 - P8 What it depends on -$ -$ If F$Search(P1) .Eqs. "" Then Goto Makeit -$ Time = F$CvTime(F$File(P1,"RDT")) -$arg=3 -$Loop: -$ Argument = P'arg -$ If Argument .Eqs. "" Then Goto Exit -$ El=0 -$Loop2: -$ File = F$Element(El," ",Argument) -$ If File .Eqs. " " Then Goto Endl -$ AFile = "" -$Loop3: -$ OFile = AFile -$ AFile = F$Search(File) -$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl -$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit -$ Goto Loop3 -$NextEL: -$ El = El + 1 -$ Goto Loop2 -$EndL: -$ arg=arg+1 -$ If arg .Le. 8 Then Goto Loop -$ Goto Exit -$ -$Makeit: -$ VV=F$VERIFY(0) -$ write sys$output P2 -$ 'P2 -$ VV='F$Verify(VV) -$Exit: -$ If V Then Set Verify -$ENDSUBROUTINE -$!------------------------------------------------------------------------------ -$! -$! Check command line options and set symbols accordingly -$! -$!------------------------------------------------------------------------------ -$! Version history -$! 0.01 20041206 First version to receive a number -$! 0.02 20060126 Add new "HELP" target -$ CHECK_OPTS: -$ i = 1 -$ OPT_LOOP: -$ if i .lt. 9 -$ then -$ cparm = f$edit(p'i',"upcase") -$! -$! Check if parameter actually contains something -$! -$ if f$edit(cparm,"trim") .nes. "" -$ then -$ if cparm .eqs. "DEBUG" -$ then -$ ccopt = ccopt + "/noopt/deb" -$ lopts = lopts + "/deb" -$ endif -$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ ccopt = ccopt + f$extract(start,len,cparm) -$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) - - then s_case = true -$ endif -$ if cparm .eqs. "LINK" then linkonly = true -$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ lopts = lopts + f$extract(start,len,cparm) -$ endif -$ if f$locate("CC=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ cc_com = f$extract(start,len,cparm) - if (cc_com .nes. "DECC") .and. - - (cc_com .nes. "VAXC") .and. - - (cc_com .nes. "GNUC") -$ then -$ write sys$output "Unsupported compiler choice ''cc_com' ignored" -$ write sys$output "Use DECC, VAXC, or GNUC instead" -$ else -$ if cc_com .eqs. "DECC" then its_decc = true -$ if cc_com .eqs. "VAXC" then its_vaxc = true -$ if cc_com .eqs. "GNUC" then its_gnuc = true -$ endif -$ endif -$ if f$locate("MAKE=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ mmks = f$extract(start,len,cparm) -$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS") -$ then -$ make = mmks -$ else -$ write sys$output "Unsupported make choice ''mmks' ignored" -$ write sys$output "Use MMK or MMS instead" -$ endif -$ endif -$ if cparm .eqs. "HELP" then gosub bhelp -$ endif -$ i = i + 1 -$ goto opt_loop -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Look for the compiler used -$! -$! Version history -$! 0.01 20040223 First version to receive a number -$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists -$! 0.03 20060202 Extend handling of GNU C -$! 0.04 20090402 Compaq -> hp -$CHECK_COMPILER: -$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) -$ then -$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "") -$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "") -$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "") -$ endif -$! -$! Exit if no compiler available -$! -$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) -$ then goto CC_ERR -$ else -$ if its_decc -$ then -$ write sys$output "CC compiler check ... hp C" -$ if f$trnlnm("decc$no_rooted_search_lists") .nes. "" -$ then -$ dnrsl = f$trnlnm("decc$no_rooted_search_lists") -$ endif -$ define/nolog decc$no_rooted_search_lists 1 -$ else -$ if its_vaxc then write sys$output "CC compiler check ... VAX C" -$ if its_gnuc -$ then -$ write sys$output "CC compiler check ... GNU C" -$ if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib" -$ if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib" -$ cc = "gcc" -$ endif -$ if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share" -$ if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share" -$ endif -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! If MMS/MMK are available dump out the descrip.mms if required -$! -$CREA_MMS: -$ write sys$output "Creating descrip.mms..." -$ create descrip.mms -$ open/append out descrip.mms -$ copy sys$input: out -$ deck -# descrip.mms: MMS description file for building zlib on VMS -# written by Martin P.J. Zinser -# - -OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\ - gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\ - deflate.obj, trees.obj, zutil.obj, inflate.obj, \ - inftrees.obj, inffast.obj - -$ eod -$ write out "CFLAGS=", ccopt -$ write out "LOPTS=", lopts -$ write out "all : example.exe minigzip.exe libz.olb" -$ copy sys$input: out -$ deck - @ write sys$output " Example applications available" - -libz.olb : libz.olb($(OBJS)) - @ write sys$output " libz available" - -example.exe : example.obj libz.olb - link $(LOPTS) example,libz.olb/lib - -minigzip.exe : minigzip.obj libz.olb - link $(LOPTS) minigzip,libz.olb/lib - -clean : - delete *.obj;*,libz.olb;*,*.opt;*,*.exe;* - - -# Other dependencies. -adler32.obj : adler32.c zutil.h zlib.h zconf.h -compress.obj : compress.c zlib.h zconf.h -crc32.obj : crc32.c zutil.h zlib.h zconf.h -deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h -example.obj : [.test]example.c zlib.h zconf.h -gzclose.obj : gzclose.c zutil.h zlib.h zconf.h -gzlib.obj : gzlib.c zutil.h zlib.h zconf.h -gzread.obj : gzread.c zutil.h zlib.h zconf.h -gzwrite.obj : gzwrite.c zutil.h zlib.h zconf.h -inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h -inflate.obj : inflate.c zutil.h zlib.h zconf.h -inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h -minigzip.obj : [.test]minigzip.c zlib.h zconf.h -trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h -uncompr.obj : uncompr.c zlib.h zconf.h -zutil.obj : zutil.c zutil.h zlib.h zconf.h -infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h -$ eod -$ close out -$ return -$!------------------------------------------------------------------------------ -$! -$! Read list of core library sources from makefile.in and create options -$! needed to build shareable image -$! -$CREA_OLIST: -$ open/read min makefile.in -$ open/write mod modules.opt -$ src_check_list = "OBJZ =#OBJG =" -$MRLOOP: -$ read/end=mrdone min rec -$ i = 0 -$SRC_CHECK_LOOP: -$ src_check = f$element(i, "#", src_check_list) -$ i = i+1 -$ if src_check .eqs. "#" then goto mrloop -$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop -$ rec = rec - src_check -$ gosub extra_filnam -$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop -$MRSLOOP: -$ read/end=mrdone min rec -$ gosub extra_filnam -$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop -$MRDONE: -$ close min -$ close mod -$ return -$!------------------------------------------------------------------------------ -$! -$! Take record extracted in crea_olist and split it into single filenames -$! -$EXTRA_FILNAM: -$ myrec = f$edit(rec - "\", "trim,compress") -$ i = 0 -$FELOOP: -$ srcfil = f$element(i," ", myrec) -$ if (srcfil .nes. " ") -$ then -$ write mod f$parse(srcfil,,,"NAME"), ".obj" -$ i = i + 1 -$ goto feloop -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Find current Zlib version number -$! -$FIND_VERSION: -$ open/read h_in 'v_file' -$hloop: -$ read/end=hdone h_in rec -$ rec = f$edit(rec,"TRIM") -$ if (f$extract(0,1,rec) .nes. "#") then goto hloop -$ rec = f$edit(rec - "#", "TRIM") -$ if f$element(0," ",rec) .nes. "define" then goto hloop -$ if f$element(1," ",rec) .eqs. v_string -$ then -$ version = 'f$element(2," ",rec)' -$ goto hdone -$ endif -$ goto hloop -$hdone: -$ close h_in -$ return -$!------------------------------------------------------------------------------ -$! -$CHECK_CONFIG: -$! -$ in_ldef = f$locate(cdef,libdefs) -$ if (in_ldef .lt. f$length(libdefs)) -$ then -$ write aconf "#define ''cdef' 1" -$ libdefs = f$extract(0,in_ldef,libdefs) + - - f$extract(in_ldef + f$length(cdef) + 1, - - f$length(libdefs) - in_ldef - f$length(cdef) - 1, - - libdefs) -$ else -$ if (f$type('cdef') .eqs. "INTEGER") -$ then -$ write aconf "#define ''cdef' ", 'cdef' -$ else -$ if (f$type('cdef') .eqs. "STRING") -$ then -$ write aconf "#define ''cdef' ", """", '''cdef'', """" -$ else -$ gosub check_cc_def -$ endif -$ endif -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Check if this is a define relating to the properties of the C/C++ -$! compiler -$! -$ CHECK_CC_DEF: -$ if (cdef .eqs. "_LARGEFILE64_SOURCE") -$ then -$ copy sys$input: 'tc' -$ deck -#include "tconfig" -#define _LARGEFILE -#include - -int main(){ -FILE *fp; - fp = fopen("temp.txt","r"); - fseeko(fp,1,SEEK_SET); - fclose(fp); -} - -$ eod -$ test_inv = false -$ comm_h = false -$ gosub cc_prop_check -$ return -$ endif -$ write aconf "/* ", line, " */" -$ return -$!------------------------------------------------------------------------------ -$! -$! Check for properties of C/C++ compiler -$! -$! Version history -$! 0.01 20031020 First version to receive a number -$! 0.02 20031022 Added logic for defines with value -$! 0.03 20040309 Make sure local config file gets not deleted -$! 0.04 20041230 Also write include for configure run -$! 0.05 20050103 Add processing of "comment defines" -$CC_PROP_CHECK: -$ cc_prop = true -$ is_need = false -$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true) -$ if f$search(th) .eqs. "" then create 'th' -$ set message/nofac/noident/nosever/notext -$ on error then continue -$ cc 'tmpnam' -$ if .not. ($status) then cc_prop = false -$ on error then continue -$! The headers might lie about the capabilities of the RTL -$ link 'tmpnam',tmp.opt/opt -$ if .not. ($status) then cc_prop = false -$ set message/fac/ident/sever/text -$ on error then goto err_exit -$ delete/nolog 'tmpnam'.*;*/exclude='th' -$ if (cc_prop .and. .not. is_need) .or. - - (.not. cc_prop .and. is_need) -$ then -$ write sys$output "Checking for ''cdef'... yes" -$ if f$type('cdef_val'_yes) .nes. "" -$ then -$ if f$type('cdef_val'_yes) .eqs. "INTEGER" - - then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes) -$ if f$type('cdef_val'_yes) .eqs. "STRING" - - then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes) -$ else -$ call write_config f$fao("#define !AS 1",cdef) -$ endif -$ if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. - - (cdef .eqs. "_LARGEFILE64_SOURCE") then - - call write_config f$string("#define _LARGEFILE 1") -$ else -$ write sys$output "Checking for ''cdef'... no" -$ if (comm_h) -$ then - call write_config f$fao("/* !AS */",line) -$ else -$ if f$type('cdef_val'_no) .nes. "" -$ then -$ if f$type('cdef_val'_no) .eqs. "INTEGER" - - then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no) -$ if f$type('cdef_val'_no) .eqs. "STRING" - - then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no) -$ else -$ call write_config f$fao("#undef !AS",cdef) -$ endif -$ endif -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Check for properties of C/C++ compiler with multiple result values -$! -$! Version history -$! 0.01 20040127 First version -$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05 -$CC_MPROP_CHECK: -$ cc_prop = true -$ i = 1 -$ idel = 1 -$ MT_LOOP: -$ if f$type(result_'i') .eqs. "STRING" -$ then -$ set message/nofac/noident/nosever/notext -$ on error then continue -$ cc 'tmpnam'_'i' -$ if .not. ($status) then cc_prop = false -$ on error then continue -$! The headers might lie about the capabilities of the RTL -$ link 'tmpnam'_'i',tmp.opt/opt -$ if .not. ($status) then cc_prop = false -$ set message/fac/ident/sever/text -$ on error then goto err_exit -$ delete/nolog 'tmpnam'_'i'.*;* -$ if (cc_prop) -$ then -$ write sys$output "Checking for ''cdef'... ", mdef_'i' -$ if f$type(mdef_'i') .eqs. "INTEGER" - - then call write_config f$fao("#define !AS !UL",cdef,mdef_'i') -$ if f$type('cdef_val'_yes) .eqs. "STRING" - - then call write_config f$fao("#define !AS !AS",cdef,mdef_'i') -$ goto msym_clean -$ else -$ i = i + 1 -$ goto mt_loop -$ endif -$ endif -$ write sys$output "Checking for ''cdef'... no" -$ call write_config f$fao("#undef !AS",cdef) -$ MSYM_CLEAN: -$ if (idel .le. msym_max) -$ then -$ delete/sym mdef_'idel' -$ idel = idel + 1 -$ goto msym_clean -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Write configuration to both permanent and temporary config file -$! -$! Version history -$! 0.01 20031029 First version to receive a number -$! -$WRITE_CONFIG: SUBROUTINE -$ write aconf 'p1' -$ open/append confh 'th' -$ write confh 'p1' -$ close confh -$ENDSUBROUTINE -$!------------------------------------------------------------------------------ -$! -$! Analyze the project map file and create the symbol vector for a shareable -$! image from it -$! -$! Version history -$! 0.01 20120128 First version -$! 0.02 20120226 Add pre-load logic -$! -$ MAP_2_SHOPT: Subroutine -$! -$ SAY := "WRITE_ SYS$OUTPUT" -$! -$ IF F$SEARCH("''P1'") .EQS. "" -$ THEN -$ SAY "MAP_2_SHOPT-E-NOSUCHFILE: Error, inputfile ''p1' not available" -$ goto exit_m2s -$ ENDIF -$ IF "''P2'" .EQS. "" -$ THEN -$ SAY "MAP_2_SHOPT: Error, no output file provided" -$ goto exit_m2s -$ ENDIF -$! -$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary" -$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread" -$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary" -$ module4 = "inflateSync#uncompress#zlibVersion#compress" -$ open/read map 'p1 -$ if axp .or. ia64 -$ then -$ open/write aopt a.opt -$ open/write bopt b.opt -$ write aopt " CASE_SENSITIVE=YES" -$ write bopt "SYMBOL_VECTOR= (-" -$ mod_sym_num = 1 -$ MOD_SYM_LOOP: -$ if f$type(module'mod_sym_num') .nes. "" -$ then -$ mod_in = 0 -$ MOD_SYM_IN: -$ shared_proc = f$element(mod_in, "#", module'mod_sym_num') -$ if shared_proc .nes. "#" -$ then -$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",- - f$edit(shared_proc,"upcase"),shared_proc) -$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc) -$ mod_in = mod_in + 1 -$ goto mod_sym_in -$ endif -$ mod_sym_num = mod_sym_num + 1 -$ goto mod_sym_loop -$ endif -$MAP_LOOP: -$ read/end=map_end map line -$ if (f$locate("{",line).lt. f$length(line)) .or. - - (f$locate("global:", line) .lt. f$length(line)) -$ then -$ proc = true -$ goto map_loop -$ endif -$ if f$locate("}",line).lt. f$length(line) then proc = false -$ if f$locate("local:", line) .lt. f$length(line) then proc = false -$ if proc -$ then -$ shared_proc = f$edit(line,"collapse") -$ chop_semi = f$locate(";", shared_proc) -$ if chop_semi .lt. f$length(shared_proc) then - - shared_proc = f$extract(0, chop_semi, shared_proc) -$ write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",- - f$edit(shared_proc,"upcase"),shared_proc) -$ write bopt f$fao("!AS=PROCEDURE,-",shared_proc) -$ endif -$ goto map_loop -$MAP_END: -$ close/nolog aopt -$ close/nolog bopt -$ open/append libopt 'p2' -$ open/read aopt a.opt -$ open/read bopt b.opt -$ALOOP: -$ read/end=aloop_end aopt line -$ write libopt line -$ goto aloop -$ALOOP_END: -$ close/nolog aopt -$ sv = "" -$BLOOP: -$ read/end=bloop_end bopt svn -$ if (svn.nes."") -$ then -$ if (sv.nes."") then write libopt sv -$ sv = svn -$ endif -$ goto bloop -$BLOOP_END: -$ write libopt f$extract(0,f$length(sv)-2,sv), "-" -$ write libopt ")" -$ close/nolog bopt -$ delete/nolog/noconf a.opt;*,b.opt;* -$ else -$ if vax -$ then -$ open/append libopt 'p2' -$ mod_sym_num = 1 -$ VMOD_SYM_LOOP: -$ if f$type(module'mod_sym_num') .nes. "" -$ then -$ mod_in = 0 -$ VMOD_SYM_IN: -$ shared_proc = f$element(mod_in, "#", module'mod_sym_num') -$ if shared_proc .nes. "#" -$ then -$ write libopt f$fao("UNIVERSAL=!AS",- - f$edit(shared_proc,"upcase")) -$ mod_in = mod_in + 1 -$ goto vmod_sym_in -$ endif -$ mod_sym_num = mod_sym_num + 1 -$ goto vmod_sym_loop -$ endif -$VMAP_LOOP: -$ read/end=vmap_end map line -$ if (f$locate("{",line).lt. f$length(line)) .or. - - (f$locate("global:", line) .lt. f$length(line)) -$ then -$ proc = true -$ goto vmap_loop -$ endif -$ if f$locate("}",line).lt. f$length(line) then proc = false -$ if f$locate("local:", line) .lt. f$length(line) then proc = false -$ if proc -$ then -$ shared_proc = f$edit(line,"collapse") -$ chop_semi = f$locate(";", shared_proc) -$ if chop_semi .lt. f$length(shared_proc) then - - shared_proc = f$extract(0, chop_semi, shared_proc) -$ write libopt f$fao("UNIVERSAL=!AS",- - f$edit(shared_proc,"upcase")) -$ endif -$ goto vmap_loop -$VMAP_END: -$ else -$ write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)" -$ write sys$output "No options file created" -$ endif -$ endif -$ EXIT_M2S: -$ close/nolog map -$ close/nolog libopt -$ endsubroutine diff --git a/Sources/PerfectCZlib/msdos/Makefile.bor b/Sources/PerfectCZlib/msdos/Makefile.bor deleted file mode 100644 index 3d12a2c2..00000000 --- a/Sources/PerfectCZlib/msdos/Makefile.bor +++ /dev/null @@ -1,115 +0,0 @@ -# Makefile for zlib -# Borland C++ -# Last updated: 15-Mar-2003 - -# To use, do "make -fmakefile.bor" -# To compile in small model, set below: MODEL=s - -# WARNING: the small model is supported but only for small values of -# MAX_WBITS and MAX_MEM_LEVEL. For example: -# -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3 -# If you wish to reduce the memory requirements (default 256K for big -# objects plus a few K), you can add to the LOC macro below: -# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 -# See zconf.h for details about the memory requirements. - -# ------------ Turbo C++, Borland C++ ------------ - -# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) -# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added -# to the declaration of LOC here: -LOC = $(LOCAL_ZLIB) - -# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. -CPU_TYP = 0 - -# memory model: one of s, m, c, l (small, medium, compact, large) -MODEL=l - -# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version -CC=bcc -LD=bcc -AR=tlib - -# compiler flags -# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0 -CFLAGS=-O2 -Z -m$(MODEL) $(LOC) - -LDFLAGS=-m$(MODEL) -f- - - -# variables -ZLIB_LIB = zlib_$(MODEL).lib - -OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj -OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj -OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj -OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj - - -# targets -all: $(ZLIB_LIB) example.exe minigzip.exe - -.c.obj: - $(CC) -c $(CFLAGS) $*.c - -adler32.obj: adler32.c zlib.h zconf.h - -compress.obj: compress.c zlib.h zconf.h - -crc32.obj: crc32.c zlib.h zconf.h crc32.h - -deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h - -gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h - -gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h - -gzread.obj: gzread.c zlib.h zconf.h gzguts.h - -gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h - -infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h inffixed.h - -inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h - -inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h inffixed.h - -inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h - -trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h - -uncompr.obj: uncompr.c zlib.h zconf.h - -zutil.obj: zutil.c zutil.h zlib.h zconf.h - -example.obj: test/example.c zlib.h zconf.h - -minigzip.obj: test/minigzip.c zlib.h zconf.h - - -# the command line is cut to fit in the MS-DOS 128 byte limit: -$(ZLIB_LIB): $(OBJ1) $(OBJ2) - -del $(ZLIB_LIB) - $(AR) $(ZLIB_LIB) $(OBJP1) - $(AR) $(ZLIB_LIB) $(OBJP2) - -example.exe: example.obj $(ZLIB_LIB) - $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) - -minigzip.exe: minigzip.obj $(ZLIB_LIB) - $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) - -test: example.exe minigzip.exe - example - echo hello world | minigzip | minigzip -d - -clean: - -del *.obj - -del *.lib - -del *.exe - -del zlib_*.bak - -del foo.gz diff --git a/Sources/PerfectCZlib/msdos/Makefile.dj2 b/Sources/PerfectCZlib/msdos/Makefile.dj2 deleted file mode 100644 index 59d2037d..00000000 --- a/Sources/PerfectCZlib/msdos/Makefile.dj2 +++ /dev/null @@ -1,104 +0,0 @@ -# Makefile for zlib. Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96. -# Copyright (C) 1995-1998 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile, or to compile and test, type: -# -# make -fmakefile.dj2; make test -fmakefile.dj2 -# -# To install libz.a, zconf.h and zlib.h in the djgpp directories, type: -# -# make install -fmakefile.dj2 -# -# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as -# in the sample below if the pattern of the DJGPP distribution is to -# be followed. Remember that, while 'es around <=> are ignored in -# makefiles, they are *not* in batch files or in djgpp.env. -# - - - - - -# [make] -# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include -# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib -# BUTT=-m486 -# - - - - - -# Alternately, these variables may be defined below, overriding the values -# in djgpp.env, as -# INCLUDE_PATH=c:\usr\include -# LIBRARY_PATH=c:\usr\lib - -CC=gcc - -#CFLAGS=-MMD -O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-MMD -g -DZLIB_DEBUG -CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ - -Wstrict-prototypes -Wmissing-prototypes - -# If cp.exe is available, replace "copy /Y" with "cp -fp" . -CP=copy /Y -# If gnu install.exe is available, replace $(CP) with ginstall. -INSTALL=$(CP) -# The default value of RM is "rm -f." If "rm.exe" is found, comment out: -RM=del -LDLIBS=-L. -lz -LD=$(CC) -s -o -LDSHARED=$(CC) - -INCL=zlib.h zconf.h -LIBS=libz.a - -AR=ar rcs - -prefix=/usr/local -exec_prefix = $(prefix) - -OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ - uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o - -OBJA = -# to use the asm code: make OBJA=match.o - -TEST_OBJS = example.o minigzip.o - -all: example.exe minigzip.exe - -check: test -test: all - ./example - echo hello world | .\minigzip | .\minigzip -d - -%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -libz.a: $(OBJS) $(OBJA) - $(AR) $@ $(OBJS) $(OBJA) - -%.exe : %.o $(LIBS) - $(LD) $@ $< $(LDLIBS) - -# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env . - -.PHONY : uninstall clean - -install: $(INCL) $(LIBS) - -@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH) - -@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH) - $(INSTALL) zlib.h $(INCLUDE_PATH) - $(INSTALL) zconf.h $(INCLUDE_PATH) - $(INSTALL) libz.a $(LIBRARY_PATH) - -uninstall: - $(RM) $(INCLUDE_PATH)\zlib.h - $(RM) $(INCLUDE_PATH)\zconf.h - $(RM) $(LIBRARY_PATH)\libz.a - -clean: - $(RM) *.d - $(RM) *.o - $(RM) *.exe - $(RM) libz.a - $(RM) foo.gz - -DEPS := $(wildcard *.d) -ifneq ($(DEPS),) -include $(DEPS) -endif diff --git a/Sources/PerfectCZlib/msdos/Makefile.emx b/Sources/PerfectCZlib/msdos/Makefile.emx deleted file mode 100644 index e30f67be..00000000 --- a/Sources/PerfectCZlib/msdos/Makefile.emx +++ /dev/null @@ -1,69 +0,0 @@ -# Makefile for zlib. Modified for emx 0.9c by Chr. Spieler, 6/17/98. -# Copyright (C) 1995-1998 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile, or to compile and test, type: -# -# make -fmakefile.emx; make test -fmakefile.emx -# - -CC=gcc - -#CFLAGS=-MMD -O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-MMD -g -DZLIB_DEBUG -CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ - -Wstrict-prototypes -Wmissing-prototypes - -# If cp.exe is available, replace "copy /Y" with "cp -fp" . -CP=copy /Y -# If gnu install.exe is available, replace $(CP) with ginstall. -INSTALL=$(CP) -# The default value of RM is "rm -f." If "rm.exe" is found, comment out: -RM=del -LDLIBS=-L. -lzlib -LD=$(CC) -s -o -LDSHARED=$(CC) - -INCL=zlib.h zconf.h -LIBS=zlib.a - -AR=ar rcs - -prefix=/usr/local -exec_prefix = $(prefix) - -OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \ - uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o - -TEST_OBJS = example.o minigzip.o - -all: example.exe minigzip.exe - -test: all - ./example - echo hello world | .\minigzip | .\minigzip -d - -%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -zlib.a: $(OBJS) - $(AR) $@ $(OBJS) - -%.exe : %.o $(LIBS) - $(LD) $@ $< $(LDLIBS) - - -.PHONY : clean - -clean: - $(RM) *.d - $(RM) *.o - $(RM) *.exe - $(RM) zlib.a - $(RM) foo.gz - -DEPS := $(wildcard *.d) -ifneq ($(DEPS),) -include $(DEPS) -endif diff --git a/Sources/PerfectCZlib/msdos/Makefile.msc b/Sources/PerfectCZlib/msdos/Makefile.msc deleted file mode 100644 index ae837861..00000000 --- a/Sources/PerfectCZlib/msdos/Makefile.msc +++ /dev/null @@ -1,112 +0,0 @@ -# Makefile for zlib -# Microsoft C 5.1 or later -# Last updated: 19-Mar-2003 - -# To use, do "make makefile.msc" -# To compile in small model, set below: MODEL=S - -# If you wish to reduce the memory requirements (default 256K for big -# objects plus a few K), you can add to the LOC macro below: -# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 -# See zconf.h for details about the memory requirements. - -# ------------- Microsoft C 5.1 and later ------------- - -# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) -# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added -# to the declaration of LOC here: -LOC = $(LOCAL_ZLIB) - -# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc. -CPU_TYP = 0 - -# Memory model: one of S, M, C, L (small, medium, compact, large) -MODEL=L - -CC=cl -CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC) -#-Ox generates bad code with MSC 5.1 -LIB_CFLAGS=-Zl $(CFLAGS) - -LD=link -LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode -# "/farcall/packcode" are only useful for `large code' memory models -# but should be a "no-op" for small code models. - - -# variables -ZLIB_LIB = zlib_$(MODEL).lib - -OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj -OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj - - -# targets -all: $(ZLIB_LIB) example.exe minigzip.exe - -.c.obj: - $(CC) -c $(LIB_CFLAGS) $*.c - -adler32.obj: adler32.c zlib.h zconf.h - -compress.obj: compress.c zlib.h zconf.h - -crc32.obj: crc32.c zlib.h zconf.h crc32.h - -deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h - -gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h - -gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h - -gzread.obj: gzread.c zlib.h zconf.h gzguts.h - -gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h - -infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h inffixed.h - -inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h - -inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h inffixed.h - -inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h - -trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h - -uncompr.obj: uncompr.c zlib.h zconf.h - -zutil.obj: zutil.c zutil.h zlib.h zconf.h - -example.obj: test/example.c zlib.h zconf.h - $(CC) -c $(CFLAGS) $*.c - -minigzip.obj: test/minigzip.c zlib.h zconf.h - $(CC) -c $(CFLAGS) $*.c - - -# the command line is cut to fit in the MS-DOS 128 byte limit: -$(ZLIB_LIB): $(OBJ1) $(OBJ2) - if exist $(ZLIB_LIB) del $(ZLIB_LIB) - lib $(ZLIB_LIB) $(OBJ1); - lib $(ZLIB_LIB) $(OBJ2); - -example.exe: example.obj $(ZLIB_LIB) - $(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB); - -minigzip.exe: minigzip.obj $(ZLIB_LIB) - $(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB); - -test: example.exe minigzip.exe - example - echo hello world | minigzip | minigzip -d - -clean: - -del *.obj - -del *.lib - -del *.exe - -del *.map - -del zlib_*.bak - -del foo.gz diff --git a/Sources/PerfectCZlib/msdos/Makefile.tc b/Sources/PerfectCZlib/msdos/Makefile.tc deleted file mode 100644 index 5aec82a9..00000000 --- a/Sources/PerfectCZlib/msdos/Makefile.tc +++ /dev/null @@ -1,100 +0,0 @@ -# Makefile for zlib -# Turbo C 2.01, Turbo C++ 1.01 -# Last updated: 15-Mar-2003 - -# To use, do "make -fmakefile.tc" -# To compile in small model, set below: MODEL=s - -# WARNING: the small model is supported but only for small values of -# MAX_WBITS and MAX_MEM_LEVEL. For example: -# -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 -# If you wish to reduce the memory requirements (default 256K for big -# objects plus a few K), you can add to CFLAGS below: -# -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14 -# See zconf.h for details about the memory requirements. - -# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------ -MODEL=l -CC=tcc -LD=tcc -AR=tlib -# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3 -CFLAGS=-O2 -G -Z -m$(MODEL) -LDFLAGS=-m$(MODEL) -f- - - -# variables -ZLIB_LIB = zlib_$(MODEL).lib - -OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj -OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj -OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj -OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj - - -# targets -all: $(ZLIB_LIB) example.exe minigzip.exe - -.c.obj: - $(CC) -c $(CFLAGS) $*.c - -adler32.obj: adler32.c zlib.h zconf.h - -compress.obj: compress.c zlib.h zconf.h - -crc32.obj: crc32.c zlib.h zconf.h crc32.h - -deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h - -gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h - -gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h - -gzread.obj: gzread.c zlib.h zconf.h gzguts.h - -gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h - -infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h inffixed.h - -inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h - -inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h inffixed.h - -inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h - -trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h - -uncompr.obj: uncompr.c zlib.h zconf.h - -zutil.obj: zutil.c zutil.h zlib.h zconf.h - -example.obj: test/example.c zlib.h zconf.h - -minigzip.obj: test/minigzip.c zlib.h zconf.h - - -# the command line is cut to fit in the MS-DOS 128 byte limit: -$(ZLIB_LIB): $(OBJ1) $(OBJ2) - -del $(ZLIB_LIB) - $(AR) $(ZLIB_LIB) $(OBJP1) - $(AR) $(ZLIB_LIB) $(OBJP2) - -example.exe: example.obj $(ZLIB_LIB) - $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) - -minigzip.exe: minigzip.obj $(ZLIB_LIB) - $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) - -test: example.exe minigzip.exe - example - echo hello world | minigzip | minigzip -d - -clean: - -del *.obj - -del *.lib - -del *.exe - -del zlib_*.bak - -del foo.gz diff --git a/Sources/PerfectCZlib/nintendods/Makefile b/Sources/PerfectCZlib/nintendods/Makefile deleted file mode 100644 index 21337d01..00000000 --- a/Sources/PerfectCZlib/nintendods/Makefile +++ /dev/null @@ -1,126 +0,0 @@ -#--------------------------------------------------------------------------------- -.SUFFIXES: -#--------------------------------------------------------------------------------- - -ifeq ($(strip $(DEVKITARM)),) -$(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") -endif - -include $(DEVKITARM)/ds_rules - -#--------------------------------------------------------------------------------- -# TARGET is the name of the output -# BUILD is the directory where object files & intermediate files will be placed -# SOURCES is a list of directories containing source code -# DATA is a list of directories containing data files -# INCLUDES is a list of directories containing header files -#--------------------------------------------------------------------------------- -TARGET := $(shell basename $(CURDIR)) -BUILD := build -SOURCES := ../../ -DATA := data -INCLUDES := include - -#--------------------------------------------------------------------------------- -# options for code generation -#--------------------------------------------------------------------------------- -ARCH := -mthumb -mthumb-interwork - -CFLAGS := -Wall -O2\ - -march=armv5te -mtune=arm946e-s \ - -fomit-frame-pointer -ffast-math \ - $(ARCH) - -CFLAGS += $(INCLUDE) -DARM9 -CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions - -ASFLAGS := $(ARCH) -march=armv5te -mtune=arm946e-s -LDFLAGS = -specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) - -#--------------------------------------------------------------------------------- -# list of directories containing libraries, this must be the top level containing -# include and lib -#--------------------------------------------------------------------------------- -LIBDIRS := $(LIBNDS) - -#--------------------------------------------------------------------------------- -# no real need to edit anything past this point unless you need to add additional -# rules for different file extensions -#--------------------------------------------------------------------------------- -ifneq ($(BUILD),$(notdir $(CURDIR))) -#--------------------------------------------------------------------------------- - -export OUTPUT := $(CURDIR)/lib/libz.a - -export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ - $(foreach dir,$(DATA),$(CURDIR)/$(dir)) - -export DEPSDIR := $(CURDIR)/$(BUILD) - -CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) -CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) -SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) -BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) - -#--------------------------------------------------------------------------------- -# use CXX for linking C++ projects, CC for standard C -#--------------------------------------------------------------------------------- -ifeq ($(strip $(CPPFILES)),) -#--------------------------------------------------------------------------------- - export LD := $(CC) -#--------------------------------------------------------------------------------- -else -#--------------------------------------------------------------------------------- - export LD := $(CXX) -#--------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------- - -export OFILES := $(addsuffix .o,$(BINFILES)) \ - $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) - -export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ - $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ - -I$(CURDIR)/$(BUILD) - -.PHONY: $(BUILD) clean all - -#--------------------------------------------------------------------------------- -all: $(BUILD) - @[ -d $@ ] || mkdir -p include - @cp ../../*.h include - -lib: - @[ -d $@ ] || mkdir -p $@ - -$(BUILD): lib - @[ -d $@ ] || mkdir -p $@ - @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile - -#--------------------------------------------------------------------------------- -clean: - @echo clean ... - @rm -fr $(BUILD) lib - -#--------------------------------------------------------------------------------- -else - -DEPENDS := $(OFILES:.o=.d) - -#--------------------------------------------------------------------------------- -# main targets -#--------------------------------------------------------------------------------- -$(OUTPUT) : $(OFILES) - -#--------------------------------------------------------------------------------- -%.bin.o : %.bin -#--------------------------------------------------------------------------------- - @echo $(notdir $<) - @$(bin2o) - - --include $(DEPENDS) - -#--------------------------------------------------------------------------------------- -endif -#--------------------------------------------------------------------------------------- diff --git a/Sources/PerfectCZlib/nintendods/README b/Sources/PerfectCZlib/nintendods/README deleted file mode 100644 index ba7a37db..00000000 --- a/Sources/PerfectCZlib/nintendods/README +++ /dev/null @@ -1,5 +0,0 @@ -This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template. - -Eduardo Costa -January 3, 2009 - diff --git a/Sources/PerfectCZlib/old/Makefile.emx b/Sources/PerfectCZlib/old/Makefile.emx deleted file mode 100644 index 612b0379..00000000 --- a/Sources/PerfectCZlib/old/Makefile.emx +++ /dev/null @@ -1,69 +0,0 @@ -# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98. -# Copyright (C) 1995-1998 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile, or to compile and test, type: -# -# make -fmakefile.emx; make test -fmakefile.emx -# - -CC=gcc -Zwin32 - -#CFLAGS=-MMD -O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-MMD -g -DZLIB_DEBUG -CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ - -Wstrict-prototypes -Wmissing-prototypes - -# If cp.exe is available, replace "copy /Y" with "cp -fp" . -CP=copy /Y -# If gnu install.exe is available, replace $(CP) with ginstall. -INSTALL=$(CP) -# The default value of RM is "rm -f." If "rm.exe" is found, comment out: -RM=del -LDLIBS=-L. -lzlib -LD=$(CC) -s -o -LDSHARED=$(CC) - -INCL=zlib.h zconf.h -LIBS=zlib.a - -AR=ar rcs - -prefix=/usr/local -exec_prefix = $(prefix) - -OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ - gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o - -TEST_OBJS = example.o minigzip.o - -all: example.exe minigzip.exe - -test: all - ./example - echo hello world | .\minigzip | .\minigzip -d - -%.o : %.c - $(CC) $(CFLAGS) -c $< -o $@ - -zlib.a: $(OBJS) - $(AR) $@ $(OBJS) - -%.exe : %.o $(LIBS) - $(LD) $@ $< $(LDLIBS) - - -.PHONY : clean - -clean: - $(RM) *.d - $(RM) *.o - $(RM) *.exe - $(RM) zlib.a - $(RM) foo.gz - -DEPS := $(wildcard *.d) -ifneq ($(DEPS),) -include $(DEPS) -endif diff --git a/Sources/PerfectCZlib/old/Makefile.riscos b/Sources/PerfectCZlib/old/Makefile.riscos deleted file mode 100644 index 57e29d3f..00000000 --- a/Sources/PerfectCZlib/old/Makefile.riscos +++ /dev/null @@ -1,151 +0,0 @@ -# Project: zlib_1_03 -# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430 -# test works out-of-the-box, installs `somewhere' on demand - -# Toolflags: -CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah -C++flags = -c -depend !Depend -IC: -throwback -Linkflags = -aif -c++ -o $@ -ObjAsmflags = -throwback -NoCache -depend !Depend -CMHGflags = -LibFileflags = -c -l -o $@ -Squeezeflags = -o $@ - -# change the line below to where _you_ want the library installed. -libdest = lib:zlib - -# Final targets: -@.lib: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ - @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ - @.o.uncompr @.o.zutil - LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ - @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ - @.o.trees @.o.uncompr @.o.zutil -test: @.minigzip @.example @.lib - @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV - @echo running tests: hang on. - @/@.minigzip -f -9 libc - @/@.minigzip -d libc-gz - @/@.minigzip -f -1 libc - @/@.minigzip -d libc-gz - @/@.minigzip -h -9 libc - @/@.minigzip -d libc-gz - @/@.minigzip -h -1 libc - @/@.minigzip -d libc-gz - @/@.minigzip -9 libc - @/@.minigzip -d libc-gz - @/@.minigzip -1 libc - @/@.minigzip -d libc-gz - @diff @.lib @.libc - @echo that should have reported '@.lib and @.libc identical' if you have diff. - @/@.example @.fred @.fred - @echo that will have given lots of hello!'s. - -@.minigzip: @.o.minigzip @.lib C:o.Stubs - Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs -@.example: @.o.example @.lib C:o.Stubs - Link $(Linkflags) @.o.example @.lib C:o.Stubs - -install: @.lib - cdir $(libdest) - cdir $(libdest).h - @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV - @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV - @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV - @echo okay, installed zlib in $(libdest) - -clean:; remove @.minigzip - remove @.example - remove @.libc - -wipe @.o.* F~r~cV - remove @.fred - -# User-editable dependencies: -.c.o: - cc $(ccflags) -o $@ $< - -# Static dependencies: - -# Dynamic dependencies: -o.example: c.example -o.example: h.zlib -o.example: h.zconf -o.minigzip: c.minigzip -o.minigzip: h.zlib -o.minigzip: h.zconf -o.adler32: c.adler32 -o.adler32: h.zlib -o.adler32: h.zconf -o.compress: c.compress -o.compress: h.zlib -o.compress: h.zconf -o.crc32: c.crc32 -o.crc32: h.zlib -o.crc32: h.zconf -o.deflate: c.deflate -o.deflate: h.deflate -o.deflate: h.zutil -o.deflate: h.zlib -o.deflate: h.zconf -o.gzio: c.gzio -o.gzio: h.zutil -o.gzio: h.zlib -o.gzio: h.zconf -o.infblock: c.infblock -o.infblock: h.zutil -o.infblock: h.zlib -o.infblock: h.zconf -o.infblock: h.infblock -o.infblock: h.inftrees -o.infblock: h.infcodes -o.infblock: h.infutil -o.infcodes: c.infcodes -o.infcodes: h.zutil -o.infcodes: h.zlib -o.infcodes: h.zconf -o.infcodes: h.inftrees -o.infcodes: h.infblock -o.infcodes: h.infcodes -o.infcodes: h.infutil -o.infcodes: h.inffast -o.inffast: c.inffast -o.inffast: h.zutil -o.inffast: h.zlib -o.inffast: h.zconf -o.inffast: h.inftrees -o.inffast: h.infblock -o.inffast: h.infcodes -o.inffast: h.infutil -o.inffast: h.inffast -o.inflate: c.inflate -o.inflate: h.zutil -o.inflate: h.zlib -o.inflate: h.zconf -o.inflate: h.infblock -o.inftrees: c.inftrees -o.inftrees: h.zutil -o.inftrees: h.zlib -o.inftrees: h.zconf -o.inftrees: h.inftrees -o.inftrees: h.inffixed -o.infutil: c.infutil -o.infutil: h.zutil -o.infutil: h.zlib -o.infutil: h.zconf -o.infutil: h.infblock -o.infutil: h.inftrees -o.infutil: h.infcodes -o.infutil: h.infutil -o.trees: c.trees -o.trees: h.deflate -o.trees: h.zutil -o.trees: h.zlib -o.trees: h.zconf -o.trees: h.trees -o.uncompr: c.uncompr -o.uncompr: h.zlib -o.uncompr: h.zconf -o.zutil: c.zutil -o.zutil: h.zutil -o.zutil: h.zlib -o.zutil: h.zconf diff --git a/Sources/PerfectCZlib/old/README b/Sources/PerfectCZlib/old/README deleted file mode 100644 index 800bf079..00000000 --- a/Sources/PerfectCZlib/old/README +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains files that have not been updated for zlib 1.2.x - -(Volunteers are encouraged to help clean this up. Thanks.) diff --git a/Sources/PerfectCZlib/old/descrip.mms b/Sources/PerfectCZlib/old/descrip.mms deleted file mode 100644 index 7066da5b..00000000 --- a/Sources/PerfectCZlib/old/descrip.mms +++ /dev/null @@ -1,48 +0,0 @@ -# descrip.mms: MMS description file for building zlib on VMS -# written by Martin P.J. Zinser - -cc_defs = -c_deb = - -.ifdef __DECC__ -pref = /prefix=all -.endif - -OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ - deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ - inftrees.obj, infcodes.obj, infutil.obj, inffast.obj - -CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) - -all : example.exe minigzip.exe - @ write sys$output " Example applications available" -libz.olb : libz.olb($(OBJS)) - @ write sys$output " libz available" - -example.exe : example.obj libz.olb - link example,libz.olb/lib - -minigzip.exe : minigzip.obj libz.olb - link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib - -clean : - delete *.obj;*,libz.olb;* - - -# Other dependencies. -adler32.obj : zutil.h zlib.h zconf.h -compress.obj : zlib.h zconf.h -crc32.obj : zutil.h zlib.h zconf.h -deflate.obj : deflate.h zutil.h zlib.h zconf.h -example.obj : zlib.h zconf.h -gzio.obj : zutil.h zlib.h zconf.h -infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h -infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h -inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h -inflate.obj : zutil.h zlib.h zconf.h infblock.h -inftrees.obj : zutil.h zlib.h zconf.h inftrees.h -infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h -minigzip.obj : zlib.h zconf.h -trees.obj : deflate.h zutil.h zlib.h zconf.h -uncompr.obj : zlib.h zconf.h -zutil.obj : zutil.h zlib.h zconf.h diff --git a/Sources/PerfectCZlib/old/os2/Makefile.os2 b/Sources/PerfectCZlib/old/os2/Makefile.os2 deleted file mode 100644 index bb426c0d..00000000 --- a/Sources/PerfectCZlib/old/os2/Makefile.os2 +++ /dev/null @@ -1,136 +0,0 @@ -# Makefile for zlib under OS/2 using GCC (PGCC) -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# cp Makefile.os2 .. -# cd .. -# make -f Makefile.os2 test - -# This makefile will build a static library z.lib, a shared library -# z.dll and a import library zdll.lib. You can use either z.lib or -# zdll.lib by specifying either -lz or -lzdll on gcc's command line - -CC=gcc -Zomf -s - -CFLAGS=-O6 -Wall -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DZLIB_DEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -#################### BUG WARNING: ##################### -## infcodes.c hits a bug in pgcc-1.0, so you have to use either -## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem) -## This bug is reportedly fixed in pgcc >1.0, but this was not tested -CFLAGS+=-fno-force-mem - -LDFLAGS=-s -L. -lzdll -Zcrtdll -LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll - -VER=1.1.0 -ZLIB=z.lib -SHAREDLIB=z.dll -SHAREDLIBIMP=zdll.lib -LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP) - -AR=emxomfar cr -IMPLIB=emximp -RANLIB=echo -TAR=tar -SHELL=bash - -prefix=/usr/local -exec_prefix = $(prefix) - -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o - -TEST_OBJS = example.o minigzip.o - -DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \ - algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \ - nt/Makefile.nt nt/zlib.dnt contrib/README.contrib contrib/*.txt \ - contrib/asm386/*.asm contrib/asm386/*.c \ - contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \ - contrib/iostream/*.h contrib/iostream2/*.h contrib/iostream2/*.cpp \ - contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32 - -all: example.exe minigzip.exe - -test: all - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - echo hello world | ./minigzip | ./minigzip -d || \ - echo ' *** minigzip test FAILED ***' ; \ - if ./example; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; \ - fi - -$(ZLIB): $(OBJS) - $(AR) $@ $(OBJS) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -$(SHAREDLIB): $(OBJS) os2/z.def - $(LDSHARED) -o $@ $^ - -$(SHAREDLIBIMP): os2/z.def - $(IMPLIB) -o $@ $^ - -example.exe: example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) - -minigzip.exe: minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) - -clean: - rm -f *.o *~ example minigzip libz.a libz.so* foo.gz - -distclean: clean - -zip: - mv Makefile Makefile~; cp -p Makefile.in Makefile - rm -f test.c ztest*.c - v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ - zip -ul9 zlib$$v $(DISTFILES) - mv Makefile~ Makefile - -dist: - mv Makefile Makefile~; cp -p Makefile.in Makefile - rm -f test.c ztest*.c - d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\ - rm -f $$d.tar.gz; \ - if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \ - files=""; \ - for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \ - cd ..; \ - GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \ - if test ! -d $$d; then rm -f $$d; fi - mv Makefile~ Makefile - -tags: - etags *.[ch] - -depend: - makedepend -- $(CFLAGS) -- *.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h -infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h -infcodes.o: zutil.h zlib.h zconf.h -infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h -inffast.o: infblock.h infcodes.h infutil.h inffast.h -inflate.o: zutil.h zlib.h zconf.h infblock.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/Sources/PerfectCZlib/old/os2/zlib.def b/Sources/PerfectCZlib/old/os2/zlib.def deleted file mode 100644 index 4c753f1a..00000000 --- a/Sources/PerfectCZlib/old/os2/zlib.def +++ /dev/null @@ -1,51 +0,0 @@ -; -; Slightly modified version of ../nt/zlib.dnt :-) -; - -LIBRARY Z -DESCRIPTION "Zlib compression library for OS/2" -CODE PRELOAD MOVEABLE DISCARDABLE -DATA PRELOAD MOVEABLE MULTIPLE - -EXPORTS - adler32 - compress - crc32 - deflate - deflateCopy - deflateEnd - deflateInit2_ - deflateInit_ - deflateParams - deflateReset - deflateSetDictionary - gzclose - gzdopen - gzerror - gzflush - gzopen - gzread - gzwrite - inflate - inflateEnd - inflateInit2_ - inflateInit_ - inflateReset - inflateSetDictionary - inflateSync - uncompress - zlibVersion - gzprintf - gzputc - gzgetc - gzseek - gzrewind - gztell - gzeof - gzsetparams - zError - inflateSyncPoint - get_crc_table - compress2 - gzputs - gzgets diff --git a/Sources/PerfectCZlib/old/visual-basic.txt b/Sources/PerfectCZlib/old/visual-basic.txt deleted file mode 100644 index 57efe581..00000000 --- a/Sources/PerfectCZlib/old/visual-basic.txt +++ /dev/null @@ -1,160 +0,0 @@ -See below some functions declarations for Visual Basic. - -Frequently Asked Question: - -Q: Each time I use the compress function I get the -5 error (not enough - room in the output buffer). - -A: Make sure that the length of the compressed buffer is passed by - reference ("as any"), not by value ("as long"). Also check that - before the call of compress this length is equal to the total size of - the compressed buffer and not zero. - - -From: "Jon Caruana" -Subject: Re: How to port zlib declares to vb? -Date: Mon, 28 Oct 1996 18:33:03 -0600 - -Got the answer! (I haven't had time to check this but it's what I got, and -looks correct): - -He has the following routines working: - compress - uncompress - gzopen - gzwrite - gzread - gzclose - -Declares follow: (Quoted from Carlos Rios , in Vb4 form) - -#If Win16 Then 'Use Win16 calls. -Declare Function compress Lib "ZLIB.DLL" (ByVal compr As - String, comprLen As Any, ByVal buf As String, ByVal buflen - As Long) As Integer -Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr - As String, uncomprLen As Any, ByVal compr As String, ByVal - lcompr As Long) As Integer -Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As - String, ByVal mode As String) As Long -Declare Function gzread Lib "ZLIB.DLL" (ByVal file As - Long, ByVal uncompr As String, ByVal uncomprLen As Integer) - As Integer -Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As - Long, ByVal uncompr As String, ByVal uncomprLen As Integer) - As Integer -Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As - Long) As Integer -#Else -Declare Function compress Lib "ZLIB32.DLL" - (ByVal compr As String, comprLen As Any, ByVal buf As - String, ByVal buflen As Long) As Integer -Declare Function uncompress Lib "ZLIB32.DLL" - (ByVal uncompr As String, uncomprLen As Any, ByVal compr As - String, ByVal lcompr As Long) As Long -Declare Function gzopen Lib "ZLIB32.DLL" - (ByVal file As String, ByVal mode As String) As Long -Declare Function gzread Lib "ZLIB32.DLL" - (ByVal file As Long, ByVal uncompr As String, ByVal - uncomprLen As Long) As Long -Declare Function gzwrite Lib "ZLIB32.DLL" - (ByVal file As Long, ByVal uncompr As String, ByVal - uncomprLen As Long) As Long -Declare Function gzclose Lib "ZLIB32.DLL" - (ByVal file As Long) As Long -#End If - --Jon Caruana -jon-net@usa.net -Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member - - -Here is another example from Michael that he -says conforms to the VB guidelines, and that solves the problem of not -knowing the uncompressed size by storing it at the end of the file: - -'Calling the functions: -'bracket meaning: [optional] {Range of possible values} -'Call subCompressFile( [, , [level of compression {1..9}]]) -'Call subUncompressFile() - -Option Explicit -Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller' -Private Const SUCCESS As Long = 0 -Private Const strFilExt As String = ".cpr" -Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef -dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long, -ByVal level As Integer) As Long -Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef -dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long) -As Long - -Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal -strargCprFilPth As String, Optional ByVal intLvl As Integer = 9) - Dim strCprPth As String - Dim lngOriSiz As Long - Dim lngCprSiz As Long - Dim bytaryOri() As Byte - Dim bytaryCpr() As Byte - lngOriSiz = FileLen(strargOriFilPth) - ReDim bytaryOri(lngOriSiz - 1) - Open strargOriFilPth For Binary Access Read As #1 - Get #1, , bytaryOri() - Close #1 - strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth) -'Select file path and name - strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) = -strFilExt, "", strFilExt) 'Add file extension if not exists - lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit -more space then original file size - ReDim bytaryCpr(lngCprSiz - 1) - If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) = -SUCCESS Then - lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100 - ReDim Preserve bytaryCpr(lngCprSiz - 1) - Open strCprPth For Binary Access Write As #1 - Put #1, , bytaryCpr() - Put #1, , lngOriSiz 'Add the the original size value to the end -(last 4 bytes) - Close #1 - Else - MsgBox "Compression error" - End If - Erase bytaryCpr - Erase bytaryOri -End Sub - -Public Sub subUncompressFile(ByVal strargFilPth As String) - Dim bytaryCpr() As Byte - Dim bytaryOri() As Byte - Dim lngOriSiz As Long - Dim lngCprSiz As Long - Dim strOriPth As String - lngCprSiz = FileLen(strargFilPth) - ReDim bytaryCpr(lngCprSiz - 1) - Open strargFilPth For Binary Access Read As #1 - Get #1, , bytaryCpr() - Close #1 - 'Read the original file size value: - lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _ - + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _ - + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _ - + bytaryCpr(lngCprSiz - 4) - ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value - ReDim bytaryOri(lngOriSiz - 1) - If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS -Then - strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt)) - Open strOriPth For Binary Access Write As #1 - Put #1, , bytaryOri() - Close #1 - Else - MsgBox "Uncompression error" - End If - Erase bytaryCpr - Erase bytaryOri -End Sub -Public Property Get lngPercentSmaller() As Long - lngPercentSmaller = lngpvtPcnSml -End Property diff --git a/Sources/PerfectCZlib/os400/README400 b/Sources/PerfectCZlib/os400/README400 deleted file mode 100644 index 7926d7c5..00000000 --- a/Sources/PerfectCZlib/os400/README400 +++ /dev/null @@ -1,48 +0,0 @@ - ZLIB version 1.2.9 for OS/400 installation instructions - -1) Download and unpack the zlib tarball to some IFS directory. - (i.e.: /path/to/the/zlib/ifs/source/directory) - - If the installed IFS command suppors gzip format, this is straightforward, -else you have to unpack first to some directory on a system supporting it, -then move the whole directory to the IFS via the network (via SMB or FTP). - -2) Edit the configuration parameters in the compilation script. - - EDTF STMF('/path/to/the/zlib/ifs/source/directory/os400/make.sh') - -Tune the parameters according to your needs if not matching the defaults. -Save the file and exit after edition. - -3) Enter qshell, then work in the zlib OS/400 specific directory. - - QSH - cd /path/to/the/zlib/ifs/source/directory/os400 - -4) Compile and install - - sh make.sh - -The script will: -- create the libraries, objects and IFS directories for the zlib environment, -- compile all modules, -- create a service program, -- create a static and a dynamic binding directory, -- install header files for C/C++ and for ILE/RPG, both for compilation in - DB2 and IFS environments. - -That's all. - - -Notes: For OS/400 ILE RPG programmers, a /copy member defining the ZLIB - API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC). - In the ILE environment, the same definitions are available from - file zlib.inc located in the same IFS include directory as the - C/C++ header files. - Please read comments in this member for more information. - - Remember that most foreign textual data are ASCII coded: this - implementation does not handle conversion from/to ASCII, so - text data code conversions must be done explicitely. - - Mainly for the reason above, always open zipped files in binary mode. diff --git a/Sources/PerfectCZlib/os400/bndsrc b/Sources/PerfectCZlib/os400/bndsrc deleted file mode 100644 index 5e6e0a2f..00000000 --- a/Sources/PerfectCZlib/os400/bndsrc +++ /dev/null @@ -1,119 +0,0 @@ -STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB') - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/* Version 1.1.3 entry points. */ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - EXPORT SYMBOL("adler32") - EXPORT SYMBOL("compress") - EXPORT SYMBOL("compress2") - EXPORT SYMBOL("crc32") - EXPORT SYMBOL("get_crc_table") - EXPORT SYMBOL("deflate") - EXPORT SYMBOL("deflateEnd") - EXPORT SYMBOL("deflateSetDictionary") - EXPORT SYMBOL("deflateCopy") - EXPORT SYMBOL("deflateReset") - EXPORT SYMBOL("deflateParams") - EXPORT SYMBOL("deflatePrime") - EXPORT SYMBOL("deflateInit_") - EXPORT SYMBOL("deflateInit2_") - EXPORT SYMBOL("gzopen") - EXPORT SYMBOL("gzdopen") - EXPORT SYMBOL("gzsetparams") - EXPORT SYMBOL("gzread") - EXPORT SYMBOL("gzwrite") - EXPORT SYMBOL("gzprintf") - EXPORT SYMBOL("gzputs") - EXPORT SYMBOL("gzgets") - EXPORT SYMBOL("gzputc") - EXPORT SYMBOL("gzgetc") - EXPORT SYMBOL("gzflush") - EXPORT SYMBOL("gzseek") - EXPORT SYMBOL("gzrewind") - EXPORT SYMBOL("gztell") - EXPORT SYMBOL("gzeof") - EXPORT SYMBOL("gzclose") - EXPORT SYMBOL("gzerror") - EXPORT SYMBOL("inflate") - EXPORT SYMBOL("inflateEnd") - EXPORT SYMBOL("inflateSetDictionary") - EXPORT SYMBOL("inflateSync") - EXPORT SYMBOL("inflateReset") - EXPORT SYMBOL("inflateInit_") - EXPORT SYMBOL("inflateInit2_") - EXPORT SYMBOL("inflateSyncPoint") - EXPORT SYMBOL("uncompress") - EXPORT SYMBOL("zlibVersion") - EXPORT SYMBOL("zError") - EXPORT SYMBOL("z_errmsg") - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/* Version 1.2.1 additional entry points. */ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - EXPORT SYMBOL("compressBound") - EXPORT SYMBOL("deflateBound") - EXPORT SYMBOL("deflatePending") - EXPORT SYMBOL("gzungetc") - EXPORT SYMBOL("gzclearerr") - EXPORT SYMBOL("inflateBack") - EXPORT SYMBOL("inflateBackEnd") - EXPORT SYMBOL("inflateBackInit_") - EXPORT SYMBOL("inflateCopy") - EXPORT SYMBOL("zlibCompileFlags") - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/* Version 1.2.4 additional entry points. */ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - EXPORT SYMBOL("adler32_combine") - EXPORT SYMBOL("adler32_combine64") - EXPORT SYMBOL("crc32_combine") - EXPORT SYMBOL("crc32_combine64") - EXPORT SYMBOL("deflateSetHeader") - EXPORT SYMBOL("deflateTune") - EXPORT SYMBOL("gzbuffer") - EXPORT SYMBOL("gzclose_r") - EXPORT SYMBOL("gzclose_w") - EXPORT SYMBOL("gzdirect") - EXPORT SYMBOL("gzoffset") - EXPORT SYMBOL("gzoffset64") - EXPORT SYMBOL("gzopen64") - EXPORT SYMBOL("gzseek64") - EXPORT SYMBOL("gztell64") - EXPORT SYMBOL("inflateGetHeader") - EXPORT SYMBOL("inflateMark") - EXPORT SYMBOL("inflatePrime") - EXPORT SYMBOL("inflateReset2") - EXPORT SYMBOL("inflateUndermine") - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/* Version 1.2.6 additional entry points. */ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - EXPORT SYMBOL("deflateResetKeep") - EXPORT SYMBOL("gzgetc_") - EXPORT SYMBOL("inflateResetKeep") - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/* Version 1.2.8 additional entry points. */ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - EXPORT SYMBOL("gzvprintf") - EXPORT SYMBOL("inflateGetDictionary") - -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ -/* Version 1.2.9 additional entry points. */ -/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/ - - EXPORT SYMBOL("adler32_z") - EXPORT SYMBOL("crc32_z") - EXPORT SYMBOL("deflateGetDictionary") - EXPORT SYMBOL("gzfread") - EXPORT SYMBOL("gzfwrite") - EXPORT SYMBOL("inflateCodesUsed") - EXPORT SYMBOL("inflateValidate") - EXPORT SYMBOL("uncompress2") - -ENDPGMEXP diff --git a/Sources/PerfectCZlib/os400/make.sh b/Sources/PerfectCZlib/os400/make.sh deleted file mode 100644 index ddbfb16b..00000000 --- a/Sources/PerfectCZlib/os400/make.sh +++ /dev/null @@ -1,366 +0,0 @@ -#!/bin/sh -# -# ZLIB compilation script for the OS/400. -# -# -# This is a shell script since make is not a standard component of OS/400. - - -################################################################################ -# -# Tunable configuration parameters. -# -################################################################################ - -TARGETLIB='ZLIB' # Target OS/400 program library -STATBNDDIR='ZLIB_A' # Static binding directory. -DYNBNDDIR='ZLIB' # Dynamic binding directory. -SRVPGM="ZLIB" # Service program. -IFSDIR='/zlib' # IFS support base directory. -TGTCCSID='500' # Target CCSID of objects -DEBUG='*NONE' # Debug level -OPTIMIZE='40' # Optimisation level -OUTPUT='*NONE' # Compilation output option. -TGTRLS='V6R1M0' # Target OS release - -export TARGETLIB STATBNDDIR DYNBNDDIR SRVPGM IFSDIR -export TGTCCSID DEBUG OPTIMIZE OUTPUT TGTRLS - - -################################################################################ -# -# OS/400 specific definitions. -# -################################################################################ - -LIBIFSNAME="/QSYS.LIB/${TARGETLIB}.LIB" - - -################################################################################ -# -# Procedures. -# -################################################################################ - -# action_needed dest [src] -# -# dest is an object to build -# if specified, src is an object on which dest depends. -# -# exit 0 (succeeds) if some action has to be taken, else 1. - -action_needed() - -{ - [ ! -e "${1}" ] && return 0 - [ "${2}" ] || return 1 - [ "${1}" -ot "${2}" ] && return 0 - return 1 -} - - -# make_module module_name source_name [additional_definitions] -# -# Compile source name into module if needed. -# As side effect, append the module name to variable MODULES. -# Set LINK to "YES" if the module has been compiled. - -make_module() - -{ - MODULES="${MODULES} ${1}" - MODIFSNAME="${LIBIFSNAME}/${1}.MODULE" - CSRC="`basename \"${2}\"`" - - if action_needed "${MODIFSNAME}" "${2}" - then : - elif [ ! "`sed -e \"//,/<\\\\/source>/!d\" \ - -e '/ tmphdrfile - - # Need to translate to target CCSID. - - CMD="CPY OBJ('`pwd`/tmphdrfile') TOOBJ('${DEST}')" - CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)" - system "${CMD}" - # touch -r "${HFILE}" "${DEST}" - rm -f tmphdrfile - fi - - IFSFILE="${IFSDIR}/include/`basename \"${HFILE}\"`" - - if action_needed "${IFSFILE}" "${DEST}" - then rm -f "${IFSFILE}" - ln -s "${DEST}" "${IFSFILE}" - fi -done - - -# Install the ILE/RPG header file. - - -HFILE="${SCRIPTDIR}/zlib.inc" -DEST="${SRCPF}/ZLIB.INC.MBR" - -if action_needed "${DEST}" "${HFILE}" -then CMD="CPY OBJ('${HFILE}') TOOBJ('${DEST}')" - CMD="${CMD} TOCCSID(${TGTCCSID}) DTAFMT(*TEXT) REPLACE(*YES)" - system "${CMD}" - # touch -r "${HFILE}" "${DEST}" -fi - -IFSFILE="${IFSDIR}/include/`basename \"${HFILE}\"`" - -if action_needed "${IFSFILE}" "${DEST}" -then rm -f "${IFSFILE}" - ln -s "${DEST}" "${IFSFILE}" -fi - - -# Create and compile the identification source file. - -echo '#pragma comment(user, "ZLIB version '"${VERSION}"'")' > os400.c -echo '#pragma comment(user, __DATE__)' >> os400.c -echo '#pragma comment(user, __TIME__)' >> os400.c -echo '#pragma comment(copyright, "Copyright (C) 1995-2016 Jean-Loup Gailly, Mark Adler. OS/400 version by P. Monnerat.")' >> os400.c -make_module OS400 os400.c -LINK= # No need to rebuild service program yet. -MODULES= - - -# Get source list. - -CSOURCES=`sed -e '/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Library - - Medium - - 2.0 - - - - zlib - zlib - alain.bonnefoy@icbt.com - Public - public - www.gzip.org/zlib - - - Jean-Loup Gailly,Mark Adler - www.gzip.org/zlib - - zlib@gzip.org - - - A massively spiffy yet delicately unobtrusive compression library. - zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system. - http://www.gzip.org/zlib - - - - - 1.2.9 - Medium - Stable - - - - - - - No License - - - - Software Development/Libraries and Extensions/C Libraries - zlib,compression - qnx6 - qnx6 - None - Developer - - - - - - - - - - - - - - Install - Post - No - Ignore - - No - Optional - - - - - - - - - - - - - InstallOver - zlib - - - - - - - - - - - - - InstallOver - zlib-dev - - - - - - - - - diff --git a/Sources/PerfectCZlib/treebuild.xml b/Sources/PerfectCZlib/treebuild.xml deleted file mode 100644 index 931ee5a2..00000000 --- a/Sources/PerfectCZlib/treebuild.xml +++ /dev/null @@ -1,116 +0,0 @@ - - - - zip compression library - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Sources/PerfectCZlib/trees.c b/Sources/PerfectCZlib/trees.c deleted file mode 100644 index 357f3139..00000000 --- a/Sources/PerfectCZlib/trees.c +++ /dev/null @@ -1,1203 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2016 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef ZLIB_DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local const static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local const static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local const static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, const ct_data *ltree, - const ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef ZLIB_DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* !ZLIB_DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef ZLIB_DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !ZLIB_DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = (int)value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* ZLIB_DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef ZLIB_DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (unsigned)(bits + xbits); - if (stree) s->static_len += (ulg)f * (unsigned)(stree[n].Len + xbits); - } - if (overflow == 0) return; - - Tracev((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Tracev((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((ulg)bits - tree[m].Len) * tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - unsigned code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - code = (code + bl_count[bits-1]) << 1; - next_code[bits] = (ush)code; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*((ulg)max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ - bi_windup(s); /* align on byte boundary */ - put_short(s, (ush)stored_len); - put_short(s, (ush)~stored_len); - zmemcpy(s->pending_buf + s->pending, (Bytef *)buf, stored_len); - s->pending += stored_len; -#ifdef ZLIB_DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; - s->bits_sent += 2*16; - s->bits_sent += stored_len<<3; -#endif -} - -/* =========================================================================== - * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) - */ -void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; -{ - bi_flush(s); -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef ZLIB_DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (const ct_data *)static_ltree, - (const ct_data *)static_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (const ct_data *)s->dyn_ltree, - (const ct_data *)s->dyn_dtree); -#ifdef ZLIB_DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef ZLIB_DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - const ct_data *ltree; /* literal tree */ - const ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= (unsigned)base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef ZLIB_DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} diff --git a/Sources/PerfectCZlib/trees.h b/Sources/PerfectCZlib/trees.h deleted file mode 100644 index d35639d8..00000000 --- a/Sources/PerfectCZlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/Sources/PerfectCZlib/uncompr.c b/Sources/PerfectCZlib/uncompr.c deleted file mode 100644 index f03a1a86..00000000 --- a/Sources/PerfectCZlib/uncompr.c +++ /dev/null @@ -1,93 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. *sourceLen is - the byte length of the source buffer. Upon entry, *destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, - *destLen is the size of the decompressed data and *sourceLen is the number - of source bytes consumed. Upon return, source + *sourceLen points to the - first unused input byte. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, or - Z_DATA_ERROR if the input data was corrupted, including if the input data is - an incomplete zlib stream. -*/ -int ZEXPORT uncompress2 (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong *sourceLen; -{ - z_stream stream; - int err; - const uInt max = (uInt)-1; - uLong len, left; - Byte buf[1]; /* for detection of incomplete stream when *destLen == 0 */ - - len = *sourceLen; - if (*destLen) { - left = *destLen; - *destLen = 0; - } - else { - left = 1; - dest = buf; - } - - stream.next_in = (z_const Bytef *)source; - stream.avail_in = 0; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - stream.next_out = dest; - stream.avail_out = 0; - - do { - if (stream.avail_out == 0) { - stream.avail_out = left > (uLong)max ? max : (uInt)left; - left -= stream.avail_out; - } - if (stream.avail_in == 0) { - stream.avail_in = len > (uLong)max ? max : (uInt)len; - len -= stream.avail_in; - } - err = inflate(&stream, Z_NO_FLUSH); - } while (err == Z_OK); - - *sourceLen -= len + stream.avail_in; - if (dest != buf) - *destLen = stream.total_out; - else if (stream.total_out && err == Z_BUF_ERROR) - left = 1; - - inflateEnd(&stream); - return err == Z_STREAM_END ? Z_OK : - err == Z_NEED_DICT ? Z_DATA_ERROR : - err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : - err; -} - -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return uncompress2(dest, destLen, source, &sourceLen); -} diff --git a/Sources/PerfectCZlib/watcom/watcom_f.mak b/Sources/PerfectCZlib/watcom/watcom_f.mak deleted file mode 100644 index 37f4d74c..00000000 --- a/Sources/PerfectCZlib/watcom/watcom_f.mak +++ /dev/null @@ -1,43 +0,0 @@ -# Makefile for zlib -# OpenWatcom flat model -# Last updated: 28-Dec-2005 - -# To use, do "wmake -f watcom_f.mak" - -C_SOURCE = adler32.c compress.c crc32.c deflate.c & - gzclose.c gzlib.c gzread.c gzwrite.c & - infback.c inffast.c inflate.c inftrees.c & - trees.c uncompr.c zutil.c - -OBJS = adler32.obj compress.obj crc32.obj deflate.obj & - gzclose.obj gzlib.obj gzread.obj gzwrite.obj & - infback.obj inffast.obj inflate.obj inftrees.obj & - trees.obj uncompr.obj zutil.obj - -CC = wcc386 -LINKER = wcl386 -CFLAGS = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx -ZLIB_LIB = zlib_f.lib - -.C.OBJ: - $(CC) $(CFLAGS) $[@ - -all: $(ZLIB_LIB) example.exe minigzip.exe - -$(ZLIB_LIB): $(OBJS) - wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj - wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj - wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj - wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj - wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj - -example.exe: $(ZLIB_LIB) example.obj - $(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB) - -minigzip.exe: $(ZLIB_LIB) minigzip.obj - $(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB) - -clean: .SYMBOLIC - del *.obj - del $(ZLIB_LIB) - @echo Cleaning done diff --git a/Sources/PerfectCZlib/watcom/watcom_l.mak b/Sources/PerfectCZlib/watcom/watcom_l.mak deleted file mode 100644 index 193eed7b..00000000 --- a/Sources/PerfectCZlib/watcom/watcom_l.mak +++ /dev/null @@ -1,43 +0,0 @@ -# Makefile for zlib -# OpenWatcom large model -# Last updated: 28-Dec-2005 - -# To use, do "wmake -f watcom_l.mak" - -C_SOURCE = adler32.c compress.c crc32.c deflate.c & - gzclose.c gzlib.c gzread.c gzwrite.c & - infback.c inffast.c inflate.c inftrees.c & - trees.c uncompr.c zutil.c - -OBJS = adler32.obj compress.obj crc32.obj deflate.obj & - gzclose.obj gzlib.obj gzread.obj gzwrite.obj & - infback.obj inffast.obj inflate.obj inftrees.obj & - trees.obj uncompr.obj zutil.obj - -CC = wcc -LINKER = wcl -CFLAGS = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx -ZLIB_LIB = zlib_l.lib - -.C.OBJ: - $(CC) $(CFLAGS) $[@ - -all: $(ZLIB_LIB) example.exe minigzip.exe - -$(ZLIB_LIB): $(OBJS) - wlib -b -c $(ZLIB_LIB) -+adler32.obj -+compress.obj -+crc32.obj - wlib -b -c $(ZLIB_LIB) -+gzclose.obj -+gzlib.obj -+gzread.obj -+gzwrite.obj - wlib -b -c $(ZLIB_LIB) -+deflate.obj -+infback.obj - wlib -b -c $(ZLIB_LIB) -+inffast.obj -+inflate.obj -+inftrees.obj - wlib -b -c $(ZLIB_LIB) -+trees.obj -+uncompr.obj -+zutil.obj - -example.exe: $(ZLIB_LIB) example.obj - $(LINKER) -fe=example.exe example.obj $(ZLIB_LIB) - -minigzip.exe: $(ZLIB_LIB) minigzip.obj - $(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB) - -clean: .SYMBOLIC - del *.obj - del $(ZLIB_LIB) - @echo Cleaning done diff --git a/Sources/PerfectCZlib/win32/DLL_FAQ.txt b/Sources/PerfectCZlib/win32/DLL_FAQ.txt deleted file mode 100644 index 12c00901..00000000 --- a/Sources/PerfectCZlib/win32/DLL_FAQ.txt +++ /dev/null @@ -1,397 +0,0 @@ - - Frequently Asked Questions about ZLIB1.DLL - - -This document describes the design, the rationale, and the usage -of the official DLL build of zlib, named ZLIB1.DLL. If you have -general questions about zlib, you should see the file "FAQ" found -in the zlib distribution, or at the following location: - http://www.gzip.org/zlib/zlib_faq.html - - - 1. What is ZLIB1.DLL, and how can I get it? - - - ZLIB1.DLL is the official build of zlib as a DLL. - (Please remark the character '1' in the name.) - - Pointers to a precompiled ZLIB1.DLL can be found in the zlib - web site at: - http://www.zlib.net/ - - Applications that link to ZLIB1.DLL can rely on the following - specification: - - * The exported symbols are exclusively defined in the source - files "zlib.h" and "zlib.def", found in an official zlib - source distribution. - * The symbols are exported by name, not by ordinal. - * The exported names are undecorated. - * The calling convention of functions is "C" (CDECL). - * The ZLIB1.DLL binary is linked to MSVCRT.DLL. - - The archive in which ZLIB1.DLL is bundled contains compiled - test programs that must run with a valid build of ZLIB1.DLL. - It is recommended to download the prebuilt DLL from the zlib - web site, instead of building it yourself, to avoid potential - incompatibilities that could be introduced by your compiler - and build settings. If you do build the DLL yourself, please - make sure that it complies with all the above requirements, - and it runs with the precompiled test programs, bundled with - the original ZLIB1.DLL distribution. - - If, for any reason, you need to build an incompatible DLL, - please use a different file name. - - - 2. Why did you change the name of the DLL to ZLIB1.DLL? - What happened to the old ZLIB.DLL? - - - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required - compilation settings that were incompatible to those used by - a static build. The DLL settings were supposed to be enabled - by defining the macro ZLIB_DLL, before including "zlib.h". - Incorrect handling of this macro was silently accepted at - build time, resulting in two major problems: - - * ZLIB_DLL was missing from the old makefile. When building - the DLL, not all people added it to the build options. In - consequence, incompatible incarnations of ZLIB.DLL started - to circulate around the net. - - * When switching from using the static library to using the - DLL, applications had to define the ZLIB_DLL macro and - to recompile all the sources that contained calls to zlib - functions. Failure to do so resulted in creating binaries - that were unable to run with the official ZLIB.DLL build. - - The only possible solution that we could foresee was to make - a binary-incompatible change in the DLL interface, in order to - remove the dependency on the ZLIB_DLL macro, and to release - the new DLL under a different name. - - We chose the name ZLIB1.DLL, where '1' indicates the major - zlib version number. We hope that we will not have to break - the binary compatibility again, at least not as long as the - zlib-1.x series will last. - - There is still a ZLIB_DLL macro, that can trigger a more - efficient build and use of the DLL, but compatibility no - longer dependents on it. - - - 3. Can I build ZLIB.DLL from the new zlib sources, and replace - an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier? - - - In principle, you can do it by assigning calling convention - keywords to the macros ZEXPORT and ZEXPORTVA. In practice, - it depends on what you mean by "an old ZLIB.DLL", because the - old DLL exists in several mutually-incompatible versions. - You have to find out first what kind of calling convention is - being used in your particular ZLIB.DLL build, and to use the - same one in the new build. If you don't know what this is all - about, you might be better off if you would just leave the old - DLL intact. - - - 4. Can I compile my application using the new zlib interface, and - link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or - earlier? - - - The official answer is "no"; the real answer depends again on - what kind of ZLIB.DLL you have. Even if you are lucky, this - course of action is unreliable. - - If you rebuild your application and you intend to use a newer - version of zlib (post- 1.1.4), it is strongly recommended to - link it to the new ZLIB1.DLL. - - - 5. Why are the zlib symbols exported by name, and not by ordinal? - - - Although exporting symbols by ordinal is a little faster, it - is risky. Any single glitch in the maintenance or use of the - DEF file that contains the ordinals can result in incompatible - builds and frustrating crashes. Simply put, the benefits of - exporting symbols by ordinal do not justify the risks. - - Technically, it should be possible to maintain ordinals in - the DEF file, and still export the symbols by name. Ordinals - exist in every DLL, and even if the dynamic linking performed - at the DLL startup is searching for names, ordinals serve as - hints, for a faster name lookup. However, if the DEF file - contains ordinals, the Microsoft linker automatically builds - an implib that will cause the executables linked to it to use - those ordinals, and not the names. It is interesting to - notice that the GNU linker for Win32 does not suffer from this - problem. - - It is possible to avoid the DEF file if the exported symbols - are accompanied by a "__declspec(dllexport)" attribute in the - source files. You can do this in zlib by predefining the - ZLIB_DLL macro. - - - 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling - convention. Why not use the STDCALL convention? - STDCALL is the standard convention in Win32, and I need it in - my Visual Basic project! - - (For readability, we use CDECL to refer to the convention - triggered by the "__cdecl" keyword, STDCALL to refer to - the convention triggered by "__stdcall", and FASTCALL to - refer to the convention triggered by "__fastcall".) - - - Most of the native Windows API functions (without varargs) use - indeed the WINAPI convention (which translates to STDCALL in - Win32), but the standard C functions use CDECL. If a user - application is intrinsically tied to the Windows API (e.g. - it calls native Windows API functions such as CreateFile()), - sometimes it makes sense to decorate its own functions with - WINAPI. But if ANSI C or POSIX portability is a goal (e.g. - it calls standard C functions such as fopen()), it is not a - sound decision to request the inclusion of , or to - use non-ANSI constructs, for the sole purpose to make the user - functions STDCALL-able. - - The functionality offered by zlib is not in the category of - "Windows functionality", but is more like "C functionality". - - Technically, STDCALL is not bad; in fact, it is slightly - faster than CDECL, and it works with variable-argument - functions, just like CDECL. It is unfortunate that, in spite - of using STDCALL in the Windows API, it is not the default - convention used by the C compilers that run under Windows. - The roots of the problem reside deep inside the unsafety of - the K&R-style function prototypes, where the argument types - are not specified; but that is another story for another day. - - The remaining fact is that CDECL is the default convention. - Even if an explicit convention is hard-coded into the function - prototypes inside C headers, problems may appear. The - necessity to expose the convention in users' callbacks is one - of these problems. - - The calling convention issues are also important when using - zlib in other programming languages. Some of them, like Ada - (GNAT) and Fortran (GNU G77), have C bindings implemented - initially on Unix, and relying on the C calling convention. - On the other hand, the pre- .NET versions of Microsoft Visual - Basic require STDCALL, while Borland Delphi prefers, although - it does not require, FASTCALL. - - In fairness to all possible uses of zlib outside the C - programming language, we choose the default "C" convention. - Anyone interested in different bindings or conventions is - encouraged to maintain specialized projects. The "contrib/" - directory from the zlib distribution already holds a couple - of foreign bindings, such as Ada, C++, and Delphi. - - - 7. I need a DLL for my Visual Basic project. What can I do? - - - Define the ZLIB_WINAPI macro before including "zlib.h", when - building both the DLL and the user application (except that - you don't need to define anything when using the DLL in Visual - Basic). The ZLIB_WINAPI macro will switch on the WINAPI - (STDCALL) convention. The name of this DLL must be different - than the official ZLIB1.DLL. - - Gilles Vollant has contributed a build named ZLIBWAPI.DLL, - with the ZLIB_WINAPI macro turned on, and with the minizip - functionality built in. For more information, please read - the notes inside "contrib/vstudio/readme.txt", found in the - zlib distribution. - - - 8. I need to use zlib in my Microsoft .NET project. What can I - do? - - - Henrik Ravn has contributed a .NET wrapper around zlib. Look - into contrib/dotzlib/, inside the zlib distribution. - - - 9. If my application uses ZLIB1.DLL, should I link it to - MSVCRT.DLL? Why? - - - It is not required, but it is recommended to link your - application to MSVCRT.DLL, if it uses ZLIB1.DLL. - - The executables (.EXE, .DLL, etc.) that are involved in the - same process and are using the C run-time library (i.e. they - are calling standard C functions), must link to the same - library. There are several libraries in the Win32 system: - CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc. - Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that - depend on it should also be linked to MSVCRT.DLL. - - -10. Why are you saying that ZLIB1.DLL and my application should - be linked to the same C run-time (CRT) library? I linked my - application and my DLLs to different C libraries (e.g. my - application to a static library, and my DLLs to MSVCRT.DLL), - and everything works fine. - - - If a user library invokes only pure Win32 API (accessible via - and the related headers), its DLL build will work - in any context. But if this library invokes standard C API, - things get more complicated. - - There is a single Win32 library in a Win32 system. Every - function in this library resides in a single DLL module, that - is safe to call from anywhere. On the other hand, there are - multiple versions of the C library, and each of them has its - own separate internal state. Standalone executables and user - DLLs that call standard C functions must link to a C run-time - (CRT) library, be it static or shared (DLL). Intermixing - occurs when an executable (not necessarily standalone) and a - DLL are linked to different CRTs, and both are running in the - same process. - - Intermixing multiple CRTs is possible, as long as their - internal states are kept intact. The Microsoft Knowledge Base - articles KB94248 "HOWTO: Use the C Run-Time" and KB140584 - "HOWTO: Link with the Correct C Run-Time (CRT) Library" - mention the potential problems raised by intermixing. - - If intermixing works for you, it's because your application - and DLLs are avoiding the corruption of each of the CRTs' - internal states, maybe by careful design, or maybe by fortune. - - Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such - as those provided by Borland, raises similar problems. - - -11. Why are you linking ZLIB1.DLL to MSVCRT.DLL? - - - MSVCRT.DLL exists on every Windows 95 with a new service pack - installed, or with Microsoft Internet Explorer 4 or later, and - on all other Windows 4.x or later (Windows 98, Windows NT 4, - or later). It is freely distributable; if not present in the - system, it can be downloaded from Microsoft or from other - software provider for free. - - The fact that MSVCRT.DLL does not exist on a virgin Windows 95 - is not so problematic. Windows 95 is scarcely found nowadays, - Microsoft ended its support a long time ago, and many recent - applications from various vendors, including Microsoft, do not - even run on it. Furthermore, no serious user should run - Windows 95 without a proper update installed. - - -12. Why are you not linking ZLIB1.DLL to - <> ? - - - We considered and abandoned the following alternatives: - - * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or - LIBCMT.LIB) is not a good option. People are using the DLL - mainly to save disk space. If you are linking your program - to a static C library, you may as well consider linking zlib - in statically, too. - - * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because - CRTDLL.DLL is present on every Win32 installation. - Unfortunately, it has a series of problems: it does not - work properly with Microsoft's C++ libraries, it does not - provide support for 64-bit file offsets, (and so on...), - and Microsoft discontinued its support a long time ago. - - * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied - with the Microsoft .NET platform, and Visual C++ 7.0/7.1, - raises problems related to the status of ZLIB1.DLL as a - system component. According to the Microsoft Knowledge Base - article KB326922 "INFO: Redistribution of the Shared C - Runtime Component in Visual C++ .NET", MSVCR70.DLL and - MSVCR71.DLL are not supposed to function as system DLLs, - because they may clash with MSVCRT.DLL. Instead, the - application's installer is supposed to put these DLLs - (if needed) in the application's private directory. - If ZLIB1.DLL depends on a non-system runtime, it cannot - function as a redistributable system component. - - * Linking ZLIB1.DLL to non-Microsoft runtimes, such as - Borland's, or Cygwin's, raises problems related to the - reliable presence of these runtimes on Win32 systems. - It's easier to let the DLL build of zlib up to the people - who distribute these runtimes, and who may proceed as - explained in the answer to Question 14. - - -13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL, - how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0 - (Visual Studio .NET) or newer? - - - Due to the problems explained in the Microsoft Knowledge Base - article KB326922 (see the previous answer), the C runtime that - comes with the VC7 environment is no longer considered a - system component. That is, it should not be assumed that this - runtime exists, or may be installed in a system directory. - Since ZLIB1.DLL is supposed to be a system component, it may - not depend on a non-system component. - - In order to link ZLIB1.DLL and your application to MSVCRT.DLL - in VC7, you need the library of Visual C++ 6.0 or older. If - you don't have this library at hand, it's probably best not to - use ZLIB1.DLL. - - We are hoping that, in the future, Microsoft will provide a - way to build applications linked to a proper system runtime, - from the Visual C++ environment. Until then, you have a - couple of alternatives, such as linking zlib in statically. - If your application requires dynamic linking, you may proceed - as explained in the answer to Question 14. - - -14. I need to link my own DLL build to a CRT different than - MSVCRT.DLL. What can I do? - - - Feel free to rebuild the DLL from the zlib sources, and link - it the way you want. You should, however, clearly state that - your build is unofficial. You should give it a different file - name, and/or install it in a private directory that can be - accessed by your application only, and is not visible to the - others (i.e. it's neither in the PATH, nor in the SYSTEM or - SYSTEM32 directories). Otherwise, your build may clash with - applications that link to the official build. - - For example, in Cygwin, zlib is linked to the Cygwin runtime - CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL. - - -15. May I include additional pieces of code that I find useful, - link them in ZLIB1.DLL, and export them? - - - No. A legitimate build of ZLIB1.DLL must not include code - that does not originate from the official zlib source code. - But you can make your own private DLL build, under a different - file name, as suggested in the previous answer. - - For example, zlib is a part of the VCL library, distributed - with Borland Delphi and C++ Builder. The DLL build of VCL - is a redistributable file, named VCLxx.DLL. - - -16. May I remove some functionality out of ZLIB1.DLL, by enabling - macros like NO_GZCOMPRESS or NO_GZIP at compile time? - - - No. A legitimate build of ZLIB1.DLL must provide the complete - zlib functionality, as implemented in the official zlib source - code. But you can make your own private DLL build, under a - different file name, as suggested in the previous answer. - - -17. I made my own ZLIB1.DLL build. Can I test it for compliance? - - - We prefer that you download the official DLL from the zlib - web site. If you need something peculiar from this DLL, you - can send your suggestion to the zlib mailing list. - - However, in case you do rebuild the DLL yourself, you can run - it with the test programs found in the DLL distribution. - Running these test programs is not a guarantee of compliance, - but a failure can imply a detected problem. - -** - -This document is written and maintained by -Cosmin Truta diff --git a/Sources/PerfectCZlib/win32/Makefile.bor b/Sources/PerfectCZlib/win32/Makefile.bor deleted file mode 100644 index d152bbb7..00000000 --- a/Sources/PerfectCZlib/win32/Makefile.bor +++ /dev/null @@ -1,110 +0,0 @@ -# Makefile for zlib -# Borland C++ for Win32 -# -# Usage: -# make -f win32/Makefile.bor -# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj - -# ------------ Borland C++ ------------ - -# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7) -# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or -# added to the declaration of LOC here: -LOC = $(LOCAL_ZLIB) - -CC = bcc32 -AS = bcc32 -LD = bcc32 -AR = tlib -CFLAGS = -a -d -k- -O2 $(LOC) -ASFLAGS = $(LOC) -LDFLAGS = $(LOC) - - -# variables -ZLIB_LIB = zlib.lib - -OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj -OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj -#OBJA = -OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj -OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj -#OBJPA= - - -# targets -all: $(ZLIB_LIB) example.exe minigzip.exe - -.c.obj: - $(CC) -c $(CFLAGS) $< - -.asm.obj: - $(AS) -c $(ASFLAGS) $< - -adler32.obj: adler32.c zlib.h zconf.h - -compress.obj: compress.c zlib.h zconf.h - -crc32.obj: crc32.c zlib.h zconf.h crc32.h - -deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h - -gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h - -gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h - -gzread.obj: gzread.c zlib.h zconf.h gzguts.h - -gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h - -infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h inffixed.h - -inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h - -inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \ - inffast.h inffixed.h - -inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h - -trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h - -uncompr.obj: uncompr.c zlib.h zconf.h - -zutil.obj: zutil.c zutil.h zlib.h zconf.h - -example.obj: test/example.c zlib.h zconf.h - -minigzip.obj: test/minigzip.c zlib.h zconf.h - - -# For the sake of the old Borland make, -# the command line is cut to fit in the MS-DOS 128 byte limit: -$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA) - -del $(ZLIB_LIB) - $(AR) $(ZLIB_LIB) $(OBJP1) - $(AR) $(ZLIB_LIB) $(OBJP2) - $(AR) $(ZLIB_LIB) $(OBJPA) - - -# testing -test: example.exe minigzip.exe - example - echo hello world | minigzip | minigzip -d - -example.exe: example.obj $(ZLIB_LIB) - $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB) - -minigzip.exe: minigzip.obj $(ZLIB_LIB) - $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB) - - -# cleanup -clean: - -del $(ZLIB_LIB) - -del *.obj - -del *.exe - -del *.tds - -del zlib.bak - -del foo.gz diff --git a/Sources/PerfectCZlib/win32/Makefile.gcc b/Sources/PerfectCZlib/win32/Makefile.gcc deleted file mode 100644 index 305be50a..00000000 --- a/Sources/PerfectCZlib/win32/Makefile.gcc +++ /dev/null @@ -1,182 +0,0 @@ -# Makefile for zlib, derived from Makefile.dj2. -# Modified for mingw32 by C. Spieler, 6/16/98. -# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003. -# Last updated: Mar 2012. -# Tested under Cygwin and MinGW. - -# Copyright (C) 1995-2003 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile, or to compile and test, type from the top level zlib directory: -# -# make -fwin32/Makefile.gcc; make test testdll -fwin32/Makefile.gcc -# -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc -# -# To install libz.a, zconf.h and zlib.h in the system directories, type: -# -# make install -fwin32/Makefile.gcc -# -# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set. -# -# To install the shared lib, append SHARED_MODE=1 to the make command : -# -# make install -fwin32/Makefile.gcc SHARED_MODE=1 - -# Note: -# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN), -# the DLL name should be changed from "zlib1.dll". - -STATICLIB = libz.a -SHAREDLIB = zlib1.dll -IMPLIB = libz.dll.a - -# -# Set to 1 if shared object needs to be installed -# -SHARED_MODE=0 - -#LOC = -DASMV -#LOC = -DZLIB_DEBUG -g - -PREFIX = -CC = $(PREFIX)gcc -CFLAGS = $(LOC) -O3 -Wall - -AS = $(CC) -ASFLAGS = $(LOC) -Wall - -LD = $(CC) -LDFLAGS = $(LOC) - -AR = $(PREFIX)ar -ARFLAGS = rcs - -RC = $(PREFIX)windres -RCFLAGS = --define GCC_WINDRES - -STRIP = $(PREFIX)strip - -CP = cp -fp -# If GNU install is available, replace $(CP) with install. -INSTALL = $(CP) -RM = rm -f - -prefix ?= /usr/local -exec_prefix = $(prefix) - -OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \ - gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o -OBJA = - -all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe - -test: example.exe minigzip.exe - ./example - echo hello world | ./minigzip | ./minigzip -d - -testdll: example_d.exe minigzip_d.exe - ./example_d - echo hello world | ./minigzip_d | ./minigzip_d -d - -.c.o: - $(CC) $(CFLAGS) -c -o $@ $< - -.S.o: - $(AS) $(ASFLAGS) -c -o $@ $< - -$(STATICLIB): $(OBJS) $(OBJA) - $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA) - -$(IMPLIB): $(SHAREDLIB) - -$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o - $(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \ - -o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o - $(STRIP) $@ - -example.exe: example.o $(STATICLIB) - $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB) - $(STRIP) $@ - -minigzip.exe: minigzip.o $(STATICLIB) - $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB) - $(STRIP) $@ - -example_d.exe: example.o $(IMPLIB) - $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB) - $(STRIP) $@ - -minigzip_d.exe: minigzip.o $(IMPLIB) - $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB) - $(STRIP) $@ - -example.o: test/example.c zlib.h zconf.h - $(CC) $(CFLAGS) -I. -c -o $@ test/example.c - -minigzip.o: test/minigzip.c zlib.h zconf.h - $(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c - -zlibrc.o: win32/zlib1.rc - $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc - -.PHONY: install uninstall clean - -install: zlib.h zconf.h $(STATICLIB) $(IMPLIB) - @if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \ - echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \ - exit 1; \ - fi - -@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)' - -@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig - -if [ "$(SHARED_MODE)" = "1" ]; then \ - mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \ - $(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \ - $(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \ - fi - -$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)' - -$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)' - -$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)' - sed \ - -e 's|@prefix@|${prefix}|g' \ - -e 's|@exec_prefix@|${exec_prefix}|g' \ - -e 's|@libdir@|$(LIBRARY_PATH)|g' \ - -e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \ - -e 's|@includedir@|$(INCLUDE_PATH)|g' \ - -e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \ - zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc - -uninstall: - -if [ "$(SHARED_MODE)" = "1" ]; then \ - $(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \ - $(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \ - fi - -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h - -$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h - -$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB) - -clean: - -$(RM) $(STATICLIB) - -$(RM) $(SHAREDLIB) - -$(RM) $(IMPLIB) - -$(RM) *.o - -$(RM) *.exe - -$(RM) foo.gz - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -gzclose.o: zlib.h zconf.h gzguts.h -gzlib.o: zlib.h zconf.h gzguts.h -gzread.o: zlib.h zconf.h gzguts.h -gzwrite.o: zlib.h zconf.h gzguts.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/Sources/PerfectCZlib/win32/Makefile.msc b/Sources/PerfectCZlib/win32/Makefile.msc deleted file mode 100644 index 67b77317..00000000 --- a/Sources/PerfectCZlib/win32/Makefile.msc +++ /dev/null @@ -1,163 +0,0 @@ -# Makefile for zlib using Microsoft (Visual) C -# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler -# -# Usage: -# nmake -f win32/Makefile.msc (standard build) -# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) -# nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \ -# OBJA="inffas32.obj match686.obj" (use ASM code, x86) -# nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \ -# OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" (use ASM code, x64) - -# The toplevel directory of the source tree. -# -TOP = . - -# optional build flags -LOC = - -# variables -STATICLIB = zlib.lib -SHAREDLIB = zlib1.dll -IMPLIB = zdll.lib - -CC = cl -AS = ml -LD = link -AR = lib -RC = rc -CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) -WFLAGS = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -ASFLAGS = -coff -Zi $(LOC) -LDFLAGS = -nologo -debug -incremental:no -opt:ref -ARFLAGS = -nologo -RCFLAGS = /dWIN32 /r - -OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \ - gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj -OBJA = - - -# targets -all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ - example.exe minigzip.exe example_d.exe minigzip_d.exe - -$(STATICLIB): $(OBJS) $(OBJA) - $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA) - -$(IMPLIB): $(SHAREDLIB) - -$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res - $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \ - -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;2 - -example.exe: example.obj $(STATICLIB) - $(LD) $(LDFLAGS) example.obj $(STATICLIB) - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;1 - -minigzip.exe: minigzip.obj $(STATICLIB) - $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB) - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;1 - -example_d.exe: example.obj $(IMPLIB) - $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB) - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;1 - -minigzip_d.exe: minigzip.obj $(IMPLIB) - $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB) - if exist $@.manifest \ - mt -nologo -manifest $@.manifest -outputresource:$@;1 - -{$(TOP)}.c.obj: - $(CC) -c $(WFLAGS) $(CFLAGS) $< - -{$(TOP)/test}.c.obj: - $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< - -{$(TOP)/contrib/masmx64}.c.obj: - $(CC) -c $(WFLAGS) $(CFLAGS) $< - -{$(TOP)/contrib/masmx64}.asm.obj: - $(AS) -c $(ASFLAGS) $< - -{$(TOP)/contrib/masmx86}.asm.obj: - $(AS) -c $(ASFLAGS) $< - -adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h - -compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h - -crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h - -deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h - -gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h - -gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h - -gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h - -gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h - -infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ - $(TOP)/inffast.h $(TOP)/inffixed.h - -inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ - $(TOP)/inffast.h - -inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \ - $(TOP)/inffast.h $(TOP)/inffixed.h - -inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h - -trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h - -uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h - -zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h - -gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm - -inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm - -inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \ - $(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h - -inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm - -match686.obj: $(TOP)/contrib\masmx86\match686.asm - -example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h - -minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h - -zlib1.res: $(TOP)/win32/zlib1.rc - $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc - -# testing -test: example.exe minigzip.exe - example - echo hello world | minigzip | minigzip -d - -testdll: example_d.exe minigzip_d.exe - example_d - echo hello world | minigzip_d | minigzip_d -d - - -# cleanup -clean: - -del $(STATICLIB) - -del $(SHAREDLIB) - -del $(IMPLIB) - -del *.obj - -del *.res - -del *.exp - -del *.exe - -del *.pdb - -del *.manifest - -del foo.gz diff --git a/Sources/PerfectCZlib/win32/README-WIN32.txt b/Sources/PerfectCZlib/win32/README-WIN32.txt deleted file mode 100644 index 5002f3c9..00000000 --- a/Sources/PerfectCZlib/win32/README-WIN32.txt +++ /dev/null @@ -1,103 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.9 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). Two compiled -examples are distributed in this package, example and minigzip. The example_d -and minigzip_d flavors validate that the zlib1.dll file is working correctly. - -Questions about zlib should be sent to . The zlib home page -is http://zlib.net/ . Before reporting a problem, please check this site to -verify that you have the latest version of zlib; otherwise get the latest -version and check whether the problem still exists or not. - -PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html -before asking for help. - - -Manifest: - -The package zlib-1.2.9-win32-x86.zip will contain the following files: - - README-WIN32.txt This document - ChangeLog Changes since previous zlib packages - DLL_FAQ.txt Frequently asked questions about zlib1.dll - zlib.3.pdf Documentation of this library in Adobe Acrobat format - - example.exe A statically-bound example (using zlib.lib, not the dll) - example.pdb Symbolic information for debugging example.exe - - example_d.exe A zlib1.dll bound example (using zdll.lib) - example_d.pdb Symbolic information for debugging example_d.exe - - minigzip.exe A statically-bound test program (using zlib.lib, not the dll) - minigzip.pdb Symbolic information for debugging minigzip.exe - - minigzip_d.exe A zlib1.dll bound test program (using zdll.lib) - minigzip_d.pdb Symbolic information for debugging minigzip_d.exe - - zlib.h Install these files into the compilers' INCLUDE path to - zconf.h compile programs which use zlib.lib or zdll.lib - - zdll.lib Install these files into the compilers' LIB path if linking - zdll.exp a compiled program to the zlib1.dll binary - - zlib.lib Install these files into the compilers' LIB path to link zlib - zlib.pdb into compiled programs, without zlib1.dll runtime dependency - (zlib.pdb provides debugging info to the compile time linker) - - zlib1.dll Install this binary shared library into the system PATH, or - the program's runtime directory (where the .exe resides) - zlib1.pdb Install in the same directory as zlib1.dll, in order to debug - an application crash using WinDbg or similar tools. - -All .pdb files above are entirely optional, but are very useful to a developer -attempting to diagnose program misbehavior or a crash. Many additional -important files for developers can be found in the zlib127.zip source package -available from http://zlib.net/ - review that package's README file for details. - - -Acknowledgments: - -The deflate format used by zlib was defined by Phil Katz. The deflate and -zlib specifications were written by L. Peter Deutsch. Thanks to all the -people who reported problems and suggested various improvements in zlib; they -are too numerous to cite here. - - -Copyright notice: - - (C) 1995-2012 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* receiving -lengthy legal documents to sign. The sources are provided for free but without -warranty of any kind. The library has been entirely written by Jean-loup -Gailly and Mark Adler; it does not include third-party code. - -If you redistribute modified sources, we would appreciate that you include in -the file ChangeLog history information documenting your changes. Please read -the FAQ for more information on the distribution of modified source versions. diff --git a/Sources/PerfectCZlib/win32/VisualC.txt b/Sources/PerfectCZlib/win32/VisualC.txt deleted file mode 100644 index 579a5fc9..00000000 --- a/Sources/PerfectCZlib/win32/VisualC.txt +++ /dev/null @@ -1,3 +0,0 @@ - -To build zlib using the Microsoft Visual C++ environment, -use the appropriate project from the projects/ directory. diff --git a/Sources/PerfectCZlib/win32/zlib.def b/Sources/PerfectCZlib/win32/zlib.def deleted file mode 100644 index 784b1386..00000000 --- a/Sources/PerfectCZlib/win32/zlib.def +++ /dev/null @@ -1,94 +0,0 @@ -; zlib data compression library -EXPORTS -; basic functions - zlibVersion - deflate - deflateEnd - inflate - inflateEnd -; advanced functions - deflateSetDictionary - deflateGetDictionary - deflateCopy - deflateReset - deflateParams - deflateTune - deflateBound - deflatePending - deflatePrime - deflateSetHeader - inflateSetDictionary - inflateGetDictionary - inflateSync - inflateCopy - inflateReset - inflateReset2 - inflatePrime - inflateMark - inflateGetHeader - inflateBack - inflateBackEnd - zlibCompileFlags -; utility functions - compress - compress2 - compressBound - uncompress - uncompress2 - gzopen - gzdopen - gzbuffer - gzsetparams - gzread - gzfread - gzwrite - gzfwrite - gzprintf - gzvprintf - gzputs - gzgets - gzputc - gzgetc - gzungetc - gzflush - gzseek - gzrewind - gztell - gzoffset - gzeof - gzdirect - gzclose - gzclose_r - gzclose_w - gzerror - gzclearerr -; large file functions - gzopen64 - gzseek64 - gztell64 - gzoffset64 - adler32_combine64 - crc32_combine64 -; checksum functions - adler32 - adler32_z - crc32 - crc32_z - adler32_combine - crc32_combine -; various hacks, don't look :) - deflateInit_ - deflateInit2_ - inflateInit_ - inflateInit2_ - inflateBackInit_ - gzgetc_ - zError - inflateSyncPoint - get_crc_table - inflateUndermine - inflateValidate - inflateCodesUsed - inflateResetKeep - deflateResetKeep - gzopen_w diff --git a/Sources/PerfectCZlib/win32/zlib1.rc b/Sources/PerfectCZlib/win32/zlib1.rc deleted file mode 100644 index 5c0feed1..00000000 --- a/Sources/PerfectCZlib/win32/zlib1.rc +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include "../zlib.h" - -#ifdef GCC_WINDRES -VS_VERSION_INFO VERSIONINFO -#else -VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE -#endif - FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 - PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS 1 -#else - FILEFLAGS 0 -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE 0 // not used -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904E4" - //language ID = U.S. English, char set = Windows, Multilingual - BEGIN - VALUE "FileDescription", "zlib data compression library\0" - VALUE "FileVersion", ZLIB_VERSION "\0" - VALUE "InternalName", "zlib1.dll\0" - VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" - VALUE "OriginalFilename", "zlib1.dll\0" - VALUE "ProductName", "zlib\0" - VALUE "ProductVersion", ZLIB_VERSION "\0" - VALUE "Comments", "For more information visit http://www.zlib.net/\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 1252 - END -END diff --git a/Sources/PerfectCZlib/zconf.h b/Sources/PerfectCZlib/zconf.h deleted file mode 100644 index 77398c11..00000000 --- a/Sources/PerfectCZlib/zconf.h +++ /dev/null @@ -1,534 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -#ifdef Z_SOLO - typedef unsigned long z_size_t; -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#if 1 /* was set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#if 1 /* was set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/Sources/PerfectCZlib/zconf.h.cmakein b/Sources/PerfectCZlib/zconf.h.cmakein deleted file mode 100644 index a7f24cce..00000000 --- a/Sources/PerfectCZlib/zconf.h.cmakein +++ /dev/null @@ -1,536 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H -#cmakedefine Z_PREFIX -#cmakedefine Z_HAVE_UNISTD_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -#ifdef Z_SOLO - typedef unsigned long z_size_t; -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/Sources/PerfectCZlib/zconf.h.in b/Sources/PerfectCZlib/zconf.h.in deleted file mode 100644 index 5e1d68a0..00000000 --- a/Sources/PerfectCZlib/zconf.h.in +++ /dev/null @@ -1,534 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - * Even better than compiling with -DZ_PREFIX would be to use configure to set - * this permanently in zconf.h using "./configure --zprefix". - */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET - -/* all linked symbols and init macros */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# define adler32_z z_adler32_z -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define crc32_z z_crc32_z -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateGetDictionary z_deflateGetDictionary -# define deflateInit z_deflateInit -# define deflateInit2 z_deflateInit2 -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzfread z_gzfread -# define gzfwrite z_gzfwrite -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzvprintf z_gzvprintf -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit z_inflateBackInit -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCodesUsed z_inflateCodesUsed -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetDictionary z_inflateGetDictionary -# define inflateGetHeader z_inflateGetHeader -# define inflateInit z_inflateInit -# define inflateInit2 z_inflateInit2 -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateResetKeep z_inflateResetKeep -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateValidate z_inflateValidate -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# define uncompress2 z_uncompress2 -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion - -/* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf - -/* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state - -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -#ifdef Z_SOLO - typedef unsigned long z_size_t; -#else -# define z_longlong long long -# if defined(NO_SIZE_T) - typedef unsigned NO_SIZE_T z_size_t; -# elif defined(STDC) -# include - typedef size_t z_size_t; -# else - typedef unsigned long z_size_t; -# endif -# undef z_longlong -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -#ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif -#endif - -#ifdef Z_U4 - typedef Z_U4 z_crc_t; -#else - typedef unsigned long z_crc_t; -#endif - -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H -#endif - -#ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif -#endif - -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif -#endif - -#ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif -#endif - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H -#endif -#ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/Sources/PerfectCZlib/zlib.3 b/Sources/PerfectCZlib/zlib.3 deleted file mode 100644 index cbac4588..00000000 --- a/Sources/PerfectCZlib/zlib.3 +++ /dev/null @@ -1,149 +0,0 @@ -.TH ZLIB 3 "31 Dec 2016" -.SH NAME -zlib \- compression/decompression library -.SH SYNOPSIS -[see -.I zlib.h -for full description] -.SH DESCRIPTION -The -.I zlib -library is a general purpose data compression library. -The code is thread safe, assuming that the standard library functions -used are thread safe, such as memory allocation routines. -It provides in-memory compression and decompression functions, -including integrity checks of the uncompressed data. -This version of the library supports only one compression method (deflation) -but other algorithms may be added later -with the same stream interface. -.LP -Compression can be done in a single step if the buffers are large enough -or can be done by repeated calls of the compression function. -In the latter case, -the application must provide more input and/or consume the output -(providing more output space) before each call. -.LP -The library also supports reading and writing files in -.IR gzip (1) -(.gz) format -with an interface similar to that of stdio. -.LP -The library does not install any signal handler. -The decoder checks the consistency of the compressed data, -so the library should never crash even in the case of corrupted input. -.LP -All functions of the compression library are documented in the file -.IR zlib.h . -The distribution source includes examples of use of the library -in the files -.I test/example.c -and -.IR test/minigzip.c, -as well as other examples in the -.IR examples/ -directory. -.LP -Changes to this version are documented in the file -.I ChangeLog -that accompanies the source. -.LP -.I zlib -is built in to many languages and operating systems, including but not limited to -Java, Python, .NET, PHP, Perl, Ruby, Swift, and Go. -.LP -An experimental package to read and write files in the .zip format, -written on top of -.I zlib -by Gilles Vollant (info@winimage.com), -is available at: -.IP -http://www.winimage.com/zLibDll/minizip.html -and also in the -.I contrib/minizip -directory of the main -.I zlib -source distribution. -.SH "SEE ALSO" -The -.I zlib -web site can be found at: -.IP -http://zlib.net/ -.LP -The data format used by the -.I zlib -library is described by RFC -(Request for Comments) 1950 to 1952 in the files: -.IP -http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format) -.br -http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format) -.br -http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format) -.LP -Mark Nelson wrote an article about -.I zlib -for the Jan. 1997 issue of Dr. Dobb's Journal; -a copy of the article is available at: -.IP -http://marknelson.us/1997/01/01/zlib-engine/ -.SH "REPORTING PROBLEMS" -Before reporting a problem, -please check the -.I zlib -web site to verify that you have the latest version of -.IR zlib ; -otherwise, -obtain the latest version and see if the problem still exists. -Please read the -.I zlib -FAQ at: -.IP -http://zlib.net/zlib_faq.html -.LP -before asking for help. -Send questions and/or comments to zlib@gzip.org, -or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). -.SH AUTHORS AND LICENSE -Version 1.2.9 -.LP -Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler -.LP -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. -.LP -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: -.LP -.nr step 1 1 -.IP \n[step]. 3 -The origin of this software must not be misrepresented; you must not -claim that you wrote the original software. If you use this software -in a product, an acknowledgment in the product documentation would be -appreciated but is not required. -.IP \n+[step]. -Altered source versions must be plainly marked as such, and must not be -misrepresented as being the original software. -.IP \n+[step]. -This notice may not be removed or altered from any source distribution. -.LP -Jean-loup Gailly Mark Adler -.br -jloup@gzip.org madler@alumni.caltech.edu -.LP -The deflate format used by -.I zlib -was defined by Phil Katz. -The deflate and -.I zlib -specifications were written by L. Peter Deutsch. -Thanks to all the people who reported problems and suggested various -improvements in -.IR zlib ; -who are too numerous to cite here. -.LP -UNIX manual page by R. P. C. Rodgers, -U.S. National Library of Medicine (rodgers@nlm.nih.gov). -.\" end of man page diff --git a/Sources/PerfectCZlib/zlib.3.pdf b/Sources/PerfectCZlib/zlib.3.pdf deleted file mode 100644 index 5c71eedad26a17b0696fadf1110d138d0f01973b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19422 zcmch<1z40@*8nP|gi;DfI&?EL4Bg$`-9vYWpp|NQZRX0rebD zeEg4PQHMBu>Ps`PscAOT&_8wR7({816 z2*96-OFGFi*;2CZRDxQKOWF8RP#DR=v%qO3wiq5OA3ZrfoB=(jQGKf|mjH!JUSH?) zK694mtBgj&9eHwa?C9lqL~86dE7`p*$M*{Pd-TheMD3$}0^pa!u#M@5mk|apO*Dxr zH?|~IzVNikA5*u@1LqnWQL<9;o%s7puS3d^O1i=V)Pj{Gc;SFKe&u8rKA^H)T*c3J#YPn?-N(%uaA@_M;9p6a|n zY2v}79bETc_-3~=r?1ykH?qUWMs+fwnxH9>lCQMO!-(3nA`V?=Ku2iKxb(R^G9lRy z)&(|=ne=2gc7H!_vytwV%vd>88xVE}u?-&89x{Bw*q`B5U^;zF#70daTopk?Bd&45PQ;e&hItc-Mov@U+u!RoPLZ1Ihzf#*__jQY`s9Xoaxy1?vnO5F!Z!+e)|SYUs{md4=GJ z^}cWp#^$?;vABZ#9jE`h=A#`0?kmW7Rq%-9oZ}$6*1@^c3<< zJ7kx-E+#g+jDq9DH7-v1xFMm*W-tADfg?iRb7j3Gglfeby{4+$>gXGy0ZGiK z;rd|(n4bw6=C(35v8A|N*NSlHkH?g|uwuSQnq<+wV?kTsNq?4MoJy2vrRHj_ZKDmf z6d7*auxO9tsqA`2J^>SV^JiZB8Q;fZj|#MBPd=e{1^xdz6@2~s4KA?1BwhUncsCFSeZ#0^W% zhe*JE3Uoe~;wDOSi@ea0=q`J|JuLXrJw*SA%jamhMCuE|ekf=rp6Y8=O?u?~&3z`} zye3#GUM`kRQAw{zUqeqfk)55G9)bbfBT)?Gs5gG1%}vC?|o()3&yKa zZLw9~q|#8mX8MYX70Z(t*?V6npjNR07a|!S_oyw?jFDl!($Q%gdvr-Bu+Ohv-_CbO zDgDDp?VVb@k@|DEHzu5n4^_^1aWG$cAfACWN*2asCym3r7>XcGGfMU3w6%02G>9>| ztx#5FYyB^9;|>oc`$V}g8x}%7tsnF_wY{~TfRC3fErgT#3@1)Fl{ZzP6(p`$7j8sC z(1#eLEs6qIm_c(TQ|?DRm)q;go0(TFww&siO(7My(nBMb|0rs%yx*2Xk%q+2(Jmce zc;#LFW+58q^Q1L{*klF8Ql$rhsYDNh`>1(90&kt8rYpf14X(hOEKUp2Vqid`BLjB-wgfAMGc+vXiRNkx` zwc`5&kVh#x2E{7wNpR70wM_n;HA#?`#UXKail8ZW*KCxMzt4GDgpne>XinTc6uii_ z?dGwDkf${7>?P1_;e8?Vh!@+0S8593fz+>7l@j2k&Us@Mk#Od)kk{<*`_m=p-pNZ+ zFw{{HBE_j;1zDS8zI&tyrhJiDD0Cm>dRb&^_8Dtxhg81fBDrPxg44~ct|R@@XRO^$ zcDh6E(Nl@Wx5EkW`D*qFI;JtwxdUZ_?w#85>Pu&(zSdgg5~-GDZ}KI^q)@P_D>9D8 zFxDs?JaM}+;cK#T-gah7AmU)8C&;S%3#Y93Clxrwp}KRTR93_v)1$xn@NkbB}0|FN%Y&W17rz#jz(} zw^Yy)?tBfIGh;h{%)%-KZ=y+pB)gM<2sdkv^wyDc5AW1za$D9EYm~_KeQ2ok{o`H^ z;eL{LPjF@=^6{Pz0KP}s7dUzNMbdgJ(IezlJbc-)FLM6I6@|d6O4ibw;xb1UlO`ud zCSxs93BZ_IC5|N@gc&aCft8P2hA6!tw^13~rD$3mWh)V_J_n?L$J zGuwDQT`YxcxZ)gt^6>{v1uPqv7jjOq8j`J%?|JI?tQ7+Y`=8Y*ASOQ_)MZ5{Ve{#3r*WcgFT|ic zjr%0hAY4fI=uY-)6~`-3962`LTHpy67xSL^!9@QY<-xj}|%%GZ(GDCD?PQ;}h|uy`^t?^JEjH z#HW5sUe(>l)+{EIeA+KSVc1dSMfk^V$%6?SP}B8cu0zEc zPb&&8z=4Mqb(Wf8DpN#;lh|8g`z|8e4#R}lK6}*|_NJwpE>HO@U26&ygIbj)FcP8_ z?YlnXcK|0F)m`lk1gZ=%mr7bfOa5ce4LMVDX zHsjUSsYA=2zAnSF-F;qDx!J-#6tldIv!B1?HvcMpc7A>kTbbm#Avs+u+^`RJ;tYLn)koYn!(w*c~LpH!!unV5N&3&PQO{F?IcAz<)bEN;U-L ztd1XxpWh6~R62M45oOQ#br{N!cbxyZWxKmS5jyTNZWm#?LS(9<|N2+^z9Rv_nzdMp z8DR%RJ+Y7!s?x$U2shFJHLYPreW{#mstX2c%JFl@VkFthK10xWtY(BZUj55nWlAqY z=S5RSjHXwGg=H@JSp>XQy4R11P_H-mxdI0haGy*U=j~n*BfK|kQs^4$z;TLv#2+#t zwz=r9FHs)9VeR9IRCKD~%_rc>4CxjCq6{`!)~Xdnen=O_Wr3$f<{YGnbE z86uJjpVtaxWn=JbXd=ml=Dqs+>5Yjm_>*ZPUrIXl`>gHAc-chsj^)l&eppw(vRnQF zUM{FjK2ZpGc$^t5GN|=;-{mVknWAp4=XH%RwwHQb3C`Wm zGd|NO$`P8)x`_~#!q79s43DvyFsAJe4mS3CN8Y1fXd7JW^z7jNrXleAyDoF0xbIi&N^S&CgJ>Ir2Y37P0p-*g(m_u4fLL z=?n(tUZK?-SsBF2;9(rt}uiqGS5Vd{c{2Ybs~``~}^2 zSIox7d2mbH+7$%ekCKu&c3;0e7ooM2V(o#m+^V12>{DT*RnbT7GFh}2wP$tBPlvyY z)1FU}PQcnA&BVAybMNEQlP%q-`-MsjagUtO9? zIL4CEFQ6vl;bH2*Mx6fM*Ourx4`QgT$S0-^qdf!Y6Ys|n`# zZ|*f+GU`Ck*znLWYd9|!~;p387~R`NTtSOCx0lK!y{nsI<4mTnEDwLF+E0? zuUdD&n@{*Pb3VHn7S)$GPFC{o4_JQZ7tNQ;;z?x_$5U;P$a>cY@NY^%oZ9Mdvfovh+}9==|s;Zv1ry*X(gI z65IDeI*0a`t|o98u`HEu<~vdc#JBwc(oK!{Osm}iXoit0C-4h-e9#DowxcI3c(+TQN=%<3Lf7NpHLbZ zp*ienwnpEqu(EQDifA(3A}2}O6pPn5TV!&7c&=8Ee6Q7Oao-B96%qYiMloHcUXlcx zzyH{XN%f{|$-)fGQSieJB298a)JqyvQwqq)UAzxA2UP`x%`)WoOY)eVj_9pWyD|Yf zQ;w82J06rkjm$6Cdi$=d+I+I4J_Pn2tW@3QOTiG}jRTN&R~YBlu!A@WsL&p~N|bhH zUt?`bqTMcJI!5?kcq>{X1xc>Y#DsY&RR;iG#>SsbY;1{D<>Zja>< zO+{OQME)_9U#5|isOO%(Omw(^9yBWb^VmvCqN1NlgYY@)#W3pC-eNY>U9LEqcS|0s z)y?GJUS^3eVp#3tQVqRg1XFgxKgwAE5Gjg>M@O-qzF#y za}?E~l4(|dRD1++6cL@9z$mu3M>ki$$t{bW8xr4A-mCL|%iPU`S?(*bXhM>T*Xe?q zPw#dY>bMP0hM;hpl{;;^gP@e z^8ppT^*nCkGP5W?ls$`c1XtLN1rEG?|5SuZ0gx_M7|q6@6nYo27UfLt8HqH=3!5#w zJ1((*CMIoGk<^^L2+R64Ef-IgJA95^SLx7Z7?3$R%JYKktn(W#4 zDWWtQ5voPmx+g0tF= zxVhO4&2_J8$HB(I9PX5~GznR!V2xg&nSdBl3)WlnGS5YNn4TymzfQXpB?4Vk$bV=H zM#H<9<(U^e9d7^HycZMB$NiL1_6Zs!ybB#?sd`JKaSOd0b<#ai-FP;>@wJ*FQQchB zhvMnF48qX~^ofN5y=x3gl=OVR_UHJ$ojc~Z)m-exKu=$Znc(UP-wOrVQTXsrf-J}G zo`H4xa&ew73S*8Y%Jkptw>`icW+&&>8YmV!Wx@OqLWrESJz2I&U#?3P<`m)}cRk6m zWBSm*9hdqbXV(+#ODjbQfkZ+(uM#oz>sn+Dcn3a5XNEqYR)a%zZjcaThr6OFy+Y)@ zaAJM(4s3;nr|=GfGvFyZ>pq46-|K%&^5tsN6Wo(abaxhDK7PG*Cvi_9z{x(ztB8R~ zX>o5{eGG>pvqNljVlR~>h$Nm2X!KN#S(gZN8#R{wl_z(RN{!jtQGn#>Q)|U5>X8D_ zuEggdnF2V2@KUerz)Sa5ig5XH1YS!;M++u%+#sN9=v=>9?laspfgab?72t zj<2n{tApQ!mxXe%#vxKJ&Av&x7HZNG{)8n~<^Qmh;34rE6(%ybP5XNuXPvndA&QAO zEaHHy?G(?8I-rTclX(UTN#oMkAyvl){@0x;U?Vp4LS*%h!v;>*c;upS(!O~;yWSHW zzKbzWdFGu=g$L_A%ACR5%}+ttp>TLfX`8MCL7RG1ld`jS8XvbYoZeeq&$7-t2aM@) z;LUsKY;qGWROS_VD3hET5(EhA6!D+1k&+D*Wcx0!3-MAaa3f`3W0a%6=W&RZ@H{Z8 zJ-v5zh0$_tv;7Z;;C83K@d&`2?2um`0n48bfr^Jc6sTZm1_jDOO)LzB?A!s`AXqgU zm>Iy%$*hYCRI+o1MWO*97?vZ{))@e~aUEb_sFR(GqcPM87Qj|;v@=$QI%@-AA#MOr z1?uh$qZ4&^7FWI{1>f`sBN4NMk%Mmn-%6;km^M%tb`5LM3GfH#m&fwUje)iO|H}Y5 ze;Xk4&Gi2^z*`sU7WQ+5H%#~uy@$;g#zMd?51jx&X$uo4fHvxn8G~;_`lz}9*i>C$ zb7#Jp_OChq(ZbILgbkeyt?kTywe*wCvQTG36Icy^`R`2n&8xfR(I5Oq1FHH zzk2#j+)C`IH*`wBjpMh22qiExDopOMdY}>*gbKdp1W<_s_10bdjpl}5Kc)}-XN$KC z{8jtkws_O)PZ}XZC+Ll;0M+Cbq(r6ZC7{->P-hEcLq>TcYYPV#=&d4&K%I;oE$p4` z90A~4Uj5LN8$y_-SvWd53!57{0wByl8N;7tFf%hy-NMA#+({dinf+!?|Mvb-bMp=R zp#B@iZ?K>B?94ag|LdET^+x)z_kYpG4esp+bVKoj@)wNxXWKWw91zG4JXSW;A6SqZ z2#o5_`P^K=+5mxWY|s{Veq>>52Aj66pska|AJ@t*M$R{uf1^1tP5DD9Z%F?x1}$YF zNezwP#2{p6ZSoHpfMJwM|GNx0IR6U~+>8SD{x2AJ!}#AnY-~5`%?=aZ4fGdN*udah z*4<*lg!&T;hH+E6slBQB(JKt{|ABEg%Jg@>NvX?dsLB1wx4*OOcG3CYIR<8j{707E z=){c%+35m^35;obE_l2^ysfz_2<=3+@I6Gv3l4NeajaZZ+`Li4?g|I*&9W> zf!{QBqnNimyyfjL{{KPslhd3mEVmRl+Y9)obZ)x8Re6}S{}?K)?nnGb4Gi)c;Mul(!9bD{S=f@Ui=FX^K77)dTr(eTYOQ0f=b@Jg{|{2?}G*?43q&H0*!#iKw~=_ z8$%!zXa+O~S^%wqHb7gT9nch}7lYiO{E(5m2}#3+lJB%(BHaCw33$E#4h#~NSF5v7xlE;3m( zq<5A6@^->~y>DG4x<$z2TD>^=%KjK2D8UeGa3L)Tbw-UKiBN5vq#6l#K4dpfS!tO~_{u z!+xglg)onU#u4vSf_!KW_(4qQ5P4!ULZqIPV`?ZuBH-83(GKA5i1 zVZGS;&{$5H%)T0SYIrr_%7EfTT=6`XH}5&p!ZRFH}eLEav>;p5QMw3zhJ=6_8#$;RrrYJ z$j4>0x`^(C(l6k&bt$9pO%ZlvTOf1cw+#;)8}sn9J@75;QJHQOH`$vzBHOxt?@k}l6T=@N8lY1EWsC!YNPABqd*kYUaLtPPi49gZp#XZ!wfbAb_g)hkyan2Ib z#j~~p24bfpb*_>-5u6vv-mdM4P-$L-sw1j9GqWmtf0`mZ>a6EhoUvH}YA#lqfwf$l z6QZ)8J4A&9&cM|t*DS247NKPZd~>qVT>bKLH%?}u# z_e7Qlktiel>WyrMzu*0qteL2((chK`A?Pl{P7An*JGBgLi-rKljCEVNUOzojpB;KN zHm-*JriUq=?NK8=XNfJHF>gFCw>FV188HU2py>N!ipr2Z?VyX`1d6j4v_{PM#Ct$& z8*$RImzYbl4E=`Bh_^VyYu^Tdz6uan<&VtEtt* z?JFvgc8Wlmt*%6=qg={Pw~$MJuG zahCJS_{~ZZC6urHu21w`jv)7*$3$wr8uXXq|w|ILJ!z&J^ zzjmK7RJnYST#3HITO122sZJN*ZN^=3B8prwMK%k7jG%>ccn7%*92)JHll$7njka5a zQQY&Zq3#VwJV?vI8$IC5$8ZE^jdh$%e7*Bcps;ZSOBP2bZ_bX$r2IP}C6gB-={DAV zIM)UJ6*tzU&|=yZK7dm)QL*r2G`bN^zz9-7zn8Xtx-wn{-9xp<9(eQj`S6j7S~MFO z$=M;)ft_OmG~vN!IZ1rWArujDgj&Y8oq^VO=gaPGv-m2`WNG}q< z4OqUcVBzjryZG@d=YR?K z22q+^%EIfDvgVf&M|375;|KB!wPU?UIdDYksI`!mOZoCwi~Jb%O@^r)ZB|JOd|dJx zuit5&`=q^Bq?H~?yug+<$C(~a4A*bJ8q`afYV*uDKHBYd!d3RyAMaC{+e~pdC!abS zl6LLCZ{bDaqFwtf!BE^u$w?_t`=$IVtEredbn;z0eWhRw1e5N7$Ug3x{j`j1+Rtm5 z$rxi6tU&{v>YccO&*@J-c%J6WoEJ{vq#5pH>NXS(N~4Uyg%Q5`QUQ7rE53;xZ`2*H z#oNzTmDo}rysG70N1FP@n_YNio*|)LxV{je)^N&@V6h>;{$4k>CPV6#g=r?2ym}(( zD~Qk6k1fw2;N$j5Wdd12K|Q^UI?flDc*EomaBl9J{(AfZ^J@RN54iQ=Zf-~a&8Pa$ z_f)qI6$s`N!5nIKw%@%eHkdmL^OOE7hYIqa{3$Tozxh*txKM&XA($H_0u%*`10{fx zFo#MOC&-52>={98Wo454a&HR7wErB5%EWdk8%3dW}%8 zj^@}(KjXaP>YOZ6crAhSC?=>^0n7P0e0_g%$bvg7~&iX zpXDpd7Q^{sr|>n1+2L8Y(fje{(X`l2oo_}*;-jnFEjxQ&@xqRH?;U1xlB+iTSfoFH zcy!&lx+$LSv@l`@h_Gsl3B#X&a#=I&b>8FXbE>_J< zw3O8PcyHpEPV|vTzu?xnZ^h;+4ugA*mzUH_rDU|4#DazxSO^12<-Y_TcHcWCL)aG= zW5GjuEx>}&FWzPjw-n8t9sI={i!1C!9mp2LZLYJIax!;l<#jJ(5?B*ZSWG9@q1PFah!r5ktg*T_tjm z?gaHCmQsI%=Ulrvajj0F)4gpUL4f;<(m~THQz?=9ZL=q?TI21mxrBAzi|!j`qq|Wa zc*^p2=4U6nWW_m`@Q(|`0x%a>Ee=w~@K{BUO7d z)l6nv6HP;-V=xQw79p{HqsYFN>$>02+&l=F1Va4BzO}tJP}gcrQ1Rm)|G>4m69Zq7 z^EGUBGckwTmoeUWTDg$>dmi^Xx_!2%#0#9)o+yi|T19xS_z(G5n1h+mz>=V(NtW7Mm?}Ohi zf8OSVU!fK#fky82T(WtEDI#l3f4 z(Aq{xaNZAbmRJ;PHDFidpAyi1?Mv`M<~|!mLFTZ9TGV^$UR&&RdB2qBIdjh=yZ}ws z&n|_eC~K@2iOr@}L73Ty-Be9vG7g9P#dsnkz1*H%c(^nL4cSr6!e{Q54swZ+37)ya zKnbi#eh(r``%PSP`pJIfY(xrZnJ5L0OslEdko1Cu>zlPe;kQdhY9hH_hPW6#tR6>9 z8zCe!hwv?}{?uNj$2#2SsQhNzdHnhg%l?Fm)TTyId>1@Jr55%FSua3#MOoj1^9>M} zFY{lMu#ewuc=_CPb&J<^0xm=a?o)8N(sPSvkrVQ zLOQDDFuqL$i?I2H-0fd(7kq=fgVxmLq;4r2+7vhu>b3-3K@x`~U|y6M6w>kq$j7&@ zjv#zkZF|T#dxF*6SOPgX%-iATBnnDE$M{+U;3RC&aX^1U%d6&GRX~Sfw%BJ>S#5s) zHIS09JQl0`dFUs3Tk_TFJpVloatsK67dNnQoJ<8cO zyf~S3r9ADWySR&&G0pp&fdqg1geq?T31RBo!!yEBgR+IvF^ zD%u&d-_sN7m{63zG^DL>-$J|p;|}(((XAiR09dr; zHX6Xm3Ja|L84Y0hFZZth91LKA#S{J+4EUGLOYGC+xW?C9KqVo_GdJ~1Qt&)y^W_>xWY=-x4{K-4|{W{ zEiA@h3ADP6Gu%d5V9^F!3tK2G z8zBE}gZ?e_^WSgKENrZtzirSF8Yn7{#%oI677CgSZN~?jv%`ssP{G|ZQHYl`QJ_Nb z3l67?3kHb9a!@D&rLwX<6l{f`5k&_RAc;~&(qJkI+O&%8PmvB6d@LNWxjL^UjB7j| zKeK8=vQkvl_1@t;->e*L9*S4w56!b!UZ^T=uku5p{dmUBJsgS~^!;IwbmCGPzo~f` zz6qHimDpHEfT5Bi82NLu|G0pZ(5O!Z?Wp5H=mDOI39iO;m&gDKuW9)5y!?z#m#4-c z@ao{9)pZpm8na{ZR=233mYS`etCpPLiQnd_bdrWRkCozij3+OKmg37}KkZf>zQnI&CdU(D4A*-Uhm*?d z6@OVVth^e}St{@BDCg)vys^q>+xQ)EP*U#^R9I9YBc72pjzF+KtFa(Pg#s!rs+e71 z-jflUDW+TzkHDHrAnYw7n@d#4VM(we(y4qE4`B^LeXUaKn@ORP`S*UWJ3i^ulOU2bsk1PSK!Ldrr-w-T8P{H9( zn3gn9(FfT=l9V*$me{I7=~-PPfrraJ8JDX^)5AOJA-NP%N)(EO{U9wH=b1G#vGxft zZ6EIE3|SNQia}0t+q<<1R$qKpI!>TZm9MWZJI=4oH=!356`pt4Uq5ZFhU2A5q;jCD zqau{mOO0fEz^V(?GMqB68QpBGE3Aw22svdtSYE~J*Y4B5pT-RGFz5ix3(iYK6{Bzg2M^-o#fO)YoVwqrX$o4#9j-`Wyy*AZ9d zbr|^JMvPLpb-#*~_S92uL*bynP4lpK+Cy900R(cNPtFq(scWs2gjP=UiL+Sq(d&$; zlj_c1zuSCY_>|pjLX}XUrV2X(N#kCt0ZN$Jk|hz`*nLxt6L^HVEQslI9clrDzP1PV z?TfEc>1fp391{*R?~+)yv*NyW!?@=kY9of{syd#=QP>zvpx`Febbz8qHOJ{#e08PZ zT)1{#Wn9>`-10zxrxeP15_zYWG`S%dy=1OsQ(%~Vk_IU^-W15xqn}vm$>u@(m>=sk zQ7FeGx2la_t^8BJe7_vsAu6t#Vd_r`Wr?jmdjZe4W^Ky((bsAMhYhX|iDi7F9qh`p zv-;HCT|4nGJ|LK#)^mv0_}({pU_%i2lC4RAvRP&LD=T)1e{cZNuDwMUi8;&uKxjxZ zA7clup>cq0kr>M)9i2sp~? zJnJaFmMq+ZHe{8m&s#T@-2r9xd+$d$O=r<``wwys1;b<4$1IO zj9Hu1{M-@p>_JPu27S+Drxqfh6DEmC4bmsZAcV?|sO!Qt^1-_}@kMJS5s0P& zNdTXM5pU$&tT$4%&FtDLMb65a5O<-qCYjSfr74-#%4l6XpTVt59efF(9-Qri`Oc3z z<4L7-+J-p(tH6}yj$Tu~uZP_?hU4>JWeh#*FO?opA(9=#m8&0|29))wl-1N4(`xfdMn;AyY+hShtck2ToX=~pdAzP*JIK_%>f;iqUh8X1@ zAf;4DK4Dk>Iu3Z=yQ1RH^ee($8QDv~)0*QDr>vEtqgYcIMEGMp+(W*8{lw+7 zbzex@2VU;+XR5Szi+s8Vll9o|&58>OlhJ8z~on(-mpy|4!AB`!JF&s=n^#-96b>?>sKie`fz zEMk{*NvE}$Q~uTc7b=k=6V#k#8Ipj+q0fcv=P#RaUr3GGJAx=e8}O-dr#GIKSFZ^( zk*d_D4kx|QwaU(M;|c1_$&o*dFIyNY9>h!hg7=k)MpFE#z_&W4PR=fTA~xGs@csfv zyQC5;OD~%b4>!W_?)q06dTXaIBM-;me~cXA)QUsH!zKF2HaIb!)oaIv_aQoeZAxss zz)(9#x;ww=p*| zw!(H%?1dka<^g}C_*03gn6qALI5?b0hxx5kaCf6$p*C?G8#^?u zVYn!mCF5R?fWy1j&^}y7Y-&zWKj(j1(xnzkUh#+wUmQ1Y5tZmgLZ1^Z11T1RJ=sAl zYn6AE(tWFY`dK=}_AzT}?Ue8yc1M@oX~k?84QFX;^wGzdq%TpMm*)*TtD^Qz^XL{Z z@433yzFvP=Tz*Zi@m(T!CH{~+*7u2KL;%f)!g4wJJ89V?J_2+s0YkV^pE#E?bLeat z5Z8{FQZ!QZbW%bXq=)l2!g^0>XCf20n`ivdvxHNRpL!XLAMwtA7AX8|-L22-9l&x( z=Fa%kW3e(@G>F+!7(_82o>?L(7J7Nx&+p)}yGpZV}C3%f7r8Ic_Tb9Qp_Xr2+OnMP^9Nvk@;Ccp^OX0lDo;aMZ{!U%zyM9*i#5ru=HpG=i^OJ7A zp^LxB1LORts#F|Vm)SmU;h1T_I~1NN^9p!AtfB0|L13BQ?)!};^S4du4-*aeH^+?; zjtoYI5jSn&)dUTM#6Y2HmLvF2S|>f_pn7RfX}7bR>{ zF;@lNSFNm@;8hI3`Euav_lqoEua6E}spx9=La~XFx zqd7iW&_(#UQ4L)BtfKctpIgH~CO6OhSD#*pckfX)g@&n#mE#-L<$rf-Y&81%Zk_Xm zla@hr#$6LjV)c$aHnd65a7F<5Wn5F^%QOwnS=8Q{3h!AnD_g--} z#bvV+39(BH?Em~s~>eW3ds__{7Nwg##VUzyZDQ+w7rm9)`nGKsQdT%;@xd-w-K z>6NKBZ3cmqp^Zq|l#s$jEVfL>GF+;*BocPZRGrO1%_ zS>oc&YPM-}KiT{_CF~)++EGS=7^(wta$6jQ*%UiIzQhsEtNU!!@rUKd?}cXuM4P(R zTMs!?DDy`Yb10=4Wj<=9C?~%&qS_a#XkfP5zuH^hds}J3lZ0d^%@wbNH}Mh$J4cM4 zZZN%|gl|MbYWAVa^c5gOk^8;(e3q1RV9U71Ib=7YvMYYwzmv0MYLP`QX{>*O4pbI1yQ0;TF2GtkzRYOvzcj%nduT;@EaJT5Gi6JgVn(fnKd zbMn*ufH`Y~fgRcF^0r-8PW_2W_tH{4;3Kb>iVW7&)DQd*FQ@Csz7W82`|`9)Ap%?lXGyuNj>>M8wfL91y(>7fKI(%q3_k9F3ua63w$H z$azN#@XpqL8>Se1Ido59R+&fgsT6$c^2Zf>M~hw|#E=zrT&iGTtM;)U>8bh4TIX!B z5sBCe-ob=^y8hk^Kl$a-geSZ~Bzt9&J@Qo!QuW^}5c$Y=!rO5(IS>~skQ-*-la>Wr z)%Vr=+wi!P?+PsFq4CWc2wR^S2U}%!D!+c@423hoKldR`KGMi)d)ZE3{tkr{`2(3f zT41!IL7RBx>_iQ&7rCQp>-OG67jazRmB2*agFY=GTfuS0a*H^U4Zj%PB{61xYV-8> z)$Jqer~DL8LaA(cAEhpny64!0)#hCtX4LQCyd8*QQ)g_3x;)Y4c3zxX(H1Ak4C3kQ z053#H@7-aDICe~mat&)0esBbQvbrR2ayHkobx(Vx&W#FJq%54Q*K`2|gqj7=m8a}} zZob?4d4llZAsE6}CQxVRbUGmGg~Mwf-_}3n>D$px3wnNeo_Rdc5{Fug#^KuHw!)bUYU6H6sy+$QKYIGzh zzMvOC5s3lV%zx{mIV#KUJlBv4Ad`Dq_$*h#!a%-)qztEtKDn2nc&OCfj&6E-eUw*W zjNDhsCJjU^`X#4}`UMULK~en~mV;^J!fUd7V@lD$OS5)H56{`Y9)tJik9qmO24~wF zWsRDD4R}S0Yc$CFY>pk#d}4~xw`9pvu(ny7kUgxo-FeuNr#Jv(OxraF*Qz`IcrzxL z@RMIDf5U0eGnGPMV?E24BxyXY5H>wsN6tE~x^LO(g60gU15ytL<x zgtd>ic`q-0J>T=!<8pFZE~X9L5A3zJ<~P*arQ5WmHT{k+wx^e>qH>6Mq|u#X2(CiY zo+x5oh3byD*RE+Kfl-nk=eg|4PL9#wB8BE9not$?0yVoa>gns} zhhOj|eMLp?AO^^~$`zvU;(L&X5#4G1wnDGa8eKuafEGNEnx034&_WN?%O+fN{>CoI zv-e>+p!Dozq%9U{98X7z&$nh*-4eT+=8!A2kI*2#C?X8S4@OTeJODLOow*l~8iLS_ zcI(~eNIS|=)=_1JvYl^-7CEc^mEaO3SmQYJr|3I7*B%Hkj5eac*nu^QF|5Yua0$W zRPe)RwatB`h56gB0=+l!+z9bg7Rm-GzEp}LQd}w%&Rkp{Ikf3H9J>b35Huxifj-|a zpq+nbvHaq}ioOjqm{YZR-O90I?@gJE4DGjPa14XBRsW1N-sZIap7Qi7+x5?k8Vy;Q zU+FYp2n*XE@h2XBcUbBUENllbf|^;_@>1_Kv`_;qOn9l)S!F@8_QFte3kgq0sIsS= zim|7aF{cSNKOZU&zai`~DJY}6p*^GN?H_G80bof;ykx>kGGb&m2<}|&Hug5Kq+5Wy zjkT>4mpd=@EeRK_d;P_CQc?WBN)N}Fm;3_O}W`Q zS^>aJY}BwO9ZgKRlwgU`KN^Hx@lu;RJKJ*sfo^VYOl}Y+J4Z7hn3Ize2x11pj+9^+ zj7}c5&W7%cwoc@*{%!|iq45WqtrOGjn3!N`PCyF{AeadR{MFH~!$u1`Tfj}nhDLTS z&b-tvE*2(S>?|Nt2$bEF5yWn2%m@aXGBbi;FGhAKl#`7OWDGWChyLo${;H7rESq%S?z3|(y{V%(w`8Ttsh2>n{SP6{bH+DiJ!gXV0U}gvy42Ce@ z+7~qlL=8iO+2Q|!@zWY;{>@%!|9FJK-4SXE%fn@6L%mtBe!Kv%db~J=#>N>*yJ_`U;w(x|)bOQi;RLKtZfDtSOM+pFwv^BK@+-NlH!6Qi#fHn`C z7%PVmNK{Oe6~qE!Wfx`_WaZ!#6NP|SI7LC6EMk2BJBIGf^E*z?hK|m+3JK<5XW>Al Lq!g7GL;ZgM@4LVU diff --git a/Sources/PerfectCZlib/zlib.h b/Sources/PerfectCZlib/zlib.h deleted file mode 100644 index 69fbb978..00000000 --- a/Sources/PerfectCZlib/zlib.h +++ /dev/null @@ -1,1910 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.9, December 31st, 2016 - - Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.9" -#define ZLIB_VERNUM 0x1290 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 9 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip and raw deflate streams in - memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in the case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ - - Bytef *next_out; /* next output byte will go here */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ - - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text - for deflate, or the decoding state for inflate */ - uLong adler; /* Adler-32 or CRC-32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. In that case, zlib is thread-safe. When zalloc and zfree are - Z_NULL on entry to the initialization function, they are set to internal - routines that use the standard library functions malloc() and free(). - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use by the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field for deflate() */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary. Some output may be provided even if - flush is zero. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. See deflatePending(), - which can be used if desired to determine whether or not there is more ouput - in that case. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed - codes block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this - function must be called again with Z_FINISH and more output space (updated - avail_out) but no more input data, until it returns with Z_STREAM_END or an - error. After deflate has returned Z_STREAM_END, the only possible operations - on the stream are deflateReset or deflateEnd. - - Z_FINISH can be used in the first deflate call after deflateInit if all the - compression is to be done in a single step. In order to complete in one - call, avail_out must be at least the value returned by deflateBound (see - below). Then deflate is guaranteed to return Z_STREAM_END. If not enough - output space is provided, deflate will not return Z_STREAM_END, and it must - be called again as described above. - - deflate() sets strm->adler to the Adler-32 checksum of all input read - so far (that is, total_in bytes). If a gzip stream is being generated, then - strm->adler will be the CRC-32 checksum of the input read so far. (See - deflateInit2 below.) - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is - considered binary. This field is only for information purposes and does not - affect the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL or the state was inadvertently written over - by the application), or Z_BUF_ERROR if no progress is possible (for example - avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and - deflate() can be called again with more input and more output space to - continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. In the current version of inflate, the provide input is not - read or consumed. Any memory allocation will be deferred to the first call - of inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them - to use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression. - Actual decompression will be done by inflate(). So next_in, and avail_in, - next_out, and avail_out are unused and unchanged. The current - implementation of inflateInit() does not process any header information -- - that is deferred until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), then next_in and avail_on are updated - accordingly, and processing will resume at this point for the next call of - inflate(). - - - Generate more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. If the - caller of inflate() does not provide both available input and available - output space, it is possible that there will be no progress made. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - To assist in this, on return inflate() always sets strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all of the uncompressed data for the - operation to complete. (The size of the uncompressed data may have been - saved by the compressor for this purpose.) The use of Z_FINISH is not - required to perform an inflation in one step. However it may be used to - inform inflate that a faster approach can be used for the single inflate() - call. Z_FINISH also informs inflate to not maintain a sliding window if the - stream completes, which reduces inflate's memory footprint. If the stream - does not complete, either because not all of the stream is provided or not - enough output space is provided, then a sliding window will be allocated and - inflate() can be called again to continue the operation as if Z_NO_FLUSH had - been used. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the effects of the flush parameter in this implementation are - on the return value of inflate() as noted below, when inflate() returns early - when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of - memory for a sliding window when Z_FINISH is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the Adler-32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the Adler-32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed Adler-32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained unless inflateGetHeader() is used. When processing - gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output - produced so far. The CRC-32 is checked against the gzip trailer, as is the - uncompressed length, modulo 2^32. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value, in which case strm->msg points to a string with a more specific - error), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL, or the state was inadvertently written over - by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR - if no progress was possible or if there was not enough room in the output - buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is to be attempted. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state - was inconsistent. -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - For the current implementation of deflate(), a windowBits value of 8 (a - window size of 256 bytes) is not supported. As a result, a request for 8 - will result in 9 (a 512-byte window). In that case, providing 8 to - inflateInit2() will result in an error when the zlib header with 9 is - checked against the initialization of inflate(). The remedy is to not use 8 - with deflateInit2() with this initialization, or at least in that case use 9 - with inflateInit2(). - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute a check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to the appropriate value, - if the operating system was determined at compile time. If a gzip stream is - being written, strm->adler is a CRC-32 instead of an Adler-32. - - For raw deflate or gzip encoding, a request for a 256-byte window is - rejected as invalid, since only the zlib header provides a means of - transmitting the window size to the decompressor. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. When using the zlib format, this - function must be called immediately after deflateInit, deflateInit2 or - deflateReset, and before any call of deflate. When doing raw deflate, this - function must be called either before any call of deflate, or immediately - after the completion of a deflate block, i.e. after all input has been - consumed and all output has been delivered when using any of the flush - options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The - compressor and decompressor must use exactly the same dictionary (see - inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the Adler-32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The Adler-32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - Adler-32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if not at a block boundary for raw deflate). deflateSetDictionary does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by deflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If deflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - deflateGetDictionary() may return a length less than the window size, even - when more than the window size in input has been provided. It may return up - to 258 bytes less in that case, due to how zlib's implementation of deflate - manages the sliding window and lookahead for matches, where matches can be - up to 258 bytes long. If the application needs the last window-size bytes of - input, then that would need to be saved by the application outside of zlib. - - deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, but - does not free and reallocate the internal compression state. The stream - will leave the compression level and any other attributes that may have been - set unchanged. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2(). This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression approach (which is a function of the level) or the - strategy is changed, then the input available so far is compressed with the - old level and strategy using deflate(strm, Z_BLOCK). There are three - approaches for the compression levels 0, 1..3, and 4..9 respectively. The - new level and strategy will take effect at the next call of deflate(). - - If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does - not have enough output space to complete, then the parameter change will not - take effect. In this case, deflateParams() can be called again with the - same parameters and more output space to try again. - - In order to assure a change in the parameters on the first try, the - deflate stream should be flushed using deflate() with Z_BLOCK or other flush - request until strm.avail_out is not zero, before calling deflateParams(). - Then no more input data should be provided before the deflateParams() call. - If this is done, the old level and strategy will be applied to the data - compressed before deflateParams(), and the new level and strategy will be - applied to the the data compressed after deflateParams(). - - deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream - state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if - there was not enough output space to complete the compression of the - available input data before a change in the strategy or approach. Note that - in the case of a Z_BUF_ERROR, the parameters are not changed. A return - value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be - retried with more output space. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). If that first deflate() call is provided the - sourceLen input bytes, an output buffer allocated to the size returned by - deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed - to return Z_STREAM_END. Note that it is possible for the compressed size to - be larger than the value returned by deflateBound() if flush options other - than Z_FINISH or Z_NO_FLUSH are used. -*/ - -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* - deflatePending() returns the number of bytes and bits of output that have - been generated, but not yet provided in the available output. The bytes not - provided would be due to the available output space having being consumed. - The number of bits of output not provided are between 0 and 7, where they - await more bits to join them in order to fill out a full byte. If pending - or bits are Z_NULL, then those values are not set. - - deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. - */ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough - room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an Adler-32 or a CRC-32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will not automatically decode concatenated gzip streams. - inflate() will return Z_STREAM_END at the end of the gzip stream. The state - would need to be reset to continue decoding a subsequent gzip stream. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler-32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called at any - time to set the dictionary. If the provided dictionary is smaller than the - window and there is already data in the window, then the provided dictionary - will amend what's there. The application must insure that the dictionary - that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler-32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* - Returns the sliding dictionary being maintained by inflate. dictLength is - set to the number of bytes in the dictionary, and that many bytes are copied - to dictionary. dictionary must have enough space, where 32768 bytes is - always enough. If inflateGetDictionary() is called with dictionary equal to - Z_NULL, then only the dictionary length is returned, and nothing is copied. - Similary, if dictLength is Z_NULL, then it is not set. - - inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the - stream state is inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a possible full flush point (see above - for the description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync searches for a 00 00 FF FF pattern in the compressed data. - All full flush points have this pattern, but not all occurrences of this - pattern are full flush points. - - inflateSync returns Z_OK if a possible full flush point has been found, - Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point - has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. - In the success case, the application may save the current current value of - total_in which indicates where valid compressed data was found. In the - error case, the application may repeatedly call inflateSync, providing more - input each time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. If the window size is changed, then the - memory allocated for the window is freed, and the window will be reallocated - by inflate() if needed. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above, or -65536 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the parameters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is potentially more efficient than - inflate() for file i/o applications, in that it avoids copying between the - output and the sliding window by simply making the window itself the output - buffer. inflate() can be faster on modern CPUs when used with large - buffers. inflateBack() trusts the application to not change the output - buffer passed by the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the default - behavior of inflate(), which expects a zlib header and trailer around the - deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero -- buf is ignored in that - case -- and inflateBack() will return a buffer error. inflateBack() will - call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. - out() should return zero on success, or non-zero on failure. If out() - returns non-zero, inflateBack() will return with an error. Neither in() nor - out() are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: ZLIB_DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - -#ifndef Z_SOLO - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. compress() is equivalent to compress2() with a level - parameter of Z_DEFAULT_COMPRESSION. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed data. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In - the case where there is not enough room, uncompress() will fill the output - buffer with the uncompressed data up to that point. -*/ - -ZEXTERN int ZEXPORT uncompress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong *sourceLen)); -/* - Same as uncompress, except that sourceLen is a pointer, where the - length of the source is *sourceLen. On return, *sourceLen is the number of - source bytes consumed. -*/ - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. - - "a" can be used instead of "w" to request that the gzip stream that will - be written be appended to the file. "+" will result in an error, since - reading and writing to the same gzip file is not supported. The addition of - "x" when writing will create the file exclusively, which fails if the file - already exists. On systems that support it, the addition of "e" when - reading or writing will set the flag to close the file on an execve() call. - - These functions, as well as gzip, will read and decode a sequence of gzip - streams in a file. The append function of gzopen() can be used to create - such a file. (Also see gzflush() for another way to do this.) When - appending, gzopen does not test whether the file begins with a gzip stream, - nor does it look for the end of the gzip streams to begin appending. gzopen - will simply append a gzip stream to the existing file. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. When - reading, this will be detected automatically by looking for the magic two- - byte gzip header. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. If you are using fileno() to get the - file descriptor from a FILE *, then you will have to use dup() to avoid - double-close()ing the file descriptor. Both gzclose() and fclose() will - close the associated file descriptor, so they need to have different file - descriptors. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Three times that size in buffer space is allocated. A larger buffer - size of, for example, 64K or 128K bytes will noticeably increase the speed - of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. Previously provided - data is flushed before the parameter change. - - gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not - opened for writing, Z_ERRNO if there is an error writing the flushed data, - or Z_MEM_ERROR if there is a memory allocation error. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file is not in gzip format, gzread copies the given number of - bytes into the buffer directly from the file. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream. Any number of gzip streams may be - concatenated in the input file, and will all be decompressed by gzread(). - If something other than a gzip stream is encountered after a gzip stream, - that remaining trailing garbage is ignored (and no error is returned). - - gzread can be used to read a gzip file that is being concurrently written. - Upon reaching the end of the input, gzread will return with the available - data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then - gzclearerr can be used to clear the end of file indicator in order to permit - gzread to be tried again. Z_OK indicates that a gzip stream was completed - on the last gzread. Z_BUF_ERROR indicates that the input file ended in the - middle of a gzip stream. Note that gzread does not return -1 in the event - of an incomplete gzip stream. This error is deferred until gzclose(), which - will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip - stream. Alternatively, gzerror can be used before gzclose to detect this - case. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. If len is too large to fit in an int, - then nothing is read, -1 is returned, and the error state is set to - Z_STREAM_ERROR. -*/ - -ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, - gzFile file)); -/* - Read up to nitems items of size size from file to buf, otherwise operating - as gzread() does. This duplicates the interface of stdio's fread(), with - size_t request and return types. If the library defines size_t, then - z_size_t is identical to size_t. If not, then z_size_t is an unsigned - integer type that can contain a pointer. - - gzfread() returns the number of full items read of size size, or zero if - the end of the file was reached and a full item could not be read, or if - there was an error. gzerror() must be consulted if zero is returned in - order to determine if there was an error. If the multiplication of size and - nitems overflows, i.e. the product does not fit in a z_size_t, then nothing - is read, zero is returned, and the error state is set to Z_STREAM_ERROR. - - In the event that the end of file is reached and only a partial item is - available at the end, i.e. the remaining uncompressed data length is not a - multiple of size, then the final partial item is nevetheless read into buf - and the end-of-file flag is set. The length of the partial item read is not - provided, but could be inferred from the result of gztell(). This behavior - is the same as the behavior of fread() implementations in common libraries, - but it prevents the direct use of gzfread() to read a concurrently written - file, reseting and retrying on end-of-file, when size is not 1. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, - z_size_t nitems, gzFile file)); -/* - gzfwrite() writes nitems items of size size from buf to file, duplicating - the interface of stdio's fwrite(), with size_t request and return types. If - the library defines size_t, then z_size_t is identical to size_t. If not, - then z_size_t is an unsigned integer type that can contain a pointer. - - gzfwrite() returns the number of full items written of size size, or zero - if there was an error. If the multiplication of size and nitems overflows, - i.e. the product does not fit in a z_size_t, then nothing is written, zero - is returned, and the error state is set to Z_STREAM_ERROR. -*/ - -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or a negative zlib error code in case - of error. The number of uncompressed bytes written is limited to 8191, or - one less than the buffer size given to gzbuffer(). The caller should assure - that this limit is not exceeded. If it is exceeded, then gzprintf() will - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. - This can be determined using zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. This is implemented as a macro for speed. - As such, it does not do all of the checking the other functions do. I.e. - it does not check to see if file is NULL, nor whether the structure file - points to has been clobbered or not. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatenated gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). - - When writing, gzdirect() returns true (1) if transparent writing was - requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: - gzdirect() is not needed when writing. Transparent writing must be - explicitly requested, so the application already knows the answer. When - linking statically, using gzdirect() will include all of the zlib code for - gzip file reading and decompression, which may not be desired.) -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the - last read ended in the middle of a gzip stream, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - -#endif /* !Z_SOLO */ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT adler32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as adler32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note - that the z_off_t type (like off_t) is a signed integer. If len2 is - negative, the result has no meaning or utility. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, - z_size_t len)); -/* - Same as crc32(), but with a size_t length. -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#ifdef Z_PREFIX_SET -# define z_deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define z_inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define z_inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#else -# define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) -# define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -# define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -# define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) -#endif - -#ifndef Z_SOLO - -/* gzgetc() macro and its supporting function and exposed data structure. Note - * that the real internal state is much larger than the exposed structure. - * This abbreviated structure exposes just enough for the gzgetc() macro. The - * user should not mess with these exposed elements, since their names or - * behavior could change in the future, perhaps even capriciously. They can - * only be used by the gzgetc() macro. You have been warned. - */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ -#ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (gzgetc)(g)) -#endif - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -#else /* Z_SOLO */ - - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); - -#endif /* !Z_SOLO */ - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateValidate OF((z_streamp, int)); -ZEXTERN unsigned long ZEXPORT inflateCodesUsed OF ((z_streamp)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); -#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); -# endif -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/Sources/PerfectCZlib/zlib.map b/Sources/PerfectCZlib/zlib.map deleted file mode 100644 index 40fa9db2..00000000 --- a/Sources/PerfectCZlib/zlib.map +++ /dev/null @@ -1,94 +0,0 @@ -ZLIB_1.2.0 { - global: - compressBound; - deflateBound; - inflateBack; - inflateBackEnd; - inflateBackInit_; - inflateCopy; - local: - deflate_copyright; - inflate_copyright; - inflate_fast; - inflate_table; - zcalloc; - zcfree; - z_errmsg; - gz_error; - gz_intmax; - _*; -}; - -ZLIB_1.2.0.2 { - gzclearerr; - gzungetc; - zlibCompileFlags; -} ZLIB_1.2.0; - -ZLIB_1.2.0.8 { - deflatePrime; -} ZLIB_1.2.0.2; - -ZLIB_1.2.2 { - adler32_combine; - crc32_combine; - deflateSetHeader; - inflateGetHeader; -} ZLIB_1.2.0.8; - -ZLIB_1.2.2.3 { - deflateTune; - gzdirect; -} ZLIB_1.2.2; - -ZLIB_1.2.2.4 { - inflatePrime; -} ZLIB_1.2.2.3; - -ZLIB_1.2.3.3 { - adler32_combine64; - crc32_combine64; - gzopen64; - gzseek64; - gztell64; - inflateUndermine; -} ZLIB_1.2.2.4; - -ZLIB_1.2.3.4 { - inflateReset2; - inflateMark; -} ZLIB_1.2.3.3; - -ZLIB_1.2.3.5 { - gzbuffer; - gzoffset; - gzoffset64; - gzclose_r; - gzclose_w; -} ZLIB_1.2.3.4; - -ZLIB_1.2.5.1 { - deflatePending; -} ZLIB_1.2.3.5; - -ZLIB_1.2.5.2 { - deflateResetKeep; - gzgetc_; - inflateResetKeep; -} ZLIB_1.2.5.1; - -ZLIB_1.2.7.1 { - inflateGetDictionary; - gzvprintf; -} ZLIB_1.2.5.2; - -ZLIB_1.2.9 { - inflateCodesUsed; - inflateValidate; - uncompress2; - gzfread; - gzfwrite; - deflateGetDictionary; - adler32_z; - crc32_z; -} ZLIB_1.2.7.1; diff --git a/Sources/PerfectCZlib/zlib.pc b/Sources/PerfectCZlib/zlib.pc deleted file mode 100644 index e9bd8235..00000000 --- a/Sources/PerfectCZlib/zlib.pc +++ /dev/null @@ -1,13 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${exec_prefix}/lib -sharedlibdir=${libdir} -includedir=${prefix}/include - -Name: zlib -Description: zlib compression library -Version: 1.2.9 - -Requires: -Libs: -L${libdir} -L${sharedlibdir} -lz -Cflags: -I${includedir} diff --git a/Sources/PerfectCZlib/zlib.pc.cmakein b/Sources/PerfectCZlib/zlib.pc.cmakein deleted file mode 100644 index a5e64293..00000000 --- a/Sources/PerfectCZlib/zlib.pc.cmakein +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@INSTALL_LIB_DIR@ -sharedlibdir=@INSTALL_LIB_DIR@ -includedir=@INSTALL_INC_DIR@ - -Name: zlib -Description: zlib compression library -Version: @VERSION@ - -Requires: -Libs: -L${libdir} -L${sharedlibdir} -lz -Cflags: -I${includedir} diff --git a/Sources/PerfectCZlib/zlib.pc.in b/Sources/PerfectCZlib/zlib.pc.in deleted file mode 100644 index 7e5acf9c..00000000 --- a/Sources/PerfectCZlib/zlib.pc.in +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -sharedlibdir=@sharedlibdir@ -includedir=@includedir@ - -Name: zlib -Description: zlib compression library -Version: @VERSION@ - -Requires: -Libs: -L${libdir} -L${sharedlibdir} -lz -Cflags: -I${includedir} diff --git a/Sources/PerfectCZlib/zlib2ansi b/Sources/PerfectCZlib/zlib2ansi deleted file mode 100755 index 15e3e165..00000000 --- a/Sources/PerfectCZlib/zlib2ansi +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/perl - -# Transform K&R C function definitions into ANSI equivalent. -# -# Author: Paul Marquess -# Version: 1.0 -# Date: 3 October 2006 - -# TODO -# -# Asumes no function pointer parameters. unless they are typedefed. -# Assumes no literal strings that look like function definitions -# Assumes functions start at the beginning of a line - -use strict; -use warnings; - -local $/; -$_ = <>; - -my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments - -my $d1 = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ; -my $decl = qr{ $sp (?: \w+ $sp )+ $d1 }xo ; -my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ; - - -while (s/^ - ( # Start $1 - ( # Start $2 - .*? # Minimal eat content - ( ^ \w [\w\s\*]+ ) # $3 -- function name - \s* # optional whitespace - ) # $2 - Matched up to before parameter list - - \( \s* # Literal "(" + optional whitespace - ( [^\)]+ ) # $4 - one or more anythings except ")" - \s* \) # optional whitespace surrounding a Literal ")" - - ( (?: $dList )+ ) # $5 - - $sp ^ { # literal "{" at start of line - ) # Remember to $1 - //xsom - ) -{ - my $all = $1 ; - my $prefix = $2; - my $param_list = $4 ; - my $params = $5; - - StripComments($params); - StripComments($param_list); - $param_list =~ s/^\s+//; - $param_list =~ s/\s+$//; - - my $i = 0 ; - my %pList = map { $_ => $i++ } - split /\s*,\s*/, $param_list; - my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ; - - my @params = split /\s*;\s*/, $params; - my @outParams = (); - foreach my $p (@params) - { - if ($p =~ /,/) - { - my @bits = split /\s*,\s*/, $p; - my $first = shift @bits; - $first =~ s/^\s*//; - push @outParams, $first; - $first =~ /^(\w+\s*)/; - my $type = $1 ; - push @outParams, map { $type . $_ } @bits; - } - else - { - $p =~ s/^\s+//; - push @outParams, $p; - } - } - - - my %tmp = map { /$pMatch/; $_ => $pList{$1} } - @outParams ; - - @outParams = map { " $_" } - sort { $tmp{$a} <=> $tmp{$b} } - @outParams ; - - print $prefix ; - print "(\n" . join(",\n", @outParams) . ")\n"; - print "{" ; - -} - -# Output any trailing code. -print ; -exit 0; - - -sub StripComments -{ - - no warnings; - - # Strip C & C++ coments - # From the perlfaq - $_[0] =~ - - s{ - /\* ## Start of /* ... */ comment - [^*]*\*+ ## Non-* followed by 1-or-more *'s - ( - [^/*][^*]*\*+ - )* ## 0-or-more things which don't start with / - ## but do end with '*' - / ## End of /* ... */ comment - - | ## OR C++ Comment - // ## Start of C++ comment // - [^\n]* ## followed by 0-or-more non end of line characters - - | ## OR various things which aren't comments: - - ( - " ## Start of " ... " string - ( - \\. ## Escaped char - | ## OR - [^"\\] ## Non "\ - )* - " ## End of " ... " string - - | ## OR - - ' ## Start of ' ... ' string - ( - \\. ## Escaped char - | ## OR - [^'\\] ## Non '\ - )* - ' ## End of ' ... ' string - - | ## OR - - . ## Anything other char - [^/"'\\]* ## Chars which doesn't start a comment, string or escape - ) - }{$2}gxs; - -} diff --git a/Sources/PerfectCZlib/zutil.c b/Sources/PerfectCZlib/zutil.c deleted file mode 100644 index 3b4d9045..00000000 --- a/Sources/PerfectCZlib/zutil.c +++ /dev/null @@ -1,325 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010, 2011, 2012, 2016 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" -#ifndef Z_SOLO -# include "gzguts.h" -#endif - -z_const char * const z_errmsg[10] = { - (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ - (z_const char *)"stream end", /* Z_STREAM_END 1 */ - (z_const char *)"", /* Z_OK 0 */ - (z_const char *)"file error", /* Z_ERRNO (-1) */ - (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ - (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ - (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ - (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ - (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ - (z_const char *)"" -}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef ZLIB_DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef ZLIB_DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - -#ifndef Z_SOLO - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf; - ulg bsize = (ulg)items*size; - - (void)opaque; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - int n; - - (void)opaque; - - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ - (void)opaque; - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - (void)opaque; - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - (void)opaque; - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - (void)opaque; - free(ptr); -} - -#endif /* MY_ZCALLOC */ - -#endif /* !Z_SOLO */ diff --git a/Sources/PerfectCZlib/zutil.h b/Sources/PerfectCZlib/zutil.h deleted file mode 100644 index b079ea6a..00000000 --- a/Sources/PerfectCZlib/zutil.h +++ /dev/null @@ -1,271 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif - -#ifdef Z_SOLO - typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ -#endif - -#ifndef local -# define local static -#endif -/* since "static" is used to mean two completely different things in C, we - define "local" for the non-static meaning of "static", for readability - (compile with -Dlocal if your debugger can't find static symbols) */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 1 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 2 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#ifdef __370__ -# if __TARGET_LIB__ < 0x20000000 -# define OS_CODE 4 -# elif __TARGET_LIB__ < 0x40000000 -# define OS_CODE 11 -# else -# define OS_CODE 8 -# endif -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 5 -#endif - -#ifdef OS2 -# define OS_CODE 6 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 7 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif -#endif - -#ifdef __acorn -# define OS_CODE 13 -#endif - -#if defined(WIN32) && !defined(__CYGWIN__) -# define OS_CODE 10 -#endif - -#ifdef _BEOS_ -# define OS_CODE 16 -#endif - -#ifdef __TOS_OS400__ -# define OS_CODE 18 -#endif - -#ifdef __APPLE__ -# define OS_CODE 19 -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - -#if defined(__BORLANDC__) && !defined(MSDOS) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_WIN32) && \ - (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 3 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef ZLIB_DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - -#ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); -#endif - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -/* Reverse the bytes in a 32-bit value */ -#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -#endif /* ZUTIL_H */ diff --git a/Sources/PerfectWebSockets/WebSocketHandler.swift b/Sources/PerfectWebSockets/WebSocketHandler.swift deleted file mode 100644 index eab3e6c4..00000000 --- a/Sources/PerfectWebSockets/WebSocketHandler.swift +++ /dev/null @@ -1,382 +0,0 @@ -// -// WebSocketHandler.swift -// PerfectLib -// -// Created by Kyle Jessup on 2016-01-06. -// Copyright © 2016 PerfectlySoft. All rights reserved. -// -// ===----------------------------------------------------------------------===// -// -// This source file is part of the Perfect.org open source project -// -// Copyright (c) 2015 - 2016 PerfectlySoft Inc. and the Perfect project authors -// Licensed under Apache License v2.0 -// -// See http://perfect.org/licensing.html for license information -// -// ===----------------------------------------------------------------------===// -// - -import PerfectNet -import PerfectLib -import PerfectHTTP - -#if os(Linux) -import SwiftGlibc -import LinuxBridge -private let UINT16_MAX = UInt(0xFFFF) -#else -import Darwin -#endif - -import COpenSSL - -private let smallPayloadSize = 126 - -/// This class represents the communications channel for a WebSocket session. -public class WebSocket: Equatable { - - /// The various types of WebSocket messages. - public enum OpcodeType: UInt8 { - /// Continuation op code - case continuation = 0x0, - /// Text data indicator - text = 0x1, - /// Binary data indicator - binary = 0x2, - /// Close indicator - close = 0x8, - /// Ping message - ping = 0x9, - /// Ping response message - pong = 0xA, - /// Invalid op code - invalid - } - - private struct Frame { - let fin: Bool - let rsv1: Bool - let rsv2: Bool - let rsv3: Bool - let opCode: OpcodeType - let bytesPayload: [UInt8] - - var stringPayload: String? { - return UTF8Encoding.encode(bytes: self.bytesPayload) - } - } - - /// The read timeout, in seconds. By default this is -1, which means no timeout. - public var readTimeoutSeconds: Double = NetEvent.noTimeout - - /// Indicates if the socket is still likely connected or if it has been closed. - public var isConnected: Bool { return self.socket.isValid } - private let socket: NetTCP - private var nextIsContinuation = false - private let readBuffer = Bytes() - - init(socket: NetTCP) { - self.socket = socket - } - - /// Close the connection. - public func close() { - if self.socket.isValid { - self.sendMessage(opcode: .close, bytes: [UInt8](), final: true) { - self.socket.close() - } - } - } - - private func clearFrame() { - let position = self.readBuffer.position - self.readBuffer.data.removeFirst(position) - self.readBuffer.position = 0 - } - - private func fillFrame() -> Frame? { - guard self.readBuffer.availableExportBytes >= 2 else { - return nil - } - // we know we potentially have a valid frame here - // for to be resetting the position if we don't have a valid frame yet - let oldPosition = self.readBuffer.position - - let byte1 = self.readBuffer.export8Bits() - let byte2 = self.readBuffer.export8Bits() - - let fin = (byte1 & 0x80) != 0 - let rsv1 = (byte1 & 0x40) != 0 - let rsv2 = (byte1 & 0x20) != 0 - let rsv3 = (byte1 & 0x10) != 0 - let opcode = OpcodeType(rawValue: byte1 & 0xF) ?? .invalid - let maskBit = (byte2 & 0x80) != 0 - - guard maskBit else { - self.close() - return nil - } - - var unmaskedLength = Int(byte2 ^ 0x80) - if unmaskedLength == smallPayloadSize { - if self.readBuffer.availableExportBytes >= 2 { - unmaskedLength = Int(self.readBuffer.export16Bits().netToHost) - } - } else if unmaskedLength > smallPayloadSize { - if self.readBuffer.availableExportBytes >= 8 { - unmaskedLength = Int(self.readBuffer.export64Bits().netToHost) - } - } // else small payload - if self.readBuffer.availableExportBytes >= 4 { - let maskingKey = self.readBuffer.exportBytes(count: 4) - if self.readBuffer.availableExportBytes >= unmaskedLength { - var exported = self.readBuffer.exportBytes(count: unmaskedLength) - for i in 0.. ()) { - self.socket.readBytesFully(count: demnd, timeoutSeconds: self.readTimeoutSeconds) { [weak self] (b: [UInt8]?) -> () in - if let b = b { - self?.readBuffer.data.append(contentsOf: b) - } - completion(b != nil) - } - } - - func fillBufferSome(suggestion suggest: Int, completion: @escaping () -> ()) { - self.socket.readSomeBytes(count: suggest) { [weak self] (b: [UInt8]?) -> () in - if let b = b { - self?.readBuffer.data.append(contentsOf: b) - } - completion() - } - } - - private func readFrame(completion comp: @escaping (Frame?) -> ()) { - if let frame = self.fillFrame() { - switch frame.opCode { - // check for and handle ping/pong - case .ping: - self.sendMessage(opcode: .pong, bytes: frame.bytesPayload, final: true) { - self.readFrame(completion: comp) - } - // check for and handle close - case .close: - self.close() - comp(nil) - default: - comp(frame) - } - } else { - self.fillBuffer(demand: 1) { b in - guard b else { - return comp(nil) - } - self.fillBufferSome(suggestion: 1024 * 32) { // some arbitrary read-ahead amount - self.readFrame(completion: comp) - } - } - } - } - - /// Read string data from the client. - public func readStringMessage(continuation: @escaping (String?, _ opcode: OpcodeType, _ final: Bool) -> ()) { - self.readFrame { frame in - continuation(frame?.stringPayload, frame?.opCode ?? .invalid, frame?.fin ?? true) - } - } - - /// Read binary data from the client. - public func readBytesMessage(continuation: @escaping ([UInt8]?, _ opcode: OpcodeType, _ final: Bool) -> ()) { - self.readFrame { frame in - continuation(frame?.bytesPayload, frame?.opCode ?? .invalid, frame?.fin ?? true) - } - } - - /// Send binary data to thew client. - public func sendBinaryMessage(bytes: [UInt8], final: Bool, completion: @escaping () -> ()) { - self.sendMessage(opcode: .binary, bytes: bytes, final: final, completion: completion) - } - - /// Send string data to the client. - public func sendStringMessage(string: String, final: Bool, completion: @escaping () -> ()) { - self.sendMessage(opcode: .text, bytes: UTF8Encoding.decode(string: string), final: final, completion: completion) - } - - /// Send a "pong" message to the client. - public func sendPong(completion: @escaping () -> ()) { - self.sendMessage(opcode: .pong, bytes: [UInt8](), final: true, completion: completion) - } - - /// Send a "ping" message to the client. - /// Expect a "pong" message to follow. - public func sendPing(completion: @escaping () -> ()) { - self.sendMessage(opcode: .ping, bytes: [UInt8](), final: true, completion: completion) - } - - private func sendMessage(opcode op: OpcodeType, bytes: [UInt8], final: Bool, completion: @escaping () -> ()) { - let sendBuffer = Bytes() - - let byte1 = UInt8(final ? 0x80 : 0x0) | (self.nextIsContinuation ? 0 : op.rawValue) - - self.nextIsContinuation = !final - - _ = sendBuffer.import8Bits(from: byte1) - - let payloadSize = bytes.count - if payloadSize < smallPayloadSize { - - let byte2 = UInt8(payloadSize) - - _ = sendBuffer.import8Bits(from: byte2) - - } else if payloadSize <= Int(UINT16_MAX) { - - _ = sendBuffer.import8Bits(from: UInt8(smallPayloadSize)) - .import16Bits(from: UInt16(payloadSize).hostToNet) - - } else { - - _ = sendBuffer.import8Bits(from: UInt8(1+smallPayloadSize)) - .import64Bits(from: UInt64(payloadSize).hostToNet) - - } - _ = sendBuffer.importBytes(from: bytes) - self.socket.write(bytes: sendBuffer.data) { _ in - completion() - } - } - - /// implement Equatable protocol - public static func == (lhs: WebSocket, rhs: WebSocket) -> Bool { - return lhs.socket == rhs.socket - } -} - -/// The protocol that all WebSocket handlers must implement. -public protocol WebSocketSessionHandler { - - /// Optionally indicate the name of the protocol the handler implements. - /// If this has a valid, the protocol name will be validated against what the client is requesting. - var socketProtocol: String? { get } - /// This function is called once the WebSocket session has been initiated. - func handleSession(request req: HTTPRequest, socket: WebSocket) - -} - -private let acceptableProtocolVersions = [13] -private let webSocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - -/// This request handler accepts WebSocket requests from client. -/// It will initialize the session and then deliver it to the `WebSocketSessionHandler`. -public struct WebSocketHandler { - - /// Function which produces a WebSocketSessionHandler - public typealias HandlerProducer = (_ request: HTTPRequest, _ protocols: [String]) -> WebSocketSessionHandler? - - private let handlerProducer: HandlerProducer - - /// Initialize WebSocketHandler with a handler producer function - public init(handlerProducer: @escaping HandlerProducer) { - self.handlerProducer = handlerProducer - } - - /// Handle the request and negotiate the WebSocket session - public func handleRequest(request: HTTPRequest, response: HTTPResponse) { - - guard let upgrade = request.header(.upgrade), - let connection = request.header(.connection), - let secWebSocketKey = request.header(.custom(name: "sec-websocket-key")), - let secWebSocketVersion = request.header(.custom(name: "sec-websocket-version")), upgrade.lowercased() == "websocket" && connection.lowercased().contains(string: "upgrade") else { - response.status = .badRequest - return response.completed() - } - - guard acceptableProtocolVersions.contains(Int(secWebSocketVersion) ?? 0) else { - response.status = .badRequest - response.addHeader(.custom(name: "Sec-WebSocket-Version"), value: "\(acceptableProtocolVersions[0])") - response.appendBody(string: "WebSocket protocol version \(secWebSocketVersion) not supported. Supported protocol versions are: \(acceptableProtocolVersions)") - return response.completed() - } - - let secWebSocketProtocol = request.header(.custom(name: "sec-websocket-protocol")) ?? "" - let protocolList = secWebSocketProtocol.split(separator: ",").compactMap { i -> String? in - var s = String(i) - while s.count > 0 && s[s.startIndex] == " " { - s.remove(at: s.startIndex) - } - return s.count > 0 ? s : nil - } - - guard let handler = self.handlerProducer(request, protocolList) else { - response.status = .badRequest - response.appendBody(string: "WebSocket protocols not supported.") - response.completed() - return - } - request.scratchPad["no-compression"] = true - response.status = .switchingProtocols - response.addHeader(.upgrade, value: "websocket") - response.addHeader(.connection, value: "Upgrade") - response.addHeader(.custom(name: "Sec-WebSocket-Accept"), value: self.base64((secWebSocketKey + webSocketGUID).utf8.sha1)) - - if let chosenProtocol = handler.socketProtocol { - response.addHeader(.custom(name: "Sec-WebSocket-Protocol"), value: chosenProtocol) - } - - response.push { ok in - guard ok else { - request.connection.close() - return - } - handler.handleSession(request: request, socket: WebSocket(socket: request.connection)) - } - } - - private func base64(_ a: [UInt8]) -> String { - let bio = BIO_push(BIO_new(BIO_f_base64()), BIO_new(BIO_s_mem())) - - BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL) - BIO_write(bio, a, Int32(a.count)) - BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, nil) - - var mem = UnsafeMutablePointer(nil as OpaquePointer?) - BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, &mem) - BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, Int(BIO_NOCLOSE), nil) - BIO_free_all(bio) - - guard let amem = mem else { - return "" - } - guard let txt = UnsafeMutableRawPointer(amem.pointee.data)?.assumingMemoryBound(to: UInt8.self) else { - return "" - } - let ret = UTF8Encoding.encode(generator: GenerateFromPointer(from: txt, count: amem.pointee.length)) - free(amem.pointee.data) - return ret - } -} - -extension String.UTF8View { - var sha1: [UInt8] { - let bytes = UnsafeMutablePointer.allocate(capacity: Int(SHA_DIGEST_LENGTH)) - defer { bytes.deallocate() } - - SHA1(Array(self), (self.count), bytes) - - var r = [UInt8]() - for idx in 0.. - -#ifdef CURLOPT_HEADERDATA -#undef CURLOPT_HEADERDATA -CURLoption CURLOPT_HEADERDATA = CURLOPT_WRITEHEADER; -#endif -#ifdef CURLOPT_WRITEDATA -#undef CURLOPT_WRITEDATA -CURLoption CURLOPT_WRITEDATA = CURLOPT_FILE; -#endif -#ifdef CURLOPT_READDATA -#undef CURLOPT_READDATA -CURLoption CURLOPT_READDATA = CURLOPT_INFILE; -#endif - -typedef size_t (*curl_func)(void * ptr, size_t size, size_t num, void * ud); - -static CURLcode curl_easy_setopt_long(CURL *handle, CURLoption option, long value) -{ - return curl_easy_setopt(handle, option, value); -} - -static CURLcode curl_easy_setopt_cstr(CURL *handle, CURLoption option, const char * value) -{ - return curl_easy_setopt(handle, option, value); -} - -static CURLcode curl_easy_setopt_int64(CURL *handle, CURLoption option, long long value) -{ - return curl_easy_setopt(handle, option, value); -} - -static CURLcode curl_easy_setopt_slist(CURL *handle, CURLoption option, struct curl_slist * value) -{ - return curl_easy_setopt(handle, option, value); -} - -static CURLcode curl_easy_setopt_void(CURL *handle, CURLoption option, void * value) -{ - return curl_easy_setopt(handle, option, value); -} - -static CURLcode curl_easy_setopt_func(CURL *handle, CURLoption option, curl_func value) -{ - return curl_easy_setopt(handle, option, value); -} - -static CURLcode curl_easy_getinfo_long(CURL *handle, CURLINFO option, long * value) -{ - return curl_easy_getinfo(handle, option, value); -} - -static CURLcode curl_easy_getinfo_cstr(CURL *handle, CURLINFO option, const char ** value) -{ - return curl_easy_getinfo(handle, option, value); -} - -static CURLcode curl_easy_getinfo_double(CURL *handle, CURLINFO option, double * value) -{ - return curl_easy_getinfo(handle, option, value); -} - -static CURLcode curl_easy_getinfo_slist(CURL *handle, CURLINFO option, struct curl_slist ** value) -{ - return curl_easy_getinfo(handle, option, value); -} - -static CURLcode curl_get_msg_result(CURLMsg * msg) -{ - return msg->data.result; -} - -static CURLFORMcode curl_formadd_content(struct curl_httppost **firstitem, struct curl_httppost **lastitem, - const char * name, const char * content, const long size, const char * type) { - return type ? - curl_formadd(firstitem, lastitem, - CURLFORM_COPYNAME, name, - CURLFORM_COPYCONTENTS, content, - CURLFORM_CONTENTSLENGTH, size, - CURLFORM_CONTENTTYPE, type, - CURLFORM_END) - : - curl_formadd(firstitem, lastitem, - CURLFORM_COPYNAME, name, - CURLFORM_COPYCONTENTS, content, - CURLFORM_CONTENTSLENGTH, size, - CURLFORM_END); -} - -static CURLFORMcode curl_formadd_file(struct curl_httppost **firstitem, struct curl_httppost **lastitem, - const char * name, const char * path, const char * type) { - return type ? - curl_formadd(firstitem, lastitem, - CURLFORM_COPYNAME, name, - CURLFORM_CONTENTTYPE, type, - CURLFORM_FILE, path, - CURLFORM_END) - : - curl_formadd(firstitem, lastitem, - CURLFORM_COPYNAME, name, - CURLFORM_FILE, path, - CURLFORM_END); -} - -static CURLcode curl_form_post(CURL * handle, struct curl_httppost * post) { - return curl_easy_setopt(handle, CURLOPT_HTTPPOST, post); -} - - -#endif From 70935e5ba03e3da3401c8c39fff6780e67785181 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Wed, 23 Aug 2023 16:32:44 -0400 Subject: [PATCH 46/48] cleaning up --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7d801efd..5173dc0f 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ DerivedData *.ipa *.xcuserstate *.xcscmblueprint +*.resolved # CocoaPods # @@ -62,4 +63,4 @@ smtp.test.json .vscode/ *.json *.pem -*.sqlite* \ No newline at end of file +*.sqlite* From 8af193f801337929f0174f51904e2dfc547378e7 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Sat, 3 Feb 2024 10:34:35 -0500 Subject: [PATCH 47/48] fixing critical warnings --- Package.resolved | 78 ++++++++++++------- Package.swift | 2 +- Sources/PerfectCRUD/Coding/CodingNames.swift | 2 +- .../PerfectCryptoTests.swift | 3 +- smtp.test.json.example | 2 +- 5 files changed, 54 insertions(+), 33 deletions(-) diff --git a/Package.resolved b/Package.resolved index 55185125..e68406e0 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,32 +1,52 @@ { - "pins" : [ - { - "identity" : "perfect-copenssl", - "kind" : "remoteSourceControl", - "location" : "https://github.com/PerfectlySoft/Perfect-COpenSSL.git", - "state" : { - "revision" : "ce3113e159b8c6d8565e5d8db2672b572c81aea9", - "version" : "4.0.2" + "object": { + "pins": [ + { + "package": "COpenSSL", + "repositoryURL": "https://github.com/PerfectlySoft/Perfect-COpenSSL.git", + "state": { + "branch": null, + "revision": "ce3113e159b8c6d8565e5d8db2672b572c81aea9", + "version": "4.0.2" + } + }, + { + "package": "PerfectCZlib", + "repositoryURL": "https://github.com/RockfordWei/Perfect-CZlib-src.git", + "state": { + "branch": null, + "revision": "8295883fd760f601a2c8c3236af83c8c35f941c6", + "version": "0.0.6" + } + }, + { + "package": "cURL", + "repositoryURL": "https://github.com/PerfectlySoft/Perfect-libcurl.git", + "state": { + "branch": null, + "revision": "b3d7e65ef5c27c0a027cdc621f34835975301bf1", + "version": "2.1.0" + } + }, + { + "package": "LinuxBridge", + "repositoryURL": "https://github.com/PerfectlySoft/Perfect-LinuxBridge.git", + "state": { + "branch": null, + "revision": "d6e64c48e6b06b6f1ab7ab9338280447baa8ca5c", + "version": "3.1.0" + } + }, + { + "package": "PerfectCSQLite3", + "repositoryURL": "https://github.com/PerfectlySoft/Perfect-sqlite3-support.git", + "state": { + "branch": null, + "revision": "64c2bd87e1fd3a41cdeeba073bab794db7e97e42", + "version": "3.1.1" + } } - }, - { - "identity" : "perfect-czlib-src", - "kind" : "remoteSourceControl", - "location" : "https://github.com/PerfectlySoft/Perfect-CZlib-src.git", - "state" : { - "revision" : "b63e46909aad937c6434766f8f8c6720d8f3bd05", - "version" : "0.0.4" - } - }, - { - "identity" : "perfect-libcurl", - "kind" : "remoteSourceControl", - "location" : "https://github.com/PerfectlySoft/Perfect-libcurl.git", - "state" : { - "revision" : "b3d7e65ef5c27c0a027cdc621f34835975301bf1", - "version" : "2.1.0" - } - } - ], - "version" : 2 + ] + }, + "version": 1 } diff --git a/Package.swift b/Package.swift index a959f6f3..b8dfcbc2 100644 --- a/Package.swift +++ b/Package.swift @@ -41,7 +41,7 @@ let package = Package( dependencies: pkdep + [ .package(url: "https://github.com/PerfectlySoft/Perfect-libcurl.git", from: "2.0.0"), .package(url: "https://github.com/PerfectlySoft/Perfect-COpenSSL.git", from: "4.0.2"), - .package(url: "https://github.com/PerfectlySoft/Perfect-CZlib-src.git", from: "0.0.4") + .package(url: "https://github.com/RockfordWei/Perfect-CZlib-src.git", from: "0.0.6") ], targets: [ .target(name: "PerfectAuth", dependencies: ["PerfectCrypto", "PerfectCRUD", "PerfectSQLite"]), diff --git a/Sources/PerfectCRUD/Coding/CodingNames.swift b/Sources/PerfectCRUD/Coding/CodingNames.swift index 144d0206..908a42b0 100644 --- a/Sources/PerfectCRUD/Coding/CodingNames.swift +++ b/Sources/PerfectCRUD/Coding/CodingNames.swift @@ -325,7 +325,7 @@ struct SubTable: SubTableProto { func tableStructure() throws -> TableStructure { return try type.self.CRUDTableStructure(columnDecoder: decoder) } - func matches(_ type: T.Type) -> Bool { + func matches(_ type: U.Type) -> Bool { return self.type == type } } diff --git a/Tests/PerfectCryptoTests/PerfectCryptoTests.swift b/Tests/PerfectCryptoTests/PerfectCryptoTests.swift index de1cc4c4..d39f5b6d 100644 --- a/Tests/PerfectCryptoTests/PerfectCryptoTests.swift +++ b/Tests/PerfectCryptoTests/PerfectCryptoTests.swift @@ -589,7 +589,7 @@ class PerfectCryptoTests: XCTestCase { try testFileDigestBy(size: 15838, alg: alg, name: name) try testFileDigestBy(size: 1048573, alg: alg, name: name) } - +/* func testFiles() { do { try testFileDigest(alg: .md4, name: "md4") @@ -609,4 +609,5 @@ class PerfectCryptoTests: XCTestCase { XCTFail(error.localizedDescription) } } +*/ } diff --git a/smtp.test.json.example b/smtp.test.json.example index 683b124d..d083f184 100644 --- a/smtp.test.json.example +++ b/smtp.test.json.example @@ -1,5 +1,5 @@ { - "url": "smtp://smtp.mailtrap.io", + "url": "smtps://sandbox.smtp.mailtrap.io", "username": "someone", "password": "some password", "requiresTLSUpgrade": true From 65439bb868c03e3a13c47f5c2b6e130a1ae5dc59 Mon Sep 17 00:00:00 2001 From: Rockford Wei Date: Sat, 3 Feb 2024 10:38:37 -0500 Subject: [PATCH 48/48] Update README.md to Swift 5.9 / Ventura / Ubuntu 22.04 LTS --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 42279e9b..190d3ad6 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,9 @@ **OS**|**Version**|**Chip**|**Status** --|-------|----|------ -Monterey|macOS 12.4|Apple Silicon M1|Monterey Apple silicon -Ubuntu|20.04 LTS|i386|Ubuntu 20.04 LTS i386 -Ubuntu|20.04 LTS|arm64|Ubuntu 20.04 LTS arm64 +Ventura|macOS 13.6|Apple Silicon M2|Ventura Apple silicon +Ubuntu|22.04 LTS|i386|Ubuntu 22.04 LTS i386 +Ubuntu|22.04 LTS|arm64|Ubuntu 22.04 LTS arm64 **Package**|**Status**|**Package**|**Status** PerfectLib|PerfectLib|PerfectThread|PerfectThread PerfectAuth|PerfectAuth|PerfectCRUD|PerfectCRUD